Merge branch 'release-3.17'
diff --git a/.clang-format b/.clang-format
index 4bfce44..cba23d6 100644
--- a/.clang-format
+++ b/.clang-format
@@ -20,6 +20,8 @@
 SpaceAfterTemplateKeyword: true
 IncludeBlocks: Regroup
 IncludeCategories:
+  - Regex:           '^[<"]cmSTL\.hxx'
+    Priority:        -2
   - Regex:           '^[<"]cmConfigure\.h'
     Priority:        -1
   - Regex:           '^<queue>'
@@ -32,16 +34,18 @@
     Priority:        5
   - Regex:           '^(<|")Qt?[A-Z]'
     Priority:        6
-  - Regex:           '^(<|")cmsys/'
+  - Regex:           '^<cmtp/'
     Priority:        7
-  - Regex:           '^(<|")cm_'
+  - Regex:           '^(<|")cmsys/'
     Priority:        8
-  - Regex:           '^(<|")cm[A-Z][^.]+\.h'
+  - Regex:           '^(<|")cm_'
     Priority:        9
+  - Regex:           '^(<|")cm[A-Z][^.]+\.h'
+    Priority:        10
   - Regex:           '^<[^.]+\.h'
     Priority:        4
   - Regex:           '^<'
     Priority:        1
   - Regex:           '.*'
-    Priority:        10
+    Priority:        11
 ...
diff --git a/.clang-tidy b/.clang-tidy
index a520679..10819ef 100644
--- a/.clang-tidy
+++ b/.clang-tidy
@@ -13,9 +13,11 @@
 -modernize-avoid-c-arrays,\
 -modernize-use-nodiscard,\
 -modernize-use-noexcept,\
+-modernize-use-trailing-return-type,\
 -modernize-use-transparent-functors,\
 performance-*,\
 readability-*,\
+-readability-convert-member-functions-to-static,\
 -readability-function-size,\
 -readability-identifier-naming,\
 -readability-implicit-bool-conversion,\
diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md
index d934bf9..5281c92 100644
--- a/.github/pull_request_template.md
+++ b/.github/pull_request_template.md
@@ -2,6 +2,6 @@
 is a mirror provided for convenience, but CMake does not use GitHub pull
 requests for contribution.  Please see
 
-  https://gitlab.kitware.com/cmake/cmake/tree/master/CONTRIBUTING.rst
+  https://gitlab.kitware.com/cmake/cmake/-/tree/master/CONTRIBUTING.rst
 
 for contribution instructions.  GitHub OAuth may be used to sign in.
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
new file mode 100644
index 0000000..ec2393b
--- /dev/null
+++ b/.gitlab-ci.yml
@@ -0,0 +1,201 @@
+include:
+    # Metadata shared my many jobs
+    - local: .gitlab/rules.yml
+    - local: .gitlab/artifacts.yml
+
+    # OS builds.
+    - local: .gitlab/os-linux.yml
+    - local: .gitlab/os-macos.yml
+    - local: .gitlab/os-windows.yml
+
+stages:
+    - build
+    - test
+    - test-ext
+
+################################################################################
+# Job declarations
+#
+# Each job must pull in each of the following keys:
+#
+#   - a "base image"
+#   - a build script
+#   - tags for the jobs
+#   - rules for when to run the job
+#
+# Additionally, jobs may also contain:
+#
+#   - artifacts
+#   - dependency/needs jobs for required jobs
+################################################################################
+
+# Lint builds
+
+build:debian10-iwyu:
+    extends:
+        - .debian10_iwyu
+        - .cmake_build_linux
+        - .linux_builder_tags
+        - .run_automatically
+
+build:fedora31-tidy:
+    extends:
+        - .fedora31_tidy
+        - .cmake_build_linux
+        - .linux_builder_tags_qt
+        - .run_automatically
+
+build:fedora31-sphinx:
+    extends:
+        - .fedora31_sphinx
+        - .cmake_build_linux
+        - .linux_builder_tags_qt
+        - .run_automatically
+
+# Linux builds
+
+build:centos6-release:
+    extends:
+        - .release_linux
+        - .cmake_build_release_linux
+        - .cmake_release_artifacts
+        - .linux_builder_tags
+        - .run_manually
+
+test:fedora31-makefiles:
+    extends:
+        - .fedora31_makefiles
+        - .cmake_test_linux_package
+        - .linux_builder_tags_qt
+        - .run_automatically
+    dependencies:
+        - build:centos6-release
+    needs:
+        - build:centos6-release
+
+test:cuda10.2-nvidia:
+    extends:
+        - .cuda10.2_nvidia
+        - .cmake_test_linux_package
+        - .linux_builder_tags_cuda
+        - .run_automatically
+    dependencies:
+        - build:centos6-release
+    needs:
+        - build:centos6-release
+
+build:fedora31-ninja:
+    extends:
+        - .fedora31_ninja
+        - .cmake_build_linux
+        - .cmake_build_artifacts
+        - .linux_builder_tags_qt
+        - .run_manually
+
+test:fedora31-ninja:
+    extends:
+        - .fedora31_ninja
+        - .cmake_test_linux
+        - .linux_builder_tags_qt
+        - .cmake_test_artifacts
+        - .run_automatically
+    dependencies:
+        - build:fedora31-ninja
+    needs:
+        - build:fedora31-ninja
+
+test:fedora31-ninja-multi:
+    extends:
+        - .fedora31_ninja_multi
+        - .cmake_test_linux_external
+        - .linux_builder_tags_qt
+        - .run_automatically
+    dependencies:
+        - test:fedora31-ninja
+    needs:
+        - test:fedora31-ninja
+
+# macOS builds
+
+build:macos-ninja:
+    extends:
+        - .macos_ninja
+        - .cmake_build_macos
+        - .cmake_build_artifacts
+        - .macos_builder_tags
+        - .run_manually
+
+test:macos-ninja:
+    extends:
+        - .macos_ninja
+        - .cmake_test_macos
+        - .cmake_test_artifacts
+        - .macos_builder_tags
+        - .run_automatically
+    dependencies:
+        - build:macos-ninja
+    needs:
+        - build:macos-ninja
+
+build:macos-makefiles:
+    extends:
+        - .macos_makefiles
+        - .cmake_build_macos
+        - .cmake_build_artifacts
+        - .macos_builder_tags
+        - .run_manually
+
+test:macos-makefiles:
+    extends:
+        - .macos_makefiles
+        - .cmake_test_macos
+        - .macos_builder_tags
+        - .run_automatically
+    dependencies:
+        - build:macos-makefiles
+    needs:
+        - build:macos-makefiles
+
+test:macos-xcode:
+    extends:
+        - .macos_xcode
+        - .cmake_test_macos_external
+        - .macos_builder_ext_tags
+        - .run_automatically
+    dependencies:
+        - test:macos-ninja
+    needs:
+        - test:macos-ninja
+
+# Windows builds
+
+build:windows-vs2019-x64-ninja:
+    extends:
+        - .windows_vs2019_x64_ninja
+        - .cmake_build_windows
+        - .cmake_build_artifacts
+        - .windows_builder_tags
+        - .run_manually
+
+test:windows-vs2019-x64-ninja:
+    extends:
+        - .windows_vs2019_x64_ninja
+        - .cmake_test_windows
+        - .windows_builder_tags
+        - .cmake_test_artifacts
+        - .run_automatically
+    dependencies:
+        - build:windows-vs2019-x64-ninja
+    needs:
+        - build:windows-vs2019-x64-ninja
+
+test:windows-vs2019-x64:
+    extends:
+        - .windows_vs2019_x64
+        - .cmake_test_windows_external
+        - .windows_builder_ext_tags
+        - .run_automatically
+    dependencies:
+        - test:windows-vs2019-x64-ninja
+    needs:
+        - test:windows-vs2019-x64-ninja
diff --git a/.gitlab/artifacts.yml b/.gitlab/artifacts.yml
new file mode 100644
index 0000000..be10e24
--- /dev/null
+++ b/.gitlab/artifacts.yml
@@ -0,0 +1,81 @@
+# Lists of paths for artifacts of various stages.
+
+.cmake_build_artifacts:
+    artifacts:
+        expire_in: 1d
+        paths:
+            # XXX(globbing): Can be simplified with support from
+            # https://gitlab.com/gitlab-org/gitlab-runner/issues/4840
+            - build/CTestTestfile.cmake
+            - build/*/CTestTestfile.cmake
+            - build/*/*/CTestTestfile.cmake
+            - build/*/*/*/CTestTestfile.cmake
+            - build/*/*/*/*/CTestTestfile.cmake
+
+            # Allow CMake to find CMAKE_ROOT.
+            - build/CMakeFiles/CMakeSourceDir.txt
+
+            # Take the install tree.
+            - build/install/
+
+            # We need the main binaries.
+            - build/bin/
+            # The cache is needed for the installation test.
+            - build/CMakeCache.txt
+            # Test binaries. Eventually these might be better under
+            # `Source/Tests` or the like.
+            - build/Tests/EnforceConfig.cmake
+            - build/Tests/CMakeBuildTest.cmake
+            - build/Tests/CMakeBuildDoubleProjectTest.cmake
+            - build/Tests/CMake*/runcompilecommands
+            - build/Tests/CMake*/runcompilecommands.exe
+            - build/Tests/CMake*/test*
+            - build/Tests/CMake*/PseudoMemcheck/valgrind
+            - build/Tests/CMake*/PseudoMemcheck/purify
+            - build/Tests/CMake*/PseudoMemcheck/memcheck_fail
+            - build/Tests/CMake*/PseudoMemcheck/BC
+            - build/Tests/CMake*/PseudoMemcheck/cuda-memcheck
+            - build/Tests/CMake*/PseudoMemcheck/valgrind.exe
+            - build/Tests/CMake*/PseudoMemcheck/purify.exe
+            - build/Tests/CMake*/PseudoMemcheck/memcheck_fail.exe
+            - build/Tests/CMake*/PseudoMemcheck/BC.exe
+            - build/Tests/CMake*/PseudoMemcheck/cuda-memcheck.exe
+            - build/Tests/CMake*/PseudoMemcheck/NoLog
+            - build/Tests/CMake*Lib/*LibTests
+            - build/Tests/CMake*Lib/*LibTests.exe
+            - build/Source/kwsys/cmsysTest*
+            - build/Source/kwsys/testConsoleBufChild.exe
+            - build/Utilities/cmcurl/curltest
+            - build/Utilities/cmcurl/curltest.exe
+            - build/Utilities/KWIML/test/kwiml_test
+            - build/Utilities/KWIML/test/kwiml_test.exe
+            - build/Source/kwsys/*cmsysTestDynload.*
+            - build/Source/kwsys/dynloaddir/cmsysTestDynloadImpl.dll
+            - build/Source/kwsys/dynloaddir/cmsysTestDynloadUse.dll
+
+            # Test directories.
+            - build/Tests/CTest*
+            - build/Tests/Find*
+            - build/Tests/Qt5*
+            - build/Tests/RunCMake/
+            - build/Tests/CMakeOnly/
+            - build/Tests/CMakeTests/
+
+            # CTest/CDash information.
+            - build/Testing/
+            - build/DartConfiguation.tcl
+            - build/CTestCustom.cmake
+
+.cmake_release_artifacts:
+    artifacts:
+        expire_in: 5d
+        paths:
+            # Any packages made.
+            - build/cmake-*-Linux-x86_64.*
+
+.cmake_test_artifacts:
+    artifacts:
+        expire_in: 1d
+        paths:
+            # Take the install tree.
+            - build/install/
diff --git a/.gitlab/ci/cmake.ps1 b/.gitlab/ci/cmake.ps1
new file mode 100755
index 0000000..3b42cae
--- /dev/null
+++ b/.gitlab/ci/cmake.ps1
@@ -0,0 +1,18 @@
+$erroractionpreference = "stop"
+
+$version = "3.17.2"
+$sha256sum = "CF82B1EB20B6FBE583487656FCD496490FFCCDFBCBBA0F26E19F1C9C63B0B041"
+$filename = "cmake-$version-win64-x64"
+$tarball = "$filename.zip"
+
+$outdir = $pwd.Path
+$outdir = "$outdir\.gitlab"
+Invoke-WebRequest -Uri "https://github.com/Kitware/CMake/releases/download/v$version/$tarball" -OutFile "$outdir\$tarball"
+$hash = Get-FileHash "$outdir\$tarball" -Algorithm SHA256
+if ($hash.Hash -ne $sha256sum) {
+    exit 1
+}
+
+Add-Type -AssemblyName System.IO.Compression.FileSystem
+[System.IO.Compression.ZipFile]::ExtractToDirectory("$outdir\$tarball", "$outdir")
+Move-Item -Path "$outdir\$filename" -Destination "$outdir\cmake"
diff --git a/.gitlab/ci/cmake.sh b/.gitlab/ci/cmake.sh
new file mode 100755
index 0000000..658a62a
--- /dev/null
+++ b/.gitlab/ci/cmake.sh
@@ -0,0 +1,40 @@
+#!/bin/sh
+
+set -e
+
+readonly version="3.17.2"
+
+case "$( uname -s )" in
+    Linux)
+        shatool="sha256sum"
+        sha256sum="dc57f3cc448ca67fc8776b4ad4c22b087b9c6a8e459938b9622b8c7f4ef6b21e"
+        platform="Linux"
+        ;;
+    Darwin)
+        shatool="shasum -a 256"
+        sha256sum="139500e20b080444fcafe57f24f57248c691c5187cce6695bee2b9aad6792c7d"
+        platform="Darwin"
+        ;;
+    *)
+        echo "Unrecognized platform $( uname -s )"
+        exit 1
+        ;;
+esac
+readonly shatool
+readonly sha256sum
+readonly platform
+
+readonly filename="cmake-$version-$platform-x86_64"
+readonly tarball="$filename.tar.gz"
+
+cd .gitlab
+
+echo "$sha256sum  $tarball" > cmake.sha256sum
+curl -OL "https://github.com/Kitware/CMake/releases/download/v$version/$tarball"
+$shatool --check cmake.sha256sum
+tar xf "$tarball"
+mv "$filename" cmake
+
+if [ "$( uname -s )" = "Darwin" ]; then
+    ln -s CMake.app/Contents/bin cmake/bin
+fi
diff --git a/.gitlab/ci/configure_common.cmake b/.gitlab/ci/configure_common.cmake
new file mode 100644
index 0000000..df49b2d
--- /dev/null
+++ b/.gitlab/ci/configure_common.cmake
@@ -0,0 +1,13 @@
+set(CTEST_USE_LAUNCHERS "ON" CACHE BOOL "")
+
+# We run the install right after the build. Avoid rerunning it when installing.
+set(CMAKE_SKIP_INSTALL_ALL_DEPENDENCY "ON" CACHE BOOL "")
+# Install CMake under the build tree.
+set(CMAKE_INSTALL_PREFIX "${CMAKE_BINARY_DIR}/install" CACHE PATH "")
+set(CMake_TEST_INSTALL "OFF" CACHE BOOL "")
+
+if (NOT "$ENV{CMAKE_BUILD_TYPE}" STREQUAL "")
+  set(CMAKE_BUILD_TYPE "$ENV{CMAKE_BUILD_TYPE}" CACHE STRING "")
+endif ()
+
+include("${CMAKE_CURRENT_LIST_DIR}/configure_sccache.cmake")
diff --git a/.gitlab/ci/configure_cuda10.2_nvidia.cmake b/.gitlab/ci/configure_cuda10.2_nvidia.cmake
new file mode 100644
index 0000000..519699b
--- /dev/null
+++ b/.gitlab/ci/configure_cuda10.2_nvidia.cmake
@@ -0,0 +1,3 @@
+set(CMake_TEST_CUDA "NVIDIA" CACHE STRING "")
+
+include("${CMAKE_CURRENT_LIST_DIR}/configure_external_test.cmake")
diff --git a/.gitlab/ci/configure_debian10_iwyu.cmake b/.gitlab/ci/configure_debian10_iwyu.cmake
new file mode 100644
index 0000000..1daa581
--- /dev/null
+++ b/.gitlab/ci/configure_debian10_iwyu.cmake
@@ -0,0 +1,4 @@
+set(CMake_RUN_IWYU ON CACHE BOOL "")
+set(IWYU_COMMAND "/usr/bin/include-what-you-use-6.0" CACHE FILEPATH "")
+
+include("${CMAKE_CURRENT_LIST_DIR}/configure_common.cmake")
diff --git a/.gitlab/ci/configure_external_test.cmake b/.gitlab/ci/configure_external_test.cmake
new file mode 100644
index 0000000..71397d1
--- /dev/null
+++ b/.gitlab/ci/configure_external_test.cmake
@@ -0,0 +1,3 @@
+set(CMake_TEST_HOST_CMAKE "ON" CACHE BOOL "")
+
+include("${CMAKE_CURRENT_LIST_DIR}/configure_common.cmake")
diff --git a/.gitlab/ci/configure_fedora31_common.cmake b/.gitlab/ci/configure_fedora31_common.cmake
new file mode 100644
index 0000000..dc068d5
--- /dev/null
+++ b/.gitlab/ci/configure_fedora31_common.cmake
@@ -0,0 +1,4 @@
+set(BUILD_CursesDialog ON CACHE BOOL "")
+set(BUILD_QtDialog ON CACHE BOOL "")
+
+include("${CMAKE_CURRENT_LIST_DIR}/configure_common.cmake")
diff --git a/.gitlab/ci/configure_fedora31_makefiles.cmake b/.gitlab/ci/configure_fedora31_makefiles.cmake
new file mode 100644
index 0000000..20863a2
--- /dev/null
+++ b/.gitlab/ci/configure_fedora31_makefiles.cmake
@@ -0,0 +1 @@
+include("${CMAKE_CURRENT_LIST_DIR}/configure_external_test.cmake")
diff --git a/.gitlab/ci/configure_fedora31_ninja.cmake b/.gitlab/ci/configure_fedora31_ninja.cmake
new file mode 100644
index 0000000..74768b7
--- /dev/null
+++ b/.gitlab/ci/configure_fedora31_ninja.cmake
@@ -0,0 +1 @@
+include("${CMAKE_CURRENT_LIST_DIR}/configure_fedora31_common.cmake")
diff --git a/.gitlab/ci/configure_fedora31_ninja_multi.cmake b/.gitlab/ci/configure_fedora31_ninja_multi.cmake
new file mode 100644
index 0000000..20863a2
--- /dev/null
+++ b/.gitlab/ci/configure_fedora31_ninja_multi.cmake
@@ -0,0 +1 @@
+include("${CMAKE_CURRENT_LIST_DIR}/configure_external_test.cmake")
diff --git a/.gitlab/ci/configure_fedora31_sphinx.cmake b/.gitlab/ci/configure_fedora31_sphinx.cmake
new file mode 100644
index 0000000..dfc9b8c
--- /dev/null
+++ b/.gitlab/ci/configure_fedora31_sphinx.cmake
@@ -0,0 +1,8 @@
+set(SPHINX_INFO ON CACHE BOOL "")
+set(SPHINX_MAN ON CACHE BOOL "")
+set(SPHINX_HTML ON CACHE BOOL "")
+set(SPHINX_SINGLEHTML ON CACHE BOOL "")
+set(SPHINX_QTHELP ON CACHE BOOL "")
+set(SPHINX_TEXT ON CACHE BOOL "")
+
+include("${CMAKE_CURRENT_LIST_DIR}/configure_common.cmake")
diff --git a/.gitlab/ci/configure_fedora31_tidy.cmake b/.gitlab/ci/configure_fedora31_tidy.cmake
new file mode 100644
index 0000000..55d022c
--- /dev/null
+++ b/.gitlab/ci/configure_fedora31_tidy.cmake
@@ -0,0 +1,3 @@
+set(CMake_RUN_CLANG_TIDY ON CACHE BOOL "")
+
+include("${CMAKE_CURRENT_LIST_DIR}/configure_fedora31_common.cmake")
diff --git a/.gitlab/ci/configure_macos_common.cmake b/.gitlab/ci/configure_macos_common.cmake
new file mode 100644
index 0000000..bd5902b
--- /dev/null
+++ b/.gitlab/ci/configure_macos_common.cmake
@@ -0,0 +1,9 @@
+# Our CI machines do not consistently have Java installed, so a build may
+# detect that Java is available and working, but a test machine then not have a
+# working Java installed. To work around this, just act as if Java is not
+# available on any CI machine.
+set(Java_JAVA_EXECUTABLE "" CACHE FILEPATH "")
+set(Java_JAVAC_EXECUTABLE "" CACHE FILEPATH "")
+set(Java_JAR_EXECUTABLE "" CACHE FILEPATH "")
+
+set(BUILD_QtDialog ON CACHE BOOL "")
diff --git a/.gitlab/ci/configure_macos_makefiles.cmake b/.gitlab/ci/configure_macos_makefiles.cmake
new file mode 100644
index 0000000..85f67b5
--- /dev/null
+++ b/.gitlab/ci/configure_macos_makefiles.cmake
@@ -0,0 +1,2 @@
+include("${CMAKE_CURRENT_LIST_DIR}/configure_macos_common.cmake")
+include("${CMAKE_CURRENT_LIST_DIR}/configure_common.cmake")
diff --git a/.gitlab/ci/configure_macos_ninja.cmake b/.gitlab/ci/configure_macos_ninja.cmake
new file mode 100644
index 0000000..85f67b5
--- /dev/null
+++ b/.gitlab/ci/configure_macos_ninja.cmake
@@ -0,0 +1,2 @@
+include("${CMAKE_CURRENT_LIST_DIR}/configure_macos_common.cmake")
+include("${CMAKE_CURRENT_LIST_DIR}/configure_common.cmake")
diff --git a/.gitlab/ci/configure_macos_xcode.cmake b/.gitlab/ci/configure_macos_xcode.cmake
new file mode 100644
index 0000000..1b976d2
--- /dev/null
+++ b/.gitlab/ci/configure_macos_xcode.cmake
@@ -0,0 +1,2 @@
+include("${CMAKE_CURRENT_LIST_DIR}/configure_macos_common.cmake")
+include("${CMAKE_CURRENT_LIST_DIR}/configure_external_test.cmake")
diff --git a/.gitlab/ci/configure_sccache.cmake b/.gitlab/ci/configure_sccache.cmake
new file mode 100644
index 0000000..261bb28
--- /dev/null
+++ b/.gitlab/ci/configure_sccache.cmake
@@ -0,0 +1,2 @@
+set(CMAKE_C_COMPILER_LAUNCHER "sccache" CACHE STRING "")
+set(CMAKE_CXX_COMPILER_LAUNCHER "sccache" CACHE STRING "")
diff --git a/.gitlab/ci/configure_windows_common.cmake b/.gitlab/ci/configure_windows_common.cmake
new file mode 100644
index 0000000..45250ac
--- /dev/null
+++ b/.gitlab/ci/configure_windows_common.cmake
@@ -0,0 +1,4 @@
+set(BUILD_QtDialog ON CACHE BOOL "")
+set(CMAKE_PREFIX_PATH "$ENV{CI_PROJECT_DIR}/.gitlab/qt" CACHE STRING "")
+
+include("${CMAKE_CURRENT_LIST_DIR}/configure_common.cmake")
diff --git a/.gitlab/ci/configure_windows_vs2019_x64.cmake b/.gitlab/ci/configure_windows_vs2019_x64.cmake
new file mode 100644
index 0000000..f6ece57
--- /dev/null
+++ b/.gitlab/ci/configure_windows_vs2019_x64.cmake
@@ -0,0 +1,3 @@
+set(CMake_TEST_WIX_NO_VERIFY "ON" CACHE BOOL "")
+
+include("${CMAKE_CURRENT_LIST_DIR}/configure_external_test.cmake")
diff --git a/.gitlab/ci/configure_windows_vs2019_x64_ninja.cmake b/.gitlab/ci/configure_windows_vs2019_x64_ninja.cmake
new file mode 100644
index 0000000..719c93c
--- /dev/null
+++ b/.gitlab/ci/configure_windows_vs2019_x64_ninja.cmake
@@ -0,0 +1,3 @@
+set(CMake_TEST_WIX_NO_VERIFY "ON" CACHE BOOL "")
+
+include("${CMAKE_CURRENT_LIST_DIR}/configure_windows_common.cmake")
diff --git a/.gitlab/ci/ctest_build.cmake b/.gitlab/ci/ctest_build.cmake
new file mode 100644
index 0000000..6402a5d
--- /dev/null
+++ b/.gitlab/ci/ctest_build.cmake
@@ -0,0 +1,41 @@
+cmake_minimum_required(VERSION 3.8)
+
+include("${CMAKE_CURRENT_LIST_DIR}/gitlab_ci.cmake")
+
+# Read the files from the build directory.
+ctest_read_custom_files("${CTEST_BINARY_DIRECTORY}")
+
+# Pick up from where the configure left off.
+ctest_start(APPEND)
+
+if (CTEST_CMAKE_GENERATOR STREQUAL "Unix Makefiles")
+  include(ProcessorCount)
+  ProcessorCount(nproc)
+  set(CTEST_BUILD_FLAGS "-j${nproc}")
+endif ()
+
+ctest_build(
+  NUMBER_WARNINGS num_warnings
+  RETURN_VALUE build_result)
+ctest_submit(PARTS Build)
+
+if (build_result)
+  message(FATAL_ERROR
+    "Failed to build")
+endif ()
+
+if ("$ENV{CTEST_NO_WARNINGS_ALLOWED}" AND num_warnings GREATER 0)
+  message(FATAL_ERROR
+    "Found ${num_warnings} warnings (treating as fatal).")
+endif ()
+
+if (NOT "$ENV{CMake_SKIP_INSTALL}")
+  ctest_build(APPEND
+    TARGET install
+    RETURN_VALUE install_result)
+
+  if (install_result)
+    message(FATAL_ERROR
+      "Failed to install")
+  endif ()
+endif ()
diff --git a/.gitlab/ci/ctest_configure.cmake b/.gitlab/ci/ctest_configure.cmake
new file mode 100644
index 0000000..55cad13
--- /dev/null
+++ b/.gitlab/ci/ctest_configure.cmake
@@ -0,0 +1,32 @@
+cmake_minimum_required(VERSION 3.8)
+
+include("${CMAKE_CURRENT_LIST_DIR}/gitlab_ci.cmake")
+
+set(cmake_args
+  -C "${CMAKE_CURRENT_LIST_DIR}/configure_$ENV{CMAKE_CONFIGURATION}.cmake")
+
+# Create an entry in CDash.
+ctest_start(Experimental TRACK "${ctest_track}")
+
+# Gather update information.
+find_package(Git)
+set(CTEST_UPDATE_VERSION_ONLY ON)
+set(CTEST_UPDATE_COMMAND "${GIT_EXECUTABLE}")
+ctest_update()
+
+# Configure the project.
+ctest_configure(
+  OPTIONS "${cmake_args}"
+  RETURN_VALUE configure_result)
+
+# Read the files from the build directory.
+ctest_read_custom_files("${CTEST_BINARY_DIRECTORY}")
+
+# We can now submit because we've configured. This is a cmb-superbuild-ism.
+ctest_submit(PARTS Update)
+ctest_submit(PARTS Configure)
+
+if (configure_result)
+  message(FATAL_ERROR
+    "Failed to configure")
+endif ()
diff --git a/.gitlab/ci/ctest_exclusions.cmake b/.gitlab/ci/ctest_exclusions.cmake
new file mode 100644
index 0000000..b885a6a
--- /dev/null
+++ b/.gitlab/ci/ctest_exclusions.cmake
@@ -0,0 +1,19 @@
+set(test_exclusions
+  # This test hits global resources and can be handled by nightly testing.
+  # https://gitlab.kitware.com/cmake/cmake/-/merge_requests/4769
+  "^BundleGeneratorTest$"
+)
+
+if (CTEST_CMAKE_GENERATOR MATCHES "Visual Studio")
+  list(APPEND test_exclusions
+    # This test takes around 5 minutes with Visual Studio.
+    # https://gitlab.kitware.com/cmake/cmake/-/issues/20733
+    "^ExternalProjectUpdate$"
+    # This test is a dependency of the above and is only required for it.
+    "^ExternalProjectUpdateSetup$")
+endif ()
+
+string(REPLACE ";" "|" test_exclusions "${test_exclusions}")
+if (test_exclusions)
+  set(test_exclusions "(${test_exclusions})")
+endif ()
diff --git a/.gitlab/ci/ctest_test.cmake b/.gitlab/ci/ctest_test.cmake
new file mode 100644
index 0000000..569139d
--- /dev/null
+++ b/.gitlab/ci/ctest_test.cmake
@@ -0,0 +1,24 @@
+cmake_minimum_required(VERSION 3.8)
+
+include("${CMAKE_CURRENT_LIST_DIR}/gitlab_ci.cmake")
+
+# Read the files from the build directory.
+ctest_read_custom_files("${CTEST_BINARY_DIRECTORY}")
+
+# Pick up from where the configure left off.
+ctest_start(APPEND)
+
+include(ProcessorCount)
+ProcessorCount(nproc)
+
+include("${CMAKE_CURRENT_LIST_DIR}/ctest_exclusions.cmake")
+ctest_test(
+  PARALLEL_LEVEL "${nproc}"
+  RETURN_VALUE test_result
+  EXCLUDE "${test_exclusions}")
+ctest_submit(PARTS Test)
+
+if (test_result)
+  message(FATAL_ERROR
+    "Failed to test")
+endif ()
diff --git a/.gitlab/ci/ctest_test_external.cmake b/.gitlab/ci/ctest_test_external.cmake
new file mode 100644
index 0000000..d92b936
--- /dev/null
+++ b/.gitlab/ci/ctest_test_external.cmake
@@ -0,0 +1,73 @@
+cmake_minimum_required(VERSION 3.8)
+
+include("${CMAKE_CURRENT_LIST_DIR}/gitlab_ci.cmake")
+
+set(cmake_args
+  -C "${CMAKE_CURRENT_LIST_DIR}/configure_$ENV{CMAKE_CONFIGURATION}.cmake")
+
+# Create an entry in CDash.
+ctest_start(Experimental TRACK "${ctest_track}")
+
+# Gather update information.
+find_package(Git)
+set(CTEST_UPDATE_VERSION_ONLY ON)
+set(CTEST_UPDATE_COMMAND "${GIT_EXECUTABLE}")
+ctest_update()
+
+# Configure the project.
+ctest_configure(
+  OPTIONS "${cmake_args}"
+  RETURN_VALUE configure_result)
+
+# Read the files from the build directory.
+ctest_read_custom_files("${CTEST_BINARY_DIRECTORY}")
+
+# We can now submit because we've configured. This is a cmb-superbuild-ism.
+ctest_submit(PARTS Update)
+ctest_submit(PARTS Configure)
+
+if (configure_result)
+  message(FATAL_ERROR
+    "Failed to configure")
+endif ()
+
+include(ProcessorCount)
+ProcessorCount(nproc)
+
+if (CTEST_CMAKE_GENERATOR STREQUAL "Unix Makefiles")
+  set(CTEST_BUILD_FLAGS "-j${nproc}")
+endif ()
+
+ctest_build(
+  NUMBER_WARNINGS num_warnings
+  RETURN_VALUE build_result)
+ctest_submit(PARTS Build)
+
+if (build_result)
+  message(FATAL_ERROR
+    "Failed to build")
+endif ()
+
+if ("$ENV{CTEST_NO_WARNINGS_ALLOWED}" AND num_warnings GREATER 0)
+  message(FATAL_ERROR
+    "Found ${num_warnings} warnings (treating as fatal).")
+endif ()
+
+set(ctest_label_args)
+if (NOT "$ENV{CTEST_LABELS}" STREQUAL "")
+  list(APPEND ctest_label_args
+    INCLUDE_LABEL "$ENV{CTEST_LABELS}")
+endif ()
+
+include("${CMAKE_CURRENT_LIST_DIR}/ctest_exclusions.cmake")
+ctest_test(
+  PARALLEL_LEVEL "${nproc}"
+  RETURN_VALUE test_result
+  ${ctest_label_args}
+  EXCLUDE "${test_exclusions}")
+ctest_submit(PARTS Test)
+
+if (test_result)
+  message(FATAL_ERROR
+    "Failed to test")
+endif ()
diff --git a/.gitlab/ci/docker/cuda10.2/Dockerfile b/.gitlab/ci/docker/cuda10.2/Dockerfile
new file mode 100644
index 0000000..e0ea0e7
--- /dev/null
+++ b/.gitlab/ci/docker/cuda10.2/Dockerfile
@@ -0,0 +1,5 @@
+FROM nvidia/cuda:10.2-devel-ubuntu18.04
+MAINTAINER Ben Boeckel <ben.boeckel@kitware.com>
+
+COPY install_deps.sh /root/install_deps.sh
+RUN sh /root/install_deps.sh
diff --git a/.gitlab/ci/docker/cuda10.2/install_deps.sh b/.gitlab/ci/docker/cuda10.2/install_deps.sh
new file mode 100755
index 0000000..0d57cd3
--- /dev/null
+++ b/.gitlab/ci/docker/cuda10.2/install_deps.sh
@@ -0,0 +1,13 @@
+#!/bin/sh
+
+set -e
+
+apt-get update
+
+# Install development tools.
+apt-get install -y \
+    g++ \
+    curl \
+    git
+
+apt-get clean
diff --git a/.gitlab/ci/docker/debian10/Dockerfile b/.gitlab/ci/docker/debian10/Dockerfile
new file mode 100644
index 0000000..e8c3851
--- /dev/null
+++ b/.gitlab/ci/docker/debian10/Dockerfile
@@ -0,0 +1,15 @@
+FROM debian:10 as iwyu-build
+MAINTAINER Ben Boeckel <ben.boeckel@kitware.com>
+
+COPY install_iwyu.sh /root/install_iwyu.sh
+RUN sh /root/install_iwyu.sh
+
+FROM debian:10
+MAINTAINER Ben Boeckel <ben.boeckel@kitware.com>
+
+COPY install_deps.sh /root/install_deps.sh
+RUN sh /root/install_deps.sh
+
+COPY --from=iwyu-build /root/iwyu.tar.gz /root/iwyu.tar.gz
+RUN tar -C / -xf /root/iwyu.tar.gz
+RUN ln -s /usr/lib/llvm-6.0/bin/include-what-you-use /usr/bin/include-what-you-use-6.0
diff --git a/.gitlab/ci/docker/debian10/install_deps.sh b/.gitlab/ci/docker/debian10/install_deps.sh
new file mode 100755
index 0000000..9c32d64
--- /dev/null
+++ b/.gitlab/ci/docker/debian10/install_deps.sh
@@ -0,0 +1,22 @@
+#!/bin/sh
+
+set -e
+
+apt-get update
+
+# Install build requirements.
+apt-get install -y \
+    libssl-dev
+
+# Install development tools.
+apt-get install -y \
+    g++ \
+    curl \
+    git
+
+# Install iwyu runtime deps.
+apt-get install -y \
+    clang-6.0 \
+    libncurses6
+
+apt-get clean
diff --git a/.gitlab/ci/docker/debian10/install_iwyu.sh b/.gitlab/ci/docker/debian10/install_iwyu.sh
new file mode 100755
index 0000000..54d26ef
--- /dev/null
+++ b/.gitlab/ci/docker/debian10/install_iwyu.sh
@@ -0,0 +1,32 @@
+#!/bin/sh
+
+set -e
+
+# Install development tools.
+apt-get update
+apt-get install -y \
+    clang-6.0 \
+    libclang-6.0-dev \
+    llvm-6.0-dev \
+    libz-dev \
+    g++ \
+    cmake \
+    ninja-build \
+    git
+
+cd /root
+git clone "https://github.com/include-what-you-use/include-what-you-use.git"
+cd include-what-you-use
+readonly llvm_version="$( clang-6.0 --version | head -n1 | cut -d' ' -f3 | cut -d. -f-2 )"
+git checkout "clang_$llvm_version"
+mkdir build
+cd build
+
+cmake -GNinja \
+    -DCMAKE_BUILD_TYPE=Release \
+    "-DCMAKE_INSTALL_PREFIX=/usr/lib/llvm-$llvm_version" \
+    "-DIWYU_LLVM_ROOT_PATH=/usr/lib/llvm-$llvm_version" \
+    ..
+ninja
+DESTDIR=/root/iwyu-destdir ninja install
+tar -C /root/iwyu-destdir -cf /root/iwyu.tar.gz .
diff --git a/.gitlab/ci/docker/fedora31/Dockerfile b/.gitlab/ci/docker/fedora31/Dockerfile
new file mode 100644
index 0000000..5588a85
--- /dev/null
+++ b/.gitlab/ci/docker/fedora31/Dockerfile
@@ -0,0 +1,5 @@
+FROM fedora:31
+MAINTAINER Ben Boeckel <ben.boeckel@kitware.com>
+
+COPY install_deps.sh /root/install_deps.sh
+RUN sh /root/install_deps.sh
diff --git a/.gitlab/ci/docker/fedora31/install_deps.sh b/.gitlab/ci/docker/fedora31/install_deps.sh
new file mode 100755
index 0000000..0d857c1
--- /dev/null
+++ b/.gitlab/ci/docker/fedora31/install_deps.sh
@@ -0,0 +1,27 @@
+#!/bin/sh
+
+# Install build requirements.
+dnf install --setopt=install_weak_deps=False -y \
+    ncurses-devel \
+    openssl-devel \
+    qt5-qtbase-devel
+
+# Install development tools.
+dnf install --setopt=install_weak_deps=False -y \
+    clang-tools-extra \
+    gcc-c++ \
+    git-core \
+    make
+
+# Install documentation tools.
+dnf install --setopt=install_weak_deps=False -y \
+    python3-sphinx \
+    texinfo \
+    qt5-qttools-devel
+
+# Tools needed for the test suite.
+dnf install --setopt=install_weak_deps=False -y \
+    findutils \
+    file
+
+dnf clean all
diff --git a/.gitlab/ci/download_qt.cmake b/.gitlab/ci/download_qt.cmake
new file mode 100644
index 0000000..c392b1c
--- /dev/null
+++ b/.gitlab/ci/download_qt.cmake
@@ -0,0 +1,146 @@
+cmake_minimum_required(VERSION 3.12)
+
+# Input variables.
+set(qt_version_major "5")
+set(qt_version_minor "15")
+set(qt_version_patch "0")
+# This URL is only visible inside of Kitware's network. Please use your own Qt
+# Account to obtain these files.
+set(qt_url_root "https://paraview.org/files/dependencies/internal/qt")
+
+# Determine the ABI to fetch for Qt.
+if ("$ENV{CMAKE_CONFIGURATION}" MATCHES "vs2015")
+  set(qt_platform "windows_x86")
+  set(msvc_year "2015")
+  set(qt_abi "win64_msvc${msvc_year}_64")
+elseif ("$ENV{CMAKE_CONFIGURATION}" MATCHES "vs2017" OR
+        "$ENV{CMAKE_CONFIGURATION}" MATCHES "vs2019")
+  set(qt_platform "windows_x86")
+  set(msvc_year "2017")
+  set(qt_abi "win64_msvc${msvc_year}_64")
+elseif ("$ENV{CMAKE_CONFIGURATION}" MATCHES "macos")
+  set(qt_platform "mac_x64")
+  set(qt_abi "clang_64")
+else ()
+  message(FATAL_ERROR
+    "Unknown ABI to use for Qt")
+endif ()
+
+# Combined version variables.
+set(qt_version "${qt_version_major}.${qt_version_minor}.${qt_version_patch}")
+set(qt_version_nodot "${qt_version_major}${qt_version_minor}${qt_version_patch}")
+
+# Files needed to download.
+set(qt_files)
+if (qt_platform STREQUAL "windows_x86")
+  if (msvc_year STREQUAL "2017")
+    set(qt_build_stamp "202002260536")
+  elseif (msvc_year STREQUAL "2015")
+    set(qt_build_stamp "202005150700")
+  else ()
+    message(FATAL_ERROR
+      "Build stamp for MSVC ${msvc_year} is unknown")
+  endif ()
+
+  set(qt_file_name_prefix "${qt_version}-0-${qt_build_stamp}")
+
+  foreach (qt_component IN ITEMS qtbase qtwinextras)
+    list(APPEND qt_files
+      "${qt_file_name_prefix}${qt_component}-Windows-Windows_10-MSVC${msvc_year}-Windows-Windows_10-X86_64.7z")
+  endforeach ()
+
+  set(qt_subdir "${qt_version}/msvc${msvc_year}_64")
+elseif (qt_platform STREQUAL "mac_x64")
+  set(qt_build_stamp "202005140805")
+  set(qt_file_name_prefix "${qt_version}-0-${qt_build_stamp}")
+
+  foreach (qt_component IN ITEMS qtbase)
+    list(APPEND qt_files
+      "${qt_file_name_prefix}${qt_component}-MacOS-MacOS_10_13-Clang-MacOS-MacOS_10_13-X86_64.7z")
+  endforeach ()
+
+  set(qt_subdir "${qt_version}/clang_64")
+else ()
+  message(FATAL_ERROR
+    "Unknown files for ${qt_platform}")
+endif ()
+
+# Verify that we know what directory will be extracted.
+if (NOT qt_subdir)
+  message(FATAL_ERROR
+    "The extracted subdirectory is not set")
+endif ()
+
+# Build up the path to the file to download.
+set(qt_url_path "${qt_platform}/desktop/qt5_${qt_version_nodot}/qt.qt5.${qt_version_nodot}.${qt_abi}")
+set(qt_url_prefix "${qt_url_root}/${qt_url_path}")
+
+# Include the file containing the hashes of the files that matter.
+include("${CMAKE_CURRENT_LIST_DIR}/download_qt_hashes.cmake")
+
+# Download and extract each file.
+foreach (qt_file IN LISTS qt_files)
+  # Ensure we have a hash to verify.
+  if (NOT DEFINED "${qt_file}_hash")
+    message(FATAL_ERROR
+      "Unknown hash for ${qt_file}")
+  endif ()
+
+  # Download the file.
+  file(DOWNLOAD
+    "${qt_url_prefix}/${qt_file}"
+    ".gitlab/${qt_file}"
+    STATUS download_status
+    EXPECTED_HASH "SHA256=${${qt_file}_hash}")
+
+  # Check the download status.
+  list(GET download_status 0 res)
+  if (res)
+    list(GET download_status 1 err)
+    message(FATAL_ERROR
+      "Failed to download ${qt_file}: ${err}")
+  endif ()
+
+  # Extract the file.
+  execute_process(
+    COMMAND
+      "${CMAKE_COMMAND}"
+      -E tar
+      xf "${qt_file}"
+    WORKING_DIRECTORY ".gitlab"
+    RESULT_VARIABLE res
+    ERROR_VARIABLE err
+    ERROR_STRIP_TRAILING_WHITESPACE)
+  if (res)
+    message(FATAL_ERROR
+      "Failed to extract ${qt_file}: ${err}")
+  endif ()
+endforeach ()
+
+# The Windows tarballs have some unfortunate permissions in them that prevent
+# deletion when `git clean -ffdx` tries to clean up the directory.
+if (qt_platform STREQUAL "windows_x86")
+  # Fix permissions.
+  file(TO_NATIVE_PATH ".gitlab/${qt_subdir}/*.*" native_qt_dir)
+  execute_process(
+    # Remove any read-only flags that aren't affected by `icacls`.
+    COMMAND
+      attrib
+      -r # Remove readonly flag
+      "${native_qt_dir}"
+      /d # Treat as a directory
+      /s # Recursive
+      /l # Don't dereference symlinks
+    RESULT_VARIABLE res
+    ERROR_VARIABLE err
+    ERROR_STRIP_TRAILING_WHITESPACE)
+  if (res)
+    message(FATAL_ERROR
+      "Failed to fix remove read-only flags in ${qt_file}: ${err}")
+  endif ()
+endif ()
+
+# Move to a predictable prefix.
+file(RENAME
+  ".gitlab/${qt_subdir}"
+  ".gitlab/qt")
diff --git a/.gitlab/ci/download_qt_hashes.cmake b/.gitlab/ci/download_qt_hashes.cmake
new file mode 100644
index 0000000..59cb597
--- /dev/null
+++ b/.gitlab/ci/download_qt_hashes.cmake
@@ -0,0 +1,11 @@
+# Lines can be generated by doing:
+#
+#   sha256sum $files | awk '{ print "set(\"" $2 "_hash\" " $1 ")" }' >> $thisfile
+
+set("5.15.0-0-202002260536qtbase-Windows-Windows_10-MSVC2017-Windows-Windows_10-X86_64.7z_hash" c041596be8f7a16c7be9ea6757c14766ff3200ab6d56f7db8f865dbfe039fe20)
+set("5.15.0-0-202002260536qtwinextras-Windows-Windows_10-MSVC2017-Windows-Windows_10-X86_64.7z_hash" 10796128fac54f146767e33f6872975ba238858547de7a9650ec4cd9581fe71a)
+
+set("5.15.0-0-202005150700qtbase-Windows-Windows_10-MSVC2015-Windows-Windows_10-X86_64.7z_hash" 0c2653c5eca256f59c0b48b537cd633b05560e4241c0226856d2ae22ab066df4)
+set("5.15.0-0-202005150700qtwinextras-Windows-Windows_10-MSVC2015-Windows-Windows_10-X86_64.7z_hash" 4bca3a8d8c7611e211a82d86b3396f8a622abe7859d5052452414642ec191844)
+
+set("5.15.0-0-202005140805qtbase-MacOS-MacOS_10_13-Clang-MacOS-MacOS_10_13-X86_64.7z_hash" 04d867c81d2431f288c42c9752642759460b9468477de349368dcc8de0c8ddc4)
diff --git a/.gitlab/ci/gitlab_ci.cmake b/.gitlab/ci/gitlab_ci.cmake
new file mode 100644
index 0000000..698d5ea
--- /dev/null
+++ b/.gitlab/ci/gitlab_ci.cmake
@@ -0,0 +1,58 @@
+if (NOT DEFINED "ENV{GITLAB_CI}")
+  message(FATAL_ERROR
+    "This script assumes it is being run inside of GitLab-CI")
+endif ()
+
+# Set up the source and build paths.
+set(CTEST_SOURCE_DIRECTORY "$ENV{CI_PROJECT_DIR}")
+if (NOT "$ENV{CTEST_SOURCE_SUBDIRECTORY}" STREQUAL "")
+  string(APPEND CTEST_SOURCE_DIRECTORY "/$ENV{CTEST_SOURCE_SUBDIRECTORY}")
+endif ()
+set(CTEST_BINARY_DIRECTORY "${CTEST_SOURCE_DIRECTORY}/build")
+
+if ("$ENV{CMAKE_CONFIGURATION}" STREQUAL "")
+  message(FATAL_ERROR
+    "The CMAKE_CONFIGURATION environment variable is required to know what "
+    "cache initialization file to use.")
+endif ()
+
+# Set the build metadata.
+set(CTEST_BUILD_NAME "$ENV{CI_PROJECT_NAME}-$ENV{CMAKE_CONFIGURATION}")
+set(CTEST_SITE "gitlab-ci")
+
+# Default to Release builds.
+if (NOT "$ENV{CMAKE_BUILD_TYPE}" STREQUAL "")
+  set(CTEST_BUILD_CONFIGURATION "$ENV{CMAKE_BUILD_TYPE}")
+endif ()
+if (NOT CTEST_BUILD_CONFIGURATION)
+  set(CTEST_BUILD_CONFIGURATION "Release")
+endif ()
+set(CTEST_CONFIGURATION_TYPE "${CTEST_BUILD_CONFIGURATION}")
+
+# Default to using Ninja.
+if (NOT "$ENV{CMAKE_GENERATOR}" STREQUAL "")
+  set(CTEST_CMAKE_GENERATOR "$ENV{CMAKE_GENERATOR}")
+endif ()
+if (NOT CTEST_CMAKE_GENERATOR)
+  set(CTEST_CMAKE_GENERATOR "Ninja")
+endif ()
+
+# Set the toolset and platform if requested.
+if (NOT "$ENV{CMAKE_GENERATOR_PLATFORM}" STREQUAL "")
+  set(CTEST_CMAKE_GENERATOR_PLATFORM "$ENV{CMAKE_GENERATOR_PLATFORM}")
+endif ()
+if (NOT "$ENV{CMAKE_GENERATOR_TOOLSET}" STREQUAL "")
+  set(CTEST_CMAKE_GENERATOR_TOOLSET "$ENV{CMAKE_GENERATOR_TOOLSET}")
+endif ()
+
+# Determine the track to submit to.
+set(ctest_track "Experimental")
+if (NOT "$ENV{CI_MERGE_REQUEST_ID}" STREQUAL "")
+  set(ctest_track "merge-requests")
+elseif ("$ENV{CI_PROJECT_PATH}" STREQUAL "cmake/cmake")
+  if ("$ENV{CI_COMMIT_REF_NAME}" STREQUAL "master")
+    set(ctest_track "master")
+  elseif ("$ENV{CI_COMMIT_REF_NAME}" STREQUAL "release")
+    set(ctest_track "release")
+  endif ()
+endif ()
diff --git a/.gitlab/ci/ninja.ps1 b/.gitlab/ci/ninja.ps1
new file mode 100755
index 0000000..91f8b02
--- /dev/null
+++ b/.gitlab/ci/ninja.ps1
@@ -0,0 +1,17 @@
+$erroractionpreference = "stop"
+
+$version = "1.10.0"
+$sha256sum = "919FD158C16BF135E8A850BB4046EC1CE28A7439EE08B977CD0B7F6B3463D178"
+$filename = "ninja-win"
+$tarball = "$filename.zip"
+
+$outdir = $pwd.Path
+$outdir = "$outdir\.gitlab"
+Invoke-WebRequest -Uri "https://github.com/ninja-build/ninja/releases/download/v$version/$tarball" -OutFile "$outdir\$tarball"
+$hash = Get-FileHash "$outdir\$tarball" -Algorithm SHA256
+if ($hash.Hash -ne $sha256sum) {
+    exit 1
+}
+
+Add-Type -AssemblyName System.IO.Compression.FileSystem
+[System.IO.Compression.ZipFile]::ExtractToDirectory("$outdir\$tarball", "$outdir")
diff --git a/.gitlab/ci/ninja.sh b/.gitlab/ci/ninja.sh
new file mode 100755
index 0000000..93c1ee9
--- /dev/null
+++ b/.gitlab/ci/ninja.sh
@@ -0,0 +1,35 @@
+#!/bin/sh
+
+set -e
+
+readonly version="1.10.0"
+
+case "$( uname -s )" in
+    Linux)
+        shatool="sha256sum"
+        sha256sum="6566836ddf3d72ca06685b34814e0c6fa0f0943542d651d0dab3150f10307c82"
+        platform="linux"
+        ;;
+    Darwin)
+        shatool="shasum -a 256"
+        sha256sum="2ee405c0e205d55666c60cc9c0d8d04c8ede06d3ef2e2c2aabe08fd81c17d22e"
+        platform="mac"
+        ;;
+    *)
+        echo "Unrecognized platform $( uname -s )"
+        exit 1
+        ;;
+esac
+readonly shatool
+readonly sha256sum
+readonly platform
+
+readonly filename="ninja-$platform"
+readonly tarball="$filename.zip"
+
+cd .gitlab
+
+echo "$sha256sum  $tarball" > ninja.sha256sum
+curl -OL "https://github.com/ninja-build/ninja/releases/download/v$version/$tarball"
+$shatool --check ninja.sha256sum
+./cmake/bin/cmake -E tar xf "$tarball"
diff --git a/.gitlab/ci/sccache.sh b/.gitlab/ci/sccache.sh
new file mode 100755
index 0000000..f7d51ff
--- /dev/null
+++ b/.gitlab/ci/sccache.sh
@@ -0,0 +1,36 @@
+#!/bin/sh
+
+set -e
+
+readonly version="0.2.13"
+
+case "$( uname -s )" in
+    Linux)
+        shatool="sha256sum"
+        sha256sum="28a5499e340865b08b632306b435913beb590fbd7b49a3f887a623b459fabdeb"
+        platform="x86_64-unknown-linux-musl"
+        ;;
+    Darwin)
+        shatool="shasum -a 256"
+        sha256sum="f564e948abadfc9e409eb1cd7babf24c6784057d5506c3b0a04cdd37cd830ae9"
+        platform="x86_64-apple-darwin"
+        ;;
+    *)
+        echo "Unrecognized platform $( uname -s )"
+        exit 1
+        ;;
+esac
+readonly shatool
+readonly sha256sum
+readonly platform
+
+readonly filename="sccache-$version-$platform"
+readonly tarball="$filename.tar.gz"
+
+cd .gitlab
+
+echo "$sha256sum  $tarball" > sccache.sha256sum
+curl -OL "https://github.com/mozilla/sccache/releases/download/$version/$tarball"
+$shatool --check sccache.sha256sum
+tar xf "$tarball"
+mv "$filename/sccache" .
diff --git a/.gitlab/ci/vcvarsall.ps1 b/.gitlab/ci/vcvarsall.ps1
new file mode 100755
index 0000000..57d3386
--- /dev/null
+++ b/.gitlab/ci/vcvarsall.ps1
@@ -0,0 +1,9 @@
+$erroractionpreference = "stop"
+
+cmd /c "`"$env:VCVARSALL`" $VCVARSPLATFORM -vcvars_ver=$VCVARSVERSION & set" |
+foreach {
+    if ($_ -match "=") {
+        $v = $_.split("=")
+        [Environment]::SetEnvironmentVariable($v[0], $v[1])
+    }
+}
diff --git a/.gitlab/os-linux.yml b/.gitlab/os-linux.yml
new file mode 100644
index 0000000..1c97377
--- /dev/null
+++ b/.gitlab/os-linux.yml
@@ -0,0 +1,210 @@
+# Linux-specific builder configurations and build commands
+
+## Base images
+
+### Release
+
+.release_linux:
+    image: "kitware/cmake:build-linux-x86_64-deps-2020-04-02@sha256:77e9ab183f34680990db9da5945473e288f0d6556bce79ecc1589670d656e157"
+
+    variables:
+        GIT_CLONE_PATH: "$CI_BUILDS_DIR/cmake ci"
+        LAUNCHER: "scl enable devtoolset-6 rh-python36 --"
+
+### Debian
+
+.debian10:
+    image: "kitware/cmake:ci-debian10-x86_64-2020-04-27"
+
+    variables:
+        GIT_CLONE_PATH: "$CI_BUILDS_DIR/cmake ci"
+
+.debian10_iwyu:
+    extends: .debian10
+
+    variables:
+        CMAKE_CONFIGURATION: debian10_iwyu
+        CTEST_NO_WARNINGS_ALLOWED: 1
+        CMake_SKIP_INSTALL: 1
+
+### Fedora
+
+.fedora31:
+    image: "kitware/cmake:ci-fedora31-x86_64-2020-06-01"
+
+    variables:
+        GIT_CLONE_PATH: "$CI_BUILDS_DIR/cmake ci"
+
+#### Lint builds
+
+.fedora31_tidy:
+    extends: .fedora31
+
+    variables:
+        CMAKE_CONFIGURATION: fedora31_tidy
+        CTEST_NO_WARNINGS_ALLOWED: 1
+        CMake_SKIP_INSTALL: 1
+
+.fedora31_sphinx:
+    extends: .fedora31
+
+    variables:
+        CMAKE_CONFIGURATION: fedora31_sphinx
+        CTEST_NO_WARNINGS_ALLOWED: 1
+        CTEST_SOURCE_SUBDIRECTORY: "Utilities/Sphinx"
+        CMake_SKIP_INSTALL: 1
+
+#### Build and test
+
+.fedora31_ninja:
+    extends: .fedora31
+
+    variables:
+        CMAKE_CONFIGURATION: fedora31_ninja
+        CTEST_NO_WARNINGS_ALLOWED: 1
+
+.fedora31_ninja_multi:
+    extends: .fedora31
+
+    variables:
+        CMAKE_CONFIGURATION: fedora31_ninja_multi
+        CTEST_NO_WARNINGS_ALLOWED: 1
+        CMAKE_GENERATOR: "Ninja Multi-Config"
+
+.fedora31_makefiles:
+    extends: .fedora31
+
+    variables:
+        CMAKE_CONFIGURATION: fedora31_makefiles
+        CTEST_NO_WARNINGS_ALLOWED: 1
+        CMAKE_GENERATOR: "Unix Makefiles"
+
+### CUDA builds
+
+.cuda10.2:
+    image: "kitware/cmake:ci-cuda10.2-x86_64-2020-06-11"
+
+    variables:
+        GIT_CLONE_PATH: "$CI_BUILDS_DIR/cmake ci"
+        CTEST_LABELS: "CUDA"
+
+.cuda10.2_nvidia:
+    extends: .cuda10.2
+
+    variables:
+        CMAKE_CONFIGURATION: cuda10.2_nvidia
+        CTEST_NO_WARNINGS_ALLOWED: 1
+
+## Tags
+
+.linux_builder_tags:
+    tags:
+        - build
+        - docker
+        - linux
+
+.linux_builder_tags_qt:
+    tags:
+        - build
+        - docker
+        - linux
+        - linux-3.17 # Needed to be able to load Fedora's Qt libraries.
+
+.linux_builder_tags_cuda:
+    tags:
+        - cuda-rt
+        - docker
+        - linux
+
+## Linux-specific scripts
+
+.before_script_linux: &before_script_linux
+    - .gitlab/ci/cmake.sh
+    - .gitlab/ci/ninja.sh
+    - export PATH=$PWD/.gitlab:$PWD/.gitlab/cmake/bin:$PATH
+    - cmake --version
+    - ninja --version
+
+.cmake_build_linux:
+    stage: build
+
+    script:
+        - *before_script_linux
+        - .gitlab/ci/sccache.sh
+        - sccache --start-server
+        - sccache --show-stats
+        - "$LAUNCHER ctest -VV -S .gitlab/ci/ctest_configure.cmake"
+        - "$LAUNCHER ctest -VV -S .gitlab/ci/ctest_build.cmake"
+        - sccache --show-stats
+
+    interruptible: true
+
+.cmake_test_linux:
+    stage: test
+
+    script:
+        - *before_script_linux
+        - "$LAUNCHER ctest --output-on-failure -V -S .gitlab/ci/ctest_test.cmake"
+
+    interruptible: true
+
+.cmake_build_release_linux:
+    stage: build
+
+    script:
+        # Bootstrap.
+        - mkdir build/
+        - cp -v Utilities/Release/linux/x86_64/cache.txt build/CMakeCache.txt
+        # Make sccache available.
+        - .gitlab/ci/sccache.sh
+        - export PATH=$PWD/.gitlab:$PATH
+        # Append sccache settings to the cache.
+        - echo "CMAKE_C_COMPILER_LAUNCHER:STRING=sccache" >> build/CMakeCache.txt
+        - echo "CMAKE_CXX_COMPILER_LAUNCHER:STRING=sccache" >> build/CMakeCache.txt
+        # CI settings.
+        - echo "CMake_TEST_INSTALL:BOOL=OFF" >> build/CMakeCache.txt
+        - echo "CMAKE_INSTALL_PREFIX:PATH=$PWD/build/install" >> build/CMakeCache.txt
+        - echo "CMAKE_SKIP_INSTALL_ALL_DEPENDENCY:BOOL=ON" >> build/CMakeCache.txt
+        # Bootstrap
+        - cd build/
+        - "$LAUNCHER ../bootstrap --parallel=$(nproc) --docdir=doc/cmake"
+        # FIXME: When CTest can drive an external CMake for the build as well,
+        # use the scripts here.
+        - "$LAUNCHER make -j$(nproc)"
+        # NOTE: This regex matches that used in the release build.
+        - "$LAUNCHER bin/ctest --output-on-failure -j$(nproc) -R '^(CMake\\.|CMakeLib\\.|CMakeServerLib\\.|RunCMake\\.ctest_memcheck)'"
+        # Make a package.
+        - bin/cpack -G TGZ
+        - bin/cpack -G STGZ
+        - sccache --show-stats
+
+    interruptible: true
+
+.cmake_test_linux_package:
+    stage: test-ext
+
+    script:
+        - *before_script_linux
+        # Make the CMake package available.
+        - mkdir -p build/install
+        - tar -C build/install --strip-components=1 -xzf build/cmake-*-Linux-x86_64.tar.gz
+        - .gitlab/ci/sccache.sh
+        - sccache --start-server
+        - sccache --show-stats
+        - "$LAUNCHER build/install/bin/ctest --output-on-failure -V -S .gitlab/ci/ctest_test_external.cmake"
+        - sccache --show-stats
+
+    interruptible: true
+
+.cmake_test_linux_external:
+    stage: test-ext
+
+    script:
+        - *before_script_linux
+        - .gitlab/ci/sccache.sh
+        - sccache --start-server
+        - sccache --show-stats
+        - "$LAUNCHER build/install/bin/ctest --output-on-failure -V -S .gitlab/ci/ctest_test_external.cmake"
+        - sccache --show-stats
+
+    interruptible: true
diff --git a/.gitlab/os-macos.yml b/.gitlab/os-macos.yml
new file mode 100644
index 0000000..9d123ec
--- /dev/null
+++ b/.gitlab/os-macos.yml
@@ -0,0 +1,115 @@
+# macOS-specific builder configurations and build commands
+
+## Base configurations
+
+.macos:
+    variables:
+        GIT_CLONE_PATH: "$CI_BUILDS_DIR/cmake ci ext/$CI_CONCURRENT_ID"
+        # TODO: Factor this out so that each job selects the Xcode version to
+        # use so that different versions can be tested in a single pipeline.
+        DEVELOPER_DIR: "/Applications/Xcode-11.5.app/Contents/Developer"
+
+### Build and test
+
+.macos_build:
+    extends: .macos
+
+    variables:
+        # Note that shell runners only support runners with a single
+        # concurrency level. We can't use `$CI_CONCURRENCY_ID` because this may
+        # change between the build and test stages which CMake doesn't support.
+        # Even if we could, it could change if other runners on the machine
+        # could run at the same time, so we drop it.
+        GIT_CLONE_PATH: "$CI_BUILDS_DIR/cmake ci"
+
+.macos_ninja:
+    extends: .macos_build
+
+    variables:
+        CMAKE_CONFIGURATION: macos_ninja
+        CTEST_NO_WARNINGS_ALLOWED: 1
+
+.macos_makefiles:
+    extends: .macos_build
+
+    variables:
+        CMAKE_CONFIGURATION: macos_makefiles
+        CTEST_NO_WARNINGS_ALLOWED: 1
+        CMAKE_GENERATOR: "Unix Makefiles"
+
+### External testing
+
+.macos_xcode:
+    extends: .macos
+
+    variables:
+        CMAKE_CONFIGURATION: macos_xcode
+        CMAKE_GENERATOR: Xcode
+
+## Tags
+
+.macos_builder_tags:
+    tags:
+        - cmake # Since this is a bare runner, pin to a project.
+        - macos
+        - shell
+        - xcode-11.5
+        - nonconcurrent
+
+.macos_builder_ext_tags:
+    tags:
+        - cmake # Since this is a bare runner, pin to a project.
+        - macos
+        - shell
+        - xcode-11.5
+        - concurrent
+
+## macOS-specific scripts
+
+.before_script_macos: &before_script_macos
+    - .gitlab/ci/cmake.sh
+    - .gitlab/ci/ninja.sh
+    - export PATH=$PWD/.gitlab:$PWD/.gitlab/cmake/bin:$PATH
+    - cmake --version
+    - ninja --version
+    # Download Qt
+    - cmake -P .gitlab/ci/download_qt.cmake
+    - export CMAKE_PREFIX_PATH=$PWD/.gitlab/qt
+
+.cmake_build_macos:
+    stage: build
+
+    script:
+        - *before_script_macos
+        - .gitlab/ci/sccache.sh
+        # Allow the server to already be running.
+        - "sccache --start-server || :"
+        - sccache --show-stats
+        - ctest -VV -S .gitlab/ci/ctest_configure.cmake
+        - ctest -VV -S .gitlab/ci/ctest_build.cmake
+        - sccache --show-stats
+
+    interruptible: true
+
+.cmake_test_macos:
+    stage: test
+
+    script:
+        - *before_script_macos
+        - ctest --output-on-failure -V -S .gitlab/ci/ctest_test.cmake
+
+    interruptible: true
+
+.cmake_test_macos_external:
+    stage: test-ext
+
+    script:
+        - *before_script_macos
+        - .gitlab/ci/sccache.sh
+        # Allow the server to already be running.
+        - "sccache --start-server || :"
+        - sccache --show-stats
+        - "$LAUNCHER build/install/CMake.app/Contents/bin/ctest --output-on-failure -V -S .gitlab/ci/ctest_test_external.cmake"
+        - sccache --show-stats
+
+    interruptible: true
diff --git a/.gitlab/os-windows.yml b/.gitlab/os-windows.yml
new file mode 100644
index 0000000..910a232
--- /dev/null
+++ b/.gitlab/os-windows.yml
@@ -0,0 +1,116 @@
+# Windows-specific builder configurations and build commands
+
+## Base configurations
+
+.windows:
+    variables:
+        GIT_CLONE_PATH: "$CI_BUILDS_DIR\\cmake ci ext\\$CI_CONCURRENT_ID"
+
+### Build and test
+
+.windows_build:
+    extends: .windows
+
+    variables:
+        # Note that shell runners only support runners with a single
+        # concurrency level. We can't use `$CI_CONCURRENCY_ID` because this may
+        # change between the build and test stages which CMake doesn't support.
+        # Even if we could, it could change if other runners on the machine
+        # could run at the same time, so we drop it.
+        GIT_CLONE_PATH: "$CI_BUILDS_DIR\\cmake ci"
+
+.windows_ninja:
+    extends: .windows_build
+
+    variables:
+        # Debug and RelWithDebinfo build types use the `/Zi` which results in
+        # uncacheable compiations.
+        # https://github.com/mozilla/sccache/issues/242
+        CMAKE_BUILD_TYPE: Release
+        CTEST_NO_WARNINGS_ALLOWED: 1
+
+.windows_vs2019_x64_ninja:
+    extends: .windows_ninja
+
+    variables:
+        CMAKE_CONFIGURATION: windows_vs2019_x64_ninja
+        VCVARSALL: "${VS160COMNTOOLS}\\..\\..\\VC\\Auxiliary\\Build\\vcvarsall.bat"
+        VCVARSPLATFORM: "x64"
+        VCVARSVERSION: "14.26"
+
+### External testing
+
+.windows_vs2019_x64:
+    extends: .windows
+
+    variables:
+        CMAKE_CONFIGURATION: windows_vs2019_x64
+        CMAKE_GENERATOR: "Visual Studio 16 2019"
+        CMAKE_GENERATOR_PLATFORM: "x64"
+        CMAKE_GENERATOR_TOOLSET: "v142,version=14.26"
+
+## Tags
+
+.windows_builder_tags:
+    tags:
+        - cmake # Since this is a bare runner, pin to a project.
+        - windows
+        - shell
+        - vs2019
+        - msvc-19.25
+        - nonconcurrent
+
+.windows_builder_ext_tags:
+    tags:
+        - cmake # Since this is a bare runner, pin to a project.
+        - windows
+        - shell
+        - vs2019
+        - msvc-19.25
+        - concurrent
+
+## Windows-specific scripts
+
+.before_script_windows: &before_script_windows
+    - Invoke-Expression -Command .gitlab/ci/cmake.ps1
+    - Invoke-Expression -Command .gitlab/ci/ninja.ps1
+    - $pwdpath = $pwd.Path
+    - Set-Item -Force -Path "env:PATH" -Value "$pwdpath\.gitlab;$pwdpath\.gitlab\cmake\bin;$env:PATH"
+    - cmake --version
+    - ninja --version
+    - cmake -P .gitlab/ci/download_qt.cmake
+    - Set-Item -Force -Path "env:PATH" -Value "$pwdpath\.gitlab\qt\bin;$env:PATH"
+
+.cmake_build_windows:
+    stage: build
+
+    script:
+        - *before_script_windows
+        - Set-Item -Force -Path "env:PATH" -Value "$env:PATH;$env:SCCACHE_PATH"
+        - Invoke-Expression -Command .gitlab/ci/vcvarsall.ps1
+        - sccache --start-server
+        - sccache --show-stats
+        - ctest -VV -S .gitlab/ci/ctest_configure.cmake
+        - ctest -VV -S .gitlab/ci/ctest_build.cmake
+        - sccache --show-stats
+        - sccache --stop-server
+
+    interruptible: true
+
+.cmake_test_windows:
+    stage: test
+
+    script:
+        - *before_script_windows
+        - Invoke-Expression -Command .gitlab/ci/vcvarsall.ps1
+        - ctest --output-on-failure -V -S .gitlab/ci/ctest_test.cmake
+
+    interruptible: true
+
+.cmake_test_windows_external:
+    stage: test-ext
+
+    script:
+        - build/install/bin/ctest --output-on-failure -V -S .gitlab/ci/ctest_test_external.cmake
+
+    interruptible: true
diff --git a/.gitlab/rules.yml b/.gitlab/rules.yml
new file mode 100644
index 0000000..88756eb
--- /dev/null
+++ b/.gitlab/rules.yml
@@ -0,0 +1,18 @@
+# Rules for where jobs can run
+
+.run_manually:
+    rules:
+        - if: '$CI_PROJECT_PATH == "cmake/cmake"'
+          when: delayed
+          start_in: 5 minutes
+        - if: '$CI_MERGE_REQUEST_ID'
+          when: manual
+        - when: never
+
+.run_automatically:
+    rules:
+        - if: '$CI_PROJECT_PATH == "cmake/cmake"'
+          when: on_success
+        - if: '$CI_MERGE_REQUEST_ID'
+          when: on_success
+        - when: never
diff --git a/Auxiliary/CMakeLists.txt b/Auxiliary/CMakeLists.txt
index 53cf2c5..c0aebef 100644
--- a/Auxiliary/CMakeLists.txt
+++ b/Auxiliary/CMakeLists.txt
@@ -1,4 +1,16 @@
-install(DIRECTORY vim/indent vim/syntax DESTINATION ${CMAKE_DATA_DIR}/editors/vim)
-install(FILES cmake-mode.el DESTINATION ${CMAKE_DATA_DIR}/editors/emacs)
+# Install Vim files to a typical system integration directory.
+# Packagers can set CMake_INSTALL_VIMFILES_DIR to control this.
+if(NOT CMake_INSTALL_VIMFILES_DIR)
+  set(CMake_INSTALL_VIMFILES_DIR ${CMAKE_XDGDATA_DIR}/vim/vimfiles)
+endif()
+install(DIRECTORY vim/indent vim/syntax DESTINATION ${CMake_INSTALL_VIMFILES_DIR})
+
+# Install Emacs files to a typical system integration directory.
+# Packagers can set CMake_INSTALL_EMACS_DIR to control this.
+if(NOT CMake_INSTALL_EMACS_DIR)
+  set(CMake_INSTALL_EMACS_DIR ${CMAKE_XDGDATA_DIR}/emacs/site-lisp)
+endif()
+install(FILES cmake-mode.el DESTINATION ${CMake_INSTALL_EMACS_DIR})
+
 install(FILES cmake.m4 DESTINATION ${CMAKE_XDGDATA_DIR}/aclocal)
 add_subdirectory (bash-completion)
diff --git a/Auxiliary/bash-completion/CMakeLists.txt b/Auxiliary/bash-completion/CMakeLists.txt
index c0a8899..93b6ffd 100644
--- a/Auxiliary/bash-completion/CMakeLists.txt
+++ b/Auxiliary/bash-completion/CMakeLists.txt
@@ -1,8 +1,21 @@
-# Always install completion file in local dir
-# in order to be sure to always be able to install
-# in a local user directory rooted in a single directory.
-# packager should either patch that out or
-# add symlinks to the files in appropriate places
-#  /etc/bash_completion.d/
-#  DATADIR/completions (may be /usr/share/<package>/completions
-install(FILES cmake cpack ctest DESTINATION ${CMAKE_DATA_DIR}/completions)
+# We need to integrate into the system install, or this will silently fail to
+# accomplish anything at all, and packagers won't even know it exists. Use the
+# `<sharedir>/bash-completion/completions/` hierarchy by default, rooted in
+# CMake's XDGDATA_DIR definition of the sharedir. This works with installation
+# to `/usr` or `/usr/local` (or any prefix which bash-completion is configured
+# with) as well as a simple installation by a local user into their home
+# directory *if* the prefix is `$HOME/.local` since `.local/share/` is part of
+# the bash-completion search path too.
+# For more complex installations, packagers can set CMake_INSTALL_BASH_COMP_DIR
+# to another system location.
+
+if(NOT CMake_INSTALL_BASH_COMP_DIR)
+  if(CMAKE_BASH_COMP_DIR)
+    # Honor previous customization option.
+    set(CMake_INSTALL_BASH_COMP_DIR "${CMAKE_BASH_COMP_DIR}")
+  else()
+    # Default.
+    set(CMake_INSTALL_BASH_COMP_DIR ${CMAKE_XDGDATA_DIR}/bash-completion/completions)
+  endif()
+endif()
+install(FILES cmake cpack ctest DESTINATION ${CMake_INSTALL_BASH_COMP_DIR})
diff --git a/Auxiliary/vim/syntax/cmake.vim b/Auxiliary/vim/syntax/cmake.vim
index 0676f7e..2d63eb0 100644
--- a/Auxiliary/vim/syntax/cmake.vim
+++ b/Auxiliary/vim/syntax/cmake.vim
@@ -170,6 +170,7 @@
             \ FRAMEWORK_VERSION
             \ Fortran_FORMAT
             \ Fortran_MODULE_DIRECTORY
+            \ Fortran_PREPROCESS
             \ GENERATED
             \ GENERATOR_FILE_NAME
             \ GENERATOR_IS_MULTI_CONFIG
@@ -1019,6 +1020,7 @@
             \ CMAKE_Fortran_MODULE_DIRECTORY
             \ CMAKE_Fortran_OUTPUT_EXTENSION
             \ CMAKE_Fortran_PLATFORM_ID
+            \ CMAKE_Fortran_PREPROCESS
             \ CMAKE_Fortran_SIMULATE_ID
             \ CMAKE_Fortran_SIMULATE_VERSION
             \ CMAKE_Fortran_SIZEOF_DATA_PTR
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 0d6a38c..2d860d4 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -37,7 +37,7 @@
   if(CMAKE_SYSTEM_NAME STREQUAL "HP-UX")
     message(FATAL_ERROR
       "CMake no longer compiles on HP-UX.  See\n"
-      "  https://gitlab.kitware.com/cmake/cmake/issues/17137\n"
+      "  https://gitlab.kitware.com/cmake/cmake/-/issues/17137\n"
       "Use CMake 3.9 or lower instead."
       )
   endif()
@@ -108,6 +108,11 @@
   endif()
 endif()
 
+# Inform STL library header wrappers whether to use system versions.
+configure_file(${CMake_SOURCE_DIR}/Utilities/std/cmSTL.hxx.in
+  ${CMake_BINARY_DIR}/Utilities/cmSTL.hxx
+  @ONLY)
+
 # set the internal encoding of CMake to UTF-8
 set(KWSYS_ENCODING_DEFAULT_CODEPAGE CP_UTF8)
 
@@ -154,7 +159,7 @@
 
   # Allow the user to enable/disable all system utility library options by
   # defining CMAKE_USE_SYSTEM_LIBRARIES or CMAKE_USE_SYSTEM_LIBRARY_${util}.
-  set(UTILITIES BZIP2 CURL EXPAT FORM JSONCPP LIBARCHIVE LIBLZMA LIBRHASH LIBUV ZLIB ZSTD)
+  set(UTILITIES BZIP2 CURL EXPAT FORM JSONCPP LIBARCHIVE LIBLZMA LIBRHASH LIBUV NGHTTP2 ZLIB ZSTD)
   foreach(util ${UTILITIES})
     if(NOT DEFINED CMAKE_USE_SYSTEM_LIBRARY_${util}
         AND DEFINED CMAKE_USE_SYSTEM_LIBRARIES)
@@ -192,6 +197,8 @@
     "${CMAKE_USE_SYSTEM_LIBRARY_ZSTD}" "NOT CMAKE_USE_SYSTEM_LIBARCHIVE" ON)
   CMAKE_DEPENDENT_OPTION(CMAKE_USE_SYSTEM_LIBLZMA "Use system-installed liblzma"
     "${CMAKE_USE_SYSTEM_LIBRARY_LIBLZMA}" "NOT CMAKE_USE_SYSTEM_LIBARCHIVE" ON)
+  CMAKE_DEPENDENT_OPTION(CMAKE_USE_SYSTEM_NGHTTP2 "Use system-installed nghttp2"
+    "${CMAKE_USE_SYSTEM_LIBRARY_NGHTTP2}" "NOT CMAKE_USE_SYSTEM_CURL" ON)
   option(CMAKE_USE_SYSTEM_FORM "Use system-installed libform" "${CMAKE_USE_SYSTEM_LIBRARY_FORM}")
   option(CMAKE_USE_SYSTEM_JSONCPP "Use system-installed jsoncpp" "${CMAKE_USE_SYSTEM_LIBRARY_JSONCPP}")
   option(CMAKE_USE_SYSTEM_LIBRHASH "Use system-installed librhash" "${CMAKE_USE_SYSTEM_LIBRARY_LIBRHASH}")
@@ -335,6 +342,9 @@
 macro (CMAKE_BUILD_UTILITIES)
   find_package(Threads)
 
+  # Suppress unnecessary checks in third-party code.
+  include(Utilities/cmThirdPartyChecks.cmake)
+
   #---------------------------------------------------------------------
   # Create the kwsys library for CMake.
   set(KWSYS_NAMESPACE cmsys)
@@ -351,6 +361,21 @@
   if(CMake_NO_CXX_STANDARD)
     set(KWSYS_CXX_STANDARD "")
   endif()
+  if(WIN32)
+    # FIXME: Teach KWSys to hard-code these checks on Windows.
+    set(KWSYS_C_HAS_CLOCK_GETTIME_MONOTONIC_COMPILED 0)
+    set(KWSYS_C_HAS_PTRDIFF_T_COMPILED 1)
+    set(KWSYS_CXX_HAS_ENVIRON_IN_STDLIB_H_COMPILED 1)
+    set(KWSYS_CXX_HAS_RLIMIT64_COMPILED 0)
+    set(KWSYS_CXX_HAS_SETENV_COMPILED 0)
+    set(KWSYS_CXX_HAS_UNSETENV_COMPILED 0)
+    set(KWSYS_CXX_HAS_UTIMENSAT_COMPILED 0)
+    set(KWSYS_CXX_HAS_UTIMES_COMPILED 0)
+    set(KWSYS_CXX_STAT_HAS_ST_MTIM_COMPILED 0)
+    set(KWSYS_CXX_STAT_HAS_ST_MTIMESPEC_COMPILED 0)
+    set(KWSYS_STL_HAS_WSTRING_COMPILED 1)
+    set(KWSYS_SYS_HAS_IFADDRS_H 0)
+  endif()
   add_subdirectory(Source/kwsys)
   set(kwsys_folder "Utilities/KWSys")
   CMAKE_SET_TARGET_FOLDER(${KWSYS_NAMESPACE} "${kwsys_folder}")
@@ -374,10 +399,13 @@
     include_directories(SYSTEM "${CMake_SOURCE_DIR}/Utilities/std")
   endif()
 
-  include_directories(
-    ${CMake_BINARY_DIR}/Utilities
-    ${CMake_SOURCE_DIR}/Utilities
-    )
+  include_directories("${CMake_BINARY_DIR}/Utilities")
+  if ((CMAKE_SYSTEM_NAME STREQUAL "AIX" OR CMAKE_SYSTEM_NAME STREQUAL "OS400") AND CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
+    # using -isystem option generate error "template with C linkage"
+    include_directories("${CMake_SOURCE_DIR}/Utilities")
+  else()
+    include_directories(SYSTEM "${CMake_SOURCE_DIR}/Utilities")
+  endif()
 
   #---------------------------------------------------------------------
   # Build CMake std library for CMake and CTest.
@@ -430,6 +458,13 @@
   else()
     set(CMAKE_ZLIB_INCLUDES ${CMake_SOURCE_DIR}/Utilities)
     set(CMAKE_ZLIB_LIBRARIES cmzlib)
+    set(WITHOUT_ZLIB_DLL "")
+    set(WITHOUT_ZLIB_DLL_WITH_LIB cmzlib)
+    set(ZLIB_DLL "")
+    set(ZLIB_DLL_WITH_LIB cmzlib)
+    set(ZLIB_WINAPI "")
+    set(ZLIB_WINAPI_COMPILED 0)
+    set(ZLIB_WINAPI_WITH_LIB cmzlib)
     add_subdirectory(Utilities/cmzlib)
     CMAKE_SET_TARGET_FOLDER(cmzlib "Utilities/3rdParty")
   endif()
@@ -465,9 +500,19 @@
       set(CURL_CA_PATH "" CACHE PATH "Path to SSL CA Certificate Directory")
       mark_as_advanced(CURL_CA_BUNDLE CURL_CA_PATH)
     endif()
+    if(NOT CMAKE_USE_SYSTEM_NGHTTP2)
+      # Tell curl's FindNGHTTP2 module to use our library.
+      set(NGHTTP2_LIBRARY cmnghttp2)
+      set(NGHTTP2_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/Utilities/cmnghttp2/lib/includes)
+    endif()
     add_subdirectory(Utilities/cmcurl)
     CMAKE_SET_TARGET_FOLDER(cmcurl "Utilities/3rdParty")
     CMAKE_SET_TARGET_FOLDER(LIBCURL "Utilities/3rdParty")
+    if(NOT CMAKE_USE_SYSTEM_NGHTTP2)
+      # Configure after curl to re-use some check results.
+      add_subdirectory(Utilities/cmnghttp2)
+      CMAKE_SET_TARGET_FOLDER(cmnghttp2 "Utilities/3rdParty")
+    endif()
   endif()
 
   #---------------------------------------------------------------------
@@ -496,6 +541,11 @@
       set(BZIP2_INCLUDE_DIR
         "${CMAKE_CURRENT_SOURCE_DIR}/Utilities/cmbzip2")
       set(BZIP2_LIBRARIES cmbzip2)
+      set(BZIP2_NEED_PREFIX "")
+      set(USE_BZIP2_DLL "")
+      set(USE_BZIP2_DLL_WITH_LIB cmbzip2)
+      set(USE_BZIP2_STATIC "")
+      set(USE_BZIP2_STATIC_WITH_LIB cmbzip2)
       add_subdirectory(Utilities/cmbzip2)
       CMAKE_SET_TARGET_FOLDER(cmbzip2 "Utilities/3rdParty")
     endif()
@@ -547,21 +597,25 @@
     set(ZLIB_INCLUDE_DIR ${CMAKE_ZLIB_INCLUDES})
     set(ZLIB_LIBRARY ${CMAKE_ZLIB_LIBRARIES})
     add_definitions(-DLIBARCHIVE_STATIC)
+    set(ENABLE_MBEDTLS OFF CACHE INTERNAL "Enable use of mbed TLS")
     set(ENABLE_NETTLE OFF CACHE INTERNAL "Enable use of Nettle")
     set(ENABLE_OPENSSL ${CMAKE_USE_OPENSSL} CACHE INTERNAL "Enable use of OpenSSL")
+    set(ENABLE_LIBB2 OFF CACHE INTERNAL "Enable the use of the system LIBB2 library if found")
     set(ENABLE_LZMA ON CACHE INTERNAL "Enable the use of the system LZMA library if found")
     set(ENABLE_LZ4 OFF CACHE INTERNAL "Enable the use of the system LZ4 library if found")
     set(ENABLE_LZO OFF CACHE INTERNAL "Enable the use of the system LZO library if found")
     set(ENABLE_ZLIB ON CACHE INTERNAL "Enable the use of the system ZLIB library if found")
     set(ENABLE_BZip2 ON CACHE INTERNAL "Enable the use of the system BZip2 library if found")
+    set(ENABLE_ZSTD ON CACHE INTERNAL "Enable the use of the system zstd library if found")
     set(ENABLE_LIBXML2 OFF CACHE INTERNAL "Enable the use of the system libxml2 library if found")
-    set(ENABLE_EXPAT ON CACHE INTERNAL "Enable the use of the system EXPAT library if found")
+    set(ENABLE_EXPAT OFF CACHE INTERNAL "Enable the use of the system EXPAT library if found")
     set(ENABLE_PCREPOSIX OFF CACHE INTERNAL "Enable the use of the system PCREPOSIX library if found")
     set(ENABLE_LibGCC OFF CACHE INTERNAL "Enable the use of the system LibGCC library if found")
     set(ENABLE_XATTR OFF CACHE INTERNAL "Enable extended attribute support")
     set(ENABLE_ACL OFF CACHE INTERNAL "Enable ACL support")
     set(ENABLE_ICONV OFF CACHE INTERNAL "Enable iconv support")
     set(ENABLE_CNG OFF CACHE INTERNAL "Enable the use of CNG(Crypto Next Generation)")
+    SET(POSIX_REGEX_LIB "" CACHE INTERNAL "Choose what library should provide POSIX regular expression support")
     add_subdirectory(Utilities/cmlibarchive)
     CMAKE_SET_TARGET_FOLDER(cmlibarchive "Utilities/3rdParty")
     set(CMAKE_TAR_LIBRARIES cmlibarchive ${BZIP2_LIBRARIES})
@@ -677,10 +731,15 @@
     include(${CMake_SOURCE_DIR}/Tests/CMakeInstall.cmake)
   endif()
 
-  # no clue why we are testing for this here
-  include(CheckSymbolExists)
-  CHECK_SYMBOL_EXISTS(unsetenv "stdlib.h" HAVE_UNSETENV)
-  CHECK_SYMBOL_EXISTS(environ "stdlib.h" HAVE_ENVIRON_NOT_REQUIRE_PROTOTYPE)
+  # Checks for cmSystemTools.
+  if(WIN32)
+    set(HAVE_UNSETENV 0)
+    set(HAVE_ENVIRON_NOT_REQUIRE_PROTOTYPE 1)
+  else()
+    include(CheckSymbolExists)
+    CHECK_SYMBOL_EXISTS(unsetenv "stdlib.h" HAVE_UNSETENV)
+    CHECK_SYMBOL_EXISTS(environ "stdlib.h" HAVE_ENVIRON_NOT_REQUIRE_PROTOTYPE)
+  endif()
 endif()
 
 # CMAKE_TESTS_CDASH_SERVER: CDash server used by CMake/Tests.
diff --git a/CONTRIBUTING.rst b/CONTRIBUTING.rst
index 7983be1..3006214 100644
--- a/CONTRIBUTING.rst
+++ b/CONTRIBUTING.rst
@@ -11,11 +11,11 @@
 
 CMake is maintained and supported by `Kitware`_ and developed in
 collaboration with a productive community of contributors.
-Please subscribe and post to the `CMake Developers List`_ to raise
+Please post to the ``Development`` category of the `CMake Forum`_ to raise
 discussion of development topics.
 
 .. _`Kitware`: http://www.kitware.com/cmake
-.. _`CMake Developers List`: https://cmake.org/mailman/listinfo/cmake-developers
+.. _`CMake Forum`: https://discourse.cmake.org
 
 Patches
 =======
diff --git a/CTestConfig.cmake b/CTestConfig.cmake
index 020582e..476a1c6 100644
--- a/CTestConfig.cmake
+++ b/CTestConfig.cmake
@@ -1,10 +1,14 @@
 # Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
 # file Copyright.txt or https://cmake.org/licensing for details.
 
+# If changing this file, also update Utilities/Sphinx/CTestConfig.cmake
+
 set(CTEST_PROJECT_NAME "CMake")
 set(CTEST_NIGHTLY_START_TIME "1:00:00 UTC")
 
-set(CTEST_DROP_METHOD "http")
+if(NOT CTEST_DROP_METHOD STREQUAL "https")
+  set(CTEST_DROP_METHOD "http")
+endif()
 set(CTEST_DROP_SITE "open.cdash.org")
 set(CTEST_DROP_LOCATION "/submit.php?project=CMake")
 set(CTEST_DROP_SITE_CDASH TRUE)
diff --git a/CTestCustom.cmake.in b/CTestCustom.cmake.in
index fb8e099..4c8267d 100644
--- a/CTestCustom.cmake.in
+++ b/CTestCustom.cmake.in
@@ -11,6 +11,7 @@
   "warning: \\(Long double usage is reported only once for each file"
   "warning: To disable this warning use"
   "could not be inlined"
+  "libcmexpat.*has no symbols"
   "libcmcurl.*has no symbols"
   "not sorted slower link editing will result"
   "stl_deque.h:479"
@@ -64,6 +65,7 @@
   "ld: warning .*/libgcc.a archive's cputype"
   "ld: warning: ignoring file .*/libgcc.a, file was built for archive which is not the architecture being linked"
   "ld: warning: in .*/libgcc.a, file is not of required architecture"
+  "ld: warning: symbol .(deflate|inflate)_copyright. has differing sizes" # system libz and QtCore disagree
   "warning.*This version of Mac OS X is unsupported"
   "clang.*: warning: argument unused during compilation: .-g"
   "note: in expansion of macro" # diagnostic context note
@@ -80,7 +82,7 @@
   "compilation completed with warnings" # PGI
   "[0-9]+ Warning\\(s\\) detected" # SunPro
 
-# scanbuild exceptions
+  # scanbuild exceptions
   "char_traits.h:.*: warning: Null pointer argument in call to string length function"
   "stl_construct.h:.*: warning: Forming reference to null pointer"
   ".*stl_uninitialized.h:75:19: warning: Forming reference to null pointer.*"
@@ -99,6 +101,9 @@
   "liblzma/common/index_encoder.c:[0-9]+:[0-9]+: warning: Value stored to .* during its initialization is never read"
   "libuv/src/.*:[0-9]+:[0-9]+: warning: Dereference of null pointer"
   "libuv/src/.*:[0-9]+:[0-9]+: warning: The left operand of '==' is a garbage value"
+  "libuv/src/.*:[0-9]+:[0-9]+: warning: 1st function call argument is an uninitialized value"
+  "nghttp2/lib/.*:[0-9]+:[0-9]+: warning: Dereference of null pointer"
+  "nghttp2/lib/.*:[0-9]+:[0-9]+: warning: Value stored to .* is never read"
   )
 
 if(NOT "@CMAKE_GENERATOR@" MATCHES "Xcode")
diff --git a/Help/command/DEVICE_LINK_OPTIONS.txt b/Help/command/DEVICE_LINK_OPTIONS.txt
new file mode 100644
index 0000000..3f0226f
--- /dev/null
+++ b/Help/command/DEVICE_LINK_OPTIONS.txt
@@ -0,0 +1,11 @@
+
+When a device link step is involved, which is controlled by
+:prop_tgt:`CUDA_SEPARABLE_COMPILATION` and
+:prop_tgt:`CUDA_RESOLVE_DEVICE_SYMBOLS` properties and policy :policy:`CMP0105`,
+the raw options will be delivered to the host and device link steps (wrapped in
+``-Xcompiler`` or equivalent for device link). Options wrapped with
+``$<DEVICE_LINK:...>``
+:manual:`generator expression <cmake-generator-expressions(7)>` will be used
+only for the device link step. Options wrapped with ``$<HOST_LINK:...>``
+:manual:`generator expression <cmake-generator-expressions(7)>` will be used
+only for the host link step.
diff --git a/Help/command/FIND_XXX.txt b/Help/command/FIND_XXX.txt
index 42bf52b..4a62c5b 100644
--- a/Help/command/FIND_XXX.txt
+++ b/Help/command/FIND_XXX.txt
@@ -15,6 +15,7 @@
              [PATHS path1 [path2 ... ENV var]]
              [PATH_SUFFIXES suffix1 [suffix2 ...]]
              [DOC "cache documentation string"]
+             [REQUIRED]
              [NO_DEFAULT_PATH]
              [NO_PACKAGE_ROOT_PATH]
              [NO_CMAKE_PATH]
@@ -31,8 +32,9 @@
 of this command.
 If the |SEARCH_XXX| is found the result is stored in the variable
 and the search will not be repeated unless the variable is cleared.
-If nothing is found, the result will be
-``<VAR>-NOTFOUND``, and the search will be attempted again the
+If nothing is found, the result will be ``<VAR>-NOTFOUND``.
+The ``REQUIRED`` option stops processing with an error message if nothing
+is found, otherwise the search will be attempted again the
 next time |FIND_XXX| is invoked with the same variable.
 
 Options include:
@@ -57,6 +59,9 @@
 ``DOC``
   Specify the documentation string for the ``<VAR>`` cache entry.
 
+``REQUIRED``
+  Stop processing with an error message if nothing is found.
+
 If ``NO_DEFAULT_PATH`` is specified, then no additional paths are
 added to the search.
 If ``NO_DEFAULT_PATH`` is not specified, the search process is as follows:
@@ -138,6 +143,10 @@
    * |CMAKE_SYSTEM_XXX_PATH|
    * |CMAKE_SYSTEM_XXX_MAC_PATH|
 
+   The platform paths that these variables contain are locations that
+   typically include installed software. An example being ``/usr/local`` for
+   UNIX based platforms.
+
 7. Search the paths specified by the PATHS option
    or in the short-hand version of the command.
    These are typically hard-coded guesses.
diff --git a/Help/command/add_compile_definitions.rst b/Help/command/add_compile_definitions.rst
index e10aba0..48e33be 100644
--- a/Help/command/add_compile_definitions.rst
+++ b/Help/command/add_compile_definitions.rst
@@ -1,6 +1,8 @@
 add_compile_definitions
 -----------------------
 
+.. versionadded:: 3.12
+
 Add preprocessor definitions to the compilation of source files.
 
 .. code-block:: cmake
diff --git a/Help/command/add_compile_options.rst b/Help/command/add_compile_options.rst
index 43805c3..36f403c 100644
--- a/Help/command/add_compile_options.rst
+++ b/Help/command/add_compile_options.rst
@@ -46,3 +46,6 @@
 and :command:`include_directories`.
 
 The command :command:`target_compile_options` adds target-specific options.
+
+The source file property :prop_sf:`COMPILE_OPTIONS` adds options to one
+source file.
diff --git a/Help/command/add_executable.rst b/Help/command/add_executable.rst
index 0a7d7e1..e073228 100644
--- a/Help/command/add_executable.rst
+++ b/Help/command/add_executable.rst
@@ -1,8 +1,15 @@
 add_executable
 --------------
 
+.. only:: html
+
+  .. contents::
+
 Add an executable to the project using the specified source files.
 
+Normal Executables
+^^^^^^^^^^^^^^^^^^
+
 .. code-block:: cmake
 
   add_executable(<name> [WIN32] [MACOSX_BUNDLE]
@@ -45,7 +52,8 @@
 pre-processed, and you want to have the original sources reachable from
 within IDE.
 
---------------------------------------------------------------------------
+Imported Executables
+^^^^^^^^^^^^^^^^^^^^
 
 .. code-block:: cmake
 
@@ -65,7 +73,8 @@
 the main executable file on disk.  See documentation of the ``IMPORTED_*``
 properties for more information.
 
---------------------------------------------------------------------------
+Alias Executables
+^^^^^^^^^^^^^^^^^
 
 .. code-block:: cmake
 
@@ -74,8 +83,13 @@
 Creates an :ref:`Alias Target <Alias Targets>`, such that ``<name>`` can
 be used to refer to ``<target>`` in subsequent commands.  The ``<name>``
 does not appear in the generated buildsystem as a make target.  The
-``<target>`` may not be a non-``GLOBAL``
-:ref:`Imported Target <Imported Targets>` or an ``ALIAS``.
+``<target>`` may not be an ``ALIAS``.
+
+An ``ALIAS`` to a non-``GLOBAL`` :ref:`Imported Target <Imported Targets>`
+has scope in the directory in which the alias is created and below.
+The :prop_tgt:`ALIAS_GLOBAL` target property can be used to check if the
+alias is global or not.
+
 ``ALIAS`` targets can be used as targets to read properties
 from, executables for custom commands and custom targets.  They can also be
 tested for existence with the regular :command:`if(TARGET)` subcommand.
diff --git a/Help/command/add_library.rst b/Help/command/add_library.rst
index 7274e44..f3df631 100644
--- a/Help/command/add_library.rst
+++ b/Help/command/add_library.rst
@@ -64,42 +64,6 @@
 pre-processed, and you want to have the original sources reachable from
 within IDE.
 
-Imported Libraries
-^^^^^^^^^^^^^^^^^^
-
-.. code-block:: cmake
-
-  add_library(<name> <SHARED|STATIC|MODULE|OBJECT|UNKNOWN> IMPORTED
-              [GLOBAL])
-
-An :ref:`IMPORTED library target <Imported Targets>` references a library
-file located outside the project.  No rules are generated to build it, and
-the :prop_tgt:`IMPORTED` target property is ``True``.  The target name has
-scope in the directory in which it is created and below, but the ``GLOBAL``
-option extends visibility.  It may be referenced like any target built
-within the project.  ``IMPORTED`` libraries are useful for convenient
-reference from commands like :command:`target_link_libraries`.  Details
-about the imported library are specified by setting properties whose names
-begin in ``IMPORTED_`` and ``INTERFACE_``.
-
-The most important properties are:
-
-* :prop_tgt:`IMPORTED_LOCATION` (and its per-configuration
-  variant :prop_tgt:`IMPORTED_LOCATION_<CONFIG>`) which specifies the
-  location of the main library file on disk.
-* :prop_tgt:`IMPORTED_OBJECTS` (and :prop_tgt:`IMPORTED_OBJECTS_<CONFIG>`)
-  for object libraries, specifies the locations of object files on disk.
-* :prop_tgt:`PUBLIC_HEADER` files to be installed during :command:`install` invocation
-
-See documentation of the ``IMPORTED_*`` and ``INTERFACE_*`` properties
-for more information.
-
-An ``UNKNOWN`` library type is typically only used in the implementation of
-:ref:`Find Modules`.  It allows the path to an imported library (often found
-using the :command:`find_library` command) to be used without having to know
-what type of library it is.  This is especially useful on Windows where a
-static library and a DLL's import library both have the same file extension.
-
 Object Libraries
 ^^^^^^^^^^^^^^^^
 
@@ -129,38 +93,19 @@
 consider adding at least one real source file to any target that references
 ``$<TARGET_OBJECTS:objlib>``.
 
-Alias Libraries
-^^^^^^^^^^^^^^^
-
-.. code-block:: cmake
-
-  add_library(<name> ALIAS <target>)
-
-Creates an :ref:`Alias Target <Alias Targets>`, such that ``<name>`` can be
-used to refer to ``<target>`` in subsequent commands.  The ``<name>`` does
-not appear in the generated buildsystem as a make target.  The ``<target>``
-may not be a non-``GLOBAL`` :ref:`Imported Target <Imported Targets>` or an
-``ALIAS``.
-``ALIAS`` targets can be used as linkable targets and as targets to
-read properties from.  They can also be tested for existence with the
-regular :command:`if(TARGET)` subcommand.  The ``<name>`` may not be used
-to modify properties of ``<target>``, that is, it may not be used as the
-operand of :command:`set_property`, :command:`set_target_properties`,
-:command:`target_link_libraries` etc.  An ``ALIAS`` target may not be
-installed or exported.
-
 Interface Libraries
 ^^^^^^^^^^^^^^^^^^^
 
 .. code-block:: cmake
 
-  add_library(<name> INTERFACE [IMPORTED [GLOBAL]])
+  add_library(<name> INTERFACE)
 
-Creates an :ref:`Interface Library <Interface Libraries>`.  An ``INTERFACE``
-library target does not directly create build output, though it may
-have properties set on it and it may be installed, exported and
-imported. Typically the ``INTERFACE_*`` properties are populated on
-the interface target using the commands:
+Creates an :ref:`Interface Library <Interface Libraries>`.
+An ``INTERFACE`` library target does not compile sources and does
+not produce a library artifact on disk.  However, it may have
+properties set on it and it may be installed and exported.
+Typically, ``INTERFACE_*`` properties are populated on an interface
+target using the commands:
 
 * :command:`set_property`,
 * :command:`target_link_libraries(INTERFACE)`,
@@ -173,10 +118,108 @@
 and then it is used as an argument to :command:`target_link_libraries`
 like any other target.
 
-An ``INTERFACE`` :ref:`Imported Target <Imported Targets>` may also be
-created with this signature.  An ``IMPORTED`` library target references a
-library defined outside the project.  The target name has scope in the
-directory in which it is created and below, but the ``GLOBAL`` option
-extends visibility.  It may be referenced like any target built within
-the project.  ``IMPORTED`` libraries are useful for convenient reference
-from commands like :command:`target_link_libraries`.
+An interface library created with the above signature has no source files
+itself and is not included as a target in the generated buildsystem.
+
+Since CMake 3.19, an interface library target may be created with
+source files:
+
+.. code-block:: cmake
+
+  add_library(<name> INTERFACE [<source>...] [EXCLUDE_FROM_ALL])
+
+Source files may be listed directly in the ``add_library`` call or added
+later by calls to :command:`target_sources` with the ``PRIVATE`` or
+``PUBLIC`` keywords.
+
+If an interface library has source files (i.e. the :prop_tgt:`SOURCES`
+target property is set), it will appear in the generated buildsystem
+as a build target much like a target defined by the
+:command:`add_custom_target` command.  It does not compile any sources,
+but does contain build rules for custom commands created by the
+:command:`add_custom_command` command.
+
+.. note::
+  In most command signatures where the ``INTERFACE`` keyword appears,
+  the items listed after it only become part of that target's usage
+  requirements and are not part of the target's own settings.  However,
+  in this signature of ``add_library``, the ``INTERFACE`` keyword refers
+  to the library type only.  Sources listed after it in the ``add_library``
+  call are ``PRIVATE`` to the interface library and do not appear in its
+  :prop_tgt:`INTERFACE_SOURCES` target property.
+
+Imported Libraries
+^^^^^^^^^^^^^^^^^^
+
+.. code-block:: cmake
+
+  add_library(<name> <type> IMPORTED [GLOBAL])
+
+Creates an :ref:`IMPORTED library target <Imported Targets>` called ``<name>``.
+No rules are generated to build it, and the :prop_tgt:`IMPORTED` target
+property is ``True``.  The target name has scope in the directory in which
+it is created and below, but the ``GLOBAL`` option extends visibility.
+It may be referenced like any target built within the project.
+``IMPORTED`` libraries are useful for convenient reference from commands
+like :command:`target_link_libraries`.  Details about the imported library
+are specified by setting properties whose names begin in ``IMPORTED_`` and
+``INTERFACE_``.
+
+The ``<type>`` must be one of:
+
+``STATIC``, ``SHARED``, ``MODULE``, ``UNKNOWN``
+  References a library file located outside the project.  The
+  :prop_tgt:`IMPORTED_LOCATION` target property (or its per-configuration
+  variant :prop_tgt:`IMPORTED_LOCATION_<CONFIG>`) specifies the
+  location of the main library file on disk.  In the case of a ``SHARED``
+  library on Windows, the :prop_tgt:`IMPORTED_IMPLIB` target property
+  (or its per-configuration variant :prop_tgt:`IMPORTED_IMPLIB_<CONFIG>`)
+  specifies the location of the DLL import library file (``.lib`` or
+  ``.dll.a``) on disk, and the ``IMPORTED_LOCATION`` is the location of
+  the ``.dll`` runtime library (and is optional).
+  Additional usage requirements may be specified in ``INTERFACE_*`` properties.
+
+  An ``UNKNOWN`` library type is typically only used in the implementation of
+  :ref:`Find Modules`.  It allows the path to an imported library (often found
+  using the :command:`find_library` command) to be used without having to know
+  what type of library it is.  This is especially useful on Windows where a
+  static library and a DLL's import library both have the same file extension.
+
+``OBJECT``
+  References a set of object files located outside the project.
+  The :prop_tgt:`IMPORTED_OBJECTS` target property (or its per-configuration
+  variant :prop_tgt:`IMPORTED_OBJECTS_<CONFIG>`) specifies the locations of
+  object files on disk.
+  Additional usage requirements may be specified in ``INTERFACE_*`` properties.
+
+``INTERFACE``
+  Does not reference any library or object files on disk, but may
+  specify usage requirements in ``INTERFACE_*`` properties.
+
+See documentation of the ``IMPORTED_*`` and ``INTERFACE_*`` properties
+for more information.
+
+Alias Libraries
+^^^^^^^^^^^^^^^
+
+.. code-block:: cmake
+
+  add_library(<name> ALIAS <target>)
+
+Creates an :ref:`Alias Target <Alias Targets>`, such that ``<name>`` can be
+used to refer to ``<target>`` in subsequent commands.  The ``<name>`` does
+not appear in the generated buildsystem as a make target.  The ``<target>``
+may not be an ``ALIAS``.
+
+An ``ALIAS`` to a non-``GLOBAL`` :ref:`Imported Target <Imported Targets>`
+has scope in the directory in which the alias is created and below.
+The :prop_tgt:`ALIAS_GLOBAL` target property can be used to check if the
+alias is global or not.
+
+``ALIAS`` targets can be used as linkable targets and as targets to
+read properties from.  They can also be tested for existence with the
+regular :command:`if(TARGET)` subcommand.  The ``<name>`` may not be used
+to modify properties of ``<target>``, that is, it may not be used as the
+operand of :command:`set_property`, :command:`set_target_properties`,
+:command:`target_link_libraries` etc.  An ``ALIAS`` target may not be
+installed or exported.
diff --git a/Help/command/add_link_options.rst b/Help/command/add_link_options.rst
index a83005b..f03e7c0 100644
--- a/Help/command/add_link_options.rst
+++ b/Help/command/add_link_options.rst
@@ -1,6 +1,8 @@
 add_link_options
 ----------------
 
+.. versionadded:: 3.13
+
 Add options to the link step for executable, shared library or module
 library targets in the current directory and below that are added after
 this command is invoked.
@@ -26,6 +28,8 @@
 manual for available expressions.  See the :manual:`cmake-buildsystem(7)`
 manual for more on defining buildsystem properties.
 
+.. include:: DEVICE_LINK_OPTIONS.txt
+
 .. include:: OPTIONS_SHELL.txt
 
 .. include:: LINK_OPTIONS_LINKER.txt
diff --git a/Help/command/cmake_language.rst b/Help/command/cmake_language.rst
new file mode 100644
index 0000000..9e98d79
--- /dev/null
+++ b/Help/command/cmake_language.rst
@@ -0,0 +1,101 @@
+cmake_language
+--------------
+
+.. versionadded:: 3.18
+
+Call meta-operations on CMake commands.
+
+Synopsis
+^^^^^^^^
+
+.. parsed-literal::
+
+  cmake_language(`CALL`_ <command> [<args>...])
+  cmake_language(`EVAL`_ CODE <code>...)
+
+Introduction
+^^^^^^^^^^^^
+
+This command will call meta-operations on built-in CMake commands or
+those created via the :command:`macro` or :command:`function` commands.
+
+``cmake_language`` does not introduce a new variable or policy scope.
+
+Calling Commands
+^^^^^^^^^^^^^^^^
+
+.. _CALL:
+
+.. code-block:: cmake
+
+  cmake_language(CALL <command> [<args>...])
+
+Calls the named ``<command>`` with the given arguments (if any).
+For example, the code:
+
+.. code-block:: cmake
+
+  set(message_command "message")
+  cmake_language(CALL ${message_command} STATUS "Hello World!")
+
+is equivalent to
+
+.. code-block:: cmake
+
+  message(STATUS "Hello World!")
+
+.. note::
+  To ensure consistency of the code, the following commands are not allowed:
+
+  * ``if`` / ``elseif`` / ``else`` / ``endif``
+  * ``while`` / ``endwhile``
+  * ``foreach`` / ``endforeach``
+  * ``function`` / ``endfunction``
+  * ``macro`` / ``endmacro``
+
+Evaluating Code
+^^^^^^^^^^^^^^^
+
+.. _EVAL:
+
+.. code-block:: cmake
+
+  cmake_language(EVAL CODE <code>...)
+
+Evaluates the ``<code>...`` as CMake code.
+
+For example, the code:
+
+.. code-block:: cmake
+
+  set(A TRUE)
+  set(B TRUE)
+  set(C TRUE)
+  set(condition "(A AND B) OR C")
+
+  cmake_language(EVAL CODE "
+    if (${condition})
+      message(STATUS TRUE)
+    else()
+      message(STATUS FALSE)
+    endif()"
+  )
+
+is equivalent to
+
+.. code-block:: cmake
+
+  set(A TRUE)
+  set(B TRUE)
+  set(C TRUE)
+  set(condition "(A AND B) OR C")
+
+  file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/eval.cmake "
+    if (${condition})
+      message(STATUS TRUE)
+    else()
+      message(STATUS FALSE)
+    endif()"
+  )
+
+  include(${CMAKE_CURRENT_BINARY_DIR}/eval.cmake)
diff --git a/Help/command/cmake_parse_arguments.rst b/Help/command/cmake_parse_arguments.rst
index fcd36d0..8803ec8 100644
--- a/Help/command/cmake_parse_arguments.rst
+++ b/Help/command/cmake_parse_arguments.rst
@@ -1,6 +1,8 @@
 cmake_parse_arguments
 ---------------------
 
+.. versionadded:: 3.5
+
 Parse function or macro arguments.
 
 .. code-block:: cmake
diff --git a/Help/command/configure_file.rst b/Help/command/configure_file.rst
index 29e85bd..46d1a05 100644
--- a/Help/command/configure_file.rst
+++ b/Help/command/configure_file.rst
@@ -7,6 +7,7 @@
 
   configure_file(<input> <output>
                  [COPYONLY] [ESCAPE_QUOTES] [@ONLY]
+                 [NO_SOURCE_PERMISSIONS]
                  [NEWLINE_STYLE [UNIX|DOS|WIN32|LF|CRLF] ])
 
 Copies an ``<input>`` file to an ``<output>`` file and substitutes
@@ -82,6 +83,11 @@
   Restrict variable replacement to references of the form ``@VAR@``.
   This is useful for configuring scripts that use ``${VAR}`` syntax.
 
+ ``NO_SOURCE_PERMISSIONS``
+  Does not transfer the file permissions of the original file to the copy.
+  The copied file permissions default to the standard 644 value
+  (-rw-r--r--).
+
 ``NEWLINE_STYLE <style>``
   Specify the newline style for the output file.  Specify
   ``UNIX`` or ``LF`` for ``\n`` newlines, or specify
diff --git a/Help/command/continue.rst b/Help/command/continue.rst
index 31c7089..f62802e 100644
--- a/Help/command/continue.rst
+++ b/Help/command/continue.rst
@@ -1,6 +1,8 @@
 continue
 --------
 
+.. versionadded:: 3.2
+
 Continue to the top of enclosing foreach or while loop.
 
 .. code-block:: cmake
diff --git a/Help/command/ctest_test.rst b/Help/command/ctest_test.rst
index 5c67b2c..3589296 100644
--- a/Help/command/ctest_test.rst
+++ b/Help/command/ctest_test.rst
@@ -20,6 +20,7 @@
              [RESOURCE_SPEC_FILE <file>]
              [TEST_LOAD <threshold>]
              [SCHEDULE_RANDOM <ON|OFF>]
+             [STOP_ON_FAILURE]
              [STOP_TIME <time-of-day>]
              [RETURN_VALUE <result-var>]
              [CAPTURE_CMAKE_ERROR <result-var>]
@@ -119,6 +120,9 @@
   Launch tests in a random order.  This may be useful for detecting
   implicit test dependencies.
 
+``STOP_ON_FAILURE``
+  Stop the execution of the tests once one has failed.
+
 ``STOP_TIME <time-of-day>``
   Specify a time of day at which the tests should all stop running.
 
diff --git a/Help/command/execute_process.rst b/Help/command/execute_process.rst
index 14f879d..b32025f 100644
--- a/Help/command/execute_process.rst
+++ b/Help/command/execute_process.rst
@@ -21,7 +21,9 @@
                   [COMMAND_ECHO <where>]
                   [OUTPUT_STRIP_TRAILING_WHITESPACE]
                   [ERROR_STRIP_TRAILING_WHITESPACE]
-                  [ENCODING <name>])
+                  [ENCODING <name>]
+                  [ECHO_OUTPUT_VARIABLE]
+                  [ECHO_ERROR_VARIABLE])
 
 Runs the given sequence of one or more commands.
 
@@ -105,6 +107,15 @@
    for this encoding. In CMake 3.11.0, ``UTF-8`` was added for consistency with
    the `UTF-8 RFC <https://www.ietf.org/rfc/rfc3629>`_ naming convention.
 
+``ECHO_OUTPUT_VARIABLE``, ``ECHO_ERROR_VARIABLE``
+  The standard output or standard error will not be exclusively redirected to
+  the configured variables.
+
+  The output will be duplicated, it will be sent into the configured variables
+  and also on standard output or standard error.
+
+  This is analogous to the ``tee`` Unix command.
+
 If more than one ``OUTPUT_*`` or ``ERROR_*`` option is given for the
 same pipe the precedence is not specified.
 If no ``OUTPUT_*`` or ``ERROR_*`` options are given the output will
diff --git a/Help/command/file.rst b/Help/command/file.rst
index df7d8ba..2cf938b 100644
--- a/Help/command/file.rst
+++ b/Help/command/file.rst
@@ -19,6 +19,7 @@
     file({`WRITE`_ | `APPEND`_} <filename> <content>...)
     file({`TOUCH`_ | `TOUCH_NOCREATE`_} [<file>...])
     file(`GENERATE`_ OUTPUT <output-file> [...])
+    file(`CONFIGURE`_ OUTPUT <output-file> CONTENT <content> [...])
 
   `Filesystem`_
     file({`GLOB`_ | `GLOB_RECURSE`_} <out-var> [...] [<globbing-expr>...])
@@ -41,6 +42,10 @@
   `Locking`_
     file(`LOCK`_ <path> [...])
 
+  `Archiving`_
+    file(`ARCHIVE_CREATE`_ OUTPUT <archive> PATHS <paths>... [...])
+    file(`ARCHIVE_EXTRACT`_ INPUT <archive> [...])
+
 Reading
 ^^^^^^^
 
@@ -54,7 +59,9 @@
 Read content from a file called ``<filename>`` and store it in a
 ``<variable>``.  Optionally start from the given ``<offset>`` and
 read at most ``<max-in>`` bytes.  The ``HEX`` option causes data to
-be converted to a hexadecimal representation (useful for binary data).
+be converted to a hexadecimal representation (useful for binary data). If the
+``HEX`` option is specified, letters in the output (``a`` through ``f``) are in
+lowercase.
 
 .. _STRINGS:
 
@@ -243,8 +250,8 @@
   List of post-exclude regexes through which to filter the names of resolved
   dependencies.
 
-These arguments can be used to blacklist unwanted system libraries when
-resolving the dependencies, or to whitelist libraries from a specific
+These arguments can be used to exclude unwanted system libraries when
+resolving the dependencies, or to include libraries from a specific
 directory. The filtering works as follows:
 
 1. If the not-yet-resolved dependency matches any of the
@@ -395,8 +402,8 @@
   Determines the path to the tool to use for dependency resolution. This is the
   actual path to ``objdump``, ``dumpbin``, or ``otool``.
 
-  If this variable is not specified, it is determined automatically by system
-  introspection.
+  If this variable is not specified, it is determined by the value of
+  ``CMAKE_OBJDUMP`` if set, else by system introspection.
 
 Writing
 ^^^^^^^
@@ -482,6 +489,44 @@
 ``file(GENERATE)`` command returns, it is written only after processing all
 of a project's ``CMakeLists.txt`` files.
 
+.. _CONFIGURE:
+
+.. code-block:: cmake
+
+  file(CONFIGURE OUTPUT output-file
+       CONTENT content
+       [ESCAPE_QUOTES] [@ONLY]
+       [NEWLINE_STYLE [UNIX|DOS|WIN32|LF|CRLF] ])
+
+Generate an output file using the input given by ``CONTENT`` and substitute
+variable values referenced as ``@VAR@`` or ``${VAR}`` contained therein. The
+substitution rules behave the same as the :command:`configure_file` command.
+In order to match :command:`configure_file`'s behavior, generator expressions
+are not supported for both ``OUTPUT`` and ``CONTENT``.
+
+The arguments are:
+
+``OUTPUT <output-file>``
+  Specify the output file name to generate. A relative path is treated with
+  respect to the value of :variable:`CMAKE_CURRENT_BINARY_DIR`.
+  ``<output-file>`` does not support generator expressions.
+
+``CONTENT <content>``
+  Use the content given explicitly as input.
+  ``<content>`` does not support generator expressions.
+
+``ESCAPE_QUOTES``
+  Escape any substituted quotes with backslashes (C-style).
+
+``@ONLY``
+  Restrict variable replacement to references of the form ``@VAR@``.
+  This is useful for configuring scripts that use ``${VAR}`` syntax.
+
+``NEWLINE_STYLE <style>``
+  Specify the newline style for the output file.  Specify
+  ``UNIX`` or ``LF`` for ``\n`` newlines, or specify
+  ``DOS``, ``WIN32``, or ``CRLF`` for ``\r\n`` newlines.
+
 Filesystem
 ^^^^^^^^^^
 
@@ -731,11 +776,14 @@
 
 .. code-block:: cmake
 
-  file(DOWNLOAD <url> <file> [<options>...])
+  file(DOWNLOAD <url> [<file>] [<options>...])
   file(UPLOAD   <file> <url> [<options>...])
 
-The ``DOWNLOAD`` mode downloads the given ``<url>`` to a local ``<file>``.
-The ``UPLOAD`` mode uploads a local ``<file>`` to a given ``<url>``.
+The ``DOWNLOAD`` mode downloads the given ``<url>`` to a local ``<file>``. If
+``<file>`` is not specified for ``file(DOWNLOAD)``, the file is not saved. This
+can be useful if you want to know if a file can be downloaded (for example, to
+check that it exists) without actually saving it anywhere. The ``UPLOAD`` mode
+uploads a local ``<file>`` to a given ``<url>``.
 
 Options to both ``DOWNLOAD`` and ``UPLOAD`` are:
 
@@ -790,17 +838,6 @@
 If neither ``NETRC`` option is given CMake will check variables
 ``CMAKE_NETRC`` and ``CMAKE_NETRC_FILE``, respectively.
 
-Additional options to ``DOWNLOAD`` are:
-
-``EXPECTED_HASH ALGO=<value>``
-
-  Verify that the downloaded content hash matches the expected value, where
-  ``ALGO`` is one of the algorithms supported by ``file(<HASH>)``.
-  If it does not match, the operation fails with an error.
-
-``EXPECTED_MD5 <value>``
-  Historical short-hand for ``EXPECTED_HASH MD5=<value>``.
-
 ``TLS_VERIFY <ON|OFF>``
   Specify whether to verify the server certificate for ``https://`` URLs.
   The default is to *not* verify.
@@ -810,9 +847,21 @@
 
 For ``https://`` URLs CMake must be built with OpenSSL support.  ``TLS/SSL``
 certificates are not checked by default.  Set ``TLS_VERIFY`` to ``ON`` to
-check certificates and/or use ``EXPECTED_HASH`` to verify downloaded content.
-If neither ``TLS`` option is given CMake will check variables
-``CMAKE_TLS_VERIFY`` and ``CMAKE_TLS_CAINFO``, respectively.
+check certificates. If neither ``TLS`` option is given CMake will check
+variables ``CMAKE_TLS_VERIFY`` and ``CMAKE_TLS_CAINFO``, respectively.
+
+Additional options to ``DOWNLOAD`` are:
+
+``EXPECTED_HASH ALGO=<value>``
+
+  Verify that the downloaded content hash matches the expected value, where
+  ``ALGO`` is one of the algorithms supported by ``file(<HASH>)``.
+  If it does not match, the operation fails with an error. It is an error to
+  specify this if ``DOWNLOAD`` is not given a ``<file>``.
+
+``EXPECTED_MD5 <value>``
+  Historical short-hand for ``EXPECTED_HASH MD5=<value>``. It is an error to
+  specify this if ``DOWNLOAD`` is not given a ``<file>``.
 
 Locking
 ^^^^^^^
@@ -846,3 +895,66 @@
 Trying to lock file twice is not allowed.  Any intermediate directories and
 file itself will be created if they not exist.  ``GUARD`` and ``TIMEOUT``
 options ignored on ``RELEASE`` operation.
+
+Archiving
+^^^^^^^^^
+
+.. _ARCHIVE_CREATE:
+
+.. code-block:: cmake
+
+  file(ARCHIVE_CREATE OUTPUT <archive>
+    PATHS <paths>...
+    [FORMAT <format>]
+    [COMPRESSION <compression>]
+    [MTIME <mtime>]
+    [VERBOSE])
+
+Creates the specified ``<archive>`` file with the files and directories
+listed in ``<paths>``.  Note that ``<paths>`` must list actual files or
+directories, wildcards are not supported.
+
+Use the ``FORMAT`` option to specify the archive format.  Supported values
+for ``<format>`` are ``7zip``, ``gnutar``, ``pax``, ``paxr``, ``raw`` and
+``zip``.  If ``FORMAT`` is not given, the default format is ``paxr``.
+
+Some archive formats allow the type of compression to be specified.
+The ``7zip`` and ``zip`` archive formats already imply a specific type of
+compression.  The other formats use no compression by default, but can be
+directed to do so with the ``COMPRESSION`` option.  Valid values for
+``<compression>`` are ``None``, ``BZip2``, ``GZip``, ``XZ``, and ``Zstd``.
+
+.. note::
+  With ``FORMAT`` set to ``raw`` only one file will be compressed with the
+  compression type specified by ``COMPRESSION``.
+
+The ``VERBOSE`` option enables verbose output for the archive operation.
+
+To specify the modification time recorded in tarball entries, use
+the ``MTIME`` option.
+
+.. _ARCHIVE_EXTRACT:
+
+.. code-block:: cmake
+
+  file(ARCHIVE_EXTRACT INPUT <archive>
+    [DESTINATION <dir>]
+    [PATTERNS <patterns>...]
+    [LIST_ONLY]
+    [VERBOSE])
+
+Extracts or lists the content of the specified ``<archive>``.
+
+The directory where the content of the archive will be extracted to can
+be specified using the ``DESTINATION`` option.  If the directory does not
+exist, it will be created.  If ``DESTINATION`` is not given, the current
+binary directory will be used.
+
+If required, you may select which files and directories to list or extract
+from the archive using the specified ``<patterns>``.  Wildcards are supported.
+If the ``PATTERNS`` option is not given, the entire archive will be listed or
+extracted.
+
+``LIST_ONLY`` will list the files in the archive rather than extract them.
+
+With ``VERBOSE``, the command will produce verbose output.
diff --git a/Help/command/find_package.rst b/Help/command/find_package.rst
index 64a16f3..857de78 100644
--- a/Help/command/find_package.rst
+++ b/Help/command/find_package.rst
@@ -59,7 +59,7 @@
 messages.  Some find-modules provide limited or no support for versioning;
 check the module documentation.
 
-If the ``MODULE`` option is not specfied in the above signature,
+If the ``MODULE`` option is not specified in the above signature,
 CMake first searches for the package using Module mode. Then, if the
 package is not found, it searches again using Config mode. A user
 may set the variable :variable:`CMAKE_FIND_PACKAGE_PREFER_CONFIG` to
@@ -302,23 +302,23 @@
    are intended to be used on the command line with a ``-DVAR=value``.
    The values are interpreted as :ref:`semicolon-separated lists <CMake Language Lists>`.
    This can be skipped if ``NO_CMAKE_PATH`` is passed or by setting the
-   :variable:`CMAKE_FIND_USE_CMAKE_PATH` to ``FALSE``::
+   :variable:`CMAKE_FIND_USE_CMAKE_PATH` to ``FALSE``:
 
-     CMAKE_PREFIX_PATH
-     CMAKE_FRAMEWORK_PATH
-     CMAKE_APPBUNDLE_PATH
+   * :variable:`CMAKE_PREFIX_PATH`
+   * :variable:`CMAKE_FRAMEWORK_PATH`
+   * :variable:`CMAKE_APPBUNDLE_PATH`
 
 3. Search paths specified in cmake-specific environment variables.
    These are intended to be set in the user's shell configuration,
    and therefore use the host's native path separator
    (``;`` on Windows and ``:`` on UNIX).
    This can be skipped if ``NO_CMAKE_ENVIRONMENT_PATH`` is passed or by setting
-   the :variable:`CMAKE_FIND_USE_CMAKE_ENVIRONMENT_PATH` to ``FALSE``::
+   the :variable:`CMAKE_FIND_USE_CMAKE_ENVIRONMENT_PATH` to ``FALSE``:
 
-     <PackageName>_DIR
-     CMAKE_PREFIX_PATH
-     CMAKE_FRAMEWORK_PATH
-     CMAKE_APPBUNDLE_PATH
+   * ``<PackageName>_DIR``
+   * :envvar:`CMAKE_PREFIX_PATH`
+   * ``CMAKE_FRAMEWORK_PATH``
+   * ``CMAKE_APPBUNDLE_PATH``
 
 4. Search paths specified by the ``HINTS`` option.  These should be paths
    computed by system introspection, such as a hint provided by the
@@ -329,9 +329,9 @@
    skipped if ``NO_SYSTEM_ENVIRONMENT_PATH`` is passed  or by setting the
    :variable:`CMAKE_FIND_USE_SYSTEM_ENVIRONMENT_PATH` to ``FALSE``. Path entries
    ending in ``/bin`` or ``/sbin`` are automatically converted to their
-   parent directories::
+   parent directories:
 
-     PATH
+   * ``PATH``
 
 6. Search paths stored in the CMake :ref:`User Package Registry`.
    This can be skipped if ``NO_CMAKE_PACKAGE_REGISTRY`` is passed or by
@@ -345,11 +345,15 @@
 7. Search cmake variables defined in the Platform files for the
    current system.  This can be skipped if ``NO_CMAKE_SYSTEM_PATH`` is
    passed or by setting the :variable:`CMAKE_FIND_USE_CMAKE_SYSTEM_PATH`
-   to ``FALSE``::
+   to ``FALSE``:
 
-     CMAKE_SYSTEM_PREFIX_PATH
-     CMAKE_SYSTEM_FRAMEWORK_PATH
-     CMAKE_SYSTEM_APPBUNDLE_PATH
+   * :variable:`CMAKE_SYSTEM_PREFIX_PATH`
+   * :variable:`CMAKE_SYSTEM_FRAMEWORK_PATH`
+   * :variable:`CMAKE_SYSTEM_APPBUNDLE_PATH`
+
+   The platform paths that these variables contain are locations that
+   typically include installed software. An example being ``/usr/local`` for
+   UNIX based platforms.
 
 8. Search paths stored in the CMake :ref:`System Package Registry`.
    This can be skipped if ``NO_CMAKE_SYSTEM_PACKAGE_REGISTRY`` is passed
diff --git a/Help/command/function.rst b/Help/command/function.rst
index 53ba754..7a9b907 100644
--- a/Help/command/function.rst
+++ b/Help/command/function.rst
@@ -44,11 +44,15 @@
   foo()
   Foo()
   FOO()
+  cmake_language(CALL foo)
 
 and so on. However, it is strongly recommended to stay with the
 case chosen in the function definition. Typically functions use
 all-lowercase names.
 
+The :command:`cmake_language(CALL ...)` command can also be used to
+invoke the function.
+
 Arguments
 ^^^^^^^^^
 
diff --git a/Help/command/get_property.rst b/Help/command/get_property.rst
index c0f9b46..0602518 100644
--- a/Help/command/get_property.rst
+++ b/Help/command/get_property.rst
@@ -10,6 +10,7 @@
                 DIRECTORY [<dir>]  |
                 TARGET    <target> |
                 SOURCE    <source> |
+                          [DIRECTORY <dir> | TARGET_DIRECTORY <target>] |
                 INSTALL   <file>   |
                 TEST      <test>   |
                 CACHE     <entry>  |
@@ -30,18 +31,36 @@
   Scope defaults to the current directory but another
   directory (already processed by CMake) may be named by the
   full or relative path ``<dir>``.
+  See also the :command:`get_directory_property` command.
 
 ``TARGET``
   Scope must name one existing target.
+  See also the :command:`get_target_property` command.
 
 ``SOURCE``
-  Scope must name one source file.
+  Scope must name one source file.  By default, the source file's property
+  will be read from the current source directory's scope, but this can be
+  overridden with one of the following sub-options:
+
+  ``DIRECTORY <dir>``
+    The source file property will be read from the ``<dir>`` directory's
+    scope.  CMake must already know about that source directory, either by
+    having added it through a call to :command:`add_subdirectory` or ``<dir>``
+    being the top level source directory.  Relative paths are treated as
+    relative to the current source directory.
+
+  ``TARGET_DIRECTORY <target>``
+    The source file property will be read from the directory scope in which
+    ``<target>`` was created (``<target>`` must therefore already exist).
+
+  See also the :command:`get_source_file_property` command.
 
 ``INSTALL``
   Scope must name one installed file path.
 
 ``TEST``
   Scope must name one existing test.
+  See also the :command:`get_test_property` command.
 
 ``CACHE``
   Scope must name one cache entry.
diff --git a/Help/command/get_source_file_property.rst b/Help/command/get_source_file_property.rst
index decec19..76ed776 100644
--- a/Help/command/get_source_file_property.rst
+++ b/Help/command/get_source_file_property.rst
@@ -5,15 +5,33 @@
 
 .. code-block:: cmake
 
-  get_source_file_property(VAR file property)
+  get_source_file_property(<variable> <file>
+                           [DIRECTORY <dir> | TARGET_DIRECTORY <target>]
+                           <property>)
 
 Gets a property from a source file.  The value of the property is
-stored in the variable ``VAR``.  If the source property is not found, the
-behavior depends on whether it has been defined to be an ``INHERITED`` property
-or not (see :command:`define_property`).  Non-inherited properties will set
-``VAR`` to "NOTFOUND", whereas inherited properties will search the relevant
-parent scope as described for the :command:`define_property` command and
-if still unable to find the property, ``VAR`` will be set to an empty string.
+stored in the specified ``<variable>``.  If the source property is not found,
+the behavior depends on whether it has been defined to be an ``INHERITED``
+property or not (see :command:`define_property`).  Non-inherited properties
+will set ``variable`` to ``NOTFOUND``, whereas inherited properties will search
+the relevant parent scope as described for the :command:`define_property`
+command and if still unable to find the property, ``variable`` will be set to
+an empty string.
+
+By default, the source file's property will be read from the current source
+directory's scope, but this can be overridden with one of the following
+sub-options:
+
+``DIRECTORY <dir>``
+  The source file property will be read from the ``<dir>`` directory's
+  scope.  CMake must already know about that source directory, either by
+  having added it through a call to :command:`add_subdirectory` or ``<dir>``
+  being the top level source directory.  Relative paths are treated as
+  relative to the current source directory.
+
+``TARGET_DIRECTORY <target>``
+  The source file property will be read from the directory scope in which
+  ``<target>`` was created (``<target>`` must therefore already exist).
 
 Use :command:`set_source_files_properties` to set property values.  Source
 file properties usually control how the file is built. One property that is
diff --git a/Help/command/get_target_property.rst b/Help/command/get_target_property.rst
index 11e07ea..985b1ff 100644
--- a/Help/command/get_target_property.rst
+++ b/Help/command/get_target_property.rst
@@ -5,15 +5,15 @@
 
 .. code-block:: cmake
 
-  get_target_property(VAR target property)
+  get_target_property(<VAR> target property)
 
 Get a property from a target.  The value of the property is stored in
-the variable ``VAR``.  If the target property is not found, the behavior
+the variable ``<VAR>``.  If the target property is not found, the behavior
 depends on whether it has been defined to be an ``INHERITED`` property
 or not (see :command:`define_property`).  Non-inherited properties will
-set ``VAR`` to ``NOTFOUND``, whereas inherited properties will search the
-relevant parent scope as described for the :command:`define_property`
-command and if still unable to find the property, ``VAR`` will be set to
+set ``<VAR>`` to ``<VAR>-NOTFOUND``, whereas inherited properties will search
+the relevant parent scope as described for the :command:`define_property`
+command and if still unable to find the property, ``<VAR>`` will be set to
 an empty string.
 
 Use :command:`set_target_properties` to set target property values.
diff --git a/Help/command/include_guard.rst b/Help/command/include_guard.rst
index 877aa86..dca3b6f 100644
--- a/Help/command/include_guard.rst
+++ b/Help/command/include_guard.rst
@@ -1,6 +1,8 @@
 include_guard
 -------------
 
+.. versionadded:: 3.10
+
 Provides an include guard for the file currently being processed by CMake.
 
 .. code-block:: cmake
diff --git a/Help/command/install.rst b/Help/command/install.rst
index 5affc5b..c11eaf4 100644
--- a/Help/command/install.rst
+++ b/Help/command/install.rst
@@ -18,10 +18,12 @@
 Introduction
 ^^^^^^^^^^^^
 
-This command generates installation rules for a project.  Rules
-specified by calls to this command within a source directory are
-executed in order during installation.  The order across directories
-is not defined.
+This command generates installation rules for a project.  Install rules
+specified by calls to the ``install()`` command within a source directory
+are executed in order during installation.  Install rules in subdirectories
+added by calls to the :command:`add_subdirectory` command are interleaved
+with those in the parent directory to run in the order declared (see
+policy :policy:`CMP0082`).
 
 There are multiple signatures for this command.  Some of them define
 installation options for files and targets.  Options common to
@@ -30,13 +32,23 @@
 
 ``DESTINATION``
   Specify the directory on disk to which a file will be installed.
-  If a full path (with a leading slash or drive letter) is given
-  it is used directly.  If a relative path is given it is interpreted
-  relative to the value of the :variable:`CMAKE_INSTALL_PREFIX` variable.
+  Arguments can be relative or absolute paths.
+
+  If a relative path is given it is interpreted relative to the value
+  of the :variable:`CMAKE_INSTALL_PREFIX` variable.
   The prefix can be relocated at install time using the ``DESTDIR``
   mechanism explained in the :variable:`CMAKE_INSTALL_PREFIX` variable
   documentation.
 
+  If an absolute path (with a leading slash or drive letter) is given
+  it is used verbatim.
+
+  As absolute paths are not supported by :manual:`cpack <cpack(1)>` installer
+  generators, it is preferable to use relative paths throughout.
+  In particular, there is no need to make paths absolute by prepending
+  :variable:`CMAKE_INSTALL_PREFIX`; this prefix is used by default if
+  the DESTINATION is a relative path.
+
 ``PERMISSIONS``
   Specify permissions for installed files.  Valid permissions are
   ``OWNER_READ``, ``OWNER_WRITE``, ``OWNER_EXECUTE``, ``GROUP_READ``,
@@ -119,31 +131,38 @@
           )
 
 The ``TARGETS`` form specifies rules for installing targets from a
-project.  There are several kinds of target files that may be installed:
+project.  There are several kinds of target :ref:`Output Artifacts`
+that may be installed:
 
 ``ARCHIVE``
-  Static libraries are treated as ``ARCHIVE`` targets, except those
-  marked with the ``FRAMEWORK`` property on macOS (see ``FRAMEWORK``
-  below.) For DLL platforms (all Windows-based systems including
-  Cygwin), the DLL import library is treated as an ``ARCHIVE`` target.
-  On AIX, the linker import file created for executables with
-  :prop_tgt:`ENABLE_EXPORTS` is treated as an ``ARCHIVE`` target.
+  Target artifacts of this kind include:
+
+  * *Static libraries*
+    (except on macOS when marked as ``FRAMEWORK``, see below);
+  * *DLL import libraries*
+    (on all Windows-based systems including Cygwin; they have extension
+    ``.lib``, in contrast to the ``.dll`` libraries that go to ``RUNTIME``);
+  * On AIX, the *linker import file* created for executables with
+    :prop_tgt:`ENABLE_EXPORTS` enabled.
 
 ``LIBRARY``
-  Module libraries are always treated as ``LIBRARY`` targets. For non-
-  DLL platforms shared libraries are treated as ``LIBRARY`` targets,
-  except those marked with the ``FRAMEWORK`` property on macOS (see
-  ``FRAMEWORK`` below.)
+  Target artifacts of this kind include:
+
+  * *Shared libraries*, except
+
+    - DLLs (these go to ``RUNTIME``, see below),
+    - on macOS when marked as ``FRAMEWORK`` (see below).
 
 ``RUNTIME``
-  Executables are treated as ``RUNTIME`` objects, except those marked
-  with the ``MACOSX_BUNDLE`` property on macOS (see ``BUNDLE`` below.)
-  For DLL platforms (all Windows-based systems including Cygwin), the
-  DLL part of a shared library is treated as a ``RUNTIME`` target.
+  Target artifacts of this kind include:
+
+  * *Executables*
+    (except on macOS when marked as ``MACOSX_BUNDLE``, see ``BUNDLE`` below);
+  * DLLs (on all Windows-based systems including Cygwin; note that the
+    accompanying import libraries are of kind ``ARCHIVE``).
 
 ``OBJECTS``
-  Object libraries (a simple group of object files) are always treated
-  as ``OBJECTS`` targets.
+  Object files associated with *object libraries*.
 
 ``FRAMEWORK``
   Both static and shared libraries marked with the ``FRAMEWORK``
@@ -630,6 +649,13 @@
 ``(IMPORTED_)?LINK_INTERFACE_LIBRARIES(_<CONFIG>)?`` to be exported, when
 policy :policy:`CMP0022` is ``NEW``.
 
+.. note::
+  The installed ``<export-name>.cmake`` file may come with additional
+  per-configuration ``<export-name>-*.cmake`` files to be loaded by
+  globbing.  Do not use an export name that is the same as the package
+  name in combination with installing a ``<package-name>-config.cmake``
+  file or the latter may be incorrectly matched by the glob and loaded.
+
 When a ``COMPONENT`` option is given, the listed ``<component>`` implicitly
 depends on all components mentioned in the export set. The exported
 ``<name>.cmake`` file will require each of the exported components to be
@@ -684,6 +710,11 @@
 Generated Installation Script
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
+.. note::
+
+  Use of this feature is not recommended. Please consider using the
+  ``--install`` argument of :manual:`cmake(1)` instead.
+
 The ``install()`` command generates a file, ``cmake_install.cmake``, inside
 the build directory, which is used internally by the generated install target
 and by CPack. You can also invoke this script manually with ``cmake -P``. This
diff --git a/Help/command/list.rst b/Help/command/list.rst
index 50bf417..4d339a0 100644
--- a/Help/command/list.rst
+++ b/Help/command/list.rst
@@ -308,6 +308,13 @@
 * ``STRING``: Sorts a list of strings alphabetically.  This is the
   default behavior if the ``COMPARE`` option is not given.
 * ``FILE_BASENAME``: Sorts a list of pathnames of files by their basenames.
+* ``NATURAL``: Sorts a list of strings using natural order
+  (see ``strverscmp(3)`` manual), i.e. such that contiguous digits
+  are compared as whole numbers.
+  For example: the following list `10.0 1.1 2.1 8.0 2.0 3.1`
+  will be sorted as `1.1 2.0 2.1 3.1 8.0 10.0` if the ``NATURAL``
+  comparison is selected where it will be sorted as
+  `1.1 10.0 2.0 2.1 3.1 8.0` with the ``STRING`` comparison.
 
 Use the ``CASE`` keyword to select a case sensitive or case insensitive
 sort mode.  The ``<case>`` option should be one of:
diff --git a/Help/command/macro.rst b/Help/command/macro.rst
index 008d049..797a90d 100644
--- a/Help/command/macro.rst
+++ b/Help/command/macro.rst
@@ -42,11 +42,15 @@
   foo()
   Foo()
   FOO()
+  cmake_language(CALL foo)
 
 and so on. However, it is strongly recommended to stay with the
 case chosen in the macro definition.  Typically macros use
 all-lowercase names.
 
+The :command:`cmake_language(CALL ...)` command can also be used to
+invoke the macro.
+
 Arguments
 ^^^^^^^^^
 
diff --git a/Help/command/option.rst b/Help/command/option.rst
index 8956307..02b8dac 100644
--- a/Help/command/option.rst
+++ b/Help/command/option.rst
@@ -9,7 +9,7 @@
 
 Provides an option for the user to select as ``ON`` or ``OFF``.
 If no initial ``<value>`` is provided, ``OFF`` is used.
-If ``<variable>`` is already set as a normal variable
+If ``<variable>`` is already set as a normal or cache variable,
 then the command does nothing (see policy :policy:`CMP0077`).
 
 If you have options that depend on the values of other options, see
diff --git a/Help/command/separate_arguments.rst b/Help/command/separate_arguments.rst
index fbca859..ab3d5c1 100644
--- a/Help/command/separate_arguments.rst
+++ b/Help/command/separate_arguments.rst
@@ -19,7 +19,7 @@
 be one of the following keywords:
 
 ``UNIX_COMMAND``
-  Arguments are separated by by unquoted whitespace.
+  Arguments are separated by unquoted whitespace.
   Both single-quote and double-quote pairs are respected.
   A backslash escapes the next literal character (``\"`` is ``"``);
   there are no special escapes (``\n`` is just ``n``).
diff --git a/Help/command/set_property.rst b/Help/command/set_property.rst
index ec08c8f..93c2d9c 100644
--- a/Help/command/set_property.rst
+++ b/Help/command/set_property.rst
@@ -8,12 +8,14 @@
   set_property(<GLOBAL                      |
                 DIRECTORY [<dir>]           |
                 TARGET    [<target1> ...]   |
-                SOURCE    [<src1> ...]      |
+                SOURCE    [<src1> ...]
+                          [DIRECTORY <dirs> ...] |
+                          [TARGET_DIRECTORY <targets> ...]
                 INSTALL   [<file1> ...]     |
                 TEST      [<test1> ...]     |
                 CACHE     [<entry1> ...]    >
                [APPEND] [APPEND_STRING]
-               PROPERTY <name> [value1 ...])
+               PROPERTY <name> [<value1> ...])
 
 Sets one property on zero or more objects of a scope.
 
@@ -33,9 +35,23 @@
   See also the :command:`set_target_properties` command.
 
 ``SOURCE``
-  Scope may name zero or more source files.  Note that source
-  file properties are visible only to targets added in the same
-  directory (``CMakeLists.txt``).
+  Scope may name zero or more source files.  By default, source file properties
+  are only visible to targets added in the same directory (``CMakeLists.txt``).
+  Visibility can be set in other directory scopes using one or both of the
+  following sub-options:
+
+  ``DIRECTORY <dirs>...``
+    The source file property will be set in each of the ``<dirs>``
+    directories' scopes.  CMake must already know about each of these
+    source directories, either by having added them through a call to
+    :command:`add_subdirectory` or it being the top level source directory.
+    Relative paths are treated as relative to the current source directory.
+
+  ``TARGET_DIRECTORY <targets>...``
+    The source file property will be set in each of the directory scopes
+    where any of the specified ``<targets>`` were created (the ``<targets>``
+    must therefore already exist).
+
   See also the :command:`set_source_files_properties` command.
 
 ``INSTALL``
@@ -66,7 +82,8 @@
 property value in the form of a semicolon-separated list.
 
 If the ``APPEND`` option is given the list is appended to any existing
-property value.  If the ``APPEND_STRING`` option is given the string is
+property value (except that empty values are ignored and not appended).
+If the ``APPEND_STRING`` option is given the string is
 appended to any existing property value as string, i.e. it results in a
 longer string and not a list of strings.  When using ``APPEND`` or
 ``APPEND_STRING`` with a property defined to support ``INHERITED``
diff --git a/Help/command/set_source_files_properties.rst b/Help/command/set_source_files_properties.rst
index ab95d70..9558b40 100644
--- a/Help/command/set_source_files_properties.rst
+++ b/Help/command/set_source_files_properties.rst
@@ -5,15 +5,33 @@
 
 .. code-block:: cmake
 
-  set_source_files_properties([file1 [file2 [...]]]
-                              PROPERTIES prop1 value1
-                              [prop2 value2 [...]])
+  set_source_files_properties(<files> ...
+                              [DIRECTORY <dirs> ...]
+                              [TARGET_DIRECTORY <targets> ...]
+                              PROPERTIES <prop1> <value1>
+                              [<prop2> <value2>] ...)
 
 Sets properties associated with source files using a key/value paired
 list.
 
+By default, source file properties are only visible to targets added in the
+same directory (``CMakeLists.txt``).  Visibility can be set in other directory
+scopes using one or both of the following options:
+
+``DIRECTORY <dirs>...``
+  The source file properties will be set in each of the ``<dirs>``
+  directories' scopes.  CMake must already know about each of these
+  source directories, either by having added them through a call to
+  :command:`add_subdirectory` or it being the top level source directory.
+  Relative paths are treated as relative to the current source directory.
+
+``TARGET_DIRECTORY <targets>...``
+  The source file properties will be set in each of the directory scopes
+  where any of the specified ``<targets>`` were created (the ``<targets>``
+  must therefore already exist).
+
+Use :command:`get_source_file_property` to get property values.
 See also the :command:`set_property(SOURCE)` command.
 
 See :ref:`Source File Properties` for the list of properties known
-to CMake.  Source file properties are visible only to targets added
-in the same directory (``CMakeLists.txt``).
+to CMake.
diff --git a/Help/command/source_group.rst b/Help/command/source_group.rst
index 6623c98..5ae9e51 100644
--- a/Help/command/source_group.rst
+++ b/Help/command/source_group.rst
@@ -37,11 +37,13 @@
 If no group explicitly lists the file, the *last* group whose
 regular expression matches the file will be favored.
 
-The ``<name>`` of the group and ``<prefix>`` argument may contain backslashes
-to specify subgroups:
+The ``<name>`` of the group and ``<prefix>`` argument may contain forward
+slashes or backslashes to specify subgroups.  Backslashes need to be escaped
+appropriately:
 
 .. code-block:: cmake
 
+  source_group(base/subdir ...)
   source_group(outer\\inner ...)
   source_group(TREE <root> PREFIX sources\\inc ...)
 
diff --git a/Help/command/string.rst b/Help/command/string.rst
index 81a2061..cfcf914 100644
--- a/Help/command/string.rst
+++ b/Help/command/string.rst
@@ -11,8 +11,6 @@
   `Search and Replace`_
     string(`FIND`_ <string> <substring> <out-var> [...])
     string(`REPLACE`_ <match-string> <replace-string> <out-var> <input>...)
-
-  `Regular Expressions`_
     string(`REGEX MATCH`_ <match-regex> <out-var> <input>...)
     string(`REGEX MATCHALL`_ <match-regex> <out-var> <input>...)
     string(`REGEX REPLACE`_ <match-regex> <replace-expr> <out-var> <input>...)
@@ -38,6 +36,7 @@
 
   `Generation`_
     string(`ASCII`_ <number>... <out-var>)
+    string(`HEX`_ <string> <out-var>)
     string(`CONFIGURE`_ <string> <out-var> [...])
     string(`MAKE_C_IDENTIFIER`_ <string> <out-var>)
     string(`RANDOM`_ [<option>...] <out-var>)
@@ -47,6 +46,9 @@
 Search and Replace
 ^^^^^^^^^^^^^^^^^^
 
+Search and Replace With Plain Strings
+"""""""""""""""""""""""""""""""""""""
+
 .. _FIND:
 
 .. code-block:: cmake
@@ -74,8 +76,8 @@
 Replace all occurrences of ``<match_string>`` in the ``<input>``
 with ``<replace_string>`` and store the result in the ``<output_variable>``.
 
-Regular Expressions
-^^^^^^^^^^^^^^^^^^^
+Search and Replace With Regular Expressions
+"""""""""""""""""""""""""""""""""""""""""""
 
 .. _`REGEX MATCH`:
 
@@ -87,6 +89,7 @@
 Match the ``<regular_expression>`` once and store the match in the
 ``<output_variable>``.
 All ``<input>`` arguments are concatenated before matching.
+Regular expressions are specified in the subsection just below.
 
 .. _`REGEX MATCHALL`:
 
@@ -353,6 +356,16 @@
 
 Convert all numbers into corresponding ASCII characters.
 
+.. _HEX:
+
+.. code-block:: cmake
+
+  string(HEX <string> <output_variable>)
+
+Convert each byte in the input ``<string>`` to its hexadecimal representation
+and store the concatenated hex digits in the ``<output_variable>``. Letters in
+the output (``a`` through ``f``) are in lowercase.
+
 .. _CONFIGURE:
 
 .. code-block:: cmake
diff --git a/Help/command/target_compile_features.rst b/Help/command/target_compile_features.rst
index c5401e6..b50be34 100644
--- a/Help/command/target_compile_features.rst
+++ b/Help/command/target_compile_features.rst
@@ -1,6 +1,8 @@
 target_compile_features
 -----------------------
 
+.. versionadded:: 3.1
+
 Add expected compiler features to a target.
 
 .. code-block:: cmake
diff --git a/Help/command/target_compile_options.rst b/Help/command/target_compile_options.rst
index 47e7d86..3c733c5 100644
--- a/Help/command/target_compile_options.rst
+++ b/Help/command/target_compile_options.rst
@@ -46,3 +46,5 @@
 and :command:`target_include_directories`.
 
 For directory-wide settings, there is the command :command:`add_compile_options`.
+
+For file-specific settings, there is the source file property :prop_sf:`COMPILE_OPTIONS`.
diff --git a/Help/command/target_link_directories.rst b/Help/command/target_link_directories.rst
index 76da94d..bb75a3d 100644
--- a/Help/command/target_link_directories.rst
+++ b/Help/command/target_link_directories.rst
@@ -1,6 +1,8 @@
 target_link_directories
 -----------------------
 
+.. versionadded:: 3.13
+
 Add link directories to a target.
 
 .. code-block:: cmake
diff --git a/Help/command/target_link_options.rst b/Help/command/target_link_options.rst
index b5abbc4..e59e0e1 100644
--- a/Help/command/target_link_options.rst
+++ b/Help/command/target_link_options.rst
@@ -1,6 +1,8 @@
 target_link_options
 -------------------
 
+.. versionadded:: 3.13
+
 Add options to the link step for an executable, shared library or module
 library target.
 
@@ -43,6 +45,8 @@
 manual for available expressions.  See the :manual:`cmake-buildsystem(7)`
 manual for more on defining buildsystem properties.
 
+.. include:: DEVICE_LINK_OPTIONS.txt
+
 .. include:: OPTIONS_SHELL.txt
 
 .. include:: LINK_OPTIONS_LINKER.txt
diff --git a/Help/command/target_precompile_headers.rst b/Help/command/target_precompile_headers.rst
index 0d4f45a..7005180 100644
--- a/Help/command/target_precompile_headers.rst
+++ b/Help/command/target_precompile_headers.rst
@@ -1,6 +1,8 @@
 target_precompile_headers
 -------------------------
 
+.. versionadded:: 3.16
+
 Add a list of header files to precompile.
 
 Precompiling header files can speed up compilation by creating a partially
@@ -93,7 +95,7 @@
 ^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 The command also supports a second signature which can be used to specify that
-one target re-uses a precompiled header file artefact from another target
+one target re-uses a precompiled header file artifact from another target
 instead of generating its own:
 
 .. code-block:: cmake
diff --git a/Help/command/target_sources.rst b/Help/command/target_sources.rst
index 27e737b..653b8d7 100644
--- a/Help/command/target_sources.rst
+++ b/Help/command/target_sources.rst
@@ -1,6 +1,8 @@
 target_sources
 --------------
 
+.. versionadded:: 3.1
+
 Add sources to a target.
 
 .. code-block:: cmake
@@ -9,19 +11,21 @@
     <INTERFACE|PUBLIC|PRIVATE> [items1...]
     [<INTERFACE|PUBLIC|PRIVATE> [items2...] ...])
 
-Specifies sources to use when compiling a given target.  Relative
-source file paths are interpreted as being relative to the current
+Specifies sources to use when building a target and/or its dependents.
+Relative source file paths are interpreted as being relative to the current
 source directory (i.e. :variable:`CMAKE_CURRENT_SOURCE_DIR`).  The
 named ``<target>`` must have been created by a command such as
 :command:`add_executable` or :command:`add_library` and must not be an
 :ref:`ALIAS target <Alias Targets>`.
 
 The ``INTERFACE``, ``PUBLIC`` and ``PRIVATE`` keywords are required to
-specify the scope of the following arguments.  ``PRIVATE`` and ``PUBLIC``
+specify the scope of the items following them.  ``PRIVATE`` and ``PUBLIC``
 items will populate the :prop_tgt:`SOURCES` property of
-``<target>``.  ``PUBLIC`` and ``INTERFACE`` items will populate the
-:prop_tgt:`INTERFACE_SOURCES` property of ``<target>``.
-(:ref:`IMPORTED targets <Imported Targets>` only support ``INTERFACE`` items.)
+``<target>``, which are used when building the target itself.
+``PUBLIC`` and ``INTERFACE`` items will populate the
+:prop_tgt:`INTERFACE_SOURCES` property of ``<target>``, which are used
+when building dependents.  (:ref:`IMPORTED targets <Imported Targets>`
+only support ``INTERFACE`` items because they are not build targets.)
 The following arguments specify sources.  Repeated calls for the same
 ``<target>`` append items in the order called.
 
diff --git a/Help/command/variable_watch.rst b/Help/command/variable_watch.rst
index ce69bcf..8293f5a 100644
--- a/Help/command/variable_watch.rst
+++ b/Help/command/variable_watch.rst
@@ -7,9 +7,42 @@
 
   variable_watch(<variable> [<command>])
 
-If the specified ``<variable>`` changes, a message will be printed
-to inform about the change.
+If the specified ``<variable>`` changes and no ``<command>`` is given,
+a message will be printed to inform about the change.
 
-Additionally, if ``<command>`` is given, this command will be executed.
+If ``<command>`` is given, this command will be executed instead.
 The command will receive the following arguments:
 ``COMMAND(<variable> <access> <value> <current_list_file> <stack>)``
+
+``<variable>``
+ Name of the variable being accessed.
+
+``<access>``
+ One of ``READ_ACCESS``, ``UNKNOWN_READ_ACCESS``, ``MODIFIED_ACCESS``,
+ ``UNKNOWN_MODIFIED_ACCESS``, or ``REMOVED_ACCESS``.  The ``UNKNOWN_``
+ values are only used when the variable has never been set.  Once set,
+ they are never used again during the same CMake run, even if the
+ variable is later unset.
+
+``<value>``
+ The value of the variable.  On a modification, this is the new
+ (modified) value of the variable.  On removal, the value is empty.
+
+``<current_list_file>``
+ Full path to the file doing the access.
+
+``<stack>``
+ List of absolute paths of all files currently on the stack of file
+ inclusion, with the bottom-most file first and the currently
+ processed file (that is, ``current_list_file``) last.
+
+Note that for some accesses such as :command:`list(APPEND)`, the watcher
+is executed twice, first with a read access and then with a write one.
+Also note that an :command:`if(DEFINED)` query on the variable does not
+register as an access and the watcher is not executed.
+
+Only non-cache variables can be watched using this command.  Access to
+cache variables is never watched.  However, the existence of a cache
+variable ``var`` causes accesses to the non-cache variable ``var`` to
+not use the ``UNKNOWN_`` prefix, even if a non-cache variable ``var``
+has never existed.
diff --git a/Help/cpack_gen/archive.rst b/Help/cpack_gen/archive.rst
index d455f4b..3656aa2 100644
--- a/Help/cpack_gen/archive.rst
+++ b/Help/cpack_gen/archive.rst
@@ -1,8 +1,8 @@
 CPack Archive Generator
 -----------------------
 
-Archive CPack generator that supports packaging of sources and binaries in
-different formats:
+CPack generator for packaging files into an archive, which can have
+any of the following formats:
 
   - 7Z - 7zip - (.7z)
   - TBZ2 (.tar.bz2)
@@ -12,25 +12,64 @@
   - TZST (.tar.zst)
   - ZIP (.zip)
 
+When this generator is called from ``CPackSourceConfig.cmake`` (or through
+the ``package_source`` target), then the generated archive will contain all
+files in the project directory, except those specified in
+:variable:`CPACK_SOURCE_IGNORE_FILES`.  The following is one example of
+packaging all source files of a project:
+
+.. code-block:: cmake
+
+  set(CPACK_SOURCE_GENERATOR "TGZ")
+  set(CPACK_SOURCE_IGNORE_FILES
+    \\.git/
+    build/
+    ".*~$"
+  )
+  set(CPACK_VERBATIM_VARIABLES YES)
+  include(CPack)
+
+When this generator is called from ``CPackConfig.cmake`` (or through the
+``package`` target), then the generated archive will contain all files
+that have been installed via CMake's :command:`install` command (and the
+deprecated commands :command:`install_files`, :command:`install_programs`,
+and :command:`install_targets`).
+
 Variables specific to CPack Archive generator
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 .. variable:: CPACK_ARCHIVE_FILE_NAME
               CPACK_ARCHIVE_<component>_FILE_NAME
 
- Package file name without extension which is added automatically depending
- on the archive format.
-
- * Mandatory : YES
- * Default   : ``<CPACK_PACKAGE_FILE_NAME>[-<component>].<extension>`` with
-               spaces replaced by '-'
+  Package file name without extension. The extension is determined from the
+  archive format (see list above) and automatically appended to the file name.
+  The default is ``<CPACK_PACKAGE_FILE_NAME>[-<component>]``, with spaces
+  replaced by '-'.
 
 .. variable:: CPACK_ARCHIVE_COMPONENT_INSTALL
 
- Enable component packaging for CPackArchive
+  Enable component packaging. If enabled (ON), then the archive generator
+  creates  multiple packages. The default is OFF, which means that a single
+  package containing files of all components is generated.
 
- * Mandatory : NO
- * Default   : OFF
+Variables used by CPack Archive generator
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
- If enabled (ON) multiple packages are generated. By default a single package
- containing files of all components is generated.
+These variables are used by the Archive generator, but are also available to
+CPack generators which are essentially archives at their core. These include:
+
+  - :cpack_gen:`CPack Cygwin Generator`
+  - :cpack_gen:`CPack FreeBSD Generator`
+
+.. variable:: CPACK_ARCHIVE_THREADS
+
+  The number of threads to use when performing the compression. If set to
+  ``0``, the number of available cores on the machine will be used instead.
+  The default is ``1`` which limits compression to a single thread. Note that
+  not all compression modes support threading in all environments. Currently,
+  only the XZ compression may support it.
+
+.. note::
+
+    Official CMake binaries available on ``cmake.org`` ship with a ``liblzma``
+    that does not support parallel compression.
diff --git a/Help/cpack_gen/cygwin.rst b/Help/cpack_gen/cygwin.rst
index 1c5f7af..c65653e 100644
--- a/Help/cpack_gen/cygwin.rst
+++ b/Help/cpack_gen/cygwin.rst
@@ -3,6 +3,11 @@
 
 Cygwin CPack generator (Cygwin).
 
+Variables affecting the CPack Cygwin generator
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+  - :variable:`CPACK_ARCHIVE_THREADS`
+
 Variables specific to CPack Cygwin generator
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
diff --git a/Help/cpack_gen/deb.rst b/Help/cpack_gen/deb.rst
index db71c87..bf50c55 100644
--- a/Help/cpack_gen/deb.rst
+++ b/Help/cpack_gen/deb.rst
@@ -25,8 +25,8 @@
 Here are some CPack DEB generator wiki resources that are here for historic
 reasons and are no longer maintained but may still prove useful:
 
- - https://gitlab.kitware.com/cmake/community/wikis/doc/cpack/Configuration
- - https://gitlab.kitware.com/cmake/community/wikis/doc/cpack/PackageGenerators#deb-unix-only
+ - https://gitlab.kitware.com/cmake/community/-/wikis/doc/cpack/Configuration
+ - https://gitlab.kitware.com/cmake/community/-/wikis/doc/cpack/PackageGenerators#deb-unix-only
 
 List of CPack DEB generator specific variables:
 
@@ -282,7 +282,7 @@
    You may need set :variable:`CMAKE_INSTALL_RPATH` to an appropriate value
    if you use this feature, because if you don't ``dpkg-shlibdeps``
    may fail to find your own shared libs.
-   See https://gitlab.kitware.com/cmake/community/wikis/doc/cmake/RPATH-handling
+   See https://gitlab.kitware.com/cmake/community/-/wikis/doc/cmake/RPATH-handling
 
 .. variable:: CPACK_DEBIAN_PACKAGE_DEBUG
 
diff --git a/Help/cpack_gen/external.rst b/Help/cpack_gen/external.rst
index 406f6be..7ef1071 100644
--- a/Help/cpack_gen/external.rst
+++ b/Help/cpack_gen/external.rst
@@ -281,3 +281,10 @@
   It is invoked after (optional) staging took place and may
   run an external packaging tool. The script has access to
   the variables defined by the CPack config file.
+
+.. variable:: CPACK_EXTERNAL_BUILT_PACKAGES
+
+  The ``CPACK_EXTERNAL_PACKAGE_SCRIPT`` script may set this list variable to the
+  full paths of generated package files.  CPack copy these files from the stage
+  directory back to the top build directory and possibly produce checksum files
+  if the :variable:`CPACK_PACKAGE_CHECKSUM` is set.
diff --git a/Help/cpack_gen/freebsd.rst b/Help/cpack_gen/freebsd.rst
index a8dd320..47a7784 100644
--- a/Help/cpack_gen/freebsd.rst
+++ b/Help/cpack_gen/freebsd.rst
@@ -3,6 +3,11 @@
 
 The built in (binary) CPack FreeBSD (pkg) generator (Unix only)
 
+Variables affecting the CPack FreeBSD (pkg) generator
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+  - :variable:`CPACK_ARCHIVE_THREADS`
+
 Variables specific to CPack FreeBSD (pkg) generator
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
diff --git a/Help/cpack_gen/ifw.rst b/Help/cpack_gen/ifw.rst
index 4a9ab99..776bb46 100644
--- a/Help/cpack_gen/ifw.rst
+++ b/Help/cpack_gen/ifw.rst
@@ -1,73 +1,28 @@
 CPack IFW Generator
 -------------------
 
+Configure and run the Qt Installer Framework to generate a Qt installer.
+
+.. only:: html
+
+  .. contents::
+
 Overview
 ^^^^^^^^
 
 This :manual:`cpack generator <cpack-generators(7)>` generates
 configuration and meta information for the `Qt Installer Framework
-<http://doc.qt.io/qtinstallerframework/index.html>`_ (QtIFW).
+<http://doc.qt.io/qtinstallerframework/index.html>`_ (QtIFW),
+and runs QtIFW tools to generate a Qt installer.
 
 QtIFW provides tools and utilities to create installers for
 the platforms supported by `Qt <https://www.qt.io>`_: Linux,
 Microsoft Windows, and macOS.
 
-To make use of this generator, QtIFW should also be installed.
-The module :module:`CPackIFW` looks for the location of the
-QtIFW command-line utilities.
-
-Hints
-^^^^^
-
-Generally, the CPack ``IFW`` generator automatically finds QtIFW tools,
-but if you don't use a default path for installation of the QtIFW tools,
-the path may be specified in either a CMake or an environment variable:
-
-.. variable:: CPACK_IFW_ROOT
-
- An CMake variable which specifies the location of the QtIFW tool suite.
-
- The variable will be cached in the ``CPackConfig.cmake`` file and used at
- CPack runtime.
-
-.. variable:: QTIFWDIR
-
- An environment variable which specifies the location of the QtIFW tool
- suite.
-
-.. note::
-  The specified path should not contain "bin" at the end
-  (for example: "D:\\DevTools\\QtIFW2.0.5").
-
-The :variable:`CPACK_IFW_ROOT` variable has a higher priority and overrides
-the value of the :variable:`QTIFWDIR` variable.
-
-Internationalization
-^^^^^^^^^^^^^^^^^^^^
-
-Some variables and command arguments support internationalization via
-CMake script. This is an optional feature.
-
-Installers created by QtIFW tools have built-in support for
-internationalization and many phrases are localized to many languages,
-but this does not apply to the description of the your components and groups
-that will be distributed.
-
-Localization of the description of your components and groups is useful for
-users of your installers.
-
-A localized variable or argument can contain a single default value, and a
-set of pairs the name of the locale and the localized value.
-
-For example:
-
-.. code-block:: cmake
-
-   set(LOCALIZABLE_VARIABLE "Default value"
-     en "English value"
-     en_US "American value"
-     en_GB "Great Britain value"
-     )
+To make use of this generator, QtIFW needs to be installed.
+The :module:`CPackIFW` module looks for the location of the
+QtIFW command-line utilities, and defines several commands to
+control the behavior of this generator.
 
 Variables
 ^^^^^^^^^
@@ -157,6 +112,8 @@
  Default target directory for installation.
  By default used
  "@ApplicationsDir@/:variable:`CPACK_PACKAGE_INSTALL_DIRECTORY`"
+ (variables embedded in '@' are expanded by the
+ `QtIFW scripting engine <https://doc.qt.io/qtinstallerframework/scripting.html>`_).
 
  You can use predefined variables.
 
@@ -263,55 +220,111 @@
  repack dependent components. This feature available only
  since QtIFW 3.1.
 
-Tools
-"""""
+QtIFW Tools
+"""""""""""
 
 .. variable:: CPACK_IFW_FRAMEWORK_VERSION
 
  The version of used QtIFW tools.
 
+The following variables provide the locations of the QtIFW
+command-line tools as discovered by the module :module:`CPackIFW`.
+These variables are cached, and may be configured if needed.
+
 .. variable:: CPACK_IFW_BINARYCREATOR_EXECUTABLE
 
- The path to "binarycreator" command line client.
-
- This variable is cached and may be configured if needed.
+ The path to ``binarycreator``.
 
 .. variable:: CPACK_IFW_REPOGEN_EXECUTABLE
 
- The path to "repogen" command line client.
-
- This variable is cached and may be configured if needed.
+ The path to ``repogen``.
 
 .. variable:: CPACK_IFW_INSTALLERBASE_EXECUTABLE
 
- The path to "installerbase" installer executable base.
-
- This variable is cached and may be configured if needed.
+ The path to ``installerbase``.
 
 .. variable:: CPACK_IFW_DEVTOOL_EXECUTABLE
 
- The path to "devtool" command line client.
+ The path to ``devtool``.
 
- This variable is cached and may be configured if needed.
+Hints for Finding QtIFW
+"""""""""""""""""""""""
 
+Generally, the CPack ``IFW`` generator automatically finds QtIFW tools,
+but if you don't use a default path for installation of the QtIFW tools,
+the path may be specified in either a CMake or an environment variable:
+
+.. variable:: CPACK_IFW_ROOT
+
+ An CMake variable which specifies the location of the QtIFW tool suite.
+
+ The variable will be cached in the ``CPackConfig.cmake`` file and used at
+ CPack runtime.
+
+.. variable:: QTIFWDIR
+
+ An environment variable which specifies the location of the QtIFW tool
+ suite.
+
+.. note::
+  The specified path should not contain "bin" at the end
+  (for example: "D:\\DevTools\\QtIFW2.0.5").
+
+The :variable:`CPACK_IFW_ROOT` variable has a higher priority and overrides
+the value of the :variable:`QTIFWDIR` variable.
+
+Other Settings
+^^^^^^^^^^^^^^
 
 Online installer
-^^^^^^^^^^^^^^^^
+""""""""""""""""
 
-By default CPack IFW generator makes offline installer. This means that all
-components will be packaged into a binary file.
+By default, this generator generates an *offline installer*. This means that
+that all packaged files are fully contained in the installer executable.
 
-To make a component downloaded, you must set the ``DOWNLOADED`` option in
-:command:`cpack_add_component`.
+In contrast, an *online installer* will download some or all components from
+a remote server.
 
-Then you would use the command :command:`cpack_configure_downloads`.
-If you set ``ALL`` option all components will be downloaded.
+The ``DOWNLOADED`` option in the :command:`cpack_add_component` command
+specifies that a component is to be downloaded. Alternatively, the ``ALL``
+option in the :command:`cpack_configure_downloads` command specifies that
+`all` components are to be be downloaded.
 
-You also can use command :command:`cpack_ifw_add_repository` and
-variable :variable:`CPACK_IFW_DOWNLOAD_ALL` for more specific configuration.
+The :command:`cpack_ifw_add_repository` command and the
+:variable:`CPACK_IFW_DOWNLOAD_ALL` variable allow for more specific
+configuration.
 
-CPack IFW generator creates "repository" dir in current binary dir. You
-would copy content of this dir to specified ``site`` (``url``).
+When there are online components, CPack will write them to archive files.
+The help page of the :module:`CPackComponent` module, especially the section
+on the :command:`cpack_configure_downloads` function, explains how to make
+these files accessible from a download URL.
+
+Internationalization
+""""""""""""""""""""
+
+Some variables and command arguments support internationalization via
+CMake script. This is an optional feature.
+
+Installers created by QtIFW tools have built-in support for
+internationalization and many phrases are localized to many languages,
+but this does not apply to the description of the your components and groups
+that will be distributed.
+
+Localization of the description of your components and groups is useful for
+users of your installers.
+
+A localized variable or argument can contain a single default value, and a
+set of pairs the name of the locale and the localized value.
+
+For example:
+
+.. code-block:: cmake
+
+   set(LOCALIZABLE_VARIABLE "Default value"
+     en "English value"
+     en_US "American value"
+     en_GB "Great Britain value"
+     )
 
 See Also
 ^^^^^^^^
@@ -330,5 +343,5 @@
 * Promoting Updates:
   http://doc.qt.io/qtinstallerframework/ifw-updates.html
 
-Download Qt Installer Framework for you platform from Qt site:
+Download Qt Installer Framework for your platform from Qt site:
  http://download.qt.io/official_releases/qt-installer-framework
diff --git a/Help/cpack_gen/nsis.rst b/Help/cpack_gen/nsis.rst
index d1e495f..0dd876e 100644
--- a/Help/cpack_gen/nsis.rst
+++ b/Help/cpack_gen/nsis.rst
@@ -155,3 +155,7 @@
 .. variable:: CPACK_NSIS_MUI_HEADERIMAGE
 
  The image to display on the header of installers pages.
+
+.. variable:: CPACK_NSIS_MANIFEST_DPI_AWARE
+
+ If set, declares that the installer is DPI-aware.
diff --git a/Help/cpack_gen/packagemaker.rst b/Help/cpack_gen/packagemaker.rst
index c2a450e..357eb73 100644
--- a/Help/cpack_gen/packagemaker.rst
+++ b/Help/cpack_gen/packagemaker.rst
@@ -29,7 +29,7 @@
 
 .. variable:: CPACK_PACKAGEMAKER_BACKGROUND
 
- Adds a background to Distribtion XML if specified. The value contains the
+ Adds a background to Distribution XML if specified. The value contains the
  path to image in ``Resources`` directory.
 
 .. variable:: CPACK_PACKAGEMAKER_BACKGROUND_ALIGNMENT
diff --git a/Help/cpack_gen/productbuild.rst b/Help/cpack_gen/productbuild.rst
index 82b79ae..fd99e5a 100644
--- a/Help/cpack_gen/productbuild.rst
+++ b/Help/cpack_gen/productbuild.rst
@@ -68,7 +68,7 @@
 
 .. variable:: CPACK_PRODUCTBUILD_BACKGROUND
 
- Adds a background to Distribtion XML if specified. The value contains the
+ Adds a background to Distribution XML if specified. The value contains the
  path to image in ``Resources`` directory.
 
 .. variable:: CPACK_PRODUCTBUILD_BACKGROUND_ALIGNMENT
diff --git a/Help/cpack_gen/rpm.rst b/Help/cpack_gen/rpm.rst
index 2693c7b..ccb7ebd 100644
--- a/Help/cpack_gen/rpm.rst
+++ b/Help/cpack_gen/rpm.rst
@@ -36,8 +36,8 @@
 Here are some CPack RPM generator wiki resources that are here for historic
 reasons and are no longer maintained but may still prove useful:
 
- - https://gitlab.kitware.com/cmake/community/wikis/doc/cpack/Configuration
- - https://gitlab.kitware.com/cmake/community/wikis/doc/cpack/PackageGenerators#rpm-unix-only
+ - https://gitlab.kitware.com/cmake/community/-/wikis/doc/cpack/Configuration
+ - https://gitlab.kitware.com/cmake/community/-/wikis/doc/cpack/PackageGenerators#rpm-unix-only
 
 List of CPack RPM generator specific variables:
 
@@ -473,38 +473,42 @@
 
 .. variable:: CPACK_RPM_PRE_INSTALL_SCRIPT_FILE
               CPACK_RPM_PRE_UNINSTALL_SCRIPT_FILE
+              CPACK_RPM_PRE_TRANS_SCRIPT_FILE
 
- Path to file containing pre (un)install script.
+ Path to file containing pre install/uninstall/transaction script.
 
  * Mandatory : NO
  * Default   : -
 
- May be used to embed a pre (un)installation script in the spec file.
+ May be used to embed a pre installation/uninstallation/transaction script in the spec file.
  The referred script file (or both) will be read and directly
  put after the ``%pre`` or ``%preun`` section
- If :variable:`CPACK_RPM_COMPONENT_INSTALL` is set to ON the (un)install
+ If :variable:`CPACK_RPM_COMPONENT_INSTALL` is set to ON the install/uninstall/transaction
  script for each component can be overridden with
- ``CPACK_RPM_<COMPONENT>_PRE_INSTALL_SCRIPT_FILE`` and
- ``CPACK_RPM_<COMPONENT>_PRE_UNINSTALL_SCRIPT_FILE``.
+ ``CPACK_RPM_<COMPONENT>_PRE_INSTALL_SCRIPT_FILE``,
+ ``CPACK_RPM_<COMPONENT>_PRE_UNINSTALL_SCRIPT_FILE``, and
+ ``CPACK_RPM_<COMPONENT>_PRE_TRANS_SCRIPT_FILE``
  One may verify which scriptlet has been included with::
 
   rpm -qp --scripts  package.rpm
 
 .. variable:: CPACK_RPM_POST_INSTALL_SCRIPT_FILE
               CPACK_RPM_POST_UNINSTALL_SCRIPT_FILE
+              CPACK_RPM_POST_TRANS_SCRIPT_FILE
 
- Path to file containing post (un)install script.
+ Path to file containing post install/uninstall/transaction script.
 
  * Mandatory : NO
  * Default   : -
 
- May be used to embed a post (un)installation script in the spec file.
+ May be used to embed a post installation/uninstallation/transaction script in the spec file.
  The referred script file (or both) will be read and directly
  put after the ``%post`` or ``%postun`` section.
- If :variable:`CPACK_RPM_COMPONENT_INSTALL` is set to ON the (un)install
+ If :variable:`CPACK_RPM_COMPONENT_INSTALL` is set to ON the install/uninstall/transaction
  script for each component can be overridden with
- ``CPACK_RPM_<COMPONENT>_POST_INSTALL_SCRIPT_FILE`` and
- ``CPACK_RPM_<COMPONENT>_POST_UNINSTALL_SCRIPT_FILE``.
+ ``CPACK_RPM_<COMPONENT>_POST_INSTALL_SCRIPT_FILE``,
+ ``CPACK_RPM_<COMPONENT>_POST_UNINSTALL_SCRIPT_FILE``, and
+ ``CPACK_RPM_<COMPONENT>_POST_TRANS_SCRIPT_FILE``
  One may verify which scriptlet has been included with::
 
   rpm -qp --scripts  package.rpm
diff --git a/Help/dev/maint.rst b/Help/dev/maint.rst
index a1c1a6f..4c2c89f 100644
--- a/Help/dev/maint.rst
+++ b/Help/dev/maint.rst
@@ -200,6 +200,23 @@
   Add section headers similar to the $prev release notes and move each
   individual bullet into an appropriate section.  Revise a few bullets.
 
+Update Sphinx ``versionadded`` directives in documents added since
+the previous release by running the `update_versions.py`_ script:
+
+.. code-block:: shell
+
+  Utilities/Sphinx/update_versions.py --since v$prev.0 --overwrite
+
+.. _`update_versions.py`: ../../Utilities/Sphinx/update_versions.py
+
+Commit the changes with a message such as::
+
+  Help: Update Sphinx versionadded directives for $ver release
+
+  Run the script:
+
+      Utilities/Sphinx/update_versions.py --since v$prev.0 --overwrite
+
 Open a merge request with the ``doc-$ver-relnotes`` branch for review
 and integration.  Further steps may proceed after this has been merged
 to ``master``.
@@ -299,3 +316,28 @@
   before staging or merging.
 
 .. _`CMake Discourse Forum Development Category`: https://discourse.cmake.org/c/development
+
+Initial Post-Release Development
+--------------------------------
+
+Deprecate policies more than 8 release series old by updating the
+policy range check in ``cmMakefile::SetPolicy``.
+Commit with a message such as::
+
+  Add deprecation warnings for policies CMP#### and below
+
+  The OLD behaviors of all policies are deprecated, but only by
+  documentation.  Add an explicit deprecation diagnostic for policies
+  introduced in CMake $OLDVER and below to encourage projects to port
+  away from setting policies to OLD.
+
+Update the ``cmake_policy`` version range generated by ``install(EXPORT)``
+in ``cmExportFileGenerator::GeneratePolicyHeaderCode`` to end at the
+previous release.  We use one release back since we now know all the
+policies added for that version.  Commit with a message such as::
+
+  export: Increase maximum policy version in exported files to $prev
+
+  The files generatd by `install(EXPORT)` and `export()` commands
+  are known to work with policies as of CMake $prev, so enable them
+  in sufficiently new CMake versions.
diff --git a/Help/dev/review.rst b/Help/dev/review.rst
index 8ec41d2..f2a91c0 100644
--- a/Help/dev/review.rst
+++ b/Help/dev/review.rst
@@ -28,7 +28,7 @@
 This will cause the MR topic branch to be automatically removed from
 the user's fork during the `Merge`_ step.
 
-.. _`CMake Merge Requests Page`: https://gitlab.kitware.com/cmake/cmake/merge_requests
+.. _`CMake Merge Requests Page`: https://gitlab.kitware.com/cmake/cmake/-/merge_requests
 .. _`CMake Repository`: https://gitlab.kitware.com/cmake/cmake
 
 Workflow Status
@@ -60,7 +60,7 @@
 The workflow status labels are intended to be mutually exclusive,
 so please remove any existing workflow label when adding one.
 
-.. _`CMake GitLab Project Developers`: https://gitlab.kitware.com/cmake/cmake/settings/members
+.. _`CMake GitLab Project Developers`: https://gitlab.kitware.com/cmake/cmake/-/settings/members
 
 Robot Review
 ============
@@ -260,7 +260,7 @@
 If the commit is a fix for the mentioned commit, consider using a ``Fixes:``
 trailer in the commit message with the specified format. This trailer should
 not be word-wrapped. Note that if there is also an issue for what is being
-fixed, it is preferrable to link to the issue instead.
+fixed, it is preferable to link to the issue instead.
 
 If relevant, add the first release tag of CMake containing the commit after
 the ``<date>``, i.e., ``commit <shorthash> (<subject>, <date>, <tag>)``.
@@ -278,42 +278,52 @@
 Topic Testing
 =============
 
-CMake has a `buildbot`_ instance watching for merge requests to test.
-`CMake GitLab Project Developers`_ may activate buildbot on a MR by
-adding a comment with a command among the `comment trailing lines`_::
+CMake uses `GitLab CI`_ to test merge requests, configured by the top-level
+``.gitlab-ci.yml`` file.  Results may be seen both on the merge request's
+pipeline page and on the `CMake CDash Page`_.  Filtered CDash results
+showing just the pipeline's jobs can be reached by selecting the ``cdash``
+job in the ``External`` stage of the pipeline.
 
-  Do: test
+Lint and documentation build jobs run automatically after every push.
+Heavier jobs require a manual trigger to run:
 
-``@kwrobot`` will add an award emoji to the comment to indicate that it
-was processed and also inform buildbot about the request.  The buildbot
-user (``@buildbot``) will schedule builds and respond with a comment
-linking to the `CMake CDash Page`_ with a filter for results associated
-with the topic test request.  If the MR topic branch is updated by a
-push a new ``Do: test`` command is needed to activate testing again.
+* Merge request authors may visit their merge request's pipeline and click the
+  "Play" button on one or more jobs manually.  If the merge request has the
+  "Allow commits from members who can merge to the target branch" check box
+  enabled, CMake maintainers may use the "Play" button too.
 
-The ``Do: test`` command accepts the following arguments:
+* `CMake GitLab Project Developers`_ may trigger CI on a merge request by
+  adding a comment with a command among the `comment trailing lines`_::
 
-* ``--stop``: clear the list of commands for the merge request
-* ``--clear``: clear previous commands before adding this command
-* ``--regex-include <arg>`` or ``-i <arg>``: only build on builders
-  matching ``<arg>`` (a Python regular expression)
-* ``--regex-exclude <arg>`` or ``-e <arg>``: exclude builds on builders
-  matching ``<arg>`` (a Python regular expression)
+    Do: test
 
-Builder names follow the pattern ``project-host-os-buildtype-generator``:
+  ``@kwrobot`` will add an award emoji to the comment to indicate that it
+  was processed and also trigger all manual jobs in the merge request's
+  pipeline.
 
-* ``project``: always ``cmake`` for CMake builds
-* ``host``: the buildbot host
-* ``os``: one of ``windows``, ``osx``, or ``linux``
-* ``buildtype``: ``release`` or ``debug``
-* ``generator``: ``ninja``, ``makefiles``, ``vs<year>``,
-  or ``lint-iwyu-tidy``
+  The ``Do: test`` command accepts the following arguments:
 
-The special ``lint-<tools>`` generator name is a builder that builds
-CMake using lint tools but does not run the test suite (so the actual
-generator does not matter).
+  * ``--named <regex>``, ``-n <regex>``: Trigger jobs matching ``<regex>``
+    anywhere in their name.  Job names may be seen on the merge request's
+    pipeline page.
+  * ``--stage <stage>``, ``-s <stage>``: Only affect jobs in a given stage.
+    Stage names may be seen on the merge request's pipeline page.  Note that
+    the names are determined by what is in the ``.gitlab-ci.yml`` file and may
+    be capitalized in the web page, so lowercasing the webpage's display name
+    for stages may be required.
+  * ``--action <action>``, ``-a <action>``: The action to perform on the jobs.
+    Possible actions:
 
-.. _`buildbot`: http://buildbot.net
+    * ``manual`` (the default): Start jobs awaiting manual interaction.
+    * ``unsuccessful``: Start or restart jobs which have not completed
+      successfully.
+    * ``failed``: Restart jobs which have completed, but without success.
+    * ``completed``: Restart all completed jobs.
+
+If the merge request topic branch is updated by a push, a new manual trigger
+using one of the above methods is needed to start CI again.
+
+.. _`GitLab CI`: https://gitlab.kitware.com/help/ci/README.md
 .. _`CMake CDash Page`: https://open.cdash.org/index.php?project=CMake
 
 Integration Testing
@@ -454,8 +464,8 @@
   The ``-t`` option to a ``Do: merge`` command overrides any topic
   rename set in the MR description.
 
-.. _`CMake GitLab Project Masters`: https://gitlab.kitware.com/cmake/cmake/settings/members
-.. _`backport instructions`: https://gitlab.kitware.com/utils/git-workflow/wikis/Backport-topics
+.. _`CMake GitLab Project Masters`: https://gitlab.kitware.com/cmake/cmake/-/settings/members
+.. _`backport instructions`: https://gitlab.kitware.com/utils/git-workflow/-/wikis/Backport-topics
 .. _`git rev-parse`: https://git-scm.com/docs/git-rev-parse
 
 Close
diff --git a/Help/dev/source.rst b/Help/dev/source.rst
index 0f7488b..d93e55c 100644
--- a/Help/dev/source.rst
+++ b/Help/dev/source.rst
@@ -23,12 +23,163 @@
 C++ Subset Permitted
 ====================
 
-CMake requires compiling as C++11 or above.  However, in order to support
-building on older toolchains some constructs need to be handled with care:
+CMake requires compiling as C++11 in order to support building on older
+toolchains.  However, to facilitate development, some standard library
+features from more recent C++ standards are supported through a compatibility
+layer.  These features are defined under the namespace ``cm`` and headers
+are accessible under the ``cm/`` directory.  The headers under ``cm/`` can
+be used in place of the standard ones when extended features are needed.
+For example ``<cm/memory>`` can be used in place of ``<memory>``.
 
-* Do not use ``std::auto_ptr``.
+Available features are:
 
-  The ``std::auto_ptr`` template is deprecated in C++11. Use ``std::unique_ptr``.
+* From ``C++14``:
+
+  * ``<cm/iomanip>``:
+    ``cm::quoted``
+
+  * ``<cm/iterator>``:
+    ``cm::make_reverse_iterator``, ``cm::cbegin``, ``cm::cend``,
+    ``cm::rbegin``, ``cm::rend``, ``cm::crbegin``, ``cm::crend``
+
+  * ``<cm/memory>``:
+    ``cm::make_unique``
+
+  * ``<cm/shared_mutex>``:
+    ``cm::shared_lock``
+
+  * ``<cm/type_traits>``:
+    ``cm::enable_if_t``
+
+* From ``C++17``:
+
+  * ``<cm/algorithm>``:
+    ``cm::clamp``
+
+  * ``cm/filesystem>``:
+    ``cm::filesystem::path``
+
+  * ``<cm/iterator>``:
+    ``cm::size``, ``cm::empty``, ``cm::data``
+
+  * ``<cm/optional>``:
+    ``cm::nullopt_t``, ``cm::nullopt``, ``cm::optional``,
+    ``cm::make_optional``, ``cm::bad_optional_access``
+
+  * ``<cm/shared_mutex>``:
+    ``cm::shared_mutex``
+
+  * ``<cm/string_view>``:
+    ``cm::string_view``
+
+  * ``<cm/type_traits>``:
+    ``cm::bool_constant``, ``cm::invoke_result_t``, ``cm::invoke_result``,
+    ``cm::void_t``
+
+  * ``<cm/utility>``:
+    ``cm::in_place_t``, ``cm::in_place``
+
+* From ``C++20``:
+
+  * ``<cm/deque>``:
+    ``cm::erase``, ``cm::erase_if``
+
+  * ``<cm/list>``:
+    ``cm::erase``, ``cm::erase_if``
+
+  * ``<cm/map>`` :
+    ``cm::erase_if``
+
+  * ``<cm/set>`` :
+    ``cm::erase_if``
+
+  * ``<cm/string>``:
+    ``cm::erase``, ``cm::erase_if``
+
+  * ``<cm/unordered_map>``:
+    ``cm::erase_if``
+
+  * ``<cm/unordered_set>``:
+    ``cm::erase_if``
+
+  * ``<cm/vector>``:
+    ``cm::erase``, ``cm::erase_if``
+
+Additionally, some useful non-standard extensions to the C++ standard library
+are available in headers under the directory ``cmext/`` in namespace ``cm``.
+These are:
+
+* ``<cmext/algorithm>``:
+
+  * ``cm::append``:
+    Append elements to a sequential container.
+
+  * ``cm::contains``:
+    Checks if element or key is contained in container.
+
+* ``<cmext/iterator>``:
+
+  * ``cm::is_terator``:
+    Checks if a type is an iterator type.
+
+  * ``cm::is_input_iterator``:
+    Checks if a type is an input iterator type.
+
+  * ``cm::is_range``:
+    Checks if a type is a range type: functions ``std::begin()`` and
+    ``std::end()`` apply.
+
+  * ``cm::is_input_range``:
+    Checks if a type is an input range type: functions ``std::begin()`` and
+    ``std::end()`` apply and return an input iterator.
+
+* ``<cmext/memory>``:
+
+  * ``cm::static_reference_cast``:
+    Apply a ``static_cast`` to a smart pointer.
+
+  * ``cm::dynamic_reference_cast``:
+    Apply a ``dynamic_cast`` to a smart pointer.
+
+* ``<cmext/type_traits>``:
+
+  * ``cm::is_container``:
+    Checks if a type is a container type.
+
+  * ``cm::is_associative_container``:
+    Checks if a type is an associative container type.
+
+  * ``cm::is_unordered_associative_container``:
+    Checks if a type is an unordered associative container type.
+
+  * ``cm::is_sequence_container``:
+    Checks if a type is a sequence container type.
+
+  * ``cm::is_unique_ptr``:
+    Checks if a type is a ``std::unique_ptr`` type.
+
+Dynamic Memory Management
+=========================
+
+To ensure efficient memory management, i.e. no memory leaks, it is required
+to use smart pointers.  Any dynamic memory allocation must be handled by a
+smart pointer such as ``std::unique_ptr`` or ``std::shared_ptr``.
+
+It is allowed to pass raw pointers between objects to enable objects sharing.
+A raw pointer **must** not be deleted. Only the object(s) owning the smart
+pointer are allowed to delete dynamically allocated memory.
+
+Third Parties
+=============
+
+To build CMake, some third parties are needed. Under ``Utilities``
+directory, are versions of these third parties which can be used as an
+alternate to the ones provided by the system.
+
+To enable the selection of the third parties between the system and CMake ones,
+in CMake sources, third parties headers must be prefixed by ``cm3p/``
+(for example: ``<cm3p/json/reader.h>``). These wrappers are located under
+``Utilities/cm3p`` directory.
 
 Source Tree Layout
 ==================
@@ -69,6 +220,15 @@
 * ``Utilities/``:
   Scripts, third-party source code.
 
+  * ``Utilities/std/cm``:
+    Support files for various C++ standards.
+
+  * ``Utilities/std/cmext``:
+    Extensions to the C++ STL.
+
+  * ``Utilities/cm3p``:
+    Public headers for third parties needed to build CMake.
+
   * ``Utilities/Sphinx/``:
     Sphinx configuration to build CMake user documentation.
 
diff --git a/Help/dev/testing.rst b/Help/dev/testing.rst
index 23d0ca3..279e4b2 100644
--- a/Help/dev/testing.rst
+++ b/Help/dev/testing.rst
@@ -33,7 +33,7 @@
 .. _`CMake Review Process`: review.rst
 .. _`CMake CDash Page`: https://open.cdash.org/index.php?project=CMake
 .. _`CMake Dashboard Scripts Repository`: https://gitlab.kitware.com/cmake/dashboard-scripts
-.. _`cmake_common.cmake`: https://gitlab.kitware.com/cmake/dashboard-scripts/blob/master/cmake_common.cmake
+.. _`cmake_common.cmake`: https://gitlab.kitware.com/cmake/dashboard-scripts/-/blob/master/cmake_common.cmake
 
 Nightly Start Time
 ------------------
diff --git a/Help/envvar/ASM_DIALECT.rst b/Help/envvar/ASM_DIALECT.rst
index a06e3cb..a606280 100644
--- a/Help/envvar/ASM_DIALECT.rst
+++ b/Help/envvar/ASM_DIALECT.rst
@@ -1,6 +1,8 @@
 ASM<DIALECT>
 ------------
 
+.. versionadded:: 3.10
+
 .. include:: ENV_VAR.txt
 
 Preferred executable for compiling a specific dialect of assembly language
@@ -12,3 +14,11 @@
 :variable:`CMAKE_ASM<DIALECT>_COMPILER <CMAKE_<LANG>_COMPILER>`. For subsequent
 configuration runs, the environment variable will be ignored in favor of
 :variable:`CMAKE_ASM<DIALECT>_COMPILER <CMAKE_<LANG>_COMPILER>`.
+
+.. note::
+  Options that are required to make the compiler work correctly can be included;
+  they can not be changed.
+
+.. code-block:: console
+
+  $ export ASM="custom-compiler --arg1 --arg2"
diff --git a/Help/envvar/ASM_DIALECTFLAGS.rst b/Help/envvar/ASM_DIALECTFLAGS.rst
index 3c3b02a..66a75e2 100644
--- a/Help/envvar/ASM_DIALECTFLAGS.rst
+++ b/Help/envvar/ASM_DIALECTFLAGS.rst
@@ -1,6 +1,8 @@
 ASM<DIALECT>FLAGS
 -----------------
 
+.. versionadded:: 3.10
+
 .. include:: ENV_VAR.txt
 
 Default compilation flags to be used when compiling a specific dialect of an
@@ -11,3 +13,5 @@
 as ``CMAKE_ASM<DIALECT>_FLAGS <CMAKE_<LANG>_FLAGS>``.  For any configuration
 run (including the first), the environment variable will be ignored, if the
 ``CMAKE_ASM<DIALECT>_FLAGS <CMAKE_<LANG>_FLAGS>`` variable is defined.
+
+See also :variable:`CMAKE_ASM<DIALECT>_FLAGS_INIT <CMAKE_<LANG>_FLAGS_INIT>`.
diff --git a/Help/envvar/CC.rst b/Help/envvar/CC.rst
index ef12059..4c970b4 100644
--- a/Help/envvar/CC.rst
+++ b/Help/envvar/CC.rst
@@ -1,6 +1,8 @@
 CC
 --
 
+.. versionadded:: 3.10
+
 .. include:: ENV_VAR.txt
 
 Preferred executable for compiling ``C`` language files. Will only be used by
@@ -9,3 +11,11 @@
 :variable:`CMAKE_C_COMPILER <CMAKE_<LANG>_COMPILER>`. For any configuration run
 (including the first), the environment variable will be ignored if the
 :variable:`CMAKE_C_COMPILER <CMAKE_<LANG>_COMPILER>` variable is defined.
+
+.. note::
+  Options that are required to make the compiler work correctly can be included;
+  they can not be changed.
+
+.. code-block:: console
+
+  $ export CC="custom-compiler --arg1 --arg2"
diff --git a/Help/envvar/CCMAKE_COLORS.rst b/Help/envvar/CCMAKE_COLORS.rst
new file mode 100644
index 0000000..4e76bf8
--- /dev/null
+++ b/Help/envvar/CCMAKE_COLORS.rst
@@ -0,0 +1,36 @@
+CCMAKE_COLORS
+-------------
+
+.. versionadded:: 3.18
+
+Determines what colors are used by the CMake curses interface,
+when run on a terminal that supports colors.
+The syntax follows the same conventions as ``LS_COLORS``;
+that is, a list of key/value pairs separated by ``:``.
+
+Keys are a single letter corresponding to a CMake cache variable type:
+
+- ``s``: A ``STRING``.
+- ``p``: A ``FILEPATH``.
+- ``c``: A value which has an associated list of choices.
+- ``y``: A ``BOOL`` which has a true-like value (e.g. ``ON``, ``YES``).
+- ``n``: A ``BOOL`` which has a false-like value (e.g. ``OFF``, ``NO``).
+
+Values are an integer number that specifies what color to use.
+``0`` is black (you probably don't want to use that).
+Others are determined by your terminal's color support.
+Most (color) terminals will support at least 8 or 16 colors.
+Some will support up to 256 colors. The colors will likely match
+`this chart <https://upload.wikimedia.org/wikipedia/commons/1/15/Xterm_256color_chart.svg>`_,
+although the first 16 colors may match the original
+`CGA color palette <https://en.wikipedia.org/wiki/Color_Graphics_Adapter#Color_palette>`_.
+(Many modern terminal emulators also allow their color palette,
+at least for the first 16 colors, to be configured by the user.)
+
+Note that fairly minimal checking is done for bad colors
+(although a value higher than what curses believes your terminal supports
+will be silently ignored) or bad syntax.
+
+For example::
+
+  CCMAKE_COLORS='s=39:p=220:c=207:n=196:y=46'
diff --git a/Help/envvar/CFLAGS.rst b/Help/envvar/CFLAGS.rst
index fda9ccc..31db6a6 100644
--- a/Help/envvar/CFLAGS.rst
+++ b/Help/envvar/CFLAGS.rst
@@ -1,6 +1,8 @@
 CFLAGS
 ------
 
+.. versionadded:: 3.10
+
 .. include:: ENV_VAR.txt
 
 Default compilation flags to be used when compiling ``C`` files. Will only be
@@ -9,3 +11,5 @@
 as :variable:`CMAKE_C_FLAGS <CMAKE_<LANG>_FLAGS>`. For any configuration run
 (including the first), the environment variable will be ignored if the
 :variable:`CMAKE_C_FLAGS <CMAKE_<LANG>_FLAGS>` variable is defined.
+
+See also :variable:`CMAKE_C_FLAGS_INIT <CMAKE_<LANG>_FLAGS_INIT>`.
diff --git a/Help/envvar/CMAKE_BUILD_PARALLEL_LEVEL.rst b/Help/envvar/CMAKE_BUILD_PARALLEL_LEVEL.rst
index 199ca3e..dbc589a 100644
--- a/Help/envvar/CMAKE_BUILD_PARALLEL_LEVEL.rst
+++ b/Help/envvar/CMAKE_BUILD_PARALLEL_LEVEL.rst
@@ -1,6 +1,8 @@
 CMAKE_BUILD_PARALLEL_LEVEL
 --------------------------
 
+.. versionadded:: 3.12
+
 .. include:: ENV_VAR.txt
 
 Specifies the maximum number of concurrent processes to use when building
diff --git a/Help/envvar/CMAKE_CONFIG_TYPE.rst b/Help/envvar/CMAKE_CONFIG_TYPE.rst
index 168593d..c207a48 100644
--- a/Help/envvar/CMAKE_CONFIG_TYPE.rst
+++ b/Help/envvar/CMAKE_CONFIG_TYPE.rst
@@ -1,6 +1,8 @@
 CMAKE_CONFIG_TYPE
 -----------------
 
+.. versionadded:: 3.10
+
 .. include:: ENV_VAR.txt
 
 The default build configuration for :ref:`Build Tool Mode` and
diff --git a/Help/envvar/CMAKE_EXPORT_COMPILE_COMMANDS.rst b/Help/envvar/CMAKE_EXPORT_COMPILE_COMMANDS.rst
index e9e0810..9e678be 100644
--- a/Help/envvar/CMAKE_EXPORT_COMPILE_COMMANDS.rst
+++ b/Help/envvar/CMAKE_EXPORT_COMPILE_COMMANDS.rst
@@ -1,6 +1,8 @@
 CMAKE_EXPORT_COMPILE_COMMANDS
 -----------------------------
 
+.. versionadded:: 3.17
+
 .. include:: ENV_VAR.txt
 
 The default value for :variable:`CMAKE_EXPORT_COMPILE_COMMANDS` when there
diff --git a/Help/envvar/CMAKE_GENERATOR.rst b/Help/envvar/CMAKE_GENERATOR.rst
index f2d055f..3488b04 100644
--- a/Help/envvar/CMAKE_GENERATOR.rst
+++ b/Help/envvar/CMAKE_GENERATOR.rst
@@ -1,6 +1,8 @@
 CMAKE_GENERATOR
 ---------------
 
+.. versionadded:: 3.15
+
 .. include:: ENV_VAR.txt
 
 Specifies the CMake default generator to use when no generator is supplied
diff --git a/Help/envvar/CMAKE_GENERATOR_INSTANCE.rst b/Help/envvar/CMAKE_GENERATOR_INSTANCE.rst
index 1654fa1..8ca7d80 100644
--- a/Help/envvar/CMAKE_GENERATOR_INSTANCE.rst
+++ b/Help/envvar/CMAKE_GENERATOR_INSTANCE.rst
@@ -1,6 +1,8 @@
 CMAKE_GENERATOR_INSTANCE
 ------------------------
 
+.. versionadded:: 3.15
+
 .. include:: ENV_VAR.txt
 
 Default value for :variable:`CMAKE_GENERATOR_INSTANCE` if no Cache entry is
diff --git a/Help/envvar/CMAKE_GENERATOR_PLATFORM.rst b/Help/envvar/CMAKE_GENERATOR_PLATFORM.rst
index 917b30b..b039845 100644
--- a/Help/envvar/CMAKE_GENERATOR_PLATFORM.rst
+++ b/Help/envvar/CMAKE_GENERATOR_PLATFORM.rst
@@ -1,6 +1,8 @@
 CMAKE_GENERATOR_PLATFORM
 ------------------------
 
+.. versionadded:: 3.15
+
 .. include:: ENV_VAR.txt
 
 Default value for :variable:`CMAKE_GENERATOR_PLATFORM` if no Cache entry
diff --git a/Help/envvar/CMAKE_GENERATOR_TOOLSET.rst b/Help/envvar/CMAKE_GENERATOR_TOOLSET.rst
index 7ac3856..394dd88 100644
--- a/Help/envvar/CMAKE_GENERATOR_TOOLSET.rst
+++ b/Help/envvar/CMAKE_GENERATOR_TOOLSET.rst
@@ -1,6 +1,8 @@
 CMAKE_GENERATOR_TOOLSET
 -----------------------
 
+.. versionadded:: 3.15
+
 .. include:: ENV_VAR.txt
 
 Default value for :variable:`CMAKE_GENERATOR_TOOLSET` if no Cache entry
diff --git a/Help/envvar/CMAKE_LANG_COMPILER_LAUNCHER.rst b/Help/envvar/CMAKE_LANG_COMPILER_LAUNCHER.rst
index 4f91e9a..c384fa1 100644
--- a/Help/envvar/CMAKE_LANG_COMPILER_LAUNCHER.rst
+++ b/Help/envvar/CMAKE_LANG_COMPILER_LAUNCHER.rst
@@ -1,6 +1,8 @@
 CMAKE_<LANG>_COMPILER_LAUNCHER
 ------------------------------
 
+.. versionadded:: 3.17
+
 .. include:: ENV_VAR.txt
 
 Default compiler launcher to use for the specified language. Will only be used
diff --git a/Help/envvar/CMAKE_MSVCIDE_RUN_PATH.rst b/Help/envvar/CMAKE_MSVCIDE_RUN_PATH.rst
index 77ead4d..5babbe5 100644
--- a/Help/envvar/CMAKE_MSVCIDE_RUN_PATH.rst
+++ b/Help/envvar/CMAKE_MSVCIDE_RUN_PATH.rst
@@ -1,6 +1,8 @@
 CMAKE_MSVCIDE_RUN_PATH
 ----------------------
 
+.. versionadded:: 3.10
+
 .. include:: ENV_VAR.txt
 
 Extra PATH locations for custom commands when using
diff --git a/Help/envvar/CMAKE_NO_VERBOSE.rst b/Help/envvar/CMAKE_NO_VERBOSE.rst
index 149efbd..fe733f8 100644
--- a/Help/envvar/CMAKE_NO_VERBOSE.rst
+++ b/Help/envvar/CMAKE_NO_VERBOSE.rst
@@ -1,6 +1,8 @@
 CMAKE_NO_VERBOSE
 ----------------
 
+.. versionadded:: 3.14
+
 Disables verbose output from CMake when :envvar:`VERBOSE` environment variable
 is set.
 
diff --git a/Help/envvar/CMAKE_OSX_ARCHITECTURES.rst b/Help/envvar/CMAKE_OSX_ARCHITECTURES.rst
index ef7d547..4bfa36a 100644
--- a/Help/envvar/CMAKE_OSX_ARCHITECTURES.rst
+++ b/Help/envvar/CMAKE_OSX_ARCHITECTURES.rst
@@ -1,6 +1,8 @@
 CMAKE_OSX_ARCHITECTURES
 -----------------------
 
+.. versionadded:: 3.10
+
 .. include:: ENV_VAR.txt
 
 Target specific architectures for macOS.
diff --git a/Help/envvar/CMAKE_PREFIX_PATH.rst b/Help/envvar/CMAKE_PREFIX_PATH.rst
new file mode 100644
index 0000000..e5d6aa1
--- /dev/null
+++ b/Help/envvar/CMAKE_PREFIX_PATH.rst
@@ -0,0 +1,19 @@
+CMAKE_PREFIX_PATH
+-----------------
+
+.. versionadded:: 3.18
+
+.. include:: ENV_VAR.txt
+
+The ``CMAKE_PREFIX_PATH`` environment variable may be set to a list of
+directories specifying installation *prefixes* to be searched by the
+:command:`find_package`, :command:`find_program`, :command:`find_library`,
+:command:`find_file`, and :command:`find_path` commands.  Each command will
+add appropriate subdirectories (like ``bin``, ``lib``, or ``include``)
+as specified in its own documentation.
+
+This variable may hold a single prefix or a list of prefixes separated
+by ``:`` on UNIX or ``;`` on Windows (the same as the ``PATH`` environment
+variable convention on those platforms).
+
+See also the :variable:`CMAKE_PREFIX_PATH` CMake variable.
diff --git a/Help/envvar/CSFLAGS.rst b/Help/envvar/CSFLAGS.rst
index 404bb59..d875209 100644
--- a/Help/envvar/CSFLAGS.rst
+++ b/Help/envvar/CSFLAGS.rst
@@ -1,11 +1,15 @@
 CSFLAGS
 -------
 
+.. versionadded:: 3.10
+
 .. include:: ENV_VAR.txt
 
-Preferred executable for compiling ``CSharp`` language files. Will only be
+Default compilation flags to be used when compiling ``CSharp`` files. Will only be
 used by CMake on the first configuration to determine ``CSharp`` default
 compilation flags, after which the value for ``CSFLAGS`` is stored in the cache
 as :variable:`CMAKE_CSharp_FLAGS <CMAKE_<LANG>_FLAGS>`. For any configuration
 run (including the first), the environment variable will be ignored if the
 :variable:`CMAKE_CSharp_FLAGS <CMAKE_<LANG>_FLAGS>` variable is defined.
+
+See also :variable:`CMAKE_CSharp_FLAGS_INIT <CMAKE_<LANG>_FLAGS_INIT>`.
diff --git a/Help/envvar/CTEST_INTERACTIVE_DEBUG_MODE.rst b/Help/envvar/CTEST_INTERACTIVE_DEBUG_MODE.rst
index e1991b2..b27bc09 100644
--- a/Help/envvar/CTEST_INTERACTIVE_DEBUG_MODE.rst
+++ b/Help/envvar/CTEST_INTERACTIVE_DEBUG_MODE.rst
@@ -1,6 +1,8 @@
 CTEST_INTERACTIVE_DEBUG_MODE
 ----------------------------
 
+.. versionadded:: 3.10
+
 .. include:: ENV_VAR.txt
 
 Environment variable that will exist and be set to ``1`` when a test executed
diff --git a/Help/envvar/CTEST_OUTPUT_ON_FAILURE.rst b/Help/envvar/CTEST_OUTPUT_ON_FAILURE.rst
index d8b4262..9c6bd03 100644
--- a/Help/envvar/CTEST_OUTPUT_ON_FAILURE.rst
+++ b/Help/envvar/CTEST_OUTPUT_ON_FAILURE.rst
@@ -1,6 +1,8 @@
 CTEST_OUTPUT_ON_FAILURE
 -----------------------
 
+.. versionadded:: 3.10
+
 .. include:: ENV_VAR.txt
 
 Boolean environment variable that controls if the output should be logged for
diff --git a/Help/envvar/CTEST_PARALLEL_LEVEL.rst b/Help/envvar/CTEST_PARALLEL_LEVEL.rst
index fd4936e..a21c783 100644
--- a/Help/envvar/CTEST_PARALLEL_LEVEL.rst
+++ b/Help/envvar/CTEST_PARALLEL_LEVEL.rst
@@ -1,6 +1,8 @@
 CTEST_PARALLEL_LEVEL
 --------------------
 
+.. versionadded:: 3.10
+
 .. include:: ENV_VAR.txt
 
 Specify the number of tests for CTest to run in parallel. See :manual:`ctest(1)`
diff --git a/Help/envvar/CTEST_PROGRESS_OUTPUT.rst b/Help/envvar/CTEST_PROGRESS_OUTPUT.rst
index b36a6b8..8c29d7d 100644
--- a/Help/envvar/CTEST_PROGRESS_OUTPUT.rst
+++ b/Help/envvar/CTEST_PROGRESS_OUTPUT.rst
@@ -1,6 +1,8 @@
 CTEST_PROGRESS_OUTPUT
 ---------------------
 
+.. versionadded:: 3.13
+
 .. include:: ENV_VAR.txt
 
 Boolean environment variable that affects how :manual:`ctest <ctest(1)>`
diff --git a/Help/envvar/CTEST_USE_LAUNCHERS_DEFAULT.rst b/Help/envvar/CTEST_USE_LAUNCHERS_DEFAULT.rst
index 79dbb79..dffd63d 100644
--- a/Help/envvar/CTEST_USE_LAUNCHERS_DEFAULT.rst
+++ b/Help/envvar/CTEST_USE_LAUNCHERS_DEFAULT.rst
@@ -1,6 +1,8 @@
 CTEST_USE_LAUNCHERS_DEFAULT
 ---------------------------
 
+.. versionadded:: 3.10
+
 .. include:: ENV_VAR.txt
 
 Initializes the :variable:`CTEST_USE_LAUNCHERS` variable if not already defined.
diff --git a/Help/envvar/CUDACXX.rst b/Help/envvar/CUDACXX.rst
index 10c0f9d..69471b0 100644
--- a/Help/envvar/CUDACXX.rst
+++ b/Help/envvar/CUDACXX.rst
@@ -1,6 +1,8 @@
 CUDACXX
 -------
 
+.. versionadded:: 3.10
+
 .. include:: ENV_VAR.txt
 
 Preferred executable for compiling ``CUDA`` language files. Will only be used by
@@ -9,3 +11,11 @@
 :variable:`CMAKE_CUDA_COMPILER <CMAKE_<LANG>_COMPILER>`. For any configuration
 run (including the first), the environment variable will be ignored if the
 :variable:`CMAKE_CUDA_COMPILER <CMAKE_<LANG>_COMPILER>` variable is defined.
+
+.. note::
+  Options that are required to make the compiler work correctly can be included;
+  they can not be changed.
+
+.. code-block:: console
+
+  $ export CUDACXX="custom-compiler --arg1 --arg2"
diff --git a/Help/envvar/CUDAFLAGS.rst b/Help/envvar/CUDAFLAGS.rst
index 4456d6b..1f1bde5 100644
--- a/Help/envvar/CUDAFLAGS.rst
+++ b/Help/envvar/CUDAFLAGS.rst
@@ -1,6 +1,8 @@
 CUDAFLAGS
 ---------
 
+.. versionadded:: 3.10
+
 .. include:: ENV_VAR.txt
 
 Default compilation flags to be used when compiling ``CUDA`` files. Will only be
@@ -9,3 +11,5 @@
 cache as :variable:`CMAKE_CUDA_FLAGS <CMAKE_<LANG>_FLAGS>`. For any configuration
 run (including the first), the environment variable will be ignored if
 the :variable:`CMAKE_CUDA_FLAGS <CMAKE_<LANG>_FLAGS>` variable is defined.
+
+See also :variable:`CMAKE_CUDA_FLAGS_INIT <CMAKE_<LANG>_FLAGS_INIT>`.
diff --git a/Help/envvar/CUDAHOSTCXX.rst b/Help/envvar/CUDAHOSTCXX.rst
index b9f65bd..81c1228 100644
--- a/Help/envvar/CUDAHOSTCXX.rst
+++ b/Help/envvar/CUDAHOSTCXX.rst
@@ -1,6 +1,8 @@
 CUDAHOSTCXX
 -----------
 
+.. versionadded:: 3.10
+
 .. include:: ENV_VAR.txt
 
 Preferred executable for compiling host code when compiling ``CUDA``
diff --git a/Help/envvar/CXX.rst b/Help/envvar/CXX.rst
index d655350..908a521 100644
--- a/Help/envvar/CXX.rst
+++ b/Help/envvar/CXX.rst
@@ -1,6 +1,8 @@
 CXX
 ---
 
+.. versionadded:: 3.10
+
 .. include:: ENV_VAR.txt
 
 Preferred executable for compiling ``CXX`` language files. Will only be used by
@@ -9,3 +11,11 @@
 :variable:`CMAKE_CXX_COMPILER <CMAKE_<LANG>_COMPILER>`. For any configuration
 run (including the first), the environment variable will be ignored if the
 :variable:`CMAKE_CXX_COMPILER <CMAKE_<LANG>_COMPILER>` variable is defined.
+
+.. note::
+  Options that are required to make the compiler work correctly can be included;
+  they can not be changed.
+
+.. code-block:: console
+
+  $ export CXX="custom-compiler --arg1 --arg2"
diff --git a/Help/envvar/CXXFLAGS.rst b/Help/envvar/CXXFLAGS.rst
index d7296dc..a3cef77 100644
--- a/Help/envvar/CXXFLAGS.rst
+++ b/Help/envvar/CXXFLAGS.rst
@@ -1,6 +1,8 @@
 CXXFLAGS
 --------
 
+.. versionadded:: 3.10
+
 .. include:: ENV_VAR.txt
 
 Default compilation flags to be used when compiling ``CXX`` (C++) files. Will
@@ -9,3 +11,5 @@
 as :variable:`CMAKE_CXX_FLAGS <CMAKE_<LANG>_FLAGS>`. For any configuration run (
 including the first), the environment variable will be ignored if
 the :variable:`CMAKE_CXX_FLAGS <CMAKE_<LANG>_FLAGS>` variable is defined.
+
+See also :variable:`CMAKE_CXX_FLAGS_INIT <CMAKE_<LANG>_FLAGS_INIT>`.
diff --git a/Help/envvar/DASHBOARD_TEST_FROM_CTEST.rst b/Help/envvar/DASHBOARD_TEST_FROM_CTEST.rst
index 6a52d64..7635342 100644
--- a/Help/envvar/DASHBOARD_TEST_FROM_CTEST.rst
+++ b/Help/envvar/DASHBOARD_TEST_FROM_CTEST.rst
@@ -1,6 +1,8 @@
 DASHBOARD_TEST_FROM_CTEST
 -------------------------
 
+.. versionadded:: 3.10
+
 .. include:: ENV_VAR.txt
 
 Environment variable that will exist when a test executed by :manual:`ctest(1)`
diff --git a/Help/envvar/DESTDIR.rst b/Help/envvar/DESTDIR.rst
index d2144ae..ee290f2 100644
--- a/Help/envvar/DESTDIR.rst
+++ b/Help/envvar/DESTDIR.rst
@@ -1,6 +1,8 @@
 DESTDIR
 -------
 
+.. versionadded:: 3.12
+
 .. include:: ENV_VAR.txt
 
 On UNIX one can use the ``DESTDIR`` mechanism in order to relocate the
diff --git a/Help/envvar/FC.rst b/Help/envvar/FC.rst
index d6cabbc..dcee02d 100644
--- a/Help/envvar/FC.rst
+++ b/Help/envvar/FC.rst
@@ -1,6 +1,8 @@
 FC
 --
 
+.. versionadded:: 3.10
+
 .. include:: ENV_VAR.txt
 
 Preferred executable for compiling ``Fortran`` language files. Will only be used
@@ -10,3 +12,11 @@
 configuration run (including the first), the environment variable will be
 ignored if the :variable:`CMAKE_Fortran_COMPILER <CMAKE_<LANG>_COMPILER>`
 variable is defined.
+
+.. note::
+  Options that are required to make the compiler work correctly can be included;
+  they can not be changed.
+
+.. code-block:: console
+
+  $ export FC="custom-compiler --arg1 --arg2"
diff --git a/Help/envvar/FFLAGS.rst b/Help/envvar/FFLAGS.rst
index 02d3c34..4c1f3d2 100644
--- a/Help/envvar/FFLAGS.rst
+++ b/Help/envvar/FFLAGS.rst
@@ -1,6 +1,8 @@
 FFLAGS
 ------
 
+.. versionadded:: 3.10
+
 .. include:: ENV_VAR.txt
 
 Default compilation flags to be used when compiling ``Fortran`` files. Will only
@@ -9,3 +11,5 @@
 as :variable:`CMAKE_Fortran_FLAGS <CMAKE_<LANG>_FLAGS>`. For any configuration
 run (including the first), the environment variable will be ignored if
 the :variable:`CMAKE_Fortran_FLAGS <CMAKE_<LANG>_FLAGS>` variable is defined.
+
+See also :variable:`CMAKE_Fortran_FLAGS_INIT <CMAKE_<LANG>_FLAGS_INIT>`.
diff --git a/Help/envvar/LDFLAGS.rst b/Help/envvar/LDFLAGS.rst
index 816d6ef..78b34f4 100644
--- a/Help/envvar/LDFLAGS.rst
+++ b/Help/envvar/LDFLAGS.rst
@@ -1,6 +1,8 @@
 LDFLAGS
 -------
 
+.. versionadded:: 3.10
+
 .. include:: ENV_VAR.txt
 
 Will only be used by CMake on the first configuration to determine the default
diff --git a/Help/envvar/MACOSX_DEPLOYMENT_TARGET.rst b/Help/envvar/MACOSX_DEPLOYMENT_TARGET.rst
index 662bd03..1558704 100644
--- a/Help/envvar/MACOSX_DEPLOYMENT_TARGET.rst
+++ b/Help/envvar/MACOSX_DEPLOYMENT_TARGET.rst
@@ -1,6 +1,8 @@
 MACOSX_DEPLOYMENT_TARGET
 ------------------------
 
+.. versionadded:: 3.10
+
 .. include:: ENV_VAR.txt
 
 Specify the minimum version of macOS on which the target binaries are
diff --git a/Help/envvar/OBJC.rst b/Help/envvar/OBJC.rst
index 30c0d13..2d95806 100644
--- a/Help/envvar/OBJC.rst
+++ b/Help/envvar/OBJC.rst
@@ -1,6 +1,8 @@
 OBJC
 ----
 
+.. versionadded:: 3.16.7
+
 .. include:: ENV_VAR.txt
 
 Preferred executable for compiling ``OBJC`` language files. Will only be used
diff --git a/Help/envvar/OBJCXX.rst b/Help/envvar/OBJCXX.rst
index a72f7e7..71286d9 100644
--- a/Help/envvar/OBJCXX.rst
+++ b/Help/envvar/OBJCXX.rst
@@ -1,6 +1,8 @@
 OBJCXX
 ------
 
+.. versionadded:: 3.16.7
+
 .. include:: ENV_VAR.txt
 
 Preferred executable for compiling ``OBJCXX`` language files. Will only be used
diff --git a/Help/envvar/PackageName_ROOT.rst b/Help/envvar/PackageName_ROOT.rst
index 82b0a06..fc2a1d5 100644
--- a/Help/envvar/PackageName_ROOT.rst
+++ b/Help/envvar/PackageName_ROOT.rst
@@ -1,6 +1,8 @@
 <PackageName>_ROOT
 ------------------
 
+.. versionadded:: 3.12.1
+
 .. include:: ENV_VAR.txt
 
 Calls to :command:`find_package(<PackageName>)` will search in prefixes
diff --git a/Help/envvar/RC.rst b/Help/envvar/RC.rst
index 557520e..adfaecc 100644
--- a/Help/envvar/RC.rst
+++ b/Help/envvar/RC.rst
@@ -1,6 +1,8 @@
 RC
 --
 
+.. versionadded:: 3.10
+
 .. include:: ENV_VAR.txt
 
 Preferred executable for compiling ``resource`` files. Will only be used by CMake
@@ -9,3 +11,11 @@
 :variable:`CMAKE_RC_COMPILER <CMAKE_<LANG>_COMPILER>`. For any configuration run
 (including the first), the environment variable will be ignored if the
 :variable:`CMAKE_RC_COMPILER <CMAKE_<LANG>_COMPILER>` variable is defined.
+
+.. note::
+  Options that are required to make the compiler work correctly can be included;
+  they can not be changed.
+
+.. code-block:: console
+
+  $ export RC="custom-compiler --arg1 --arg2"
diff --git a/Help/envvar/RCFLAGS.rst b/Help/envvar/RCFLAGS.rst
index 45419fe..f33a9a8 100644
--- a/Help/envvar/RCFLAGS.rst
+++ b/Help/envvar/RCFLAGS.rst
@@ -1,6 +1,8 @@
 RCFLAGS
 -------
 
+.. versionadded:: 3.10
+
 .. include:: ENV_VAR.txt
 
 Default compilation flags to be used when compiling ``resource`` files. Will
@@ -9,3 +11,5 @@
 the cache as :variable:`CMAKE_RC_FLAGS <CMAKE_<LANG>_FLAGS>`. For any
 configuration run (including the first), the environment variable will be ignored
 if the :variable:`CMAKE_RC_FLAGS <CMAKE_<LANG>_FLAGS>` variable is defined.
+
+See also :variable:`CMAKE_RC_FLAGS_INIT <CMAKE_<LANG>_FLAGS_INIT>`.
diff --git a/Help/envvar/SWIFTC.rst b/Help/envvar/SWIFTC.rst
index b12e51d..896e156 100644
--- a/Help/envvar/SWIFTC.rst
+++ b/Help/envvar/SWIFTC.rst
@@ -1,6 +1,8 @@
 SWIFTC
 ------
 
+.. versionadded:: 3.15
+
 .. include:: ENV_VAR.txt
 
 Preferred executable for compiling ``Swift`` language files. Will only be used by
@@ -9,3 +11,11 @@
 :variable:`CMAKE_Swift_COMPILER <CMAKE_<LANG>_COMPILER>`. For any configuration run
 (including the first), the environment variable will be ignored if the
 :variable:`CMAKE_Swift_COMPILER <CMAKE_<LANG>_COMPILER>` variable is defined.
+
+.. note::
+  Options that are required to make the compiler work correctly can be included;
+  they can not be changed.
+
+.. code-block:: console
+
+  $ export SWIFTC="custom-compiler --arg1 --arg2"
diff --git a/Help/envvar/VERBOSE.rst b/Help/envvar/VERBOSE.rst
index 2d775a5..5911951 100644
--- a/Help/envvar/VERBOSE.rst
+++ b/Help/envvar/VERBOSE.rst
@@ -1,6 +1,8 @@
 VERBOSE
 -------
 
+.. versionadded:: 3.14
+
 Activates verbose output from CMake and your build tools of choice when
 you start to actually build your project.
 
diff --git a/Help/generator/Green Hills MULTI.rst b/Help/generator/Green Hills MULTI.rst
index dffc679..2246699 100644
--- a/Help/generator/Green Hills MULTI.rst
+++ b/Help/generator/Green Hills MULTI.rst
@@ -1,6 +1,8 @@
 Green Hills MULTI
 -----------------
 
+.. versionadded:: 3.3
+
 Generates Green Hills MULTI project files (experimental, work-in-progress).
 
 The buildsystem has predetermined build-configuration settings that can be controlled
diff --git a/Help/generator/Ninja Multi-Config.rst b/Help/generator/Ninja Multi-Config.rst
index f480eb8..e6c7a1c 100644
--- a/Help/generator/Ninja Multi-Config.rst
+++ b/Help/generator/Ninja Multi-Config.rst
@@ -1,6 +1,8 @@
 Ninja Multi-Config
 ------------------
 
+.. versionadded:: 3.17
+
 Generates multiple ``build-<Config>.ninja`` files.
 
 This generator is very much like the :generator:`Ninja` generator, but with
diff --git a/Help/generator/Visual Studio 14 2015.rst b/Help/generator/Visual Studio 14 2015.rst
index 7383f7a..401845d 100644
--- a/Help/generator/Visual Studio 14 2015.rst
+++ b/Help/generator/Visual Studio 14 2015.rst
@@ -1,6 +1,8 @@
 Visual Studio 14 2015
 ---------------------
 
+.. versionadded:: 3.1
+
 Generates Visual Studio 14 (VS 2015) project files.
 
 Project Types
diff --git a/Help/generator/Visual Studio 15 2017.rst b/Help/generator/Visual Studio 15 2017.rst
index 7e6f0fb..e7baaad 100644
--- a/Help/generator/Visual Studio 15 2017.rst
+++ b/Help/generator/Visual Studio 15 2017.rst
@@ -1,6 +1,8 @@
 Visual Studio 15 2017
 ---------------------
 
+.. versionadded:: 3.7.1
+
 Generates Visual Studio 15 (VS 2017) project files.
 
 Project Types
diff --git a/Help/generator/Visual Studio 16 2019.rst b/Help/generator/Visual Studio 16 2019.rst
index 4aec7f7..3da8091 100644
--- a/Help/generator/Visual Studio 16 2019.rst
+++ b/Help/generator/Visual Studio 16 2019.rst
@@ -1,6 +1,8 @@
 Visual Studio 16 2019
 ---------------------
 
+.. versionadded:: 3.14
+
 Generates Visual Studio 16 (VS 2019) project files.
 
 Project Types
diff --git a/Help/guide/tutorial/Complete/MathFunctions/CMakeLists.txt b/Help/guide/tutorial/Complete/MathFunctions/CMakeLists.txt
index c911625..a47d5e0 100644
--- a/Help/guide/tutorial/Complete/MathFunctions/CMakeLists.txt
+++ b/Help/guide/tutorial/Complete/MathFunctions/CMakeLists.txt
@@ -57,7 +57,11 @@
 set_property(TARGET MathFunctions PROPERTY SOVERSION "1")
 
 # install rules
-install(TARGETS MathFunctions tutorial_compiler_flags
+set(installable_libs MathFunctions tutorial_compiler_flags)
+if(TARGET SqrtLibrary)
+  list(APPEND installable_libs SqrtLibrary)
+endif()
+install(TARGETS ${installable_libs}
         DESTINATION lib
         EXPORT MathFunctionsTargets)
 install(FILES MathFunctions.h DESTINATION include)
diff --git a/Help/guide/tutorial/Step10/MathFunctions/CMakeLists.txt b/Help/guide/tutorial/Step10/MathFunctions/CMakeLists.txt
index e0c0621..0bfe20c 100644
--- a/Help/guide/tutorial/Step10/MathFunctions/CMakeLists.txt
+++ b/Help/guide/tutorial/Step10/MathFunctions/CMakeLists.txt
@@ -47,5 +47,9 @@
 target_compile_definitions(MathFunctions PRIVATE "EXPORTING_MYMATH")
 
 # install rules
-install(TARGETS MathFunctions DESTINATION lib)
+set(installable_libs MathFunctions)
+if(TARGET SqrtLibrary)
+  list(APPEND installable_libs SqrtLibrary)
+endif()
+install(TARGETS ${installable_libs} DESTINATION lib)
 install(FILES MathFunctions.h DESTINATION include)
diff --git a/Help/guide/tutorial/Step11/MathFunctions/CMakeLists.txt b/Help/guide/tutorial/Step11/MathFunctions/CMakeLists.txt
index 32f5e08..0d287ca 100644
--- a/Help/guide/tutorial/Step11/MathFunctions/CMakeLists.txt
+++ b/Help/guide/tutorial/Step11/MathFunctions/CMakeLists.txt
@@ -51,5 +51,9 @@
 target_compile_definitions(MathFunctions PRIVATE "EXPORTING_MYMATH")
 
 # install rules
-install(TARGETS MathFunctions DESTINATION lib)
+set(installable_libs MathFunctions tutorial_compiler_flags)
+if(TARGET SqrtLibrary)
+  list(APPEND installable_libs SqrtLibrary)
+endif()
+install(TARGETS ${installable_libs} DESTINATION lib)
 install(FILES MathFunctions.h DESTINATION include)
diff --git a/Help/guide/tutorial/Step12/MathFunctions/CMakeLists.txt b/Help/guide/tutorial/Step12/MathFunctions/CMakeLists.txt
index 720ee64..ea3861c 100644
--- a/Help/guide/tutorial/Step12/MathFunctions/CMakeLists.txt
+++ b/Help/guide/tutorial/Step12/MathFunctions/CMakeLists.txt
@@ -53,7 +53,11 @@
 target_compile_definitions(MathFunctions PRIVATE "EXPORTING_MYMATH")
 
 # install rules
-install(TARGETS MathFunctions tutorial_compiler_flags
+set(installable_libs MathFunctions tutorial_compiler_flags)
+if(TARGET SqrtLibrary)
+  list(APPEND installable_libs SqrtLibrary)
+endif()
+install(TARGETS ${installable_libs}
         DESTINATION lib
         EXPORT MathFunctionsTargets)
 install(FILES MathFunctions.h DESTINATION include)
diff --git a/Help/guide/tutorial/Step5/MathFunctions/MakeTable.cxx b/Help/guide/tutorial/Step5/MathFunctions/MakeTable.cxx
deleted file mode 100644
index ee58556..0000000
--- a/Help/guide/tutorial/Step5/MathFunctions/MakeTable.cxx
+++ /dev/null
@@ -1,25 +0,0 @@
-// A simple program that builds a sqrt table
-#include <cmath>
-#include <fstream>
-#include <iostream>
-
-int main(int argc, char* argv[])
-{
-  // make sure we have enough arguments
-  if (argc < 2) {
-    return 1;
-  }
-
-  std::ofstream fout(argv[1], std::ios_base::out);
-  const bool fileOpen = fout.is_open();
-  if (fileOpen) {
-    fout << "double sqrtTable[] = {" << std::endl;
-    for (int i = 0; i < 10; ++i) {
-      fout << sqrt(static_cast<double>(i)) << "," << std::endl;
-    }
-    // close the table with a zero
-    fout << "0};" << std::endl;
-    fout.close();
-  }
-  return fileOpen ? 0 : 1; // return 0 if wrote the file
-}
diff --git a/Help/guide/tutorial/Step6/MathFunctions/CMakeLists.txt b/Help/guide/tutorial/Step6/MathFunctions/CMakeLists.txt
index 4bf6024..f64c6ac 100644
--- a/Help/guide/tutorial/Step6/MathFunctions/CMakeLists.txt
+++ b/Help/guide/tutorial/Step6/MathFunctions/CMakeLists.txt
@@ -8,10 +8,20 @@
 
 # does this system provide the log and exp functions?
 include(CheckSymbolExists)
-set(CMAKE_REQUIRED_LIBRARIES "m")
 check_symbol_exists(log "math.h" HAVE_LOG)
 check_symbol_exists(exp "math.h" HAVE_EXP)
+if(NOT (HAVE_LOG AND HAVE_EXP))
+  unset(HAVE_LOG CACHE)
+  unset(HAVE_EXP CACHE)
+  set(CMAKE_REQUIRED_LIBRARIES "m")
+  check_symbol_exists(log "math.h" HAVE_LOG)
+  check_symbol_exists(exp "math.h" HAVE_EXP)
+  if(HAVE_LOG AND HAVE_EXP)
+    target_link_libraries(MathFunctions PRIVATE m)
+  endif()
+endif()
 
+# add compile definitions
 if(HAVE_LOG AND HAVE_EXP)
   target_compile_definitions(MathFunctions
                              PRIVATE "HAVE_LOG" "HAVE_EXP")
diff --git a/Help/guide/tutorial/index.rst b/Help/guide/tutorial/index.rst
index a844cbf..665d123 100644
--- a/Help/guide/tutorial/index.rst
+++ b/Help/guide/tutorial/index.rst
@@ -81,8 +81,8 @@
 Next modify ``tutorial.cxx`` to include the configured header file,
 ``TutorialConfig.h``.
 
-Finally, let's print out the version number by updating ``tutorial.cxx`` as
-follows:
+Finally, let's print out the executable name and version number by updating
+``tutorial.cxx`` as follows:
 
 .. literalinclude:: Step2/tutorial.cxx
   :language: c++
@@ -106,7 +106,8 @@
 in CMake is by using the :variable:`CMAKE_CXX_STANDARD` variable. For this
 tutorial, set the :variable:`CMAKE_CXX_STANDARD` variable in the
 ``CMakeLists.txt`` file to 11 and :variable:`CMAKE_CXX_STANDARD_REQUIRED` to
-True:
+True. Make sure to add the ``CMAKE_CXX_STANDARD`` declarations above the call
+to ``add_executable``.
 
 .. literalinclude:: Step2/CMakeLists.txt
   :language: cmake
@@ -120,18 +121,28 @@
 with your chosen build tool.
 
 For example, from the command line we could navigate to the
-``Help/guide/tutorial`` directory of the CMake source code tree and run the
-following commands:
+``Help/guide/tutorial`` directory of the CMake source code tree and create a
+build directory:
 
 .. code-block:: console
 
   mkdir Step1_build
+
+Next, navigate to the build directory and run CMake to configure the project
+and generate a native build system:
+
+.. code-block:: console
+
   cd Step1_build
   cmake ../Step1
+
+Then call that build system to actually compile/link the project:
+
+.. code-block:: console
+
   cmake --build .
 
-Navigate to the directory where Tutorial was built (likely the make directory
-or a Debug or Release build configuration subdirectory) and run these commands:
+Finally, try to use the newly built ``Tutorial`` with these commands:
 
 .. code-block:: console
 
@@ -212,8 +223,9 @@
 classic approach when dealing with many optional components, we will cover
 the modern approach in the next step.
 
-The corresponding changes to the source code are fairly straightforward. First,
-in ``tutorial.cxx``, include the ``MathFunctions.h`` header if we need it:
+The corresponding changes to the source code are fairly straightforward.
+First, in ``tutorial.cxx``, include the ``MathFunctions.h`` header if we
+need it:
 
 .. literalinclude:: Step3/tutorial.cxx
   :language: c++
@@ -242,8 +254,17 @@
 :manual:`cmake-gui <cmake-gui(1)>` to configure the project and then build it
 with your chosen build tool. Then run the built Tutorial executable.
 
-Use the :manual:`ccmake <ccmake(1)>` executable or the :manual:`cmake-gui <cmake-gui(1)>`
-to update the value of ``USE_MYMATH``. Rebuild and run the tutorial again.
+Now let's update the value of ``USE_MYMATH``. The easiest way is to use the
+:manual:`cmake-gui <cmake-gui(1)>` or  :manual:`ccmake <ccmake(1)>` if you're
+in the terminal. Or, alternatively, if you want to change the option from the
+command-line, try:
+
+.. code-block:: console
+
+  cmake ../Step2 -DUSE_MYMATH=OFF
+
+Rebuild and run the tutorial again.
+
 Which function gives better results, sqrt or mysqrt?
 
 Adding Usage Requirements for Library (Step 3)
@@ -320,21 +341,32 @@
 
 That is all that is needed to create a basic local install of the tutorial.
 
-Run the :manual:`cmake  <cmake(1)>` executable or the
+Now run the :manual:`cmake  <cmake(1)>` executable or the
 :manual:`cmake-gui <cmake-gui(1)>` to configure the project and then build it
-with your chosen build tool. Run the install step by using the ``install``
-option of the :manual:`cmake  <cmake(1)>` command (introduced in 3.15, older
-versions of CMake must use ``make install``) from the command line, or build
-the ``INSTALL`` target from an IDE. This will install the appropriate header
-files, libraries, and executables.
+with your chosen build tool.
+
+Then run the install step by using the ``install`` option of the
+:manual:`cmake  <cmake(1)>` command (introduced in 3.15, older versions of
+CMake must use ``make install``) from the command line. For
+multi-configuration tools, don't forget to use the ``--config`` argument to
+specify the configuration. If using an IDE, simply build the ``INSTALL``
+target. This step will install the appropriate header files, libraries, and
+executables. For example:
+
+.. code-block:: console
+
+  cmake --install .
 
 The CMake variable :variable:`CMAKE_INSTALL_PREFIX` is used to determine the
-root of where the files will be installed. If using ``cmake --install`` a
-custom installation directory can be given via the ``--prefix`` argument. For
-multi-configuration tools, use the ``--config`` argument to specify the
-configuration.
+root of where the files will be installed. If using the ``cmake --install``
+command, the installation prefix can be overridden via the ``--prefix``
+argument. For example:
 
-Verify that the installed Tutorial runs.
+.. code-block:: console
+
+  cmake --install . --prefix "/home/myuser/installdir"
+
+Navigate to the install directory and verify that the installed Tutorial runs.
 
 Testing Support
 ---------------
@@ -380,13 +412,17 @@
 If the platform has ``log`` and ``exp`` then we will use them to compute the
 square root in the ``mysqrt`` function. We first test for the availability of
 these functions using the :module:`CheckSymbolExists` module in the top-level
-``CMakeLists.txt``. We're going to use the new defines in
-``TutorialConfig.h.in``, so be sure to set them before that file is configured.
+``CMakeLists.txt``. On some platforms, we will need to link to the m library.
+If ``log`` and ``exp`` are not initially found, require the m library and try
+again.
+
+We're going to use the new defines in ``TutorialConfig.h.in``, so be sure to
+set them before that file is configured.
 
 .. literalinclude:: Step6/MathFunctions/CMakeLists.txt
   :language: cmake
   :start-after: # does this system provide the log and exp functions?
-  :end-before: if(HAVE_LOG AND HAVE_EXP)
+  :end-before: # add compile definitions
 
 Now let's add these defines to ``TutorialConfig.h.in`` so that we can use them
 from ``mysqrt.cxx``:
@@ -516,6 +552,7 @@
 directories so that ``Table.h`` can be found and included by ``mysqrt.cxx``.
 
 .. literalinclude:: Step7/MathFunctions/CMakeLists.txt
+  :language: cmake
   :start-after: # state that we depend on our bin
   :end-before: # install rules
 
@@ -671,9 +708,9 @@
 
 Now that we have made MathFunctions always be used, we will need to update
 the logic of that library. So, in ``MathFunctions/CMakeLists.txt`` we need to
-create a SqrtLibrary that will conditionally be built when ``USE_MYMATH`` is
-enabled. Now, since this is a tutorial, we are going to explicitly require
-that SqrtLibrary is built statically.
+create a SqrtLibrary that will conditionally be built and installed when
+``USE_MYMATH`` is enabled. Now, since this is a tutorial, we are going to
+explicitly require that SqrtLibrary is built statically.
 
 The end result is that ``MathFunctions/CMakeLists.txt`` should look like:
 
@@ -699,7 +736,7 @@
 .. literalinclude:: Step10/MathFunctions/MathFunctions.h
   :language: c++
 
-At this point, if you build everything, you will notice that linking fails
+At this point, if you build everything, you may notice that linking fails
 as we are combining a static library without position independent code with a
 library that has position independent code. The solution to this is to
 explicitly set the :prop_tgt:`POSITION_INDEPENDENT_CODE` target property of
@@ -746,7 +783,7 @@
 :manual:`generator expressions <cmake-generator-expressions(7)>` is to
 conditionally add compiler flags, such as those for language levels or
 warnings. A nice pattern is to associate this information to an ``INTERFACE``
-target allowing this information to propagate. Lets start by constructing an
+target allowing this information to propagate. Let's start by constructing an
 ``INTERFACE`` target and specifying the required C++ standard level of ``11``
 instead of using :variable:`CMAKE_CXX_STANDARD`.
 
diff --git a/Help/guide/user-interaction/index.rst b/Help/guide/user-interaction/index.rst
index 3a1038f..c724b6f 100644
--- a/Help/guide/user-interaction/index.rst
+++ b/Help/guide/user-interaction/index.rst
@@ -86,6 +86,7 @@
 directories for the source and the build.
 
 .. image:: /guide/user-interaction/GUI-Source-Binary.png
+   :alt: Choosing source and binary directories
 
 Generating a Buildsystem
 ========================
@@ -246,16 +247,19 @@
 select the CMake generator to use.
 
 .. image:: /guide/user-interaction/GUI-Configure-Dialog.png
+   :alt: Configuring a generator
 
 All generators available on the command line are also
 available in :manual:`cmake-gui(1)`.
 
 .. image:: /guide/user-interaction/GUI-Choose-Generator.png
+   :alt: Choosing a generator
 
 When choosing a Visual Studio generator, further options
 are available to set an architecture to generate for.
 
 .. image:: /manual/VS-Choose-Arch.png
+   :alt: Choosing an architecture for Visual Studio generators
 
 .. _`Setting Build Variables`:
 
@@ -356,6 +360,7 @@
 the variable.
 
 .. image:: /guide/user-interaction/GUI-Add-Entry.png
+   :alt: Editing a cache entry
 
 The main view of the :manual:`cmake-gui(1)` user interface
 can be used to edit existing variables.
diff --git a/Help/manual/cmake-buildsystem.7.rst b/Help/manual/cmake-buildsystem.7.rst
index d8142a2..cd27316 100644
--- a/Help/manual/cmake-buildsystem.7.rst
+++ b/Help/manual/cmake-buildsystem.7.rst
@@ -922,8 +922,8 @@
 Interface Libraries
 -------------------
 
-An ``INTERFACE`` target has no :prop_tgt:`LOCATION` and is mutable, but is
-otherwise similar to an :prop_tgt:`IMPORTED` target.
+An ``INTERFACE`` library target does not compile sources and does not
+produce a library artifact on disk, so it has no :prop_tgt:`LOCATION`.
 
 It may specify usage requirements such as
 :prop_tgt:`INTERFACE_INCLUDE_DIRECTORIES`,
@@ -937,11 +937,22 @@
 :command:`target_sources`, and :command:`target_link_libraries` commands
 may be used with ``INTERFACE`` libraries.
 
+Since CMake 3.19, an ``INTERFACE`` library target may optionally contain
+source files.  An interface library that contains source files will be
+included as a build target in the generated buildsystem.  It does not
+compile sources, but may contain custom commands to generate other sources.
+Additionally, IDEs will show the source files as part of the target for
+interactive reading and editing.
+
 A primary use-case for ``INTERFACE`` libraries is header-only libraries.
 
 .. code-block:: cmake
 
-  add_library(Eigen INTERFACE)
+  add_library(Eigen INTERFACE
+    src/eigen.h
+    src/vector.h
+    src/matrix.h
+    )
   target_include_directories(Eigen INTERFACE
     $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/src>
     $<INSTALL_INTERFACE:include/Eigen>
@@ -975,25 +986,17 @@
 targets, and the complexity of compiler-specific flags is encapsulated in an
 ``INTERFACE`` library target.
 
-The properties permitted to be set on or read from an ``INTERFACE`` library
-are:
-
-* Properties matching ``INTERFACE_*``
-* Built-in properties matching ``COMPATIBLE_INTERFACE_*``
-* ``EXPORT_NAME``
-* ``EXPORT_PROPERTIES``
-* ``IMPORTED``
-* ``MANUALLY_ADDED_DEPENDENCIES``
-* ``NAME``
-* Properties matching ``IMPORTED_LIBNAME_*``
-* Properties matching ``MAP_IMPORTED_CONFIG_*``
-
 ``INTERFACE`` libraries may be installed and exported.  Any content they refer
 to must be installed separately:
 
 .. code-block:: cmake
 
-  add_library(Eigen INTERFACE)
+  set(Eigen_headers
+    src/eigen.h
+    src/vector.h
+    src/matrix.h
+    )
+  add_library(Eigen INTERFACE ${Eigen_headers})
   target_include_directories(Eigen INTERFACE
     $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/src>
     $<INSTALL_INTERFACE:include/Eigen>
@@ -1003,9 +1006,6 @@
   install(EXPORT eigenExport NAMESPACE Upstream::
     DESTINATION lib/cmake/Eigen
   )
-  install(FILES
-      ${CMAKE_CURRENT_SOURCE_DIR}/src/eigen.h
-      ${CMAKE_CURRENT_SOURCE_DIR}/src/vector.h
-      ${CMAKE_CURRENT_SOURCE_DIR}/src/matrix.h
+  install(FILES ${Eigen_headers}
     DESTINATION include/Eigen
   )
diff --git a/Help/manual/cmake-commands.7.rst b/Help/manual/cmake-commands.7.rst
index 59ba897..0aa4f75 100644
--- a/Help/manual/cmake-commands.7.rst
+++ b/Help/manual/cmake-commands.7.rst
@@ -17,6 +17,7 @@
 
    /command/break
    /command/cmake_host_system_information
+   /command/cmake_language
    /command/cmake_minimum_required
    /command/cmake_parse_arguments
    /command/cmake_policy
diff --git a/Help/manual/cmake-env-variables.7.rst b/Help/manual/cmake-env-variables.7.rst
index f72e414..ce1e360 100644
--- a/Help/manual/cmake-env-variables.7.rst
+++ b/Help/manual/cmake-env-variables.7.rst
@@ -14,6 +14,13 @@
 :ref:`Environment Variables <CMake Language Environment Variables>`
 section in the cmake-language manual.
 
+Environment Variables that Change Behavior
+==========================================
+
+.. toctree::
+   :maxdepth: 1
+
+   /envvar/CMAKE_PREFIX_PATH
 
 Environment Variables that Control the Build
 ============================================
@@ -75,3 +82,11 @@
    /envvar/CTEST_PROGRESS_OUTPUT
    /envvar/CTEST_USE_LAUNCHERS_DEFAULT
    /envvar/DASHBOARD_TEST_FROM_CTEST
+
+Environment Variables for the CMake curses interface
+====================================================
+
+.. toctree::
+   :maxdepth: 1
+
+   /envvar/CCMAKE_COLORS
diff --git a/Help/manual/cmake-file-api.7.rst b/Help/manual/cmake-file-api.7.rst
index 12eecd9..6876e1c 100644
--- a/Help/manual/cmake-file-api.7.rst
+++ b/Help/manual/cmake-file-api.7.rst
@@ -425,7 +425,7 @@
 
   {
     "kind": "codemodel",
-    "version": { "major": 2, "minor": 0 },
+    "version": { "major": 2, "minor": 2 },
     "paths": {
       "source": "/path/to/top-level-source-dir",
       "build": "/path/to/top-level-build-dir"
@@ -650,7 +650,8 @@
 ``type``
   A string specifying the type of the target.  The value is one of
   ``EXECUTABLE``, ``STATIC_LIBRARY``, ``SHARED_LIBRARY``,
-  ``MODULE_LIBRARY``, ``OBJECT_LIBRARY``, or ``UTILITY``.
+  ``MODULE_LIBRARY``, ``OBJECT_LIBRARY``, ``INTERFACE_LIBRARY``,
+  or ``UTILITY``.
 
 ``backtrace``
   Optional member that is present when a CMake language backtrace to
@@ -869,6 +870,26 @@
     A string specifying the language (e.g. ``C``, ``CXX``, ``Fortran``)
     of the toolchain is used to compile the source file.
 
+  ``languageStandard``
+    Optional member that is present when the language standard is set
+    explicitly (e.g. via :prop_tgt:`CXX_STANDARD`) or implicitly by
+    compile features.  Each entry is a JSON object with two members:
+
+    ``backtraces``
+      Optional member that is present when a CMake language backtrace to
+      the ``<LANG>_STANDARD`` setting is available.  If the language
+      standard was set implicitly by compile features those are used as
+      the backtrace(s).  It's possible for multiple compile features to
+      require the same language standard so there could be multiple
+      backtraces. The value is a JSON array with each entry being an
+      unsigned integer 0-based index into the ``backtraceGraph``
+      member's ``nodes`` array.
+
+    ``standard``
+      String representing the language standard.
+
+    This field was added in codemodel version 2.2.
+
   ``compileCommandFragments``
     Optional member that is present when fragments of the compiler command
     line invocation are available.  The value is a JSON array of entries
@@ -899,6 +920,24 @@
       an unsigned integer 0-based index into the ``backtraceGraph``
       member's ``nodes`` array.
 
+  ``precompileHeaders``
+    Optional member that is present when :command:`target_precompile_headers`
+    or other command invocations set :prop_tgt:`PRECOMPILE_HEADERS` on the
+    target.  The value is a JSON array with an entry for each header.  Each
+    entry is a JSON object with members:
+
+    ``header``
+      Full path to the precompile header file.
+
+    ``backtrace``
+      Optional member that is present when a CMake language backtrace to
+      the :command:`target_precompile_headers` or other command invocation
+      that added this precompiled header is available.  The value is an
+      unsigned integer 0-based index into the ``backtraceGraph`` member's
+      ``nodes`` array.
+
+    This field was added in codemodel version 2.1.
+
   ``defines``
     Optional member that is present when there are preprocessor definitions.
     The value is a JSON array with an entry for each definition.  Each
diff --git a/Help/manual/cmake-generator-expressions.7.rst b/Help/manual/cmake-generator-expressions.7.rst
index 691481b..c7f6b27 100644
--- a/Help/manual/cmake-generator-expressions.7.rst
+++ b/Help/manual/cmake-generator-expressions.7.rst
@@ -105,10 +105,11 @@
 
 ``$<TARGET_EXISTS:target>``
   ``1`` if ``target`` exists, else ``0``.
-``$<CONFIG:cfg>``
-  ``1`` if config is ``cfg``, else ``0``. This is a case-insensitive comparison.
-  The mapping in :prop_tgt:`MAP_IMPORTED_CONFIG_<CONFIG>` is also considered by
-  this expression when it is evaluated on a property on an :prop_tgt:`IMPORTED`
+``$<CONFIG:cfgs>``
+  ``1`` if config is any one of the entries in ``cfgs``, else ``0``. This is a
+  case-insensitive comparison. The mapping in
+  :prop_tgt:`MAP_IMPORTED_CONFIG_<CONFIG>` is also considered by this
+  expression when it is evaluated on a property on an :prop_tgt:`IMPORTED`
   target.
 ``$<PLATFORM_ID:platform_ids>``
   where ``platform_ids`` is a comma-separated list.
@@ -259,6 +260,122 @@
     add_executable(myapp main.cpp)
     target_link_libraries(myapp myapp_c myapp_cxx)
 
+.. _`Boolean LINK_LANGUAGE Generator Expression`:
+
+``$<LINK_LANG_AND_ID:language,compiler_ids>``
+  ``1`` when the language used for link step matches ``language`` and the
+  CMake's compiler id of the language linker matches any one of the entries
+  in ``compiler_ids``, otherwise ``0``. This expression is a short form for the
+  combination of ``$<LINK_LANGUAGE:language>`` and
+  ``$<LANG_COMPILER_ID:compiler_ids>``. This expression may be used to specify
+  link libraries, link options, link directories and link dependencies of a
+  particular language and linker combination in a target. For example:
+
+  .. code-block:: cmake
+
+    add_library(libC_Clang ...)
+    add_library(libCXX_Clang ...)
+    add_library(libC_Intel ...)
+    add_library(libCXX_Intel ...)
+
+    add_executable(myapp main.c)
+    if (CXX_CONFIG)
+      target_sources(myapp PRIVATE file.cxx)
+    endif()
+    target_link_libraries(myapp
+      PRIVATE $<$<LINK_LANG_AND_ID:CXX,Clang,AppleClang>:libCXX_Clang>
+              $<$<LINK_LANG_AND_ID:C,Clang,AppleClang>:libC_Clang>
+              $<$<LINK_LANG_AND_ID:CXX,Intel>:libCXX_Intel>
+              $<$<LINK_LANG_AND_ID:C,Intel>:libC_Intel>)
+
+  This specifies the use of different link libraries based on both the
+  compiler id and link language. This example will have target ``libCXX_Clang``
+  as link dependency when ``Clang`` or ``AppleClang`` is the ``CXX``
+  linker, and ``libCXX_Intel`` when ``Intel`` is the ``CXX`` linker.
+  Likewise when the ``C`` linker is ``Clang`` or ``AppleClang``, target
+  ``libC_Clang`` will be added as link dependency and ``libC_Intel`` when
+  ``Intel`` is the ``C`` linker.
+
+  See :ref:`the note related to
+  <Constraints LINK_LANGUAGE Generator Expression>`
+  ``$<LINK_LANGUAGE:language>`` for constraints about the usage of this
+  generator expression.
+
+``$<LINK_LANGUAGE:languages>``
+  ``1`` when the language used for link step matches any of the entries
+  in ``languages``, otherwise ``0``.  This expression may be used to specify
+  link libraries, link options, link directories and link dependencies of a
+  particular language in a target. For example:
+
+  .. code-block:: cmake
+
+    add_library(api_C ...)
+    add_library(api_CXX ...)
+    add_library(api INTERFACE)
+    target_link_options(api INTERFACE $<$<LINK_LANGUAGE:C>:-opt_c>
+                                        $<$<LINK_LANGUAGE:CXX>:-opt_cxx>)
+    target_link_libraries(api INTERFACE $<$<LINK_LANGUAGE:C>:api_C>
+                                        $<$<LINK_LANGUAGE:CXX>:api_CXX>)
+
+    add_executable(myapp1 main.c)
+    target_link_options(myapp1 PRIVATE api)
+
+    add_executable(myapp2 main.cpp)
+    target_link_options(myapp2 PRIVATE api)
+
+  This specifies to use the ``api`` target for linking targets ``myapp1`` and
+  ``myapp2``. In practice, ``myapp1`` will link with target ``api_C`` and
+  option ``-opt_c`` because it will use ``C`` as link language. And ``myapp2``
+  will link with ``api_CXX`` and option ``-opt_cxx`` because ``CXX`` will be
+  the link language.
+
+  .. _`Constraints LINK_LANGUAGE Generator Expression`:
+
+  .. note::
+
+    To determine the link language of a target, it is required to collect,
+    transitively, all the targets which will be linked to it. So, for link
+    libraries properties, a double evaluation will be done. During the first
+    evaluation, ``$<LINK_LANGUAGE:..>`` expressions will always return ``0``.
+    The link language computed after this first pass will be used to do the
+    second pass. To avoid inconsistency, it is required that the second pass
+    do not change the link language. Moreover, to avoid unexpected
+    side-effects, it is required to specify complete entities as part of the
+    ``$<LINK_LANGUAGE:..>`` expression. For example:
+
+    .. code-block:: cmake
+
+      add_library(lib STATIC file.cxx)
+      add_library(libother STATIC file.c)
+
+      # bad usage
+      add_executable(myapp1 main.c)
+      target_link_libraries(myapp1 PRIVATE lib$<$<LINK_LANGUAGE:C>:other>)
+
+      # correct usage
+      add_executable(myapp2 main.c)
+      target_link_libraries(myapp2 PRIVATE $<$<LINK_LANGUAGE:C>:libother>)
+
+    In this example, for ``myapp1``, the first pass will, unexpectedly,
+    determine that the link language is ``CXX`` because the evaluation of the
+    generator expression will be an empty string so ``myapp1`` will depends on
+    target ``lib`` which is ``C++``. On the contrary, for ``myapp2``, the first
+    evaluation will give ``C`` as link language, so the second pass will
+    correctly add target ``libother`` as link dependency.
+
+``$<DEVICE_LINK:list>``
+  Returns the list if it is the device link step, an empty list otherwise.
+  The device link step is controlled by :prop_tgt:`CUDA_SEPARABLE_COMPILATION`
+  and :prop_tgt:`CUDA_RESOLVE_DEVICE_SYMBOLS` properties and
+  policy :policy:`CMP0105`. This expression can only be used to specify link
+  options.
+
+``$<HOST_LINK:list>``
+  Returns the list if it is the normal link step, an empty list otherwise.
+  This expression is mainly useful when a device link step is also involved
+  (see ``$<DEVICE_LINK:list>`` generator expression). This expression can only
+  be used to specify link options.
+
 String-Valued Generator Expressions
 ===================================
 
@@ -450,22 +567,41 @@
   <Boolean COMPILE_LANGUAGE Generator Expression>`
   ``$<COMPILE_LANGUAGE:language>``
   for notes about the portability of this generator expression.
+``$<LINK_LANGUAGE>``
+  The link language of target when evaluating link options.
+  See :ref:`the related boolean expression
+  <Boolean LINK_LANGUAGE Generator Expression>` ``$<LINK_LANGUAGE:language>``
+  for notes about the portability of this generator expression.
+
+  .. note::
+
+    This generator expression is not supported by the link libraries
+    properties to avoid side-effects due to the double evaluation of
+    these properties.
 
 Target-Dependent Queries
 ------------------------
 
-``$<TARGET_NAME_IF_EXISTS:tgt>``
-  Expands to the ``tgt`` if the given target exists, an empty string
-  otherwise.
-``$<TARGET_FILE:tgt>``
-  Full path to main file (.exe, .so.1.2, .a) where ``tgt`` is the name of a
-  target.
-``$<TARGET_FILE_BASE_NAME:tgt>``
-  Base name of main file where ``tgt`` is the name of a target.
+These queries refer to a target ``tgt``. This can be any runtime artifact,
+namely:
 
-  The base name corresponds to the target file name (see
-  ``$<TARGET_FILE_NAME:tgt>``) without prefix and suffix. For example, if
-  target file name is ``libbase.so``, the base name is ``base``.
+* an executable target created by :command:`add_executable`
+* a shared library target (``.so``, ``.dll`` but not their ``.lib`` import library)
+  created by :command:`add_library`
+* a static library target created by :command:`add_library`
+
+In the following, "the ``tgt`` filename" means the name of the ``tgt``
+binary file. This has to be distinguished from "the target name",
+which is just the string ``tgt``.
+
+``$<TARGET_NAME_IF_EXISTS:tgt>``
+  The target name ``tgt`` if the target exists, an empty string otherwise.
+``$<TARGET_FILE:tgt>``
+  Full path to the ``tgt`` binary file.
+``$<TARGET_FILE_BASE_NAME:tgt>``
+  Base name of ``tgt``, i.e. ``$<TARGET_FILE_NAME:tgt>`` without prefix and
+  suffix.
+  For example, if the ``tgt`` filename is ``libbase.so``, the base name is ``base``.
 
   See also the :prop_tgt:`OUTPUT_NAME`, :prop_tgt:`ARCHIVE_OUTPUT_NAME`,
   :prop_tgt:`LIBRARY_OUTPUT_NAME` and :prop_tgt:`RUNTIME_OUTPUT_NAME`
@@ -480,32 +616,31 @@
   Note that ``tgt`` is not added as a dependency of the target this
   expression is evaluated on.
 ``$<TARGET_FILE_PREFIX:tgt>``
-  Prefix of main file where ``tgt`` is the name of a target.
+  Prefix of the ``tgt`` filename (such as ``lib``).
 
   See also the :prop_tgt:`PREFIX` target property.
 
   Note that ``tgt`` is not added as a dependency of the target this
   expression is evaluated on.
 ``$<TARGET_FILE_SUFFIX:tgt>``
-  Suffix of main file where ``tgt`` is the name of a target.
-
-  The suffix corresponds to the file extension (such as ".so" or ".exe").
+  Suffix of the ``tgt`` filename (extension such as ``.so`` or ``.exe``).
 
   See also the :prop_tgt:`SUFFIX` target property.
 
   Note that ``tgt`` is not added as a dependency of the target this
   expression is evaluated on.
 ``$<TARGET_FILE_NAME:tgt>``
-  Name of main file (.exe, .so.1.2, .a).
+  The ``tgt`` filename.
 ``$<TARGET_FILE_DIR:tgt>``
-  Directory of main file (.exe, .so.1.2, .a).
+  Directory of the ``tgt`` binary file.
 ``$<TARGET_LINKER_FILE:tgt>``
-  File used to link (.a, .lib, .so) where ``tgt`` is the name of a target.
+  File used when linking to the ``tgt`` target.  This will usually
+  be the library that ``tgt`` represents (``.a``, ``.lib``, ``.so``),
+  but for a shared library on DLL platforms, it would be the ``.lib``
+  import library associated with the DLL.
 ``$<TARGET_LINKER_FILE_BASE_NAME:tgt>``
-  Base name of file used to link where ``tgt`` is the name of a target.
-
-  The base name corresponds to the target linker file name (see
-  ``$<TARGET_LINKER_FILE_NAME:tgt>``) without prefix and suffix. For example,
+  Base name of file used to link the target ``tgt``, i.e.
+  ``$<TARGET_LINKER_FILE_NAME:tgt>`` without prefix and suffix. For example,
   if target file name is ``libbase.a``, the base name is ``base``.
 
   See also the :prop_tgt:`OUTPUT_NAME`, :prop_tgt:`ARCHIVE_OUTPUT_NAME`,
@@ -520,7 +655,7 @@
   Note that ``tgt`` is not added as a dependency of the target this
   expression is evaluated on.
 ``$<TARGET_LINKER_FILE_PREFIX:tgt>``
-  Prefix of file used to link where ``tgt`` is the name of a target.
+  Prefix of file used to link target ``tgt``.
 
   See also the :prop_tgt:`PREFIX` and :prop_tgt:`IMPORT_PREFIX` target
   properties.
@@ -538,15 +673,15 @@
   Note that ``tgt`` is not added as a dependency of the target this
   expression is evaluated on.
 ``$<TARGET_LINKER_FILE_NAME:tgt>``
-  Name of file used to link (.a, .lib, .so).
+  Name of file used to link target ``tgt``.
 ``$<TARGET_LINKER_FILE_DIR:tgt>``
-  Directory of file used to link (.a, .lib, .so).
+  Directory of file used to link target ``tgt``.
 ``$<TARGET_SONAME_FILE:tgt>``
-  File with soname (.so.3) where ``tgt`` is the name of a target.
+  File with soname (``.so.3``) where ``tgt`` is the name of a target.
 ``$<TARGET_SONAME_FILE_NAME:tgt>``
-  Name of file with soname (.so.3).
+  Name of file with soname (``.so.3``).
 ``$<TARGET_SONAME_FILE_DIR:tgt>``
-  Directory of with soname (.so.3).
+  Directory of with soname (``.so.3``).
 ``$<TARGET_PDB_FILE:tgt>``
   Full path to the linker generated program database file (.pdb)
   where ``tgt`` is the name of a target.
@@ -589,11 +724,10 @@
   Note that ``tgt`` is not added as a dependency of the target this
   expression is evaluated on.
 ``$<TARGET_PROPERTY:prop>``
-  Value of the property ``prop`` on the target on which the generator
-  expression is evaluated. Note that for generator expressions in
-  :ref:`Target Usage Requirements` this is the value of the property
-  on the consuming target rather than the target specifying the
-  requirement.
+  Value of the property ``prop`` on the target for which the expression
+  is being evaluated. Note that for generator expressions in
+  :ref:`Target Usage Requirements` this is the consuming target rather
+  than the target specifying the requirement.
 ``$<INSTALL_PREFIX>``
   Content of the install prefix when the target is exported via
   :command:`install(EXPORT)`, or when evaluated in
diff --git a/Help/manual/cmake-modules.7.rst b/Help/manual/cmake-modules.7.rst
index be64112..50131e8 100644
--- a/Help/manual/cmake-modules.7.rst
+++ b/Help/manual/cmake-modules.7.rst
@@ -36,6 +36,7 @@
    /module/CheckIncludeFiles
    /module/CheckLanguage
    /module/CheckLibraryExists
+   /module/CheckLinkerFlag
    /module/CheckOBJCCompilerFlag
    /module/CheckOBJCSourceCompiles
    /module/CheckOBJCSourceRuns
diff --git a/Help/manual/cmake-policies.7.rst b/Help/manual/cmake-policies.7.rst
index c256250..3ceb1df 100644
--- a/Help/manual/cmake-policies.7.rst
+++ b/Help/manual/cmake-policies.7.rst
@@ -51,6 +51,27 @@
 to determine whether to report an error on use of deprecated macros or
 functions.
 
+Policies Introduced by CMake 3.18
+=================================
+
+.. toctree::
+   :maxdepth: 1
+
+   CMP0109: find_program() requires permission to execute but not to read. </policy/CMP0109>
+
+Policies Introduced by CMake 3.18
+=================================
+
+.. toctree::
+   :maxdepth: 1
+
+   CMP0108: A target cannot link to itself through an alias. </policy/CMP0108>
+   CMP0107: An ALIAS target cannot overwrite another target. </policy/CMP0107>
+   CMP0106: The Documentation module is removed. </policy/CMP0106>
+   CMP0105: Device link step uses the link options. </policy/CMP0105>
+   CMP0104: CMAKE_CUDA_ARCHITECTURES now detected for NVCC, empty CUDA_ARCHITECTURES not allowed. </policy/CMP0104>
+   CMP0103: Multiple export() with same FILE without APPEND is not allowed. </policy/CMP0103>
+
 Policies Introduced by CMake 3.17
 =================================
 
diff --git a/Help/manual/cmake-properties.7.rst b/Help/manual/cmake-properties.7.rst
index 060a072..30b2a05 100644
--- a/Help/manual/cmake-properties.7.rst
+++ b/Help/manual/cmake-properties.7.rst
@@ -105,6 +105,7 @@
 
    /prop_tgt/ADDITIONAL_CLEAN_FILES
    /prop_tgt/AIX_EXPORT_ALL_SYMBOLS
+   /prop_tgt/ALIAS_GLOBAL
    /prop_tgt/ALIASED_TARGET
    /prop_tgt/ANDROID_ANT_ADDITIONAL_OPTIONS
    /prop_tgt/ANDROID_API
@@ -171,6 +172,7 @@
    /prop_tgt/CONFIG_OUTPUT_NAME
    /prop_tgt/CONFIG_POSTFIX
    /prop_tgt/CROSSCOMPILING_EMULATOR
+   /prop_tgt/CUDA_ARCHITECTURES
    /prop_tgt/CUDA_PTX_COMPILATION
    /prop_tgt/CUDA_SEPARABLE_COMPILATION
    /prop_tgt/CUDA_RESOLVE_DEVICE_SYMBOLS
@@ -199,7 +201,9 @@
    /prop_tgt/FOLDER
    /prop_tgt/Fortran_FORMAT
    /prop_tgt/Fortran_MODULE_DIRECTORY
+   /prop_tgt/Fortran_PREPROCESS
    /prop_tgt/FRAMEWORK
+   /prop_tgt/FRAMEWORK_MULTI_CONFIG_POSTFIX_CONFIG
    /prop_tgt/FRAMEWORK_VERSION
    /prop_tgt/GENERATOR_FILE_NAME
    /prop_tgt/GHS_INTEGRITY_APP
@@ -307,6 +311,7 @@
    /prop_tgt/OSX_ARCHITECTURES
    /prop_tgt/OUTPUT_NAME_CONFIG
    /prop_tgt/OUTPUT_NAME
+   /prop_tgt/PCH_WARN_INVALID
    /prop_tgt/PDB_NAME_CONFIG
    /prop_tgt/PDB_NAME
    /prop_tgt/PDB_OUTPUT_DIRECTORY_CONFIG
@@ -343,6 +348,7 @@
    /prop_tgt/UNITY_BUILD_BATCH_SIZE
    /prop_tgt/UNITY_BUILD_CODE_AFTER_INCLUDE
    /prop_tgt/UNITY_BUILD_CODE_BEFORE_INCLUDE
+   /prop_tgt/UNITY_BUILD_MODE
    /prop_tgt/VERSION
    /prop_tgt/VISIBILITY_INLINES_HIDDEN
    /prop_tgt/VS_CONFIGURATION_TYPE
@@ -369,12 +375,15 @@
    /prop_tgt/VS_MOBILE_EXTENSIONS_VERSION
    /prop_tgt/VS_NO_SOLUTION_DEPLOY
    /prop_tgt/VS_PACKAGE_REFERENCES
+   /prop_tgt/VS_PLATFORM_TOOLSET
    /prop_tgt/VS_PROJECT_IMPORT
    /prop_tgt/VS_SCC_AUXPATH
    /prop_tgt/VS_SCC_LOCALPATH
    /prop_tgt/VS_SCC_PROJECTNAME
    /prop_tgt/VS_SCC_PROVIDER
    /prop_tgt/VS_SDK_REFERENCES
+   /prop_tgt/VS_SOLUTION_DEPLOY
+   /prop_tgt/VS_SOURCE_SETTINGS_tool
    /prop_tgt/VS_USER_PROPS
    /prop_tgt/VS_WINDOWS_TARGET_PLATFORM_MIN_VERSION
    /prop_tgt/VS_WINRT_COMPONENT
@@ -459,6 +468,7 @@
    /prop_sf/COMPILE_OPTIONS
    /prop_sf/EXTERNAL_OBJECT
    /prop_sf/Fortran_FORMAT
+   /prop_sf/Fortran_PREPROCESS
    /prop_sf/GENERATED
    /prop_sf/HEADER_FILE_ONLY
    /prop_sf/INCLUDE_DIRECTORIES
@@ -478,12 +488,14 @@
    /prop_sf/Swift_DEPENDENCIES_FILE
    /prop_sf/Swift_DIAGNOSTICS_FILE
    /prop_sf/SYMBOLIC
+   /prop_sf/UNITY_GROUP
    /prop_sf/VS_COPY_TO_OUT_DIR
    /prop_sf/VS_CSHARP_tagname
    /prop_sf/VS_DEPLOYMENT_CONTENT
    /prop_sf/VS_DEPLOYMENT_LOCATION
    /prop_sf/VS_INCLUDE_IN_VSIX
    /prop_sf/VS_RESOURCE_GENERATOR
+   /prop_sf/VS_SETTINGS
    /prop_sf/VS_SHADER_DISABLE_OPTIMIZATIONS
    /prop_sf/VS_SHADER_ENABLE_DEBUG
    /prop_sf/VS_SHADER_ENTRYPOINT
diff --git a/Help/manual/cmake-variables.7.rst b/Help/manual/cmake-variables.7.rst
index fc27739..d780a65 100644
--- a/Help/manual/cmake-variables.7.rst
+++ b/Help/manual/cmake-variables.7.rst
@@ -158,6 +158,7 @@
    /variable/CMAKE_AUTOMOC_RELAXED_MODE
    /variable/CMAKE_BACKWARDS_COMPATIBILITY
    /variable/CMAKE_BUILD_TYPE
+   /variable/CMAKE_CLANG_VFS_OVERLAY
    /variable/CMAKE_CODEBLOCKS_COMPILER_ID
    /variable/CMAKE_CODEBLOCKS_EXCLUDE_EXTERNAL_FILES
    /variable/CMAKE_CODELITE_USE_TARGETS
@@ -388,8 +389,10 @@
    /variable/CMAKE_EXE_LINKER_FLAGS_INIT
    /variable/CMAKE_FOLDER
    /variable/CMAKE_FRAMEWORK
+   /variable/CMAKE_FRAMEWORK_MULTI_CONFIG_POSTFIX_CONFIG
    /variable/CMAKE_Fortran_FORMAT
    /variable/CMAKE_Fortran_MODULE_DIRECTORY
+   /variable/CMAKE_Fortran_PREPROCESS
    /variable/CMAKE_GHS_NO_SOURCE_GROUP_FILE
    /variable/CMAKE_GLOBAL_AUTOGEN_TARGET
    /variable/CMAKE_GLOBAL_AUTOGEN_TARGET_NAME
@@ -437,6 +440,7 @@
    /variable/CMAKE_OSX_ARCHITECTURES
    /variable/CMAKE_OSX_DEPLOYMENT_TARGET
    /variable/CMAKE_OSX_SYSROOT
+   /variable/CMAKE_PCH_WARN_INVALID
    /variable/CMAKE_PDB_OUTPUT_DIRECTORY
    /variable/CMAKE_PDB_OUTPUT_DIRECTORY_CONFIG
    /variable/CMAKE_POSITION_INDEPENDENT_CODE
@@ -486,6 +490,7 @@
    /variable/CMAKE_COMPILER_IS_GNUCC
    /variable/CMAKE_COMPILER_IS_GNUCXX
    /variable/CMAKE_COMPILER_IS_GNUG77
+   /variable/CMAKE_CUDA_ARCHITECTURES
    /variable/CMAKE_CUDA_COMPILE_FEATURES
    /variable/CMAKE_CUDA_HOST_COMPILER
    /variable/CMAKE_CUDA_EXTENSIONS
@@ -621,6 +626,7 @@
    /variable/CTEST_P4_COMMAND
    /variable/CTEST_P4_OPTIONS
    /variable/CTEST_P4_UPDATE_OPTIONS
+   /variable/CTEST_RESOURCE_SPEC_FILE
    /variable/CTEST_RUN_CURRENT_SCRIPT
    /variable/CTEST_SCP_COMMAND
    /variable/CTEST_SITE
diff --git a/Help/manual/cmake.1.rst b/Help/manual/cmake.1.rst
index d343874..c5e0aae 100644
--- a/Help/manual/cmake.1.rst
+++ b/Help/manual/cmake.1.rst
@@ -341,9 +341,9 @@
  Print a warning when an uninitialized variable is used.
 
 ``--warn-unused-vars``
- Warn about unused variables.
-
- Find variables that are declared or set, but not used.
+ Does nothing.  In CMake versions 3.2 and below this enabled warnings about
+ unused variables.  In CMake versions 3.3 through 3.18 the option was broken.
+ In CMake 3.19 and above the option has been removed.
 
 ``--no-warn-unused-cli``
  Don't warn about command line options.
@@ -358,6 +358,20 @@
  in :variable:`CMAKE_SOURCE_DIR` and :variable:`CMAKE_BINARY_DIR`.
  This flag tells CMake to warn about other files as well.
 
+``--profiling-output=<path>``
+ Used in conjunction with ``--profiling-format`` to output to a given path.
+
+``--profiling-format=<file>``
+ Enable the output of profiling data of CMake script in the given format.
+
+ This can aid performance analysis of CMake scripts executed. Third party
+ applications should be used to process the output into human readable format.
+
+ Currently supported values are:
+ ``google-trace`` Outputs in Google Trace Format, which can be parsed by the
+ about:tracing tab of Google Chrome or using a plugin for a tool like Trace
+ Compass.
+
 .. _`Build Tool Mode`:
 
 Build a Project
@@ -436,6 +450,9 @@
 ``--component <comp>``
   Component-based install. Only install component ``<comp>``.
 
+``--default-directory-permissions <permissions>``
+  Default directory install permissions. Permissions in format ``<u=rwx,g=rx,o=rx>``.
+
 ``--prefix <prefix>``
   Override the installation prefix, :variable:`CMAKE_INSTALL_PREFIX`.
 
@@ -467,13 +484,17 @@
 
 .. code-block:: shell
 
-  cmake [{-D <var>=<value>}...] -P <cmake-script-file>
+  cmake [{-D <var>=<value>}...] -P <cmake-script-file> [-- <unparsed-options>...]
 
 Process the given cmake file as a script written in the CMake
 language.  No configure or generate step is performed and the cache
 is not modified.  If variables are defined using ``-D``, this must be
 done before the ``-P`` argument.
 
+Any options after ``--`` are not parsed by CMake, but they are still included
+in the set of :variable:`CMAKE_ARGV<n> <CMAKE_ARGV0>` variables passed to the
+script (including the ``--`` itself).
+
 
 Run a Command-Line Tool
 =======================
@@ -540,12 +561,16 @@
   ``serverMode``
     ``true`` if cmake supports server-mode and ``false`` otherwise.
 
+``cat <files>...``
+  Concatenate files and print on the standard output.
+
 ``chdir <dir> <cmd> [<arg>...]``
   Change the current working directory and run a command.
 
 ``compare_files [--ignore-eol] <file1> <file2>``
   Check if ``<file1>`` is same as ``<file2>``. If files are the same,
-  then returns ``0``, if not it returns ``1``.  The ``--ignore-eol`` option
+  then returns ``0``, if not it returns ``1``.  In case of invalid
+  arguments, it returns 2. The ``--ignore-eol`` option
   implies line-wise comparison and ignores LF/CRLF differences.
 
 ``copy <file>... <destination>``
@@ -573,6 +598,13 @@
   .. note::
     Path to where ``<new>`` symbolic link will be created has to exist beforehand.
 
+``create_hardlink <old> <new>``
+  Create a hard link ``<new>`` naming ``<old>``.
+
+  .. note::
+    Path to where ``<new>`` hard link will be created has to exist beforehand.
+    ``<old>`` has to exist beforehand.
+
 ``echo [<string>...]``
   Displays arguments as text.
 
diff --git a/Help/manual/ctest.1.rst b/Help/manual/ctest.1.rst
index 6503f0e..b5bb1c1 100644
--- a/Help/manual/ctest.1.rst
+++ b/Help/manual/ctest.1.rst
@@ -72,6 +72,9 @@
  This option can also be enabled by setting the
  :envvar:`CTEST_OUTPUT_ON_FAILURE` environment variable
 
+``--stop-on-failure``
+ Stop running the tests when the first failure happens.
+
 ``-F``
  Enable failover.
 
@@ -994,8 +997,12 @@
 
 ``ResourceSpecFile``
   Specify a
-  :ref:`resource specification file <ctest-resource-specification-file>`. See
-  :ref:`ctest-resource-allocation` for more information.
+  :ref:`resource specification file <ctest-resource-specification-file>`.
+
+  * `CTest Script`_ variable: :variable:`CTEST_RESOURCE_SPEC_FILE`
+  * :module:`CTest` module variable: ``CTEST_RESOURCE_SPEC_FILE``
+
+  See :ref:`ctest-resource-allocation` for more information.
 
 ``LabelsForSubprojects``
   Specify a semicolon-separated list of labels that will be treated as
@@ -1326,7 +1333,7 @@
 ===================
 
 CTest provides a mechanism for tests to specify the resources that they need
-in a fine-grained way, and for users to specify the resources availiable on
+in a fine-grained way, and for users to specify the resources available on
 the running machine. This allows CTest to internally keep track of which
 resources are in use and which are free, scheduling tests in a way that
 prevents them from trying to claim resources that are not available.
@@ -1403,9 +1410,16 @@
 
 The resource specification file is a JSON file which is passed to CTest, either
 on the :manual:`ctest(1)` command line as ``--resource-spec-file``, or as the
-``RESOURCE_SPEC_FILE`` argument of :command:`ctest_test`. The resource
-specification file must be a JSON object. All examples in this document assume
-the following resource specification file:
+``RESOURCE_SPEC_FILE`` argument of :command:`ctest_test`. If a dashboard script
+is used and ``RESOURCE_SPEC_FILE`` is not specified, the value of
+:variable:`CTEST_RESOURCE_SPEC_FILE` in the dashboard script is used instead.
+If ``--resource-spec-file``, ``RESOURCE_SPEC_FILE``, and
+:variable:`CTEST_RESOURCE_SPEC_FILE` in the dashboard script are not specified,
+the value of :variable:`CTEST_RESOURCE_SPEC_FILE` in the CMake build is used
+instead. If none of these are specified, no resource spec file is used.
+
+The resource specification file must be a JSON object. All examples in this
+document assume the following resource specification file:
 
 .. code-block:: json
 
diff --git a/Help/module/CPackArchive.rst b/Help/module/CPackArchive.rst
index 8616098..f5d6da4 100644
--- a/Help/module/CPackArchive.rst
+++ b/Help/module/CPackArchive.rst
@@ -1,4 +1,6 @@
 CPackArchive
 ------------
 
+.. versionadded:: 3.9
+
 The documentation for the CPack Archive generator has moved here: :cpack_gen:`CPack Archive Generator`
diff --git a/Help/module/CPackFreeBSD.rst b/Help/module/CPackFreeBSD.rst
index 69701b8..7ae6164 100644
--- a/Help/module/CPackFreeBSD.rst
+++ b/Help/module/CPackFreeBSD.rst
@@ -1,4 +1,6 @@
 CPackFreeBSD
 ------------
 
+.. versionadded:: 3.10
+
 The documentation for the CPack FreeBSD generator has moved here: :cpack_gen:`CPack FreeBSD Generator`
diff --git a/Help/module/CPackNuGet.rst b/Help/module/CPackNuGet.rst
index 4f39b3a..bbed7f9 100644
--- a/Help/module/CPackNuGet.rst
+++ b/Help/module/CPackNuGet.rst
@@ -1,4 +1,6 @@
 CPackNuGet
 ----------
 
+.. versionadded:: 3.12
+
 The documentation for the CPack NuGet generator has moved here: :cpack_gen:`CPack NuGet Generator`
diff --git a/Help/module/CPackProductBuild.rst b/Help/module/CPackProductBuild.rst
index 8cd9198..e12cd32 100644
--- a/Help/module/CPackProductBuild.rst
+++ b/Help/module/CPackProductBuild.rst
@@ -1,4 +1,6 @@
 CPackProductBuild
 -----------------
 
+.. versionadded:: 3.7
+
 The documentation for the CPack productbuild generator has moved here: :cpack_gen:`CPack productbuild Generator`
diff --git a/Help/module/CheckLinkerFlag.rst b/Help/module/CheckLinkerFlag.rst
new file mode 100644
index 0000000..4005725
--- /dev/null
+++ b/Help/module/CheckLinkerFlag.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/CheckLinkerFlag.cmake
diff --git a/Help/policy/CMP0051.rst b/Help/policy/CMP0051.rst
index 6b679e5..053bc97 100644
--- a/Help/policy/CMP0051.rst
+++ b/Help/policy/CMP0051.rst
@@ -1,6 +1,8 @@
 CMP0051
 -------
 
+.. versionadded:: 3.1
+
 List TARGET_OBJECTS in SOURCES target property.
 
 CMake 3.0 and lower did not include the ``TARGET_OBJECTS``
diff --git a/Help/policy/CMP0052.rst b/Help/policy/CMP0052.rst
index ee2e6e8..c75f9ab 100644
--- a/Help/policy/CMP0052.rst
+++ b/Help/policy/CMP0052.rst
@@ -1,6 +1,8 @@
 CMP0052
 -------
 
+.. versionadded:: 3.1
+
 Reject source and build dirs in installed
 :prop_tgt:`INTERFACE_INCLUDE_DIRECTORIES`.
 
diff --git a/Help/policy/CMP0053.rst b/Help/policy/CMP0053.rst
index 032b3e5..9b18b2d 100644
--- a/Help/policy/CMP0053.rst
+++ b/Help/policy/CMP0053.rst
@@ -1,6 +1,8 @@
 CMP0053
 -------
 
+.. versionadded:: 3.1
+
 Simplify variable reference and escape sequence evaluation.
 
 CMake 3.1 introduced a much faster implementation of evaluation of the
diff --git a/Help/policy/CMP0054.rst b/Help/policy/CMP0054.rst
index 1e000a6..c7ae019 100644
--- a/Help/policy/CMP0054.rst
+++ b/Help/policy/CMP0054.rst
@@ -1,6 +1,8 @@
 CMP0054
 -------
 
+.. versionadded:: 3.1
+
 Only interpret :command:`if` arguments as variables or keywords when unquoted.
 
 CMake 3.1 and above no longer implicitly dereference variables or
diff --git a/Help/policy/CMP0055.rst b/Help/policy/CMP0055.rst
index bc5ad08..47cac8e 100644
--- a/Help/policy/CMP0055.rst
+++ b/Help/policy/CMP0055.rst
@@ -1,6 +1,8 @@
 CMP0055
 -------
 
+.. versionadded:: 3.2
+
 Strict checking for the :command:`break` command.
 
 CMake 3.1 and lower allowed calls to the :command:`break` command
diff --git a/Help/policy/CMP0056.rst b/Help/policy/CMP0056.rst
index 834da84..628a6a1 100644
--- a/Help/policy/CMP0056.rst
+++ b/Help/policy/CMP0056.rst
@@ -1,6 +1,8 @@
 CMP0056
 -------
 
+.. versionadded:: 3.2
+
 Honor link flags in :command:`try_compile` source-file signature.
 
 The :command:`try_compile` command source-file signature generates a
diff --git a/Help/policy/CMP0057.rst b/Help/policy/CMP0057.rst
index 83db186..76aebfb 100644
--- a/Help/policy/CMP0057.rst
+++ b/Help/policy/CMP0057.rst
@@ -1,6 +1,8 @@
 CMP0057
 -------
 
+.. versionadded:: 3.3
+
 Support new :command:`if` IN_LIST operator.
 
 CMake 3.3 adds support for the new IN_LIST operator.
diff --git a/Help/policy/CMP0058.rst b/Help/policy/CMP0058.rst
index 05efd48..06cc74b 100644
--- a/Help/policy/CMP0058.rst
+++ b/Help/policy/CMP0058.rst
@@ -1,6 +1,8 @@
 CMP0058
 -------
 
+.. versionadded:: 3.3
+
 Ninja requires custom command byproducts to be explicit.
 
 When an intermediate file generated during the build is consumed
diff --git a/Help/policy/CMP0059.rst b/Help/policy/CMP0059.rst
index bce982e..6317d05 100644
--- a/Help/policy/CMP0059.rst
+++ b/Help/policy/CMP0059.rst
@@ -1,6 +1,8 @@
 CMP0059
 -------
 
+.. versionadded:: 3.3
+
 Do not treat ``DEFINITIONS`` as a built-in directory property.
 
 CMake 3.3 and above no longer make a list of definitions available through
diff --git a/Help/policy/CMP0060.rst b/Help/policy/CMP0060.rst
index 98ac2cf..09257d1 100644
--- a/Help/policy/CMP0060.rst
+++ b/Help/policy/CMP0060.rst
@@ -1,6 +1,8 @@
 CMP0060
 -------
 
+.. versionadded:: 3.3
+
 Link libraries by full path even in implicit directories.
 
 Policy :policy:`CMP0003` was introduced with the intention of always
diff --git a/Help/policy/CMP0061.rst b/Help/policy/CMP0061.rst
index 57e4161..aca551d 100644
--- a/Help/policy/CMP0061.rst
+++ b/Help/policy/CMP0061.rst
@@ -1,6 +1,8 @@
 CMP0061
 -------
 
+.. versionadded:: 3.3
+
 CTest does not by default tell ``make`` to ignore errors (``-i``).
 
 The :command:`ctest_build` and :command:`build_command` commands no
diff --git a/Help/policy/CMP0062.rst b/Help/policy/CMP0062.rst
index 0db7aaf..01e93f0 100644
--- a/Help/policy/CMP0062.rst
+++ b/Help/policy/CMP0062.rst
@@ -1,6 +1,8 @@
 CMP0062
 -------
 
+.. versionadded:: 3.3
+
 Disallow :command:`install` of :command:`export` result.
 
 The :command:`export()` command generates a file containing
diff --git a/Help/policy/CMP0063.rst b/Help/policy/CMP0063.rst
index d736d06..fec3ad8 100644
--- a/Help/policy/CMP0063.rst
+++ b/Help/policy/CMP0063.rst
@@ -1,6 +1,8 @@
 CMP0063
 -------
 
+.. versionadded:: 3.3
+
 Honor visibility properties for all target types.
 
 The :prop_tgt:`<LANG>_VISIBILITY_PRESET` and
diff --git a/Help/policy/CMP0064.rst b/Help/policy/CMP0064.rst
index e9a061b..0c20c13 100644
--- a/Help/policy/CMP0064.rst
+++ b/Help/policy/CMP0064.rst
@@ -1,6 +1,8 @@
 CMP0064
 -------
 
+.. versionadded:: 3.4
+
 Recognize ``TEST`` as a operator for the :command:`if` command.
 
 The ``TEST`` operator was added to the :command:`if` command to determine if a
diff --git a/Help/policy/CMP0065.rst b/Help/policy/CMP0065.rst
index b820aad..8968b91 100644
--- a/Help/policy/CMP0065.rst
+++ b/Help/policy/CMP0065.rst
@@ -1,6 +1,8 @@
 CMP0065
 -------
 
+.. versionadded:: 3.4
+
 Do not add flags to export symbols from executables without
 the :prop_tgt:`ENABLE_EXPORTS` target property.
 
diff --git a/Help/policy/CMP0066.rst b/Help/policy/CMP0066.rst
index e110ae1..b08430f 100644
--- a/Help/policy/CMP0066.rst
+++ b/Help/policy/CMP0066.rst
@@ -1,6 +1,8 @@
 CMP0066
 -------
 
+.. versionadded:: 3.7
+
 Honor per-config flags in :command:`try_compile` source-file signature.
 
 The source file signature of the :command:`try_compile` command uses the value
diff --git a/Help/policy/CMP0067.rst b/Help/policy/CMP0067.rst
index f802787..8358bb2 100644
--- a/Help/policy/CMP0067.rst
+++ b/Help/policy/CMP0067.rst
@@ -1,6 +1,8 @@
 CMP0067
 -------
 
+.. versionadded:: 3.8
+
 Honor language standard in :command:`try_compile` source-file signature.
 
 The :command:`try_compile` source file signature is intended to allow
diff --git a/Help/policy/CMP0068.rst b/Help/policy/CMP0068.rst
index 978a6e3..5d2a4b1 100644
--- a/Help/policy/CMP0068.rst
+++ b/Help/policy/CMP0068.rst
@@ -1,6 +1,8 @@
 CMP0068
 -------
 
+.. versionadded:: 3.9
+
 ``RPATH`` settings on macOS do not affect ``install_name``.
 
 CMake 3.9 and newer remove any effect the following settings may have on the
diff --git a/Help/policy/CMP0069.rst b/Help/policy/CMP0069.rst
index 0d5ddfd..eafac45 100644
--- a/Help/policy/CMP0069.rst
+++ b/Help/policy/CMP0069.rst
@@ -1,6 +1,8 @@
 CMP0069
 -------
 
+.. versionadded:: 3.9
+
 :prop_tgt:`INTERPROCEDURAL_OPTIMIZATION` is enforced when enabled.
 
 CMake 3.9 and newer prefer to add IPO flags whenever the
diff --git a/Help/policy/CMP0070.rst b/Help/policy/CMP0070.rst
index 0fb3617..c880d1f 100644
--- a/Help/policy/CMP0070.rst
+++ b/Help/policy/CMP0070.rst
@@ -1,6 +1,8 @@
 CMP0070
 -------
 
+.. versionadded:: 3.10
+
 Define :command:`file(GENERATE)` behavior for relative paths.
 
 CMake 3.10 and newer define that relative paths given to ``INPUT`` and
diff --git a/Help/policy/CMP0071.rst b/Help/policy/CMP0071.rst
index 855ecf0..700d3b0 100644
--- a/Help/policy/CMP0071.rst
+++ b/Help/policy/CMP0071.rst
@@ -1,6 +1,8 @@
 CMP0071
 -------
 
+.. versionadded:: 3.10
+
 Let :prop_tgt:`AUTOMOC` and :prop_tgt:`AUTOUIC` process
 :prop_sf:`GENERATED` files.
 
diff --git a/Help/policy/CMP0072.rst b/Help/policy/CMP0072.rst
index 3abbad7..1dcdfef 100644
--- a/Help/policy/CMP0072.rst
+++ b/Help/policy/CMP0072.rst
@@ -1,6 +1,8 @@
 CMP0072
 -------
 
+.. versionadded:: 3.11
+
 :module:`FindOpenGL` prefers GLVND by default when available.
 
 The :module:`FindOpenGL` module provides an ``OpenGL::GL`` target and an
diff --git a/Help/policy/CMP0073.rst b/Help/policy/CMP0073.rst
index 9bfa0e9..8f0345c 100644
--- a/Help/policy/CMP0073.rst
+++ b/Help/policy/CMP0073.rst
@@ -1,6 +1,8 @@
 CMP0073
 -------
 
+.. versionadded:: 3.12
+
 Do not produce legacy ``_LIB_DEPENDS`` cache entries.
 
 Ancient CMake versions once used ``<tgt>_LIB_DEPENDS`` cache entries to
diff --git a/Help/policy/CMP0074.rst b/Help/policy/CMP0074.rst
index 63ebf7b..863bbb2 100644
--- a/Help/policy/CMP0074.rst
+++ b/Help/policy/CMP0074.rst
@@ -1,6 +1,8 @@
 CMP0074
 -------
 
+.. versionadded:: 3.12
+
 :command:`find_package` uses ``<PackageName>_ROOT`` variables.
 
 In CMake 3.12 and above the :command:`find_package(<PackageName>)` command now
diff --git a/Help/policy/CMP0075.rst b/Help/policy/CMP0075.rst
index aa5c3f7..4213782 100644
--- a/Help/policy/CMP0075.rst
+++ b/Help/policy/CMP0075.rst
@@ -1,6 +1,8 @@
 CMP0075
 -------
 
+.. versionadded:: 3.12
+
 Include file check macros honor ``CMAKE_REQUIRED_LIBRARIES``.
 
 In CMake 3.12 and above, the
diff --git a/Help/policy/CMP0076.rst b/Help/policy/CMP0076.rst
index dd25f80..edca742 100644
--- a/Help/policy/CMP0076.rst
+++ b/Help/policy/CMP0076.rst
@@ -1,6 +1,8 @@
 CMP0076
 -------
 
+.. versionadded:: 3.13
+
 The :command:`target_sources` command converts relative paths to absolute.
 
 In CMake 3.13 and above, the :command:`target_sources` command now converts
diff --git a/Help/policy/CMP0077.rst b/Help/policy/CMP0077.rst
index 44797b6..174cde9 100644
--- a/Help/policy/CMP0077.rst
+++ b/Help/policy/CMP0077.rst
@@ -1,6 +1,8 @@
 CMP0077
 -------
 
+.. versionadded:: 3.13
+
 :command:`option` honors normal variables.
 
 The :command:`option` command is typically used to create a cache entry
diff --git a/Help/policy/CMP0078.rst b/Help/policy/CMP0078.rst
index 2e97934..89fdb0b 100644
--- a/Help/policy/CMP0078.rst
+++ b/Help/policy/CMP0078.rst
@@ -1,6 +1,8 @@
 CMP0078
 -------
 
+.. versionadded:: 3.13
+
 :module:`UseSWIG` generates standard target names.
 
 Starting with CMake 3.13, :module:`UseSWIG` generates now standard target
diff --git a/Help/policy/CMP0079.rst b/Help/policy/CMP0079.rst
index 0244d6c..01aa08d 100644
--- a/Help/policy/CMP0079.rst
+++ b/Help/policy/CMP0079.rst
@@ -1,6 +1,8 @@
 CMP0079
 -------
 
+.. versionadded:: 3.13
+
 :command:`target_link_libraries` allows use with targets in other directories.
 
 Prior to CMake 3.13 the :command:`target_link_libraries` command did not
diff --git a/Help/policy/CMP0080.rst b/Help/policy/CMP0080.rst
index 5ce9591..789efea 100644
--- a/Help/policy/CMP0080.rst
+++ b/Help/policy/CMP0080.rst
@@ -1,6 +1,8 @@
 CMP0080
 -------
 
+.. versionadded:: 3.13
+
 :module:`BundleUtilities` cannot be included at configure time.
 
 The macros provided by :module:`BundleUtilities` are intended to be invoked
diff --git a/Help/policy/CMP0081.rst b/Help/policy/CMP0081.rst
index d3b2872..d1573dd 100644
--- a/Help/policy/CMP0081.rst
+++ b/Help/policy/CMP0081.rst
@@ -1,6 +1,8 @@
 CMP0081
 -------
 
+.. versionadded:: 3.13
+
 Relative paths not allowed in :prop_tgt:`LINK_DIRECTORIES` target property.
 
 CMake 3.12 and lower allowed the :prop_dir:`LINK_DIRECTORIES` directory
diff --git a/Help/policy/CMP0082.rst b/Help/policy/CMP0082.rst
index d887616..25c9580 100644
--- a/Help/policy/CMP0082.rst
+++ b/Help/policy/CMP0082.rst
@@ -1,6 +1,8 @@
 CMP0082
 -------
 
+.. versionadded:: 3.14
+
 Install rules from :command:`add_subdirectory` calls are interleaved with
 those in caller.
 
diff --git a/Help/policy/CMP0083.rst b/Help/policy/CMP0083.rst
index e0b09cf..7518ee3 100644
--- a/Help/policy/CMP0083.rst
+++ b/Help/policy/CMP0083.rst
@@ -1,6 +1,8 @@
 CMP0083
 -------
 
+.. versionadded:: 3.14
+
 To control generation of Position Independent Executable (``PIE``) or not, some
 flags are required at link time.
 
diff --git a/Help/policy/CMP0084.rst b/Help/policy/CMP0084.rst
index 713d295..9547701 100644
--- a/Help/policy/CMP0084.rst
+++ b/Help/policy/CMP0084.rst
@@ -1,6 +1,8 @@
 CMP0084
 -------
 
+.. versionadded:: 3.14
+
 The :module:`FindQt` module does not exist for :command:`find_package`.
 
 The existence of :module:`FindQt` means that for Qt upstream to provide
diff --git a/Help/policy/CMP0085.rst b/Help/policy/CMP0085.rst
index d9ec9a2..d90c72f 100644
--- a/Help/policy/CMP0085.rst
+++ b/Help/policy/CMP0085.rst
@@ -1,6 +1,8 @@
 CMP0085
 -------
 
+.. versionadded:: 3.14
+
 ``$<IN_LIST:...>`` handles empty list items.
 
 In CMake 3.13 and lower, the ``$<IN_LIST:...>`` generator expression always
diff --git a/Help/policy/CMP0086.rst b/Help/policy/CMP0086.rst
index 4a9e8b8..725b502 100644
--- a/Help/policy/CMP0086.rst
+++ b/Help/policy/CMP0086.rst
@@ -1,6 +1,8 @@
 CMP0086
 -------
 
+.. versionadded:: 3.14
+
 :module:`UseSWIG` honors ``SWIG_MODULE_NAME`` via ``-module`` flag.
 
 Starting with CMake 3.14, :module:`UseSWIG` passes option
diff --git a/Help/policy/CMP0087.rst b/Help/policy/CMP0087.rst
index 4c45b99..4a65506 100644
--- a/Help/policy/CMP0087.rst
+++ b/Help/policy/CMP0087.rst
@@ -1,6 +1,8 @@
 CMP0087
 -------
 
+.. versionadded:: 3.14
+
 :command:`install(CODE)` and :command:`install(SCRIPT)` support generator
 expressions.
 
diff --git a/Help/policy/CMP0088.rst b/Help/policy/CMP0088.rst
index 82c04ef..1840a58 100644
--- a/Help/policy/CMP0088.rst
+++ b/Help/policy/CMP0088.rst
@@ -1,6 +1,8 @@
 CMP0088
 -------
 
+.. versionadded:: 3.14
+
 :module:`FindBISON` runs bison in :variable:`CMAKE_CURRENT_BINARY_DIR`
 when executing.
 
diff --git a/Help/policy/CMP0089.rst b/Help/policy/CMP0089.rst
index 029de55..e3fc77a 100644
--- a/Help/policy/CMP0089.rst
+++ b/Help/policy/CMP0089.rst
@@ -1,6 +1,8 @@
 CMP0089
 -------
 
+.. versionadded:: 3.15
+
 Compiler id for IBM Clang-based XL compilers is now ``XLClang``.
 
 CMake 3.15 and above recognize that IBM's Clang-based XL compilers
diff --git a/Help/policy/CMP0090.rst b/Help/policy/CMP0090.rst
index 720c17c..58dd999 100644
--- a/Help/policy/CMP0090.rst
+++ b/Help/policy/CMP0090.rst
@@ -1,6 +1,8 @@
 CMP0090
 -------
 
+.. versionadded:: 3.15
+
 :command:`export(PACKAGE)` does not populate package registry by default.
 
 In CMake 3.14 and below the :command:`export(PACKAGE)` command populated the
diff --git a/Help/policy/CMP0091.rst b/Help/policy/CMP0091.rst
index 1a5878a..ffc0ade 100644
--- a/Help/policy/CMP0091.rst
+++ b/Help/policy/CMP0091.rst
@@ -1,6 +1,8 @@
 CMP0091
 -------
 
+.. versionadded:: 3.15
+
 MSVC runtime library flags are selected by an abstraction.
 
 Compilers targeting the MSVC ABI have flags to select the MSVC runtime library.
diff --git a/Help/policy/CMP0092.rst b/Help/policy/CMP0092.rst
index 8d3a288..2f39830 100644
--- a/Help/policy/CMP0092.rst
+++ b/Help/policy/CMP0092.rst
@@ -1,6 +1,8 @@
 CMP0092
 -------
 
+.. versionadded:: 3.15
+
 MSVC warning flags are not in :variable:`CMAKE_<LANG>_FLAGS` by default.
 
 When using MSVC-like compilers in CMake 3.14 and below, warning flags
@@ -16,7 +18,7 @@
 This policy provides compatibility with projects that have not been updated
 to expect the lack of warning flags.  The policy setting takes effect as of
 the first :command:`project` or :command:`enable_language` command that
-initializes :variable:`CMAKE_<LANG>_FLAGS` for a given lanuage ``<LANG>``.
+initializes :variable:`CMAKE_<LANG>_FLAGS` for a given language ``<LANG>``.
 
 .. note::
 
diff --git a/Help/policy/CMP0093.rst b/Help/policy/CMP0093.rst
index 0ffc493..4a9955f 100644
--- a/Help/policy/CMP0093.rst
+++ b/Help/policy/CMP0093.rst
@@ -1,6 +1,8 @@
 CMP0093
 -------
 
+.. versionadded:: 3.15
+
 :module:`FindBoost` reports ``Boost_VERSION`` in ``x.y.z`` format.
 
 In CMake 3.14 and below the module would report the Boost version
diff --git a/Help/policy/CMP0094.rst b/Help/policy/CMP0094.rst
index 836f30f..1b57658 100644
--- a/Help/policy/CMP0094.rst
+++ b/Help/policy/CMP0094.rst
@@ -1,6 +1,8 @@
 CMP0094
 -------
 
+.. versionadded:: 3.15
+
 Modules :module:`FindPython3`, :module:`FindPython2` and :module:`FindPython`
 use ``LOCATION`` for lookup strategy.
 
diff --git a/Help/policy/CMP0095.rst b/Help/policy/CMP0095.rst
index 4c56a05..ebdbab6 100644
--- a/Help/policy/CMP0095.rst
+++ b/Help/policy/CMP0095.rst
@@ -1,6 +1,8 @@
 CMP0095
 -------
 
+.. versionadded:: 3.16
+
 ``RPATH`` entries are properly escaped in the intermediary CMake install script.
 
 In CMake 3.15 and earlier, ``RPATH`` entries set via
diff --git a/Help/policy/CMP0096.rst b/Help/policy/CMP0096.rst
index 8eaf0f9..8fd6f72 100644
--- a/Help/policy/CMP0096.rst
+++ b/Help/policy/CMP0096.rst
@@ -1,6 +1,8 @@
 CMP0096
 -------
 
+.. versionadded:: 3.16
+
 The :command:`project` command preserves leading zeros in version components.
 
 When a ``VERSION <major>[.<minor>[.<patch>[.<tweak>]]]]`` argument is given
diff --git a/Help/policy/CMP0097.rst b/Help/policy/CMP0097.rst
index 4840aa6..2240874 100644
--- a/Help/policy/CMP0097.rst
+++ b/Help/policy/CMP0097.rst
@@ -1,6 +1,8 @@
 CMP0097
 -------
 
+.. versionadded:: 3.16
+
 :command:`ExternalProject_Add` with ``GIT_SUBMODULES ""`` initializes no
 submodules.
 
diff --git a/Help/policy/CMP0098.rst b/Help/policy/CMP0098.rst
index 6d1443b..e793380 100644
--- a/Help/policy/CMP0098.rst
+++ b/Help/policy/CMP0098.rst
@@ -1,6 +1,8 @@
 CMP0098
 -------
 
+.. versionadded:: 3.17
+
 :module:`FindFLEX` runs ``flex`` in directory
 :variable:`CMAKE_CURRENT_BINARY_DIR` when executing.
 
diff --git a/Help/policy/CMP0099.rst b/Help/policy/CMP0099.rst
index c897e7b..0c64949 100644
--- a/Help/policy/CMP0099.rst
+++ b/Help/policy/CMP0099.rst
@@ -1,6 +1,8 @@
 CMP0099
 -------
 
+.. versionadded:: 3.17
+
 Target link properties :prop_tgt:`INTERFACE_LINK_OPTIONS`,
 :prop_tgt:`INTERFACE_LINK_DIRECTORIES` and :prop_tgt:`INTERFACE_LINK_DEPENDS`
 are now transitive over private dependencies of static libraries.
diff --git a/Help/policy/CMP0100.rst b/Help/policy/CMP0100.rst
index b24d013..730fa82 100644
--- a/Help/policy/CMP0100.rst
+++ b/Help/policy/CMP0100.rst
@@ -1,6 +1,8 @@
 CMP0100
 -------
 
+.. versionadded:: 3.17
+
 Let :prop_tgt:`AUTOMOC` and :prop_tgt:`AUTOUIC` process
 header files that end with a ``.hh`` extension.
 
diff --git a/Help/policy/CMP0101.rst b/Help/policy/CMP0101.rst
index 9941acf..f02bccc 100644
--- a/Help/policy/CMP0101.rst
+++ b/Help/policy/CMP0101.rst
@@ -1,6 +1,8 @@
 CMP0101
 -------
 
+.. versionadded:: 3.17
+
 :command:`target_compile_options` now honors ``BEFORE`` keyword in all scopes.
 
 In CMake 3.16 and below the :command:`target_compile_options` ignores the
diff --git a/Help/policy/CMP0102.rst b/Help/policy/CMP0102.rst
index 9859006..78b5584 100644
--- a/Help/policy/CMP0102.rst
+++ b/Help/policy/CMP0102.rst
@@ -1,6 +1,8 @@
 CMP0102
 -------
 
+.. versionadded:: 3.17
+
 The :command:`mark_as_advanced` command no longer creates a cache entry if one
 does not already exist.
 
diff --git a/Help/policy/CMP0103.rst b/Help/policy/CMP0103.rst
new file mode 100644
index 0000000..b5f44d1
--- /dev/null
+++ b/Help/policy/CMP0103.rst
@@ -0,0 +1,24 @@
+CMP0103
+-------
+
+.. versionadded:: 3.18
+
+Multiple calls to :command:`export` command with same ``FILE`` without
+``APPEND`` is no longer allowed.
+
+In CMake 3.17 and below, multiple calls to :command:`export` command with the
+same ``FILE`` without ``APPEND`` are accepted silently but only the last
+occurrence is taken into account during the generation.
+
+The ``OLD`` behavior for this policy is to ignore the multiple occurrences of
+ :command:`export` command except the last one.
+
+The ``NEW`` behavior of this policy is to raise an error on second call to
+:command:`export` command with same ``FILE`` without ``APPEND``.
+
+This policy was introduced in CMake version 3.18.  CMake version
+|release| warns when the policy is not set and uses ``OLD`` behavior.
+Use the :command:`cmake_policy` command to set it to ``OLD`` or ``NEW``
+explicitly.
+
+.. include:: DEPRECATED.txt
diff --git a/Help/policy/CMP0104.rst b/Help/policy/CMP0104.rst
new file mode 100644
index 0000000..7c7a16e
--- /dev/null
+++ b/Help/policy/CMP0104.rst
@@ -0,0 +1,58 @@
+CMP0104
+-------
+
+.. versionadded:: 3.18
+
+Initialize :variable:`CMAKE_CUDA_ARCHITECTURES` when
+:variable:`CMAKE_CUDA_COMPILER_ID <CMAKE_<LANG>_COMPILER_ID>` is ``NVIDIA``.
+Raise an error if :prop_tgt:`CUDA_ARCHITECTURES` is empty.
+
+:variable:`CMAKE_CUDA_ARCHITECTURES` introduced in CMake 3.18 is used to
+initialize :prop_tgt:`CUDA_ARCHITECTURES`, which passes correct code generation
+flags to the CUDA compiler.
+
+Previous to this users had to manually specify the code generation flags. This
+policy is for backwards compatibility with manually specifying code generation
+flags.
+
+The ``OLD`` behavior for this policy is to not initialize
+:variable:`CMAKE_CUDA_ARCHITECTURES` when
+:variable:`CMAKE_CUDA_COMPILER_ID <CMAKE_<LANG>_COMPILER_ID>` is ``NVIDIA``.
+Empty :prop_tgt:`CUDA_ARCHITECTURES` is allowed.
+
+The ``NEW`` behavior of this policy is to initialize
+:variable:`CMAKE_CUDA_ARCHITECTURES` when
+:variable:`CMAKE_CUDA_COMPILER_ID <CMAKE_<LANG>_COMPILER_ID>` is ``NVIDIA``
+and raise an error if :prop_tgt:`CUDA_ARCHITECTURES` is empty during generation.
+
+If :prop_tgt:`CUDA_ARCHITECTURES` is set to a false value no architectures
+flags are passed to the compiler. This is intended to support packagers and
+the rare cases where full control over the passed flags is required.
+
+This policy was introduced in CMake version 3.18.  CMake version
+|release| warns when the policy is not set and uses ``OLD`` behavior.
+Use the :command:`cmake_policy` command to set it to ``OLD`` or ``NEW``
+explicitly.
+
+.. include:: DEPRECATED.txt
+
+Examples
+^^^^^^^^
+
+.. code-block:: cmake
+
+  set_property(TARGET tgt PROPERTY CUDA_ARCHITECTURES 35 50 72)
+
+Generates code for real and virtual architectures ``30``, ``50`` and ``72``.
+
+.. code-block:: cmake
+
+  set_property(TARGET tgt PROPERTY CUDA_ARCHITECTURES 70-real 72-virtual)
+
+Generates code for real architecture ``70`` and virtual architecture ``72``.
+
+.. code-block:: cmake
+
+  set_property(TARGET tgt PROPERTY CUDA_ARCHITECTURES OFF)
+
+CMake will not pass any architecture flags to the compiler.
diff --git a/Help/policy/CMP0105.rst b/Help/policy/CMP0105.rst
new file mode 100644
index 0000000..097a59a
--- /dev/null
+++ b/Help/policy/CMP0105.rst
@@ -0,0 +1,21 @@
+CMP0105
+-------
+
+.. versionadded:: 3.18
+
+:prop_tgt:`LINK_OPTIONS` and :prop_tgt:`INTERFACE_LINK_OPTIONS` target
+properties are now used for the device link step.
+
+In CMake 3.17 and below, link options are not used by the device link step.
+
+The ``OLD`` behavior for this policy is to ignore the link options.
+
+The ``NEW`` behavior of this policy is to use the link options during the
+device link step.
+
+This policy was introduced in CMake version 3.17.  Use the
+:command:`cmake_policy` command to set it to ``OLD`` or ``NEW`` explicitly.
+Unlike many policies, CMake version |release| does *not* warn
+when this policy is not set and simply uses ``OLD`` behavior.
+
+.. include:: DEPRECATED.txt
diff --git a/Help/policy/CMP0106.rst b/Help/policy/CMP0106.rst
new file mode 100644
index 0000000..18a6635
--- /dev/null
+++ b/Help/policy/CMP0106.rst
@@ -0,0 +1,21 @@
+CMP0106
+-------
+
+.. versionadded:: 3.18
+
+The :module:`Documentation` module is removed.
+
+The :module:`Documentation` was added as a support mechanism for the VTK
+project and was tuned for that project. Instead of CMake providing this module
+with (now old) VTK patterns for cache variables and required packages, the
+module is now deprecated by CMake itself.
+
+The ``OLD`` behavior of this policy is for :module:`Documentation` to add
+cache variables and find VTK documentation dependent packages. The ``NEW``
+behavior is to act as an empty module.
+
+This policy was introduced in CMake version 3.18.  CMake version |release|
+warns when the policy is not set and uses ``OLD`` behavior. Use the
+:command:`cmake_policy` command to set it to ``OLD`` or ``NEW`` explicitly.
+
+.. include:: DEPRECATED.txt
diff --git a/Help/policy/CMP0107.rst b/Help/policy/CMP0107.rst
new file mode 100644
index 0000000..da5ae06
--- /dev/null
+++ b/Help/policy/CMP0107.rst
@@ -0,0 +1,21 @@
+CMP0107
+-------
+
+.. versionadded:: 3.18
+
+It is not allowed to create an ``ALIAS`` target with the same name as an
+another target.
+
+In CMake 3.17 and below, an ``ALIAS`` target can overwrite silently an existing
+target with the same name.
+
+The ``OLD`` behavior for this policy is to allow target overwrite.
+
+The ``NEW`` behavior of this policy is to prevent target overwriting.
+
+This policy was introduced in CMake version 3.17.  Use the
+:command:`cmake_policy` command to set it to ``OLD`` or ``NEW`` explicitly.
+Unlike many policies, CMake version |release| does *not* warn
+when this policy is not set and simply uses ``OLD`` behavior.
+
+.. include:: DEPRECATED.txt
diff --git a/Help/policy/CMP0108.rst b/Help/policy/CMP0108.rst
new file mode 100644
index 0000000..4d1091d
--- /dev/null
+++ b/Help/policy/CMP0108.rst
@@ -0,0 +1,21 @@
+CMP0108
+-------
+
+.. versionadded:: 3.18
+
+A target is not allowed to link to itself even through an ``ALIAS`` target.
+
+In CMake 3.17 and below, a target can link to a target aliased to itself.
+
+The ``OLD`` behavior for this policy is to allow a target to link to a target
+aliased to itself.
+
+The ``NEW`` behavior of this policy is to prevent a target to link to itself
+through an ``ALIAS`` target.
+
+This policy was introduced in CMake version 3.17.  Use the
+:command:`cmake_policy` command to set it to ``OLD`` or ``NEW`` explicitly.
+Unlike many policies, CMake version |release| does *not* warn
+when this policy is not set and simply uses ``OLD`` behavior.
+
+.. include:: DEPRECATED.txt
diff --git a/Help/policy/CMP0109.rst b/Help/policy/CMP0109.rst
new file mode 100644
index 0000000..f86287f
--- /dev/null
+++ b/Help/policy/CMP0109.rst
@@ -0,0 +1,24 @@
+CMP0109
+-------
+
+.. versionadded:: 3.19
+
+:command:`find_program` requires permission to execute but not to read.
+
+In CMake 3.18 and below, the :command:`find_program` command on UNIX
+would find files that are readable without requiring execute permission,
+and would not find files that are executable without read permission.
+In CMake 3.19 and above, ``find_program`` now prefers to require execute
+permission but not read permission.  This policy provides compatibility
+with projects that have not been updated to expect the new behavior.
+
+The ``OLD`` behavior for this policy is for ``find_program`` to require
+read permission but not execute permission.
+The ``NEW`` behavior for this policy is for ``find_program`` to require
+execute permission but not read permission.
+
+This policy was introduced in CMake version 3.19.  CMake version |release|
+warns when the policy is not set and uses ``OLD`` behavior.  Use the
+:command:`cmake_policy` command to set it to ``OLD`` or ``NEW`` explicitly.
+
+.. include:: DEPRECATED.txt
diff --git a/Help/prop_dir/ADDITIONAL_CLEAN_FILES.rst b/Help/prop_dir/ADDITIONAL_CLEAN_FILES.rst
index 051d22a..6097d14 100644
--- a/Help/prop_dir/ADDITIONAL_CLEAN_FILES.rst
+++ b/Help/prop_dir/ADDITIONAL_CLEAN_FILES.rst
@@ -1,6 +1,8 @@
 ADDITIONAL_CLEAN_FILES
 ----------------------
 
+.. versionadded:: 3.15
+
 A :ref:`;-list <CMake Language Lists>` of files or directories that will be
 removed as a part of the global ``clean`` target.  It is useful for
 specifying generated files or directories that are used by multiple targets
diff --git a/Help/prop_dir/BINARY_DIR.rst b/Help/prop_dir/BINARY_DIR.rst
index 597c79a..fcf9d17 100644
--- a/Help/prop_dir/BINARY_DIR.rst
+++ b/Help/prop_dir/BINARY_DIR.rst
@@ -1,5 +1,7 @@
 BINARY_DIR
 ----------
 
+.. versionadded:: 3.7
+
 This read-only directory property reports absolute path to the binary
 directory corresponding to the source on which it is read.
diff --git a/Help/prop_dir/BUILDSYSTEM_TARGETS.rst b/Help/prop_dir/BUILDSYSTEM_TARGETS.rst
index 04bb56e..5c5893d 100644
--- a/Help/prop_dir/BUILDSYSTEM_TARGETS.rst
+++ b/Help/prop_dir/BUILDSYSTEM_TARGETS.rst
@@ -1,6 +1,8 @@
 BUILDSYSTEM_TARGETS
 -------------------
 
+.. versionadded:: 3.7
+
 This read-only directory property contains a
 :ref:`semicolon-separated list <CMake Language Lists>` of buildsystem targets added in the
 directory by calls to the :command:`add_library`, :command:`add_executable`,
diff --git a/Help/prop_dir/LABELS.rst b/Help/prop_dir/LABELS.rst
index de27d90..bf14368 100644
--- a/Help/prop_dir/LABELS.rst
+++ b/Help/prop_dir/LABELS.rst
@@ -1,6 +1,8 @@
 LABELS
 ------
 
+.. versionadded:: 3.10
+
 Specify a list of text labels associated with a directory and all of its
 subdirectories. This is equivalent to setting the :prop_tgt:`LABELS` target
 property and the :prop_test:`LABELS` test property on all targets and tests in
diff --git a/Help/prop_dir/LINK_OPTIONS.rst b/Help/prop_dir/LINK_OPTIONS.rst
index 54ac6dd..3a5c72f 100644
--- a/Help/prop_dir/LINK_OPTIONS.rst
+++ b/Help/prop_dir/LINK_OPTIONS.rst
@@ -1,8 +1,10 @@
 LINK_OPTIONS
 ------------
 
+.. versionadded:: 3.13
+
 List of options to use for the link step of shared library, module
-and executable targets.
+and executable targets as well as the device link step.
 
 This property holds a :ref:`semicolon-separated list <CMake Language Lists>` of options
 given so far to the :command:`add_link_options` command.
diff --git a/Help/prop_dir/SOURCE_DIR.rst b/Help/prop_dir/SOURCE_DIR.rst
index ac98c3b..d73707d 100644
--- a/Help/prop_dir/SOURCE_DIR.rst
+++ b/Help/prop_dir/SOURCE_DIR.rst
@@ -1,5 +1,7 @@
 SOURCE_DIR
 ----------
 
+.. versionadded:: 3.7
+
 This read-only directory property reports absolute path to the source
 directory on which it is read.
diff --git a/Help/prop_dir/SUBDIRECTORIES.rst b/Help/prop_dir/SUBDIRECTORIES.rst
index 6a0ac80..71ea496 100644
--- a/Help/prop_dir/SUBDIRECTORIES.rst
+++ b/Help/prop_dir/SUBDIRECTORIES.rst
@@ -1,6 +1,8 @@
 SUBDIRECTORIES
 --------------
 
+.. versionadded:: 3.7
+
 This read-only directory property contains a
 :ref:`semicolon-separated list <CMake Language Lists>` of subdirectories processed so far by
 the :command:`add_subdirectory` or :command:`subdirs` commands.  Each entry is
diff --git a/Help/prop_dir/TESTS.rst b/Help/prop_dir/TESTS.rst
index 1c9f6e5..294be17 100644
--- a/Help/prop_dir/TESTS.rst
+++ b/Help/prop_dir/TESTS.rst
@@ -1,6 +1,8 @@
 TESTS
 -----
 
+.. versionadded:: 3.12
+
 List of tests.
 
 This read-only property holds a
diff --git a/Help/prop_dir/TEST_INCLUDE_FILES.rst b/Help/prop_dir/TEST_INCLUDE_FILES.rst
index c3e4602..f9a66f4 100644
--- a/Help/prop_dir/TEST_INCLUDE_FILES.rst
+++ b/Help/prop_dir/TEST_INCLUDE_FILES.rst
@@ -1,6 +1,8 @@
 TEST_INCLUDE_FILES
 ------------------
 
+.. versionadded:: 3.10
+
 A list of cmake files that will be included when ctest is run.
 
 If you specify ``TEST_INCLUDE_FILES``, those files will be included and
diff --git a/Help/prop_dir/VS_STARTUP_PROJECT.rst b/Help/prop_dir/VS_STARTUP_PROJECT.rst
index 2680dfa..8a0c3c8 100644
--- a/Help/prop_dir/VS_STARTUP_PROJECT.rst
+++ b/Help/prop_dir/VS_STARTUP_PROJECT.rst
@@ -1,6 +1,8 @@
 VS_STARTUP_PROJECT
 ------------------
 
+.. versionadded:: 3.6
+
 Specify the default startup project in a Visual Studio solution.
 
 The :ref:`Visual Studio Generators` create a ``.sln`` file for each directory
diff --git a/Help/prop_gbl/AUTOGEN_SOURCE_GROUP.rst b/Help/prop_gbl/AUTOGEN_SOURCE_GROUP.rst
index d294eb1..2e32320 100644
--- a/Help/prop_gbl/AUTOGEN_SOURCE_GROUP.rst
+++ b/Help/prop_gbl/AUTOGEN_SOURCE_GROUP.rst
@@ -1,6 +1,8 @@
 AUTOGEN_SOURCE_GROUP
 --------------------
 
+.. versionadded:: 3.9
+
 Name of the  :command:`source_group` for :prop_tgt:`AUTOMOC` and
 :prop_tgt:`AUTORCC` generated files.
 
diff --git a/Help/prop_gbl/AUTOMOC_SOURCE_GROUP.rst b/Help/prop_gbl/AUTOMOC_SOURCE_GROUP.rst
index 2455dc7..a266fde 100644
--- a/Help/prop_gbl/AUTOMOC_SOURCE_GROUP.rst
+++ b/Help/prop_gbl/AUTOMOC_SOURCE_GROUP.rst
@@ -1,6 +1,8 @@
 AUTOMOC_SOURCE_GROUP
 --------------------
 
+.. versionadded:: 3.9
+
 Name of the  :command:`source_group` for :prop_tgt:`AUTOMOC` generated files.
 
 When set this is used instead of :prop_gbl:`AUTOGEN_SOURCE_GROUP` for
diff --git a/Help/prop_gbl/AUTORCC_SOURCE_GROUP.rst b/Help/prop_gbl/AUTORCC_SOURCE_GROUP.rst
index 65ea95b..54ebabb 100644
--- a/Help/prop_gbl/AUTORCC_SOURCE_GROUP.rst
+++ b/Help/prop_gbl/AUTORCC_SOURCE_GROUP.rst
@@ -1,6 +1,8 @@
 AUTORCC_SOURCE_GROUP
 --------------------
 
+.. versionadded:: 3.9
+
 Name of the  :command:`source_group` for :prop_tgt:`AUTORCC` generated files.
 
 When set this is used instead of :prop_gbl:`AUTOGEN_SOURCE_GROUP` for
diff --git a/Help/prop_gbl/CMAKE_CUDA_KNOWN_FEATURES.rst b/Help/prop_gbl/CMAKE_CUDA_KNOWN_FEATURES.rst
index 44e37fe..e8e3148 100644
--- a/Help/prop_gbl/CMAKE_CUDA_KNOWN_FEATURES.rst
+++ b/Help/prop_gbl/CMAKE_CUDA_KNOWN_FEATURES.rst
@@ -1,6 +1,8 @@
 CMAKE_CUDA_KNOWN_FEATURES
 -------------------------
 
+.. versionadded:: 3.17
+
 List of CUDA features known to this version of CMake.
 
 The features listed in this global property may be known to be available to the
diff --git a/Help/prop_gbl/CMAKE_CXX_KNOWN_FEATURES.rst b/Help/prop_gbl/CMAKE_CXX_KNOWN_FEATURES.rst
index b921c6b..9b53282 100644
--- a/Help/prop_gbl/CMAKE_CXX_KNOWN_FEATURES.rst
+++ b/Help/prop_gbl/CMAKE_CXX_KNOWN_FEATURES.rst
@@ -1,6 +1,8 @@
 CMAKE_CXX_KNOWN_FEATURES
 ------------------------
 
+.. versionadded:: 3.1
+
 List of C++ features known to this version of CMake.
 
 The features listed in this global property may be known to be available to the
diff --git a/Help/prop_gbl/CMAKE_C_KNOWN_FEATURES.rst b/Help/prop_gbl/CMAKE_C_KNOWN_FEATURES.rst
index e5f896e..7166381 100644
--- a/Help/prop_gbl/CMAKE_C_KNOWN_FEATURES.rst
+++ b/Help/prop_gbl/CMAKE_C_KNOWN_FEATURES.rst
@@ -1,6 +1,8 @@
 CMAKE_C_KNOWN_FEATURES
 ----------------------
 
+.. versionadded:: 3.1
+
 List of C features known to this version of CMake.
 
 The features listed in this global property may be known to be available to the
diff --git a/Help/prop_gbl/CMAKE_ROLE.rst b/Help/prop_gbl/CMAKE_ROLE.rst
index 27512fa..3f4492f 100644
--- a/Help/prop_gbl/CMAKE_ROLE.rst
+++ b/Help/prop_gbl/CMAKE_ROLE.rst
@@ -1,6 +1,8 @@
 CMAKE_ROLE
 ----------
 
+.. versionadded:: 3.14
+
 Tells what mode the current running script is in. Could be one of several
 values:
 
diff --git a/Help/prop_gbl/ECLIPSE_EXTRA_CPROJECT_CONTENTS.rst b/Help/prop_gbl/ECLIPSE_EXTRA_CPROJECT_CONTENTS.rst
index 50c41a9..2f110a7 100644
--- a/Help/prop_gbl/ECLIPSE_EXTRA_CPROJECT_CONTENTS.rst
+++ b/Help/prop_gbl/ECLIPSE_EXTRA_CPROJECT_CONTENTS.rst
@@ -1,6 +1,8 @@
 ECLIPSE_EXTRA_CPROJECT_CONTENTS
 -------------------------------
 
+.. versionadded:: 3.12
+
 Additional contents to be inserted into the generated Eclipse cproject file.
 
 The cproject file defines the CDT specific information. Some third party IDE's
diff --git a/Help/prop_gbl/FIND_LIBRARY_USE_LIB32_PATHS.rst b/Help/prop_gbl/FIND_LIBRARY_USE_LIB32_PATHS.rst
index 8396026..f6cad66 100644
--- a/Help/prop_gbl/FIND_LIBRARY_USE_LIB32_PATHS.rst
+++ b/Help/prop_gbl/FIND_LIBRARY_USE_LIB32_PATHS.rst
@@ -1,6 +1,8 @@
 FIND_LIBRARY_USE_LIB32_PATHS
 ----------------------------
 
+.. versionadded:: 3.7
+
 Whether the :command:`find_library` command should automatically search
 ``lib32`` directories.
 
diff --git a/Help/prop_gbl/FIND_LIBRARY_USE_LIBX32_PATHS.rst b/Help/prop_gbl/FIND_LIBRARY_USE_LIBX32_PATHS.rst
index b87b09b..851f859 100644
--- a/Help/prop_gbl/FIND_LIBRARY_USE_LIBX32_PATHS.rst
+++ b/Help/prop_gbl/FIND_LIBRARY_USE_LIBX32_PATHS.rst
@@ -1,6 +1,8 @@
 FIND_LIBRARY_USE_LIBX32_PATHS
 -----------------------------
 
+.. versionadded:: 3.9
+
 Whether the :command:`find_library` command should automatically search
 ``libx32`` directories.
 
diff --git a/Help/prop_gbl/GENERATOR_IS_MULTI_CONFIG.rst b/Help/prop_gbl/GENERATOR_IS_MULTI_CONFIG.rst
index b8ec8a6..6f1a9e1 100644
--- a/Help/prop_gbl/GENERATOR_IS_MULTI_CONFIG.rst
+++ b/Help/prop_gbl/GENERATOR_IS_MULTI_CONFIG.rst
@@ -1,6 +1,8 @@
 GENERATOR_IS_MULTI_CONFIG
 -------------------------
 
+.. versionadded:: 3.9
+
 Read-only property that is true on multi-configuration generators.
 
 True when using a multi-configuration generator
diff --git a/Help/prop_gbl/TARGET_MESSAGES.rst b/Help/prop_gbl/TARGET_MESSAGES.rst
index 275b074..bb91772 100644
--- a/Help/prop_gbl/TARGET_MESSAGES.rst
+++ b/Help/prop_gbl/TARGET_MESSAGES.rst
@@ -1,6 +1,8 @@
 TARGET_MESSAGES
 ---------------
 
+.. versionadded:: 3.4
+
 Specify whether to report the completion of each target.
 
 This property specifies whether :ref:`Makefile Generators` should
diff --git a/Help/prop_gbl/XCODE_EMIT_EFFECTIVE_PLATFORM_NAME.rst b/Help/prop_gbl/XCODE_EMIT_EFFECTIVE_PLATFORM_NAME.rst
index 9500443..392b704 100644
--- a/Help/prop_gbl/XCODE_EMIT_EFFECTIVE_PLATFORM_NAME.rst
+++ b/Help/prop_gbl/XCODE_EMIT_EFFECTIVE_PLATFORM_NAME.rst
@@ -1,6 +1,8 @@
 XCODE_EMIT_EFFECTIVE_PLATFORM_NAME
 ----------------------------------
 
+.. versionadded:: 3.8
+
 Control emission of ``EFFECTIVE_PLATFORM_NAME`` by the :generator:`Xcode`
 generator.
 
diff --git a/Help/prop_inst/CPACK_DESKTOP_SHORTCUTS.rst b/Help/prop_inst/CPACK_DESKTOP_SHORTCUTS.rst
index 729ab60..55e9a20 100644
--- a/Help/prop_inst/CPACK_DESKTOP_SHORTCUTS.rst
+++ b/Help/prop_inst/CPACK_DESKTOP_SHORTCUTS.rst
@@ -1,6 +1,8 @@
 CPACK_DESKTOP_SHORTCUTS
 -----------------------
 
+.. versionadded:: 3.3
+
 Species a list of shortcut names that should be created on the `Desktop`
 for this file.
 
diff --git a/Help/prop_inst/CPACK_NEVER_OVERWRITE.rst b/Help/prop_inst/CPACK_NEVER_OVERWRITE.rst
index 4789e25..12eef9e 100644
--- a/Help/prop_inst/CPACK_NEVER_OVERWRITE.rst
+++ b/Help/prop_inst/CPACK_NEVER_OVERWRITE.rst
@@ -1,6 +1,8 @@
 CPACK_NEVER_OVERWRITE
 ---------------------
 
+.. versionadded:: 3.1
+
 Request that this file not be overwritten on install or reinstall.
 
 The property is currently only supported by the :cpack_gen:`CPack WIX Generator`.
diff --git a/Help/prop_inst/CPACK_PERMANENT.rst b/Help/prop_inst/CPACK_PERMANENT.rst
index 985de0d..e89c552 100644
--- a/Help/prop_inst/CPACK_PERMANENT.rst
+++ b/Help/prop_inst/CPACK_PERMANENT.rst
@@ -1,6 +1,8 @@
 CPACK_PERMANENT
 ---------------
 
+.. versionadded:: 3.1
+
 Request that this file not be removed on uninstall.
 
 The property is currently only supported by the :cpack_gen:`CPack WIX Generator`.
diff --git a/Help/prop_inst/CPACK_STARTUP_SHORTCUTS.rst b/Help/prop_inst/CPACK_STARTUP_SHORTCUTS.rst
index d9208b9..e896acd 100644
--- a/Help/prop_inst/CPACK_STARTUP_SHORTCUTS.rst
+++ b/Help/prop_inst/CPACK_STARTUP_SHORTCUTS.rst
@@ -1,6 +1,8 @@
 CPACK_STARTUP_SHORTCUTS
 -----------------------
 
+.. versionadded:: 3.3
+
 Species a list of shortcut names that should be created in the `Startup` folder
 for this file.
 
diff --git a/Help/prop_inst/CPACK_START_MENU_SHORTCUTS.rst b/Help/prop_inst/CPACK_START_MENU_SHORTCUTS.rst
index 092334a..fb8807f 100644
--- a/Help/prop_inst/CPACK_START_MENU_SHORTCUTS.rst
+++ b/Help/prop_inst/CPACK_START_MENU_SHORTCUTS.rst
@@ -1,6 +1,8 @@
 CPACK_START_MENU_SHORTCUTS
 --------------------------
 
+.. versionadded:: 3.3
+
 Species a list of shortcut names that should be created in the `Start Menu`
 for this file.
 
diff --git a/Help/prop_inst/CPACK_WIX_ACL.rst b/Help/prop_inst/CPACK_WIX_ACL.rst
index c88f426..8b4fb5c 100644
--- a/Help/prop_inst/CPACK_WIX_ACL.rst
+++ b/Help/prop_inst/CPACK_WIX_ACL.rst
@@ -1,6 +1,8 @@
 CPACK_WIX_ACL
 -------------
 
+.. versionadded:: 3.1
+
 Specifies access permissions for files or directories
 installed by a WiX installer.
 
diff --git a/Help/prop_sf/COMPILE_OPTIONS.rst b/Help/prop_sf/COMPILE_OPTIONS.rst
index 7e48271..a694c3e 100644
--- a/Help/prop_sf/COMPILE_OPTIONS.rst
+++ b/Help/prop_sf/COMPILE_OPTIONS.rst
@@ -1,13 +1,13 @@
 COMPILE_OPTIONS
 ---------------
 
+.. versionadded:: 3.11
+
 List of additional options to pass to the compiler.
 
 This property holds a :ref:`semicolon-separated list <CMake Language Lists>` of options
 and will be added to the list of compile flags when this
-source file builds.  Use :prop_sf:`COMPILE_DEFINITIONS` to pass
-additional preprocessor definitions and :prop_sf:`INCLUDE_DIRECTORIES` to pass
-additional include directories.
+source file builds.
 
 Contents of ``COMPILE_OPTIONS`` may use "generator expressions" with the
 syntax ``$<...>``.  See the :manual:`cmake-generator-expressions(7)` manual
@@ -16,6 +16,19 @@
 that depend on the build configuration are not allowed with that
 generator.
 
-.. note::
+Usage example:
 
-  This property should be preferred over the :prop_sf:`COMPILE_FLAGS` property.
+.. code-block:: cmake
+
+  set_source_files_properties(foo.cpp PROPERTIES COMPILE_OPTIONS "-Wno-unused-parameter;-Wno-missing-field-initializer")
+
+Related properties:
+
+* Prefer this property over :prop_sf:`COMPILE_FLAGS`.
+* Use :prop_sf:`COMPILE_DEFINITIONS` to pass additional preprocessor definitions.
+* Use :prop_sf:`INCLUDE_DIRECTORIES` to pass additional include directories.
+
+Related commands:
+
+* :command:`add_compile_options` for directory-wide settings
+* :command:`target_compile_options` for target-specific settings
diff --git a/Help/prop_sf/Fortran_FORMAT.rst b/Help/prop_sf/Fortran_FORMAT.rst
index 1cbbf48..ef33926 100644
--- a/Help/prop_sf/Fortran_FORMAT.rst
+++ b/Help/prop_sf/Fortran_FORMAT.rst
@@ -4,7 +4,9 @@
 Set to ``FIXED`` or ``FREE`` to indicate the Fortran source layout.
 
 This property tells CMake whether a given Fortran source file uses
-fixed-format or free-format.  CMake will pass the corresponding format
-flag to the compiler.  Consider using the target-wide
-:prop_tgt:`Fortran_FORMAT` property if all source files in a target
-share the same format.
+fixed-format or free-format.  CMake will pass the corresponding format flag
+to the compiler.  Consider using the target-wide :prop_tgt:`Fortran_FORMAT`
+property if all source files in a target share the same format.
+
+.. note:: For some compilers, ``NAG``, ``PGI`` and ``Solaris Studio``,
+          setting this to ``OFF`` will have no effect.
diff --git a/Help/prop_sf/Fortran_PREPROCESS.rst b/Help/prop_sf/Fortran_PREPROCESS.rst
new file mode 100644
index 0000000..548a97b
--- /dev/null
+++ b/Help/prop_sf/Fortran_PREPROCESS.rst
@@ -0,0 +1,19 @@
+Fortran_PREPROCESS
+------------------
+
+.. versionadded:: 3.18
+
+Control whether the Fortran source file should be unconditionally preprocessed.
+
+If unset or empty, rely on the compiler to determine whether the file
+should be preprocessed. If explicitly set to ``OFF`` then the file
+does not need to be preprocessed. If explicitly set to ``ON``, then
+the file does need to be preprocessed as part of the compilation step.
+
+When using the :generator:`Ninja` generator, all source files are
+first preprocessed in order to generate module dependency
+information. Setting this property to ``OFF`` will make ``Ninja``
+skip this step.
+
+Consider using the target-wide :prop_tgt:`Fortran_PREPROCESS` property
+if all source files in a target need to be preprocessed.
diff --git a/Help/prop_sf/INCLUDE_DIRECTORIES.rst b/Help/prop_sf/INCLUDE_DIRECTORIES.rst
index 23de70e..89ffd15 100644
--- a/Help/prop_sf/INCLUDE_DIRECTORIES.rst
+++ b/Help/prop_sf/INCLUDE_DIRECTORIES.rst
@@ -1,6 +1,8 @@
 INCLUDE_DIRECTORIES
 -------------------
 
+.. versionadded:: 3.11
+
 List of preprocessor include file search directories.
 
 This property holds a :ref:`semicolon-separated list <CMake Language Lists>` of paths
diff --git a/Help/prop_sf/OBJECT_OUTPUTS.rst b/Help/prop_sf/OBJECT_OUTPUTS.rst
index e7e880b..3e799ed 100644
--- a/Help/prop_sf/OBJECT_OUTPUTS.rst
+++ b/Help/prop_sf/OBJECT_OUTPUTS.rst
@@ -7,3 +7,6 @@
 of these outputs is missing the object will be recompiled.  This is
 supported only on the :generator:`Ninja` and :ref:`Makefile Generators`
 and will be ignored on other generators.
+
+This property supports
+:manual:`generator expressions <cmake-generator-expressions(7)>`.
diff --git a/Help/prop_sf/SKIP_AUTOGEN.rst b/Help/prop_sf/SKIP_AUTOGEN.rst
index f31185a..2173f59 100644
--- a/Help/prop_sf/SKIP_AUTOGEN.rst
+++ b/Help/prop_sf/SKIP_AUTOGEN.rst
@@ -1,6 +1,8 @@
 SKIP_AUTOGEN
 ------------
 
+.. versionadded:: 3.8
+
 Exclude the source file from :prop_tgt:`AUTOMOC`, :prop_tgt:`AUTOUIC` and
 :prop_tgt:`AUTORCC` processing (for Qt projects).
 
diff --git a/Help/prop_sf/SKIP_AUTOMOC.rst b/Help/prop_sf/SKIP_AUTOMOC.rst
index a929448..e92cfe0 100644
--- a/Help/prop_sf/SKIP_AUTOMOC.rst
+++ b/Help/prop_sf/SKIP_AUTOMOC.rst
@@ -1,6 +1,8 @@
 SKIP_AUTOMOC
 ------------
 
+.. versionadded:: 3.8
+
 Exclude the source file from :prop_tgt:`AUTOMOC` processing (for Qt projects).
 
 For broader exclusion control see :prop_sf:`SKIP_AUTOGEN`.
diff --git a/Help/prop_sf/SKIP_AUTORCC.rst b/Help/prop_sf/SKIP_AUTORCC.rst
index bccccfc..2829c25 100644
--- a/Help/prop_sf/SKIP_AUTORCC.rst
+++ b/Help/prop_sf/SKIP_AUTORCC.rst
@@ -1,6 +1,8 @@
 SKIP_AUTORCC
 ------------
 
+.. versionadded:: 3.8
+
 Exclude the source file from :prop_tgt:`AUTORCC` processing (for Qt projects).
 
 For broader exclusion control see :prop_sf:`SKIP_AUTOGEN`.
diff --git a/Help/prop_sf/SKIP_AUTOUIC.rst b/Help/prop_sf/SKIP_AUTOUIC.rst
index 8c962db..ae9725a 100644
--- a/Help/prop_sf/SKIP_AUTOUIC.rst
+++ b/Help/prop_sf/SKIP_AUTOUIC.rst
@@ -1,6 +1,8 @@
 SKIP_AUTOUIC
 ------------
 
+.. versionadded:: 3.8
+
 Exclude the source file from :prop_tgt:`AUTOUIC` processing (for Qt projects).
 
 :prop_sf:`SKIP_AUTOUIC` can be set on C++ header and source files and on
diff --git a/Help/prop_sf/SKIP_PRECOMPILE_HEADERS.rst b/Help/prop_sf/SKIP_PRECOMPILE_HEADERS.rst
index 0031da3..660de3f 100644
--- a/Help/prop_sf/SKIP_PRECOMPILE_HEADERS.rst
+++ b/Help/prop_sf/SKIP_PRECOMPILE_HEADERS.rst
@@ -1,6 +1,8 @@
 SKIP_PRECOMPILE_HEADERS
 -----------------------
 
+.. versionadded:: 3.16
+
 Is this source file skipped by :prop_tgt:`PRECOMPILE_HEADERS` feature.
 
 This property helps with build problems that one would run into
diff --git a/Help/prop_sf/SKIP_UNITY_BUILD_INCLUSION.rst b/Help/prop_sf/SKIP_UNITY_BUILD_INCLUSION.rst
index 6d1e60d..ae526ac 100644
--- a/Help/prop_sf/SKIP_UNITY_BUILD_INCLUSION.rst
+++ b/Help/prop_sf/SKIP_UNITY_BUILD_INCLUSION.rst
@@ -1,6 +1,8 @@
 SKIP_UNITY_BUILD_INCLUSION
 --------------------------
 
+.. versionadded:: 3.16
+
 Setting this property to true ensures the source file will be skipped by
 unity builds when its associated target has its :prop_tgt:`UNITY_BUILD`
 property set to true.  The source file will instead be compiled on its own
diff --git a/Help/prop_sf/Swift_DEPENDENCIES_FILE.rst b/Help/prop_sf/Swift_DEPENDENCIES_FILE.rst
index faac2df..a90c7eb 100644
--- a/Help/prop_sf/Swift_DEPENDENCIES_FILE.rst
+++ b/Help/prop_sf/Swift_DEPENDENCIES_FILE.rst
@@ -1,5 +1,7 @@
 Swift_DEPENDENCIES_FILE
 -----------------------
 
+.. versionadded:: 3.15
+
 This property sets the path for the Swift dependency file (swiftdeps) for the
 source.  If one is not specified, it will default to ``<OBJECT>.swiftdeps``.
diff --git a/Help/prop_sf/Swift_DIAGNOSTICS_FILE.rst b/Help/prop_sf/Swift_DIAGNOSTICS_FILE.rst
index 5bf5d59..47d5ac3 100644
--- a/Help/prop_sf/Swift_DIAGNOSTICS_FILE.rst
+++ b/Help/prop_sf/Swift_DIAGNOSTICS_FILE.rst
@@ -1,4 +1,6 @@
 Swift_DIAGNOSTICS_FILE
 ----------------------
 
+.. versionadded:: 3.15
+
 This property controls where the Swift diagnostics are serialized.
diff --git a/Help/prop_sf/UNITY_GROUP.rst b/Help/prop_sf/UNITY_GROUP.rst
new file mode 100644
index 0000000..9c18b70
--- /dev/null
+++ b/Help/prop_sf/UNITY_GROUP.rst
@@ -0,0 +1,7 @@
+UNITY_GROUP
+-----------
+
+.. versionadded:: 3.18
+
+This property controls which *bucket* the source will be part of when
+the :prop_tgt:`UNITY_BUILD_MODE` is set to ``GROUP``.
diff --git a/Help/prop_sf/VS_COPY_TO_OUT_DIR.rst b/Help/prop_sf/VS_COPY_TO_OUT_DIR.rst
index 16c8d83..ebc3061 100644
--- a/Help/prop_sf/VS_COPY_TO_OUT_DIR.rst
+++ b/Help/prop_sf/VS_COPY_TO_OUT_DIR.rst
@@ -1,6 +1,8 @@
 VS_COPY_TO_OUT_DIR
 ------------------
 
+.. versionadded:: 3.8
+
 Sets the ``<CopyToOutputDirectory>`` tag for a source file in a
 Visual Studio project file. Valid values are ``Never``, ``Always``
 and ``PreserveNewest``.
diff --git a/Help/prop_sf/VS_CSHARP_tagname.rst b/Help/prop_sf/VS_CSHARP_tagname.rst
index 91c4a06..75720f8 100644
--- a/Help/prop_sf/VS_CSHARP_tagname.rst
+++ b/Help/prop_sf/VS_CSHARP_tagname.rst
@@ -1,6 +1,8 @@
 VS_CSHARP_<tagname>
 -------------------
 
+.. versionadded:: 3.8
+
 Visual Studio and CSharp source-file-specific configuration.
 
 Tell the :manual:`Visual Studio generators <cmake-generators(7)>`
diff --git a/Help/prop_sf/VS_DEPLOYMENT_CONTENT.rst b/Help/prop_sf/VS_DEPLOYMENT_CONTENT.rst
index 6a38478..ee49b27 100644
--- a/Help/prop_sf/VS_DEPLOYMENT_CONTENT.rst
+++ b/Help/prop_sf/VS_DEPLOYMENT_CONTENT.rst
@@ -1,6 +1,8 @@
 VS_DEPLOYMENT_CONTENT
 ---------------------
 
+.. versionadded:: 3.1
+
 Mark a source file as content for deployment with a Windows Phone or
 Windows Store application when built with a
 :manual:`Visual Studio generators <cmake-generators(7)>`.
diff --git a/Help/prop_sf/VS_DEPLOYMENT_LOCATION.rst b/Help/prop_sf/VS_DEPLOYMENT_LOCATION.rst
index 2ce22fc..b170544 100644
--- a/Help/prop_sf/VS_DEPLOYMENT_LOCATION.rst
+++ b/Help/prop_sf/VS_DEPLOYMENT_LOCATION.rst
@@ -1,6 +1,8 @@
 VS_DEPLOYMENT_LOCATION
 ----------------------
 
+.. versionadded:: 3.1
+
 Specifies the deployment location for a content source file with a Windows
 Phone or Windows Store application when built
 with a :manual:`Visual Studio generators <cmake-generators(7)>`.
diff --git a/Help/prop_sf/VS_INCLUDE_IN_VSIX.rst b/Help/prop_sf/VS_INCLUDE_IN_VSIX.rst
index db470ef..16c56bf 100644
--- a/Help/prop_sf/VS_INCLUDE_IN_VSIX.rst
+++ b/Help/prop_sf/VS_INCLUDE_IN_VSIX.rst
@@ -1,6 +1,8 @@
 VS_INCLUDE_IN_VSIX
 ------------------
 
+.. versionadded:: 3.8
+
 Boolean property to specify if the file should be included within a
 VSIX (Visual Studio Integration Extension) extension package.
 This is needed for development of Visual Studio extensions.
diff --git a/Help/prop_sf/VS_RESOURCE_GENERATOR.rst b/Help/prop_sf/VS_RESOURCE_GENERATOR.rst
index 97e5aac..c5bb4f6 100644
--- a/Help/prop_sf/VS_RESOURCE_GENERATOR.rst
+++ b/Help/prop_sf/VS_RESOURCE_GENERATOR.rst
@@ -1,6 +1,8 @@
 VS_RESOURCE_GENERATOR
 ---------------------
 
+.. versionadded:: 3.8
+
 This property allows to specify the resource generator to be used
 on this file. It defaults to ``PublicResXFileCodeGenerator`` if
 not set.
diff --git a/Help/prop_sf/VS_SETTINGS.rst b/Help/prop_sf/VS_SETTINGS.rst
new file mode 100644
index 0000000..322f5a6
--- /dev/null
+++ b/Help/prop_sf/VS_SETTINGS.rst
@@ -0,0 +1,20 @@
+VS_SETTINGS
+-----------
+
+.. versionadded:: 3.18
+
+Set any item metadata on a non-built file.
+
+Takes a list of ``Key=Value`` pairs. Tells the Visual Studio generator to set
+``Key`` to ``Value`` as item metadata on the file.
+
+For example:
+
+.. code-block:: cmake
+
+  set_property(SOURCE file.hlsl PROPERTY VS_SETTINGS "Key=Value" "Key2=Value2")
+
+will set ``Key`` to ``Value`` and ``Key2`` to ``Value2`` on the
+``file.hlsl`` item as metadata.
+
+:manual:`Generator expressions <cmake-generator-expressions(7)>` are supported.
diff --git a/Help/prop_sf/VS_SHADER_DISABLE_OPTIMIZATIONS.rst b/Help/prop_sf/VS_SHADER_DISABLE_OPTIMIZATIONS.rst
index 446dd26..6fb6778 100644
--- a/Help/prop_sf/VS_SHADER_DISABLE_OPTIMIZATIONS.rst
+++ b/Help/prop_sf/VS_SHADER_DISABLE_OPTIMIZATIONS.rst
@@ -1,6 +1,8 @@
 VS_SHADER_DISABLE_OPTIMIZATIONS
 -------------------------------
 
+.. versionadded:: 3.11
+
 Disable compiler optimizations for an ``.hlsl`` source file.  This adds the
 ``-Od`` flag to the command line for the FxCompiler tool.  Specify the value
 ``true`` for this property to disable compiler optimizations.
diff --git a/Help/prop_sf/VS_SHADER_ENABLE_DEBUG.rst b/Help/prop_sf/VS_SHADER_ENABLE_DEBUG.rst
index c0e60a3..9c8f9d7 100644
--- a/Help/prop_sf/VS_SHADER_ENABLE_DEBUG.rst
+++ b/Help/prop_sf/VS_SHADER_ENABLE_DEBUG.rst
@@ -1,6 +1,8 @@
 VS_SHADER_ENABLE_DEBUG
 ----------------------
 
+.. versionadded:: 3.11
+
 Enable debugging information for an ``.hlsl`` source file.  This adds the
 ``-Zi`` flag to the command line for the FxCompiler tool.  Specify the value
 ``true`` to generate debugging information for the compiled shader.
diff --git a/Help/prop_sf/VS_SHADER_ENTRYPOINT.rst b/Help/prop_sf/VS_SHADER_ENTRYPOINT.rst
index fe3471f..4b311ba 100644
--- a/Help/prop_sf/VS_SHADER_ENTRYPOINT.rst
+++ b/Help/prop_sf/VS_SHADER_ENTRYPOINT.rst
@@ -1,5 +1,7 @@
 VS_SHADER_ENTRYPOINT
 --------------------
 
+.. versionadded:: 3.1
+
 Specifies the name of the entry point for the shader of a ``.hlsl`` source
 file.
diff --git a/Help/prop_sf/VS_SHADER_FLAGS.rst b/Help/prop_sf/VS_SHADER_FLAGS.rst
index 0a53afd..07f8497 100644
--- a/Help/prop_sf/VS_SHADER_FLAGS.rst
+++ b/Help/prop_sf/VS_SHADER_FLAGS.rst
@@ -1,4 +1,6 @@
 VS_SHADER_FLAGS
 ---------------
 
+.. versionadded:: 3.2
+
 Set additional Visual Studio shader flags of a ``.hlsl`` source file.
diff --git a/Help/prop_sf/VS_SHADER_MODEL.rst b/Help/prop_sf/VS_SHADER_MODEL.rst
index b1cf0df..072df89 100644
--- a/Help/prop_sf/VS_SHADER_MODEL.rst
+++ b/Help/prop_sf/VS_SHADER_MODEL.rst
@@ -1,5 +1,7 @@
 VS_SHADER_MODEL
 ---------------
 
+.. versionadded:: 3.1
+
 Specifies the shader model of a ``.hlsl`` source file. Some shader types can
 only be used with recent shader models
diff --git a/Help/prop_sf/VS_SHADER_OBJECT_FILE_NAME.rst b/Help/prop_sf/VS_SHADER_OBJECT_FILE_NAME.rst
index 093bcc6..3647a5e 100644
--- a/Help/prop_sf/VS_SHADER_OBJECT_FILE_NAME.rst
+++ b/Help/prop_sf/VS_SHADER_OBJECT_FILE_NAME.rst
@@ -1,6 +1,8 @@
 VS_SHADER_OBJECT_FILE_NAME
 --------------------------
 
+.. versionadded:: 3.12
+
 Specifies a file name for the compiled shader object file for an ``.hlsl``
 source file.  This adds the ``-Fo`` flag to the command line for the FxCompiler
 tool.
diff --git a/Help/prop_sf/VS_SHADER_OUTPUT_HEADER_FILE.rst b/Help/prop_sf/VS_SHADER_OUTPUT_HEADER_FILE.rst
index e6763d3..4113a16 100644
--- a/Help/prop_sf/VS_SHADER_OUTPUT_HEADER_FILE.rst
+++ b/Help/prop_sf/VS_SHADER_OUTPUT_HEADER_FILE.rst
@@ -1,5 +1,7 @@
 VS_SHADER_OUTPUT_HEADER_FILE
 ----------------------------
 
+.. versionadded:: 3.10
+
 Set filename for output header file containing object code of a ``.hlsl``
 source file.
diff --git a/Help/prop_sf/VS_SHADER_TYPE.rst b/Help/prop_sf/VS_SHADER_TYPE.rst
index f104837..3fb7e60 100644
--- a/Help/prop_sf/VS_SHADER_TYPE.rst
+++ b/Help/prop_sf/VS_SHADER_TYPE.rst
@@ -1,4 +1,6 @@
 VS_SHADER_TYPE
 --------------
 
+.. versionadded:: 3.1
+
 Set the Visual Studio shader type of a ``.hlsl`` source file.
diff --git a/Help/prop_sf/VS_SHADER_VARIABLE_NAME.rst b/Help/prop_sf/VS_SHADER_VARIABLE_NAME.rst
index 1a5e369..3361b40 100644
--- a/Help/prop_sf/VS_SHADER_VARIABLE_NAME.rst
+++ b/Help/prop_sf/VS_SHADER_VARIABLE_NAME.rst
@@ -1,5 +1,7 @@
 VS_SHADER_VARIABLE_NAME
 -----------------------
 
+.. versionadded:: 3.10
+
 Set name of variable in header file containing object code of a ``.hlsl``
 source file.
diff --git a/Help/prop_sf/VS_TOOL_OVERRIDE.rst b/Help/prop_sf/VS_TOOL_OVERRIDE.rst
index 8bdc5ca..b2f4112 100644
--- a/Help/prop_sf/VS_TOOL_OVERRIDE.rst
+++ b/Help/prop_sf/VS_TOOL_OVERRIDE.rst
@@ -1,5 +1,7 @@
 VS_TOOL_OVERRIDE
 ----------------
 
+.. versionadded:: 3.7
+
 Override the default Visual Studio tool that will be applied to the source file
 with a new tool not based on the extension of the file.
diff --git a/Help/prop_sf/VS_XAML_TYPE.rst b/Help/prop_sf/VS_XAML_TYPE.rst
index 1a274ba..612b07b 100644
--- a/Help/prop_sf/VS_XAML_TYPE.rst
+++ b/Help/prop_sf/VS_XAML_TYPE.rst
@@ -1,6 +1,8 @@
 VS_XAML_TYPE
 ------------
 
+.. versionadded:: 3.3
+
 Mark a Extensible Application Markup Language (XAML) source file
 as a different type than the default ``Page``.
 The most common usage would be to set the default ``App.xaml`` file as
diff --git a/Help/prop_sf/XCODE_EXPLICIT_FILE_TYPE.rst b/Help/prop_sf/XCODE_EXPLICIT_FILE_TYPE.rst
index b8cf946..5a50d7d 100644
--- a/Help/prop_sf/XCODE_EXPLICIT_FILE_TYPE.rst
+++ b/Help/prop_sf/XCODE_EXPLICIT_FILE_TYPE.rst
@@ -1,6 +1,8 @@
 XCODE_EXPLICIT_FILE_TYPE
 ------------------------
 
+.. versionadded:: 3.1
+
 Set the :generator:`Xcode` ``explicitFileType`` attribute on its reference to a
 source file.  CMake computes a default based on file extension but
 can be told explicitly with this property.
diff --git a/Help/prop_sf/XCODE_FILE_ATTRIBUTES.rst b/Help/prop_sf/XCODE_FILE_ATTRIBUTES.rst
index 4c93f44..ba51e00 100644
--- a/Help/prop_sf/XCODE_FILE_ATTRIBUTES.rst
+++ b/Help/prop_sf/XCODE_FILE_ATTRIBUTES.rst
@@ -1,6 +1,8 @@
 XCODE_FILE_ATTRIBUTES
 ---------------------
 
+.. versionadded:: 3.7
+
 Add values to the :generator:`Xcode` ``ATTRIBUTES`` setting on its reference to a
 source file.  Among other things, this can be used to set the role on
 a ``.mig`` file::
diff --git a/Help/prop_sf/XCODE_LAST_KNOWN_FILE_TYPE.rst b/Help/prop_sf/XCODE_LAST_KNOWN_FILE_TYPE.rst
index b21891f..0b84e31 100644
--- a/Help/prop_sf/XCODE_LAST_KNOWN_FILE_TYPE.rst
+++ b/Help/prop_sf/XCODE_LAST_KNOWN_FILE_TYPE.rst
@@ -1,6 +1,8 @@
 XCODE_LAST_KNOWN_FILE_TYPE
 --------------------------
 
+.. versionadded:: 3.1
+
 Set the :generator:`Xcode` ``lastKnownFileType`` attribute on its reference to
 a source file.  CMake computes a default based on file extension but
 can be told explicitly with this property.
diff --git a/Help/prop_test/DEPENDS.rst b/Help/prop_test/DEPENDS.rst
index 89c7553..5aa36b4 100644
--- a/Help/prop_test/DEPENDS.rst
+++ b/Help/prop_test/DEPENDS.rst
@@ -8,3 +8,15 @@
 purely for order of execution (i.e. it is really just a *run after*
 relationship). Consider using test fixtures with setup tests if a dependency
 with successful completion is required (see :prop_test:`FIXTURES_REQUIRED`).
+
+Examples
+~~~~~~~~
+
+.. code-block:: cmake
+
+  add_test(NAME baseTest1 ...)
+  add_test(NAME baseTest2 ...)
+  add_test(NAME dependsTest12 ...)
+
+  set_tests_properties(dependsTest12 PROPERTIES DEPENDS "baseTest1;baseTest2")
+  # dependsTest12 runs after baseTest1 and baseTest2, even if they fail
diff --git a/Help/prop_test/DISABLED.rst b/Help/prop_test/DISABLED.rst
index 1d469e8..cbf07a5 100644
--- a/Help/prop_test/DISABLED.rst
+++ b/Help/prop_test/DISABLED.rst
@@ -1,6 +1,8 @@
 DISABLED
 --------
 
+.. versionadded:: 3.9
+
 If set to ``True``, the test will be skipped and its status will be 'Not Run'. A
 ``DISABLED`` test will not be counted in the total number of tests and its
 completion status will be reported to CDash as ``Disabled``.
diff --git a/Help/prop_test/FIXTURES_CLEANUP.rst b/Help/prop_test/FIXTURES_CLEANUP.rst
index 3075b4d..aa043da 100644
--- a/Help/prop_test/FIXTURES_CLEANUP.rst
+++ b/Help/prop_test/FIXTURES_CLEANUP.rst
@@ -1,6 +1,8 @@
 FIXTURES_CLEANUP
 ----------------
 
+.. versionadded:: 3.7
+
 Specifies a list of fixtures for which the test is to be treated as a cleanup
 test. These fixture names are distinct from test case names and are not
 required to have any similarity to the names of tests associated with them.
diff --git a/Help/prop_test/FIXTURES_REQUIRED.rst b/Help/prop_test/FIXTURES_REQUIRED.rst
index e3f60c4..d92808a 100644
--- a/Help/prop_test/FIXTURES_REQUIRED.rst
+++ b/Help/prop_test/FIXTURES_REQUIRED.rst
@@ -1,6 +1,8 @@
 FIXTURES_REQUIRED
 -----------------
 
+.. versionadded:: 3.7
+
 Specifies a list of fixtures the test requires. Fixture names are case
 sensitive and they are not required to have any similarity to test names.
 
diff --git a/Help/prop_test/FIXTURES_SETUP.rst b/Help/prop_test/FIXTURES_SETUP.rst
index fdb21cc..04a09d8 100644
--- a/Help/prop_test/FIXTURES_SETUP.rst
+++ b/Help/prop_test/FIXTURES_SETUP.rst
@@ -1,6 +1,8 @@
 FIXTURES_SETUP
 --------------
 
+.. versionadded:: 3.7
+
 Specifies a list of fixtures for which the test is to be treated as a setup
 test. These fixture names are distinct from test case names and are not
 required to have any similarity to the names of tests associated with them.
diff --git a/Help/prop_test/PROCESSOR_AFFINITY.rst b/Help/prop_test/PROCESSOR_AFFINITY.rst
index 38ec179..f48a69c 100644
--- a/Help/prop_test/PROCESSOR_AFFINITY.rst
+++ b/Help/prop_test/PROCESSOR_AFFINITY.rst
@@ -1,6 +1,8 @@
 PROCESSOR_AFFINITY
 ------------------
 
+.. versionadded:: 3.12
+
 Set to a true value to ask CTest to launch the test process with CPU affinity
 for a fixed set of processors.  If enabled and supported for the current
 platform, CTest will choose a set of processors to place in the CPU affinity
diff --git a/Help/prop_test/REQUIRED_FILES.rst b/Help/prop_test/REQUIRED_FILES.rst
index fac357c..baf209c 100644
--- a/Help/prop_test/REQUIRED_FILES.rst
+++ b/Help/prop_test/REQUIRED_FILES.rst
@@ -1,7 +1,38 @@
 REQUIRED_FILES
 --------------
 
-List of files required to run the test.
+List of files required to run the test.  The filenames are relative to the
+test :prop_test:`WORKING_DIRECTORY` unless an absolute path is specified.
 
 If set to a list of files, the test will not be run unless all of the
 files exist.
+
+Examples
+~~~~~~~~
+
+Suppose that ``test.txt`` is created by test ``baseTest`` and ``none.txt``
+does not exist:
+
+.. code-block:: cmake
+
+  add_test(NAME baseTest ...)   # Assumed to create test.txt
+  add_test(NAME fileTest ...)
+
+  # The following ensures that if baseTest is successful, test.txt will
+  # have been created before fileTest is run
+  set_tests_properties(fileTest PROPERTIES
+    DEPENDS baseTest
+    REQUIRED_FILES test.txt
+  )
+
+  add_test(NAME notRunTest ...)
+
+  # The following makes notRunTest depend on two files. Nothing creates
+  # the none.txt file, so notRunTest will fail with status "Not Run".
+  set_tests_properties(notRunTest PROPERTIES
+    REQUIRED_FILES "test.txt;none.txt"
+  )
+
+The above example demonstrates how ``REQUIRED_FILES`` works, but it is not the
+most robust way to implement test ordering with failure detection.  For that,
+test fixtures are a better alternative (see :prop_test:`FIXTURES_REQUIRED`).
diff --git a/Help/prop_test/RESOURCE_GROUPS.rst b/Help/prop_test/RESOURCE_GROUPS.rst
index 63c56ce..26c8fa2 100644
--- a/Help/prop_test/RESOURCE_GROUPS.rst
+++ b/Help/prop_test/RESOURCE_GROUPS.rst
@@ -1,6 +1,8 @@
 RESOURCE_GROUPS
 ---------------
 
+.. versionadded:: 3.16
+
 Specify resources required by a test, grouped in a way that is meaningful to
 the test.  See :ref:`resource allocation <ctest-resource-allocation>`
 for more information on how this property integrates into the CTest resource
diff --git a/Help/prop_test/SKIP_REGULAR_EXPRESSION.rst b/Help/prop_test/SKIP_REGULAR_EXPRESSION.rst
index 2c6d980..46c4363 100644
--- a/Help/prop_test/SKIP_REGULAR_EXPRESSION.rst
+++ b/Help/prop_test/SKIP_REGULAR_EXPRESSION.rst
@@ -1,6 +1,8 @@
 SKIP_REGULAR_EXPRESSION
 -----------------------
 
+.. versionadded:: 3.16
+
 If the output matches this regular expression the test will be marked as skipped.
 
 If set, if the output matches one of specified regular expressions,
diff --git a/Help/prop_test/TIMEOUT_AFTER_MATCH.rst b/Help/prop_test/TIMEOUT_AFTER_MATCH.rst
index d607992..726dcab 100644
--- a/Help/prop_test/TIMEOUT_AFTER_MATCH.rst
+++ b/Help/prop_test/TIMEOUT_AFTER_MATCH.rst
@@ -1,6 +1,8 @@
 TIMEOUT_AFTER_MATCH
 -------------------
 
+.. versionadded:: 3.6
+
 Change a test's timeout duration after a matching line is encountered
 in its output.
 
diff --git a/Help/prop_tgt/ADDITIONAL_CLEAN_FILES.rst b/Help/prop_tgt/ADDITIONAL_CLEAN_FILES.rst
index 3b9d965..dc87d23 100644
--- a/Help/prop_tgt/ADDITIONAL_CLEAN_FILES.rst
+++ b/Help/prop_tgt/ADDITIONAL_CLEAN_FILES.rst
@@ -1,6 +1,8 @@
 ADDITIONAL_CLEAN_FILES
 ----------------------
 
+.. versionadded:: 3.15
+
 A :ref:`;-list <CMake Language Lists>` of files or directories that will be
 removed as a part of the global ``clean`` target.  It can be used to specify
 files and directories that are generated as part of building the target or
diff --git a/Help/prop_tgt/AIX_EXPORT_ALL_SYMBOLS.rst b/Help/prop_tgt/AIX_EXPORT_ALL_SYMBOLS.rst
index 15ddc0b..de98fdf 100644
--- a/Help/prop_tgt/AIX_EXPORT_ALL_SYMBOLS.rst
+++ b/Help/prop_tgt/AIX_EXPORT_ALL_SYMBOLS.rst
@@ -1,6 +1,8 @@
 AIX_EXPORT_ALL_SYMBOLS
 ----------------------
 
+.. versionadded:: 3.17
+
 On AIX, CMake automatically exports all symbols from shared libraries, and
 from executables with the :prop_tgt:`ENABLE_EXPORTS` target property set.
 Explicitly disable this boolean property to suppress the behavior and
diff --git a/Help/prop_tgt/ALIAS_GLOBAL.rst b/Help/prop_tgt/ALIAS_GLOBAL.rst
new file mode 100644
index 0000000..a8859c6
--- /dev/null
+++ b/Help/prop_tgt/ALIAS_GLOBAL.rst
@@ -0,0 +1,19 @@
+ALIAS_GLOBAL
+------------
+
+.. versionadded:: 3.18
+
+Read-only property indicating of whether an :ref:`ALIAS target <Alias Targets>`
+is globally visible.
+
+The boolean value of this property is ``TRUE`` for aliases to
+:ref:`IMPORTED targets <Imported Targets>` created
+with the ``GLOBAL`` options to :command:`add_executable()` or
+:command:`add_library()`, ``FALSE`` otherwise. It is undefined for
+targets built within the project.
+
+.. note::
+
+  Promoting an :ref:`IMPORTED target <Imported Targets>` from ``LOCAL``
+  to ``GLOBAL`` scope by changing the value or :prop_tgt:`IMPORTED_GLOBAL`
+  target property do not change the scope of local aliases.
diff --git a/Help/prop_tgt/ANDROID_ANT_ADDITIONAL_OPTIONS.rst b/Help/prop_tgt/ANDROID_ANT_ADDITIONAL_OPTIONS.rst
index af6b405..eceb17d 100644
--- a/Help/prop_tgt/ANDROID_ANT_ADDITIONAL_OPTIONS.rst
+++ b/Help/prop_tgt/ANDROID_ANT_ADDITIONAL_OPTIONS.rst
@@ -1,6 +1,8 @@
 ANDROID_ANT_ADDITIONAL_OPTIONS
 ------------------------------
 
+.. versionadded:: 3.4
+
 Set the additional options for Android Ant build system. This is
 a string value containing all command line options for the Ant build.
 This property is initialized by the value of the
diff --git a/Help/prop_tgt/ANDROID_API.rst b/Help/prop_tgt/ANDROID_API.rst
index 63464d7..7664f18 100644
--- a/Help/prop_tgt/ANDROID_API.rst
+++ b/Help/prop_tgt/ANDROID_API.rst
@@ -1,6 +1,8 @@
 ANDROID_API
 -----------
 
+.. versionadded:: 3.1
+
 When :ref:`Cross Compiling for Android with NVIDIA Nsight Tegra Visual Studio
 Edition`, this property sets the Android target API version (e.g. ``15``).
 The version number must be a positive decimal integer.  This property is
diff --git a/Help/prop_tgt/ANDROID_API_MIN.rst b/Help/prop_tgt/ANDROID_API_MIN.rst
index 773ab3f..7ca2455 100644
--- a/Help/prop_tgt/ANDROID_API_MIN.rst
+++ b/Help/prop_tgt/ANDROID_API_MIN.rst
@@ -1,6 +1,8 @@
 ANDROID_API_MIN
 ---------------
 
+.. versionadded:: 3.2
+
 Set the Android MIN API version (e.g. ``9``).  The version number
 must be a positive decimal integer.  This property is initialized by
 the value of the :variable:`CMAKE_ANDROID_API_MIN` variable if it is set
diff --git a/Help/prop_tgt/ANDROID_ARCH.rst b/Help/prop_tgt/ANDROID_ARCH.rst
index 3e07e5a..94b76dd 100644
--- a/Help/prop_tgt/ANDROID_ARCH.rst
+++ b/Help/prop_tgt/ANDROID_ARCH.rst
@@ -1,6 +1,8 @@
 ANDROID_ARCH
 ------------
 
+.. versionadded:: 3.4
+
 When :ref:`Cross Compiling for Android with NVIDIA Nsight Tegra Visual Studio
 Edition`, this property sets the Android target architecture.
 
diff --git a/Help/prop_tgt/ANDROID_ASSETS_DIRECTORIES.rst b/Help/prop_tgt/ANDROID_ASSETS_DIRECTORIES.rst
index 764a582..b09a8b7 100644
--- a/Help/prop_tgt/ANDROID_ASSETS_DIRECTORIES.rst
+++ b/Help/prop_tgt/ANDROID_ASSETS_DIRECTORIES.rst
@@ -1,6 +1,8 @@
 ANDROID_ASSETS_DIRECTORIES
 --------------------------
 
+.. versionadded:: 3.4
+
 Set the Android assets directories to copy into the main assets
 folder before build. This a string property that contains the
 directory paths separated by semicolon.
diff --git a/Help/prop_tgt/ANDROID_GUI.rst b/Help/prop_tgt/ANDROID_GUI.rst
index 92e2041..cc022db 100644
--- a/Help/prop_tgt/ANDROID_GUI.rst
+++ b/Help/prop_tgt/ANDROID_GUI.rst
@@ -1,6 +1,8 @@
 ANDROID_GUI
 -----------
 
+.. versionadded:: 3.1
+
 When :ref:`Cross Compiling for Android with NVIDIA Nsight Tegra Visual Studio
 Edition`, this property specifies whether to build an executable as an
 application package on Android.
diff --git a/Help/prop_tgt/ANDROID_JAR_DEPENDENCIES.rst b/Help/prop_tgt/ANDROID_JAR_DEPENDENCIES.rst
index 42937c1..9880daf 100644
--- a/Help/prop_tgt/ANDROID_JAR_DEPENDENCIES.rst
+++ b/Help/prop_tgt/ANDROID_JAR_DEPENDENCIES.rst
@@ -1,6 +1,8 @@
 ANDROID_JAR_DEPENDENCIES
 ------------------------
 
+.. versionadded:: 3.4
+
 Set the Android property that specifies JAR dependencies.
 This is a string value property. This property is initialized
 by the value of the :variable:`CMAKE_ANDROID_JAR_DEPENDENCIES`
diff --git a/Help/prop_tgt/ANDROID_JAR_DIRECTORIES.rst b/Help/prop_tgt/ANDROID_JAR_DIRECTORIES.rst
index 54f0a8f..6fef50b 100644
--- a/Help/prop_tgt/ANDROID_JAR_DIRECTORIES.rst
+++ b/Help/prop_tgt/ANDROID_JAR_DIRECTORIES.rst
@@ -1,6 +1,8 @@
 ANDROID_JAR_DIRECTORIES
 -----------------------
 
+.. versionadded:: 3.4
+
 Set the Android property that specifies directories to search for
 the JAR libraries.
 
diff --git a/Help/prop_tgt/ANDROID_JAVA_SOURCE_DIR.rst b/Help/prop_tgt/ANDROID_JAVA_SOURCE_DIR.rst
index 90ef1ce..9ea9884 100644
--- a/Help/prop_tgt/ANDROID_JAVA_SOURCE_DIR.rst
+++ b/Help/prop_tgt/ANDROID_JAVA_SOURCE_DIR.rst
@@ -1,6 +1,8 @@
 ANDROID_JAVA_SOURCE_DIR
 -----------------------
 
+.. versionadded:: 3.4
+
 Set the Android property that defines the Java source code root directories.
 This a string property that contains the directory paths separated by semicolon.
 This property is initialized by the value of the
diff --git a/Help/prop_tgt/ANDROID_NATIVE_LIB_DEPENDENCIES.rst b/Help/prop_tgt/ANDROID_NATIVE_LIB_DEPENDENCIES.rst
index 759a37b..3aa741f 100644
--- a/Help/prop_tgt/ANDROID_NATIVE_LIB_DEPENDENCIES.rst
+++ b/Help/prop_tgt/ANDROID_NATIVE_LIB_DEPENDENCIES.rst
@@ -1,6 +1,8 @@
 ANDROID_NATIVE_LIB_DEPENDENCIES
 -------------------------------
 
+.. versionadded:: 3.4
+
 Set the Android property that specifies the .so dependencies.
 This is a string property.
 
diff --git a/Help/prop_tgt/ANDROID_NATIVE_LIB_DIRECTORIES.rst b/Help/prop_tgt/ANDROID_NATIVE_LIB_DIRECTORIES.rst
index d0cd29d..98200d9 100644
--- a/Help/prop_tgt/ANDROID_NATIVE_LIB_DIRECTORIES.rst
+++ b/Help/prop_tgt/ANDROID_NATIVE_LIB_DIRECTORIES.rst
@@ -1,6 +1,8 @@
 ANDROID_NATIVE_LIB_DIRECTORIES
 ------------------------------
 
+.. versionadded:: 3.4
+
 Set the Android property that specifies directories to search for the ``.so``
 libraries.
 
diff --git a/Help/prop_tgt/ANDROID_PROCESS_MAX.rst b/Help/prop_tgt/ANDROID_PROCESS_MAX.rst
index 847acae..0b6aba7 100644
--- a/Help/prop_tgt/ANDROID_PROCESS_MAX.rst
+++ b/Help/prop_tgt/ANDROID_PROCESS_MAX.rst
@@ -1,6 +1,8 @@
 ANDROID_PROCESS_MAX
 -------------------
 
+.. versionadded:: 3.4
+
 Set the Android property that defines the maximum number of a
 parallel Android NDK compiler processes (e.g. ``4``).
 This property is initialized by the value of the
diff --git a/Help/prop_tgt/ANDROID_PROGUARD.rst b/Help/prop_tgt/ANDROID_PROGUARD.rst
index dafc51e..b5ce166 100644
--- a/Help/prop_tgt/ANDROID_PROGUARD.rst
+++ b/Help/prop_tgt/ANDROID_PROGUARD.rst
@@ -1,6 +1,8 @@
 ANDROID_PROGUARD
 ----------------
 
+.. versionadded:: 3.4
+
 When this property is set to true that enables the ProGuard tool to shrink,
 optimize, and obfuscate the code by removing unused code and renaming
 classes, fields, and methods with semantically obscure names.
diff --git a/Help/prop_tgt/ANDROID_PROGUARD_CONFIG_PATH.rst b/Help/prop_tgt/ANDROID_PROGUARD_CONFIG_PATH.rst
index 0e929d1..6ac59d8 100644
--- a/Help/prop_tgt/ANDROID_PROGUARD_CONFIG_PATH.rst
+++ b/Help/prop_tgt/ANDROID_PROGUARD_CONFIG_PATH.rst
@@ -1,6 +1,8 @@
 ANDROID_PROGUARD_CONFIG_PATH
 ----------------------------
 
+.. versionadded:: 3.4
+
 Set the Android property that specifies the location of the ProGuard
 config file. Leave empty to use the default one.
 This a string property that contains the path to ProGuard config file.
diff --git a/Help/prop_tgt/ANDROID_SECURE_PROPS_PATH.rst b/Help/prop_tgt/ANDROID_SECURE_PROPS_PATH.rst
index 9533f1a..f2ffa2e 100644
--- a/Help/prop_tgt/ANDROID_SECURE_PROPS_PATH.rst
+++ b/Help/prop_tgt/ANDROID_SECURE_PROPS_PATH.rst
@@ -1,6 +1,8 @@
 ANDROID_SECURE_PROPS_PATH
 -------------------------
 
+.. versionadded:: 3.4
+
 Set the Android property that states the location of the secure properties file.
 This is a string property that contains the file path.
 This property is initialized by the value of the
diff --git a/Help/prop_tgt/ANDROID_SKIP_ANT_STEP.rst b/Help/prop_tgt/ANDROID_SKIP_ANT_STEP.rst
index 6361896..1a54bce 100644
--- a/Help/prop_tgt/ANDROID_SKIP_ANT_STEP.rst
+++ b/Help/prop_tgt/ANDROID_SKIP_ANT_STEP.rst
@@ -1,6 +1,8 @@
 ANDROID_SKIP_ANT_STEP
 ---------------------
 
+.. versionadded:: 3.4
+
 Set the Android property that defines whether or not to skip the Ant build step.
 This is a boolean property initialized by the value of the
 :variable:`CMAKE_ANDROID_SKIP_ANT_STEP` variable if it is set when a target is created.
diff --git a/Help/prop_tgt/ANDROID_STL_TYPE.rst b/Help/prop_tgt/ANDROID_STL_TYPE.rst
index 386e96e..c83712b 100644
--- a/Help/prop_tgt/ANDROID_STL_TYPE.rst
+++ b/Help/prop_tgt/ANDROID_STL_TYPE.rst
@@ -1,6 +1,8 @@
 ANDROID_STL_TYPE
 ----------------
 
+.. versionadded:: 3.4
+
 When :ref:`Cross Compiling for Android with NVIDIA Nsight Tegra Visual Studio
 Edition`, this property specifies the type of STL support for the project.
 This is a string property that could set to the one of the following values:
diff --git a/Help/prop_tgt/AUTOGEN_BUILD_DIR.rst b/Help/prop_tgt/AUTOGEN_BUILD_DIR.rst
index 909b14c..ff42ae8 100644
--- a/Help/prop_tgt/AUTOGEN_BUILD_DIR.rst
+++ b/Help/prop_tgt/AUTOGEN_BUILD_DIR.rst
@@ -1,6 +1,8 @@
 AUTOGEN_BUILD_DIR
 -----------------
 
+.. versionadded:: 3.9
+
 Directory where :prop_tgt:`AUTOMOC`, :prop_tgt:`AUTOUIC` and :prop_tgt:`AUTORCC`
 generate files for the target.
 
diff --git a/Help/prop_tgt/AUTOGEN_ORIGIN_DEPENDS.rst b/Help/prop_tgt/AUTOGEN_ORIGIN_DEPENDS.rst
index 022bab5..563190a 100644
--- a/Help/prop_tgt/AUTOGEN_ORIGIN_DEPENDS.rst
+++ b/Help/prop_tgt/AUTOGEN_ORIGIN_DEPENDS.rst
@@ -1,6 +1,8 @@
 AUTOGEN_ORIGIN_DEPENDS
 ----------------------
 
+.. versionadded:: 3.14
+
 Switch for forwarding origin target dependencies to the corresponding
 ``_autogen`` target.
 
diff --git a/Help/prop_tgt/AUTOGEN_PARALLEL.rst b/Help/prop_tgt/AUTOGEN_PARALLEL.rst
index 968b619..663b54e 100644
--- a/Help/prop_tgt/AUTOGEN_PARALLEL.rst
+++ b/Help/prop_tgt/AUTOGEN_PARALLEL.rst
@@ -1,6 +1,8 @@
 AUTOGEN_PARALLEL
 ----------------
 
+.. versionadded:: 3.11
+
 Number of parallel ``moc`` or ``uic`` processes to start when using
 :prop_tgt:`AUTOMOC` and :prop_tgt:`AUTOUIC`.
 
diff --git a/Help/prop_tgt/AUTOMOC_COMPILER_PREDEFINES.rst b/Help/prop_tgt/AUTOMOC_COMPILER_PREDEFINES.rst
index 57a647f..8998284 100644
--- a/Help/prop_tgt/AUTOMOC_COMPILER_PREDEFINES.rst
+++ b/Help/prop_tgt/AUTOMOC_COMPILER_PREDEFINES.rst
@@ -1,6 +1,8 @@
 AUTOMOC_COMPILER_PREDEFINES
 ---------------------------
 
+.. versionadded:: 3.10
+
 Boolean value used by :prop_tgt:`AUTOMOC` to determine if the
 compiler pre definitions file ``moc_predefs.h`` should be generated.
 
diff --git a/Help/prop_tgt/AUTOMOC_DEPEND_FILTERS.rst b/Help/prop_tgt/AUTOMOC_DEPEND_FILTERS.rst
index 6eda26c..1f31700 100644
--- a/Help/prop_tgt/AUTOMOC_DEPEND_FILTERS.rst
+++ b/Help/prop_tgt/AUTOMOC_DEPEND_FILTERS.rst
@@ -1,6 +1,8 @@
 AUTOMOC_DEPEND_FILTERS
 ----------------------
 
+.. versionadded:: 3.9
+
 Filter definitions used by :prop_tgt:`AUTOMOC` to extract file names from a
 source file that are registered as additional dependencies for the
 ``moc`` file of the source file.
diff --git a/Help/prop_tgt/AUTOMOC_EXECUTABLE.rst b/Help/prop_tgt/AUTOMOC_EXECUTABLE.rst
index 6b66ce8..f4b8396 100644
--- a/Help/prop_tgt/AUTOMOC_EXECUTABLE.rst
+++ b/Help/prop_tgt/AUTOMOC_EXECUTABLE.rst
@@ -1,6 +1,8 @@
 AUTOMOC_EXECUTABLE
 ------------------
 
+.. versionadded:: 3.14
+
 :prop_tgt:`AUTOMOC_EXECUTABLE` is file path pointing to the ``moc``
 executable to use for :prop_tgt:`AUTOMOC` enabled files. Setting
 this property will make CMake skip the automatic detection of the
diff --git a/Help/prop_tgt/AUTOMOC_MACRO_NAMES.rst b/Help/prop_tgt/AUTOMOC_MACRO_NAMES.rst
index 5329bba..a53810d 100644
--- a/Help/prop_tgt/AUTOMOC_MACRO_NAMES.rst
+++ b/Help/prop_tgt/AUTOMOC_MACRO_NAMES.rst
@@ -1,6 +1,8 @@
 AUTOMOC_MACRO_NAMES
 -------------------
 
+.. versionadded:: 3.10
+
 A :ref:`semicolon-separated list <CMake Language Lists>` list of macro names used by
 :prop_tgt:`AUTOMOC` to determine if a C++ file needs to be processed by ``moc``.
 
diff --git a/Help/prop_tgt/AUTOMOC_PATH_PREFIX.rst b/Help/prop_tgt/AUTOMOC_PATH_PREFIX.rst
index 5ed504f..836d953 100644
--- a/Help/prop_tgt/AUTOMOC_PATH_PREFIX.rst
+++ b/Help/prop_tgt/AUTOMOC_PATH_PREFIX.rst
@@ -1,6 +1,8 @@
 AUTOMOC_PATH_PREFIX
 -------------------
 
+.. versionadded:: 3.16
+
 When this property is ``ON``, CMake will generate the ``-p`` path prefix
 option for ``moc`` on :prop_tgt:`AUTOMOC` enabled Qt targets.
 
diff --git a/Help/prop_tgt/AUTORCC_EXECUTABLE.rst b/Help/prop_tgt/AUTORCC_EXECUTABLE.rst
index ca0fbd7..4f85fba 100644
--- a/Help/prop_tgt/AUTORCC_EXECUTABLE.rst
+++ b/Help/prop_tgt/AUTORCC_EXECUTABLE.rst
@@ -1,6 +1,8 @@
 AUTORCC_EXECUTABLE
 ------------------
 
+.. versionadded:: 3.14
+
 :prop_tgt:`AUTORCC_EXECUTABLE` is file path pointing to the ``rcc``
 executable to use for :prop_tgt:`AUTORCC` enabled files. Setting
 this property will make CMake skip the automatic detection of the
diff --git a/Help/prop_tgt/AUTOUIC_EXECUTABLE.rst b/Help/prop_tgt/AUTOUIC_EXECUTABLE.rst
index 03bd554..5966326 100644
--- a/Help/prop_tgt/AUTOUIC_EXECUTABLE.rst
+++ b/Help/prop_tgt/AUTOUIC_EXECUTABLE.rst
@@ -1,6 +1,8 @@
 AUTOUIC_EXECUTABLE
 ------------------
 
+.. versionadded:: 3.14
+
 :prop_tgt:`AUTOUIC_EXECUTABLE` is file path pointing to the ``uic``
 executable to use for :prop_tgt:`AUTOUIC` enabled files. Setting
 this property will make CMake skip the automatic detection of the
diff --git a/Help/prop_tgt/AUTOUIC_SEARCH_PATHS.rst b/Help/prop_tgt/AUTOUIC_SEARCH_PATHS.rst
index 96d9f89..87fea48 100644
--- a/Help/prop_tgt/AUTOUIC_SEARCH_PATHS.rst
+++ b/Help/prop_tgt/AUTOUIC_SEARCH_PATHS.rst
@@ -1,6 +1,8 @@
 AUTOUIC_SEARCH_PATHS
 --------------------
 
+.. versionadded:: 3.9
+
 Search path list used by :prop_tgt:`AUTOUIC` to find included
 ``.ui`` files.
 
diff --git a/Help/prop_tgt/BINARY_DIR.rst b/Help/prop_tgt/BINARY_DIR.rst
index 246f7e6..beab12c 100644
--- a/Help/prop_tgt/BINARY_DIR.rst
+++ b/Help/prop_tgt/BINARY_DIR.rst
@@ -1,6 +1,8 @@
 BINARY_DIR
 ----------
 
+.. versionadded:: 3.4
+
 This read-only property reports the value of the
 :variable:`CMAKE_CURRENT_BINARY_DIR` variable in the directory in which
 the target was defined.
diff --git a/Help/prop_tgt/BUILD_RPATH.rst b/Help/prop_tgt/BUILD_RPATH.rst
index d978b94..1f917a5 100644
--- a/Help/prop_tgt/BUILD_RPATH.rst
+++ b/Help/prop_tgt/BUILD_RPATH.rst
@@ -1,6 +1,8 @@
 BUILD_RPATH
 -----------
 
+.. versionadded:: 3.8
+
 A :ref:`semicolon-separated list <CMake Language Lists>` specifying runtime path (``RPATH``)
 entries to add to binaries linked in the build tree (for platforms that
 support it).  The entries will *not* be used for binaries in the install
diff --git a/Help/prop_tgt/BUILD_RPATH_USE_ORIGIN.rst b/Help/prop_tgt/BUILD_RPATH_USE_ORIGIN.rst
index 3378797..2cdfa0d 100644
--- a/Help/prop_tgt/BUILD_RPATH_USE_ORIGIN.rst
+++ b/Help/prop_tgt/BUILD_RPATH_USE_ORIGIN.rst
@@ -1,6 +1,8 @@
 BUILD_RPATH_USE_ORIGIN
 ----------------------
 
+.. versionadded:: 3.14
+
 Whether to use relative paths for the build ``RPATH``.
 
 This property is initialized by the value of the variable
diff --git a/Help/prop_tgt/BUILD_WITH_INSTALL_NAME_DIR.rst b/Help/prop_tgt/BUILD_WITH_INSTALL_NAME_DIR.rst
index bbb9a24..073dce5 100644
--- a/Help/prop_tgt/BUILD_WITH_INSTALL_NAME_DIR.rst
+++ b/Help/prop_tgt/BUILD_WITH_INSTALL_NAME_DIR.rst
@@ -1,6 +1,8 @@
 BUILD_WITH_INSTALL_NAME_DIR
 ---------------------------
 
+.. versionadded:: 3.9
+
 ``BUILD_WITH_INSTALL_NAME_DIR`` is a boolean specifying whether the macOS
 ``install_name`` of a target in the build tree uses the directory given by
 :prop_tgt:`INSTALL_NAME_DIR`.  This setting only applies to targets on macOS.
diff --git a/Help/prop_tgt/COMMON_LANGUAGE_RUNTIME.rst b/Help/prop_tgt/COMMON_LANGUAGE_RUNTIME.rst
index 052ac6d..adfa6f7 100644
--- a/Help/prop_tgt/COMMON_LANGUAGE_RUNTIME.rst
+++ b/Help/prop_tgt/COMMON_LANGUAGE_RUNTIME.rst
@@ -1,6 +1,8 @@
 COMMON_LANGUAGE_RUNTIME
 -----------------------
 
+.. versionadded:: 3.12
+
 By setting this target property, the target is configured to build with
 ``C++/CLI`` support.
 
diff --git a/Help/prop_tgt/COMPILE_FEATURES.rst b/Help/prop_tgt/COMPILE_FEATURES.rst
index 46aec4f..9b937ed 100644
--- a/Help/prop_tgt/COMPILE_FEATURES.rst
+++ b/Help/prop_tgt/COMPILE_FEATURES.rst
@@ -1,6 +1,8 @@
 COMPILE_FEATURES
 ----------------
 
+.. versionadded:: 3.1
+
 Compiler features enabled for this target.
 
 The list of features in this property are a subset of the features listed
diff --git a/Help/prop_tgt/COMPILE_PDB_NAME.rst b/Help/prop_tgt/COMPILE_PDB_NAME.rst
index 24a9f62..b76afeb 100644
--- a/Help/prop_tgt/COMPILE_PDB_NAME.rst
+++ b/Help/prop_tgt/COMPILE_PDB_NAME.rst
@@ -1,6 +1,8 @@
 COMPILE_PDB_NAME
 ----------------
 
+.. versionadded:: 3.1
+
 Output name for the MS debug symbol ``.pdb`` file generated by the
 compiler while building source files.
 
diff --git a/Help/prop_tgt/COMPILE_PDB_NAME_CONFIG.rst b/Help/prop_tgt/COMPILE_PDB_NAME_CONFIG.rst
index e4077f5..4c9825d 100644
--- a/Help/prop_tgt/COMPILE_PDB_NAME_CONFIG.rst
+++ b/Help/prop_tgt/COMPILE_PDB_NAME_CONFIG.rst
@@ -1,6 +1,8 @@
 COMPILE_PDB_NAME_<CONFIG>
 -------------------------
 
+.. versionadded:: 3.1
+
 Per-configuration output name for the MS debug symbol ``.pdb`` file
 generated by the compiler while building source files.
 
diff --git a/Help/prop_tgt/COMPILE_PDB_OUTPUT_DIRECTORY.rst b/Help/prop_tgt/COMPILE_PDB_OUTPUT_DIRECTORY.rst
index 34f49be..3f3df66 100644
--- a/Help/prop_tgt/COMPILE_PDB_OUTPUT_DIRECTORY.rst
+++ b/Help/prop_tgt/COMPILE_PDB_OUTPUT_DIRECTORY.rst
@@ -1,6 +1,8 @@
 COMPILE_PDB_OUTPUT_DIRECTORY
 ----------------------------
 
+.. versionadded:: 3.1
+
 Output directory for the MS debug symbol ``.pdb`` file
 generated by the compiler while building source files.
 
diff --git a/Help/prop_tgt/COMPILE_PDB_OUTPUT_DIRECTORY_CONFIG.rst b/Help/prop_tgt/COMPILE_PDB_OUTPUT_DIRECTORY_CONFIG.rst
index f261756..c25c2fc 100644
--- a/Help/prop_tgt/COMPILE_PDB_OUTPUT_DIRECTORY_CONFIG.rst
+++ b/Help/prop_tgt/COMPILE_PDB_OUTPUT_DIRECTORY_CONFIG.rst
@@ -1,6 +1,8 @@
 COMPILE_PDB_OUTPUT_DIRECTORY_<CONFIG>
 -------------------------------------
 
+.. versionadded:: 3.1
+
 Per-configuration output directory for the MS debug symbol ``.pdb`` file
 generated by the compiler while building source files.
 
diff --git a/Help/prop_tgt/CONFIG_POSTFIX.rst b/Help/prop_tgt/CONFIG_POSTFIX.rst
index 11b50b9..5c2fbd7 100644
--- a/Help/prop_tgt/CONFIG_POSTFIX.rst
+++ b/Help/prop_tgt/CONFIG_POSTFIX.rst
@@ -8,3 +8,6 @@
 targets, this property is initialized by the value of the variable
 CMAKE_<CONFIG>_POSTFIX if it is set when a target is created.  This
 property is ignored on the Mac for Frameworks and App Bundles.
+
+For macOS see also the :prop_tgt:`FRAMEWORK_MULTI_CONFIG_POSTFIX_<CONFIG>`
+target property.
diff --git a/Help/prop_tgt/CROSSCOMPILING_EMULATOR.rst b/Help/prop_tgt/CROSSCOMPILING_EMULATOR.rst
index 87c5978..d7fb9b1 100644
--- a/Help/prop_tgt/CROSSCOMPILING_EMULATOR.rst
+++ b/Help/prop_tgt/CROSSCOMPILING_EMULATOR.rst
@@ -1,6 +1,8 @@
 CROSSCOMPILING_EMULATOR
 -----------------------
 
+.. versionadded:: 3.3
+
 Use the given emulator to run executables created when crosscompiling.
 This command will be added as a prefix to :command:`add_test`,
 :command:`add_custom_command`, and :command:`add_custom_target` commands
diff --git a/Help/prop_tgt/CUDA_ARCHITECTURES.rst b/Help/prop_tgt/CUDA_ARCHITECTURES.rst
new file mode 100644
index 0000000..d56b769
--- /dev/null
+++ b/Help/prop_tgt/CUDA_ARCHITECTURES.rst
@@ -0,0 +1,42 @@
+CUDA_ARCHITECTURES
+------------------
+
+.. versionadded:: 3.18
+
+List of architectures to generate device code for.
+
+An architecture can be suffixed by either ``-real`` or ``-virtual`` to specify
+the kind of architecture to generate code for.
+If no suffix is given then code is generated for both real and virtual
+architectures.
+
+A non-empty false value (e.g. ``OFF``) disables adding architectures.
+This is intended to support packagers and rare cases where full control
+over the passed flags is required.
+
+This property is initialized by the value of the :variable:`CMAKE_CUDA_ARCHITECTURES`
+variable if it is set when a target is created.
+
+The ``CUDA_ARCHITECTURES`` target property must be set to a non-empty value on targets
+that compile CUDA sources, or it is an error.  See policy :policy:`CMP0104`.
+
+Examples
+^^^^^^^^
+
+.. code-block:: cmake
+
+  set_property(TARGET tgt PROPERTY CUDA_ARCHITECTURES 35 50 72)
+
+Generates code for real and virtual architectures ``30``, ``50`` and ``72``.
+
+.. code-block:: cmake
+
+  set_property(TARGET tgt PROPERTY CUDA_ARCHITECTURES 70-real 72-virtual)
+
+Generates code for real architecture ``70`` and virtual architecture ``72``.
+
+.. code-block:: cmake
+
+  set_property(TARGET tgt PROPERTY CUDA_ARCHITECTURES OFF)
+
+CMake will not pass any architecture flags to the compiler.
diff --git a/Help/prop_tgt/CUDA_EXTENSIONS.rst b/Help/prop_tgt/CUDA_EXTENSIONS.rst
index 098ca3c..2ddba0b 100644
--- a/Help/prop_tgt/CUDA_EXTENSIONS.rst
+++ b/Help/prop_tgt/CUDA_EXTENSIONS.rst
@@ -1,6 +1,8 @@
 CUDA_EXTENSIONS
 ---------------
 
+.. versionadded:: 3.8
+
 Boolean specifying whether compiler specific extensions are requested.
 
 This property specifies whether compiler specific extensions should be
diff --git a/Help/prop_tgt/CUDA_PTX_COMPILATION.rst b/Help/prop_tgt/CUDA_PTX_COMPILATION.rst
index 0ee372b..4e90afe 100644
--- a/Help/prop_tgt/CUDA_PTX_COMPILATION.rst
+++ b/Help/prop_tgt/CUDA_PTX_COMPILATION.rst
@@ -1,6 +1,8 @@
 CUDA_PTX_COMPILATION
 --------------------
 
+.. versionadded:: 3.9
+
 Compile CUDA sources to ``.ptx`` files instead of ``.obj`` files
 within :ref:`Object Libraries`.
 
diff --git a/Help/prop_tgt/CUDA_RESOLVE_DEVICE_SYMBOLS.rst b/Help/prop_tgt/CUDA_RESOLVE_DEVICE_SYMBOLS.rst
index dae960f..819ce3e 100644
--- a/Help/prop_tgt/CUDA_RESOLVE_DEVICE_SYMBOLS.rst
+++ b/Help/prop_tgt/CUDA_RESOLVE_DEVICE_SYMBOLS.rst
@@ -1,6 +1,8 @@
 CUDA_RESOLVE_DEVICE_SYMBOLS
 ---------------------------
 
+.. versionadded:: 3.9
+
 CUDA only: Enables device linking for the specific library target where
 required.
 
diff --git a/Help/prop_tgt/CUDA_RUNTIME_LIBRARY.rst b/Help/prop_tgt/CUDA_RUNTIME_LIBRARY.rst
index 11b344c..e937fc6 100644
--- a/Help/prop_tgt/CUDA_RUNTIME_LIBRARY.rst
+++ b/Help/prop_tgt/CUDA_RUNTIME_LIBRARY.rst
@@ -1,6 +1,8 @@
 CUDA_RUNTIME_LIBRARY
 --------------------
 
+.. versionadded:: 3.17
+
 Select the CUDA runtime library for use by compilers targeting the CUDA language.
 
 The allowed case insensitive values are:
diff --git a/Help/prop_tgt/CUDA_SEPARABLE_COMPILATION.rst b/Help/prop_tgt/CUDA_SEPARABLE_COMPILATION.rst
index d306d7f..32222f9 100644
--- a/Help/prop_tgt/CUDA_SEPARABLE_COMPILATION.rst
+++ b/Help/prop_tgt/CUDA_SEPARABLE_COMPILATION.rst
@@ -1,6 +1,8 @@
 CUDA_SEPARABLE_COMPILATION
 --------------------------
 
+.. versionadded:: 3.8
+
 CUDA only: Enables separate compilation of device code
 
 If set this will enable separable compilation for all CUDA files for
diff --git a/Help/prop_tgt/CUDA_STANDARD.rst b/Help/prop_tgt/CUDA_STANDARD.rst
index a3a2f56..fcc4725 100644
--- a/Help/prop_tgt/CUDA_STANDARD.rst
+++ b/Help/prop_tgt/CUDA_STANDARD.rst
@@ -1,13 +1,15 @@
 CUDA_STANDARD
 -------------
 
+.. versionadded:: 3.8
+
 The CUDA/C++ standard whose features are requested to build this target.
 
 This property specifies the CUDA/C++ standard whose features are requested
 to build this target.  For some compilers, this results in adding a
 flag such as ``-std=gnu++11`` to the compile line.
 
-Supported values are ``98``, ``11``, ``14``.
+Supported values are ``98``, ``03``, ``11``, ``14``, ``17``, ``20``.
 
 If the value requested does not result in a compile flag being added for
 the compiler in use, a previous standard flag will be added instead.  This
diff --git a/Help/prop_tgt/CUDA_STANDARD_REQUIRED.rst b/Help/prop_tgt/CUDA_STANDARD_REQUIRED.rst
index b2d5b28..c9301b5 100644
--- a/Help/prop_tgt/CUDA_STANDARD_REQUIRED.rst
+++ b/Help/prop_tgt/CUDA_STANDARD_REQUIRED.rst
@@ -1,6 +1,8 @@
 CUDA_STANDARD_REQUIRED
 ----------------------
 
+.. versionadded:: 3.8
+
 Boolean describing whether the value of :prop_tgt:`CUDA_STANDARD` is a requirement.
 
 If this property is set to ``ON``, then the value of the
@@ -8,7 +10,7 @@
 property is ``OFF`` or unset, the :prop_tgt:`CUDA_STANDARD` target property is
 treated as optional and may "decay" to a previous standard if the requested is
 not available.  For compilers that have no notion of a standard level, such as
-MSVC, this has no effect.
+MSVC 1800 (Visual Studio 2013) and lower, this has no effect.
 
 See the :manual:`cmake-compile-features(7)` manual for information on
 compile features and a list of supported compilers.
diff --git a/Help/prop_tgt/CXX_EXTENSIONS.rst b/Help/prop_tgt/CXX_EXTENSIONS.rst
index 280bb3a..bda531e 100644
--- a/Help/prop_tgt/CXX_EXTENSIONS.rst
+++ b/Help/prop_tgt/CXX_EXTENSIONS.rst
@@ -1,6 +1,8 @@
 CXX_EXTENSIONS
 --------------
 
+.. versionadded:: 3.1
+
 Boolean specifying whether compiler specific extensions are requested.
 
 This property specifies whether compiler specific extensions should be
diff --git a/Help/prop_tgt/CXX_STANDARD.rst b/Help/prop_tgt/CXX_STANDARD.rst
index ccc0147..f322ffe 100644
--- a/Help/prop_tgt/CXX_STANDARD.rst
+++ b/Help/prop_tgt/CXX_STANDARD.rst
@@ -1,6 +1,8 @@
 CXX_STANDARD
 ------------
 
+.. versionadded:: 3.1
+
 The C++ standard whose features are requested to build this target.
 
 This property specifies the C++ standard whose features are requested
diff --git a/Help/prop_tgt/CXX_STANDARD_REQUIRED.rst b/Help/prop_tgt/CXX_STANDARD_REQUIRED.rst
index 697d7f6..8b17490 100644
--- a/Help/prop_tgt/CXX_STANDARD_REQUIRED.rst
+++ b/Help/prop_tgt/CXX_STANDARD_REQUIRED.rst
@@ -1,6 +1,8 @@
 CXX_STANDARD_REQUIRED
 ---------------------
 
+.. versionadded:: 3.1
+
 Boolean describing whether the value of :prop_tgt:`CXX_STANDARD` is a requirement.
 
 If this property is set to ``ON``, then the value of the
@@ -8,7 +10,7 @@
 property is ``OFF`` or unset, the :prop_tgt:`CXX_STANDARD` target property is
 treated as optional and may "decay" to a previous standard if the requested is
 not available.  For compilers that have no notion of a standard level, such as
-MSVC, this has no effect.
+MSVC 1800 (Visual Studio 2013) and lower, this has no effect.
 
 See the :manual:`cmake-compile-features(7)` manual for information on
 compile features and a list of supported compilers.
diff --git a/Help/prop_tgt/C_EXTENSIONS.rst b/Help/prop_tgt/C_EXTENSIONS.rst
index 05b14ce..b2abb46 100644
--- a/Help/prop_tgt/C_EXTENSIONS.rst
+++ b/Help/prop_tgt/C_EXTENSIONS.rst
@@ -1,6 +1,8 @@
 C_EXTENSIONS
 ------------
 
+.. versionadded:: 3.1
+
 Boolean specifying whether compiler specific extensions are requested.
 
 This property specifies whether compiler specific extensions should be
diff --git a/Help/prop_tgt/C_STANDARD.rst b/Help/prop_tgt/C_STANDARD.rst
index e7f7904..999a9e7 100644
--- a/Help/prop_tgt/C_STANDARD.rst
+++ b/Help/prop_tgt/C_STANDARD.rst
@@ -1,13 +1,15 @@
 C_STANDARD
 ----------
 
+.. versionadded:: 3.1
+
 The C standard whose features are requested to build this target.
 
 This property specifies the C standard whose features are requested
 to build this target.  For some compilers, this results in adding a
 flag such as ``-std=gnu11`` to the compile line.  For compilers that
-have no notion of a standard level, such as Microsoft Visual C++ before
-2015 Update 3, this has no effect.
+have no notion of a C standard level, such as all versions of
+MSVC known as of this version of CMake, this has no effect.
 
 Supported values are ``90``, ``99`` and ``11``.
 
diff --git a/Help/prop_tgt/C_STANDARD_REQUIRED.rst b/Help/prop_tgt/C_STANDARD_REQUIRED.rst
index acfad98..55bff04 100644
--- a/Help/prop_tgt/C_STANDARD_REQUIRED.rst
+++ b/Help/prop_tgt/C_STANDARD_REQUIRED.rst
@@ -1,6 +1,8 @@
 C_STANDARD_REQUIRED
 -------------------
 
+.. versionadded:: 3.1
+
 Boolean describing whether the value of :prop_tgt:`C_STANDARD` is a requirement.
 
 If this property is set to ``ON``, then the value of the
@@ -8,7 +10,7 @@
 property is ``OFF`` or unset, the :prop_tgt:`C_STANDARD` target property is
 treated as optional and may "decay" to a previous standard if the requested is
 not available.  For compilers that have no notion of a standard level, such as
-MSVC, this has no effect.
+MSVC 1800 (Visual Studio 2013) and lower, this has no effect.
 
 See the :manual:`cmake-compile-features(7)` manual for information on
 compile features and a list of supported compilers.
diff --git a/Help/prop_tgt/DEBUG_POSTFIX.rst b/Help/prop_tgt/DEBUG_POSTFIX.rst
index 04e312e..eca7cb0 100644
--- a/Help/prop_tgt/DEBUG_POSTFIX.rst
+++ b/Help/prop_tgt/DEBUG_POSTFIX.rst
@@ -1,7 +1,7 @@
 DEBUG_POSTFIX
 -------------
 
-See target property ``<CONFIG>_POSTFIX``.
+See target property :prop_tgt:`<CONFIG>_POSTFIX`.
 
-This property is a special case of the more-general ``<CONFIG>_POSTFIX``
+This property is a special case of the more-general :prop_tgt:`<CONFIG>_POSTFIX`
 property for the ``DEBUG`` configuration.
diff --git a/Help/prop_tgt/DEPLOYMENT_ADDITIONAL_FILES.rst b/Help/prop_tgt/DEPLOYMENT_ADDITIONAL_FILES.rst
index 5e9c191..f11fe7c 100644
--- a/Help/prop_tgt/DEPLOYMENT_ADDITIONAL_FILES.rst
+++ b/Help/prop_tgt/DEPLOYMENT_ADDITIONAL_FILES.rst
@@ -1,6 +1,8 @@
 DEPLOYMENT_ADDITIONAL_FILES
 ---------------------------
 
+.. versionadded:: 3.13
+
 Set the WinCE project ``AdditionalFiles`` in ``DeploymentTool`` in ``.vcproj``
 files generated by the :generator:`Visual Studio 9 2008` generator.
 This is useful when you want to debug on remote WinCE device.
diff --git a/Help/prop_tgt/DEPLOYMENT_REMOTE_DIRECTORY.rst b/Help/prop_tgt/DEPLOYMENT_REMOTE_DIRECTORY.rst
index 368768a..0680238 100644
--- a/Help/prop_tgt/DEPLOYMENT_REMOTE_DIRECTORY.rst
+++ b/Help/prop_tgt/DEPLOYMENT_REMOTE_DIRECTORY.rst
@@ -1,6 +1,8 @@
 DEPLOYMENT_REMOTE_DIRECTORY
 ---------------------------
 
+.. versionadded:: 3.6
+
 Set the WinCE project ``RemoteDirectory`` in ``DeploymentTool`` and
 ``RemoteExecutable`` in ``DebuggerTool`` in ``.vcproj`` files generated
 by the :generator:`Visual Studio 9 2008` generator.
diff --git a/Help/prop_tgt/DEPRECATION.rst b/Help/prop_tgt/DEPRECATION.rst
index fef2e2e..45ca848 100644
--- a/Help/prop_tgt/DEPRECATION.rst
+++ b/Help/prop_tgt/DEPRECATION.rst
@@ -1,6 +1,8 @@
 DEPRECATION
 -----------
 
+.. versionadded:: 3.17
+
 Deprecation message from imported target's developer.
 
 ``DEPRECATION`` is the message regarding a deprecation status to be displayed
diff --git a/Help/prop_tgt/DISABLE_PRECOMPILE_HEADERS.rst b/Help/prop_tgt/DISABLE_PRECOMPILE_HEADERS.rst
index 4cef023..7b3826b 100644
--- a/Help/prop_tgt/DISABLE_PRECOMPILE_HEADERS.rst
+++ b/Help/prop_tgt/DISABLE_PRECOMPILE_HEADERS.rst
@@ -1,6 +1,8 @@
 DISABLE_PRECOMPILE_HEADERS
 --------------------------
 
+.. versionadded:: 3.16
+
 Disables the precompilation of header files specified by
 :prop_tgt:`PRECOMPILE_HEADERS` property.
 
diff --git a/Help/prop_tgt/DOTNET_TARGET_FRAMEWORK.rst b/Help/prop_tgt/DOTNET_TARGET_FRAMEWORK.rst
index 8698eb6..3ba4e25 100644
--- a/Help/prop_tgt/DOTNET_TARGET_FRAMEWORK.rst
+++ b/Help/prop_tgt/DOTNET_TARGET_FRAMEWORK.rst
@@ -1,6 +1,8 @@
 DOTNET_TARGET_FRAMEWORK
 -----------------------
 
+.. versionadded:: 3.17
+
 Specify the .NET target framework.
 
 Used to specify the .NET target framework for C++/CLI and C#.  For
diff --git a/Help/prop_tgt/DOTNET_TARGET_FRAMEWORK_VERSION.rst b/Help/prop_tgt/DOTNET_TARGET_FRAMEWORK_VERSION.rst
index b33f4fb..fbd1aab 100644
--- a/Help/prop_tgt/DOTNET_TARGET_FRAMEWORK_VERSION.rst
+++ b/Help/prop_tgt/DOTNET_TARGET_FRAMEWORK_VERSION.rst
@@ -1,6 +1,8 @@
 DOTNET_TARGET_FRAMEWORK_VERSION
 -------------------------------
 
+.. versionadded:: 3.12
+
 Specify the .NET target framework version.
 
 Used to specify the .NET target framework version for C++/CLI and C#.
diff --git a/Help/prop_tgt/EXCLUDE_FROM_ALL.rst b/Help/prop_tgt/EXCLUDE_FROM_ALL.rst
index 3aa296d..f0200f3 100644
--- a/Help/prop_tgt/EXCLUDE_FROM_ALL.rst
+++ b/Help/prop_tgt/EXCLUDE_FROM_ALL.rst
@@ -13,9 +13,16 @@
 
 With ``EXCLUDE_FROM_ALL`` set to false or not set at all, the target
 will be brought up to date as part of doing a ``make install`` or its
-equivalent for the CMake generator being used.  If a target has
-``EXCLUDE_FROM_ALL`` set to true, then any attempt to install that
-target has undefined behavior.  Note that such a target can still safely
-be listed in an :command:`install(TARGETS)` command as long as the install
-components the target belongs to are not part of the set of components
-that anything tries to install.
+equivalent for the CMake generator being used.
+
+If a target has ``EXCLUDE_FROM_ALL`` set to true, it may still be listed
+in an :command:`install(TARGETS)` command, but the user is responsible for
+ensuring that the target's build artifacts are not missing or outdated when
+an install is performed.
+
+This property may use "generator expressions" with the syntax ``$<...>``. See
+the :manual:`cmake-generator-expressions(7)` manual for available expressions.
+
+Only the "Ninja Multi-Config" generator supports a property value that varies by
+configuration.  For all other generators the value of this property must be the
+same for all configurations.
diff --git a/Help/prop_tgt/EXPORT_PROPERTIES.rst b/Help/prop_tgt/EXPORT_PROPERTIES.rst
index bcf47a6..2d54f8b 100644
--- a/Help/prop_tgt/EXPORT_PROPERTIES.rst
+++ b/Help/prop_tgt/EXPORT_PROPERTIES.rst
@@ -1,6 +1,8 @@
 EXPORT_PROPERTIES
 -----------------
 
+.. versionadded:: 3.12
+
 List additional properties to export for a target.
 
 This property contains a list of property names that should be exported by
@@ -12,3 +14,11 @@
 they are reserved for internal CMake use.
 
 Properties containing generator expressions are also not allowed.
+
+.. note::
+
+  Since CMake 3.19, :ref:`Interface Libraries` may have arbitrary
+  target properties.  If a project exports an interface library
+  with custom properties, the resulting package may not work with
+  dependents configured by older versions of CMake that reject the
+  custom properties.
diff --git a/Help/prop_tgt/FRAMEWORK_MULTI_CONFIG_POSTFIX_CONFIG.rst b/Help/prop_tgt/FRAMEWORK_MULTI_CONFIG_POSTFIX_CONFIG.rst
new file mode 100644
index 0000000..84d0c1e
--- /dev/null
+++ b/Help/prop_tgt/FRAMEWORK_MULTI_CONFIG_POSTFIX_CONFIG.rst
@@ -0,0 +1,28 @@
+FRAMEWORK_MULTI_CONFIG_POSTFIX_<CONFIG>
+---------------------------------------
+
+.. versionadded:: 3.18
+
+Postfix to append to the framework file name for configuration ``<CONFIG>``,
+when using a multi-config generator (like Xcode and Ninja Multi-Config).
+
+When building with configuration ``<CONFIG>`` the value of this property
+is appended to the framework file name built on disk.
+
+For example, given a framework called ``my_fw``, a value of ``_debug``
+for the ``FRAMEWORK_MULTI_CONFIG_POSTFIX_DEBUG`` property, and
+``Debug;Release`` in :variable:`CMAKE_CONFIGURATION_TYPES`, the following
+relevant files would be created for the ``Debug`` and ``Release``
+configurations:
+
+- ``Release/my_fw.framework/my_fw``
+- ``Release/my_fw.framework/Versions/A/my_fw``
+- ``Debug/my_fw.framework/my_fw_debug``
+- ``Debug/my_fw.framework/Versions/A/my_fw_debug``
+
+For framework targets, this property is initialized by the value of the
+:variable:`CMAKE_FRAMEWORK_MULTI_CONFIG_POSTFIX_<CONFIG>` variable if it
+is set when a target is created.
+
+This property is ignored for non-framework targets, and when using single
+config generators.
diff --git a/Help/prop_tgt/FRAMEWORK_VERSION.rst b/Help/prop_tgt/FRAMEWORK_VERSION.rst
index c2ae7b9..38b8137 100644
--- a/Help/prop_tgt/FRAMEWORK_VERSION.rst
+++ b/Help/prop_tgt/FRAMEWORK_VERSION.rst
@@ -1,6 +1,8 @@
 FRAMEWORK_VERSION
 -----------------
 
+.. versionadded:: 3.4
+
 Version of a framework created using the :prop_tgt:`FRAMEWORK` target
 property (e.g. ``A``).
 
diff --git a/Help/prop_tgt/Fortran_PREPROCESS.rst b/Help/prop_tgt/Fortran_PREPROCESS.rst
new file mode 100644
index 0000000..e7e2fba
--- /dev/null
+++ b/Help/prop_tgt/Fortran_PREPROCESS.rst
@@ -0,0 +1,25 @@
+Fortran_PREPROCESS
+------------------
+
+.. versionadded:: 3.18
+
+Control whether the Fortran source file should be unconditionally
+preprocessed.
+
+If unset or empty, rely on the compiler to determine whether the file
+should be preprocessed. If explicitly set to ``OFF`` then the file does not
+need to be preprocessed. If explicitly set to ``ON``, then the file does
+need to be preprocessed as part of the compilation step.
+
+When using the :generator:`Ninja` generator, all source files are
+first preprocessed in order to generate module dependency
+information. Setting this property to ``OFF`` will make ``Ninja``
+skip this step.
+
+Use the source-specific :prop_sf:`Fortran_PREPROCESS` property if a single
+file needs to be preprocessed. If the variable
+:variable:`CMAKE_Fortran_PREPROCESS` is set when a target is created its
+value is used to initialize this property.
+
+.. note:: For some compilers, ``NAG``, ``PGI`` and ``Solaris Studio``,
+          setting this to ``OFF`` will have no effect.
diff --git a/Help/prop_tgt/GHS_INTEGRITY_APP.rst b/Help/prop_tgt/GHS_INTEGRITY_APP.rst
index b669781..cccd087 100644
--- a/Help/prop_tgt/GHS_INTEGRITY_APP.rst
+++ b/Help/prop_tgt/GHS_INTEGRITY_APP.rst
@@ -1,6 +1,8 @@
 GHS_INTEGRITY_APP
 -----------------
 
+.. versionadded:: 3.14
+
 ``ON`` / ``OFF`` boolean to determine if an executable target should
 be treated as an `Integrity Application`.
 
diff --git a/Help/prop_tgt/GHS_NO_SOURCE_GROUP_FILE.rst b/Help/prop_tgt/GHS_NO_SOURCE_GROUP_FILE.rst
index 11ce0b22..fe6b8e6 100644
--- a/Help/prop_tgt/GHS_NO_SOURCE_GROUP_FILE.rst
+++ b/Help/prop_tgt/GHS_NO_SOURCE_GROUP_FILE.rst
@@ -1,6 +1,8 @@
 GHS_NO_SOURCE_GROUP_FILE
 ------------------------
 
+.. versionadded:: 3.14
+
 ``ON`` / ``OFF`` boolean to control if the project file for a target should
 be one single file or multiple files.
 
diff --git a/Help/prop_tgt/IMPORTED_COMMON_LANGUAGE_RUNTIME.rst b/Help/prop_tgt/IMPORTED_COMMON_LANGUAGE_RUNTIME.rst
index 99e3bc4..8c20e07 100644
--- a/Help/prop_tgt/IMPORTED_COMMON_LANGUAGE_RUNTIME.rst
+++ b/Help/prop_tgt/IMPORTED_COMMON_LANGUAGE_RUNTIME.rst
@@ -1,6 +1,8 @@
 IMPORTED_COMMON_LANGUAGE_RUNTIME
 --------------------------------
 
+.. versionadded:: 3.12
+
 Property to define if the target uses ``C++/CLI``.
 
 Ignored for non-imported targets.
diff --git a/Help/prop_tgt/IMPORTED_GLOBAL.rst b/Help/prop_tgt/IMPORTED_GLOBAL.rst
index 1feca04..176127f 100644
--- a/Help/prop_tgt/IMPORTED_GLOBAL.rst
+++ b/Help/prop_tgt/IMPORTED_GLOBAL.rst
@@ -1,6 +1,8 @@
 IMPORTED_GLOBAL
 ---------------
 
+.. versionadded:: 3.11
+
 Indication of whether an :ref:`IMPORTED target <Imported Targets>` is
 globally visible.
 
@@ -16,7 +18,15 @@
 target to global scope. This promotion can only be done in the same
 directory where that ``IMPORTED`` target was created in the first place.
 
-Once an imported target has been made global, it cannot be changed back to
-non-global. Therefore, if a project sets this property, it may only
-provide a value of True. CMake will issue an error if the project tries to
-set the property to a non-True value, even if the value was already False.
+.. note::
+
+  Once an imported target has been made global, it cannot be changed back to
+  non-global. Therefore, if a project sets this property, it may only
+  provide a value of True. CMake will issue an error if the project tries to
+  set the property to a non-True value, even if the value was already False.
+
+.. note::
+
+  Local :ref:`ALIAS targets <Alias Targets>` created before promoting an
+  :ref:`IMPORTED target <Imported Targets>` from ``LOCAL`` to ``GLOBAL``, keep
+  their initial scope (see :prop_tgt:`ALIAS_GLOBAL` target property).
diff --git a/Help/prop_tgt/IMPORTED_LIBNAME.rst b/Help/prop_tgt/IMPORTED_LIBNAME.rst
index 1943dba..7a83906 100644
--- a/Help/prop_tgt/IMPORTED_LIBNAME.rst
+++ b/Help/prop_tgt/IMPORTED_LIBNAME.rst
@@ -1,6 +1,8 @@
 IMPORTED_LIBNAME
 ----------------
 
+.. versionadded:: 3.8
+
 Specify the link library name for an :ref:`imported <Imported Targets>`
 :ref:`Interface Library <Interface Libraries>`.
 
diff --git a/Help/prop_tgt/IMPORTED_LIBNAME_CONFIG.rst b/Help/prop_tgt/IMPORTED_LIBNAME_CONFIG.rst
index a28b838..df64769 100644
--- a/Help/prop_tgt/IMPORTED_LIBNAME_CONFIG.rst
+++ b/Help/prop_tgt/IMPORTED_LIBNAME_CONFIG.rst
@@ -1,6 +1,8 @@
 IMPORTED_LIBNAME_<CONFIG>
 -------------------------
 
+.. versionadded:: 3.8
+
 <CONFIG>-specific version of :prop_tgt:`IMPORTED_LIBNAME` property.
 
 Configuration names correspond to those provided by the project from
diff --git a/Help/prop_tgt/IMPORTED_OBJECTS.rst b/Help/prop_tgt/IMPORTED_OBJECTS.rst
index 50a329f..bbbcd86 100644
--- a/Help/prop_tgt/IMPORTED_OBJECTS.rst
+++ b/Help/prop_tgt/IMPORTED_OBJECTS.rst
@@ -1,6 +1,8 @@
 IMPORTED_OBJECTS
 ----------------
 
+.. versionadded:: 3.9
+
 A :ref:`semicolon-separated list <CMake Language Lists>` of absolute paths to the object
 files on disk for an :ref:`imported <Imported targets>`
 :ref:`object library <object libraries>`.
diff --git a/Help/prop_tgt/IMPORTED_OBJECTS_CONFIG.rst b/Help/prop_tgt/IMPORTED_OBJECTS_CONFIG.rst
index 4419ed1..b12ca38 100644
--- a/Help/prop_tgt/IMPORTED_OBJECTS_CONFIG.rst
+++ b/Help/prop_tgt/IMPORTED_OBJECTS_CONFIG.rst
@@ -1,6 +1,8 @@
 IMPORTED_OBJECTS_<CONFIG>
 -------------------------
 
+.. versionadded:: 3.9
+
 <CONFIG>-specific version of :prop_tgt:`IMPORTED_OBJECTS` property.
 
 Configuration names correspond to those provided by the project from
diff --git a/Help/prop_tgt/INSTALL_REMOVE_ENVIRONMENT_RPATH.rst b/Help/prop_tgt/INSTALL_REMOVE_ENVIRONMENT_RPATH.rst
index 72dcaa0..f41e41c 100644
--- a/Help/prop_tgt/INSTALL_REMOVE_ENVIRONMENT_RPATH.rst
+++ b/Help/prop_tgt/INSTALL_REMOVE_ENVIRONMENT_RPATH.rst
@@ -1,6 +1,8 @@
 INSTALL_REMOVE_ENVIRONMENT_RPATH
 --------------------------------
 
+.. versionadded:: 3.16
+
 Controls whether toolchain-defined rpaths should be removed during installation.
 
 When a target is being installed, CMake may need to rewrite its rpath
diff --git a/Help/prop_tgt/INSTALL_RPATH.rst b/Help/prop_tgt/INSTALL_RPATH.rst
index 93b4488..4549b92 100644
--- a/Help/prop_tgt/INSTALL_RPATH.rst
+++ b/Help/prop_tgt/INSTALL_RPATH.rst
@@ -8,5 +8,9 @@
 by the value of the variable :variable:`CMAKE_INSTALL_RPATH` if it is set when
 a target is created.
 
+Because the rpath may contain ``${ORIGIN}``, which coincides with CMake syntax,
+the contents of ``INSTALL_RPATH`` are properly escaped in the
+``cmake_install.cmake`` script (see policy :policy:`CMP0095`.)
+
 This property supports
 :manual:`generator expressions <cmake-generator-expressions(7)>`.
diff --git a/Help/prop_tgt/INTERFACE_COMPILE_FEATURES.rst b/Help/prop_tgt/INTERFACE_COMPILE_FEATURES.rst
index 31b594f..0db3b0c 100644
--- a/Help/prop_tgt/INTERFACE_COMPILE_FEATURES.rst
+++ b/Help/prop_tgt/INTERFACE_COMPILE_FEATURES.rst
@@ -1,6 +1,8 @@
 INTERFACE_COMPILE_FEATURES
 --------------------------
 
+.. versionadded:: 3.1
+
 .. |property_name| replace:: compile features
 .. |command_name| replace:: :command:`target_compile_features`
 .. |PROPERTY_INTERFACE_NAME| replace:: ``INTERFACE_COMPILE_FEATURES``
diff --git a/Help/prop_tgt/INTERFACE_LINK_DEPENDS.rst b/Help/prop_tgt/INTERFACE_LINK_DEPENDS.rst
index 790554d..9c8275d 100644
--- a/Help/prop_tgt/INTERFACE_LINK_DEPENDS.rst
+++ b/Help/prop_tgt/INTERFACE_LINK_DEPENDS.rst
@@ -1,6 +1,8 @@
 INTERFACE_LINK_DEPENDS
 ----------------------
 
+.. versionadded:: 3.13
+
 Additional public interface files on which a target binary depends for linking.
 
 This property is supported only by :generator:`Ninja` and
diff --git a/Help/prop_tgt/INTERFACE_LINK_DIRECTORIES.rst b/Help/prop_tgt/INTERFACE_LINK_DIRECTORIES.rst
index 56a4ec0..de1dabb 100644
--- a/Help/prop_tgt/INTERFACE_LINK_DIRECTORIES.rst
+++ b/Help/prop_tgt/INTERFACE_LINK_DIRECTORIES.rst
@@ -1,6 +1,8 @@
 INTERFACE_LINK_DIRECTORIES
 --------------------------
 
+.. versionadded:: 3.13
+
 .. |property_name| replace:: link directories
 .. |command_name| replace:: :command:`target_link_directories`
 .. |PROPERTY_INTERFACE_NAME| replace:: ``INTERFACE_LINK_DIRECTORIES``
diff --git a/Help/prop_tgt/INTERFACE_LINK_OPTIONS.rst b/Help/prop_tgt/INTERFACE_LINK_OPTIONS.rst
index c293b98..4245fe9 100644
--- a/Help/prop_tgt/INTERFACE_LINK_OPTIONS.rst
+++ b/Help/prop_tgt/INTERFACE_LINK_OPTIONS.rst
@@ -1,6 +1,8 @@
 INTERFACE_LINK_OPTIONS
 ----------------------
 
+.. versionadded:: 3.13
+
 .. |property_name| replace:: link options
 .. |command_name| replace:: :command:`target_link_options`
 .. |PROPERTY_INTERFACE_NAME| replace:: ``INTERFACE_LINK_OPTIONS``
diff --git a/Help/prop_tgt/INTERFACE_PRECOMPILE_HEADERS.rst b/Help/prop_tgt/INTERFACE_PRECOMPILE_HEADERS.rst
index e285407..2299264 100644
--- a/Help/prop_tgt/INTERFACE_PRECOMPILE_HEADERS.rst
+++ b/Help/prop_tgt/INTERFACE_PRECOMPILE_HEADERS.rst
@@ -1,6 +1,8 @@
 INTERFACE_PRECOMPILE_HEADERS
 ----------------------------
 
+.. versionadded:: 3.16
+
 List of interface header files to precompile into consuming targets.
 
 Targets may populate this property to publish the header files
diff --git a/Help/prop_tgt/INTERFACE_SOURCES.rst b/Help/prop_tgt/INTERFACE_SOURCES.rst
index a224b68..759c482 100644
--- a/Help/prop_tgt/INTERFACE_SOURCES.rst
+++ b/Help/prop_tgt/INTERFACE_SOURCES.rst
@@ -1,6 +1,8 @@
 INTERFACE_SOURCES
 -----------------
 
+.. versionadded:: 3.1
+
 List of interface sources to compile into consuming targets.
 
 Targets may populate this property to publish the sources
diff --git a/Help/prop_tgt/IOS_INSTALL_COMBINED.rst b/Help/prop_tgt/IOS_INSTALL_COMBINED.rst
index 59f67a7..23a86e6 100644
--- a/Help/prop_tgt/IOS_INSTALL_COMBINED.rst
+++ b/Help/prop_tgt/IOS_INSTALL_COMBINED.rst
@@ -1,6 +1,8 @@
 IOS_INSTALL_COMBINED
 --------------------
 
+.. versionadded:: 3.5
+
 Build a combined (device and simulator) target when installing.
 
 When this property is set to set to false (which is the default) then it will
diff --git a/Help/prop_tgt/JOB_POOL_PRECOMPILE_HEADER.rst b/Help/prop_tgt/JOB_POOL_PRECOMPILE_HEADER.rst
index ece28a4..42cace0 100644
--- a/Help/prop_tgt/JOB_POOL_PRECOMPILE_HEADER.rst
+++ b/Help/prop_tgt/JOB_POOL_PRECOMPILE_HEADER.rst
@@ -1,6 +1,8 @@
 JOB_POOL_PRECOMPILE_HEADER
 --------------------------
 
+.. versionadded:: 3.17
+
 Ninja only: Pool used for generating pre-compiled headers.
 
 The number of parallel compile processes could be limited by defining
diff --git a/Help/prop_tgt/LANG_CLANG_TIDY.rst b/Help/prop_tgt/LANG_CLANG_TIDY.rst
index 2bfef66..7fc2372 100644
--- a/Help/prop_tgt/LANG_CLANG_TIDY.rst
+++ b/Help/prop_tgt/LANG_CLANG_TIDY.rst
@@ -1,6 +1,8 @@
 <LANG>_CLANG_TIDY
 -----------------
 
+.. versionadded:: 3.6
+
 This property is implemented only when ``<LANG>`` is ``C`` or ``CXX``.
 
 Specify a :ref:`semicolon-separated list <CMake Language Lists>` containing a command
diff --git a/Help/prop_tgt/LANG_COMPILER_LAUNCHER.rst b/Help/prop_tgt/LANG_COMPILER_LAUNCHER.rst
index a6f2b24..77ae1f6 100644
--- a/Help/prop_tgt/LANG_COMPILER_LAUNCHER.rst
+++ b/Help/prop_tgt/LANG_COMPILER_LAUNCHER.rst
@@ -1,6 +1,8 @@
 <LANG>_COMPILER_LAUNCHER
 ------------------------
 
+.. versionadded:: 3.4
+
 This property is implemented only when ``<LANG>`` is ``C``, ``CXX``,
 ``Fortran``, ``OBJC``, ``OBJCXX``, or ``CUDA``.
 
diff --git a/Help/prop_tgt/LANG_CPPCHECK.rst b/Help/prop_tgt/LANG_CPPCHECK.rst
index 60785d0..80acbc0 100644
--- a/Help/prop_tgt/LANG_CPPCHECK.rst
+++ b/Help/prop_tgt/LANG_CPPCHECK.rst
@@ -1,6 +1,8 @@
 <LANG>_CPPCHECK
 ---------------
 
+.. versionadded:: 3.10
+
 This property is supported only when ``<LANG>`` is ``C`` or ``CXX``.
 
 Specify a :ref:`semicolon-separated list <CMake Language Lists>` containing a command line
diff --git a/Help/prop_tgt/LANG_CPPLINT.rst b/Help/prop_tgt/LANG_CPPLINT.rst
index 9944c88..be6db46 100644
--- a/Help/prop_tgt/LANG_CPPLINT.rst
+++ b/Help/prop_tgt/LANG_CPPLINT.rst
@@ -1,6 +1,8 @@
 <LANG>_CPPLINT
 --------------
 
+.. versionadded:: 3.8
+
 This property is supported only when ``<LANG>`` is ``C`` or ``CXX``.
 
 Specify a :ref:`semicolon-separated list <CMake Language Lists>` containing a command line
diff --git a/Help/prop_tgt/LANG_INCLUDE_WHAT_YOU_USE.rst b/Help/prop_tgt/LANG_INCLUDE_WHAT_YOU_USE.rst
index 35220e4..eebef56 100644
--- a/Help/prop_tgt/LANG_INCLUDE_WHAT_YOU_USE.rst
+++ b/Help/prop_tgt/LANG_INCLUDE_WHAT_YOU_USE.rst
@@ -1,6 +1,8 @@
 <LANG>_INCLUDE_WHAT_YOU_USE
 ---------------------------
 
+.. versionadded:: 3.3
+
 This property is implemented only when ``<LANG>`` is ``C`` or ``CXX``.
 
 Specify a :ref:`semicolon-separated list <CMake Language Lists>` containing a command
diff --git a/Help/prop_tgt/LINK_DIRECTORIES.rst b/Help/prop_tgt/LINK_DIRECTORIES.rst
index c2905b3..67be494 100644
--- a/Help/prop_tgt/LINK_DIRECTORIES.rst
+++ b/Help/prop_tgt/LINK_DIRECTORIES.rst
@@ -1,6 +1,8 @@
 LINK_DIRECTORIES
 ----------------
 
+.. versionadded:: 3.13
+
 List of directories to use for the link step of shared library, module
 and executable targets.
 
diff --git a/Help/prop_tgt/LINK_OPTIONS.rst b/Help/prop_tgt/LINK_OPTIONS.rst
index 2a05ea7..8c0dfc4 100644
--- a/Help/prop_tgt/LINK_OPTIONS.rst
+++ b/Help/prop_tgt/LINK_OPTIONS.rst
@@ -1,13 +1,19 @@
 LINK_OPTIONS
 ------------
 
+.. versionadded:: 3.13
+
 List of options to use for the link step of shared library, module
-and executable targets. Targets that are static libraries need to use
-the :prop_tgt:`STATIC_LIBRARY_OPTIONS` target property.
+and executable targets as well as the device link step. Targets that are static
+libraries need to use the :prop_tgt:`STATIC_LIBRARY_OPTIONS` target property.
 
+These options are used for both normal linking and device linking
+(see policy :policy:`CMP0105`). To control link options for normal and device
+link steps, ``$<HOST_LINK>`` and ``$<DEVICE_LINK>``
+:manual:`generator expressions <cmake-generator-expressions(7)>` can be used.
 
-This property holds a :ref:`semicolon-separated list <CMake Language Lists>` of options
-specified so far for its target.  Use the :command:`target_link_options`
+This property holds a :ref:`semicolon-separated list <CMake Language Lists>` of
+options specified so far for its target.  Use the :command:`target_link_options`
 command to append more options.
 
 This property is initialized by the :prop_dir:`LINK_OPTIONS` directory
diff --git a/Help/prop_tgt/LINK_WHAT_YOU_USE.rst b/Help/prop_tgt/LINK_WHAT_YOU_USE.rst
index 32d6edb..2ed93ad 100644
--- a/Help/prop_tgt/LINK_WHAT_YOU_USE.rst
+++ b/Help/prop_tgt/LINK_WHAT_YOU_USE.rst
@@ -1,6 +1,8 @@
 LINK_WHAT_YOU_USE
 ---------------------------
 
+.. versionadded:: 3.7
+
 This is a boolean option that when set to ``TRUE`` will automatically run
 ``ldd -r -u`` on the target after it is linked. In addition, the linker flag
 ``-Wl,--no-as-needed`` will be passed to the target with the link command so
diff --git a/Help/prop_tgt/MACHO_COMPATIBILITY_VERSION.rst b/Help/prop_tgt/MACHO_COMPATIBILITY_VERSION.rst
index 26d5cc8..a24b255 100644
--- a/Help/prop_tgt/MACHO_COMPATIBILITY_VERSION.rst
+++ b/Help/prop_tgt/MACHO_COMPATIBILITY_VERSION.rst
@@ -1,6 +1,8 @@
 MACHO_COMPATIBILITY_VERSION
 ---------------------------
 
+.. versionadded:: 3.17
+
 What compatibility version number is this target for Mach-O binaries.
 
 For shared libraries on Mach-O systems (e.g. macOS, iOS)
diff --git a/Help/prop_tgt/MACHO_CURRENT_VERSION.rst b/Help/prop_tgt/MACHO_CURRENT_VERSION.rst
index 9afb356..530f79b 100644
--- a/Help/prop_tgt/MACHO_CURRENT_VERSION.rst
+++ b/Help/prop_tgt/MACHO_CURRENT_VERSION.rst
@@ -1,6 +1,8 @@
 MACHO_CURRENT_VERSION
 ---------------------
 
+.. versionadded:: 3.17
+
 What current version number is this target for Mach-O binaries.
 
 For shared libraries on Mach-O systems (e.g. macOS, iOS)
diff --git a/Help/prop_tgt/MANUALLY_ADDED_DEPENDENCIES.rst b/Help/prop_tgt/MANUALLY_ADDED_DEPENDENCIES.rst
index c12ea14..72871b3 100644
--- a/Help/prop_tgt/MANUALLY_ADDED_DEPENDENCIES.rst
+++ b/Help/prop_tgt/MANUALLY_ADDED_DEPENDENCIES.rst
@@ -1,6 +1,8 @@
 MANUALLY_ADDED_DEPENDENCIES
 ---------------------------
 
+.. versionadded:: 3.8
+
 Get manually added dependencies to other top-level targets.
 
 This read-only property can be used to query all dependencies that
diff --git a/Help/prop_tgt/MSVC_RUNTIME_LIBRARY.rst b/Help/prop_tgt/MSVC_RUNTIME_LIBRARY.rst
index 73792de..9b978b2 100644
--- a/Help/prop_tgt/MSVC_RUNTIME_LIBRARY.rst
+++ b/Help/prop_tgt/MSVC_RUNTIME_LIBRARY.rst
@@ -1,6 +1,8 @@
 MSVC_RUNTIME_LIBRARY
 --------------------
 
+.. versionadded:: 3.15
+
 Select the MSVC runtime library for use by compilers targeting the MSVC ABI.
 
 The allowed values are:
diff --git a/Help/prop_tgt/OBJCXX_EXTENSIONS.rst b/Help/prop_tgt/OBJCXX_EXTENSIONS.rst
index 9f9d804..8a254f2 100644
--- a/Help/prop_tgt/OBJCXX_EXTENSIONS.rst
+++ b/Help/prop_tgt/OBJCXX_EXTENSIONS.rst
@@ -1,6 +1,8 @@
 OBJCXX_EXTENSIONS
 -----------------
 
+.. versionadded:: 3.16
+
 Boolean specifying whether compiler specific extensions are requested.
 
 This property specifies whether compiler specific extensions should be
diff --git a/Help/prop_tgt/OBJCXX_STANDARD.rst b/Help/prop_tgt/OBJCXX_STANDARD.rst
index 3c925dc..1067153 100644
--- a/Help/prop_tgt/OBJCXX_STANDARD.rst
+++ b/Help/prop_tgt/OBJCXX_STANDARD.rst
@@ -1,6 +1,8 @@
 OBJCXX_STANDARD
 ---------------
 
+.. versionadded:: 3.16
+
 The ObjC++ standard whose features are requested to build this target.
 
 This property specifies the ObjC++ standard whose features are requested
diff --git a/Help/prop_tgt/OBJCXX_STANDARD_REQUIRED.rst b/Help/prop_tgt/OBJCXX_STANDARD_REQUIRED.rst
index c330abf..3cee740 100644
--- a/Help/prop_tgt/OBJCXX_STANDARD_REQUIRED.rst
+++ b/Help/prop_tgt/OBJCXX_STANDARD_REQUIRED.rst
@@ -1,6 +1,8 @@
 OBJCXX_STANDARD_REQUIRED
 ------------------------
 
+.. versionadded:: 3.16
+
 Boolean describing whether the value of :prop_tgt:`OBJCXX_STANDARD` is a requirement.
 
 If this property is set to ``ON``, then the value of the
diff --git a/Help/prop_tgt/OBJC_EXTENSIONS.rst b/Help/prop_tgt/OBJC_EXTENSIONS.rst
index 2de9e48..ef1c754 100644
--- a/Help/prop_tgt/OBJC_EXTENSIONS.rst
+++ b/Help/prop_tgt/OBJC_EXTENSIONS.rst
@@ -1,6 +1,8 @@
 OBJC_EXTENSIONS
 ---------------
 
+.. versionadded:: 3.16
+
 Boolean specifying whether compiler specific extensions are requested.
 
 This property specifies whether compiler specific extensions should be
diff --git a/Help/prop_tgt/OBJC_STANDARD.rst b/Help/prop_tgt/OBJC_STANDARD.rst
index d1e1b24..2143ff9 100644
--- a/Help/prop_tgt/OBJC_STANDARD.rst
+++ b/Help/prop_tgt/OBJC_STANDARD.rst
@@ -1,6 +1,8 @@
 OBJC_STANDARD
 -------------
 
+.. versionadded:: 3.16
+
 The OBJC standard whose features are requested to build this target.
 
 This property specifies the OBJC standard whose features are requested
diff --git a/Help/prop_tgt/OBJC_STANDARD_REQUIRED.rst b/Help/prop_tgt/OBJC_STANDARD_REQUIRED.rst
index 8cf377c..11547c8 100644
--- a/Help/prop_tgt/OBJC_STANDARD_REQUIRED.rst
+++ b/Help/prop_tgt/OBJC_STANDARD_REQUIRED.rst
@@ -1,6 +1,8 @@
 OBJC_STANDARD_REQUIRED
 ----------------------
 
+.. versionadded:: 3.16
+
 Boolean describing whether the value of :prop_tgt:`OBJC_STANDARD` is a requirement.
 
 If this property is set to ``ON``, then the value of the
diff --git a/Help/prop_tgt/PCH_WARN_INVALID.rst b/Help/prop_tgt/PCH_WARN_INVALID.rst
new file mode 100644
index 0000000..2d5ec55
--- /dev/null
+++ b/Help/prop_tgt/PCH_WARN_INVALID.rst
@@ -0,0 +1,12 @@
+PCH_WARN_INVALID
+----------------
+
+.. versionadded:: 3.18
+
+When this property is set to true, the precompile header compiler options
+will contain a compiler flag which should warn about invalid precompiled
+headers e.g. ``-Winvalid-pch`` for GNU compiler.
+
+This property is initialized by the value of the
+:variable:`CMAKE_PCH_WARN_INVALID` variable if it is set when a target is
+created.  If that variable is not set, the property defaults to ``ON``.
diff --git a/Help/prop_tgt/PRECOMPILE_HEADERS.rst b/Help/prop_tgt/PRECOMPILE_HEADERS.rst
index 9e70b65..af27947 100644
--- a/Help/prop_tgt/PRECOMPILE_HEADERS.rst
+++ b/Help/prop_tgt/PRECOMPILE_HEADERS.rst
@@ -1,6 +1,8 @@
 PRECOMPILE_HEADERS
 ------------------
 
+.. versionadded:: 3.16
+
 List of header files to precompile.
 
 This property holds a :ref:`semicolon-separated list <CMake Language Lists>`
diff --git a/Help/prop_tgt/PRECOMPILE_HEADERS_REUSE_FROM.rst b/Help/prop_tgt/PRECOMPILE_HEADERS_REUSE_FROM.rst
index 9c3e7ea..6f5635b 100644
--- a/Help/prop_tgt/PRECOMPILE_HEADERS_REUSE_FROM.rst
+++ b/Help/prop_tgt/PRECOMPILE_HEADERS_REUSE_FROM.rst
@@ -1,6 +1,8 @@
 PRECOMPILE_HEADERS_REUSE_FROM
 -----------------------------
 
+.. versionadded:: 3.16
+
 Target from which to reuse the precompiled headers build artifact.
 
 See the second signature of :command:`target_precompile_headers` command
diff --git a/Help/prop_tgt/SOURCE_DIR.rst b/Help/prop_tgt/SOURCE_DIR.rst
index b25813b..78ce220 100644
--- a/Help/prop_tgt/SOURCE_DIR.rst
+++ b/Help/prop_tgt/SOURCE_DIR.rst
@@ -1,6 +1,8 @@
 SOURCE_DIR
 ----------
 
+.. versionadded:: 3.4
+
 This read-only property reports the value of the
 :variable:`CMAKE_CURRENT_SOURCE_DIR` variable in the directory in which
 the target was defined.
diff --git a/Help/prop_tgt/STATIC_LIBRARY_OPTIONS.rst b/Help/prop_tgt/STATIC_LIBRARY_OPTIONS.rst
index d05fda4..2f4a3ba 100644
--- a/Help/prop_tgt/STATIC_LIBRARY_OPTIONS.rst
+++ b/Help/prop_tgt/STATIC_LIBRARY_OPTIONS.rst
@@ -1,6 +1,8 @@
 STATIC_LIBRARY_OPTIONS
 ----------------------
 
+.. versionadded:: 3.13
+
 Archiver (or MSVC librarian) flags for a static library target.
 Targets that are shared libraries, modules, or executables need to use
 the :prop_tgt:`LINK_OPTIONS` target property.
diff --git a/Help/prop_tgt/Swift_DEPENDENCIES_FILE.rst b/Help/prop_tgt/Swift_DEPENDENCIES_FILE.rst
index 46c9a1d..0f944b6 100644
--- a/Help/prop_tgt/Swift_DEPENDENCIES_FILE.rst
+++ b/Help/prop_tgt/Swift_DEPENDENCIES_FILE.rst
@@ -1,5 +1,7 @@
 Swift_DEPENDENCIES_FILE
 -----------------------
 
+.. versionadded:: 3.15
+
 This property sets the path for the Swift dependency file (swiftdep) for the
 target.  If one is not specified, it will default to ``<TARGET>.swiftdeps``.
diff --git a/Help/prop_tgt/Swift_LANGUAGE_VERSION.rst b/Help/prop_tgt/Swift_LANGUAGE_VERSION.rst
index 7579447..afc6b31 100644
--- a/Help/prop_tgt/Swift_LANGUAGE_VERSION.rst
+++ b/Help/prop_tgt/Swift_LANGUAGE_VERSION.rst
@@ -1,6 +1,8 @@
 Swift_LANGUAGE_VERSION
 ----------------------
 
+.. versionadded:: 3.16
+
 This property sets the language version for the Swift sources in the target.  If
 one is not specified, it will default to ``<CMAKE_Swift_LANGUAGE_VERSION>`` if
 specified, otherwise it is the latest version supported by the compiler.
diff --git a/Help/prop_tgt/Swift_MODULE_DIRECTORY.rst b/Help/prop_tgt/Swift_MODULE_DIRECTORY.rst
index d404251..a6484f2 100644
--- a/Help/prop_tgt/Swift_MODULE_DIRECTORY.rst
+++ b/Help/prop_tgt/Swift_MODULE_DIRECTORY.rst
@@ -1,6 +1,8 @@
 Swift_MODULE_DIRECTORY
 ----------------------
 
+.. versionadded:: 3.15
+
 Specify output directory for Swift modules provided by the target.
 
 If the target contains Swift source files, this specifies the directory in which
diff --git a/Help/prop_tgt/Swift_MODULE_NAME.rst b/Help/prop_tgt/Swift_MODULE_NAME.rst
index 2866020..d941b54 100644
--- a/Help/prop_tgt/Swift_MODULE_NAME.rst
+++ b/Help/prop_tgt/Swift_MODULE_NAME.rst
@@ -1,5 +1,7 @@
 Swift_MODULE_NAME
 -----------------
 
+.. versionadded:: 3.15
+
 This property specifies the name of the Swift module.  It is defaulted to the
 name of the target.
diff --git a/Help/prop_tgt/UNITY_BUILD.rst b/Help/prop_tgt/UNITY_BUILD.rst
index 479802e..04cede6 100644
--- a/Help/prop_tgt/UNITY_BUILD.rst
+++ b/Help/prop_tgt/UNITY_BUILD.rst
@@ -1,12 +1,34 @@
 UNITY_BUILD
 -----------
 
+.. versionadded:: 3.16
+
 When this property is set to true, the target source files will be combined
 into batches for faster compilation.  This is done by creating a (set of)
 unity sources which ``#include`` the original sources, then compiling these
 unity sources instead of the originals.  This is known as a *Unity* or *Jumbo*
-build.  The :prop_tgt:`UNITY_BUILD_BATCH_SIZE` property controls the upper
-limit on how many sources can be combined per unity source file.
+build.
+
+CMake provides different algorithms for selecting which sources are grouped
+together into a *bucket*. Algorithm selection is decided by the
+:prop_tgt:`UNITY_BUILD_MODE` target property, which has the following acceptable
+values:
+
+* ``BATCH``
+  When in this mode CMake determines which files are grouped together.
+  The :prop_tgt:`UNITY_BUILD_BATCH_SIZE` property controls the upper limit on
+  how many sources can be combined per unity source file.
+
+* ``GROUP``
+  When in this mode each target explicitly specifies how to group
+  source files. Each source file that has the same
+  :prop_sf:`UNITY_GROUP` value will be grouped together. Any sources
+  that don't have this property will be compiled individually. The
+  :prop_tgt:`UNITY_BUILD_BATCH_SIZE` property is ignored when using
+  this mode.
+
+If no explicit :prop_tgt:`UNITY_BUILD_MODE` has been specified, CMake will
+default to ``BATCH``.
 
 Unity builds are not currently supported for all languages.  CMake version
 |release| supports combining ``C`` and ``CXX`` source files.  For targets that
diff --git a/Help/prop_tgt/UNITY_BUILD_BATCH_SIZE.rst b/Help/prop_tgt/UNITY_BUILD_BATCH_SIZE.rst
index 44ffe27..3886ec9 100644
--- a/Help/prop_tgt/UNITY_BUILD_BATCH_SIZE.rst
+++ b/Help/prop_tgt/UNITY_BUILD_BATCH_SIZE.rst
@@ -1,6 +1,8 @@
 UNITY_BUILD_BATCH_SIZE
 ----------------------
 
+.. versionadded:: 3.16
+
 Specifies the maximum number of source files that can be combined into any one
 unity source file when unity builds are enabled by the :prop_tgt:`UNITY_BUILD`
 target property.  The original source files will be distributed across as many
diff --git a/Help/prop_tgt/UNITY_BUILD_CODE_AFTER_INCLUDE.rst b/Help/prop_tgt/UNITY_BUILD_CODE_AFTER_INCLUDE.rst
index 7231b61..ac2b19c 100644
--- a/Help/prop_tgt/UNITY_BUILD_CODE_AFTER_INCLUDE.rst
+++ b/Help/prop_tgt/UNITY_BUILD_CODE_AFTER_INCLUDE.rst
@@ -1,6 +1,8 @@
 UNITY_BUILD_CODE_AFTER_INCLUDE
 ------------------------------
 
+.. versionadded:: 3.16
+
 Code snippet which is included verbatim by the :prop_tgt:`UNITY_BUILD`
 feature just after every ``#include`` statement in the generated unity
 source files.  For example:
diff --git a/Help/prop_tgt/UNITY_BUILD_CODE_BEFORE_INCLUDE.rst b/Help/prop_tgt/UNITY_BUILD_CODE_BEFORE_INCLUDE.rst
index 7ed6fa1..6f0d56b 100644
--- a/Help/prop_tgt/UNITY_BUILD_CODE_BEFORE_INCLUDE.rst
+++ b/Help/prop_tgt/UNITY_BUILD_CODE_BEFORE_INCLUDE.rst
@@ -1,6 +1,8 @@
 UNITY_BUILD_CODE_BEFORE_INCLUDE
 -------------------------------
 
+.. versionadded:: 3.16
+
 Code snippet which is included verbatim by the :prop_tgt:`UNITY_BUILD`
 feature just before every ``#include`` statement in the generated unity
 source files.  For example:
diff --git a/Help/prop_tgt/UNITY_BUILD_MODE.rst b/Help/prop_tgt/UNITY_BUILD_MODE.rst
new file mode 100644
index 0000000..003451e
--- /dev/null
+++ b/Help/prop_tgt/UNITY_BUILD_MODE.rst
@@ -0,0 +1,60 @@
+UNITY_BUILD_MODE
+----------------
+
+.. versionadded:: 3.18
+
+CMake provides different algorithms for selecting which sources are grouped
+together into a *bucket*. Selection is decided by this property,
+which has the following acceptable values:
+
+``BATCH``
+  When in this mode CMake determines which files are grouped together.
+  The :prop_tgt:`UNITY_BUILD_BATCH_SIZE` property controls the upper limit on
+  how many sources can be combined per unity source file.
+
+  Example usage:
+
+  .. code-block:: cmake
+
+    add_library(example_library
+                source1.cxx
+                source2.cxx
+                source3.cxx
+                source4.cxx)
+
+    set_target_properties(example_library PROPERTIES
+                          UNITY_BUILD_MODE BATCH
+                          UNITY_BUILD_BATCH_SIZE 2
+                          )
+
+``GROUP``
+  When in this mode each target explicitly specifies how to group
+  source files. Each source file that has the same
+  :prop_sf:`UNITY_GROUP` value will be grouped together. Any sources
+  that don't have this property will be compiled individually. The
+  :prop_tgt:`UNITY_BUILD_BATCH_SIZE` property is ignored when using
+  this mode.
+
+  Example usage:
+
+  .. code-block:: cmake
+
+    add_library(example_library
+                source1.cxx
+                source2.cxx
+                source3.cxx
+                source4.cxx)
+
+    set_target_properties(example_library PROPERTIES
+                          UNITY_BUILD_MODE GROUP
+                          )
+
+    set_source_files_properties(source1.cxx source2.cxx source3.cxx
+                                PROPERTIES UNITY_GROUP "bucket1"
+                                )
+    set_source_files_properties(source4.cxx
+                                PROPERTIES UNITY_GROUP "bucket2"
+                                )
+
+If no explicit :prop_tgt:`UNITY_BUILD_MODE` has been specified, CMake will
+default to ``BATCH``.
diff --git a/Help/prop_tgt/VS_CONFIGURATION_TYPE.rst b/Help/prop_tgt/VS_CONFIGURATION_TYPE.rst
index 640bed5..4adffd4 100644
--- a/Help/prop_tgt/VS_CONFIGURATION_TYPE.rst
+++ b/Help/prop_tgt/VS_CONFIGURATION_TYPE.rst
@@ -1,6 +1,8 @@
 VS_CONFIGURATION_TYPE
 ---------------------
 
+.. versionadded:: 3.6
+
 Visual Studio project configuration type.
 
 Sets the ``ConfigurationType`` attribute for a generated Visual Studio project.
diff --git a/Help/prop_tgt/VS_DEBUGGER_COMMAND.rst b/Help/prop_tgt/VS_DEBUGGER_COMMAND.rst
index ba5fd0a..58476d6 100644
--- a/Help/prop_tgt/VS_DEBUGGER_COMMAND.rst
+++ b/Help/prop_tgt/VS_DEBUGGER_COMMAND.rst
@@ -1,6 +1,8 @@
 VS_DEBUGGER_COMMAND
 -------------------
 
+.. versionadded:: 3.12
+
 Sets the local debugger command for Visual Studio C++ targets.
 The property value may use
 :manual:`generator expressions <cmake-generator-expressions(7)>`.
diff --git a/Help/prop_tgt/VS_DEBUGGER_COMMAND_ARGUMENTS.rst b/Help/prop_tgt/VS_DEBUGGER_COMMAND_ARGUMENTS.rst
index 06ef5d5..6c26601 100644
--- a/Help/prop_tgt/VS_DEBUGGER_COMMAND_ARGUMENTS.rst
+++ b/Help/prop_tgt/VS_DEBUGGER_COMMAND_ARGUMENTS.rst
@@ -1,6 +1,8 @@
 VS_DEBUGGER_COMMAND_ARGUMENTS
 -----------------------------
 
+.. versionadded:: 3.13
+
 Sets the local debugger command line arguments for Visual Studio C++ targets.
 The property value may use
 :manual:`generator expressions <cmake-generator-expressions(7)>`.
diff --git a/Help/prop_tgt/VS_DEBUGGER_ENVIRONMENT.rst b/Help/prop_tgt/VS_DEBUGGER_ENVIRONMENT.rst
index f55ac7b..2f59a82 100644
--- a/Help/prop_tgt/VS_DEBUGGER_ENVIRONMENT.rst
+++ b/Help/prop_tgt/VS_DEBUGGER_ENVIRONMENT.rst
@@ -1,6 +1,8 @@
 VS_DEBUGGER_ENVIRONMENT
 -----------------------
 
+.. versionadded:: 3.13
+
 Sets the local debugger environment for Visual Studio C++ targets.
 The property value may use
 :manual:`generator expressions <cmake-generator-expressions(7)>`.
diff --git a/Help/prop_tgt/VS_DEBUGGER_WORKING_DIRECTORY.rst b/Help/prop_tgt/VS_DEBUGGER_WORKING_DIRECTORY.rst
index 008bbf6..c163abf 100644
--- a/Help/prop_tgt/VS_DEBUGGER_WORKING_DIRECTORY.rst
+++ b/Help/prop_tgt/VS_DEBUGGER_WORKING_DIRECTORY.rst
@@ -1,6 +1,8 @@
 VS_DEBUGGER_WORKING_DIRECTORY
 -----------------------------
 
+.. versionadded:: 3.8
+
 Sets the local debugger working directory for Visual Studio C++ targets.
 The property value may use
 :manual:`generator expressions <cmake-generator-expressions(7)>`.
diff --git a/Help/prop_tgt/VS_DESKTOP_EXTENSIONS_VERSION.rst b/Help/prop_tgt/VS_DESKTOP_EXTENSIONS_VERSION.rst
index 19d1620..5fd23e1 100644
--- a/Help/prop_tgt/VS_DESKTOP_EXTENSIONS_VERSION.rst
+++ b/Help/prop_tgt/VS_DESKTOP_EXTENSIONS_VERSION.rst
@@ -1,6 +1,8 @@
 VS_DESKTOP_EXTENSIONS_VERSION
 -----------------------------
 
+.. versionadded:: 3.4
+
 Visual Studio Windows 10 Desktop Extensions Version
 
 Specifies the version of the Desktop Extensions that should be included in the
diff --git a/Help/prop_tgt/VS_DOTNET_DOCUMENTATION_FILE.rst b/Help/prop_tgt/VS_DOTNET_DOCUMENTATION_FILE.rst
index 1bc361c..a388256 100644
--- a/Help/prop_tgt/VS_DOTNET_DOCUMENTATION_FILE.rst
+++ b/Help/prop_tgt/VS_DOTNET_DOCUMENTATION_FILE.rst
@@ -1,6 +1,8 @@
 VS_DOTNET_DOCUMENTATION_FILE
 ----------------------------
 
+.. versionadded:: 3.17
+
 Visual Studio managed project .NET documentation output
 
 Sets the target XML documentation file output.
diff --git a/Help/prop_tgt/VS_DOTNET_REFERENCEPROP_refname_TAG_tagname.rst b/Help/prop_tgt/VS_DOTNET_REFERENCEPROP_refname_TAG_tagname.rst
index ab311ea..5b9caee 100644
--- a/Help/prop_tgt/VS_DOTNET_REFERENCEPROP_refname_TAG_tagname.rst
+++ b/Help/prop_tgt/VS_DOTNET_REFERENCEPROP_refname_TAG_tagname.rst
@@ -1,6 +1,8 @@
 VS_DOTNET_REFERENCEPROP_<refname>_TAG_<tagname>
 -----------------------------------------------
 
+.. versionadded:: 3.10
+
 Defines an XML property ``<tagname>`` for a .NET reference
 ``<refname>``.
 
diff --git a/Help/prop_tgt/VS_DOTNET_REFERENCES_COPY_LOCAL.rst b/Help/prop_tgt/VS_DOTNET_REFERENCES_COPY_LOCAL.rst
index 7641ba5..556fa8a 100644
--- a/Help/prop_tgt/VS_DOTNET_REFERENCES_COPY_LOCAL.rst
+++ b/Help/prop_tgt/VS_DOTNET_REFERENCES_COPY_LOCAL.rst
@@ -1,6 +1,8 @@
 VS_DOTNET_REFERENCES_COPY_LOCAL
 -------------------------------
 
+.. versionadded:: 3.8
+
 Sets the **Copy Local** property for all .NET hint references in the target
 
 Boolean property to enable/disable copying of .NET hint references to
diff --git a/Help/prop_tgt/VS_DOTNET_REFERENCE_refname.rst b/Help/prop_tgt/VS_DOTNET_REFERENCE_refname.rst
index 5814005..9c4d34a 100644
--- a/Help/prop_tgt/VS_DOTNET_REFERENCE_refname.rst
+++ b/Help/prop_tgt/VS_DOTNET_REFERENCE_refname.rst
@@ -1,6 +1,8 @@
 VS_DOTNET_REFERENCE_<refname>
 -----------------------------
 
+.. versionadded:: 3.8
+
 Visual Studio managed project .NET reference with name ``<refname>``
 and hint path.
 
diff --git a/Help/prop_tgt/VS_DPI_AWARE.rst b/Help/prop_tgt/VS_DPI_AWARE.rst
index 82640cc..47ce1ce 100644
--- a/Help/prop_tgt/VS_DPI_AWARE.rst
+++ b/Help/prop_tgt/VS_DPI_AWARE.rst
@@ -1,6 +1,8 @@
 VS_DPI_AWARE
 ------------
 
+.. versionadded:: 3.16
+
 Set the Manifest Tool -> Input and Output -> DPI Awareness in the Visual Studio
 target project properties.
 
diff --git a/Help/prop_tgt/VS_IOT_EXTENSIONS_VERSION.rst b/Help/prop_tgt/VS_IOT_EXTENSIONS_VERSION.rst
index 27c8a3d..ca6a3ca 100644
--- a/Help/prop_tgt/VS_IOT_EXTENSIONS_VERSION.rst
+++ b/Help/prop_tgt/VS_IOT_EXTENSIONS_VERSION.rst
@@ -1,6 +1,8 @@
 VS_IOT_EXTENSIONS_VERSION
 -------------------------
 
+.. versionadded:: 3.4
+
 Visual Studio Windows 10 IoT Extensions Version
 
 Specifies the version of the IoT Extensions that should be included in the
diff --git a/Help/prop_tgt/VS_IOT_STARTUP_TASK.rst b/Help/prop_tgt/VS_IOT_STARTUP_TASK.rst
index add50cb..259055d 100644
--- a/Help/prop_tgt/VS_IOT_STARTUP_TASK.rst
+++ b/Help/prop_tgt/VS_IOT_STARTUP_TASK.rst
@@ -1,6 +1,8 @@
 VS_IOT_STARTUP_TASK
 -------------------
 
+.. versionadded:: 3.4
+
 Visual Studio Windows 10 IoT Continuous Background Task
 
 Specifies that the target should be compiled as a Continuous Background Task library.
diff --git a/Help/prop_tgt/VS_JUST_MY_CODE_DEBUGGING.rst b/Help/prop_tgt/VS_JUST_MY_CODE_DEBUGGING.rst
index 42fb8ad..724bd2f 100644
--- a/Help/prop_tgt/VS_JUST_MY_CODE_DEBUGGING.rst
+++ b/Help/prop_tgt/VS_JUST_MY_CODE_DEBUGGING.rst
@@ -1,6 +1,8 @@
 VS_JUST_MY_CODE_DEBUGGING
 -------------------------
 
+.. versionadded:: 3.15
+
 Enable Just My Code with Visual Studio debugger.
 
 Supported on :ref:`Visual Studio Generators` for VS 2010 and higher,
diff --git a/Help/prop_tgt/VS_MOBILE_EXTENSIONS_VERSION.rst b/Help/prop_tgt/VS_MOBILE_EXTENSIONS_VERSION.rst
index be3c9a0..b307e84 100644
--- a/Help/prop_tgt/VS_MOBILE_EXTENSIONS_VERSION.rst
+++ b/Help/prop_tgt/VS_MOBILE_EXTENSIONS_VERSION.rst
@@ -1,6 +1,8 @@
 VS_MOBILE_EXTENSIONS_VERSION
 ----------------------------
 
+.. versionadded:: 3.4
+
 Visual Studio Windows 10 Mobile Extensions Version
 
 Specifies the version of the Mobile Extensions that should be included in the
diff --git a/Help/prop_tgt/VS_NO_SOLUTION_DEPLOY.rst b/Help/prop_tgt/VS_NO_SOLUTION_DEPLOY.rst
index ffcbde5..bf6ac10 100644
--- a/Help/prop_tgt/VS_NO_SOLUTION_DEPLOY.rst
+++ b/Help/prop_tgt/VS_NO_SOLUTION_DEPLOY.rst
@@ -1,6 +1,8 @@
 VS_NO_SOLUTION_DEPLOY
 ---------------------
 
+.. versionadded:: 3.15
+
 Specify that the target should not be marked for deployment to a Windows CE
 or Windows Phone device in the generated Visual Studio solution.
 
diff --git a/Help/prop_tgt/VS_PACKAGE_REFERENCES.rst b/Help/prop_tgt/VS_PACKAGE_REFERENCES.rst
index 5a0465b..ec17567 100644
--- a/Help/prop_tgt/VS_PACKAGE_REFERENCES.rst
+++ b/Help/prop_tgt/VS_PACKAGE_REFERENCES.rst
@@ -1,6 +1,8 @@
 VS_PACKAGE_REFERENCES
 ---------------------
 
+.. versionadded:: 3.15
+
 Visual Studio package references for nuget.
 
 Adds one or more semicolon-delimited package references to a generated
diff --git a/Help/prop_tgt/VS_PLATFORM_TOOLSET.rst b/Help/prop_tgt/VS_PLATFORM_TOOLSET.rst
new file mode 100644
index 0000000..27a92d6
--- /dev/null
+++ b/Help/prop_tgt/VS_PLATFORM_TOOLSET.rst
@@ -0,0 +1,12 @@
+VS_PLATFORM_TOOLSET
+-------------------
+
+.. versionadded:: 3.18
+
+Overrides the platform toolset used to build a target.
+
+Only supported when the compiler used by the given toolset is the
+same as the compiler used to build the whole source tree.
+
+This is especially useful to create driver projects with the toolsets
+"WindowsUserModeDriver10.0" or "WindowsKernelModeDriver10.0".
diff --git a/Help/prop_tgt/VS_PROJECT_IMPORT.rst b/Help/prop_tgt/VS_PROJECT_IMPORT.rst
index 569c8ea..f5e9698 100644
--- a/Help/prop_tgt/VS_PROJECT_IMPORT.rst
+++ b/Help/prop_tgt/VS_PROJECT_IMPORT.rst
@@ -1,6 +1,8 @@
 VS_PROJECT_IMPORT
 -----------------
 
+.. versionadded:: 3.15
+
 Visual Studio managed project imports
 
 Adds to a generated Visual Studio project one or more semicolon-delimited paths
diff --git a/Help/prop_tgt/VS_SDK_REFERENCES.rst b/Help/prop_tgt/VS_SDK_REFERENCES.rst
index 99987f5..9a082e7 100644
--- a/Help/prop_tgt/VS_SDK_REFERENCES.rst
+++ b/Help/prop_tgt/VS_SDK_REFERENCES.rst
@@ -1,6 +1,8 @@
 VS_SDK_REFERENCES
 -----------------
 
+.. versionadded:: 3.7
+
 Visual Studio project SDK references.
 Specify a :ref:`semicolon-separated list <CMake Language Lists>` of SDK references
 to be added to a generated Visual Studio project, e.g.
diff --git a/Help/prop_tgt/VS_SOLUTION_DEPLOY.rst b/Help/prop_tgt/VS_SOLUTION_DEPLOY.rst
new file mode 100644
index 0000000..e56f411
--- /dev/null
+++ b/Help/prop_tgt/VS_SOLUTION_DEPLOY.rst
@@ -0,0 +1,29 @@
+VS_SOLUTION_DEPLOY
+------------------
+
+.. versionadded:: 3.18
+
+Specify that the target should be marked for deployment when not targeting
+Windows CE, Windows Phone or a Windows Store application.
+
+If the target platform doesn't support deployment, this property won't have
+any effect.
+
+:manual:`Generator expressions <cmake-generator-expressions(7)>` are supported.
+
+Examples
+^^^^^^^^
+
+Always deploy target ``foo``:
+
+.. code-block:: cmake
+
+  add_executable(foo SHARED foo.cpp)
+  set_property(TARGET foo PROPERTY VS_SOLUTION_DEPLOY ON)
+
+Deploy target ``foo`` for all configurations except ``Release``:
+
+.. code-block:: cmake
+
+  add_executable(foo SHARED foo.cpp)
+  set_property(TARGET foo PROPERTY VS_SOLUTION_DEPLOY "$<NOT:$<CONFIG:Release>>")
diff --git a/Help/prop_tgt/VS_SOURCE_SETTINGS_tool.rst b/Help/prop_tgt/VS_SOURCE_SETTINGS_tool.rst
new file mode 100644
index 0000000..b5a76fc
--- /dev/null
+++ b/Help/prop_tgt/VS_SOURCE_SETTINGS_tool.rst
@@ -0,0 +1,21 @@
+VS_SOURCE_SETTINGS_<tool>
+-------------------------
+
+.. versionadded:: 3.18
+
+Set any item metadata on all non-built files that use <tool>.
+
+Takes a list of ``Key=Value`` pairs. Tells the Visual Studio generator
+to set ``Key`` to ``Value`` as item metadata on all non-built files
+that use ``<tool>``.
+
+For example:
+
+.. code-block:: cmake
+
+  set_property(TARGET main PROPERTY VS_SOURCE_SETTINGS_FXCompile "Key=Value" "Key2=Value2")
+
+will set ``Key`` to ``Value`` and ``Key2`` to ``Value2`` for all
+non-built files that use ``FXCompile``.
+
+:manual:`Generator expressions <cmake-generator-expressions(7)>` are supported.
diff --git a/Help/prop_tgt/VS_USER_PROPS.rst b/Help/prop_tgt/VS_USER_PROPS.rst
index 1be222b..8f2a105 100644
--- a/Help/prop_tgt/VS_USER_PROPS.rst
+++ b/Help/prop_tgt/VS_USER_PROPS.rst
@@ -1,6 +1,8 @@
 VS_USER_PROPS
 -------------
 
+.. versionadded:: 3.8
+
 Sets the user props file to be included in the visual studio
 C++ project file. The standard path is
 ``$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props``, which is
diff --git a/Help/prop_tgt/VS_WINDOWS_TARGET_PLATFORM_MIN_VERSION.rst b/Help/prop_tgt/VS_WINDOWS_TARGET_PLATFORM_MIN_VERSION.rst
index 1ad7a71..50cf203 100644
--- a/Help/prop_tgt/VS_WINDOWS_TARGET_PLATFORM_MIN_VERSION.rst
+++ b/Help/prop_tgt/VS_WINDOWS_TARGET_PLATFORM_MIN_VERSION.rst
@@ -1,6 +1,8 @@
 VS_WINDOWS_TARGET_PLATFORM_MIN_VERSION
 --------------------------------------
 
+.. versionadded:: 3.4
+
 Visual Studio Windows Target Platform Minimum Version
 
 For Windows 10. Specifies the minimum version of the OS that is being
diff --git a/Help/prop_tgt/VS_WINRT_COMPONENT.rst b/Help/prop_tgt/VS_WINRT_COMPONENT.rst
index e160bd6..8b4aaf7 100644
--- a/Help/prop_tgt/VS_WINRT_COMPONENT.rst
+++ b/Help/prop_tgt/VS_WINRT_COMPONENT.rst
@@ -1,6 +1,8 @@
 VS_WINRT_COMPONENT
 ------------------
 
+.. versionadded:: 3.1
+
 Mark a target as a Windows Runtime component for the Visual Studio generator.
 Compile the target with ``C++/CX`` language extensions for Windows Runtime.
 For ``SHARED`` and ``MODULE`` libraries, this also defines the
diff --git a/Help/prop_tgt/WINDOWS_EXPORT_ALL_SYMBOLS.rst b/Help/prop_tgt/WINDOWS_EXPORT_ALL_SYMBOLS.rst
index 86711bf..00f32f6 100644
--- a/Help/prop_tgt/WINDOWS_EXPORT_ALL_SYMBOLS.rst
+++ b/Help/prop_tgt/WINDOWS_EXPORT_ALL_SYMBOLS.rst
@@ -1,6 +1,8 @@
 WINDOWS_EXPORT_ALL_SYMBOLS
 --------------------------
 
+.. versionadded:: 3.4
+
 This property is implemented only for MS-compatible tools on Windows.
 
 Enable this boolean property to automatically create a module definition
diff --git a/Help/prop_tgt/XCODE_EXPLICIT_FILE_TYPE.rst b/Help/prop_tgt/XCODE_EXPLICIT_FILE_TYPE.rst
index dc92902..e01a034 100644
--- a/Help/prop_tgt/XCODE_EXPLICIT_FILE_TYPE.rst
+++ b/Help/prop_tgt/XCODE_EXPLICIT_FILE_TYPE.rst
@@ -1,6 +1,8 @@
 XCODE_EXPLICIT_FILE_TYPE
 ------------------------
 
+.. versionadded:: 3.8
+
 Set the Xcode ``explicitFileType`` attribute on its reference to a
 target.  CMake computes a default based on target type but
 can be told explicitly with this property.
diff --git a/Help/prop_tgt/XCODE_GENERATE_SCHEME.rst b/Help/prop_tgt/XCODE_GENERATE_SCHEME.rst
index c32b4de..06a3cf9 100644
--- a/Help/prop_tgt/XCODE_GENERATE_SCHEME.rst
+++ b/Help/prop_tgt/XCODE_GENERATE_SCHEME.rst
@@ -1,6 +1,8 @@
 XCODE_GENERATE_SCHEME
 ---------------------
 
+.. versionadded:: 3.15
+
 If enabled, the :generator:`Xcode` generator will generate schema files.  These
 are useful to invoke analyze, archive, build-for-testing and test
 actions from the command line.
diff --git a/Help/prop_tgt/XCODE_PRODUCT_TYPE.rst b/Help/prop_tgt/XCODE_PRODUCT_TYPE.rst
index f4ef5c0..17a9c3f 100644
--- a/Help/prop_tgt/XCODE_PRODUCT_TYPE.rst
+++ b/Help/prop_tgt/XCODE_PRODUCT_TYPE.rst
@@ -1,6 +1,8 @@
 XCODE_PRODUCT_TYPE
 ------------------
 
+.. versionadded:: 3.8
+
 Set the Xcode ``productType`` attribute on its reference to a
 target.  CMake computes a default based on target type but
 can be told explicitly with this property.
diff --git a/Help/prop_tgt/XCODE_SCHEME_ADDRESS_SANITIZER.rst b/Help/prop_tgt/XCODE_SCHEME_ADDRESS_SANITIZER.rst
index cc9bac2..c72ec06 100644
--- a/Help/prop_tgt/XCODE_SCHEME_ADDRESS_SANITIZER.rst
+++ b/Help/prop_tgt/XCODE_SCHEME_ADDRESS_SANITIZER.rst
@@ -1,6 +1,8 @@
 XCODE_SCHEME_ADDRESS_SANITIZER
 ------------------------------
 
+.. versionadded:: 3.13
+
 Whether to enable ``Address Sanitizer`` in the Diagnostics
 section of the generated Xcode scheme.
 
diff --git a/Help/prop_tgt/XCODE_SCHEME_ADDRESS_SANITIZER_USE_AFTER_RETURN.rst b/Help/prop_tgt/XCODE_SCHEME_ADDRESS_SANITIZER_USE_AFTER_RETURN.rst
index 37a043a..293b5d4 100644
--- a/Help/prop_tgt/XCODE_SCHEME_ADDRESS_SANITIZER_USE_AFTER_RETURN.rst
+++ b/Help/prop_tgt/XCODE_SCHEME_ADDRESS_SANITIZER_USE_AFTER_RETURN.rst
@@ -1,6 +1,8 @@
 XCODE_SCHEME_ADDRESS_SANITIZER_USE_AFTER_RETURN
 -----------------------------------------------
 
+.. versionadded:: 3.13
+
 Whether to enable ``Detect use of stack after return``
 in the Diagnostics section of the generated Xcode scheme.
 
diff --git a/Help/prop_tgt/XCODE_SCHEME_ARGUMENTS.rst b/Help/prop_tgt/XCODE_SCHEME_ARGUMENTS.rst
index 1f228e3..2bfcb41 100644
--- a/Help/prop_tgt/XCODE_SCHEME_ARGUMENTS.rst
+++ b/Help/prop_tgt/XCODE_SCHEME_ARGUMENTS.rst
@@ -1,6 +1,8 @@
 XCODE_SCHEME_ARGUMENTS
 ----------------------
 
+.. versionadded:: 3.13
+
 Specify command line arguments that should be added to the Arguments
 section of the generated Xcode scheme.
 
diff --git a/Help/prop_tgt/XCODE_SCHEME_DEBUG_AS_ROOT.rst b/Help/prop_tgt/XCODE_SCHEME_DEBUG_AS_ROOT.rst
index 5407e80..2523deb 100644
--- a/Help/prop_tgt/XCODE_SCHEME_DEBUG_AS_ROOT.rst
+++ b/Help/prop_tgt/XCODE_SCHEME_DEBUG_AS_ROOT.rst
@@ -1,6 +1,8 @@
 XCODE_SCHEME_DEBUG_AS_ROOT
 --------------------------
 
+.. versionadded:: 3.15
+
 Whether to debug the target as 'root'.
 
 Please refer to the :prop_tgt:`XCODE_GENERATE_SCHEME` target property
diff --git a/Help/prop_tgt/XCODE_SCHEME_DEBUG_DOCUMENT_VERSIONING.rst b/Help/prop_tgt/XCODE_SCHEME_DEBUG_DOCUMENT_VERSIONING.rst
index 9afeedd..bbcae35 100644
--- a/Help/prop_tgt/XCODE_SCHEME_DEBUG_DOCUMENT_VERSIONING.rst
+++ b/Help/prop_tgt/XCODE_SCHEME_DEBUG_DOCUMENT_VERSIONING.rst
@@ -1,6 +1,8 @@
 XCODE_SCHEME_DEBUG_DOCUMENT_VERSIONING
 --------------------------------------
 
+.. versionadded:: 3.16
+
 Whether to enable
 ``Allow debugging when using document Versions Browser``
 in the Options section of the generated Xcode scheme.
diff --git a/Help/prop_tgt/XCODE_SCHEME_DISABLE_MAIN_THREAD_CHECKER.rst b/Help/prop_tgt/XCODE_SCHEME_DISABLE_MAIN_THREAD_CHECKER.rst
index 1a6fcfd..3d315a2 100644
--- a/Help/prop_tgt/XCODE_SCHEME_DISABLE_MAIN_THREAD_CHECKER.rst
+++ b/Help/prop_tgt/XCODE_SCHEME_DISABLE_MAIN_THREAD_CHECKER.rst
@@ -1,6 +1,8 @@
 XCODE_SCHEME_DISABLE_MAIN_THREAD_CHECKER
 ----------------------------------------
 
+.. versionadded:: 3.13
+
 Whether to disable the ``Main Thread Checker``
 in the Diagnostics section of the generated Xcode scheme.
 
diff --git a/Help/prop_tgt/XCODE_SCHEME_DYNAMIC_LIBRARY_LOADS.rst b/Help/prop_tgt/XCODE_SCHEME_DYNAMIC_LIBRARY_LOADS.rst
index 9224022..2ca20f7 100644
--- a/Help/prop_tgt/XCODE_SCHEME_DYNAMIC_LIBRARY_LOADS.rst
+++ b/Help/prop_tgt/XCODE_SCHEME_DYNAMIC_LIBRARY_LOADS.rst
@@ -1,6 +1,8 @@
 XCODE_SCHEME_DYNAMIC_LIBRARY_LOADS
 ----------------------------------
 
+.. versionadded:: 3.13
+
 Whether to enable ``Dynamic Library Loads``
 in the Diagnostics section of the generated Xcode scheme.
 
diff --git a/Help/prop_tgt/XCODE_SCHEME_DYNAMIC_LINKER_API_USAGE.rst b/Help/prop_tgt/XCODE_SCHEME_DYNAMIC_LINKER_API_USAGE.rst
index 203c803..278c9ef 100644
--- a/Help/prop_tgt/XCODE_SCHEME_DYNAMIC_LINKER_API_USAGE.rst
+++ b/Help/prop_tgt/XCODE_SCHEME_DYNAMIC_LINKER_API_USAGE.rst
@@ -1,6 +1,8 @@
 XCODE_SCHEME_DYNAMIC_LINKER_API_USAGE
 -------------------------------------
 
+.. versionadded:: 3.13
+
 Whether to enable ``Dynamic Linker API usage``
 in the Diagnostics section of the generated Xcode scheme.
 
diff --git a/Help/prop_tgt/XCODE_SCHEME_ENVIRONMENT.rst b/Help/prop_tgt/XCODE_SCHEME_ENVIRONMENT.rst
index c6d875e..16542f8 100644
--- a/Help/prop_tgt/XCODE_SCHEME_ENVIRONMENT.rst
+++ b/Help/prop_tgt/XCODE_SCHEME_ENVIRONMENT.rst
@@ -1,6 +1,8 @@
 XCODE_SCHEME_ENVIRONMENT
 ------------------------
 
+.. versionadded:: 3.13
+
 Specify environment variables that should be added to the Arguments
 section of the generated Xcode scheme.
 
diff --git a/Help/prop_tgt/XCODE_SCHEME_EXECUTABLE.rst b/Help/prop_tgt/XCODE_SCHEME_EXECUTABLE.rst
index 104841b..b453f10 100644
--- a/Help/prop_tgt/XCODE_SCHEME_EXECUTABLE.rst
+++ b/Help/prop_tgt/XCODE_SCHEME_EXECUTABLE.rst
@@ -1,6 +1,8 @@
 XCODE_SCHEME_EXECUTABLE
 -----------------------
 
+.. versionadded:: 3.13
+
 Specify path to executable in the Info section of the generated
 Xcode scheme. If not set the schema generator will select the
 current target if it is actually executable.
diff --git a/Help/prop_tgt/XCODE_SCHEME_GUARD_MALLOC.rst b/Help/prop_tgt/XCODE_SCHEME_GUARD_MALLOC.rst
index c4e83da..4b242a2 100644
--- a/Help/prop_tgt/XCODE_SCHEME_GUARD_MALLOC.rst
+++ b/Help/prop_tgt/XCODE_SCHEME_GUARD_MALLOC.rst
@@ -1,6 +1,8 @@
 XCODE_SCHEME_GUARD_MALLOC
 ------------------------------
 
+.. versionadded:: 3.13
+
 Whether to enable ``Guard Malloc``
 in the Diagnostics section of the generated Xcode scheme.
 
diff --git a/Help/prop_tgt/XCODE_SCHEME_MAIN_THREAD_CHECKER_STOP.rst b/Help/prop_tgt/XCODE_SCHEME_MAIN_THREAD_CHECKER_STOP.rst
index 73992c3..2a813aa 100644
--- a/Help/prop_tgt/XCODE_SCHEME_MAIN_THREAD_CHECKER_STOP.rst
+++ b/Help/prop_tgt/XCODE_SCHEME_MAIN_THREAD_CHECKER_STOP.rst
@@ -1,6 +1,8 @@
 XCODE_SCHEME_MAIN_THREAD_CHECKER_STOP
 -------------------------------------
 
+.. versionadded:: 3.13
+
 Whether to enable the ``Main Thread Checker`` option
 ``Pause on issues``
 in the Diagnostics section of the generated Xcode scheme.
diff --git a/Help/prop_tgt/XCODE_SCHEME_MALLOC_GUARD_EDGES.rst b/Help/prop_tgt/XCODE_SCHEME_MALLOC_GUARD_EDGES.rst
index ca761c0..750da74 100644
--- a/Help/prop_tgt/XCODE_SCHEME_MALLOC_GUARD_EDGES.rst
+++ b/Help/prop_tgt/XCODE_SCHEME_MALLOC_GUARD_EDGES.rst
@@ -1,6 +1,8 @@
 XCODE_SCHEME_MALLOC_GUARD_EDGES
 -------------------------------
 
+.. versionadded:: 3.13
+
 Whether to enable ``Malloc Guard Edges``
 in the Diagnostics section of the generated Xcode scheme.
 
diff --git a/Help/prop_tgt/XCODE_SCHEME_MALLOC_SCRIBBLE.rst b/Help/prop_tgt/XCODE_SCHEME_MALLOC_SCRIBBLE.rst
index c5ddb95..4ebd21b 100644
--- a/Help/prop_tgt/XCODE_SCHEME_MALLOC_SCRIBBLE.rst
+++ b/Help/prop_tgt/XCODE_SCHEME_MALLOC_SCRIBBLE.rst
@@ -1,6 +1,8 @@
 XCODE_SCHEME_MALLOC_SCRIBBLE
 ------------------------------
 
+.. versionadded:: 3.13
+
 Whether to enable ``Malloc Scribble``
 in the Diagnostics section of the generated Xcode scheme.
 
diff --git a/Help/prop_tgt/XCODE_SCHEME_MALLOC_STACK.rst b/Help/prop_tgt/XCODE_SCHEME_MALLOC_STACK.rst
index 170f33d..5afe34e 100644
--- a/Help/prop_tgt/XCODE_SCHEME_MALLOC_STACK.rst
+++ b/Help/prop_tgt/XCODE_SCHEME_MALLOC_STACK.rst
@@ -1,6 +1,8 @@
 XCODE_SCHEME_MALLOC_STACK
 -------------------------
 
+.. versionadded:: 3.13
+
 Whether to enable ``Malloc Stack`` in the Diagnostics
 section of the generated Xcode scheme.
 
diff --git a/Help/prop_tgt/XCODE_SCHEME_THREAD_SANITIZER.rst b/Help/prop_tgt/XCODE_SCHEME_THREAD_SANITIZER.rst
index bb70141..cc774c4 100644
--- a/Help/prop_tgt/XCODE_SCHEME_THREAD_SANITIZER.rst
+++ b/Help/prop_tgt/XCODE_SCHEME_THREAD_SANITIZER.rst
@@ -1,6 +1,8 @@
 XCODE_SCHEME_THREAD_SANITIZER
 -----------------------------
 
+.. versionadded:: 3.13
+
 Whether to enable ``Thread Sanitizer`` in the Diagnostics
 section of the generated Xcode scheme.
 
diff --git a/Help/prop_tgt/XCODE_SCHEME_THREAD_SANITIZER_STOP.rst b/Help/prop_tgt/XCODE_SCHEME_THREAD_SANITIZER_STOP.rst
index 5deadb1..3bb2596 100644
--- a/Help/prop_tgt/XCODE_SCHEME_THREAD_SANITIZER_STOP.rst
+++ b/Help/prop_tgt/XCODE_SCHEME_THREAD_SANITIZER_STOP.rst
@@ -1,6 +1,8 @@
 XCODE_SCHEME_THREAD_SANITIZER_STOP
 ----------------------------------
 
+.. versionadded:: 3.13
+
 Whether to enable ``Thread Sanitizer - Pause on issues``
 in the Diagnostics section of the generated Xcode scheme.
 
diff --git a/Help/prop_tgt/XCODE_SCHEME_UNDEFINED_BEHAVIOUR_SANITIZER.rst b/Help/prop_tgt/XCODE_SCHEME_UNDEFINED_BEHAVIOUR_SANITIZER.rst
index 0cd823d..1146130 100644
--- a/Help/prop_tgt/XCODE_SCHEME_UNDEFINED_BEHAVIOUR_SANITIZER.rst
+++ b/Help/prop_tgt/XCODE_SCHEME_UNDEFINED_BEHAVIOUR_SANITIZER.rst
@@ -1,6 +1,8 @@
 XCODE_SCHEME_UNDEFINED_BEHAVIOUR_SANITIZER
 ------------------------------------------
 
+.. versionadded:: 3.13
+
 Whether to enable ``Undefined Behavior Sanitizer``
 in the Diagnostics section of the generated Xcode scheme.
 
diff --git a/Help/prop_tgt/XCODE_SCHEME_UNDEFINED_BEHAVIOUR_SANITIZER_STOP.rst b/Help/prop_tgt/XCODE_SCHEME_UNDEFINED_BEHAVIOUR_SANITIZER_STOP.rst
index d1a9bca..358f298 100644
--- a/Help/prop_tgt/XCODE_SCHEME_UNDEFINED_BEHAVIOUR_SANITIZER_STOP.rst
+++ b/Help/prop_tgt/XCODE_SCHEME_UNDEFINED_BEHAVIOUR_SANITIZER_STOP.rst
@@ -1,6 +1,8 @@
 XCODE_SCHEME_UNDEFINED_BEHAVIOUR_SANITIZER_STOP
 -----------------------------------------------
 
+.. versionadded:: 3.13
+
 Whether to enable ``Undefined Behavior Sanitizer`` option
 ``Pause on issues``
 in the Diagnostics section of the generated Xcode scheme.
diff --git a/Help/prop_tgt/XCODE_SCHEME_WORKING_DIRECTORY.rst b/Help/prop_tgt/XCODE_SCHEME_WORKING_DIRECTORY.rst
index f538f1d..d8d56fc 100644
--- a/Help/prop_tgt/XCODE_SCHEME_WORKING_DIRECTORY.rst
+++ b/Help/prop_tgt/XCODE_SCHEME_WORKING_DIRECTORY.rst
@@ -1,6 +1,8 @@
 XCODE_SCHEME_WORKING_DIRECTORY
 ------------------------------
 
+.. versionadded:: 3.17
+
 Specify the ``Working Directory`` of the *Run* and *Profile*
 actions in the generated Xcode scheme. In case the value contains
 generator expressions those are evaluated.
diff --git a/Help/prop_tgt/XCODE_SCHEME_ZOMBIE_OBJECTS.rst b/Help/prop_tgt/XCODE_SCHEME_ZOMBIE_OBJECTS.rst
index 6e70e8b..6030109 100644
--- a/Help/prop_tgt/XCODE_SCHEME_ZOMBIE_OBJECTS.rst
+++ b/Help/prop_tgt/XCODE_SCHEME_ZOMBIE_OBJECTS.rst
@@ -1,6 +1,8 @@
 XCODE_SCHEME_ZOMBIE_OBJECTS
 ------------------------------
 
+.. versionadded:: 3.13
+
 Whether to enable ``Zombie Objects``
 in the Diagnostics section of the generated Xcode scheme.
 
diff --git a/Help/prop_tgt/XCTEST.rst b/Help/prop_tgt/XCTEST.rst
index eb47e60..67e9a70 100644
--- a/Help/prop_tgt/XCTEST.rst
+++ b/Help/prop_tgt/XCTEST.rst
@@ -1,6 +1,8 @@
 XCTEST
 ------
 
+.. versionadded:: 3.3
+
 This target is a XCTest CFBundle on the Mac.
 
 This property will usually get set via the :command:`xctest_add_bundle`
diff --git a/Help/release/3.1.rst b/Help/release/3.1.rst
index 8bea28f..3f4712b 100644
--- a/Help/release/3.1.rst
+++ b/Help/release/3.1.rst
@@ -83,7 +83,7 @@
   :manual:`generator expression <cmake-generator-expressions(7)>`.
 
 * The :command:`string` command learned a new ``UUID`` subcommand
-  to generate a univerally unique identifier.
+  to generate a universally unique identifier.
 
 * New :command:`target_compile_features` command allows populating the
   :prop_tgt:`COMPILE_FEATURES` target property, just like any other
diff --git a/Help/release/3.10.rst b/Help/release/3.10.rst
index 03eda36..117415b 100644
--- a/Help/release/3.10.rst
+++ b/Help/release/3.10.rst
@@ -236,7 +236,7 @@
   support for C++11 and a port of libuv.  See `CMake Issue 17137`_.
   Use CMake 3.9 or lower instead for HP-UX support.
 
-.. _`CMake Issue 17137`: https://gitlab.kitware.com/cmake/cmake/issues/17137
+.. _`CMake Issue 17137`: https://gitlab.kitware.com/cmake/cmake/-/issues/17137
 
 Other Changes
 =============
diff --git a/Help/release/3.18.rst b/Help/release/3.18.rst
new file mode 100644
index 0000000..93694f6
--- /dev/null
+++ b/Help/release/3.18.rst
@@ -0,0 +1,349 @@
+CMake 3.18 Release Notes
+************************
+
+.. only:: html
+
+  .. contents::
+
+Changes made since CMake 3.17 include the following.
+
+New Features
+============
+
+Languages
+---------
+
+* The ``CUDA`` language can now be compiled using Clang on non-Windows
+  platforms. Separable compilation is not yet supported on any platform.
+
+Command-Line
+------------
+
+* :manual:`cmake(1)` gained support for profiling of CMake scripts through
+  the parameters ``--profiling-output`` and ``--profiling-format``.
+
+* :manual:`cmake(1)` gained a ``cat`` command line
+  option that can be used to concatenate files and print them
+  on standard output.
+
+Commands
+--------
+
+* The :command:`add_library` and :command:`add_executable` commands
+  learned to create :ref:`Alias Targets` referencing non-``GLOBAL``
+  :ref:`Imported Targets`.
+
+* The :command:`cmake_language()` command was added for meta-operations on
+  scripted or built-in commands, starting with a mode to ``CALL`` other
+  commands, and ``EVAL CODE`` to inplace evaluate a CMake script.
+
+* The :command:`execute_process` command gained the ``ECHO_OUTPUT_VARIABLE``
+  and ``ECHO_ERROR_VARIABLE`` options.
+
+* The :command:`export` command now raise an error if used multiple times with
+  same ``FILE`` without ``APPEND``. See policy :policy:`CMP0103`.
+
+* The :command:`file` command gained the ``ARCHIVE_CREATE`` and
+  ``ARCHIVE_EXTRACT`` subcommands to expose the :manual:`cmake(1)` ``-E tar``
+  functionality to CMake scripting code.
+
+* The :command:`file(CONFIGURE)` subcommand was created in order to replicate
+  the :command:`configure_file` functionality without resorting to a
+  pre-existing file on disk as input. The content is instead passed as a
+  string.
+
+* The :command:`file(UPLOAD)` command gained ``TLS_VERIFY`` and ``TLS_CAINFO``
+  options to control server certificate verification.
+
+* The :command:`find_program`, :command:`find_library`, :command:`find_path`
+  and :command:`find_file` commands gained a new ``REQUIRED`` option that will
+  stop processing with an error message if nothing is found.
+
+* The :command:`get_property` command with ``SOURCE`` scope gained the
+  ``DIRECTORY`` and ``TARGET_DIRECTORY`` options to get a property
+  from the provided directory scope.
+
+* The :command:`get_source_file_property` command gained the ``DIRECTORY``
+  and ``TARGET_DIRECTORY`` options to get a property from the
+  provided directory scope.
+
+* The :command:`list` operation ``SORT`` gained the ``NATURAL`` sort
+  option to sort using natural order (see ``strverscmp(3)`` manual).
+
+* The :command:`set_property` command with the ``SOURCE`` scope gained the
+  ``DIRECTORY`` and ``TARGET_DIRECTORY`` options to set properties
+  in the provided directory scopes.
+
+* The :command:`set_source_files_properties` command gained the ``DIRECTORY``
+  and ``TARGET_DIRECTORY`` options to set properties in the provided
+  directory scopes.
+
+* The :command:`string` command learned a new ``HEX`` sub-command, which
+  converts strings into their hexadecimal representation.
+
+Variables
+---------
+
+* A :variable:`CMAKE_CUDA_ARCHITECTURES` variable was added to specify
+  CUDA output architectures.  Users are encouraged to use this instead of
+  specifying options manually, as this approach is compiler-agnostic.
+  The variable is initialized automatically when
+  :variable:`CMAKE_CUDA_COMPILER_ID <CMAKE_<LANG>_COMPILER_ID>` is ``NVIDIA``.
+  The variable is used to initialize the new :prop_tgt:`CUDA_ARCHITECTURES`
+  target property.  See policy :policy:`CMP0104`.
+
+* The :variable:`CMAKE_PCH_WARN_INVALID` variable was added to initialize the
+  :prop_tgt:`PCH_WARN_INVALID` target property to allow the removal of the
+  precompiled header invalid warning.
+
+Properties
+----------
+
+* The :prop_tgt:`CUDA_ARCHITECTURES` target property was added to specify
+  CUDA output architectures. Users are encouraged to use this instead of
+  specifying options manually, as this approach is compiler-agnostic.
+  The property is initialized by the new :variable:`CMAKE_CUDA_ARCHITECTURES`
+  variable.  See policy :policy:`CMP0104`.
+
+* The :prop_tgt:`Fortran_PREPROCESS` target property and
+  :prop_sf:`Fortran_PREPROCESS` source-file property were added to
+  control preprocessing of Fortran source files.
+
+* The :prop_tgt:`FRAMEWORK_MULTI_CONFIG_POSTFIX_<CONFIG>` target property
+  and associated :variable:`CMAKE_FRAMEWORK_MULTI_CONFIG_POSTFIX_<CONFIG>`
+  variable were created to allow adding a postfix to the name of a
+  framework file name when using a multi-config generator.
+
+* The :prop_sf:`OBJECT_OUTPUTS` source file property now supports
+  :manual:`generator expressions <cmake-generator-expressions(7)>`.
+
+* The :prop_tgt:`PCH_WARN_INVALID` target property was added to allow the
+  removal of the precompiled header invalid warning.
+
+* The :prop_tgt:`UNITY_BUILD_MODE` target property was added to tell
+  generators which algorithm to use for grouping included source
+  files.
+
+* The :prop_tgt:`VS_SOURCE_SETTINGS_<tool>` target property was added
+  to tell :ref:`Visual Studio Generators` for VS 2010 and above to add
+  metadata to non-built source files using ``<tool>``.
+
+* The :prop_sf:`VS_SETTINGS` source file property was added to tell
+  :ref:`Visual Studio Generators` for VS 2010 and above to add
+  metadata to a non-built source file.
+
+* The :prop_tgt:`VS_PLATFORM_TOOLSET` target property was added to tell
+  :ref:`Visual Studio Generators` for VS 2010 and above to override
+  the platform toolset.
+
+* The :prop_tgt:`VS_SOLUTION_DEPLOY` target property was added to tell
+  :ref:`Visual Studio Generators` for VS 2010 and above to mark a
+  target for deployment even when not building for Windows Phone/Store/CE.
+
+Modules
+-------
+
+* The :module:`CheckLinkerFlag` module has been added to provide a
+  facility to check validity of link flags.
+
+* The :module:`ExternalProject` module :command:`ExternalProject_Add` command
+  gained a new ``GIT_REMOTE_UPDATE_STRATEGY`` keyword.  This can be used to
+  specify how failed rebase operations during a git update should be handled.
+  The ``CMAKE_EP_GIT_REMOTE_UPDATE_STRATEGY`` variable was also added as a
+  global default and is honored by both the :module:`ExternalProject` and
+  :module:`FetchContent` modules.
+
+* The :module:`FetchContent` module :command:`FetchContent_Declare` command
+  now supports a ``SOURCE_SUBDIR`` option.  It can be used to direct
+  :command:`FetchContent_MakeAvailable` to look in a different location
+  for the ``CMakeLists.txt`` file.
+
+* The :module:`FindBLAS` module now provides an imported target.
+
+* The :module:`FindCUDAToolkit` module:
+
+  * gained the variable
+    ``CUDAToolkit_LIBRARY_ROOT``, which is the directory containing the
+    ``nvvm`` directory and ``version.txt``.
+
+  * uses toolkit and library root found during ``CUDA`` compiler detection.
+
+* The :module:`FindLAPACK` module now provides an imported target.
+
+* The :module:`FindPython3`, :module:`FindPython2` and :module:`FindPython`
+  modules:
+
+  * gained the possibility to create per-artifact cache variables for
+    interactive editing in :manual:`cmake-gui(1)` and :manual:`ccmake(1)`.
+
+  * gained sub-components ``Development.Module`` and
+    ``Development.Embed`` under the ``Development`` component.
+
+  * gained the capability to specify which Python implementations to find,
+    including ``IronPython`` and ``PyPy``.
+
+* The :module:`FindRuby` module input and output variables were all renamed
+  from ``RUBY_`` to ``Ruby_`` for consistency with other find modules.
+  Input variables of the old case will be honored if provided, and output
+  variables of the old case are always provided.
+
+* The :module:`FindSWIG` module now accepts target languages as  ``COMPONENTS``
+  and ``OPTIONAL_COMPONENTS`` arguments to ``find_package``.
+
+* The :module:`GoogleTest` module :command:`gtest_discover_tests` command:
+
+  * gained a new ``DISCOVERY_MODE`` option to control when the test
+    discovery step is run.  It offers a new ``PRE_TEST`` setting to
+    run the discovery at test time instead of build time.  A new
+    ``CMAKE_GTEST_DISCOVER_TESTS_DISCOVERY_MODE`` variable can be used
+    to change the default globally.
+
+  * gained a new optional parameter ``XML_OUTPUT_DIR``. When set the
+    JUnit XML test results are stored in that directory.
+
+* The :module:`FindLibXslt` module now provides imported targets.
+
+* The :module:`UseSWIG` module now supports Fortran as a target language if
+  the ``SWIG_EXECUTABLE`` is SWIG-Fortran_.
+
+.. _`SWIG-Fortran`: https://github.com/swig-fortran/swig
+
+Generator Expressions
+---------------------
+
+* The ``$<DEVICE_LINK:...>`` and ``$<HOST_LINK:...>``
+  :manual:`generator expressions <cmake-generator-expressions(7)>` were added
+  to manage device and host link steps.
+
+* The ``$<LINK_LANGUAGE:...>`` and ``$<LINK_LANG_AND_ID:...>``
+  :manual:`generator expressions <cmake-generator-expressions(7)>` were added.
+
+CTest
+-----
+
+* :manual:`ctest(1)` gained a new :variable:`CTEST_RESOURCE_SPEC_FILE`
+  variable, which can be used to specify a
+  :ref:`resource specification file <ctest-resource-specification-file>`.
+
+* :manual:`ctest(1)` gained a ``--stop-on-failure`` option,
+  which can be used to stop running the tests once one has failed.
+
+* The :command:`ctest_test` command gained a ``STOP_ON_FAILURE`` option
+  which can be used to stop running the tests once one has failed.
+
+* The :module:`CTestCoverageCollectGCOV` module
+  :command:`ctest_coverage_collect_gcov` command gained a
+  ``TARBALL_COMPRESSION`` option to control compression of the
+  tarball of collected results.
+
+CPack
+-----
+
+* The :cpack_gen:`CPack Archive Generator`'s ``TXZ`` format learned the
+  :variable:`CPACK_ARCHIVE_THREADS` variable to enable parallel compression.
+  Requires support in the ``liblzma`` used by CMake.
+
+* The :cpack_gen:`CPack NSIS Generator` gained a new variable
+  :variable:`CPACK_NSIS_MANIFEST_DPI_AWARE` to declare that the
+  installer is DPI-aware.
+
+* The :cpack_gen:`CPack RPM Generator` gained
+  :variable:`CPACK_RPM_PRE_TRANS_SCRIPT_FILE` and
+  :variable:`CPACK_RPM_POST_TRANS_SCRIPT_FILE`
+  variables to specify pre- and post-transaction scripts.
+
+Other
+-----
+
+* :manual:`cmake-gui(1)` now populates its generator selection
+  widget default value from the :envvar:`CMAKE_GENERATOR` environment
+  variable.  Additionally, environment variables
+  :envvar:`CMAKE_GENERATOR_PLATFORM` and :envvar:`CMAKE_GENERATOR_TOOLSET`
+  are used to populate their respective widget defaults.
+
+* :manual:`ccmake(1)` learned to read a :envvar:`CCMAKE_COLORS`
+  environment variable to customize colors.
+
+Deprecated and Removed Features
+===============================
+
+* The :module:`Documentation` module has been deprecated via
+  :policy:`CMP0106`. This module was essentially VTK code that CMake should
+  not be shipping anymore.
+
+* An explicit deprecation diagnostic was added for policy ``CMP0070``
+  and policy ``CMP0071`` (``CMP0069`` and below were already deprecated).
+  The :manual:`cmake-policies(7)` manual explains that the OLD behaviors
+  of all policies are deprecated and that projects should port to the
+  NEW behaviors.
+
+Other Changes
+=============
+
+* On Windows, the :generator:`Ninja` and :generator:`Ninja Multi-Config`
+  generators, when a compiler is not explicitly specified, now select
+  the first compiler (of any name) found in directories listed by the
+  ``PATH`` environment variable.
+
+* The :prop_tgt:`LINK_OPTIONS` and :prop_tgt:`INTERFACE_LINK_OPTIONS` target
+  properties are now used for the device link step.
+  See policy :policy:`CMP0105`.
+
+* Creation of an ``ALIAS`` target overwriting an existing target now raises an
+  error. See policy :policy:`CMP0107`.
+
+* Linking a target to itself through an alias now raises an error.
+  See policy :policy:`CMP0108`.
+
+* The :module:`FindPackageHandleStandardArgs` module option ``REQUIRED_VARS``
+  is now optional if ``HANDLE_COMPONENTS`` is specified.
+
+* The :command:`source_group` command now also recognizes forward slashes
+  as subgroup delimiters, not just backslashes.
+
+* :manual:`ctest(1)` now logs environment variables that it sets for each test,
+  either due to the :prop_test:`ENVIRONMENT` property or the
+  :ref:`resource allocation <ctest-resource-allocation>` feature, and submits
+  this log to CDash. It does not log environment variables that were set
+  outside of CTest.
+
+* When building CMake itself from source and not using a system-provided
+  libcurl, HTTP/2 support is now enabled for commands supporting
+  network communication via ``http(s)``, such as :command:`file(DOWNLOAD)`,
+  :command:`file(UPLOAD)`, and :command:`ctest_submit`.
+  The precompiled binaries provided on ``cmake.org`` now support HTTP/2.
+
+* The :manual:`cmake-file-api(7)` "codemodel" version 2 ``version`` field has
+  been updated to 2.1.
+
+* The :manual:`cmake-file-api(7)` "codemodel" version 2 "target" object gained
+  a new ``precompileHeaders`` field in the ``compileGroups`` objects.
+
+Updates
+=======
+
+Changes made since CMake 3.18.0 include the following.
+
+3.18.1
+------
+
+* The :generator:`Xcode` generator, when :variable:`CMAKE_OSX_ARCHITECTURES`
+  is not defined, now selects ``$(NATIVE_ARCH_ACTUAL)`` as the default
+  architecture (the Xcode ``ARCHS`` setting).  This is needed for Xcode 12
+  to select the host's architecture, which older versions of Xcode did
+  by default.
+
+* In CMake 3.18.0 the :command:`add_test` command learned to support
+  special characters in test names.  This was accidentally left out of
+  its release notes.  Unfortunately the fix breaks existing projects
+  that were using manual quoting or escaping to work around the prior
+  limitation.  This fix has been reverted in 3.18.1, but may be
+  re-introduced in future versions of CMake with a policy for compatibility.
+
+3.18.2
+------
+
+* The default value of :variable:`CMAKE_AUTOMOC_PATH_PREFIX` was changed to
+  ``OFF`` because this feature can break existing projects that have
+  identically named header files in different include directories.
+  This restores compatibility with behavior of CMake 3.15 and below.
diff --git a/Help/release/3.3.rst b/Help/release/3.3.rst
index 6657e8d..44f4e19 100644
--- a/Help/release/3.3.rst
+++ b/Help/release/3.3.rst
@@ -196,7 +196,7 @@
   :prop_inst:`CPACK_START_MENU_SHORTCUTS`,
   :prop_inst:`CPACK_DESKTOP_SHORTCUTS` and
   :prop_inst:`CPACK_STARTUP_SHORTCUTS` installed file properties which can
-  be used to install shorcuts in the Start Menu, on the Desktop and
+  be used to install shortcuts in the Start Menu, on the Desktop and
   in the Startup Folder respectively.
 
 Other
diff --git a/Help/release/dev/0-sample-topic.rst b/Help/release/dev/0-sample-topic.rst
new file mode 100644
index 0000000..e4cc01e
--- /dev/null
+++ b/Help/release/dev/0-sample-topic.rst
@@ -0,0 +1,7 @@
+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/dev/CPACK_EXTERNAL_BUILT_PACKAGES.rst b/Help/release/dev/CPACK_EXTERNAL_BUILT_PACKAGES.rst
new file mode 100644
index 0000000..af446d2
--- /dev/null
+++ b/Help/release/dev/CPACK_EXTERNAL_BUILT_PACKAGES.rst
@@ -0,0 +1,4 @@
+CPACK_EXTERNAL_BUILT_PACKAGES
+-----------------------------
+
+* :cpack_gen:`CPack External Generator` learned the :variable:`CPACK_EXTERNAL_BUILT_PACKAGES` variable.
diff --git a/Help/release/dev/EXCLUDE_FROM_ALL-genex.rst b/Help/release/dev/EXCLUDE_FROM_ALL-genex.rst
new file mode 100644
index 0000000..4d5a83c
--- /dev/null
+++ b/Help/release/dev/EXCLUDE_FROM_ALL-genex.rst
@@ -0,0 +1,5 @@
+EXCLUDE_FROM_ALL-genex
+----------------------
+
+* The :prop_tgt:`EXCLUDE_FROM_ALL` target property gained support for
+  :manual:`generator expressions <cmake-generator-expressions(7)>`.
diff --git a/Help/release/dev/FindCUDAToolkit-no-nvcc.rst b/Help/release/dev/FindCUDAToolkit-no-nvcc.rst
new file mode 100644
index 0000000..e815876
--- /dev/null
+++ b/Help/release/dev/FindCUDAToolkit-no-nvcc.rst
@@ -0,0 +1,5 @@
+FindCUDAToolkit-no-nvcc
+-----------------------
+
+* The :module:`FindCUDAToolkit` module gained support for finding CUDA toolkits
+  that do not contain ``nvcc``.
diff --git a/Help/release/dev/FindSDL-update.rst b/Help/release/dev/FindSDL-update.rst
new file mode 100644
index 0000000..a85d2b9
--- /dev/null
+++ b/Help/release/dev/FindSDL-update.rst
@@ -0,0 +1,11 @@
+FindSDL-update
+--------------
+
+* The :module:`FindSDL` module now provides:
+
+  * imported target ``SDL::SDL``,
+
+  * result variables ``SDL_LIBRARIES`` and ``SDL_INCLUDE_DIRS``,
+
+  * version variables ``SDL_VERSION``, ``SDL_VERSION_MAJOR``
+    ``SDL_VERSION_MINOR``, and ``SDL_VERSION_PATCH``.
diff --git a/Help/release/dev/FindTIFF-tiffxx.rst b/Help/release/dev/FindTIFF-tiffxx.rst
new file mode 100644
index 0000000..656d38f
--- /dev/null
+++ b/Help/release/dev/FindTIFF-tiffxx.rst
@@ -0,0 +1,5 @@
+FindTIFF-tiffxx
+---------------
+
+* The :module:`FindTIFF` module gained a ``CXX`` component to
+  find the ``tiffxx`` library containing C++ bindings.
diff --git a/Help/release/dev/FindVulkan-glslc.rst b/Help/release/dev/FindVulkan-glslc.rst
new file mode 100644
index 0000000..246bc8f
--- /dev/null
+++ b/Help/release/dev/FindVulkan-glslc.rst
@@ -0,0 +1,10 @@
+FindVulkan-glslc
+----------------
+
+* The :module:`FindVulkan` module gained a new output variable
+  ``Vulkan_GLSLC_EXECUTABLE`` which contains the path to the
+  GLSL SPIR-V compiler.
+
+* The :module:`FindVulkan` module gained a new target
+  ``Vulkan::glslc`` which contains the path to the
+  GLSL SPIR-V compiler.
diff --git a/Help/release/dev/build-interface-targets.rst b/Help/release/dev/build-interface-targets.rst
new file mode 100644
index 0000000..37bded4
--- /dev/null
+++ b/Help/release/dev/build-interface-targets.rst
@@ -0,0 +1,6 @@
+build-interface-targets
+-----------------------
+
+* :ref:`Interface Libraries` may now have source files added via
+  :command:`add_library` or :command:`target_sources`.  Those
+  with sources will be generated as part of the build system.
diff --git a/Help/release/dev/clang-cl-vfs.rst b/Help/release/dev/clang-cl-vfs.rst
new file mode 100644
index 0000000..40b19ef
--- /dev/null
+++ b/Help/release/dev/clang-cl-vfs.rst
@@ -0,0 +1,6 @@
+clang-cl-vfs
+------------
+
+* A :variable:`CMAKE_CLANG_VFS_OVERLAY` variable was added to tell
+  Clang to use a VFS overlay to support the Windows SDK when
+  cross-compiling from hosts with case-sensitive filesystems.
diff --git a/Help/release/dev/cmake-E-create_hardlink.rst b/Help/release/dev/cmake-E-create_hardlink.rst
new file mode 100644
index 0000000..66cdc87
--- /dev/null
+++ b/Help/release/dev/cmake-E-create_hardlink.rst
@@ -0,0 +1,5 @@
+cmake-E-create_hardlink
+-----------------------
+
+* The :manual:`cmake(1)` gained a ``-E create_hardlink`` command-line tool
+  that can be used to create hardlinks between files.
diff --git a/Help/release/dev/compiler_flags.rst b/Help/release/dev/compiler_flags.rst
new file mode 100644
index 0000000..7138e80
--- /dev/null
+++ b/Help/release/dev/compiler_flags.rst
@@ -0,0 +1,9 @@
+compiler_flags
+-----------------
+
+* The :variable:`CMAKE_<LANG>_COMPILER` variable may now be used to
+  store "mandatory" compiler flags like the :envvar:`CC` and other environment variables.
+
+* The :variable:`CMAKE_<LANG>_FLAGS_INIT` variable will now be considered during
+  the compiler indentification check if other sources like :variable:`CMAKE_<LANG>_FLAGS`
+  or :envvar:`CFLAGS` are not set.
diff --git a/Help/release/dev/configure_file-permission-control.rst b/Help/release/dev/configure_file-permission-control.rst
new file mode 100644
index 0000000..54b52b7
--- /dev/null
+++ b/Help/release/dev/configure_file-permission-control.rst
@@ -0,0 +1,5 @@
+configure_file-permission-control
+---------------------------------
+
+* The :command:`configure_file` command gained a ``NO_SOURCE_PERMISSIONS``
+  option to suppress copying the input file's permissions to the output file.
diff --git a/Help/release/dev/cpack-pre-and-post-build-scripts.rst b/Help/release/dev/cpack-pre-and-post-build-scripts.rst
new file mode 100644
index 0000000..bf7958b
--- /dev/null
+++ b/Help/release/dev/cpack-pre-and-post-build-scripts.rst
@@ -0,0 +1,5 @@
+cpack-pre-and-post-build-scripts
+--------------------------------
+
+* CPack learned the :variable:`CPACK_PRE_BUILD_SCRIPTS`, :variable:`CPACK_POST_BUILD_SCRIPTS`,
+  and :variable:`CPACK_PACKAGE_FILES` variables.
diff --git a/Help/release/dev/ctest-cuda-memcheck.rst b/Help/release/dev/ctest-cuda-memcheck.rst
new file mode 100644
index 0000000..f8f861a
--- /dev/null
+++ b/Help/release/dev/ctest-cuda-memcheck.rst
@@ -0,0 +1,8 @@
+CTest
+-----
+
+* :manual:`ctest(1)` gained support for cuda-memcheck as ``CTEST_MEMORYCHECK_COMMAND``.
+  The different tools (memcheck, racecheck, synccheck, initcheck) supplied by
+  cuda-memcheck can be selected by setting the appropriate flags using the
+  ``CTEST_MEMORYCHECK_COMMAND_OPTIONS`` variable.
+  The default flags are `--tool memcheck --leak-check full`.
diff --git a/Help/release/dev/deprecate-policy-old.rst b/Help/release/dev/deprecate-policy-old.rst
new file mode 100644
index 0000000..1dc01cc
--- /dev/null
+++ b/Help/release/dev/deprecate-policy-old.rst
@@ -0,0 +1,13 @@
+deprecate-policy-old
+--------------------
+
+* An explicit deprecation diagnostic was added for policy ``CMP0071``
+  (``CMP0071`` and below were already deprecated).
+  The :manual:`cmake-policies(7)` manual explains that the OLD behaviors
+  of all policies are deprecated and that projects should port to the
+  NEW behaviors.
+
+* Compatibility with versions of CMake older than 2.8.12 is now deprecated
+  and will be removed from a future version.  Calls to
+  :command:`cmake_minimum_required` or :command:`cmake_policy` that set
+  the policy version to an older value now issue a deprecation diagnostic.
diff --git a/Help/release/dev/file-download-optional-file.rst b/Help/release/dev/file-download-optional-file.rst
new file mode 100644
index 0000000..f3dc24c
--- /dev/null
+++ b/Help/release/dev/file-download-optional-file.rst
@@ -0,0 +1,5 @@
+file-download-optional-file
+---------------------------
+
+* The ``<file>`` argument is now optional for :command:`file(DOWNLOAD)`. If it
+  is not specified, the file is not saved.
diff --git a/Help/release/dev/fileapi-codemodel-2.2.rst b/Help/release/dev/fileapi-codemodel-2.2.rst
new file mode 100644
index 0000000..5954df6
--- /dev/null
+++ b/Help/release/dev/fileapi-codemodel-2.2.rst
@@ -0,0 +1,7 @@
+fileapi-codemodel-2.2
+---------------------
+
+* The :manual:`cmake-file-api(7)` "codemodel" version 2 ``version`` field has
+  been updated to 2.2.
+* The :manual:`cmake-file-api(7)` "codemodel" version 2 "target" object gained
+  a new ``languageStandard`` field in the ``compileGroups`` objects.
diff --git a/Help/release/dev/find_program-exe-no-read.rst b/Help/release/dev/find_program-exe-no-read.rst
new file mode 100644
index 0000000..161b5db
--- /dev/null
+++ b/Help/release/dev/find_program-exe-no-read.rst
@@ -0,0 +1,5 @@
+find_program-exe-no-read
+------------------------
+
+* The :command:`find_program` command now requires permission to execute
+  but not to read the file found.  See policy :policy:`CMP0109`.
diff --git a/Help/release/dev/install-default-directory-permissions.rst b/Help/release/dev/install-default-directory-permissions.rst
new file mode 100644
index 0000000..27cffee
--- /dev/null
+++ b/Help/release/dev/install-default-directory-permissions.rst
@@ -0,0 +1,5 @@
+install-default-directory-permissions
+-------------------------------------
+
+* The ``--install`` argument of the :manual:`cmake(1)` command line tool gained a
+  ``--default-directory-permissions`` argument.
diff --git a/Help/release/dev/macOS-sdk-latest.rst b/Help/release/dev/macOS-sdk-latest.rst
new file mode 100644
index 0000000..c5ac3a6
--- /dev/null
+++ b/Help/release/dev/macOS-sdk-latest.rst
@@ -0,0 +1,10 @@
+macOS-sdk-latest
+----------------
+
+* Building for macOS will now use the latest SDK available on the system,
+  unless the user has explicitly chosen a SDK using :variable:`CMAKE_OSX_SYSROOT`.
+
+  The deployment target or system macOS version will not affect
+  the choice of SDK.
+
+* macOS SDKs older than 10.5 are no longer supported.
diff --git a/Help/release/dev/remove-cmake-gui-qt4.rst b/Help/release/dev/remove-cmake-gui-qt4.rst
new file mode 100644
index 0000000..2b29b75
--- /dev/null
+++ b/Help/release/dev/remove-cmake-gui-qt4.rst
@@ -0,0 +1,5 @@
+remove-cmake-gui-qt4
+--------------------
+
+* :manual:`cmake-gui(1)` now requires Qt5. Support for compiling with Qt4 has
+  been removed.
diff --git a/Help/release/dev/remove-warn-unused-vars.rst b/Help/release/dev/remove-warn-unused-vars.rst
new file mode 100644
index 0000000..7a06e91
--- /dev/null
+++ b/Help/release/dev/remove-warn-unused-vars.rst
@@ -0,0 +1,6 @@
+remove-warn-unused-vars
+-----------------------
+
+* The :manual:`cmake(1)` command-line option ``--warn-unused-vars`` has
+  been removed and is now silently ignored.  The option has not worked
+  correctly since CMake 3.3.
diff --git a/Help/release/dev/visual-studio-android.rst b/Help/release/dev/visual-studio-android.rst
new file mode 100644
index 0000000..4e1a110
--- /dev/null
+++ b/Help/release/dev/visual-studio-android.rst
@@ -0,0 +1,7 @@
+visual-studio-android
+---------------------
+
+* The :ref:`Visual Studio Generators` for Visual Studio 2015 and above gained
+  support for the Visual Studio Tools for Android. This allows you to set
+  :variable:`CMAKE_SYSTEM_NAME` to `Android` to generate `.vcxproj` files for
+  the Android tools.
diff --git a/Help/release/index.rst b/Help/release/index.rst
index 5d1f8a2..cdc3e8b 100644
--- a/Help/release/index.rst
+++ b/Help/release/index.rst
@@ -7,12 +7,15 @@
   This file should include the adjacent "dev.txt" file
   in development versions but not in release versions.
 
+.. include:: dev.txt
+
 Releases
 ========
 
 .. toctree::
    :maxdepth: 1
 
+   3.18 <3.18>
    3.17 <3.17>
    3.16 <3.16>
    3.15 <3.15>
diff --git a/Help/variable/ANDROID.rst b/Help/variable/ANDROID.rst
index fede4ca..68dccf2 100644
--- a/Help/variable/ANDROID.rst
+++ b/Help/variable/ANDROID.rst
@@ -1,5 +1,7 @@
 ANDROID
 -------
 
+.. versionadded:: 3.7
+
 Set to ``1`` when the target system (:variable:`CMAKE_SYSTEM_NAME`) is
 ``Android``.
diff --git a/Help/variable/CACHE.rst b/Help/variable/CACHE.rst
index 2cef27e..d5489c8 100644
--- a/Help/variable/CACHE.rst
+++ b/Help/variable/CACHE.rst
@@ -1,6 +1,8 @@
 CACHE
 -----
 
+.. versionadded:: 3.13
+
 Operator to read cache variables.
 
 Use the syntax ``$CACHE{VAR}`` to read cache entry ``VAR``.
diff --git a/Help/variable/CMAKE_AIX_EXPORT_ALL_SYMBOLS.rst b/Help/variable/CMAKE_AIX_EXPORT_ALL_SYMBOLS.rst
index c64dd48..699fe0f 100644
--- a/Help/variable/CMAKE_AIX_EXPORT_ALL_SYMBOLS.rst
+++ b/Help/variable/CMAKE_AIX_EXPORT_ALL_SYMBOLS.rst
@@ -1,6 +1,8 @@
 CMAKE_AIX_EXPORT_ALL_SYMBOLS
 ----------------------------
 
+.. versionadded:: 3.17
+
 Default value for :prop_tgt:`AIX_EXPORT_ALL_SYMBOLS` target property.
 This variable is used to initialize the property on each target as it is
 created.
diff --git a/Help/variable/CMAKE_ANDROID_ANT_ADDITIONAL_OPTIONS.rst b/Help/variable/CMAKE_ANDROID_ANT_ADDITIONAL_OPTIONS.rst
index 8862ba9..2d6b4b9 100644
--- a/Help/variable/CMAKE_ANDROID_ANT_ADDITIONAL_OPTIONS.rst
+++ b/Help/variable/CMAKE_ANDROID_ANT_ADDITIONAL_OPTIONS.rst
@@ -1,5 +1,7 @@
 CMAKE_ANDROID_ANT_ADDITIONAL_OPTIONS
 ------------------------------------
 
+.. versionadded:: 3.4
+
 Default value for the :prop_tgt:`ANDROID_ANT_ADDITIONAL_OPTIONS` target property.
 See that target property for additional information.
diff --git a/Help/variable/CMAKE_ANDROID_API.rst b/Help/variable/CMAKE_ANDROID_API.rst
index c07a05a..4388bf2 100644
--- a/Help/variable/CMAKE_ANDROID_API.rst
+++ b/Help/variable/CMAKE_ANDROID_API.rst
@@ -1,6 +1,8 @@
 CMAKE_ANDROID_API
 -----------------
 
+.. versionadded:: 3.1
+
 When :ref:`Cross Compiling for Android with NVIDIA Nsight Tegra Visual Studio
 Edition`, this variable may be set to specify the default value for the
 :prop_tgt:`ANDROID_API` target property.  See that target property for
diff --git a/Help/variable/CMAKE_ANDROID_API_MIN.rst b/Help/variable/CMAKE_ANDROID_API_MIN.rst
index 0246c75..a0d2ab4 100644
--- a/Help/variable/CMAKE_ANDROID_API_MIN.rst
+++ b/Help/variable/CMAKE_ANDROID_API_MIN.rst
@@ -1,5 +1,7 @@
 CMAKE_ANDROID_API_MIN
 ---------------------
 
+.. versionadded:: 3.2
+
 Default value for the :prop_tgt:`ANDROID_API_MIN` target property.
 See that target property for additional information.
diff --git a/Help/variable/CMAKE_ANDROID_ARCH.rst b/Help/variable/CMAKE_ANDROID_ARCH.rst
index b91ca57..9f12742 100644
--- a/Help/variable/CMAKE_ANDROID_ARCH.rst
+++ b/Help/variable/CMAKE_ANDROID_ARCH.rst
@@ -1,6 +1,8 @@
 CMAKE_ANDROID_ARCH
 ------------------
 
+.. versionadded:: 3.4
+
 When :ref:`Cross Compiling for Android with NVIDIA Nsight Tegra Visual Studio
 Edition`, this variable may be set to specify the default value for the
 :prop_tgt:`ANDROID_ARCH` target property.  See that target property for
diff --git a/Help/variable/CMAKE_ANDROID_ARCH_ABI.rst b/Help/variable/CMAKE_ANDROID_ARCH_ABI.rst
index 0a3ed3c..5a2e3ec 100644
--- a/Help/variable/CMAKE_ANDROID_ARCH_ABI.rst
+++ b/Help/variable/CMAKE_ANDROID_ARCH_ABI.rst
@@ -1,6 +1,8 @@
 CMAKE_ANDROID_ARCH_ABI
 ----------------------
 
+.. versionadded:: 3.7
+
 When :ref:`Cross Compiling for Android`, this variable specifies the
 target architecture and ABI to be used.  Valid values are:
 
diff --git a/Help/variable/CMAKE_ANDROID_ARM_MODE.rst b/Help/variable/CMAKE_ANDROID_ARM_MODE.rst
index ad3c37c..973ff7e 100644
--- a/Help/variable/CMAKE_ANDROID_ARM_MODE.rst
+++ b/Help/variable/CMAKE_ANDROID_ARM_MODE.rst
@@ -1,6 +1,8 @@
 CMAKE_ANDROID_ARM_MODE
 ----------------------
 
+.. versionadded:: 3.7
+
 When :ref:`Cross Compiling for Android` and :variable:`CMAKE_ANDROID_ARCH_ABI`
 is set to one of the ``armeabi`` architectures, set ``CMAKE_ANDROID_ARM_MODE``
 to ``ON`` to target 32-bit ARM processors (``-marm``).  Otherwise, the
diff --git a/Help/variable/CMAKE_ANDROID_ARM_NEON.rst b/Help/variable/CMAKE_ANDROID_ARM_NEON.rst
index 4b7ae03..6b9cf08 100644
--- a/Help/variable/CMAKE_ANDROID_ARM_NEON.rst
+++ b/Help/variable/CMAKE_ANDROID_ARM_NEON.rst
@@ -1,6 +1,8 @@
 CMAKE_ANDROID_ARM_NEON
 ----------------------
 
+.. versionadded:: 3.7
+
 When :ref:`Cross Compiling for Android` and :variable:`CMAKE_ANDROID_ARCH_ABI`
 is set to ``armeabi-v7a`` set ``CMAKE_ANDROID_ARM_NEON`` to ``ON`` to target
 ARM NEON devices.
diff --git a/Help/variable/CMAKE_ANDROID_ASSETS_DIRECTORIES.rst b/Help/variable/CMAKE_ANDROID_ASSETS_DIRECTORIES.rst
index c372fe4..3de2be4 100644
--- a/Help/variable/CMAKE_ANDROID_ASSETS_DIRECTORIES.rst
+++ b/Help/variable/CMAKE_ANDROID_ASSETS_DIRECTORIES.rst
@@ -1,5 +1,7 @@
 CMAKE_ANDROID_ASSETS_DIRECTORIES
 --------------------------------
 
+.. versionadded:: 3.4
+
 Default value for the :prop_tgt:`ANDROID_ASSETS_DIRECTORIES` target property.
 See that target property for additional information.
diff --git a/Help/variable/CMAKE_ANDROID_GUI.rst b/Help/variable/CMAKE_ANDROID_GUI.rst
index 1755375..821bbee 100644
--- a/Help/variable/CMAKE_ANDROID_GUI.rst
+++ b/Help/variable/CMAKE_ANDROID_GUI.rst
@@ -1,5 +1,7 @@
 CMAKE_ANDROID_GUI
 -----------------
 
+.. versionadded:: 3.1
+
 Default value for the :prop_tgt:`ANDROID_GUI` target property of
 executables.  See that target property for additional information.
diff --git a/Help/variable/CMAKE_ANDROID_JAR_DEPENDENCIES.rst b/Help/variable/CMAKE_ANDROID_JAR_DEPENDENCIES.rst
index 451a929..80ab842 100644
--- a/Help/variable/CMAKE_ANDROID_JAR_DEPENDENCIES.rst
+++ b/Help/variable/CMAKE_ANDROID_JAR_DEPENDENCIES.rst
@@ -1,5 +1,7 @@
 CMAKE_ANDROID_JAR_DEPENDENCIES
 ------------------------------
 
+.. versionadded:: 3.4
+
 Default value for the :prop_tgt:`ANDROID_JAR_DEPENDENCIES` target property.
 See that target property for additional information.
diff --git a/Help/variable/CMAKE_ANDROID_JAR_DIRECTORIES.rst b/Help/variable/CMAKE_ANDROID_JAR_DIRECTORIES.rst
index af83e34..4d148d8 100644
--- a/Help/variable/CMAKE_ANDROID_JAR_DIRECTORIES.rst
+++ b/Help/variable/CMAKE_ANDROID_JAR_DIRECTORIES.rst
@@ -1,5 +1,7 @@
 CMAKE_ANDROID_JAR_DIRECTORIES
 -----------------------------
 
+.. versionadded:: 3.4
+
 Default value for the :prop_tgt:`ANDROID_JAR_DIRECTORIES` target property.
 See that target property for additional information.
diff --git a/Help/variable/CMAKE_ANDROID_JAVA_SOURCE_DIR.rst b/Help/variable/CMAKE_ANDROID_JAVA_SOURCE_DIR.rst
index 3dc05e0..021baa0 100644
--- a/Help/variable/CMAKE_ANDROID_JAVA_SOURCE_DIR.rst
+++ b/Help/variable/CMAKE_ANDROID_JAVA_SOURCE_DIR.rst
@@ -1,5 +1,7 @@
 CMAKE_ANDROID_JAVA_SOURCE_DIR
 -----------------------------
 
+.. versionadded:: 3.4
+
 Default value for the :prop_tgt:`ANDROID_JAVA_SOURCE_DIR` target property.
 See that target property for additional information.
diff --git a/Help/variable/CMAKE_ANDROID_NATIVE_LIB_DEPENDENCIES.rst b/Help/variable/CMAKE_ANDROID_NATIVE_LIB_DEPENDENCIES.rst
index 4191907..41d4cc3 100644
--- a/Help/variable/CMAKE_ANDROID_NATIVE_LIB_DEPENDENCIES.rst
+++ b/Help/variable/CMAKE_ANDROID_NATIVE_LIB_DEPENDENCIES.rst
@@ -1,5 +1,7 @@
 CMAKE_ANDROID_NATIVE_LIB_DEPENDENCIES
 -------------------------------------
 
+.. versionadded:: 3.4
+
 Default value for the :prop_tgt:`ANDROID_NATIVE_LIB_DEPENDENCIES` target
 property.  See that target property for additional information.
diff --git a/Help/variable/CMAKE_ANDROID_NATIVE_LIB_DIRECTORIES.rst b/Help/variable/CMAKE_ANDROID_NATIVE_LIB_DIRECTORIES.rst
index 7cb9527..e87547d 100644
--- a/Help/variable/CMAKE_ANDROID_NATIVE_LIB_DIRECTORIES.rst
+++ b/Help/variable/CMAKE_ANDROID_NATIVE_LIB_DIRECTORIES.rst
@@ -1,5 +1,7 @@
 CMAKE_ANDROID_NATIVE_LIB_DIRECTORIES
 ------------------------------------
 
+.. versionadded:: 3.4
+
 Default value for the :prop_tgt:`ANDROID_NATIVE_LIB_DIRECTORIES` target
 property.  See that target property for additional information.
diff --git a/Help/variable/CMAKE_ANDROID_NDK.rst b/Help/variable/CMAKE_ANDROID_NDK.rst
index d241dd0..72ac99e 100644
--- a/Help/variable/CMAKE_ANDROID_NDK.rst
+++ b/Help/variable/CMAKE_ANDROID_NDK.rst
@@ -1,6 +1,8 @@
 CMAKE_ANDROID_NDK
 -----------------
 
+.. versionadded:: 3.7
+
 When :ref:`Cross Compiling for Android with the NDK`, this variable holds
 the absolute path to the root directory of the NDK.  The directory must
 contain a ``platforms`` subdirectory holding the ``android-<api>``
diff --git a/Help/variable/CMAKE_ANDROID_NDK_DEPRECATED_HEADERS.rst b/Help/variable/CMAKE_ANDROID_NDK_DEPRECATED_HEADERS.rst
index 8ea1257..40a5c1a 100644
--- a/Help/variable/CMAKE_ANDROID_NDK_DEPRECATED_HEADERS.rst
+++ b/Help/variable/CMAKE_ANDROID_NDK_DEPRECATED_HEADERS.rst
@@ -1,6 +1,8 @@
 CMAKE_ANDROID_NDK_DEPRECATED_HEADERS
 ------------------------------------
 
+.. versionadded:: 3.9
+
 When :ref:`Cross Compiling for Android with the NDK`, this variable
 may be set to specify whether to use the deprecated per-api-level
 headers instead of the unified headers.
diff --git a/Help/variable/CMAKE_ANDROID_NDK_TOOLCHAIN_HOST_TAG.rst b/Help/variable/CMAKE_ANDROID_NDK_TOOLCHAIN_HOST_TAG.rst
index 207019a..9d61fa4 100644
--- a/Help/variable/CMAKE_ANDROID_NDK_TOOLCHAIN_HOST_TAG.rst
+++ b/Help/variable/CMAKE_ANDROID_NDK_TOOLCHAIN_HOST_TAG.rst
@@ -1,6 +1,8 @@
 CMAKE_ANDROID_NDK_TOOLCHAIN_HOST_TAG
 ------------------------------------
 
+.. versionadded:: 3.7.1
+
 When :ref:`Cross Compiling for Android with the NDK`, this variable
 provides the NDK's "host tag" used to construct the path to prebuilt
 toolchains that run on the host.
diff --git a/Help/variable/CMAKE_ANDROID_NDK_TOOLCHAIN_VERSION.rst b/Help/variable/CMAKE_ANDROID_NDK_TOOLCHAIN_VERSION.rst
index 22808e3..15fe18f 100644
--- a/Help/variable/CMAKE_ANDROID_NDK_TOOLCHAIN_VERSION.rst
+++ b/Help/variable/CMAKE_ANDROID_NDK_TOOLCHAIN_VERSION.rst
@@ -1,6 +1,8 @@
 CMAKE_ANDROID_NDK_TOOLCHAIN_VERSION
 -----------------------------------
 
+.. versionadded:: 3.7
+
 When :ref:`Cross Compiling for Android with the NDK`, this variable
 may be set to specify the version of the toolchain to be used
 as the compiler.
diff --git a/Help/variable/CMAKE_ANDROID_PROCESS_MAX.rst b/Help/variable/CMAKE_ANDROID_PROCESS_MAX.rst
index 19fb527..be241c2 100644
--- a/Help/variable/CMAKE_ANDROID_PROCESS_MAX.rst
+++ b/Help/variable/CMAKE_ANDROID_PROCESS_MAX.rst
@@ -1,5 +1,7 @@
 CMAKE_ANDROID_PROCESS_MAX
 -------------------------
 
+.. versionadded:: 3.4
+
 Default value for the :prop_tgt:`ANDROID_PROCESS_MAX` target property.
 See that target property for additional information.
diff --git a/Help/variable/CMAKE_ANDROID_PROGUARD.rst b/Help/variable/CMAKE_ANDROID_PROGUARD.rst
index b8fdd46..bb001d3 100644
--- a/Help/variable/CMAKE_ANDROID_PROGUARD.rst
+++ b/Help/variable/CMAKE_ANDROID_PROGUARD.rst
@@ -1,5 +1,7 @@
 CMAKE_ANDROID_PROGUARD
 ----------------------
 
+.. versionadded:: 3.4
+
 Default value for the :prop_tgt:`ANDROID_PROGUARD` target property.
 See that target property for additional information.
diff --git a/Help/variable/CMAKE_ANDROID_PROGUARD_CONFIG_PATH.rst b/Help/variable/CMAKE_ANDROID_PROGUARD_CONFIG_PATH.rst
index 8dea009..6fd4067 100644
--- a/Help/variable/CMAKE_ANDROID_PROGUARD_CONFIG_PATH.rst
+++ b/Help/variable/CMAKE_ANDROID_PROGUARD_CONFIG_PATH.rst
@@ -1,5 +1,7 @@
 CMAKE_ANDROID_PROGUARD_CONFIG_PATH
 ----------------------------------
 
+.. versionadded:: 3.4
+
 Default value for the :prop_tgt:`ANDROID_PROGUARD_CONFIG_PATH` target property.
 See that target property for additional information.
diff --git a/Help/variable/CMAKE_ANDROID_SECURE_PROPS_PATH.rst b/Help/variable/CMAKE_ANDROID_SECURE_PROPS_PATH.rst
index 69a4d0b..9f5743e 100644
--- a/Help/variable/CMAKE_ANDROID_SECURE_PROPS_PATH.rst
+++ b/Help/variable/CMAKE_ANDROID_SECURE_PROPS_PATH.rst
@@ -1,5 +1,7 @@
 CMAKE_ANDROID_SECURE_PROPS_PATH
 -------------------------------
 
+.. versionadded:: 3.4
+
 Default value for the :prop_tgt:`ANDROID_SECURE_PROPS_PATH` target property.
 See that target property for additional information.
diff --git a/Help/variable/CMAKE_ANDROID_SKIP_ANT_STEP.rst b/Help/variable/CMAKE_ANDROID_SKIP_ANT_STEP.rst
index 0a96df9..588769b 100644
--- a/Help/variable/CMAKE_ANDROID_SKIP_ANT_STEP.rst
+++ b/Help/variable/CMAKE_ANDROID_SKIP_ANT_STEP.rst
@@ -1,5 +1,7 @@
 CMAKE_ANDROID_SKIP_ANT_STEP
 ---------------------------
 
+.. versionadded:: 3.4
+
 Default value for the :prop_tgt:`ANDROID_SKIP_ANT_STEP` target property.
 See that target property for additional information.
diff --git a/Help/variable/CMAKE_ANDROID_STANDALONE_TOOLCHAIN.rst b/Help/variable/CMAKE_ANDROID_STANDALONE_TOOLCHAIN.rst
index ea62cab..3ca89f5 100644
--- a/Help/variable/CMAKE_ANDROID_STANDALONE_TOOLCHAIN.rst
+++ b/Help/variable/CMAKE_ANDROID_STANDALONE_TOOLCHAIN.rst
@@ -1,6 +1,8 @@
 CMAKE_ANDROID_STANDALONE_TOOLCHAIN
 ----------------------------------
 
+.. versionadded:: 3.7
+
 When :ref:`Cross Compiling for Android with a Standalone Toolchain`, this
 variable holds the absolute path to the root directory of the toolchain.
 The specified directory must contain a ``sysroot`` subdirectory.
diff --git a/Help/variable/CMAKE_ANDROID_STL_TYPE.rst b/Help/variable/CMAKE_ANDROID_STL_TYPE.rst
index d174575..3778181 100644
--- a/Help/variable/CMAKE_ANDROID_STL_TYPE.rst
+++ b/Help/variable/CMAKE_ANDROID_STL_TYPE.rst
@@ -1,6 +1,8 @@
 CMAKE_ANDROID_STL_TYPE
 ----------------------
 
+.. versionadded:: 3.4
+
 When :ref:`Cross Compiling for Android with NVIDIA Nsight Tegra Visual Studio
 Edition`, this variable may be set to specify the default value for the
 :prop_tgt:`ANDROID_STL_TYPE` target property.  See that target property
diff --git a/Help/variable/CMAKE_ARCHIVE_OUTPUT_DIRECTORY_CONFIG.rst b/Help/variable/CMAKE_ARCHIVE_OUTPUT_DIRECTORY_CONFIG.rst
index 94c2b6e..d8bd82c 100644
--- a/Help/variable/CMAKE_ARCHIVE_OUTPUT_DIRECTORY_CONFIG.rst
+++ b/Help/variable/CMAKE_ARCHIVE_OUTPUT_DIRECTORY_CONFIG.rst
@@ -1,6 +1,8 @@
 CMAKE_ARCHIVE_OUTPUT_DIRECTORY_<CONFIG>
 ---------------------------------------
 
+.. versionadded:: 3.3
+
 Where to put all the :ref:`ARCHIVE <Archive Output Artifacts>`
 target files when built for a specific configuration.
 
diff --git a/Help/variable/CMAKE_AUTOGEN_ORIGIN_DEPENDS.rst b/Help/variable/CMAKE_AUTOGEN_ORIGIN_DEPENDS.rst
index 1398e78..c24e462 100644
--- a/Help/variable/CMAKE_AUTOGEN_ORIGIN_DEPENDS.rst
+++ b/Help/variable/CMAKE_AUTOGEN_ORIGIN_DEPENDS.rst
@@ -1,6 +1,8 @@
 CMAKE_AUTOGEN_ORIGIN_DEPENDS
 ----------------------------
 
+.. versionadded:: 3.14
+
 Switch for forwarding origin target dependencies to the corresponding
 ``_autogen`` targets.
 
diff --git a/Help/variable/CMAKE_AUTOGEN_PARALLEL.rst b/Help/variable/CMAKE_AUTOGEN_PARALLEL.rst
index dd9499a..2ada012 100644
--- a/Help/variable/CMAKE_AUTOGEN_PARALLEL.rst
+++ b/Help/variable/CMAKE_AUTOGEN_PARALLEL.rst
@@ -1,6 +1,8 @@
 CMAKE_AUTOGEN_PARALLEL
 ----------------------
 
+.. versionadded:: 3.11
+
 Number of parallel ``moc`` or ``uic`` processes to start when using
 :prop_tgt:`AUTOMOC` and :prop_tgt:`AUTOUIC`.
 
diff --git a/Help/variable/CMAKE_AUTOGEN_VERBOSE.rst b/Help/variable/CMAKE_AUTOGEN_VERBOSE.rst
index bad9cf2..f77ed6a 100644
--- a/Help/variable/CMAKE_AUTOGEN_VERBOSE.rst
+++ b/Help/variable/CMAKE_AUTOGEN_VERBOSE.rst
@@ -1,6 +1,8 @@
 CMAKE_AUTOGEN_VERBOSE
 ---------------------
 
+.. versionadded:: 3.13
+
 Sets the verbosity of :prop_tgt:`AUTOMOC`, :prop_tgt:`AUTOUIC` and
 :prop_tgt:`AUTORCC`.  A positive integer value or a true boolean value
 lets the ``AUTO*`` generators output additional processing information.
diff --git a/Help/variable/CMAKE_AUTOMOC_COMPILER_PREDEFINES.rst b/Help/variable/CMAKE_AUTOMOC_COMPILER_PREDEFINES.rst
index 7e1c53d..f1b03a0 100644
--- a/Help/variable/CMAKE_AUTOMOC_COMPILER_PREDEFINES.rst
+++ b/Help/variable/CMAKE_AUTOMOC_COMPILER_PREDEFINES.rst
@@ -1,6 +1,8 @@
 CMAKE_AUTOMOC_COMPILER_PREDEFINES
 ---------------------------------
 
+.. versionadded:: 3.10
+
 This variable is used to initialize the :prop_tgt:`AUTOMOC_COMPILER_PREDEFINES`
 property on all the targets. See that target property for additional
 information.
diff --git a/Help/variable/CMAKE_AUTOMOC_DEPEND_FILTERS.rst b/Help/variable/CMAKE_AUTOMOC_DEPEND_FILTERS.rst
index 5c3662d..2c1551a 100644
--- a/Help/variable/CMAKE_AUTOMOC_DEPEND_FILTERS.rst
+++ b/Help/variable/CMAKE_AUTOMOC_DEPEND_FILTERS.rst
@@ -1,6 +1,8 @@
 CMAKE_AUTOMOC_DEPEND_FILTERS
 ----------------------------
 
+.. versionadded:: 3.9
+
 Filter definitions used by :variable:`CMAKE_AUTOMOC`
 to extract file names from source code as additional dependencies
 for the ``moc`` file.
diff --git a/Help/variable/CMAKE_AUTOMOC_MACRO_NAMES.rst b/Help/variable/CMAKE_AUTOMOC_MACRO_NAMES.rst
index ba1b9d2..8e34df2 100644
--- a/Help/variable/CMAKE_AUTOMOC_MACRO_NAMES.rst
+++ b/Help/variable/CMAKE_AUTOMOC_MACRO_NAMES.rst
@@ -1,6 +1,8 @@
 CMAKE_AUTOMOC_MACRO_NAMES
 ----------------------------
 
+.. versionadded:: 3.10
+
 :ref:`Semicolon-separated list <CMake Language Lists>` list of macro names used by
 :variable:`CMAKE_AUTOMOC` to determine if a C++ file needs to be
 processed by ``moc``.
diff --git a/Help/variable/CMAKE_AUTOMOC_PATH_PREFIX.rst b/Help/variable/CMAKE_AUTOMOC_PATH_PREFIX.rst
index 1e9790f..42f48b4 100644
--- a/Help/variable/CMAKE_AUTOMOC_PATH_PREFIX.rst
+++ b/Help/variable/CMAKE_AUTOMOC_PATH_PREFIX.rst
@@ -1,6 +1,8 @@
 CMAKE_AUTOMOC_PATH_PREFIX
 -------------------------
 
+.. versionadded:: 3.16
+
 Whether to generate the ``-p`` path prefix option for ``moc`` on
 :prop_tgt:`AUTOMOC` enabled Qt targets.
 
diff --git a/Help/variable/CMAKE_AUTOUIC_SEARCH_PATHS.rst b/Help/variable/CMAKE_AUTOUIC_SEARCH_PATHS.rst
index aa132bf..0262368 100644
--- a/Help/variable/CMAKE_AUTOUIC_SEARCH_PATHS.rst
+++ b/Help/variable/CMAKE_AUTOUIC_SEARCH_PATHS.rst
@@ -1,6 +1,8 @@
 CMAKE_AUTOUIC_SEARCH_PATHS
 --------------------------
 
+.. versionadded:: 3.9
+
 Search path list used by :variable:`CMAKE_AUTOUIC` to find included
 ``.ui`` files.
 
diff --git a/Help/variable/CMAKE_BUILD_RPATH.rst b/Help/variable/CMAKE_BUILD_RPATH.rst
index f5d53b8..7a8ace7 100644
--- a/Help/variable/CMAKE_BUILD_RPATH.rst
+++ b/Help/variable/CMAKE_BUILD_RPATH.rst
@@ -1,6 +1,8 @@
 CMAKE_BUILD_RPATH
 -----------------
 
+.. versionadded:: 3.8
+
 :ref:`Semicolon-separated list <CMake Language Lists>` specifying runtime path (``RPATH``)
 entries to add to binaries linked in the build tree (for platforms that
 support it).  The entries will *not* be used for binaries in the install
diff --git a/Help/variable/CMAKE_BUILD_RPATH_USE_ORIGIN.rst b/Help/variable/CMAKE_BUILD_RPATH_USE_ORIGIN.rst
index e34ede6..ecd9278 100644
--- a/Help/variable/CMAKE_BUILD_RPATH_USE_ORIGIN.rst
+++ b/Help/variable/CMAKE_BUILD_RPATH_USE_ORIGIN.rst
@@ -1,6 +1,8 @@
 CMAKE_BUILD_RPATH_USE_ORIGIN
 ----------------------------
 
+.. versionadded:: 3.14
+
 Whether to use relative paths for the build ``RPATH``.
 
 This is used to initialize the :prop_tgt:`BUILD_RPATH_USE_ORIGIN` target
diff --git a/Help/variable/CMAKE_BUILD_WITH_INSTALL_NAME_DIR.rst b/Help/variable/CMAKE_BUILD_WITH_INSTALL_NAME_DIR.rst
index 30d5d3b..5ba775c 100644
--- a/Help/variable/CMAKE_BUILD_WITH_INSTALL_NAME_DIR.rst
+++ b/Help/variable/CMAKE_BUILD_WITH_INSTALL_NAME_DIR.rst
@@ -1,6 +1,8 @@
 CMAKE_BUILD_WITH_INSTALL_NAME_DIR
 ---------------------------------
 
+.. versionadded:: 3.9
+
 Whether to use :prop_tgt:`INSTALL_NAME_DIR` on targets in the build tree.
 
 This variable is used to initialize the :prop_tgt:`BUILD_WITH_INSTALL_NAME_DIR`
diff --git a/Help/variable/CMAKE_CLANG_VFS_OVERLAY.rst b/Help/variable/CMAKE_CLANG_VFS_OVERLAY.rst
new file mode 100644
index 0000000..56ac328
--- /dev/null
+++ b/Help/variable/CMAKE_CLANG_VFS_OVERLAY.rst
@@ -0,0 +1,9 @@
+CMAKE_CLANG_VFS_OVERLAY
+-----------------------
+
+.. versionadded:: 3.19
+
+When cross compiling for windows with clang-cl, this variable can be an
+absolute path pointing to a clang virtual file system yaml file, which
+will enable clang-cl to resolve windows header names on a case sensitive
+file system.
diff --git a/Help/variable/CMAKE_CODEBLOCKS_COMPILER_ID.rst b/Help/variable/CMAKE_CODEBLOCKS_COMPILER_ID.rst
index ad2709d..0b2b0a0 100644
--- a/Help/variable/CMAKE_CODEBLOCKS_COMPILER_ID.rst
+++ b/Help/variable/CMAKE_CODEBLOCKS_COMPILER_ID.rst
@@ -1,6 +1,8 @@
 CMAKE_CODEBLOCKS_COMPILER_ID
 ----------------------------
 
+.. versionadded:: 3.11
+
 Change the compiler id in the generated CodeBlocks project files.
 
 CodeBlocks uses its own compiler id string which differs from
diff --git a/Help/variable/CMAKE_CODEBLOCKS_EXCLUDE_EXTERNAL_FILES.rst b/Help/variable/CMAKE_CODEBLOCKS_EXCLUDE_EXTERNAL_FILES.rst
index 80ffce3..dbb8606 100644
--- a/Help/variable/CMAKE_CODEBLOCKS_EXCLUDE_EXTERNAL_FILES.rst
+++ b/Help/variable/CMAKE_CODEBLOCKS_EXCLUDE_EXTERNAL_FILES.rst
@@ -1,6 +1,8 @@
 CMAKE_CODEBLOCKS_EXCLUDE_EXTERNAL_FILES
 ---------------------------------------
 
+.. versionadded:: 3.10
+
 Change the way the CodeBlocks generator creates project files.
 
 If this variable evaluates to ``ON`` the generator excludes from
diff --git a/Help/variable/CMAKE_CODELITE_USE_TARGETS.rst b/Help/variable/CMAKE_CODELITE_USE_TARGETS.rst
index 33cdf6c..21af5f7 100644
--- a/Help/variable/CMAKE_CODELITE_USE_TARGETS.rst
+++ b/Help/variable/CMAKE_CODELITE_USE_TARGETS.rst
@@ -1,6 +1,8 @@
 CMAKE_CODELITE_USE_TARGETS
 --------------------------
 
+.. versionadded:: 3.7
+
 Change the way the CodeLite generator creates projectfiles.
 
 If this variable evaluates to ``ON`` at the end of the top-level
diff --git a/Help/variable/CMAKE_COMPILER_IS_GNUCC.rst b/Help/variable/CMAKE_COMPILER_IS_GNUCC.rst
index a40667e..91cf848 100644
--- a/Help/variable/CMAKE_COMPILER_IS_GNUCC.rst
+++ b/Help/variable/CMAKE_COMPILER_IS_GNUCC.rst
@@ -1,5 +1,7 @@
 CMAKE_COMPILER_IS_GNUCC
 -----------------------
 
+.. versionadded:: 3.7
+
 True if the ``C`` compiler is GNU.
 Use :variable:`CMAKE_C_COMPILER_ID <CMAKE_<LANG>_COMPILER_ID>` instead.
diff --git a/Help/variable/CMAKE_COMPILER_IS_GNUCXX.rst b/Help/variable/CMAKE_COMPILER_IS_GNUCXX.rst
index f1f5cf7..e67718a 100644
--- a/Help/variable/CMAKE_COMPILER_IS_GNUCXX.rst
+++ b/Help/variable/CMAKE_COMPILER_IS_GNUCXX.rst
@@ -1,5 +1,7 @@
 CMAKE_COMPILER_IS_GNUCXX
 ------------------------
 
+.. versionadded:: 3.7
+
 True if the C++ (``CXX``) compiler is GNU.
 Use :variable:`CMAKE_CXX_COMPILER_ID <CMAKE_<LANG>_COMPILER_ID>` instead.
diff --git a/Help/variable/CMAKE_COMPILER_IS_GNUG77.rst b/Help/variable/CMAKE_COMPILER_IS_GNUG77.rst
index 3d6dab4..f69c01a 100644
--- a/Help/variable/CMAKE_COMPILER_IS_GNUG77.rst
+++ b/Help/variable/CMAKE_COMPILER_IS_GNUG77.rst
@@ -1,5 +1,7 @@
 CMAKE_COMPILER_IS_GNUG77
 ------------------------
 
+.. versionadded:: 3.7
+
 True if the ``Fortran`` compiler is GNU.
 Use :variable:`CMAKE_Fortran_COMPILER_ID <CMAKE_<LANG>_COMPILER_ID>` instead.
diff --git a/Help/variable/CMAKE_COMPILE_PDB_OUTPUT_DIRECTORY.rst b/Help/variable/CMAKE_COMPILE_PDB_OUTPUT_DIRECTORY.rst
index ea33c7d..11f52c7 100644
--- a/Help/variable/CMAKE_COMPILE_PDB_OUTPUT_DIRECTORY.rst
+++ b/Help/variable/CMAKE_COMPILE_PDB_OUTPUT_DIRECTORY.rst
@@ -1,6 +1,8 @@
 CMAKE_COMPILE_PDB_OUTPUT_DIRECTORY
 ----------------------------------
 
+.. versionadded:: 3.1
+
 Output directory for MS debug symbol ``.pdb`` files
 generated by the compiler while building source files.
 
diff --git a/Help/variable/CMAKE_COMPILE_PDB_OUTPUT_DIRECTORY_CONFIG.rst b/Help/variable/CMAKE_COMPILE_PDB_OUTPUT_DIRECTORY_CONFIG.rst
index fdeb9ab..99d0bdc 100644
--- a/Help/variable/CMAKE_COMPILE_PDB_OUTPUT_DIRECTORY_CONFIG.rst
+++ b/Help/variable/CMAKE_COMPILE_PDB_OUTPUT_DIRECTORY_CONFIG.rst
@@ -1,6 +1,8 @@
 CMAKE_COMPILE_PDB_OUTPUT_DIRECTORY_<CONFIG>
 -------------------------------------------
 
+.. versionadded:: 3.1
+
 Per-configuration output directory for MS debug symbol ``.pdb`` files
 generated by the compiler while building source files.
 
diff --git a/Help/variable/CMAKE_CPACK_COMMAND.rst b/Help/variable/CMAKE_CPACK_COMMAND.rst
index 559108a..3a81d68 100644
--- a/Help/variable/CMAKE_CPACK_COMMAND.rst
+++ b/Help/variable/CMAKE_CPACK_COMMAND.rst
@@ -1,6 +1,8 @@
 CMAKE_CPACK_COMMAND
 -------------------
 
+.. versionadded:: 3.13
+
 Full path to :manual:`cpack(1)` command installed with CMake.
 
 This is the full path to the CPack executable :manual:`cpack(1)` which is
diff --git a/Help/variable/CMAKE_CROSSCOMPILING_EMULATOR.rst b/Help/variable/CMAKE_CROSSCOMPILING_EMULATOR.rst
index 1d013b7..815da00 100644
--- a/Help/variable/CMAKE_CROSSCOMPILING_EMULATOR.rst
+++ b/Help/variable/CMAKE_CROSSCOMPILING_EMULATOR.rst
@@ -1,6 +1,8 @@
 CMAKE_CROSSCOMPILING_EMULATOR
 -----------------------------
 
+.. versionadded:: 3.3
+
 This variable is only used when :variable:`CMAKE_CROSSCOMPILING` is on. It
 should point to a command on the host system that can run executable built
 for the target system.
diff --git a/Help/variable/CMAKE_CROSS_CONFIGS.rst b/Help/variable/CMAKE_CROSS_CONFIGS.rst
index 94157f3..be921d6 100644
--- a/Help/variable/CMAKE_CROSS_CONFIGS.rst
+++ b/Help/variable/CMAKE_CROSS_CONFIGS.rst
@@ -1,6 +1,8 @@
 CMAKE_CROSS_CONFIGS
 -------------------
 
+.. versionadded:: 3.17
+
 Specifies a :ref:`semicolon-separated list <CMake Language Lists>` of
 configurations available from all ``build-<Config>.ninja`` files in the
 :generator:`Ninja Multi-Config` generator.  This variable activates
diff --git a/Help/variable/CMAKE_CTEST_ARGUMENTS.rst b/Help/variable/CMAKE_CTEST_ARGUMENTS.rst
index 0940b46..4dfc8fe 100644
--- a/Help/variable/CMAKE_CTEST_ARGUMENTS.rst
+++ b/Help/variable/CMAKE_CTEST_ARGUMENTS.rst
@@ -1,6 +1,8 @@
 CMAKE_CTEST_ARGUMENTS
 ---------------------
 
+.. versionadded:: 3.17
+
 Set this to a :ref:`semicolon-separated list <CMake Language Lists>` of
 command-line arguments to pass to :manual:`ctest(1)` when running tests
 through the ``test`` (or ``RUN_TESTS``) target of the generated build system.
diff --git a/Help/variable/CMAKE_CUDA_ARCHITECTURES.rst b/Help/variable/CMAKE_CUDA_ARCHITECTURES.rst
new file mode 100644
index 0000000..985040d
--- /dev/null
+++ b/Help/variable/CMAKE_CUDA_ARCHITECTURES.rst
@@ -0,0 +1,19 @@
+CMAKE_CUDA_ARCHITECTURES
+------------------------
+
+.. versionadded:: 3.18
+
+Default value for :prop_tgt:`CUDA_ARCHITECTURES` property of targets.
+
+This is initialized as follows depending on :variable:`CMAKE_CUDA_COMPILER_ID <CMAKE_<LANG>_COMPILER_ID>`:
+
+- For ``Clang``: the oldest architecture that works.
+
+- For ``NVIDIA``: the default architecture chosen by the compiler.
+  See policy :policy:`CMP0104`.
+
+Users are encouraged to override this, as the default varies across compilers
+and compiler versions.
+
+This variable is used to initialize the :prop_tgt:`CUDA_ARCHITECTURES` property
+on all targets. See the target property for additional information.
diff --git a/Help/variable/CMAKE_CUDA_COMPILE_FEATURES.rst b/Help/variable/CMAKE_CUDA_COMPILE_FEATURES.rst
index 2cd2650..c1c270c 100644
--- a/Help/variable/CMAKE_CUDA_COMPILE_FEATURES.rst
+++ b/Help/variable/CMAKE_CUDA_COMPILE_FEATURES.rst
@@ -1,6 +1,8 @@
 CMAKE_CUDA_COMPILE_FEATURES
 ---------------------------
 
+.. versionadded:: 3.17
+
 List of features known to the CUDA compiler
 
 These features are known to be available for use with the CUDA compiler. This
diff --git a/Help/variable/CMAKE_CUDA_EXTENSIONS.rst b/Help/variable/CMAKE_CUDA_EXTENSIONS.rst
index 4fe758e..b86c0ea 100644
--- a/Help/variable/CMAKE_CUDA_EXTENSIONS.rst
+++ b/Help/variable/CMAKE_CUDA_EXTENSIONS.rst
@@ -1,6 +1,8 @@
 CMAKE_CUDA_EXTENSIONS
 ---------------------
 
+.. versionadded:: 3.8
+
 Default value for :prop_tgt:`CUDA_EXTENSIONS` property of targets.
 
 This variable is used to initialize the :prop_tgt:`CUDA_EXTENSIONS`
diff --git a/Help/variable/CMAKE_CUDA_HOST_COMPILER.rst b/Help/variable/CMAKE_CUDA_HOST_COMPILER.rst
index 6d34c5c..07342b5 100644
--- a/Help/variable/CMAKE_CUDA_HOST_COMPILER.rst
+++ b/Help/variable/CMAKE_CUDA_HOST_COMPILER.rst
@@ -1,8 +1,25 @@
 CMAKE_CUDA_HOST_COMPILER
 ------------------------
 
-Executable to use when compiling host code when compiling ``CUDA`` language
-files. Maps to the ``nvcc -ccbin`` option.  Will only be used by CMake on the first
-configuration to determine a valid host compiler for ``CUDA``. After a valid
-host compiler has been found, this value is read-only.  This variable takes
-priority over the :envvar:`CUDAHOSTCXX` environment variable.
+.. versionadded:: 3.10
+
+When :variable:`CMAKE_CUDA_COMPILER <CMAKE_<LANG>_COMPILER>` is set to
+NVIDIA ``nvcc``, ``CMAKE_CUDA_HOST_COMPILER`` selects the compiler
+executable to use when compiling host code for ``CUDA`` language files.
+This maps to the ``nvcc -ccbin`` option.
+
+The ``CMAKE_CUDA_HOST_COMPILER`` variable may be set explicitly before CUDA is
+first enabled by a :command:`project` or :command:`enable_language` command.
+This can be done via ``-DCMAKE_CUDA_HOST_COMPILER=...`` on the command line
+or in a :ref:`toolchain file <Cross Compiling Toolchain>`.  Or, one may set
+the :envvar:`CUDAHOSTCXX` environment variable to provide a default value.
+
+Once the CUDA language is enabled, the ``CMAKE_CUDA_HOST_COMPILER`` variable
+is read-only and changes to it are undefined behavior.
+
+.. note::
+
+  Since ``CMAKE_CUDA_HOST_COMPILER`` is meaningful only when the
+  ``CMAKE_CUDA_COMPILER`` is ``nvcc``, it does not make sense to
+  set ``CMAKE_CUDA_HOST_COMPILER`` explicitly without also setting
+  ``CMAKE_CUDA_COMPILER`` explicitly to be sure it is ``nvcc``.
diff --git a/Help/variable/CMAKE_CUDA_RESOLVE_DEVICE_SYMBOLS.rst b/Help/variable/CMAKE_CUDA_RESOLVE_DEVICE_SYMBOLS.rst
index fc835cd..474baee 100644
--- a/Help/variable/CMAKE_CUDA_RESOLVE_DEVICE_SYMBOLS.rst
+++ b/Help/variable/CMAKE_CUDA_RESOLVE_DEVICE_SYMBOLS.rst
@@ -1,6 +1,8 @@
 CMAKE_CUDA_RESOLVE_DEVICE_SYMBOLS
 ---------------------------------
 
+.. versionadded:: 3.16
+
 Default value for :prop_tgt:`CUDA_RESOLVE_DEVICE_SYMBOLS` target
 property. This variable is used to initialize the property on each target as
 it is created.
diff --git a/Help/variable/CMAKE_CUDA_RUNTIME_LIBRARY.rst b/Help/variable/CMAKE_CUDA_RUNTIME_LIBRARY.rst
index e3205d3..69b9d93 100644
--- a/Help/variable/CMAKE_CUDA_RUNTIME_LIBRARY.rst
+++ b/Help/variable/CMAKE_CUDA_RUNTIME_LIBRARY.rst
@@ -1,6 +1,8 @@
 CMAKE_CUDA_RUNTIME_LIBRARY
 --------------------------
 
+.. versionadded:: 3.17
+
 Select the CUDA runtime library for use when compiling and linking CUDA.
 This variable is used to initialize the :prop_tgt:`CUDA_RUNTIME_LIBRARY`
 property on all targets as they are created.
diff --git a/Help/variable/CMAKE_CUDA_SEPARABLE_COMPILATION.rst b/Help/variable/CMAKE_CUDA_SEPARABLE_COMPILATION.rst
index eef92fb..3dbaef9 100644
--- a/Help/variable/CMAKE_CUDA_SEPARABLE_COMPILATION.rst
+++ b/Help/variable/CMAKE_CUDA_SEPARABLE_COMPILATION.rst
@@ -1,6 +1,8 @@
 CMAKE_CUDA_SEPARABLE_COMPILATION
 --------------------------------
 
+.. versionadded:: 3.11
+
 Default value for :prop_tgt:`CUDA_SEPARABLE_COMPILATION` target property.
 This variable is used to initialize the property on each target as it is
 created.
diff --git a/Help/variable/CMAKE_CUDA_STANDARD.rst b/Help/variable/CMAKE_CUDA_STANDARD.rst
index 6c23031..798ab1e 100644
--- a/Help/variable/CMAKE_CUDA_STANDARD.rst
+++ b/Help/variable/CMAKE_CUDA_STANDARD.rst
@@ -1,6 +1,8 @@
 CMAKE_CUDA_STANDARD
 -------------------
 
+.. versionadded:: 3.8
+
 Default value for :prop_tgt:`CUDA_STANDARD` property of targets.
 
 This variable is used to initialize the :prop_tgt:`CUDA_STANDARD`
diff --git a/Help/variable/CMAKE_CUDA_STANDARD_REQUIRED.rst b/Help/variable/CMAKE_CUDA_STANDARD_REQUIRED.rst
index 935d605..ae2f52f 100644
--- a/Help/variable/CMAKE_CUDA_STANDARD_REQUIRED.rst
+++ b/Help/variable/CMAKE_CUDA_STANDARD_REQUIRED.rst
@@ -1,6 +1,8 @@
 CMAKE_CUDA_STANDARD_REQUIRED
 ----------------------------
 
+.. versionadded:: 3.8
+
 Default value for :prop_tgt:`CUDA_STANDARD_REQUIRED` property of targets.
 
 This variable is used to initialize the :prop_tgt:`CUDA_STANDARD_REQUIRED`
diff --git a/Help/variable/CMAKE_CUDA_TOOLKIT_INCLUDE_DIRECTORIES.rst b/Help/variable/CMAKE_CUDA_TOOLKIT_INCLUDE_DIRECTORIES.rst
index 7de50a5..e586dab 100644
--- a/Help/variable/CMAKE_CUDA_TOOLKIT_INCLUDE_DIRECTORIES.rst
+++ b/Help/variable/CMAKE_CUDA_TOOLKIT_INCLUDE_DIRECTORIES.rst
@@ -1,6 +1,8 @@
 CMAKE_CUDA_TOOLKIT_INCLUDE_DIRECTORIES
 --------------------------------------
 
+.. versionadded:: 3.8
+
 When the ``CUDA`` language has been enabled, this provides a
 :ref:`semicolon-separated list <CMake Language Lists>` of include directories provided
 by the CUDA Toolkit.  The value may be useful for C++ source files
diff --git a/Help/variable/CMAKE_CURRENT_FUNCTION.rst b/Help/variable/CMAKE_CURRENT_FUNCTION.rst
index fb7f610..5d1a4e9 100644
--- a/Help/variable/CMAKE_CURRENT_FUNCTION.rst
+++ b/Help/variable/CMAKE_CURRENT_FUNCTION.rst
@@ -1,6 +1,8 @@
 CMAKE_CURRENT_FUNCTION
 ----------------------
 
+.. versionadded:: 3.17
+
 When executing code inside a :command:`function`, this variable
 contains the name of the current function.  It can be useful for
 diagnostic or debug messages.
diff --git a/Help/variable/CMAKE_CURRENT_FUNCTION_LIST_DIR.rst b/Help/variable/CMAKE_CURRENT_FUNCTION_LIST_DIR.rst
index 44ae1e5..f8f553d 100644
--- a/Help/variable/CMAKE_CURRENT_FUNCTION_LIST_DIR.rst
+++ b/Help/variable/CMAKE_CURRENT_FUNCTION_LIST_DIR.rst
@@ -1,6 +1,8 @@
 CMAKE_CURRENT_FUNCTION_LIST_DIR
 -------------------------------
 
+.. versionadded:: 3.17
+
 When executing code inside a :command:`function`, this variable
 contains the full directory of the listfile that defined the current function.
 
diff --git a/Help/variable/CMAKE_CURRENT_FUNCTION_LIST_FILE.rst b/Help/variable/CMAKE_CURRENT_FUNCTION_LIST_FILE.rst
index c737af9..437dfec 100644
--- a/Help/variable/CMAKE_CURRENT_FUNCTION_LIST_FILE.rst
+++ b/Help/variable/CMAKE_CURRENT_FUNCTION_LIST_FILE.rst
@@ -1,6 +1,8 @@
 CMAKE_CURRENT_FUNCTION_LIST_FILE
 --------------------------------
 
+.. versionadded:: 3.17
+
 When executing code inside a :command:`function`, this variable
 contains the full path to the listfile that defined the current function.
 
diff --git a/Help/variable/CMAKE_CURRENT_FUNCTION_LIST_LINE.rst b/Help/variable/CMAKE_CURRENT_FUNCTION_LIST_LINE.rst
index ad6282e..2fc7012 100644
--- a/Help/variable/CMAKE_CURRENT_FUNCTION_LIST_LINE.rst
+++ b/Help/variable/CMAKE_CURRENT_FUNCTION_LIST_LINE.rst
@@ -1,6 +1,8 @@
 CMAKE_CURRENT_FUNCTION_LIST_LINE
 --------------------------------
 
+.. versionadded:: 3.17
+
 When executing code inside a :command:`function`, this variable
 contains the line number in the listfile where the current function
 was defined.
diff --git a/Help/variable/CMAKE_CXX_COMPILE_FEATURES.rst b/Help/variable/CMAKE_CXX_COMPILE_FEATURES.rst
index 5c59f95..8fcfbae 100644
--- a/Help/variable/CMAKE_CXX_COMPILE_FEATURES.rst
+++ b/Help/variable/CMAKE_CXX_COMPILE_FEATURES.rst
@@ -1,6 +1,8 @@
 CMAKE_CXX_COMPILE_FEATURES
 --------------------------
 
+.. versionadded:: 3.1
+
 List of features known to the C++ compiler
 
 These features are known to be available for use with the C++ compiler. This
diff --git a/Help/variable/CMAKE_CXX_EXTENSIONS.rst b/Help/variable/CMAKE_CXX_EXTENSIONS.rst
index 4a92425..ea8c4be 100644
--- a/Help/variable/CMAKE_CXX_EXTENSIONS.rst
+++ b/Help/variable/CMAKE_CXX_EXTENSIONS.rst
@@ -1,6 +1,8 @@
 CMAKE_CXX_EXTENSIONS
 --------------------
 
+.. versionadded:: 3.1
+
 Default value for :prop_tgt:`CXX_EXTENSIONS` property of targets.
 
 This variable is used to initialize the :prop_tgt:`CXX_EXTENSIONS`
diff --git a/Help/variable/CMAKE_CXX_STANDARD.rst b/Help/variable/CMAKE_CXX_STANDARD.rst
index 8a8bdff..8ef8c80 100644
--- a/Help/variable/CMAKE_CXX_STANDARD.rst
+++ b/Help/variable/CMAKE_CXX_STANDARD.rst
@@ -1,6 +1,8 @@
 CMAKE_CXX_STANDARD
 ------------------
 
+.. versionadded:: 3.1
+
 Default value for :prop_tgt:`CXX_STANDARD` property of targets.
 
 This variable is used to initialize the :prop_tgt:`CXX_STANDARD`
diff --git a/Help/variable/CMAKE_CXX_STANDARD_REQUIRED.rst b/Help/variable/CMAKE_CXX_STANDARD_REQUIRED.rst
index 4c71058..f7b2ae9 100644
--- a/Help/variable/CMAKE_CXX_STANDARD_REQUIRED.rst
+++ b/Help/variable/CMAKE_CXX_STANDARD_REQUIRED.rst
@@ -1,6 +1,8 @@
 CMAKE_CXX_STANDARD_REQUIRED
 ---------------------------
 
+.. versionadded:: 3.1
+
 Default value for :prop_tgt:`CXX_STANDARD_REQUIRED` property of targets.
 
 This variable is used to initialize the :prop_tgt:`CXX_STANDARD_REQUIRED`
diff --git a/Help/variable/CMAKE_C_COMPILE_FEATURES.rst b/Help/variable/CMAKE_C_COMPILE_FEATURES.rst
index 8d1eca0..2b306a3 100644
--- a/Help/variable/CMAKE_C_COMPILE_FEATURES.rst
+++ b/Help/variable/CMAKE_C_COMPILE_FEATURES.rst
@@ -1,6 +1,8 @@
 CMAKE_C_COMPILE_FEATURES
 ------------------------
 
+.. versionadded:: 3.1
+
 List of features known to the C compiler
 
 These features are known to be available for use with the C compiler. This
diff --git a/Help/variable/CMAKE_C_EXTENSIONS.rst b/Help/variable/CMAKE_C_EXTENSIONS.rst
index fa510d4..fce8fc7 100644
--- a/Help/variable/CMAKE_C_EXTENSIONS.rst
+++ b/Help/variable/CMAKE_C_EXTENSIONS.rst
@@ -1,6 +1,8 @@
 CMAKE_C_EXTENSIONS
 ------------------
 
+.. versionadded:: 3.1
+
 Default value for :prop_tgt:`C_EXTENSIONS` property of targets.
 
 This variable is used to initialize the :prop_tgt:`C_EXTENSIONS`
diff --git a/Help/variable/CMAKE_C_STANDARD.rst b/Help/variable/CMAKE_C_STANDARD.rst
index b55e00c..64ef8ce 100644
--- a/Help/variable/CMAKE_C_STANDARD.rst
+++ b/Help/variable/CMAKE_C_STANDARD.rst
@@ -1,6 +1,8 @@
 CMAKE_C_STANDARD
 ----------------
 
+.. versionadded:: 3.1
+
 Default value for :prop_tgt:`C_STANDARD` property of targets.
 
 This variable is used to initialize the :prop_tgt:`C_STANDARD`
diff --git a/Help/variable/CMAKE_C_STANDARD_REQUIRED.rst b/Help/variable/CMAKE_C_STANDARD_REQUIRED.rst
index 7f70f6e..e70b6bd 100644
--- a/Help/variable/CMAKE_C_STANDARD_REQUIRED.rst
+++ b/Help/variable/CMAKE_C_STANDARD_REQUIRED.rst
@@ -1,6 +1,8 @@
 CMAKE_C_STANDARD_REQUIRED
 -------------------------
 
+.. versionadded:: 3.1
+
 Default value for :prop_tgt:`C_STANDARD_REQUIRED` property of targets.
 
 This variable is used to initialize the :prop_tgt:`C_STANDARD_REQUIRED`
diff --git a/Help/variable/CMAKE_DEFAULT_BUILD_TYPE.rst b/Help/variable/CMAKE_DEFAULT_BUILD_TYPE.rst
index aa4f82d..cadbf3a 100644
--- a/Help/variable/CMAKE_DEFAULT_BUILD_TYPE.rst
+++ b/Help/variable/CMAKE_DEFAULT_BUILD_TYPE.rst
@@ -1,6 +1,8 @@
 CMAKE_DEFAULT_BUILD_TYPE
 ------------------------
 
+.. versionadded:: 3.17
+
 Specifies the configuration to use by default in a ``build.ninja`` file in the
 :generator:`Ninja Multi-Config` generator. If this variable is specified,
 ``build.ninja`` uses build rules from ``build-<Config>.ninja`` by default. All
diff --git a/Help/variable/CMAKE_DEFAULT_CONFIGS.rst b/Help/variable/CMAKE_DEFAULT_CONFIGS.rst
index 84c642a..65a5f0d 100644
--- a/Help/variable/CMAKE_DEFAULT_CONFIGS.rst
+++ b/Help/variable/CMAKE_DEFAULT_CONFIGS.rst
@@ -1,6 +1,8 @@
 CMAKE_DEFAULT_CONFIGS
 ---------------------
 
+.. versionadded:: 3.17
+
 Specifies a :ref:`semicolon-separated list <CMake Language Lists>` of configurations
 to build for a target in ``build.ninja`` if no ``:<Config>`` suffix is specified in
 the :generator:`Ninja Multi-Config` generator. If it is set to ``all``, all
diff --git a/Help/variable/CMAKE_DEPENDS_IN_PROJECT_ONLY.rst b/Help/variable/CMAKE_DEPENDS_IN_PROJECT_ONLY.rst
index 7179071..bfe9402 100644
--- a/Help/variable/CMAKE_DEPENDS_IN_PROJECT_ONLY.rst
+++ b/Help/variable/CMAKE_DEPENDS_IN_PROJECT_ONLY.rst
@@ -1,6 +1,8 @@
 CMAKE_DEPENDS_IN_PROJECT_ONLY
 -----------------------------
 
+.. versionadded:: 3.6
+
 When set to ``TRUE`` in a directory, the build system produced by the
 :ref:`Makefile Generators` is set up to only consider dependencies on source
 files that appear either in the source or in the binary directories.  Changes
diff --git a/Help/variable/CMAKE_DIRECTORY_LABELS.rst b/Help/variable/CMAKE_DIRECTORY_LABELS.rst
index 2a6c410..81d6dd1 100644
--- a/Help/variable/CMAKE_DIRECTORY_LABELS.rst
+++ b/Help/variable/CMAKE_DIRECTORY_LABELS.rst
@@ -1,6 +1,8 @@
 CMAKE_DIRECTORY_LABELS
 -----------------------
 
+.. versionadded:: 3.10
+
 Specify labels for the current directory.
 
 This is used to initialize the :prop_dir:`LABELS` directory property.
diff --git a/Help/variable/CMAKE_DISABLE_PRECOMPILE_HEADERS.rst b/Help/variable/CMAKE_DISABLE_PRECOMPILE_HEADERS.rst
index 7c30ede..cf52776 100644
--- a/Help/variable/CMAKE_DISABLE_PRECOMPILE_HEADERS.rst
+++ b/Help/variable/CMAKE_DISABLE_PRECOMPILE_HEADERS.rst
@@ -1,6 +1,8 @@
 CMAKE_DISABLE_PRECOMPILE_HEADERS
 --------------------------------
 
+.. versionadded:: 3.16
+
 Default value for :prop_tgt:`DISABLE_PRECOMPILE_HEADERS` of targets.
 
 By default ``CMAKE_DISABLE_PRECOMPILE_HEADERS`` is ``OFF``.
diff --git a/Help/variable/CMAKE_DOTNET_TARGET_FRAMEWORK.rst b/Help/variable/CMAKE_DOTNET_TARGET_FRAMEWORK.rst
index 8edcd1e..29249d6 100644
--- a/Help/variable/CMAKE_DOTNET_TARGET_FRAMEWORK.rst
+++ b/Help/variable/CMAKE_DOTNET_TARGET_FRAMEWORK.rst
@@ -1,6 +1,8 @@
 CMAKE_DOTNET_TARGET_FRAMEWORK
 -----------------------------
 
+.. versionadded:: 3.17
+
 Default value for :prop_tgt:`DOTNET_TARGET_FRAMEWORK` property	of
 targets.
 
diff --git a/Help/variable/CMAKE_DOTNET_TARGET_FRAMEWORK_VERSION.rst b/Help/variable/CMAKE_DOTNET_TARGET_FRAMEWORK_VERSION.rst
index c2eef9e..fc3c360 100644
--- a/Help/variable/CMAKE_DOTNET_TARGET_FRAMEWORK_VERSION.rst
+++ b/Help/variable/CMAKE_DOTNET_TARGET_FRAMEWORK_VERSION.rst
@@ -1,6 +1,8 @@
 CMAKE_DOTNET_TARGET_FRAMEWORK_VERSION
 -------------------------------------
 
+.. versionadded:: 3.12
+
 Default value for :prop_tgt:`DOTNET_TARGET_FRAMEWORK_VERSION`
 property of targets.
 
diff --git a/Help/variable/CMAKE_ECLIPSE_GENERATE_LINKED_RESOURCES.rst b/Help/variable/CMAKE_ECLIPSE_GENERATE_LINKED_RESOURCES.rst
index 331aae8..548c563 100644
--- a/Help/variable/CMAKE_ECLIPSE_GENERATE_LINKED_RESOURCES.rst
+++ b/Help/variable/CMAKE_ECLIPSE_GENERATE_LINKED_RESOURCES.rst
@@ -1,6 +1,8 @@
 CMAKE_ECLIPSE_GENERATE_LINKED_RESOURCES
 ---------------------------------------
 
+.. versionadded:: 3.6
+
 This cache variable is used by the Eclipse project generator.  See
 :manual:`cmake-generators(7)`.
 
diff --git a/Help/variable/CMAKE_ECLIPSE_GENERATE_SOURCE_PROJECT.rst b/Help/variable/CMAKE_ECLIPSE_GENERATE_SOURCE_PROJECT.rst
index 7b4367d..fc28ebb 100644
--- a/Help/variable/CMAKE_ECLIPSE_GENERATE_SOURCE_PROJECT.rst
+++ b/Help/variable/CMAKE_ECLIPSE_GENERATE_SOURCE_PROJECT.rst
@@ -1,6 +1,8 @@
 CMAKE_ECLIPSE_GENERATE_SOURCE_PROJECT
 -------------------------------------
 
+.. versionadded:: 3.6
+
 This cache variable is used by the Eclipse project generator.  See
 :manual:`cmake-generators(7)`.
 
diff --git a/Help/variable/CMAKE_ECLIPSE_MAKE_ARGUMENTS.rst b/Help/variable/CMAKE_ECLIPSE_MAKE_ARGUMENTS.rst
index 6e8a408..90e36f5 100644
--- a/Help/variable/CMAKE_ECLIPSE_MAKE_ARGUMENTS.rst
+++ b/Help/variable/CMAKE_ECLIPSE_MAKE_ARGUMENTS.rst
@@ -1,6 +1,8 @@
 CMAKE_ECLIPSE_MAKE_ARGUMENTS
 ----------------------------
 
+.. versionadded:: 3.6
+
 This cache variable is used by the Eclipse project generator.  See
 :manual:`cmake-generators(7)`.
 
diff --git a/Help/variable/CMAKE_ECLIPSE_RESOURCE_ENCODING.rst b/Help/variable/CMAKE_ECLIPSE_RESOURCE_ENCODING.rst
index 314efe5..492acd8 100644
--- a/Help/variable/CMAKE_ECLIPSE_RESOURCE_ENCODING.rst
+++ b/Help/variable/CMAKE_ECLIPSE_RESOURCE_ENCODING.rst
@@ -1,6 +1,8 @@
 CMAKE_ECLIPSE_RESOURCE_ENCODING
 -------------------------------
 
+.. versionadded:: 3.16
+
 This cache variable tells the :generator:`Eclipse CDT4` project generator
 to set the resource encoding to the given value in generated project files.
 If no value is given, no encoding will be set.
diff --git a/Help/variable/CMAKE_ECLIPSE_VERSION.rst b/Help/variable/CMAKE_ECLIPSE_VERSION.rst
index 8cc7882..db65d89 100644
--- a/Help/variable/CMAKE_ECLIPSE_VERSION.rst
+++ b/Help/variable/CMAKE_ECLIPSE_VERSION.rst
@@ -1,6 +1,8 @@
 CMAKE_ECLIPSE_VERSION
 ---------------------
 
+.. versionadded:: 3.6
+
 This cache variable is used by the Eclipse project generator.  See
 :manual:`cmake-generators(7)`.
 
diff --git a/Help/variable/CMAKE_ENABLE_EXPORTS.rst b/Help/variable/CMAKE_ENABLE_EXPORTS.rst
index 8848da1..9f43de3 100644
--- a/Help/variable/CMAKE_ENABLE_EXPORTS.rst
+++ b/Help/variable/CMAKE_ENABLE_EXPORTS.rst
@@ -1,6 +1,8 @@
 CMAKE_ENABLE_EXPORTS
 --------------------
 
+.. versionadded:: 3.4
+
 Specify whether executables export symbols for loadable modules.
 
 This variable is used to initialize the :prop_tgt:`ENABLE_EXPORTS` target
diff --git a/Help/variable/CMAKE_EXECUTE_PROCESS_COMMAND_ECHO.rst b/Help/variable/CMAKE_EXECUTE_PROCESS_COMMAND_ECHO.rst
index 76561d8..90a16c3 100644
--- a/Help/variable/CMAKE_EXECUTE_PROCESS_COMMAND_ECHO.rst
+++ b/Help/variable/CMAKE_EXECUTE_PROCESS_COMMAND_ECHO.rst
@@ -1,6 +1,8 @@
 CMAKE_EXECUTE_PROCESS_COMMAND_ECHO
 ----------------------------------
 
+.. versionadded:: 3.15
+
 If this variable is set to ``STDERR``, ``STDOUT`` or ``NONE`` then commands
 in :command:`execute_process` calls will be printed to either stderr or
 stdout or not at all.
diff --git a/Help/variable/CMAKE_EXE_LINKER_FLAGS_CONFIG_INIT.rst b/Help/variable/CMAKE_EXE_LINKER_FLAGS_CONFIG_INIT.rst
index 592a369..4d2718a 100644
--- a/Help/variable/CMAKE_EXE_LINKER_FLAGS_CONFIG_INIT.rst
+++ b/Help/variable/CMAKE_EXE_LINKER_FLAGS_CONFIG_INIT.rst
@@ -1,6 +1,8 @@
 CMAKE_EXE_LINKER_FLAGS_<CONFIG>_INIT
 ------------------------------------
 
+.. versionadded:: 3.7
+
 Value used to initialize the :variable:`CMAKE_EXE_LINKER_FLAGS_<CONFIG>`
 cache entry the first time a build tree is configured.
 This variable is meant to be set by a :variable:`toolchain file
diff --git a/Help/variable/CMAKE_EXE_LINKER_FLAGS_INIT.rst b/Help/variable/CMAKE_EXE_LINKER_FLAGS_INIT.rst
index 0b8afe4..6e3927c 100644
--- a/Help/variable/CMAKE_EXE_LINKER_FLAGS_INIT.rst
+++ b/Help/variable/CMAKE_EXE_LINKER_FLAGS_INIT.rst
@@ -1,6 +1,8 @@
 CMAKE_EXE_LINKER_FLAGS_INIT
 ---------------------------
 
+.. versionadded:: 3.7
+
 Value used to initialize the :variable:`CMAKE_EXE_LINKER_FLAGS`
 cache entry the first time a build tree is configured.
 This variable is meant to be set by a :variable:`toolchain file
diff --git a/Help/variable/CMAKE_EXPORT_COMPILE_COMMANDS.rst b/Help/variable/CMAKE_EXPORT_COMPILE_COMMANDS.rst
index 6d2450b..724f309 100644
--- a/Help/variable/CMAKE_EXPORT_COMPILE_COMMANDS.rst
+++ b/Help/variable/CMAKE_EXPORT_COMPILE_COMMANDS.rst
@@ -1,6 +1,8 @@
 CMAKE_EXPORT_COMPILE_COMMANDS
 -----------------------------
 
+.. versionadded:: 3.5
+
 Enable/Disable output of compile commands during generation.
 
 If enabled, generates a ``compile_commands.json`` file containing the exact
diff --git a/Help/variable/CMAKE_EXPORT_NO_PACKAGE_REGISTRY.rst b/Help/variable/CMAKE_EXPORT_NO_PACKAGE_REGISTRY.rst
index 768ed64..5772490 100644
--- a/Help/variable/CMAKE_EXPORT_NO_PACKAGE_REGISTRY.rst
+++ b/Help/variable/CMAKE_EXPORT_NO_PACKAGE_REGISTRY.rst
@@ -1,6 +1,8 @@
 CMAKE_EXPORT_NO_PACKAGE_REGISTRY
 --------------------------------
 
+.. versionadded:: 3.1
+
 Disable the :command:`export(PACKAGE)` command when :policy:`CMP0090`
 is not set to ``NEW``.
 
diff --git a/Help/variable/CMAKE_EXPORT_PACKAGE_REGISTRY.rst b/Help/variable/CMAKE_EXPORT_PACKAGE_REGISTRY.rst
index 3476a19..663639b 100644
--- a/Help/variable/CMAKE_EXPORT_PACKAGE_REGISTRY.rst
+++ b/Help/variable/CMAKE_EXPORT_PACKAGE_REGISTRY.rst
@@ -1,6 +1,8 @@
 CMAKE_EXPORT_PACKAGE_REGISTRY
 -----------------------------
 
+.. versionadded:: 3.15
+
 Enables the :command:`export(PACKAGE)` command when :policy:`CMP0090`
 is set to ``NEW``.
 
diff --git a/Help/variable/CMAKE_FIND_APPBUNDLE.rst b/Help/variable/CMAKE_FIND_APPBUNDLE.rst
index 7a05fac..17563f3 100644
--- a/Help/variable/CMAKE_FIND_APPBUNDLE.rst
+++ b/Help/variable/CMAKE_FIND_APPBUNDLE.rst
@@ -1,6 +1,8 @@
 CMAKE_FIND_APPBUNDLE
 --------------------
 
+.. versionadded:: 3.4
+
 This variable affects how ``find_*`` commands choose between
 macOS Application Bundles and unix-style package components.
 
diff --git a/Help/variable/CMAKE_FIND_DEBUG_MODE.rst b/Help/variable/CMAKE_FIND_DEBUG_MODE.rst
index f5fd8ce..8f2a82f 100644
--- a/Help/variable/CMAKE_FIND_DEBUG_MODE.rst
+++ b/Help/variable/CMAKE_FIND_DEBUG_MODE.rst
@@ -1,6 +1,8 @@
 CMAKE_FIND_DEBUG_MODE
 ---------------------
 
+.. versionadded:: 3.17
+
 Print extra find call information for the following commands to standard
 error:
 
diff --git a/Help/variable/CMAKE_FIND_FRAMEWORK.rst b/Help/variable/CMAKE_FIND_FRAMEWORK.rst
index 4d5078f..3b62cda 100644
--- a/Help/variable/CMAKE_FIND_FRAMEWORK.rst
+++ b/Help/variable/CMAKE_FIND_FRAMEWORK.rst
@@ -1,6 +1,8 @@
 CMAKE_FIND_FRAMEWORK
 --------------------
 
+.. versionadded:: 3.4
+
 This variable affects how ``find_*`` commands choose between
 macOS Frameworks and unix-style package components.
 
diff --git a/Help/variable/CMAKE_FIND_LIBRARY_CUSTOM_LIB_SUFFIX.rst b/Help/variable/CMAKE_FIND_LIBRARY_CUSTOM_LIB_SUFFIX.rst
index ada8955..ca2ad7f 100644
--- a/Help/variable/CMAKE_FIND_LIBRARY_CUSTOM_LIB_SUFFIX.rst
+++ b/Help/variable/CMAKE_FIND_LIBRARY_CUSTOM_LIB_SUFFIX.rst
@@ -1,6 +1,8 @@
 CMAKE_FIND_LIBRARY_CUSTOM_LIB_SUFFIX
 ------------------------------------
 
+.. versionadded:: 3.9
+
 Specify a ``<suffix>`` to tell the :command:`find_library` command to
 search in a ``lib<suffix>`` directory before each ``lib`` directory that
 would normally be searched.
diff --git a/Help/variable/CMAKE_FIND_PACKAGE_NAME.rst b/Help/variable/CMAKE_FIND_PACKAGE_NAME.rst
index bd1a30f..fc1fd43 100644
--- a/Help/variable/CMAKE_FIND_PACKAGE_NAME.rst
+++ b/Help/variable/CMAKE_FIND_PACKAGE_NAME.rst
@@ -1,6 +1,8 @@
 CMAKE_FIND_PACKAGE_NAME
 -----------------------
 
+.. versionadded:: 3.1.1
+
 Defined by the :command:`find_package` command while loading
 a find module to record the caller-specified package name.
 See command documentation for details.
diff --git a/Help/variable/CMAKE_FIND_PACKAGE_NO_PACKAGE_REGISTRY.rst b/Help/variable/CMAKE_FIND_PACKAGE_NO_PACKAGE_REGISTRY.rst
index 4ee9d8b..8d86a94 100644
--- a/Help/variable/CMAKE_FIND_PACKAGE_NO_PACKAGE_REGISTRY.rst
+++ b/Help/variable/CMAKE_FIND_PACKAGE_NO_PACKAGE_REGISTRY.rst
@@ -1,6 +1,8 @@
 CMAKE_FIND_PACKAGE_NO_PACKAGE_REGISTRY
 --------------------------------------
 
+.. versionadded:: 3.1
+
 .. deprecated:: 3.16
 
   Use the :variable:`CMAKE_FIND_USE_PACKAGE_REGISTRY` variable instead.
diff --git a/Help/variable/CMAKE_FIND_PACKAGE_NO_SYSTEM_PACKAGE_REGISTRY.rst b/Help/variable/CMAKE_FIND_PACKAGE_NO_SYSTEM_PACKAGE_REGISTRY.rst
index 107c183..cc67f08 100644
--- a/Help/variable/CMAKE_FIND_PACKAGE_NO_SYSTEM_PACKAGE_REGISTRY.rst
+++ b/Help/variable/CMAKE_FIND_PACKAGE_NO_SYSTEM_PACKAGE_REGISTRY.rst
@@ -1,6 +1,8 @@
 CMAKE_FIND_PACKAGE_NO_SYSTEM_PACKAGE_REGISTRY
 ---------------------------------------------
 
+.. versionadded:: 3.1
+
 .. deprecated:: 3.16
 
   Use the :variable:`CMAKE_FIND_USE_SYSTEM_PACKAGE_REGISTRY` variable instead.
diff --git a/Help/variable/CMAKE_FIND_PACKAGE_PREFER_CONFIG.rst b/Help/variable/CMAKE_FIND_PACKAGE_PREFER_CONFIG.rst
index db658a1..ba81529 100644
--- a/Help/variable/CMAKE_FIND_PACKAGE_PREFER_CONFIG.rst
+++ b/Help/variable/CMAKE_FIND_PACKAGE_PREFER_CONFIG.rst
@@ -1,6 +1,8 @@
 CMAKE_FIND_PACKAGE_PREFER_CONFIG
 ---------------------------------
 
+.. versionadded:: 3.15
+
 Tell :command:`find_package` to try "Config" mode before "Module" mode if no
 mode was specified.
 
diff --git a/Help/variable/CMAKE_FIND_PACKAGE_RESOLVE_SYMLINKS.rst b/Help/variable/CMAKE_FIND_PACKAGE_RESOLVE_SYMLINKS.rst
index dfbde20..86d75e7 100644
--- a/Help/variable/CMAKE_FIND_PACKAGE_RESOLVE_SYMLINKS.rst
+++ b/Help/variable/CMAKE_FIND_PACKAGE_RESOLVE_SYMLINKS.rst
@@ -1,6 +1,8 @@
 CMAKE_FIND_PACKAGE_RESOLVE_SYMLINKS
 -----------------------------------
 
+.. versionadded:: 3.14
+
 Set to ``TRUE`` to tell :command:`find_package` calls to resolve symbolic
 links in the value of ``<PackageName>_DIR``.
 
diff --git a/Help/variable/CMAKE_FIND_PACKAGE_SORT_DIRECTION.rst b/Help/variable/CMAKE_FIND_PACKAGE_SORT_DIRECTION.rst
index 99e4ec1..98c2a8f 100644
--- a/Help/variable/CMAKE_FIND_PACKAGE_SORT_DIRECTION.rst
+++ b/Help/variable/CMAKE_FIND_PACKAGE_SORT_DIRECTION.rst
@@ -1,6 +1,8 @@
 CMAKE_FIND_PACKAGE_SORT_DIRECTION
 ---------------------------------
 
+.. versionadded:: 3.7
+
 The sorting direction used by :variable:`CMAKE_FIND_PACKAGE_SORT_ORDER`.
 It can assume one of the following values:
 
diff --git a/Help/variable/CMAKE_FIND_PACKAGE_SORT_ORDER.rst b/Help/variable/CMAKE_FIND_PACKAGE_SORT_ORDER.rst
index ba5f3a8..1725ba1 100644
--- a/Help/variable/CMAKE_FIND_PACKAGE_SORT_ORDER.rst
+++ b/Help/variable/CMAKE_FIND_PACKAGE_SORT_ORDER.rst
@@ -1,6 +1,8 @@
 CMAKE_FIND_PACKAGE_SORT_ORDER
 -----------------------------
 
+.. versionadded:: 3.7
+
 The default order for sorting packages found using :command:`find_package`.
 It can assume one of the following values:
 
diff --git a/Help/variable/CMAKE_FIND_USE_CMAKE_ENVIRONMENT_PATH.rst b/Help/variable/CMAKE_FIND_USE_CMAKE_ENVIRONMENT_PATH.rst
index 957e956..de1bad7 100644
--- a/Help/variable/CMAKE_FIND_USE_CMAKE_ENVIRONMENT_PATH.rst
+++ b/Help/variable/CMAKE_FIND_USE_CMAKE_ENVIRONMENT_PATH.rst
@@ -1,6 +1,8 @@
 CMAKE_FIND_USE_CMAKE_ENVIRONMENT_PATH
 -------------------------------------
 
+.. versionadded:: 3.16
+
 Controls the default behavior of the following commands for whether or not to
 search paths provided by cmake-specific environment variables:
 
diff --git a/Help/variable/CMAKE_FIND_USE_CMAKE_PATH.rst b/Help/variable/CMAKE_FIND_USE_CMAKE_PATH.rst
index d2bdb09..47ce3a3 100644
--- a/Help/variable/CMAKE_FIND_USE_CMAKE_PATH.rst
+++ b/Help/variable/CMAKE_FIND_USE_CMAKE_PATH.rst
@@ -1,6 +1,8 @@
 CMAKE_FIND_USE_CMAKE_PATH
 -------------------------
 
+.. versionadded:: 3.16
+
 Controls the default behavior of the following commands for whether or not to
 search paths provided by cmake-specific cache variables:
 
diff --git a/Help/variable/CMAKE_FIND_USE_CMAKE_SYSTEM_PATH.rst b/Help/variable/CMAKE_FIND_USE_CMAKE_SYSTEM_PATH.rst
index b99081d..2fd00df 100644
--- a/Help/variable/CMAKE_FIND_USE_CMAKE_SYSTEM_PATH.rst
+++ b/Help/variable/CMAKE_FIND_USE_CMAKE_SYSTEM_PATH.rst
@@ -1,6 +1,8 @@
 CMAKE_FIND_USE_CMAKE_SYSTEM_PATH
 --------------------------------
 
+.. versionadded:: 3.16
+
 Controls the default behavior of the following commands for whether or not to
 search paths provided by platform-specific cmake variables:
 
diff --git a/Help/variable/CMAKE_FIND_USE_PACKAGE_REGISTRY.rst b/Help/variable/CMAKE_FIND_USE_PACKAGE_REGISTRY.rst
index 7c7ca36..3127206 100644
--- a/Help/variable/CMAKE_FIND_USE_PACKAGE_REGISTRY.rst
+++ b/Help/variable/CMAKE_FIND_USE_PACKAGE_REGISTRY.rst
@@ -1,6 +1,8 @@
 CMAKE_FIND_USE_PACKAGE_REGISTRY
 -------------------------------
 
+.. versionadded:: 3.16
+
 Controls the default behavior of the :command:`find_package` command for
 whether or not to search paths provided by the :ref:`User Package Registry`.
 
diff --git a/Help/variable/CMAKE_FIND_USE_PACKAGE_ROOT_PATH.rst b/Help/variable/CMAKE_FIND_USE_PACKAGE_ROOT_PATH.rst
index e7f5b0f..64e5c6d 100644
--- a/Help/variable/CMAKE_FIND_USE_PACKAGE_ROOT_PATH.rst
+++ b/Help/variable/CMAKE_FIND_USE_PACKAGE_ROOT_PATH.rst
@@ -1,6 +1,8 @@
 CMAKE_FIND_USE_PACKAGE_ROOT_PATH
 --------------------------------
 
+.. versionadded:: 3.16
+
 Controls the default behavior of the following commands for whether or not to
 search paths provided by :variable:`<PackageName>_ROOT` variables:
 
diff --git a/Help/variable/CMAKE_FIND_USE_SYSTEM_ENVIRONMENT_PATH.rst b/Help/variable/CMAKE_FIND_USE_SYSTEM_ENVIRONMENT_PATH.rst
index fbaba5a..a0a86e4 100644
--- a/Help/variable/CMAKE_FIND_USE_SYSTEM_ENVIRONMENT_PATH.rst
+++ b/Help/variable/CMAKE_FIND_USE_SYSTEM_ENVIRONMENT_PATH.rst
@@ -1,6 +1,8 @@
 CMAKE_FIND_USE_SYSTEM_ENVIRONMENT_PATH
 --------------------------------------
 
+.. versionadded:: 3.16
+
 Controls the default behavior of the following commands for whether or not to
 search paths provided by standard system environment variables:
 
diff --git a/Help/variable/CMAKE_FIND_USE_SYSTEM_PACKAGE_REGISTRY.rst b/Help/variable/CMAKE_FIND_USE_SYSTEM_PACKAGE_REGISTRY.rst
index cb4eec5..504b7e8 100644
--- a/Help/variable/CMAKE_FIND_USE_SYSTEM_PACKAGE_REGISTRY.rst
+++ b/Help/variable/CMAKE_FIND_USE_SYSTEM_PACKAGE_REGISTRY.rst
@@ -1,6 +1,8 @@
 CMAKE_FIND_USE_SYSTEM_PACKAGE_REGISTRY
 --------------------------------------
 
+.. versionadded:: 3.16
+
 Controls searching the :ref:`System Package Registry` by the
 :command:`find_package` command.
 
diff --git a/Help/variable/CMAKE_FOLDER.rst b/Help/variable/CMAKE_FOLDER.rst
index 50a2b88..37f137c 100644
--- a/Help/variable/CMAKE_FOLDER.rst
+++ b/Help/variable/CMAKE_FOLDER.rst
@@ -1,6 +1,8 @@
 CMAKE_FOLDER
 ------------
 
+.. versionadded:: 3.12
+
 Set the folder name. Use to organize targets in an IDE.
 
 This variable is used to initialize the :prop_tgt:`FOLDER` property on all the
diff --git a/Help/variable/CMAKE_FRAMEWORK.rst b/Help/variable/CMAKE_FRAMEWORK.rst
index 591041c..37385bf 100644
--- a/Help/variable/CMAKE_FRAMEWORK.rst
+++ b/Help/variable/CMAKE_FRAMEWORK.rst
@@ -1,6 +1,8 @@
 CMAKE_FRAMEWORK
 ---------------
 
+.. versionadded:: 3.15
+
 Default value for :prop_tgt:`FRAMEWORK` of targets.
 
 This variable is used to initialize the :prop_tgt:`FRAMEWORK` property on
diff --git a/Help/variable/CMAKE_FRAMEWORK_MULTI_CONFIG_POSTFIX_CONFIG.rst b/Help/variable/CMAKE_FRAMEWORK_MULTI_CONFIG_POSTFIX_CONFIG.rst
new file mode 100644
index 0000000..47fb66e
--- /dev/null
+++ b/Help/variable/CMAKE_FRAMEWORK_MULTI_CONFIG_POSTFIX_CONFIG.rst
@@ -0,0 +1,10 @@
+CMAKE_FRAMEWORK_MULTI_CONFIG_POSTFIX_<CONFIG>
+---------------------------------------------
+
+.. versionadded:: 3.18
+
+Default framework filename postfix under configuration ``<CONFIG>`` when
+using a multi-config generator.
+
+When a framework target is created its :prop_tgt:`FRAMEWORK_MULTI_CONFIG_POSTFIX_<CONFIG>`
+target property is initialized with the value of this variable if it is set.
diff --git a/Help/variable/CMAKE_Fortran_PREPROCESS.rst b/Help/variable/CMAKE_Fortran_PREPROCESS.rst
new file mode 100644
index 0000000..7d405f3
--- /dev/null
+++ b/Help/variable/CMAKE_Fortran_PREPROCESS.rst
@@ -0,0 +1,10 @@
+CMAKE_Fortran_PREPROCESS
+------------------------
+
+.. versionadded:: 3.18
+
+Default value for :prop_tgt:`Fortran_PREPROCESS` of targets.
+
+This variable is used to initialize the :prop_tgt:`Fortran_PREPROCESS`
+property on all the targets.  See that target property for additional
+information.
diff --git a/Help/variable/CMAKE_GENERATOR_INSTANCE.rst b/Help/variable/CMAKE_GENERATOR_INSTANCE.rst
index 3657ed4..5858d7a 100644
--- a/Help/variable/CMAKE_GENERATOR_INSTANCE.rst
+++ b/Help/variable/CMAKE_GENERATOR_INSTANCE.rst
@@ -1,6 +1,8 @@
 CMAKE_GENERATOR_INSTANCE
 ------------------------
 
+.. versionadded:: 3.11
+
 Generator-specific instance specification provided by user.
 
 Some CMake generators support selection of an instance of the native build
diff --git a/Help/variable/CMAKE_GENERATOR_PLATFORM.rst b/Help/variable/CMAKE_GENERATOR_PLATFORM.rst
index 2c115a3..b17d83a 100644
--- a/Help/variable/CMAKE_GENERATOR_PLATFORM.rst
+++ b/Help/variable/CMAKE_GENERATOR_PLATFORM.rst
@@ -1,6 +1,8 @@
 CMAKE_GENERATOR_PLATFORM
 ------------------------
 
+.. versionadded:: 3.1
+
 Generator-specific target platform specification provided by user.
 
 Some CMake generators support a target platform name to be given
diff --git a/Help/variable/CMAKE_GHS_NO_SOURCE_GROUP_FILE.rst b/Help/variable/CMAKE_GHS_NO_SOURCE_GROUP_FILE.rst
index b6768a1..0e8ae5e 100644
--- a/Help/variable/CMAKE_GHS_NO_SOURCE_GROUP_FILE.rst
+++ b/Help/variable/CMAKE_GHS_NO_SOURCE_GROUP_FILE.rst
@@ -1,6 +1,8 @@
 CMAKE_GHS_NO_SOURCE_GROUP_FILE
 ------------------------------
 
+.. versionadded:: 3.14
+
 ``ON`` / ``OFF`` boolean to control if the project file for a target should
 be one single file or multiple files.  Refer to
 :prop_tgt:`GHS_NO_SOURCE_GROUP_FILE` for further details.
diff --git a/Help/variable/CMAKE_GLOBAL_AUTOGEN_TARGET.rst b/Help/variable/CMAKE_GLOBAL_AUTOGEN_TARGET.rst
index 8587742..96e9907 100644
--- a/Help/variable/CMAKE_GLOBAL_AUTOGEN_TARGET.rst
+++ b/Help/variable/CMAKE_GLOBAL_AUTOGEN_TARGET.rst
@@ -1,6 +1,8 @@
 CMAKE_GLOBAL_AUTOGEN_TARGET
 ---------------------------
 
+.. versionadded:: 3.14
+
 Switch to enable generation of a global ``autogen`` target.
 
 When :variable:`CMAKE_GLOBAL_AUTOGEN_TARGET` is enabled, a custom target
diff --git a/Help/variable/CMAKE_GLOBAL_AUTOGEN_TARGET_NAME.rst b/Help/variable/CMAKE_GLOBAL_AUTOGEN_TARGET_NAME.rst
index c86a5d0..4af4bc3 100644
--- a/Help/variable/CMAKE_GLOBAL_AUTOGEN_TARGET_NAME.rst
+++ b/Help/variable/CMAKE_GLOBAL_AUTOGEN_TARGET_NAME.rst
@@ -1,6 +1,8 @@
 CMAKE_GLOBAL_AUTOGEN_TARGET_NAME
 --------------------------------
 
+.. versionadded:: 3.14
+
 Change the name of the global ``autogen`` target.
 
 When :variable:`CMAKE_GLOBAL_AUTOGEN_TARGET` is enabled, a global custom target
diff --git a/Help/variable/CMAKE_GLOBAL_AUTORCC_TARGET.rst b/Help/variable/CMAKE_GLOBAL_AUTORCC_TARGET.rst
index f92128c..efea5be 100644
--- a/Help/variable/CMAKE_GLOBAL_AUTORCC_TARGET.rst
+++ b/Help/variable/CMAKE_GLOBAL_AUTORCC_TARGET.rst
@@ -1,6 +1,8 @@
 CMAKE_GLOBAL_AUTORCC_TARGET
 ---------------------------
 
+.. versionadded:: 3.14
+
 Switch to enable generation of a global ``autorcc`` target.
 
 When :variable:`CMAKE_GLOBAL_AUTORCC_TARGET` is enabled, a custom target
diff --git a/Help/variable/CMAKE_GLOBAL_AUTORCC_TARGET_NAME.rst b/Help/variable/CMAKE_GLOBAL_AUTORCC_TARGET_NAME.rst
index c6e05de..4d2e313 100644
--- a/Help/variable/CMAKE_GLOBAL_AUTORCC_TARGET_NAME.rst
+++ b/Help/variable/CMAKE_GLOBAL_AUTORCC_TARGET_NAME.rst
@@ -1,6 +1,8 @@
 CMAKE_GLOBAL_AUTORCC_TARGET_NAME
 --------------------------------
 
+.. versionadded:: 3.14
+
 Change the name of the global ``autorcc`` target.
 
 When :variable:`CMAKE_GLOBAL_AUTORCC_TARGET` is enabled, a global custom target
diff --git a/Help/variable/CMAKE_HOST_SOLARIS.rst b/Help/variable/CMAKE_HOST_SOLARIS.rst
index 82b5d69..7054acd 100644
--- a/Help/variable/CMAKE_HOST_SOLARIS.rst
+++ b/Help/variable/CMAKE_HOST_SOLARIS.rst
@@ -1,6 +1,8 @@
 CMAKE_HOST_SOLARIS
 ------------------
 
+.. versionadded:: 3.6
+
 ``True`` for Oracle Solaris operating systems.
 
 Set to ``true`` when the host system is Oracle Solaris.
diff --git a/Help/variable/CMAKE_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS.rst b/Help/variable/CMAKE_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS.rst
index f994fbe..aad99e4 100644
--- a/Help/variable/CMAKE_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS.rst
+++ b/Help/variable/CMAKE_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS.rst
@@ -1,6 +1,8 @@
 CMAKE_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS
 -------------------------------------------
 
+.. versionadded:: 3.11
+
 Default permissions for directories created implicitly during installation
 of files by :command:`install` and :command:`file(INSTALL)`.
 
diff --git a/Help/variable/CMAKE_INSTALL_MESSAGE.rst b/Help/variable/CMAKE_INSTALL_MESSAGE.rst
index 304df26..4f39cfe 100644
--- a/Help/variable/CMAKE_INSTALL_MESSAGE.rst
+++ b/Help/variable/CMAKE_INSTALL_MESSAGE.rst
@@ -1,6 +1,8 @@
 CMAKE_INSTALL_MESSAGE
 ---------------------
 
+.. versionadded:: 3.1
+
 Specify verbosity of installation script code generated by the
 :command:`install` command (using the :command:`file(INSTALL)` command).
 For paths that are newly installed or updated, installation
diff --git a/Help/variable/CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT.rst b/Help/variable/CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT.rst
index 2a5842d..93cc319 100644
--- a/Help/variable/CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT.rst
+++ b/Help/variable/CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT.rst
@@ -1,6 +1,8 @@
 CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT
 -------------------------------------------
 
+.. versionadded:: 3.7.1
+
 CMake sets this variable to a ``TRUE`` value when the
 :variable:`CMAKE_INSTALL_PREFIX` has just been initialized to
 its default value, typically on the first run of CMake within
diff --git a/Help/variable/CMAKE_INSTALL_REMOVE_ENVIRONMENT_RPATH.rst b/Help/variable/CMAKE_INSTALL_REMOVE_ENVIRONMENT_RPATH.rst
index 76ca3da..c86e433 100644
--- a/Help/variable/CMAKE_INSTALL_REMOVE_ENVIRONMENT_RPATH.rst
+++ b/Help/variable/CMAKE_INSTALL_REMOVE_ENVIRONMENT_RPATH.rst
@@ -1,6 +1,8 @@
 CMAKE_INSTALL_REMOVE_ENVIRONMENT_RPATH
 --------------------------------------
 
+.. versionadded:: 3.16
+
 Sets the default for whether toolchain-defined rpaths should be removed during
 installation.
 
diff --git a/Help/variable/CMAKE_INTERPROCEDURAL_OPTIMIZATION.rst b/Help/variable/CMAKE_INTERPROCEDURAL_OPTIMIZATION.rst
index b0cbb62..cf7da76 100644
--- a/Help/variable/CMAKE_INTERPROCEDURAL_OPTIMIZATION.rst
+++ b/Help/variable/CMAKE_INTERPROCEDURAL_OPTIMIZATION.rst
@@ -1,6 +1,8 @@
 CMAKE_INTERPROCEDURAL_OPTIMIZATION
 ----------------------------------
 
+.. versionadded:: 3.9
+
 Default value for :prop_tgt:`INTERPROCEDURAL_OPTIMIZATION` of targets.
 
 This variable is used to initialize the :prop_tgt:`INTERPROCEDURAL_OPTIMIZATION`
diff --git a/Help/variable/CMAKE_INTERPROCEDURAL_OPTIMIZATION_CONFIG.rst b/Help/variable/CMAKE_INTERPROCEDURAL_OPTIMIZATION_CONFIG.rst
index b291102..5b3ee77 100644
--- a/Help/variable/CMAKE_INTERPROCEDURAL_OPTIMIZATION_CONFIG.rst
+++ b/Help/variable/CMAKE_INTERPROCEDURAL_OPTIMIZATION_CONFIG.rst
@@ -1,6 +1,8 @@
 CMAKE_INTERPROCEDURAL_OPTIMIZATION_<CONFIG>
 -------------------------------------------
 
+.. versionadded:: 3.9
+
 Default value for :prop_tgt:`INTERPROCEDURAL_OPTIMIZATION_<CONFIG>` of targets.
 
 This variable is used to initialize the :prop_tgt:`INTERPROCEDURAL_OPTIMIZATION_<CONFIG>`
diff --git a/Help/variable/CMAKE_IOS_INSTALL_COMBINED.rst b/Help/variable/CMAKE_IOS_INSTALL_COMBINED.rst
index c5cb9b6..cd7fd8d 100644
--- a/Help/variable/CMAKE_IOS_INSTALL_COMBINED.rst
+++ b/Help/variable/CMAKE_IOS_INSTALL_COMBINED.rst
@@ -1,6 +1,8 @@
 CMAKE_IOS_INSTALL_COMBINED
 --------------------------
 
+.. versionadded:: 3.5
+
 Default value for :prop_tgt:`IOS_INSTALL_COMBINED` of targets.
 
 This variable is used to initialize the :prop_tgt:`IOS_INSTALL_COMBINED`
diff --git a/Help/variable/CMAKE_JOB_POOLS.rst b/Help/variable/CMAKE_JOB_POOLS.rst
index 72b50b4..43d3c84 100644
--- a/Help/variable/CMAKE_JOB_POOLS.rst
+++ b/Help/variable/CMAKE_JOB_POOLS.rst
@@ -1,6 +1,8 @@
 CMAKE_JOB_POOLS
 ---------------
 
+.. versionadded:: 3.11
+
 If the :prop_gbl:`JOB_POOLS` global property is not set, the value
 of this variable is used in its place.  See :prop_gbl:`JOB_POOLS`
 for additional information.
diff --git a/Help/variable/CMAKE_JOB_POOL_PRECOMPILE_HEADER.rst b/Help/variable/CMAKE_JOB_POOL_PRECOMPILE_HEADER.rst
index f9467b3..1a6f66a 100644
--- a/Help/variable/CMAKE_JOB_POOL_PRECOMPILE_HEADER.rst
+++ b/Help/variable/CMAKE_JOB_POOL_PRECOMPILE_HEADER.rst
@@ -1,6 +1,8 @@
 CMAKE_JOB_POOL_PRECOMPILE_HEADER
 --------------------------------
 
+.. versionadded:: 3.17
+
 This variable is used to initialize the :prop_tgt:`JOB_POOL_PRECOMPILE_HEADER`
 property on all the targets. See :prop_tgt:`JOB_POOL_PRECOMPILE_HEADER`
 for additional information.
diff --git a/Help/variable/CMAKE_LANG_ANDROID_TOOLCHAIN_MACHINE.rst b/Help/variable/CMAKE_LANG_ANDROID_TOOLCHAIN_MACHINE.rst
index d336364..f539277 100644
--- a/Help/variable/CMAKE_LANG_ANDROID_TOOLCHAIN_MACHINE.rst
+++ b/Help/variable/CMAKE_LANG_ANDROID_TOOLCHAIN_MACHINE.rst
@@ -1,6 +1,8 @@
 CMAKE_<LANG>_ANDROID_TOOLCHAIN_MACHINE
 --------------------------------------
 
+.. versionadded:: 3.7.1
+
 When :ref:`Cross Compiling for Android` this variable contains the
 toolchain binutils machine name (e.g. ``gcc -dumpmachine``).  The
 binutils typically have a ``<machine>-`` prefix on their name.
diff --git a/Help/variable/CMAKE_LANG_ANDROID_TOOLCHAIN_PREFIX.rst b/Help/variable/CMAKE_LANG_ANDROID_TOOLCHAIN_PREFIX.rst
index db04af3..ff072ca 100644
--- a/Help/variable/CMAKE_LANG_ANDROID_TOOLCHAIN_PREFIX.rst
+++ b/Help/variable/CMAKE_LANG_ANDROID_TOOLCHAIN_PREFIX.rst
@@ -1,6 +1,8 @@
 CMAKE_<LANG>_ANDROID_TOOLCHAIN_PREFIX
 -------------------------------------
 
+.. versionadded:: 3.7
+
 When :ref:`Cross Compiling for Android` this variable contains the absolute
 path prefixing the toolchain GNU compiler and its binutils.
 
diff --git a/Help/variable/CMAKE_LANG_ANDROID_TOOLCHAIN_SUFFIX.rst b/Help/variable/CMAKE_LANG_ANDROID_TOOLCHAIN_SUFFIX.rst
index 159eb22..d595280 100644
--- a/Help/variable/CMAKE_LANG_ANDROID_TOOLCHAIN_SUFFIX.rst
+++ b/Help/variable/CMAKE_LANG_ANDROID_TOOLCHAIN_SUFFIX.rst
@@ -1,6 +1,8 @@
 CMAKE_<LANG>_ANDROID_TOOLCHAIN_SUFFIX
 -------------------------------------
 
+.. versionadded:: 3.7
+
 When :ref:`Cross Compiling for Android` this variable contains the
 host platform suffix of the toolchain GNU compiler and its binutils.
 
diff --git a/Help/variable/CMAKE_LANG_CLANG_TIDY.rst b/Help/variable/CMAKE_LANG_CLANG_TIDY.rst
index bd49de3..78f0f6a 100644
--- a/Help/variable/CMAKE_LANG_CLANG_TIDY.rst
+++ b/Help/variable/CMAKE_LANG_CLANG_TIDY.rst
@@ -1,6 +1,8 @@
 CMAKE_<LANG>_CLANG_TIDY
 -----------------------
 
+.. versionadded:: 3.6
+
 Default value for :prop_tgt:`<LANG>_CLANG_TIDY` target property
 when ``<LANG>`` is ``C`` or ``CXX``.
 
diff --git a/Help/variable/CMAKE_LANG_COMPILER.rst b/Help/variable/CMAKE_LANG_COMPILER.rst
index 89df495..e694b33 100644
--- a/Help/variable/CMAKE_LANG_COMPILER.rst
+++ b/Help/variable/CMAKE_LANG_COMPILER.rst
@@ -5,3 +5,28 @@
 
 This is the command that will be used as the ``<LANG>`` compiler.  Once
 set, you can not change this variable.
+
+Usage
+^^^^^
+
+This variable can be set by the user during the first time a build tree is configured.
+
+If a non-full path value is supplied then CMake will resolve the full path of
+the compiler.
+
+The variable could be set in a user supplied toolchain file or via `-D` on the command line.
+
+.. note::
+  Options that are required to make the compiler work correctly can be included
+  as items in a list; they can not be changed.
+
+.. code-block:: cmake
+
+  #set within user supplied toolchain file
+  set(CMAKE_C_COMPILER /full/path/to/qcc --arg1 --arg2)
+
+or
+
+.. code-block:: console
+
+  $ cmake ... -DCMAKE_C_COMPILER='qcc;--arg1;--arg2'
diff --git a/Help/variable/CMAKE_LANG_COMPILER_AR.rst b/Help/variable/CMAKE_LANG_COMPILER_AR.rst
index b83a1d4..74f2758 100644
--- a/Help/variable/CMAKE_LANG_COMPILER_AR.rst
+++ b/Help/variable/CMAKE_LANG_COMPILER_AR.rst
@@ -1,6 +1,8 @@
 CMAKE_<LANG>_COMPILER_AR
 ------------------------
 
+.. versionadded:: 3.9
+
 A wrapper around ``ar`` adding the appropriate ``--plugin`` option for the
 compiler.
 
diff --git a/Help/variable/CMAKE_LANG_COMPILER_ARCHITECTURE_ID.rst b/Help/variable/CMAKE_LANG_COMPILER_ARCHITECTURE_ID.rst
index 054c648..8057566 100644
--- a/Help/variable/CMAKE_LANG_COMPILER_ARCHITECTURE_ID.rst
+++ b/Help/variable/CMAKE_LANG_COMPILER_ARCHITECTURE_ID.rst
@@ -1,6 +1,8 @@
 CMAKE_<LANG>_COMPILER_ARCHITECTURE_ID
 -------------------------------------
 
+.. versionadded:: 3.10
+
 An internal variable subject to change.
 
 This is used to identify the variant of a compiler based on its target
diff --git a/Help/variable/CMAKE_LANG_COMPILER_LAUNCHER.rst b/Help/variable/CMAKE_LANG_COMPILER_LAUNCHER.rst
index c76e2d0..98634c2 100644
--- a/Help/variable/CMAKE_LANG_COMPILER_LAUNCHER.rst
+++ b/Help/variable/CMAKE_LANG_COMPILER_LAUNCHER.rst
@@ -1,6 +1,8 @@
 CMAKE_<LANG>_COMPILER_LAUNCHER
 ------------------------------
 
+.. versionadded:: 3.4
+
 Default value for :prop_tgt:`<LANG>_COMPILER_LAUNCHER` target property.
 This variable is used to initialize the property on each target as it is
 created.  This is done only when ``<LANG>`` is ``C``, ``CXX``, ``Fortran``,
diff --git a/Help/variable/CMAKE_LANG_COMPILER_PREDEFINES_COMMAND.rst b/Help/variable/CMAKE_LANG_COMPILER_PREDEFINES_COMMAND.rst
index e050f43..935329a 100644
--- a/Help/variable/CMAKE_LANG_COMPILER_PREDEFINES_COMMAND.rst
+++ b/Help/variable/CMAKE_LANG_COMPILER_PREDEFINES_COMMAND.rst
@@ -1,6 +1,8 @@
 CMAKE_<LANG>_COMPILER_PREDEFINES_COMMAND
 ----------------------------------------
 
+.. versionadded:: 3.10
+
 Command that outputs the compiler pre definitions.
 
 See :prop_tgt:`AUTOMOC` which uses
diff --git a/Help/variable/CMAKE_LANG_COMPILER_RANLIB.rst b/Help/variable/CMAKE_LANG_COMPILER_RANLIB.rst
index 945160b..1d10b55 100644
--- a/Help/variable/CMAKE_LANG_COMPILER_RANLIB.rst
+++ b/Help/variable/CMAKE_LANG_COMPILER_RANLIB.rst
@@ -1,6 +1,8 @@
 CMAKE_<LANG>_COMPILER_RANLIB
 ----------------------------
 
+.. versionadded:: 3.9
+
 A wrapper around ``ranlib`` adding the appropriate ``--plugin`` option for the
 compiler.
 
diff --git a/Help/variable/CMAKE_LANG_COMPILER_VERSION_INTERNAL.rst b/Help/variable/CMAKE_LANG_COMPILER_VERSION_INTERNAL.rst
index c3cd980..596a989 100644
--- a/Help/variable/CMAKE_LANG_COMPILER_VERSION_INTERNAL.rst
+++ b/Help/variable/CMAKE_LANG_COMPILER_VERSION_INTERNAL.rst
@@ -1,6 +1,8 @@
 CMAKE_<LANG>_COMPILER_VERSION_INTERNAL
 --------------------------------------
 
+.. versionadded:: 3.10
+
 An internal variable subject to change.
 
 This is used to identify the variant of a compiler based on an internal
diff --git a/Help/variable/CMAKE_LANG_CPPCHECK.rst b/Help/variable/CMAKE_LANG_CPPCHECK.rst
index 50b478f..5ae5faf 100644
--- a/Help/variable/CMAKE_LANG_CPPCHECK.rst
+++ b/Help/variable/CMAKE_LANG_CPPCHECK.rst
@@ -1,6 +1,8 @@
 CMAKE_<LANG>_CPPCHECK
 ---------------------
 
+.. versionadded:: 3.10
+
 Default value for :prop_tgt:`<LANG>_CPPCHECK` target property. This variable
 is used to initialize the property on each target as it is created.  This
 is done only when ``<LANG>`` is ``C`` or ``CXX``.
diff --git a/Help/variable/CMAKE_LANG_CPPLINT.rst b/Help/variable/CMAKE_LANG_CPPLINT.rst
index 3b6f452..ab7b0fc 100644
--- a/Help/variable/CMAKE_LANG_CPPLINT.rst
+++ b/Help/variable/CMAKE_LANG_CPPLINT.rst
@@ -1,6 +1,8 @@
 CMAKE_<LANG>_CPPLINT
 --------------------
 
+.. versionadded:: 3.8
+
 Default value for :prop_tgt:`<LANG>_CPPLINT` target property. This variable
 is used to initialize the property on each target as it is created.  This
 is done only when ``<LANG>`` is ``C`` or ``CXX``.
diff --git a/Help/variable/CMAKE_LANG_FLAGS_CONFIG.rst b/Help/variable/CMAKE_LANG_FLAGS_CONFIG.rst
index 1dbd036..628b62b 100644
--- a/Help/variable/CMAKE_LANG_FLAGS_CONFIG.rst
+++ b/Help/variable/CMAKE_LANG_FLAGS_CONFIG.rst
@@ -1,4 +1,6 @@
 CMAKE_<LANG>_FLAGS_<CONFIG>
 ---------------------------
 
+.. versionadded:: 3.11
+
 Flags for language ``<LANG>`` when building for the ``<CONFIG>`` configuration.
diff --git a/Help/variable/CMAKE_LANG_FLAGS_CONFIG_INIT.rst b/Help/variable/CMAKE_LANG_FLAGS_CONFIG_INIT.rst
index 1eb5b3f..17669a2 100644
--- a/Help/variable/CMAKE_LANG_FLAGS_CONFIG_INIT.rst
+++ b/Help/variable/CMAKE_LANG_FLAGS_CONFIG_INIT.rst
@@ -1,6 +1,8 @@
 CMAKE_<LANG>_FLAGS_<CONFIG>_INIT
 --------------------------------
 
+.. versionadded:: 3.11
+
 Value used to initialize the :variable:`CMAKE_<LANG>_FLAGS_<CONFIG>` cache
 entry the first time a build tree is configured for language ``<LANG>``.
 This variable is meant to be set by a :variable:`toolchain file
diff --git a/Help/variable/CMAKE_LANG_FLAGS_DEBUG_INIT.rst b/Help/variable/CMAKE_LANG_FLAGS_DEBUG_INIT.rst
index de7fcfc..49c9e99 100644
--- a/Help/variable/CMAKE_LANG_FLAGS_DEBUG_INIT.rst
+++ b/Help/variable/CMAKE_LANG_FLAGS_DEBUG_INIT.rst
@@ -1,5 +1,7 @@
 CMAKE_<LANG>_FLAGS_DEBUG_INIT
 -----------------------------
 
+.. versionadded:: 3.7
+
 This variable is the ``Debug`` variant of the
 :variable:`CMAKE_<LANG>_FLAGS_<CONFIG>_INIT` variable.
diff --git a/Help/variable/CMAKE_LANG_FLAGS_INIT.rst b/Help/variable/CMAKE_LANG_FLAGS_INIT.rst
index a88d122..67ff2cb 100644
--- a/Help/variable/CMAKE_LANG_FLAGS_INIT.rst
+++ b/Help/variable/CMAKE_LANG_FLAGS_INIT.rst
@@ -1,11 +1,17 @@
 CMAKE_<LANG>_FLAGS_INIT
 -----------------------
 
+.. versionadded:: 3.7
+
 Value used to initialize the :variable:`CMAKE_<LANG>_FLAGS` cache entry
 the first time a build tree is configured for language ``<LANG>``.
 This variable is meant to be set by a :variable:`toolchain file
 <CMAKE_TOOLCHAIN_FILE>`.  CMake may prepend or append content to
-the value based on the environment and target platform.
+the value based on the environment and target platform.  For example,
+the contents of a ``xxxFLAGS`` environment variable will be prepended,
+where ``xxx`` will be language-specific but not necessarily the same as
+``<LANG>`` (e.g. :envvar:`CXXFLAGS` for ``CXX``, :envvar:`FFLAGS` for
+``Fortran``, and so on).
 
 See also the configuration-specific
 :variable:`CMAKE_<LANG>_FLAGS_<CONFIG>_INIT` variable.
diff --git a/Help/variable/CMAKE_LANG_FLAGS_MINSIZEREL_INIT.rst b/Help/variable/CMAKE_LANG_FLAGS_MINSIZEREL_INIT.rst
index 1e7003c..3600909 100644
--- a/Help/variable/CMAKE_LANG_FLAGS_MINSIZEREL_INIT.rst
+++ b/Help/variable/CMAKE_LANG_FLAGS_MINSIZEREL_INIT.rst
@@ -1,5 +1,7 @@
 CMAKE_<LANG>_FLAGS_MINSIZEREL_INIT
 ----------------------------------
 
+.. versionadded:: 3.7
+
 This variable is the ``MinSizeRel`` variant of the
 :variable:`CMAKE_<LANG>_FLAGS_<CONFIG>_INIT` variable.
diff --git a/Help/variable/CMAKE_LANG_FLAGS_RELEASE_INIT.rst b/Help/variable/CMAKE_LANG_FLAGS_RELEASE_INIT.rst
index e7c73fe..e889852 100644
--- a/Help/variable/CMAKE_LANG_FLAGS_RELEASE_INIT.rst
+++ b/Help/variable/CMAKE_LANG_FLAGS_RELEASE_INIT.rst
@@ -1,5 +1,7 @@
 CMAKE_<LANG>_FLAGS_RELEASE_INIT
 -------------------------------
 
+.. versionadded:: 3.7
+
 This variable is the ``Release`` variant of the
 :variable:`CMAKE_<LANG>_FLAGS_<CONFIG>_INIT` variable.
diff --git a/Help/variable/CMAKE_LANG_FLAGS_RELWITHDEBINFO_INIT.rst b/Help/variable/CMAKE_LANG_FLAGS_RELWITHDEBINFO_INIT.rst
index 3ab3975..b42caee 100644
--- a/Help/variable/CMAKE_LANG_FLAGS_RELWITHDEBINFO_INIT.rst
+++ b/Help/variable/CMAKE_LANG_FLAGS_RELWITHDEBINFO_INIT.rst
@@ -1,5 +1,7 @@
 CMAKE_<LANG>_FLAGS_RELWITHDEBINFO_INIT
 --------------------------------------
 
+.. versionadded:: 3.7
+
 This variable is the ``RelWithDebInfo`` variant of the
 :variable:`CMAKE_<LANG>_FLAGS_<CONFIG>_INIT` variable.
diff --git a/Help/variable/CMAKE_LANG_INCLUDE_WHAT_YOU_USE.rst b/Help/variable/CMAKE_LANG_INCLUDE_WHAT_YOU_USE.rst
index 2c8028a..be6c210 100644
--- a/Help/variable/CMAKE_LANG_INCLUDE_WHAT_YOU_USE.rst
+++ b/Help/variable/CMAKE_LANG_INCLUDE_WHAT_YOU_USE.rst
@@ -1,6 +1,8 @@
 CMAKE_<LANG>_INCLUDE_WHAT_YOU_USE
 ---------------------------------
 
+.. versionadded:: 3.3
+
 Default value for :prop_tgt:`<LANG>_INCLUDE_WHAT_YOU_USE` target property.
 This variable is used to initialize the property on each target as it is
 created.  This is done only when ``<LANG>`` is ``C`` or ``CXX``.
diff --git a/Help/variable/CMAKE_LANG_LINKER_WRAPPER_FLAG.rst b/Help/variable/CMAKE_LANG_LINKER_WRAPPER_FLAG.rst
index df51407..471c351 100644
--- a/Help/variable/CMAKE_LANG_LINKER_WRAPPER_FLAG.rst
+++ b/Help/variable/CMAKE_LANG_LINKER_WRAPPER_FLAG.rst
@@ -1,6 +1,8 @@
 CMAKE_<LANG>_LINKER_WRAPPER_FLAG
 --------------------------------
 
+.. versionadded:: 3.13
+
 Defines the syntax of compiler driver option to pass options to the linker
 tool. It will be used to translate the ``LINKER:`` prefix in the link options
 (see :command:`add_link_options` and :command:`target_link_options`).
diff --git a/Help/variable/CMAKE_LANG_LINKER_WRAPPER_FLAG_SEP.rst b/Help/variable/CMAKE_LANG_LINKER_WRAPPER_FLAG_SEP.rst
index faf1481..a3895af 100644
--- a/Help/variable/CMAKE_LANG_LINKER_WRAPPER_FLAG_SEP.rst
+++ b/Help/variable/CMAKE_LANG_LINKER_WRAPPER_FLAG_SEP.rst
@@ -1,6 +1,8 @@
 CMAKE_<LANG>_LINKER_WRAPPER_FLAG_SEP
 ------------------------------------
 
+.. versionadded:: 3.13
+
 This variable is used with :variable:`CMAKE_<LANG>_LINKER_WRAPPER_FLAG`
 variable to format ``LINKER:`` prefix in the link options
 (see :command:`add_link_options` and :command:`target_link_options`).
diff --git a/Help/variable/CMAKE_LANG_LINK_LIBRARY_FILE_FLAG.rst b/Help/variable/CMAKE_LANG_LINK_LIBRARY_FILE_FLAG.rst
index d54f080..23ece88 100644
--- a/Help/variable/CMAKE_LANG_LINK_LIBRARY_FILE_FLAG.rst
+++ b/Help/variable/CMAKE_LANG_LINK_LIBRARY_FILE_FLAG.rst
@@ -1,6 +1,8 @@
 CMAKE_<LANG>_LINK_LIBRARY_FILE_FLAG
 -----------------------------------
 
+.. versionadded:: 3.16
+
 Language-specific flag to be used to link a library specified by
 a path to its file.
 
diff --git a/Help/variable/CMAKE_LANG_LINK_LIBRARY_FLAG.rst b/Help/variable/CMAKE_LANG_LINK_LIBRARY_FLAG.rst
index d7bb0d8..0f528db 100644
--- a/Help/variable/CMAKE_LANG_LINK_LIBRARY_FLAG.rst
+++ b/Help/variable/CMAKE_LANG_LINK_LIBRARY_FLAG.rst
@@ -1,6 +1,8 @@
 CMAKE_<LANG>_LINK_LIBRARY_FLAG
 ------------------------------
 
+.. versionadded:: 3.16
+
 Flag to be used to link a library into a shared library or executable.
 
 This flag will be used to specify a library to link to a shared library or an
diff --git a/Help/variable/CMAKE_LANG_LINK_LIBRARY_SUFFIX.rst b/Help/variable/CMAKE_LANG_LINK_LIBRARY_SUFFIX.rst
index a378657..359e29f 100644
--- a/Help/variable/CMAKE_LANG_LINK_LIBRARY_SUFFIX.rst
+++ b/Help/variable/CMAKE_LANG_LINK_LIBRARY_SUFFIX.rst
@@ -1,6 +1,8 @@
 CMAKE_<LANG>_LINK_LIBRARY_SUFFIX
 --------------------------------
 
+.. versionadded:: 3.16
+
 Language-specific suffix for libraries that you link to.
 
 The suffix to use for the end of a library filename, ``.lib`` on Windows.
diff --git a/Help/variable/CMAKE_LANG_STANDARD_INCLUDE_DIRECTORIES.rst b/Help/variable/CMAKE_LANG_STANDARD_INCLUDE_DIRECTORIES.rst
index c8e3d57..24aca8b 100644
--- a/Help/variable/CMAKE_LANG_STANDARD_INCLUDE_DIRECTORIES.rst
+++ b/Help/variable/CMAKE_LANG_STANDARD_INCLUDE_DIRECTORIES.rst
@@ -1,6 +1,8 @@
 CMAKE_<LANG>_STANDARD_INCLUDE_DIRECTORIES
 -----------------------------------------
 
+.. versionadded:: 3.6
+
 Include directories to be used for every source file compiled with
 the ``<LANG>`` compiler.  This is meant for specification of system
 include directories needed by the language for the current platform.
diff --git a/Help/variable/CMAKE_LANG_STANDARD_LIBRARIES.rst b/Help/variable/CMAKE_LANG_STANDARD_LIBRARIES.rst
index ba6df93..d5f3351 100644
--- a/Help/variable/CMAKE_LANG_STANDARD_LIBRARIES.rst
+++ b/Help/variable/CMAKE_LANG_STANDARD_LIBRARIES.rst
@@ -1,6 +1,8 @@
 CMAKE_<LANG>_STANDARD_LIBRARIES
 -------------------------------
 
+.. versionadded:: 3.6
+
 Libraries linked into every executable and shared library linked
 for language ``<LANG>``.  This is meant for specification of system
 libraries needed by the language for the current platform.
diff --git a/Help/variable/CMAKE_LIBRARY_OUTPUT_DIRECTORY_CONFIG.rst b/Help/variable/CMAKE_LIBRARY_OUTPUT_DIRECTORY_CONFIG.rst
index e069cdd..08f95c4 100644
--- a/Help/variable/CMAKE_LIBRARY_OUTPUT_DIRECTORY_CONFIG.rst
+++ b/Help/variable/CMAKE_LIBRARY_OUTPUT_DIRECTORY_CONFIG.rst
@@ -1,6 +1,8 @@
 CMAKE_LIBRARY_OUTPUT_DIRECTORY_<CONFIG>
 ---------------------------------------
 
+.. versionadded:: 3.3
+
 Where to put all the :ref:`LIBRARY <Library Output Artifacts>`
 target files when built for a specific configuration.
 
diff --git a/Help/variable/CMAKE_LINK_DIRECTORIES_BEFORE.rst b/Help/variable/CMAKE_LINK_DIRECTORIES_BEFORE.rst
index 026ca35..f120866 100644
--- a/Help/variable/CMAKE_LINK_DIRECTORIES_BEFORE.rst
+++ b/Help/variable/CMAKE_LINK_DIRECTORIES_BEFORE.rst
@@ -1,6 +1,8 @@
 CMAKE_LINK_DIRECTORIES_BEFORE
 -----------------------------
 
+.. versionadded:: 3.13
+
 Whether to append or prepend directories by default in
 :command:`link_directories`.
 
diff --git a/Help/variable/CMAKE_LINK_SEARCH_END_STATIC.rst b/Help/variable/CMAKE_LINK_SEARCH_END_STATIC.rst
index 54cdaaa..f4ccc04 100644
--- a/Help/variable/CMAKE_LINK_SEARCH_END_STATIC.rst
+++ b/Help/variable/CMAKE_LINK_SEARCH_END_STATIC.rst
@@ -1,6 +1,8 @@
 CMAKE_LINK_SEARCH_END_STATIC
 ----------------------------
 
+.. versionadded:: 3.4
+
 End a link line such that static system libraries are used.
 
 Some linkers support switches such as ``-Bstatic`` and ``-Bdynamic`` to
diff --git a/Help/variable/CMAKE_LINK_SEARCH_START_STATIC.rst b/Help/variable/CMAKE_LINK_SEARCH_START_STATIC.rst
index 0d52a31..2025c72 100644
--- a/Help/variable/CMAKE_LINK_SEARCH_START_STATIC.rst
+++ b/Help/variable/CMAKE_LINK_SEARCH_START_STATIC.rst
@@ -1,6 +1,8 @@
 CMAKE_LINK_SEARCH_START_STATIC
 ------------------------------
 
+.. versionadded:: 3.4
+
 Assume the linker looks for static libraries by default.
 
 Some linkers support switches such as ``-Bstatic`` and ``-Bdynamic`` to
diff --git a/Help/variable/CMAKE_LINK_WHAT_YOU_USE.rst b/Help/variable/CMAKE_LINK_WHAT_YOU_USE.rst
index 90c4d3f..06b3aa8 100644
--- a/Help/variable/CMAKE_LINK_WHAT_YOU_USE.rst
+++ b/Help/variable/CMAKE_LINK_WHAT_YOU_USE.rst
@@ -1,6 +1,8 @@
 CMAKE_LINK_WHAT_YOU_USE
 ---------------------------------
 
+.. versionadded:: 3.7
+
 Default value for :prop_tgt:`LINK_WHAT_YOU_USE` target property.
 This variable is used to initialize the property on each target as it is
 created.
diff --git a/Help/variable/CMAKE_MATCH_COUNT.rst b/Help/variable/CMAKE_MATCH_COUNT.rst
index 355e834..deeec8b 100644
--- a/Help/variable/CMAKE_MATCH_COUNT.rst
+++ b/Help/variable/CMAKE_MATCH_COUNT.rst
@@ -1,6 +1,8 @@
 CMAKE_MATCH_COUNT
 -----------------
 
+.. versionadded:: 3.2
+
 The number of matches with the last regular expression.
 
 When a regular expression match is used, CMake fills in
diff --git a/Help/variable/CMAKE_MATCH_n.rst b/Help/variable/CMAKE_MATCH_n.rst
index c7dd623..a92788e 100644
--- a/Help/variable/CMAKE_MATCH_n.rst
+++ b/Help/variable/CMAKE_MATCH_n.rst
@@ -1,6 +1,8 @@
 CMAKE_MATCH_<n>
 ---------------
 
+.. versionadded:: 3.9
+
 Capture group ``<n>`` matched by the last regular expression, for groups
 0 through 9.  Group 0 is the entire match.  Groups 1 through 9 are the
 subexpressions captured by ``()`` syntax.
diff --git a/Help/variable/CMAKE_MAXIMUM_RECURSION_DEPTH.rst b/Help/variable/CMAKE_MAXIMUM_RECURSION_DEPTH.rst
index 7110b16..59c60d3 100644
--- a/Help/variable/CMAKE_MAXIMUM_RECURSION_DEPTH.rst
+++ b/Help/variable/CMAKE_MAXIMUM_RECURSION_DEPTH.rst
@@ -1,6 +1,8 @@
 CMAKE_MAXIMUM_RECURSION_DEPTH
 -----------------------------
 
+.. versionadded:: 3.14
+
 Maximum recursion depth for CMake scripts. It is intended to be set on the
 command line with ``-DCMAKE_MAXIMUM_RECURSION_DEPTH=<x>``, or within
 ``CMakeLists.txt`` by projects that require a large recursion depth. Projects
diff --git a/Help/variable/CMAKE_MESSAGE_CONTEXT.rst b/Help/variable/CMAKE_MESSAGE_CONTEXT.rst
index 6b4ca40..41ace43 100644
--- a/Help/variable/CMAKE_MESSAGE_CONTEXT.rst
+++ b/Help/variable/CMAKE_MESSAGE_CONTEXT.rst
@@ -1,6 +1,8 @@
 CMAKE_MESSAGE_CONTEXT
 ---------------------
 
+.. versionadded:: 3.17
+
 When enabled by the :manual:`cmake <cmake(1)>` ``--log-context`` command line
 option or the :variable:`CMAKE_MESSAGE_CONTEXT_SHOW` variable, the
 :command:`message` command converts the ``CMAKE_MESSAGE_CONTEXT`` list into a
diff --git a/Help/variable/CMAKE_MESSAGE_CONTEXT_SHOW.rst b/Help/variable/CMAKE_MESSAGE_CONTEXT_SHOW.rst
index 7ec218e..382e9ff 100644
--- a/Help/variable/CMAKE_MESSAGE_CONTEXT_SHOW.rst
+++ b/Help/variable/CMAKE_MESSAGE_CONTEXT_SHOW.rst
@@ -1,6 +1,8 @@
 CMAKE_MESSAGE_CONTEXT_SHOW
 --------------------------
 
+.. versionadded:: 3.17
+
 Setting this variable to true enables showing a context with each line
 logged by the :command:`message` command (see :variable:`CMAKE_MESSAGE_CONTEXT`
 for how the context itself is specified).
diff --git a/Help/variable/CMAKE_MESSAGE_INDENT.rst b/Help/variable/CMAKE_MESSAGE_INDENT.rst
index 7e44a4c..c6263d2 100644
--- a/Help/variable/CMAKE_MESSAGE_INDENT.rst
+++ b/Help/variable/CMAKE_MESSAGE_INDENT.rst
@@ -1,6 +1,8 @@
 CMAKE_MESSAGE_INDENT
 --------------------
 
+.. versionadded:: 3.16
+
 The :command:`message` command joins the strings from this list and for
 log levels of ``NOTICE`` and below, it prepends the resultant string to
 each line of the message.
diff --git a/Help/variable/CMAKE_MESSAGE_LOG_LEVEL.rst b/Help/variable/CMAKE_MESSAGE_LOG_LEVEL.rst
index 1d4cfe6..3b45d1d 100644
--- a/Help/variable/CMAKE_MESSAGE_LOG_LEVEL.rst
+++ b/Help/variable/CMAKE_MESSAGE_LOG_LEVEL.rst
@@ -1,6 +1,8 @@
 CMAKE_MESSAGE_LOG_LEVEL
 -----------------------
 
+.. versionadded:: 3.17
+
 When set, this variable specifies the logging level used by the
 :command:`message` command.  Valid values are the same as those for the
 ``--log-level`` command line option of the :manual:`cmake(1)` program.
diff --git a/Help/variable/CMAKE_MODULE_LINKER_FLAGS_CONFIG_INIT.rst b/Help/variable/CMAKE_MODULE_LINKER_FLAGS_CONFIG_INIT.rst
index 3279014..e8a6401 100644
--- a/Help/variable/CMAKE_MODULE_LINKER_FLAGS_CONFIG_INIT.rst
+++ b/Help/variable/CMAKE_MODULE_LINKER_FLAGS_CONFIG_INIT.rst
@@ -1,6 +1,8 @@
 CMAKE_MODULE_LINKER_FLAGS_<CONFIG>_INIT
 ---------------------------------------
 
+.. versionadded:: 3.7
+
 Value used to initialize the :variable:`CMAKE_MODULE_LINKER_FLAGS_<CONFIG>`
 cache entry the first time a build tree is configured.
 This variable is meant to be set by a :variable:`toolchain file
diff --git a/Help/variable/CMAKE_MODULE_LINKER_FLAGS_INIT.rst b/Help/variable/CMAKE_MODULE_LINKER_FLAGS_INIT.rst
index 91b39f6..d59e9bf 100644
--- a/Help/variable/CMAKE_MODULE_LINKER_FLAGS_INIT.rst
+++ b/Help/variable/CMAKE_MODULE_LINKER_FLAGS_INIT.rst
@@ -1,6 +1,8 @@
 CMAKE_MODULE_LINKER_FLAGS_INIT
 ------------------------------
 
+.. versionadded:: 3.7
+
 Value used to initialize the :variable:`CMAKE_MODULE_LINKER_FLAGS`
 cache entry the first time a build tree is configured.
 This variable is meant to be set by a :variable:`toolchain file
diff --git a/Help/variable/CMAKE_MSVCIDE_RUN_PATH.rst b/Help/variable/CMAKE_MSVCIDE_RUN_PATH.rst
index 22e727f..721ceaa 100644
--- a/Help/variable/CMAKE_MSVCIDE_RUN_PATH.rst
+++ b/Help/variable/CMAKE_MSVCIDE_RUN_PATH.rst
@@ -1,6 +1,8 @@
 CMAKE_MSVCIDE_RUN_PATH
 ----------------------
 
+.. versionadded:: 3.10
+
 Extra PATH locations that should be used when executing
 :command:`add_custom_command` or :command:`add_custom_target` when using the
 :generator:`Visual Studio 9 2008` (or above) generator. This allows
diff --git a/Help/variable/CMAKE_MSVC_RUNTIME_LIBRARY.rst b/Help/variable/CMAKE_MSVC_RUNTIME_LIBRARY.rst
index 8b54e7e..14806e6 100644
--- a/Help/variable/CMAKE_MSVC_RUNTIME_LIBRARY.rst
+++ b/Help/variable/CMAKE_MSVC_RUNTIME_LIBRARY.rst
@@ -1,6 +1,8 @@
 CMAKE_MSVC_RUNTIME_LIBRARY
 --------------------------
 
+.. versionadded:: 3.15
+
 Select the MSVC runtime library for use by compilers targeting the MSVC ABI.
 This variable is used to initialize the :prop_tgt:`MSVC_RUNTIME_LIBRARY`
 property on all targets as they are created.  It is also propagated by
diff --git a/Help/variable/CMAKE_NETRC.rst b/Help/variable/CMAKE_NETRC.rst
index 903ec31..2c64a81 100644
--- a/Help/variable/CMAKE_NETRC.rst
+++ b/Help/variable/CMAKE_NETRC.rst
@@ -1,6 +1,8 @@
 CMAKE_NETRC
 -----------
 
+.. versionadded:: 3.11
+
 This variable is used to initialize the ``NETRC`` option for
 :command:`file(DOWNLOAD)` and :command:`file(UPLOAD)` commands and the
 module :module:`ExternalProject`. See those commands for additional
diff --git a/Help/variable/CMAKE_NETRC_FILE.rst b/Help/variable/CMAKE_NETRC_FILE.rst
index 0f09afe..97a645e 100644
--- a/Help/variable/CMAKE_NETRC_FILE.rst
+++ b/Help/variable/CMAKE_NETRC_FILE.rst
@@ -1,6 +1,8 @@
 CMAKE_NETRC_FILE
 ----------------
 
+.. versionadded:: 3.11
+
 This variable is used to initialize the ``NETRC_FILE`` option for
 :command:`file(DOWNLOAD)` and :command:`file(UPLOAD)` commands and the
 module :module:`ExternalProject`. See those commands for additional
diff --git a/Help/variable/CMAKE_NINJA_OUTPUT_PATH_PREFIX.rst b/Help/variable/CMAKE_NINJA_OUTPUT_PATH_PREFIX.rst
index 64091aa..a8c4035 100644
--- a/Help/variable/CMAKE_NINJA_OUTPUT_PATH_PREFIX.rst
+++ b/Help/variable/CMAKE_NINJA_OUTPUT_PATH_PREFIX.rst
@@ -1,6 +1,8 @@
 CMAKE_NINJA_OUTPUT_PATH_PREFIX
 ------------------------------
 
+.. versionadded:: 3.6
+
 Set output files path prefix for the :generator:`Ninja` generator.
 
 Every output files listed in the generated ``build.ninja`` will be
diff --git a/Help/variable/CMAKE_OBJCXX_EXTENSIONS.rst b/Help/variable/CMAKE_OBJCXX_EXTENSIONS.rst
index 8afa6f2..b5225ea 100644
--- a/Help/variable/CMAKE_OBJCXX_EXTENSIONS.rst
+++ b/Help/variable/CMAKE_OBJCXX_EXTENSIONS.rst
@@ -1,6 +1,8 @@
 CMAKE_OBJCXX_EXTENSIONS
 -----------------------
 
+.. versionadded:: 3.16
+
 Default value for :prop_tgt:`OBJCXX_EXTENSIONS` property of targets.
 
 This variable is used to initialize the :prop_tgt:`OBJCXX_EXTENSIONS`
diff --git a/Help/variable/CMAKE_OBJCXX_STANDARD.rst b/Help/variable/CMAKE_OBJCXX_STANDARD.rst
index 4e5016a..98e4624 100644
--- a/Help/variable/CMAKE_OBJCXX_STANDARD.rst
+++ b/Help/variable/CMAKE_OBJCXX_STANDARD.rst
@@ -1,6 +1,8 @@
 CMAKE_OBJCXX_STANDARD
 ---------------------
 
+.. versionadded:: 3.16
+
 Default value for :prop_tgt:`OBJCXX_STANDARD` property of targets.
 
 This variable is used to initialize the :prop_tgt:`OBJCXX_STANDARD`
diff --git a/Help/variable/CMAKE_OBJCXX_STANDARD_REQUIRED.rst b/Help/variable/CMAKE_OBJCXX_STANDARD_REQUIRED.rst
index 3a0602a..4b5e77c 100644
--- a/Help/variable/CMAKE_OBJCXX_STANDARD_REQUIRED.rst
+++ b/Help/variable/CMAKE_OBJCXX_STANDARD_REQUIRED.rst
@@ -1,6 +1,8 @@
 CMAKE_OBJCXX_STANDARD_REQUIRED
 ------------------------------
 
+.. versionadded:: 3.16
+
 Default value for :prop_tgt:`OBJCXX_STANDARD_REQUIRED` property of targets.
 
 This variable is used to initialize the :prop_tgt:`OBJCXX_STANDARD_REQUIRED`
diff --git a/Help/variable/CMAKE_OBJC_EXTENSIONS.rst b/Help/variable/CMAKE_OBJC_EXTENSIONS.rst
index d9619d8..d6e3c7d 100644
--- a/Help/variable/CMAKE_OBJC_EXTENSIONS.rst
+++ b/Help/variable/CMAKE_OBJC_EXTENSIONS.rst
@@ -1,6 +1,8 @@
 CMAKE_OBJC_EXTENSIONS
 ---------------------
 
+.. versionadded:: 3.16
+
 Default value for :prop_tgt:`OBJC_EXTENSIONS` property of targets.
 
 This variable is used to initialize the :prop_tgt:`OBJC_EXTENSIONS`
diff --git a/Help/variable/CMAKE_OBJC_STANDARD.rst b/Help/variable/CMAKE_OBJC_STANDARD.rst
index 976c441..fde367d 100644
--- a/Help/variable/CMAKE_OBJC_STANDARD.rst
+++ b/Help/variable/CMAKE_OBJC_STANDARD.rst
@@ -1,6 +1,8 @@
 CMAKE_OBJC_STANDARD
 -------------------
 
+.. versionadded:: 3.16
+
 Default value for :prop_tgt:`OBJC_STANDARD` property of targets.
 
 This variable is used to initialize the :prop_tgt:`OBJC_STANDARD`
diff --git a/Help/variable/CMAKE_OBJC_STANDARD_REQUIRED.rst b/Help/variable/CMAKE_OBJC_STANDARD_REQUIRED.rst
index 5c02096..8d26d95 100644
--- a/Help/variable/CMAKE_OBJC_STANDARD_REQUIRED.rst
+++ b/Help/variable/CMAKE_OBJC_STANDARD_REQUIRED.rst
@@ -1,6 +1,8 @@
 CMAKE_OBJC_STANDARD_REQUIRED
 ----------------------------
 
+.. versionadded:: 3.16
+
 Default value for :prop_tgt:`OBJC_STANDARD_REQUIRED` property of targets.
 
 This variable is used to initialize the :prop_tgt:`OBJC_STANDARD_REQUIRED`
diff --git a/Help/variable/CMAKE_PCH_WARN_INVALID.rst b/Help/variable/CMAKE_PCH_WARN_INVALID.rst
new file mode 100644
index 0000000..457a428
--- /dev/null
+++ b/Help/variable/CMAKE_PCH_WARN_INVALID.rst
@@ -0,0 +1,7 @@
+CMAKE_PCH_WARN_INVALID
+----------------------
+
+.. versionadded:: 3.18
+
+This variable is used to initialize the :prop_tgt:`PCH_WARN_INVALID`
+property of targets when they are created.
diff --git a/Help/variable/CMAKE_PROJECT_DESCRIPTION.rst b/Help/variable/CMAKE_PROJECT_DESCRIPTION.rst
index 51b0592..95cbe40 100644
--- a/Help/variable/CMAKE_PROJECT_DESCRIPTION.rst
+++ b/Help/variable/CMAKE_PROJECT_DESCRIPTION.rst
@@ -1,6 +1,8 @@
 CMAKE_PROJECT_DESCRIPTION
 -------------------------
 
+.. versionadded:: 3.9
+
 The description of the top level project.
 
 This variable holds the description of the project as specified in the top
diff --git a/Help/variable/CMAKE_PROJECT_HOMEPAGE_URL.rst b/Help/variable/CMAKE_PROJECT_HOMEPAGE_URL.rst
index ee0bf7c..4c5debe 100644
--- a/Help/variable/CMAKE_PROJECT_HOMEPAGE_URL.rst
+++ b/Help/variable/CMAKE_PROJECT_HOMEPAGE_URL.rst
@@ -1,6 +1,8 @@
 CMAKE_PROJECT_HOMEPAGE_URL
 --------------------------
 
+.. versionadded:: 3.12
+
 The homepage URL of the top level project.
 
 This variable holds the homepage URL of the project as specified in the top
diff --git a/Help/variable/CMAKE_PROJECT_INCLUDE.rst b/Help/variable/CMAKE_PROJECT_INCLUDE.rst
index 5835264..41d9e5d 100644
--- a/Help/variable/CMAKE_PROJECT_INCLUDE.rst
+++ b/Help/variable/CMAKE_PROJECT_INCLUDE.rst
@@ -1,6 +1,8 @@
 CMAKE_PROJECT_INCLUDE
 ---------------------
 
+.. versionadded:: 3.15
+
 A CMake language file or module to be included as the last step of all
 :command:`project` command calls.  This is intended for injecting custom code
 into project builds without modifying their source.
diff --git a/Help/variable/CMAKE_PROJECT_INCLUDE_BEFORE.rst b/Help/variable/CMAKE_PROJECT_INCLUDE_BEFORE.rst
index 280c14a..c2fd0f8 100644
--- a/Help/variable/CMAKE_PROJECT_INCLUDE_BEFORE.rst
+++ b/Help/variable/CMAKE_PROJECT_INCLUDE_BEFORE.rst
@@ -1,6 +1,8 @@
 CMAKE_PROJECT_INCLUDE_BEFORE
 ----------------------------
 
+.. versionadded:: 3.15
+
 A CMake language file or module to be included as the first step of all
 :command:`project` command calls.  This is intended for injecting custom code
 into project builds without modifying their source.
diff --git a/Help/variable/CMAKE_PROJECT_PROJECT-NAME_INCLUDE_BEFORE.rst b/Help/variable/CMAKE_PROJECT_PROJECT-NAME_INCLUDE_BEFORE.rst
index db1432d..39abb12 100644
--- a/Help/variable/CMAKE_PROJECT_PROJECT-NAME_INCLUDE_BEFORE.rst
+++ b/Help/variable/CMAKE_PROJECT_PROJECT-NAME_INCLUDE_BEFORE.rst
@@ -1,6 +1,8 @@
 CMAKE_PROJECT_<PROJECT-NAME>_INCLUDE_BEFORE
 -------------------------------------------
 
+.. versionadded:: 3.17
+
 A CMake language file or module to be included as the first step of any
 :command:`project` command calls that specify ``<PROJECT-NAME>`` as the project
 name.  This is intended for injecting custom code into project builds without
diff --git a/Help/variable/CMAKE_PROJECT_VERSION.rst b/Help/variable/CMAKE_PROJECT_VERSION.rst
index 4f8f556..450c136 100644
--- a/Help/variable/CMAKE_PROJECT_VERSION.rst
+++ b/Help/variable/CMAKE_PROJECT_VERSION.rst
@@ -1,6 +1,8 @@
 CMAKE_PROJECT_VERSION
 ---------------------
 
+.. versionadded:: 3.12
+
 The version of the top level project.
 
 This variable holds the version of the project as specified in the top
diff --git a/Help/variable/CMAKE_PROJECT_VERSION_MAJOR.rst b/Help/variable/CMAKE_PROJECT_VERSION_MAJOR.rst
index f1001ac..c7511e7 100644
--- a/Help/variable/CMAKE_PROJECT_VERSION_MAJOR.rst
+++ b/Help/variable/CMAKE_PROJECT_VERSION_MAJOR.rst
@@ -1,6 +1,8 @@
 CMAKE_PROJECT_VERSION_MAJOR
 ---------------------------
 
+.. versionadded:: 3.12
+
 The major version of the top level project.
 
 This variable holds the major version of the project as specified in the top
diff --git a/Help/variable/CMAKE_PROJECT_VERSION_MINOR.rst b/Help/variable/CMAKE_PROJECT_VERSION_MINOR.rst
index 13202be..dd91dcf 100644
--- a/Help/variable/CMAKE_PROJECT_VERSION_MINOR.rst
+++ b/Help/variable/CMAKE_PROJECT_VERSION_MINOR.rst
@@ -1,6 +1,8 @@
 CMAKE_PROJECT_VERSION_MINOR
 ---------------------------
 
+.. versionadded:: 3.12
+
 The minor version of the top level project.
 
 This variable holds the minor version of the project as specified in the top
diff --git a/Help/variable/CMAKE_PROJECT_VERSION_PATCH.rst b/Help/variable/CMAKE_PROJECT_VERSION_PATCH.rst
index b8570d9..61fd1f3 100644
--- a/Help/variable/CMAKE_PROJECT_VERSION_PATCH.rst
+++ b/Help/variable/CMAKE_PROJECT_VERSION_PATCH.rst
@@ -1,6 +1,8 @@
 CMAKE_PROJECT_VERSION_PATCH
 ---------------------------
 
+.. versionadded:: 3.12
+
 The patch version of the top level project.
 
 This variable holds the patch version of the project as specified in the top
diff --git a/Help/variable/CMAKE_PROJECT_VERSION_TWEAK.rst b/Help/variable/CMAKE_PROJECT_VERSION_TWEAK.rst
index e1ad4be..0deae8b 100644
--- a/Help/variable/CMAKE_PROJECT_VERSION_TWEAK.rst
+++ b/Help/variable/CMAKE_PROJECT_VERSION_TWEAK.rst
@@ -1,6 +1,8 @@
 CMAKE_PROJECT_VERSION_TWEAK
 ---------------------------
 
+.. versionadded:: 3.12
+
 The tweak version of the top level project.
 
 This variable holds the tweak version of the project as specified in the top
diff --git a/Help/variable/CMAKE_RULE_MESSAGES.rst b/Help/variable/CMAKE_RULE_MESSAGES.rst
index 7460a81..39be2e9 100644
--- a/Help/variable/CMAKE_RULE_MESSAGES.rst
+++ b/Help/variable/CMAKE_RULE_MESSAGES.rst
@@ -1,6 +1,8 @@
 CMAKE_RULE_MESSAGES
 -------------------
 
+.. versionadded:: 3.13
+
 Specify whether to report a message for each make rule.
 
 If set in the cache it is used to initialize the value of the :prop_gbl:`RULE_MESSAGES` property.
diff --git a/Help/variable/CMAKE_RUNTIME_OUTPUT_DIRECTORY_CONFIG.rst b/Help/variable/CMAKE_RUNTIME_OUTPUT_DIRECTORY_CONFIG.rst
index 080dea6..c9c55c5 100644
--- a/Help/variable/CMAKE_RUNTIME_OUTPUT_DIRECTORY_CONFIG.rst
+++ b/Help/variable/CMAKE_RUNTIME_OUTPUT_DIRECTORY_CONFIG.rst
@@ -1,6 +1,8 @@
 CMAKE_RUNTIME_OUTPUT_DIRECTORY_<CONFIG>
 ---------------------------------------
 
+.. versionadded:: 3.3
+
 Where to put all the :ref:`RUNTIME <Runtime Output Artifacts>`
 target files when built for a specific configuration.
 
diff --git a/Help/variable/CMAKE_SHARED_LINKER_FLAGS_CONFIG_INIT.rst b/Help/variable/CMAKE_SHARED_LINKER_FLAGS_CONFIG_INIT.rst
index 185df38..7f3dec7 100644
--- a/Help/variable/CMAKE_SHARED_LINKER_FLAGS_CONFIG_INIT.rst
+++ b/Help/variable/CMAKE_SHARED_LINKER_FLAGS_CONFIG_INIT.rst
@@ -1,6 +1,8 @@
 CMAKE_SHARED_LINKER_FLAGS_<CONFIG>_INIT
 ---------------------------------------
 
+.. versionadded:: 3.7
+
 Value used to initialize the :variable:`CMAKE_SHARED_LINKER_FLAGS_<CONFIG>`
 cache entry the first time a build tree is configured.
 This variable is meant to be set by a :variable:`toolchain file
diff --git a/Help/variable/CMAKE_SHARED_LINKER_FLAGS_INIT.rst b/Help/variable/CMAKE_SHARED_LINKER_FLAGS_INIT.rst
index cb819a7..6d51afe 100644
--- a/Help/variable/CMAKE_SHARED_LINKER_FLAGS_INIT.rst
+++ b/Help/variable/CMAKE_SHARED_LINKER_FLAGS_INIT.rst
@@ -1,6 +1,8 @@
 CMAKE_SHARED_LINKER_FLAGS_INIT
 ------------------------------
 
+.. versionadded:: 3.7
+
 Value used to initialize the :variable:`CMAKE_SHARED_LINKER_FLAGS`
 cache entry the first time a build tree is configured.
 This variable is meant to be set by a :variable:`toolchain file
diff --git a/Help/variable/CMAKE_STATIC_LINKER_FLAGS_CONFIG_INIT.rst b/Help/variable/CMAKE_STATIC_LINKER_FLAGS_CONFIG_INIT.rst
index a49d1cb..5e65ef2 100644
--- a/Help/variable/CMAKE_STATIC_LINKER_FLAGS_CONFIG_INIT.rst
+++ b/Help/variable/CMAKE_STATIC_LINKER_FLAGS_CONFIG_INIT.rst
@@ -1,6 +1,8 @@
 CMAKE_STATIC_LINKER_FLAGS_<CONFIG>_INIT
 ---------------------------------------
 
+.. versionadded:: 3.7
+
 Value used to initialize the :variable:`CMAKE_STATIC_LINKER_FLAGS_<CONFIG>`
 cache entry the first time a build tree is configured.
 This variable is meant to be set by a :variable:`toolchain file
diff --git a/Help/variable/CMAKE_STATIC_LINKER_FLAGS_INIT.rst b/Help/variable/CMAKE_STATIC_LINKER_FLAGS_INIT.rst
index 113ca71..cbf681c 100644
--- a/Help/variable/CMAKE_STATIC_LINKER_FLAGS_INIT.rst
+++ b/Help/variable/CMAKE_STATIC_LINKER_FLAGS_INIT.rst
@@ -1,6 +1,8 @@
 CMAKE_STATIC_LINKER_FLAGS_INIT
 ------------------------------
 
+.. versionadded:: 3.7
+
 Value used to initialize the :variable:`CMAKE_STATIC_LINKER_FLAGS`
 cache entry the first time a build tree is configured.
 This variable is meant to be set by a :variable:`toolchain file
diff --git a/Help/variable/CMAKE_SUBLIME_TEXT_2_ENV_SETTINGS.rst b/Help/variable/CMAKE_SUBLIME_TEXT_2_ENV_SETTINGS.rst
index 02c8663..5c1c8d1 100644
--- a/Help/variable/CMAKE_SUBLIME_TEXT_2_ENV_SETTINGS.rst
+++ b/Help/variable/CMAKE_SUBLIME_TEXT_2_ENV_SETTINGS.rst
@@ -1,6 +1,8 @@
 CMAKE_SUBLIME_TEXT_2_ENV_SETTINGS
 ---------------------------------
 
+.. versionadded:: 3.8
+
 This variable contains a list of env vars as a list of tokens with the
 syntax ``var=value``.
 
diff --git a/Help/variable/CMAKE_SUBLIME_TEXT_2_EXCLUDE_BUILD_TREE.rst b/Help/variable/CMAKE_SUBLIME_TEXT_2_EXCLUDE_BUILD_TREE.rst
index d654425..28b0dbd 100644
--- a/Help/variable/CMAKE_SUBLIME_TEXT_2_EXCLUDE_BUILD_TREE.rst
+++ b/Help/variable/CMAKE_SUBLIME_TEXT_2_EXCLUDE_BUILD_TREE.rst
@@ -1,6 +1,8 @@
 CMAKE_SUBLIME_TEXT_2_EXCLUDE_BUILD_TREE
 ---------------------------------------
 
+.. versionadded:: 3.8
+
 If this variable evaluates to ``ON`` at the end of the top-level
 ``CMakeLists.txt`` file, the :generator:`Sublime Text 2` extra generator
 excludes the build tree from the ``.sublime-project`` if it is inside the
diff --git a/Help/variable/CMAKE_SUPPRESS_REGENERATION.rst b/Help/variable/CMAKE_SUPPRESS_REGENERATION.rst
index 96184dd..48490ff 100644
--- a/Help/variable/CMAKE_SUPPRESS_REGENERATION.rst
+++ b/Help/variable/CMAKE_SUPPRESS_REGENERATION.rst
@@ -1,6 +1,8 @@
 CMAKE_SUPPRESS_REGENERATION
 ---------------------------
 
+.. versionadded:: 3.12
+
 If ``CMAKE_SUPPRESS_REGENERATION`` is ``OFF``, which is default, then CMake
 adds a special target on which all other targets depend that checks the build
 system and optionally re-runs CMake to regenerate the build system when
diff --git a/Help/variable/CMAKE_SYSROOT_COMPILE.rst b/Help/variable/CMAKE_SYSROOT_COMPILE.rst
index e96c62b..4aea48e 100644
--- a/Help/variable/CMAKE_SYSROOT_COMPILE.rst
+++ b/Help/variable/CMAKE_SYSROOT_COMPILE.rst
@@ -1,6 +1,8 @@
 CMAKE_SYSROOT_COMPILE
 ---------------------
 
+.. versionadded:: 3.9
+
 Path to pass to the compiler in the ``--sysroot`` flag when compiling source
 files.  This is the same as :variable:`CMAKE_SYSROOT` but is used only for
 compiling sources and not linking.
diff --git a/Help/variable/CMAKE_SYSROOT_LINK.rst b/Help/variable/CMAKE_SYSROOT_LINK.rst
index 88b48ef..9749b7b 100644
--- a/Help/variable/CMAKE_SYSROOT_LINK.rst
+++ b/Help/variable/CMAKE_SYSROOT_LINK.rst
@@ -1,6 +1,8 @@
 CMAKE_SYSROOT_LINK
 ------------------
 
+.. versionadded:: 3.9
+
 Path to pass to the compiler in the ``--sysroot`` flag when linking.  This is
 the same as :variable:`CMAKE_SYSROOT` but is used only for linking and not
 compiling sources.
diff --git a/Help/variable/CMAKE_SYSTEM_APPBUNDLE_PATH.rst b/Help/variable/CMAKE_SYSTEM_APPBUNDLE_PATH.rst
index 666af46..06a99a8 100644
--- a/Help/variable/CMAKE_SYSTEM_APPBUNDLE_PATH.rst
+++ b/Help/variable/CMAKE_SYSTEM_APPBUNDLE_PATH.rst
@@ -1,6 +1,8 @@
 CMAKE_SYSTEM_APPBUNDLE_PATH
 ---------------------------
 
+.. versionadded:: 3.4
+
 Search path for macOS application bundles used by the :command:`find_program`,
 and :command:`find_package` commands.  By default it contains the standard
 directories for the current system.  It is *not* intended to be modified by
diff --git a/Help/variable/CMAKE_SYSTEM_FRAMEWORK_PATH.rst b/Help/variable/CMAKE_SYSTEM_FRAMEWORK_PATH.rst
index 14ba18e..1a402c1 100644
--- a/Help/variable/CMAKE_SYSTEM_FRAMEWORK_PATH.rst
+++ b/Help/variable/CMAKE_SYSTEM_FRAMEWORK_PATH.rst
@@ -1,6 +1,8 @@
 CMAKE_SYSTEM_FRAMEWORK_PATH
 ---------------------------
 
+.. versionadded:: 3.4
+
 Search path for macOS frameworks used by the :command:`find_library`,
 :command:`find_package`, :command:`find_path`, and :command:`find_file`
 commands.  By default it contains the standard directories for the
diff --git a/Help/variable/CMAKE_SYSTEM_PREFIX_PATH.rst b/Help/variable/CMAKE_SYSTEM_PREFIX_PATH.rst
index 87a9d06..81a7a0b 100644
--- a/Help/variable/CMAKE_SYSTEM_PREFIX_PATH.rst
+++ b/Help/variable/CMAKE_SYSTEM_PREFIX_PATH.rst
@@ -8,11 +8,43 @@
 subdirectories (like ``bin``, ``lib``, or ``include``) as specified in its own
 documentation.
 
-By default this contains the standard directories for the current system, the
+By default this contains the system directories for the current system, the
 :variable:`CMAKE_INSTALL_PREFIX`, and the :variable:`CMAKE_STAGING_PREFIX`.
 The installation and staging prefixes may be excluded by setting
 the :variable:`CMAKE_FIND_NO_INSTALL_PREFIX` variable.
 
+The system directories that are contained in ``CMAKE_SYSTEM_PREFIX_PATH`` are
+locations that typically include installed software. An example being
+``/usr/local`` for UNIX based platforms. In addition to standard platform
+locations, CMake will also add values to ``CMAKE_SYSTEM_PREFIX_PATH`` based on
+environment variables. The environment variables and search locations that
+CMake uses may evolve over time, as platforms and their conventions also
+evolve. The following provides an indicative list of environment variables
+and locations that CMake searches, but they are subject to change:
+
+
+CrayLinuxEnvironment:
+  * ``ENV{SYSROOT_DIR}/``
+  * ``ENV{SYSROOT_DIR}/usr``
+  * ``ENV{SYSROOT_DIR}/usr/local``
+
+Darwin:
+  * ``ENV{SDKROOT}/usr`` When ``CMAKE_OSX_SYSROOT`` is not explicitly specified.
+
+OpenBSD:
+  * ``ENV{LOCALBASE}``
+
+Unix:
+  * ``ENV{CONDA_PREFIX}`` when using a conda compiler
+
+Windows:
+  * ``ENV{ProgramW6432}``
+  * ``ENV{ProgramFiles}``
+  * ``ENV{ProgramFiles(x86)}``
+  * ``ENV{SystemDrive}/Program Files``
+  * ``ENV{SystemDrive}/Program Files (x86)``
+
+
 ``CMAKE_SYSTEM_PREFIX_PATH`` is *not* intended to be modified by the project;
 use :variable:`CMAKE_PREFIX_PATH` for this.
 
diff --git a/Help/variable/CMAKE_Swift_LANGUAGE_VERSION.rst b/Help/variable/CMAKE_Swift_LANGUAGE_VERSION.rst
index b4a74eb..fce6fa7 100644
--- a/Help/variable/CMAKE_Swift_LANGUAGE_VERSION.rst
+++ b/Help/variable/CMAKE_Swift_LANGUAGE_VERSION.rst
@@ -1,6 +1,8 @@
 CMAKE_Swift_LANGUAGE_VERSION
 ----------------------------
 
+.. versionadded:: 3.7
+
 Set to the Swift language version number.  If not set, the oldest legacy
 version known to be available in the host Xcode version is assumed:
 
diff --git a/Help/variable/CMAKE_Swift_MODULE_DIRECTORY.rst b/Help/variable/CMAKE_Swift_MODULE_DIRECTORY.rst
index b11253b..3694973 100644
--- a/Help/variable/CMAKE_Swift_MODULE_DIRECTORY.rst
+++ b/Help/variable/CMAKE_Swift_MODULE_DIRECTORY.rst
@@ -1,6 +1,8 @@
 CMAKE_Swift_MODULE_DIRECTORY
 ----------------------------
 
+.. versionadded:: 3.15
+
 Swift module output directory.
 
 This variable is used to initialise the :prop_tgt:`Swift_MODULE_DIRECTORY`
diff --git a/Help/variable/CMAKE_Swift_NUM_THREADS.rst b/Help/variable/CMAKE_Swift_NUM_THREADS.rst
index cb33678..e1dafb0 100644
--- a/Help/variable/CMAKE_Swift_NUM_THREADS.rst
+++ b/Help/variable/CMAKE_Swift_NUM_THREADS.rst
@@ -1,6 +1,8 @@
 CMAKE_Swift_NUM_THREADS
 -----------------------
 
+.. versionadded:: 3.15.1
+
 Number of threads for parallel compilation for Swift targets.
 
 This variable controls the number of parallel jobs that the swift driver creates
diff --git a/Help/variable/CMAKE_TRY_COMPILE_PLATFORM_VARIABLES.rst b/Help/variable/CMAKE_TRY_COMPILE_PLATFORM_VARIABLES.rst
index 0f96787..d178513 100644
--- a/Help/variable/CMAKE_TRY_COMPILE_PLATFORM_VARIABLES.rst
+++ b/Help/variable/CMAKE_TRY_COMPILE_PLATFORM_VARIABLES.rst
@@ -1,6 +1,8 @@
 CMAKE_TRY_COMPILE_PLATFORM_VARIABLES
 ------------------------------------
 
+.. versionadded:: 3.6
+
 List of variables that the :command:`try_compile` command source file signature
 must propagate into the test project in order to target the same platform as
 the host project.
diff --git a/Help/variable/CMAKE_TRY_COMPILE_TARGET_TYPE.rst b/Help/variable/CMAKE_TRY_COMPILE_TARGET_TYPE.rst
index 5fa8dfc..b60539f 100644
--- a/Help/variable/CMAKE_TRY_COMPILE_TARGET_TYPE.rst
+++ b/Help/variable/CMAKE_TRY_COMPILE_TARGET_TYPE.rst
@@ -1,6 +1,8 @@
 CMAKE_TRY_COMPILE_TARGET_TYPE
 -----------------------------
 
+.. versionadded:: 3.6
+
 Type of target generated for :command:`try_compile` calls using the
 source file signature.  Valid values are:
 
diff --git a/Help/variable/CMAKE_UNITY_BUILD.rst b/Help/variable/CMAKE_UNITY_BUILD.rst
index a86cd67..54a781a 100644
--- a/Help/variable/CMAKE_UNITY_BUILD.rst
+++ b/Help/variable/CMAKE_UNITY_BUILD.rst
@@ -1,6 +1,8 @@
 CMAKE_UNITY_BUILD
 -----------------
 
+.. versionadded:: 3.16
+
 This variable is used to initialize the :prop_tgt:`UNITY_BUILD`
 property of targets when they are created.  Setting it to true
 enables batch compilation of multiple sources within each target.
diff --git a/Help/variable/CMAKE_UNITY_BUILD_BATCH_SIZE.rst b/Help/variable/CMAKE_UNITY_BUILD_BATCH_SIZE.rst
index 7988d4b..7733fe8 100644
--- a/Help/variable/CMAKE_UNITY_BUILD_BATCH_SIZE.rst
+++ b/Help/variable/CMAKE_UNITY_BUILD_BATCH_SIZE.rst
@@ -1,6 +1,8 @@
 CMAKE_UNITY_BUILD_BATCH_SIZE
 ----------------------------
 
+.. versionadded:: 3.16
+
 This variable is used to initialize the :prop_tgt:`UNITY_BUILD_BATCH_SIZE`
 property of targets when they are created.  It specifies the default upper
 limit on the number of source files that may be combined in any one unity
diff --git a/Help/variable/CMAKE_VS_GLOBALS.rst b/Help/variable/CMAKE_VS_GLOBALS.rst
index 83777b6..d4514fe 100644
--- a/Help/variable/CMAKE_VS_GLOBALS.rst
+++ b/Help/variable/CMAKE_VS_GLOBALS.rst
@@ -1,6 +1,8 @@
 CMAKE_VS_GLOBALS
 ----------------
 
+.. versionadded:: 3.13
+
 List of ``Key=Value`` records to be set per target as target properties
 :prop_tgt:`VS_GLOBAL_<variable>` with ``variable=Key`` and value ``Value``.
 
diff --git a/Help/variable/CMAKE_VS_INCLUDE_INSTALL_TO_DEFAULT_BUILD.rst b/Help/variable/CMAKE_VS_INCLUDE_INSTALL_TO_DEFAULT_BUILD.rst
index f54472a..ace94e4 100644
--- a/Help/variable/CMAKE_VS_INCLUDE_INSTALL_TO_DEFAULT_BUILD.rst
+++ b/Help/variable/CMAKE_VS_INCLUDE_INSTALL_TO_DEFAULT_BUILD.rst
@@ -1,6 +1,8 @@
 CMAKE_VS_INCLUDE_INSTALL_TO_DEFAULT_BUILD
 -----------------------------------------
 
+.. versionadded:: 3.3
+
 Include ``INSTALL`` target to default build.
 
 In Visual Studio solution, by default the ``INSTALL`` target will not be part
diff --git a/Help/variable/CMAKE_VS_INCLUDE_PACKAGE_TO_DEFAULT_BUILD.rst b/Help/variable/CMAKE_VS_INCLUDE_PACKAGE_TO_DEFAULT_BUILD.rst
index 693ba45..ab4d0fa 100644
--- a/Help/variable/CMAKE_VS_INCLUDE_PACKAGE_TO_DEFAULT_BUILD.rst
+++ b/Help/variable/CMAKE_VS_INCLUDE_PACKAGE_TO_DEFAULT_BUILD.rst
@@ -1,6 +1,8 @@
 CMAKE_VS_INCLUDE_PACKAGE_TO_DEFAULT_BUILD
 -----------------------------------------
 
+.. versionadded:: 3.8
+
 Include ``PACKAGE`` target to default build.
 
 In Visual Studio solution, by default the ``PACKAGE`` target will not be part
diff --git a/Help/variable/CMAKE_VS_JUST_MY_CODE_DEBUGGING.rst b/Help/variable/CMAKE_VS_JUST_MY_CODE_DEBUGGING.rst
index 546cdf4..0a02a32 100644
--- a/Help/variable/CMAKE_VS_JUST_MY_CODE_DEBUGGING.rst
+++ b/Help/variable/CMAKE_VS_JUST_MY_CODE_DEBUGGING.rst
@@ -1,6 +1,8 @@
 CMAKE_VS_JUST_MY_CODE_DEBUGGING
 -------------------------------
 
+.. versionadded:: 3.15
+
 Enable Just My Code with Visual Studio debugger.
 
 This variable is used to initialize the :prop_tgt:`VS_JUST_MY_CODE_DEBUGGING`
diff --git a/Help/variable/CMAKE_VS_NsightTegra_VERSION.rst b/Help/variable/CMAKE_VS_NsightTegra_VERSION.rst
index 386c3a9..2982b39 100644
--- a/Help/variable/CMAKE_VS_NsightTegra_VERSION.rst
+++ b/Help/variable/CMAKE_VS_NsightTegra_VERSION.rst
@@ -1,6 +1,8 @@
 CMAKE_VS_NsightTegra_VERSION
 ----------------------------
 
+.. versionadded:: 3.1
+
 When using a Visual Studio generator with the
 :variable:`CMAKE_SYSTEM_NAME` variable set to ``Android``,
 this variable contains the version number of the
diff --git a/Help/variable/CMAKE_VS_PLATFORM_NAME.rst b/Help/variable/CMAKE_VS_PLATFORM_NAME.rst
index 7a4642a..7d08add 100644
--- a/Help/variable/CMAKE_VS_PLATFORM_NAME.rst
+++ b/Help/variable/CMAKE_VS_PLATFORM_NAME.rst
@@ -1,6 +1,8 @@
 CMAKE_VS_PLATFORM_NAME
 ----------------------
 
+.. versionadded:: 3.1
+
 Visual Studio target platform name used by the current generator.
 
 VS 8 and above allow project files to specify a target platform.
diff --git a/Help/variable/CMAKE_VS_PLATFORM_NAME_DEFAULT.rst b/Help/variable/CMAKE_VS_PLATFORM_NAME_DEFAULT.rst
index c18e6fd..6440174 100644
--- a/Help/variable/CMAKE_VS_PLATFORM_NAME_DEFAULT.rst
+++ b/Help/variable/CMAKE_VS_PLATFORM_NAME_DEFAULT.rst
@@ -1,6 +1,8 @@
 CMAKE_VS_PLATFORM_NAME_DEFAULT
 ------------------------------
 
+.. versionadded:: 3.14.3
+
 Default for the Visual Studio target platform name for the current generator
 without considering the value of the :variable:`CMAKE_GENERATOR_PLATFORM`
 variable.  For :ref:`Visual Studio Generators` for VS 2017 and below this is
diff --git a/Help/variable/CMAKE_VS_PLATFORM_TOOLSET_CUDA.rst b/Help/variable/CMAKE_VS_PLATFORM_TOOLSET_CUDA.rst
index 67b7f74..e66378d 100644
--- a/Help/variable/CMAKE_VS_PLATFORM_TOOLSET_CUDA.rst
+++ b/Help/variable/CMAKE_VS_PLATFORM_TOOLSET_CUDA.rst
@@ -1,6 +1,8 @@
 CMAKE_VS_PLATFORM_TOOLSET_CUDA
 ------------------------------
 
+.. versionadded:: 3.9
+
 NVIDIA CUDA Toolkit version whose Visual Studio toolset to use.
 
 The :ref:`Visual Studio Generators` for VS 2010 and above support using
diff --git a/Help/variable/CMAKE_VS_PLATFORM_TOOLSET_CUDA_CUSTOM_DIR.rst b/Help/variable/CMAKE_VS_PLATFORM_TOOLSET_CUDA_CUSTOM_DIR.rst
index 060648a..74db6b1 100644
--- a/Help/variable/CMAKE_VS_PLATFORM_TOOLSET_CUDA_CUSTOM_DIR.rst
+++ b/Help/variable/CMAKE_VS_PLATFORM_TOOLSET_CUDA_CUSTOM_DIR.rst
@@ -1,6 +1,8 @@
 CMAKE_VS_PLATFORM_TOOLSET_CUDA_CUSTOM_DIR
 -----------------------------------------
 
+.. versionadded:: 3.16
+
 Path to standalone NVIDIA CUDA Toolkit (eg. extracted from installer).
 
 The :ref:`Visual Studio Generators` for VS 2010 and above support using
diff --git a/Help/variable/CMAKE_VS_PLATFORM_TOOLSET_HOST_ARCHITECTURE.rst b/Help/variable/CMAKE_VS_PLATFORM_TOOLSET_HOST_ARCHITECTURE.rst
index 99ac90d..84d7212 100644
--- a/Help/variable/CMAKE_VS_PLATFORM_TOOLSET_HOST_ARCHITECTURE.rst
+++ b/Help/variable/CMAKE_VS_PLATFORM_TOOLSET_HOST_ARCHITECTURE.rst
@@ -1,6 +1,8 @@
 CMAKE_VS_PLATFORM_TOOLSET_HOST_ARCHITECTURE
 -------------------------------------------
 
+.. versionadded:: 3.8
+
 Visual Studio preferred tool architecture.
 
 The :ref:`Visual Studio Generators` for VS 2013 and above support using
diff --git a/Help/variable/CMAKE_VS_PLATFORM_TOOLSET_VERSION.rst b/Help/variable/CMAKE_VS_PLATFORM_TOOLSET_VERSION.rst
index 4d9b978..64f2e39 100644
--- a/Help/variable/CMAKE_VS_PLATFORM_TOOLSET_VERSION.rst
+++ b/Help/variable/CMAKE_VS_PLATFORM_TOOLSET_VERSION.rst
@@ -1,6 +1,8 @@
 CMAKE_VS_PLATFORM_TOOLSET_VERSION
 ---------------------------------
 
+.. versionadded:: 3.12
+
 Visual Studio Platform Toolset version.
 
 The :ref:`Visual Studio Generators` for VS 2017 and above allow to
diff --git a/Help/variable/CMAKE_VS_SDK_EXCLUDE_DIRECTORIES.rst b/Help/variable/CMAKE_VS_SDK_EXCLUDE_DIRECTORIES.rst
index 36c4dcc..969f328 100644
--- a/Help/variable/CMAKE_VS_SDK_EXCLUDE_DIRECTORIES.rst
+++ b/Help/variable/CMAKE_VS_SDK_EXCLUDE_DIRECTORIES.rst
@@ -1,4 +1,6 @@
 CMAKE_VS_SDK_EXCLUDE_DIRECTORIES
 --------------------------------
 
+.. versionadded:: 3.12
+
 This variable allows to override Visual Studio default Exclude Directories.
diff --git a/Help/variable/CMAKE_VS_SDK_EXECUTABLE_DIRECTORIES.rst b/Help/variable/CMAKE_VS_SDK_EXECUTABLE_DIRECTORIES.rst
index 3ec755b..7455e10 100644
--- a/Help/variable/CMAKE_VS_SDK_EXECUTABLE_DIRECTORIES.rst
+++ b/Help/variable/CMAKE_VS_SDK_EXECUTABLE_DIRECTORIES.rst
@@ -1,4 +1,6 @@
 CMAKE_VS_SDK_EXECUTABLE_DIRECTORIES
 -----------------------------------
 
+.. versionadded:: 3.12
+
 This variable allows to override Visual Studio default Executable Directories.
diff --git a/Help/variable/CMAKE_VS_SDK_INCLUDE_DIRECTORIES.rst b/Help/variable/CMAKE_VS_SDK_INCLUDE_DIRECTORIES.rst
index da10bde..3f27aea 100644
--- a/Help/variable/CMAKE_VS_SDK_INCLUDE_DIRECTORIES.rst
+++ b/Help/variable/CMAKE_VS_SDK_INCLUDE_DIRECTORIES.rst
@@ -1,4 +1,6 @@
 CMAKE_VS_SDK_INCLUDE_DIRECTORIES
 --------------------------------
 
+.. versionadded:: 3.12
+
 This variable allows to override Visual Studio default Include Directories.
diff --git a/Help/variable/CMAKE_VS_SDK_LIBRARY_DIRECTORIES.rst b/Help/variable/CMAKE_VS_SDK_LIBRARY_DIRECTORIES.rst
index b33754a..35e45a3 100644
--- a/Help/variable/CMAKE_VS_SDK_LIBRARY_DIRECTORIES.rst
+++ b/Help/variable/CMAKE_VS_SDK_LIBRARY_DIRECTORIES.rst
@@ -1,4 +1,6 @@
 CMAKE_VS_SDK_LIBRARY_DIRECTORIES
 --------------------------------
 
+.. versionadded:: 3.12
+
 This variable allows to override Visual Studio default Library Directories.
diff --git a/Help/variable/CMAKE_VS_SDK_LIBRARY_WINRT_DIRECTORIES.rst b/Help/variable/CMAKE_VS_SDK_LIBRARY_WINRT_DIRECTORIES.rst
index b022215..24b90b6 100644
--- a/Help/variable/CMAKE_VS_SDK_LIBRARY_WINRT_DIRECTORIES.rst
+++ b/Help/variable/CMAKE_VS_SDK_LIBRARY_WINRT_DIRECTORIES.rst
@@ -1,5 +1,7 @@
 CMAKE_VS_SDK_LIBRARY_WINRT_DIRECTORIES
 --------------------------------------
 
+.. versionadded:: 3.12
+
 This variable allows to override Visual Studio default Library WinRT
 Directories.
diff --git a/Help/variable/CMAKE_VS_SDK_REFERENCE_DIRECTORIES.rst b/Help/variable/CMAKE_VS_SDK_REFERENCE_DIRECTORIES.rst
index c03f0ae..00382fe 100644
--- a/Help/variable/CMAKE_VS_SDK_REFERENCE_DIRECTORIES.rst
+++ b/Help/variable/CMAKE_VS_SDK_REFERENCE_DIRECTORIES.rst
@@ -1,4 +1,6 @@
 CMAKE_VS_SDK_REFERENCE_DIRECTORIES
 ----------------------------------
 
+.. versionadded:: 3.12
+
 This variable allows to override Visual Studio default Reference Directories.
diff --git a/Help/variable/CMAKE_VS_SDK_SOURCE_DIRECTORIES.rst b/Help/variable/CMAKE_VS_SDK_SOURCE_DIRECTORIES.rst
index 0c73f06..b98c999 100644
--- a/Help/variable/CMAKE_VS_SDK_SOURCE_DIRECTORIES.rst
+++ b/Help/variable/CMAKE_VS_SDK_SOURCE_DIRECTORIES.rst
@@ -1,4 +1,6 @@
 CMAKE_VS_SDK_SOURCE_DIRECTORIES
 -------------------------------
 
+.. versionadded:: 3.12
+
 This variable allows to override Visual Studio default Source Directories.
diff --git a/Help/variable/CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION.rst b/Help/variable/CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION.rst
index 83b9bc1..cb55bc2 100644
--- a/Help/variable/CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION.rst
+++ b/Help/variable/CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION.rst
@@ -1,6 +1,8 @@
 CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION
 ----------------------------------------
 
+.. versionadded:: 3.4
+
 Visual Studio Windows Target Platform Version.
 
 When targeting Windows 10 and above Visual Studio 2015 and above support
diff --git a/Help/variable/CMAKE_VS_WINRT_BY_DEFAULT.rst b/Help/variable/CMAKE_VS_WINRT_BY_DEFAULT.rst
index 2eea424..9ded85f 100644
--- a/Help/variable/CMAKE_VS_WINRT_BY_DEFAULT.rst
+++ b/Help/variable/CMAKE_VS_WINRT_BY_DEFAULT.rst
@@ -1,6 +1,8 @@
 CMAKE_VS_WINRT_BY_DEFAULT
 -------------------------
 
+.. versionadded:: 3.13
+
 Inform :ref:`Visual Studio Generators` for VS 2010 and above that the
 target platform enables WinRT compilation by default and it needs to
 be explicitly disabled if ``/ZW`` or :prop_tgt:`VS_WINRT_COMPONENT` is
diff --git a/Help/variable/CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS.rst b/Help/variable/CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS.rst
index 1636842..7b01185 100644
--- a/Help/variable/CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS.rst
+++ b/Help/variable/CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS.rst
@@ -1,6 +1,8 @@
 CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS
 --------------------------------
 
+.. versionadded:: 3.4
+
 Default value for :prop_tgt:`WINDOWS_EXPORT_ALL_SYMBOLS` target property.
 This variable is used to initialize the property on each target as it is
 created.
diff --git a/Help/variable/CMAKE_XCODE_ATTRIBUTE_an-attribute.rst b/Help/variable/CMAKE_XCODE_ATTRIBUTE_an-attribute.rst
index be683d6..90e4c0e 100644
--- a/Help/variable/CMAKE_XCODE_ATTRIBUTE_an-attribute.rst
+++ b/Help/variable/CMAKE_XCODE_ATTRIBUTE_an-attribute.rst
@@ -1,6 +1,8 @@
 CMAKE_XCODE_ATTRIBUTE_<an-attribute>
 ------------------------------------
 
+.. versionadded:: 3.1
+
 Set Xcode target attributes directly.
 
 Tell the :generator:`Xcode` generator to set '<an-attribute>' to a given value
diff --git a/Help/variable/CMAKE_XCODE_GENERATE_SCHEME.rst b/Help/variable/CMAKE_XCODE_GENERATE_SCHEME.rst
index 5b1a003..40070e1 100644
--- a/Help/variable/CMAKE_XCODE_GENERATE_SCHEME.rst
+++ b/Help/variable/CMAKE_XCODE_GENERATE_SCHEME.rst
@@ -1,6 +1,8 @@
 CMAKE_XCODE_GENERATE_SCHEME
 ---------------------------
 
+.. versionadded:: 3.9
+
 If enabled, the :generator:`Xcode` generator will generate schema files.  These
 are useful to invoke analyze, archive, build-for-testing and test
 actions from the command line.
diff --git a/Help/variable/CMAKE_XCODE_GENERATE_TOP_LEVEL_PROJECT_ONLY.rst b/Help/variable/CMAKE_XCODE_GENERATE_TOP_LEVEL_PROJECT_ONLY.rst
index ea3e240..38d043c 100644
--- a/Help/variable/CMAKE_XCODE_GENERATE_TOP_LEVEL_PROJECT_ONLY.rst
+++ b/Help/variable/CMAKE_XCODE_GENERATE_TOP_LEVEL_PROJECT_ONLY.rst
@@ -1,6 +1,8 @@
 CMAKE_XCODE_GENERATE_TOP_LEVEL_PROJECT_ONLY
 -------------------------------------------
 
+.. versionadded:: 3.11
+
 If enabled, the :generator:`Xcode` generator will generate only a
 single Xcode project file for the topmost :command:`project()` command
 instead of generating one for every ``project()`` command.
diff --git a/Help/variable/CMAKE_XCODE_SCHEME_ADDRESS_SANITIZER.rst b/Help/variable/CMAKE_XCODE_SCHEME_ADDRESS_SANITIZER.rst
index b972ba5..b3fa93b 100644
--- a/Help/variable/CMAKE_XCODE_SCHEME_ADDRESS_SANITIZER.rst
+++ b/Help/variable/CMAKE_XCODE_SCHEME_ADDRESS_SANITIZER.rst
@@ -1,6 +1,8 @@
 CMAKE_XCODE_SCHEME_ADDRESS_SANITIZER
 ------------------------------------
 
+.. versionadded:: 3.13
+
 Whether to enable ``Address Sanitizer`` in the Diagnostics
 section of the generated Xcode scheme.
 
diff --git a/Help/variable/CMAKE_XCODE_SCHEME_ADDRESS_SANITIZER_USE_AFTER_RETURN.rst b/Help/variable/CMAKE_XCODE_SCHEME_ADDRESS_SANITIZER_USE_AFTER_RETURN.rst
index 59eb32d..1a0a17a 100644
--- a/Help/variable/CMAKE_XCODE_SCHEME_ADDRESS_SANITIZER_USE_AFTER_RETURN.rst
+++ b/Help/variable/CMAKE_XCODE_SCHEME_ADDRESS_SANITIZER_USE_AFTER_RETURN.rst
@@ -1,6 +1,8 @@
 CMAKE_XCODE_SCHEME_ADDRESS_SANITIZER_USE_AFTER_RETURN
 -----------------------------------------------------
 
+.. versionadded:: 3.13
+
 Whether to enable ``Detect use of stack after return``
 in the Diagnostics section of the generated Xcode scheme.
 
diff --git a/Help/variable/CMAKE_XCODE_SCHEME_DEBUG_DOCUMENT_VERSIONING.rst b/Help/variable/CMAKE_XCODE_SCHEME_DEBUG_DOCUMENT_VERSIONING.rst
index a264d36..917fc7f 100644
--- a/Help/variable/CMAKE_XCODE_SCHEME_DEBUG_DOCUMENT_VERSIONING.rst
+++ b/Help/variable/CMAKE_XCODE_SCHEME_DEBUG_DOCUMENT_VERSIONING.rst
@@ -1,6 +1,8 @@
 CMAKE_XCODE_SCHEME_DEBUG_DOCUMENT_VERSIONING
 --------------------------------------------
 
+.. versionadded:: 3.16
+
 Whether to enable
 ``Allow debugging when using document Versions Browser``
 in the Options section of the generated Xcode scheme.
diff --git a/Help/variable/CMAKE_XCODE_SCHEME_DISABLE_MAIN_THREAD_CHECKER.rst b/Help/variable/CMAKE_XCODE_SCHEME_DISABLE_MAIN_THREAD_CHECKER.rst
index 71bcf42..b604598 100644
--- a/Help/variable/CMAKE_XCODE_SCHEME_DISABLE_MAIN_THREAD_CHECKER.rst
+++ b/Help/variable/CMAKE_XCODE_SCHEME_DISABLE_MAIN_THREAD_CHECKER.rst
@@ -1,6 +1,8 @@
 CMAKE_XCODE_SCHEME_DISABLE_MAIN_THREAD_CHECKER
 ----------------------------------------------
 
+.. versionadded:: 3.13
+
 Whether to disable the ``Main Thread Checker``
 in the Diagnostics section of the generated Xcode scheme.
 
diff --git a/Help/variable/CMAKE_XCODE_SCHEME_DYNAMIC_LIBRARY_LOADS.rst b/Help/variable/CMAKE_XCODE_SCHEME_DYNAMIC_LIBRARY_LOADS.rst
index 53f55e6..070ddfc 100644
--- a/Help/variable/CMAKE_XCODE_SCHEME_DYNAMIC_LIBRARY_LOADS.rst
+++ b/Help/variable/CMAKE_XCODE_SCHEME_DYNAMIC_LIBRARY_LOADS.rst
@@ -1,6 +1,8 @@
 CMAKE_XCODE_SCHEME_DYNAMIC_LIBRARY_LOADS
 ----------------------------------------
 
+.. versionadded:: 3.13
+
 Whether to enable ``Dynamic Library Loads``
 in the Diagnostics section of the generated Xcode scheme.
 
diff --git a/Help/variable/CMAKE_XCODE_SCHEME_DYNAMIC_LINKER_API_USAGE.rst b/Help/variable/CMAKE_XCODE_SCHEME_DYNAMIC_LINKER_API_USAGE.rst
index 784ceb6..4291816 100644
--- a/Help/variable/CMAKE_XCODE_SCHEME_DYNAMIC_LINKER_API_USAGE.rst
+++ b/Help/variable/CMAKE_XCODE_SCHEME_DYNAMIC_LINKER_API_USAGE.rst
@@ -1,6 +1,8 @@
 CMAKE_XCODE_SCHEME_DYNAMIC_LINKER_API_USAGE
 -------------------------------------------
 
+.. versionadded:: 3.13
+
 Whether to enable ``Dynamic Linker API usage``
 in the Diagnostics section of the generated Xcode scheme.
 
diff --git a/Help/variable/CMAKE_XCODE_SCHEME_ENVIRONMENT.rst b/Help/variable/CMAKE_XCODE_SCHEME_ENVIRONMENT.rst
index 4832659..62b698d 100644
--- a/Help/variable/CMAKE_XCODE_SCHEME_ENVIRONMENT.rst
+++ b/Help/variable/CMAKE_XCODE_SCHEME_ENVIRONMENT.rst
@@ -1,6 +1,8 @@
 CMAKE_XCODE_SCHEME_ENVIRONMENT
 ------------------------------
 
+.. versionadded:: 3.17
+
 Specify environment variables that should be added to the Arguments
 section of the generated Xcode scheme.
 
diff --git a/Help/variable/CMAKE_XCODE_SCHEME_GUARD_MALLOC.rst b/Help/variable/CMAKE_XCODE_SCHEME_GUARD_MALLOC.rst
index 9350244..48b481e 100644
--- a/Help/variable/CMAKE_XCODE_SCHEME_GUARD_MALLOC.rst
+++ b/Help/variable/CMAKE_XCODE_SCHEME_GUARD_MALLOC.rst
@@ -1,6 +1,8 @@
 CMAKE_XCODE_SCHEME_GUARD_MALLOC
 -------------------------------
 
+.. versionadded:: 3.13
+
 Whether to enable ``Guard Malloc``
 in the Diagnostics section of the generated Xcode scheme.
 
diff --git a/Help/variable/CMAKE_XCODE_SCHEME_MAIN_THREAD_CHECKER_STOP.rst b/Help/variable/CMAKE_XCODE_SCHEME_MAIN_THREAD_CHECKER_STOP.rst
index 45a2dad..ef8ed9b 100644
--- a/Help/variable/CMAKE_XCODE_SCHEME_MAIN_THREAD_CHECKER_STOP.rst
+++ b/Help/variable/CMAKE_XCODE_SCHEME_MAIN_THREAD_CHECKER_STOP.rst
@@ -1,6 +1,8 @@
 CMAKE_XCODE_SCHEME_MAIN_THREAD_CHECKER_STOP
 -------------------------------------------
 
+.. versionadded:: 3.13
+
 Whether to enable the ``Main Thread Checker`` option
 ``Pause on issues``
 in the Diagnostics section of the generated Xcode scheme.
diff --git a/Help/variable/CMAKE_XCODE_SCHEME_MALLOC_GUARD_EDGES.rst b/Help/variable/CMAKE_XCODE_SCHEME_MALLOC_GUARD_EDGES.rst
index 94d1c61..d4ae9eb 100644
--- a/Help/variable/CMAKE_XCODE_SCHEME_MALLOC_GUARD_EDGES.rst
+++ b/Help/variable/CMAKE_XCODE_SCHEME_MALLOC_GUARD_EDGES.rst
@@ -1,6 +1,8 @@
 CMAKE_XCODE_SCHEME_MALLOC_GUARD_EDGES
 -------------------------------------
 
+.. versionadded:: 3.13
+
 Whether to enable ``Malloc Guard Edges``
 in the Diagnostics section of the generated Xcode scheme.
 
diff --git a/Help/variable/CMAKE_XCODE_SCHEME_MALLOC_SCRIBBLE.rst b/Help/variable/CMAKE_XCODE_SCHEME_MALLOC_SCRIBBLE.rst
index 9bf0eb4..e28f6a1 100644
--- a/Help/variable/CMAKE_XCODE_SCHEME_MALLOC_SCRIBBLE.rst
+++ b/Help/variable/CMAKE_XCODE_SCHEME_MALLOC_SCRIBBLE.rst
@@ -1,6 +1,8 @@
 CMAKE_XCODE_SCHEME_MALLOC_SCRIBBLE
 ----------------------------------
 
+.. versionadded:: 3.13
+
 Whether to enable ``Malloc Scribble``
 in the Diagnostics section of the generated Xcode scheme.
 
diff --git a/Help/variable/CMAKE_XCODE_SCHEME_MALLOC_STACK.rst b/Help/variable/CMAKE_XCODE_SCHEME_MALLOC_STACK.rst
index 4cc21ee..59fcfd3 100644
--- a/Help/variable/CMAKE_XCODE_SCHEME_MALLOC_STACK.rst
+++ b/Help/variable/CMAKE_XCODE_SCHEME_MALLOC_STACK.rst
@@ -1,6 +1,8 @@
 CMAKE_XCODE_SCHEME_MALLOC_STACK
 -------------------------------
 
+.. versionadded:: 3.13
+
 Whether to enable ``Malloc Stack`` in the Diagnostics
 section of the generated Xcode scheme.
 
diff --git a/Help/variable/CMAKE_XCODE_SCHEME_THREAD_SANITIZER.rst b/Help/variable/CMAKE_XCODE_SCHEME_THREAD_SANITIZER.rst
index 6d1b56e..511eb04 100644
--- a/Help/variable/CMAKE_XCODE_SCHEME_THREAD_SANITIZER.rst
+++ b/Help/variable/CMAKE_XCODE_SCHEME_THREAD_SANITIZER.rst
@@ -1,6 +1,8 @@
 CMAKE_XCODE_SCHEME_THREAD_SANITIZER
 -----------------------------------
 
+.. versionadded:: 3.13
+
 Whether to enable ``Thread Sanitizer`` in the Diagnostics
 section of the generated Xcode scheme.
 
diff --git a/Help/variable/CMAKE_XCODE_SCHEME_THREAD_SANITIZER_STOP.rst b/Help/variable/CMAKE_XCODE_SCHEME_THREAD_SANITIZER_STOP.rst
index de40478..6f3b8ce 100644
--- a/Help/variable/CMAKE_XCODE_SCHEME_THREAD_SANITIZER_STOP.rst
+++ b/Help/variable/CMAKE_XCODE_SCHEME_THREAD_SANITIZER_STOP.rst
@@ -1,6 +1,8 @@
 CMAKE_XCODE_SCHEME_THREAD_SANITIZER_STOP
 ----------------------------------------
 
+.. versionadded:: 3.13
+
 Whether to enable ``Thread Sanitizer - Pause on issues``
 in the Diagnostics section of the generated Xcode scheme.
 
diff --git a/Help/variable/CMAKE_XCODE_SCHEME_UNDEFINED_BEHAVIOUR_SANITIZER.rst b/Help/variable/CMAKE_XCODE_SCHEME_UNDEFINED_BEHAVIOUR_SANITIZER.rst
index ec5df66..46d3ccf 100644
--- a/Help/variable/CMAKE_XCODE_SCHEME_UNDEFINED_BEHAVIOUR_SANITIZER.rst
+++ b/Help/variable/CMAKE_XCODE_SCHEME_UNDEFINED_BEHAVIOUR_SANITIZER.rst
@@ -1,6 +1,8 @@
 CMAKE_XCODE_SCHEME_UNDEFINED_BEHAVIOUR_SANITIZER
 ------------------------------------------------
 
+.. versionadded:: 3.13
+
 Whether to enable ``Undefined Behavior Sanitizer``
 in the Diagnostics section of the generated Xcode scheme.
 
diff --git a/Help/variable/CMAKE_XCODE_SCHEME_UNDEFINED_BEHAVIOUR_SANITIZER_STOP.rst b/Help/variable/CMAKE_XCODE_SCHEME_UNDEFINED_BEHAVIOUR_SANITIZER_STOP.rst
index dcec9b0..8fa5ece 100644
--- a/Help/variable/CMAKE_XCODE_SCHEME_UNDEFINED_BEHAVIOUR_SANITIZER_STOP.rst
+++ b/Help/variable/CMAKE_XCODE_SCHEME_UNDEFINED_BEHAVIOUR_SANITIZER_STOP.rst
@@ -1,6 +1,8 @@
 CMAKE_XCODE_SCHEME_UNDEFINED_BEHAVIOUR_SANITIZER_STOP
 -----------------------------------------------------
 
+.. versionadded:: 3.13
+
 Whether to enable ``Undefined Behavior Sanitizer`` option
 ``Pause on issues``
 in the Diagnostics section of the generated Xcode scheme.
diff --git a/Help/variable/CMAKE_XCODE_SCHEME_WORKING_DIRECTORY.rst b/Help/variable/CMAKE_XCODE_SCHEME_WORKING_DIRECTORY.rst
index 5bb7907..4221e48 100644
--- a/Help/variable/CMAKE_XCODE_SCHEME_WORKING_DIRECTORY.rst
+++ b/Help/variable/CMAKE_XCODE_SCHEME_WORKING_DIRECTORY.rst
@@ -1,6 +1,8 @@
 CMAKE_XCODE_SCHEME_WORKING_DIRECTORY
 ------------------------------------
 
+.. versionadded:: 3.17
+
 Specify the ``Working Directory`` of the *Run* and *Profile*
 actions in the generated Xcode scheme.
 
diff --git a/Help/variable/CMAKE_XCODE_SCHEME_ZOMBIE_OBJECTS.rst b/Help/variable/CMAKE_XCODE_SCHEME_ZOMBIE_OBJECTS.rst
index 82e9d76..fd9488e 100644
--- a/Help/variable/CMAKE_XCODE_SCHEME_ZOMBIE_OBJECTS.rst
+++ b/Help/variable/CMAKE_XCODE_SCHEME_ZOMBIE_OBJECTS.rst
@@ -1,6 +1,8 @@
 CMAKE_XCODE_SCHEME_ZOMBIE_OBJECTS
 ---------------------------------
 
+.. versionadded:: 3.13
+
 Whether to enable ``Zombie Objects``
 in the Diagnostics section of the generated Xcode scheme.
 
diff --git a/Help/variable/CPACK_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS.rst b/Help/variable/CPACK_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS.rst
index 83d5ce7..01fb189 100644
--- a/Help/variable/CPACK_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS.rst
+++ b/Help/variable/CPACK_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS.rst
@@ -1,6 +1,8 @@
 CPACK_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS
 -------------------------------------------
 
+.. versionadded:: 3.11
+
 Default permissions for implicitly created directories during packaging.
 
 This variable serves the same purpose during packaging as the
diff --git a/Help/variable/CTEST_BINARY_DIRECTORY.rst b/Help/variable/CTEST_BINARY_DIRECTORY.rst
index fd8461f..8413e37 100644
--- a/Help/variable/CTEST_BINARY_DIRECTORY.rst
+++ b/Help/variable/CTEST_BINARY_DIRECTORY.rst
@@ -1,5 +1,7 @@
 CTEST_BINARY_DIRECTORY
 ----------------------
 
+.. versionadded:: 3.1
+
 Specify the CTest ``BuildDirectory`` setting
 in a :manual:`ctest(1)` dashboard client script.
diff --git a/Help/variable/CTEST_BUILD_COMMAND.rst b/Help/variable/CTEST_BUILD_COMMAND.rst
index 7b13ba0..31c44e2 100644
--- a/Help/variable/CTEST_BUILD_COMMAND.rst
+++ b/Help/variable/CTEST_BUILD_COMMAND.rst
@@ -1,5 +1,7 @@
 CTEST_BUILD_COMMAND
 -------------------
 
+.. versionadded:: 3.1
+
 Specify the CTest ``MakeCommand`` setting
 in a :manual:`ctest(1)` dashboard client script.
diff --git a/Help/variable/CTEST_BUILD_NAME.rst b/Help/variable/CTEST_BUILD_NAME.rst
index d25d84c..3d08397 100644
--- a/Help/variable/CTEST_BUILD_NAME.rst
+++ b/Help/variable/CTEST_BUILD_NAME.rst
@@ -1,5 +1,7 @@
 CTEST_BUILD_NAME
 ----------------
 
+.. versionadded:: 3.1
+
 Specify the CTest ``BuildName`` setting
 in a :manual:`ctest(1)` dashboard client script.
diff --git a/Help/variable/CTEST_BZR_COMMAND.rst b/Help/variable/CTEST_BZR_COMMAND.rst
index 474d621..0c05d1a 100644
--- a/Help/variable/CTEST_BZR_COMMAND.rst
+++ b/Help/variable/CTEST_BZR_COMMAND.rst
@@ -1,5 +1,7 @@
 CTEST_BZR_COMMAND
 -----------------
 
+.. versionadded:: 3.1
+
 Specify the CTest ``BZRCommand`` setting
 in a :manual:`ctest(1)` dashboard client script.
diff --git a/Help/variable/CTEST_BZR_UPDATE_OPTIONS.rst b/Help/variable/CTEST_BZR_UPDATE_OPTIONS.rst
index d0f9579..4dd5e5b 100644
--- a/Help/variable/CTEST_BZR_UPDATE_OPTIONS.rst
+++ b/Help/variable/CTEST_BZR_UPDATE_OPTIONS.rst
@@ -1,5 +1,7 @@
 CTEST_BZR_UPDATE_OPTIONS
 ------------------------
 
+.. versionadded:: 3.1
+
 Specify the CTest ``BZRUpdateOptions`` setting
 in a :manual:`ctest(1)` dashboard client script.
diff --git a/Help/variable/CTEST_CHANGE_ID.rst b/Help/variable/CTEST_CHANGE_ID.rst
index a423f49..a6d15f7 100644
--- a/Help/variable/CTEST_CHANGE_ID.rst
+++ b/Help/variable/CTEST_CHANGE_ID.rst
@@ -1,6 +1,8 @@
 CTEST_CHANGE_ID
 ---------------
 
+.. versionadded:: 3.4
+
 Specify the CTest ``ChangeId`` setting
 in a :manual:`ctest(1)` dashboard client script.
 
diff --git a/Help/variable/CTEST_CHECKOUT_COMMAND.rst b/Help/variable/CTEST_CHECKOUT_COMMAND.rst
index da256f2..852c28e 100644
--- a/Help/variable/CTEST_CHECKOUT_COMMAND.rst
+++ b/Help/variable/CTEST_CHECKOUT_COMMAND.rst
@@ -1,5 +1,7 @@
 CTEST_CHECKOUT_COMMAND
 ----------------------
 
+.. versionadded:: 3.1
+
 Tell the :command:`ctest_start` command how to checkout or initialize
 the source directory in a :manual:`ctest(1)` dashboard client script.
diff --git a/Help/variable/CTEST_CONFIGURATION_TYPE.rst b/Help/variable/CTEST_CONFIGURATION_TYPE.rst
index 9e277fa..392845e 100644
--- a/Help/variable/CTEST_CONFIGURATION_TYPE.rst
+++ b/Help/variable/CTEST_CONFIGURATION_TYPE.rst
@@ -1,6 +1,8 @@
 CTEST_CONFIGURATION_TYPE
 ------------------------
 
+.. versionadded:: 3.1
+
 Specify the CTest ``DefaultCTestConfigurationType`` setting
 in a :manual:`ctest(1)` dashboard client script.
 
diff --git a/Help/variable/CTEST_CONFIGURE_COMMAND.rst b/Help/variable/CTEST_CONFIGURE_COMMAND.rst
index 5561b6d..992ef47 100644
--- a/Help/variable/CTEST_CONFIGURE_COMMAND.rst
+++ b/Help/variable/CTEST_CONFIGURE_COMMAND.rst
@@ -1,5 +1,7 @@
 CTEST_CONFIGURE_COMMAND
 -----------------------
 
+.. versionadded:: 3.1
+
 Specify the CTest ``ConfigureCommand`` setting
 in a :manual:`ctest(1)` dashboard client script.
diff --git a/Help/variable/CTEST_COVERAGE_COMMAND.rst b/Help/variable/CTEST_COVERAGE_COMMAND.rst
index a78792e..f5425cb 100644
--- a/Help/variable/CTEST_COVERAGE_COMMAND.rst
+++ b/Help/variable/CTEST_COVERAGE_COMMAND.rst
@@ -1,6 +1,8 @@
 CTEST_COVERAGE_COMMAND
 ----------------------
 
+.. versionadded:: 3.1
+
 Specify the CTest ``CoverageCommand`` setting
 in a :manual:`ctest(1)` dashboard client script.
 
diff --git a/Help/variable/CTEST_COVERAGE_EXTRA_FLAGS.rst b/Help/variable/CTEST_COVERAGE_EXTRA_FLAGS.rst
index 2981955..39d9b5d 100644
--- a/Help/variable/CTEST_COVERAGE_EXTRA_FLAGS.rst
+++ b/Help/variable/CTEST_COVERAGE_EXTRA_FLAGS.rst
@@ -1,5 +1,7 @@
 CTEST_COVERAGE_EXTRA_FLAGS
 --------------------------
 
+.. versionadded:: 3.1
+
 Specify the CTest ``CoverageExtraFlags`` setting
 in a :manual:`ctest(1)` dashboard client script.
diff --git a/Help/variable/CTEST_CURL_OPTIONS.rst b/Help/variable/CTEST_CURL_OPTIONS.rst
index fc5dfc4..14af4e4 100644
--- a/Help/variable/CTEST_CURL_OPTIONS.rst
+++ b/Help/variable/CTEST_CURL_OPTIONS.rst
@@ -1,5 +1,7 @@
 CTEST_CURL_OPTIONS
 ------------------
 
+.. versionadded:: 3.1
+
 Specify the CTest ``CurlOptions`` setting
 in a :manual:`ctest(1)` dashboard client script.
diff --git a/Help/variable/CTEST_CUSTOM_COVERAGE_EXCLUDE.rst b/Help/variable/CTEST_CUSTOM_COVERAGE_EXCLUDE.rst
index d5893c9..84ba12d 100644
--- a/Help/variable/CTEST_CUSTOM_COVERAGE_EXCLUDE.rst
+++ b/Help/variable/CTEST_CUSTOM_COVERAGE_EXCLUDE.rst
@@ -1,6 +1,8 @@
 CTEST_CUSTOM_COVERAGE_EXCLUDE
 -----------------------------
 
+.. versionadded:: 3.4
+
 A list of regular expressions which will be used to exclude files by their
 path from coverage output by the :command:`ctest_coverage` command.
 
diff --git a/Help/variable/CTEST_CUSTOM_ERROR_EXCEPTION.rst b/Help/variable/CTEST_CUSTOM_ERROR_EXCEPTION.rst
index cd65ae3..7191ce4 100644
--- a/Help/variable/CTEST_CUSTOM_ERROR_EXCEPTION.rst
+++ b/Help/variable/CTEST_CUSTOM_ERROR_EXCEPTION.rst
@@ -1,6 +1,8 @@
 CTEST_CUSTOM_ERROR_EXCEPTION
 ----------------------------
 
+.. versionadded:: 3.4
+
 A list of regular expressions which will be used to exclude when detecting
 error messages in build outputs by the :command:`ctest_test` command.
 
diff --git a/Help/variable/CTEST_CUSTOM_ERROR_MATCH.rst b/Help/variable/CTEST_CUSTOM_ERROR_MATCH.rst
index 558f5e5..5d213f2 100644
--- a/Help/variable/CTEST_CUSTOM_ERROR_MATCH.rst
+++ b/Help/variable/CTEST_CUSTOM_ERROR_MATCH.rst
@@ -1,6 +1,8 @@
 CTEST_CUSTOM_ERROR_MATCH
 ------------------------
 
+.. versionadded:: 3.4
+
 A list of regular expressions which will be used to detect error messages in
 build outputs by the :command:`ctest_test` command.
 
diff --git a/Help/variable/CTEST_CUSTOM_ERROR_POST_CONTEXT.rst b/Help/variable/CTEST_CUSTOM_ERROR_POST_CONTEXT.rst
index 614859b..452d060 100644
--- a/Help/variable/CTEST_CUSTOM_ERROR_POST_CONTEXT.rst
+++ b/Help/variable/CTEST_CUSTOM_ERROR_POST_CONTEXT.rst
@@ -1,6 +1,8 @@
 CTEST_CUSTOM_ERROR_POST_CONTEXT
 -------------------------------
 
+.. versionadded:: 3.4
+
 The number of lines to include as context which follow an error message by the
 :command:`ctest_test` command. The default is 10.
 
diff --git a/Help/variable/CTEST_CUSTOM_ERROR_PRE_CONTEXT.rst b/Help/variable/CTEST_CUSTOM_ERROR_PRE_CONTEXT.rst
index 74dc47a..b7717dd 100644
--- a/Help/variable/CTEST_CUSTOM_ERROR_PRE_CONTEXT.rst
+++ b/Help/variable/CTEST_CUSTOM_ERROR_PRE_CONTEXT.rst
@@ -1,6 +1,8 @@
 CTEST_CUSTOM_ERROR_PRE_CONTEXT
 ------------------------------
 
+.. versionadded:: 3.4
+
 The number of lines to include as context which precede an error message by
 the :command:`ctest_test` command. The default is 10.
 
diff --git a/Help/variable/CTEST_CUSTOM_MAXIMUM_FAILED_TEST_OUTPUT_SIZE.rst b/Help/variable/CTEST_CUSTOM_MAXIMUM_FAILED_TEST_OUTPUT_SIZE.rst
index 5aeae88..31ba099 100644
--- a/Help/variable/CTEST_CUSTOM_MAXIMUM_FAILED_TEST_OUTPUT_SIZE.rst
+++ b/Help/variable/CTEST_CUSTOM_MAXIMUM_FAILED_TEST_OUTPUT_SIZE.rst
@@ -1,6 +1,8 @@
 CTEST_CUSTOM_MAXIMUM_FAILED_TEST_OUTPUT_SIZE
 --------------------------------------------
 
+.. versionadded:: 3.4
+
 When saving a failing test's output, this is the maximum size, in bytes, that
 will be collected by the :command:`ctest_test` command. Defaults to 307200
 (300 KiB).
diff --git a/Help/variable/CTEST_CUSTOM_MAXIMUM_NUMBER_OF_ERRORS.rst b/Help/variable/CTEST_CUSTOM_MAXIMUM_NUMBER_OF_ERRORS.rst
index 920cb04..e5be1ad 100644
--- a/Help/variable/CTEST_CUSTOM_MAXIMUM_NUMBER_OF_ERRORS.rst
+++ b/Help/variable/CTEST_CUSTOM_MAXIMUM_NUMBER_OF_ERRORS.rst
@@ -1,6 +1,8 @@
 CTEST_CUSTOM_MAXIMUM_NUMBER_OF_ERRORS
 -------------------------------------
 
+.. versionadded:: 3.4
+
 The maximum number of errors in a single build step which will be detected.
 After this, the :command:`ctest_test` command will truncate the output.
 Defaults to 50.
diff --git a/Help/variable/CTEST_CUSTOM_MAXIMUM_NUMBER_OF_WARNINGS.rst b/Help/variable/CTEST_CUSTOM_MAXIMUM_NUMBER_OF_WARNINGS.rst
index a1f1cc1..b513a5c 100644
--- a/Help/variable/CTEST_CUSTOM_MAXIMUM_NUMBER_OF_WARNINGS.rst
+++ b/Help/variable/CTEST_CUSTOM_MAXIMUM_NUMBER_OF_WARNINGS.rst
@@ -1,6 +1,8 @@
 CTEST_CUSTOM_MAXIMUM_NUMBER_OF_WARNINGS
 ---------------------------------------
 
+.. versionadded:: 3.4
+
 The maximum number of warnings in a single build step which will be detected.
 After this, the :command:`ctest_test` command will truncate the output.
 Defaults to 50.
diff --git a/Help/variable/CTEST_CUSTOM_MAXIMUM_PASSED_TEST_OUTPUT_SIZE.rst b/Help/variable/CTEST_CUSTOM_MAXIMUM_PASSED_TEST_OUTPUT_SIZE.rst
index 1fbb8c5..08762d8 100644
--- a/Help/variable/CTEST_CUSTOM_MAXIMUM_PASSED_TEST_OUTPUT_SIZE.rst
+++ b/Help/variable/CTEST_CUSTOM_MAXIMUM_PASSED_TEST_OUTPUT_SIZE.rst
@@ -1,6 +1,8 @@
 CTEST_CUSTOM_MAXIMUM_PASSED_TEST_OUTPUT_SIZE
 --------------------------------------------
 
+.. versionadded:: 3.4
+
 When saving a passing test's output, this is the maximum size, in bytes, that
 will be collected by the :command:`ctest_test` command. Defaults to 1024
 (1 KiB).
diff --git a/Help/variable/CTEST_CUSTOM_MEMCHECK_IGNORE.rst b/Help/variable/CTEST_CUSTOM_MEMCHECK_IGNORE.rst
index 578576c..405fc33 100644
--- a/Help/variable/CTEST_CUSTOM_MEMCHECK_IGNORE.rst
+++ b/Help/variable/CTEST_CUSTOM_MEMCHECK_IGNORE.rst
@@ -1,6 +1,8 @@
 CTEST_CUSTOM_MEMCHECK_IGNORE
 ----------------------------
 
+.. versionadded:: 3.4
+
 A list of regular expressions to use to exclude tests during the
 :command:`ctest_memcheck` command.
 
diff --git a/Help/variable/CTEST_CUSTOM_POST_MEMCHECK.rst b/Help/variable/CTEST_CUSTOM_POST_MEMCHECK.rst
index 40291fe..5e488a7 100644
--- a/Help/variable/CTEST_CUSTOM_POST_MEMCHECK.rst
+++ b/Help/variable/CTEST_CUSTOM_POST_MEMCHECK.rst
@@ -1,6 +1,8 @@
 CTEST_CUSTOM_POST_MEMCHECK
 --------------------------
 
+.. versionadded:: 3.4
+
 A list of commands to run at the end of the :command:`ctest_memcheck` command.
 
 .. include:: CTEST_CUSTOM_XXX.txt
diff --git a/Help/variable/CTEST_CUSTOM_POST_TEST.rst b/Help/variable/CTEST_CUSTOM_POST_TEST.rst
index 791292c..7ec42f7 100644
--- a/Help/variable/CTEST_CUSTOM_POST_TEST.rst
+++ b/Help/variable/CTEST_CUSTOM_POST_TEST.rst
@@ -1,6 +1,8 @@
 CTEST_CUSTOM_POST_TEST
 ----------------------
 
+.. versionadded:: 3.4
+
 A list of commands to run at the end of the :command:`ctest_test` command.
 
 .. include:: CTEST_CUSTOM_XXX.txt
diff --git a/Help/variable/CTEST_CUSTOM_PRE_MEMCHECK.rst b/Help/variable/CTEST_CUSTOM_PRE_MEMCHECK.rst
index 00de8aa..99e47bd 100644
--- a/Help/variable/CTEST_CUSTOM_PRE_MEMCHECK.rst
+++ b/Help/variable/CTEST_CUSTOM_PRE_MEMCHECK.rst
@@ -1,6 +1,8 @@
 CTEST_CUSTOM_PRE_MEMCHECK
 -------------------------
 
+.. versionadded:: 3.4
+
 A list of commands to run at the start of the :command:`ctest_memcheck`
 command.
 
diff --git a/Help/variable/CTEST_CUSTOM_PRE_TEST.rst b/Help/variable/CTEST_CUSTOM_PRE_TEST.rst
index 6af7152..95c6314 100644
--- a/Help/variable/CTEST_CUSTOM_PRE_TEST.rst
+++ b/Help/variable/CTEST_CUSTOM_PRE_TEST.rst
@@ -1,6 +1,8 @@
 CTEST_CUSTOM_PRE_TEST
 ----------------------
 
+.. versionadded:: 3.4
+
 A list of commands to run at the start of the :command:`ctest_test` command.
 
 .. include:: CTEST_CUSTOM_XXX.txt
diff --git a/Help/variable/CTEST_CUSTOM_TESTS_IGNORE.rst b/Help/variable/CTEST_CUSTOM_TESTS_IGNORE.rst
index 57222ca..27a75d9 100644
--- a/Help/variable/CTEST_CUSTOM_TESTS_IGNORE.rst
+++ b/Help/variable/CTEST_CUSTOM_TESTS_IGNORE.rst
@@ -1,6 +1,8 @@
 CTEST_CUSTOM_TESTS_IGNORE
 -------------------------
 
+.. versionadded:: 3.14
+
 A list of regular expressions to use to exclude tests during the
 :command:`ctest_test` command.
 
diff --git a/Help/variable/CTEST_CUSTOM_WARNING_EXCEPTION.rst b/Help/variable/CTEST_CUSTOM_WARNING_EXCEPTION.rst
index a03d473..539760b 100644
--- a/Help/variable/CTEST_CUSTOM_WARNING_EXCEPTION.rst
+++ b/Help/variable/CTEST_CUSTOM_WARNING_EXCEPTION.rst
@@ -1,6 +1,8 @@
 CTEST_CUSTOM_WARNING_EXCEPTION
 ------------------------------
 
+.. versionadded:: 3.4
+
 A list of regular expressions which will be used to exclude when detecting
 warning messages in build outputs by the :command:`ctest_build` command.
 
diff --git a/Help/variable/CTEST_CUSTOM_WARNING_MATCH.rst b/Help/variable/CTEST_CUSTOM_WARNING_MATCH.rst
index 18aa6b3..53e7707 100644
--- a/Help/variable/CTEST_CUSTOM_WARNING_MATCH.rst
+++ b/Help/variable/CTEST_CUSTOM_WARNING_MATCH.rst
@@ -1,6 +1,8 @@
 CTEST_CUSTOM_WARNING_MATCH
 --------------------------
 
+.. versionadded:: 3.4
+
 A list of regular expressions which will be used to detect warning messages in
 build outputs by the :command:`ctest_build` command.
 
diff --git a/Help/variable/CTEST_CVS_CHECKOUT.rst b/Help/variable/CTEST_CVS_CHECKOUT.rst
index 6431c02..32cf9eb 100644
--- a/Help/variable/CTEST_CVS_CHECKOUT.rst
+++ b/Help/variable/CTEST_CVS_CHECKOUT.rst
@@ -1,4 +1,6 @@
 CTEST_CVS_CHECKOUT
 ------------------
 
+.. versionadded:: 3.1
+
 Deprecated.  Use :variable:`CTEST_CHECKOUT_COMMAND` instead.
diff --git a/Help/variable/CTEST_CVS_COMMAND.rst b/Help/variable/CTEST_CVS_COMMAND.rst
index 049700b..7932070 100644
--- a/Help/variable/CTEST_CVS_COMMAND.rst
+++ b/Help/variable/CTEST_CVS_COMMAND.rst
@@ -1,5 +1,7 @@
 CTEST_CVS_COMMAND
 -----------------
 
+.. versionadded:: 3.1
+
 Specify the CTest ``CVSCommand`` setting
 in a :manual:`ctest(1)` dashboard client script.
diff --git a/Help/variable/CTEST_CVS_UPDATE_OPTIONS.rst b/Help/variable/CTEST_CVS_UPDATE_OPTIONS.rst
index d7f2f7c..359e708 100644
--- a/Help/variable/CTEST_CVS_UPDATE_OPTIONS.rst
+++ b/Help/variable/CTEST_CVS_UPDATE_OPTIONS.rst
@@ -1,5 +1,7 @@
 CTEST_CVS_UPDATE_OPTIONS
 ------------------------
 
+.. versionadded:: 3.1
+
 Specify the CTest ``CVSUpdateOptions`` setting
 in a :manual:`ctest(1)` dashboard client script.
diff --git a/Help/variable/CTEST_DROP_LOCATION.rst b/Help/variable/CTEST_DROP_LOCATION.rst
index c0f2215..f66793b 100644
--- a/Help/variable/CTEST_DROP_LOCATION.rst
+++ b/Help/variable/CTEST_DROP_LOCATION.rst
@@ -1,5 +1,7 @@
 CTEST_DROP_LOCATION
 -------------------
 
+.. versionadded:: 3.1
+
 Specify the CTest ``DropLocation`` setting
 in a :manual:`ctest(1)` dashboard client script.
diff --git a/Help/variable/CTEST_DROP_METHOD.rst b/Help/variable/CTEST_DROP_METHOD.rst
index 50fbd4d..3a84658 100644
--- a/Help/variable/CTEST_DROP_METHOD.rst
+++ b/Help/variable/CTEST_DROP_METHOD.rst
@@ -1,5 +1,7 @@
 CTEST_DROP_METHOD
 -----------------
 
+.. versionadded:: 3.1
+
 Specify the CTest ``DropMethod`` setting
 in a :manual:`ctest(1)` dashboard client script.
diff --git a/Help/variable/CTEST_DROP_SITE.rst b/Help/variable/CTEST_DROP_SITE.rst
index d15d99b..9c871e3 100644
--- a/Help/variable/CTEST_DROP_SITE.rst
+++ b/Help/variable/CTEST_DROP_SITE.rst
@@ -1,5 +1,7 @@
 CTEST_DROP_SITE
 ---------------
 
+.. versionadded:: 3.1
+
 Specify the CTest ``DropSite`` setting
 in a :manual:`ctest(1)` dashboard client script.
diff --git a/Help/variable/CTEST_DROP_SITE_CDASH.rst b/Help/variable/CTEST_DROP_SITE_CDASH.rst
index 22b9776..dcdb286 100644
--- a/Help/variable/CTEST_DROP_SITE_CDASH.rst
+++ b/Help/variable/CTEST_DROP_SITE_CDASH.rst
@@ -1,5 +1,7 @@
 CTEST_DROP_SITE_CDASH
 ---------------------
 
+.. versionadded:: 3.1
+
 Specify the CTest ``IsCDash`` setting
 in a :manual:`ctest(1)` dashboard client script.
diff --git a/Help/variable/CTEST_DROP_SITE_PASSWORD.rst b/Help/variable/CTEST_DROP_SITE_PASSWORD.rst
index 904d2c8..8259651 100644
--- a/Help/variable/CTEST_DROP_SITE_PASSWORD.rst
+++ b/Help/variable/CTEST_DROP_SITE_PASSWORD.rst
@@ -1,5 +1,7 @@
 CTEST_DROP_SITE_PASSWORD
 ------------------------
 
+.. versionadded:: 3.1
+
 Specify the CTest ``DropSitePassword`` setting
 in a :manual:`ctest(1)` dashboard client script.
diff --git a/Help/variable/CTEST_DROP_SITE_USER.rst b/Help/variable/CTEST_DROP_SITE_USER.rst
index a860a03..8d2e3a3 100644
--- a/Help/variable/CTEST_DROP_SITE_USER.rst
+++ b/Help/variable/CTEST_DROP_SITE_USER.rst
@@ -1,5 +1,7 @@
 CTEST_DROP_SITE_USER
 --------------------
 
+.. versionadded:: 3.1
+
 Specify the CTest ``DropSiteUser`` setting
 in a :manual:`ctest(1)` dashboard client script.
diff --git a/Help/variable/CTEST_EXTRA_COVERAGE_GLOB.rst b/Help/variable/CTEST_EXTRA_COVERAGE_GLOB.rst
index 286f7df..1d7e8d4 100644
--- a/Help/variable/CTEST_EXTRA_COVERAGE_GLOB.rst
+++ b/Help/variable/CTEST_EXTRA_COVERAGE_GLOB.rst
@@ -1,6 +1,8 @@
 CTEST_EXTRA_COVERAGE_GLOB
 -------------------------
 
+.. versionadded:: 3.4
+
 A list of regular expressions which will be used to find files which should be
 covered by the :command:`ctest_coverage` command.
 
diff --git a/Help/variable/CTEST_GIT_COMMAND.rst b/Help/variable/CTEST_GIT_COMMAND.rst
index eb83792..eb9b440 100644
--- a/Help/variable/CTEST_GIT_COMMAND.rst
+++ b/Help/variable/CTEST_GIT_COMMAND.rst
@@ -1,5 +1,7 @@
 CTEST_GIT_COMMAND
 -----------------
 
+.. versionadded:: 3.1
+
 Specify the CTest ``GITCommand`` setting
 in a :manual:`ctest(1)` dashboard client script.
diff --git a/Help/variable/CTEST_GIT_INIT_SUBMODULES.rst b/Help/variable/CTEST_GIT_INIT_SUBMODULES.rst
index fd27003..529bfc7 100644
--- a/Help/variable/CTEST_GIT_INIT_SUBMODULES.rst
+++ b/Help/variable/CTEST_GIT_INIT_SUBMODULES.rst
@@ -1,5 +1,7 @@
 CTEST_GIT_INIT_SUBMODULES
 -------------------------
 
+.. versionadded:: 3.6
+
 Specify the CTest ``GITInitSubmodules`` setting
 in a :manual:`ctest(1)` dashboard client script.
diff --git a/Help/variable/CTEST_GIT_UPDATE_CUSTOM.rst b/Help/variable/CTEST_GIT_UPDATE_CUSTOM.rst
index 0c479e6..82a8a6a 100644
--- a/Help/variable/CTEST_GIT_UPDATE_CUSTOM.rst
+++ b/Help/variable/CTEST_GIT_UPDATE_CUSTOM.rst
@@ -1,5 +1,7 @@
 CTEST_GIT_UPDATE_CUSTOM
 -----------------------
 
+.. versionadded:: 3.1
+
 Specify the CTest ``GITUpdateCustom`` setting
 in a :manual:`ctest(1)` dashboard client script.
diff --git a/Help/variable/CTEST_GIT_UPDATE_OPTIONS.rst b/Help/variable/CTEST_GIT_UPDATE_OPTIONS.rst
index 4590a78..1568239 100644
--- a/Help/variable/CTEST_GIT_UPDATE_OPTIONS.rst
+++ b/Help/variable/CTEST_GIT_UPDATE_OPTIONS.rst
@@ -1,5 +1,7 @@
 CTEST_GIT_UPDATE_OPTIONS
 ------------------------
 
+.. versionadded:: 3.1
+
 Specify the CTest ``GITUpdateOptions`` setting
 in a :manual:`ctest(1)` dashboard client script.
diff --git a/Help/variable/CTEST_HG_COMMAND.rst b/Help/variable/CTEST_HG_COMMAND.rst
index 3854950..3372fe4 100644
--- a/Help/variable/CTEST_HG_COMMAND.rst
+++ b/Help/variable/CTEST_HG_COMMAND.rst
@@ -1,5 +1,7 @@
 CTEST_HG_COMMAND
 ----------------
 
+.. versionadded:: 3.1
+
 Specify the CTest ``HGCommand`` setting
 in a :manual:`ctest(1)` dashboard client script.
diff --git a/Help/variable/CTEST_HG_UPDATE_OPTIONS.rst b/Help/variable/CTEST_HG_UPDATE_OPTIONS.rst
index 9049c1f..85c6b03 100644
--- a/Help/variable/CTEST_HG_UPDATE_OPTIONS.rst
+++ b/Help/variable/CTEST_HG_UPDATE_OPTIONS.rst
@@ -1,5 +1,7 @@
 CTEST_HG_UPDATE_OPTIONS
 -----------------------
 
+.. versionadded:: 3.1
+
 Specify the CTest ``HGUpdateOptions`` setting
 in a :manual:`ctest(1)` dashboard client script.
diff --git a/Help/variable/CTEST_LABELS_FOR_SUBPROJECTS.rst b/Help/variable/CTEST_LABELS_FOR_SUBPROJECTS.rst
index 959596b..dd6d125 100644
--- a/Help/variable/CTEST_LABELS_FOR_SUBPROJECTS.rst
+++ b/Help/variable/CTEST_LABELS_FOR_SUBPROJECTS.rst
@@ -1,5 +1,7 @@
 CTEST_LABELS_FOR_SUBPROJECTS
 ----------------------------
 
+.. versionadded:: 3.10
+
 Specify the CTest ``LabelsForSubprojects`` setting
 in a :manual:`ctest(1)` dashboard client script.
diff --git a/Help/variable/CTEST_MEMORYCHECK_COMMAND.rst b/Help/variable/CTEST_MEMORYCHECK_COMMAND.rst
index 8c199ba..25f1bd9 100644
--- a/Help/variable/CTEST_MEMORYCHECK_COMMAND.rst
+++ b/Help/variable/CTEST_MEMORYCHECK_COMMAND.rst
@@ -1,5 +1,7 @@
 CTEST_MEMORYCHECK_COMMAND
 -------------------------
 
+.. versionadded:: 3.1
+
 Specify the CTest ``MemoryCheckCommand`` setting
 in a :manual:`ctest(1)` dashboard client script.
diff --git a/Help/variable/CTEST_MEMORYCHECK_COMMAND_OPTIONS.rst b/Help/variable/CTEST_MEMORYCHECK_COMMAND_OPTIONS.rst
index 3e26ab5..51830d5 100644
--- a/Help/variable/CTEST_MEMORYCHECK_COMMAND_OPTIONS.rst
+++ b/Help/variable/CTEST_MEMORYCHECK_COMMAND_OPTIONS.rst
@@ -1,5 +1,7 @@
 CTEST_MEMORYCHECK_COMMAND_OPTIONS
 ---------------------------------
 
+.. versionadded:: 3.1
+
 Specify the CTest ``MemoryCheckCommandOptions`` setting
 in a :manual:`ctest(1)` dashboard client script.
diff --git a/Help/variable/CTEST_MEMORYCHECK_SANITIZER_OPTIONS.rst b/Help/variable/CTEST_MEMORYCHECK_SANITIZER_OPTIONS.rst
index 2de5fb6..6cd51fa 100644
--- a/Help/variable/CTEST_MEMORYCHECK_SANITIZER_OPTIONS.rst
+++ b/Help/variable/CTEST_MEMORYCHECK_SANITIZER_OPTIONS.rst
@@ -1,5 +1,7 @@
 CTEST_MEMORYCHECK_SANITIZER_OPTIONS
 -----------------------------------
 
+.. versionadded:: 3.1
+
 Specify the CTest ``MemoryCheckSanitizerOptions`` setting
 in a :manual:`ctest(1)` dashboard client script.
diff --git a/Help/variable/CTEST_MEMORYCHECK_SUPPRESSIONS_FILE.rst b/Help/variable/CTEST_MEMORYCHECK_SUPPRESSIONS_FILE.rst
index 1147ee8..a61a3ef 100644
--- a/Help/variable/CTEST_MEMORYCHECK_SUPPRESSIONS_FILE.rst
+++ b/Help/variable/CTEST_MEMORYCHECK_SUPPRESSIONS_FILE.rst
@@ -1,5 +1,7 @@
 CTEST_MEMORYCHECK_SUPPRESSIONS_FILE
 -----------------------------------
 
+.. versionadded:: 3.1
+
 Specify the CTest ``MemoryCheckSuppressionFile`` setting
 in a :manual:`ctest(1)` dashboard client script.
diff --git a/Help/variable/CTEST_MEMORYCHECK_TYPE.rst b/Help/variable/CTEST_MEMORYCHECK_TYPE.rst
index 4e7d5c0..2452228 100644
--- a/Help/variable/CTEST_MEMORYCHECK_TYPE.rst
+++ b/Help/variable/CTEST_MEMORYCHECK_TYPE.rst
@@ -1,6 +1,8 @@
 CTEST_MEMORYCHECK_TYPE
 ----------------------
 
+.. versionadded:: 3.1
+
 Specify the CTest ``MemoryCheckType`` setting
 in a :manual:`ctest(1)` dashboard client script.
 Valid values are ``Valgrind``, ``Purify``, ``BoundsChecker``, ``DrMemory`` and
diff --git a/Help/variable/CTEST_NIGHTLY_START_TIME.rst b/Help/variable/CTEST_NIGHTLY_START_TIME.rst
index bc80276..2d707d5 100644
--- a/Help/variable/CTEST_NIGHTLY_START_TIME.rst
+++ b/Help/variable/CTEST_NIGHTLY_START_TIME.rst
@@ -1,5 +1,11 @@
 CTEST_NIGHTLY_START_TIME
 ------------------------
 
-Specify the CTest ``NightlyStartTime`` setting
-in a :manual:`ctest(1)` dashboard client script.
+.. versionadded:: 3.1
+
+Specify the CTest ``NightlyStartTime`` setting in a :manual:`ctest(1)`
+dashboard client script.
+
+Note that this variable must always be set for a nightly build in a
+dashboard script. It is needed so that nightly builds can be properly grouped
+together in CDash.
diff --git a/Help/variable/CTEST_P4_CLIENT.rst b/Help/variable/CTEST_P4_CLIENT.rst
index 347ea54..0778c5b 100644
--- a/Help/variable/CTEST_P4_CLIENT.rst
+++ b/Help/variable/CTEST_P4_CLIENT.rst
@@ -1,5 +1,7 @@
 CTEST_P4_CLIENT
 ---------------
 
+.. versionadded:: 3.1
+
 Specify the CTest ``P4Client`` setting
 in a :manual:`ctest(1)` dashboard client script.
diff --git a/Help/variable/CTEST_P4_COMMAND.rst b/Help/variable/CTEST_P4_COMMAND.rst
index defab12..5cc2a81 100644
--- a/Help/variable/CTEST_P4_COMMAND.rst
+++ b/Help/variable/CTEST_P4_COMMAND.rst
@@ -1,5 +1,7 @@
 CTEST_P4_COMMAND
 ----------------
 
+.. versionadded:: 3.1
+
 Specify the CTest ``P4Command`` setting
 in a :manual:`ctest(1)` dashboard client script.
diff --git a/Help/variable/CTEST_P4_OPTIONS.rst b/Help/variable/CTEST_P4_OPTIONS.rst
index fee4ce2..01b6534 100644
--- a/Help/variable/CTEST_P4_OPTIONS.rst
+++ b/Help/variable/CTEST_P4_OPTIONS.rst
@@ -1,5 +1,7 @@
 CTEST_P4_OPTIONS
 ----------------
 
+.. versionadded:: 3.1
+
 Specify the CTest ``P4Options`` setting
 in a :manual:`ctest(1)` dashboard client script.
diff --git a/Help/variable/CTEST_P4_UPDATE_OPTIONS.rst b/Help/variable/CTEST_P4_UPDATE_OPTIONS.rst
index 0e2790f..365aa3f 100644
--- a/Help/variable/CTEST_P4_UPDATE_OPTIONS.rst
+++ b/Help/variable/CTEST_P4_UPDATE_OPTIONS.rst
@@ -1,5 +1,7 @@
 CTEST_P4_UPDATE_OPTIONS
 -----------------------
 
+.. versionadded:: 3.1
+
 Specify the CTest ``P4UpdateOptions`` setting
 in a :manual:`ctest(1)` dashboard client script.
diff --git a/Help/variable/CTEST_RESOURCE_SPEC_FILE.rst b/Help/variable/CTEST_RESOURCE_SPEC_FILE.rst
new file mode 100644
index 0000000..8e9bf01
--- /dev/null
+++ b/Help/variable/CTEST_RESOURCE_SPEC_FILE.rst
@@ -0,0 +1,12 @@
+CTEST_RESOURCE_SPEC_FILE
+------------------------
+
+.. versionadded:: 3.18
+
+Specify the CTest ``ResourceSpecFile`` setting in a :manual:`ctest(1)`
+dashboard client script.
+
+This can also be used to specify the resource spec file from a CMake build. If
+no ``RESOURCE_SPEC_FILE`` is passed to :command:`ctest_test`, and
+``CTEST_RESOURCE_SPEC_FILE`` is not specified in the dashboard script, the
+value of this variable from the build is used.
diff --git a/Help/variable/CTEST_RUN_CURRENT_SCRIPT.rst b/Help/variable/CTEST_RUN_CURRENT_SCRIPT.rst
index abc123c..32c85ad 100644
--- a/Help/variable/CTEST_RUN_CURRENT_SCRIPT.rst
+++ b/Help/variable/CTEST_RUN_CURRENT_SCRIPT.rst
@@ -1,5 +1,7 @@
 CTEST_RUN_CURRENT_SCRIPT
 ------------------------
 
+.. versionadded:: 3.11
+
 Setting this to 0 prevents :manual:`ctest(1)` from being run again when it
 reaches the end of a script run by calling ``ctest -S``.
diff --git a/Help/variable/CTEST_SCP_COMMAND.rst b/Help/variable/CTEST_SCP_COMMAND.rst
index 19ea8b3..155b058 100644
--- a/Help/variable/CTEST_SCP_COMMAND.rst
+++ b/Help/variable/CTEST_SCP_COMMAND.rst
@@ -1,4 +1,6 @@
 CTEST_SCP_COMMAND
 -----------------
 
+.. versionadded:: 3.1
+
 Legacy option.  Not used.
diff --git a/Help/variable/CTEST_SITE.rst b/Help/variable/CTEST_SITE.rst
index 8a5ec25..526e6ed 100644
--- a/Help/variable/CTEST_SITE.rst
+++ b/Help/variable/CTEST_SITE.rst
@@ -1,5 +1,7 @@
 CTEST_SITE
 ----------
 
+.. versionadded:: 3.1
+
 Specify the CTest ``Site`` setting
 in a :manual:`ctest(1)` dashboard client script.
diff --git a/Help/variable/CTEST_SOURCE_DIRECTORY.rst b/Help/variable/CTEST_SOURCE_DIRECTORY.rst
index b6837d1..4c6ac54 100644
--- a/Help/variable/CTEST_SOURCE_DIRECTORY.rst
+++ b/Help/variable/CTEST_SOURCE_DIRECTORY.rst
@@ -1,5 +1,7 @@
 CTEST_SOURCE_DIRECTORY
 ----------------------
 
+.. versionadded:: 3.1
+
 Specify the CTest ``SourceDirectory`` setting
 in a :manual:`ctest(1)` dashboard client script.
diff --git a/Help/variable/CTEST_SUBMIT_URL.rst b/Help/variable/CTEST_SUBMIT_URL.rst
index 7d84da4..b6e7f68 100644
--- a/Help/variable/CTEST_SUBMIT_URL.rst
+++ b/Help/variable/CTEST_SUBMIT_URL.rst
@@ -1,5 +1,7 @@
 CTEST_SUBMIT_URL
 ----------------
 
+.. versionadded:: 3.14
+
 Specify the CTest ``SubmitURL`` setting
 in a :manual:`ctest(1)` dashboard client script.
diff --git a/Help/variable/CTEST_SVN_COMMAND.rst b/Help/variable/CTEST_SVN_COMMAND.rst
index af90143..e97acd0 100644
--- a/Help/variable/CTEST_SVN_COMMAND.rst
+++ b/Help/variable/CTEST_SVN_COMMAND.rst
@@ -1,5 +1,7 @@
 CTEST_SVN_COMMAND
 -----------------
 
+.. versionadded:: 3.1
+
 Specify the CTest ``SVNCommand`` setting
 in a :manual:`ctest(1)` dashboard client script.
diff --git a/Help/variable/CTEST_SVN_OPTIONS.rst b/Help/variable/CTEST_SVN_OPTIONS.rst
index 76551dc..5326e20 100644
--- a/Help/variable/CTEST_SVN_OPTIONS.rst
+++ b/Help/variable/CTEST_SVN_OPTIONS.rst
@@ -1,5 +1,7 @@
 CTEST_SVN_OPTIONS
 -----------------
 
+.. versionadded:: 3.1
+
 Specify the CTest ``SVNOptions`` setting
 in a :manual:`ctest(1)` dashboard client script.
diff --git a/Help/variable/CTEST_SVN_UPDATE_OPTIONS.rst b/Help/variable/CTEST_SVN_UPDATE_OPTIONS.rst
index 5f01a19..24e0bbf 100644
--- a/Help/variable/CTEST_SVN_UPDATE_OPTIONS.rst
+++ b/Help/variable/CTEST_SVN_UPDATE_OPTIONS.rst
@@ -1,5 +1,7 @@
 CTEST_SVN_UPDATE_OPTIONS
 ------------------------
 
+.. versionadded:: 3.1
+
 Specify the CTest ``SVNUpdateOptions`` setting
 in a :manual:`ctest(1)` dashboard client script.
diff --git a/Help/variable/CTEST_TEST_LOAD.rst b/Help/variable/CTEST_TEST_LOAD.rst
index 80823fe..b6a9d62 100644
--- a/Help/variable/CTEST_TEST_LOAD.rst
+++ b/Help/variable/CTEST_TEST_LOAD.rst
@@ -1,6 +1,8 @@
 CTEST_TEST_LOAD
 ---------------
 
+.. versionadded:: 3.4
+
 Specify the ``TestLoad`` setting in the :ref:`CTest Test Step`
 of a :manual:`ctest(1)` dashboard client script.  This sets the
 default value for the ``TEST_LOAD`` option of the :command:`ctest_test`
diff --git a/Help/variable/CTEST_TEST_TIMEOUT.rst b/Help/variable/CTEST_TEST_TIMEOUT.rst
index c031437..61d9191 100644
--- a/Help/variable/CTEST_TEST_TIMEOUT.rst
+++ b/Help/variable/CTEST_TEST_TIMEOUT.rst
@@ -1,5 +1,7 @@
 CTEST_TEST_TIMEOUT
 ------------------
 
+.. versionadded:: 3.1
+
 Specify the CTest ``TimeOut`` setting
 in a :manual:`ctest(1)` dashboard client script.
diff --git a/Help/variable/CTEST_TRIGGER_SITE.rst b/Help/variable/CTEST_TRIGGER_SITE.rst
index a50e405..6abb852 100644
--- a/Help/variable/CTEST_TRIGGER_SITE.rst
+++ b/Help/variable/CTEST_TRIGGER_SITE.rst
@@ -1,4 +1,6 @@
 CTEST_TRIGGER_SITE
 ------------------
 
+.. versionadded:: 3.1
+
 Legacy option.  Not used.
diff --git a/Help/variable/CTEST_UPDATE_COMMAND.rst b/Help/variable/CTEST_UPDATE_COMMAND.rst
index 90155d0..c4ed645 100644
--- a/Help/variable/CTEST_UPDATE_COMMAND.rst
+++ b/Help/variable/CTEST_UPDATE_COMMAND.rst
@@ -1,5 +1,7 @@
 CTEST_UPDATE_COMMAND
 --------------------
 
+.. versionadded:: 3.1
+
 Specify the CTest ``UpdateCommand`` setting
 in a :manual:`ctest(1)` dashboard client script.
diff --git a/Help/variable/CTEST_UPDATE_OPTIONS.rst b/Help/variable/CTEST_UPDATE_OPTIONS.rst
index e43d61d..96c4b6c 100644
--- a/Help/variable/CTEST_UPDATE_OPTIONS.rst
+++ b/Help/variable/CTEST_UPDATE_OPTIONS.rst
@@ -1,5 +1,7 @@
 CTEST_UPDATE_OPTIONS
 --------------------
 
+.. versionadded:: 3.1
+
 Specify the CTest ``UpdateOptions`` setting
 in a :manual:`ctest(1)` dashboard client script.
diff --git a/Help/variable/CTEST_UPDATE_VERSION_ONLY.rst b/Help/variable/CTEST_UPDATE_VERSION_ONLY.rst
index a862baa..f7c863c 100644
--- a/Help/variable/CTEST_UPDATE_VERSION_ONLY.rst
+++ b/Help/variable/CTEST_UPDATE_VERSION_ONLY.rst
@@ -1,5 +1,7 @@
 CTEST_UPDATE_VERSION_ONLY
 -------------------------
 
+.. versionadded:: 3.1
+
 Specify the CTest :ref:`UpdateVersionOnly <UpdateVersionOnly>` setting
 in a :manual:`ctest(1)` dashboard client script.
diff --git a/Help/variable/CTEST_UPDATE_VERSION_OVERRIDE.rst b/Help/variable/CTEST_UPDATE_VERSION_OVERRIDE.rst
index 39fbaba..87918cb 100644
--- a/Help/variable/CTEST_UPDATE_VERSION_OVERRIDE.rst
+++ b/Help/variable/CTEST_UPDATE_VERSION_OVERRIDE.rst
@@ -1,5 +1,7 @@
 CTEST_UPDATE_VERSION_OVERRIDE
 -----------------------------
 
+.. versionadded:: 3.15
+
 Specify the CTest :ref:`UpdateVersionOverride <UpdateVersionOverride>` setting
 in a :manual:`ctest(1)` dashboard client script.
diff --git a/Help/variable/CTEST_USE_LAUNCHERS.rst b/Help/variable/CTEST_USE_LAUNCHERS.rst
index 9f48a2e..728cdc5 100644
--- a/Help/variable/CTEST_USE_LAUNCHERS.rst
+++ b/Help/variable/CTEST_USE_LAUNCHERS.rst
@@ -1,5 +1,7 @@
 CTEST_USE_LAUNCHERS
 -------------------
 
+.. versionadded:: 3.1
+
 Specify the CTest ``UseLaunchers`` setting
 in a :manual:`ctest(1)` dashboard client script.
diff --git a/Help/variable/GHS-MULTI.rst b/Help/variable/GHS-MULTI.rst
index fe3b17e..bb139af 100644
--- a/Help/variable/GHS-MULTI.rst
+++ b/Help/variable/GHS-MULTI.rst
@@ -1,4 +1,6 @@
 GHS-MULTI
 ---------
 
+.. versionadded:: 3.3
+
 ``True`` when using :generator:`Green Hills MULTI` generator.
diff --git a/Help/variable/IOS.rst b/Help/variable/IOS.rst
index e5cc3f6..b27be55 100644
--- a/Help/variable/IOS.rst
+++ b/Help/variable/IOS.rst
@@ -1,4 +1,6 @@
 IOS
 ---
 
+.. versionadded:: 3.14
+
 Set to ``1`` when the target system (:variable:`CMAKE_SYSTEM_NAME`) is ``iOS``.
diff --git a/Help/variable/MINGW.rst b/Help/variable/MINGW.rst
index 6d29be4..27c56ea 100644
--- a/Help/variable/MINGW.rst
+++ b/Help/variable/MINGW.rst
@@ -1,6 +1,8 @@
 MINGW
 -----
 
+.. versionadded:: 3.2
+
 ``True`` when using MinGW
 
 Set to ``true`` when the compiler is some version of MinGW.
diff --git a/Help/variable/MSVC14.rst b/Help/variable/MSVC14.rst
index 79e0c10..1eb5183 100644
--- a/Help/variable/MSVC14.rst
+++ b/Help/variable/MSVC14.rst
@@ -1,6 +1,8 @@
 MSVC14
 ------
 
+.. versionadded:: 3.1
+
 Discouraged.  Use the :variable:`MSVC_VERSION` variable instead.
 
 ``True`` when using the Microsoft Visual Studio ``v140`` or ``v141``
diff --git a/Help/variable/MSVC_TOOLSET_VERSION.rst b/Help/variable/MSVC_TOOLSET_VERSION.rst
index f4a33e2..c642a9f 100644
--- a/Help/variable/MSVC_TOOLSET_VERSION.rst
+++ b/Help/variable/MSVC_TOOLSET_VERSION.rst
@@ -1,6 +1,8 @@
 MSVC_TOOLSET_VERSION
 --------------------
 
+.. versionadded:: 3.12
+
 The toolset version of Microsoft Visual C/C++ being used if any.
 If MSVC-like is being used, this variable is set based on the version
 of the compiler as given by the :variable:`MSVC_VERSION` variable.
diff --git a/Help/variable/MSYS.rst b/Help/variable/MSYS.rst
index 25ddc7f..6be7681 100644
--- a/Help/variable/MSYS.rst
+++ b/Help/variable/MSYS.rst
@@ -1,4 +1,6 @@
 MSYS
 ----
 
+.. versionadded:: 3.14
+
 ``True`` when using the :generator:`MSYS Makefiles` generator.
diff --git a/Help/variable/PROJECT-NAME_DESCRIPTION.rst b/Help/variable/PROJECT-NAME_DESCRIPTION.rst
index 2b88b1a..f372f5c 100644
--- a/Help/variable/PROJECT-NAME_DESCRIPTION.rst
+++ b/Help/variable/PROJECT-NAME_DESCRIPTION.rst
@@ -1,5 +1,7 @@
 <PROJECT-NAME>_DESCRIPTION
 --------------------------
 
+.. versionadded:: 3.12
+
 Value given to the ``DESCRIPTION`` option of the most recent call to the
 :command:`project` command with project name ``<PROJECT-NAME>``, if any.
diff --git a/Help/variable/PROJECT-NAME_HOMEPAGE_URL.rst b/Help/variable/PROJECT-NAME_HOMEPAGE_URL.rst
index 22cc304..4800b13 100644
--- a/Help/variable/PROJECT-NAME_HOMEPAGE_URL.rst
+++ b/Help/variable/PROJECT-NAME_HOMEPAGE_URL.rst
@@ -1,5 +1,7 @@
 <PROJECT-NAME>_HOMEPAGE_URL
 ---------------------------
 
+.. versionadded:: 3.12
+
 Value given to the ``HOMEPAGE_URL`` option of the most recent call to the
 :command:`project` command with project name ``<PROJECT-NAME>``, if any.
diff --git a/Help/variable/PROJECT_DESCRIPTION.rst b/Help/variable/PROJECT_DESCRIPTION.rst
index 2833e11..1fefcdc 100644
--- a/Help/variable/PROJECT_DESCRIPTION.rst
+++ b/Help/variable/PROJECT_DESCRIPTION.rst
@@ -1,6 +1,8 @@
 PROJECT_DESCRIPTION
 -------------------
 
+.. versionadded:: 3.9
+
 Short project description given to the project command.
 
 This is the description given to the most recently called :command:`project`
diff --git a/Help/variable/PROJECT_HOMEPAGE_URL.rst b/Help/variable/PROJECT_HOMEPAGE_URL.rst
index 754c9e8..0d2c937 100644
--- a/Help/variable/PROJECT_HOMEPAGE_URL.rst
+++ b/Help/variable/PROJECT_HOMEPAGE_URL.rst
@@ -1,6 +1,8 @@
 PROJECT_HOMEPAGE_URL
 --------------------
 
+.. versionadded:: 3.12
+
 The homepage URL of the project.
 
 This is the homepage URL given to the most recently called :command:`project`
diff --git a/Help/variable/PROJECT_SOURCE_DIR.rst b/Help/variable/PROJECT_SOURCE_DIR.rst
index 27f2838..b4601c2 100644
--- a/Help/variable/PROJECT_SOURCE_DIR.rst
+++ b/Help/variable/PROJECT_SOURCE_DIR.rst
@@ -1,6 +1,8 @@
 PROJECT_SOURCE_DIR
 ------------------
 
-Top level source directory for the current project.
-
-This is the source directory of the most recent :command:`project` command.
+This is the source directory of the last call to the
+:command:`project` command made in the current directory scope or one
+of its parents. Note, it is not affected by calls to
+:command:`project` made within a child directory scope (i.e. from
+within a call to :command:`add_subdirectory` from the current scope).
diff --git a/Help/variable/PackageName_ROOT.rst b/Help/variable/PackageName_ROOT.rst
index 1c2fd34..3f7ee4c 100644
--- a/Help/variable/PackageName_ROOT.rst
+++ b/Help/variable/PackageName_ROOT.rst
@@ -1,6 +1,8 @@
 <PackageName>_ROOT
 ------------------
 
+.. versionadded:: 3.12.1
+
 Calls to :command:`find_package(<PackageName>)` will search in prefixes
 specified by the ``<PackageName>_ROOT`` CMake variable, where
 ``<PackageName>`` is the name given to the :command:`find_package` call
diff --git a/Help/variable/WINCE.rst b/Help/variable/WINCE.rst
index 54ff7de..4dca297 100644
--- a/Help/variable/WINCE.rst
+++ b/Help/variable/WINCE.rst
@@ -1,5 +1,7 @@
 WINCE
 -----
 
+.. versionadded:: 3.1
+
 True when the :variable:`CMAKE_SYSTEM_NAME` variable is set
 to ``WindowsCE``.
diff --git a/Help/variable/WINDOWS_PHONE.rst b/Help/variable/WINDOWS_PHONE.rst
index 61d91b0..bf7099d 100644
--- a/Help/variable/WINDOWS_PHONE.rst
+++ b/Help/variable/WINDOWS_PHONE.rst
@@ -1,5 +1,7 @@
 WINDOWS_PHONE
 -------------
 
+.. versionadded:: 3.1
+
 True when the :variable:`CMAKE_SYSTEM_NAME` variable is set
 to ``WindowsPhone``.
diff --git a/Help/variable/WINDOWS_STORE.rst b/Help/variable/WINDOWS_STORE.rst
index dae3b53..13831c2 100644
--- a/Help/variable/WINDOWS_STORE.rst
+++ b/Help/variable/WINDOWS_STORE.rst
@@ -1,5 +1,7 @@
 WINDOWS_STORE
 -------------
 
+.. versionadded:: 3.1
+
 True when the :variable:`CMAKE_SYSTEM_NAME` variable is set
 to ``WindowsStore``.
diff --git a/Help/variable/XCODE.rst b/Help/variable/XCODE.rst
index 99f20fb..167ca86 100644
--- a/Help/variable/XCODE.rst
+++ b/Help/variable/XCODE.rst
@@ -1,4 +1,6 @@
 XCODE
 -----
 
+.. versionadded:: 3.7
+
 ``True`` when using :generator:`Xcode` generator.
diff --git a/Modules/AndroidTestUtilities.cmake b/Modules/AndroidTestUtilities.cmake
index 95e2ef7..ddccf58 100644
--- a/Modules/AndroidTestUtilities.cmake
+++ b/Modules/AndroidTestUtilities.cmake
@@ -5,6 +5,8 @@
 AndroidTestUtilities
 ------------------------
 
+.. versionadded:: 3.7
+
 Create a test that automatically loads specified data onto an Android device.
 
 Introduction
diff --git a/Modules/BundleUtilities.cmake b/Modules/BundleUtilities.cmake
index 2f3b9e1..f521d22 100644
--- a/Modules/BundleUtilities.cmake
+++ b/Modules/BundleUtilities.cmake
@@ -894,11 +894,16 @@
   # to install_name_tool:
   #
   if(changes)
-    set(cmd ${CMAKE_INSTALL_NAME_TOOL} ${changes} "${resolved_embedded_item}")
-    execute_process(COMMAND ${cmd} RESULT_VARIABLE install_name_tool_result)
-    if(NOT install_name_tool_result EQUAL 0)
-      string(REPLACE ";" "' '" msg "'${cmd}'")
-      message(FATAL_ERROR "Command failed:\n ${msg}")
+    # Check for a script by extension (.bat,.sh,...) or if the file starts with "#!" (shebang)
+    file(READ ${resolved_embedded_item} file_contents LIMIT 5)
+    if(NOT "${resolved_embedded_item}" MATCHES "\\.(bat|c?sh|bash|ksh|cmd)$" AND
+       NOT file_contents MATCHES "^#!")
+      set(cmd ${CMAKE_INSTALL_NAME_TOOL} ${changes} "${resolved_embedded_item}")
+      execute_process(COMMAND ${cmd} RESULT_VARIABLE install_name_tool_result)
+      if(NOT install_name_tool_result EQUAL 0)
+        string(REPLACE ";" "' '" msg "'${cmd}'")
+        message(FATAL_ERROR "Command failed:\n ${msg}")
+      endif()
     endif()
   endif()
 endfunction()
diff --git a/Modules/CMakeASMCompiler.cmake.in b/Modules/CMakeASMCompiler.cmake.in
index b8e09fe..3953b30 100644
--- a/Modules/CMakeASMCompiler.cmake.in
+++ b/Modules/CMakeASMCompiler.cmake.in
@@ -10,7 +10,9 @@
 set(CMAKE_ASM@ASM_DIALECT@_COMPILER_ID "@_CMAKE_ASM_COMPILER_ID@")
 set(CMAKE_ASM@ASM_DIALECT@_COMPILER_VERSION "@_CMAKE_ASM_COMPILER_VERSION@")
 set(CMAKE_ASM@ASM_DIALECT@_COMPILER_ENV_VAR "@_CMAKE_ASM_COMPILER_ENV_VAR@")
+@_SET_CMAKE_ASM_COMPILER_ID_VENDOR_MATCH@
 @_SET_CMAKE_ASM_COMPILER_ARCHITECTURE_ID@
+@_SET_CMAKE_ASM_COMPILER_SYSROOT@
 
 set(CMAKE_ASM@ASM_DIALECT@_IGNORE_EXTENSIONS h;H;o;O;obj;OBJ;def;DEF;rc;RC)
 set(CMAKE_ASM@ASM_DIALECT@_LINKER_PREFERENCE 0)
diff --git a/Modules/CMakeASMInformation.cmake b/Modules/CMakeASMInformation.cmake
index 6b73730..2dc1585 100644
--- a/Modules/CMakeASMInformation.cmake
+++ b/Modules/CMakeASMInformation.cmake
@@ -76,12 +76,12 @@
 if(NOT CMAKE_ASM${ASM_DIALECT}_CREATE_STATIC_LIBRARY)
   set(CMAKE_ASM${ASM_DIALECT}_CREATE_STATIC_LIBRARY
       "<CMAKE_AR> cr <TARGET> <LINK_FLAGS> <OBJECTS> "
-      "<CMAKE_RANLIB> <TARGET> ")
+      "<CMAKE_RANLIB> <TARGET>")
 endif()
 
 if(NOT CMAKE_ASM${ASM_DIALECT}_LINK_EXECUTABLE)
   set(CMAKE_ASM${ASM_DIALECT}_LINK_EXECUTABLE
-    "<CMAKE_ASM${ASM_DIALECT}_COMPILER> <FLAGS> <CMAKE_ASM${ASM_DIALECT}_LINK_FLAGS> <LINK_FLAGS> <OBJECTS>  -o <TARGET> <LINK_LIBRARIES>")
+    "<CMAKE_ASM${ASM_DIALECT}_COMPILER> <FLAGS> <CMAKE_ASM${ASM_DIALECT}_LINK_FLAGS> <LINK_FLAGS> <OBJECTS> -o <TARGET> <LINK_LIBRARIES>")
 endif()
 
 if(NOT CMAKE_EXECUTABLE_RUNTIME_ASM${ASM_DIALECT}_FLAG)
@@ -96,15 +96,5 @@
   set(CMAKE_EXECUTABLE_RPATH_LINK_ASM${ASM_DIALECT}_FLAG ${CMAKE_SHARED_LIBRARY_RPATH_LINK_ASM${ASM_DIALECT}_FLAG})
 endif()
 
-# to be done
-if(NOT CMAKE_ASM${ASM_DIALECT}_CREATE_SHARED_LIBRARY)
-  set(CMAKE_ASM${ASM_DIALECT}_CREATE_SHARED_LIBRARY)
-endif()
-
-if(NOT CMAKE_ASM${ASM_DIALECT}_CREATE_SHARED_MODULE)
-  set(CMAKE_ASM${ASM_DIALECT}_CREATE_SHARED_MODULE)
-endif()
-
 
 set(CMAKE_ASM${ASM_DIALECT}_INFOMATION_LOADED 1)
-
diff --git a/Modules/CMakeASM_MASMInformation.cmake b/Modules/CMakeASM_MASMInformation.cmake
index 9f7e934..6d1e174 100644
--- a/Modules/CMakeASM_MASMInformation.cmake
+++ b/Modules/CMakeASM_MASMInformation.cmake
@@ -8,7 +8,7 @@
 
 set(CMAKE_ASM${ASM_DIALECT}_SOURCE_FILE_EXTENSIONS asm)
 
-set(CMAKE_ASM${ASM_DIALECT}_COMPILE_OBJECT "<CMAKE_ASM${ASM_DIALECT}_COMPILER> <DEFINES> <INCLUDES> <FLAGS> /c  /Fo <OBJECT> <SOURCE>")
+set(CMAKE_ASM${ASM_DIALECT}_COMPILE_OBJECT "<CMAKE_ASM${ASM_DIALECT}_COMPILER> <DEFINES> <INCLUDES> <FLAGS> /c /Fo <OBJECT> <SOURCE>")
 
 # The ASM_MASM compiler id for this compiler is "MSVC", so fill out the runtime library table.
 set(CMAKE_ASM${ASM_DIALECT}_COMPILE_OPTIONS_MSVC_RUNTIME_LIBRARY_MultiThreaded         "")
diff --git a/Modules/CMakeASM_NASMInformation.cmake b/Modules/CMakeASM_NASMInformation.cmake
index cb793e7..97cb488 100644
--- a/Modules/CMakeASM_NASMInformation.cmake
+++ b/Modules/CMakeASM_NASMInformation.cmake
@@ -8,19 +8,25 @@
 
 if(NOT CMAKE_ASM_NASM_OBJECT_FORMAT)
   if(WIN32)
-    if(CMAKE_C_SIZEOF_DATA_PTR EQUAL 8)
+    if(DEFINED CMAKE_C_SIZEOF_DATA_PTR AND CMAKE_C_SIZEOF_DATA_PTR EQUAL 8)
+      set(CMAKE_ASM_NASM_OBJECT_FORMAT win64)
+    elseif(DEFINED CMAKE_CXX_SIZEOF_DATA_PTR AND CMAKE_CXX_SIZEOF_DATA_PTR EQUAL 8)
       set(CMAKE_ASM_NASM_OBJECT_FORMAT win64)
     else()
       set(CMAKE_ASM_NASM_OBJECT_FORMAT win32)
     endif()
   elseif(APPLE)
-    if(CMAKE_C_SIZEOF_DATA_PTR EQUAL 8)
+    if(DEFINED CMAKE_C_SIZEOF_DATA_PTR AND CMAKE_C_SIZEOF_DATA_PTR EQUAL 8)
+      set(CMAKE_ASM_NASM_OBJECT_FORMAT macho64)
+    elseif(DEFINED CMAKE_CXX_SIZEOF_DATA_PTR AND CMAKE_CXX_SIZEOF_DATA_PTR EQUAL 8)
       set(CMAKE_ASM_NASM_OBJECT_FORMAT macho64)
     else()
       set(CMAKE_ASM_NASM_OBJECT_FORMAT macho)
     endif()
   else()
-    if(CMAKE_C_SIZEOF_DATA_PTR EQUAL 8)
+    if(DEFINED CMAKE_C_SIZEOF_DATA_PTR AND CMAKE_C_SIZEOF_DATA_PTR EQUAL 8)
+      set(CMAKE_ASM_NASM_OBJECT_FORMAT elf64)
+    elseif(DEFINED CMAKE_CXX_SIZEOF_DATA_PTR AND CMAKE_CXX_SIZEOF_DATA_PTR EQUAL 8)
       set(CMAKE_ASM_NASM_OBJECT_FORMAT elf64)
     else()
       set(CMAKE_ASM_NASM_OBJECT_FORMAT elf)
diff --git a/Modules/CMakeCCompiler.cmake.in b/Modules/CMakeCCompiler.cmake.in
index 9b8d423..eea3f5d 100644
--- a/Modules/CMakeCCompiler.cmake.in
+++ b/Modules/CMakeCCompiler.cmake.in
@@ -15,6 +15,7 @@
 set(CMAKE_C_COMPILER_FRONTEND_VARIANT "@CMAKE_C_COMPILER_FRONTEND_VARIANT@")
 set(CMAKE_C_SIMULATE_VERSION "@CMAKE_C_SIMULATE_VERSION@")
 @_SET_CMAKE_C_COMPILER_ARCHITECTURE_ID@
+@_SET_CMAKE_C_COMPILER_SYSROOT@
 @SET_MSVC_C_ARCHITECTURE_ID@
 @SET_CMAKE_XCODE_ARCHS@
 set(CMAKE_AR "@CMAKE_AR@")
diff --git a/Modules/CMakeCInformation.cmake b/Modules/CMakeCInformation.cmake
index 1e08bb7..f6d620f 100644
--- a/Modules/CMakeCInformation.cmake
+++ b/Modules/CMakeCInformation.cmake
@@ -161,7 +161,7 @@
   set(CMAKE_C_ARCHIVE_CREATE "<CMAKE_AR> qc <TARGET> <LINK_FLAGS> <OBJECTS>")
 endif()
 if(NOT DEFINED CMAKE_C_ARCHIVE_APPEND)
-  set(CMAKE_C_ARCHIVE_APPEND "<CMAKE_AR> q  <TARGET> <LINK_FLAGS> <OBJECTS>")
+  set(CMAKE_C_ARCHIVE_APPEND "<CMAKE_AR> q <TARGET> <LINK_FLAGS> <OBJECTS>")
 endif()
 if(NOT DEFINED CMAKE_C_ARCHIVE_FINISH)
   set(CMAKE_C_ARCHIVE_FINISH "<CMAKE_RANLIB> <TARGET>")
@@ -170,12 +170,12 @@
 # compile a C file into an object file
 if(NOT CMAKE_C_COMPILE_OBJECT)
   set(CMAKE_C_COMPILE_OBJECT
-    "<CMAKE_C_COMPILER> <DEFINES> <INCLUDES> <FLAGS> -o <OBJECT>   -c <SOURCE>")
+    "<CMAKE_C_COMPILER> <DEFINES> <INCLUDES> <FLAGS> -o <OBJECT> -c <SOURCE>")
 endif()
 
 if(NOT CMAKE_C_LINK_EXECUTABLE)
   set(CMAKE_C_LINK_EXECUTABLE
-    "<CMAKE_C_COMPILER> <FLAGS> <CMAKE_C_LINK_FLAGS> <LINK_FLAGS> <OBJECTS>  -o <TARGET> <LINK_LIBRARIES>")
+    "<CMAKE_C_COMPILER> <FLAGS> <CMAKE_C_LINK_FLAGS> <LINK_FLAGS> <OBJECTS> -o <TARGET> <LINK_LIBRARIES>")
 endif()
 
 if(NOT CMAKE_EXECUTABLE_RUNTIME_C_FLAG)
diff --git a/Modules/CMakeCUDACompiler.cmake.in b/Modules/CMakeCUDACompiler.cmake.in
index 04a4c42..704ad09 100644
--- a/Modules/CMakeCUDACompiler.cmake.in
+++ b/Modules/CMakeCUDACompiler.cmake.in
@@ -16,6 +16,7 @@
 set(CMAKE_CUDA_COMPILER_FRONTEND_VARIANT "@CMAKE_CUDA_COMPILER_FRONTEND_VARIANT@")
 set(CMAKE_CUDA_SIMULATE_VERSION "@CMAKE_CUDA_SIMULATE_VERSION@")
 @SET_MSVC_CUDA_ARCHITECTURE_ID@
+@_SET_CMAKE_CUDA_COMPILER_SYSROOT@
 
 set(CMAKE_CUDA_COMPILER_ENV_VAR "CUDACXX")
 set(CMAKE_CUDA_HOST_COMPILER_ENV_VAR "CUDAHOSTCXX")
@@ -42,6 +43,9 @@
   set(CMAKE_LIBRARY_ARCHITECTURE "@CMAKE_CUDA_LIBRARY_ARCHITECTURE@")
 endif()
 
+set(CMAKE_CUDA_COMPILER_TOOLKIT_ROOT "@CMAKE_CUDA_COMPILER_TOOLKIT_ROOT@")
+set(CMAKE_CUDA_COMPILER_LIBRARY_ROOT "@CMAKE_CUDA_COMPILER_LIBRARY_ROOT@")
+
 set(CMAKE_CUDA_TOOLKIT_INCLUDE_DIRECTORIES "@CMAKE_CUDA_TOOLKIT_INCLUDE_DIRECTORIES@")
 
 set(CMAKE_CUDA_HOST_IMPLICIT_LINK_LIBRARIES "@CMAKE_CUDA_HOST_IMPLICIT_LINK_LIBRARIES@")
@@ -56,4 +60,5 @@
 @_SET_CMAKE_CUDA_RUNTIME_LIBRARY_DEFAULT@
 
 set(CMAKE_LINKER "@CMAKE_LINKER@")
+set(CMAKE_AR "@CMAKE_AR@")
 set(CMAKE_MT "@CMAKE_MT@")
diff --git a/Modules/CMakeCUDAInformation.cmake b/Modules/CMakeCUDAInformation.cmake
index 974f5fa..f9f7574 100644
--- a/Modules/CMakeCUDAInformation.cmake
+++ b/Modules/CMakeCUDAInformation.cmake
@@ -8,6 +8,19 @@
 endif()
 set(CMAKE_INCLUDE_FLAG_CUDA "-I")
 
+# Set implicit links early so compiler-specific modules can use them.
+set(__IMPLICT_LINKS )
+foreach(dir ${CMAKE_CUDA_HOST_IMPLICIT_LINK_DIRECTORIES})
+  string(APPEND __IMPLICT_LINKS " -L\"${dir}\"")
+endforeach()
+foreach(lib ${CMAKE_CUDA_HOST_IMPLICIT_LINK_LIBRARIES})
+  if(${lib} MATCHES "/")
+    string(APPEND __IMPLICT_LINKS " \"${lib}\"")
+  else()
+    string(APPEND __IMPLICT_LINKS " -l${lib}")
+  endif()
+endforeach()
+
 # Load compiler-specific information.
 if(CMAKE_CUDA_COMPILER_ID)
   include(Compiler/${CMAKE_CUDA_COMPILER_ID}-CUDA OPTIONAL)
@@ -97,22 +110,10 @@
 # CMAKE_CUDA_COMPILE_SEPARABLE_COMPILATION
 # CMAKE_CUDA_LINK_EXECUTABLE
 
-if(CMAKE_CUDA_HOST_COMPILER)
+if(CMAKE_CUDA_HOST_COMPILER AND CMAKE_CUDA_COMPILER_ID STREQUAL "NVIDIA")
   string(APPEND _CMAKE_CUDA_EXTRA_FLAGS " -ccbin=<CMAKE_CUDA_HOST_COMPILER>")
 endif()
 
-set(__IMPLICT_LINKS )
-foreach(dir ${CMAKE_CUDA_HOST_IMPLICIT_LINK_DIRECTORIES})
-  string(APPEND __IMPLICT_LINKS " -L\"${dir}\"")
-endforeach()
-foreach(lib ${CMAKE_CUDA_HOST_IMPLICIT_LINK_LIBRARIES})
-  if(${lib} MATCHES "/")
-    string(APPEND __IMPLICT_LINKS " \"${lib}\"")
-  else()
-    string(APPEND __IMPLICT_LINKS " -l${lib}")
-  endif()
-endforeach()
-
 # create a shared library
 if(NOT CMAKE_CUDA_CREATE_SHARED_LIBRARY)
   set(CMAKE_CUDA_CREATE_SHARED_LIBRARY
@@ -129,7 +130,7 @@
   set(CMAKE_CUDA_ARCHIVE_CREATE "<CMAKE_AR> qc <TARGET> <LINK_FLAGS> <OBJECTS>")
 endif()
 if(NOT DEFINED CMAKE_CUDA_ARCHIVE_APPEND)
-  set(CMAKE_CUDA_ARCHIVE_APPEND "<CMAKE_AR> q  <TARGET> <LINK_FLAGS> <OBJECTS>")
+  set(CMAKE_CUDA_ARCHIVE_APPEND "<CMAKE_AR> q <TARGET> <LINK_FLAGS> <OBJECTS>")
 endif()
 if(NOT DEFINED CMAKE_CUDA_ARCHIVE_FINISH)
   set(CMAKE_CUDA_ARCHIVE_FINISH "<CMAKE_RANLIB> <TARGET>")
@@ -138,24 +139,24 @@
 #Specify how to compile when ptx has been requested
 if(NOT CMAKE_CUDA_COMPILE_PTX_COMPILATION)
   set(CMAKE_CUDA_COMPILE_PTX_COMPILATION
-    "<CMAKE_CUDA_COMPILER> ${_CMAKE_CUDA_EXTRA_FLAGS} <DEFINES> <INCLUDES> <FLAGS> -x cu -ptx <SOURCE> -o <OBJECT>")
+    "<CMAKE_CUDA_COMPILER> ${_CMAKE_CUDA_EXTRA_FLAGS} <DEFINES> <INCLUDES> <FLAGS> ${_CMAKE_COMPILE_AS_CUDA_FLAG} ${_CMAKE_CUDA_PTX_FLAG} <SOURCE> -o <OBJECT>")
 endif()
 
 #Specify how to compile when separable compilation has been requested
 if(NOT CMAKE_CUDA_COMPILE_SEPARABLE_COMPILATION)
   set(CMAKE_CUDA_COMPILE_SEPARABLE_COMPILATION
-    "<CMAKE_CUDA_COMPILER> ${_CMAKE_CUDA_EXTRA_FLAGS} <DEFINES> <INCLUDES> <FLAGS> -x cu -dc <SOURCE> -o <OBJECT>")
+    "<CMAKE_CUDA_COMPILER> ${_CMAKE_CUDA_EXTRA_FLAGS} <DEFINES> <INCLUDES> <FLAGS> ${_CMAKE_COMPILE_AS_CUDA_FLAG} -dc <SOURCE> -o <OBJECT>")
 endif()
 
 #Specify how to compile when whole compilation has been requested
 if(NOT CMAKE_CUDA_COMPILE_WHOLE_COMPILATION)
   set(CMAKE_CUDA_COMPILE_WHOLE_COMPILATION
-    "<CMAKE_CUDA_COMPILER> ${_CMAKE_CUDA_EXTRA_FLAGS} <DEFINES> <INCLUDES> <FLAGS> -x cu -c <SOURCE> -o <OBJECT>")
+    "<CMAKE_CUDA_COMPILER> ${_CMAKE_CUDA_EXTRA_FLAGS} <DEFINES> <INCLUDES> <FLAGS> ${_CMAKE_COMPILE_AS_CUDA_FLAG} -c <SOURCE> -o <OBJECT>")
 endif()
 
-if(CMAKE_GENERATOR STREQUAL "Ninja" AND NOT CMAKE_DEPFILE_FLAGS_CUDA )
+if(CMAKE_GENERATOR STREQUAL "Ninja" AND NOT CMAKE_DEPFILE_FLAGS_CUDA)
   set(CMAKE_CUDA_COMPILE_DEPENDENCY_DETECTION
-    "<CMAKE_CUDA_COMPILER> ${_CMAKE_CUDA_EXTRA_FLAGS} <DEFINES> <INCLUDES> <FLAGS> -x cu -M <SOURCE> -MT <OBJECT> -o $DEP_FILE")
+    "<CMAKE_CUDA_COMPILER> ${_CMAKE_CUDA_EXTRA_FLAGS} <DEFINES> <INCLUDES> <FLAGS> ${_CMAKE_COMPILE_AS_CUDA_FLAG} -M <SOURCE> -MT <OBJECT> -o $DEP_FILE")
   #The Ninja generator uses the make file dependency files to determine what
   #files need to be recompiled. Unfortunately, nvcc < 10.2 doesn't support building
   #a source file and generating the dependencies of said file in a single
@@ -192,14 +193,13 @@
 #These are used when linking relocatable (dc) cuda code
 if(NOT CMAKE_CUDA_DEVICE_LINK_LIBRARY)
   set(CMAKE_CUDA_DEVICE_LINK_LIBRARY
-    "<CMAKE_CUDA_COMPILER> ${_CMAKE_CUDA_EXTRA_FLAGS} <LANGUAGE_COMPILE_FLAGS> ${CMAKE_CUDA_COMPILE_OPTIONS_PIC} ${_CMAKE_CUDA_EXTRA_DEVICE_LINK_FLAGS} -shared -dlink <OBJECTS> -o <TARGET> <LINK_LIBRARIES>${__IMPLICT_DLINK_FLAGS}")
+    "<CMAKE_CUDA_COMPILER> ${_CMAKE_CUDA_EXTRA_FLAGS} <LANGUAGE_COMPILE_FLAGS> <LINK_FLAGS> ${CMAKE_CUDA_COMPILE_OPTIONS_PIC} ${_CMAKE_CUDA_EXTRA_DEVICE_LINK_FLAGS} -shared -dlink <OBJECTS> -o <TARGET> <LINK_LIBRARIES>${__IMPLICT_DLINK_FLAGS}")
 endif()
 if(NOT CMAKE_CUDA_DEVICE_LINK_EXECUTABLE)
   set(CMAKE_CUDA_DEVICE_LINK_EXECUTABLE
-    "<CMAKE_CUDA_COMPILER> ${_CMAKE_CUDA_EXTRA_FLAGS} <FLAGS> ${CMAKE_CUDA_COMPILE_OPTIONS_PIC} ${_CMAKE_CUDA_EXTRA_DEVICE_LINK_FLAGS} -shared -dlink <OBJECTS> -o <TARGET> <LINK_LIBRARIES>${__IMPLICT_DLINK_FLAGS}")
+    "<CMAKE_CUDA_COMPILER> ${_CMAKE_CUDA_EXTRA_FLAGS} <LANGUAGE_COMPILE_FLAGS> <LINK_FLAGS> ${CMAKE_CUDA_COMPILE_OPTIONS_PIC} ${_CMAKE_CUDA_EXTRA_DEVICE_LINK_FLAGS} -shared -dlink <OBJECTS> -o <TARGET> <LINK_LIBRARIES>${__IMPLICT_DLINK_FLAGS}")
 endif()
 
-unset(_CMAKE_CUDA_EXTRA_DEVICE_LINK_FLAGS)
 unset(__IMPLICT_DLINK_FLAGS)
 
 set(CMAKE_CUDA_INFORMATION_LOADED 1)
diff --git a/Modules/CMakeCXXCompiler.cmake.in b/Modules/CMakeCXXCompiler.cmake.in
index efb8abf..09bdc23 100644
--- a/Modules/CMakeCXXCompiler.cmake.in
+++ b/Modules/CMakeCXXCompiler.cmake.in
@@ -17,6 +17,7 @@
 set(CMAKE_CXX_COMPILER_FRONTEND_VARIANT "@CMAKE_CXX_COMPILER_FRONTEND_VARIANT@")
 set(CMAKE_CXX_SIMULATE_VERSION "@CMAKE_CXX_SIMULATE_VERSION@")
 @_SET_CMAKE_CXX_COMPILER_ARCHITECTURE_ID@
+@_SET_CMAKE_CXX_COMPILER_SYSROOT@
 @SET_MSVC_CXX_ARCHITECTURE_ID@
 @SET_CMAKE_XCODE_ARCHS@
 set(CMAKE_AR "@CMAKE_AR@")
diff --git a/Modules/CMakeCXXInformation.cmake b/Modules/CMakeCXXInformation.cmake
index da7440a..dbb4366 100644
--- a/Modules/CMakeCXXInformation.cmake
+++ b/Modules/CMakeCXXInformation.cmake
@@ -258,7 +258,7 @@
   set(CMAKE_CXX_ARCHIVE_CREATE "<CMAKE_AR> qc <TARGET> <LINK_FLAGS> <OBJECTS>")
 endif()
 if(NOT DEFINED CMAKE_CXX_ARCHIVE_APPEND)
-  set(CMAKE_CXX_ARCHIVE_APPEND "<CMAKE_AR> q  <TARGET> <LINK_FLAGS> <OBJECTS>")
+  set(CMAKE_CXX_ARCHIVE_APPEND "<CMAKE_AR> q <TARGET> <LINK_FLAGS> <OBJECTS>")
 endif()
 if(NOT DEFINED CMAKE_CXX_ARCHIVE_FINISH)
   set(CMAKE_CXX_ARCHIVE_FINISH "<CMAKE_RANLIB> <TARGET>")
@@ -267,12 +267,12 @@
 # compile a C++ file into an object file
 if(NOT CMAKE_CXX_COMPILE_OBJECT)
   set(CMAKE_CXX_COMPILE_OBJECT
-    "<CMAKE_CXX_COMPILER>  <DEFINES> <INCLUDES> <FLAGS> -o <OBJECT> -c <SOURCE>")
+    "<CMAKE_CXX_COMPILER> <DEFINES> <INCLUDES> <FLAGS> -o <OBJECT> -c <SOURCE>")
 endif()
 
 if(NOT CMAKE_CXX_LINK_EXECUTABLE)
   set(CMAKE_CXX_LINK_EXECUTABLE
-    "<CMAKE_CXX_COMPILER>  <FLAGS> <CMAKE_CXX_LINK_FLAGS> <LINK_FLAGS> <OBJECTS>  -o <TARGET> <LINK_LIBRARIES>")
+    "<CMAKE_CXX_COMPILER> <FLAGS> <CMAKE_CXX_LINK_FLAGS> <LINK_FLAGS> <OBJECTS> -o <TARGET> <LINK_LIBRARIES>")
 endif()
 
 mark_as_advanced(
diff --git a/Modules/CMakeCompilerIdDetection.cmake b/Modules/CMakeCompilerIdDetection.cmake
index bb573b7..acd15df 100644
--- a/Modules/CMakeCompilerIdDetection.cmake
+++ b/Modules/CMakeCompilerIdDetection.cmake
@@ -89,9 +89,8 @@
       )
     endif()
 
-    #Currently the only CUDA compilers are NVIDIA
     if(lang STREQUAL CUDA)
-      set(ordered_compilers NVIDIA)
+      set(ordered_compilers NVIDIA Clang)
     endif()
 
     if(CID_ID_DEFINE)
diff --git a/Modules/CMakeDetermineASMCompiler.cmake b/Modules/CMakeDetermineASMCompiler.cmake
index e47f3a4..a3e5a12 100644
--- a/Modules/CMakeDetermineASMCompiler.cmake
+++ b/Modules/CMakeDetermineASMCompiler.cmake
@@ -11,7 +11,7 @@
   if(NOT $ENV{ASM${ASM_DIALECT}} STREQUAL "")
     get_filename_component(CMAKE_ASM${ASM_DIALECT}_COMPILER_INIT $ENV{ASM${ASM_DIALECT}} PROGRAM PROGRAM_ARGS CMAKE_ASM${ASM_DIALECT}_FLAGS_ENV_INIT)
     if(CMAKE_ASM${ASM_DIALECT}_FLAGS_ENV_INIT)
-      set(CMAKE_ASM${ASM_DIALECT}_COMPILER_ARG1 "${CMAKE_ASM${ASM_DIALECT}_FLAGS_ENV_INIT}" CACHE STRING "First argument to ASM${ASM_DIALECT} compiler")
+      set(CMAKE_ASM${ASM_DIALECT}_COMPILER_ARG1 "${CMAKE_ASM${ASM_DIALECT}_FLAGS_ENV_INIT}" CACHE STRING "Arguments to ASM${ASM_DIALECT} compiler")
     endif()
     if(NOT EXISTS ${CMAKE_ASM${ASM_DIALECT}_COMPILER_INIT})
       message(FATAL_ERROR "Could not find compiler set in environment variable ASM${ASM_DIALECT}:\n$ENV{ASM${ASM_DIALECT}}.")
@@ -134,6 +134,9 @@
       list(GET _all_compileid_matches "-1" CMAKE_ASM${ASM_DIALECT}_COMPILER_ARCHITECTURE_ID)
     endif()
   endif()
+
+  _cmake_find_compiler_sysroot(ASM${ASM_DIALECT})
+
   unset(CMAKE_ASM${ASM_DIALECT}_COMPILER_ID_OUTPUT)
   unset(_all_compileid_matches)
   unset(_compileid)
@@ -211,6 +214,21 @@
   set(_CMAKE_ASM_${_var} "${CMAKE_ASM${ASM_DIALECT}_${_var}}")
 endforeach()
 
+if(CMAKE_ASM${ASM_DIALECT}_COMPILER_SYSROOT)
+  string(CONCAT _SET_CMAKE_ASM_COMPILER_SYSROOT
+    "set(CMAKE_ASM${ASM_DIALECT}_COMPILER_SYSROOT \"${CMAKE_ASM${ASM_DIALECT}_COMPILER_SYSROOT}\")\n"
+    "set(CMAKE_COMPILER_SYSROOT \"${CMAKE_ASM${ASM_DIALECT}_COMPILER_SYSROOT}\")")
+else()
+  set(_SET_CMAKE_ASM_COMPILER_SYSROOT "")
+endif()
+
+if(CMAKE_ASM${ASM_DIALECT}_COMPILER_ID_VENDOR_MATCH)
+  set(_SET_CMAKE_ASM_COMPILER_ID_VENDOR_MATCH
+    "set(CMAKE_ASM${ASM_DIALECT}_COMPILER_ID_VENDOR_MATCH [==[${CMAKE_ASM${ASM_DIALECT}_COMPILER_ID_VENDOR_MATCH}]==])")
+else()
+  set(_SET_CMAKE_ASM_COMPILER_ID_VENDOR_MATCH "")
+endif()
+
 if(CMAKE_ASM${ASM_DIALECT}_COMPILER_ARCHITECTURE_ID)
   set(_SET_CMAKE_ASM_COMPILER_ARCHITECTURE_ID
     "set(CMAKE_ASM${ASM_DIALECT}_COMPILER_ARCHITECTURE_ID ${CMAKE_ASM${ASM_DIALECT}_COMPILER_ARCHITECTURE_ID})")
diff --git a/Modules/CMakeDetermineCCompiler.cmake b/Modules/CMakeDetermineCCompiler.cmake
index 037c33b..96f32e5 100644
--- a/Modules/CMakeDetermineCCompiler.cmake
+++ b/Modules/CMakeDetermineCCompiler.cmake
@@ -43,7 +43,7 @@
     if(NOT $ENV{CC} STREQUAL "")
       get_filename_component(CMAKE_C_COMPILER_INIT $ENV{CC} PROGRAM PROGRAM_ARGS CMAKE_C_FLAGS_ENV_INIT)
       if(CMAKE_C_FLAGS_ENV_INIT)
-        set(CMAKE_C_COMPILER_ARG1 "${CMAKE_C_FLAGS_ENV_INIT}" CACHE STRING "First argument to C compiler")
+        set(CMAKE_C_COMPILER_ARG1 "${CMAKE_C_FLAGS_ENV_INIT}" CACHE STRING "Arguments to C compiler")
       endif()
       if(NOT EXISTS ${CMAKE_C_COMPILER_INIT})
         message(FATAL_ERROR "Could not find compiler set in environment variable CC:\n$ENV{CC}.")
@@ -87,7 +87,9 @@
     "--target=arm-arm-none-eabi -mcpu=cortex-m3"
     )
 endif()
-
+if(CMAKE_C_COMPILER_TARGET)
+  list(PREPEND CMAKE_C_COMPILER_ID_TEST_FLAGS "-c --target=${CMAKE_C_COMPILER_TARGET}")
+endif()
 # Build a small source file to identify the compiler.
 if(NOT CMAKE_C_COMPILER_ID_RUN)
   set(CMAKE_C_COMPILER_ID_RUN 1)
@@ -99,7 +101,7 @@
     CMAKE_C_COMPILER_ID_PLATFORM_CONTENT)
 
   # The IAR compiler produces weird output.
-  # See https://gitlab.kitware.com/cmake/cmake/issues/10176#note_153591
+  # See https://gitlab.kitware.com/cmake/cmake/-/issues/10176#note_153591
   list(APPEND CMAKE_C_COMPILER_ID_VENDORS IAR)
   set(CMAKE_C_COMPILER_ID_VENDOR_FLAGS_IAR )
   set(CMAKE_C_COMPILER_ID_VENDOR_REGEX_IAR "IAR .+ Compiler")
@@ -115,6 +117,8 @@
   include(${CMAKE_ROOT}/Modules/CMakeDetermineCompilerId.cmake)
   CMAKE_DETERMINE_COMPILER_ID(C CFLAGS CMakeCCompilerId.c)
 
+  _cmake_find_compiler_sysroot(C)
+
   # Set old compiler and platform id variables.
   if(CMAKE_C_COMPILER_ID STREQUAL "GNU")
     set(CMAKE_COMPILER_IS_GNUCC 1)
@@ -153,7 +157,7 @@
 # NAME_WE cannot be used since then this test will fail for names like
 # "arm-unknown-nto-qnx6.3.0-gcc.exe", where BASENAME would be
 # "arm-unknown-nto-qnx6" instead of the correct "arm-unknown-nto-qnx6.3.0-"
-if (CMAKE_CROSSCOMPILING  AND NOT _CMAKE_TOOLCHAIN_PREFIX)
+if (NOT _CMAKE_TOOLCHAIN_PREFIX)
 
   if(CMAKE_C_COMPILER_ID MATCHES "GNU|Clang|QCC")
     get_filename_component(COMPILER_BASENAME "${CMAKE_C_COMPILER}" NAME)
@@ -191,6 +195,14 @@
 include(Compiler/${CMAKE_C_COMPILER_ID}-FindBinUtils OPTIONAL)
 unset(_CMAKE_PROCESSING_LANGUAGE)
 
+if(CMAKE_C_COMPILER_SYSROOT)
+  string(CONCAT _SET_CMAKE_C_COMPILER_SYSROOT
+    "set(CMAKE_C_COMPILER_SYSROOT \"${CMAKE_C_COMPILER_SYSROOT}\")\n"
+    "set(CMAKE_COMPILER_SYSROOT \"${CMAKE_C_COMPILER_SYSROOT}\")")
+else()
+  set(_SET_CMAKE_C_COMPILER_SYSROOT "")
+endif()
+
 if(CMAKE_C_COMPILER_ARCHITECTURE_ID)
   set(_SET_CMAKE_C_COMPILER_ARCHITECTURE_ID
     "set(CMAKE_C_COMPILER_ARCHITECTURE_ID ${CMAKE_C_COMPILER_ARCHITECTURE_ID})")
diff --git a/Modules/CMakeDetermineCUDACompiler.cmake b/Modules/CMakeDetermineCUDACompiler.cmake
index baf1501..daca382 100644
--- a/Modules/CMakeDetermineCUDACompiler.cmake
+++ b/Modules/CMakeDetermineCUDACompiler.cmake
@@ -2,7 +2,7 @@
 # file Copyright.txt or https://cmake.org/licensing for details.
 
 include(${CMAKE_ROOT}/Modules/CMakeDetermineCompiler.cmake)
-include(${CMAKE_ROOT}/Modules//CMakeParseImplicitLinkInfo.cmake)
+include(${CMAKE_ROOT}/Modules/CMakeParseImplicitLinkInfo.cmake)
 
 if( NOT ( ("${CMAKE_GENERATOR}" MATCHES "Make") OR
           ("${CMAKE_GENERATOR}" MATCHES "Ninja") OR
@@ -19,7 +19,7 @@
       if(NOT $ENV{CUDACXX} STREQUAL "")
         get_filename_component(CMAKE_CUDA_COMPILER_INIT $ENV{CUDACXX} PROGRAM PROGRAM_ARGS CMAKE_CUDA_FLAGS_ENV_INIT)
         if(CMAKE_CUDA_FLAGS_ENV_INIT)
-          set(CMAKE_CUDA_COMPILER_ARG1 "${CMAKE_CUDA_FLAGS_ENV_INIT}" CACHE STRING "First argument to CXX compiler")
+          set(CMAKE_CUDA_COMPILER_ARG1 "${CMAKE_CUDA_FLAGS_ENV_INIT}" CACHE STRING "Arguments to CXX compiler")
         endif()
         if(NOT EXISTS ${CMAKE_CUDA_COMPILER_INIT})
           message(FATAL_ERROR "Could not find compiler set in environment variable CUDACXX:\n$ENV{CUDACXX}.\n${CMAKE_CUDA_COMPILER_INIT}")
@@ -51,29 +51,210 @@
 if(NOT CMAKE_CUDA_COMPILER_ID_RUN)
   set(CMAKE_CUDA_COMPILER_ID_RUN 1)
 
-  # Try to identify the compiler.
+  include(${CMAKE_ROOT}/Modules/CMakeDetermineCompilerId.cmake)
+
+  if(${CMAKE_GENERATOR} MATCHES "Visual Studio")
+    # We will not know CMAKE_CUDA_COMPILER until the main compiler id step
+    # below extracts it, but we do know that the compiler id will be NVIDIA.
+    set(CMAKE_CUDA_COMPILER_ID "NVIDIA")
+  else()
+    # We determine the vendor to help with find the toolkit and use the right flags for detection right away.
+    # The main compiler identification is still needed below to extract other information.
+    list(APPEND CMAKE_CUDA_COMPILER_ID_VENDORS NVIDIA Clang)
+    set(CMAKE_CUDA_COMPILER_ID_VENDOR_REGEX_NVIDIA "nvcc: NVIDIA \\(R\\) Cuda compiler driver")
+    set(CMAKE_CUDA_COMPILER_ID_VENDOR_REGEX_Clang "(clang version)")
+    CMAKE_DETERMINE_COMPILER_ID_VENDOR(CUDA "--version")
+
+    # Find the CUDA toolkit. We store the CMAKE_CUDA_COMPILER_TOOLKIT_ROOT and CMAKE_CUDA_COMPILER_LIBRARY_ROOT
+    # in CMakeCUDACompiler.cmake, so FindCUDAToolkit can avoid searching on future runs and the toolkit stays the same.
+    # This is very similar to FindCUDAToolkit, but somewhat simplified since we can issue fatal errors
+    # if we fail to find things we need and we don't need to account for searching the libraries.
+
+    # For NVCC we can easily deduce the SDK binary directory from the compiler path.
+    if(CMAKE_CUDA_COMPILER_ID STREQUAL "NVIDIA")
+      set(_CUDA_NVCC_EXECUTABLE "${CMAKE_CUDA_COMPILER}")
+    else()
+      # Search using CUDAToolkit_ROOT and then CUDA_PATH for equivalence with FindCUDAToolkit.
+      # In FindCUDAToolkit CUDAToolkit_ROOT is searched automatically due to being in a find_package().
+      # First we search candidate non-default paths to give them priority.
+      find_program(_CUDA_NVCC_EXECUTABLE
+        NAMES nvcc nvcc.exe
+        PATHS ${CUDAToolkit_ROOT}
+        ENV CUDAToolkit_ROOT
+        ENV CUDA_PATH
+        PATH_SUFFIXES bin
+        NO_DEFAULT_PATH
+      )
+
+      # If we didn't find NVCC, then try the default paths.
+      find_program(_CUDA_NVCC_EXECUTABLE
+        NAMES nvcc nvcc.exe
+        PATH_SUFFIXES bin
+      )
+
+      # If the user specified CUDAToolkit_ROOT but nvcc could not be found, this is an error.
+      if(NOT _CUDA_NVCC_EXECUTABLE AND (DEFINED CUDAToolkit_ROOT OR DEFINED ENV{CUDAToolkit_ROOT}))
+        set(fail_base "Could not find nvcc executable in path specified by")
+
+        if(DEFINED CUDAToolkit_ROOT)
+          message(FATAL_ERROR "${fail_base} CUDAToolkit_ROOT=${CUDAToolkit_ROOT}")
+        elseif(DEFINED ENV{CUDAToolkit_ROOT})
+          message(FATAL_ERROR "${fail_base} environment variable CUDAToolkit_ROOT=$ENV{CUDAToolkit_ROOT}")
+        endif()
+      endif()
+
+      # CUDAToolkit_ROOT cmake/env variable not specified, try platform defaults.
+      #
+      # - Linux: /usr/local/cuda-X.Y
+      # - macOS: /Developer/NVIDIA/CUDA-X.Y
+      # - Windows: C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\vX.Y
+      #
+      # We will also search the default symlink location /usr/local/cuda first since
+      # if CUDAToolkit_ROOT is not specified, it is assumed that the symlinked
+      # directory is the desired location.
+      if(NOT _CUDA_NVCC_EXECUTABLE)
+        if(UNIX)
+          if(NOT APPLE)
+            set(platform_base "/usr/local/cuda-")
+          else()
+            set(platform_base "/Developer/NVIDIA/CUDA-")
+          endif()
+        else()
+          set(platform_base "C:\\Program Files\\NVIDIA GPU Computing Toolkit\\CUDA\\v")
+        endif()
+
+        # Build out a descending list of possible cuda installations, e.g.
+        file(GLOB possible_paths "${platform_base}*")
+        # Iterate the glob results and create a descending list.
+        set(versions)
+        foreach(p ${possible_paths})
+          # Extract version number from end of string
+          string(REGEX MATCH "[0-9][0-9]?\\.[0-9]$" p_version ${p})
+          if(IS_DIRECTORY ${p} AND p_version)
+            list(APPEND versions ${p_version})
+          endif()
+        endforeach()
+
+        # Sort numerically in descending order, so we try the newest versions first.
+        list(SORT versions COMPARE NATURAL ORDER DESCENDING)
+
+        # With a descending list of versions, populate possible paths to search.
+        set(search_paths)
+        foreach(v ${versions})
+          list(APPEND search_paths "${platform_base}${v}")
+        endforeach()
+
+        # Force the global default /usr/local/cuda to the front on Unix.
+        if(UNIX)
+          list(INSERT search_paths 0 "/usr/local/cuda")
+        endif()
+
+        # Now search for nvcc again using the platform default search paths.
+        find_program(_CUDA_NVCC_EXECUTABLE
+          NAMES nvcc nvcc.exe
+          PATHS ${search_paths}
+          PATH_SUFFIXES bin
+        )
+
+        # We are done with these variables now, cleanup.
+        unset(platform_base)
+        unset(possible_paths)
+        unset(versions)
+        unset(search_paths)
+
+        if(NOT _CUDA_NVCC_EXECUTABLE)
+          message(FATAL_ERROR "Could not find nvcc, please set CUDAToolkit_ROOT.")
+        endif()
+      endif()
+    endif()
+
+    get_filename_component(CMAKE_CUDA_COMPILER_TOOLKIT_ROOT "${_CUDA_NVCC_EXECUTABLE}" DIRECTORY)
+    get_filename_component(CMAKE_CUDA_COMPILER_TOOLKIT_ROOT "${CMAKE_CUDA_COMPILER_TOOLKIT_ROOT}" DIRECTORY)
+
+    # CMAKE_CUDA_COMPILER_LIBRARY_ROOT contains the device library and version file.
+    # In a non-scattered installation this is equivalent to CMAKE_CUDA_COMPILER_TOOLKIT_ROOT.
+    # We first check for a non-scattered installation to prefer it over a scattered installation.
+    if(EXISTS "${CMAKE_CUDA_COMPILER_TOOLKIT_ROOT}/version.txt")
+      set(CMAKE_CUDA_COMPILER_LIBRARY_ROOT "${CMAKE_CUDA_COMPILER_TOOLKIT_ROOT}")
+    elseif(CMAKE_SYSROOT_LINK AND EXISTS "${CMAKE_SYSROOT_LINK}/usr/lib/cuda/version.txt")
+      set(CMAKE_CUDA_COMPILER_LIBRARY_ROOT "${CMAKE_SYSROOT_LINK}/usr/lib/cuda")
+    elseif(EXISTS "${CMAKE_SYSROOT}/usr/lib/cuda/version.txt")
+      set(CMAKE_CUDA_COMPILER_LIBRARY_ROOT "${CMAKE_SYSROOT}/usr/lib/cuda")
+    endif()
+  endif()
+
+  set(CMAKE_CUDA_COMPILER_ID_FLAGS_ALWAYS "-v")
+
+  if(CMAKE_CUDA_COMPILER_ID STREQUAL "NVIDIA")
+    set(nvcc_test_flags "--keep --keep-dir tmp")
+    if(CMAKE_CUDA_HOST_COMPILER)
+      string(APPEND nvcc_test_flags " -ccbin=\"${CMAKE_CUDA_HOST_COMPILER}\"")
+    endif()
+  elseif(CMAKE_CUDA_COMPILER_ID STREQUAL "Clang")
+    if(WIN32)
+      message(FATAL_ERROR "Clang with CUDA is not yet supported on Windows. See CMake issue #20776.")
+    endif()
+
+    set(clang_test_flags "--cuda-path=\"${CMAKE_CUDA_COMPILER_LIBRARY_ROOT}\"")
+    if(CMAKE_CROSSCOMPILING)
+      # Need to pass the host target and include directories if we're crosscompiling.
+      string(APPEND clang_test_flags " --sysroot=\"${CMAKE_SYSROOT}\" --target=${CMAKE_CUDA_COMPILER_TARGET}")
+    endif()
+  endif()
+
+  # First try with the user-specified architectures.
+  if(CMAKE_CUDA_ARCHITECTURES)
+    set(clang_archs "${clang_test_flags}")
+    set(nvcc_archs "${nvcc_test_flags}")
+
+    foreach(arch ${CMAKE_CUDA_ARCHITECTURES})
+      # Strip specifiers as PTX vs binary doesn't matter.
+      string(REGEX MATCH "[0-9]+" arch_name "${arch}")
+      string(APPEND clang_archs " --cuda-gpu-arch=sm_${arch_name}")
+      string(APPEND nvcc_archs " -gencode=arch=compute_${arch_name},code=sm_${arch_name}")
+      list(APPEND tested_architectures "${arch_name}")
+    endforeach()
+
+    list(APPEND CMAKE_CUDA_COMPILER_ID_TEST_FLAGS_FIRST "${clang_archs}")
+    list(APPEND CMAKE_CUDA_COMPILER_ID_TEST_FLAGS_FIRST "${nvcc_archs}")
+  endif()
+
+  # Fallback default NVCC flags.
+  list(APPEND CMAKE_CUDA_COMPILER_ID_TEST_FLAGS_FIRST ${nvcc_test_flags})
+
+  # Clang doesn't automatically select an architecture supported by the SDK.
+  # Try in reverse order of deprecation with the most recent at front (i.e. the most likely to work for new setups).
+  foreach(arch "20" "30" "52")
+    list(APPEND CMAKE_CUDA_COMPILER_ID_TEST_FLAGS_FIRST "${clang_test_flags} --cuda-gpu-arch=sm_${arch}")
+  endforeach()
+
+  # Finally also try the default.
+  list(APPEND CMAKE_CUDA_COMPILER_ID_TEST_FLAGS_FIRST "${clang_test_flags}")
+
+  # We perform compiler identification for a second time to extract implicit linking info and host compiler for NVCC.
+  # We also use it to verify that CMAKE_CUDA_ARCHITECTURES and additionally on Clang that CUDA toolkit path works.
+  # The latter could be done during compiler testing in the future to avoid doing this for Clang.
+  # We need to unset the compiler ID otherwise CMAKE_DETERMINE_COMPILER_ID() doesn't work.
   set(CMAKE_CUDA_COMPILER_ID)
   set(CMAKE_CUDA_PLATFORM_ID)
   file(READ ${CMAKE_ROOT}/Modules/CMakePlatformId.h.in
     CMAKE_CUDA_COMPILER_ID_PLATFORM_CONTENT)
 
-  list(APPEND CMAKE_CUDA_COMPILER_ID_MATCH_VENDORS NVIDIA)
-  set(CMAKE_CUDA_COMPILER_ID_MATCH_VENDOR_REGEX_NVIDIA "nvcc: NVIDIA \(R\) Cuda compiler driver")
+  CMAKE_DETERMINE_COMPILER_ID(CUDA CUDAFLAGS CMakeCUDACompilerId.cu)
 
-  set(CMAKE_CXX_COMPILER_ID_TOOL_MATCH_REGEX "\nLd[^\n]*(\n[ \t]+[^\n]*)*\n[ \t]+([^ \t\r\n]+)[^\r\n]*-o[^\r\n]*CompilerIdCUDA/(\\./)?(CompilerIdCUDA.xctest/)?CompilerIdCUDA[ \t\n\\\"]")
-  set(CMAKE_CXX_COMPILER_ID_TOOL_MATCH_INDEX 2)
-
-  set(CMAKE_CUDA_COMPILER_ID_FLAGS_ALWAYS -v --keep --keep-dir tmp)
-  if(CMAKE_CUDA_HOST_COMPILER)
-      list(APPEND CMAKE_CUDA_COMPILER_ID_FLAGS_ALWAYS "-ccbin=${CMAKE_CUDA_HOST_COMPILER}")
+  if(${CMAKE_GENERATOR} MATCHES "Visual Studio")
+    # Now that we have the path to nvcc, we can compute the toolkit root.
+    get_filename_component(CMAKE_CUDA_COMPILER_TOOLKIT_ROOT "${CMAKE_CUDA_COMPILER}" DIRECTORY)
+    get_filename_component(CMAKE_CUDA_COMPILER_TOOLKIT_ROOT "${CMAKE_CUDA_COMPILER_TOOLKIT_ROOT}" DIRECTORY)
+    set(CMAKE_CUDA_COMPILER_LIBRARY_ROOT "${CMAKE_CUDA_COMPILER_TOOLKIT_ROOT}")
   endif()
 
-  include(${CMAKE_ROOT}/Modules/CMakeDetermineCompilerId.cmake)
-  CMAKE_DETERMINE_COMPILER_ID(CUDA CUDAFLAGS CMakeCUDACompilerId.cu)
+  _cmake_find_compiler_sysroot(CUDA)
 endif()
 
 set(_CMAKE_PROCESSING_LANGUAGE "CUDA")
 include(CMakeFindBinUtils)
+include(Compiler/${CMAKE_CUDA_COMPILER_ID}-FindBinUtils OPTIONAL)
 unset(_CMAKE_PROCESSING_LANGUAGE)
 
 if(MSVC_CUDA_ARCHITECTURE_ID)
@@ -100,7 +281,71 @@
   endif()
   set(_SET_CMAKE_CUDA_RUNTIME_LIBRARY_DEFAULT
     "set(CMAKE_CUDA_RUNTIME_LIBRARY_DEFAULT \"${CMAKE_CUDA_RUNTIME_LIBRARY_DEFAULT}\")")
-elseif(CMAKE_CUDA_COMPILER_ID STREQUAL NVIDIA)
+elseif(CMAKE_CUDA_COMPILER_ID STREQUAL "Clang")
+  if(NOT CMAKE_CUDA_ARCHITECTURES)
+    # Find the architecture that we successfully compiled using and set it as the default.
+    string(REGEX MATCH "-target-cpu sm_([0-9]+)" dont_care "${CMAKE_CUDA_COMPILER_PRODUCED_OUTPUT}")
+    set(detected_architecture "${CMAKE_MATCH_1}")
+  else()
+    string(REGEX MATCHALL "-target-cpu sm_([0-9]+)" target_cpus "${CMAKE_CUDA_COMPILER_PRODUCED_OUTPUT}")
+
+    foreach(cpu ${target_cpus})
+      string(REGEX MATCH "-target-cpu sm_([0-9]+)" dont_care "${cpu}")
+      list(APPEND architectures "${CMAKE_MATCH_1}")
+    endforeach()
+  endif()
+
+  # Find target directory. Account for crosscompiling.
+  if(CMAKE_CROSSCOMPILING)
+    if(CMAKE_SYSTEM_PROCESSOR STREQUAL "armv7-a")
+      # Support for NVPACK
+      set(_CUDA_TARGET_NAME "armv7-linux-androideabi")
+    elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "arm")
+      set(_CUDA_TARGET_NAME "armv7-linux-gnueabihf")
+    elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "aarch64")
+      if(ANDROID_ARCH_NAME STREQUAL "arm64")
+        set(_CUDA_TARGET_NAME "aarch64-linux-androideabi")
+      else()
+        set(_CUDA_TARGET_NAME "aarch64-linux")
+      endif()
+    elseif(CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64")
+      set(_CUDA_TARGET_NAME "x86_64-linux")
+    endif()
+
+    if(EXISTS "${CMAKE_CUDA_COMPILER_TOOLKIT_ROOT}/targets/${_CUDA_TARGET_NAME}")
+      set(_CUDA_TARGET_DIR "${CMAKE_CUDA_COMPILER_TOOLKIT_ROOT}/targets/${_CUDA_TARGET_NAME}")
+    endif()
+  else()
+    set(_CUDA_TARGET_DIR "${CMAKE_CUDA_COMPILER_TOOLKIT_ROOT}")
+  endif()
+
+  # We can't use find_library() yet at this point, so try a few guesses.
+  if(EXISTS "${_CUDA_TARGET_DIR}/lib64")
+    set(_CUDA_LIBRARY_DIR "${_CUDA_TARGET_DIR}/lib64")
+  elseif(EXISTS "${_CUDA_TARGET_DIR}/lib/x64")
+    set(_CUDA_LIBRARY_DIR "${_CUDA_TARGET_DIR}/lib/x64")
+  elseif(EXISTS "${_CUDA_TARGET_DIR}/lib")
+    set(_CUDA_LIBRARY_DIR "${_CUDA_TARGET_DIR}/lib")
+  else()
+    message(FATAL_ERROR "Unable to find _CUDA_LIBRARY_DIR based on _CUDA_TARGET_DIR=${_CUDA_TARGET_DIR}")
+  endif()
+
+  # _CUDA_TARGET_DIR always points to the directory containing the include directory.
+  # On a scattered installation /usr, on a non-scattered something like /usr/local/cuda or /usr/local/cuda-10.2/targets/aarch64-linux.
+  if(EXISTS "${_CUDA_TARGET_DIR}/include/cuda_runtime.h")
+    set(_CUDA_INCLUDE_DIR "${_CUDA_TARGET_DIR}/include")
+  else()
+    message(FATAL_ERROR "Unable to find cuda_runtime.h in \"${_CUDA_TARGET_DIR}/include\" for _CUDA_INCLUDE_DIR.")
+  endif()
+
+  # Clang does not add any CUDA SDK libraries or directories when invoking the host linker.
+  # Add the CUDA toolkit library directory ourselves so that linking works.
+  # The CUDA runtime libraries are handled elsewhere by CMAKE_CUDA_RUNTIME_LIBRARY.
+  set(CMAKE_CUDA_TOOLKIT_INCLUDE_DIRECTORIES "${_CUDA_INCLUDE_DIR}")
+  set(CMAKE_CUDA_HOST_IMPLICIT_LINK_DIRECTORIES "${_CUDA_LIBRARY_DIR}")
+  set(CMAKE_CUDA_HOST_IMPLICIT_LINK_LIBRARIES "")
+  set(CMAKE_CUDA_HOST_IMPLICIT_LINK_FRAMEWORK_DIRECTORIES "")
+elseif(CMAKE_CUDA_COMPILER_ID STREQUAL "NVIDIA")
   set(_nvcc_log "")
   string(REPLACE "\r" "" _nvcc_output_orig "${CMAKE_CUDA_COMPILER_PRODUCED_OUTPUT}")
   if(_nvcc_output_orig MATCHES "#\\\$ +PATH= *([^\n]*)\n")
@@ -211,42 +456,120 @@
       "Parsed CUDA nvcc implicit link information from above output:\n${_nvcc_log}\n${log}\n\n")
   else()
     file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
-      "Failed to parsed CUDA nvcc implicit link information:\n${_nvcc_log}\n\n")
+      "Failed to parse CUDA nvcc implicit link information:\n${_nvcc_log}\n\n")
     message(FATAL_ERROR "Failed to extract nvcc implicit link line.")
   endif()
 endif()
 
-set(CMAKE_CUDA_TOOLKIT_INCLUDE_DIRECTORIES )
-string(REPLACE "\r" "" _nvcc_output_orig "${CMAKE_CUDA_COMPILER_PRODUCED_OUTPUT}")
-if(_nvcc_output_orig MATCHES "#\\\$ +INCLUDES= *([^\n]*)\n")
-  set(_nvcc_includes "${CMAKE_MATCH_1}")
-  string(APPEND _nvcc_log "  found 'INCLUDES=' string: [${_nvcc_includes}]\n")
-else()
-  set(_nvcc_includes "")
-  string(REPLACE "\n" "\n    " _nvcc_output_log "\n${_nvcc_output_orig}")
-  string(APPEND _nvcc_log "  no 'INCLUDES=' string found in nvcc output:${_nvcc_output_log}\n")
-endif()
-if(_nvcc_includes)
-  # across all operating system each include directory is prefixed with -I
-  separate_arguments(_nvcc_output NATIVE_COMMAND "${_nvcc_includes}")
-  foreach(line IN LISTS _nvcc_output)
-    string(REGEX REPLACE "^-I" "" line "${line}")
-    get_filename_component(line "${line}" ABSOLUTE)
-    list(APPEND CMAKE_CUDA_TOOLKIT_INCLUDE_DIRECTORIES "${line}")
-  endforeach()
+# CMAKE_CUDA_HOST_IMPLICIT_LINK_LIBRARIES is detected above as the list of
+# libraries that the CUDA compiler implicitly passes to the host linker.
+# CMake invokes the host linker directly and so needs to pass these libraries.
+# We filter out those that should not be passed unconditionally both here
+# and from CMAKE_CUDA_IMPLICIT_LINK_LIBRARIES in CMakeTestCUDACompiler.
+set(CMAKE_CUDA_IMPLICIT_LINK_LIBRARIES_EXCLUDE
+  # The CUDA runtime libraries are controlled by CMAKE_CUDA_RUNTIME_LIBRARY.
+  cudart        cudart.lib
+  cudart_static cudart_static.lib
+  cudadevrt     cudadevrt.lib
 
-  file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
-    "Parsed CUDA nvcc include information from above output:\n${_nvcc_log}\n${log}\n\n")
+  # Dependencies of the CUDA static runtime library on Linux hosts.
+  rt
+  pthread
+  dl
+  )
+list(REMOVE_ITEM CMAKE_CUDA_HOST_IMPLICIT_LINK_LIBRARIES ${CMAKE_CUDA_IMPLICIT_LINK_LIBRARIES_EXCLUDE})
+
+if(CMAKE_CUDA_COMPILER_SYSROOT)
+  string(CONCAT _SET_CMAKE_CUDA_COMPILER_SYSROOT
+    "set(CMAKE_CUDA_COMPILER_SYSROOT \"${CMAKE_CUDA_COMPILER_SYSROOT}\")\n"
+    "set(CMAKE_COMPILER_SYSROOT \"${CMAKE_CUDA_COMPILER_SYSROOT}\")")
 else()
-  file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
-    "Failed to detect CUDA nvcc include information:\n${_nvcc_log}\n\n")
+  set(_SET_CMAKE_CUDA_COMPILER_SYSROOT "")
+endif()
+
+# Determine CMAKE_CUDA_TOOLKIT_INCLUDE_DIRECTORIES
+if(CMAKE_CUDA_COMPILER_ID STREQUAL "NVIDIA")
+  set(CMAKE_CUDA_TOOLKIT_INCLUDE_DIRECTORIES)
+  string(REPLACE "\r" "" _nvcc_output_orig "${CMAKE_CUDA_COMPILER_PRODUCED_OUTPUT}")
+  if(_nvcc_output_orig MATCHES "#\\\$ +INCLUDES= *([^\n]*)\n")
+    set(_nvcc_includes "${CMAKE_MATCH_1}")
+    string(APPEND _nvcc_log "  found 'INCLUDES=' string: [${_nvcc_includes}]\n")
+  else()
+    set(_nvcc_includes "")
+    string(REPLACE "\n" "\n    " _nvcc_output_log "\n${_nvcc_output_orig}")
+    string(APPEND _nvcc_log "  no 'INCLUDES=' string found in nvcc output:${_nvcc_output_log}\n")
+  endif()
+  if(_nvcc_includes)
+    # across all operating system each include directory is prefixed with -I
+    separate_arguments(_nvcc_output NATIVE_COMMAND "${_nvcc_includes}")
+    foreach(line IN LISTS _nvcc_output)
+      string(REGEX REPLACE "^-I" "" line "${line}")
+      get_filename_component(line "${line}" ABSOLUTE)
+      list(APPEND CMAKE_CUDA_TOOLKIT_INCLUDE_DIRECTORIES "${line}")
+    endforeach()
+
+    file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
+      "Parsed CUDA nvcc include information from above output:\n${_nvcc_log}\n${log}\n\n")
+  else()
+    file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
+      "Failed to detect CUDA nvcc include information:\n${_nvcc_log}\n\n")
+  endif()
+
+  # Parse default CUDA architecture.
+  cmake_policy(GET CMP0104 _CUDA_CMP0104)
+  if(NOT CMAKE_CUDA_ARCHITECTURES AND _CUDA_CMP0104 STREQUAL "NEW")
+    string(REGEX MATCH "arch[ =]compute_([0-9]+)" dont_care "${CMAKE_CUDA_COMPILER_PRODUCED_OUTPUT}")
+    set(detected_architecture "${CMAKE_MATCH_1}")
+  elseif(CMAKE_CUDA_ARCHITECTURES)
+    string(REGEX MATCHALL "-arch compute_([0-9]+)" target_cpus "${CMAKE_CUDA_COMPILER_PRODUCED_OUTPUT}")
+
+    foreach(cpu ${target_cpus})
+      string(REGEX MATCH "-arch compute_([0-9]+)" dont_care "${cpu}")
+      list(APPEND architectures "${CMAKE_MATCH_1}")
+    endforeach()
+  endif()
+endif()
+
+# If the user didn't set the architectures, then set them to a default.
+# If the user did, then make sure those architectures worked.
+if(DEFINED detected_architecture AND "${CMAKE_CUDA_ARCHITECTURES}" STREQUAL "")
+  set(CMAKE_CUDA_ARCHITECTURES "${detected_architecture}" CACHE STRING "CUDA architectures")
+
+  if(NOT CMAKE_CUDA_ARCHITECTURES)
+    message(FATAL_ERROR "Failed to find a working CUDA architecture.")
+  endif()
+elseif(architectures)
+  # Sort since order mustn't matter.
+  list(SORT architectures)
+  list(SORT tested_architectures)
+
+  # We don't distinguish real/virtual architectures during testing.
+  # For "70-real;70-virtual" we detect "70" as working and tested_architectures is "70;70".
+  # Thus we need to remove duplicates before checking if they're equal.
+  list(REMOVE_DUPLICATES tested_architectures)
+
+  if(NOT "${architectures}" STREQUAL "${tested_architectures}")
+    message(FATAL_ERROR
+      "The CMAKE_CUDA_ARCHITECTURES:\n"
+      "  ${CMAKE_CUDA_ARCHITECTURES}\n"
+      "do not all work with this compiler.  Try:\n"
+      "  ${architectures}\n"
+      "instead.")
+  endif()
 endif()
 
 # configure all variables set in this file
 configure_file(${CMAKE_ROOT}/Modules/CMakeCUDACompiler.cmake.in
   ${CMAKE_PLATFORM_INFO_DIR}/CMakeCUDACompiler.cmake
   @ONLY
-  )
+)
+
+# Don't leak variables unnecessarily to user code.
+unset(_CUDA_INCLUDE_DIR CACHE)
+unset(_CUDA_NVCC_EXECUTABLE CACHE)
+unset(_CUDA_LIBRARY_DIR)
+unset(_CUDA_TARGET_DIR)
+unset(_CUDA_TARGET_NAME)
 
 set(CMAKE_CUDA_COMPILER_ENV_VAR "CUDACXX")
 set(CMAKE_CUDA_HOST_COMPILER_ENV_VAR "CUDAHOSTCXX")
diff --git a/Modules/CMakeDetermineCXXCompiler.cmake b/Modules/CMakeDetermineCXXCompiler.cmake
index 7274eec..4c2924a 100644
--- a/Modules/CMakeDetermineCXXCompiler.cmake
+++ b/Modules/CMakeDetermineCXXCompiler.cmake
@@ -42,7 +42,7 @@
     if(NOT $ENV{CXX} STREQUAL "")
       get_filename_component(CMAKE_CXX_COMPILER_INIT $ENV{CXX} PROGRAM PROGRAM_ARGS CMAKE_CXX_FLAGS_ENV_INIT)
       if(CMAKE_CXX_FLAGS_ENV_INIT)
-        set(CMAKE_CXX_COMPILER_ARG1 "${CMAKE_CXX_FLAGS_ENV_INIT}" CACHE STRING "First argument to CXX compiler")
+        set(CMAKE_CXX_COMPILER_ARG1 "${CMAKE_CXX_FLAGS_ENV_INIT}" CACHE STRING "Arguments to CXX compiler")
       endif()
       if(NOT EXISTS ${CMAKE_CXX_COMPILER_INIT})
         message(FATAL_ERROR "Could not find compiler set in environment variable CXX:\n$ENV{CXX}.\n${CMAKE_CXX_COMPILER_INIT}")
@@ -83,6 +83,10 @@
     )
 endif()
 
+if(CMAKE_CXX_COMPILER_TARGET)
+  list(PREPEND CMAKE_CXX_COPMILER_ID_TEST_FLAGS "-c --target=${CMAKE_CXX_COMPILER_TARGET}")
+endif()
+
 # Build a small source file to identify the compiler.
 if(NOT CMAKE_CXX_COMPILER_ID_RUN)
   set(CMAKE_CXX_COMPILER_ID_RUN 1)
@@ -94,7 +98,7 @@
     CMAKE_CXX_COMPILER_ID_PLATFORM_CONTENT)
 
   # The IAR compiler produces weird output.
-  # See https://gitlab.kitware.com/cmake/cmake/issues/10176#note_153591
+  # See https://gitlab.kitware.com/cmake/cmake/-/issues/10176#note_153591
   list(APPEND CMAKE_CXX_COMPILER_ID_VENDORS IAR)
   set(CMAKE_CXX_COMPILER_ID_VENDOR_FLAGS_IAR )
   set(CMAKE_CXX_COMPILER_ID_VENDOR_REGEX_IAR "IAR .+ Compiler")
@@ -110,6 +114,8 @@
   include(${CMAKE_ROOT}/Modules/CMakeDetermineCompilerId.cmake)
   CMAKE_DETERMINE_COMPILER_ID(CXX CXXFLAGS CMakeCXXCompilerId.cpp)
 
+  _cmake_find_compiler_sysroot(CXX)
+
   # Set old compiler and platform id variables.
   if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
     set(CMAKE_COMPILER_IS_GNUCXX 1)
@@ -150,7 +156,7 @@
 # "arm-unknown-nto-qnx6" instead of the correct "arm-unknown-nto-qnx6.3.0-"
 
 
-if (CMAKE_CROSSCOMPILING  AND NOT  _CMAKE_TOOLCHAIN_PREFIX)
+if (NOT _CMAKE_TOOLCHAIN_PREFIX)
 
   if("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU|Clang|QCC")
     get_filename_component(COMPILER_BASENAME "${CMAKE_CXX_COMPILER}" NAME)
@@ -189,6 +195,14 @@
 include(Compiler/${CMAKE_CXX_COMPILER_ID}-FindBinUtils OPTIONAL)
 unset(_CMAKE_PROCESSING_LANGUAGE)
 
+if(CMAKE_CXX_COMPILER_SYSROOT)
+  string(CONCAT _SET_CMAKE_CXX_COMPILER_SYSROOT
+    "set(CMAKE_CXX_COMPILER_SYSROOT \"${CMAKE_CXX_COMPILER_SYSROOT}\")\n"
+    "set(CMAKE_COMPILER_SYSROOT \"${CMAKE_CXX_COMPILER_SYSROOT}\")")
+else()
+  set(_SET_CMAKE_CXX_COMPILER_SYSROOT "")
+endif()
+
 if(CMAKE_CXX_COMPILER_ARCHITECTURE_ID)
   set(_SET_CMAKE_CXX_COMPILER_ARCHITECTURE_ID
     "set(CMAKE_CXX_COMPILER_ARCHITECTURE_ID ${CMAKE_CXX_COMPILER_ARCHITECTURE_ID})")
diff --git a/Modules/CMakeDetermineCompiler.cmake b/Modules/CMakeDetermineCompiler.cmake
index c37adae..2780399 100644
--- a/Modules/CMakeDetermineCompiler.cmake
+++ b/Modules/CMakeDetermineCompiler.cmake
@@ -53,6 +53,20 @@
       NO_DEFAULT_PATH
       DOC "${lang} compiler")
   endif()
+  if(CMAKE_HOST_WIN32 AND CMAKE_GENERATOR MATCHES "Ninja")
+    # On Windows command-line builds, the Makefile generators each imply
+    # a preferred compiler tool.  The Ninja generator does not imply a
+    # compiler tool, so use the compiler that occurs first in PATH.
+    find_program(CMAKE_${lang}_COMPILER
+      NAMES ${CMAKE_${lang}_COMPILER_LIST}
+      NAMES_PER_DIR
+      DOC "${lang} compiler"
+      NO_PACKAGE_ROOT_PATH
+      NO_CMAKE_PATH
+      NO_CMAKE_ENVIRONMENT_PATH
+      NO_CMAKE_SYSTEM_PATH
+      )
+  endif()
   find_program(CMAKE_${lang}_COMPILER NAMES ${CMAKE_${lang}_COMPILER_LIST} DOC "${lang} compiler")
   if(CMAKE_${lang}_COMPILER_INIT AND NOT CMAKE_${lang}_COMPILER)
     set_property(CACHE CMAKE_${lang}_COMPILER PROPERTY VALUE "${CMAKE_${lang}_COMPILER_INIT}")
@@ -93,16 +107,14 @@
   if(CMAKE_${lang}_COMPILER)
     # we only get here if CMAKE_${lang}_COMPILER was specified using -D or a pre-made CMakeCache.txt
     # (e.g. via ctest) or set in CMAKE_TOOLCHAIN_FILE
-    # if CMAKE_${lang}_COMPILER is a list of length 2, use the first item as
-    # CMAKE_${lang}_COMPILER and the 2nd one as CMAKE_${lang}_COMPILER_ARG1
-    list(LENGTH CMAKE_${lang}_COMPILER _CMAKE_${lang}_COMPILER_LIST_LENGTH)
-    if("${_CMAKE_${lang}_COMPILER_LIST_LENGTH}" EQUAL 2)
-      list(GET CMAKE_${lang}_COMPILER 1 CMAKE_${lang}_COMPILER_ARG1)
-      list(GET CMAKE_${lang}_COMPILER 0 CMAKE_${lang}_COMPILER)
-    endif()
-    unset(_CMAKE_${lang}_COMPILER_LIST_LENGTH)
+    # if CMAKE_${lang}_COMPILER is a list, use the first item as
+    # CMAKE_${lang}_COMPILER and the rest as CMAKE_${lang}_COMPILER_ARG1
+    set(CMAKE_${lang}_COMPILER_ARG1 "${CMAKE_${lang}_COMPILER}")
+    list(POP_FRONT CMAKE_${lang}_COMPILER_ARG1 CMAKE_${lang}_COMPILER)
+    list(JOIN CMAKE_${lang}_COMPILER_ARG1 " " CMAKE_${lang}_COMPILER_ARG1)
 
     # find the compiler in the PATH if necessary
+    # if compiler (and arguments) comes from cache then synchronize cache with updated CMAKE_<LANG>_COMPILER
     get_filename_component(_CMAKE_USER_${lang}_COMPILER_PATH "${CMAKE_${lang}_COMPILER}" PATH)
     if(NOT _CMAKE_USER_${lang}_COMPILER_PATH)
       find_program(CMAKE_${lang}_COMPILER_WITH_PATH NAMES ${CMAKE_${lang}_COMPILER})
@@ -115,6 +127,30 @@
         unset(_CMAKE_${lang}_COMPILER_CACHED)
       endif()
       unset(CMAKE_${lang}_COMPILER_WITH_PATH CACHE)
+    elseif (EXISTS ${CMAKE_${lang}_COMPILER})
+      get_property(_CMAKE_${lang}_COMPILER_CACHED CACHE CMAKE_${lang}_COMPILER PROPERTY TYPE)
+      if(_CMAKE_${lang}_COMPILER_CACHED)
+        set(CMAKE_${lang}_COMPILER "${CMAKE_${lang}_COMPILER}" CACHE STRING "${lang} compiler" FORCE)
+      endif()
+      unset(_CMAKE_${lang}_COMPILER_CACHED)
     endif()
   endif()
 endmacro()
+
+function(_cmake_find_compiler_sysroot lang)
+  if(CMAKE_${lang}_COMPILER_ID STREQUAL "GNU")
+    execute_process(COMMAND "${CMAKE_${lang}_COMPILER}" -print-sysroot
+      OUTPUT_STRIP_TRAILING_WHITESPACE
+      OUTPUT_VARIABLE _cmake_sysroot_run_out
+      ERROR_VARIABLE _cmake_sysroot_run_err)
+
+    if(_cmake_sysroot_run_out AND NOT _cmake_sysroot_run_err
+        AND NOT _cmake_sysroot_run_out STREQUAL "/"
+        AND IS_DIRECTORY "${_cmake_sysroot_run_out}/usr")
+      file(TO_CMAKE_PATH "${_cmake_sysroot_run_out}/usr" _cmake_sysroot_run_out_usr)
+      set(CMAKE_${lang}_COMPILER_SYSROOT "${_cmake_sysroot_run_out_usr}" PARENT_SCOPE)
+    else()
+      set(CMAKE_${lang}_COMPILER_SYSROOT "" PARENT_SCOPE)
+    endif()
+  endif()
+endfunction()
diff --git a/Modules/CMakeDetermineCompilerABI.cmake b/Modules/CMakeDetermineCompilerABI.cmake
index e1b3c52..50d5cd1 100644
--- a/Modules/CMakeDetermineCompilerABI.cmake
+++ b/Modules/CMakeDetermineCompilerABI.cmake
@@ -65,10 +65,13 @@
     # Move result from cache to normal variable.
     set(CMAKE_${lang}_ABI_COMPILED ${CMAKE_${lang}_ABI_COMPILED})
     unset(CMAKE_${lang}_ABI_COMPILED CACHE)
+    if(CMAKE_${lang}_ABI_COMPILED AND _copy_error)
+      set(CMAKE_${lang}_ABI_COMPILED 0)
+    endif()
     set(CMAKE_${lang}_ABI_COMPILED ${CMAKE_${lang}_ABI_COMPILED} PARENT_SCOPE)
 
     # Load the resulting information strings.
-    if(CMAKE_${lang}_ABI_COMPILED AND NOT _copy_error)
+    if(CMAKE_${lang}_ABI_COMPILED)
       message(CHECK_PASS "done")
       file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
         "Detecting ${lang} compiler ABI info compiled with the following output:\n${OUTPUT}\n\n")
diff --git a/Modules/CMakeDetermineCompilerId.cmake b/Modules/CMakeDetermineCompilerId.cmake
index 9eeb7a1..d7a35e1 100644
--- a/Modules/CMakeDetermineCompilerId.cmake
+++ b/Modules/CMakeDetermineCompilerId.cmake
@@ -14,8 +14,10 @@
   # Make sure user-specified compiler flags are used.
   if(CMAKE_${lang}_FLAGS)
     set(CMAKE_${lang}_COMPILER_ID_FLAGS ${CMAKE_${lang}_FLAGS})
-  else()
+  elseif(DEFINED ENV{${flagvar}})
     set(CMAKE_${lang}_COMPILER_ID_FLAGS $ENV{${flagvar}})
+  else(CMAKE_${lang}_FLAGS_INIT)
+    set(CMAKE_${lang}_COMPILER_ID_FLAGS ${CMAKE_${lang}_FLAGS_INIT})
   endif()
   string(REPLACE " " ";" CMAKE_${lang}_COMPILER_ID_FLAGS_LIST "${CMAKE_${lang}_COMPILER_ID_FLAGS}")
 
@@ -248,7 +250,7 @@
     set(id_PostBuildEvent_Command "")
     if(CMAKE_VS_PLATFORM_TOOLSET MATCHES "^[Ll][Ll][Vv][Mm](_v[0-9]+(_xp)?)?$")
       set(id_cl_var "ClangClExecutable")
-    elseif(CMAKE_VS_PLATFORM_TOOLSET MATCHES "^[Cc][Ll][Aa][Nn][Gg][Cc][Ll]$")
+    elseif(CMAKE_VS_PLATFORM_TOOLSET MATCHES "^[Cc][Ll][Aa][Nn][Gg]([Cc][Ll]$|_[0-9])")
       set(id_cl "$(CLToolExe)")
     elseif(CMAKE_VS_PLATFORM_TOOLSET MATCHES "v[0-9]+_clang_.*")
       set(id_cl clang.exe)
@@ -310,17 +312,36 @@
       set(id_PreferredToolArchitecture "")
     endif()
     if(CMAKE_SYSTEM_NAME STREQUAL "WindowsPhone")
+      set(id_keyword "Win32Proj")
       set(id_system "<ApplicationType>Windows Phone</ApplicationType>")
     elseif(CMAKE_SYSTEM_NAME STREQUAL "WindowsStore")
+      set(id_keyword "Win32Proj")
       set(id_system "<ApplicationType>Windows Store</ApplicationType>")
+    elseif(CMAKE_SYSTEM_NAME STREQUAL "Android")
+      set(id_keyword "Android")
+      set(id_system "<ApplicationType>Android</ApplicationType>")
     else()
+      set(id_keyword "Win32Proj")
       set(id_system "")
     endif()
-    if(id_system AND CMAKE_SYSTEM_VERSION MATCHES "^([0-9]+\\.[0-9]+)")
+    if(id_keyword STREQUAL "Android")
+      if(CMAKE_GENERATOR MATCHES "Visual Studio 14")
+        set(id_system_version "<ApplicationTypeRevision>2.0</ApplicationTypeRevision>")
+      elseif(CMAKE_GENERATOR MATCHES "Visual Studio 1[56]")
+        set(id_system_version "<ApplicationTypeRevision>3.0</ApplicationTypeRevision>")
+      else()
+        set(id_system_version "")
+      endif()
+    elseif(id_system AND CMAKE_SYSTEM_VERSION MATCHES "^([0-9]+\\.[0-9]+)")
       set(id_system_version "<ApplicationTypeRevision>${CMAKE_MATCH_1}</ApplicationTypeRevision>")
     else()
       set(id_system_version "")
     endif()
+    if(id_keyword STREQUAL "Android")
+      set(id_config_type "DynamicLibrary")
+    else()
+      set(id_config_type "Application")
+    endif()
     if(CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION)
       set(id_WindowsTargetPlatformVersion "<WindowsTargetPlatformVersion>${CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION}</WindowsTargetPlatformVersion>")
     endif()
@@ -333,9 +354,11 @@
         string(APPEND id_CustomGlobals "<${CMAKE_MATCH_1}>${CMAKE_MATCH_2}</${CMAKE_MATCH_1}>\n    ")
       endif()
     endforeach()
-    if(id_platform STREQUAL ARM64)
+    if(id_keyword STREQUAL "Android")
+      set(id_WindowsSDKDesktopARMSupport "")
+    elseif(id_platform STREQUAL "ARM64")
       set(id_WindowsSDKDesktopARMSupport "<WindowsSDKDesktopARM64Support>true</WindowsSDKDesktopARM64Support>")
-    elseif(id_platform STREQUAL ARM)
+    elseif(id_platform STREQUAL "ARM")
       set(id_WindowsSDKDesktopARMSupport "<WindowsSDKDesktopARMSupport>true</WindowsSDKDesktopARMSupport>")
     else()
       set(id_WindowsSDKDesktopARMSupport "")
@@ -469,6 +492,12 @@
         set(id_clang_cxx_library "CLANG_CXX_LIBRARY = \"${CMAKE_MATCH_3}\";")
       endif()
     endif()
+    if(CMAKE_SYSTEM_NAME STREQUAL "Darwin" AND CMAKE_OSX_SYSROOT MATCHES "^$|[Mm][Aa][Cc][Oo][Ss]")
+      # When targeting macOS, use only the host architecture.
+      set(id_archs [[ARCHS = "$(NATIVE_ARCH_ACTUAL)";]])
+    else()
+      set(id_archs "")
+    endif()
     configure_file(${CMAKE_ROOT}/Modules/CompilerId/Xcode-3.pbxproj.in
       ${id_dir}/CompilerId${lang}.xcodeproj/project.pbxproj @ONLY)
     unset(_ENV_MACOSX_DEPLOYMENT_TARGET)
@@ -696,7 +725,7 @@
     foreach(info ${CMAKE_${lang}_COMPILER_ID_STRINGS})
       # The IAR-AVR compiler uses a binary format that places a '6'
       # character (0x34) before each character in the string.  Strip
-      # out these characters without removing any legitamate characters.
+      # out these characters without removing any legitimate characters.
       if("${info}" MATCHES "(.)I.N.F.O.:.")
         string(REGEX REPLACE "${CMAKE_MATCH_1}(.)" "\\1" info "${info}")
       endif()
@@ -874,6 +903,14 @@
     file(MAKE_DIRECTORY ${CMAKE_${lang}_COMPILER_ID_DIR})
   endif()
 
+  # Save the current LC_ALL, LC_MESSAGES, and LANG environment variables
+  # and set them to "C" so we get the expected output to match.
+  set(_orig_lc_all      $ENV{LC_ALL})
+  set(_orig_lc_messages $ENV{LC_MESSAGES})
+  set(_orig_lang        $ENV{LANG})
+  set(ENV{LC_ALL}      C)
+  set(ENV{LC_MESSAGES} C)
+  set(ENV{LANG}        C)
 
   foreach(vendor ${CMAKE_${lang}_COMPILER_ID_VENDORS})
     set(flags ${CMAKE_${lang}_COMPILER_ID_VENDOR_FLAGS_${vendor}})
@@ -895,6 +932,7 @@
         "matched \"${regex}\":\n${output}")
       set(CMAKE_${lang}_COMPILER_ID "${vendor}" PARENT_SCOPE)
       set(CMAKE_${lang}_COMPILER_ID_OUTPUT "${output}" PARENT_SCOPE)
+      set(CMAKE_${lang}_COMPILER_ID_VENDOR_MATCH "${CMAKE_MATCH_1}" PARENT_SCOPE)
       break()
     else()
       if("${result}" MATCHES  "timeout")
@@ -908,6 +946,11 @@
        endif()
     endif()
   endforeach()
+
+  # Restore original LC_ALL, LC_MESSAGES, and LANG
+  set(ENV{LC_ALL}      ${_orig_lc_all})
+  set(ENV{LC_MESSAGES} ${_orig_lc_messages})
+  set(ENV{LANG}        ${_orig_lang})
 endfunction()
 
 function(CMAKE_DETERMINE_MSVC_SHOWINCLUDES_PREFIX lang userflags)
diff --git a/Modules/CMakeDetermineFortranCompiler.cmake b/Modules/CMakeDetermineFortranCompiler.cmake
index e850541..8a57408 100644
--- a/Modules/CMakeDetermineFortranCompiler.cmake
+++ b/Modules/CMakeDetermineFortranCompiler.cmake
@@ -26,7 +26,7 @@
     if(NOT $ENV{FC} STREQUAL "")
       get_filename_component(CMAKE_Fortran_COMPILER_INIT $ENV{FC} PROGRAM PROGRAM_ARGS CMAKE_Fortran_FLAGS_ENV_INIT)
       if(CMAKE_Fortran_FLAGS_ENV_INIT)
-        set(CMAKE_Fortran_COMPILER_ARG1 "${CMAKE_Fortran_FLAGS_ENV_INIT}" CACHE STRING "First argument to Fortran compiler")
+        set(CMAKE_Fortran_COMPILER_ARG1 "${CMAKE_Fortran_FLAGS_ENV_INIT}" CACHE STRING "Arguments to Fortran compiler")
       endif()
       if(EXISTS ${CMAKE_Fortran_COMPILER_INIT})
       else()
@@ -186,6 +186,8 @@
   include(${CMAKE_ROOT}/Modules/CMakeDetermineCompilerId.cmake)
   CMAKE_DETERMINE_COMPILER_ID(Fortran FFLAGS CMakeFortranCompilerId.F)
 
+  _cmake_find_compiler_sysroot(Fortran)
+
   # Fall back to old is-GNU test.
   if(NOT CMAKE_Fortran_COMPILER_ID)
     execute_process(COMMAND ${CMAKE_Fortran_COMPILER} ${CMAKE_Fortran_COMPILER_ID_FLAGS_LIST} -E "${CMAKE_ROOT}/Modules/CMakeTestGNU.c"
@@ -249,7 +251,7 @@
 # NAME_WE cannot be used since then this test will fail for names like
 # "arm-unknown-nto-qnx6.3.0-gcc.exe", where BASENAME would be
 # "arm-unknown-nto-qnx6" instead of the correct "arm-unknown-nto-qnx6.3.0-"
-if (CMAKE_CROSSCOMPILING  AND NOT _CMAKE_TOOLCHAIN_PREFIX)
+if (NOT _CMAKE_TOOLCHAIN_PREFIX)
 
   if(CMAKE_Fortran_COMPILER_ID MATCHES "GNU")
     get_filename_component(COMPILER_BASENAME "${CMAKE_Fortran_COMPILER}" NAME)
@@ -276,6 +278,14 @@
     "set(CMAKE_Fortran_XL_CPP \"${CMAKE_Fortran_XL_CPP}\")")
 endif()
 
+if(CMAKE_Fortran_COMPILER_SYSROOT)
+  string(CONCAT _SET_CMAKE_Fortran_COMPILER_SYSROOT
+    "set(CMAKE_Fortran_COMPILER_SYSROOT \"${CMAKE_Fortran_COMPILER_SYSROOT}\")\n"
+    "set(CMAKE_COMPILER_SYSROOT \"${CMAKE_Fortran_COMPILER_SYSROOT}\")")
+else()
+  set(_SET_CMAKE_Fortran_COMPILER_SYSROOT "")
+endif()
+
 if(CMAKE_Fortran_COMPILER_ARCHITECTURE_ID)
   set(_SET_CMAKE_Fortran_COMPILER_ARCHITECTURE_ID
     "set(CMAKE_Fortran_COMPILER_ARCHITECTURE_ID ${CMAKE_Fortran_COMPILER_ARCHITECTURE_ID})")
diff --git a/Modules/CMakeDetermineJavaCompiler.cmake b/Modules/CMakeDetermineJavaCompiler.cmake
index 3092bb5..db456c0 100644
--- a/Modules/CMakeDetermineJavaCompiler.cmake
+++ b/Modules/CMakeDetermineJavaCompiler.cmake
@@ -11,7 +11,7 @@
   if(NOT $ENV{JAVA_COMPILER} STREQUAL "")
     get_filename_component(CMAKE_Java_COMPILER_INIT $ENV{JAVA_COMPILER} PROGRAM PROGRAM_ARGS CMAKE_Java_FLAGS_ENV_INIT)
     if(CMAKE_Java_FLAGS_ENV_INIT)
-      set(CMAKE_Java_COMPILER_ARG1 "${CMAKE_Java_FLAGS_ENV_INIT}" CACHE STRING "First argument to Java compiler")
+      set(CMAKE_Java_COMPILER_ARG1 "${CMAKE_Java_FLAGS_ENV_INIT}" CACHE STRING "Arguments to Java compiler")
     endif()
     if(NOT EXISTS ${CMAKE_Java_COMPILER_INIT})
       message(SEND_ERROR "Could not find compiler set in environment variable JAVA_COMPILER:\n$ENV{JAVA_COMPILER}.")
diff --git a/Modules/CMakeDetermineOBJCCompiler.cmake b/Modules/CMakeDetermineOBJCCompiler.cmake
index 11b47fd..709eb25 100644
--- a/Modules/CMakeDetermineOBJCCompiler.cmake
+++ b/Modules/CMakeDetermineOBJCCompiler.cmake
@@ -39,7 +39,7 @@
       if($ENV{${var}} MATCHES ".+")
         get_filename_component(CMAKE_OBJC_COMPILER_INIT $ENV{${var}} PROGRAM PROGRAM_ARGS CMAKE_OBJC_FLAGS_ENV_INIT)
         if(CMAKE_OBJC_FLAGS_ENV_INIT)
-          set(CMAKE_OBJC_COMPILER_ARG1 "${CMAKE_OBJC_FLAGS_ENV_INIT}" CACHE STRING "First argument to Objective-C compiler")
+          set(CMAKE_OBJC_COMPILER_ARG1 "${CMAKE_OBJC_FLAGS_ENV_INIT}" CACHE STRING "Arguments to Objective-C compiler")
         endif()
         if(NOT EXISTS ${CMAKE_OBJC_COMPILER_INIT})
           message(FATAL_ERROR "Could not find compiler set in environment variable ${var}:\n  $ENV{${var}}")
@@ -65,14 +65,11 @@
   else()
     # we only get here if CMAKE_OBJC_COMPILER was specified using -D or a pre-made CMakeCache.txt
     # (e.g. via ctest) or set in CMAKE_TOOLCHAIN_FILE
-    # if CMAKE_OBJC_COMPILER is a list of length 2, use the first item as
-    # CMAKE_OBJC_COMPILER and the 2nd one as CMAKE_OBJC_COMPILER_ARG1
-
-    list(LENGTH CMAKE_OBJC_COMPILER _CMAKE_OBJC_COMPILER_LIST_LENGTH)
-    if("${_CMAKE_OBJC_COMPILER_LIST_LENGTH}" EQUAL 2)
-      list(GET CMAKE_OBJC_COMPILER 1 CMAKE_OBJC_COMPILER_ARG1)
-      list(GET CMAKE_OBJC_COMPILER 0 CMAKE_OBJC_COMPILER)
-    endif()
+    # if CMAKE_OBJC_COMPILER is a list, use the first item as
+    # CMAKE_OBJC_COMPILER and the rest as CMAKE_OBJC_COMPILER_ARG1
+    set(CMAKE_OBJC_COMPILER_ARG1 "${CMAKE_OBJC_COMPILER}")
+    list(POP_FRONT CMAKE_OBJC_COMPILER_ARG1 CMAKE_OBJC_COMPILER)
+    list(JOIN CMAKE_OBJC_COMPILER_ARG1 " " CMAKE_OBJC_COMPILER_ARG1)
 
     # if a compiler was specified by the user but without path,
     # now try to find it with the full path
diff --git a/Modules/CMakeDetermineOBJCXXCompiler.cmake b/Modules/CMakeDetermineOBJCXXCompiler.cmake
index db874d1..ffd0091 100644
--- a/Modules/CMakeDetermineOBJCXXCompiler.cmake
+++ b/Modules/CMakeDetermineOBJCXXCompiler.cmake
@@ -41,7 +41,7 @@
       if($ENV{${var}} MATCHES ".+")
         get_filename_component(CMAKE_OBJCXX_COMPILER_INIT $ENV{${var}} PROGRAM PROGRAM_ARGS CMAKE_OBJCXX_FLAGS_ENV_INIT)
         if(CMAKE_OBJCXX_FLAGS_ENV_INIT)
-          set(CMAKE_OBJCXX_COMPILER_ARG1 "${CMAKE_OBJCXX_FLAGS_ENV_INIT}" CACHE STRING "First argument to Objective-C++ compiler")
+          set(CMAKE_OBJCXX_COMPILER_ARG1 "${CMAKE_OBJCXX_FLAGS_ENV_INIT}" CACHE STRING "Arguments to Objective-C++ compiler")
         endif()
         if(NOT EXISTS ${CMAKE_OBJCXX_COMPILER_INIT})
           message(FATAL_ERROR "Could not find compiler set in environment variable ${var}:\n  $ENV{${var}}")
@@ -67,14 +67,11 @@
   else()
     # we only get here if CMAKE_OBJCXX_COMPILER was specified using -D or a pre-made CMakeCache.txt
     # (e.g. via ctest) or set in CMAKE_TOOLCHAIN_FILE
-    # if CMAKE_OBJCXX_COMPILER is a list of length 2, use the first item as
-    # CMAKE_OBJCXX_COMPILER and the 2nd one as CMAKE_OBJCXX_COMPILER_ARG1
-
-    list(LENGTH CMAKE_OBJCXX_COMPILER _CMAKE_OBJCXX_COMPILER_LIST_LENGTH)
-    if("${_CMAKE_OBJCXX_COMPILER_LIST_LENGTH}" EQUAL 2)
-      list(GET CMAKE_OBJCXX_COMPILER 1 CMAKE_OBJCXX_COMPILER_ARG1)
-      list(GET CMAKE_OBJCXX_COMPILER 0 CMAKE_OBJCXX_COMPILER)
-    endif()
+    # if CMAKE_OBJCXX_COMPILER is a list, use the first item as
+    # CMAKE_OBJCXX_COMPILER and the rest as CMAKE_OBJCXX_COMPILER_ARG1
+    set(CMAKE_OBJCXX_COMPILER_ARG1 "${CMAKE_OBJCXX_COMPILER}")
+    list(POP_FRONT CMAKE_OBJCXX_COMPILER_ARG1 CMAKE_OBJCXX_COMPILER)
+    list(JOIN CMAKE_OBJCXX_COMPILER_ARG1 " " CMAKE_OBJCXX_COMPILER_ARG1)
 
     # if a compiler was specified by the user but without path,
     # now try to find it with the full path
@@ -148,7 +145,7 @@
 # "arm-unknown-nto-qnx6" instead of the correct "arm-unknown-nto-qnx6.3.0-"
 
 
-if (CMAKE_CROSSCOMPILING  AND NOT  _CMAKE_TOOLCHAIN_PREFIX)
+if (NOT _CMAKE_TOOLCHAIN_PREFIX)
 
   if("${CMAKE_OBJCXX_COMPILER_ID}" MATCHES "GNU|Clang|QCC")
     get_filename_component(COMPILER_BASENAME "${CMAKE_OBJCXX_COMPILER}" NAME)
diff --git a/Modules/CMakeDetermineRCCompiler.cmake b/Modules/CMakeDetermineRCCompiler.cmake
index 8801e16..f8d55a5 100644
--- a/Modules/CMakeDetermineRCCompiler.cmake
+++ b/Modules/CMakeDetermineRCCompiler.cmake
@@ -13,7 +13,7 @@
   if(NOT $ENV{RC} STREQUAL "")
     get_filename_component(CMAKE_RC_COMPILER_INIT $ENV{RC} PROGRAM PROGRAM_ARGS CMAKE_RC_FLAGS_ENV_INIT)
     if(CMAKE_RC_FLAGS_ENV_INIT)
-      set(CMAKE_RC_COMPILER_ARG1 "${CMAKE_RC_FLAGS_ENV_INIT}" CACHE STRING "First argument to RC compiler")
+      set(CMAKE_RC_COMPILER_ARG1 "${CMAKE_RC_FLAGS_ENV_INIT}" CACHE STRING "Arguments to RC compiler")
     endif()
     if(EXISTS ${CMAKE_RC_COMPILER_INIT})
     else()
diff --git a/Modules/CMakeDetermineSwiftCompiler.cmake b/Modules/CMakeDetermineSwiftCompiler.cmake
index 688133f..aaad560 100644
--- a/Modules/CMakeDetermineSwiftCompiler.cmake
+++ b/Modules/CMakeDetermineSwiftCompiler.cmake
@@ -27,7 +27,7 @@
         PROGRAM_ARGS CMAKE_Swift_FLAGS_ENV_INIT)
       if(CMAKE_Swift_FLAGS_ENV_INIT)
         set(CMAKE_Swift_COMPILER_ARG1 "${CMAKE_Swift_FLAGS_ENV_INIT}" CACHE
-          STRING "First argument to the Swift compiler")
+          STRING "Arguments to the Swift compiler")
       endif()
       if(NOT EXISTS ${CMAKE_Swift_COMPILER_INIT})
         message(FATAL_ERROR "Could not find compiler set in environment variable SWIFTC\n$ENV{SWIFTC}.\n${CMAKE_Swift_COMPILER_INIT}")
diff --git a/Modules/CMakeFindBinUtils.cmake b/Modules/CMakeFindBinUtils.cmake
index c23e447..de9ef9a 100644
--- a/Modules/CMakeFindBinUtils.cmake
+++ b/Modules/CMakeFindBinUtils.cmake
@@ -75,6 +75,7 @@
   endif()
 
   find_program(CMAKE_LINKER NAMES ${_CMAKE_ADDITIONAL_LINKER_NAMES} link HINTS ${_CMAKE_TOOLCHAIN_LOCATION})
+  find_program(CMAKE_AR     NAMES lib  HINTS ${_CMAKE_TOOLCHAIN_LOCATION})
   find_program(CMAKE_MT     NAMES mt   HINTS ${_CMAKE_TOOLCHAIN_LOCATION})
 
   list(APPEND _CMAKE_TOOL_VARS LINKER MT)
diff --git a/Modules/CMakeFindEclipseCDT4.cmake b/Modules/CMakeFindEclipseCDT4.cmake
index 199005d..e563a12 100644
--- a/Modules/CMakeFindEclipseCDT4.cmake
+++ b/Modules/CMakeFindEclipseCDT4.cmake
@@ -25,7 +25,7 @@
 
   if(NOT DEFINED CMAKE_ECLIPSE_VERSION)
     if(CMAKE_ECLIPSE_EXECUTABLE)
-      # use REALPATH to resolve symlinks (https://gitlab.kitware.com/cmake/cmake/issues/13036)
+      # use REALPATH to resolve symlinks (https://gitlab.kitware.com/cmake/cmake/-/issues/13036)
       get_filename_component(_REALPATH_CMAKE_ECLIPSE_EXECUTABLE "${CMAKE_ECLIPSE_EXECUTABLE}" REALPATH)
       get_filename_component(_ECLIPSE_DIR "${_REALPATH_CMAKE_ECLIPSE_EXECUTABLE}" PATH)
       file(GLOB _ECLIPSE_FEATURE_DIR "${_ECLIPSE_DIR}/features/org.eclipse.platform*")
diff --git a/Modules/CMakeFindFrameworks.cmake b/Modules/CMakeFindFrameworks.cmake
index 06c05fb..8906f48 100644
--- a/Modules/CMakeFindFrameworks.cmake
+++ b/Modules/CMakeFindFrameworks.cmake
@@ -17,13 +17,25 @@
   macro(CMAKE_FIND_FRAMEWORKS fwk)
     set(${fwk}_FRAMEWORKS)
     if(APPLE)
-      foreach(dir
-          ~/Library/Frameworks/${fwk}.framework
-          /usr/local/Frameworks/${fwk}.framework
-          /Library/Frameworks/${fwk}.framework
-          /System/Library/Frameworks/${fwk}.framework
-          /Network/Library/Frameworks/${fwk}.framework
-          ${CMAKE_FIND_FRAMEWORK_EXTRA_LOCATIONS})
+      file(TO_CMAKE_PATH "$ENV{CMAKE_FRAMEWORK_PATH}" _cmff_CMAKE_FRAMEWORK_PATH)
+      set(_cmff_search_paths
+            ${CMAKE_FRAMEWORK_PATH}
+            ${_cmff_CMAKE_FRAMEWORK_PATH}
+            ~/Library/Frameworks
+            /usr/local/Frameworks
+            /Library/Frameworks
+            /System/Library/Frameworks
+            /Network/Library/Frameworks
+            ${CMAKE_SYSTEM_FRAMEWORK_PATH})
+
+      # For backwards compatibility reasons,
+      # CMAKE_FIND_FRAMEWORK_EXTRA_LOCATIONS includes ${fwk}.framework
+      list(TRANSFORM _cmff_search_paths APPEND /${fwk}.framework)
+      list(APPEND _cmff_search_paths ${CMAKE_FIND_FRAMEWORK_EXTRA_LOCATIONS})
+
+      list(REMOVE_DUPLICATES _cmff_search_paths)
+
+      foreach(dir IN LISTS _cmff_search_paths)
         if(EXISTS ${dir})
           set(${fwk}_FRAMEWORKS ${${fwk}_FRAMEWORKS} ${dir})
         endif()
diff --git a/Modules/CMakeFortranCompiler.cmake.in b/Modules/CMakeFortranCompiler.cmake.in
index 34f44aa..06ee528 100644
--- a/Modules/CMakeFortranCompiler.cmake.in
+++ b/Modules/CMakeFortranCompiler.cmake.in
@@ -8,6 +8,7 @@
 set(CMAKE_Fortran_SIMULATE_VERSION "@CMAKE_Fortran_SIMULATE_VERSION@")
 @_SET_CMAKE_Fortran_XL_CPP@
 @_SET_CMAKE_Fortran_COMPILER_ARCHITECTURE_ID@
+@_SET_CMAKE_Fortran_COMPILER_SYSROOT@
 @SET_MSVC_Fortran_ARCHITECTURE_ID@
 set(CMAKE_AR "@CMAKE_AR@")
 set(CMAKE_Fortran_COMPILER_AR "@CMAKE_Fortran_COMPILER_AR@")
diff --git a/Modules/CMakeFortranInformation.cmake b/Modules/CMakeFortranInformation.cmake
index e80716b..9a4ce63 100644
--- a/Modules/CMakeFortranInformation.cmake
+++ b/Modules/CMakeFortranInformation.cmake
@@ -193,7 +193,7 @@
   set(CMAKE_Fortran_ARCHIVE_CREATE "<CMAKE_AR> qc <TARGET> <LINK_FLAGS> <OBJECTS>")
 endif()
 if(NOT DEFINED CMAKE_Fortran_ARCHIVE_APPEND)
-  set(CMAKE_Fortran_ARCHIVE_APPEND "<CMAKE_AR> q  <TARGET> <LINK_FLAGS> <OBJECTS>")
+  set(CMAKE_Fortran_ARCHIVE_APPEND "<CMAKE_AR> q <TARGET> <LINK_FLAGS> <OBJECTS>")
 endif()
 if(NOT DEFINED CMAKE_Fortran_ARCHIVE_FINISH)
   set(CMAKE_Fortran_ARCHIVE_FINISH "<CMAKE_RANLIB> <TARGET>")
@@ -209,7 +209,7 @@
 # link a fortran program
 if(NOT CMAKE_Fortran_LINK_EXECUTABLE)
   set(CMAKE_Fortran_LINK_EXECUTABLE
-    "<CMAKE_Fortran_COMPILER> <CMAKE_Fortran_LINK_FLAGS> <LINK_FLAGS> <FLAGS> <OBJECTS>  -o <TARGET> <LINK_LIBRARIES>")
+    "<CMAKE_Fortran_COMPILER> <CMAKE_Fortran_LINK_FLAGS> <LINK_FLAGS> <FLAGS> <OBJECTS> -o <TARGET> <LINK_LIBRARIES>")
 endif()
 
 if(CMAKE_Fortran_STANDARD_LIBRARIES_INIT)
diff --git a/Modules/CMakeGenericSystem.cmake b/Modules/CMakeGenericSystem.cmake
index a773dcd..6f665a6 100644
--- a/Modules/CMakeGenericSystem.cmake
+++ b/Modules/CMakeGenericSystem.cmake
@@ -52,15 +52,9 @@
   if(DEFINED CMAKE_TARGET_MESSAGES)
     set_property(GLOBAL PROPERTY TARGET_MESSAGES ${CMAKE_TARGET_MESSAGES})
   endif()
-  if(CMAKE_GENERATOR MATCHES "Unix Makefiles")
-    set(CMAKE_EXPORT_COMPILE_COMMANDS "$ENV{CMAKE_EXPORT_COMPILE_COMMANDS}"
-      CACHE BOOL "Enable/Disable output of compile commands during generation."
-      )
-    mark_as_advanced(CMAKE_EXPORT_COMPILE_COMMANDS)
-  endif()
 endif()
 
-if(CMAKE_GENERATOR MATCHES "Ninja")
+if(NOT DEFINED CMAKE_EXPORT_COMPILE_COMMANDS AND CMAKE_GENERATOR MATCHES "Ninja|Unix Makefiles")
   set(CMAKE_EXPORT_COMPILE_COMMANDS "$ENV{CMAKE_EXPORT_COMPILE_COMMANDS}"
     CACHE BOOL "Enable/Disable output of compile commands during generation."
     )
diff --git a/Modules/CMakeOBJCInformation.cmake b/Modules/CMakeOBJCInformation.cmake
index 15a3311..b3da82d 100644
--- a/Modules/CMakeOBJCInformation.cmake
+++ b/Modules/CMakeOBJCInformation.cmake
@@ -161,7 +161,7 @@
   set(CMAKE_OBJC_ARCHIVE_CREATE "<CMAKE_AR> qc <TARGET> <LINK_FLAGS> <OBJECTS>")
 endif()
 if(NOT DEFINED CMAKE_OBJC_ARCHIVE_APPEND)
-  set(CMAKE_OBJC_ARCHIVE_APPEND "<CMAKE_AR> q  <TARGET> <LINK_FLAGS> <OBJECTS>")
+  set(CMAKE_OBJC_ARCHIVE_APPEND "<CMAKE_AR> q <TARGET> <LINK_FLAGS> <OBJECTS>")
 endif()
 if(NOT DEFINED CMAKE_OBJC_ARCHIVE_FINISH)
   set(CMAKE_OBJC_ARCHIVE_FINISH "<CMAKE_RANLIB> <TARGET>")
@@ -170,12 +170,12 @@
 # compile an Objective-C file into an object file
 if(NOT CMAKE_OBJC_COMPILE_OBJECT)
   set(CMAKE_OBJC_COMPILE_OBJECT
-    "<CMAKE_OBJC_COMPILER> <DEFINES> <INCLUDES> <FLAGS> -x objective-c -o <OBJECT>   -c <SOURCE>")
+    "<CMAKE_OBJC_COMPILER> <DEFINES> <INCLUDES> <FLAGS> -x objective-c -o <OBJECT> -c <SOURCE>")
 endif()
 
 if(NOT CMAKE_OBJC_LINK_EXECUTABLE)
   set(CMAKE_OBJC_LINK_EXECUTABLE
-    "<CMAKE_OBJC_COMPILER> <FLAGS> <CMAKE_OBJC_LINK_FLAGS> <LINK_FLAGS> <OBJECTS>  -o <TARGET> <LINK_LIBRARIES>")
+    "<CMAKE_OBJC_COMPILER> <FLAGS> <CMAKE_OBJC_LINK_FLAGS> <LINK_FLAGS> <OBJECTS> -o <TARGET> <LINK_LIBRARIES>")
 endif()
 
 if(NOT CMAKE_EXECUTABLE_RUNTIME_OBJC_FLAG)
diff --git a/Modules/CMakeOBJCXXInformation.cmake b/Modules/CMakeOBJCXXInformation.cmake
index cb349d7..71beb7f 100644
--- a/Modules/CMakeOBJCXXInformation.cmake
+++ b/Modules/CMakeOBJCXXInformation.cmake
@@ -254,7 +254,7 @@
   set(CMAKE_OBJCXX_ARCHIVE_CREATE "<CMAKE_AR> qc <TARGET> <LINK_FLAGS> <OBJECTS>")
 endif()
 if(NOT DEFINED CMAKE_OBJCXX_ARCHIVE_APPEND)
-  set(CMAKE_OBJCXX_ARCHIVE_APPEND "<CMAKE_AR> q  <TARGET> <LINK_FLAGS> <OBJECTS>")
+  set(CMAKE_OBJCXX_ARCHIVE_APPEND "<CMAKE_AR> q <TARGET> <LINK_FLAGS> <OBJECTS>")
 endif()
 if(NOT DEFINED CMAKE_OBJCXX_ARCHIVE_FINISH)
   set(CMAKE_OBJCXX_ARCHIVE_FINISH "<CMAKE_RANLIB> <TARGET>")
@@ -263,12 +263,12 @@
 # compile an Objective-C++ file into an object file
 if(NOT CMAKE_OBJCXX_COMPILE_OBJECT)
   set(CMAKE_OBJCXX_COMPILE_OBJECT
-    "<CMAKE_OBJCXX_COMPILER>  <DEFINES> <INCLUDES> <FLAGS> -x objective-c++ -o <OBJECT> -c <SOURCE>")
+    "<CMAKE_OBJCXX_COMPILER> <DEFINES> <INCLUDES> <FLAGS> -x objective-c++ -o <OBJECT> -c <SOURCE>")
 endif()
 
 if(NOT CMAKE_OBJCXX_LINK_EXECUTABLE)
   set(CMAKE_OBJCXX_LINK_EXECUTABLE
-    "<CMAKE_OBJCXX_COMPILER>  <FLAGS> <CMAKE_OBJCXX_LINK_FLAGS> <LINK_FLAGS> <OBJECTS>  -o <TARGET> <LINK_LIBRARIES>")
+    "<CMAKE_OBJCXX_COMPILER> <FLAGS> <CMAKE_OBJCXX_LINK_FLAGS> <LINK_FLAGS> <OBJECTS> -o <TARGET> <LINK_LIBRARIES>")
 endif()
 
 mark_as_advanced(
diff --git a/Modules/CMakeParseImplicitIncludeInfo.cmake b/Modules/CMakeParseImplicitIncludeInfo.cmake
index ff4c325..7cd7548 100644
--- a/Modules/CMakeParseImplicitIncludeInfo.cmake
+++ b/Modules/CMakeParseImplicitIncludeInfo.cmake
@@ -7,7 +7,7 @@
 # for compilers that report them that way.  on success we return the
 # list of dirs in id_var and set state_var to the 'done' state.
 function(cmake_parse_implicit_include_line line lang id_var log_var state_var)
-  # clear variables we append to (avoids possible polution from parent scopes)
+  # clear variables we append to (avoids possible pollution from parent scopes)
   unset(rv)
   set(log "")
 
@@ -162,7 +162,7 @@
 function(cmake_parse_implicit_include_info text lang dir_var log_var state_var)
   set(state start)    # values: start, loading, done
 
-  # clear variables we append to (avoids possible polution from parent scopes)
+  # clear variables we append to (avoids possible pollution from parent scopes)
   set(implicit_dirs_tmp)
   set(log "")
 
diff --git a/Modules/CMakePlatformId.h.in b/Modules/CMakePlatformId.h.in
index 64a00b3..0b81c88 100644
--- a/Modules/CMakePlatformId.h.in
+++ b/Modules/CMakePlatformId.h.in
@@ -87,6 +87,9 @@
 # elif defined(__WINDOWS__)
 #  define PLATFORM_ID "Windows3x"
 
+# elif defined(__VXWORKS__)
+#  define PLATFORM_ID "VxWorks"
+
 # else /* unknown platform */
 #  define PLATFORM_ID
 # endif
@@ -203,6 +206,24 @@
 # else /* unknown architecture */
 #  define ARCHITECTURE_ID ""
 # endif
+
+#elif defined(__TI_COMPILER_VERSION__)
+# if defined(__TI_ARM__)
+#  define ARCHITECTURE_ID "ARM"
+
+# elif defined(__MSP430__)
+#  define ARCHITECTURE_ID "MSP430"
+
+# elif defined(__TMS320C28XX__)
+#  define ARCHITECTURE_ID "TMS320C28x"
+
+# elif defined(__TMS320C6X__) || defined(_TMS320C6X)
+#  define ARCHITECTURE_ID "TMS320C6x"
+
+# else /* unknown architecture */
+#  define ARCHITECTURE_ID ""
+# endif
+
 #else
 #  define ARCHITECTURE_ID
 #endif
@@ -280,4 +301,3 @@
    array rather than assigning a pointer to a static array.  */
 char const* info_platform = "INFO" ":" "platform[" PLATFORM_ID "]";
 char const* info_arch = "INFO" ":" "arch[" ARCHITECTURE_ID "]";
-
diff --git a/Modules/CMakePrintSystemInformation.cmake b/Modules/CMakePrintSystemInformation.cmake
index 8d5cf5c..d44e933 100644
--- a/Modules/CMakePrintSystemInformation.cmake
+++ b/Modules/CMakePrintSystemInformation.cmake
@@ -11,7 +11,7 @@
 project to see various internal CMake variables.
 #]=======================================================================]
 
-message("CMAKE_SYSTEM is ${CMAKE_SYSTEM} ${CMAKE_SYSTEM_NAME} ${CMAKE_SYSTEM_VERSION}")
+message("CMAKE_SYSTEM is ${CMAKE_SYSTEM} ${CMAKE_SYSTEM_NAME} ${CMAKE_SYSTEM_VERSION} ${CMAKE_SYSTEM_PROCESSOR}")
 message("CMAKE_SYSTEM file is ${CMAKE_SYSTEM_INFO_FILE}")
 message("CMAKE_C_COMPILER is ${CMAKE_C_COMPILER}")
 message("CMAKE_CXX_COMPILER is ${CMAKE_CXX_COMPILER}")
diff --git a/Modules/CMakeTestCCompiler.cmake b/Modules/CMakeTestCCompiler.cmake
index eadea89..03f2db2 100644
--- a/Modules/CMakeTestCCompiler.cmake
+++ b/Modules/CMakeTestCCompiler.cmake
@@ -11,7 +11,7 @@
 
 include(CMakeTestCompilerCommon)
 
-# work around enforced code signing and / or missing exectuable target type
+# work around enforced code signing and / or missing executable target type
 set(__CMAKE_SAVED_TRY_COMPILE_TARGET_TYPE ${CMAKE_TRY_COMPILE_TARGET_TYPE})
 if(_CMAKE_FEATURE_DETECTION_TARGET_TYPE)
   set(CMAKE_TRY_COMPILE_TARGET_TYPE ${_CMAKE_FEATURE_DETECTION_TARGET_TYPE})
@@ -21,6 +21,15 @@
 # We now store this in CMakeCCompiler.cmake.
 unset(CMAKE_C_COMPILER_WORKS CACHE)
 
+# Try to identify the ABI and configure it into CMakeCCompiler.cmake
+include(${CMAKE_ROOT}/Modules/CMakeDetermineCompilerABI.cmake)
+CMAKE_DETERMINE_COMPILER_ABI(C ${CMAKE_ROOT}/Modules/CMakeCCompilerABI.c)
+if(CMAKE_C_ABI_COMPILED)
+  # The compiler worked so skip dedicated test below.
+  set(CMAKE_C_COMPILER_WORKS TRUE)
+  message(STATUS "Check for working C compiler: ${CMAKE_C_COMPILER} - skipped")
+endif()
+
 # This file is used by EnableLanguage in cmGlobalGenerator to
 # determine that that selected C compiler can actually compile
 # and link the most basic of programs.   If not, a fatal error
@@ -47,49 +56,41 @@
   # Move result from cache to normal variable.
   set(CMAKE_C_COMPILER_WORKS ${CMAKE_C_COMPILER_WORKS})
   unset(CMAKE_C_COMPILER_WORKS CACHE)
-  set(C_TEST_WAS_RUN 1)
   __TestCompiler_restoreTryCompileTargetType()
+  if(NOT CMAKE_C_COMPILER_WORKS)
+    PrintTestCompilerResult(CHECK_FAIL "broken")
+    file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
+      "Determining if the C compiler works failed with "
+      "the following output:\n${__CMAKE_C_COMPILER_OUTPUT}\n\n")
+    string(REPLACE "\n" "\n  " _output "${__CMAKE_C_COMPILER_OUTPUT}")
+    message(FATAL_ERROR "The C compiler\n  \"${CMAKE_C_COMPILER}\"\n"
+      "is not able to compile a simple test program.\nIt fails "
+      "with the following output:\n  ${_output}\n\n"
+      "CMake will not be able to correctly generate this project.")
+  endif()
+  PrintTestCompilerResult(CHECK_PASS "works")
+  file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
+    "Determining if the C compiler works passed with "
+    "the following output:\n${__CMAKE_C_COMPILER_OUTPUT}\n\n")
 endif()
 
-if(NOT CMAKE_C_COMPILER_WORKS)
-  PrintTestCompilerResult(CHECK_FAIL "broken")
-  file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
-    "Determining if the C compiler works failed with "
-    "the following output:\n${__CMAKE_C_COMPILER_OUTPUT}\n\n")
-  string(REPLACE "\n" "\n  " _output "${__CMAKE_C_COMPILER_OUTPUT}")
-  message(FATAL_ERROR "The C compiler\n  \"${CMAKE_C_COMPILER}\"\n"
-    "is not able to compile a simple test program.\nIt fails "
-    "with the following output:\n  ${_output}\n\n"
-    "CMake will not be able to correctly generate this project.")
-else()
-  if(C_TEST_WAS_RUN)
-    PrintTestCompilerResult(CHECK_PASS "works")
-    file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
-      "Determining if the C compiler works passed with "
-      "the following output:\n${__CMAKE_C_COMPILER_OUTPUT}\n\n")
-  endif()
+# Try to identify the compiler features
+include(${CMAKE_ROOT}/Modules/CMakeDetermineCompileFeatures.cmake)
+CMAKE_DETERMINE_COMPILE_FEATURES(C)
 
-  # Try to identify the ABI and configure it into CMakeCCompiler.cmake
-  include(${CMAKE_ROOT}/Modules/CMakeDetermineCompilerABI.cmake)
-  CMAKE_DETERMINE_COMPILER_ABI(C ${CMAKE_ROOT}/Modules/CMakeCCompilerABI.c)
-  # Try to identify the compiler features
-  include(${CMAKE_ROOT}/Modules/CMakeDetermineCompileFeatures.cmake)
-  CMAKE_DETERMINE_COMPILE_FEATURES(C)
+# Re-configure to save learned information.
+configure_file(
+  ${CMAKE_ROOT}/Modules/CMakeCCompiler.cmake.in
+  ${CMAKE_PLATFORM_INFO_DIR}/CMakeCCompiler.cmake
+  @ONLY
+  )
+include(${CMAKE_PLATFORM_INFO_DIR}/CMakeCCompiler.cmake)
 
-  # Re-configure to save learned information.
-  configure_file(
-    ${CMAKE_ROOT}/Modules/CMakeCCompiler.cmake.in
-    ${CMAKE_PLATFORM_INFO_DIR}/CMakeCCompiler.cmake
-    @ONLY
-    )
-  include(${CMAKE_PLATFORM_INFO_DIR}/CMakeCCompiler.cmake)
-
-  if(CMAKE_C_SIZEOF_DATA_PTR)
-    foreach(f ${CMAKE_C_ABI_FILES})
-      include(${f})
-    endforeach()
-    unset(CMAKE_C_ABI_FILES)
-  endif()
+if(CMAKE_C_SIZEOF_DATA_PTR)
+  foreach(f ${CMAKE_C_ABI_FILES})
+    include(${f})
+  endforeach()
+  unset(CMAKE_C_ABI_FILES)
 endif()
 
 set(CMAKE_TRY_COMPILE_TARGET_TYPE ${__CMAKE_SAVED_TRY_COMPILE_TARGET_TYPE})
diff --git a/Modules/CMakeTestCUDACompiler.cmake b/Modules/CMakeTestCUDACompiler.cmake
index 05811a8..a18947b 100644
--- a/Modules/CMakeTestCUDACompiler.cmake
+++ b/Modules/CMakeTestCUDACompiler.cmake
@@ -14,6 +14,15 @@
 # We now store this in CMakeCUDACompiler.cmake.
 unset(CMAKE_CUDA_COMPILER_WORKS CACHE)
 
+# Try to identify the ABI and configure it into CMakeCUDACompiler.cmake
+include(${CMAKE_ROOT}/Modules/CMakeDetermineCompilerABI.cmake)
+CMAKE_DETERMINE_COMPILER_ABI(CUDA ${CMAKE_ROOT}/Modules/CMakeCUDACompilerABI.cu)
+if(CMAKE_CUDA_ABI_COMPILED)
+  # The compiler worked so skip dedicated test below.
+  set(CMAKE_CUDA_COMPILER_WORKS TRUE)
+  message(STATUS "Check for working CUDA compiler: ${CMAKE_CUDA_COMPILER} - skipped")
+endif()
+
 # This file is used by EnableLanguage in cmGlobalGenerator to
 # determine that the selected cuda compiler can actually compile
 # and link the most basic of programs.   If not, a fatal error
@@ -34,50 +43,37 @@
   # Move result from cache to normal variable.
   set(CMAKE_CUDA_COMPILER_WORKS ${CMAKE_CUDA_COMPILER_WORKS})
   unset(CMAKE_CUDA_COMPILER_WORKS CACHE)
-  set(CUDA_TEST_WAS_RUN 1)
+  if(NOT CMAKE_CUDA_COMPILER_WORKS)
+    PrintTestCompilerResult(CHECK_FAIL "broken")
+    file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
+      "Determining if the CUDA compiler works failed with "
+      "the following output:\n${__CMAKE_CUDA_COMPILER_OUTPUT}\n\n")
+    string(REPLACE "\n" "\n  " _output "${__CMAKE_CUDA_COMPILER_OUTPUT}")
+    message(FATAL_ERROR "The CUDA compiler\n  \"${CMAKE_CUDA_COMPILER}\"\n"
+      "is not able to compile a simple test program.\nIt fails "
+      "with the following output:\n  ${_output}\n\n"
+      "CMake will not be able to correctly generate this project.")
+  endif()
+  PrintTestCompilerResult(CHECK_PASS "works")
+  file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
+    "Determining if the CUDA compiler works passed with "
+    "the following output:\n${__CMAKE_CUDA_COMPILER_OUTPUT}\n\n")
 endif()
 
-if(NOT CMAKE_CUDA_COMPILER_WORKS)
-  PrintTestCompilerResult(CHECK_FAIL "broken")
-  file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
-    "Determining if the CUDA compiler works failed with "
-    "the following output:\n${__CMAKE_CUDA_COMPILER_OUTPUT}\n\n")
-  string(REPLACE "\n" "\n  " _output "${__CMAKE_CUDA_COMPILER_OUTPUT}")
-  message(FATAL_ERROR "The CUDA compiler\n  \"${CMAKE_CUDA_COMPILER}\"\n"
-    "is not able to compile a simple test program.\nIt fails "
-    "with the following output:\n  ${_output}\n\n"
-    "CMake will not be able to correctly generate this project.")
-else()
-  if(CUDA_TEST_WAS_RUN)
-    PrintTestCompilerResult(CHECK_PASS "works")
-    file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
-      "Determining if the CUDA compiler works passed with "
-      "the following output:\n${__CMAKE_CUDA_COMPILER_OUTPUT}\n\n")
-  endif()
+# Try to identify the compiler features
+include(${CMAKE_ROOT}/Modules/CMakeDetermineCompileFeatures.cmake)
+CMAKE_DETERMINE_COMPILE_FEATURES(CUDA)
 
-  # Try to identify the ABI and configure it into CMakeCUDACompiler.cmake
-  include(${CMAKE_ROOT}/Modules/CMakeDetermineCompilerABI.cmake)
-  CMAKE_DETERMINE_COMPILER_ABI(CUDA ${CMAKE_ROOT}/Modules/CMakeCUDACompilerABI.cu)
-  # Try to identify the compiler features
-  include(${CMAKE_ROOT}/Modules/CMakeDetermineCompileFeatures.cmake)
-  CMAKE_DETERMINE_COMPILE_FEATURES(CUDA)
+if("x${CMAKE_CUDA_SIMULATE_ID}" STREQUAL "xMSVC")
+  set(CMAKE_CUDA_IMPLICIT_LINK_LIBRARIES "${CMAKE_CUDA_HOST_IMPLICIT_LINK_LIBRARIES}")
+  set(CMAKE_CUDA_IMPLICIT_LINK_DIRECTORIES "${CMAKE_CUDA_HOST_IMPLICIT_LINK_DIRECTORIES}")
+endif()
 
-  if("x${CMAKE_CUDA_SIMULATE_ID}" STREQUAL "xMSVC")
-    set(CMAKE_CUDA_IMPLICIT_LINK_LIBRARIES "${CMAKE_CUDA_HOST_IMPLICIT_LINK_LIBRARIES}")
-    set(CMAKE_CUDA_IMPLICIT_LINK_DIRECTORIES "${CMAKE_CUDA_HOST_IMPLICIT_LINK_DIRECTORIES}")
-  endif()
+# Filter out implicit link libraries that should not be passed unconditionally.
+# See CMAKE_CUDA_IMPLICIT_LINK_LIBRARIES_EXCLUDE in CMakeDetermineCUDACompiler.
+list(REMOVE_ITEM CMAKE_CUDA_IMPLICIT_LINK_LIBRARIES ${CMAKE_CUDA_IMPLICIT_LINK_LIBRARIES_EXCLUDE})
 
-  # Remove the following libraries from CMAKE_CUDA_HOST_IMPLICIT_LINK_LIBRARIES and
-  # CMAKE_CUDA_IMPLICIT_LINK_LIBRARIES
-  #
-  # - cudart
-  # - cudart_static
-  # - cudadevrt
-  #
-  # These are controlled by CMAKE_CUDA_RUNTIME_LIBRARY
-  list(REMOVE_ITEM CMAKE_CUDA_IMPLICIT_LINK_LIBRARIES cudart cudart_static cudadevrt)
-  list(REMOVE_ITEM CMAKE_CUDA_HOST_IMPLICIT_LINK_LIBRARIES cudart cudart_static cudadevrt)
-
+if(CMAKE_CUDA_COMPILER_ID STREQUAL "NVIDIA")
   # Remove the CUDA Toolkit include directories from the set of
   # implicit system include directories.
   # This resolves the issue that NVCC doesn't specify these
@@ -89,15 +85,14 @@
       ${CMAKE_CUDA_TOOLKIT_INCLUDE_DIRECTORIES}
       )
   endif()
-
-  # Re-configure to save learned information.
-  configure_file(
-    ${CMAKE_ROOT}/Modules/CMakeCUDACompiler.cmake.in
-    ${CMAKE_PLATFORM_INFO_DIR}/CMakeCUDACompiler.cmake
-    @ONLY
-    )
-  include(${CMAKE_PLATFORM_INFO_DIR}/CMakeCUDACompiler.cmake)
 endif()
 
+# Re-configure to save learned information.
+configure_file(
+  ${CMAKE_ROOT}/Modules/CMakeCUDACompiler.cmake.in
+  ${CMAKE_PLATFORM_INFO_DIR}/CMakeCUDACompiler.cmake
+  @ONLY
+  )
+include(${CMAKE_PLATFORM_INFO_DIR}/CMakeCUDACompiler.cmake)
 
 unset(__CMAKE_CUDA_COMPILER_OUTPUT)
diff --git a/Modules/CMakeTestCXXCompiler.cmake b/Modules/CMakeTestCXXCompiler.cmake
index bd42153..0d2d0b0 100644
--- a/Modules/CMakeTestCXXCompiler.cmake
+++ b/Modules/CMakeTestCXXCompiler.cmake
@@ -11,7 +11,7 @@
 
 include(CMakeTestCompilerCommon)
 
-# work around enforced code signing and / or missing exectuable target type
+# work around enforced code signing and / or missing executable target type
 set(__CMAKE_SAVED_TRY_COMPILE_TARGET_TYPE ${CMAKE_TRY_COMPILE_TARGET_TYPE})
 if(_CMAKE_FEATURE_DETECTION_TARGET_TYPE)
   set(CMAKE_TRY_COMPILE_TARGET_TYPE ${_CMAKE_FEATURE_DETECTION_TARGET_TYPE})
@@ -21,6 +21,15 @@
 # We now store this in CMakeCXXCompiler.cmake.
 unset(CMAKE_CXX_COMPILER_WORKS CACHE)
 
+# Try to identify the ABI and configure it into CMakeCXXCompiler.cmake
+include(${CMAKE_ROOT}/Modules/CMakeDetermineCompilerABI.cmake)
+CMAKE_DETERMINE_COMPILER_ABI(CXX ${CMAKE_ROOT}/Modules/CMakeCXXCompilerABI.cpp)
+if(CMAKE_CXX_ABI_COMPILED)
+  # The compiler worked so skip dedicated test below.
+  set(CMAKE_CXX_COMPILER_WORKS TRUE)
+  message(STATUS "Check for working CXX compiler: ${CMAKE_CXX_COMPILER} - skipped")
+endif()
+
 # This file is used by EnableLanguage in cmGlobalGenerator to
 # determine that the selected C++ compiler can actually compile
 # and link the most basic of programs.   If not, a fatal error
@@ -40,49 +49,41 @@
   # Move result from cache to normal variable.
   set(CMAKE_CXX_COMPILER_WORKS ${CMAKE_CXX_COMPILER_WORKS})
   unset(CMAKE_CXX_COMPILER_WORKS CACHE)
-  set(CXX_TEST_WAS_RUN 1)
   __TestCompiler_restoreTryCompileTargetType()
+  if(NOT CMAKE_CXX_COMPILER_WORKS)
+    PrintTestCompilerResult(CHECK_FAIL "broken")
+    file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
+      "Determining if the CXX compiler works failed with "
+      "the following output:\n${__CMAKE_CXX_COMPILER_OUTPUT}\n\n")
+    string(REPLACE "\n" "\n  " _output "${__CMAKE_CXX_COMPILER_OUTPUT}")
+    message(FATAL_ERROR "The C++ compiler\n  \"${CMAKE_CXX_COMPILER}\"\n"
+      "is not able to compile a simple test program.\nIt fails "
+      "with the following output:\n  ${_output}\n\n"
+      "CMake will not be able to correctly generate this project.")
+  endif()
+  PrintTestCompilerResult(CHECK_PASS "works")
+  file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
+    "Determining if the CXX compiler works passed with "
+    "the following output:\n${__CMAKE_CXX_COMPILER_OUTPUT}\n\n")
 endif()
 
-if(NOT CMAKE_CXX_COMPILER_WORKS)
-  PrintTestCompilerResult(CHECK_FAIL "broken")
-  file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
-    "Determining if the CXX compiler works failed with "
-    "the following output:\n${__CMAKE_CXX_COMPILER_OUTPUT}\n\n")
-  string(REPLACE "\n" "\n  " _output "${__CMAKE_CXX_COMPILER_OUTPUT}")
-  message(FATAL_ERROR "The C++ compiler\n  \"${CMAKE_CXX_COMPILER}\"\n"
-    "is not able to compile a simple test program.\nIt fails "
-    "with the following output:\n  ${_output}\n\n"
-    "CMake will not be able to correctly generate this project.")
-else()
-  if(CXX_TEST_WAS_RUN)
-    PrintTestCompilerResult(CHECK_PASS "works")
-    file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
-      "Determining if the CXX compiler works passed with "
-      "the following output:\n${__CMAKE_CXX_COMPILER_OUTPUT}\n\n")
-  endif()
+# Try to identify the compiler features
+include(${CMAKE_ROOT}/Modules/CMakeDetermineCompileFeatures.cmake)
+CMAKE_DETERMINE_COMPILE_FEATURES(CXX)
 
-  # Try to identify the ABI and configure it into CMakeCXXCompiler.cmake
-  include(${CMAKE_ROOT}/Modules/CMakeDetermineCompilerABI.cmake)
-  CMAKE_DETERMINE_COMPILER_ABI(CXX ${CMAKE_ROOT}/Modules/CMakeCXXCompilerABI.cpp)
-  # Try to identify the compiler features
-  include(${CMAKE_ROOT}/Modules/CMakeDetermineCompileFeatures.cmake)
-  CMAKE_DETERMINE_COMPILE_FEATURES(CXX)
+# Re-configure to save learned information.
+configure_file(
+  ${CMAKE_ROOT}/Modules/CMakeCXXCompiler.cmake.in
+  ${CMAKE_PLATFORM_INFO_DIR}/CMakeCXXCompiler.cmake
+  @ONLY
+  )
+include(${CMAKE_PLATFORM_INFO_DIR}/CMakeCXXCompiler.cmake)
 
-  # Re-configure to save learned information.
-  configure_file(
-    ${CMAKE_ROOT}/Modules/CMakeCXXCompiler.cmake.in
-    ${CMAKE_PLATFORM_INFO_DIR}/CMakeCXXCompiler.cmake
-    @ONLY
-    )
-  include(${CMAKE_PLATFORM_INFO_DIR}/CMakeCXXCompiler.cmake)
-
-  if(CMAKE_CXX_SIZEOF_DATA_PTR)
-    foreach(f ${CMAKE_CXX_ABI_FILES})
-      include(${f})
-    endforeach()
-    unset(CMAKE_CXX_ABI_FILES)
-  endif()
+if(CMAKE_CXX_SIZEOF_DATA_PTR)
+  foreach(f ${CMAKE_CXX_ABI_FILES})
+    include(${f})
+  endforeach()
+  unset(CMAKE_CXX_ABI_FILES)
 endif()
 
 set(CMAKE_TRY_COMPILE_TARGET_TYPE ${__CMAKE_SAVED_TRY_COMPILE_TARGET_TYPE})
diff --git a/Modules/CMakeTestFortranCompiler.cmake b/Modules/CMakeTestFortranCompiler.cmake
index 7461f9c..10fb0a7 100644
--- a/Modules/CMakeTestFortranCompiler.cmake
+++ b/Modules/CMakeTestFortranCompiler.cmake
@@ -15,6 +15,15 @@
 # We now store this in CMakeFortranCompiler.cmake.
 unset(CMAKE_Fortran_COMPILER_WORKS CACHE)
 
+# Try to identify the ABI and configure it into CMakeFortranCompiler.cmake
+include(${CMAKE_ROOT}/Modules/CMakeDetermineCompilerABI.cmake)
+CMAKE_DETERMINE_COMPILER_ABI(Fortran ${CMAKE_ROOT}/Modules/CMakeFortranCompilerABI.F)
+if(CMAKE_Fortran_ABI_COMPILED)
+  # The compiler worked so skip dedicated test below.
+  set(CMAKE_Fortran_COMPILER_WORKS TRUE)
+  message(STATUS "Check for working Fortran compiler: ${CMAKE_Fortran_COMPILER} - skipped")
+endif()
+
 # This file is used by EnableLanguage in cmGlobalGenerator to
 # determine that the selected Fortran compiler can actually compile
 # and link the most basic of programs.   If not, a fatal error
@@ -33,70 +42,61 @@
   # Move result from cache to normal variable.
   set(CMAKE_Fortran_COMPILER_WORKS ${CMAKE_Fortran_COMPILER_WORKS})
   unset(CMAKE_Fortran_COMPILER_WORKS CACHE)
-  set(FORTRAN_TEST_WAS_RUN 1)
+  if(NOT CMAKE_Fortran_COMPILER_WORKS)
+    PrintTestCompilerResult(CHECK_FAIL "broken")
+    file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
+      "Determining if the Fortran compiler works failed with "
+      "the following output:\n${OUTPUT}\n\n")
+    string(REPLACE "\n" "\n  " _output "${OUTPUT}")
+    message(FATAL_ERROR "The Fortran compiler\n  \"${CMAKE_Fortran_COMPILER}\"\n"
+      "is not able to compile a simple test program.\nIt fails "
+      "with the following output:\n  ${_output}\n\n"
+      "CMake will not be able to correctly generate this project.")
+  endif()
+  PrintTestCompilerResult(CHECK_PASS "works")
+  file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
+    "Determining if the Fortran compiler works passed with "
+    "the following output:\n${OUTPUT}\n\n")
 endif()
 
-if(NOT CMAKE_Fortran_COMPILER_WORKS)
-  PrintTestCompilerResult(CHECK_FAIL "broken")
-  file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
-    "Determining if the Fortran compiler works failed with "
-    "the following output:\n${OUTPUT}\n\n")
-  string(REPLACE "\n" "\n  " _output "${OUTPUT}")
-  message(FATAL_ERROR "The Fortran compiler\n  \"${CMAKE_Fortran_COMPILER}\"\n"
-    "is not able to compile a simple test program.\nIt fails "
-    "with the following output:\n  ${_output}\n\n"
-    "CMake will not be able to correctly generate this project.")
-else()
-  if(FORTRAN_TEST_WAS_RUN)
-    PrintTestCompilerResult(CHECK_PASS "works")
-    file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
-      "Determining if the Fortran compiler works passed with "
-      "the following output:\n${OUTPUT}\n\n")
-  endif()
-
-  # Try to identify the ABI and configure it into CMakeFortranCompiler.cmake
-  include(${CMAKE_ROOT}/Modules/CMakeDetermineCompilerABI.cmake)
-  CMAKE_DETERMINE_COMPILER_ABI(Fortran ${CMAKE_ROOT}/Modules/CMakeFortranCompilerABI.F)
-
-  # Test for Fortran 90 support by using an f90-specific construct.
-  if(NOT DEFINED CMAKE_Fortran_COMPILER_SUPPORTS_F90)
-    message(CHECK_START "Checking whether ${CMAKE_Fortran_COMPILER} supports Fortran 90")
-    file(WRITE ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/testFortranCompilerF90.f90 "
-      PROGRAM TESTFortran90
-      integer stop ; stop = 1 ; do while ( stop .eq. 0 ) ; end do
-      END PROGRAM TESTFortran90
+# Test for Fortran 90 support by using an f90-specific construct.
+if(NOT DEFINED CMAKE_Fortran_COMPILER_SUPPORTS_F90)
+  message(CHECK_START "Checking whether ${CMAKE_Fortran_COMPILER} supports Fortran 90")
+  file(WRITE ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/testFortranCompilerF90.f90 "
+    PROGRAM TESTFortran90
+    integer stop ; stop = 1 ; do while ( stop .eq. 0 ) ; end do
+    END PROGRAM TESTFortran90
 ")
-    try_compile(CMAKE_Fortran_COMPILER_SUPPORTS_F90 ${CMAKE_BINARY_DIR}
-      ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/testFortranCompilerF90.f90
-      OUTPUT_VARIABLE OUTPUT)
-    if(CMAKE_Fortran_COMPILER_SUPPORTS_F90)
-      message(CHECK_PASS "yes")
-      file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
-        "Determining if the Fortran compiler supports Fortran 90 passed with "
-        "the following output:\n${OUTPUT}\n\n")
-      set(CMAKE_Fortran_COMPILER_SUPPORTS_F90 1)
-    else()
-      message(CHECK_FAIL "no")
-      file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
-        "Determining if the Fortran compiler supports Fortran 90 failed with "
-        "the following output:\n${OUTPUT}\n\n")
-      set(CMAKE_Fortran_COMPILER_SUPPORTS_F90 0)
-    endif()
-    unset(CMAKE_Fortran_COMPILER_SUPPORTS_F90 CACHE)
+  try_compile(CMAKE_Fortran_COMPILER_SUPPORTS_F90 ${CMAKE_BINARY_DIR}
+    ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/testFortranCompilerF90.f90
+    OUTPUT_VARIABLE OUTPUT)
+  if(CMAKE_Fortran_COMPILER_SUPPORTS_F90)
+    message(CHECK_PASS "yes")
+    file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
+      "Determining if the Fortran compiler supports Fortran 90 passed with "
+      "the following output:\n${OUTPUT}\n\n")
+    set(CMAKE_Fortran_COMPILER_SUPPORTS_F90 1)
+  else()
+    message(CHECK_FAIL "no")
+    file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
+      "Determining if the Fortran compiler supports Fortran 90 failed with "
+      "the following output:\n${OUTPUT}\n\n")
+    set(CMAKE_Fortran_COMPILER_SUPPORTS_F90 0)
   endif()
+  unset(CMAKE_Fortran_COMPILER_SUPPORTS_F90 CACHE)
+endif()
 
-  # Re-configure to save learned information.
-  configure_file(
-    ${CMAKE_ROOT}/Modules/CMakeFortranCompiler.cmake.in
-    ${CMAKE_PLATFORM_INFO_DIR}/CMakeFortranCompiler.cmake
-    @ONLY
-    )
-  include(${CMAKE_PLATFORM_INFO_DIR}/CMakeFortranCompiler.cmake)
+# Re-configure to save learned information.
+configure_file(
+  ${CMAKE_ROOT}/Modules/CMakeFortranCompiler.cmake.in
+  ${CMAKE_PLATFORM_INFO_DIR}/CMakeFortranCompiler.cmake
+  @ONLY
+  )
+include(${CMAKE_PLATFORM_INFO_DIR}/CMakeFortranCompiler.cmake)
 
-  if(CMAKE_Fortran_SIZEOF_DATA_PTR)
-    foreach(f ${CMAKE_Fortran_ABI_FILES})
-      include(${f})
-    endforeach()
-    unset(CMAKE_Fortran_ABI_FILES)
-  endif()
+if(CMAKE_Fortran_SIZEOF_DATA_PTR)
+  foreach(f ${CMAKE_Fortran_ABI_FILES})
+    include(${f})
+  endforeach()
+  unset(CMAKE_Fortran_ABI_FILES)
 endif()
diff --git a/Modules/CMakeTestOBJCCompiler.cmake b/Modules/CMakeTestOBJCCompiler.cmake
index bcc6fae..298272b 100644
--- a/Modules/CMakeTestOBJCCompiler.cmake
+++ b/Modules/CMakeTestOBJCCompiler.cmake
@@ -11,7 +11,7 @@
 
 include(CMakeTestCompilerCommon)
 
-# work around enforced code signing and / or missing exectuable target type
+# work around enforced code signing and / or missing executable target type
 set(__CMAKE_SAVED_TRY_COMPILE_TARGET_TYPE ${CMAKE_TRY_COMPILE_TARGET_TYPE})
 if(_CMAKE_FEATURE_DETECTION_TARGET_TYPE)
   set(CMAKE_TRY_COMPILE_TARGET_TYPE ${_CMAKE_FEATURE_DETECTION_TARGET_TYPE})
@@ -21,6 +21,15 @@
 # We now store this in CMakeCCompiler.cmake.
 unset(CMAKE_OBJC_COMPILER_WORKS CACHE)
 
+# Try to identify the ABI and configure it into CMakeOBJCCompiler.cmake
+include(${CMAKE_ROOT}/Modules/CMakeDetermineCompilerABI.cmake)
+CMAKE_DETERMINE_COMPILER_ABI(OBJC ${CMAKE_ROOT}/Modules/CMakeOBJCCompilerABI.m)
+if(CMAKE_OBJC_ABI_COMPILED)
+  # The compiler worked so skip dedicated test below.
+  set(CMAKE_OBJC_COMPILER_WORKS TRUE)
+  message(STATUS "Check for working OBJC compiler: ${CMAKE_OBJC_COMPILER} - skipped")
+endif()
+
 # This file is used by EnableLanguage in cmGlobalGenerator to
 # determine that that selected Objective-C compiler can actually compile
 # and link the most basic of programs.   If not, a fatal error
@@ -44,49 +53,41 @@
   # Move result from cache to normal variable.
   set(CMAKE_OBJC_COMPILER_WORKS ${CMAKE_OBJC_COMPILER_WORKS})
   unset(CMAKE_OBJC_COMPILER_WORKS CACHE)
-  set(OBJC_TEST_WAS_RUN 1)
   __TestCompiler_restoreTryCompileTargetType()
+  if(NOT CMAKE_OBJC_COMPILER_WORKS)
+    PrintTestCompilerResult(CHECK_FAIL "broken")
+    file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
+      "Determining if the Objective-C compiler works failed with "
+      "the following output:\n${__CMAKE_OBJC_COMPILER_OUTPUT}\n\n")
+    string(REPLACE "\n" "\n  " _output "${__CMAKE_OBJC_COMPILER_OUTPUT}")
+    message(FATAL_ERROR "The Objective-C compiler\n  \"${CMAKE_OBJC_COMPILER}\"\n"
+      "is not able to compile a simple test program.\nIt fails "
+      "with the following output:\n  ${_output}\n\n"
+      "CMake will not be able to correctly generate this project.")
+  endif()
+  PrintTestCompilerResult(CHECK_PASS "works")
+  file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
+    "Determining if the Objective-C compiler works passed with "
+    "the following output:\n${__CMAKE_OBJC_COMPILER_OUTPUT}\n\n")
 endif()
 
-if(NOT CMAKE_OBJC_COMPILER_WORKS)
-  PrintTestCompilerResult(CHECK_FAIL "broken")
-  file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
-    "Determining if the Objective-C compiler works failed with "
-    "the following output:\n${__CMAKE_OBJC_COMPILER_OUTPUT}\n\n")
-  string(REPLACE "\n" "\n  " _output "${__CMAKE_OBJC_COMPILER_OUTPUT}")
-  message(FATAL_ERROR "The Objective-C compiler\n  \"${CMAKE_OBJC_COMPILER}\"\n"
-    "is not able to compile a simple test program.\nIt fails "
-    "with the following output:\n  ${_output}\n\n"
-    "CMake will not be able to correctly generate this project.")
-else()
-  if(OBJC_TEST_WAS_RUN)
-    PrintTestCompilerResult(CHECK_PASS "works")
-    file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
-      "Determining if the Objective-C compiler works passed with "
-      "the following output:\n${__CMAKE_OBJC_COMPILER_OUTPUT}\n\n")
-  endif()
+# Try to identify the compiler features
+include(${CMAKE_ROOT}/Modules/CMakeDetermineCompileFeatures.cmake)
+CMAKE_DETERMINE_COMPILE_FEATURES(OBJC)
 
-  # Try to identify the ABI and configure it into CMakeOBJCCompiler.cmake
-  include(${CMAKE_ROOT}/Modules/CMakeDetermineCompilerABI.cmake)
-  CMAKE_DETERMINE_COMPILER_ABI(OBJC ${CMAKE_ROOT}/Modules/CMakeOBJCCompilerABI.m)
-  # Try to identify the compiler features
-  include(${CMAKE_ROOT}/Modules/CMakeDetermineCompileFeatures.cmake)
-  CMAKE_DETERMINE_COMPILE_FEATURES(OBJC)
+# Re-configure to save learned information.
+configure_file(
+  ${CMAKE_ROOT}/Modules/CMakeOBJCCompiler.cmake.in
+  ${CMAKE_PLATFORM_INFO_DIR}/CMakeOBJCCompiler.cmake
+  @ONLY
+  )
+include(${CMAKE_PLATFORM_INFO_DIR}/CMakeOBJCCompiler.cmake)
 
-  # Re-configure to save learned information.
-  configure_file(
-    ${CMAKE_ROOT}/Modules/CMakeOBJCCompiler.cmake.in
-    ${CMAKE_PLATFORM_INFO_DIR}/CMakeOBJCCompiler.cmake
-    @ONLY
-    )
-  include(${CMAKE_PLATFORM_INFO_DIR}/CMakeOBJCCompiler.cmake)
-
-  if(CMAKE_OBJC_SIZEOF_DATA_PTR)
-    foreach(f ${CMAKE_OBJC_ABI_FILES})
-      include(${f})
-    endforeach()
-    unset(CMAKE_OBJC_ABI_FILES)
-  endif()
+if(CMAKE_OBJC_SIZEOF_DATA_PTR)
+  foreach(f ${CMAKE_OBJC_ABI_FILES})
+    include(${f})
+  endforeach()
+  unset(CMAKE_OBJC_ABI_FILES)
 endif()
 
 set(CMAKE_TRY_COMPILE_TARGET_TYPE ${__CMAKE_SAVED_TRY_COMPILE_TARGET_TYPE})
diff --git a/Modules/CMakeTestOBJCXXCompiler.cmake b/Modules/CMakeTestOBJCXXCompiler.cmake
index 83227d5..36e3efc 100644
--- a/Modules/CMakeTestOBJCXXCompiler.cmake
+++ b/Modules/CMakeTestOBJCXXCompiler.cmake
@@ -11,7 +11,7 @@
 
 include(CMakeTestCompilerCommon)
 
-# work around enforced code signing and / or missing exectuable target type
+# work around enforced code signing and / or missing executable target type
 set(__CMAKE_SAVED_TRY_COMPILE_TARGET_TYPE ${CMAKE_TRY_COMPILE_TARGET_TYPE})
 if(_CMAKE_FEATURE_DETECTION_TARGET_TYPE)
   set(CMAKE_TRY_COMPILE_TARGET_TYPE ${_CMAKE_FEATURE_DETECTION_TARGET_TYPE})
@@ -21,6 +21,15 @@
 # We now store this in CMakeOBJCXXCompiler.cmake.
 unset(CMAKE_OBJCXX_COMPILER_WORKS CACHE)
 
+# Try to identify the ABI and configure it into CMakeOBJCXXCompiler.cmake
+include(${CMAKE_ROOT}/Modules/CMakeDetermineCompilerABI.cmake)
+CMAKE_DETERMINE_COMPILER_ABI(OBJCXX ${CMAKE_ROOT}/Modules/CMakeOBJCXXCompilerABI.mm)
+if(CMAKE_OBJCXX_ABI_COMPILED)
+  # The compiler worked so skip dedicated test below.
+  set(CMAKE_OBJCXX_COMPILER_WORKS TRUE)
+  message(STATUS "Check for working OBJCXX compiler: ${CMAKE_OBJCXX_COMPILER} - skipped")
+endif()
+
 # This file is used by EnableLanguage in cmGlobalGenerator to
 # determine that the selected Objective-C++ compiler can actually compile
 # and link the most basic of programs.   If not, a fatal error
@@ -43,49 +52,41 @@
   # Move result from cache to normal variable.
   set(CMAKE_OBJCXX_COMPILER_WORKS ${CMAKE_OBJCXX_COMPILER_WORKS})
   unset(CMAKE_OBJCXX_COMPILER_WORKS CACHE)
-  set(OBJCXX_TEST_WAS_RUN 1)
   __TestCompiler_restoreTryCompileTargetType()
+  if(NOT CMAKE_OBJCXX_COMPILER_WORKS)
+    PrintTestCompilerResult(CHECK_FAIL "broken")
+    file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
+      "Determining if the Objective-C++ compiler works failed with "
+      "the following output:\n${__CMAKE_OBJCXX_COMPILER_OUTPUT}\n\n")
+    string(REPLACE "\n" "\n  " _output "${__CMAKE_OBJCXX_COMPILER_OUTPUT}")
+    message(FATAL_ERROR "The Objective-C++ compiler\n  \"${CMAKE_OBJCXX_COMPILER}\"\n"
+      "is not able to compile a simple test program.\nIt fails "
+      "with the following output:\n  ${_output}\n\n"
+      "CMake will not be able to correctly generate this project.")
+  endif()
+  PrintTestCompilerResult(CHECK_PASS "works")
+  file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
+    "Determining if the Objective-C++ compiler works passed with "
+    "the following output:\n${__CMAKE_OBJCXX_COMPILER_OUTPUT}\n\n")
 endif()
 
-if(NOT CMAKE_OBJCXX_COMPILER_WORKS)
-  PrintTestCompilerResult(CHECK_FAIL "broken")
-  file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
-    "Determining if the Objective-C++ compiler works failed with "
-    "the following output:\n${__CMAKE_OBJCXX_COMPILER_OUTPUT}\n\n")
-  string(REPLACE "\n" "\n  " _output "${__CMAKE_OBJCXX_COMPILER_OUTPUT}")
-  message(FATAL_ERROR "The Objective-C++ compiler\n  \"${CMAKE_OBJCXX_COMPILER}\"\n"
-    "is not able to compile a simple test program.\nIt fails "
-    "with the following output:\n  ${_output}\n\n"
-    "CMake will not be able to correctly generate this project.")
-else()
-  if(OBJCXX_TEST_WAS_RUN)
-    PrintTestCompilerResult(CHECK_PASS "works")
-    file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
-      "Determining if the Objective-C++ compiler works passed with "
-      "the following output:\n${__CMAKE_OBJCXX_COMPILER_OUTPUT}\n\n")
-  endif()
+# Try to identify the compiler features
+include(${CMAKE_ROOT}/Modules/CMakeDetermineCompileFeatures.cmake)
+CMAKE_DETERMINE_COMPILE_FEATURES(OBJCXX)
 
-  # Try to identify the ABI and configure it into CMakeOBJCXXCompiler.cmake
-  include(${CMAKE_ROOT}/Modules/CMakeDetermineCompilerABI.cmake)
-  CMAKE_DETERMINE_COMPILER_ABI(OBJCXX ${CMAKE_ROOT}/Modules/CMakeOBJCXXCompilerABI.mm)
-  # Try to identify the compiler features
-  include(${CMAKE_ROOT}/Modules/CMakeDetermineCompileFeatures.cmake)
-  CMAKE_DETERMINE_COMPILE_FEATURES(OBJCXX)
+# Re-configure to save learned information.
+configure_file(
+  ${CMAKE_ROOT}/Modules/CMakeOBJCXXCompiler.cmake.in
+  ${CMAKE_PLATFORM_INFO_DIR}/CMakeOBJCXXCompiler.cmake
+  @ONLY
+  )
+include(${CMAKE_PLATFORM_INFO_DIR}/CMakeOBJCXXCompiler.cmake)
 
-  # Re-configure to save learned information.
-  configure_file(
-    ${CMAKE_ROOT}/Modules/CMakeOBJCXXCompiler.cmake.in
-    ${CMAKE_PLATFORM_INFO_DIR}/CMakeOBJCXXCompiler.cmake
-    @ONLY
-    )
-  include(${CMAKE_PLATFORM_INFO_DIR}/CMakeOBJCXXCompiler.cmake)
-
-  if(CMAKE_OBJCXX_SIZEOF_DATA_PTR)
-    foreach(f ${CMAKE_OBJCXX_ABI_FILES})
-      include(${f})
-    endforeach()
-    unset(CMAKE_OBJCXX_ABI_FILES)
-  endif()
+if(CMAKE_OBJCXX_SIZEOF_DATA_PTR)
+  foreach(f ${CMAKE_OBJCXX_ABI_FILES})
+    include(${f})
+  endforeach()
+  unset(CMAKE_OBJCXX_ABI_FILES)
 endif()
 
 set(CMAKE_TRY_COMPILE_TARGET_TYPE ${__CMAKE_SAVED_TRY_COMPILE_TARGET_TYPE})
diff --git a/Modules/CPack.cmake b/Modules/CPack.cmake
index baf7e47..8a0ef30 100644
--- a/Modules/CPack.cmake
+++ b/Modules/CPack.cmake
@@ -5,7 +5,7 @@
 CPack
 -----
 
-Configure the binary and source package installers.
+Configure generators for binary installers and source packages.
 
 Introduction
 ^^^^^^^^^^^^
@@ -19,13 +19,21 @@
 targets, ``package`` and ``package_source``. See the `packaging targets`_
 section below for details.
 
-The generated binary installers contain everything installed via CMake's
-:command:`install` command (and the deprecated commands :command:`install_files`,
-:command:`install_programs`, and :command:`install_targets`).
-For certain kinds of binary installers (including the graphical
-installers on macOS and Windows), CPack generates installers that
-allow users to select individual application components to install.
-See :module:`CPackComponent` module for further details.
+The generated binary installers will contain all files that have been installed
+via CMake's :command:`install` command (and the deprecated commands
+:command:`install_files`, :command:`install_programs`, and
+:command:`install_targets`). Note that the ``DESTINATION`` option of the
+:command:`install` command must be a relative path; otherwise installed files
+are ignored by CPack.
+
+Certain kinds of binary installers can be configured such that users can select
+individual application components to install.  See the :module:`CPackComponent`
+module for further details.
+
+Source packages (configured through ``CPackSourceConfig.cmake`` and generated
+by the :cpack_gen:`CPack Archive Generator`) will contain all source files in
+the project directory except those specified in
+:variable:`CPACK_SOURCE_IGNORE_FILES`.
 
 CPack Generators
 ^^^^^^^^^^^^^^^^
@@ -38,10 +46,6 @@
 :variable:`CPACK_GENERATOR` is a *string naming a single generator*.  If you
 need per-cpack-generator logic to control *other* cpack settings, then you
 need a :variable:`CPACK_PROJECT_CONFIG_FILE`.
-
-The CMake source tree itself contains a :variable:`CPACK_PROJECT_CONFIG_FILE`.
-See the top level file ``CMakeCPackOptions.cmake.in`` for an example.
-
 If set, the :variable:`CPACK_PROJECT_CONFIG_FILE` is included automatically
 on a per-generator basis.  It only need contain overrides.
 
@@ -79,7 +83,7 @@
 
 If CMake is run with the Makefile or Ninja generator, then ``include(CPack)``
 also generates a target ``package_source``. To build a source package,
-instead of ``cpack -G TGZ --config CPackConfig.cmake`` one may call
+instead of ``cpack -G TGZ --config CPackSourceConfig.cmake`` one may call
 ``cmake --build . --target package_source``, ``make package_source``,
 or ``ninja package_source``.
 
@@ -386,6 +390,21 @@
   select the CPack generator(s) to be used when building the ``package``
   target or when running :manual:`cpack <cpack(1)>` without the ``-G`` option.
 
+.. variable:: CPACK_PRE_BUILD_SCRIPTS
+
+  List of CMake scripts to execute after CPack has installed the files to
+  be packed into a staging directory and before producing the result
+  packages.
+
+.. variable:: CPACK_POST_BUILD_SCRIPTS
+
+  List of CMake scripts to execute after CPack has produced the result
+  packages and before copying them back to a build directory.
+
+.. variable:: CPACK_PACKAGE_FILES
+
+  List of resulting package files passed to the ``CPACK_POST_BUILD_SCRIPTS``.
+
 #]=======================================================================]
 
 # Define this var in order to avoid (or warn) concerning multiple inclusion
@@ -420,7 +439,7 @@
 # find any variable that starts with CPACK and create a variable
 # _CPACK_OTHER_VARIABLES_ that contains SET commands for
 # each cpack variable.  _CPACK_OTHER_VARIABLES_ is then
-# used as an @ replacment in configure_file for the CPackConfig.
+# used as an @ replacement in configure_file for the CPackConfig.
 function(cpack_encode_variables)
   set(commands "")
   get_cmake_property(res VARIABLES)
diff --git a/Modules/CPackComponent.cmake b/Modules/CPackComponent.cmake
index 211d767..1f8c38c 100644
--- a/Modules/CPackComponent.cmake
+++ b/Modules/CPackComponent.cmake
@@ -5,29 +5,34 @@
 CPackComponent
 --------------
 
-Build binary and source package installers
+Configure components for binary installers and source packages.
 
-Variables concerning CPack Components
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+.. only:: html
 
-The CPackComponent module is the module which handles the component
-part of CPack.  See CPack module for general information about CPack.
+  .. contents::
 
-For certain kinds of binary installers (including the graphical
-installers on macOS and Windows), CPack generates installers that
-allow users to select individual application components to install.
-The contents of each of the components are identified by the COMPONENT
-argument of CMake's INSTALL command.  These components can be
+Introduction
+^^^^^^^^^^^^
+
+This module is automatically included by :module:`CPack`.
+
+Certain binary installers (especially the graphical installers) generated
+by CPack allow users to select individual application *components* to install.
+This module allows developers to configure the packaging of such components.
+
+Contents is assigned to components by the ``COMPONENT``
+argument of CMake's :command:`install` command.  Components can be
 annotated with user-friendly names and descriptions, inter-component
 dependencies, etc., and grouped in various ways to customize the
-resulting installer.  See the cpack_add_* commands, described below,
-for more information about component-specific installations.
+resulting installer, using the commands described below.
 
-Component-specific installation allows users to select specific sets
-of components to install during the install process.  Installation
-components are identified by the COMPONENT argument of CMake's INSTALL
-commands, and should be further described by the following CPack
-commands:
+To specify different groupings for different CPack generators use
+a CPACK_PROJECT_CONFIG_FILE.
+
+Variables
+^^^^^^^^^
+
+The following variables influence the component-specific packaging:
 
 .. variable:: CPACK_COMPONENTS_ALL
 
@@ -61,16 +66,14 @@
  Specify how components are grouped for multi-package component-aware CPack
  generators.
 
- Some generators like RPM or ARCHIVE family (TGZ, ZIP, ...) generates
- several packages files when asked for component packaging.  They group
- the component differently depending on the value of this variable:
+ Some generators like RPM or ARCHIVE (TGZ, ZIP, ...) may generate
+ several packages files when there are components, depending
+ on the value of this variable:
 
- * ONE_PER_GROUP (default): creates one package file per component group
- * ALL_COMPONENTS_IN_ONE : creates a single package with all (requested) components
- * IGNORE : creates one package per component, i.e. IGNORE component group
-
- One can specify different grouping for different CPack generator by
- using a CPACK_PROJECT_CONFIG_FILE.
+ * ONE_PER_GROUP (default): create one package per component group
+ * IGNORE : create one package per component (ignore the groups)
+ * ALL_COMPONENTS_IN_ONE : create a single package with all requested
+   components
 
 .. variable:: CPACK_COMPONENT_<compName>_DISPLAY_NAME
 
@@ -100,10 +103,15 @@
 
  True if this component is not selected to be installed by default.
 
+Commands
+^^^^^^^^
+
+Add component
+"""""""""""""
+
 .. command:: cpack_add_component
 
-Describes a CPack installation
-component named by the COMPONENT argument to a CMake INSTALL command.
+Describe an installation component.
 
 ::
 
@@ -118,13 +126,11 @@
                       [ARCHIVE_FILE filename]
                       [PLIST filename])
 
-
-
-The cmake_add_component command describes an installation component,
-which the user can opt to install or remove as part of the graphical
-installation process.  compname is the name of the component, as
-provided to the COMPONENT argument of one or more CMake INSTALL
-commands.
+``compname`` is the name of an installation component, as defined by the
+``COMPONENT`` argument of one or more CMake :command:`install` commands.
+With the ``cpack_add_component`` command one can set a name, a description,
+and other attributes of an installation component.
+One can also assign a component to a component group.
 
 DISPLAY_NAME is the displayed name of the component, used in graphical
 installers to display the component name.  This value can be any
@@ -177,6 +183,9 @@
 PLIST gives a filename that is passed to pkgbuild with the
 ``--component-plist`` argument when using the productbuild generator.
 
+Add component group
+"""""""""""""""""""
+
 .. command:: cpack_add_component_group
 
 Describes a group of related CPack installation components.
@@ -225,6 +234,9 @@
 BOLD_TITLE indicates that the group title should appear in bold, to
 call the user's attention to the group.
 
+Add installation type
+"""""""""""""""""""""
+
 .. command:: cpack_add_install_type
 
 Add a new installation type containing
@@ -249,6 +261,9 @@
 typically show up in a drop-down box within a graphical installer.
 This value can be any string.
 
+Configure downloads
+"""""""""""""""""""
+
 .. command:: cpack_configure_downloads
 
 Configure CPack to download
@@ -281,8 +296,6 @@
 
   http://nsis.sourceforge.net/ZipDLL_plug-in
 
-
-
 On macOS, installers that download components on-the-fly can only
 be built and installed on system using macOS 10.5 or later.
 
diff --git a/Modules/CPackIFW.cmake b/Modules/CPackIFW.cmake
index f58f9ef..58e6a37 100644
--- a/Modules/CPackIFW.cmake
+++ b/Modules/CPackIFW.cmake
@@ -5,6 +5,8 @@
 CPackIFW
 --------
 
+.. versionadded:: 3.1
+
 This module looks for the location of the command-line utilities supplied with the
 `Qt Installer Framework <http://doc.qt.io/qtinstallerframework/index.html>`_
 (QtIFW).
@@ -59,7 +61,7 @@
 
   ``FORCED_INSTALLATION``
     if set, then the component must always be installed.
-    It is a equivalent of the ``REQUARED`` option from the
+    It is a equivalent of the ``REQUIRED`` option from the
     :command:`cpack_add_component` command.
 
   ``REQUIRES_ADMIN_RIGHTS``
@@ -359,6 +361,8 @@
   "QtIFW-")
 
 set(_CPACK_IFW_VERSIONS
+  "3.2"
+  "3.2.0"
   "3.1"
   "3.1.0"
   "3.0"
diff --git a/Modules/CPackIFWConfigureFile.cmake b/Modules/CPackIFWConfigureFile.cmake
index 0abe0da..296b13f 100644
--- a/Modules/CPackIFWConfigureFile.cmake
+++ b/Modules/CPackIFWConfigureFile.cmake
@@ -5,6 +5,8 @@
 CPackIFWConfigureFile
 ---------------------
 
+.. versionadded:: 3.8
+
 The module defines :command:`configure_file` similar command to
 configure file templates prepared in QtIFW/SDK/Creator style.
 
diff --git a/Modules/CSharpUtilities.cmake b/Modules/CSharpUtilities.cmake
index 6a4b5c7..dedb146 100644
--- a/Modules/CSharpUtilities.cmake
+++ b/Modules/CSharpUtilities.cmake
@@ -5,6 +5,8 @@
 CSharpUtilities
 ---------------
 
+.. versionadded:: 3.8
+
 Functions to make configuration of CSharp/.NET targets easier.
 
 A collection of CMake utility functions useful for dealing with CSharp
diff --git a/Modules/CTestCoverageCollectGCOV.cmake b/Modules/CTestCoverageCollectGCOV.cmake
index ff48cc2..a01a2fe 100644
--- a/Modules/CTestCoverageCollectGCOV.cmake
+++ b/Modules/CTestCoverageCollectGCOV.cmake
@@ -5,6 +5,8 @@
 CTestCoverageCollectGCOV
 ------------------------
 
+.. versionadded:: 3.2
+
 This module provides the ``ctest_coverage_collect_gcov`` function.
 
 This function runs gcov on all .gcda files found in the binary tree
@@ -37,6 +39,17 @@
     upload to CDash.  Relative paths will be interpreted with respect
     to the top-level build directory.
 
+  ``TARBALL_COMPRESSION <option>`` Specify a compression algorithm for the
+    ``TARBALL`` data file.  Using this option reduces the size of the data file
+    before it is submitted to CDash.  ``<option>`` must be one of ``GZIP``,
+    ``BZIP2``, ``XZ``, ``ZSTD``, ``FROM_EXT``, or an expression that CMake
+    evaluates as ``FALSE``. The default value is ``BZIP2``.
+
+    If ``FROM_EXT`` is specified, the resulting file will be compressed based on
+    the file extension of the ``<tarfile>`` (i.e. ``.tar.gz`` will use ``GZIP``
+    compression). File extensions that will produce compressed output include
+    ``.tar.gz``, ``.tgz``, ``.tar.bzip2``, ``.tbz``, ``.tar.xz``, and ``.txz``.
+
   ``SOURCE <source_dir>``
     Specify the top-level source directory for the build.
     Default is the value of :variable:`CTEST_SOURCE_DIRECTORY`.
@@ -68,7 +81,7 @@
 
 function(ctest_coverage_collect_gcov)
   set(options QUIET GLOB DELETE)
-  set(oneValueArgs TARBALL SOURCE BUILD GCOV_COMMAND)
+  set(oneValueArgs TARBALL SOURCE BUILD GCOV_COMMAND TARBALL_COMPRESSION)
   set(multiValueArgs GCOV_OPTIONS)
   cmake_parse_arguments(GCOV  "${options}" "${oneValueArgs}"
     "${multiValueArgs}" "" ${ARGN} )
@@ -91,6 +104,13 @@
   else()
     set(gcov_command "${GCOV_GCOV_COMMAND}")
   endif()
+  if(NOT DEFINED GCOV_TARBALL_COMPRESSION)
+    set(GCOV_TARBALL_COMPRESSION "BZIP2")
+  elseif( GCOV_TARBALL_COMPRESSION AND
+      NOT GCOV_TARBALL_COMPRESSION MATCHES "^(GZIP|BZIP2|XZ|ZSTD|FROM_EXT)$")
+    message(FATAL_ERROR "TARBALL_COMPRESSION must be one of OFF, GZIP, "
+      "BZIP2, XZ, ZSTD, or FROM_EXT for ctest_coverage_collect_gcov")
+  endif()
   # run gcov on each gcda file in the binary tree
   set(gcda_files)
   set(label_files)
@@ -137,11 +157,23 @@
   if(NOT DEFINED GCOV_GCOV_OPTIONS)
     set(GCOV_GCOV_OPTIONS -b -x)
   endif()
+  if (GCOV_QUIET)
+    set(coverage_out_opts
+      OUTPUT_QUIET
+      ERROR_QUIET
+      )
+  else()
+    set(coverage_out_opts
+      OUTPUT_FILE "${coverage_dir}/gcov.log"
+      ERROR_FILE  "${coverage_dir}/gcov.log"
+      )
+  endif()
   execute_process(COMMAND
     ${gcov_command} ${GCOV_GCOV_OPTIONS} ${gcda_files}
-    OUTPUT_VARIABLE out
     RESULT_VARIABLE res
-    WORKING_DIRECTORY ${coverage_dir})
+    WORKING_DIRECTORY ${coverage_dir}
+    ${coverage_out_opts}
+    )
 
   if (GCOV_DELETE)
     file(REMOVE ${gcda_files})
@@ -149,7 +181,7 @@
 
   if(NOT "${res}" EQUAL 0)
     if (NOT GCOV_QUIET)
-      message(STATUS "Error running gcov: ${res} ${out}")
+      message(STATUS "Error running gcov: ${res}, see\n  ${coverage_dir}/gcov.log")
     endif()
   endif()
   # create json file with project information
@@ -258,14 +290,38 @@
 ${uncovered_files_for_tar}
 ")
 
-  if (GCOV_QUIET)
-    set(tar_opts "cfj")
-  else()
-    set(tar_opts "cvfj")
+  # Prepare tar command line arguments
+
+  set(tar_opts "")
+  # Select data compression mode
+  if( GCOV_TARBALL_COMPRESSION STREQUAL "FROM_EXT")
+    if( GCOV_TARBALL MATCHES [[\.(tgz|tar.gz)$]] )
+      string(APPEND tar_opts "z")
+    elseif( GCOV_TARBALL MATCHES [[\.(txz|tar.xz)$]] )
+      string(APPEND tar_opts "J")
+    elseif( GCOV_TARBALL MATCHES [[\.(tbz|tar.bz)$]] )
+      string(APPEND tar_opts "j")
+    endif()
+  elseif(GCOV_TARBALL_COMPRESSION STREQUAL "GZIP")
+    string(APPEND tar_opts "z")
+  elseif(GCOV_TARBALL_COMPRESSION STREQUAL "XZ")
+    string(APPEND tar_opts "J")
+  elseif(GCOV_TARBALL_COMPRESSION STREQUAL "BZIP2")
+    string(APPEND tar_opts "j")
+  elseif(GCOV_TARBALL_COMPRESSION STREQUAL "ZSTD")
+    set(zstd_tar_opt "--zstd")
   endif()
+  # Verbosity options
+  if(NOT GCOV_QUIET AND NOT tar_opts MATCHES v)
+    string(APPEND tar_opts "v")
+  endif()
+  # Prepend option 'c' specifying 'create'
+  string(PREPEND tar_opts "c")
+  # Append option 'f' so that the next argument is the filename
+  string(APPEND tar_opts "f")
 
   execute_process(COMMAND
-    ${CMAKE_COMMAND} -E tar ${tar_opts} ${GCOV_TARBALL}
+    ${CMAKE_COMMAND} -E tar ${tar_opts} ${GCOV_TARBALL} ${zstd_tar_opt}
     "--mtime=1970-01-01 0:0:0 UTC"
     "--format=gnutar"
     --files-from=${coverage_dir}/coverage_file_list.txt
diff --git a/Modules/CheckFortranCompilerFlag.cmake b/Modules/CheckFortranCompilerFlag.cmake
index 299cd8c..b8fac97 100644
--- a/Modules/CheckFortranCompilerFlag.cmake
+++ b/Modules/CheckFortranCompilerFlag.cmake
@@ -5,6 +5,8 @@
 CheckFortranCompilerFlag
 ------------------------
 
+.. versionadded:: 3.3
+
 Check whether the Fortran compiler supports a given flag.
 
 .. command:: check_fortran_compiler_flag
diff --git a/Modules/CheckFortranSourceCompiles.cmake b/Modules/CheckFortranSourceCompiles.cmake
index f0fde8d..d776b0c 100644
--- a/Modules/CheckFortranSourceCompiles.cmake
+++ b/Modules/CheckFortranSourceCompiles.cmake
@@ -5,6 +5,8 @@
 CheckFortranSourceCompiles
 --------------------------
 
+.. versionadded:: 3.1
+
 Check if given Fortran source compiles and links into an executable.
 
 .. command:: check_fortran_source_compiles
@@ -103,8 +105,6 @@
     if(NOT _SRC_EXT)
       set(_SRC_EXT F)
     endif()
-    set(MACRO_CHECK_FUNCTION_DEFINITIONS
-      "-D${VAR} ${CMAKE_REQUIRED_FLAGS}")
     if(CMAKE_REQUIRED_LINK_OPTIONS)
       set(CHECK_Fortran_SOURCE_COMPILES_ADD_LINK_OPTIONS
         LINK_OPTIONS ${CMAKE_REQUIRED_LINK_OPTIONS})
@@ -132,10 +132,10 @@
     try_compile(${VAR}
       ${CMAKE_BINARY_DIR}
       ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/src.${_SRC_EXT}
-      COMPILE_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS}
+      COMPILE_DEFINITIONS -D${VAR} ${CMAKE_REQUIRED_DEFINITIONS}
       ${CHECK_Fortran_SOURCE_COMPILES_ADD_LINK_OPTIONS}
       ${CHECK_Fortran_SOURCE_COMPILES_ADD_LIBRARIES}
-      CMAKE_FLAGS -DCOMPILE_DEFINITIONS:STRING=${MACRO_CHECK_FUNCTION_DEFINITIONS}
+      CMAKE_FLAGS -DCOMPILE_DEFINITIONS:STRING=${CMAKE_REQUIRED_FLAGS}
       "${CHECK_Fortran_SOURCE_COMPILES_ADD_INCLUDES}"
       OUTPUT_VARIABLE OUTPUT)
 
diff --git a/Modules/CheckFortranSourceRuns.cmake b/Modules/CheckFortranSourceRuns.cmake
index a3e5d5d..a710352 100644
--- a/Modules/CheckFortranSourceRuns.cmake
+++ b/Modules/CheckFortranSourceRuns.cmake
@@ -5,6 +5,8 @@
 CheckFortranSourceRuns
 ----------------------
 
+.. versionadded:: 3.14
+
 Check if given Fortran source compiles and links into an executable and can
 subsequently be run.
 
@@ -98,8 +100,6 @@
     if(NOT _SRC_EXT)
       set(_SRC_EXT F90)
     endif()
-    set(MACRO_CHECK_FUNCTION_DEFINITIONS
-      "-D${VAR} ${CMAKE_REQUIRED_FLAGS}")
     if(CMAKE_REQUIRED_LINK_OPTIONS)
       set(CHECK_Fortran_SOURCE_COMPILES_ADD_LINK_OPTIONS
         LINK_OPTIONS ${CMAKE_REQUIRED_LINK_OPTIONS})
@@ -127,10 +127,10 @@
     try_run(${VAR}_EXITCODE ${VAR}_COMPILED
       ${CMAKE_BINARY_DIR}
       ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/src.${_SRC_EXT}
-      COMPILE_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS}
+      COMPILE_DEFINITIONS -D${VAR} ${CMAKE_REQUIRED_DEFINITIONS}
       ${CHECK_Fortran_SOURCE_COMPILES_ADD_LINK_OPTIONS}
       ${CHECK_Fortran_SOURCE_COMPILES_ADD_LIBRARIES}
-      CMAKE_FLAGS -DCOMPILE_DEFINITIONS:STRING=${MACRO_CHECK_FUNCTION_DEFINITIONS}
+      CMAKE_FLAGS -DCOMPILE_DEFINITIONS:STRING=${CMAKE_REQUIRED_FLAGS}
       -DCMAKE_SKIP_RPATH:BOOL=${CMAKE_SKIP_RPATH}
       "${CHECK_Fortran_SOURCE_COMPILES_ADD_INCLUDES}"
       COMPILE_OUTPUT_VARIABLE OUTPUT
diff --git a/Modules/CheckIPOSupported.cmake b/Modules/CheckIPOSupported.cmake
index 90a9f61..1dd951d 100644
--- a/Modules/CheckIPOSupported.cmake
+++ b/Modules/CheckIPOSupported.cmake
@@ -5,6 +5,8 @@
 CheckIPOSupported
 -----------------
 
+.. versionadded:: 3.9
+
 Check whether the compiler supports an interprocedural optimization (IPO/LTO).
 Use this before enabling the :prop_tgt:`INTERPROCEDURAL_OPTIMIZATION` target
 property.
diff --git a/Modules/CheckLanguage.cmake b/Modules/CheckLanguage.cmake
index 1c4e7d3..44387d4 100644
--- a/Modules/CheckLanguage.cmake
+++ b/Modules/CheckLanguage.cmake
@@ -20,7 +20,7 @@
 as the compiler that was found, or ``NOTFOUND`` if the language cannot be
 enabled. For CUDA which can have an explicit host compiler, the cache
 :variable:`CMAKE_CUDA_HOST_COMPILER` variable will be set if it was required
-for compilation.
+for compilation (and cleared if it was not).
 
 Example:
 
@@ -47,7 +47,7 @@
       set(extra_compiler_variables "set(CMAKE_CUDA_HOST_COMPILER \\\"\${CMAKE_CUDA_HOST_COMPILER}\\\")")
     endif()
 
-    set(content
+    set(_cl_content
       "cmake_minimum_required(VERSION ${CMAKE_VERSION})
 project(Check${lang} ${lang})
 file(WRITE \"\${CMAKE_CURRENT_BINARY_DIR}/result.cmake\"
@@ -57,7 +57,7 @@
     )
 
     file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/Check${lang}/CMakeLists.txt"
-      "${content}")
+      "${_cl_content}")
     if(CMAKE_GENERATOR_INSTANCE)
       set(_D_CMAKE_GENERATOR_INSTANCE "-DCMAKE_GENERATOR_INSTANCE:INTERNAL=${CMAKE_GENERATOR_INSTANCE}")
     else()
@@ -75,22 +75,22 @@
                                  -T "${CMAKE_GENERATOR_TOOLSET}"
                                  ${_D_CMAKE_GENERATOR_INSTANCE}
                                  ${_D_CMAKE_MAKE_PROGRAM}
-      OUTPUT_VARIABLE output
-      ERROR_VARIABLE output
-      RESULT_VARIABLE result
+      OUTPUT_VARIABLE _cl_output
+      ERROR_VARIABLE _cl_output
+      RESULT_VARIABLE _cl_result
       )
     include(${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/Check${lang}/result.cmake OPTIONAL)
-    if(CMAKE_${lang}_COMPILER AND "${result}" STREQUAL "0")
+    if(CMAKE_${lang}_COMPILER AND "${_cl_result}" STREQUAL "0")
       file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
         "${_desc} passed with the following output:\n"
-        "${output}\n")
+        "${_cl_output}\n")
       set(_CHECK_COMPILER_STATUS CHECK_PASS)
     else()
       set(CMAKE_${lang}_COMPILER NOTFOUND)
       set(_CHECK_COMPILER_STATUS CHECK_FAIL)
       file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
         "${_desc} failed with the following output:\n"
-        "${output}\n")
+        "${_cl_output}\n")
     endif()
     message(${_CHECK_COMPILER_STATUS} "${CMAKE_${lang}_COMPILER}")
     set(CMAKE_${lang}_COMPILER "${CMAKE_${lang}_COMPILER}" CACHE FILEPATH "${lang} compiler")
diff --git a/Modules/CheckLinkerFlag.cmake b/Modules/CheckLinkerFlag.cmake
new file mode 100644
index 0000000..cd7301f
--- /dev/null
+++ b/Modules/CheckLinkerFlag.cmake
@@ -0,0 +1,83 @@
+# Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
+# file Copyright.txt or https://cmake.org/licensing for details.
+
+#[=======================================================================[.rst:
+CheckLinkerFlag
+---------------
+
+.. versionadded:: 3.18
+
+Check whether the compiler supports a given link flag.
+
+.. command:: check_linker_flag
+
+  .. code-block:: cmake
+
+    check_linker_flag(<lang> <flag> <var>)
+
+Check that the link ``<flag>`` is accepted by the ``<lang>`` compiler without
+a diagnostic.  Stores the result in an internal cache entry named ``<var>``.
+
+This command temporarily sets the ``CMAKE_REQUIRED_LINK_OPTIONS`` variable
+and calls the ``check_<lang>_source_compiles`` macro from the
+``Check<lang>SourceCompiles`` module (:module:`CheckCSourceCompiles`,
+:module:`CheckCSourceCompiles`, :module:`CheckCXXSourceCompiles`,
+:module:`CheckOBJCSourceCompiles`, :module:`CheckOBJCXXSourceCompiles` or
+:module:`CheckFortranSourceCompiles`).  See documentation of these
+modules for a listing of variables that can otherwise modify the build.
+
+The underlying implementation rely on :prop_tgt:`LINK_OPTIONS` property to
+check the specified flag. The ``LINKER:`` prefix, as described in
+:command:`target_link_options` command, can be used as well.
+
+A positive result from this check indicates only that the compiler did not
+issue a diagnostic message when given the link flag.  Whether the flag has any
+effect or even a specific one is beyond the scope of this module.
+
+.. note::
+  Since the :command:`try_compile` command forwards flags from variables
+  like :variable:`CMAKE_<LANG>_FLAGS`, unknown flags in such variables may
+  cause a false negative for this check.
+#]=======================================================================]
+
+include_guard(GLOBAL)
+
+include(CMakeCheckCompilerFlagCommonPatterns)
+
+function(CHECK_LINKER_FLAG _lang _flag _var)
+  get_property (_supported_languages GLOBAL PROPERTY ENABLED_LANGUAGES)
+  if (NOT _lang IN_LIST _supported_languages)
+    message (SEND_ERROR "check_linker_flag: ${_lang}: unknown language.")
+    return()
+  endif()
+
+  include (Check${_lang}SourceCompiles)
+
+  set(CMAKE_REQUIRED_LINK_OPTIONS "${_flag}")
+
+  # Normalize locale during test compilation.
+  set(_locale_vars LC_ALL LC_MESSAGES LANG)
+  foreach(v IN LISTS _locale_vars)
+    set(_locale_vars_saved_${v} "$ENV{${v}}")
+    set(ENV{${v}} C)
+  endforeach()
+
+  if (_lang MATCHES "^(C|CXX)$")
+    set (_source "int main() { return 0; }")
+  elseif (_lang STREQUAL "Fortran")
+    set (_source "       program test\n       stop\n       end program")
+  elseif (_lang MATCHES "^(OBJC|OBJCXX)$")
+    set (_source "#ifndef __OBJC__\n#  error \"Not an Objective-C++ compiler\"\n#endif\nint main(void) { return 0; }")
+  else()
+    message (SEND_ERROR "check_linker_flag: ${_lang}: unsupported language.")
+    return()
+  endif()
+  check_compiler_flag_common_patterns(_common_patterns)
+
+  cmake_language (CALL check_${_lang}_source_compiles "${_source}" ${_var} ${_common_patterns})
+
+  foreach(v IN LISTS _locale_vars)
+    set(ENV{${v}} ${_locale_vars_saved_${v}})
+  endforeach()
+  set(${_var} "${${_var}}" PARENT_SCOPE)
+endfunction()
diff --git a/Modules/CheckOBJCCompilerFlag.cmake b/Modules/CheckOBJCCompilerFlag.cmake
index 1d975da..a98f429 100644
--- a/Modules/CheckOBJCCompilerFlag.cmake
+++ b/Modules/CheckOBJCCompilerFlag.cmake
@@ -5,6 +5,8 @@
 CheckOBJCCompilerFlag
 ---------------------
 
+.. versionadded:: 3.16
+
 Check whether the Objective-C compiler supports a given flag.
 
 .. command:: check_objc_compiler_flag
diff --git a/Modules/CheckOBJCSourceCompiles.cmake b/Modules/CheckOBJCSourceCompiles.cmake
index 601f1fa..502ed74 100644
--- a/Modules/CheckOBJCSourceCompiles.cmake
+++ b/Modules/CheckOBJCSourceCompiles.cmake
@@ -5,6 +5,8 @@
 CheckOBJCSourceCompiles
 -----------------------
 
+.. versionadded:: 3.16
+
 Check if given Objective-C source compiles and links into an executable.
 
 .. command:: check_objc_source_compiles
diff --git a/Modules/CheckOBJCSourceRuns.cmake b/Modules/CheckOBJCSourceRuns.cmake
index 6684693..9d4fb1b 100644
--- a/Modules/CheckOBJCSourceRuns.cmake
+++ b/Modules/CheckOBJCSourceRuns.cmake
@@ -5,6 +5,8 @@
 CheckOBJCSourceRuns
 -------------------
 
+.. versionadded:: 3.16
+
 Check if given Objective-C source compiles and links into an executable and can
 subsequently be run.
 
diff --git a/Modules/CheckOBJCXXCompilerFlag.cmake b/Modules/CheckOBJCXXCompilerFlag.cmake
index c32741b..7944ab0 100644
--- a/Modules/CheckOBJCXXCompilerFlag.cmake
+++ b/Modules/CheckOBJCXXCompilerFlag.cmake
@@ -5,6 +5,8 @@
 CheckOBJCXXCompilerFlag
 -----------------------
 
+.. versionadded:: 3.16
+
 Check whether the Objective-C++ compiler supports a given flag.
 
 .. command:: check_objcxx_compiler_flag
diff --git a/Modules/CheckOBJCXXSourceCompiles.cmake b/Modules/CheckOBJCXXSourceCompiles.cmake
index 2ee79f4..7b839e4 100644
--- a/Modules/CheckOBJCXXSourceCompiles.cmake
+++ b/Modules/CheckOBJCXXSourceCompiles.cmake
@@ -5,6 +5,8 @@
 CheckOBJCXXSourceCompiles
 -------------------------
 
+.. versionadded:: 3.16
+
 Check if given Objective-C++ source compiles and links into an executable.
 
 .. command:: check_objcxx_source_compiles
diff --git a/Modules/CheckOBJCXXSourceRuns.cmake b/Modules/CheckOBJCXXSourceRuns.cmake
index 7f7e04f..c327598 100644
--- a/Modules/CheckOBJCXXSourceRuns.cmake
+++ b/Modules/CheckOBJCXXSourceRuns.cmake
@@ -5,6 +5,8 @@
 CheckOBJCXXSourceRuns
 ---------------------
 
+.. versionadded:: 3.16
+
 Check if given Objective-C++ source compiles and links into an executable and can
 subsequently be run.
 
diff --git a/Modules/CheckPIESupported.cmake b/Modules/CheckPIESupported.cmake
index 6d63f0b..a99d8c4 100644
--- a/Modules/CheckPIESupported.cmake
+++ b/Modules/CheckPIESupported.cmake
@@ -5,6 +5,8 @@
 CheckPIESupported
 -----------------
 
+.. versionadded:: 3.14
+
 Check whether the linker supports Position Independent Code (PIE) or No
 Position Independent Code (NO_PIE) for executables.
 Use this to ensure that the :prop_tgt:`POSITION_INDEPENDENT_CODE` target
diff --git a/Modules/CheckTypeSize.c.in b/Modules/CheckTypeSize.c.in
index 82035a3..fb93073 100644
--- a/Modules/CheckTypeSize.c.in
+++ b/Modules/CheckTypeSize.c.in
@@ -5,10 +5,14 @@
 # define KEY '_','_','i','3','8','6'
 #elif defined(__x86_64)
 # define KEY '_','_','x','8','6','_','6','4'
-#elif defined(__ppc__)
-# define KEY '_','_','p','p','c','_','_'
+#elif defined(__PPC64__)
+# define KEY '_','_','P','P','C','6','4','_','_'
 #elif defined(__ppc64__)
 # define KEY '_','_','p','p','c','6','4','_','_'
+#elif defined(__PPC__)
+# define KEY '_','_','P','P','C','_','_'
+#elif defined(__ppc__)
+# define KEY '_','_','p','p','c','_','_'
 #elif defined(__aarch64__)
 # define KEY '_','_','a','a','r','c','h','6','4','_','_'
 #elif defined(__ARM_ARCH_7A__)
diff --git a/Modules/CheckTypeSize.cmake b/Modules/CheckTypeSize.cmake
index 2b07b7c..17beadc 100644
--- a/Modules/CheckTypeSize.cmake
+++ b/Modules/CheckTypeSize.cmake
@@ -89,25 +89,7 @@
     message(CHECK_START "Check size of ${type}")
   endif()
 
-  # Include header files.
-  set(headers)
-  if(builtin)
-    if(HAVE_SYS_TYPES_H)
-      string(APPEND headers "#include <sys/types.h>\n")
-    endif()
-    if(HAVE_STDINT_H)
-      string(APPEND headers "#include <stdint.h>\n")
-    endif()
-    if(HAVE_STDDEF_H)
-      string(APPEND headers "#include <stddef.h>\n")
-    endif()
-  endif()
-  foreach(h ${CMAKE_EXTRA_INCLUDE_FILES})
-    string(APPEND headers "#include \"${h}\"\n")
-  endforeach()
-
-  # Perform the check.
-
+  # Perform language check
   if(language STREQUAL "C")
     set(src ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CheckTypeSize/${var}.c)
   elseif(language STREQUAL "CXX")
@@ -115,6 +97,37 @@
   else()
     message(FATAL_ERROR "Unknown language:\n  ${language}\nSupported languages: C, CXX.\n")
   endif()
+
+  # Include header files.
+  set(headers)
+  if(builtin)
+    if(language STREQUAL "CXX" AND type MATCHES "^std::")
+      if(HAVE_SYS_TYPES_H)
+        string(APPEND headers "#include <sys/types.h>\n")
+      endif()
+      if(HAVE_CSTDINT)
+        string(APPEND headers "#include <cstdint>\n")
+      endif()
+      if(HAVE_CSTDDEF)
+        string(APPEND headers "#include <cstddef>\n")
+      endif()
+    else()
+      if(HAVE_SYS_TYPES_H)
+        string(APPEND headers "#include <sys/types.h>\n")
+      endif()
+      if(HAVE_STDINT_H)
+        string(APPEND headers "#include <stdint.h>\n")
+      endif()
+      if(HAVE_STDDEF_H)
+        string(APPEND headers "#include <stddef.h>\n")
+      endif()
+    endif()
+  endif()
+  foreach(h ${CMAKE_EXTRA_INCLUDE_FILES})
+    string(APPEND headers "#include \"${h}\"\n")
+  endforeach()
+
+  # Perform the check.
   set(bin ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CheckTypeSize/${var}.bin)
   configure_file(${__check_type_size_dir}/CheckTypeSize.c.in ${src} @ONLY)
   try_compile(HAVE_${var} ${CMAKE_BINARY_DIR} ${src}
@@ -232,8 +245,13 @@
       check_include_file(stddef.h HAVE_STDDEF_H)
     elseif(_language STREQUAL "CXX")
       check_include_file_cxx(sys/types.h HAVE_SYS_TYPES_H)
-      check_include_file_cxx(stdint.h HAVE_STDINT_H)
-      check_include_file_cxx(stddef.h HAVE_STDDEF_H)
+      if("${TYPE}" MATCHES "^std::")
+        check_include_file_cxx(cstdint HAVE_CSTDINT)
+        check_include_file_cxx(cstddef HAVE_CSTDDEF)
+      else()
+        check_include_file_cxx(stdint.h HAVE_STDINT_H)
+        check_include_file_cxx(stddef.h HAVE_STDDEF_H)
+      endif()
     endif()
   endif()
   unset(_CHECK_TYPE_SIZE_BUILTIN_TYPES_ONLY)
diff --git a/Modules/Compiler/ARMClang.cmake b/Modules/Compiler/ARMClang.cmake
index 2518ac7..70e6ffb 100644
--- a/Modules/Compiler/ARMClang.cmake
+++ b/Modules/Compiler/ARMClang.cmake
@@ -19,6 +19,13 @@
 set(CMAKE_AR "${CMAKE_ARMClang_AR}" CACHE FILEPATH "The ARMClang archiver" FORCE)
 mark_as_advanced(CMAKE_ARMClang_AR)
 
+if (CMAKE_LINKER MATCHES "armlink")
+  set(__CMAKE_ARMClang_USING_armlink TRUE)
+  set(CMAKE_LIBRARY_PATH_FLAG "--userlibpath=")
+else()
+  set(__CMAKE_ARMClang_USING_armlink FALSE)
+endif()
+
 # get compiler supported cpu list
 function(__armclang_set_processor_list lang out_var)
   execute_process(COMMAND "${CMAKE_${lang}_COMPILER}" --target=${CMAKE_${lang}_COMPILER_TARGET} -mcpu=list
@@ -39,6 +46,32 @@
   endif()
 endfunction()
 
+# get compiler supported arch list
+function(__armclang_set_arch_list lang out_var)
+  execute_process(COMMAND "${CMAKE_${lang}_COMPILER}" --target=${CMAKE_${lang}_COMPILER_TARGET} -march=list
+    OUTPUT_VARIABLE arch_list
+    ERROR_VARIABLE arch_list)
+  string(REGEX MATCHALL "-march=([^ \n]*)" arch_list "${arch_list}")
+  string(REGEX REPLACE "-march=" "" arch_list "${arch_list}")
+  set(${out_var} "${arch_list}" PARENT_SCOPE)
+endfunction()
+
+# get linker supported cpu list
+function(__armlink_set_cpu_list lang out_var)
+  if(__CMAKE_ARMClang_USING_armlink)
+    set(__linker_wrapper_flags "")
+  else()
+    set(__linker_wrapper_flags --target=${CMAKE_${lang}_COMPILER_TARGET} -Xlinker)
+  endif()
+
+  execute_process(COMMAND "${CMAKE_LINKER}" ${__linker_wrapper_flags} --cpu=list
+    OUTPUT_VARIABLE cpu_list
+    ERROR_VARIABLE cpu_list)
+  string(REGEX MATCHALL "--cpu=([^ \n]*)" cpu_list "${cpu_list}")
+  string(REGEX REPLACE "--cpu=" "" cpu_list "${cpu_list}")
+  set(${out_var} "${cpu_list}" PARENT_SCOPE)
+endfunction()
+
 macro(__compiler_armclang lang)
   if(NOT CMAKE_${lang}_COMPILER_TARGET)
     set(CMAKE_${lang}_COMPILER_TARGET arm-arm-none-eabi)
@@ -46,24 +79,50 @@
   if(NOT CMAKE_${lang}_COMPILER_PROCESSOR_LIST)
     __armclang_set_processor_list(${lang} CMAKE_${lang}_COMPILER_PROCESSOR_LIST)
   endif()
-  if(NOT CMAKE_SYSTEM_PROCESSOR)
-    message(FATAL_ERROR "  CMAKE_SYSTEM_PROCESSOR must be set for ARMClang\n"
-      "  Supported processor: ${CMAKE_${lang}_COMPILER_PROCESSOR_LIST}\n")
-  else()
-    __armclang_check_processor("${CMAKE_SYSTEM_PROCESSOR}" "${CMAKE_${lang}_COMPILER_PROCESSOR_LIST}" _CMAKE_${lang}_CHECK_RESULT)
-    if(NOT _CMAKE_${lang}_CHECK_RESULT)
-      message(FATAL_ERROR "  System processor '${CMAKE_SYSTEM_PROCESSOR}' not supported by ARMClang ${lang} compiler\n"
-        "  Supported processor: ${CMAKE_${lang}_COMPILER_PROCESSOR_LIST}\n")
-    endif()
-    unset(_CMAKE_${lang}_CHECK_RESULT)
+  if(NOT CMAKE_${lang}_COMPILER_ARCH_LIST)
+    __armclang_set_arch_list(${lang} CMAKE_${lang}_COMPILER_ARCH_LIST)
   endif()
-  string(APPEND CMAKE_${lang}_FLAGS_INIT "-mcpu=${CMAKE_SYSTEM_PROCESSOR}")
-  string(APPEND CMAKE_${lang}_LINK_FLAGS "--cpu=${CMAKE_SYSTEM_PROCESSOR}")
+  if(NOT CMAKE_SYSTEM_PROCESSOR AND NOT CMAKE_SYSTEM_ARCH)
+    message(FATAL_ERROR "  CMAKE_SYSTEM_PROCESSOR or CMAKE_SYSTEM_ARCH must be set for ARMClang\n"
+      "  Supported processor: ${CMAKE_${lang}_COMPILER_PROCESSOR_LIST}\n"
+      "  Supported Architecture: ${CMAKE_${lang}_COMPILER_ARCH_LIST}")
+  else()
+    __armclang_check_processor("${CMAKE_SYSTEM_ARCH}" "${CMAKE_${lang}_COMPILER_ARCH_LIST}" _CMAKE_${lang}_CHECK_ARCH_RESULT)
+    if( _CMAKE_${lang}_CHECK_ARCH_RESULT)
+      string(APPEND CMAKE_${lang}_FLAGS_INIT "-march=${CMAKE_SYSTEM_ARCH}")
+      set(__march_flag_set TRUE)
+    endif()
+    __armclang_check_processor("${CMAKE_SYSTEM_PROCESSOR}" "${CMAKE_${lang}_COMPILER_PROCESSOR_LIST}" _CMAKE_${lang}_CHECK_PROCESSOR_RESULT)
+    if(_CMAKE_${lang}_CHECK_PROCESSOR_RESULT)
+      string(APPEND CMAKE_${lang}_FLAGS_INIT "-mcpu=${CMAKE_SYSTEM_PROCESSOR}")
+      set(__mcpu_flag_set TRUE)
+    endif()
+    if(NOT __march_flag_set AND NOT __mcpu_flag_set)
+      message(FATAL_ERROR "At least one of the variables CMAKE_SYSTEM_PROCESSOR or CMAKE_SYSTEM_ARCH must be set for ARMClang\n"
+                          "Supported processor: ${CMAKE_${lang}_COMPILER_PROCESSOR_LIST}\n"
+                          "  Supported Architecture: ${CMAKE_${lang}_COMPILER_ARCH_LIST}")
+    endif()
+    unset(_CMAKE_${lang}_CHECK_PROCESSOR_RESULT)
+    unset(_CMAKE_${lang}_CHECK_ARCH_RESULT)
+  endif()
 
-  set(CMAKE_${lang}_LINK_EXECUTABLE "<CMAKE_LINKER> <CMAKE_${lang}_LINK_FLAGS> <LINK_FLAGS> <LINK_LIBRARIES> <OBJECTS> -o <TARGET> --list <TARGET_BASE>.map")
+  #check if CMAKE_SYSTEM_PROCESSOR belongs to supported cpu list for armlink
+  __armlink_set_cpu_list( ${lang} CMAKE_LINKER_CPU_LIST)
+  list(TRANSFORM CMAKE_LINKER_CPU_LIST TOLOWER)
+  __armclang_check_processor("${CMAKE_SYSTEM_PROCESSOR}" "${CMAKE_LINKER_CPU_LIST}" _CMAKE_CHECK_LINK_CPU_RESULT)
+  if(_CMAKE_CHECK_LINK_CPU_RESULT)
+    string(APPEND CMAKE_${lang}_LINK_FLAGS "--cpu=${CMAKE_SYSTEM_PROCESSOR}")
+  endif()
+
+  if(__CMAKE_ARMClang_USING_armlink)
+    set(__CMAKE_ARMClang_USING_armlink_WRAPPER "")
+  else()
+    set(__CMAKE_ARMClang_USING_armlink_WRAPPER ${CMAKE_${lang}_LINKER_WRAPPER_FLAG})
+  endif()
+  set(CMAKE_${lang}_LINK_EXECUTABLE "<CMAKE_LINKER> <CMAKE_${lang}_LINK_FLAGS> <LINK_FLAGS> <LINK_LIBRARIES> <OBJECTS> -o <TARGET> ${__CMAKE_ARMClang_USING_armlink_WRAPPER} --list <TARGET_BASE>.map")
   set(CMAKE_${lang}_CREATE_STATIC_LIBRARY  "<CMAKE_AR> --create -cr <TARGET> <LINK_FLAGS> <OBJECTS>")
   set(CMAKE_${lang}_ARCHIVE_CREATE         "<CMAKE_AR> --create -cr <TARGET> <LINK_FLAGS> <OBJECTS>")
-  set(CMAKE_${lang}_RESPONSE_FILE_LINK_FLAG "--via=")
+  set(CMAKE_${lang}_RESPONSE_FILE_LINK_FLAG "${__CMAKE_ARMClang_USING_armlink_WRAPPER} --via=")
   set(CMAKE_${lang}_OUTPUT_EXTENSION ".o")
   set(CMAKE_${lang}_OUTPUT_EXTENSION_REPLACE 1)
 endmacro()
diff --git a/Modules/Compiler/Absoft-Fortran.cmake b/Modules/Compiler/Absoft-Fortran.cmake
index 76502dc..8724f85 100644
--- a/Modules/Compiler/Absoft-Fortran.cmake
+++ b/Modules/Compiler/Absoft-Fortran.cmake
@@ -9,3 +9,5 @@
 set(CMAKE_Fortran_FORMAT_FIXED_FLAG "-ffixed")
 set(CMAKE_Fortran_FORMAT_FREE_FLAG "-ffree")
 set(CMAKE_Fortran_LINKER_WRAPPER_FLAG "-X")
+set(CMAKE_Fortran_COMPILE_OPTIONS_PREPROCESS_ON "-cpp")
+set(CMAKE_Fortran_COMPILE_OPTIONS_PREPROCESS_OFF "-no-cpp")
diff --git a/Modules/Compiler/AppleClang-C.cmake b/Modules/Compiler/AppleClang-C.cmake
index 2794f52..26a4bbd 100644
--- a/Modules/Compiler/AppleClang-C.cmake
+++ b/Modules/Compiler/AppleClang-C.cmake
@@ -1,6 +1,8 @@
 include(Compiler/Clang)
 __compiler_clang(C)
 
+set(CMAKE_C_COMPILE_OPTIONS_EXPLICIT_LANGUAGE -x c)
+
 if(NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 4.0)
   set(CMAKE_C90_STANDARD_COMPILE_OPTION "-std=c90")
   set(CMAKE_C90_EXTENSION_COMPILE_OPTION "-std=gnu90")
diff --git a/Modules/Compiler/AppleClang-CXX.cmake b/Modules/Compiler/AppleClang-CXX.cmake
index 15edc21..611c674 100644
--- a/Modules/Compiler/AppleClang-CXX.cmake
+++ b/Modules/Compiler/AppleClang-CXX.cmake
@@ -1,6 +1,8 @@
 include(Compiler/Clang)
 __compiler_clang(CXX)
 
+set(CMAKE_CXX_COMPILE_OPTIONS_EXPLICIT_LANGUAGE -x c++)
+
 if(NOT "x${CMAKE_CXX_SIMULATE_ID}" STREQUAL "xMSVC")
   set(CMAKE_CXX_COMPILE_OPTIONS_VISIBILITY_INLINES_HIDDEN "-fvisibility-inlines-hidden")
 endif()
diff --git a/Modules/Compiler/Clang-C.cmake b/Modules/Compiler/Clang-C.cmake
index 7c4a263..fb6ffa7 100644
--- a/Modules/Compiler/Clang-C.cmake
+++ b/Modules/Compiler/Clang-C.cmake
@@ -8,6 +8,8 @@
 
 if("x${CMAKE_C_COMPILER_FRONTEND_VARIANT}" STREQUAL "xMSVC")
   set(CMAKE_C_CLANG_TIDY_DRIVER_MODE "cl")
+elseif("x${CMAKE_CXX_COMPILER_FRONTEND_VARIANT}" STREQUAL "xGNU")
+  set(CMAKE_C_COMPILE_OPTIONS_EXPLICIT_LANGUAGE -x c)
 endif()
 
 if(NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 3.4)
diff --git a/Modules/Compiler/Clang-CUDA.cmake b/Modules/Compiler/Clang-CUDA.cmake
new file mode 100644
index 0000000..336827b
--- /dev/null
+++ b/Modules/Compiler/Clang-CUDA.cmake
@@ -0,0 +1,28 @@
+include(Compiler/Clang)
+__compiler_clang(CUDA)
+
+# Set explicitly, because __compiler_clang() doesn't set this if we're simulating MSVC.
+set(CMAKE_DEPFILE_FLAGS_CUDA "-MD -MT <OBJECT> -MF <DEPFILE>")
+
+# C++03 isn't supported for CXX, but is for CUDA, so we need to set these manually.
+# Do this before __compiler_clang_cxx_standards() since that adds the feature.
+set(CMAKE_CUDA03_STANDARD_COMPILE_OPTION "-std=c++03")
+set(CMAKE_CUDA03_EXTENSION_COMPILE_OPTION "-std=gnu++03")
+__compiler_clang_cxx_standards(CUDA)
+
+set(CMAKE_CUDA_COMPILER_HAS_DEVICE_LINK_PHASE TRUE)
+set(_CMAKE_COMPILE_AS_CUDA_FLAG "-x cuda")
+set(_CMAKE_CUDA_PTX_FLAG "--cuda-device-only -S")
+
+# RulePlaceholderExpander expands crosscompile variables like sysroot and target only for CMAKE_<LANG>_COMPILER. Override the default.
+set(CMAKE_CUDA_LINK_EXECUTABLE "<CMAKE_CUDA_COMPILER> <LINK_FLAGS> <OBJECTS> -o <TARGET> <LINK_LIBRARIES>${__IMPLICT_LINKS}")
+set(CMAKE_CUDA_CREATE_SHARED_LIBRARY "<CMAKE_CUDA_COMPILER> <CMAKE_SHARED_LIBRARY_CUDA_FLAGS> <LINK_FLAGS> <CMAKE_SHARED_LIBRARY_CREATE_CUDA_FLAGS> <SONAME_FLAG><TARGET_SONAME> -o <TARGET> <OBJECTS> <LINK_LIBRARIES>${__IMPLICT_LINKS}")
+
+set(CMAKE_CUDA_RUNTIME_LIBRARY_DEFAULT "STATIC")
+set(CMAKE_CUDA_RUNTIME_LIBRARY_LINK_OPTIONS_STATIC "cudadevrt;cudart_static")
+set(CMAKE_CUDA_RUNTIME_LIBRARY_LINK_OPTIONS_SHARED "cudadevrt;cudart")
+set(CMAKE_CUDA_RUNTIME_LIBRARY_LINK_OPTIONS_NONE   "")
+
+if(UNIX)
+  list(APPEND CMAKE_CUDA_RUNTIME_LIBRARY_LINK_OPTIONS_STATIC "rt" "pthread" "dl")
+endif()
diff --git a/Modules/Compiler/Clang-CXX.cmake b/Modules/Compiler/Clang-CXX.cmake
index cb240f9..311d2b0 100644
--- a/Modules/Compiler/Clang-CXX.cmake
+++ b/Modules/Compiler/Clang-CXX.cmake
@@ -1,7 +1,10 @@
 include(Compiler/Clang)
 __compiler_clang(CXX)
+__compiler_clang_cxx_standards(CXX)
+
 
 if("x${CMAKE_CXX_COMPILER_FRONTEND_VARIANT}" STREQUAL "xGNU")
+  set(CMAKE_CXX_COMPILE_OPTIONS_EXPLICIT_LANGUAGE -x c++)
   set(CMAKE_CXX_COMPILE_OPTIONS_VISIBILITY_INLINES_HIDDEN "-fvisibility-inlines-hidden")
 endif()
 
@@ -13,121 +16,3 @@
 if("x${CMAKE_CXX_COMPILER_FRONTEND_VARIANT}" STREQUAL "xMSVC")
   set(CMAKE_CXX_CLANG_TIDY_DRIVER_MODE "cl")
 endif()
-
-if("x${CMAKE_CXX_COMPILER_FRONTEND_VARIANT}" STREQUAL "xGNU")
-  if(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 2.1)
-    set(CMAKE_CXX98_STANDARD_COMPILE_OPTION "-std=c++98")
-    set(CMAKE_CXX98_EXTENSION_COMPILE_OPTION "-std=gnu++98")
-  endif()
-
-  if(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 3.1)
-    set(CMAKE_CXX98_STANDARD__HAS_FULL_SUPPORT ON)
-    set(CMAKE_CXX11_STANDARD_COMPILE_OPTION "-std=c++11")
-    set(CMAKE_CXX11_EXTENSION_COMPILE_OPTION "-std=gnu++11")
-    set(CMAKE_CXX11_STANDARD__HAS_FULL_SUPPORT ON)
-  elseif(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 2.1)
-    set(CMAKE_CXX11_STANDARD_COMPILE_OPTION "-std=c++0x")
-    set(CMAKE_CXX11_EXTENSION_COMPILE_OPTION "-std=gnu++0x")
-  endif()
-
-  if(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 3.5)
-    set(CMAKE_CXX14_STANDARD_COMPILE_OPTION "-std=c++14")
-    set(CMAKE_CXX14_EXTENSION_COMPILE_OPTION "-std=gnu++14")
-    set(CMAKE_CXX14_STANDARD__HAS_FULL_SUPPORT ON)
-  elseif(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 3.4)
-    set(CMAKE_CXX14_STANDARD_COMPILE_OPTION "-std=c++1y")
-    set(CMAKE_CXX14_EXTENSION_COMPILE_OPTION "-std=gnu++1y")
-    set(CMAKE_CXX14_STANDARD__HAS_FULL_SUPPORT ON)
-  endif()
-
-  set(_clang_version_std17 5.0)
-  if(CMAKE_SYSTEM_NAME STREQUAL "Android")
-    set(_clang_version_std17 6.0)
-  endif()
-
-  if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS "${_clang_version_std17}")
-    set(CMAKE_CXX17_STANDARD_COMPILE_OPTION "-std=c++17")
-    set(CMAKE_CXX17_EXTENSION_COMPILE_OPTION "-std=gnu++17")
-  elseif (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 3.5)
-    set(CMAKE_CXX17_STANDARD_COMPILE_OPTION "-std=c++1z")
-    set(CMAKE_CXX17_EXTENSION_COMPILE_OPTION "-std=gnu++1z")
-  endif()
-
-  if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS "${_clang_version_std17}")
-    set(CMAKE_CXX20_STANDARD_COMPILE_OPTION "-std=c++2a")
-    set(CMAKE_CXX20_EXTENSION_COMPILE_OPTION "-std=gnu++2a")
-  endif()
-
-  unset(_clang_version_std17)
-
-  if("x${CMAKE_CXX_SIMULATE_ID}" STREQUAL "xMSVC")
-    # The MSVC standard library requires C++14, and MSVC itself has no
-    # notion of operating in a mode not aware of at least that standard.
-    set(CMAKE_CXX98_STANDARD_COMPILE_OPTION "-std=c++14")
-    set(CMAKE_CXX98_EXTENSION_COMPILE_OPTION "-std=gnu++14")
-    set(CMAKE_CXX11_STANDARD_COMPILE_OPTION "-std=c++14")
-    set(CMAKE_CXX11_EXTENSION_COMPILE_OPTION "-std=gnu++14")
-
-    # This clang++ is missing some features because of MSVC compatibility.
-    unset(CMAKE_CXX11_STANDARD__HAS_FULL_SUPPORT)
-    unset(CMAKE_CXX14_STANDARD__HAS_FULL_SUPPORT)
-    unset(CMAKE_CXX17_STANDARD__HAS_FULL_SUPPORT)
-    unset(CMAKE_CXX20_STANDARD__HAS_FULL_SUPPORT)
-  endif()
-
-  __compiler_check_default_language_standard(CXX 2.1 98)
-elseif(CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 3.9
-    AND CMAKE_CXX_SIMULATE_VERSION VERSION_GREATER_EQUAL 19.0)
-  # This version of clang-cl and the MSVC version it simulates have
-  # support for -std: flags.
-  set(CMAKE_CXX98_STANDARD_COMPILE_OPTION "")
-  set(CMAKE_CXX98_EXTENSION_COMPILE_OPTION "")
-  set(CMAKE_CXX98_STANDARD__HAS_FULL_SUPPORT ON)
-  set(CMAKE_CXX11_STANDARD_COMPILE_OPTION "")
-  set(CMAKE_CXX11_EXTENSION_COMPILE_OPTION "")
-  set(CMAKE_CXX14_STANDARD_COMPILE_OPTION "-std:c++14")
-  set(CMAKE_CXX14_EXTENSION_COMPILE_OPTION "-std:c++14")
-  if (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 6.0)
-    set(CMAKE_CXX17_STANDARD_COMPILE_OPTION "-std:c++17")
-    set(CMAKE_CXX17_EXTENSION_COMPILE_OPTION "-std:c++17")
-    set(CMAKE_CXX20_STANDARD_COMPILE_OPTION "-std:c++latest")
-    set(CMAKE_CXX20_EXTENSION_COMPILE_OPTION "-std:c++latest")
-  else()
-    set(CMAKE_CXX17_STANDARD_COMPILE_OPTION "-std:c++latest")
-    set(CMAKE_CXX17_EXTENSION_COMPILE_OPTION "-std:c++latest")
-  endif()
-
-  __compiler_check_default_language_standard(CXX 3.9 14)
-else()
-  # This version of clang-cl, or the MSVC version it simulates, does not have
-  # language standards.  Set these options as empty strings so the feature
-  # test infrastructure can at least check to see if they are defined.
-  set(CMAKE_CXX98_STANDARD_COMPILE_OPTION "")
-  set(CMAKE_CXX98_EXTENSION_COMPILE_OPTION "")
-  set(CMAKE_CXX11_STANDARD_COMPILE_OPTION "")
-  set(CMAKE_CXX11_EXTENSION_COMPILE_OPTION "")
-  set(CMAKE_CXX14_STANDARD_COMPILE_OPTION "")
-  set(CMAKE_CXX14_EXTENSION_COMPILE_OPTION "")
-  set(CMAKE_CXX17_STANDARD_COMPILE_OPTION "")
-  set(CMAKE_CXX17_EXTENSION_COMPILE_OPTION "")
-  set(CMAKE_CXX20_STANDARD_COMPILE_OPTION "")
-  set(CMAKE_CXX20_EXTENSION_COMPILE_OPTION "")
-
-  # There is no meaningful default for this
-  set(CMAKE_CXX_STANDARD_DEFAULT "")
-
-  # There are no compiler modes so we only need to test features once.
-  # Override the default macro for this special case.  Pretend that
-  # all language standards are available so that at least compilation
-  # can be attempted.
-  macro(cmake_record_cxx_compile_features)
-    list(APPEND CMAKE_CXX_COMPILE_FEATURES
-      cxx_std_98
-      cxx_std_11
-      cxx_std_14
-      cxx_std_17
-      cxx_std_20
-      )
-    _record_compiler_features(CXX "" CMAKE_CXX_COMPILE_FEATURES)
-  endmacro()
-endif()
diff --git a/Modules/Compiler/Clang-OBJCXX.cmake b/Modules/Compiler/Clang-OBJCXX.cmake
index b01ce64..453b5fd 100644
--- a/Modules/Compiler/Clang-OBJCXX.cmake
+++ b/Modules/Compiler/Clang-OBJCXX.cmake
@@ -1,70 +1,3 @@
 include(Compiler/Clang)
 __compiler_clang(OBJCXX)
-
-if("x${CMAKE_OBJCXX_COMPILER_FRONTEND_VARIANT}" STREQUAL "xGNU")
-  if(NOT CMAKE_OBJCXX_COMPILER_VERSION VERSION_LESS 2.1)
-    set(CMAKE_OBJCXX98_STANDARD_COMPILE_OPTION "-std=c++98")
-    set(CMAKE_OBJCXX98_EXTENSION_COMPILE_OPTION "-std=gnu++98")
-  endif()
-
-  if(NOT CMAKE_OBJCXX_COMPILER_VERSION VERSION_LESS 3.1)
-    set(CMAKE_OBJCXX98_STANDARD__HAS_FULL_SUPPORT ON)
-    set(CMAKE_OBJCXX11_STANDARD_COMPILE_OPTION "-std=c++11")
-    set(CMAKE_OBJCXX11_EXTENSION_COMPILE_OPTION "-std=gnu++11")
-    set(CMAKE_OBJCXX11_STANDARD__HAS_FULL_SUPPORT ON)
-  elseif(NOT CMAKE_OBJCXX_COMPILER_VERSION VERSION_LESS 2.1)
-    set(CMAKE_OBJCXX11_STANDARD_COMPILE_OPTION "-std=c++0x")
-    set(CMAKE_OBJCXX11_EXTENSION_COMPILE_OPTION "-std=gnu++0x")
-  endif()
-
-  if(NOT CMAKE_OBJCXX_COMPILER_VERSION VERSION_LESS 3.5)
-    set(CMAKE_OBJCXX14_STANDARD_COMPILE_OPTION "-std=c++14")
-    set(CMAKE_OBJCXX14_EXTENSION_COMPILE_OPTION "-std=gnu++14")
-    set(CMAKE_OBJCXX14_STANDARD__HAS_FULL_SUPPORT ON)
-  elseif(NOT CMAKE_OBJCXX_COMPILER_VERSION VERSION_LESS 3.4)
-    set(CMAKE_OBJCXX14_STANDARD_COMPILE_OPTION "-std=c++1y")
-    set(CMAKE_OBJCXX14_EXTENSION_COMPILE_OPTION "-std=gnu++1y")
-    set(CMAKE_OBJCXX14_STANDARD__HAS_FULL_SUPPORT ON)
-  endif()
-
-  set(_clang_version_std17 5.0)
-
-  if (NOT CMAKE_OBJCXX_COMPILER_VERSION VERSION_LESS "${_clang_version_std17}")
-    set(CMAKE_OBJCXX17_STANDARD_COMPILE_OPTION "-std=c++17")
-    set(CMAKE_OBJCXX17_EXTENSION_COMPILE_OPTION "-std=gnu++17")
-  elseif (NOT CMAKE_OBJCXX_COMPILER_VERSION VERSION_LESS 3.5)
-    set(CMAKE_OBJCXX17_STANDARD_COMPILE_OPTION "-std=c++1z")
-    set(CMAKE_OBJCXX17_EXTENSION_COMPILE_OPTION "-std=gnu++1z")
-  endif()
-
-  if (NOT CMAKE_OBJCXX_COMPILER_VERSION VERSION_LESS "${_clang_version_std17}")
-    set(CMAKE_OBJCXX20_STANDARD_COMPILE_OPTION "-std=c++2a")
-    set(CMAKE_OBJCXX20_EXTENSION_COMPILE_OPTION "-std=gnu++2a")
-  endif()
-
-  unset(_clang_version_std17)
-
-  __compiler_check_default_language_standard(OBJCXX 2.1 98)
-elseif(CMAKE_OBJCXX_COMPILER_VERSION VERSION_GREATER_EQUAL 3.9
-    AND CMAKE_OBJCXX_SIMULATE_VERSION VERSION_GREATER_EQUAL 19.0)
-  # This version of clang-cl and the MSVC version it simulates have
-  # support for -std: flags.
-  set(CMAKE_OBJCXX98_STANDARD_COMPILE_OPTION "")
-  set(CMAKE_OBJCXX98_EXTENSION_COMPILE_OPTION "")
-  set(CMAKE_OBJCXX98_STANDARD__HAS_FULL_SUPPORT ON)
-  set(CMAKE_OBJCXX11_STANDARD_COMPILE_OPTION "")
-  set(CMAKE_OBJCXX11_EXTENSION_COMPILE_OPTION "")
-  set(CMAKE_OBJCXX14_STANDARD_COMPILE_OPTION "-std:c++14")
-  set(CMAKE_OBJCXX14_EXTENSION_COMPILE_OPTION "-std:c++14")
-  if (CMAKE_OBJCXX_COMPILER_VERSION VERSION_GREATER_EQUAL 6.0)
-    set(CMAKE_OBJCXX17_STANDARD_COMPILE_OPTION "-std:c++17")
-    set(CMAKE_OBJCXX17_EXTENSION_COMPILE_OPTION "-std:c++17")
-    set(CMAKE_OBJCXX20_STANDARD_COMPILE_OPTION "-std:c++latest")
-    set(CMAKE_OBJCXX20_EXTENSION_COMPILE_OPTION "-std:c++latest")
-  else()
-    set(CMAKE_OBJCXX17_STANDARD_COMPILE_OPTION "-std:c++latest")
-    set(CMAKE_OBJCXX17_EXTENSION_COMPILE_OPTION "-std:c++latest")
-  endif()
-
-  __compiler_check_default_language_standard(OBJCXX 3.9 14)
-endif()
+__compiler_clang_cxx_standards(OBJCXX)
diff --git a/Modules/Compiler/Clang.cmake b/Modules/Compiler/Clang.cmake
index f65916f..52d5350 100644
--- a/Modules/Compiler/Clang.cmake
+++ b/Modules/Compiler/Clang.cmake
@@ -105,3 +105,130 @@
     set(CMAKE_${lang}_COMPILE_OPTIONS_CREATE_PCH -Xclang -emit-pch -Xclang -include -Xclang <PCH_HEADER>)
   endmacro()
 endif()
+
+macro(__compiler_clang_cxx_standards lang)
+  if("x${CMAKE_${lang}_COMPILER_FRONTEND_VARIANT}" STREQUAL "xGNU")
+    if(NOT CMAKE_${lang}_COMPILER_VERSION VERSION_LESS 2.1)
+      set(CMAKE_${lang}98_STANDARD_COMPILE_OPTION "-std=c++98")
+      set(CMAKE_${lang}98_EXTENSION_COMPILE_OPTION "-std=gnu++98")
+    endif()
+
+    if(NOT CMAKE_${lang}_COMPILER_VERSION VERSION_LESS 3.1)
+      set(CMAKE_${lang}98_STANDARD__HAS_FULL_SUPPORT ON)
+      set(CMAKE_${lang}11_STANDARD_COMPILE_OPTION "-std=c++11")
+      set(CMAKE_${lang}11_EXTENSION_COMPILE_OPTION "-std=gnu++11")
+      set(CMAKE_${lang}11_STANDARD__HAS_FULL_SUPPORT ON)
+    elseif(NOT CMAKE_${lang}_COMPILER_VERSION VERSION_LESS 2.1)
+      set(CMAKE_${lang}11_STANDARD_COMPILE_OPTION "-std=c++0x")
+      set(CMAKE_${lang}11_EXTENSION_COMPILE_OPTION "-std=gnu++0x")
+    endif()
+
+    if(NOT CMAKE_${lang}_COMPILER_VERSION VERSION_LESS 3.5)
+      set(CMAKE_${lang}14_STANDARD_COMPILE_OPTION "-std=c++14")
+      set(CMAKE_${lang}14_EXTENSION_COMPILE_OPTION "-std=gnu++14")
+      set(CMAKE_${lang}14_STANDARD__HAS_FULL_SUPPORT ON)
+    elseif(NOT CMAKE_${lang}_COMPILER_VERSION VERSION_LESS 3.4)
+      set(CMAKE_${lang}14_STANDARD_COMPILE_OPTION "-std=c++1y")
+      set(CMAKE_${lang}14_EXTENSION_COMPILE_OPTION "-std=gnu++1y")
+      set(CMAKE_${lang}14_STANDARD__HAS_FULL_SUPPORT ON)
+    endif()
+
+    set(_clang_version_std17 5.0)
+    if(CMAKE_SYSTEM_NAME STREQUAL "Android")
+      set(_clang_version_std17 6.0)
+    endif()
+
+    if (NOT CMAKE_${lang}_COMPILER_VERSION VERSION_LESS "${_clang_version_std17}")
+      set(CMAKE_${lang}17_STANDARD_COMPILE_OPTION "-std=c++17")
+      set(CMAKE_${lang}17_EXTENSION_COMPILE_OPTION "-std=gnu++17")
+    elseif (NOT CMAKE_${lang}_COMPILER_VERSION VERSION_LESS 3.5)
+      set(CMAKE_${lang}17_STANDARD_COMPILE_OPTION "-std=c++1z")
+      set(CMAKE_${lang}17_EXTENSION_COMPILE_OPTION "-std=gnu++1z")
+    endif()
+
+    if(NOT CMAKE_${lang}_COMPILER_VERSION VERSION_LESS 6.0)
+      set(CMAKE_${lang}17_STANDARD__HAS_FULL_SUPPORT ON)
+    endif()
+
+    if(NOT CMAKE_${lang}_COMPILER_VERSION VERSION_LESS 11.0)
+      set(CMAKE_${lang}20_STANDARD_COMPILE_OPTION "-std=c++20")
+      set(CMAKE_${lang}20_EXTENSION_COMPILE_OPTION "-std=gnu++20")
+    elseif(NOT CMAKE_${lang}_COMPILER_VERSION VERSION_LESS "${_clang_version_std17}")
+      set(CMAKE_${lang}20_STANDARD_COMPILE_OPTION "-std=c++2a")
+      set(CMAKE_${lang}20_EXTENSION_COMPILE_OPTION "-std=gnu++2a")
+    endif()
+
+    unset(_clang_version_std17)
+
+    if("x${CMAKE_${lang}_SIMULATE_ID}" STREQUAL "xMSVC")
+      # The MSVC standard library requires C++14, and MSVC itself has no
+      # notion of operating in a mode not aware of at least that standard.
+      set(CMAKE_${lang}98_STANDARD_COMPILE_OPTION "-std=c++14")
+      set(CMAKE_${lang}98_EXTENSION_COMPILE_OPTION "-std=gnu++14")
+      set(CMAKE_${lang}11_STANDARD_COMPILE_OPTION "-std=c++14")
+      set(CMAKE_${lang}11_EXTENSION_COMPILE_OPTION "-std=gnu++14")
+
+      # This clang++ is missing some features because of MSVC compatibility.
+      unset(CMAKE_${lang}11_STANDARD__HAS_FULL_SUPPORT)
+      unset(CMAKE_${lang}14_STANDARD__HAS_FULL_SUPPORT)
+      unset(CMAKE_${lang}17_STANDARD__HAS_FULL_SUPPORT)
+      unset(CMAKE_${lang}20_STANDARD__HAS_FULL_SUPPORT)
+    endif()
+
+    __compiler_check_default_language_standard(${lang} 2.1 98)
+  elseif(CMAKE_${lang}_COMPILER_VERSION VERSION_GREATER_EQUAL 3.9
+      AND CMAKE_${lang}_SIMULATE_VERSION VERSION_GREATER_EQUAL 19.0)
+    # This version of clang-cl and the MSVC version it simulates have
+    # support for -std: flags.
+    set(CMAKE_${lang}98_STANDARD_COMPILE_OPTION "")
+    set(CMAKE_${lang}98_EXTENSION_COMPILE_OPTION "")
+    set(CMAKE_${lang}98_STANDARD__HAS_FULL_SUPPORT ON)
+    set(CMAKE_${lang}11_STANDARD_COMPILE_OPTION "")
+    set(CMAKE_${lang}11_EXTENSION_COMPILE_OPTION "")
+    set(CMAKE_${lang}14_STANDARD_COMPILE_OPTION "-std:c++14")
+    set(CMAKE_${lang}14_EXTENSION_COMPILE_OPTION "-std:c++14")
+    if (CMAKE_${lang}_COMPILER_VERSION VERSION_GREATER_EQUAL 6.0)
+      set(CMAKE_${lang}17_STANDARD_COMPILE_OPTION "-std:c++17")
+      set(CMAKE_${lang}17_EXTENSION_COMPILE_OPTION "-std:c++17")
+      set(CMAKE_${lang}20_STANDARD_COMPILE_OPTION "-std:c++latest")
+      set(CMAKE_${lang}20_EXTENSION_COMPILE_OPTION "-std:c++latest")
+    else()
+      set(CMAKE_${lang}17_STANDARD_COMPILE_OPTION "-std:c++latest")
+      set(CMAKE_${lang}17_EXTENSION_COMPILE_OPTION "-std:c++latest")
+    endif()
+
+    __compiler_check_default_language_standard(${lang} 3.9 14)
+  else()
+    # This version of clang-cl, or the MSVC version it simulates, does not have
+    # language standards.  Set these options as empty strings so the feature
+    # test infrastructure can at least check to see if they are defined.
+    set(CMAKE_${lang}98_STANDARD_COMPILE_OPTION "")
+    set(CMAKE_${lang}98_EXTENSION_COMPILE_OPTION "")
+    set(CMAKE_${lang}11_STANDARD_COMPILE_OPTION "")
+    set(CMAKE_${lang}11_EXTENSION_COMPILE_OPTION "")
+    set(CMAKE_${lang}14_STANDARD_COMPILE_OPTION "")
+    set(CMAKE_${lang}14_EXTENSION_COMPILE_OPTION "")
+    set(CMAKE_${lang}17_STANDARD_COMPILE_OPTION "")
+    set(CMAKE_${lang}17_EXTENSION_COMPILE_OPTION "")
+    set(CMAKE_${lang}20_STANDARD_COMPILE_OPTION "")
+    set(CMAKE_${lang}20_EXTENSION_COMPILE_OPTION "")
+
+    # There is no meaningful default for this
+    set(CMAKE_${lang}_STANDARD_DEFAULT "")
+
+    # There are no compiler modes so we only need to test features once.
+    # Override the default macro for this special case.  Pretend that
+    # all language standards are available so that at least compilation
+    # can be attempted.
+    macro(cmake_record_${lang}_compile_features)
+      list(APPEND CMAKE_${lang}_COMPILE_FEATURES
+        cxx_std_98
+        cxx_std_11
+        cxx_std_14
+        cxx_std_17
+        cxx_std_20
+        )
+      _record_compiler_features(${lang} "" CMAKE_${lang}_COMPILE_FEATURES)
+    endmacro()
+  endif()
+endmacro()
diff --git a/Modules/Compiler/Cray-Fortran.cmake b/Modules/Compiler/Cray-Fortran.cmake
index ccb7c2e..696ae76 100644
--- a/Modules/Compiler/Cray-Fortran.cmake
+++ b/Modules/Compiler/Cray-Fortran.cmake
@@ -11,3 +11,11 @@
 set(CMAKE_Fortran_MODDIR_DEFAULT .)
 set(CMAKE_Fortran_FORMAT_FIXED_FLAG "-f fixed")
 set(CMAKE_Fortran_FORMAT_FREE_FLAG "-f free")
+
+if (NOT CMAKE_Fortran_COMPILER_VERSION VERSION_LESS 8.5)
+  set(CMAKE_Fortran_COMPILE_OPTIONS_PREPROCESS_ON "-eT")
+  set(CMAKE_Fortran_COMPILE_OPTIONS_PREPROCESS_OFF "-dT")
+else()
+  set(CMAKE_Fortran_COMPILE_OPTIONS_PREPROCESS_ON "-eZ")
+  set(CMAKE_Fortran_COMPILE_OPTIONS_PREPROCESS_OFF "-dZ")
+endif()
diff --git a/Modules/Compiler/Flang-Fortran.cmake b/Modules/Compiler/Flang-Fortran.cmake
index f0e61d8..de0484e 100644
--- a/Modules/Compiler/Flang-Fortran.cmake
+++ b/Modules/Compiler/Flang-Fortran.cmake
@@ -11,3 +11,6 @@
 set(CMAKE_Fortran_FORMAT_FREE_FLAG "-ffree-form")
 
 set(CMAKE_Fortran_MODDIR_FLAG "-J")
+
+set(CMAKE_Fortran_COMPILE_OPTIONS_PREPROCESS_ON "-cpp")
+set(CMAKE_Fortran_COMPILE_OPTIONS_PREPROCESS_OFF "-nocpp")
diff --git a/Modules/Compiler/G95-Fortran.cmake b/Modules/Compiler/G95-Fortran.cmake
index 03b7e08..5dba04e 100644
--- a/Modules/Compiler/G95-Fortran.cmake
+++ b/Modules/Compiler/G95-Fortran.cmake
@@ -9,3 +9,5 @@
 set(CMAKE_Fortran_FORMAT_FREE_FLAG "-ffree-form")
 set(CMAKE_Fortran_LINKER_WRAPPER_FLAG "-Wl,")
 set(CMAKE_Fortran_LINKER_WRAPPER_FLAG_SEP ",")
+set(CMAKE_Fortran_COMPILE_OPTIONS_PREPROCESS_ON "-cpp")
+set(CMAKE_Fortran_COMPILE_OPTIONS_PREPROCESS_OFF "-no-cpp")
diff --git a/Modules/Compiler/GNU-ASM.cmake b/Modules/Compiler/GNU-ASM.cmake
index e07401d..94af401 100644
--- a/Modules/Compiler/GNU-ASM.cmake
+++ b/Modules/Compiler/GNU-ASM.cmake
@@ -4,3 +4,10 @@
 set(CMAKE_ASM_SOURCE_FILE_EXTENSIONS s;S;asm)
 
 __compiler_gnu(ASM)
+
+if(CMAKE_ASM${ASM_DIALECT}_COMPILER_ID_VENDOR_MATCH STREQUAL "GNU assembler")
+  set(CMAKE_DEPFILE_FLAGS_ASM${ASM_DIALECT} "--MD <DEPFILE>")
+  set(CMAKE_ASM${ASM_DIALECT}_LINK_EXECUTABLE
+    "<CMAKE_LINKER> <FLAGS> <CMAKE_ASM${ASM_DIALECT}_LINK_FLAGS> <LINK_FLAGS> <OBJECTS> -o <TARGET> <LINK_LIBRARIES>")
+  set(CMAKE_ASM_DEFINE_FLAG "--defsym ")
+endif()
diff --git a/Modules/Compiler/GNU-C.cmake b/Modules/Compiler/GNU-C.cmake
index ca286b3..8105a77 100644
--- a/Modules/Compiler/GNU-C.cmake
+++ b/Modules/Compiler/GNU-C.cmake
@@ -1,6 +1,8 @@
 include(Compiler/GNU)
 __compiler_gnu(C)
 
+set(CMAKE_C_COMPILE_OPTIONS_EXPLICIT_LANGUAGE -x c)
+
 if (NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 4.5)
   set(CMAKE_C90_STANDARD_COMPILE_OPTION "-std=c90")
   set(CMAKE_C90_EXTENSION_COMPILE_OPTION "-std=gnu90")
diff --git a/Modules/Compiler/GNU-CXX.cmake b/Modules/Compiler/GNU-CXX.cmake
index fcaaeab..59ec056 100644
--- a/Modules/Compiler/GNU-CXX.cmake
+++ b/Modules/Compiler/GNU-CXX.cmake
@@ -1,6 +1,8 @@
 include(Compiler/GNU)
 __compiler_gnu(CXX)
 
+set(CMAKE_CXX_COMPILE_OPTIONS_EXPLICIT_LANGUAGE -x c++)
+
 if (WIN32)
   if(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.6)
     set(CMAKE_CXX_COMPILE_OPTIONS_VISIBILITY_INLINES_HIDDEN "-fno-keep-inline-dllexport")
diff --git a/Modules/Compiler/GNU-Fortran.cmake b/Modules/Compiler/GNU-Fortran.cmake
index 6413769..5dfb03e 100644
--- a/Modules/Compiler/GNU-Fortran.cmake
+++ b/Modules/Compiler/GNU-Fortran.cmake
@@ -10,6 +10,11 @@
 set(CMAKE_Fortran_FORMAT_FIXED_FLAG "-ffixed-form")
 set(CMAKE_Fortran_FORMAT_FREE_FLAG "-ffree-form")
 
+if (NOT CMAKE_Fortran_COMPILER_VERSION VERSION_LESS 4.4)
+  set(CMAKE_Fortran_COMPILE_OPTIONS_PREPROCESS_ON "-cpp")
+  set(CMAKE_Fortran_COMPILE_OPTIONS_PREPROCESS_OFF "-nocpp")
+endif()
+
 set(CMAKE_Fortran_POSTPROCESS_FLAG "-fpreprocessed")
 
 # No -DNDEBUG for Fortran.
diff --git a/Modules/Compiler/GNU.cmake b/Modules/Compiler/GNU.cmake
index a68bb6c..668a6a9 100644
--- a/Modules/Compiler/GNU.cmake
+++ b/Modules/Compiler/GNU.cmake
@@ -44,7 +44,8 @@
   # tests to always succeed.  Work around this by disabling dependency tracking
   # in try_compile mode.
   get_property(_IN_TC GLOBAL PROPERTY IN_TRY_COMPILE)
-  if(NOT _IN_TC OR CMAKE_FORCE_DEPFILES)
+  if(CMAKE_${lang}_COMPILER_ID STREQUAL "GNU" AND _IN_TC AND NOT CMAKE_FORCE_DEPFILES)
+  else()
     # distcc does not transform -o to -MT when invoking the preprocessor
     # internally, as it ought to.  Work around this bug by setting -MT here
     # even though it isn't strictly necessary.
@@ -115,7 +116,8 @@
     if (NOT CMAKE_GENERATOR MATCHES "Xcode")
       set(CMAKE_PCH_PROLOGUE "#pragma GCC system_header")
     endif()
-    set(CMAKE_${lang}_COMPILE_OPTIONS_USE_PCH -Winvalid-pch -include <PCH_HEADER>)
-    set(CMAKE_${lang}_COMPILE_OPTIONS_CREATE_PCH -Winvalid-pch -x ${__pch_header_${lang}} -include <PCH_HEADER>)
+    set(CMAKE_${lang}_COMPILE_OPTIONS_INVALID_PCH -Winvalid-pch)
+    set(CMAKE_${lang}_COMPILE_OPTIONS_USE_PCH -include <PCH_HEADER>)
+    set(CMAKE_${lang}_COMPILE_OPTIONS_CREATE_PCH -x ${__pch_header_${lang}} -include <PCH_HEADER>)
   endif()
 endmacro()
diff --git a/Modules/Compiler/HP-Fortran.cmake b/Modules/Compiler/HP-Fortran.cmake
index 63a0331..d3e2a30 100644
--- a/Modules/Compiler/HP-Fortran.cmake
+++ b/Modules/Compiler/HP-Fortran.cmake
@@ -7,3 +7,6 @@
 
 set(CMAKE_Fortran_LINKER_WRAPPER_FLAG "-Wl,")
 set(CMAKE_Fortran_LINKER_WRAPPER_FLAG ",")
+
+set(CMAKE_Fortran_COMPILE_OPTIONS_PREPROCESS_ON "+cpp=yes")
+set(CMAKE_Fortran_COMPILE_OPTIONS_PREPROCESS_OFF "+cpp=no")
diff --git a/Modules/Compiler/IAR.cmake b/Modules/Compiler/IAR.cmake
index 8e75caa..296e2fd 100644
--- a/Modules/Compiler/IAR.cmake
+++ b/Modules/Compiler/IAR.cmake
@@ -1,6 +1,6 @@
 # This file is processed when the IAR compiler is used for a C or C++ file
 # Documentation can be downloaded here: http://www.iar.com/website1/1.0.1.0/675/1/
-# The initial feature request is here: https://gitlab.kitware.com/cmake/cmake/issues/10176
+# The initial feature request is here: https://gitlab.kitware.com/cmake/cmake/-/issues/10176
 # It also contains additional links and information.
 # See USER GUIDES -> C/C++ Development Guide and ReleaseNotes for EWARM:
 # version 6.30.8: http://supp.iar.com/FilesPublic/UPDINFO/006607/arm/doc/infocenter/index.ENU.html
diff --git a/Modules/Compiler/Intel-C.cmake b/Modules/Compiler/Intel-C.cmake
index ec3bfd8..322f63d 100644
--- a/Modules/Compiler/Intel-C.cmake
+++ b/Modules/Compiler/Intel-C.cmake
@@ -28,6 +28,8 @@
 
 else()
 
+  set(CMAKE_C_COMPILE_OPTIONS_EXPLICIT_LANGUAGE -x c)
+
   if (NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 15.0.0)
     set(CMAKE_C11_STANDARD_COMPILE_OPTION "-std=c11")
     set(CMAKE_C11_EXTENSION_COMPILE_OPTION "-std=gnu11")
diff --git a/Modules/Compiler/Intel-CXX.cmake b/Modules/Compiler/Intel-CXX.cmake
index 1ed1b08..42adfd1 100644
--- a/Modules/Compiler/Intel-CXX.cmake
+++ b/Modules/Compiler/Intel-CXX.cmake
@@ -11,6 +11,11 @@
 
   set(CMAKE_CXX_CLANG_TIDY_DRIVER_MODE "cl")
 
+  if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 19.0.0)
+    set(CMAKE_CXX20_STANDARD_COMPILE_OPTION "-Qstd=c++20")
+    set(CMAKE_CXX20_EXTENSION_COMPILE_OPTION "-Qstd=c++20")
+  endif()
+
   if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 18.0.0)
     set(CMAKE_CXX17_STANDARD_COMPILE_OPTION "-Qstd=c++17")
     set(CMAKE_CXX17_EXTENSION_COMPILE_OPTION "-Qstd=c++17")
@@ -37,6 +42,13 @@
 
 else()
 
+  set(CMAKE_CXX_COMPILE_OPTIONS_EXPLICIT_LANGUAGE -x c++)
+
+  if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 19.0.0)
+    set(CMAKE_CXX20_STANDARD_COMPILE_OPTION "-std=c++20")
+    set(CMAKE_CXX20_EXTENSION_COMPILE_OPTION "-std=gnu++20")
+  endif()
+
   if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 18.0.0)
     set(CMAKE_CXX17_STANDARD_COMPILE_OPTION "-std=c++17")
     set(CMAKE_CXX17_EXTENSION_COMPILE_OPTION "-std=gnu++17")
diff --git a/Modules/Compiler/Intel-Fortran.cmake b/Modules/Compiler/Intel-Fortran.cmake
index 156b533..71f25f4 100644
--- a/Modules/Compiler/Intel-Fortran.cmake
+++ b/Modules/Compiler/Intel-Fortran.cmake
@@ -15,3 +15,5 @@
 
 set(CMAKE_Fortran_PREPROCESS_SOURCE
   "<CMAKE_Fortran_COMPILER> -fpp <DEFINES> <INCLUDES> <FLAGS> -E <SOURCE> > <PREPROCESSED_SOURCE>")
+set(CMAKE_Fortran_COMPILE_OPTIONS_PREPROCESS_ON "-fpp")
+set(CMAKE_Fortran_COMPILE_OPTIONS_PREPROCESS_OFF "-nofpp")
diff --git a/Modules/Compiler/Intel.cmake b/Modules/Compiler/Intel.cmake
index 56a3078..9a760c8 100644
--- a/Modules/Compiler/Intel.cmake
+++ b/Modules/Compiler/Intel.cmake
@@ -38,8 +38,9 @@
       set(CMAKE_PCH_EXTENSION .pchi)
       set(CMAKE_LINK_PCH ON)
       set(CMAKE_PCH_EPILOGUE "#pragma hdrstop")
-      set(CMAKE_${lang}_COMPILE_OPTIONS_USE_PCH -Winvalid-pch -Wno-pch-messages -pch-use <PCH_FILE> -include <PCH_HEADER>)
-      set(CMAKE_${lang}_COMPILE_OPTIONS_CREATE_PCH -Winvalid-pch -Wno-pch-messages -pch-create <PCH_FILE> -include <PCH_HEADER>)
+      set(CMAKE_${lang}_COMPILE_OPTIONS_INVALID_PCH -Winvalid-pch)
+      set(CMAKE_${lang}_COMPILE_OPTIONS_USE_PCH -Wno-pch-messages -pch-use <PCH_FILE> -include <PCH_HEADER>)
+      set(CMAKE_${lang}_COMPILE_OPTIONS_CREATE_PCH -Wno-pch-messages -pch-create <PCH_FILE> -include <PCH_HEADER>)
     endif()
   endmacro()
 endif()
diff --git a/Modules/Compiler/NAG-Fortran.cmake b/Modules/Compiler/NAG-Fortran.cmake
index 2111c65..ffce97e 100644
--- a/Modules/Compiler/NAG-Fortran.cmake
+++ b/Modules/Compiler/NAG-Fortran.cmake
@@ -37,3 +37,4 @@
 set(CMAKE_Fortran_COMPILE_OPTIONS_PIC "-PIC")
 set(CMAKE_Fortran_COMPILE_OPTIONS_PIE "-PIC")
 set(CMAKE_Fortran_RESPONSE_FILE_LINK_FLAG "-Wl,@")
+set(CMAKE_Fortran_COMPILE_OPTIONS_PREPROCESS_ON "-fpp")
diff --git a/Modules/Compiler/NVIDIA-CUDA.cmake b/Modules/Compiler/NVIDIA-CUDA.cmake
index 671468d..feb5ecc 100644
--- a/Modules/Compiler/NVIDIA-CUDA.cmake
+++ b/Modules/Compiler/NVIDIA-CUDA.cmake
@@ -4,6 +4,9 @@
 set(CMAKE_CUDA_VERBOSE_FLAG "-v")
 set(CMAKE_CUDA_VERBOSE_COMPILE_FLAG "-Xcompiler=-v")
 
+set(_CMAKE_COMPILE_AS_CUDA_FLAG "-x cu")
+set(_CMAKE_CUDA_PTX_FLAG "-ptx")
+
 if (CMAKE_CUDA_COMPILER_VERSION VERSION_GREATER_EQUAL 10.2.89)
   # The -forward-unknown-to-host-compiler flag was only
   # added to nvcc in 10.2 so before that we had no good
@@ -43,10 +46,27 @@
 set(CMAKE_SHARED_LIBRARY_CREATE_CUDA_FLAGS -shared)
 set(CMAKE_INCLUDE_SYSTEM_FLAG_CUDA -isystem=)
 
+if (CMAKE_CUDA_SIMULATE_ID STREQUAL "GNU")
+  set(CMAKE_CUDA_LINKER_WRAPPER_FLAG "-Wl,")
+  set(CMAKE_CUDA_LINKER_WRAPPER_FLAG_SEP ",")
+elseif(CMAKE_CUDA_SIMULATE_ID STREQUAL "Clang")
+  set(CMAKE_CUDA_LINKER_WRAPPER_FLAG "-Xlinker" " ")
+  set(CMAKE_CUDA_LINKER_WRAPPER_FLAG_SEP)
+endif()
+
+set(CMAKE_CUDA_DEVICE_COMPILER_WRAPPER_FLAG "-Xcompiler=")
+set(CMAKE_CUDA_DEVICE_COMPILER_WRAPPER_FLAG_SEP ",")
+set(CMAKE_CUDA_DEVICE_LINKER_WRAPPER_FLAG "-Xlinker=")
+set(CMAKE_CUDA_DEVICE_LINKER_WRAPPER_FLAG_SEP ",")
+
 set(CMAKE_CUDA_RUNTIME_LIBRARY_LINK_OPTIONS_STATIC  "cudadevrt;cudart_static")
 set(CMAKE_CUDA_RUNTIME_LIBRARY_LINK_OPTIONS_SHARED  "cudadevrt;cudart")
 set(CMAKE_CUDA_RUNTIME_LIBRARY_LINK_OPTIONS_NONE    "")
 
+if(UNIX)
+  list(APPEND CMAKE_CUDA_RUNTIME_LIBRARY_LINK_OPTIONS_STATIC "rt" "pthread" "dl")
+endif()
+
 if("x${CMAKE_CUDA_SIMULATE_ID}" STREQUAL "xMSVC")
   set(CMAKE_CUDA03_STANDARD_COMPILE_OPTION "")
   set(CMAKE_CUDA03_EXTENSION_COMPILE_OPTION "")
@@ -58,6 +78,12 @@
     set(CMAKE_CUDA14_STANDARD_COMPILE_OPTION "")
     set(CMAKE_CUDA14_EXTENSION_COMPILE_OPTION "")
   endif()
+
+  if (NOT CMAKE_CUDA_COMPILER_VERSION VERSION_LESS 11.0)
+    set(CMAKE_CUDA17_STANDARD_COMPILE_OPTION "")
+    set(CMAKE_CUDA17_EXTENSION_COMPILE_OPTION "")
+  endif()
+
 else()
   set(CMAKE_CUDA03_STANDARD_COMPILE_OPTION "")
   set(CMAKE_CUDA03_EXTENSION_COMPILE_OPTION "")
@@ -72,6 +98,11 @@
     set(CMAKE_CUDA14_EXTENSION_COMPILE_OPTION "-std=c++14")
   endif()
 
+  if (NOT CMAKE_CUDA_COMPILER_VERSION VERSION_LESS 11.0)
+    set(CMAKE_CUDA17_STANDARD_COMPILE_OPTION "-std=c++17")
+    set(CMAKE_CUDA17_EXTENSION_COMPILE_OPTION "-std=c++17")
+  endif()
+
 endif()
 
 # FIXME: investigate use of --options-file.
diff --git a/Modules/Compiler/NVIDIA-DetermineCompiler.cmake b/Modules/Compiler/NVIDIA-DetermineCompiler.cmake
index bf9111a..4f6ddc2 100644
--- a/Modules/Compiler/NVIDIA-DetermineCompiler.cmake
+++ b/Modules/Compiler/NVIDIA-DetermineCompiler.cmake
@@ -11,9 +11,19 @@
    /* _MSC_VER = VVRR */
 #  define @PREFIX@SIMULATE_VERSION_MAJOR @MACRO_DEC@(_MSC_VER / 100)
 #  define @PREFIX@SIMULATE_VERSION_MINOR @MACRO_DEC@(_MSC_VER % 100)
+# elif defined(__clang__)
+#  define @PREFIX@SIMULATE_VERSION_MAJOR @MACRO_DEC@(__clang_major__)
+#  define @PREFIX@SIMULATE_VERSION_MINOR @MACRO_DEC@(__clang_minor__)
+# elif defined(__GNUC__)
+#  define @PREFIX@SIMULATE_VERSION_MAJOR @MACRO_DEC@(__GNUC__)
+#  define @PREFIX@SIMULATE_VERSION_MINOR @MACRO_DEC@(__GNUC_MINOR__)
 # endif")
 
 set(_compiler_id_simulate "
 # if defined(_MSC_VER)
 #  define @PREFIX@SIMULATE_ID \"MSVC\"
+# elif defined(__clang__)
+#  define @PREFIX@SIMULATE_ID \"Clang\"
+# elif defined(__GNUC__)
+#  define @PREFIX@SIMULATE_ID \"GNU\"
 # endif")
diff --git a/Modules/Compiler/OpenWatcom-C.cmake b/Modules/Compiler/OpenWatcom-C.cmake
new file mode 100644
index 0000000..19e3359
--- /dev/null
+++ b/Modules/Compiler/OpenWatcom-C.cmake
@@ -0,0 +1 @@
+include(Compiler/OpenWatcom)
diff --git a/Modules/Compiler/OpenWatcom-CXX.cmake b/Modules/Compiler/OpenWatcom-CXX.cmake
new file mode 100644
index 0000000..19e3359
--- /dev/null
+++ b/Modules/Compiler/OpenWatcom-CXX.cmake
@@ -0,0 +1 @@
+include(Compiler/OpenWatcom)
diff --git a/Modules/Compiler/OpenWatcom.cmake b/Modules/Compiler/OpenWatcom.cmake
new file mode 100644
index 0000000..a962513
--- /dev/null
+++ b/Modules/Compiler/OpenWatcom.cmake
@@ -0,0 +1,118 @@
+# Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
+# file Copyright.txt or https://cmake.org/licensing for details.
+
+# This module is shared by multiple languages; use include blocker.
+include_guard()
+
+set(CMAKE_LIBRARY_PATH_FLAG "libpath ")
+set(CMAKE_LINK_LIBRARY_FLAG "library ")
+set(CMAKE_LINK_LIBRARY_FILE_FLAG "library ")
+
+if(CMAKE_VERBOSE_MAKEFILE)
+  set(CMAKE_WCL_QUIET)
+  set(CMAKE_WLINK_QUIET)
+  set(CMAKE_LIB_QUIET)
+else()
+  set(CMAKE_WCL_QUIET "-zq")
+  set(CMAKE_WLINK_QUIET "option quiet")
+  set(CMAKE_LIB_QUIET "-q")
+endif()
+
+foreach(type CREATE_SHARED_LIBRARY CREATE_SHARED_MODULE LINK_EXECUTABLE)
+  set(CMAKE_C_${type}_USE_WATCOM_QUOTE 1)
+  set(CMAKE_CXX_${type}_USE_WATCOM_QUOTE 1)
+endforeach()
+
+foreach(type SHARED MODULE EXE)
+  # linker map file creation directives
+  string(APPEND CMAKE_${type}_LINKER_FLAGS_INIT " opt map")
+  # linker debug directives
+  string(APPEND CMAKE_${type}_LINKER_FLAGS_DEBUG_INIT " debug all")
+  string(APPEND CMAKE_${type}_LINKER_FLAGS_RELWITHDEBINFO_INIT " debug all")
+endforeach()
+
+foreach(lang C CXX)
+  # warning level
+  string(APPEND CMAKE_${lang}_FLAGS_INIT " -w3")
+  # debug options
+  string(APPEND CMAKE_${lang}_FLAGS_DEBUG_INIT " -d2")
+  string(APPEND CMAKE_${lang}_FLAGS_MINSIZEREL_INIT " -s -os -d0 -dNDEBUG")
+  string(APPEND CMAKE_${lang}_FLAGS_RELEASE_INIT " -s -ot -d0 -dNDEBUG")
+  string(APPEND CMAKE_${lang}_FLAGS_RELWITHDEBINFO_INIT " -s -ot -d1 -dNDEBUG")
+endforeach()
+
+# C create import library
+set(CMAKE_C_CREATE_IMPORT_LIBRARY
+  "wlib -c -q -n -b <TARGET_IMPLIB> +<TARGET_QUOTED>")
+# C++ create import library
+set(CMAKE_CXX_CREATE_IMPORT_LIBRARY ${CMAKE_C_CREATE_IMPORT_LIBRARY})
+
+# C link a object files into an executable file
+set(CMAKE_C_LINK_EXECUTABLE
+  "wlink ${CMAKE_WLINK_QUIET} name <TARGET> <LINK_FLAGS> file {<OBJECTS>} <LINK_LIBRARIES>")
+# C++ link a object files into an executable file
+set(CMAKE_CXX_LINK_EXECUTABLE ${CMAKE_C_LINK_EXECUTABLE})
+
+# C compile a file into an object file
+set(CMAKE_C_COMPILE_OBJECT
+  "<CMAKE_C_COMPILER> ${CMAKE_WCL_QUIET} -d+ <DEFINES> <INCLUDES> <FLAGS> -fo<OBJECT> -c -cc <SOURCE>")
+# C++ compile a file into an object file
+set(CMAKE_CXX_COMPILE_OBJECT
+  "<CMAKE_CXX_COMPILER> ${CMAKE_WCL_QUIET} -d+ <DEFINES> <INCLUDES> <FLAGS> -fo<OBJECT> -c -cc++ <SOURCE>")
+
+# C preprocess a source file
+set(CMAKE_C_CREATE_PREPROCESSED_SOURCE
+  "<CMAKE_C_COMPILER> ${CMAKE_WCL_QUIET} -d+ <DEFINES> <INCLUDES> <FLAGS> -fo<PREPROCESSED_SOURCE> -pl -cc <SOURCE>")
+# C++ preprocess a source file
+set(CMAKE_CXX_CREATE_PREPROCESSED_SOURCE
+  "<CMAKE_CXX_COMPILER> ${CMAKE_WCL_QUIET} -d+ <DEFINES> <INCLUDES> <FLAGS> -fo<PREPROCESSED_SOURCE> -pl -cc++ <SOURCE>")
+
+# C create a shared library
+set(CMAKE_C_CREATE_SHARED_LIBRARY
+  "wlink ${CMAKE_WLINK_QUIET} name <TARGET> <LINK_FLAGS> option implib=<TARGET_IMPLIB> file {<OBJECTS>} <LINK_LIBRARIES>")
+# C++ create a shared library
+set(CMAKE_CXX_CREATE_SHARED_LIBRARY ${CMAKE_C_CREATE_SHARED_LIBRARY})
+
+# C create a shared module
+set(CMAKE_C_CREATE_SHARED_MODULE
+  "wlink ${CMAKE_WLINK_QUIET} name <TARGET> <LINK_FLAGS> file {<OBJECTS>} <LINK_LIBRARIES>")
+# C++ create a shared module
+set(CMAKE_CXX_CREATE_SHARED_MODULE ${CMAKE_C_CREATE_SHARED_MODULE})
+
+# C create a static library
+set(CMAKE_C_CREATE_STATIC_LIBRARY
+  "wlib ${CMAKE_LIB_QUIET} -c -n -b <TARGET_QUOTED> <LINK_FLAGS> <OBJECTS> ")
+# C++ create a static library
+set(CMAKE_CXX_CREATE_STATIC_LIBRARY ${CMAKE_C_CREATE_STATIC_LIBRARY})
+
+
+# old CMake internally used OpenWatcom version macros
+# for backward compatibility
+if(NOT _CMAKE_WATCOM_VERSION)
+  set(_CMAKE_WATCOM_VERSION 1)
+  if(CMAKE_C_COMPILER_VERSION)
+    set(_compiler_version ${CMAKE_C_COMPILER_VERSION})
+    set(_compiler_id ${CMAKE_C_COMPILER_ID})
+  else()
+    set(_compiler_version ${CMAKE_CXX_COMPILER_VERSION})
+    set(_compiler_id ${CMAKE_CXX_COMPILER_ID})
+  endif()
+  set(WATCOM16)
+  set(WATCOM17)
+  set(WATCOM18)
+  set(WATCOM19)
+  if("${_compiler_id}" STREQUAL "OpenWatcom")
+    if("${_compiler_version}" VERSION_LESS 1.7)
+      set(WATCOM16 1)
+    endif()
+    if("${_compiler_version}" VERSION_EQUAL 1.7)
+      set(WATCOM17 1)
+    endif()
+    if("${_compiler_version}" VERSION_EQUAL 1.8)
+      set(WATCOM18 1)
+    endif()
+    if("${_compiler_version}" VERSION_EQUAL 1.9)
+      set(WATCOM19 1)
+    endif()
+  endif()
+endif()
diff --git a/Modules/Compiler/PGI-CXX.cmake b/Modules/Compiler/PGI-CXX.cmake
index c77de36..2d7a303 100644
--- a/Modules/Compiler/PGI-CXX.cmake
+++ b/Modules/Compiler/PGI-CXX.cmake
@@ -4,19 +4,19 @@
 string(APPEND CMAKE_CXX_FLAGS_RELEASE_INIT " -DNDEBUG")
 
 if(CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 12.10)
-  set(CMAKE_CXX98_STANDARD_COMPILE_OPTION  -A)
+  set(CMAKE_CXX98_STANDARD_COMPILE_OPTION "")
   set(CMAKE_CXX98_EXTENSION_COMPILE_OPTION --gnu_extensions)
   set(CMAKE_CXX98_STANDARD__HAS_FULL_SUPPORT ON)
   if(CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 13.10)
-    set(CMAKE_CXX11_STANDARD_COMPILE_OPTION  --c++11 -A)
+    set(CMAKE_CXX11_STANDARD_COMPILE_OPTION  --c++11)
     set(CMAKE_CXX11_EXTENSION_COMPILE_OPTION --c++11 --gnu_extensions)
     set(CMAKE_CXX11_STANDARD__HAS_FULL_SUPPORT ON)
     if(CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 15.7)
-      set(CMAKE_CXX14_STANDARD_COMPILE_OPTION  --c++14 -A)
+      set(CMAKE_CXX14_STANDARD_COMPILE_OPTION  --c++14)
       set(CMAKE_CXX14_EXTENSION_COMPILE_OPTION --c++14 --gnu_extensions)
       set(CMAKE_CXX14_STANDARD__HAS_FULL_SUPPORT ON)
       if(CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 17.1)
-        set(CMAKE_CXX17_STANDARD_COMPILE_OPTION  --c++17 -A)
+        set(CMAKE_CXX17_STANDARD_COMPILE_OPTION  --c++17)
         set(CMAKE_CXX17_EXTENSION_COMPILE_OPTION --c++17 --gnu_extensions)
         set(CMAKE_CXX17_STANDARD__HAS_FULL_SUPPORT ON)
       endif()
diff --git a/Modules/Compiler/PGI-Fortran.cmake b/Modules/Compiler/PGI-Fortran.cmake
index 3daf798..ff87577 100644
--- a/Modules/Compiler/PGI-Fortran.cmake
+++ b/Modules/Compiler/PGI-Fortran.cmake
@@ -6,6 +6,7 @@
 
 set(CMAKE_Fortran_PREPROCESS_SOURCE
   "<CMAKE_Fortran_COMPILER> -Mpreprocess <DEFINES> <INCLUDES> <FLAGS> -E <SOURCE> > <PREPROCESSED_SOURCE>")
+set(CMAKE_Fortran_COMPILE_OPTIONS_PREPROCESS_ON "-Mpreprocess")
 
 set(CMAKE_Fortran_FORMAT_FIXED_FLAG "-Mnofreeform")
 set(CMAKE_Fortran_FORMAT_FREE_FLAG "-Mfreeform")
diff --git a/Modules/Compiler/PathScale-Fortran.cmake b/Modules/Compiler/PathScale-Fortran.cmake
index d903621..891d93e 100644
--- a/Modules/Compiler/PathScale-Fortran.cmake
+++ b/Modules/Compiler/PathScale-Fortran.cmake
@@ -4,3 +4,6 @@
 set(CMAKE_Fortran_MODDIR_FLAG "-module ")
 set(CMAKE_Fortran_FORMAT_FIXED_FLAG "-fixedform")
 set(CMAKE_Fortran_FORMAT_FREE_FLAG "-freeform")
+
+set(CMAKE_Fortran_COMPILE_OPTIONS_PREPROCESS_ON "-cpp")
+set(CMAKE_Fortran_COMPILE_OPTIONS_PREPROCESS_OFF "-nocpp")
diff --git a/Modules/Compiler/QCC-CXX.cmake b/Modules/Compiler/QCC-CXX.cmake
index 0e7314a..42303f4 100644
--- a/Modules/Compiler/QCC-CXX.cmake
+++ b/Modules/Compiler/QCC-CXX.cmake
@@ -10,6 +10,6 @@
   "<CMAKE_CXX_COMPILER> -lang-c++ <DEFINES> <INCLUDES> <FLAGS> -o <OBJECT> -c <SOURCE>")
 
 set(CMAKE_CXX_LINK_EXECUTABLE
-  "<CMAKE_CXX_COMPILER> -lang-c++ <FLAGS> <CMAKE_CXX_LINK_FLAGS> <LINK_FLAGS> <OBJECTS>  -o <TARGET> <LINK_LIBRARIES>")
+  "<CMAKE_CXX_COMPILER> -lang-c++ <FLAGS> <CMAKE_CXX_LINK_FLAGS> <LINK_FLAGS> <OBJECTS> -o <TARGET> <LINK_LIBRARIES>")
 
 set(CMAKE_CXX_COMPILE_OPTIONS_VISIBILITY_INLINES_HIDDEN "-fvisibility-inlines-hidden")
diff --git a/Modules/Compiler/SunPro-Fortran.cmake b/Modules/Compiler/SunPro-Fortran.cmake
index 0c93c94..0ba5015 100644
--- a/Modules/Compiler/SunPro-Fortran.cmake
+++ b/Modules/Compiler/SunPro-Fortran.cmake
@@ -30,3 +30,5 @@
 
 set(CMAKE_Fortran_CREATE_PREPROCESSED_SOURCE "<CMAKE_Fortran_COMPILER> <DEFINES> <INCLUDES> <FLAGS> -F -fpp <SOURCE> -o <PREPROCESSED_SOURCE>")
 set(CMAKE_Fortran_CREATE_ASSEMBLY_SOURCE "<CMAKE_Fortran_COMPILER> <DEFINES> <INCLUDES> <FLAGS> -S <SOURCE> -o <ASSEMBLY_SOURCE>")
+
+set(CMAKE_Fortran_COMPILE_OPTIONS_PREPROCESS_ON "-fpp")
diff --git a/Modules/Compiler/TI-ASM.cmake b/Modules/Compiler/TI-ASM.cmake
index a566d70..01965d2 100644
--- a/Modules/Compiler/TI-ASM.cmake
+++ b/Modules/Compiler/TI-ASM.cmake
@@ -1,8 +1,4 @@
-set(CMAKE_LIBRARY_PATH_FLAG "--search_path=")
-set(CMAKE_LINK_LIBRARY_FLAG "--library=")
-set(CMAKE_INCLUDE_FLAG_ASM "--include_path=")
-
-set(CMAKE_ASM_COMPILE_OBJECT  "<CMAKE_ASM_COMPILER> --compile_only --asm_file=<SOURCE> <DEFINES> <INCLUDES> <FLAGS> --output_file=<OBJECT>")
-set(CMAKE_ASM_LINK_EXECUTABLE "<CMAKE_ASM_COMPILER> <OBJECTS> --run_linker --output_file=<TARGET> <CMAKE_ASM_LINK_FLAGS> <LINK_FLAGS> <LINK_LIBRARIES>")
+include(Compiler/TI)
+__compiler_ti(ASM)
 
 set(CMAKE_ASM_SOURCE_FILE_EXTENSIONS asm;s;abs)
diff --git a/Modules/Compiler/TI-C.cmake b/Modules/Compiler/TI-C.cmake
index 1c0f4bc..8ea01b5 100644
--- a/Modules/Compiler/TI-C.cmake
+++ b/Modules/Compiler/TI-C.cmake
@@ -1,18 +1,8 @@
-set(CMAKE_LIBRARY_PATH_FLAG "--search_path=")
-set(CMAKE_LINK_LIBRARY_FLAG "--library=")
-set(CMAKE_INCLUDE_FLAG_C "--include_path=")
+include(Compiler/TI)
+__compiler_ti(C)
 
 set(CMAKE_C90_STANDARD_COMPILE_OPTION "--c89")
 set(CMAKE_C90_EXTENSION_COMPILE_OPTION "--c89 --relaxed_ansi")
 
 set(CMAKE_C99_STANDARD_COMPILE_OPTION "--c99")
 set(CMAKE_C99_EXTENSION_COMPILE_OPTION "--c99 --relaxed_ansi")
-
-set(CMAKE_DEPFILE_FLAGS_C "--preproc_with_compile --preproc_dependency=<DEPFILE>")
-
-set(CMAKE_C_CREATE_ASSEMBLY_SOURCE "<CMAKE_C_COMPILER> --compile_only --skip_assembler --c_file=<SOURCE> <DEFINES> <INCLUDES> <FLAGS> --output_file=<ASSEMBLY_SOURCE>")
-set(CMAKE_C_CREATE_PREPROCESSED_SOURCE "<CMAKE_C_COMPILER> --preproc_only --c_file=<SOURCE> <DEFINES> <INCLUDES> <FLAGS> --output_file=<PREPROCESSED_SOURCE>")
-
-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_FLAGS> <OBJECTS> <LINK_LIBRARIES>")
diff --git a/Modules/Compiler/TI-CXX.cmake b/Modules/Compiler/TI-CXX.cmake
index 4c6af06..c08d9a1 100644
--- a/Modules/Compiler/TI-CXX.cmake
+++ b/Modules/Compiler/TI-CXX.cmake
@@ -1,12 +1,2 @@
-set(CMAKE_LIBRARY_PATH_FLAG "--search_path=")
-set(CMAKE_LINK_LIBRARY_FLAG "--library=")
-set(CMAKE_INCLUDE_FLAG_CXX "--include_path=")
-
-set(CMAKE_DEPFILE_FLAGS_CXX "--preproc_with_compile --preproc_dependency=<DEPFILE>")
-
-set(CMAKE_CXX_CREATE_ASSEMBLY_SOURCE "<CMAKE_CXX_COMPILER> --compile_only --skip_assembler --cpp_file=<SOURCE> <DEFINES> <INCLUDES> <FLAGS> --output_file=<ASSEMBLY_SOURCE>")
-set(CMAKE_CXX_CREATE_PREPROCESSED_SOURCE "<CMAKE_CXX_COMPILER> --preproc_only --cpp_file=<SOURCE> <DEFINES> <INCLUDES> <FLAGS> --output_file=<PREPROCESSED_SOURCE>")
-
-set(CMAKE_CXX_COMPILE_OBJECT  "<CMAKE_CXX_COMPILER> --compile_only --cpp_file=<SOURCE> <DEFINES> <INCLUDES> <FLAGS> --output_file=<OBJECT>")
-set(CMAKE_CXX_ARCHIVE_CREATE "<CMAKE_AR> -r <TARGET> <OBJECTS>")
-set(CMAKE_CXX_LINK_EXECUTABLE "<CMAKE_CXX_COMPILER> --run_linker --output_file=<TARGET> --map_file=<TARGET>.map <CMAKE_CXX_LINK_FLAGS> <LINK_LIBRARIES> <LINK_FLAGS> <OBJECTS>")
+include(Compiler/TI)
+__compiler_ti(CXX)
diff --git a/Modules/Compiler/TI.cmake b/Modules/Compiler/TI.cmake
new file mode 100644
index 0000000..9f2e813
--- /dev/null
+++ b/Modules/Compiler/TI.cmake
@@ -0,0 +1,40 @@
+# Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
+# file Copyright.txt or https://cmake.org/licensing for details.
+
+
+# This module is shared by multiple languages; use include blocker.
+if(__COMPILER_TI)
+  return()
+endif()
+set(__COMPILER_TI 1)
+
+macro(__compiler_ti lang)
+  string(TOLOWER ${lang} prefix)
+  if("x${lang}" STREQUAL "xCXX")
+    set(prefix "cpp")
+  endif()
+
+  set(CMAKE_${lang}_RESPONSE_FILE_FLAG "--cmd_file=")
+
+  set(CMAKE_INCLUDE_FLAG_${lang} "--include_path=")
+  set(CMAKE_DEPFILE_FLAGS_${lang} "--preproc_with_compile --preproc_dependency=<DEPFILE>")
+
+  set(CMAKE_${lang}_CREATE_PREPROCESSED_SOURCE "<CMAKE_${lang}_COMPILER> --preproc_only --${prefix}_file=<SOURCE> <DEFINES> <INCLUDES> <FLAGS> --output_file=<PREPROCESSED_SOURCE>")
+  set(CMAKE_${lang}_CREATE_ASSEMBLY_SOURCE     "<CMAKE_${lang}_COMPILER> --compile_only --skip_assembler --${prefix}_file=<SOURCE> <DEFINES> <INCLUDES> <FLAGS> --output_file=<ASSEMBLY_SOURCE>")
+
+  set(CMAKE_${lang}_COMPILE_OBJECT  "<CMAKE_${lang}_COMPILER> --compile_only --${prefix}_file=<SOURCE> <DEFINES> <INCLUDES> <FLAGS> --output_file=<OBJECT>")
+
+  set(CMAKE_${lang}_ARCHIVE_CREATE "<CMAKE_AR> qr <TARGET> <OBJECTS>")
+  set(CMAKE_${lang}_ARCHIVE_APPEND "<CMAKE_AR> qa <TARGET> <OBJECTS>")
+  set(CMAKE_${lang}_ARCHIVE_FINISH "")
+
+  # After the --run_linker flag a response file is not possible
+  set(CMAKE_${lang}_RESPONSE_FILE_LINK_FLAG "")
+  set(CMAKE_${lang}_USE_RESPONSE_FILE_FOR_LIBRARIES 0)
+  set(CMAKE_${lang}_USE_RESPONSE_FILE_FOR_OBJECTS 0)
+
+  set(CMAKE_${lang}_LINK_EXECUTABLE "<CMAKE_${lang}_COMPILER> <FLAGS> --run_linker --output_file=<TARGET> --map_file=<TARGET_NAME>.map <CMAKE_${lang}_LINK_FLAGS> <LINK_FLAGS> <OBJECTS> <LINK_LIBRARIES>")
+endmacro()
+
+set(CMAKE_LIBRARY_PATH_FLAG "--search_path=")
+set(CMAKE_LINK_LIBRARY_FLAG "--library=")
diff --git a/Modules/Compiler/XL-C.cmake b/Modules/Compiler/XL-C.cmake
index 2077bda..78c44d5 100644
--- a/Modules/Compiler/XL-C.cmake
+++ b/Modules/Compiler/XL-C.cmake
@@ -6,6 +6,8 @@
 # -qthreaded = Ensures that all optimizations will be thread-safe
 string(APPEND CMAKE_C_FLAGS_INIT " -qthreaded")
 
+set(CMAKE_C_COMPILE_OPTIONS_EXPLICIT_LANGUAGE -qsourcetype=c)
+
 if (CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 10.1)
   set(CMAKE_C90_STANDARD_COMPILE_OPTION "-qlanglvl=stdc89")
   set(CMAKE_C90_EXTENSION_COMPILE_OPTION "-qlanglvl=extc89")
diff --git a/Modules/Compiler/XL-CXX.cmake b/Modules/Compiler/XL-CXX.cmake
index 41e3e11..3b911f3 100644
--- a/Modules/Compiler/XL-CXX.cmake
+++ b/Modules/Compiler/XL-CXX.cmake
@@ -6,6 +6,8 @@
 # -qthreaded = Ensures that all optimizations will be thread-safe
 string(APPEND CMAKE_CXX_FLAGS_INIT " -qthreaded")
 
+set(CMAKE_CXX_COMPILE_OPTIONS_EXPLICIT_LANGUAGE -+)
+
 if (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 10.1)
   if(CMAKE_SYSTEM MATCHES "Linux")
     set(CMAKE_CXX98_STANDARD_COMPILE_OPTION "")
@@ -32,6 +34,3 @@
 endif ()
 
 __compiler_check_default_language_standard(CXX 10.1 98)
-
-set(CMAKE_CXX_COMPILE_OBJECT
-  "<CMAKE_CXX_COMPILER> -+ <DEFINES> <INCLUDES> <FLAGS> -o <OBJECT> -c <SOURCE>")
diff --git a/Modules/Compiler/XL-Fortran.cmake b/Modules/Compiler/XL-Fortran.cmake
index 1683dff..cc15e65 100644
--- a/Modules/Compiler/XL-Fortran.cmake
+++ b/Modules/Compiler/XL-Fortran.cmake
@@ -8,6 +8,7 @@
 set(CMAKE_Fortran_FORMAT_FREE_FLAG "-qfree") # [=f90|ibm]
 
 set(CMAKE_Fortran_MODDIR_FLAG "-qmoddir=")
+set(CMAKE_Fortran_MODDIR_INCLUDE_FLAG "-I") # -qmoddir= does not affect search path
 
 set(CMAKE_Fortran_DEFINE_FLAG "-WF,-D")
 
@@ -22,3 +23,8 @@
 set(CMAKE_Fortran_PREPROCESS_SOURCE
   "<CMAKE_Fortran_COMPILER> <DEFINES> <INCLUDES> <FLAGS> -qpreprocess -qnoobject -qsuppress=1517-020 -tF -B \"${CMAKE_CURRENT_LIST_DIR}/XL-Fortran/\" -WF,--cpp,\"${CMAKE_Fortran_XL_CPP}\",--out,<PREPROCESSED_SOURCE> <SOURCE>"
   )
+
+if (NOT CMAKE_Fortran_COMPILER_VERSION VERSION_LESS 15.1.6)
+  set(CMAKE_Fortran_COMPILE_OPTIONS_PREPROCESS_ON "-qpreprocess")
+  set(CMAKE_Fortran_COMPILE_OPTIONS_PREPROCESS_OFF "-qnopreprocess")
+endif()
diff --git a/Modules/Compiler/XLClang-C.cmake b/Modules/Compiler/XLClang-C.cmake
index 54c18a6..1668a4d 100644
--- a/Modules/Compiler/XLClang-C.cmake
+++ b/Modules/Compiler/XLClang-C.cmake
@@ -1,6 +1,8 @@
 include(Compiler/XLClang)
 __compiler_xlclang(C)
 
+set(CMAKE_C_COMPILE_OPTIONS_EXPLICIT_LANGUAGE -x c)
+
 if (CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 13.1.1)
   set(CMAKE_C90_STANDARD_COMPILE_OPTION  "-std=c89")
   set(CMAKE_C90_EXTENSION_COMPILE_OPTION "-std=gnu89")
diff --git a/Modules/Compiler/XLClang-CXX.cmake b/Modules/Compiler/XLClang-CXX.cmake
index 9ea3d7c..02638c7 100644
--- a/Modules/Compiler/XLClang-CXX.cmake
+++ b/Modules/Compiler/XLClang-CXX.cmake
@@ -1,6 +1,8 @@
 include(Compiler/XLClang)
 __compiler_xlclang(CXX)
 
+set(CMAKE_CXX_COMPILE_OPTIONS_EXPLICIT_LANGUAGE -x c++)
+
 if (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 13.1.1)
   set(CMAKE_CXX98_STANDARD_COMPILE_OPTION  "")
   set(CMAKE_CXX98_EXTENSION_COMPILE_OPTION "")
diff --git a/Modules/CompilerId/VS-10.vcxproj.in b/Modules/CompilerId/VS-10.vcxproj.in
index b48a332..3598fc7 100644
--- a/Modules/CompilerId/VS-10.vcxproj.in
+++ b/Modules/CompilerId/VS-10.vcxproj.in
@@ -9,7 +9,7 @@
   <PropertyGroup Label="Globals">
     <ProjectGuid>{CAE07175-D007-4FC3-BFE8-47B392814159}</ProjectGuid>
     <RootNamespace>CompilerId@id_lang@</RootNamespace>
-    <Keyword>Win32Proj</Keyword>
+    <Keyword>@id_keyword@</Keyword>
     @id_system@
     @id_system_version@
     @id_WindowsTargetPlatformVersion@
@@ -24,7 +24,7 @@
     @id_PreferredToolArchitecture@
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|@id_platform@'" Label="Configuration">
-    <ConfigurationType>Application</ConfigurationType>
+    <ConfigurationType>@id_config_type@</ConfigurationType>
     @id_toolset@
     <CharacterSet>MultiByte</CharacterSet>
   </PropertyGroup>
diff --git a/Modules/CompilerId/Xcode-3.pbxproj.in b/Modules/CompilerId/Xcode-3.pbxproj.in
index 672044e..6fe17e5 100644
--- a/Modules/CompilerId/Xcode-3.pbxproj.in
+++ b/Modules/CompilerId/Xcode-3.pbxproj.in
@@ -84,6 +84,7 @@
 				CODE_SIGNING_REQUIRED = NO;
 				CONFIGURATION_BUILD_DIR = "$(BUILD_DIR)";
 				SYMROOT = .;
+				@id_archs@
 				@id_toolset@
 				@id_lang_version@
 				@id_clang_cxx_library@
diff --git a/Modules/Documentation.cmake b/Modules/Documentation.cmake
index aaf24f6..c297231 100644
--- a/Modules/Documentation.cmake
+++ b/Modules/Documentation.cmake
@@ -9,6 +9,30 @@
 relies on several tools (Doxygen, Perl, etc).
 #]=======================================================================]
 
+cmake_policy(GET CMP0106 _Documentation_policy)
+
+if (_Documentation_policy STREQUAL "NEW")
+  message(FATAL_ERROR
+    "Documentation.cmake is VTK-specific code and should not be used in "
+    "non-VTK projects. This logic in this module is best shipped with the "
+    "project using it rather than with CMake. This is now an error according "
+    "to policy CMP0106.")
+else ()
+
+if (_Documentation_policy STREQUAL "")
+  # Ignore the warning if the project is detected as VTK itself.
+  if (NOT CMAKE_PROJECT_NAME STREQUAL "VTK" AND
+      NOT PROJECT_NAME STREQUAL "VTK")
+    cmake_policy(GET_WARNING CMP0106 _Documentation_policy_warning)
+    message(AUTHOR_WARNING
+      "${_Documentation_policy_warning}\n"
+      "Documentation.cmake is VTK-specific code and should not be used in "
+      "non-VTK projects. This logic in this module is best shipped with the "
+      "project using it rather than with CMake.")
+  endif ()
+  unset(_Documentation_policy_warning)
+endif ()
+
 #
 # Build the documentation ?
 #
@@ -44,3 +68,7 @@
   #
 
 endif ()
+
+endif ()
+
+unset(_Documentation_policy)
diff --git a/Modules/ExternalProject-gitupdate.cmake.in b/Modules/ExternalProject-gitupdate.cmake.in
new file mode 100644
index 0000000..eff39c1
--- /dev/null
+++ b/Modules/ExternalProject-gitupdate.cmake.in
@@ -0,0 +1,216 @@
+# Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
+# file Copyright.txt or https://cmake.org/licensing for details.
+
+cmake_minimum_required(VERSION 3.5)
+
+execute_process(
+  COMMAND "@git_EXECUTABLE@" rev-list --max-count=1 HEAD
+  WORKING_DIRECTORY "@work_dir@"
+  RESULT_VARIABLE error_code
+  OUTPUT_VARIABLE head_sha
+  OUTPUT_STRIP_TRAILING_WHITESPACE
+  )
+if(error_code)
+  message(FATAL_ERROR "Failed to get the hash for HEAD")
+endif()
+
+execute_process(
+  COMMAND "@git_EXECUTABLE@" show-ref "@git_tag@"
+  WORKING_DIRECTORY "@work_dir@"
+  OUTPUT_VARIABLE show_ref_output
+  )
+# If a remote ref is asked for, which can possibly move around,
+# we must always do a fetch and checkout.
+if("${show_ref_output}" MATCHES "remotes")
+  set(is_remote_ref 1)
+else()
+  set(is_remote_ref 0)
+endif()
+
+# Tag is in the form <remote>/<tag> (i.e. origin/master) we must strip
+# the remote from the tag.
+if("${show_ref_output}" MATCHES "refs/remotes/@git_tag@")
+  string(REGEX MATCH "^([^/]+)/(.+)$" _unused "@git_tag@")
+  set(git_remote "${CMAKE_MATCH_1}")
+  set(git_tag "${CMAKE_MATCH_2}")
+else()
+  set(git_remote "@git_remote_name@")
+  set(git_tag "@git_tag@")
+endif()
+
+# This will fail if the tag does not exist (it probably has not been fetched
+# yet).
+execute_process(
+  COMMAND "@git_EXECUTABLE@" rev-list --max-count=1 "${git_tag}"
+  WORKING_DIRECTORY "@work_dir@"
+  RESULT_VARIABLE error_code
+  OUTPUT_VARIABLE tag_sha
+  OUTPUT_STRIP_TRAILING_WHITESPACE
+  )
+
+# Is the hash checkout out that we want?
+if(error_code OR is_remote_ref OR NOT ("${tag_sha}" STREQUAL "${head_sha}"))
+  execute_process(
+    COMMAND "@git_EXECUTABLE@" fetch
+    WORKING_DIRECTORY "@work_dir@"
+    RESULT_VARIABLE error_code
+    )
+  if(error_code)
+    message(FATAL_ERROR "Failed to fetch repository '@git_repository@'")
+  endif()
+
+  if(is_remote_ref)
+    # Check if stash is needed
+    execute_process(
+      COMMAND "@git_EXECUTABLE@" status --porcelain
+      WORKING_DIRECTORY "@work_dir@"
+      RESULT_VARIABLE error_code
+      OUTPUT_VARIABLE repo_status
+      )
+    if(error_code)
+      message(FATAL_ERROR "Failed to get the status")
+    endif()
+    string(LENGTH "${repo_status}" need_stash)
+
+    # If not in clean state, stash changes in order to be able to perform a
+    # rebase or checkout without losing those changes permanently
+    if(need_stash)
+      execute_process(
+        COMMAND "@git_EXECUTABLE@" stash save @git_stash_save_options@
+        WORKING_DIRECTORY "@work_dir@"
+        RESULT_VARIABLE error_code
+        )
+      if(error_code)
+        message(FATAL_ERROR "Failed to stash changes")
+      endif()
+    endif()
+
+    if("@git_update_strategy@" STREQUAL "CHECKOUT")
+      execute_process(
+        COMMAND "@git_EXECUTABLE@" checkout "${git_remote}/${git_tag}"
+        WORKING_DIRECTORY "@work_dir@"
+        RESULT_VARIABLE error_code
+        )
+      if(error_code)
+        message(FATAL_ERROR "Failed to checkout tag: '${git_remote}/${git_tag}'")
+      endif()
+    else()
+      # Pull changes from the remote branch
+      execute_process(
+        COMMAND "@git_EXECUTABLE@" rebase "${git_remote}/${git_tag}"
+        WORKING_DIRECTORY "@work_dir@"
+        RESULT_VARIABLE error_code
+        OUTPUT_VARIABLE rebase_output
+        ERROR_VARIABLE  rebase_output
+        )
+      if(error_code)
+        # Rebase failed, undo the rebase attempt before continuing
+        execute_process(
+          COMMAND "@git_EXECUTABLE@" rebase --abort
+          WORKING_DIRECTORY "@work_dir@"
+        )
+
+        if(NOT "@git_update_strategy@" STREQUAL "REBASE_CHECKOUT")
+          # Not allowed to do a checkout as a fallback, so cannot proceed
+          if(need_stash)
+            execute_process(
+              COMMAND "@git_EXECUTABLE@" stash pop --index --quiet
+              WORKING_DIRECTORY "@work_dir@"
+              )
+          endif()
+          message(FATAL_ERROR "\nFailed to rebase in: '@work_dir@'."
+                              "\nOutput from the attempted rebase follows:"
+                              "\n${rebase_output}"
+                              "\n\nYou will have to resolve the conflicts manually")
+        endif()
+
+        # Fall back to checkout. We create an annotated tag so that the user
+        # can manually inspect the situation and revert if required.
+        # We can't log the failed rebase output because MSVC sees it and
+        # intervenes, causing the build to fail even though it completes.
+        # Write it to a file instead.
+        string(TIMESTAMP tag_timestamp "%Y%m%dT%H%M%S" UTC)
+        set(tag_name _cmake_ExternalProject_moved_from_here_${tag_timestamp}Z)
+        set(error_log_file ${CMAKE_CURRENT_LIST_DIR}/rebase_error_${tag_timestamp}Z.log)
+        file(WRITE ${error_log_file} "${rebase_output}")
+        message(WARNING "Rebase failed, output has been saved to ${error_log_file}"
+                        "\nFalling back to checkout, previous commit tagged as ${tag_name}")
+        execute_process(
+          COMMAND "@git_EXECUTABLE@" tag -a
+                  -m "ExternalProject attempting to move from here to ${git_remote}/${git_tag}"
+                  ${tag_name}
+          WORKING_DIRECTORY "@work_dir@"
+          RESULT_VARIABLE error_code
+        )
+        if(error_code)
+          message(FATAL_ERROR "Failed to add marker tag")
+        endif()
+
+        execute_process(
+          COMMAND "@git_EXECUTABLE@" checkout "${git_remote}/${git_tag}"
+          WORKING_DIRECTORY "@work_dir@"
+          RESULT_VARIABLE error_code
+        )
+        if(error_code)
+          message(FATAL_ERROR "Failed to checkout : '${git_remote}/${git_tag}'")
+        endif()
+
+      endif()
+    endif()
+
+    if(need_stash)
+      execute_process(
+        COMMAND "@git_EXECUTABLE@" stash pop --index --quiet
+        WORKING_DIRECTORY "@work_dir@"
+        RESULT_VARIABLE error_code
+        )
+      if(error_code)
+        # Stash pop --index failed: Try again dropping the index
+        execute_process(
+          COMMAND "@git_EXECUTABLE@" reset --hard --quiet
+          WORKING_DIRECTORY "@work_dir@"
+          RESULT_VARIABLE error_code
+          )
+        execute_process(
+          COMMAND "@git_EXECUTABLE@" stash pop --quiet
+          WORKING_DIRECTORY "@work_dir@"
+          RESULT_VARIABLE error_code
+          )
+        if(error_code)
+          # Stash pop failed: Restore previous state.
+          execute_process(
+            COMMAND "@git_EXECUTABLE@" reset --hard --quiet ${head_sha}
+            WORKING_DIRECTORY "@work_dir@"
+          )
+          execute_process(
+            COMMAND "@git_EXECUTABLE@" stash pop --index --quiet
+            WORKING_DIRECTORY "@work_dir@"
+          )
+          message(FATAL_ERROR "\nFailed to unstash changes in: '@work_dir@'."
+                              "\nYou will have to resolve the conflicts manually")
+        endif()
+      endif()
+    endif()
+  else()
+    execute_process(
+      COMMAND "@git_EXECUTABLE@" checkout "${git_tag}"
+      WORKING_DIRECTORY "@work_dir@"
+      RESULT_VARIABLE error_code
+      )
+    if(error_code)
+      message(FATAL_ERROR "Failed to checkout tag: '${git_tag}'")
+    endif()
+  endif()
+
+  set(init_submodules "@init_submodules@")
+  if(init_submodules)
+    execute_process(
+      COMMAND "@git_EXECUTABLE@" submodule update @git_submodules_recurse@ --init @git_submodules@
+      WORKING_DIRECTORY "@work_dir@"
+      RESULT_VARIABLE error_code
+      )
+  endif()
+  if(error_code)
+    message(FATAL_ERROR "Failed to update submodules in: '@work_dir@'")
+  endif()
+endif()
diff --git a/Modules/ExternalProject.cmake b/Modules/ExternalProject.cmake
index 12a91b3..aecc00b 100644
--- a/Modules/ExternalProject.cmake
+++ b/Modules/ExternalProject.cmake
@@ -9,8 +9,11 @@
 
    .. contents::
 
+Commands
+^^^^^^^^
+
 External Project Definition
-^^^^^^^^^^^^^^^^^^^^^^^^^^^
+"""""""""""""""""""""""""""
 
 .. command:: ExternalProject_Add
 
@@ -291,6 +294,42 @@
         ``git clone`` command line, with each option required to be in the
         form ``key=value``.
 
+      ``GIT_REMOTE_UPDATE_STRATEGY <strategy>``
+        When ``GIT_TAG`` refers to a remote branch, this option can be used to
+        specify how the update step behaves.  The ``<strategy>`` must be one of
+        the following:
+
+        ``CHECKOUT``
+          Ignore the local branch and always checkout the branch specified by
+          ``GIT_TAG``.
+
+        ``REBASE``
+          Try to rebase the current branch to the one specified by ``GIT_TAG``.
+          If there are local uncommitted changes, they will be stashed first
+          and popped again after rebasing.  If rebasing or popping stashed
+          changes fail, abort the rebase and halt with an error.
+          When ``GIT_REMOTE_UPDATE_STRATEGY`` is not present, this is the
+          default strategy unless the default has been overridden with
+          ``CMAKE_EP_GIT_REMOTE_UPDATE_STRATEGY`` (see below).
+
+        ``REBASE_CHECKOUT``
+          Same as ``REBASE`` except if the rebase fails, an annotated tag will
+          be created at the original ``HEAD`` position from before the rebase
+          and then checkout ``GIT_TAG`` just like the ``CHECKOUT`` strategy.
+          The message stored on the annotated tag will give information about
+          what was attempted and the tag name will include a timestamp so that
+          each failed run will add a new tag.  This strategy ensures no changes
+          will be lost, but updates should always succeed if ``GIT_TAG`` refers
+          to a valid ref unless there are uncommitted changes that cannot be
+          popped successfully.
+
+        The variable ``CMAKE_EP_GIT_REMOTE_UPDATE_STRATEGY`` can be set to
+        override the default strategy.  This variable should not be set by a
+        project, it is intended for the user to set.  It is primarily intended
+        for use in continuous integration scripts to ensure that when history
+        is rewritten on a remote branch, the build doesn't end up with unintended
+        changes or failed builds resulting from conflicts during rebase operations.
+
     *Subversion*
       ``SVN_REPOSITORY <url>``
         URL of the Subversion repository.
@@ -665,7 +704,7 @@
   automatic substitutions that are supported for some options.
 
 Obtaining Project Properties
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+""""""""""""""""""""""""""""
 
 .. command:: ExternalProject_Get_Property
 
@@ -686,7 +725,7 @@
     message("Source dir of myExtProj = ${SOURCE_DIR}")
 
 Explicit Step Management
-^^^^^^^^^^^^^^^^^^^^^^^^
+""""""""""""""""""""""""
 
 The ``ExternalProject_Add()`` function on its own is often sufficient for
 incorporating an external project into the main build. Certain scenarios
@@ -935,6 +974,7 @@
 
 cmake_policy(PUSH)
 cmake_policy(SET CMP0054 NEW) # if() quoted variables not dereferenced
+cmake_policy(SET CMP0057 NEW) # if() supports IN_LIST
 
 # Pre-compute a regex to match documented keywords for each command.
 math(EXPR _ep_documentation_line_count "${CMAKE_CURRENT_LIST_LINE} - 4")
@@ -1084,7 +1124,11 @@
     message(FATAL_ERROR "Tag for git checkout should not be empty.")
   endif()
 
-  set(git_clone_options "--no-checkout")
+  if(GIT_VERSION_STRING VERSION_LESS 2.20 OR 2.21 VERSION_LESS_EQUAL GIT_VERSION_STRING)
+    set(git_clone_options "--no-checkout")
+  else()
+    set(git_clone_options)
+  endif()
   if(git_shallow)
     if(NOT GIT_VERSION_STRING VERSION_LESS 1.7.10)
       list(APPEND git_clone_options "--depth 1 --no-single-branch")
@@ -1239,7 +1283,7 @@
 endfunction()
 
 
-function(_ep_write_gitupdate_script script_filename git_EXECUTABLE git_tag git_remote_name init_submodules git_submodules_recurse git_submodules git_repository work_dir)
+function(_ep_write_gitupdate_script script_filename git_EXECUTABLE git_tag git_remote_name init_submodules git_submodules_recurse git_submodules git_repository work_dir git_update_strategy)
   if("${git_tag}" STREQUAL "")
     message(FATAL_ERROR "Tag for git checkout should not be empty.")
   endif()
@@ -1248,171 +1292,13 @@
   else()
     set(git_stash_save_options --quiet)
   endif()
-  file(WRITE ${script_filename}
-"
-execute_process(
-  COMMAND \"${git_EXECUTABLE}\" rev-list --max-count=1 HEAD
-  WORKING_DIRECTORY \"${work_dir}\"
-  RESULT_VARIABLE error_code
-  OUTPUT_VARIABLE head_sha
-  OUTPUT_STRIP_TRAILING_WHITESPACE
+
+  configure_file(
+      "${_ExternalProject_SELF_DIR}/ExternalProject-gitupdate.cmake.in"
+      "${script_filename}"
+      @ONLY
   )
-if(error_code)
-  message(FATAL_ERROR \"Failed to get the hash for HEAD\")
-endif()
-
-execute_process(
-  COMMAND \"${git_EXECUTABLE}\" show-ref ${git_tag}
-  WORKING_DIRECTORY \"${work_dir}\"
-  OUTPUT_VARIABLE show_ref_output
-  )
-# If a remote ref is asked for, which can possibly move around,
-# we must always do a fetch and checkout.
-if(\"\${show_ref_output}\" MATCHES \"remotes\")
-  set(is_remote_ref 1)
-else()
-  set(is_remote_ref 0)
-endif()
-
-# Tag is in the form <remote>/<tag> (i.e. origin/master) we must strip
-# the remote from the tag.
-if(\"\${show_ref_output}\" MATCHES \"refs/remotes/${git_tag}\")
-  string(REGEX MATCH \"^([^/]+)/(.+)$\" _unused \"${git_tag}\")
-  set(git_remote \"\${CMAKE_MATCH_1}\")
-  set(git_tag \"\${CMAKE_MATCH_2}\")
-else()
-  set(git_remote \"${git_remote_name}\")
-  set(git_tag \"${git_tag}\")
-endif()
-
-# This will fail if the tag does not exist (it probably has not been fetched
-# yet).
-execute_process(
-  COMMAND \"${git_EXECUTABLE}\" rev-list --max-count=1 ${git_tag}
-  WORKING_DIRECTORY \"${work_dir}\"
-  RESULT_VARIABLE error_code
-  OUTPUT_VARIABLE tag_sha
-  OUTPUT_STRIP_TRAILING_WHITESPACE
-  )
-
-# Is the hash checkout out that we want?
-if(error_code OR is_remote_ref OR NOT (\"\${tag_sha}\" STREQUAL \"\${head_sha}\"))
-  execute_process(
-    COMMAND \"${git_EXECUTABLE}\" fetch
-    WORKING_DIRECTORY \"${work_dir}\"
-    RESULT_VARIABLE error_code
-    )
-  if(error_code)
-    message(FATAL_ERROR \"Failed to fetch repository '${git_repository}'\")
-  endif()
-
-  if(is_remote_ref)
-    # Check if stash is needed
-    execute_process(
-      COMMAND \"${git_EXECUTABLE}\" status --porcelain
-      WORKING_DIRECTORY \"${work_dir}\"
-      RESULT_VARIABLE error_code
-      OUTPUT_VARIABLE repo_status
-      )
-    if(error_code)
-      message(FATAL_ERROR \"Failed to get the status\")
-    endif()
-    string(LENGTH \"\${repo_status}\" need_stash)
-
-    # If not in clean state, stash changes in order to be able to be able to
-    # perform git pull --rebase
-    if(need_stash)
-      execute_process(
-        COMMAND \"${git_EXECUTABLE}\" stash save ${git_stash_save_options}
-        WORKING_DIRECTORY \"${work_dir}\"
-        RESULT_VARIABLE error_code
-        )
-      if(error_code)
-        message(FATAL_ERROR \"Failed to stash changes\")
-      endif()
-    endif()
-
-    # Pull changes from the remote branch
-    execute_process(
-      COMMAND \"${git_EXECUTABLE}\" rebase \${git_remote}/\${git_tag}
-      WORKING_DIRECTORY \"${work_dir}\"
-      RESULT_VARIABLE error_code
-      )
-    if(error_code)
-      # Rebase failed: Restore previous state.
-      execute_process(
-        COMMAND \"${git_EXECUTABLE}\" rebase --abort
-        WORKING_DIRECTORY \"${work_dir}\"
-      )
-      if(need_stash)
-        execute_process(
-          COMMAND \"${git_EXECUTABLE}\" stash pop --index --quiet
-          WORKING_DIRECTORY \"${work_dir}\"
-          )
-      endif()
-      message(FATAL_ERROR \"\\nFailed to rebase in: '${work_dir}/${src_name}'.\\nYou will have to resolve the conflicts manually\")
-    endif()
-
-    if(need_stash)
-      execute_process(
-        COMMAND \"${git_EXECUTABLE}\" stash pop --index --quiet
-        WORKING_DIRECTORY \"${work_dir}\"
-        RESULT_VARIABLE error_code
-        )
-      if(error_code)
-        # Stash pop --index failed: Try again dropping the index
-        execute_process(
-          COMMAND \"${git_EXECUTABLE}\" reset --hard --quiet
-          WORKING_DIRECTORY \"${work_dir}\"
-          RESULT_VARIABLE error_code
-          )
-        execute_process(
-          COMMAND \"${git_EXECUTABLE}\" stash pop --quiet
-          WORKING_DIRECTORY \"${work_dir}\"
-          RESULT_VARIABLE error_code
-          )
-        if(error_code)
-          # Stash pop failed: Restore previous state.
-          execute_process(
-            COMMAND \"${git_EXECUTABLE}\" reset --hard --quiet \${head_sha}
-            WORKING_DIRECTORY \"${work_dir}\"
-          )
-          execute_process(
-            COMMAND \"${git_EXECUTABLE}\" stash pop --index --quiet
-            WORKING_DIRECTORY \"${work_dir}\"
-          )
-          message(FATAL_ERROR \"\\nFailed to unstash changes in: '${work_dir}/${src_name}'.\\nYou will have to resolve the conflicts manually\")
-        endif()
-      endif()
-    endif()
-  else()
-    execute_process(
-      COMMAND \"${git_EXECUTABLE}\" checkout ${git_tag}
-      WORKING_DIRECTORY \"${work_dir}\"
-      RESULT_VARIABLE error_code
-      )
-    if(error_code)
-      message(FATAL_ERROR \"Failed to checkout tag: '${git_tag}'\")
-    endif()
-  endif()
-
-  set(init_submodules ${init_submodules})
-  if(init_submodules)
-    execute_process(
-      COMMAND \"${git_EXECUTABLE}\" submodule update ${git_submodules_recurse} --init ${git_submodules}
-      WORKING_DIRECTORY \"${work_dir}/${src_name}\"
-      RESULT_VARIABLE error_code
-      )
-  endif()
-  if(error_code)
-    message(FATAL_ERROR \"Failed to update submodules in: '${work_dir}/${src_name}'\")
-  endif()
-endif()
-
-"
-)
-
-endfunction(_ep_write_gitupdate_script)
+endfunction()
 
 function(_ep_write_downloadfile_script script_filename REMOTE LOCAL timeout no_progress hash tls_verify tls_cainfo userpwd http_headers netrc netrc_file)
   if(timeout)
@@ -1905,7 +1791,11 @@
     get_target_property(args ${name} _EP_${step}_ARGS)
   endif()
 
-  list(APPEND cmd ${args})
+  if(NOT "${args}" STREQUAL "")
+    # args could have empty items, so we must quote it to prevent them
+    # from being silently removed
+    list(APPEND cmd "${args}")
+  endif()
   set(${cmd_var} "${cmd}" PARENT_SCOPE)
 endfunction()
 
@@ -2221,17 +2111,23 @@
     set(command ${CMAKE_COMMAND} -E echo_append)
   endif()
 
-  add_custom_command(
-    OUTPUT ${stamp_file}
-    BYPRODUCTS ${byproducts}
-    COMMENT ${comment}
-    COMMAND ${command}
-    COMMAND ${touch}
-    DEPENDS ${depends}
-    WORKING_DIRECTORY ${work_dir}
-    VERBATIM
-    ${uses_terminal}
-    )
+  set(__cmdQuoted)
+  foreach(__item IN LISTS command)
+    string(APPEND __cmdQuoted " [==[${__item}]==]")
+  endforeach()
+  cmake_language(EVAL CODE "
+    add_custom_command(
+      OUTPUT \${stamp_file}
+      BYPRODUCTS \${byproducts}
+      COMMENT \${comment}
+      COMMAND ${__cmdQuoted}
+      COMMAND \${touch}
+      DEPENDS \${depends}
+      WORKING_DIRECTORY \${work_dir}
+      VERBATIM
+      ${uses_terminal}
+    )"
+  )
   set_property(TARGET ${name} APPEND PROPERTY _EP_STEPS ${step})
 
   # Add custom "step target"?
@@ -2279,7 +2175,7 @@
 
   get_property(steps TARGET ${name} PROPERTY _EP_STEPS)
   list(FIND steps ${step} is_step)
-  if(NOT is_step)
+  if(is_step LESS 0)
     message(FATAL_ERROR "External project \"${name}\" does not have a step \"${step}\".")
   endif()
 
@@ -2686,17 +2582,32 @@
     set(uses_terminal "")
   endif()
 
-  ExternalProject_Add_Step(${name} download
-    COMMENT ${comment}
-    COMMAND ${cmd}
-    WORKING_DIRECTORY ${work_dir}
-    DEPENDS ${depends}
-    DEPENDEES mkdir
-    ${log}
-    ${uses_terminal}
-    )
+  set(__cmdQuoted)
+  foreach(__item IN LISTS cmd)
+    string(APPEND __cmdQuoted " [==[${__item}]==]")
+  endforeach()
+  cmake_language(EVAL CODE "
+    ExternalProject_Add_Step(\${name} download
+      COMMENT \${comment}
+      COMMAND ${__cmdQuoted}
+      WORKING_DIRECTORY \${work_dir}
+      DEPENDS \${depends}
+      DEPENDEES mkdir
+      ${log}
+      ${uses_terminal}
+      )"
+  )
 endfunction()
 
+function(_ep_get_update_disconnected var name)
+  get_property(update_disconnected_set TARGET ${name} PROPERTY _EP_UPDATE_DISCONNECTED SET)
+  if(update_disconnected_set)
+    get_property(update_disconnected TARGET ${name} PROPERTY _EP_UPDATE_DISCONNECTED)
+  else()
+    get_property(update_disconnected DIRECTORY PROPERTY EP_UPDATE_DISCONNECTED)
+  endif()
+  set(${var} "${update_disconnected}" PARENT_SCOPE)
+endfunction()
 
 function(_ep_add_update_command name)
   ExternalProject_Get_Property(${name} source_dir tmp_dir)
@@ -2707,12 +2618,8 @@
   get_property(svn_repository TARGET ${name} PROPERTY _EP_SVN_REPOSITORY)
   get_property(git_repository TARGET ${name} PROPERTY _EP_GIT_REPOSITORY)
   get_property(hg_repository  TARGET ${name} PROPERTY _EP_HG_REPOSITORY )
-  get_property(update_disconnected_set TARGET ${name} PROPERTY _EP_UPDATE_DISCONNECTED SET)
-  if(update_disconnected_set)
-    get_property(update_disconnected TARGET ${name} PROPERTY _EP_UPDATE_DISCONNECTED)
-  else()
-    get_property(update_disconnected DIRECTORY PROPERTY EP_UPDATE_DISCONNECTED)
-  endif()
+
+  _ep_get_update_disconnected(update_disconnected ${name})
 
   set(work_dir)
   set(comment)
@@ -2781,10 +2688,22 @@
       endif()
     endif()
 
+    get_property(git_update_strategy TARGET ${name} PROPERTY _EP_GIT_REMOTE_UPDATE_STRATEGY)
+    if(NOT git_update_strategy)
+      set(git_update_strategy "${CMAKE_EP_GIT_REMOTE_UPDATE_STRATEGY}")
+    endif()
+    if(NOT git_update_strategy)
+      set(git_update_strategy REBASE)
+    endif()
+    set(strategies CHECKOUT REBASE REBASE_CHECKOUT)
+    if(NOT git_update_strategy IN_LIST strategies)
+      message(FATAL_ERROR "'${git_update_strategy}' is not one of the supported strategies: ${strategies}")
+    endif()
+
     _ep_get_git_submodules_recurse(git_submodules_recurse)
 
     _ep_write_gitupdate_script(${tmp_dir}/${name}-gitupdate.cmake
-      ${GIT_EXECUTABLE} ${git_tag} ${git_remote_name} ${git_init_submodules} "${git_submodules_recurse}" "${git_submodules}" ${git_repository} ${work_dir}
+      ${GIT_EXECUTABLE} ${git_tag} ${git_remote_name} ${git_init_submodules} "${git_submodules_recurse}" "${git_submodules}" ${git_repository} ${work_dir} ${git_update_strategy}
       )
     set(cmd ${CMAKE_COMMAND} -P ${tmp_dir}/${name}-gitupdate.cmake)
     set(always 1)
@@ -2826,16 +2745,22 @@
     set(uses_terminal "")
   endif()
 
-  ExternalProject_Add_Step(${name} update
-    COMMENT ${comment}
-    COMMAND ${cmd}
-    ALWAYS ${always}
-    EXCLUDE_FROM_MAIN ${update_disconnected}
-    WORKING_DIRECTORY ${work_dir}
-    DEPENDEES download
-    ${log}
-    ${uses_terminal}
-    )
+  set(__cmdQuoted)
+  foreach(__item IN LISTS cmd)
+    string(APPEND __cmdQuoted " [==[${__item}]==]")
+  endforeach()
+  cmake_language(EVAL CODE "
+    ExternalProject_Add_Step(${name} update
+      COMMENT \${comment}
+      COMMAND ${__cmdQuoted}
+      ALWAYS \${always}
+      EXCLUDE_FROM_MAIN \${update_disconnected}
+      WORKING_DIRECTORY \${work_dir}
+      DEPENDEES download
+      ${log}
+      ${uses_terminal}
+      )"
+  )
 
   if(update_disconnected)
     _ep_get_step_stampfile(${name} skip-update skip-update_stamp_file)
@@ -2874,12 +2799,25 @@
     set(log "")
   endif()
 
-  ExternalProject_Add_Step(${name} patch
-    COMMAND ${cmd}
-    WORKING_DIRECTORY ${work_dir}
-    DEPENDEES download
-    ${log}
-    )
+  _ep_get_update_disconnected(update_disconnected ${name})
+  if(update_disconnected)
+    set(update_dep skip-update)
+  else()
+    set(update_dep update)
+  endif()
+
+  set(__cmdQuoted)
+  foreach(__item IN LISTS cmd)
+    string(APPEND __cmdQuoted " [==[${__item}]==]")
+  endforeach()
+  cmake_language(EVAL CODE "
+    ExternalProject_Add_Step(${name} patch
+      COMMAND ${__cmdQuoted}
+      WORKING_DIRECTORY \${work_dir}
+      DEPENDEES download \${update_dep}
+      ${log}
+      )"
+  )
 endfunction()
 
 
@@ -3008,7 +2946,7 @@
 
   # If anything about the configure command changes, (command itself, cmake
   # used, cmake args or cmake generator) then re-run the configure step.
-  # Fixes issue https://gitlab.kitware.com/cmake/cmake/issues/10258
+  # Fixes issue https://gitlab.kitware.com/cmake/cmake/-/issues/10258
   #
   if(NOT EXISTS ${tmp_dir}/${name}-cfgcmd.txt.in)
     file(WRITE ${tmp_dir}/${name}-cfgcmd.txt.in "cmd='\@cmd\@'\n")
@@ -3032,26 +2970,27 @@
     set(uses_terminal "")
   endif()
 
-  get_property(update_disconnected_set TARGET ${name} PROPERTY _EP_UPDATE_DISCONNECTED SET)
-  if(update_disconnected_set)
-    get_property(update_disconnected TARGET ${name} PROPERTY _EP_UPDATE_DISCONNECTED)
-  else()
-    get_property(update_disconnected DIRECTORY PROPERTY EP_UPDATE_DISCONNECTED)
-  endif()
+  _ep_get_update_disconnected(update_disconnected ${name})
   if(update_disconnected)
     set(update_dep skip-update)
   else()
     set(update_dep update)
   endif()
 
-  ExternalProject_Add_Step(${name} configure
-    COMMAND ${cmd}
-    WORKING_DIRECTORY ${binary_dir}
-    DEPENDEES ${update_dep} patch
-    DEPENDS ${file_deps}
-    ${log}
-    ${uses_terminal}
-    )
+  set(__cmdQuoted)
+  foreach(__item IN LISTS cmd)
+    string(APPEND __cmdQuoted " [==[${__item}]==]")
+  endforeach()
+  cmake_language(EVAL CODE "
+    ExternalProject_Add_Step(${name} configure
+      COMMAND ${__cmdQuoted}
+      WORKING_DIRECTORY \${binary_dir}
+      DEPENDEES \${update_dep} patch
+      DEPENDS \${file_deps}
+      ${log}
+      ${uses_terminal}
+      )"
+  )
 endfunction()
 
 
@@ -3089,15 +3028,21 @@
 
   get_property(build_byproducts TARGET ${name} PROPERTY _EP_BUILD_BYPRODUCTS)
 
-  ExternalProject_Add_Step(${name} build
-    COMMAND ${cmd}
-    BYPRODUCTS ${build_byproducts}
-    WORKING_DIRECTORY ${binary_dir}
-    DEPENDEES configure
-    ALWAYS ${always}
-    ${log}
-    ${uses_terminal}
-    )
+  set(__cmdQuoted)
+  foreach(__item IN LISTS cmd)
+    string(APPEND __cmdQuoted " [==[${__item}]==]")
+  endforeach()
+  cmake_language(EVAL CODE "
+    ExternalProject_Add_Step(${name} build
+      COMMAND ${__cmdQuoted}
+      BYPRODUCTS \${build_byproducts}
+      WORKING_DIRECTORY \${binary_dir}
+      DEPENDEES configure
+      ALWAYS \${always}
+      ${log}
+      ${uses_terminal}
+      )"
+  )
 endfunction()
 
 
@@ -3126,13 +3071,19 @@
     set(uses_terminal "")
   endif()
 
-  ExternalProject_Add_Step(${name} install
-    COMMAND ${cmd}
-    WORKING_DIRECTORY ${binary_dir}
-    DEPENDEES build
-    ${log}
-    ${uses_terminal}
-    )
+  set(__cmdQuoted)
+  foreach(__item IN LISTS cmd)
+    string(APPEND __cmdQuoted " [==[${__item}]==]")
+  endforeach()
+  cmake_language(EVAL CODE "
+    ExternalProject_Add_Step(${name} install
+      COMMAND ${__cmdQuoted}
+      WORKING_DIRECTORY \${binary_dir}
+      DEPENDEES build
+      ${log}
+      ${uses_terminal}
+      )"
+  )
 endfunction()
 
 
@@ -3187,15 +3138,21 @@
       set(uses_terminal "")
     endif()
 
-    ExternalProject_Add_Step(${name} test
-      COMMAND ${cmd}
-      WORKING_DIRECTORY ${binary_dir}
-      ${dependees_args}
-      ${dependers_args}
-      ${exclude_args}
-      ${log}
-      ${uses_terminal}
-      )
+    set(__cmdQuoted)
+    foreach(__item IN LISTS cmd)
+      string(APPEND __cmdQuoted " [==[${__item}]==]")
+    endforeach()
+    cmake_language(EVAL CODE "
+      ExternalProject_Add_Step(${name} test
+        COMMAND ${__cmdQuoted}
+        WORKING_DIRECTORY \${binary_dir}
+        ${dependees_args}
+        ${dependers_args}
+        ${exclude_args}
+        ${log}
+        ${uses_terminal}
+        )"
+    )
   endif()
 endfunction()
 
diff --git a/Modules/FetchContent.cmake b/Modules/FetchContent.cmake
index f3e1b51..c85e2d8 100644
--- a/Modules/FetchContent.cmake
+++ b/Modules/FetchContent.cmake
@@ -5,6 +5,8 @@
 FetchContent
 ------------------
 
+.. versionadded:: 3.11
+
 .. only:: html
 
   .. contents::
@@ -76,8 +78,11 @@
 populate some content in CMake's script mode.
 
 
+Commands
+^^^^^^^^
+
 Declaring Content Details
-^^^^^^^^^^^^^^^^^^^^^^^^^
+"""""""""""""""""""""""""
 
 .. command:: FetchContent_Declare
 
@@ -105,9 +110,13 @@
   The ``<contentOptions>`` can be any of the download or update/patch options
   that the :command:`ExternalProject_Add` command understands.  The configure,
   build, install and test steps are explicitly disabled and therefore options
-  related to them will be ignored.  In most cases, ``<contentOptions>`` will
-  just be a couple of options defining the download method and method-specific
-  details like a commit tag or archive hash.  For example:
+  related to them will be ignored.  The ``SOURCE_SUBDIR`` option is an
+  exception, see :command:`FetchContent_MakeAvailable` for details on how that
+  affects behavior.
+
+  In most cases, ``<contentOptions>`` will just be a couple of options defining
+  the download method and method-specific details like a commit tag or archive
+  hash.  For example:
 
   .. code-block:: cmake
 
@@ -130,7 +139,7 @@
     )
 
 Populating The Content
-^^^^^^^^^^^^^^^^^^^^^^
+""""""""""""""""""""""
 
 For most common scenarios, population means making content available to the
 main build according to previously declared details for that dependency.
@@ -161,8 +170,9 @@
 The above is such a common pattern that, where no custom steps are needed
 between the calls to :command:`FetchContent_Populate` and
 :command:`add_subdirectory`, equivalent logic can be obtained by calling
-:command:`FetchContent_MakeAvailable` instead (and should be preferred where
-it meets the needs of the project).
+:command:`FetchContent_MakeAvailable` instead.  Where it meets the needs of
+the project, :command:`FetchContent_MakeAvailable` should be preferred, as it
+is simpler and provides additional features over the pattern above.
 
 .. command:: FetchContent_Populate
 
@@ -332,6 +342,8 @@
     ``${CMAKE_CURRENT_BINARY_DIR}/<lcName>-subbuild`` and it would be unusual
     to need to override this default.  If a relative path is specified, it will
     be interpreted as relative to :variable:`CMAKE_CURRENT_BINARY_DIR`.
+    This option should not be confused with the ``SOURCE_SUBDIR`` option which
+    only affects the :command:`FetchContent_MakeAvailable` command.
 
   ``SOURCE_DIR``, ``BINARY_DIR``
     The ``SOURCE_DIR`` and ``BINARY_DIR`` arguments are supported by
@@ -406,15 +418,22 @@
 
   This command implements the common pattern typically needed for most
   dependencies.  It iterates over each of the named dependencies in turn
-  and for each one it loosely follows the same
+  and for each one it loosely follows the
   :ref:`canonical pattern <fetch-content-canonical-pattern>` as
-  presented at the beginning of this section.  One small difference to
-  that pattern is that it will only call :command:`add_subdirectory` on the
+  presented at the beginning of this section.  An important difference is
+  that :command:`add_subdirectory` will only be called on the
   populated content if there is a ``CMakeLists.txt`` file in its top level
   source directory.  This allows the command to be used for dependencies
   that make downloaded content available at a known location but which do
   not need or support being added directly to the build.
 
+  The ``SOURCE_SUBDIR`` option can be given in the declared details to
+  instruct ``FetchContent_MakeAvailable()`` to look for a ``CMakeLists.txt``
+  file in a subdirectory below the top level (i.e. the same way that
+  ``SOURCE_SUBDIR`` is used by the :command:`ExternalProject_Add` command).
+  ``SOURCE_SUBDIR`` must always be a relative path.  See the next section
+  for an example of this option.
+
 
 .. _`fetch-content-examples`:
 
@@ -442,6 +461,23 @@
   # Catch2 will be defined and available to the rest of the build
   FetchContent_MakeAvailable(googletest Catch2)
 
+If the sub-project's ``CMakeLists.txt`` file is not at the top level of its
+source tree, the ``SOURCE_SUBDIR`` option can be used to tell ``FetchContent``
+where to find it.  The following example shows how to use that option and
+it also sets a variable which is meaningful to the subproject before pulling
+it into the main build:
+
+.. code-block:: cmake
+
+  include(FetchContent)
+  FetchContent_Declare(
+    protobuf
+    GIT_REPOSITORY https://github.com/protocolbuffers/protobuf.git
+    GIT_TAG        v3.12.0
+    SOURCE_SUBDIR  cmake
+  )
+  set(protobuf_BUILD_TESTS OFF)
+  FetchContent_MakeAvailable(protobuf)
 
 In more complex project hierarchies, the dependency relationships can be more
 complicated.  Consider a hierarchy where ``projA`` is the top level project and
@@ -622,7 +658,12 @@
       BRIEF_DOCS "Internal implementation detail of FetchContent_Populate()"
       FULL_DOCS  "Details used by FetchContent_Populate() for ${contentName}"
     )
-    set_property(GLOBAL PROPERTY ${propertyName} ${ARGN})
+    set(__cmdArgs)
+    foreach(__item IN LISTS ARGN)
+      string(APPEND __cmdArgs " [==[${__item}]==]")
+    endforeach()
+    cmake_language(EVAL CODE
+      "set_property(GLOBAL PROPERTY ${propertyName} ${__cmdArgs})")
   endif()
 
 endfunction()
@@ -655,7 +696,8 @@
   set(oneValueArgs SVN_REPOSITORY)
   set(multiValueArgs "")
 
-  cmake_parse_arguments(ARG "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
+  cmake_parse_arguments(PARSE_ARGV 1 ARG
+    "${options}" "${oneValueArgs}" "${multiValueArgs}")
 
   unset(srcDirSuffix)
   unset(svnRepoArgs)
@@ -673,13 +715,20 @@
   endif()
 
   string(TOLOWER ${contentName} contentNameLower)
-  __FetchContent_declareDetails(
-    ${contentNameLower}
-    SOURCE_DIR "${FETCHCONTENT_BASE_DIR}/${contentNameLower}-src${srcDirSuffix}"
-    BINARY_DIR "${FETCHCONTENT_BASE_DIR}/${contentNameLower}-build"
-    ${svnRepoArgs}
-    # List these last so they can override things we set above
-    ${ARG_UNPARSED_ARGUMENTS}
+
+  set(__argsQuoted)
+  foreach(__item IN LISTS ARG_UNPARSED_ARGUMENTS)
+    string(APPEND __argsQuoted " [==[${__item}]==]")
+  endforeach()
+  cmake_language(EVAL CODE "
+    __FetchContent_declareDetails(
+      ${contentNameLower}
+      SOURCE_DIR \"${FETCHCONTENT_BASE_DIR}/${contentNameLower}-src${srcDirSuffix}\"
+      BINARY_DIR \"${FETCHCONTENT_BASE_DIR}/${contentNameLower}-build\"
+      \${svnRepoArgs}
+      # List these last so they can override things we set above
+      ${__argsQuoted}
+    )"
   )
 
 endfunction()
@@ -793,6 +842,8 @@
       SUBBUILD_DIR
       SOURCE_DIR
       BINARY_DIR
+      # We need special processing if DOWNLOAD_NO_EXTRACT is true
+      DOWNLOAD_NO_EXTRACT
       # Prevent the following from being passed through
       CONFIGURE_COMMAND
       BUILD_COMMAND
@@ -808,7 +859,8 @@
   )
   set(multiValueArgs "")
 
-  cmake_parse_arguments(ARG "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
+  cmake_parse_arguments(PARSE_ARGV 1 ARG
+    "${options}" "${oneValueArgs}" "${multiValueArgs}")
 
   if(NOT ARG_SUBBUILD_DIR)
     message(FATAL_ERROR "Internal error: SUBBUILD_DIR not set")
@@ -843,6 +895,26 @@
     set(ARG_EXTRA "${ARG_EXTRA} \"${arg}\"")
   endforeach()
 
+  if(ARG_DOWNLOAD_NO_EXTRACT)
+    set(ARG_EXTRA "${ARG_EXTRA} DOWNLOAD_NO_EXTRACT YES")
+    set(__FETCHCONTENT_COPY_FILE
+"
+ExternalProject_Get_Property(${contentName}-populate DOWNLOADED_FILE)
+get_filename_component(dlFileName \"\${DOWNLOADED_FILE}\" NAME)
+
+ExternalProject_Add_Step(${contentName}-populate copyfile
+  COMMAND    \"${CMAKE_COMMAND}\" -E copy_if_different
+             \"<DOWNLOADED_FILE>\" \"${ARG_SOURCE_DIR}\"
+  DEPENDEES  patch
+  DEPENDERS  configure
+  BYPRODUCTS \"${ARG_SOURCE_DIR}/\${dlFileName}\"
+  COMMENT    \"Copying file to SOURCE_DIR\"
+)
+")
+  else()
+    unset(__FETCHCONTENT_COPY_FILE)
+  endif()
+
   # Hide output if requested, but save it to a variable in case there's an
   # error so we can show the output upon failure. When not quiet, don't
   # capture the output to a variable because the user may want to see the
@@ -860,16 +932,16 @@
   endif()
 
   if(CMAKE_GENERATOR)
-    set(generatorOpts "-G${CMAKE_GENERATOR}")
+    set(subCMakeOpts "-G${CMAKE_GENERATOR}")
     if(CMAKE_GENERATOR_PLATFORM)
-      list(APPEND generatorOpts "-A${CMAKE_GENERATOR_PLATFORM}")
+      list(APPEND subCMakeOpts "-A${CMAKE_GENERATOR_PLATFORM}")
     endif()
     if(CMAKE_GENERATOR_TOOLSET)
-      list(APPEND generatorOpts "-T${CMAKE_GENERATOR_TOOLSET}")
+      list(APPEND subCMakeOpts "-T${CMAKE_GENERATOR_TOOLSET}")
     endif()
 
     if(CMAKE_MAKE_PROGRAM)
-      list(APPEND generatorOpts "-DCMAKE_MAKE_PROGRAM:FILEPATH=${CMAKE_MAKE_PROGRAM}")
+      list(APPEND subCMakeOpts "-DCMAKE_MAKE_PROGRAM:FILEPATH=${CMAKE_MAKE_PROGRAM}")
     endif()
 
   else()
@@ -877,7 +949,12 @@
     # generator is set (and hence CMAKE_MAKE_PROGRAM could not be
     # trusted even if provided). We will have to rely on being
     # able to find the default generator and build tool.
-    unset(generatorOpts)
+    unset(subCMakeOpts)
+  endif()
+
+  if(DEFINED CMAKE_EP_GIT_REMOTE_UPDATE_STRATEGY)
+    list(APPEND subCMakeOpts
+      "-DCMAKE_EP_GIT_REMOTE_UPDATE_STRATEGY=${CMAKE_EP_GIT_REMOTE_UPDATE_STRATEGY}")
   endif()
 
   # Create and build a separate CMake project to carry out the population.
@@ -888,7 +965,7 @@
   configure_file("${CMAKE_CURRENT_FUNCTION_LIST_DIR}/FetchContent/CMakeLists.cmake.in"
                  "${ARG_SUBBUILD_DIR}/CMakeLists.txt")
   execute_process(
-    COMMAND ${CMAKE_COMMAND} ${generatorOpts} .
+    COMMAND ${CMAKE_COMMAND} ${subCMakeOpts} .
     RESULT_VARIABLE result
     ${outputOptions}
     WORKING_DIRECTORY "${ARG_SUBBUILD_DIR}"
@@ -1000,17 +1077,23 @@
       message(FATAL_ERROR "No details have been set for content: ${contentName}")
     endif()
 
-    __FetchContent_directPopulate(
-      ${contentNameLower}
-      ${quietFlag}
-      UPDATE_DISCONNECTED ${disconnectUpdates}
-      SUBBUILD_DIR "${FETCHCONTENT_BASE_DIR}/${contentNameLower}-subbuild"
-      SOURCE_DIR   "${FETCHCONTENT_BASE_DIR}/${contentNameLower}-src"
-      BINARY_DIR   "${FETCHCONTENT_BASE_DIR}/${contentNameLower}-build"
-      # Put the saved details last so they can override any of the
-      # the options we set above (this can include SOURCE_DIR or
-      # BUILD_DIR)
-      ${contentDetails}
+    set(__detailsQuoted)
+    foreach(__item IN LISTS contentDetails)
+      string(APPEND __detailsQuoted " [==[${__item}]==]")
+    endforeach()
+    cmake_language(EVAL CODE "
+      __FetchContent_directPopulate(
+        ${contentNameLower}
+        ${quietFlag}
+        UPDATE_DISCONNECTED ${disconnectUpdates}
+        SUBBUILD_DIR \"${FETCHCONTENT_BASE_DIR}/${contentNameLower}-subbuild\"
+        SOURCE_DIR   \"${FETCHCONTENT_BASE_DIR}/${contentNameLower}-src\"
+        BINARY_DIR   \"${FETCHCONTENT_BASE_DIR}/${contentNameLower}-build\"
+        # Put the saved details last so they can override any of the
+        # the options we set above (this can include SOURCE_DIR or
+        # BUILD_DIR)
+        ${__detailsQuoted}
+      )"
     )
   endif()
 
@@ -1047,11 +1130,26 @@
       # can be treated that way. Protecting the call with the check
       # allows this function to be used for projects that just want
       # to ensure the content exists, such as to provide content at
-      # a known location.
-      if(EXISTS ${${contentNameLower}_SOURCE_DIR}/CMakeLists.txt)
-        add_subdirectory(${${contentNameLower}_SOURCE_DIR}
-                         ${${contentNameLower}_BINARY_DIR})
+      # a known location. We check the saved details for an optional
+      # SOURCE_SUBDIR which can be used in the same way as its meaning
+      # for ExternalProject. It won't matter if it was passed through
+      # to the ExternalProject sub-build, since it would have been
+      # ignored there.
+      set(__fc_srcdir "${${contentNameLower}_SOURCE_DIR}")
+      __FetchContent_getSavedDetails(${contentName} contentDetails)
+      if("${contentDetails}" STREQUAL "")
+        message(FATAL_ERROR "No details have been set for content: ${contentName}")
       endif()
+      cmake_parse_arguments(__fc_arg "" "SOURCE_SUBDIR" "" ${contentDetails})
+      if(NOT "${__fc_arg_SOURCE_SUBDIR}" STREQUAL "")
+        string(APPEND __fc_srcdir "/${__fc_arg_SOURCE_SUBDIR}")
+      endif()
+
+      if(EXISTS ${__fc_srcdir}/CMakeLists.txt)
+        add_subdirectory(${__fc_srcdir} ${${contentNameLower}_BINARY_DIR})
+      endif()
+
+      unset(__fc_srcdir)
     endif()
   endforeach()
 
diff --git a/Modules/FetchContent/CMakeLists.cmake.in b/Modules/FetchContent/CMakeLists.cmake.in
index 0095b11..45e4df0 100644
--- a/Modules/FetchContent/CMakeLists.cmake.in
+++ b/Modules/FetchContent/CMakeLists.cmake.in
@@ -21,3 +21,5 @@
                     USES_TERMINAL_DOWNLOAD  YES
                     USES_TERMINAL_UPDATE    YES
 )
+
+@__FETCHCONTENT_COPY_FILE@
diff --git a/Modules/FindArmadillo.cmake b/Modules/FindArmadillo.cmake
index c4e55ce..c8a31a0 100644
--- a/Modules/FindArmadillo.cmake
+++ b/Modules/FindArmadillo.cmake
@@ -6,7 +6,7 @@
 -------------
 
 Find the Armadillo C++ library.
-Armadillo is library for linear algebra & scientific computing.
+Armadillo is a library for linear algebra & scientific computing.
 
 Using Armadillo:
 
@@ -31,19 +31,13 @@
   ARMADILLO_VERSION_NAME - name of the version (ex: "Antipodean Antileech")
 #]=======================================================================]
 
-# UNIX paths are standard, no need to write.
-find_library(ARMADILLO_LIBRARY
-  NAMES armadillo
-  PATHS "$ENV{ProgramFiles}/Armadillo/lib"  "$ENV{ProgramFiles}/Armadillo/lib64" "$ENV{ProgramFiles}/Armadillo"
-  )
 find_path(ARMADILLO_INCLUDE_DIR
   NAMES armadillo
   PATHS "$ENV{ProgramFiles}/Armadillo/include"
   )
-
+mark_as_advanced(ARMADILLO_INCLUDE_DIR)
 
 if(ARMADILLO_INCLUDE_DIR)
-
   # ------------------------------------------------------------------------
   #  Extract version information from <armadillo>
   # ------------------------------------------------------------------------
@@ -59,32 +53,80 @@
   if(EXISTS "${ARMADILLO_INCLUDE_DIR}/armadillo_bits/arma_version.hpp")
 
     # Read and parse armdillo version header file for version number
-    file(STRINGS "${ARMADILLO_INCLUDE_DIR}/armadillo_bits/arma_version.hpp" _armadillo_HEADER_CONTENTS REGEX "#define ARMA_VERSION_[A-Z]+ ")
-    string(REGEX REPLACE ".*#define ARMA_VERSION_MAJOR ([0-9]+).*" "\\1" ARMADILLO_VERSION_MAJOR "${_armadillo_HEADER_CONTENTS}")
-    string(REGEX REPLACE ".*#define ARMA_VERSION_MINOR ([0-9]+).*" "\\1" ARMADILLO_VERSION_MINOR "${_armadillo_HEADER_CONTENTS}")
-    string(REGEX REPLACE ".*#define ARMA_VERSION_PATCH ([0-9]+).*" "\\1" ARMADILLO_VERSION_PATCH "${_armadillo_HEADER_CONTENTS}")
+    file(STRINGS "${ARMADILLO_INCLUDE_DIR}/armadillo_bits/arma_version.hpp" _ARMA_HEADER_CONTENTS REGEX "#define ARMA_VERSION_[A-Z]+ ")
+    string(REGEX REPLACE ".*#define ARMA_VERSION_MAJOR ([0-9]+).*" "\\1" ARMADILLO_VERSION_MAJOR "${_ARMA_HEADER_CONTENTS}")
+    string(REGEX REPLACE ".*#define ARMA_VERSION_MINOR ([0-9]+).*" "\\1" ARMADILLO_VERSION_MINOR "${_ARMA_HEADER_CONTENTS}")
+    string(REGEX REPLACE ".*#define ARMA_VERSION_PATCH ([0-9]+).*" "\\1" ARMADILLO_VERSION_PATCH "${_ARMA_HEADER_CONTENTS}")
 
     # WARNING: The number of spaces before the version name is not one.
-    string(REGEX REPLACE ".*#define ARMA_VERSION_NAME +\"([0-9a-zA-Z _-]+)\".*" "\\1" ARMADILLO_VERSION_NAME "${_armadillo_HEADER_CONTENTS}")
+    string(REGEX REPLACE ".*#define ARMA_VERSION_NAME\ +\"([0-9a-zA-Z\ _-]+)\".*" "\\1" ARMADILLO_VERSION_NAME "${_ARMA_HEADER_CONTENTS}")
 
-    unset(_armadillo_HEADER_CONTENTS)
   endif()
 
   set(ARMADILLO_VERSION_STRING "${ARMADILLO_VERSION_MAJOR}.${ARMADILLO_VERSION_MINOR}.${ARMADILLO_VERSION_PATCH}")
 endif ()
 
+if(EXISTS "${ARMADILLO_INCLUDE_DIR}/armadillo_bits/config.hpp")
+  file(STRINGS "${ARMADILLO_INCLUDE_DIR}/armadillo_bits/config.hpp" _ARMA_CONFIG_CONTENTS REGEX "^#define ARMA_USE_[A-Z]+")
+  string(REGEX MATCH "ARMA_USE_WRAPPER" _ARMA_USE_WRAPPER "${_ARMA_CONFIG_CONTENTS}")
+  string(REGEX MATCH "ARMA_USE_LAPACK" _ARMA_USE_LAPACK "${_ARMA_CONFIG_CONTENTS}")
+  string(REGEX MATCH "ARMA_USE_BLAS" _ARMA_USE_BLAS "${_ARMA_CONFIG_CONTENTS}")
+  string(REGEX MATCH "ARMA_USE_ARPACK" _ARMA_USE_ARPACK "${_ARMA_CONFIG_CONTENTS}")
+  string(REGEX MATCH "ARMA_USE_HDF5" _ARMA_USE_HDF5 "${_ARMA_CONFIG_CONTENTS}")
+endif()
+
 include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
+
+# If _ARMA_USE_WRAPPER is set, then we just link to armadillo, but if it's not then we need support libraries instead
+set(_ARMA_SUPPORT_LIBRARIES)
+
+if(_ARMA_USE_WRAPPER)
+  # Link to the armadillo wrapper library.
+  find_library(ARMADILLO_LIBRARY
+    NAMES armadillo
+    NAMES_PER_DIR
+    PATHS
+      "$ENV{ProgramFiles}/Armadillo/lib"
+      "$ENV{ProgramFiles}/Armadillo/lib64"
+      "$ENV{ProgramFiles}/Armadillo"
+    )
+  mark_as_advanced(ARMADILLO_LIBRARY)
+  set(_ARMA_REQUIRED_VARS ARMADILLO_LIBRARY)
+else()
+  # Link directly to individual components.
+  set(ARMADILLO_LIBRARY "")
+  foreach(pkg
+      LAPACK
+      BLAS
+      ARPACK
+      HDF5
+      )
+    if(_ARMA_USE_${pkg})
+      find_package(${pkg} QUIET)
+      list(APPEND _ARMA_REQUIRED_VARS "${pkg}_FOUND")
+      if(${pkg}_FOUND)
+        list(APPEND _ARMA_SUPPORT_LIBRARIES ${${pkg}_LIBRARIES})
+      endif()
+    endif()
+  endforeach()
+endif()
+
 find_package_handle_standard_args(Armadillo
-  REQUIRED_VARS ARMADILLO_LIBRARY ARMADILLO_INCLUDE_DIR
+  REQUIRED_VARS ARMADILLO_INCLUDE_DIR ${_ARMA_REQUIRED_VARS}
   VERSION_VAR ARMADILLO_VERSION_STRING)
-# version_var fails with cmake < 2.8.4.
 
 if (ARMADILLO_FOUND)
   set(ARMADILLO_INCLUDE_DIRS ${ARMADILLO_INCLUDE_DIR})
-  set(ARMADILLO_LIBRARIES ${ARMADILLO_LIBRARY})
+  set(ARMADILLO_LIBRARIES ${ARMADILLO_LIBRARY} ${_ARMA_SUPPORT_LIBRARIES})
 endif ()
 
-# Hide internal variables
-mark_as_advanced(
-  ARMADILLO_INCLUDE_DIR
-  ARMADILLO_LIBRARY)
+# Clean up internal variables
+unset(_ARMA_REQUIRED_VARS)
+unset(_ARMA_SUPPORT_LIBRARIES)
+unset(_ARMA_USE_WRAPPER)
+unset(_ARMA_USE_LAPACK)
+unset(_ARMA_USE_BLAS)
+unset(_ARMA_USE_ARPACK)
+unset(_ARMA_USE_HDF5)
+unset(_ARMA_CONFIG_CONTENTS)
+unset(_ARMA_HEADER_CONTENTS)
diff --git a/Modules/FindBISON.cmake b/Modules/FindBISON.cmake
index 6b5828e..1e1a5a3 100644
--- a/Modules/FindBISON.cmake
+++ b/Modules/FindBISON.cmake
@@ -82,7 +82,7 @@
   add_executable(Foo main.cpp ${BISON_MyParser_OUTPUTS})
 #]=======================================================================]
 
-find_program(BISON_EXECUTABLE NAMES bison win_bison DOC "path to the bison executable")
+find_program(BISON_EXECUTABLE NAMES bison win-bison win_bison DOC "path to the bison executable")
 mark_as_advanced(BISON_EXECUTABLE)
 
 if(BISON_EXECUTABLE)
diff --git a/Modules/FindBLAS.cmake b/Modules/FindBLAS.cmake
index 9b6d09c..88a252d 100644
--- a/Modules/FindBLAS.cmake
+++ b/Modules/FindBLAS.cmake
@@ -36,7 +36,7 @@
   * ``SCSL``
   * ``SGIMATH``
   * ``IBMESSL``
-  * ``Intel10_32`` (intel mkl v10 32 bit)
+  * ``Intel10_32`` (intel mkl v10 32 bit, threaded code)
   * ``Intel10_64lp`` (intel mkl v10+ 64 bit, threaded code, lp64 model)
   * ``Intel10_64lp_seq`` (intel mkl v10+ 64 bit, sequential code, lp64 model)
   * ``Intel10_64ilp`` (intel mkl v10+ 64 bit, threaded code, ilp64 model)
@@ -48,6 +48,10 @@
   * ``ACML_GPU``
   * ``Apple``
   * ``NAS``
+  * ``Arm``
+  * ``Arm_mp``
+  * ``Arm_ilp64``
+  * ``Arm_ilp64_mp``
   * ``Generic``
 
 ``BLA_F95``
@@ -57,6 +61,15 @@
   if set ``pkg-config`` will be used to search for a BLAS library first
   and if one is found that is preferred
 
+Imported targets
+^^^^^^^^^^^^^^^^
+
+This module defines the following :prop_tgt:`IMPORTED` target:
+
+``BLAS::BLAS``
+  The libraries to use for BLAS, if found.
+
+
 Result Variables
 ^^^^^^^^^^^^^^^^
 
@@ -107,6 +120,17 @@
   endif()
 endif()
 
+function(_add_blas_target)
+  if(NOT TARGET BLAS::BLAS)
+    add_library(BLAS::BLAS INTERFACE IMPORTED)
+    if(BLAS_LIBRARIES)
+      set_target_properties(BLAS::BLAS PROPERTIES
+        INTERFACE_LINK_LIBRARIES "${BLAS_LIBRARIES}"
+      )
+    endif()
+  endif()
+endfunction()
+
 if(CMAKE_Fortran_COMPILER_LOADED)
   include(${CMAKE_CURRENT_LIST_DIR}/CheckFortranFunctionExists.cmake)
 else()
@@ -123,6 +147,7 @@
   if(PKGC_BLAS_FOUND)
     set(BLAS_FOUND ${PKGC_BLAS_FOUND})
     set(BLAS_LIBRARIES "${PKGC_BLAS_LINK_LIBRARIES}")
+    _add_blas_target()
     return()
   endif()
 endif()
@@ -183,6 +208,7 @@
       if(_libraries_work)
         find_library(${_prefix}_${_library}_LIBRARY
           NAMES ${_library}
+          NAMES_PER_DIR
           PATHS ${_extaddlibdir}
           PATH_SUFFIXES ${_subdirs}
         )
@@ -372,6 +398,10 @@
 
           # Add threading/sequential libs
           set(BLAS_SEARCH_LIBS_WIN_THREAD "")
+          if(BLA_VENDOR STREQUAL "Intel10_32" OR BLA_VENDOR STREQUAL "All")
+            list(APPEND BLAS_SEARCH_LIBS_WIN_THREAD
+              "libiomp5md mkl_intel_thread${BLAS_mkl_DLL_SUFFIX}")
+          endif()
           if(BLA_VENDOR MATCHES "^Intel10_64i?lp$" OR BLA_VENDOR STREQUAL "All")
             # old version
             list(APPEND BLAS_SEARCH_LIBS_WIN_THREAD
@@ -416,7 +446,7 @@
               "${BLAS_mkl_START_GROUP} mkl_${BLAS_mkl_INTFACE}_${BLAS_mkl_ILP_MODE} mkl_sequential mkl_core ${BLAS_mkl_END_GROUP}")
           endif()
 
-          #older vesions of intel mkl libs
+          #older versions of intel mkl libs
           if(BLA_VENDOR STREQUAL "Intel" OR BLA_VENDOR STREQUAL "All")
             list(APPEND BLAS_SEARCH_LIBS
               "mkl")
@@ -448,7 +478,7 @@
         set(BLAS_mkl_OS_NAME "lin")
       endif()
       if(DEFINED ENV{MKLROOT})
-        set(BLAS_mkl_MKLROOT "$ENV{MKLROOT}")
+        file(TO_CMAKE_PATH "$ENV{MKLROOT}" BLAS_mkl_MKLROOT)
         # If MKLROOT points to the subdirectory 'mkl', use the parent directory instead
         # so we can better detect other relevant libraries in 'compiler' or 'tbb':
         get_filename_component(BLAS_mkl_MKLROOT_LAST_DIR "${BLAS_mkl_MKLROOT}" NAME)
@@ -458,7 +488,9 @@
       endif()
       set(BLAS_mkl_LIB_PATH_SUFFIXES
           "compiler/lib" "compiler/lib/${BLAS_mkl_ARCH_NAME}_${BLAS_mkl_OS_NAME}"
+          "compiler/lib/${BLAS_mkl_ARCH_NAME}"
           "mkl/lib" "mkl/lib/${BLAS_mkl_ARCH_NAME}_${BLAS_mkl_OS_NAME}"
+          "mkl/lib/${BLAS_mkl_ARCH_NAME}"
           "lib/${BLAS_mkl_ARCH_NAME}_${BLAS_mkl_OS_NAME}")
 
       foreach(IT ${BLAS_SEARCH_LIBS})
@@ -550,6 +582,36 @@
   endif()
 endif()
 
+# ArmPL blas library? (https://developer.arm.com/tools-and-software/server-and-hpc/compile/arm-compiler-for-linux/arm-performance-libraries)
+if(BLA_VENDOR MATCHES "Arm" OR BLA_VENDOR STREQUAL "All")
+
+   # Check for 64bit Integer support
+   if(BLA_VENDOR MATCHES "_ilp64")
+     set(BLAS_armpl_LIB "armpl_ilp64")
+   else()
+     set(BLAS_armpl_LIB "armpl_lp64")
+   endif()
+
+   # Check for OpenMP support, VIA BLA_VENDOR of Arm_mp or Arm_ipl64_mp
+   if(BLA_VENDOR MATCHES "_mp")
+     set(BLAS_armpl_LIB "${BLAS_armpl_LIB}_mp")
+   endif()
+
+   if(NOT BLAS_LIBRARIES)
+    check_blas_libraries(
+      BLAS_LIBRARIES
+      BLAS
+      sgemm
+      ""
+      "${BLAS_armpl_LIB}"
+      ""
+      ""
+      ""
+      )
+  endif()
+
+endif()
+
 # FLAME's blis library? (https://github.com/flame/blis)
 if(BLA_VENDOR STREQUAL "FLAME" OR BLA_VENDOR STREQUAL "All")
   if(NOT BLAS_LIBRARIES)
@@ -892,11 +954,13 @@
   find_package_handle_standard_args(BLAS REQUIRED_VARS BLAS_LIBRARIES)
 endif()
 
+
 # On compilers that implicitly link BLAS (such as ftn, cc, and CC on Cray HPC machines)
 # we used a placeholder for empty BLAS_LIBRARIES to get through our logic above.
 if(BLAS_LIBRARIES STREQUAL "BLAS_LIBRARIES-PLACEHOLDER-FOR-EMPTY-LIBRARIES")
   set(BLAS_LIBRARIES "")
 endif()
 
+_add_blas_target()
 cmake_pop_check_state()
 set(CMAKE_FIND_LIBRARY_SUFFIXES ${_blas_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES})
diff --git a/Modules/FindBZip2.cmake b/Modules/FindBZip2.cmake
index 98ab72c..5704d1d 100644
--- a/Modules/FindBZip2.cmake
+++ b/Modules/FindBZip2.cmake
@@ -45,8 +45,8 @@
 find_path(BZIP2_INCLUDE_DIR bzlib.h ${_BZIP2_PATHS} PATH_SUFFIXES include)
 
 if (NOT BZIP2_LIBRARIES)
-    find_library(BZIP2_LIBRARY_RELEASE NAMES bz2 bzip2 libbz2 libbzip2 ${_BZIP2_PATHS} PATH_SUFFIXES lib)
-    find_library(BZIP2_LIBRARY_DEBUG NAMES bz2d bzip2d libbz2d libbzip2d ${_BZIP2_PATHS} PATH_SUFFIXES lib)
+    find_library(BZIP2_LIBRARY_RELEASE NAMES bz2 bzip2 libbz2 libbzip2 NAMES_PER_DIR ${_BZIP2_PATHS} PATH_SUFFIXES lib)
+    find_library(BZIP2_LIBRARY_DEBUG NAMES bz2d bzip2d libbz2d libbzip2d NAMES_PER_DIR ${_BZIP2_PATHS} PATH_SUFFIXES lib)
 
     include(${CMAKE_CURRENT_LIST_DIR}/SelectLibraryConfigurations.cmake)
     SELECT_LIBRARY_CONFIGURATIONS(BZIP2)
diff --git a/Modules/FindBoost.cmake b/Modules/FindBoost.cmake
index 1e815a0..ec087ad 100644
--- a/Modules/FindBoost.cmake
+++ b/Modules/FindBoost.cmake
@@ -155,6 +155,10 @@
                              used if multiple compatible suffixes should
                              be tested for, in decreasing order of
                              preference.
+  Boost_LIB_PREFIX         - Set to the platform-specific library name
+                             prefix (e.g. "lib") used by Boost static libs.
+                             This is needed only on platforms where CMake
+                             does not know the prefix by default.
   Boost_ARCHITECTURE       - Set to the architecture-specific library suffix
                              (e.g. "-x64").  Default is auto-computed for the
                              C++ compiler in use.
@@ -301,7 +305,7 @@
 endfunction()
 
 macro(_boost_set_in_parent_scope name value)
-  # Set a variable in parent scope and make it visibile in current scope
+  # Set a variable in parent scope and make it visible in current scope
   set(${name} "${value}" PARENT_SCOPE)
   set(${name} "${value}")
 endmacro()
@@ -1266,10 +1270,8 @@
   set(_Boost_UNIT_TEST_FRAMEWORK_HEADERS "boost/test/framework.hpp")
   set(_Boost_WAVE_HEADERS                "boost/wave.hpp")
   set(_Boost_WSERIALIZATION_HEADERS      "boost/archive/text_wiarchive.hpp")
-  if(WIN32)
-    set(_Boost_BZIP2_HEADERS             "boost/iostreams/filter/bzip2.hpp")
-    set(_Boost_ZLIB_HEADERS              "boost/iostreams/filter/zlib.hpp")
-  endif()
+  set(_Boost_BZIP2_HEADERS               "boost/iostreams/filter/bzip2.hpp")
+  set(_Boost_ZLIB_HEADERS                "boost/iostreams/filter/zlib.hpp")
 
   string(TOUPPER ${component} uppercomponent)
   set(${_hdrs} ${_Boost_${uppercomponent}_HEADERS} PARENT_SCOPE)
@@ -1667,10 +1669,17 @@
 #  Prefix initialization
 # ------------------------------------------------------------------------
 
-set(Boost_LIB_PREFIX "")
-if ( (GHSMULTI AND Boost_USE_STATIC_LIBS) OR
-    (WIN32 AND Boost_USE_STATIC_LIBS AND NOT CYGWIN) )
-  set(Boost_LIB_PREFIX "lib")
+if ( NOT DEFINED Boost_LIB_PREFIX )
+  # Boost's static libraries use a "lib" prefix on DLL platforms
+  # to distinguish them from the DLL import libraries.
+  if (Boost_USE_STATIC_LIBS AND (
+      (WIN32 AND NOT CYGWIN)
+      OR GHSMULTI
+      ))
+    set(Boost_LIB_PREFIX "lib")
+  else()
+    set(Boost_LIB_PREFIX "")
+  endif()
 endif()
 
 if ( NOT Boost_NAMESPACE )
diff --git a/Modules/FindCUDA.cmake b/Modules/FindCUDA.cmake
index e1af2d6..a93d4fd 100644
--- a/Modules/FindCUDA.cmake
+++ b/Modules/FindCUDA.cmake
@@ -357,7 +357,8 @@
   CUDA_nppicc_LIBRARY   -- NVIDIA Performance Primitives lib (image processing).
                            Only available for CUDA version 9.0.
   CUDA_nppicom_LIBRARY  -- NVIDIA Performance Primitives lib (image processing).
-                           Only available for CUDA version 9.0.
+                           Only available for CUDA version 9.0 - 10.2.
+                           Replaced by nvjpeg.
   CUDA_nppidei_LIBRARY  -- NVIDIA Performance Primitives lib (image processing).
                            Only available for CUDA version 9.0.
   CUDA_nppif_LIBRARY    -- NVIDIA Performance Primitives lib (image processing).
@@ -1002,7 +1003,9 @@
   find_cuda_helper_libs(nppc)
   find_cuda_helper_libs(nppial)
   find_cuda_helper_libs(nppicc)
-  find_cuda_helper_libs(nppicom)
+  if(CUDA_VERSION VERSION_LESS "11.0")
+    find_cuda_helper_libs(nppicom)
+  endif()
   find_cuda_helper_libs(nppidei)
   find_cuda_helper_libs(nppif)
   find_cuda_helper_libs(nppig)
diff --git a/Modules/FindCUDA/run_nvcc.cmake b/Modules/FindCUDA/run_nvcc.cmake
index ba35433..17e12f8 100644
--- a/Modules/FindCUDA/run_nvcc.cmake
+++ b/Modules/FindCUDA/run_nvcc.cmake
@@ -155,7 +155,7 @@
     # copy and paste a runnable command line.
     set(cuda_execute_process_string)
     foreach(arg ${ARGN})
-      # If there are quotes, excape them, so they come through.
+      # If there are quotes, escape them, so they come through.
       string(REPLACE "\"" "\\\"" arg ${arg})
       # Args with spaces need quotes around them to get them to be parsed as a single argument.
       if(arg MATCHES " ")
diff --git a/Modules/FindCUDA/select_compute_arch.cmake b/Modules/FindCUDA/select_compute_arch.cmake
index 7ddb709..c11725d 100644
--- a/Modules/FindCUDA/select_compute_arch.cmake
+++ b/Modules/FindCUDA/select_compute_arch.cmake
@@ -5,9 +5,9 @@
 #       - "Auto" detects local machine GPU compute arch at runtime.
 #       - "Common" and "All" cover common and entire subsets of architectures
 #      ARCH_AND_PTX : NAME | NUM.NUM | NUM.NUM(NUM.NUM) | NUM.NUM+PTX
-#      NAME: Fermi Kepler Maxwell Kepler+Tegra Kepler+Tesla Maxwell+Tegra Pascal Volta Turing
+#      NAME: Fermi Kepler Maxwell Kepler+Tegra Kepler+Tesla Maxwell+Tegra Pascal Volta Turing Ampere
 #      NUM: Any number. Only those pairs are currently accepted by NVCC though:
-#            2.0 2.1 3.0 3.2 3.5 3.7 5.0 5.2 5.3 6.0 6.2 7.0 7.2 7.5
+#            2.0 2.1 3.0 3.2 3.5 3.7 5.0 5.2 5.3 6.0 6.2 7.0 7.2 7.5 8.0
 #      Returns LIST of flags to be added to CUDA_NVCC_FLAGS in ${out_variable}
 #      Additionally, sets ${out_variable}_readable to the resulting numeric list
 #      Example:
@@ -30,7 +30,12 @@
 set(CUDA_KNOWN_GPU_ARCHITECTURES  "Fermi" "Kepler" "Maxwell")
 
 # This list will be used for CUDA_ARCH_NAME = Common option (enabled by default)
-set(CUDA_COMMON_GPU_ARCHITECTURES "3.0" "3.5" "5.0")
+set(CUDA_COMMON_GPU_ARCHITECTURES "3.5" "5.0")
+# 3.0 is removed in CUDA 11, see:
+# https://docs.nvidia.com/cuda/cuda-toolkit-release-notes/index.html#deprecated-features
+if(CUDA_VERSION VERSION_LESS "11.0")
+  list(APPEND CUDA_COMMON_GPU_ARCHITECTURES "3.0")
+endif()
 
 if(CUDA_VERSION VERSION_LESS "7.0")
   set(CUDA_LIMIT_GPU_ARCHITECTURE "5.2")
@@ -55,27 +60,39 @@
   list(APPEND CUDA_ALL_GPU_ARCHITECTURES "6.0" "6.1" "6.2")
 
   if(CUDA_VERSION VERSION_LESS "9.0")
-    list(APPEND CUDA_COMMON_GPU_ARCHITECTURES "6.1+PTX")
+    list(APPEND CUDA_COMMON_GPU_ARCHITECTURES "6.2+PTX")
     set(CUDA_LIMIT_GPU_ARCHITECTURE "7.0")
   endif()
 endif ()
 
 if(CUDA_VERSION VERSION_GREATER_EQUAL "9.0")
   list(APPEND CUDA_KNOWN_GPU_ARCHITECTURES "Volta")
-  list(APPEND CUDA_COMMON_GPU_ARCHITECTURES "7.0" "7.0+PTX")
-  list(APPEND CUDA_ALL_GPU_ARCHITECTURES "7.0" "7.0+PTX" "7.2" "7.2+PTX")
+  list(APPEND CUDA_COMMON_GPU_ARCHITECTURES "7.0")
+  list(APPEND CUDA_ALL_GPU_ARCHITECTURES "7.0" "7.2")
 
   if(CUDA_VERSION VERSION_LESS "10.0")
+    list(APPEND CUDA_COMMON_GPU_ARCHITECTURES "7.2+PTX")
     set(CUDA_LIMIT_GPU_ARCHITECTURE "8.0")
   endif()
 endif()
 
 if(CUDA_VERSION VERSION_GREATER_EQUAL "10.0")
   list(APPEND CUDA_KNOWN_GPU_ARCHITECTURES "Turing")
-  list(APPEND CUDA_COMMON_GPU_ARCHITECTURES "7.5" "7.5+PTX")
-  list(APPEND CUDA_ALL_GPU_ARCHITECTURES "7.5" "7.5+PTX")
+  list(APPEND CUDA_COMMON_GPU_ARCHITECTURES "7.5")
+  list(APPEND CUDA_ALL_GPU_ARCHITECTURES "7.5")
 
   if(CUDA_VERSION VERSION_LESS "11.0")
+    set(CUDA_LIMIT_GPU_ARCHITECTURE "8.0")
+    list(APPEND CUDA_COMMON_GPU_ARCHITECTURES "7.5+PTX")
+  endif()
+endif()
+
+if(CUDA_VERSION VERSION_GREATER_EQUAL "11.0")
+  list(APPEND CUDA_KNOWN_GPU_ARCHITECTURES "Ampere")
+  list(APPEND CUDA_COMMON_GPU_ARCHITECTURES "8.0" "8.0+PTX")
+  list(APPEND CUDA_ALL_GPU_ARCHITECTURES "8.0")
+
+  if(CUDA_VERSION VERSION_LESS "12.0")
     set(CUDA_LIMIT_GPU_ARCHITECTURE "9.0")
   endif()
 endif()
@@ -214,6 +231,9 @@
       elseif(${arch_name} STREQUAL "Turing")
         set(arch_bin 7.5)
         set(arch_ptx 7.5)
+      elseif(${arch_name} STREQUAL "Ampere")
+        set(arch_bin 8.0)
+        set(arch_ptx 8.0)
       else()
         message(SEND_ERROR "Unknown CUDA Architecture Name ${arch_name} in CUDA_SELECT_NVCC_ARCH_FLAGS")
       endif()
diff --git a/Modules/FindCUDAToolkit.cmake b/Modules/FindCUDAToolkit.cmake
index de7e785..1054f60 100644
--- a/Modules/FindCUDAToolkit.cmake
+++ b/Modules/FindCUDAToolkit.cmake
@@ -5,6 +5,8 @@
 FindCUDAToolkit
 ---------------
 
+.. versionadded:: 3.17
+
 This script locates the NVIDIA CUDA toolkit and the associated libraries, but
 does not require the ``CUDA`` language be enabled for a given project. This
 module does not search for the NVIDIA CUDA Samples.
@@ -12,8 +14,7 @@
 Search Behavior
 ^^^^^^^^^^^^^^^
 
-Finding the CUDA Toolkit requires finding the ``nvcc`` executable, which is
-searched for in the following order:
+The CUDA Toolkit search behavior uses the following order:
 
 1. If the ``CUDA`` language has been enabled we will use the directory
    containing the compiler as the first search location for ``nvcc``.
@@ -24,13 +25,12 @@
    configuration variable are specified, the *configuration* variable takes
    precedence.
 
-   The directory specified here must be such that the executable ``nvcc`` can be
-   found underneath the directory specified by ``CUDAToolkit_ROOT``.  If
-   ``CUDAToolkit_ROOT`` is specified, but no ``nvcc`` is found underneath, this
-   package is marked as **not** found.  No subsequent search attempts are
-   performed.
+   The directory specified here must be such that the executable ``nvcc`` or
+   the appropriate ``version.txt`` file can be found underneath the specified
+   directory.
 
-3. If the CUDA_PATH environment variable is defined, it will be searched.
+3. If the CUDA_PATH environment variable is defined, it will be searched
+   for ``nvcc``.
 
 4. The user's path is searched for ``nvcc`` using :command:`find_program`.  If
    this is found, no subsequent search attempts are performed.  Users are
@@ -154,6 +154,8 @@
 
 - ``CUDA::cublas``
 - ``CUDA::cublas_static``
+- ``CUDA::cublasLt`` starting in CUDA 10.1
+- ``CUDA::cublasLt_static`` starting in CUDA 10.1
 
 .. _`cuda_toolkit_cuFFT`:
 
@@ -240,6 +242,7 @@
   - ``CUDA::nppicc_static``
 
 - `nppicom`: JPEG compression and decompression functions in `nppi_compression_functions.h`
+  Removed starting in CUDA 11.0, use :ref:`nvJPEG<cuda_toolkit_nvJPEG>` instead.
 
   - ``CUDA::nppicom``
   - ``CUDA::nppicom_static``
@@ -302,6 +305,7 @@
 """""""
 
 The `nvGRAPH <https://docs.nvidia.com/cuda/nvgraph/index.html>`_ library.
+Removed starting in CUDA 11.0
 
 Targets Created:
 
@@ -398,7 +402,7 @@
 
 ``CUDAToolkit_VERSION``
     The exact version of the CUDA Toolkit found (as reported by
-    ``nvcc --version``).
+    ``nvcc --version`` or ``version.txt``).
 
 ``CUDAToolkit_VERSION_MAJOR``
     The major version of the CUDA Toolkit.
@@ -421,10 +425,14 @@
     The path to the CUDA Toolkit library directory that contains the CUDA
     Runtime library ``cudart``.
 
+``CUDAToolkit_LIBRARY_ROOT``
+    The path to the CUDA Toolkit directory containing the nvvm directory and
+    version.txt.
+
 ``CUDAToolkit_TARGET_DIR``
     The path to the CUDA Toolkit directory including the target architecture
-    when cross-compiling. When not cross-compiling this will be equivalant to
-    ``CUDAToolkit_ROOT_DIR``.
+    when cross-compiling. When not cross-compiling this will be equivalent to
+    the parent directory of ``CUDAToolkit_BIN_DIR``.
 
 ``CUDAToolkit_NVCC_EXECUTABLE``
     The path to the NVIDIA CUDA compiler ``nvcc``.  Note that this path may
@@ -473,214 +481,213 @@
 #
 ###############################################################################
 
-if(CMAKE_CUDA_COMPILER_LOADED AND NOT CUDAToolkit_BIN_DIR)
-  get_filename_component(cuda_dir "${CMAKE_CUDA_COMPILER}" DIRECTORY)
-  # use the already detected cuda compiler
-  set(CUDAToolkit_BIN_DIR "${cuda_dir}" CACHE PATH "")
-  mark_as_advanced(CUDAToolkit_BIN_DIR)
-  unset(cuda_dir)
-endif()
-
-# Try language- or user-provided path first.
-if(CUDAToolkit_BIN_DIR)
-  find_program(CUDAToolkit_NVCC_EXECUTABLE
-    NAMES nvcc nvcc.exe
-    PATHS ${CUDAToolkit_BIN_DIR}
-    NO_DEFAULT_PATH
-    )
-endif()
-
-# Search using CUDAToolkit_ROOT
-find_program(CUDAToolkit_NVCC_EXECUTABLE
-  NAMES nvcc nvcc.exe
-  PATHS ENV CUDA_PATH
-  PATH_SUFFIXES bin
-)
-
-# If the user specified CUDAToolkit_ROOT but nvcc could not be found, this is an error.
-if (NOT CUDAToolkit_NVCC_EXECUTABLE AND (DEFINED CUDAToolkit_ROOT OR DEFINED ENV{CUDAToolkit_ROOT}))
-  # Declare error messages now, print later depending on find_package args.
-  set(fail_base "Could not find nvcc executable in path specified by")
-  set(cuda_root_fail "${fail_base} CUDAToolkit_ROOT=${CUDAToolkit_ROOT}")
-  set(env_cuda_root_fail "${fail_base} environment variable CUDAToolkit_ROOT=$ENV{CUDAToolkit_ROOT}")
-
-  if (CUDAToolkit_FIND_REQUIRED)
-    if (DEFINED CUDAToolkit_ROOT)
-      message(FATAL_ERROR ${cuda_root_fail})
-    elseif (DEFINED ENV{CUDAToolkit_ROOT})
-      message(FATAL_ERROR ${env_cuda_root_fail})
-    endif()
-  else()
-    if (NOT CUDAToolkit_FIND_QUIETLY)
-      if (DEFINED CUDAToolkit_ROOT)
-        message(STATUS ${cuda_root_fail})
-      elseif (DEFINED ENV{CUDAToolkit_ROOT})
-        message(STATUS ${env_cuda_root_fail})
-      endif()
-    endif()
-    set(CUDAToolkit_FOUND FALSE)
-    unset(fail_base)
-    unset(cuda_root_fail)
-    unset(env_cuda_root_fail)
-    return()
-  endif()
-endif()
-
-# CUDAToolkit_ROOT cmake / env variable not specified, try platform defaults.
-#
-# - Linux: /usr/local/cuda-X.Y
-# - macOS: /Developer/NVIDIA/CUDA-X.Y
-# - Windows: C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\vX.Y
-#
-# We will also search the default symlink location /usr/local/cuda first since
-# if CUDAToolkit_ROOT is not specified, it is assumed that the symlinked
-# directory is the desired location.
-if (NOT CUDAToolkit_NVCC_EXECUTABLE)
-  if (UNIX)
-    if (NOT APPLE)
-      set(platform_base "/usr/local/cuda-")
-    else()
-      set(platform_base "/Developer/NVIDIA/CUDA-")
-    endif()
-  else()
-    set(platform_base "C:\\Program Files\\NVIDIA GPU Computing Toolkit\\CUDA\\v")
-  endif()
-
-  # Build out a descending list of possible cuda installations, e.g.
-  file(GLOB possible_paths "${platform_base}*")
-  # Iterate the glob results and create a descending list.
-  set(possible_versions)
-  foreach (p ${possible_paths})
-    # Extract version number from end of string
-    string(REGEX MATCH "[0-9][0-9]?\\.[0-9]$" p_version ${p})
-    if (IS_DIRECTORY ${p} AND p_version)
-      list(APPEND possible_versions ${p_version})
-    endif()
-  endforeach()
-
-  # Cannot use list(SORT) because that is alphabetical, we need numerical.
-  # NOTE: this is not an efficient sorting strategy.  But even if a user had
-  # every possible version of CUDA installed, this wouldn't create any
-  # significant overhead.
-  set(versions)
-  foreach (v ${possible_versions})
-    list(LENGTH versions num_versions)
-    # First version, nothing to compare with so just append.
-    if (num_versions EQUAL 0)
-      list(APPEND versions ${v})
-    else()
-      # Loop through list.  Insert at an index when comparison is
-      # VERSION_GREATER since we want a descending list.  Duplicates will not
-      # happen since this came from a glob list of directories.
-      set(i 0)
-      set(early_terminate FALSE)
-      while (i LESS num_versions)
-        list(GET versions ${i} curr)
-        if (v VERSION_GREATER curr)
-          list(INSERT versions ${i} ${v})
-          set(early_terminate TRUE)
-          break()
-        endif()
-        math(EXPR i "${i} + 1")
-      endwhile()
-      # If it did not get inserted, place it at the end.
-      if (NOT early_terminate)
-        list(APPEND versions ${v})
-      endif()
-    endif()
-  endforeach()
-
-  # With a descending list of versions, populate possible paths to search.
-  set(search_paths)
-  foreach (v ${versions})
-    list(APPEND search_paths "${platform_base}${v}")
-  endforeach()
-
-  # Force the global default /usr/local/cuda to the front on Unix.
-  if (UNIX)
-    list(INSERT search_paths 0 "/usr/local/cuda")
-  endif()
-
-  # Now search for nvcc again using the platform default search paths.
-  find_program(CUDAToolkit_NVCC_EXECUTABLE
-    NAMES nvcc nvcc.exe
-    PATHS ${search_paths}
-    PATH_SUFFIXES bin
-  )
-
-  # We are done with these variables now, cleanup for caller.
-  unset(platform_base)
-  unset(possible_paths)
-  unset(possible_versions)
-  unset(versions)
-  unset(i)
-  unset(early_terminate)
-  unset(search_paths)
-
-  if (NOT CUDAToolkit_NVCC_EXECUTABLE)
-    if (CUDAToolkit_FIND_REQUIRED)
-      message(FATAL_ERROR "Could not find nvcc, please set CUDAToolkit_ROOT.")
-    elseif(NOT CUDAToolkit_FIND_QUIETLY)
-      message(STATUS "Could not find nvcc, please set CUDAToolkit_ROOT.")
-    endif()
-
-    set(CUDAToolkit_FOUND FALSE)
-    return()
-  endif()
-endif()
-
-if(NOT CUDAToolkit_BIN_DIR AND CUDAToolkit_NVCC_EXECUTABLE)
-  get_filename_component(cuda_dir "${CUDAToolkit_NVCC_EXECUTABLE}" DIRECTORY)
-  set(CUDAToolkit_BIN_DIR "${cuda_dir}" CACHE PATH "" FORCE)
-  mark_as_advanced(CUDAToolkit_BIN_DIR)
-  unset(cuda_dir)
-endif()
-
-if(CUDAToolkit_NVCC_EXECUTABLE AND
-   CUDAToolkit_NVCC_EXECUTABLE STREQUAL CMAKE_CUDA_COMPILER)
-  # Need to set these based off the already computed CMAKE_CUDA_COMPILER_VERSION value
-  # This if statement will always match, but is used to provide variables for MATCH 1,2,3...
-  if(CMAKE_CUDA_COMPILER_VERSION MATCHES [=[([0-9]+)\.([0-9]+)\.([0-9]+)]=])
-    set(CUDAToolkit_VERSION_MAJOR "${CMAKE_MATCH_1}")
-    set(CUDAToolkit_VERSION_MINOR "${CMAKE_MATCH_2}")
-    set(CUDAToolkit_VERSION_PATCH "${CMAKE_MATCH_3}")
-    set(CUDAToolkit_VERSION "${CMAKE_CUDA_COMPILER_VERSION}")
-  endif()
+# The toolkit is located during compiler detection for CUDA and stored in CMakeCUDACompiler.cmake as
+# CMAKE_CUDA_COMPILER_TOOLKIT_ROOT and CMAKE_CUDA_COMPILER_LIBRARY_ROOT.
+# We compute the rest based on those here to avoid re-searching and to avoid finding a possibly
+# different installation.
+if(CMAKE_CUDA_COMPILER_TOOLKIT_ROOT)
+  set(CUDAToolkit_ROOT_DIR "${CMAKE_CUDA_COMPILER_TOOLKIT_ROOT}")
+  set(CUDAToolkit_LIBRARY_ROOT "${CMAKE_CUDA_COMPILER_LIBRARY_ROOT}")
+  set(CUDAToolkit_BIN_DIR "${CUDAToolkit_ROOT_DIR}/bin")
+  set(CUDAToolkit_NVCC_EXECUTABLE "${CUDAToolkit_BIN_DIR}/nvcc${CMAKE_EXECUTABLE_SUFFIX}")
 else()
-  # Compute the version by invoking nvcc
-  execute_process (COMMAND ${CUDAToolkit_NVCC_EXECUTABLE} "--version" OUTPUT_VARIABLE NVCC_OUT)
-  if(NVCC_OUT MATCHES [=[ V([0-9]+)\.([0-9]+)\.([0-9]+)]=])
-    set(CUDAToolkit_VERSION_MAJOR "${CMAKE_MATCH_1}")
-    set(CUDAToolkit_VERSION_MINOR "${CMAKE_MATCH_2}")
-    set(CUDAToolkit_VERSION_PATCH "${CMAKE_MATCH_3}")
-    set(CUDAToolkit_VERSION  "${CMAKE_MATCH_1}.${CMAKE_MATCH_2}.${CMAKE_MATCH_3}")
+
+  function(_CUDAToolkit_find_root_dir )
+    cmake_parse_arguments(arg "" "" "SEARCH_PATHS;FIND_FLAGS" ${ARGN})
+
+
+    if(NOT CUDAToolkit_BIN_DIR)
+      if(NOT CUDAToolkit_SENTINEL_FILE)
+        find_program(CUDAToolkit_NVCC_EXECUTABLE
+          NAMES nvcc nvcc.exe
+          PATHS ${arg_SEARCH_PATHS}
+          ${arg_FIND_FLAGS}
+        )
+      endif()
+
+      if(NOT CUDAToolkit_NVCC_EXECUTABLE)
+        find_file(CUDAToolkit_SENTINEL_FILE
+          NAMES version.txt
+          PATHS ${arg_SEARCH_PATHS}
+          NO_DEFAULT_PATH
+        )
+      endif()
+
+      if(CUDAToolkit_NVCC_EXECUTABLE)
+        get_filename_component(CUDAToolkit_BIN_DIR "${CUDAToolkit_NVCC_EXECUTABLE}" DIRECTORY)
+
+        set(CUDAToolkit_BIN_DIR "${CUDAToolkit_BIN_DIR}" CACHE PATH "" FORCE)
+        mark_as_advanced(CUDAToolkit_BIN_DIR)
+      elseif(CUDAToolkit_SENTINEL_FILE)
+        get_filename_component(CUDAToolkit_BIN_DIR ${CUDAToolkit_SENTINEL_FILE} DIRECTORY ABSOLUTE)
+        set(CUDAToolkit_BIN_DIR "${CUDAToolkit_BIN_DIR}/bin")
+
+        set(CUDAToolkit_BIN_DIR "${CUDAToolkit_BIN_DIR}" CACHE PATH "" FORCE)
+        mark_as_advanced(CUDAToolkit_BIN_DIR)
+      endif()
+    endif()
+
+    if(CUDAToolkit_BIN_DIR)
+      get_filename_component(CUDAToolkit_ROOT_DIR ${CUDAToolkit_BIN_DIR} DIRECTORY ABSOLUTE)
+      set(CUDAToolkit_ROOT_DIR "${CUDAToolkit_ROOT_DIR}" PARENT_SCOPE)
+    endif()
+
+  endfunction()
+
+  function(_CUDAToolkit_find_version_file result_variable)
+    # We first check for a non-scattered installation to prefer it over a scattered installation.
+    if(CUDAToolkit_ROOT AND EXISTS "${CUDAToolkit_ROOT}/version.txt")
+      set(${result_variable} "${CUDAToolkit_ROOT}/version.txt" PARENT_SCOPE)
+    elseif(CUDAToolkit_ROOT_DIR AND EXISTS "${CUDAToolkit_ROOT_DIR}/version.txt")
+      set(${result_variable} "${CUDAToolkit_ROOT_DIR}/version.txt" PARENT_SCOPE)
+    elseif(CMAKE_SYSROOT_LINK AND EXISTS "${CMAKE_SYSROOT_LINK}/usr/lib/cuda/version.txt")
+      set(${result_variable} "${CMAKE_SYSROOT_LINK}/usr/lib/cuda/version.txt" PARENT_SCOPE)
+    elseif(EXISTS "${CMAKE_SYSROOT}/usr/lib/cuda/version.txt")
+      set(${result_variable} "${CMAKE_SYSROOT}/usr/lib/cuda/version.txt" PARENT_SCOPE)
+    endif()
+  endfunction()
+
+  # For NVCC we can easily deduce the SDK binary directory from the compiler path.
+  if(CMAKE_CUDA_COMPILER_LOADED AND NOT CUDAToolkit_BIN_DIR AND CMAKE_CUDA_COMPILER_ID STREQUAL "NVIDIA")
+    get_filename_component(CUDAToolkit_BIN_DIR "${CMAKE_CUDA_COMPILER}" DIRECTORY)
+    set(CUDAToolkit_BIN_DIR "${CUDAToolkit_BIN_DIR}" CACHE PATH "")
+    # Try language provided path first.
+    _CUDAToolkit_find_root_dir(SEARCH_PATHS "${CUDAToolkit_BIN_DIR}" FIND_FLAGS NO_DEFAULT_PATH)
+    mark_as_advanced(CUDAToolkit_BIN_DIR)
   endif()
-  unset(NVCC_OUT)
+
+  # Try user provided path
+  if(NOT CUDAToolkit_ROOT_DIR AND CUDAToolkit_ROOT)
+    _CUDAToolkit_find_root_dir(SEARCH_PATHS "${CUDAToolkit_ROOT}" FIND_FLAGS PATH_SUFFIXES bin NO_DEFAULT_PATH)
+  endif()
+  if(NOT CUDAToolkit_ROOT_DIR)
+    _CUDAToolkit_find_root_dir(FIND_FLAGS PATHS "ENV CUDA_PATH" PATH_SUFFIXES bin)
+  endif()
+
+  # If the user specified CUDAToolkit_ROOT but the toolkit could not be found, this is an error.
+  if(NOT CUDAToolkit_ROOT_DIR AND (DEFINED CUDAToolkit_ROOT OR DEFINED ENV{CUDAToolkit_ROOT}))
+    # Declare error messages now, print later depending on find_package args.
+    set(fail_base "Could not find nvcc executable in path specified by")
+    set(cuda_root_fail "${fail_base} CUDAToolkit_ROOT=${CUDAToolkit_ROOT}")
+    set(env_cuda_root_fail "${fail_base} environment variable CUDAToolkit_ROOT=$ENV{CUDAToolkit_ROOT}")
+
+    if(CUDAToolkit_FIND_REQUIRED)
+      if(DEFINED CUDAToolkit_ROOT)
+        message(FATAL_ERROR ${cuda_root_fail})
+      elseif(DEFINED ENV{CUDAToolkit_ROOT})
+        message(FATAL_ERROR ${env_cuda_root_fail})
+      endif()
+    else()
+      if(NOT CUDAToolkit_FIND_QUIETLY)
+        if(DEFINED CUDAToolkit_ROOT)
+          message(STATUS ${cuda_root_fail})
+        elseif(DEFINED ENV{CUDAToolkit_ROOT})
+          message(STATUS ${env_cuda_root_fail})
+        endif()
+      endif()
+      set(CUDAToolkit_FOUND FALSE)
+      unset(fail_base)
+      unset(cuda_root_fail)
+      unset(env_cuda_root_fail)
+      return()
+    endif()
+  endif()
+
+  # CUDAToolkit_ROOT cmake / env variable not specified, try platform defaults.
+  #
+  # - Linux: /usr/local/cuda-X.Y
+  # - macOS: /Developer/NVIDIA/CUDA-X.Y
+  # - Windows: C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\vX.Y
+  #
+  # We will also search the default symlink location /usr/local/cuda first since
+  # if CUDAToolkit_ROOT is not specified, it is assumed that the symlinked
+  # directory is the desired location.
+  if(NOT CUDAToolkit_ROOT_DIR)
+    if(UNIX)
+      if(NOT APPLE)
+        set(platform_base "/usr/local/cuda-")
+      else()
+        set(platform_base "/Developer/NVIDIA/CUDA-")
+      endif()
+    else()
+      set(platform_base "C:\\Program Files\\NVIDIA GPU Computing Toolkit\\CUDA\\v")
+    endif()
+
+    # Build out a descending list of possible cuda installations, e.g.
+    file(GLOB possible_paths "${platform_base}*")
+    # Iterate the glob results and create a descending list.
+    set(versions)
+    foreach(p ${possible_paths})
+      # Extract version number from end of string
+      string(REGEX MATCH "[0-9][0-9]?\\.[0-9]$" p_version ${p})
+      if(IS_DIRECTORY ${p} AND p_version)
+        list(APPEND versions ${p_version})
+      endif()
+    endforeach()
+
+    # Sort numerically in descending order, so we try the newest versions first.
+    list(SORT versions COMPARE NATURAL ORDER DESCENDING)
+
+    # With a descending list of versions, populate possible paths to search.
+    set(search_paths)
+    foreach(v ${versions})
+      list(APPEND search_paths "${platform_base}${v}")
+    endforeach()
+
+    # Force the global default /usr/local/cuda to the front on Unix.
+    if(UNIX)
+      list(INSERT search_paths 0 "/usr/local/cuda")
+    endif()
+
+    # Now search for the toolkit again using the platform default search paths.
+    _CUDAToolkit_find_root_dir(SEARCH_PATHS "${search_paths}" FIND_FLAGS PATH_SUFFIXES bin)
+
+    # We are done with these variables now, cleanup for caller.
+    unset(platform_base)
+    unset(possible_paths)
+    unset(versions)
+    unset(search_paths)
+
+    if(NOT CUDAToolkit_ROOT_DIR)
+      if(CUDAToolkit_FIND_REQUIRED)
+        message(FATAL_ERROR "Could not find nvcc, please set CUDAToolkit_ROOT.")
+      elseif(NOT CUDAToolkit_FIND_QUIETLY)
+        message(STATUS "Could not find nvcc, please set CUDAToolkit_ROOT.")
+      endif()
+
+      set(CUDAToolkit_FOUND FALSE)
+      return()
+    endif()
+  endif()
+
+  _CUDAToolkit_find_version_file( _CUDAToolkit_version_file )
+  if(_CUDAToolkit_version_file)
+    # CUDAToolkit_LIBRARY_ROOT contains the device library and version file.
+    get_filename_component(CUDAToolkit_LIBRARY_ROOT "${_CUDAToolkit_version_file}" DIRECTORY ABSOLUTE)
+  endif()
+  unset(_CUDAToolkit_version_file)
 endif()
 
-
-get_filename_component(CUDAToolkit_ROOT_DIR ${CUDAToolkit_BIN_DIR} DIRECTORY ABSOLUTE)
-
 # Handle cross compilation
 if(CMAKE_CROSSCOMPILING)
   if(CMAKE_SYSTEM_PROCESSOR STREQUAL "armv7-a")
     # Support for NVPACK
-    set (CUDAToolkit_TARGET_NAME "armv7-linux-androideabi")
+    set(CUDAToolkit_TARGET_NAME "armv7-linux-androideabi")
   elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "arm")
     # Support for arm cross compilation
     set(CUDAToolkit_TARGET_NAME "armv7-linux-gnueabihf")
   elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "aarch64")
     # Support for aarch64 cross compilation
-    if (ANDROID_ARCH_NAME STREQUAL "arm64")
+    if(ANDROID_ARCH_NAME STREQUAL "arm64")
       set(CUDAToolkit_TARGET_NAME "aarch64-linux-androideabi")
     else()
       set(CUDAToolkit_TARGET_NAME "aarch64-linux")
-    endif (ANDROID_ARCH_NAME STREQUAL "arm64")
+    endif(ANDROID_ARCH_NAME STREQUAL "arm64")
   elseif(CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64")
-      set(CUDAToolkit_TARGET_NAME "x86_64-linux")
+    set(CUDAToolkit_TARGET_NAME "x86_64-linux")
   endif()
 
-  if (EXISTS "${CUDAToolkit_ROOT_DIR}/targets/${CUDAToolkit_TARGET_NAME}")
+  if(EXISTS "${CUDAToolkit_ROOT_DIR}/targets/${CUDAToolkit_TARGET_NAME}")
     set(CUDAToolkit_TARGET_DIR "${CUDAToolkit_ROOT_DIR}/targets/${CUDAToolkit_TARGET_NAME}")
     # add known CUDA target root path to the set of directories we search for programs, libraries and headers
     list(PREPEND CMAKE_FIND_ROOT_PATH "${CUDAToolkit_TARGET_DIR}")
@@ -702,29 +709,61 @@
   set(_CUDAToolkit_Pop_Prefix True)
 endif()
 
+# CUDAToolkit_TARGET_DIR always points to the directory containing the include directory.
+# On a scattered installation /usr, on a non-scattered something like /usr/local/cuda or /usr/local/cuda-10.2/targets/aarch64-linux.
+if(EXISTS "${CUDAToolkit_TARGET_DIR}/include/cuda_runtime.h")
+  set(CUDAToolkit_INCLUDE_DIR "${CUDAToolkit_TARGET_DIR}/include")
+elseif(NOT CUDAToolkit_FIND_QUIETLY)
+  message(STATUS "Unable to find cuda_runtime.h in \"${CUDAToolkit_TARGET_DIR}/include\" for CUDAToolkit_INCLUDE_DIR.")
+endif()
 
-# Find the include/ directory
-find_path(CUDAToolkit_INCLUDE_DIR
-  NAMES cuda_runtime.h
-)
+if(CUDAToolkit_NVCC_EXECUTABLE AND
+   CUDAToolkit_NVCC_EXECUTABLE STREQUAL CMAKE_CUDA_COMPILER)
+  # Need to set these based off the already computed CMAKE_CUDA_COMPILER_VERSION value
+  # This if statement will always match, but is used to provide variables for MATCH 1,2,3...
+  if(CMAKE_CUDA_COMPILER_VERSION MATCHES [=[([0-9]+)\.([0-9]+)\.([0-9]+)]=])
+    set(CUDAToolkit_VERSION_MAJOR "${CMAKE_MATCH_1}")
+    set(CUDAToolkit_VERSION_MINOR "${CMAKE_MATCH_2}")
+    set(CUDAToolkit_VERSION_PATCH "${CMAKE_MATCH_3}")
+    set(CUDAToolkit_VERSION "${CMAKE_CUDA_COMPILER_VERSION}")
+  endif()
+elseif(CUDAToolkit_NVCC_EXECUTABLE)
+  # Compute the version by invoking nvcc
+  execute_process(COMMAND ${CUDAToolkit_NVCC_EXECUTABLE} "--version" OUTPUT_VARIABLE NVCC_OUT)
+  if(NVCC_OUT MATCHES [=[ V([0-9]+)\.([0-9]+)\.([0-9]+)]=])
+    set(CUDAToolkit_VERSION_MAJOR "${CMAKE_MATCH_1}")
+    set(CUDAToolkit_VERSION_MINOR "${CMAKE_MATCH_2}")
+    set(CUDAToolkit_VERSION_PATCH "${CMAKE_MATCH_3}")
+    set(CUDAToolkit_VERSION  "${CMAKE_MATCH_1}.${CMAKE_MATCH_2}.${CMAKE_MATCH_3}")
+  endif()
+  unset(NVCC_OUT)
+else()
+  _CUDAToolkit_find_version_file(version_file)
+  if(version_file)
+    file(READ "${version_file}" VERSION_INFO)
+    if(VERSION_INFO MATCHES [=[CUDA Version ([0-9]+)\.([0-9]+)\.([0-9]+)]=])
+      set(CUDAToolkit_VERSION_MAJOR "${CMAKE_MATCH_1}")
+      set(CUDAToolkit_VERSION_MINOR "${CMAKE_MATCH_2}")
+      set(CUDAToolkit_VERSION_PATCH "${CMAKE_MATCH_3}")
+      set(CUDAToolkit_VERSION  "${CMAKE_MATCH_1}.${CMAKE_MATCH_2}.${CMAKE_MATCH_3}")
+    endif()
+  endif()
+endif()
 
-# And find the CUDA Runtime Library libcudart
+# Find the CUDA Runtime Library libcudart
 find_library(CUDA_CUDART
   NAMES cudart
   PATH_SUFFIXES lib64 lib/x64
 )
-if (NOT CUDA_CUDART)
-  find_library(CUDA_CUDART
-    NAMES cudart
-    PATH_SUFFIXES lib64/stubs lib/x64/stubs
-  )
-endif()
+find_library(CUDA_CUDART
+  NAMES cudart
+  PATH_SUFFIXES lib64/stubs lib/x64/stubs
+)
 
-if (NOT CUDA_CUDART AND NOT CUDAToolkit_FIND_QUIETLY)
+if(NOT CUDA_CUDART AND NOT CUDAToolkit_FIND_QUIETLY)
   message(STATUS "Unable to find cudart library.")
 endif()
 
-unset(CUDAToolkit_ROOT_DIR)
 if(_CUDAToolkit_Pop_Prefix)
   list(REMOVE_AT CMAKE_PREFIX_PATH -1)
   unset(_CUDAToolkit_Pop_Prefix)
@@ -737,20 +776,23 @@
   REQUIRED_VARS
     CUDAToolkit_INCLUDE_DIR
     CUDA_CUDART
-    CUDAToolkit_NVCC_EXECUTABLE
+    CUDAToolkit_BIN_DIR
   VERSION_VAR
     CUDAToolkit_VERSION
 )
+
+unset(CUDAToolkit_ROOT_DIR)
 mark_as_advanced(CUDA_CUDART
                  CUDAToolkit_INCLUDE_DIR
                  CUDAToolkit_NVCC_EXECUTABLE
+                 CUDAToolkit_SENTINEL_FILE
                  )
 
 #-----------------------------------------------------------------------------
 # Construct result variables
 if(CUDAToolkit_FOUND)
- set(CUDAToolkit_INCLUDE_DIRS ${CUDAToolkit_INCLUDE_DIR})
- get_filename_component(CUDAToolkit_LIBRARY_DIR ${CUDA_CUDART} DIRECTORY ABSOLUTE)
+  set(CUDAToolkit_INCLUDE_DIRS ${CUDAToolkit_INCLUDE_DIR})
+  get_filename_component(CUDAToolkit_LIBRARY_DIR ${CUDA_CUDART} DIRECTORY ABSOLUTE)
 endif()
 
 #-----------------------------------------------------------------------------
@@ -769,16 +811,14 @@
       PATH_SUFFIXES nvidia/current lib64 lib/x64 lib
                     ${arg_EXTRA_PATH_SUFFIXES}
     )
-    # Don't try any stub directories intil we have exhausted all other
+    # Don't try any stub directories until we have exhausted all other
     # search locations.
-    if(NOT CUDA_${lib_name}_LIBRARY)
-      find_library(CUDA_${lib_name}_LIBRARY
-        NAMES ${search_names}
-        HINTS ${CUDAToolkit_LIBRARY_DIR}
-              ENV CUDA_PATH
-        PATH_SUFFIXES lib64/stubs lib/x64/stubs lib/stubs stubs
-      )
-    endif()
+    find_library(CUDA_${lib_name}_LIBRARY
+      NAMES ${search_names}
+      HINTS ${CUDAToolkit_LIBRARY_DIR}
+            ENV CUDA_PATH
+      PATH_SUFFIXES lib64/stubs lib/x64/stubs lib/stubs stubs
+    )
 
     mark_as_advanced(CUDA_${lib_name}_LIBRARY)
 
@@ -832,7 +872,7 @@
   endif()
 
   _CUDAToolkit_find_and_add_import_lib(culibos) # it's a static library
-  foreach (cuda_lib cublas cufft curand cusparse nppc nvjpeg)
+  foreach (cuda_lib cublasLt cublas cufft curand cusparse nppc nvjpeg)
     _CUDAToolkit_find_and_add_import_lib(${cuda_lib})
     _CUDAToolkit_find_and_add_import_lib(${cuda_lib}_static DEPS culibos)
   endforeach()
diff --git a/Modules/FindCURL.cmake b/Modules/FindCURL.cmake
index 919babc..74b36c6 100644
--- a/Modules/FindCURL.cmake
+++ b/Modules/FindCURL.cmake
@@ -92,6 +92,7 @@
       curllib_static
     # Windows older "Win32 - MSVC" prebuilts (libcurl.lib, e.g. libcurl-7.15.5-win32-msvc.zip):
       libcurl
+      NAMES_PER_DIR
       HINTS ${PC_CURL_LIBRARY_DIRS}
   )
   mark_as_advanced(CURL_LIBRARY_RELEASE)
@@ -100,6 +101,7 @@
     # Windows MSVC CMake builds in debug configuration on vcpkg:
       libcurl-d_imp
       libcurl-d
+      NAMES_PER_DIR
       HINTS ${PC_CURL_LIBRARY_DIRS}
   )
   mark_as_advanced(CURL_LIBRARY_DEBUG)
@@ -148,16 +150,16 @@
   endif()
   foreach(component IN LISTS CURL_FIND_COMPONENTS)
     list(FIND CURL_KNOWN_PROTOCOLS ${component} _found)
-    if(_found)
+    if(NOT _found EQUAL -1)
       list(FIND CURL_SUPPORTED_PROTOCOLS ${component} _found)
-      if(_found)
+      if(NOT _found EQUAL -1)
         set(CURL_${component}_FOUND TRUE)
       elseif(CURL_FIND_REQUIRED)
         message(FATAL_ERROR "CURL: Required protocol ${component} is not found")
       endif()
     else()
       list(FIND CURL_SUPPORTED_FEATURES ${component} _found)
-      if(_found)
+      if(NOT _found EQUAL -1)
         set(CURL_${component}_FOUND TRUE)
       elseif(CURL_FIND_REQUIRED)
         message(FATAL_ERROR "CURL: Required feature ${component} is not found")
diff --git a/Modules/FindCurses.cmake b/Modules/FindCurses.cmake
index ba56078..cde3a4d 100644
--- a/Modules/FindCurses.cmake
+++ b/Modules/FindCurses.cmake
@@ -156,7 +156,9 @@
 
   CHECK_LIBRARY_EXISTS("${CURSES_NCURSES_LIBRARY}"
     cbreak "" CURSES_NCURSES_HAS_CBREAK)
-  if(NOT CURSES_NCURSES_HAS_CBREAK)
+  CHECK_LIBRARY_EXISTS("${CURSES_NCURSES_LIBRARY}"
+    nodelay "" CURSES_NCURSES_HAS_NODELAY)
+  if(NOT CURSES_NCURSES_HAS_CBREAK OR NOT CURSES_NCURSES_HAS_NODELAY)
     find_library(CURSES_EXTRA_LIBRARY "${CURSES_TINFO_LIBRARY_NAME}" HINTS "${_cursesLibDir}")
     find_library(CURSES_EXTRA_LIBRARY "${CURSES_TINFO_LIBRARY_NAME}" )
 
diff --git a/Modules/FindDoxygen.cmake b/Modules/FindDoxygen.cmake
index faa03f9..184a9a2 100644
--- a/Modules/FindDoxygen.cmake
+++ b/Modules/FindDoxygen.cmake
@@ -999,9 +999,11 @@
     foreach(_item IN LISTS DOXYGEN_INPUT)
         get_filename_component(_abs_item "${_item}" ABSOLUTE
                                BASE_DIR "${_args_WORKING_DIRECTORY}")
-        if(EXISTS "${_abs_item}" AND
-           NOT IS_DIRECTORY "${_abs_item}" AND
-           NOT IS_SYMLINK "${_abs_item}")
+        get_source_file_property(_isGenerated "${_abs_item}" GENERATED)
+        if(_isGenerated OR
+           (EXISTS "${_abs_item}" AND
+            NOT IS_DIRECTORY "${_abs_item}" AND
+            NOT IS_SYMLINK "${_abs_item}"))
             list(APPEND _sources "${_abs_item}")
         elseif(_args_USE_STAMP_FILE)
             message(FATAL_ERROR "Source does not exist or is not a file:\n"
diff --git a/Modules/FindEXPAT.cmake b/Modules/FindEXPAT.cmake
index 15b419a..b0bb02a 100644
--- a/Modules/FindEXPAT.cmake
+++ b/Modules/FindEXPAT.cmake
@@ -38,7 +38,7 @@
 find_path(EXPAT_INCLUDE_DIR NAMES expat.h HINTS ${PC_EXPAT_INCLUDE_DIRS})
 
 # Look for the library.
-find_library(EXPAT_LIBRARY NAMES expat libexpat HINTS ${PC_EXPAT_LIBRARY_DIRS})
+find_library(EXPAT_LIBRARY NAMES expat libexpat NAMES_PER_DIR HINTS ${PC_EXPAT_LIBRARY_DIRS})
 
 if (EXPAT_INCLUDE_DIR AND EXISTS "${EXPAT_INCLUDE_DIR}/expat.h")
     file(STRINGS "${EXPAT_INCLUDE_DIR}/expat.h" expat_version_str
diff --git a/Modules/FindEnvModules.cmake b/Modules/FindEnvModules.cmake
index 4dd5116..a4ac0b4 100644
--- a/Modules/FindEnvModules.cmake
+++ b/Modules/FindEnvModules.cmake
@@ -5,6 +5,8 @@
 FindEnvModules
 --------------
 
+.. versionadded:: 3.15
+
 Locate an environment module implementation and make commands available to
 CMake scripts to use them.  This is compatible with both Lua-based Lmod
 and TCL-based EnvironmentModules.
diff --git a/Modules/FindFLEX.cmake b/Modules/FindFLEX.cmake
index 90e5f86..1384736 100644
--- a/Modules/FindFLEX.cmake
+++ b/Modules/FindFLEX.cmake
@@ -99,7 +99,7 @@
   ====================================================================
 #]=======================================================================]
 
-find_program(FLEX_EXECUTABLE NAMES flex win_flex DOC "path to the flex executable")
+find_program(FLEX_EXECUTABLE NAMES flex win-flex win_flex DOC "path to the flex executable")
 mark_as_advanced(FLEX_EXECUTABLE)
 
 find_library(FL_LIBRARY NAMES fl
diff --git a/Modules/FindFontconfig.cmake b/Modules/FindFontconfig.cmake
index a6f0180..5228831 100644
--- a/Modules/FindFontconfig.cmake
+++ b/Modules/FindFontconfig.cmake
@@ -5,6 +5,8 @@
 FindFontconfig
 --------------
 
+.. versionadded:: 3.14
+
 Find Fontconfig headers and library.
 
 Imported Targets
diff --git a/Modules/FindGIF.cmake b/Modules/FindGIF.cmake
index d5a143e..cea9cd8 100644
--- a/Modules/FindGIF.cmake
+++ b/Modules/FindGIF.cmake
@@ -60,6 +60,7 @@
 
 find_library(GIF_LIBRARY
   NAMES ${POTENTIAL_GIF_LIBS}
+  NAMES_PER_DIR
   HINTS
     ENV GIF_DIR
   PATH_SUFFIXES lib
diff --git a/Modules/FindGLEW.cmake b/Modules/FindGLEW.cmake
index 27ffa13..080371a 100644
--- a/Modules/FindGLEW.cmake
+++ b/Modules/FindGLEW.cmake
@@ -139,11 +139,13 @@
 
 find_library(GLEW_SHARED_LIBRARY_RELEASE
              NAMES GLEW glew glew32
+             NAMES_PER_DIR
              PATH_SUFFIXES lib lib64 libx32 lib/Release/${_arch}
              PATHS ENV GLEW_ROOT)
 
 find_library(GLEW_SHARED_LIBRARY_DEBUG
              NAMES GLEWd glewd glew32d
+             NAMES_PER_DIR
              PATH_SUFFIXES lib lib64
              PATHS ENV GLEW_ROOT)
 
@@ -152,11 +154,13 @@
 
 find_library(GLEW_STATIC_LIBRARY_RELEASE
              NAMES GLEW glew glew32s
+             NAMES_PER_DIR
              PATH_SUFFIXES lib lib64 libx32 lib/Release/${_arch}
              PATHS ENV GLEW_ROOT)
 
 find_library(GLEW_STATIC_LIBRARY_DEBUG
              NAMES GLEWds glewds glew32ds
+             NAMES_PER_DIR
              PATH_SUFFIXES lib lib64
              PATHS ENV GLEW_ROOT)
 
diff --git a/Modules/FindGSL.cmake b/Modules/FindGSL.cmake
index da1b3c4..3d4e7f9 100644
--- a/Modules/FindGSL.cmake
+++ b/Modules/FindGSL.cmake
@@ -5,6 +5,8 @@
 FindGSL
 --------
 
+.. versionadded:: 3.2
+
 Find the native GNU Scientific Library (GSL) includes and libraries.
 
 The GNU Scientific Library (GSL) is a numerical library for C and C++
diff --git a/Modules/FindGTest.cmake b/Modules/FindGTest.cmake
index 53cab1a..10e31b2 100644
--- a/Modules/FindGTest.cmake
+++ b/Modules/FindGTest.cmake
@@ -96,6 +96,27 @@
     mark_as_advanced(${_name})
 endfunction()
 
+function(__gtest_find_library_configuration _name _lib _cfg_suffix)
+    set(_libs ${_lib})
+    if(MSVC AND GTEST_MSVC_SEARCH STREQUAL "MD")
+        # The provided /MD project files for Google Test add -md suffixes to the
+        # library names.
+        list(INSERT _libs 0 ${_lib}-md)
+    endif()
+    list(TRANSFORM _libs APPEND "${_cfg_suffix}")
+
+    __gtest_find_library(${_name} ${_libs})
+endfunction()
+
+include(${CMAKE_CURRENT_LIST_DIR}/SelectLibraryConfigurations.cmake)
+function(__gtest_find_and_select_library_configurations _basename _lib)
+    __gtest_find_library_configuration(${_basename}_LIBRARY_RELEASE ${_lib} "")
+    __gtest_find_library_configuration(${_basename}_LIBRARY_DEBUG   ${_lib} "d")
+
+    select_library_configurations(${_basename})
+    set(${_basename}_LIBRARY ${${_basename}_LIBRARY} PARENT_SCOPE)
+endfunction()
+
 macro(__gtest_determine_windows_library_type _var)
     if(EXISTS "${${_var}}")
         file(TO_NATIVE_PATH "${${_var}}" _lib_path)
@@ -187,18 +208,13 @@
 )
 mark_as_advanced(GTEST_INCLUDE_DIR)
 
-if(MSVC AND GTEST_MSVC_SEARCH STREQUAL "MD")
-    # The provided /MD project files for Google Test add -md suffixes to the
-    # library names.
-    __gtest_find_library(GTEST_LIBRARY            gtest-md  gtest)
-    __gtest_find_library(GTEST_LIBRARY_DEBUG      gtest-mdd gtestd)
-    __gtest_find_library(GTEST_MAIN_LIBRARY       gtest_main-md  gtest_main)
-    __gtest_find_library(GTEST_MAIN_LIBRARY_DEBUG gtest_main-mdd gtest_maind)
-else()
-    __gtest_find_library(GTEST_LIBRARY            gtest)
-    __gtest_find_library(GTEST_LIBRARY_DEBUG      gtestd)
-    __gtest_find_library(GTEST_MAIN_LIBRARY       gtest_main)
-    __gtest_find_library(GTEST_MAIN_LIBRARY_DEBUG gtest_maind)
+# Allow GTEST_LIBRARY and GTEST_MAIN_LIBRARY to be set manually, as the
+# locations of the gtest and gtest_main libraries, respectively.
+if(NOT GTEST_LIBRARY)
+    __gtest_find_and_select_library_configurations(GTEST gtest)
+endif()
+if(NOT GTEST_MAIN_LIBRARY)
+    __gtest_find_and_select_library_configurations(GTEST_MAIN gtest_main)
 endif()
 
 include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
diff --git a/Modules/FindHDF5.cmake b/Modules/FindHDF5.cmake
index b488418..7a1c252 100644
--- a/Modules/FindHDF5.cmake
+++ b/Modules/FindHDF5.cmake
@@ -19,9 +19,12 @@
 ``COMPONENTS`` are specified, then the find module will default to finding
 only the ``HDF5`` C library.  If one or more ``COMPONENTS`` are specified, the
 module will attempt to find the language bindings for the specified
-components.  The only valid components are ``C``, ``CXX``, ``Fortran``, ``HL``,
-and ``Fortran_HL``.  If the ``COMPONENTS`` argument is not given, the module will
+components.  The valid components are ``C``, ``CXX``, ``Fortran``, ``HL``.
+``HL`` refers to the "high-level" HDF5 functions for C and Fortran.
+If the ``COMPONENTS`` argument is not given, the module will
 attempt to find only the C bindings.
+For example, to use Fortran HDF5 and HDF5-HL functions, do:
+``find_package(HDF5 COMPONENTS Fortran HL)``.
 
 This module will read the variable
 ``HDF5_USE_STATIC_LIBRARIES`` to determine whether or not to prefer a
@@ -29,16 +32,11 @@
 To use this feature, make sure that the ``HDF5_USE_STATIC_LIBRARIES``
 variable is set before the call to find_package.
 
-To provide the module with a hint about where to find your ``HDF5``
-installation, you can set the environment variable ``HDF5_ROOT``.  The
-Find module will then look in this path when searching for ``HDF5``
-executables, paths, and libraries.
-
 Both the serial and parallel ``HDF5`` wrappers are considered and the first
 directory to contain either one will be used.  In the event that both appear
 in the same directory the serial version is preferentially selected. This
 behavior can be reversed by setting the variable ``HDF5_PREFER_PARALLEL`` to
-``True``.
+``TRUE``.
 
 In addition to finding the includes and libraries required to compile
 an ``HDF5`` client application, this module also makes an effort to find
@@ -115,10 +113,10 @@
 Hints
 ^^^^^
 
-The following variable can be set to guide the search for HDF5 libraries and includes:
+The following variables can be set to guide the search for HDF5 libraries and includes:
 
-``HDF5_ROOT``
-  Specify the path to the HDF5 installation to use.
+``HDF5_PREFER_PARALLEL``
+  set ``true`` to prefer parallel HDF5 (by default, serial is preferred)
 
 ``HDF5_FIND_DEBUG``
   Set ``true`` to get extra debugging output.
@@ -127,8 +125,6 @@
   Set ``true`` to skip trying to find ``hdf5-config.cmake``.
 #]=======================================================================]
 
-# This module is maintained by Will Dicharry <wdicharry@stellarscience.com>.
-
 include(${CMAKE_CURRENT_LIST_DIR}/SelectLibraryConfigurations.cmake)
 include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
 
@@ -141,28 +137,30 @@
 else()
   set(HDF5_LANGUAGE_BINDINGS)
   # add the extra specified components, ensuring that they are valid.
-  set(FIND_HL OFF)
-  foreach(component IN LISTS HDF5_FIND_COMPONENTS)
-    list(FIND HDF5_VALID_LANGUAGE_BINDINGS ${component} component_location)
-    if(NOT component_location EQUAL -1)
-      list(APPEND HDF5_LANGUAGE_BINDINGS ${component})
-    elseif(component STREQUAL "HL")
-      set(FIND_HL ON)
-    elseif(component STREQUAL "Fortran_HL") # only for compatibility
+  set(HDF5_FIND_HL OFF)
+  foreach(_component IN LISTS HDF5_FIND_COMPONENTS)
+    list(FIND HDF5_VALID_LANGUAGE_BINDINGS ${_component} _component_location)
+    if(NOT _component_location EQUAL -1)
+      list(APPEND HDF5_LANGUAGE_BINDINGS ${_component})
+    elseif(_component STREQUAL "HL")
+      set(HDF5_FIND_HL ON)
+    elseif(_component STREQUAL "Fortran_HL") # only for compatibility
       list(APPEND HDF5_LANGUAGE_BINDINGS Fortran)
-      set(FIND_HL ON)
-      set(HDF5_FIND_REQUIRED_Fortran_HL False)
-      set(HDF5_FIND_REQUIRED_Fortran True)
-      set(HDF5_FIND_REQUIRED_HL True)
+      set(HDF5_FIND_HL ON)
+      set(HDF5_FIND_REQUIRED_Fortran_HL FALSE)
+      set(HDF5_FIND_REQUIRED_Fortran TRUE)
+      set(HDF5_FIND_REQUIRED_HL TRUE)
     else()
-      message(FATAL_ERROR "${component} is not a valid HDF5 component.")
+      message(FATAL_ERROR "${_component} is not a valid HDF5 component.")
     endif()
   endforeach()
+  unset(_component)
+  unset(_component_location)
   if(NOT HDF5_LANGUAGE_BINDINGS)
-    get_property(__langs GLOBAL PROPERTY ENABLED_LANGUAGES)
-    foreach(__lang IN LISTS __langs)
-      if(__lang MATCHES "^(C|CXX|Fortran)$")
-        list(APPEND HDF5_LANGUAGE_BINDINGS ${__lang})
+    get_property(_langs GLOBAL PROPERTY ENABLED_LANGUAGES)
+    foreach(_lang IN LISTS _langs)
+      if(_lang MATCHES "^(C|CXX|Fortran)$")
+        list(APPEND HDF5_LANGUAGE_BINDINGS ${_lang})
       endif()
     endforeach()
   endif()
@@ -328,97 +326,111 @@
 
 # Invoke the HDF5 wrapper compiler.  The compiler return value is stored to the
 # return_value argument, the text output is stored to the output variable.
-macro( _HDF5_invoke_compiler language output return_value version is_parallel)
-    set(${version})
-    if(HDF5_USE_STATIC_LIBRARIES)
-        set(lib_type_args -noshlib)
-    else()
-        set(lib_type_args -shlib)
-    endif()
-    set(scratch_dir ${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/hdf5)
-    if("${language}" STREQUAL "C")
-        set(test_file ${scratch_dir}/cmake_hdf5_test.c)
-    elseif("${language}" STREQUAL "CXX")
-        set(test_file ${scratch_dir}/cmake_hdf5_test.cxx)
-    elseif("${language}" STREQUAL "Fortran")
-        set(test_file ${scratch_dir}/cmake_hdf5_test.f90)
-    endif()
+function( _HDF5_invoke_compiler language output_var return_value_var version_var is_parallel_var)
+  set(is_parallel FALSE)
+  if(HDF5_USE_STATIC_LIBRARIES)
+    set(lib_type_args -noshlib)
+  else()
+    set(lib_type_args -shlib)
+  endif()
+  set(scratch_dir ${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/hdf5)
+  if("${language}" STREQUAL "C")
+    set(test_file ${scratch_dir}/cmake_hdf5_test.c)
+  elseif("${language}" STREQUAL "CXX")
+    set(test_file ${scratch_dir}/cmake_hdf5_test.cxx)
+  elseif("${language}" STREQUAL "Fortran")
+    set(test_file ${scratch_dir}/cmake_hdf5_test.f90)
+  endif()
+  # Verify that the compiler wrapper can actually compile: sometimes the compiler
+  # wrapper exists, but not the compiler.  E.g. Miniconda / Anaconda Python
+  execute_process(
+    COMMAND ${HDF5_${language}_COMPILER_EXECUTABLE} ${test_file}
+    WORKING_DIRECTORY ${scratch_dir}
+    RESULT_VARIABLE return_value
+    )
+  if(return_value)
+    message(STATUS
+      "HDF5 ${language} compiler wrapper is unable to compile a minimal HDF5 program.")
+  else()
     execute_process(
       COMMAND ${HDF5_${language}_COMPILER_EXECUTABLE} -show ${lib_type_args} ${test_file}
-      OUTPUT_VARIABLE ${output}
-      ERROR_VARIABLE ${output}
-      RESULT_VARIABLE ${return_value}
+      WORKING_DIRECTORY ${scratch_dir}
+      OUTPUT_VARIABLE output
+      ERROR_VARIABLE output
+      RESULT_VARIABLE return_value
+      OUTPUT_STRIP_TRAILING_WHITESPACE
       )
-    if(NOT ${${return_value}} EQUAL 0)
-        message(STATUS
-          "Unable to determine HDF5 ${language} flags from HDF5 wrapper.")
+    if(return_value)
+      message(STATUS
+        "Unable to determine HDF5 ${language} flags from HDF5 wrapper.")
     endif()
     execute_process(
       COMMAND ${HDF5_${language}_COMPILER_EXECUTABLE} -showconfig
       OUTPUT_VARIABLE config_output
       ERROR_VARIABLE config_output
-      RESULT_VARIABLE config_return
+      RESULT_VARIABLE return_value
+      OUTPUT_STRIP_TRAILING_WHITESPACE
       )
-    if(NOT ${return_value} EQUAL 0)
-        message( STATUS
-          "Unable to determine HDF5 ${language} version from HDF5 wrapper.")
+    if(return_value)
+      message(STATUS
+        "Unable to determine HDF5 ${language} version_var from HDF5 wrapper.")
     endif()
-    string(REGEX MATCH "HDF5 Version: ([a-zA-Z0-9\\.\\-]*)" version_match "${config_output}")
-    if(version_match)
-        string(REPLACE "HDF5 Version: " "" ${version} "${version_match}")
-        string(REPLACE "-patch" "." ${version} "${${version}}")
+    string(REGEX MATCH "HDF5 Version: ([a-zA-Z0-9\\.\\-]*)" version "${config_output}")
+    if(version)
+      string(REPLACE "HDF5 Version: " "" version "${version}")
+      string(REPLACE "-patch" "." version "${version}")
     endif()
     if(config_output MATCHES "Parallel HDF5: yes")
-      set(${is_parallel} TRUE)
-    else()
-      set(${is_parallel} FALSE)
+      set(is_parallel TRUE)
     endif()
-endmacro()
+  endif()
+  foreach(var output return_value version is_parallel)
+    set(${${var}_var} ${${var}} PARENT_SCOPE)
+  endforeach()
+endfunction()
 
 # Parse a compile line for definitions, includes, library paths, and libraries.
-macro( _HDF5_parse_compile_line
-    compile_line_var
-    include_paths
-    definitions
-    library_paths
-    libraries
-    libraries_hl)
+function(_HDF5_parse_compile_line compile_line_var include_paths definitions
+    library_paths libraries libraries_hl)
 
-  separate_arguments(_HDF5_COMPILE_ARGS NATIVE_COMMAND "${${compile_line_var}}")
+  separate_arguments(_compile_args NATIVE_COMMAND "${${compile_line_var}}")
 
-  foreach(arg IN LISTS _HDF5_COMPILE_ARGS)
-    if("${arg}" MATCHES "^-I(.*)$")
+  foreach(_arg IN LISTS _compile_args)
+    if("${_arg}" MATCHES "^-I(.*)$")
       # include directory
-      list(APPEND ${include_paths} "${CMAKE_MATCH_1}")
-    elseif("${arg}" MATCHES "^-D(.*)$")
+      list(APPEND include_paths "${CMAKE_MATCH_1}")
+    elseif("${_arg}" MATCHES "^-D(.*)$")
       # compile definition
-      list(APPEND ${definitions} "-D${CMAKE_MATCH_1}")
-    elseif("${arg}" MATCHES "^-L(.*)$")
+      list(APPEND definitions "-D${CMAKE_MATCH_1}")
+    elseif("${_arg}" MATCHES "^-L(.*)$")
       # library search path
-      list(APPEND ${library_paths} "${CMAKE_MATCH_1}")
-    elseif("${arg}" MATCHES "^-l(hdf5.*hl.*)$")
+      list(APPEND library_paths "${CMAKE_MATCH_1}")
+    elseif("${_arg}" MATCHES "^-l(hdf5.*hl.*)$")
       # library name (hl)
-      list(APPEND ${libraries_hl} "${CMAKE_MATCH_1}")
-    elseif("${arg}" MATCHES "^-l(.*)$")
+      list(APPEND libraries_hl "${CMAKE_MATCH_1}")
+    elseif("${_arg}" MATCHES "^-l(.*)$")
       # library name
-      list(APPEND ${libraries} "${CMAKE_MATCH_1}")
-    elseif("${arg}" MATCHES "^(.:)?[/\\].*\\.(a|so|dylib|sl|lib)$")
+      list(APPEND libraries "${CMAKE_MATCH_1}")
+    elseif("${_arg}" MATCHES "^(.:)?[/\\].*\\.(a|so|dylib|sl|lib)$")
       # library file
-      if(NOT EXISTS "${arg}")
+      if(NOT EXISTS "${_arg}")
         continue()
       endif()
-      get_filename_component(_HDF5_LPATH "${arg}" DIRECTORY)
-      get_filename_component(_HDF5_LNAME "${arg}" NAME_WE)
-      string(REGEX REPLACE "^lib" "" _HDF5_LNAME "${_HDF5_LNAME}")
-      list(APPEND ${library_paths} "${_HDF5_LPATH}")
-      if(_HDF5_LNAME MATCHES "hdf5.*hl")
-        list(APPEND ${libraries_hl} "${_HDF5_LNAME}")
+      get_filename_component(_lpath "${_arg}" DIRECTORY)
+      get_filename_component(_lname "${_arg}" NAME_WE)
+      string(REGEX REPLACE "^lib" "" _lname "${_lname}")
+      list(APPEND library_paths "${_lpath}")
+      if(_lname MATCHES "hdf5.*hl")
+        list(APPEND libraries_hl "${_lname}")
       else()
-        list(APPEND ${libraries} "${_HDF5_LNAME}")
+        list(APPEND libraries "${_lname}")
       endif()
     endif()
   endforeach()
-endmacro()
+  foreach(var include_paths definitions library_paths libraries libraries_hl)
+    set(${${var}_var} ${${var}} PARENT_SCOPE)
+  endforeach()
+endfunction()
 
 # Select a preferred imported configuration from a target
 function(_HDF5_select_imported_config target imported_conf)
@@ -528,10 +540,10 @@
                 set(HDF5_${_lang}_LIBRARY ${_hdf5_lang_location})
                 list(APPEND HDF5_LIBRARIES ${HDF5_${_lang}_TARGET}${_suffix})
                 set(HDF5_${_lang}_LIBRARIES ${HDF5_${_lang}_TARGET}${_suffix})
-                set(HDF5_${_lang}_FOUND True)
+                set(HDF5_${_lang}_FOUND TRUE)
             endif()
-            if(FIND_HL)
-                get_target_property(__lang_hl_location ${HDF5_${_lang}_HL_TARGET}${_suffix} IMPORTED_IMPLIB_${_hdf5_imported_conf} )
+            if(HDF5_FIND_HL)
+                get_target_property(_lang_hl_location ${HDF5_${_lang}_HL_TARGET}${_suffix} IMPORTED_IMPLIB_${_hdf5_imported_conf} )
                 if (NOT _hdf5_lang_hl_location)
                     get_target_property(_hdf5_lang_hl_location ${HDF5_${_lang}_HL_TARGET}${_suffix} LOCATION_${_hdf5_imported_conf})
                     if (NOT _hdf5_hl_lang_location)
@@ -542,7 +554,7 @@
                     set(HDF5_${_lang}_HL_LIBRARY ${_hdf5_lang_hl_location})
                     list(APPEND HDF5_HL_LIBRARIES ${HDF5_${_lang}_HL_TARGET}${_suffix})
                     set(HDF5_${_lang}_HL_LIBRARIES ${HDF5_${_lang}_HL_TARGET}${_suffix})
-                    set(HDF5_HL_FOUND True)
+                    set(HDF5_HL_FOUND TRUE)
                 endif()
                 unset(_hdf5_lang_hl_location)
             endif()
@@ -553,172 +565,177 @@
 endif()
 
 if(NOT HDF5_FOUND)
-  set(_HDF5_NEED_TO_SEARCH False)
-  set(HDF5_COMPILER_NO_INTERROGATE True)
+  set(_HDF5_NEED_TO_SEARCH FALSE)
+  set(HDF5_COMPILER_NO_INTERROGATE TRUE)
   # Only search for languages we've enabled
-  foreach(__lang IN LISTS HDF5_LANGUAGE_BINDINGS)
+  foreach(_lang IN LISTS HDF5_LANGUAGE_BINDINGS)
     # First check to see if our regular compiler is one of wrappers
-    if(__lang STREQUAL "C")
+    if(_lang STREQUAL "C")
       _HDF5_test_regular_compiler_C(
-        HDF5_${__lang}_COMPILER_NO_INTERROGATE
-        HDF5_${__lang}_VERSION
-        HDF5_${__lang}_IS_PARALLEL)
-    elseif(__lang STREQUAL "CXX")
+        HDF5_${_lang}_COMPILER_NO_INTERROGATE
+        HDF5_${_lang}_VERSION
+        HDF5_${_lang}_IS_PARALLEL)
+    elseif(_lang STREQUAL "CXX")
       _HDF5_test_regular_compiler_CXX(
-        HDF5_${__lang}_COMPILER_NO_INTERROGATE
-        HDF5_${__lang}_VERSION
-        HDF5_${__lang}_IS_PARALLEL)
-    elseif(__lang STREQUAL "Fortran")
+        HDF5_${_lang}_COMPILER_NO_INTERROGATE
+        HDF5_${_lang}_VERSION
+        HDF5_${_lang}_IS_PARALLEL)
+    elseif(_lang STREQUAL "Fortran")
       _HDF5_test_regular_compiler_Fortran(
-        HDF5_${__lang}_COMPILER_NO_INTERROGATE
-        HDF5_${__lang}_IS_PARALLEL)
+        HDF5_${_lang}_COMPILER_NO_INTERROGATE
+        HDF5_${_lang}_IS_PARALLEL)
     else()
       continue()
     endif()
-    if(HDF5_${__lang}_COMPILER_NO_INTERROGATE)
-      message(STATUS "HDF5: Using hdf5 compiler wrapper for all ${__lang} compiling")
-      set(HDF5_${__lang}_FOUND True)
-      set(HDF5_${__lang}_COMPILER_EXECUTABLE_NO_INTERROGATE
-          "${CMAKE_${__lang}_COMPILER}"
-          CACHE FILEPATH "HDF5 ${__lang} compiler wrapper")
-      set(HDF5_${__lang}_DEFINITIONS)
-      set(HDF5_${__lang}_INCLUDE_DIRS)
-      set(HDF5_${__lang}_LIBRARIES)
-      set(HDF5_${__lang}_HL_LIBRARIES)
+    if(HDF5_${_lang}_COMPILER_NO_INTERROGATE)
+      if(HDF5_FIND_DEBUG)
+        message(STATUS "HDF5: Using hdf5 compiler wrapper for all ${_lang} compiling")
+      endif()
+      set(HDF5_${_lang}_FOUND TRUE)
+      set(HDF5_${_lang}_COMPILER_EXECUTABLE_NO_INTERROGATE
+          "${CMAKE_${_lang}_COMPILER}"
+          CACHE FILEPATH "HDF5 ${_lang} compiler wrapper")
+      set(HDF5_${_lang}_DEFINITIONS)
+      set(HDF5_${_lang}_INCLUDE_DIRS)
+      set(HDF5_${_lang}_LIBRARIES)
+      set(HDF5_${_lang}_HL_LIBRARIES)
 
-      mark_as_advanced(HDF5_${__lang}_COMPILER_EXECUTABLE_NO_INTERROGATE)
+      mark_as_advanced(HDF5_${_lang}_COMPILER_EXECUTABLE_NO_INTERROGATE)
 
-      set(HDF5_${__lang}_FOUND True)
-      set(HDF5_HL_FOUND True)
+      set(HDF5_${_lang}_FOUND TRUE)
+      set(HDF5_HL_FOUND TRUE)
     else()
-      set(HDF5_COMPILER_NO_INTERROGATE False)
+      set(HDF5_COMPILER_NO_INTERROGATE FALSE)
       # If this language isn't using the wrapper, then try to seed the
       # search options with the wrapper
-      find_program(HDF5_${__lang}_COMPILER_EXECUTABLE
-        NAMES ${HDF5_${__lang}_COMPILER_NAMES} NAMES_PER_DIR
+      find_program(HDF5_${_lang}_COMPILER_EXECUTABLE
+        NAMES ${HDF5_${_lang}_COMPILER_NAMES} NAMES_PER_DIR
         HINTS ${HDF5_ROOT}
         PATH_SUFFIXES bin Bin
-        DOC "HDF5 ${__lang} Wrapper compiler.  Used only to detect HDF5 compile flags."
+        DOC "HDF5 ${_lang} Wrapper compiler.  Used only to detect HDF5 compile flags."
         ${_HDF5_SEARCH_OPTS}
       )
-      mark_as_advanced( HDF5_${__lang}_COMPILER_EXECUTABLE )
-      unset(HDF5_${__lang}_COMPILER_NAMES)
+      mark_as_advanced( HDF5_${_lang}_COMPILER_EXECUTABLE )
+      unset(HDF5_${_lang}_COMPILER_NAMES)
 
-      if(HDF5_${__lang}_COMPILER_EXECUTABLE)
-        _HDF5_invoke_compiler(${__lang} HDF5_${__lang}_COMPILE_LINE
-          HDF5_${__lang}_RETURN_VALUE HDF5_${__lang}_VERSION HDF5_${__lang}_IS_PARALLEL)
-        if(HDF5_${__lang}_RETURN_VALUE EQUAL 0)
-          message(STATUS "HDF5: Using hdf5 compiler wrapper to determine ${__lang} configuration")
-          _HDF5_parse_compile_line( HDF5_${__lang}_COMPILE_LINE
-            HDF5_${__lang}_INCLUDE_DIRS
-            HDF5_${__lang}_DEFINITIONS
-            HDF5_${__lang}_LIBRARY_DIRS
-            HDF5_${__lang}_LIBRARY_NAMES
-            HDF5_${__lang}_HL_LIBRARY_NAMES
+      if(HDF5_${_lang}_COMPILER_EXECUTABLE)
+        _HDF5_invoke_compiler(${_lang} HDF5_${_lang}_COMPILE_LINE
+          HDF5_${_lang}_RETURN_VALUE HDF5_${_lang}_VERSION HDF5_${_lang}_IS_PARALLEL)
+        if(HDF5_${_lang}_RETURN_VALUE EQUAL 0)
+          if(HDF5_FIND_DEBUG)
+            message(STATUS "HDF5: Using hdf5 compiler wrapper to determine ${_lang} configuration")
+          endif()
+          _HDF5_parse_compile_line( HDF5_${_lang}_COMPILE_LINE
+            HDF5_${_lang}_INCLUDE_DIRS
+            HDF5_${_lang}_DEFINITIONS
+            HDF5_${_lang}_LIBRARY_DIRS
+            HDF5_${_lang}_LIBRARY_NAMES
+            HDF5_${_lang}_HL_LIBRARY_NAMES
           )
-          set(HDF5_${__lang}_LIBRARIES)
+          set(HDF5_${_lang}_LIBRARIES)
 
-          foreach(L IN LISTS HDF5_${__lang}_LIBRARY_NAMES)
+          foreach(_lib IN LISTS HDF5_${_lang}_LIBRARY_NAMES)
             set(_HDF5_SEARCH_NAMES_LOCAL)
-            if("x${L}" MATCHES "hdf5")
+            if("x${_lib}" MATCHES "hdf5")
               # hdf5 library
               set(_HDF5_SEARCH_OPTS_LOCAL ${_HDF5_SEARCH_OPTS})
               if(HDF5_USE_STATIC_LIBRARIES)
                 if(WIN32)
-                  set(_HDF5_SEARCH_NAMES_LOCAL lib${L})
+                  set(_HDF5_SEARCH_NAMES_LOCAL lib${_lib})
                 else()
-                  set(_HDF5_SEARCH_NAMES_LOCAL lib${L}.a)
+                  set(_HDF5_SEARCH_NAMES_LOCAL lib${_lib}.a)
                 endif()
               endif()
             else()
               # external library
               set(_HDF5_SEARCH_OPTS_LOCAL)
             endif()
-            find_library(HDF5_${__lang}_LIBRARY_${L}
-              NAMES ${_HDF5_SEARCH_NAMES_LOCAL} ${L} NAMES_PER_DIR
-              HINTS ${HDF5_${__lang}_LIBRARY_DIRS}
+            find_library(HDF5_${_lang}_LIBRARY_${_lib}
+              NAMES ${_HDF5_SEARCH_NAMES_LOCAL} ${_lib} NAMES_PER_DIR
+              HINTS ${HDF5_${_lang}_LIBRARY_DIRS}
                     ${HDF5_ROOT}
               ${_HDF5_SEARCH_OPTS_LOCAL}
               )
             unset(_HDF5_SEARCH_OPTS_LOCAL)
             unset(_HDF5_SEARCH_NAMES_LOCAL)
-            if(HDF5_${__lang}_LIBRARY_${L})
-              list(APPEND HDF5_${__lang}_LIBRARIES ${HDF5_${__lang}_LIBRARY_${L}})
+            if(HDF5_${_lang}_LIBRARY_${_lib})
+              list(APPEND HDF5_${_lang}_LIBRARIES ${HDF5_${_lang}_LIBRARY_${_lib}})
             else()
-              list(APPEND HDF5_${__lang}_LIBRARIES ${L})
+              list(APPEND HDF5_${_lang}_LIBRARIES ${_lib})
             endif()
           endforeach()
-          if(FIND_HL)
-            set(HDF5_${__lang}_HL_LIBRARIES)
-            foreach(L IN LISTS HDF5_${__lang}_HL_LIBRARY_NAMES)
+          if(HDF5_FIND_HL)
+            set(HDF5_${_lang}_HL_LIBRARIES)
+            foreach(_lib IN LISTS HDF5_${_lang}_HL_LIBRARY_NAMES)
               set(_HDF5_SEARCH_NAMES_LOCAL)
-              if("x${L}" MATCHES "hdf5")
+              if("x${_lib}" MATCHES "hdf5")
                 # hdf5 library
                 set(_HDF5_SEARCH_OPTS_LOCAL ${_HDF5_SEARCH_OPTS})
                 if(HDF5_USE_STATIC_LIBRARIES)
                   if(WIN32)
-                    set(_HDF5_SEARCH_NAMES_LOCAL lib${L})
+                    set(_HDF5_SEARCH_NAMES_LOCAL lib${_lib})
                   else()
-                    set(_HDF5_SEARCH_NAMES_LOCAL lib${L}.a)
+                    set(_HDF5_SEARCH_NAMES_LOCAL lib${_lib}.a)
                   endif()
                 endif()
               else()
                 # external library
                 set(_HDF5_SEARCH_OPTS_LOCAL)
               endif()
-              find_library(HDF5_${__lang}_LIBRARY_${L}
-                NAMES ${_HDF5_SEARCH_NAMES_LOCAL} ${L} NAMES_PER_DIR
-                HINTS ${HDF5_${__lang}_LIBRARY_DIRS}
+              find_library(HDF5_${_lang}_LIBRARY_${_lib}
+                NAMES ${_HDF5_SEARCH_NAMES_LOCAL} ${_lib} NAMES_PER_DIR
+                HINTS ${HDF5_${_lang}_LIBRARY_DIRS}
                       ${HDF5_ROOT}
                 ${_HDF5_SEARCH_OPTS_LOCAL}
                 )
               unset(_HDF5_SEARCH_OPTS_LOCAL)
               unset(_HDF5_SEARCH_NAMES_LOCAL)
-              if(HDF5_${__lang}_LIBRARY_${L})
-                list(APPEND HDF5_${__lang}_HL_LIBRARIES ${HDF5_${__lang}_LIBRARY_${L}})
+              if(HDF5_${_lang}_LIBRARY_${_lib})
+                list(APPEND HDF5_${_lang}_HL_LIBRARIES ${HDF5_${_lang}_LIBRARY_${_lib}})
               else()
-                list(APPEND HDF5_${__lang}_HL_LIBRARIES ${L})
+                list(APPEND HDF5_${_lang}_HL_LIBRARIES ${_lib})
               endif()
             endforeach()
-            set(HDF5_HL_FOUND True)
+            set(HDF5_HL_FOUND TRUE)
           endif()
 
-          set(HDF5_${__lang}_FOUND True)
-          _HDF5_remove_duplicates_from_beginning(HDF5_${__lang}_DEFINITIONS)
-          _HDF5_remove_duplicates_from_beginning(HDF5_${__lang}_INCLUDE_DIRS)
-          _HDF5_remove_duplicates_from_beginning(HDF5_${__lang}_LIBRARIES)
-          _HDF5_remove_duplicates_from_beginning(HDF5_${__lang}_HL_LIBRARIES)
+          set(HDF5_${_lang}_FOUND TRUE)
+          _HDF5_remove_duplicates_from_beginning(HDF5_${_lang}_DEFINITIONS)
+          _HDF5_remove_duplicates_from_beginning(HDF5_${_lang}_INCLUDE_DIRS)
+          _HDF5_remove_duplicates_from_beginning(HDF5_${_lang}_LIBRARIES)
+          _HDF5_remove_duplicates_from_beginning(HDF5_${_lang}_HL_LIBRARIES)
         else()
-          set(_HDF5_NEED_TO_SEARCH True)
+          set(_HDF5_NEED_TO_SEARCH TRUE)
         endif()
       else()
-        set(_HDF5_NEED_TO_SEARCH True)
+        set(_HDF5_NEED_TO_SEARCH TRUE)
       endif()
     endif()
-    if(HDF5_${__lang}_VERSION)
+    if(HDF5_${_lang}_VERSION)
       if(NOT HDF5_VERSION)
-        set(HDF5_VERSION ${HDF5_${__lang}_VERSION})
-      elseif(NOT HDF5_VERSION VERSION_EQUAL HDF5_${__lang}_VERSION)
-        message(WARNING "HDF5 Version found for language ${__lang}, ${HDF5_${__lang}_VERSION} is different than previously found version ${HDF5_VERSION}")
+        set(HDF5_VERSION ${HDF5_${_lang}_VERSION})
+      elseif(NOT HDF5_VERSION VERSION_EQUAL HDF5_${_lang}_VERSION)
+        message(WARNING "HDF5 Version found for language ${_lang}, ${HDF5_${_lang}_VERSION} is different than previously found version ${HDF5_VERSION}")
       endif()
     endif()
-    if(DEFINED HDF5_${__lang}_IS_PARALLEL)
+    if(DEFINED HDF5_${_lang}_IS_PARALLEL)
       if(NOT DEFINED HDF5_IS_PARALLEL)
-        set(HDF5_IS_PARALLEL ${HDF5_${__lang}_IS_PARALLEL})
-      elseif(NOT HDF5_IS_PARALLEL AND HDF5_${__lang}_IS_PARALLEL)
-        message(WARNING "HDF5 found for language ${__lang} is parallel but previously found language is not parallel.")
-      elseif(HDF5_IS_PARALLEL AND NOT HDF5_${__lang}_IS_PARALLEL)
-        message(WARNING "HDF5 found for language ${__lang} is not parallel but previously found language is parallel.")
+        set(HDF5_IS_PARALLEL ${HDF5_${_lang}_IS_PARALLEL})
+      elseif(NOT HDF5_IS_PARALLEL AND HDF5_${_lang}_IS_PARALLEL)
+        message(WARNING "HDF5 found for language ${_lang} is parallel but previously found language is not parallel.")
+      elseif(HDF5_IS_PARALLEL AND NOT HDF5_${_lang}_IS_PARALLEL)
+        message(WARNING "HDF5 found for language ${_lang} is not parallel but previously found language is parallel.")
       endif()
     endif()
   endforeach()
+  unset(_lib)
 else()
-  set(_HDF5_NEED_TO_SEARCH True)
+  set(_HDF5_NEED_TO_SEARCH TRUE)
 endif()
 
 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_FOUND TRUE)
   set(HDF5_METHOD "Included by compiler wrappers")
   set(HDF5_REQUIRED_VARS HDF5_METHOD)
 elseif(NOT HDF5_FOUND AND NOT _HDF5_NEED_TO_SEARCH)
@@ -727,14 +744,14 @@
   set(HDF5_INCLUDE_DIRS)
   set(HDF5_LIBRARIES)
   set(HDF5_HL_LIBRARIES)
-  foreach(__lang IN LISTS HDF5_LANGUAGE_BINDINGS)
-    if(HDF5_${__lang}_FOUND)
-      if(NOT HDF5_${__lang}_COMPILER_NO_INTERROGATE)
-        list(APPEND HDF5_DEFINITIONS ${HDF5_${__lang}_DEFINITIONS})
-        list(APPEND HDF5_INCLUDE_DIRS ${HDF5_${__lang}_INCLUDE_DIRS})
-        list(APPEND HDF5_LIBRARIES ${HDF5_${__lang}_LIBRARIES})
-        if(FIND_HL)
-          list(APPEND HDF5_HL_LIBRARIES ${HDF5_${__lang}_HL_LIBRARIES})
+  foreach(_lang IN LISTS HDF5_LANGUAGE_BINDINGS)
+    if(HDF5_${_lang}_FOUND)
+      if(NOT HDF5_${_lang}_COMPILER_NO_INTERROGATE)
+        list(APPEND HDF5_DEFINITIONS ${HDF5_${_lang}_DEFINITIONS})
+        list(APPEND HDF5_INCLUDE_DIRS ${HDF5_${_lang}_INCLUDE_DIRS})
+        list(APPEND HDF5_LIBRARIES ${HDF5_${_lang}_LIBRARIES})
+        if(HDF5_FIND_HL)
+          list(APPEND HDF5_HL_LIBRARIES ${HDF5_${_lang}_HL_LIBRARIES})
         endif()
       endif()
     endif()
@@ -743,9 +760,9 @@
   _HDF5_remove_duplicates_from_beginning(HDF5_INCLUDE_DIRS)
   _HDF5_remove_duplicates_from_beginning(HDF5_LIBRARIES)
   _HDF5_remove_duplicates_from_beginning(HDF5_HL_LIBRARIES)
-  set(HDF5_FOUND True)
+  set(HDF5_FOUND TRUE)
   set(HDF5_REQUIRED_VARS HDF5_LIBRARIES)
-  if(FIND_HL)
+  if(HDF5_FIND_HL)
     list(APPEND HDF5_REQUIRED_VARS HDF5_HL_LIBRARIES)
   endif()
 endif()
@@ -769,33 +786,44 @@
     set(HDF5_Fortran_LIBRARY_NAMES    hdf5_fortran   ${HDF5_C_LIBRARY_NAMES})
     set(HDF5_Fortran_HL_LIBRARY_NAMES hdf5hl_fortran ${HDF5_C_HL_LIBRARY_NAMES} ${HDF5_Fortran_LIBRARY_NAMES})
 
-    foreach(__lang IN LISTS HDF5_LANGUAGE_BINDINGS)
+    # suffixes as seen on Linux, MSYS2, ...
+    set(_lib_suffixes hdf5)
+    if(NOT HDF5_PREFER_PARALLEL)
+      list(APPEND _lib_suffixes hdf5/serial)
+    endif()
+    if(HDF5_USE_STATIC_LIBRARIES)
+      set(_inc_suffixes include/static)
+    else()
+      set(_inc_suffixes include/shared)
+    endif()
+
+    foreach(_lang IN LISTS HDF5_LANGUAGE_BINDINGS)
         # find the HDF5 include directories
-        if("${__lang}" STREQUAL "Fortran")
+        if("${_lang}" STREQUAL "Fortran")
             set(HDF5_INCLUDE_FILENAME hdf5.mod HDF5.mod)
-        elseif("${__lang}" STREQUAL "CXX")
+        elseif("${_lang}" STREQUAL "CXX")
             set(HDF5_INCLUDE_FILENAME H5Cpp.h)
         else()
             set(HDF5_INCLUDE_FILENAME hdf5.h)
         endif()
 
-        find_path(HDF5_${__lang}_INCLUDE_DIR ${HDF5_INCLUDE_FILENAME}
+        find_path(HDF5_${_lang}_INCLUDE_DIR ${HDF5_INCLUDE_FILENAME}
             HINTS ${HDF5_ROOT}
             PATHS $ENV{HOME}/.local/include
-            PATH_SUFFIXES include Include
+            PATH_SUFFIXES include Include ${_inc_suffixes} ${_lib_suffixes}
             ${_HDF5_SEARCH_OPTS}
         )
-        mark_as_advanced(HDF5_${__lang}_INCLUDE_DIR)
+        mark_as_advanced(HDF5_${_lang}_INCLUDE_DIR)
         # set the _DIRS variable as this is what the user will normally use
-        set(HDF5_${__lang}_INCLUDE_DIRS ${HDF5_${__lang}_INCLUDE_DIR})
-        list(APPEND HDF5_INCLUDE_DIRS ${HDF5_${__lang}_INCLUDE_DIR})
+        set(HDF5_${_lang}_INCLUDE_DIRS ${HDF5_${_lang}_INCLUDE_DIR})
+        list(APPEND HDF5_INCLUDE_DIRS ${HDF5_${_lang}_INCLUDE_DIR})
 
         # find the HDF5 libraries
-        foreach(LIB IN LISTS HDF5_${__lang}_LIBRARY_NAMES)
+        foreach(LIB IN LISTS HDF5_${_lang}_LIBRARY_NAMES)
             if(HDF5_USE_STATIC_LIBRARIES)
                 # According to bug 1643 on the CMake bug tracker, this is the
                 # preferred method for searching for a static library.
-                # See https://gitlab.kitware.com/cmake/cmake/issues/1643.  We search
+                # See https://gitlab.kitware.com/cmake/cmake/-/issues/1643.  We search
                 # first for the full static library name, but fall back to a
                 # generic search on the name if the static search fails.
                 set( THIS_LIBRARY_SEARCH_DEBUG
@@ -811,31 +839,32 @@
             endif()
             find_library(HDF5_${LIB}_LIBRARY_DEBUG
                 NAMES ${THIS_LIBRARY_SEARCH_DEBUG}
-                HINTS ${HDF5_ROOT} PATH_SUFFIXES lib Lib
+                HINTS ${HDF5_ROOT} PATH_SUFFIXES lib Lib ${_lib_suffixes}
                 ${_HDF5_SEARCH_OPTS}
             )
-            find_library( HDF5_${LIB}_LIBRARY_RELEASE
+            find_library(HDF5_${LIB}_LIBRARY_RELEASE
                 NAMES ${THIS_LIBRARY_SEARCH_RELEASE}
-                HINTS ${HDF5_ROOT} PATH_SUFFIXES lib Lib
+                HINTS ${HDF5_ROOT} PATH_SUFFIXES lib Lib ${_lib_suffixes}
                 ${_HDF5_SEARCH_OPTS}
             )
+
             select_library_configurations( HDF5_${LIB} )
-            list(APPEND HDF5_${__lang}_LIBRARIES ${HDF5_${LIB}_LIBRARY})
+            list(APPEND HDF5_${_lang}_LIBRARIES ${HDF5_${LIB}_LIBRARY})
         endforeach()
-        if(HDF5_${__lang}_LIBRARIES)
-            set(HDF5_${__lang}_FOUND True)
+        if(HDF5_${_lang}_LIBRARIES)
+            set(HDF5_${_lang}_FOUND TRUE)
         endif()
 
         # Append the libraries for this language binding to the list of all
         # required libraries.
-        list(APPEND HDF5_LIBRARIES ${HDF5_${__lang}_LIBRARIES})
+        list(APPEND HDF5_LIBRARIES ${HDF5_${_lang}_LIBRARIES})
 
-        if(FIND_HL)
-            foreach(LIB IN LISTS HDF5_${__lang}_HL_LIBRARY_NAMES)
+        if(HDF5_FIND_HL)
+            foreach(LIB IN LISTS HDF5_${_lang}_HL_LIBRARY_NAMES)
                 if(HDF5_USE_STATIC_LIBRARIES)
                     # According to bug 1643 on the CMake bug tracker, this is the
                     # preferred method for searching for a static library.
-                    # See https://gitlab.kitware.com/cmake/cmake/issues/1643.  We search
+                    # See https://gitlab.kitware.com/cmake/cmake/-/issues/1643.  We search
                     # first for the full static library name, but fall back to a
                     # generic search on the name if the static search fails.
                     set( THIS_LIBRARY_SEARCH_DEBUG
@@ -848,25 +877,26 @@
                 endif()
                 find_library(HDF5_${LIB}_LIBRARY_DEBUG
                     NAMES ${THIS_LIBRARY_SEARCH_DEBUG}
-                    HINTS ${HDF5_ROOT} PATH_SUFFIXES lib Lib
+                    HINTS ${HDF5_ROOT} PATH_SUFFIXES lib Lib ${_lib_suffixes}
                     ${_HDF5_SEARCH_OPTS}
                 )
-                find_library( HDF5_${LIB}_LIBRARY_RELEASE
+                find_library(HDF5_${LIB}_LIBRARY_RELEASE
                     NAMES ${THIS_LIBRARY_SEARCH_RELEASE}
-                    HINTS ${HDF5_ROOT} PATH_SUFFIXES lib Lib
+                    HINTS ${HDF5_ROOT} PATH_SUFFIXES lib Lib ${_lib_suffixes}
                     ${_HDF5_SEARCH_OPTS}
                 )
+
                 select_library_configurations( HDF5_${LIB} )
-                list(APPEND HDF5_${__lang}_HL_LIBRARIES ${HDF5_${LIB}_LIBRARY})
+                list(APPEND HDF5_${_lang}_HL_LIBRARIES ${HDF5_${LIB}_LIBRARY})
             endforeach()
 
             # Append the libraries for this language binding to the list of all
             # required libraries.
-            list(APPEND HDF5_HL_LIBRARIES ${HDF5_${__lang}_HL_LIBRARIES})
+            list(APPEND HDF5_HL_LIBRARIES ${HDF5_${_lang}_HL_LIBRARIES})
         endif()
     endforeach()
-    if(FIND_HL AND HDF5_HL_LIBRARIES)
-        set(HDF5_HL_FOUND True)
+    if(HDF5_FIND_HL AND HDF5_HL_LIBRARIES)
+        set(HDF5_HL_FOUND TRUE)
     endif()
 
     _HDF5_remove_duplicates_from_beginning(HDF5_DEFINITIONS)
@@ -903,12 +933,14 @@
         endif()
       endforeach()
     endforeach()
+    unset(_hdr)
+    unset(_dir)
     set( HDF5_IS_PARALLEL ${HDF5_IS_PARALLEL} CACHE BOOL
         "HDF5 library compiled with parallel IO support" )
     mark_as_advanced( HDF5_IS_PARALLEL )
 
     set(HDF5_REQUIRED_VARS HDF5_LIBRARIES HDF5_INCLUDE_DIRS)
-    if(FIND_HL)
+    if(HDF5_FIND_HL)
         list(APPEND HDF5_REQUIRED_VARS HDF5_HL_LIBRARIES)
     endif()
 endif()
@@ -946,13 +978,15 @@
   message(STATUS "HDF5_INCLUDE_DIRS: ${HDF5_INCLUDE_DIRS}")
   message(STATUS "HDF5_LIBRARIES: ${HDF5_LIBRARIES}")
   message(STATUS "HDF5_HL_LIBRARIES: ${HDF5_HL_LIBRARIES}")
-  foreach(__lang IN LISTS HDF5_LANGUAGE_BINDINGS)
-    message(STATUS "HDF5_${__lang}_DEFINITIONS: ${HDF5_${__lang}_DEFINITIONS}")
-    message(STATUS "HDF5_${__lang}_INCLUDE_DIR: ${HDF5_${__lang}_INCLUDE_DIR}")
-    message(STATUS "HDF5_${__lang}_INCLUDE_DIRS: ${HDF5_${__lang}_INCLUDE_DIRS}")
-    message(STATUS "HDF5_${__lang}_LIBRARY: ${HDF5_${__lang}_LIBRARY}")
-    message(STATUS "HDF5_${__lang}_LIBRARIES: ${HDF5_${__lang}_LIBRARIES}")
-    message(STATUS "HDF5_${__lang}_HL_LIBRARY: ${HDF5_${__lang}_HL_LIBRARY}")
-    message(STATUS "HDF5_${__lang}_HL_LIBRARIES: ${HDF5_${__lang}_HL_LIBRARIES}")
+  foreach(_lang IN LISTS HDF5_LANGUAGE_BINDINGS)
+    message(STATUS "HDF5_${_lang}_DEFINITIONS: ${HDF5_${_lang}_DEFINITIONS}")
+    message(STATUS "HDF5_${_lang}_INCLUDE_DIR: ${HDF5_${_lang}_INCLUDE_DIR}")
+    message(STATUS "HDF5_${_lang}_INCLUDE_DIRS: ${HDF5_${_lang}_INCLUDE_DIRS}")
+    message(STATUS "HDF5_${_lang}_LIBRARY: ${HDF5_${_lang}_LIBRARY}")
+    message(STATUS "HDF5_${_lang}_LIBRARIES: ${HDF5_${_lang}_LIBRARIES}")
+    message(STATUS "HDF5_${_lang}_HL_LIBRARY: ${HDF5_${_lang}_HL_LIBRARY}")
+    message(STATUS "HDF5_${_lang}_HL_LIBRARIES: ${HDF5_${_lang}_HL_LIBRARIES}")
   endforeach()
 endif()
+unset(_lang)
+unset(_HDF5_NEED_TO_SEARCH)
diff --git a/Modules/FindICU.cmake b/Modules/FindICU.cmake
index 38081f5..c8b3e1f 100644
--- a/Modules/FindICU.cmake
+++ b/Modules/FindICU.cmake
@@ -5,6 +5,8 @@
 FindICU
 -------
 
+.. versionadded:: 3.7
+
 Find the International Components for Unicode (ICU) libraries and
 programs.
 
diff --git a/Modules/FindIce.cmake b/Modules/FindIce.cmake
index 5ce2b42..0f821e8 100644
--- a/Modules/FindIce.cmake
+++ b/Modules/FindIce.cmake
@@ -5,6 +5,8 @@
 FindIce
 -------
 
+.. versionadded:: 3.1
+
 Find the ZeroC Internet Communication Engine (ICE) programs,
 libraries and datafiles.
 
diff --git a/Modules/FindIconv.cmake b/Modules/FindIconv.cmake
index bf20f6f..41b7550 100644
--- a/Modules/FindIconv.cmake
+++ b/Modules/FindIconv.cmake
@@ -5,6 +5,8 @@
 FindIconv
 ---------
 
+.. versionadded:: 3.11
+
 This module finds the ``iconv()`` POSIX.1 functions on the system.
 These functions might be provided in the regular C library or externally
 in the form of an additional library.
@@ -110,6 +112,7 @@
 
 find_library(Iconv_LIBRARY
   NAMES ${Iconv_LIBRARY_NAMES}
+  NAMES_PER_DIR
   DOC "iconv library (potentially the C library)")
 
 mark_as_advanced(Iconv_INCLUDE_DIR)
diff --git a/Modules/FindIntl.cmake b/Modules/FindIntl.cmake
index 3818d45..1a09a60 100644
--- a/Modules/FindIntl.cmake
+++ b/Modules/FindIntl.cmake
@@ -5,6 +5,8 @@
 FindIntl
 --------
 
+.. versionadded:: 3.2
+
 Find the Gettext libintl headers and libraries.
 
 This module reports information about the Gettext libintl
@@ -40,7 +42,7 @@
 mark_as_advanced(Intl_INCLUDE_DIR)
 
 # Find all Intl libraries
-find_library(Intl_LIBRARY "intl"
+find_library(Intl_LIBRARY "intl" NAMES_PER_DIR
   DOC "libintl libraries (if not in the C library)")
 mark_as_advanced(Intl_LIBRARY)
 
diff --git a/Modules/FindJPEG.cmake b/Modules/FindJPEG.cmake
index 0bb6989..632fc9a 100644
--- a/Modules/FindJPEG.cmake
+++ b/Modules/FindJPEG.cmake
@@ -58,8 +58,8 @@
 endforeach()
 
 if(NOT JPEG_LIBRARY)
-  find_library(JPEG_LIBRARY_RELEASE NAMES ${jpeg_names})
-  find_library(JPEG_LIBRARY_DEBUG NAMES ${jpeg_names_debug})
+  find_library(JPEG_LIBRARY_RELEASE NAMES ${jpeg_names} NAMES_PER_DIR)
+  find_library(JPEG_LIBRARY_DEBUG NAMES ${jpeg_names_debug} NAMES_PER_DIR)
   include(${CMAKE_CURRENT_LIST_DIR}/SelectLibraryConfigurations.cmake)
   select_library_configurations(JPEG)
   mark_as_advanced(JPEG_LIBRARY_RELEASE JPEG_LIBRARY_DEBUG)
diff --git a/Modules/FindJava.cmake b/Modules/FindJava.cmake
index 945df3c..9db740b 100644
--- a/Modules/FindJava.cmake
+++ b/Modules/FindJava.cmake
@@ -160,9 +160,8 @@
       OUTPUT_STRIP_TRAILING_WHITESPACE
       ERROR_STRIP_TRAILING_WHITESPACE)
     if( res )
-      if(var MATCHES "No Java runtime present, requesting install")
-        set_property(CACHE Java_JAVA_EXECUTABLE
-          PROPERTY VALUE "Java_JAVA_EXECUTABLE-NOTFOUND")
+      if(var MATCHES "Unable to locate a Java Runtime to invoke|No Java runtime present, requesting install")
+        set(Java_JAVA_EXECUTABLE Java_JAVA_EXECUTABLE-NOTFOUND)
       elseif(${Java_FIND_REQUIRED})
         message( FATAL_ERROR "Error executing java -version" )
       else()
diff --git a/Modules/FindLAPACK.cmake b/Modules/FindLAPACK.cmake
index c962976..f996d4c 100644
--- a/Modules/FindLAPACK.cmake
+++ b/Modules/FindLAPACK.cmake
@@ -28,7 +28,7 @@
 
   * ``OpenBLAS``
   * ``FLAME``
-  * ``Intel10_32`` (intel mkl v10 32 bit)
+  * ``Intel10_32`` (intel mkl v10 32 bit, threaded code)
   * ``Intel10_64lp`` (intel mkl v10+ 64 bit, threaded code, lp64 model)
   * ``Intel10_64lp_seq`` (intel mkl v10+ 64 bit, sequential code, lp64 model)
   * ``Intel10_64ilp`` (intel mkl v10+ 64 bit, threaded code, ilp64 model)
@@ -38,11 +38,23 @@
   * ``ACML``
   * ``Apple``
   * ``NAS``
+  * ``Arm``
+  * ``Arm_mp``
+  * ``Arm_ilp64``
+  * ``Arm_ilp64_mp``
   * ``Generic``
 
 ``BLA_F95``
   if ``ON`` tries to find the BLAS95/LAPACK95 interfaces
 
+Imported targets
+^^^^^^^^^^^^^^^^
+
+This module defines the following :prop_tgt:`IMPORTED` target:
+
+``LAPACK::LAPACK``
+  The libraries to use for LAPACK, if found.
+
 Result Variables
 ^^^^^^^^^^^^^^^^
 
@@ -150,6 +162,7 @@
       if(_libraries_work)
         find_library(${_prefix}_${_library}_LIBRARY
           NAMES ${_library}
+          NAMES_PER_DIR
           PATHS ${_extaddlibdir}
           PATH_SUFFIXES ${_subdirs}
         )
@@ -267,7 +280,7 @@
           set(LAPACK_mkl_OS_NAME "lin")
         endif()
         if(DEFINED ENV{MKLROOT})
-          set(LAPACK_mkl_MKLROOT "$ENV{MKLROOT}")
+          file(TO_CMAKE_PATH "$ENV{MKLROOT}" LAPACK_mkl_MKLROOT)
           # If MKLROOT points to the subdirectory 'mkl', use the parent directory instead
           # so we can better detect other relevant libraries in 'compiler' or 'tbb':
           get_filename_component(LAPACK_mkl_MKLROOT_LAST_DIR "${LAPACK_mkl_MKLROOT}" NAME)
@@ -277,7 +290,9 @@
         endif()
         set(LAPACK_mkl_LIB_PATH_SUFFIXES
             "compiler/lib" "compiler/lib/${LAPACK_mkl_ARCH_NAME}_${LAPACK_mkl_OS_NAME}"
+            "compiler/lib/${LAPACK_mkl_ARCH_NAME}"
             "mkl/lib" "mkl/lib/${LAPACK_mkl_ARCH_NAME}_${LAPACK_mkl_OS_NAME}"
+            "mkl/lib/${LAPACK_mkl_ARCH_NAME}"
             "lib/${LAPACK_mkl_ARCH_NAME}_${LAPACK_mkl_OS_NAME}")
 
         # First try empty lapack libs
@@ -359,6 +374,36 @@
     endif()
   endif()
 
+  # ArmPL? (https://developer.arm.com/tools-and-software/server-and-hpc/compile/arm-compiler-for-linux/arm-performance-libraries)
+  if(BLA_VENDOR MATCHES "Arm" OR BLA_VENDOR STREQUAL "All")
+
+    # Check for 64bit Integer support
+    if(BLA_VENDOR MATCHES "_ilp64")
+      set(LAPACK_armpl_LIB "armpl_ilp64")
+    else()
+      set(LAPACK_armpl_LIB "armpl_lp64")
+    endif()
+
+    # Check for OpenMP support, VIA BLA_VENDOR of Arm_mp or Arm_ipl64_mp
+    if(BLA_VENDOR MATCHES "_mp")
+     set(LAPACK_armpl_LIB "${LAPACK_armpl_LIB}_mp")
+    endif()
+
+    if(NOT LAPACK_LIBRARIES)
+      check_lapack_libraries(
+        LAPACK_LIBRARIES
+        LAPACK
+        cheev
+        ""
+        "${LAPACK_armpl_LIB}"
+        ""
+        ""
+        ""
+        "${BLAS_LIBRARIES}"
+      )
+    endif()
+  endif()
+
   # FLAME's blis library? (https://github.com/flame/blis)
   if(BLA_VENDOR STREQUAL "FLAME" OR BLA_VENDOR STREQUAL "All")
     if(NOT LAPACK_LIBRARIES)
@@ -492,5 +537,22 @@
   set(LAPACK_LIBRARIES "")
 endif()
 
+if(NOT TARGET LAPACK::LAPACK)
+  add_library(LAPACK::LAPACK INTERFACE IMPORTED)
+  set(_lapack_libs "${LAPACK_LIBRARIES}")
+  if(_lapack_libs AND TARGET BLAS::BLAS)
+    # remove the ${BLAS_LIBRARIES} from the interface and replace it
+    # with the BLAS::BLAS target
+    list(REMOVE_ITEM _lapack_libs "${BLAS_LIBRARIES}")
+  endif()
+
+  if(_lapack_libs)
+    set_target_properties(LAPACK::LAPACK PROPERTIES
+      INTERFACE_LINK_LIBRARIES "${_lapack_libs}"
+    )
+  endif()
+  unset(_lapack_libs)
+endif()
+
 cmake_pop_check_state()
 set(CMAKE_FIND_LIBRARY_SUFFIXES ${_lapack_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES})
diff --git a/Modules/FindLTTngUST.cmake b/Modules/FindLTTngUST.cmake
index 9cd17eb..f478e4d 100644
--- a/Modules/FindLTTngUST.cmake
+++ b/Modules/FindLTTngUST.cmake
@@ -5,6 +5,8 @@
 FindLTTngUST
 ------------
 
+.. versionadded:: 3.6
+
 Find
 `Linux Trace Toolkit Next Generation (LTTng-UST) <http://lttng.org/>`__ library.
 
diff --git a/Modules/FindLibLZMA.cmake b/Modules/FindLibLZMA.cmake
index 200d6bf..4a79a10 100644
--- a/Modules/FindLibLZMA.cmake
+++ b/Modules/FindLibLZMA.cmake
@@ -43,8 +43,8 @@
 
 find_path(LIBLZMA_INCLUDE_DIR lzma.h )
 if(NOT LIBLZMA_LIBRARY)
-  find_library(LIBLZMA_LIBRARY_RELEASE NAMES lzma liblzma PATH_SUFFIXES lib)
-  find_library(LIBLZMA_LIBRARY_DEBUG NAMES lzmad liblzmad PATH_SUFFIXES lib)
+  find_library(LIBLZMA_LIBRARY_RELEASE NAMES lzma liblzma NAMES_PER_DIR PATH_SUFFIXES lib)
+  find_library(LIBLZMA_LIBRARY_DEBUG NAMES lzmad liblzmad NAMES_PER_DIR PATH_SUFFIXES lib)
   include(${CMAKE_CURRENT_LIST_DIR}/SelectLibraryConfigurations.cmake)
   select_library_configurations(LIBLZMA)
 else()
diff --git a/Modules/FindLibXslt.cmake b/Modules/FindLibXslt.cmake
index 01a9d8b..fc7adeb 100644
--- a/Modules/FindLibXslt.cmake
+++ b/Modules/FindLibXslt.cmake
@@ -8,9 +8,22 @@
 Find the XSL Transformations, Extensible Stylesheet Language
 Transformations (XSLT) library (LibXslt)
 
-Once done this will define
+IMPORTED Targets
+^^^^^^^^^^^^^^^^
 
-::
+The following :prop_tgt:`IMPORTED` targets may be defined:
+
+``LibXslt::LibXslt``
+  If the libxslt library has been found
+``LibXslt::LibExslt``
+  If the libexslt library has been found
+``LibXslt::xsltproc``
+  If the xsltproc command-line executable has been found
+
+Result variables
+^^^^^^^^^^^^^^^^
+
+This module will set the following variables in your project:
 
   LIBXSLT_FOUND - system has LibXslt
   LIBXSLT_INCLUDE_DIR - the LibXslt include directory
@@ -21,6 +34,8 @@
 Additionally, the following two variables are set (but not required
 for using xslt):
 
+``LIBXSLT_EXSLT_INCLUDE_DIR``
+  The include directory for exslt.
 ``LIBXSLT_EXSLT_LIBRARIES``
   Link to these if you need to link against the exslt library.
 ``LIBXSLT_XSLTPROC_EXECUTABLE``
@@ -39,16 +54,36 @@
    ${PC_LIBXSLT_INCLUDE_DIRS}
   )
 
-find_library(LIBXSLT_LIBRARIES NAMES xslt libxslt
+# CMake 3.17 and below used 'LIBXSLT_LIBRARIES' as the name of
+# the cache entry storing the find_library result.  Use the
+# value if it was set by the project or user.
+if(DEFINED LIBXSLT_LIBRARIES AND NOT DEFINED LIBXSLT_LIBRARY)
+  set(LIBXSLT_LIBRARY ${LIBXSLT_LIBRARIES})
+endif()
+
+find_library(LIBXSLT_LIBRARY NAMES xslt libxslt
     HINTS
    ${PC_LIBXSLT_LIBDIR}
    ${PC_LIBXSLT_LIBRARY_DIRS}
   )
 
+set(LIBXSLT_LIBRARIES ${LIBXSLT_LIBRARY})
+
+PKG_CHECK_MODULES(PC_LIBXSLT_EXSLT QUIET libexslt)
+set(LIBXSLT_EXSLT_DEFINITIONS ${PC_LIBXSLT_EXSLT_CFLAGS_OTHER})
+
+find_path(LIBXSLT_EXSLT_INCLUDE_DIR NAMES libexslt/exslt.h
+  HINTS
+  ${PC_LIBXSLT_EXSLT_INCLUDEDIR}
+  ${PC_LIBXSLT_EXSLT_INCLUDE_DIRS}
+)
+
 find_library(LIBXSLT_EXSLT_LIBRARY NAMES exslt libexslt
     HINTS
     ${PC_LIBXSLT_LIBDIR}
     ${PC_LIBXSLT_LIBRARY_DIRS}
+    ${PC_LIBXSLT_EXSLT_LIBDIR}
+    ${PC_LIBXSLT_EXSLT_LIBRARY_DIRS}
   )
 
 set(LIBXSLT_EXSLT_LIBRARIES ${LIBXSLT_EXSLT_LIBRARY} )
@@ -75,3 +110,22 @@
                  LIBXSLT_LIBRARIES
                  LIBXSLT_EXSLT_LIBRARY
                  LIBXSLT_XSLTPROC_EXECUTABLE)
+
+if(LIBXSLT_FOUND AND NOT TARGET LibXslt::LibXslt)
+  add_library(LibXslt::LibXslt UNKNOWN IMPORTED)
+  set_target_properties(LibXslt::LibXslt PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${LIBXSLT_INCLUDE_DIR}")
+  set_target_properties(LibXslt::LibXslt PROPERTIES INTERFACE_COMPILE_OPTIONS "${LIBXSLT_DEFINITIONS}")
+  set_property(TARGET LibXslt::LibXslt APPEND PROPERTY IMPORTED_LOCATION "${LIBXSLT_LIBRARY}")
+endif()
+
+if(LIBXSLT_FOUND AND NOT TARGET LibXslt::LibExslt)
+  add_library(LibXslt::LibExslt UNKNOWN IMPORTED)
+  set_target_properties(LibXslt::LibExslt PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${LIBXSLT_EXSLT_INCLUDE_DIR}")
+  set_target_properties(LibXslt::LibExslt PROPERTIES INTERFACE_COMPILE_OPTIONS "${LIBXSLT_EXSLT_DEFINITIONS}")
+  set_property(TARGET LibXslt::LibExslt APPEND PROPERTY IMPORTED_LOCATION "${LIBXSLT_EXSLT_LIBRARY}")
+endif()
+
+if(LIBXSLT_XSLTPROC_EXECUTABLE AND NOT TARGET LibXslt::xsltproc)
+  add_executable(LibXslt::xsltproc IMPORTED)
+  set_target_properties(LibXslt::xsltproc PROPERTIES IMPORTED_LOCATION "${LIBXSLT_XSLTPROC_EXECUTABLE}")
+endif()
diff --git a/Modules/FindLibinput.cmake b/Modules/FindLibinput.cmake
index c1fe455..88d5b2f 100644
--- a/Modules/FindLibinput.cmake
+++ b/Modules/FindLibinput.cmake
@@ -5,6 +5,8 @@
 FindLibinput
 ------------
 
+.. versionadded:: 3.14
+
 Find libinput headers and library.
 
 Imported Targets
diff --git a/Modules/FindLua.cmake b/Modules/FindLua.cmake
index 0b0c970..c4361b7 100644
--- a/Modules/FindLua.cmake
+++ b/Modules/FindLua.cmake
@@ -48,7 +48,7 @@
 
 # this is a function only to have all the variables inside go away automatically
 function(_lua_get_versions)
-    set(LUA_VERSIONS5 5.3 5.2 5.1 5.0)
+    set(LUA_VERSIONS5 5.4 5.3 5.2 5.1 5.0)
 
     if (Lua_FIND_VERSION_EXACT)
         if (Lua_FIND_VERSION_COUNT GREATER 1)
diff --git a/Modules/FindMPI.cmake b/Modules/FindMPI.cmake
index cdbb927..b2526c1 100644
--- a/Modules/FindMPI.cmake
+++ b/Modules/FindMPI.cmake
@@ -760,7 +760,7 @@
   # Save the explicitly given link directories
   set(MPI_LINK_DIRECTORIES_LEFTOVER "${MPI_LINK_DIRECTORIES_WORK}")
 
-  # An MPI compiler wrapper could have its MPI libraries in the implictly
+  # An MPI compiler wrapper could have its MPI libraries in the implicitly
   # linked directories of the compiler itself.
   if(DEFINED CMAKE_${LANG}_IMPLICIT_LINK_DIRECTORIES)
     list(APPEND MPI_LINK_DIRECTORIES_WORK "${CMAKE_${LANG}_IMPLICIT_LINK_DIRECTORIES}")
@@ -867,11 +867,11 @@
       # We first attempt to locate the msmpi.lib. Should be find it, we'll assume that the MPI present is indeed
       # Microsoft MPI.
       if("${CMAKE_SIZEOF_VOID_P}" EQUAL 8)
-        set(MPI_MSMPI_LIB_PATH "$ENV{MSMPI_LIB64}")
-        set(MPI_MSMPI_INC_PATH_EXTRA "$ENV{MSMPI_INC}/x64")
+        file(TO_CMAKE_PATH "$ENV{MSMPI_LIB64}" MPI_MSMPI_LIB_PATH)
+        file(TO_CMAKE_PATH "$ENV{MSMPI_INC}/x64" MPI_MSMPI_INC_PATH_EXTRA)
       else()
-        set(MPI_MSMPI_LIB_PATH "$ENV{MSMPI_LIB32}")
-        set(MPI_MSMPI_INC_PATH_EXTRA "$ENV{MSMPI_INC}/x86")
+        file(TO_CMAKE_PATH "$ENV{MSMPI_LIB32}" MPI_MSMPI_LIB_PATH)
+        file(TO_CMAKE_PATH "$ENV{MSMPI_INC}/x86" MPI_MSMPI_INC_PATH_EXTRA)
       endif()
 
       find_library(MPI_msmpi_LIBRARY
@@ -1153,8 +1153,10 @@
     add_library(MPI::MPI_${LANG} INTERFACE IMPORTED)
   endif()
 
-  # When this is consumed for compiling CUDA, use '-Xcompiler' to wrap '-pthread'.
-  string(REPLACE "-pthread" "$<$<COMPILE_LANGUAGE:CUDA>:SHELL:-Xcompiler >-pthread"
+  # When this is consumed for compiling CUDA, use '-Xcompiler' to wrap '-pthread' and '-fexceptions'.
+  string(REPLACE "-pthread" "$<$<COMPILE_LANG_AND_ID:CUDA,NVIDIA>:SHELL:-Xcompiler >-pthread"
+    _MPI_${LANG}_COMPILE_OPTIONS "${MPI_${LANG}_COMPILE_OPTIONS}")
+  string(REPLACE "-fexceptions" "$<$<COMPILE_LANG_AND_ID:CUDA,NVIDIA>:SHELL:-Xcompiler >-fexceptions"
     _MPI_${LANG}_COMPILE_OPTIONS "${MPI_${LANG}_COMPILE_OPTIONS}")
   set_property(TARGET MPI::MPI_${LANG} PROPERTY INTERFACE_COMPILE_OPTIONS "${_MPI_${LANG}_COMPILE_OPTIONS}")
   unset(_MPI_${LANG}_COMPILE_OPTIONS)
@@ -1162,6 +1164,8 @@
   set_property(TARGET MPI::MPI_${LANG} PROPERTY INTERFACE_COMPILE_DEFINITIONS "${MPI_${LANG}_COMPILE_DEFINITIONS}")
 
   if(MPI_${LANG}_LINK_FLAGS)
+    string(REPLACE "-pthread" "$<$<LINK_LANG_AND_ID:CUDA,NVIDIA>:-Xlinker >-pthread"
+      _MPI_${LANG}_LINK_FLAGS "${MPI_${LANG}_LINK_FLAGS}")
     set_property(TARGET MPI::MPI_${LANG} PROPERTY INTERFACE_LINK_OPTIONS "SHELL:${MPI_${LANG}_LINK_FLAGS}")
   endif()
   # If the compiler links MPI implicitly, no libraries will be found as they're contained within
diff --git a/Modules/FindMatlab.cmake b/Modules/FindMatlab.cmake
index e42c206..05ec3ae 100644
--- a/Modules/FindMatlab.cmake
+++ b/Modules/FindMatlab.cmake
@@ -992,7 +992,10 @@
     endif()
   endif()
 
-  if(NOT Matlab_VERSION_STRING VERSION_LESS "9.4") # For 9.4 (R2018a) and newer, add API macro
+  # For 9.4 (R2018a) and newer, add API macro.
+  # Add it for unknown versions too, just in case.
+  if(NOT Matlab_VERSION_STRING VERSION_LESS "9.4"
+      OR Matlab_VERSION_STRING STREQUAL "unknown")
     if(${${prefix}_R2018a})
       set(MEX_API_MACRO "MATLAB_DEFAULT_RELEASE=R2018a")
     else()
diff --git a/Modules/FindODBC.cmake b/Modules/FindODBC.cmake
index 3f710db..884653c 100644
--- a/Modules/FindODBC.cmake
+++ b/Modules/FindODBC.cmake
@@ -5,6 +5,8 @@
 FindODBC
 --------
 
+.. versionadded:: 3.12
+
 Find an Open Database Connectivity (ODBC) include directory and library.
 
 On Windows, when building with Visual Studio, this module assumes the ODBC
diff --git a/Modules/FindOpenACC.cmake b/Modules/FindOpenACC.cmake
index 398dcf5..ed52e35 100644
--- a/Modules/FindOpenACC.cmake
+++ b/Modules/FindOpenACC.cmake
@@ -5,6 +5,8 @@
 FindOpenACC
 -----------
 
+.. versionadded:: 3.10
+
 Detect OpenACC support by the compiler.
 
 This module can be used to detect OpenACC support in a compiler.
diff --git a/Modules/FindOpenAL.cmake b/Modules/FindOpenAL.cmake
index 27dcaf5..b5b92c5 100644
--- a/Modules/FindOpenAL.cmake
+++ b/Modules/FindOpenAL.cmake
@@ -5,27 +5,45 @@
 FindOpenAL
 ----------
 
-
 Finds Open Audio Library (OpenAL).
-This module defines ``OPENAL_LIBRARY OPENAL_FOUND``, if
-false, do not try to link to OpenAL ``OPENAL_INCLUDE_DIR``, where to find
-the headers.
 
-``$OPENALDIR`` is an environment variable that would correspond to the
-``./configure --prefix=$OPENALDIR`` used in building OpenAL.
+Projects using this module should use ``#include "al.h"`` to include the OpenAL
+header file, **not** ``#include <AL/al.h>``.  The reason for this is that the
+latter is not entirely portable.  Windows/Creative Labs does not by default put
+their headers in ``AL/`` and macOS uses the convention ``<OpenAL/al.h>``.
 
-Created by Eric Wing.  This was influenced by the ``FindSDL.cmake``
-module.
+Hints
+^^^^^
+
+Environment variable ``$OPENALDIR`` can be used to set the prefix of OpenAL
+installation to be found.
+
+By default on macOS, system framework is search first.  In other words,
+OpenAL is searched in the following order:
+
+1. System framework: ``/System/Library/Frameworks``, whose priority can be
+   changed via setting the :variable:`CMAKE_FIND_FRAMEWORK` variable.
+2. Environment variable ``$OPENALDIR``.
+3. System paths.
+4. User-compiled framework: ``~/Library/Frameworks``.
+5. Manually compiled framework: ``/Library/Frameworks``.
+6. Add-on package: ``/opt``.
+
+Result Variables
+^^^^^^^^^^^^^^^^
+
+This module defines the following variables:
+
+``OPENAL_FOUND``
+  If false, do not try to link to OpenAL
+``OPENAL_INCLUDE_DIR``
+  OpenAL include directory
+``OPENAL_LIBRARY``
+  Path to the OpenAL library
+``OPENAL_VERSION_STRING``
+  Human-readable string containing the version of OpenAL
 #]=======================================================================]
 
-# This makes the presumption that you are include al.h like
-# #include "al.h"
-# and not
-# #include <AL/al.h>
-# The reason for this is that the latter is not entirely portable.
-# Windows/Creative Labs does not by default put their headers in AL/ and
-# OS X uses the convention <OpenAL/al.h>.
-#
 # For Windows, Creative Labs seems to have added a registry key for their
 # OpenAL 1.1 installer. I have added that key to the list of search paths,
 # however, the key looks like it could be a little fragile depending on
@@ -36,36 +54,17 @@
 # platforms are introduced.
 # The OpenAL 1.0 installer doesn't seem to have a useful key I can use.
 # I do not know if the Nvidia OpenAL SDK has a registry key.
-#
-# For OS X, remember that OpenAL was added by Apple in 10.4 (Tiger).
-# To support the framework, I originally wrote special framework detection
-# code in this module which I have now removed with CMake's introduction
-# of native support for frameworks.
-# In addition, OpenAL is open source, and it is possible to compile on Panther.
-# Furthermore, due to bugs in the initial OpenAL release, and the
-# transition to OpenAL 1.1, it is common to need to override the built-in
-# framework.
-# Per my request, CMake should search for frameworks first in
-# the following order:
-# ~/Library/Frameworks/OpenAL.framework/Headers
-# /Library/Frameworks/OpenAL.framework/Headers
-# /System/Library/Frameworks/OpenAL.framework/Headers
-#
-# On OS X, this will prefer the Framework version (if found) over others.
-# People will have to manually change the cache values of
-# OPENAL_LIBRARY to override this selection or set the CMake environment
-# CMAKE_INCLUDE_PATH to modify the search paths.
 
 find_path(OPENAL_INCLUDE_DIR al.h
   HINTS
     ENV OPENALDIR
-  PATH_SUFFIXES include/AL include/OpenAL include AL OpenAL
   PATHS
-  ~/Library/Frameworks
-  /Library/Frameworks
-  /opt
-  [HKEY_LOCAL_MACHINE\\SOFTWARE\\Creative\ Labs\\OpenAL\ 1.1\ Software\ Development\ Kit\\1.00.0000;InstallDir]
-)
+    ~/Library/Frameworks
+    /Library/Frameworks
+    /opt
+    [HKEY_LOCAL_MACHINE\\SOFTWARE\\Creative\ Labs\\OpenAL\ 1.1\ Software\ Development\ Kit\\1.00.0000;InstallDir]
+  PATH_SUFFIXES include/AL include/OpenAL include AL OpenAL
+  )
 
 if(CMAKE_SIZEOF_VOID_P EQUAL 8)
   set(_OpenAL_ARCH_DIR libs/Win64)
@@ -77,17 +76,21 @@
   NAMES OpenAL al openal OpenAL32
   HINTS
     ENV OPENALDIR
-  PATH_SUFFIXES libx32 lib64 lib libs64 libs ${_OpenAL_ARCH_DIR}
   PATHS
-  ~/Library/Frameworks
-  /Library/Frameworks
-  /opt
-  [HKEY_LOCAL_MACHINE\\SOFTWARE\\Creative\ Labs\\OpenAL\ 1.1\ Software\ Development\ Kit\\1.00.0000;InstallDir]
-)
+    ~/Library/Frameworks
+    /Library/Frameworks
+    /opt
+    [HKEY_LOCAL_MACHINE\\SOFTWARE\\Creative\ Labs\\OpenAL\ 1.1\ Software\ Development\ Kit\\1.00.0000;InstallDir]
+  PATH_SUFFIXES libx32 lib64 lib libs64 libs ${_OpenAL_ARCH_DIR}
+  )
 
 unset(_OpenAL_ARCH_DIR)
 
 include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
-FIND_PACKAGE_HANDLE_STANDARD_ARGS(OpenAL  DEFAULT_MSG  OPENAL_LIBRARY OPENAL_INCLUDE_DIR)
+find_package_handle_standard_args(
+  OpenAL
+  REQUIRED_VARS OPENAL_LIBRARY OPENAL_INCLUDE_DIR
+  VERSION_VAR OPENAL_VERSION_STRING
+  )
 
 mark_as_advanced(OPENAL_LIBRARY OPENAL_INCLUDE_DIR)
diff --git a/Modules/FindOpenCL.cmake b/Modules/FindOpenCL.cmake
index 9891724..b3e5a9f 100644
--- a/Modules/FindOpenCL.cmake
+++ b/Modules/FindOpenCL.cmake
@@ -5,6 +5,8 @@
 FindOpenCL
 ----------
 
+.. versionadded:: 3.1
+
 Finds Open Computing Language (OpenCL)
 
 IMPORTED Targets
@@ -78,6 +80,8 @@
     ENV CUDA_PATH
     ENV ATISTREAMSDKROOT
     ENV OCL_ROOT
+    /usr/local/cuda
+    /opt/cuda
   PATH_SUFFIXES
     include
     OpenCL/common/inc
@@ -126,6 +130,8 @@
       PATHS
         ENV AMDAPPSDKROOT
         ENV CUDA_PATH
+        /usr/local/cuda
+        /opt/cuda
       PATH_SUFFIXES
         lib/x86
         lib)
@@ -135,6 +141,8 @@
       PATHS
         ENV AMDAPPSDKROOT
         ENV CUDA_PATH
+        /usr/local/cuda
+        /opt/cuda
       PATH_SUFFIXES
         lib/x86_64
         lib/x64
diff --git a/Modules/FindOpenGL.cmake b/Modules/FindOpenGL.cmake
index 74392da..110e7f9 100644
--- a/Modules/FindOpenGL.cmake
+++ b/Modules/FindOpenGL.cmake
@@ -132,19 +132,7 @@
 
 set(_OpenGL_CACHE_VARS)
 
-if (CYGWIN)
-  find_path(OPENGL_INCLUDE_DIR GL/gl.h )
-  list(APPEND _OpenGL_REQUIRED_VARS OPENGL_INCLUDE_DIR)
-
-  find_library(OPENGL_gl_LIBRARY opengl32 )
-  find_library(OPENGL_glu_LIBRARY glu32 )
-
-  list(APPEND _OpenGL_CACHE_VARS
-    OPENGL_INCLUDE_DIR
-    OPENGL_gl_LIBRARY
-    OPENGL_glu_LIBRARY
-    )
-elseif (WIN32)
+if (WIN32)
 
   if(BORLAND)
     set (OPENGL_gl_LIBRARY import32 CACHE STRING "OpenGL library for win32")
@@ -424,8 +412,15 @@
 endif()
 
 include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
+if (CMAKE_FIND_PACKAGE_NAME STREQUAL "GLU")
+  # FindGLU include()'s this module. It's an old pattern, but rather than
+  # trying to suppress this from outside the module (which is then sensitive to
+  # the contents, detect the case in this module and suppress it explicitly.
+  set(FPHSA_NAME_MISMATCHED 1)
+endif ()
 FIND_PACKAGE_HANDLE_STANDARD_ARGS(OpenGL REQUIRED_VARS ${_OpenGL_REQUIRED_VARS}
                                   HANDLE_COMPONENTS)
+unset(FPHSA_NAME_MISMATCHED)
 unset(_OpenGL_REQUIRED_VARS)
 
 # OpenGL:: targets
diff --git a/Modules/FindOpenMP.cmake b/Modules/FindOpenMP.cmake
index a4b1e1e..bb38e28 100644
--- a/Modules/FindOpenMP.cmake
+++ b/Modules/FindOpenMP.cmake
@@ -509,8 +509,8 @@
       _OPENMP_GET_SPEC_DATE("${LANG}" OpenMP_${LANG}_SPEC_DATE_INTERNAL)
       set(OpenMP_${LANG}_SPEC_DATE "${OpenMP_${LANG}_SPEC_DATE_INTERNAL}" CACHE
         INTERNAL "${LANG} compiler's OpenMP specification date")
-      _OPENMP_SET_VERSION_BY_SPEC_DATE("${LANG}")
     endif()
+    _OPENMP_SET_VERSION_BY_SPEC_DATE("${LANG}")
 
     set(OpenMP_${LANG}_FIND_QUIETLY ${OpenMP_FIND_QUIETLY})
     set(OpenMP_${LANG}_FIND_REQUIRED ${OpenMP_FIND_REQUIRED})
diff --git a/Modules/FindOpenSSL.cmake b/Modules/FindOpenSSL.cmake
index ad1018f..9196851 100644
--- a/Modules/FindOpenSSL.cmake
+++ b/Modules/FindOpenSSL.cmake
@@ -22,6 +22,27 @@
   The OpenSSL ``ssl`` library, if found.
 ``OpenSSL::Crypto``
   The OpenSSL ``crypto`` library, if found.
+``OpenSSL::applink``
+  The OpenSSL ``applink`` components that might be need to be compiled into
+  projects under MSVC. This target is available only if found OpenSSL version
+  is not less than 0.9.8. By linking this target the above OpenSSL targets can
+  be linked even if the project has different MSVC runtime configurations with
+  the above OpenSSL targets. This target has no effect on platforms other than
+  MSVC.
+
+NOTE: Due to how ``INTERFACE_SOURCES`` are consumed by the consuming target,
+unless you certainly know what you are doing, it is always preferred to link
+``OpenSSL::applink`` target as ``PRIVATE`` and to make sure that this target is
+linked at most once for the whole dependency graph of any library or
+executable:
+
+.. code-block:: cmake
+
+   target_link_libraries(myTarget PRIVATE OpenSSL::applink)
+
+Otherwise you would probably encounter unexpected random problems when building
+and linking, as both the ISO C and the ISO C++ standard claims almost nothing
+about what a link process should be.
 
 Result Variables
 ^^^^^^^^^^^^^^^^
@@ -45,6 +66,10 @@
   All OpenSSL libraries and their dependencies.
 ``OPENSSL_VERSION``
   This is set to ``$major.$minor.$revision$patch`` (e.g. ``0.9.8s``).
+``OPENSSL_APPLINK_SOURCE``
+  The sources in the target ``OpenSSL::applink`` that is mentioned above. This
+  variable shall always be undefined if found openssl version is less than
+  0.9.8 or if platform is not MSVC.
 
 Hints
 ^^^^^
@@ -535,6 +560,28 @@
     endif()
     _OpenSSL_target_add_dependencies(OpenSSL::SSL)
   endif()
+
+  if("${OPENSSL_VERSION_MAJOR}.${OPENSSL_VERSION_MAJOR}.${OPENSSL_VERSION_FIX}" VERSION_GREATER_EQUAL "0.9.8")
+    if(MSVC)
+      if(EXISTS "${OPENSSL_INCLUDE_DIR}")
+        set(_OPENSSL_applink_paths PATHS ${OPENSSL_INCLUDE_DIR})
+      endif()
+      find_file(OPENSSL_APPLINK_SOURCE
+        NAMES
+          openssl/applink.c
+        ${_OPENSSL_applink_paths}
+        NO_DEFAULT_PATH)
+      if(OPENSSL_APPLINK_SOURCE)
+        set(_OPENSSL_applink_interface_srcs ${OPENSSL_APPLINK_SOURCE})
+      endif()
+    endif()
+    if(NOT TARGET OpenSSL::applink)
+      add_library(OpenSSL::applink INTERFACE IMPORTED)
+      set_property(TARGET OpenSSL::applink APPEND
+        PROPERTY INTERFACE_SOURCES
+          ${_OPENSSL_applink_interface_srcs})
+    endif()
+  endif()
 endif()
 
 # Restore the original find library ordering
diff --git a/Modules/FindPNG.cmake b/Modules/FindPNG.cmake
index f1fe89a..fd0e4e9 100644
--- a/Modules/FindPNG.cmake
+++ b/Modules/FindPNG.cmake
@@ -76,8 +76,8 @@
   # For compatibility with versions prior to this multi-config search, honor
   # any PNG_LIBRARY that is already specified and skip the search.
   if(NOT PNG_LIBRARY)
-    find_library(PNG_LIBRARY_RELEASE NAMES ${PNG_NAMES})
-    find_library(PNG_LIBRARY_DEBUG NAMES ${PNG_NAMES_DEBUG})
+    find_library(PNG_LIBRARY_RELEASE NAMES ${PNG_NAMES} NAMES_PER_DIR)
+    find_library(PNG_LIBRARY_DEBUG NAMES ${PNG_NAMES_DEBUG} NAMES_PER_DIR)
     include(${CMAKE_CURRENT_LIST_DIR}/SelectLibraryConfigurations.cmake)
     select_library_configurations(PNG)
     mark_as_advanced(PNG_LIBRARY_RELEASE PNG_LIBRARY_DEBUG)
diff --git a/Modules/FindPackageHandleStandardArgs.cmake b/Modules/FindPackageHandleStandardArgs.cmake
index a078049..4fb0825 100644
--- a/Modules/FindPackageHandleStandardArgs.cmake
+++ b/Modules/FindPackageHandleStandardArgs.cmake
@@ -57,7 +57,8 @@
     These may be named in the generated failure message asking the
     user to set the missing variable values.  Therefore these should
     typically be cache entries such as ``FOO_LIBRARY`` and not output
-    variables like ``FOO_LIBRARIES``.
+    variables like ``FOO_LIBRARIES``. This option is mandatory if
+    ``HANDLE_COMPONENTS`` is not specified.
 
   ``VERSION_VAR <version-var>``
     Specify the name of a variable that holds the version of the package
@@ -257,7 +258,7 @@
       set(FPHSA_VERSION_VAR ${_NAME}_VERSION)
     endif()
 
-    if(NOT FPHSA_REQUIRED_VARS)
+    if(NOT FPHSA_REQUIRED_VARS AND NOT FPHSA_HANDLE_COMPONENTS)
       message(FATAL_ERROR "No REQUIRED_VARS specified for FIND_PACKAGE_HANDLE_STANDARD_ARGS()")
     endif()
   endif()
@@ -283,7 +284,9 @@
     set(FPHSA_FAIL_MESSAGE "Could NOT find ${_NAME}")
   endif()
 
-  list(GET FPHSA_REQUIRED_VARS 0 _FIRST_REQUIRED_VAR)
+  if (FPHSA_REQUIRED_VARS)
+    list(GET FPHSA_REQUIRED_VARS 0 _FIRST_REQUIRED_VAR)
+  endif()
 
   string(TOUPPER ${_NAME} _NAME_UPPER)
   string(TOLOWER ${_NAME} _NAME_LOWER)
@@ -440,7 +443,17 @@
       _FPHSA_HANDLE_FAILURE_CONFIG_MODE()
     else()
       if(NOT VERSION_OK)
-        _FPHSA_FAILURE_MESSAGE("${FPHSA_FAIL_MESSAGE}: ${VERSION_MSG} (found ${${_FIRST_REQUIRED_VAR}})")
+        set(RESULT_MSG)
+        if (_FIRST_REQUIRED_VAR)
+          string (APPEND RESULT_MSG "found ${${_FIRST_REQUIRED_VAR}}")
+        endif()
+        if (COMPONENT_MSG)
+          if (RESULT_MSG)
+            string (APPEND RESULT_MSG ", ")
+          endif()
+          string (APPEND RESULT_MSG "${FOUND_COMPONENTS_MSG}")
+        endif()
+        _FPHSA_FAILURE_MESSAGE("${FPHSA_FAIL_MESSAGE}: ${VERSION_MSG} (${RESULT_MSG})")
       else()
         _FPHSA_FAILURE_MESSAGE("${FPHSA_FAIL_MESSAGE} (missing:${MISSING_VARS}) ${VERSION_MSG}")
       endif()
diff --git a/Modules/FindPatch.cmake b/Modules/FindPatch.cmake
index 4998839..4108651 100644
--- a/Modules/FindPatch.cmake
+++ b/Modules/FindPatch.cmake
@@ -5,6 +5,8 @@
 FindPatch
 ---------
 
+.. versionadded:: 3.10
+
 The module defines the following variables:
 
 ``Patch_EXECUTABLE``
diff --git a/Modules/FindPerl.cmake b/Modules/FindPerl.cmake
index fd120bf..c14e059 100644
--- a/Modules/FindPerl.cmake
+++ b/Modules/FindPerl.cmake
@@ -73,8 +73,15 @@
 set(PERL ${PERL_EXECUTABLE})
 
 include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
+if (CMAKE_FIND_PACKAGE_NAME STREQUAL "PerlLibs")
+  # FindPerlLibs include()'s this module. It's an old pattern, but rather than
+  # trying to suppress this from outside the module (which is then sensitive to
+  # the contents, detect the case in this module and suppress it explicitly.
+  set(FPHSA_NAME_MISMATCHED 1)
+endif ()
 FIND_PACKAGE_HANDLE_STANDARD_ARGS(Perl
                                   REQUIRED_VARS PERL_EXECUTABLE
                                   VERSION_VAR PERL_VERSION_STRING)
+unset(FPHSA_NAME_MISMATCHED)
 
 mark_as_advanced(PERL_EXECUTABLE)
diff --git a/Modules/FindPerlLibs.cmake b/Modules/FindPerlLibs.cmake
index 7e27f31..d576b86 100644
--- a/Modules/FindPerlLibs.cmake
+++ b/Modules/FindPerlLibs.cmake
@@ -108,6 +108,9 @@
   if (NOT PERL_POSSIBLE_LIBRARY_NAMES)
     set(PERL_POSSIBLE_LIBRARY_NAMES perl${PERL_VERSION_STRING} perl)
   endif()
+  if(CMAKE_SYSTEM_NAME MATCHES "CYGWIN")
+    list (APPEND PERL_POSSIBLE_LIBRARY_NAMES perl${PERL_VERSION_STRING})
+  endif()
   if (CMAKE_SYSTEM_NAME MATCHES "MSYS|CYGWIN")
     # on MSYS and CYGWIN environments, current perl -V:libperl gives shared library name
     # rather than the import library. So, extends possible library names
diff --git a/Modules/FindPkgConfig.cmake b/Modules/FindPkgConfig.cmake
index 28de575..93827d8 100644
--- a/Modules/FindPkgConfig.cmake
+++ b/Modules/FindPkgConfig.cmake
@@ -34,16 +34,31 @@
 find_program(PKG_CONFIG_EXECUTABLE NAMES pkg-config DOC "pkg-config executable")
 mark_as_advanced(PKG_CONFIG_EXECUTABLE)
 
+set(_PKG_CONFIG_FAILURE_MESSAGE "")
 if (PKG_CONFIG_EXECUTABLE)
   execute_process(COMMAND ${PKG_CONFIG_EXECUTABLE} --version
-    OUTPUT_VARIABLE PKG_CONFIG_VERSION_STRING
-    ERROR_QUIET
-    OUTPUT_STRIP_TRAILING_WHITESPACE)
+    OUTPUT_VARIABLE PKG_CONFIG_VERSION_STRING OUTPUT_STRIP_TRAILING_WHITESPACE
+    ERROR_VARIABLE _PKG_CONFIG_VERSION_ERROR ERROR_STRIP_TRAILING_WHITESPACE
+    RESULT_VARIABLE _PKG_CONFIG_VERSION_RESULT
+    )
+
+  if (NOT _PKG_CONFIG_VERSION_RESULT EQUAL 0)
+    string(REPLACE "\n" "\n    " _PKG_CONFIG_VERSION_ERROR "      ${_PKG_CONFIG_VERSION_ERROR}")
+    string(APPEND _PKG_CONFIG_FAILURE_MESSAGE
+      "The command\n"
+      "      \"${PKG_CONFIG_EXECUTABLE}\" --version\n"
+      "    failed with output\n${_PKG_CONFIG_VERSION_ERROR}"
+      )
+    set(PKG_CONFIG_EXECUTABLE "")
+    unset(PKG_CONFIG_VERSION_STRING)
+  endif ()
+  unset(_PKG_CONFIG_VERSION_RESULT)
 endif ()
 
 include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
 find_package_handle_standard_args(PkgConfig
                                   REQUIRED_VARS PKG_CONFIG_EXECUTABLE
+                                  REASON_FAILURE_MESSAGE "${_PKG_CONFIG_FAILURE_MESSAGE}"
                                   VERSION_VAR PKG_CONFIG_VERSION_STRING)
 
 # This is needed because the module name is "PkgConfig" but the name of
@@ -197,7 +212,13 @@
   endif()
 
   unset(_search_paths)
+  unset(_next_is_framework)
   foreach (flag IN LISTS ${_prefix}_LDFLAGS)
+    if (_next_is_framework)
+      list(APPEND _libs "-framework ${flag}")
+      unset(_next_is_framework)
+      continue()
+    endif ()
     if (flag MATCHES "^-L(.*)")
       list(APPEND _search_paths ${CMAKE_MATCH_1})
       continue()
@@ -205,6 +226,9 @@
     if (flag MATCHES "^-l(.*)")
       set(_pkg_search "${CMAKE_MATCH_1}")
     else()
+      if (flag STREQUAL "-framework")
+        set(_next_is_framework TRUE)
+      endif ()
       continue()
     endif()
 
@@ -364,6 +388,30 @@
   unset(_pkgconfig_path_old)
 endmacro()
 
+# pkg-config returns frameworks in --libs-only-other
+# they need to be in ${_prefix}_LIBRARIES so "-framework a -framework b" does
+# not incorrectly be combined to "-framework a b"
+function(_pkgconfig_extract_frameworks _prefix)
+  set(ldflags "${${_prefix}_LDFLAGS_OTHER}")
+  list(FIND ldflags "-framework" FR_POS)
+  list(LENGTH ldflags LD_LENGTH)
+
+  # reduce length by 1 as we need "-framework" and the next entry
+  math(EXPR LD_LENGTH "${LD_LENGTH} - 1")
+  while (FR_POS GREATER -1 AND LD_LENGTH GREATER FR_POS)
+    list(REMOVE_AT ldflags ${FR_POS})
+    list(GET ldflags ${FR_POS} HEAD)
+    list(REMOVE_AT ldflags ${FR_POS})
+    math(EXPR LD_LENGTH "${LD_LENGTH} - 2")
+
+    list(APPEND LIBS "-framework ${HEAD}")
+
+    list(FIND ldflags "-framework" FR_POS)
+  endwhile ()
+  set(${_prefix}_LIBRARIES ${${_prefix}_LIBRARIES} ${LIBS} PARENT_SCOPE)
+  set(${_prefix}_LDFLAGS_OTHER "${ldflags}" PARENT_SCOPE)
+endfunction()
+
 # pkg-config returns -isystem include directories in --cflags-only-other,
 # depending on the version and if there is a space between -isystem and
 # the actual path
@@ -532,6 +580,10 @@
       _pkgconfig_invoke_dyn("${_pkg_check_modules_packages}" "${_prefix}" LDFLAGS       ""                    --libs )
       _pkgconfig_invoke_dyn("${_pkg_check_modules_packages}" "${_prefix}" LDFLAGS_OTHER ""                    --libs-only-other )
 
+      if (APPLE AND "-framework" IN_LIST ${_prefix}_LDFLAGS_OTHER)
+        _pkgconfig_extract_frameworks("${_prefix}")
+      endif()
+
       _pkgconfig_invoke_dyn("${_pkg_check_modules_packages}" "${_prefix}" INCLUDE_DIRS  "(^| )(-I|-isystem ?)" --cflags-only-I )
       _pkgconfig_invoke_dyn("${_pkg_check_modules_packages}" "${_prefix}" CFLAGS        ""                    --cflags )
       _pkgconfig_invoke_dyn("${_pkg_check_modules_packages}" "${_prefix}" CFLAGS_OTHER  ""                    --cflags-only-other )
diff --git a/Modules/FindProtobuf.cmake b/Modules/FindProtobuf.cmake
index f35978d..f6d8fe3 100644
--- a/Modules/FindProtobuf.cmake
+++ b/Modules/FindProtobuf.cmake
@@ -117,7 +117,7 @@
   ``PY``
     Variable to define with autogenerated Python files
   ``ARGN``
-    ``.proto`` filess
+    ``.proto`` files
 #]=======================================================================]
 
 function(protobuf_generate)
@@ -376,11 +376,13 @@
   else()
     find_library(${name}_LIBRARY_RELEASE
       NAMES ${filename}
+      NAMES_PER_DIR
       PATHS ${Protobuf_SRC_ROOT_FOLDER}/vsprojects/${_PROTOBUF_ARCH_DIR}Release)
     mark_as_advanced(${name}_LIBRARY_RELEASE)
 
     find_library(${name}_LIBRARY_DEBUG
       NAMES ${filename}d ${filename}
+      NAMES_PER_DIR
       PATHS ${Protobuf_SRC_ROOT_FOLDER}/vsprojects/${_PROTOBUF_ARCH_DIR}Debug)
     mark_as_advanced(${name}_LIBRARY_DEBUG)
 
diff --git a/Modules/FindPython.cmake b/Modules/FindPython.cmake
index 32ef120..d89029a 100644
--- a/Modules/FindPython.cmake
+++ b/Modules/FindPython.cmake
@@ -5,6 +5,8 @@
 FindPython
 ----------
 
+.. versionadded:: 3.12
+
 Find Python interpreter, compiler and development environment (include
 directories and libraries).
 
@@ -13,13 +15,24 @@
 * ``Interpreter``: search for Python interpreter.
 * ``Compiler``: search for Python compiler. Only offered by IronPython.
 * ``Development``: search for development artifacts (include directories and
-  libraries).
+  libraries). This component includes two sub-components which can be specified
+  independently:
+
+  * ``Development.Module``: search for artifacts for Python module
+    developments.
+  * ``Development.Embed``: search for artifacts for Python embedding
+    developments.
+
 * ``NumPy``: search for NumPy include directories.
 
 If no ``COMPONENTS`` are specified, ``Interpreter`` is assumed.
 
+If component ``Development`` is specified, it implies sub-components
+``Development.Module`` and ``Development.Embed``.
+
 To ensure consistent versions between components ``Interpreter``, ``Compiler``,
-``Development`` and ``NumPy``, specify all components at the same time::
+``Development`` (or one of its sub-components) and ``NumPy``, specify all
+components at the same time::
 
   find_package (Python COMPONENTS Interpreter Development)
 
@@ -30,10 +43,11 @@
 
 .. note::
 
-  If components ``Interpreter`` and ``Development`` are both specified, this
-  module search only for interpreter with same platform architecture as the one
-  defined by ``CMake`` configuration. This contraint does not apply if only
-  ``Interpreter`` component is specified.
+  If components ``Interpreter`` and ``Development`` (or one of its
+  sub-components) are both specified, this module search only for interpreter
+  with same platform architecture as the one defined by ``CMake``
+  configuration. This constraint does not apply if only ``Interpreter``
+  component is specified.
 
 Imported Targets
 ^^^^^^^^^^^^^^^^
@@ -45,12 +59,12 @@
   Python interpreter. Target defined if component ``Interpreter`` is found.
 ``Python::Compiler``
   Python compiler. Target defined if component ``Compiler`` is found.
+``Python::Module``
+  Python library for Python module. Target defined if component
+  ``Development.Module`` is found.
 ``Python::Python``
   Python library for Python embedding. Target defined if component
-  ``Development`` is found.
-``Python::Module``
-  Python library for Python module. Target defined if component ``Development``
-  is found.
+  ``Development.Embed`` is found.
 ``Python::NumPy``
   NumPy Python library. Target defined if component ``NumPy`` is found.
 
@@ -73,33 +87,40 @@
     * Anaconda
     * Canopy
     * IronPython
+    * PyPy
 ``Python_STDLIB``
   Standard platform independent installation directory.
 
   Information returned by
-  ``distutils.sysconfig.get_python_lib(plat_specific=False,standard_lib=True)``.
+  ``distutils.sysconfig.get_python_lib(plat_specific=False,standard_lib=True)``
+  or else ``sysconfig.get_path('stdlib')``.
 ``Python_STDARCH``
   Standard platform dependent installation directory.
 
   Information returned by
-  ``distutils.sysconfig.get_python_lib(plat_specific=True,standard_lib=True)``.
+  ``distutils.sysconfig.get_python_lib(plat_specific=True,standard_lib=True)``
+  or else ``sysconfig.get_path('platstdlib')``.
 ``Python_SITELIB``
   Third-party platform independent installation directory.
 
   Information returned by
-  ``distutils.sysconfig.get_python_lib(plat_specific=False,standard_lib=False)``.
+  ``distutils.sysconfig.get_python_lib(plat_specific=False,standard_lib=False)``
+  or else ``sysconfig.get_path('purelib')``.
 ``Python_SITEARCH``
   Third-party platform dependent installation directory.
 
   Information returned by
-  ``distutils.sysconfig.get_python_lib(plat_specific=True,standard_lib=False)``.
+  ``distutils.sysconfig.get_python_lib(plat_specific=True,standard_lib=False)``
+  or else ``sysconfig.get_path('platlib')``.
 ``Python_SOABI``
   Extension suffix for modules.
 
   Information returned by
-  ``distutils.sysconfig.get_config_flag('SOABI')`` or computed from
-  ``distutils.sysconfig.get_config_flag('EXT_SUFFIX')`` or
-  ``python-config --extension-suffix``.
+  ``distutils.sysconfig.get_config_var('SOABI')`` or computed from
+  ``distutils.sysconfig.get_config_var('EXT_SUFFIX')`` or
+  ``python-config --extension-suffix``. If package ``distutils.sysconfig`` is
+  not available, ``sysconfig.get_config_var('SOABI')`` or
+  ``sysconfig.get_config_var('EXT_SUFFIX')`` are used.
 ``Python_Compiler_FOUND``
   System has the Python compiler.
 ``Python_COMPILER``
@@ -107,8 +128,14 @@
 ``Python_COMPILER_ID``
   A short string unique to the compiler. Possible values include:
     * IronPython
+``Python_DOTNET_LAUNCHER``
+  The ``.Net`` interpreter. Only used by ``IronPython`` implementation.
 ``Python_Development_FOUND``
   System has the Python development artifacts.
+``Python_Development.Module_FOUND``
+  System has the Python development artifacts for Python module.
+``Python_Development.Embed_FOUND``
+  System has the Python development artifacts for Python embedding.
 ``Python_INCLUDE_DIRS``
   The Python include directories.
 ``Python_LIBRARIES``
@@ -125,10 +152,12 @@
   Python minor version.
 ``Python_VERSION_PATCH``
   Python patch version.
+``Python_PyPy_VERSION``
+  Python PyPy version.
 ``Python_NumPy_FOUND``
   System has the NumPy.
 ``Python_NumPy_INCLUDE_DIRS``
-  The NumPy include directries.
+  The NumPy include directories.
 ``Python_NumPy_VERSION``
   The NumPy version.
 
@@ -162,7 +191,7 @@
 
   * ``ON``: Corresponding flag is selected.
   * ``OFF``: Corresponding flag is not selected.
-  * ``ANY``: The two posibilties (``ON`` and ``OFF``) will be searched.
+  * ``ANY``: The two possibilities (``ON`` and ``OFF``) will be searched.
 
   From this 3-tuple, various ABIs will be searched starting from the most
   specialized to the most general. Moreover, ``debug`` versions will be
@@ -237,8 +266,9 @@
   * ``ONLY``: Only the virtual environment is used to look-up for the
     interpreter.
   * ``STANDARD``: The virtual environment is not used to look-up for the
-    interpreter. In this case, variable ``Python_FIND_REGISTRY`` (Windows)
-    or ``CMAKE_FIND_FRAMEWORK`` (macOS) can be set with value ``LAST`` or
+    interpreter but environment variable ``PATH`` is always considered.
+    In this case, variable ``Python_FIND_REGISTRY`` (Windows) or
+    ``CMAKE_FIND_FRAMEWORK`` (macOS) can be set with value ``LAST`` or
     ``NEVER`` to select preferably the interpreter from the virtual
     environment.
 
@@ -248,6 +278,39 @@
     recommended to also include the component ``Interpreter`` to get expected
     result.
 
+``Python_FIND_IMPLEMENTATIONS``
+  This variable defines, in an ordered list, the different implementations
+  which will be searched. The ``Python_FIND_IMPLEMENTATIONS`` variable can
+  hold the following values:
+
+  * ``CPython``: this is the standard implementation. Various products, like
+    ``Anaconda`` or ``ActivePython``, rely on this implementation.
+  * ``IronPython``: This implementation use the ``CSharp`` language for
+    ``.NET Framework`` on top of the `Dynamic Language Runtime` (``DLR``).
+    See `IronPython <http://ironpython.net>`_.
+  * ``PyPy``: This implementation use ``RPython`` language and
+    ``RPython translation toolchain`` to produce the python interpreter.
+    See `PyPy <https://www.pypy.org>`_.
+
+  The default value is:
+
+  * Windows platform: ``CPython``, ``IronPython``
+  * Other platforms: ``CPython``
+
+  .. note::
+
+    This hint has the lowest priority of all hints, so even if, for example,
+    you specify ``IronPython`` first and ``CPython`` in second, a python
+    product based on ``CPython`` can be selected because, for example with
+    ``Python_FIND_STRATEGY=LOCATION``, each location will be search first for
+    ``IronPython`` and second for ``CPython``.
+
+  .. note::
+
+    When ``IronPython`` is specified, on platforms other than ``Windows``, the
+    ``.Net`` interpreter (i.e. ``mono`` command) is expected to be available
+    through the ``PATH`` variable.
+
 Artifacts Specification
 ^^^^^^^^^^^^^^^^^^^^^^^
 
@@ -260,6 +323,9 @@
 ``Python_COMPILER``
   The path to the compiler.
 
+``Python_DOTNET_LAUNCHER``
+  The ``.Net`` interpreter. Only used by ``IronPython`` implementation.
+
 ``Python_LIBRARY``
   The path to the library. It will be used to compute the
   variables ``Python_LIBRARIES``, ``Python_LIBRAY_DIRS`` and
@@ -283,9 +349,25 @@
   When an artifact is specified, all ``HINTS`` will be ignored and no search
   will be performed for this artifact.
 
-  If more than one artifact is specified, it is the user's responsability to
+  If more than one artifact is specified, it is the user's responsibility to
   ensure the consistency of the various artifacts.
 
+By default, this module supports multiple calls in different directories of a
+project with different version/component requirements while providing correct
+and consistent results for each call. To support this behavior, ``CMake`` cache
+is not used in the traditional way which can be problematic for interactive
+specification. So, to enable also interactive specification, module behavior
+can be controlled with the following variable:
+
+``Python_ARTIFACTS_INTERACTIVE``
+  Selects the behavior of the module. This is a boolean variable:
+
+  * If set to ``TRUE``: Create CMake cache entries for the above artifact
+    specification variables so that users can edit them interactively.
+    This disables support for multiple version/component requirements.
+  * If set to ``FALSE`` or undefined: Enable multiple version/component
+    requirements.
+
 Commands
 ^^^^^^^^
 
diff --git a/Modules/FindPython/Support.cmake b/Modules/FindPython/Support.cmake
index 8aa7b97..9b65f39 100644
--- a/Modules/FindPython/Support.cmake
+++ b/Modules/FindPython/Support.cmake
@@ -5,17 +5,13 @@
 # This file is a "template" file used by various FindPython modules.
 #
 
-cmake_policy (GET CMP0094 _${_PYTHON_PREFIX}_LOOKUP_POLICY)
-
-cmake_policy (VERSION 3.7)
-
-if (_${_PYTHON_PREFIX}_LOOKUP_POLICY)
-  cmake_policy (SET CMP0094 ${_${_PYTHON_PREFIX}_LOOKUP_POLICY})
-endif()
-
 #
 # Initial configuration
 #
+
+# IN_LIST operator
+cmake_policy (SET CMP0057 NEW)
+
 if (NOT DEFINED _PYTHON_PREFIX)
   message (FATAL_ERROR "FindPython: INTERNAL ERROR")
 endif()
@@ -75,71 +71,135 @@
       (_PYTHON_isMultiConfig OR CMAKE_BUILD_TYPE))
     # if the generator is multi-config or if CMAKE_BUILD_TYPE is set for
     # single-config generators, set optimized and debug libraries
-    set (${_PYTHON_BASENAME}_LIBRARY "")
-    foreach (_PYTHON_libname IN LISTS ${_PYTHON_BASENAME}_LIBRARY_RELEASE )
-      list( APPEND ${_PYTHON_BASENAME}_LIBRARY optimized "${_PYTHON_libname}" )
+    set (${_PYTHON_BASENAME}_LIBRARIES "")
+    foreach (_PYTHON_libname IN LISTS ${_PYTHON_BASENAME}_LIBRARY_RELEASE)
+      list( APPEND ${_PYTHON_BASENAME}_LIBRARIES optimized "${_PYTHON_libname}")
     endforeach()
-    foreach (_PYTHON_libname IN LISTS ${_PYTHON_BASENAME}_LIBRARY_DEBUG )
-      list( APPEND ${_PYTHON_BASENAME}_LIBRARY debug "${_PYTHON_libname}" )
+    foreach (_PYTHON_libname IN LISTS ${_PYTHON_BASENAME}_LIBRARY_DEBUG)
+      list( APPEND ${_PYTHON_BASENAME}_LIBRARIES debug "${_PYTHON_libname}")
     endforeach()
   elseif (${_PYTHON_BASENAME}_LIBRARY_RELEASE)
-    set (${_PYTHON_BASENAME}_LIBRARY "${${_PYTHON_BASENAME}_LIBRARY_RELEASE}")
+    set (${_PYTHON_BASENAME}_LIBRARIES "${${_PYTHON_BASENAME}_LIBRARY_RELEASE}")
   elseif (${_PYTHON_BASENAME}_LIBRARY_DEBUG)
-    set (${_PYTHON_BASENAME}_LIBRARY "${${_PYTHON_BASENAME}_LIBRARY_DEBUG}")
+    set (${_PYTHON_BASENAME}_LIBRARIES "${${_PYTHON_BASENAME}_LIBRARY_DEBUG}")
   else()
-    set (${_PYTHON_BASENAME}_LIBRARY "${_PYTHON_BASENAME}_LIBRARY-NOTFOUND")
+    set (${_PYTHON_BASENAME}_LIBRARIES "${_PYTHON_BASENAME}_LIBRARY-NOTFOUND")
   endif()
-
-  set (${_PYTHON_BASENAME}_LIBRARIES "${${_PYTHON_BASENAME}_LIBRARY}")
 endmacro()
 
 
 macro (_PYTHON_FIND_FRAMEWORKS)
-  set (${_PYTHON_PREFIX}_FRAMEWORKS)
   if (CMAKE_HOST_APPLE OR APPLE)
     file(TO_CMAKE_PATH "$ENV{CMAKE_FRAMEWORK_PATH}" _pff_CMAKE_FRAMEWORK_PATH)
     set (_pff_frameworks ${CMAKE_FRAMEWORK_PATH}
-                    ${_pff_CMAKE_FRAMEWORK_PATH}
-                    ~/Library/Frameworks
-                    /usr/local/Frameworks
-                    ${CMAKE_SYSTEM_FRAMEWORK_PATH})
+                         ${_pff_CMAKE_FRAMEWORK_PATH}
+                         ~/Library/Frameworks
+                         /usr/local/Frameworks
+                         ${CMAKE_SYSTEM_FRAMEWORK_PATH})
     list (REMOVE_DUPLICATES _pff_frameworks)
-    foreach (_pff_framework IN LISTS _pff_frameworks)
-      if (EXISTS ${_pff_framework}/Python${_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR}.framework)
-        list (APPEND ${_PYTHON_PREFIX}_FRAMEWORKS ${_pff_framework}/Python${_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR}.framework)
-      endif()
-      if (EXISTS ${_pff_framework}/Python.framework)
-        list (APPEND ${_PYTHON_PREFIX}_FRAMEWORKS ${_pff_framework}/Python.framework)
+    foreach (_pff_implementation IN LISTS _${_PYTHON_PREFIX}_FIND_IMPLEMENTATIONS)
+      unset (_${_PYTHON_PREFIX}_${_pff_implementation}_FRAMEWORKS)
+      if (_pff_implementation STREQUAL "CPython")
+        foreach (_pff_framework IN LISTS _pff_frameworks)
+          if (EXISTS ${_pff_framework}/Python${_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR}.framework)
+            list (APPEND _${_PYTHON_PREFIX}_${_pff_implementation}_FRAMEWORKS ${_pff_framework}/Python${_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR}.framework)
+          endif()
+          if (EXISTS ${_pff_framework}/Python.framework)
+            list (APPEND _${_PYTHON_PREFIX}_${_pff_implementation}_FRAMEWORKS ${_pff_framework}/Python.framework)
+          endif()
+        endforeach()
+      elseif (_pff_implementation STREQUAL "IronPython")
+        foreach (_pff_framework IN LISTS _pff_frameworks)
+          if (EXISTS ${_pff_framework}/IronPython.framework)
+            list (APPEND _${_PYTHON_PREFIX}_${_pff_implementation}_FRAMEWORKS ${_pff_framework}/IronPython.framework)
+          endif()
+        endforeach()
       endif()
     endforeach()
+    unset (_pff_implementation)
     unset (_pff_frameworks)
     unset (_pff_framework)
   endif()
 endmacro()
 
-function (_PYTHON_GET_FRAMEWORKS _PYTHON_PGF_FRAMEWORK_PATHS _PYTHON_VERSION)
-  set (_PYTHON_FRAMEWORK_PATHS)
-  foreach (_PYTHON_FRAMEWORK IN LISTS ${_PYTHON_PREFIX}_FRAMEWORKS)
-    list (APPEND _PYTHON_FRAMEWORK_PATHS
-          "${_PYTHON_FRAMEWORK}/Versions/${_PYTHON_VERSION}")
+function (_PYTHON_GET_FRAMEWORKS _PYTHON_PGF_FRAMEWORK_PATHS)
+  cmake_parse_arguments (PARSE_ARGV 1 _PGF "" "" "IMPLEMENTATIONS;VERSION")
+
+  if (NOT _PGF_IMPLEMENTATIONS)
+    set (_PGF_IMPLEMENTATIONS ${_${_PYTHON_PREFIX}_FIND_IMPLEMENTATIONS})
+  endif()
+
+  set (framework_paths)
+
+  foreach (implementation IN LISTS _PGF_IMPLEMENTATIONS)
+    if (implementation STREQUAL "CPython")
+      foreach (version IN LISTS _PGF_VERSION)
+        foreach (framework IN LISTS _${_PYTHON_PREFIX}_${implementation}_FRAMEWORKS)
+          if (EXISTS "${framework}/Versions/${version}")
+            list (APPEND framework_paths "${framework}/Versions/${version}")
+          endif()
+        endforeach()
+      endforeach()
+    elseif (implementation STREQUAL "IronPython")
+      foreach (version IN LISTS _PGF_VERSION)
+        foreach (framework IN LISTS _${_PYTHON_PREFIX}_${implementation}_FRAMEWORKS)
+          # pick-up all available versions
+          file (GLOB versions LIST_DIRECTORIES true RELATIVE "${framework}/Versions/"
+                              "${framework}/Versions/${version}*")
+          list (SORT versions ORDER DESCENDING)
+          list (TRANSFORM versions PREPEND "${framework}/Versions/")
+          list (APPEND framework_paths ${versions})
+        endforeach()
+      endforeach()
+    endif()
   endforeach()
-  set (${_PYTHON_PGF_FRAMEWORK_PATHS} ${_PYTHON_FRAMEWORK_PATHS} PARENT_SCOPE)
+
+  set (${_PYTHON_PGF_FRAMEWORK_PATHS} ${framework_paths} PARENT_SCOPE)
 endfunction()
 
-function (_PYTHON_GET_REGISTRIES _PYTHON_PGR_REGISTRY_PATHS _PYTHON_VERSION)
-  string (REPLACE "." "" _PYTHON_VERSION_NO_DOTS ${_PYTHON_VERSION})
-  set (${_PYTHON_PGR_REGISTRY_PATHS}
-       [HKEY_CURRENT_USER\\SOFTWARE\\Python\\PythonCore\\${_PYTHON_VERSION}-${_${_PYTHON_PREFIX}_ARCH}\\InstallPath]
-       [HKEY_CURRENT_USER\\SOFTWARE\\Python\\PythonCore\\${_PYTHON_VERSION}-${_${_PYTHON_PREFIX}_ARCH2}\\InstallPath]
-       [HKEY_CURRENT_USER\\SOFTWARE\\Python\\PythonCore\\${_PYTHON_VERSION}\\InstallPath]
-       [HKEY_CURRENT_USER\\SOFTWARE\\Python\\ContinuumAnalytics\\Anaconda${_PYTHON_VERSION_NO_DOTS}-${_${_PYTHON_PREFIX}_ARCH}\\InstallPath]
-       [HKEY_CURRENT_USER\\SOFTWARE\\Python\\ContinuumAnalytics\\Anaconda${_PYTHON_VERSION_NO_DOTS}-${_${_PYTHON_PREFIX}_ARCH2}\\InstallPath]
-       [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\${_PYTHON_VERSION}-${_${_PYTHON_PREFIX}_ARCH}\\InstallPath]
-       [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\${_PYTHON_VERSION}-${_${_PYTHON_PREFIX}_ARCH2}\\InstallPath]
-       [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\${_PYTHON_VERSION}\\InstallPath]
-       [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\ContinuumAnalytics\\Anaconda${_PYTHON_VERSION_NO_DOTS}-${_${_PYTHON_PREFIX}_ARCH}\\InstallPath]
-       [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\ContinuumAnalytics\\Anaconda${_PYTHON_VERSION_NO_DOTS}-${_${_PYTHON_PREFIX}_ARCH2}\\InstallPath]
-       PARENT_SCOPE)
+function (_PYTHON_GET_REGISTRIES _PYTHON_PGR_REGISTRY_PATHS)
+  cmake_parse_arguments (PARSE_ARGV 1 _PGR "" "" "IMPLEMENTATIONS;VERSION")
+
+  if (NOT _PGR_IMPLEMENTATIONS)
+    set (_PGR_IMPLEMENTATIONS ${_${_PYTHON_PREFIX}_FIND_IMPLEMENTATIONS})
+  endif()
+
+  set (registries)
+
+  foreach (implementation IN LISTS _PGR_IMPLEMENTATIONS)
+    if (implementation STREQUAL "CPython")
+      foreach (version IN LISTS _PGR_VERSION)
+        string (REPLACE "." "" version_no_dots ${version})
+        list (APPEND registries
+                     [HKEY_CURRENT_USER\\SOFTWARE\\Python\\PythonCore\\${version}-${_${_PYTHON_PREFIX}_ARCH}\\InstallPath]
+                     [HKEY_CURRENT_USER\\SOFTWARE\\Python\\PythonCore\\${version}-${_${_PYTHON_PREFIX}_ARCH2}\\InstallPath])
+        if (version VERSION_GREATER_EQUAL "3.5")
+          get_filename_component (arch "[HKEY_CURRENT_USER\\Software\\Python\\PythonCore\\${version};SysArchitecture]" NAME)
+          if (arch MATCHES "(${_${_PYTHON_PREFIX}_ARCH}|${_${_PYTHON_PREFIX}_ARCH2})bit")
+            list (APPEND registries
+                         [HKEY_CURRENT_USER\\SOFTWARE\\Python\\PythonCore\\${version}\\InstallPath])
+          endif()
+        else()
+          list (APPEND registries
+                       [HKEY_CURRENT_USER\\SOFTWARE\\Python\\PythonCore\\${version}\\InstallPath])
+        endif()
+        list (APPEND registries
+                     [HKEY_CURRENT_USER\\SOFTWARE\\Python\\ContinuumAnalytics\\Anaconda${version_no_dots}-${_${_PYTHON_PREFIX}_ARCH}\\InstallPath]
+                     [HKEY_CURRENT_USER\\SOFTWARE\\Python\\ContinuumAnalytics\\Anaconda${version_no_dots}-${_${_PYTHON_PREFIX}_ARCH2}\\InstallPath]
+                     [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\${version}-${_${_PYTHON_PREFIX}_ARCH}\\InstallPath]
+                     [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\${version}-${_${_PYTHON_PREFIX}_ARCH2}\\InstallPath]
+                     [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\${version}\\InstallPath]
+                     [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\ContinuumAnalytics\\Anaconda${version_no_dots}-${_${_PYTHON_PREFIX}_ARCH}\\InstallPath]
+                     [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\ContinuumAnalytics\\Anaconda${version_no_dots}-${_${_PYTHON_PREFIX}_ARCH2}\\InstallPath])
+      endforeach()
+    elseif (implementation STREQUAL "IronPython")
+      foreach (version  IN LISTS _PGR_VERSION)
+        list (APPEND registries [HKEY_LOCAL_MACHINE\\SOFTWARE\\IronPython\\${version}\\InstallPath])
+      endforeach()
+    endif()
+  endforeach()
+
+  set (${_PYTHON_PGR_REGISTRY_PATHS} "${registries}" PARENT_SCOPE)
 endfunction()
 
 
@@ -187,7 +247,11 @@
 endfunction()
 
 function (_PYTHON_GET_PATH_SUFFIXES _PYTHON_PGPS_PATH_SUFFIXES)
-  cmake_parse_arguments (PARSE_ARGV 1 _PGPS "LIBRARY;INCLUDE" "VERSION" "")
+  cmake_parse_arguments (PARSE_ARGV 1 _PGPS "INTERPRETER;COMPILER;LIBRARY;INCLUDE" "" "IMPLEMENTATIONS;VERSION")
+
+  if (NOT _PGPS_IMPLEMENTATIONS)
+    set (_PGPS_IMPLEMENTATIONS ${_${_PYTHON_PREFIX}_FIND_IMPLEMENTATIONS})
+  endif()
 
   if (DEFINED _${_PYTHON_PREFIX}_ABIFLAGS)
     set (abi "${_${_PYTHON_PREFIX}_ABIFLAGS}")
@@ -196,93 +260,163 @@
   endif()
 
   set (path_suffixes)
-  if (_PGPS_LIBRARY)
-    if (CMAKE_LIBRARY_ARCHITECTURE)
-      list (APPEND path_suffixes lib/${CMAKE_LIBRARY_ARCHITECTURE})
-    endif()
-    list (APPEND path_suffixes lib libs)
 
-    if (CMAKE_LIBRARY_ARCHITECTURE)
-      set (suffixes "${abi}")
-      if (suffixes)
-        list (TRANSFORM suffixes PREPEND "lib/python${_PGPS_VERSION}/config-${_PGPS_VERSION}")
-        list (TRANSFORM suffixes APPEND "-${CMAKE_LIBRARY_ARCHITECTURE}")
+  foreach (implementation IN LISTS _PGPS_IMPLEMENTATIONS)
+    if (implementation STREQUAL "CPython")
+      if (_PGPS_INTERPRETER)
+        list (APPEND path_suffixes bin Scripts)
       else()
-        set (suffixes "lib/python${_PGPS_VERSION}/config-${_PGPS_VERSION}-${CMAKE_LIBRARY_ARCHITECTURE}")
+        foreach (version IN LISTS _PGPS_VERSION)
+          if (_PGPS_LIBRARY)
+            if (CMAKE_LIBRARY_ARCHITECTURE)
+              list (APPEND path_suffixes lib/${CMAKE_LIBRARY_ARCHITECTURE})
+            endif()
+            list (APPEND path_suffixes lib libs)
+
+            if (CMAKE_LIBRARY_ARCHITECTURE)
+              set (suffixes "${abi}")
+              if (suffixes)
+                list (TRANSFORM suffixes PREPEND "lib/python${_PGPS_VERSION}/config-${_PGPS_VERSION}")
+                list (TRANSFORM suffixes APPEND "-${CMAKE_LIBRARY_ARCHITECTURE}")
+              else()
+                set (suffixes "lib/python${_PGPS_VERSION}/config-${_PGPS_VERSION}-${CMAKE_LIBRARY_ARCHITECTURE}")
+              endif()
+              list (APPEND path_suffixes ${suffixes})
+            endif()
+            set (suffixes "${abi}")
+            if (suffixes)
+              list (TRANSFORM suffixes PREPEND "lib/python${_PGPS_VERSION}/config-${_PGPS_VERSION}")
+            else()
+              set (suffixes "lib/python${_PGPS_VERSION}/config-${_PGPS_VERSION}")
+            endif()
+            list (APPEND path_suffixes ${suffixes})
+          elseif (_PGPS_INCLUDE)
+            set (suffixes "${abi}")
+            if (suffixes)
+              list (TRANSFORM suffixes PREPEND "include/python${_PGPS_VERSION}")
+            else()
+              set (suffixes "include/python${_PGPS_VERSION}")
+            endif()
+            list (APPEND path_suffixes ${suffixes} include)
+          endif()
+        endforeach()
       endif()
-      list (APPEND path_suffixes ${suffixes})
+    elseif (implementation STREQUAL "IronPython")
+      if (_PGPS_INTERPRETER OR _PGPS_COMPILER)
+        foreach (version IN LISTS _PGPS_VERSION)
+          list (APPEND path_suffixes "share/ironpython${version}")
+        endforeach()
+        list (APPEND path_suffixes ${_${_PYTHON_PREFIX}_IRON_PYTHON_PATH_SUFFIXES})
+      endif()
+    elseif (implementation STREQUAL "PyPy")
+      if (_PGPS_INTERPRETER)
+        list (APPEND path_suffixes ${_${_PYTHON_PREFIX}_PYPY_EXECUTABLE_PATH_SUFFIXES})
+      elseif (_PGPS_LIBRARY)
+        list (APPEND path_suffixes ${_${_PYTHON_PREFIX}_PYPY_LIBRARY_PATH_SUFFIXES})
+      elseif (_PGPS_INCLUDE)
+        list (APPEND path_suffixes ${_${_PYTHON_PREFIX}_PYPY_INCLUDE_PATH_SUFFIXES})
+      endif()
     endif()
-    set (suffixes "${abi}")
-    if (suffixes)
-      list (TRANSFORM suffixes PREPEND "lib/python${_PGPS_VERSION}/config-${_PGPS_VERSION}")
-    else()
-      set (suffixes "lib/python${_PGPS_VERSION}/config-${_PGPS_VERSION}")
-    endif()
-    list (APPEND path_suffixes ${suffixes})
-  elseif (_PGPS_INCLUDE)
-    set (suffixes "${abi}")
-    if (suffixes)
-      list (TRANSFORM suffixes PREPEND "include/python${_PGPS_VERSION}")
-    else()
-      set (suffixes "include/python${_PGPS_VERSION}")
-    endif()
-    list (APPEND path_suffixes ${suffixes} include)
-  endif()
+  endforeach()
+  list (REMOVE_DUPLICATES path_suffixes)
 
   set (${_PYTHON_PGPS_PATH_SUFFIXES} ${path_suffixes} PARENT_SCOPE)
 endfunction()
 
 function (_PYTHON_GET_NAMES _PYTHON_PGN_NAMES)
-  cmake_parse_arguments (PARSE_ARGV 1 _PGN "POSIX;EXECUTABLE;CONFIG;LIBRARY;WIN32;DEBUG" "VERSION" "")
+  cmake_parse_arguments (PARSE_ARGV 1 _PGN "POSIX;INTERPRETER;COMPILER;CONFIG;LIBRARY;WIN32;DEBUG" "" "IMPLEMENTATIONS;VERSION")
+
+  if (NOT _PGN_IMPLEMENTATIONS)
+    set (_PGN_IMPLEMENTATIONS ${_${_PYTHON_PREFIX}_FIND_IMPLEMENTATIONS})
+  endif()
 
   set (names)
 
-  if (_PGN_WIN32)
-    string (REPLACE "." "" _PYTHON_VERSION_NO_DOTS ${_PGN_VERSION})
+  foreach (implementation IN LISTS _PGN_IMPLEMENTATIONS)
+    if (implementation STREQUAL "CPython")
+      foreach (version IN LISTS _PGN_VERSION)
+        if (_PGN_WIN32)
+          string (REPLACE "." "" version_no_dots ${version})
 
-    set (name python${_PYTHON_VERSION_NO_DOTS})
-    if (_PGN_DEBUG)
-      string (APPEND name "_d")
-    endif()
+          set (name python${version_no_dots})
+          if (_PGN_DEBUG)
+            string (APPEND name "_d")
+          endif()
 
-    list (APPEND names "${name}")
-  endif()
+          list (APPEND names "${name}")
+        endif()
 
-  if (_PGN_POSIX)
-    if (DEFINED _${_PYTHON_PREFIX}_ABIFLAGS)
-      set (abi "${_${_PYTHON_PREFIX}_ABIFLAGS}")
-    else()
-      if (_PGN_EXECUTABLE OR _PGN_CONFIG)
-        set (abi "")
-      else()
-        set (abi "mu" "m" "u" "")
+        if (_PGN_POSIX)
+          if (DEFINED _${_PYTHON_PREFIX}_ABIFLAGS)
+            set (abi "${_${_PYTHON_PREFIX}_ABIFLAGS}")
+          else()
+            if (_PGN_INTERPRETER OR _PGN_CONFIG)
+              set (abi "")
+            else()
+              set (abi "mu" "m" "u" "")
+            endif()
+          endif()
+
+          if (abi)
+            if (_PGN_CONFIG AND DEFINED CMAKE_LIBRARY_ARCHITECTURE)
+              set (abinames "${abi}")
+              list (TRANSFORM abinames PREPEND "${CMAKE_LIBRARY_ARCHITECTURE}-python${version}")
+              list (TRANSFORM abinames APPEND "-config")
+              list (APPEND names ${abinames})
+            endif()
+            set (abinames "${abi}")
+            list (TRANSFORM abinames PREPEND "python${version}")
+            if (_PGN_CONFIG)
+              list (TRANSFORM abinames APPEND "-config")
+            endif()
+            list (APPEND names ${abinames})
+          else()
+            unset (abinames)
+            if (_PGN_CONFIG AND DEFINED CMAKE_LIBRARY_ARCHITECTURE)
+              set (abinames "${CMAKE_LIBRARY_ARCHITECTURE}-python${version}")
+            endif()
+            list (APPEND abinames "python${version}")
+            if (_PGN_CONFIG)
+              list (TRANSFORM abinames APPEND "-config")
+            endif()
+            list (APPEND names ${abinames})
+          endif()
+        endif()
+      endforeach()
+      if (_PGN_INTERPRETER)
+        list (APPEND names python${_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR} python)
+      endif()
+    elseif (implementation STREQUAL "IronPython")
+      if (_PGN_INTERPRETER)
+        if (NOT CMAKE_SYSTEM_NAME STREQUAL "Linux")
+          # Do not use wrapper script on Linux because it is buggy: -c interpreter option cannot be used
+          foreach (version IN LISTS _PGN_VERSION)
+            list (APPEND names "ipy${version}")
+          endforeach()
+        endif()
+        list (APPEND names ${_${_PYTHON_PREFIX}_IRON_PYTHON_INTERPRETER_NAMES})
+      elseif (_PGN_COMPILER)
+        list (APPEND names ${_${_PYTHON_PREFIX}_IRON_PYTHON_COMPILER_NAMES})
+      endif()
+    elseif (implementation STREQUAL "PyPy")
+      if (_PGN_INTERPRETER)
+        list (APPEND names ${_${_PYTHON_PREFIX}_PYPY_NAMES})
+      elseif (_PGN_LIBRARY)
+        if (_PGN_WIN32)
+          foreach (version IN LISTS _PGN_VERSION)
+            string (REPLACE "." "" version_no_dots ${version})
+
+            set (name "python${version_no_dots}")
+            if (_PGN_DEBUG)
+              string (APPEND name "_d")
+            endif()
+            list (APPEND names "${name}")
+          endforeach()
+        endif()
+        list (APPEND names ${_${_PYTHON_PREFIX}_PYPY_LIB_NAMES})
       endif()
     endif()
-
-    if (abi)
-      if (_PGN_CONFIG AND DEFINED CMAKE_LIBRARY_ARCHITECTURE)
-        set (abinames "${abi}")
-        list (TRANSFORM abinames PREPEND "${CMAKE_LIBRARY_ARCHITECTURE}-python${_PGN_VERSION}")
-        list (TRANSFORM abinames APPEND "-config")
-        list (APPEND names ${abinames})
-      endif()
-      set (abinames "${abi}")
-      list (TRANSFORM abinames PREPEND "python${_PGN_VERSION}")
-      if (_PGN_CONFIG)
-        list (TRANSFORM abinames APPEND "-config")
-      endif()
-      list (APPEND names ${abinames})
-    else()
-      if (_PGN_CONFIG AND DEFINED CMAKE_LIBRARY_ARCHITECTURE)
-        set (abinames "${CMAKE_LIBRARY_ARCHITECTURE}-python${_PGN_VERSION}")
-      endif()
-      list (APPEND abinames "python${_PGN_VERSION}")
-      if (_PGN_CONFIG)
-        list (TRANSFORM abinames APPEND "-config")
-      endif()
-      list (APPEND names ${abinames})
-    endif()
-  endif()
+  endforeach()
 
   set (${_PYTHON_PGN_NAMES} ${names} PARENT_SCOPE)
 endfunction()
@@ -323,7 +457,7 @@
 
   if (_${_PYTHON_PREFIX}_EXECUTABLE AND NOT CMAKE_CROSSCOMPILING)
     if (NAME STREQUAL "PREFIX")
-      execute_process (COMMAND "${_${_PYTHON_PREFIX}_EXECUTABLE}" -c "import sys; from distutils import sysconfig; sys.stdout.write(';'.join([sysconfig.PREFIX,sysconfig.EXEC_PREFIX,sysconfig.BASE_EXEC_PREFIX]))"
+      execute_process (COMMAND ${_${_PYTHON_PREFIX}_INTERPRETER_LAUNCHER} "${_${_PYTHON_PREFIX}_EXECUTABLE}" -c "import sys\ntry:\n   from distutils import sysconfig\n   sys.stdout.write(';'.join([sysconfig.PREFIX,sysconfig.EXEC_PREFIX,sysconfig.BASE_EXEC_PREFIX]))\nexcept Exception:\n   import sysconfig\n   sys.stdout.write(';'.join([sysconfig.get_config_var('base') or '', sysconfig.get_config_var('installed_base') or '']))"
                        RESULT_VARIABLE _result
                        OUTPUT_VARIABLE _values
                        ERROR_QUIET
@@ -334,16 +468,25 @@
         list (REMOVE_DUPLICATES _values)
       endif()
     elseif (NAME STREQUAL "INCLUDES")
-      execute_process (COMMAND "${_${_PYTHON_PREFIX}_EXECUTABLE}" -c "import sys; from distutils import sysconfig; sys.stdout.write(';'.join([sysconfig.get_python_inc(plat_specific=True),sysconfig.get_python_inc(plat_specific=False)]))"
+      if (WIN32)
+        set (_scheme "nt")
+      else()
+        set (_scheme "posix_prefix")
+      endif()
+      execute_process (COMMAND ${_${_PYTHON_PREFIX}_INTERPRETER_LAUNCHER} "${_${_PYTHON_PREFIX}_EXECUTABLE}" -c
+                               "import sys\ntry:\n   from distutils import sysconfig\n   sys.stdout.write(';'.join([sysconfig.get_python_inc(plat_specific=True),sysconfig.get_python_inc(plat_specific=False)]))\nexcept Exception:\n   import sysconfig\n   sys.stdout.write(';'.join([sysconfig.get_path('platinclude'),sysconfig.get_path('platinclude','${_scheme}'),sysconfig.get_path('include'),sysconfig.get_path('include','${_scheme}')]))"
                        RESULT_VARIABLE _result
                        OUTPUT_VARIABLE _values
                        ERROR_QUIET
                        OUTPUT_STRIP_TRAILING_WHITESPACE)
       if (_result)
         unset (_values)
+      else()
+        list (REMOVE_DUPLICATES _values)
       endif()
     elseif (NAME STREQUAL "SOABI")
-      execute_process (COMMAND "${_${_PYTHON_PREFIX}_EXECUTABLE}" -c "import sys; from distutils import sysconfig;sys.stdout.write(';'.join([sysconfig.get_config_var('SOABI') or '',sysconfig.get_config_var('EXT_SUFFIX') or '']))"
+      execute_process (COMMAND ${_${_PYTHON_PREFIX}_INTERPRETER_LAUNCHER} "${_${_PYTHON_PREFIX}_EXECUTABLE}" -c
+                               "import sys\ntry:\n   from distutils import sysconfig\n   sys.stdout.write(';'.join([sysconfig.get_config_var('SOABI') or '',sysconfig.get_config_var('EXT_SUFFIX') or '']))\nexcept Exception:\n   import sysconfig;sys.stdout.write(';'.join([sysconfig.get_config_var('SOABI') or '',sysconfig.get_config_var('EXT_SUFFIX') or '']))"
                        RESULT_VARIABLE _result
                        OUTPUT_VARIABLE _soabi
                        ERROR_QUIET
@@ -351,14 +494,15 @@
       if (_result)
         unset (_values)
       else()
-        list (GET _soabi 0 _values)
-        if (NOT _values)
-          # try to compute SOABI from EXT_SUFFIX
-          list (GET _soabi 1 _values)
-          if (_values)
-            # clean-up: remove prefix character and suffix
-            string (REGEX REPLACE "^[.-](.+)(${CMAKE_SHARED_LIBRARY_SUFFIX}|\\.(so|pyd))$" "\\1" _values "${_values}")
+        foreach (_item IN LISTS _soabi)
+          if (_item)
+            set (_values "${_item}")
+            break()
           endif()
+        endforeach()
+        if (_values)
+          # clean-up: remove prefix character and suffix
+          string (REGEX REPLACE "^[.-](.+)(${CMAKE_SHARED_LIBRARY_SUFFIX}|\\.(so|pyd))$" "\\1" _values "${_values}")
         endif()
       endif()
     else()
@@ -366,7 +510,8 @@
       if (NAME STREQUAL "CONFIGDIR")
         set (config_flag "LIBPL")
       endif()
-      execute_process (COMMAND "${_${_PYTHON_PREFIX}_EXECUTABLE}" -c "import sys; from distutils import sysconfig; sys.stdout.write(sysconfig.get_config_var('${config_flag}'))"
+      execute_process (COMMAND ${_${_PYTHON_PREFIX}_INTERPRETER_LAUNCHER} "${_${_PYTHON_PREFIX}_EXECUTABLE}" -c
+                               "import sys\ntry:\n   from distutils import sysconfig\n   sys.stdout.write(sysconfig.get_config_var('${config_flag}'))\nexcept Exception:\n   import sysconfig\n   sys.stdout.write(sysconfig.get_config_var('${config_flag}'))"
                        RESULT_VARIABLE _result
                        OUTPUT_VARIABLE _values
                        ERROR_QUIET
@@ -394,6 +539,10 @@
     list (REMOVE_DUPLICATES _values)
   endif()
 
+  if (WIN32 AND NAME MATCHES "^(PREFIX|CONFIGDIR|INCLUDES)$")
+    file (TO_CMAKE_PATH "${_values}" _values)
+  endif()
+
   set (${_PYTHON_PGCV_VALUE} "${_values}" PARENT_SCOPE)
 endfunction()
 
@@ -420,6 +569,16 @@
         set (${_PGV_PREFIX}VERSION_MINOR "${CMAKE_MATCH_2}" PARENT_SCOPE)
         set (${_PGV_PREFIX}VERSION "${CMAKE_MATCH_1}.${CMAKE_MATCH_2}" PARENT_SCOPE)
         set (${_PGV_PREFIX}ABI "${CMAKE_MATCH_3}" PARENT_SCOPE)
+      elseif (_${_PYTHON_PREFIX}_LIBRARY_RELEASE MATCHES "pypy(3)?")
+        set (version "${CMAKE_MATCH_1}")
+        if (version EQUAL "3")
+          set (${_PGV_PREFIX}VERSION_MAJOR "3" PARENT_SCOPE)
+          set (${_PGV_PREFIX}VERSION "3" PARENT_SCOPE)
+        else()
+          set (${_PGV_PREFIX}VERSION_MAJOR "2" PARENT_SCOPE)
+          set (${_PGV_PREFIX}VERSION "2" PARENT_SCOPE)
+        endif()
+        set (${_PGV_PREFIX}ABI "" PARENT_SCOPE)
       endif()
     endif()
   else()
@@ -466,6 +625,36 @@
   endif()
 endfunction()
 
+function (_PYTHON_GET_LAUNCHER _PYTHON_PGL_NAME)
+  cmake_parse_arguments (PARSE_ARGV 1 _PGL "INTERPRETER;COMPILER" "" "")
+
+  unset ({_PYTHON_PGL_NAME} PARENT_SCOPE)
+
+  if ((_PGL_INTERPRETER AND NOT _${_PYTHON_PREFIX}_EXECUTABLE)
+      OR (_PGL_COMPILER AND NOT _${_PYTHON_PREFIX}_COMPILER))
+    return()
+  endif()
+
+  if ("IronPython" IN_LIST _${_PYTHON_PREFIX}_FIND_IMPLEMENTATIONS
+      AND NOT SYSTEM_NAME MATCHES "Windows|Linux")
+    if (_PGL_INTERPRETER)
+      get_filename_component (name "${_${_PYTHON_PREFIX}_EXECUTABLE}" NAME)
+      get_filename_component (ext "${_${_PYTHON_PREFIX}_EXECUTABLE}" LAST_EXT)
+      if (name IN_LIST _${_PYTHON_PREFIX}_IRON_PYTHON_INTERPRETER_NAMES
+          AND ext STREQUAL ".exe")
+        set (${_PYTHON_PGL_NAME} "${${_PYTHON_PREFIX}_DOTNET_LAUNCHER}" PARENT_SCOPE)
+      endif()
+    else()
+      get_filename_component (name "${_${_PYTHON_PREFIX}_COMPILER}" NAME)
+      get_filename_component (ext "${_${_PYTHON_PREFIX}_COMPILER}" LAST_EXT)
+      if (name IN_LIST _${_PYTHON_PREFIX}_IRON_PYTHON_COMPILER_NAMES
+          AND ext STREQUAL ".exe")
+        set (${_PYTHON_PGL_NAME} "${${_PYTHON_PREFIX}_DOTNET_LAUNCHER}" PARENT_SCOPE)
+      endif()
+    endif()
+  endif()
+endfunction()
+
 
 function (_PYTHON_VALIDATE_INTERPRETER)
   if (NOT _${_PYTHON_PREFIX}_EXECUTABLE)
@@ -486,9 +675,11 @@
     return()
   endif()
 
+  _python_get_launcher (launcher INTERPRETER)
+
   # validate ABI compatibility
   if (DEFINED _${_PYTHON_PREFIX}_FIND_ABI)
-    execute_process (COMMAND "${_${_PYTHON_PREFIX}_EXECUTABLE}" -c
+    execute_process (COMMAND ${launcher} "${_${_PYTHON_PREFIX}_EXECUTABLE}" -c
                              "import sys; sys.stdout.write(sys.abiflags)"
                      RESULT_VARIABLE result
                      OUTPUT_VARIABLE abi
@@ -519,7 +710,7 @@
       endif()
 
       # executable found must have a specific version
-      execute_process (COMMAND "${_${_PYTHON_PREFIX}_EXECUTABLE}" -c
+      execute_process (COMMAND ${launcher} "${_${_PYTHON_PREFIX}_EXECUTABLE}" -c
                                "import sys; sys.stdout.write('.'.join([str(x) for x in sys.version_info[:${count}]]))"
                        RESULT_VARIABLE result
                        OUTPUT_VARIABLE version
@@ -553,7 +744,7 @@
     if (NOT python_name STREQUAL "python${_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR}${CMAKE_EXECUTABLE_SUFFIX}")
       # executable found do not have version in name
       # ensure major version is OK
-      execute_process (COMMAND "${_${_PYTHON_PREFIX}_EXECUTABLE}" -c
+      execute_process (COMMAND ${launcher} "${_${_PYTHON_PREFIX}_EXECUTABLE}" -c
                                "import sys; sys.stdout.write(str(sys.version_info[0]))"
                        RESULT_VARIABLE result
                        OUTPUT_VARIABLE version
@@ -572,10 +763,11 @@
     endif()
   endif()
 
-  if (CMAKE_SIZEOF_VOID_P AND "Development" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS
+  if (CMAKE_SIZEOF_VOID_P AND ("Development.Module" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS
+        OR "Development.Embed" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS)
       AND NOT CMAKE_CROSSCOMPILING)
     # In this case, interpreter must have same architecture as environment
-    execute_process (COMMAND "${_${_PYTHON_PREFIX}_EXECUTABLE}" -c
+    execute_process (COMMAND ${launcher} "${_${_PYTHON_PREFIX}_EXECUTABLE}" -c
                              "import sys, struct; sys.stdout.write(str(struct.calcsize(\"P\")))"
                      RESULT_VARIABLE result
                      OUTPUT_VARIABLE size
@@ -617,6 +809,8 @@
     return()
   endif()
 
+  _python_get_launcher (launcher COMPILER)
+
   # retrieve python environment version from compiler
   set (working_dir "${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/PythonCompilerVersion.dir")
   if (major_version)
@@ -632,12 +826,16 @@
     endif()
     file (WRITE "${working_dir}/version.py" "import sys; sys.stdout.write('.'.join([str(x) for x in sys.version_info[:${count}]]))\n")
   endif()
-  execute_process (COMMAND "${_${_PYTHON_PREFIX}_COMPILER}" /target:exe /embed "${working_dir}/version.py"
+  execute_process (COMMAND ${launcher} "${_${_PYTHON_PREFIX}_COMPILER}"
+                           ${_${_PYTHON_PREFIX}_IRON_PYTHON_COMPILER_ARCH_FLAGS}
+                           /target:exe /embed "${working_dir}/version.py"
                    WORKING_DIRECTORY "${working_dir}"
                    OUTPUT_QUIET
                    ERROR_QUIET
                    OUTPUT_STRIP_TRAILING_WHITESPACE)
-  execute_process (COMMAND "${working_dir}/version"
+  get_filename_component (ir_dir "${_${_PYTHON_PREFIX}_COMPILER}" DIRECTORY)
+  execute_process (COMMAND "${CMAKE_COMMAND}" -E env "MONO_PATH=${ir_dir}"
+                                              ${${_PYTHON_PREFIX}_DOTNET_LAUNCHER} "${working_dir}/version.exe"
                    WORKING_DIRECTORY "${working_dir}"
                    RESULT_VARIABLE result
                    OUTPUT_VARIABLE version
@@ -658,6 +856,7 @@
 
 function (_PYTHON_VALIDATE_LIBRARY)
   if (NOT _${_PYTHON_PREFIX}_LIBRARY_RELEASE)
+    unset (_${_PYTHON_PREFIX}_LIBRARY_DEBUG)
     return()
   endif()
 
@@ -784,13 +983,30 @@
       list (APPEND _PYTHON_DIRS "${_PYTHON_DIR}")
     endif()
   endforeach()
-  if (_PYTHON_DIRS)
-    list (REMOVE_DUPLICATES _PYTHON_DIRS)
-  endif()
+  list (REMOVE_DUPLICATES _PYTHON_DIRS)
   set (${_PYTHON_SLD_RESULT} ${_PYTHON_DIRS} PARENT_SCOPE)
 endfunction()
 
 
+function (_PYTHON_SET_DEVELOPMENT_MODULE_FOUND module)
+  if ("Development.${module}" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS)
+    string(TOUPPER "${module}" id)
+    set (module_found TRUE)
+
+    if ("LIBRARY" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_${id}_ARTIFACTS
+        AND NOT _${_PYTHON_PREFIX}_LIBRARY_RELEASE)
+      set (module_found FALSE)
+    endif()
+    if ("INCLUDE_DIR" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_${id}_ARTIFACTS
+        AND NOT _${_PYTHON_PREFIX}_INCLUDE_DIR)
+      set (module_found FALSE)
+    endif()
+
+    set (${_PYTHON_PREFIX}_Development.${module}_FOUND ${module_found} PARENT_SCOPE)
+  endif()
+endfunction()
+
+
 # If major version is specified, it must be the same as internal major version
 if (DEFINED ${_PYTHON_PREFIX}_FIND_VERSION_MAJOR
     AND NOT ${_PYTHON_PREFIX}_FIND_VERSION_MAJOR VERSION_EQUAL _${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR)
@@ -804,12 +1020,34 @@
   set (${_PYTHON_PREFIX}_FIND_REQUIRED_Interpreter TRUE)
 endif()
 if ("NumPy" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS)
-  list (APPEND ${_PYTHON_PREFIX}_FIND_COMPONENTS "Interpreter" "Development")
-  list (REMOVE_DUPLICATES ${_PYTHON_PREFIX}_FIND_COMPONENTS)
+  list (APPEND ${_PYTHON_PREFIX}_FIND_COMPONENTS "Interpreter" "Development.Module")
 endif()
-foreach (_${_PYTHON_PREFIX}_COMPONENT IN ITEMS Interpreter Compiler Development NumPy)
+if ("Development" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS)
+  list (APPEND ${_PYTHON_PREFIX}_FIND_COMPONENTS "Development.Module" "Development.Embed")
+endif()
+list (REMOVE_DUPLICATES ${_PYTHON_PREFIX}_FIND_COMPONENTS)
+foreach (_${_PYTHON_PREFIX}_COMPONENT IN ITEMS Interpreter Compiler Development Development.Module Development.Embed NumPy)
   set (${_PYTHON_PREFIX}_${_${_PYTHON_PREFIX}_COMPONENT}_FOUND FALSE)
 endforeach()
+if (${_PYTHON_PREFIX}_FIND_REQUIRED_Development)
+  set (${_PYTHON_PREFIX}_FIND_REQUIRED_Development.Module TRUE)
+  set (${_PYTHON_PREFIX}_FIND_REQUIRED_Development.Embed TRUE)
+endif()
+
+unset (_${_PYTHON_PREFIX}_FIND_DEVELOPMENT_ARTIFACTS)
+unset (_${_PYTHON_PREFIX}_FIND_DEVELOPMENT_MODULE_ARTIFACTS)
+unset (_${_PYTHON_PREFIX}_FIND_DEVELOPMENT_EMBED_ARTIFACTS)
+if ("Development.Module" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS)
+  if (CMAKE_SYSTEM_NAME MATCHES "^(Windows.*|CYGWIN|MSYS)$")
+    list (APPEND _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_MODULE_ARTIFACTS "LIBRARY")
+  endif()
+  list (APPEND _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_MODULE_ARTIFACTS "INCLUDE_DIR")
+endif()
+if ("Development.Embed" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS)
+  list (APPEND _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_EMBED_ARTIFACTS "LIBRARY" "INCLUDE_DIR")
+endif()
+set (_${_PYTHON_PREFIX}_FIND_DEVELOPMENT_ARTIFACTS ${_${_PYTHON_PREFIX}_FIND_DEVELOPMENT_MODULE_ARTIFACTS} ${_${_PYTHON_PREFIX}_FIND_DEVELOPMENT_EMBED_ARTIFACTS})
+list (REMOVE_DUPLICATES _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_ARTIFACTS)
 
 # Set versions to search
 ## default: search any version
@@ -819,13 +1057,13 @@
 if (${_PYTHON_PREFIX}_FIND_VERSION_COUNT)
   if (${_PYTHON_PREFIX}_FIND_VERSION_EXACT)
     set (_${_PYTHON_PREFIX}_FIND_VERSION_EXACT "EXACT")
-    set (_${_PYTHON_PREFIX}_FIND_VERSIONS "${${_PYTHON_PREFIX}_FIND_VERSION_MAJOR}.${${_PYTHON_PREFIX}_FIND_VERSION_MINOR}")
+    set (_${_PYTHON_PREFIX}_FIND_VERSIONS ${${_PYTHON_PREFIX}_FIND_VERSION_MAJOR}.${${_PYTHON_PREFIX}_FIND_VERSION_MINOR})
   else()
     unset (_${_PYTHON_PREFIX}_FIND_VERSIONS)
     # add all compatible versions
     foreach (_${_PYTHON_PREFIX}_VERSION IN LISTS _${_PYTHON_PREFIX}_VERSIONS)
       if (_${_PYTHON_PREFIX}_VERSION VERSION_GREATER_EQUAL "${${_PYTHON_PREFIX}_FIND_VERSION_MAJOR}.${${_PYTHON_PREFIX}_FIND_VERSION_MINOR}")
-        list (APPEND _${_PYTHON_PREFIX}_FIND_VERSIONS "${_${_PYTHON_PREFIX}_VERSION}")
+        list (APPEND _${_PYTHON_PREFIX}_FIND_VERSIONS ${_${_PYTHON_PREFIX}_VERSION})
       endif()
     endforeach()
   endif()
@@ -855,6 +1093,7 @@
 unset (${_PYTHON_PREFIX}_SOABI)
 
 # Define lookup strategy
+cmake_policy (GET CMP0094 _${_PYTHON_PREFIX}_LOOKUP_POLICY)
 if (_${_PYTHON_PREFIX}_LOOKUP_POLICY STREQUAL "NEW")
   set (_${_PYTHON_PREFIX}_FIND_STRATEGY "LOCATION")
 else()
@@ -881,15 +1120,75 @@
 endif()
 
 # IronPython support
+unset (_${_PYTHON_PREFIX}_IRON_PYTHON_INTERPRETER_NAMES)
+unset (_${_PYTHON_PREFIX}_IRON_PYTHON_COMPILER_NAMES)
+unset (_${_PYTHON_PREFIX}_IRON_PYTHON_COMPILER_ARCH_FLAGS)
 if (CMAKE_SIZEOF_VOID_P)
-  # In this case, search only for 64bit or 32bit
-  math (EXPR _${_PYTHON_PREFIX}_ARCH "${CMAKE_SIZEOF_VOID_P} * 8")
-  set (_${_PYTHON_PREFIX}_IRON_PYTHON_NAMES ipy${_${_PYTHON_PREFIX}_ARCH} ipy)
-else()
-  # architecture unknown, search for natural interpreter
-  set (_${_PYTHON_PREFIX}_IRON_PYTHON_NAMES ipy)
+  if (_${_PYTHON_PREFIX}_ARCH EQUAL "32")
+    set (_${_PYTHON_PREFIX}_IRON_PYTHON_COMPILER_ARCH_FLAGS "/platform:x86")
+  else()
+    set (_${_PYTHON_PREFIX}_IRON_PYTHON_COMPILER_ARCH_FLAGS "/platform:x64")
+  endif()
 endif()
-set (_${_PYTHON_PREFIX}_IRON_PYTHON_PATH_SUFFIXES net45 net40)
+if (NOT CMAKE_SYSTEM_NAME STREQUAL "Linux")
+  # Do not use wrapper script on Linux because it is buggy: -c interpreter option cannot be used
+  list (APPEND _${_PYTHON_PREFIX}_IRON_PYTHON_INTERPRETER_NAMES "ipy${_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR}" "ipy64" "ipy32" "ipy")
+  list (APPEND _${_PYTHON_PREFIX}_IRON_PYTHON_COMPILER_NAMES "ipyc")
+endif()
+list (APPEND _${_PYTHON_PREFIX}_IRON_PYTHON_INTERPRETER_NAMES "ipy.exe")
+list (APPEND _${_PYTHON_PREFIX}_IRON_PYTHON_COMPILER_NAMES "ipyc.exe")
+set (_${_PYTHON_PREFIX}_IRON_PYTHON_PATH_SUFFIXES net45 net40 bin)
+
+# PyPy support
+if (_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR EQUAL "3")
+  set (_${_PYTHON_PREFIX}_PYPY_NAMES pypy3)
+  set (_${_PYTHON_PREFIX}_PYPY_LIB_NAMES pypy3-c)
+  if (WIN32)
+    # special name for runtime part
+    list (APPEND _${_PYTHON_PREFIX}_PYPY_LIB_NAMES libpypy3-c)
+  endif()
+  set (_${_PYTHON_PREFIX}_PYPY_INCLUDE_PATH_SUFFIXES lib/pypy3)
+else()
+  set (_${_PYTHON_PREFIX}_PYPY_NAMES pypy)
+  set (_${_PYTHON_PREFIX}_PYPY_LIB_NAMES pypy-c)
+  if (WIN32)
+    # special name for runtime part
+    list (APPEND _${_PYTHON_PREFIX}_PYPY_LIB_NAMES libpypy-c)
+  endif()
+  set (_${_PYTHON_PREFIX}_PYPY_INCLUDE_PATH_SUFFIXES lib/pypy)
+endif()
+set (_${_PYTHON_PREFIX}_PYPY_EXECUTABLE_PATH_SUFFIXES bin)
+set (_${_PYTHON_PREFIX}_PYPY_LIBRARY_PATH_SUFFIXES lib libs bin)
+list (APPEND _${_PYTHON_PREFIX}_PYPY_INCLUDE_PATH_SUFFIXES include)
+
+# Python Implementations handling
+unset (_${_PYTHON_PREFIX}_FIND_IMPLEMENTATIONS)
+if (DEFINED ${_PYTHON_PREFIX}_FIND_IMPLEMENTATIONS)
+  foreach (_${_PYTHON_PREFIX}_IMPLEMENTATION IN LISTS ${_PYTHON_PREFIX}_FIND_IMPLEMENTATIONS)
+    if (NOT _${_PYTHON_PREFIX}_IMPLEMENTATION MATCHES "^(CPython|IronPython|PyPy)$")
+      message (AUTHOR_WARNING "Find${_PYTHON_PREFIX}: ${_${_PYTHON_PREFIX}_IMPLEMENTATION}: invalid value for '${_PYTHON_PREFIX}_FIND_IMPLEMENTATIONS'. 'CPython', 'IronPython' or 'PyPy' expected. Value will be ignored.")
+    else()
+      list (APPEND _${_PYTHON_PREFIX}_FIND_IMPLEMENTATIONS ${_${_PYTHON_PREFIX}_IMPLEMENTATION})
+    endif()
+  endforeach()
+else()
+  if (WIN32)
+    set (_${_PYTHON_PREFIX}_FIND_IMPLEMENTATIONS CPython IronPython)
+  else()
+    set (_${_PYTHON_PREFIX}_FIND_IMPLEMENTATIONS CPython)
+  endif()
+endif()
+
+# compute list of names for header file
+unset (_${_PYTHON_PREFIX}_INCLUDE_NAMES)
+foreach (_${_PYTHON_PREFIX}_IMPLEMENTATION IN LISTS _${_PYTHON_PREFIX}_FIND_IMPLEMENTATIONS)
+  if (_${_PYTHON_PREFIX}_IMPLEMENTATION STREQUAL "CPython")
+    list (APPEND _${_PYTHON_PREFIX}_INCLUDE_NAMES "Python.h")
+  elseif (_${_PYTHON_PREFIX}_IMPLEMENTATION STREQUAL "PyPy")
+    list (APPEND _${_PYTHON_PREFIX}_INCLUDE_NAMES "PyPy.h")
+  endif()
+endforeach()
+
 
 # Apple frameworks handling
 _python_find_frameworks ()
@@ -961,7 +1260,7 @@
 
 # Compute search signature
 # This signature will be used to check validity of cached variables on new search
-set (_${_PYTHON_PREFIX}_SIGNATURE "${${_PYTHON_PREFIX}_ROOT_DIR}:${_${_PYTHON_PREFIX}_FIND_STRATEGY}:${${_PYTHON_PREFIX}_FIND_VIRTUALENV}")
+set (_${_PYTHON_PREFIX}_SIGNATURE "${${_PYTHON_PREFIX}_ROOT_DIR}:${_${_PYTHON_PREFIX}_FIND_IMPLEMENTATIONS}:${_${_PYTHON_PREFIX}_FIND_STRATEGY}:${${_PYTHON_PREFIX}_FIND_VIRTUALENV}")
 if (NOT WIN32)
   string (APPEND _${_PYTHON_PREFIX}_SIGNATURE ":${${_PYTHON_PREFIX}_USE_STATIC_LIBS}:")
 endif()
@@ -972,6 +1271,64 @@
   string (APPEND _${_PYTHON_PREFIX}_SIGNATURE ":${_${_PYTHON_PREFIX}_FIND_REGISTRY}")
 endif()
 
+function (_PYTHON_CHECK_DEVELOPMENT_SIGNATURE module)
+  if ("Development.${module}" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS)
+    string (TOUPPER "${module}" id)
+    set (signature "${_${_PYTHON_PREFIX}_SIGNATURE}:")
+    if ("LIBRARY" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_${id}_ARTIFACTS)
+      list (APPEND signature "${_${_PYTHON_PREFIX}_LIBRARY_RELEASE}:")
+    endif()
+    if ("INCLUDE_DIR" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_${id}_ARTIFACTS)
+      list (APPEND signature "${_${_PYTHON_PREFIX}_INCLUDE_DIR}:")
+    endif()
+    string (MD5 signature "${signature}")
+    if (signature STREQUAL _${_PYTHON_PREFIX}_DEVELOPMENT_${id}_SIGNATURE)
+      if ("LIBRARY" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_${id}_ARTIFACTS)
+        _python_validate_library (${${_PYTHON_PREFIX}_FIND_VERSION}
+                                  ${_${_PYTHON_PREFIX}_FIND_VERSION_EXACT}
+                                  CHECK_EXISTS)
+      endif()
+      if ("INCLUDE_DIR" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_${id}_ARTIFACTS)
+        _python_validate_include_dir (${${_PYTHON_PREFIX}_FIND_VERSION}
+                                      ${_${_PYTHON_PREFIX}_FIND_VERSION_EXACT}
+                                      CHECK_EXISTS)
+      endif()
+    else()
+      if ("LIBRARY" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_${id}_ARTIFACTS)
+        unset (_${_PYTHON_PREFIX}_LIBRARY_RELEASE CACHE)
+        unset (_${_PYTHON_PREFIX}_LIBRARY_DEBUG CACHE)
+      endif()
+      if ("INCLUDE_DIR" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_${id}_ARTIFACTS)
+        unset (_${_PYTHON_PREFIX}_INCLUDE_DIR CACHE)
+      endif()
+    endif()
+    if (("LIBRARY" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_${id}_ARTIFACTS
+          AND NOT _${_PYTHON_PREFIX}_LIBRARY_RELEASE)
+        OR ("INCLUDE_DIR" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_${id}_ARTIFACTS
+          AND NOT _${_PYTHON_PREFIX}_INCLUDE_DIR))
+      unset (_${_PYTHON_PREFIX}_CONFIG CACHE)
+      unset (_${_PYTHON_PREFIX}_DEVELOPMENT_${id}_SIGNATURE CACHE)
+    endif()
+  endif()
+endfunction()
+
+function (_PYTHON_COMPUTE_DEVELOPMENT_SIGNATURE module)
+  string (TOUPPER "${module}" id)
+  if (${_PYTHON_PREFIX}_Development.${module}_FOUND)
+    set (signature "${_${_PYTHON_PREFIX}_SIGNATURE}:")
+    if ("LIBRARY" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_${id}_ARTIFACTS)
+      list (APPEND signature "${_${_PYTHON_PREFIX}_LIBRARY_RELEASE}:")
+    endif()
+    if ("INCLUDE_DIR" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_${id}_ARTIFACTS)
+      list (APPEND signature "${_${_PYTHON_PREFIX}_INCLUDE_DIR}:")
+    endif()
+    string (MD5 signature "${signature}")
+    set (_${_PYTHON_PREFIX}_DEVELOPMENT_${id}_SIGNATURE "${signature}" CACHE INTERNAL "")
+  else()
+    unset (_${_PYTHON_PREFIX}_DEVELOPMENT_${id}_SIGNATURE CACHE)
+  endif()
+endfunction()
+
 
 unset (_${_PYTHON_PREFIX}_REQUIRED_VARS)
 unset (_${_PYTHON_PREFIX}_CACHED_VARS)
@@ -981,6 +1338,15 @@
 unset (_${_PYTHON_PREFIX}_NumPy_REASON_FAILURE)
 
 
+# preamble
+## For IronPython on platforms other than Windows, search for the .Net interpreter
+if ("IronPython" IN_LIST _${_PYTHON_PREFIX}_FIND_IMPLEMENTATIONS
+    AND NOT WIN32)
+  find_program (${_PYTHON_PREFIX}_DOTNET_LAUNCHER
+                NAMES "mono")
+endif()
+
+
 # first step, search for the interpreter
 if ("Interpreter" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS)
   list (APPEND _${_PYTHON_PREFIX}_CACHED_VARS _${_PYTHON_PREFIX}_EXECUTABLE
@@ -1019,25 +1385,14 @@
     set (_${_PYTHON_PREFIX}_HINTS "${${_PYTHON_PREFIX}_ROOT_DIR}" ENV ${_PYTHON_PREFIX}_ROOT_DIR)
 
     if (_${_PYTHON_PREFIX}_FIND_STRATEGY STREQUAL "LOCATION")
-      unset (_${_PYTHON_PREFIX}_NAMES)
-      unset (_${_PYTHON_PREFIX}_FRAMEWORK_PATHS)
-      unset (_${_PYTHON_PREFIX}_REGISTRY_PATHS)
+      # build all executable names
+      _python_get_names (_${_PYTHON_PREFIX}_NAMES VERSION ${_${_PYTHON_PREFIX}_FIND_VERSIONS} POSIX INTERPRETER)
+      _python_get_path_suffixes (_${_PYTHON_PREFIX}_PATH_SUFFIXES VERSION ${_${_PYTHON_PREFIX}_FIND_VERSIONS} INTERPRETER)
 
-      foreach (_${_PYTHON_PREFIX}_VERSION IN LISTS _${_PYTHON_PREFIX}_FIND_VERSIONS)
-        # build all executable names
-        _python_get_names (_${_PYTHON_PREFIX}_VERSION_NAMES VERSION ${_${_PYTHON_PREFIX}_VERSION} POSIX EXECUTABLE)
-        list (APPEND _${_PYTHON_PREFIX}_NAMES ${_${_PYTHON_PREFIX}_VERSION_NAMES})
-
-        # Framework Paths
-        _python_get_frameworks (_${_PYTHON_PREFIX}_VERSION_PATHS ${_${_PYTHON_PREFIX}_VERSION})
-        list (APPEND _${_PYTHON_PREFIX}_FRAMEWORK_PATHS ${_${_PYTHON_PREFIX}_VERSION_PATHS})
-
-        # Registry Paths
-        _python_get_registries (_${_PYTHON_PREFIX}_VERSION_PATHS ${_${_PYTHON_PREFIX}_VERSION})
-        list (APPEND _${_PYTHON_PREFIX}_REGISTRY_PATHS ${_${_PYTHON_PREFIX}_VERSION_PATHS}
-                     [HKEY_LOCAL_MACHINE\\SOFTWARE\\IronPython\\${_${_PYTHON_PREFIX}_VERSION}\\InstallPath])
-      endforeach()
-      list (APPEND _${_PYTHON_PREFIX}_NAMES python${_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR} python)
+      # Framework Paths
+      _python_get_frameworks (_${_PYTHON_PREFIX}_FRAMEWORK_PATHS VERSION ${_${_PYTHON_PREFIX}_FIND_VERSIONS})
+      # Registry Paths
+      _python_get_registries (_${_PYTHON_PREFIX}_REGISTRY_PATHS VERSION ${_${_PYTHON_PREFIX}_FIND_VERSIONS})
 
       while (TRUE)
         # Virtual environments handling
@@ -1047,7 +1402,7 @@
                         NAMES_PER_DIR
                         HINTS ${_${_PYTHON_PREFIX}_HINTS}
                         PATHS ENV VIRTUAL_ENV ENV CONDA_PREFIX
-                        PATH_SUFFIXES bin Scripts
+                        PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES}
                         NO_CMAKE_PATH
                         NO_CMAKE_ENVIRONMENT_PATH
                         NO_SYSTEM_ENVIRONMENT_PATH
@@ -1069,7 +1424,7 @@
                         NAMES_PER_DIR
                         HINTS ${_${_PYTHON_PREFIX}_HINTS}
                         PATHS ${_${_PYTHON_PREFIX}_FRAMEWORK_PATHS}
-                        PATH_SUFFIXES bin
+                        PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES}
                         NO_CMAKE_PATH
                         NO_CMAKE_ENVIRONMENT_PATH
                         NO_SYSTEM_ENVIRONMENT_PATH
@@ -1083,11 +1438,10 @@
         if (CMAKE_HOST_WIN32 AND _${_PYTHON_PREFIX}_FIND_REGISTRY STREQUAL "FIRST")
           find_program (_${_PYTHON_PREFIX}_EXECUTABLE
                         NAMES ${_${_PYTHON_PREFIX}_NAMES}
-                              ${_${_PYTHON_PREFIX}_IRON_PYTHON_NAMES}
                         NAMES_PER_DIR
                         HINTS ${_${_PYTHON_PREFIX}_HINTS}
                         PATHS ${_${_PYTHON_PREFIX}_REGISTRY_PATHS}
-                        PATH_SUFFIXES bin ${_${_PYTHON_PREFIX}_IRON_PYTHON_PATH_SUFFIXES}
+                        PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES}
                         NO_SYSTEM_ENVIRONMENT_PATH
                         NO_CMAKE_SYSTEM_PATH)
           _python_validate_interpreter (${${_PYTHON_PREFIX}_FIND_VERSION} ${_${_PYTHON_PREFIX}_FIND_VERSION_EXACT})
@@ -1099,10 +1453,9 @@
         # try using HINTS
         find_program (_${_PYTHON_PREFIX}_EXECUTABLE
                       NAMES ${_${_PYTHON_PREFIX}_NAMES}
-                            ${_${_PYTHON_PREFIX}_IRON_PYTHON_NAMES}
                       NAMES_PER_DIR
                       HINTS ${_${_PYTHON_PREFIX}_HINTS}
-                      PATH_SUFFIXES bin ${_${_PYTHON_PREFIX}_IRON_PYTHON_PATH_SUFFIXES}
+                      PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES}
                       NO_SYSTEM_ENVIRONMENT_PATH
                       NO_CMAKE_SYSTEM_PATH)
         _python_validate_interpreter (${${_PYTHON_PREFIX}_FIND_VERSION} ${_${_PYTHON_PREFIX}_FIND_VERSION_EXACT})
@@ -1112,9 +1465,8 @@
         # try using standard paths
         find_program (_${_PYTHON_PREFIX}_EXECUTABLE
                       NAMES ${_${_PYTHON_PREFIX}_NAMES}
-                            ${_${_PYTHON_PREFIX}_IRON_PYTHON_NAMES}
                       NAMES_PER_DIR
-                      PATH_SUFFIXES bin ${_${_PYTHON_PREFIX}_IRON_PYTHON_PATH_SUFFIXES})
+                      PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES})
         _python_validate_interpreter (${${_PYTHON_PREFIX}_FIND_VERSION} ${_${_PYTHON_PREFIX}_FIND_VERSION_EXACT})
         if (_${_PYTHON_PREFIX}_EXECUTABLE)
           break()
@@ -1126,7 +1478,7 @@
                         NAMES ${_${_PYTHON_PREFIX}_NAMES}
                         NAMES_PER_DIR
                         PATHS ${_${_PYTHON_PREFIX}_FRAMEWORK_PATHS}
-                        PATH_SUFFIXES bin
+                        PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES}
                         NO_DEFAULT_PATH)
           _python_validate_interpreter (${${_PYTHON_PREFIX}_FIND_VERSION} ${_${_PYTHON_PREFIX}_FIND_VERSION_EXACT})
           if (_${_PYTHON_PREFIX}_EXECUTABLE)
@@ -1137,10 +1489,9 @@
         if (CMAKE_HOST_WIN32 AND _${_PYTHON_PREFIX}_FIND_REGISTRY STREQUAL "LAST")
           find_program (_${_PYTHON_PREFIX}_EXECUTABLE
                         NAMES ${_${_PYTHON_PREFIX}_NAMES}
-                              ${_${_PYTHON_PREFIX}_IRON_PYTHON_NAMES}
                         NAMES_PER_DIR
                         PATHS ${_${_PYTHON_PREFIX}_REGISTRY_PATHS}
-                        PATH_SUFFIXES bin ${_${_PYTHON_PREFIX}_IRON_PYTHON_PATH_SUFFIXES}
+                        PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES}
                         NO_DEFAULT_PATH)
           _python_validate_interpreter (${${_PYTHON_PREFIX}_FIND_VERSION} ${_${_PYTHON_PREFIX}_FIND_VERSION_EXACT})
           if (_${_PYTHON_PREFIX}_EXECUTABLE)
@@ -1153,12 +1504,11 @@
     else()
       # look-up for various versions and locations
       foreach (_${_PYTHON_PREFIX}_VERSION IN LISTS _${_PYTHON_PREFIX}_FIND_VERSIONS)
-        _python_get_names (_${_PYTHON_PREFIX}_NAMES VERSION ${_${_PYTHON_PREFIX}_VERSION} POSIX EXECUTABLE)
-        list (APPEND _${_PYTHON_PREFIX}_NAMES python${_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR}
-                                              python)
+        _python_get_names (_${_PYTHON_PREFIX}_NAMES VERSION ${_${_PYTHON_PREFIX}_VERSION} POSIX INTERPRETER)
+        _python_get_path_suffixes (_${_PYTHON_PREFIX}_PATH_SUFFIXES VERSION ${_${_PYTHON_PREFIX}_VERSION} INTERPRETER)
 
-        _python_get_frameworks (_${_PYTHON_PREFIX}_FRAMEWORK_PATHS ${_${_PYTHON_PREFIX}_VERSION})
-        _python_get_registries (_${_PYTHON_PREFIX}_REGISTRY_PATHS ${_${_PYTHON_PREFIX}_VERSION})
+        _python_get_frameworks (_${_PYTHON_PREFIX}_FRAMEWORK_PATHS VERSION ${_${_PYTHON_PREFIX}_VERSION})
+        _python_get_registries (_${_PYTHON_PREFIX}_REGISTRY_PATHS VERSION ${_${_PYTHON_PREFIX}_VERSION})
 
         # Virtual environments handling
         if (_${_PYTHON_PREFIX}_FIND_VIRTUALENV MATCHES "^(FIRST|ONLY)$")
@@ -1167,7 +1517,7 @@
                         NAMES_PER_DIR
                         HINTS ${_${_PYTHON_PREFIX}_HINTS}
                         PATHS ENV VIRTUAL_ENV ENV CONDA_PREFIX
-                        PATH_SUFFIXES bin Scripts
+                        PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES}
                         NO_CMAKE_PATH
                         NO_CMAKE_ENVIRONMENT_PATH
                         NO_SYSTEM_ENVIRONMENT_PATH
@@ -1188,7 +1538,7 @@
                         NAMES_PER_DIR
                         HINTS ${_${_PYTHON_PREFIX}_HINTS}
                         PATHS ${_${_PYTHON_PREFIX}_FRAMEWORK_PATHS}
-                        PATH_SUFFIXES bin
+                        PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES}
                         NO_CMAKE_PATH
                         NO_CMAKE_ENVIRONMENT_PATH
                         NO_SYSTEM_ENVIRONMENT_PATH
@@ -1199,12 +1549,10 @@
         if (CMAKE_HOST_WIN32 AND _${_PYTHON_PREFIX}_FIND_REGISTRY STREQUAL "FIRST")
           find_program (_${_PYTHON_PREFIX}_EXECUTABLE
                         NAMES ${_${_PYTHON_PREFIX}_NAMES}
-                              ${_${_PYTHON_PREFIX}_IRON_PYTHON_NAMES}
                         NAMES_PER_DIR
                         HINTS ${_${_PYTHON_PREFIX}_HINTS}
                         PATHS ${_${_PYTHON_PREFIX}_REGISTRY_PATHS}
-                              [HKEY_LOCAL_MACHINE\\SOFTWARE\\IronPython\\${_${_PYTHON_PREFIX}_VERSION}\\InstallPath]
-                        PATH_SUFFIXES bin ${_${_PYTHON_PREFIX}_IRON_PYTHON_PATH_SUFFIXES}
+                        PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES}
                         NO_SYSTEM_ENVIRONMENT_PATH
                         NO_CMAKE_SYSTEM_PATH)
         endif()
@@ -1217,10 +1565,9 @@
         # try using HINTS
         find_program (_${_PYTHON_PREFIX}_EXECUTABLE
                       NAMES ${_${_PYTHON_PREFIX}_NAMES}
-                            ${_${_PYTHON_PREFIX}_IRON_PYTHON_NAMES}
                       NAMES_PER_DIR
                       HINTS ${_${_PYTHON_PREFIX}_HINTS}
-                      PATH_SUFFIXES bin ${_${_PYTHON_PREFIX}_IRON_PYTHON_PATH_SUFFIXES}
+                      PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES}
                       NO_SYSTEM_ENVIRONMENT_PATH
                       NO_CMAKE_SYSTEM_PATH)
         _python_validate_interpreter (${_${_PYTHON_PREFIX}_VERSION} EXACT)
@@ -1233,15 +1580,9 @@
         # For example, typical systems have 'python' for version 2.* and 'python3'
         # for version 3.*. So looking for names per dir will find, potentially,
         # systematically 'python' (i.e. version 2) even if version 3 is searched.
-        if (CMAKE_HOST_WIN32)
-          find_program (_${_PYTHON_PREFIX}_EXECUTABLE
-                        NAMES ${_${_PYTHON_PREFIX}_NAMES}
-                              python
-                              ${_${_PYTHON_PREFIX}_IRON_PYTHON_NAMES})
-        else()
-          find_program (_${_PYTHON_PREFIX}_EXECUTABLE
-                        NAMES ${_${_PYTHON_PREFIX}_NAMES})
-        endif()
+        find_program (_${_PYTHON_PREFIX}_EXECUTABLE
+                      NAMES ${_${_PYTHON_PREFIX}_NAMES}
+                      PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES})
         _python_validate_interpreter (${_${_PYTHON_PREFIX}_VERSION} EXACT)
         if (_${_PYTHON_PREFIX}_EXECUTABLE)
           break()
@@ -1253,7 +1594,7 @@
                         NAMES ${_${_PYTHON_PREFIX}_NAMES}
                         NAMES_PER_DIR
                         PATHS ${_${_PYTHON_PREFIX}_FRAMEWORK_PATHS}
-                        PATH_SUFFIXES bin
+                        PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES}
                         NO_DEFAULT_PATH)
         endif()
 
@@ -1261,11 +1602,9 @@
         if (CMAKE_HOST_WIN32 AND _${_PYTHON_PREFIX}_FIND_REGISTRY STREQUAL "LAST")
           find_program (_${_PYTHON_PREFIX}_EXECUTABLE
                         NAMES ${_${_PYTHON_PREFIX}_NAMES}
-                              ${_${_PYTHON_PREFIX}_IRON_PYTHON_NAMES}
                         NAMES_PER_DIR
                         PATHS ${_${_PYTHON_PREFIX}_REGISTRY_PATHS}
-                              [HKEY_LOCAL_MACHINE\\SOFTWARE\\IronPython\\${_${_PYTHON_PREFIX}_VERSION}\\InstallPath]
-                        PATH_SUFFIXES bin ${_${_PYTHON_PREFIX}_IRON_PYTHON_PATH_SUFFIXES}
+                        PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES}
                         NO_DEFAULT_PATH)
         endif()
 
@@ -1283,20 +1622,20 @@
         # For example, typical systems have 'python' for version 2.* and 'python3'
         # for version 3.*. So looking for names per dir will find, potentially,
         # systematically 'python' (i.e. version 2) even if version 3 is searched.
+        _python_get_names (_${_PYTHON_PREFIX}_NAMES POSIX INTERPRETER)
         find_program (_${_PYTHON_PREFIX}_EXECUTABLE
-                      NAMES python${_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR}
-                            python
-                            ${_${_PYTHON_PREFIX}_IRON_PYTHON_NAMES})
+                      NAMES ${_${_PYTHON_PREFIX}_NAMES})
         _python_validate_interpreter ()
       endif()
     endif()
   endif()
 
   set (${_PYTHON_PREFIX}_EXECUTABLE "${_${_PYTHON_PREFIX}_EXECUTABLE}")
+  _python_get_launcher (_${_PYTHON_PREFIX}_INTERPRETER_LAUNCHER INTERPRETER)
 
   # retrieve exact version of executable found
   if (_${_PYTHON_PREFIX}_EXECUTABLE)
-    execute_process (COMMAND "${_${_PYTHON_PREFIX}_EXECUTABLE}" -c
+    execute_process (COMMAND ${_${_PYTHON_PREFIX}_INTERPRETER_LAUNCHER} "${_${_PYTHON_PREFIX}_EXECUTABLE}" -c
                              "import sys; sys.stdout.write('.'.join([str(x) for x in sys.version_info[:3]]))"
                      RESULT_VARIABLE _${_PYTHON_PREFIX}_RESULT
                      OUTPUT_VARIABLE ${_PYTHON_PREFIX}_VERSION
@@ -1343,7 +1682,8 @@
 
         # Use interpreter version and ABI for future searches to ensure consistency
         set (_${_PYTHON_PREFIX}_FIND_VERSIONS ${${_PYTHON_PREFIX}_VERSION_MAJOR}.${${_PYTHON_PREFIX}_VERSION_MINOR})
-        execute_process (COMMAND "${_${_PYTHON_PREFIX}_EXECUTABLE}" -c "import sys; sys.stdout.write(sys.abiflags)"
+        execute_process (COMMAND ${_${_PYTHON_PREFIX}_INTERPRETR_LAUNCHER} "${_${_PYTHON_PREFIX}_EXECUTABLE}" -c
+                                 "import sys; sys.stdout.write(sys.abiflags)"
                          RESULT_VARIABLE _${_PYTHON_PREFIX}_RESULT
                          OUTPUT_VARIABLE _${_PYTHON_PREFIX}_ABIFLAGS
                          ERROR_QUIET
@@ -1355,13 +1695,16 @@
       endif()
 
       if (${_PYTHON_PREFIX}_Interpreter_FOUND)
+        unset (_${_PYTHON_PREFIX}_Interpreter_REASON_FAILURE)
+
         # compute and save interpreter signature
         string (MD5 __${_PYTHON_PREFIX}_INTERPRETER_SIGNATURE "${_${_PYTHON_PREFIX}_SIGNATURE}:${_${_PYTHON_PREFIX}_EXECUTABLE}")
         set (_${_PYTHON_PREFIX}_INTERPRETER_SIGNATURE "${__${_PYTHON_PREFIX}_INTERPRETER_SIGNATURE}" CACHE INTERNAL "")
 
         if (NOT CMAKE_SIZEOF_VOID_P)
           # determine interpreter architecture
-          execute_process (COMMAND "${_${_PYTHON_PREFIX}_EXECUTABLE}" -c "import sys; print(sys.maxsize > 2**32)"
+          execute_process (COMMAND ${_${_PYTHON_PREFIX}_INTERPRETER_LAUNCHER} "${_${_PYTHON_PREFIX}_EXECUTABLE}" -c
+                                   "import sys; sys.stdout.write(str(sys.maxsize > 2**32))"
                            RESULT_VARIABLE _${_PYTHON_PREFIX}_RESULT
                            OUTPUT_VARIABLE ${_PYTHON_PREFIX}_IS64BIT
                            ERROR_VARIABLE ${_PYTHON_PREFIX}_IS64BIT)
@@ -1377,7 +1720,7 @@
         endif()
 
         # retrieve interpreter identity
-        execute_process (COMMAND "${_${_PYTHON_PREFIX}_EXECUTABLE}" -V
+        execute_process (COMMAND ${_${_PYTHON_PREFIX}_INTERPRETER_LAUNCHER} "${_${_PYTHON_PREFIX}_EXECUTABLE}" -V
                          RESULT_VARIABLE _${_PYTHON_PREFIX}_RESULT
                          OUTPUT_VARIABLE ${_PYTHON_PREFIX}_INTERPRETER_ID
                          ERROR_VARIABLE ${_PYTHON_PREFIX}_INTERPRETER_ID)
@@ -1386,11 +1729,15 @@
             set (${_PYTHON_PREFIX}_INTERPRETER_ID "Anaconda")
           elseif (${_PYTHON_PREFIX}_INTERPRETER_ID MATCHES "Enthought")
             set (${_PYTHON_PREFIX}_INTERPRETER_ID "Canopy")
+          elseif (${_PYTHON_PREFIX}_INTERPRETER_ID MATCHES "PyPy ([0-9.]+)")
+            set (${_PYTHON_PREFIX}_INTERPRETER_ID "PyPy")
+            set  (${_PYTHON_PREFIX}_PyPy_VERSION "${CMAKE_MATCH_1}")
           else()
             string (REGEX REPLACE "^([^ ]+).*" "\\1" ${_PYTHON_PREFIX}_INTERPRETER_ID "${${_PYTHON_PREFIX}_INTERPRETER_ID}")
             if (${_PYTHON_PREFIX}_INTERPRETER_ID STREQUAL "Python")
               # try to get a more precise ID
-              execute_process (COMMAND "${_${_PYTHON_PREFIX}_EXECUTABLE}" -c "import sys; print(sys.copyright)"
+              execute_process (COMMAND ${_${_PYTHON_PREFIX}_INTERPRETER_LAUNCHER} "${_${_PYTHON_PREFIX}_EXECUTABLE}" -c
+                                       "import sys; sys.stdout.write(sys.copyright)"
                                RESULT_VARIABLE _${_PYTHON_PREFIX}_RESULT
                                OUTPUT_VARIABLE ${_PYTHON_PREFIX}_COPYRIGHT
                                ERROR_QUIET)
@@ -1404,10 +1751,11 @@
         endif()
 
         # retrieve various package installation directories
-        execute_process (COMMAND "${_${_PYTHON_PREFIX}_EXECUTABLE}" -c "import sys; from distutils import sysconfig;sys.stdout.write(';'.join([sysconfig.get_python_lib(plat_specific=False,standard_lib=True),sysconfig.get_python_lib(plat_specific=True,standard_lib=True),sysconfig.get_python_lib(plat_specific=False,standard_lib=False),sysconfig.get_python_lib(plat_specific=True,standard_lib=False)]))"
-                        RESULT_VARIABLE _${_PYTHON_PREFIX}_RESULT
-                        OUTPUT_VARIABLE _${_PYTHON_PREFIX}_LIBPATHS
-                        ERROR_QUIET)
+        execute_process (COMMAND ${_${_PYTHON_PREFIX}_INTERPRETER_LAUNCHER} "${_${_PYTHON_PREFIX}_EXECUTABLE}" -c
+                                 "import sys\ntry:\n   from distutils import sysconfig\n   sys.stdout.write(';'.join([sysconfig.get_python_lib(plat_specific=False,standard_lib=True),sysconfig.get_python_lib(plat_specific=True,standard_lib=True),sysconfig.get_python_lib(plat_specific=False,standard_lib=False),sysconfig.get_python_lib(plat_specific=True,standard_lib=False)]))\nexcept Exception:\n   import sysconfig\n   sys.stdout.write(';'.join([sysconfig.get_path('stdlib'),sysconfig.get_path('platstdlib'),sysconfig.get_path('purelib'),sysconfig.get_path('platlib')]))"
+                         RESULT_VARIABLE _${_PYTHON_PREFIX}_RESULT
+                         OUTPUT_VARIABLE _${_PYTHON_PREFIX}_LIBPATHS
+                         ERROR_QUIET)
         if (NOT _${_PYTHON_PREFIX}_RESULT)
           list (GET _${_PYTHON_PREFIX}_LIBPATHS 0 ${_PYTHON_PREFIX}_STDLIB)
           list (GET _${_PYTHON_PREFIX}_LIBPATHS 1 ${_PYTHON_PREFIX}_STDARCH)
@@ -1434,6 +1782,10 @@
     endif()
   endif()
 
+  if (${_PYTHON_PREFIX}_ARTIFACTS_INTERACTIVE)
+    set (${_PYTHON_PREFIX}_EXECUTABLE "${_${_PYTHON_PREFIX}_EXECUTABLE}" CACHE FILEPATH "${_PYTHON_PREFIX} Interpreter")
+  endif()
+
   _python_mark_as_internal (_${_PYTHON_PREFIX}_EXECUTABLE
                             _${_PYTHON_PREFIX}_INTERPRETER_PROPERTIES
                             _${_PYTHON_PREFIX}_INTERPRETER_SIGNATURE)
@@ -1447,7 +1799,10 @@
     list (APPEND _${_PYTHON_PREFIX}_REQUIRED_VARS ${_PYTHON_PREFIX}_COMPILER)
   endif()
 
-  if (DEFINED ${_PYTHON_PREFIX}_COMPILER
+  if (NOT "IronPython" IN_LIST _${_PYTHON_PREFIX}_FIND_IMPLEMENTATIONS)
+    unset (_${_PYTHON_PREFIX}_COMPILER CACHE)
+    unset (_${_PYTHON_PREFIX}_COMPILER_SIGNATURE CACHE)
+  elseif (DEFINED ${_PYTHON_PREFIX}_COMPILER
       AND IS_ABSOLUTE "${${_PYTHON_PREFIX}_COMPILER}")
     set (_${_PYTHON_PREFIX}_COMPILER "${${_PYTHON_PREFIX}_COMPILER}" CACHE INTERNAL "")
   elseif (DEFINED _${_PYTHON_PREFIX}_COMPILER)
@@ -1466,7 +1821,8 @@
     endif()
   endif()
 
-  if (NOT _${_PYTHON_PREFIX}_COMPILER)
+  if ("IronPython" IN_LIST _${_PYTHON_PREFIX}_FIND_IMPLEMENTATIONS
+      AND NOT _${_PYTHON_PREFIX}_COMPILER)
     # IronPython specific artifacts
     # If IronPython interpreter is found, use its path
     unset (_${_PYTHON_PREFIX}_IRON_ROOT)
@@ -1475,21 +1831,49 @@
     endif()
 
     if (_${_PYTHON_PREFIX}_FIND_STRATEGY STREQUAL "LOCATION")
-      set (_${_PYTHON_PREFIX}_REGISTRY_PATHS)
+      _python_get_names (_${_PYTHON_PREFIX}_COMPILER_NAMES
+                         IMPLEMENTATIONS IronPython
+                         VERSION ${_${_PYTHON_PREFIX}_FIND_VERSIONS}
+                         COMPILER)
 
-      foreach (_${_PYTHON_PREFIX}_VERSION IN LISTS _${_PYTHON_PREFIX}_FIND_VERSIONS)
-        # Registry Paths
-        list (APPEND _${_PYTHON_PREFIX}_REGISTRY_PATHS
-                     [HKEY_LOCAL_MACHINE\\SOFTWARE\\IronPython\\${_${_PYTHON_PREFIX}_VERSION}\\InstallPath])
-      endforeach()
+      _python_get_path_suffixes (_${_PYTHON_PREFIX}_PATH_SUFFIXES
+                                 IMPLEMENTATIONS IronPython
+                                 VERSION ${_${_PYTHON_PREFIX}_FIND_VERSIONS}
+                                 COMPILER)
+
+      _python_get_frameworks (_${_PYTHON_PREFIX}_FRAMEWORK_PATHS
+                              IMPLEMENTATIONS IronPython
+                              VERSION ${_${_PYTHON_PREFIX}_FIND_VERSIONS})
+      _python_get_registries (_${_PYTHON_PREFIX}_REGISTRY_PATHS
+                              IMPLEMENTATIONS IronPython
+                              VERSION ${_${_PYTHON_PREFIX}_FIND_VERSIONS})
 
       while (TRUE)
-        if (_${_PYTHON_PREFIX}_FIND_REGISTRY STREQUAL "FIRST")
+        # Apple frameworks handling
+        if (CMAKE_HOST_APPLE AND _${_PYTHON_PREFIX}_FIND_FRAMEWORK STREQUAL "FIRST")
           find_program (_${_PYTHON_PREFIX}_COMPILER
-                        NAMES ipyc
+                        NAMES ${_${_PYTHON_PREFIX}_COMPILER_NAMES}
+                        NAMES_PER_DIR
+                        HINTS ${_${_PYTHON_PREFIX}_IRON_ROOT} ${_${_PYTHON_PREFIX}_HINTS}
+                        PATHS ${_${_PYTHON_PREFIX}_FRAMEWORK_PATHS}
+                        PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES}
+                        NO_CMAKE_PATH
+                        NO_CMAKE_ENVIRONMENT_PATH
+                        NO_SYSTEM_ENVIRONMENT_PATH
+                        NO_CMAKE_SYSTEM_PATH)
+          _python_validate_compiler (${${_PYTHON_PREFIX}_FIND_VERSION} ${_${_PYTHON_PREFIX}_FIND_VERSION_EXACT})
+          if (_${_PYTHON_PREFIX}_COMPILER)
+            break()
+          endif()
+        endif()
+        # Windows registry
+        if (CMAKE_HOST_WIN32 AND _${_PYTHON_PREFIX}_FIND_REGISTRY STREQUAL "FIRST")
+          find_program (_${_PYTHON_PREFIX}_COMPILER
+                        NAMES ${_${_PYTHON_PREFIX}_COMPILER_NAMES}
+                        NAMES_PER_DIR
                         HINTS ${_${_PYTHON_PREFIX}_IRON_ROOT} ${_${_PYTHON_PREFIX}_HINTS}
                         PATHS ${_${_PYTHON_PREFIX}_REGISTRY_PATHS}
-                        PATH_SUFFIXES ${_${_PYTHON_PREFIX}_IRON_PYTHON_PATH_SUFFIXES}
+                        PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES}
                         NO_SYSTEM_ENVIRONMENT_PATH
                         NO_CMAKE_SYSTEM_PATH)
           _python_validate_compiler (${${_PYTHON_PREFIX}_FIND_VERSION} ${_${_PYTHON_PREFIX}_FIND_VERSION_EXACT})
@@ -1498,10 +1882,12 @@
           endif()
         endif()
 
+        # try using HINTS
         find_program (_${_PYTHON_PREFIX}_COMPILER
-                      NAMES ipyc
+                      NAMES ${_${_PYTHON_PREFIX}_COMPILER_NAMES}
+                      NAMES_PER_DIR
                       HINTS ${_${_PYTHON_PREFIX}_IRON_ROOT} ${_${_PYTHON_PREFIX}_HINTS}
-                      PATH_SUFFIXES ${_${_PYTHON_PREFIX}_IRON_PYTHON_PATH_SUFFIXES}
+                      PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES}
                       NO_SYSTEM_ENVIRONMENT_PATH
                       NO_CMAKE_SYSTEM_PATH)
         _python_validate_compiler (${${_PYTHON_PREFIX}_FIND_VERSION} ${_${_PYTHON_PREFIX}_FIND_VERSION_EXACT})
@@ -1509,12 +1895,40 @@
           break()
         endif()
 
-        if (_${_PYTHON_PREFIX}_FIND_REGISTRY STREQUAL "LAST")
+        # try using standard paths
+        find_program (_${_PYTHON_PREFIX}_COMPILER
+                      NAMES ${_${_PYTHON_PREFIX}_COMPILER_NAMES}
+                      NAMES_PER_DIR
+                      PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES})
+        _python_validate_compiler (${${_PYTHON_PREFIX}_FIND_VERSION} ${_${_PYTHON_PREFIX}_FIND_VERSION_EXACT})
+        if (_${_PYTHON_PREFIX}_COMPILER)
+          break()
+        endif()
+
+        # Apple frameworks handling
+        if (CMAKE_HOST_APPLE AND _${_PYTHON_PREFIX}_FIND_FRAMEWORK STREQUAL "LAST")
           find_program (_${_PYTHON_PREFIX}_COMPILER
-                        NAMES ipyc
-                        PATHS ${_${_PYTHON_PREFIX}_REGISTRY_PATHS}
-                        PATH_SUFFIXES ${_${_PYTHON_PREFIX}_IRON_PYTHON_PATH_SUFFIXES}
+                        NAMES ${_${_PYTHON_PREFIX}_COMPILER_NAMES}
+                        NAMES_PER_DIR
+                        PATHS ${_${_PYTHON_PREFIX}_FRAMEWORK_PATHS}
+                        PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES}
                         NO_DEFAULT_PATH)
+          _python_validate_compiler (${${_PYTHON_PREFIX}_FIND_VERSION} ${_${_PYTHON_PREFIX}_FIND_VERSION_EXACT})
+          if (_${_PYTHON_PREFIX}_COMPILER)
+            break()
+          endif()
+        endif()
+        # Windows registry
+        if (CMAKE_HOST_WIN32 AND _${_PYTHON_PREFIX}_FIND_REGISTRY STREQUAL "LAST")
+          find_program (_${_PYTHON_PREFIX}_COMPILER
+                        NAMES ${_${_PYTHON_PREFIX}_COMPILER_NAMES}
+                        NAMES_PER_DIR
+                        PATHS ${_${_PYTHON_PREFIX}_REGISTRY_PATHS}
+                        PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES}
+                        NO_DEFAULT_PATH)
+          if (_${_PYTHON_PREFIX}_COMPILER)
+            break()
+          endif()
         endif()
 
         break()
@@ -1522,12 +1936,48 @@
     else()
       # try using root dir and registry
       foreach (_${_PYTHON_PREFIX}_VERSION IN LISTS _${_PYTHON_PREFIX}_FIND_VERSIONS)
-        if (_${_PYTHON_PREFIX}_FIND_REGISTRY STREQUAL "FIRST")
+        _python_get_names (_${_PYTHON_PREFIX}_COMPILER_NAMES
+                           IMPLEMENTATIONS IronPython
+                           VERSION ${_${_PYTHON_PREFIX}_FIND_VERSIONS}
+                           COMPILER)
+
+        _python_get_path_suffixes (_${_PYTHON_PREFIX}_PATH_SUFFIXES
+                                   IMPLEMENTATIONS IronPython
+                                   VERSION ${_${_PYTHON_PREFIX}_FIND_VERSION}
+                                   COMPILER)
+
+        _python_get_frameworks (_${_PYTHON_PREFIX}_FRAMEWORK_PATHS
+                                IMPLEMENTATIONS IronPython
+                                VERSION ${_${_PYTHON_PREFIX}_VERSION})
+        _python_get_registries (_${_PYTHON_PREFIX}_REGISTRY_PATHS
+                                IMPLEMENTATIONS IronPython
+                                VERSION ${_${_PYTHON_PREFIX}_VERSION})
+
+        # Apple frameworks handling
+        if (CMAKE_HOST_APPLE AND _${_PYTHON_PREFIX}_FIND_FRAMEWORK STREQUAL "FIRST")
           find_program (_${_PYTHON_PREFIX}_COMPILER
-                        NAMES ipyc
+                        NAMES ${_${_PYTHON_PREFIX}_COMPILER_NAMES}
+                        NAMES_PER_DIR
                         HINTS ${_${_PYTHON_PREFIX}_IRON_ROOT} ${_${_PYTHON_PREFIX}_HINTS}
-                        PATHS [HKEY_LOCAL_MACHINE\\SOFTWARE\\IronPython\\${_${_PYTHON_PREFIX}_VERSION}\\InstallPath]
-                        PATH_SUFFIXES ${_${_PYTHON_PREFIX}_IRON_PYTHON_PATH_SUFFIXES}
+                        PATHS ${_${_PYTHON_PREFIX}_FRAMEWORK_PATHS}
+                        PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES}
+                        NO_CMAKE_PATH
+                        NO_CMAKE_ENVIRONMENT_PATH
+                        NO_SYSTEM_ENVIRONMENT_PATH
+                        NO_CMAKE_SYSTEM_PATH)
+          _python_validate_compiler (${_${_PYTHON_PREFIX}_VERSION} EXACT)
+          if (_${_PYTHON_PREFIX}_COMPILER)
+            break()
+          endif()
+        endif()
+        # Windows registry
+        if (CMAKE_HOST_WIN32 AND _${_PYTHON_PREFIX}_FIND_REGISTRY STREQUAL "FIRST")
+          find_program (_${_PYTHON_PREFIX}_COMPILER
+                        NAMES ${_${_PYTHON_PREFIX}_COMPILER_NAMES}
+                        NAMES_PER_DIR
+                        HINTS ${_${_PYTHON_PREFIX}_IRON_ROOT} ${_${_PYTHON_PREFIX}_HINTS}
+                        PATHS ${_${_PYTHON_PREFIX}_REGISTRY_PATHS}
+                        PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES}
                         NO_SYSTEM_ENVIRONMENT_PATH
                         NO_CMAKE_SYSTEM_PATH)
           _python_validate_compiler (${_${_PYTHON_PREFIX}_VERSION} EXACT)
@@ -1536,10 +1986,12 @@
           endif()
         endif()
 
+        # try using HINTS
         find_program (_${_PYTHON_PREFIX}_COMPILER
-                      NAMES ipyc
+                      NAMES ${_${_PYTHON_PREFIX}_COMPILER_NAMES}
+                      NAMES_PER_DIR
                       HINTS ${_${_PYTHON_PREFIX}_IRON_ROOT} ${_${_PYTHON_PREFIX}_HINTS}
-                      PATH_SUFFIXES ${_${_PYTHON_PREFIX}_IRON_PYTHON_PATH_SUFFIXES}
+                      PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES}
                       NO_SYSTEM_ENVIRONMENT_PATH
                       NO_CMAKE_SYSTEM_PATH)
         _python_validate_compiler (${_${_PYTHON_PREFIX}_VERSION} EXACT)
@@ -1547,11 +1999,26 @@
           break()
         endif()
 
-        if (_${_PYTHON_PREFIX}_FIND_REGISTRY STREQUAL "LAST")
+        # Apple frameworks handling
+        if (CMAKE_HOST_APPLE AND _${_PYTHON_PREFIX}_FIND_FRAMEWORK STREQUAL "LAST")
           find_program (_${_PYTHON_PREFIX}_COMPILER
-                        NAMES ipyc
-                        PATHS [HKEY_LOCAL_MACHINE\\SOFTWARE\\IronPython\\${_${_PYTHON_PREFIX}_VERSION}\\InstallPath]
-                        PATH_SUFFIXES ${_${_PYTHON_PREFIX}_IRON_PYTHON_PATH_SUFFIXES}
+                        NAMES ${_${_PYTHON_PREFIX}_COMPILER_NAMES}
+                        NAMES_PER_DIR
+                        PATHS ${_${_PYTHON_PREFIX}_FRAMEWORK_PATHS}
+                        PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES}
+                        NO_DEFAULT_PATH)
+          _python_validate_compiler (${_${_PYTHON_PREFIX}_VERSION} EXACT)
+          if (_${_PYTHON_PREFIX}_COMPILER)
+            break()
+          endif()
+        endif()
+        # Windows registry
+        if (CMAKE_HOST_WIN32 AND _${_PYTHON_PREFIX}_FIND_REGISTRY STREQUAL "LAST")
+          find_program (_${_PYTHON_PREFIX}_COMPILER
+                        NAMES ${_${_PYTHON_PREFIX}_COMPILER_NAMES}
+                        NAMES_PER_DIR
+                        PATHS ${_${_PYTHON_PREFIX}_REGISTRY_PATHS}
+                        PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES}
                         NO_DEFAULT_PATH)
           _python_validate_compiler (${_${_PYTHON_PREFIX}_VERSION} EXACT)
           if (_${_PYTHON_PREFIX}_COMPILER)
@@ -1561,10 +2028,18 @@
       endforeach()
 
       # no specific version found, re-try in standard paths
+      _python_get_names (_${_PYTHON_PREFIX}_COMPILER_NAMES
+                         IMPLEMENTATIONS IronPython
+                         VERSION ${_${_PYTHON_PREFIX}_FIND_VERSIONS}
+                         COMPILER)
+      _python_get_path_suffixes (_${_PYTHON_PREFIX}_PATH_SUFFIXES
+                                 IMPLEMENTATIONS IronPython
+                                 VERSION ${_${_PYTHON_PREFIX}_FIND_VERSIONS}
+                                 COMPILER)
       find_program (_${_PYTHON_PREFIX}_COMPILER
-                    NAMES ipyc
+                    NAMES ${_${_PYTHON_PREFIX}_COMPILER_NAMES}
                     HINTS ${_${_PYTHON_PREFIX}_IRON_ROOT} ${_${_PYTHON_PREFIX}_HINTS}
-                    PATH_SUFFIXES ${_${_PYTHON_PREFIX}_IRON_PYTHON_PATH_SUFFIXES})
+                    PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES})
     endif()
   endif()
 
@@ -1572,13 +2047,18 @@
 
   if (_${_PYTHON_PREFIX}_COMPILER)
     # retrieve python environment version from compiler
+    _python_get_launcher (_${_PYTHON_PREFIX}_COMPILER_LAUNCHER COMPILER)
     set (_${_PYTHON_PREFIX}_VERSION_DIR "${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/PythonCompilerVersion.dir")
     file (WRITE "${_${_PYTHON_PREFIX}_VERSION_DIR}/version.py" "import sys; sys.stdout.write('.'.join([str(x) for x in sys.version_info[:3]]))\n")
-    execute_process (COMMAND "${_${_PYTHON_PREFIX}_COMPILER}" /target:exe /embed "${_${_PYTHON_PREFIX}_VERSION_DIR}/version.py"
+    execute_process (COMMAND ${_${_PYTHON_PREFIX}_COMPILER_LAUNCHER} "${_${_PYTHON_PREFIX}_COMPILER}"
+                             ${_${_PYTHON_PREFIX}_IRON_PYTHON_COMPILER_ARCH_FLAGS}
+                             /target:exe /embed "${_${_PYTHON_PREFIX}_VERSION_DIR}/version.py"
                      WORKING_DIRECTORY "${_${_PYTHON_PREFIX}_VERSION_DIR}"
                      OUTPUT_QUIET
                      ERROR_QUIET)
-    execute_process (COMMAND "${_${_PYTHON_PREFIX}_VERSION_DIR}/version"
+    get_filename_component (_${_PYTHON_PREFIX}_IR_DIR "${_${_PYTHON_PREFIX}_COMPILER}" DIRECTORY)
+    execute_process (COMMAND "${CMAKE_COMMAND}" -E env "MONO_PATH=${_${_PYTHON_PREFIX}_IR_DIR}"
+                             ${${_PYTHON_PREFIX}_DOTNET_LAUNCHER} "${_${_PYTHON_PREFIX}_VERSION_DIR}/version.exe"
                      WORKING_DIRECTORY "${_${_PYTHON_PREFIX}_VERSION_DIR}"
                      RESULT_VARIABLE _${_PYTHON_PREFIX}_RESULT
                      OUTPUT_VARIABLE _${_PYTHON_PREFIX}_VERSION
@@ -1613,12 +2093,14 @@
       endif()
     elseif (${_PYTHON_PREFIX}_VERSION_MAJOR VERSION_EQUAL _${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR)
       set (${_PYTHON_PREFIX}_Compiler_FOUND TRUE)
-    # Use compiler version for future searches to ensure consistency
-    set (_${_PYTHON_PREFIX}_FIND_VERSIONS ${${_PYTHON_PREFIX}_VERSION_MAJOR}.${${_PYTHON_PREFIX}_VERSION_MINOR})
+      # Use compiler version for future searches to ensure consistency
+      set (_${_PYTHON_PREFIX}_FIND_VERSIONS ${${_PYTHON_PREFIX}_VERSION_MAJOR}.${${_PYTHON_PREFIX}_VERSION_MINOR})
     endif()
   endif()
 
   if (${_PYTHON_PREFIX}_Compiler_FOUND)
+    unset (_${_PYTHON_PREFIX}_Compiler_REASON_FAILURE)
+
     # compute and save compiler signature
     string (MD5 __${_PYTHON_PREFIX}_COMPILER_SIGNATURE "${_${_PYTHON_PREFIX}_SIGNATURE}:${_${_PYTHON_PREFIX}_COMPILER}")
     set (_${_PYTHON_PREFIX}_COMPILER_SIGNATURE "${__${_PYTHON_PREFIX}_COMPILER_SIGNATURE}" CACHE INTERNAL "")
@@ -1629,53 +2111,60 @@
     unset (${_PYTHON_PREFIX}_COMPILER_ID)
   endif()
 
+  if (${_PYTHON_PREFIX}_ARTIFACTS_INTERACTIVE)
+    set (${_PYTHON_PREFIX}_COMPILER "${_${_PYTHON_PREFIX}_COMPILER}" CACHE FILEPATH "${_PYTHON_PREFIX} Compiler")
+  endif()
+
   _python_mark_as_internal (_${_PYTHON_PREFIX}_COMPILER
                             _${_PYTHON_PREFIX}_COMPILER_SIGNATURE)
 endif()
 
-
 # third step, search for the development artifacts
-if (${_PYTHON_PREFIX}_FIND_REQUIRED_Development)
-  list (APPEND _${_PYTHON_PREFIX}_REQUIRED_VARS ${_PYTHON_PREFIX}_LIBRARIES
-                                                ${_PYTHON_PREFIX}_INCLUDE_DIRS)
+if (${_PYTHON_PREFIX}_FIND_REQUIRED_Development.Module)
+  if ("LIBRARY" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_MODULE_ARTIFACTS)
+    list (APPEND _${_PYTHON_PREFIX}_REQUIRED_VARS ${_PYTHON_PREFIX}_LIBRARIES)
+  endif()
+  if ("INCLUDE_DIR" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_MODULE_ARTIFACTS)
+    list (APPEND _${_PYTHON_PREFIX}_REQUIRED_VARS ${_PYTHON_PREFIX}_INCLUDE_DIRS)
+  endif()
 endif()
+if (${_PYTHON_PREFIX}_FIND_REQUIRED_Development.Embed)
+  if ("LIBRARY" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_EMBED_ARTIFACTS)
+    list (APPEND _${_PYTHON_PREFIX}_REQUIRED_VARS ${_PYTHON_PREFIX}_LIBRARIES)
+  endif()
+  if ("INCLUDE_DIR" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_EMBED_ARTIFACTS)
+    list (APPEND _${_PYTHON_PREFIX}_REQUIRED_VARS ${_PYTHON_PREFIX}_INCLUDE_DIRS)
+  endif()
+endif()
+list (REMOVE_DUPLICATES _${_PYTHON_PREFIX}_REQUIRED_VARS)
 ## Development environment is not compatible with IronPython interpreter
-if ("Development" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS
-    AND NOT ${_PYTHON_PREFIX}_INTERPRETER_ID STREQUAL "IronPython")
+if (("Development.Module" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS
+      OR "Development.Embed" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS)
+    AND ((${_PYTHON_PREFIX}_Interpreter_FOUND
+        AND NOT ${_PYTHON_PREFIX}_INTERPRETER_ID STREQUAL "IronPython")
+      OR NOT ${_PYTHON_PREFIX}_Interpreter_FOUND))
+  if (${_PYTHON_PREFIX}_Interpreter_FOUND)
+    # reduce possible implementations to the interpreter one
+    if (${_PYTHON_PREFIX}_INTERPRETER_ID STREQUAL "PyPy")
+      set (_${_PYTHON_PREFIX}_FIND_IMPLEMENTATIONS "PyPy")
+    else()
+      set (_${_PYTHON_PREFIX}_FIND_IMPLEMENTATIONS "CPython")
+    endif()
+  else()
+    list (REMOVE_ITEM _${_PYTHON_PREFIX}_FIND_IMPLEMENTATIONS "IronPython")
+  endif()
+  if ("LIBRARY" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_ARTIFACTS)
   list (APPEND _${_PYTHON_PREFIX}_CACHED_VARS _${_PYTHON_PREFIX}_LIBRARY_RELEASE
                                               _${_PYTHON_PREFIX}_RUNTIME_LIBRARY_RELEASE
                                               _${_PYTHON_PREFIX}_LIBRARY_DEBUG
-                                              _${_PYTHON_PREFIX}_RUNTIME_LIBRARY_DEBUG
-                                              _${_PYTHON_PREFIX}_INCLUDE_DIR)
+                                              _${_PYTHON_PREFIX}_RUNTIME_LIBRARY_DEBUG)
+  endif()
+  if ("INCLUDE_DIR" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_ARTIFACTS)
+    list (APPEND _${_PYTHON_PREFIX}_CACHED_VARS _${_PYTHON_PREFIX}_INCLUDE_DIR)
+  endif()
 
-  if (DEFINED _${_PYTHON_PREFIX}_LIBRARY_RELEASE OR DEFINED _${_PYTHON_PREFIX}_INCLUDE_DIR)
-    # compute development signature and check validity of definition
-    string (MD5 __${_PYTHON_PREFIX}_DEVELOPMENT_SIGNATURE "${_${_PYTHON_PREFIX}_SIGNATURE}:${_${_PYTHON_PREFIX}_LIBRARY_RELEASE}:${_${_PYTHON_PREFIX}_INCLUDE_DIR}")
-    if (WIN32 AND NOT DEFINED _${_PYTHON_PREFIX}_LIBRARY_DEBUG)
-      set (_${_PYTHON_PREFIX}_LIBRARY_DEBUG "${_PYTHON_PREFIX}_LIBRARY_DEBUG-NOTFOUND" CACHE INTERNAL "")
-    endif()
-    if (NOT DEFINED _${_PYTHON_PREFIX}_INCLUDE_DIR)
-      set (_${_PYTHON_PREFIX}_INCLUDE_DIR "${_PYTHON_PREFIX}_INCLUDE_DIR-NOTFOUND" CACHE INTERNAL "")
-    endif()
-    if (__${_PYTHON_PREFIX}_DEVELOPMENT_SIGNATURE STREQUAL _${_PYTHON_PREFIX}_DEVELOPMENT_SIGNATURE)
-      # check version validity
-      if (${_PYTHON_PREFIX}_FIND_VERSION_EXACT)
-        _python_validate_library (${${_PYTHON_PREFIX}_FIND_VERSION} EXACT CHECK_EXISTS)
-        _python_validate_include_dir (${${_PYTHON_PREFIX}_FIND_VERSION} EXACT CHECK_EXISTS)
-      else()
-        _python_validate_library (${${_PYTHON_PREFIX}_FIND_VERSION} CHECK_EXISTS)
-        _python_validate_include_dir (${${_PYTHON_PREFIX}_FIND_VERSION} CHECK_EXISTS)
-      endif()
-    else()
-      unset (_${_PYTHON_PREFIX}_LIBRARY_RELEASE CACHE)
-      unset (_${_PYTHON_PREFIX}_LIBRARY_DEBUG CACHE)
-      unset (_${_PYTHON_PREFIX}_INCLUDE_DIR CACHE)
-    endif()
-  endif()
-  if (NOT _${_PYTHON_PREFIX}_LIBRARY_RELEASE OR NOT _${_PYTHON_PREFIX}_INCLUDE_DIR)
-    unset (_${_PYTHON_PREFIX}_CONFIG CACHE)
-    unset (_${_PYTHON_PREFIX}_DEVELOPMENT_SIGNATURE CACHE)
-  endif()
+  _python_check_development_signature (Module)
+  _python_check_development_signature (Embed)
 
   if (DEFINED ${_PYTHON_PREFIX}_LIBRARY
       AND IS_ABSOLUTE "${${_PYTHON_PREFIX}_LIBRARY}")
@@ -1703,25 +2192,18 @@
     # if python interpreter is found, use it to look-up for artifacts
     # to ensure consistency between interpreter and development environments.
     # If not, try to locate a compatible config tool
-    if (NOT ${_PYTHON_PREFIX}_Interpreter_FOUND OR CMAKE_CROSSCOMPILING)
+    if ((NOT ${_PYTHON_PREFIX}_Interpreter_FOUND OR CMAKE_CROSSCOMPILING)
+        AND "CPython" IN_LIST _${_PYTHON_PREFIX}_FIND_IMPLEMENTATIONS)
       set (_${_PYTHON_PREFIX}_HINTS "${${_PYTHON_PREFIX}_ROOT_DIR}" ENV ${_PYTHON_PREFIX}_ROOT_DIR)
       unset (_${_PYTHON_PREFIX}_VIRTUALENV_PATHS)
       if (_${_PYTHON_PREFIX}_FIND_VIRTUALENV MATCHES "^(FIRST|ONLY)$")
         set (_${_PYTHON_PREFIX}_VIRTUALENV_PATHS ENV VIRTUAL_ENV ENV CONDA_PREFIX)
       endif()
-      unset (_${_PYTHON_PREFIX}_FRAMEWORK_PATHS)
 
       if (_${_PYTHON_PREFIX}_FIND_STRATEGY STREQUAL "LOCATION")
-        set (_${_PYTHON_PREFIX}_CONFIG_NAMES)
-
-        foreach (_${_PYTHON_PREFIX}_VERSION IN LISTS _${_PYTHON_PREFIX}_FIND_VERSIONS)
-          _python_get_names (_${_PYTHON_PREFIX}_VERSION_NAMES VERSION ${_${_PYTHON_PREFIX}_VERSION} POSIX CONFIG)
-          list (APPEND _${_PYTHON_PREFIX}_CONFIG_NAMES ${_${_PYTHON_PREFIX}_VERSION_NAMES})
-
+        _python_get_names (_${_PYTHON_PREFIX}_CONFIG_NAMES VERSION ${_${_PYTHON_PREFIX}_FIND_VERSIONS} POSIX CONFIG)
           # Framework Paths
-          _python_get_frameworks (_${_PYTHON_PREFIX}_VERSION_PATHS ${_${_PYTHON_PREFIX}_VERSION})
-          list (APPEND _${_PYTHON_PREFIX}_FRAMEWORK_PATHS ${_${_PYTHON_PREFIX}_VERSION_PATHS})
-        endforeach()
+        _python_get_frameworks (_${_PYTHON_PREFIX}_FRAMEWORK_PATHS VERSION ${_${_PYTHON_PREFIX}_FIND_VERSIONS})
 
         # Apple frameworks handling
         if (CMAKE_HOST_APPLE AND _${_PYTHON_PREFIX}_FIND_FRAMEWORK STREQUAL "FIRST")
@@ -1805,7 +2287,7 @@
           _python_get_names (_${_PYTHON_PREFIX}_CONFIG_NAMES VERSION ${_${_PYTHON_PREFIX}_VERSION} POSIX CONFIG)
 
           # Framework Paths
-          _python_get_frameworks (_${_PYTHON_PREFIX}_FRAMEWORK_PATHS ${_${_PYTHON_PREFIX}_VERSION})
+          _python_get_frameworks (_${_PYTHON_PREFIX}_FRAMEWORK_PATHS VERSION ${_${_PYTHON_PREFIX}_VERSION})
 
           # Apple frameworks handling
           if (CMAKE_HOST_APPLE AND _${_PYTHON_PREFIX}_FIND_FRAMEWORK STREQUAL "FIRST")
@@ -1898,140 +2380,61 @@
     endif()
   endif()
 
-  if (NOT _${_PYTHON_PREFIX}_LIBRARY_RELEASE)
-    if ((${_PYTHON_PREFIX}_Interpreter_FOUND AND NOT CMAKE_CROSSCOMPILING) OR _${_PYTHON_PREFIX}_CONFIG)
-      # retrieve root install directory
-      _python_get_config_var (_${_PYTHON_PREFIX}_PREFIX PREFIX)
-
-      # enforce current ABI
-      _python_get_config_var (_${_PYTHON_PREFIX}_ABIFLAGS ABIFLAGS)
-
-      set (_${_PYTHON_PREFIX}_HINTS "${_${_PYTHON_PREFIX}_PREFIX}")
-
-      # retrieve library
-      ## compute some paths and artifact names
-      if (_${_PYTHON_PREFIX}_CONFIG)
-        string (REGEX REPLACE "^.+python([0-9.]+)[a-z]*-config" "\\1" _${_PYTHON_PREFIX}_VERSION "${_${_PYTHON_PREFIX}_CONFIG}")
-      else()
-        set (_${_PYTHON_PREFIX}_VERSION "${${_PYTHON_PREFIX}_VERSION_MAJOR}.${${_PYTHON_PREFIX}_VERSION_MINOR}")
-      endif()
-      _python_get_path_suffixes (_${_PYTHON_PREFIX}_PATH_SUFFIXES VERSION ${_${_PYTHON_PREFIX}_VERSION} LIBRARY)
-      _python_get_names (_${_PYTHON_PREFIX}_LIB_NAMES VERSION ${_${_PYTHON_PREFIX}_VERSION} WIN32 POSIX LIBRARY)
-
-      _python_get_config_var (_${_PYTHON_PREFIX}_CONFIGDIR CONFIGDIR)
-      list (APPEND _${_PYTHON_PREFIX}_HINTS "${_${_PYTHON_PREFIX}_CONFIGDIR}")
-
-      list (APPEND _${_PYTHON_PREFIX}_HINTS "${${_PYTHON_PREFIX}_ROOT_DIR}" ENV ${_PYTHON_PREFIX}_ROOT_DIR)
-
-      find_library (_${_PYTHON_PREFIX}_LIBRARY_RELEASE
-                    NAMES ${_${_PYTHON_PREFIX}_LIB_NAMES}
-                    NAMES_PER_DIR
-                    HINTS ${_${_PYTHON_PREFIX}_HINTS}
-                    PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES}
-                    NO_SYSTEM_ENVIRONMENT_PATH
-                    NO_CMAKE_SYSTEM_PATH)
-    endif()
-
-    # Rely on HINTS and standard paths if interpreter or config tool failed to locate artifacts
+  if ("LIBRARY" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_ARTIFACTS)
     if (NOT _${_PYTHON_PREFIX}_LIBRARY_RELEASE)
-      set (_${_PYTHON_PREFIX}_HINTS "${${_PYTHON_PREFIX}_ROOT_DIR}" ENV ${_PYTHON_PREFIX}_ROOT_DIR)
+      if ((${_PYTHON_PREFIX}_Interpreter_FOUND AND NOT CMAKE_CROSSCOMPILING) OR _${_PYTHON_PREFIX}_CONFIG)
+        # retrieve root install directory
+        _python_get_config_var (_${_PYTHON_PREFIX}_PREFIX PREFIX)
 
-      unset (_${_PYTHON_PREFIX}_VIRTUALENV_PATHS)
-      if (_${_PYTHON_PREFIX}_FIND_VIRTUALENV MATCHES "^(FIRST|ONLY)$")
-        set (_${_PYTHON_PREFIX}_VIRTUALENV_PATHS ENV VIRTUAL_ENV ENV CONDA_PREFIX)
-      endif()
+        # enforce current ABI
+        _python_get_config_var (_${_PYTHON_PREFIX}_ABIFLAGS ABIFLAGS)
 
-      if (_${_PYTHON_PREFIX}_FIND_STRATEGY STREQUAL "LOCATION")
-        unset (_${_PYTHON_PREFIX}_LIB_NAMES)
-        unset (_${_PYTHON_PREFIX}_LIB_NAMES_DEBUG)
-        unset (_${_PYTHON_PREFIX}_FRAMEWORK_PATHS)
-        unset (_${_PYTHON_PREFIX}_REGISTRY_PATHS)
-        unset (_${_PYTHON_PREFIX}_PATH_SUFFIXES)
+        set (_${_PYTHON_PREFIX}_HINTS "${_${_PYTHON_PREFIX}_PREFIX}")
 
-        foreach (_${_PYTHON_PREFIX}_LIB_VERSION IN LISTS _${_PYTHON_PREFIX}_FIND_VERSIONS)
-          # library names
-          _python_get_names (_${_PYTHON_PREFIX}_VERSION_NAMES VERSION ${_${_PYTHON_PREFIX}_LIB_VERSION} WIN32 POSIX LIBRARY)
-          list (APPEND _${_PYTHON_PREFIX}_LIB_NAMES ${_${_PYTHON_PREFIX}_VERSION_NAMES})
-          _python_get_names (_${_PYTHON_PREFIX}_VERSION_NAMES VERSION ${_${_PYTHON_PREFIX}_LIB_VERSION} WIN32 DEBUG)
-          list (APPEND _${_PYTHON_PREFIX}_LIB_NAMES_DEBUG ${_${_PYTHON_PREFIX}_VERSION_NAMES})
-
-          # Framework Paths
-          _python_get_frameworks (_${_PYTHON_PREFIX}_VERSION_PATHS ${_${_PYTHON_PREFIX}_LIB_VERSION})
-          list (APPEND _${_PYTHON_PREFIX}_FRAMEWORK_PATHS ${_${_PYTHON_PREFIX}_VERSION_PATHS})
-
-          # Registry Paths
-          _python_get_registries (_${_PYTHON_PREFIX}_VERSION_PATHS ${_${_PYTHON_PREFIX}_LIB_VERSION})
-          list (APPEND _${_PYTHON_PREFIX}_REGISTRY_PATHS ${_${_PYTHON_PREFIX}_VERSION_PATHS})
-
-          # Paths suffixes
-          _python_get_path_suffixes (_${_PYTHON_PREFIX}_VERSION_PATHS VERSION ${_${_PYTHON_PREFIX}_LIB_VERSION} LIBRARY)
-          list (APPEND _${_PYTHON_PREFIX}_PATH_SUFFIXES ${_${_PYTHON_PREFIX}_VERSION_PATHS})
-        endforeach()
-
-        if (APPLE AND _${_PYTHON_PREFIX}_FIND_FRAMEWORK STREQUAL "FIRST")
-          find_library (_${_PYTHON_PREFIX}_LIBRARY_RELEASE
-                        NAMES ${_${_PYTHON_PREFIX}_LIB_NAMES}
-                        NAMES_PER_DIR
-                        HINTS ${_${_PYTHON_PREFIX}_HINTS}
-                        PATHS ${_${_PYTHON_PREFIX}_VIRTUALENV_PATHS}
-                              ${_${_PYTHON_PREFIX}_FRAMEWORK_PATHS}
-                        PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES}
-                        NO_CMAKE_PATH
-                        NO_CMAKE_ENVIRONMENT_PATH
-                        NO_SYSTEM_ENVIRONMENT_PATH
-                        NO_CMAKE_SYSTEM_PATH)
+        # retrieve library
+        ## compute some paths and artifact names
+        if (_${_PYTHON_PREFIX}_CONFIG)
+          string (REGEX REPLACE "^.+python([0-9.]+)[a-z]*-config" "\\1" _${_PYTHON_PREFIX}_VERSION "${_${_PYTHON_PREFIX}_CONFIG}")
+        else()
+          set (_${_PYTHON_PREFIX}_VERSION "${${_PYTHON_PREFIX}_VERSION_MAJOR}.${${_PYTHON_PREFIX}_VERSION_MINOR}")
         endif()
+        _python_get_path_suffixes (_${_PYTHON_PREFIX}_PATH_SUFFIXES VERSION ${_${_PYTHON_PREFIX}_VERSION} LIBRARY)
+        _python_get_names (_${_PYTHON_PREFIX}_LIB_NAMES VERSION ${_${_PYTHON_PREFIX}_VERSION} WIN32 POSIX LIBRARY)
 
-        if (WIN32 AND _${_PYTHON_PREFIX}_FIND_REGISTRY STREQUAL "FIRST")
-          find_library (_${_PYTHON_PREFIX}_LIBRARY_RELEASE
-                        NAMES ${_${_PYTHON_PREFIX}_LIB_NAMES}
-                        NAMES_PER_DIR
-                        HINTS ${_${_PYTHON_PREFIX}_HINTS}
-                        PATHS ${_${_PYTHON_PREFIX}_VIRTUALENV_PATHS}
-                              ${_${_PYTHON_PREFIX}_REGISTRY_PATHS}
-                        PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES}
-                        NO_SYSTEM_ENVIRONMENT_PATH
-                        NO_CMAKE_SYSTEM_PATH)
-        endif()
+        _python_get_config_var (_${_PYTHON_PREFIX}_CONFIGDIR CONFIGDIR)
+        list (APPEND _${_PYTHON_PREFIX}_HINTS "${_${_PYTHON_PREFIX}_CONFIGDIR}")
 
-        # search in HINTS locations
+        list (APPEND _${_PYTHON_PREFIX}_HINTS "${${_PYTHON_PREFIX}_ROOT_DIR}" ENV ${_PYTHON_PREFIX}_ROOT_DIR)
+
         find_library (_${_PYTHON_PREFIX}_LIBRARY_RELEASE
                       NAMES ${_${_PYTHON_PREFIX}_LIB_NAMES}
                       NAMES_PER_DIR
                       HINTS ${_${_PYTHON_PREFIX}_HINTS}
-                      PATHS ${_${_PYTHON_PREFIX}_VIRTUALENV_PATHS}
                       PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES}
                       NO_SYSTEM_ENVIRONMENT_PATH
                       NO_CMAKE_SYSTEM_PATH)
+      endif()
 
-        if (APPLE AND _${_PYTHON_PREFIX}_FIND_FRAMEWORK STREQUAL "LAST")
-          set (__${_PYTHON_PREFIX}_FRAMEWORK_PATHS ${_${_PYTHON_PREFIX}_FRAMEWORK_PATHS})
-        else()
-          unset (__${_PYTHON_PREFIX}_FRAMEWORK_PATHS)
+      # Rely on HINTS and standard paths if interpreter or config tool failed to locate artifacts
+      if (NOT _${_PYTHON_PREFIX}_LIBRARY_RELEASE)
+        set (_${_PYTHON_PREFIX}_HINTS "${${_PYTHON_PREFIX}_ROOT_DIR}" ENV ${_PYTHON_PREFIX}_ROOT_DIR)
+
+        unset (_${_PYTHON_PREFIX}_VIRTUALENV_PATHS)
+        if (_${_PYTHON_PREFIX}_FIND_VIRTUALENV MATCHES "^(FIRST|ONLY)$")
+          set (_${_PYTHON_PREFIX}_VIRTUALENV_PATHS ENV VIRTUAL_ENV ENV CONDA_PREFIX)
         endif()
 
-        if (WIN32 AND _${_PYTHON_PREFIX}_FIND_REGISTRY STREQUAL "LAST")
-          set (__${_PYTHON_PREFIX}_REGISTRY_PATHS ${_${_PYTHON_PREFIX}_REGISTRY_PATHS})
-        else()
-          unset (__${_PYTHON_PREFIX}_REGISTRY_PATHS)
-        endif()
+        if (_${_PYTHON_PREFIX}_FIND_STRATEGY STREQUAL "LOCATION")
+          # library names
+          _python_get_names (_${_PYTHON_PREFIX}_LIB_NAMES VERSION ${_${_PYTHON_PREFIX}_FIND_VERSIONS} WIN32 POSIX LIBRARY)
+          _python_get_names (_${_PYTHON_PREFIX}_LIB_NAMES_DEBUG VERSION ${_${_PYTHON_PREFIX}_FIND_VERSIONS} WIN32 DEBUG)
+          # Paths suffixes
+          _python_get_path_suffixes (_${_PYTHON_PREFIX}_PATH_SUFFIXES VERSION ${_${_PYTHON_PREFIX}_FIND_VERSIONS} LIBRARY)
 
-        # search in all default paths
-        find_library (_${_PYTHON_PREFIX}_LIBRARY_RELEASE
-                      NAMES ${_${_PYTHON_PREFIX}_LIB_NAMES}
-                      NAMES_PER_DIR
-                      PATHS ${__${_PYTHON_PREFIX}_FRAMEWORK_PATHS}
-                            ${__${_PYTHON_PREFIX}_REGISTRY_PATHS}
-                      PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES})
-      else()
-        foreach (_${_PYTHON_PREFIX}_LIB_VERSION IN LISTS _${_PYTHON_PREFIX}_FIND_VERSIONS)
-          _python_get_names (_${_PYTHON_PREFIX}_LIB_NAMES VERSION ${_${_PYTHON_PREFIX}_LIB_VERSION} WIN32 POSIX LIBRARY)
-          _python_get_names (_${_PYTHON_PREFIX}_LIB_NAMES_DEBUG VERSION ${_${_PYTHON_PREFIX}_LIB_VERSION} WIN32 DEBUG)
-
-          _python_get_frameworks (_${_PYTHON_PREFIX}_FRAMEWORK_PATHS ${_${_PYTHON_PREFIX}_LIB_VERSION})
-          _python_get_registries (_${_PYTHON_PREFIX}_REGISTRY_PATHS ${_${_PYTHON_PREFIX}_LIB_VERSION})
-
-          _python_get_path_suffixes (_${_PYTHON_PREFIX}_PATH_SUFFIXES VERSION ${_${_PYTHON_PREFIX}_LIB_VERSION} LIBRARY)
+          # Framework Paths
+          _python_get_frameworks (_${_PYTHON_PREFIX}_FRAMEWORK_PATHS VERSION ${_${_PYTHON_PREFIX}_LIB_FIND_VERSIONS})
+          # Registry Paths
+          _python_get_registries (_${_PYTHON_PREFIX}_REGISTRY_PATHS VERSION ${_${_PYTHON_PREFIX}_FIND_VERSIONS} )
 
           if (APPLE AND _${_PYTHON_PREFIX}_FIND_FRAMEWORK STREQUAL "FIRST")
             find_library (_${_PYTHON_PREFIX}_LIBRARY_RELEASE
@@ -2069,200 +2472,288 @@
                         NO_SYSTEM_ENVIRONMENT_PATH
                         NO_CMAKE_SYSTEM_PATH)
 
-         if (APPLE AND _${_PYTHON_PREFIX}_FIND_FRAMEWORK STREQUAL "LAST")
-           set (__${_PYTHON_PREFIX}_FRAMEWORK_PATHS ${_${_PYTHON_PREFIX}_FRAMEWORK_PATHS})
-         else()
-           unset (__${_PYTHON_PREFIX}_FRAMEWORK_PATHS)
-         endif()
+          if (APPLE AND _${_PYTHON_PREFIX}_FIND_FRAMEWORK STREQUAL "LAST")
+            set (__${_PYTHON_PREFIX}_FRAMEWORK_PATHS ${_${_PYTHON_PREFIX}_FRAMEWORK_PATHS})
+          else()
+            unset (__${_PYTHON_PREFIX}_FRAMEWORK_PATHS)
+          endif()
 
-         if (WIN32 AND _${_PYTHON_PREFIX}_FIND_REGISTRY STREQUAL "LAST")
-           set (__${_PYTHON_PREFIX}_REGISTRY_PATHS ${_${_PYTHON_PREFIX}_REGISTRY_PATHS})
-         else()
-           unset (__${_PYTHON_PREFIX}_REGISTRY_PATHS)
-         endif()
+          if (WIN32 AND _${_PYTHON_PREFIX}_FIND_REGISTRY STREQUAL "LAST")
+            set (__${_PYTHON_PREFIX}_REGISTRY_PATHS ${_${_PYTHON_PREFIX}_REGISTRY_PATHS})
+          else()
+            unset (__${_PYTHON_PREFIX}_REGISTRY_PATHS)
+          endif()
 
-         # search in all default paths
-         find_library (_${_PYTHON_PREFIX}_LIBRARY_RELEASE
+          # search in all default paths
+          find_library (_${_PYTHON_PREFIX}_LIBRARY_RELEASE
                         NAMES ${_${_PYTHON_PREFIX}_LIB_NAMES}
                         NAMES_PER_DIR
                         PATHS ${__${_PYTHON_PREFIX}_FRAMEWORK_PATHS}
                               ${__${_PYTHON_PREFIX}_REGISTRY_PATHS}
                         PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES})
+        else()
+          foreach (_${_PYTHON_PREFIX}_LIB_VERSION IN LISTS _${_PYTHON_PREFIX}_FIND_VERSIONS)
+            _python_get_names (_${_PYTHON_PREFIX}_LIB_NAMES VERSION ${_${_PYTHON_PREFIX}_LIB_VERSION} WIN32 POSIX LIBRARY)
+            _python_get_names (_${_PYTHON_PREFIX}_LIB_NAMES_DEBUG VERSION ${_${_PYTHON_PREFIX}_LIB_VERSION} WIN32 DEBUG)
 
-          if (_${_PYTHON_PREFIX}_LIBRARY_RELEASE)
-            break()
-          endif()
-        endforeach()
+            _python_get_frameworks (_${_PYTHON_PREFIX}_FRAMEWORK_PATHS VERSION ${_${_PYTHON_PREFIX}_LIB_VERSION})
+            _python_get_registries (_${_PYTHON_PREFIX}_REGISTRY_PATHS VERSION ${_${_PYTHON_PREFIX}_LIB_VERSION})
+
+            _python_get_path_suffixes (_${_PYTHON_PREFIX}_PATH_SUFFIXES VERSION ${_${_PYTHON_PREFIX}_LIB_VERSION} LIBRARY)
+
+            if (APPLE AND _${_PYTHON_PREFIX}_FIND_FRAMEWORK STREQUAL "FIRST")
+              find_library (_${_PYTHON_PREFIX}_LIBRARY_RELEASE
+                            NAMES ${_${_PYTHON_PREFIX}_LIB_NAMES}
+                            NAMES_PER_DIR
+                            HINTS ${_${_PYTHON_PREFIX}_HINTS}
+                            PATHS ${_${_PYTHON_PREFIX}_VIRTUALENV_PATHS}
+                                  ${_${_PYTHON_PREFIX}_FRAMEWORK_PATHS}
+                            PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES}
+                            NO_CMAKE_PATH
+                            NO_CMAKE_ENVIRONMENT_PATH
+                            NO_SYSTEM_ENVIRONMENT_PATH
+                            NO_CMAKE_SYSTEM_PATH)
+            endif()
+
+            if (WIN32 AND _${_PYTHON_PREFIX}_FIND_REGISTRY STREQUAL "FIRST")
+              find_library (_${_PYTHON_PREFIX}_LIBRARY_RELEASE
+                            NAMES ${_${_PYTHON_PREFIX}_LIB_NAMES}
+                            NAMES_PER_DIR
+                            HINTS ${_${_PYTHON_PREFIX}_HINTS}
+                            PATHS ${_${_PYTHON_PREFIX}_VIRTUALENV_PATHS}
+                                  ${_${_PYTHON_PREFIX}_REGISTRY_PATHS}
+                            PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES}
+                            NO_SYSTEM_ENVIRONMENT_PATH
+                            NO_CMAKE_SYSTEM_PATH)
+            endif()
+
+            # search in HINTS locations
+            find_library (_${_PYTHON_PREFIX}_LIBRARY_RELEASE
+                          NAMES ${_${_PYTHON_PREFIX}_LIB_NAMES}
+                          NAMES_PER_DIR
+                          HINTS ${_${_PYTHON_PREFIX}_HINTS}
+                          PATHS ${_${_PYTHON_PREFIX}_VIRTUALENV_PATHS}
+                          PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES}
+                          NO_SYSTEM_ENVIRONMENT_PATH
+                          NO_CMAKE_SYSTEM_PATH)
+
+            if (APPLE AND _${_PYTHON_PREFIX}_FIND_FRAMEWORK STREQUAL "LAST")
+              set (__${_PYTHON_PREFIX}_FRAMEWORK_PATHS ${_${_PYTHON_PREFIX}_FRAMEWORK_PATHS})
+            else()
+              unset (__${_PYTHON_PREFIX}_FRAMEWORK_PATHS)
+            endif()
+
+            if (WIN32 AND _${_PYTHON_PREFIX}_FIND_REGISTRY STREQUAL "LAST")
+              set (__${_PYTHON_PREFIX}_REGISTRY_PATHS ${_${_PYTHON_PREFIX}_REGISTRY_PATHS})
+            else()
+              unset (__${_PYTHON_PREFIX}_REGISTRY_PATHS)
+            endif()
+
+            # search in all default paths
+            find_library (_${_PYTHON_PREFIX}_LIBRARY_RELEASE
+                          NAMES ${_${_PYTHON_PREFIX}_LIB_NAMES}
+                          NAMES_PER_DIR
+                          PATHS ${__${_PYTHON_PREFIX}_FRAMEWORK_PATHS}
+                                ${__${_PYTHON_PREFIX}_REGISTRY_PATHS}
+                          PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES})
+
+            if (_${_PYTHON_PREFIX}_LIBRARY_RELEASE)
+              break()
+            endif()
+          endforeach()
+        endif()
       endif()
     endif()
-  endif()
 
-  # finalize library version information
-  _python_get_version (LIBRARY PREFIX _${_PYTHON_PREFIX}_)
-
-  set (${_PYTHON_PREFIX}_LIBRARY_RELEASE "${_${_PYTHON_PREFIX}_LIBRARY_RELEASE}")
-
-  if (_${_PYTHON_PREFIX}_LIBRARY_RELEASE AND NOT EXISTS "${_${_PYTHON_PREFIX}_LIBRARY_RELEASE}")
-    set (_${_PYTHON_PREFIX}_Development_REASON_FAILURE "Cannot find the library \"${_${_PYTHON_PREFIX}_LIBRARY_RELEASE}\"")
-    set_property (CACHE _${_PYTHON_PREFIX}_LIBRARY_RELEASE PROPERTY VALUE "${_PYTHON_PREFIX}_LIBRARY_RELEASE-NOTFOUND")
-  endif()
-
-  set (_${_PYTHON_PREFIX}_HINTS "${${_PYTHON_PREFIX}_ROOT_DIR}" ENV ${_PYTHON_PREFIX}_ROOT_DIR)
-
-  if (WIN32 AND _${_PYTHON_PREFIX}_LIBRARY_RELEASE)
-    # search for debug library
-    # use release library location as a hint
-    _python_get_names (_${_PYTHON_PREFIX}_LIB_NAMES_DEBUG VERSION ${_${_PYTHON_PREFIX}_VERSION} WIN32 DEBUG)
-    get_filename_component (_${_PYTHON_PREFIX}_PATH "${_${_PYTHON_PREFIX}_LIBRARY_RELEASE}" DIRECTORY)
-    find_library (_${_PYTHON_PREFIX}_LIBRARY_DEBUG
-                  NAMES ${_${_PYTHON_PREFIX}_LIB_NAMES_DEBUG}
-                  NAMES_PER_DIR
-                  HINTS "${_${_PYTHON_PREFIX}_PATH}" ${_${_PYTHON_PREFIX}_HINTS}
-                  NO_DEFAULT_PATH)
-    # second try including CMAKE variables to catch-up non conventional layouts
-    find_library (_${_PYTHON_PREFIX}_LIBRARY_DEBUG
-                  NAMES ${_${_PYTHON_PREFIX}_LIB_NAMES_DEBUG}
-                  NAMES_PER_DIR
-                  NO_SYSTEM_ENVIRONMENT_PATH
-                  NO_CMAKE_SYSTEM_PATH)
-  endif()
-
-  # retrieve runtime libraries
-  if (_${_PYTHON_PREFIX}_LIBRARY_RELEASE)
-    _python_get_names (_${_PYTHON_PREFIX}_LIB_NAMES VERSION ${_${_PYTHON_PREFIX}_VERSION} WIN32 POSIX LIBRARY)
-    get_filename_component (_${_PYTHON_PREFIX}_PATH "${_${_PYTHON_PREFIX}_LIBRARY_RELEASE}" DIRECTORY)
-    get_filename_component (_${_PYTHON_PREFIX}_PATH2 "${_${_PYTHON_PREFIX}_PATH}" DIRECTORY)
-    _python_find_runtime_library (_${_PYTHON_PREFIX}_RUNTIME_LIBRARY_RELEASE
-                                  NAMES ${_${_PYTHON_PREFIX}_LIB_NAMES}
-                                  NAMES_PER_DIR
-                                  HINTS "${_${_PYTHON_PREFIX}_PATH}" "${_${_PYTHON_PREFIX}_PATH2}" ${_${_PYTHON_PREFIX}_HINTS}
-                                  PATH_SUFFIXES bin)
-  endif()
-  if (_${_PYTHON_PREFIX}_LIBRARY_DEBUG)
-    _python_get_names (_${_PYTHON_PREFIX}_LIB_NAMES_DEBUG VERSION ${_${_PYTHON_PREFIX}_VERSION} WIN32 DEBUG)
-    get_filename_component (_${_PYTHON_PREFIX}_PATH "${_${_PYTHON_PREFIX}_LIBRARY_DEBUG}" DIRECTORY)
-    get_filename_component (_${_PYTHON_PREFIX}_PATH2 "${_${_PYTHON_PREFIX}_PATH}" DIRECTORY)
-    _python_find_runtime_library (_${_PYTHON_PREFIX}_RUNTIME_LIBRARY_DEBUG
-                                  NAMES ${_${_PYTHON_PREFIX}_LIB_NAMES_DEBUG}
-                                  NAMES_PER_DIR
-                                  HINTS "${_${_PYTHON_PREFIX}_PATH}" "${_${_PYTHON_PREFIX}_PATH2}" ${_${_PYTHON_PREFIX}_HINTS}
-                                  PATH_SUFFIXES bin)
-  endif()
-
-  # Don't search for include dir if no library was founded
-  if (_${_PYTHON_PREFIX}_LIBRARY_RELEASE AND NOT _${_PYTHON_PREFIX}_INCLUDE_DIR)
-    if ((${_PYTHON_PREFIX}_Interpreter_FOUND AND NOT CMAKE_CROSSCOMPILING) OR _${_PYTHON_PREFIX}_CONFIG)
-      _python_get_config_var (_${_PYTHON_PREFIX}_INCLUDE_DIRS INCLUDES)
-
-      find_path (_${_PYTHON_PREFIX}_INCLUDE_DIR
-                 NAMES Python.h
-                 HINTS ${_${_PYTHON_PREFIX}_INCLUDE_DIRS}
-                 NO_SYSTEM_ENVIRONMENT_PATH
-                 NO_CMAKE_SYSTEM_PATH)
+    # finalize library version information
+    _python_get_version (LIBRARY PREFIX _${_PYTHON_PREFIX}_)
+    if (_${_PYTHON_PREFIX}_VERSION EQUAL "${_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR}")
+      # not able to extract full version from library name
+      if (${_PYTHON_PREFIX}_Interpreter_FOUND)
+        # update from interpreter
+        set (_${_PYTHON_PREFIX}_VERSION ${${_PYTHON_PREFIX}_VERSION})
+        set (_${_PYTHON_PREFIX}_VERSION_MAJOR ${${_PYTHON_PREFIX}_VERSION_MAJOR})
+        set (_${_PYTHON_PREFIX}_VERSION_MINOR ${${_PYTHON_PREFIX}_VERSION_MINOR})
+        set (_${_PYTHON_PREFIX}_VERSION_PATCH ${${_PYTHON_PREFIX}_VERSION_PATCH})
+      endif()
     endif()
 
-    # Rely on HINTS and standard paths if interpreter or config tool failed to locate artifacts
-    if (NOT _${_PYTHON_PREFIX}_INCLUDE_DIR)
-      unset (_${_PYTHON_PREFIX}_VIRTUALENV_PATHS)
-      if (_${_PYTHON_PREFIX}_FIND_VIRTUALENV MATCHES "^(FIRST|ONLY)$")
-        set (_${_PYTHON_PREFIX}_VIRTUALENV_PATHS ENV VIRTUAL_ENV ENV CONDA_PREFIX)
-      endif()
-      unset (_${_PYTHON_PREFIX}_INCLUDE_HINTS)
+    set (${_PYTHON_PREFIX}_LIBRARY_RELEASE "${_${_PYTHON_PREFIX}_LIBRARY_RELEASE}")
 
-      # Use the library's install prefix as a hint
-      if (${_${_PYTHON_PREFIX}_LIBRARY_RELEASE} MATCHES "^(.+/Frameworks/Python.framework/Versions/[0-9.]+)")
-        list (APPEND _${_PYTHON_PREFIX}_INCLUDE_HINTS "${CMAKE_MATCH_1}")
-      elseif (${_${_PYTHON_PREFIX}_LIBRARY_RELEASE} MATCHES "^(.+)/lib(64|32)?/python[0-9.]+/config")
-        list (APPEND _${_PYTHON_PREFIX}_INCLUDE_HINTS "${CMAKE_MATCH_1}")
-      elseif (DEFINED CMAKE_LIBRARY_ARCHITECTURE AND ${_${_PYTHON_PREFIX}_LIBRARY_RELEASE} MATCHES "^(.+)/lib/${CMAKE_LIBRARY_ARCHITECTURE}")
-        list (APPEND _${_PYTHON_PREFIX}_INCLUDE_HINTS "${CMAKE_MATCH_1}")
-      else()
-        # assume library is in a directory under root
-        get_filename_component (_${_PYTHON_PREFIX}_PREFIX "${_${_PYTHON_PREFIX}_LIBRARY_RELEASE}" DIRECTORY)
-        get_filename_component (_${_PYTHON_PREFIX}_PREFIX "${_${_PYTHON_PREFIX}_PREFIX}" DIRECTORY)
-        list (APPEND _${_PYTHON_PREFIX}_INCLUDE_HINTS "${_${_PYTHON_PREFIX}_PREFIX}")
-      endif()
-
-      _python_get_frameworks (_${_PYTHON_PREFIX}_FRAMEWORK_PATHS ${_${_PYTHON_PREFIX}_VERSION})
-      _python_get_registries (_${_PYTHON_PREFIX}_REGISTRY_PATHS ${_${_PYTHON_PREFIX}_VERSION})
-      _python_get_path_suffixes (_${_PYTHON_PREFIX}_PATH_SUFFIXES VERSION ${_${_PYTHON_PREFIX}_VERSION} INCLUDE)
-
-      if (APPLE AND _${_PYTHON_PREFIX}_FIND_FRAMEWORK STREQUAL "FIRST")
-        find_path (_${_PYTHON_PREFIX}_INCLUDE_DIR
-                   NAMES Python.h
-                   HINTS ${_${_PYTHON_PREFIX}_INCLUDE_HINTS} ${_${_PYTHON_PREFIX}_HINTS}
-                   PATHS ${_${_PYTHON_PREFIX}_VIRTUALENV_PATHS}
-                         ${_${_PYTHON_PREFIX}_FRAMEWORK_PATHS}
-                   PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES}
-                   NO_CMAKE_PATH
-                   NO_CMAKE_ENVIRONMENT_PATH
-                   NO_SYSTEM_ENVIRONMENT_PATH
-                   NO_CMAKE_SYSTEM_PATH)
-      endif()
-
-      if (WIN32 AND _${_PYTHON_PREFIX}_FIND_REGISTRY STREQUAL "FIRST")
-        find_path (_${_PYTHON_PREFIX}_INCLUDE_DIR
-                   NAMES Python.h
-                   HINTS ${_${_PYTHON_PREFIX}_INCLUDE_HINTS} ${_${_PYTHON_PREFIX}_HINTS}
-                   PATHS ${_${_PYTHON_PREFIX}_VIRTUALENV_PATHS}
-                         ${_${_PYTHON_PREFIX}_REGISTRY_PATHS}
-                   PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES}
-                   NO_SYSTEM_ENVIRONMENT_PATH
-                   NO_CMAKE_SYSTEM_PATH)
-      endif()
-
-      if (APPLE AND _${_PYTHON_PREFIX}_FIND_FRAMEWORK STREQUAL "LAST")
-        set (__${_PYTHON_PREFIX}_FRAMEWORK_PATHS ${_${_PYTHON_PREFIX}_FRAMEWORK_PATHS})
-      else()
-        unset (__${_PYTHON_PREFIX}_FRAMEWORK_PATHS)
-      endif()
-
-      if (WIN32 AND _${_PYTHON_PREFIX}_FIND_REGISTRY STREQUAL "LAST")
-        set (__${_PYTHON_PREFIX}_REGISTRY_PATHS ${_${_PYTHON_PREFIX}_REGISTRY_PATHS})
-      else()
-        unset (__${_PYTHON_PREFIX}_REGISTRY_PATHS)
-      endif()
-
-      find_path (_${_PYTHON_PREFIX}_INCLUDE_DIR
-                 NAMES Python.h
-                 HINTS ${_${_PYTHON_PREFIX}_INCLUDE_HINTS} ${_${_PYTHON_PREFIX}_HINTS}
-                 PATHS ${_${_PYTHON_PREFIX}_VIRTUALENV_PATHS}
-                       ${__${_PYTHON_PREFIX}_FRAMEWORK_PATHS}
-                       ${__${_PYTHON_PREFIX}_REGISTRY_PATHS}
-                 PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES}
-                 NO_SYSTEM_ENVIRONMENT_PATH
-                 NO_CMAKE_SYSTEM_PATH)
+    if (_${_PYTHON_PREFIX}_LIBRARY_RELEASE AND NOT EXISTS "${_${_PYTHON_PREFIX}_LIBRARY_RELEASE}")
+      set (_${_PYTHON_PREFIX}_Development_REASON_FAILURE "Cannot find the library \"${_${_PYTHON_PREFIX}_LIBRARY_RELEASE}\"")
+      set_property (CACHE _${_PYTHON_PREFIX}_LIBRARY_RELEASE PROPERTY VALUE "${_PYTHON_PREFIX}_LIBRARY_RELEASE-NOTFOUND")
     endif()
 
-    # search header file in standard locations
-    find_path (_${_PYTHON_PREFIX}_INCLUDE_DIR
-               NAMES Python.h)
-  endif()
+    set (_${_PYTHON_PREFIX}_HINTS "${${_PYTHON_PREFIX}_ROOT_DIR}" ENV ${_PYTHON_PREFIX}_ROOT_DIR)
 
-  set (${_PYTHON_PREFIX}_INCLUDE_DIRS "${_${_PYTHON_PREFIX}_INCLUDE_DIR}")
+    if (WIN32 AND _${_PYTHON_PREFIX}_LIBRARY_RELEASE)
+      # search for debug library
+      # use release library location as a hint
+      _python_get_names (_${_PYTHON_PREFIX}_LIB_NAMES_DEBUG VERSION ${_${_PYTHON_PREFIX}_VERSION} WIN32 DEBUG)
+      get_filename_component (_${_PYTHON_PREFIX}_PATH "${_${_PYTHON_PREFIX}_LIBRARY_RELEASE}" DIRECTORY)
+      find_library (_${_PYTHON_PREFIX}_LIBRARY_DEBUG
+                    NAMES ${_${_PYTHON_PREFIX}_LIB_NAMES_DEBUG}
+                    NAMES_PER_DIR
+                    HINTS "${_${_PYTHON_PREFIX}_PATH}" ${_${_PYTHON_PREFIX}_HINTS}
+                    NO_DEFAULT_PATH)
+      # second try including CMAKE variables to catch-up non conventional layouts
+      find_library (_${_PYTHON_PREFIX}_LIBRARY_DEBUG
+                    NAMES ${_${_PYTHON_PREFIX}_LIB_NAMES_DEBUG}
+                    NAMES_PER_DIR
+                    NO_SYSTEM_ENVIRONMENT_PATH
+                    NO_CMAKE_SYSTEM_PATH)
+    endif()
 
-  if (_${_PYTHON_PREFIX}_INCLUDE_DIR AND NOT EXISTS "${_${_PYTHON_PREFIX}_INCLUDE_DIR}")
-    set (_${_PYTHON_PREFIX}_Development_REASON_FAILURE "Cannot find the directory \"${_${_PYTHON_PREFIX}_INCLUDE_DIR}\"")
-    set_property (CACHE _${_PYTHON_PREFIX}_INCLUDE_DIR PROPERTY VALUE "${_PYTHON_PREFIX}_INCLUDE_DIR-NOTFOUND")
-  endif()
-
-  if (_${_PYTHON_PREFIX}_INCLUDE_DIR)
-    # retrieve version from header file
-    _python_get_version (INCLUDE PREFIX _${_PYTHON_PREFIX}_INC_)
-
+    # retrieve runtime libraries
     if (_${_PYTHON_PREFIX}_LIBRARY_RELEASE)
-      if ("${_${_PYTHON_PREFIX}_INC_VERSION_MAJOR}.${_${_PYTHON_PREFIX}_INC_VERSION_MINOR}"
-          VERSION_EQUAL _${_PYTHON_PREFIX}_VERSION)
-        # update versioning
+      _python_get_names (_${_PYTHON_PREFIX}_LIB_NAMES VERSION ${_${_PYTHON_PREFIX}_VERSION} WIN32 POSIX LIBRARY)
+      get_filename_component (_${_PYTHON_PREFIX}_PATH "${_${_PYTHON_PREFIX}_LIBRARY_RELEASE}" DIRECTORY)
+      get_filename_component (_${_PYTHON_PREFIX}_PATH2 "${_${_PYTHON_PREFIX}_PATH}" DIRECTORY)
+      _python_find_runtime_library (_${_PYTHON_PREFIX}_RUNTIME_LIBRARY_RELEASE
+                                    NAMES ${_${_PYTHON_PREFIX}_LIB_NAMES}
+                                    NAMES_PER_DIR
+                                    HINTS "${_${_PYTHON_PREFIX}_PATH}"
+                                          "${_${_PYTHON_PREFIX}_PATH2}" ${_${_PYTHON_PREFIX}_HINTS}
+                                    PATH_SUFFIXES bin)
+    endif()
+    if (_${_PYTHON_PREFIX}_LIBRARY_DEBUG)
+      _python_get_names (_${_PYTHON_PREFIX}_LIB_NAMES_DEBUG VERSION ${_${_PYTHON_PREFIX}_VERSION} WIN32 DEBUG)
+      get_filename_component (_${_PYTHON_PREFIX}_PATH "${_${_PYTHON_PREFIX}_LIBRARY_DEBUG}" DIRECTORY)
+      get_filename_component (_${_PYTHON_PREFIX}_PATH2 "${_${_PYTHON_PREFIX}_PATH}" DIRECTORY)
+      _python_find_runtime_library (_${_PYTHON_PREFIX}_RUNTIME_LIBRARY_DEBUG
+                                    NAMES ${_${_PYTHON_PREFIX}_LIB_NAMES_DEBUG}
+                                    NAMES_PER_DIR
+                                    HINTS "${_${_PYTHON_PREFIX}_PATH}"
+                                          "${_${_PYTHON_PREFIX}_PATH2}" ${_${_PYTHON_PREFIX}_HINTS}
+                                    PATH_SUFFIXES bin)
+    endif()
+  endif()
+
+  if ("INCLUDE_DIR" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_ARTIFACTS)
+    while (NOT _${_PYTHON_PREFIX}_INCLUDE_DIR)
+      if ("LIBRARY" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_ARTIFACTS
+          AND NOT _${_PYTHON_PREFIX}_LIBRARY_RELEASE)
+        # Don't search for include dir if no library was founded
+        break()
+      endif()
+
+      if ((${_PYTHON_PREFIX}_Interpreter_FOUND AND NOT CMAKE_CROSSCOMPILING) OR _${_PYTHON_PREFIX}_CONFIG)
+        _python_get_config_var (_${_PYTHON_PREFIX}_INCLUDE_DIRS INCLUDES)
+
+        find_path (_${_PYTHON_PREFIX}_INCLUDE_DIR
+                   NAMES ${_${_PYTHON_PREFIX}_INCLUDE_NAMES}
+                   HINTS ${_${_PYTHON_PREFIX}_INCLUDE_DIRS}
+                   NO_SYSTEM_ENVIRONMENT_PATH
+                   NO_CMAKE_SYSTEM_PATH)
+      endif()
+
+      # Rely on HINTS and standard paths if interpreter or config tool failed to locate artifacts
+      if (NOT _${_PYTHON_PREFIX}_INCLUDE_DIR)
+        unset (_${_PYTHON_PREFIX}_VIRTUALENV_PATHS)
+        if (_${_PYTHON_PREFIX}_FIND_VIRTUALENV MATCHES "^(FIRST|ONLY)$")
+          set (_${_PYTHON_PREFIX}_VIRTUALENV_PATHS ENV VIRTUAL_ENV ENV CONDA_PREFIX)
+        endif()
+        unset (_${_PYTHON_PREFIX}_INCLUDE_HINTS)
+
+        if (_${_PYTHON_PREFIX}_LIBRARY_RELEASE)
+          # Use the library's install prefix as a hint
+          if (_${_PYTHON_PREFIX}_LIBRARY_RELEASE MATCHES "^(.+/Frameworks/Python.framework/Versions/[0-9.]+)")
+            list (APPEND _${_PYTHON_PREFIX}_INCLUDE_HINTS "${CMAKE_MATCH_1}")
+          elseif (_${_PYTHON_PREFIX}_LIBRARY_RELEASE MATCHES "^(.+)/lib(64|32)?/python[0-9.]+/config")
+            list (APPEND _${_PYTHON_PREFIX}_INCLUDE_HINTS "${CMAKE_MATCH_1}")
+          elseif (DEFINED CMAKE_LIBRARY_ARCHITECTURE AND ${_${_PYTHON_PREFIX}_LIBRARY_RELEASE} MATCHES "^(.+)/lib/${CMAKE_LIBRARY_ARCHITECTURE}")
+            list (APPEND _${_PYTHON_PREFIX}_INCLUDE_HINTS "${CMAKE_MATCH_1}")
+          else()
+            # assume library is in a directory under root
+            get_filename_component (_${_PYTHON_PREFIX}_PREFIX "${_${_PYTHON_PREFIX}_LIBRARY_RELEASE}" DIRECTORY)
+            get_filename_component (_${_PYTHON_PREFIX}_PREFIX "${_${_PYTHON_PREFIX}_PREFIX}" DIRECTORY)
+            list (APPEND _${_PYTHON_PREFIX}_INCLUDE_HINTS "${_${_PYTHON_PREFIX}_PREFIX}")
+          endif()
+        endif()
+
+        _python_get_frameworks (_${_PYTHON_PREFIX}_FRAMEWORK_PATHS VERSION ${_${_PYTHON_PREFIX}_VERSION})
+        _python_get_registries (_${_PYTHON_PREFIX}_REGISTRY_PATHS VERSION ${_${_PYTHON_PREFIX}_VERSION})
+        _python_get_path_suffixes (_${_PYTHON_PREFIX}_PATH_SUFFIXES VERSION ${_${_PYTHON_PREFIX}_VERSION} INCLUDE)
+
+        if (APPLE AND _${_PYTHON_PREFIX}_FIND_FRAMEWORK STREQUAL "FIRST")
+          find_path (_${_PYTHON_PREFIX}_INCLUDE_DIR
+                     NAMES ${_${_PYTHON_PREFIX}_INCLUDE_NAMES}
+                     HINTS ${_${_PYTHON_PREFIX}_INCLUDE_HINTS} ${_${_PYTHON_PREFIX}_HINTS}
+                     PATHS ${_${_PYTHON_PREFIX}_VIRTUALENV_PATHS}
+                           ${_${_PYTHON_PREFIX}_FRAMEWORK_PATHS}
+                     PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES}
+                     NO_CMAKE_PATH
+                     NO_CMAKE_ENVIRONMENT_PATH
+                     NO_SYSTEM_ENVIRONMENT_PATH
+                     NO_CMAKE_SYSTEM_PATH)
+        endif()
+
+        if (WIN32 AND _${_PYTHON_PREFIX}_FIND_REGISTRY STREQUAL "FIRST")
+          find_path (_${_PYTHON_PREFIX}_INCLUDE_DIR
+                     NAMES ${_${_PYTHON_PREFIX}_INCLUDE_NAMES}
+                     HINTS ${_${_PYTHON_PREFIX}_INCLUDE_HINTS} ${_${_PYTHON_PREFIX}_HINTS}
+                     PATHS ${_${_PYTHON_PREFIX}_VIRTUALENV_PATHS}
+                           ${_${_PYTHON_PREFIX}_REGISTRY_PATHS}
+                     PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES}
+                     NO_SYSTEM_ENVIRONMENT_PATH
+                     NO_CMAKE_SYSTEM_PATH)
+        endif()
+
+        if (APPLE AND _${_PYTHON_PREFIX}_FIND_FRAMEWORK STREQUAL "LAST")
+          set (__${_PYTHON_PREFIX}_FRAMEWORK_PATHS ${_${_PYTHON_PREFIX}_FRAMEWORK_PATHS})
+        else()
+          unset (__${_PYTHON_PREFIX}_FRAMEWORK_PATHS)
+        endif()
+
+        if (WIN32 AND _${_PYTHON_PREFIX}_FIND_REGISTRY STREQUAL "LAST")
+          set (__${_PYTHON_PREFIX}_REGISTRY_PATHS ${_${_PYTHON_PREFIX}_REGISTRY_PATHS})
+        else()
+          unset (__${_PYTHON_PREFIX}_REGISTRY_PATHS)
+        endif()
+
+        find_path (_${_PYTHON_PREFIX}_INCLUDE_DIR
+                   NAMES ${_${_PYTHON_PREFIX}_INCLUDE_NAMES}
+                   HINTS ${_${_PYTHON_PREFIX}_INCLUDE_HINTS} ${_${_PYTHON_PREFIX}_HINTS}
+                   PATHS ${_${_PYTHON_PREFIX}_VIRTUALENV_PATHS}
+                         ${__${_PYTHON_PREFIX}_FRAMEWORK_PATHS}
+                         ${__${_PYTHON_PREFIX}_REGISTRY_PATHS}
+                   PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES}
+                   NO_SYSTEM_ENVIRONMENT_PATH
+                   NO_CMAKE_SYSTEM_PATH)
+      endif()
+
+      # search header file in standard locations
+      find_path (_${_PYTHON_PREFIX}_INCLUDE_DIR
+                 NAMES ${_${_PYTHON_PREFIX}_INCLUDE_NAMES})
+
+      break()
+    endwhile()
+
+    set (${_PYTHON_PREFIX}_INCLUDE_DIRS "${_${_PYTHON_PREFIX}_INCLUDE_DIR}")
+
+    if (_${_PYTHON_PREFIX}_INCLUDE_DIR AND NOT EXISTS "${_${_PYTHON_PREFIX}_INCLUDE_DIR}")
+      set (_${_PYTHON_PREFIX}_Development_REASON_FAILURE "Cannot find the directory \"${_${_PYTHON_PREFIX}_INCLUDE_DIR}\"")
+      set_property (CACHE _${_PYTHON_PREFIX}_INCLUDE_DIR PROPERTY VALUE "${_PYTHON_PREFIX}_INCLUDE_DIR-NOTFOUND")
+    endif()
+
+    if (_${_PYTHON_PREFIX}_INCLUDE_DIR)
+      # retrieve version from header file
+      _python_get_version (INCLUDE PREFIX _${_PYTHON_PREFIX}_INC_)
+
+      if (_${_PYTHON_PREFIX}_LIBRARY_RELEASE)
+        if ("${_${_PYTHON_PREFIX}_INC_VERSION_MAJOR}.${_${_PYTHON_PREFIX}_INC_VERSION_MINOR}"
+            VERSION_EQUAL _${_PYTHON_PREFIX}_VERSION)
+          # update versioning
+          set (_${_PYTHON_PREFIX}_VERSION ${_${_PYTHON_PREFIX}_INC_VERSION})
+          set (_${_PYTHON_PREFIX}_VERSION_PATCH ${_${_PYTHON_PREFIX}_INC_VERSION_PATCH})
+        endif()
+      else()
         set (_${_PYTHON_PREFIX}_VERSION ${_${_PYTHON_PREFIX}_INC_VERSION})
+        set (_${_PYTHON_PREFIX}_VERSION_MAJOR ${_${_PYTHON_PREFIX}_INC_VERSION_MAJOR})
+        set (_${_PYTHON_PREFIX}_VERSION_MINOR ${_${_PYTHON_PREFIX}_INC_VERSION_MINOR})
         set (_${_PYTHON_PREFIX}_VERSION_PATCH ${_${_PYTHON_PREFIX}_INC_VERSION_PATCH})
       endif()
-    else()
-      # library is not defined, rely on header for version
-      set (_${_PYTHON_PREFIX}_VERSION ${_${_PYTHON_PREFIX}_INC_VERSION})
-      set (_${_PYTHON_PREFIX}_VERSION_MAJOR ${_${_PYTHON_PREFIX}_INC_VERSION_MAJOR})
-      set (_${_PYTHON_PREFIX}_VERSION_MINOR ${_${_PYTHON_PREFIX}_INC_VERSION_MINOR})
-      set (_${_PYTHON_PREFIX}_VERSION_PATCH ${_${_PYTHON_PREFIX}_INC_VERSION_PATCH})
     endif()
   endif()
 
@@ -2275,74 +2766,111 @@
   endif()
 
   # define public variables
-  set (${_PYTHON_PREFIX}_LIBRARY_DEBUG "${_${_PYTHON_PREFIX}_LIBRARY_DEBUG}")
-  _python_select_library_configurations (${_PYTHON_PREFIX})
+  if ("LIBRARY" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_ARTIFACTS)
+    set (${_PYTHON_PREFIX}_LIBRARY_DEBUG "${_${_PYTHON_PREFIX}_LIBRARY_DEBUG}")
+    _python_select_library_configurations (${_PYTHON_PREFIX})
 
-  set (${_PYTHON_PREFIX}_RUNTIME_LIBRARY_RELEASE "${_${_PYTHON_PREFIX}_RUNTIME_LIBRARY_RELEASE}")
-  set (${_PYTHON_PREFIX}_RUNTIME_LIBRARY_DEBUG "${_${_PYTHON_PREFIX}_RUNTIME_LIBRARY_DEBUG}")
+    set (${_PYTHON_PREFIX}_RUNTIME_LIBRARY_RELEASE "${_${_PYTHON_PREFIX}_RUNTIME_LIBRARY_RELEASE}")
+    set (${_PYTHON_PREFIX}_RUNTIME_LIBRARY_DEBUG "${_${_PYTHON_PREFIX}_RUNTIME_LIBRARY_DEBUG}")
 
-  if (_${_PYTHON_PREFIX}_RUNTIME_LIBRARY_RELEASE)
-    set (${_PYTHON_PREFIX}_RUNTIME_LIBRARY "${_${_PYTHON_PREFIX}_RUNTIME_LIBRARY_RELEASE}")
-  elseif (_${_PYTHON_PREFIX}_RUNTIME_LIBRARY_DEBUG)
-    set (${_PYTHON_PREFIX}_RUNTIME_LIBRARY "${_${_PYTHON_PREFIX}_RUNTIME_LIBRARY_DEBUG}")
-  else()
-    set (${_PYTHON_PREFIX}_RUNTIME_LIBRARY "${_PYTHON_PREFIX}_RUNTIME_LIBRARY-NOTFOUND")
-  endif()
-
-  _python_set_library_dirs (${_PYTHON_PREFIX}_LIBRARY_DIRS
-                            _${_PYTHON_PREFIX}_LIBRARY_RELEASE _${_PYTHON_PREFIX}_LIBRARY_DEBUG)
-  if (UNIX)
-    if (_${_PYTHON_PREFIX}_LIBRARY_RELEASE MATCHES "${CMAKE_SHARED_LIBRARY_SUFFIX}$")
-      set (${_PYTHON_PREFIX}_RUNTIME_LIBRARY_DIRS ${${_PYTHON_PREFIX}_LIBRARY_DIRS})
+    if (_${_PYTHON_PREFIX}_RUNTIME_LIBRARY_RELEASE)
+      set (${_PYTHON_PREFIX}_RUNTIME_LIBRARY "${_${_PYTHON_PREFIX}_RUNTIME_LIBRARY_RELEASE}")
+    elseif (_${_PYTHON_PREFIX}_RUNTIME_LIBRARY_DEBUG)
+      set (${_PYTHON_PREFIX}_RUNTIME_LIBRARY "${_${_PYTHON_PREFIX}_RUNTIME_LIBRARY_DEBUG}")
+    else()
+      set (${_PYTHON_PREFIX}_RUNTIME_LIBRARY "${_PYTHON_PREFIX}_RUNTIME_LIBRARY-NOTFOUND")
     endif()
-  else()
+
+    _python_set_library_dirs (${_PYTHON_PREFIX}_LIBRARY_DIRS
+                              _${_PYTHON_PREFIX}_LIBRARY_RELEASE
+                              _${_PYTHON_PREFIX}_LIBRARY_DEBUG)
+    if (UNIX)
+      if (_${_PYTHON_PREFIX}_LIBRARY_RELEASE MATCHES "${CMAKE_SHARED_LIBRARY_SUFFIX}$")
+        set (${_PYTHON_PREFIX}_RUNTIME_LIBRARY_DIRS ${${_PYTHON_PREFIX}_LIBRARY_DIRS})
+      endif()
+    else()
       _python_set_library_dirs (${_PYTHON_PREFIX}_RUNTIME_LIBRARY_DIRS
-                                _${_PYTHON_PREFIX}_RUNTIME_LIBRARY_RELEASE _${_PYTHON_PREFIX}_RUNTIME_LIBRARY_DEBUG)
+                                _${_PYTHON_PREFIX}_RUNTIME_LIBRARY_RELEASE
+                                _${_PYTHON_PREFIX}_RUNTIME_LIBRARY_DEBUG)
+    endif()
   endif()
 
-  if (_${_PYTHON_PREFIX}_LIBRARY_RELEASE AND _${_PYTHON_PREFIX}_INCLUDE_DIR)
+  if (_${_PYTHON_PREFIX}_LIBRARY_RELEASE OR _${_PYTHON_PREFIX}_INCLUDE_DIR)
     if (${_PYTHON_PREFIX}_Interpreter_FOUND OR ${_PYTHON_PREFIX}_Compiler_FOUND)
       # development environment must be compatible with interpreter/compiler
       if ("${_${_PYTHON_PREFIX}_VERSION_MAJOR}.${_${_PYTHON_PREFIX}_VERSION_MINOR}" VERSION_EQUAL "${${_PYTHON_PREFIX}_VERSION_MAJOR}.${${_PYTHON_PREFIX}_VERSION_MINOR}"
           AND "${_${_PYTHON_PREFIX}_INC_VERSION_MAJOR}.${_${_PYTHON_PREFIX}_INC_VERSION_MINOR}" VERSION_EQUAL "${_${_PYTHON_PREFIX}_VERSION_MAJOR}.${_${_PYTHON_PREFIX}_VERSION_MINOR}")
-        set (${_PYTHON_PREFIX}_Development_FOUND TRUE)
+        _python_set_development_module_found (Module)
+        _python_set_development_module_found (Embed)
       endif()
     elseif (${_PYTHON_PREFIX}_VERSION_MAJOR VERSION_EQUAL _${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR
-            AND "${_${_PYTHON_PREFIX}_INC_VERSION_MAJOR}.${_${_PYTHON_PREFIX}_INC_VERSION_MINOR}" VERSION_EQUAL "${_${_PYTHON_PREFIX}_VERSION_MAJOR}.${_${_PYTHON_PREFIX}_VERSION_MINOR}")
-      set (${_PYTHON_PREFIX}_Development_FOUND TRUE)
+        AND "${_${_PYTHON_PREFIX}_INC_VERSION_MAJOR}.${_${_PYTHON_PREFIX}_INC_VERSION_MINOR}" VERSION_EQUAL "${_${_PYTHON_PREFIX}_VERSION_MAJOR}.${_${_PYTHON_PREFIX}_VERSION_MINOR}")
+      _python_set_development_module_found (Module)
+      _python_set_development_module_found (Embed)
     endif()
     if (DEFINED _${_PYTHON_PREFIX}_FIND_ABI AND
         (NOT _${_PYTHON_PREFIX}_ABI IN_LIST _${_PYTHON_PREFIX}_ABIFLAGS
           OR NOT _${_PYTHON_PREFIX}_INC_ABI IN_LIST _${_PYTHON_PREFIX}_ABIFLAGS))
-      set (${_PYTHON_PREFIX}_Development_FOUND FALSE)
+      set (${_PYTHON_PREFIX}_Development.Module_FOUND FALSE)
+      set (${_PYTHON_PREFIX}_Development.Embed_FOUND FALSE)
     endif()
   endif()
 
+  if (( ${_PYTHON_PREFIX}_Development.Module_FOUND
+        AND ${_PYTHON_PREFIX}_Development.Embed_FOUND)
+      OR (NOT "Development.Module" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS
+        AND ${_PYTHON_PREFIX}_Development.Embed_FOUND)
+      OR (NOT "Development.Embed" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS
+        AND ${_PYTHON_PREFIX}_Development.Module_FOUND))
+    unset (_${_PYTHON_PREFIX}_Development_REASON_FAILURE)
+  endif()
+
+  if ("Development" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS
+      AND ${_PYTHON_PREFIX}_Development.Module_FOUND
+      AND ${_PYTHON_PREFIX}_Development.Embed_FOUND)
+    set (${_PYTHON_PREFIX}_Development_FOUND TRUE)
+  endif()
+
+  if ((${_PYTHON_PREFIX}_Development.Module_FOUND
+      OR ${_PYTHON_PREFIX}_Development.Embed_FOUND)
+    AND EXISTS "${_${_PYTHON_PREFIX}_INCLUDE_DIR}/PyPy.h")
+  # retrieve PyPy version
+  file (STRINGS "${_${_PYTHON_PREFIX}_INCLUDE_DIR}/patchlevel.h" ${_PYTHON_PREFIX}_PyPy_VERSION
+                REGEX "^#define[ \t]+PYPY_VERSION[ \t]+\"[^\"]+\"")
+  string (REGEX REPLACE "^#define[ \t]+PYPY_VERSION[ \t]+\"([^\"]+)\".*" "\\1"
+                ${_PYTHON_PREFIX}_PyPy_VERSION "${${_PYTHON_PREFIX}_PyPy_VERSION}")
+  endif()
+
   if (_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR VERSION_GREATER_EQUAL "3"
       AND NOT DEFINED ${_PYTHON_PREFIX}_SOABI)
     _python_get_config_var (${_PYTHON_PREFIX}_SOABI SOABI)
   endif()
 
-  if (${_PYTHON_PREFIX}_Development_FOUND)
-    # compute and save development signature
-    string (MD5 __${_PYTHON_PREFIX}_DEVELOPMENT_SIGNATURE "${_${_PYTHON_PREFIX}_SIGNATURE}:${_${_PYTHON_PREFIX}_LIBRARY_RELEASE}:${_${_PYTHON_PREFIX}_INCLUDE_DIR}")
-    set (_${_PYTHON_PREFIX}_DEVELOPMENT_SIGNATURE "${__${_PYTHON_PREFIX}_DEVELOPMENT_SIGNATURE}" CACHE INTERNAL "")
-  else()
-    unset (_${_PYTHON_PREFIX}_DEVELOPMENT_SIGNATURE CACHE)
-  endif()
+  _python_compute_development_signature (Module)
+  _python_compute_development_signature (Embed)
 
   # Restore the original find library ordering
   if (DEFINED _${_PYTHON_PREFIX}_CMAKE_FIND_LIBRARY_SUFFIXES)
     set (CMAKE_FIND_LIBRARY_SUFFIXES ${_${_PYTHON_PREFIX}_CMAKE_FIND_LIBRARY_SUFFIXES})
   endif()
 
+  if (${_PYTHON_PREFIX}_ARTIFACTS_INTERACTIVE)
+    if ("LIBRARY" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_ARTIFACTS)
+      set (${_PYTHON_PREFIX}_LIBRARY "${_${_PYTHON_PREFIX}_LIBRARY_RELEASE}" CACHE FILEPATH "${_PYTHON_PREFIX} Library")
+    endif()
+    if ("INCLUDE_DIR" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_ARTIFACTS)
+      set (${_PYTHON_PREFIX}_INCLUDE_DIR "${_${_PYTHON_PREFIX}_INCLUDE_DIR}" CACHE FILEPATH "${_PYTHON_PREFIX} Include Directory")
+    endif()
+  endif()
+
   _python_mark_as_internal (_${_PYTHON_PREFIX}_LIBRARY_RELEASE
                             _${_PYTHON_PREFIX}_LIBRARY_DEBUG
                             _${_PYTHON_PREFIX}_RUNTIME_LIBRARY_RELEASE
                             _${_PYTHON_PREFIX}_RUNTIME_LIBRARY_DEBUG
                             _${_PYTHON_PREFIX}_INCLUDE_DIR
                             _${_PYTHON_PREFIX}_CONFIG
-                            _${_PYTHON_PREFIX}_DEVELOPMENT_SIGNATURE)
+                            _${_PYTHON_PREFIX}_DEVELOPMENT_MODULE_SIGNATURE
+                            _${_PYTHON_PREFIX}_DEVELOPMENT_EMBED_SIGNATURE)
 endif()
 
 if (${_PYTHON_PREFIX}_FIND_REQUIRED_NumPy)
@@ -2356,7 +2884,7 @@
     set (_${_PYTHON_PREFIX}_NumPy_INCLUDE_DIR "${${_PYTHON_PREFIX}_NumPy_INCLUDE_DIR}" CACHE INTERNAL "")
   elseif (DEFINED _${_PYTHON_PREFIX}_NumPy_INCLUDE_DIR)
     # compute numpy signature. Depends on interpreter and development signatures
-    string (MD5 __${_PYTHON_PREFIX}_NUMPY_SIGNATURE "${_${_PYTHON_PREFIX}_INTERPRETER_SIGNATURE}:${_${_PYTHON_PREFIX}_DEVELOPMENT_SIGNATURE}:${_${_PYTHON_PREFIX}_NumPy_INCLUDE_DIR}")
+    string (MD5 __${_PYTHON_PREFIX}_NUMPY_SIGNATURE "${_${_PYTHON_PREFIX}_INTERPRETER_SIGNATURE}:${_${_PYTHON_PREFIX}_DEVELOPMENT_MODULE_SIGNATURE}:${_${_PYTHON_PREFIX}_NumPy_INCLUDE_DIR}")
     if (NOT __${_PYTHON_PREFIX}_NUMPY_SIGNATURE STREQUAL _${_PYTHON_PREFIX}_NUMPY_SIGNATURE
         OR NOT EXISTS "${_${_PYTHON_PREFIX}_NumPy_INCLUDE_DIR}")
       unset (_${_PYTHON_PREFIX}_NumPy_INCLUDE_DIR CACHE)
@@ -2365,13 +2893,12 @@
   endif()
 
   if (NOT _${_PYTHON_PREFIX}_NumPy_INCLUDE_DIR)
-    execute_process(
-      COMMAND "${${_PYTHON_PREFIX}_EXECUTABLE}" -c
-              "from __future__ import print_function\ntry: import numpy; print(numpy.get_include(), end='')\nexcept:pass\n"
-      RESULT_VARIABLE _${_PYTHON_PREFIX}_RESULT
-      OUTPUT_VARIABLE _${_PYTHON_PREFIX}_NumPy_PATH
-      ERROR_QUIET
-      OUTPUT_STRIP_TRAILING_WHITESPACE)
+    execute_process(COMMAND ${${_PYTHON_PREFIX}_INTERPRETER_LAUNCHER} "${_${_PYTHON_PREFIX}_EXECUTABLE}" -c
+                            "import sys\ntry: import numpy; sys.stdout.write(numpy.get_include())\nexcept:pass\n"
+                    RESULT_VARIABLE _${_PYTHON_PREFIX}_RESULT
+                    OUTPUT_VARIABLE _${_PYTHON_PREFIX}_NumPy_PATH
+                    ERROR_QUIET
+                    OUTPUT_STRIP_TRAILING_WHITESPACE)
 
     if (NOT _${_PYTHON_PREFIX}_RESULT)
       find_path (_${_PYTHON_PREFIX}_NumPy_INCLUDE_DIR
@@ -2389,31 +2916,36 @@
   endif()
 
   if (_${_PYTHON_PREFIX}_NumPy_INCLUDE_DIR)
-    execute_process (
-            COMMAND "${${_PYTHON_PREFIX}_EXECUTABLE}" -c
-            "from __future__ import print_function\ntry: import numpy; print(numpy.__version__, end='')\nexcept:pass\n"
-            RESULT_VARIABLE _${_PYTHON_PREFIX}_RESULT
-            OUTPUT_VARIABLE _${_PYTHON_PREFIX}_NumPy_VERSION)
+    execute_process (COMMAND ${${_PYTHON_PREFIX}_INTERPRETER_LAUNCHER} "${_${_PYTHON_PREFIX}_EXECUTABLE}" -c
+                             "import sys\ntry: import numpy; sys.stdout.write(numpy.__version__)\nexcept:pass\n"
+                     RESULT_VARIABLE _${_PYTHON_PREFIX}_RESULT
+                     OUTPUT_VARIABLE _${_PYTHON_PREFIX}_NumPy_VERSION)
     if (NOT _${_PYTHON_PREFIX}_RESULT)
       set (${_PYTHON_PREFIX}_NumPy_VERSION "${_${_PYTHON_PREFIX}_NumPy_VERSION}")
     else()
       unset (${_PYTHON_PREFIX}_NumPy_VERSION)
     endif()
 
-    # final step: set NumPy founded only if Development component is founded as well
-    set(${_PYTHON_PREFIX}_NumPy_FOUND ${${_PYTHON_PREFIX}_Development_FOUND})
+    # final step: set NumPy founded only if Development.Module component is founded as well
+    set(${_PYTHON_PREFIX}_NumPy_FOUND ${${_PYTHON_PREFIX}_Development.Module_FOUND})
   else()
     set (${_PYTHON_PREFIX}_NumPy_FOUND FALSE)
   endif()
 
   if (${_PYTHON_PREFIX}_NumPy_FOUND)
+    unset (_${_PYTHON_PREFIX}_NumPy_REASON_FAILURE)
+
     # compute and save numpy signature
-    string (MD5 __${_PYTHON_PREFIX}_NUMPY_SIGNATURE "${_${_PYTHON_PREFIX}_INTERPRETER_SIGNATURE}:${_${_PYTHON_PREFIX}_DEVELOPMENT_SIGNATURE}:${${_PYTHON_PREFIX}_NumPyINCLUDE_DIR}")
+    string (MD5 __${_PYTHON_PREFIX}_NUMPY_SIGNATURE "${_${_PYTHON_PREFIX}_INTERPRETER_SIGNATURE}:${_${_PYTHON_PREFIX}_DEVELOPMENT_MODULE_SIGNATURE}:${${_PYTHON_PREFIX}_NumPyINCLUDE_DIR}")
     set (_${_PYTHON_PREFIX}_NUMPY_SIGNATURE "${__${_PYTHON_PREFIX}_NUMPY_SIGNATURE}" CACHE INTERNAL "")
   else()
     unset (_${_PYTHON_PREFIX}_NUMPY_SIGNATURE CACHE)
   endif()
 
+  if (${_PYTHON_PREFIX}_ARTIFACTS_INTERACTIVE)
+    set (${_PYTHON_PREFIX}_NumPy_INCLUDE_DIR "${_${_PYTHON_PREFIX}_NumPy_INCLUDE_DIR}" CACHE FILEPATH "${_PYTHON_PREFIX} NumPy Include Directory")
+  endif()
+
   _python_mark_as_internal (_${_PYTHON_PREFIX}_NumPy_INCLUDE_DIR
                             _${_PYTHON_PREFIX}_NUMPY_SIGNATURE)
 endif()
@@ -2426,11 +2958,10 @@
 
 unset (_${_PYTHON_PREFIX}_REASON_FAILURE)
 foreach (_${_PYTHON_PREFIX}_COMPONENT IN ITEMS Interpreter Compiler Development NumPy)
-  if (NOT ${_PYTHON_PREFIX}_${_${_PYTHON_PREFIX}_COMPONENT}_FOUND
-      AND _${_PYTHON_PREFIX}_${_${_PYTHON_PREFIX}_COMPONENT}_REASON_FAILURE)
+  if (_${_PYTHON_PREFIX}_${_${_PYTHON_PREFIX}_COMPONENT}_REASON_FAILURE)
     string (APPEND _${_PYTHON_PREFIX}_REASON_FAILURE "\n        ${_${_PYTHON_PREFIX}_COMPONENT}: ${_${_PYTHON_PREFIX}_${_${_PYTHON_PREFIX}_COMPONENT}_REASON_FAILURE}")
+    unset (_${_PYTHON_PREFIX}_${_${_PYTHON_PREFIX}_COMPONENT}_REASON_FAILURE)
   endif()
-  unset (_${_PYTHON_PREFIX}_${_${_PYTHON_PREFIX}_COMPONENT}_REASON_FAILURE)
 endforeach()
 
 include (${CMAKE_CURRENT_LIST_DIR}/../FindPackageHandleStandardArgs.cmake)
@@ -2458,8 +2989,10 @@
                   PROPERTY IMPORTED_LOCATION "${${_PYTHON_PREFIX}_COMPILER}")
   endif()
 
-  if ("Development" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS
-      AND ${_PYTHON_PREFIX}_Development_FOUND)
+  if (("Development.Module" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS
+        AND ${_PYTHON_PREFIX}_Development.Module_FOUND)
+      OR ("Development.Embed" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS
+        AND ${_PYTHON_PREFIX}_Development.Embed_FOUND))
 
     macro (__PYTHON_IMPORT_LIBRARY __name)
       if (${_PYTHON_PREFIX}_LIBRARY_RELEASE MATCHES "${CMAKE_SHARED_LIBRARY_SUFFIX}$"
@@ -2491,8 +3024,8 @@
         else()
           set_target_properties (${__name}
                                  PROPERTIES IMPORTED_LINK_INTERFACE_LANGUAGES "C"
-                                            IMPORTED_IMPLIB "${${_PYTHON_PREFIX}_LIBRARY}"
-                                            IMPORTED_LOCATION "${${_PYTHON_PREFIX}_RUNTIME_LIBRARY}")
+                                            IMPORTED_IMPLIB "${${_PYTHON_PREFIX}_LIBRARIES}"
+                                            IMPORTED_LOCATION "${${_PYTHON_PREFIX}_RUNTIME_LIBRARY_RELEASE}")
         endif()
       else()
         if (${_PYTHON_PREFIX}_LIBRARY_RELEASE AND ${_PYTHON_PREFIX}_LIBRARY_DEBUG)
@@ -2506,7 +3039,7 @@
         else()
           set_target_properties (${__name}
                                  PROPERTIES IMPORTED_LINK_INTERFACE_LANGUAGES "C"
-                                            IMPORTED_LOCATION "${${_PYTHON_PREFIX}_LIBRARY}")
+                                            IMPORTED_LOCATION "${${_PYTHON_PREFIX}_LIBRARY_RELEASE}")
         endif()
       endif()
 
@@ -2520,31 +3053,35 @@
       endif()
     endmacro()
 
-    __python_import_library (${_PYTHON_PREFIX}::Python)
+    if (${_PYTHON_PREFIX}_Development.Embed_FOUND)
+      __python_import_library (${_PYTHON_PREFIX}::Python)
+    endif()
 
-    if (CMAKE_SYSTEM_NAME MATCHES "^(Windows.*|CYGWIN|MSYS)$")
-      # On Windows/CYGWIN/MSYS, Python::Module is the same as Python::Python
-      # but ALIAS cannot be used because the imported library is not GLOBAL.
-      __python_import_library (${_PYTHON_PREFIX}::Module)
-    else()
-      if (NOT TARGET ${_PYTHON_PREFIX}::Module )
-        add_library (${_PYTHON_PREFIX}::Module INTERFACE IMPORTED)
-      endif()
-      set_property (TARGET ${_PYTHON_PREFIX}::Module
-                    PROPERTY INTERFACE_INCLUDE_DIRECTORIES "${${_PYTHON_PREFIX}_INCLUDE_DIRS}")
+    if (${_PYTHON_PREFIX}_Development.Module_FOUND)
+      if ("LIBRARY" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_MODULE_ARTIFACTS)
+        # On Windows/CYGWIN/MSYS, Python::Module is the same as Python::Python
+        # but ALIAS cannot be used because the imported library is not GLOBAL.
+        __python_import_library (${_PYTHON_PREFIX}::Module)
+      else()
+        if (NOT TARGET ${_PYTHON_PREFIX}::Module)
+          add_library (${_PYTHON_PREFIX}::Module INTERFACE IMPORTED)
+        endif()
+        set_property (TARGET ${_PYTHON_PREFIX}::Module
+                      PROPERTY INTERFACE_INCLUDE_DIRECTORIES "${${_PYTHON_PREFIX}_INCLUDE_DIRS}")
 
-      # When available, enforce shared library generation with undefined symbols
-      if (APPLE)
-        set_property (TARGET ${_PYTHON_PREFIX}::Module
-                      PROPERTY INTERFACE_LINK_OPTIONS "LINKER:-undefined,dynamic_lookup")
-      endif()
-      if (CMAKE_SYSTEM_NAME STREQUAL "SunOS")
-        set_property (TARGET ${_PYTHON_PREFIX}::Module
-                      PROPERTY INTERFACE_LINK_OPTIONS "LINKER:-z,nodefs")
-      endif()
-      if (CMAKE_SYSTEM_NAME STREQUAL "AIX")
-        set_property (TARGET ${_PYTHON_PREFIX}::Module
-                      PROPERTY INTERFACE_LINK_OPTIONS "LINKER:-b,erok")
+        # When available, enforce shared library generation with undefined symbols
+        if (APPLE)
+          set_property (TARGET ${_PYTHON_PREFIX}::Module
+                        PROPERTY INTERFACE_LINK_OPTIONS "LINKER:-undefined,dynamic_lookup")
+        endif()
+        if (CMAKE_SYSTEM_NAME STREQUAL "SunOS")
+          set_property (TARGET ${_PYTHON_PREFIX}::Module
+                        PROPERTY INTERFACE_LINK_OPTIONS "LINKER:-z,nodefs")
+        endif()
+        if (CMAKE_SYSTEM_NAME STREQUAL "AIX")
+          set_property (TARGET ${_PYTHON_PREFIX}::Module
+                        PROPERTY INTERFACE_LINK_OPTIONS "LINKER:-b,erok")
+        endif()
       endif()
     endif()
 
@@ -2553,8 +3090,7 @@
     # It is used to build modules for python.
     #
     function (__${_PYTHON_PREFIX}_ADD_LIBRARY prefix name)
-      cmake_parse_arguments (PARSE_ARGV 2 PYTHON_ADD_LIBRARY
-        "STATIC;SHARED;MODULE;WITH_SOABI" "" "")
+      cmake_parse_arguments (PARSE_ARGV 2 PYTHON_ADD_LIBRARY "STATIC;SHARED;MODULE;WITH_SOABI" "" "")
 
       if (prefix STREQUAL "Python2" AND PYTHON_ADD_LIBRARY_WITH_SOABI)
         message (AUTHOR_WARNING "FindPython2: Option `WITH_SOABI` is not supported for Python2 and will be ignored.")
@@ -2568,6 +3104,16 @@
       else()
         set (type MODULE)
       endif()
+
+      if (type STREQUAL "MODULE" AND NOT TARGET ${prefix}::Module)
+        message (SEND_ERROR "${prefix}_ADD_LIBRARY: dependent target '${prefix}::Module' is not defined.\n   Did you miss to request COMPONENT 'Development.Module'?")
+        return()
+      endif()
+      if (NOT type STREQUAL "MODULE" AND NOT TARGET ${prefix}::Python)
+        message (SEND_ERROR "${prefix}_ADD_LIBRARY: dependent target '${prefix}::Python' is not defined.\n   Did you miss to request COMPONENT 'Development.Embed'?")
+        return()
+      endif()
+
       add_library (${name} ${type} ${PYTHON_ADD_LIBRARY_UNPARSED_ARGUMENTS})
 
       get_property (type TARGET ${name} PROPERTY TYPE)
diff --git a/Modules/FindPython2.cmake b/Modules/FindPython2.cmake
index 3d0e6b9..f5ad454 100644
--- a/Modules/FindPython2.cmake
+++ b/Modules/FindPython2.cmake
@@ -5,6 +5,8 @@
 FindPython2
 -----------
 
+.. versionadded:: 3.12
+
 Find Python 2 interpreter, compiler and development environment (include
 directories and libraries).
 
@@ -13,13 +15,24 @@
 * ``Interpreter``: search for Python 2 interpreter
 * ``Compiler``: search for Python 2 compiler. Only offered by IronPython.
 * ``Development``: search for development artifacts (include directories and
-  libraries)
+  libraries). This component includes two sub-components which can be specified
+  independently:
+
+  * ``Development.Module``: search for artifacts for Python 2 module
+    developments.
+  * ``Development.Embed``: search for artifacts for Python 2 embedding
+    developments.
+
 * ``NumPy``: search for NumPy include directories.
 
 If no ``COMPONENTS`` are specified, ``Interpreter`` is assumed.
 
+If component ``Development`` is specified, it implies sub-components
+``Development.Module`` and ``Development.Embed``.
+
 To ensure consistent versions between components ``Interpreter``, ``Compiler``,
-``Development`` and ``NumPy``, specify all components at the same time::
+``Development`` (or one of its sub-components) and ``NumPy``, specify all
+components at the same time::
 
   find_package (Python2 COMPONENTS Interpreter Development)
 
@@ -31,10 +44,11 @@
 
 .. note::
 
-  If components ``Interpreter`` and ``Development`` are both specified, this
-  module search only for interpreter with same platform architecture as the one
-  defined by ``CMake`` configuration. This contraint does not apply if only
-  ``Interpreter`` component is specified.
+  If components ``Interpreter`` and ``Development`` (or one of its
+  sub-components) are both specified, this module search only for interpreter
+  with same platform architecture as the one defined by ``CMake``
+  configuration. This constraint does not apply if only ``Interpreter``
+  component is specified.
 
 Imported Targets
 ^^^^^^^^^^^^^^^^
@@ -46,12 +60,12 @@
   Python 2 interpreter. Target defined if component ``Interpreter`` is found.
 ``Python2::Compiler``
   Python 2 compiler. Target defined if component ``Compiler`` is found.
-``Python2::Python``
-  Python 2 library for Python embedding. Target defined if component
-  ``Development`` is found.
 ``Python2::Module``
   Python 2 library for Python module. Target defined if component
-  ``Development`` is found.
+  ``Development.Module`` is found.
+``Python2::Python``
+  Python 2 library for Python embedding. Target defined if component
+  ``Development.Embed`` is found.
 ``Python2::NumPy``
   NumPy library for Python 2. Target defined if component ``NumPy`` is found.
 
@@ -74,26 +88,31 @@
     * Anaconda
     * Canopy
     * IronPython
+    * PyPy
 ``Python2_STDLIB``
   Standard platform independent installation directory.
 
   Information returned by
-  ``distutils.sysconfig.get_python_lib(plat_specific=False,standard_lib=True)``.
+  ``distutils.sysconfig.get_python_lib(plat_specific=False,standard_lib=True)``
+  or else ``sysconfig.get_path('stdlib')``.
 ``Python2_STDARCH``
   Standard platform dependent installation directory.
 
   Information returned by
-  ``distutils.sysconfig.get_python_lib(plat_specific=True,standard_lib=True)``.
+  ``distutils.sysconfig.get_python_lib(plat_specific=True,standard_lib=True)``
+  or else ``sysconfig.get_path('platstdlib')``.
 ``Python2_SITELIB``
   Third-party platform independent installation directory.
 
   Information returned by
-  ``distutils.sysconfig.get_python_lib(plat_specific=False,standard_lib=False)``.
+  ``distutils.sysconfig.get_python_lib(plat_specific=False,standard_lib=False)``
+  or else ``sysconfig.get_path('purelib')``.
 ``Python2_SITEARCH``
   Third-party platform dependent installation directory.
 
   Information returned by
-  ``distutils.sysconfig.get_python_lib(plat_specific=True,standard_lib=False)``.
+  ``distutils.sysconfig.get_python_lib(plat_specific=True,standard_lib=False)``
+  or else ``sysconfig.get_path('platlib')``.
 ``Python2_Compiler_FOUND``
   System has the Python 2 compiler.
 ``Python2_COMPILER``
@@ -101,8 +120,14 @@
 ``Python2_COMPILER_ID``
   A short string unique to the compiler. Possible values include:
     * IronPython
+``Python2_DOTNET_LAUNCHER``
+  The ``.Net`` interpreter. Only used by ``IronPython`` implementation.
 ``Python2_Development_FOUND``
   System has the Python 2 development artifacts.
+``Python2_Development.Module_FOUND``
+  System has the Python 2 development artifacts for Python module.
+``Python2_Development.Embed_FOUND``
+  System has the Python 2 development artifacts for Python embedding.
 ``Python2_INCLUDE_DIRS``
   The Python 2 include directories.
 ``Python2_LIBRARIES``
@@ -119,10 +144,12 @@
   Python 2 minor version.
 ``Python2_VERSION_PATCH``
   Python 2 patch version.
+``Python2_PyPy_VERSION``
+  Python 2 PyPy version.
 ``Python2_NumPy_FOUND``
   System has the NumPy.
 ``Python2_NumPy_INCLUDE_DIRS``
-  The NumPy include directries.
+  The NumPy include directories.
 ``Python2_NumPy_VERSION``
   The NumPy version.
 
@@ -186,8 +213,9 @@
   * ``ONLY``: Only the virtual environment is used to look-up for the
     interpreter.
   * ``STANDARD``: The virtual environment is not used to look-up for the
-    interpreter. In this case, variable ``Python2_FIND_REGISTRY`` (Windows)
-    or ``CMAKE_FIND_FRAMEWORK`` (macOS) can be set with value ``LAST`` or
+    interpreter but environment variable ``PATH`` is always considered.
+    In this case, variable ``Python2_FIND_REGISTRY`` (Windows) or
+    ``CMAKE_FIND_FRAMEWORK`` (macOS) can be set with value ``LAST`` or
     ``NEVER`` to select preferably the interpreter from the virtual
     environment.
 
@@ -197,6 +225,39 @@
     recommended to also include the component ``Interpreter`` to get expected
     result.
 
+``Python2_FIND_IMPLEMENTATIONS``
+  This variable defines, in an ordered list, the different implementations
+  which will be searched. The ``Python2_FIND_IMPLEMENTATIONS`` variable can
+  hold the following values:
+
+  * ``CPython``: this is the standard implementation. Various products, like
+    ``Anaconda`` or ``ActivePython``, rely on this implementation.
+  * ``IronPython``: This implementation use the ``CSharp`` language for
+    ``.NET Framework`` on top of the `Dynamic Language Runtime` (``DLR``).
+    See `IronPython <http://ironpython.net>`_.
+  * ``PyPy``: This implementation use ``RPython`` language and
+    ``RPython translation toolchain`` to produce the python interpreter.
+    See `PyPy <https://www.pypy.org>`_.
+
+  The default value is:
+
+  * Windows platform: ``CPython``, ``IronPython``
+  * Other platforms: ``CPython``
+
+  .. note::
+
+    This hint has the lowest priority of all hints, so even if, for example,
+    you specify ``IronPython`` first and ``CPython`` in second, a python
+    product based on ``CPython`` can be selected because, for example with
+    ``Python2_FIND_STRATEGY=LOCATION``, each location will be search first for
+    ``IronPython`` and second for ``CPython``.
+
+  .. note::
+
+    When ``IronPython`` is specified, on platforms other than ``Windows``, the
+    ``.Net`` interpreter (i.e. ``mono`` command) is expected to be available
+    through the ``PATH`` variable.
+
 Artifacts Specification
 ^^^^^^^^^^^^^^^^^^^^^^^
 
@@ -209,6 +270,9 @@
 ``Python2_COMPILER``
   The path to the compiler.
 
+``Python2_DOTNET_LAUNCHER``
+  The ``.Net`` interpreter. Only used by ``IronPython`` implementation.
+
 ``Python2_LIBRARY``
   The path to the library. It will be used to compute the
   variables ``Python2_LIBRARIES``, ``Python2_LIBRAY_DIRS`` and
@@ -232,9 +296,25 @@
   When an artifact is specified, all ``HINTS`` will be ignored and no search
   will be performed for this artifact.
 
-  If more than one artifact is specified, it is the user's responsability to
+  If more than one artifact is specified, it is the user's responsibility to
   ensure the consistency of the various artifacts.
 
+By default, this module supports multiple calls in different directories of a
+project with different version/component requirements while providing correct
+and consistent results for each call. To support this behavior, ``CMake`` cache
+is not used in the traditional way which can be problematic for interactive
+specification. So, to enable also interactive specification, module behavior
+can be controlled with the following variable:
+
+``Python2_ARTIFACTS_INTERACTIVE``
+  Selects the behavior of the module. This is a boolean variable:
+
+  * If set to ``TRUE``: Create CMake cache entries for the above artifact
+    specification variables so that users can edit them interactively.
+    This disables support for multiple version/component requirements.
+  * If set to ``FALSE`` or undefined: Enable multiple version/component
+    requirements.
+
 Commands
 ^^^^^^^^
 
diff --git a/Modules/FindPython3.cmake b/Modules/FindPython3.cmake
index c9a5d09..bacdc42 100644
--- a/Modules/FindPython3.cmake
+++ b/Modules/FindPython3.cmake
@@ -5,6 +5,8 @@
 FindPython3
 -----------
 
+.. versionadded:: 3.12
+
 Find Python 3 interpreter, compiler and development environment (include
 directories and libraries).
 
@@ -13,13 +15,24 @@
 * ``Interpreter``: search for Python 3 interpreter
 * ``Compiler``: search for Python 3 compiler. Only offered by IronPython.
 * ``Development``: search for development artifacts (include directories and
-  libraries)
+  libraries). This component includes two sub-components which can be specified
+  independently:
+
+  * ``Development.Module``: search for artifacts for Python 3 module
+    developments.
+  * ``Development.Embed``: search for artifacts for Python 3 embedding
+    developments.
+
 * ``NumPy``: search for NumPy include directories.
 
 If no ``COMPONENTS`` are specified, ``Interpreter`` is assumed.
 
+If component ``Development`` is specified, it implies sub-components
+``Development.Module`` and ``Development.Embed``.
+
 To ensure consistent versions between components ``Interpreter``, ``Compiler``,
-``Development`` and ``NumPy``, specify all components at the same time::
+``Development`` (or one of its sub-components) and ``NumPy``, specify all
+components at the same time::
 
   find_package (Python3 COMPONENTS Interpreter Development)
 
@@ -31,10 +44,11 @@
 
 .. note::
 
-  If components ``Interpreter`` and ``Development`` are both specified, this
-  module search only for interpreter with same platform architecture as the one
-  defined by ``CMake`` configuration. This contraint does not apply if only
-  ``Interpreter`` component is specified.
+  If components ``Interpreter`` and ``Development`` (or one of its
+  sub-components) are both specified, this module search only for interpreter
+  with same platform architecture as the one defined by ``CMake``
+  configuration. This constraint does not apply if only ``Interpreter``
+  component is specified.
 
 Imported Targets
 ^^^^^^^^^^^^^^^^
@@ -46,12 +60,12 @@
   Python 3 interpreter. Target defined if component ``Interpreter`` is found.
 ``Python3::Compiler``
   Python 3 compiler. Target defined if component ``Compiler`` is found.
-``Python3::Python``
-  Python 3 library for Python embedding. Target defined if component
-  ``Development`` is found.
 ``Python3::Module``
   Python 3 library for Python module. Target defined if component
-  ``Development`` is found.
+  ``Development.Module`` is found.
+``Python3::Python``
+  Python 3 library for Python embedding. Target defined if component
+  ``Development.Embed`` is found.
 ``Python3::NumPy``
   NumPy library for Python 3. Target defined if component ``NumPy`` is found.
 
@@ -74,33 +88,40 @@
     * Anaconda
     * Canopy
     * IronPython
+    * PyPy
 ``Python3_STDLIB``
   Standard platform independent installation directory.
 
   Information returned by
-  ``distutils.sysconfig.get_python_lib(plat_specific=False,standard_lib=True)``.
+  ``distutils.sysconfig.get_python_lib(plat_specific=False,standard_lib=True)``
+  or else ``sysconfig.get_path('stdlib')``.
 ``Python3_STDARCH``
   Standard platform dependent installation directory.
 
   Information returned by
-  ``distutils.sysconfig.get_python_lib(plat_specific=True,standard_lib=True)``.
+  ``distutils.sysconfig.get_python_lib(plat_specific=True,standard_lib=True)``
+  or else ``sysconfig.get_path('platstdlib')``.
 ``Python3_SITELIB``
   Third-party platform independent installation directory.
 
   Information returned by
-  ``distutils.sysconfig.get_python_lib(plat_specific=False,standard_lib=False)``.
+  ``distutils.sysconfig.get_python_lib(plat_specific=False,standard_lib=False)``
+  or else ``sysconfig.get_path('purelib')``.
 ``Python3_SITEARCH``
   Third-party platform dependent installation directory.
 
   Information returned by
-  ``distutils.sysconfig.get_python_lib(plat_specific=True,standard_lib=False)``.
+  ``distutils.sysconfig.get_python_lib(plat_specific=True,standard_lib=False)``
+  or else ``sysconfig.get_path('platlib')``.
 ``Python3_SOABI``
   Extension suffix for modules.
 
   Information returned by
-  ``distutils.sysconfig.get_config_flag('SOABI')`` or computed from
-  ``distutils.sysconfig.get_config_flag('EXT_SUFFIX')`` or
-  ``python3-config --extension-suffix``.
+  ``distutils.sysconfig.get_config_var('SOABI')`` or computed from
+  ``distutils.sysconfig.get_config_var('EXT_SUFFIX')`` or
+  ``python3-config --extension-suffix``. If package ``distutils.sysconfig`` is
+  not available, ``sysconfig.get_config_var('SOABI')`` or
+  ``sysconfig.get_config_var('EXT_SUFFIX')`` are used.
 ``Python3_Compiler_FOUND``
   System has the Python 3 compiler.
 ``Python3_COMPILER``
@@ -108,8 +129,14 @@
 ``Python3_COMPILER_ID``
   A short string unique to the compiler. Possible values include:
     * IronPython
+``Python3_DOTNET_LAUNCHER``
+  The ``.Net`` interpreter. Only used by ``IronPython`` implementation.
 ``Python3_Development_FOUND``
   System has the Python 3 development artifacts.
+``Python3_Development.Module_FOUND``
+  System has the Python 3 development artifacts for Python module.
+``Python3_Development.Embed_FOUND``
+  System has the Python 3 development artifacts for Python embedding.
 ``Python3_INCLUDE_DIRS``
   The Python 3 include directories.
 ``Python3_LIBRARIES``
@@ -126,10 +153,12 @@
   Python 3 minor version.
 ``Python3_VERSION_PATCH``
   Python 3 patch version.
+``Python3_PyPy_VERSION``
+  Python 3 PyPy version.
 ``Python3_NumPy_FOUND``
   System has the NumPy.
 ``Python3_NumPy_INCLUDE_DIRS``
-  The NumPy include directries.
+  The NumPy include directories.
 ``Python3_NumPy_VERSION``
   The NumPy version.
 
@@ -159,7 +188,7 @@
 
   * ``ON``: Corresponding flag is selected.
   * ``OFF``: Corresponding flag is not selected.
-  * ``ANY``: The two posibilties (``ON`` and ``OFF``) will be searched.
+  * ``ANY``: The two possibilities (``ON`` and ``OFF``) will be searched.
 
   From this 3-tuple, various ABIs will be searched starting from the most
   specialized to the most general. Moreover, ``debug`` versions will be
@@ -234,8 +263,9 @@
   * ``ONLY``: Only the virtual environment is used to look-up for the
     interpreter.
   * ``STANDARD``: The virtual environment is not used to look-up for the
-    interpreter. In this case, variable ``Python3_FIND_REGISTRY`` (Windows)
-    or ``CMAKE_FIND_FRAMEWORK`` (macOS) can be set with value ``LAST`` or
+    interpreter but environment variable ``PATH`` is always considered.
+    In this case, variable ``Python3_FIND_REGISTRY`` (Windows) or
+    ``CMAKE_FIND_FRAMEWORK`` (macOS) can be set with value ``LAST`` or
     ``NEVER`` to select preferably the interpreter from the virtual
     environment.
 
@@ -245,6 +275,39 @@
     recommended to also include the component ``Interpreter`` to get expected
     result.
 
+``Python3_FIND_IMPLEMENTATIONS``
+  This variable defines, in an ordered list, the different implementations
+  which will be searched. The ``Python3_FIND_IMPLEMENTATIONS`` variable can
+  hold the following values:
+
+  * ``CPython``: this is the standard implementation. Various products, like
+    ``Anaconda`` or ``ActivePython``, rely on this implementation.
+  * ``IronPython``: This implementation use the ``CSharp`` language for
+    ``.NET Framework`` on top of the `Dynamic Language Runtime` (``DLR``).
+    See `IronPython <http://ironpython.net>`_.
+  * ``PyPy``: This implementation use ``RPython`` language and
+    ``RPython translation toolchain`` to produce the python interpreter.
+    See `PyPy <https://www.pypy.org>`_.
+
+  The default value is:
+
+  * Windows platform: ``CPython``, ``IronPython``
+  * Other platforms: ``CPython``
+
+  .. note::
+
+    This hint has the lowest priority of all hints, so even if, for example,
+    you specify ``IronPython`` first and ``CPython`` in second, a python
+    product based on ``CPython`` can be selected because, for example with
+    ``Python3_FIND_STRATEGY=LOCATION``, each location will be search first for
+    ``IronPython`` and second for ``CPython``.
+
+  .. note::
+
+    When ``IronPython`` is specified, on platforms other than ``Windows``, the
+    ``.Net`` interpreter (i.e. ``mono`` command) is expected to be available
+    through the ``PATH`` variable.
+
 Artifacts Specification
 ^^^^^^^^^^^^^^^^^^^^^^^
 
@@ -257,6 +320,9 @@
 ``Python3_COMPILER``
   The path to the compiler.
 
+``Python3_DOTNET_LAUNCHER``
+  The ``.Net`` interpreter. Only used by ``IronPython`` implementation.
+
 ``Python3_LIBRARY``
   The path to the library. It will be used to compute the
   variables ``Python3_LIBRARIES``, ``Python3_LIBRAY_DIRS`` and
@@ -280,9 +346,25 @@
   When an artifact is specified, all ``HINTS`` will be ignored and no search
   will be performed for this artifact.
 
-  If more than one artifact is specified, it is the user's responsability to
+  If more than one artifact is specified, it is the user's responsibility to
   ensure the consistency of the various artifacts.
 
+By default, this module supports multiple calls in different directories of a
+project with different version/component requirements while providing correct
+and consistent results for each call. To support this behavior, ``CMake`` cache
+is not used in the traditional way which can be problematic for interactive
+specification. So, to enable also interactive specification, module behavior
+can be controlled with the following variable:
+
+``Python3_ARTIFACTS_INTERACTIVE``
+  Selects the behavior of the module. This is a boolean variable:
+
+  * If set to ``TRUE``: Create CMake cache entries for the above artifact
+    specification variables so that users can edit them interactively.
+    This disables support for multiple version/component requirements.
+  * If set to ``FALSE`` or undefined: Enable multiple version/component
+    requirements.
+
 Commands
 ^^^^^^^^
 
diff --git a/Modules/FindQt3.cmake b/Modules/FindQt3.cmake
index 563ed46..b5bc8b1 100644
--- a/Modules/FindQt3.cmake
+++ b/Modules/FindQt3.cmake
@@ -201,9 +201,16 @@
 
 # if the include a library are found then we have it
 include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
+if (CMAKE_FIND_PACKAGE_NAME STREQUAL "Qt")
+  # FindQt include()'s this module. It's an old pattern, but rather than trying
+  # to suppress this from outside the module (which is then sensitive to the
+  # contents, detect the case in this module and suppress it explicitly.
+  set(FPHSA_NAME_MISMATCHED 1)
+endif ()
 FIND_PACKAGE_HANDLE_STANDARD_ARGS(Qt3
                                   REQUIRED_VARS QT_QT_LIBRARY QT_INCLUDE_DIR QT_MOC_EXECUTABLE
                                   VERSION_VAR QT_VERSION_STRING)
+unset(FPHSA_NAME_MISMATCHED)
 set(QT_FOUND ${QT3_FOUND} )
 
 if(QT_FOUND)
diff --git a/Modules/FindQt4.cmake b/Modules/FindQt4.cmake
index 3993968..ec0f453 100644
--- a/Modules/FindQt4.cmake
+++ b/Modules/FindQt4.cmake
@@ -147,7 +147,7 @@
         in:  directories sources ts_files
         options: flags to pass to lupdate, such as -extensions to specify
         extensions for a directory scan.
-        generates commands to create .ts (vie lupdate) and .qm
+        generates commands to create .ts (via lupdate) and .qm
         (via lrelease) - files from directories and/or sources. The ts files are
         created and/or updated in the source tree (unless given with full paths).
         The qm files are generated in the build tree.
@@ -1318,10 +1318,18 @@
       endif()
     endif()
 else()
+  if (CMAKE_FIND_PACKAGE_NAME STREQUAL "Qt")
+    # FindQt include()'s this module. It's an old pattern, but rather than
+    # trying to suppress this from outside the module (which is then sensitive
+    # to the contents, detect the case in this module and suppress it
+    # explicitly.
+    set(FPHSA_NAME_MISMATCHED 1)
+  endif ()
   FIND_PACKAGE_HANDLE_STANDARD_ARGS(Qt4 FOUND_VAR Qt4_FOUND
     REQUIRED_VARS ${_QT4_FOUND_REQUIRED_VARS}
     VERSION_VAR QTVERSION
     )
+  unset(FPHSA_NAME_MISMATCHED)
 endif()
 
 #######################################
diff --git a/Modules/FindRuby.cmake b/Modules/FindRuby.cmake
index 7e01fbc..3b8122e 100644
--- a/Modules/FindRuby.cmake
+++ b/Modules/FindRuby.cmake
@@ -8,288 +8,504 @@
 Find Ruby
 
 This module finds if Ruby is installed and determines where the
-include files and libraries are.  Ruby 1.8, 1.9, 2.0 and 2.1 are
+include files and libraries are.  Ruby 1.8 through 2.7 are
 supported.
 
 The minimum required version of Ruby can be specified using the
-standard syntax, e.g.  find_package(Ruby 1.8)
+standard syntax, e.g.
 
-It also determines what the name of the library is.  This code sets
-the following variables:
+.. code-block:: cmake
 
-``RUBY_EXECUTABLE``
+  find_package(Ruby 2.5.1 EXACT REQUIRED)
+  # OR
+  find_package(Ruby 2.4)
+
+It also determines what the name of the library is.
+
+Virtual environments such as RVM are handled as well, by passing
+the argument ``Ruby_FIND_VIRTUALENV``
+
+Result Variables
+^^^^^^^^^^^^^^^^
+
+This module will set the following variables in your project:
+
+``Ruby_FOUND``
+  set to true if ruby was found successfully
+``Ruby_EXECUTABLE``
   full path to the ruby binary
-``RUBY_INCLUDE_DIRS``
+``Ruby_INCLUDE_DIRS``
   include dirs to be used when using the ruby library
-``RUBY_LIBRARY``
-  full path to the ruby library
-``RUBY_VERSION``
+``Ruby_LIBRARIES``
+  libraries needed to use ruby from C.
+``Ruby_VERSION``
   the version of ruby which was found, e.g. "1.8.7"
-``RUBY_FOUND``
-  set to true if ruby ws found successfully
+``Ruby_VERSION_MAJOR``
+  Ruby major version.
+``Ruby_VERSION_MINOR``
+  Ruby minor version.
+``Ruby_VERSION_PATCH``
+  Ruby patch version.
+
 
 Also:
 
 ``RUBY_INCLUDE_PATH``
-  same as RUBY_INCLUDE_DIRS, only provided for compatibility reasons, don't use it
+  same as Ruby_INCLUDE_DIRS, only provided for compatibility reasons, don't use it
+
+Hints
+^^^^^
+
+``Ruby_ROOT_DIR``
+  Define the root directory of a Ruby installation.
+
+``Ruby_FIND_VIRTUALENV``
+  This variable defines the handling of virtual environments managed by
+  ``rvm``. It is meaningful only when a virtual environment
+  is active (i.e. the ``rvm`` script has been evaluated or at least the
+  ``MY_RUBY_HOME`` environment variable is set).
+  The ``Ruby_FIND_VIRTUALENV`` variable can be set to empty or
+  one of the following:
+
+  * ``FIRST``: The virtual environment is used before any other standard
+    paths to look-up for the interpreter. This is the default.
+  * ``ONLY``: Only the virtual environment is used to look-up for the
+    interpreter.
+  * ``STANDARD``: The virtual environment is not used to look-up for the
+    interpreter (assuming it isn't still in the PATH...)
+
 #]=======================================================================]
 
-#   RUBY_ARCHDIR=`$RUBY -r rbconfig -e 'printf("%s",Config::CONFIG@<:@"archdir"@:>@)'`
-#   RUBY_SITEARCHDIR=`$RUBY -r rbconfig -e 'printf("%s",Config::CONFIG@<:@"sitearchdir"@:>@)'`
-#   RUBY_SITEDIR=`$RUBY -r rbconfig -e 'printf("%s",Config::CONFIG@<:@"sitelibdir"@:>@)'`
-#   RUBY_LIBDIR=`$RUBY -r rbconfig -e 'printf("%s",Config::CONFIG@<:@"libdir"@:>@)'`
-#   RUBY_LIBRUBYARG=`$RUBY -r rbconfig -e 'printf("%s",Config::CONFIG@<:@"LIBRUBYARG_SHARED"@:>@)'`
+# Backwards compatibility
+# Define camel case versions of input variables
+foreach(UPPER
+    RUBY_EXECUTABLE
+    RUBY_LIBRARY
+    RUBY_INCLUDE_DIR
+    RUBY_CONFIG_INCLUDE_DIR
+    )
+    if (DEFINED ${UPPER})
+      string(REPLACE "RUBY_" "Ruby_" Camel ${UPPER})
+        if (NOT DEFINED ${Camel})
+            set(${Camel} ${${UPPER}})
+        endif()
+    endif()
+endforeach()
+
+#   Ruby_ARCHDIR=`$RUBY -r rbconfig -e 'printf("%s",Config::CONFIG@<:@"archdir"@:>@)'`
+#   Ruby_SITEARCHDIR=`$RUBY -r rbconfig -e 'printf("%s",Config::CONFIG@<:@"sitearchdir"@:>@)'`
+#   Ruby_SITEDIR=`$RUBY -r rbconfig -e 'printf("%s",Config::CONFIG@<:@"sitelibdir"@:>@)'`
+#   Ruby_LIBDIR=`$RUBY -r rbconfig -e 'printf("%s",Config::CONFIG@<:@"libdir"@:>@)'`
+#   Ruby_LIBRUBYARG=`$RUBY -r rbconfig -e 'printf("%s",Config::CONFIG@<:@"LIBRUBYARG_SHARED"@:>@)'`
 
 # uncomment the following line to get debug output for this file
-# set(_RUBY_DEBUG_OUTPUT TRUE)
+# set(_Ruby_DEBUG_OUTPUT TRUE)
 
 # Determine the list of possible names of the ruby executable depending
 # on which version of ruby is required
-set(_RUBY_POSSIBLE_EXECUTABLE_NAMES ruby)
+set(_Ruby_POSSIBLE_EXECUTABLE_NAMES ruby)
 
-# if 1.9 is required, don't look for ruby18 and ruby1.8, default to version 1.8
-if(DEFINED Ruby_FIND_VERSION_MAJOR AND DEFINED Ruby_FIND_VERSION_MINOR)
-  set(Ruby_FIND_VERSION_SHORT_NODOT "${Ruby_FIND_VERSION_MAJOR}${RUBY_FIND_VERSION_MINOR}")
-  # we can't construct that if only major version is given
-  set(_RUBY_POSSIBLE_EXECUTABLE_NAMES
-    ruby${Ruby_FIND_VERSION_MAJOR}.${Ruby_FIND_VERSION_MINOR}
-    ruby${Ruby_FIND_VERSION_MAJOR}${Ruby_FIND_VERSION_MINOR}
-    ${_RUBY_POSSIBLE_EXECUTABLE_NAMES})
-else()
-  set(Ruby_FIND_VERSION_SHORT_NODOT "18")
+# If not specified, allow everything as far back as 1.8.0
+if(NOT DEFINED Ruby_FIND_VERSION_MAJOR)
+  set(Ruby_FIND_VERSION "1.8.0")
+  set(Ruby_FIND_VERSION_MAJOR 1)
+  set(Ruby_FIND_VERSION_MINOR 8)
+  set(Ruby_FIND_VERSION_PATCH 0)
 endif()
 
-if(NOT Ruby_FIND_VERSION_EXACT)
-  list(APPEND _RUBY_POSSIBLE_EXECUTABLE_NAMES ruby2.4 ruby24)
-  list(APPEND _RUBY_POSSIBLE_EXECUTABLE_NAMES ruby2.3 ruby23)
-  list(APPEND _RUBY_POSSIBLE_EXECUTABLE_NAMES ruby2.2 ruby22)
-  list(APPEND _RUBY_POSSIBLE_EXECUTABLE_NAMES ruby2.1 ruby21)
-  list(APPEND _RUBY_POSSIBLE_EXECUTABLE_NAMES ruby2.0 ruby20)
-  list(APPEND _RUBY_POSSIBLE_EXECUTABLE_NAMES ruby1.9 ruby19)
+if(_Ruby_DEBUG_OUTPUT)
+  message("Ruby_FIND_VERSION=${Ruby_FIND_VERSION}")
+  message("Ruby_FIND_VERSION_MAJOR=${Ruby_FIND_VERSION_MAJOR}")
+  message("Ruby_FIND_VERSION_MINOR=${Ruby_FIND_VERSION_MINOR}")
+  message("Ruby_FIND_VERSION_PATCH=${Ruby_FIND_VERSION_PATCH}")
+endif()
 
-  # if we want a version below 1.9, also look for ruby 1.8
-  if("${Ruby_FIND_VERSION_SHORT_NODOT}" VERSION_LESS "19")
-    list(APPEND _RUBY_POSSIBLE_EXECUTABLE_NAMES ruby1.8 ruby18)
+set(Ruby_FIND_VERSION_SHORT_NODOT "${Ruby_FIND_VERSION_MAJOR}${Ruby_FIND_VERSION_MINOR}")
+
+# Set name of possible executables, ignoring the minor
+# Eg:
+# 2.1.1 => from ruby27 to ruby21 included
+# 2.1   => from ruby27 to ruby21 included
+# 2     => from ruby26 to ruby20 included
+# empty => from ruby27 to ruby18 included
+if(NOT Ruby_FIND_VERSION_EXACT)
+
+  foreach(_ruby_version RANGE 27 18 -1)
+    string(SUBSTRING "${_ruby_version}" 0 1 _ruby_major_version)
+    string(SUBSTRING "${_ruby_version}" 1 1 _ruby_minor_version)
+
+    if(NOT "${_ruby_major_version}${_ruby_minor_version}" VERSION_LESS ${Ruby_FIND_VERSION_SHORT_NODOT})
+      # Append both rubyX.Y and rubyXY (eg: ruby2.7 ruby27)
+      list(APPEND _Ruby_POSSIBLE_EXECUTABLE_NAMES ruby${_ruby_major_version}.${_ruby_minor_version} ruby${_ruby_major_version}${_ruby_minor_version})
+    else()
+      break()
+    endif()
+
+  endforeach()
+
+  list(REMOVE_DUPLICATES _Ruby_POSSIBLE_EXECUTABLE_NAMES)
+endif()
+
+# virtual environments handling (eg RVM)
+if (DEFINED ENV{MY_RUBY_HOME})
+  if(_Ruby_DEBUG_OUTPUT)
+    message("My ruby home is defined: $ENV{MY_RUBY_HOME}")
   endif()
 
-  list(REMOVE_DUPLICATES _RUBY_POSSIBLE_EXECUTABLE_NAMES)
+  if (DEFINED Ruby_FIND_VIRTUALENV)
+    if (NOT Ruby_FIND_VIRTUALENV MATCHES "^(FIRST|ONLY|STANDARD)$")
+      message (AUTHOR_WARNING "FindRuby: ${Ruby_FIND_VIRTUALENV}: invalid value for 'Ruby_FIND_VIRTUALENV'. 'FIRST', 'ONLY' or 'STANDARD' expected. 'FIRST' will be used instead.")
+      set (_Ruby_FIND_VIRTUALENV "FIRST")
+    else()
+      set (_Ruby_FIND_VIRTUALENV ${Ruby_FIND_VIRTUALENV})
+    endif()
+  else()
+    set (_Ruby_FIND_VIRTUALENV FIRST)
+  endif()
+else()
+  if (DEFINED Ruby_FIND_VIRTUALENV)
+    message("Environment variable MY_RUBY_HOME isn't set, defaulting back to Ruby_FIND_VIRTUALENV=STANDARD")
+  endif()
+  set (_Ruby_FIND_VIRTUALENV STANDARD)
 endif()
 
-find_program(RUBY_EXECUTABLE NAMES ${_RUBY_POSSIBLE_EXECUTABLE_NAMES})
+if(_Ruby_DEBUG_OUTPUT)
+  message("_Ruby_POSSIBLE_EXECUTABLE_NAMES=${_Ruby_POSSIBLE_EXECUTABLE_NAMES}")
+  message("_Ruby_FIND_VIRTUALENV=${_Ruby_FIND_VIRTUALENV}")
+endif()
 
-if(RUBY_EXECUTABLE  AND NOT  RUBY_VERSION_MAJOR)
+function (_RUBY_VALIDATE_INTERPRETER)
+  if (NOT Ruby_EXECUTABLE)
+    return()
+  endif()
+
+  cmake_parse_arguments (PARSE_ARGV 0 _RVI "EXACT;CHECK_EXISTS" "" "")
+  if (_RVI_UNPARSED_ARGUMENTS)
+    set (expected_version ${_RVI_UNPARSED_ARGUMENTS})
+  else()
+    unset (expected_version)
+  endif()
+
+  if (_RVI_CHECK_EXISTS AND NOT EXISTS "${Ruby_EXECUTABLE}")
+    # interpreter does not exist anymore
+    set (_Ruby_Interpreter_REASON_FAILURE "Cannot find the interpreter \"${Ruby_EXECUTABLE}\"")
+    set_property (CACHE Ruby_EXECUTABLE PROPERTY VALUE "Ruby_EXECUTABLE-NOTFOUND")
+    return()
+  endif()
+
+  # Check the version it returns
+  # executable found must have a specific version
+  execute_process (COMMAND "${Ruby_EXECUTABLE}" -e "puts RUBY_VERSION"
+                   RESULT_VARIABLE result
+                   OUTPUT_VARIABLE version
+                   ERROR_QUIET
+                   OUTPUT_STRIP_TRAILING_WHITESPACE)
+  if (result OR (_RVI_EXACT AND NOT version VERSION_EQUAL expected_version) OR (version VERSION_LESS expected_version))
+    # interpreter not usable or has wrong major version
+    if (result)
+      set (_Ruby_Interpreter_REASON_FAILURE "Cannot use the interpreter \"${Ruby_EXECUTABLE}\"")
+    else()
+      set (_Ruby_Interpreter_REASON_FAILURE "Wrong major version for the interpreter \"${Ruby_EXECUTABLE}\"")
+    endif()
+    set_property (CACHE Ruby_EXECUTABLE PROPERTY VALUE "Ruby_EXECUTABLE-NOTFOUND")
+    return()
+  endif()
+
+endfunction()
+
+while(1)
+  # Virtual environments handling
+  if(_Ruby_FIND_VIRTUALENV MATCHES "^(FIRST|ONLY)$")
+    if(_Ruby_DEBUG_OUTPUT)
+      message("Inside Matches")
+    endif()
+    find_program (Ruby_EXECUTABLE
+                  NAMES ${_Ruby_POSSIBLE_EXECUTABLE_NAMES}
+                  NAMES_PER_DIR
+                  PATHS ENV MY_RUBY_HOME
+                  PATH_SUFFIXES bin Scripts
+                  NO_CMAKE_PATH
+                  NO_CMAKE_ENVIRONMENT_PATH
+                  NO_SYSTEM_ENVIRONMENT_PATH
+                  NO_CMAKE_SYSTEM_PATH)
+
+    if(_Ruby_DEBUG_OUTPUT)
+      message("Ruby_EXECUTABLE=${Ruby_EXECUTABLE}")
+    endif()
+
+    _RUBY_VALIDATE_INTERPRETER (${Ruby_FIND_VERSION}})
+    if(Ruby_EXECUTABLE)
+      break()
+    endif()
+    if(NOT _Ruby_FIND_VIRTUALENV STREQUAL "ONLY")
+      break()
+    endif()
+  elseif(_Ruby_DEBUG_OUTPUT)
+    message("_Ruby_FIND_VIRTUALENV doesn't match: ${_Ruby_FIND_VIRTUALENV}")
+  endif()
+
+  # try using standard paths
+  find_program (Ruby_EXECUTABLE
+                NAMES ${_Ruby_POSSIBLE_EXECUTABLE_NAMES}
+                NAMES_PER_DIR)
+  _RUBY_VALIDATE_INTERPRETER (${Ruby_FIND_VERSION})
+  if (Ruby_EXECUTABLE)
+    break()
+  endif()
+
+  break()
+endwhile()
+
+if(Ruby_EXECUTABLE AND NOT Ruby_VERSION_MAJOR)
   function(_RUBY_CONFIG_VAR RBVAR OUTVAR)
-    execute_process(COMMAND ${RUBY_EXECUTABLE} -r rbconfig -e "print RbConfig::CONFIG['${RBVAR}']"
-      RESULT_VARIABLE _RUBY_SUCCESS
-      OUTPUT_VARIABLE _RUBY_OUTPUT
+    execute_process(COMMAND ${Ruby_EXECUTABLE} -r rbconfig -e "print RbConfig::CONFIG['${RBVAR}']"
+      RESULT_VARIABLE _Ruby_SUCCESS
+      OUTPUT_VARIABLE _Ruby_OUTPUT
       ERROR_QUIET)
-    if(_RUBY_SUCCESS OR _RUBY_OUTPUT STREQUAL "")
-      execute_process(COMMAND ${RUBY_EXECUTABLE} -r rbconfig -e "print Config::CONFIG['${RBVAR}']"
-        RESULT_VARIABLE _RUBY_SUCCESS
-        OUTPUT_VARIABLE _RUBY_OUTPUT
+    if(_Ruby_SUCCESS OR _Ruby_OUTPUT STREQUAL "")
+      execute_process(COMMAND ${Ruby_EXECUTABLE} -r rbconfig -e "print Config::CONFIG['${RBVAR}']"
+        RESULT_VARIABLE _Ruby_SUCCESS
+        OUTPUT_VARIABLE _Ruby_OUTPUT
         ERROR_QUIET)
     endif()
-    set(${OUTVAR} "${_RUBY_OUTPUT}" PARENT_SCOPE)
+    set(${OUTVAR} "${_Ruby_OUTPUT}" PARENT_SCOPE)
   endfunction()
 
 
   # query the ruby version
-  _RUBY_CONFIG_VAR("MAJOR" RUBY_VERSION_MAJOR)
-  _RUBY_CONFIG_VAR("MINOR" RUBY_VERSION_MINOR)
-  _RUBY_CONFIG_VAR("TEENY" RUBY_VERSION_PATCH)
+  _RUBY_CONFIG_VAR("MAJOR" Ruby_VERSION_MAJOR)
+  _RUBY_CONFIG_VAR("MINOR" Ruby_VERSION_MINOR)
+  _RUBY_CONFIG_VAR("TEENY" Ruby_VERSION_PATCH)
 
   # query the different directories
-  _RUBY_CONFIG_VAR("archdir" RUBY_ARCH_DIR)
-  _RUBY_CONFIG_VAR("arch" RUBY_ARCH)
-  _RUBY_CONFIG_VAR("rubyhdrdir" RUBY_HDR_DIR)
-  _RUBY_CONFIG_VAR("rubyarchhdrdir" RUBY_ARCHHDR_DIR)
-  _RUBY_CONFIG_VAR("libdir" RUBY_POSSIBLE_LIB_DIR)
-  _RUBY_CONFIG_VAR("rubylibdir" RUBY_RUBY_LIB_DIR)
+  _RUBY_CONFIG_VAR("archdir" Ruby_ARCH_DIR)
+  _RUBY_CONFIG_VAR("arch" Ruby_ARCH)
+  _RUBY_CONFIG_VAR("rubyhdrdir" Ruby_HDR_DIR)
+  _RUBY_CONFIG_VAR("rubyarchhdrdir" Ruby_ARCHHDR_DIR)
+  _RUBY_CONFIG_VAR("libdir" Ruby_POSSIBLE_LIB_DIR)
+  _RUBY_CONFIG_VAR("rubylibdir" Ruby_RUBY_LIB_DIR)
 
   # site_ruby
-  _RUBY_CONFIG_VAR("sitearchdir" RUBY_SITEARCH_DIR)
-  _RUBY_CONFIG_VAR("sitelibdir" RUBY_SITELIB_DIR)
+  _RUBY_CONFIG_VAR("sitearchdir" Ruby_SITEARCH_DIR)
+  _RUBY_CONFIG_VAR("sitelibdir" Ruby_SITELIB_DIR)
 
   # vendor_ruby available ?
-  execute_process(COMMAND ${RUBY_EXECUTABLE} -r vendor-specific -e "print 'true'"
-    OUTPUT_VARIABLE RUBY_HAS_VENDOR_RUBY  ERROR_QUIET)
+  execute_process(COMMAND ${Ruby_EXECUTABLE} -r vendor-specific -e "print 'true'"
+    OUTPUT_VARIABLE Ruby_HAS_VENDOR_RUBY  ERROR_QUIET)
 
-  if(RUBY_HAS_VENDOR_RUBY)
-    _RUBY_CONFIG_VAR("vendorlibdir" RUBY_VENDORLIB_DIR)
-    _RUBY_CONFIG_VAR("vendorarchdir" RUBY_VENDORARCH_DIR)
+  if(Ruby_HAS_VENDOR_RUBY)
+    _RUBY_CONFIG_VAR("vendorlibdir" Ruby_VENDORLIB_DIR)
+    _RUBY_CONFIG_VAR("vendorarchdir" Ruby_VENDORARCH_DIR)
   endif()
 
   # save the results in the cache so we don't have to run ruby the next time again
-  set(RUBY_VERSION_MAJOR    ${RUBY_VERSION_MAJOR}    CACHE PATH "The Ruby major version" FORCE)
-  set(RUBY_VERSION_MINOR    ${RUBY_VERSION_MINOR}    CACHE PATH "The Ruby minor version" FORCE)
-  set(RUBY_VERSION_PATCH    ${RUBY_VERSION_PATCH}    CACHE PATH "The Ruby patch version" FORCE)
-  set(RUBY_ARCH_DIR         ${RUBY_ARCH_DIR}         CACHE PATH "The Ruby arch dir" FORCE)
-  set(RUBY_HDR_DIR          ${RUBY_HDR_DIR}          CACHE PATH "The Ruby header dir (1.9+)" FORCE)
-  set(RUBY_ARCHHDR_DIR      ${RUBY_ARCHHDR_DIR}      CACHE PATH "The Ruby arch header dir (2.0+)" FORCE)
-  set(RUBY_POSSIBLE_LIB_DIR ${RUBY_POSSIBLE_LIB_DIR} CACHE PATH "The Ruby lib dir" FORCE)
-  set(RUBY_RUBY_LIB_DIR     ${RUBY_RUBY_LIB_DIR}     CACHE PATH "The Ruby ruby-lib dir" FORCE)
-  set(RUBY_SITEARCH_DIR     ${RUBY_SITEARCH_DIR}     CACHE PATH "The Ruby site arch dir" FORCE)
-  set(RUBY_SITELIB_DIR      ${RUBY_SITELIB_DIR}      CACHE PATH "The Ruby site lib dir" FORCE)
-  set(RUBY_HAS_VENDOR_RUBY  ${RUBY_HAS_VENDOR_RUBY}  CACHE BOOL "Vendor Ruby is available" FORCE)
-  set(RUBY_VENDORARCH_DIR   ${RUBY_VENDORARCH_DIR}   CACHE PATH "The Ruby vendor arch dir" FORCE)
-  set(RUBY_VENDORLIB_DIR    ${RUBY_VENDORLIB_DIR}    CACHE PATH "The Ruby vendor lib dir" FORCE)
+  set(Ruby_VERSION_MAJOR    ${Ruby_VERSION_MAJOR}    CACHE PATH "The Ruby major version" FORCE)
+  set(Ruby_VERSION_MINOR    ${Ruby_VERSION_MINOR}    CACHE PATH "The Ruby minor version" FORCE)
+  set(Ruby_VERSION_PATCH    ${Ruby_VERSION_PATCH}    CACHE PATH "The Ruby patch version" FORCE)
+  set(Ruby_ARCH_DIR         ${Ruby_ARCH_DIR}         CACHE PATH "The Ruby arch dir" FORCE)
+  set(Ruby_HDR_DIR          ${Ruby_HDR_DIR}          CACHE PATH "The Ruby header dir (1.9+)" FORCE)
+  set(Ruby_ARCHHDR_DIR      ${Ruby_ARCHHDR_DIR}      CACHE PATH "The Ruby arch header dir (2.0+)" FORCE)
+  set(Ruby_POSSIBLE_LIB_DIR ${Ruby_POSSIBLE_LIB_DIR} CACHE PATH "The Ruby lib dir" FORCE)
+  set(Ruby_RUBY_LIB_DIR     ${Ruby_RUBY_LIB_DIR}     CACHE PATH "The Ruby ruby-lib dir" FORCE)
+  set(Ruby_SITEARCH_DIR     ${Ruby_SITEARCH_DIR}     CACHE PATH "The Ruby site arch dir" FORCE)
+  set(Ruby_SITELIB_DIR      ${Ruby_SITELIB_DIR}      CACHE PATH "The Ruby site lib dir" FORCE)
+  set(Ruby_HAS_VENDOR_RUBY  ${Ruby_HAS_VENDOR_RUBY}  CACHE BOOL "Vendor Ruby is available" FORCE)
+  set(Ruby_VENDORARCH_DIR   ${Ruby_VENDORARCH_DIR}   CACHE PATH "The Ruby vendor arch dir" FORCE)
+  set(Ruby_VENDORLIB_DIR    ${Ruby_VENDORLIB_DIR}    CACHE PATH "The Ruby vendor lib dir" FORCE)
 
   mark_as_advanced(
-    RUBY_ARCH_DIR
-    RUBY_ARCH
-    RUBY_HDR_DIR
-    RUBY_ARCHHDR_DIR
-    RUBY_POSSIBLE_LIB_DIR
-    RUBY_RUBY_LIB_DIR
-    RUBY_SITEARCH_DIR
-    RUBY_SITELIB_DIR
-    RUBY_HAS_VENDOR_RUBY
-    RUBY_VENDORARCH_DIR
-    RUBY_VENDORLIB_DIR
-    RUBY_VERSION_MAJOR
-    RUBY_VERSION_MINOR
-    RUBY_VERSION_PATCH
+    Ruby_ARCH_DIR
+    Ruby_ARCH
+    Ruby_HDR_DIR
+    Ruby_ARCHHDR_DIR
+    Ruby_POSSIBLE_LIB_DIR
+    Ruby_RUBY_LIB_DIR
+    Ruby_SITEARCH_DIR
+    Ruby_SITELIB_DIR
+    Ruby_HAS_VENDOR_RUBY
+    Ruby_VENDORARCH_DIR
+    Ruby_VENDORLIB_DIR
+    Ruby_VERSION_MAJOR
+    Ruby_VERSION_MINOR
+    Ruby_VERSION_PATCH
     )
 endif()
 
-# In case RUBY_EXECUTABLE could not be executed (e.g. cross compiling)
+# In case Ruby_EXECUTABLE could not be executed (e.g. cross compiling)
 # try to detect which version we found. This is not too good.
-if(RUBY_EXECUTABLE AND NOT RUBY_VERSION_MAJOR)
+if(Ruby_EXECUTABLE AND NOT Ruby_VERSION_MAJOR)
   # by default assume 1.8.0
-  set(RUBY_VERSION_MAJOR 1)
-  set(RUBY_VERSION_MINOR 8)
-  set(RUBY_VERSION_PATCH 0)
+  set(Ruby_VERSION_MAJOR 1)
+  set(Ruby_VERSION_MINOR 8)
+  set(Ruby_VERSION_PATCH 0)
   # check whether we found 1.9.x
-  if(${RUBY_EXECUTABLE} MATCHES "ruby1\\.?9")
-    set(RUBY_VERSION_MAJOR 1)
-    set(RUBY_VERSION_MINOR 9)
+  if(${Ruby_EXECUTABLE} MATCHES "ruby1\\.?9")
+    set(Ruby_VERSION_MAJOR 1)
+    set(Ruby_VERSION_MINOR 9)
   endif()
   # check whether we found 2.0.x
-  if(${RUBY_EXECUTABLE} MATCHES "ruby2\\.?0")
-    set(RUBY_VERSION_MAJOR 2)
-    set(RUBY_VERSION_MINOR 0)
+  if(${Ruby_EXECUTABLE} MATCHES "ruby2\\.?0")
+    set(Ruby_VERSION_MAJOR 2)
+    set(Ruby_VERSION_MINOR 0)
   endif()
   # check whether we found 2.1.x
-  if(${RUBY_EXECUTABLE} MATCHES "ruby2\\.?1")
-    set(RUBY_VERSION_MAJOR 2)
-    set(RUBY_VERSION_MINOR 1)
+  if(${Ruby_EXECUTABLE} MATCHES "ruby2\\.?1")
+    set(Ruby_VERSION_MAJOR 2)
+    set(Ruby_VERSION_MINOR 1)
   endif()
   # check whether we found 2.2.x
-  if(${RUBY_EXECUTABLE} MATCHES "ruby2\\.?2")
-    set(RUBY_VERSION_MAJOR 2)
-    set(RUBY_VERSION_MINOR 2)
+  if(${Ruby_EXECUTABLE} MATCHES "ruby2\\.?2")
+    set(Ruby_VERSION_MAJOR 2)
+    set(Ruby_VERSION_MINOR 2)
   endif()
   # check whether we found 2.3.x
-  if(${RUBY_EXECUTABLE} MATCHES "ruby2\\.?3")
-    set(RUBY_VERSION_MAJOR 2)
-    set(RUBY_VERSION_MINOR 3)
+  if(${Ruby_EXECUTABLE} MATCHES "ruby2\\.?3")
+    set(Ruby_VERSION_MAJOR 2)
+    set(Ruby_VERSION_MINOR 3)
   endif()
   # check whether we found 2.4.x
-  if(${RUBY_EXECUTABLE} MATCHES "ruby2\\.?4")
-    set(RUBY_VERSION_MAJOR 2)
-    set(RUBY_VERSION_MINOR 4)
+  if(${Ruby_EXECUTABLE} MATCHES "ruby2\\.?4")
+    set(Ruby_VERSION_MAJOR 2)
+    set(Ruby_VERSION_MINOR 4)
+  endif()
+  # check whether we found 2.5.x
+  if(${Ruby_EXECUTABLE} MATCHES "ruby2\\.?5")
+    set(Ruby_VERSION_MAJOR 2)
+    set(Ruby_VERSION_MINOR 5)
+  endif()
+  # check whether we found 2.6.x
+  if(${Ruby_EXECUTABLE} MATCHES "ruby2\\.?6")
+    set(Ruby_VERSION_MAJOR 2)
+    set(Ruby_VERSION_MINOR 6)
+  endif()
+  # check whether we found 2.7.x
+  if(${Ruby_EXECUTABLE} MATCHES "ruby2\\.?7")
+    set(Ruby_VERSION_MAJOR 2)
+    set(Ruby_VERSION_MINOR 7)
   endif()
 endif()
 
-if(RUBY_VERSION_MAJOR)
-  set(RUBY_VERSION "${RUBY_VERSION_MAJOR}.${RUBY_VERSION_MINOR}.${RUBY_VERSION_PATCH}")
-  set(_RUBY_VERSION_SHORT "${RUBY_VERSION_MAJOR}.${RUBY_VERSION_MINOR}")
-  set(_RUBY_VERSION_SHORT_NODOT "${RUBY_VERSION_MAJOR}${RUBY_VERSION_MINOR}")
-  set(_RUBY_NODOT_VERSION "${RUBY_VERSION_MAJOR}${RUBY_VERSION_MINOR}${RUBY_VERSION_PATCH}")
+if(Ruby_VERSION_MAJOR)
+  set(Ruby_VERSION "${Ruby_VERSION_MAJOR}.${Ruby_VERSION_MINOR}.${Ruby_VERSION_PATCH}")
+  set(_Ruby_VERSION_SHORT "${Ruby_VERSION_MAJOR}.${Ruby_VERSION_MINOR}")
+  set(_Ruby_VERSION_SHORT_NODOT "${Ruby_VERSION_MAJOR}${Ruby_VERSION_MINOR}")
+  set(_Ruby_NODOT_VERSION "${Ruby_VERSION_MAJOR}${Ruby_VERSION_MINOR}${Ruby_VERSION_PATCH}")
 endif()
 
-find_path(RUBY_INCLUDE_DIR
+# FIXME: Currently we require both the interpreter and development components to be found
+# in order to use either.  See issue #20474.
+find_path(Ruby_INCLUDE_DIR
   NAMES ruby.h
   HINTS
-    ${RUBY_HDR_DIR}
-    ${RUBY_ARCH_DIR}
-    /usr/lib/ruby/${_RUBY_VERSION_SHORT}/i586-linux-gnu/
+    ${Ruby_HDR_DIR}
+    ${Ruby_ARCH_DIR}
+    /usr/lib/ruby/${_Ruby_VERSION_SHORT}/i586-linux-gnu/
 )
 
-set(RUBY_INCLUDE_DIRS ${RUBY_INCLUDE_DIR} )
+set(Ruby_INCLUDE_DIRS ${Ruby_INCLUDE_DIR})
 
 # if ruby > 1.8 is required or if ruby > 1.8 was found, search for the config.h dir
-if( "${Ruby_FIND_VERSION_SHORT_NODOT}" GREATER 18  OR  "${_RUBY_VERSION_SHORT_NODOT}" GREATER 18  OR  RUBY_HDR_DIR)
-  find_path(RUBY_CONFIG_INCLUDE_DIR
+if( Ruby_FIND_VERSION VERSION_GREATER_EQUAL "1.9"  OR  Ruby_VERSION VERSION_GREATER_EQUAL "1.9"  OR  Ruby_HDR_DIR)
+  find_path(Ruby_CONFIG_INCLUDE_DIR
     NAMES ruby/config.h  config.h
     HINTS
-      ${RUBY_HDR_DIR}/${RUBY_ARCH}
-      ${RUBY_ARCH_DIR}
-      ${RUBY_ARCHHDR_DIR}
+      ${Ruby_HDR_DIR}/${Ruby_ARCH}
+      ${Ruby_ARCH_DIR}
+      ${Ruby_ARCHHDR_DIR}
   )
 
-  set(RUBY_INCLUDE_DIRS ${RUBY_INCLUDE_DIRS} ${RUBY_CONFIG_INCLUDE_DIR} )
+  set(Ruby_INCLUDE_DIRS ${Ruby_INCLUDE_DIRS} ${Ruby_CONFIG_INCLUDE_DIR} )
 endif()
 
 
 # Determine the list of possible names for the ruby library
-set(_RUBY_POSSIBLE_LIB_NAMES ruby ruby-static ruby${_RUBY_VERSION_SHORT} ruby${_RUBY_VERSION_SHORT_NODOT} ruby-${_RUBY_VERSION_SHORT} ruby-${RUBY_VERSION})
+set(_Ruby_POSSIBLE_LIB_NAMES ruby ruby-static ruby${_Ruby_VERSION_SHORT} ruby${_Ruby_VERSION_SHORT_NODOT} ruby-${_Ruby_VERSION_SHORT} ruby-${Ruby_VERSION})
 
 if(WIN32)
-  set( _RUBY_MSVC_RUNTIME "" )
-  if( MSVC_VERSION EQUAL 1200 )
-    set( _RUBY_MSVC_RUNTIME "60" )
-  endif()
-  if( MSVC_VERSION EQUAL 1300 )
-    set( _RUBY_MSVC_RUNTIME "70" )
-  endif()
-  if( MSVC_VERSION EQUAL 1310 )
-    set( _RUBY_MSVC_RUNTIME "71" )
-  endif()
-  if( MSVC_VERSION EQUAL 1400 )
-    set( _RUBY_MSVC_RUNTIME "80" )
-  endif()
-  if( MSVC_VERSION EQUAL 1500 )
-    set( _RUBY_MSVC_RUNTIME "90" )
+  if(MSVC_TOOLSET_VERSION)
+    set(_Ruby_MSVC_RUNTIME "${MSVC_TOOLSET_VERSION}")
+  else()
+    set(_Ruby_MSVC_RUNTIME "")
   endif()
 
-  set(_RUBY_ARCH_PREFIX "")
+  set(_Ruby_ARCH_PREFIX "")
   if(CMAKE_SIZEOF_VOID_P EQUAL 8)
-    set(_RUBY_ARCH_PREFIX "x64-")
+    set(_Ruby_ARCH_PREFIX "x64-")
   endif()
 
-  list(APPEND _RUBY_POSSIBLE_LIB_NAMES
-             "${_RUBY_ARCH_PREFIX}msvcr${_RUBY_MSVC_RUNTIME}-ruby${_RUBY_NODOT_VERSION}"
-             "${_RUBY_ARCH_PREFIX}msvcr${_RUBY_MSVC_RUNTIME}-ruby${_RUBY_NODOT_VERSION}-static"
-             "${_RUBY_ARCH_PREFIX}msvcrt-ruby${_RUBY_NODOT_VERSION}"
-             "${_RUBY_ARCH_PREFIX}msvcrt-ruby${_RUBY_NODOT_VERSION}-static" )
+  list(APPEND _Ruby_POSSIBLE_LIB_NAMES
+             "${_Ruby_ARCH_PREFIX}msvcr${_Ruby_MSVC_RUNTIME}-ruby${_Ruby_NODOT_VERSION}"
+             "${_Ruby_ARCH_PREFIX}msvcr${_Ruby_MSVC_RUNTIME}-ruby${_Ruby_NODOT_VERSION}-static"
+             "${_Ruby_ARCH_PREFIX}msvcrt-ruby${_Ruby_NODOT_VERSION}"
+             "${_Ruby_ARCH_PREFIX}msvcrt-ruby${_Ruby_NODOT_VERSION}-static" )
 endif()
 
-find_library(RUBY_LIBRARY NAMES ${_RUBY_POSSIBLE_LIB_NAMES} HINTS ${RUBY_POSSIBLE_LIB_DIR} )
+find_library(Ruby_LIBRARY NAMES ${_Ruby_POSSIBLE_LIB_NAMES} HINTS ${Ruby_POSSIBLE_LIB_DIR} )
 
-include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
-set(_RUBY_REQUIRED_VARS RUBY_EXECUTABLE RUBY_INCLUDE_DIR RUBY_LIBRARY)
-if(_RUBY_VERSION_SHORT_NODOT GREATER 18)
-  list(APPEND _RUBY_REQUIRED_VARS RUBY_CONFIG_INCLUDE_DIR)
+set(_Ruby_REQUIRED_VARS Ruby_EXECUTABLE Ruby_INCLUDE_DIR Ruby_LIBRARY)
+if(_Ruby_VERSION_SHORT_NODOT GREATER 18)
+  list(APPEND _Ruby_REQUIRED_VARS Ruby_CONFIG_INCLUDE_DIR)
 endif()
 
-if(_RUBY_DEBUG_OUTPUT)
+if(_Ruby_DEBUG_OUTPUT)
   message(STATUS "--------FindRuby.cmake debug------------")
-  message(STATUS "_RUBY_POSSIBLE_EXECUTABLE_NAMES: ${_RUBY_POSSIBLE_EXECUTABLE_NAMES}")
-  message(STATUS "_RUBY_POSSIBLE_LIB_NAMES: ${_RUBY_POSSIBLE_LIB_NAMES}")
-  message(STATUS "RUBY_ARCH_DIR: ${RUBY_ARCH_DIR}")
-  message(STATUS "RUBY_HDR_DIR: ${RUBY_HDR_DIR}")
-  message(STATUS "RUBY_POSSIBLE_LIB_DIR: ${RUBY_POSSIBLE_LIB_DIR}")
-  message(STATUS "Found RUBY_VERSION: \"${RUBY_VERSION}\" , short: \"${_RUBY_VERSION_SHORT}\", nodot: \"${_RUBY_VERSION_SHORT_NODOT}\"")
-  message(STATUS "_RUBY_REQUIRED_VARS: ${_RUBY_REQUIRED_VARS}")
-  message(STATUS "RUBY_EXECUTABLE: ${RUBY_EXECUTABLE}")
-  message(STATUS "RUBY_LIBRARY: ${RUBY_LIBRARY}")
-  message(STATUS "RUBY_INCLUDE_DIR: ${RUBY_INCLUDE_DIR}")
-  message(STATUS "RUBY_CONFIG_INCLUDE_DIR: ${RUBY_CONFIG_INCLUDE_DIR}")
+  message(STATUS "_Ruby_POSSIBLE_EXECUTABLE_NAMES: ${_Ruby_POSSIBLE_EXECUTABLE_NAMES}")
+  message(STATUS "_Ruby_POSSIBLE_LIB_NAMES: ${_Ruby_POSSIBLE_LIB_NAMES}")
+  message(STATUS "Ruby_ARCH_DIR: ${Ruby_ARCH_DIR}")
+  message(STATUS "Ruby_HDR_DIR: ${Ruby_HDR_DIR}")
+  message(STATUS "Ruby_POSSIBLE_LIB_DIR: ${Ruby_POSSIBLE_LIB_DIR}")
+  message(STATUS "Found Ruby_VERSION: \"${Ruby_VERSION}\" , short: \"${_Ruby_VERSION_SHORT}\", nodot: \"${_Ruby_VERSION_SHORT_NODOT}\"")
+  message(STATUS "_Ruby_REQUIRED_VARS: ${_Ruby_REQUIRED_VARS}")
+  message(STATUS "Ruby_EXECUTABLE: ${Ruby_EXECUTABLE}")
+  message(STATUS "Ruby_LIBRARY: ${Ruby_LIBRARY}")
+  message(STATUS "Ruby_INCLUDE_DIR: ${Ruby_INCLUDE_DIR}")
+  message(STATUS "Ruby_CONFIG_INCLUDE_DIR: ${Ruby_CONFIG_INCLUDE_DIR}")
   message(STATUS "--------------------")
 endif()
 
-FIND_PACKAGE_HANDLE_STANDARD_ARGS(Ruby  REQUIRED_VARS  ${_RUBY_REQUIRED_VARS}
-                                        VERSION_VAR RUBY_VERSION )
+include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(Ruby  REQUIRED_VARS  ${_Ruby_REQUIRED_VARS}
+                                        VERSION_VAR Ruby_VERSION )
+
+if(Ruby_FOUND)
+  set(Ruby_LIBRARIES ${Ruby_LIBRARY})
+endif()
 
 mark_as_advanced(
-  RUBY_EXECUTABLE
-  RUBY_LIBRARY
-  RUBY_INCLUDE_DIR
-  RUBY_CONFIG_INCLUDE_DIR
+  Ruby_EXECUTABLE
+  Ruby_LIBRARY
+  Ruby_INCLUDE_DIR
+  Ruby_CONFIG_INCLUDE_DIR
   )
 
-# Set some variables for compatibility with previous version of this file
-set(RUBY_POSSIBLE_LIB_PATH ${RUBY_POSSIBLE_LIB_DIR})
-set(RUBY_RUBY_LIB_PATH ${RUBY_RUBY_LIB_DIR})
-set(RUBY_INCLUDE_PATH ${RUBY_INCLUDE_DIRS})
+# Set some variables for compatibility with previous version of this file (no need to provide a CamelCase version of that...)
+set(RUBY_POSSIBLE_LIB_PATH ${Ruby_POSSIBLE_LIB_DIR})
+set(RUBY_RUBY_LIB_PATH ${Ruby_RUBY_LIB_DIR})
+set(RUBY_INCLUDE_PATH ${Ruby_INCLUDE_DIRS})
+
+# Backwards compatibility
+# Define upper case versions of output variables
+foreach(Camel
+    Ruby_EXECUTABLE
+    Ruby_INCLUDE_DIRS
+    Ruby_LIBRARY
+    Ruby_VERSION
+    Ruby_VERSION_MAJOR
+    Ruby_VERSION_MINOR
+    Ruby_VERSION_PATCH
+
+    Ruby_ARCH_DIR
+    Ruby_ARCH
+    Ruby_HDR_DIR
+    Ruby_ARCHHDR_DIR
+    Ruby_POSSIBLE_LIB_DIR
+    Ruby_RUBY_LIB_DIR
+    Ruby_SITEARCH_DIR
+    Ruby_SITELIB_DIR
+    Ruby_HAS_VENDOR_RUBY
+    Ruby_VENDORARCH_DIR
+
+    )
+    string(TOUPPER ${Camel} UPPER)
+    set(${UPPER} ${${Camel}})
+endforeach()
diff --git a/Modules/FindSDL.cmake b/Modules/FindSDL.cmake
index 8d793a9..59eddbb 100644
--- a/Modules/FindSDL.cmake
+++ b/Modules/FindSDL.cmake
@@ -5,24 +5,54 @@
 FindSDL
 -------
 
-Locate SDL library
-
-This module defines
-
-::
-
-  SDL_LIBRARY, the name of the library to link against
-  SDL_FOUND, if false, do not try to link to SDL
-  SDL_INCLUDE_DIR, where to find SDL.h
-  SDL_VERSION_STRING, human-readable string containing the version of SDL
+Locate the SDL library
 
 
+Imported targets
+^^^^^^^^^^^^^^^^
+
+This module defines the following :prop_tgt:`IMPORTED` target:
+
+``SDL::SDL``
+  The SDL library, if found
+
+Result variables
+^^^^^^^^^^^^^^^^
+
+This module will set the following variables in your project:
+
+``SDL_INCLUDE_DIRS``
+  where to find SDL.h
+``SDL_LIBRARIES``
+  the name of the library to link against
+``SDL_FOUND``
+  if false, do not try to link to SDL
+``SDL_VERSION``
+  the human-readable string containing the version of SDL if found
+``SDL_VERSION_MAJOR``
+  SDL major version
+``SDL_VERSION_MINOR``
+  SDL minor version
+``SDL_VERSION_PATCH``
+  SDL patch version
+
+Cache variables
+^^^^^^^^^^^^^^^
+
+These variables may optionally be set to help this module find the correct files:
+
+``SDL_INCLUDE_DIR``
+  where to find SDL.h
+``SDL_LIBRARY``
+  the name of the library to link against
+
+
+Variables for locating SDL
+^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 This module responds to the flag:
 
-::
-
-  SDL_BUILDING_LIBRARY
+``SDL_BUILDING_LIBRARY``
     If this is defined, then no SDL_main will be linked in because
     only applications need main().
     Otherwise, it is assumed you are building an application and this
@@ -30,6 +60,15 @@
     as part of the returned SDL_LIBRARY variable.
 
 
+Obsolete variables
+^^^^^^^^^^^^^^^^^^
+
+These variables are obsolete and provided for backwards compatibility:
+
+``SDL_VERSION_STRING``
+  the human-readable string containing the version of SDL if found.
+  Identical to SDL_VERSION
+
 
 Don't forget to include SDLmain.h and SDLmain.m your project for the
 OS X framework based version.  (Other versions link to -lSDLmain which
@@ -52,15 +91,6 @@
 $SDLDIR is an environment variable that would correspond to the
 ./configure --prefix=$SDLDIR used in building SDL.  l.e.galup 9-20-02
 
-Modified by Eric Wing.  Added code to assist with automated building
-by using environmental variables and providing a more
-controlled/consistent search behavior.  Added new modifications to
-recognize OS X frameworks and additional Unix paths (FreeBSD, etc).
-Also corrected the header search path to follow "proper" SDL
-guidelines.  Added a search for SDLmain which is needed by some
-platforms.  Added a search for threads which is needed by some
-platforms.  Added needed compile switches for MinGW.
-
 On OSX, this will prefer the Framework version (if found) over others.
 People will have to manually change the cache values of SDL_LIBRARY to
 override this selection or set the CMake environment
@@ -174,13 +204,11 @@
   string(REGEX REPLACE "^#define[ \t]+SDL_MAJOR_VERSION[ \t]+([0-9]+)$" "\\1" SDL_VERSION_MAJOR "${SDL_VERSION_MAJOR_LINE}")
   string(REGEX REPLACE "^#define[ \t]+SDL_MINOR_VERSION[ \t]+([0-9]+)$" "\\1" SDL_VERSION_MINOR "${SDL_VERSION_MINOR_LINE}")
   string(REGEX REPLACE "^#define[ \t]+SDL_PATCHLEVEL[ \t]+([0-9]+)$" "\\1" SDL_VERSION_PATCH "${SDL_VERSION_PATCH_LINE}")
-  set(SDL_VERSION_STRING ${SDL_VERSION_MAJOR}.${SDL_VERSION_MINOR}.${SDL_VERSION_PATCH})
   unset(SDL_VERSION_MAJOR_LINE)
   unset(SDL_VERSION_MINOR_LINE)
   unset(SDL_VERSION_PATCH_LINE)
-  unset(SDL_VERSION_MAJOR)
-  unset(SDL_VERSION_MINOR)
-  unset(SDL_VERSION_PATCH)
+  set(SDL_VERSION ${SDL_VERSION_MAJOR}.${SDL_VERSION_MINOR}.${SDL_VERSION_PATCH})
+  set(SDL_VERSION_STRING ${SDL_VERSION})
 endif()
 
 include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
@@ -188,3 +216,14 @@
 FIND_PACKAGE_HANDLE_STANDARD_ARGS(SDL
                                   REQUIRED_VARS SDL_LIBRARY SDL_INCLUDE_DIR
                                   VERSION_VAR SDL_VERSION_STRING)
+
+if(SDL_FOUND)
+  set(SDL_LIBRARIES ${SDL_LIBRARY})
+  set(SDL_INCLUDE_DIRS ${SDL_INCLUDE_DIR})
+  if(NOT TARGET SDL::SDL)
+    add_library(SDL::SDL INTERFACE IMPORTED)
+    set_target_properties(SDL::SDL PROPERTIES
+      INTERFACE_INCLUDE_DIRECTORIES "${SDL_INCLUDE_DIR}"
+      INTERFACE_LINK_LIBRARIES "${SDL_LIBRARY}")
+  endif()
+endif()
diff --git a/Modules/FindSQLite3.cmake b/Modules/FindSQLite3.cmake
index 374d7af..88c7dd2 100644
--- a/Modules/FindSQLite3.cmake
+++ b/Modules/FindSQLite3.cmake
@@ -5,6 +5,8 @@
 FindSQLite3
 -----------
 
+.. versionadded:: 3.14
+
 Find the SQLite libraries, v3
 
 IMPORTED targets
diff --git a/Modules/FindSWIG.cmake b/Modules/FindSWIG.cmake
index ae6ae56..2fded49 100644
--- a/Modules/FindSWIG.cmake
+++ b/Modules/FindSWIG.cmake
@@ -5,25 +5,49 @@
 FindSWIG
 --------
 
-Find Simplified Wrapper and Interface Generator (SWIG)
-
-This module finds an installed SWIG.  It sets the following variables:
-
-::
-
-  SWIG_FOUND - set to "True" if SWIG is found
-  SWIG_DIR - the directory where swig is installed
-  SWIG_EXECUTABLE - the path to the swig executable
-  SWIG_VERSION   - the version number of the swig executable
+Find the Simplified Wrapper and Interface Generator (SWIG_) executable.
 
 
+This module finds an installed SWIG and determines its version. If a
+``COMPONENTS`` or ``OPTIONAL_COMPONENTS`` argument is given to ``find_package``,
+it will also determine supported target languages.  The module sents the
+following variables:
 
-The minimum required version of SWIG can be specified using the
-standard syntax, e.g.   :command:`find_package(SWIG 1.1)`
+``SWIG_FOUND``
+  Whether SWIG and any required components were found on the system.
+``SWIG_EXECUTABLE``
+  Path to the SWIG executable.
+``SWIG_DIR``
+  Path to the installed SWIG ``Lib`` directory (result of ``swig -swiglib``).
+``SWIG_VERSION``
+  SWIG executable version (result of ``swig -version``).
+``SWIG_<lang>_FOUND``
+  If ``COMPONENTS`` or ``OPTIONAL_COMPONENTS`` are requested, each available
+  target language ``<lang>`` (lowercase) will be set to TRUE.
+
+Any ``COMPONENTS`` given to ``find_package`` should be the names of supported
+target languages as provided to the LANGUAGE argument of ``swig_add_library``,
+such as ``python`` or ``perl5``. Language names *must* be lowercase.
 
 All information is collected from the ``SWIG_EXECUTABLE``, so the version
 to be found can be changed from the command line by means of setting
-``SWIG_EXECUTABLE``
+``SWIG_EXECUTABLE``.
+
+Example usage requiring SWIG 4.0 or higher and Python language support, with
+optional Fortran support:
+
+.. code-block:: cmake
+
+   find_package(SWIG 4.0 COMPONENTS python OPTIONAL_COMPONENTS fortran)
+   if(SWIG_FOUND)
+     message("SWIG found: ${SWIG_EXECUTABLE}")
+     if(NOT SWIG_fortran_FOUND)
+       message(WARNING "SWIG Fortran bindings cannot be generated")
+     endif()
+   endif()
+
+.. _`SWIG`: http://swig.org
+
 #]=======================================================================]
 
 find_program(SWIG_EXECUTABLE NAMES swig4.0 swig3.0 swig2.0 swig)
@@ -58,10 +82,29 @@
       endif()
     endif()
   endif()
+
+  if(SWIG_FIND_COMPONENTS)
+    execute_process(COMMAND ${SWIG_EXECUTABLE} -help
+      OUTPUT_VARIABLE SWIG_swighelp_output
+      ERROR_VARIABLE SWIG_swighelp_error
+      RESULT_VARIABLE SWIG_swighelp_result)
+    if(SWIG_swighelp_result)
+      message(SEND_ERROR "Command \"${SWIG_EXECUTABLE} -help\" failed with output:\n${SWIG_swiglib_error}")
+    else()
+      string(REPLACE "\n" ";" SWIG_swighelp_output "${SWIG_swighelp_output}")
+      foreach(SWIG_line IN LISTS SWIG_swighelp_output)
+        if(SWIG_line MATCHES "-([A-Za-z0-9_]+) +- *Generate.*wrappers")
+          set(SWIG_${CMAKE_MATCH_1}_FOUND TRUE)
+        endif()
+      endforeach()
+    endif()
+  endif()
 endif()
 
 include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
-FIND_PACKAGE_HANDLE_STANDARD_ARGS(SWIG  REQUIRED_VARS SWIG_EXECUTABLE SWIG_DIR
-                                        VERSION_VAR SWIG_VERSION )
+find_package_handle_standard_args(
+  SWIG HANDLE_COMPONENTS
+  REQUIRED_VARS SWIG_EXECUTABLE SWIG_DIR
+  VERSION_VAR SWIG_VERSION)
 
 mark_as_advanced(SWIG_DIR SWIG_VERSION SWIG_EXECUTABLE)
diff --git a/Modules/FindSquish.cmake b/Modules/FindSquish.cmake
index 7d49505..91d1410 100644
--- a/Modules/FindSquish.cmake
+++ b/Modules/FindSquish.cmake
@@ -9,8 +9,7 @@
 
 
 
-This module can be used to find Squish.  Currently Squish versions 3
-and 4 are supported.
+This module can be used to find Squish.
 
 ::
 
@@ -39,12 +38,12 @@
 
 
 
-It provides the function squish_v4_add_test() for adding a squish test
-to cmake using Squish 4.x:
+It provides the function squish_add_test() for adding a squish test
+to cmake using Squish >= 4.x:
 
 ::
 
-   squish_v4_add_test(cmakeTestName
+   squish_add_test(cmakeTestName
      AUT targetName SUITE suiteName TEST squishTestName
      [SETTINGSGROUP group] [PRE_COMMAND command] [POST_COMMAND command] )
 
@@ -66,8 +65,7 @@
   the name of the squish test, i.e. the name of the subdirectory
   of the test inside the suite directory.
 ``SETTINGSGROUP group``
-  if specified, the given settings group will be used for executing the test.
-  If not specified, the groupname will be "CTest_<username>"
+  deprecated, this argument will be ignored.
 ``PRE_COMMAND command``
   if specified, the given command will be executed before starting the squish test.
 ``POST_COMMAND command``
@@ -78,13 +76,12 @@
 ::
 
    enable_testing()
-   find_package(Squish 4.0)
+   find_package(Squish 6.5)
    if (SQUISH_FOUND)
-      squish_v4_add_test(myTestName
+      squish_add_test(myTestName
         AUT myApp
         SUITE ${CMAKE_SOURCE_DIR}/tests/mySuite
         TEST someSquishTest
-        SETTINGSGROUP myGroup
         )
    endif ()
 
@@ -105,19 +102,12 @@
 ::
 
   enable_testing()
-  find_package(Squish)
+  find_package(Squish 3.0)
   if (SQUISH_FOUND)
     squish_v3_add_test(myTestName myApplication testCase envVars testWrapper)
   endif ()
 
 
-
-macro SQUISH_ADD_TEST(testName applicationUnderTest testCase envVars
-testWrapper)
-
-::
-
-   This is deprecated. Use SQUISH_V3_ADD_TEST() if you are using Squish 3.x instead.
 #]=======================================================================]
 
 set(SQUISH_INSTALL_DIR_STRING "Directory containing the bin, doc, and lib directories for Squish; this should be the root of the installation directory.")
@@ -137,7 +127,8 @@
   string(REPLACE "//" "/" SQUISH_INSTALL_DIR_SEARCH "${SQUISH_INSTALL_DIR_SEARCH}")
 
   # Look for an installation
-  find_path(SQUISH_INSTALL_DIR bin/squishrunner
+  find_path(SQUISH_INSTALL_DIR
+    NAMES bin/squishrunner bin/squishrunner.exe
     HINTS
     # Look for an environment variable SQUISH_INSTALL_DIR.
       ENV SQUISH_INSTALL_DIR
@@ -169,9 +160,9 @@
 
 
 set(SQUISH_VERSION)
-set(SQUISH_VERSION_MAJOR )
-set(SQUISH_VERSION_MINOR )
-set(SQUISH_VERSION_PATCH )
+set(SQUISH_VERSION_MAJOR)
+set(SQUISH_VERSION_MINOR)
+set(SQUISH_VERSION_PATCH)
 
 # record if executables are set
 if(SQUISH_CLIENT_EXECUTABLE)
@@ -203,8 +194,8 @@
 
 set(_SQUISH_MODULE_DIR "${CMAKE_CURRENT_LIST_DIR}")
 
-macro(SQUISH_V3_ADD_TEST testName testAUT testCase envVars testWraper)
-  if("${SQUISH_VERSION_MAJOR}" STREQUAL "4")
+macro(squish_v3_add_test testName testAUT testCase envVars testWraper)
+  if("${SQUISH_VERSION_MAJOR}" STRGREATER "3")
     message(STATUS "Using squish_v3_add_test(), but SQUISH_VERSION_MAJOR is ${SQUISH_VERSION_MAJOR}.\nThis may not work.")
   endif()
 
@@ -227,16 +218,9 @@
 endmacro()
 
 
-macro(SQUISH_ADD_TEST)
-  message(STATUS "Using squish_add_test() is deprecated, use squish_v3_add_test() instead.")
-  squish_v3_add_test(${ARGV})
-endmacro()
-
-
-function(SQUISH_V4_ADD_TEST testName)
-
-  if(NOT "${SQUISH_VERSION_MAJOR}" STREQUAL "4")
-    message(STATUS "Using squish_v4_add_test(), but SQUISH_VERSION_MAJOR is ${SQUISH_VERSION_MAJOR}.\nThis may not work.")
+function(squish_v4_add_test testName)
+  if(NOT "${SQUISH_VERSION_MAJOR}" STRGREATER "3")
+    message(STATUS "Using squish_add_test(), but SQUISH_VERSION_MAJOR is ${SQUISH_VERSION_MAJOR}.\nThis may not work.")
   endif()
 
   set(oneValueArgs AUT SUITE TEST SETTINGSGROUP PRE_COMMAND POST_COMMAND)
@@ -259,10 +243,6 @@
     message(FATAL_ERROR "Required argument TEST not given for SQUISH_ADD_TEST()")
   endif()
 
-  get_target_property(testAUTLocation ${_SQUISH_AUT} LOCATION)
-  get_filename_component(testAUTDir ${testAUTLocation} PATH)
-  get_filename_component(testAUTName ${testAUTLocation} NAME)
-
   get_filename_component(absTestSuite "${_SQUISH_SUITE}" ABSOLUTE)
   if(NOT EXISTS "${absTestSuite}")
     message(FATAL_ERROR "Could not find squish test suite ${_SQUISH_SUITE} (checked ${absTestSuite})")
@@ -273,15 +253,15 @@
     message(FATAL_ERROR "Could not find squish testcase ${_SQUISH_TEST} (checked ${absTestCase})")
   endif()
 
-  if(NOT _SQUISH_SETTINGSGROUP)
-    set(_SQUISH_SETTINGSGROUP "CTest_$ENV{LOGNAME}")
+  if(_SQUISH_SETTINGSGROUP)
+    message("SETTINGSGROUP is deprecated and will be ignored.")
   endif()
 
-  add_test(${testName}
-    ${CMAKE_COMMAND} -V -VV
+  add_test(NAME ${testName}
+    COMMAND ${CMAKE_COMMAND} -V -VV
     "-Dsquish_version:STRING=4"
-    "-Dsquish_aut:STRING=${testAUTName}"
-    "-Dsquish_aut_dir:STRING=${testAUTDir}"
+    "-Dsquish_aut:STRING=$<TARGET_FILE_BASE_NAME:${_SQUISH_AUT}>"
+    "-Dsquish_aut_dir:STRING=$<TARGET_FILE_DIR:${_SQUISH_AUT}>"
     "-Dsquish_server_executable:STRING=${SQUISH_SERVER_EXECUTABLE}"
     "-Dsquish_client_executable:STRING=${SQUISH_CLIENT_EXECUTABLE}"
     "-Dsquish_libqtdir:STRING=${QT_LIBRARY_DIR}"
@@ -290,7 +270,6 @@
     "-Dsquish_env_vars:STRING=${envVars}"
     "-Dsquish_wrapper:STRING=${testWraper}"
     "-Dsquish_module_dir:STRING=${_SQUISH_MODULE_DIR}"
-    "-Dsquish_settingsgroup:STRING=${_SQUISH_SETTINGSGROUP}"
     "-Dsquish_pre_command:STRING=${_SQUISH_PRE_COMMAND}"
     "-Dsquish_post_command:STRING=${_SQUISH_POST_COMMAND}"
     -P "${_SQUISH_MODULE_DIR}/SquishTestScript.cmake"
@@ -299,3 +278,11 @@
     PROPERTIES FAIL_REGULAR_EXPRESSION "FAIL;FAILED;ERROR;FATAL"
     )
 endfunction()
+
+macro(squish_add_test)
+  if("${SQUISH_VERSION_MAJOR}" STRGREATER "3")
+    squish_v4_add_test(${ARGV})
+  else()
+    squish_v3_add_test(${ARGV})
+  endif()
+endmacro()
diff --git a/Modules/FindTCL.cmake b/Modules/FindTCL.cmake
index 960265f..9b771dc 100644
--- a/Modules/FindTCL.cmake
+++ b/Modules/FindTCL.cmake
@@ -223,6 +223,12 @@
 
 include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
 
+if (CMAKE_FIND_PACKAGE_NAME STREQUAL "TclStub")
+  # FindTclStub include()'s this module. It's an old pattern, but rather than
+  # trying to suppress this from outside the module (which is then sensitive to
+  # the contents, detect the case in this module and suppress it explicitly.
+  set(FPHSA_NAME_MISMATCHED 1)
+endif ()
 FIND_PACKAGE_HANDLE_STANDARD_ARGS(TCL DEFAULT_MSG TCL_LIBRARY TCL_INCLUDE_PATH)
 set(FPHSA_NAME_MISMATCHED 1)
 set(TCLTK_FIND_REQUIRED ${TCL_FIND_REQUIRED})
diff --git a/Modules/FindTIFF.cmake b/Modules/FindTIFF.cmake
index 00a3a41..3b74c94 100644
--- a/Modules/FindTIFF.cmake
+++ b/Modules/FindTIFF.cmake
@@ -5,7 +5,14 @@
 FindTIFF
 --------
 
-Find the TIFF library (``libtiff``).
+Find the TIFF library (``libtiff``, https://libtiff.gitlab.io/libtiff/).
+
+Optional COMPONENTS
+^^^^^^^^^^^^^^^^^^^
+
+This module supports the optional component `CXX`, for use with the COMPONENTS
+argument of the :command:`find_package` command. This component has an associated
+imported target, as described below.
 
 Imported targets
 ^^^^^^^^^^^^^^^^
@@ -15,6 +22,11 @@
 ``TIFF::TIFF``
   The TIFF library, if found.
 
+``TIFF::CXX``
+  The C++ wrapper libtiffxx, if requested by the `COMPONENTS CXX` option,
+  if the compiler is not MSVC (which includes the C++ wrapper in libtiff),
+  and if found.
+
 Result variables
 ^^^^^^^^^^^^^^^^
 
@@ -36,10 +48,19 @@
 
 ``TIFF_INCLUDE_DIR``
   the directory containing the TIFF headers
-``TIFF_LIBRARY``
-  the path to the TIFF library
+``TIFF_LIBRARY_RELEASE``
+  the path to the TIFF library for release configurations
+``TIFF_LIBRARY_DEBUG``
+  the path to the TIFF library for debug configurations
+``TIFFXX_LIBRARY_RELEASE``
+  the path to the TIFFXX library for release configurations
+``TIFFXX_LIBRARY_DEBUG``
+  the path to the TIFFXX library for debug configurations
 #]=======================================================================]
 
+cmake_policy(PUSH)
+cmake_policy(SET CMP0057 NEW)
+
 find_path(TIFF_INCLUDE_DIR tiff.h)
 
 set(TIFF_NAMES ${TIFF_NAMES} tiff libtiff tiff3 libtiff3)
@@ -54,8 +75,6 @@
   select_library_configurations(TIFF)
   mark_as_advanced(TIFF_LIBRARY_RELEASE TIFF_LIBRARY_DEBUG)
 endif()
-unset(TIFF_NAMES)
-unset(TIFF_NAMES_DEBUG)
 
 if(TIFF_INCLUDE_DIR AND EXISTS "${TIFF_INCLUDE_DIR}/tiffvers.h")
     file(STRINGS "${TIFF_INCLUDE_DIR}/tiffvers.h" tiff_version_str
@@ -66,13 +85,46 @@
     unset(tiff_version_str)
 endif()
 
+foreach(_comp IN LISTS TIFF_FIND_COMPONENTS)
+  if(_comp STREQUAL "CXX")
+    if(MSVC)
+      # C++ bindings are built into the main tiff library.
+      set(TIFF_CXX_FOUND 1)
+    else()
+      foreach(name ${TIFF_NAMES})
+        list(APPEND TIFFXX_NAMES "${name}xx")
+        list(APPEND TIFFXX_NAMES_DEBUG "${name}xxd")
+      endforeach()
+      find_library(TIFFXX_LIBRARY_RELEASE NAMES ${TIFFXX_NAMES})
+      find_library(TIFFXX_LIBRARY_DEBUG NAMES ${TIFFXX_NAMES_DEBUG})
+      include(${CMAKE_CURRENT_LIST_DIR}/SelectLibraryConfigurations.cmake)
+      select_library_configurations(TIFFXX)
+      mark_as_advanced(TIFFXX_LIBRARY_RELEASE TIFFXX_LIBRARY_DEBUG)
+      unset(TIFFXX_NAMES)
+      unset(TIFFXX_NAMES_DEBUG)
+      if(TIFFXX_LIBRARY)
+        set(TIFF_CXX_FOUND 1)
+      endif()
+    endif()
+  endif()
+endforeach()
+unset(_comp)
+
+unset(TIFF_NAMES)
+unset(TIFF_NAMES_DEBUG)
+
 include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
 FIND_PACKAGE_HANDLE_STANDARD_ARGS(TIFF
+                                  HANDLE_COMPONENTS
                                   REQUIRED_VARS TIFF_LIBRARY TIFF_INCLUDE_DIR
                                   VERSION_VAR TIFF_VERSION_STRING)
 
 if(TIFF_FOUND)
   set(TIFF_LIBRARIES ${TIFF_LIBRARY})
+  if("CXX" IN_LIST TIFF_FIND_COMPONENTS AND NOT MSVC)
+    list(APPEND TIFF_LIBRARIES ${TIFFXX_LIBRARY})
+  endif()
+
   set(TIFF_INCLUDE_DIRS "${TIFF_INCLUDE_DIR}")
 
   if(NOT TARGET TIFF::TIFF)
@@ -101,6 +153,41 @@
         IMPORTED_LOCATION_DEBUG "${TIFF_LIBRARY_DEBUG}")
     endif()
   endif()
+
+  if(NOT TARGET TIFF::CXX)
+    if(MSVC)
+      add_library(TIFF::CXX INTERFACE IMPORTED)
+      set_property(TARGET TIFF::CXX PROPERTY INTERFACE_LINK_LIBRARIES TIFF::TIFF)
+    else()
+      add_library(TIFF::CXX UNKNOWN IMPORTED)
+      set_property(TARGET TIFF::CXX PROPERTY INTERFACE_LINK_LIBRARIES TIFF::TIFF)
+      if(TIFF_INCLUDE_DIRS)
+        set_target_properties(TIFF::CXX PROPERTIES
+          INTERFACE_INCLUDE_DIRECTORIES "${TIFF_INCLUDE_DIRS}")
+      endif()
+      if(EXISTS "${TIFFXX_LIBRARY}")
+        set_target_properties(TIFF::CXX PROPERTIES
+          IMPORTED_LINK_INTERFACE_LANGUAGES "CXX"
+          IMPORTED_LOCATION "${TIFFXX_LIBRARY}")
+      endif()
+      if(EXISTS "${TIFFXX_LIBRARY_RELEASE}")
+        set_property(TARGET TIFF::CXX APPEND PROPERTY
+          IMPORTED_CONFIGURATIONS RELEASE)
+        set_target_properties(TIFF::CXX PROPERTIES
+          IMPORTED_LINK_INTERFACE_LANGUAGES_RELEASE "CXX"
+          IMPORTED_LOCATION_RELEASE "${TIFFXX_LIBRARY_RELEASE}")
+      endif()
+      if(EXISTS "${TIFFXX_LIBRARY_DEBUG}")
+        set_property(TARGET TIFF::CXX APPEND PROPERTY
+          IMPORTED_CONFIGURATIONS DEBUG)
+        set_target_properties(TIFF::CXX PROPERTIES
+          IMPORTED_LINK_INTERFACE_LANGUAGES_DEBUG "CXX"
+          IMPORTED_LOCATION_DEBUG "${TIFFXX_LIBRARY_DEBUG}")
+      endif()
+    endif()
+  endif()
+
 endif()
 
-mark_as_advanced(TIFF_INCLUDE_DIR TIFF_LIBRARY)
+mark_as_advanced(TIFF_INCLUDE_DIR)
+cmake_policy(POP)
diff --git a/Modules/FindTclsh.cmake b/Modules/FindTclsh.cmake
index 82be473..594d0ec 100644
--- a/Modules/FindTclsh.cmake
+++ b/Modules/FindTclsh.cmake
@@ -15,15 +15,8 @@
 
   TCLSH_FOUND = TRUE if tclsh has been found
   TCL_TCLSH = the path to the tclsh executable
-
-In cygwin, look for the cygwin version first.  Don't look for it later
-to avoid finding the cygwin version on a Win32 build.
 #]=======================================================================]
 
-if(CYGWIN)
-  find_program(TCL_TCLSH NAMES cygtclsh83 cygtclsh80)
-endif()
-
 get_filename_component(TK_WISH_PATH "${TK_WISH}" PATH)
 get_filename_component(TK_WISH_PATH_PARENT "${TK_WISH_PATH}" PATH)
 string(REGEX REPLACE
@@ -92,8 +85,17 @@
 endif()
 
 include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
+if (CMAKE_FIND_PACKAGE_NAME STREQUAL "TCL" OR
+    CMAKE_FIND_PACKAGE_NAME STREQUAL "TclStub")
+  # FindTCL include()'s this module. It's an old pattern, but rather than
+  # trying to suppress this from outside the module (which is then sensitive to
+  # the contents, detect the case in this module and suppress it explicitly.
+  # Transitively, FindTclStub includes FindTCL.
+  set(FPHSA_NAME_MISMATCHED 1)
+endif ()
 FIND_PACKAGE_HANDLE_STANDARD_ARGS(Tclsh
                                   REQUIRED_VARS TCL_TCLSH
                                   VERSION_VAR TCLSH_VERSION_STRING)
+unset(FPHSA_NAME_MISMATCHED)
 
 mark_as_advanced(TCL_TCLSH)
diff --git a/Modules/FindThreads.cmake b/Modules/FindThreads.cmake
index f97e5c8..ee49867 100644
--- a/Modules/FindThreads.cmake
+++ b/Modules/FindThreads.cmake
@@ -238,8 +238,8 @@
 
   if(THREADS_HAVE_PTHREAD_ARG)
     set_property(TARGET Threads::Threads
-                 PROPERTY INTERFACE_COMPILE_OPTIONS "$<$<COMPILE_LANGUAGE:CUDA>:SHELL:-Xcompiler -pthread>"
-                                                    "$<$<NOT:$<COMPILE_LANGUAGE:CUDA>>:-pthread>")
+                 PROPERTY INTERFACE_COMPILE_OPTIONS "$<$<COMPILE_LANG_AND_ID:CUDA,NVIDIA>:SHELL:-Xcompiler -pthread>"
+                                                    "$<$<NOT:$<COMPILE_LANG_AND_ID:CUDA,NVIDIA>>:-pthread>")
   endif()
 
   if(CMAKE_THREAD_LIBS_INIT)
diff --git a/Modules/FindVulkan.cmake b/Modules/FindVulkan.cmake
index 55da55f..0ec6013 100644
--- a/Modules/FindVulkan.cmake
+++ b/Modules/FindVulkan.cmake
@@ -5,6 +5,8 @@
 FindVulkan
 ----------
 
+.. versionadded:: 3.7
+
 Find Vulkan, which is a low-overhead, cross-platform 3D graphics
 and computing API.
 
@@ -14,6 +16,9 @@
 This module defines :prop_tgt:`IMPORTED` target ``Vulkan::Vulkan``, if
 Vulkan has been found.
 
+This module defines :prop_tgt:`IMPORTED` target ``Vulkan::glslc``, if
+Vulkan and the GLSLC SPIR-V compiler has been found.
+
 Result Variables
 ^^^^^^^^^^^^^^^^
 
@@ -23,45 +28,65 @@
   Vulkan_INCLUDE_DIRS   - include directories for Vulkan
   Vulkan_LIBRARIES      - link against this library to use Vulkan
 
-The module will also define two cache variables::
+The module will also define three cache variables::
 
-  Vulkan_INCLUDE_DIR    - the Vulkan include directory
-  Vulkan_LIBRARY        - the path to the Vulkan library
+  Vulkan_INCLUDE_DIR        - the Vulkan include directory
+  Vulkan_LIBRARY            - the path to the Vulkan library
+  Vulkan_GLSLC_EXECUTABLE   - the path to the GLSL SPIR-V compiler
+
+Hints
+^^^^^
+
+The ``VULKAN_SDK`` environment variable optionally specifies the
+location of the Vulkan SDK root directory for the given
+architecture. It is typically set by sourcing the toplevel
+``setup-env.sh`` script of the Vulkan SDK directory into the shell
+environment.
 
 #]=======================================================================]
 
 if(WIN32)
   find_path(Vulkan_INCLUDE_DIR
     NAMES vulkan/vulkan.h
-    PATHS
+    HINTS
       "$ENV{VULKAN_SDK}/Include"
     )
 
   if(CMAKE_SIZEOF_VOID_P EQUAL 8)
     find_library(Vulkan_LIBRARY
       NAMES vulkan-1
-      PATHS
+      HINTS
         "$ENV{VULKAN_SDK}/Lib"
         "$ENV{VULKAN_SDK}/Bin"
-        )
+      )
+    find_program(Vulkan_GLSLC_EXECUTABLE
+      NAMES glslc
+      HINTS
+        "$ENV{VULKAN_SDK}/Bin"
+      )
   elseif(CMAKE_SIZEOF_VOID_P EQUAL 4)
     find_library(Vulkan_LIBRARY
       NAMES vulkan-1
-      PATHS
+      HINTS
         "$ENV{VULKAN_SDK}/Lib32"
         "$ENV{VULKAN_SDK}/Bin32"
-        NO_SYSTEM_ENVIRONMENT_PATH
-        )
+      )
+    find_program(Vulkan_GLSLC_EXECUTABLE
+      NAMES glslc
+      HINTS
+        "$ENV{VULKAN_SDK}/Bin32"
+      )
   endif()
 else()
-    find_path(Vulkan_INCLUDE_DIR
-      NAMES vulkan/vulkan.h
-      PATHS
-        "$ENV{VULKAN_SDK}/include")
-    find_library(Vulkan_LIBRARY
-      NAMES vulkan
-      PATHS
-        "$ENV{VULKAN_SDK}/lib")
+  find_path(Vulkan_INCLUDE_DIR
+    NAMES vulkan/vulkan.h
+    HINTS "$ENV{VULKAN_SDK}/include")
+  find_library(Vulkan_LIBRARY
+    NAMES vulkan
+    HINTS "$ENV{VULKAN_SDK}/lib")
+  find_program(Vulkan_GLSLC_EXECUTABLE
+    NAMES glslc
+    HINTS "$ENV{VULKAN_SDK}/bin")
 endif()
 
 set(Vulkan_LIBRARIES ${Vulkan_LIBRARY})
@@ -72,7 +97,7 @@
   DEFAULT_MSG
   Vulkan_LIBRARY Vulkan_INCLUDE_DIR)
 
-mark_as_advanced(Vulkan_INCLUDE_DIR Vulkan_LIBRARY)
+mark_as_advanced(Vulkan_INCLUDE_DIR Vulkan_LIBRARY Vulkan_GLSLC_EXECUTABLE)
 
 if(Vulkan_FOUND AND NOT TARGET Vulkan::Vulkan)
   add_library(Vulkan::Vulkan UNKNOWN IMPORTED)
@@ -80,3 +105,8 @@
     IMPORTED_LOCATION "${Vulkan_LIBRARIES}"
     INTERFACE_INCLUDE_DIRECTORIES "${Vulkan_INCLUDE_DIRS}")
 endif()
+
+if(Vulkan_FOUND AND Vulkan_GLSLC_EXECUTABLE AND NOT TARGET Vulkan::glslc)
+  add_executable(Vulkan::glslc IMPORTED)
+  set_property(TARGET Vulkan::glslc PROPERTY IMPORTED_LOCATION "${Vulkan_GLSLC_EXECUTABLE}")
+endif()
diff --git a/Modules/FindX11.cmake b/Modules/FindX11.cmake
index b28dd12..778da9b 100644
--- a/Modules/FindX11.cmake
+++ b/Modules/FindX11.cmake
@@ -25,6 +25,10 @@
   X11_Xaccessrules_INCLUDE_PATH,
   X11_Xaccessstr_INCLUDE_PATH,                       X11_Xaccess_FOUND
   X11_Xau_INCLUDE_PATH,          X11_Xau_LIB,        X11_Xau_FOUND,        X11::Xau
+  X11_xcb_INCLUDE_PATH,          X11_xcb_LIB,        X11_xcb_FOUND,        X11::xcb
+  X11_X11_xcb_INCLUDE_PATH,      X11_X11_xcb_LIB,    X11_X11_xcb_FOUND,    X11::X11_xcb
+  X11_xcb_icccm_INCLUDE_PATH,    X11_xcb_icccm_LIB,  X11_xcb_icccm_FOUND,  X11::xcb_icccm
+  X11_xcb_xkb_INCLUDE_PATH,      X11_xcb_xkb_LIB,    X11_xcb_xkb_FOUND,    X11::xcb_xkb
   X11_Xcomposite_INCLUDE_PATH,   X11_Xcomposite_LIB, X11_Xcomposite_FOUND, X11::Xcomposite
   X11_Xcursor_INCLUDE_PATH,      X11_Xcursor_LIB,    X11_Xcursor_FOUND,    X11::Xcursor
   X11_Xdamage_INCLUDE_PATH,      X11_Xdamage_LIB,    X11_Xdamage_FOUND,    X11::Xdamage
@@ -38,6 +42,8 @@
   X11_Xinerama_INCLUDE_PATH,     X11_Xinerama_LIB,   X11_Xinerama_FOUND,   X11::Xinerama
   X11_Xkb_INCLUDE_PATH,
   X11_Xkblib_INCLUDE_PATH,                           X11_Xkb_FOUND,        X11::Xkb
+  X11_xkbcommon_INCLUDE_PATH,    X11_xkbcommon_LIB,  X11_xkbcommon_FOUND,  X11::xkbcommon
+  X11_xkbcommon_X11_INCLUDE_PATH,X11_xkbcommon_X11_LIB,X11_xkbcommon_X11_FOUND,X11::xkbcommon_X11
   X11_xkbfile_INCLUDE_PATH,      X11_xkbfile_LIB,    X11_xkbfile_FOUND,    X11::xkbfile
   X11_Xmu_INCLUDE_PATH,          X11_Xmu_LIB,        X11_Xmu_FOUND,        X11::Xmu
   X11_Xpm_INCLUDE_PATH,          X11_Xpm_LIB,        X11_Xpm_FOUND,        X11::Xpm
@@ -53,6 +59,7 @@
   X11_XShm_INCLUDE_PATH,         (in X11_Xext_LIB),  X11_XShm_FOUND
   X11_Xshape_INCLUDE_PATH,       (in X11_Xext_LIB),  X11_Xshape_FOUND
   X11_XSync_INCLUDE_PATH,        (in X11_Xext_LIB),  X11_XSync_FOUND
+  X11_Xaw_INCLUDE_PATH,          X11_Xaw_LIB         X11_Xaw_FOUND         X11::Xaw
 #]=======================================================================]
 
 if (UNIX)
@@ -94,6 +101,10 @@
   find_path(X11_Xaccessrules_INCLUDE_PATH X11/extensions/XKBrules.h  ${X11_INC_SEARCH_PATH})
   find_path(X11_Xaccessstr_INCLUDE_PATH X11/extensions/XKBstr.h      ${X11_INC_SEARCH_PATH})
   find_path(X11_Xau_INCLUDE_PATH X11/Xauth.h                         ${X11_INC_SEARCH_PATH})
+  find_path(X11_Xaw_INCLUDE_PATH X11/Xaw/Intrinsic.h                 ${X11_INC_SEARCH_PATH})
+  find_path(X11_xcb_INCLUDE_PATH xcb/xcb.h                           ${X11_INC_SEARCH_PATH})
+  find_path(X11_X11_xcb_INCLUDE_PATH X11/Xlib-xcb.h                  ${X11_INC_SEARCH_PATH})
+  find_path(X11_xcb_icccm_INCLUDE_PATH xcb/xcb_icccm.h               ${X11_INC_SEARCH_PATH})
   find_path(X11_Xcomposite_INCLUDE_PATH X11/extensions/Xcomposite.h  ${X11_INC_SEARCH_PATH})
   find_path(X11_Xcursor_INCLUDE_PATH X11/Xcursor/Xcursor.h           ${X11_INC_SEARCH_PATH})
   find_path(X11_Xdamage_INCLUDE_PATH X11/extensions/Xdamage.h        ${X11_INC_SEARCH_PATH})
@@ -107,6 +118,8 @@
   find_path(X11_Xi_INCLUDE_PATH X11/extensions/XInput.h              ${X11_INC_SEARCH_PATH})
   find_path(X11_Xinerama_INCLUDE_PATH X11/extensions/Xinerama.h      ${X11_INC_SEARCH_PATH})
   find_path(X11_Xkb_INCLUDE_PATH X11/extensions/XKB.h                ${X11_INC_SEARCH_PATH})
+  find_path(X11_xkbcommon_INCLUDE_PATH xkbcommon/xkbcommon.h         ${X11_INC_SEARCH_PATH})
+  find_path(X11_xkbcommon_X11_INCLUDE_PATH xkbcommon/xkbcommon-x11.h ${X11_INC_SEARCH_PATH})
   find_path(X11_Xkblib_INCLUDE_PATH X11/XKBlib.h                     ${X11_INC_SEARCH_PATH})
   find_path(X11_xkbfile_INCLUDE_PATH X11/extensions/XKBfile.h        ${X11_INC_SEARCH_PATH})
   find_path(X11_Xmu_INCLUDE_PATH X11/Xmu/Xmu.h                       ${X11_INC_SEARCH_PATH})
@@ -123,6 +136,8 @@
   find_path(X11_Xv_INCLUDE_PATH X11/extensions/Xvlib.h               ${X11_INC_SEARCH_PATH})
   find_path(X11_XSync_INCLUDE_PATH X11/extensions/sync.h             ${X11_INC_SEARCH_PATH})
 
+
+
   # Backwards compatibility.
   set(X11_Xinput_INCLUDE_PATH "${X11_Xi_INCLUDE_PATH}")
   set(X11_xf86misc_INCLUDE_PATH "${X11_Xxf86misc_INCLUDE_PATH}")
@@ -137,6 +152,11 @@
   find_library(X11_ICE_LIB ICE               ${X11_LIB_SEARCH_PATH})
   find_library(X11_SM_LIB SM                 ${X11_LIB_SEARCH_PATH})
   find_library(X11_Xau_LIB Xau               ${X11_LIB_SEARCH_PATH})
+  find_library(X11_Xaw_LIB Xaw               ${X11_LIB_SEARCH_PATH})
+  find_library(X11_xcb_LIB xcb               ${X11_LIB_SEARCH_PATH})
+  find_library(X11_X11_xcb_LIB X11-xcb       ${X11_LIB_SEARCH_PATH})
+  find_library(X11_xcb_icccm_LIB xcb-icccm   ${X11_LIB_SEARCH_PATH})
+  find_library(X11_xcb_xkb_LIB xcb-xkb       ${X11_LIB_SEARCH_PATH})
   find_library(X11_Xcomposite_LIB Xcomposite ${X11_LIB_SEARCH_PATH})
   find_library(X11_Xcursor_LIB Xcursor       ${X11_LIB_SEARCH_PATH})
   find_library(X11_Xdamage_LIB Xdamage       ${X11_LIB_SEARCH_PATH})
@@ -146,6 +166,8 @@
   find_library(X11_Xft_LIB Xft               ${X11_LIB_SEARCH_PATH})
   find_library(X11_Xi_LIB Xi                 ${X11_LIB_SEARCH_PATH})
   find_library(X11_Xinerama_LIB Xinerama     ${X11_LIB_SEARCH_PATH})
+  find_library(X11_xkbcommon_LIB xkbcommon   ${X11_LIB_SEARCH_PATH})
+  find_library(X11_xkbcommon_X11_LIB xkbcommon-x11   ${X11_LIB_SEARCH_PATH})
   find_library(X11_xkbfile_LIB xkbfile       ${X11_LIB_SEARCH_PATH})
   find_library(X11_Xmu_LIB Xmu               ${X11_LIB_SEARCH_PATH})
   find_library(X11_Xpm_LIB Xpm               ${X11_LIB_SEARCH_PATH})
@@ -221,6 +243,22 @@
     set(X11_Xau_FOUND TRUE)
   endif ()
 
+  if (X11_xcb_LIB AND X11_xcb_INCLUDE_PATH)
+    set(X11_xcb_FOUND TRUE)
+  endif ()
+
+  if (X11_X11_xcb_LIB AND X11_X11_xcb_INCLUDE_PATH)
+    set(X11_X11_xcb_FOUND TRUE)
+  endif ()
+
+  if (X11_xcb_icccm_LIB AND X11_xcb_icccm_INCLUDE_PATH)
+    set(X11_xcb_icccm_FOUND TRUE)
+  endif ()
+
+  if (X11_xcb_xkb_LIB)
+    set(X11_xcb_xkb_FOUND TRUE)
+  endif ()
+
   if (X11_Xdmcp_INCLUDE_PATH AND X11_Xdmcp_LIB)
       set(X11_Xdmcp_FOUND TRUE)
       list(APPEND X11_INCLUDE_DIR ${X11_Xdmcp_INCLUDE_PATH})
@@ -326,6 +364,14 @@
      list(APPEND X11_INCLUDE_DIR ${X11_Xkb_INCLUDE_PATH} )
   endif ()
 
+  if (X11_xkbcommon_INCLUDE_PATH AND X11_xkbcommon_LIB)
+     set(X11_xkbcommon_FOUND TRUE)
+  endif ()
+
+  if (X11_xkbcommon_X11_INCLUDE_PATH AND X11_xkbcommon_X11_LIB)
+     set(X11_xkbcommon_X11_FOUND TRUE)
+  endif ()
+
   if (X11_xkbfile_INCLUDE_PATH AND X11_xkbfile_LIB AND X11_Xlib_INCLUDE_PATH)
      set(X11_xkbfile_FOUND TRUE)
      # Backwards compatibility.
@@ -351,6 +397,10 @@
      set(X11_SM_FOUND TRUE)
   endif()
 
+  if(X11_Xaw_LIB AND X11_Xaw_INCLUDE_PATH)
+      set(X11_Xaw_FOUND TRUE)
+  endif()
+
   # Most of the X11 headers will be in the same directories, avoid
   # creating a huge list of duplicates.
   if (X11_INCLUDE_DIR)
@@ -363,9 +413,17 @@
   endif ()
 
   include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
+  if (CMAKE_FIND_PACKAGE_NAME STREQUAL "FLTK")
+    # FindFLTK include()'s this module. It's an old pattern, but rather than
+    # trying to suppress this from outside the module (which is then sensitive
+    # to the contents, detect the case in this module and suppress it
+    # explicitly.
+    set(FPHSA_NAME_MISMATCHED 1)
+  endif ()
   find_package_handle_standard_args(X11
     REQUIRED_VARS X11_X11_INCLUDE_PATH X11_X11_LIB
     HANDLE_COMPONENTS)
+  unset(FPHSA_NAME_MISMATCHED)
 
   if(X11_FOUND)
     include(${CMAKE_CURRENT_LIST_DIR}/CheckFunctionExists.cmake)
@@ -478,6 +536,43 @@
       INTERFACE_INCLUDE_DIRECTORIES "${X11_Xau_INCLUDE_PATH}")
   endif ()
 
+  if (X11_Xaw_FOUND AND NOT TARGET X11::Xaw)
+    add_library(X11::Xaw UNKNOWN IMPORTED)
+    set_target_properties(X11::Xaw PROPERTIES
+      IMPORTED_LOCATION "${X11_Xaw_LIB}"
+      INTERFACE_INCLUDE_DIRECTORIES "${X11_Xaw_INCLUDE_PATH}"
+      INTERFACE_LINK_LIBRARIES "X11::Xext;X11::Xmu;X11::Xt;X11::Xpm;X11::X11")
+  endif ()
+
+  if (X11_xcb_FOUND AND NOT TARGET X11::xcb)
+    add_library(X11::xcb UNKNOWN IMPORTED)
+    set_target_properties(X11::xcb PROPERTIES
+      IMPORTED_LOCATION "${X11_xcb_LIB}"
+      INTERFACE_INCLUDE_DIRECTORIES "${X11_xcb_INCLUDE_PATH}")
+  endif ()
+
+  if (X11_X11_xcb_FOUND AND NOT TARGET X11::X11_xcb)
+    add_library(X11::X11_xcb UNKNOWN IMPORTED)
+    set_target_properties(X11::X11_xcb PROPERTIES
+      IMPORTED_LOCATION "${X11_X11_xcb_LIB}"
+      INTERFACE_INCLUDE_DIRECTORIES "${X11_X11_xcb_INCLUDE_PATH}"
+      INTERFACE_LINK_LIBRARIES "X11::xcb;X11::X11")
+  endif ()
+
+  if (X11_xcb_icccm_FOUND AND NOT TARGET X11::xcb_icccm)
+    add_library(X11::xcb_icccm UNKNOWN IMPORTED)
+    set_target_properties(X11::xcb_icccm PROPERTIES
+      IMPORTED_LOCATION "${X11_xcb_icccm_LIB}"
+      INTERFACE_LINK_LIBRARIES "X11::xcb")
+  endif ()
+
+  if (X11_xcb_xkb_FOUND AND NOT TARGET X11::xcb_xkb)
+    add_library(X11::xcb_xkb UNKNOWN IMPORTED)
+    set_target_properties(X11::xcb_xkb PROPERTIES
+      IMPORTED_LOCATION "${X11_xcb_xkb_LIB}"
+      INTERFACE_LINK_LIBRARIES "X11::xcb")
+  endif ()
+
   if (X11_Xcomposite_FOUND AND NOT TARGET X11::Xcomposite)
     add_library(X11::Xcomposite UNKNOWN IMPORTED)
     set_target_properties(X11::Xcomposite PROPERTIES
@@ -572,6 +667,21 @@
       INTERFACE_LINK_LIBRARIES "X11::X11")
   endif ()
 
+  if (X11_xkbcommon_FOUND AND NOT TARGET X11::xkbcommon)
+    add_library(X11::xkbcommon UNKNOWN IMPORTED)
+    set_target_properties(X11::xkbcommon PROPERTIES
+      IMPORTED_LOCATION "${X11_xkbcommon_LIB}"
+      INTERFACE_INCLUDE_DIRECTORIES "${X11_xkbcommon_INCLUDE_PATH}")
+  endif ()
+
+  if (X11_xkbcommon_X11_FOUND AND NOT TARGET X11::xkbcommon_X11)
+    add_library(X11::xkbcommon_X11 UNKNOWN IMPORTED)
+    set_target_properties(X11::xkbcommon_X11 PROPERTIES
+      IMPORTED_LOCATION "${X11_xkbcommon_X11_LIB}"
+      INTERFACE_INCLUDE_DIRECTORIES "${X11_xkbcommon_X11_INCLUDE_PATH}"
+      INTERFACE_LINK_LIBRARIES "X11::X11;X11::xkbcommon")
+  endif ()
+
   if (X11_xkbfile_FOUND AND NOT TARGET X11::xkbfile)
     add_library(X11::xkbfile UNKNOWN IMPORTED)
     set_target_properties(X11::xkbfile PROPERTIES
@@ -668,6 +778,11 @@
     X11_Xext_LIB
     X11_Xau_LIB
     X11_Xau_INCLUDE_PATH
+    X11_xcb_LIB
+    X11_xcb_INCLUDE_PATH
+    X11_xcb_xkb_LIB
+    X11_X11_xcb_LIB
+    X11_X11_xcb_INCLUDE_PATH
     X11_Xlib_INCLUDE_PATH
     X11_Xutil_INCLUDE_PATH
     X11_Xcomposite_INCLUDE_PATH
@@ -704,6 +819,10 @@
     X11_Xdmcp_INCLUDE_PATH
     X11_Xkb_INCLUDE_PATH
     X11_Xkblib_INCLUDE_PATH
+    X11_xkbcommon_INCLUDE_PATH
+    X11_xkbcommon_LIB
+    X11_xkbcommon_X11_INCLUDE_PATH
+    X11_xkbcommon_X11_LIB
     X11_xkbfile_INCLUDE_PATH
     X11_xkbfile_LIB
     X11_Xmu_INCLUDE_PATH
@@ -723,6 +842,8 @@
     X11_SM_LIB
     X11_SM_INCLUDE_PATH
     X11_XSync_INCLUDE_PATH
+    X11_Xaw_LIB
+    X11_Xaw_INCLUDE_PATH
   )
   set(CMAKE_FIND_FRAMEWORK ${CMAKE_FIND_FRAMEWORK_SAVE})
   set(CMAKE_REQUIRED_QUIET ${CMAKE_REQUIRED_QUIET_SAVE})
diff --git a/Modules/FindXCTest.cmake b/Modules/FindXCTest.cmake
index 15721e1..1f6e825 100644
--- a/Modules/FindXCTest.cmake
+++ b/Modules/FindXCTest.cmake
@@ -5,6 +5,8 @@
 FindXCTest
 ----------
 
+.. versionadded:: 3.3
+
 Functions to help creating and executing XCTest bundles.
 
 An XCTest bundle is a CFBundle with a special product-type
diff --git a/Modules/FindXalanC.cmake b/Modules/FindXalanC.cmake
index 3adaa44..a7fb766 100644
--- a/Modules/FindXalanC.cmake
+++ b/Modules/FindXalanC.cmake
@@ -5,6 +5,8 @@
 FindXalanC
 -----------
 
+.. versionadded:: 3.5
+
 Find the Apache Xalan-C++ XSL transform processor headers and libraries.
 
 Imported targets
@@ -47,9 +49,9 @@
 function(_XalanC_GET_VERSION  version_hdr)
     file(STRINGS ${version_hdr} _contents REGEX "^[ \t]*#define XALAN_VERSION_.*")
     if(_contents)
-        string(REGEX REPLACE "[^*]*#define XALAN_VERSION_MAJOR[ \t]+([0-9]+).*" "\\1" XalanC_MAJOR "${_contents}")
-        string(REGEX REPLACE "[^*]*#define XALAN_VERSION_MINOR[ \t]+([0-9]+).*" "\\1" XalanC_MINOR "${_contents}")
-        string(REGEX REPLACE "[^*]*#define XALAN_VERSION_REVISION[ \t]+([0-9]+).*" "\\1" XalanC_PATCH "${_contents}")
+        string(REGEX REPLACE "[^*]*#define XALAN_VERSION_MAJOR[ \t(]+([0-9]+).*" "\\1" XalanC_MAJOR "${_contents}")
+        string(REGEX REPLACE "[^*]*#define XALAN_VERSION_MINOR[ \t(]+([0-9]+).*" "\\1" XalanC_MINOR "${_contents}")
+        string(REGEX REPLACE "[^*]*#define XALAN_VERSION_REVISION[ \t(]+([0-9]+).*" "\\1" XalanC_PATCH "${_contents}")
 
         if(NOT XalanC_MAJOR MATCHES "^[0-9]+$")
             message(FATAL_ERROR "Version parsing failed for XALAN_VERSION_MAJOR!")
diff --git a/Modules/FindXercesC.cmake b/Modules/FindXercesC.cmake
index 47bfd62..abe18c0 100644
--- a/Modules/FindXercesC.cmake
+++ b/Modules/FindXercesC.cmake
@@ -5,6 +5,8 @@
 FindXercesC
 -----------
 
+.. versionadded:: 3.1
+
 Find the Apache Xerces-C++ validating XML parser headers and libraries.
 
 Imported targets
@@ -81,10 +83,14 @@
 if(NOT XercesC_LIBRARY)
   # Find all XercesC libraries
   find_library(XercesC_LIBRARY_RELEASE
-               NAMES "xerces-c" "xerces-c_${XercesC_VERSION_MAJOR}"
+               NAMES "xerces-c"
+                     "xerces-c_${XercesC_VERSION_MAJOR}"
+                     "xerces-c-${XercesC_VERSION_MAJOR}.${XercesC_VERSION_MINOR}"
                DOC "Xerces-C++ libraries (release)")
   find_library(XercesC_LIBRARY_DEBUG
-               NAMES "xerces-cd" "xerces-c_${XercesC_VERSION_MAJOR}D" "xerces-c_${XercesC_VERSION_MAJOR}_${XercesC_VERSION_MINOR}D"
+               NAMES "xerces-cd"
+                     "xerces-c_${XercesC_VERSION_MAJOR}D"
+                     "xerces-c_${XercesC_VERSION_MAJOR}_${XercesC_VERSION_MINOR}D"
                DOC "Xerces-C++ libraries (debug)")
   include(${CMAKE_CURRENT_LIST_DIR}/SelectLibraryConfigurations.cmake)
   select_library_configurations(XercesC)
diff --git a/Modules/FindwxWindows.cmake b/Modules/FindwxWindows.cmake
index 35840f5..07fbc1b 100644
--- a/Modules/FindwxWindows.cmake
+++ b/Modules/FindwxWindows.cmake
@@ -307,7 +307,7 @@
   else ()
     ## WX is built as multiple small pieces libraries instead of monolithic
 
-    ## DEPECATED (jw) replaced by more general WXWINDOWS_USE_MONOLITHIC ON/OFF
+    ## DEPRECATED (jw) replaced by more general WXWINDOWS_USE_MONOLITHIC ON/OFF
     # option(WXWINDOWS_SEPARATE_LIBS_BUILD "Is wxWindows build with separate libs?" OFF)
 
     ## HACK: This is very dirty.
diff --git a/Modules/FortranCInterface/CMakeLists.txt b/Modules/FortranCInterface/CMakeLists.txt
index 381080b..13e4498 100644
--- a/Modules/FortranCInterface/CMakeLists.txt
+++ b/Modules/FortranCInterface/CMakeLists.txt
@@ -101,3 +101,7 @@
 # Require symbols through Fortran.
 add_executable(FortranCInterface main.F call_sub.f ${call_mod})
 target_link_libraries(FortranCInterface PUBLIC symbols)
+
+file(GENERATE OUTPUT exe-$<CONFIG>.cmake CONTENT [[
+set(FortranCInterface_EXE "$<TARGET_FILE:FortranCInterface>")
+]])
diff --git a/Modules/FortranCInterface/Detect.cmake b/Modules/FortranCInterface/Detect.cmake
index 33de6c6..c75067b 100644
--- a/Modules/FortranCInterface/Detect.cmake
+++ b/Modules/FortranCInterface/Detect.cmake
@@ -43,17 +43,11 @@
 unset(FortranCInterface_COMPILED CACHE)
 
 # Locate the sample project executable.
+set(FortranCInterface_EXE)
 if(FortranCInterface_COMPILED)
-  find_program(FortranCInterface_EXE
-    NAMES FortranCInterface${CMAKE_EXECUTABLE_SUFFIX}
-    PATHS ${FortranCInterface_BINARY_DIR} ${FortranCInterface_BINARY_DIR}/Release
-    NO_DEFAULT_PATH
-    )
-  set(FortranCInterface_EXE ${FortranCInterface_EXE})
-  unset(FortranCInterface_EXE CACHE)
+  include(${FortranCInterface_BINARY_DIR}/exe-Release.cmake OPTIONAL)
 else()
   set(_result "Failed to compile")
-  set(FortranCInterface_EXE)
   file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
     "Fortran/C interface test project failed with the following output:\n"
     "${FortranCInterface_OUTPUT}\n")
diff --git a/Modules/GetPrerequisites.cmake b/Modules/GetPrerequisites.cmake
index 5c8c196..c99c772 100644
--- a/Modules/GetPrerequisites.cmake
+++ b/Modules/GetPrerequisites.cmake
@@ -61,7 +61,7 @@
 exclude "system" prerequisites.  If <recurse> is set to 1 all
 prerequisites will be found recursively, if set to 0 only direct
 prerequisites are listed.  <exepath> is the path to the top level
-executable used for @executable_path replacment on the Mac.  <dirs> is
+executable used for @executable_path replacement on the Mac.  <dirs> is
 a list of paths where libraries might be found: these paths are
 searched first when a target without any path info is given.  Then
 standard system locations are also searched: PATH, Framework
diff --git a/Modules/GoogleTest.cmake b/Modules/GoogleTest.cmake
index a5bb863..057b29d 100644
--- a/Modules/GoogleTest.cmake
+++ b/Modules/GoogleTest.cmake
@@ -5,6 +5,8 @@
 GoogleTest
 ----------
 
+.. versionadded:: 3.9
+
 This module defines functions to help use the Google Test infrastructure.  Two
 mechanisms for adding tests are provided. :command:`gtest_add_tests` has been
 around for some time, originally via ``find_package(GTest)``.
@@ -151,9 +153,11 @@
                          [PROPERTIES name1 value1...]
                          [TEST_LIST var]
                          [DISCOVERY_TIMEOUT seconds]
+                         [XML_OUTPUT_DIR dir]
+                         [DISCOVERY_MODE <POST_BUILD|PRE_TEST>]
     )
 
-  ``gtest_discover_tests`` sets up a post-build command on the test executable
+  ``gtest_discover_tests()`` sets up a post-build command on the test executable
   that generates the list of tests by parsing the output from running the test
   with the ``--gtest_list_tests`` argument.  Compared to the source parsing
   approach of :command:`gtest_add_tests`, this ensures that the full list of
@@ -210,7 +214,7 @@
 
   ``PROPERTIES name1 value1...``
     Specifies additional properties to be set on all tests discovered by this
-    invocation of ``gtest_discover_tests``.
+    invocation of ``gtest_discover_tests()``.
 
   ``TEST_LIST var``
     Make the list of tests available in the variable ``var``, rather than the
@@ -236,6 +240,29 @@
       problem.  The ambiguous behavior of the ``TIMEOUT`` keyword in 3.10.1
       and 3.10.2 has not been preserved.
 
+  ``XML_OUTPUT_DIR dir``
+    If specified, the parameter is passed along with ``--gtest_output=xml:``
+    to test executable. The actual file name is the same as the test target,
+    including prefix and suffix. This should be used instead of
+    ``EXTRA_ARGS --gtest_output=xml`` to avoid race conditions writing the
+    XML result output when using parallel test execution.
+
+  ``DISCOVERY_MODE``
+    Provides greater control over when ``gtest_discover_tests()`` performs test
+    discovery. By default, ``POST_BUILD`` sets up a post-build command
+    to perform test discovery at build time. In certain scenarios, like
+    cross-compiling, this ``POST_BUILD`` behavior is not desirable.
+    By contrast, ``PRE_TEST`` delays test discovery until just prior to test
+    execution. This way test discovery occurs in the target environment
+    where the test has a better chance at finding appropriate runtime
+    dependencies.
+
+    ``DISCOVERY_MODE`` defaults to the value of the
+    ``CMAKE_GTEST_DISCOVER_TESTS_DISCOVERY_MODE`` variable if it is not
+    passed when calling ``gtest_discover_tests()``. This provides a mechanism
+    for globally selecting a preferred test discovery behavior without having
+    to modify each call site.
+
 #]=======================================================================]
 
 # Save project's policies
@@ -368,11 +395,12 @@
 endfunction()
 
 #------------------------------------------------------------------------------
+
 function(gtest_discover_tests TARGET)
   cmake_parse_arguments(
     ""
     "NO_PRETTY_TYPES;NO_PRETTY_VALUES"
-    "TEST_PREFIX;TEST_SUFFIX;WORKING_DIRECTORY;TEST_LIST;DISCOVERY_TIMEOUT"
+    "TEST_PREFIX;TEST_SUFFIX;WORKING_DIRECTORY;TEST_LIST;DISCOVERY_TIMEOUT;XML_OUTPUT_DIR;DISCOVERY_MODE"
     "EXTRA_ARGS;PROPERTIES"
     ${ARGN}
   )
@@ -386,6 +414,12 @@
   if(NOT _DISCOVERY_TIMEOUT)
     set(_DISCOVERY_TIMEOUT 5)
   endif()
+  if(NOT _DISCOVERY_MODE)
+    if(NOT CMAKE_GTEST_DISCOVER_TESTS_DISCOVERY_MODE)
+      set(CMAKE_GTEST_DISCOVER_TESTS_DISCOVERY_MODE "POST_BUILD")
+    endif()
+    set(_DISCOVERY_MODE ${CMAKE_GTEST_DISCOVER_TESTS_DISCOVERY_MODE})
+  endif()
 
   get_property(
     has_counter
@@ -417,34 +451,86 @@
     TARGET ${TARGET}
     PROPERTY CROSSCOMPILING_EMULATOR
   )
-  add_custom_command(
-    TARGET ${TARGET} POST_BUILD
-    BYPRODUCTS "${ctest_tests_file}"
-    COMMAND "${CMAKE_COMMAND}"
-            -D "TEST_TARGET=${TARGET}"
-            -D "TEST_EXECUTABLE=$<TARGET_FILE:${TARGET}>"
-            -D "TEST_EXECUTOR=${crosscompiling_emulator}"
-            -D "TEST_WORKING_DIR=${_WORKING_DIRECTORY}"
-            -D "TEST_EXTRA_ARGS=${_EXTRA_ARGS}"
-            -D "TEST_PROPERTIES=${_PROPERTIES}"
-            -D "TEST_PREFIX=${_TEST_PREFIX}"
-            -D "TEST_SUFFIX=${_TEST_SUFFIX}"
-            -D "NO_PRETTY_TYPES=${_NO_PRETTY_TYPES}"
-            -D "NO_PRETTY_VALUES=${_NO_PRETTY_VALUES}"
-            -D "TEST_LIST=${_TEST_LIST}"
-            -D "CTEST_FILE=${ctest_tests_file}"
-            -D "TEST_DISCOVERY_TIMEOUT=${_DISCOVERY_TIMEOUT}"
-            -P "${_GOOGLETEST_DISCOVER_TESTS_SCRIPT}"
-    VERBATIM
-  )
 
-  file(WRITE "${ctest_include_file}"
-    "if(EXISTS \"${ctest_tests_file}\")\n"
-    "  include(\"${ctest_tests_file}\")\n"
-    "else()\n"
-    "  add_test(${TARGET}_NOT_BUILT ${TARGET}_NOT_BUILT)\n"
-    "endif()\n"
-  )
+  if(_DISCOVERY_MODE STREQUAL "POST_BUILD")
+    add_custom_command(
+      TARGET ${TARGET} POST_BUILD
+      BYPRODUCTS "${ctest_tests_file}"
+      COMMAND "${CMAKE_COMMAND}"
+              -D "TEST_TARGET=${TARGET}"
+              -D "TEST_EXECUTABLE=$<TARGET_FILE:${TARGET}>"
+              -D "TEST_EXECUTOR=${crosscompiling_emulator}"
+              -D "TEST_WORKING_DIR=${_WORKING_DIRECTORY}"
+              -D "TEST_EXTRA_ARGS=${_EXTRA_ARGS}"
+              -D "TEST_PROPERTIES=${_PROPERTIES}"
+              -D "TEST_PREFIX=${_TEST_PREFIX}"
+              -D "TEST_SUFFIX=${_TEST_SUFFIX}"
+              -D "NO_PRETTY_TYPES=${_NO_PRETTY_TYPES}"
+              -D "NO_PRETTY_VALUES=${_NO_PRETTY_VALUES}"
+              -D "TEST_LIST=${_TEST_LIST}"
+              -D "CTEST_FILE=${ctest_tests_file}"
+              -D "TEST_DISCOVERY_TIMEOUT=${_DISCOVERY_TIMEOUT}"
+              -D "TEST_XML_OUTPUT_DIR=${_XML_OUTPUT_DIR}"
+              -P "${_GOOGLETEST_DISCOVER_TESTS_SCRIPT}"
+      VERBATIM
+    )
+
+    file(WRITE "${ctest_include_file}"
+      "if(EXISTS \"${ctest_tests_file}\")\n"
+      "  include(\"${ctest_tests_file}\")\n"
+      "else()\n"
+      "  add_test(${TARGET}_NOT_BUILT ${TARGET}_NOT_BUILT)\n"
+      "endif()\n"
+    )
+  elseif(_DISCOVERY_MODE STREQUAL "PRE_TEST")
+
+    get_property(GENERATOR_IS_MULTI_CONFIG GLOBAL
+        PROPERTY GENERATOR_IS_MULTI_CONFIG
+    )
+
+    if(GENERATOR_IS_MULTI_CONFIG)
+      set(ctest_tests_file "${ctest_file_base}_tests-$<CONFIG>.cmake")
+    endif()
+
+    string(CONCAT ctest_include_content
+      "if(EXISTS \"$<TARGET_FILE:${TARGET}>\")"                                    "\n"
+      "  if(\"$<TARGET_FILE:${TARGET}>\" IS_NEWER_THAN \"${ctest_tests_file}\")"   "\n"
+      "    include(\"${_GOOGLETEST_DISCOVER_TESTS_SCRIPT}\")"                      "\n"
+      "    gtest_discover_tests_impl("                                             "\n"
+      "      TEST_EXECUTABLE"        " [==[" "$<TARGET_FILE:${TARGET}>"   "]==]"   "\n"
+      "      TEST_EXECUTOR"          " [==[" "${crosscompiling_emulator}" "]==]"   "\n"
+      "      TEST_WORKING_DIR"       " [==[" "${_WORKING_DIRECTORY}"      "]==]"   "\n"
+      "      TEST_EXTRA_ARGS"        " [==[" "${_EXTRA_ARGS}"             "]==]"   "\n"
+      "      TEST_PROPERTIES"        " [==[" "${_PROPERTIES}"             "]==]"   "\n"
+      "      TEST_PREFIX"            " [==[" "${_TEST_PREFIX}"            "]==]"   "\n"
+      "      TEST_SUFFIX"            " [==[" "${_TEST_SUFFIX}"            "]==]"   "\n"
+      "      NO_PRETTY_TYPES"        " [==[" "${_NO_PRETTY_TYPES}"        "]==]"   "\n"
+      "      NO_PRETTY_VALUES"       " [==[" "${_NO_PRETTY_VALUES}"       "]==]"   "\n"
+      "      TEST_LIST"              " [==[" "${_TEST_LIST}"              "]==]"   "\n"
+      "      CTEST_FILE"             " [==[" "${ctest_tests_file}"        "]==]"   "\n"
+      "      TEST_DISCOVERY_TIMEOUT" " [==[" "${_DISCOVERY_TIMEOUT}"      "]==]"   "\n"
+      "      TEST_XML_OUTPUT_DIR"    " [==[" "${_XML_OUTPUT_DIR}"         "]==]"   "\n"
+      "    )"                                                                      "\n"
+      "  endif()"                                                                  "\n"
+      "  include(\"${ctest_tests_file}\")"                                         "\n"
+      "else()"                                                                     "\n"
+      "  add_test(${TARGET}_NOT_BUILT ${TARGET}_NOT_BUILT)"                        "\n"
+      "endif()"                                                                    "\n"
+    )
+
+    if(GENERATOR_IS_MULTI_CONFIG)
+      foreach(_config ${CMAKE_CONFIGURATION_TYPES})
+        file(GENERATE OUTPUT "${ctest_file_base}_include-${_config}.cmake" CONTENT "${ctest_include_content}" CONDITION $<CONFIG:${_config}>)
+      endforeach()
+      file(WRITE "${ctest_include_file}" "include(\"${ctest_file_base}_include-\${CTEST_CONFIGURATION_TYPE}.cmake\")")
+    else()
+      file(GENERATE OUTPUT "${ctest_file_base}_include.cmake" CONTENT "${ctest_include_content}")
+      file(WRITE "${ctest_include_file}" "include(\"${ctest_file_base}_include.cmake\")")
+    endif()
+
+  else()
+    message(FATAL_ERROR "Unknown DISCOVERY_MODE: ${_DISCOVERY_MODE}")
+  endif()
 
   # Add discovered tests to directory TEST_INCLUDE_FILES
   set_property(DIRECTORY
diff --git a/Modules/GoogleTestAddTests.cmake b/Modules/GoogleTestAddTests.cmake
index 4abbbec..883e1f4 100644
--- a/Modules/GoogleTestAddTests.cmake
+++ b/Modules/GoogleTestAddTests.cmake
@@ -1,106 +1,188 @@
 # Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
 # file Copyright.txt or https://cmake.org/licensing for details.
 
-set(prefix "${TEST_PREFIX}")
-set(suffix "${TEST_SUFFIX}")
-set(extra_args ${TEST_EXTRA_ARGS})
-set(properties ${TEST_PROPERTIES})
-set(script)
-set(suite)
-set(tests)
+cmake_minimum_required(VERSION ${CMAKE_VERSION})
 
-function(add_command NAME)
+# Overwrite possibly existing ${_CTEST_FILE} with empty file
+set(flush_tests_MODE WRITE)
+
+# Flushes script to ${_CTEST_FILE}
+macro(flush_script)
+  file(${flush_tests_MODE} "${_CTEST_FILE}" "${script}")
+  set(flush_tests_MODE APPEND)
+
+  set(script "")
+endmacro()
+
+# Flushes tests_buffer to tests
+macro(flush_tests_buffer)
+  list(APPEND tests "${tests_buffer}")
+  set(tests_buffer "")
+endmacro()
+
+macro(add_command NAME)
   set(_args "")
   foreach(_arg ${ARGN})
     if(_arg MATCHES "[^-./:a-zA-Z0-9_]")
-      set(_args "${_args} [==[${_arg}]==]")
+      string(APPEND _args " [==[${_arg}]==]")
     else()
-      set(_args "${_args} ${_arg}")
+      string(APPEND _args " ${_arg}")
     endif()
   endforeach()
-  set(script "${script}${NAME}(${_args})\n" PARENT_SCOPE)
+  string(APPEND script "${NAME}(${_args})\n")
+  string(LENGTH "${script}" _script_len)
+  if(${_script_len} GREATER "50000")
+    flush_script()
+  endif()
+  # Unsets macro local variables to prevent leakage outside of this macro.
+  unset(_args)
+  unset(_script_len)
+endmacro()
+
+function(gtest_discover_tests_impl)
+
+  cmake_parse_arguments(
+    ""
+    ""
+    "NO_PRETTY_TYPES;NO_PRETTY_VALUES;TEST_EXECUTABLE;TEST_WORKING_DIR;TEST_PREFIX;TEST_SUFFIX;TEST_LIST;CTEST_FILE;TEST_DISCOVERY_TIMEOUT;TEST_XML_OUTPUT_DIR"
+    "TEST_EXTRA_ARGS;TEST_PROPERTIES;TEST_EXECUTOR"
+    ${ARGN}
+  )
+
+  set(prefix "${_TEST_PREFIX}")
+  set(suffix "${_TEST_SUFFIX}")
+  set(extra_args ${_TEST_EXTRA_ARGS})
+  set(properties ${_TEST_PROPERTIES})
+  set(script)
+  set(suite)
+  set(tests)
+  set(tests_buffer)
+
+  # Run test executable to get list of available tests
+  if(NOT EXISTS "${_TEST_EXECUTABLE}")
+    message(FATAL_ERROR
+      "Specified test executable does not exist.\n"
+      "  Path: '${_TEST_EXECUTABLE}'"
+    )
+  endif()
+  execute_process(
+    COMMAND ${_TEST_EXECUTOR} "${_TEST_EXECUTABLE}" --gtest_list_tests
+    WORKING_DIRECTORY "${_TEST_WORKING_DIR}"
+    TIMEOUT ${_TEST_DISCOVERY_TIMEOUT}
+    OUTPUT_VARIABLE output
+    RESULT_VARIABLE result
+  )
+  if(NOT ${result} EQUAL 0)
+    string(REPLACE "\n" "\n    " output "${output}")
+    message(FATAL_ERROR
+      "Error running test executable.\n"
+      "  Path: '${_TEST_EXECUTABLE}'\n"
+      "  Result: ${result}\n"
+      "  Output:\n"
+      "    ${output}\n"
+    )
+  endif()
+
+  # Preserve semicolon in test-parameters
+  string(REPLACE [[;]] [[\;]] output "${output}")
+  string(REPLACE "\n" ";" output "${output}")
+
+  # Parse output
+  foreach(line ${output})
+    # Skip header
+    if(NOT line MATCHES "gtest_main\\.cc")
+      # Do we have a module name or a test name?
+      if(NOT line MATCHES "^  ")
+        # Module; remove trailing '.' to get just the name...
+        string(REGEX REPLACE "\\.( *#.*)?" "" suite "${line}")
+        if(line MATCHES "#" AND NOT _NO_PRETTY_TYPES)
+          string(REGEX REPLACE "/[0-9]\\.+ +#.*= +" "/" pretty_suite "${line}")
+        else()
+          set(pretty_suite "${suite}")
+        endif()
+        string(REGEX REPLACE "^DISABLED_" "" pretty_suite "${pretty_suite}")
+      else()
+        # Test name; strip spaces and comments to get just the name...
+        string(REGEX REPLACE " +" "" test "${line}")
+        if(test MATCHES "#" AND NOT _NO_PRETTY_VALUES)
+          string(REGEX REPLACE "/[0-9]+#GetParam..=" "/" pretty_test "${test}")
+        else()
+          string(REGEX REPLACE "#.*" "" pretty_test "${test}")
+        endif()
+        string(REGEX REPLACE "^DISABLED_" "" pretty_test "${pretty_test}")
+        string(REGEX REPLACE "#.*" "" test "${test}")
+        if(NOT "${_TEST_XML_OUTPUT_DIR}" STREQUAL "")
+          set(TEST_XML_OUTPUT_PARAM "--gtest_output=xml:${_TEST_XML_OUTPUT_DIR}/${prefix}${suite}.${test}${suffix}.xml")
+        else()
+          unset(TEST_XML_OUTPUT_PARAM)
+        endif()
+
+        # sanitize test name for further processing downstream
+        set(testname "${prefix}${pretty_suite}.${pretty_test}${suffix}")
+        # escape \
+        string(REPLACE [[\]] [[\\]] testname "${testname}")
+        # escape ;
+        string(REPLACE [[;]] [[\;]] testname "${testname}")
+        # escape $
+        string(REPLACE [[$]] [[\$]] testname "${testname}")
+
+        # ...and add to script
+        add_command(add_test
+          "${testname}"
+          ${_TEST_EXECUTOR}
+          "${_TEST_EXECUTABLE}"
+          "--gtest_filter=${suite}.${test}"
+          "--gtest_also_run_disabled_tests"
+          ${TEST_XML_OUTPUT_PARAM}
+          ${extra_args}
+        )
+        if(suite MATCHES "^DISABLED" OR test MATCHES "^DISABLED")
+          add_command(set_tests_properties
+            "${testname}"
+            PROPERTIES DISABLED TRUE
+          )
+        endif()
+        add_command(set_tests_properties
+          "${testname}"
+          PROPERTIES
+          WORKING_DIRECTORY "${_TEST_WORKING_DIR}"
+          SKIP_REGULAR_EXPRESSION "\\\\[  SKIPPED \\\\]"
+          ${properties}
+        )
+        list(APPEND tests_buffer "${testname}")
+        list(LENGTH tests_buffer tests_buffer_length)
+        if(${tests_buffer_length} GREATER "250")
+          flush_tests_buffer()
+        endif()
+      endif()
+    endif()
+  endforeach()
+
+
+  # Create a list of all discovered tests, which users may use to e.g. set
+  # properties on the tests
+  flush_tests_buffer()
+  add_command(set ${_TEST_LIST} ${tests})
+
+  # Write CTest script
+  flush_script()
+
 endfunction()
 
-# Run test executable to get list of available tests
-if(NOT EXISTS "${TEST_EXECUTABLE}")
-  message(FATAL_ERROR
-    "Specified test executable does not exist.\n"
-    "  Path: '${TEST_EXECUTABLE}'"
+if(CMAKE_SCRIPT_MODE_FILE)
+  gtest_discover_tests_impl(
+    NO_PRETTY_TYPES ${NO_PRETTY_TYPES}
+    NO_PRETTY_VALUES ${NO_PRETTY_VALUES}
+    TEST_EXECUTABLE ${TEST_EXECUTABLE}
+    TEST_EXECUTOR ${TEST_EXECUTOR}
+    TEST_WORKING_DIR ${TEST_WORKING_DIR}
+    TEST_PREFIX ${TEST_PREFIX}
+    TEST_SUFFIX ${TEST_SUFFIX}
+    TEST_LIST ${TEST_LIST}
+    CTEST_FILE ${CTEST_FILE}
+    TEST_DISCOVERY_TIMEOUT ${TEST_DISCOVERY_TIMEOUT}
+    TEST_XML_OUTPUT_DIR ${TEST_XML_OUTPUT_DIR}
+    TEST_EXTRA_ARGS ${TEST_EXTRA_ARGS}
+    TEST_PROPERTIES ${TEST_PROPERTIES}
   )
 endif()
-execute_process(
-  COMMAND ${TEST_EXECUTOR} "${TEST_EXECUTABLE}" --gtest_list_tests
-  WORKING_DIRECTORY "${TEST_WORKING_DIR}"
-  TIMEOUT ${TEST_DISCOVERY_TIMEOUT}
-  OUTPUT_VARIABLE output
-  RESULT_VARIABLE result
-)
-if(NOT ${result} EQUAL 0)
-  string(REPLACE "\n" "\n    " output "${output}")
-  message(FATAL_ERROR
-    "Error running test executable.\n"
-    "  Path: '${TEST_EXECUTABLE}'\n"
-    "  Result: ${result}\n"
-    "  Output:\n"
-    "    ${output}\n"
-  )
-endif()
-
-string(REPLACE "\n" ";" output "${output}")
-
-# Parse output
-foreach(line ${output})
-  # Skip header
-  if(NOT line MATCHES "gtest_main\\.cc")
-    # Do we have a module name or a test name?
-    if(NOT line MATCHES "^  ")
-      # Module; remove trailing '.' to get just the name...
-      string(REGEX REPLACE "\\.( *#.*)?" "" suite "${line}")
-      if(line MATCHES "#" AND NOT NO_PRETTY_TYPES)
-        string(REGEX REPLACE "/[0-9]\\.+ +#.*= +" "/" pretty_suite "${line}")
-      else()
-        set(pretty_suite "${suite}")
-      endif()
-      string(REGEX REPLACE "^DISABLED_" "" pretty_suite "${pretty_suite}")
-    else()
-      # Test name; strip spaces and comments to get just the name...
-      string(REGEX REPLACE " +" "" test "${line}")
-      if(test MATCHES "#" AND NOT NO_PRETTY_VALUES)
-        string(REGEX REPLACE "/[0-9]+#GetParam..=" "/" pretty_test "${test}")
-      else()
-        string(REGEX REPLACE "#.*" "" pretty_test "${test}")
-      endif()
-      string(REGEX REPLACE "^DISABLED_" "" pretty_test "${pretty_test}")
-      string(REGEX REPLACE "#.*" "" test "${test}")
-      # ...and add to script
-      add_command(add_test
-        "${prefix}${pretty_suite}.${pretty_test}${suffix}"
-        ${TEST_EXECUTOR}
-        "${TEST_EXECUTABLE}"
-        "--gtest_filter=${suite}.${test}"
-        "--gtest_also_run_disabled_tests"
-        ${extra_args}
-      )
-      if(suite MATCHES "^DISABLED" OR test MATCHES "^DISABLED")
-        add_command(set_tests_properties
-          "${prefix}${pretty_suite}.${pretty_test}${suffix}"
-          PROPERTIES DISABLED TRUE
-        )
-      endif()
-      add_command(set_tests_properties
-        "${prefix}${pretty_suite}.${pretty_test}${suffix}"
-        PROPERTIES
-        WORKING_DIRECTORY "${TEST_WORKING_DIR}"
-        ${properties}
-      )
-     list(APPEND tests "${prefix}${pretty_suite}.${pretty_test}${suffix}")
-    endif()
-  endif()
-endforeach()
-
-# Create a list of all discovered tests, which users may use to e.g. set
-# properties on the tests
-add_command(set ${TEST_LIST} ${tests})
-
-# Write CTest script
-file(WRITE "${CTEST_FILE}" "${script}")
diff --git a/Modules/InstallRequiredSystemLibraries.cmake b/Modules/InstallRequiredSystemLibraries.cmake
index 04687b9..caca697 100644
--- a/Modules/InstallRequiredSystemLibraries.cmake
+++ b/Modules/InstallRequiredSystemLibraries.cmake
@@ -69,7 +69,7 @@
       if(CMAKE_SIZEOF_VOID_P EQUAL 8)
         set(_Intel_archdir intel64)
       else()
-        set(_Intel_archdir x86)
+        set(_Intel_archdir ia32)
       endif()
       set(_Intel_compiler_ver ${CMAKE_${LANG}_COMPILER_VERSION})
       if(WIN32)
diff --git a/Modules/Internal/CPack/CPackDeb.cmake b/Modules/Internal/CPack/CPackDeb.cmake
index db35e3a..431b074 100644
--- a/Modules/Internal/CPack/CPackDeb.cmake
+++ b/Modules/Internal/CPack/CPackDeb.cmake
@@ -547,8 +547,8 @@
       message(FATAL_ERROR _description_failure_message)
     endif()
 
-  # Ok, description has set. According to the `Debian Policy Manual`_ the frist
-  # line is a pacakge summary.  Try to get it as well...
+  # Ok, description has set. According to the `Debian Policy Manual`_ the first
+  # line is a package summary.  Try to get it as well...
   # See also: https://www.debian.org/doc/debian-policy/ch-controlfields.html#description
   elseif(CPACK_PACKAGE_DESCRIPTION_SUMMARY AND
          NOT CPACK_PACKAGE_DESCRIPTION_SUMMARY STREQUAL CPACK_DEFAULT_PACKAGE_DESCRIPTION_SUMMARY)
diff --git a/Modules/Internal/CPack/CPackNuGet.cmake b/Modules/Internal/CPack/CPackNuGet.cmake
index 1f4bcfd..20eed2e 100644
--- a/Modules/Internal/CPack/CPackNuGet.cmake
+++ b/Modules/Internal/CPack/CPackNuGet.cmake
@@ -287,7 +287,11 @@
     execute_process(
         COMMAND "${NUGET_EXECUTABLE}" pack ${CPACK_NUGET_PACK_ADDITIONAL_OPTIONS}
         WORKING_DIRECTORY "${CPACK_TEMPORARY_DIRECTORY}"
+        RESULT_VARIABLE _nuget_result
       )
+    if(NOT _nuget_result EQUAL 0)
+        message(FATAL_ERROR "Nuget pack failed")
+    endif()
 
 elseif(CPACK_NUGET_ALL_IN_ONE)
     # This variable `CPACK_NUGET_ALL_IN_ONE` set by C++ code:
@@ -300,7 +304,11 @@
     execute_process(
         COMMAND "${NUGET_EXECUTABLE}" pack ${CPACK_NUGET_PACK_ADDITIONAL_OPTIONS}
         WORKING_DIRECTORY "${CPACK_TEMPORARY_DIRECTORY}"
+        RESULT_VARIABLE _nuget_result
       )
+    if(NOT _nuget_result EQUAL 0)
+        message(FATAL_ERROR "Nuget pack failed")
+    endif()
 
 else()
     # Is there any grouped component?
@@ -322,7 +330,11 @@
             execute_process(
                 COMMAND "${NUGET_EXECUTABLE}" pack ${CPACK_NUGET_PACK_ADDITIONAL_OPTIONS}
                 WORKING_DIRECTORY "${CPACK_TEMPORARY_DIRECTORY}"
+                RESULT_VARIABLE _nuget_result
               )
+            if(NOT _nuget_result EQUAL 0)
+                message(FATAL_ERROR "Nuget pack failed")
+            endif()
         endforeach()
     endif()
     # Is there any single component package needed?
@@ -341,7 +353,11 @@
             execute_process(
                 COMMAND "${NUGET_EXECUTABLE}" pack ${CPACK_NUGET_PACK_ADDITIONAL_OPTIONS}
                 WORKING_DIRECTORY "${CPACK_TEMPORARY_DIRECTORY}"
+                RESULT_VARIABLE _nuget_result
               )
+            if(NOT _nuget_result EQUAL 0)
+                message(FATAL_ERROR "Nuget pack failed")
+            endif()
         endforeach()
     endif()
 endif()
diff --git a/Modules/Internal/CPack/CPackRPM.cmake b/Modules/Internal/CPack/CPackRPM.cmake
index 3485e7d..08bbc68 100644
--- a/Modules/Internal/CPack/CPackRPM.cmake
+++ b/Modules/Internal/CPack/CPackRPM.cmake
@@ -1099,16 +1099,18 @@
 
   # CPACK_RPM_POST_INSTALL_SCRIPT_FILE (or CPACK_RPM_<COMPONENT>_POST_INSTALL_SCRIPT_FILE)
   # CPACK_RPM_POST_UNINSTALL_SCRIPT_FILE (or CPACK_RPM_<COMPONENT>_POST_UNINSTALL_SCRIPT_FILE)
-  # May be used to embed a post (un)installation script in the spec file.
+  # CPACK_RPM_POST_TRANS_SCRIPT_FILE (or CPACK_RPM_<COMPONENT>_POST_TRANS_SCRIPT_FILE)
+  # May be used to embed a post installation/uninstallation/transaction script in the spec file.
   # The referred script file(s) will be read and directly
-  # put after the %post or %postun section
+  # put after the %post or %postun or %posttrans section
   # ----------------------------------------------------------------
   # CPACK_RPM_PRE_INSTALL_SCRIPT_FILE (or CPACK_RPM_<COMPONENT>_PRE_INSTALL_SCRIPT_FILE)
   # CPACK_RPM_PRE_UNINSTALL_SCRIPT_FILE (or CPACK_RPM_<COMPONENT>_PRE_UNINSTALL_SCRIPT_FILE)
-  # May be used to embed a pre (un)installation script in the spec file.
+  # CPACK_RPM_PRE_TRANS_SCRIPT_FILE (or CPACK_RPM_<COMPONENT>_PRE_TRANS_SCRIPT_FILE)
+  # May be used to embed a pre installation/uninstallation/transaction script in the spec file.
   # The referred script file(s) will be read and directly
-  # put after the %pre or %preun section
-  foreach(RPM_SCRIPT_FILE_TYPE_ "INSTALL" "UNINSTALL")
+  # put after the %pre or %preun or %pretrans section
+  foreach(RPM_SCRIPT_FILE_TYPE_ "INSTALL" "UNINSTALL" "TRANS")
     foreach(RPM_SCRIPT_FILE_TIME_ "PRE" "POST")
       set("CPACK_RPM_${RPM_SCRIPT_FILE_TIME_}_${RPM_SCRIPT_FILE_TYPE_}_READ_FILE"
         "${CPACK_RPM_${RPM_SCRIPT_FILE_TIME_}_${RPM_SCRIPT_FILE_TYPE_}_SCRIPT_FILE}")
@@ -1727,12 +1729,18 @@
 \@RPM_SYMLINK_POSTINSTALL\@
 \@CPACK_RPM_SPEC_POSTINSTALL\@
 
+%posttrans
+\@CPACK_RPM_SPEC_POSTTRANS\@
+
 %postun
 \@CPACK_RPM_SPEC_POSTUNINSTALL\@
 
 %pre
 \@CPACK_RPM_SPEC_PREINSTALL\@
 
+%pretrans
+\@CPACK_RPM_SPEC_PRETRANS\@
+
 %preun
 \@CPACK_RPM_SPEC_PREUNINSTALL\@
 
diff --git a/Modules/Internal/CPack/NSIS.template.in b/Modules/Internal/CPack/NSIS.template.in
index 660bfa3..6009ce0 100644
--- a/Modules/Internal/CPack/NSIS.template.in
+++ b/Modules/Internal/CPack/NSIS.template.in
@@ -41,6 +41,7 @@
   RequestExecutionLevel admin
 
 @CPACK_NSIS_DEFINES@
+@CPACK_NSIS_MANIFEST_DPI_AWARE_CODE@
 
   !include Sections.nsh
 
diff --git a/Modules/Platform/Android-Clang.cmake b/Modules/Platform/Android-Clang.cmake
index 759448b..160eada 100644
--- a/Modules/Platform/Android-Clang.cmake
+++ b/Modules/Platform/Android-Clang.cmake
@@ -53,4 +53,7 @@
     endif()
     list(APPEND CMAKE_${lang}_COMPILER_PREDEFINES_COMMAND "--target=${CMAKE_${lang}_COMPILER_TARGET}")
   endif()
+  if(CMAKE_GENERATOR MATCHES "Visual Studio")
+    set(_ANDROID_STL_NOSTDLIBXX 1)
+  endif()
 endmacro()
diff --git a/Modules/Platform/Android-Common.cmake b/Modules/Platform/Android-Common.cmake
index 1affcd0..581fde4 100644
--- a/Modules/Platform/Android-Common.cmake
+++ b/Modules/Platform/Android-Common.cmake
@@ -73,7 +73,7 @@
       macro(__android_stl lang)
         # FIXME: Add a way to add project-wide language-specific compile-only flags.
         set(CMAKE_CXX_COMPILE_OBJECT
-          "<CMAKE_CXX_COMPILER>  <DEFINES> <INCLUDES> <FLAGS> -o <OBJECT> -c <SOURCE> -nostdinc++")
+          "<CMAKE_CXX_COMPILER> <DEFINES> <INCLUDES> <FLAGS> -o <OBJECT> -c <SOURCE> -nostdinc++")
         string(APPEND CMAKE_${lang}_STANDARD_LIBRARIES " -nostdlib++")
       endmacro()
     else()
diff --git a/Modules/Platform/Android-Determine.cmake b/Modules/Platform/Android-Determine.cmake
index 2225897..11a0504 100644
--- a/Modules/Platform/Android-Determine.cmake
+++ b/Modules/Platform/Android-Determine.cmake
@@ -7,8 +7,8 @@
 
 # Support for NVIDIA Nsight Tegra Visual Studio Edition was previously
 # implemented in the CMake VS IDE generators.  Avoid interfering with
-# that functionality for now.  Later we may try to integrate this.
-if(CMAKE_GENERATOR MATCHES "Visual Studio")
+# that functionality for now.
+if(CMAKE_GENERATOR_PLATFORM STREQUAL "Tegra-Android")
   return()
 endif()
 
@@ -27,6 +27,63 @@
 cmake_policy(PUSH)
 cmake_policy(SET CMP0057 NEW) # if IN_LIST
 
+# If using Android tools for Visual Studio, compile a sample project to get the
+# sysroot.
+if(CMAKE_GENERATOR MATCHES "Visual Studio")
+  if(NOT CMAKE_SYSROOT)
+    set(vcx_platform ${CMAKE_GENERATOR_PLATFORM})
+    if(CMAKE_GENERATOR MATCHES "Visual Studio 1[45]")
+      set(vcx_sysroot_var "Sysroot")
+    else()
+      set(vcx_sysroot_var "SysrootLink")
+    endif()
+    if(CMAKE_GENERATOR MATCHES "Visual Studio 14")
+      set(vcx_revision "2.0")
+    elseif(CMAKE_GENERATOR MATCHES "Visual Studio 1[56]")
+      set(vcx_revision "3.0")
+    else()
+      set(vcx_revision "")
+    endif()
+    configure_file(${CMAKE_ROOT}/Modules/Platform/Android/VCXProjInspect.vcxproj.in
+      ${CMAKE_PLATFORM_INFO_DIR}/VCXProjInspect.vcxproj @ONLY)
+    execute_process(
+      COMMAND "${CMAKE_VS_MSBUILD_COMMAND}" "VCXProjInspect.vcxproj"
+        "/p:Configuration=Debug" "/p:Platform=${vcx_platform}"
+      WORKING_DIRECTORY ${CMAKE_PLATFORM_INFO_DIR}
+      OUTPUT_VARIABLE VCXPROJ_INSPECT_OUTPUT
+      ERROR_VARIABLE VCXPROJ_INSPECT_OUTPUT
+      RESULT_VARIABLE VCXPROJ_INSPECT_RESULT
+      )
+    if(NOT CMAKE_SYSROOT AND VCXPROJ_INSPECT_OUTPUT MATCHES "CMAKE_SYSROOT=([^%\r\n]+)[\r\n]")
+      # Strip VS diagnostic output from the end of the line.
+      string(REGEX REPLACE " \\(TaskId:[0-9]*\\)$" "" _sysroot "${CMAKE_MATCH_1}")
+      if(EXISTS "${_sysroot}")
+        file(TO_CMAKE_PATH "${_sysroot}" CMAKE_SYSROOT)
+      endif()
+    endif()
+    if(VCXPROJ_INSPECT_RESULT)
+      file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
+        "Determining the sysroot for the Android NDK failed.
+The output was:
+${VCXPROJ_INSPECT_RESULT}
+${VCXPROJ_INSPECT_OUTPUT}
+
+")
+    else()
+      file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
+        "Determining the sysroot for the Android NDK succeeded.
+The output was:
+${VCXPROJ_INSPECT_RESULT}
+${VCXPROJ_INSPECT_OUTPUT}
+
+")
+    endif()
+  endif()
+  if(NOT CMAKE_ANDROID_NDK_TOOLCHAIN_VERSION)
+    set(CMAKE_ANDROID_NDK_TOOLCHAIN_VERSION "clang")
+  endif()
+endif()
+
 # If the user provided CMAKE_SYSROOT for us, extract information from it.
 set(_ANDROID_SYSROOT_NDK "")
 set(_ANDROID_SYSROOT_API "")
diff --git a/Modules/Platform/Android-Initialize.cmake b/Modules/Platform/Android-Initialize.cmake
index b90dd7a..5019c28 100644
--- a/Modules/Platform/Android-Initialize.cmake
+++ b/Modules/Platform/Android-Initialize.cmake
@@ -6,7 +6,7 @@
 
 # Support for NVIDIA Nsight Tegra Visual Studio Edition was previously
 # implemented in the CMake VS IDE generators.  Avoid interfering with
-# that functionality for now.  Later we may try to integrate this.
+# that functionality for now.
 if(CMAKE_VS_PLATFORM_NAME STREQUAL "Tegra-Android")
   return()
 endif()
diff --git a/Modules/Platform/Android/Determine-Compiler-NDK.cmake b/Modules/Platform/Android/Determine-Compiler-NDK.cmake
index f56e1d5..a4d67c4 100644
--- a/Modules/Platform/Android/Determine-Compiler-NDK.cmake
+++ b/Modules/Platform/Android/Determine-Compiler-NDK.cmake
@@ -184,7 +184,7 @@
       # We just matched the gcc toolchain name without version number.  Save it for later.
       set(_ANDROID_TOOL_NAME_ONLY "${CMAKE_MATCH_1}")
     elseif(line MATCHES [[^TOOLCHAIN_PREFIX +:= +.*/bin/(\$\(TOOLCHAIN_NAME\)-) *$]])
-      # We just matched the toolchain prefix with a name placholder, so substitute it.
+      # We just matched the toolchain prefix with a name placeholder, so substitute it.
       # The gcc toolchain name will have already been extracted without version number from a TOOLCHAIN_NAME line.
       string(REPLACE "$(TOOLCHAIN_NAME)" "${_ANDROID_TOOL_NAME_ONLY}" _ANDROID_TOOL_PREFIX "${CMAKE_MATCH_1}")
     elseif(line MATCHES [[^LLVM_VERSION +:= +([0-9.]+)$]])
diff --git a/Modules/Platform/Android/VCXProjInspect.vcxproj.in b/Modules/Platform/Android/VCXProjInspect.vcxproj.in
new file mode 100644
index 0000000..6919d2c
--- /dev/null
+++ b/Modules/Platform/Android/VCXProjInspect.vcxproj.in
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup Label="ProjectConfigurations">
+    <ProjectConfiguration Include="Debug|@vcx_platform@">
+      <Configuration>Debug</Configuration>
+      <Platform>@vcx_platform@</Platform>
+    </ProjectConfiguration>
+  </ItemGroup>
+  <PropertyGroup Label="Globals">
+    <ProjectGuid>{14D44772-ECF7-47BD-9E29-BC62FAF940A5}</ProjectGuid>
+    <RootNamespace>VCXProjInspect</RootNamespace>
+    <Keyword>Android</Keyword>
+    <ApplicationType>Android</ApplicationType>
+    <ApplicationTypeRevision>@vcx_revision@</ApplicationTypeRevision>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+  <PropertyGroup>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|@vcx_platform@'" Label="Configuration">
+    <ConfigurationType>DynamicLibrary</ConfigurationType>
+    <CharacterSet>MultiByte</CharacterSet>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+  <ImportGroup Label="ExtensionSettings">
+  </ImportGroup>
+  <PropertyGroup>
+    <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|@vcx_platform@'">false</LinkIncremental>
+  </PropertyGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|@vcx_platform@'">
+    <PostBuildEvent>
+      <Command>%40echo CMAKE_SYSROOT=$(@vcx_sysroot_var@)</Command>
+    </PostBuildEvent>
+  </ItemDefinitionGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+  <ImportGroup Label="ExtensionTargets">
+  </ImportGroup>
+</Project>
diff --git a/Modules/Platform/BlueGeneL.cmake b/Modules/Platform/BlueGeneL.cmake
index 082e46c..0ed9975 100644
--- a/Modules/Platform/BlueGeneL.cmake
+++ b/Modules/Platform/BlueGeneL.cmake
@@ -23,18 +23,18 @@
 
 if(CMAKE_COMPILER_IS_GNUCC)
   set(CMAKE_C_LINK_EXECUTABLE
-    "<CMAKE_C_COMPILER> -Wl,-relax <FLAGS> <CMAKE_C_LINK_FLAGS> <LINK_FLAGS> <OBJECTS>  -o <TARGET> <LINK_LIBRARIES> -Wl,-lgcc,-lc -lnss_files -lnss_dns -lresolv")
+    "<CMAKE_C_COMPILER> -Wl,-relax <FLAGS> <CMAKE_C_LINK_FLAGS> <LINK_FLAGS> <OBJECTS> -o <TARGET> <LINK_LIBRARIES> -Wl,-lgcc,-lc -lnss_files -lnss_dns -lresolv")
 else()
   # when using IBM xlc we probably don't want to link to -lgcc
   set(CMAKE_C_LINK_EXECUTABLE
-    "<CMAKE_C_COMPILER> -Wl,-relax <FLAGS> <CMAKE_C_LINK_FLAGS> <LINK_FLAGS> <OBJECTS>  -o <TARGET> <LINK_LIBRARIES> -Wl,-lc -lnss_files -lnss_dns -lresolv")
+    "<CMAKE_C_COMPILER> -Wl,-relax <FLAGS> <CMAKE_C_LINK_FLAGS> <LINK_FLAGS> <OBJECTS> -o <TARGET> <LINK_LIBRARIES> -Wl,-lc -lnss_files -lnss_dns -lresolv")
 endif()
 
 if(CMAKE_COMPILER_IS_GNUCXX)
   set(CMAKE_CXX_LINK_EXECUTABLE
-    "<CMAKE_CXX_COMPILER> -Wl,-relax <FLAGS> <CMAKE_CXX_LINK_FLAGS> <LINK_FLAGS> <OBJECTS>  -o <TARGET> <LINK_LIBRARIES> -Wl,-lstdc++,-lgcc,-lc -lnss_files -lnss_dns -lresolv")
+    "<CMAKE_CXX_COMPILER> -Wl,-relax <FLAGS> <CMAKE_CXX_LINK_FLAGS> <LINK_FLAGS> <OBJECTS> -o <TARGET> <LINK_LIBRARIES> -Wl,-lstdc++,-lgcc,-lc -lnss_files -lnss_dns -lresolv")
 else()
   # when using the IBM xlC we probably don't want to link to -lgcc
   set(CMAKE_CXX_LINK_EXECUTABLE
-    "<CMAKE_CXX_COMPILER> -Wl,-relax <FLAGS> <CMAKE_CXX_LINK_FLAGS> <LINK_FLAGS> <OBJECTS>  -o <TARGET> <LINK_LIBRARIES> -Wl,-lstdc++,-lc -lnss_files -lnss_dns -lresolv")
+    "<CMAKE_CXX_COMPILER> -Wl,-relax <FLAGS> <CMAKE_CXX_LINK_FLAGS> <LINK_FLAGS> <OBJECTS> -o <TARGET> <LINK_LIBRARIES> -Wl,-lstdc++,-lc -lnss_files -lnss_dns -lresolv")
 endif()
diff --git a/Modules/Platform/BlueGeneP-base.cmake b/Modules/Platform/BlueGeneP-base.cmake
index fe95b42..7095dd8 100644
--- a/Modules/Platform/BlueGeneP-base.cmake
+++ b/Modules/Platform/BlueGeneP-base.cmake
@@ -97,7 +97,7 @@
   set(CMAKE_SHARED_LIBRARY_RUNTIME_${lang}_FLAG_SEP  ":") # : or empty
 
   set(BGP_${lang}_DEFAULT_EXE_FLAGS
-    "<FLAGS> <CMAKE_${lang}_LINK_FLAGS> <LINK_FLAGS> <OBJECTS>  -o <TARGET> <LINK_LIBRARIES>")
+    "<FLAGS> <CMAKE_${lang}_LINK_FLAGS> <LINK_FLAGS> <OBJECTS> -o <TARGET> <LINK_LIBRARIES>")
   set(CMAKE_${lang}_LINK_EXECUTABLE
     "<CMAKE_${lang}_COMPILER> -Wl,-relax ${BGP_${lang}_DYNAMIC_EXE_FLAGS} ${BGP_${lang}_DEFAULT_EXE_FLAGS}")
 endmacro()
@@ -108,7 +108,7 @@
 #
 macro(__BlueGeneP_set_static_flags compiler_id lang)
   set(BGP_${lang}_DEFAULT_EXE_FLAGS
-    "<FLAGS> <CMAKE_${lang}_LINK_FLAGS> <LINK_FLAGS> <OBJECTS>  -o <TARGET> <LINK_LIBRARIES>")
+    "<FLAGS> <CMAKE_${lang}_LINK_FLAGS> <LINK_FLAGS> <OBJECTS> -o <TARGET> <LINK_LIBRARIES>")
   set(CMAKE_${lang}_LINK_EXECUTABLE
     "<CMAKE_${lang}_COMPILER> -Wl,-relax ${BGP_${lang}_DEFAULT_EXE_FLAGS}")
 endmacro()
diff --git a/Modules/Platform/BlueGeneQ-base.cmake b/Modules/Platform/BlueGeneQ-base.cmake
index 5e56d8e..94cb0a8 100644
--- a/Modules/Platform/BlueGeneQ-base.cmake
+++ b/Modules/Platform/BlueGeneQ-base.cmake
@@ -101,7 +101,7 @@
   foreach(dir ${CMAKE_SYSTEM_INCLUDE_PATH})
     string(APPEND BGQ_SYSTEM_INCLUDES " -I${dir}")
   endforeach()
-  set(CMAKE_C_COMPILE_OBJECT   "<CMAKE_C_COMPILER>   <DEFINES> ${BGQ_SYSTEM_INCLUDES} <INCLUDES> <FLAGS> -o <OBJECT> -c <SOURCE>")
+  set(CMAKE_C_COMPILE_OBJECT   "<CMAKE_C_COMPILER> <DEFINES> ${BGQ_SYSTEM_INCLUDES} <INCLUDES> <FLAGS> -o <OBJECT> -c <SOURCE>")
   set(CMAKE_CXX_COMPILE_OBJECT "<CMAKE_CXX_COMPILER> <DEFINES> ${BGQ_SYSTEM_INCLUDES} <INCLUDES> <FLAGS> -o <OBJECT> -c <SOURCE>")
 
   #
@@ -146,7 +146,7 @@
 
   # For dynamic executables, need to provide special BG/Q arguments.
   set(BGQ_${lang}_DEFAULT_EXE_FLAGS
-    "<FLAGS> <CMAKE_${lang}_LINK_FLAGS> <LINK_FLAGS> <OBJECTS>  -o <TARGET> <LINK_LIBRARIES>")
+    "<FLAGS> <CMAKE_${lang}_LINK_FLAGS> <LINK_FLAGS> <OBJECTS> -o <TARGET> <LINK_LIBRARIES>")
   set(CMAKE_${lang}_LINK_EXECUTABLE
     "<CMAKE_${lang}_COMPILER> -Wl,-relax ${BGQ_${lang}_DYNAMIC_EXE_FLAGS} ${BGQ_${lang}_DEFAULT_EXE_FLAGS}")
 endmacro()
@@ -160,7 +160,7 @@
 
   # For static executables, use default link settings.
   set(BGQ_${lang}_DEFAULT_EXE_FLAGS
-    "<FLAGS> <CMAKE_${lang}_LINK_FLAGS> <LINK_FLAGS> <OBJECTS>  -o <TARGET> <LINK_LIBRARIES>")
+    "<FLAGS> <CMAKE_${lang}_LINK_FLAGS> <LINK_FLAGS> <OBJECTS> -o <TARGET> <LINK_LIBRARIES>")
   set(CMAKE_${lang}_LINK_EXECUTABLE
     "<CMAKE_${lang}_COMPILER> -Wl,-relax ${BGQ_${lang}_DEFAULT_EXE_FLAGS}")
 endmacro()
diff --git a/Modules/Platform/CYGWIN-GNU.cmake b/Modules/Platform/CYGWIN-GNU.cmake
index ca90712..4fa14ce 100644
--- a/Modules/Platform/CYGWIN-GNU.cmake
+++ b/Modules/Platform/CYGWIN-GNU.cmake
@@ -22,7 +22,7 @@
   set(CMAKE_${lang}_CREATE_SHARED_LIBRARY
     "<CMAKE_${lang}_COMPILER> <LANGUAGE_COMPILE_FLAGS> <CMAKE_SHARED_LIBRARY_${lang}_FLAGS> <LINK_FLAGS> <CMAKE_SHARED_LIBRARY_CREATE_${lang}_FLAGS> -o <TARGET> -Wl,--out-implib,<TARGET_IMPLIB> ${CMAKE_GNULD_IMAGE_VERSION} <OBJECTS> <LINK_LIBRARIES>")
   set(CMAKE_${lang}_LINK_EXECUTABLE
-    "<CMAKE_${lang}_COMPILER> <FLAGS> <CMAKE_${lang}_LINK_FLAGS> <LINK_FLAGS> <OBJECTS>  -o <TARGET> -Wl,--out-implib,<TARGET_IMPLIB> ${CMAKE_GNULD_IMAGE_VERSION} <LINK_LIBRARIES>")
+    "<CMAKE_${lang}_COMPILER> <FLAGS> <CMAKE_${lang}_LINK_FLAGS> <LINK_FLAGS> <OBJECTS> -o <TARGET> -Wl,--out-implib,<TARGET_IMPLIB> ${CMAKE_GNULD_IMAGE_VERSION} <LINK_LIBRARIES>")
 
    # No -fPIC on cygwin
   set(CMAKE_${lang}_COMPILE_OPTIONS_PIC "")
diff --git a/Modules/Platform/DOS-OpenWatcom-C.cmake b/Modules/Platform/DOS-OpenWatcom-C.cmake
new file mode 100644
index 0000000..cf71c84
--- /dev/null
+++ b/Modules/Platform/DOS-OpenWatcom-C.cmake
@@ -0,0 +1 @@
+include(Platform/DOS-OpenWatcom)
diff --git a/Modules/Platform/DOS-OpenWatcom-CXX.cmake b/Modules/Platform/DOS-OpenWatcom-CXX.cmake
new file mode 100644
index 0000000..cf71c84
--- /dev/null
+++ b/Modules/Platform/DOS-OpenWatcom-CXX.cmake
@@ -0,0 +1 @@
+include(Platform/DOS-OpenWatcom)
diff --git a/Modules/Platform/DOS-OpenWatcom.cmake b/Modules/Platform/DOS-OpenWatcom.cmake
new file mode 100644
index 0000000..54c452e
--- /dev/null
+++ b/Modules/Platform/DOS-OpenWatcom.cmake
@@ -0,0 +1,28 @@
+
+# This module is shared by multiple languages; use include blocker.
+include_guard()
+
+set(CMAKE_BUILD_TYPE_INIT Debug)
+
+if(DEFINED CMAKE_SYSTEM_PROCESSOR AND CMAKE_SYSTEM_PROCESSOR STREQUAL "I86")
+  string(APPEND CMAKE_EXE_LINKER_FLAGS_INIT " system dos")
+  string(APPEND CMAKE_SHARED_LINKER_FLAGS_INIT " system dos")
+  string(APPEND CMAKE_MODULE_LINKER_FLAGS_INIT " system dos")
+else()
+  string(APPEND CMAKE_EXE_LINKER_FLAGS_INIT " system dos4g")
+  string(APPEND CMAKE_SHARED_LINKER_FLAGS_INIT " system dos4g")
+  string(APPEND CMAKE_MODULE_LINKER_FLAGS_INIT " system dos4g")
+endif()
+
+set(CMAKE_C_COMPILE_OPTIONS_DLL "-bd") # Note: This variable is a ';' separated list
+set(CMAKE_SHARED_LIBRARY_C_FLAGS "-bd") # ... while this is a space separated string.
+
+string(APPEND CMAKE_C_FLAGS_INIT " -bt=dos")
+string(APPEND CMAKE_CXX_FLAGS_INIT " -bt=dos -xs")
+
+if(NOT CMAKE_C_STANDARD_INCLUDE_DIRECTORIES)
+  set(CMAKE_C_STANDARD_INCLUDE_DIRECTORIES $ENV{WATCOM}/h)
+endif()
+if(NOT CMAKE_CXX_STANDARD_INCLUDE_DIRECTORIES)
+  set(CMAKE_CXX_STANDARD_INCLUDE_DIRECTORIES $ENV{WATCOM}/h)
+endif()
diff --git a/Modules/Platform/DOS.cmake b/Modules/Platform/DOS.cmake
new file mode 100644
index 0000000..fc95936
--- /dev/null
+++ b/Modules/Platform/DOS.cmake
@@ -0,0 +1,14 @@
+set(DOS 1)
+
+set(CMAKE_STATIC_LIBRARY_PREFIX "")
+set(CMAKE_STATIC_LIBRARY_SUFFIX ".lib")
+set(CMAKE_SHARED_LIBRARY_PREFIX "")
+set(CMAKE_SHARED_LIBRARY_SUFFIX ".dll")
+set(CMAKE_IMPORT_LIBRARY_PREFIX "")
+set(CMAKE_IMPORT_LIBRARY_SUFFIX ".lib")
+set(CMAKE_EXECUTABLE_SUFFIX ".exe")
+set(CMAKE_LINK_LIBRARY_SUFFIX ".lib")
+set(CMAKE_DL_LIBS "")
+
+set(CMAKE_FIND_LIBRARY_PREFIXES "")
+set(CMAKE_FIND_LIBRARY_SUFFIXES ".lib")
diff --git a/Modules/Platform/Darwin-Initialize.cmake b/Modules/Platform/Darwin-Initialize.cmake
index 80e9a40..d087412 100644
--- a/Modules/Platform/Darwin-Initialize.cmake
+++ b/Modules/Platform/Darwin-Initialize.cmake
@@ -62,45 +62,36 @@
   # Find installed SDKs in either Xcode-4.3+ or pre-4.3 SDKs directory.
   set(_CMAKE_OSX_SDKS_DIR "")
   if(OSX_DEVELOPER_ROOT)
-    foreach(d Platforms/MacOSX.platform/Developer/SDKs SDKs)
-      file(GLOB _CMAKE_OSX_SDKS ${OSX_DEVELOPER_ROOT}/${d}/*)
+    foreach(_d Platforms/MacOSX.platform/Developer/SDKs SDKs)
+      file(GLOB _CMAKE_OSX_SDKS ${OSX_DEVELOPER_ROOT}/${_d}/*)
       if(_CMAKE_OSX_SDKS)
-        set(_CMAKE_OSX_SDKS_DIR ${OSX_DEVELOPER_ROOT}/${d})
+        set(_CMAKE_OSX_SDKS_DIR ${OSX_DEVELOPER_ROOT}/${_d})
         break()
       endif()
     endforeach()
   endif()
 
   if(_CMAKE_OSX_SDKS_DIR)
-    # Select SDK for current OSX version accounting for the known
-    # specially named SDKs.
-    set(_CMAKE_OSX_SDKS_VER_SUFFIX_10.4 "u")
-    set(_CMAKE_OSX_SDKS_VER_SUFFIX_10.3 ".9")
-
-    # find the latest SDK
+    # Find the latest SDK as recommended by Apple (Technical Q&A QA1806)
     set(_CMAKE_OSX_LATEST_SDK_VERSION "0.0")
     file(GLOB _CMAKE_OSX_SDKS RELATIVE "${_CMAKE_OSX_SDKS_DIR}" "${_CMAKE_OSX_SDKS_DIR}/MacOSX*.sdk")
     foreach(_SDK ${_CMAKE_OSX_SDKS})
-      if(_SDK MATCHES "MacOSX([0-9]+\\.[0-9]+)[^/]*\\.sdk" AND CMAKE_MATCH_1 VERSION_GREATER ${_CMAKE_OSX_LATEST_SDK_VERSION})
+      if(IS_DIRECTORY "${_CMAKE_OSX_SDKS_DIR}/${_SDK}"
+         AND _SDK MATCHES "MacOSX([0-9]+\\.[0-9]+)[^/]*\\.sdk"
+         AND CMAKE_MATCH_1 VERSION_GREATER ${_CMAKE_OSX_LATEST_SDK_VERSION})
         set(_CMAKE_OSX_LATEST_SDK_VERSION "${CMAKE_MATCH_1}")
       endif()
     endforeach()
 
-    # pick an SDK that works
-    set(_CMAKE_OSX_SYSROOT_DEFAULT)
-    foreach(ver ${CMAKE_OSX_DEPLOYMENT_TARGET}
-                ${_CURRENT_OSX_VERSION}
-                ${_CMAKE_OSX_LATEST_SDK_VERSION})
-      set(_CMAKE_OSX_DEPLOYMENT_TARGET ${ver})
-      set(_CMAKE_OSX_SDKS_VER ${_CMAKE_OSX_DEPLOYMENT_TARGET}${_CMAKE_OSX_SDKS_VER_SUFFIX_${_CMAKE_OSX_DEPLOYMENT_TARGET}})
-      set(_CMAKE_OSX_SYSROOT_CHECK "${_CMAKE_OSX_SDKS_DIR}/MacOSX${_CMAKE_OSX_SDKS_VER}.sdk")
-      if(IS_DIRECTORY "${_CMAKE_OSX_SYSROOT_CHECK}")
-        set(_CMAKE_OSX_SYSROOT_DEFAULT "${_CMAKE_OSX_SYSROOT_CHECK}")
-        break()
-      endif()
-    endforeach()
+    if(NOT _CMAKE_OSX_LATEST_SDK_VERSION STREQUAL "0.0")
+      set(_CMAKE_OSX_SYSROOT_DEFAULT "${_CMAKE_OSX_SDKS_DIR}/MacOSX${_CMAKE_OSX_LATEST_SDK_VERSION}.sdk")
+    else()
+      message(WARNING "Could not find any valid SDKs in ${_CMAKE_OSX_SDKS_DIR}")
+    endif()
 
-    if(NOT CMAKE_CROSSCOMPILING AND NOT CMAKE_OSX_DEPLOYMENT_TARGET AND _CURRENT_OSX_VERSION VERSION_LESS _CMAKE_OSX_DEPLOYMENT_TARGET)
+    if(NOT CMAKE_CROSSCOMPILING AND NOT CMAKE_OSX_DEPLOYMENT_TARGET
+       AND (_CURRENT_OSX_VERSION VERSION_LESS _CMAKE_OSX_LATEST_SDK_VERSION
+            OR _CMAKE_OSX_LATEST_SDK_VERSION STREQUAL "0.0"))
       set(CMAKE_OSX_DEPLOYMENT_TARGET ${_CURRENT_OSX_VERSION} CACHE STRING
         "Minimum OS X version to target for deployment (at runtime); newer APIs weak linked. Set to empty string for default value." FORCE)
     endif()
@@ -113,8 +104,8 @@
 # Set cache variable - end user may change this during ccmake or cmake-gui configure.
 # Choose the type based on the current value.
 set(_CMAKE_OSX_SYSROOT_TYPE STRING)
-foreach(v CMAKE_OSX_SYSROOT _CMAKE_OSX_SYSROOT_DEFAULT)
-  if("x${${v}}" MATCHES "/")
+foreach(_v CMAKE_OSX_SYSROOT _CMAKE_OSX_SYSROOT_DEFAULT)
+  if("x${${_v}}" MATCHES "/")
     set(_CMAKE_OSX_SYSROOT_TYPE PATH)
     break()
   endif()
diff --git a/Modules/Platform/Darwin.cmake b/Modules/Platform/Darwin.cmake
index 0a4d4e1..c6de3b0 100644
--- a/Modules/Platform/Darwin.cmake
+++ b/Modules/Platform/Darwin.cmake
@@ -42,6 +42,7 @@
 
 set(CMAKE_SHARED_LIBRARY_PREFIX "lib")
 set(CMAKE_SHARED_LIBRARY_SUFFIX ".dylib")
+set(CMAKE_EXTRA_SHARED_LIBRARY_SUFFIXES ".tbd" ".so")
 set(CMAKE_SHARED_MODULE_PREFIX "lib")
 set(CMAKE_SHARED_MODULE_SUFFIX ".so")
 set(CMAKE_MODULE_EXISTS 1)
@@ -156,6 +157,13 @@
       break()
     endif()
   endforeach()
+
+  if(EXISTS ${_CMAKE_OSX_SYSROOT_PATH}/usr/lib)
+    list(INSERT CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES 0 ${_CMAKE_OSX_SYSROOT_PATH}/usr/lib)
+  endif()
+  if(EXISTS ${_CMAKE_OSX_SYSROOT_PATH}/usr/local/lib)
+    list(INSERT CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES 0 ${_CMAKE_OSX_SYSROOT_PATH}/usr/local/lib)
+  endif()
 endif()
 if (OSX_DEVELOPER_ROOT AND EXISTS "${OSX_DEVELOPER_ROOT}/Library/Frameworks")
   list(APPEND CMAKE_SYSTEM_FRAMEWORK_PATH
@@ -208,11 +216,19 @@
 unset(_apps_paths)
 
 include(Platform/UnixPaths)
-if(_CMAKE_OSX_SYSROOT_PATH AND EXISTS ${_CMAKE_OSX_SYSROOT_PATH}/usr/include)
-  list(APPEND CMAKE_SYSTEM_PREFIX_PATH ${_CMAKE_OSX_SYSROOT_PATH}/usr)
-  foreach(lang C CXX OBJC OBJCXX Swift)
-    list(APPEND _CMAKE_${lang}_IMPLICIT_INCLUDE_DIRECTORIES_INIT ${_CMAKE_OSX_SYSROOT_PATH}/usr/include)
-  endforeach()
+if(_CMAKE_OSX_SYSROOT_PATH)
+  if(EXISTS ${_CMAKE_OSX_SYSROOT_PATH}/usr/include)
+    list(INSERT CMAKE_SYSTEM_PREFIX_PATH 0 ${_CMAKE_OSX_SYSROOT_PATH}/usr)
+    foreach(lang C CXX OBJC OBJCXX Swift)
+      list(APPEND _CMAKE_${lang}_IMPLICIT_INCLUDE_DIRECTORIES_INIT ${_CMAKE_OSX_SYSROOT_PATH}/usr/include)
+    endforeach()
+  endif()
+  if(EXISTS ${_CMAKE_OSX_SYSROOT_PATH}/usr/local/include)
+    list(INSERT CMAKE_SYSTEM_PREFIX_PATH 0 ${_CMAKE_OSX_SYSROOT_PATH}/usr/local)
+    foreach(lang C CXX OBJC OBJCXX Swift)
+      list(APPEND _CMAKE_${lang}_IMPLICIT_INCLUDE_DIRECTORIES_INIT ${_CMAKE_OSX_SYSROOT_PATH}/usr/local/include)
+    endforeach()
+  endif()
 endif()
 list(APPEND CMAKE_SYSTEM_PREFIX_PATH
   /sw        # Fink
diff --git a/Modules/Platform/HP-UX-HP-C.cmake b/Modules/Platform/HP-UX-HP-C.cmake
index 7610383..57ba2eb 100644
--- a/Modules/Platform/HP-UX-HP-C.cmake
+++ b/Modules/Platform/HP-UX-HP-C.cmake
@@ -3,4 +3,4 @@
 
 set(CMAKE_C_CREATE_PREPROCESSED_SOURCE "<CMAKE_C_COMPILER> <DEFINES> <INCLUDES> <FLAGS> -E <SOURCE> > <PREPROCESSED_SOURCE>")
 set(CMAKE_C_CREATE_ASSEMBLY_SOURCE "<CMAKE_C_COMPILER> <DEFINES> <INCLUDES> <FLAGS> -S <SOURCE> -o <ASSEMBLY_SOURCE>")
-set(CMAKE_C_COMPILE_OBJECT "<CMAKE_C_COMPILER> <DEFINES> -Aa -Ae <INCLUDES> <FLAGS> -o <OBJECT>   -c <SOURCE>")
+set(CMAKE_C_COMPILE_OBJECT "<CMAKE_C_COMPILER> <DEFINES> -Aa -Ae <INCLUDES> <FLAGS> -o <OBJECT> -c <SOURCE>")
diff --git a/Modules/Platform/HP-UX.cmake b/Modules/Platform/HP-UX.cmake
index 9572a7e..425a13f 100644
--- a/Modules/Platform/HP-UX.cmake
+++ b/Modules/Platform/HP-UX.cmake
@@ -22,7 +22,7 @@
 # set flags for gcc support
 include(Platform/UnixPaths)
 
-# Look in both 32-bit and 64-bit implict link directories, but tell
+# Look in both 32-bit and 64-bit implicit link directories, but tell
 # CMake not to pass the paths to the linker.  The linker will find the
 # library for the proper architecture.  In the future we should detect
 # which path will be used by the linker.  Since the pointer type size
diff --git a/Modules/Platform/Linux-OpenWatcom-C.cmake b/Modules/Platform/Linux-OpenWatcom-C.cmake
new file mode 100644
index 0000000..383349a
--- /dev/null
+++ b/Modules/Platform/Linux-OpenWatcom-C.cmake
@@ -0,0 +1 @@
+include(Platform/Linux-OpenWatcom)
diff --git a/Modules/Platform/Linux-OpenWatcom-CXX.cmake b/Modules/Platform/Linux-OpenWatcom-CXX.cmake
new file mode 100644
index 0000000..383349a
--- /dev/null
+++ b/Modules/Platform/Linux-OpenWatcom-CXX.cmake
@@ -0,0 +1 @@
+include(Platform/Linux-OpenWatcom)
diff --git a/Modules/Platform/Linux-OpenWatcom.cmake b/Modules/Platform/Linux-OpenWatcom.cmake
new file mode 100644
index 0000000..5b4e995
--- /dev/null
+++ b/Modules/Platform/Linux-OpenWatcom.cmake
@@ -0,0 +1,25 @@
+# Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
+# file Copyright.txt or https://cmake.org/licensing for details.
+
+# This module is shared by multiple languages; use include blocker.
+include_guard()
+
+set(CMAKE_BUILD_TYPE_INIT Debug)
+
+string(APPEND CMAKE_EXE_LINKER_FLAGS_INIT " system linux opt noextension")
+string(APPEND CMAKE_MODULE_LINKER_FLAGS_INIT " system linux")
+string(APPEND CMAKE_SHARED_LINKER_FLAGS_INIT " system linux")
+
+# single/multi-threaded                 /-bm
+# default is setup for single-threaded libraries
+string(APPEND CMAKE_C_FLAGS_INIT " -bt=linux")
+string(APPEND CMAKE_CXX_FLAGS_INIT " -bt=linux -xs")
+
+if(CMAKE_CROSSCOMPILING)
+  if(NOT CMAKE_C_STANDARD_INCLUDE_DIRECTORIES)
+    set(CMAKE_C_STANDARD_INCLUDE_DIRECTORIES $ENV{WATCOM}/lh)
+  endif()
+  if(NOT CMAKE_CXX_STANDARD_INCLUDE_DIRECTORIES)
+    set(CMAKE_CXX_STANDARD_INCLUDE_DIRECTORIES $ENV{WATCOM}/lh)
+  endif()
+endif()
diff --git a/Modules/Platform/Linux-como.cmake b/Modules/Platform/Linux-como.cmake
index d1550d2..f6db34c 100644
--- a/Modules/Platform/Linux-como.cmake
+++ b/Modules/Platform/Linux-como.cmake
@@ -11,7 +11,7 @@
 
 set(CMAKE_CXX_LINK_EXECUTABLE
     "<CMAKE_CXX_COMPILER> --prelink_objects <OBJECTS>"
-    "<CMAKE_CXX_COMPILER> <CMAKE_CXX_LINK_FLAGS> <LINK_FLAGS> <FLAGS> <OBJECTS>  -o <TARGET> <LINK_LIBRARIES>")
+    "<CMAKE_CXX_COMPILER> <CMAKE_CXX_LINK_FLAGS> <LINK_FLAGS> <FLAGS> <OBJECTS> -o <TARGET> <LINK_LIBRARIES>")
 
 set(CMAKE_SHARED_LIBRARY_RUNTIME_C_FLAG "")
 set(CMAKE_SHARED_LIBRARY_C_FLAGS "")
diff --git a/Modules/Platform/OS2-OpenWatcom-C.cmake b/Modules/Platform/OS2-OpenWatcom-C.cmake
new file mode 100644
index 0000000..21a4d9e
--- /dev/null
+++ b/Modules/Platform/OS2-OpenWatcom-C.cmake
@@ -0,0 +1 @@
+include(Platform/OS2-OpenWatcom)
diff --git a/Modules/Platform/OS2-OpenWatcom-CXX.cmake b/Modules/Platform/OS2-OpenWatcom-CXX.cmake
new file mode 100644
index 0000000..21a4d9e
--- /dev/null
+++ b/Modules/Platform/OS2-OpenWatcom-CXX.cmake
@@ -0,0 +1 @@
+include(Platform/OS2-OpenWatcom)
diff --git a/Modules/Platform/OS2-OpenWatcom.cmake b/Modules/Platform/OS2-OpenWatcom.cmake
new file mode 100644
index 0000000..998fb9f
--- /dev/null
+++ b/Modules/Platform/OS2-OpenWatcom.cmake
@@ -0,0 +1,35 @@
+# This module is shared by multiple languages; use include blocker.
+include_guard()
+
+set(CMAKE_BUILD_TYPE_INIT Debug)
+
+if(DEFINED CMAKE_SYSTEM_PROCESSOR AND CMAKE_SYSTEM_PROCESSOR STREQUAL "I86")
+  string(APPEND CMAKE_EXE_LINKER_FLAGS_INIT " system os2")
+  string(APPEND CMAKE_SHARED_LINKER_FLAGS_INIT " system os2_dll")
+  string(APPEND CMAKE_MODULE_LINKER_FLAGS_INIT " system os2_dll")
+else()
+  string(APPEND CMAKE_EXE_LINKER_FLAGS_INIT " system os2v2")
+  string(APPEND CMAKE_SHARED_LINKER_FLAGS_INIT " system os2v2_dll")
+  string(APPEND CMAKE_MODULE_LINKER_FLAGS_INIT " system os2v2_dll")
+endif()
+
+set(CMAKE_C_COMPILE_OPTIONS_DLL "-bd") # Note: This variable is a ';' separated list
+set(CMAKE_SHARED_LIBRARY_C_FLAGS "-bd") # ... while this is a space separated string.
+
+string(APPEND CMAKE_C_FLAGS_INIT " -bt=os2")
+string(APPEND CMAKE_CXX_FLAGS_INIT " -bt=os2 -xs")
+
+if(NOT CMAKE_C_STANDARD_INCLUDE_DIRECTORIES)
+  if(DEFINED CMAKE_SYSTEM_PROCESSOR AND CMAKE_SYSTEM_PROCESSOR STREQUAL "I86")
+    set(CMAKE_C_STANDARD_INCLUDE_DIRECTORIES $ENV{WATCOM}/h $ENV{WATCOM}/h/os21x)
+  else()
+    set(CMAKE_C_STANDARD_INCLUDE_DIRECTORIES $ENV{WATCOM}/h $ENV{WATCOM}/h/os2)
+  endif()
+endif()
+if(NOT CMAKE_CXX_STANDARD_INCLUDE_DIRECTORIES)
+  if(DEFINED CMAKE_SYSTEM_PROCESSOR AND CMAKE_SYSTEM_PROCESSOR STREQUAL "I86")
+    set(CMAKE_CXX_STANDARD_INCLUDE_DIRECTORIES $ENV{WATCOM}/h $ENV{WATCOM}/h/os21x)
+  else()
+    set(CMAKE_CXX_STANDARD_INCLUDE_DIRECTORIES $ENV{WATCOM}/h $ENV{WATCOM}/h/os2)
+  endif()
+endif()
diff --git a/Modules/Platform/OS2.cmake b/Modules/Platform/OS2.cmake
new file mode 100644
index 0000000..a9df66d
--- /dev/null
+++ b/Modules/Platform/OS2.cmake
@@ -0,0 +1,14 @@
+set(OS2 1)
+
+set(CMAKE_STATIC_LIBRARY_PREFIX "")
+set(CMAKE_STATIC_LIBRARY_SUFFIX ".lib")
+set(CMAKE_SHARED_LIBRARY_PREFIX "")
+set(CMAKE_SHARED_LIBRARY_SUFFIX ".dll")
+set(CMAKE_IMPORT_LIBRARY_PREFIX "")
+set(CMAKE_IMPORT_LIBRARY_SUFFIX ".lib")
+set(CMAKE_EXECUTABLE_SUFFIX ".exe")
+set(CMAKE_LINK_LIBRARY_SUFFIX ".lib")
+set(CMAKE_DL_LIBS "")
+
+set(CMAKE_FIND_LIBRARY_PREFIXES "")
+set(CMAKE_FIND_LIBRARY_SUFFIXES ".lib")
diff --git a/Modules/Platform/UnixPaths.cmake b/Modules/Platform/UnixPaths.cmake
index 97f744d..b9381c3 100644
--- a/Modules/Platform/UnixPaths.cmake
+++ b/Modules/Platform/UnixPaths.cmake
@@ -21,6 +21,10 @@
 
 # List common installation prefixes.  These will be used for all
 # search types.
+#
+# Reminder when adding new locations computed from environment variables
+# please make sure to keep Help/variable/CMAKE_SYSTEM_PREFIX_PATH.rst
+# synchronized
 list(APPEND CMAKE_SYSTEM_PREFIX_PATH
   # Standard
   /usr/local /usr /
@@ -86,6 +90,17 @@
 
 unset(_cmake_sysroot_compile)
 
+# Reminder when adding new locations computed from environment variables
+# please make sure to keep Help/variable/CMAKE_SYSTEM_PREFIX_PATH.rst
+# synchronized
+if(CMAKE_COMPILER_SYSROOT)
+  list(PREPEND CMAKE_SYSTEM_PREFIX_PATH "${CMAKE_COMPILER_SYSROOT}")
+
+  if(DEFINED ENV{CONDA_PREFIX} AND EXISTS "$ENV{CONDA_PREFIX}")
+    list(APPEND CMAKE_SYSTEM_PREFIX_PATH "$ENV{CONDA_PREFIX}")
+  endif()
+endif()
+
 # Enable use of lib32 and lib64 search path variants by default.
 set_property(GLOBAL PROPERTY FIND_LIBRARY_USE_LIB32_PATHS TRUE)
 set_property(GLOBAL PROPERTY FIND_LIBRARY_USE_LIB64_PATHS TRUE)
diff --git a/Modules/Platform/Windows-Clang.cmake b/Modules/Platform/Windows-Clang.cmake
index a048698..05dff9d 100644
--- a/Modules/Platform/Windows-Clang.cmake
+++ b/Modules/Platform/Windows-Clang.cmake
@@ -55,13 +55,13 @@
 
   # Create archiving rules to support large object file lists for static libraries.
   set(CMAKE_${lang}_ARCHIVE_CREATE "<CMAKE_AR> qc <TARGET> <LINK_FLAGS> <OBJECTS>")
-  set(CMAKE_${lang}_ARCHIVE_APPEND "<CMAKE_AR> q  <TARGET> <LINK_FLAGS> <OBJECTS>")
+  set(CMAKE_${lang}_ARCHIVE_APPEND "<CMAKE_AR> q <TARGET> <LINK_FLAGS> <OBJECTS>")
   set(CMAKE_${lang}_ARCHIVE_FINISH "<CMAKE_RANLIB> <TARGET>")
   set(CMAKE_${lang}_CREATE_SHARED_LIBRARY
     "<CMAKE_${lang}_COMPILER> -fuse-ld=lld-link -nostartfiles -nostdlib <CMAKE_SHARED_LIBRARY_${lang}_FLAGS> <LANGUAGE_COMPILE_FLAGS> <LINK_FLAGS> <CMAKE_SHARED_LIBRARY_CREATE_${lang}_FLAGS> -o <TARGET> ${CMAKE_GNULD_IMAGE_VERSION} -Xlinker /implib:<TARGET_IMPLIB> -Xlinker /pdb:<TARGET_PDB> -Xlinker /version:<TARGET_VERSION_MAJOR>.<TARGET_VERSION_MINOR> <OBJECTS> <LINK_LIBRARIES>")
   set(CMAKE_${lang}_CREATE_SHARED_MODULE ${CMAKE_${lang}_CREATE_SHARED_LIBRARY})
   set(CMAKE_${lang}_LINK_EXECUTABLE
-    "<CMAKE_${lang}_COMPILER> -fuse-ld=lld-link -nostartfiles -nostdlib <FLAGS> <CMAKE_${lang}_LINK_FLAGS> <LINK_FLAGS> <OBJECTS>  -o <TARGET> -Xlinker /implib:<TARGET_IMPLIB> -Xlinker /pdb:<TARGET_PDB> -Xlinker /version:<TARGET_VERSION_MAJOR>.<TARGET_VERSION_MINOR> ${CMAKE_GNULD_IMAGE_VERSION} <LINK_LIBRARIES>")
+    "<CMAKE_${lang}_COMPILER> -fuse-ld=lld-link -nostartfiles -nostdlib <FLAGS> <CMAKE_${lang}_LINK_FLAGS> <LINK_FLAGS> <OBJECTS> -o <TARGET> -Xlinker /implib:<TARGET_IMPLIB> -Xlinker /pdb:<TARGET_PDB> -Xlinker /version:<TARGET_VERSION_MAJOR>.<TARGET_VERSION_MINOR> ${CMAKE_GNULD_IMAGE_VERSION} <LINK_LIBRARIES>")
 
   if(NOT "${lang}" STREQUAL "ASM")
     set(CMAKE_${lang}_COMPILE_OPTIONS_MSVC_RUNTIME_LIBRARY_MultiThreaded         -Xclang -flto-visibility-public-std -D_MT -Xclang --dependent-lib=libcmt)
@@ -142,7 +142,7 @@
       endif()
       if(DEFINED CMAKE_RC_PREPROCESSOR)
         set(CMAKE_DEPFILE_FLAGS_RC "-clang:-MD -clang:-MF -clang:<DEPFILE>")
-        set(CMAKE_RC_COMPILE_OBJECT "${CMAKE_COMMAND} -E cmake_llvm_rc <SOURCE> <OBJECT>.pp <${CMAKE_RC_PREPROCESSOR}> <DEFINES> -DRC_INVOKED <INCLUDES> <FLAGS> -E <SOURCE> -- <CMAKE_RC_COMPILER> <DEFINES> -I <SOURCE_DIR> <INCLUDES> /fo <OBJECT> <OBJECT>.pp")
+        set(CMAKE_RC_COMPILE_OBJECT "${CMAKE_COMMAND} -E cmake_llvm_rc <SOURCE> <OBJECT>.pp <${CMAKE_RC_PREPROCESSOR}> <DEFINES> -DRC_INVOKED <INCLUDES> <FLAGS> -E -- <SOURCE> ++ <CMAKE_RC_COMPILER> <DEFINES> -I <SOURCE_DIR> <INCLUDES> /fo <OBJECT> <OBJECT>.pp")
         if(CMAKE_GENERATOR STREQUAL "Ninja")
           set(CMAKE_NINJA_CMCLDEPS_RC 0)
           set(CMAKE_NINJA_DEP_TYPE_RC gcc)
diff --git a/Modules/Platform/Windows-GNU.cmake b/Modules/Platform/Windows-GNU.cmake
index 38a8cf4..a2e3811 100644
--- a/Modules/Platform/Windows-GNU.cmake
+++ b/Modules/Platform/Windows-GNU.cmake
@@ -47,16 +47,12 @@
   set(__WINDOWS_GNU_LD_RESPONSE 0)
 endif()
 
-if(NOT CMAKE_GENERATOR_RC AND CMAKE_GENERATOR MATCHES "Unix Makefiles")
-  set(CMAKE_GENERATOR_RC windres)
-endif()
-
 macro(__windows_compiler_gnu lang)
 
   if(MSYS OR MINGW)
     # Create archiving rules to support large object file lists for static libraries.
     set(CMAKE_${lang}_ARCHIVE_CREATE "<CMAKE_AR> qc <TARGET> <LINK_FLAGS> <OBJECTS>")
-    set(CMAKE_${lang}_ARCHIVE_APPEND "<CMAKE_AR> q  <TARGET> <LINK_FLAGS> <OBJECTS>")
+    set(CMAKE_${lang}_ARCHIVE_APPEND "<CMAKE_AR> q <TARGET> <LINK_FLAGS> <OBJECTS>")
     set(CMAKE_${lang}_ARCHIVE_FINISH "<CMAKE_RANLIB> <TARGET>")
 
     # Initialize C link type selection flags.  These flags are used when
@@ -108,7 +104,7 @@
   set(CMAKE_${lang}_CREATE_SHARED_LIBRARY
     "<CMAKE_${lang}_COMPILER> <CMAKE_SHARED_LIBRARY_${lang}_FLAGS> <LANGUAGE_COMPILE_FLAGS> <LINK_FLAGS> <CMAKE_SHARED_LIBRARY_CREATE_${lang}_FLAGS> -o <TARGET> -Wl,--out-implib,<TARGET_IMPLIB> ${CMAKE_GNULD_IMAGE_VERSION} <OBJECTS> <LINK_LIBRARIES>")
   set(CMAKE_${lang}_LINK_EXECUTABLE
-    "<CMAKE_${lang}_COMPILER> <FLAGS> <CMAKE_${lang}_LINK_FLAGS> <LINK_FLAGS> <OBJECTS>  -o <TARGET> -Wl,--out-implib,<TARGET_IMPLIB> ${CMAKE_GNULD_IMAGE_VERSION} <LINK_LIBRARIES>")
+    "<CMAKE_${lang}_COMPILER> <FLAGS> <CMAKE_${lang}_LINK_FLAGS> <LINK_FLAGS> <OBJECTS> -o <TARGET> -Wl,--out-implib,<TARGET_IMPLIB> ${CMAKE_GNULD_IMAGE_VERSION} <LINK_LIBRARIES>")
 
   list(APPEND CMAKE_${lang}_ABI_FILES "Platform/Windows-GNU-${lang}-ABI")
 
@@ -132,7 +128,7 @@
   endif()
 
   if(NOT CMAKE_RC_COMPILER_INIT AND NOT CMAKE_GENERATOR_RC)
-    set(CMAKE_RC_COMPILER_INIT windres)
+    set(CMAKE_RC_COMPILER_INIT ${_CMAKE_TOOLCHAIN_PREFIX}windres)
   endif()
 
   enable_language(RC)
diff --git a/Modules/Platform/Windows-Intel.cmake b/Modules/Platform/Windows-Intel.cmake
index 96b1760..5d8f7fc 100644
--- a/Modules/Platform/Windows-Intel.cmake
+++ b/Modules/Platform/Windows-Intel.cmake
@@ -11,7 +11,7 @@
 include(Platform/Windows-MSVC)
 macro(__windows_compiler_intel lang)
   __windows_compiler_msvc(${lang})
-  string(REPLACE "<CMAKE_LINKER> /lib" "xilib" CMAKE_${lang}_CREATE_STATIC_LIBRARY "${CMAKE_${lang}_CREATE_STATIC_LIBRARY}")
+  string(REPLACE "<CMAKE_AR>" "xilib" CMAKE_${lang}_CREATE_STATIC_LIBRARY "${CMAKE_${lang}_CREATE_STATIC_LIBRARY}")
   foreach(rule CREATE_SHARED_LIBRARY CREATE_SHARED_MODULE LINK_EXECUTABLE)
     string(REPLACE "<CMAKE_LINKER>" "xilink" CMAKE_${lang}_${rule} "${CMAKE_${lang}_${rule}}")
   endforeach()
diff --git a/Modules/Platform/Windows-MSVC.cmake b/Modules/Platform/Windows-MSVC.cmake
index fb23058..173ef40 100644
--- a/Modules/Platform/Windows-MSVC.cmake
+++ b/Modules/Platform/Windows-MSVC.cmake
@@ -316,7 +316,7 @@
     "${_CMAKE_VS_LINK_DLL}<CMAKE_LINKER> ${CMAKE_CL_NOLOGO} <OBJECTS> ${CMAKE_START_TEMP_FILE} /out:<TARGET> /implib:<TARGET_IMPLIB> /pdb:<TARGET_PDB> /dll /version:<TARGET_VERSION_MAJOR>.<TARGET_VERSION_MINOR>${_PLATFORM_LINK_FLAGS} <LINK_FLAGS> <LINK_LIBRARIES> ${CMAKE_END_TEMP_FILE}")
 
   set(CMAKE_${lang}_CREATE_SHARED_MODULE ${CMAKE_${lang}_CREATE_SHARED_LIBRARY})
-  set(CMAKE_${lang}_CREATE_STATIC_LIBRARY  "<CMAKE_LINKER> /lib ${CMAKE_CL_NOLOGO} <LINK_FLAGS> /out:<TARGET> <OBJECTS> ")
+  set(CMAKE_${lang}_CREATE_STATIC_LIBRARY  "<CMAKE_AR> ${CMAKE_CL_NOLOGO} <LINK_FLAGS> /out:<TARGET> <OBJECTS> ")
 
   set(CMAKE_${lang}_COMPILE_OBJECT
     "<CMAKE_${lang}_COMPILER> ${CMAKE_START_TEMP_FILE} ${CMAKE_CL_NOLOGO}${_COMPILE_${lang}} <DEFINES> <INCLUDES> <FLAGS> /Fo<OBJECT> /Fd<TARGET_COMPILE_PDB>${_FS_${lang}} -c <SOURCE>${CMAKE_END_TEMP_FILE}")
@@ -333,6 +333,14 @@
   set(CMAKE_LINK_PCH ON)
   if (CMAKE_${lang}_COMPILER_ID STREQUAL "Clang")
     set(CMAKE_PCH_PROLOGUE "#pragma clang system_header")
+
+    # macOS paths usually start with /Users/*. Unfortunately, clang-cl interprets
+    # paths starting with /U as macro undefines, so we need to put a -- before the
+    # input file path to force it to be treated as a path.
+    string(REPLACE "-c <SOURCE>" "-c -- <SOURCE>" CMAKE_${lang}_COMPILE_OBJECT "${CMAKE_${lang}_COMPILE_OBJECT}")
+    string(REPLACE "-c <SOURCE>" "-c -- <SOURCE>" CMAKE_${lang}_CREATE_PREPROCESSED_SOURCE "${CMAKE_${lang}_COMPILE_OBJECT}")
+    string(REPLACE "-c <SOURCE>" "-c -- <SOURCE>" CMAKE_${lang}_CREATE_ASSEMBLY_SOURCE "${CMAKE_${lang}_COMPILE_OBJECT}")
+
   elseif(MSVC_VERSION GREATER_EQUAL 1913)
     # At least MSVC toolet 14.13 from VS 2017 15.6
     set(CMAKE_PCH_PROLOGUE "#pragma system_header")
@@ -356,6 +364,11 @@
     set(_CMAKE_${lang}_IPO_SUPPORTED_BY_CMAKE YES)
     set(_CMAKE_${lang}_IPO_MAY_BE_SUPPORTED_BY_COMPILER YES)
 
+    if(CMAKE_${lang}_COMPILER_VERSION VERSION_LESS 3.4.0)
+      set(CMAKE_${lang}_COMPILE_OPTIONS_TARGET "-target ")
+    else()
+      set(CMAKE_${lang}_COMPILE_OPTIONS_TARGET "--target=")
+    endif()
     # '-flto=thin' available since Clang 3.9 and Xcode 8
     # * http://clang.llvm.org/docs/ThinLTO.html#clang-llvm
     # * https://trac.macports.org/wiki/XcodeVersionInfo
diff --git a/Modules/Platform/Windows-NVIDIA-CUDA.cmake b/Modules/Platform/Windows-NVIDIA-CUDA.cmake
index 98cd5ef..a88f4bc 100644
--- a/Modules/Platform/Windows-NVIDIA-CUDA.cmake
+++ b/Modules/Platform/Windows-NVIDIA-CUDA.cmake
@@ -1,11 +1,11 @@
 include(Platform/Windows-MSVC)
 
 set(CMAKE_CUDA_COMPILE_PTX_COMPILATION
-  "<CMAKE_CUDA_COMPILER> ${_CMAKE_CUDA_EXTRA_FLAGS} <DEFINES> <INCLUDES> <FLAGS> -x cu -ptx <SOURCE> -o <OBJECT> -Xcompiler=-Fd<TARGET_COMPILE_PDB>,-FS")
+  "<CMAKE_CUDA_COMPILER> ${_CMAKE_CUDA_EXTRA_FLAGS} <DEFINES> <INCLUDES> <FLAGS> ${_CMAKE_COMPILE_AS_CUDA_FLAG} -ptx <SOURCE> -o <OBJECT> -Xcompiler=-Fd<TARGET_COMPILE_PDB>,-FS")
 set(CMAKE_CUDA_COMPILE_SEPARABLE_COMPILATION
-  "<CMAKE_CUDA_COMPILER> ${_CMAKE_CUDA_EXTRA_FLAGS} <DEFINES> <INCLUDES> <FLAGS> -x cu -dc <SOURCE> -o <OBJECT> -Xcompiler=-Fd<TARGET_COMPILE_PDB>,-FS")
+  "<CMAKE_CUDA_COMPILER> ${_CMAKE_CUDA_EXTRA_FLAGS} <DEFINES> <INCLUDES> <FLAGS> ${_CMAKE_COMPILE_AS_CUDA_FLAG} -dc <SOURCE> -o <OBJECT> -Xcompiler=-Fd<TARGET_COMPILE_PDB>,-FS")
 set(CMAKE_CUDA_COMPILE_WHOLE_COMPILATION
-  "<CMAKE_CUDA_COMPILER> ${_CMAKE_CUDA_EXTRA_FLAGS} <DEFINES> <INCLUDES> <FLAGS> -x cu -c <SOURCE> -o <OBJECT> -Xcompiler=-Fd<TARGET_COMPILE_PDB>,-FS")
+  "<CMAKE_CUDA_COMPILER> ${_CMAKE_CUDA_EXTRA_FLAGS} <DEFINES> <INCLUDES> <FLAGS> ${_CMAKE_COMPILE_AS_CUDA_FLAG} -c <SOURCE> -o <OBJECT> -Xcompiler=-Fd<TARGET_COMPILE_PDB>,-FS")
 
 set(__IMPLICT_LINKS )
 foreach(dir ${CMAKE_CUDA_HOST_IMPLICIT_LINK_DIRECTORIES})
@@ -23,7 +23,7 @@
   "${_CMAKE_VS_LINK_DLL}<CMAKE_LINKER> ${CMAKE_CL_NOLOGO} <OBJECTS> ${CMAKE_START_TEMP_FILE} /out:<TARGET> /implib:<TARGET_IMPLIB> /pdb:<TARGET_PDB> /dll /version:<TARGET_VERSION_MAJOR>.<TARGET_VERSION_MINOR>${_PLATFORM_LINK_FLAGS} <LINK_FLAGS> <LINK_LIBRARIES>${__IMPLICT_LINKS} ${CMAKE_END_TEMP_FILE}")
 
 set(CMAKE_CUDA_CREATE_SHARED_MODULE ${CMAKE_CUDA_CREATE_SHARED_LIBRARY})
-set(CMAKE_CUDA_CREATE_STATIC_LIBRARY  "<CMAKE_LINKER> /lib ${CMAKE_CL_NOLOGO} <LINK_FLAGS> /out:<TARGET> <OBJECTS> ")
+set(CMAKE_CUDA_CREATE_STATIC_LIBRARY  "<CMAKE_AR> ${CMAKE_CL_NOLOGO} <LINK_FLAGS> /out:<TARGET> <OBJECTS> ")
 set(CMAKE_CUDA_LINKER_SUPPORTS_PDB ON)
 set(CMAKE_CUDA_LINK_EXECUTABLE
   "${_CMAKE_VS_LINK_EXE}<CMAKE_LINKER> ${CMAKE_CL_NOLOGO} <OBJECTS> ${CMAKE_START_TEMP_FILE} /out:<TARGET> /implib:<TARGET_IMPLIB> /pdb:<TARGET_PDB> /version:<TARGET_VERSION_MAJOR>.<TARGET_VERSION_MINOR>${_PLATFORM_LINK_FLAGS} <LINK_FLAGS> <LINK_LIBRARIES>${__IMPLICT_LINKS} ${CMAKE_END_TEMP_FILE}")
@@ -46,9 +46,9 @@
 unset(__IMPLICT_DLINK_DIRS)
 
 set(CMAKE_CUDA_DEVICE_LINK_LIBRARY
-  "<CMAKE_CUDA_COMPILER> ${_CMAKE_CUDA_EXTRA_FLAGS} <LANGUAGE_COMPILE_FLAGS> ${_CMAKE_CUDA_EXTRA_DEVICE_LINK_FLAGS} -shared -dlink <OBJECTS> -o <TARGET> <LINK_LIBRARIES> -Xcompiler=-Fd<TARGET_COMPILE_PDB>,-FS${__IMPLICT_DLINK_FLAGS}")
+  "<CMAKE_CUDA_COMPILER> ${_CMAKE_CUDA_EXTRA_FLAGS} <LANGUAGE_COMPILE_FLAGS> <LINK_FLAGS> ${_CMAKE_CUDA_EXTRA_DEVICE_LINK_FLAGS} -shared -dlink <OBJECTS> -o <TARGET> <LINK_LIBRARIES> -Xcompiler=-Fd<TARGET_COMPILE_PDB>,-FS${__IMPLICT_DLINK_FLAGS}")
 set(CMAKE_CUDA_DEVICE_LINK_EXECUTABLE
-  "<CMAKE_CUDA_COMPILER>  ${_CMAKE_CUDA_EXTRA_FLAGS} <FLAGS> ${_CMAKE_CUDA_EXTRA_DEVICE_LINK_FLAGS} -shared -dlink <OBJECTS> -o <TARGET> <LINK_LIBRARIES> -Xcompiler=-Fd<TARGET_COMPILE_PDB>,-FS${__IMPLICT_DLINK_FLAGS}")
+  "<CMAKE_CUDA_COMPILER> ${_CMAKE_CUDA_EXTRA_FLAGS} <LANGUAGE_COMPILE_FLAGS> <LINK_FLAGS> ${_CMAKE_CUDA_EXTRA_DEVICE_LINK_FLAGS} -shared -dlink <OBJECTS> -o <TARGET> <LINK_LIBRARIES> -Xcompiler=-Fd<TARGET_COMPILE_PDB>,-FS${__IMPLICT_DLINK_FLAGS}")
 unset(__IMPLICT_DLINK_FLAGS)
 
 string(REPLACE "/D" "-D" _PLATFORM_DEFINES_CUDA "${_PLATFORM_DEFINES}${_PLATFORM_DEFINES_CXX}")
@@ -73,6 +73,10 @@
 set(CMAKE_CUDA_RUNTIME_LIBRARY_LINK_OPTIONS_SHARED  "cudadevrt;cudart")
 set(CMAKE_CUDA_RUNTIME_LIBRARY_LINK_OPTIONS_NONE    "")
 
+if(UNIX)
+  list(APPEND CMAKE_CUDA_RUNTIME_LIBRARY_LINK_OPTIONS_STATIC "rt" "pthread" "dl")
+endif()
+
 string(APPEND CMAKE_CUDA_FLAGS_INIT " ${PLATFORM_DEFINES_CUDA} -D_WINDOWS -Xcompiler=\"${_W3}${_FLAGS_CXX}\"")
 string(APPEND CMAKE_CUDA_FLAGS_DEBUG_INIT " -Xcompiler=\"${_MDd}-Zi -Ob0 -Od ${_RTC1}\"")
 string(APPEND CMAKE_CUDA_FLAGS_RELEASE_INIT " -Xcompiler=\"${_MD}-O2 -Ob2\" -DNDEBUG")
diff --git a/Modules/Platform/Windows-OpenWatcom.cmake b/Modules/Platform/Windows-OpenWatcom.cmake
index 76cd28b..70055da 100644
--- a/Modules/Platform/Windows-OpenWatcom.cmake
+++ b/Modules/Platform/Windows-OpenWatcom.cmake
@@ -1,129 +1,32 @@
 # Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
 # file Copyright.txt or https://cmake.org/licensing for details.
 
-
 # This module is shared by multiple languages; use include blocker.
-if(__WINDOWS_OPENWATCOM)
-  return()
-endif()
-set(__WINDOWS_OPENWATCOM 1)
+include_guard()
 
-set(CMAKE_LIBRARY_PATH_FLAG "libpath ")
-set(CMAKE_LINK_LIBRARY_FLAG "library ")
-set(CMAKE_LINK_LIBRARY_FILE_FLAG "library ")
+set(CMAKE_BUILD_TYPE_INIT Debug)
 
-if(CMAKE_VERBOSE_MAKEFILE)
-  set(CMAKE_WCL_QUIET)
-  set(CMAKE_WLINK_QUIET)
-  set(CMAKE_LIB_QUIET)
-else()
-  set(CMAKE_WCL_QUIET "-zq")
-  set(CMAKE_WLINK_QUIET "option quiet")
-  set(CMAKE_LIB_QUIET "-q")
-endif()
-
-string(APPEND CMAKE_EXE_LINKER_FLAGS_INIT " ")
 set(CMAKE_CREATE_WIN32_EXE "system nt_win" )
 set(CMAKE_CREATE_CONSOLE_EXE "system nt" )
 string(APPEND CMAKE_SHARED_LINKER_FLAGS_INIT " system nt_dll")
 string(APPEND CMAKE_MODULE_LINKER_FLAGS_INIT " system nt_dll")
-foreach(type SHARED MODULE EXE)
-  string(APPEND CMAKE_${type}_LINKER_FLAGS_DEBUG_INIT " debug all opt map")
-  string(APPEND CMAKE_${type}_LINKER_FLAGS_RELWITHDEBINFO_INIT " debug all opt map")
-endforeach()
 
 set(CMAKE_C_COMPILE_OPTIONS_DLL "-bd") # Note: This variable is a ';' separated list
 set(CMAKE_SHARED_LIBRARY_C_FLAGS "-bd") # ... while this is a space separated string.
 
 set(CMAKE_RC_COMPILER "rc" )
 
-set(CMAKE_BUILD_TYPE_INIT Debug)
-
 # single/multi-threaded                 /-bm
 # static/DLL run-time libraries         /-br
 # default is setup for multi-threaded + DLL run-time libraries
-string(APPEND CMAKE_C_FLAGS_INIT " -bt=nt -w3 -dWIN32 -br -bm")
-string(APPEND CMAKE_CXX_FLAGS_INIT " -bt=nt -xs -w3 -dWIN32 -br -bm")
-foreach(lang C CXX)
-  string(APPEND CMAKE_${lang}_FLAGS_DEBUG_INIT " -d2")
-  string(APPEND CMAKE_${lang}_FLAGS_MINSIZEREL_INIT " -s -os -d0 -dNDEBUG")
-  string(APPEND CMAKE_${lang}_FLAGS_RELEASE_INIT " -s -ot -d0 -dNDEBUG")
-  string(APPEND CMAKE_${lang}_FLAGS_RELWITHDEBINFO_INIT " -s -ot -d1 -dNDEBUG")
-endforeach()
+string(APPEND CMAKE_C_FLAGS_INIT " -bt=nt -dWIN32 -br -bm")
+string(APPEND CMAKE_CXX_FLAGS_INIT " -bt=nt -xs -dWIN32 -br -bm")
 
-foreach(type CREATE_SHARED_LIBRARY CREATE_SHARED_MODULE LINK_EXECUTABLE)
-  set(CMAKE_C_${type}_USE_WATCOM_QUOTE 1)
-  set(CMAKE_CXX_${type}_USE_WATCOM_QUOTE 1)
-endforeach()
-
-set(CMAKE_C_CREATE_IMPORT_LIBRARY
-  "wlib -c -q -n -b <TARGET_IMPLIB> +<TARGET_QUOTED>")
-set(CMAKE_CXX_CREATE_IMPORT_LIBRARY ${CMAKE_C_CREATE_IMPORT_LIBRARY})
-
-set(CMAKE_C_LINK_EXECUTABLE
-    "wlink ${CMAKE_START_TEMP_FILE} ${CMAKE_WLINK_QUIET} name <TARGET> <LINK_FLAGS> file {<OBJECTS>} <LINK_LIBRARIES> ${CMAKE_END_TEMP_FILE}")
-
-
-set(CMAKE_CXX_LINK_EXECUTABLE ${CMAKE_C_LINK_EXECUTABLE})
-
-# compile a C++ file into an object file
-set(CMAKE_CXX_COMPILE_OBJECT
-    "<CMAKE_CXX_COMPILER> ${CMAKE_START_TEMP_FILE} ${CMAKE_WCL_QUIET} -d+ <DEFINES> <INCLUDES> <FLAGS> -fo<OBJECT> -c -cc++ <SOURCE>${CMAKE_END_TEMP_FILE}")
-
-# compile a C file into an object file
-set(CMAKE_C_COMPILE_OBJECT
-    "<CMAKE_C_COMPILER> ${CMAKE_START_TEMP_FILE} ${CMAKE_WCL_QUIET} -d+ <DEFINES> <INCLUDES> <FLAGS> -fo<OBJECT> -c -cc <SOURCE>${CMAKE_END_TEMP_FILE}")
-
-# preprocess a C source file
-set(CMAKE_C_CREATE_PREPROCESSED_SOURCE
-    "<CMAKE_C_COMPILER> ${CMAKE_START_TEMP_FILE} ${CMAKE_WCL_QUIET} -d+ <DEFINES> <INCLUDES> <FLAGS> -fo<PREPROCESSED_SOURCE> -pl -cc <SOURCE>${CMAKE_END_TEMP_FILE}")
-
-# preprocess a C++ source file
-set(CMAKE_CXX_CREATE_PREPROCESSED_SOURCE
-    "<CMAKE_CXX_COMPILER> ${CMAKE_START_TEMP_FILE} ${CMAKE_WCL_QUIET} -d+ <DEFINES> <INCLUDES> <FLAGS> -fo<PREPROCESSED_SOURCE> -pl -cc++ <SOURCE>${CMAKE_END_TEMP_FILE}")
-
-set(CMAKE_CXX_CREATE_SHARED_LIBRARY
- "wlink ${CMAKE_START_TEMP_FILE} ${CMAKE_WLINK_QUIET} name <TARGET> <LINK_FLAGS> option implib=<TARGET_IMPLIB> file {<OBJECTS>} <LINK_LIBRARIES> ${CMAKE_END_TEMP_FILE}")
-string(REPLACE " option implib=<TARGET_IMPLIB>" ""
-  CMAKE_CXX_CREATE_SHARED_MODULE "${CMAKE_CXX_CREATE_SHARED_LIBRARY}")
-
-# create a C shared library
-set(CMAKE_C_CREATE_SHARED_LIBRARY ${CMAKE_CXX_CREATE_SHARED_LIBRARY})
-
-# create a C shared module
-set(CMAKE_C_CREATE_SHARED_MODULE ${CMAKE_CXX_CREATE_SHARED_MODULE})
-
-# create a C++ static library
-set(CMAKE_CXX_CREATE_STATIC_LIBRARY  "wlib ${CMAKE_LIB_QUIET} -c -n -b <TARGET_QUOTED> <LINK_FLAGS> <OBJECTS> ")
-
-# create a C static library
-set(CMAKE_C_CREATE_STATIC_LIBRARY ${CMAKE_CXX_CREATE_STATIC_LIBRARY})
-
-if(NOT _CMAKE_WATCOM_VERSION)
-  set(_CMAKE_WATCOM_VERSION 1)
-  if(CMAKE_C_COMPILER_VERSION)
-    set(_compiler_version ${CMAKE_C_COMPILER_VERSION})
-    set(_compiler_id ${CMAKE_C_COMPILER_ID})
-  else()
-    set(_compiler_version ${CMAKE_CXX_COMPILER_VERSION})
-    set(_compiler_id ${CMAKE_CXX_COMPILER_ID})
+if(CMAKE_CROSSCOMPILING)
+  if(NOT CMAKE_C_STANDARD_INCLUDE_DIRECTORIES)
+    set(CMAKE_C_STANDARD_INCLUDE_DIRECTORIES $ENV{WATCOM}/h $ENV{WATCOM}/h/nt)
   endif()
-  set(WATCOM16)
-  set(WATCOM17)
-  set(WATCOM18)
-  set(WATCOM19)
-  if("${_compiler_id}" STREQUAL "OpenWatcom")
-    if("${_compiler_version}" VERSION_LESS 1.7)
-      set(WATCOM16 1)
-    endif()
-    if("${_compiler_version}" VERSION_EQUAL 1.7)
-      set(WATCOM17 1)
-    endif()
-    if("${_compiler_version}" VERSION_EQUAL 1.8)
-      set(WATCOM18 1)
-    endif()
-    if("${_compiler_version}" VERSION_EQUAL 1.9)
-      set(WATCOM19 1)
-    endif()
+  if(NOT CMAKE_CXX_STANDARD_INCLUDE_DIRECTORIES)
+    set(CMAKE_CXX_STANDARD_INCLUDE_DIRECTORIES $ENV{WATCOM}/h $ENV{WATCOM}/h/nt)
   endif()
 endif()
diff --git a/Modules/Platform/Windows-df.cmake b/Modules/Platform/Windows-df.cmake
index f948914..8b824bc 100644
--- a/Modules/Platform/Windows-df.cmake
+++ b/Modules/Platform/Windows-df.cmake
@@ -13,7 +13,7 @@
 set(CMAKE_Fortran_MODDIR_FLAG "-module:")
 
 set(CMAKE_Fortran_CREATE_SHARED_LIBRARY
- "link ${CMAKE_CL_NOLOGO} ${CMAKE_START_TEMP_FILE}  /out:<TARGET> /dll  <LINK_FLAGS> <OBJECTS> <LINK_LIBRARIES> ${CMAKE_END_TEMP_FILE}")
+ "link ${CMAKE_CL_NOLOGO} ${CMAKE_START_TEMP_FILE} /out:<TARGET> /dll <LINK_FLAGS> <OBJECTS> <LINK_LIBRARIES> ${CMAKE_END_TEMP_FILE}")
 
 set(CMAKE_Fortran_CREATE_SHARED_MODULE ${CMAKE_Fortran_CREATE_SHARED_LIBRARY})
 
@@ -22,7 +22,7 @@
 
 # compile a C++ file into an object file
 set(CMAKE_Fortran_COMPILE_OBJECT
-    "<CMAKE_Fortran_COMPILER>  ${CMAKE_START_TEMP_FILE} ${CMAKE_CL_NOLOGO} /object:<OBJECT> <FLAGS> /compile_only <SOURCE>${CMAKE_END_TEMP_FILE}")
+    "<CMAKE_Fortran_COMPILER> ${CMAKE_START_TEMP_FILE} ${CMAKE_CL_NOLOGO} /object:<OBJECT> <FLAGS> /compile_only <SOURCE>${CMAKE_END_TEMP_FILE}")
 
 set(CMAKE_Fortran_LINK_EXECUTABLE
     "<CMAKE_Fortran_COMPILER> ${CMAKE_CL_NOLOGO} ${CMAKE_START_TEMP_FILE} <FLAGS> /exe:<TARGET> <OBJECTS> /link <CMAKE_Fortran_LINK_FLAGS> <LINK_FLAGS> <LINK_LIBRARIES>${CMAKE_END_TEMP_FILE}")
diff --git a/Modules/Platform/WindowsPaths.cmake b/Modules/Platform/WindowsPaths.cmake
index 71cc609..b9e2f17 100644
--- a/Modules/Platform/WindowsPaths.cmake
+++ b/Modules/Platform/WindowsPaths.cmake
@@ -24,6 +24,10 @@
 #   ENV{ProgramFiles(x86)} = [C:\Program Files (x86)]
 #   ENV{ProgramFiles} = [C:\Program Files (x86)]
 #   ENV{ProgramW6432} = [C:\Program Files]
+#
+# Reminder when adding new locations computed from environment variables
+# please make sure to keep Help/variable/CMAKE_SYSTEM_PREFIX_PATH.rst
+# synchronized
 set(_programfiles "")
 foreach(v "ProgramW6432" "ProgramFiles" "ProgramFiles(x86)")
   if(DEFINED "ENV{${v}}")
diff --git a/Modules/Platform/eCos.cmake b/Modules/Platform/eCos.cmake
index e1279ef..25db028 100644
--- a/Modules/Platform/eCos.cmake
+++ b/Modules/Platform/eCos.cmake
@@ -52,8 +52,8 @@
 add_definitions(-D__ECOS__=1 -D__ECOS=1)
 
 # special link commands for eCos executables
-set(CMAKE_CXX_LINK_EXECUTABLE  "<CMAKE_CXX_COMPILER> <FLAGS> <CMAKE_CXX_LINK_FLAGS> <LINK_FLAGS> <OBJECTS> -o <TARGET> -nostdlib -nostartfiles -L${ECOS_LIBTARGET_DIRECTORY} -Ttarget.ld  <LINK_LIBRARIES>")
-set(CMAKE_C_LINK_EXECUTABLE    "<CMAKE_C_COMPILER>   <FLAGS> <CMAKE_C_LINK_FLAGS>   <LINK_FLAGS> <OBJECTS> -o <TARGET> -nostdlib -nostartfiles -L${ECOS_LIBTARGET_DIRECTORY} -Ttarget.ld  <LINK_LIBRARIES>")
+set(CMAKE_CXX_LINK_EXECUTABLE  "<CMAKE_CXX_COMPILER> <FLAGS> <CMAKE_CXX_LINK_FLAGS> <LINK_FLAGS> <OBJECTS> -o <TARGET> -nostdlib -nostartfiles -L${ECOS_LIBTARGET_DIRECTORY} -Ttarget.ld <LINK_LIBRARIES>")
+set(CMAKE_C_LINK_EXECUTABLE    "<CMAKE_C_COMPILER> <FLAGS> <CMAKE_C_LINK_FLAGS> <LINK_FLAGS> <OBJECTS> -o <TARGET> -nostdlib -nostartfiles -L${ECOS_LIBTARGET_DIRECTORY} -Ttarget.ld <LINK_LIBRARIES>")
 
 # eCos doesn't support shared libs
 set_property(GLOBAL PROPERTY TARGET_SUPPORTS_SHARED_LIBS FALSE)
diff --git a/Modules/Platform/gas.cmake b/Modules/Platform/gas.cmake
index 7c659f2..8484076 100644
--- a/Modules/Platform/gas.cmake
+++ b/Modules/Platform/gas.cmake
@@ -11,7 +11,7 @@
       "<CMAKE_RANLIB> <TARGET> ")
 
 set(CMAKE_ASM${ASM_DIALECT}_LINK_EXECUTABLE
-    "<CMAKE_LINKER> <FLAGS> <CMAKE_ASM${ASM_DIALECT}_LINK_FLAGS> <LINK_FLAGS> <OBJECTS>  -o <TARGET> <LINK_LIBRARIES>")
+    "<CMAKE_LINKER> <FLAGS> <CMAKE_ASM${ASM_DIALECT}_LINK_FLAGS> <LINK_FLAGS> <OBJECTS> -o <TARGET> <LINK_LIBRARIES>")
 
 # to be done
 set(CMAKE_ASM${ASM_DIALECT}_CREATE_SHARED_LIBRARY)
diff --git a/Modules/Squish4RunTestCase.bat b/Modules/Squish4RunTestCase.bat
index ad1cc8c..fe303b8 100755
--- a/Modules/Squish4RunTestCase.bat
+++ b/Modules/Squish4RunTestCase.bat
@@ -4,7 +4,6 @@
 set TESTCASE=%4
 set AUT=%5
 set AUTDIR=%6
-set SETTINGSGROUP=%7
 
 %SQUISHSERVER% --stop
 
@@ -12,9 +11,9 @@
 %SQUISHSERVER% --config addAUT "%AUT%" "%AUTDIR%"
 
 echo "Starting the squish server... %SQUISHSERVER%"
-start /B %SQUISHSERVER%
+start /B "Squish Server" %SQUISHSERVER%
 
-echo "Running the test case...%SQUISHRUNNER% --testsuite %TESTSUITE% --testcase %TESTCASE%"
+echo "Running the test case... %SQUISHRUNNER% --testsuite %TESTSUITE% --testcase %TESTCASE%"
 %SQUISHRUNNER% --testsuite "%TESTSUITE%" --testcase "%TESTCASE%"
 set returnValue=%ERRORLEVEL%
 
diff --git a/Modules/Squish4RunTestCase.sh b/Modules/Squish4RunTestCase.sh
index 39a3907..4d1e382 100755
--- a/Modules/Squish4RunTestCase.sh
+++ b/Modules/Squish4RunTestCase.sh
@@ -6,20 +6,19 @@
 TESTCASE=$4
 AUT=$5
 AUTDIR=$6
-SETTINGSGROUP=$7
 
 $SQUISHSERVER --stop > /dev/null 2>&1
 
-echo "Adding AUT... $SQUISHSERVER --settingsGroup $SETTINGSGROUP --config addAUT $AUT $AUTDIR"
-$SQUISHSERVER --settingsGroup "$SETTINGSGROUP" --config addAUT "$AUT" "$AUTDIR" || exit 255
+echo "Adding AUT... $SQUISHSERVER --config addAUT $AUT $AUTDIR"
+$SQUISHSERVER --config addAUT "$AUT" "$AUTDIR" || exit 255
 # sleep 1
 
 echo "Starting the squish server... $SQUISHSERVER --daemon"
 $SQUISHSERVER --daemon || exit 255
 # sleep 2
 
-echo "Running the test case...$SQUISHRUNNER --settingsGroup $SETTINGSGROUP --testsuite $TESTSUITE --testcase $TESTCASE"
-$SQUISHRUNNER --settingsGroup "$SETTINGSGROUP" --testsuite "$TESTSUITE" --testcase "$TESTCASE"
+echo "Running the test case... $SQUISHRUNNER --testsuite $TESTSUITE --testcase $TESTCASE"
+$SQUISHRUNNER --testsuite "$TESTSUITE" --testcase "$TESTCASE"
 returnValue=$?
 
 echo "Stopping the squish server... $SQUISHSERVER --stop"
diff --git a/Modules/SquishTestScript.cmake b/Modules/SquishTestScript.cmake
index 2a80be5..b0cb4af 100644
--- a/Modules/SquishTestScript.cmake
+++ b/Modules/SquishTestScript.cmake
@@ -31,7 +31,6 @@
 message(STATUS "squish_wrapper='${squish_wrapper}'")
 message(STATUS "squish_env_vars='${squish_env_vars}'")
 message(STATUS "squish_module_dir='${squish_module_dir}'")
-message(STATUS "squish_settingsgroup='${squish_settingsgroup}'")
 message(STATUS "squish_pre_command='${squish_pre_command}'")
 message(STATUS "squish_post_command='${squish_post_command}'")
 
@@ -57,10 +56,10 @@
 # run the test
 if("${squish_version}" STREQUAL "4")
   if (WIN32)
-    execute_process(COMMAND ${squish_module_dir}/Squish4RunTestCase.bat ${squish_server_executable} ${squish_client_executable} ${squish_test_suite} ${squish_test_case} ${squish_aut} ${squish_aut_dir} ${squish_settingsgroup}
+    execute_process(COMMAND ${squish_module_dir}/Squish4RunTestCase.bat ${squish_server_executable} ${squish_client_executable} ${squish_test_suite} ${squish_test_case} ${squish_aut} ${squish_aut_dir}
                     RESULT_VARIABLE test_rv )
   elseif(UNIX)
-    execute_process(COMMAND ${squish_module_dir}/Squish4RunTestCase.sh ${squish_server_executable} ${squish_client_executable} ${squish_test_suite} ${squish_test_case} ${squish_aut} ${squish_aut_dir} ${squish_settingsgroup}
+    execute_process(COMMAND ${squish_module_dir}/Squish4RunTestCase.sh ${squish_server_executable} ${squish_client_executable} ${squish_test_suite} ${squish_test_case} ${squish_aut} ${squish_aut_dir}
                     RESULT_VARIABLE test_rv )
   endif ()
 
diff --git a/Modules/UseEcos.cmake b/Modules/UseEcos.cmake
index 60324b1..83c9b20 100644
--- a/Modules/UseEcos.cmake
+++ b/Modules/UseEcos.cmake
@@ -185,11 +185,11 @@
 # when using nmake makefiles, the custom buildtype suppresses the default cl.exe flags
 # and the rules for creating objects are adjusted for gcc
   set(CMAKE_BUILD_TYPE CUSTOM_ECOS_BUILD)
-  set(CMAKE_C_COMPILE_OBJECT     "<CMAKE_C_COMPILER>   <DEFINES> <INCLUDES> <FLAGS> -o <OBJECT> -c <SOURCE>")
+  set(CMAKE_C_COMPILE_OBJECT     "<CMAKE_C_COMPILER> <DEFINES> <INCLUDES> <FLAGS> -o <OBJECT> -c <SOURCE>")
   set(CMAKE_CXX_COMPILE_OBJECT   "<CMAKE_CXX_COMPILER> <DEFINES> <INCLUDES> <FLAGS> -o <OBJECT> -c <SOURCE>")
 # special link commands for ecos-executables
-  set(CMAKE_CXX_LINK_EXECUTABLE  "<CMAKE_CXX_COMPILER> <CMAKE_CXX_LINK_FLAGS> <OBJECTS>  -o <TARGET> ${_ecos_EXTRA_LIBS} -nostdlib  -nostartfiles -L${CMAKE_CURRENT_BINARY_DIR}/ecos/install/lib -Ttarget.ld ${ECOS_LD_MCPU}")
-  set(CMAKE_C_LINK_EXECUTABLE    "<CMAKE_C_COMPILER>   <CMAKE_C_LINK_FLAGS>   <OBJECTS>  -o <TARGET> ${_ecos_EXTRA_LIBS} -nostdlib  -nostartfiles -L${CMAKE_CURRENT_BINARY_DIR}/ecos/install/lib -Ttarget.ld ${ECOS_LD_MCPU}")
+  set(CMAKE_CXX_LINK_EXECUTABLE  "<CMAKE_CXX_COMPILER> <CMAKE_CXX_LINK_FLAGS> <OBJECTS> -o <TARGET> ${_ecos_EXTRA_LIBS} -nostdlib -nostartfiles -L${CMAKE_CURRENT_BINARY_DIR}/ecos/install/lib -Ttarget.ld ${ECOS_LD_MCPU}")
+  set(CMAKE_C_LINK_EXECUTABLE    "<CMAKE_C_COMPILER> <CMAKE_C_LINK_FLAGS> <OBJECTS> -o <TARGET> ${_ecos_EXTRA_LIBS} -nostdlib -nostartfiles -L${CMAKE_CURRENT_BINARY_DIR}/ecos/install/lib -Ttarget.ld ${ECOS_LD_MCPU}")
 # some strict compiler flags
   set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wstrict-prototypes")
   set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Woverloaded-virtual -fno-rtti -Wctor-dtor-privacy -fno-strict-aliasing -fno-exceptions")
diff --git a/Modules/UseJava.cmake b/Modules/UseJava.cmake
index b668b9e..db3fb95 100644
--- a/Modules/UseJava.cmake
+++ b/Modules/UseJava.cmake
@@ -377,7 +377,9 @@
         ARGS    ${src}
                 ${dest}
         DEPENDS ${src}
-        COMMENT ${comment})
+        COMMENT ${comment}
+        VERBATIM
+        )
 endfunction ()
 
 function(__java_lcat VAR)
@@ -597,7 +599,10 @@
             # Create the list of files to compile.
             set(_JAVA_SOURCES_FILE ${CMAKE_JAVA_CLASS_OUTPUT_PATH}/java_sources)
             string(REPLACE ";" "\"\n\"" _JAVA_COMPILE_STRING "\"${_JAVA_COMPILE_FILES}\"")
-            file(WRITE ${_JAVA_SOURCES_FILE} ${_JAVA_COMPILE_STRING})
+            set(CMAKE_CONFIGURABLE_FILE_CONTENT "${_JAVA_COMPILE_STRING}")
+            configure_file("${CMAKE_ROOT}/Modules/CMakeConfigurableFile.in"
+              "${_JAVA_SOURCES_FILE}" @ONLY)
+            unset(CMAKE_CONFIGURABLE_FILE_CONTENT)
             list (APPEND _JAVA_SOURCES_FILELISTS "@${_JAVA_SOURCES_FILE}")
         endif()
         if (_JAVA_COMPILE_FILELISTS)
@@ -610,6 +615,10 @@
         add_custom_command(
             # NOTE: this command generates an artificial dependency file
             OUTPUT ${CMAKE_JAVA_CLASS_OUTPUT_PATH}/java_compiled_${_TARGET_NAME}
+            COMMAND ${CMAKE_COMMAND}
+                -DCMAKE_JAVA_CLASS_OUTPUT_PATH=${CMAKE_JAVA_CLASS_OUTPUT_PATH}
+                -DCMAKE_JAR_CLASSES_PREFIX=${CMAKE_JAR_CLASSES_PREFIX}
+                -P ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/UseJava/ClearClassFiles.cmake
             COMMAND ${Java_JAVAC_EXECUTABLE}
                 ${CMAKE_JAVA_COMPILE_FLAGS}
                 -classpath "${CMAKE_JAVA_INCLUDE_PATH_FINAL}"
@@ -617,18 +626,20 @@
                 ${_GENERATE_NATIVE_HEADERS}
                 ${_JAVA_SOURCES_FILELISTS}
             COMMAND ${CMAKE_COMMAND} -E touch ${CMAKE_JAVA_CLASS_OUTPUT_PATH}/java_compiled_${_TARGET_NAME}
-            DEPENDS ${_JAVA_COMPILE_FILES} ${_JAVA_COMPILE_FILELISTS} ${_JAVA_COMPILE_DEPENDS}
+            DEPENDS ${_JAVA_COMPILE_FILES} ${_JAVA_COMPILE_FILELISTS} ${_JAVA_COMPILE_DEPENDS} ${_JAVA_SOURCES_FILE}
             WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
             COMMENT "Building Java objects for ${_TARGET_NAME}.jar"
+            VERBATIM
         )
         add_custom_command(
             OUTPUT ${CMAKE_JAVA_CLASS_OUTPUT_PATH}/java_class_filelist
             COMMAND ${CMAKE_COMMAND}
                 -DCMAKE_JAVA_CLASS_OUTPUT_PATH=${CMAKE_JAVA_CLASS_OUTPUT_PATH}
-                -DCMAKE_JAR_CLASSES_PREFIX="${CMAKE_JAR_CLASSES_PREFIX}"
+                -DCMAKE_JAR_CLASSES_PREFIX=${CMAKE_JAR_CLASSES_PREFIX}
                 -P ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/UseJavaClassFilelist.cmake
             DEPENDS ${CMAKE_JAVA_CLASS_OUTPUT_PATH}/java_compiled_${_TARGET_NAME}
             WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
+            VERBATIM
         )
     else ()
         # create an empty java_class_filelist
@@ -659,6 +670,7 @@
             DEPENDS ${_JAVA_RESOURCE_FILES} ${_JAVA_DEPENDS} ${CMAKE_JAVA_CLASS_OUTPUT_PATH}/java_class_filelist
             WORKING_DIRECTORY ${CMAKE_JAVA_CLASS_OUTPUT_PATH}
             COMMENT "Creating Java archive ${_JAVA_TARGET_OUTPUT_NAME}"
+            VERBATIM
         )
     else ()
         add_custom_command(
@@ -674,6 +686,7 @@
             WORKING_DIRECTORY ${CMAKE_JAVA_CLASS_OUTPUT_PATH}
             DEPENDS ${_JAVA_RESOURCE_FILES} ${_JAVA_DEPENDS} ${CMAKE_JAVA_CLASS_OUTPUT_PATH}/java_class_filelist
             COMMENT "Creating Java archive ${_JAVA_TARGET_OUTPUT_NAME}"
+            VERBATIM
         )
     endif ()
 
diff --git a/Modules/UseJava/ClearClassFiles.cmake b/Modules/UseJava/ClearClassFiles.cmake
new file mode 100644
index 0000000..f3115c6
--- /dev/null
+++ b/Modules/UseJava/ClearClassFiles.cmake
@@ -0,0 +1,17 @@
+# Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
+# file Copyright.txt or https://cmake.org/licensing for details.
+
+# This script deletes compiled Java class files.
+
+if(CMAKE_JAVA_CLASS_OUTPUT_PATH)
+  if(EXISTS "${CMAKE_JAVA_CLASS_OUTPUT_PATH}/java_class_filelist")
+    file(STRINGS "${CMAKE_JAVA_CLASS_OUTPUT_PATH}/java_class_filelist" classes)
+    list(TRANSFORM classes PREPEND "${CMAKE_JAVA_CLASS_OUTPUT_PATH}/")
+    if(classes)
+      file(REMOVE ${classes})
+      message(STATUS "Clean class files from previous build")
+    endif()
+  endif()
+else()
+  message(FATAL_ERROR "Can't find CMAKE_JAVA_CLASS_OUTPUT_PATH")
+endif()
diff --git a/Modules/UseSWIG.cmake b/Modules/UseSWIG.cmake
index 78522da..b75eb5e 100644
--- a/Modules/UseSWIG.cmake
+++ b/Modules/UseSWIG.cmake
@@ -41,6 +41,14 @@
     configuration-specific files generated by ``SWIG``. All build
     configurations must result in the same generated source file.
 
+  .. note::
+
+    For Make-based generators, ``swig_add_library`` does not track file
+    dependencies, so depending on the ``<name>_swig_compilation`` custom target
+    is required for targets which require the ``swig``-generated files to
+    exist. Other generators may depend on the source files that would be
+    generated by SWIG.
+
   ``TYPE``
     ``SHARED``, ``MODULE`` and ``STATIC`` have the same semantic as for the
     :command:`add_library` command. If ``USE_BUILD_SHARED_LIBS`` is specified,
@@ -75,7 +83,7 @@
   ``SOURCES``
     List of sources for the library. Files with extension ``.i`` will be
     identified as sources for the ``SWIG`` tool. Other files will be handled in
-    the standard way. This behavior can be overriden by specifying the variable
+    the standard way. This behavior can be overridden by specifying the variable
     ``SWIG_SOURCE_FILE_EXTENSIONS``.
 
   .. note::
@@ -341,6 +349,23 @@
     list(APPEND files "${extra_file}")
   endforeach()
 
+  if (language STREQUAL "FORTRAN" AND CMAKE_Fortran_COMPILER_LOADED)
+    # Process possible user-supplied extension in flags (obtained via parent
+    # scope variable) to determine the source file name.
+    list(FIND SWIG_COMPILATION_FLAGS "-fext" fext_idx)
+    if (fext_idx EQUAL -1)
+      # Default Fortran generated extension
+      set(fext "f90")
+    else()
+      # Get extension from user-provided flag
+      math(EXPR fext_idx "${fext_idx} + 1")
+      list(GET SWIG_COMPILATION_FLAGS "${fext_idx}" fext)
+    endif()
+    set(extra_file "${generatedpath}/${module_basename}.${fext}")
+    set_source_files_properties("${extra_file}" PROPERTIES LANGUAGE "Fortran")
+    list(APPEND files "${extra_file}")
+  endif()
+
   set (${outfiles} ${files} PARENT_SCOPE)
 endfunction()
 
@@ -415,6 +440,7 @@
   get_filename_component(swig_source_file_fullname "${infile}" ABSOLUTE)
 
   if (NOT SWIG_MODULE_${name}_NOPROXY)
+    set(SWIG_COMPILATION_FLAGS ${swig_source_file_flags})
     SWIG_GET_EXTRA_OUTPUT_FILES(${SWIG_MODULE_${name}_LANGUAGE}
       swig_extra_generated_files
       "${outdir}"
@@ -787,6 +813,8 @@
     if (APPLE)
       set_target_properties (${target_name} PROPERTIES SUFFIX ".dylib")
     endif ()
+  elseif (swig_lowercase_language STREQUAL "fortran")
+    # Do *not* override the target's library prefix
   else()
     # assume empty prefix because we expect the module to be dynamically loaded
     set_target_properties (${target_name} PROPERTIES PREFIX "")
diff --git a/Modules/UseSWIG/ManageSupportFiles.cmake b/Modules/UseSWIG/ManageSupportFiles.cmake
index 4a03900..6618fd5 100644
--- a/Modules/UseSWIG/ManageSupportFiles.cmake
+++ b/Modules/UseSWIG/ManageSupportFiles.cmake
@@ -4,7 +4,7 @@
 
 if (ACTION STREQUAL "CLEAN")
   # Collect current list of generated files
-  file (GLOB files LIST_DIRECTORIES FALSE RELATIVE "${SUPPORT_FILES_WORKING_DIRECTORY}" "${SUPPORT_FILES_WORKING_DIRECTORY}/*")
+  file (GLOB_RECURSE files LIST_DIRECTORIES TRUE RELATIVE "${SUPPORT_FILES_WORKING_DIRECTORY}" "${SUPPORT_FILES_WORKING_DIRECTORY}/*")
 
   if (files)
     # clean-up the output directory
@@ -22,7 +22,7 @@
 
 if (ACTION STREQUAL "COPY")
   # Collect current list of generated files
-  file (GLOB files LIST_DIRECTORIES FALSE "${SUPPORT_FILES_WORKING_DIRECTORY}/*")
+  file (GLOB files LIST_DIRECTORIES TRUE "${SUPPORT_FILES_WORKING_DIRECTORY}/*")
 
   if (files)
     # copy files to the output directory
diff --git a/Modules/WriteCompilerDetectionHeader.cmake b/Modules/WriteCompilerDetectionHeader.cmake
index 23d81b5..5100035 100644
--- a/Modules/WriteCompilerDetectionHeader.cmake
+++ b/Modules/WriteCompilerDetectionHeader.cmake
@@ -5,6 +5,8 @@
 WriteCompilerDetectionHeader
 ----------------------------
 
+.. versionadded:: 3.1
+
 This module provides the function ``write_compiler_detection_header()``.
 
 This function can be used to generate a file suitable for preprocessor
diff --git a/Modules/readme.txt b/Modules/readme.txt
index a629478..da78730 100644
--- a/Modules/readme.txt
+++ b/Modules/readme.txt
@@ -1,4 +1,4 @@
 See the "Find Modules" section of the cmake-developer(7) manual page.
 
 For more information about how to contribute modules to CMake, see this page:
-https://gitlab.kitware.com/cmake/community/wikis/doc/cmake/dev/Module-Maintainers
+https://gitlab.kitware.com/cmake/community/-/wikis/doc/cmake/dev/Module-Maintainers
diff --git a/README.rst b/README.rst
index 5020d39..64e2353 100644
--- a/README.rst
+++ b/README.rst
@@ -11,7 +11,7 @@
 
 .. _`CMake Home Page`: https://cmake.org
 .. _`CMake Documentation Page`: https://cmake.org/documentation
-.. _`CMake Community Wiki`: https://gitlab.kitware.com/cmake/community/wikis/home
+.. _`CMake Community Wiki`: https://gitlab.kitware.com/cmake/community/-/wikis/home
 
 CMake is maintained and supported by `Kitware`_ and developed in
 collaboration with a productive community of contributors.
@@ -122,7 +122,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://gitlab.kitware.com/cmake/cmake/issues
+.. _`CMake Issue Tracker`: https://gitlab.kitware.com/cmake/cmake/-/issues
 
 Contributing
 ============
diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt
index c57f713..ee8767f 100644
--- a/Source/CMakeLists.txt
+++ b/Source/CMakeLists.txt
@@ -1,9 +1,16 @@
 # Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
 # file Copyright.txt or https://cmake.org/licensing for details.
 
+# To ensure maximum portability across various compilers and platforms
+# deactivate any compiler extensions
+set(CMAKE_C_EXTENSIONS FALSE)
+set(CMAKE_CXX_EXTENSIONS FALSE)
+
 include(CheckIncludeFile)
 # Check if we can build support for ELF parsing.
-if(CMAKE_CXX_PLATFORM_ID MATCHES "OpenBSD")
+if(WIN32)
+  set(HAVE_ELF_H 0)
+elseif(CMAKE_CXX_PLATFORM_ID MATCHES "OpenBSD")
   CHECK_INCLUDE_FILES("stdint.h;elf_abi.h" HAVE_ELF_H)
 else()
   CHECK_INCLUDE_FILE("elf.h" HAVE_ELF_H)
@@ -354,6 +361,7 @@
   cmMakefileTargetGenerator.cxx
   cmMakefileExecutableTargetGenerator.cxx
   cmMakefileLibraryTargetGenerator.cxx
+  cmMakefileProfilingData.cxx
   cmMakefileUtilityTargetGenerator.cxx
   cmMessageType.h
   cmMessenger.cxx
@@ -377,8 +385,6 @@
   cmProperty.h
   cmPropertyDefinition.cxx
   cmPropertyDefinition.h
-  cmPropertyDefinitionMap.cxx
-  cmPropertyDefinitionMap.h
   cmPropertyMap.cxx
   cmPropertyMap.h
   cmQtAutoGen.cxx
@@ -406,6 +412,8 @@
   cmSourceFileLocationKind.h
   cmSourceGroup.cxx
   cmSourceGroup.h
+  cmStandardLevelResolver.cxx
+  cmStandardLevelResolver.h
   cmState.cxx
   cmState.h
   cmStateDirectory.cxx
@@ -486,6 +494,8 @@
   cmBuildNameCommand.h
   cmCMakeHostSystemInformationCommand.cxx
   cmCMakeHostSystemInformationCommand.h
+  cmCMakeLanguageCommand.cxx
+  cmCMakeLanguageCommand.h
   cmCMakeMinimumRequired.cxx
   cmCMakeMinimumRequired.h
   cmCMakePolicyCommand.cxx
@@ -690,7 +700,6 @@
   cmWriteFileCommand.cxx
   cmWriteFileCommand.h
 
-  cm_static_string_view.hxx
   cm_get_date.h
   cm_get_date.c
   cm_utf8.h
diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake
index 567c867..c82a659 100644
--- a/Source/CMakeVersion.cmake
+++ b/Source/CMakeVersion.cmake
@@ -1,7 +1,7 @@
 # CMake version number components.
 set(CMake_VERSION_MAJOR 3)
-set(CMake_VERSION_MINOR 17)
-set(CMake_VERSION_PATCH 4)
+set(CMake_VERSION_MINOR 18)
+set(CMake_VERSION_PATCH 20200811)
 #set(CMake_VERSION_RC 0)
 set(CMake_VERSION_IS_DIRTY 0)
 
diff --git a/Source/CPack/IFW/cmCPackIFWCommon.cxx b/Source/CPack/IFW/cmCPackIFWCommon.cxx
index 9fa74be..20d392d 100644
--- a/Source/CPack/IFW/cmCPackIFWCommon.cxx
+++ b/Source/CPack/IFW/cmCPackIFWCommon.cxx
@@ -2,7 +2,7 @@
    file Copyright.txt or https://cmake.org/licensing for details.  */
 #include "cmCPackIFWCommon.h"
 
-#include <cstddef>
+#include <cstddef> // IWYU pragma: keep
 #include <sstream>
 #include <utility>
 #include <vector>
diff --git a/Source/CPack/IFW/cmCPackIFWGenerator.cxx b/Source/CPack/IFW/cmCPackIFWGenerator.cxx
index 509ac65..2806c61 100644
--- a/Source/CPack/IFW/cmCPackIFWGenerator.cxx
+++ b/Source/CPack/IFW/cmCPackIFWGenerator.cxx
@@ -544,10 +544,7 @@
   if (group->ParentGroup) {
     cmCPackIFWPackage* package = this->GetGroupPackage(group->ParentGroup);
     bool dot = !this->ResolveDuplicateNames;
-    if (dot && name.substr(0, package->Name.size()) == package->Name) {
-      dot = false;
-    }
-    if (dot) {
+    if (dot && !cmHasPrefix(name, package->Name)) {
       name = package->Name + "." + name;
     }
   }
@@ -576,10 +573,7 @@
       return package->Name;
     }
     bool dot = !this->ResolveDuplicateNames;
-    if (dot && name.substr(0, package->Name.size()) == package->Name) {
-      dot = false;
-    }
-    if (dot) {
+    if (dot && !cmHasPrefix(name, package->Name)) {
       name = package->Name + "." + name;
     }
   }
diff --git a/Source/CPack/IFW/cmCPackIFWPackage.cxx b/Source/CPack/IFW/cmCPackIFWPackage.cxx
index 9a9cd56..56a74c5 100644
--- a/Source/CPack/IFW/cmCPackIFWPackage.cxx
+++ b/Source/CPack/IFW/cmCPackIFWPackage.cxx
@@ -55,8 +55,7 @@
   if (dashPos != std::string::npos) {
     pos = dashPos;
   }
-  this->Name =
-    pos == std::string::npos ? dependence : dependence.substr(0, pos);
+  this->Name = dependence.substr(0, pos);
 }
 
 std::string cmCPackIFWPackage::DependenceStruct::NameWithCompare() const
diff --git a/Source/CPack/IFW/cmCPackIFWRepository.cxx b/Source/CPack/IFW/cmCPackIFWRepository.cxx
index a696549..f5e8744 100644
--- a/Source/CPack/IFW/cmCPackIFWRepository.cxx
+++ b/Source/CPack/IFW/cmCPackIFWRepository.cxx
@@ -21,11 +21,7 @@
 
   switch (this->Update) {
     case cmCPackIFWRepository::None:
-      valid = !this->Url.empty();
-      break;
     case cmCPackIFWRepository::Add:
-      valid = !this->Url.empty();
-      break;
     case cmCPackIFWRepository::Remove:
       valid = !this->Url.empty();
       break;
diff --git a/Source/CPack/OSXScriptLauncher.cxx b/Source/CPack/OSXScriptLauncher.cxx
index 21d27a0..bdaf779 100644
--- a/Source/CPack/OSXScriptLauncher.cxx
+++ b/Source/CPack/OSXScriptLauncher.cxx
@@ -5,6 +5,8 @@
 #include <string>
 #include <vector>
 
+#include <cm/memory>
+
 #include <CoreFoundation/CoreFoundation.h>
 
 #include "cmsys/FStream.hxx"
@@ -26,7 +28,6 @@
   CFStringRef fileName;
   CFBundleRef appBundle;
   CFURLRef scriptFileURL;
-  UInt8* path;
 
   // get CF URL for script
   if (!(appBundle = CFBundleGetMainBundle())) {
@@ -41,13 +42,15 @@
   }
 
   // create path string
-  if (!(path = new UInt8[PATH_MAX])) {
+  auto path = cm::make_unique<UInt8[]>(PATH_MAX);
+  if (!path) {
     return 1;
   }
 
   // get the file system path of the url as a cstring
   // in an encoding suitable for posix apis
-  if (!CFURLGetFileSystemRepresentation(scriptFileURL, true, path, PATH_MAX)) {
+  if (!CFURLGetFileSystemRepresentation(scriptFileURL, true, path.get(),
+                                        PATH_MAX)) {
     DebugError("CFURLGetFileSystemRepresentation failed");
     return 1;
   }
@@ -55,10 +58,10 @@
   // dispose of the CF variable
   CFRelease(scriptFileURL);
 
-  std::string fullScriptPath = reinterpret_cast<char*>(path);
-  delete[] path;
+  std::string fullScriptPath = reinterpret_cast<char*>(path.get());
+  path.reset();
 
-  if (!cmsys::SystemTools::FileExists(fullScriptPath.c_str())) {
+  if (!cmsys::SystemTools::FileExists(fullScriptPath)) {
     return 1;
   }
 
@@ -80,7 +83,6 @@
   cmsysProcess_SetTimeout(cp, 0);
   cmsysProcess_Execute(cp);
 
-  std::vector<char> tempOutput;
   char* data;
   int length;
   while (cmsysProcess_WaitForData(cp, &data, &length, nullptr)) {
diff --git a/Source/CPack/WiX/cmCPackWIXGenerator.cxx b/Source/CPack/WiX/cmCPackWIXGenerator.cxx
index e71a38f..72af10b 100644
--- a/Source/CPack/WiX/cmCPackWIXGenerator.cxx
+++ b/Source/CPack/WiX/cmCPackWIXGenerator.cxx
@@ -4,14 +4,15 @@
 
 #include <algorithm>
 
+#include <cm/memory>
 #include <cm/string_view>
+#include <cmext/algorithm>
 
 #include "cmsys/Directory.hxx"
 #include "cmsys/Encoding.hxx"
 #include "cmsys/FStream.hxx"
 #include "cmsys/SystemTools.hxx"
 
-#include "cmAlgorithms.h"
 #include "cmCPackComponentGroup.h"
 #include "cmCPackLog.h"
 #include "cmCryptoHash.h"
@@ -35,22 +36,16 @@
 #include "cmCMakeToWixPath.h"
 
 cmCPackWIXGenerator::cmCPackWIXGenerator()
-  : Patch(0)
-  , ComponentGuidType(cmWIXSourceWriter::WIX_GENERATED_GUID)
+  : ComponentGuidType(cmWIXSourceWriter::WIX_GENERATED_GUID)
 {
 }
 
-cmCPackWIXGenerator::~cmCPackWIXGenerator()
-{
-  if (this->Patch) {
-    delete this->Patch;
-  }
-}
+cmCPackWIXGenerator::~cmCPackWIXGenerator() = default;
 
 int cmCPackWIXGenerator::InitializeInternal()
 {
   componentPackageMethod = ONE_PACKAGE;
-  this->Patch = new cmWIXPatch(this->Logger);
+  this->Patch = cm::make_unique<cmWIXPatch>(this->Logger);
 
   return this->Superclass::InitializeInternal();
 }
@@ -103,7 +98,7 @@
     command << " -ext " << QuotePath(ext);
   }
 
-  if (sourceFile.rfind(this->CPackTopLevel, 0) != 0) {
+  if (!cmHasSuffix(sourceFile, this->CPackTopLevel)) {
     command << " " << QuotePath("-I" + this->CPackTopLevel);
   }
 
@@ -355,8 +350,7 @@
   std::vector<std::string> options = GetOptions();
 
   for (std::string const& name : options) {
-    if (name.length() > prefix.length() &&
-        name.substr(0, prefix.length()) == prefix) {
+    if (cmHasPrefix(name, prefix)) {
       std::string id = name.substr(prefix.length());
       std::string value = GetOption(name.c_str());
 
@@ -960,7 +954,7 @@
           shortcut.workingDirectoryId = directoryId;
           shortcuts.insert(cmWIXShortcuts::START_MENU, id, shortcut);
 
-          if (cmContains(desktopExecutables, executableName)) {
+          if (cm::contains(desktopExecutables, executableName)) {
             shortcuts.insert(cmWIXShortcuts::DESKTOP, id, shortcut);
           }
         }
@@ -1104,14 +1098,14 @@
   cmCryptoHash sha1(cmCryptoHash::AlgoSHA1);
   std::string const hash = sha1.HashString(path);
 
-  std::string identifier = cmStrCat(cm::string_view(hash).substr(0, 7), '_');
-
   const size_t maxFileNameLength = 52;
+  std::string identifier =
+    cmStrCat(cm::string_view(hash).substr(0, 7), '_',
+             cm::string_view(normalizedFilename).substr(0, maxFileNameLength));
+
+  // if the name was truncated
   if (normalizedFilename.length() > maxFileNameLength) {
-    identifier += normalizedFilename.substr(0, maxFileNameLength - 3);
     identifier += "...";
-  } else {
-    identifier += normalizedFilename;
   }
 
   return identifier;
diff --git a/Source/CPack/WiX/cmCPackWIXGenerator.h b/Source/CPack/WiX/cmCPackWIXGenerator.h
index d193348..d5a16ec 100644
--- a/Source/CPack/WiX/cmCPackWIXGenerator.h
+++ b/Source/CPack/WiX/cmCPackWIXGenerator.h
@@ -4,6 +4,7 @@
 #define cmCPackWIXGenerator_h
 
 #include <map>
+#include <memory>
 #include <string>
 
 #include "cmCPackGenerator.h"
@@ -24,6 +25,8 @@
   cmCPackTypeMacro(cmCPackWIXGenerator, cmCPackGenerator);
 
   cmCPackWIXGenerator();
+  cmCPackWIXGenerator(const cmCPackWIXGenerator&) = delete;
+  const cmCPackWIXGenerator& operator=(const cmCPackWIXGenerator&) = delete;
   ~cmCPackWIXGenerator();
 
 protected:
@@ -157,7 +160,7 @@
 
   std::string CPackTopLevel;
 
-  cmWIXPatch* Patch;
+  std::unique_ptr<cmWIXPatch> Patch;
 
   cmWIXSourceWriter::GuidType ComponentGuidType;
 };
diff --git a/Source/CPack/WiX/cmWIXAccessControlList.cxx b/Source/CPack/WiX/cmWIXAccessControlList.cxx
index 3668b46..9685a7f 100644
--- a/Source/CPack/WiX/cmWIXAccessControlList.cxx
+++ b/Source/CPack/WiX/cmWIXAccessControlList.cxx
@@ -2,6 +2,8 @@
    file Copyright.txt or https://cmake.org/licensing for details.  */
 #include "cmWIXAccessControlList.h"
 
+#include <cm/string_view>
+
 #include "cmCPackGenerator.h"
 #include "cmStringAlgorithms.h"
 #include "cmSystemTools.h"
@@ -35,12 +37,13 @@
     return;
   }
 
-  std::string user_and_domain = entry.substr(0, pos);
-  std::string permission_string = entry.substr(pos + 1);
+  cm::string_view enview(entry);
+  cm::string_view user_and_domain = enview.substr(0, pos);
+  cm::string_view permission_string = enview.substr(pos + 1);
 
   pos = user_and_domain.find('@');
-  std::string user;
-  std::string domain;
+  cm::string_view user;
+  cm::string_view domain;
   if (pos != std::string::npos) {
     user = user_and_domain.substr(0, pos);
     domain = user_and_domain.substr(pos + 1);
@@ -51,9 +54,9 @@
   std::vector<std::string> permissions = cmTokenize(permission_string, ",");
 
   this->SourceWriter.BeginElement("Permission");
-  this->SourceWriter.AddAttribute("User", user);
+  this->SourceWriter.AddAttribute("User", std::string(user));
   if (!domain.empty()) {
-    this->SourceWriter.AddAttribute("Domain", domain);
+    this->SourceWriter.AddAttribute("Domain", std::string(domain));
   }
   for (std::string const& permission : permissions) {
     this->EmitBooleanAttribute(entry, cmTrimWhitespace(permission));
diff --git a/Source/CPack/WiX/cmWIXFilesSourceWriter.cxx b/Source/CPack/WiX/cmWIXFilesSourceWriter.cxx
index c0d879a..b4085d5 100644
--- a/Source/CPack/WiX/cmWIXFilesSourceWriter.cxx
+++ b/Source/CPack/WiX/cmWIXFilesSourceWriter.cxx
@@ -1,5 +1,10 @@
 /* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
    file Copyright.txt or https://cmake.org/licensing for details.  */
+#if defined(__CYGWIN__)
+// For S_IWRITE symbol
+#  define _DEFAULT_SOURCE
+#endif
+
 #include "cmWIXFilesSourceWriter.h"
 
 #include "cm_sys_stat.h"
diff --git a/Source/CPack/WiX/cmWIXPatch.cxx b/Source/CPack/WiX/cmWIXPatch.cxx
index ca232f9..122ffaf 100644
--- a/Source/CPack/WiX/cmWIXPatch.cxx
+++ b/Source/CPack/WiX/cmWIXPatch.cxx
@@ -41,7 +41,7 @@
 void cmWIXPatch::ApplyElementChildren(const cmWIXPatchElement& element,
                                       cmWIXSourceWriter& writer)
 {
-  for (cmWIXPatchNode* node : element.children) {
+  for (const auto& node : element.children) {
     switch (node->type()) {
       case cmWIXPatchNode::ELEMENT:
         ApplyElement(dynamic_cast<const cmWIXPatchElement&>(*node), writer);
diff --git a/Source/CPack/WiX/cmWIXPatchParser.cxx b/Source/CPack/WiX/cmWIXPatchParser.cxx
index fd9103b..8b26c4e 100644
--- a/Source/CPack/WiX/cmWIXPatchParser.cxx
+++ b/Source/CPack/WiX/cmWIXPatchParser.cxx
@@ -2,7 +2,11 @@
    file Copyright.txt or https://cmake.org/licensing for details.  */
 #include "cmWIXPatchParser.h"
 
-#include "cm_expat.h"
+#include <utility>
+
+#include <cm/memory>
+
+#include <cm3p/expat.h>
 
 #include "cmCPackGenerator.h"
 
@@ -20,12 +24,8 @@
 {
 }
 
-cmWIXPatchElement::~cmWIXPatchElement()
-{
-  for (cmWIXPatchNode* child : children) {
-    delete child;
-  }
-}
+cmWIXPatchElement::cmWIXPatchElement() = default;
+cmWIXPatchElement::~cmWIXPatchElement() = default;
 
 cmWIXPatchParser::cmWIXPatchParser(fragment_map_t& fragments,
                                    cmCPackLog* logger)
@@ -54,8 +54,7 @@
   } else if (State == INSIDE_FRAGMENT) {
     cmWIXPatchElement& parent = *ElementStack.back();
 
-    cmWIXPatchElement* element = new cmWIXPatchElement;
-    parent.children.push_back(element);
+    auto element = cm::make_unique<cmWIXPatchElement>();
 
     element->name = name;
 
@@ -66,7 +65,8 @@
       element->attributes[key] = value;
     }
 
-    ElementStack.push_back(element);
+    ElementStack.push_back(element.get());
+    parent.children.push_back(std::move(element));
   }
 }
 
@@ -130,10 +130,10 @@
     std::string::size_type last = text.find_last_not_of(whitespace);
 
     if (first != std::string::npos && last != std::string::npos) {
-      cmWIXPatchText* text_node = new cmWIXPatchText;
+      auto text_node = cm::make_unique<cmWIXPatchText>();
       text_node->text = text.substr(first, last - first + 1);
 
-      parent.children.push_back(text_node);
+      parent.children.push_back(std::move(text_node));
     }
   }
 }
diff --git a/Source/CPack/WiX/cmWIXPatchParser.h b/Source/CPack/WiX/cmWIXPatchParser.h
index 87dd892..8d5d2ad 100644
--- a/Source/CPack/WiX/cmWIXPatchParser.h
+++ b/Source/CPack/WiX/cmWIXPatchParser.h
@@ -4,6 +4,7 @@
 #define cmCPackWIXPatchParser_h
 
 #include <map>
+#include <memory>
 #include <vector>
 
 #include "cmCPackLog.h"
@@ -33,9 +34,14 @@
 {
   virtual Type type();
 
+  cmWIXPatchElement();
+
+  cmWIXPatchElement(const cmWIXPatchElement&) = delete;
+  const cmWIXPatchElement& operator=(const cmWIXPatchElement&) = delete;
+
   ~cmWIXPatchElement();
 
-  using child_list_t = std::vector<cmWIXPatchNode*>;
+  using child_list_t = std::vector<std::unique_ptr<cmWIXPatchNode>>;
   using attributes_t = std::map<std::string, std::string>;
 
   std::string name;
diff --git a/Source/CPack/cmCPackArchiveGenerator.cxx b/Source/CPack/cmCPackArchiveGenerator.cxx
index 43f2946..967cc60 100644
--- a/Source/CPack/cmCPackArchiveGenerator.cxx
+++ b/Source/CPack/cmCPackArchiveGenerator.cxx
@@ -8,6 +8,8 @@
 #include <utility>
 #include <vector>
 
+#include <cm3p/archive.h>
+
 #include "cmCPackComponentGroup.h"
 #include "cmCPackGenerator.h"
 #include "cmCPackLog.h"
@@ -154,6 +156,20 @@
   }                                                                           \
   cmArchiveWrite archive(gf, this->Compress, this->ArchiveFormat);            \
   do {                                                                        \
+    if (!this->SetArchiveOptions(&archive)) {                                 \
+      cmCPackLogger(cmCPackLog::LOG_ERROR,                                    \
+                    "Problem to set archive options <"                        \
+                      << (filename) << ">, ERROR = " << (archive).GetError()  \
+                      << std::endl);                                          \
+      return 0;                                                               \
+    }                                                                         \
+    if (!archive.Open()) {                                                    \
+      cmCPackLogger(cmCPackLog::LOG_ERROR,                                    \
+                    "Problem to open archive <"                               \
+                      << (filename) << ">, ERROR = " << (archive).GetError()  \
+                      << std::endl);                                          \
+      return 0;                                                               \
+    }                                                                         \
     if (!(archive)) {                                                         \
       cmCPackLogger(cmCPackLog::LOG_ERROR,                                    \
                     "Problem to create archive <"                             \
@@ -328,3 +344,23 @@
   // (for backward compatibility reason)
   return IsOn("CPACK_ARCHIVE_COMPONENT_INSTALL");
 }
+
+bool cmCPackArchiveGenerator::SetArchiveOptions(cmArchiveWrite* archive)
+{
+#if ARCHIVE_VERSION_NUMBER >= 3004000
+  // Upstream fixed an issue with their integer parsing in 3.4.0 which would
+  // cause spurious errors to be raised from `strtoull`.
+  if (this->Compress == cmArchiveWrite::CompressXZ) {
+    const char* threads = "1";
+    if (this->IsSet("CPACK_ARCHIVE_THREADS")) {
+      threads = this->GetOption("CPACK_ARCHIVE_THREADS");
+    }
+
+    if (!archive->SetFilterOption("xz", "threads", threads)) {
+      return false;
+    }
+  }
+#endif
+
+  return true;
+}
diff --git a/Source/CPack/cmCPackArchiveGenerator.h b/Source/CPack/cmCPackArchiveGenerator.h
index 8d67720..7eb5665 100644
--- a/Source/CPack/cmCPackArchiveGenerator.h
+++ b/Source/CPack/cmCPackArchiveGenerator.h
@@ -86,6 +86,8 @@
     return this->OutputExtension.c_str();
   }
 
+  bool SetArchiveOptions(cmArchiveWrite* archive);
+
 private:
   cmArchiveWrite::Compress Compress;
   std::string ArchiveFormat;
diff --git a/Source/CPack/cmCPackDebGenerator.cxx b/Source/CPack/cmCPackDebGenerator.cxx
index d92acde..560e5c1 100644
--- a/Source/CPack/cmCPackDebGenerator.cxx
+++ b/Source/CPack/cmCPackDebGenerator.cxx
@@ -135,16 +135,17 @@
 {
   // debian-binary file
   const std::string dbfilename = WorkDir + "/debian-binary";
-  cmGeneratedFileStream out(dbfilename);
-  out << "2.0";
-  out << std::endl; // required for valid debian package
+  cmGeneratedFileStream out;
+  out.Open(dbfilename, false, true);
+  out << "2.0\n"; // required for valid debian package
 }
 
 void DebGenerator::generateControlFile() const
 {
   std::string ctlfilename = WorkDir + "/control";
 
-  cmGeneratedFileStream out(ctlfilename);
+  cmGeneratedFileStream out;
+  out.Open(ctlfilename, false, true);
   for (auto const& kv : ControlValues) {
     out << kv.first << ": " << kv.second << "\n";
   }
@@ -156,8 +157,7 @@
       totalSize += cmSystemTools::FileLength(file);
     }
   }
-  out << "Installed-Size: " << (totalSize + 1023) / 1024 << "\n";
-  out << std::endl;
+  out << "Installed-Size: " << (totalSize + 1023) / 1024 << "\n\n";
 }
 
 bool DebGenerator::generateDataTar() const
@@ -173,6 +173,7 @@
   }
   cmArchiveWrite data_tar(fileStream_data_tar, TarCompressionType,
                           DebianArchiveType);
+  data_tar.Open();
 
   // uid/gid should be the one of the root user, and this root user has
   // always uid/gid equal to 0.
@@ -247,7 +248,8 @@
 {
   std::string md5filename = WorkDir + "/md5sums";
 
-  cmGeneratedFileStream out(md5filename);
+  cmGeneratedFileStream out;
+  out.Open(md5filename, false, true);
 
   std::string topLevelWithTrailingSlash = cmStrCat(TemporaryDir, '/');
   for (std::string const& file : PackageFiles) {
@@ -291,6 +293,7 @@
   }
   cmArchiveWrite control_tar(fileStream_control_tar,
                              cmArchiveWrite::CompressGZip, DebianArchiveType);
+  control_tar.Open();
 
   // sets permissions and uid/gid for the files
   control_tar.SetUIDAndGID(0u, 0u);
@@ -410,6 +413,7 @@
   cmGeneratedFileStream debStream;
   debStream.Open(outputPath, false, true);
   cmArchiveWrite deb(debStream, cmArchiveWrite::CompressNone, "arbsd");
+  deb.Open();
 
   // uid/gid should be the one of the root user, and this root user has
   // always uid/gid equal to 0.
@@ -692,57 +696,57 @@
 
   const char* debian_pkg_source =
     this->GetOption("GEN_CPACK_DEBIAN_PACKAGE_SOURCE");
-  if (debian_pkg_source && *debian_pkg_source) {
+  if (cmNonempty(debian_pkg_source)) {
     controlValues["Source"] = debian_pkg_source;
   }
   const char* debian_pkg_dep =
     this->GetOption("GEN_CPACK_DEBIAN_PACKAGE_DEPENDS");
-  if (debian_pkg_dep && *debian_pkg_dep) {
+  if (cmNonempty(debian_pkg_dep)) {
     controlValues["Depends"] = debian_pkg_dep;
   }
   const char* debian_pkg_rec =
     this->GetOption("GEN_CPACK_DEBIAN_PACKAGE_RECOMMENDS");
-  if (debian_pkg_rec && *debian_pkg_rec) {
+  if (cmNonempty(debian_pkg_rec)) {
     controlValues["Recommends"] = debian_pkg_rec;
   }
   const char* debian_pkg_sug =
     this->GetOption("GEN_CPACK_DEBIAN_PACKAGE_SUGGESTS");
-  if (debian_pkg_sug && *debian_pkg_sug) {
+  if (cmNonempty(debian_pkg_sug)) {
     controlValues["Suggests"] = debian_pkg_sug;
   }
   const char* debian_pkg_url =
     this->GetOption("GEN_CPACK_DEBIAN_PACKAGE_HOMEPAGE");
-  if (debian_pkg_url && *debian_pkg_url) {
+  if (cmNonempty(debian_pkg_url)) {
     controlValues["Homepage"] = debian_pkg_url;
   }
   const char* debian_pkg_predep =
     this->GetOption("GEN_CPACK_DEBIAN_PACKAGE_PREDEPENDS");
-  if (debian_pkg_predep && *debian_pkg_predep) {
+  if (cmNonempty(debian_pkg_predep)) {
     controlValues["Pre-Depends"] = debian_pkg_predep;
   }
   const char* debian_pkg_enhances =
     this->GetOption("GEN_CPACK_DEBIAN_PACKAGE_ENHANCES");
-  if (debian_pkg_enhances && *debian_pkg_enhances) {
+  if (cmNonempty(debian_pkg_enhances)) {
     controlValues["Enhances"] = debian_pkg_enhances;
   }
   const char* debian_pkg_breaks =
     this->GetOption("GEN_CPACK_DEBIAN_PACKAGE_BREAKS");
-  if (debian_pkg_breaks && *debian_pkg_breaks) {
+  if (cmNonempty(debian_pkg_breaks)) {
     controlValues["Breaks"] = debian_pkg_breaks;
   }
   const char* debian_pkg_conflicts =
     this->GetOption("GEN_CPACK_DEBIAN_PACKAGE_CONFLICTS");
-  if (debian_pkg_conflicts && *debian_pkg_conflicts) {
+  if (cmNonempty(debian_pkg_conflicts)) {
     controlValues["Conflicts"] = debian_pkg_conflicts;
   }
   const char* debian_pkg_provides =
     this->GetOption("GEN_CPACK_DEBIAN_PACKAGE_PROVIDES");
-  if (debian_pkg_provides && *debian_pkg_provides) {
+  if (cmNonempty(debian_pkg_provides)) {
     controlValues["Provides"] = debian_pkg_provides;
   }
   const char* debian_pkg_replaces =
     this->GetOption("GEN_CPACK_DEBIAN_PACKAGE_REPLACES");
-  if (debian_pkg_replaces && *debian_pkg_replaces) {
+  if (cmNonempty(debian_pkg_replaces)) {
     controlValues["Replaces"] = debian_pkg_replaces;
   }
 
@@ -752,17 +756,19 @@
   const char* debian_pkg_shlibs =
     this->GetOption("GEN_CPACK_DEBIAN_PACKAGE_SHLIBS");
   const bool gen_shibs = this->IsOn("CPACK_DEBIAN_PACKAGE_GENERATE_SHLIBS") &&
-    debian_pkg_shlibs && *debian_pkg_shlibs;
+    cmNonempty(debian_pkg_shlibs);
   if (gen_shibs) {
-    cmGeneratedFileStream out(shlibsfilename);
+    cmGeneratedFileStream out;
+    out.Open(shlibsfilename, false, true);
     out << debian_pkg_shlibs;
-    out << std::endl;
+    out << '\n';
   }
 
   const std::string postinst = strGenWDIR + "/postinst";
   const std::string postrm = strGenWDIR + "/postrm";
   if (this->IsOn("GEN_CPACK_DEBIAN_GENERATE_POSTINST")) {
-    cmGeneratedFileStream out(postinst);
+    cmGeneratedFileStream out;
+    out.Open(postinst, false, true);
     out << "#!/bin/sh\n\n"
            "set -e\n\n"
            "if [ \"$1\" = \"configure\" ]; then\n"
@@ -770,7 +776,8 @@
            "fi\n";
   }
   if (this->IsOn("GEN_CPACK_DEBIAN_GENERATE_POSTRM")) {
-    cmGeneratedFileStream out(postrm);
+    cmGeneratedFileStream out;
+    out.Open(postrm, false, true);
     out << "#!/bin/sh\n\n"
            "set -e\n\n"
            "if [ \"$1\" = \"remove\" ]; then\n"
@@ -825,11 +832,11 @@
 
   const char* debian_pkg_source =
     this->GetOption("GEN_CPACK_DEBIAN_PACKAGE_SOURCE");
-  if (debian_pkg_source && *debian_pkg_source) {
+  if (cmNonempty(debian_pkg_source)) {
     controlValues["Source"] = debian_pkg_source;
   }
   const char* debian_build_ids = this->GetOption("GEN_BUILD_IDS");
-  if (debian_build_ids && *debian_build_ids) {
+  if (cmNonempty(debian_build_ids)) {
     controlValues["Build-Ids"] = debian_build_ids;
   }
 
diff --git a/Source/CPack/cmCPackDragNDropGenerator.cxx b/Source/CPack/cmCPackDragNDropGenerator.cxx
index fe7abf4..cefb906 100644
--- a/Source/CPack/cmCPackDragNDropGenerator.cxx
+++ b/Source/CPack/cmCPackDragNDropGenerator.cxx
@@ -8,7 +8,9 @@
 #include <map>
 
 #include <CoreFoundation/CoreFoundation.h>
+#include <cm3p/kwiml/abi.h>
 
+#include "cmsys/Base64.h"
 #include "cmsys/FStream.hxx"
 #include "cmsys/RegularExpression.hxx"
 
@@ -18,6 +20,7 @@
 #include "cmGeneratedFileStream.h"
 #include "cmStringAlgorithms.h"
 #include "cmSystemTools.h"
+#include "cmXMLWriter.h"
 
 #ifdef HAVE_CoreServices
 // For the old LocaleStringToLangAndRegionCodes() function, to convert
@@ -26,36 +29,28 @@
 #  include <CoreServices/CoreServices.h>
 #endif
 
-static const char* SLAHeader =
-  "data 'LPic' (5000) {\n"
-  "    $\"0002 0011 0003 0001 0000 0000 0002 0000\"\n"
-  "    $\"0008 0003 0000 0001 0004 0000 0004 0005\"\n"
-  "    $\"0000 000E 0006 0001 0005 0007 0000 0007\"\n"
-  "    $\"0008 0000 0047 0009 0000 0034 000A 0001\"\n"
-  "    $\"0035 000B 0001 0020 000C 0000 0011 000D\"\n"
-  "    $\"0000 005B 0004 0000 0033 000F 0001 000C\"\n"
-  "    $\"0010 0000 000B 000E 0000\"\n"
-  "};\n"
-  "\n";
+static const uint16_t DefaultLpic[] = {
+  /* clang-format off */
+  0x0002, 0x0011, 0x0003, 0x0001, 0x0000, 0x0000, 0x0002, 0x0000,
+  0x0008, 0x0003, 0x0000, 0x0001, 0x0004, 0x0000, 0x0004, 0x0005,
+  0x0000, 0x000E, 0x0006, 0x0001, 0x0005, 0x0007, 0x0000, 0x0007,
+  0x0008, 0x0000, 0x0047, 0x0009, 0x0000, 0x0034, 0x000A, 0x0001,
+  0x0035, 0x000B, 0x0001, 0x0020, 0x000C, 0x0000, 0x0011, 0x000D,
+  0x0000, 0x005B, 0x0004, 0x0000, 0x0033, 0x000F, 0x0001, 0x000C,
+  0x0010, 0x0000, 0x000B, 0x000E, 0x0000
+  /* clang-format on */
+};
 
-static const char* SLASTREnglish =
-  "resource 'STR#' (5002, \"English\") {\n"
-  "    {\n"
-  "        \"English\",\n"
-  "        \"Agree\",\n"
-  "        \"Disagree\",\n"
-  "        \"Print\",\n"
-  "        \"Save...\",\n"
-  "        \"You agree to the License Agreement terms when you click \"\n"
-  "        \"the \\\"Agree\\\" button.\",\n"
-  "        \"Software License Agreement\",\n"
-  "        \"This text cannot be saved.  This disk may be full or locked, "
-  "or the \"\n"
-  "        \"file may be locked.\",\n"
-  "        \"Unable to print.  Make sure you have selected a printer.\"\n"
-  "    }\n"
-  "};\n"
-  "\n";
+static const std::vector<std::string> DefaultMenu = {
+  { "English", "Agree", "Disagree", "Print", "Save...",
+    // NOLINTNEXTLINE(bugprone-suspicious-missing-comma)
+    "You agree to the License Agreement terms when "
+    "you click the \"Agree\" button.",
+    "Software License Agreement",
+    "This text cannot be saved.  "
+    "This disk may be full or locked, or the file may be locked.",
+    "Unable to print.  Make sure you have selected a printer." }
+};
 
 cmCPackDragNDropGenerator::cmCPackDragNDropGenerator()
   : singleLicense(false)
@@ -523,22 +518,43 @@
     }
   }
 
+  // Create the final compressed read-only disk image ...
+  std::ostringstream final_image_command;
+  final_image_command << this->GetOption("CPACK_COMMAND_HDIUTIL");
+  final_image_command << " convert \"" << temp_image << "\"";
+  final_image_command << " -format ";
+  final_image_command << cpack_dmg_format;
+  final_image_command << " -imagekey";
+  final_image_command << " zlib-level=9";
+  final_image_command << " -o \"" << output_file << "\"";
+
+  std::string convert_error;
+
+  if (!this->RunCommand(final_image_command, &convert_error)) {
+    cmCPackLogger(cmCPackLog::LOG_ERROR,
+                  "Error compressing disk image." << std::endl
+                                                  << convert_error
+                                                  << std::endl);
+
+    return 0;
+  }
+
   if (!cpack_license_file.empty() || !slaDirectory.empty()) {
     // Use old hardcoded style if sla_dir is not set
     bool oldStyle = slaDirectory.empty();
-    std::string sla_r =
-      cmStrCat(this->GetOption("CPACK_TOPLEVEL_DIRECTORY"), "/sla.r");
+    std::string sla_xml =
+      cmStrCat(this->GetOption("CPACK_TOPLEVEL_DIRECTORY"), "/sla.xml");
 
     std::vector<std::string> languages;
     if (!oldStyle) {
       cmExpandList(cpack_dmg_languages, languages);
     }
 
-    cmGeneratedFileStream ofs(sla_r);
-    ofs << "#include <CoreServices/CoreServices.r>\n\n";
+    std::vector<uint16_t> header_data;
     if (oldStyle) {
-      ofs << SLAHeader;
-      ofs << "\n";
+      header_data = std::vector<uint16_t>(
+        DefaultLpic,
+        DefaultLpic + (sizeof(DefaultLpic) / sizeof(*DefaultLpic)));
     } else {
       /*
        * LPic Layout
@@ -558,8 +574,6 @@
        * }
        */
 
-      // Create vector first for readability, then iterate to write to ofs
-      std::vector<uint16_t> header_data;
       header_data.push_back(0);
       header_data.push_back(languages.size());
       for (size_t i = 0; i < languages.size(); ++i) {
@@ -596,52 +610,50 @@
         header_data.push_back(0);
 #endif
       }
-      ofs << "data 'LPic' (5000) {\n";
-      ofs << std::hex << std::uppercase << std::setfill('0');
+    }
 
-      for (size_t i = 0; i < header_data.size(); ++i) {
-        if (i % 8 == 0) {
-          ofs << "    $\"";
-        }
+    RezDoc rez;
 
-        ofs << std::setw(4) << header_data[i];
-
-        if (i % 8 == 7 || i == header_data.size() - 1) {
-          ofs << "\"\n";
-        } else {
-          ofs << " ";
-        }
+    {
+      RezDict lpic = { {}, 5000, {} };
+      lpic.Data.reserve(header_data.size() * sizeof(header_data[0]));
+      for (uint16_t x : header_data) {
+        // LPic header is big-endian.
+        char* d = reinterpret_cast<char*>(&x);
+#if KWIML_ABI_ENDIAN_ID == KWIML_ABI_ENDIAN_ID_LITTLE
+        lpic.Data.push_back(d[1]);
+        lpic.Data.push_back(d[0]);
+#else
+        lpic.Data.push_back(d[0]);
+        lpic.Data.push_back(d[1]);
+#endif
       }
-      ofs << "};\n\n";
-      // Reset ofs options
-      ofs << std::dec << std::nouppercase << std::setfill(' ');
+      rez.LPic.Entries.emplace_back(std::move(lpic));
     }
 
     bool have_write_license_error = false;
     std::string error;
 
     if (oldStyle) {
-      if (!this->WriteLicense(ofs, 0, "", cpack_license_file, &error)) {
+      if (!this->WriteLicense(rez, 0, "", cpack_license_file, &error)) {
         have_write_license_error = true;
       }
     } else {
       for (size_t i = 0; i < languages.size() && !have_write_license_error;
            ++i) {
         if (singleLicense) {
-          if (!this->WriteLicense(ofs, i + 5000, languages[i],
+          if (!this->WriteLicense(rez, i + 5000, languages[i],
                                   cpack_license_file, &error)) {
             have_write_license_error = true;
           }
         } else {
-          if (!this->WriteLicense(ofs, i + 5000, languages[i], "", &error)) {
+          if (!this->WriteLicense(rez, i + 5000, languages[i], "", &error)) {
             have_write_license_error = true;
           }
         }
       }
     }
 
-    ofs.Close();
-
     if (have_write_license_error) {
       cmCPackLogger(cmCPackLog::LOG_ERROR,
                     "Error writing license file to SLA." << std::endl
@@ -650,94 +662,25 @@
       return 0;
     }
 
-    if (temp_image_format != "UDZO") {
-      temp_image_format = "UDZO";
-      // convert to UDZO to enable unflatten/flatten
-      std::string temp_udzo = cmStrCat(
-        this->GetOption("CPACK_TOPLEVEL_DIRECTORY"), "/temp-udzo.dmg");
+    this->WriteRezXML(sla_xml, rez);
 
-      std::ostringstream udco_image_command;
-      udco_image_command << this->GetOption("CPACK_COMMAND_HDIUTIL");
-      udco_image_command << " convert \"" << temp_image << "\"";
-      udco_image_command << " -format UDZO";
-      udco_image_command << " -ov -o \"" << temp_udzo << "\"";
-
-      if (!this->RunCommand(udco_image_command, &error)) {
-        cmCPackLogger(cmCPackLog::LOG_ERROR,
-                      "Error converting to UDCO dmg for adding SLA."
-                        << std::endl
-                        << error << std::endl);
-        return 0;
-      }
-      temp_image = temp_udzo;
-    }
-
-    // unflatten dmg
-    std::ostringstream unflatten_command;
-    unflatten_command << this->GetOption("CPACK_COMMAND_HDIUTIL");
-    unflatten_command << " unflatten ";
-    unflatten_command << "\"" << temp_image << "\"";
-
-    if (!this->RunCommand(unflatten_command, &error)) {
-      cmCPackLogger(cmCPackLog::LOG_ERROR,
-                    "Error unflattening dmg for adding SLA." << std::endl
-                                                             << error
-                                                             << std::endl);
-      return 0;
-    }
-
-    // Rez the SLA
+    // Create the final compressed read-only disk image ...
     std::ostringstream embed_sla_command;
-    embed_sla_command << this->GetOption("CPACK_COMMAND_REZ");
-    const char* sysroot = this->GetOption("CPACK_OSX_SYSROOT");
-    if (sysroot && sysroot[0] != '\0') {
-      embed_sla_command << " -isysroot \"" << sysroot << "\"";
-    }
-    embed_sla_command << " \"" << sla_r << "\"";
-    embed_sla_command << " -a -o ";
-    embed_sla_command << "\"" << temp_image << "\"";
-
-    if (!this->RunCommand(embed_sla_command, &error)) {
+    embed_sla_command << this->GetOption("CPACK_COMMAND_HDIUTIL");
+    embed_sla_command << " udifrez";
+    embed_sla_command << " -xml";
+    embed_sla_command << " \"" << sla_xml << "\"";
+    embed_sla_command << " FIXME_WHY_IS_THIS_ARGUMENT_NEEDED";
+    embed_sla_command << " \"" << output_file << "\"";
+    std::string embed_error;
+    if (!this->RunCommand(embed_sla_command, &embed_error)) {
       cmCPackLogger(cmCPackLog::LOG_ERROR,
-                    "Error adding SLA." << std::endl
-                                        << error << std::endl);
+                    "Error compressing disk image." << std::endl
+                                                    << embed_error
+                                                    << std::endl);
+
       return 0;
     }
-
-    // flatten dmg
-    std::ostringstream flatten_command;
-    flatten_command << this->GetOption("CPACK_COMMAND_HDIUTIL");
-    flatten_command << " flatten ";
-    flatten_command << "\"" << temp_image << "\"";
-
-    if (!this->RunCommand(flatten_command, &error)) {
-      cmCPackLogger(cmCPackLog::LOG_ERROR,
-                    "Error flattening dmg for adding SLA." << std::endl
-                                                           << error
-                                                           << std::endl);
-      return 0;
-    }
-  }
-
-  // Create the final compressed read-only disk image ...
-  std::ostringstream final_image_command;
-  final_image_command << this->GetOption("CPACK_COMMAND_HDIUTIL");
-  final_image_command << " convert \"" << temp_image << "\"";
-  final_image_command << " -format ";
-  final_image_command << cpack_dmg_format;
-  final_image_command << " -imagekey";
-  final_image_command << " zlib-level=9";
-  final_image_command << " -o \"" << output_file << "\"";
-
-  std::string convert_error;
-
-  if (!this->RunCommand(final_image_command, &convert_error)) {
-    cmCPackLogger(cmCPackLog::LOG_ERROR,
-                  "Error compressing disk image." << std::endl
-                                                  << convert_error
-                                                  << std::endl);
-
-    return 0;
   }
 
   return 1;
@@ -788,10 +731,67 @@
   return GetComponentPackageFileName(package_file_name, componentName, false);
 }
 
-bool cmCPackDragNDropGenerator::WriteLicense(
-  cmGeneratedFileStream& outputStream, int licenseNumber,
-  std::string licenseLanguage, const std::string& licenseFile,
-  std::string* error)
+void cmCPackDragNDropGenerator::WriteRezXML(std::string const& file,
+                                            RezDoc const& rez)
+{
+  cmGeneratedFileStream fxml(file);
+  cmXMLWriter xml(fxml);
+  xml.StartDocument();
+  xml.StartElement("plist");
+  xml.Attribute("version", "1.0");
+  xml.StartElement("dict");
+  this->WriteRezArray(xml, rez.LPic);
+  this->WriteRezArray(xml, rez.Menu);
+  this->WriteRezArray(xml, rez.Text);
+  this->WriteRezArray(xml, rez.RTF);
+  xml.EndElement(); // dict
+  xml.EndElement(); // plist
+  xml.EndDocument();
+  fxml.Close();
+}
+
+void cmCPackDragNDropGenerator::WriteRezArray(cmXMLWriter& xml,
+                                              RezArray const& array)
+{
+  if (array.Entries.empty()) {
+    return;
+  }
+  xml.StartElement("key");
+  xml.Content(array.Key);
+  xml.EndElement(); // key
+  xml.StartElement("array");
+  for (RezDict const& dict : array.Entries) {
+    this->WriteRezDict(xml, dict);
+  }
+  xml.EndElement(); // array
+}
+
+void cmCPackDragNDropGenerator::WriteRezDict(cmXMLWriter& xml,
+                                             RezDict const& dict)
+{
+  std::vector<char> base64buf(dict.Data.size() * 3 / 2 + 5);
+  size_t base64len =
+    cmsysBase64_Encode(dict.Data.data(), dict.Data.size(),
+                       reinterpret_cast<unsigned char*>(base64buf.data()), 0);
+  std::string base64data(base64buf.data(), base64len);
+  /* clang-format off */
+  xml.StartElement("dict");
+  xml.StartElement("key");    xml.Content("Attributes"); xml.EndElement();
+  xml.StartElement("string"); xml.Content("0x0000");     xml.EndElement();
+  xml.StartElement("key");    xml.Content("Data");       xml.EndElement();
+  xml.StartElement("data");   xml.Content(base64data);   xml.EndElement();
+  xml.StartElement("key");    xml.Content("ID");         xml.EndElement();
+  xml.StartElement("string"); xml.Content(dict.ID);      xml.EndElement();
+  xml.StartElement("key");    xml.Content("Name");       xml.EndElement();
+  xml.StartElement("string"); xml.Content(dict.Name);    xml.EndElement();
+  xml.EndElement(); // dict
+  /* clang-format on */
+}
+
+bool cmCPackDragNDropGenerator::WriteLicense(RezDoc& rez, size_t licenseNumber,
+                                             std::string licenseLanguage,
+                                             const std::string& licenseFile,
+                                             std::string* error)
 {
   if (!licenseFile.empty() && !singleLicense) {
     licenseNumber = 5002;
@@ -799,11 +799,11 @@
   }
 
   // License file
-  std::string license_format = "TEXT";
+  RezArray* licenseArray = &rez.Text;
   std::string actual_license;
   if (!licenseFile.empty()) {
     if (cmHasLiteralSuffix(licenseFile, ".rtf")) {
-      license_format = "RTF ";
+      licenseArray = &rez.RTF;
     }
     actual_license = licenseFile;
   } else {
@@ -812,93 +812,94 @@
     if (cmSystemTools::FileExists(license_wo_ext + ".txt")) {
       actual_license = license_wo_ext + ".txt";
     } else {
-      license_format = "RTF ";
+      licenseArray = &rez.RTF;
       actual_license = license_wo_ext + ".rtf";
     }
   }
 
-  // License header
-  outputStream << "data '" << license_format << "' (" << licenseNumber
-               << ", \"" << licenseLanguage << "\") {\n";
   // License body
-  cmsys::ifstream license_ifs;
-  license_ifs.open(actual_license.c_str());
-  if (license_ifs.is_open()) {
-    while (license_ifs.good()) {
-      std::string line;
-      std::getline(license_ifs, line);
-      if (!line.empty()) {
-        EscapeQuotesAndBackslashes(line);
-        std::vector<std::string> lines;
-        if (!this->BreakLongLine(line, lines, error)) {
-          return false;
-        }
-        for (auto const& l : lines) {
-          outputStream << "        \"" << l << "\"\n";
-        }
-      }
-      outputStream << "        \"\\n\"\n";
+  {
+    RezDict license = { licenseLanguage, licenseNumber, {} };
+    std::vector<std::string> lines;
+    if (!this->ReadFile(actual_license, lines, error)) {
+      return false;
     }
-    license_ifs.close();
+    this->EncodeLicense(license, lines);
+    licenseArray->Entries.emplace_back(std::move(license));
   }
 
-  // End of License
-  outputStream << "};\n\n";
-  if (!licenseFile.empty() && !singleLicense) {
-    outputStream << SLASTREnglish;
-  } else {
-    // Menu header
-    outputStream << "resource 'STR#' (" << licenseNumber << ", \""
-                 << licenseLanguage << "\") {\n";
-    outputStream << "    {\n";
-
-    // Menu body
-    cmsys::ifstream menu_ifs;
-    menu_ifs.open(
-      (slaDirectory + "/" + licenseLanguage + ".menu.txt").c_str());
-    if (menu_ifs.is_open()) {
-      size_t lines_written = 0;
-      while (menu_ifs.good()) {
-        // Lines written from original file, not from broken up lines
-        std::string line;
-        std::getline(menu_ifs, line);
-        if (!line.empty()) {
-          EscapeQuotesAndBackslashes(line);
-          std::vector<std::string> lines;
-          if (!this->BreakLongLine(line, lines, error)) {
-            return false;
-          }
-          for (size_t i = 0; i < lines.size(); ++i) {
-            std::string comma;
-            // We need a comma after every complete string,
-            // but not on the very last line
-            if (lines_written != 8 && i == lines.size() - 1) {
-              comma = ",";
-            } else {
-              comma = "";
-            }
-            outputStream << "        \"" << lines[i] << "\"" << comma << "\n";
-          }
-          ++lines_written;
-        }
+  // Menu body
+  {
+    RezDict menu = { licenseLanguage, licenseNumber, {} };
+    if (!licenseFile.empty() && !singleLicense) {
+      this->EncodeMenu(menu, DefaultMenu);
+    } else {
+      std::vector<std::string> lines;
+      std::string actual_menu =
+        slaDirectory + "/" + licenseLanguage + ".menu.txt";
+      if (!this->ReadFile(actual_menu, lines, error)) {
+        return false;
       }
-      menu_ifs.close();
+      this->EncodeMenu(menu, lines);
     }
-
-    // End of menu
-    outputStream << "    }\n";
-    outputStream << "};\n";
-    outputStream << "\n";
+    rez.Menu.Entries.emplace_back(std::move(menu));
   }
 
   return true;
 }
 
+void cmCPackDragNDropGenerator::EncodeLicense(
+  RezDict& dict, std::vector<std::string> const& lines)
+{
+  // License text uses CR newlines.
+  for (std::string const& l : lines) {
+    dict.Data.insert(dict.Data.end(), l.begin(), l.end());
+    dict.Data.push_back('\r');
+  }
+  dict.Data.push_back('\r');
+}
+
+void cmCPackDragNDropGenerator::EncodeMenu(
+  RezDict& dict, std::vector<std::string> const& lines)
+{
+  // Menu resources start with a big-endian uint16_t for number of lines:
+  {
+    uint16_t numLines = static_cast<uint16_t>(lines.size());
+    char* d = reinterpret_cast<char*>(&numLines);
+#if KWIML_ABI_ENDIAN_ID == KWIML_ABI_ENDIAN_ID_LITTLE
+    dict.Data.push_back(d[1]);
+    dict.Data.push_back(d[0]);
+#else
+    dict.Data.push_back(d[0]);
+    dict.Data.push_back(d[1]);
+#endif
+  }
+  // Each line starts with a uint8_t length, plus the bytes themselves:
+  for (std::string const& l : lines) {
+    dict.Data.push_back(static_cast<unsigned char>(l.length()));
+    dict.Data.insert(dict.Data.end(), l.begin(), l.end());
+  }
+}
+
+bool cmCPackDragNDropGenerator::ReadFile(std::string const& file,
+                                         std::vector<std::string>& lines,
+                                         std::string* error)
+{
+  cmsys::ifstream ifs(file);
+  std::string line;
+  while (std::getline(ifs, line)) {
+    if (!this->BreakLongLine(line, lines, error)) {
+      return false;
+    }
+  }
+  return true;
+}
+
 bool cmCPackDragNDropGenerator::BreakLongLine(const std::string& line,
                                               std::vector<std::string>& lines,
                                               std::string* error)
 {
-  const size_t max_line_length = 512;
+  const size_t max_line_length = 255;
   size_t line_length = max_line_length;
   for (size_t i = 0; i < line.size(); i += line_length) {
     line_length = max_line_length;
@@ -913,25 +914,10 @@
     if (line_length == 0) {
       *error = "Please make sure there are no words "
                "(or character sequences not broken up by spaces or newlines) "
-               "in your license file which are more than 512 characters long.";
+               "in your license file which are more than 255 characters long.";
       return false;
     }
     lines.push_back(line.substr(i, line_length));
   }
   return true;
 }
-
-void cmCPackDragNDropGenerator::EscapeQuotesAndBackslashes(std::string& line)
-{
-  std::string::size_type backslash_pos = line.find('\\');
-  while (backslash_pos != std::string::npos) {
-    line.replace(backslash_pos, 1, "\\\\");
-    backslash_pos = line.find('\\', backslash_pos + 2);
-  }
-
-  std::string::size_type quote_pos = line.find('\"');
-  while (quote_pos != std::string::npos) {
-    line.replace(quote_pos, 1, "\\\"");
-    quote_pos = line.find('\"', quote_pos + 2);
-  }
-}
diff --git a/Source/CPack/cmCPackDragNDropGenerator.h b/Source/CPack/cmCPackDragNDropGenerator.h
index f8c86c0..dbd190c 100644
--- a/Source/CPack/cmCPackDragNDropGenerator.h
+++ b/Source/CPack/cmCPackDragNDropGenerator.h
@@ -14,6 +14,7 @@
 #include "cmCPackGenerator.h"
 
 class cmGeneratedFileStream;
+class cmXMLWriter;
 
 /** \class cmCPackDragNDropGenerator
  * \brief A generator for OSX drag-n-drop installs
@@ -45,12 +46,40 @@
   std::string slaDirectory;
   bool singleLicense;
 
-  bool WriteLicense(cmGeneratedFileStream& outputStream, int licenseNumber,
+  struct RezDict
+  {
+    std::string Name;
+    size_t ID;
+    std::vector<unsigned char> Data;
+  };
+
+  struct RezArray
+  {
+    std::string Key;
+    std::vector<RezDict> Entries;
+  };
+
+  struct RezDoc
+  {
+    RezArray LPic = { "LPic", {} };
+    RezArray Menu = { "STR#", {} };
+    RezArray Text = { "TEXT", {} };
+    RezArray RTF = { "RTF ", {} };
+  };
+
+  void WriteRezXML(std::string const& file, RezDoc const& rez);
+  void WriteRezArray(cmXMLWriter& xml, RezArray const& array);
+  void WriteRezDict(cmXMLWriter& xml, RezDict const& dict);
+
+  bool WriteLicense(RezDoc& rez, size_t licenseNumber,
                     std::string licenseLanguage,
                     const std::string& licenseFile, std::string* error);
+  void EncodeLicense(RezDict& dict, std::vector<std::string> const& lines);
+  void EncodeMenu(RezDict& dict, std::vector<std::string> const& lines);
+  bool ReadFile(std::string const& file, std::vector<std::string>& lines,
+                std::string* error);
   bool BreakLongLine(const std::string& line, std::vector<std::string>& lines,
                      std::string* error);
-  void EscapeQuotesAndBackslashes(std::string& line);
 };
 
 #endif
diff --git a/Source/CPack/cmCPackExternalGenerator.cxx b/Source/CPack/cmCPackExternalGenerator.cxx
index 142eb6f..0bc8456 100644
--- a/Source/CPack/cmCPackExternalGenerator.cxx
+++ b/Source/CPack/cmCPackExternalGenerator.cxx
@@ -8,10 +8,10 @@
 
 #include <cm/memory>
 
-#include "cmsys/FStream.hxx"
+#include <cm3p/json/value.h>
+#include <cm3p/json/writer.h>
 
-#include "cm_jsoncpp_value.h"
-#include "cm_jsoncpp_writer.h"
+#include "cmsys/FStream.hxx"
 
 #include "cmCPackComponentGroup.h"
 #include "cmCPackLog.h"
@@ -61,7 +61,7 @@
   }
 
   const char* packageScript = this->GetOption("CPACK_EXTERNAL_PACKAGE_SCRIPT");
-  if (packageScript && *packageScript) {
+  if (cmNonempty(packageScript)) {
     if (!cmSystemTools::FileIsFullPath(packageScript)) {
       cmCPackLogger(
         cmCPackLog::LOG_ERROR,
@@ -75,6 +75,12 @@
     if (cmSystemTools::GetErrorOccuredFlag() || !res) {
       return 0;
     }
+
+    const char* builtPackagesStr =
+      this->GetOption("CPACK_EXTERNAL_BUILT_PACKAGES");
+    if (builtPackagesStr) {
+      cmExpandList(builtPackagesStr, this->packageFileNames, false);
+    }
   }
 
   return 1;
@@ -205,7 +211,7 @@
 
   const char* defaultDirectoryPermissions =
     this->Parent->GetOption("CPACK_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS");
-  if (defaultDirectoryPermissions && *defaultDirectoryPermissions) {
+  if (cmNonempty(defaultDirectoryPermissions)) {
     root["defaultDirectoryPermissions"] = defaultDirectoryPermissions;
   }
   if (cmIsInternallyOn(this->Parent->GetOption("CPACK_SET_DESTDIR"))) {
diff --git a/Source/CPack/cmCPackFreeBSDGenerator.cxx b/Source/CPack/cmCPackFreeBSDGenerator.cxx
index e3cc352..b673006 100644
--- a/Source/CPack/cmCPackFreeBSDGenerator.cxx
+++ b/Source/CPack/cmCPackFreeBSDGenerator.cxx
@@ -8,6 +8,7 @@
 #include "cmGeneratedFileStream.h"
 #include "cmStringAlgorithms.h"
 #include "cmSystemTools.h"
+#include "cmWorkingDirectory.h"
 
 // Needed for ::open() and ::stat()
 #include <algorithm>
@@ -285,8 +286,7 @@
   }
 
   std::vector<std::string>::const_iterator fileIt;
-  std::string dir = cmSystemTools::GetCurrentWorkingDirectory();
-  cmSystemTools::ChangeDirectory(toplevel);
+  cmWorkingDirectory wd(toplevel);
 
   files.erase(std::remove_if(files.begin(), files.end(), ignore_file),
               files.end());
@@ -332,6 +332,5 @@
     }
   }
 
-  cmSystemTools::ChangeDirectory(dir);
   return 1;
 }
diff --git a/Source/CPack/cmCPackGenerator.cxx b/Source/CPack/cmCPackGenerator.cxx
index e053144..3880f65 100644
--- a/Source/CPack/cmCPackGenerator.cxx
+++ b/Source/CPack/cmCPackGenerator.cxx
@@ -216,7 +216,7 @@
   mode_t* default_dir_mode = nullptr;
   const char* default_dir_install_permissions =
     this->GetOption("CPACK_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS");
-  if (default_dir_install_permissions && *default_dir_install_permissions) {
+  if (cmNonempty(default_dir_install_permissions)) {
     std::vector<std::string> items =
       cmExpandedList(default_dir_install_permissions);
     for (const auto& arg : items) {
@@ -264,6 +264,23 @@
     return 0;
   }
 
+  // Run pre-build actions
+  const char* preBuildScripts = this->GetOption("CPACK_PRE_BUILD_SCRIPTS");
+  if (preBuildScripts) {
+    const auto scripts = cmExpandedList(preBuildScripts, false);
+    for (const auto& script : scripts) {
+      cmCPackLogger(cmCPackLog::LOG_OUTPUT,
+                    "Executing pre-build script: " << script << std::endl);
+
+      if (!this->MakefileMap->ReadListFile(script)) {
+        cmCPackLogger(cmCPackLog::LOG_ERROR,
+                      "The pre-build script not found: " << script
+                                                         << std::endl);
+        return 0;
+      }
+    }
+  }
+
   if (setDestDir) {
     cmSystemTools::PutEnv("DESTDIR=");
   }
@@ -276,7 +293,7 @@
 {
   (void)setDestDir;
   const char* installCommands = this->GetOption("CPACK_INSTALL_COMMANDS");
-  if (installCommands && *installCommands) {
+  if (cmNonempty(installCommands)) {
     std::string tempInstallDirectoryEnv =
       cmStrCat("CMAKE_INSTALL_PREFIX=", tempInstallDirectory);
     cmSystemTools::PutEnv(tempInstallDirectoryEnv);
@@ -327,13 +344,14 @@
   }
   const char* installDirectories =
     this->GetOption("CPACK_INSTALLED_DIRECTORIES");
-  if (installDirectories && *installDirectories) {
+  if (cmNonempty(installDirectories)) {
     std::vector<std::string> installDirectoriesVector =
       cmExpandedList(installDirectories);
     if (installDirectoriesVector.size() % 2 != 0) {
       cmCPackLogger(
         cmCPackLog::LOG_ERROR,
-        "CPACK_INSTALLED_DIRECTORIES should contain pairs of <directory> and "
+        "CPACK_INSTALLED_DIRECTORIES should contain pairs of <directory> "
+        "and "
         "<subdirectory>. The <subdirectory> can be '.' to be installed in "
         "the toplevel directory of installation."
           << std::endl);
@@ -403,7 +421,6 @@
       }
       /* rebuild symlinks in the installed tree */
       if (!symlinkedFiles.empty()) {
-        std::string curDir = cmSystemTools::GetCurrentWorkingDirectory();
         std::string goToDir = cmStrCat(tempDir, '/', subdir);
         cmCPackLogger(cmCPackLog::LOG_DEBUG,
                       "Change dir to: " << goToDir << std::endl);
@@ -442,7 +459,8 @@
           }
         }
         cmCPackLogger(cmCPackLog::LOG_DEBUG,
-                      "Going back to: " << curDir << std::endl);
+                      "Going back to: " << workdir.GetOldDirectory()
+                                        << std::endl);
       }
     }
   }
@@ -475,10 +493,10 @@
                     "- Install script: " << installScript << std::endl);
 
       if (setDestDir) {
-        // For DESTDIR based packaging, use the *project* CMAKE_INSTALL_PREFIX
-        // underneath the tempInstallDirectory. The value of the project's
-        // CMAKE_INSTALL_PREFIX is sent in here as the value of the
-        // CPACK_INSTALL_PREFIX variable.
+        // For DESTDIR based packaging, use the *project*
+        // CMAKE_INSTALL_PREFIX underneath the tempInstallDirectory. The
+        // value of the project's CMAKE_INSTALL_PREFIX is sent in here as the
+        // value of the CPACK_INSTALL_PREFIX variable.
 
         std::string dir;
         if (this->GetOption("CPACK_INSTALL_PREFIX")) {
@@ -523,7 +541,7 @@
   const char* cmakeProjects = this->GetOption("CPACK_INSTALL_CMAKE_PROJECTS");
   const char* cmakeGenerator = this->GetOption("CPACK_CMAKE_GENERATOR");
   std::string absoluteDestFiles;
-  if (cmakeProjects && *cmakeProjects) {
+  if (cmNonempty(cmakeProjects)) {
     if (!cmakeGenerator) {
       cmCPackLogger(cmCPackLog::LOG_ERROR,
                     "CPACK_INSTALL_CMAKE_PROJECTS is specified, but "
@@ -576,7 +594,7 @@
         std::string installTypesVar = "CPACK_" +
           cmSystemTools::UpperCase(project.Component) + "_INSTALL_TYPES";
         const char* installTypes = this->GetOption(installTypesVar);
-        if (installTypes && *installTypes) {
+        if (cmNonempty(installTypes)) {
           std::vector<std::string> installTypesVector =
             cmExpandedList(installTypes);
           for (std::string const& installType : installTypesVector) {
@@ -589,7 +607,7 @@
         std::string componentsVar =
           "CPACK_COMPONENTS_" + cmSystemTools::UpperCase(project.Component);
         const char* components = this->GetOption(componentsVar);
-        if (components && *components) {
+        if (cmNonempty(components)) {
           cmExpandList(components, componentsVector);
           for (std::string const& comp : componentsVector) {
             project.Components.push_back(
@@ -753,7 +771,7 @@
 
   const char* default_dir_inst_permissions =
     this->GetOption("CPACK_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS");
-  if (default_dir_inst_permissions && *default_dir_inst_permissions) {
+  if (cmNonempty(default_dir_inst_permissions)) {
     mf.AddDefinition("CMAKE_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS",
                      default_dir_inst_permissions);
   }
@@ -811,7 +829,7 @@
      *     - Because it was already used for component install
      *       in order to put things in subdirs...
      */
-    cmSystemTools::PutEnv(std::string("DESTDIR=") + tempInstallDirectory);
+    cmSystemTools::PutEnv("DESTDIR=" + tempInstallDirectory);
     cmCPackLogger(cmCPackLog::LOG_DEBUG,
                   "- Creating directory: '" << dir << "'" << std::endl);
 
@@ -921,11 +939,11 @@
     }
   }
 
-  if (nullptr != mf.GetDefinition("CPACK_ABSOLUTE_DESTINATION_FILES")) {
+  if (auto d = mf.GetDefinition("CPACK_ABSOLUTE_DESTINATION_FILES")) {
     if (!absoluteDestFiles.empty()) {
       absoluteDestFiles += ";";
     }
-    absoluteDestFiles += mf.GetDefinition("CPACK_ABSOLUTE_DESTINATION_FILES");
+    absoluteDestFiles += d;
     cmCPackLogger(cmCPackLog::LOG_DEBUG,
                   "Got some ABSOLUTE DESTINATION FILES: " << absoluteDestFiles
                                                           << std::endl);
@@ -936,8 +954,7 @@
         GetComponentInstallDirNameSuffix(component);
       if (nullptr != this->GetOption(absoluteDestFileComponent)) {
         std::string absoluteDestFilesListComponent =
-          cmStrCat(this->GetOption(absoluteDestFileComponent), ';',
-                   mf.GetDefinition("CPACK_ABSOLUTE_DESTINATION_FILES"));
+          cmStrCat(this->GetOption(absoluteDestFileComponent), ';', d);
         this->SetOption(absoluteDestFileComponent,
                         absoluteDestFilesListComponent.c_str());
       } else {
@@ -966,7 +983,7 @@
                                          const char* value)
 {
   const char* def = this->MakefileMap->GetDefinition(op);
-  if (def && *def) {
+  if (cmNonempty(def)) {
     return;
   }
   this->SetOption(op, value);
@@ -1077,6 +1094,25 @@
       return 0;
     }
   }
+  // Run post-build actions
+  const char* postBuildScripts = this->GetOption("CPACK_POST_BUILD_SCRIPTS");
+  if (postBuildScripts) {
+    this->MakefileMap->AddDefinition("CPACK_PACKAGE_FILES",
+                                     cmJoin(this->packageFileNames, ";"));
+
+    const auto scripts = cmExpandedList(postBuildScripts, false);
+    for (const auto& script : scripts) {
+      cmCPackLogger(cmCPackLog::LOG_OUTPUT,
+                    "Executing post-build script: " << script << std::endl);
+
+      if (!this->MakefileMap->ReadListFile(script)) {
+        cmCPackLogger(cmCPackLog::LOG_ERROR,
+                      "The post-build script not found: " << script
+                                                          << std::endl);
+        return 0;
+      }
+    }
+  }
 
   /* Prepare checksum algorithm*/
   const char* algo = this->GetOption("CPACK_PACKAGE_CHECKSUM");
@@ -1179,7 +1215,7 @@
 bool cmCPackGenerator::IsSetToOff(const std::string& op) const
 {
   const char* ret = this->MakefileMap->GetDefinition(op);
-  if (ret && *ret) {
+  if (cmNonempty(ret)) {
     return cmIsOff(ret);
   }
   return false;
@@ -1290,7 +1326,7 @@
                                      bool copyOnly /* = false */)
 {
   return this->MakefileMap->ConfigureFile(inName, outName, copyOnly, true,
-                                          false) == 1;
+                                          false, true) == 1;
 }
 
 int cmCPackGenerator::CleanTemporaryDirectory()
@@ -1379,7 +1415,8 @@
           << std::endl);
   }
 
-  // if user specified packaging method, override the default packaging method
+  // if user specified packaging method, override the default packaging
+  // method
   if (method != UNKNOWN_COMPONENT_PACKAGE_METHOD) {
     componentPackageMethod = method;
   }
@@ -1472,7 +1509,7 @@
     installType->Name = name;
 
     const char* displayName = this->GetOption(macroPrefix + "_DISPLAY_NAME");
-    if (displayName && *displayName) {
+    if (cmNonempty(displayName)) {
       installType->DisplayName = displayName;
     } else {
       installType->DisplayName = installType->Name;
@@ -1494,7 +1531,7 @@
       "CPACK_COMPONENT_" + cmsys::SystemTools::UpperCase(name);
     component->Name = name;
     const char* displayName = this->GetOption(macroPrefix + "_DISPLAY_NAME");
-    if (displayName && *displayName) {
+    if (cmNonempty(displayName)) {
       component->DisplayName = displayName;
     } else {
       component->DisplayName = component->Name;
@@ -1506,17 +1543,17 @@
       cmIsOn(this->GetOption("CPACK_DOWNLOAD_ALL"));
 
     const char* archiveFile = this->GetOption(macroPrefix + "_ARCHIVE_FILE");
-    if (archiveFile && *archiveFile) {
+    if (cmNonempty(archiveFile)) {
       component->ArchiveFile = archiveFile;
     }
 
     const char* plist = this->GetOption(macroPrefix + "_PLIST");
-    if (plist && *plist) {
+    if (cmNonempty(plist)) {
       component->Plist = plist;
     }
 
     const char* groupName = this->GetOption(macroPrefix + "_GROUP");
-    if (groupName && *groupName) {
+    if (cmNonempty(groupName)) {
       component->Group = GetComponentGroup(projectName, groupName);
       component->Group->Components.push_back(component);
     } else {
@@ -1524,13 +1561,13 @@
     }
 
     const char* description = this->GetOption(macroPrefix + "_DESCRIPTION");
-    if (description && *description) {
+    if (cmNonempty(description)) {
       component->Description = description;
     }
 
     // Determine the installation types.
     const char* installTypes = this->GetOption(macroPrefix + "_INSTALL_TYPES");
-    if (installTypes && *installTypes) {
+    if (cmNonempty(installTypes)) {
       std::vector<std::string> installTypesVector =
         cmExpandedList(installTypes);
       for (std::string const& installType : installTypesVector) {
@@ -1541,7 +1578,7 @@
 
     // Determine the component dependencies.
     const char* depends = this->GetOption(macroPrefix + "_DEPENDS");
-    if (depends && *depends) {
+    if (cmNonempty(depends)) {
       std::vector<std::string> dependsVector = cmExpandedList(depends);
       for (std::string const& depend : dependsVector) {
         cmCPackComponent* child = GetComponent(projectName, depend);
@@ -1565,21 +1602,21 @@
     // Define the group
     group->Name = name;
     const char* displayName = this->GetOption(macroPrefix + "_DISPLAY_NAME");
-    if (displayName && *displayName) {
+    if (cmNonempty(displayName)) {
       group->DisplayName = displayName;
     } else {
       group->DisplayName = group->Name;
     }
 
     const char* description = this->GetOption(macroPrefix + "_DESCRIPTION");
-    if (description && *description) {
+    if (cmNonempty(description)) {
       group->Description = description;
     }
     group->IsBold = this->IsOn(macroPrefix + "_BOLD_TITLE");
     group->IsExpandedByDefault = this->IsOn(macroPrefix + "_EXPANDED");
     const char* parentGroupName =
       this->GetOption(macroPrefix + "_PARENT_GROUP");
-    if (parentGroupName && *parentGroupName) {
+    if (cmNonempty(parentGroupName)) {
       group->ParentGroup = GetComponentGroup(projectName, parentGroupName);
       group->ParentGroup->Subgroups.push_back(group);
     } else {
diff --git a/Source/CPack/cmCPackLog.cxx b/Source/CPack/cmCPackLog.cxx
index ca675fd..49e4113 100644
--- a/Source/CPack/cmCPackLog.cxx
+++ b/Source/CPack/cmCPackLog.cxx
@@ -4,54 +4,38 @@
 
 #include <iostream>
 
+#include <cm/memory>
+
 #include "cmGeneratedFileStream.h"
 #include "cmSystemTools.h"
 
 cmCPackLog::cmCPackLog()
 {
-  this->Verbose = false;
-  this->Debug = false;
-  this->Quiet = false;
-  this->NewLine = true;
-
-  this->LastTag = cmCPackLog::NOTAG;
   this->DefaultOutput = &std::cout;
   this->DefaultError = &std::cerr;
-
-  this->LogOutput = nullptr;
-  this->LogOutputCleanup = false;
 }
 
-cmCPackLog::~cmCPackLog()
-{
-  this->SetLogOutputStream(nullptr);
-}
+cmCPackLog::~cmCPackLog() = default;
 
 void cmCPackLog::SetLogOutputStream(std::ostream* os)
 {
-  if (this->LogOutputCleanup && this->LogOutput) {
-    delete this->LogOutput;
-  }
-  this->LogOutputCleanup = false;
+  this->LogOutputStream.reset();
   this->LogOutput = os;
 }
 
 bool cmCPackLog::SetLogOutputFile(const char* fname)
 {
-  cmGeneratedFileStream* cg = nullptr;
+  this->LogOutputStream.reset();
   if (fname) {
-    cg = new cmGeneratedFileStream(fname);
+    this->LogOutputStream = cm::make_unique<cmGeneratedFileStream>(fname);
   }
-  if (cg && !*cg) {
-    delete cg;
-    cg = nullptr;
+  if (this->LogOutputStream && !*this->LogOutputStream) {
+    this->LogOutputStream.reset();
   }
-  this->SetLogOutputStream(cg);
-  if (!cg) {
-    return false;
-  }
-  this->LogOutputCleanup = true;
-  return true;
+
+  this->LogOutput = this->LogOutputStream.get();
+
+  return this->LogOutput != nullptr;
 }
 
 void cmCPackLog::Log(int tag, const char* file, int line, const char* msg,
diff --git a/Source/CPack/cmCPackLog.h b/Source/CPack/cmCPackLog.h
index 1cb1643..68ffcce 100644
--- a/Source/CPack/cmCPackLog.h
+++ b/Source/CPack/cmCPackLog.h
@@ -5,6 +5,7 @@
 
 #include "cmConfigure.h" // IWYU pragma: keep
 
+#include <memory>
 #include <ostream>
 #include <string>
 
@@ -97,13 +98,13 @@
   void SetErrorPrefix(std::string const& pfx) { this->ErrorPrefix = pfx; }
 
 private:
-  bool Verbose;
-  bool Debug;
-  bool Quiet;
+  bool Verbose = false;
+  bool Debug = false;
+  bool Quiet = false;
 
-  bool NewLine;
+  bool NewLine = true;
 
-  int LastTag;
+  int LastTag = cmCPackLog::NOTAG;
 
   std::string Prefix;
   std::string OutputPrefix;
@@ -112,13 +113,11 @@
   std::string WarningPrefix;
   std::string ErrorPrefix;
 
-  std::ostream* DefaultOutput;
-  std::ostream* DefaultError;
+  std::ostream* DefaultOutput = nullptr;
+  std::ostream* DefaultError = nullptr;
 
-  std::string LogOutputFileName;
-  std::ostream* LogOutput;
-  // Do we need to cleanup log output stream
-  bool LogOutputCleanup;
+  std::ostream* LogOutput = nullptr;
+  std::unique_ptr<std::ostream> LogOutputStream;
 };
 
 class cmCPackLogWrite
diff --git a/Source/CPack/cmCPackNSISGenerator.cxx b/Source/CPack/cmCPackNSISGenerator.cxx
index 2a46627..2109b4e 100644
--- a/Source/CPack/cmCPackNSISGenerator.cxx
+++ b/Source/CPack/cmCPackNSISGenerator.cxx
@@ -9,10 +9,11 @@
 #include <sstream>
 #include <utility>
 
+#include <cmext/algorithm>
+
 #include "cmsys/Directory.hxx"
 #include "cmsys/RegularExpression.hxx"
 
-#include "cmAlgorithms.h"
 #include "cmCPackComponentGroup.h"
 #include "cmCPackGenerator.h"
 #include "cmCPackLog.h"
@@ -68,7 +69,7 @@
 
       // Use the custom component install directory if we have one
       if (pos != std::string::npos) {
-        const std::string componentName = fileN.substr(0, pos);
+        auto componentName = cm::string_view(fileN).substr(0, pos);
         outputDir = CustomComponentInstallDirectory(componentName);
       } else {
         outputDir = CustomComponentInstallDirectory(fileN);
@@ -103,7 +104,7 @@
         componentName = fileN.substr(0, slash);
 
         // Strip off the component part of the path.
-        fileN = fileN.substr(slash + 1);
+        fileN.erase(0, slash + 1);
       }
     }
     std::replace(fileN.begin(), fileN.end(), '/', '\\');
@@ -203,6 +204,11 @@
                             "!define MUI_FINISHPAGE_TITLE_3LINES");
   }
 
+  if (this->IsSet("CPACK_NSIS_MANIFEST_DPI_AWARE")) {
+    this->SetOptionIfNotSet("CPACK_NSIS_MANIFEST_DPI_AWARE_CODE",
+                            "ManifestDPIAware true");
+  }
+
   // Setup all of the component sections
   if (this->Components.empty()) {
     this->SetOptionIfNotSet("CPACK_NSIS_INSTALLATION_TYPES", "");
@@ -524,7 +530,7 @@
                 << ".lnk\"" << std::endl;
       // see if CPACK_CREATE_DESKTOP_LINK_ExeName is on
       // if so add a desktop link
-      if (cmContains(cpackPackageDesktopLinksVector, execName)) {
+      if (cm::contains(cpackPackageDesktopLinksVector, execName)) {
         str << "  StrCmp \"$INSTALL_DESKTOP\" \"1\" 0 +2\n";
         str << "    CreateShortCut \"$DESKTOP\\" << linkName
             << R"(.lnk" "$INSTDIR\)" << cpackNsisExecutablesDirectory << "\\"
@@ -672,7 +678,7 @@
 
   const std::string componentOutputDir =
     CustomComponentInstallDirectory(component->Name);
-  componentCode += "  SetOutPath \"" + componentOutputDir + "\"\n";
+  componentCode += cmStrCat("  SetOutPath \"", componentOutputDir, "\"\n");
 
   // Create the actual installation commands
   if (component->IsDownloaded) {
@@ -690,7 +696,7 @@
     const char* userUploadDirectory =
       this->GetOption("CPACK_UPLOAD_DIRECTORY");
     std::string uploadDirectory;
-    if (userUploadDirectory && *userUploadDirectory) {
+    if (cmNonempty(userUploadDirectory)) {
       uploadDirectory = userUploadDirectory;
     } else {
       uploadDirectory =
@@ -921,12 +927,11 @@
 }
 
 std::string cmCPackNSISGenerator::CustomComponentInstallDirectory(
-  const std::string& componentName)
+  cm::string_view componentName)
 {
-  const char* outputDir =
-    this->GetOption("CPACK_NSIS_" + componentName + "_INSTALL_DIRECTORY");
-  const std::string componentOutputDir = (outputDir ? outputDir : "$INSTDIR");
-  return componentOutputDir;
+  const char* outputDir = this->GetOption(
+    cmStrCat("CPACK_NSIS_", componentName, "_INSTALL_DIRECTORY"));
+  return outputDir ? outputDir : "$INSTDIR";
 }
 
 std::string cmCPackNSISGenerator::TranslateNewlines(std::string str)
diff --git a/Source/CPack/cmCPackNSISGenerator.h b/Source/CPack/cmCPackNSISGenerator.h
index 0af37af..88cba45 100644
--- a/Source/CPack/cmCPackNSISGenerator.h
+++ b/Source/CPack/cmCPackNSISGenerator.h
@@ -10,6 +10,8 @@
 #include <string>
 #include <vector>
 
+#include <cm/string_view>
+
 #include "cmCPackGenerator.h"
 
 class cmCPackComponent;
@@ -75,8 +77,7 @@
 
   /// Returns the custom install directory if available for the specified
   /// component, otherwise $INSTDIR is returned.
-  std::string CustomComponentInstallDirectory(
-    const std::string& componentName);
+  std::string CustomComponentInstallDirectory(cm::string_view componentName);
 
   /// Translations any newlines found in the string into \\r\\n, so that the
   /// resulting string can be used within NSIS.
diff --git a/Source/CPack/cpack.cxx b/Source/CPack/cpack.cxx
index dc31623..3a400b7 100644
--- a/Source/CPack/cpack.cxx
+++ b/Source/CPack/cpack.cxx
@@ -85,7 +85,7 @@
     return 0;
   }
   std::string key = value.substr(0, pos);
-  value = value.substr(pos + 1);
+  value.erase(0, pos + 1);
   def->Map[key] = value;
   cmCPack_Log(def->Log, cmCPackLog::LOG_DEBUG,
               "Set CPack variable: " << key << " to \"" << value << "\""
@@ -312,7 +312,7 @@
     // The value has not been set on the command line
     else {
       // get a default value (current working directory)
-      cpackProjectDirectory = cmsys::SystemTools::GetCurrentWorkingDirectory();
+      cpackProjectDirectory = cmSystemTools::GetCurrentWorkingDirectory();
       // use default value if no value has been provided by the config file
       if (!globalMF.IsSet("CPACK_PACKAGE_DIRECTORY")) {
         globalMF.AddDefinition("CPACK_PACKAGE_DIRECTORY",
diff --git a/Source/CTest/cmCTestBZR.cxx b/Source/CTest/cmCTestBZR.cxx
index c87fb83b..c533cd7 100644
--- a/Source/CTest/cmCTestBZR.cxx
+++ b/Source/CTest/cmCTestBZR.cxx
@@ -10,9 +10,9 @@
 
 #include <cmext/algorithm>
 
-#include "cmsys/RegularExpression.hxx"
+#include <cm3p/expat.h>
 
-#include "cm_expat.h"
+#include "cmsys/RegularExpression.hxx"
 
 #include "cmCTest.h"
 #include "cmCTestVC.h"
diff --git a/Source/CTest/cmCTestBuildAndTestHandler.cxx b/Source/CTest/cmCTestBuildAndTestHandler.cxx
index 5e29386..a18cbb4 100644
--- a/Source/CTest/cmCTestBuildAndTestHandler.cxx
+++ b/Source/CTest/cmCTestBuildAndTestHandler.cxx
@@ -182,10 +182,9 @@
     std::vector<std::string> extraPaths;
     std::vector<std::string> failed;
     fullPath = cmCTestTestHandler::FindExecutable(
-      this->CTest, this->ConfigSample.c_str(), resultingConfig, extraPaths,
-      failed);
+      this->CTest, this->ConfigSample, resultingConfig, extraPaths, failed);
     if (!fullPath.empty() && !resultingConfig.empty()) {
-      this->CTest->SetConfigType(resultingConfig.c_str());
+      this->CTest->SetConfigType(resultingConfig);
     }
     out << "Using config sample with results: " << fullPath << " and "
         << resultingConfig << std::endl;
@@ -296,9 +295,8 @@
     extraPaths.push_back(tempPath);
   }
   std::vector<std::string> failed;
-  fullPath =
-    cmCTestTestHandler::FindExecutable(this->CTest, this->TestCommand.c_str(),
-                                       resultingConfig, extraPaths, failed);
+  fullPath = cmCTestTestHandler::FindExecutable(
+    this->CTest, this->TestCommand, resultingConfig, extraPaths, failed);
 
   if (!cmSystemTools::FileExists(fullPath)) {
     out << "Could not find path to executable, perhaps it was not built: "
@@ -379,7 +377,7 @@
   const std::vector<std::string>& allArgs)
 {
   // --build-and-test options
-  if (currentArg.find("--build-and-test", 0) == 0 &&
+  if (cmHasLiteralPrefix(currentArg, "--build-and-test") &&
       idx < allArgs.size() - 1) {
     if (idx + 2 < allArgs.size()) {
       idx++;
@@ -397,25 +395,29 @@
       return 0;
     }
   }
-  if (currentArg.find("--build-target", 0) == 0 && idx < allArgs.size() - 1) {
+  if (cmHasLiteralPrefix(currentArg, "--build-target") &&
+      idx < allArgs.size() - 1) {
     idx++;
     this->BuildTargets.push_back(allArgs[idx]);
   }
-  if (currentArg.find("--build-nocmake", 0) == 0) {
+  if (cmHasLiteralPrefix(currentArg, "--build-nocmake")) {
     this->BuildNoCMake = true;
   }
-  if (currentArg.find("--build-run-dir", 0) == 0 && idx < allArgs.size() - 1) {
+  if (cmHasLiteralPrefix(currentArg, "--build-run-dir") &&
+      idx < allArgs.size() - 1) {
     idx++;
     this->BuildRunDir = allArgs[idx];
   }
-  if (currentArg.find("--build-two-config", 0) == 0) {
+  if (cmHasLiteralPrefix(currentArg, "--build-two-config")) {
     this->BuildTwoConfig = true;
   }
-  if (currentArg.find("--build-exe-dir", 0) == 0 && idx < allArgs.size() - 1) {
+  if (cmHasLiteralPrefix(currentArg, "--build-exe-dir") &&
+      idx < allArgs.size() - 1) {
     idx++;
     this->ExecutableDirectory = allArgs[idx];
   }
-  if (currentArg.find("--test-timeout", 0) == 0 && idx < allArgs.size() - 1) {
+  if (cmHasLiteralPrefix(currentArg, "--test-timeout") &&
+      idx < allArgs.size() - 1) {
     idx++;
     this->Timeout = cmDuration(atof(allArgs[idx].c_str()));
   }
@@ -431,31 +433,33 @@
     idx++;
     this->BuildGeneratorToolset = allArgs[idx];
   }
-  if (currentArg.find("--build-project", 0) == 0 && idx < allArgs.size() - 1) {
+  if (cmHasLiteralPrefix(currentArg, "--build-project") &&
+      idx < allArgs.size() - 1) {
     idx++;
     this->BuildProject = allArgs[idx];
   }
-  if (currentArg.find("--build-makeprogram", 0) == 0 &&
+  if (cmHasLiteralPrefix(currentArg, "--build-makeprogram") &&
       idx < allArgs.size() - 1) {
     idx++;
     this->BuildMakeProgram = allArgs[idx];
   }
-  if (currentArg.find("--build-config-sample", 0) == 0 &&
+  if (cmHasLiteralPrefix(currentArg, "--build-config-sample") &&
       idx < allArgs.size() - 1) {
     idx++;
     this->ConfigSample = allArgs[idx];
   }
-  if (currentArg.find("--build-noclean", 0) == 0) {
+  if (cmHasLiteralPrefix(currentArg, "--build-noclean")) {
     this->BuildNoClean = true;
   }
-  if (currentArg.find("--build-options", 0) == 0) {
+  if (cmHasLiteralPrefix(currentArg, "--build-options")) {
     while (idx + 1 < allArgs.size() && allArgs[idx + 1] != "--build-target" &&
            allArgs[idx + 1] != "--test-command") {
       ++idx;
       this->BuildOptions.push_back(allArgs[idx]);
     }
   }
-  if (currentArg.find("--test-command", 0) == 0 && idx < allArgs.size() - 1) {
+  if (cmHasLiteralPrefix(currentArg, "--test-command") &&
+      idx < allArgs.size() - 1) {
     ++idx;
     this->TestCommand = allArgs[idx];
     while (idx + 1 < allArgs.size()) {
diff --git a/Source/CTest/cmCTestBuildCommand.cxx b/Source/CTest/cmCTestBuildCommand.cxx
index d1b7701..8aab167 100644
--- a/Source/CTest/cmCTestBuildCommand.cxx
+++ b/Source/CTest/cmCTestBuildCommand.cxx
@@ -5,13 +5,14 @@
 #include <cstring>
 #include <sstream>
 
-#include "cm_static_string_view.hxx"
+#include <cmext/string_view>
 
 #include "cmCTest.h"
 #include "cmCTestBuildHandler.h"
 #include "cmGlobalGenerator.h"
 #include "cmMakefile.h"
 #include "cmMessageType.h"
+#include "cmProperty.h"
 #include "cmStringAlgorithms.h"
 #include "cmSystemTools.h"
 #include "cmake.h"
@@ -38,10 +39,9 @@
 
   this->Handler = handler;
 
-  const char* ctestBuildCommand =
-    this->Makefile->GetDefinition("CTEST_BUILD_COMMAND");
-  if (ctestBuildCommand && *ctestBuildCommand) {
-    this->CTest->SetCTestConfiguration("MakeCommand", ctestBuildCommand,
+  cmProp ctestBuildCommand = this->Makefile->GetDef("CTEST_BUILD_COMMAND");
+  if (cmNonempty(ctestBuildCommand)) {
+    this->CTest->SetCTestConfiguration("MakeCommand", *ctestBuildCommand,
                                        this->Quiet);
   } else {
     const char* cmakeGeneratorName =
@@ -56,7 +56,7 @@
       this->Makefile->GetDefinition("CTEST_BUILD_CONFIGURATION");
     const char* cmakeBuildConfiguration = !this->Configuration.empty()
       ? this->Configuration.c_str()
-      : ((ctestBuildConfiguration && *ctestBuildConfiguration)
+      : (cmNonempty(ctestBuildConfiguration)
            ? ctestBuildConfiguration
            : this->CTest->GetConfigType().c_str());
 
@@ -67,7 +67,7 @@
       ? this->Target.c_str()
       : this->Makefile->GetDefinition("CTEST_BUILD_TARGET");
 
-    if (cmakeGeneratorName && *cmakeGeneratorName) {
+    if (cmNonempty(cmakeGeneratorName)) {
       if (!cmakeBuildConfiguration) {
         cmakeBuildConfiguration = "Release";
       }
@@ -108,7 +108,7 @@
       cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
                          "SetMakeCommand:" << buildCommand << "\n",
                          this->Quiet);
-      this->CTest->SetCTestConfiguration("MakeCommand", buildCommand.c_str(),
+      this->CTest->SetCTestConfiguration("MakeCommand", buildCommand,
                                          this->Quiet);
     } else {
       std::ostringstream ostr;
@@ -123,16 +123,15 @@
     }
   }
 
-  if (const char* useLaunchers =
-        this->Makefile->GetDefinition("CTEST_USE_LAUNCHERS")) {
-    this->CTest->SetCTestConfiguration("UseLaunchers", useLaunchers,
+  if (cmProp useLaunchers = this->Makefile->GetDef("CTEST_USE_LAUNCHERS")) {
+    this->CTest->SetCTestConfiguration("UseLaunchers", *useLaunchers,
                                        this->Quiet);
   }
 
-  if (const char* labelsForSubprojects =
-        this->Makefile->GetDefinition("CTEST_LABELS_FOR_SUBPROJECTS")) {
+  if (cmProp labelsForSubprojects =
+        this->Makefile->GetDef("CTEST_LABELS_FOR_SUBPROJECTS")) {
     this->CTest->SetCTestConfiguration("LabelsForSubprojects",
-                                       labelsForSubprojects, this->Quiet);
+                                       *labelsForSubprojects, this->Quiet);
   }
 
   handler->SetQuiet(this->Quiet);
diff --git a/Source/CTest/cmCTestBuildHandler.cxx b/Source/CTest/cmCTestBuildHandler.cxx
index 03a3fd3..35c2b11 100644
--- a/Source/CTest/cmCTestBuildHandler.cxx
+++ b/Source/CTest/cmCTestBuildHandler.cxx
@@ -386,24 +386,20 @@
   if (this->CTest->GetCTestConfiguration("SourceDirectory").size() > 20) {
     std::string srcdir =
       this->CTest->GetCTestConfiguration("SourceDirectory") + "/";
-    for (cc = srcdir.size() - 2; cc > 0; cc--) {
-      if (srcdir[cc] == '/') {
-        srcdir = srcdir.substr(0, cc + 1);
-        break;
-      }
+    cc = srcdir.rfind('/', srcdir.size() - 2);
+    if (cc != std::string::npos) {
+      srcdir.resize(cc + 1);
+      this->SimplifySourceDir = std::move(srcdir);
     }
-    this->SimplifySourceDir = srcdir;
   }
   if (this->CTest->GetCTestConfiguration("BuildDirectory").size() > 20) {
     std::string bindir =
       this->CTest->GetCTestConfiguration("BuildDirectory") + "/";
-    for (cc = bindir.size() - 2; cc > 0; cc--) {
-      if (bindir[cc] == '/') {
-        bindir = bindir.substr(0, cc + 1);
-        break;
-      }
+    cc = bindir.rfind('/', bindir.size() - 2);
+    if (cc != std::string::npos) {
+      bindir.resize(cc + 1);
+      this->SimplifyBuildDir = std::move(bindir);
     }
-    this->SimplifyBuildDir = bindir;
   }
 
   // Ok, let's do the build
@@ -545,11 +541,11 @@
     const char* fname = launchDir.GetFile(i);
     if (this->IsLaunchedErrorFile(fname) && numErrorsAllowed) {
       numErrorsAllowed--;
-      fragments.insert(this->CTestLaunchDir + "/" + fname);
+      fragments.insert(this->CTestLaunchDir + '/' + fname);
       ++this->TotalErrors;
     } else if (this->IsLaunchedWarningFile(fname) && numWarningsAllowed) {
       numWarningsAllowed--;
-      fragments.insert(this->CTestLaunchDir + "/" + fname);
+      fragments.insert(this->CTestLaunchDir + '/' + fname);
       ++this->TotalWarnings;
     }
   }
diff --git a/Source/CTest/cmCTestCVS.cxx b/Source/CTest/cmCTestCVS.cxx
index 45ec390..1209e06 100644
--- a/Source/CTest/cmCTestCVS.cxx
+++ b/Source/CTest/cmCTestCVS.cxx
@@ -152,10 +152,12 @@
         this->FinishRevision();
       }
     } else if (this->Section == SectionRevisions) {
+      // XXX(clang-tidy): https://bugs.llvm.org/show_bug.cgi?id=44165
+      // NOLINTNEXTLINE(bugprone-branch-clone)
       if (!this->Rev.Log.empty()) {
         // Continue the existing log.
         this->Rev.Log += this->Line;
-        this->Rev.Log += "\n";
+        this->Rev.Log += '\n';
       } else if (this->Rev.Rev.empty() &&
                  this->RegexRevision.find(this->Line)) {
         this->Rev.Rev = this->RegexRevision.match(1);
@@ -166,7 +168,7 @@
       } else if (!this->RegexBranches.find(this->Line)) {
         // Start the log.
         this->Rev.Log += this->Line;
-        this->Rev.Log += "\n";
+        this->Rev.Log += '\n';
       }
     }
     return this->Section != SectionEnd;
diff --git a/Source/CTest/cmCTestConfigureCommand.cxx b/Source/CTest/cmCTestConfigureCommand.cxx
index 3854710..ac57130 100644
--- a/Source/CTest/cmCTestConfigureCommand.cxx
+++ b/Source/CTest/cmCTestConfigureCommand.cxx
@@ -6,12 +6,13 @@
 #include <sstream>
 #include <vector>
 
-#include "cm_static_string_view.hxx"
+#include <cmext/string_view>
 
 #include "cmCTest.h"
 #include "cmCTestConfigureHandler.h"
 #include "cmGlobalGenerator.h"
 #include "cmMakefile.h"
+#include "cmProperty.h"
 #include "cmStringAlgorithms.h"
 #include "cmSystemTools.h"
 #include "cmake.h"
@@ -38,16 +39,16 @@
     return nullptr;
   }
 
-  const char* ctestConfigureCommand =
-    this->Makefile->GetDefinition("CTEST_CONFIGURE_COMMAND");
+  cmProp ctestConfigureCommand =
+    this->Makefile->GetDef("CTEST_CONFIGURE_COMMAND");
 
-  if (ctestConfigureCommand && *ctestConfigureCommand) {
+  if (cmNonempty(ctestConfigureCommand)) {
     this->CTest->SetCTestConfiguration("ConfigureCommand",
-                                       ctestConfigureCommand, this->Quiet);
+                                       *ctestConfigureCommand, this->Quiet);
   } else {
     const char* cmakeGeneratorName =
       this->Makefile->GetDefinition("CTEST_CMAKE_GENERATOR");
-    if (cmakeGeneratorName && *cmakeGeneratorName) {
+    if (cmNonempty(cmakeGeneratorName)) {
       const std::string& source_dir =
         this->CTest->GetCTestConfiguration("SourceDirectory");
       if (source_dir.empty()) {
@@ -107,7 +108,7 @@
 
       const char* cmakeGeneratorPlatform =
         this->Makefile->GetDefinition("CTEST_CMAKE_GENERATOR_PLATFORM");
-      if (cmakeGeneratorPlatform && *cmakeGeneratorPlatform) {
+      if (cmNonempty(cmakeGeneratorPlatform)) {
         cmakeConfigureCommand += " \"-A";
         cmakeConfigureCommand += cmakeGeneratorPlatform;
         cmakeConfigureCommand += "\"";
@@ -115,7 +116,7 @@
 
       const char* cmakeGeneratorToolset =
         this->Makefile->GetDefinition("CTEST_CMAKE_GENERATOR_TOOLSET");
-      if (cmakeGeneratorToolset && *cmakeGeneratorToolset) {
+      if (cmNonempty(cmakeGeneratorToolset)) {
         cmakeConfigureCommand += " \"-T";
         cmakeConfigureCommand += cmakeGeneratorToolset;
         cmakeConfigureCommand += "\"";
@@ -125,8 +126,8 @@
       cmakeConfigureCommand += source_dir;
       cmakeConfigureCommand += "\"";
 
-      this->CTest->SetCTestConfiguration(
-        "ConfigureCommand", cmakeConfigureCommand.c_str(), this->Quiet);
+      this->CTest->SetCTestConfiguration("ConfigureCommand",
+                                         cmakeConfigureCommand, this->Quiet);
     } else {
       this->SetError(
         "Configure command is not specified. If this is a "
@@ -136,10 +137,10 @@
     }
   }
 
-  if (const char* labelsForSubprojects =
-        this->Makefile->GetDefinition("CTEST_LABELS_FOR_SUBPROJECTS")) {
+  if (cmProp labelsForSubprojects =
+        this->Makefile->GetDef("CTEST_LABELS_FOR_SUBPROJECTS")) {
     this->CTest->SetCTestConfiguration("LabelsForSubprojects",
-                                       labelsForSubprojects, this->Quiet);
+                                       *labelsForSubprojects, this->Quiet);
   }
 
   cmCTestConfigureHandler* handler = this->CTest->GetConfigureHandler();
diff --git a/Source/CTest/cmCTestCoverageCommand.cxx b/Source/CTest/cmCTestCoverageCommand.cxx
index d6e6be3..7432d08 100644
--- a/Source/CTest/cmCTestCoverageCommand.cxx
+++ b/Source/CTest/cmCTestCoverageCommand.cxx
@@ -4,9 +4,9 @@
 
 #include <set>
 
-#include "cm_static_string_view.hxx"
+#include <cmext/algorithm>
+#include <cmext/string_view>
 
-#include "cmAlgorithms.h"
 #include "cmCTest.h"
 #include "cmCTestCoverageHandler.h"
 
@@ -22,7 +22,7 @@
   std::vector<std::string> const& keywords)
 {
   this->LabelsMentioned =
-    !this->Labels.empty() || cmContains(keywords, "LABELS");
+    !this->Labels.empty() || cm::contains(keywords, "LABELS");
 }
 
 cmCTestGenericHandler* cmCTestCoverageCommand::InitializeHandler()
diff --git a/Source/CTest/cmCTestCoverageHandler.cxx b/Source/CTest/cmCTestCoverageHandler.cxx
index 2c8f119..093b2d1 100644
--- a/Source/CTest/cmCTestCoverageHandler.cxx
+++ b/Source/CTest/cmCTestCoverageHandler.cxx
@@ -469,8 +469,8 @@
     }
 
     const std::string fileName = cmSystemTools::GetFilenameName(fullFileName);
-    std::string shortFileName =
-      this->CTest->GetShortPathToFile(fullFileName.c_str());
+    const std::string shortFileName =
+      this->CTest->GetShortPathToFile(fullFileName);
     const cmCTestCoverageHandlerContainer::SingleFileCoverageVector& fcov =
       file.second;
     covLogXML.StartElement("File");
@@ -538,7 +538,7 @@
     covSumXML.StartElement("File");
     covSumXML.Attribute("Name", fileName);
     covSumXML.Attribute("FullPath",
-                        this->CTest->GetShortPathToFile(fullFileName.c_str()));
+                        this->CTest->GetShortPathToFile(fullFileName));
     covSumXML.Attribute("Covered", tested + untested > 0 ? "true" : "false");
     covSumXML.Element("LOCTested", tested);
     covSumXML.Element("LOCUnTested", untested);
@@ -680,8 +680,9 @@
 //
 #ifdef _WIN32
 #  define fnc(s) cmSystemTools::LowerCase(s)
+#  define fnc_prefix(s, t) fnc(s.substr(0, t.size())) == fnc(t)
 #else
-#  define fnc(s) s
+#  define fnc_prefix(s, t) cmHasPrefix(s, t)
 #endif
 
 bool IsFileInDir(const std::string& infile, const std::string& indir)
@@ -689,8 +690,8 @@
   std::string file = cmSystemTools::CollapseFullPath(infile);
   std::string dir = cmSystemTools::CollapseFullPath(indir);
 
-  return file.size() > dir.size() &&
-    fnc(file.substr(0, dir.size())) == fnc(dir) && file[dir.size()] == '/';
+  return file.size() > dir.size() && fnc_prefix(file, dir) &&
+    file[dir.size()] == '/';
 }
 
 int cmCTestCoverageHandler::HandlePHPCoverage(
@@ -1214,8 +1215,6 @@
           while (cmSystemTools::GetLineFromStream(ifile, nl)) {
             cnt++;
 
-            // TODO: Handle gcov 3.0 non-coverage lines
-
             // Skip empty lines
             if (nl.empty()) {
               continue;
@@ -1226,6 +1225,14 @@
               continue;
             }
 
+            // Handle gcov 3.0 non-coverage lines
+            // non-coverage lines seem to always start with something not
+            // a space and don't have a ':' in the 9th position
+            // TODO: Verify that this is actually a robust metric
+            if (nl[0] != ' ' && nl[9] != ':') {
+              continue;
+            }
+
             // Read the coverage count from the beginning of the gcov output
             // line
             std::string prefix = nl.substr(0, 12);
@@ -1709,29 +1716,26 @@
 
         // Read the coverage count from the beginning of the Trace.py output
         // line
-        std::string prefix = nl.substr(0, 6);
-        if (prefix[5] != ' ' && prefix[5] != ':') {
-          // This is a hack. We should really do something more elaborate
-          prefix = nl.substr(0, 7);
-          if (prefix[6] != ' ' && prefix[6] != ':') {
-            prefix = nl.substr(0, 8);
-            if (prefix[7] != ' ' && prefix[7] != ':') {
-              cmCTestLog(this->CTest, ERROR_MESSAGE,
-                         "Currently the limit is maximum coverage of 999999"
-                           << std::endl);
-            }
+        std::string::size_type pos;
+        int cov = 0;
+        // This is a hack. We should really do something more elaborate
+        for (pos = 5; pos < 8; pos++) {
+          if (nl[pos] == ' ') {
+            // This line does not have ':' so no coverage here. That said,
+            // Trace.py does not handle not covered lines versus comments etc.
+            // So, this will be set to 0.
+            break;
+          }
+          if (nl[pos] == ':') {
+            cov = atoi(nl.substr(0, pos - 1).c_str());
+            break;
           }
         }
-        int cov = atoi(prefix.c_str());
-        if (prefix[prefix.size() - 1] != ':') {
-          // This line does not have ':' so no coverage here. That said,
-          // Trace.py does not handle not covered lines versus comments etc.
-          // So, this will be set to 0.
-          cov = 0;
+        if (pos == 8) {
+          cmCTestLog(this->CTest, ERROR_MESSAGE,
+                     "Currently the limit is maximum coverage of 999999"
+                       << std::endl);
         }
-        cmCTestOptionalLog(
-          this->CTest, DEBUG,
-          "Prefix: " << prefix << " cov: " << cov << std::endl, this->Quiet);
         // Read the line number starting at the 10th character of the gcov
         // output line
         long lineIdx = cnt;
@@ -1883,8 +1887,8 @@
         // start the file output
         covLogXML.StartElement("File");
         covLogXML.Attribute("Name", i->first);
-        covLogXML.Attribute(
-          "FullPath", this->CTest->GetShortPathToFile(i->second.c_str()));
+        covLogXML.Attribute("FullPath",
+                            this->CTest->GetShortPathToFile(i->second));
         covLogXML.StartElement("Report");
         // write the bullseye header
         line = 0;
@@ -2060,8 +2064,7 @@
       total_untested += (totalFunctions - functionsCalled);
 
       std::string fileName = cmSystemTools::GetFilenameName(file);
-      std::string shortFileName =
-        this->CTest->GetShortPathToFile(file.c_str());
+      std::string shortFileName = this->CTest->GetShortPathToFile(file);
 
       float cper = static_cast<float>(percentBranch + percentFunction);
       if (totalBranches > 0) {
@@ -2262,7 +2265,7 @@
       // is the end of the target-wide labels.
       inTarget = false;
 
-      source = this->CTest->GetShortPathToFile(line.c_str());
+      source = this->CTest->GetShortPathToFile(line);
 
       // Label the source with the target labels.
       LabelSet& labelSet = this->SourceLabels[source];
@@ -2316,7 +2319,7 @@
 
   // The source is filtered out if it does not have any labels in
   // common with the filter set.
-  std::string shortSrc = this->CTest->GetShortPathToFile(source.c_str());
+  std::string shortSrc = this->CTest->GetShortPathToFile(source);
   auto li = this->SourceLabels.find(shortSrc);
   if (li != this->SourceLabels.end()) {
     return !this->IntersectsFilter(li->second);
@@ -2338,14 +2341,14 @@
     std::vector<std::string> files = gl.GetFiles();
     for (std::string const& f : files) {
       if (this->ShouldIDoCoverage(f, cont->SourceDir, cont->BinaryDir)) {
-        extraMatches.insert(this->CTest->GetShortPathToFile(f.c_str()));
+        extraMatches.insert(this->CTest->GetShortPathToFile(f));
       }
     }
   }
 
   if (!extraMatches.empty()) {
     for (auto const& i : cont->TotalCoverage) {
-      std::string shortPath = this->CTest->GetShortPathToFile(i.first.c_str());
+      std::string shortPath = this->CTest->GetShortPathToFile(i.first);
       extraMatches.erase(shortPath);
     }
   }
diff --git a/Source/CTest/cmCTestCurl.h b/Source/CTest/cmCTestCurl.h
index 9c5ba66..b0d7f07 100644
--- a/Source/CTest/cmCTestCurl.h
+++ b/Source/CTest/cmCTestCurl.h
@@ -8,7 +8,7 @@
 #include <string>
 #include <vector>
 
-#include "cm_curl.h"
+#include <cm3p/curl/curl.h>
 
 class cmCTest;
 
diff --git a/Source/CTest/cmCTestGIT.cxx b/Source/CTest/cmCTestGIT.cxx
index 3f3c107..568b091 100644
--- a/Source/CTest/cmCTestGIT.cxx
+++ b/Source/CTest/cmCTestGIT.cxx
@@ -6,6 +6,7 @@
 #include <cstdio>
 #include <cstdlib>
 #include <ctime>
+#include <utility>
 #include <vector>
 
 #include "cmsys/FStream.hxx"
@@ -193,7 +194,8 @@
       if (line.find("\tnot-for-merge\t") == std::string::npos) {
         std::string::size_type pos = line.find('\t');
         if (pos != std::string::npos) {
-          sha1 = line.substr(0, pos);
+          sha1 = std::move(line);
+          sha1.resize(pos);
         }
       }
     }
diff --git a/Source/CTest/cmCTestGenericHandler.cxx b/Source/CTest/cmCTestGenericHandler.cxx
index cc0b4ed..a71f550 100644
--- a/Source/CTest/cmCTestGenericHandler.cxx
+++ b/Source/CTest/cmCTestGenericHandler.cxx
@@ -100,7 +100,7 @@
                                                     << std::endl);
     return false;
   }
-  this->CTest->AddSubmitFile(part, ostr.str().c_str());
+  this->CTest->AddSubmitFile(part, ostr.str());
   return true;
 }
 
diff --git a/Source/CTest/cmCTestHandlerCommand.cxx b/Source/CTest/cmCTestHandlerCommand.cxx
index b1034c9..03b7173 100644
--- a/Source/CTest/cmCTestHandlerCommand.cxx
+++ b/Source/CTest/cmCTestHandlerCommand.cxx
@@ -7,13 +7,14 @@
 #include <cstring>
 #include <sstream>
 
-#include "cm_static_string_view.hxx"
+#include <cmext/string_view>
 
 #include "cmCTest.h"
 #include "cmCTestGenericHandler.h"
 #include "cmExecutionStatus.h"
 #include "cmMakefile.h"
 #include "cmMessageType.h"
+#include "cmProperty.h"
 #include "cmStringAlgorithms.h"
 #include "cmSystemTools.h"
 #include "cmWorkingDirectory.h"
@@ -125,23 +126,21 @@
   // CTEST_CONFIGURATION_TYPE script variable if it is defined.
   // The current script value trumps the -C argument on the command
   // line.
-  const char* ctestConfigType =
-    this->Makefile->GetDefinition("CTEST_CONFIGURATION_TYPE");
+  cmProp ctestConfigType = this->Makefile->GetDef("CTEST_CONFIGURATION_TYPE");
   if (ctestConfigType) {
-    this->CTest->SetConfigType(ctestConfigType);
+    this->CTest->SetConfigType(*ctestConfigType);
   }
 
   if (!this->Build.empty()) {
     this->CTest->SetCTestConfiguration(
-      "BuildDirectory", cmSystemTools::CollapseFullPath(this->Build).c_str(),
+      "BuildDirectory", cmSystemTools::CollapseFullPath(this->Build),
       this->Quiet);
   } else {
     std::string const& bdir =
       this->Makefile->GetSafeDefinition("CTEST_BINARY_DIRECTORY");
     if (!bdir.empty()) {
       this->CTest->SetCTestConfiguration(
-        "BuildDirectory", cmSystemTools::CollapseFullPath(bdir).c_str(),
-        this->Quiet);
+        "BuildDirectory", cmSystemTools::CollapseFullPath(bdir), this->Quiet);
     } else {
       cmCTestLog(this->CTest, ERROR_MESSAGE,
                  "CTEST_BINARY_DIRECTORY not set" << std::endl;);
@@ -151,20 +150,18 @@
     cmCTestLog(this->CTest, DEBUG,
                "Set source directory to: " << this->Source << std::endl);
     this->CTest->SetCTestConfiguration(
-      "SourceDirectory", cmSystemTools::CollapseFullPath(this->Source).c_str(),
+      "SourceDirectory", cmSystemTools::CollapseFullPath(this->Source),
       this->Quiet);
   } else {
     this->CTest->SetCTestConfiguration(
       "SourceDirectory",
       cmSystemTools::CollapseFullPath(
-        this->Makefile->GetSafeDefinition("CTEST_SOURCE_DIRECTORY"))
-        .c_str(),
+        this->Makefile->GetSafeDefinition("CTEST_SOURCE_DIRECTORY")),
       this->Quiet);
   }
 
-  if (const char* changeId =
-        this->Makefile->GetDefinition("CTEST_CHANGE_ID")) {
-    this->CTest->SetCTestConfiguration("ChangeId", changeId, this->Quiet);
+  if (cmProp changeId = this->Makefile->GetDef("CTEST_CHANGE_ID")) {
+    this->CTest->SetCTestConfiguration("ChangeId", *changeId, this->Quiet);
   }
 
   cmCTestLog(this->CTest, DEBUG, "Initialize handler" << std::endl;);
diff --git a/Source/CTest/cmCTestMemCheckCommand.cxx b/Source/CTest/cmCTestMemCheckCommand.cxx
index 39dec6d..d0e2974 100644
--- a/Source/CTest/cmCTestMemCheckCommand.cxx
+++ b/Source/CTest/cmCTestMemCheckCommand.cxx
@@ -2,7 +2,7 @@
    file Copyright.txt or https://cmake.org/licensing for details.  */
 #include "cmCTestMemCheckCommand.h"
 
-#include "cm_static_string_view.hxx"
+#include <cmext/string_view>
 
 #include "cmCTest.h"
 #include "cmCTestMemCheckHandler.h"
diff --git a/Source/CTest/cmCTestMemCheckHandler.cxx b/Source/CTest/cmCTestMemCheckHandler.cxx
index c1ecaf1..8b31e4b 100644
--- a/Source/CTest/cmCTestMemCheckHandler.cxx
+++ b/Source/CTest/cmCTestMemCheckHandler.cxx
@@ -10,11 +10,12 @@
 #include <sstream>
 #include <utility>
 
+#include <cmext/algorithm>
+
 #include "cmsys/FStream.hxx"
 #include "cmsys/Glob.hxx"
 #include "cmsys/RegularExpression.hxx"
 
-#include "cmAlgorithms.h"
 #include "cmCTest.h"
 #include "cmDuration.h"
 #include "cmSystemTools.h"
@@ -297,9 +298,6 @@
 
   this->CTest->PopulateCustomVector(mf, "CTEST_CUSTOM_MEMCHECK_IGNORE",
                                     this->CustomTestsIgnore);
-  std::string cmake = cmSystemTools::GetCMakeCommand();
-  this->CTest->SetCTestConfiguration("CMakeCommand", cmake.c_str(),
-                                     this->Quiet);
 }
 
 int cmCTestMemCheckHandler::GetDefectCount()
@@ -328,6 +326,9 @@
     case cmCTestMemCheckHandler::BOUNDS_CHECKER:
       xml.Attribute("Checker", "BoundsChecker");
       break;
+    case cmCTestMemCheckHandler::CUDA_MEMCHECK:
+      xml.Attribute("Checker", "CudaMemcheck");
+      break;
     case cmCTestMemCheckHandler::ADDRESS_SANITIZER:
       xml.Attribute("Checker", "AddressSanitizer");
       break;
@@ -353,7 +354,7 @@
   cmCTestMemCheckHandler::TestResultsVector::size_type cc;
   for (cmCTestTestResult const& result : this->TestResults) {
     std::string testPath = result.Path + "/" + result.Name;
-    xml.Element("Test", this->CTest->GetShortPathToFile(testPath.c_str()));
+    xml.Element("Test", this->CTest->GetShortPathToFile(testPath));
   }
   xml.EndElement(); // TestList
   cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT,
@@ -467,6 +468,8 @@
       this->MemoryTesterStyle = cmCTestMemCheckHandler::PURIFY;
     } else if (testerName.find("BC") != std::string::npos) {
       this->MemoryTesterStyle = cmCTestMemCheckHandler::BOUNDS_CHECKER;
+    } else if (testerName.find("cuda-memcheck") != std::string::npos) {
+      this->MemoryTesterStyle = cmCTestMemCheckHandler::CUDA_MEMCHECK;
     } else {
       this->MemoryTesterStyle = cmCTestMemCheckHandler::UNKNOWN;
     }
@@ -487,34 +490,39 @@
     this->MemoryTester =
       this->CTest->GetCTestConfiguration("BoundsCheckerCommand");
     this->MemoryTesterStyle = cmCTestMemCheckHandler::BOUNDS_CHECKER;
+  } else if (cmSystemTools::FileExists(
+               this->CTest->GetCTestConfiguration("CudaMemcheckCommand"))) {
+    this->MemoryTester =
+      this->CTest->GetCTestConfiguration("CudaMemcheckCommand");
+    this->MemoryTesterStyle = cmCTestMemCheckHandler::CUDA_MEMCHECK;
   }
   if (this->CTest->GetCTestConfiguration("MemoryCheckType") ==
       "AddressSanitizer") {
-    this->MemoryTester = this->CTest->GetCTestConfiguration("CMakeCommand");
+    this->MemoryTester = cmSystemTools::GetCMakeCommand();
     this->MemoryTesterStyle = cmCTestMemCheckHandler::ADDRESS_SANITIZER;
     this->LogWithPID = true; // even if we give the log file the pid is added
   }
   if (this->CTest->GetCTestConfiguration("MemoryCheckType") ==
       "LeakSanitizer") {
-    this->MemoryTester = this->CTest->GetCTestConfiguration("CMakeCommand");
+    this->MemoryTester = cmSystemTools::GetCMakeCommand();
     this->MemoryTesterStyle = cmCTestMemCheckHandler::LEAK_SANITIZER;
     this->LogWithPID = true; // even if we give the log file the pid is added
   }
   if (this->CTest->GetCTestConfiguration("MemoryCheckType") ==
       "ThreadSanitizer") {
-    this->MemoryTester = this->CTest->GetCTestConfiguration("CMakeCommand");
+    this->MemoryTester = cmSystemTools::GetCMakeCommand();
     this->MemoryTesterStyle = cmCTestMemCheckHandler::THREAD_SANITIZER;
     this->LogWithPID = true; // even if we give the log file the pid is added
   }
   if (this->CTest->GetCTestConfiguration("MemoryCheckType") ==
       "MemorySanitizer") {
-    this->MemoryTester = this->CTest->GetCTestConfiguration("CMakeCommand");
+    this->MemoryTester = cmSystemTools::GetCMakeCommand();
     this->MemoryTesterStyle = cmCTestMemCheckHandler::MEMORY_SANITIZER;
     this->LogWithPID = true; // even if we give the log file the pid is added
   }
   if (this->CTest->GetCTestConfiguration("MemoryCheckType") ==
       "UndefinedBehaviorSanitizer") {
-    this->MemoryTester = this->CTest->GetCTestConfiguration("CMakeCommand");
+    this->MemoryTester = cmSystemTools::GetCMakeCommand();
     this->MemoryTesterStyle = cmCTestMemCheckHandler::UB_SANITIZER;
     this->LogWithPID = true; // even if we give the log file the pid is added
   }
@@ -530,6 +538,8 @@
       this->MemoryTesterStyle = cmCTestMemCheckHandler::VALGRIND;
     } else if (checkType == "DrMemory") {
       this->MemoryTesterStyle = cmCTestMemCheckHandler::DRMEMORY;
+    } else if (checkType == "CudaMemcheck") {
+      this->MemoryTesterStyle = cmCTestMemCheckHandler::CUDA_MEMCHECK;
     }
   }
   if (this->MemoryTester.empty()) {
@@ -555,6 +565,10 @@
                 .empty()) {
     memoryTesterOptions =
       this->CTest->GetCTestConfiguration("DrMemoryCommandOptions");
+  } else if (!this->CTest->GetCTestConfiguration("CudaMemcheckCommandOptions")
+                .empty()) {
+    memoryTesterOptions =
+      this->CTest->GetCTestConfiguration("CudaMemcheckCommandOptions");
   }
   this->MemoryTesterOptions =
     cmSystemTools::ParseArguments(memoryTesterOptions);
@@ -594,11 +608,11 @@
       std::string tempDrMemoryDir =
         this->CTest->GetBinaryDir() + "/Testing/Temporary/DrMemory";
 
-      if (!cmContains(this->MemoryTesterOptions, "-quiet")) {
+      if (!cm::contains(this->MemoryTesterOptions, "-quiet")) {
         this->MemoryTesterOptions.emplace_back("-quiet");
       }
 
-      if (!cmContains(this->MemoryTesterOptions, "-batch")) {
+      if (!cm::contains(this->MemoryTesterOptions, "-batch")) {
         this->MemoryTesterOptions.emplace_back("-batch");
       }
 
@@ -688,6 +702,18 @@
       this->MemoryTesterOptions.emplace_back("/M");
       break;
     }
+    case cmCTestMemCheckHandler::CUDA_MEMCHECK: {
+      // cuda-memcheck separates flags from arguments by spaces
+      if (this->MemoryTesterOptions.empty()) {
+        this->MemoryTesterOptions.emplace_back("--tool");
+        this->MemoryTesterOptions.emplace_back("memcheck");
+        this->MemoryTesterOptions.emplace_back("--leak-check");
+        this->MemoryTesterOptions.emplace_back("full");
+      }
+      this->MemoryTesterDynamicOptions.emplace_back("--log-file");
+      this->MemoryTesterDynamicOptions.push_back(this->MemoryTesterOutputFile);
+      break;
+    }
     // these are almost the same but the env var used is different
     case cmCTestMemCheckHandler::ADDRESS_SANITIZER:
     case cmCTestMemCheckHandler::LEAK_SANITIZER:
@@ -773,6 +799,8 @@
       return this->ProcessMemCheckSanitizerOutput(str, log, results);
     case cmCTestMemCheckHandler::BOUNDS_CHECKER:
       return this->ProcessMemCheckBoundsCheckerOutput(str, log, results);
+    case cmCTestMemCheckHandler::CUDA_MEMCHECK:
+      return this->ProcessMemCheckCudaOutput(str, log, results);
     default:
       log.append("\nMemory checking style used was: ");
       log.append("None that I know");
@@ -957,35 +985,25 @@
                          "valgrind  line " << lines[cc] << std::endl,
                          this->Quiet);
       int failure = cmCTestMemCheckHandler::NO_MEMORY_FAULT;
-      if (vgFIM.find(lines[cc])) {
+      auto& line = lines[cc];
+      if (vgFIM.find(line)) {
         failure = cmCTestMemCheckHandler::FIM;
-      } else if (vgFMM.find(lines[cc])) {
+      } else if (vgFMM.find(line)) {
         failure = cmCTestMemCheckHandler::FMM;
-      } else if (vgMLK1.find(lines[cc])) {
+      } else if (vgMLK1.find(line) || vgMLK2.find(line)) {
         failure = cmCTestMemCheckHandler::MLK;
-      } else if (vgMLK2.find(lines[cc])) {
-        failure = cmCTestMemCheckHandler::MLK;
-      } else if (vgPAR.find(lines[cc])) {
+      } else if (vgPAR.find(line)) {
         failure = cmCTestMemCheckHandler::PAR;
-      } else if (vgMPK1.find(lines[cc])) {
+      } else if (vgMPK1.find(line) || vgMPK2.find(line)) {
         failure = cmCTestMemCheckHandler::MPK;
-      } else if (vgMPK2.find(lines[cc])) {
-        failure = cmCTestMemCheckHandler::MPK;
-      } else if (vgUMC.find(lines[cc])) {
+      } else if (vgUMC.find(line)) {
         failure = cmCTestMemCheckHandler::UMC;
-      } else if (vgUMR1.find(lines[cc])) {
+      } else if (vgUMR1.find(line) || vgUMR2.find(line) || vgUMR3.find(line) ||
+                 vgUMR4.find(line) || vgUMR5.find(line)) {
         failure = cmCTestMemCheckHandler::UMR;
-      } else if (vgUMR2.find(lines[cc])) {
-        failure = cmCTestMemCheckHandler::UMR;
-      } else if (vgUMR3.find(lines[cc])) {
-        failure = cmCTestMemCheckHandler::UMR;
-      } else if (vgUMR4.find(lines[cc])) {
-        failure = cmCTestMemCheckHandler::UMR;
-      } else if (vgUMR5.find(lines[cc])) {
-        failure = cmCTestMemCheckHandler::UMR;
-      } else if (vgIPW.find(lines[cc])) {
+      } else if (vgIPW.find(line)) {
         failure = cmCTestMemCheckHandler::IPW;
-      } else if (vgABR.find(lines[cc])) {
+      } else if (vgABR.find(line)) {
         failure = cmCTestMemCheckHandler::ABR;
       }
 
@@ -1049,13 +1067,9 @@
     ostr << l << std::endl;
     if (drMemoryError.find(l)) {
       defects++;
-      if (unaddressableAccess.find(l)) {
+      if (unaddressableAccess.find(l) || uninitializedRead.find(l)) {
         results[cmCTestMemCheckHandler::UMR]++;
-      } else if (uninitializedRead.find(l)) {
-        results[cmCTestMemCheckHandler::UMR]++;
-      } else if (leak.find(l)) {
-        results[cmCTestMemCheckHandler::MLK]++;
-      } else if (handleLeak.find(l)) {
+      } else if (leak.find(l) || handleLeak.find(l)) {
         results[cmCTestMemCheckHandler::MLK]++;
       } else if (invalidHeapArgument.find(l)) {
         results[cmCTestMemCheckHandler::FMM]++;
@@ -1119,6 +1133,119 @@
   return defects == 0;
 }
 
+bool cmCTestMemCheckHandler::ProcessMemCheckCudaOutput(
+  const std::string& str, std::string& log, std::vector<int>& results)
+{
+  std::vector<std::string> lines;
+  cmsys::SystemTools::Split(str, lines);
+  bool unlimitedOutput = false;
+  if (str.find("CTEST_FULL_OUTPUT") != std::string::npos ||
+      this->CustomMaximumFailedTestOutputSize == 0) {
+    unlimitedOutput = true;
+  }
+
+  std::string::size_type cc;
+
+  std::ostringstream ostr;
+  log.clear();
+
+  int defects = 0;
+
+  cmsys::RegularExpression memcheckLine("^========");
+
+  cmsys::RegularExpression leakExpr("== Leaked [0-9,]+ bytes at");
+
+  // list of matchers for output messages that contain variable content
+  // (addresses, sizes, ...) or can be shortened in general. the first match is
+  // used as a error name.
+  std::vector<cmsys::RegularExpression> matchers{
+    // API errors
+    "== Malloc/Free error encountered: (.*)",
+    "== Program hit error ([^ ]*).* on CUDA API call to",
+    "== Program hit ([^ ]*).* on CUDA API call to",
+    // memcheck
+    "== (Invalid .*) of size [0-9,]+", "== (Fatal UVM [CG]PU fault)",
+    // racecheck
+    "== .* (Potential .* hazard detected)", "== .* (Race reported)",
+    // synccheck
+    "== (Barrier error)",
+    // initcheck
+    "== (Uninitialized .* memory read)", "== (Unused memory)",
+    "== (Host API memory access error)",
+    // generic error: ignore ERROR SUMMARY, CUDA-MEMCHECK and others
+    "== ([A-Z][a-z].*)"
+  };
+
+  std::vector<std::string::size_type> nonMemcheckOutput;
+  auto sttime = std::chrono::steady_clock::now();
+  cmCTestOptionalLog(this->CTest, DEBUG,
+                     "Start test: " << lines.size() << std::endl, this->Quiet);
+  std::string::size_type totalOutputSize = 0;
+  for (cc = 0; cc < lines.size(); cc++) {
+    cmCTestOptionalLog(this->CTest, DEBUG,
+                       "test line " << lines[cc] << std::endl, this->Quiet);
+
+    if (memcheckLine.find(lines[cc])) {
+      cmCTestOptionalLog(this->CTest, DEBUG,
+                         "cuda-memcheck line " << lines[cc] << std::endl,
+                         this->Quiet);
+      int failure = -1;
+      auto& line = lines[cc];
+      if (leakExpr.find(line)) {
+        failure = static_cast<int>(this->FindOrAddWarning("Memory leak"));
+      } else {
+        for (auto& matcher : matchers) {
+          if (matcher.find(line)) {
+            failure =
+              static_cast<int>(this->FindOrAddWarning(matcher.match(1)));
+            break;
+          }
+        }
+      }
+
+      if (failure >= 0) {
+        ostr << "<b>" << this->ResultStrings[failure] << "</b> ";
+        if (results.empty() || unsigned(failure) > results.size() - 1) {
+          results.push_back(1);
+        } else {
+          results[failure]++;
+        }
+        defects++;
+      }
+      totalOutputSize += lines[cc].size();
+      ostr << lines[cc] << std::endl;
+    } else {
+      nonMemcheckOutput.push_back(cc);
+    }
+  }
+  // Now put all all the non cuda-memcheck output into the test output
+  // This should be last in case it gets truncated by the output
+  // limiting code
+  for (std::string::size_type i : nonMemcheckOutput) {
+    totalOutputSize += lines[i].size();
+    ostr << lines[i] << std::endl;
+    if (!unlimitedOutput &&
+        totalOutputSize >
+          static_cast<size_t>(this->CustomMaximumFailedTestOutputSize)) {
+      ostr << "....\n";
+      ostr << "Test Output for this test has been truncated see testing"
+              " machine logs for full output,\n";
+      ostr << "or put CTEST_FULL_OUTPUT in the output of "
+              "this test program.\n";
+      break; // stop the copy of output if we are full
+    }
+  }
+  cmCTestOptionalLog(this->CTest, DEBUG,
+                     "End test (elapsed: "
+                       << cmDurationTo<unsigned int>(
+                            std::chrono::steady_clock::now() - sttime)
+                       << "s)" << std::endl,
+                     this->Quiet);
+  log = ostr.str();
+  this->DefectCount += defects;
+  return defects == 0;
+}
+
 // PostProcessTest memcheck results
 void cmCTestMemCheckHandler::PostProcessTest(cmCTestTestResult& res, int test)
 {
diff --git a/Source/CTest/cmCTestMemCheckHandler.h b/Source/CTest/cmCTestMemCheckHandler.h
index 52667f8..63ab573 100644
--- a/Source/CTest/cmCTestMemCheckHandler.h
+++ b/Source/CTest/cmCTestMemCheckHandler.h
@@ -46,6 +46,7 @@
     DRMEMORY,
     BOUNDS_CHECKER,
     // checkers after here do not use the standard error list
+    CUDA_MEMCHECK,
     ADDRESS_SANITIZER,
     LEAK_SANITIZER,
     THREAD_SANITIZER,
@@ -137,6 +138,8 @@
                                      std::vector<int>& results);
   bool ProcessMemCheckPurifyOutput(const std::string& str, std::string& log,
                                    std::vector<int>& results);
+  bool ProcessMemCheckCudaOutput(const std::string& str, std::string& log,
+                                 std::vector<int>& results);
   bool ProcessMemCheckSanitizerOutput(const std::string& str, std::string& log,
                                       std::vector<int>& results);
   bool ProcessMemCheckBoundsCheckerOutput(const std::string& str,
diff --git a/Source/CTest/cmCTestMultiProcessHandler.cxx b/Source/CTest/cmCTestMultiProcessHandler.cxx
index 2192843..a08cb34 100644
--- a/Source/CTest/cmCTestMultiProcessHandler.cxx
+++ b/Source/CTest/cmCTestMultiProcessHandler.cxx
@@ -6,30 +6,29 @@
 #include <cassert>
 #include <chrono>
 #include <cmath>
-#include <cstddef>
+#include <cstddef> // IWYU pragma: keep
 #include <cstdlib>
 #include <cstring>
 #include <iomanip>
 #include <iostream>
 #include <list>
-#include <memory>
 #include <sstream>
 #include <stack>
 #include <unordered_map>
 #include <utility>
 #include <vector>
 
+#include <cm/memory>
 #include <cmext/algorithm>
 
+#include <cm3p/json/value.h>
+#include <cm3p/json/writer.h>
+#include <cm3p/uv.h>
+
 #include "cmsys/FStream.hxx"
 #include "cmsys/SystemInformation.hxx"
 
-#include "cm_jsoncpp_value.h"
-#include "cm_jsoncpp_writer.h"
-#include "cm_uv.h"
-
 #include "cmAffinity.h"
-#include "cmAlgorithms.h"
 #include "cmCTest.h"
 #include "cmCTestBinPacker.h"
 #include "cmCTestRunTest.h"
@@ -138,7 +137,7 @@
   uv_run(&this->Loop, UV_RUN_DEFAULT);
   uv_loop_close(&this->Loop);
 
-  if (!this->StopTimePassed) {
+  if (!this->StopTimePassed && !this->CheckStopOnFailure()) {
     assert(this->Completed == this->Total);
     assert(this->Tests.empty());
   }
@@ -172,7 +171,8 @@
   this->EraseTest(test);
   this->RunningCount += GetProcessorsUsed(test);
 
-  cmCTestRunTest* testRun = new cmCTestRunTest(*this);
+  auto testRun = cm::make_unique<cmCTestRunTest>(*this);
+
   if (this->RepeatMode != cmCTest::Repeat::Never) {
     testRun->SetRepeatMode(this->RepeatMode);
     testRun->SetNumberOfRuns(this->RepeatCount);
@@ -187,7 +187,7 @@
   // Find any failed dependencies for this test. We assume the more common
   // scenario has no failed tests, so make it the outer loop.
   for (std::string const& f : *this->Failed) {
-    if (cmContains(this->Properties[test]->RequireSuccessDepends, f)) {
+    if (cm::contains(this->Properties[test]->RequireSuccessDepends, f)) {
       testRun->AddFailedDependency(f);
     }
   }
@@ -229,28 +229,25 @@
       e << "\n";
     }
     e << "Resource spec file:\n\n  " << this->TestHandler->ResourceSpecFile;
-    testRun->StartFailure(e.str(), "Insufficient resources");
-    this->FinishTestProcess(testRun, false);
+    cmCTestRunTest::StartFailure(std::move(testRun), e.str(),
+                                 "Insufficient resources");
     return false;
   }
 
   cmWorkingDirectory workdir(this->Properties[test]->Directory);
   if (workdir.Failed()) {
-    testRun->StartFailure("Failed to change working directory to " +
-                            this->Properties[test]->Directory + " : " +
-                            std::strerror(workdir.GetLastResult()),
-                          "Failed to change working directory");
-  } else {
-    if (testRun->StartTest(this->Completed, this->Total)) {
-      // Ownership of 'testRun' has moved to another structure.
-      // When the test finishes, FinishTestProcess will be called.
-      return true;
-    }
+    cmCTestRunTest::StartFailure(std::move(testRun),
+                                 "Failed to change working directory to " +
+                                   this->Properties[test]->Directory + " : " +
+                                   std::strerror(workdir.GetLastResult()),
+                                 "Failed to change working directory");
+    return false;
   }
 
-  // Pass ownership of 'testRun'.
-  this->FinishTestProcess(testRun, false);
-  return false;
+  // Ownership of 'testRun' has moved to another structure.
+  // When the test finishes, FinishTestProcess will be called.
+  return cmCTestRunTest::StartTest(std::move(testRun), this->Completed,
+                                   this->Total);
 }
 
 bool cmCTestMultiProcessHandler::AllocateResources(int index)
@@ -370,6 +367,11 @@
   }
 }
 
+bool cmCTestMultiProcessHandler::CheckStopOnFailure()
+{
+  return this->CTest->GetStopOnFailure();
+}
+
 bool cmCTestMultiProcessHandler::CheckStopTimePassed()
 {
   if (!this->StopTimePassed) {
@@ -447,7 +449,7 @@
 {
   // Check for locked resources
   for (std::string const& i : this->Properties[test]->LockedResources) {
-    if (cmContains(this->LockedResources, i)) {
+    if (cm::contains(this->LockedResources, i)) {
       return false;
     }
   }
@@ -486,6 +488,10 @@
     return;
   }
 
+  if (this->CheckStopOnFailure() && !this->Failed->empty()) {
+    return;
+  }
+
   size_t numToStart = 0;
 
   if (this->RunningCount < this->ParallelLevel) {
@@ -540,7 +546,8 @@
     if (this->SerialTestRunning) {
       break;
     }
-    // We can only start a RUN_SERIAL test if no other tests are also running.
+    // We can only start a RUN_SERIAL test if no other tests are also
+    // running.
     if (this->Properties[test]->RunSerial && this->RunningCount > 0) {
       continue;
     }
@@ -618,8 +625,8 @@
   self->StartNextTests();
 }
 
-void cmCTestMultiProcessHandler::FinishTestProcess(cmCTestRunTest* runner,
-                                                   bool started)
+void cmCTestMultiProcessHandler::FinishTestProcess(
+  std::unique_ptr<cmCTestRunTest> runner, bool started)
 {
   this->Completed++;
 
@@ -631,7 +638,8 @@
     this->SetStopTimePassed();
   }
   if (started) {
-    if (!this->StopTimePassed && runner->StartAgain(this->Completed)) {
+    if (!this->StopTimePassed &&
+        cmCTestRunTest::StartAgain(std::move(runner), this->Completed)) {
       this->Completed--; // remove the completed test because run again
       return;
     }
@@ -659,7 +667,7 @@
   }
   properties->Affinity.clear();
 
-  delete runner;
+  runner.reset();
   if (started) {
     this->StartNextTests();
   }
@@ -802,7 +810,7 @@
   // In parallel test runs add previously failed tests to the front
   // of the cost list and queue other tests for further sorting
   for (auto const& t : this->Tests) {
-    if (cmContains(this->LastTestsFailed, this->Properties[t.first]->Name)) {
+    if (cm::contains(this->LastTestsFailed, this->Properties[t.first]->Name)) {
       // If the test failed last time, it should be run first.
       this->SortedTests.push_back(t.first);
       alreadySortedTests.insert(t.first);
@@ -841,7 +849,7 @@
                      TestComparator(this));
 
     for (auto const& j : sortedCopy) {
-      if (!cmContains(alreadySortedTests, j)) {
+      if (!cm::contains(alreadySortedTests, j)) {
         this->SortedTests.push_back(j);
         alreadySortedTests.insert(j);
       }
@@ -873,7 +881,7 @@
   TestSet alreadySortedTests;
 
   for (int test : presortedList) {
-    if (cmContains(alreadySortedTests, test)) {
+    if (cm::contains(alreadySortedTests, test)) {
       continue;
     }
 
@@ -881,7 +889,7 @@
     GetAllTestDependencies(test, dependencies);
 
     for (int testDependency : dependencies) {
-      if (!cmContains(alreadySortedTests, testDependency)) {
+      if (!cm::contains(alreadySortedTests, testDependency)) {
         alreadySortedTests.insert(testDependency);
         this->SortedTests.push_back(testDependency);
       }
diff --git a/Source/CTest/cmCTestMultiProcessHandler.h b/Source/CTest/cmCTestMultiProcessHandler.h
index 5b429d4..e21b912 100644
--- a/Source/CTest/cmCTestMultiProcessHandler.h
+++ b/Source/CTest/cmCTestMultiProcessHandler.h
@@ -6,14 +6,14 @@
 #include "cmConfigure.h" // IWYU pragma: keep
 
 #include <map>
+#include <memory>
 #include <set>
 #include <string>
 #include <vector>
 
+#include <cm3p/uv.h>
 #include <stddef.h>
 
-#include "cm_uv.h"
-
 #include "cmCTest.h"
 #include "cmCTestResourceAllocator.h"
 #include "cmCTestTestHandler.h"
@@ -124,7 +124,7 @@
   // Removes the checkpoint file
   void MarkFinished();
   void EraseTest(int index);
-  void FinishTestProcess(cmCTestRunTest* runner, bool started);
+  void FinishTestProcess(std::unique_ptr<cmCTestRunTest> runner, bool started);
 
   static void OnTestLoadRetryCB(uv_timer_t* timer);
 
@@ -137,6 +137,8 @@
   inline size_t GetProcessorsUsed(int index);
   std::string GetName(int index);
 
+  bool CheckStopOnFailure();
+
   bool CheckStopTimePassed();
   void SetStopTimePassed();
 
diff --git a/Source/CTest/cmCTestReadCustomFilesCommand.cxx b/Source/CTest/cmCTestReadCustomFilesCommand.cxx
index ed14d06..a25cca4 100644
--- a/Source/CTest/cmCTestReadCustomFilesCommand.cxx
+++ b/Source/CTest/cmCTestReadCustomFilesCommand.cxx
@@ -15,7 +15,7 @@
   }
 
   for (std::string const& arg : args) {
-    this->CTest->ReadCustomConfigurationFileTree(arg.c_str(), this->Makefile);
+    this->CTest->ReadCustomConfigurationFileTree(arg, this->Makefile);
   }
 
   return true;
diff --git a/Source/CTest/cmCTestResourceSpec.cxx b/Source/CTest/cmCTestResourceSpec.cxx
index 8f91efb..21c97de 100644
--- a/Source/CTest/cmCTestResourceSpec.cxx
+++ b/Source/CTest/cmCTestResourceSpec.cxx
@@ -7,12 +7,12 @@
 #include <utility>
 #include <vector>
 
+#include <cm3p/json/reader.h>
+#include <cm3p/json/value.h>
+
 #include "cmsys/FStream.hxx"
 #include "cmsys/RegularExpression.hxx"
 
-#include "cm_jsoncpp_reader.h"
-#include "cm_jsoncpp_value.h"
-
 static const cmsys::RegularExpression IdentifierRegex{ "^[a-z_][a-z0-9_]*$" };
 static const cmsys::RegularExpression IdRegex{ "^[a-z0-9_]+$" };
 
diff --git a/Source/CTest/cmCTestRunTest.cxx b/Source/CTest/cmCTestRunTest.cxx
index 58289ea..4d65c9b 100644
--- a/Source/CTest/cmCTestRunTest.cxx
+++ b/Source/CTest/cmCTestRunTest.cxx
@@ -3,7 +3,7 @@
 #include "cmCTestRunTest.h"
 
 #include <chrono>
-#include <cstddef>
+#include <cstddef> // IWYU pragma: keep
 #include <cstdint>
 #include <cstdio>
 #include <cstring>
@@ -314,23 +314,27 @@
   return passed || skipped;
 }
 
-bool cmCTestRunTest::StartAgain(size_t completed)
+bool cmCTestRunTest::StartAgain(std::unique_ptr<cmCTestRunTest> runner,
+                                size_t completed)
 {
-  if (!this->RunAgain) {
+  auto* testRun = runner.get();
+
+  if (!testRun->RunAgain) {
     return false;
   }
-  this->RunAgain = false; // reset
+  testRun->RunAgain = false; // reset
+  testRun->TestProcess = cm::make_unique<cmProcess>(std::move(runner));
   // change to tests directory
-  cmWorkingDirectory workdir(this->TestProperties->Directory);
+  cmWorkingDirectory workdir(testRun->TestProperties->Directory);
   if (workdir.Failed()) {
-    this->StartFailure("Failed to change working directory to " +
-                         this->TestProperties->Directory + " : " +
-                         std::strerror(workdir.GetLastResult()),
-                       "Failed to change working directory");
+    testRun->StartFailure("Failed to change working directory to " +
+                            testRun->TestProperties->Directory + " : " +
+                            std::strerror(workdir.GetLastResult()),
+                          "Failed to change working directory");
     return true;
   }
 
-  this->StartTest(completed, this->TotalNumberOfTests);
+  testRun->StartTest(completed, testRun->TotalNumberOfTests);
   return true;
 }
 
@@ -387,6 +391,18 @@
   handler->PostProcessTest(this->TestResult, this->Index);
 }
 
+void cmCTestRunTest::StartFailure(std::unique_ptr<cmCTestRunTest> runner,
+                                  std::string const& output,
+                                  std::string const& detail)
+{
+  auto* testRun = runner.get();
+
+  testRun->TestProcess = cm::make_unique<cmProcess>(std::move(runner));
+  testRun->StartFailure(output, detail);
+
+  testRun->FinalizeTest(false);
+}
+
 void cmCTestRunTest::StartFailure(std::string const& output,
                                   std::string const& detail)
 {
@@ -418,7 +434,7 @@
   this->TestResult.Path = this->TestProperties->Directory;
   this->TestResult.Output = output;
   this->TestResult.FullCommandLine.clear();
-  this->TestProcess = cm::make_unique<cmProcess>(*this);
+  this->TestResult.Environment.clear();
 }
 
 std::string cmCTestRunTest::GetTestPrefix(size_t completed, size_t total) const
@@ -442,6 +458,21 @@
   return outputStream.str();
 }
 
+bool cmCTestRunTest::StartTest(std::unique_ptr<cmCTestRunTest> runner,
+                               size_t completed, size_t total)
+{
+  auto* testRun = runner.get();
+
+  testRun->TestProcess = cm::make_unique<cmProcess>(std::move(runner));
+
+  if (!testRun->StartTest(completed, total)) {
+    testRun->FinalizeTest(false);
+    return false;
+  }
+
+  return true;
+}
+
 // Starts the execution of a test.  Returns once it has started
 bool cmCTestRunTest::StartTest(size_t completed, size_t total)
 {
@@ -473,9 +504,9 @@
   if (this->TestProperties->Disabled) {
     this->TestResult.CompletionStatus = "Disabled";
     this->TestResult.Status = cmCTestTestHandler::NOT_RUN;
-    this->TestProcess = cm::make_unique<cmProcess>(*this);
     this->TestResult.Output = "Disabled";
     this->TestResult.FullCommandLine.clear();
+    this->TestResult.Environment.clear();
     return false;
   }
 
@@ -487,7 +518,6 @@
   // its arguments are irrelevant. This matters for the case where a fixture
   // dependency might be creating the executable we want to run.
   if (!this->FailedDependencies.empty()) {
-    this->TestProcess = cm::make_unique<cmProcess>(*this);
     std::string msg = "Failed test dependencies:";
     for (std::string const& failedDep : this->FailedDependencies) {
       msg += " " + failedDep;
@@ -496,6 +526,7 @@
     cmCTestLog(this->CTest, HANDLER_OUTPUT, msg << std::endl);
     this->TestResult.Output = msg;
     this->TestResult.FullCommandLine.clear();
+    this->TestResult.Environment.clear();
     this->TestResult.CompletionStatus = "Fixture dependency failed";
     this->TestResult.Status = cmCTestTestHandler::NOT_RUN;
     return false;
@@ -504,7 +535,6 @@
   this->ComputeArguments();
   std::vector<std::string>& args = this->TestProperties->Args;
   if (args.size() >= 2 && args[1] == "NOT_AVAILABLE") {
-    this->TestProcess = cm::make_unique<cmProcess>(*this);
     std::string msg;
     if (this->CTest->GetConfigType().empty()) {
       msg = "Test not available without configuration.  (Missing \"-C "
@@ -517,6 +547,7 @@
     cmCTestLog(this->CTest, ERROR_MESSAGE, msg << std::endl);
     this->TestResult.Output = msg;
     this->TestResult.FullCommandLine.clear();
+    this->TestResult.Environment.clear();
     this->TestResult.CompletionStatus = "Missing Configuration";
     this->TestResult.Status = cmCTestTestHandler::NOT_RUN;
     return false;
@@ -526,13 +557,13 @@
   for (std::string const& file : this->TestProperties->RequiredFiles) {
     if (!cmSystemTools::FileExists(file)) {
       // Required file was not found
-      this->TestProcess = cm::make_unique<cmProcess>(*this);
       *this->TestHandler->LogFile << "Unable to find required file: " << file
                                   << std::endl;
       cmCTestLog(this->CTest, ERROR_MESSAGE,
                  "Unable to find required file: " << file << std::endl);
       this->TestResult.Output = "Unable to find required file: " + file;
       this->TestResult.FullCommandLine.clear();
+      this->TestResult.Environment.clear();
       this->TestResult.CompletionStatus = "Required Files Missing";
       this->TestResult.Status = cmCTestTestHandler::NOT_RUN;
       return false;
@@ -542,13 +573,13 @@
   if (this->ActualCommand.empty()) {
     // if the command was not found create a TestResult object
     // that has that information
-    this->TestProcess = cm::make_unique<cmProcess>(*this);
     *this->TestHandler->LogFile << "Unable to find executable: " << args[1]
                                 << std::endl;
     cmCTestLog(this->CTest, ERROR_MESSAGE,
                "Unable to find executable: " << args[1] << std::endl);
     this->TestResult.Output = "Unable to find executable: " + args[1];
     this->TestResult.FullCommandLine.clear();
+    this->TestResult.Environment.clear();
     this->TestResult.CompletionStatus = "Unable to find executable";
     this->TestResult.Status = cmCTestTestHandler::NOT_RUN;
     return false;
@@ -588,11 +619,11 @@
     cmCTestMemCheckHandler* handler =
       static_cast<cmCTestMemCheckHandler*>(this->TestHandler);
     this->ActualCommand = handler->MemoryTester;
-    this->TestProperties->Args[1] = this->TestHandler->FindTheExecutable(
-      this->TestProperties->Args[1].c_str());
+    this->TestProperties->Args[1] =
+      this->TestHandler->FindTheExecutable(this->TestProperties->Args[1]);
   } else {
-    this->ActualCommand = this->TestHandler->FindTheExecutable(
-      this->TestProperties->Args[1].c_str());
+    this->ActualCommand =
+      this->TestHandler->FindTheExecutable(this->TestProperties->Args[1]);
     ++j; // skip the executable (it will be actualCommand)
   }
   std::string testCommand =
@@ -654,7 +685,6 @@
                                  std::vector<std::string>* environment,
                                  std::vector<size_t>* affinity)
 {
-  this->TestProcess = cm::make_unique<cmProcess>(*this);
   this->TestProcess->SetId(this->Index);
   this->TestProcess->SetWorkingDirectory(this->TestProperties->Directory);
   this->TestProcess->SetCommand(this->ActualCommand);
@@ -694,25 +724,43 @@
   cmSystemTools::SaveRestoreEnvironment sre;
 #endif
 
+  std::ostringstream envMeasurement;
   if (environment && !environment->empty()) {
     cmSystemTools::AppendEnv(*environment);
+    for (auto const& var : *environment) {
+      envMeasurement << var << std::endl;
+    }
   }
 
   if (this->UseAllocatedResources) {
-    this->SetupResourcesEnvironment();
+    std::vector<std::string> envLog;
+    this->SetupResourcesEnvironment(&envLog);
+    for (auto const& var : envLog) {
+      envMeasurement << var << std::endl;
+    }
   } else {
     cmSystemTools::UnsetEnv("CTEST_RESOURCE_GROUP_COUNT");
+    // Signify that this variable is being actively unset
+    envMeasurement << "#CTEST_RESOURCE_GROUP_COUNT=" << std::endl;
   }
 
+  this->TestResult.Environment = envMeasurement.str();
+  // Remove last newline
+  this->TestResult.Environment.erase(this->TestResult.Environment.length() -
+                                     1);
+
   return this->TestProcess->StartProcess(this->MultiTestHandler.Loop,
                                          affinity);
 }
 
-void cmCTestRunTest::SetupResourcesEnvironment()
+void cmCTestRunTest::SetupResourcesEnvironment(std::vector<std::string>* log)
 {
   std::string processCount = "CTEST_RESOURCE_GROUP_COUNT=";
   processCount += std::to_string(this->AllocatedResources.size());
   cmSystemTools::PutEnv(processCount);
+  if (log) {
+    log->push_back(processCount);
+  }
 
   std::size_t i = 0;
   for (auto const& process : this->AllocatedResources) {
@@ -738,8 +786,14 @@
         var += "id:" + it2.Id + ",slots:" + std::to_string(it2.Slots);
       }
       cmSystemTools::PutEnv(var);
+      if (log) {
+        log->push_back(var);
+      }
     }
     cmSystemTools::PutEnv(resourceList);
+    if (log) {
+      log->push_back(resourceList);
+    }
     ++i;
   }
 }
@@ -821,7 +875,8 @@
              "Testing " << this->TestProperties->Name << " ... ");
 }
 
-void cmCTestRunTest::FinalizeTest()
+void cmCTestRunTest::FinalizeTest(bool started)
 {
-  this->MultiTestHandler.FinishTestProcess(this, true);
+  this->MultiTestHandler.FinishTestProcess(this->TestProcess->GetRunner(),
+                                           started);
 }
diff --git a/Source/CTest/cmCTestRunTest.h b/Source/CTest/cmCTestRunTest.h
index 4988839..d831247 100644
--- a/Source/CTest/cmCTestRunTest.h
+++ b/Source/CTest/cmCTestRunTest.h
@@ -65,6 +65,15 @@
   // Read and store output.  Returns true if it must be called again.
   void CheckOutput(std::string const& line);
 
+  static bool StartTest(std::unique_ptr<cmCTestRunTest> runner,
+                        size_t completed, size_t total);
+  static bool StartAgain(std::unique_ptr<cmCTestRunTest> runner,
+                         size_t completed);
+
+  static void StartFailure(std::unique_ptr<cmCTestRunTest> runner,
+                           std::string const& output,
+                           std::string const& detail);
+
   // launch the test process, return whether it started correctly
   bool StartTest(size_t completed, size_t total);
   // capture and report the test results
@@ -74,8 +83,6 @@
 
   void ComputeWeightedCost();
 
-  bool StartAgain(size_t completed);
-
   void StartFailure(std::string const& output, std::string const& detail);
 
   cmCTest* GetCTest() const { return this->CTest; }
@@ -84,7 +91,7 @@
 
   const std::vector<std::string>& GetArguments() { return this->Arguments; }
 
-  void FinalizeTest();
+  void FinalizeTest(bool started = true);
 
   bool TimedOutForStopTime() const { return this->TimeoutIsForStopTime; }
 
@@ -112,7 +119,7 @@
   // Run post processing of the process output for MemCheck
   void MemCheckPostProcess();
 
-  void SetupResourcesEnvironment();
+  void SetupResourcesEnvironment(std::vector<std::string>* log = nullptr);
 
   // Returns "completed/total Test #Index: "
   std::string GetTestPrefix(size_t completed, size_t total) const;
diff --git a/Source/CTest/cmCTestScriptHandler.cxx b/Source/CTest/cmCTestScriptHandler.cxx
index 7803e37..4fa4dc0 100644
--- a/Source/CTest/cmCTestScriptHandler.cxx
+++ b/Source/CTest/cmCTestScriptHandler.cxx
@@ -6,7 +6,6 @@
 #include <cstdlib>
 #include <cstring>
 #include <map>
-#include <memory>
 #include <ratio>
 #include <sstream>
 #include <utility>
@@ -51,22 +50,7 @@
 
 #define CTEST_INITIAL_CMAKE_OUTPUT_FILE_NAME "CTestInitialCMakeOutput.log"
 
-cmCTestScriptHandler::cmCTestScriptHandler()
-{
-  this->Backup = false;
-  this->EmptyBinDir = false;
-  this->EmptyBinDirOnce = false;
-  this->Makefile = nullptr;
-  this->ParentMakefile = nullptr;
-  this->CMake = nullptr;
-  this->GlobalGenerator = nullptr;
-
-  this->ScriptStartTime = std::chrono::steady_clock::time_point();
-
-  // the *60 is because the settings are in minutes but GetTime is seconds
-  this->MinimumInterval = 30 * 60;
-  this->ContinuousDuration = -1;
-}
+cmCTestScriptHandler::cmCTestScriptHandler() = default;
 
 void cmCTestScriptHandler::Initialize()
 {
@@ -95,22 +79,15 @@
   // what time in seconds did this script start running
   this->ScriptStartTime = std::chrono::steady_clock::time_point();
 
-  delete this->Makefile;
-  this->Makefile = nullptr;
+  this->Makefile.reset();
   this->ParentMakefile = nullptr;
 
-  delete this->GlobalGenerator;
-  this->GlobalGenerator = nullptr;
+  this->GlobalGenerator.reset();
 
-  delete this->CMake;
+  this->CMake.reset();
 }
 
-cmCTestScriptHandler::~cmCTestScriptHandler()
-{
-  delete this->Makefile;
-  delete this->GlobalGenerator;
-  delete this->CMake;
-}
+cmCTestScriptHandler::~cmCTestScriptHandler() = default;
 
 // just adds an argument to the vector
 void cmCTestScriptHandler::AddConfigurationScript(const char* script,
@@ -247,23 +224,20 @@
 void cmCTestScriptHandler::CreateCMake()
 {
   // create a cmake instance to read the configuration script
-  if (this->CMake) {
-    delete this->CMake;
-    delete this->GlobalGenerator;
-    delete this->Makefile;
-  }
-  this->CMake = new cmake(cmake::RoleScript, cmState::CTest);
+  this->CMake = cm::make_unique<cmake>(cmake::RoleScript, cmState::CTest);
   this->CMake->SetHomeDirectory("");
   this->CMake->SetHomeOutputDirectory("");
   this->CMake->GetCurrentSnapshot().SetDefaultDefinitions();
   this->CMake->AddCMakePaths();
-  this->GlobalGenerator = new cmGlobalGenerator(this->CMake);
+  this->GlobalGenerator =
+    cm::make_unique<cmGlobalGenerator>(this->CMake.get());
 
   cmStateSnapshot snapshot = this->CMake->GetCurrentSnapshot();
   std::string cwd = cmSystemTools::GetCurrentWorkingDirectory();
   snapshot.GetDirectory().SetCurrentSource(cwd);
   snapshot.GetDirectory().SetCurrentBinary(cwd);
-  this->Makefile = new cmMakefile(this->GlobalGenerator, snapshot);
+  this->Makefile =
+    cm::make_unique<cmMakefile>(this->GlobalGenerator.get(), snapshot);
   if (this->ParentMakefile) {
     this->Makefile->SetRecursionDepth(
       this->ParentMakefile->GetRecursionDepth());
@@ -310,12 +284,14 @@
   // if the argument has a , in it then it needs to be broken into the fist
   // argument (which is the script) and the second argument which will be
   // passed into the scripts as S_ARG
-  std::string script = total_script_arg;
+  std::string script;
   std::string script_arg;
   const std::string::size_type comma_pos = total_script_arg.find(',');
   if (comma_pos != std::string::npos) {
     script = total_script_arg.substr(0, comma_pos);
     script_arg = total_script_arg.substr(comma_pos + 1);
+  } else {
+    script = total_script_arg;
   }
   // make sure the file exists
   if (!cmSystemTools::FileExists(script)) {
@@ -878,7 +854,7 @@
                                      const char* sname, bool InProcess,
                                      int* returnValue)
 {
-  cmCTestScriptHandler* sh = new cmCTestScriptHandler();
+  auto sh = cm::make_unique<cmCTestScriptHandler>();
   sh->SetCTestInstance(ctest);
   sh->ParentMakefile = mf;
   sh->AddConfigurationScript(sname, InProcess);
@@ -886,7 +862,6 @@
   if (returnValue) {
     *returnValue = res;
   }
-  delete sh;
   return true;
 }
 
diff --git a/Source/CTest/cmCTestScriptHandler.h b/Source/CTest/cmCTestScriptHandler.h
index d003199..ebb7905 100644
--- a/Source/CTest/cmCTestScriptHandler.h
+++ b/Source/CTest/cmCTestScriptHandler.h
@@ -101,12 +101,14 @@
   cmDuration GetRemainingTimeAllowed();
 
   cmCTestScriptHandler();
+  cmCTestScriptHandler(const cmCTestScriptHandler&) = delete;
+  const cmCTestScriptHandler& operator=(const cmCTestScriptHandler&) = delete;
   ~cmCTestScriptHandler() override;
 
   void Initialize() override;
 
   void CreateCMake();
-  cmake* GetCMake() { return this->CMake; }
+  cmake* GetCMake() { return this->CMake.get(); }
 
   void SetRunCurrentScript(bool value);
 
@@ -143,9 +145,9 @@
 
   bool ShouldRunCurrentScript;
 
-  bool Backup;
-  bool EmptyBinDir;
-  bool EmptyBinDirOnce;
+  bool Backup = false;
+  bool EmptyBinDir = false;
+  bool EmptyBinDirOnce = false;
 
   std::string SourceDir;
   std::string BinaryDir;
@@ -161,16 +163,18 @@
   std::string CMOutFile;
   std::vector<std::string> ExtraUpdates;
 
-  double MinimumInterval;
-  double ContinuousDuration;
+  // the *60 is because the settings are in minutes but GetTime is seconds
+  double MinimumInterval = 30 * 60;
+  double ContinuousDuration = -1;
 
   // what time in seconds did this script start running
-  std::chrono::steady_clock::time_point ScriptStartTime;
+  std::chrono::steady_clock::time_point ScriptStartTime =
+    std::chrono::steady_clock::time_point();
 
-  cmMakefile* Makefile;
-  cmMakefile* ParentMakefile;
-  cmGlobalGenerator* GlobalGenerator;
-  cmake* CMake;
+  std::unique_ptr<cmMakefile> Makefile;
+  cmMakefile* ParentMakefile = nullptr;
+  std::unique_ptr<cmGlobalGenerator> GlobalGenerator;
+  std::unique_ptr<cmake> CMake;
 };
 
 #endif
diff --git a/Source/CTest/cmCTestStartCommand.cxx b/Source/CTest/cmCTestStartCommand.cxx
index fe68406..6398d66 100644
--- a/Source/CTest/cmCTestStartCommand.cxx
+++ b/Source/CTest/cmCTestStartCommand.cxx
@@ -94,10 +94,9 @@
 
   std::string sourceDir = cmSystemTools::CollapseFullPath(src_dir);
   std::string binaryDir = cmSystemTools::CollapseFullPath(bld_dir);
-  this->CTest->SetCTestConfiguration("SourceDirectory", sourceDir.c_str(),
+  this->CTest->SetCTestConfiguration("SourceDirectory", sourceDir,
                                      this->Quiet);
-  this->CTest->SetCTestConfiguration("BuildDirectory", binaryDir.c_str(),
-                                     this->Quiet);
+  this->CTest->SetCTestConfiguration("BuildDirectory", binaryDir, this->Quiet);
 
   if (smodel) {
     cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT,
diff --git a/Source/CTest/cmCTestSubmitCommand.cxx b/Source/CTest/cmCTestSubmitCommand.cxx
index acb75b2..026e98f 100644
--- a/Source/CTest/cmCTestSubmitCommand.cxx
+++ b/Source/CTest/cmCTestSubmitCommand.cxx
@@ -8,10 +8,9 @@
 
 #include <cm/memory>
 #include <cm/vector>
+#include <cmext/algorithm>
+#include <cmext/string_view>
 
-#include "cm_static_string_view.hxx"
-
-#include "cmAlgorithms.h"
 #include "cmCTest.h"
 #include "cmCTestSubmitHandler.h"
 #include "cmCommand.h"
@@ -36,12 +35,12 @@
 
 cmCTestGenericHandler* cmCTestSubmitCommand::InitializeHandler()
 {
-  const char* submitURL = !this->SubmitURL.empty()
-    ? this->SubmitURL.c_str()
-    : this->Makefile->GetDefinition("CTEST_SUBMIT_URL");
+  const std::string* submitURL = !this->SubmitURL.empty()
+    ? &this->SubmitURL
+    : this->Makefile->GetDef("CTEST_SUBMIT_URL");
 
   if (submitURL) {
-    this->CTest->SetCTestConfiguration("SubmitURL", submitURL, this->Quiet);
+    this->CTest->SetCTestConfiguration("SubmitURL", *submitURL, this->Quiet);
   } else {
     this->CTest->SetCTestConfigurationFromCMakeVariable(
       this->Makefile, "DropMethod", "CTEST_DROP_METHOD", this->Quiet);
@@ -109,7 +108,7 @@
   if (this->PartsMentioned) {
     auto parts =
       cmMakeRange(this->Parts).transform([this](std::string const& arg) {
-        return this->CTest->GetPartFromName(arg.c_str());
+        return this->CTest->GetPartFromName(arg);
       });
     handler->SelectParts(std::set<cmCTest::Part>(parts.begin(), parts.end()));
   }
@@ -172,11 +171,13 @@
 void cmCTestSubmitCommand::CheckArguments(
   std::vector<std::string> const& keywords)
 {
-  this->PartsMentioned = !this->Parts.empty() || cmContains(keywords, "PARTS");
-  this->FilesMentioned = !this->Files.empty() || cmContains(keywords, "FILES");
+  this->PartsMentioned =
+    !this->Parts.empty() || cm::contains(keywords, "PARTS");
+  this->FilesMentioned =
+    !this->Files.empty() || cm::contains(keywords, "FILES");
 
   cm::erase_if(this->Parts, [this](std::string const& arg) -> bool {
-    cmCTest::Part p = this->CTest->GetPartFromName(arg.c_str());
+    cmCTest::Part p = this->CTest->GetPartFromName(arg);
     if (p == cmCTest::PartCount) {
       std::ostringstream e;
       e << "Part name \"" << arg << "\" is invalid.";
diff --git a/Source/CTest/cmCTestSubmitHandler.cxx b/Source/CTest/cmCTestSubmitHandler.cxx
index 22ab48f..5b54573 100644
--- a/Source/CTest/cmCTestSubmitHandler.cxx
+++ b/Source/CTest/cmCTestSubmitHandler.cxx
@@ -9,9 +9,9 @@
 
 #include <cmext/algorithm>
 
-#include "cm_curl.h"
-#include "cm_jsoncpp_reader.h"
-#include "cm_jsoncpp_value.h"
+#include <cm3p/curl/curl.h>
+#include <cm3p/json/reader.h>
+#include <cm3p/json/value.h>
 
 #include "cmAlgorithms.h"
 #include "cmCTest.h"
@@ -21,6 +21,7 @@
 #include "cmCurl.h"
 #include "cmDuration.h"
 #include "cmGeneratedFileStream.h"
+#include "cmProperty.h"
 #include "cmState.h"
 #include "cmStringAlgorithms.h"
 #include "cmSystemTools.h"
@@ -260,11 +261,10 @@
         cmCTestScriptHandler* ch = this->CTest->GetScriptHandler();
         cmake* cm = ch->GetCMake();
         if (cm) {
-          const char* subproject =
-            cm->GetState()->GetGlobalProperty("SubProject");
+          cmProp subproject = cm->GetState()->GetGlobalProperty("SubProject");
           if (subproject) {
             upload_as += "&subproject=";
-            upload_as += ctest_curl.Escape(subproject);
+            upload_as += ctest_curl.Escape(*subproject);
           }
         }
       }
@@ -506,18 +506,19 @@
   curl.SetTimeOutSeconds(SUBMIT_TIMEOUT_IN_SECONDS_DEFAULT);
   curl.SetHttpHeaders(this->HttpHeaders);
   std::string url = this->CTest->GetSubmitURL();
-  std::string fields;
-  std::string::size_type pos = url.find('?');
-  if (pos != std::string::npos) {
-    fields = url.substr(pos + 1);
-    url = url.substr(0, pos);
-  }
   if (!cmHasLiteralPrefix(url, "http://") &&
       !cmHasLiteralPrefix(url, "https://")) {
     cmCTestLog(this->CTest, ERROR_MESSAGE,
                "Only http and https are supported for CDASH_UPLOAD\n");
     return -1;
   }
+
+  std::string fields;
+  std::string::size_type pos = url.find('?');
+  if (pos != std::string::npos) {
+    fields = url.substr(pos + 1);
+    url.erase(pos);
+  }
   bool internalTest = cmIsOn(this->GetOption("InternalTest"));
 
   // Get RETRY_COUNT and RETRY_DELAY values if they were set.
@@ -555,11 +556,11 @@
   // a "&subproject=subprojectname" to the first POST.
   cmCTestScriptHandler* ch = this->CTest->GetScriptHandler();
   cmake* cm = ch->GetCMake();
-  const char* subproject = cm->GetState()->GetGlobalProperty("SubProject");
+  cmProp subproject = cm->GetState()->GetGlobalProperty("SubProject");
   // TODO: Encode values for a URL instead of trusting caller.
   std::ostringstream str;
   if (subproject) {
-    str << "subproject=" << curl.Escape(subproject) << "&";
+    str << "subproject=" << curl.Escape(*subproject) << "&";
   }
   auto timeNow =
     std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());
@@ -796,7 +797,7 @@
         gfile = gfile.substr(glen);
         cmCTestOptionalLog(this->CTest, DEBUG,
                            "Glob file: " << gfile << std::endl, this->Quiet);
-        this->CTest->AddSubmitFile(cmCTest::PartCoverage, gfile.c_str());
+        this->CTest->AddSubmitFile(cmCTest::PartCoverage, gfile);
       }
     } else {
       cmCTestLog(this->CTest, ERROR_MESSAGE, "Problem globbing" << std::endl);
diff --git a/Source/CTest/cmCTestTestCommand.cxx b/Source/CTest/cmCTestTestCommand.cxx
index 0f9b695..cbc3c0c 100644
--- a/Source/CTest/cmCTestTestCommand.cxx
+++ b/Source/CTest/cmCTestTestCommand.cxx
@@ -6,13 +6,14 @@
 #include <cstdlib>
 #include <sstream>
 
-#include "cm_static_string_view.hxx"
+#include <cmext/string_view>
 
 #include "cmCTest.h"
 #include "cmCTestGenericHandler.h"
 #include "cmCTestTestHandler.h"
 #include "cmDuration.h"
 #include "cmMakefile.h"
+#include "cmProperty.h"
 #include "cmStringAlgorithms.h"
 
 void cmCTestTestCommand::BindArguments()
@@ -34,6 +35,7 @@
   this->Bind("STOP_TIME"_s, this->StopTime);
   this->Bind("TEST_LOAD"_s, this->TestLoad);
   this->Bind("RESOURCE_SPEC_FILE"_s, this->ResourceSpecFile);
+  this->Bind("STOP_ON_FAILURE"_s, this->StopOnFailure);
 }
 
 cmCTestGenericHandler* cmCTestTestCommand::InitializeHandler()
@@ -52,6 +54,13 @@
     }
   }
   this->CTest->SetTimeOut(timeout);
+
+  const char* resourceSpecFile =
+    this->Makefile->GetDefinition("CTEST_RESOURCE_SPEC_FILE");
+  if (this->ResourceSpecFile.empty() && resourceSpecFile) {
+    this->ResourceSpecFile = resourceSpecFile;
+  }
+
   cmCTestGenericHandler* handler = this->InitializeActualHandler();
   if (!this->Start.empty() || !this->End.empty() || !this->Stride.empty()) {
     handler->SetOption(
@@ -83,6 +92,9 @@
     handler->SetOption("ExcludeFixtureCleanupRegularExpression",
                        this->ExcludeFixtureCleanup.c_str());
   }
+  if (this->StopOnFailure) {
+    handler->SetOption("StopOnFailure", "ON");
+  }
   if (!this->ParallelLevel.empty()) {
     handler->SetOption("ParallelLevel", this->ParallelLevel.c_str());
   }
@@ -105,13 +117,13 @@
   unsigned long testLoad;
   const char* ctestTestLoad = this->Makefile->GetDefinition("CTEST_TEST_LOAD");
   if (!this->TestLoad.empty()) {
-    if (!cmStrToULong(this->TestLoad.c_str(), &testLoad)) {
+    if (!cmStrToULong(this->TestLoad, &testLoad)) {
       testLoad = 0;
       cmCTestLog(this->CTest, WARNING,
                  "Invalid value for 'TEST_LOAD' : " << this->TestLoad
                                                     << std::endl);
     }
-  } else if (ctestTestLoad && *ctestTestLoad) {
+  } else if (cmNonempty(ctestTestLoad)) {
     if (!cmStrToULong(ctestTestLoad, &testLoad)) {
       testLoad = 0;
       cmCTestLog(this->CTest, WARNING,
@@ -123,10 +135,10 @@
   }
   handler->SetTestLoad(testLoad);
 
-  if (const char* labelsForSubprojects =
-        this->Makefile->GetDefinition("CTEST_LABELS_FOR_SUBPROJECTS")) {
+  if (cmProp labelsForSubprojects =
+        this->Makefile->GetDef("CTEST_LABELS_FOR_SUBPROJECTS")) {
     this->CTest->SetCTestConfiguration("LabelsForSubprojects",
-                                       labelsForSubprojects, this->Quiet);
+                                       *labelsForSubprojects, this->Quiet);
   }
 
   handler->SetQuiet(this->Quiet);
diff --git a/Source/CTest/cmCTestTestCommand.h b/Source/CTest/cmCTestTestCommand.h
index 2345afb..7925586 100644
--- a/Source/CTest/cmCTestTestCommand.h
+++ b/Source/CTest/cmCTestTestCommand.h
@@ -60,6 +60,7 @@
   std::string StopTime;
   std::string TestLoad;
   std::string ResourceSpecFile;
+  bool StopOnFailure = false;
 };
 
 #endif
diff --git a/Source/CTest/cmCTestTestHandler.cxx b/Source/CTest/cmCTestTestHandler.cxx
index 4f324ea..70e84ee 100644
--- a/Source/CTest/cmCTestTestHandler.cxx
+++ b/Source/CTest/cmCTestTestHandler.cxx
@@ -5,7 +5,7 @@
 #include <algorithm>
 #include <chrono>
 #include <cmath>
-#include <cstddef>
+#include <cstddef> // IWYU pragma: keep
 #include <cstdio>
 #include <cstdlib>
 #include <cstring>
@@ -18,6 +18,9 @@
 #include <utility>
 
 #include <cm/memory>
+#include <cm/string_view>
+#include <cmext/algorithm>
+#include <cmext/string_view>
 
 #include "cmsys/FStream.hxx"
 #include <cmsys/Base64.h>
@@ -26,7 +29,6 @@
 
 #include "cm_utf8.h"
 
-#include "cmAlgorithms.h"
 #include "cmCTest.h"
 #include "cmCTestMultiProcessHandler.h"
 #include "cmCTestResourceGroupsLexerHelper.h"
@@ -406,7 +408,9 @@
   // start the real time clock
   auto clock_start = std::chrono::steady_clock::now();
 
-  this->ProcessDirectory(passed, failed);
+  if (!this->ProcessDirectory(passed, failed)) {
+    return -1;
+  }
 
   auto clock_finish = std::chrono::steady_clock::now();
 
@@ -510,6 +514,10 @@
     this->CTest->SetParallelLevel(atoi(this->GetOption("ParallelLevel")));
   }
 
+  if (this->GetOption("StopOnFailure")) {
+    this->CTest->SetStopOnFailure(true);
+  }
+
   const char* val;
   val = this->GetOption("LabelRegularExpression");
   if (val) {
@@ -543,22 +551,11 @@
   if (val) {
     this->ExcludeFixtureCleanupRegExp = val;
   }
-  this->SetRerunFailed(cmIsOn(this->GetOption("RerunFailed")));
-
   val = this->GetOption("ResourceSpecFile");
   if (val) {
-    this->UseResourceSpec = true;
     this->ResourceSpecFile = val;
-    auto result = this->ResourceSpec.ReadFromJSONFile(val);
-    if (result != cmCTestResourceSpec::ReadFileResult::READ_OK) {
-      cmCTestLog(this->CTest, ERROR_MESSAGE,
-                 "Could not read/parse resource spec file "
-                   << val << ": "
-                   << cmCTestResourceSpec::ResultToString(result)
-                   << std::endl);
-      return false;
-    }
   }
+  this->SetRerunFailed(cmIsOn(this->GetOption("RerunFailed")));
 
   return true;
 }
@@ -718,7 +715,7 @@
     cmCTestTestProperties& p = *result.Properties;
     for (std::string const& l : p.Labels) {
       // only use labels found in labels
-      if (cmContains(labels, l)) {
+      if (cm::contains(labels, l)) {
         labelTimes[l] +=
           result.ExecutionTime.count() * result.Properties->Processors;
         ++labelCounts[l];
@@ -860,14 +857,15 @@
 
     if (this->UseUnion) {
       // if it is not in the list and not in the regexp then skip
-      if ((!this->TestsToRun.empty() && !cmContains(this->TestsToRun, cnt)) &&
+      if ((!this->TestsToRun.empty() &&
+           !cm::contains(this->TestsToRun, cnt)) &&
           !tp.IsInBasedOnREOptions) {
         continue;
       }
     } else {
       // is this test in the list of tests to run? If not then skip it
       if ((!this->TestsToRun.empty() &&
-           !cmContains(this->TestsToRun, inREcnt)) ||
+           !cm::contains(this->TestsToRun, inREcnt)) ||
           !tp.IsInBasedOnREOptions) {
         continue;
       }
@@ -896,7 +894,7 @@
     cnt++;
 
     // if this test is not in our list of tests to run, then skip it.
-    if (!this->TestsToRun.empty() && !cmContains(this->TestsToRun, cnt)) {
+    if (!this->TestsToRun.empty() && !cm::contains(this->TestsToRun, cnt)) {
       continue;
     }
 
@@ -1015,7 +1013,7 @@
       for (auto sIt = setupRange.first; sIt != setupRange.second; ++sIt) {
         const std::string& setupTestName = sIt->second->Name;
         tests[i].RequireSuccessDepends.insert(setupTestName);
-        if (!cmContains(tests[i].Depends, setupTestName)) {
+        if (!cm::contains(tests[i].Depends, setupTestName)) {
           tests[i].Depends.push_back(setupTestName);
         }
       }
@@ -1119,7 +1117,7 @@
         const std::vector<size_t>& indices = cIt->second;
         for (size_t index : indices) {
           const std::string& reqTestName = tests[index].Name;
-          if (!cmContains(p.Depends, reqTestName)) {
+          if (!cm::contains(p.Depends, reqTestName)) {
             p.Depends.push_back(reqTestName);
           }
         }
@@ -1132,7 +1130,7 @@
         const std::vector<size_t>& indices = cIt->second;
         for (size_t index : indices) {
           const std::string& setupTestName = tests[index].Name;
-          if (!cmContains(p.Depends, setupTestName)) {
+          if (!cm::contains(p.Depends, setupTestName)) {
             p.Depends.push_back(setupTestName);
           }
         }
@@ -1259,7 +1257,7 @@
   return ret;
 }
 
-void cmCTestTestHandler::ProcessDirectory(std::vector<std::string>& passed,
+bool cmCTestTestHandler::ProcessDirectory(std::vector<std::string>& passed,
                                           std::vector<std::string>& failed)
 {
   this->ComputeTestList();
@@ -1267,7 +1265,7 @@
   this->StartTestTime = std::chrono::system_clock::now();
   auto elapsed_time_start = std::chrono::steady_clock::now();
 
-  cmCTestMultiProcessHandler* parallel = new cmCTestMultiProcessHandler;
+  auto parallel = cm::make_unique<cmCTestMultiProcessHandler>();
   parallel->SetCTest(this->CTest);
   parallel->SetParallelLevel(this->CTest->GetParallelLevel());
   parallel->SetTestHandler(this);
@@ -1283,7 +1281,17 @@
   } else {
     parallel->SetTestLoad(this->CTest->GetTestLoad());
   }
-  if (this->UseResourceSpec) {
+  if (!this->ResourceSpecFile.empty()) {
+    this->UseResourceSpec = true;
+    auto result = this->ResourceSpec.ReadFromJSONFile(this->ResourceSpecFile);
+    if (result != cmCTestResourceSpec::ReadFileResult::READ_OK) {
+      cmCTestLog(this->CTest, ERROR_MESSAGE,
+                 "Could not read/parse resource spec file "
+                   << this->ResourceSpecFile << ": "
+                   << cmCTestResourceSpec::ResultToString(result)
+                   << std::endl);
+      return false;
+    }
     parallel->InitResourceAllocator(this->ResourceSpec);
   }
 
@@ -1338,12 +1346,13 @@
   } else {
     parallel->RunTests();
   }
-  delete parallel;
   this->EndTest = this->CTest->CurrentTime();
   this->EndTestTime = std::chrono::system_clock::now();
   this->ElapsedTestingTime =
     std::chrono::steady_clock::now() - elapsed_time_start;
   *this->LogFile << "End testing: " << this->CTest->CurrentTime() << std::endl;
+
+  return true;
 }
 
 void cmCTestTestHandler::GenerateTestCommand(
@@ -1365,7 +1374,7 @@
   xml.StartElement("TestList");
   for (cmCTestTestResult const& result : this->TestResults) {
     std::string testPath = result.Path + "/" + result.Name;
-    xml.Element("Test", this->CTest->GetShortPathToFile(testPath.c_str()));
+    xml.Element("Test", this->CTest->GetShortPathToFile(testPath));
   }
   xml.EndElement(); // TestList
   for (cmCTestTestResult& result : this->TestResults) {
@@ -1423,6 +1432,12 @@
     xml.Attribute("name", "Command Line");
     xml.Element("Value", result.FullCommandLine);
     xml.EndElement(); // NamedMeasurement
+
+    xml.StartElement("NamedMeasurement");
+    xml.Attribute("type", "text/string");
+    xml.Attribute("name", "Environment");
+    xml.Element("Value", result.Environment);
+    xml.EndElement(); // NamedMeasurement
     for (auto const& measure : result.Properties->Measurements) {
       xml.StartElement("NamedMeasurement");
       xml.Attribute("type", "text/string");
@@ -1468,8 +1483,8 @@
   }
   std::string testPath = result.Path + "/" + result.Name;
   xml.Element("Name", result.Name);
-  xml.Element("Path", this->CTest->GetShortPathToFile(result.Path.c_str()));
-  xml.Element("FullName", this->CTest->GetShortPathToFile(testPath.c_str()));
+  xml.Element("Path", this->CTest->GetShortPathToFile(result.Path));
+  xml.Element("FullName", this->CTest->GetShortPathToFile(testPath));
   xml.Element("FullCommandLine", result.FullCommandLine);
 }
 
@@ -1531,12 +1546,12 @@
 }
 
 // Find the appropriate executable to run for a test
-std::string cmCTestTestHandler::FindTheExecutable(const char* exe)
+std::string cmCTestTestHandler::FindTheExecutable(const std::string& exe)
 {
   std::string resConfig;
   std::vector<std::string> extraPaths;
   std::vector<std::string> failedPaths;
-  if (strcmp(exe, "NOT_AVAILABLE") == 0) {
+  if (exe == "NOT_AVAILABLE") {
     return exe;
   }
   return cmCTestTestHandler::FindExecutable(this->CTest, exe, resConfig,
@@ -1592,7 +1607,7 @@
 
 // Find the appropriate executable to run for a test
 std::string cmCTestTestHandler::FindExecutable(
-  cmCTest* ctest, const char* testCommand, std::string& resultingConfig,
+  cmCTest* ctest, const std::string& testCommand, std::string& resultingConfig,
   std::vector<std::string>& extraPaths, std::vector<std::string>& failed)
 {
   // now run the compiled test if we can find it
@@ -1742,6 +1757,10 @@
   if (cmSystemTools::GetErrorOccuredFlag()) {
     return;
   }
+  const char* specFile = mf.GetDefinition("CTEST_RESOURCE_SPEC_FILE");
+  if (this->ResourceSpecFile.empty() && specFile) {
+    this->ResourceSpecFile = specFile;
+  }
   cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
                      "Done constructing a list of tests" << std::endl,
                      this->Quiet);
@@ -1894,7 +1913,8 @@
         continue;
       }
 
-      int val = atoi(line.substr(0, pos).c_str());
+      line.erase(pos);
+      int val = atoi(line.c_str());
       this->TestsToRun.push_back(val);
     }
     ifs.close();
@@ -2016,13 +2036,13 @@
                                 | std::ios::binary
 #endif
           );
-          unsigned char* file_buffer = new unsigned char[len + 1];
-          ifs.read(reinterpret_cast<char*>(file_buffer), len);
-          unsigned char* encoded_buffer = new unsigned char[static_cast<int>(
-            static_cast<double>(len) * 1.5 + 5.0)];
+          auto file_buffer = cm::make_unique<unsigned char[]>(len + 1);
+          ifs.read(reinterpret_cast<char*>(file_buffer.get()), len);
+          auto encoded_buffer = cm::make_unique<unsigned char[]>(
+            static_cast<int>(static_cast<double>(len) * 1.5 + 5.0));
 
-          size_t rlen =
-            cmsysBase64_Encode(file_buffer, len, encoded_buffer, 1);
+          size_t rlen = cmsysBase64_Encode(file_buffer.get(), len,
+                                           encoded_buffer.get(), 1);
 
           xml.StartElement("NamedMeasurement");
           xml.Attribute(measurementfile.match(1).c_str(),
@@ -2039,8 +2059,6 @@
           }
           xml.Element("Value", ostr.str());
           xml.EndElement(); // NamedMeasurement
-          delete[] file_buffer;
-          delete[] encoded_buffer;
         }
       } else {
         int idx = 4;
@@ -2085,19 +2103,18 @@
   if (cmSystemTools::FileExists(in)) {
     cmsys::ifstream fin(in);
     unsigned long filelen = cmSystemTools::FileLength(in);
-    char* buff = new char[filelen + 1];
-    fin.getline(buff, filelen);
+    auto buff = cm::make_unique<char[]>(filelen + 1);
+    fin.getline(buff.get(), filelen);
     buff[fin.gcount()] = 0;
-    this->TestsToRunString = buff;
-    delete[] buff;
+    this->TestsToRunString = buff.get();
   }
 }
 
-bool cmCTestTestHandler::CleanTestOutput(std::string& output, size_t length)
+void cmCTestTestHandler::CleanTestOutput(std::string& output, size_t length)
 {
   if (!length || length >= output.size() ||
       output.find("CTEST_FULL_OUTPUT") != std::string::npos) {
-    return true;
+    return;
   }
 
   // Truncate at given length but do not break in the middle of a multi-byte
@@ -2118,7 +2135,7 @@
       ++current;
     }
   }
-  output = output.substr(0, current - begin);
+  output.erase(current - begin);
 
   // Append truncation message.
   std::ostringstream msg;
@@ -2128,7 +2145,6 @@
          "of "
       << length << " bytes.\n";
   output += msg.str();
-  return true;
 }
 
 bool cmCTestTestHandler::SetTestsProperties(
@@ -2149,16 +2165,16 @@
   }
   ++it; // skip PROPERTIES
   for (; it != args.end(); ++it) {
-    std::string key = *it;
+    std::string const& key = *it;
     ++it;
     if (it == args.end()) {
       break;
     }
-    std::string val = *it;
+    std::string const& val = *it;
     for (std::string const& t : tests) {
       for (cmCTestTestProperties& rt : this->TestList) {
         if (t == rt.Name) {
-          if (key == "_BACKTRACE_TRIPLES") {
+          if (key == "_BACKTRACE_TRIPLES"_s) {
             std::vector<std::string> triples;
             // allow empty args in the triples
             cmExpandList(val, triples, true);
@@ -2182,91 +2198,70 @@
                 rt.Backtrace = rt.Backtrace.Push(fc);
               }
             }
-          }
-          if (key == "WILL_FAIL") {
+          } else if (key == "WILL_FAIL"_s) {
             rt.WillFail = cmIsOn(val);
-          }
-          if (key == "DISABLED") {
+          } else if (key == "DISABLED"_s) {
             rt.Disabled = cmIsOn(val);
-          }
-          if (key == "ATTACHED_FILES") {
+          } else if (key == "ATTACHED_FILES"_s) {
             cmExpandList(val, rt.AttachedFiles);
-          }
-          if (key == "ATTACHED_FILES_ON_FAIL") {
+          } else if (key == "ATTACHED_FILES_ON_FAIL"_s) {
             cmExpandList(val, rt.AttachOnFail);
-          }
-          if (key == "RESOURCE_LOCK") {
+          } else if (key == "RESOURCE_LOCK"_s) {
             std::vector<std::string> lval = cmExpandedList(val);
 
             rt.LockedResources.insert(lval.begin(), lval.end());
-          }
-          if (key == "FIXTURES_SETUP") {
+          } else if (key == "FIXTURES_SETUP"_s) {
             std::vector<std::string> lval = cmExpandedList(val);
 
             rt.FixturesSetup.insert(lval.begin(), lval.end());
-          }
-          if (key == "FIXTURES_CLEANUP") {
+          } else if (key == "FIXTURES_CLEANUP"_s) {
             std::vector<std::string> lval = cmExpandedList(val);
 
             rt.FixturesCleanup.insert(lval.begin(), lval.end());
-          }
-          if (key == "FIXTURES_REQUIRED") {
+          } else if (key == "FIXTURES_REQUIRED"_s) {
             std::vector<std::string> lval = cmExpandedList(val);
 
             rt.FixturesRequired.insert(lval.begin(), lval.end());
-          }
-          if (key == "TIMEOUT") {
+          } else if (key == "TIMEOUT"_s) {
             rt.Timeout = cmDuration(atof(val.c_str()));
             rt.ExplicitTimeout = true;
-          }
-          if (key == "COST") {
+          } else if (key == "COST"_s) {
             rt.Cost = static_cast<float>(atof(val.c_str()));
-          }
-          if (key == "REQUIRED_FILES") {
+          } else if (key == "REQUIRED_FILES"_s) {
             cmExpandList(val, rt.RequiredFiles);
-          }
-          if (key == "RUN_SERIAL") {
+          } else if (key == "RUN_SERIAL"_s) {
             rt.RunSerial = cmIsOn(val);
-          }
-          if (key == "FAIL_REGULAR_EXPRESSION") {
+          } else if (key == "FAIL_REGULAR_EXPRESSION"_s) {
             std::vector<std::string> lval = cmExpandedList(val);
             for (std::string const& cr : lval) {
               rt.ErrorRegularExpressions.emplace_back(cr, cr);
             }
-          }
-          if (key == "SKIP_REGULAR_EXPRESSION") {
+          } else if (key == "SKIP_REGULAR_EXPRESSION"_s) {
             std::vector<std::string> lval = cmExpandedList(val);
             for (std::string const& cr : lval) {
               rt.SkipRegularExpressions.emplace_back(cr, cr);
             }
-          }
-          if (key == "PROCESSORS") {
+          } else if (key == "PROCESSORS"_s) {
             rt.Processors = atoi(val.c_str());
             if (rt.Processors < 1) {
               rt.Processors = 1;
             }
-          }
-          if (key == "PROCESSOR_AFFINITY") {
+          } else if (key == "PROCESSOR_AFFINITY"_s) {
             rt.WantAffinity = cmIsOn(val);
-          }
-          if (key == "RESOURCE_GROUPS") {
+          } else if (key == "RESOURCE_GROUPS"_s) {
             if (!ParseResourceGroupsProperty(val, rt.ResourceGroups)) {
               return false;
             }
-          }
-          if (key == "SKIP_RETURN_CODE") {
+          } else if (key == "SKIP_RETURN_CODE"_s) {
             rt.SkipReturnCode = atoi(val.c_str());
             if (rt.SkipReturnCode < 0 || rt.SkipReturnCode > 255) {
               rt.SkipReturnCode = -1;
             }
-          }
-          if (key == "DEPENDS") {
+          } else if (key == "DEPENDS"_s) {
             cmExpandList(val, rt.Depends);
-          }
-          if (key == "ENVIRONMENT") {
+          } else if (key == "ENVIRONMENT"_s) {
             cmExpandList(val, rt.Environment);
-          }
-          if (key == "LABELS") {
+          } else if (key == "LABELS"_s) {
             std::vector<std::string> Labels = cmExpandedList(val);
             rt.Labels.insert(rt.Labels.end(), Labels.begin(), Labels.end());
             // sort the array
@@ -2274,8 +2269,7 @@
             // remove duplicates
             auto new_end = std::unique(rt.Labels.begin(), rt.Labels.end());
             rt.Labels.erase(new_end, rt.Labels.end());
-          }
-          if (key == "MEASUREMENT") {
+          } else if (key == "MEASUREMENT"_s) {
             size_t pos = val.find_first_of('=');
             if (pos != std::string::npos) {
               std::string mKey = val.substr(0, pos);
@@ -2284,17 +2278,14 @@
             } else {
               rt.Measurements[val] = "1";
             }
-          }
-          if (key == "PASS_REGULAR_EXPRESSION") {
+          } else if (key == "PASS_REGULAR_EXPRESSION"_s) {
             std::vector<std::string> lval = cmExpandedList(val);
             for (std::string const& cr : lval) {
               rt.RequiredRegularExpressions.emplace_back(cr, cr);
             }
-          }
-          if (key == "WORKING_DIRECTORY") {
+          } else if (key == "WORKING_DIRECTORY"_s) {
             rt.Directory = val;
-          }
-          if (key == "TIMEOUT_AFTER_MATCH") {
+          } else if (key == "TIMEOUT_AFTER_MATCH"_s) {
             std::vector<std::string> propArgs = cmExpandedList(val);
             if (propArgs.size() != 2) {
               cmCTestLog(this->CTest, WARNING,
@@ -2334,16 +2325,16 @@
   }
   ++it; // skip PROPERTIES
   for (; it != args.end(); ++it) {
-    std::string key = *it;
+    std::string const& key = *it;
     ++it;
     if (it == args.end()) {
       break;
     }
-    std::string val = *it;
+    std::string const& val = *it;
     for (cmCTestTestProperties& rt : this->TestList) {
       std::string cwd = cmSystemTools::GetCurrentWorkingDirectory();
       if (cwd == rt.Directory) {
-        if (key == "LABELS") {
+        if (key == "LABELS"_s) {
           std::vector<std::string> DirectoryLabels = cmExpandedList(val);
           rt.Labels.insert(rt.Labels.end(), DirectoryLabels.begin(),
                            DirectoryLabels.end());
@@ -2422,10 +2413,9 @@
   test.SkipReturnCode = -1;
   test.PreviousRuns = 0;
   if (this->UseIncludeRegExpFlag &&
-      !this->IncludeTestsRegularExpression.find(testname)) {
-    test.IsInBasedOnREOptions = false;
-  } else if (this->UseExcludeRegExpFlag && !this->UseExcludeRegExpFirst &&
-             this->ExcludeTestsRegularExpression.find(testname)) {
+      (!this->IncludeTestsRegularExpression.find(testname) ||
+       (!this->UseExcludeRegExpFirst &&
+        this->ExcludeTestsRegularExpression.find(testname)))) {
     test.IsInBasedOnREOptions = false;
   }
   this->TestList.push_back(test);
diff --git a/Source/CTest/cmCTestTestHandler.h b/Source/CTest/cmCTestTestHandler.h
index b1c8755..b26f8a6 100644
--- a/Source/CTest/cmCTestTestHandler.h
+++ b/Source/CTest/cmCTestTestHandler.h
@@ -169,6 +169,7 @@
     std::string Path;
     std::string Reason;
     std::string FullCommandLine;
+    std::string Environment;
     cmDuration ExecutionTime;
     std::int64_t ReturnValue;
     int Status;
@@ -197,7 +198,8 @@
                                 std::string filepath, std::string& filename);
 
   // full signature static method to find an executable
-  static std::string FindExecutable(cmCTest* ctest, const char* testCommand,
+  static std::string FindExecutable(cmCTest* ctest,
+                                    const std::string& testCommand,
                                     std::string& resultingConfig,
                                     std::vector<std::string>& extraPaths,
                                     std::vector<std::string>& failed);
@@ -235,7 +237,7 @@
   void AttachFiles(cmXMLWriter& xml, cmCTestTestResult& result);
 
   //! Clean test output to specified length
-  bool CleanTestOutput(std::string& output, size_t length);
+  void CleanTestOutput(std::string& output, size_t length);
 
   cmDuration ElapsedTestingTime;
 
@@ -278,7 +280,7 @@
   /**
    * Run the tests for a directory and any subdirectories
    */
-  void ProcessDirectory(std::vector<std::string>& passed,
+  bool ProcessDirectory(std::vector<std::string>& passed,
                         std::vector<std::string>& failed);
 
   /**
@@ -308,7 +310,7 @@
   /**
    * Find the executable for a test
    */
-  std::string FindTheExecutable(const char* exe);
+  std::string FindTheExecutable(const std::string& exe);
 
   std::string GetTestStatus(cmCTestTestResult const&);
   void ExpandTestsToRunInformation(size_t numPossibleTests);
diff --git a/Source/CTest/cmCTestUpdateCommand.cxx b/Source/CTest/cmCTestUpdateCommand.cxx
index 673eb9a..95cae13 100644
--- a/Source/CTest/cmCTestUpdateCommand.cxx
+++ b/Source/CTest/cmCTestUpdateCommand.cxx
@@ -11,14 +11,13 @@
 {
   if (!this->Source.empty()) {
     this->CTest->SetCTestConfiguration(
-      "SourceDirectory", cmSystemTools::CollapseFullPath(this->Source).c_str(),
+      "SourceDirectory", cmSystemTools::CollapseFullPath(this->Source),
       this->Quiet);
   } else {
     this->CTest->SetCTestConfiguration(
       "SourceDirectory",
       cmSystemTools::CollapseFullPath(
-        this->Makefile->GetDefinition("CTEST_SOURCE_DIRECTORY"))
-        .c_str(),
+        this->Makefile->GetDefinition("CTEST_SOURCE_DIRECTORY")),
       this->Quiet);
   }
   std::string source_dir =
diff --git a/Source/CTest/cmCTestUploadCommand.cxx b/Source/CTest/cmCTestUploadCommand.cxx
index eaef1ca..f86ee0d 100644
--- a/Source/CTest/cmCTestUploadCommand.cxx
+++ b/Source/CTest/cmCTestUploadCommand.cxx
@@ -6,8 +6,7 @@
 #include <sstream>
 
 #include <cm/vector>
-
-#include "cm_static_string_view.hxx"
+#include <cmext/string_view>
 
 #include "cmCTest.h"
 #include "cmCTestUploadHandler.h"
diff --git a/Source/CTest/cmCTestVC.cxx b/Source/CTest/cmCTestVC.cxx
index 6026c69..452d714 100644
--- a/Source/CTest/cmCTestVC.cxx
+++ b/Source/CTest/cmCTestVC.cxx
@@ -38,7 +38,7 @@
   this->SourceDirectory = dir;
 }
 
-bool cmCTestVC::InitialCheckout(const char* command)
+bool cmCTestVC::InitialCheckout(const std::string& command)
 {
   cmCTestLog(this->CTest, HANDLER_OUTPUT,
              "   First perform the initial checkout: " << command << "\n");
diff --git a/Source/CTest/cmCTestVC.h b/Source/CTest/cmCTestVC.h
index 2a4765d..3037e01 100644
--- a/Source/CTest/cmCTestVC.h
+++ b/Source/CTest/cmCTestVC.h
@@ -36,7 +36,7 @@
   std::string GetNightlyTime();
 
   /** Prepare the work tree.  */
-  bool InitialCheckout(const char* command);
+  bool InitialCheckout(const std::string& command);
 
   /** Perform cleanup operations on the work tree.  */
   void Cleanup();
diff --git a/Source/CTest/cmParseCacheCoverage.cxx b/Source/CTest/cmParseCacheCoverage.cxx
index 8c4da75..84d7de0 100644
--- a/Source/CTest/cmParseCacheCoverage.cxx
+++ b/Source/CTest/cmParseCacheCoverage.cxx
@@ -4,6 +4,7 @@
 #include <cstdlib>
 #include <map>
 #include <utility>
+#include <vector>
 
 #include "cmsys/Directory.hxx"
 #include "cmsys/FStream.hxx"
@@ -19,7 +20,7 @@
 {
 }
 
-bool cmParseCacheCoverage::LoadCoverageData(const char* d)
+bool cmParseCacheCoverage::LoadCoverageData(std::string const& d)
 {
   // load all the .mcov files in the specified directory
   cmsys::Directory dir;
@@ -69,26 +70,6 @@
   }
 }
 
-bool cmParseCacheCoverage::SplitString(std::vector<std::string>& args,
-                                       std::string const& line)
-{
-  std::string::size_type pos1 = 0;
-  std::string::size_type pos2 = line.find(',', 0);
-  if (pos2 == std::string::npos) {
-    return false;
-  }
-  std::string arg;
-  while (pos2 != std::string::npos) {
-    arg = line.substr(pos1, pos2 - pos1);
-    args.push_back(arg);
-    pos1 = pos2 + 1;
-    pos2 = line.find(',', pos1);
-  }
-  arg = line.substr(pos1);
-  args.push_back(arg);
-  return true;
-}
-
 bool cmParseCacheCoverage::ReadCMCovFile(const char* file)
 {
   cmsys::ifstream in(file);
@@ -97,7 +78,6 @@
     return false;
   }
   std::string line;
-  std::vector<std::string> separateLine;
   if (!cmSystemTools::GetLineFromStream(in, line)) {
     cmCTestLog(this->CTest, ERROR_MESSAGE,
                "Empty file : " << file
@@ -106,8 +86,8 @@
                                << line << "]\n");
     return false;
   }
-  separateLine.clear();
-  this->SplitString(separateLine, line);
+  std::vector<std::string> separateLine =
+    cmSystemTools::SplitString(line, ',');
   if (separateLine.size() != 4 || separateLine[0] != "Routine" ||
       separateLine[1] != "Line" || separateLine[2] != "RtnLine" ||
       separateLine[3] != "Code") {
@@ -120,10 +100,8 @@
   std::string routine;
   std::string filepath;
   while (cmSystemTools::GetLineFromStream(in, line)) {
-    // clear out line argument vector
-    separateLine.clear();
     // parse the comma separated line
-    this->SplitString(separateLine, line);
+    separateLine = cmSystemTools::SplitString(line, ',');
     // might have more because code could have a quoted , in it
     // but we only care about the first 3 args anyway
     if (separateLine.size() < 4) {
@@ -155,7 +133,7 @@
     // if we have a routine name, check for end of routine
     else {
       // Totals in arg 0 marks the end of a routine
-      if (separateLine[0].substr(0, 6) == "Totals") {
+      if (cmHasLiteralPrefix(separateLine[0], "Totals")) {
         routine.clear(); // at the end of this routine
         filepath.clear();
         continue; // move to next line
diff --git a/Source/CTest/cmParseCacheCoverage.h b/Source/CTest/cmParseCacheCoverage.h
index e89b9e4..a8200b7 100644
--- a/Source/CTest/cmParseCacheCoverage.h
+++ b/Source/CTest/cmParseCacheCoverage.h
@@ -6,7 +6,6 @@
 #include "cmConfigure.h" // IWYU pragma: keep
 
 #include <string>
-#include <vector>
 
 #include "cmParseMumpsCoverage.h"
 
@@ -26,13 +25,11 @@
 
 protected:
   // implement virtual from parent
-  bool LoadCoverageData(const char* dir) override;
+  bool LoadCoverageData(std::string const& dir) override;
   // remove files with no coverage
   void RemoveUnCoveredFiles();
   // Read a single mcov file
   bool ReadCMCovFile(const char* f);
-  // split a string based on ,
-  bool SplitString(std::vector<std::string>& args, std::string const& line);
 };
 
 #endif
diff --git a/Source/CTest/cmParseCoberturaCoverage.cxx b/Source/CTest/cmParseCoberturaCoverage.cxx
index 05da84e..711a856 100644
--- a/Source/CTest/cmParseCoberturaCoverage.cxx
+++ b/Source/CTest/cmParseCoberturaCoverage.cxx
@@ -67,7 +67,7 @@
           // Check if this is an absolute path that falls within our
           // source or binary directories.
           for (std::string const& filePath : FilePaths) {
-            if (filename.find(filePath) == 0) {
+            if (cmHasPrefix(filename, filePath)) {
               this->CurFileName = filename;
               break;
             }
diff --git a/Source/CTest/cmParseGTMCoverage.cxx b/Source/CTest/cmParseGTMCoverage.cxx
index 1dc5b70..14417cc 100644
--- a/Source/CTest/cmParseGTMCoverage.cxx
+++ b/Source/CTest/cmParseGTMCoverage.cxx
@@ -19,7 +19,7 @@
 {
 }
 
-bool cmParseGTMCoverage::LoadCoverageData(const char* d)
+bool cmParseGTMCoverage::LoadCoverageData(std::string const& d)
 {
   // load all the .mcov files in the specified directory
   cmsys::Directory dir;
diff --git a/Source/CTest/cmParseGTMCoverage.h b/Source/CTest/cmParseGTMCoverage.h
index fe0ae0b..41cc7f5 100644
--- a/Source/CTest/cmParseGTMCoverage.h
+++ b/Source/CTest/cmParseGTMCoverage.h
@@ -25,7 +25,7 @@
 
 protected:
   // implement virtual from parent
-  bool LoadCoverageData(const char* dir) override;
+  bool LoadCoverageData(std::string const& dir) override;
   // Read a single mcov file
   bool ReadMCovFile(const char* f);
   // find out what line in a mumps file (filepath) the given entry point
diff --git a/Source/CTest/cmParseMumpsCoverage.cxx b/Source/CTest/cmParseMumpsCoverage.cxx
index b16f101..dc3064d 100644
--- a/Source/CTest/cmParseMumpsCoverage.cxx
+++ b/Source/CTest/cmParseMumpsCoverage.cxx
@@ -39,9 +39,9 @@
       std::string type = line.substr(0, pos);
       std::string path = line.substr(pos + 1);
       if (type == "packages") {
-        this->LoadPackages(path.c_str());
+        this->LoadPackages(path);
       } else if (type == "coverage_dir") {
-        this->LoadCoverageData(path.c_str());
+        this->LoadCoverageData(path);
       } else {
         cmCTestLog(this->CTest, ERROR_MESSAGE,
                    "Parse Error in Mumps coverage file :\n"
@@ -105,7 +105,7 @@
   }
 }
 
-bool cmParseMumpsCoverage::LoadPackages(const char* d)
+bool cmParseMumpsCoverage::LoadPackages(std::string const& d)
 {
   cmsys::Glob glob;
   glob.RecurseOn();
@@ -113,7 +113,8 @@
   glob.FindFiles(pat);
   for (std::string& file : glob.GetFiles()) {
     std::string name = cmSystemTools::GetFilenameName(file);
-    this->RoutineToDirectory[name.substr(0, name.size() - 2)] = file;
+    name.erase(name.size() - 2);
+    this->RoutineToDirectory[name] = file;
     // initialize each file, this is left out until CDash is fixed
     // to handle large numbers of files
     this->InitializeMumpsFile(file);
diff --git a/Source/CTest/cmParseMumpsCoverage.h b/Source/CTest/cmParseMumpsCoverage.h
index 2c54495..8c08702 100644
--- a/Source/CTest/cmParseMumpsCoverage.h
+++ b/Source/CTest/cmParseMumpsCoverage.h
@@ -29,10 +29,10 @@
 protected:
   // sub classes will use this to
   // load all coverage files found in the given directory
-  virtual bool LoadCoverageData(const char* d) = 0;
+  virtual bool LoadCoverageData(std::string const& d) = 0;
   // search the package directory for mumps files and fill
   // in the RoutineToDirectory map
-  bool LoadPackages(const char* dir);
+  bool LoadPackages(std::string const& dir);
   // initialize the coverage information for a single mumps file
   void InitializeMumpsFile(std::string& file);
   // Find mumps file for routine
diff --git a/Source/CTest/cmParsePHPCoverage.cxx b/Source/CTest/cmParsePHPCoverage.cxx
index a494b92..044f518 100644
--- a/Source/CTest/cmParsePHPCoverage.cxx
+++ b/Source/CTest/cmParsePHPCoverage.cxx
@@ -3,6 +3,8 @@
 #include <cstdlib>
 #include <cstring>
 
+#include <cm/memory>
+
 #include "cmsys/Directory.hxx"
 #include "cmsys/FStream.hxx"
 
@@ -142,17 +144,15 @@
   int size = 0;
   if (this->ReadInt(in, size)) {
     size++; // add one for null termination
-    char* s = new char[size + 1];
+    auto s = cm::make_unique<char[]>(size + 1);
     // read open quote
     if (in.get(c) && c != '"') {
-      delete[] s;
       return false;
     }
     // read the string data
-    in.read(s, size - 1);
+    in.read(s.get(), size - 1);
     s[size - 1] = 0;
-    std::string fileName = s;
-    delete[] s;
+    std::string fileName = s.get();
     // read close quote
     if (in.get(c) && c != '"') {
       cmCTestLog(this->CTest, ERROR_MESSAGE,
diff --git a/Source/CTest/cmProcess.cxx b/Source/CTest/cmProcess.cxx
index 6097aa5..9ee1c17 100644
--- a/Source/CTest/cmProcess.cxx
+++ b/Source/CTest/cmProcess.cxx
@@ -5,6 +5,7 @@
 #include <csignal>
 #include <iostream>
 #include <string>
+#include <utility>
 
 #include <cmext/algorithm>
 
@@ -16,14 +17,13 @@
 #include "cmGetPipes.h"
 #include "cmStringAlgorithms.h"
 #if defined(_WIN32)
-#  include "cm_kwiml.h"
+#  include <cm3p/kwiml/int.h>
 #endif
-#include <utility>
 
 #define CM_PROCESS_BUF_SIZE 65536
 
-cmProcess::cmProcess(cmCTestRunTest& runner)
-  : Runner(runner)
+cmProcess::cmProcess(std::unique_ptr<cmCTestRunTest> runner)
+  : Runner(std::move(runner))
   , Conv(cmProcessOutput::UTF8, CM_PROCESS_BUF_SIZE)
 {
   this->Timeout = cmDuration::zero();
@@ -69,7 +69,7 @@
   cm::uv_timer_ptr timer;
   int status = timer.init(loop, this);
   if (status != 0) {
-    cmCTestLog(this->Runner.GetCTest(), ERROR_MESSAGE,
+    cmCTestLog(this->Runner->GetCTest(), ERROR_MESSAGE,
                "Error initializing timer: " << uv_strerror(status)
                                             << std::endl);
     return false;
@@ -84,7 +84,7 @@
   int fds[2] = { -1, -1 };
   status = cmGetPipes(fds);
   if (status != 0) {
-    cmCTestLog(this->Runner.GetCTest(), ERROR_MESSAGE,
+    cmCTestLog(this->Runner->GetCTest(), ERROR_MESSAGE,
                "Error initializing pipe: " << uv_strerror(status)
                                            << std::endl);
     return false;
@@ -127,7 +127,7 @@
     uv_read_start(pipe_reader, &cmProcess::OnAllocateCB, &cmProcess::OnReadCB);
 
   if (status != 0) {
-    cmCTestLog(this->Runner.GetCTest(), ERROR_MESSAGE,
+    cmCTestLog(this->Runner->GetCTest(), ERROR_MESSAGE,
                "Error starting read events: " << uv_strerror(status)
                                               << std::endl);
     return false;
@@ -135,7 +135,7 @@
 
   status = this->Process.spawn(loop, options, this);
   if (status != 0) {
-    cmCTestLog(this->Runner.GetCTest(), ERROR_MESSAGE,
+    cmCTestLog(this->Runner->GetCTest(), ERROR_MESSAGE,
                "Process not started\n " << this->Command << "\n["
                                         << uv_strerror(status) << "]\n");
     return false;
@@ -152,7 +152,7 @@
 
 void cmProcess::StartTimer()
 {
-  auto properties = this->Runner.GetTestProperties();
+  auto properties = this->Runner->GetTestProperties();
   auto msec =
     std::chrono::duration_cast<std::chrono::milliseconds>(this->Timeout);
 
@@ -222,7 +222,7 @@
     cm::append(this->Output, strdata);
 
     while (this->Output.GetLine(line)) {
-      this->Runner.CheckOutput(line);
+      this->Runner->CheckOutput(line);
       line.clear();
     }
 
@@ -236,13 +236,13 @@
   // The process will provide no more data.
   if (nread != UV_EOF) {
     auto error = static_cast<int>(nread);
-    cmCTestLog(this->Runner.GetCTest(), ERROR_MESSAGE,
+    cmCTestLog(this->Runner->GetCTest(), ERROR_MESSAGE,
                "Error reading stream: " << uv_strerror(error) << std::endl);
   }
 
   // Look for partial last lines.
   if (this->Output.GetLast(line)) {
-    this->Runner.CheckOutput(line);
+    this->Runner->CheckOutput(line);
   }
 
   this->ReadHandleClosed = true;
@@ -339,7 +339,7 @@
   if (this->TotalTime <= cmDuration::zero()) {
     this->TotalTime = cmDuration::zero();
   }
-  this->Runner.FinalizeTest();
+  this->Runner->FinalizeTest();
 }
 
 cmProcess::State cmProcess::GetProcessStatus()
@@ -545,17 +545,17 @@
 #  endif
 #  ifdef SIGABRT
     case SIGABRT:
-      exception_str = "Child aborted";
+      exception_str = "Subprocess aborted";
       break;
 #  endif
 #  ifdef SIGKILL
     case SIGKILL:
-      exception_str = "Child killed";
+      exception_str = "Subprocess killed";
       break;
 #  endif
 #  ifdef SIGTERM
     case SIGTERM:
-      exception_str = "Child terminated";
+      exception_str = "Subprocess terminated";
       break;
 #  endif
 #  ifdef SIGHUP
diff --git a/Source/CTest/cmProcess.h b/Source/CTest/cmProcess.h
index ea72a26..1e6578c 100644
--- a/Source/CTest/cmProcess.h
+++ b/Source/CTest/cmProcess.h
@@ -6,14 +6,15 @@
 #include "cmConfigure.h" // IWYU pragma: keep
 
 #include <chrono>
+#include <memory>
 #include <string>
+#include <utility>
 #include <vector>
 
+#include <cm3p/uv.h>
 #include <stddef.h>
 #include <stdint.h>
 
-#include "cm_uv.h"
-
 #include "cmDuration.h"
 #include "cmProcessOutput.h"
 #include "cmUVHandlePtr.h"
@@ -28,7 +29,7 @@
 class cmProcess
 {
 public:
-  explicit cmProcess(cmCTestRunTest& runner);
+  explicit cmProcess(std::unique_ptr<cmCTestRunTest> runner);
   ~cmProcess();
   void SetCommand(std::string const& command);
   void SetCommandArguments(std::vector<std::string> const& arg);
@@ -70,6 +71,11 @@
   Exception GetExitException();
   std::string GetExitExceptionString();
 
+  std::unique_ptr<cmCTestRunTest> GetRunner()
+  {
+    return std::move(this->Runner);
+  }
+
 private:
   cmDuration Timeout;
   std::chrono::steady_clock::time_point StartTime;
@@ -82,7 +88,7 @@
   cm::uv_timer_ptr Timer;
   std::vector<char> Buf;
 
-  cmCTestRunTest& Runner;
+  std::unique_ptr<cmCTestRunTest> Runner;
   cmProcessOutput Conv;
   int Signal = 0;
   cmProcess::State ProcessState = cmProcess::State::Starting;
diff --git a/Source/Checks/cm_cxx_features.cmake b/Source/Checks/cm_cxx_features.cmake
index 2a67748..e726fc7 100644
--- a/Source/Checks/cm_cxx_features.cmake
+++ b/Source/Checks/cm_cxx_features.cmake
@@ -36,8 +36,6 @@
     string(REGEX REPLACE "[^\n]*icpc: command line warning #10121: overriding [^\n]*" "" check_output "${check_output}")
     # Filter out ld warnings.
     string(REGEX REPLACE "[^\n]*ld: warning: [^\n]*" "" check_output "${check_output}")
-    # Filter out CUDA installation warnings.
-    string(REGEX REPLACE "[^\n]*clang: warning: Unknown CUDA version[^\n]*" "" check_output "${check_output}")
     # If using the feature causes warnings, treat it as broken/unavailable.
     if(check_output MATCHES "(^|[ :])[Ww][Aa][Rr][Nn][Ii][Nn][Gg]")
       set(CMake_HAVE_CXX_${FEATURE} OFF CACHE INTERNAL "TRY_COMPILE" FORCE)
@@ -65,3 +63,8 @@
   set(CMake_HAVE_CXX_UNIQUE_PTR 1)
 endif()
 cm_check_cxx_feature(unique_ptr)
+if (NOT CMAKE_CXX_STANDARD LESS "17")
+  cm_check_cxx_feature(filesystem)
+else()
+  set(CMake_HAVE_CXX_FILESYSTEM FALSE)
+endif()
diff --git a/Source/Checks/cm_cxx_filesystem.cxx b/Source/Checks/cm_cxx_filesystem.cxx
new file mode 100644
index 0000000..e508d1c
--- /dev/null
+++ b/Source/Checks/cm_cxx_filesystem.cxx
@@ -0,0 +1,10 @@
+
+#include <filesystem>
+
+int main()
+{
+  std::filesystem::path p1("/a/b/c");
+  std::filesystem::path p2("/a/b/c");
+
+  return p1 == p2 ? 0 : 1;
+}
diff --git a/Source/CursesDialog/ccmake.cxx b/Source/CursesDialog/ccmake.cxx
index 01fce85..85e256b 100644
--- a/Source/CursesDialog/ccmake.cxx
+++ b/Source/CursesDialog/ccmake.cxx
@@ -2,11 +2,15 @@
    file Copyright.txt or https://cmake.org/licensing for details.  */
 
 #include <csignal>
+#include <cstdio>
+#include <cstdlib>
 #include <cstring>
 #include <iostream>
 #include <string>
 #include <vector>
 
+#include <unistd.h>
+
 #include "cmsys/Encoding.hxx"
 
 #include "cmCursesColor.h"
@@ -16,6 +20,7 @@
 #include "cmDocumentation.h"
 #include "cmDocumentationEntry.h" // IWYU pragma: keep
 #include "cmState.h"
+#include "cmStringAlgorithms.h"
 #include "cmSystemTools.h"
 #include "cmake.h"
 
@@ -53,7 +58,12 @@
 {
   if (cmCursesForm::CurrentForm) {
     endwin();
-    initscr();            /* Initialization */
+    if (initscr() == nullptr) {
+      static const char errmsg[] = "Error: ncurses initialization failed\n";
+      auto r = write(STDERR_FILENO, errmsg, sizeof(errmsg) - 1);
+      static_cast<void>(r);
+      exit(1);
+    }
     noecho();             /* Echo off */
     cbreak();             /* nl- or cr not needed */
     keypad(stdscr, true); /* Use key symbols as KEY_DOWN */
@@ -111,8 +121,8 @@
 
   std::string cacheDir = cmSystemTools::GetCurrentWorkingDirectory();
   for (i = 1; i < args.size(); ++i) {
-    std::string arg = args[i];
-    if (arg.find("-B", 0) == 0) {
+    std::string const& arg = args[i];
+    if (cmHasPrefix(arg, "-B")) {
       cacheDir = arg.substr(2);
     }
   }
@@ -123,7 +133,10 @@
     cmCursesForm::DebugStart();
   }
 
-  initscr();            /* Initialization */
+  if (initscr() == nullptr) {
+    fprintf(stderr, "Error: ncurses initialization failed\n");
+    exit(1);
+  }
   noecho();             /* Echo off */
   cbreak();             /* nl- or cr not needed */
   keypad(stdscr, true); /* Use key symbols as KEY_DOWN */
diff --git a/Source/CursesDialog/cmCursesCacheEntryComposite.cxx b/Source/CursesDialog/cmCursesCacheEntryComposite.cxx
index 4d3131b..35f09fd 100644
--- a/Source/CursesDialog/cmCursesCacheEntryComposite.cxx
+++ b/Source/CursesDialog/cmCursesCacheEntryComposite.cxx
@@ -15,6 +15,7 @@
 #include "cmCursesPathWidget.h"
 #include "cmCursesStringWidget.h"
 #include "cmCursesWidget.h"
+#include "cmProperty.h"
 #include "cmState.h"
 #include "cmStateTypes.h"
 #include "cmStringAlgorithms.h"
@@ -48,42 +49,42 @@
     this->IsNewLabel = cm::make_unique<cmCursesLabelWidget>(1, 1, 1, 1, " ");
   }
 
-  const char* value = state->GetCacheEntryValue(key);
+  cmProp value = state->GetCacheEntryValue(key);
   assert(value);
   switch (state->GetCacheEntryType(key)) {
     case cmStateEnums::BOOL: {
       auto bw = cm::make_unique<cmCursesBoolWidget>(this->EntryWidth, 1, 1, 1);
-      bw->SetValueAsBool(cmIsOn(value));
+      bw->SetValueAsBool(cmIsOn(*value));
       this->Entry = std::move(bw);
       break;
     }
     case cmStateEnums::PATH: {
       auto pw = cm::make_unique<cmCursesPathWidget>(this->EntryWidth, 1, 1, 1);
-      pw->SetString(value);
+      pw->SetString(*value);
       this->Entry = std::move(pw);
       break;
     }
     case cmStateEnums::FILEPATH: {
       auto fpw =
         cm::make_unique<cmCursesFilePathWidget>(this->EntryWidth, 1, 1, 1);
-      fpw->SetString(value);
+      fpw->SetString(*value);
       this->Entry = std::move(fpw);
       break;
     }
     case cmStateEnums::STRING: {
-      const char* stringsProp = state->GetCacheEntryProperty(key, "STRINGS");
+      cmProp stringsProp = state->GetCacheEntryProperty(key, "STRINGS");
       if (stringsProp) {
         auto ow =
           cm::make_unique<cmCursesOptionsWidget>(this->EntryWidth, 1, 1, 1);
-        for (std::string const& opt : cmExpandedList(stringsProp)) {
+        for (std::string const& opt : cmExpandedList(*stringsProp)) {
           ow->AddOption(opt);
         }
-        ow->SetOption(value);
+        ow->SetOption(*value);
         this->Entry = std::move(ow);
       } else {
         auto sw =
           cm::make_unique<cmCursesStringWidget>(this->EntryWidth, 1, 1, 1);
-        sw->SetString(value);
+        sw->SetString(*value);
         this->Entry = std::move(sw);
       }
       break;
diff --git a/Source/CursesDialog/cmCursesColor.cxx b/Source/CursesDialog/cmCursesColor.cxx
index 641d48c..c0b468b 100644
--- a/Source/CursesDialog/cmCursesColor.cxx
+++ b/Source/CursesDialog/cmCursesColor.cxx
@@ -2,6 +2,12 @@
    file Copyright.txt or https://cmake.org/licensing for details.  */
 #include "cmCursesColor.h"
 
+#include <cctype>
+#include <cstdlib>
+#include <cstring>
+#include <unordered_map>
+#include <utility>
+
 #include "cmCursesStandardIncludes.h"
 
 bool cmCursesColor::HasColors()
@@ -19,11 +25,54 @@
   if (HasColors()) {
     start_color();
     use_default_colors();
-    init_pair(cmCursesColor::BoolOff, COLOR_RED, -1);
-    init_pair(cmCursesColor::BoolOn, COLOR_GREEN, -1);
-    init_pair(cmCursesColor::String, COLOR_BLUE, -1);
-    init_pair(cmCursesColor::Path, COLOR_YELLOW, -1);
-    init_pair(cmCursesColor::Options, COLOR_MAGENTA, -1);
+    init_pair(BoolOff, GetColor('N', COLOR_RED), -1);
+    init_pair(BoolOn, GetColor('Y', COLOR_GREEN), -1);
+    init_pair(String, GetColor('S', COLOR_CYAN), -1);
+    init_pair(Path, GetColor('P', COLOR_YELLOW), -1);
+    init_pair(Choice, GetColor('C', COLOR_MAGENTA), -1);
   }
 #endif
 }
+
+short cmCursesColor::GetColor(char id, short fallback)
+{
+  static bool initialized = false;
+  static std::unordered_map<char, short> env;
+
+  if (!initialized) {
+    if (auto* v = getenv("CCMAKE_COLORS")) {
+      while (v[0] && v[1] && v[1] == '=') {
+        auto const n = std::toupper(*v);
+
+        char buffer[12];
+        memset(buffer, 0, sizeof(buffer));
+
+        if (auto* const e = strchr(v, ':')) {
+          if (static_cast<size_t>(e - v) > sizeof(buffer)) {
+            break;
+          }
+
+          strncpy(buffer, v + 2, static_cast<size_t>(e - v - 2));
+          v = e + 1;
+        } else {
+          auto const l = strlen(v);
+          if (l > sizeof(buffer)) {
+            break;
+          }
+
+          strncpy(buffer, v + 2, l - 2);
+          v += l;
+        }
+
+        auto const c = atoi(buffer);
+        if (c && c < COLORS) {
+          env.emplace(n, static_cast<short>(c));
+        }
+      }
+    }
+    initialized = true;
+  }
+
+  auto const iter = env.find(id);
+  return (iter == env.end() ? fallback : iter->second);
+}
diff --git a/Source/CursesDialog/cmCursesColor.h b/Source/CursesDialog/cmCursesColor.h
index 78ca52c..f83265f 100644
--- a/Source/CursesDialog/cmCursesColor.h
+++ b/Source/CursesDialog/cmCursesColor.h
@@ -13,12 +13,15 @@
     BoolOn,
     String,
     Path,
-    Options
+    Choice
   };
 
   static bool HasColors();
 
   static void InitColors();
+
+protected:
+  static short GetColor(char id, short fallback);
 };
 
 #endif // cmCursesColor_h
diff --git a/Source/CursesDialog/cmCursesLongMessageForm.cxx b/Source/CursesDialog/cmCursesLongMessageForm.cxx
index afd2b6b..591c546 100644
--- a/Source/CursesDialog/cmCursesLongMessageForm.cxx
+++ b/Source/CursesDialog/cmCursesLongMessageForm.cxx
@@ -41,7 +41,8 @@
   this->Title = title;
 
   if (!output.empty() && this->Messages.size() < MAX_CONTENT_SIZE) {
-    this->Messages.append("\n" + output);
+    this->Messages.push_back('\n');
+    this->Messages.append(output);
     form_driver(this->Form, REQ_NEW_LINE);
     this->DrawMessage(output.c_str());
   }
@@ -67,7 +68,7 @@
     bar[i] = ' ';
   }
   int width;
-  if (x < cmCursesMainForm::MAX_WIDTH) {
+  if (x >= 0 && x < cmCursesMainForm::MAX_WIDTH) {
     width = x;
   } else {
     width = cmCursesMainForm::MAX_WIDTH - 1;
diff --git a/Source/CursesDialog/cmCursesMainForm.cxx b/Source/CursesDialog/cmCursesMainForm.cxx
index 65376d1..6fc556c 100644
--- a/Source/CursesDialog/cmCursesMainForm.cxx
+++ b/Source/CursesDialog/cmCursesMainForm.cxx
@@ -17,6 +17,7 @@
 #include "cmCursesStandardIncludes.h"
 #include "cmCursesStringWidget.h"
 #include "cmCursesWidget.h"
+#include "cmProperty.h"
 #include "cmState.h"
 #include "cmStateTypes.h"
 #include "cmStringAlgorithms.h"
@@ -161,7 +162,7 @@
     // If normal mode, count only non-advanced entries
     this->NumberOfVisibleEntries = 0;
     for (cmCursesCacheEntryComposite& entry : this->Entries) {
-      const char* existingValue =
+      cmProp existingValue =
         this->CMakeInstance->GetState()->GetCacheEntryValue(entry.GetValue());
       bool advanced =
         this->CMakeInstance->GetState()->GetCacheEntryPropertyAsBool(
@@ -182,7 +183,7 @@
 
   // Assign fields
   for (cmCursesCacheEntryComposite& entry : this->Entries) {
-    const char* existingValue =
+    cmProp existingValue =
       this->CMakeInstance->GetState()->GetCacheEntryValue(entry.GetValue());
     bool advanced =
       this->CMakeInstance->GetState()->GetCacheEntryPropertyAsBool(
@@ -241,7 +242,7 @@
     // If normal, display only non-advanced entries
     this->NumberOfVisibleEntries = 0;
     for (cmCursesCacheEntryComposite& entry : this->Entries) {
-      const char* existingValue =
+      cmProp existingValue =
         this->CMakeInstance->GetState()->GetCacheEntryValue(entry.GetValue());
       bool advanced =
         this->CMakeInstance->GetState()->GetCacheEntryPropertyAsBool(
@@ -259,7 +260,7 @@
     bool isNewPage;
     int i = 0;
     for (cmCursesCacheEntryComposite& entry : this->Entries) {
-      const char* existingValue =
+      cmProp existingValue =
         this->CMakeInstance->GetState()->GetCacheEntryValue(entry.GetValue());
       bool advanced =
         this->CMakeInstance->GetState()->GetCacheEntryPropertyAsBool(
@@ -405,11 +406,12 @@
     // Get the help string of the current entry
     // and add it to the help string
     auto cmakeState = this->CMakeInstance->GetState();
-    const char* existingValue = cmakeState->GetCacheEntryValue(labelValue);
+    cmProp existingValue = cmakeState->GetCacheEntryValue(labelValue);
     if (existingValue) {
-      auto help = cmakeState->GetCacheEntryProperty(labelValue, "HELPSTRING");
+      cmProp help =
+        cmakeState->GetCacheEntryProperty(labelValue, "HELPSTRING");
       if (help) {
-        bar += help;
+        bar += *help;
       }
     }
   }
@@ -616,10 +618,10 @@
 {
   for (cmCursesCacheEntryComposite& entry : this->Entries) {
     const std::string& cacheKey = entry.Key;
-    const char* existingValue =
+    cmProp existingValue =
       this->CMakeInstance->GetState()->GetCacheEntryValue(cacheKey);
     if (existingValue) {
-      std::string oldValue = existingValue;
+      std::string oldValue = *existingValue;
       std::string newValue = entry.Entry->GetValue();
       std::string fixedOldValue;
       std::string fixedNewValue;
@@ -802,9 +804,9 @@
         cmCursesWidget* lbl = reinterpret_cast<cmCursesWidget*>(
           field_userptr(this->Fields[findex - 2]));
         const char* curField = lbl->GetValue();
-        const char* helpString = nullptr;
+        cmProp helpString = nullptr;
 
-        const char* existingValue =
+        cmProp existingValue =
           this->CMakeInstance->GetState()->GetCacheEntryValue(curField);
         if (existingValue) {
           helpString = this->CMakeInstance->GetState()->GetCacheEntryProperty(
@@ -813,7 +815,7 @@
         if (helpString) {
           this->HelpMessage[1] =
             cmStrCat("Current option is: ", curField, '\n',
-                     "Help string for this option is: ", helpString, '\n');
+                     "Help string for this option is: ", *helpString, '\n');
         } else {
           this->HelpMessage[1] = "";
         }
@@ -852,11 +854,7 @@
       }
       // switch advanced on/off
       else if (key == 't') {
-        if (this->AdvancedMode) {
-          this->AdvancedMode = false;
-        } else {
-          this->AdvancedMode = true;
-        }
+        this->AdvancedMode = !this->AdvancedMode;
         getmaxyx(stdscr, y, x);
         this->RePost();
         this->Render(1, 1, x, y);
diff --git a/Source/CursesDialog/cmCursesOptionsWidget.cxx b/Source/CursesDialog/cmCursesOptionsWidget.cxx
index a15241f..8df32e2 100644
--- a/Source/CursesDialog/cmCursesOptionsWidget.cxx
+++ b/Source/CursesDialog/cmCursesOptionsWidget.cxx
@@ -17,8 +17,8 @@
   // the widget into a string widget at some point.  BOOL is safe for
   // now.
   if (cmCursesColor::HasColors()) {
-    set_field_fore(this->Field, COLOR_PAIR(cmCursesColor::Options));
-    set_field_back(this->Field, COLOR_PAIR(cmCursesColor::Options));
+    set_field_fore(this->Field, COLOR_PAIR(cmCursesColor::Choice));
+    set_field_back(this->Field, COLOR_PAIR(cmCursesColor::Choice));
   } else {
     set_field_fore(this->Field, A_NORMAL);
     set_field_back(this->Field, A_STANDOUT);
diff --git a/Source/CursesDialog/cmCursesStringWidget.cxx b/Source/CursesDialog/cmCursesStringWidget.cxx
index c629478..4830d63 100644
--- a/Source/CursesDialog/cmCursesStringWidget.cxx
+++ b/Source/CursesDialog/cmCursesStringWidget.cxx
@@ -105,12 +105,10 @@
     if (!this->InEdit && (key != 10 && key != KEY_ENTER && key != 'i')) {
       return false;
     }
-    // enter edit with return and i (vim binding)
-    if (!this->InEdit && (key == 10 || key == KEY_ENTER || key == 'i')) {
-      this->OnReturn(fm, w);
-    }
-    // leave edit with return (but not i -- not a toggle)
-    else if (this->InEdit && (key == 10 || key == KEY_ENTER)) {
+    // toggle edit with return
+    if ((key == 10 || key == KEY_ENTER)
+        // enter edit with i (and not-edit mode)
+        || (!this->InEdit && key == 'i')) {
       this->OnReturn(fm, w);
     } else if (key == KEY_DOWN || key == ctrl('n') || key == KEY_UP ||
                key == ctrl('p') || key == KEY_NPAGE || key == ctrl('d') ||
diff --git a/Source/CursesDialog/form/frm_driver.c b/Source/CursesDialog/form/frm_driver.c
index e4e72aa..112ab08 100644
--- a/Source/CursesDialog/form/frm_driver.c
+++ b/Source/CursesDialog/form/frm_driver.c
@@ -2983,7 +2983,7 @@
 |   Function      :  static FIELD *Upper_Neighbour_Field(FIELD * field)
 |   
 |   Description   :  Because of the row-major nature of sorting the fields,
-|                    its more difficult to define whats the upper neighbour
+|                    its more difficult to define what's the upper neighbour
 |                    field really means. We define that it must be on a
 |                    'previous' line (cyclic order!) and is the rightmost
 |                    field laying on the left side of the given field. If
@@ -3030,7 +3030,7 @@
 |   Function      :  static FIELD *Down_Neighbour_Field(FIELD * field)
 |   
 |   Description   :  Because of the row-major nature of sorting the fields,
-|                    its more difficult to define whats the down neighbour
+|                    its more difficult to define what's the down neighbour
 |                    field really means. We define that it must be on a
 |                    'next' line (cyclic order!) and is the leftmost
 |                    field laying on the right side of the given field. If
diff --git a/Source/LexerParser/cmListFileLexer.c b/Source/LexerParser/cmListFileLexer.c
index 15dcda0..ec7424c 100644
--- a/Source/LexerParser/cmListFileLexer.c
+++ b/Source/LexerParser/cmListFileLexer.c
@@ -2787,7 +2787,7 @@
 /*--------------------------------------------------------------------------*/
 cmListFileLexer_Token* cmListFileLexer_Scan(cmListFileLexer* lexer)
 {
-  if (!lexer->file) {
+  if (!lexer->file && !lexer->string_buffer) {
     return 0;
   }
   if (cmListFileLexer_yylex(lexer->scanner, lexer)) {
@@ -2801,21 +2801,13 @@
 /*--------------------------------------------------------------------------*/
 long cmListFileLexer_GetCurrentLine(cmListFileLexer* lexer)
 {
-  if (lexer->file) {
-    return lexer->line;
-  } else {
-    return 0;
-  }
+  return lexer->line;
 }
 
 /*--------------------------------------------------------------------------*/
 long cmListFileLexer_GetCurrentColumn(cmListFileLexer* lexer)
 {
-  if (lexer->file) {
-    return lexer->column;
-  } else {
-    return 0;
-  }
+  return lexer->column;
 }
 
 /*--------------------------------------------------------------------------*/
diff --git a/Source/LexerParser/cmListFileLexer.in.l b/Source/LexerParser/cmListFileLexer.in.l
index fdf14d2..94cf8a5 100644
--- a/Source/LexerParser/cmListFileLexer.in.l
+++ b/Source/LexerParser/cmListFileLexer.in.l
@@ -500,7 +500,7 @@
 /*--------------------------------------------------------------------------*/
 cmListFileLexer_Token* cmListFileLexer_Scan(cmListFileLexer* lexer)
 {
-  if (!lexer->file) {
+  if (!lexer->file && !lexer->string_buffer) {
     return 0;
   }
   if (cmListFileLexer_yylex(lexer->scanner, lexer)) {
@@ -514,21 +514,13 @@
 /*--------------------------------------------------------------------------*/
 long cmListFileLexer_GetCurrentLine(cmListFileLexer* lexer)
 {
-  if (lexer->file) {
-    return lexer->line;
-  } else {
-    return 0;
-  }
+  return lexer->line;
 }
 
 /*--------------------------------------------------------------------------*/
 long cmListFileLexer_GetCurrentColumn(cmListFileLexer* lexer)
 {
-  if (lexer->file) {
-    return lexer->column;
-  } else {
-    return 0;
-  }
+  return lexer->column;
 }
 
 /*--------------------------------------------------------------------------*/
diff --git a/Source/QtDialog/CMakeLists.txt b/Source/QtDialog/CMakeLists.txt
index 98dd0e2..e6d6b17 100644
--- a/Source/QtDialog/CMakeLists.txt
+++ b/Source/QtDialog/CMakeLists.txt
@@ -3,111 +3,79 @@
 
 project(QtDialog)
 CMake_OPTIONAL_COMPONENT(cmake-gui)
-find_package(Qt5Widgets QUIET)
-if (Qt5Widgets_FOUND)
-  include_directories(${Qt5Widgets_INCLUDE_DIRS})
-  add_definitions(${Qt5Widgets_DEFINITONS})
-  macro(qt4_wrap_ui)
-    qt5_wrap_ui(${ARGN})
-  endmacro()
-  macro(qt4_wrap_cpp)
-    qt5_wrap_cpp(${ARGN})
-  endmacro()
-  macro(qt4_add_resources)
-    qt5_add_resources(${ARGN})
-  endmacro()
+find_package(Qt5Widgets REQUIRED)
 
-  set(CMake_QT_LIBRARIES ${Qt5Widgets_LIBRARIES})
-  set(QT_QTMAIN_LIBRARY ${Qt5Core_QTMAIN_LIBRARIES})
+set(CMake_QT_EXTRA_LIBRARIES)
 
-  # Try to find the package WinExtras for the task bar progress
-  if(WIN32)
-    find_package(Qt5WinExtras QUIET)
-    if (Qt5WinExtras_FOUND)
-      include_directories(${Qt5WinExtras_INCLUDE_DIRS})
-      add_definitions(-DQT_WINEXTRAS)
-      list(APPEND CMake_QT_LIBRARIES ${Qt5WinExtras_LIBRARIES})
-    endif()
+# Try to find the package WinExtras for the task bar progress
+if(WIN32)
+  find_package(Qt5WinExtras QUIET)
+  if (Qt5WinExtras_FOUND)
+    add_definitions(-DQT_WINEXTRAS)
+    list(APPEND CMake_QT_EXTRA_LIBRARIES Qt5::WinExtras)
   endif()
+endif()
 
-  # Remove this when the minimum version of Qt is 4.6.
-  add_definitions(-DQT_DISABLE_DEPRECATED_BEFORE=0)
+set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${Qt5Widgets_EXECUTABLE_COMPILE_FLAGS}")
 
-  set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${Qt5Widgets_EXECUTABLE_COMPILE_FLAGS}")
+if(CMake_QT_STATIC_QXcbIntegrationPlugin_LIBRARIES)
+  list(APPEND CMake_QT_EXTRA_LIBRARIES ${CMake_QT_STATIC_QXcbIntegrationPlugin_LIBRARIES})
+  set_property(SOURCE CMakeSetup.cxx
+    PROPERTY COMPILE_DEFINITIONS USE_QXcbIntegrationPlugin)
+endif()
 
-  if(CMake_QT_STATIC_QXcbIntegrationPlugin_LIBRARIES)
-    list(APPEND CMake_QT_LIBRARIES ${CMake_QT_STATIC_QXcbIntegrationPlugin_LIBRARIES})
-    set_property(SOURCE CMakeSetup.cxx
-      PROPERTY COMPILE_DEFINITIONS USE_QXcbIntegrationPlugin)
-  endif()
+if(CMake_QT_STATIC_QWindowsIntegrationPlugin_LIBRARIES)
+  list(APPEND CMake_QT_EXTRA_LIBRARIES ${CMake_QT_STATIC_QWindowsIntegrationPlugin_LIBRARIES})
+  set_property(SOURCE CMakeSetup.cxx
+    PROPERTY COMPILE_DEFINITIONS USE_QWindowsIntegrationPlugin)
+endif()
 
-  if(CMake_QT_STATIC_QWindowsIntegrationPlugin_LIBRARIES)
-    list(APPEND CMake_QT_LIBRARIES ${CMake_QT_STATIC_QWindowsIntegrationPlugin_LIBRARIES})
-    set_property(SOURCE CMakeSetup.cxx
-      PROPERTY COMPILE_DEFINITIONS USE_QWindowsIntegrationPlugin)
-  endif()
-
-  # We need to install platform plugin and add qt.conf for Qt5 on Mac and Windows.
-  # FIXME: This should be part of Qt5 CMake scripts, but unfortunately
-  # Qt5 support is missing there.
-  if(CMake_INSTALL_DEPENDENCIES AND (APPLE OR WIN32))
-    macro(install_qt5_plugin _qt_plugin_name _qt_plugins_var)
-      get_target_property(_qt_plugin_path "${_qt_plugin_name}" LOCATION)
-      if(EXISTS "${_qt_plugin_path}")
-        get_filename_component(_qt_plugin_file "${_qt_plugin_path}" NAME)
-        get_filename_component(_qt_plugin_type "${_qt_plugin_path}" PATH)
-        get_filename_component(_qt_plugin_type "${_qt_plugin_type}" NAME)
-        if(APPLE)
-          set(_qt_plugin_dir "PlugIns")
-        elseif(WIN32)
-          set(_qt_plugin_dir "plugins")
-        endif()
-        set(_qt_plugin_dest "${_qt_plugin_dir}/${_qt_plugin_type}")
-        install(FILES "${_qt_plugin_path}"
-          DESTINATION "${_qt_plugin_dest}"
-          ${COMPONENT})
-        set(${_qt_plugins_var}
-          "${${_qt_plugins_var}};\$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/${_qt_plugin_dest}/${_qt_plugin_file}")
-      else()
-        message(FATAL_ERROR "QT plugin ${_qt_plugin_name} not found")
+# We need to install platform plugin and add qt.conf for Qt5 on Mac and Windows.
+# FIXME: This should be part of Qt5 CMake scripts, but unfortunately
+# Qt5 support is missing there.
+if(CMake_INSTALL_DEPENDENCIES AND (APPLE OR WIN32))
+  macro(install_qt5_plugin _qt_plugin_name _qt_plugins_var)
+    get_target_property(_qt_plugin_path "${_qt_plugin_name}" LOCATION)
+    if(EXISTS "${_qt_plugin_path}")
+      get_filename_component(_qt_plugin_file "${_qt_plugin_path}" NAME)
+      get_filename_component(_qt_plugin_type "${_qt_plugin_path}" PATH)
+      get_filename_component(_qt_plugin_type "${_qt_plugin_type}" NAME)
+      if(APPLE)
+        set(_qt_plugin_dir "PlugIns")
+      elseif(WIN32)
+        set(_qt_plugin_dir "plugins")
       endif()
-    endmacro()
-    if(APPLE)
-      install_qt5_plugin("Qt5::QCocoaIntegrationPlugin" QT_PLUGINS)
-      file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/qt.conf"
-        "[Paths]\nPlugins = ${_qt_plugin_dir}\n")
-      install(FILES "${CMAKE_CURRENT_BINARY_DIR}/qt.conf"
-        DESTINATION "${CMAKE_INSTALL_PREFIX}/Resources"
+      set(_qt_plugin_dest "${_qt_plugin_dir}/${_qt_plugin_type}")
+      install(FILES "${_qt_plugin_path}"
+        DESTINATION "${_qt_plugin_dest}"
         ${COMPONENT})
-    elseif(WIN32 AND NOT CMake_QT_STATIC_QWindowsIntegrationPlugin_LIBRARIES)
-      install_qt5_plugin("Qt5::QWindowsIntegrationPlugin" QT_PLUGINS)
-      file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/qt.conf"
-        "[Paths]\nPlugins = ../${_qt_plugin_dir}\n")
-      install(FILES "${CMAKE_CURRENT_BINARY_DIR}/qt.conf"
-        DESTINATION bin
-        ${COMPONENT})
+      set(${_qt_plugins_var}
+        "${${_qt_plugins_var}};\$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/${_qt_plugin_dest}/${_qt_plugin_file}")
+    else()
+      message(FATAL_ERROR "QT plugin ${_qt_plugin_name} not found")
     endif()
+  endmacro()
+  if(APPLE)
+    install_qt5_plugin("Qt5::QCocoaIntegrationPlugin" QT_PLUGINS)
+    file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/qt.conf"
+      "[Paths]\nPlugins = ${_qt_plugin_dir}\n")
+    install(FILES "${CMAKE_CURRENT_BINARY_DIR}/qt.conf"
+      DESTINATION "${CMAKE_INSTALL_PREFIX}/Resources"
+      ${COMPONENT})
+  elseif(WIN32 AND NOT CMake_QT_STATIC_QWindowsIntegrationPlugin_LIBRARIES)
+    install_qt5_plugin("Qt5::QWindowsIntegrationPlugin" QT_PLUGINS)
+    file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/qt.conf"
+      "[Paths]\nPlugins = ../${_qt_plugin_dir}\n")
+    install(FILES "${CMAKE_CURRENT_BINARY_DIR}/qt.conf"
+      DESTINATION bin
+      ${COMPONENT})
   endif()
+endif()
 
-  if(TARGET Qt5::Core)
-    get_property(_Qt5_Core_LOCATION TARGET Qt5::Core PROPERTY LOCATION)
-    get_filename_component(Qt_BIN_DIR "${_Qt5_Core_LOCATION}" PATH)
-    if(APPLE)
-      get_filename_component(Qt_BIN_DIR "${Qt_BIN_DIR}" PATH)
-    endif()
-  endif()
-else()
-  set(QT_MIN_VERSION "4.4.0")
-  find_package(Qt4 REQUIRED)
-  if(NOT QT4_FOUND)
-    message(SEND_ERROR "Failed to find Qt 4.4 or greater.")
-    return()
-  endif()
-
-  include(${QT_USE_FILE})
-
-  set(CMake_QT_LIBRARIES ${QT_LIBRARIES})
-
+get_property(_Qt5_Core_LOCATION TARGET Qt5::Core PROPERTY LOCATION)
+get_filename_component(Qt_BIN_DIR "${_Qt5_Core_LOCATION}" PATH)
+if(APPLE)
+  get_filename_component(Qt_BIN_DIR "${Qt_BIN_DIR}" PATH)
 endif()
 
 set(SRCS
@@ -116,6 +84,7 @@
   CMakeSetup.cxx
   CMakeSetupDialog.cxx
   CMakeSetupDialog.h
+  Compilers.h
   FirstConfigure.cxx
   FirstConfigure.h
   QCMake.cxx
@@ -129,7 +98,7 @@
   WarningMessagesDialog.cxx
   WarningMessagesDialog.h
   )
-QT4_WRAP_UI(UI_SRCS
+qt5_wrap_ui(UI_SRCS
   CMakeSetupDialog.ui
   Compilers.ui
   CrossCompiler.ui
@@ -137,7 +106,7 @@
   RegexExplorer.ui
   WarningMessagesDialog.ui
   )
-QT4_WRAP_CPP(MOC_SRCS
+qt5_wrap_cpp(MOC_SRCS
   AddCacheEntry.h
   Compilers.h
   CMakeSetupDialog.h
@@ -148,14 +117,24 @@
   RegexExplorer.h
   WarningMessagesDialog.h
   )
-QT4_ADD_RESOURCES(RC_SRCS CMakeSetup.qrc)
+qt5_add_resources(RC_SRCS CMakeSetup.qrc)
 
-set(SRCS ${SRCS} ${UI_SRCS} ${MOC_SRCS} ${RC_SRCS})
+if (FALSE) # CMake's bootstrap binary does not support automoc
+  set(CMAKE_AUTOMOC 1)
+  set(CMAKE_AUTORCC 1)
+  set(CMAKE_AUTOUIC 1)
+else ()
+  list(APPEND SRCS
+    ${UI_SRCS}
+    ${MOC_SRCS}
+    ${RC_SRCS})
+endif ()
+
 if(WIN32)
-  set(SRCS ${SRCS} CMakeSetup.rc)
+  list(APPEND SRCS CMakeSetup.rc)
 endif()
 if(APPLE)
-  set(SRCS ${SRCS} CMakeSetup.icns)
+  list(APPEND SRCS CMakeSetup.icns)
   set(MACOSX_BUNDLE_ICON_FILE CMakeSetup.icns)
   set_source_files_properties(CMakeSetup.icns PROPERTIES
     MACOSX_PACKAGE_LOCATION Resources)
@@ -172,7 +151,7 @@
 set(CMAKE_INCLUDE_CURRENT_DIR ON)
 
 add_executable(cmake-gui WIN32 MACOSX_BUNDLE ${SRCS} ${MANIFEST_FILE})
-target_link_libraries(cmake-gui CMakeLib ${QT_QTMAIN_LIBRARY} ${CMake_QT_LIBRARIES})
+target_link_libraries(cmake-gui CMakeLib Qt5::Core Qt5::Widgets ${CMake_QT_EXTRA_LIBRARIES})
 
 if(WIN32)
   target_sources(cmake-gui PRIVATE $<TARGET_OBJECTS:CMakeVersion>)
diff --git a/Source/QtDialog/CMakeSetup.cxx b/Source/QtDialog/CMakeSetup.cxx
index ee81a7d..7ef5a72 100644
--- a/Source/QtDialog/CMakeSetup.cxx
+++ b/Source/QtDialog/CMakeSetup.cxx
@@ -115,14 +115,6 @@
   QTextCodec* utf8_codec = QTextCodec::codecForName("UTF-8");
   QTextCodec::setCodecForLocale(utf8_codec);
 
-#if QT_VERSION < 0x050000
-  // clean out standard Qt paths for plugins, which we don't use anyway
-  // when creating Mac bundles, it potentially causes problems
-  foreach (QString p, QApplication::libraryPaths()) {
-    QApplication::removeLibraryPath(p);
-  }
-#endif
-
   // tell the cmake library where cmake is
   QDir cmExecDir(QApplication::applicationDirPath());
 #if defined(Q_OS_MAC)
@@ -201,8 +193,7 @@
         cmSystemTools::CollapseFullPath(args[1].toLocal8Bit().data());
 
       // check if argument is a directory containing CMakeCache.txt
-      std::string buildFilePath =
-        cmSystemTools::CollapseFullPath("CMakeCache.txt", filePath.c_str());
+      std::string buildFilePath = cmStrCat(filePath, "/CMakeCache.txt");
 
       // check if argument is a CMakeCache.txt file
       if (cmSystemTools::GetFilenameName(filePath) == "CMakeCache.txt" &&
@@ -211,8 +202,7 @@
       }
 
       // check if argument is a directory containing CMakeLists.txt
-      std::string srcFilePath =
-        cmSystemTools::CollapseFullPath("CMakeLists.txt", filePath.c_str());
+      std::string srcFilePath = cmStrCat(filePath, "/CMakeLists.txt");
 
       if (cmSystemTools::FileExists(buildFilePath.c_str())) {
         dialog.setBinaryDirectory(QString::fromLocal8Bit(
diff --git a/Source/QtDialog/CMakeSetupDialog.cxx b/Source/QtDialog/CMakeSetupDialog.cxx
index 436a904..fcc8408 100644
--- a/Source/QtDialog/CMakeSetupDialog.cxx
+++ b/Source/QtDialog/CMakeSetupDialog.cxx
@@ -2,6 +2,8 @@
    file Copyright.txt or https://cmake.org/licensing for details.  */
 #include "CMakeSetupDialog.h"
 
+#include <cm/memory>
+
 #include <QCloseEvent>
 #include <QCoreApplication>
 #include <QDesktopServices>
@@ -39,23 +41,21 @@
 
 QCMakeThread::QCMakeThread(QObject* p)
   : QThread(p)
-  , CMakeInstance(nullptr)
 {
 }
 
 QCMake* QCMakeThread::cmakeInstance() const
 {
-  return this->CMakeInstance;
+  return this->CMakeInstance.get();
 }
 
 void QCMakeThread::run()
 {
-  this->CMakeInstance = new QCMake;
+  this->CMakeInstance = cm::make_unique<QCMake>();
   // emit that this cmake thread is ready for use
   emit this->cmakeInitialized();
   this->exec();
-  delete this->CMakeInstance;
-  this->CMakeInstance = nullptr;
+  this->CMakeInstance.reset();
 }
 
 CMakeSetupDialog::CMakeSetupDialog()
@@ -152,9 +152,6 @@
   this->WarnUninitializedAction =
     OptionsMenu->addAction(tr("&Warn Uninitialized (--warn-uninitialized)"));
   this->WarnUninitializedAction->setCheckable(true);
-  this->WarnUnusedAction =
-    OptionsMenu->addAction(tr("&Warn Unused (--warn-unused-vars)"));
-  this->WarnUnusedAction->setCheckable(true);
 
   QAction* debugAction = OptionsMenu->addAction(tr("&Debug Output"));
   debugAction->setCheckable(true);
@@ -290,9 +287,6 @@
   QObject::connect(this->WarnUninitializedAction, SIGNAL(triggered(bool)),
                    this->CMakeThread->cmakeInstance(),
                    SLOT(setWarnUninitializedMode(bool)));
-  QObject::connect(this->WarnUnusedAction, SIGNAL(triggered(bool)),
-                   this->CMakeThread->cmakeInstance(),
-                   SLOT(setWarnUnusedMode(bool)));
 
   if (!this->SourceDirectory->text().isEmpty() ||
       !this->BinaryDirectory->lineEdit()->text().isEmpty()) {
@@ -595,7 +589,11 @@
 
   QDialog dialog;
   QFontMetrics met(this->font());
+#if QT_VERSION >= QT_VERSION_CHECK(5, 11, 0)
+  int msgWidth = met.horizontalAdvance(msg);
+#else
   int msgWidth = met.width(msg);
+#endif
   dialog.setMinimumSize(msgWidth / 15, 20);
   dialog.setWindowTitle(tr("Help"));
   QVBoxLayout* l = new QVBoxLayout(&dialog);
@@ -804,12 +802,19 @@
       QString systemVersion = dialog.getSystemVersion();
       m->insertProperty(QCMakeProperty::STRING, "CMAKE_SYSTEM_VERSION",
                         tr("CMake System Version"), systemVersion, false);
+      QString systemProcessor = dialog.getSystemProcessor();
+      m->insertProperty(QCMakeProperty::STRING, "CMAKE_SYSTEM_PROCESSOR",
+                        tr("CMake System Processor"), systemProcessor, false);
       QString cxxCompiler = dialog.getCXXCompiler();
-      m->insertProperty(QCMakeProperty::FILEPATH, "CMAKE_CXX_COMPILER",
-                        tr("CXX compiler."), cxxCompiler, false);
+      if (!cxxCompiler.isEmpty()) {
+        m->insertProperty(QCMakeProperty::FILEPATH, "CMAKE_CXX_COMPILER",
+                          tr("CXX compiler."), cxxCompiler, false);
+      }
       QString cCompiler = dialog.getCCompiler();
-      m->insertProperty(QCMakeProperty::FILEPATH, "CMAKE_C_COMPILER",
-                        tr("C compiler."), cCompiler, false);
+      if (!cCompiler.isEmpty()) {
+        m->insertProperty(QCMakeProperty::FILEPATH, "CMAKE_C_COMPILER",
+                          tr("C compiler."), cCompiler, false);
+      }
     } else if (dialog.crossCompilerToolChainFile()) {
       QString toolchainFile = dialog.getCrossCompilerToolChainFile();
       m->insertProperty(QCMakeProperty::FILEPATH, "CMAKE_TOOLCHAIN_FILE",
@@ -1049,14 +1054,7 @@
     this->GenerateAction->setEnabled(false);
     this->OpenProjectButton->setEnabled(false);
     this->GenerateButton->setText(tr("&Stop"));
-  } else if (s == ReadyConfigure) {
-    this->setEnabledState(true);
-    this->GenerateButton->setEnabled(true);
-    this->GenerateAction->setEnabled(true);
-    this->ConfigureButton->setEnabled(true);
-    this->ConfigureButton->setText(tr("&Configure"));
-    this->GenerateButton->setText(tr("&Generate"));
-  } else if (s == ReadyGenerate) {
+  } else if (s == ReadyConfigure || s == ReadyGenerate) {
     this->setEnabledState(true);
     this->GenerateButton->setEnabled(true);
     this->GenerateAction->setEnabled(true);
@@ -1206,7 +1204,7 @@
 
 void CMakeSetupDialog::doOutputContextMenu(QPoint pt)
 {
-  QMenu* menu = this->Output->createStandardContextMenu();
+  std::unique_ptr<QMenu> menu(this->Output->createStandardContextMenu());
 
   menu->addSeparator();
   menu->addAction(tr("Find..."), this, SLOT(doOutputFindDialog()),
@@ -1220,7 +1218,6 @@
                   QKeySequence(Qt::Key_F8));
 
   menu->exec(this->Output->mapToGlobal(pt));
-  delete menu;
 }
 
 void CMakeSetupDialog::doOutputFindDialog()
diff --git a/Source/QtDialog/CMakeSetupDialog.h b/Source/QtDialog/CMakeSetupDialog.h
index f23aee6..914be12 100644
--- a/Source/QtDialog/CMakeSetupDialog.h
+++ b/Source/QtDialog/CMakeSetupDialog.h
@@ -3,6 +3,8 @@
 #ifndef CMakeSetupDialog_h
 #define CMakeSetupDialog_h
 
+#include <memory>
+
 #include "QCMake.h"
 #include <QEventLoop>
 #include <QMainWindow>
@@ -109,7 +111,6 @@
   QAction* ConfigureAction;
   QAction* GenerateAction;
   QAction* WarnUninitializedAction;
-  QAction* WarnUnusedAction;
   QAction* InstallForCommandLineAction;
   State CurrentState;
 
@@ -143,7 +144,7 @@
 
 protected:
   virtual void run();
-  QCMake* CMakeInstance;
+  std::unique_ptr<QCMake> CMakeInstance;
 };
 
 #endif // CMakeSetupDialog_h
diff --git a/Source/QtDialog/FirstConfigure.cxx b/Source/QtDialog/FirstConfigure.cxx
index ca28b19..3c24b9b 100644
--- a/Source/QtDialog/FirstConfigure.cxx
+++ b/Source/QtDialog/FirstConfigure.cxx
@@ -10,8 +10,12 @@
 
 #include "Compilers.h"
 
-StartCompilerSetup::StartCompilerSetup(QWidget* p)
+StartCompilerSetup::StartCompilerSetup(QString defaultGeneratorPlatform,
+                                       QString defaultGeneratorToolset,
+                                       QWidget* p)
   : QWizardPage(p)
+  , DefaultGeneratorPlatform(std::move(defaultGeneratorPlatform))
+  , DefaultGeneratorToolset(std::move(defaultGeneratorToolset))
 {
   QVBoxLayout* l = new QVBoxLayout(this);
   l->addWidget(new QLabel(tr("Specify the generator for this project")));
@@ -68,6 +72,10 @@
   Toolset = new QLineEdit(frame);
   l->addWidget(Toolset);
 
+  // Default to CMAKE_GENERATOR_TOOLSET env var if set
+  if (!DefaultGeneratorToolset.isEmpty()) {
+    this->Toolset->setText(DefaultGeneratorToolset);
+  }
   return frame;
 }
 
@@ -199,6 +207,14 @@
 
     this->PlatformOptions->addItems(platform_list);
     PlatformFrame->show();
+
+    // Default to generator platform from environment
+    if (!DefaultGeneratorPlatform.isEmpty()) {
+      int platform_index = platforms.indexOf(DefaultGeneratorPlatform);
+      if (platform_index != -1) {
+        this->PlatformOptions->setCurrentIndex(platform_index);
+      }
+    }
   } else {
     PlatformFrame->hide();
   }
@@ -421,8 +437,26 @@
 
 FirstConfigure::FirstConfigure()
 {
+  const char* env_generator = std::getenv("CMAKE_GENERATOR");
+  const char* env_generator_platform = nullptr;
+  const char* env_generator_toolset = nullptr;
+  if (env_generator && std::strlen(env_generator)) {
+    mDefaultGenerator = env_generator;
+    env_generator_platform = std::getenv("CMAKE_GENERATOR_PLATFORM");
+    env_generator_toolset = std::getenv("CMAKE_GENERATOR_TOOLSET");
+  }
+
+  if (!env_generator_platform) {
+    env_generator_platform = "";
+  }
+
+  if (!env_generator_toolset) {
+    env_generator_toolset = "";
+  }
+
   // this->setOption(QWizard::HaveFinishButtonOnEarlyPages, true);
-  this->mStartCompilerSetupPage = new StartCompilerSetup(this);
+  this->mStartCompilerSetupPage = new StartCompilerSetup(
+    env_generator_platform, env_generator_toolset, this);
   this->setPage(Start, this->mStartCompilerSetupPage);
   QObject::connect(this->mStartCompilerSetupPage, SIGNAL(selectionChanged()),
                    this, SLOT(restart()));
@@ -504,6 +538,17 @@
   this->mCrossCompilerSetupPage->setIncludeMode(
     settings.value("IncludeMode", 0).toInt());
   settings.endGroup();
+
+  // environment variables take precedence over application settings because...
+  // - they're harder to set
+  // - settings always exist after the program is run once, so the environment
+  //     variables would never be used otherwise
+  // - platform and toolset are populated only from environment variables, so
+  //     this prevents them from being taken from environment, while the
+  //     generator is taken from application settings
+  if (!mDefaultGenerator.isEmpty()) {
+    this->mStartCompilerSetupPage->setCurrentGenerator(mDefaultGenerator);
+  }
 }
 
 void FirstConfigure::saveToSettings()
diff --git a/Source/QtDialog/FirstConfigure.h b/Source/QtDialog/FirstConfigure.h
index d1db5bf..c26f489 100644
--- a/Source/QtDialog/FirstConfigure.h
+++ b/Source/QtDialog/FirstConfigure.h
@@ -29,7 +29,8 @@
 {
   Q_OBJECT
 public:
-  StartCompilerSetup(QWidget* p);
+  StartCompilerSetup(QString defaultGeneratorPlatform,
+                     QString defaultGeneratorToolset, QWidget* p);
   ~StartCompilerSetup();
   void setGenerators(std::vector<cmake::GeneratorInfo> const& gens);
   void setCurrentGenerator(const QString& gen);
@@ -64,6 +65,7 @@
   QStringList GeneratorsSupportingPlatform;
   QMultiMap<QString, QString> GeneratorSupportedPlatforms;
   QMap<QString, QString> GeneratorDefaultPlatform;
+  QString DefaultGeneratorPlatform, DefaultGeneratorToolset;
 
 private:
   QFrame* CreateToolsetWidgets();
@@ -197,6 +199,7 @@
   NativeCompilerSetup* mNativeCompilerSetupPage;
   CrossCompilerSetup* mCrossCompilerSetupPage;
   ToolchainCompilerSetup* mToolchainCompilerSetupPage;
+  QString mDefaultGenerator;
 };
 
 #endif // FirstConfigure_h
diff --git a/Source/QtDialog/QCMake.cxx b/Source/QtDialog/QCMake.cxx
index a9089e5..6090256 100644
--- a/Source/QtDialog/QCMake.cxx
+++ b/Source/QtDialog/QCMake.cxx
@@ -2,6 +2,8 @@
    file Copyright.txt or https://cmake.org/licensing for details.  */
 #include "QCMake.h"
 
+#include <cm/memory>
+
 #include <QCoreApplication>
 #include <QDir>
 
@@ -19,7 +21,6 @@
   : QObject(p)
 {
   this->WarnUninitializedMode = false;
-  this->WarnUnusedMode = false;
   qRegisterMetaType<QCMakeProperty>();
   qRegisterMetaType<QCMakePropertyList>();
 
@@ -35,7 +36,8 @@
   cmSystemTools::SetStderrCallback(
     [this](std::string const& msg) { this->stderrCallback(msg); });
 
-  this->CMakeInstance = new cmake(cmake::RoleProject, cmState::Project);
+  this->CMakeInstance =
+    cm::make_unique<cmake>(cmake::RoleProject, cmState::Project);
   this->CMakeInstance->SetCMakeEditCommand(
     cmSystemTools::GetCMakeGUICommand());
   this->CMakeInstance->SetProgressCallback(
@@ -55,11 +57,7 @@
   }
 }
 
-QCMake::~QCMake()
-{
-  delete this->CMakeInstance;
-  // cmDynamicLoader::FlushCache();
-}
+QCMake::~QCMake() = default;
 
 void QCMake::loadCache(const QString& dir)
 {
@@ -101,29 +99,28 @@
 
     QCMakePropertyList props = this->properties();
     emit this->propertiesChanged(props);
-    const char* homeDir = state->GetCacheEntryValue("CMAKE_HOME_DIRECTORY");
+    cmProp homeDir = state->GetCacheEntryValue("CMAKE_HOME_DIRECTORY");
     if (homeDir) {
-      setSourceDirectory(QString::fromLocal8Bit(homeDir));
+      setSourceDirectory(QString::fromLocal8Bit(homeDir->c_str()));
     }
-    const char* gen = state->GetCacheEntryValue("CMAKE_GENERATOR");
+    cmProp gen = state->GetCacheEntryValue("CMAKE_GENERATOR");
     if (gen) {
       const std::string* extraGen =
         state->GetInitializedCacheValue("CMAKE_EXTRA_GENERATOR");
       std::string curGen =
         cmExternalMakefileProjectGenerator::CreateFullGeneratorName(
-          gen, extraGen ? *extraGen : "");
+          *gen, extraGen ? *extraGen : "");
       this->setGenerator(QString::fromLocal8Bit(curGen.c_str()));
     }
 
-    const char* platform =
-      state->GetCacheEntryValue("CMAKE_GENERATOR_PLATFORM");
+    cmProp platform = state->GetCacheEntryValue("CMAKE_GENERATOR_PLATFORM");
     if (platform) {
-      this->setPlatform(QString::fromLocal8Bit(platform));
+      this->setPlatform(QString::fromLocal8Bit(platform->c_str()));
     }
 
-    const char* toolset = state->GetCacheEntryValue("CMAKE_GENERATOR_TOOLSET");
+    cmProp toolset = state->GetCacheEntryValue("CMAKE_GENERATOR_TOOLSET");
     if (toolset) {
-      this->setToolset(QString::fromLocal8Bit(toolset));
+      this->setToolset(QString::fromLocal8Bit(toolset->c_str()));
     }
 
     checkOpenPossible();
@@ -172,7 +169,6 @@
   this->CMakeInstance->SetGeneratorToolset(this->Toolset.toLocal8Bit().data());
   this->CMakeInstance->LoadCache();
   this->CMakeInstance->SetWarnUninitialized(this->WarnUninitializedMode);
-  this->CMakeInstance->SetWarnUnused(this->WarnUnusedMode);
   this->CMakeInstance->PreLoadCMakeFiles();
 
   InterruptFlag = 0;
@@ -304,27 +300,28 @@
       continue;
     }
 
-    const char* cachedValue = state->GetCacheEntryValue(key);
+    cmProp cachedValue = state->GetCacheEntryValue(key);
 
     QCMakeProperty prop;
     prop.Key = QString::fromLocal8Bit(key.c_str());
-    prop.Help =
-      QString::fromLocal8Bit(state->GetCacheEntryProperty(key, "HELPSTRING"));
-    prop.Value = QString::fromLocal8Bit(cachedValue);
+    if (cmProp hs = state->GetCacheEntryProperty(key, "HELPSTRING")) {
+      prop.Help = QString::fromLocal8Bit(hs->c_str());
+    }
+    prop.Value = QString::fromLocal8Bit(cachedValue->c_str());
     prop.Advanced = state->GetCacheEntryPropertyAsBool(key, "ADVANCED");
     if (t == cmStateEnums::BOOL) {
       prop.Type = QCMakeProperty::BOOL;
-      prop.Value = cmIsOn(cachedValue);
+      prop.Value = cmIsOn(*cachedValue);
     } else if (t == cmStateEnums::PATH) {
       prop.Type = QCMakeProperty::PATH;
     } else if (t == cmStateEnums::FILEPATH) {
       prop.Type = QCMakeProperty::FILEPATH;
     } else if (t == cmStateEnums::STRING) {
       prop.Type = QCMakeProperty::STRING;
-      const char* stringsProperty =
-        state->GetCacheEntryProperty(key, "STRINGS");
+      cmProp stringsProperty = state->GetCacheEntryProperty(key, "STRINGS");
       if (stringsProperty) {
-        prop.Strings = QString::fromLocal8Bit(stringsProperty).split(";");
+        prop.Strings =
+          QString::fromLocal8Bit(stringsProperty->c_str()).split(";");
       }
     }
 
@@ -341,10 +338,10 @@
 
 bool QCMake::interruptCallback()
 {
-#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
-  return this->InterruptFlag;
-#else
+#if QT_VERSION < QT_VERSION_CHECK(5, 14, 0)
   return this->InterruptFlag.load();
+#else
+  return this->InterruptFlag.loadRelaxed();
 #endif
 }
 
@@ -479,11 +476,6 @@
   this->WarnUninitializedMode = value;
 }
 
-void QCMake::setWarnUnusedMode(bool value)
-{
-  this->WarnUnusedMode = value;
-}
-
 void QCMake::checkOpenPossible()
 {
   std::string data = this->BinaryDirectory.toLocal8Bit().data();
diff --git a/Source/QtDialog/QCMake.h b/Source/QtDialog/QCMake.h
index fa4451b..39555d6 100644
--- a/Source/QtDialog/QCMake.h
+++ b/Source/QtDialog/QCMake.h
@@ -12,6 +12,7 @@
 #  pragma warning(disable : 4512)
 #endif
 
+#include <memory>
 #include <vector>
 
 #include <QAtomicInt>
@@ -113,8 +114,6 @@
   void setDeprecatedWarningsAsErrors(bool value);
   /// set whether to run cmake with warnings about uninitialized variables
   void setWarnUninitializedMode(bool value);
-  /// set whether to run cmake with warnings about unused variables
-  void setWarnUnusedMode(bool value);
   /// check if project IDE open is possible and emit openPossible signal
   void checkOpenPossible();
 
@@ -165,7 +164,7 @@
   void openPossible(bool possible);
 
 protected:
-  cmake* CMakeInstance;
+  std::unique_ptr<cmake> CMakeInstance;
 
   bool interruptCallback();
   void progressCallback(std::string const& msg, float percent);
@@ -174,8 +173,6 @@
   void stderrCallback(std::string const& msg);
 
   bool WarnUninitializedMode;
-  bool WarnUnusedMode;
-  bool WarnUnusedAllMode;
   QString SourceDirectory;
   QString BinaryDirectory;
   QString Generator;
diff --git a/Source/QtDialog/QCMakeCacheView.cxx b/Source/QtDialog/QCMakeCacheView.cxx
index 3e6a49e..3bf4409 100644
--- a/Source/QtDialog/QCMakeCacheView.cxx
+++ b/Source/QtDialog/QCMakeCacheView.cxx
@@ -155,11 +155,7 @@
 
 void QCMakeCacheView::setShowAdvanced(bool s)
 {
-#if QT_VERSION >= 040300
-  // new 4.3 API that needs to be called.  what about an older Qt?
   this->SearchFilter->invalidate();
-#endif
-
   this->AdvancedFilter->setShowAdvanced(s);
 }
 
@@ -209,18 +205,34 @@
 
 void QCMakeCacheModel::setProperties(const QCMakePropertyList& props)
 {
+  this->beginResetModel();
+
   QSet<QCMakeProperty> newProps;
   QSet<QCMakeProperty> newProps2;
 
   if (this->ShowNewProperties) {
+#if QT_VERSION < QT_VERSION_CHECK(5, 14, 0)
     newProps = props.toSet();
+#else
+    newProps = QSet<QCMakeProperty>(props.begin(), props.end());
+#endif
     newProps2 = newProps;
+#if QT_VERSION < QT_VERSION_CHECK(5, 14, 0)
     QSet<QCMakeProperty> oldProps = this->properties().toSet();
+#else
+    QCMakePropertyList const& oldPropsList = this->properties();
+    QSet<QCMakeProperty> oldProps =
+      QSet<QCMakeProperty>(oldPropsList.begin(), oldPropsList.end());
+#endif
     oldProps.intersect(newProps);
     newProps.subtract(oldProps);
     newProps2.subtract(newProps);
   } else {
+#if QT_VERSION < QT_VERSION_CHECK(5, 14, 0)
     newProps2 = props.toSet();
+#else
+    newProps2 = QSet<QCMakeProperty>(props.begin(), props.end());
+#endif
   }
 
   bool b = this->blockSignals(true);
@@ -229,10 +241,15 @@
   this->NewPropertyCount = newProps.size();
 
   if (View == FlatView) {
-    QCMakePropertyList newP = newProps.toList();
-    QCMakePropertyList newP2 = newProps2.toList();
+    QCMakePropertyList newP = newProps.values();
+    QCMakePropertyList newP2 = newProps2.values();
+#if QT_VERSION >= QT_VERSION_CHECK(5, 9, 0)
+    std::sort(newP.begin(), newP.end());
+    std::sort(newP2.begin(), newP2.end());
+#else
     qSort(newP);
     qSort(newP2);
+#endif
     int row_count = 0;
     foreach (QCMakeProperty const& p, newP) {
       this->insertRow(row_count);
@@ -262,10 +279,17 @@
       parentItems.append(
         new QStandardItem(key.isEmpty() ? tr("Ungrouped Entries") : key));
       parentItems.append(new QStandardItem());
+#if QT_VERSION >= QT_VERSION_CHECK(5, 9, 0)
+      parentItems[0]->setData(QBrush(QColor(255, 100, 100)),
+                              Qt::BackgroundRole);
+      parentItems[1]->setData(QBrush(QColor(255, 100, 100)),
+                              Qt::BackgroundRole);
+#else
       parentItems[0]->setData(QBrush(QColor(255, 100, 100)),
                               Qt::BackgroundColorRole);
       parentItems[1]->setData(QBrush(QColor(255, 100, 100)),
                               Qt::BackgroundColorRole);
+#endif
       parentItems[0]->setData(1, GroupRole);
       parentItems[1]->setData(1, GroupRole);
       root->appendRow(parentItems);
@@ -305,7 +329,7 @@
   }
 
   this->blockSignals(b);
-  this->reset();
+  this->endResetModel();
 }
 
 QCMakeCacheModel::ViewType QCMakeCacheModel::viewType() const
@@ -315,6 +339,8 @@
 
 void QCMakeCacheModel::setViewType(QCMakeCacheModel::ViewType t)
 {
+  this->beginResetModel();
+
   this->View = t;
 
   QCMakePropertyList props = this->properties();
@@ -330,7 +356,7 @@
   this->setProperties(oldProps);
   this->setProperties(props);
   this->blockSignals(b);
-  this->reset();
+  this->endResetModel();
 }
 
 void QCMakeCacheModel::setPropertyData(const QModelIndex& idx1,
@@ -356,10 +382,15 @@
   }
 
   if (isNew) {
+#if QT_VERSION >= QT_VERSION_CHECK(5, 9, 0)
+    this->setData(idx1, QBrush(QColor(255, 100, 100)), Qt::BackgroundRole);
+    this->setData(idx2, QBrush(QColor(255, 100, 100)), Qt::BackgroundRole);
+#else
     this->setData(idx1, QBrush(QColor(255, 100, 100)),
                   Qt::BackgroundColorRole);
     this->setData(idx2, QBrush(QColor(255, 100, 100)),
                   Qt::BackgroundColorRole);
+#endif
   }
 }
 
@@ -409,7 +440,11 @@
       reorgProps.append((*iter)[0]);
       iter = tmp.erase(iter);
     } else {
+#if QT_VERSION >= QT_VERSION_CHECK(5, 9, 0)
+      std::sort(iter->begin(), iter->end());
+#else
       qSort(*iter);
+#endif
       ++iter;
     }
   }
@@ -447,8 +482,7 @@
       // go to the next in the tree
       while (!idxs.isEmpty() &&
              (
-#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) &&                                \
-  QT_VERSION < QT_VERSION_CHECK(5, 1, 0)
+#if QT_VERSION < QT_VERSION_CHECK(5, 1, 0)
                (idxs.last().row() + 1) >= rowCount(idxs.last().parent()) ||
 #endif
                !idxs.last().sibling(idxs.last().row() + 1, 0).isValid())) {
@@ -608,20 +642,6 @@
   return success;
 }
 
-// Issue 205903 fixed in Qt 4.5.0.
-// Can remove this function and FileDialogFlag when minimum Qt version is 4.5
-bool QCMakeCacheModelDelegate::eventFilter(QObject* object, QEvent* evt)
-{
-  // workaround for what looks like a bug in Qt on macOS
-  // where it doesn't create a QWidget wrapper for the native file dialog
-  // so the Qt library ends up assuming the focus was lost to something else
-
-  if (evt->type() == QEvent::FocusOut && this->FileDialogFlag) {
-    return false;
-  }
-  return QItemDelegate::eventFilter(object, evt);
-}
-
 void QCMakeCacheModelDelegate::setModelData(QWidget* editor,
                                             QAbstractItemModel* model,
                                             const QModelIndex& index) const
@@ -639,9 +659,15 @@
   // increase to checkbox size
   QStyleOptionButton opt;
   opt.QStyleOption::operator=(option);
+#if QT_VERSION >= QT_VERSION_CHECK(5, 13, 0)
+  sz = sz.expandedTo(
+    style->subElementRect(QStyle::SE_ItemViewItemCheckIndicator, &opt, nullptr)
+      .size());
+#else
   sz = sz.expandedTo(
     style->subElementRect(QStyle::SE_ViewItemCheckIndicator, &opt, nullptr)
       .size());
+#endif
 
   return sz;
 }
diff --git a/Source/QtDialog/QCMakeCacheView.h b/Source/QtDialog/QCMakeCacheView.h
index bea1965..a252708 100644
--- a/Source/QtDialog/QCMakeCacheView.h
+++ b/Source/QtDialog/QCMakeCacheView.h
@@ -144,7 +144,6 @@
   bool editorEvent(QEvent* event, QAbstractItemModel* model,
                    const QStyleOptionViewItem& option,
                    const QModelIndex& index);
-  bool eventFilter(QObject* object, QEvent* event);
   void setModelData(QWidget* editor, QAbstractItemModel* model,
                     const QModelIndex& index) const;
   QSize sizeHint(const QStyleOptionViewItem& option,
diff --git a/Source/QtDialog/QCMakeWidgets.cxx b/Source/QtDialog/QCMakeWidgets.cxx
index 332a770..d16ea58 100644
--- a/Source/QtDialog/QCMakeWidgets.cxx
+++ b/Source/QtDialog/QCMakeWidgets.cxx
@@ -4,9 +4,9 @@
 
 #include <utility>
 
-#include <QDirModel>
 #include <QFileDialog>
 #include <QFileInfo>
+#include <QFileSystemModel>
 #include <QResizeEvent>
 #include <QToolButton>
 
@@ -88,20 +88,20 @@
   }
 }
 
-// use same QDirModel for all completers
-static QDirModel* fileDirModel()
+// use same QFileSystemModel for all completers
+static QFileSystemModel* fileDirModel()
 {
-  static QDirModel* m = nullptr;
+  static QFileSystemModel* m = nullptr;
   if (!m) {
-    m = new QDirModel();
+    m = new QFileSystemModel();
   }
   return m;
 }
-static QDirModel* pathDirModel()
+static QFileSystemModel* pathDirModel()
 {
-  static QDirModel* m = nullptr;
+  static QFileSystemModel* m = nullptr;
   if (!m) {
-    m = new QDirModel();
+    m = new QFileSystemModel();
     m->setFilter(QDir::AllDirs | QDir::Drives | QDir::NoDotAndDotDot);
   }
   return m;
@@ -110,7 +110,7 @@
 QCMakeFileCompleter::QCMakeFileCompleter(QObject* o, bool dirs)
   : QCompleter(o)
 {
-  QDirModel* m = dirs ? pathDirModel() : fileDirModel();
+  QFileSystemModel* m = dirs ? pathDirModel() : fileDirModel();
   this->setModel(m);
 }
 
diff --git a/Source/QtDialog/RegexExplorer.cxx b/Source/QtDialog/RegexExplorer.cxx
index 746fd8a..6194940 100644
--- a/Source/QtDialog/RegexExplorer.cxx
+++ b/Source/QtDialog/RegexExplorer.cxx
@@ -147,9 +147,6 @@
       } else if (nextc == 'n') {
         result.append(1, '\n');
         in++;
-      } else if (nextc == 't') {
-        result.append(1, '\t');
-        in++;
       } else if (isalnum(nextc) || nextc == '\0') {
         return false;
       } else {
diff --git a/Source/bindexplib.cxx b/Source/bindexplib.cxx
index 0b2750d..8435740 100644
--- a/Source/bindexplib.cxx
+++ b/Source/bindexplib.cxx
@@ -64,7 +64,7 @@
  */
 #include "bindexplib.h"
 
-#include <cstddef>
+#include <cstddef> // IWYU pragma: keep
 #include <sstream>
 #include <vector>
 
@@ -276,8 +276,9 @@
               symbol.compare(0, 4, vectorPrefix)) {
             SectChar = this->SectionHeaders[pSymbolTable->SectionNumber - 1]
                          .Characteristics;
-            // skip symbols containing a dot
-            if (symbol.find('.') == std::string::npos) {
+            // skip symbols containing a dot or are from managed code
+            if (symbol.find('.') == std::string::npos &&
+                !SymbolIsFromManagedCode(symbol)) {
               if (!pSymbolTable->Type && (SectChar & IMAGE_SCN_MEM_WRITE)) {
                 // Read only (i.e. constants) must be excluded
                 this->DataSymbols.insert(symbol);
@@ -302,6 +303,13 @@
   }
 
 private:
+  bool SymbolIsFromManagedCode(std::string const& symbol)
+  {
+    return symbol == "__t2m" || symbol == "__m2mep" || symbol == "__mep" ||
+      symbol.find("$$F") != std::string::npos ||
+      symbol.find("$$J") != std::string::npos;
+  }
+
   std::set<std::string>& Symbols;
   std::set<std::string>& DataSymbols;
   DWORD_PTR SymbolCount;
@@ -352,14 +360,14 @@
               line.c_str());
       return false;
     }
-    const std::string sym = line.substr(0, sym_end);
     const char sym_type = line[sym_end + 1];
+    line.resize(sym_end);
     switch (sym_type) {
       case 'D':
-        dataSymbols.insert(sym);
+        dataSymbols.insert(line);
         break;
       case 'T':
-        symbols.insert(sym);
+        symbols.insert(line);
         break;
     }
   }
diff --git a/Source/cmAddExecutableCommand.cxx b/Source/cmAddExecutableCommand.cxx
index e738bc4..9dd8a19 100644
--- a/Source/cmAddExecutableCommand.cxx
+++ b/Source/cmAddExecutableCommand.cxx
@@ -117,14 +117,9 @@
                                "\" is not an executable."));
       return false;
     }
-    if (aliasedTarget->IsImported() &&
-        !aliasedTarget->IsImportedGloballyVisible()) {
-      status.SetError(cmStrCat("cannot create ALIAS target \"", exename,
-                               "\" because target \"", aliasedName,
-                               "\" is imported but not globally visible."));
-      return false;
-    }
-    mf.AddAlias(exename, aliasedName);
+    mf.AddAlias(exename, aliasedName,
+                !aliasedTarget->IsImported() ||
+                  aliasedTarget->IsImportedGloballyVisible());
     return true;
   }
 
diff --git a/Source/cmAddLibraryCommand.cxx b/Source/cmAddLibraryCommand.cxx
index f443fc6..f262fac 100644
--- a/Source/cmAddLibraryCommand.cxx
+++ b/Source/cmAddLibraryCommand.cxx
@@ -2,13 +2,12 @@
    file Copyright.txt or https://cmake.org/licensing for details.  */
 #include "cmAddLibraryCommand.h"
 
-#include <cmext/algorithm>
-
 #include "cmExecutionStatus.h"
 #include "cmGeneratorExpression.h"
 #include "cmGlobalGenerator.h"
 #include "cmMakefile.h"
 #include "cmMessageType.h"
+#include "cmPolicies.h"
 #include "cmState.h"
 #include "cmStateTypes.h"
 #include "cmStringAlgorithms.h"
@@ -110,20 +109,10 @@
           "INTERFACE library specified with conflicting ALIAS type.");
         return false;
       }
-      if (excludeFromAll) {
-        status.SetError(
-          "INTERFACE library may not be used with EXCLUDE_FROM_ALL.");
-        return false;
-      }
       ++s;
       type = cmStateEnums::INTERFACE_LIBRARY;
       haveSpecifiedType = true;
     } else if (*s == "EXCLUDE_FROM_ALL") {
-      if (type == cmStateEnums::INTERFACE_LIBRARY) {
-        status.SetError(
-          "INTERFACE library may not be used with EXCLUDE_FROM_ALL.");
-        return false;
-      }
       ++s;
       excludeFromAll = true;
     } else if (*s == "IMPORTED") {
@@ -142,10 +131,6 @@
   }
 
   if (type == cmStateEnums::INTERFACE_LIBRARY) {
-    if (s != args.end()) {
-      status.SetError("INTERFACE library requires no source arguments.");
-      return false;
-    }
     if (importGlobal && !importTarget) {
       status.SetError(
         "INTERFACE library specified as GLOBAL, but not as IMPORTED.");
@@ -181,6 +166,16 @@
       return false;
     }
 
+    if (mf.GetPolicyStatus(cmPolicies::CMP0107) == cmPolicies::NEW) {
+      // Make sure the target does not already exist.
+      if (mf.FindTargetToUse(libName)) {
+        status.SetError(cmStrCat(
+          "cannot create ALIAS target \"", libName,
+          "\" because another target with the same name already exists."));
+        return false;
+      }
+    }
+
     std::string const& aliasedName = *s;
     if (mf.IsAlias(aliasedName)) {
       status.SetError(cmStrCat("cannot create ALIAS target \"", libName,
@@ -208,14 +203,9 @@
                                "\" is not a library."));
       return false;
     }
-    if (aliasedTarget->IsImported() &&
-        !aliasedTarget->IsImportedGloballyVisible()) {
-      status.SetError(cmStrCat("cannot create ALIAS target \"", libName,
-                               "\" because target \"", aliasedName,
-                               "\" is imported but not globally visible."));
-      return false;
-    }
-    mf.AddAlias(libName, aliasedName);
+    mf.AddAlias(libName, aliasedName,
+                !aliasedTarget->IsImported() ||
+                  aliasedTarget->IsImportedGloballyVisible());
     return true;
   }
 
@@ -296,8 +286,6 @@
     }
   }
 
-  std::vector<std::string> srclists;
-
   if (type == cmStateEnums::INTERFACE_LIBRARY) {
     if (!cmGeneratorExpression::IsValidTargetName(libName) ||
         libName.find("::") != std::string::npos) {
@@ -305,14 +293,10 @@
         cmStrCat("Invalid name for INTERFACE library target: ", libName));
       return false;
     }
-
-    mf.AddLibrary(libName, type, srclists, excludeFromAll);
-    return true;
   }
 
-  cm::append(srclists, s, args.end());
-
-  mf.AddLibrary(libName, type, srclists, excludeFromAll);
+  std::vector<std::string> srcs(s, args.end());
+  mf.AddLibrary(libName, type, srcs, excludeFromAll);
 
   return true;
 }
diff --git a/Source/cmAddSubDirectoryCommand.cxx b/Source/cmAddSubDirectoryCommand.cxx
index 35eabaf..83d6306 100644
--- a/Source/cmAddSubDirectoryCommand.cxx
+++ b/Source/cmAddSubDirectoryCommand.cxx
@@ -4,6 +4,8 @@
 
 #include <cstring>
 
+#include <cm/string_view>
+
 #include "cmExecutionStatus.h"
 #include "cmMakefile.h"
 #include "cmRange.h"
@@ -86,7 +88,8 @@
     if (binLen > 0 && bin.back() == '/') {
       --binLen;
     }
-    binPath = bin.substr(0, binLen) + srcPath.substr(srcLen);
+    binPath = cmStrCat(cm::string_view(bin).substr(0, binLen),
+                       cm::string_view(srcPath).substr(srcLen));
   } else {
     // Use the binary directory specified.
     // Interpret a relative path with respect to the current binary directory.
diff --git a/Source/cmAffinity.cxx b/Source/cmAffinity.cxx
index 8f9fe2a..35443e7 100644
--- a/Source/cmAffinity.cxx
+++ b/Source/cmAffinity.cxx
@@ -2,7 +2,7 @@
    file Copyright.txt or https://cmake.org/licensing for details.  */
 #include "cmAffinity.h"
 
-#include "cm_uv.h"
+#include <cm3p/uv.h>
 
 #ifndef CMAKE_USE_SYSTEM_LIBUV
 #  ifdef _WIN32
diff --git a/Source/cmAlgorithms.h b/Source/cmAlgorithms.h
index c0ac551..c8e8dcb 100644
--- a/Source/cmAlgorithms.h
+++ b/Source/cmAlgorithms.h
@@ -13,20 +13,10 @@
 #include <utility>
 #include <vector>
 
-#include "cm_kwiml.h"
+#include <cmext/algorithm>
 
 #include "cmRange.h"
 
-template <std::size_t N>
-struct cmOverloadPriority : cmOverloadPriority<N - 1>
-{
-};
-
-template <>
-struct cmOverloadPriority<0>
-{
-};
-
 template <typename FwdIt>
 FwdIt cmRotate(FwdIt first, FwdIt middle, FwdIt last)
 {
@@ -37,34 +27,6 @@
   return first;
 }
 
-template <typename Range, typename Key>
-auto cmContainsImpl(Range const& range, Key const& key, cmOverloadPriority<2>)
-  -> decltype(range.exists(key))
-{
-  return range.exists(key);
-}
-
-template <typename Range, typename Key>
-auto cmContainsImpl(Range const& range, Key const& key, cmOverloadPriority<1>)
-  -> decltype(range.find(key) != range.end())
-{
-  return range.find(key) != range.end();
-}
-
-template <typename Range, typename Key>
-bool cmContainsImpl(Range const& range, Key const& key, cmOverloadPriority<0>)
-{
-  using std::begin;
-  using std::end;
-  return std::find(begin(range), end(range), key) != end(range);
-}
-
-template <typename Range, typename Key>
-bool cmContains(Range const& range, Key const& key)
-{
-  return cmContainsImpl(range, key, cmOverloadPriority<2>{});
-}
-
 namespace ContainerAlgorithms {
 
 template <typename FwdIt>
@@ -158,7 +120,7 @@
 
   ForwardIterator result = first;
   while (first != last) {
-    if (!cmContains(uniq, first)) {
+    if (!cm::contains(uniq, first)) {
       if (result != first) {
         *result = std::move(*first);
       }
diff --git a/Source/cmArchiveWrite.cxx b/Source/cmArchiveWrite.cxx
index d29b2ac..addfbff 100644
--- a/Source/cmArchiveWrite.cxx
+++ b/Source/cmArchiveWrite.cxx
@@ -7,12 +7,14 @@
 #include <iostream>
 #include <sstream>
 
+#include <cm3p/archive.h>
+#include <cm3p/archive_entry.h>
+
 #include "cmsys/Directory.hxx"
 #include "cmsys/Encoding.hxx"
 #include "cmsys/FStream.hxx"
 
 #include "cm_get_date.h"
-#include "cm_libarchive.h"
 
 #include "cmLocale.h"
 #include "cmStringAlgorithms.h"
@@ -170,15 +172,19 @@
                            cm_archive_error_string(this->Archive));
     return;
   }
+}
 
+bool cmArchiveWrite::Open()
+{
   if (archive_write_open(
         this->Archive, this, nullptr,
         reinterpret_cast<archive_write_callback*>(&Callback::Write),
         nullptr) != ARCHIVE_OK) {
     this->Error =
       cmStrCat("archive_write_open: ", cm_archive_error_string(this->Archive));
-    return;
+    return false;
   }
+  return true;
 }
 
 cmArchiveWrite::~cmArchiveWrite()
@@ -276,7 +282,12 @@
       time_t epochTime;
       iss >> epochTime;
       if (iss.eof() && !iss.fail()) {
+        // Set all of the file times to the epoch time to handle archive
+        // formats that include creation/access time.
         archive_entry_set_mtime(e, epochTime, 0);
+        archive_entry_set_atime(e, epochTime, 0);
+        archive_entry_set_ctime(e, epochTime, 0);
+        archive_entry_set_birthtime(e, epochTime, 0);
       }
     }
   }
@@ -365,3 +376,16 @@
   }
   return true;
 }
+
+bool cmArchiveWrite::SetFilterOption(const char* module, const char* key,
+                                     const char* value)
+{
+  if (archive_write_set_filter_option(this->Archive, module, key, value) !=
+      ARCHIVE_OK) {
+    this->Error = "archive_write_set_filter_option: ";
+    this->Error += cm_archive_error_string(this->Archive);
+    return false;
+  }
+
+  return true;
+}
diff --git a/Source/cmArchiveWrite.h b/Source/cmArchiveWrite.h
index e791761..b643bce 100644
--- a/Source/cmArchiveWrite.h
+++ b/Source/cmArchiveWrite.h
@@ -62,6 +62,8 @@
   cmArchiveWrite(const cmArchiveWrite&) = delete;
   cmArchiveWrite& operator=(const cmArchiveWrite&) = delete;
 
+  bool Open();
+
   /**
    * Add a path (file or directory) to the archive.  Directories are
    * added recursively.  The "path" must be readable on disk, either
@@ -139,6 +141,9 @@
     this->Gname = "";
   }
 
+  //! Set an option on a filter;
+  bool SetFilterOption(const char* module, const char* key, const char* value);
+
 private:
   bool Okay() const { return this->Error.empty(); }
   bool AddPath(const char* path, size_t skip, const char* prefix,
diff --git a/Source/cmArgumentParser.cxx b/Source/cmArgumentParser.cxx
index 4c87177..4624f1c 100644
--- a/Source/cmArgumentParser.cxx
+++ b/Source/cmArgumentParser.cxx
@@ -3,7 +3,6 @@
 #include "cmArgumentParser.h"
 
 #include <algorithm>
-#include <type_traits>
 
 namespace ArgumentParser {
 
diff --git a/Source/cmArgumentParser.h b/Source/cmArgumentParser.h
index 9426537..5d2dfa2 100644
--- a/Source/cmArgumentParser.h
+++ b/Source/cmArgumentParser.h
@@ -12,8 +12,7 @@
 #include <vector>
 
 #include <cm/string_view>
-
-#include "cm_static_string_view.hxx"
+#include <cmext/string_view>
 
 namespace ArgumentParser {
 
diff --git a/Source/cmAuxSourceDirectoryCommand.cxx b/Source/cmAuxSourceDirectoryCommand.cxx
index 289bb72..53d4cb4 100644
--- a/Source/cmAuxSourceDirectoryCommand.cxx
+++ b/Source/cmAuxSourceDirectoryCommand.cxx
@@ -6,6 +6,8 @@
 #include <cstddef>
 #include <utility>
 
+#include <cm/string_view>
+
 #include "cmsys/Directory.hxx"
 
 #include "cmExecutionStatus.h"
@@ -50,11 +52,10 @@
       // Split the filename into base and extension
       std::string::size_type dotpos = file.rfind('.');
       if (dotpos != std::string::npos) {
-        std::string ext = file.substr(dotpos + 1);
-        std::string base = file.substr(0, dotpos);
+        auto ext = cm::string_view(file).substr(dotpos + 1);
         // Process only source files
         auto cm = mf.GetCMakeInstance();
-        if (!base.empty() && cm->IsSourceExtension(ext)) {
+        if (dotpos > 0 && cm->IsACLikeSourceExtension(ext)) {
           std::string fullname = cmStrCat(templateDirectory, '/', file);
           // add the file as a class file so
           // depends can be done
diff --git a/Source/cmBinUtilsLinuxELFLinker.cxx b/Source/cmBinUtilsLinuxELFLinker.cxx
index 0dea825..9ce403d 100644
--- a/Source/cmBinUtilsLinuxELFLinker.cxx
+++ b/Source/cmBinUtilsLinuxELFLinker.cxx
@@ -6,6 +6,7 @@
 #include <sstream>
 
 #include <cm/memory>
+#include <cm/string_view>
 
 #include <cmsys/RegularExpression.hxx>
 
@@ -26,14 +27,16 @@
 
   cmsys::RegularExpressionMatch match;
   if (originRegex.find(rpath.c_str(), match)) {
-    std::string begin = rpath.substr(0, match.start(1));
-    std::string end = rpath.substr(match.end(1));
-    return begin + origin + end;
+    cm::string_view pathv(rpath);
+    auto begin = pathv.substr(0, match.start(1));
+    auto end = pathv.substr(match.end(1));
+    return cmStrCat(begin, origin, end);
   }
   if (originCurlyRegex.find(rpath.c_str(), match)) {
-    std::string begin = rpath.substr(0, match.start());
-    std::string end = rpath.substr(match.end());
-    return begin + origin + end;
+    cm::string_view pathv(rpath);
+    auto begin = pathv.substr(0, match.start());
+    auto end = pathv.substr(match.end());
+    return cmStrCat(begin, origin, end);
   }
   return rpath;
 }
diff --git a/Source/cmBinUtilsMacOSMachOLinker.cxx b/Source/cmBinUtilsMacOSMachOLinker.cxx
index 98250b1..0f47146 100644
--- a/Source/cmBinUtilsMacOSMachOLinker.cxx
+++ b/Source/cmBinUtilsMacOSMachOLinker.cxx
@@ -14,6 +14,18 @@
 #include "cmStringAlgorithms.h"
 #include "cmSystemTools.h"
 
+namespace {
+bool IsMissingSystemDylib(std::string const& path)
+{
+  // Starting on macOS 11, the dynamic loader has a builtin cache of
+  // system-provided dylib files that do not exist on the filesystem.
+  // Tell our caller that these are expected to be missing.
+  return ((cmHasLiteralPrefix(path, "/System/Library/") ||
+           cmHasLiteralPrefix(path, "/usr/lib/")) &&
+          !cmSystemTools::PathExists(path));
+}
+}
+
 cmBinUtilsMacOSMachOLinker::cmBinUtilsMacOSMachOLinker(
   cmRuntimeDependencyArchive* archive)
   : cmBinUtilsLinker(archive)
@@ -82,7 +94,8 @@
         return false;
       }
       if (resolved) {
-        if (!this->Archive->IsPostExcluded(path)) {
+        if (!this->Archive->IsPostExcluded(path) &&
+            !IsMissingSystemDylib(path)) {
           auto filename = cmSystemTools::GetFilenameName(path);
           bool unique;
           this->Archive->AddResolvedPath(filename, path, unique);
diff --git a/Source/cmBuildCommand.cxx b/Source/cmBuildCommand.cxx
index 49c9439..b82fb9a 100644
--- a/Source/cmBuildCommand.cxx
+++ b/Source/cmBuildCommand.cxx
@@ -108,7 +108,7 @@
   if (cacheValue) {
     return true;
   }
-  mf.AddCacheDefinition(define, makecommand.c_str(),
+  mf.AddCacheDefinition(define, makecommand,
                         "Command used to build entire project "
                         "from the command line.",
                         cmStateEnums::STRING);
diff --git a/Source/cmBuildNameCommand.cxx b/Source/cmBuildNameCommand.cxx
index 3e517dc..ad4d665 100644
--- a/Source/cmBuildNameCommand.cxx
+++ b/Source/cmBuildNameCommand.cxx
@@ -28,7 +28,7 @@
       std::replace(cv.begin(), cv.end(), '/', '_');
       std::replace(cv.begin(), cv.end(), '(', '_');
       std::replace(cv.begin(), cv.end(), ')', '_');
-      mf.AddCacheDefinition(args[0], cv.c_str(), "Name of build.",
+      mf.AddCacheDefinition(args[0], cv, "Name of build.",
                             cmStateEnums::STRING);
     }
     return true;
@@ -54,7 +54,7 @@
   std::replace(buildname.begin(), buildname.end(), '(', '_');
   std::replace(buildname.begin(), buildname.end(), ')', '_');
 
-  mf.AddCacheDefinition(args[0], buildname.c_str(), "Name of build.",
+  mf.AddCacheDefinition(args[0], buildname, "Name of build.",
                         cmStateEnums::STRING);
   return true;
 }
diff --git a/Source/cmCMakeLanguageCommand.cxx b/Source/cmCMakeLanguageCommand.cxx
new file mode 100644
index 0000000..eb9269f
--- /dev/null
+++ b/Source/cmCMakeLanguageCommand.cxx
@@ -0,0 +1,137 @@
+/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
+   file Copyright.txt or https://cmake.org/licensing for details.  */
+#include "cmCMakeLanguageCommand.h"
+
+#include <algorithm>
+#include <array>
+#include <cstddef>
+#include <memory>
+#include <string>
+
+#include <cm/string_view>
+#include <cmext/string_view>
+
+#include "cmExecutionStatus.h"
+#include "cmListFileCache.h"
+#include "cmMakefile.h"
+#include "cmRange.h"
+#include "cmStringAlgorithms.h"
+#include "cmSystemTools.h"
+
+namespace {
+std::array<cm::static_string_view, 12> InvalidCommands{
+  { // clang-format off
+  "function"_s, "endfunction"_s,
+  "macro"_s, "endmacro"_s,
+  "if"_s, "elseif"_s, "else"_s, "endif"_s,
+  "while"_s, "endwhile"_s,
+  "foreach"_s, "endforeach"_s
+  } // clang-format on
+};
+}
+
+bool cmCMakeLanguageCommand(std::vector<cmListFileArgument> const& args,
+                            cmExecutionStatus& status)
+{
+  if (args.empty()) {
+    status.SetError("called with incorrect number of arguments");
+    return false;
+  }
+
+  cmMakefile& makefile = status.GetMakefile();
+  cmListFileContext context = makefile.GetExecutionContext();
+
+  bool result = false;
+
+  std::vector<std::string> dispatchExpandedArgs;
+  std::vector<cmListFileArgument> dispatchArgs;
+  dispatchArgs.emplace_back(args[0]);
+  makefile.ExpandArguments(dispatchArgs, dispatchExpandedArgs);
+
+  if (dispatchExpandedArgs.empty()) {
+    status.SetError("called with incorrect number of arguments");
+    return false;
+  }
+
+  if (dispatchExpandedArgs[0] == "CALL") {
+    if ((args.size() == 1 && dispatchExpandedArgs.size() != 2) ||
+        dispatchExpandedArgs.size() > 2) {
+      status.SetError("called with incorrect number of arguments");
+      return false;
+    }
+
+    // First argument is the name of the function to call
+    std::string callCommand;
+    size_t startArg;
+    if (dispatchExpandedArgs.size() == 1) {
+      std::vector<std::string> functionExpandedArg;
+      std::vector<cmListFileArgument> functionArg;
+      functionArg.emplace_back(args[1]);
+      makefile.ExpandArguments(functionArg, functionExpandedArg);
+
+      if (functionExpandedArg.size() != 1) {
+        status.SetError("called with incorrect number of arguments");
+        return false;
+      }
+
+      callCommand = functionExpandedArg[0];
+      startArg = 2;
+    } else {
+      callCommand = dispatchExpandedArgs[1];
+      startArg = 1;
+    }
+
+    // ensure specified command is valid
+    // start/end flow control commands are not allowed
+    auto cmd = cmSystemTools::LowerCase(callCommand);
+    if (std::find(InvalidCommands.cbegin(), InvalidCommands.cend(), cmd) !=
+        InvalidCommands.cend()) {
+      status.SetError(cmStrCat("invalid command specified: "_s, callCommand));
+      return false;
+    }
+
+    cmListFileFunction func;
+    func.Name = callCommand;
+    func.Line = context.Line;
+
+    // The rest of the arguments are passed to the function call above
+    for (size_t i = startArg; i < args.size(); ++i) {
+      cmListFileArgument lfarg;
+      lfarg.Delim = args[i].Delim;
+      lfarg.Line = context.Line;
+      lfarg.Value = args[i].Value;
+      func.Arguments.emplace_back(lfarg);
+    }
+
+    result = makefile.ExecuteCommand(func, status);
+  } else if (dispatchExpandedArgs[0] == "EVAL") {
+    std::vector<std::string> expandedArgs;
+    makefile.ExpandArguments(args, expandedArgs);
+
+    if (expandedArgs.size() < 2) {
+      status.SetError("called with incorrect number of arguments");
+      return false;
+    }
+
+    if (expandedArgs[1] != "CODE") {
+      auto code_iter =
+        std::find(expandedArgs.begin() + 2, expandedArgs.end(), "CODE");
+      if (code_iter == expandedArgs.end()) {
+        status.SetError("called without CODE argument");
+      } else {
+        status.SetError(
+          "called with unsupported arguments between EVAL and CODE arguments");
+      }
+      return false;
+    }
+
+    const std::string code =
+      cmJoin(cmMakeRange(expandedArgs.begin() + 2, expandedArgs.end()), " ");
+    result = makefile.ReadListFileAsString(
+      code, cmStrCat(context.FilePath, ":", context.Line, ":EVAL"));
+  } else {
+    status.SetError("called with unknown meta-operation");
+  }
+
+  return result;
+}
diff --git a/Source/cmCMakeLanguageCommand.h b/Source/cmCMakeLanguageCommand.h
new file mode 100644
index 0000000..aeb8f60
--- /dev/null
+++ b/Source/cmCMakeLanguageCommand.h
@@ -0,0 +1,20 @@
+/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
+   file Copyright.txt or https://cmake.org/licensing for details.  */
+#ifndef cmCMakeLanguageCommand_h
+#define cmCMakeLanguageCommand_h
+
+#include "cmConfigure.h" // IWYU pragma: keep
+
+#include <vector>
+
+class cmExecutionStatus;
+struct cmListFileArgument;
+
+/**
+ * \brief Calls a scripted or built-in command
+ *
+ */
+bool cmCMakeLanguageCommand(std::vector<cmListFileArgument> const& args,
+                            cmExecutionStatus& status);
+
+#endif
diff --git a/Source/cmCPluginAPI.cxx b/Source/cmCPluginAPI.cxx
index b5c7e96..697d435 100644
--- a/Source/cmCPluginAPI.cxx
+++ b/Source/cmCPluginAPI.cxx
@@ -488,24 +488,8 @@
 
 // Keep a map from real cmSourceFile instances stored in a makefile to
 // the CPluginAPI proxy source file.
-class cmCPluginAPISourceFileMap
-  : public std::map<cmSourceFile*, cmCPluginAPISourceFile*>
-{
-public:
-  using derived = std::map<cmSourceFile*, cmCPluginAPISourceFile*>;
-  using iterator = derived::iterator;
-  using value_type = derived::value_type;
-  cmCPluginAPISourceFileMap() = default;
-  ~cmCPluginAPISourceFileMap()
-  {
-    for (auto const& i : *this) {
-      delete i.second;
-    }
-  }
-  cmCPluginAPISourceFileMap(const cmCPluginAPISourceFileMap&) = delete;
-  cmCPluginAPISourceFileMap& operator=(const cmCPluginAPISourceFileMap&) =
-    delete;
-};
+using cmCPluginAPISourceFileMap =
+  std::map<cmSourceFile*, std::unique_ptr<cmCPluginAPISourceFile>>;
 cmCPluginAPISourceFileMap cmCPluginAPISourceFiles;
 
 void* CCONV cmCreateSourceFile(void)
@@ -536,7 +520,7 @@
     auto i = cmCPluginAPISourceFiles.find(rsf);
     if (i == cmCPluginAPISourceFiles.end()) {
       // Create a proxy source file object for this source.
-      cmCPluginAPISourceFile* sf = new cmCPluginAPISourceFile;
+      auto sf = cm::make_unique<cmCPluginAPISourceFile>();
       sf->RealSourceFile = rsf;
       sf->FullPath = rsf->ResolveFullPath();
       sf->SourceName =
@@ -545,10 +529,9 @@
         cmSystemTools::GetFilenameLastExtension(sf->FullPath);
 
       // Store the proxy in the map so it can be re-used and deleted later.
-      cmCPluginAPISourceFileMap::value_type entry(rsf, sf);
-      i = cmCPluginAPISourceFiles.insert(entry).first;
+      i = cmCPluginAPISourceFiles.emplace(rsf, std::move(sf)).first;
     }
-    return i->second;
+    return i->second.get();
   }
   return nullptr;
 }
@@ -569,15 +552,16 @@
   }
 
   // Create the proxy for the real source file.
-  cmCPluginAPISourceFile* sf = new cmCPluginAPISourceFile;
+  auto sf = cm::make_unique<cmCPluginAPISourceFile>();
   sf->RealSourceFile = rsf;
   sf->FullPath = osf->FullPath;
   sf->SourceName = osf->SourceName;
   sf->SourceExtension = osf->SourceExtension;
 
   // Store the proxy in the map so it can be re-used and deleted later.
-  cmCPluginAPISourceFiles[rsf] = sf;
-  return sf;
+  auto value = sf.get();
+  cmCPluginAPISourceFiles[rsf] = std::move(sf);
+  return value;
 }
 
 const char* CCONV cmSourceFileGetSourceName(void* arg)
@@ -596,12 +580,14 @@
 {
   cmCPluginAPISourceFile* sf = static_cast<cmCPluginAPISourceFile*>(arg);
   if (cmSourceFile* rsf = sf->RealSourceFile) {
-    return rsf->GetProperty(prop);
+    cmProp p = rsf->GetProperty(prop);
+    return p ? p->c_str() : nullptr;
   }
   if (!strcmp(prop, "LOCATION")) {
     return sf->FullPath.c_str();
   }
-  return sf->Properties.GetPropertyValue(prop);
+  cmProp retVal = sf->Properties.GetPropertyValue(prop);
+  return retVal ? retVal->c_str() : nullptr;
 }
 
 int CCONV cmSourceFileGetPropertyAsBool(void* arg, const char* prop)
@@ -791,8 +777,9 @@
                                     const char* longDocs, int chained)
 {
   cmMakefile* mf = static_cast<cmMakefile*>(arg);
-  mf->GetState()->DefineProperty(name, cmProperty::SOURCE_FILE, briefDocs,
-                                 longDocs, chained != 0);
+  mf->GetState()->DefineProperty(name, cmProperty::SOURCE_FILE,
+                                 briefDocs ? briefDocs : "",
+                                 longDocs ? longDocs : "", chained != 0);
 }
 
 } // close the extern "C" scope
diff --git a/Source/cmCTest.cxx b/Source/cmCTest.cxx
index 04f75bd..a5fde89 100644
--- a/Source/cmCTest.cxx
+++ b/Source/cmCTest.cxx
@@ -16,6 +16,14 @@
 #include <utility>
 #include <vector>
 
+#include <cm/memory>
+#include <cm/string_view>
+#include <cmext/algorithm>
+#include <cmext/string_view>
+
+#include <cm3p/curl/curl.h>
+#include <cm3p/zlib.h>
+
 #include "cmsys/Base64.h"
 #include "cmsys/Directory.hxx"
 #include "cmsys/FStream.hxx"
@@ -23,18 +31,12 @@
 #include "cmsys/Process.h"
 #include "cmsys/RegularExpression.hxx"
 #include "cmsys/SystemInformation.hxx"
-
-#include "cm_curl.h"
-#include "cm_zlib.h"
 #if defined(_WIN32)
 #  include <windows.h> // IWYU pragma: keep
 #else
 #  include <unistd.h> // IWYU pragma: keep
 #endif
 
-#include <cm/memory>
-#include <cmext/algorithm>
-
 #include "cmCTestBuildAndTestHandler.h"
 #include "cmCTestBuildHandler.h"
 #include "cmCTestConfigureHandler.h"
@@ -52,6 +54,7 @@
 #include "cmGlobalGenerator.h"
 #include "cmMakefile.h"
 #include "cmProcessOutput.h"
+#include "cmProperty.h"
 #include "cmState.h"
 #include "cmStateSnapshot.h"
 #include "cmStateTypes.h"
@@ -89,6 +92,7 @@
   std::string ConfigType;
   std::string ScheduleType;
   std::chrono::system_clock::time_point StopTime;
+  bool StopOnFailure = false;
   bool TestProgressOutput = false;
   bool Verbose = false;
   bool ExtraVerbose = false;
@@ -201,7 +205,7 @@
 
   int SubmitIndex = 0;
 
-  cmGeneratedFileStream* OutputLogFile = nullptr;
+  std::unique_ptr<cmGeneratedFileStream> OutputLogFile;
   int OutputLogFileLastTag = -1;
 
   bool OutputTestOutputOnTestFailure = false;
@@ -271,9 +275,10 @@
   return this->Impl->TomorrowTag;
 }
 
-std::string cmCTest::CleanString(const std::string& str)
+std::string cmCTest::CleanString(const std::string& str,
+                                 std::string::size_type spos)
 {
-  std::string::size_type spos = str.find_first_not_of(" \n\t\r\f\v");
+  spos = str.find_first_not_of(" \n\t\r\f\v", spos);
   std::string::size_type epos = str.find_last_not_of(" \n\t\r\f\v");
   if (spos == std::string::npos) {
     return std::string();
@@ -362,10 +367,7 @@
   cmSystemTools::EnableVSConsoleOutput();
 }
 
-cmCTest::~cmCTest()
-{
-  delete this->Impl->OutputLogFile;
-}
+cmCTest::~cmCTest() = default;
 
 int cmCTest::GetParallelLevel() const
 {
@@ -392,7 +394,7 @@
   return this->Impl->CompressTestOutput;
 }
 
-cmCTest::Part cmCTest::GetPartFromName(const char* name)
+cmCTest::Part cmCTest::GetPartFromName(const std::string& name)
 {
   // Look up by lower-case to make names case-insensitive.
   std::string lower_name = cmSystemTools::LowerCase(name);
@@ -456,8 +458,7 @@
   cm.GetCurrentSnapshot().SetDefaultDefinitions();
   cmGlobalGenerator gg(&cm);
   cmMakefile mf(&gg, cm.GetCurrentSnapshot());
-  if (!this->ReadCustomConfigurationFileTree(this->Impl->BinaryDir.c_str(),
-                                             &mf)) {
+  if (!this->ReadCustomConfigurationFileTree(this->Impl->BinaryDir, &mf)) {
     cmCTestOptionalLog(
       this, DEBUG, "Cannot find custom configuration file tree" << std::endl,
       quiet);
@@ -521,7 +522,7 @@
         std::string model;
         if (cmSystemTools::GetLineFromStream(tfin, model) &&
             !this->Impl->Parts[PartStart] && !command) {
-          this->Impl->TestModel = GetTestModelFromString(model.c_str());
+          this->Impl->TestModel = GetTestModelFromString(model);
         }
         tfin.close();
       }
@@ -577,7 +578,7 @@
         cmSystemTools::GetLineFromStream(tfin, tag);
         cmSystemTools::GetLineFromStream(tfin, group);
         if (cmSystemTools::GetLineFromStream(tfin, modelStr)) {
-          model = GetTestModelFromString(modelStr.c_str());
+          model = GetTestModelFromString(modelStr);
         }
         tfin.close();
       }
@@ -727,7 +728,7 @@
         continue;
       }
       while (fin && (line.back() == '\\')) {
-        line = line.substr(0, line.size() - 1);
+        line.resize(line.size() - 1);
         buffer[0] = 0;
         fin.getline(buffer, 1023);
         buffer[1023] = 0;
@@ -741,7 +742,7 @@
         continue;
       }
       std::string key = line.substr(0, cpos);
-      std::string value = cmCTest::CleanString(line.substr(cpos + 1));
+      std::string value = cmCTest::CleanString(line, cpos + 1);
       this->Impl->CTestConfiguration[key] = value;
     }
     fin.close();
@@ -791,7 +792,7 @@
   return this->Impl->TestModel;
 }
 
-bool cmCTest::SetTest(const char* ttype, bool report)
+bool cmCTest::SetTest(const std::string& ttype, bool report)
 {
   if (cmSystemTools::LowerCase(ttype) == "all") {
     for (Part p = PartStart; p != PartCount; p = Part(p + 1)) {
@@ -839,6 +840,7 @@
     }
   }
   std::string filename = testingDir + "/" + name;
+  stream.SetTempExt("tmp");
   stream.Open(filename);
   if (!stream) {
     cmCTestLog(this, ERROR_MESSAGE,
@@ -853,7 +855,7 @@
   return true;
 }
 
-bool cmCTest::AddIfExists(Part part, const char* file)
+bool cmCTest::AddIfExists(Part part, const std::string& file)
 {
   if (this->CTestFileExists(file)) {
     this->AddSubmitFile(part, file);
@@ -1005,7 +1007,7 @@
   if (this->Impl->Parts[PartNotes]) {
     this->UpdateCTestConfiguration();
     if (!this->Impl->NotesFiles.empty()) {
-      this->GenerateNotesFile(this->Impl->NotesFiles.c_str());
+      this->GenerateNotesFile(this->Impl->NotesFiles);
     }
   }
   if (this->Impl->Parts[PartSubmit]) {
@@ -1034,9 +1036,9 @@
   return "Experimental";
 }
 
-int cmCTest::GetTestModelFromString(const char* str)
+int cmCTest::GetTestModelFromString(const std::string& str)
 {
-  if (!str) {
+  if (str.empty()) {
     return cmCTest::EXPERIMENTAL;
   }
   std::string rstr = cmSystemTools::LowerCase(str);
@@ -1442,16 +1444,15 @@
     return;
   }
   // This code should go when cdash is changed to use labels only
-  const char* subproject = cm->GetState()->GetGlobalProperty("SubProject");
+  cmProp subproject = cm->GetState()->GetGlobalProperty("SubProject");
   if (subproject) {
     xml.StartElement("Subproject");
-    xml.Attribute("name", subproject);
-    const char* labels =
+    xml.Attribute("name", *subproject);
+    cmProp labels =
       ch->GetCMake()->GetState()->GetGlobalProperty("SubProjectLabels");
     if (labels) {
       xml.StartElement("Labels");
-      std::string l = labels;
-      std::vector<std::string> args = cmExpandedList(l);
+      std::vector<std::string> args = cmExpandedList(*labels);
       for (std::string const& i : args) {
         xml.Element("Label", i);
       }
@@ -1461,10 +1462,10 @@
   }
 
   // This code should stay when cdash only does label based sub-projects
-  const char* label = cm->GetState()->GetGlobalProperty("Label");
+  cmProp label = cm->GetState()->GetGlobalProperty("Label");
   if (label) {
     xml.StartElement("Labels");
-    xml.Element("Label", label);
+    xml.Element("Label", *label);
     xml.EndElement();
   }
 }
@@ -1563,9 +1564,9 @@
   return 0;
 }
 
-int cmCTest::GenerateNotesFile(const char* cfiles)
+int cmCTest::GenerateNotesFile(const std::string& cfiles)
 {
-  if (!cfiles) {
+  if (cfiles.empty()) {
     return 1;
   }
 
@@ -1648,14 +1649,14 @@
                                             << std::endl;);
       return false;
     }
-    this->AddSubmitFile(PartExtraFiles, file.c_str());
+    this->AddSubmitFile(PartExtraFiles, file);
   }
   return true;
 }
 
-bool cmCTest::SubmitExtraFiles(const char* cfiles)
+bool cmCTest::SubmitExtraFiles(const std::string& cfiles)
 {
-  if (!cfiles) {
+  if (cfiles.empty()) {
     return true;
   }
 
@@ -1816,10 +1817,10 @@
       << "  ctest -D NightlyMemoryCheck" << std::endl);
 }
 
-bool cmCTest::CheckArgument(const std::string& arg, const char* varg1,
+bool cmCTest::CheckArgument(const std::string& arg, cm::string_view varg1,
                             const char* varg2)
 {
-  return (varg1 && arg == varg1) || (varg2 && arg == varg2);
+  return (arg == varg1) || (varg2 && arg == varg2);
 }
 
 // Processes one command line argument (and its arguments if any)
@@ -1829,21 +1830,21 @@
                                          std::string& errormsg)
 {
   std::string arg = args[i];
-  if (this->CheckArgument(arg, "-F")) {
+  if (this->CheckArgument(arg, "-F"_s)) {
     this->Impl->Failover = true;
-  }
-  if (this->CheckArgument(arg, "-j", "--parallel") && i < args.size() - 1) {
+  } else if (this->CheckArgument(arg, "-j"_s, "--parallel") &&
+             i < args.size() - 1) {
     i++;
     int plevel = atoi(args[i].c_str());
     this->SetParallelLevel(plevel);
     this->Impl->ParallelLevelSetInCli = true;
-  } else if (arg.find("-j") == 0) {
+  } else if (cmHasPrefix(arg, "-j")) {
     int plevel = atoi(arg.substr(2).c_str());
     this->SetParallelLevel(plevel);
     this->Impl->ParallelLevelSetInCli = true;
   }
 
-  if (this->CheckArgument(arg, "--repeat-until-fail")) {
+  else if (this->CheckArgument(arg, "--repeat-until-fail"_s)) {
     if (i >= args.size() - 1) {
       errormsg = "'--repeat-until-fail' requires an argument";
       return false;
@@ -1855,8 +1856,8 @@
     i++;
     long repeat = 1;
     if (!cmStrToLong(args[i], &repeat)) {
-      errormsg =
-        "'--repeat-until-fail' given non-integer value '" + args[i] + "'";
+      errormsg = cmStrCat("'--repeat-until-fail' given non-integer value '",
+                          args[i], "'");
       return false;
     }
     this->Impl->RepeatCount = static_cast<int>(repeat);
@@ -1865,7 +1866,7 @@
     }
   }
 
-  if (this->CheckArgument(arg, "--repeat")) {
+  else if (this->CheckArgument(arg, "--repeat"_s)) {
     if (i >= args.size() - 1) {
       errormsg = "'--repeat' requires an argument";
       return false;
@@ -1893,12 +1894,12 @@
         }
       }
     } else {
-      errormsg = "'--repeat' given invalid value '" + args[i] + "'";
+      errormsg = cmStrCat("'--repeat' given invalid value '", args[i], "'");
       return false;
     }
   }
 
-  if (this->CheckArgument(arg, "--test-load") && i < args.size() - 1) {
+  else if (this->CheckArgument(arg, "--test-load"_s) && i < args.size() - 1) {
     i++;
     unsigned long load;
     if (cmStrToULong(args[i], &load)) {
@@ -1909,76 +1910,68 @@
     }
   }
 
-  if (this->CheckArgument(arg, "--no-compress-output")) {
+  else if (this->CheckArgument(arg, "--no-compress-output"_s)) {
     this->Impl->CompressTestOutput = false;
   }
 
-  if (this->CheckArgument(arg, "--print-labels")) {
+  else if (this->CheckArgument(arg, "--print-labels"_s)) {
     this->Impl->PrintLabels = true;
   }
 
-  if (this->CheckArgument(arg, "--http1.0")) {
+  else if (this->CheckArgument(arg, "--http1.0"_s)) {
     this->Impl->UseHTTP10 = true;
   }
 
-  if (this->CheckArgument(arg, "--timeout") && i < args.size() - 1) {
+  else if (this->CheckArgument(arg, "--timeout"_s) && i < args.size() - 1) {
     i++;
     auto timeout = cmDuration(atof(args[i].c_str()));
     this->Impl->GlobalTimeout = timeout;
   }
 
-  if (this->CheckArgument(arg, "--stop-time") && i < args.size() - 1) {
+  else if (this->CheckArgument(arg, "--stop-time"_s) && i < args.size() - 1) {
     i++;
     this->SetStopTime(args[i]);
   }
 
-  if (this->CheckArgument(arg, "-C", "--build-config") &&
-      i < args.size() - 1) {
-    i++;
-    this->SetConfigType(args[i].c_str());
+  else if (this->CheckArgument(arg, "--stop-on-failure"_s)) {
+    this->Impl->StopOnFailure = true;
   }
 
-  if (this->CheckArgument(arg, "--debug")) {
+  else if (this->CheckArgument(arg, "-C"_s, "--build-config") &&
+           i < args.size() - 1) {
+    i++;
+    this->SetConfigType(args[i]);
+  }
+
+  else if (this->CheckArgument(arg, "--debug"_s)) {
     this->Impl->Debug = true;
     this->Impl->ShowLineNumbers = true;
-  }
-  if (this->CheckArgument(arg, "--group") && i < args.size() - 1) {
+  } else if ((this->CheckArgument(arg, "--group"_s) ||
+              // This is an undocumented / deprecated option.
+              // "Track" has been renamed to "Group".
+              this->CheckArgument(arg, "--track"_s)) &&
+             i < args.size() - 1) {
     i++;
     this->Impl->SpecificGroup = args[i];
-  }
-  // This is an undocumented / deprecated option.
-  // "Track" has been renamed to "Group".
-  if (this->CheckArgument(arg, "--track") && i < args.size() - 1) {
-    i++;
-    this->Impl->SpecificGroup = args[i];
-  }
-  if (this->CheckArgument(arg, "--show-line-numbers")) {
+  } else if (this->CheckArgument(arg, "--show-line-numbers"_s)) {
     this->Impl->ShowLineNumbers = true;
-  }
-  if (this->CheckArgument(arg, "--no-label-summary")) {
+  } else if (this->CheckArgument(arg, "--no-label-summary"_s)) {
     this->Impl->LabelSummary = false;
-  }
-  if (this->CheckArgument(arg, "--no-subproject-summary")) {
+  } else if (this->CheckArgument(arg, "--no-subproject-summary"_s)) {
     this->Impl->SubprojectSummary = false;
-  }
-  if (this->CheckArgument(arg, "-Q", "--quiet")) {
+  } else if (this->CheckArgument(arg, "-Q"_s, "--quiet")) {
     this->Impl->Quiet = true;
-  }
-  if (this->CheckArgument(arg, "--progress")) {
+  } else if (this->CheckArgument(arg, "--progress"_s)) {
     this->Impl->TestProgressOutput = true;
-  }
-  if (this->CheckArgument(arg, "-V", "--verbose")) {
+  } else if (this->CheckArgument(arg, "-V"_s, "--verbose")) {
     this->Impl->Verbose = true;
-  }
-  if (this->CheckArgument(arg, "-VV", "--extra-verbose")) {
+  } else if (this->CheckArgument(arg, "-VV"_s, "--extra-verbose")) {
     this->Impl->ExtraVerbose = true;
     this->Impl->Verbose = true;
-  }
-  if (this->CheckArgument(arg, "--output-on-failure")) {
+  } else if (this->CheckArgument(arg, "--output-on-failure"_s)) {
     this->Impl->OutputTestOutputOnTestFailure = true;
-  }
-  if (this->CheckArgument(arg, "--test-output-size-passed") &&
-      i < args.size() - 1) {
+  } else if (this->CheckArgument(arg, "--test-output-size-passed"_s) &&
+             i < args.size() - 1) {
     i++;
     long outputSize;
     if (cmStrToLong(args[i], &outputSize)) {
@@ -1988,9 +1981,8 @@
                  "Invalid value for '--test-output-size-passed': " << args[i]
                                                                    << "\n");
     }
-  }
-  if (this->CheckArgument(arg, "--test-output-size-failed") &&
-      i < args.size() - 1) {
+  } else if (this->CheckArgument(arg, "--test-output-size-failed"_s) &&
+             i < args.size() - 1) {
     i++;
     long outputSize;
     if (cmStrToLong(args[i], &outputSize)) {
@@ -2000,11 +1992,9 @@
                  "Invalid value for '--test-output-size-failed': " << args[i]
                                                                    << "\n");
     }
-  }
-  if (this->CheckArgument(arg, "-N", "--show-only")) {
+  } else if (this->CheckArgument(arg, "-N"_s, "--show-only")) {
     this->Impl->ShowOnly = true;
-  }
-  if (cmHasLiteralPrefix(arg, "--show-only=")) {
+  } else if (cmHasLiteralPrefix(arg, "--show-only=")) {
     this->Impl->ShowOnly = true;
 
     // Check if a specific format is requested. Defaults to human readable
@@ -2022,27 +2012,26 @@
     }
   }
 
-  if (this->CheckArgument(arg, "-O", "--output-log") && i < args.size() - 1) {
+  else if (this->CheckArgument(arg, "-O"_s, "--output-log") &&
+           i < args.size() - 1) {
     i++;
-    this->SetOutputLogFileName(args[i].c_str());
+    this->SetOutputLogFileName(args[i]);
   }
 
-  if (this->CheckArgument(arg, "--tomorrow-tag")) {
+  else if (this->CheckArgument(arg, "--tomorrow-tag"_s)) {
     this->Impl->TomorrowTag = true;
-  }
-  if (this->CheckArgument(arg, "--force-new-ctest-process")) {
+  } else if (this->CheckArgument(arg, "--force-new-ctest-process"_s)) {
     this->Impl->ForceNewCTestProcess = true;
-  }
-  if (this->CheckArgument(arg, "-W", "--max-width") && i < args.size() - 1) {
+  } else if (this->CheckArgument(arg, "-W"_s, "--max-width") &&
+             i < args.size() - 1) {
     i++;
     this->Impl->MaxTestNameWidth = atoi(args[i].c_str());
-  }
-  if (this->CheckArgument(arg, "--interactive-debug-mode") &&
-      i < args.size() - 1) {
+  } else if (this->CheckArgument(arg, "--interactive-debug-mode"_s) &&
+             i < args.size() - 1) {
     i++;
     this->Impl->InteractiveDebugMode = cmIsOn(args[i]);
-  }
-  if (this->CheckArgument(arg, "--submit-index") && i < args.size() - 1) {
+  } else if (this->CheckArgument(arg, "--submit-index"_s) &&
+             i < args.size() - 1) {
     i++;
     this->Impl->SubmitIndex = atoi(args[i].c_str());
     if (this->Impl->SubmitIndex < 0) {
@@ -2050,24 +2039,27 @@
     }
   }
 
-  if (this->CheckArgument(arg, "--overwrite") && i < args.size() - 1) {
+  else if (this->CheckArgument(arg, "--overwrite"_s) && i < args.size() - 1) {
     i++;
     this->AddCTestConfigurationOverwrite(args[i]);
-  }
-  if (this->CheckArgument(arg, "-A", "--add-notes") && i < args.size() - 1) {
+  } else if (this->CheckArgument(arg, "-A"_s, "--add-notes") &&
+             i < args.size() - 1) {
     this->Impl->ProduceXML = true;
     this->SetTest("Notes");
     i++;
-    this->SetNotesFiles(args[i].c_str());
+    this->SetNotesFiles(args[i]);
+    return true;
   }
 
-  const std::string noTestsPrefix = "--no-tests=";
+  cm::string_view noTestsPrefix = "--no-tests=";
   if (cmHasPrefix(arg, noTestsPrefix)) {
-    const std::string noTestsMode = arg.substr(noTestsPrefix.length());
+    cm::string_view noTestsMode =
+      cm::string_view(arg).substr(noTestsPrefix.length());
     if (noTestsMode == "error") {
       this->Impl->NoTestsMode = cmCTest::NoTests::Error;
     } else if (noTestsMode != "ignore") {
-      errormsg = "'--no-tests=' given unknown value '" + noTestsMode + "'";
+      errormsg =
+        cmStrCat("'--no-tests=' given unknown value '", noTestsMode, '\'');
       return false;
     } else {
       this->Impl->NoTestsMode = cmCTest::NoTests::Ignore;
@@ -2075,34 +2067,32 @@
   }
 
   // options that control what tests are run
-  if (this->CheckArgument(arg, "-I", "--tests-information") &&
-      i < args.size() - 1) {
+  else if (this->CheckArgument(arg, "-I"_s, "--tests-information") &&
+           i < args.size() - 1) {
     i++;
     this->GetTestHandler()->SetPersistentOption("TestsToRunInformation",
                                                 args[i].c_str());
     this->GetMemCheckHandler()->SetPersistentOption("TestsToRunInformation",
                                                     args[i].c_str());
-  }
-  if (this->CheckArgument(arg, "-U", "--union")) {
+  } else if (this->CheckArgument(arg, "-U"_s, "--union")) {
     this->GetTestHandler()->SetPersistentOption("UseUnion", "true");
     this->GetMemCheckHandler()->SetPersistentOption("UseUnion", "true");
-  }
-  if (this->CheckArgument(arg, "-R", "--tests-regex") && i < args.size() - 1) {
+  } else if (this->CheckArgument(arg, "-R"_s, "--tests-regex") &&
+             i < args.size() - 1) {
     i++;
     this->GetTestHandler()->SetPersistentOption("IncludeRegularExpression",
                                                 args[i].c_str());
     this->GetMemCheckHandler()->SetPersistentOption("IncludeRegularExpression",
                                                     args[i].c_str());
-  }
-  if (this->CheckArgument(arg, "-L", "--label-regex") && i < args.size() - 1) {
+  } else if (this->CheckArgument(arg, "-L"_s, "--label-regex") &&
+             i < args.size() - 1) {
     i++;
     this->GetTestHandler()->SetPersistentOption("LabelRegularExpression",
                                                 args[i].c_str());
     this->GetMemCheckHandler()->SetPersistentOption("LabelRegularExpression",
                                                     args[i].c_str());
-  }
-  if (this->CheckArgument(arg, "-LE", "--label-exclude") &&
-      i < args.size() - 1) {
+  } else if (this->CheckArgument(arg, "-LE"_s, "--label-exclude") &&
+             i < args.size() - 1) {
     i++;
     this->GetTestHandler()->SetPersistentOption(
       "ExcludeLabelRegularExpression", args[i].c_str());
@@ -2110,8 +2100,8 @@
       "ExcludeLabelRegularExpression", args[i].c_str());
   }
 
-  if (this->CheckArgument(arg, "-E", "--exclude-regex") &&
-      i < args.size() - 1) {
+  else if (this->CheckArgument(arg, "-E"_s, "--exclude-regex") &&
+           i < args.size() - 1) {
     i++;
     this->GetTestHandler()->SetPersistentOption("ExcludeRegularExpression",
                                                 args[i].c_str());
@@ -2119,24 +2109,22 @@
                                                     args[i].c_str());
   }
 
-  if (this->CheckArgument(arg, "-FA", "--fixture-exclude-any") &&
-      i < args.size() - 1) {
+  else if (this->CheckArgument(arg, "-FA"_s, "--fixture-exclude-any") &&
+           i < args.size() - 1) {
     i++;
     this->GetTestHandler()->SetPersistentOption(
       "ExcludeFixtureRegularExpression", args[i].c_str());
     this->GetMemCheckHandler()->SetPersistentOption(
       "ExcludeFixtureRegularExpression", args[i].c_str());
-  }
-  if (this->CheckArgument(arg, "-FS", "--fixture-exclude-setup") &&
-      i < args.size() - 1) {
+  } else if (this->CheckArgument(arg, "-FS"_s, "--fixture-exclude-setup") &&
+             i < args.size() - 1) {
     i++;
     this->GetTestHandler()->SetPersistentOption(
       "ExcludeFixtureSetupRegularExpression", args[i].c_str());
     this->GetMemCheckHandler()->SetPersistentOption(
       "ExcludeFixtureSetupRegularExpression", args[i].c_str());
-  }
-  if (this->CheckArgument(arg, "-FC", "--fixture-exclude-cleanup") &&
-      i < args.size() - 1) {
+  } else if (this->CheckArgument(arg, "-FC"_s, "--fixture-exclude-cleanup") &&
+             i < args.size() - 1) {
     i++;
     this->GetTestHandler()->SetPersistentOption(
       "ExcludeFixtureCleanupRegularExpression", args[i].c_str());
@@ -2144,8 +2132,8 @@
       "ExcludeFixtureCleanupRegularExpression", args[i].c_str());
   }
 
-  if (this->CheckArgument(arg, "--resource-spec-file") &&
-      i < args.size() - 1) {
+  else if (this->CheckArgument(arg, "--resource-spec-file"_s) &&
+           i < args.size() - 1) {
     i++;
     this->GetTestHandler()->SetPersistentOption("ResourceSpecFile",
                                                 args[i].c_str());
@@ -2153,7 +2141,7 @@
                                                     args[i].c_str());
   }
 
-  if (this->CheckArgument(arg, "--rerun-failed")) {
+  else if (this->CheckArgument(arg, "--rerun-failed"_s)) {
     this->GetTestHandler()->SetPersistentOption("RerunFailed", "true");
     this->GetMemCheckHandler()->SetPersistentOption("RerunFailed", "true");
   }
@@ -2205,7 +2193,7 @@
                                     bool& SRArgumentSpecified)
 {
   std::string arg = args[i];
-  if (this->CheckArgument(arg, "-SP", "--script-new-process") &&
+  if (this->CheckArgument(arg, "-SP"_s, "--script-new-process") &&
       i < args.size() - 1) {
     this->Impl->RunConfigurationScript = true;
     i++;
@@ -2216,7 +2204,8 @@
     }
   }
 
-  if (this->CheckArgument(arg, "-SR", "--script-run") && i < args.size() - 1) {
+  if (this->CheckArgument(arg, "-SR"_s, "--script-run") &&
+      i < args.size() - 1) {
     SRArgumentSpecified = true;
     this->Impl->RunConfigurationScript = true;
     i++;
@@ -2224,7 +2213,7 @@
     ch->AddConfigurationScript(args[i].c_str(), true);
   }
 
-  if (this->CheckArgument(arg, "-S", "--script") && i < args.size() - 1) {
+  if (this->CheckArgument(arg, "-S"_s, "--script") && i < args.size() - 1) {
     this->Impl->RunConfigurationScript = true;
     i++;
     cmCTestScriptHandler* ch = this->GetScriptHandler();
@@ -2274,7 +2263,8 @@
 
     // --dashboard: handle a request for a dashboard
     std::string arg = args[i];
-    if (this->CheckArgument(arg, "-D", "--dashboard") && i < args.size() - 1) {
+    if (this->CheckArgument(arg, "-D"_s, "--dashboard") &&
+        i < args.size() - 1) {
       this->Impl->ProduceXML = true;
       i++;
       std::string targ = args[i];
@@ -2310,22 +2300,23 @@
     }
 
     // --extra-submit
-    if (this->CheckArgument(arg, "--extra-submit") && i < args.size() - 1) {
+    if (this->CheckArgument(arg, "--extra-submit"_s) && i < args.size() - 1) {
       this->Impl->ProduceXML = true;
       this->SetTest("Submit");
       i++;
-      if (!this->SubmitExtraFiles(args[i].c_str())) {
+      if (!this->SubmitExtraFiles(args[i])) {
         return 0;
       }
     }
 
     // --build-and-test options
-    if (this->CheckArgument(arg, "--build-and-test") && i < args.size() - 1) {
+    if (this->CheckArgument(arg, "--build-and-test"_s) &&
+        i < args.size() - 1) {
       cmakeAndTest = true;
     }
 
     // --schedule-random
-    if (this->CheckArgument(arg, "--schedule-random")) {
+    if (this->CheckArgument(arg, "--schedule-random"_s)) {
       this->Impl->ScheduleType = "Random";
     }
 
@@ -2380,11 +2371,11 @@
 {
   bool success = true;
   std::string arg = args[i];
-  if (this->CheckArgument(arg, "-T", "--test-action") &&
+  if (this->CheckArgument(arg, "-T"_s, "--test-action") &&
       (i < args.size() - 1)) {
     this->Impl->ProduceXML = true;
     i++;
-    if (!this->SetTest(args[i].c_str(), false)) {
+    if (!this->SetTest(args[i], false)) {
       success = false;
       cmCTestLog(this, ERROR_MESSAGE,
                  "CTest -T called with incorrect option: " << args[i]
@@ -2412,15 +2403,15 @@
 {
   bool success = true;
   std::string arg = args[i];
-  if (this->CheckArgument(arg, "-M", "--test-model") &&
+  if (this->CheckArgument(arg, "-M"_s, "--test-model") &&
       (i < args.size() - 1)) {
     i++;
     std::string const& str = args[i];
-    if (cmSystemTools::LowerCase(str) == "nightly") {
+    if (cmSystemTools::LowerCase(str) == "nightly"_s) {
       this->SetTestModel(cmCTest::NIGHTLY);
-    } else if (cmSystemTools::LowerCase(str) == "continuous") {
+    } else if (cmSystemTools::LowerCase(str) == "continuous"_s) {
       this->SetTestModel(cmCTest::CONTINUOUS);
-    } else if (cmSystemTools::LowerCase(str) == "experimental") {
+    } else if (cmSystemTools::LowerCase(str) == "experimental"_s) {
       this->SetTestModel(cmCTest::EXPERIMENTAL);
     } else {
       success = false;
@@ -2499,14 +2490,21 @@
   return retv;
 }
 
-void cmCTest::SetNotesFiles(const char* notes)
+void cmCTest::SetNotesFiles(const std::string& notes)
 {
-  if (!notes) {
-    return;
-  }
   this->Impl->NotesFiles = notes;
 }
 
+bool cmCTest::GetStopOnFailure() const
+{
+  return this->Impl->StopOnFailure;
+}
+
+void cmCTest::SetStopOnFailure(bool stop)
+{
+  this->Impl->StopOnFailure = stop;
+}
+
 std::chrono::system_clock::time_point cmCTest::GetStopTime() const
 {
   return this->Impl->StopTime;
@@ -2559,7 +2557,8 @@
   this->Impl->ScheduleType = type;
 }
 
-int cmCTest::ReadCustomConfigurationFileTree(const char* dir, cmMakefile* mf)
+int cmCTest::ReadCustomConfigurationFileTree(const std::string& dir,
+                                             cmMakefile* mf)
 {
   bool found = false;
   cmCTestLog(this, DEBUG,
@@ -2646,7 +2645,7 @@
   val = atoi(dval);
 }
 
-std::string cmCTest::GetShortPathToFile(const char* cfname)
+std::string cmCTest::GetShortPathToFile(const std::string& cfname)
 {
   const std::string& sourceDir = cmSystemTools::CollapseFullPath(
     this->GetCTestConfiguration("SourceDirectory"));
@@ -2687,7 +2686,7 @@
 
     path = "./" + *res;
     if (path.back() == '/') {
-      path = path.substr(0, path.size() - 1);
+      path.resize(path.size() - 1);
     }
   }
 
@@ -2710,18 +2709,17 @@
   this->Impl->CTestConfiguration.clear();
 }
 
-void cmCTest::SetCTestConfiguration(const char* name, const char* value,
+void cmCTest::SetCTestConfiguration(const char* name, const std::string& value,
                                     bool suppress)
 {
   cmCTestOptionalLog(this, HANDLER_VERBOSE_OUTPUT,
-                     "SetCTestConfiguration:"
-                       << name << ":" << (value ? value : "(null)") << "\n",
+                     "SetCTestConfiguration:" << name << ":" << value << "\n",
                      suppress);
 
   if (!name) {
     return;
   }
-  if (!value) {
+  if (value.empty()) {
     this->Impl->CTestConfiguration.erase(name);
     return;
   }
@@ -2738,7 +2736,7 @@
     std::string site = this->GetCTestConfiguration("DropSite");
     std::string location = this->GetCTestConfiguration("DropLocation");
 
-    url = cmStrCat(method.empty() ? "http" : method, "://");
+    url = cmStrCat(method.empty() ? "http" : method, "://"_s);
     if (!user.empty()) {
       url += user;
       if (!password.empty()) {
@@ -2926,7 +2924,7 @@
   return this->Impl->BuildID;
 }
 
-void cmCTest::AddSubmitFile(Part part, const char* name)
+void cmCTest::AddSubmitFile(Part part, const std::string& name)
 {
   this->Impl->Parts[part].SubmitFiles.emplace_back(name);
 }
@@ -2962,9 +2960,9 @@
   this->Impl->CTestConfigurationOverwrites[key] = value;
 }
 
-void cmCTest::SetConfigType(const char* ct)
+void cmCTest::SetConfigType(const std::string& ct)
 {
-  this->Impl->ConfigType = ct ? ct : "";
+  this->Impl->ConfigType = ct;
   cmSystemTools::ReplaceString(this->Impl->ConfigType, ".\\", "");
   std::string confTypeEnv = "CMAKE_CONFIG_TYPE=" + this->Impl->ConfigType;
   cmSystemTools::PutEnv(confTypeEnv);
@@ -2974,8 +2972,7 @@
   cmMakefile* mf, const char* dconfig, const std::string& cmake_var,
   bool suppress)
 {
-  const char* ctvar;
-  ctvar = mf->GetDefinition(cmake_var);
+  cmProp ctvar = mf->GetDef(cmake_var);
   if (!ctvar) {
     return false;
   }
@@ -2983,7 +2980,7 @@
                      "SetCTestConfigurationFromCMakeVariable:"
                        << dconfig << ":" << cmake_var << std::endl,
                      suppress);
-  this->SetCTestConfiguration(dconfig, ctvar, suppress);
+  this->SetCTestConfiguration(dconfig, *ctvar, suppress);
   return true;
 }
 
@@ -3084,14 +3081,12 @@
   return result;
 }
 
-void cmCTest::SetOutputLogFileName(const char* name)
+void cmCTest::SetOutputLogFileName(const std::string& name)
 {
-  if (this->Impl->OutputLogFile) {
-    delete this->Impl->OutputLogFile;
-    this->Impl->OutputLogFile = nullptr;
-  }
-  if (name) {
-    this->Impl->OutputLogFile = new cmGeneratedFileStream(name);
+  if (!name.empty()) {
+    this->Impl->OutputLogFile = cm::make_unique<cmGeneratedFileStream>(name);
+  } else {
+    this->Impl->OutputLogFile.reset();
   }
 }
 
diff --git a/Source/cmCTest.h b/Source/cmCTest.h
index 7f8f913..1e0fb8c 100644
--- a/Source/cmCTest.h
+++ b/Source/cmCTest.h
@@ -13,6 +13,8 @@
 #include <string>
 #include <vector>
 
+#include <cm/string_view>
+
 #include "cmDuration.h"
 #include "cmProcessOutput.h"
 
@@ -62,7 +64,7 @@
 
   /** Get a testing part id from its string name.  Returns PartCount
       if the string does not name a valid part.  */
-  Part GetPartFromName(const char* name);
+  Part GetPartFromName(const std::string& name);
 
   /** Process Command line arguments */
   int Run(std::vector<std::string>&, std::string* output = nullptr);
@@ -125,12 +127,12 @@
    * Check if CTest file exists
    */
   bool CTestFileExists(const std::string& filename);
-  bool AddIfExists(Part part, const char* file);
+  bool AddIfExists(Part part, const std::string& file);
 
   /**
    * Set the cmake test
    */
-  bool SetTest(const char*, bool report = true);
+  bool SetTest(const std::string&, bool report = true);
 
   /**
    * Set the cmake test mode (experimental, nightly, continuous).
@@ -139,10 +141,11 @@
   int GetTestModel() const;
 
   std::string GetTestModelString();
-  static int GetTestModelFromString(const char* str);
-  static std::string CleanString(const std::string& str);
+  static int GetTestModelFromString(const std::string& str);
+  static std::string CleanString(const std::string& str,
+                                 std::string::size_type spos = 0);
   std::string GetCTestConfiguration(const std::string& name);
-  void SetCTestConfiguration(const char* name, const char* value,
+  void SetCTestConfiguration(const char* name, const std::string& value,
                              bool suppress = false);
   void EmptyCTestConfiguration();
 
@@ -158,7 +161,7 @@
   cmCTest& operator=(const cmCTest&) = delete;
 
   /** Set the notes files to be created. */
-  void SetNotesFiles(const char* notes);
+  void SetNotesFiles(const std::string& notes);
 
   void PopulateCustomVector(cmMakefile* mf, const std::string& definition,
                             std::vector<std::string>& vec);
@@ -201,6 +204,9 @@
   bool ShouldCompressTestOutput();
   bool CompressString(std::string& str);
 
+  bool GetStopOnFailure() const;
+  void SetStopOnFailure(bool stop);
+
   std::chrono::system_clock::time_point GetStopTime() const;
   void SetStopTime(std::string const& time);
 
@@ -266,7 +272,7 @@
    * This means if the file is in binary or
    * source directory, it will become /.../relative/path/to/file
    */
-  std::string GetShortPathToFile(const char* fname);
+  std::string GetShortPathToFile(const std::string& fname);
 
   enum
   {
@@ -348,14 +354,14 @@
   int GenerateDoneFile();
 
   /** Submit extra files to the server */
-  bool SubmitExtraFiles(const char* files);
+  bool SubmitExtraFiles(const std::string& files);
   bool SubmitExtraFiles(std::vector<std::string> const& files);
 
   /** Set the output log file name */
-  void SetOutputLogFileName(const char* name);
+  void SetOutputLogFileName(const std::string& name);
 
   /** Set the visual studio or Xcode config type */
-  void SetConfigType(const char* ct);
+  void SetConfigType(const std::string& ct);
 
   /** Various log types */
   enum
@@ -393,14 +399,14 @@
   std::string GetBuildID() const;
 
   /** Add file to be submitted */
-  void AddSubmitFile(Part part, const char* name);
+  void AddSubmitFile(Part part, const std::string& name);
   std::vector<std::string> const& GetSubmitFiles(Part part) const;
   void ClearSubmitFiles(Part part);
 
   /**
    * Read the custom configuration files and apply them to the current ctest
    */
-  int ReadCustomConfigurationFileTree(const char* dir, cmMakefile* mf);
+  int ReadCustomConfigurationFileTree(const std::string& dir, cmMakefile* mf);
 
   std::vector<std::string>& GetInitialCommandLineArguments();
 
@@ -456,7 +462,7 @@
   void SetRunCurrentScript(bool value);
 
 private:
-  int GenerateNotesFile(const char* files);
+  int GenerateNotesFile(const std::string& files);
 
   void BlockTestErrorDiagnostics();
 
@@ -506,8 +512,8 @@
                                std::vector<std::string> const& files);
 
   /** Check if the argument is the one specified */
-  bool CheckArgument(const std::string& arg, const char* varg1,
-                     const char* varg2 = nullptr);
+  static bool CheckArgument(const std::string& arg, cm::string_view varg1,
+                            const char* varg2 = nullptr);
 
   /** Output errors from a test */
   void OutputTestErrors(std::vector<char> const& process_output);
diff --git a/Source/cmCacheManager.cxx b/Source/cmCacheManager.cxx
index dc9aba1..95686ea 100644
--- a/Source/cmCacheManager.cxx
+++ b/Source/cmCacheManager.cxx
@@ -19,12 +19,6 @@
 #include "cmSystemTools.h"
 #include "cmVersion.h"
 
-cmCacheManager::cmCacheManager()
-{
-  this->CacheMajorVersion = 0;
-  this->CacheMinorVersion = 0;
-}
-
 void cmCacheManager::CleanCMakeFiles(const std::string& path)
 {
   std::string glob = cmStrCat(path, "/CMakeFiles/*.cmake");
@@ -77,7 +71,7 @@
     }
     while (realbuffer[0] == '/' && realbuffer[1] == '/') {
       if ((realbuffer[2] == '\\') && (realbuffer[3] == 'n')) {
-        helpString += "\n";
+        helpString += '\n';
         helpString += &realbuffer[4];
       } else {
         helpString += &realbuffer[2];
@@ -117,20 +111,20 @@
       }
     } else {
       std::ostringstream error;
-      error << "Parse error in cache file " << cacheFile;
-      error << " on line " << lineno << ". Offending entry: " << realbuffer;
+      error << "Parse error in cache file " << cacheFile << " on line "
+            << lineno << ". Offending entry: " << realbuffer;
       cmSystemTools::Error(error.str());
     }
   }
   this->CacheMajorVersion = 0;
   this->CacheMinorVersion = 0;
-  if (const std::string* cmajor =
+  if (cmProp cmajor =
         this->GetInitializedCacheValue("CMAKE_CACHE_MAJOR_VERSION")) {
     unsigned int v = 0;
     if (sscanf(cmajor->c_str(), "%u", &v) == 1) {
       this->CacheMajorVersion = v;
     }
-    if (const std::string* cminor =
+    if (cmProp cminor =
           this->GetInitializedCacheValue("CMAKE_CACHE_MINOR_VERSION")) {
       if (sscanf(cminor->c_str(), "%u", &v) == 1) {
         this->CacheMinorVersion = v;
@@ -150,8 +144,7 @@
   }
   // check to make sure the cache directory has not
   // been moved
-  const std::string* oldDir =
-    this->GetInitializedCacheValue("CMAKE_CACHEFILE_DIR");
+  cmProp oldDir = this->GetInitializedCacheValue("CMAKE_CACHEFILE_DIR");
   if (internal && oldDir) {
     std::string currentcwd = path;
     std::string oldcwd = *oldDir;
@@ -159,8 +152,7 @@
     currentcwd += "/CMakeCache.txt";
     oldcwd += "/CMakeCache.txt";
     if (!cmSystemTools::SameFile(oldcwd, currentcwd)) {
-      const std::string* dir =
-        this->GetInitializedCacheValue("CMAKE_CACHEFILE_DIR");
+      cmProp dir = this->GetInitializedCacheValue("CMAKE_CACHEFILE_DIR");
       std::ostringstream message;
       message << "The current CMakeCache.txt directory " << currentcwd
               << " is different than the directory " << (dir ? *dir : "")
@@ -174,10 +166,10 @@
 }
 
 const char* cmCacheManager::PersistentProperties[] = { "ADVANCED", "MODIFIED",
-                                                       "STRINGS", nullptr };
+                                                       "STRINGS" };
 
-bool cmCacheManager::ReadPropertyEntry(std::string const& entryKey,
-                                       CacheEntry& e)
+bool cmCacheManager::ReadPropertyEntry(const std::string& entryKey,
+                                       const CacheEntry& e)
 {
   // All property entries are internal.
   if (e.Type != cmStateEnums::INTERNAL) {
@@ -185,20 +177,18 @@
   }
 
   const char* end = entryKey.c_str() + entryKey.size();
-  for (const char** p = cmCacheManager::PersistentProperties; *p; ++p) {
-    std::string::size_type plen = strlen(*p) + 1;
+  for (const char* p : cmCacheManager::PersistentProperties) {
+    std::string::size_type plen = strlen(p) + 1;
     if (entryKey.size() > plen && *(end - plen) == '-' &&
-        strcmp(end - plen + 1, *p) == 0) {
+        strcmp(end - plen + 1, p) == 0) {
       std::string key = entryKey.substr(0, entryKey.size() - plen);
-      cmCacheManager::CacheIterator it = this->GetCacheIterator(key);
-      if (it.IsAtEnd()) {
+      if (auto entry = this->GetCacheEntry(key)) {
+        // Store this property on its entry.
+        entry->SetProperty(p, e.Value.c_str());
+      } else {
         // Create an entry and store the property.
         CacheEntry& ne = this->Cache[key];
-        ne.Type = cmStateEnums::UNINITIALIZED;
-        ne.SetProperty(*p, e.Value.c_str());
-      } else {
-        // Store this property on its entry.
-        it.SetProperty(*p, e.Value.c_str());
+        ne.SetProperty(p, e.Value.c_str());
       }
       return true;
     }
@@ -206,21 +196,23 @@
   return false;
 }
 
-void cmCacheManager::WritePropertyEntries(std::ostream& os, CacheIterator i,
-                                          cmMessenger* messenger)
+void cmCacheManager::WritePropertyEntries(std::ostream& os,
+                                          const std::string& entryKey,
+                                          const CacheEntry& e,
+                                          cmMessenger* messenger) const
 {
-  for (const char** p = cmCacheManager::PersistentProperties; *p; ++p) {
-    if (const char* value = i.GetProperty(*p)) {
+  for (const char* p : cmCacheManager::PersistentProperties) {
+    if (cmProp value = e.GetProperty(p)) {
       std::string helpstring =
-        cmStrCat(*p, " property for variable: ", i.GetName());
+        cmStrCat(p, " property for variable: ", entryKey);
       cmCacheManager::OutputHelpString(os, helpstring);
 
-      std::string key = cmStrCat(i.GetName(), '-', *p);
+      std::string key = cmStrCat(entryKey, '-', p);
       cmCacheManager::OutputKey(os, key);
       os << ":INTERNAL=";
-      cmCacheManager::OutputValue(os, value);
-      os << "\n";
-      cmCacheManager::OutputNewlineTruncationWarning(os, key, value,
+      cmCacheManager::OutputValue(os, *value);
+      os << '\n';
+      cmCacheManager::OutputNewlineTruncationWarning(os, key, *value,
                                                      messenger);
     }
   }
@@ -270,31 +262,29 @@
 
   /* clang-format off */
   fout << "# This is the CMakeCache file.\n"
-       << "# For build in directory: " << currentcwd << "\n"
-       << "# It was generated by CMake: "
-       << cmSystemTools::GetCMakeCommand() << std::endl;
+          "# For build in directory: " << currentcwd << "\n"
+          "# It was generated by CMake: "
+       << cmSystemTools::GetCMakeCommand()
+       << "\n"
+          "# You can edit this file to change values found and used by cmake."
+          "\n"
+          "# If you do not want to change any of the values, simply exit the "
+          "editor.\n"
+          "# If you do want to change a value, simply edit, save, and exit "
+          "the editor.\n"
+          "# The syntax for the file is as follows:\n"
+          "# KEY:TYPE=VALUE\n"
+          "# KEY is the name of a variable in the cache.\n"
+          "# TYPE is a hint to GUIs for the type of VALUE, DO NOT EDIT TYPE!."
+          "\n"
+          "# VALUE is the current value for the KEY.\n"
+          "\n"
+          "########################\n"
+          "# EXTERNAL cache entries\n"
+          "########################\n"
+          "\n";
   /* clang-format on */
 
-  /* clang-format off */
-  fout << "# You can edit this file to change values found and used by cmake."
-       << std::endl
-       << "# If you do not want to change any of the values, simply exit the "
-       "editor." << std::endl
-       << "# If you do want to change a value, simply edit, save, and exit "
-       "the editor." << std::endl
-       << "# The syntax for the file is as follows:\n"
-       << "# KEY:TYPE=VALUE\n"
-       << "# KEY is the name of a variable in the cache.\n"
-       << "# TYPE is a hint to GUIs for the type of VALUE, DO NOT EDIT "
-       "TYPE!." << std::endl
-       << "# VALUE is the current value for the KEY.\n\n";
-  /* clang-format on */
-
-  fout << "########################\n";
-  fout << "# EXTERNAL cache entries\n";
-  fout << "########################\n";
-  fout << "\n";
-
   for (auto const& i : this->Cache) {
     CacheEntry const& ce = i.second;
     cmStateEnums::CacheEntryType t = ce.Type;
@@ -305,49 +295,48 @@
       */
     } else if (t != cmStateEnums::INTERNAL) {
       // Format is key:type=value
-      if (const char* help = ce.GetProperty("HELPSTRING")) {
-        cmCacheManager::OutputHelpString(fout, help);
+      if (cmProp help = ce.GetProperty("HELPSTRING")) {
+        cmCacheManager::OutputHelpString(fout, *help);
       } else {
         cmCacheManager::OutputHelpString(fout, "Missing description");
       }
       cmCacheManager::OutputKey(fout, i.first);
-      fout << ":" << cmState::CacheEntryTypeToString(t) << "=";
+      fout << ':' << cmState::CacheEntryTypeToString(t) << '=';
       cmCacheManager::OutputValue(fout, ce.Value);
-      fout << "\n";
+      fout << '\n';
       cmCacheManager::OutputNewlineTruncationWarning(fout, i.first, ce.Value,
                                                      messenger);
-      fout << "\n";
+      fout << '\n';
     }
   }
 
-  fout << "\n";
-  fout << "########################\n";
-  fout << "# INTERNAL cache entries\n";
-  fout << "########################\n";
-  fout << "\n";
+  fout << "\n"
+          "########################\n"
+          "# INTERNAL cache entries\n"
+          "########################\n"
+          "\n";
 
-  for (cmCacheManager::CacheIterator i = this->NewIterator(); !i.IsAtEnd();
-       i.Next()) {
-    if (!i.Initialized()) {
+  for (auto const& i : this->Cache) {
+    if (!i.second.Initialized) {
       continue;
     }
 
-    cmStateEnums::CacheEntryType t = i.GetType();
-    this->WritePropertyEntries(fout, i, messenger);
+    cmStateEnums::CacheEntryType t = i.second.GetType();
+    this->WritePropertyEntries(fout, i.first, i.second, messenger);
     if (t == cmStateEnums::INTERNAL) {
       // Format is key:type=value
-      if (const char* help = i.GetProperty("HELPSTRING")) {
-        cmCacheManager::OutputHelpString(fout, help);
+      if (cmProp help = i.second.GetProperty("HELPSTRING")) {
+        cmCacheManager::OutputHelpString(fout, *help);
       }
-      cmCacheManager::OutputKey(fout, i.GetName());
-      fout << ":" << cmState::CacheEntryTypeToString(t) << "=";
-      cmCacheManager::OutputValue(fout, i.GetValue());
-      fout << "\n";
-      cmCacheManager::OutputNewlineTruncationWarning(fout, i.GetName(),
-                                                     i.GetValue(), messenger);
+      cmCacheManager::OutputKey(fout, i.first);
+      fout << ':' << cmState::CacheEntryTypeToString(t) << '=';
+      cmCacheManager::OutputValue(fout, i.second.GetValue());
+      fout << '\n';
+      cmCacheManager::OutputNewlineTruncationWarning(
+        fout, i.first, i.second.GetValue(), messenger);
     }
   }
-  fout << "\n";
+  fout << '\n';
   fout.Close();
   std::string checkCacheFile = cmStrCat(path, "/CMakeFiles");
   cmSystemTools::MakeDirectory(checkCacheFile);
@@ -385,7 +374,9 @@
 {
   // support : in key name by double quoting
   const char* q =
-    (key.find(':') != std::string::npos || key.find("//") == 0) ? "\"" : "";
+    (key.find(':') != std::string::npos || cmHasLiteralPrefix(key, "//"))
+    ? "\""
+    : "";
   fout << q << key << q;
 }
 
@@ -430,7 +421,7 @@
         fout << "\\n";
       }
       oneLine = helpString.substr(pos, i - pos);
-      fout << oneLine << "\n";
+      fout << oneLine << '\n';
       pos = i;
     }
   }
@@ -452,7 +443,7 @@
         fout << "\\n";
       }
       oneLine = message.substr(pos, i - pos);
-      fout << oneLine << "\n";
+      fout << oneLine << '\n';
       pos = i;
     }
   }
@@ -481,10 +472,7 @@
 
 void cmCacheManager::RemoveCacheEntry(const std::string& key)
 {
-  auto i = this->Cache.find(key);
-  if (i != this->Cache.end()) {
-    this->Cache.erase(i);
-  }
+  this->Cache.erase(key);
 }
 
 cmCacheManager::CacheEntry* cmCacheManager::GetCacheEntry(
@@ -497,40 +485,39 @@
   return nullptr;
 }
 
-cmCacheManager::CacheIterator cmCacheManager::GetCacheIterator(
-  const std::string& key)
-{
-  return { *this, key.c_str() };
-}
-
-cmCacheManager::CacheIterator cmCacheManager::GetCacheIterator()
-{
-  return { *this, nullptr };
-}
-
-const std::string* cmCacheManager::GetInitializedCacheValue(
+const cmCacheManager::CacheEntry* cmCacheManager::GetCacheEntry(
   const std::string& key) const
 {
   auto i = this->Cache.find(key);
-  if (i != this->Cache.end() && i->second.Initialized) {
-    return &i->second.Value;
+  if (i != this->Cache.end()) {
+    return &i->second;
+  }
+  return nullptr;
+}
+
+cmProp cmCacheManager::GetInitializedCacheValue(const std::string& key) const
+{
+  if (auto entry = this->GetCacheEntry(key)) {
+    if (entry->Initialized) {
+      return &entry->GetValue();
+    }
   }
   return nullptr;
 }
 
 void cmCacheManager::PrintCache(std::ostream& out) const
 {
-  out << "=================================================" << std::endl;
-  out << "CMakeCache Contents:" << std::endl;
+  out << "=================================================\n"
+         "CMakeCache Contents:\n";
   for (auto const& i : this->Cache) {
     if (i.second.Type != cmStateEnums::INTERNAL) {
-      out << i.first << " = " << i.second.Value << std::endl;
+      out << i.first << " = " << i.second.Value << '\n';
     }
   }
-  out << "\n\n";
-  out << "To change values in the CMakeCache, " << std::endl
-      << "edit CMakeCache.txt in your output directory.\n";
-  out << "=================================================" << std::endl;
+  out << "\n\n"
+         "To change values in the CMakeCache, \n"
+         "edit CMakeCache.txt in your output directory.\n"
+         "=================================================\n";
 }
 
 void cmCacheManager::AddCacheEntry(const std::string& key, const char* value,
@@ -538,12 +525,7 @@
                                    cmStateEnums::CacheEntryType type)
 {
   CacheEntry& e = this->Cache[key];
-  if (value) {
-    e.Value = value;
-    e.Initialized = true;
-  } else {
-    e.Value.clear();
-  }
+  e.SetValue(value);
   e.Type = type;
   // make sure we only use unix style paths
   if (type == cmStateEnums::FILEPATH || type == cmStateEnums::PATH) {
@@ -567,70 +549,38 @@
                   : "(This variable does not exist and should not be used)");
 }
 
-bool cmCacheManager::CacheIterator::IsAtEnd() const
+void cmCacheManager::CacheEntry::SetValue(const char* value)
 {
-  return this->Position == this->Container.Cache.end();
-}
-
-void cmCacheManager::CacheIterator::Begin()
-{
-  this->Position = this->Container.Cache.begin();
-}
-
-bool cmCacheManager::CacheIterator::Find(const std::string& key)
-{
-  this->Position = this->Container.Cache.find(key);
-  return !this->IsAtEnd();
-}
-
-void cmCacheManager::CacheIterator::Next()
-{
-  if (!this->IsAtEnd()) {
-    ++this->Position;
-  }
-}
-
-std::vector<std::string> cmCacheManager::CacheIterator::GetPropertyList() const
-{
-  return this->GetEntry().GetPropertyList();
-}
-
-void cmCacheManager::CacheIterator::SetValue(const char* value)
-{
-  if (this->IsAtEnd()) {
-    return;
-  }
-  CacheEntry* entry = &this->GetEntry();
   if (value) {
-    entry->Value = value;
-    entry->Initialized = true;
+    this->Value = value;
+    this->Initialized = true;
   } else {
-    entry->Value.clear();
+    this->Value.clear();
   }
 }
 
-bool cmCacheManager::CacheIterator::GetValueAsBool() const
-{
-  return cmIsOn(this->GetEntry().Value);
-}
-
 std::vector<std::string> cmCacheManager::CacheEntry::GetPropertyList() const
 {
   return this->Properties.GetKeys();
 }
 
-const char* cmCacheManager::CacheEntry::GetProperty(
-  const std::string& prop) const
+cmProp cmCacheManager::CacheEntry::GetProperty(const std::string& prop) const
 {
   if (prop == "TYPE") {
-    return cmState::CacheEntryTypeToString(this->Type).c_str();
+    return &cmState::CacheEntryTypeToString(this->Type);
   }
   if (prop == "VALUE") {
-    return this->Value.c_str();
+    return &this->Value;
   }
   return this->Properties.GetPropertyValue(prop);
 }
 
+bool cmCacheManager::CacheEntry::GetPropertyAsBool(
+  const std::string& prop) const
+{
+  return cmIsOn(this->GetProperty(prop));
+}
+
 void cmCacheManager::CacheEntry::SetProperty(const std::string& prop,
                                              const char* value)
 {
@@ -643,6 +593,11 @@
   }
 }
 
+void cmCacheManager::CacheEntry::SetProperty(const std::string& p, bool v)
+{
+  this->SetProperty(p, v ? "ON" : "OFF");
+}
+
 void cmCacheManager::CacheEntry::AppendProperty(const std::string& prop,
                                                 const std::string& value,
                                                 bool asString)
@@ -661,49 +616,3 @@
     this->Properties.AppendProperty(prop, value, asString);
   }
 }
-
-const char* cmCacheManager::CacheIterator::GetProperty(
-  const std::string& prop) const
-{
-  if (!this->IsAtEnd()) {
-    return this->GetEntry().GetProperty(prop);
-  }
-  return nullptr;
-}
-
-void cmCacheManager::CacheIterator::SetProperty(const std::string& p,
-                                                const char* v)
-{
-  if (!this->IsAtEnd()) {
-    this->GetEntry().SetProperty(p, v);
-  }
-}
-
-void cmCacheManager::CacheIterator::AppendProperty(const std::string& p,
-                                                   const std::string& v,
-                                                   bool asString)
-{
-  if (!this->IsAtEnd()) {
-    this->GetEntry().AppendProperty(p, v, asString);
-  }
-}
-
-bool cmCacheManager::CacheIterator::GetPropertyAsBool(
-  const std::string& prop) const
-{
-  if (const char* value = this->GetProperty(prop)) {
-    return cmIsOn(value);
-  }
-  return false;
-}
-
-void cmCacheManager::CacheIterator::SetProperty(const std::string& p, bool v)
-{
-  this->SetProperty(p, v ? "ON" : "OFF");
-}
-
-bool cmCacheManager::CacheIterator::PropertyExists(
-  const std::string& prop) const
-{
-  return this->GetProperty(prop) != nullptr;
-}
diff --git a/Source/cmCacheManager.h b/Source/cmCacheManager.h
index d8be991..f036258 100644
--- a/Source/cmCacheManager.h
+++ b/Source/cmCacheManager.h
@@ -12,6 +12,7 @@
 #include <utility>
 #include <vector>
 
+#include "cmProperty.h"
 #include "cmPropertyMap.h"
 #include "cmStateTypes.h"
 
@@ -25,77 +26,33 @@
  */
 class cmCacheManager
 {
-public:
-  cmCacheManager();
-  class CacheIterator;
-  friend class cmCacheManager::CacheIterator;
-
-private:
-  struct CacheEntry
+  class CacheEntry
   {
+    friend class cmCacheManager;
+
+  public:
+    const std::string& GetValue() const { return this->Value; }
+    void SetValue(const char*);
+
+    cmStateEnums::CacheEntryType GetType() const { return this->Type; }
+    void SetType(cmStateEnums::CacheEntryType ty) { this->Type = ty; }
+
+    std::vector<std::string> GetPropertyList() const;
+    cmProp GetProperty(const std::string& property) const;
+    bool GetPropertyAsBool(const std::string& property) const;
+    void SetProperty(const std::string& property, const char* value);
+    void SetProperty(const std::string& property, bool value);
+    void AppendProperty(const std::string& property, const std::string& value,
+                        bool asString = false);
+
+  private:
     std::string Value;
     cmStateEnums::CacheEntryType Type = cmStateEnums::UNINITIALIZED;
     cmPropertyMap Properties;
-    std::vector<std::string> GetPropertyList() const;
-    const char* GetProperty(const std::string&) const;
-    void SetProperty(const std::string& property, const char* value);
-    void AppendProperty(const std::string& property, const std::string& value,
-                        bool asString = false);
     bool Initialized = false;
   };
 
 public:
-  class CacheIterator
-  {
-  public:
-    void Begin();
-    bool Find(const std::string&);
-    bool IsAtEnd() const;
-    void Next();
-    std::string GetName() const { return this->Position->first; }
-    std::vector<std::string> GetPropertyList() const;
-    const char* GetProperty(const std::string&) const;
-    bool GetPropertyAsBool(const std::string&) const;
-    bool PropertyExists(const std::string&) const;
-    void SetProperty(const std::string& property, const char* value);
-    void AppendProperty(const std::string& property, const std::string& value,
-                        bool asString = false);
-    void SetProperty(const std::string& property, bool value);
-    const std::string& GetValue() const { return this->GetEntry().Value; }
-    bool GetValueAsBool() const;
-    void SetValue(const char*);
-    cmStateEnums::CacheEntryType GetType() const
-    {
-      return this->GetEntry().Type;
-    }
-    void SetType(cmStateEnums::CacheEntryType ty)
-    {
-      this->GetEntry().Type = ty;
-    }
-    bool Initialized() { return this->GetEntry().Initialized; }
-    cmCacheManager& Container;
-    std::map<std::string, CacheEntry>::iterator Position;
-    CacheIterator(cmCacheManager& cm)
-      : Container(cm)
-    {
-      this->Begin();
-    }
-    CacheIterator(cmCacheManager& cm, const char* key)
-      : Container(cm)
-    {
-      if (key) {
-        this->Find(key);
-      }
-    }
-
-  private:
-    CacheEntry const& GetEntry() const { return this->Position->second; }
-    CacheEntry& GetEntry() { return this->Position->second; }
-  };
-
-  //! return an iterator to iterate through the cache map
-  cmCacheManager::CacheIterator NewIterator() { return { *this }; }
-
   //! Load a cache for given makefile.  Loads from path/CMakeCache.txt.
   bool LoadCache(const std::string& path, bool internal,
                  std::set<std::string>& excludes,
@@ -110,67 +67,82 @@
   //! Print the cache to a stream
   void PrintCache(std::ostream&) const;
 
-  //! Get the iterator for an entry with a given key.
-  cmCacheManager::CacheIterator GetCacheIterator(const std::string& key);
-  cmCacheManager::CacheIterator GetCacheIterator();
-
-  //! Remove an entry from the cache
-  void RemoveCacheEntry(const std::string& key);
-
-  //! Get the number of entries in the cache
-  int GetSize() { return static_cast<int>(this->Cache.size()); }
-
   //! Get a value from the cache given a key
-  const std::string* GetInitializedCacheValue(const std::string& key) const;
+  cmProp GetInitializedCacheValue(const std::string& key) const;
 
-  const char* GetCacheEntryValue(const std::string& key)
+  cmProp GetCacheEntryValue(const std::string& key) const
   {
-    cmCacheManager::CacheIterator it = this->GetCacheIterator(key);
-    if (it.IsAtEnd()) {
-      return nullptr;
+    if (auto entry = this->GetCacheEntry(key)) {
+      return &entry->GetValue();
     }
-    return it.GetValue().c_str();
+    return nullptr;
   }
 
-  const char* GetCacheEntryProperty(std::string const& key,
-                                    std::string const& propName)
+  void SetCacheEntryValue(std::string const& key, std::string const& value)
   {
-    return this->GetCacheIterator(key).GetProperty(propName);
+    if (auto entry = this->GetCacheEntry(key)) {
+      entry->SetValue(value.c_str());
+    }
   }
 
-  cmStateEnums::CacheEntryType GetCacheEntryType(std::string const& key)
+  cmStateEnums::CacheEntryType GetCacheEntryType(std::string const& key) const
   {
-    return this->GetCacheIterator(key).GetType();
+    if (auto entry = this->GetCacheEntry(key)) {
+      return entry->GetType();
+    }
+    return cmStateEnums::UNINITIALIZED;
+  }
+
+  std::vector<std::string> GetCacheEntryPropertyList(
+    std::string const& key) const
+  {
+    if (auto entry = this->GetCacheEntry(key)) {
+      return entry->GetPropertyList();
+    }
+    return {};
+  }
+
+  cmProp GetCacheEntryProperty(std::string const& key,
+                               std::string const& propName) const
+  {
+    if (auto entry = this->GetCacheEntry(key)) {
+      return entry->GetProperty(propName);
+    }
+    return nullptr;
   }
 
   bool GetCacheEntryPropertyAsBool(std::string const& key,
-                                   std::string const& propName)
+                                   std::string const& propName) const
   {
-    return this->GetCacheIterator(key).GetPropertyAsBool(propName);
+    if (auto entry = this->GetCacheEntry(key)) {
+      return entry->GetPropertyAsBool(propName);
+    }
+    return false;
   }
 
   void SetCacheEntryProperty(std::string const& key,
                              std::string const& propName,
                              std::string const& value)
   {
-    this->GetCacheIterator(key).SetProperty(propName, value.c_str());
+    if (auto entry = this->GetCacheEntry(key)) {
+      entry->SetProperty(propName, value.c_str());
+    }
   }
 
   void SetCacheEntryBoolProperty(std::string const& key,
                                  std::string const& propName, bool value)
   {
-    this->GetCacheIterator(key).SetProperty(propName, value);
-  }
-
-  void SetCacheEntryValue(std::string const& key, std::string const& value)
-  {
-    this->GetCacheIterator(key).SetValue(value.c_str());
+    if (auto entry = this->GetCacheEntry(key)) {
+      entry->SetProperty(propName, value);
+    }
   }
 
   void RemoveCacheEntryProperty(std::string const& key,
                                 std::string const& propName)
   {
-    this->GetCacheIterator(key).SetProperty(propName, nullptr);
+    if (auto entry = this->GetCacheEntry(key)) {
+      entry->SetProperty(propName, nullptr);
+    }
   }
 
   void AppendCacheEntryProperty(std::string const& key,
@@ -178,16 +150,17 @@
                                 std::string const& value,
                                 bool asString = false)
   {
-    this->GetCacheIterator(key).AppendProperty(propName, value, asString);
+    if (auto entry = this->GetCacheEntry(key)) {
+      entry->AppendProperty(propName, value, asString);
+    }
   }
 
-  std::vector<std::string> GetCacheEntryKeys()
+  std::vector<std::string> GetCacheEntryKeys() const
   {
     std::vector<std::string> definitions;
-    definitions.reserve(this->GetSize());
-    cmCacheManager::CacheIterator cit = this->GetCacheIterator();
-    for (cit.Begin(); !cit.IsAtEnd(); cit.Next()) {
-      definitions.push_back(cit.GetName());
+    definitions.reserve(this->Cache.size());
+    for (auto const& i : this->Cache) {
+      definitions.push_back(i.first);
     }
     return definitions;
   }
@@ -196,23 +169,22 @@
   unsigned int GetCacheMajorVersion() const { return this->CacheMajorVersion; }
   unsigned int GetCacheMinorVersion() const { return this->CacheMinorVersion; }
 
-protected:
   //! Add an entry into the cache
   void AddCacheEntry(const std::string& key, const char* value,
                      const char* helpString,
                      cmStateEnums::CacheEntryType type);
 
+  //! Remove an entry from the cache
+  void RemoveCacheEntry(const std::string& key);
+
+private:
   //! Get a cache entry object for a key
   CacheEntry* GetCacheEntry(const std::string& key);
+  const CacheEntry* GetCacheEntry(const std::string& key) const;
+
   //! Clean out the CMakeFiles directory if no CMakeCache.txt
   void CleanCMakeFiles(const std::string& path);
 
-  // Cache version info
-  unsigned int CacheMajorVersion;
-  unsigned int CacheMinorVersion;
-
-private:
-  using CacheEntryMap = std::map<std::string, CacheEntry>;
   static void OutputHelpString(std::ostream& fout,
                                const std::string& helpString);
   static void OutputWarningComment(std::ostream& fout,
@@ -228,15 +200,15 @@
                                     std::string const& value);
 
   static const char* PersistentProperties[];
-  bool ReadPropertyEntry(std::string const& key, CacheEntry& e);
-  void WritePropertyEntries(std::ostream& os, CacheIterator i,
-                            cmMessenger* messenger);
+  bool ReadPropertyEntry(const std::string& key, const CacheEntry& e);
+  void WritePropertyEntries(std::ostream& os, const std::string& entryKey,
+                            const CacheEntry& e, cmMessenger* messenger) const;
 
-  CacheEntryMap Cache;
-  // Only cmake and cmState should be able to add cache values
-  // the commands should never use the cmCacheManager directly
-  friend class cmState; // allow access to add cache values
-  friend class cmake;   // allow access to add cache values
+  std::map<std::string, CacheEntry> Cache;
+
+  // Cache version info
+  unsigned int CacheMajorVersion = 0;
+  unsigned int CacheMinorVersion = 0;
 };
 
 #endif
diff --git a/Source/cmCallVisualStudioMacro.cxx b/Source/cmCallVisualStudioMacro.cxx
index 9e152ff..94b6e18 100644
--- a/Source/cmCallVisualStudioMacro.cxx
+++ b/Source/cmCallVisualStudioMacro.cxx
@@ -43,8 +43,7 @@
       if (LogErrorsAsMessages) {                                              \
         std::ostringstream _hresult_oss;                                      \
         _hresult_oss.flags(std::ios::hex);                                    \
-        _hresult_oss << context << " failed HRESULT, hr = 0x" << hr           \
-                     << std::endl;                                            \
+        _hresult_oss << context << " failed HRESULT, hr = 0x" << hr << '\n';  \
         _hresult_oss.flags(std::ios::dec);                                    \
         _hresult_oss << __FILE__ << "(" << __LINE__ << ")";                   \
         cmSystemTools::Message(_hresult_oss.str());                           \
@@ -98,32 +97,37 @@
                          DISPATCH_METHOD, &params, &result, &excep, &arg);
 
       std::ostringstream oss;
-      oss << std::endl;
-      oss << "Invoke(ExecuteCommand)" << std::endl;
-      oss << "  Macro: " << macro << std::endl;
-      oss << "  Args: " << args << std::endl;
+      /* clang-format off */
+      oss << "\nInvoke(ExecuteCommand)\n"
+             "  Macro: " << macro << "\n"
+             "  Args: " << args << '\n';
+      /* clang-format on */
 
       if (DISP_E_EXCEPTION == hr) {
-        oss << "DISP_E_EXCEPTION EXCEPINFO:" << excep.wCode << std::endl;
-        oss << "  wCode: " << excep.wCode << std::endl;
-        oss << "  wReserved: " << excep.wReserved << std::endl;
+        /* clang-format off */
+        oss << "DISP_E_EXCEPTION EXCEPINFO:" << excep.wCode << "\n"
+               "  wCode: " << excep.wCode << "\n"
+               "  wReserved: " << excep.wReserved << '\n';
+        /* clang-format on */
         if (excep.bstrSource) {
           oss << "  bstrSource: " << (const char*)(_bstr_t)excep.bstrSource
-              << std::endl;
+              << '\n';
         }
         if (excep.bstrDescription) {
           oss << "  bstrDescription: "
-              << (const char*)(_bstr_t)excep.bstrDescription << std::endl;
+              << (const char*)(_bstr_t)excep.bstrDescription << '\n';
         }
         if (excep.bstrHelpFile) {
           oss << "  bstrHelpFile: " << (const char*)(_bstr_t)excep.bstrHelpFile
-              << std::endl;
+              << '\n';
         }
-        oss << "  dwHelpContext: " << excep.dwHelpContext << std::endl;
-        oss << "  pvReserved: " << excep.pvReserved << std::endl;
-        oss << "  pfnDeferredFillIn: "
-            << reinterpret_cast<void*>(excep.pfnDeferredFillIn) << std::endl;
-        oss << "  scode: " << excep.scode << std::endl;
+        /* clang-format off */
+        oss << "  dwHelpContext: " << excep.dwHelpContext << "\n"
+               "  pvReserved: " << excep.pvReserved << "\n"
+               "  pfnDeferredFillIn: "
+            << reinterpret_cast<void*>(excep.pfnDeferredFillIn) << "\n"
+               "  scode: " << excep.scode << '\n';
+        /* clang-format on */
       }
 
       std::string exstr(oss.str());
diff --git a/Source/cmCommandArgumentParserHelper.cxx b/Source/cmCommandArgumentParserHelper.cxx
index 613ae06..87eb91c 100644
--- a/Source/cmCommandArgumentParserHelper.cxx
+++ b/Source/cmCommandArgumentParserHelper.cxx
@@ -5,9 +5,13 @@
 #include <cstring>
 #include <iostream>
 #include <sstream>
+#include <utility>
+
+#include <cm/memory>
 
 #include "cmCommandArgumentLexer.h"
 #include "cmMakefile.h"
+#include "cmProperty.h"
 #include "cmState.h"
 #include "cmStringAlgorithms.h"
 #include "cmSystemTools.h"
@@ -40,10 +44,10 @@
   if (str.empty()) {
     return "";
   }
-  char* stVal = new char[str.size() + 1];
-  strcpy(stVal, str.c_str());
-  this->Variables.push_back(stVal);
-  return stVal;
+  auto stVal = cm::make_unique<char[]>(str.size() + 1);
+  strcpy(stVal.get(), str.c_str());
+  this->Variables.push_back(std::move(stVal));
+  return this->Variables.back().get();
 }
 
 const char* cmCommandArgumentParserHelper::ExpandSpecialVariable(
@@ -66,8 +70,7 @@
     return "";
   }
   if (strcmp(key, "CACHE") == 0) {
-    if (const std::string* c =
-          this->Makefile->GetState()->GetInitializedCacheValue(var)) {
+    if (cmProp c = this->Makefile->GetState()->GetInitializedCacheValue(var)) {
       if (this->EscapeQuotes) {
         return this->AddString(cmEscapeQuotes(*c));
       }
@@ -136,11 +139,11 @@
     return in1;
   }
   size_t len = strlen(in1) + strlen(in2) + 1;
-  char* out = new char[len];
-  strcpy(out, in1);
-  strcat(out, in2);
-  this->Variables.push_back(out);
-  return out;
+  auto out = cm::make_unique<char[]>(len);
+  strcpy(out.get(), in1);
+  strcat(out.get(), in2);
+  this->Variables.push_back(std::move(out));
+  return this->Variables.back().get();
 }
 
 void cmCommandArgumentParserHelper::AllocateParserType(
@@ -153,11 +156,11 @@
   if (len == 0) {
     return;
   }
-  char* out = new char[len + 1];
-  memcpy(out, str, len);
-  out[len] = 0;
-  pt->str = out;
-  this->Variables.push_back(out);
+  auto out = cm::make_unique<char[]>(len + 1);
+  memcpy(out.get(), str, len);
+  out.get()[len] = 0;
+  pt->str = out.get();
+  this->Variables.push_back(std::move(out));
 }
 
 bool cmCommandArgumentParserHelper::HandleEscapeSymbol(
@@ -235,10 +238,7 @@
 
 void cmCommandArgumentParserHelper::CleanupParser()
 {
-  for (char* var : this->Variables) {
-    delete[] var;
-  }
-  this->Variables.erase(this->Variables.begin(), this->Variables.end());
+  this->Variables.clear();
 }
 
 int cmCommandArgumentParserHelper::LexInput(char* buf, int maxlen)
diff --git a/Source/cmCommandArgumentParserHelper.h b/Source/cmCommandArgumentParserHelper.h
index 25e6892..b46edcb 100644
--- a/Source/cmCommandArgumentParserHelper.h
+++ b/Source/cmCommandArgumentParserHelper.h
@@ -5,6 +5,7 @@
 
 #include "cmConfigure.h" // IWYU pragma: keep
 
+#include <memory>
 #include <string>
 #include <vector>
 
@@ -69,7 +70,7 @@
   void CleanupParser();
   void SetError(std::string const& msg);
 
-  std::vector<char*> Variables;
+  std::vector<std::unique_ptr<char[]>> Variables;
   const cmMakefile* Makefile;
   std::string Result;
   std::string ErrorString;
diff --git a/Source/cmCommands.cxx b/Source/cmCommands.cxx
index 896b6a9..c94f128 100644
--- a/Source/cmCommands.cxx
+++ b/Source/cmCommands.cxx
@@ -92,6 +92,7 @@
 #  include "cmAuxSourceDirectoryCommand.h"
 #  include "cmBuildNameCommand.h"
 #  include "cmCMakeHostSystemInformationCommand.h"
+#  include "cmCMakeLanguageCommand.h"
 #  include "cmExportCommand.h"
 #  include "cmExportLibraryDependenciesCommand.h"
 #  include "cmFLTKWrapUICommand.h"
@@ -198,6 +199,7 @@
 #if !defined(CMAKE_BOOTSTRAP)
   state->AddBuiltinCommand("cmake_host_system_information",
                            cmCMakeHostSystemInformationCommand);
+  state->AddBuiltinCommand("cmake_language", cmCMakeLanguageCommand);
   state->AddBuiltinCommand("load_cache", cmLoadCacheCommand);
   state->AddBuiltinCommand("remove", cmRemoveCommand);
   state->AddBuiltinCommand("variable_watch", cmVariableWatchCommand);
diff --git a/Source/cmCommonTargetGenerator.cxx b/Source/cmCommonTargetGenerator.cxx
index 033cb60..8aee27c 100644
--- a/Source/cmCommonTargetGenerator.cxx
+++ b/Source/cmCommonTargetGenerator.cxx
@@ -14,6 +14,7 @@
 #include "cmLocalGenerator.h"
 #include "cmMakefile.h"
 #include "cmOutputConverter.h"
+#include "cmProperty.h"
 #include "cmSourceFile.h"
 #include "cmStateTypes.h"
 #include "cmStringAlgorithms.h"
@@ -40,7 +41,7 @@
 const char* cmCommonTargetGenerator::GetFeature(const std::string& feature,
                                                 const std::string& config)
 {
-  return this->GeneratorTarget->GetFeature(feature, config);
+  return this->GeneratorTarget->GetFeature(feature, config)->c_str();
 }
 
 void cmCommonTargetGenerator::AddModuleDefinitionFlag(
@@ -73,11 +74,12 @@
 void cmCommonTargetGenerator::AppendFortranFormatFlags(
   std::string& flags, cmSourceFile const& source)
 {
-  const char* srcfmt = source.GetProperty("Fortran_FORMAT");
+  const std::string srcfmt = source.GetSafeProperty("Fortran_FORMAT");
   cmOutputConverter::FortranFormat format =
     cmOutputConverter::GetFortranFormat(srcfmt);
   if (format == cmOutputConverter::FortranFormatNone) {
-    const char* tgtfmt = this->GeneratorTarget->GetProperty("Fortran_FORMAT");
+    std::string const& tgtfmt =
+      this->GeneratorTarget->GetSafeProperty("Fortran_FORMAT");
     format = cmOutputConverter::GetFortranFormat(tgtfmt);
   }
   const char* var = nullptr;
@@ -97,18 +99,49 @@
   }
 }
 
-std::string cmCommonTargetGenerator::GetFlags(const std::string& l,
-                                              const std::string& config)
+void cmCommonTargetGenerator::AppendFortranPreprocessFlags(
+  std::string& flags, cmSourceFile const& source)
 {
-  auto i = this->Configs[config].FlagsByLanguage.find(l);
-  if (i == this->Configs[config].FlagsByLanguage.end()) {
+  const std::string srcpp = source.GetSafeProperty("Fortran_PREPROCESS");
+  cmOutputConverter::FortranPreprocess preprocess =
+    cmOutputConverter::GetFortranPreprocess(srcpp);
+  if (preprocess == cmOutputConverter::FortranPreprocess::Unset) {
+    std::string const& tgtpp =
+      this->GeneratorTarget->GetSafeProperty("Fortran_PREPROCESS");
+    preprocess = cmOutputConverter::GetFortranPreprocess(tgtpp);
+  }
+  const char* var = nullptr;
+  switch (preprocess) {
+    case cmOutputConverter::FortranPreprocess::Needed:
+      var = "CMAKE_Fortran_COMPILE_OPTIONS_PREPROCESS_ON";
+      break;
+    case cmOutputConverter::FortranPreprocess::NotNeeded:
+      var = "CMAKE_Fortran_COMPILE_OPTIONS_PREPROCESS_OFF";
+      break;
+    default:
+      break;
+  }
+  if (var) {
+    this->LocalCommonGenerator->AppendCompileOptions(
+      flags, this->Makefile->GetSafeDefinition(var));
+  }
+}
+
+std::string cmCommonTargetGenerator::GetFlags(const std::string& l,
+                                              const std::string& config,
+                                              const std::string& arch)
+{
+  const std::string key = config + arch;
+
+  auto i = this->Configs[key].FlagsByLanguage.find(l);
+  if (i == this->Configs[key].FlagsByLanguage.end()) {
     std::string flags;
 
     this->LocalCommonGenerator->GetTargetCompileFlags(this->GeneratorTarget,
-                                                      config, l, flags);
+                                                      config, l, flags, arch);
 
     ByLanguageMap::value_type entry(l, flags);
-    i = this->Configs[config].FlagsByLanguage.insert(entry).first;
+    i = this->Configs[key].FlagsByLanguage.insert(entry).first;
   }
   return i->second;
 }
@@ -221,9 +254,9 @@
 {
   std::string aixExports;
   if (this->GeneratorTarget->Target->IsAIX()) {
-    if (const char* exportAll =
+    if (cmProp exportAll =
           this->GeneratorTarget->GetProperty("AIX_EXPORT_ALL_SYMBOLS")) {
-      if (cmIsOff(exportAll)) {
+      if (cmIsOff(*exportAll)) {
         aixExports = "-n";
       }
     }
diff --git a/Source/cmCommonTargetGenerator.h b/Source/cmCommonTargetGenerator.h
index b40a2ed..c3c3a3a 100644
--- a/Source/cmCommonTargetGenerator.h
+++ b/Source/cmCommonTargetGenerator.h
@@ -45,13 +45,17 @@
   void AppendFortranFormatFlags(std::string& flags,
                                 cmSourceFile const& source);
 
+  void AppendFortranPreprocessFlags(std::string& flags,
+                                    cmSourceFile const& source);
+
   virtual void AddIncludeFlags(std::string& flags, std::string const& lang,
                                const std::string& config) = 0;
 
   void AppendOSXVerFlag(std::string& flags, const std::string& lang,
                         const char* name, bool so);
 
-  std::string GetFlags(const std::string& l, const std::string& config);
+  std::string GetFlags(const std::string& l, const std::string& config,
+                       const std::string& arch = std::string());
   std::string GetDefines(const std::string& l, const std::string& config);
   std::string GetIncludes(std::string const& l, const std::string& config);
   std::string GetManifests(const std::string& config);
diff --git a/Source/cmComputeComponentGraph.cxx b/Source/cmComputeComponentGraph.cxx
index 81cd878..6591fb1 100644
--- a/Source/cmComputeComponentGraph.cxx
+++ b/Source/cmComputeComponentGraph.cxx
@@ -8,6 +8,12 @@
 cmComputeComponentGraph::cmComputeComponentGraph(Graph const& input)
   : InputGraph(input)
 {
+}
+
+cmComputeComponentGraph::~cmComputeComponentGraph() = default;
+
+void cmComputeComponentGraph::Compute()
+{
   // Identify components.
   this->Tarjan();
 
@@ -17,8 +23,6 @@
   this->TransferEdges();
 }
 
-cmComputeComponentGraph::~cmComputeComponentGraph() = default;
-
 void cmComputeComponentGraph::Tarjan()
 {
   int n = static_cast<int>(this->InputGraph.size());
diff --git a/Source/cmComputeComponentGraph.h b/Source/cmComputeComponentGraph.h
index 202888c..b873131 100644
--- a/Source/cmComputeComponentGraph.h
+++ b/Source/cmComputeComponentGraph.h
@@ -31,6 +31,9 @@
   cmComputeComponentGraph(Graph const& input);
   ~cmComputeComponentGraph();
 
+  /** Run the computation.  */
+  void Compute();
+
   /** Get the adjacency list of the component graph.  */
   Graph const& GetComponentGraph() const { return this->ComponentGraph; }
   EdgeList const& GetComponentGraphEdges(int c) const
diff --git a/Source/cmComputeLinkDepends.cxx b/Source/cmComputeLinkDepends.cxx
index e9bf5a5..8ca2168 100644
--- a/Source/cmComputeLinkDepends.cxx
+++ b/Source/cmComputeLinkDepends.cxx
@@ -253,13 +253,13 @@
   // Compute the final set of link entries.
   // Iterate in reverse order so we can keep only the last occurrence
   // of a shared library.
-  std::set<int> emmitted;
+  std::set<int> emitted;
   for (int i : cmReverseRange(this->FinalLinkOrder)) {
     LinkEntry const& e = this->EntryList[i];
     cmGeneratorTarget const* t = e.Target;
     // Entries that we know the linker will re-use do not need to be repeated.
     bool uniquify = t && t->GetType() == cmStateEnums::SHARED_LIBRARY;
-    if (!uniquify || emmitted.insert(i).second) {
+    if (!uniquify || emitted.insert(i).second) {
       this->FinalLinkEntries.push_back(e);
     }
   }
@@ -626,6 +626,7 @@
   // constraints disallow it.
   this->CCG =
     cm::make_unique<cmComputeComponentGraph>(this->EntryConstraintGraph);
+  this->CCG->Compute();
 
   // The component graph is guaranteed to be acyclic.  Start a DFS
   // from every entry to compute a topological order for the
diff --git a/Source/cmComputeLinkInformation.cxx b/Source/cmComputeLinkInformation.cxx
index 11570d6..43cceae 100644
--- a/Source/cmComputeLinkInformation.cxx
+++ b/Source/cmComputeLinkInformation.cxx
@@ -9,10 +9,9 @@
 #include <utility>
 
 #include <cm/memory>
+#include <cmext/algorithm>
 
-#include "cmAlgorithms.h"
 #include "cmComputeLinkDepends.h"
-#include "cmGeneratorExpression.h"
 #include "cmGeneratorTarget.h"
 #include "cmGlobalGenerator.h"
 #include "cmListFileCache.h"
@@ -22,6 +21,7 @@
 #include "cmOrderDirectories.h"
 #include "cmOutputConverter.h"
 #include "cmPolicies.h"
+#include "cmProperty.h"
 #include "cmState.h"
 #include "cmStateTypes.h"
 #include "cmStringAlgorithms.h"
@@ -514,7 +514,7 @@
 
   // Restore the target link type so the correct system runtime
   // libraries are found.
-  const char* lss = this->Target->GetProperty("LINK_SEARCH_END_STATIC");
+  cmProp lss = this->Target->GetProperty("LINK_SEARCH_END_STATIC");
   if (cmIsOn(lss)) {
     this->SetCurrentLinkType(LinkStatic);
   } else {
@@ -587,33 +587,18 @@
 }
 
 void cmComputeLinkInformation::AddRuntimeLinkLibrary(std::string const& lang)
-{ // Add the lang runtime library flags. This is activated by the presence
-  // of a default selection whether or not it is overridden by a property.
-  std::string defaultVar =
-    cmStrCat("CMAKE_", lang, "_RUNTIME_LIBRARY_DEFAULT");
-  const char* langRuntimeLibraryDefault =
-    this->Makefile->GetDefinition(defaultVar);
-  if (langRuntimeLibraryDefault && *langRuntimeLibraryDefault) {
-    const char* runtimeLibraryValue =
-      this->Target->GetProperty(cmStrCat(lang, "_RUNTIME_LIBRARY"));
-    if (!runtimeLibraryValue) {
-      runtimeLibraryValue = langRuntimeLibraryDefault;
-    }
-
-    std::string runtimeLibrary =
-      cmSystemTools::UpperCase(cmGeneratorExpression::Evaluate(
-        runtimeLibraryValue, this->Target->GetLocalGenerator(), this->Config,
-        this->Target));
-    if (!runtimeLibrary.empty()) {
-      if (const char* runtimeLinkOptions = this->Makefile->GetDefinition(
-            "CMAKE_" + lang + "_RUNTIME_LIBRARY_LINK_OPTIONS_" +
-            runtimeLibrary)) {
-        std::vector<std::string> libsVec = cmExpandedList(runtimeLinkOptions);
-        for (std::string const& i : libsVec) {
-          if (!cmContains(this->ImplicitLinkLibs, i)) {
-            this->AddItem(i, nullptr);
-          }
-        }
+{
+  std::string const& runtimeLibrary =
+    this->Target->GetRuntimeLinkLibrary(lang, this->Config);
+  if (runtimeLibrary.empty()) {
+    return;
+  }
+  if (const char* runtimeLinkOptions = this->Makefile->GetDefinition(
+        "CMAKE_" + lang + "_RUNTIME_LIBRARY_LINK_OPTIONS_" + runtimeLibrary)) {
+    std::vector<std::string> libsVec = cmExpandedList(runtimeLinkOptions);
+    for (std::string const& i : libsVec) {
+      if (!cm::contains(this->ImplicitLinkLibs, i)) {
+        this->AddItem(i, nullptr);
       }
     }
   }
@@ -627,7 +612,7 @@
   if (const char* libs = this->Makefile->GetDefinition(libVar)) {
     std::vector<std::string> libsVec = cmExpandedList(libs);
     for (std::string const& i : libsVec) {
-      if (!cmContains(this->ImplicitLinkLibs, i)) {
+      if (!cm::contains(this->ImplicitLinkLibs, i)) {
         this->AddItem(i, nullptr);
       }
     }
@@ -847,15 +832,14 @@
 
   // We can support link type switching only if all needed flags are
   // known.
-  if (static_link_type_flag && *static_link_type_flag &&
-      shared_link_type_flag && *shared_link_type_flag) {
+  if (cmNonempty(static_link_type_flag) && cmNonempty(shared_link_type_flag)) {
     this->LinkTypeEnabled = true;
     this->StaticLinkTypeFlag = static_link_type_flag;
     this->SharedLinkTypeFlag = shared_link_type_flag;
   }
 
   // Lookup the starting link type from the target (linked statically?).
-  const char* lss = this->Target->GetProperty("LINK_SEARCH_START_STATIC");
+  cmProp lss = this->Target->GetProperty("LINK_SEARCH_START_STATIC");
   this->StartLinkType = cmIsOn(lss) ? LinkStatic : LinkShared;
   this->CurrentLinkType = this->StartLinkType;
 }
@@ -864,31 +848,31 @@
 {
   // Get possible library name prefixes.
   cmMakefile* mf = this->Makefile;
-  this->AddLinkPrefix(mf->GetDefinition("CMAKE_STATIC_LIBRARY_PREFIX"));
-  this->AddLinkPrefix(mf->GetDefinition("CMAKE_SHARED_LIBRARY_PREFIX"));
+  this->AddLinkPrefix(mf->GetSafeDefinition("CMAKE_STATIC_LIBRARY_PREFIX"));
+  this->AddLinkPrefix(mf->GetSafeDefinition("CMAKE_SHARED_LIBRARY_PREFIX"));
 
   // Import library names should be matched and treated as shared
   // libraries for the purposes of linking.
-  this->AddLinkExtension(mf->GetDefinition("CMAKE_IMPORT_LIBRARY_SUFFIX"),
+  this->AddLinkExtension(mf->GetSafeDefinition("CMAKE_IMPORT_LIBRARY_SUFFIX"),
                          LinkShared);
-  this->AddLinkExtension(mf->GetDefinition("CMAKE_STATIC_LIBRARY_SUFFIX"),
+  this->AddLinkExtension(mf->GetSafeDefinition("CMAKE_STATIC_LIBRARY_SUFFIX"),
                          LinkStatic);
-  this->AddLinkExtension(mf->GetDefinition("CMAKE_SHARED_LIBRARY_SUFFIX"),
+  this->AddLinkExtension(mf->GetSafeDefinition("CMAKE_SHARED_LIBRARY_SUFFIX"),
                          LinkShared);
-  this->AddLinkExtension(mf->GetDefinition("CMAKE_LINK_LIBRARY_SUFFIX"),
+  this->AddLinkExtension(mf->GetSafeDefinition("CMAKE_LINK_LIBRARY_SUFFIX"),
                          LinkUnknown);
   if (const char* linkSuffixes =
         mf->GetDefinition("CMAKE_EXTRA_LINK_EXTENSIONS")) {
     std::vector<std::string> linkSuffixVec = cmExpandedList(linkSuffixes);
     for (std::string const& i : linkSuffixVec) {
-      this->AddLinkExtension(i.c_str(), LinkUnknown);
+      this->AddLinkExtension(i, LinkUnknown);
     }
   }
   if (const char* sharedSuffixes =
         mf->GetDefinition("CMAKE_EXTRA_SHARED_LIBRARY_SUFFIXES")) {
     std::vector<std::string> sharedSuffixVec = cmExpandedList(sharedSuffixes);
     for (std::string const& i : sharedSuffixVec) {
-      this->AddLinkExtension(i.c_str(), LinkShared);
+      this->AddLinkExtension(i, LinkShared);
     }
   }
 
@@ -918,7 +902,7 @@
 #ifdef CM_COMPUTE_LINK_INFO_DEBUG
   fprintf(stderr, "any regex [%s]\n", reg_any.c_str());
 #endif
-  this->ExtractAnyLibraryName.compile(reg_any.c_str());
+  this->ExtractAnyLibraryName.compile(reg_any);
 
   // Create a regex to match static library names.
   if (!this->StaticLinkExtensions.empty()) {
@@ -927,7 +911,7 @@
 #ifdef CM_COMPUTE_LINK_INFO_DEBUG
     fprintf(stderr, "static regex [%s]\n", reg_static.c_str());
 #endif
-    this->ExtractStaticLibraryName.compile(reg_static.c_str());
+    this->ExtractStaticLibraryName.compile(reg_static);
   }
 
   // Create a regex to match shared library names.
@@ -939,20 +923,21 @@
 #ifdef CM_COMPUTE_LINK_INFO_DEBUG
     fprintf(stderr, "shared regex [%s]\n", reg_shared.c_str());
 #endif
-    this->ExtractSharedLibraryName.compile(reg_shared.c_str());
+    this->ExtractSharedLibraryName.compile(reg_shared);
   }
 }
 
-void cmComputeLinkInformation::AddLinkPrefix(const char* p)
+void cmComputeLinkInformation::AddLinkPrefix(std::string const& p)
 {
-  if (p && *p) {
+  if (!p.empty()) {
     this->LinkPrefixes.insert(p);
   }
 }
 
-void cmComputeLinkInformation::AddLinkExtension(const char* e, LinkType type)
+void cmComputeLinkInformation::AddLinkExtension(std::string const& e,
+                                                LinkType type)
 {
-  if (e && *e) {
+  if (!e.empty()) {
     if (type == LinkStatic) {
       this->StaticLinkExtensions.emplace_back(e);
     }
@@ -977,7 +962,7 @@
     // Store this extension choice with the "." escaped.
     libext += "\\";
 #if defined(_WIN32) && !defined(__CYGWIN__)
-    libext += this->NoCaseExpression(i.c_str());
+    libext += this->NoCaseExpression(i);
 #else
     libext += i;
 #endif
@@ -995,20 +980,19 @@
   return libext;
 }
 
-std::string cmComputeLinkInformation::NoCaseExpression(const char* str)
+std::string cmComputeLinkInformation::NoCaseExpression(std::string const& str)
 {
   std::string ret;
-  const char* s = str;
-  while (*s) {
-    if (*s == '.') {
-      ret += *s;
+  ret.reserve(str.size() * 4);
+  for (char c : str) {
+    if (c == '.') {
+      ret += c;
     } else {
-      ret += "[";
-      ret += static_cast<char>(tolower(*s));
-      ret += static_cast<char>(toupper(*s));
-      ret += "]";
+      ret += '[';
+      ret += static_cast<char>(tolower(c));
+      ret += static_cast<char>(toupper(c));
+      ret += ']';
     }
-    s++;
   }
   return ret;
 }
@@ -1063,8 +1047,8 @@
   // For compatibility with CMake 2.4 include the item's directory in
   // the linker search path.
   if (this->OldLinkDirMode && !target->IsFrameworkOnApple() &&
-      !cmContains(this->OldLinkDirMask,
-                  cmSystemTools::GetFilenamePath(item.Value))) {
+      !cm::contains(this->OldLinkDirMask,
+                    cmSystemTools::GetFilenamePath(item.Value))) {
     this->OldLinkDirItems.push_back(item.Value);
   }
 
@@ -1117,8 +1101,8 @@
   // For compatibility with CMake 2.4 include the item's directory in
   // the linker search path.
   if (this->OldLinkDirMode &&
-      !cmContains(this->OldLinkDirMask,
-                  cmSystemTools::GetFilenamePath(item.Value))) {
+      !cm::contains(this->OldLinkDirMask,
+                    cmSystemTools::GetFilenamePath(item.Value))) {
     this->OldLinkDirItems.push_back(item.Value);
   }
 
@@ -1137,7 +1121,7 @@
 
   // Check if this item is in an implicit link directory.
   std::string dir = cmSystemTools::GetFilenamePath(item);
-  if (!cmContains(this->ImplicitLinkDirs, dir)) {
+  if (!cm::contains(this->ImplicitLinkDirs, dir)) {
     // Only libraries in implicit link directories are converted to
     // pathless items.
     return false;
@@ -1200,7 +1184,8 @@
     // CMP0003 so put it in OldUserFlagItems, if it is not a -l
     // or -Wl,-l (-framework -pthread), then allow it without a
     // CMP0003 as -L will not affect those other linker flags
-    if (item.Value.find("-l") == 0 || item.Value.find("-Wl,-l") == 0) {
+    if (cmHasLiteralPrefix(item.Value, "-l") ||
+        cmHasLiteralPrefix(item.Value, "-Wl,-l")) {
       // This is a linker option provided by the user.
       this->OldUserFlagItems.push_back(item.Value);
     }
@@ -1344,18 +1329,13 @@
   std::vector<std::string> implicitDirVec;
 
   // Get platform-wide implicit directories.
-  if (const char* implicitLinks = this->Makefile->GetDefinition(
-        "CMAKE_PLATFORM_IMPLICIT_LINK_FRAMEWORK_DIRECTORIES")) {
-    cmExpandList(implicitLinks, implicitDirVec);
-  }
+  this->Makefile->GetDefExpandList(
+    "CMAKE_PLATFORM_IMPLICIT_LINK_FRAMEWORK_DIRECTORIES", implicitDirVec);
 
   // Get language-specific implicit directories.
   std::string implicitDirVar = cmStrCat(
     "CMAKE_", this->LinkLanguage, "_IMPLICIT_LINK_FRAMEWORK_DIRECTORIES");
-  if (const char* implicitDirs =
-        this->Makefile->GetDefinition(implicitDirVar)) {
-    cmExpandList(implicitDirs, implicitDirVec);
-  }
+  this->Makefile->GetDefExpandList(implicitDirVar, implicitDirVec);
 
   this->FrameworkPathsEmmitted.insert(implicitDirVec.begin(),
                                       implicitDirVec.end());
@@ -1439,7 +1419,6 @@
     }
     case cmPolicies::OLD:
       // OLD behavior does not warn.
-      break;
     case cmPolicies::NEW:
       // NEW behavior will not get here.
       break;
@@ -1569,10 +1548,8 @@
   std::vector<std::string> implicitDirVec;
 
   // Get platform-wide implicit directories.
-  if (const char* implicitLinks = (this->Makefile->GetDefinition(
-        "CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES"))) {
-    cmExpandList(implicitLinks, implicitDirVec);
-  }
+  this->Makefile->GetDefExpandList("CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES",
+                                   implicitDirVec);
 
   // Append library architecture to all implicit platform directories
   // and add them to the set
@@ -1586,10 +1563,7 @@
   // Get language-specific implicit directories.
   std::string implicitDirVar =
     cmStrCat("CMAKE_", this->LinkLanguage, "_IMPLICIT_LINK_DIRECTORIES");
-  if (const char* implicitDirs =
-        this->Makefile->GetDefinition(implicitDirVar)) {
-    cmExpandList(implicitDirs, implicitDirVec);
-  }
+  this->Makefile->GetDefExpandList(implicitDirVar, implicitDirVec);
 
   // Store implicit link directories.
   this->ImplicitLinkDirs.insert(implicitDirVec.begin(), implicitDirVec.end());
@@ -1598,10 +1572,7 @@
   std::vector<std::string> implicitLibVec;
   std::string implicitLibVar =
     cmStrCat("CMAKE_", this->LinkLanguage, "_IMPLICIT_LINK_LIBRARIES");
-  if (const char* implicitLibs =
-        this->Makefile->GetDefinition(implicitLibVar)) {
-    cmExpandList(implicitLibs, implicitLibVec);
-  }
+  this->Makefile->GetDefExpandList(implicitLibVar, implicitLibVec);
 
   // Store implicit link libraries.
   for (std::string const& item : implicitLibVec) {
@@ -1613,10 +1584,8 @@
   }
 
   // Get platform specific rpath link directories
-  if (const char* rpathDirs =
-        (this->Makefile->GetDefinition("CMAKE_PLATFORM_RUNTIME_PATH"))) {
-    cmExpandList(rpathDirs, this->RuntimeLinkDirs);
-  }
+  this->Makefile->GetDefExpandList("CMAKE_PLATFORM_RUNTIME_PATH",
+                                   this->RuntimeLinkDirs);
 }
 
 std::vector<std::string> const&
@@ -1717,7 +1686,7 @@
   }
 }
 
-static void cmCLI_ExpandListUnique(const char* str,
+static void cmCLI_ExpandListUnique(std::string const& str,
                                    std::vector<std::string>& out,
                                    std::set<std::string>& emitted)
 {
@@ -1764,7 +1733,7 @@
   if (use_install_rpath) {
     std::string install_rpath;
     this->Target->GetInstallRPATH(this->Config, install_rpath);
-    cmCLI_ExpandListUnique(install_rpath.c_str(), runtimeDirs, emitted);
+    cmCLI_ExpandListUnique(install_rpath, runtimeDirs, emitted);
   }
   if (use_build_rpath) {
     // Add directories explicitly specified by user
@@ -1772,7 +1741,7 @@
     if (this->Target->GetBuildRPATH(this->Config, build_rpath)) {
       // This will not resolve entries to use $ORIGIN, the user is expected to
       // do that if necessary.
-      cmCLI_ExpandListUnique(build_rpath.c_str(), runtimeDirs, emitted);
+      cmCLI_ExpandListUnique(build_rpath, runtimeDirs, emitted);
     }
   }
   if (use_build_rpath || use_link_rpath) {
@@ -1796,11 +1765,11 @@
       // support or if using the link path as an rpath.
       if (use_build_rpath) {
         std::string d = ri;
-        if (!rootPath.empty() && d.find(rootPath) == 0) {
-          d = d.substr(rootPath.size());
-        } else if (stagePath && *stagePath && d.find(stagePath) == 0) {
-          std::string suffix = d.substr(strlen(stagePath));
-          d = cmStrCat(installPrefix, '/', suffix);
+        if (!rootPath.empty() && cmHasPrefix(d, rootPath)) {
+          d.erase(0, rootPath.size());
+        } else if (cmNonempty(stagePath) && cmHasPrefix(d, stagePath)) {
+          d.erase(0, strlen(stagePath));
+          d = cmStrCat(installPrefix, '/', d);
           cmSystemTools::ConvertToUnixSlashes(d);
         } else if (use_relative_build_rpath) {
           // If expansion of the $ORIGIN token is supported and permitted per
@@ -1827,11 +1796,11 @@
             !cmSystemTools::IsSubDirectory(ri, topSourceDir) &&
             !cmSystemTools::IsSubDirectory(ri, topBinaryDir)) {
           std::string d = ri;
-          if (!rootPath.empty() && d.find(rootPath) == 0) {
-            d = d.substr(rootPath.size());
-          } else if (stagePath && *stagePath && d.find(stagePath) == 0) {
-            std::string suffix = d.substr(strlen(stagePath));
-            d = cmStrCat(installPrefix, '/', suffix);
+          if (!rootPath.empty() && cmHasPrefix(d, rootPath)) {
+            d.erase(0, rootPath.size());
+          } else if (cmNonempty(stagePath) && cmHasPrefix(d, stagePath)) {
+            d.erase(0, strlen(stagePath));
+            d = cmStrCat(installPrefix, '/', d);
             cmSystemTools::ConvertToUnixSlashes(d);
           }
           if (emitted.insert(d).second) {
@@ -1852,8 +1821,8 @@
         "CMAKE_" + li + "_USE_IMPLICIT_LINK_DIRECTORIES_IN_RUNTIME_PATH";
       if (this->Makefile->IsOn(useVar)) {
         std::string dirVar = "CMAKE_" + li + "_IMPLICIT_LINK_DIRECTORIES";
-        if (const char* dirs = this->Makefile->GetDefinition(dirVar)) {
-          cmCLI_ExpandListUnique(dirs, runtimeDirs, emitted);
+        if (cmProp dirs = this->Makefile->GetDef(dirVar)) {
+          cmCLI_ExpandListUnique(*dirs, runtimeDirs, emitted);
         }
       }
     }
@@ -1861,7 +1830,7 @@
 
   // Add runtime paths required by the platform to always be
   // present.  This is done even when skipping rpath support.
-  cmCLI_ExpandListUnique(this->RuntimeAlways.c_str(), runtimeDirs, emitted);
+  cmCLI_ExpandListUnique(this->RuntimeAlways, runtimeDirs, emitted);
 }
 
 std::string cmComputeLinkInformation::GetRPathString(bool for_install) const
diff --git a/Source/cmComputeLinkInformation.h b/Source/cmComputeLinkInformation.h
index e50d369..544ff23 100644
--- a/Source/cmComputeLinkInformation.h
+++ b/Source/cmComputeLinkInformation.h
@@ -144,11 +144,11 @@
   cmsys::RegularExpression ExtractSharedLibraryName;
   cmsys::RegularExpression ExtractAnyLibraryName;
   std::string SharedRegexString;
-  void AddLinkPrefix(const char* p);
-  void AddLinkExtension(const char* e, LinkType type);
+  void AddLinkPrefix(std::string const& p);
+  void AddLinkExtension(std::string const& e, LinkType type);
   std::string CreateExtensionRegex(std::vector<std::string> const& exts,
                                    LinkType type);
-  std::string NoCaseExpression(const char* str);
+  std::string NoCaseExpression(std::string const& str);
 
   // Handling of link items.
   void AddTargetItem(BT<std::string> const& item,
diff --git a/Source/cmComputeTargetDepends.cxx b/Source/cmComputeTargetDepends.cxx
index a98a608..e717f71 100644
--- a/Source/cmComputeTargetDepends.cxx
+++ b/Source/cmComputeTargetDepends.cxx
@@ -118,6 +118,7 @@
 
   // Identify components.
   cmComputeComponentGraph ccg(this->InitialGraph);
+  ccg.Compute();
   if (this->DebugMode) {
     this->DisplayComponents(ccg);
   }
@@ -184,7 +185,7 @@
 {
   // Get the depender.
   cmGeneratorTarget const* depender = this->Targets[depender_index];
-  if (depender->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
+  if (!depender->IsInBuildSystem()) {
     return;
   }
 
@@ -196,8 +197,24 @@
     std::set<cmLinkItem> emitted;
 
     std::vector<std::string> const& configs =
-      depender->Makefile->GetGeneratorConfigs();
+      depender->Makefile->GetGeneratorConfigs(cmMakefile::IncludeEmptyConfig);
     for (std::string const& it : configs) {
+      // A target should not depend on itself.
+      emitted.insert(cmLinkItem(depender, false, cmListFileBacktrace()));
+      emitted.insert(cmLinkItem(depender, true, cmListFileBacktrace()));
+
+      if (cmLinkImplementation const* impl =
+            depender->GetLinkImplementation(it)) {
+        for (cmLinkImplItem const& lib : impl->Libraries) {
+          // Don't emit the same library twice for this target.
+          if (emitted.insert(lib).second) {
+            this->AddTargetDepend(depender_index, lib, true, false);
+            this->AddInterfaceDepends(depender_index, lib, it, emitted);
+          }
+        }
+      }
+
+      // Add dependencies on object libraries not otherwise handled above.
       std::vector<cmSourceFile const*> objectFiles;
       depender->GetExternalObjects(objectFiles, it);
       for (cmSourceFile const* o : objectFiles) {
@@ -222,19 +239,6 @@
           }
         }
       }
-
-      cmLinkImplementation const* impl = depender->GetLinkImplementation(it);
-
-      // A target should not depend on itself.
-      emitted.insert(cmLinkItem(depender, false, cmListFileBacktrace()));
-      emitted.insert(cmLinkItem(depender, true, cmListFileBacktrace()));
-      for (cmLinkImplItem const& lib : impl->Libraries) {
-        // Don't emit the same library twice for this target.
-        if (emitted.insert(lib).second) {
-          this->AddTargetDepend(depender_index, lib, true, false);
-          this->AddInterfaceDepends(depender_index, lib, it, emitted);
-        }
-      }
     }
   }
 
@@ -355,10 +359,9 @@
   int depender_index, cmGeneratorTarget const* dependee,
   cmListFileBacktrace const& dependee_backtrace, bool linking, bool cross)
 {
-  if (dependee->IsImported() ||
-      dependee->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
-    // Skip IMPORTED and INTERFACE targets but follow their utility
-    // dependencies.
+  if (!dependee->IsInBuildSystem()) {
+    // Skip targets that are not in the buildsystem but follow their
+    // utility dependencies.
     std::set<cmLinkItem> const& utils = dependee->GetUtilityItems();
     for (cmLinkItem const& i : utils) {
       if (cmGeneratorTarget const* transitive_dependee = i.Target) {
diff --git a/Source/cmConditionEvaluator.cxx b/Source/cmConditionEvaluator.cxx
index fda687f..7a3a3e8 100644
--- a/Source/cmConditionEvaluator.cxx
+++ b/Source/cmConditionEvaluator.cxx
@@ -13,7 +13,6 @@
 
 #include "cmsys/RegularExpression.hxx"
 
-#include "cmAlgorithms.h"
 #include "cmMakefile.h"
 #include "cmMessageType.h"
 #include "cmState.h"
@@ -494,12 +493,12 @@
       if (this->IsKeyword(keyDEFINED, *arg) && argP1 != newArgs.end()) {
         size_t argP1len = argP1->GetValue().size();
         bool bdef = false;
-        if (argP1len > 4 && argP1->GetValue().substr(0, 4) == "ENV{" &&
+        if (argP1len > 4 && cmHasLiteralPrefix(argP1->GetValue(), "ENV{") &&
             argP1->GetValue().operator[](argP1len - 1) == '}') {
           std::string env = argP1->GetValue().substr(4, argP1len - 5);
           bdef = cmSystemTools::HasEnv(env);
         } else if (argP1len > 6 &&
-                   argP1->GetValue().substr(0, 6) == "CACHE{" &&
+                   cmHasLiteralPrefix(argP1->GetValue(), "CACHE{") &&
                    argP1->GetValue().operator[](argP1len - 1) == '}') {
           std::string cache = argP1->GetValue().substr(6, argP1len - 7);
           bdef =
@@ -673,7 +672,7 @@
           if (def2) {
             std::vector<std::string> list = cmExpandedList(def2, true);
 
-            result = cmContains(list, def);
+            result = cm::contains(list, def);
           }
 
           this->HandleBinaryOp(result, reducible, arg, newArgs, argP1, argP2);
diff --git a/Source/cmConfigure.cmake.h.in b/Source/cmConfigure.cmake.h.in
index 4de1c5d..97e7856 100644
--- a/Source/cmConfigure.cmake.h.in
+++ b/Source/cmConfigure.cmake.h.in
@@ -19,7 +19,6 @@
 #cmakedefine HAVE_UNSETENV
 #cmakedefine CMAKE_USE_ELF_PARSER
 #cmakedefine CMAKE_USE_MACH_PARSER
-#cmakedefine CMake_HAVE_CXX_MAKE_UNIQUE
 #define CMake_DEFAULT_RECURSION_LIMIT @CMake_DEFAULT_RECURSION_LIMIT@
 #define CMAKE_BIN_DIR "/@CMAKE_BIN_DIR@"
 #define CMAKE_DATA_DIR "/@CMAKE_DATA_DIR@"
diff --git a/Source/cmConfigureFileCommand.cxx b/Source/cmConfigureFileCommand.cxx
index 8767386..68322cc 100644
--- a/Source/cmConfigureFileCommand.cxx
+++ b/Source/cmConfigureFileCommand.cxx
@@ -2,6 +2,11 @@
    file Copyright.txt or https://cmake.org/licensing for details.  */
 #include "cmConfigureFileCommand.h"
 
+#include <set>
+
+#include <cm/string_view>
+#include <cmext/string_view>
+
 #include "cmExecutionStatus.h"
 #include "cmMakefile.h"
 #include "cmMessageType.h"
@@ -55,6 +60,19 @@
   }
   bool copyOnly = false;
   bool escapeQuotes = false;
+  bool use_source_permissions = true;
+
+  static std::set<cm::string_view> noopOptions = {
+    /* Legacy.  */
+    "IMMEDIATE"_s,
+    /* Handled by NewLineStyle member.  */
+    "NEWLINE_STYLE"_s,
+    "LF"_s,
+    "UNIX"_s,
+    "CRLF"_s,
+    "WIN32"_s,
+    "DOS"_s,
+  };
 
   std::string unknown_args;
   bool atOnly = false;
@@ -70,12 +88,10 @@
       escapeQuotes = true;
     } else if (args[i] == "@ONLY") {
       atOnly = true;
-    } else if (args[i] == "IMMEDIATE") {
-      /* Ignore legacy option.  */
-    } else if (args[i] == "NEWLINE_STYLE" || args[i] == "LF" ||
-               args[i] == "UNIX" || args[i] == "CRLF" || args[i] == "WIN32" ||
-               args[i] == "DOS") {
-      /* Options handled by NewLineStyle member above.  */
+    } else if (args[i] == "NO_SOURCE_PERMISSIONS") {
+      use_source_permissions = false;
+    } else if (noopOptions.find(args[i]) != noopOptions.end()) {
+      /* Ignore no-op options.  */
     } else {
       unknown_args += " ";
       unknown_args += args[i];
@@ -89,7 +105,8 @@
   }
 
   if (!status.GetMakefile().ConfigureFile(
-        inputFile, outputFile, copyOnly, atOnly, escapeQuotes, newLineStyle)) {
+        inputFile, outputFile, copyOnly, atOnly, escapeQuotes,
+        use_source_permissions, newLineStyle)) {
     status.SetError("Problem configuring file");
     return false;
   }
diff --git a/Source/cmConnection.cxx b/Source/cmConnection.cxx
index 884e314..e4d0cf1 100644
--- a/Source/cmConnection.cxx
+++ b/Source/cmConnection.cxx
@@ -5,7 +5,7 @@
 #include <cassert>
 #include <cstring>
 
-#include "cm_uv.h"
+#include <cm3p/uv.h>
 
 #include "cmServer.h"
 
@@ -20,8 +20,13 @@
                                              uv_buf_t* buf)
 {
   (void)(handle);
+#ifndef __clang_analyzer__
   char* rawBuffer = new char[suggested_size];
   *buf = uv_buf_init(rawBuffer, static_cast<unsigned int>(suggested_size));
+#else
+  (void)(suggested_size);
+  (void)(buf);
+#endif /* __clang_analyzer__ */
 }
 
 void cmEventBasedConnection::on_read(uv_stream_t* stream, ssize_t nread,
@@ -76,6 +81,7 @@
   assert(uv_thread_equal(&curr_thread_id, &this->Server->ServeThreadId));
 #endif
 
+#ifndef __clang_analyzer__
   auto data = _data;
   assert(this->WriteStream.get());
   if (BufferStrategy) {
@@ -90,6 +96,9 @@
   memcpy(req->buf.base, data.c_str(), ds);
   uv_write(reinterpret_cast<uv_write_t*>(req), this->WriteStream, &req->buf, 1,
            on_write);
+#else
+  (void)(_data);
+#endif /* __clang_analyzer__ */
 }
 
 void cmEventBasedConnection::ReadData(const std::string& data)
diff --git a/Source/cmConnection.h b/Source/cmConnection.h
index 7bb2494..5335a7f 100644
--- a/Source/cmConnection.h
+++ b/Source/cmConnection.h
@@ -9,7 +9,7 @@
 #include <memory>
 #include <string>
 
-#include "cm_uv.h"
+#include <cm3p/uv.h>
 
 #include "cmUVHandlePtr.h"
 
diff --git a/Source/cmConvertMSBuildXMLToJSON.py b/Source/cmConvertMSBuildXMLToJSON.py
index 02074ba..2be3781 100644
--- a/Source/cmConvertMSBuildXMLToJSON.py
+++ b/Source/cmConvertMSBuildXMLToJSON.py
@@ -35,12 +35,14 @@
     return values
 
 
-def read_msbuild_xml(path, values={}):
+def read_msbuild_xml(path, values=None):
     """Reads the MS Build XML file at the path and returns its contents.
 
     Keyword arguments:
     values -- The map to append the contents to (default {})
     """
+    if values is None:
+        values = {}
 
     # Attempt to read the file contents
     try:
@@ -76,12 +78,15 @@
     return values
 
 
-def read_msbuild_json(path, values=[]):
+def read_msbuild_json(path, values=None):
     """Reads the MS Build JSON file at the path and returns its contents.
 
     Keyword arguments:
     values -- The list to append the contents to (default [])
     """
+    if values is None:
+        values = []
+
     if not os.path.exists(path):
         logging.info('Could not find MS Build JSON file at %s', path)
         return values
diff --git a/Source/cmCoreTryCompile.cxx b/Source/cmCoreTryCompile.cxx
index 73f099b..63c1484 100644
--- a/Source/cmCoreTryCompile.cxx
+++ b/Source/cmCoreTryCompile.cxx
@@ -8,9 +8,9 @@
 #include <sstream>
 #include <utility>
 
-#include "cmsys/Directory.hxx"
+#include <cmext/string_view>
 
-#include "cm_static_string_view.hxx"
+#include "cmsys/Directory.hxx"
 
 #include "cmExportTryCompileFileGenerator.h"
 #include "cmGlobalGenerator.h"
@@ -18,6 +18,7 @@
 #include "cmMessageType.h"
 #include "cmOutputConverter.h"
 #include "cmPolicies.h"
+#include "cmProperty.h"
 #include "cmState.h"
 #include "cmStringAlgorithms.h"
 #include "cmSystemTools.h"
@@ -25,73 +26,205 @@
 #include "cmVersion.h"
 #include "cmake.h"
 
-static std::string const kCMAKE_C_COMPILER_EXTERNAL_TOOLCHAIN =
-  "CMAKE_C_COMPILER_EXTERNAL_TOOLCHAIN";
-static std::string const kCMAKE_C_COMPILER_TARGET = "CMAKE_C_COMPILER_TARGET";
-static std::string const kCMAKE_C_LINK_NO_PIE_SUPPORTED =
-  "CMAKE_C_LINK_NO_PIE_SUPPORTED";
-static std::string const kCMAKE_C_LINK_PIE_SUPPORTED =
-  "CMAKE_C_LINK_PIE_SUPPORTED";
-static std::string const kCMAKE_CXX_COMPILER_EXTERNAL_TOOLCHAIN =
-  "CMAKE_CXX_COMPILER_EXTERNAL_TOOLCHAIN";
-static std::string const kCMAKE_CXX_COMPILER_TARGET =
-  "CMAKE_CXX_COMPILER_TARGET";
-static std::string const kCMAKE_CXX_LINK_NO_PIE_SUPPORTED =
-  "CMAKE_CXX_LINK_NO_PIE_SUPPORTED";
-static std::string const kCMAKE_CXX_LINK_PIE_SUPPORTED =
-  "CMAKE_CXX_LINK_PIE_SUPPORTED";
-static std::string const kCMAKE_CUDA_RUNTIME_LIBRARY =
-  "CMAKE_CUDA_RUNTIME_LIBRARY";
-static std::string const kCMAKE_ENABLE_EXPORTS = "CMAKE_ENABLE_EXPORTS";
-static std::string const kCMAKE_LINK_SEARCH_END_STATIC =
+namespace {
+class LanguageStandardState
+{
+public:
+  LanguageStandardState(std::string&& lang)
+    : IsEnabled(false)
+    , DidStandard(false)
+    , DidStandardRequired(false)
+    , DidExtensions(false)
+    , StandardFlag(lang + "_STANDARD")
+    , RequiredFlag(lang + "_STANDARD_REQUIRED")
+    , ExtensionFlag(lang + "_EXTENSIONS")
+  {
+  }
+
+  void Enabled(bool isEnabled) { this->IsEnabled = isEnabled; }
+
+  bool UpdateIfMatches(std::vector<std::string> const& argv, size_t& index)
+  {
+    bool updated = false;
+    if (argv[index] == this->StandardFlag) {
+      this->DidStandard = true;
+      this->StandardValue = argv[++index];
+      updated = true;
+    } else if (argv[index] == this->RequiredFlag) {
+      this->DidStandardRequired = true;
+      this->RequiredValue = argv[++index];
+      updated = true;
+    } else if (argv[index] == this->ExtensionFlag) {
+      this->DidExtensions = true;
+      this->ExtensionValue = argv[++index];
+      updated = true;
+    }
+    return updated;
+  }
+
+  bool Validate(cmMakefile* const makefile) const
+  {
+    if (this->DidStandard) {
+      makefile->IssueMessage(
+        MessageType::FATAL_ERROR,
+        cmStrCat(this->StandardFlag,
+                 " allowed only in source file signature."));
+      return false;
+    }
+    if (this->DidStandardRequired) {
+      makefile->IssueMessage(
+        MessageType::FATAL_ERROR,
+        cmStrCat(this->RequiredFlag,
+                 " allowed only in source file signature."));
+      return false;
+    }
+    if (this->DidExtensions) {
+      makefile->IssueMessage(
+        MessageType::FATAL_ERROR,
+        cmStrCat(this->ExtensionFlag,
+                 " allowed only in source file signature."));
+      return false;
+    }
+
+    return true;
+  }
+
+  bool DidNone() const
+  {
+    return !this->DidStandard && !this->DidStandardRequired &&
+      !this->DidExtensions;
+  }
+
+  void LoadUnsetPropertyValues(cmMakefile* const makefile, bool honorStandard,
+                               bool warnCMP0067,
+                               std::vector<std::string>& warnCMP0067Variables)
+  {
+    if (!this->IsEnabled) {
+      return;
+    }
+
+    auto lookupStdVar = [&](std::string const& var) -> std::string {
+      std::string value = makefile->GetSafeDefinition(var);
+      if (warnCMP0067 && !value.empty()) {
+        value.clear();
+        warnCMP0067Variables.push_back(var);
+      }
+      return value;
+    };
+
+    if (honorStandard || warnCMP0067) {
+      if (!this->DidStandard) {
+        this->StandardValue =
+          lookupStdVar(cmStrCat("CMAKE_", this->StandardFlag));
+      }
+      if (!this->DidStandardRequired) {
+        this->RequiredValue =
+          lookupStdVar(cmStrCat("CMAKE_", this->RequiredFlag));
+      }
+      if (!this->DidExtensions) {
+        this->ExtensionValue =
+          lookupStdVar(cmStrCat("CMAKE_", this->ExtensionFlag));
+      }
+    }
+  }
+
+  void WriteProperties(FILE* fout, std::string const& targetName) const
+  {
+    if (!this->IsEnabled) {
+      return;
+    }
+
+    auto writeProp = [&](std::string const& prop, std::string const& value) {
+      fprintf(fout, "set_property(TARGET %s PROPERTY %s %s)\n",
+              targetName.c_str(),
+              cmOutputConverter::EscapeForCMake(prop).c_str(),
+              cmOutputConverter::EscapeForCMake(value).c_str());
+    };
+
+    if (!this->StandardValue.empty()) {
+      writeProp(this->StandardFlag, this->StandardValue);
+    }
+    if (!this->RequiredValue.empty()) {
+      writeProp(this->RequiredFlag, this->RequiredValue);
+    }
+    if (!this->ExtensionValue.empty()) {
+      writeProp(this->ExtensionFlag, this->ExtensionValue);
+    }
+  }
+
+private:
+  bool IsEnabled;
+  bool DidStandard;
+  bool DidStandardRequired;
+  bool DidExtensions;
+
+  std::string StandardFlag;
+  std::string RequiredFlag;
+  std::string ExtensionFlag;
+
+  std::string StandardValue;
+  std::string RequiredValue;
+  std::string ExtensionValue;
+};
+
+constexpr size_t lang_property_start = 0;
+constexpr size_t lang_property_size = 4;
+constexpr size_t pie_property_start = 4;
+constexpr size_t pie_property_size = 2;
+#define SETUP_LANGUAGE(name, lang)                                            \
+  static const std::string name[lang_property_size + pie_property_size + 1] = \
+    { "CMAKE_" #lang "_COMPILER_EXTERNAL_TOOLCHAIN",                          \
+      "CMAKE_" #lang "_COMPILER_TARGET",                                      \
+      "CMAKE_" #lang "_LINK_NO_PIE_SUPPORTED",                                \
+      "CMAKE_" #lang "_PIE_SUPPORTED", "" }
+
+// NOLINTNEXTLINE(bugprone-suspicious-missing-comma)
+SETUP_LANGUAGE(c_properties, C);
+// NOLINTNEXTLINE(bugprone-suspicious-missing-comma)
+SETUP_LANGUAGE(cxx_properties, CXX);
+
+// NOLINTNEXTLINE(bugprone-suspicious-missing-comma)
+SETUP_LANGUAGE(cuda_properties, CUDA);
+// NOLINTNEXTLINE(bugprone-suspicious-missing-comma)
+SETUP_LANGUAGE(fortran_properties, Fortran);
+// NOLINTNEXTLINE(bugprone-suspicious-missing-comma)
+SETUP_LANGUAGE(objc_properties, OBJC);
+// NOLINTNEXTLINE(bugprone-suspicious-missing-comma)
+SETUP_LANGUAGE(objcxx_properties, OBJCXX);
+// NOLINTNEXTLINE(bugprone-suspicious-missing-comma)
+SETUP_LANGUAGE(swift_properties, Swift);
+#undef SETUP_LANGUAGE
+
+std::string const kCMAKE_CUDA_ARCHITECTURES = "CMAKE_CUDA_ARCHITECTURES";
+std::string const kCMAKE_CUDA_RUNTIME_LIBRARY = "CMAKE_CUDA_RUNTIME_LIBRARY";
+std::string const kCMAKE_ENABLE_EXPORTS = "CMAKE_ENABLE_EXPORTS";
+std::string const kCMAKE_LINK_SEARCH_END_STATIC =
   "CMAKE_LINK_SEARCH_END_STATIC";
-static std::string const kCMAKE_LINK_SEARCH_START_STATIC =
+std::string const kCMAKE_LINK_SEARCH_START_STATIC =
   "CMAKE_LINK_SEARCH_START_STATIC";
-static std::string const kCMAKE_MSVC_RUNTIME_LIBRARY_DEFAULT =
+std::string const kCMAKE_MSVC_RUNTIME_LIBRARY_DEFAULT =
   "CMAKE_MSVC_RUNTIME_LIBRARY_DEFAULT";
-static std::string const kCMAKE_OSX_ARCHITECTURES = "CMAKE_OSX_ARCHITECTURES";
-static std::string const kCMAKE_OSX_DEPLOYMENT_TARGET =
-  "CMAKE_OSX_DEPLOYMENT_TARGET";
-static std::string const kCMAKE_OSX_SYSROOT = "CMAKE_OSX_SYSROOT";
-static std::string const kCMAKE_APPLE_ARCH_SYSROOTS =
-  "CMAKE_APPLE_ARCH_SYSROOTS";
-static std::string const kCMAKE_POSITION_INDEPENDENT_CODE =
+std::string const kCMAKE_OSX_ARCHITECTURES = "CMAKE_OSX_ARCHITECTURES";
+std::string const kCMAKE_OSX_DEPLOYMENT_TARGET = "CMAKE_OSX_DEPLOYMENT_TARGET";
+std::string const kCMAKE_OSX_SYSROOT = "CMAKE_OSX_SYSROOT";
+std::string const kCMAKE_APPLE_ARCH_SYSROOTS = "CMAKE_APPLE_ARCH_SYSROOTS";
+std::string const kCMAKE_POSITION_INDEPENDENT_CODE =
   "CMAKE_POSITION_INDEPENDENT_CODE";
-static std::string const kCMAKE_SYSROOT = "CMAKE_SYSROOT";
-static std::string const kCMAKE_SYSROOT_COMPILE = "CMAKE_SYSROOT_COMPILE";
-static std::string const kCMAKE_SYSROOT_LINK = "CMAKE_SYSROOT_LINK";
-static std::string const kCMAKE_Swift_COMPILER_TARGET =
-  "CMAKE_Swift_COMPILER_TARGET";
-static std::string const kCMAKE_TRY_COMPILE_OSX_ARCHITECTURES =
+std::string const kCMAKE_SYSROOT = "CMAKE_SYSROOT";
+std::string const kCMAKE_SYSROOT_COMPILE = "CMAKE_SYSROOT_COMPILE";
+std::string const kCMAKE_SYSROOT_LINK = "CMAKE_SYSROOT_LINK";
+std::string const kCMAKE_TRY_COMPILE_OSX_ARCHITECTURES =
   "CMAKE_TRY_COMPILE_OSX_ARCHITECTURES";
-static std::string const kCMAKE_TRY_COMPILE_PLATFORM_VARIABLES =
+std::string const kCMAKE_TRY_COMPILE_PLATFORM_VARIABLES =
   "CMAKE_TRY_COMPILE_PLATFORM_VARIABLES";
-static std::string const kCMAKE_WARN_DEPRECATED = "CMAKE_WARN_DEPRECATED";
+std::string const kCMAKE_WARN_DEPRECATED = "CMAKE_WARN_DEPRECATED";
 
 /* GHS Multi platform variables */
-static std::set<std::string> ghs_platform_vars{
+std::set<std::string> const ghs_platform_vars{
   "GHS_TARGET_PLATFORM", "GHS_PRIMARY_TARGET", "GHS_TOOLSET_ROOT",
   "GHS_OS_ROOT",         "GHS_OS_DIR",         "GHS_BSP_NAME",
   "GHS_OS_DIR_OPTION"
 };
-
-static void writeProperty(FILE* fout, std::string const& targetName,
-                          std::string const& prop, std::string const& value)
-{
-  fprintf(fout, "set_property(TARGET %s PROPERTY %s %s)\n", targetName.c_str(),
-          cmOutputConverter::EscapeForCMake(prop).c_str(),
-          cmOutputConverter::EscapeForCMake(value).c_str());
-}
-
-std::string cmCoreTryCompile::LookupStdVar(std::string const& var,
-                                           bool warnCMP0067)
-{
-  std::string value = this->Makefile->GetSafeDefinition(var);
-  if (warnCMP0067 && !value.empty()) {
-    value.clear();
-    this->WarnCMP0067.push_back(var);
-  }
-  return value;
 }
 
 int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv,
@@ -103,29 +236,22 @@
   this->SrcFileSignature = true;
 
   cmStateEnums::TargetType targetType = cmStateEnums::EXECUTABLE;
-  const char* tt =
-    this->Makefile->GetDefinition("CMAKE_TRY_COMPILE_TARGET_TYPE");
-  if (!isTryRun && tt && *tt) {
-    if (strcmp(tt, cmState::GetTargetTypeName(cmStateEnums::EXECUTABLE)) ==
-        0) {
+  cmProp tt = this->Makefile->GetDef("CMAKE_TRY_COMPILE_TARGET_TYPE");
+  if (!isTryRun && cmNonempty(tt)) {
+    if (*tt == cmState::GetTargetTypeName(cmStateEnums::EXECUTABLE)) {
       targetType = cmStateEnums::EXECUTABLE;
-    } else if (strcmp(tt,
-                      cmState::GetTargetTypeName(
-                        cmStateEnums::STATIC_LIBRARY)) == 0) {
+    } else if (*tt ==
+               cmState::GetTargetTypeName(cmStateEnums::STATIC_LIBRARY)) {
       targetType = cmStateEnums::STATIC_LIBRARY;
     } else {
       this->Makefile->IssueMessage(
         MessageType::FATAL_ERROR,
-        std::string("Invalid value '") + tt +
-          "' for "
-          "CMAKE_TRY_COMPILE_TARGET_TYPE.  Only "
-          "'" +
-          cmState::GetTargetTypeName(cmStateEnums::EXECUTABLE) +
-          "' and "
-          "'" +
-          cmState::GetTargetTypeName(cmStateEnums::STATIC_LIBRARY) +
-          "' "
-          "are allowed.");
+        cmStrCat("Invalid value '", *tt,
+                 "' for CMAKE_TRY_COMPILE_TARGET_TYPE.  Only '",
+                 cmState::GetTargetTypeName(cmStateEnums::EXECUTABLE),
+                 "' and '",
+                 cmState::GetTargetTypeName(cmStateEnums::STATIC_LIBRARY),
+                 "' are allowed."));
       return -1;
     }
   }
@@ -139,21 +265,11 @@
   std::string outputVariable;
   std::string copyFile;
   std::string copyFileError;
-  std::string cStandard;
-  std::string objcStandard;
-  std::string cxxStandard;
-  std::string objcxxStandard;
-  std::string cudaStandard;
-  std::string cStandardRequired;
-  std::string cxxStandardRequired;
-  std::string objcStandardRequired;
-  std::string objcxxStandardRequired;
-  std::string cudaStandardRequired;
-  std::string cExtensions;
-  std::string cxxExtensions;
-  std::string objcExtensions;
-  std::string objcxxExtensions;
-  std::string cudaExtensions;
+  LanguageStandardState cState("C");
+  LanguageStandardState cudaState("CUDA");
+  LanguageStandardState cxxState("CXX");
+  LanguageStandardState objcState("OBJC");
+  LanguageStandardState objcxxState("OBJCXX");
   std::vector<std::string> targets;
   std::vector<std::string> linkOptions;
   std::string libsToLink = " ";
@@ -162,21 +278,6 @@
   bool didOutputVariable = false;
   bool didCopyFile = false;
   bool didCopyFileError = false;
-  bool didCStandard = false;
-  bool didCxxStandard = false;
-  bool didObjCStandard = false;
-  bool didObjCxxStandard = false;
-  bool didCudaStandard = false;
-  bool didCStandardRequired = false;
-  bool didCxxStandardRequired = false;
-  bool didObjCStandardRequired = false;
-  bool didObjCxxStandardRequired = false;
-  bool didCudaStandardRequired = false;
-  bool didCExtensions = false;
-  bool didCxxExtensions = false;
-  bool didObjCExtensions = false;
-  bool didObjCxxExtensions = false;
-  bool didCudaExtensions = false;
   bool useSources = argv[2] == "SOURCES";
   std::vector<std::string> sources;
 
@@ -190,21 +291,6 @@
     DoingOutputVariable,
     DoingCopyFile,
     DoingCopyFileError,
-    DoingCStandard,
-    DoingCxxStandard,
-    DoingObjCStandard,
-    DoingObjCxxStandard,
-    DoingCudaStandard,
-    DoingCStandardRequired,
-    DoingCxxStandardRequired,
-    DoingObjCStandardRequired,
-    DoingObjCxxStandardRequired,
-    DoingCudaStandardRequired,
-    DoingCExtensions,
-    DoingCxxExtensions,
-    DoingObjCExtensions,
-    DoingObjCxxExtensions,
-    DoingCudaExtensions,
     DoingSources,
     DoingCMakeInternal
   };
@@ -228,51 +314,12 @@
     } else if (argv[i] == "COPY_FILE_ERROR") {
       doing = DoingCopyFileError;
       didCopyFileError = true;
-    } else if (argv[i] == "C_STANDARD") {
-      doing = DoingCStandard;
-      didCStandard = true;
-    } else if (argv[i] == "CXX_STANDARD") {
-      doing = DoingCxxStandard;
-      didCxxStandard = true;
-    } else if (argv[i] == "OBJC_STANDARD") {
-      doing = DoingObjCStandard;
-      didObjCStandard = true;
-    } else if (argv[i] == "OBJCXX_STANDARD") {
-      doing = DoingObjCxxStandard;
-      didObjCxxStandard = true;
-    } else if (argv[i] == "CUDA_STANDARD") {
-      doing = DoingCudaStandard;
-      didCudaStandard = true;
-    } else if (argv[i] == "C_STANDARD_REQUIRED") {
-      doing = DoingCStandardRequired;
-      didCStandardRequired = true;
-    } else if (argv[i] == "CXX_STANDARD_REQUIRED") {
-      doing = DoingCxxStandardRequired;
-      didCxxStandardRequired = true;
-    } else if (argv[i] == "OBJC_STANDARD_REQUIRED") {
-      doing = DoingObjCStandardRequired;
-      didObjCStandardRequired = true;
-    } else if (argv[i] == "OBJCXX_STANDARD_REQUIRED") {
-      doing = DoingObjCxxStandardRequired;
-      didObjCxxStandardRequired = true;
-    } else if (argv[i] == "CUDA_STANDARD_REQUIRED") {
-      doing = DoingCudaStandardRequired;
-      didCudaStandardRequired = true;
-    } else if (argv[i] == "C_EXTENSIONS") {
-      doing = DoingCExtensions;
-      didCExtensions = true;
-    } else if (argv[i] == "CXX_EXTENSIONS") {
-      doing = DoingCxxExtensions;
-      didCxxExtensions = true;
-    } else if (argv[i] == "OBJC_EXTENSIONS") {
-      doing = DoingObjCExtensions;
-      didObjCExtensions = true;
-    } else if (argv[i] == "OBJCXX_EXTENSIONS") {
-      doing = DoingObjCxxExtensions;
-      didObjCxxExtensions = true;
-    } else if (argv[i] == "CUDA_EXTENSIONS") {
-      doing = DoingCudaExtensions;
-      didCudaExtensions = true;
+    } else if (cState.UpdateIfMatches(argv, i) ||
+               cxxState.UpdateIfMatches(argv, i) ||
+               cudaState.UpdateIfMatches(argv, i) ||
+               objcState.UpdateIfMatches(argv, i) ||
+               objcxxState.UpdateIfMatches(argv, i)) {
+      continue;
     } else if (argv[i] == "__CMAKE_INTERNAL") {
       doing = DoingCMakeInternal;
     } else if (doing == DoingCMakeFlags) {
@@ -298,12 +345,10 @@
           default:
             this->Makefile->IssueMessage(
               MessageType::FATAL_ERROR,
-              "Only libraries may be used as try_compile or try_run IMPORTED "
-              "LINK_LIBRARIES.  Got " +
-                std::string(tgt->GetName()) +
-                " of "
-                "type " +
-                cmState::GetTargetTypeName(tgt->GetType()) + ".");
+              cmStrCat("Only libraries may be used as try_compile or try_run "
+                       "IMPORTED LINK_LIBRARIES.  Got ",
+                       tgt->GetName(), " of type ",
+                       cmState::GetTargetTypeName(tgt->GetType()), "."));
             return -1;
         }
         if (tgt->IsImported()) {
@@ -319,51 +364,6 @@
     } else if (doing == DoingCopyFileError) {
       copyFileError = argv[i];
       doing = DoingNone;
-    } else if (doing == DoingCStandard) {
-      cStandard = argv[i];
-      doing = DoingNone;
-    } else if (doing == DoingCxxStandard) {
-      cxxStandard = argv[i];
-      doing = DoingNone;
-    } else if (doing == DoingObjCStandard) {
-      objcStandard = argv[i];
-      doing = DoingNone;
-    } else if (doing == DoingObjCxxStandard) {
-      objcxxStandard = argv[i];
-      doing = DoingNone;
-    } else if (doing == DoingCudaStandard) {
-      cudaStandard = argv[i];
-      doing = DoingNone;
-    } else if (doing == DoingCStandardRequired) {
-      cStandardRequired = argv[i];
-      doing = DoingNone;
-    } else if (doing == DoingCxxStandardRequired) {
-      cxxStandardRequired = argv[i];
-      doing = DoingNone;
-    } else if (doing == DoingObjCStandardRequired) {
-      objcStandardRequired = argv[i];
-      doing = DoingNone;
-    } else if (doing == DoingObjCxxStandardRequired) {
-      objcxxStandardRequired = argv[i];
-      doing = DoingNone;
-    } else if (doing == DoingCudaStandardRequired) {
-      cudaStandardRequired = argv[i];
-      doing = DoingNone;
-    } else if (doing == DoingCExtensions) {
-      cExtensions = argv[i];
-      doing = DoingNone;
-    } else if (doing == DoingCxxExtensions) {
-      cxxExtensions = argv[i];
-      doing = DoingNone;
-    } else if (doing == DoingObjCExtensions) {
-      objcExtensions = argv[i];
-      doing = DoingNone;
-    } else if (doing == DoingObjCxxExtensions) {
-      objcxxExtensions = argv[i];
-      doing = DoingNone;
-    } else if (doing == DoingCudaExtensions) {
-      cudaExtensions = argv[i];
-      doing = DoingNone;
     } else if (doing == DoingSources) {
       sources.push_back(argv[i]);
     } else if (doing == DoingCMakeInternal) {
@@ -415,59 +415,22 @@
     return -1;
   }
 
-  if (didCStandard && !this->SrcFileSignature) {
-    this->Makefile->IssueMessage(
-      MessageType::FATAL_ERROR,
-      "C_STANDARD allowed only in source file signature.");
-    return -1;
-  }
-  if (didCxxStandard && !this->SrcFileSignature) {
-    this->Makefile->IssueMessage(
-      MessageType::FATAL_ERROR,
-      "CXX_STANDARD allowed only in source file signature.");
-    return -1;
-  }
-  if (didCudaStandard && !this->SrcFileSignature) {
-    this->Makefile->IssueMessage(
-      MessageType::FATAL_ERROR,
-      "CUDA_STANDARD allowed only in source file signature.");
-    return -1;
-  }
-  if (didCStandardRequired && !this->SrcFileSignature) {
-    this->Makefile->IssueMessage(
-      MessageType::FATAL_ERROR,
-      "C_STANDARD_REQUIRED allowed only in source file signature.");
-    return -1;
-  }
-  if (didCxxStandardRequired && !this->SrcFileSignature) {
-    this->Makefile->IssueMessage(
-      MessageType::FATAL_ERROR,
-      "CXX_STANDARD_REQUIRED allowed only in source file signature.");
-    return -1;
-  }
-  if (didCudaStandardRequired && !this->SrcFileSignature) {
-    this->Makefile->IssueMessage(
-      MessageType::FATAL_ERROR,
-      "CUDA_STANDARD_REQUIRED allowed only in source file signature.");
-    return -1;
-  }
-  if (didCExtensions && !this->SrcFileSignature) {
-    this->Makefile->IssueMessage(
-      MessageType::FATAL_ERROR,
-      "C_EXTENSIONS allowed only in source file signature.");
-    return -1;
-  }
-  if (didCxxExtensions && !this->SrcFileSignature) {
-    this->Makefile->IssueMessage(
-      MessageType::FATAL_ERROR,
-      "CXX_EXTENSIONS allowed only in source file signature.");
-    return -1;
-  }
-  if (didCudaExtensions && !this->SrcFileSignature) {
-    this->Makefile->IssueMessage(
-      MessageType::FATAL_ERROR,
-      "CUDA_EXTENSIONS allowed only in source file signature.");
-    return -1;
+  if (!this->SrcFileSignature) {
+    if (!cState.Validate(this->Makefile)) {
+      return -1;
+    }
+    if (!cudaState.Validate(this->Makefile)) {
+      return -1;
+    }
+    if (!cxxState.Validate(this->Makefile)) {
+      return -1;
+    }
+    if (!objcState.Validate(this->Makefile)) {
+      return -1;
+    }
+    if (!objcxxState.Validate(this->Makefile)) {
+      return -1;
+    }
   }
 
   // compute the binary dir when TRY_COMPILE is called with a src file
@@ -571,6 +534,14 @@
               *msvcRuntimeLibraryDefault ? "NEW" : "OLD");
     }
 
+    /* Set CUDA architectures policy to match outer project.  */
+    if (this->Makefile->GetPolicyStatus(cmPolicies::CMP0104) !=
+          cmPolicies::NEW &&
+        testLangs.find("CUDA") != testLangs.end() &&
+        this->Makefile->GetSafeDefinition(kCMAKE_CUDA_ARCHITECTURES).empty()) {
+      fprintf(fout, "cmake_policy(SET CMP0104 OLD)\n");
+    }
+
     std::string projectLangs;
     for (std::string const& li : testLangs) {
       projectLangs += " " + li;
@@ -717,10 +688,23 @@
     // Forward a set of variables to the inner project cache.
     {
       std::set<std::string> vars;
-      vars.insert(kCMAKE_C_COMPILER_EXTERNAL_TOOLCHAIN);
-      vars.insert(kCMAKE_C_COMPILER_TARGET);
-      vars.insert(kCMAKE_CXX_COMPILER_EXTERNAL_TOOLCHAIN);
-      vars.insert(kCMAKE_CXX_COMPILER_TARGET);
+      vars.insert(&c_properties[lang_property_start],
+                  &c_properties[lang_property_start + lang_property_size]);
+      vars.insert(&cxx_properties[lang_property_start],
+                  &cxx_properties[lang_property_start + lang_property_size]);
+      vars.insert(&cuda_properties[lang_property_start],
+                  &cuda_properties[lang_property_start + lang_property_size]);
+      vars.insert(
+        &fortran_properties[lang_property_start],
+        &fortran_properties[lang_property_start + lang_property_size]);
+      vars.insert(&objc_properties[lang_property_start],
+                  &objc_properties[lang_property_start + lang_property_size]);
+      vars.insert(
+        &objcxx_properties[lang_property_start],
+        &objcxx_properties[lang_property_start + lang_property_size]);
+      vars.insert(&swift_properties[lang_property_start],
+                  &swift_properties[lang_property_start + lang_property_size]);
+      vars.insert(kCMAKE_CUDA_ARCHITECTURES);
       vars.insert(kCMAKE_CUDA_RUNTIME_LIBRARY);
       vars.insert(kCMAKE_ENABLE_EXPORTS);
       vars.insert(kCMAKE_LINK_SEARCH_END_STATIC);
@@ -733,7 +717,6 @@
       vars.insert(kCMAKE_SYSROOT);
       vars.insert(kCMAKE_SYSROOT_COMPILE);
       vars.insert(kCMAKE_SYSROOT_LINK);
-      vars.insert(kCMAKE_Swift_COMPILER_TARGET);
       vars.insert(kCMAKE_WARN_DEPRECATED);
       vars.emplace("CMAKE_MSVC_RUNTIME_LIBRARY"_s);
 
@@ -747,10 +730,22 @@
           cmPolicies::NEW) {
         // To ensure full support of PIE, propagate cache variables
         // driving the link options
-        vars.insert(kCMAKE_C_LINK_PIE_SUPPORTED);
-        vars.insert(kCMAKE_C_LINK_NO_PIE_SUPPORTED);
-        vars.insert(kCMAKE_CXX_LINK_PIE_SUPPORTED);
-        vars.insert(kCMAKE_CXX_LINK_NO_PIE_SUPPORTED);
+        vars.insert(&c_properties[pie_property_start],
+                    &c_properties[pie_property_start + pie_property_size]);
+        vars.insert(&cxx_properties[pie_property_start],
+                    &cxx_properties[pie_property_start + pie_property_size]);
+        vars.insert(&cuda_properties[pie_property_start],
+                    &cuda_properties[pie_property_start + pie_property_size]);
+        vars.insert(
+          &fortran_properties[pie_property_start],
+          &fortran_properties[pie_property_start + pie_property_size]);
+        vars.insert(&objc_properties[pie_property_start],
+                    &objc_properties[pie_property_start + pie_property_size]);
+        vars.insert(
+          &objcxx_properties[pie_property_start],
+          &objcxx_properties[pie_property_start + pie_property_size]);
+        vars.insert(&swift_properties[pie_property_start],
+                    &swift_properties[pie_property_start + pie_property_size]);
       }
 
       /* for the TRY_COMPILEs we want to be able to specify the architecture.
@@ -813,21 +808,17 @@
     }
     fprintf(fout, ")\n");
 
-    bool const testC = testLangs.find("C") != testLangs.end();
-    bool const testObjC = testLangs.find("OBJC") != testLangs.end();
-    bool const testCxx = testLangs.find("CXX") != testLangs.end();
-    bool const testObjCxx = testLangs.find("OBJCXX") != testLangs.end();
-    bool const testCuda = testLangs.find("CUDA") != testLangs.end();
+    cState.Enabled(testLangs.find("C") != testLangs.end());
+    cxxState.Enabled(testLangs.find("CXX") != testLangs.end());
+    cudaState.Enabled(testLangs.find("CUDA") != testLangs.end());
+    objcState.Enabled(testLangs.find("OBJC") != testLangs.end());
+    objcxxState.Enabled(testLangs.find("OBJCXX") != testLangs.end());
 
     bool warnCMP0067 = false;
     bool honorStandard = true;
 
-    if (!didCStandard && !didCxxStandard && !didObjCStandard &&
-        !didObjCxxStandard && !didCudaStandard && !didCStandardRequired &&
-        !didCxxStandardRequired && !didObjCStandardRequired &&
-        !didObjCxxStandardRequired && !didCudaStandardRequired &&
-        !didCExtensions && !didCxxExtensions && !didObjCExtensions &&
-        !didObjCxxExtensions && !didCudaExtensions) {
+    if (cState.DidNone() && cxxState.DidNone() && objcState.DidNone() &&
+        objcxxState.DidNone() && cudaState.DidNone()) {
       switch (this->Makefile->GetPolicyStatus(cmPolicies::CMP0067)) {
         case cmPolicies::WARN:
           warnCMP0067 = this->Makefile->PolicyOptionalWarningEnabled(
@@ -849,46 +840,20 @@
       }
     }
 
-    if (honorStandard || warnCMP0067) {
+    std::vector<std::string> warnCMP0067Variables;
 
-      auto testLanguage =
-        [&](bool testLang, bool didLangStandard, bool didLangStandardRequired,
-            bool didLangExtensions, std::string& langStandard,
-            std::string& langStandardRequired, std::string& langExtensions,
-            const std::string& lang) {
-          if (testLang) {
-            if (!didLangStandard) {
-              langStandard = this->LookupStdVar(
-                cmStrCat("CMAKE_", lang, "_STANDARD"), warnCMP0067);
-            }
-            if (!didLangStandardRequired) {
-              langStandardRequired = this->LookupStdVar(
-                cmStrCat("CMAKE_", lang, "_STANDARD_REQUIRED"), warnCMP0067);
-            }
-            if (!didLangExtensions) {
-              langExtensions = this->LookupStdVar(
-                cmStrCat("CMAKE_", lang, "_EXTENSIONS"), warnCMP0067);
-            }
-          }
-        };
+    cState.LoadUnsetPropertyValues(this->Makefile, honorStandard, warnCMP0067,
+                                   warnCMP0067Variables);
+    cxxState.LoadUnsetPropertyValues(this->Makefile, honorStandard,
+                                     warnCMP0067, warnCMP0067Variables);
+    cudaState.LoadUnsetPropertyValues(this->Makefile, honorStandard,
+                                      warnCMP0067, warnCMP0067Variables);
+    objcState.LoadUnsetPropertyValues(this->Makefile, honorStandard,
+                                      warnCMP0067, warnCMP0067Variables);
+    objcxxState.LoadUnsetPropertyValues(this->Makefile, honorStandard,
+                                        warnCMP0067, warnCMP0067Variables);
 
-      testLanguage(testC, didCStandard, didCStandardRequired, didCExtensions,
-                   cStandard, cStandardRequired, cExtensions, "C");
-      testLanguage(testObjC, didObjCStandard, didObjCStandardRequired,
-                   didObjCExtensions, objcStandard, objcStandardRequired,
-                   objcExtensions, "OBJC");
-      testLanguage(testCxx, didCxxStandard, didCxxStandardRequired,
-                   didCxxExtensions, cxxStandard, cxxStandardRequired,
-                   cxxExtensions, "CXX");
-      testLanguage(testObjCxx, didObjCxxStandard, didObjCxxStandardRequired,
-                   didObjCxxExtensions, objcxxStandard, objcxxStandardRequired,
-                   objcxxExtensions, "OBJCXX");
-      testLanguage(testCuda, didCudaStandard, didCudaStandardRequired,
-                   didCudaExtensions, cudaStandard, cudaStandardRequired,
-                   cudaExtensions, "CUDA");
-    }
-
-    if (!this->WarnCMP0067.empty()) {
+    if (!warnCMP0067Variables.empty()) {
       std::ostringstream w;
       /* clang-format off */
       w << cmPolicies::GetPolicyWarning(cmPolicies::CMP0067) << "\n"
@@ -896,43 +861,17 @@
         "is not honoring language standard variables in the test project:\n"
         ;
       /* clang-format on */
-      for (std::string const& vi : this->WarnCMP0067) {
+      for (std::string const& vi : warnCMP0067Variables) {
         w << "  " << vi << "\n";
       }
       this->Makefile->IssueMessage(MessageType::AUTHOR_WARNING, w.str());
     }
 
-    auto writeLanguageProperties = [&](bool testLang,
-                                       const std::string& langStandard,
-                                       const std::string& langStandardRequired,
-                                       const std::string& langExtensions,
-                                       const std::string& lang) {
-      if (testLang) {
-        if (!langStandard.empty()) {
-          writeProperty(fout, targetName, cmStrCat(lang, "_STANDARD"),
-                        langStandard);
-        }
-        if (!langStandardRequired.empty()) {
-          writeProperty(fout, targetName, cmStrCat(lang, "_STANDARD_REQUIRED"),
-                        langStandardRequired);
-        }
-        if (!langExtensions.empty()) {
-          writeProperty(fout, targetName, cmStrCat(lang, "_EXTENSIONS"),
-                        langExtensions);
-        }
-      }
-    };
-
-    writeLanguageProperties(testC, cStandard, cStandardRequired, cExtensions,
-                            "C");
-    writeLanguageProperties(testObjC, objcStandard, objcStandardRequired,
-                            objcExtensions, "OBJC");
-    writeLanguageProperties(testCxx, cxxStandard, cxxStandardRequired,
-                            cxxExtensions, "CXX");
-    writeLanguageProperties(testObjCxx, objcxxStandard, objcxxStandardRequired,
-                            objcxxExtensions, "OBJCXX");
-    writeLanguageProperties(testCuda, cudaStandard, cudaStandardRequired,
-                            cudaExtensions, "CUDA");
+    cState.WriteProperties(fout, targetName);
+    cxxState.WriteProperties(fout, targetName);
+    cudaState.WriteProperties(fout, targetName);
+    objcState.WriteProperties(fout, targetName);
+    objcxxState.WriteProperties(fout, targetName);
 
     if (!linkOptions.empty()) {
       std::vector<std::string> options;
@@ -1044,7 +983,9 @@
   std::set<std::string> deletedFiles;
   for (unsigned long i = 0; i < dir.GetNumberOfFiles(); ++i) {
     const char* fileName = dir.GetFile(i);
-    if (strcmp(fileName, ".") != 0 && strcmp(fileName, "..") != 0) {
+    if (strcmp(fileName, ".") != 0 && strcmp(fileName, "..") != 0 &&
+        // Do not delete NFS temporary files.
+        !cmHasPrefix(fileName, ".nfs")) {
       if (deletedFiles.insert(fileName).second) {
         std::string const fullPath =
           std::string(binDir).append("/").append(fileName);
@@ -1104,14 +1045,14 @@
   const char* config =
     this->Makefile->GetDefinition("CMAKE_TRY_COMPILE_CONFIGURATION");
   // if a config was specified try that first
-  if (config && config[0]) {
+  if (cmNonempty(config)) {
     std::string tmp = cmStrCat('/', config);
     searchDirs.push_back(std::move(tmp));
   }
   searchDirs.emplace_back("/Debug");
 #if defined(__APPLE__)
   std::string app = "/" + targetName + ".app";
-  if (config && config[0]) {
+  if (cmNonempty(config)) {
     std::string tmp = cmStrCat('/', config, app);
     searchDirs.push_back(std::move(tmp));
   }
diff --git a/Source/cmCoreTryCompile.h b/Source/cmCoreTryCompile.h
index ae714a6..916572a 100644
--- a/Source/cmCoreTryCompile.h
+++ b/Source/cmCoreTryCompile.h
@@ -47,10 +47,6 @@
   std::string OutputFile;
   std::string FindErrorMessage;
   bool SrcFileSignature = false;
-
-private:
-  std::vector<std::string> WarnCMP0067;
-  std::string LookupStdVar(std::string const& var, bool warnCMP0067);
 };
 
 #endif
diff --git a/Source/cmCreateTestSourceList.cxx b/Source/cmCreateTestSourceList.cxx
index 9d492ba..9c4deea 100644
--- a/Source/cmCreateTestSourceList.cxx
+++ b/Source/cmCreateTestSourceList.cxx
@@ -127,7 +127,7 @@
   mf.AddDefinition("CMAKE_FORWARD_DECLARE_TESTS", forwardDeclareCode);
   mf.AddDefinition("CMAKE_FUNCTION_TABLE_ENTIRES", functionMapCode);
   bool res = true;
-  if (!mf.ConfigureFile(configFile, driver, false, true, false)) {
+  if (!mf.ConfigureFile(configFile, driver, false, true, false, true)) {
     res = false;
   }
 
diff --git a/Source/cmCryptoHash.cxx b/Source/cmCryptoHash.cxx
index dc7d939..b1e63ba 100644
--- a/Source/cmCryptoHash.cxx
+++ b/Source/cmCryptoHash.cxx
@@ -4,10 +4,10 @@
 
 #include <cm/memory>
 
-#include "cmsys/FStream.hxx"
+#include <cm3p/kwiml/int.h>
+#include <cm3p/rhash.h>
 
-#include "cm_kwiml.h"
-#include "cm_rhash.h"
+#include "cmsys/FStream.hxx"
 
 static unsigned int const cmCryptoHashAlgoToId[] = {
   /* clang-format needs this comment to break after the opening brace */
diff --git a/Source/cmCurl.h b/Source/cmCurl.h
index cb73ce6..7bd036e 100644
--- a/Source/cmCurl.h
+++ b/Source/cmCurl.h
@@ -7,7 +7,7 @@
 
 #include <string>
 
-#include "cm_curl.h"
+#include <cm3p/curl/curl.h>
 
 std::string cmCurlSetCAInfo(::CURL* curl, const char* cafile = nullptr);
 std::string cmCurlSetNETRCOption(::CURL* curl, const std::string& netrc_level,
diff --git a/Source/cmCustomCommand.cxx b/Source/cmCustomCommand.cxx
index 0dd8722..149f5e9 100644
--- a/Source/cmCustomCommand.cxx
+++ b/Source/cmCustomCommand.cxx
@@ -11,7 +11,8 @@
                                  std::vector<std::string> depends,
                                  cmCustomCommandLines commandLines,
                                  cmListFileBacktrace lfbt, const char* comment,
-                                 const char* workingDirectory)
+                                 const char* workingDirectory,
+                                 bool stdPipesUTF8)
   : Outputs(std::move(outputs))
   , Byproducts(std::move(byproducts))
   , Depends(std::move(depends))
@@ -20,6 +21,7 @@
   , Comment(comment ? comment : "")
   , WorkingDirectory(workingDirectory ? workingDirectory : "")
   , HaveComment(comment != nullptr)
+  , StdPipesUTF8(stdPipesUTF8)
 {
 }
 
diff --git a/Source/cmCustomCommand.h b/Source/cmCustomCommand.h
index d300fa5..aa572ad 100644
--- a/Source/cmCustomCommand.h
+++ b/Source/cmCustomCommand.h
@@ -30,7 +30,8 @@
                   std::vector<std::string> byproducts,
                   std::vector<std::string> depends,
                   cmCustomCommandLines commandLines, cmListFileBacktrace lfbt,
-                  const char* comment, const char* workingDirectory);
+                  const char* comment, const char* workingDirectory,
+                  bool stdPipesUTF8);
 
   /** Get the output file produced by the command.  */
   const std::vector<std::string>& GetOutputs() const;
@@ -53,6 +54,9 @@
   /** Get the comment string for the command.  */
   const char* GetComment() const;
 
+  /** Get a value indicating if the command uses UTF-8 output pipes. */
+  bool GetStdPipesUTF8() const { return this->StdPipesUTF8; }
+
   /** Append to the list of command lines.  */
   void AppendCommands(const cmCustomCommandLines& commandLines);
 
@@ -108,6 +112,7 @@
   bool EscapeOldStyle = true;
   bool UsesTerminal = false;
   bool CommandExpandLists = false;
+  bool StdPipesUTF8 = false;
 };
 
 #endif
diff --git a/Source/cmCustomCommandGenerator.cxx b/Source/cmCustomCommandGenerator.cxx
index 2432d2b..60504ba 100644
--- a/Source/cmCustomCommandGenerator.cxx
+++ b/Source/cmCustomCommandGenerator.cxx
@@ -14,6 +14,7 @@
 #include "cmGeneratorTarget.h"
 #include "cmLocalGenerator.h"
 #include "cmMakefile.h"
+#include "cmProperty.h"
 #include "cmStateTypes.h"
 #include "cmStringAlgorithms.h"
 #include "cmSystemTools.h"
@@ -111,13 +112,13 @@
     if (target && target->GetType() == cmStateEnums::EXECUTABLE &&
         !target->IsImported()) {
 
-      const char* emulator_property =
+      cmProp emulator_property =
         target->GetProperty("CROSSCOMPILING_EMULATOR");
       if (!emulator_property) {
         continue;
       }
 
-      cmExpandList(emulator_property, this->EmulatorsWithArguments[c]);
+      cmExpandList(*emulator_property, this->EmulatorsWithArguments[c]);
     }
   }
 }
diff --git a/Source/cmDefinePropertyCommand.cxx b/Source/cmDefinePropertyCommand.cxx
index f4e4fda..4e2d9b0 100644
--- a/Source/cmDefinePropertyCommand.cxx
+++ b/Source/cmDefinePropertyCommand.cxx
@@ -95,7 +95,7 @@
 
   // Actually define the property.
   status.GetMakefile().GetState()->DefineProperty(
-    PropertyName, scope, BriefDocs.c_str(), FullDocs.c_str(), inherited);
+    PropertyName, scope, BriefDocs, FullDocs, inherited);
 
   return true;
 }
diff --git a/Source/cmDefinitions.cxx b/Source/cmDefinitions.cxx
index 69a6427..4a4f87d 100644
--- a/Source/cmDefinitions.cxx
+++ b/Source/cmDefinitions.cxx
@@ -19,7 +19,6 @@
   {
     auto it = begin->Map.find(cm::String::borrow(key));
     if (it != begin->Map.end()) {
-      it->second.Used = true;
       return it->second;
     }
   }
@@ -108,16 +107,3 @@
 {
   this->Map[key] = Def();
 }
-
-std::vector<std::string> cmDefinitions::UnusedKeys() const
-{
-  std::vector<std::string> keys;
-  keys.reserve(this->Map.size());
-  // Consider local definitions.
-  for (auto const& mi : this->Map) {
-    if (!mi.second.Used) {
-      keys.push_back(*mi.first.str_if_stable());
-    }
-  }
-  return keys;
-}
diff --git a/Source/cmDefinitions.h b/Source/cmDefinitions.h
index 0e38fb1..d57750a 100644
--- a/Source/cmDefinitions.h
+++ b/Source/cmDefinitions.h
@@ -48,9 +48,6 @@
   /** Unset a definition.  */
   void Unset(const std::string& key);
 
-  /** List of unused keys.  */
-  std::vector<std::string> UnusedKeys() const;
-
 private:
   /** String with existence boolean.  */
   struct Def
@@ -62,7 +59,6 @@
     {
     }
     cm::String Value;
-    bool Used = false;
   };
   static Def NoDef;
 
diff --git a/Source/cmDepends.cxx b/Source/cmDepends.cxx
index 129a5f7..d8aa730 100644
--- a/Source/cmDepends.cxx
+++ b/Source/cmDepends.cxx
@@ -2,7 +2,6 @@
    file Copyright.txt or https://cmake.org/licensing for details.  */
 #include "cmDepends.h"
 
-#include <sstream>
 #include <utility>
 
 #include "cmsys/FStream.hxx"
@@ -10,12 +9,12 @@
 #include "cmFileTime.h"
 #include "cmFileTimeCache.h"
 #include "cmGeneratedFileStream.h"
-#include "cmLocalGenerator.h"
+#include "cmLocalUnixMakefileGenerator3.h"
 #include "cmMakefile.h"
 #include "cmStringAlgorithms.h"
 #include "cmSystemTools.h"
 
-cmDepends::cmDepends(cmLocalGenerator* lg, std::string targetDir)
+cmDepends::cmDepends(cmLocalUnixMakefileGenerator3* lg, std::string targetDir)
   : LocalGenerator(lg)
   , TargetDirectory(std::move(targetDir))
 {
@@ -81,16 +80,14 @@
 {
   // Print verbose output.
   if (this->Verbose) {
-    std::ostringstream msg;
-    msg << "Clearing dependencies in \"" << file << "\"." << std::endl;
-    cmSystemTools::Stdout(msg.str());
+    cmSystemTools::Stdout(
+      cmStrCat("Clearing dependencies in \"", file, "\".\n"));
   }
 
   // Write an empty dependency file.
   cmGeneratedFileStream depFileStream(file);
   depFileStream << "# Empty dependencies file\n"
-                << "# This may be replaced when dependencies are built."
-                << std::endl;
+                   "# This may be replaced when dependencies are built.\n";
 }
 
 bool cmDepends::WriteDependencies(const std::set<std::string>& /*unused*/,
@@ -172,10 +169,9 @@
 
       // Print verbose output.
       if (this->Verbose) {
-        std::ostringstream msg;
-        msg << "Dependee \"" << dependee << "\" does not exist for depender \""
-            << depender << "\"." << std::endl;
-        cmSystemTools::Stdout(msg.str());
+        cmSystemTools::Stdout(cmStrCat("Dependee \"", dependee,
+                                       "\" does not exist for depender \"",
+                                       depender, "\".\n"));
       }
     } else if (dependerExists) {
       // The dependee and depender both exist.  Compare file times.
@@ -185,10 +181,9 @@
 
         // Print verbose output.
         if (this->Verbose) {
-          std::ostringstream msg;
-          msg << "Dependee \"" << dependee << "\" is newer than depender \""
-              << depender << "\"." << std::endl;
-          cmSystemTools::Stdout(msg.str());
+          cmSystemTools::Stdout(cmStrCat("Dependee \"", dependee,
+                                         "\" is newer than depender \"",
+                                         depender, "\".\n"));
         }
       }
     } else {
@@ -200,11 +195,9 @@
 
         // Print verbose output.
         if (this->Verbose) {
-          std::ostringstream msg;
-          msg << "Dependee \"" << dependee
-              << "\" is newer than depends file \"" << internalDependsFileName
-              << "\"." << std::endl;
-          cmSystemTools::Stdout(msg.str());
+          cmSystemTools::Stdout(cmStrCat("Dependee \"", dependee,
+                                         "\" is newer than depends file \"",
+                                         internalDependsFileName, "\".\n"));
         }
       }
     }
diff --git a/Source/cmDepends.h b/Source/cmDepends.h
index d938775..8cf528f 100644
--- a/Source/cmDepends.h
+++ b/Source/cmDepends.h
@@ -12,7 +12,7 @@
 #include <vector>
 
 class cmFileTimeCache;
-class cmLocalGenerator;
+class cmLocalUnixMakefileGenerator3;
 
 /** \class cmDepends
  * \brief Dependency scanner superclass.
@@ -29,7 +29,8 @@
 public:
   /** Instances need to know the build directory name and the relative
       path from the build directory to the target file.  */
-  cmDepends(cmLocalGenerator* lg = nullptr, std::string targetDir = "");
+  cmDepends(cmLocalUnixMakefileGenerator3* lg = nullptr,
+            std::string targetDir = "");
 
   cmDepends(cmDepends const&) = delete;
   cmDepends& operator=(cmDepends const&) = delete;
@@ -38,7 +39,10 @@
       scanning dependencies.  This is not a full local generator; it
       has been setup to do relative path conversions for the current
       directory.  */
-  void SetLocalGenerator(cmLocalGenerator* lg) { this->LocalGenerator = lg; }
+  void SetLocalGenerator(cmLocalUnixMakefileGenerator3* lg)
+  {
+    this->LocalGenerator = lg;
+  }
 
   /** Set the specific language to be scanned.  */
   void SetLanguage(const std::string& lang) { this->Language = lang; }
@@ -92,7 +96,7 @@
                         std::ostream& internalDepends);
 
   // The local generator.
-  cmLocalGenerator* LocalGenerator;
+  cmLocalUnixMakefileGenerator3* LocalGenerator;
 
   // Flag for verbose output.
   bool Verbose = false;
diff --git a/Source/cmDependsC.cxx b/Source/cmDependsC.cxx
index e30d959..e05c964 100644
--- a/Source/cmDependsC.cxx
+++ b/Source/cmDependsC.cxx
@@ -7,7 +7,7 @@
 #include "cmsys/FStream.hxx"
 
 #include "cmFileTime.h"
-#include "cmLocalGenerator.h"
+#include "cmLocalUnixMakefileGenerator3.h"
 #include "cmMakefile.h"
 #include "cmStringAlgorithms.h"
 #include "cmSystemTools.h"
@@ -22,8 +22,9 @@
 
 cmDependsC::cmDependsC() = default;
 
-cmDependsC::cmDependsC(cmLocalGenerator* lg, const std::string& targetDir,
-                       const std::string& lang, const DependencyMap* validDeps)
+cmDependsC::cmDependsC(cmLocalUnixMakefileGenerator3* lg,
+                       const std::string& targetDir, const std::string& lang,
+                       const DependencyMap* validDeps)
   : cmDepends(lg, targetDir)
   , ValidDeps(validDeps)
 {
@@ -211,18 +212,18 @@
   // written by the original local generator for this directory
   // convert the dependencies to paths relative to the home output
   // directory.  We must do the same here.
-  std::string obj_m = cmSystemTools::ConvertToOutputPath(obj_i);
-  internalDepends << obj_i << std::endl;
+  std::string obj_m = this->LocalGenerator->ConvertToMakefilePath(obj_i);
+  internalDepends << obj_i << '\n';
 
   for (std::string const& dep : dependencies) {
     makeDepends << obj_m << ": "
-                << cmSystemTools::ConvertToOutputPath(
+                << this->LocalGenerator->ConvertToMakefilePath(
                      this->LocalGenerator->MaybeConvertToRelativePath(binDir,
                                                                       dep))
-                << std::endl;
-    internalDepends << " " << dep << std::endl;
+                << '\n';
+    internalDepends << ' ' << dep << '\n';
   }
-  makeDepends << std::endl;
+  makeDepends << '\n';
 
   return true;
 }
@@ -264,19 +265,19 @@
       // file doesn't exist, check that the regular expressions
       // haven't changed
       else if (!res) {
-        if (line.find(INCLUDE_REGEX_LINE_MARKER) == 0) {
+        if (cmHasLiteralPrefix(line, INCLUDE_REGEX_LINE_MARKER)) {
           if (line != this->IncludeRegexLineString) {
             return;
           }
-        } else if (line.find(INCLUDE_REGEX_SCAN_MARKER) == 0) {
+        } else if (cmHasLiteralPrefix(line, INCLUDE_REGEX_SCAN_MARKER)) {
           if (line != this->IncludeRegexScanString) {
             return;
           }
-        } else if (line.find(INCLUDE_REGEX_COMPLAIN_MARKER) == 0) {
+        } else if (cmHasLiteralPrefix(line, INCLUDE_REGEX_COMPLAIN_MARKER)) {
           if (line != this->IncludeRegexComplainString) {
             return;
           }
-        } else if (line.find(INCLUDE_REGEX_TRANSFORM_MARKER) == 0) {
+        } else if (cmHasLiteralPrefix(line, INCLUDE_REGEX_TRANSFORM_MARKER)) {
           if (line != this->IncludeRegexTransformString) {
             return;
           }
@@ -312,17 +313,17 @@
 
   for (auto const& fileIt : this->FileCache) {
     if (fileIt.second.Used) {
-      cacheOut << fileIt.first << std::endl;
+      cacheOut << fileIt.first << '\n';
 
       for (UnscannedEntry const& inc : fileIt.second.UnscannedEntries) {
-        cacheOut << inc.FileName << std::endl;
+        cacheOut << inc.FileName << '\n';
         if (inc.QuotedLocation.empty()) {
-          cacheOut << "-" << std::endl;
+          cacheOut << '-' << '\n';
         } else {
-          cacheOut << inc.QuotedLocation << std::endl;
+          cacheOut << inc.QuotedLocation << '\n';
         }
       }
-      cacheOut << std::endl;
+      cacheOut << '\n';
     }
   }
 }
@@ -383,9 +384,7 @@
   // Get the transformation rules.
   std::vector<std::string> transformRules;
   cmMakefile* mf = this->LocalGenerator->GetMakefile();
-  if (const char* xform = mf->GetDefinition("CMAKE_INCLUDE_TRANSFORMS")) {
-    cmExpandList(xform, transformRules, true);
-  }
+  mf->GetDefExpandList("CMAKE_INCLUDE_TRANSFORMS", transformRules, true);
   for (std::string const& tr : transformRules) {
     this->ParseTransform(tr);
   }
diff --git a/Source/cmDependsC.h b/Source/cmDependsC.h
index 868c94a..e01faa4 100644
--- a/Source/cmDependsC.h
+++ b/Source/cmDependsC.h
@@ -16,7 +16,7 @@
 
 #include "cmDepends.h"
 
-class cmLocalGenerator;
+class cmLocalUnixMakefileGenerator3;
 
 /** \class cmDependsC
  * \brief Dependency scanner for C and C++ object files.
@@ -27,7 +27,7 @@
   /** Checking instances need to know the build directory name and the
       relative path from the build directory to the target file.  */
   cmDependsC();
-  cmDependsC(cmLocalGenerator* lg, const std::string& targetDir,
+  cmDependsC(cmLocalUnixMakefileGenerator3* lg, const std::string& targetDir,
              const std::string& lang, const DependencyMap* validDeps);
 
   /** Virtual destructor to cleanup subclasses properly.  */
diff --git a/Source/cmDependsFortran.cxx b/Source/cmDependsFortran.cxx
index 3692202..54418df 100644
--- a/Source/cmDependsFortran.cxx
+++ b/Source/cmDependsFortran.cxx
@@ -12,7 +12,7 @@
 
 #include "cmFortranParser.h" /* Interface to parser object.  */
 #include "cmGeneratedFileStream.h"
-#include "cmLocalGenerator.h"
+#include "cmLocalUnixMakefileGenerator3.h"
 #include "cmMakefile.h"
 #include "cmOutputConverter.h"
 #include "cmStateDirectory.h"
@@ -29,12 +29,10 @@
                                             std::string& mod_lower)
 {
   std::string::size_type ext_len = 0;
-  if (cmHasLiteralSuffix(mod, ".mod")) {
+  if (cmHasLiteralSuffix(mod, ".mod") || cmHasLiteralSuffix(mod, ".sub")) {
     ext_len = 4;
   } else if (cmHasLiteralSuffix(mod, ".smod")) {
     ext_len = 5;
-  } else if (cmHasLiteralSuffix(mod, ".sub")) {
-    ext_len = 4;
   }
   std::string const& name = mod.substr(0, mod.size() - ext_len);
   std::string const& ext = mod.substr(mod.size() - ext_len);
@@ -72,7 +70,7 @@
 
 cmDependsFortran::cmDependsFortran() = default;
 
-cmDependsFortran::cmDependsFortran(cmLocalGenerator* lg)
+cmDependsFortran::cmDependsFortran(cmLocalUnixMakefileGenerator3* lg)
   : cmDepends(lg)
   , Internal(new cmDependsFortranInternals)
 {
@@ -82,10 +80,7 @@
   // Get the list of definitions.
   std::vector<std::string> definitions;
   cmMakefile* mf = this->LocalGenerator->GetMakefile();
-  if (const char* c_defines =
-        mf->GetDefinition("CMAKE_TARGET_DEFINITIONS_Fortran")) {
-    cmExpandList(c_defines, definitions);
-  }
+  mf->GetDefExpandList("CMAKE_TARGET_DEFINITIONS_Fortran", definitions);
 
   // translate i.e. FOO=BAR to FOO and add it to the list of defined
   // preprocessor symbols
@@ -102,10 +97,7 @@
   this->SModExt = mf->GetSafeDefinition("CMAKE_Fortran_SUBMODULE_EXT");
 }
 
-cmDependsFortran::~cmDependsFortran()
-{
-  delete this->Internal;
-}
+cmDependsFortran::~cmDependsFortran() = default;
 
 bool cmDependsFortran::WriteDependencies(const std::set<std::string>& sources,
                                          const std::string& obj,
@@ -188,7 +180,7 @@
   fiStream << "provides\n";
   std::set<std::string> const& provides = this->Internal->TargetProvides;
   for (std::string const& i : provides) {
-    fiStream << " " << i << "\n";
+    fiStream << ' ' << i << '\n';
   }
 
   // Create a script to clean the modules.
@@ -205,14 +197,14 @@
       std::string mod_lower = cmStrCat(mod_dir, '/');
       cmFortranModuleAppendUpperLower(i, mod_upper, mod_lower);
       std::string stamp = cmStrCat(stamp_dir, '/', i, ".stamp");
-      fcStream << "\n";
-      fcStream << "  \""
+      fcStream << "\n"
+                  "  \""
                << this->MaybeConvertToRelativePath(currentBinDir, mod_lower)
-               << "\"\n";
-      fcStream << "  \""
+               << "\"\n"
+                  "  \""
                << this->MaybeConvertToRelativePath(currentBinDir, mod_upper)
-               << "\"\n";
-      fcStream << "  \""
+               << "\"\n"
+                  "  \""
                << this->MaybeConvertToRelativePath(currentBinDir, stamp)
                << "\"\n";
     }
@@ -248,10 +240,7 @@
   // Load information about other targets.
   cmMakefile* mf = this->LocalGenerator->GetMakefile();
   std::vector<std::string> infoFiles;
-  if (const char* infoFilesValue =
-        mf->GetDefinition("CMAKE_TARGET_LINKED_INFO_FILES")) {
-    cmExpandList(infoFilesValue, infoFiles);
-  }
+  mf->GetDefExpandList("CMAKE_TARGET_LINKED_INFO_FILES", infoFiles);
   for (std::string const& i : infoFiles) {
     std::string targetDir = cmSystemTools::GetFilenamePath(i);
     std::string fname = targetDir + "/fortran.internal";
@@ -329,16 +318,15 @@
   std::string binDir = this->LocalGenerator->GetBinaryDirectory();
   std::string obj_i = this->MaybeConvertToRelativePath(binDir, obj);
   std::string obj_m = cmSystemTools::ConvertToOutputPath(obj_i);
-  internalDepends << obj_i << std::endl;
-  internalDepends << " " << src << std::endl;
+  internalDepends << obj_i << "\n " << src << '\n';
   for (std::string const& i : info.Includes) {
     makeDepends << obj_m << ": "
                 << cmSystemTools::ConvertToOutputPath(
                      this->MaybeConvertToRelativePath(binDir, i))
-                << std::endl;
-    internalDepends << " " << i << std::endl;
+                << '\n';
+    internalDepends << ' ' << i << '\n';
   }
-  makeDepends << std::endl;
+  makeDepends << '\n';
 
   // Write module requirements to the output stream.
   for (std::string const& i : info.Requires) {
@@ -357,7 +345,7 @@
       // This module is known.  Depend on its timestamp file.
       std::string stampFile = cmSystemTools::ConvertToOutputPath(
         this->MaybeConvertToRelativePath(binDir, required->second));
-      makeDepends << obj_m << ": " << stampFile << "\n";
+      makeDepends << obj_m << ": " << stampFile << '\n';
     } else {
       // This module is not known to CMake.  Try to locate it where
       // the compiler will and depend on that.
@@ -365,7 +353,7 @@
       if (this->FindModule(i, module)) {
         module = cmSystemTools::ConvertToOutputPath(
           this->MaybeConvertToRelativePath(binDir, module));
-        makeDepends << obj_m << ": " << module << "\n";
+        makeDepends << obj_m << ": " << module << '\n';
       }
     }
   }
@@ -394,7 +382,7 @@
         cmSystemTools::ConvertToOutputPath(stampFile);
 
       makeDepends << obj_m << ".provides.build"
-                  << ": " << stampFileForMake << "\n";
+                  << ": " << stampFileForMake << '\n';
       // Note that when cmake_copy_f90_mod finds that a module file
       // and the corresponding stamp file have no differences, the stamp
       // file is not updated. In such case the stamp file will be always
@@ -402,15 +390,15 @@
       // on each new build. This is expected behavior for incremental
       // builds and can not be changed without preforming recursive make
       // calls that would considerably slow down the building process.
-      makeDepends << stampFileForMake << ": " << obj_m << "\n";
+      makeDepends << stampFileForMake << ": " << obj_m << '\n';
       makeDepends << "\t$(CMAKE_COMMAND) -E cmake_copy_f90_mod " << modFile
-                  << " " << stampFileForShell;
+                  << ' ' << stampFileForShell;
       cmMakefile* mf = this->LocalGenerator->GetMakefile();
       const char* cid = mf->GetDefinition("CMAKE_Fortran_COMPILER_ID");
-      if (cid && *cid) {
-        makeDepends << " " << cid;
+      if (cmNonempty(cid)) {
+        makeDepends << ' ' << cid;
       }
-      makeDepends << "\n";
+      makeDepends << '\n';
     }
     makeDepends << obj_m << ".provides.build:\n";
     // After copying the modules update the timestamp file.
diff --git a/Source/cmDependsFortran.h b/Source/cmDependsFortran.h
index 0485115..3e306dd 100644
--- a/Source/cmDependsFortran.h
+++ b/Source/cmDependsFortran.h
@@ -6,6 +6,7 @@
 #include "cmConfigure.h" // IWYU pragma: keep
 
 #include <iosfwd>
+#include <memory>
 #include <set>
 #include <string>
 #include <vector>
@@ -14,7 +15,7 @@
 
 class cmDependsFortranInternals;
 class cmFortranSourceInfo;
-class cmLocalGenerator;
+class cmLocalUnixMakefileGenerator3;
 
 /** \class cmDependsFortran
  * \brief Dependency scanner for Fortran object files.
@@ -30,7 +31,7 @@
       path from the build directory to the target file, the source
       file from which to start scanning, the include file search
       path, and the target directory.  */
-  cmDependsFortran(cmLocalGenerator* lg);
+  cmDependsFortran(cmLocalUnixMakefileGenerator3* lg);
 
   /** Virtual destructor to cleanup subclasses properly.  */
   ~cmDependsFortran() override;
@@ -84,7 +85,7 @@
   std::set<std::string> PPDefinitions;
 
   // Internal implementation details.
-  cmDependsFortranInternals* Internal = nullptr;
+  std::unique_ptr<cmDependsFortranInternals> Internal;
 
 private:
   std::string MaybeConvertToRelativePath(std::string const& base,
diff --git a/Source/cmDependsJavaParserHelper.cxx b/Source/cmDependsJavaParserHelper.cxx
index 516bbbf..fc1bbdd 100644
--- a/Source/cmDependsJavaParserHelper.cxx
+++ b/Source/cmDependsJavaParserHelper.cxx
@@ -8,6 +8,7 @@
 #include <iostream>
 #include <utility>
 
+#include <cm/memory>
 #include <cm/string_view>
 
 #include "cmsys/FStream.hxx"
@@ -169,10 +170,11 @@
     return;
   }
   this->UnionsAvailable++;
-  pt->str = new char[len + 1];
+  auto up = cm::make_unique<char[]>(len + 1);
+  pt->str = up.get();
   strncpy(pt->str, str, len);
   pt->str[len] = 0;
-  this->Allocates.push_back(pt->str);
+  this->Allocates.push_back(std::move(up));
 }
 
 void cmDependsJavaParserHelper::StartClass(const char* cls)
@@ -275,10 +277,7 @@
 
 void cmDependsJavaParserHelper::CleanupParser()
 {
-  for (char* allocate : this->Allocates) {
-    delete[] allocate;
-  }
-  this->Allocates.erase(this->Allocates.begin(), this->Allocates.end());
+  this->Allocates.clear();
 }
 
 int cmDependsJavaParserHelper::LexInput(char* buf, int maxlen)
diff --git a/Source/cmDependsJavaParserHelper.h b/Source/cmDependsJavaParserHelper.h
index a673b5b..c545ee2 100644
--- a/Source/cmDependsJavaParserHelper.h
+++ b/Source/cmDependsJavaParserHelper.h
@@ -5,6 +5,7 @@
 
 #include "cmConfigure.h" // IWYU pragma: keep
 
+#include <memory>
 #include <string>
 #include <vector>
 
@@ -81,7 +82,7 @@
   int CurrentDepth;
   int Verbose;
 
-  std::vector<char*> Allocates;
+  std::vector<std::unique_ptr<char[]>> Allocates;
 
   void PrintClasses();
 
diff --git a/Source/cmDynamicLoader.cxx b/Source/cmDynamicLoader.cxx
index 0b72a94..a3731c1 100644
--- a/Source/cmDynamicLoader.cxx
+++ b/Source/cmDynamicLoader.cxx
@@ -6,6 +6,7 @@
 #include <string>
 #include <utility>
 
+namespace {
 class cmDynamicLoaderCache
 {
 public:
@@ -15,14 +16,15 @@
                     cmsys::DynamicLoader::LibraryHandle& /*p*/);
   bool FlushCache(const char* path);
   void FlushCache();
-  static cmDynamicLoaderCache* GetInstance();
+  static cmDynamicLoaderCache& GetInstance();
 
 private:
   std::map<std::string, cmsys::DynamicLoader::LibraryHandle> CacheMap;
-  static cmDynamicLoaderCache* Instance;
+  static cmDynamicLoaderCache Instance;
 };
 
-cmDynamicLoaderCache* cmDynamicLoaderCache::Instance = nullptr;
+cmDynamicLoaderCache cmDynamicLoaderCache::Instance;
+}
 
 cmDynamicLoaderCache::~cmDynamicLoaderCache() = default;
 
@@ -64,15 +66,11 @@
   for (auto const& it : this->CacheMap) {
     cmsys::DynamicLoader::CloseLibrary(it.second);
   }
-  delete cmDynamicLoaderCache::Instance;
-  cmDynamicLoaderCache::Instance = nullptr;
+  this->CacheMap.clear();
 }
 
-cmDynamicLoaderCache* cmDynamicLoaderCache::GetInstance()
+cmDynamicLoaderCache& cmDynamicLoaderCache::GetInstance()
 {
-  if (!cmDynamicLoaderCache::Instance) {
-    cmDynamicLoaderCache::Instance = new cmDynamicLoaderCache;
-  }
   return cmDynamicLoaderCache::Instance;
 }
 
@@ -80,15 +78,15 @@
   const char* libname)
 {
   cmsys::DynamicLoader::LibraryHandle lh;
-  if (cmDynamicLoaderCache::GetInstance()->GetCacheFile(libname, lh)) {
+  if (cmDynamicLoaderCache::GetInstance().GetCacheFile(libname, lh)) {
     return lh;
   }
   lh = cmsys::DynamicLoader::OpenLibrary(libname);
-  cmDynamicLoaderCache::GetInstance()->CacheFile(libname, lh);
+  cmDynamicLoaderCache::GetInstance().CacheFile(libname, lh);
   return lh;
 }
 
 void cmDynamicLoader::FlushCache()
 {
-  cmDynamicLoaderCache::GetInstance()->FlushCache();
+  cmDynamicLoaderCache::GetInstance().FlushCache();
 }
diff --git a/Source/cmELF.cxx b/Source/cmELF.cxx
index 202b205..a8d81f7 100644
--- a/Source/cmELF.cxx
+++ b/Source/cmELF.cxx
@@ -3,6 +3,7 @@
 #include "cmELF.h"
 
 #include <cstddef>
+#include <cstdint>
 #include <map>
 #include <memory>
 #include <sstream>
@@ -12,14 +13,13 @@
 #include <cm/memory>
 #include <cmext/algorithm>
 
-#include "cmsys/FStream.hxx"
+#include <cm3p/kwiml/abi.h>
 
-#include "cm_kwiml.h"
+#include "cmsys/FStream.hxx"
 
 // Include the ELF format information system header.
 #if defined(__OpenBSD__)
 #  include <elf_abi.h>
-#  include <stdint.h>
 #elif defined(__HAIKU__)
 #  include <elf32.h>
 #  include <elf64.h>
diff --git a/Source/cmExecuteProcessCommand.cxx b/Source/cmExecuteProcessCommand.cxx
index 5be5bce..9c53bdf 100644
--- a/Source/cmExecuteProcessCommand.cxx
+++ b/Source/cmExecuteProcessCommand.cxx
@@ -10,11 +10,10 @@
 #include <vector>
 
 #include <cmext/algorithm>
+#include <cmext/string_view>
 
 #include "cmsys/Process.h"
 
-#include "cm_static_string_view.hxx"
-
 #include "cmArgumentParser.h"
 #include "cmExecutionStatus.h"
 #include "cmMakefile.h"
@@ -61,6 +60,8 @@
     bool ErrorQuiet = false;
     bool OutputStripTrailingWhitespace = false;
     bool ErrorStripTrailingWhitespace = false;
+    bool EchoOutputVariable = false;
+    bool EchoErrorVariable = false;
     std::string Encoding;
   };
 
@@ -83,7 +84,9 @@
             &Arguments::OutputStripTrailingWhitespace)
       .Bind("ERROR_STRIP_TRAILING_WHITESPACE"_s,
             &Arguments::ErrorStripTrailingWhitespace)
-      .Bind("ENCODING"_s, &Arguments::Encoding);
+      .Bind("ENCODING"_s, &Arguments::Encoding)
+      .Bind("ECHO_OUTPUT_VARIABLE"_s, &Arguments::EchoOutputVariable)
+      .Bind("ECHO_ERROR_VARIABLE"_s, &Arguments::EchoErrorVariable);
 
   std::vector<std::string> unparsedArguments;
   std::vector<std::string> keywordsMissingValue;
@@ -241,28 +244,32 @@
   while ((p = cmsysProcess_WaitForData(cp, &data, &length, nullptr))) {
     // Put the output in the right place.
     if (p == cmsysProcess_Pipe_STDOUT && !arguments.OutputQuiet) {
-      if (arguments.OutputVariable.empty()) {
+      if (arguments.OutputVariable.empty() || arguments.EchoOutputVariable) {
         processOutput.DecodeText(data, length, strdata, 1);
         cmSystemTools::Stdout(strdata);
-      } else {
+      }
+      if (!arguments.OutputVariable.empty()) {
         cmExecuteProcessCommandAppend(tempOutput, data, length);
       }
     } else if (p == cmsysProcess_Pipe_STDERR && !arguments.ErrorQuiet) {
-      if (arguments.ErrorVariable.empty()) {
+      if (arguments.ErrorVariable.empty() || arguments.EchoErrorVariable) {
         processOutput.DecodeText(data, length, strdata, 2);
         cmSystemTools::Stderr(strdata);
-      } else {
+      }
+      if (!arguments.ErrorVariable.empty()) {
         cmExecuteProcessCommandAppend(tempError, data, length);
       }
     }
   }
-  if (!arguments.OutputQuiet && arguments.OutputVariable.empty()) {
+  if (!arguments.OutputQuiet &&
+      (arguments.OutputVariable.empty() || arguments.EchoOutputVariable)) {
     processOutput.DecodeText(std::string(), strdata, 1);
     if (!strdata.empty()) {
       cmSystemTools::Stdout(strdata);
     }
   }
-  if (!arguments.ErrorQuiet && arguments.ErrorVariable.empty()) {
+  if (!arguments.ErrorQuiet &&
+      (arguments.ErrorVariable.empty() || arguments.EchoErrorVariable)) {
     processOutput.DecodeText(std::string(), strdata, 2);
     if (!strdata.empty()) {
       cmSystemTools::Stderr(strdata);
diff --git a/Source/cmExportBuildAndroidMKGenerator.cxx b/Source/cmExportBuildAndroidMKGenerator.cxx
index 561e830..3641cb2 100644
--- a/Source/cmExportBuildAndroidMKGenerator.cxx
+++ b/Source/cmExportBuildAndroidMKGenerator.cxx
@@ -5,7 +5,8 @@
 #include <sstream>
 #include <utility>
 
-#include "cmAlgorithms.h"
+#include <cmext/algorithm>
+
 #include "cmGeneratorTarget.h"
 #include "cmLinkItem.h"
 #include "cmMakefile.h"
@@ -46,7 +47,9 @@
   os << "LOCAL_MODULE := ";
   os << targetName << "\n";
   os << "LOCAL_SRC_FILES := ";
-  std::string path = cmSystemTools::ConvertToOutputPath(target->GetFullPath());
+  std::string const noConfig; // FIXME: What config to use here?
+  std::string path =
+    cmSystemTools::ConvertToOutputPath(target->GetFullPath(noConfig));
   os << path << "\n";
 }
 
@@ -118,13 +121,13 @@
           } else {
             bool relpath = false;
             if (type == cmExportBuildAndroidMKGenerator::INSTALL) {
-              relpath = lib.substr(0, 3) == "../";
+              relpath = cmHasLiteralPrefix(lib, "../");
             }
             // check for full path or if it already has a -l, or
             // in the case of an install check for relative paths
             // if it is full or a link library then use string directly
             if (cmSystemTools::FileIsFullPath(lib) ||
-                lib.substr(0, 2) == "-l" || relpath) {
+                cmHasLiteralPrefix(lib, "-l") || relpath) {
               ldlibs += " " + lib;
               // if it is not a path and does not have a -l then add -l
             } else if (!lib.empty()) {
@@ -165,7 +168,7 @@
   // Tell the NDK build system if prebuilt static libraries use C++.
   if (target->GetType() == cmStateEnums::STATIC_LIBRARY) {
     cmLinkImplementation const* li = target->GetLinkImplementation(config);
-    if (cmContains(li->Languages, "CXX")) {
+    if (cm::contains(li->Languages, "CXX")) {
       os << "LOCAL_HAS_CPP := true\n";
     }
   }
diff --git a/Source/cmExportBuildFileGenerator.cxx b/Source/cmExportBuildFileGenerator.cxx
index d22bd48..dd700c5 100644
--- a/Source/cmExportBuildFileGenerator.cxx
+++ b/Source/cmExportBuildFileGenerator.cxx
@@ -8,7 +8,8 @@
 #include <sstream>
 #include <utility>
 
-#include "cmAlgorithms.h"
+#include <cmext/algorithm>
+
 #include "cmExportSet.h"
 #include "cmGeneratorExpression.h"
 #include "cmGeneratorTarget.h"
@@ -307,7 +308,7 @@
     const auto& exportSet = exp.second;
     std::vector<std::string> targets;
     exportSet->GetTargets(targets);
-    if (cmContains(targets, name)) {
+    if (cm::contains(targets, name)) {
       exportFiles.push_back(exp.first);
       ns = exportSet->GetNamespace();
     }
diff --git a/Source/cmExportCommand.cxx b/Source/cmExportCommand.cxx
index e49c174..352eaf2 100644
--- a/Source/cmExportCommand.cxx
+++ b/Source/cmExportCommand.cxx
@@ -7,12 +7,11 @@
 #include <utility>
 
 #include <cm/memory>
+#include <cmext/algorithm>
+#include <cmext/string_view>
 
 #include "cmsys/RegularExpression.hxx"
 
-#include "cm_static_string_view.hxx"
-
-#include "cmAlgorithms.h"
 #include "cmArgumentParser.h"
 #include "cmExecutionStatus.h"
 #include "cmExportBuildAndroidMKGenerator.h"
@@ -24,6 +23,7 @@
 #include "cmMessageType.h"
 #include "cmPolicies.h"
 #include "cmStateTypes.h"
+#include "cmStringAlgorithms.h"
 #include "cmSystemTools.h"
 #include "cmTarget.h"
 
@@ -146,7 +146,7 @@
     }
     exportSet = &it->second;
   } else if (!arguments.Targets.empty() ||
-             cmContains(keywordsMissingValue, "TARGETS")) {
+             cm::contains(keywordsMissingValue, "TARGETS")) {
     for (std::string const& currentTarget : arguments.Targets) {
       if (mf.IsAlias(currentTarget)) {
         std::ostringstream e;
@@ -183,6 +183,28 @@
     return false;
   }
 
+  // if cmExportBuildFileGenerator is already defined for the file
+  // and APPEND is not specified, if CMP0103 is OLD ignore previous definition
+  // else raise an error
+  if (gg->GetExportedTargetsFile(fname) != nullptr) {
+    switch (mf.GetPolicyStatus(cmPolicies::CMP0103)) {
+      case cmPolicies::WARN:
+        mf.IssueMessage(
+          MessageType::AUTHOR_WARNING,
+          cmStrCat(cmPolicies::GetPolicyWarning(cmPolicies::CMP0103), '\n',
+                   "export() command already specified for the file\n  ",
+                   arguments.Filename, "\nDid you miss 'APPEND' keyword?"));
+        CM_FALLTHROUGH;
+      case cmPolicies::OLD:
+        break;
+      default:
+        status.SetError(cmStrCat("command already specified for the file\n  ",
+                                 arguments.Filename,
+                                 "\nDid you miss 'APPEND' keyword?"));
+        return false;
+    }
+  }
+
   // Setup export file generation.
   std::unique_ptr<cmExportBuildFileGenerator> ebfg = nullptr;
   if (android) {
@@ -201,11 +223,9 @@
   ebfg->SetExportOld(arguments.ExportOld);
 
   // Compute the set of configurations exported.
-  std::vector<std::string> configurationTypes;
-  mf.GetConfigurations(configurationTypes);
-  if (configurationTypes.empty()) {
-    configurationTypes.emplace_back();
-  }
+  std::vector<std::string> configurationTypes =
+    mf.GetGeneratorConfigs(cmMakefile::IncludeEmptyConfig);
+
   for (std::string const& ct : configurationTypes) {
     ebfg->AddConfiguration(ct);
   }
diff --git a/Source/cmExportFileGenerator.cxx b/Source/cmExportFileGenerator.cxx
index 6441e6f..58aa391 100644
--- a/Source/cmExportFileGenerator.cxx
+++ b/Source/cmExportFileGenerator.cxx
@@ -21,6 +21,7 @@
 #include "cmMessageType.h"
 #include "cmOutputConverter.h"
 #include "cmPolicies.h"
+#include "cmProperty.h"
 #include "cmPropertyMap.h"
 #include "cmStateTypes.h"
 #include "cmStringAlgorithms.h"
@@ -125,9 +126,9 @@
   const std::string& propName, cmGeneratorTarget* target,
   ImportPropertyMap& properties)
 {
-  const char* input = target->GetProperty(propName);
+  cmProp input = target->GetProperty(propName);
   if (input) {
-    properties[propName] = input;
+    properties[propName] = *input;
   }
 }
 
@@ -137,16 +138,16 @@
   cmGeneratorExpression::PreprocessContext preprocessRule,
   ImportPropertyMap& properties, std::vector<std::string>& missingTargets)
 {
-  const char* input = target->GetProperty(propName);
+  cmProp input = target->GetProperty(propName);
   if (input) {
-    if (!*input) {
+    if (input->empty()) {
       // Set to empty
       properties[outputName].clear();
       return;
     }
 
     std::string prepro =
-      cmGeneratorExpression::Preprocess(input, preprocessRule);
+      cmGeneratorExpression::Preprocess(*input, preprocessRule);
     if (!prepro.empty()) {
       this->ResolveTargetsInGeneratorExpressions(prepro, target,
                                                  missingTargets);
@@ -174,10 +175,10 @@
   if (!target->IsLinkable()) {
     return false;
   }
-  const char* input = target->GetProperty("INTERFACE_LINK_LIBRARIES");
+  cmProp input = target->GetProperty("INTERFACE_LINK_LIBRARIES");
   if (input) {
     std::string prepro =
-      cmGeneratorExpression::Preprocess(input, preprocessRule);
+      cmGeneratorExpression::Preprocess(*input, preprocessRule);
     if (!prepro.empty()) {
       this->ResolveTargetsInGeneratorExpressions(
         prepro, target, missingTargets, ReplaceFreeTargets);
@@ -276,8 +277,7 @@
                 << "\"\nhowever it is also "
                    "a subdirectory of the "
                 << (inBinary ? "build" : "source") << " tree:\n    \""
-                << (inBinary ? topBinaryDir : topSourceDir) << "\""
-                << std::endl;
+                << (inBinary ? topBinaryDir : topSourceDir) << "\"\n";
               target->GetLocalGenerator()->IssueMessage(
                 MessageType::AUTHOR_WARNING, s.str());
               CM_FALLTHROUGH;
@@ -342,19 +342,19 @@
   assert(preprocessRule == cmGeneratorExpression::InstallInterface);
 
   const char* propName = "INTERFACE_SOURCES";
-  const char* input = gt->GetProperty(propName);
+  cmProp input = gt->GetProperty(propName);
 
   if (!input) {
     return;
   }
 
-  if (!*input) {
+  if (input->empty()) {
     properties[propName].clear();
     return;
   }
 
   std::string prepro =
-    cmGeneratorExpression::Preprocess(input, preprocessRule, true);
+    cmGeneratorExpression::Preprocess(*input, preprocessRule, true);
   if (!prepro.empty()) {
     this->ResolveTargetsInGeneratorExpressions(prepro, gt, missingTargets);
 
@@ -373,7 +373,7 @@
   assert(preprocessRule == cmGeneratorExpression::InstallInterface);
 
   const char* propName = "INTERFACE_INCLUDE_DIRECTORIES";
-  const char* input = target->GetProperty(propName);
+  cmProp input = target->GetProperty(propName);
 
   cmGeneratorExpression ge;
 
@@ -400,7 +400,7 @@
   if (!input && exportDirs.empty()) {
     return;
   }
-  if ((input && !*input) && exportDirs.empty()) {
+  if ((input && input->empty()) && exportDirs.empty()) {
     // Set to empty
     properties[propName].clear();
     return;
@@ -408,7 +408,7 @@
 
   prefixItems(exportDirs);
 
-  std::string includes = (input ? input : "");
+  std::string includes = (input ? *input : "");
   const char* sep = input ? ";" : "";
   includes += sep + exportDirs;
   std::string prepro =
@@ -431,19 +431,19 @@
   assert(preprocessRule == cmGeneratorExpression::InstallInterface);
 
   const char* propName = "INTERFACE_LINK_DEPENDS";
-  const char* input = gt->GetProperty(propName);
+  cmProp input = gt->GetProperty(propName);
 
   if (!input) {
     return;
   }
 
-  if (!*input) {
+  if (input->empty()) {
     properties[propName].clear();
     return;
   }
 
   std::string prepro =
-    cmGeneratorExpression::Preprocess(input, preprocessRule, true);
+    cmGeneratorExpression::Preprocess(*input, preprocessRule, true);
   if (!prepro.empty()) {
     this->ResolveTargetsInGeneratorExpressions(prepro, gt, missingTargets);
 
@@ -462,19 +462,19 @@
   assert(preprocessRule == cmGeneratorExpression::InstallInterface);
 
   const char* propName = "INTERFACE_LINK_DIRECTORIES";
-  const char* input = gt->GetProperty(propName);
+  cmProp input = gt->GetProperty(propName);
 
   if (!input) {
     return;
   }
 
-  if (!*input) {
+  if (input->empty()) {
     properties[propName].clear();
     return;
   }
 
   std::string prepro =
-    cmGeneratorExpression::Preprocess(input, preprocessRule, true);
+    cmGeneratorExpression::Preprocess(*input, preprocessRule, true);
   if (!prepro.empty()) {
     this->ResolveTargetsInGeneratorExpressions(prepro, gt, missingTargets);
 
@@ -497,11 +497,11 @@
 void getPropertyContents(cmGeneratorTarget const* tgt, const std::string& prop,
                          std::set<std::string>& ifaceProperties)
 {
-  const char* p = tgt->GetProperty(prop);
+  cmProp p = tgt->GetProperty(prop);
   if (!p) {
     return;
   }
-  std::vector<std::string> content = cmExpandedList(p);
+  std::vector<std::string> content = cmExpandedList(*p);
   ifaceProperties.insert(content.begin(), content.end());
 }
 
@@ -567,8 +567,9 @@
   if (gtarget->GetType() != cmStateEnums::INTERFACE_LIBRARY) {
     getCompatibleInterfaceProperties(gtarget, ifaceProperties, "");
 
-    std::vector<std::string> configNames;
-    gtarget->Target->GetMakefile()->GetConfigurations(configNames);
+    std::vector<std::string> configNames =
+      gtarget->Target->GetMakefile()->GetGeneratorConfigs(
+        cmMakefile::ExcludeEmptyConfig);
 
     for (std::string const& cn : configNames) {
       getCompatibleInterfaceProperties(gtarget, ifaceProperties, cn);
@@ -762,13 +763,12 @@
     return;
   }
 
-  const char* propContent;
+  cmProp propContent;
 
-  if (const char* prop_suffixed =
+  if (cmProp prop_suffixed =
         target->GetProperty("LINK_INTERFACE_LIBRARIES" + suffix)) {
     propContent = prop_suffixed;
-  } else if (const char* prop =
-               target->GetProperty("LINK_INTERFACE_LIBRARIES")) {
+  } else if (cmProp prop = target->GetProperty("LINK_INTERFACE_LIBRARIES")) {
     propContent = prop;
   } else {
     return;
@@ -790,13 +790,13 @@
     return;
   }
 
-  if (!*propContent) {
+  if (propContent->empty()) {
     properties["IMPORTED_LINK_INTERFACE_LIBRARIES" + suffix].clear();
     return;
   }
 
   std::string prepro =
-    cmGeneratorExpression::Preprocess(propContent, preprocessRule);
+    cmGeneratorExpression::Preprocess(*propContent, preprocessRule);
   if (!prepro.empty()) {
     this->ResolveTargetsInGeneratorExpressions(prepro, target, missingTargets,
                                                ReplaceFreeTargets);
@@ -856,8 +856,8 @@
       cmGeneratorTarget::ManagedType::Native) {
     std::string prop = cmStrCat("IMPORTED_COMMON_LANGUAGE_RUNTIME", suffix);
     std::string propval;
-    if (auto* p = target->GetProperty("COMMON_LANGUAGE_RUNTIME")) {
-      propval = p;
+    if (cmProp p = target->GetProperty("COMMON_LANGUAGE_RUNTIME")) {
+      propval = *p;
     } else if (target->IsCSharpOnly()) {
       // C# projects do not have the /clr flag, so we set the property
       // here to mark the target as (only) managed (i.e. no .lib file
@@ -925,12 +925,14 @@
   /* clang-format on */
 
   // Isolate the file policy level.
-  // We use 2.6 here instead of the current version because newer
-  // versions of CMake should be able to export files imported by 2.6
-  // until the import format changes.
+  // Support CMake versions as far back as 2.6 but also support using NEW
+  // policy settings for up to CMake 3.17 (this upper limit may be reviewed
+  // and increased from time to time). This reduces the opportunity for CMake
+  // warnings when an older export file is later used with newer CMake
+  // versions.
   /* clang-format off */
   os << "cmake_policy(PUSH)\n"
-     << "cmake_policy(VERSION 2.6)\n";
+     << "cmake_policy(VERSION 2.6...3.17)\n";
   /* clang-format on */
 }
 
@@ -1116,7 +1118,7 @@
     return;
   }
   /* clang-format off */
-  os << "# Make sure the targets which have been exported in some other \n"
+  os << "# Make sure the targets which have been exported in some other\n"
         "# export set exist.\n"
         "unset(${CMAKE_FIND_PACKAGE_NAME}_NOT_FOUND_MESSAGE_targets)\n"
         "foreach(_target ";
@@ -1215,9 +1217,9 @@
   std::string& errorMessage)
 {
   auto& targetProperties = gte->Target->GetProperties();
-  if (const char* exportProperties =
+  if (cmProp exportProperties =
         targetProperties.GetPropertyValue("EXPORT_PROPERTIES")) {
-    for (auto& prop : cmExpandedList(exportProperties)) {
+    for (auto& prop : cmExpandedList(*exportProperties)) {
       /* Black list reserved properties */
       if (cmHasLiteralPrefix(prop, "IMPORTED_") ||
           cmHasLiteralPrefix(prop, "INTERFACE_")) {
@@ -1228,15 +1230,15 @@
         errorMessage = e.str();
         return false;
       }
-      auto propertyValue = targetProperties.GetPropertyValue(prop);
+      cmProp propertyValue = targetProperties.GetPropertyValue(prop);
       if (propertyValue == nullptr) {
         // Asked to export a property that isn't defined on the target. Do not
         // consider this an error, there's just nothing to export.
         continue;
       }
       std::string evaluatedValue = cmGeneratorExpression::Preprocess(
-        propertyValue, cmGeneratorExpression::StripAllGeneratorExpressions);
-      if (evaluatedValue != propertyValue) {
+        *propertyValue, cmGeneratorExpression::StripAllGeneratorExpressions);
+      if (evaluatedValue != *propertyValue) {
         std::ostringstream e;
         e << "Target \"" << gte->Target->GetName() << "\" contains property \""
           << prop << "\" in EXPORT_PROPERTIES but this property contains a "
@@ -1244,7 +1246,7 @@
         errorMessage = e.str();
         return false;
       }
-      properties[prop] = propertyValue;
+      properties[prop] = *propertyValue;
     }
   }
   return true;
diff --git a/Source/cmExportInstallAndroidMKGenerator.cxx b/Source/cmExportInstallAndroidMKGenerator.cxx
index 9702e0e..80f776e 100644
--- a/Source/cmExportInstallAndroidMKGenerator.cxx
+++ b/Source/cmExportInstallAndroidMKGenerator.cxx
@@ -66,7 +66,7 @@
   os << "LOCAL_MODULE := ";
   os << targetName << "\n";
   os << "LOCAL_SRC_FILES := $(_IMPORT_PREFIX)/";
-  os << target->Target->GetProperty("__dest") << "/";
+  os << target->Target->GetSafeProperty("__dest") << "/";
   std::string config;
   if (!this->Configurations.empty()) {
     config = this->Configurations[0];
diff --git a/Source/cmExportLibraryDependenciesCommand.cxx b/Source/cmExportLibraryDependenciesCommand.cxx
index 6011ba4..7f31dd2 100644
--- a/Source/cmExportLibraryDependenciesCommand.cxx
+++ b/Source/cmExportLibraryDependenciesCommand.cxx
@@ -14,6 +14,7 @@
 #include "cmGlobalGenerator.h"
 #include "cmLocalGenerator.h"
 #include "cmMakefile.h"
+#include "cmProperty.h"
 #include "cmStateTypes.h"
 #include "cmStringAlgorithms.h"
 #include "cmSystemTools.h"
@@ -95,8 +96,8 @@
           // Handle simple output name changes.  This command is
           // deprecated so we do not support full target name
           // translation (which requires per-configuration info).
-          if (const char* outname = libtgt->GetProperty("OUTPUT_NAME")) {
-            lib = outname;
+          if (cmProp outname = libtgt->GetProperty("OUTPUT_NAME")) {
+            lib = *outname;
           }
         }
         valueOld += lib;
diff --git a/Source/cmExportTryCompileFileGenerator.cxx b/Source/cmExportTryCompileFileGenerator.cxx
index 3df6a5c..c6b6184 100644
--- a/Source/cmExportTryCompileFileGenerator.cxx
+++ b/Source/cmExportTryCompileFileGenerator.cxx
@@ -12,6 +12,7 @@
 #include "cmGlobalGenerator.h"
 #include "cmLocalGenerator.h"
 #include "cmMakefile.h"
+#include "cmProperty.h"
 #include "cmStateTypes.h"
 #include "cmStringAlgorithms.h"
 #include "cmTarget.h"
@@ -58,7 +59,7 @@
   const std::string& propName, cmGeneratorTarget const* tgt,
   std::string const& language, std::set<cmGeneratorTarget const*>& emitted)
 {
-  const char* prop = tgt->GetProperty(propName);
+  cmProp prop = tgt->GetProperty(propName);
   if (!prop) {
     return std::string();
   }
@@ -67,11 +68,11 @@
 
   cmGeneratorExpressionDAGChecker dagChecker(tgt, propName, nullptr, nullptr);
 
-  std::unique_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(prop);
+  std::unique_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(*prop);
 
   cmTarget dummyHead("try_compile_dummy_exe", cmStateEnums::EXECUTABLE,
                      cmTarget::VisibilityNormal, tgt->Target->GetMakefile(),
-                     true);
+                     cmTarget::PerConfig::Yes);
 
   cmGeneratorTarget gDummyHead(&dummyHead, tgt->GetLocalGenerator());
 
@@ -95,11 +96,11 @@
   std::vector<std::string> props = target->GetPropertyKeys();
   for (std::string const& p : props) {
 
-    properties[p] = target->GetProperty(p);
+    properties[p] = *target->GetProperty(p);
 
-    if (p.find("IMPORTED_LINK_INTERFACE_LIBRARIES") == 0 ||
-        p.find("IMPORTED_LINK_DEPENDENT_LIBRARIES") == 0 ||
-        p.find("INTERFACE_LINK_LIBRARIES") == 0) {
+    if (cmHasLiteralPrefix(p, "IMPORTED_LINK_INTERFACE_LIBRARIES") ||
+        cmHasLiteralPrefix(p, "IMPORTED_LINK_DEPENDENT_LIBRARIES") ||
+        cmHasLiteralPrefix(p, "INTERFACE_LINK_LIBRARIES")) {
       std::string evalResult =
         this->FindTargets(p, target, std::string(), emitted);
 
diff --git a/Source/cmExprParserHelper.h b/Source/cmExprParserHelper.h
index eaf5dc7..717acdc 100644
--- a/Source/cmExprParserHelper.h
+++ b/Source/cmExprParserHelper.h
@@ -8,7 +8,7 @@
 #include <string>
 #include <vector>
 
-#include "cm_kwiml.h"
+#include <cm3p/kwiml/int.h>
 
 class cmExprParserHelper
 {
diff --git a/Source/cmExtraCodeBlocksGenerator.cxx b/Source/cmExtraCodeBlocksGenerator.cxx
index b710467..511168b 100644
--- a/Source/cmExtraCodeBlocksGenerator.cxx
+++ b/Source/cmExtraCodeBlocksGenerator.cxx
@@ -95,7 +95,7 @@
   std::string path; // only one component of the path
   std::vector<Tree> folders;
   std::set<std::string> files;
-  void InsertPath(const std::vector<std::string>& splitted,
+  void InsertPath(const std::vector<std::string>& split,
                   std::vector<std::string>::size_type start,
                   const std::string& fileName);
   void BuildVirtualFolder(cmXMLWriter& xml) const;
@@ -106,34 +106,34 @@
                      const std::string& fsPath) const;
 };
 
-void Tree::InsertPath(const std::vector<std::string>& splitted,
+void Tree::InsertPath(const std::vector<std::string>& split,
                       std::vector<std::string>::size_type start,
                       const std::string& fileName)
 {
-  if (start == splitted.size()) {
+  if (start == split.size()) {
     files.insert(fileName);
     return;
   }
   for (Tree& folder : folders) {
-    if (folder.path == splitted[start]) {
-      if (start + 1 < splitted.size()) {
-        folder.InsertPath(splitted, start + 1, fileName);
+    if (folder.path == split[start]) {
+      if (start + 1 < split.size()) {
+        folder.InsertPath(split, start + 1, fileName);
         return;
       }
-      // last part of splitted
+      // last part of split
       folder.files.insert(fileName);
       return;
     }
   }
   // Not found in folders, thus insert
   Tree newFolder;
-  newFolder.path = splitted[start];
-  if (start + 1 < splitted.size()) {
-    newFolder.InsertPath(splitted, start + 1, fileName);
+  newFolder.path = split[start];
+  if (start + 1 < split.size()) {
+    newFolder.InsertPath(split, start + 1, fileName);
     folders.push_back(newFolder);
     return;
   }
-  // last part of splitted
+  // last part of split
   newFolder.files.insert(fileName);
   folders.push_back(newFolder);
 }
@@ -218,17 +218,17 @@
     // Convert
     for (std::string const& listFile : listFiles) {
       // don't put cmake's own files into the project (#12110):
-      if (listFile.find(cmSystemTools::GetCMakeRoot()) == 0) {
+      if (cmHasPrefix(listFile, cmSystemTools::GetCMakeRoot())) {
         continue;
       }
 
       const std::string& relative = cmSystemTools::RelativePath(
         it.second[0]->GetSourceDirectory(), listFile);
-      std::vector<std::string> splitted;
-      cmSystemTools::SplitPath(relative, splitted, false);
+      std::vector<std::string> split;
+      cmSystemTools::SplitPath(relative, split, false);
       // Split filename from path
-      std::string fileName = *(splitted.end() - 1);
-      splitted.erase(splitted.end() - 1, splitted.end());
+      std::string fileName = *(split.end() - 1);
+      split.erase(split.end() - 1, split.end());
 
       // We don't want paths with CMakeFiles in them
       // or do we?
@@ -236,13 +236,12 @@
       //
       // Also we can disable external (outside the project) files by setting ON
       // CMAKE_CODEBLOCKS_EXCLUDE_EXTERNAL_FILES variable.
-      const bool excludeExternal =
-        cmIsOn(it.second[0]->GetMakefile()->GetSafeDefinition(
-          "CMAKE_CODEBLOCKS_EXCLUDE_EXTERNAL_FILES"));
-      if (!splitted.empty() &&
+      const bool excludeExternal = it.second[0]->GetMakefile()->IsOn(
+        "CMAKE_CODEBLOCKS_EXCLUDE_EXTERNAL_FILES");
+      if (!split.empty() &&
           (!excludeExternal || (relative.find("..") == std::string::npos)) &&
           relative.find("CMakeFiles") == std::string::npos) {
-        tree.InsertPath(splitted, 1, fileName);
+        tree.InsertPath(split, 1, fileName);
       }
     }
   }
@@ -301,11 +300,11 @@
         case cmStateEnums::UTILITY:
           // Add all utility targets, except the Nightly/Continuous/
           // Experimental-"sub"targets as e.g. NightlyStart
-          if (((targetName.find("Nightly") == 0) &&
+          if ((cmHasLiteralPrefix(targetName, "Nightly") &&
                (targetName != "Nightly")) ||
-              ((targetName.find("Continuous") == 0) &&
+              (cmHasLiteralPrefix(targetName, "Continuous") &&
                (targetName != "Continuous")) ||
-              ((targetName.find("Experimental") == 0) &&
+              (cmHasLiteralPrefix(targetName, "Experimental") &&
                (targetName != "Experimental"))) {
             break;
           }
@@ -370,7 +369,7 @@
             std::string lang = s->GetOrDetermineLanguage();
             if (lang == "C" || lang == "CXX" || lang == "CUDA") {
               std::string const& srcext = s->GetExtension();
-              isCFile = cm->IsSourceExtension(srcext);
+              isCFile = cm->IsACLikeSourceExtension(srcext);
             }
 
             std::string const& fullPath = s->ResolveFullPath();
@@ -380,9 +379,8 @@
               cmSystemTools::RelativePath(lg->GetSourceDirectory(), fullPath);
             // Do not add this file if it has ".." in relative path and
             // if CMAKE_CODEBLOCKS_EXCLUDE_EXTERNAL_FILES variable is on.
-            const bool excludeExternal =
-              cmIsOn(lg->GetMakefile()->GetSafeDefinition(
-                "CMAKE_CODEBLOCKS_EXCLUDE_EXTERNAL_FILES"));
+            const bool excludeExternal = lg->GetMakefile()->IsOn(
+              "CMAKE_CODEBLOCKS_EXCLUDE_EXTERNAL_FILES");
             if (excludeExternal &&
                 (relative.find("..") != std::string::npos)) {
               continue;
@@ -723,7 +721,7 @@
   if (generator == "NMake Makefiles" || generator == "NMake Makefiles JOM") {
     // For Windows ConvertToOutputPath already adds quotes when required.
     // These need to be escaped, see
-    // https://gitlab.kitware.com/cmake/cmake/issues/13952
+    // https://gitlab.kitware.com/cmake/cmake/-/issues/13952
     std::string makefileName = cmSystemTools::ConvertToOutputPath(makefile);
     command += " /NOLOGO /f ";
     command += makefileName;
@@ -731,7 +729,7 @@
     command += target;
   } else if (generator == "MinGW Makefiles") {
     // no escaping of spaces in this case, see
-    // https://gitlab.kitware.com/cmake/cmake/issues/10014
+    // https://gitlab.kitware.com/cmake/cmake/-/issues/10014
     std::string const& makefileName = makefile;
     command += " -f \"";
     command += makefileName;
diff --git a/Source/cmExtraCodeLiteGenerator.cxx b/Source/cmExtraCodeLiteGenerator.cxx
index de40c77..95cfb0a 100644
--- a/Source/cmExtraCodeLiteGenerator.cxx
+++ b/Source/cmExtraCodeLiteGenerator.cxx
@@ -204,9 +204,7 @@
     case cmStateEnums::STATIC_LIBRARY: {
       projectType = "Static Library";
     } break;
-    case cmStateEnums::SHARED_LIBRARY: {
-      projectType = "Dynamic Library";
-    } break;
+    case cmStateEnums::SHARED_LIBRARY:
     case cmStateEnums::MODULE_LIBRARY: {
       projectType = "Dynamic Library";
     } break;
@@ -229,8 +227,7 @@
           cmSystemTools::LowerCase(s->GetExtension());
         // check whether it is a source or a include file
         // then put it accordingly into one of the two containers
-        if (cm->IsSourceExtension(extLower) || cm->IsCudaExtension(extLower) ||
-            cm->IsFortranExtension(extLower)) {
+        if (cm->IsAKnownSourceExtension(extLower)) {
           cFiles[fullPath] = s;
         } else {
           otherFiles.insert(fullPath);
diff --git a/Source/cmExtraEclipseCDT4Generator.cxx b/Source/cmExtraEclipseCDT4Generator.cxx
index 78cabce..b6c0a7a 100644
--- a/Source/cmExtraEclipseCDT4Generator.cxx
+++ b/Source/cmExtraEclipseCDT4Generator.cxx
@@ -19,6 +19,7 @@
 #include "cmLocalGenerator.h"
 #include "cmMakefile.h"
 #include "cmMessageType.h"
+#include "cmProperty.h"
 #include "cmSourceFile.h"
 #include "cmSourceGroup.h"
 #include "cmState.h"
@@ -187,10 +188,10 @@
     return;
   }
 
-  fout << "eclipse.preferences.version=1" << std::endl;
+  fout << "eclipse.preferences.version=1\n";
   const char* encoding = mf->GetDefinition("CMAKE_ECLIPSE_RESOURCE_ENCODING");
   if (encoding) {
-    fout << "encoding/<project>=" << encoding << std::endl;
+    fout << "encoding/<project>=" << encoding << '\n';
   }
 }
 
@@ -243,8 +244,7 @@
   const bool envVarSet = cmSystemTools::GetEnv(envVar, envVarValue);
 
   std::string cacheEntryName = cmStrCat("CMAKE_ECLIPSE_ENVVAR_", envVar);
-  const std::string* cacheValue =
-    lg.GetState()->GetInitializedCacheValue(cacheEntryName);
+  cmProp cacheValue = lg.GetState()->GetInitializedCacheValue(cacheEntryName);
 
   // now we have both, decide which one to use
   std::string valueToUse;
@@ -255,8 +255,8 @@
     // The variable is in the env, but not in the cache. Use it and put it
     // in the cache
     valueToUse = envVarValue;
-    mf->AddCacheDefinition(cacheEntryName, valueToUse.c_str(),
-                           cacheEntryName.c_str(), cmStateEnums::STRING, true);
+    mf->AddCacheDefinition(cacheEntryName, valueToUse, cacheEntryName.c_str(),
+                           cmStateEnums::STRING, true);
     mf->GetCMakeInstance()->SaveCache(lg.GetBinaryDirectory());
   } else if (!envVarSet && cacheValue != nullptr) {
     // It is already in the cache, but not in the env, so use it from the cache
@@ -270,7 +270,7 @@
     valueToUse = *cacheValue;
     if (valueToUse.find(envVarValue) == std::string::npos) {
       valueToUse = envVarValue;
-      mf->AddCacheDefinition(cacheEntryName, valueToUse.c_str(),
+      mf->AddCacheDefinition(cacheEntryName, valueToUse,
                              cacheEntryName.c_str(), cmStateEnums::STRING,
                              true);
       mf->GetCMakeInstance()->SaveCache(lg.GetBinaryDirectory());
@@ -415,9 +415,9 @@
     xml.Element("nature", n);
   }
 
-  if (const char* extraNaturesProp =
+  if (cmProp extraNaturesProp =
         mf->GetState()->GetGlobalProperty("ECLIPSE_EXTRA_NATURES")) {
-    std::vector<std::string> extraNatures = cmExpandedList(extraNaturesProp);
+    std::vector<std::string> extraNatures = cmExpandedList(*extraNaturesProp);
     for (std::string const& n : extraNatures) {
       xml.Element("nature", n);
     }
@@ -430,7 +430,7 @@
   if (this->IsOutOfSourceBuild) {
     // create a linked resource to CMAKE_SOURCE_DIR
     // (this is not done anymore for each project because of
-    // https://gitlab.kitware.com/cmake/cmake/issues/9978 and because I found
+    // https://gitlab.kitware.com/cmake/cmake/-/issues/9978 and because I found
     // it actually quite confusing in bigger projects with many directories and
     // projects, Alex
 
@@ -604,7 +604,7 @@
 
 void cmExtraEclipseCDT4Generator::CreateCProjectFile() const
 {
-  std::set<std::string> emmited;
+  std::set<std::string> emitted;
 
   const auto& lg = this->GlobalGenerator->GetLocalGenerators()[0];
   const cmMakefile* mf = lg->GetMakefile();
@@ -751,14 +751,14 @@
   xml.EndElement();
 
   // add pre-processor definitions to allow eclipse to gray out sections
-  emmited.clear();
+  emitted.clear();
   for (const auto& lgen : this->GlobalGenerator->GetLocalGenerators()) {
 
-    if (const char* cdefs =
+    if (cmProp cdefs =
           lgen->GetMakefile()->GetProperty("COMPILE_DEFINITIONS")) {
       // Expand the list.
       std::vector<std::string> defs;
-      cmGeneratorExpression::Split(cdefs, defs);
+      cmGeneratorExpression::Split(*cdefs, defs);
 
       for (std::string const& d : defs) {
         if (cmGeneratorExpression::Find(d) != std::string::npos) {
@@ -780,8 +780,8 @@
         }
 
         // insert the definition if not already added.
-        if (emmited.find(def) == emmited.end()) {
-          emmited.insert(def);
+        if (emitted.find(def) == emitted.end()) {
+          emitted.insert(def);
           xml.StartElement("pathentry");
           xml.Attribute("kind", "mac");
           xml.Attribute("name", def);
@@ -812,8 +812,8 @@
         }
 
         // insert the definition if not already added.
-        if (emmited.find(def) == emmited.end()) {
-          emmited.insert(def);
+        if (emitted.find(def) == emitted.end()) {
+          emitted.insert(def);
           xml.StartElement("pathentry");
           xml.Attribute("kind", "mac");
           xml.Attribute("name", def);
@@ -844,8 +844,8 @@
         }
 
         // insert the definition if not already added.
-        if (emmited.find(def) == emmited.end()) {
-          emmited.insert(def);
+        if (emitted.find(def) == emitted.end()) {
+          emitted.insert(def);
           xml.StartElement("pathentry");
           xml.Attribute("kind", "mac");
           xml.Attribute("name", def);
@@ -858,7 +858,7 @@
   }
 
   // include dirs
-  emmited.clear();
+  emitted.clear();
   for (const auto& lgen : this->GlobalGenerator->GetLocalGenerators()) {
     const auto& targets = lgen->GetGeneratorTargets();
     for (const auto& target : targets) {
@@ -868,7 +868,7 @@
       std::vector<std::string> includeDirs;
       std::string config = mf->GetSafeDefinition("CMAKE_BUILD_TYPE");
       lgen->GetIncludeDirectories(includeDirs, target.get(), "C", config);
-      this->AppendIncludeDirectories(xml, includeDirs, emmited);
+      this->AppendIncludeDirectories(xml, includeDirs, emitted);
     }
   }
   // now also the system include directories, in case we found them in
@@ -879,14 +879,14 @@
     std::string systemIncludeDirs =
       mf->GetSafeDefinition("CMAKE_EXTRA_GENERATOR_C_SYSTEM_INCLUDE_DIRS");
     std::vector<std::string> dirs = cmExpandedList(systemIncludeDirs);
-    this->AppendIncludeDirectories(xml, dirs, emmited);
+    this->AppendIncludeDirectories(xml, dirs, emitted);
   }
   compiler = mf->GetSafeDefinition("CMAKE_CXX_COMPILER");
   if (this->CXXEnabled && !compiler.empty()) {
     std::string systemIncludeDirs =
       mf->GetSafeDefinition("CMAKE_EXTRA_GENERATOR_CXX_SYSTEM_INCLUDE_DIRS");
     std::vector<std::string> dirs = cmExpandedList(systemIncludeDirs);
-    this->AppendIncludeDirectories(xml, dirs, emmited);
+    this->AppendIncludeDirectories(xml, dirs, emitted);
   }
 
   xml.EndElement(); // storageModule
@@ -895,7 +895,7 @@
   xml.StartElement("storageModule");
   xml.Attribute("moduleId", "org.eclipse.cdt.make.core.buildtargets");
   xml.StartElement("buildTargets");
-  emmited.clear();
+  emitted.clear();
   const std::string& make = mf->GetRequiredDefinition("CMAKE_MAKE_PROGRAM");
   const std::string& makeArgs =
     mf->GetSafeDefinition("CMAKE_ECLIPSE_MAKE_ARGUMENTS");
@@ -936,11 +936,11 @@
         case cmStateEnums::UTILITY:
           // Add all utility targets, except the Nightly/Continuous/
           // Experimental-"sub"targets as e.g. NightlyStart
-          if (((targetName.find("Nightly") == 0) &&
+          if ((cmHasLiteralPrefix(targetName, "Nightly") &&
                (targetName != "Nightly")) ||
-              ((targetName.find("Continuous") == 0) &&
+              (cmHasLiteralPrefix(targetName, "Continuous") &&
                (targetName != "Continuous")) ||
-              ((targetName.find("Experimental") == 0) &&
+              (cmHasLiteralPrefix(targetName, "Experimental") &&
                (targetName != "Experimental"))) {
             break;
           }
@@ -981,7 +981,6 @@
           }
         } break;
         case cmStateEnums::INTERFACE_LIBRARY:
-          break;
         default:
           break;
       }
@@ -1033,9 +1032,9 @@
   xml.EndElement(); // storageModule
 
   // Append additional cproject contents without applying any XML formatting
-  if (const char* extraCProjectContents =
+  if (cmProp extraCProjectContents =
         mf->GetState()->GetGlobalProperty("ECLIPSE_EXTRA_CPROJECT_CONTENTS")) {
-    fout << extraCProjectContents;
+    fout << *extraCProjectContents;
   }
 
   xml.EndElement(); // cproject
diff --git a/Source/cmExtraKateGenerator.cxx b/Source/cmExtraKateGenerator.cxx
index 3a22846..01fac5a 100644
--- a/Source/cmExtraKateGenerator.cxx
+++ b/Source/cmExtraKateGenerator.cxx
@@ -129,9 +129,8 @@
             if (targetName == "edit_cache") {
               const char* editCommand =
                 localGen->GetMakefile()->GetDefinition("CMAKE_EDIT_COMMAND");
-              if (editCommand == nullptr) {
-                insertTarget = false;
-              } else if (strstr(editCommand, "ccmake") != nullptr) {
+              if (editCommand == nullptr ||
+                  strstr(editCommand, "ccmake") != nullptr) {
                 insertTarget = false;
               }
             }
@@ -144,11 +143,11 @@
         case cmStateEnums::UTILITY:
           // Add all utility targets, except the Nightly/Continuous/
           // Experimental-"sub"targets as e.g. NightlyStart
-          if (((targetName.find("Nightly") == 0) &&
+          if ((cmHasLiteralPrefix(targetName, "Nightly") &&
                (targetName != "Nightly")) ||
-              ((targetName.find("Continuous") == 0) &&
+              (cmHasLiteralPrefix(targetName, "Continuous") &&
                (targetName != "Continuous")) ||
-              ((targetName.find("Experimental") == 0) &&
+              (cmHasLiteralPrefix(targetName, "Experimental") &&
                (targetName != "Experimental"))) {
             break;
           }
@@ -274,7 +273,7 @@
   const std::string& name, const std::string& type,
   const std::string& path) const
 {
-  return name + (type.empty() ? "" : "-") + type + "@" + path;
+  return name + (type.empty() ? "" : "-") + type + '@' + path;
 }
 
 std::string cmExtraKateGenerator::GetPathBasename(
diff --git a/Source/cmExtraSublimeTextGenerator.cxx b/Source/cmExtraSublimeTextGenerator.cxx
index 413449c..3e265a0 100644
--- a/Source/cmExtraSublimeTextGenerator.cxx
+++ b/Source/cmExtraSublimeTextGenerator.cxx
@@ -17,6 +17,7 @@
 #include "cmLocalGenerator.h"
 #include "cmMakefile.h"
 #include "cmMessageType.h"
+#include "cmProperty.h"
 #include "cmSourceFile.h"
 #include "cmStateTypes.h"
 #include "cmStringAlgorithms.h"
@@ -199,11 +200,11 @@
         case cmStateEnums::UTILITY:
           // Add all utility targets, except the Nightly/Continuous/
           // Experimental-"sub"targets as e.g. NightlyStart
-          if (((targetName.find("Nightly") == 0) &&
+          if ((cmHasLiteralPrefix(targetName, "Nightly") &&
                (targetName != "Nightly")) ||
-              ((targetName.find("Continuous") == 0) &&
+              (cmHasLiteralPrefix(targetName, "Continuous") &&
                (targetName != "Continuous")) ||
-              ((targetName.find("Experimental") == 0) &&
+              (cmHasLiteralPrefix(targetName, "Experimental") &&
                (targetName != "Experimental"))) {
             break;
           }
@@ -327,7 +328,7 @@
     std::string makefileName;
     if (generator == "MinGW Makefiles") {
       // no escaping of spaces in this case, see
-      // https://gitlab.kitware.com/cmake/cmake/issues/10014
+      // https://gitlab.kitware.com/cmake/cmake/-/issues/10014
       makefileName = makefile;
     } else {
       makefileName = cmSystemTools::ConvertToOutputPath(makefile);
@@ -348,6 +349,13 @@
   if (language.empty()) {
     language = "C";
   }
+
+  // explicitly add the explicit language flag before any other flag
+  // this way backwards compatibility with user flags is maintained
+  if (source->GetProperty("LANGUAGE")) {
+    lg->AppendFeatureOptions(flags, language, "EXPLICIT_LANGUAGE");
+  }
+
   std::string const& config =
     lg->GetMakefile()->GetSafeDefinition("CMAKE_BUILD_TYPE");
 
@@ -358,14 +366,14 @@
                                                     language);
 
   const std::string COMPILE_FLAGS("COMPILE_FLAGS");
-  if (const char* cflags = source->GetProperty(COMPILE_FLAGS)) {
-    lg->AppendFlags(flags, genexInterpreter.Evaluate(cflags, COMPILE_FLAGS));
+  if (cmProp cflags = source->GetProperty(COMPILE_FLAGS)) {
+    lg->AppendFlags(flags, genexInterpreter.Evaluate(*cflags, COMPILE_FLAGS));
   }
 
   const std::string COMPILE_OPTIONS("COMPILE_OPTIONS");
-  if (const char* coptions = source->GetProperty(COMPILE_OPTIONS)) {
+  if (cmProp coptions = source->GetProperty(COMPILE_OPTIONS)) {
     lg->AppendCompileOptions(
-      flags, genexInterpreter.Evaluate(coptions, COMPILE_OPTIONS));
+      flags, genexInterpreter.Evaluate(*coptions, COMPILE_OPTIONS));
   }
 
   return flags;
@@ -387,17 +395,17 @@
   // Add preprocessor definitions for this target and configuration.
   lg->GetTargetDefines(target, config, language, defines);
   const std::string COMPILE_DEFINITIONS("COMPILE_DEFINITIONS");
-  if (const char* compile_defs = source->GetProperty(COMPILE_DEFINITIONS)) {
+  if (cmProp compile_defs = source->GetProperty(COMPILE_DEFINITIONS)) {
     lg->AppendDefines(
-      defines, genexInterpreter.Evaluate(compile_defs, COMPILE_DEFINITIONS));
+      defines, genexInterpreter.Evaluate(*compile_defs, COMPILE_DEFINITIONS));
   }
 
   std::string defPropName =
     cmStrCat("COMPILE_DEFINITIONS_", cmSystemTools::UpperCase(config));
-  if (const char* config_compile_defs = source->GetProperty(defPropName)) {
+  if (cmProp config_compile_defs = source->GetProperty(defPropName)) {
     lg->AppendDefines(
       defines,
-      genexInterpreter.Evaluate(config_compile_defs, COMPILE_DEFINITIONS));
+      genexInterpreter.Evaluate(*config_compile_defs, COMPILE_DEFINITIONS));
   }
 
   std::string definesString;
@@ -419,9 +427,9 @@
 
   // Add include directories for this source file
   const std::string INCLUDE_DIRECTORIES("INCLUDE_DIRECTORIES");
-  if (const char* cincludes = source->GetProperty(INCLUDE_DIRECTORIES)) {
+  if (cmProp cincludes = source->GetProperty(INCLUDE_DIRECTORIES)) {
     lg->AppendIncludeDirectories(
-      includes, genexInterpreter.Evaluate(cincludes, INCLUDE_DIRECTORIES),
+      includes, genexInterpreter.Evaluate(*cincludes, INCLUDE_DIRECTORIES),
       *source);
   }
 
diff --git a/Source/cmFileAPI.cxx b/Source/cmFileAPI.cxx
index a56ad22..c2ab2f1 100644
--- a/Source/cmFileAPI.cxx
+++ b/Source/cmFileAPI.cxx
@@ -665,7 +665,7 @@
 
 // The "codemodel" object kind.
 
-static unsigned int const CodeModelV2Minor = 0;
+static unsigned int const CodeModelV2Minor = 2;
 
 void cmFileAPI::BuildClientRequestCodeModel(
   ClientRequest& r, std::vector<RequestVersion> const& versions)
diff --git a/Source/cmFileAPI.h b/Source/cmFileAPI.h
index e183e0d..ae07612 100644
--- a/Source/cmFileAPI.h
+++ b/Source/cmFileAPI.h
@@ -11,9 +11,9 @@
 #include <unordered_set>
 #include <vector>
 
-#include "cm_jsoncpp_reader.h"
-#include "cm_jsoncpp_value.h"
-#include "cm_jsoncpp_writer.h"
+#include <cm3p/json/reader.h>
+#include <cm3p/json/value.h>
+#include <cm3p/json/writer.h>
 
 class cmake;
 
diff --git a/Source/cmFileAPICMakeFiles.cxx b/Source/cmFileAPICMakeFiles.cxx
index 44ba96c..1e4f3b6 100644
--- a/Source/cmFileAPICMakeFiles.cxx
+++ b/Source/cmFileAPICMakeFiles.cxx
@@ -6,7 +6,7 @@
 #include <string>
 #include <vector>
 
-#include "cm_jsoncpp_value.h"
+#include <cm3p/json/value.h>
 
 #include "cmFileAPI.h"
 #include "cmGlobalGenerator.h"
diff --git a/Source/cmFileAPICMakeFiles.h b/Source/cmFileAPICMakeFiles.h
index a851c32..1ae1e4f 100644
--- a/Source/cmFileAPICMakeFiles.h
+++ b/Source/cmFileAPICMakeFiles.h
@@ -5,7 +5,7 @@
 
 #include "cmConfigure.h" // IWYU pragma: keep
 
-#include "cm_jsoncpp_value.h"
+#include <cm3p/json/value.h>
 
 class cmFileAPI;
 
diff --git a/Source/cmFileAPICache.cxx b/Source/cmFileAPICache.cxx
index ef77795..3ba943a 100644
--- a/Source/cmFileAPICache.cxx
+++ b/Source/cmFileAPICache.cxx
@@ -7,9 +7,10 @@
 #include <utility>
 #include <vector>
 
-#include "cm_jsoncpp_value.h"
+#include <cm3p/json/value.h>
 
 #include "cmFileAPI.h"
+#include "cmProperty.h"
 #include "cmState.h"
 #include "cmake.h"
 
@@ -67,7 +68,7 @@
   entry["name"] = name;
   entry["type"] =
     cmState::CacheEntryTypeToString(this->State->GetCacheEntryType(name));
-  entry["value"] = this->State->GetCacheEntryValue(name);
+  entry["value"] = this->State->GetSafeCacheEntryValue(name);
 
   Json::Value properties = this->DumpEntryProperties(name);
   if (!properties.empty()) {
@@ -94,7 +95,8 @@
 {
   Json::Value property = Json::objectValue;
   property["name"] = prop;
-  property["value"] = this->State->GetCacheEntryProperty(name, prop);
+  cmProp p = this->State->GetCacheEntryProperty(name, prop);
+  property["value"] = p ? *p : "";
   return property;
 }
 }
diff --git a/Source/cmFileAPICache.h b/Source/cmFileAPICache.h
index 09d9e1c..2f30c76 100644
--- a/Source/cmFileAPICache.h
+++ b/Source/cmFileAPICache.h
@@ -5,7 +5,7 @@
 
 #include "cmConfigure.h" // IWYU pragma: keep
 
-#include "cm_jsoncpp_value.h"
+#include <cm3p/json/value.h>
 
 class cmFileAPI;
 
diff --git a/Source/cmFileAPICodemodel.cxx b/Source/cmFileAPICodemodel.cxx
index 955195f..55fb115 100644
--- a/Source/cmFileAPICodemodel.cxx
+++ b/Source/cmFileAPICodemodel.cxx
@@ -17,7 +17,7 @@
 
 #include <cmext/algorithm>
 
-#include "cm_jsoncpp_value.h"
+#include <cm3p/json/value.h>
 
 #include "cmCryptoHash.h"
 #include "cmFileAPI.h"
@@ -31,6 +31,7 @@
 #include "cmListFileCache.h"
 #include "cmLocalGenerator.h"
 #include "cmMakefile.h"
+#include "cmProperty.h"
 #include "cmSourceFile.h"
 #include "cmSourceGroup.h"
 #include "cmState.h"
@@ -174,6 +175,38 @@
   }
 };
 
+template <typename T>
+class JBTs
+{
+public:
+  JBTs(T v = T(), std::vector<JBTIndex> ids = std::vector<JBTIndex>())
+    : Value(std::move(v))
+    , Backtraces(std::move(ids))
+  {
+  }
+  T Value;
+  std::vector<JBTIndex> Backtraces;
+  friend bool operator==(JBTs<T> const& l, JBTs<T> const& r)
+  {
+    if ((l.Value == r.Value) && (l.Backtraces.size() == r.Backtraces.size())) {
+      for (size_t i = 0; i < l.Backtraces.size(); i++) {
+        if (l.Backtraces[i].Index != r.Backtraces[i].Index) {
+          return false;
+        }
+      }
+    }
+    return true;
+  }
+  static bool ValueEq(JBTs<T> const& l, JBTs<T> const& r)
+  {
+    return l.Value == r.Value;
+  }
+  static bool ValueLess(JBTs<T> const& l, JBTs<T> const& r)
+  {
+    return l.Value < r.Value;
+  }
+};
+
 class BacktraceData
 {
   std::string TopSource;
@@ -276,14 +309,18 @@
 
   std::string Language;
   std::string Sysroot;
+  JBTs<std::string> LanguageStandard;
   std::vector<JBT<std::string>> Flags;
   std::vector<JBT<std::string>> Defines;
+  std::vector<JBT<std::string>> PrecompileHeaders;
   std::vector<IncludeEntry> Includes;
 
   friend bool operator==(CompileData const& l, CompileData const& r)
   {
     return (l.Language == r.Language && l.Sysroot == r.Sysroot &&
             l.Flags == r.Flags && l.Defines == r.Defines &&
+            l.PrecompileHeaders == r.PrecompileHeaders &&
+            l.LanguageStandard == r.LanguageStandard &&
             l.Includes == r.Includes);
   }
 };
@@ -313,6 +350,16 @@
       result = result ^ hash<std::string>()(i.Value) ^
         hash<Json::ArrayIndex>()(i.Backtrace.Index);
     }
+    for (auto const& i : in.PrecompileHeaders) {
+      result = result ^ hash<std::string>()(i.Value) ^
+        hash<Json::ArrayIndex>()(i.Backtrace.Index);
+    }
+    if (!in.LanguageStandard.Value.empty()) {
+      result = result ^ hash<std::string>()(in.LanguageStandard.Value);
+      for (JBTIndex backtrace : in.LanguageStandard.Backtraces) {
+        result = result ^ hash<Json::ArrayIndex>()(backtrace.Index);
+      }
+    }
     return result;
   }
 };
@@ -356,6 +403,16 @@
     return JBT<T>(bt.Value, this->Backtraces.Add(bt.Backtrace));
   }
 
+  template <typename T>
+  JBTs<T> ToJBTs(BTs<T> const& bts)
+  {
+    std::vector<JBTIndex> ids;
+    for (cmListFileBacktrace const& backtrace : bts.Backtraces) {
+      ids.emplace_back(this->Backtraces.Add(backtrace));
+    }
+    return JBTs<T>(bts.Value, ids);
+  }
+
   void ProcessLanguages();
   void ProcessLanguage(std::string const& lang);
 
@@ -369,6 +426,8 @@
   Json::Value DumpPaths();
   Json::Value DumpCompileData(CompileData const& cd);
   Json::Value DumpInclude(CompileData::IncludeEntry const& inc);
+  Json::Value DumpPrecompileHeader(JBT<std::string> const& header);
+  Json::Value DumpLanguageStandard(JBTs<std::string> const& standard);
   Json::Value DumpDefine(JBT<std::string> const& def);
   Json::Value DumpSources();
   Json::Value DumpSource(cmGeneratorTarget::SourceAndKind const& sk,
@@ -430,7 +489,7 @@
   const auto& makefiles = gg->GetMakefiles();
   if (!makefiles.empty()) {
     std::vector<std::string> const& configs =
-      makefiles[0]->GetGeneratorConfigs();
+      makefiles[0]->GetGeneratorConfigs(cmMakefile::IncludeEmptyConfig);
     for (std::string const& config : configs) {
       configurations.append(this->DumpConfiguration(config));
     }
@@ -566,7 +625,7 @@
 
   for (cmGeneratorTarget* gt : targetList) {
     if (gt->GetType() == cmStateEnums::GLOBAL_TARGET ||
-        gt->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
+        !gt->IsInBuildSystem()) {
       continue;
     }
 
@@ -825,6 +884,16 @@
       this->ToJBT(i),
       this->GT->IsSystemIncludeDirectory(i.Value, this->Config, lang));
   }
+  std::vector<BT<std::string>> precompileHeaders =
+    this->GT->GetPrecompileHeaders(this->Config, lang);
+  for (BT<std::string> const& pch : precompileHeaders) {
+    cd.PrecompileHeaders.emplace_back(this->ToJBT(pch));
+  }
+  BTs<std::string> const* languageStandard =
+    this->GT->GetLanguageStandardProperty(lang, this->Config);
+  if (languageStandard) {
+    cd.LanguageStandard = this->ToJBTs(*languageStandard);
+  }
 }
 
 Json::ArrayIndex Target::AddSourceGroup(cmSourceGroup* sg, Json::ArrayIndex si)
@@ -855,8 +924,8 @@
                                                     fd.Language);
 
   const std::string COMPILE_FLAGS("COMPILE_FLAGS");
-  if (const char* cflags = sf->GetProperty(COMPILE_FLAGS)) {
-    std::string flags = genexInterpreter.Evaluate(cflags, COMPILE_FLAGS);
+  if (cmProp cflags = sf->GetProperty(COMPILE_FLAGS)) {
+    std::string flags = genexInterpreter.Evaluate(*cflags, COMPILE_FLAGS);
     fd.Flags.emplace_back(std::move(flags), JBTIndex());
   }
   const std::string COMPILE_OPTIONS("COMPILE_OPTIONS");
@@ -872,14 +941,27 @@
   }
 
   // Add precompile headers compile options.
-  const std::string pchSource =
-    this->GT->GetPchSource(this->Config, fd.Language);
+  std::vector<std::string> architectures;
+  this->GT->GetAppleArchs(this->Config, architectures);
+  if (architectures.empty()) {
+    architectures.emplace_back();
+  }
 
-  if (!pchSource.empty() && !sf->GetProperty("SKIP_PRECOMPILE_HEADERS")) {
+  std::unordered_map<std::string, std::string> pchSources;
+  for (const std::string& arch : architectures) {
+    const std::string pchSource =
+      this->GT->GetPchSource(this->Config, fd.Language, arch);
+    if (!pchSource.empty()) {
+      pchSources.insert(std::make_pair(pchSource, arch));
+    }
+  }
+
+  if (!pchSources.empty() && !sf->GetProperty("SKIP_PRECOMPILE_HEADERS")) {
     std::string pchOptions;
-    if (sf->ResolveFullPath() == pchSource) {
-      pchOptions =
-        this->GT->GetPchCreateCompileOptions(this->Config, fd.Language);
+    auto pchIt = pchSources.find(sf->ResolveFullPath());
+    if (pchIt != pchSources.end()) {
+      pchOptions = this->GT->GetPchCreateCompileOptions(
+        this->Config, fd.Language, pchIt->second);
     } else {
       pchOptions =
         this->GT->GetPchUseCompileOptions(this->Config, fd.Language);
@@ -936,10 +1018,10 @@
   std::set<std::string> configFileDefines;
   const std::string defPropName =
     "COMPILE_DEFINITIONS_" + cmSystemTools::UpperCase(this->Config);
-  if (const char* config_defs = sf->GetProperty(defPropName)) {
+  if (cmProp config_defs = sf->GetProperty(defPropName)) {
     lg->AppendDefines(
       configFileDefines,
-      genexInterpreter.Evaluate(config_defs, COMPILE_DEFINITIONS));
+      genexInterpreter.Evaluate(*config_defs, COMPILE_DEFINITIONS));
   }
 
   fd.Defines.reserve(fileDefines.size() + configFileDefines.size());
@@ -967,6 +1049,12 @@
   // All compile groups share the sysroot of the target.
   cd.Sysroot = td.Sysroot;
 
+  // All compile groups share the precompile headers of the target.
+  cd.PrecompileHeaders = td.PrecompileHeaders;
+
+  // All compile groups share the language standard of the target.
+  cd.LanguageStandard = td.LanguageStandard;
+
   // Use target-wide flags followed by source-specific flags.
   cd.Flags.reserve(td.Flags.size() + fd.Flags.size());
   cd.Flags.insert(cd.Flags.end(), td.Flags.begin(), td.Flags.end());
@@ -1117,6 +1205,17 @@
     }
     result["defines"] = std::move(defines);
   }
+  if (!cd.PrecompileHeaders.empty()) {
+    Json::Value precompileHeaders = Json::arrayValue;
+    for (JBT<std::string> const& pch : cd.PrecompileHeaders) {
+      precompileHeaders.append(this->DumpPrecompileHeader(pch));
+    }
+    result["precompileHeaders"] = std::move(precompileHeaders);
+  }
+  if (!cd.LanguageStandard.Value.empty()) {
+    result["languageStandard"] =
+      this->DumpLanguageStandard(cd.LanguageStandard);
+  }
 
   return result;
 }
@@ -1132,6 +1231,28 @@
   return include;
 }
 
+Json::Value Target::DumpPrecompileHeader(JBT<std::string> const& header)
+{
+  Json::Value precompileHeader = Json::objectValue;
+  precompileHeader["header"] = header.Value;
+  this->AddBacktrace(precompileHeader, header.Backtrace);
+  return precompileHeader;
+}
+
+Json::Value Target::DumpLanguageStandard(JBTs<std::string> const& standard)
+{
+  Json::Value languageStandard = Json::objectValue;
+  languageStandard["standard"] = standard.Value;
+  if (!standard.Backtraces.empty()) {
+    Json::Value backtraces = Json::arrayValue;
+    for (JBTIndex backtrace : standard.Backtraces) {
+      backtraces.append(backtrace.Index);
+    }
+    languageStandard["backtraces"] = backtraces;
+  }
+  return languageStandard;
+}
+
 Json::Value Target::DumpDefine(JBT<std::string> const& def)
 {
   Json::Value define = Json::objectValue;
@@ -1411,9 +1532,9 @@
 Json::Value Target::DumpFolder()
 {
   Json::Value folder;
-  if (const char* f = this->GT->GetProperty("FOLDER")) {
+  if (cmProp f = this->GT->GetProperty("FOLDER")) {
     folder = Json::objectValue;
-    folder["name"] = f;
+    folder["name"] = *f;
   }
   return folder;
 }
diff --git a/Source/cmFileAPICodemodel.h b/Source/cmFileAPICodemodel.h
index ffbd928..a6c6bdd 100644
--- a/Source/cmFileAPICodemodel.h
+++ b/Source/cmFileAPICodemodel.h
@@ -5,7 +5,7 @@
 
 #include "cmConfigure.h" // IWYU pragma: keep
 
-#include "cm_jsoncpp_value.h"
+#include <cm3p/json/value.h>
 
 class cmFileAPI;
 
diff --git a/Source/cmFileCommand.cxx b/Source/cmFileCommand.cxx
index e36abdc..8d20d35 100644
--- a/Source/cmFileCommand.cxx
+++ b/Source/cmFileCommand.cxx
@@ -16,13 +16,14 @@
 
 #include <cm/memory>
 #include <cmext/algorithm>
+#include <cmext/string_view>
+
+#include <cm3p/kwiml/int.h>
 
 #include "cmsys/FStream.hxx"
 #include "cmsys/Glob.hxx"
 #include "cmsys/RegularExpression.hxx"
 
-#include "cm_kwiml.h"
-#include "cm_static_string_view.hxx"
 #include "cm_sys_stat.h"
 
 #include "cmAlgorithms.h"
@@ -33,12 +34,14 @@
 #include "cmFileInstaller.h"
 #include "cmFileLockPool.h"
 #include "cmFileTimes.h"
+#include "cmGeneratedFileStream.h"
 #include "cmGeneratorExpression.h"
 #include "cmGlobalGenerator.h"
 #include "cmHexFileConverter.h"
 #include "cmListFileCache.h"
 #include "cmMakefile.h"
 #include "cmMessageType.h"
+#include "cmNewLineStyle.h"
 #include "cmPolicies.h"
 #include "cmRange.h"
 #include "cmRuntimeDependencyArchive.h"
@@ -47,10 +50,11 @@
 #include "cmSubcommandTable.h"
 #include "cmSystemTools.h"
 #include "cmTimestamp.h"
+#include "cmWorkingDirectory.h"
 #include "cmake.h"
 
 #if !defined(CMAKE_BOOTSTRAP)
-#  include "cm_curl.h"
+#  include <cm3p/curl/curl.h>
 
 #  include "cmCurl.h"
 #  include "cmFileLockResult.h"
@@ -672,12 +676,12 @@
     }
   }
 
+  cmake* cm = status.GetMakefile().GetCMakeInstance();
   std::vector<std::string> files;
   bool configureDepends = false;
   bool warnConfigureLate = false;
   bool warnFollowedSymlinks = false;
-  const cmake::WorkingMode workingMode =
-    status.GetMakefile().GetCMakeInstance()->GetWorkingMode();
+  const cmake::WorkingMode workingMode = cm->GetWorkingMode();
   while (i != args.end()) {
     if (*i == "LIST_DIRECTORIES") {
       ++i; // skip LIST_DIRECTORIES
@@ -765,12 +769,17 @@
               MessageType::AUTHOR_WARNING,
               "Cyclic recursion detected while globbing for '" + *i + "':\n" +
                 globMessage.content);
-          } else {
+          } else if (globMessage.type == cmsys::Glob::error) {
             status.GetMakefile().IssueMessage(
               MessageType::FATAL_ERROR,
               "Error has occurred while globbing for '" + *i + "' - " +
                 globMessage.content);
             shouldExit = true;
+          } else if (cm->GetDebugOutput() || cm->GetTrace()) {
+            status.GetMakefile().IssueMessage(
+              MessageType::LOG,
+              cmStrCat("Globbing for\n  ", *i, "\nEncountered an error:\n ",
+                       globMessage.content));
           }
         }
         if (shouldExit) {
@@ -790,7 +799,7 @@
         std::sort(foundFiles.begin(), foundFiles.end());
         foundFiles.erase(std::unique(foundFiles.begin(), foundFiles.end()),
                          foundFiles.end());
-        status.GetMakefile().GetCMakeInstance()->AddGlobCacheEntry(
+        cm->AddGlobCacheEntry(
           recurse, (recurse ? g.GetRecurseListDirs() : g.GetListDirs()),
           (recurse ? g.GetRecurseThroughSymlinks() : false),
           (g.GetRelative() ? g.GetRelative() : ""), expr, foundFiles, variable,
@@ -1385,8 +1394,10 @@
 {
   int realsize = static_cast<int>(size * nmemb);
   cmsys::ofstream* fout = static_cast<cmsys::ofstream*>(data);
-  const char* chPtr = static_cast<char*>(ptr);
-  fout->write(chPtr, realsize);
+  if (fout) {
+    const char* chPtr = static_cast<char*>(ptr);
+    fout->write(chPtr, realsize);
+  }
   return realsize;
 }
 
@@ -1542,15 +1553,14 @@
 {
 #if !defined(CMAKE_BOOTSTRAP)
   auto i = args.begin();
-  if (args.size() < 3) {
-    status.SetError("DOWNLOAD must be called with at least three arguments.");
+  if (args.size() < 2) {
+    status.SetError("DOWNLOAD must be called with at least two arguments.");
     return false;
   }
   ++i; // Get rid of subcommand
   std::string url = *i;
   ++i;
-  std::string file = *i;
-  ++i;
+  std::string file;
 
   long timeout = 0;
   long inactivity_timeout = 0;
@@ -1606,7 +1616,7 @@
       if (i != args.end()) {
         tls_verify = cmIsOn(*i);
       } else {
-        status.SetError("TLS_VERIFY missing bool value.");
+        status.SetError("DOWNLOAD missing bool value for TLS_VERIFY.");
         return false;
       }
     } else if (*i == "TLS_CAINFO") {
@@ -1614,7 +1624,7 @@
       if (i != args.end()) {
         cainfo = i->c_str();
       } else {
-        status.SetError("TLS_CAFILE missing file value.");
+        status.SetError("DOWNLOAD missing file value for TLS_CAINFO.");
         return false;
       }
     } else if (*i == "NETRC_FILE") {
@@ -1681,6 +1691,8 @@
         return false;
       }
       curl_headers.push_back(*i);
+    } else if (file.empty()) {
+      file = *i;
     } else {
       // Do not return error for compatibility reason.
       std::string err = cmStrCat("Unexpected argument: ", *i);
@@ -1688,11 +1700,18 @@
     }
     ++i;
   }
+  // Can't calculate hash if we don't save the file.
+  // TODO Incrementally calculate hash in the write callback as the file is
+  // being downloaded so this check can be relaxed.
+  if (file.empty() && hash) {
+    status.SetError("DOWNLOAD cannot calculate hash if file is not saved.");
+    return false;
+  }
   // If file exists already, and caller specified an expected md5 or sha,
   // and the existing file already has the expected hash, then simply
   // return.
   //
-  if (cmSystemTools::FileExists(file) && hash.get()) {
+  if (!file.empty() && cmSystemTools::FileExists(file) && hash.get()) {
     std::string msg;
     std::string actualHash = hash->HashFile(file);
     if (actualHash == expectedHash) {
@@ -1707,20 +1726,26 @@
   // Make sure parent directory exists so we can write to the file
   // as we receive downloaded bits from curl...
   //
-  std::string dir = cmSystemTools::GetFilenamePath(file);
-  if (!dir.empty() && !cmSystemTools::FileExists(dir) &&
-      !cmSystemTools::MakeDirectory(dir)) {
-    std::string errstring = "DOWNLOAD error: cannot create directory '" + dir +
-      "' - Specify file by full path name and verify that you "
-      "have directory creation and file write privileges.";
-    status.SetError(errstring);
-    return false;
+  if (!file.empty()) {
+    std::string dir = cmSystemTools::GetFilenamePath(file);
+    if (!dir.empty() && !cmSystemTools::FileExists(dir) &&
+        !cmSystemTools::MakeDirectory(dir)) {
+      std::string errstring = "DOWNLOAD error: cannot create directory '" +
+        dir +
+        "' - Specify file by full path name and verify that you "
+        "have directory creation and file write privileges.";
+      status.SetError(errstring);
+      return false;
+    }
   }
 
-  cmsys::ofstream fout(file.c_str(), std::ios::binary);
-  if (!fout) {
-    status.SetError("DOWNLOAD cannot open file for write.");
-    return false;
+  cmsys::ofstream fout;
+  if (!file.empty()) {
+    fout.open(file.c_str(), std::ios::binary);
+    if (!fout) {
+      status.SetError("DOWNLOAD cannot open file for write.");
+      return false;
+    }
   }
 
 #  if defined(_WIN32)
@@ -1756,11 +1781,12 @@
   // check to see if TLS verification is requested
   if (tls_verify) {
     res = ::curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 1);
-    check_curl_result(res, "Unable to set TLS/SSL Verify on: ");
+    check_curl_result(res, "DOWNLOAD cannot set TLS/SSL Verify on: ");
   } else {
     res = ::curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0);
-    check_curl_result(res, "Unable to set TLS/SSL Verify off: ");
+    check_curl_result(res, "DOWNLOAD cannot set TLS/SSL Verify off: ");
   }
+
   // check to see if a CAINFO file has been specified
   // command arg comes first
   std::string const& cainfo_err = cmCurlSetCAInfo(curl, cainfo);
@@ -1781,7 +1807,8 @@
 
   cmFileCommandVectorOfChar chunkDebug;
 
-  res = ::curl_easy_setopt(curl, CURLOPT_WRITEDATA, &fout);
+  res = ::curl_easy_setopt(curl, CURLOPT_WRITEDATA,
+                           file.empty() ? nullptr : &fout);
   check_curl_result(res, "DOWNLOAD cannot set write data: ");
 
   res = ::curl_easy_setopt(curl, CURLOPT_DEBUGDATA, &chunkDebug);
@@ -1855,8 +1882,10 @@
 
   // Explicitly flush/close so we can measure the md5 accurately.
   //
-  fout.flush();
-  fout.close();
+  if (!file.empty()) {
+    fout.flush();
+    fout.close();
+  }
 
   // Verify MD5 sum if requested:
   //
@@ -1925,6 +1954,8 @@
   std::string logVar;
   std::string statusVar;
   bool showProgress = false;
+  bool tls_verify = status.GetMakefile().IsOn("CMAKE_TLS_VERIFY");
+  const char* cainfo = status.GetMakefile().GetDefinition("CMAKE_TLS_CAINFO");
   std::string userpwd;
   std::string netrc_level =
     status.GetMakefile().GetSafeDefinition("CMAKE_NETRC");
@@ -1966,6 +1997,22 @@
       statusVar = *i;
     } else if (*i == "SHOW_PROGRESS") {
       showProgress = true;
+    } else if (*i == "TLS_VERIFY") {
+      ++i;
+      if (i != args.end()) {
+        tls_verify = cmIsOn(*i);
+      } else {
+        status.SetError("UPLOAD missing bool value for TLS_VERIFY.");
+        return false;
+      }
+    } else if (*i == "TLS_CAINFO") {
+      ++i;
+      if (i != args.end()) {
+        cainfo = i->c_str();
+      } else {
+        status.SetError("UPLOAD missing file value for TLS_CAINFO.");
+        return false;
+      }
     } else if (*i == "NETRC_FILE") {
       ++i;
       if (i != args.end()) {
@@ -2051,8 +2098,18 @@
                            cmFileCommandCurlDebugCallback);
   check_curl_result(res, "UPLOAD cannot set debug function: ");
 
-  // make sure default CAInfo is set
-  std::string const& cainfo_err = cmCurlSetCAInfo(curl, nullptr);
+  // check to see if TLS verification is requested
+  if (tls_verify) {
+    res = ::curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 1);
+    check_curl_result(res, "UPLOAD cannot set TLS/SSL Verify on: ");
+  } else {
+    res = ::curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0);
+    check_curl_result(res, "UPLOAD cannot set TLS/SSL Verify off: ");
+  }
+
+  // check to see if a CAINFO file has been specified
+  // command arg comes first
+  std::string const& cainfo_err = cmCurlSetCAInfo(curl, cainfo);
   if (!cainfo_err.empty()) {
     status.SetError(cainfo_err);
     return false;
@@ -2330,12 +2387,9 @@
     path += "/cmake.lock";
   }
 
-  if (!cmsys::SystemTools::FileIsFullPath(path)) {
-    path = status.GetMakefile().GetCurrentSourceDirectory() + "/" + path;
-  }
-
   // Unify path (remove '//', '/../', ...)
-  path = cmSystemTools::CollapseFullPath(path);
+  path = cmSystemTools::CollapseFullPath(
+    path, status.GetMakefile().GetCurrentSourceDirectory());
 
   // Create file and directories if needed
   std::string parentDir = cmSystemTools::GetParentDirectory(path);
@@ -2783,6 +2837,314 @@
   return true;
 }
 
+bool HandleConfigureCommand(std::vector<std::string> const& args,
+                            cmExecutionStatus& status)
+{
+  if (args.size() < 5) {
+    status.SetError("Incorrect arguments to CONFIGURE subcommand.");
+    return false;
+  }
+  if (args[1] != "OUTPUT") {
+    status.SetError("Incorrect arguments to CONFIGURE subcommand.");
+    return false;
+  }
+  if (args[3] != "CONTENT") {
+    status.SetError("Incorrect arguments to CONFIGURE subcommand.");
+    return false;
+  }
+
+  std::string errorMessage;
+  cmNewLineStyle newLineStyle;
+  if (!newLineStyle.ReadFromArguments(args, errorMessage)) {
+    status.SetError(cmStrCat("CONFIGURE ", errorMessage));
+    return false;
+  }
+
+  bool escapeQuotes = false;
+  bool atOnly = false;
+  for (unsigned int i = 5; i < args.size(); ++i) {
+    if (args[i] == "@ONLY") {
+      atOnly = true;
+    } else if (args[i] == "ESCAPE_QUOTES") {
+      escapeQuotes = true;
+    } else if (args[i] == "NEWLINE_STYLE" || args[i] == "LF" ||
+               args[i] == "UNIX" || args[i] == "CRLF" || args[i] == "WIN32" ||
+               args[i] == "DOS") {
+      /* Options handled by NewLineStyle member above.  */
+    } else {
+      status.SetError(
+        cmStrCat("CONFIGURE Unrecognized argument \"", args[i], "\""));
+      return false;
+    }
+  }
+
+  // Check for generator expressions
+  const std::string input = args[4];
+  std::string outputFile = cmSystemTools::CollapseFullPath(
+    args[2], status.GetMakefile().GetCurrentBinaryDirectory());
+
+  std::string::size_type pos = input.find_first_of("<>");
+  if (pos != std::string::npos) {
+    status.SetError(cmStrCat("CONFIGURE called with CONTENT containing a \"",
+                             input[pos],
+                             "\".  This character is not allowed."));
+    return false;
+  }
+
+  pos = outputFile.find_first_of("<>");
+  if (pos != std::string::npos) {
+    status.SetError(cmStrCat("CONFIGURE called with OUTPUT containing a \"",
+                             outputFile[pos],
+                             "\".  This character is not allowed."));
+    return false;
+  }
+
+  cmMakefile& makeFile = status.GetMakefile();
+  if (!makeFile.CanIWriteThisFile(outputFile)) {
+    cmSystemTools::Error("Attempt to write file: " + outputFile +
+                         " into a source directory.");
+    return false;
+  }
+
+  cmSystemTools::ConvertToUnixSlashes(outputFile);
+
+  // Re-generate if non-temporary outputs are missing.
+  // when we finalize the configuration we will remove all
+  // output files that now don't exist.
+  makeFile.AddCMakeOutputFile(outputFile);
+
+  // Create output directory
+  const std::string::size_type slashPos = outputFile.rfind('/');
+  if (slashPos != std::string::npos) {
+    const std::string path = outputFile.substr(0, slashPos);
+    cmSystemTools::MakeDirectory(path);
+  }
+
+  std::string newLineCharacters;
+  bool open_with_binary_flag = false;
+  if (newLineStyle.IsValid()) {
+    open_with_binary_flag = true;
+    newLineCharacters = newLineStyle.GetCharacters();
+  }
+
+  cmGeneratedFileStream fout;
+  fout.Open(outputFile, false, open_with_binary_flag);
+  if (!fout) {
+    cmSystemTools::Error("Could not open file for write in copy operation " +
+                         outputFile);
+    cmSystemTools::ReportLastSystemError("");
+    return false;
+  }
+  fout.SetCopyIfDifferent(true);
+
+  // copy input to output and expand variables from input at the same time
+  std::stringstream sin(input, std::ios::in);
+  std::string inLine;
+  std::string outLine;
+  while (cmSystemTools::GetLineFromStream(sin, inLine)) {
+    outLine.clear();
+    makeFile.ConfigureString(inLine, outLine, atOnly, escapeQuotes);
+    fout << outLine << newLineCharacters;
+  }
+
+  // close file before attempting to copy
+  fout.close();
+
+  return true;
+}
+
+bool HandleArchiveCreateCommand(std::vector<std::string> const& args,
+                                cmExecutionStatus& status)
+{
+  struct Arguments
+  {
+    std::string Output;
+    std::string Format;
+    std::string Compression;
+    std::string MTime;
+    bool Verbose = false;
+    std::vector<std::string> Paths;
+  };
+
+  static auto const parser = cmArgumentParser<Arguments>{}
+                               .Bind("OUTPUT"_s, &Arguments::Output)
+                               .Bind("FORMAT"_s, &Arguments::Format)
+                               .Bind("COMPRESSION"_s, &Arguments::Compression)
+                               .Bind("MTIME"_s, &Arguments::MTime)
+                               .Bind("VERBOSE"_s, &Arguments::Verbose)
+                               .Bind("PATHS"_s, &Arguments::Paths);
+
+  std::vector<std::string> unrecognizedArguments;
+  std::vector<std::string> keywordsMissingValues;
+  auto parsedArgs =
+    parser.Parse(cmMakeRange(args).advance(1), &unrecognizedArguments,
+                 &keywordsMissingValues);
+  auto argIt = unrecognizedArguments.begin();
+  if (argIt != unrecognizedArguments.end()) {
+    status.SetError(cmStrCat("Unrecognized argument: \"", *argIt, "\""));
+    cmSystemTools::SetFatalErrorOccured();
+    return false;
+  }
+
+  const std::vector<std::string> LIST_ARGS = { "OUTPUT", "FORMAT",
+                                               "COMPRESSION", "MTIME",
+                                               "PATHS" };
+  auto kwbegin = keywordsMissingValues.cbegin();
+  auto kwend = cmRemoveMatching(keywordsMissingValues, LIST_ARGS);
+  if (kwend != kwbegin) {
+    status.SetError(cmStrCat("Keywords missing values:\n  ",
+                             cmJoin(cmMakeRange(kwbegin, kwend), "\n  ")));
+    cmSystemTools::SetFatalErrorOccured();
+    return false;
+  }
+
+  const char* knownFormats[] = {
+    "7zip", "gnutar", "pax", "paxr", "raw", "zip"
+  };
+
+  if (!parsedArgs.Format.empty() &&
+      !cm::contains(knownFormats, parsedArgs.Format)) {
+    status.SetError(
+      cmStrCat("archive format ", parsedArgs.Format, " not supported"));
+    cmSystemTools::SetFatalErrorOccured();
+    return false;
+  }
+
+  const char* zipFileFormats[] = { "7zip", "zip" };
+  if (!parsedArgs.Compression.empty() &&
+      cm::contains(zipFileFormats, parsedArgs.Format)) {
+    status.SetError(cmStrCat("archive format ", parsedArgs.Format,
+                             " does not support COMPRESSION arguments"));
+    cmSystemTools::SetFatalErrorOccured();
+    return false;
+  }
+
+  static std::map<std::string, cmSystemTools::cmTarCompression>
+    compressionTypeMap = { { "None", cmSystemTools::TarCompressNone },
+                           { "BZip2", cmSystemTools::TarCompressBZip2 },
+                           { "GZip", cmSystemTools::TarCompressGZip },
+                           { "XZ", cmSystemTools::TarCompressXZ },
+                           { "Zstd", cmSystemTools::TarCompressZstd } };
+
+  cmSystemTools::cmTarCompression compress = cmSystemTools::TarCompressNone;
+  auto typeIt = compressionTypeMap.find(parsedArgs.Compression);
+  if (typeIt != compressionTypeMap.end()) {
+    compress = typeIt->second;
+  } else if (!parsedArgs.Compression.empty()) {
+    status.SetError(cmStrCat("compression type ", parsedArgs.Compression,
+                             " is not supported"));
+    cmSystemTools::SetFatalErrorOccured();
+    return false;
+  }
+
+  if (parsedArgs.Paths.empty()) {
+    status.SetError("ARCHIVE_CREATE requires a non-empty list of PATHS");
+    cmSystemTools::SetFatalErrorOccured();
+    return false;
+  }
+
+  if (!cmSystemTools::CreateTar(parsedArgs.Output, parsedArgs.Paths, compress,
+                                parsedArgs.Verbose, parsedArgs.MTime,
+                                parsedArgs.Format)) {
+    status.SetError(cmStrCat("failed to compress: ", parsedArgs.Output));
+    cmSystemTools::SetFatalErrorOccured();
+    return false;
+  }
+
+  return true;
+}
+
+bool HandleArchiveExtractCommand(std::vector<std::string> const& args,
+                                 cmExecutionStatus& status)
+{
+  struct Arguments
+  {
+    std::string Input;
+    bool Verbose = false;
+    bool ListOnly = false;
+    std::string Destination;
+    std::vector<std::string> Patterns;
+  };
+
+  static auto const parser = cmArgumentParser<Arguments>{}
+                               .Bind("INPUT"_s, &Arguments::Input)
+                               .Bind("VERBOSE"_s, &Arguments::Verbose)
+                               .Bind("LIST_ONLY"_s, &Arguments::ListOnly)
+                               .Bind("DESTINATION"_s, &Arguments::Destination)
+                               .Bind("PATTERNS"_s, &Arguments::Patterns);
+
+  std::vector<std::string> unrecognizedArguments;
+  std::vector<std::string> keywordsMissingValues;
+  auto parsedArgs =
+    parser.Parse(cmMakeRange(args).advance(1), &unrecognizedArguments,
+                 &keywordsMissingValues);
+  auto argIt = unrecognizedArguments.begin();
+  if (argIt != unrecognizedArguments.end()) {
+    status.SetError(cmStrCat("Unrecognized argument: \"", *argIt, "\""));
+    cmSystemTools::SetFatalErrorOccured();
+    return false;
+  }
+
+  const std::vector<std::string> LIST_ARGS = { "INPUT", "DESTINATION",
+                                               "PATTERNS" };
+  auto kwbegin = keywordsMissingValues.cbegin();
+  auto kwend = cmRemoveMatching(keywordsMissingValues, LIST_ARGS);
+  if (kwend != kwbegin) {
+    status.SetError(cmStrCat("Keywords missing values:\n  ",
+                             cmJoin(cmMakeRange(kwbegin, kwend), "\n  ")));
+    cmSystemTools::SetFatalErrorOccured();
+    return false;
+  }
+
+  std::string inFile = parsedArgs.Input;
+
+  if (parsedArgs.ListOnly) {
+    if (!cmSystemTools::ListTar(inFile, parsedArgs.Patterns,
+                                parsedArgs.Verbose)) {
+      status.SetError(cmStrCat("failed to list: ", inFile));
+      cmSystemTools::SetFatalErrorOccured();
+      return false;
+    }
+  } else {
+    std::string destDir = status.GetMakefile().GetCurrentBinaryDirectory();
+    if (!parsedArgs.Destination.empty()) {
+      if (cmSystemTools::FileIsFullPath(parsedArgs.Destination)) {
+        destDir = parsedArgs.Destination;
+      } else {
+        destDir = cmStrCat(destDir, "/", parsedArgs.Destination);
+      }
+
+      if (!cmSystemTools::MakeDirectory(destDir)) {
+        status.SetError(cmStrCat("failed to create directory: ", destDir));
+        cmSystemTools::SetFatalErrorOccured();
+        return false;
+      }
+
+      if (!cmSystemTools::FileIsFullPath(inFile)) {
+        inFile =
+          cmStrCat(cmSystemTools::GetCurrentWorkingDirectory(), "/", inFile);
+      }
+    }
+
+    cmWorkingDirectory workdir(destDir);
+    if (workdir.Failed()) {
+      status.SetError(
+        cmStrCat("failed to change working directory to: ", destDir));
+      cmSystemTools::SetFatalErrorOccured();
+      return false;
+    }
+
+    if (!cmSystemTools::ExtractTar(inFile, parsedArgs.Patterns,
+                                   parsedArgs.Verbose)) {
+      status.SetError(cmStrCat("failed to extract: ", inFile));
+      cmSystemTools::SetFatalErrorOccured();
+      return false;
+    }
+  }
+
+  return true;
+}
+
 } // namespace
 
 bool cmFileCommand(std::vector<std::string> const& args,
@@ -2836,6 +3198,9 @@
     { "READ_SYMLINK"_s, HandleReadSymlinkCommand },
     { "CREATE_LINK"_s, HandleCreateLinkCommand },
     { "GET_RUNTIME_DEPENDENCIES"_s, HandleGetRuntimeDependenciesCommand },
+    { "CONFIGURE"_s, HandleConfigureCommand },
+    { "ARCHIVE_CREATE"_s, HandleArchiveCreateCommand },
+    { "ARCHIVE_EXTRACT"_s, HandleArchiveExtractCommand },
   };
 
   return subcommand(args[0], args, status);
diff --git a/Source/cmFileCopier.cxx b/Source/cmFileCopier.cxx
index 627e05b..5d44a06 100644
--- a/Source/cmFileCopier.cxx
+++ b/Source/cmFileCopier.cxx
@@ -173,7 +173,7 @@
   // check if default dir creation permissions were set
   const char* default_dir_install_permissions = this->Makefile->GetDefinition(
     "CMAKE_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS");
-  if (default_dir_install_permissions && *default_dir_install_permissions) {
+  if (cmNonempty(default_dir_install_permissions)) {
     std::vector<std::string> items =
       cmExpandedList(default_dir_install_permissions);
     for (const auto& arg : items) {
diff --git a/Source/cmFileMonitor.h b/Source/cmFileMonitor.h
index b510a2c..fc75b0c 100644
--- a/Source/cmFileMonitor.h
+++ b/Source/cmFileMonitor.h
@@ -9,7 +9,7 @@
 #include <string>
 #include <vector>
 
-#include "cm_uv.h"
+#include <cm3p/uv.h>
 
 class cmRootWatcher;
 
diff --git a/Source/cmFindBase.cxx b/Source/cmFindBase.cxx
index bec99bb..743ac75 100644
--- a/Source/cmFindBase.cxx
+++ b/Source/cmFindBase.cxx
@@ -10,6 +10,7 @@
 #include <cmext/algorithm>
 
 #include "cmMakefile.h"
+#include "cmProperty.h"
 #include "cmRange.h"
 #include "cmSearchPath.h"
 #include "cmState.h"
@@ -22,10 +23,6 @@
 cmFindBase::cmFindBase(cmExecutionStatus& status)
   : cmFindCommon(status)
 {
-  this->AlreadyInCache = false;
-  this->AlreadyInCacheWithoutMetaInfo = false;
-  this->NamesPerDir = false;
-  this->NamesPerDirAllowed = false;
 }
 
 bool cmFindBase::ParseArguments(std::vector<std::string> const& argsIn)
@@ -115,6 +112,10 @@
     } else if (args[j] == "NO_SYSTEM_PATH") {
       doing = DoingNone;
       this->NoDefaultPath = true;
+    } else if (args[j] == "REQUIRED") {
+      doing = DoingNone;
+      this->Required = true;
+      newStyle = true;
     } else if (this->CheckCommonArgument(args[j])) {
       doing = DoingNone;
     } else {
@@ -296,7 +297,7 @@
   if (const char* cacheValue =
         this->Makefile->GetDefinition(this->VariableName)) {
     cmState* state = this->Makefile->GetState();
-    const char* cacheEntry = state->GetCacheEntryValue(this->VariableName);
+    cmProp cacheEntry = state->GetCacheEntryValue(this->VariableName);
     bool found = !cmIsNOTFOUND(cacheValue);
     bool cached = cacheEntry != nullptr;
     if (found) {
@@ -312,9 +313,9 @@
       return true;
     }
     if (cached) {
-      const char* hs =
+      cmProp hs =
         state->GetCacheEntryProperty(this->VariableName, "HELPSTRING");
-      this->VariableDocumentation = hs ? hs : "(none)";
+      this->VariableDocumentation = hs ? *hs : "(none)";
     }
   }
   return false;
diff --git a/Source/cmFindBase.h b/Source/cmFindBase.h
index fce0b11..4cbf09e 100644
--- a/Source/cmFindBase.h
+++ b/Source/cmFindBase.h
@@ -44,14 +44,16 @@
   std::string VariableDocumentation;
   std::string VariableName;
   std::vector<std::string> Names;
-  bool NamesPerDir;
-  bool NamesPerDirAllowed;
+  bool NamesPerDir = false;
+  bool NamesPerDirAllowed = false;
 
   // CMAKE_*_PATH CMAKE_SYSTEM_*_PATH FRAMEWORK|LIBRARY|INCLUDE|PROGRAM
   std::string EnvironmentPath; // LIB,INCLUDE
 
-  bool AlreadyInCache;
-  bool AlreadyInCacheWithoutMetaInfo;
+  bool AlreadyInCache = false;
+  bool AlreadyInCacheWithoutMetaInfo = false;
+
+  bool Required = false;
 
 private:
   // Add pieces of the search.
diff --git a/Source/cmFindCommon.cxx b/Source/cmFindCommon.cxx
index 82acfed..3401eff 100644
--- a/Source/cmFindCommon.cxx
+++ b/Source/cmFindCommon.cxx
@@ -4,7 +4,6 @@
 
 #include <algorithm>
 #include <array>
-#include <cstring>
 #include <utility>
 
 #include <cmext/algorithm>
@@ -209,10 +208,10 @@
   const char* sysrootLink =
     this->Makefile->GetDefinition("CMAKE_SYSROOT_LINK");
   const char* rootPath = this->Makefile->GetDefinition("CMAKE_FIND_ROOT_PATH");
-  const bool noSysroot = !sysroot || !*sysroot;
-  const bool noCompileSysroot = !sysrootCompile || !*sysrootCompile;
-  const bool noLinkSysroot = !sysrootLink || !*sysrootLink;
-  const bool noRootPath = !rootPath || !*rootPath;
+  const bool noSysroot = !cmNonempty(sysroot);
+  const bool noCompileSysroot = !cmNonempty(sysrootCompile);
+  const bool noLinkSysroot = !cmNonempty(sysrootLink);
+  const bool noRootPath = !cmNonempty(rootPath);
   if (noSysroot && noCompileSysroot && noLinkSysroot && noRootPath) {
     return;
   }
@@ -280,12 +279,7 @@
   // Construct the list of path roots with no trailing slashes.
   for (const char** pathName = paths; *pathName; ++pathName) {
     // Get the list of paths to ignore from the variable.
-    const char* ignorePath = this->Makefile->GetDefinition(*pathName);
-    if ((ignorePath == nullptr) || (strlen(ignorePath) == 0)) {
-      continue;
-    }
-
-    cmExpandList(ignorePath, ignore);
+    this->Makefile->GetDefExpandList(*pathName, ignore);
   }
 
   for (std::string& i : ignore) {
diff --git a/Source/cmFindLibraryCommand.cxx b/Source/cmFindLibraryCommand.cxx
index d5a4bde..3242b6d 100644
--- a/Source/cmFindLibraryCommand.cxx
+++ b/Source/cmFindLibraryCommand.cxx
@@ -12,6 +12,7 @@
 
 #include "cmGlobalGenerator.h"
 #include "cmMakefile.h"
+#include "cmMessageType.h"
 #include "cmState.h"
 #include "cmStateTypes.h"
 #include "cmStringAlgorithms.h"
@@ -75,15 +76,22 @@
   std::string const library = this->FindLibrary();
   if (!library.empty()) {
     // Save the value in the cache
-    this->Makefile->AddCacheDefinition(this->VariableName, library.c_str(),
+    this->Makefile->AddCacheDefinition(this->VariableName, library,
                                        this->VariableDocumentation.c_str(),
                                        cmStateEnums::FILEPATH);
     return true;
   }
   std::string notfound = this->VariableName + "-NOTFOUND";
-  this->Makefile->AddCacheDefinition(this->VariableName, notfound.c_str(),
+  this->Makefile->AddCacheDefinition(this->VariableName, notfound,
                                      this->VariableDocumentation.c_str(),
                                      cmStateEnums::FILEPATH);
+  if (this->Required) {
+    this->Makefile->IssueMessage(
+      MessageType::FATAL_ERROR,
+      "Could not find " + this->VariableName +
+        " using the following names: " + cmJoin(this->Names, ", "));
+    cmSystemTools::SetFatalErrorOccured();
+  }
   return true;
 }
 
@@ -425,7 +433,8 @@
 #endif
     if (name.Regex.find(testName)) {
       this->TestPath = cmStrCat(path, origName);
-      if (!cmSystemTools::FileIsDirectory(this->TestPath)) {
+      // Make sure the path is readable and is not a directory.
+      if (cmSystemTools::FileExists(this->TestPath, true)) {
         this->DebugLibraryFound(name.Raw, dir);
 
         // This is a matching file.  Check if it is better than the
diff --git a/Source/cmFindPackageCommand.cxx b/Source/cmFindPackageCommand.cxx
index 297c72b..ae06047 100644
--- a/Source/cmFindPackageCommand.cxx
+++ b/Source/cmFindPackageCommand.cxx
@@ -24,6 +24,7 @@
 #include "cmMakefile.h"
 #include "cmMessageType.h"
 #include "cmPolicies.h"
+#include "cmProperty.h"
 #include "cmRange.h"
 #include "cmSearchPath.h"
 #include "cmState.h"
@@ -279,9 +280,13 @@
     } else if (args[i] == "MODULE") {
       moduleArgs.insert(i);
       doing = DoingNone;
+      // XXX(clang-tidy): https://bugs.llvm.org/show_bug.cgi?id=44165
+      // NOLINTNEXTLINE(bugprone-branch-clone)
     } else if (args[i] == "CONFIG") {
       configArgs.insert(i);
       doing = DoingNone;
+      // XXX(clang-tidy): https://bugs.llvm.org/show_bug.cgi?id=44165
+      // NOLINTNEXTLINE(bugprone-branch-clone)
     } else if (args[i] == "NO_MODULE") {
       configArgs.insert(i);
       doing = DoingNone;
@@ -318,6 +323,8 @@
       this->NoSystemRegistry = true;
       configArgs.insert(i);
       doing = DoingNone;
+      // XXX(clang-tidy): https://bugs.llvm.org/show_bug.cgi?id=44165
+      // NOLINTNEXTLINE(bugprone-branch-clone)
     } else if (args[i] == "NO_CMAKE_BUILDS_PATH") {
       // Ignore legacy option.
       configArgs.insert(i);
@@ -498,9 +505,7 @@
       case cmPolicies::NEW: {
         // NEW behavior is to honor the <pkg>_ROOT variables.
         std::string const rootVar = this->Name + "_ROOT";
-        if (const char* pkgRoot = this->Makefile->GetDefinition(rootVar)) {
-          cmExpandList(pkgRoot, rootPaths, false);
-        }
+        this->Makefile->GetDefExpandList(rootVar, rootPaths, false);
         cmSystemTools::GetPath(rootPaths, rootVar.c_str());
       } break;
     }
@@ -1060,8 +1065,8 @@
     cmStrCat("The directory containing a CMake configuration file for ",
              this->Name, '.');
   // We force the value since we do not get here if it was already set.
-  this->Makefile->AddCacheDefinition(this->Variable, init.c_str(),
-                                     help.c_str(), cmStateEnums::PATH, true);
+  this->Makefile->AddCacheDefinition(this->Variable, init, help.c_str(),
+                                     cmStateEnums::PATH, true);
 
   return found;
 }
@@ -1114,12 +1119,10 @@
 void cmFindPackageCommand::AppendToFoundProperty(bool found)
 {
   std::vector<std::string> foundContents;
-  const char* foundProp =
+  cmProp foundProp =
     this->Makefile->GetState()->GetGlobalProperty("PACKAGES_FOUND");
-  if (foundProp && *foundProp) {
-    std::string tmp = foundProp;
-
-    cmExpandList(tmp, foundContents, false);
+  if (cmNonempty(foundProp)) {
+    cmExpandList(*foundProp, foundContents, false);
     auto nameIt =
       std::find(foundContents.begin(), foundContents.end(), this->Name);
     if (nameIt != foundContents.end()) {
@@ -1128,12 +1131,10 @@
   }
 
   std::vector<std::string> notFoundContents;
-  const char* notFoundProp =
+  cmProp notFoundProp =
     this->Makefile->GetState()->GetGlobalProperty("PACKAGES_NOT_FOUND");
-  if (notFoundProp && *notFoundProp) {
-    std::string tmp = notFoundProp;
-
-    cmExpandList(tmp, notFoundContents, false);
+  if (cmNonempty(notFoundProp)) {
+    cmExpandList(*notFoundProp, notFoundContents, false);
     auto nameIt =
       std::find(notFoundContents.begin(), notFoundContents.end(), this->Name);
     if (nameIt != notFoundContents.end()) {
@@ -1165,9 +1166,9 @@
   std::string found = cmStrCat(this->Name, "_FOUND");
   std::string upperFound = cmSystemTools::UpperCase(found);
 
-  const char* upperResult = this->Makefile->GetDefinition(upperFound);
-  const char* result = this->Makefile->GetDefinition(found);
-  bool packageFound = ((cmIsOn(result)) || (cmIsOn(upperResult)));
+  bool upperResult = this->Makefile->IsOn(upperFound);
+  bool result = this->Makefile->IsOn(found);
+  bool packageFound = (result || upperResult);
 
   this->AppendToFoundProperty(packageFound);
 
diff --git a/Source/cmFindPackageCommand.h b/Source/cmFindPackageCommand.h
index ae9ade7..7058a54 100644
--- a/Source/cmFindPackageCommand.h
+++ b/Source/cmFindPackageCommand.h
@@ -12,7 +12,7 @@
 #include <string>
 #include <vector>
 
-#include "cm_kwiml.h"
+#include <cm3p/kwiml/int.h>
 
 #include "cmFindCommon.h"
 #include "cmPolicies.h"
diff --git a/Source/cmFindPathCommand.cxx b/Source/cmFindPathCommand.cxx
index 908f0c1..4bab469 100644
--- a/Source/cmFindPathCommand.cxx
+++ b/Source/cmFindPathCommand.cxx
@@ -5,6 +5,7 @@
 #include "cmsys/Glob.hxx"
 
 #include "cmMakefile.h"
+#include "cmMessageType.h"
 #include "cmStateTypes.h"
 #include "cmStringAlgorithms.h"
 #include "cmSystemTools.h"
@@ -43,14 +44,21 @@
   std::string result = this->FindHeader();
   if (!result.empty()) {
     this->Makefile->AddCacheDefinition(
-      this->VariableName, result.c_str(), this->VariableDocumentation.c_str(),
+      this->VariableName, result, this->VariableDocumentation.c_str(),
       (this->IncludeFileInPath) ? cmStateEnums::FILEPATH : cmStateEnums::PATH);
     return true;
   }
   this->Makefile->AddCacheDefinition(
-    this->VariableName, (this->VariableName + "-NOTFOUND").c_str(),
+    this->VariableName, this->VariableName + "-NOTFOUND",
     this->VariableDocumentation.c_str(),
     (this->IncludeFileInPath) ? cmStateEnums::FILEPATH : cmStateEnums::PATH);
+  if (this->Required) {
+    this->Makefile->IssueMessage(
+      MessageType::FATAL_ERROR,
+      "Could not find " + this->VariableName +
+        " using the following files: " + cmJoin(this->Names, ", "));
+    cmSystemTools::SetFatalErrorOccured();
+  }
   return true;
 }
 
diff --git a/Source/cmFindProgramCommand.cxx b/Source/cmFindProgramCommand.cxx
index 3e49172..77728ec 100644
--- a/Source/cmFindProgramCommand.cxx
+++ b/Source/cmFindProgramCommand.cxx
@@ -3,6 +3,8 @@
 #include "cmFindProgramCommand.h"
 
 #include "cmMakefile.h"
+#include "cmMessageType.h"
+#include "cmPolicies.h"
 #include "cmStateTypes.h"
 #include "cmStringAlgorithms.h"
 #include "cmSystemTools.h"
@@ -18,6 +20,7 @@
   cmFindProgramHelper(cmMakefile* makefile, cmFindBase const* base)
     : DebugSearches("find_program", base)
     , Makefile(makefile)
+    , PolicyCMP0109(makefile->GetPolicyStatus(cmPolicies::CMP0109))
   {
 #if defined(_WIN32) || defined(__CYGWIN__) || defined(__MINGW32__)
     // Consider platform-specific extensions.
@@ -47,6 +50,8 @@
   cmFindBaseDebugState DebugSearches;
   cmMakefile* Makefile;
 
+  cmPolicies::PolicyStatus PolicyCMP0109;
+
   void AddName(std::string const& name) { this->Names.push_back(name); }
   void SetName(std::string const& name)
   {
@@ -84,7 +89,7 @@
       this->TestNameExt = cmStrCat(name, ext);
       this->TestPath =
         cmSystemTools::CollapseFullPath(this->TestNameExt, path);
-      bool exists = cmSystemTools::FileExists(this->TestPath, true);
+      bool exists = this->FileIsExecutable(this->TestPath);
       exists ? this->DebugSearches.FoundAt(this->TestPath)
              : this->DebugSearches.FailedAt(this->TestPath);
       if (exists) {
@@ -94,6 +99,48 @@
     }
     return false;
   }
+  bool FileIsExecutable(std::string const& file) const
+  {
+    switch (this->PolicyCMP0109) {
+      case cmPolicies::OLD:
+        return cmSystemTools::FileExists(file, true);
+      case cmPolicies::NEW:
+      case cmPolicies::REQUIRED_ALWAYS:
+      case cmPolicies::REQUIRED_IF_USED:
+        return cmSystemTools::FileIsExecutable(file);
+      default:
+        break;
+    }
+    bool const isExeOld = cmSystemTools::FileExists(file, true);
+    bool const isExeNew = cmSystemTools::FileIsExecutable(file);
+    if (isExeNew == isExeOld) {
+      return isExeNew;
+    }
+    if (isExeNew) {
+      this->Makefile->IssueMessage(
+        MessageType::AUTHOR_WARNING,
+        cmStrCat(cmPolicies::GetPolicyWarning(cmPolicies::CMP0109),
+                 "\n"
+                 "The file\n"
+                 "  ",
+                 file,
+                 "\n"
+                 "is executable but not readable.  "
+                 "CMake is ignoring it for compatibility."));
+    } else {
+      this->Makefile->IssueMessage(
+        MessageType::AUTHOR_WARNING,
+        cmStrCat(cmPolicies::GetPolicyWarning(cmPolicies::CMP0109),
+                 "\n"
+                 "The file\n"
+                 "  ",
+                 file,
+                 "\n"
+                 "is readable but not executable.  "
+                 "CMake is using it for compatibility."));
+    }
+    return isExeOld;
+  }
 };
 
 cmFindProgramCommand::cmFindProgramCommand(cmExecutionStatus& status)
@@ -127,15 +174,22 @@
   std::string const result = FindProgram();
   if (!result.empty()) {
     // Save the value in the cache
-    this->Makefile->AddCacheDefinition(this->VariableName, result.c_str(),
+    this->Makefile->AddCacheDefinition(this->VariableName, result,
                                        this->VariableDocumentation.c_str(),
                                        cmStateEnums::FILEPATH);
 
     return true;
   }
   this->Makefile->AddCacheDefinition(
-    this->VariableName, (this->VariableName + "-NOTFOUND").c_str(),
+    this->VariableName, this->VariableName + "-NOTFOUND",
     this->VariableDocumentation.c_str(), cmStateEnums::FILEPATH);
+  if (this->Required) {
+    this->Makefile->IssueMessage(
+      MessageType::FATAL_ERROR,
+      "Could not find " + this->VariableName +
+        " using the following names: " + cmJoin(this->Names, ", "));
+    cmSystemTools::SetFatalErrorOccured();
+  }
   return true;
 }
 
@@ -258,14 +312,13 @@
 
   if (executableURL != nullptr) {
     const int MAX_OSX_PATH_SIZE = 1024;
-    char buffer[MAX_OSX_PATH_SIZE];
+    UInt8 buffer[MAX_OSX_PATH_SIZE];
 
-    // Convert the CFString to a C string
-    CFStringGetCString(CFURLGetString(executableURL), buffer,
-                       MAX_OSX_PATH_SIZE, kCFStringEncodingUTF8);
-
-    // And finally to a c++ string
-    executable = bundlePath + "/Contents/MacOS/" + std::string(buffer);
+    if (CFURLGetFileSystemRepresentation(executableURL, false, buffer,
+                                         MAX_OSX_PATH_SIZE)) {
+      executable = bundlePath + "/Contents/MacOS/" +
+        std::string(reinterpret_cast<char*>(buffer));
+    }
     // Only release CFURLRef if it's not null
     CFRelease(executableURL);
   }
diff --git a/Source/cmForEachCommand.cxx b/Source/cmForEachCommand.cxx
index 0546186..3b82e0a 100644
--- a/Source/cmForEachCommand.cxx
+++ b/Source/cmForEachCommand.cxx
@@ -4,7 +4,7 @@
 
 #include <algorithm>
 #include <cassert>
-#include <cstddef>
+#include <cstddef> // IWYU pragma: keep
 // NOTE The declaration of `std::abs` has moved to `cmath` since C++17
 // See https://en.cppreference.com/w/cpp/numeric/math/abs
 // ALERT But IWYU used to lint `#include`s do not "understand"
@@ -18,8 +18,7 @@
 
 #include <cm/memory>
 #include <cm/string_view>
-
-#include "cm_static_string_view.hxx"
+#include <cmext/string_view>
 
 #include "cmExecutionStatus.h"
 #include "cmFunctionBlocker.h"
@@ -114,8 +113,8 @@
   // At end of for each execute recorded commands
   // store the old value
   std::string oldDef;
-  if (mf.GetDefinition(this->Args.front())) {
-    oldDef = mf.GetDefinition(this->Args.front());
+  if (auto d = mf.GetDefinition(this->Args.front())) {
+    oldDef = d;
   }
 
   auto restore = false;
@@ -187,8 +186,8 @@
   // Store old values for iteration variables
   std::map<std::string, std::string> oldDefs;
   for (auto i = 0u; i < values.size(); ++i) {
-    if (mf.GetDefinition(iterationVars[i])) {
-      oldDefs.emplace(iterationVars[i], mf.GetDefinition(iterationVars[i]));
+    if (auto d = mf.GetDefinition(iterationVars[i])) {
+      oldDefs.emplace(iterationVars[i], d);
     }
   }
 
diff --git a/Source/cmFunctionBlocker.cxx b/Source/cmFunctionBlocker.cxx
index 5778a71..643cd82 100644
--- a/Source/cmFunctionBlocker.cxx
+++ b/Source/cmFunctionBlocker.cxx
@@ -3,7 +3,9 @@
 #include "cmFunctionBlocker.h"
 
 #include <cassert>
+#include <memory> // IWYU pragma: keep
 #include <sstream>
+#include <string> // IWYU pragma: keep
 #include <utility>
 
 #include "cmExecutionStatus.h"
diff --git a/Source/cmFunctionCommand.cxx b/Source/cmFunctionCommand.cxx
index a4c9072..b6f58bd 100644
--- a/Source/cmFunctionCommand.cxx
+++ b/Source/cmFunctionCommand.cxx
@@ -7,8 +7,7 @@
 #include <cm/memory>
 #include <cm/string_view>
 #include <cmext/algorithm>
-
-#include "cm_static_string_view.hxx"
+#include <cmext/string_view>
 
 #include "cmExecutionStatus.h"
 #include "cmFunctionBlocker.h"
diff --git a/Source/cmGeneratedFileStream.cxx b/Source/cmGeneratedFileStream.cxx
index 2af04b6..2768547 100644
--- a/Source/cmGeneratedFileStream.cxx
+++ b/Source/cmGeneratedFileStream.cxx
@@ -8,15 +8,17 @@
 #include "cmSystemTools.h"
 
 #if !defined(CMAKE_BOOTSTRAP)
+#  include <cm3p/zlib.h>
+
 #  include "cm_codecvt.hxx"
-#  include "cm_zlib.h"
 #endif
 
 cmGeneratedFileStream::cmGeneratedFileStream(Encoding encoding)
+  : OriginalLocale(getloc())
 {
 #ifndef CMAKE_BOOTSTRAP
   if (encoding != codecvt::None) {
-    imbue(std::locale(getloc(), new codecvt(encoding)));
+    imbue(std::locale(OriginalLocale, new codecvt(encoding)));
   }
 #else
   static_cast<void>(encoding);
@@ -121,10 +123,17 @@
   // Create the name of the temporary file.
   this->TempName = name;
 #if defined(__VMS)
-  this->TempName += "_tmp";
+  this->TempName += "_";
 #else
-  this->TempName += ".tmp";
+  this->TempName += ".";
 #endif
+  if (!this->TempExt.empty()) {
+    this->TempName += this->TempExt;
+  } else {
+    char buf[64];
+    sprintf(buf, "tmp%05x", cmSystemTools::RandomSeed() & 0xFFFFF);
+    this->TempName += buf;
+  }
 
   // Make sure the temporary file that will be used is not present.
   cmSystemTools::RemoveFile(this->TempName);
@@ -180,6 +189,7 @@
   }
   FILE* ifs = cmsys::SystemTools::Fopen(oldname, "r");
   if (!ifs) {
+    gzclose(gf);
     return 0;
   }
   size_t res;
@@ -214,3 +224,19 @@
 {
   this->Name = fname;
 }
+
+void cmGeneratedFileStream::SetTempExt(std::string const& ext)
+{
+  this->TempExt = ext;
+}
+
+void cmGeneratedFileStream::WriteRaw(std::string const& data)
+{
+#ifndef CMAKE_BOOTSTRAP
+  std::locale activeLocale = this->imbue(this->OriginalLocale);
+  this->write(data.data(), data.size());
+  this->imbue(activeLocale);
+#else
+  this->write(data.data(), data.size());
+#endif
+}
diff --git a/Source/cmGeneratedFileStream.h b/Source/cmGeneratedFileStream.h
index a9088ac..f6da86e 100644
--- a/Source/cmGeneratedFileStream.h
+++ b/Source/cmGeneratedFileStream.h
@@ -43,6 +43,9 @@
   // The name of the final destination file for the output.
   std::string Name;
 
+  // The extension of the temporary file.
+  std::string TempExt;
+
   // The name of the temporary file.
   std::string TempName;
 
@@ -138,6 +141,22 @@
    * the output file to be changed during the use of cmGeneratedFileStream.
    */
   void SetName(const std::string& fname);
+
+  /**
+   * Set set a custom temporary file extension used with 'Open'.
+   * This does not work if the file was opened by the constructor.
+   */
+  void SetTempExt(std::string const& ext);
+
+  /**
+   * Writes the given string directly to the file without changing the
+   * encoding.
+   */
+  void WriteRaw(std::string const& data);
+
+private:
+  // The original locale of the stream (performs no encoding conversion).
+  std::locale OriginalLocale;
 };
 
 #endif
diff --git a/Source/cmGeneratorExpression.cxx b/Source/cmGeneratorExpression.cxx
index 81d1e46..840f511 100644
--- a/Source/cmGeneratorExpression.cxx
+++ b/Source/cmGeneratorExpression.cxx
@@ -32,12 +32,6 @@
     new cmCompiledGeneratorExpression(this->Backtrace, std::move(input)));
 }
 
-std::unique_ptr<cmCompiledGeneratorExpression> cmGeneratorExpression::Parse(
-  const char* input) const
-{
-  return this->Parse(std::string(input ? input : ""));
-}
-
 std::string cmGeneratorExpression::Evaluate(
   std::string input, cmLocalGenerator* lg, const std::string& config,
   cmGeneratorTarget const* headTarget,
@@ -52,17 +46,6 @@
   return input;
 }
 
-std::string cmGeneratorExpression::Evaluate(
-  const char* input, cmLocalGenerator* lg, const std::string& config,
-  cmGeneratorTarget const* headTarget,
-  cmGeneratorExpressionDAGChecker* dagChecker,
-  cmGeneratorTarget const* currentTarget, std::string const& language)
-{
-  return input ? Evaluate(std::string(input), lg, config, headTarget,
-                          dagChecker, currentTarget, language)
-               : "";
-}
-
 const std::string& cmCompiledGeneratorExpression::Evaluate(
   cmLocalGenerator* lg, const std::string& config,
   const cmGeneratorTarget* headTarget,
@@ -103,6 +86,8 @@
   if (!context.HadError) {
     this->HadContextSensitiveCondition = context.HadContextSensitiveCondition;
     this->HadHeadSensitiveCondition = context.HadHeadSensitiveCondition;
+    this->HadLinkLanguageSensitiveCondition =
+      context.HadLinkLanguageSensitiveCondition;
     this->SourceSensitiveTargets = context.SourceSensitiveTargets;
   }
 
@@ -119,6 +104,7 @@
   , Quiet(false)
   , HadContextSensitiveCondition(false)
   , HadHeadSensitiveCondition(false)
+  , HadLinkLanguageSensitiveCondition(false)
 {
   cmGeneratorExpressionLexer l;
   std::vector<cmGeneratorExpressionToken> tokens = l.Tokenize(this->Input);
@@ -420,9 +406,3 @@
     this->LocalGenerator, this->Config, this->HeadTarget, &dagChecker, nullptr,
     this->Language);
 }
-
-const std::string& cmGeneratorExpressionInterpreter::Evaluate(
-  const char* expression, const std::string& property)
-{
-  return this->Evaluate(std::string(expression ? expression : ""), property);
-}
diff --git a/Source/cmGeneratorExpression.h b/Source/cmGeneratorExpression.h
index c4be3a1..09d8b88 100644
--- a/Source/cmGeneratorExpression.h
+++ b/Source/cmGeneratorExpression.h
@@ -42,8 +42,6 @@
 
   std::unique_ptr<cmCompiledGeneratorExpression> Parse(
     std::string input) const;
-  std::unique_ptr<cmCompiledGeneratorExpression> Parse(
-    const char* input) const;
 
   static std::string Evaluate(
     std::string input, cmLocalGenerator* lg, const std::string& config,
@@ -51,12 +49,6 @@
     cmGeneratorExpressionDAGChecker* dagChecker = nullptr,
     cmGeneratorTarget const* currentTarget = nullptr,
     std::string const& language = std::string());
-  static std::string Evaluate(
-    const char* input, cmLocalGenerator* lg, const std::string& config,
-    cmGeneratorTarget const* headTarget = nullptr,
-    cmGeneratorExpressionDAGChecker* dagChecker = nullptr,
-    cmGeneratorTarget const* currentTarget = nullptr,
-    std::string const& language = std::string());
 
   enum PreprocessContext
   {
@@ -137,6 +129,10 @@
   {
     return this->HadHeadSensitiveCondition;
   }
+  bool GetHadLinkLanguageSensitiveCondition() const
+  {
+    return this->HadLinkLanguageSensitiveCondition;
+  }
   std::set<cmGeneratorTarget const*> GetSourceSensitiveTargets() const
   {
     return this->SourceSensitiveTargets;
@@ -178,6 +174,7 @@
   mutable std::string Output;
   mutable bool HadContextSensitiveCondition;
   mutable bool HadHeadSensitiveCondition;
+  mutable bool HadLinkLanguageSensitiveCondition;
   mutable std::set<cmGeneratorTarget const*> SourceSensitiveTargets;
 };
 
@@ -202,8 +199,6 @@
 
   const std::string& Evaluate(std::string expression,
                               const std::string& property);
-  const std::string& Evaluate(const char* expression,
-                              const std::string& property);
 
 protected:
   cmGeneratorExpression GeneratorExpression;
diff --git a/Source/cmGeneratorExpressionContext.cxx b/Source/cmGeneratorExpressionContext.cxx
index 6d97331..42cbe2a 100644
--- a/Source/cmGeneratorExpressionContext.cxx
+++ b/Source/cmGeneratorExpressionContext.cxx
@@ -19,6 +19,7 @@
   , HadError(false)
   , HadContextSensitiveCondition(false)
   , HadHeadSensitiveCondition(false)
+  , HadLinkLanguageSensitiveCondition(false)
   , EvaluateForBuildsystem(evaluateForBuildsystem)
 {
 }
diff --git a/Source/cmGeneratorExpressionContext.h b/Source/cmGeneratorExpressionContext.h
index 4709fa0..bceff12 100644
--- a/Source/cmGeneratorExpressionContext.h
+++ b/Source/cmGeneratorExpressionContext.h
@@ -40,6 +40,7 @@
   bool HadError;
   bool HadContextSensitiveCondition;
   bool HadHeadSensitiveCondition;
+  bool HadLinkLanguageSensitiveCondition;
   bool EvaluateForBuildsystem;
 };
 
diff --git a/Source/cmGeneratorExpressionDAGChecker.cxx b/Source/cmGeneratorExpressionDAGChecker.cxx
index 643ba34..e223f15 100644
--- a/Source/cmGeneratorExpressionDAGChecker.cxx
+++ b/Source/cmGeneratorExpressionDAGChecker.cxx
@@ -6,6 +6,9 @@
 #include <sstream>
 #include <utility>
 
+#include <cm/string_view>
+#include <cmext/string_view>
+
 #include "cmGeneratorExpressionContext.h"
 #include "cmGeneratorExpressionEvaluator.h"
 #include "cmGeneratorTarget.h"
@@ -44,12 +47,7 @@
 
 void cmGeneratorExpressionDAGChecker::Initialize()
 {
-  const cmGeneratorExpressionDAGChecker* top = this;
-  const cmGeneratorExpressionDAGChecker* p = this->Parent;
-  while (p) {
-    top = p;
-    p = p->Parent;
-  }
+  const auto* top = this->Top();
   this->CheckResult = this->CheckGraph();
 
 #define TEST_TRANSITIVE_PROPERTY_METHOD(METHOD) top->METHOD() ||
@@ -140,38 +138,65 @@
   return DAG;
 }
 
-bool cmGeneratorExpressionDAGChecker::GetTransitivePropertiesOnly()
+bool cmGeneratorExpressionDAGChecker::GetTransitivePropertiesOnly() const
 {
-  const cmGeneratorExpressionDAGChecker* top = this;
-  const cmGeneratorExpressionDAGChecker* parent = this->Parent;
-  while (parent) {
-    top = parent;
-    parent = parent->Parent;
-  }
-
-  return top->TransitivePropertiesOnly;
+  return this->Top()->TransitivePropertiesOnly;
 }
 
-bool cmGeneratorExpressionDAGChecker::EvaluatingGenexExpression()
+bool cmGeneratorExpressionDAGChecker::EvaluatingGenexExpression() const
 {
-  return this->Property.find("TARGET_GENEX_EVAL:") == 0 ||
-    this->Property.find("GENEX_EVAL:", 0) == 0;
+  return cmHasLiteralPrefix(this->Property, "TARGET_GENEX_EVAL:") ||
+    cmHasLiteralPrefix(this->Property, "GENEX_EVAL:");
 }
 
-bool cmGeneratorExpressionDAGChecker::EvaluatingPICExpression()
+bool cmGeneratorExpressionDAGChecker::EvaluatingPICExpression() const
 {
-  const cmGeneratorExpressionDAGChecker* top = this;
-  const cmGeneratorExpressionDAGChecker* parent = this->Parent;
-  while (parent) {
-    top = parent;
-    parent = parent->Parent;
-  }
+  return this->Top()->Property == "INTERFACE_POSITION_INDEPENDENT_CODE";
+}
 
-  return top->Property == "INTERFACE_POSITION_INDEPENDENT_CODE";
+bool cmGeneratorExpressionDAGChecker::EvaluatingCompileExpression() const
+{
+  cm::string_view property(this->Top()->Property);
+
+  return property == "INCLUDE_DIRECTORIES"_s ||
+    property == "COMPILE_DEFINITIONS"_s || property == "COMPILE_OPTIONS"_s;
+}
+
+bool cmGeneratorExpressionDAGChecker::EvaluatingLinkExpression() const
+{
+  cm::string_view property(this->Top()->Property);
+
+  return property == "LINK_DIRECTORIES"_s || property == "LINK_OPTIONS"_s ||
+    property == "LINK_DEPENDS"_s;
+}
+
+bool cmGeneratorExpressionDAGChecker::EvaluatingLinkOptionsExpression() const
+{
+  cm::string_view property(this->Top()->Property);
+
+  return property == "LINK_OPTIONS"_s;
 }
 
 bool cmGeneratorExpressionDAGChecker::EvaluatingLinkLibraries(
-  cmGeneratorTarget const* tgt)
+  cmGeneratorTarget const* tgt) const
+{
+  const auto* top = this->Top();
+
+  cm::string_view prop(top->Property);
+
+  if (tgt) {
+    return top->Target == tgt && prop == "LINK_LIBRARIES"_s;
+  }
+
+  return prop == "LINK_LIBRARIES"_s || prop == "LINK_INTERFACE_LIBRARIES"_s ||
+    prop == "IMPORTED_LINK_INTERFACE_LIBRARIES"_s ||
+    cmHasLiteralPrefix(prop, "LINK_INTERFACE_LIBRARIES_") ||
+    cmHasLiteralPrefix(prop, "IMPORTED_LINK_INTERFACE_LIBRARIES_") ||
+    prop == "INTERFACE_LINK_LIBRARIES"_s;
+}
+
+cmGeneratorExpressionDAGChecker const* cmGeneratorExpressionDAGChecker::Top()
+  const
 {
   const cmGeneratorExpressionDAGChecker* top = this;
   const cmGeneratorExpressionDAGChecker* parent = this->Parent;
@@ -179,30 +204,12 @@
     top = parent;
     parent = parent->Parent;
   }
-
-  const char* prop = top->Property.c_str();
-
-  if (tgt) {
-    return top->Target == tgt && strcmp(prop, "LINK_LIBRARIES") == 0;
-  }
-
-  return (strcmp(prop, "LINK_LIBRARIES") == 0 ||
-          strcmp(prop, "LINK_INTERFACE_LIBRARIES") == 0 ||
-          strcmp(prop, "IMPORTED_LINK_INTERFACE_LIBRARIES") == 0 ||
-          cmHasLiteralPrefix(prop, "LINK_INTERFACE_LIBRARIES_") ||
-          cmHasLiteralPrefix(prop, "IMPORTED_LINK_INTERFACE_LIBRARIES_")) ||
-    strcmp(prop, "INTERFACE_LINK_LIBRARIES") == 0;
+  return top;
 }
 
 cmGeneratorTarget const* cmGeneratorExpressionDAGChecker::TopTarget() const
 {
-  const cmGeneratorExpressionDAGChecker* top = this;
-  const cmGeneratorExpressionDAGChecker* parent = this->Parent;
-  while (parent) {
-    top = parent;
-    parent = parent->Parent;
-  }
-  return top->Target;
+  return this->Top()->Target;
 }
 
 enum TransitiveProperty
diff --git a/Source/cmGeneratorExpressionDAGChecker.h b/Source/cmGeneratorExpressionDAGChecker.h
index f2c49bb..ac2314c 100644
--- a/Source/cmGeneratorExpressionDAGChecker.h
+++ b/Source/cmGeneratorExpressionDAGChecker.h
@@ -66,9 +66,13 @@
   void ReportError(cmGeneratorExpressionContext* context,
                    const std::string& expr);
 
-  bool EvaluatingGenexExpression();
-  bool EvaluatingPICExpression();
-  bool EvaluatingLinkLibraries(cmGeneratorTarget const* tgt = nullptr);
+  bool EvaluatingGenexExpression() const;
+  bool EvaluatingPICExpression() const;
+  bool EvaluatingCompileExpression() const;
+  bool EvaluatingLinkExpression() const;
+  bool EvaluatingLinkOptionsExpression() const;
+
+  bool EvaluatingLinkLibraries(cmGeneratorTarget const* tgt = nullptr) const;
 
 #define DECLARE_TRANSITIVE_PROPERTY_METHOD(METHOD) bool METHOD() const;
 
@@ -76,9 +80,10 @@
 
 #undef DECLARE_TRANSITIVE_PROPERTY_METHOD
 
-  bool GetTransitivePropertiesOnly();
+  bool GetTransitivePropertiesOnly() const;
   void SetTransitivePropertiesOnly() { this->TransitivePropertiesOnly = true; }
 
+  cmGeneratorExpressionDAGChecker const* Top() const;
   cmGeneratorTarget const* TopTarget() const;
 
 private:
diff --git a/Source/cmGeneratorExpressionEvaluationFile.cxx b/Source/cmGeneratorExpressionEvaluationFile.cxx
index 9e8707d..1107adb 100644
--- a/Source/cmGeneratorExpressionEvaluationFile.cxx
+++ b/Source/cmGeneratorExpressionEvaluationFile.cxx
@@ -157,12 +157,8 @@
 
   std::map<std::string, std::string> outputFiles;
 
-  std::vector<std::string> allConfigs;
-  lg->GetMakefile()->GetConfigurations(allConfigs);
-
-  if (allConfigs.empty()) {
-    allConfigs.emplace_back();
-  }
+  std::vector<std::string> allConfigs =
+    lg->GetMakefile()->GetGeneratorConfigs(cmMakefile::IncludeEmptyConfig);
 
   std::vector<std::string> enabledLanguages;
   cmGlobalGenerator* gg = lg->GetGlobalGenerator();
diff --git a/Source/cmGeneratorExpressionNode.cxx b/Source/cmGeneratorExpressionNode.cxx
index 14478c2..fdc8f29 100644
--- a/Source/cmGeneratorExpressionNode.cxx
+++ b/Source/cmGeneratorExpressionNode.cxx
@@ -15,12 +15,13 @@
 
 #include <cm/iterator>
 #include <cm/string_view>
+#include <cm/vector>
+#include <cmext/algorithm>
+#include <cmext/string_view>
 
 #include "cmsys/RegularExpression.hxx"
 #include "cmsys/String.h"
 
-#include "cm_static_string_view.hxx"
-
 #include "cmAlgorithms.h"
 #include "cmGeneratorExpression.h"
 #include "cmGeneratorExpressionContext.h"
@@ -34,7 +35,9 @@
 #include "cmMessageType.h"
 #include "cmOutputConverter.h"
 #include "cmPolicies.h"
+#include "cmProperty.h"
 #include "cmRange.h"
+#include "cmStandardLevelResolver.h"
 #include "cmState.h"
 #include "cmStateSnapshot.h"
 #include "cmStateTypes.h"
@@ -62,6 +65,9 @@
   if (cge->GetHadHeadSensitiveCondition()) {
     context->HadHeadSensitiveCondition = true;
   }
+  if (cge->GetHadLinkLanguageSensitiveCondition()) {
+    context->HadLinkLanguageSensitiveCondition = true;
+  }
   return result;
 }
 
@@ -310,7 +316,7 @@
         break;
     }
 
-    return cmContains(values, parameters.front()) ? "1" : "0";
+    return cm::contains(values, parameters.front()) ? "1" : "0";
   }
 } inListNode;
 
@@ -876,7 +882,7 @@
 {
   ConfigurationTestNode() {} // NOLINT(modernize-use-equals-default)
 
-  int NumExpectedParameters() const override { return OneOrZeroParameters; }
+  int NumExpectedParameters() const override { return ZeroOrMoreParameters; }
 
   std::string Evaluate(
     const std::vector<std::string>& parameters,
@@ -894,34 +900,37 @@
       return std::string();
     }
     context->HadContextSensitiveCondition = true;
-    if (context->Config.empty()) {
-      return parameters.front().empty() ? "1" : "0";
-    }
-
-    if (cmsysString_strcasecmp(parameters.front().c_str(),
-                               context->Config.c_str()) == 0) {
-      return "1";
+    for (auto& param : parameters) {
+      if (context->Config.empty()) {
+        if (param.empty()) {
+          return "1";
+        }
+      } else if (cmsysString_strcasecmp(param.c_str(),
+                                        context->Config.c_str()) == 0) {
+        return "1";
+      }
     }
 
     if (context->CurrentTarget && context->CurrentTarget->IsImported()) {
-      const char* loc = nullptr;
-      const char* imp = nullptr;
+      cmProp loc = nullptr;
+      cmProp imp = nullptr;
       std::string suffix;
-      if (context->CurrentTarget->Target->GetMappedConfig(
-            context->Config, &loc, &imp, suffix)) {
+      if (context->CurrentTarget->Target->GetMappedConfig(context->Config, loc,
+                                                          imp, suffix)) {
         // This imported target has an appropriate location
         // for this (possibly mapped) config.
         // Check if there is a proper config mapping for the tested config.
         std::vector<std::string> mappedConfigs;
         std::string mapProp = cmStrCat(
           "MAP_IMPORTED_CONFIG_", cmSystemTools::UpperCase(context->Config));
-        if (const char* mapValue =
-              context->CurrentTarget->GetProperty(mapProp)) {
-          cmExpandList(cmSystemTools::UpperCase(mapValue), mappedConfigs);
-          return cmContains(mappedConfigs,
-                            cmSystemTools::UpperCase(parameters.front()))
-            ? "1"
-            : "0";
+        if (cmProp mapValue = context->CurrentTarget->GetProperty(mapProp)) {
+          cmExpandList(cmSystemTools::UpperCase(*mapValue), mappedConfigs);
+
+          for (auto& param : parameters) {
+            if (cm::contains(mappedConfigs, cmSystemTools::UpperCase(param))) {
+              return "1";
+            }
+          }
         }
       }
     }
@@ -958,9 +967,10 @@
     const std::vector<std::string>& parameters,
     cmGeneratorExpressionContext* context,
     const GeneratorExpressionContent* content,
-    cmGeneratorExpressionDAGChecker* /*dagChecker*/) const override
+    cmGeneratorExpressionDAGChecker* dagChecker) const override
   {
-    if (context->Language.empty()) {
+    if (context->Language.empty() &&
+        (!dagChecker || !dagChecker->EvaluatingCompileExpression())) {
       reportError(
         context, content->GetOriginalExpression(),
         "$<COMPILE_LANGUAGE:...> may only be used to specify include "
@@ -1005,7 +1015,9 @@
     const GeneratorExpressionContent* content,
     cmGeneratorExpressionDAGChecker* dagChecker) const override
   {
-    if (!context->HeadTarget || context->Language.empty()) {
+    if (!context->HeadTarget ||
+        (context->Language.empty() &&
+         (!dagChecker || !dagChecker->EvaluatingCompileExpression()))) {
       // reportError(context, content->GetOriginalExpression(), "");
       reportError(
         context, content->GetOriginalExpression(),
@@ -1039,6 +1051,214 @@
   }
 } languageAndIdNode;
 
+static const struct LinkLanguageNode : public cmGeneratorExpressionNode
+{
+  LinkLanguageNode() {} // NOLINT(modernize-use-equals-default)
+
+  int NumExpectedParameters() const override { return ZeroOrMoreParameters; }
+
+  std::string Evaluate(
+    const std::vector<std::string>& parameters,
+    cmGeneratorExpressionContext* context,
+    const GeneratorExpressionContent* content,
+    cmGeneratorExpressionDAGChecker* dagChecker) const override
+  {
+    if (!context->HeadTarget || !dagChecker ||
+        !(dagChecker->EvaluatingLinkExpression() ||
+          dagChecker->EvaluatingLinkLibraries())) {
+      reportError(context, content->GetOriginalExpression(),
+                  "$<LINK_LANGUAGE:...> may only be used with binary targets "
+                  "to specify link libraries, link directories, link options "
+                  "and link depends.");
+      return std::string();
+    }
+    if (dagChecker->EvaluatingLinkLibraries() && parameters.empty()) {
+      reportError(
+        context, content->GetOriginalExpression(),
+        "$<LINK_LANGUAGE> is not supported in link libraries expression.");
+      return std::string();
+    }
+
+    cmGlobalGenerator* gg = context->LG->GetGlobalGenerator();
+    std::string genName = gg->GetName();
+    if (genName.find("Makefiles") == std::string::npos &&
+        genName.find("Ninja") == std::string::npos &&
+        genName.find("Visual Studio") == std::string::npos &&
+        genName.find("Xcode") == std::string::npos &&
+        genName.find("Watcom WMake") == std::string::npos) {
+      reportError(context, content->GetOriginalExpression(),
+                  "$<LINK_LANGUAGE:...> not supported for this generator.");
+      return std::string();
+    }
+
+    if (dagChecker->EvaluatingLinkLibraries()) {
+      context->HadHeadSensitiveCondition = true;
+      context->HadLinkLanguageSensitiveCondition = true;
+    }
+
+    if (parameters.empty()) {
+      return context->Language;
+    }
+
+    for (auto& param : parameters) {
+      if (context->Language == param) {
+        return "1";
+      }
+    }
+    return "0";
+  }
+} linkLanguageNode;
+
+namespace {
+struct LinkerId
+{
+  static std::string Evaluate(const std::vector<std::string>& parameters,
+                              cmGeneratorExpressionContext* context,
+                              const GeneratorExpressionContent* content,
+                              const std::string& lang)
+  {
+    std::string const& linkerId =
+      context->LG->GetMakefile()->GetSafeDefinition("CMAKE_" + lang +
+                                                    "_COMPILER_ID");
+    if (parameters.empty()) {
+      return linkerId;
+    }
+    if (linkerId.empty()) {
+      return parameters.front().empty() ? "1" : "0";
+    }
+    static cmsys::RegularExpression linkerIdValidator("^[A-Za-z0-9_]*$");
+
+    for (auto& param : parameters) {
+      if (!linkerIdValidator.find(param)) {
+        reportError(context, content->GetOriginalExpression(),
+                    "Expression syntax not recognized.");
+        return std::string();
+      }
+
+      if (param == linkerId) {
+        return "1";
+      }
+    }
+    return "0";
+  }
+};
+}
+
+static const struct LinkLanguageAndIdNode : public cmGeneratorExpressionNode
+{
+  LinkLanguageAndIdNode() {} // NOLINT(modernize-use-equals-default)
+
+  int NumExpectedParameters() const override { return TwoOrMoreParameters; }
+
+  std::string Evaluate(
+    const std::vector<std::string>& parameters,
+    cmGeneratorExpressionContext* context,
+    const GeneratorExpressionContent* content,
+    cmGeneratorExpressionDAGChecker* dagChecker) const override
+  {
+    if (!context->HeadTarget || !dagChecker ||
+        !(dagChecker->EvaluatingLinkExpression() ||
+          dagChecker->EvaluatingLinkLibraries())) {
+      reportError(
+        context, content->GetOriginalExpression(),
+        "$<LINK_LANG_AND_ID:lang,id> may only be used with binary targets "
+        "to specify link libraries, link directories, link options, and link "
+        "depends.");
+      return std::string();
+    }
+
+    cmGlobalGenerator* gg = context->LG->GetGlobalGenerator();
+    std::string genName = gg->GetName();
+    if (genName.find("Makefiles") == std::string::npos &&
+        genName.find("Ninja") == std::string::npos &&
+        genName.find("Visual Studio") == std::string::npos &&
+        genName.find("Xcode") == std::string::npos &&
+        genName.find("Watcom WMake") == std::string::npos) {
+      reportError(
+        context, content->GetOriginalExpression(),
+        "$<LINK_LANG_AND_ID:lang,id> not supported for this generator.");
+      return std::string();
+    }
+
+    if (dagChecker->EvaluatingLinkLibraries()) {
+      context->HadHeadSensitiveCondition = true;
+      context->HadLinkLanguageSensitiveCondition = true;
+    }
+
+    const std::string& lang = context->Language;
+    if (lang == parameters.front()) {
+      std::vector<std::string> idParameter((parameters.cbegin() + 1),
+                                           parameters.cend());
+      return LinkerId::Evaluate(idParameter, context, content, lang);
+    }
+    return "0";
+  }
+} linkLanguageAndIdNode;
+
+static const struct HostLinkNode : public cmGeneratorExpressionNode
+{
+  HostLinkNode() {} // NOLINT(modernize-use-equals-default)
+
+  int NumExpectedParameters() const override { return ZeroOrMoreParameters; }
+
+  std::string Evaluate(
+    const std::vector<std::string>& parameters,
+    cmGeneratorExpressionContext* context,
+    const GeneratorExpressionContent* content,
+    cmGeneratorExpressionDAGChecker* dagChecker) const override
+  {
+    if (!context->HeadTarget || !dagChecker ||
+        !dagChecker->EvaluatingLinkOptionsExpression()) {
+      reportError(context, content->GetOriginalExpression(),
+                  "$<HOST_LINK:...> may only be used with binary targets "
+                  "to specify link options.");
+      return std::string();
+    }
+
+    return context->HeadTarget->IsDeviceLink() ? std::string()
+                                               : cmJoin(parameters, ";");
+  }
+} hostLinkNode;
+
+static const struct DeviceLinkNode : public cmGeneratorExpressionNode
+{
+  DeviceLinkNode() {} // NOLINT(modernize-use-equals-default)
+
+  int NumExpectedParameters() const override { return ZeroOrMoreParameters; }
+
+  std::string Evaluate(
+    const std::vector<std::string>& parameters,
+    cmGeneratorExpressionContext* context,
+    const GeneratorExpressionContent* content,
+    cmGeneratorExpressionDAGChecker* dagChecker) const override
+  {
+    if (!context->HeadTarget || !dagChecker ||
+        !dagChecker->EvaluatingLinkOptionsExpression()) {
+      reportError(context, content->GetOriginalExpression(),
+                  "$<DEVICE_LINK:...> may only be used with binary targets "
+                  "to specify link options.");
+      return std::string();
+    }
+
+    if (context->HeadTarget->IsDeviceLink()) {
+      std::vector<std::string> list;
+      cmExpandLists(parameters.begin(), parameters.end(), list);
+      const auto DL_BEGIN = "<DEVICE_LINK>"_s;
+      const auto DL_END = "</DEVICE_LINK>"_s;
+      cm::erase_if(list, [&](const std::string& item) {
+        return item == DL_BEGIN || item == DL_END;
+      });
+
+      list.insert(list.begin(), static_cast<std::string>(DL_BEGIN));
+      list.push_back(static_cast<std::string>(DL_END));
+
+      return cmJoin(list, ";");
+    }
+
+    return std::string();
+  }
+} deviceLinkNode;
+
 std::string getLinkedTargetsContent(
   cmGeneratorTarget const* target, std::string const& prop,
   cmGeneratorExpressionContext* context,
@@ -1130,6 +1350,14 @@
         }
         return std::string();
       }
+      if (propertyName == "ALIAS_GLOBAL"_s) {
+        if (context->LG->GetMakefile()->IsAlias(targetName)) {
+          return context->LG->GetGlobalGenerator()->IsAlias(targetName)
+            ? "TRUE"
+            : "FALSE";
+        }
+        return std::string();
+      }
       target = context->LG->FindGeneratorTargetToUse(targetName);
 
       if (!target) {
@@ -1156,6 +1384,7 @@
           context, content->GetOriginalExpression(),
           "$<TARGET_PROPERTY:prop>  may only be used with binary targets.  "
           "It may not be used with add_custom_command or add_custom_target.  "
+          " "
           "Specify the target to read a property from using the "
           "$<TARGET_PROPERTY:tgt,prop> signature instead.");
         return std::string();
@@ -1247,8 +1476,9 @@
     }
 
     if (isInterfaceProperty) {
-      return target->EvaluateInterfaceProperty(propertyName, context,
-                                               dagCheckerParent);
+      return cmGeneratorExpression::StripEmptyListElements(
+        target->EvaluateInterfaceProperty(propertyName, context,
+                                          dagCheckerParent));
     }
 
     cmGeneratorExpressionDAGChecker dagChecker(
@@ -1270,8 +1500,8 @@
 
     std::string result;
     bool haveProp = false;
-    if (const char* p = target->GetProperty(propertyName)) {
-      result = p;
+    if (cmProp p = target->GetProperty(propertyName)) {
+      result = *p;
       haveProp = true;
     } else if (evaluatingLinkLibraries) {
       return std::string();
@@ -1334,8 +1564,9 @@
     }
 
     if (!interfacePropertyName.empty()) {
-      result = this->EvaluateDependentExpression(result, context->LG, context,
-                                                 target, &dagChecker, target);
+      result = cmGeneratorExpression::StripEmptyListElements(
+        this->EvaluateDependentExpression(result, context->LG, context, target,
+                                          &dagChecker, target));
       std::string linkedTargetsContent = getLinkedTargetsContent(
         target, interfacePropertyName, context, &dagChecker);
       if (!linkedTargetsContent.empty()) {
@@ -1418,11 +1649,11 @@
     std::vector<std::string> objects;
 
     if (gt->IsImported()) {
-      const char* loc = nullptr;
-      const char* imp = nullptr;
+      cmProp loc = nullptr;
+      cmProp imp = nullptr;
       std::string suffix;
-      if (gt->Target->GetMappedConfig(context->Config, &loc, &imp, suffix)) {
-        cmExpandList(loc, objects);
+      if (gt->Target->GetMappedConfig(context->Config, loc, imp, suffix)) {
+        cmExpandList(*loc, objects);
       }
       context->HadContextSensitiveCondition = true;
     } else {
@@ -1482,12 +1713,12 @@
     static LangMap availableFeatures;
 
     LangMap testedFeatures;
-
+    cmStandardLevelResolver standardResolver(context->LG->GetMakefile());
     for (std::string const& p : parameters) {
       std::string error;
       std::string lang;
-      if (!context->LG->GetMakefile()->CompileFeatureKnown(
-            context->HeadTarget->Target, p, lang, &error)) {
+      if (!standardResolver.CompileFeatureKnown(
+            context->HeadTarget->Target->GetName(), p, lang, &error)) {
         reportError(context, content->GetOriginalExpression(), error);
         return std::string();
       }
@@ -1495,7 +1726,7 @@
 
       if (availableFeatures.find(lang) == availableFeatures.end()) {
         const char* featuresKnown =
-          context->LG->GetMakefile()->CompileFeaturesAvailable(lang, &error);
+          standardResolver.CompileFeaturesAvailable(lang, &error);
         if (!featuresKnown) {
           reportError(context, content->GetOriginalExpression(), error);
           return std::string();
@@ -1509,26 +1740,26 @@
     for (auto const& lit : testedFeatures) {
       std::vector<std::string> const& langAvailable =
         availableFeatures[lit.first];
-      const char* standardDefault = context->LG->GetMakefile()->GetDefinition(
+      cmProp standardDefault = context->LG->GetMakefile()->GetDef(
         "CMAKE_" + lit.first + "_STANDARD_DEFAULT");
       for (std::string const& it : lit.second) {
-        if (!cmContains(langAvailable, it)) {
+        if (!cm::contains(langAvailable, it)) {
           return "0";
         }
-        if (standardDefault && !*standardDefault) {
+        if (standardDefault && standardDefault->empty()) {
           // This compiler has no notion of language standard levels.
           // All features known for the language are always available.
           continue;
         }
-        if (!context->LG->GetMakefile()->HaveStandardAvailable(
-              target->Target, lit.first, it)) {
+        if (!standardResolver.HaveStandardAvailable(target, lit.first,
+                                                    context->Config, it)) {
           if (evalLL) {
-            const char* l = target->GetProperty(lit.first + "_STANDARD");
+            cmProp l = target->GetLanguageStandard(lit.first, context->Config);
             if (!l) {
               l = standardDefault;
             }
             assert(l);
-            context->MaxLanguageStandard[target][lit.first] = l;
+            context->MaxLanguageStandard[target][lit.first] = *l;
           } else {
             return "0";
           }
@@ -2314,6 +2545,10 @@
     { "LINK_ONLY", &linkOnlyNode },
     { "COMPILE_LANG_AND_ID", &languageAndIdNode },
     { "COMPILE_LANGUAGE", &languageNode },
+    { "LINK_LANG_AND_ID", &linkLanguageAndIdNode },
+    { "LINK_LANGUAGE", &linkLanguageNode },
+    { "HOST_LINK", &hostLinkNode },
+    { "DEVICE_LINK", &deviceLinkNode },
     { "SHELL_PATH", &shellPathNode }
   };
 
diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx
index 36cf213..06c32fe 100644
--- a/Source/cmGeneratorTarget.cxx
+++ b/Source/cmGeneratorTarget.cxx
@@ -17,6 +17,8 @@
 
 #include <cm/memory>
 #include <cm/string_view>
+#include <cmext/algorithm>
+#include <cmext/string_view>
 
 #include "cmsys/RegularExpression.hxx"
 
@@ -35,11 +37,13 @@
 #include "cmLocalGenerator.h"
 #include "cmMakefile.h"
 #include "cmMessageType.h"
+#include "cmOutputConverter.h"
 #include "cmPropertyMap.h"
 #include "cmRange.h"
 #include "cmSourceFile.h"
 #include "cmSourceFileLocation.h"
 #include "cmSourceFileLocationKind.h"
+#include "cmStandardLevelResolver.h"
 #include "cmState.h"
 #include "cmStringAlgorithms.h"
 #include "cmSystemTools.h"
@@ -51,11 +55,11 @@
 class cmMessenger;
 
 template <>
-const char* cmTargetPropertyComputer::GetSources<cmGeneratorTarget>(
+cmProp cmTargetPropertyComputer::GetSources<cmGeneratorTarget>(
   cmGeneratorTarget const* tgt, cmMessenger* /* messenger */,
   cmListFileBacktrace const& /* context */)
 {
-  return tgt->GetSourcesProperty().c_str();
+  return &tgt->GetSourcesProperty();
 }
 
 template <>
@@ -236,17 +240,23 @@
   return ee;
 }
 
-std::vector<EvaluatedTargetPropertyEntry> EvaluateTargetPropertyEntries(
+struct EvaluatedTargetPropertyEntries
+{
+  std::vector<EvaluatedTargetPropertyEntry> Entries;
+  bool HadContextSensitiveCondition = false;
+};
+
+EvaluatedTargetPropertyEntries EvaluateTargetPropertyEntries(
   cmGeneratorTarget const* thisTarget, std::string const& config,
   std::string const& lang, cmGeneratorExpressionDAGChecker* dagChecker,
   std::vector<std::unique_ptr<cmGeneratorTarget::TargetPropertyEntry>> const&
     in)
 {
-  std::vector<EvaluatedTargetPropertyEntry> out;
-  out.reserve(in.size());
+  EvaluatedTargetPropertyEntries out;
+  out.Entries.reserve(in.size());
   for (auto& entry : in) {
-    out.emplace_back(EvaluateTargetPropertyEntry(thisTarget, config, lang,
-                                                 dagChecker, *entry));
+    out.Entries.emplace_back(EvaluateTargetPropertyEntry(
+      thisTarget, config, lang, dagChecker, *entry));
   }
   return out;
 }
@@ -308,6 +318,13 @@
                                      this->SourceEntries, true);
 
   this->PolicyMap = t->GetPolicyMap();
+
+  // Get hard-coded linker language
+  if (this->Target->GetProperty("HAS_CXX")) {
+    this->LinkerLanguage = "CXX";
+  } else {
+    this->LinkerLanguage = this->Target->GetSafeProperty("LINKER_LANGUAGE");
+  }
 }
 
 cmGeneratorTarget::~cmGeneratorTarget() = default;
@@ -346,29 +363,24 @@
 
 std::string cmGeneratorTarget::GetExportName() const
 {
-  const char* exportName = this->GetProperty("EXPORT_NAME");
+  cmProp exportName = this->GetProperty("EXPORT_NAME");
 
-  if (exportName && *exportName) {
-    if (!cmGeneratorExpression::IsValidTargetName(exportName)) {
+  if (cmNonempty(exportName)) {
+    if (!cmGeneratorExpression::IsValidTargetName(*exportName)) {
       std::ostringstream e;
-      e << "EXPORT_NAME property \"" << exportName << "\" for \""
+      e << "EXPORT_NAME property \"" << *exportName << "\" for \""
         << this->GetName() << "\": is not valid.";
       cmSystemTools::Error(e.str());
       return "";
     }
-    return exportName;
+    return *exportName;
   }
   return this->GetName();
 }
 
-const char* cmGeneratorTarget::GetProperty(const std::string& prop) const
+cmProp cmGeneratorTarget::GetProperty(const std::string& prop) const
 {
-  if (!cmTargetPropertyComputer::PassesWhitelist(
-        this->GetType(), prop, this->Makefile->GetMessenger(),
-        this->GetBacktrace())) {
-    return nullptr;
-  }
-  if (const char* result = cmTargetPropertyComputer::GetProperty(
+  if (cmProp result = cmTargetPropertyComputer::GetProperty(
         this, prop, this->Makefile->GetMessenger(), this->GetBacktrace())) {
     return result;
   }
@@ -378,13 +390,16 @@
   return this->Target->GetProperty(prop);
 }
 
-const char* cmGeneratorTarget::GetSafeProperty(const std::string& prop) const
+std::string const& cmGeneratorTarget::GetSafeProperty(
+  std::string const& prop) const
 {
-  const char* ret = this->GetProperty(prop);
-  if (!ret) {
-    return "";
+  cmProp ret = this->GetProperty(prop);
+  if (ret) {
+    return *ret;
   }
-  return ret;
+
+  static std::string const s_empty;
+  return s_empty;
 }
 
 const char* cmGeneratorTarget::GetOutputTargetType(
@@ -473,8 +488,8 @@
 
     std::string outName;
     for (std::string const& p : props) {
-      if (const char* outNameProp = this->GetProperty(p)) {
-        outName = outNameProp;
+      if (cmProp outNameProp = this->GetProperty(p)) {
+        outName = *outNameProp;
         break;
       }
     }
@@ -530,18 +545,46 @@
 
 std::string cmGeneratorTarget::GetFilePostfix(const std::string& config) const
 {
-  const char* postfix = nullptr;
+  cmProp postfix = nullptr;
+  std::string frameworkPostfix;
   if (!config.empty()) {
     std::string configProp =
       cmStrCat(cmSystemTools::UpperCase(config), "_POSTFIX");
     postfix = this->GetProperty(configProp);
-    // Mac application bundles and frameworks have no postfix.
+
+    // Mac application bundles and frameworks have no regular postfix like
+    // libraries do.
     if (!this->IsImported() && postfix &&
         (this->IsAppBundleOnApple() || this->IsFrameworkOnApple())) {
       postfix = nullptr;
     }
+
+    // Frameworks created by multi config generators can have a special
+    // framework postfix.
+    frameworkPostfix = GetFrameworkMultiConfigPostfix(config);
+    if (!frameworkPostfix.empty()) {
+      postfix = &frameworkPostfix;
+    }
   }
-  return postfix ? postfix : std::string();
+  return postfix ? *postfix : std::string();
+}
+
+std::string cmGeneratorTarget::GetFrameworkMultiConfigPostfix(
+  const std::string& config) const
+{
+  cmProp postfix = nullptr;
+  if (!config.empty()) {
+    std::string configProp = cmStrCat("FRAMEWORK_MULTI_CONFIG_POSTFIX_",
+                                      cmSystemTools::UpperCase(config));
+    postfix = this->GetProperty(configProp);
+
+    if (!this->IsImported() && postfix &&
+        (this->IsFrameworkOnApple() &&
+         !GetGlobalGenerator()->IsMultiConfig())) {
+      postfix = nullptr;
+    }
+  }
+  return postfix ? *postfix : std::string();
 }
 
 const char* cmGeneratorTarget::GetFilePrefixInternal(
@@ -574,7 +617,7 @@
   }
 
   // Compute prefix value.
-  const char* targetPrefix =
+  cmProp targetPrefix =
     (isImportedLibraryArtifact ? this->GetProperty("IMPORT_PREFIX")
                                : this->GetProperty("PREFIX"));
 
@@ -582,17 +625,17 @@
     const char* prefixVar = this->Target->GetPrefixVariableInternal(artifact);
     if (!language.empty() && prefixVar && *prefixVar) {
       std::string langPrefix = prefixVar + std::string("_") + language;
-      targetPrefix = this->Makefile->GetDefinition(langPrefix);
+      targetPrefix = this->Makefile->GetDef(langPrefix);
     }
 
     // if there is no prefix on the target nor specific language
     // use the cmake definition.
     if (!targetPrefix && prefixVar) {
-      targetPrefix = this->Makefile->GetDefinition(prefixVar);
+      targetPrefix = this->Makefile->GetDef(prefixVar);
     }
   }
 
-  return targetPrefix;
+  return targetPrefix ? targetPrefix->c_str() : nullptr;
 }
 const char* cmGeneratorTarget::GetFileSuffixInternal(
   std::string const& config, cmStateEnums::ArtifactType artifact,
@@ -624,7 +667,7 @@
   }
 
   // Compute suffix value.
-  const char* targetSuffix =
+  cmProp targetSuffix =
     (isImportedLibraryArtifact ? this->GetProperty("IMPORT_SUFFIX")
                                : this->GetProperty("SUFFIX"));
 
@@ -632,17 +675,17 @@
     const char* suffixVar = this->Target->GetSuffixVariableInternal(artifact);
     if (!language.empty() && suffixVar && *suffixVar) {
       std::string langSuffix = suffixVar + std::string("_") + language;
-      targetSuffix = this->Makefile->GetDefinition(langSuffix);
+      targetSuffix = this->Makefile->GetDef(langSuffix);
     }
 
     // if there is no suffix on the target nor specific language
     // use the cmake definition.
     if (!targetSuffix && suffixVar) {
-      targetSuffix = this->Makefile->GetDefinition(suffixVar);
+      targetSuffix = this->Makefile->GetDef(suffixVar);
     }
   }
 
-  return targetSuffix;
+  return targetSuffix ? targetSuffix->c_str() : nullptr;
 }
 
 void cmGeneratorTarget::ClearSourcesCache()
@@ -705,9 +748,9 @@
                              std::vector<std::string>& result,
                              bool excludeImported, std::string const& language)
 {
-  if (const char* dirs =
+  if (cmProp dirs =
         depTgt->GetProperty("INTERFACE_SYSTEM_INCLUDE_DIRECTORIES")) {
-    cmExpandList(cmGeneratorExpression::Evaluate(dirs, lg, config, headTarget,
+    cmExpandList(cmGeneratorExpression::Evaluate(*dirs, lg, config, headTarget,
                                                  dagChecker, depTgt, language),
                  result);
   }
@@ -715,9 +758,8 @@
     return;
   }
 
-  if (const char* dirs =
-        depTgt->GetProperty("INTERFACE_INCLUDE_DIRECTORIES")) {
-    cmExpandList(cmGeneratorExpression::Evaluate(dirs, lg, config, headTarget,
+  if (cmProp dirs = depTgt->GetProperty("INTERFACE_INCLUDE_DIRECTORIES")) {
+    cmExpandList(cmGeneratorExpression::Evaluate(*dirs, lg, config, headTarget,
                                                  dagChecker, depTgt, language),
                  result);
   }
@@ -755,7 +797,8 @@
 
 void cmGeneratorTarget::ComputeObjectMapping()
 {
-  auto const& configs = this->Makefile->GetGeneratorConfigs();
+  auto const& configs =
+    this->Makefile->GetGeneratorConfigs(cmMakefile::IncludeEmptyConfig);
   std::set<std::string> configSet(configs.begin(), configs.end());
   if (configSet == this->VisitedConfigsForObjects) {
     return;
@@ -767,17 +810,17 @@
   }
 }
 
-const char* cmGeneratorTarget::GetFeature(const std::string& feature,
-                                          const std::string& config) const
+cmProp cmGeneratorTarget::GetFeature(const std::string& feature,
+                                     const std::string& config) const
 {
   if (!config.empty()) {
     std::string featureConfig =
       cmStrCat(feature, '_', cmSystemTools::UpperCase(config));
-    if (const char* value = this->GetProperty(featureConfig)) {
+    if (cmProp value = this->GetProperty(featureConfig)) {
       return value;
     }
   }
-  if (const char* value = this->GetProperty(feature)) {
+  if (cmProp value = this->GetProperty(feature)) {
     return value;
   }
   return this->LocalGenerator->GetFeature(feature, config);
@@ -805,10 +848,9 @@
 bool cmGeneratorTarget::IsIPOEnabled(std::string const& lang,
                                      std::string const& config) const
 {
-  const char* feature = "INTERPROCEDURAL_OPTIMIZATION";
-  const bool result = cmIsOn(this->GetFeature(feature, config));
+  cmProp feature = this->GetFeature("INTERPROCEDURAL_OPTIMIZATION", config);
 
-  if (!result) {
+  if (!cmIsOn(feature)) {
     // 'INTERPROCEDURAL_OPTIMIZATION' is off, no need to check policies
     return false;
   }
@@ -901,6 +943,61 @@
   return it != this->ExplicitObjectName.end();
 }
 
+BTs<std::string> const* cmGeneratorTarget::GetLanguageStandardProperty(
+  std::string const& lang, std::string const& config) const
+{
+  std::string key = cmStrCat(cmSystemTools::UpperCase(config), '-', lang);
+  auto langStandardIter = this->LanguageStandardMap.find(key);
+  if (langStandardIter != this->LanguageStandardMap.end()) {
+    return &langStandardIter->second;
+  }
+
+  return this->Target->GetLanguageStandardProperty(
+    cmStrCat(lang, "_STANDARD"));
+}
+
+cmProp cmGeneratorTarget::GetLanguageStandard(std::string const& lang,
+                                              std::string const& config) const
+{
+  BTs<std::string> const* languageStandard =
+    this->GetLanguageStandardProperty(lang, config);
+
+  if (languageStandard) {
+    return &(languageStandard->Value);
+  }
+
+  return nullptr;
+}
+
+cmProp cmGeneratorTarget::GetPropertyWithPairedLanguageSupport(
+  std::string const& lang, const char* suffix) const
+{
+  cmProp propertyValue = this->Target->GetProperty(cmStrCat(lang, suffix));
+  if (propertyValue == nullptr) {
+    // Check if we should use the value set by another language.
+    if (lang == "OBJC") {
+      propertyValue = this->GetPropertyWithPairedLanguageSupport("C", suffix);
+    } else if (lang == "OBJCXX" || lang == "CUDA") {
+      propertyValue =
+        this->GetPropertyWithPairedLanguageSupport("CXX", suffix);
+    }
+  }
+  return propertyValue;
+}
+
+cmProp cmGeneratorTarget::GetLanguageExtensions(std::string const& lang) const
+{
+  return this->GetPropertyWithPairedLanguageSupport(lang, "_EXTENSIONS");
+}
+
+bool cmGeneratorTarget::GetLanguageStandardRequired(
+  std::string const& lang) const
+{
+  cmProp p =
+    this->GetPropertyWithPairedLanguageSupport(lang, "_STANDARD_REQUIRED");
+  return cmIsOn(p);
+}
+
 void cmGeneratorTarget::GetModuleDefinitionSources(
   std::vector<cmSourceFile const*>& data, const std::string& config) const
 {
@@ -931,51 +1028,12 @@
   IMPLEMENT_VISIT(SourceKindExternalObject);
 }
 
-void cmGeneratorTarget::GetExpectedResxHeaders(std::set<std::string>& headers,
-                                               const std::string& config) const
-{
-  KindedSources const& kinded = this->GetKindedSources(config);
-  headers = kinded.ExpectedResxHeaders;
-}
-
-void cmGeneratorTarget::GetResxSources(std::vector<cmSourceFile const*>& data,
-                                       const std::string& config) const
-{
-  IMPLEMENT_VISIT(SourceKindResx);
-}
-
-void cmGeneratorTarget::GetAppManifest(std::vector<cmSourceFile const*>& data,
-                                       const std::string& config) const
-{
-  IMPLEMENT_VISIT(SourceKindAppManifest);
-}
-
 void cmGeneratorTarget::GetManifests(std::vector<cmSourceFile const*>& data,
                                      const std::string& config) const
 {
   IMPLEMENT_VISIT(SourceKindManifest);
 }
 
-void cmGeneratorTarget::GetCertificates(std::vector<cmSourceFile const*>& data,
-                                        const std::string& config) const
-{
-  IMPLEMENT_VISIT(SourceKindCertificate);
-}
-
-void cmGeneratorTarget::GetExpectedXamlHeaders(std::set<std::string>& headers,
-                                               const std::string& config) const
-{
-  KindedSources const& kinded = this->GetKindedSources(config);
-  headers = kinded.ExpectedXamlHeaders;
-}
-
-void cmGeneratorTarget::GetExpectedXamlSources(std::set<std::string>& srcs,
-                                               const std::string& config) const
-{
-  KindedSources const& kinded = this->GetKindedSources(config);
-  srcs = kinded.ExpectedXamlSources;
-}
-
 std::set<cmLinkItem> const& cmGeneratorTarget::GetUtilityItems() const
 {
   if (!this->UtilityItemsDone) {
@@ -995,12 +1053,6 @@
   return this->UtilityItems;
 }
 
-void cmGeneratorTarget::GetXamlSources(std::vector<cmSourceFile const*>& data,
-                                       const std::string& config) const
-{
-  IMPLEMENT_VISIT(SourceKindXaml);
-}
-
 const std::string& cmGeneratorTarget::GetLocation(
   const std::string& config) const
 {
@@ -1032,6 +1084,31 @@
   return this->Target->GetPostBuildCommands();
 }
 
+bool cmGeneratorTarget::IsInBuildSystem() const
+{
+  if (this->IsImported()) {
+    return false;
+  }
+  switch (this->Target->GetType()) {
+    case cmStateEnums::EXECUTABLE:
+    case cmStateEnums::STATIC_LIBRARY:
+    case cmStateEnums::SHARED_LIBRARY:
+    case cmStateEnums::MODULE_LIBRARY:
+    case cmStateEnums::OBJECT_LIBRARY:
+    case cmStateEnums::UTILITY:
+    case cmStateEnums::GLOBAL_TARGET:
+      return true;
+    case cmStateEnums::INTERFACE_LIBRARY:
+      // An INTERFACE library is in the build system if it has SOURCES.
+      if (!this->SourceEntries.empty()) {
+        return true;
+      }
+    case cmStateEnums::UNKNOWN_LIBRARY:
+      break;
+  }
+  return false;
+}
+
 bool cmGeneratorTarget::IsImported() const
 {
   return this->Target->IsImported();
@@ -1042,6 +1119,11 @@
   return this->Target->IsImportedGloballyVisible();
 }
 
+bool cmGeneratorTarget::CanCompileSources() const
+{
+  return this->Target->CanCompileSources();
+}
+
 const std::string& cmGeneratorTarget::GetLocationForBuild() const
 {
   static std::string location;
@@ -1052,7 +1134,8 @@
   }
 
   // Now handle the deprecated build-time configuration location.
-  location = this->GetDirectory();
+  std::string const noConfig;
+  location = this->GetDirectory(noConfig);
   const char* cfgid = this->Makefile->GetDefinition("CMAKE_CFG_INTDIR");
   if (cfgid && strcmp(cfgid, ".") != 0) {
     location += "/";
@@ -1134,8 +1217,8 @@
     bool& maybeInterfaceProp = i->second;
 
     // If this target itself has a non-empty property value, we are done.
-    const char* p = this->GetProperty(prop);
-    maybeInterfaceProp = p && *p;
+    cmProp p = this->GetProperty(prop);
+    maybeInterfaceProp = cmNonempty(p);
 
     // Otherwise, recurse to interface dependencies.
     if (!maybeInterfaceProp) {
@@ -1191,7 +1274,6 @@
       return result;
     case cmGeneratorExpressionDAGChecker::CYCLIC_REFERENCE:
       // No error. We just skip cyclic references.
-      return result;
     case cmGeneratorExpressionDAGChecker::ALREADY_SEEN:
       // No error. We have already seen this transitive property.
       return result;
@@ -1202,13 +1284,16 @@
   cmGeneratorTarget const* headTarget =
     context->HeadTarget ? context->HeadTarget : this;
 
-  if (const char* p = this->GetProperty(prop)) {
+  if (cmProp p = this->GetProperty(prop)) {
     result = cmGeneratorExpressionNode::EvaluateDependentExpression(
-      p, context->LG, context, headTarget, &dagChecker, this);
+      *p, context->LG, context, headTarget, &dagChecker, this);
   }
 
   if (cmLinkInterfaceLibraries const* iface = this->GetLinkInterfaceLibraries(
         context->Config, headTarget, usage_requirements_only)) {
+    context->HadContextSensitiveCondition =
+      context->HadContextSensitiveCondition ||
+      iface->HadContextSensitiveCondition;
     for (cmLinkItem const& lib : iface->Libraries) {
       // Broken code can have a target in its own link interface.
       // Don't follow such link interface entries so as not to create a
@@ -1247,15 +1332,99 @@
 }
 
 namespace {
+std::string AddSwiftInterfaceIncludeDirectories(
+  const cmGeneratorTarget* root, const cmGeneratorTarget* target,
+  const std::string& config, cmGeneratorExpressionDAGChecker* context)
+{
+  cmGeneratorExpressionDAGChecker dag{ target->GetBacktrace(), target,
+                                       "Swift_MODULE_DIRECTORY", nullptr,
+                                       context };
+  switch (dag.Check()) {
+    case cmGeneratorExpressionDAGChecker::SELF_REFERENCE:
+      dag.ReportError(nullptr,
+                      "$<TARGET_PROPERTY:" + target->GetName() +
+                        ",Swift_MODULE_DIRECTORY>");
+      CM_FALLTHROUGH;
+    case cmGeneratorExpressionDAGChecker::CYCLIC_REFERENCE:
+      // No error. We just skip cyclic references.
+    case cmGeneratorExpressionDAGChecker::ALREADY_SEEN:
+      // No error. We have already seen this transitive property.
+      return "";
+    case cmGeneratorExpressionDAGChecker::DAG:
+      break;
+  }
+
+  std::string directories;
+  if (const auto* interface =
+        target->GetLinkInterfaceLibraries(config, root, true)) {
+    for (const cmLinkItem& library : interface->Libraries) {
+      if (const cmGeneratorTarget* dependency = library.Target) {
+        if (cm::contains(dependency->GetAllConfigCompileLanguages(),
+                         "Swift")) {
+          std::string value =
+            dependency->GetSafeProperty("Swift_MODULE_DIRECTORY");
+          if (value.empty()) {
+            value =
+              dependency->GetLocalGenerator()->GetCurrentBinaryDirectory();
+          }
+
+          if (!directories.empty()) {
+            directories += ";";
+          }
+          directories += value;
+        }
+      }
+    }
+  }
+  return directories;
+}
+
+void AddSwiftImplicitIncludeDirectories(
+  const cmGeneratorTarget* target, const std::string& config,
+  EvaluatedTargetPropertyEntries& entries)
+{
+  if (const auto* libraries = target->GetLinkImplementationLibraries(config)) {
+    cmGeneratorExpressionDAGChecker dag{ target->GetBacktrace(), target,
+                                         "Swift_MODULE_DIRECTORY", nullptr,
+                                         nullptr };
+
+    for (const cmLinkImplItem& library : libraries->Libraries) {
+      if (const cmGeneratorTarget* dependency = library.Target) {
+        if (!dependency->IsInBuildSystem()) {
+          continue;
+        }
+        if (cm::contains(dependency->GetAllConfigCompileLanguages(),
+                         "Swift")) {
+          EvaluatedTargetPropertyEntry entry{ library, library.Backtrace };
+
+          if (cmProp val = dependency->GetProperty("Swift_MODULE_DIRECTORY")) {
+            entry.Values.emplace_back(*val);
+          } else {
+            entry.Values.emplace_back(
+              dependency->GetLocalGenerator()->GetCurrentBinaryDirectory());
+          }
+
+          cmExpandList(AddSwiftInterfaceIncludeDirectories(target, dependency,
+                                                           config, &dag),
+                       entry.Values);
+
+          entries.Entries.emplace_back(std::move(entry));
+        }
+      }
+    }
+  }
+}
+
 void AddInterfaceEntries(cmGeneratorTarget const* headTarget,
                          std::string const& config, std::string const& prop,
                          std::string const& lang,
                          cmGeneratorExpressionDAGChecker* dagChecker,
-                         std::vector<EvaluatedTargetPropertyEntry>& entries,
+                         EvaluatedTargetPropertyEntries& entries,
                          bool usage_requirements_only = true)
 {
   if (cmLinkImplementationLibraries const* impl =
         headTarget->GetLinkImplementationLibraries(config)) {
+    entries.HadContextSensitiveCondition = impl->HadContextSensitiveCondition;
     for (cmLinkImplItem const& lib : impl->Libraries) {
       if (lib.Target) {
         EvaluatedTargetPropertyEntry ee(lib, lib.Backtrace);
@@ -1269,7 +1438,7 @@
                        prop, &context, dagChecker, usage_requirements_only),
                      ee.Values);
         ee.ContextDependent = context.HadContextSensitiveCondition;
-        entries.emplace_back(std::move(ee));
+        entries.Entries.emplace_back(std::move(ee));
       }
     }
   }
@@ -1278,10 +1447,11 @@
 void AddObjectEntries(cmGeneratorTarget const* headTarget,
                       std::string const& config,
                       cmGeneratorExpressionDAGChecker* dagChecker,
-                      std::vector<EvaluatedTargetPropertyEntry>& entries)
+                      EvaluatedTargetPropertyEntries& entries)
 {
   if (cmLinkImplementationLibraries const* impl =
         headTarget->GetLinkImplementationLibraries(config)) {
+    entries.HadContextSensitiveCondition = impl->HadContextSensitiveCondition;
     for (cmLinkImplItem const& lib : impl->Libraries) {
       if (lib.Target &&
           lib.Target->GetType() == cmStateEnums::OBJECT_LIBRARY) {
@@ -1300,23 +1470,23 @@
         if (cge->GetHadContextSensitiveCondition()) {
           ee.ContextDependent = true;
         }
-        entries.emplace_back(std::move(ee));
+        entries.Entries.emplace_back(std::move(ee));
       }
     }
   }
 }
 
 bool processSources(cmGeneratorTarget const* tgt,
-                    std::vector<EvaluatedTargetPropertyEntry>& entries,
+                    EvaluatedTargetPropertyEntries& entries,
                     std::vector<BT<std::string>>& srcs,
                     std::unordered_set<std::string>& uniqueSrcs,
                     bool debugSources)
 {
   cmMakefile* mf = tgt->Target->GetMakefile();
 
-  bool contextDependent = false;
+  bool contextDependent = entries.HadContextSensitiveCondition;
 
-  for (EvaluatedTargetPropertyEntry& entry : entries) {
+  for (EvaluatedTargetPropertyEntry& entry : entries.Entries) {
     if (entry.ContextDependent) {
       contextDependent = true;
     }
@@ -1377,7 +1547,6 @@
   std::string const& config) const
 {
   std::vector<BT<std::string>> files;
-  assert(this->GetType() != cmStateEnums::INTERFACE_LIBRARY);
 
   if (!this->LocalGenerator->GetGlobalGenerator()->GetConfigureDoneCMP0026()) {
     // At configure-time, this method can be called as part of getting the
@@ -1401,14 +1570,11 @@
   }
 
   std::vector<std::string> debugProperties;
-  const char* debugProp =
-    this->Makefile->GetDefinition("CMAKE_DEBUG_TARGET_PROPERTIES");
-  if (debugProp) {
-    cmExpandList(debugProp, debugProperties);
-  }
+  this->Makefile->GetDefExpandList("CMAKE_DEBUG_TARGET_PROPERTIES",
+                                   debugProperties);
 
   bool debugSources =
-    !this->DebugSourcesDone && cmContains(debugProperties, "SOURCES");
+    !this->DebugSourcesDone && cm::contains(debugProperties, "SOURCES");
 
   if (this->LocalGenerator->GetGlobalGenerator()->GetConfigureDoneCMP0026()) {
     this->DebugSourcesDone = true;
@@ -1417,16 +1583,15 @@
   cmGeneratorExpressionDAGChecker dagChecker(this, "SOURCES", nullptr,
                                              nullptr);
 
-  std::vector<EvaluatedTargetPropertyEntry> entries =
-    EvaluateTargetPropertyEntries(this, config, std::string(), &dagChecker,
-                                  this->SourceEntries);
+  EvaluatedTargetPropertyEntries entries = EvaluateTargetPropertyEntries(
+    this, config, std::string(), &dagChecker, this->SourceEntries);
 
   std::unordered_set<std::string> uniqueSrcs;
   bool contextDependentDirectSources =
     processSources(this, entries, files, uniqueSrcs, debugSources);
 
   // Collect INTERFACE_SOURCES of all direct link-dependencies.
-  std::vector<EvaluatedTargetPropertyEntry> linkInterfaceSourcesEntries;
+  EvaluatedTargetPropertyEntries linkInterfaceSourcesEntries;
   AddInterfaceEntries(this, config, "INTERFACE_SOURCES", std::string(),
                       &dagChecker, linkInterfaceSourcesEntries);
   std::vector<std::string>::size_type numFilesBefore = files.size();
@@ -1437,7 +1602,7 @@
   bool contextDependentObjects = false;
   std::vector<std::string>::size_type numFilesBefore2 = files.size();
   if (this->GetType() != cmStateEnums::OBJECT_LIBRARY) {
-    std::vector<EvaluatedTargetPropertyEntry> linkObjectsEntries;
+    EvaluatedTargetPropertyEntries linkObjectsEntries;
     AddObjectEntries(this, config, &dagChecker, linkObjectsEntries);
     contextDependentObjects = processSources(this, linkObjectsEntries, files,
                                              uniqueSrcs, debugSources);
@@ -1573,10 +1738,16 @@
     std::string ext = cmSystemTools::LowerCase(sf->GetExtension());
     if (sf->GetCustomCommand()) {
       kind = SourceKindCustomCommand;
-    } else if (this->Target->GetType() == cmStateEnums::UTILITY) {
+    } else if (this->Target->GetType() == cmStateEnums::UTILITY ||
+               this->Target->GetType() == cmStateEnums::INTERFACE_LIBRARY
+               // XXX(clang-tidy): https://bugs.llvm.org/show_bug.cgi?id=44165
+               // NOLINTNEXTLINE(bugprone-branch-clone)
+    ) {
       kind = SourceKindExtra;
     } else if (this->IsSourceFilePartOfUnityBatch(sf->ResolveFullPath())) {
       kind = SourceKindUnityBatched;
+      // XXX(clang-tidy): https://bugs.llvm.org/show_bug.cgi?id=44165
+      // NOLINTNEXTLINE(bugprone-branch-clone)
     } else if (sf->GetPropertyAsBool("HEADER_FILE_ONLY")) {
       kind = SourceKindHeader;
     } else if (sf->GetPropertyAsBool("EXTERNAL_OBJECT")) {
@@ -1595,14 +1766,6 @@
       }
     } else if (ext == "resx") {
       kind = SourceKindResx;
-      // Build and save the name of the corresponding .h file
-      // This relationship will be used later when building the project files.
-      // Both names would have been auto generated from Visual Studio
-      // where the user supplied the file name and Visual Studio
-      // appended the suffix.
-      std::string resx = sf->ResolveFullPath();
-      std::string hFileName = resx.substr(0, resx.find_last_of('.')) + ".h";
-      files.ExpectedResxHeaders.insert(hFileName);
     } else if (ext == "appxmanifest") {
       kind = SourceKindAppManifest;
     } else if (ext == "manifest") {
@@ -1611,16 +1774,6 @@
       kind = SourceKindCertificate;
     } else if (ext == "xaml") {
       kind = SourceKindXaml;
-      // Build and save the name of the corresponding .h and .cpp file
-      // This relationship will be used later when building the project files.
-      // Both names would have been auto generated from Visual Studio
-      // where the user supplied the file name and Visual Studio
-      // appended the suffix.
-      std::string xaml = sf->ResolveFullPath();
-      std::string hFileName = xaml + ".h";
-      std::string cppFileName = xaml + ".cpp";
-      files.ExpectedXamlHeaders.insert(hFileName);
-      files.ExpectedXamlSources.insert(cppFileName);
     } else if (header_regex.find(sf->ResolveFullPath())) {
       kind = SourceKindHeader;
     } else {
@@ -1655,8 +1808,8 @@
 
 void cmGeneratorTarget::ComputeAllConfigSources() const
 {
-  std::vector<std::string> configs;
-  this->Makefile->GetConfigurations(configs);
+  std::vector<std::string> configs =
+    this->Makefile->GetGeneratorConfigs(cmMakefile::IncludeEmptyConfig);
 
   std::map<cmSourceFile const*, size_t> index;
 
@@ -1678,6 +1831,18 @@
   }
 }
 
+std::vector<cmGeneratorTarget::AllConfigSource>
+cmGeneratorTarget::GetAllConfigSources(SourceKind kind) const
+{
+  std::vector<AllConfigSource> result;
+  for (AllConfigSource const& source : this->GetAllConfigSources()) {
+    if (source.Kind == kind) {
+      result.push_back(source);
+    }
+  }
+  return result;
+}
+
 std::set<std::string> cmGeneratorTarget::GetAllConfigCompileLanguages() const
 {
   std::set<std::string> languages;
@@ -1703,14 +1868,14 @@
   // Check for a per-configuration output directory target property.
   std::string configUpper = cmSystemTools::UpperCase(config);
   std::string configProp = cmStrCat("COMPILE_PDB_NAME_", configUpper);
-  const char* config_name = this->GetProperty(configProp);
-  if (config_name && *config_name) {
-    return prefix + config_name + ".pdb";
+  cmProp config_name = this->GetProperty(configProp);
+  if (cmNonempty(config_name)) {
+    return prefix + *config_name + ".pdb";
   }
 
-  const char* name = this->GetProperty("COMPILE_PDB_NAME");
-  if (name && *name) {
-    return prefix + name + ".pdb";
+  cmProp name = this->GetProperty("COMPILE_PDB_NAME");
+  if (cmNonempty(name)) {
+    return prefix + *name + ".pdb";
   }
 
   return "";
@@ -1856,7 +2021,7 @@
     std::string sepVar =
       cmStrCat("CMAKE_SHARED_LIBRARY_RUNTIME_", ll, "_FLAG_SEP");
     const char* sep = this->Makefile->GetDefinition(sepVar);
-    if (sep && *sep) {
+    if (cmNonempty(sep)) {
       // TODO: Add ELF check to ABI detection and get rid of
       // CMAKE_EXECUTABLE_FORMAT.
       if (const char* fmt =
@@ -1892,10 +2057,9 @@
     if (this->GetType() != cmStateEnums::SHARED_LIBRARY) {
       return false;
     }
-    const char* install_name = this->GetProperty("INSTALL_NAME_DIR");
+    cmProp install_name = this->GetProperty("INSTALL_NAME_DIR");
     bool use_install_name = this->MacOSXUseInstallNameDir();
-    if (install_name && use_install_name &&
-        std::string(install_name) == "@rpath") {
+    if (install_name && use_install_name && *install_name == "@rpath") {
       install_name_is_rpath = true;
     } else if (install_name && use_install_name) {
       return false;
@@ -1908,7 +2072,7 @@
     if (cmGeneratorTarget::ImportInfo const* info =
           this->GetImportInfo(config)) {
       if (!info->NoSOName && !info->SOName.empty()) {
-        if (info->SOName.find("@rpath/") == 0) {
+        if (cmHasLiteralPrefix(info->SOName, "@rpath/")) {
           install_name_is_rpath = true;
         }
       } else {
@@ -1951,7 +2115,7 @@
     return false;
   }
 
-  const char* macosx_rpath_str = this->GetProperty("MACOSX_RPATH");
+  cmProp macosx_rpath_str = this->GetProperty("MACOSX_RPATH");
   if (macosx_rpath_str) {
     return this->GetPropertyAsBool("MACOSX_RPATH");
   }
@@ -1968,10 +2132,10 @@
 
 bool cmGeneratorTarget::MacOSXUseInstallNameDir() const
 {
-  const char* build_with_install_name =
+  cmProp build_with_install_name =
     this->GetProperty("BUILD_WITH_INSTALL_NAME_DIR");
   if (build_with_install_name) {
-    return cmIsOn(build_with_install_name);
+    return cmIsOn(*build_with_install_name);
   }
 
   cmPolicies::PolicyStatus cmp0068 = this->GetPolicyStatusCMP0068();
@@ -2025,7 +2189,7 @@
         return cmSystemTools::GetFilenameName(info->Location);
       }
       // Use the soname given if any.
-      if (info->SOName.find("@rpath/") == 0) {
+      if (cmHasLiteralPrefix(info->SOName, "@rpath/")) {
         return info->SOName.substr(6);
       }
       return info->SOName;
@@ -2053,11 +2217,8 @@
 {
   std::string fpath = cmStrCat(
     this->GetFullName(config, cmStateEnums::RuntimeBinaryArtifact), '.');
-  const char* ext = this->GetProperty("BUNDLE_EXTENSION");
-  if (!ext) {
-    ext = "app";
-  }
-  fpath += ext;
+  cmProp ext = this->GetProperty("BUNDLE_EXTENSION");
+  fpath += (ext ? *ext : "app");
   if (shouldAddContentLevel(level) &&
       !this->Makefile->PlatformIsAppleEmbedded()) {
     fpath += "/Contents";
@@ -2079,8 +2240,10 @@
 {
   std::string fpath = cmStrCat(
     this->GetOutputName(config, cmStateEnums::RuntimeBinaryArtifact), '.');
-  const char* ext = this->GetProperty("BUNDLE_EXTENSION");
-  if (!ext) {
+  std::string ext;
+  if (cmProp p = this->GetProperty("BUNDLE_EXTENSION")) {
+    ext = *p;
+  } else {
     if (this->IsXCTestOnApple()) {
       ext = "xctest";
     } else {
@@ -2103,11 +2266,8 @@
 {
   std::string fpath = cmStrCat(
     this->GetOutputName(config, cmStateEnums::RuntimeBinaryArtifact), '.');
-  const char* ext = this->GetProperty("BUNDLE_EXTENSION");
-  if (!ext) {
-    ext = "framework";
-  }
-  fpath += ext;
+  cmProp ext = this->GetProperty("BUNDLE_EXTENSION");
+  fpath += (ext ? *ext : "framework");
   if (shouldAddFullLevel(level) &&
       !this->Makefile->PlatformIsAppleEmbedded()) {
     fpath += "/Versions/";
@@ -2158,11 +2318,11 @@
 {
   if (this->Makefile->IsOn("CMAKE_PLATFORM_HAS_INSTALLNAME")) {
     std::string dir;
-    const char* install_name_dir = this->GetProperty("INSTALL_NAME_DIR");
+    cmProp install_name_dir = this->GetProperty("INSTALL_NAME_DIR");
 
     if (this->CanGenerateInstallNameDir(INSTALL_NAME_FOR_INSTALL)) {
-      if (install_name_dir && *install_name_dir) {
-        dir = install_name_dir;
+      if (cmNonempty(install_name_dir)) {
+        dir = *install_name_dir;
         cmGeneratorExpression::ReplaceInstallPrefix(dir, installPrefix);
         dir =
           cmGeneratorExpression::Evaluate(dir, this->LocalGenerator, config);
@@ -2207,8 +2367,8 @@
   if (this->GetType() == cmStateEnums::SHARED_LIBRARY ||
       this->GetType() == cmStateEnums::MODULE_LIBRARY ||
       this->IsExecutableWithExports()) {
-    if (const char* custom_export_name = this->GetProperty("DEFINE_SYMBOL")) {
-      this->ExportMacro = custom_export_name;
+    if (cmProp custom_export_name = this->GetProperty("DEFINE_SYMBOL")) {
+      this->ExportMacro = *custom_export_name;
     } else {
       std::string in = cmStrCat(this->GetName(), "_EXPORTS");
       this->ExportMacro = cmSystemTools::MakeCidentifier(in);
@@ -2224,11 +2384,12 @@
   cmTargetCollectLinkLanguages(cmGeneratorTarget const* target,
                                std::string config,
                                std::unordered_set<std::string>& languages,
-                               cmGeneratorTarget const* head)
+                               cmGeneratorTarget const* head, bool secondPass)
     : Config(std::move(config))
     , Languages(languages)
     , HeadTarget(head)
     , Target(target)
+    , SecondPass(secondPass)
   {
     this->Visited.insert(target);
   }
@@ -2270,11 +2431,14 @@
     if (!this->Visited.insert(item.Target).second) {
       return;
     }
-    cmLinkInterface const* iface =
-      item.Target->GetLinkInterface(this->Config, this->HeadTarget);
+    cmLinkInterface const* iface = item.Target->GetLinkInterface(
+      this->Config, this->HeadTarget, this->SecondPass);
     if (!iface) {
       return;
     }
+    if (iface->HadLinkLanguageSensitiveCondition) {
+      this->HadLinkLanguageSensitiveCondition = true;
+    }
 
     for (std::string const& language : iface->Languages) {
       this->Languages.insert(language);
@@ -2285,17 +2449,30 @@
     }
   }
 
+  bool GetHadLinkLanguageSensitiveCondition()
+  {
+    return HadLinkLanguageSensitiveCondition;
+  }
+
 private:
   std::string Config;
   std::unordered_set<std::string>& Languages;
   cmGeneratorTarget const* HeadTarget;
   const cmGeneratorTarget* Target;
   std::set<cmGeneratorTarget const*> Visited;
+  bool SecondPass;
+  bool HadLinkLanguageSensitiveCondition = false;
 };
 
 cmGeneratorTarget::LinkClosure const* cmGeneratorTarget::GetLinkClosure(
   const std::string& config) const
 {
+  // There is no link implementation for targets that cannot compile sources.
+  if (!this->CanCompileSources()) {
+    static LinkClosure const empty = { {}, {} };
+    return &empty;
+  }
+
   std::string key(cmSystemTools::UpperCase(config));
   auto i = this->LinkClosureMap.find(key);
   if (i == this->LinkClosureMap.end()) {
@@ -2321,7 +2498,7 @@
   {
     this->GG = this->Target->GetLocalGenerator()->GetGlobalGenerator();
   }
-  void Consider(const char* lang)
+  void Consider(const std::string& lang)
   {
     int preference = this->GG->GetLinkerPreference(lang);
     if (preference > this->Preference) {
@@ -2354,40 +2531,36 @@
   }
 };
 
-void cmGeneratorTarget::ComputeLinkClosure(const std::string& config,
-                                           LinkClosure& lc) const
+bool cmGeneratorTarget::ComputeLinkClosure(const std::string& config,
+                                           LinkClosure& lc,
+                                           bool secondPass) const
 {
   // Get languages built in this target.
   std::unordered_set<std::string> languages;
-  cmLinkImplementation const* impl = this->GetLinkImplementation(config);
+  cmLinkImplementation const* impl =
+    this->GetLinkImplementation(config, secondPass);
   assert(impl);
-  for (std::string const& li : impl->Languages) {
-    languages.insert(li);
-  }
+  languages.insert(impl->Languages.cbegin(), impl->Languages.cend());
 
   // Add interface languages from linked targets.
-  cmTargetCollectLinkLanguages cll(this, config, languages, this);
+  // cmTargetCollectLinkLanguages cll(this, config, languages, this,
+  // secondPass);
+  cmTargetCollectLinkLanguages cll(this, config, languages, this, secondPass);
   for (cmLinkImplItem const& lib : impl->Libraries) {
     cll.Visit(lib);
   }
 
   // Store the transitive closure of languages.
-  for (std::string const& lang : languages) {
-    lc.Languages.push_back(lang);
-  }
+  cm::append(lc.Languages, languages);
 
   // Choose the language whose linker should be used.
-  if (this->GetProperty("HAS_CXX")) {
-    lc.LinkerLanguage = "CXX";
-  } else if (const char* linkerLang = this->GetProperty("LINKER_LANGUAGE")) {
-    lc.LinkerLanguage = linkerLang;
-  } else {
+  if (secondPass || lc.LinkerLanguage.empty()) {
     // Find the language with the highest preference value.
     cmTargetSelectLinker tsl(this);
 
     // First select from the languages compiled directly in this target.
     for (std::string const& l : impl->Languages) {
-      tsl.Consider(l.c_str());
+      tsl.Consider(l);
     }
 
     // Now consider languages that propagate from linked targets.
@@ -2395,12 +2568,50 @@
       std::string propagates =
         "CMAKE_" + lang + "_LINKER_PREFERENCE_PROPAGATES";
       if (this->Makefile->IsOn(propagates)) {
-        tsl.Consider(lang.c_str());
+        tsl.Consider(lang);
       }
     }
 
     lc.LinkerLanguage = tsl.Choose();
   }
+
+  return impl->HadLinkLanguageSensitiveCondition ||
+    cll.GetHadLinkLanguageSensitiveCondition();
+}
+
+void cmGeneratorTarget::ComputeLinkClosure(const std::string& config,
+                                           LinkClosure& lc) const
+{
+  bool secondPass = false;
+
+  {
+    LinkClosure linkClosure;
+    linkClosure.LinkerLanguage = this->LinkerLanguage;
+
+    // Get languages built in this target.
+    secondPass = this->ComputeLinkClosure(config, linkClosure, false);
+    this->LinkerLanguage = linkClosure.LinkerLanguage;
+    if (!secondPass) {
+      lc = std::move(linkClosure);
+    }
+  }
+
+  if (secondPass) {
+    LinkClosure linkClosure;
+
+    this->ComputeLinkClosure(config, linkClosure, secondPass);
+    lc = std::move(linkClosure);
+
+    // linker language must not be changed between the two passes
+    if (this->LinkerLanguage != lc.LinkerLanguage) {
+      std::ostringstream e;
+      e << "Evaluation of $<LINK_LANGUAGE:...> or $<LINK_LAND_AND_ID:...> "
+           "changes\nthe linker language for target \""
+        << this->GetName() << "\" (from '" << this->LinkerLanguage << "' to '"
+        << lc.LinkerLanguage << "') which is invalid.";
+      cmSystemTools::Error(e.str());
+    }
+  }
 }
 
 void cmGeneratorTarget::GetFullNameComponents(
@@ -2450,9 +2661,9 @@
     return effectiveFolder;
   }
 
-  const char* targetFolder = this->GetProperty("FOLDER");
+  cmProp targetFolder = this->GetProperty("FOLDER");
   if (targetFolder) {
-    effectiveFolder += targetFolder;
+    effectiveFolder += *targetFolder;
   }
 
   return effectiveFolder;
@@ -2578,6 +2789,12 @@
 cmGeneratorTarget::GetLinkImplementationClosure(
   const std::string& config) const
 {
+  // There is no link implementation for targets that cannot compile sources.
+  if (!this->CanCompileSources()) {
+    static std::vector<const cmGeneratorTarget*> const empty;
+    return empty;
+  }
+
   LinkImplClosure& tgts = this->LinkImplClosureMap[config];
   if (!tgts.Done) {
     tgts.Done = true;
@@ -2585,6 +2802,7 @@
 
     cmLinkImplementationLibraries const* impl =
       this->GetLinkImplementationLibraries(config);
+    assert(impl);
 
     for (cmLinkImplItem const& lib : impl->Libraries) {
       processILibs(config, this, lib,
@@ -2634,29 +2852,26 @@
   this->CurrentEntry = nullptr;
 
   // Queue all the source files already specified for the target.
-  if (target->GetType() != cmStateEnums::INTERFACE_LIBRARY) {
-    std::set<cmSourceFile*> emitted;
-    std::vector<std::string> const& configs =
-      this->Makefile->GetGeneratorConfigs();
-    for (std::string const& c : configs) {
-      std::vector<cmSourceFile*> sources;
-      this->GeneratorTarget->GetSourceFiles(sources, c);
-      for (cmSourceFile* sf : sources) {
-        const std::set<cmGeneratorTarget const*> tgts =
-          this->GlobalGenerator->GetFilenameTargetDepends(sf);
-        if (cmContains(tgts, this->GeneratorTarget)) {
-          std::ostringstream e;
-          e << "Evaluation output file\n  \"" << sf->ResolveFullPath()
-            << "\"\ndepends on the sources of a target it is used in.  This "
-               "is a dependency loop and is not allowed.";
-          this->GeneratorTarget->LocalGenerator->IssueMessage(
-            MessageType::FATAL_ERROR, e.str());
-          return;
-        }
-        if (emitted.insert(sf).second &&
-            this->SourcesQueued.insert(sf).second) {
-          this->SourceQueue.push(sf);
-        }
+  std::set<cmSourceFile*> emitted;
+  std::vector<std::string> const& configs =
+    this->Makefile->GetGeneratorConfigs(cmMakefile::IncludeEmptyConfig);
+  for (std::string const& c : configs) {
+    std::vector<cmSourceFile*> sources;
+    this->GeneratorTarget->GetSourceFiles(sources, c);
+    for (cmSourceFile* sf : sources) {
+      const std::set<cmGeneratorTarget const*> tgts =
+        this->GlobalGenerator->GetFilenameTargetDepends(sf);
+      if (cm::contains(tgts, this->GeneratorTarget)) {
+        std::ostringstream e;
+        e << "Evaluation output file\n  \"" << sf->ResolveFullPath()
+          << "\"\ndepends on the sources of a target it is used in.  This "
+             "is a dependency loop and is not allowed.";
+        this->GeneratorTarget->LocalGenerator->IssueMessage(
+          MessageType::FATAL_ERROR, e.str());
+        return;
+      }
+      if (emitted.insert(sf).second && this->SourcesQueued.insert(sf).second) {
+        this->SourceQueue.push(sf);
       }
     }
   }
@@ -2677,8 +2892,8 @@
     this->CurrentEntry = &this->GeneratorTarget->SourceDepends[sf];
 
     // Queue dependencies added explicitly by the user.
-    if (const char* additionalDeps = sf->GetProperty("OBJECT_DEPENDS")) {
-      std::vector<std::string> objDeps = cmExpandedList(additionalDeps);
+    if (cmProp additionalDeps = sf->GetProperty("OBJECT_DEPENDS")) {
+      std::vector<std::string> objDeps = cmExpandedList(*additionalDeps);
       for (std::string& objDep : objDeps) {
         if (cmSystemTools::FileIsFullPath(objDep)) {
           objDep = cmSystemTools::CollapseFullPath(objDep);
@@ -2848,7 +3063,7 @@
   // Queue the custom command dependencies.
   std::set<std::string> emitted;
   std::vector<std::string> const& configs =
-    this->Makefile->GetGeneratorConfigs();
+    this->Makefile->GetGeneratorConfigs(cmMakefile::IncludeEmptyConfig);
   for (std::string const& conf : configs) {
     this->FollowCommandDepends(cc, conf, emitted);
   }
@@ -2909,7 +3124,7 @@
 void cmGeneratorTarget::GetAppleArchs(const std::string& config,
                                       std::vector<std::string>& archVec) const
 {
-  const char* archs = nullptr;
+  cmProp archs = nullptr;
   if (!config.empty()) {
     std::string defVarName =
       cmStrCat("OSX_ARCHITECTURES_", cmSystemTools::UpperCase(config));
@@ -2919,7 +3134,139 @@
     archs = this->GetProperty("OSX_ARCHITECTURES");
   }
   if (archs) {
-    cmExpandList(std::string(archs), archVec);
+    cmExpandList(*archs, archVec);
+  }
+}
+
+void cmGeneratorTarget::AddCUDAArchitectureFlags(std::string& flags) const
+{
+  const std::string& property = this->GetSafeProperty("CUDA_ARCHITECTURES");
+
+  if (property.empty()) {
+    switch (this->GetPolicyStatusCMP0104()) {
+      case cmPolicies::WARN:
+        if (!this->LocalGenerator->GetCMakeInstance()->GetIsInTryCompile()) {
+          this->Makefile->IssueMessage(
+            MessageType::AUTHOR_WARNING,
+            cmPolicies::GetPolicyWarning(cmPolicies::CMP0104) +
+              "\nCUDA_ARCHITECTURES is empty for target \"" + this->GetName() +
+              "\".");
+        }
+        CM_FALLTHROUGH;
+      case cmPolicies::OLD:
+        break;
+      default:
+        this->Makefile->IssueMessage(
+          MessageType::FATAL_ERROR,
+          "CUDA_ARCHITECTURES is empty for target \"" + this->GetName() +
+            "\".");
+    }
+  }
+
+  // If CUDA_ARCHITECTURES is false we don't add any architectures.
+  if (cmIsOff(property)) {
+    return;
+  }
+
+  struct CudaArchitecture
+  {
+    std::string name;
+    bool real{ true };
+    bool virtual_{ true };
+  };
+  std::vector<CudaArchitecture> architectures;
+
+  {
+    std::vector<std::string> options;
+    cmExpandList(property, options);
+
+    for (std::string& option : options) {
+      CudaArchitecture architecture;
+
+      // Architecture name is up to the first specifier.
+      std::size_t pos = option.find_first_of('-');
+      architecture.name = option.substr(0, pos);
+
+      if (pos != std::string::npos) {
+        cm::string_view specifier{ option.c_str() + pos + 1,
+                                   option.length() - pos - 1 };
+
+        if (specifier == "real") {
+          architecture.real = true;
+          architecture.virtual_ = false;
+        } else if (specifier == "virtual") {
+          architecture.real = false;
+          architecture.virtual_ = true;
+        } else {
+          this->Makefile->IssueMessage(
+            MessageType::FATAL_ERROR,
+            "Unknown CUDA architecture specifier \"" + std::string(specifier) +
+              "\".");
+        }
+      }
+
+      architectures.emplace_back(architecture);
+    }
+  }
+
+  std::string const& compiler =
+    this->Makefile->GetSafeDefinition("CMAKE_CUDA_COMPILER_ID");
+
+  if (compiler == "NVIDIA") {
+    for (CudaArchitecture& architecture : architectures) {
+      flags +=
+        " --generate-code=arch=compute_" + architecture.name + ",code=[";
+
+      if (architecture.virtual_) {
+        flags += "compute_" + architecture.name;
+
+        if (architecture.real) {
+          flags += ",";
+        }
+      }
+
+      if (architecture.real) {
+        flags += "sm_" + architecture.name;
+      }
+
+      flags += "]";
+    }
+  } else if (compiler == "Clang") {
+    for (CudaArchitecture& architecture : architectures) {
+      flags += " --cuda-gpu-arch=sm_" + architecture.name;
+
+      if (!architecture.real) {
+        Makefile->IssueMessage(
+          MessageType::WARNING,
+          "Clang doesn't support disabling CUDA real code generation.");
+      }
+
+      if (!architecture.virtual_) {
+        flags += " --no-cuda-include-ptx=sm_" + architecture.name;
+      }
+    }
+  }
+}
+
+void cmGeneratorTarget::AddCUDAToolkitFlags(std::string& flags) const
+{
+  std::string const& compiler =
+    this->Makefile->GetSafeDefinition("CMAKE_CUDA_COMPILER_ID");
+
+  if (compiler == "Clang") {
+    // Pass CUDA toolkit explicitly to Clang.
+    // Clang's searching for the system CUDA toolkit isn't very good and it's
+    // expected the user will explicitly pass the toolkit path.
+    // This also avoids Clang having to search for the toolkit on every
+    // invocation.
+    std::string toolkitRoot =
+      this->Makefile->GetSafeDefinition("CMAKE_CUDA_COMPILER_LIBRARY_ROOT");
+
+    if (!toolkitRoot.empty()) {
+      flags += " --cuda-path=" +
+        this->LocalGenerator->ConvertToOutputFormat(toolkitRoot,
+                                                    cmOutputConverter::SHELL);
+    }
   }
 }
 
@@ -2967,13 +3314,13 @@
 }
 
 namespace {
-void processIncludeDirectories(
-  cmGeneratorTarget const* tgt,
-  std::vector<EvaluatedTargetPropertyEntry>& entries,
-  std::vector<BT<std::string>>& includes,
-  std::unordered_set<std::string>& uniqueIncludes, bool debugIncludes)
+void processIncludeDirectories(cmGeneratorTarget const* tgt,
+                               EvaluatedTargetPropertyEntries& entries,
+                               std::vector<BT<std::string>>& includes,
+                               std::unordered_set<std::string>& uniqueIncludes,
+                               bool debugIncludes)
 {
-  for (EvaluatedTargetPropertyEntry& entry : entries) {
+  for (EvaluatedTargetPropertyEntry& entry : entries.Entries) {
     cmLinkImplItem const& item = entry.LinkImplItem;
     std::string const& targetName = item.AsStr();
     bool const fromImported = item.Target && item.Target->IsImported();
@@ -3081,44 +3428,45 @@
                                              nullptr, nullptr);
 
   std::vector<std::string> debugProperties;
-  const char* debugProp =
-    this->Makefile->GetDefinition("CMAKE_DEBUG_TARGET_PROPERTIES");
-  if (debugProp) {
-    cmExpandList(debugProp, debugProperties);
-  }
+  this->Makefile->GetDefExpandList("CMAKE_DEBUG_TARGET_PROPERTIES",
+                                   debugProperties);
 
   bool debugIncludes = !this->DebugIncludesDone &&
-    cmContains(debugProperties, "INCLUDE_DIRECTORIES");
+    cm::contains(debugProperties, "INCLUDE_DIRECTORIES");
 
   if (this->GlobalGenerator->GetConfigureDoneCMP0026()) {
     this->DebugIncludesDone = true;
   }
 
-  std::vector<EvaluatedTargetPropertyEntry> entries =
-    EvaluateTargetPropertyEntries(this, config, lang, &dagChecker,
-                                  this->IncludeDirectoriesEntries);
+  EvaluatedTargetPropertyEntries entries = EvaluateTargetPropertyEntries(
+    this, config, lang, &dagChecker, this->IncludeDirectoriesEntries);
+
+  if (lang == "Swift") {
+    AddSwiftImplicitIncludeDirectories(this, config, entries);
+  }
 
   AddInterfaceEntries(this, config, "INTERFACE_INCLUDE_DIRECTORIES", lang,
                       &dagChecker, entries);
 
   if (this->Makefile->IsOn("APPLE")) {
-    cmLinkImplementationLibraries const* impl =
-      this->GetLinkImplementationLibraries(config);
-    for (cmLinkImplItem const& lib : impl->Libraries) {
-      std::string libDir = cmSystemTools::CollapseFullPath(
-        lib.AsStr(), this->Makefile->GetHomeOutputDirectory());
+    if (cmLinkImplementationLibraries const* impl =
+          this->GetLinkImplementationLibraries(config)) {
+      for (cmLinkImplItem const& lib : impl->Libraries) {
+        std::string libDir = cmSystemTools::CollapseFullPath(
+          lib.AsStr(), this->Makefile->GetHomeOutputDirectory());
 
-      static cmsys::RegularExpression frameworkCheck(
-        "(.*\\.framework)(/Versions/[^/]+)?/[^/]+$");
-      if (!frameworkCheck.find(libDir)) {
-        continue;
+        static cmsys::RegularExpression frameworkCheck(
+          "(.*\\.framework)(/Versions/[^/]+)?/[^/]+$");
+        if (!frameworkCheck.find(libDir)) {
+          continue;
+        }
+
+        libDir = frameworkCheck.match(1);
+
+        EvaluatedTargetPropertyEntry ee(lib, cmListFileBacktrace());
+        ee.Values.emplace_back(std::move(libDir));
+        entries.Entries.emplace_back(std::move(ee));
       }
-
-      libDir = frameworkCheck.match(1);
-
-      EvaluatedTargetPropertyEntry ee(lib, cmListFileBacktrace());
-      ee.Values.emplace_back(std::move(libDir));
-      entries.emplace_back(std::move(ee));
     }
   }
 
@@ -3135,22 +3483,38 @@
 };
 
 namespace {
+const auto DL_BEGIN = "<DEVICE_LINK>"_s;
+const auto DL_END = "</DEVICE_LINK>"_s;
+
 void processOptions(cmGeneratorTarget const* tgt,
-                    std::vector<EvaluatedTargetPropertyEntry> const& entries,
+                    EvaluatedTargetPropertyEntries const& entries,
                     std::vector<BT<std::string>>& options,
                     std::unordered_set<std::string>& uniqueOptions,
-                    bool debugOptions, const char* logName, OptionsParse parse)
+                    bool debugOptions, const char* logName, OptionsParse parse,
+                    bool processDeviceOptions = false)
 {
-  for (EvaluatedTargetPropertyEntry const& entry : entries) {
+  bool splitOption = !processDeviceOptions;
+  for (EvaluatedTargetPropertyEntry const& entry : entries.Entries) {
     std::string usedOptions;
     for (std::string const& opt : entry.Values) {
+      if (processDeviceOptions && (opt == DL_BEGIN || opt == DL_END)) {
+        options.emplace_back(opt, entry.Backtrace);
+        splitOption = opt == DL_BEGIN;
+        continue;
+      }
+
       if (uniqueOptions.insert(opt).second) {
         if (parse == OptionsParse::Shell &&
             cmHasLiteralPrefix(opt, "SHELL:")) {
-          std::vector<std::string> tmp;
-          cmSystemTools::ParseUnixCommandLine(opt.c_str() + 6, tmp);
-          for (std::string& o : tmp) {
-            options.emplace_back(std::move(o), entry.Backtrace);
+          if (splitOption) {
+            std::vector<std::string> tmp;
+            cmSystemTools::ParseUnixCommandLine(opt.c_str() + 6, tmp);
+            for (std::string& o : tmp) {
+              options.emplace_back(std::move(o), entry.Backtrace);
+            }
+          } else {
+            options.emplace_back(std::string(opt.c_str() + 6),
+                                 entry.Backtrace);
           }
         } else {
           options.emplace_back(opt, entry.Backtrace);
@@ -3169,6 +3533,63 @@
     }
   }
 }
+
+std::vector<BT<std::string>> wrapOptions(
+  std::vector<std::string>& options, const cmListFileBacktrace& bt,
+  const std::vector<std::string>& wrapperFlag, const std::string& wrapperSep,
+  bool concatFlagAndArgs)
+{
+  std::vector<BT<std::string>> result;
+
+  if (options.empty()) {
+    return result;
+  }
+
+  if (wrapperFlag.empty() || cmHasLiteralPrefix(options.front(), "LINKER:")) {
+    // nothing specified or LINKER wrapper, insert elements as is
+    result.reserve(options.size());
+    for (std::string& o : options) {
+      result.emplace_back(std::move(o), bt);
+    }
+  } else {
+    if (!wrapperSep.empty()) {
+      if (concatFlagAndArgs) {
+        // insert flag elements except last one
+        for (auto i = wrapperFlag.begin(); i != wrapperFlag.end() - 1; ++i) {
+          result.emplace_back(*i, bt);
+        }
+        // concatenate last flag element and all list values
+        // in one option
+        result.emplace_back(wrapperFlag.back() + cmJoin(options, wrapperSep),
+                            bt);
+      } else {
+        for (std::string const& i : wrapperFlag) {
+          result.emplace_back(i, bt);
+        }
+        // concatenate all list values in one option
+        result.emplace_back(cmJoin(options, wrapperSep), bt);
+      }
+    } else {
+      // prefix each element of list with wrapper
+      if (concatFlagAndArgs) {
+        std::transform(options.begin(), options.end(), options.begin(),
+                       [&wrapperFlag](std::string const& o) -> std::string {
+                         return wrapperFlag.back() + o;
+                       });
+      }
+      for (std::string& o : options) {
+        for (auto i = wrapperFlag.begin(),
+                  e = concatFlagAndArgs ? wrapperFlag.end() - 1
+                                        : wrapperFlag.end();
+             i != e; ++i) {
+          result.emplace_back(*i, bt);
+        }
+        result.emplace_back(std::move(o), bt);
+      }
+    }
+  }
+  return result;
+}
 }
 
 void cmGeneratorTarget::GetCompileOptions(std::vector<std::string>& result,
@@ -3192,22 +3613,18 @@
                                              nullptr);
 
   std::vector<std::string> debugProperties;
-  const char* debugProp =
-    this->Makefile->GetDefinition("CMAKE_DEBUG_TARGET_PROPERTIES");
-  if (debugProp) {
-    cmExpandList(debugProp, debugProperties);
-  }
+  this->Makefile->GetDefExpandList("CMAKE_DEBUG_TARGET_PROPERTIES",
+                                   debugProperties);
 
   bool debugOptions = !this->DebugCompileOptionsDone &&
-    cmContains(debugProperties, "COMPILE_OPTIONS");
+    cm::contains(debugProperties, "COMPILE_OPTIONS");
 
   if (this->GlobalGenerator->GetConfigureDoneCMP0026()) {
     this->DebugCompileOptionsDone = true;
   }
 
-  std::vector<EvaluatedTargetPropertyEntry> entries =
-    EvaluateTargetPropertyEntries(this, config, language, &dagChecker,
-                                  this->CompileOptionsEntries);
+  EvaluatedTargetPropertyEntries entries = EvaluateTargetPropertyEntries(
+    this, config, language, &dagChecker, this->CompileOptionsEntries);
 
   AddInterfaceEntries(this, config, "INTERFACE_COMPILE_OPTIONS", language,
                       &dagChecker, entries);
@@ -3238,22 +3655,18 @@
                                              nullptr);
 
   std::vector<std::string> debugProperties;
-  const char* debugProp =
-    this->Makefile->GetDefinition("CMAKE_DEBUG_TARGET_PROPERTIES");
-  if (debugProp) {
-    cmExpandList(debugProp, debugProperties);
-  }
+  this->Makefile->GetDefExpandList("CMAKE_DEBUG_TARGET_PROPERTIES",
+                                   debugProperties);
 
   bool debugFeatures = !this->DebugCompileFeaturesDone &&
-    cmContains(debugProperties, "COMPILE_FEATURES");
+    cm::contains(debugProperties, "COMPILE_FEATURES");
 
   if (this->GlobalGenerator->GetConfigureDoneCMP0026()) {
     this->DebugCompileFeaturesDone = true;
   }
 
-  std::vector<EvaluatedTargetPropertyEntry> entries =
-    EvaluateTargetPropertyEntries(this, config, std::string(), &dagChecker,
-                                  this->CompileFeaturesEntries);
+  EvaluatedTargetPropertyEntries entries = EvaluateTargetPropertyEntries(
+    this, config, std::string(), &dagChecker, this->CompileFeaturesEntries);
 
   AddInterfaceEntries(this, config, "INTERFACE_COMPILE_FEATURES",
                       std::string(), &dagChecker, entries);
@@ -3286,22 +3699,18 @@
                                              nullptr, nullptr);
 
   std::vector<std::string> debugProperties;
-  const char* debugProp =
-    this->Makefile->GetDefinition("CMAKE_DEBUG_TARGET_PROPERTIES");
-  if (debugProp) {
-    cmExpandList(debugProp, debugProperties);
-  }
+  this->Makefile->GetDefExpandList("CMAKE_DEBUG_TARGET_PROPERTIES",
+                                   debugProperties);
 
   bool debugDefines = !this->DebugCompileDefinitionsDone &&
-    cmContains(debugProperties, "COMPILE_DEFINITIONS");
+    cm::contains(debugProperties, "COMPILE_DEFINITIONS");
 
   if (this->GlobalGenerator->GetConfigureDoneCMP0026()) {
     this->DebugCompileDefinitionsDone = true;
   }
 
-  std::vector<EvaluatedTargetPropertyEntry> entries =
-    EvaluateTargetPropertyEntries(this, config, language, &dagChecker,
-                                  this->CompileDefinitionsEntries);
+  EvaluatedTargetPropertyEntries entries = EvaluateTargetPropertyEntries(
+    this, config, language, &dagChecker, this->CompileDefinitionsEntries);
 
   AddInterfaceEntries(this, config, "INTERFACE_COMPILE_DEFINITIONS", language,
                       &dagChecker, entries);
@@ -3309,7 +3718,7 @@
   if (!config.empty()) {
     std::string configPropName =
       "COMPILE_DEFINITIONS_" + cmSystemTools::UpperCase(config);
-    const char* configProp = this->GetProperty(configPropName);
+    cmProp configProp = this->GetProperty(configPropName);
     if (configProp) {
       switch (this->Makefile->GetPolicyStatus(cmPolicies::CMP0043)) {
         case cmPolicies::WARN: {
@@ -3320,8 +3729,8 @@
         }
         case cmPolicies::OLD: {
           std::unique_ptr<TargetPropertyEntry> entry =
-            CreateTargetPropertyEntry(configProp);
-          entries.emplace_back(EvaluateTargetPropertyEntry(
+            CreateTargetPropertyEntry(*configProp);
+          entries.Entries.emplace_back(EvaluateTargetPropertyEntry(
             this, config, language, &dagChecker, *entry));
         } break;
         case cmPolicies::NEW:
@@ -3347,11 +3756,8 @@
                                              nullptr, nullptr);
 
   std::vector<std::string> debugProperties;
-  const char* debugProp =
-    this->Makefile->GetDefinition("CMAKE_DEBUG_TARGET_PROPERTIES");
-  if (debugProp) {
-    cmExpandList(debugProp, debugProperties);
-  }
+  this->Makefile->GetDefExpandList("CMAKE_DEBUG_TARGET_PROPERTIES",
+                                   debugProperties);
 
   bool debugDefines = !this->DebugPrecompileHeadersDone &&
     std::find(debugProperties.begin(), debugProperties.end(),
@@ -3361,9 +3767,8 @@
     this->DebugPrecompileHeadersDone = true;
   }
 
-  std::vector<EvaluatedTargetPropertyEntry> entries =
-    EvaluateTargetPropertyEntries(this, config, language, &dagChecker,
-                                  this->PrecompileHeadersEntries);
+  EvaluatedTargetPropertyEntries entries = EvaluateTargetPropertyEntries(
+    this, config, language, &dagChecker, this->PrecompileHeadersEntries);
 
   AddInterfaceEntries(this, config, "INTERFACE_PRECOMPILE_HEADERS", language,
                       &dagChecker, entries);
@@ -3376,7 +3781,8 @@
 }
 
 std::string cmGeneratorTarget::GetPchHeader(const std::string& config,
-                                            const std::string& language) const
+                                            const std::string& language,
+                                            const std::string& arch) const
 {
   if (language != "C" && language != "CXX" && language != "OBJC" &&
       language != "OBJCXX") {
@@ -3387,11 +3793,11 @@
     return std::string();
   }
   const cmGeneratorTarget* generatorTarget = this;
-  const char* pchReuseFrom =
+  cmProp pchReuseFrom =
     generatorTarget->GetProperty("PRECOMPILE_HEADERS_REUSE_FROM");
 
   const auto inserted =
-    this->PchHeaders.insert(std::make_pair(language + config, ""));
+    this->PchHeaders.insert(std::make_pair(language + config + arch, ""));
   if (inserted.second) {
     const std::vector<BT<std::string>> headers =
       this->GetPrecompileHeaders(config, language);
@@ -3402,7 +3808,7 @@
 
     if (pchReuseFrom) {
       generatorTarget =
-        this->GetGlobalGenerator()->FindGeneratorTarget(pchReuseFrom);
+        this->GetGlobalGenerator()->FindGeneratorTarget(*pchReuseFrom);
     }
 
     filename = cmStrCat(
@@ -3423,7 +3829,8 @@
     }
 
     filename =
-      cmStrCat(filename, "/cmake_pch", languageToExtension.at(language));
+      cmStrCat(filename, "/cmake_pch", arch.empty() ? "" : cmStrCat("_", arch),
+               languageToExtension.at(language));
 
     const std::string filename_tmp = cmStrCat(filename, ".tmp");
     if (!pchReuseFrom) {
@@ -3482,34 +3889,35 @@
 }
 
 std::string cmGeneratorTarget::GetPchSource(const std::string& config,
-                                            const std::string& language) const
+                                            const std::string& language,
+                                            const std::string& arch) const
 {
   if (language != "C" && language != "CXX" && language != "OBJC" &&
       language != "OBJCXX") {
     return std::string();
   }
   const auto inserted =
-    this->PchSources.insert(std::make_pair(language + config, ""));
+    this->PchSources.insert(std::make_pair(language + config + arch, ""));
   if (inserted.second) {
-    const std::string pchHeader = this->GetPchHeader(config, language);
+    const std::string pchHeader = this->GetPchHeader(config, language, arch);
     if (pchHeader.empty()) {
       return std::string();
     }
     std::string& filename = inserted.first->second;
 
     const cmGeneratorTarget* generatorTarget = this;
-    const char* pchReuseFrom =
+    cmProp pchReuseFrom =
       generatorTarget->GetProperty("PRECOMPILE_HEADERS_REUSE_FROM");
     if (pchReuseFrom) {
       generatorTarget =
-        this->GetGlobalGenerator()->FindGeneratorTarget(pchReuseFrom);
+        this->GetGlobalGenerator()->FindGeneratorTarget(*pchReuseFrom);
     }
 
     filename =
       cmStrCat(generatorTarget->LocalGenerator->GetCurrentBinaryDirectory(),
                "/CMakeFiles/", generatorTarget->GetName(), ".dir/cmake_pch");
 
-    // For GCC the source extension will be tranformed into .h[xx].gch
+    // For GCC the source extension will be transformed into .h[xx].gch
     if (!this->Makefile->IsOn("CMAKE_LINK_PCH")) {
       const std::map<std::string, std::string> languageToExtension = {
         { "C", ".h.c" },
@@ -3518,13 +3926,15 @@
         { "OBJCXX", ".objcxx.hxx.mm" }
       };
 
-      filename += languageToExtension.at(language);
+      filename = cmStrCat(filename, arch.empty() ? "" : cmStrCat("_", arch),
+                          languageToExtension.at(language));
     } else {
       const std::map<std::string, std::string> languageToExtension = {
         { "C", ".c" }, { "CXX", ".cxx" }, { "OBJC", ".m" }, { "OBJCXX", ".mm" }
       };
 
-      filename += languageToExtension.at(language);
+      filename = cmStrCat(filename, arch.empty() ? "" : cmStrCat("_", arch),
+                          languageToExtension.at(language));
     }
 
     const std::string filename_tmp = cmStrCat(filename, ".tmp");
@@ -3541,16 +3951,17 @@
 }
 
 std::string cmGeneratorTarget::GetPchFileObject(const std::string& config,
-                                                const std::string& language)
+                                                const std::string& language,
+                                                const std::string& arch)
 {
   if (language != "C" && language != "CXX" && language != "OBJC" &&
       language != "OBJCXX") {
     return std::string();
   }
   const auto inserted =
-    this->PchObjectFiles.insert(std::make_pair(language + config, ""));
+    this->PchObjectFiles.insert(std::make_pair(language + config + arch, ""));
   if (inserted.second) {
-    const std::string pchSource = this->GetPchSource(config, language);
+    const std::string pchSource = this->GetPchSource(config, language, arch);
     if (pchSource.empty()) {
       return std::string();
     }
@@ -3560,15 +3971,20 @@
       pchSource, false, cmSourceFileLocationKind::Known);
 
     filename = cmStrCat(this->ObjectDirectory, this->GetObjectName(pchSf));
+    if (this->GetGlobalGenerator()->IsMultiConfig()) {
+      cmSystemTools::ReplaceString(
+        filename, this->GetGlobalGenerator()->GetCMakeCFGIntDir(), config);
+    }
   }
   return inserted.first->second;
 }
 
 std::string cmGeneratorTarget::GetPchFile(const std::string& config,
-                                          const std::string& language)
+                                          const std::string& language,
+                                          const std::string& arch)
 {
   const auto inserted =
-    this->PchFiles.insert(std::make_pair(language + config, ""));
+    this->PchFiles.insert(std::make_pair(language + config + arch, ""));
   if (inserted.second) {
     std::string& pchFile = inserted.first->second;
 
@@ -3588,20 +4004,20 @@
       };
 
       cmGeneratorTarget* generatorTarget = this;
-      const char* pchReuseFrom =
+      cmProp pchReuseFrom =
         generatorTarget->GetProperty("PRECOMPILE_HEADERS_REUSE_FROM");
       if (pchReuseFrom) {
         generatorTarget =
-          this->GetGlobalGenerator()->FindGeneratorTarget(pchReuseFrom);
+          this->GetGlobalGenerator()->FindGeneratorTarget(*pchReuseFrom);
       }
 
       const std::string pchFileObject =
-        generatorTarget->GetPchFileObject(config, language);
+        generatorTarget->GetPchFileObject(config, language, arch);
       if (!pchExtension.empty()) {
         pchFile = replaceExtension(pchFileObject, pchExtension);
       }
     } else {
-      pchFile = this->GetPchHeader(config, language);
+      pchFile = this->GetPchHeader(config, language, arch);
       pchFile += pchExtension;
     }
   }
@@ -3609,19 +4025,27 @@
 }
 
 std::string cmGeneratorTarget::GetPchCreateCompileOptions(
-  const std::string& config, const std::string& language)
+  const std::string& config, const std::string& language,
+  const std::string& arch)
 {
   const auto inserted = this->PchCreateCompileOptions.insert(
-    std::make_pair(language + config, ""));
+    std::make_pair(language + config + arch, ""));
   if (inserted.second) {
     std::string& createOptionList = inserted.first->second;
 
+    if (this->GetPropertyAsBool("PCH_WARN_INVALID")) {
+      createOptionList = this->Makefile->GetSafeDefinition(
+        cmStrCat("CMAKE_", language, "_COMPILE_OPTIONS_INVALID_PCH"));
+    }
+
     const std::string createOptVar =
       cmStrCat("CMAKE_", language, "_COMPILE_OPTIONS_CREATE_PCH");
-    createOptionList = this->Makefile->GetSafeDefinition(createOptVar);
 
-    const std::string pchHeader = this->GetPchHeader(config, language);
-    const std::string pchFile = this->GetPchFile(config, language);
+    createOptionList = cmStrCat(
+      createOptionList, ";", this->Makefile->GetSafeDefinition(createOptVar));
+
+    const std::string pchHeader = this->GetPchHeader(config, language, arch);
+    const std::string pchFile = this->GetPchFile(config, language, arch);
 
     cmSystemTools::ReplaceString(createOptionList, "<PCH_HEADER>", pchHeader);
     cmSystemTools::ReplaceString(createOptionList, "<PCH_FILE>", pchFile);
@@ -3630,19 +4054,33 @@
 }
 
 std::string cmGeneratorTarget::GetPchUseCompileOptions(
-  const std::string& config, const std::string& language)
+  const std::string& config, const std::string& language,
+  const std::string& arch)
 {
-  const auto inserted =
-    this->PchUseCompileOptions.insert(std::make_pair(language + config, ""));
+  const auto inserted = this->PchUseCompileOptions.insert(
+    std::make_pair(language + config + arch, ""));
   if (inserted.second) {
     std::string& useOptionList = inserted.first->second;
 
-    const std::string useOptVar =
-      cmStrCat("CMAKE_", language, "_COMPILE_OPTIONS_USE_PCH");
-    useOptionList = this->Makefile->GetSafeDefinition(useOptVar);
+    if (this->GetPropertyAsBool("PCH_WARN_INVALID")) {
+      useOptionList = this->Makefile->GetSafeDefinition(
+        cmStrCat("CMAKE_", language, "_COMPILE_OPTIONS_INVALID_PCH"));
+    }
 
-    const std::string pchHeader = this->GetPchHeader(config, language);
-    const std::string pchFile = this->GetPchFile(config, language);
+    const std::string useOptVar =
+      cmStrCat(language, "_COMPILE_OPTIONS_USE_PCH");
+
+    std::string const& useOptionListProperty =
+      this->GetSafeProperty(useOptVar);
+
+    useOptionList = cmStrCat(
+      useOptionList, ";",
+      useOptionListProperty.empty()
+        ? this->Makefile->GetSafeDefinition(cmStrCat("CMAKE_", useOptVar))
+        : useOptionListProperty);
+
+    const std::string pchHeader = this->GetPchHeader(config, language, arch);
+    const std::string pchFile = this->GetPchFile(config, language, arch);
 
     cmSystemTools::ReplaceString(useOptionList, "<PCH_HEADER>", pchHeader);
     cmSystemTools::ReplaceString(useOptionList, "<PCH_FILE>", pchFile);
@@ -3671,6 +4109,12 @@
                                        const std::string& config,
                                        const std::string& language) const
 {
+  if (this->IsDeviceLink() &&
+      this->GetPolicyStatusCMP0105() != cmPolicies::NEW) {
+    // link options are not propagated to the device link step
+    return;
+  }
+
   std::vector<BT<std::string>> tmp = this->GetLinkOptions(config, language);
   result.reserve(tmp.size());
   for (BT<std::string>& v : tmp) {
@@ -3688,37 +4132,83 @@
                                              nullptr);
 
   std::vector<std::string> debugProperties;
-  const char* debugProp =
-    this->Makefile->GetDefinition("CMAKE_DEBUG_TARGET_PROPERTIES");
-  if (debugProp) {
-    cmExpandList(debugProp, debugProperties);
-  }
+  this->Makefile->GetDefExpandList("CMAKE_DEBUG_TARGET_PROPERTIES",
+                                   debugProperties);
 
-  bool debugOptions =
-    !this->DebugLinkOptionsDone && cmContains(debugProperties, "LINK_OPTIONS");
+  bool debugOptions = !this->DebugLinkOptionsDone &&
+    cm::contains(debugProperties, "LINK_OPTIONS");
 
   if (this->GlobalGenerator->GetConfigureDoneCMP0026()) {
     this->DebugLinkOptionsDone = true;
   }
 
-  std::vector<EvaluatedTargetPropertyEntry> entries =
-    EvaluateTargetPropertyEntries(this, config, language, &dagChecker,
-                                  this->LinkOptionsEntries);
+  EvaluatedTargetPropertyEntries entries = EvaluateTargetPropertyEntries(
+    this, config, language, &dagChecker, this->LinkOptionsEntries);
 
   AddInterfaceEntries(this, config, "INTERFACE_LINK_OPTIONS", language,
                       &dagChecker, entries,
                       this->GetPolicyStatusCMP0099() != cmPolicies::NEW);
 
   processOptions(this, entries, result, uniqueOptions, debugOptions,
-                 "link options", OptionsParse::Shell);
+                 "link options", OptionsParse::Shell, this->IsDeviceLink());
+
+  if (this->IsDeviceLink()) {
+    // wrap host link options
+    const std::string wrapper(this->Makefile->GetSafeDefinition(
+      "CMAKE_" + language + "_DEVICE_COMPILER_WRAPPER_FLAG"));
+    std::vector<std::string> wrapperFlag = cmExpandedList(wrapper);
+    const std::string wrapperSep(this->Makefile->GetSafeDefinition(
+      "CMAKE_" + language + "_DEVICE_COMPILER_WRAPPER_FLAG_SEP"));
+    bool concatFlagAndArgs = true;
+    if (!wrapperFlag.empty() && wrapperFlag.back() == " ") {
+      concatFlagAndArgs = false;
+      wrapperFlag.pop_back();
+    }
+
+    auto it = result.begin();
+    while (it != result.end()) {
+      if (it->Value == DL_BEGIN) {
+        // device link options, no treatment
+        it = result.erase(it);
+        it = std::find_if(it, result.end(), [](const BT<std::string>& item) {
+          return item.Value == DL_END;
+        });
+        if (it != result.end()) {
+          it = result.erase(it);
+        }
+      } else {
+        // host link options must be wrapped
+        std::vector<std::string> options;
+        cmSystemTools::ParseUnixCommandLine(it->Value.c_str(), options);
+        auto hostOptions = wrapOptions(options, it->Backtrace, wrapperFlag,
+                                       wrapperSep, concatFlagAndArgs);
+        it = result.erase(it);
+        // some compilers (like gcc 4.8 or Intel 19.0 or XLC 16) do not respect
+        // C++11 standard: 'std::vector::insert()' do not returns an iterator,
+        // so need to recompute the iterator after insertion.
+        if (it == result.end()) {
+          cm::append(result, hostOptions);
+          it = result.end();
+        } else {
+          auto index = it - result.begin();
+          result.insert(it, hostOptions.begin(), hostOptions.end());
+          it = result.begin() + index + hostOptions.size();
+        }
+      }
+    }
+  }
 
   // Last step: replace "LINKER:" prefixed elements by
   // actual linker wrapper
   const std::string wrapper(this->Makefile->GetSafeDefinition(
-    "CMAKE_" + language + "_LINKER_WRAPPER_FLAG"));
+    "CMAKE_" + language +
+    (this->IsDeviceLink() ? "_DEVICE_LINKER_WRAPPER_FLAG"
+                          : "_LINKER_WRAPPER_FLAG")));
   std::vector<std::string> wrapperFlag = cmExpandedList(wrapper);
   const std::string wrapperSep(this->Makefile->GetSafeDefinition(
-    "CMAKE_" + language + "_LINKER_WRAPPER_FLAG_SEP"));
+    "CMAKE_" + language +
+    (this->IsDeviceLink() ? "_DEVICE_LINKER_WRAPPER_FLAG_SEP"
+                          : "_LINKER_WRAPPER_FLAG_SEP")));
   bool concatFlagAndArgs = true;
   if (!wrapperFlag.empty() && wrapperFlag.back() == " ") {
     concatFlagAndArgs = false;
@@ -3764,51 +4254,8 @@
       return result;
     }
 
-    std::vector<BT<std::string>> options;
-    if (wrapperFlag.empty()) {
-      // nothing specified, insert elements as is
-      options.reserve(linkerOptions.size());
-      for (std::string& o : linkerOptions) {
-        options.emplace_back(std::move(o), bt);
-      }
-    } else {
-      if (!wrapperSep.empty()) {
-        if (concatFlagAndArgs) {
-          // insert flag elements except last one
-          for (auto i = wrapperFlag.begin(); i != wrapperFlag.end() - 1; ++i) {
-            options.emplace_back(*i, bt);
-          }
-          // concatenate last flag element and all LINKER list values
-          // in one option
-          options.emplace_back(
-            wrapperFlag.back() + cmJoin(linkerOptions, wrapperSep), bt);
-        } else {
-          for (std::string const& i : wrapperFlag) {
-            options.emplace_back(i, bt);
-          }
-          // concatenate all LINKER list values in one option
-          options.emplace_back(cmJoin(linkerOptions, wrapperSep), bt);
-        }
-      } else {
-        // prefix each element of LINKER list with wrapper
-        if (concatFlagAndArgs) {
-          std::transform(linkerOptions.begin(), linkerOptions.end(),
-                         linkerOptions.begin(),
-                         [&wrapperFlag](std::string const& o) -> std::string {
-                           return wrapperFlag.back() + o;
-                         });
-        }
-        for (std::string& o : linkerOptions) {
-          for (auto i = wrapperFlag.begin(),
-                    e = concatFlagAndArgs ? wrapperFlag.end() - 1
-                                          : wrapperFlag.end();
-               i != e; ++i) {
-            options.emplace_back(*i, bt);
-          }
-          options.emplace_back(std::move(o), bt);
-        }
-      }
-    }
+    std::vector<BT<std::string>> options = wrapOptions(
+      linkerOptions, bt, wrapperFlag, wrapperSep, concatFlagAndArgs);
     result.insert(entry, options.begin(), options.end());
   }
   return result;
@@ -3835,14 +4282,14 @@
   cmGeneratorExpressionDAGChecker dagChecker(this, "STATIC_LIBRARY_OPTIONS",
                                              nullptr, nullptr);
 
-  std::vector<EvaluatedTargetPropertyEntry> entries;
-  if (const char* linkOptions = this->GetProperty("STATIC_LIBRARY_OPTIONS")) {
-    std::vector<std::string> options = cmExpandedList(linkOptions);
+  EvaluatedTargetPropertyEntries entries;
+  if (cmProp linkOptions = this->GetProperty("STATIC_LIBRARY_OPTIONS")) {
+    std::vector<std::string> options = cmExpandedList(*linkOptions);
     for (const auto& option : options) {
       std::unique_ptr<TargetPropertyEntry> entry =
         CreateTargetPropertyEntry(option);
-      entries.emplace_back(EvaluateTargetPropertyEntry(this, config, language,
-                                                       &dagChecker, *entry));
+      entries.Entries.emplace_back(EvaluateTargetPropertyEntry(
+        this, config, language, &dagChecker, *entry));
     }
   }
   processOptions(this, entries, result, uniqueOptions, false,
@@ -3853,12 +4300,12 @@
 
 namespace {
 void processLinkDirectories(cmGeneratorTarget const* tgt,
-                            std::vector<EvaluatedTargetPropertyEntry>& entries,
+                            EvaluatedTargetPropertyEntries& entries,
                             std::vector<BT<std::string>>& directories,
                             std::unordered_set<std::string>& uniqueDirectories,
                             bool debugDirectories)
 {
-  for (EvaluatedTargetPropertyEntry& entry : entries) {
+  for (EvaluatedTargetPropertyEntry& entry : entries.Entries) {
     cmLinkImplItem const& item = entry.LinkImplItem;
     std::string const& targetName = item.AsStr();
 
@@ -3944,22 +4391,18 @@
                                              nullptr);
 
   std::vector<std::string> debugProperties;
-  const char* debugProp =
-    this->Makefile->GetDefinition("CMAKE_DEBUG_TARGET_PROPERTIES");
-  if (debugProp) {
-    cmExpandList(debugProp, debugProperties);
-  }
+  this->Makefile->GetDefExpandList("CMAKE_DEBUG_TARGET_PROPERTIES",
+                                   debugProperties);
 
   bool debugDirectories = !this->DebugLinkDirectoriesDone &&
-    cmContains(debugProperties, "LINK_DIRECTORIES");
+    cm::contains(debugProperties, "LINK_DIRECTORIES");
 
   if (this->GlobalGenerator->GetConfigureDoneCMP0026()) {
     this->DebugLinkDirectoriesDone = true;
   }
 
-  std::vector<EvaluatedTargetPropertyEntry> entries =
-    EvaluateTargetPropertyEntries(this, config, language, &dagChecker,
-                                  this->LinkDirectoriesEntries);
+  EvaluatedTargetPropertyEntries entries = EvaluateTargetPropertyEntries(
+    this, config, language, &dagChecker, this->LinkDirectoriesEntries);
 
   AddInterfaceEntries(this, config, "INTERFACE_LINK_DIRECTORIES", language,
                       &dagChecker, entries,
@@ -3990,14 +4433,14 @@
   cmGeneratorExpressionDAGChecker dagChecker(this, "LINK_DEPENDS", nullptr,
                                              nullptr);
 
-  std::vector<EvaluatedTargetPropertyEntry> entries;
-  if (const char* linkDepends = this->GetProperty("LINK_DEPENDS")) {
-    std::vector<std::string> depends = cmExpandedList(linkDepends);
+  EvaluatedTargetPropertyEntries entries;
+  if (cmProp linkDepends = this->GetProperty("LINK_DEPENDS")) {
+    std::vector<std::string> depends = cmExpandedList(*linkDepends);
     for (const auto& depend : depends) {
       std::unique_ptr<TargetPropertyEntry> entry =
         CreateTargetPropertyEntry(depend);
-      entries.emplace_back(EvaluateTargetPropertyEntry(this, config, language,
-                                                       &dagChecker, *entry));
+      entries.Entries.emplace_back(EvaluateTargetPropertyEntry(
+        this, config, language, &dagChecker, *entry));
     }
   }
   AddInterfaceEntries(this, config, "INTERFACE_LINK_DEPENDS", language,
@@ -4061,12 +4504,75 @@
 
 bool cmGeneratorTarget::ComputeCompileFeatures(std::string const& config) const
 {
+  // Compute the language standard based on the compile features.
+  cmStandardLevelResolver standardResolver(this->Makefile);
   std::vector<BT<std::string>> features = this->GetCompileFeatures(config);
   for (BT<std::string> const& f : features) {
-    if (!this->Makefile->AddRequiredTargetFeature(this->Target, f.Value)) {
+    std::string lang;
+    if (!standardResolver.CompileFeatureKnown(this->Target->GetName(), f.Value,
+                                              lang, nullptr)) {
       return false;
     }
+
+    std::string key = cmStrCat(cmSystemTools::UpperCase(config), '-', lang);
+    cmProp currentLanguageStandard = this->GetLanguageStandard(lang, config);
+
+    std::string newRequiredStandard;
+    if (!standardResolver.GetNewRequiredStandard(
+          this->Target->GetName(), f.Value, currentLanguageStandard,
+          newRequiredStandard)) {
+      return false;
+    }
+
+    if (!newRequiredStandard.empty()) {
+      BTs<std::string>& languageStandardProperty =
+        this->LanguageStandardMap[key];
+      if (languageStandardProperty.Value != newRequiredStandard) {
+        languageStandardProperty.Value = newRequiredStandard;
+        languageStandardProperty.Backtraces.clear();
+      }
+      languageStandardProperty.Backtraces.emplace_back(f.Backtrace);
+    }
   }
+
+  return true;
+}
+
+bool cmGeneratorTarget::ComputeCompileFeatures(
+  std::string const& config, std::set<LanguagePair> const& languagePairs) const
+{
+  for (const auto& language : languagePairs) {
+    BTs<std::string> const* generatorTargetLanguageStandard =
+      this->GetLanguageStandardProperty(language.first, config);
+    if (!generatorTargetLanguageStandard) {
+      // If the standard isn't explicitly set we copy it over from the
+      // specified paired language.
+      std::string key =
+        cmStrCat(cmSystemTools::UpperCase(config), '-', language.first);
+      BTs<std::string> const* standardToCopy =
+        this->GetLanguageStandardProperty(language.second, config);
+      if (standardToCopy != nullptr) {
+        this->LanguageStandardMap[key] = *standardToCopy;
+        generatorTargetLanguageStandard = &this->LanguageStandardMap[key];
+      } else {
+        cmProp defaultStandard = this->Makefile->GetDef(
+          cmStrCat("CMAKE_", language.second, "_STANDARD_DEFAULT"));
+        if (defaultStandard != nullptr) {
+          this->LanguageStandardMap[key] = BTs<std::string>(*defaultStandard);
+          generatorTargetLanguageStandard = &this->LanguageStandardMap[key];
+        }
+      }
+
+      // Custom updates for the CUDA standard.
+      if (generatorTargetLanguageStandard != nullptr &&
+          language.first == "CUDA") {
+        if (generatorTargetLanguageStandard->Value == "98") {
+          this->LanguageStandardMap[key].Value = "03";
+        }
+      }
+    }
+  }
+
   return true;
 }
 
@@ -4152,8 +4658,8 @@
   }
 
   // Check for library version properties.
-  const char* version = this->GetProperty("VERSION");
-  const char* soversion = this->GetProperty("SOVERSION");
+  cmProp version = this->GetProperty("VERSION");
+  cmProp soversion = this->GetProperty("SOVERSION");
   if (!this->HasSOName(config) ||
       this->Makefile->IsOn("CMAKE_PLATFORM_NO_VERSIONED_SONAME") ||
       this->IsFrameworkOnApple()) {
@@ -4188,17 +4694,18 @@
       targetNames.Real += this->GetFrameworkVersion();
       targetNames.Real += "/";
     }
-    targetNames.Real += targetNames.Base;
-    targetNames.SharedObject = targetNames.Real;
+    targetNames.Real += targetNames.Base + suffix;
+    targetNames.SharedObject = targetNames.Real + suffix;
   } else {
     // The library's soname.
     this->ComputeVersionedName(targetNames.SharedObject, prefix,
                                targetNames.Base, suffix, targetNames.Output,
-                               soversion);
+                               (soversion ? soversion->c_str() : nullptr));
 
     // The library's real name on disk.
     this->ComputeVersionedName(targetNames.Real, prefix, targetNames.Base,
-                               suffix, targetNames.Output, version);
+                               suffix, targetNames.Output,
+                               (version ? version->c_str() : nullptr));
   }
 
   // The import library name.
@@ -4231,10 +4738,13 @@
 // This versioning is supported only for executables and then only
 // when the platform supports symbolic links.
 #if defined(_WIN32) && !defined(__CYGWIN__)
-  const char* version = 0;
+  const char* version = nullptr;
 #else
   // Check for executable version properties.
-  const char* version = this->GetProperty("VERSION");
+  const char* version = nullptr;
+  if (cmProp p = this->GetProperty("VERSION")) {
+    version = p->c_str();
+  }
   if (this->GetType() != cmStateEnums::EXECUTABLE ||
       this->Makefile->IsOn("XCODE")) {
     version = nullptr;
@@ -4364,15 +4874,23 @@
   outBase += this->GetOutputName(config, artifact);
 
   // Append the per-configuration postfix.
-  outBase += configPostfix;
+  // When using Xcode, the postfix should be part of the suffix rather than
+  // the base, because the suffix ends up being used in Xcode's
+  // EXECUTABLE_SUFFIX attribute.
+  if (this->IsFrameworkOnApple() &&
+      GetGlobalGenerator()->GetName() == "Xcode") {
+    targetSuffix = configPostfix.c_str();
+  } else {
+    outBase += configPostfix;
+  }
 
   // Name shared libraries with their version number on some platforms.
-  if (const char* soversion = this->GetProperty("SOVERSION")) {
+  if (cmProp soversion = this->GetProperty("SOVERSION")) {
     if (this->GetType() == cmStateEnums::SHARED_LIBRARY &&
         !isImportedLibraryArtifact &&
         this->Makefile->IsOn("CMAKE_SHARED_LIBRARY_NAME_WITH_VERSION")) {
       outBase += "-";
-      outBase += soversion;
+      outBase += *soversion;
     }
   }
 
@@ -4403,8 +4921,8 @@
   props.emplace_back("PDB_NAME");
 
   for (std::string const& p : props) {
-    if (const char* outName = this->GetProperty(p)) {
-      base = outName;
+    if (cmProp outName = this->GetProperty(p)) {
+      base = *outName;
       break;
     }
   }
@@ -4430,8 +4948,8 @@
   props.emplace_back("PDB_NAME");
 
   for (std::string const& p : props) {
-    if (const char* outName = this->GetProperty(p)) {
-      base = outName;
+    if (cmProp outName = this->GetProperty(p)) {
+      base = *outName;
       break;
     }
   }
@@ -4503,16 +5021,16 @@
   } else {
     // Handle the MACOSX_PACKAGE_LOCATION property on source files that
     // were not listed in one of the other lists.
-    if (const char* location = sf->GetProperty("MACOSX_PACKAGE_LOCATION")) {
-      flags.MacFolder = location;
+    if (cmProp location = sf->GetProperty("MACOSX_PACKAGE_LOCATION")) {
+      flags.MacFolder = location->c_str();
       const bool stripResources =
         this->GlobalGenerator->ShouldStripResourcePath(this->Makefile);
-      if (strcmp(location, "Resources") == 0) {
+      if (*location == "Resources") {
         flags.Type = cmGeneratorTarget::SourceFileTypeResource;
         if (stripResources) {
           flags.MacFolder = "";
         }
-      } else if (cmHasLiteralPrefix(location, "Resources/")) {
+      } else if (cmHasLiteralPrefix(*location, "Resources/")) {
         flags.Type = cmGeneratorTarget::SourceFileTypeDeepResource;
         if (stripResources) {
           flags.MacFolder += strlen("Resources/");
@@ -4533,8 +5051,8 @@
   this->SourceFileFlagsConstructed = true;
 
   // Process public headers to mark the source files.
-  if (const char* files = this->GetProperty("PUBLIC_HEADER")) {
-    std::vector<std::string> relFiles = cmExpandedList(files);
+  if (cmProp files = this->GetProperty("PUBLIC_HEADER")) {
+    std::vector<std::string> relFiles = cmExpandedList(*files);
     for (std::string const& relFile : relFiles) {
       if (cmSourceFile* sf = this->Makefile->GetSource(relFile)) {
         SourceFileFlags& flags = this->SourceFlagsMap[sf];
@@ -4546,8 +5064,8 @@
 
   // Process private headers after public headers so that they take
   // precedence if a file is listed in both.
-  if (const char* files = this->GetProperty("PRIVATE_HEADER")) {
-    std::vector<std::string> relFiles = cmExpandedList(files);
+  if (cmProp files = this->GetProperty("PRIVATE_HEADER")) {
+    std::vector<std::string> relFiles = cmExpandedList(*files);
     for (std::string const& relFile : relFiles) {
       if (cmSourceFile* sf = this->Makefile->GetSource(relFile)) {
         SourceFileFlags& flags = this->SourceFlagsMap[sf];
@@ -4558,8 +5076,8 @@
   }
 
   // Mark sources listed as resources.
-  if (const char* files = this->GetProperty("RESOURCE")) {
-    std::vector<std::string> relFiles = cmExpandedList(files);
+  if (cmProp files = this->GetProperty("RESOURCE")) {
+    std::vector<std::string> relFiles = cmExpandedList(*files);
     for (std::string const& relFile : relFiles) {
       if (cmSourceFile* sf = this->Makefile->GetSource(relFile)) {
         SourceFileFlags& flags = this->SourceFlagsMap[sf];
@@ -4586,9 +5104,9 @@
       this->GetLinkImplementationClosure(config);
     for (cmGeneratorTarget const* li : deps) {
 #define CM_READ_COMPATIBLE_INTERFACE(X, x)                                    \
-  if (const char* prop = li->GetProperty("COMPATIBLE_INTERFACE_" #X)) {       \
+  if (cmProp prop = li->GetProperty("COMPATIBLE_INTERFACE_" #X)) {            \
     std::vector<std::string> props;                                           \
-    cmExpandList(prop, props);                                                \
+    cmExpandList(*prop, props);                                               \
     compat.Props##x.insert(props.begin(), props.end());                       \
   }
       CM_READ_COMPATIBLE_INTERFACE(BOOL, Bool)
@@ -4696,12 +5214,12 @@
                               const std::string& config, CompatibleType t,
                               PropertyType* /*unused*/)
 {
-  const char* prop = dependee->GetProperty(propName);
+  cmProp prop = dependee->GetProperty(propName);
   if (!prop) {
     return;
   }
 
-  std::vector<std::string> props = cmExpandedList(prop);
+  std::vector<std::string> props = cmExpandedList(*prop);
   std::string pdir =
     cmStrCat(cmSystemTools::GetCMakeRoot(), "/Help/prop_tgt/");
 
@@ -4855,7 +5373,8 @@
     std::ostringstream e;
     e << "Property \"" << prop << "\" appears in both the " << propsString
       << " property in the dependencies of target \"" << this->GetName()
-      << "\".  This is not allowed. A property may only require compatibility "
+      << "\".  This is not allowed. A property may only require "
+         "compatibility "
          "in a boolean interpretation, a numeric minimum, a numeric maximum "
          "or a "
          "string interpretation, but not a mixture.";
@@ -4930,8 +5449,8 @@
     return tgt->GetPropertyAsBool(prop);
   }
 
-  const char* value = tgt->GetProperty(prop);
-  return cmIsOn(genexInterpreter->Evaluate(value, prop));
+  cmProp value = tgt->GetProperty(prop);
+  return cmIsOn(genexInterpreter->Evaluate(value ? *value : "", prop));
 }
 
 template <>
@@ -4939,13 +5458,13 @@
   cmGeneratorTarget const* tgt, const std::string& prop,
   cmGeneratorExpressionInterpreter* genexInterpreter)
 {
-  const char* value = tgt->GetProperty(prop);
+  cmProp value = tgt->GetProperty(prop);
 
   if (genexInterpreter == nullptr) {
-    return value;
+    return value ? value->c_str() : nullptr;
   }
 
-  return genexInterpreter->Evaluate(value, prop).c_str();
+  return genexInterpreter->Evaluate(value ? *value : "", prop).c_str();
 }
 
 template <>
@@ -4953,13 +5472,13 @@
   cmGeneratorTarget const* tgt, const std::string& prop,
   cmGeneratorExpressionInterpreter* genexInterpreter)
 {
-  const char* value = tgt->GetProperty(prop);
+  cmProp value = tgt->GetProperty(prop);
 
   if (genexInterpreter == nullptr) {
-    return valueAsString(value);
+    return valueAsString(value ? value->c_str() : nullptr);
   }
 
-  return genexInterpreter->Evaluate(value, prop);
+  return genexInterpreter->Evaluate(value ? *value : "", prop);
 }
 
 template <typename PropertyType>
@@ -5104,7 +5623,7 @@
   PropertyType propContent = getTypedProperty<PropertyType>(tgt, p);
 
   std::vector<std::string> headPropKeys = tgt->GetPropertyKeys();
-  const bool explicitlySet = cmContains(headPropKeys, p);
+  const bool explicitlySet = cm::contains(headPropKeys, p);
 
   const bool impliedByUse = tgt->IsNullImpliedByLinkLibraries(p);
   assert((impliedByUse ^ explicitlySet) || (!impliedByUse && !explicitlySet));
@@ -5144,7 +5663,7 @@
 
     std::vector<std::string> propKeys = theTarget->GetPropertyKeys();
 
-    const bool ifaceIsSet = cmContains(propKeys, interfaceProperty);
+    const bool ifaceIsSet = cm::contains(propKeys, interfaceProperty);
     PropertyType ifacePropContent = getTypedProperty<PropertyType>(
       theTarget, interfaceProperty, genexInterpreter.get());
 
@@ -5237,6 +5756,13 @@
   return propContent;
 }
 
+bool cmGeneratorTarget::SetDeviceLink(bool deviceLink)
+{
+  bool previous = this->DeviceLink;
+  this->DeviceLink = deviceLink;
+  return previous;
+}
+
 bool cmGeneratorTarget::GetLinkInterfaceDependentBoolProperty(
   const std::string& p, const std::string& config) const
 {
@@ -5323,13 +5849,13 @@
 
   assert(this->GetType() != cmStateEnums::INTERFACE_LIBRARY);
 
-  if (const char* version = this->GetProperty(property)) {
+  if (cmProp version = this->GetProperty(property)) {
     // Try to parse the version number and store the results that were
     // successfully parsed.
     int parsed_major;
     int parsed_minor;
     int parsed_patch;
-    switch (sscanf(version, "%d.%d.%d", &parsed_major, &parsed_minor,
+    switch (sscanf(version->c_str(), "%d.%d.%d", &parsed_major, &parsed_minor,
                    &parsed_patch)) {
       case 3:
         patch = parsed_patch;
@@ -5346,6 +5872,25 @@
   }
 }
 
+std::string cmGeneratorTarget::GetRuntimeLinkLibrary(
+  std::string const& lang, std::string const& config) const
+{
+  // This is activated by the presence of a default selection whether or
+  // not it is overridden by a property.
+  cmProp runtimeLibraryDefault = this->Makefile->GetDef(
+    cmStrCat("CMAKE_", lang, "_RUNTIME_LIBRARY_DEFAULT"));
+  if (!cmNonempty(runtimeLibraryDefault)) {
+    return std::string();
+  }
+  cmProp runtimeLibraryValue =
+    this->Target->GetProperty(cmStrCat(lang, "_RUNTIME_LIBRARY"));
+  if (!runtimeLibraryValue) {
+    runtimeLibraryValue = runtimeLibraryDefault;
+  }
+  return cmSystemTools::UpperCase(cmGeneratorExpression::Evaluate(
+    *runtimeLibraryValue, this->LocalGenerator, config, this));
+}
+
 std::string cmGeneratorTarget::GetFortranModuleDirectory(
   std::string const& working_dir) const
 {
@@ -5363,8 +5908,8 @@
 {
   std::string mod_dir;
   std::string target_mod_dir;
-  if (const char* prop = this->GetProperty("Fortran_MODULE_DIRECTORY")) {
-    target_mod_dir = prop;
+  if (cmProp prop = this->GetProperty("Fortran_MODULE_DIRECTORY")) {
+    target_mod_dir = *prop;
   } else {
     std::string const& default_mod_dir =
       this->LocalGenerator->GetCurrentBinaryDirectory();
@@ -5395,11 +5940,11 @@
 {
   assert(this->GetType() != cmStateEnums::INTERFACE_LIBRARY);
 
-  if (const char* fversion = this->GetProperty("FRAMEWORK_VERSION")) {
-    return fversion;
+  if (cmProp fversion = this->GetProperty("FRAMEWORK_VERSION")) {
+    return *fversion;
   }
-  if (const char* tversion = this->GetProperty("VERSION")) {
-    return tversion;
+  if (cmProp tversion = this->GetProperty("VERSION")) {
+    return *tversion;
   }
   return "A";
 }
@@ -5429,14 +5974,11 @@
   const std::string& compatibilityType) const
 {
   std::vector<std::string> debugProperties;
-  const char* debugProp = this->Target->GetMakefile()->GetDefinition(
-    "CMAKE_DEBUG_TARGET_PROPERTIES");
-  if (debugProp) {
-    cmExpandList(debugProp, debugProperties);
-  }
+  this->Target->GetMakefile()->GetDefExpandList(
+    "CMAKE_DEBUG_TARGET_PROPERTIES", debugProperties);
 
-  bool debugOrigin =
-    !this->DebugCompatiblePropertiesDone[p] && cmContains(debugProperties, p);
+  bool debugOrigin = !this->DebugCompatiblePropertiesDone[p] &&
+    cm::contains(debugProperties, p);
 
   if (this->GlobalGenerator->GetConfigureDoneCMP0026()) {
     this->DebugCompatiblePropertiesDone[p] = true;
@@ -5492,31 +6034,44 @@
 void cmGeneratorTarget::ExpandLinkItems(
   std::string const& prop, std::string const& value, std::string const& config,
   cmGeneratorTarget const* headTarget, bool usage_requirements_only,
-  std::vector<cmLinkItem>& items, bool& hadHeadSensitiveCondition) const
+  std::vector<cmLinkItem>& items, bool& hadHeadSensitiveCondition,
+  bool& hadContextSensitiveCondition,
+  bool& hadLinkLanguageSensitiveCondition) const
 {
   // Keep this logic in sync with ComputeLinkImplementationLibraries.
   cmGeneratorExpression ge;
   cmGeneratorExpressionDAGChecker dagChecker(this, prop, nullptr, nullptr);
-  // The $<LINK_ONLY> expression may be in a link interface to specify private
-  // link dependencies that are otherwise excluded from usage requirements.
+  // The $<LINK_ONLY> expression may be in a link interface to specify
+  // private link dependencies that are otherwise excluded from usage
+  // requirements.
   if (usage_requirements_only) {
     dagChecker.SetTransitivePropertiesOnly();
   }
   std::vector<std::string> libs;
   std::unique_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(value);
-  cmExpandList(
-    cge->Evaluate(this->LocalGenerator, config, headTarget, &dagChecker, this),
-    libs);
+  cmExpandList(cge->Evaluate(this->LocalGenerator, config, headTarget,
+                             &dagChecker, this, headTarget->LinkerLanguage),
+               libs);
   this->LookupLinkItems(libs, cge->GetBacktrace(), items);
   hadHeadSensitiveCondition = cge->GetHadHeadSensitiveCondition();
+  hadContextSensitiveCondition = cge->GetHadContextSensitiveCondition();
+  hadLinkLanguageSensitiveCondition =
+    cge->GetHadLinkLanguageSensitiveCondition();
 }
 
 cmLinkInterface const* cmGeneratorTarget::GetLinkInterface(
   const std::string& config, cmGeneratorTarget const* head) const
 {
+  return this->GetLinkInterface(config, head, false);
+}
+
+cmLinkInterface const* cmGeneratorTarget::GetLinkInterface(
+  const std::string& config, cmGeneratorTarget const* head,
+  bool secondPass) const
+{
   // Imported targets have their own link interface.
   if (this->IsImported()) {
-    return this->GetImportLinkInterface(config, head, false);
+    return this->GetImportLinkInterface(config, head, false, secondPass);
   }
 
   // Link interfaces are not supported for executables that do not
@@ -5529,6 +6084,10 @@
   // Lookup any existing link interface for this configuration.
   cmHeadToLinkInterfaceMap& hm = this->GetHeadToLinkInterfaceMap(config);
 
+  if (secondPass) {
+    hm.erase(head);
+  }
+
   // If the link interface does not depend on the head target
   // then return the one we computed first.
   if (!hm.empty() && !hm.begin()->second.HadHeadSensitiveCondition) {
@@ -5543,7 +6102,7 @@
   if (!iface.AllDone) {
     iface.AllDone = true;
     if (iface.Exists) {
-      this->ComputeLinkInterface(config, iface, head);
+      this->ComputeLinkInterface(config, iface, head, secondPass);
     }
   }
 
@@ -5554,6 +6113,13 @@
   const std::string& config, cmOptionalLinkInterface& iface,
   cmGeneratorTarget const* headTarget) const
 {
+  this->ComputeLinkInterface(config, iface, headTarget, false);
+}
+
+void cmGeneratorTarget::ComputeLinkInterface(
+  const std::string& config, cmOptionalLinkInterface& iface,
+  cmGeneratorTarget const* headTarget, bool secondPass) const
+{
   if (iface.Explicit) {
     if (this->GetType() == cmStateEnums::SHARED_LIBRARY ||
         this->GetType() == cmStateEnums::STATIC_LIBRARY ||
@@ -5565,7 +6131,8 @@
         emitted.insert(lib);
       }
       if (this->GetType() != cmStateEnums::INTERFACE_LIBRARY) {
-        cmLinkImplementation const* impl = this->GetLinkImplementation(config);
+        cmLinkImplementation const* impl =
+          this->GetLinkImplementation(config, secondPass);
         for (cmLinkImplItem const& lib : impl->Libraries) {
           if (emitted.insert(lib).second) {
             if (lib.Target) {
@@ -5575,9 +6142,9 @@
               }
             } else {
               // TODO: Recognize shared library file names.  Perhaps this
-              // should be moved to cmComputeLinkInformation, but that creates
-              // a chicken-and-egg problem since this list is needed for its
-              // construction.
+              // should be moved to cmComputeLinkInformation, but that
+              // creates a chicken-and-egg problem since this list is needed
+              // for its construction.
             }
           }
         }
@@ -5595,7 +6162,7 @@
   if (this->LinkLanguagePropagatesToDependents()) {
     // Targets using this archive need its language runtime libraries.
     if (cmLinkImplementation const* impl =
-          this->GetLinkImplementation(config)) {
+          this->GetLinkImplementation(config, secondPass)) {
       iface.Languages = impl->Languages;
     }
   }
@@ -5612,11 +6179,11 @@
     // How many repetitions are needed if this library has cyclic
     // dependencies?
     std::string propName = cmStrCat("LINK_INTERFACE_MULTIPLICITY", suffix);
-    if (const char* config_reps = this->GetProperty(propName)) {
-      sscanf(config_reps, "%u", &iface.Multiplicity);
-    } else if (const char* reps =
+    if (cmProp config_reps = this->GetProperty(propName)) {
+      sscanf(config_reps->c_str(), "%u", &iface.Multiplicity);
+    } else if (cmProp reps =
                  this->GetProperty("LINK_INTERFACE_MULTIPLICITY")) {
-      sscanf(reps, "%u", &iface.Multiplicity);
+      sscanf(reps->c_str(), "%u", &iface.Multiplicity);
     }
   }
 }
@@ -5638,7 +6205,6 @@
   }
 
   // Lookup any existing link interface for this configuration.
-  std::string CONFIG = cmSystemTools::UpperCase(config);
   cmHeadToLinkInterfaceMap& hm =
     (usage_requirements_only
        ? this->GetHeadToLinkInterfaceUsageRequirementsMap(config)
@@ -5767,21 +6333,21 @@
   }
 
   // Select an output directory.
-  if (const char* config_outdir = this->GetProperty(configProp)) {
+  if (cmProp config_outdir = this->GetProperty(configProp)) {
     // Use the user-specified per-configuration output directory.
-    out = cmGeneratorExpression::Evaluate(config_outdir, this->LocalGenerator,
+    out = cmGeneratorExpression::Evaluate(*config_outdir, this->LocalGenerator,
                                           config);
 
     // Skip per-configuration subdirectory.
     conf.clear();
-  } else if (const char* outdir = this->GetProperty(propertyName)) {
+  } else if (cmProp outdir = this->GetProperty(propertyName)) {
     // Use the user-specified output directory.
     out =
-      cmGeneratorExpression::Evaluate(outdir, this->LocalGenerator, config);
+      cmGeneratorExpression::Evaluate(*outdir, this->LocalGenerator, config);
 
     // Skip per-configuration subdirectory if the value contained a
     // generator expression.
-    if (out != outdir) {
+    if (out != *outdir) {
       conf.clear();
     }
   } else if (this->GetType() == cmStateEnums::EXECUTABLE) {
@@ -5843,21 +6409,21 @@
   }
 
   // Select an output directory.
-  if (const char* config_outdir = this->GetProperty(configProp)) {
+  if (cmProp config_outdir = this->GetProperty(configProp)) {
     // Use the user-specified per-configuration output directory.
-    out = cmGeneratorExpression::Evaluate(config_outdir, this->LocalGenerator,
+    out = cmGeneratorExpression::Evaluate(*config_outdir, this->LocalGenerator,
                                           config);
 
     // Skip per-configuration subdirectory.
     conf.clear();
-  } else if (const char* outdir = this->GetProperty(propertyName)) {
+  } else if (cmProp outdir = this->GetProperty(propertyName)) {
     // Use the user-specified output directory.
     out =
-      cmGeneratorExpression::Evaluate(outdir, this->LocalGenerator, config);
+      cmGeneratorExpression::Evaluate(*outdir, this->LocalGenerator, config);
 
     // Skip per-configuration subdirectory if the value contained a
     // generator expression.
-    if (out != outdir) {
+    if (out != *outdir) {
       conf.clear();
     }
   }
@@ -5903,12 +6469,13 @@
                                  const std::string& prop,
                                  std::string& rpath) const
 {
-  const char* value = this->GetProperty(prop);
+  cmProp value = this->GetProperty(prop);
   if (!value) {
     return false;
   }
 
-  rpath = cmGeneratorExpression::Evaluate(value, this->LocalGenerator, config);
+  rpath =
+    cmGeneratorExpression::Evaluate(*value, this->LocalGenerator, config);
 
   return true;
 }
@@ -5927,7 +6494,7 @@
 
   // An explicit list of interface libraries may be set for shared
   // libraries and executables that export symbols.
-  const char* explicitLibraries = nullptr;
+  cmProp explicitLibraries = nullptr;
   std::string linkIfaceProp;
   bool const cmp0022NEW = (this->GetPolicyStatusCMP0022() != cmPolicies::OLD &&
                            this->GetPolicyStatusCMP0022() != cmPolicies::WARN);
@@ -5956,10 +6523,10 @@
       !this->PolicyWarnedCMP0022) {
     // Compare the explicitly set old link interface properties to the
     // preferred new link interface property one and warn if different.
-    const char* newExplicitLibraries =
+    cmProp newExplicitLibraries =
       this->GetProperty("INTERFACE_LINK_LIBRARIES");
     if (newExplicitLibraries &&
-        strcmp(newExplicitLibraries, explicitLibraries) != 0) {
+        (*newExplicitLibraries != *explicitLibraries)) {
       std::ostringstream w;
       /* clang-format off */
       w << cmPolicies::GetPolicyWarning(cmPolicies::CMP0022) << "\n"
@@ -5968,9 +6535,9 @@
         linkIfaceProp << " properties."
         "\n"
         "INTERFACE_LINK_LIBRARIES:\n"
-        "  " << newExplicitLibraries << "\n" <<
+        "  " << *newExplicitLibraries << "\n" <<
         linkIfaceProp << ":\n"
-        "  " << explicitLibraries << "\n";
+        "  " << *explicitLibraries << "\n";
       /* clang-format on */
       this->LocalGenerator->IssueMessage(MessageType::AUTHOR_WARNING, w.str());
       this->PolicyWarnedCMP0022 = true;
@@ -5989,18 +6556,25 @@
 
   if (explicitLibraries) {
     // The interface libraries have been explicitly set.
-    this->ExpandLinkItems(linkIfaceProp, explicitLibraries, config, headTarget,
-                          usage_requirements_only, iface.Libraries,
-                          iface.HadHeadSensitiveCondition);
-  } else if (!cmp0022NEW)
+    this->ExpandLinkItems(linkIfaceProp, *explicitLibraries, config,
+                          headTarget, usage_requirements_only, iface.Libraries,
+                          iface.HadHeadSensitiveCondition,
+                          iface.HadContextSensitiveCondition,
+                          iface.HadLinkLanguageSensitiveCondition);
+    return;
+  }
+
   // If CMP0022 is NEW then the plain tll signature sets the
   // INTERFACE_LINK_LIBRARIES, so if we get here then the project
   // cleared the property explicitly and we should not fall back
   // to the link implementation.
-  {
-    // The link implementation is the default link interface.
-    cmLinkImplementationLibraries const* impl =
-      this->GetLinkImplementationLibrariesInternal(config, headTarget);
+  if (cmp0022NEW) {
+    return;
+  }
+
+  // The link implementation is the default link interface.
+  if (cmLinkImplementationLibraries const* impl =
+        this->GetLinkImplementationLibrariesInternal(config, headTarget)) {
     iface.Libraries.insert(iface.Libraries.end(), impl->Libraries.begin(),
                            impl->Libraries.end());
     if (this->GetPolicyStatusCMP0022() == cmPolicies::WARN &&
@@ -6009,11 +6583,15 @@
       // preferred new link interface property and warn if different.
       std::vector<cmLinkItem> ifaceLibs;
       static const std::string newProp = "INTERFACE_LINK_LIBRARIES";
-      if (const char* newExplicitLibraries = this->GetProperty(newProp)) {
+      if (cmProp newExplicitLibraries = this->GetProperty(newProp)) {
         bool hadHeadSensitiveConditionDummy = false;
-        this->ExpandLinkItems(newProp, newExplicitLibraries, config,
+        bool hadContextSensitiveConditionDummy = false;
+        bool hadLinkLanguageSensitiveConditionDummy = false;
+        this->ExpandLinkItems(newProp, *newExplicitLibraries, config,
                               headTarget, usage_requirements_only, ifaceLibs,
-                              hadHeadSensitiveConditionDummy);
+                              hadHeadSensitiveConditionDummy,
+                              hadContextSensitiveConditionDummy,
+                              hadLinkLanguageSensitiveConditionDummy);
       }
       if (ifaceLibs != iface.Libraries) {
         std::string oldLibraries = cmJoin(impl->Libraries, ";");
@@ -6050,19 +6628,22 @@
 
 const cmLinkInterface* cmGeneratorTarget::GetImportLinkInterface(
   const std::string& config, cmGeneratorTarget const* headTarget,
-  bool usage_requirements_only) const
+  bool usage_requirements_only, bool secondPass) const
 {
   cmGeneratorTarget::ImportInfo const* info = this->GetImportInfo(config);
   if (!info) {
     return nullptr;
   }
 
-  std::string CONFIG = cmSystemTools::UpperCase(config);
   cmHeadToLinkInterfaceMap& hm =
     (usage_requirements_only
        ? this->GetHeadToLinkInterfaceUsageRequirementsMap(config)
        : this->GetHeadToLinkInterfaceMap(config));
 
+  if (secondPass) {
+    hm.erase(headTarget);
+  }
+
   // If the link interface does not depend on the head target
   // then return the one we computed first.
   if (!hm.empty() && !hm.begin()->second.HadHeadSensitiveCondition) {
@@ -6076,7 +6657,9 @@
     cmExpandList(info->Languages, iface.Languages);
     this->ExpandLinkItems(info->LibrariesProp, info->Libraries, config,
                           headTarget, usage_requirements_only, iface.Libraries,
-                          iface.HadHeadSensitiveCondition);
+                          iface.HadHeadSensitiveCondition,
+                          iface.HadContextSensitiveCondition,
+                          iface.HadLinkLanguageSensitiveCondition);
     std::vector<std::string> deps = cmExpandedList(info->SharedDeps);
     this->LookupLinkItems(deps, cmListFileBacktrace(), iface.SharedDeps);
   }
@@ -6132,17 +6715,17 @@
   // Initialize members.
   info.NoSOName = false;
 
-  const char* loc = nullptr;
-  const char* imp = nullptr;
+  cmProp loc = nullptr;
+  cmProp imp = nullptr;
   std::string suffix;
-  if (!this->Target->GetMappedConfig(desired_config, &loc, &imp, suffix)) {
+  if (!this->Target->GetMappedConfig(desired_config, loc, imp, suffix)) {
     return;
   }
 
   // Get the link interface.
   {
     std::string linkProp = "INTERFACE_LINK_LIBRARIES";
-    const char* propertyLibs = this->GetProperty(linkProp);
+    cmProp propertyLibs = this->GetProperty(linkProp);
 
     if (this->GetType() != cmStateEnums::INTERFACE_LIBRARY) {
       if (!propertyLibs) {
@@ -6157,12 +6740,12 @@
     }
     if (propertyLibs) {
       info.LibrariesProp = linkProp;
-      info.Libraries = propertyLibs;
+      info.Libraries = *propertyLibs;
     }
   }
   if (this->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
     if (loc) {
-      info.LibName = loc;
+      info.LibName = *loc;
     }
     return;
   }
@@ -6172,47 +6755,46 @@
 
   // Get the location.
   if (loc) {
-    info.Location = loc;
+    info.Location = *loc;
   } else {
     std::string impProp = cmStrCat("IMPORTED_LOCATION", suffix);
-    if (const char* config_location = this->GetProperty(impProp)) {
-      info.Location = config_location;
-    } else if (const char* location = this->GetProperty("IMPORTED_LOCATION")) {
-      info.Location = location;
+    if (cmProp config_location = this->GetProperty(impProp)) {
+      info.Location = *config_location;
+    } else if (cmProp location = this->GetProperty("IMPORTED_LOCATION")) {
+      info.Location = *location;
     }
   }
 
   // Get the soname.
   if (this->GetType() == cmStateEnums::SHARED_LIBRARY) {
     std::string soProp = cmStrCat("IMPORTED_SONAME", suffix);
-    if (const char* config_soname = this->GetProperty(soProp)) {
-      info.SOName = config_soname;
-    } else if (const char* soname = this->GetProperty("IMPORTED_SONAME")) {
-      info.SOName = soname;
+    if (cmProp config_soname = this->GetProperty(soProp)) {
+      info.SOName = *config_soname;
+    } else if (cmProp soname = this->GetProperty("IMPORTED_SONAME")) {
+      info.SOName = *soname;
     }
   }
 
   // Get the "no-soname" mark.
   if (this->GetType() == cmStateEnums::SHARED_LIBRARY) {
     std::string soProp = cmStrCat("IMPORTED_NO_SONAME", suffix);
-    if (const char* config_no_soname = this->GetProperty(soProp)) {
-      info.NoSOName = cmIsOn(config_no_soname);
-    } else if (const char* no_soname =
-                 this->GetProperty("IMPORTED_NO_SONAME")) {
-      info.NoSOName = cmIsOn(no_soname);
+    if (cmProp config_no_soname = this->GetProperty(soProp)) {
+      info.NoSOName = cmIsOn(*config_no_soname);
+    } else if (cmProp no_soname = this->GetProperty("IMPORTED_NO_SONAME")) {
+      info.NoSOName = cmIsOn(*no_soname);
     }
   }
 
   // Get the import library.
   if (imp) {
-    info.ImportLibrary = imp;
+    info.ImportLibrary = *imp;
   } else if (this->GetType() == cmStateEnums::SHARED_LIBRARY ||
              this->IsExecutableWithExports()) {
     std::string impProp = cmStrCat("IMPORTED_IMPLIB", suffix);
-    if (const char* config_implib = this->GetProperty(impProp)) {
-      info.ImportLibrary = config_implib;
-    } else if (const char* implib = this->GetProperty("IMPORTED_IMPLIB")) {
-      info.ImportLibrary = implib;
+    if (cmProp config_implib = this->GetProperty(impProp)) {
+      info.ImportLibrary = *config_implib;
+    } else if (cmProp implib = this->GetProperty("IMPORTED_IMPLIB")) {
+      info.ImportLibrary = *implib;
     }
   }
 
@@ -6220,11 +6802,11 @@
   {
     std::string linkProp =
       cmStrCat("IMPORTED_LINK_DEPENDENT_LIBRARIES", suffix);
-    if (const char* config_libs = this->GetProperty(linkProp)) {
-      info.SharedDeps = config_libs;
-    } else if (const char* libs =
+    if (cmProp config_libs = this->GetProperty(linkProp)) {
+      info.SharedDeps = *config_libs;
+    } else if (cmProp libs =
                  this->GetProperty("IMPORTED_LINK_DEPENDENT_LIBRARIES")) {
-      info.SharedDeps = libs;
+      info.SharedDeps = *libs;
     }
   }
 
@@ -6232,21 +6814,21 @@
   if (this->LinkLanguagePropagatesToDependents()) {
     std::string linkProp =
       cmStrCat("IMPORTED_LINK_INTERFACE_LANGUAGES", suffix);
-    if (const char* config_libs = this->GetProperty(linkProp)) {
-      info.Languages = config_libs;
-    } else if (const char* libs =
+    if (cmProp config_libs = this->GetProperty(linkProp)) {
+      info.Languages = *config_libs;
+    } else if (cmProp libs =
                  this->GetProperty("IMPORTED_LINK_INTERFACE_LANGUAGES")) {
-      info.Languages = libs;
+      info.Languages = *libs;
     }
   }
 
   // Get information if target is managed assembly.
   {
     std::string linkProp = "IMPORTED_COMMON_LANGUAGE_RUNTIME";
-    if (auto pc = this->GetProperty(linkProp + suffix)) {
-      info.Managed = this->CheckManagedType(pc);
-    } else if (auto p = this->GetProperty(linkProp)) {
-      info.Managed = this->CheckManagedType(p);
+    if (cmProp pc = this->GetProperty(linkProp + suffix)) {
+      info.Managed = this->CheckManagedType(*pc);
+    } else if (cmProp p = this->GetProperty(linkProp)) {
+      info.Managed = this->CheckManagedType(*p);
     }
   }
 
@@ -6254,11 +6836,11 @@
   if (this->GetType() == cmStateEnums::STATIC_LIBRARY) {
     std::string linkProp =
       cmStrCat("IMPORTED_LINK_INTERFACE_MULTIPLICITY", suffix);
-    if (const char* config_reps = this->GetProperty(linkProp)) {
-      sscanf(config_reps, "%u", &info.Multiplicity);
-    } else if (const char* reps =
+    if (cmProp config_reps = this->GetProperty(linkProp)) {
+      sscanf(config_reps->c_str(), "%u", &info.Multiplicity);
+    } else if (cmProp reps =
                  this->GetProperty("IMPORTED_LINK_INTERFACE_MULTIPLICITY")) {
-      sscanf(reps, "%u", &info.Multiplicity);
+      sscanf(reps->c_str(), "%u", &info.Multiplicity);
     }
   }
 }
@@ -6266,28 +6848,36 @@
 cmHeadToLinkInterfaceMap& cmGeneratorTarget::GetHeadToLinkInterfaceMap(
   const std::string& config) const
 {
-  std::string CONFIG = cmSystemTools::UpperCase(config);
-  return this->LinkInterfaceMap[CONFIG];
+  return this->LinkInterfaceMap[cmSystemTools::UpperCase(config)];
 }
 
 cmHeadToLinkInterfaceMap&
 cmGeneratorTarget::GetHeadToLinkInterfaceUsageRequirementsMap(
   const std::string& config) const
 {
-  std::string CONFIG = cmSystemTools::UpperCase(config);
-  return this->LinkInterfaceUsageRequirementsOnlyMap[CONFIG];
+  return this
+    ->LinkInterfaceUsageRequirementsOnlyMap[cmSystemTools::UpperCase(config)];
 }
 
 const cmLinkImplementation* cmGeneratorTarget::GetLinkImplementation(
   const std::string& config) const
 {
-  // There is no link implementation for imported targets.
-  if (this->IsImported()) {
+  return this->GetLinkImplementation(config, false);
+}
+
+const cmLinkImplementation* cmGeneratorTarget::GetLinkImplementation(
+  const std::string& config, bool secondPass) const
+{
+  // There is no link implementation for targets that cannot compile sources.
+  if (!this->CanCompileSources()) {
     return nullptr;
   }
 
-  std::string CONFIG = cmSystemTools::UpperCase(config);
-  cmOptionalLinkImplementation& impl = this->LinkImplMap[CONFIG][this];
+  cmOptionalLinkImplementation& impl =
+    this->LinkImplMap[cmSystemTools::UpperCase(config)][this];
+  if (secondPass) {
+    impl = cmOptionalLinkImplementation();
+  }
   if (!impl.LibrariesDone) {
     impl.LibrariesDone = true;
     this->ComputeLinkImplementationLibraries(config, impl, this);
@@ -6303,7 +6893,7 @@
   std::vector<cmSourceFile*>& files) const
 {
   std::vector<std::string> const& configs =
-    this->Makefile->GetGeneratorConfigs();
+    this->Makefile->GetGeneratorConfigs(cmMakefile::IncludeEmptyConfig);
 
   auto it = configs.begin();
   const std::string& firstConfig = *it;
@@ -6426,15 +7016,15 @@
 
 bool cmGeneratorTarget::IsDeprecated() const
 {
-  const char* deprecation = this->GetProperty("DEPRECATION");
-  return deprecation && *deprecation;
+  cmProp deprecation = this->GetProperty("DEPRECATION");
+  return cmNonempty(deprecation);
 }
 
 std::string cmGeneratorTarget::GetDeprecation() const
 {
   // find DEPRECATION property
-  if (const char* deprecation = this->GetProperty("DEPRECATION")) {
-    return deprecation;
+  if (cmProp deprecation = this->GetProperty("DEPRECATION")) {
+    return *deprecation;
   }
   return std::string();
 }
@@ -6442,6 +7032,11 @@
 void cmGeneratorTarget::GetLanguages(std::set<std::string>& languages,
                                      const std::string& config) const
 {
+  // Targets that do not compile anything have no languages.
+  if (!this->CanCompileSources()) {
+    return;
+  }
+
   std::vector<cmSourceFile*> sourceFiles;
   this->GetSourceFiles(sourceFiles, config);
   for (cmSourceFile* src : sourceFiles) {
@@ -6491,9 +7086,9 @@
   std::set<std::string> languages = this->GetAllConfigCompileLanguages();
   // Consider an explicit linker language property, but *not* the
   // computed linker language that may depend on linked targets.
-  const char* linkLang = this->GetProperty("LINKER_LANGUAGE");
-  if (linkLang && *linkLang) {
-    languages.insert(linkLang);
+  cmProp linkLang = this->GetProperty("LINKER_LANGUAGE");
+  if (cmNonempty(linkLang)) {
+    languages.insert(*linkLang);
   }
   return languages.size() == 1 && languages.count("CSharp") > 0;
 }
@@ -6537,14 +7132,14 @@
 cmGeneratorTarget::GetLinkImplementationLibrariesInternal(
   const std::string& config, cmGeneratorTarget const* head) const
 {
-  // There is no link implementation for imported targets.
-  if (this->IsImported()) {
+  // There is no link implementation for targets that cannot compile sources.
+  if (!this->CanCompileSources()) {
     return nullptr;
   }
 
   // Populate the link implementation libraries for this configuration.
-  std::string CONFIG = cmSystemTools::UpperCase(config);
-  HeadToLinkImplementationMap& hm = this->LinkImplMap[CONFIG];
+  HeadToLinkImplementationMap& hm =
+    this->LinkImplMap[cmSystemTools::UpperCase(config)];
 
   // If the link implementation does not depend on the head target
   // then return the one we computed first.
@@ -6563,7 +7158,7 @@
 bool cmGeneratorTarget::IsNullImpliedByLinkLibraries(
   const std::string& p) const
 {
-  return cmContains(this->LinkImplicitNullProperties, p);
+  return cm::contains(this->LinkImplicitNullProperties, p);
 }
 
 void cmGeneratorTarget::ComputeLinkImplementationLibraries(
@@ -6585,11 +7180,18 @@
     cmGeneratorExpression ge(*btIt);
     std::unique_ptr<cmCompiledGeneratorExpression> const cge = ge.Parse(*le);
     std::string const& evaluated =
-      cge->Evaluate(this->LocalGenerator, config, head, &dagChecker);
+      cge->Evaluate(this->LocalGenerator, config, head, &dagChecker, nullptr,
+                    this->LinkerLanguage);
     cmExpandList(evaluated, llibs);
     if (cge->GetHadHeadSensitiveCondition()) {
       impl.HadHeadSensitiveCondition = true;
     }
+    if (cge->GetHadContextSensitiveCondition()) {
+      impl.HadContextSensitiveCondition = true;
+    }
+    if (cge->GetHadLinkLanguageSensitiveCondition()) {
+      impl.HadLinkLanguageSensitiveCondition = true;
+    }
 
     for (std::string const& lib : llibs) {
       if (this->IsLinkLookupScope(lib, lg)) {
@@ -6598,6 +7200,13 @@
 
       // Skip entries that resolve to the target itself or are empty.
       std::string name = this->CheckCMP0004(lib);
+      if (this->GetPolicyStatusCMP0108() == cmPolicies::NEW) {
+        // resolve alias name
+        auto target = this->Makefile->FindTargetToUse(name);
+        if (target) {
+          name = target->GetName();
+        }
+      }
       if (name == this->GetName() || name.empty()) {
         if (name == this->GetName()) {
           bool noMessage = false;
@@ -6867,8 +7476,8 @@
   }
 
   // Check for explicitly set clr target property.
-  if (auto* clr = this->GetProperty("COMMON_LANGUAGE_RUNTIME")) {
-    return this->CheckManagedType(clr);
+  if (cmProp clr = this->GetProperty("COMMON_LANGUAGE_RUNTIME")) {
+    return this->CheckManagedType(*clr);
   }
 
   // C# targets are always managed. This language specific check
diff --git a/Source/cmGeneratorTarget.h b/Source/cmGeneratorTarget.h
index d81bb3d..4a03f65 100644
--- a/Source/cmGeneratorTarget.h
+++ b/Source/cmGeneratorTarget.h
@@ -18,6 +18,7 @@
 #include "cmLinkItem.h"
 #include "cmListFileCache.h"
 #include "cmPolicies.h"
+#include "cmProperty.h"
 #include "cmStateTypes.h"
 
 class cmComputeLinkInformation;
@@ -44,8 +45,10 @@
 
   cmGlobalGenerator* GetGlobalGenerator() const;
 
+  bool IsInBuildSystem() const;
   bool IsImported() const;
   bool IsImportedGloballyVisible() const;
+  bool CanCompileSources() const;
   const std::string& GetLocation(const std::string& config) const;
 
   std::vector<cmCustomCommand> const& GetPreBuildCommands() const;
@@ -76,9 +79,9 @@
 
   std::vector<std::string> GetPropertyKeys() const;
   //! Might return a nullptr if the property is not set or invalid
-  const char* GetProperty(const std::string& prop) const;
+  cmProp GetProperty(const std::string& prop) const;
   //! Always returns a valid pointer
-  const char* GetSafeProperty(const std::string& prop) const;
+  std::string const& GetSafeProperty(std::string const& prop) const;
   bool GetPropertyAsBool(const std::string& prop) const;
   void GetSourceFiles(std::vector<cmSourceFile*>& files,
                       const std::string& config) const;
@@ -115,9 +118,6 @@
   struct KindedSources
   {
     std::vector<SourceAndKind> Sources;
-    std::set<std::string> ExpectedResxHeaders;
-    std::set<std::string> ExpectedXamlHeaders;
-    std::set<std::string> ExpectedXamlSources;
     bool Initialized = false;
   };
 
@@ -135,6 +135,9 @@
       per-source configurations assigned.  */
   std::vector<AllConfigSource> const& GetAllConfigSources() const;
 
+  /** Get all sources needed for all configurations with given kind.  */
+  std::vector<AllConfigSource> GetAllConfigSources(SourceKind kind) const;
+
   /** Get all languages used to compile sources in any configuration.
       This excludes the languages of objects from object libraries.  */
   std::set<std::string> GetAllConfigCompileLanguages() const;
@@ -147,10 +150,18 @@
   bool HasExplicitObjectName(cmSourceFile const* file) const;
   void AddExplicitObjectName(cmSourceFile const* sf);
 
+  BTs<std::string> const* GetLanguageStandardProperty(
+    std::string const& lang, std::string const& config) const;
+
+  cmProp GetLanguageStandard(std::string const& lang,
+                             std::string const& config) const;
+
+  cmProp GetLanguageExtensions(std::string const& lang) const;
+
+  bool GetLanguageStandardRequired(std::string const& lang) const;
+
   void GetModuleDefinitionSources(std::vector<cmSourceFile const*>&,
                                   const std::string& config) const;
-  void GetResxSources(std::vector<cmSourceFile const*>&,
-                      const std::string& config) const;
   void GetExternalObjects(std::vector<cmSourceFile const*>&,
                           const std::string& config) const;
   void GetHeaderSources(std::vector<cmSourceFile const*>&,
@@ -159,27 +170,15 @@
                        const std::string& config) const;
   void GetCustomCommands(std::vector<cmSourceFile const*>&,
                          const std::string& config) const;
-  void GetExpectedResxHeaders(std::set<std::string>&,
-                              const std::string& config) const;
-  void GetAppManifest(std::vector<cmSourceFile const*>&,
-                      const std::string& config) const;
   void GetManifests(std::vector<cmSourceFile const*>&,
                     const std::string& config) const;
-  void GetCertificates(std::vector<cmSourceFile const*>&,
-                       const std::string& config) const;
-  void GetXamlSources(std::vector<cmSourceFile const*>&,
-                      const std::string& config) const;
-  void GetExpectedXamlHeaders(std::set<std::string>&,
-                              const std::string& config) const;
-  void GetExpectedXamlSources(std::set<std::string>&,
-                              const std::string& config) const;
 
   std::set<cmLinkItem> const& GetUtilityItems() const;
 
   void ComputeObjectMapping();
 
-  const char* GetFeature(const std::string& feature,
-                         const std::string& config) const;
+  cmProp GetFeature(const std::string& feature,
+                    const std::string& config) const;
 
   const char* GetLinkPIEProperty(const std::string& config) const;
 
@@ -204,6 +203,24 @@
   const char* GetLinkInterfaceDependentNumberMaxProperty(
     const std::string& p, const std::string& config) const;
 
+  class DeviceLinkSetter
+  {
+  public:
+    DeviceLinkSetter(cmGeneratorTarget& target)
+      : Target(target)
+    {
+      this->PreviousState = target.SetDeviceLink(true);
+    }
+    ~DeviceLinkSetter() { this->Target.SetDeviceLink(this->PreviousState); };
+
+  private:
+    cmGeneratorTarget& Target;
+    bool PreviousState;
+  };
+
+  bool SetDeviceLink(bool deviceLink);
+  bool IsDeviceLink() const { return this->DeviceLink; }
+
   cmLinkInterface const* GetLinkInterface(
     const std::string& config, const cmGeneratorTarget* headTarget) const;
   void ComputeLinkInterface(const std::string& config,
@@ -225,7 +242,7 @@
   /** Get the full path to the target according to the settings in its
       makefile and the configuration type.  */
   std::string GetFullPath(
-    const std::string& config = "",
+    const std::string& config,
     cmStateEnums::ArtifactType artifact = cmStateEnums::RuntimeBinaryArtifact,
     bool realname = false) const;
   std::string NormalGetFullPath(const std::string& config,
@@ -263,7 +280,7 @@
 
   /** Get the full name of the target according to the settings in its
       makefile.  */
-  std::string GetFullName(const std::string& config = "",
+  std::string GetFullName(const std::string& config,
                           cmStateEnums::ArtifactType artifact =
                             cmStateEnums::RuntimeBinaryArtifact) const;
 
@@ -306,8 +323,7 @@
   std::string GetSOName(const std::string& config) const;
 
   void GetFullNameComponents(std::string& prefix, std::string& base,
-                             std::string& suffix,
-                             const std::string& config = "",
+                             std::string& suffix, const std::string& config,
                              cmStateEnums::ArtifactType artifact =
                                cmStateEnums::RuntimeBinaryArtifact) const;
 
@@ -357,7 +373,6 @@
   };
 
   LinkClosure const* GetLinkClosure(const std::string& config) const;
-  void ComputeLinkClosure(const std::string& config, LinkClosure& lc) const;
 
   cmLinkImplementation const* GetLinkImplementation(
     const std::string& config) const;
@@ -422,6 +437,9 @@
   void GetAppleArchs(const std::string& config,
                      std::vector<std::string>& archVec) const;
 
+  void AddCUDAArchitectureFlags(std::string& flags) const;
+  void AddCUDAToolkitFlags(std::string& flags) const;
+
   std::string GetFeatureSpecificLinkRuleVariable(
     std::string const& var, std::string const& lang,
     std::string const& config) const;
@@ -479,17 +497,23 @@
     const std::string& config, const std::string& language) const;
 
   std::string GetPchHeader(const std::string& config,
-                           const std::string& language) const;
+                           const std::string& language,
+                           const std::string& arch = std::string()) const;
   std::string GetPchSource(const std::string& config,
-                           const std::string& language) const;
+                           const std::string& language,
+                           const std::string& arch = std::string()) const;
   std::string GetPchFileObject(const std::string& config,
-                               const std::string& language);
+                               const std::string& language,
+                               const std::string& arch = std::string());
   std::string GetPchFile(const std::string& config,
-                         const std::string& language);
-  std::string GetPchCreateCompileOptions(const std::string& config,
-                                         const std::string& language);
+                         const std::string& language,
+                         const std::string& arch = std::string());
+  std::string GetPchCreateCompileOptions(
+    const std::string& config, const std::string& language,
+    const std::string& arch = std::string());
   std::string GetPchUseCompileOptions(const std::string& config,
-                                      const std::string& language);
+                                      const std::string& language,
+                                      const std::string& arch = std::string());
 
   void AddSourceFileToUnityBatch(const std::string& sourceFilename);
   bool IsSourceFilePartOfUnityBatch(const std::string& sourceFilename) const;
@@ -503,6 +527,11 @@
 
   bool ComputeCompileFeatures(std::string const& config) const;
 
+  using LanguagePair = std::pair<std::string, std::string>;
+  bool ComputeCompileFeatures(
+    std::string const& config,
+    std::set<LanguagePair> const& languagePairs) const;
+
   /**
    * Trace through the source files in this target and add al source files
    * that they depend on, used by all generators
@@ -513,7 +542,7 @@
       configuration name is given then the generator will add its
       subdirectory for that configuration.  Otherwise just the canonical
       output directory is given.  */
-  std::string GetDirectory(const std::string& config = "",
+  std::string GetDirectory(const std::string& config,
                            cmStateEnums::ArtifactType artifact =
                              cmStateEnums::RuntimeBinaryArtifact) const;
 
@@ -521,7 +550,7 @@
       If the configuration name is given then the generator will add its
       subdirectory for that configuration.  Otherwise just the canonical
       compiler pdb output directory is given.  */
-  std::string GetCompilePDBDirectory(const std::string& config = "") const;
+  std::string GetCompilePDBDirectory(const std::string& config) const;
 
   /** Get sources that must be built before the given source.  */
   std::vector<cmSourceFile*> const* GetSourceDepends(
@@ -550,7 +579,7 @@
   std::string GetPDBOutputName(const std::string& config) const;
 
   /** Get the name of the pdb file for the target.  */
-  std::string GetPDBName(const std::string& config = "") const;
+  std::string GetPDBName(const std::string& config) const;
 
   /** Whether this library has soname enabled and platform supports it.  */
   bool HasSOName(const std::string& config) const;
@@ -568,10 +597,10 @@
   bool IsNullImpliedByLinkLibraries(const std::string& p) const;
 
   /** Get the name of the compiler pdb file for the target.  */
-  std::string GetCompilePDBName(const std::string& config = "") const;
+  std::string GetCompilePDBName(const std::string& config) const;
 
   /** Get the path for the MSVC /Fd option for this target.  */
-  std::string GetCompilePDBPath(const std::string& config = "") const;
+  std::string GetCompilePDBPath(const std::string& config) const;
 
   // Get the target base name.
   std::string GetOutputName(const std::string& config,
@@ -589,6 +618,9 @@
   /** Get target file postfix */
   std::string GetFilePostfix(const std::string& config) const;
 
+  /** Get framework multi-config-specific postfix */
+  std::string GetFrameworkMultiConfigPostfix(const std::string& config) const;
+
   /** Clears cached meta data for local and external source files.
    * The meta data will be recomputed on demand.
    */
@@ -768,6 +800,9 @@
                                 const std::string& fallback_property,
                                 int& major, int& minor, int& patch) const;
 
+  std::string GetRuntimeLinkLibrary(std::string const& lang,
+                                    std::string const& config) const;
+
   std::string GetFortranModuleDirectory(std::string const& working_dir) const;
 
   const std::string& GetSourcesProperty() const;
@@ -816,8 +851,10 @@
                            std::string& outPrefix, std::string& outBase,
                            std::string& outSuffix) const;
 
+  mutable std::string LinkerLanguage;
   using LinkClosureMapType = std::map<std::string, LinkClosure>;
   mutable LinkClosureMapType LinkClosureMap;
+  bool DeviceLink = false;
 
   // Returns ARCHIVE, LIBRARY, or RUNTIME based on platform and type.
   const char* GetOutputTargetType(cmStateEnums::ArtifactType artifact) const;
@@ -850,6 +887,10 @@
   void CheckPropertyCompatibility(cmComputeLinkInformation& info,
                                   const std::string& config) const;
 
+  void ComputeLinkClosure(const std::string& config, LinkClosure& lc) const;
+  bool ComputeLinkClosure(const std::string& config, LinkClosure& lc,
+                          bool secondPass) const;
+
   struct LinkImplClosure : public std::vector<cmGeneratorTarget const*>
   {
     bool Done = false;
@@ -868,6 +909,17 @@
   std::string GetLinkInterfaceDependentStringAsBoolProperty(
     const std::string& p, const std::string& config) const;
 
+  friend class cmTargetCollectLinkLanguages;
+  cmLinkInterface const* GetLinkInterface(const std::string& config,
+                                          const cmGeneratorTarget* headTarget,
+                                          bool secondPass) const;
+  void ComputeLinkInterface(const std::string& config,
+                            cmOptionalLinkInterface& iface,
+                            const cmGeneratorTarget* head,
+                            bool secondPass) const;
+  cmLinkImplementation const* GetLinkImplementation(const std::string& config,
+                                                    bool secondPass) const;
+
   // Cache import information from properties for each configuration.
   struct ImportInfo
   {
@@ -894,9 +946,10 @@
       the link dependencies of this target.  */
   std::string CheckCMP0004(std::string const& item) const;
 
-  cmLinkInterface const* GetImportLinkInterface(
-    const std::string& config, const cmGeneratorTarget* head,
-    bool usage_requirements_only) const;
+  cmLinkInterface const* GetImportLinkInterface(const std::string& config,
+                                                const cmGeneratorTarget* head,
+                                                bool usage_requirements_only,
+                                                bool secondPass = false) const;
 
   using KindedSourcesMapType = std::map<std::string, KindedSources>;
   mutable KindedSourcesMapType KindedSourcesMap;
@@ -940,7 +993,9 @@
                        const cmGeneratorTarget* headTarget,
                        bool usage_requirements_only,
                        std::vector<cmLinkItem>& items,
-                       bool& hadHeadSensitiveCondition) const;
+                       bool& hadHeadSensitiveCondition,
+                       bool& hadContextSensitiveCondition,
+                       bool& hadLinkLanguageSensitiveCondition) const;
   void LookupLinkItems(std::vector<std::string> const& names,
                        cmListFileBacktrace const& bt,
                        std::vector<cmLinkItem>& items) const;
@@ -1000,6 +1055,11 @@
   bool GetRPATH(const std::string& config, const std::string& prop,
                 std::string& rpath) const;
 
+  mutable std::map<std::string, BTs<std::string>> LanguageStandardMap;
+
+  cmProp GetPropertyWithPairedLanguageSupport(std::string const& lang,
+                                              const char* suffix) const;
+
 public:
   const std::vector<const cmGeneratorTarget*>& GetLinkImplementationClosure(
     const std::string& config) const;
diff --git a/Source/cmGetCMakePropertyCommand.cxx b/Source/cmGetCMakePropertyCommand.cxx
index ff4e312..79cbe44 100644
--- a/Source/cmGetCMakePropertyCommand.cxx
+++ b/Source/cmGetCMakePropertyCommand.cxx
@@ -7,6 +7,7 @@
 #include "cmExecutionStatus.h"
 #include "cmGlobalGenerator.h"
 #include "cmMakefile.h"
+#include "cmProperty.h"
 #include "cmState.h"
 #include "cmStringAlgorithms.h"
 
@@ -23,25 +24,25 @@
   std::string output = "NOTFOUND";
 
   if (args[1] == "VARIABLES") {
-    if (const char* varsProp = status.GetMakefile().GetProperty("VARIABLES")) {
-      output = varsProp;
+    if (cmProp varsProp = status.GetMakefile().GetProperty("VARIABLES")) {
+      output = *varsProp;
     }
   } else if (args[1] == "MACROS") {
     output.clear();
-    if (const char* macrosProp = status.GetMakefile().GetProperty("MACROS")) {
-      output = macrosProp;
+    if (cmProp macrosProp = status.GetMakefile().GetProperty("MACROS")) {
+      output = *macrosProp;
     }
   } else if (args[1] == "COMPONENTS") {
     const std::set<std::string>* components =
       status.GetMakefile().GetGlobalGenerator()->GetInstallComponents();
     output = cmJoin(*components, ";");
   } else {
-    const char* prop = nullptr;
+    cmProp prop = nullptr;
     if (!args[1].empty()) {
       prop = status.GetMakefile().GetState()->GetGlobalProperty(args[1]);
     }
     if (prop) {
-      output = prop;
+      output = *prop;
     }
   }
 
diff --git a/Source/cmGetDirectoryPropertyCommand.cxx b/Source/cmGetDirectoryPropertyCommand.cxx
index 64438d5..fa4a40b 100644
--- a/Source/cmGetDirectoryPropertyCommand.cxx
+++ b/Source/cmGetDirectoryPropertyCommand.cxx
@@ -7,7 +7,7 @@
 #include "cmMakefile.h"
 #include "cmMessageType.h"
 #include "cmPolicies.h"
-#include "cmStringAlgorithms.h"
+#include "cmProperty.h"
 #include "cmSystemTools.h"
 
 namespace {
@@ -37,14 +37,8 @@
         "DIRECTORY argument provided without subsequent arguments");
       return false;
     }
-    std::string sd = *i;
-    // make sure the start dir is a full path
-    if (!cmSystemTools::FileIsFullPath(sd)) {
-      sd = cmStrCat(status.GetMakefile().GetCurrentSourceDirectory(), '/', *i);
-    }
-
-    // The local generators are associated with collapsed paths.
-    sd = cmSystemTools::CollapseFullPath(sd);
+    std::string sd = cmSystemTools::CollapseFullPath(
+      *i, status.GetMakefile().GetCurrentSourceDirectory());
 
     // lookup the makefile from the directory name
     dir = status.GetMakefile().GetGlobalGenerator()->FindMakefile(sd);
@@ -92,7 +86,9 @@
           break;
       }
     }
-    prop = dir->GetProperty(*i);
+    if (cmProp p = dir->GetProperty(*i)) {
+      prop = p->c_str();
+    }
   }
   StoreResult(status.GetMakefile(), variable, prop);
   return true;
diff --git a/Source/cmGetFilenameComponentCommand.cxx b/Source/cmGetFilenameComponentCommand.cxx
index 7d91a75..38bffbf 100644
--- a/Source/cmGetFilenameComponentCommand.cxx
+++ b/Source/cmGetFilenameComponentCommand.cxx
@@ -14,6 +14,7 @@
 {
   if (args.size() < 3) {
     status.SetError("called with incorrect number of arguments");
+    cmSystemTools::SetFatalErrorOccured();
     return false;
   }
 
@@ -114,17 +115,18 @@
   } else {
     std::string err = "unknown component " + args[2];
     status.SetError(err);
+    cmSystemTools::SetFatalErrorOccured();
     return false;
   }
 
   if (args.size() >= 4 && args.back() == "CACHE") {
     if (!programArgs.empty() && !storeArgs.empty()) {
       status.GetMakefile().AddCacheDefinition(
-        storeArgs, programArgs.c_str(), "",
+        storeArgs, programArgs, "",
         args[2] == "PATH" ? cmStateEnums::FILEPATH : cmStateEnums::STRING);
     }
     status.GetMakefile().AddCacheDefinition(
-      args.front(), result.c_str(), "",
+      args.front(), result, "",
       args[2] == "PATH" ? cmStateEnums::FILEPATH : cmStateEnums::STRING);
   } else {
     if (!programArgs.empty() && !storeArgs.empty()) {
diff --git a/Source/cmGetPipes.cxx b/Source/cmGetPipes.cxx
index 4eda1c5..a5b6469 100644
--- a/Source/cmGetPipes.cxx
+++ b/Source/cmGetPipes.cxx
@@ -2,10 +2,9 @@
    file Copyright.txt or https://cmake.org/licensing for details.  */
 #include "cmGetPipes.h"
 
+#include <cm3p/uv.h>
 #include <fcntl.h>
 
-#include "cm_uv.h"
-
 #if defined(_WIN32) && !defined(__CYGWIN__)
 #  include <io.h>
 
diff --git a/Source/cmGetPropertyCommand.cxx b/Source/cmGetPropertyCommand.cxx
index 947d893..cdfd8c8 100644
--- a/Source/cmGetPropertyCommand.cxx
+++ b/Source/cmGetPropertyCommand.cxx
@@ -11,12 +11,12 @@
 #include "cmPolicies.h"
 #include "cmProperty.h"
 #include "cmPropertyDefinition.h"
+#include "cmSetPropertyCommand.h"
 #include "cmSourceFile.h"
 #include "cmState.h"
 #include "cmStringAlgorithms.h"
 #include "cmSystemTools.h"
 #include "cmTarget.h"
-#include "cmTargetPropertyComputer.h"
 #include "cmTest.h"
 #include "cmake.h"
 
@@ -48,7 +48,9 @@
                       const std::string& propertyName);
 bool HandleSourceMode(cmExecutionStatus& status, const std::string& name,
                       OutType infoType, const std::string& variable,
-                      const std::string& propertyName);
+                      const std::string& propertyName,
+                      cmMakefile& directory_makefile,
+                      bool source_file_paths_should_be_absolute);
 bool HandleTestMode(cmExecutionStatus& status, const std::string& name,
                     OutType infoType, const std::string& variable,
                     const std::string& propertyName);
@@ -78,6 +80,11 @@
   std::string name;
   std::string propertyName;
 
+  std::vector<std::string> source_file_directories;
+  std::vector<std::string> source_file_target_directories;
+  bool source_file_directory_option_enabled = false;
+  bool source_file_target_option_enabled = false;
+
   // Get the scope from which to get the property.
   cmProperty::ScopeType scope;
   if (args[1] == "GLOBAL") {
@@ -111,7 +118,9 @@
     DoingNone,
     DoingName,
     DoingProperty,
-    DoingType
+    DoingType,
+    DoingSourceDirectory,
+    DoingSourceTargetDirectory
   };
   Doing doing = DoingName;
   for (unsigned int i = 2; i < args.size(); ++i) {
@@ -132,6 +141,20 @@
     } else if (doing == DoingName) {
       doing = DoingNone;
       name = args[i];
+    } else if (doing == DoingNone && scope == cmProperty::SOURCE_FILE &&
+               args[i] == "DIRECTORY") {
+      doing = DoingSourceDirectory;
+      source_file_directory_option_enabled = true;
+    } else if (doing == DoingNone && scope == cmProperty::SOURCE_FILE &&
+               args[i] == "TARGET_DIRECTORY") {
+      doing = DoingSourceTargetDirectory;
+      source_file_target_option_enabled = true;
+    } else if (doing == DoingSourceDirectory) {
+      source_file_directories.push_back(args[i]);
+      doing = DoingNone;
+    } else if (doing == DoingSourceTargetDirectory) {
+      source_file_target_directories.push_back(args[i]);
+      doing = DoingNone;
     } else if (doing == DoingProperty) {
       doing = DoingNone;
       propertyName = args[i];
@@ -147,6 +170,16 @@
     return false;
   }
 
+  std::vector<cmMakefile*> source_file_directory_makefiles;
+  bool file_scopes_handled =
+    SetPropertyCommand::HandleAndValidateSourceFileDirectortoryScopes(
+      status, source_file_directory_option_enabled,
+      source_file_target_option_enabled, source_file_directories,
+      source_file_target_directories, source_file_directory_makefiles);
+  if (!file_scopes_handled) {
+    return false;
+  }
+
   // Compute requested output.
   if (infoType == OutBriefDoc) {
     // Lookup brief documentation.
@@ -180,6 +213,11 @@
     }
   } else {
     // Dispatch property getting.
+    cmMakefile& directory_scope_mf = *(source_file_directory_makefiles[0]);
+    bool source_file_paths_should_be_absolute =
+      source_file_directory_option_enabled ||
+      source_file_target_option_enabled;
+
     switch (scope) {
       case cmProperty::GLOBAL:
         return HandleGlobalMode(status, name, infoType, variable,
@@ -191,8 +229,9 @@
         return HandleTargetMode(status, name, infoType, variable,
                                 propertyName);
       case cmProperty::SOURCE_FILE:
-        return HandleSourceMode(status, name, infoType, variable,
-                                propertyName);
+        return HandleSourceMode(status, name, infoType, variable, propertyName,
+                                directory_scope_mf,
+                                source_file_paths_should_be_absolute);
       case cmProperty::TEST:
         return HandleTestMode(status, name, infoType, variable, propertyName);
       case cmProperty::VARIABLE:
@@ -241,8 +280,9 @@
 
   // Get the property.
   cmake* cm = status.GetMakefile().GetCMakeInstance();
+  cmProp p = cm->GetState()->GetGlobalProperty(propertyName);
   return StoreResult(infoType, status.GetMakefile(), variable,
-                     cm->GetState()->GetGlobalProperty(propertyName));
+                     p ? p->c_str() : nullptr);
 }
 
 bool HandleDirectoryMode(cmExecutionStatus& status, const std::string& name,
@@ -256,14 +296,8 @@
   if (!name.empty()) {
     // Construct the directory name.  Interpret relative paths with
     // respect to the current directory.
-    std::string dir = name;
-    if (!cmSystemTools::FileIsFullPath(dir)) {
-      dir =
-        cmStrCat(status.GetMakefile().GetCurrentSourceDirectory(), '/', name);
-    }
-
-    // The local generators are associated with collapsed paths.
-    dir = cmSystemTools::CollapseFullPath(dir);
+    std::string dir = cmSystemTools::CollapseFullPath(
+      name, status.GetMakefile().GetCurrentSourceDirectory());
 
     // Lookup the generator.
     mf = status.GetMakefile().GetGlobalGenerator()->FindMakefile(dir);
@@ -294,8 +328,9 @@
   }
 
   // Get the property.
+  cmProp p = mf->GetProperty(propertyName);
   return StoreResult(infoType, status.GetMakefile(), variable,
-                     mf->GetProperty(propertyName));
+                     p ? p->c_str() : nullptr);
 }
 
 bool HandleTargetMode(cmExecutionStatus& status, const std::string& name,
@@ -308,24 +343,32 @@
   }
 
   if (cmTarget* target = status.GetMakefile().FindTargetToUse(name)) {
-    if (propertyName == "ALIASED_TARGET") {
+    if (propertyName == "ALIASED_TARGET" || propertyName == "ALIAS_GLOBAL") {
       if (status.GetMakefile().IsAlias(name)) {
-        return StoreResult(infoType, status.GetMakefile(), variable,
-                           target->GetName().c_str());
+        if (propertyName == "ALIASED_TARGET") {
+
+          return StoreResult(infoType, status.GetMakefile(), variable,
+                             target->GetName().c_str());
+        }
+        if (propertyName == "ALIAS_GLOBAL") {
+          return StoreResult(
+            infoType, status.GetMakefile(), variable,
+            status.GetMakefile().GetGlobalGenerator()->IsAlias(name)
+              ? "TRUE"
+              : "FALSE");
+        }
       }
       return StoreResult(infoType, status.GetMakefile(), variable, nullptr);
     }
-    const char* prop_cstr = nullptr;
+    cmProp prop_cstr = nullptr;
     cmListFileBacktrace bt = status.GetMakefile().GetBacktrace();
     cmMessenger* messenger = status.GetMakefile().GetMessenger();
-    if (cmTargetPropertyComputer::PassesWhitelist(
-          target->GetType(), propertyName, messenger, bt)) {
-      prop_cstr = target->GetComputedProperty(propertyName, messenger, bt);
-      if (!prop_cstr) {
-        prop_cstr = target->GetProperty(propertyName);
-      }
+    prop_cstr = target->GetComputedProperty(propertyName, messenger, bt);
+    if (!prop_cstr) {
+      prop_cstr = target->GetProperty(propertyName);
     }
-    return StoreResult(infoType, status.GetMakefile(), variable, prop_cstr);
+    return StoreResult(infoType, status.GetMakefile(), variable,
+                       prop_cstr ? prop_cstr->c_str() : nullptr);
   }
   status.SetError(cmStrCat("could not find TARGET ", name,
                            ".  Perhaps it has not yet been created."));
@@ -334,7 +377,9 @@
 
 bool HandleSourceMode(cmExecutionStatus& status, const std::string& name,
                       OutType infoType, const std::string& variable,
-                      const std::string& propertyName)
+                      const std::string& propertyName,
+                      cmMakefile& directory_makefile,
+                      const bool source_file_paths_should_be_absolute)
 {
   if (name.empty()) {
     status.SetError("not given name for SOURCE scope.");
@@ -342,12 +387,17 @@
   }
 
   // Get the source file.
-  if (cmSourceFile* sf = status.GetMakefile().GetOrCreateSource(name)) {
+  const std::string source_file_absolute_path =
+    SetPropertyCommand::MakeSourceFilePathAbsoluteIfNeeded(
+      status, name, source_file_paths_should_be_absolute);
+  if (cmSourceFile* sf =
+        directory_makefile.GetOrCreateSource(source_file_absolute_path)) {
     return StoreResult(infoType, status.GetMakefile(), variable,
                        sf->GetPropertyForUser(propertyName));
   }
   status.SetError(
-    cmStrCat("given SOURCE name that could not be found or created: ", name));
+    cmStrCat("given SOURCE name that could not be found or created: ",
+             source_file_absolute_path));
   return false;
 }
 
@@ -393,12 +443,13 @@
     return false;
   }
 
-  const char* value = nullptr;
+  cmProp value = nullptr;
   if (status.GetMakefile().GetState()->GetCacheEntryValue(name)) {
     value = status.GetMakefile().GetState()->GetCacheEntryProperty(
       name, propertyName);
   }
-  StoreResult(infoType, status.GetMakefile(), variable, value);
+  StoreResult(infoType, status.GetMakefile(), variable,
+              value ? value->c_str() : nullptr);
   return true;
 }
 
diff --git a/Source/cmGetSourceFilePropertyCommand.cxx b/Source/cmGetSourceFilePropertyCommand.cxx
index eefdc6c..5395bc8 100644
--- a/Source/cmGetSourceFilePropertyCommand.cxx
+++ b/Source/cmGetSourceFilePropertyCommand.cxx
@@ -4,35 +4,71 @@
 
 #include "cmExecutionStatus.h"
 #include "cmMakefile.h"
+#include "cmSetPropertyCommand.h"
 #include "cmSourceFile.h"
 
 bool cmGetSourceFilePropertyCommand(std::vector<std::string> const& args,
                                     cmExecutionStatus& status)
 {
-  if (args.size() != 3) {
+  std::vector<std::string>::size_type args_size = args.size();
+  if (args_size != 3 && args_size != 5) {
     status.SetError("called with incorrect number of arguments");
     return false;
   }
+
+  std::vector<std::string> source_file_directories;
+  std::vector<std::string> source_file_target_directories;
+  bool source_file_directory_option_enabled = false;
+  bool source_file_target_option_enabled = false;
+
+  int property_arg_index = 2;
+  if (args[2] == "DIRECTORY" && args_size == 5) {
+    property_arg_index = 4;
+    source_file_directory_option_enabled = true;
+    source_file_directories.push_back(args[3]);
+  } else if (args[2] == "TARGET_DIRECTORY" && args_size == 5) {
+    property_arg_index = 4;
+    source_file_target_option_enabled = true;
+    source_file_target_directories.push_back(args[3]);
+  }
+
+  std::vector<cmMakefile*> source_file_directory_makefiles;
+  bool file_scopes_handled =
+    SetPropertyCommand::HandleAndValidateSourceFileDirectortoryScopes(
+      status, source_file_directory_option_enabled,
+      source_file_target_option_enabled, source_file_directories,
+      source_file_target_directories, source_file_directory_makefiles);
+  if (!file_scopes_handled) {
+    return false;
+  }
+
   std::string const& var = args[0];
-  std::string const& file = args[1];
-  cmMakefile& mf = status.GetMakefile();
+  bool source_file_paths_should_be_absolute =
+    source_file_directory_option_enabled || source_file_target_option_enabled;
+  std::string const file =
+    SetPropertyCommand::MakeSourceFilePathAbsoluteIfNeeded(
+      status, args[1], source_file_paths_should_be_absolute);
+  cmMakefile& mf = *source_file_directory_makefiles[0];
   cmSourceFile* sf = mf.GetSource(file);
 
   // for the location we must create a source file first
-  if (!sf && args[2] == "LOCATION") {
+  if (!sf && args[property_arg_index] == "LOCATION") {
     sf = mf.CreateSource(file);
   }
+
   if (sf) {
     const char* prop = nullptr;
-    if (!args[2].empty()) {
-      prop = sf->GetPropertyForUser(args[2]);
+    if (!args[property_arg_index].empty()) {
+      prop = sf->GetPropertyForUser(args[property_arg_index]);
     }
     if (prop) {
-      mf.AddDefinition(var, prop);
+      // Set the value on the original Makefile scope, not the scope of the
+      // requested directory.
+      status.GetMakefile().AddDefinition(var, prop);
       return true;
     }
   }
 
-  mf.AddDefinition(var, "NOTFOUND");
+  status.GetMakefile().AddDefinition(var, "NOTFOUND");
   return true;
 }
diff --git a/Source/cmGetTargetPropertyCommand.cxx b/Source/cmGetTargetPropertyCommand.cxx
index 7f5df9c..78a17d2 100644
--- a/Source/cmGetTargetPropertyCommand.cxx
+++ b/Source/cmGetTargetPropertyCommand.cxx
@@ -5,12 +5,13 @@
 #include <sstream>
 
 #include "cmExecutionStatus.h"
+#include "cmGlobalGenerator.h"
 #include "cmListFileCache.h"
 #include "cmMakefile.h"
 #include "cmMessageType.h"
 #include "cmPolicies.h"
+#include "cmProperty.h"
 #include "cmTarget.h"
-#include "cmTargetPropertyComputer.h"
 
 class cmMessenger;
 
@@ -28,24 +29,28 @@
   cmMakefile& mf = status.GetMakefile();
 
   if (cmTarget* tgt = mf.FindTargetToUse(targetName)) {
-    if (args[2] == "ALIASED_TARGET") {
+    if (args[2] == "ALIASED_TARGET" || args[2] == "ALIAS_GLOBAL") {
       if (mf.IsAlias(targetName)) {
-        prop = tgt->GetName();
         prop_exists = true;
-      }
-    } else if (!args[2].empty()) {
-      const char* prop_cstr = nullptr;
-      cmListFileBacktrace bt = mf.GetBacktrace();
-      cmMessenger* messenger = mf.GetMessenger();
-      if (cmTargetPropertyComputer::PassesWhitelist(tgt->GetType(), args[2],
-                                                    messenger, bt)) {
-        prop_cstr = tgt->GetComputedProperty(args[2], messenger, bt);
-        if (!prop_cstr) {
-          prop_cstr = tgt->GetProperty(args[2]);
+        if (args[2] == "ALIASED_TARGET") {
+
+          prop = tgt->GetName();
+        }
+        if (args[2] == "ALIAS_GLOBAL") {
+          prop =
+            mf.GetGlobalGenerator()->IsAlias(targetName) ? "TRUE" : "FALSE";
         }
       }
+    } else if (!args[2].empty()) {
+      cmProp prop_cstr = nullptr;
+      cmListFileBacktrace bt = mf.GetBacktrace();
+      cmMessenger* messenger = mf.GetMessenger();
+      prop_cstr = tgt->GetComputedProperty(args[2], messenger, bt);
+      if (!prop_cstr) {
+        prop_cstr = tgt->GetProperty(args[2]);
+      }
       if (prop_cstr) {
-        prop = prop_cstr;
+        prop = *prop_cstr;
         prop_exists = true;
       }
     }
diff --git a/Source/cmGhsMultiTargetGenerator.cxx b/Source/cmGhsMultiTargetGenerator.cxx
index 5e2248e..1589c47 100644
--- a/Source/cmGhsMultiTargetGenerator.cxx
+++ b/Source/cmGhsMultiTargetGenerator.cxx
@@ -14,11 +14,12 @@
 #include "cmGeneratedFileStream.h"
 #include "cmGeneratorTarget.h"
 #include "cmGlobalGhsMultiGenerator.h"
-#include "cmLinkLineComputer.h"
+#include "cmLinkLineComputer.h" // IWYU pragma: keep
 #include "cmLocalGenerator.h"
 #include "cmLocalGhsMultiGenerator.h"
 #include "cmMakefile.h"
 #include "cmOutputConverter.h"
+#include "cmProperty.h"
 #include "cmSourceFile.h"
 #include "cmSourceFileLocation.h"
 #include "cmSourceGroup.h"
@@ -165,13 +166,15 @@
     outpath = this->GeneratorTarget->GetDirectory(config);
     outpath =
       this->LocalGenerator->MaybeConvertToRelativePath(rootpath, outpath);
-    fout << "    :binDirRelative=\"" << outpath << "\"" << std::endl;
-    fout << "    -o \"" << this->TargetNameReal << "\"" << std::endl;
+    /* clang-format off */
+    fout << "    :binDirRelative=\"" << outpath << "\"\n"
+            "    -o \"" << this->TargetNameReal << "\"\n";
+    /* clang-format on */
   }
 
   // set target object file destination
   outpath = this->LocalGenerator->GetTargetDirectory(this->GeneratorTarget);
-  fout << "    :outputDirRelative=\"" << outpath << "\"" << std::endl;
+  fout << "    :outputDirRelative=\"" << outpath << "\"\n";
 }
 
 void cmGhsMultiTargetGenerator::SetCompilerFlags(std::string const& config,
@@ -180,15 +183,12 @@
   auto i = this->FlagsByLanguage.find(language);
   if (i == this->FlagsByLanguage.end()) {
     std::string flags;
-    const char* lang = language.c_str();
-
-    this->LocalGenerator->AddLanguageFlags(flags, this->GeneratorTarget, lang,
-                                           config);
-
-    this->LocalGenerator->AddCMP0018Flags(flags, this->GeneratorTarget, lang,
-                                          config);
+    this->LocalGenerator->AddLanguageFlags(flags, this->GeneratorTarget,
+                                           language, config);
+    this->LocalGenerator->AddCMP0018Flags(flags, this->GeneratorTarget,
+                                          language, config);
     this->LocalGenerator->AddVisibilityPresetFlags(
-      flags, this->GeneratorTarget, lang);
+      flags, this->GeneratorTarget, language);
 
     // Append old-style preprocessor definition flags.
     if (this->Makefile->GetDefineFlags() != " ") {
@@ -197,8 +197,8 @@
     }
 
     // Add target-specific flags.
-    this->LocalGenerator->AddCompileOptions(flags, this->GeneratorTarget, lang,
-                                            config);
+    this->LocalGenerator->AddCompileOptions(flags, this->GeneratorTarget,
+                                            language, config);
 
     std::map<std::string, std::string>::value_type entry(language, flags);
     i = this->FlagsByLanguage.insert(entry).first;
@@ -211,13 +211,12 @@
   auto i = this->DefinesByLanguage.find(language);
   if (i == this->DefinesByLanguage.end()) {
     std::set<std::string> defines;
-    const char* lang = language.c_str();
     // Add preprocessor definitions for this target and configuration.
     this->LocalGenerator->GetTargetDefines(this->GeneratorTarget, config,
                                            language, defines);
 
     std::string definesString;
-    this->LocalGenerator->JoinDefines(defines, definesString, lang);
+    this->LocalGenerator->JoinDefines(defines, definesString, language);
 
     std::map<std::string, std::string>::value_type entry(language,
                                                          definesString);
@@ -235,8 +234,8 @@
     if (!flagsByLangI->second.empty()) {
       std::vector<std::string> ghsCompFlags =
         cmSystemTools::ParseArguments(flagsByLangI->second);
-      for (auto& f : ghsCompFlags) {
-        fout << "    " << f << std::endl;
+      for (const std::string& f : ghsCompFlags) {
+        fout << "    " << f << '\n';
       }
     }
   }
@@ -249,7 +248,7 @@
   this->GeneratorTarget->GetCompileDefinitions(compileDefinitions, config,
                                                language);
   for (std::string const& compileDefinition : compileDefinitions) {
-    fout << "    -D" << compileDefinition << std::endl;
+    fout << "    -D" << compileDefinition << '\n';
   }
 }
 
@@ -262,7 +261,7 @@
                                               language, config);
 
   for (std::string const& include : includes) {
-    fout << "    -I\"" << include << "\"" << std::endl;
+    fout << "    -I\"" << include << "\"\n";
   }
 }
 
@@ -290,15 +289,15 @@
 
   // write out link options
   std::vector<std::string> lopts = cmSystemTools::ParseArguments(linkFlags);
-  for (auto& l : lopts) {
-    fout << "    " << l << std::endl;
+  for (const std::string& l : lopts) {
+    fout << "    " << l << '\n';
   }
 
   // write out link search paths
   // must be quoted for paths that contain spaces
   std::vector<std::string> lpath = cmSystemTools::ParseArguments(linkPath);
-  for (auto& l : lpath) {
-    fout << "    -L\"" << l << "\"" << std::endl;
+  for (const std::string& l : lpath) {
+    fout << "    -L\"" << l << "\"\n";
   }
 
   // write out link libs
@@ -307,12 +306,12 @@
 
   std::vector<std::string> llibs =
     cmSystemTools::ParseArguments(linkLibraries);
-  for (auto& l : llibs) {
+  for (const std::string& l : llibs) {
     if (l.compare(0, 2, "-l") == 0) {
-      fout << "    \"" << l << "\"" << std::endl;
+      fout << "    \"" << l << "\"\n";
     } else {
       std::string rl = cmSystemTools::CollapseFullPath(l, cbd);
-      fout << "    -l\"" << rl << "\"" << std::endl;
+      fout << "    -l\"" << rl << "\"\n";
     }
   }
 }
@@ -353,13 +352,12 @@
     this->WriteCustomCommandsHelper(f, ccg);
     f.Close();
     if (this->TagType != GhsMultiGpj::CUSTOM_TARGET) {
-      fout << "    :" << cmd << "=\"" << fname << "\"" << std::endl;
+      fout << "    :" << cmd << "=\"" << fname << "\"\n";
     } else {
-      fout << fname << std::endl;
-      fout << "    :outputName=\"" << fname << ".rule\"" << std::endl;
+      fout << fname << "\n    :outputName=\"" << fname << ".rule\"\n";
     }
     for (auto& byp : ccg.GetByproducts()) {
-      fout << "    :extraOutputFile=\"" << byp << "\"" << std::endl;
+      fout << "    :extraOutputFile=\"" << byp << "\"\n";
     }
   }
 }
@@ -451,8 +449,7 @@
 
   // push back the custom commands
   for (auto const& c : cmdLines) {
-    fout << c << std::endl;
-    fout << check_error << std::endl;
+    fout << c << '\n' << check_error << '\n';
   }
 }
 
@@ -460,11 +457,11 @@
   std::ostream& fout, const cmSourceFile* sf, std::string const& propName,
   std::string const& propFlag)
 {
-  const char* prop = sf->GetProperty(propName);
+  cmProp prop = sf->GetProperty(propName);
   if (prop) {
-    std::vector<std::string> list = cmExpandedList(prop);
-    for (auto& p : list) {
-      fout << "    " << propFlag << p << std::endl;
+    std::vector<std::string> list = cmExpandedList(*prop);
+    for (const std::string& p : list) {
+      fout << "    " << propFlag << p << '\n';
     }
   }
 }
@@ -483,7 +480,7 @@
   /* for each source file assign it to its group */
   std::map<std::string, std::vector<cmSourceFile*>> groupFiles;
   std::set<std::string> groupNames;
-  for (auto& sf : sources) {
+  for (cmSourceFile* sf : sources) {
     cmSourceGroup* sourceGroup =
       this->Makefile->FindSourceGroup(sf->ResolveFullPath(), sourceGroups);
     std::string gn = sourceGroup->GetFullName();
@@ -555,7 +552,7 @@
     std::ostream* fout;
     bool useProjectFile =
       cmIsOn(this->GeneratorTarget->GetProperty("GHS_NO_SOURCE_GROUP_FILE")) ||
-      cmIsOn(this->Makefile->GetDefinition("CMAKE_GHS_NO_SOURCE_GROUP_FILE"));
+      this->Makefile->IsOn("CMAKE_GHS_NO_SOURCE_GROUP_FILE");
     if (useProjectFile || sg.empty()) {
       fout = &fout_proj;
     } else {
@@ -579,12 +576,12 @@
 
     if (useProjectFile) {
       if (sg.empty()) {
-        *fout << "{comment} Others" << std::endl;
+        *fout << "{comment} Others" << '\n';
       } else {
-        *fout << "{comment} " << sg << std::endl;
+        *fout << "{comment} " << sg << '\n';
       }
     } else if (sg.empty()) {
-      *fout << "{comment} Others" << std::endl;
+      *fout << "{comment} Others\n";
     }
 
     if (sg != "CMake Rules") {
@@ -612,7 +609,7 @@
           compile = false;
         }
 
-        *fout << comment << fname << std::endl;
+        *fout << comment << fname << '\n';
         if (compile) {
           if ("ld" != si->GetExtension() && "int" != si->GetExtension() &&
               "bsp" != si->GetExtension()) {
@@ -628,7 +625,7 @@
           std::string objectName = this->GeneratorTarget->GetObjectName(si);
           if (!objectName.empty() &&
               this->GeneratorTarget->HasExplicitObjectName(si)) {
-            *fout << "    -o " << objectName << std::endl;
+            *fout << "    -o " << objectName << '\n';
           }
         }
       }
@@ -695,14 +692,14 @@
    */
   bool specifyExtra = true;
   for (auto& out : ccg.GetOutputs()) {
-    fout << fname << std::endl;
-    fout << "    :outputName=\"" << out << "\"" << std::endl;
+    fout << fname << '\n';
+    fout << "    :outputName=\"" << out << "\"\n";
     if (specifyExtra) {
       for (auto& byp : ccg.GetByproducts()) {
-        fout << "    :extraOutputFile=\"" << byp << "\"" << std::endl;
+        fout << "    :extraOutputFile=\"" << byp << "\"\n";
       }
       for (auto& dep : ccg.GetDepends()) {
-        fout << "    :depends=\"" << dep << "\"" << std::endl;
+        fout << "    :depends=\"" << dep << "\"\n";
       }
       specifyExtra = false;
     }
@@ -712,25 +709,25 @@
 void cmGhsMultiTargetGenerator::WriteObjectLangOverride(
   std::ostream& fout, const cmSourceFile* sourceFile)
 {
-  const char* rawLangProp = sourceFile->GetProperty("LANGUAGE");
+  cmProp rawLangProp = sourceFile->GetProperty("LANGUAGE");
   if (nullptr != rawLangProp) {
-    std::string sourceLangProp(rawLangProp);
+    std::string sourceLangProp(*rawLangProp);
     std::string const& extension = sourceFile->GetExtension();
     if ("CXX" == sourceLangProp && ("c" == extension || "C" == extension)) {
-      fout << "    -dotciscxx" << std::endl;
+      fout << "    -dotciscxx\n";
     }
   }
 }
 
 bool cmGhsMultiTargetGenerator::DetermineIfIntegrityApp()
 {
-  const char* p = this->GeneratorTarget->GetProperty("ghs_integrity_app");
+  cmProp p = this->GeneratorTarget->GetProperty("ghs_integrity_app");
   if (p) {
-    return cmIsOn(this->GeneratorTarget->GetProperty("ghs_integrity_app"));
+    return cmIsOn(*p);
   }
   std::vector<cmSourceFile*> sources;
   this->GeneratorTarget->GetSourceFiles(sources, this->ConfigName);
-  for (auto& sf : sources) {
+  for (const cmSourceFile* sf : sources) {
     if ("int" == sf->GetExtension()) {
       return true;
     }
diff --git a/Source/cmGhsMultiTargetGenerator.h b/Source/cmGhsMultiTargetGenerator.h
index f03ca44..5f26387 100644
--- a/Source/cmGhsMultiTargetGenerator.h
+++ b/Source/cmGhsMultiTargetGenerator.h
@@ -43,7 +43,7 @@
   void SetCompilerFlags(std::string const& config,
                         const std::string& language);
 
-  std::string GetDefines(const std::string& langugae,
+  std::string GetDefines(const std::string& language,
                          std::string const& config);
 
   void WriteIncludes(std::ostream& fout, const std::string& config,
diff --git a/Source/cmGlobalBorlandMakefileGenerator.h b/Source/cmGlobalBorlandMakefileGenerator.h
index 9af0eac..3c97955 100644
--- a/Source/cmGlobalBorlandMakefileGenerator.h
+++ b/Source/cmGlobalBorlandMakefileGenerator.h
@@ -46,6 +46,7 @@
 
   bool AllowNotParallel() const override { return false; }
   bool AllowDeleteOnError() const override { return false; }
+  bool CanEscapeOctothorpe() const override { return true; }
 
 protected:
   std::vector<GeneratedMakeCommand> GenerateBuildCommand(
diff --git a/Source/cmGlobalCommonGenerator.cxx b/Source/cmGlobalCommonGenerator.cxx
index e04eef1..9e5bbca 100644
--- a/Source/cmGlobalCommonGenerator.cxx
+++ b/Source/cmGlobalCommonGenerator.cxx
@@ -5,8 +5,13 @@
 #include <memory>
 #include <utility>
 
+#include <cmext/algorithm>
+
+#include "cmGeneratorExpression.h"
 #include "cmGeneratorTarget.h"
 #include "cmLocalGenerator.h"
+#include "cmMakefile.h"
+#include "cmProperty.h"
 #include "cmStateDirectory.h"
 #include "cmStateSnapshot.h"
 #include "cmStateTypes.h"
@@ -30,26 +35,30 @@
       lg->GetStateSnapshot().GetDirectory().GetCurrentBinary());
     DirectoryTarget& dirTarget = dirTargets[currentBinaryDir];
     dirTarget.LG = lg.get();
+    const std::vector<std::string>& configs =
+      lg->GetMakefile()->GetGeneratorConfigs(cmMakefile::IncludeEmptyConfig);
 
     // The directory-level rule should depend on the target-level rules
     // for all targets in the directory.
     for (const auto& gt : lg->GetGeneratorTargets()) {
       cmStateEnums::TargetType const type = gt->GetType();
-      if (type != cmStateEnums::EXECUTABLE &&
-          type != cmStateEnums::STATIC_LIBRARY &&
-          type != cmStateEnums::SHARED_LIBRARY &&
-          type != cmStateEnums::MODULE_LIBRARY &&
-          type != cmStateEnums::OBJECT_LIBRARY &&
-          type != cmStateEnums::UTILITY) {
+      if (type == cmStateEnums::GLOBAL_TARGET || !gt->IsInBuildSystem()) {
         continue;
       }
       DirectoryTarget::Target t;
       t.GT = gt.get();
-      if (const char* exclude = gt->GetProperty("EXCLUDE_FROM_ALL")) {
-        if (cmIsOn(exclude)) {
-          // This target has been explicitly excluded.
-          t.ExcludeFromAll = true;
-        } else {
+      const std::string EXCLUDE_FROM_ALL("EXCLUDE_FROM_ALL");
+      if (cmProp exclude = gt->GetProperty(EXCLUDE_FROM_ALL)) {
+        for (const std::string& config : configs) {
+          cmGeneratorExpressionInterpreter genexInterpreter(lg.get(), config,
+                                                            gt.get());
+          if (cmIsOn(genexInterpreter.Evaluate(*exclude, EXCLUDE_FROM_ALL))) {
+            // This target has been explicitly excluded.
+            t.ExcludedFromAllInConfigs.push_back(config);
+          }
+        }
+
+        if (t.ExcludedFromAllInConfigs.empty()) {
           // This target has been explicitly un-excluded.  The directory-level
           // rule for every directory between this and the root should depend
           // on the target-level rule for this target.
@@ -77,3 +86,12 @@
 
   return dirTargets;
 }
+
+bool cmGlobalCommonGenerator::IsExcludedFromAllInConfig(
+  const DirectoryTarget::Target& t, const std::string& config)
+{
+  if (this->IsMultiConfig()) {
+    return cm::contains(t.ExcludedFromAllInConfigs, config);
+  }
+  return !t.ExcludedFromAllInConfigs.empty();
+}
diff --git a/Source/cmGlobalCommonGenerator.h b/Source/cmGlobalCommonGenerator.h
index 7d16dac..f97b5f4 100644
--- a/Source/cmGlobalCommonGenerator.h
+++ b/Source/cmGlobalCommonGenerator.h
@@ -30,7 +30,7 @@
     struct Target
     {
       cmGeneratorTarget const* GT = nullptr;
-      bool ExcludeFromAll = false;
+      std::vector<std::string> ExcludedFromAllInConfigs;
     };
     std::vector<Target> Targets;
     struct Dir
@@ -41,6 +41,8 @@
     std::vector<Dir> Children;
   };
   std::map<std::string, DirectoryTarget> ComputeDirectoryTargets() const;
+  bool IsExcludedFromAllInConfig(const DirectoryTarget::Target& t,
+                                 const std::string& config);
 };
 
 #endif
diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx
index 238097d..cad5d1f 100644
--- a/Source/cmGlobalGenerator.cxx
+++ b/Source/cmGlobalGenerator.cxx
@@ -14,6 +14,7 @@
 #include <utility>
 
 #include <cm/memory>
+#include <cmext/algorithm>
 
 #include "cmsys/Directory.hxx"
 #include "cmsys/FStream.hxx"
@@ -41,6 +42,7 @@
 #include "cmMakefile.h"
 #include "cmMessageType.h"
 #include "cmPolicies.h"
+#include "cmProperty.h"
 #include "cmRange.h"
 #include "cmSourceFile.h"
 #include "cmState.h"
@@ -51,8 +53,8 @@
 #include "cmake.h"
 
 #if !defined(CMAKE_BOOTSTRAP)
-#  include "cm_jsoncpp_value.h"
-#  include "cm_jsoncpp_writer.h"
+#  include <cm3p/json/value.h>
+#  include <cm3p/json/writer.h>
 
 #  include "cmCryptoHash.h"
 #  include "cmQtAutoGenGlobalInitializer.h"
@@ -231,8 +233,16 @@
   if (!optional && (path.empty() || !cmSystemTools::FileExists(path))) {
     return;
   }
-  const std::string* cname =
+  cmProp cname =
     this->GetCMakeInstance()->GetState()->GetInitializedCacheValue(langComp);
+
+  // Split compiler from arguments
+  std::vector<std::string> cnameArgVec;
+  if (cname && !cname->empty()) {
+    cmExpandList(*cname, cnameArgVec);
+    cname = &cnameArgVec.front();
+  }
+
   std::string changeVars;
   if (cname && !optional) {
     std::string cnameString;
@@ -246,11 +256,10 @@
     cmSystemTools::ConvertToUnixSlashes(cnameString);
     cmSystemTools::ConvertToUnixSlashes(pathString);
     if (cnameString != pathString) {
-      const char* cvars =
-        this->GetCMakeInstance()->GetState()->GetGlobalProperty(
-          "__CMAKE_DELETE_CACHE_CHANGE_VARS_");
+      cmProp cvars = this->GetCMakeInstance()->GetState()->GetGlobalProperty(
+        "__CMAKE_DELETE_CACHE_CHANGE_VARS_");
       if (cvars) {
-        changeVars += cvars;
+        changeVars += *cvars;
         changeVars += ";";
       }
       changeVars += langComp;
@@ -301,27 +310,12 @@
   bool failed = false;
   for (const auto& localGen : this->LocalGenerators) {
     for (const auto& target : localGen->GetGeneratorTargets()) {
-      if (target->GetType() == cmStateEnums::TargetType::GLOBAL_TARGET ||
-          target->GetType() == cmStateEnums::TargetType::INTERFACE_LIBRARY ||
-          target->GetType() == cmStateEnums::TargetType::UTILITY ||
+      if (!target->CanCompileSources() ||
           cmIsOn(target->GetProperty("ghs_integrity_app"))) {
         continue;
       }
 
-      std::vector<std::string> configs;
-      target->Makefile->GetConfigurations(configs);
-      std::vector<cmSourceFile*> srcs;
-      if (configs.empty()) {
-        target->GetSourceFiles(srcs, "");
-      } else {
-        for (std::string const& config : configs) {
-          target->GetSourceFiles(srcs, config);
-          if (srcs.empty()) {
-            break;
-          }
-        }
-      }
-      if (srcs.empty()) {
+      if (target->GetAllConfigSources().empty()) {
         std::ostringstream e;
         e << "No SOURCES given to target: " << target->GetName();
         this->GetCMakeInstance()->IssueMessage(
@@ -344,7 +338,8 @@
       if (target->GetType() == cmStateEnums::EXECUTABLE &&
           target->GetPropertyAsBool("WIN32_EXECUTABLE")) {
         std::vector<std::string> const& configs =
-          target->Makefile->GetGeneratorConfigs();
+          target->Makefile->GetGeneratorConfigs(
+            cmMakefile::IncludeEmptyConfig);
         for (std::string const& config : configs) {
           if (target->GetLinkerLanguage(config) == "Swift") {
             this->GetCMakeInstance()->IssueMessage(
@@ -369,16 +364,14 @@
   bool failed = false;
   for (const auto& generator : this->LocalGenerators) {
     for (const auto& target : generator->GetGeneratorTargets()) {
-      if (target->GetType() == cmStateEnums::TargetType::GLOBAL_TARGET ||
-          target->GetType() == cmStateEnums::TargetType::INTERFACE_LIBRARY ||
-          target->GetType() == cmStateEnums::TargetType::UTILITY ||
+      if (!target->CanCompileSources() ||
           cmIsOn(target->GetProperty("ghs_integrity_app"))) {
         continue;
       }
 
-      const std::string reuseFrom =
+      std::string const& reuseFrom =
         target->GetSafeProperty("PRECOMPILE_HEADERS_REUSE_FROM");
-      const std::string compilePdb =
+      std::string const& compilePdb =
         target->GetSafeProperty("COMPILE_PDB_NAME");
 
       if (!reuseFrom.empty() && reuseFrom != compilePdb) {
@@ -404,7 +397,7 @@
   if (it == this->BuildExportSets.end()) {
     return false;
   }
-  return !cmContains(this->BuildExportExportSets, filename);
+  return !cm::contains(this->BuildExportExportSets, filename);
 }
 
 // Find the make program for the generator, required for try compiles
@@ -416,15 +409,13 @@
       "all generators must specify this->FindMakeProgramFile");
     return false;
   }
-  if (!mf->GetDefinition("CMAKE_MAKE_PROGRAM") ||
-      cmIsOff(mf->GetDefinition("CMAKE_MAKE_PROGRAM"))) {
+  if (cmIsOff(mf->GetDefinition("CMAKE_MAKE_PROGRAM"))) {
     std::string setMakeProgram = mf->GetModulesFile(this->FindMakeProgramFile);
     if (!setMakeProgram.empty()) {
       mf->ReadListFile(setMakeProgram);
     }
   }
-  if (!mf->GetDefinition("CMAKE_MAKE_PROGRAM") ||
-      cmIsOff(mf->GetDefinition("CMAKE_MAKE_PROGRAM"))) {
+  if (cmIsOff(mf->GetDefinition("CMAKE_MAKE_PROGRAM"))) {
     std::ostringstream err;
     err << "CMake was unable to find a build program corresponding to \""
         << this->GetName() << "\".  CMAKE_MAKE_PROGRAM is not set.  You "
@@ -445,8 +436,8 @@
     cmSystemTools::GetShortPath(makeProgram, makeProgram);
     cmSystemTools::SplitProgramPath(makeProgram, dir, file);
     makeProgram = cmStrCat(dir, '/', saveFile);
-    mf->AddCacheDefinition("CMAKE_MAKE_PROGRAM", makeProgram.c_str(),
-                           "make program", cmStateEnums::FILEPATH);
+    mf->AddCacheDefinition("CMAKE_MAKE_PROGRAM", makeProgram, "make program",
+                           cmStateEnums::FILEPATH);
   }
   return true;
 }
@@ -530,7 +521,7 @@
       if (lang == "NONE") {
         this->SetLanguageEnabled("NONE", mf);
       } else {
-        if (!cmContains(this->LanguagesReady, lang)) {
+        if (!cm::contains(this->LanguagesReady, lang)) {
           std::ostringstream e;
           e << "The test project needs language " << lang
             << " which is not enabled.";
@@ -587,6 +578,16 @@
       mf->ReadListFile(fpath);
     }
   }
+
+  if (readCMakeSystem) {
+    // Find the native build tool for this generator.
+    // This has to be done early so that MSBuild can be used to examine the
+    // cross-compilation environment.
+    if (!this->FindMakeProgram(mf)) {
+      return;
+    }
+  }
+
   //  Load the CMakeDetermineSystem.cmake file and find out
   // what platform we are running on
   if (!mf->GetDefinition("CMAKE_SYSTEM")) {
@@ -658,11 +659,6 @@
       cmSystemTools::SetFatalErrorOccured();
       return;
     }
-
-    // Find the native build tool for this generator.
-    if (!this->FindMakeProgram(mf)) {
-      return;
-    }
   }
 
   // Check that the languages are supported by the generator and its
@@ -785,7 +781,7 @@
     std::string compilerEnv = cmStrCat("CMAKE_", lang, "_COMPILER_ENV_VAR");
     std::ostringstream noCompiler;
     const char* compilerFile = mf->GetDefinition(compilerName);
-    if (!compilerFile || !*compilerFile || cmIsNOTFOUND(compilerFile)) {
+    if (!cmNonempty(compilerFile) || cmIsNOTFOUND(compilerFile)) {
       /* clang-format off */
       noCompiler <<
         "No " << compilerName << " could be found.\n"
@@ -1095,7 +1091,7 @@
 {
   // use LanguageToLinkerPreference to detect whether this functions has
   // run before
-  if (cmContains(this->LanguageToLinkerPreference, l)) {
+  if (cm::contains(this->LanguageToLinkerPreference, l)) {
     return;
   }
 
@@ -1418,13 +1414,13 @@
   // so create the map from project name to vector of local generators
   this->FillProjectMap();
 
-  // Iterate through all targets and set up AUTOMOC, AUTOUIC and AUTORCC
-  if (!this->QtAutoGen()) {
+  // Add automatically generated sources (e.g. unity build).
+  if (!this->AddAutomaticSources()) {
     return false;
   }
 
-  // Add automatically generated sources (e.g. unity build).
-  if (!this->AddAutomaticSources()) {
+  // Iterate through all targets and set up AUTOMOC, AUTOUIC and AUTORCC
+  if (!this->QtAutoGen()) {
     return false;
   }
 
@@ -1433,12 +1429,10 @@
     localGen->AddHelperCommands();
   }
 
-  // Finalize the set of compile features for each target.
-  // FIXME: This turns into calls to cmMakefile::AddRequiredTargetFeature
-  // which actually modifies the <lang>_STANDARD target property
-  // on the original cmTarget instance.  It accumulates features
-  // across all configurations.  Some refactoring is needed to
-  // compute a per-config resulta purely during generation.
+  // Perform up-front computation in order to handle errors (such as unknown
+  // features) at this point. While processing the compile features we also
+  // calculate and cache the language standard required by the compile
+  // features.
   for (const auto& localGen : this->LocalGenerators) {
     if (!localGen->ComputeTargetCompileFeatures()) {
       return false;
@@ -1603,9 +1597,7 @@
   for (const auto& lg : this->LocalGenerators) {
     lg->CreateEvaluationFileOutputs();
     for (const auto& gt : lg->GetGeneratorTargets()) {
-      if (gt->GetType() == cmStateEnums::INTERFACE_LIBRARY ||
-          gt->GetType() == cmStateEnums::UTILITY ||
-          gt->GetType() == cmStateEnums::GLOBAL_TARGET) {
+      if (!gt->CanCompileSources()) {
         continue;
       }
       lg->AddUnityBuild(gt.get());
@@ -1617,9 +1609,7 @@
   }
   for (const auto& lg : this->LocalGenerators) {
     for (const auto& gt : lg->GetGeneratorTargets()) {
-      if (gt->GetType() == cmStateEnums::INTERFACE_LIBRARY ||
-          gt->GetType() == cmStateEnums::UTILITY ||
-          gt->GetType() == cmStateEnums::GLOBAL_TARGET) {
+      if (!gt->CanCompileSources()) {
         continue;
       }
       // Handle targets that re-use a PCH from an above-handled target.
@@ -1689,14 +1679,14 @@
       cmPolicies::PolicyStatus polSt =
         mf->GetPolicyStatus(cmPolicies::CMP0043);
       if (polSt == cmPolicies::WARN || polSt == cmPolicies::OLD) {
-        std::vector<std::string> configs;
-        mf->GetConfigurations(configs);
+        std::vector<std::string> configs =
+          mf->GetGeneratorConfigs(cmMakefile::ExcludeEmptyConfig);
 
         for (std::string const& c : configs) {
           std::string defPropName =
             cmStrCat("COMPILE_DEFINITIONS_", cmSystemTools::UpperCase(c));
-          if (const char* val = mf->GetProperty(defPropName)) {
-            t->AppendProperty(defPropName, val);
+          if (cmProp val = mf->GetProperty(defPropName)) {
+            t->AppendProperty(defPropName, *val);
           }
         }
       }
@@ -1807,14 +1797,13 @@
         }
       }
       std::vector<std::string> incs;
-      const char* incDirProp =
-        target.second.GetProperty("INCLUDE_DIRECTORIES");
+      cmProp incDirProp = target.second.GetProperty("INCLUDE_DIRECTORIES");
       if (!incDirProp) {
         continue;
       }
 
       std::string incDirs = cmGeneratorExpression::Preprocess(
-        incDirProp, cmGeneratorExpression::StripAllGeneratorExpressions);
+        *incDirProp, cmGeneratorExpression::StripAllGeneratorExpressions);
 
       cmExpandList(incDirs, incs);
 
@@ -1980,8 +1969,9 @@
   std::string makeCommandStr;
   output += "\nRun Build Command(s):";
 
-  for (auto command = makeCommand.begin(); command != makeCommand.end();
-       ++command) {
+  retVal = 0;
+  for (auto command = makeCommand.begin();
+       command != makeCommand.end() && retVal == 0; ++command) {
     makeCommandStr = command->Printable();
     if (command != makeCommand.end()) {
       makeCommandStr += " && ";
@@ -2066,9 +2056,8 @@
 
   // update progress
   // estimate how many lg there will be
-  const std::string* numGenC =
-    this->CMakeInstance->GetState()->GetInitializedCacheValue(
-      "CMAKE_NUMBER_OF_MAKEFILES");
+  cmProp numGenC = this->CMakeInstance->GetState()->GetInitializedCacheValue(
+    "CMAKE_NUMBER_OF_MAKEFILES");
 
   if (!numGenC) {
     // If CMAKE_NUMBER_OF_MAKEFILES is not set
@@ -2172,13 +2161,38 @@
 }
 
 bool cmGlobalGenerator::IsExcluded(cmLocalGenerator* root,
-                                   cmGeneratorTarget* target) const
+                                   const cmGeneratorTarget* target) const
 {
-  if (target->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
+  if (!target->IsInBuildSystem()) {
     return true;
   }
-  if (const char* exclude = target->GetProperty("EXCLUDE_FROM_ALL")) {
-    return cmIsOn(exclude);
+  cmMakefile* mf = root->GetMakefile();
+  const std::string EXCLUDE_FROM_ALL = "EXCLUDE_FROM_ALL";
+  if (cmProp exclude = target->GetProperty(EXCLUDE_FROM_ALL)) {
+    // Expand the property value per configuration.
+    unsigned int trueCount = 0;
+    unsigned int falseCount = 0;
+    const std::vector<std::string>& configs =
+      mf->GetGeneratorConfigs(cmMakefile::IncludeEmptyConfig);
+    for (const std::string& config : configs) {
+      cmGeneratorExpressionInterpreter genexInterpreter(root, config, target);
+      if (cmIsOn(genexInterpreter.Evaluate(*exclude, EXCLUDE_FROM_ALL))) {
+        ++trueCount;
+      } else {
+        ++falseCount;
+      }
+    }
+
+    // Check whether the genex expansion of the property agrees in all
+    // configurations.
+    if (trueCount && falseCount) {
+      std::ostringstream e;
+      e << "The EXCLUDE_FROM_ALL property of target \"" << target->GetName()
+        << "\" varies by configuration. This is not supported by the \""
+        << root->GetGlobalGenerator()->GetName() << "\" generator.";
+      mf->IssueMessage(MessageType::FATAL_ERROR, e.str());
+    }
+    return trueCount;
   }
   // This target is included in its directory.  Check whether the
   // directory is excluded.
@@ -2245,7 +2259,7 @@
 
 bool cmGlobalGenerator::IsAlias(const std::string& name) const
 {
-  return cmContains(this->AliasTargets, name);
+  return cm::contains(this->AliasTargets, name);
 }
 
 void cmGlobalGenerator::IndexTarget(cmTarget* t)
@@ -2271,10 +2285,12 @@
   // Use a ":" prefix to avoid conflict with project-defined targets.
   // We must satisfy cmGeneratorExpression::IsValidTargetName so use no
   // other special characters.
-  char buf[1 + sizeof(gt) * 2];
+  constexpr size_t sizeof_ptr =
+    sizeof(gt); // NOLINT(bugprone-sizeof-expression)
+  char buf[1 + sizeof_ptr * 2];
   char* b = buf;
   *b++ = ':';
-  for (size_t i = 0; i < sizeof(gt); ++i) {
+  for (size_t i = 0; i < sizeof_ptr; ++i) {
     unsigned char const c = reinterpret_cast<unsigned char const*>(&gt)[i];
     *b++ = hexDigits[(c & 0xf0) >> 4];
     *b++ = hexDigits[(c & 0x0f)];
@@ -2436,7 +2452,7 @@
   gti.WorkingDir = mf->GetCurrentBinaryDirectory();
   cmCustomCommandLine singleLine;
   singleLine.push_back(cmSystemTools::GetCPackCommand());
-  if (cmakeCfgIntDir && *cmakeCfgIntDir && cmakeCfgIntDir[0] != '.') {
+  if (cmNonempty(cmakeCfgIntDir) && cmakeCfgIntDir[0] != '.') {
     singleLine.push_back("-C");
     singleLine.push_back(cmakeCfgIntDir);
   }
@@ -2515,14 +2531,13 @@
   cmCustomCommandLine singleLine;
   singleLine.push_back(cmSystemTools::GetCTestCommand());
   singleLine.push_back("--force-new-ctest-process");
-  if (auto testArgs = mf->GetDefinition("CMAKE_CTEST_ARGUMENTS")) {
-    std::vector<std::string> args;
-    cmExpandList(testArgs, args);
+  std::vector<std::string> args;
+  if (mf->GetDefExpandList("CMAKE_CTEST_ARGUMENTS", args)) {
     for (auto const& arg : args) {
       singleLine.push_back(arg);
     }
   }
-  if (cmakeCfgIntDir && *cmakeCfgIntDir && cmakeCfgIntDir[0] != '.') {
+  if (cmNonempty(cmakeCfgIntDir) && cmakeCfgIntDir[0] != '.') {
     singleLine.push_back("-C");
     singleLine.push_back(cmakeCfgIntDir);
   } else // TODO: This is a hack. Should be something to do with the
@@ -2543,7 +2558,7 @@
   }
   GlobalTargetInfo gti;
   gti.Name = editCacheTargetName;
-  gti.PerConfig = false;
+  gti.PerConfig = cmTarget::PerConfig::No;
   cmCustomCommandLine singleLine;
 
   // Use generator preference for the edit_cache rule if it is defined.
@@ -2561,6 +2576,7 @@
     singleLine.push_back("No interactive CMake dialog available.");
     gti.Message = "No interactive CMake dialog available...";
     gti.UsesTerminal = false;
+    gti.StdPipesUTF8 = true;
   }
   gti.CommandLines.push_back(std::move(singleLine));
 
@@ -2578,13 +2594,14 @@
   gti.Name = rebuildCacheTargetName;
   gti.Message = "Running CMake to regenerate build system...";
   gti.UsesTerminal = true;
-  gti.PerConfig = false;
+  gti.PerConfig = cmTarget::PerConfig::No;
   cmCustomCommandLine singleLine;
   singleLine.push_back(cmSystemTools::GetCMakeCommand());
   singleLine.push_back("--regenerate-during-build");
   singleLine.push_back("-S$(CMAKE_SOURCE_DIR)");
   singleLine.push_back("-B$(CMAKE_BINARY_DIR)");
   gti.CommandLines.push_back(std::move(singleLine));
+  gti.StdPipesUTF8 = true;
   targets.push_back(std::move(gti));
 }
 
@@ -2601,7 +2618,7 @@
       "installation rules have been specified",
       mf->GetBacktrace());
   } else if (this->InstallTargetEnabled && !skipInstallRules) {
-    if (!cmakeCfgIntDir || !*cmakeCfgIntDir || cmakeCfgIntDir[0] == '.') {
+    if (!(cmNonempty(cmakeCfgIntDir) && cmakeCfgIntDir[0] != '.')) {
       std::set<std::string>* componentsSet = &this->InstallComponents;
       std::ostringstream ostr;
       if (!componentsSet->empty()) {
@@ -2621,6 +2638,7 @@
     gti.Name = this->GetInstallTargetName();
     gti.Message = "Install the project...";
     gti.UsesTerminal = true;
+    gti.StdPipesUTF8 = true;
     cmCustomCommandLine singleLine;
     if (this->GetPreinstallTargetName()) {
       gti.Depends.emplace_back(this->GetPreinstallTargetName());
@@ -2639,7 +2657,7 @@
       cmd = "cmake";
     }
     singleLine.push_back(cmd);
-    if (cmakeCfgIntDir && *cmakeCfgIntDir && cmakeCfgIntDir[0] != '.') {
+    if (cmNonempty(cmakeCfgIntDir) && cmakeCfgIntDir[0] != '.') {
       std::string cfgArg = "-DBUILD_TYPE=";
       bool useEPN = this->UseEffectivePlatformName(mf.get());
       if (useEPN) {
@@ -2690,13 +2708,13 @@
   }
 }
 
-const char* cmGlobalGenerator::GetPredefinedTargetsFolder()
+std::string cmGlobalGenerator::GetPredefinedTargetsFolder()
 {
-  const char* prop = this->GetCMakeInstance()->GetState()->GetGlobalProperty(
+  cmProp prop = this->GetCMakeInstance()->GetState()->GetGlobalProperty(
     "PREDEFINED_TARGETS_FOLDER");
 
   if (prop) {
-    return prop;
+    return *prop;
   }
 
   return "CMakePredefinedTargets";
@@ -2704,13 +2722,13 @@
 
 bool cmGlobalGenerator::UseFolderProperty() const
 {
-  const char* prop =
+  cmProp prop =
     this->GetCMakeInstance()->GetState()->GetGlobalProperty("USE_FOLDERS");
 
   // If this property is defined, let the setter turn this on or off...
   //
   if (prop) {
-    return cmIsOn(prop);
+    return cmIsOn(*prop);
   }
 
   // By default, this feature is OFF, since it is not supported in the
@@ -2732,7 +2750,8 @@
   std::vector<std::string> no_depends;
   // Store the custom command in the target.
   cmCustomCommand cc(no_outputs, no_byproducts, no_depends, gti.CommandLines,
-                     cmListFileBacktrace(), nullptr, gti.WorkingDir.c_str());
+                     cmListFileBacktrace(), nullptr, gti.WorkingDir.c_str(),
+                     gti.StdPipesUTF8);
   cc.SetUsesTerminal(gti.UsesTerminal);
   target.AddPostBuildCommand(std::move(cc));
   if (!gti.Message.empty()) {
@@ -2804,7 +2823,7 @@
                                     "clean",     "edit_cache", "rebuild_cache",
                                     "ZERO_CHECK" };
 
-  return cmContains(reservedTargets, name);
+  return cm::contains(reservedTargets, name);
 }
 
 void cmGlobalGenerator::SetExternalMakefileProjectGenerator(
@@ -3033,7 +3052,7 @@
 
   for (const auto& lg : this->LocalGenerators) {
     for (const auto& tgt : lg->GetGeneratorTargets()) {
-      if (tgt->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
+      if (!tgt->IsInBuildSystem()) {
         continue;
       }
       this->WriteSummary(tgt.get());
@@ -3051,8 +3070,8 @@
 
 #ifndef CMAKE_BOOTSTRAP
   // Check whether labels are enabled for this target.
-  const char* targetLabels = target->GetProperty("LABELS");
-  const char* directoryLabels =
+  cmProp targetLabels = target->GetProperty("LABELS");
+  cmProp directoryLabels =
     target->Target->GetMakefile()->GetProperty("LABELS");
   const char* cmakeDirectoryLabels =
     target->Target->GetMakefile()->GetDefinition("CMAKE_DIRECTORY_LABELS");
@@ -3071,7 +3090,7 @@
     // List the target-wide labels.  All sources in the target get
     // these labels.
     if (targetLabels) {
-      cmExpandList(targetLabels, labels);
+      cmExpandList(*targetLabels, labels);
       if (!labels.empty()) {
         fout << "# Target labels\n";
         for (std::string const& l : labels) {
@@ -3086,7 +3105,7 @@
     std::vector<std::string> cmakeDirectoryLabelsList;
 
     if (directoryLabels) {
-      cmExpandList(directoryLabels, directoryLabelsList);
+      cmExpandList(*directoryLabels, directoryLabelsList);
     }
 
     if (cmakeDirectoryLabels) {
@@ -3111,7 +3130,8 @@
     fout << "# Source files and their labels\n";
     std::vector<cmSourceFile*> sources;
     std::vector<std::string> const& configs =
-      target->Target->GetMakefile()->GetGeneratorConfigs();
+      target->Target->GetMakefile()->GetGeneratorConfigs(
+        cmMakefile::IncludeEmptyConfig);
     for (std::string const& c : configs) {
       target->GetSourceFiles(sources, c);
     }
@@ -3121,10 +3141,10 @@
       std::string const& sfp = sf->ResolveFullPath();
       fout << sfp << "\n";
       lj_source["file"] = sfp;
-      if (const char* svalue = sf->GetProperty("LABELS")) {
+      if (cmProp svalue = sf->GetProperty("LABELS")) {
         labels.clear();
         Json::Value& lj_source_labels = lj_source["labels"] = Json::arrayValue;
-        cmExpandList(svalue, labels);
+        cmExpandList(*svalue, labels);
         for (std::string const& label : labels) {
           fout << " " << label << "\n";
           lj_source_labels.append(label);
@@ -3210,8 +3230,9 @@
   const auto& lg = this->LocalGenerators[0];
   cmMakefile* mf = lg->GetMakefile();
 
-  std::vector<std::string> configs;
-  std::string config = mf->GetConfigurations(configs, false);
+  std::vector<std::string> configs =
+    mf->GetGeneratorConfigs(cmMakefile::OnlyMultiConfig);
+  std::string config = mf->GetDefaultConfiguration();
 
   std::string path = cmStrCat(this->CMakeInstance->GetHomeOutputDirectory(),
                               "/CPackProperties.cmake");
diff --git a/Source/cmGlobalGenerator.h b/Source/cmGlobalGenerator.h
index 7dc4822..c2c80c2 100644
--- a/Source/cmGlobalGenerator.h
+++ b/Source/cmGlobalGenerator.h
@@ -28,7 +28,7 @@
 #include "cmTargetDepend.h"
 
 #if !defined(CMAKE_BOOTSTRAP)
-#  include "cm_jsoncpp_value.h"
+#  include <cm3p/json/value.h>
 
 #  include "cmFileLockPool.h"
 #endif
@@ -542,7 +542,8 @@
   bool IsExcluded(cmStateSnapshot const& root,
                   cmStateSnapshot const& snp) const;
   bool IsExcluded(cmLocalGenerator* root, cmLocalGenerator* gen) const;
-  bool IsExcluded(cmLocalGenerator* root, cmGeneratorTarget* target) const;
+  bool IsExcluded(cmLocalGenerator* root,
+                  const cmGeneratorTarget* target) const;
   virtual void InitializeProgressMarks() {}
 
   struct GlobalTargetInfo
@@ -553,7 +554,8 @@
     std::vector<std::string> Depends;
     std::string WorkingDir;
     bool UsesTerminal = false;
-    bool PerConfig = true;
+    cmTarget::PerConfig PerConfig = cmTarget::PerConfig::Yes;
+    bool StdPipesUTF8 = false;
   };
 
   void CreateDefaultGlobalTargets(std::vector<GlobalTargetInfo>& targets);
@@ -588,7 +590,7 @@
 
   cmGeneratorTarget* FindGeneratorTargetImpl(std::string const& name) const;
 
-  const char* GetPredefinedTargetsFolder();
+  std::string GetPredefinedTargetsFolder();
 
 private:
   using TargetMap = std::unordered_map<std::string, cmTarget*>;
diff --git a/Source/cmGlobalGeneratorFactory.h b/Source/cmGlobalGeneratorFactory.h
index 3709365..13cfe4d 100644
--- a/Source/cmGlobalGeneratorFactory.h
+++ b/Source/cmGlobalGeneratorFactory.h
@@ -44,7 +44,7 @@
   /** Get the list of supported platforms name for this generator */
   virtual std::vector<std::string> GetKnownPlatforms() const = 0;
 
-  /** If the generator suports platforms, get its default.  */
+  /** If the generator supports platforms, get its default.  */
   virtual std::string GetDefaultPlatformName() const = 0;
 };
 
diff --git a/Source/cmGlobalGhsMultiGenerator.cxx b/Source/cmGlobalGhsMultiGenerator.cxx
index bb9dd37..7c87131 100644
--- a/Source/cmGlobalGhsMultiGenerator.cxx
+++ b/Source/cmGlobalGhsMultiGenerator.cxx
@@ -9,8 +9,9 @@
 #include <utility>
 
 #include <cm/memory>
+#include <cm/string>
+#include <cmext/algorithm>
 
-#include "cmAlgorithms.h"
 #include "cmDocumentationEntry.h"
 #include "cmGeneratedFileStream.h"
 #include "cmGeneratorTarget.h"
@@ -18,6 +19,7 @@
 #include "cmLocalGenerator.h"
 #include "cmLocalGhsMultiGenerator.h"
 #include "cmMakefile.h"
+#include "cmProperty.h"
 #include "cmState.h"
 #include "cmStateTypes.h"
 #include "cmStringAlgorithms.h"
@@ -90,7 +92,7 @@
     /* store the full toolset for later use
      * -- already done if -T<toolset> was specified
      */
-    mf->AddCacheDefinition("CMAKE_GENERATOR_TOOLSET", tsp.c_str(),
+    mf->AddCacheDefinition("CMAKE_GENERATOR_TOOLSET", tsp,
                            "Location of generator toolset.",
                            cmStateEnums::INTERNAL);
   }
@@ -112,8 +114,8 @@
   }
 
   /* store the toolset that is being used for this build */
-  mf->AddCacheDefinition("CMAKE_MAKE_PROGRAM", gbuild.c_str(),
-                         "build program to use", cmStateEnums::INTERNAL, true);
+  mf->AddCacheDefinition("CMAKE_MAKE_PROGRAM", gbuild, "build program to use",
+                         cmStateEnums::INTERNAL, true);
 
   mf->AddDefinition("CMAKE_SYSTEM_VERSION", tsp);
 
@@ -132,7 +134,7 @@
     /* store the platform name for later use
      * -- already done if -A<arch> was specified
      */
-    mf->AddCacheDefinition("CMAKE_GENERATOR_PLATFORM", arch.c_str(),
+    mf->AddCacheDefinition("CMAKE_GENERATOR_PLATFORM", arch,
                            "Name of generator platform.",
                            cmStateEnums::INTERNAL);
   } else {
@@ -166,7 +168,7 @@
   if (cmIsOff(bspName) && platform.find("integrity") != std::string::npos) {
     bspName = "sim" + arch;
     /* write back the calculate name for next time */
-    mf->AddCacheDefinition("GHS_BSP_NAME", bspName.c_str(),
+    mf->AddCacheDefinition("GHS_BSP_NAME", bspName,
                            "Name of GHS target platform.",
                            cmStateEnums::STRING, true);
     std::string m = cmStrCat(
@@ -216,10 +218,11 @@
 {
   const char* ghsRoot = mf->GetDefinition("GHS_TOOLSET_ROOT");
 
-  if (!ghsRoot || ghsRoot[0] == '\0') {
-    ghsRoot = DEFAULT_TOOLSET_ROOT;
+  if (cmNonempty(ghsRoot)) {
+    tsd = ghsRoot;
+  } else {
+    tsd = DEFAULT_TOOLSET_ROOT;
   }
-  tsd = ghsRoot;
 
   if (ts.empty()) {
     std::vector<std::string> output;
@@ -253,14 +256,15 @@
 
 void cmGlobalGhsMultiGenerator::WriteFileHeader(std::ostream& fout)
 {
-  fout << "#!gbuild" << std::endl;
-  fout << "#" << std::endl
-       << "# CMAKE generated file: DO NOT EDIT!" << std::endl
-       << "# Generated by \"" << GetActualName() << "\""
-       << " Generator, CMake Version " << cmVersion::GetMajorVersion() << "."
-       << cmVersion::GetMinorVersion() << std::endl
-       << "#" << std::endl
-       << std::endl;
+  /* clang-format off */
+  fout << "#!gbuild\n"
+          "#\n"
+          "# CMAKE generated file: DO NOT EDIT!\n"
+          "# Generated by \"" << GetActualName() << "\""
+          " Generator, CMake Version " << cmVersion::GetMajorVersion() << '.'
+       << cmVersion::GetMinorVersion() << "\n"
+          "#\n\n";
+  /* clang-format on */
 }
 
 void cmGlobalGhsMultiGenerator::WriteCustomRuleBOD(std::ostream& fout)
@@ -268,36 +272,36 @@
   fout << "Commands {\n"
           "  Custom_Rule_Command {\n"
           "    name = \"Custom Rule Command\"\n"
-          "    exec = \"";
+          "    exec = \""
 #ifdef _WIN32
-  fout << "cmd.exe";
+          "cmd.exe"
 #else
-  fout << "/bin/sh";
+          "/bin/sh"
 #endif
-  fout << "\"\n"
+          "\"\n"
           "    options = {\"SpecialOptions\"}\n"
           "  }\n"
-          "}\n";
+          "}\n"
 
-  fout << "\n\n";
-  fout << "FileTypes {\n"
+          "\n\n"
+          "FileTypes {\n"
           "  CmakeRule {\n"
           "    name = \"Custom Rule\"\n"
           "    action = \"&Run\"\n"
-          "    extensions = {\"";
+          "    extensions = {\""
 #ifdef _WIN32
-  fout << "bat";
+          "bat"
 #else
-  fout << "sh";
+          "sh"
 #endif
-  fout << "\"}\n"
+          "\"}\n"
           "    grepable = false\n"
           "    command = \"Custom Rule Command\"\n"
-          "    commandLine = \"$COMMAND ";
+          "    commandLine = \"$COMMAND "
 #ifdef _WIN32
-  fout << "/c";
+          "/c"
 #endif
-  fout << " $INPUTFILE\"\n"
+          " $INPUTFILE\"\n"
           "    progress = \"Processing Custom Rule\"\n"
           "    promoteToFirstPass = true\n"
           "    outputType = \"None\"\n"
@@ -327,13 +331,13 @@
   this->WriteHighLevelDirectives(root, fout);
   GhsMultiGpj::WriteGpjTag(GhsMultiGpj::PROJECT, fout);
 
-  fout << "# Top Level Project File" << std::endl;
+  fout << "# Top Level Project File\n";
 
   // Specify BSP option if supplied by user
   const char* bspName =
     this->GetCMakeInstance()->GetCacheDefinition("GHS_BSP_NAME");
   if (!cmIsOff(bspName)) {
-    fout << "    -bsp " << bspName << std::endl;
+    fout << "    -bsp " << bspName << '\n';
   }
 
   // Specify OS DIR if supplied by user
@@ -348,14 +352,14 @@
     } else {
       fout << osDirOption;
     }
-    fout << "\"" << this->OsDir << "\"" << std::endl;
+    fout << "\"" << this->OsDir << "\"\n";
   }
 }
 
 void cmGlobalGhsMultiGenerator::WriteSubProjects(std::ostream& fout,
                                                  std::string& all_target)
 {
-  fout << "CMakeFiles/" << all_target << " [Project]" << std::endl;
+  fout << "CMakeFiles/" << all_target << " [Project]\n";
   // All known targets
   for (cmGeneratorTarget const* target : this->ProjectTargets) {
     if (target->GetType() == cmStateEnums::INTERFACE_LIBRARY ||
@@ -366,7 +370,7 @@
       continue;
     }
     fout << "CMakeFiles/" << target->GetName() + ".tgt" + FILE_EXTENSION
-         << " [Project]" << std::endl;
+         << " [Project]\n";
   }
 }
 
@@ -374,8 +378,8 @@
   std::ostream& fout, cmGeneratorTarget const* target, cmLocalGenerator* root,
   std::string& rootBinaryDir)
 {
-  const char* projName = target->GetProperty("GENERATOR_FILE_NAME");
-  const char* projType = target->GetProperty("GENERATOR_FILE_NAME_EXT");
+  cmProp projName = target->GetProperty("GENERATOR_FILE_NAME");
+  cmProp projType = target->GetProperty("GENERATOR_FILE_NAME_EXT");
   if (projName && projType) {
     cmLocalGenerator* lg = target->GetLocalGenerator();
     std::string dir = lg->GetCurrentBinaryDirectory();
@@ -388,9 +392,9 @@
       }
     }
 
-    std::string projFile = dir + projName + FILE_EXTENSION;
+    std::string projFile = dir + *projName + FILE_EXTENSION;
     fout << projFile;
-    fout << " " << projType << std::endl;
+    fout << ' ' << *projType << '\n';
   } else {
     /* Should never happen */
     std::string message =
@@ -464,10 +468,10 @@
     this->ProjectTargets.push_back(t);
   }
   for (cmGeneratorTarget const* t : sortedProjectTargets) {
-    if (t->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
+    if (!t->IsInBuildSystem()) {
       continue;
     }
-    if (!cmIsOn(t->GetProperty("EXCLUDE_FROM_ALL"))) {
+    if (!IsExcluded(t->GetLocalGenerator(), t)) {
       defaultTargets.push_back(t);
     }
   }
@@ -583,14 +587,14 @@
     /* if multiple top-projects are found in build directory
      * then prefer projectName top-project.
      */
-    if (!cmContains(files, proj)) {
+    if (!cm::contains(files, proj)) {
       proj = files.at(0);
     }
   }
 
   makeCommand.Add("-top", proj);
   if (!targetNames.empty()) {
-    if (cmContains(targetNames, "clean")) {
+    if (cm::contains(targetNames, "clean")) {
       makeCommand.Add("-clean");
     } else {
       for (const auto& tname : targetNames) {
@@ -612,14 +616,14 @@
 void cmGlobalGhsMultiGenerator::WriteMacros(std::ostream& fout,
                                             cmLocalGenerator* root)
 {
-  fout << "macro PROJ_NAME=" << root->GetProjectName() << std::endl;
+  fout << "macro PROJ_NAME=" << root->GetProjectName() << '\n';
   char const* ghsGpjMacros =
     this->GetCMakeInstance()->GetCacheDefinition("GHS_GPJ_MACROS");
   if (nullptr != ghsGpjMacros) {
     std::vector<std::string> expandedList =
       cmExpandedList(std::string(ghsGpjMacros));
     for (std::string const& arg : expandedList) {
-      fout << "macro " << arg << std::endl;
+      fout << "macro " << arg << '\n';
     }
   }
 }
@@ -631,7 +635,7 @@
   std::string tgt;
   const char* t =
     this->GetCMakeInstance()->GetCacheDefinition("GHS_PRIMARY_TARGET");
-  if (t && *t != '\0') {
+  if (cmNonempty(t)) {
     tgt = t;
     this->GetCMakeInstance()->MarkCliAsUsed("GHS_PRIMARY_TARGET");
   } else {
@@ -642,30 +646,27 @@
     tgt = cmStrCat((a ? a : ""), '_', (p ? p : ""), ".tgt");
   }
 
-  fout << "primaryTarget=" << tgt << std::endl;
-  fout << "customization=" << root->GetBinaryDirectory()
-       << "/CMakeFiles/custom_rule.bod" << std::endl;
-  fout << "customization=" << root->GetBinaryDirectory()
-       << "/CMakeFiles/custom_target.bod" << std::endl;
+  /* clang-format off */
+  fout << "primaryTarget=" << tgt << "\n"
+          "customization=" << root->GetBinaryDirectory()
+       << "/CMakeFiles/custom_rule.bod\n"
+          "customization=" << root->GetBinaryDirectory()
+       << "/CMakeFiles/custom_target.bod" << '\n';
+  /* clang-format on */
 
   char const* const customization =
     this->GetCMakeInstance()->GetCacheDefinition("GHS_CUSTOMIZATION");
   if (nullptr != customization && strlen(customization) > 0) {
-    fout << "customization=" << this->TrimQuotes(customization) << std::endl;
+    fout << "customization="
+         << cmGlobalGhsMultiGenerator::TrimQuotes(customization) << '\n';
     this->GetCMakeInstance()->MarkCliAsUsed("GHS_CUSTOMIZATION");
   }
 }
 
-std::string cmGlobalGhsMultiGenerator::TrimQuotes(std::string const& str)
+std::string cmGlobalGhsMultiGenerator::TrimQuotes(std::string str)
 {
-  std::string result;
-  result.reserve(str.size());
-  for (const char* ch = str.c_str(); *ch != '\0'; ++ch) {
-    if (*ch != '"') {
-      result += *ch;
-    }
-  }
-  return result;
+  cm::erase(str, '"');
+  return str;
 }
 
 bool cmGlobalGhsMultiGenerator::TargetCompare::operator()(
diff --git a/Source/cmGlobalGhsMultiGenerator.h b/Source/cmGlobalGhsMultiGenerator.h
index b82e9f5..12ca8b6 100644
--- a/Source/cmGlobalGhsMultiGenerator.h
+++ b/Source/cmGlobalGhsMultiGenerator.h
@@ -111,7 +111,7 @@
                       std::vector<cmLocalGenerator*>& generators,
                       std::string& all_target);
 
-  std::string TrimQuotes(std::string const& str);
+  static std::string TrimQuotes(std::string str);
 
   std::string OsDir;
   static const char* DEFAULT_BUILD_PROGRAM;
diff --git a/Source/cmGlobalNinjaGenerator.cxx b/Source/cmGlobalNinjaGenerator.cxx
index b6c343c..f0fa1f4 100644
--- a/Source/cmGlobalNinjaGenerator.cxx
+++ b/Source/cmGlobalNinjaGenerator.cxx
@@ -5,20 +5,19 @@
 #include <algorithm>
 #include <cctype>
 #include <cstdio>
-#include <iterator>
 #include <sstream>
 
+#include <cm/iterator>
 #include <cm/memory>
 #include <cmext/algorithm>
 #include <cmext/memory>
 
+#include <cm3p/json/reader.h>
+#include <cm3p/json/value.h>
+#include <cm3p/json/writer.h>
+
 #include "cmsys/FStream.hxx"
 
-#include "cm_jsoncpp_reader.h"
-#include "cm_jsoncpp_value.h"
-#include "cm_jsoncpp_writer.h"
-
-#include "cmAlgorithms.h"
 #include "cmDocumentationEntry.h"
 #include "cmFortranParser.h"
 #include "cmGeneratedFileStream.h"
@@ -46,7 +45,8 @@
 #include "cmake.h"
 
 const char* cmGlobalNinjaGenerator::NINJA_BUILD_FILE = "build.ninja";
-const char* cmGlobalNinjaGenerator::NINJA_RULES_FILE = "rules.ninja";
+const char* cmGlobalNinjaGenerator::NINJA_RULES_FILE =
+  "CMakeFiles/rules.ninja";
 const char* cmGlobalNinjaGenerator::INDENT = "  ";
 #ifdef _WIN32
 std::string const cmGlobalNinjaGenerator::SHELL_NOOP = "cd .";
@@ -147,15 +147,15 @@
 {
   // Make sure there is a rule.
   if (build.Rule.empty()) {
-    cmSystemTools::Error("No rule for WriteBuild! called with comment: " +
-                         build.Comment);
+    cmSystemTools::Error(cmStrCat(
+      "No rule for WriteBuild! called with comment: ", build.Comment));
     return;
   }
 
   // Make sure there is at least one output file.
   if (build.Outputs.empty()) {
-    cmSystemTools::Error(
-      "No output files for WriteBuild! called with comment: " + build.Comment);
+    cmSystemTools::Error(cmStrCat(
+      "No output files for WriteBuild! called with comment: ", build.Comment));
     return;
   }
 
@@ -166,7 +166,7 @@
   {
     // Write explicit outputs
     for (std::string const& output : build.Outputs) {
-      buildStr += " " + EncodePath(output);
+      buildStr += cmStrCat(' ', EncodePath(output));
       if (this->ComputingUnknownDependencies) {
         this->CombinedBuildOutputs.insert(output);
       }
@@ -175,14 +175,13 @@
     if (!build.ImplicitOuts.empty()) {
       buildStr += " |";
       for (std::string const& implicitOut : build.ImplicitOuts) {
-        buildStr += " " + EncodePath(implicitOut);
+        buildStr += cmStrCat(' ', EncodePath(implicitOut));
       }
     }
-    buildStr += ":";
+    buildStr += ':';
 
     // Write the rule.
-    buildStr += " ";
-    buildStr += build.Rule;
+    buildStr += cmStrCat(' ', build.Rule);
   }
 
   std::string arguments;
@@ -191,14 +190,14 @@
 
     // Write explicit dependencies.
     for (std::string const& explicitDep : build.ExplicitDeps) {
-      arguments += " " + EncodePath(explicitDep);
+      arguments += cmStrCat(' ', EncodePath(explicitDep));
     }
 
     // Write implicit dependencies.
     if (!build.ImplicitDeps.empty()) {
       arguments += " |";
       for (std::string const& implicitDep : build.ImplicitDeps) {
-        arguments += " " + EncodePath(implicitDep);
+        arguments += cmStrCat(' ', EncodePath(implicitDep));
       }
     }
 
@@ -206,11 +205,11 @@
     if (!build.OrderOnlyDeps.empty()) {
       arguments += " ||";
       for (std::string const& orderOnlyDep : build.OrderOnlyDeps) {
-        arguments += " " + EncodePath(orderOnlyDep);
+        arguments += cmStrCat(' ', EncodePath(orderOnlyDep));
       }
     }
 
-    arguments += "\n";
+    arguments += '\n';
   }
 
   // Write the variables bound to this build statement.
@@ -309,7 +308,7 @@
 void cmGlobalNinjaGenerator::AddMacOSXContentRule()
 {
   cmNinjaRule rule("COPY_OSX_CONTENT");
-  rule.Command = CMakeCmd() + " -E copy $in $out";
+  rule.Command = cmStrCat(CMakeCmd(), " -E copy $in $out");
   rule.Description = "Copying OS X Content $out";
   rule.Comment = "Rule for copying OS X bundle content file.";
   this->AddRule(rule);
@@ -334,23 +333,24 @@
   // -- Parameter checks
   // Make sure the rule has a name.
   if (rule.Name.empty()) {
-    cmSystemTools::Error("No name given for WriteRule! called with comment: " +
-                         rule.Comment);
+    cmSystemTools::Error(cmStrCat(
+      "No name given for WriteRule! called with comment: ", rule.Comment));
     return;
   }
 
   // Make sure a command is given.
   if (rule.Command.empty()) {
-    cmSystemTools::Error(
-      "No command given for WriteRule! called with comment: " + rule.Comment);
+    cmSystemTools::Error(cmStrCat(
+      "No command given for WriteRule! called with comment: ", rule.Comment));
     return;
   }
 
   // Make sure response file content is given
   if (!rule.RspFile.empty() && rule.RspContent.empty()) {
-    cmSystemTools::Error("rspfile but no rspfile_content given for WriteRule! "
-                         "called with comment: " +
-                         rule.Comment);
+    cmSystemTools::Error(
+      cmStrCat("rspfile but no rspfile_content given for WriteRule! "
+               "called with comment: ",
+               rule.Comment));
     return;
   }
 
@@ -392,9 +392,9 @@
 {
   // Make sure we have a name.
   if (name.empty()) {
-    cmSystemTools::Error("No name given for WriteVariable! called "
-                         "with comment: " +
-                         comment);
+    cmSystemTools::Error(cmStrCat("No name given for WriteVariable! called "
+                                  "with comment: ",
+                                  comment));
     return;
   }
 
@@ -435,8 +435,6 @@
 #ifdef _WIN32
   cm->GetState()->SetWindowsShell(true);
 #endif
-  // // Ninja is not ported to non-Unix OS yet.
-  // this->ForceUnixPaths = true;
   this->FindMakeProgramFile = "CMakeNinjaFindMake.cmake";
 }
 
@@ -520,7 +518,8 @@
 
   if (cmSystemTools::GetErrorOccuredFlag()) {
     this->RulesFileStream->setstate(std::ios::failbit);
-    for (auto const& config : this->Makefiles[0]->GetGeneratorConfigs()) {
+    for (auto const& config : this->Makefiles[0]->GetGeneratorConfigs(
+           cmMakefile::IncludeEmptyConfig)) {
       this->GetImplFileStream(config)->setstate(std::ios::failbit);
       this->GetConfigFileStream(config)->setstate(std::ios::failbit);
     }
@@ -558,11 +557,11 @@
                                          nullptr,
                                          cmSystemTools::OUTPUT_NONE)) {
       this->GetCMakeInstance()->IssueMessage(MessageType::FATAL_ERROR,
-                                             "Running\n '" +
-                                               cmJoin(command, "' '") +
-                                               "'\n"
-                                               "failed with:\n " +
-                                               error);
+                                             cmStrCat("Running\n '",
+                                                      cmJoin(command, "' '"),
+                                                      "'\n"
+                                                      "failed with:\n ",
+                                                      error));
       cmSystemTools::SetFatalErrorOccured();
     }
   };
@@ -626,10 +625,10 @@
                                          nullptr,
                                          cmSystemTools::OUTPUT_NONE)) {
       mf->IssueMessage(MessageType::FATAL_ERROR,
-                       "Running\n '" + cmJoin(command, "' '") +
-                         "'\n"
-                         "failed with:\n " +
-                         error);
+                       cmStrCat("Running\n '", cmJoin(command, "' '"),
+                                "'\n"
+                                "failed with:\n ",
+                                error));
       cmSystemTools::SetFatalErrorOccured();
       return false;
     }
@@ -686,10 +685,10 @@
 bool cmGlobalNinjaGenerator::CheckLanguages(
   std::vector<std::string> const& languages, cmMakefile* mf) const
 {
-  if (cmContains(languages, "Fortran")) {
+  if (cm::contains(languages, "Fortran")) {
     return this->CheckFortran(mf);
   }
-  if (cmContains(languages, "Swift")) {
+  if (cm::contains(languages, "Swift")) {
     const std::string architectures =
       mf->GetSafeDefinition("CMAKE_OSX_ARCHITECTURES");
     if (architectures.find_first_of(';') != std::string::npos) {
@@ -713,7 +712,7 @@
   /* clang-format off */
   e <<
     "The Ninja generator does not support Fortran using Ninja version\n"
-    "  " + this->NinjaVersion + "\n"
+    "  " << this->NinjaVersion << "\n"
     "due to lack of required features.  Ninja 1.10 or higher is required."
     ;
   /* clang-format on */
@@ -991,7 +990,8 @@
   std::string buildFileDir =
     this->GetCMakeInstance()->GetHomeOutputDirectory();
   if (!this->CompileCommandsStream) {
-    std::string buildFilePath = buildFileDir + "/compile_commands.json";
+    std::string buildFilePath =
+      cmStrCat(buildFileDir, "/compile_commands.json");
     if (this->ComputingUnknownDependencies) {
       this->CombinedBuildOutputs.insert(
         this->NinjaOutputPath("compile_commands.json"));
@@ -1000,9 +1000,9 @@
     // Get a stream where to generate things.
     this->CompileCommandsStream =
       cm::make_unique<cmGeneratedFileStream>(buildFilePath);
-    *this->CompileCommandsStream << "[";
+    *this->CompileCommandsStream << "[\n";
   } else {
-    *this->CompileCommandsStream << "," << std::endl;
+    *this->CompileCommandsStream << ",\n";
   }
 
   std::string sourceFileName = sourceFile;
@@ -1012,7 +1012,7 @@
   }
 
   /* clang-format off */
-  *this->CompileCommandsStream << "\n{\n"
+  *this->CompileCommandsStream << "{\n"
      << R"(  "directory": ")"
      << cmGlobalGenerator::EscapeJSON(buildFileDir) << "\",\n"
      << R"(  "command": ")"
@@ -1093,10 +1093,11 @@
     }
     // FALLTHROUGH
     case cmStateEnums::GLOBAL_TARGET:
+    case cmStateEnums::INTERFACE_LIBRARY:
     case cmStateEnums::UTILITY: {
       std::string path =
-        target->GetLocalGenerator()->GetCurrentBinaryDirectory() +
-        std::string("/") + target->GetName();
+        cmStrCat(target->GetLocalGenerator()->GetCurrentBinaryDirectory(), '/',
+                 target->GetName());
       std::string output = this->ConvertToNinjaPath(path);
       if (target->Target->IsPerConfig()) {
         output = this->BuildAlias(output, config);
@@ -1105,8 +1106,8 @@
       break;
     }
 
-    default:
-      return;
+    case cmStateEnums::UNKNOWN_LIBRARY:
+      break;
   }
 }
 
@@ -1120,15 +1121,15 @@
     for (BT<std::pair<std::string, bool>> const& util :
          target->GetUtilities()) {
       std::string d =
-        target->GetLocalGenerator()->GetCurrentBinaryDirectory() + "/" +
-        util.Value.first;
+        cmStrCat(target->GetLocalGenerator()->GetCurrentBinaryDirectory(), '/',
+                 util.Value.first);
       outputs.push_back(this->BuildAlias(this->ConvertToNinjaPath(d), config));
     }
   } else {
     cmNinjaDeps outs;
     for (cmTargetDepend const& targetDep :
          this->GetTargetDirectDepends(target)) {
-      if (targetDep->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
+      if (!targetDep->IsInBuildSystem()) {
         continue;
       }
       if (targetDep.IsCross()) {
@@ -1170,7 +1171,7 @@
     cmNinjaOuts this_outs; // this will be the new cache entry
 
     for (auto const& dep_target : this->GetTargetDirectDepends(target)) {
-      if (dep_target->GetType() == cmStateEnums::INTERFACE_LIBRARY ||
+      if (!dep_target->IsInBuildSystem() ||
           (this->EnableCrossConfigBuild() && !dep_target.IsCross())) {
         continue;
       }
@@ -1189,7 +1190,7 @@
   // finally generate the outputs of the target itself, if applicable
   cmNinjaDeps outs;
   if (!omit_self) {
-    this->AppendTargetOutputs(target, outs, config);
+    this->AppendTargetOutputs(target, outs, config, DependOnTargetArtifact);
   }
   outputs.insert(outs.begin(), outs.end());
 }
@@ -1201,14 +1202,15 @@
   std::string outputPath = this->NinjaOutputPath(alias);
   std::string buildAlias = this->BuildAlias(outputPath, config);
   cmNinjaDeps outputs;
-  this->AppendTargetOutputs(target, outputs, config);
+  this->AppendTargetOutputs(target, outputs, config, DependOnTargetArtifact);
   // Mark the target's outputs as ambiguous to ensure that no other target
   // uses the output as an alias.
   for (std::string const& output : outputs) {
     this->TargetAliases[output].GeneratorTarget = nullptr;
     this->DefaultTargetAliases[output].GeneratorTarget = nullptr;
     for (const std::string& config2 :
-         this->Makefiles.front()->GetGeneratorConfigs()) {
+         this->Makefiles.front()->GetGeneratorConfigs(
+           cmMakefile::IncludeEmptyConfig)) {
       this->Configs[config2].TargetAliases[output].GeneratorTarget = nullptr;
     }
   }
@@ -1266,11 +1268,12 @@
     if (ta.second.Config == "all") {
       for (auto const& config : this->CrossConfigs) {
         this->AppendTargetOutputs(ta.second.GeneratorTarget,
-                                  build.ExplicitDeps, config);
+                                  build.ExplicitDeps, config,
+                                  DependOnTargetArtifact);
       }
     } else {
       this->AppendTargetOutputs(ta.second.GeneratorTarget, build.ExplicitDeps,
-                                ta.second.Config);
+                                ta.second.Config, DependOnTargetArtifact);
     }
     this->WriteBuild(this->EnableCrossConfigBuild() &&
                          (ta.second.Config == "all" ||
@@ -1281,7 +1284,8 @@
   }
 
   if (this->IsMultiConfig()) {
-    for (auto const& config : this->Makefiles.front()->GetGeneratorConfigs()) {
+    for (auto const& config : this->Makefiles.front()->GetGeneratorConfigs(
+           cmMakefile::IncludeEmptyConfig)) {
       for (auto const& ta : this->Configs[config].TargetAliases) {
         // Don't write ambiguous aliases.
         if (!ta.second.GeneratorTarget) {
@@ -1297,7 +1301,8 @@
         build.Outputs.front() = ta.first;
         build.ExplicitDeps.clear();
         this->AppendTargetOutputs(ta.second.GeneratorTarget,
-                                  build.ExplicitDeps, config);
+                                  build.ExplicitDeps, config,
+                                  DependOnTargetArtifact);
         this->WriteBuild(*this->GetConfigFileStream(config), build);
       }
     }
@@ -1319,7 +1324,8 @@
         build.ExplicitDeps.clear();
         for (auto const& config : this->DefaultConfigs) {
           this->AppendTargetOutputs(ta.second.GeneratorTarget,
-                                    build.ExplicitDeps, config);
+                                    build.ExplicitDeps, config,
+                                    DependOnTargetArtifact);
         }
         this->WriteBuild(*this->GetDefaultFileStream(), build);
       }
@@ -1340,30 +1346,30 @@
     cmGlobalNinjaGenerator::WriteDivider(os);
     std::string const& currentBinaryDir = it.first;
     DirectoryTarget const& dt = it.second;
-    std::vector<std::string> configs;
-    dt.LG->GetMakefile()->GetConfigurations(configs, true);
-    if (configs.empty()) {
-      configs.emplace_back();
-    }
+    std::vector<std::string> configs =
+      dt.LG->GetMakefile()->GetGeneratorConfigs(
+        cmMakefile::IncludeEmptyConfig);
 
     // Setup target
     cmNinjaDeps configDeps;
-    build.Comment = "Folder: " + currentBinaryDir;
+    build.Comment = cmStrCat("Folder: ", currentBinaryDir);
     build.Outputs.emplace_back();
+    std::string const buildDirAllTarget =
+      this->ConvertToNinjaPath(cmStrCat(currentBinaryDir, "/all"));
     for (auto const& config : configs) {
       build.ExplicitDeps.clear();
-      build.Outputs.front() = this->BuildAlias(
-        this->ConvertToNinjaPath(currentBinaryDir + "/all"), config);
+      build.Outputs.front() = this->BuildAlias(buildDirAllTarget, config);
       configDeps.emplace_back(build.Outputs.front());
       for (DirectoryTarget::Target const& t : dt.Targets) {
-        if (!t.ExcludeFromAll) {
-          this->AppendTargetOutputs(t.GT, build.ExplicitDeps, config);
+        if (!IsExcludedFromAllInConfig(t, config)) {
+          this->AppendTargetOutputs(t.GT, build.ExplicitDeps, config,
+                                    DependOnTargetArtifact);
         }
       }
       for (DirectoryTarget::Dir const& d : dt.Children) {
         if (!d.ExcludeFromAll) {
           build.ExplicitDeps.emplace_back(this->BuildAlias(
-            this->ConvertToNinjaPath(d.Path + "/all"), config));
+            this->ConvertToNinjaPath(cmStrCat(d.Path, "/all")), config));
         }
       }
       // Write target
@@ -1377,21 +1383,18 @@
     // Add shortcut target
     if (this->IsMultiConfig()) {
       for (auto const& config : configs) {
-        build.ExplicitDeps = { this->BuildAlias(
-          this->ConvertToNinjaPath(currentBinaryDir + "/all"), config) };
-        build.Outputs.front() =
-          this->ConvertToNinjaPath(currentBinaryDir + "/all");
+        build.ExplicitDeps = { this->BuildAlias(buildDirAllTarget, config) };
+        build.Outputs.front() = buildDirAllTarget;
         this->WriteBuild(*this->GetConfigFileStream(config), build);
       }
 
       if (!this->DefaultFileConfig.empty()) {
         build.ExplicitDeps.clear();
         for (auto const& config : this->DefaultConfigs) {
-          build.ExplicitDeps.push_back(this->BuildAlias(
-            this->ConvertToNinjaPath(currentBinaryDir + "/all"), config));
+          build.ExplicitDeps.push_back(
+            this->BuildAlias(buildDirAllTarget, config));
         }
-        build.Outputs.front() =
-          this->ConvertToNinjaPath(currentBinaryDir + "/all");
+        build.Outputs.front() = buildDirAllTarget;
         this->WriteBuild(*this->GetDefaultFileStream(), build);
       }
     }
@@ -1400,11 +1403,10 @@
     if (this->EnableCrossConfigBuild()) {
       build.ExplicitDeps.clear();
       for (auto const& config : this->CrossConfigs) {
-        build.ExplicitDeps.push_back(this->BuildAlias(
-          this->ConvertToNinjaPath(currentBinaryDir + "/all"), config));
+        build.ExplicitDeps.push_back(
+          this->BuildAlias(buildDirAllTarget, config));
       }
-      build.Outputs.front() = this->BuildAlias(
-        this->ConvertToNinjaPath(currentBinaryDir + "/all"), "all");
+      build.Outputs.front() = this->BuildAlias(buildDirAllTarget, "all");
       this->WriteBuild(os, build);
     }
   }
@@ -1542,7 +1544,8 @@
   this->WriteTargetClean(os);
   this->WriteTargetHelp(os);
 
-  for (auto const& config : this->Makefiles[0]->GetGeneratorConfigs()) {
+  for (auto const& config : this->Makefiles[0]->GetGeneratorConfigs(
+         cmMakefile::IncludeEmptyConfig)) {
     this->WriteTargetDefault(*this->GetConfigFileStream(config));
   }
 
@@ -1616,7 +1619,8 @@
 
     cmNinjaBuild phonyBuild("phony");
     phonyBuild.Comment = "Phony target to force glob verification run.";
-    phonyBuild.Outputs.push_back(cm->GetGlobVerifyScript() + "_force");
+    phonyBuild.Outputs.push_back(
+      cmStrCat(cm->GetGlobVerifyScript(), "_force"));
     this->WriteBuild(os, phonyBuild);
 
     reBuild.Variables["restat"] = "1";
@@ -1715,11 +1719,8 @@
   std::string cleanScriptRel = "CMakeFiles/clean_additional.cmake";
   std::string cleanScriptAbs =
     cmStrCat(lgr->GetBinaryDirectory(), '/', cleanScriptRel);
-  std::vector<std::string> configs;
-  this->Makefiles[0]->GetConfigurations(configs, true);
-  if (configs.empty()) {
-    configs.emplace_back();
-  }
+  std::vector<std::string> configs =
+    this->Makefiles[0]->GetGeneratorConfigs(cmMakefile::IncludeEmptyConfig);
 
   // Check if there are additional files to clean
   bool empty = true;
@@ -1807,13 +1808,14 @@
   // Write rule
   {
     cmNinjaRule rule("CLEAN");
-    rule.Command = NinjaCmd() + " $FILE_ARG -t clean $TARGETS";
+    rule.Command = cmStrCat(NinjaCmd(), " $FILE_ARG -t clean $TARGETS");
     rule.Description = "Cleaning all built files...";
     rule.Comment = "Rule for cleaning all built files.";
     WriteRule(*this->RulesFileStream, rule);
   }
 
-  auto const configs = this->Makefiles.front()->GetGeneratorConfigs();
+  auto const configs = this->Makefiles.front()->GetGeneratorConfigs(
+    cmMakefile::IncludeEmptyConfig);
 
   // Write build
   {
@@ -1921,7 +1923,7 @@
 {
   {
     cmNinjaRule rule("HELP");
-    rule.Command = NinjaCmd() + " -t targets";
+    rule.Command = cmStrCat(NinjaCmd(), " -t targets");
     rule.Description = "All primary targets available:";
     rule.Comment = "Rule for printing all primary targets available.";
     WriteRule(*this->RulesFileStream, rule);
@@ -1948,7 +1950,7 @@
   if (!this->HasOutputPathPrefix() || cmSystemTools::FileIsFullPath(path)) {
     return path;
   }
-  return this->OutputPathPrefix + path;
+  return cmStrCat(this->OutputPathPrefix, path);
 }
 
 void cmGlobalNinjaGenerator::StripNinjaOutputPathPrefixAsSuffix(
@@ -2076,7 +2078,8 @@
     } else if (cmHasLiteralPrefix(arg, "--lang=")) {
       arg_lang = arg.substr(7);
     } else {
-      cmSystemTools::Error("-E cmake_ninja_depends unknown argument: " + arg);
+      cmSystemTools::Error(
+        cmStrCat("-E cmake_ninja_depends unknown argument: ", arg));
       return 1;
     }
   }
@@ -2147,7 +2150,8 @@
   cmGeneratedFileStream ddif(arg_ddi);
   ddif << ddi;
   if (!ddif) {
-    cmSystemTools::Error("-E cmake_ninja_depends failed to write " + arg_ddi);
+    cmSystemTools::Error(
+      cmStrCat("-E cmake_ninja_depends failed to write ", arg_ddi));
     return 1;
   }
   return 0;
@@ -2193,7 +2197,8 @@
   std::set<std::string> defines;
   cmFortranParser parser(fc, includes, defines, finfo);
   if (!cmFortranParser_FilePush(&parser, arg_pp.c_str())) {
-    cmSystemTools::Error("-E cmake_ninja_depends failed to open " + arg_pp);
+    cmSystemTools::Error(
+      cmStrCat("-E cmake_ninja_depends failed to open ", arg_pp));
     return nullptr;
   }
   if (cmFortran_yyparse(parser.Scanner) != 0) {
@@ -2296,7 +2301,7 @@
   Json::Value tm = Json::objectValue;
   for (cmDyndepObjectInfo const& object : objects) {
     for (std::string const& p : object.Provides) {
-      std::string const mod = module_dir + p;
+      std::string const mod = cmStrCat(module_dir, p);
       mod_files[p] = mod;
       tm[p] = mod;
     }
@@ -2332,8 +2337,8 @@
 
   // Store the map of modules provided by this target in a file for
   // use by dependents that reference this target in linked-target-dirs.
-  std::string const target_mods_file =
-    cmSystemTools::GetFilenamePath(arg_dd) + "/" + arg_lang + "Modules.json";
+  std::string const target_mods_file = cmStrCat(
+    cmSystemTools::GetFilenamePath(arg_dd), '/', arg_lang, "Modules.json");
   cmGeneratedFileStream tmf(target_mods_file);
   tmf << tm;
 
@@ -2366,7 +2371,8 @@
                cmHasLiteralSuffix(arg, ".ddi")) {
       arg_ddis.push_back(arg);
     } else {
-      cmSystemTools::Error("-E cmake_ninja_dyndep unknown argument: " + arg);
+      cmSystemTools::Error(
+        cmStrCat("-E cmake_ninja_dyndep unknown argument: ", arg));
       return 1;
     }
   }
@@ -2402,7 +2408,7 @@
   std::string const dir_top_src = tdi["dir-top-src"].asString();
   std::string module_dir = tdi["module-dir"].asString();
   if (!module_dir.empty() && !cmHasLiteralSuffix(module_dir, "/")) {
-    module_dir += "/";
+    module_dir += '/';
   }
   std::vector<std::string> linked_target_dirs;
   Json::Value const& tdi_linked_target_dirs = tdi["linked-target-dirs"];
@@ -2430,9 +2436,7 @@
   const std::string& suffix, std::string& dir)
 {
   if (!config.empty() && this->IsMultiConfig()) {
-    dir += prefix;
-    dir += config;
-    dir += suffix;
+    dir += cmStrCat(prefix, config, suffix);
   }
 }
 
@@ -2490,7 +2494,8 @@
     << "# This file contains build statements common to all "
        "configurations.\n\n";
 
-  for (auto const& config : this->Makefiles[0]->GetGeneratorConfigs()) {
+  for (auto const& config : this->Makefiles[0]->GetGeneratorConfigs(
+         cmMakefile::IncludeEmptyConfig)) {
     // Open impl file.
     if (!this->OpenFileStream(this->ImplFileStreams[config],
                               GetNinjaImplFilename(config))) {
@@ -2530,7 +2535,8 @@
     this->DefaultFileStream.reset();
   } // No error if it wasn't open
 
-  for (auto const& config : this->Makefiles[0]->GetGeneratorConfigs()) {
+  for (auto const& config : this->Makefiles[0]->GetGeneratorConfigs(
+         cmMakefile::IncludeEmptyConfig)) {
     if (this->ImplFileStreams[config]) {
       this->ImplFileStreams[config].reset();
     } else {
@@ -2572,7 +2578,8 @@
 void cmGlobalNinjaMultiGenerator::AddRebuildManifestOutputs(
   cmNinjaDeps& outputs) const
 {
-  for (auto const& config : this->Makefiles.front()->GetGeneratorConfigs()) {
+  for (auto const& config : this->Makefiles.front()->GetGeneratorConfigs(
+         cmMakefile::IncludeEmptyConfig)) {
     outputs.push_back(this->NinjaOutputPath(GetNinjaImplFilename(config)));
     outputs.push_back(this->NinjaOutputPath(GetNinjaConfigFilename(config)));
   }
@@ -2584,11 +2591,9 @@
 void cmGlobalNinjaMultiGenerator::GetQtAutoGenConfigs(
   std::vector<std::string>& configs) const
 {
-  auto const oldSize = configs.size();
-  this->Makefiles.front()->GetConfigurations(configs);
-  if (configs.size() == oldSize) {
-    configs.emplace_back();
-  }
+  auto allConfigs =
+    this->Makefiles[0]->GetGeneratorConfigs(cmMakefile::IncludeEmptyConfig);
+  configs.insert(configs.end(), cm::cbegin(allConfigs), cm::cend(allConfigs));
 }
 
 bool cmGlobalNinjaMultiGenerator::InspectConfigTypeVariables()
diff --git a/Source/cmGlobalNinjaGenerator.h b/Source/cmGlobalNinjaGenerator.h
index 44e632f..10f5cf6 100644
--- a/Source/cmGlobalNinjaGenerator.h
+++ b/Source/cmGlobalNinjaGenerator.h
@@ -318,14 +318,13 @@
   virtual std::string OrderDependsTargetForTarget(
     cmGeneratorTarget const* target, const std::string& config) const;
 
-  void AppendTargetOutputs(
-    cmGeneratorTarget const* target, cmNinjaDeps& outputs,
-    const std::string& config,
-    cmNinjaTargetDepends depends = DependOnTargetArtifact);
-  void AppendTargetDepends(
-    cmGeneratorTarget const* target, cmNinjaDeps& outputs,
-    const std::string& config, const std::string& fileConfig,
-    cmNinjaTargetDepends depends = DependOnTargetArtifact);
+  void AppendTargetOutputs(cmGeneratorTarget const* target,
+                           cmNinjaDeps& outputs, const std::string& config,
+                           cmNinjaTargetDepends depends);
+  void AppendTargetDepends(cmGeneratorTarget const* target,
+                           cmNinjaDeps& outputs, const std::string& config,
+                           const std::string& fileConfig,
+                           cmNinjaTargetDepends depends);
   void AppendTargetDependsClosure(cmGeneratorTarget const* target,
                                   cmNinjaDeps& outputs,
                                   const std::string& config);
diff --git a/Source/cmGlobalUnixMakefileGenerator3.cxx b/Source/cmGlobalUnixMakefileGenerator3.cxx
index 90c9ef0..37a77fa 100644
--- a/Source/cmGlobalUnixMakefileGenerator3.cxx
+++ b/Source/cmGlobalUnixMakefileGenerator3.cxx
@@ -20,6 +20,7 @@
 #include "cmMakefile.h"
 #include "cmMakefileTargetGenerator.h"
 #include "cmOutputConverter.h"
+#include "cmProperty.h"
 #include "cmState.h"
 #include "cmStateDirectory.h"
 #include "cmStateTypes.h"
@@ -41,7 +42,6 @@
 #else
   this->UseLinkScript = true;
 #endif
-  this->CommandDatabase = nullptr;
 
   this->IncludeDirective = "include";
   this->DefineWindowsNULL = false;
@@ -49,6 +49,8 @@
   this->UnixCD = true;
 }
 
+cmGlobalUnixMakefileGenerator3::~cmGlobalUnixMakefileGenerator3() = default;
+
 void cmGlobalUnixMakefileGenerator3::EnableLanguage(
   std::vector<std::string> const& languages, cmMakefile* mf, bool optional)
 {
@@ -116,6 +118,12 @@
   gt->ObjectDirectory = dir;
 }
 
+bool cmGlobalUnixMakefileGenerator3::CanEscapeOctothorpe() const
+{
+  // Make tools that use UNIX-style '/' paths also support '\' escaping.
+  return this->ForceUnixPaths;
+}
+
 void cmGlobalUnixMakefileGenerator3::Configure()
 {
   // Initialize CMAKE_EDIT_COMMAND cache entry.
@@ -135,7 +143,7 @@
     total += pmi.second.NumberOfActions;
   }
 
-  // write each target's progress.make this loop is done twice. Bascially the
+  // write each target's progress.make this loop is done twice. Basically the
   // Generate pass counts all the actions, the first loop below determines
   // how many actions have progress updates for each target and writes to
   // corrrect variable values for everything except the all targets. The
@@ -157,10 +165,9 @@
   this->WriteMainMakefile2();
   this->WriteMainCMakefile();
 
-  if (this->CommandDatabase != nullptr) {
-    *this->CommandDatabase << std::endl << "]";
-    delete this->CommandDatabase;
-    this->CommandDatabase = nullptr;
+  if (this->CommandDatabase) {
+    *this->CommandDatabase << "\n]";
+    this->CommandDatabase.reset();
   }
 }
 
@@ -168,26 +175,26 @@
   const std::string& sourceFile, const std::string& workingDirectory,
   const std::string& compileCommand)
 {
-  if (this->CommandDatabase == nullptr) {
+  if (!this->CommandDatabase) {
     std::string commandDatabaseName =
       this->GetCMakeInstance()->GetHomeOutputDirectory() +
       "/compile_commands.json";
-    this->CommandDatabase = new cmGeneratedFileStream(commandDatabaseName);
-    *this->CommandDatabase << "[" << std::endl;
+    this->CommandDatabase =
+      cm::make_unique<cmGeneratedFileStream>(commandDatabaseName);
+    *this->CommandDatabase << "[\n";
   } else {
-    *this->CommandDatabase << "," << std::endl;
+    *this->CommandDatabase << ",\n";
   }
-  *this->CommandDatabase << "{" << std::endl
+  *this->CommandDatabase << "{\n"
                          << R"(  "directory": ")"
                          << cmGlobalGenerator::EscapeJSON(workingDirectory)
-                         << "\"," << std::endl
+                         << "\",\n"
                          << R"(  "command": ")"
                          << cmGlobalGenerator::EscapeJSON(compileCommand)
-                         << "\"," << std::endl
+                         << "\",\n"
                          << R"(  "file": ")"
-                         << cmGlobalGenerator::EscapeJSON(sourceFile) << "\""
-                         << std::endl
-                         << "}";
+                         << cmGlobalGenerator::EscapeJSON(sourceFile)
+                         << "\"\n}";
 }
 
 void cmGlobalUnixMakefileGenerator3::WriteMainMakefile2()
@@ -343,19 +350,18 @@
     const std::string& binDir = lg.GetBinaryDirectory();
 
     // CMake must rerun if a byproduct is missing.
-    {
-      cmakefileStream << "# Byproducts of CMake generate step:\n"
-                      << "set(CMAKE_MAKEFILE_PRODUCTS\n";
-      for (std::string const& outfile : lg.GetMakefile()->GetOutputFiles()) {
+    cmakefileStream << "# Byproducts of CMake generate step:\n"
+                    << "set(CMAKE_MAKEFILE_PRODUCTS\n";
+
+    // add in any byproducts and all the directory information files
+    std::string tmpStr;
+    for (const auto& localGen : this->LocalGenerators) {
+      for (std::string const& outfile :
+           localGen->GetMakefile()->GetOutputFiles()) {
         cmakefileStream << "  \""
                         << lg.MaybeConvertToRelativePath(binDir, outfile)
                         << "\"\n";
       }
-    }
-
-    // add in all the directory information files
-    std::string tmpStr;
-    for (const auto& localGen : this->LocalGenerators) {
       tmpStr = cmStrCat(localGen->GetCurrentBinaryDirectory(),
                         "/CMakeFiles/CMakeDirectoryInformation.cmake");
       cmakefileStream << "  \""
@@ -381,12 +387,8 @@
       cm::static_reference_cast<cmLocalUnixMakefileGenerator3>(lGenerator);
     // for all of out targets
     for (const auto& tgt : lg.GetGeneratorTargets()) {
-      if ((tgt->GetType() == cmStateEnums::EXECUTABLE) ||
-          (tgt->GetType() == cmStateEnums::STATIC_LIBRARY) ||
-          (tgt->GetType() == cmStateEnums::SHARED_LIBRARY) ||
-          (tgt->GetType() == cmStateEnums::MODULE_LIBRARY) ||
-          (tgt->GetType() == cmStateEnums::OBJECT_LIBRARY) ||
-          (tgt->GetType() == cmStateEnums::UTILITY)) {
+      if (tgt->IsInBuildSystem() &&
+          tgt->GetType() != cmStateEnums::GLOBAL_TARGET) {
         std::string tname = cmStrCat(lg.GetRelativeTargetDirectory(tgt.get()),
                                      "/DependInfo.cmake");
         cmSystemTools::ConvertToUnixSlashes(tname);
@@ -410,7 +412,7 @@
   std::vector<std::string> depends;
   for (DirectoryTarget::Target const& t : dt.Targets) {
     // Add this to the list of depends rules in this directory.
-    if ((!check_all || !t.ExcludeFromAll) &&
+    if ((!check_all || t.ExcludedFromAllInConfigs.empty()) &&
         (!check_relink ||
          t.GT->NeedRelinkBeforeInstall(lg->GetConfigName()))) {
       // The target may be from a different directory; use its local gen.
@@ -481,6 +483,78 @@
   }
 }
 
+namespace {
+std::string ConvertToMakefilePathForUnix(std::string const& path)
+{
+  std::string result;
+  result.reserve(path.size());
+  for (char c : path) {
+    switch (c) {
+      case '=':
+        // We provide 'EQUALS = =' to encode '=' in a non-assignment case.
+        result.append("$(EQUALS)");
+        break;
+      case '$':
+        result.append("$$");
+        break;
+      case '\\':
+      case ' ':
+      case '#':
+        result.push_back('\\');
+        CM_FALLTHROUGH;
+      default:
+        result.push_back(c);
+        break;
+    }
+  }
+  return result;
+}
+
+#if defined(_WIN32) && !defined(__CYGWIN__)
+std::string ConvertToMakefilePathForWindows(std::string const& path)
+{
+  bool const quote = path.find_first_of(" #") != std::string::npos;
+  std::string result;
+  result.reserve(path.size() + (quote ? 2 : 0));
+  if (quote) {
+    result.push_back('"');
+  }
+  for (char c : path) {
+    switch (c) {
+      case '=':
+        // We provide 'EQUALS = =' to encode '=' in a non-assignment case.
+        result.append("$(EQUALS)");
+        break;
+      case '$':
+        result.append("$$");
+        break;
+      case '/':
+        result.push_back('\\');
+        break;
+      default:
+        result.push_back(c);
+        break;
+    }
+  }
+  if (quote) {
+    result.push_back('"');
+  }
+  return result;
+}
+#endif
+}
+
+std::string cmGlobalUnixMakefileGenerator3::ConvertToMakefilePath(
+  std::string const& path) const
+{
+#if defined(_WIN32) && !defined(__CYGWIN__)
+  if (!this->ForceUnixPaths) {
+    return ConvertToMakefilePathForWindows(path);
+  }
+#endif
+  return ConvertToMakefilePathForUnix(path);
+}
+
 std::vector<cmGlobalGenerator::GeneratedMakeCommand>
 cmGlobalUnixMakefileGenerator3::GenerateBuildCommand(
   const std::string& makeProgram, const std::string& /*projectName*/,
@@ -557,17 +631,12 @@
     for (const auto& gtarget : lg.GetGeneratorTargets()) {
       // Don't emit the same rule twice (e.g. two targets with the same
       // simple name)
-      int type = gtarget->GetType();
       std::string name = gtarget->GetName();
       if (!name.empty() && emitted.insert(name).second &&
           // Handle user targets here.  Global targets are handled in
           // the local generator on a per-directory basis.
-          ((type == cmStateEnums::EXECUTABLE) ||
-           (type == cmStateEnums::STATIC_LIBRARY) ||
-           (type == cmStateEnums::SHARED_LIBRARY) ||
-           (type == cmStateEnums::MODULE_LIBRARY) ||
-           (type == cmStateEnums::OBJECT_LIBRARY) ||
-           (type == cmStateEnums::UTILITY))) {
+          (gtarget->IsInBuildSystem() &&
+           gtarget->GetType() != cmStateEnums::GLOBAL_TARGET)) {
         // Add a rule to build the target by name.
         lg.WriteDivider(ruleFileStream);
         ruleFileStream << "# Target rules for targets named " << name
@@ -631,15 +700,10 @@
 
   // for each target Generate the rule files for each target.
   for (const auto& gtarget : lg.GetGeneratorTargets()) {
-    int type = gtarget->GetType();
     std::string name = gtarget->GetName();
     if (!name.empty() &&
-        ((type == cmStateEnums::EXECUTABLE) ||
-         (type == cmStateEnums::STATIC_LIBRARY) ||
-         (type == cmStateEnums::SHARED_LIBRARY) ||
-         (type == cmStateEnums::MODULE_LIBRARY) ||
-         (type == cmStateEnums::OBJECT_LIBRARY) ||
-         (type == cmStateEnums::UTILITY))) {
+        (gtarget->IsInBuildSystem() &&
+         gtarget->GetType() != cmStateEnums::GLOBAL_TARGET)) {
       std::string makefileName;
       // Add a rule to build the target by name.
       localName = lg.GetRelativeTargetDirectory(gtarget.get());
@@ -674,10 +738,10 @@
       }
 
       bool targetMessages = true;
-      if (const char* tgtMsg =
+      if (cmProp tgtMsg =
             this->GetCMakeInstance()->GetState()->GetGlobalProperty(
               "TARGET_MESSAGES")) {
-        targetMessages = cmIsOn(tgtMsg);
+        targetMessages = cmIsOn(*tgtMsg);
       }
 
       if (targetMessages) {
@@ -697,9 +761,8 @@
         std::ostringstream progCmd;
         progCmd << "$(CMAKE_COMMAND) -E cmake_progress_start ";
         // # in target
-        progCmd << lg.ConvertToOutputFormat(
-          cmSystemTools::CollapseFullPath(progress.Dir),
-          cmOutputConverter::SHELL);
+        progCmd << lg.ConvertToOutputFormat(progress.Dir,
+                                            cmOutputConverter::SHELL);
         //
         std::set<cmGeneratorTarget const*> emitted;
         progCmd << " "
@@ -711,9 +774,8 @@
       {
         std::ostringstream progCmd;
         progCmd << "$(CMAKE_COMMAND) -E cmake_progress_start "; // # 0
-        progCmd << lg.ConvertToOutputFormat(
-          cmSystemTools::CollapseFullPath(progress.Dir),
-          cmOutputConverter::SHELL);
+        progCmd << lg.ConvertToOutputFormat(progress.Dir,
+                                            cmOutputConverter::SHELL);
         progCmd << " 0";
         commands.push_back(progCmd.str());
       }
@@ -769,8 +831,7 @@
     for (const auto& gt : lg->GetGeneratorTargets()) {
       cmLocalGenerator* tlg = gt->GetLocalGenerator();
 
-      if (gt->GetType() == cmStateEnums::INTERFACE_LIBRARY ||
-          gt->GetPropertyAsBool("EXCLUDE_FROM_ALL")) {
+      if (!gt->IsInBuildSystem() || IsExcluded(lg.get(), gt.get())) {
         continue;
       }
 
@@ -805,7 +866,7 @@
   if (emitted.insert(target).second) {
     count = this->ProgressMap[target].Marks.size();
     for (cmTargetDepend const& depend : this->GetTargetDirectDepends(target)) {
-      if (depend->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
+      if (!depend->IsInBuildSystem()) {
         continue;
       }
       count += this->CountProgressMarksInTarget(depend, emitted);
@@ -862,7 +923,7 @@
   for (cmTargetDepend const& i : this->GetTargetDirectDepends(target)) {
     // Create the target-level dependency.
     cmGeneratorTarget const* dep = i;
-    if (dep->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
+    if (!dep->IsInBuildSystem()) {
       continue;
     }
     cmLocalUnixMakefileGenerator3* lg3 =
@@ -910,7 +971,9 @@
             (type == cmStateEnums::STATIC_LIBRARY) ||
             (type == cmStateEnums::SHARED_LIBRARY) ||
             (type == cmStateEnums::MODULE_LIBRARY) ||
-            (type == cmStateEnums::OBJECT_LIBRARY)) {
+            (type == cmStateEnums::OBJECT_LIBRARY) ||
+            (type == cmStateEnums::INTERFACE_LIBRARY &&
+             target->IsInBuildSystem())) {
           project_targets.insert(target->GetName());
         } else if (type == cmStateEnums::GLOBAL_TARGET) {
           globals_targets.insert(target->GetName());
diff --git a/Source/cmGlobalUnixMakefileGenerator3.h b/Source/cmGlobalUnixMakefileGenerator3.h
index 340a7ef..1caa4b7 100644
--- a/Source/cmGlobalUnixMakefileGenerator3.h
+++ b/Source/cmGlobalUnixMakefileGenerator3.h
@@ -68,6 +68,13 @@
       new cmGlobalGeneratorSimpleFactory<cmGlobalUnixMakefileGenerator3>());
   }
 
+  ~cmGlobalUnixMakefileGenerator3() override;
+
+  cmGlobalUnixMakefileGenerator3(const cmGlobalUnixMakefileGenerator3&) =
+    delete;
+  cmGlobalUnixMakefileGenerator3& operator=(
+    const cmGlobalUnixMakefileGenerator3&) = delete;
+
   //! Get the name for the generator.
   std::string GetName() const override
   {
@@ -129,6 +136,12 @@
       or dependencies.  */
   std::string GetEmptyRuleHackDepends() { return this->EmptyRuleHackDepends; }
 
+  /**
+   * Convert a file path to a Makefile target or dependency with
+   * escaping and quoting suitable for the generator's make tool.
+   */
+  std::string ConvertToMakefilePath(std::string const& path) const;
+
   // change the build command for speed
   std::vector<GeneratedMakeCommand> GenerateBuildCommand(
     const std::string& makeProgram, const std::string& projectName,
@@ -150,6 +163,9 @@
   /** Does the make tool tolerate .DELETE_ON_ERROR? */
   virtual bool AllowDeleteOnError() const { return true; }
 
+  /** Does the make tool interpret '\#' as '#'?  */
+  virtual bool CanEscapeOctothorpe() const;
+
   bool IsIPOSupported() const override { return true; }
 
   void ComputeTargetObjectDirectory(cmGeneratorTarget* gt) const override;
@@ -232,7 +248,7 @@
     std::set<cmGeneratorTarget const*>& emitted);
   size_t CountProgressMarksInAll(const cmLocalGenerator& lg);
 
-  cmGeneratedFileStream* CommandDatabase;
+  std::unique_ptr<cmGeneratedFileStream> CommandDatabase;
 
 private:
   const char* GetBuildIgnoreErrorsFlag() const override { return "-i"; }
diff --git a/Source/cmGlobalVisualStudio10Generator.cxx b/Source/cmGlobalVisualStudio10Generator.cxx
index ccb6c50..3805546 100644
--- a/Source/cmGlobalVisualStudio10Generator.cxx
+++ b/Source/cmGlobalVisualStudio10Generator.cxx
@@ -6,12 +6,12 @@
 
 #include <cm/memory>
 
+#include <cm3p/json/reader.h>
+
 #include "cmsys/FStream.hxx"
 #include "cmsys/Glob.hxx"
 #include "cmsys/RegularExpression.hxx"
 
-#include "cm_jsoncpp_reader.h"
-
 #include "cmAlgorithms.h"
 #include "cmDocumentationEntry.h"
 #include "cmGeneratorTarget.h"
@@ -19,6 +19,7 @@
 #include "cmMakefile.h"
 #include "cmMessageType.h"
 #include "cmSourceFile.h"
+#include "cmStringAlgorithms.h"
 #include "cmVersion.h"
 #include "cmVisualStudioSlnData.h"
 #include "cmVisualStudioSlnParser.h"
@@ -137,9 +138,6 @@
     "ProductDir",
     vc10Express, cmSystemTools::KeyWOW64_32);
   this->CudaEnabled = false;
-  this->SystemIsWindowsCE = false;
-  this->SystemIsWindowsPhone = false;
-  this->SystemIsWindowsStore = false;
   this->MSBuildCommandInitialized = false;
   {
     std::string envPlatformToolset;
@@ -313,7 +311,7 @@
       version.clear();
     }
 
-    if (version.find(this->GetPlatformToolsetString()) != 0) {
+    if (!cmHasPrefix(version, this->GetPlatformToolsetString())) {
       std::ostringstream e;
       /* clang-format off */
       e <<
@@ -510,18 +508,16 @@
       mf->IssueMessage(MessageType::FATAL_ERROR, e.str());
       return false;
     }
-    std::string v = this->GetInstalledNsightTegraVersion();
-    if (v.empty()) {
-      mf->IssueMessage(MessageType::FATAL_ERROR,
-                       "CMAKE_SYSTEM_NAME is 'Android' but "
-                       "'NVIDIA Nsight Tegra Visual Studio Edition' "
-                       "is not installed.");
-      return false;
+    if (mf->GetSafeDefinition("CMAKE_GENERATOR_PLATFORM") == "Tegra-Android") {
+      if (!this->InitializeTegraAndroid(mf)) {
+        return false;
+      }
+    } else {
+      this->SystemIsAndroid = true;
+      if (!this->InitializeAndroid(mf)) {
+        return false;
+      }
     }
-    this->DefaultPlatformName = "Tegra-Android";
-    this->DefaultPlatformToolset = "Default";
-    this->NsightTegraVersion = v;
-    mf->AddDefinition("CMAKE_VS_NsightTegra_VERSION", v);
   }
 
   return true;
@@ -563,6 +559,31 @@
   return false;
 }
 
+bool cmGlobalVisualStudio10Generator::InitializeTegraAndroid(cmMakefile* mf)
+{
+  std::string v = this->GetInstalledNsightTegraVersion();
+  if (v.empty()) {
+    mf->IssueMessage(MessageType::FATAL_ERROR,
+                     "CMAKE_SYSTEM_NAME is 'Android' but "
+                     "'NVIDIA Nsight Tegra Visual Studio Edition' "
+                     "is not installed.");
+    return false;
+  }
+  this->DefaultPlatformName = "Tegra-Android";
+  this->DefaultPlatformToolset = "Default";
+  this->NsightTegraVersion = v;
+  mf->AddDefinition("CMAKE_VS_NsightTegra_VERSION", v);
+  return true;
+}
+
+bool cmGlobalVisualStudio10Generator::InitializeAndroid(cmMakefile* mf)
+{
+  std::ostringstream e;
+  e << this->GetName() << " does not support Android.";
+  mf->IssueMessage(MessageType::FATAL_ERROR, e.str());
+  return false;
+}
+
 bool cmGlobalVisualStudio10Generator::SelectWindowsPhoneToolset(
   std::string& toolset) const
 {
@@ -597,6 +618,28 @@
 {
   this->LongestSource = LongestSourcePath();
   this->cmGlobalVisualStudio8Generator::Generate();
+  if (!this->AndroidExecutableWarnings.empty() &&
+      !this->CMakeInstance->GetIsInTryCompile()) {
+    std::ostringstream e;
+    /* clang-format off */
+    e <<
+      "You are using Visual Studio tools for Android, which does not support "
+      "standalone executables. However, the following executable targets do "
+      "not have the ANDROID_GUI property set, and thus will not be built as "
+      "expected. They will be built as shared libraries with executable "
+      "filenames:\n"
+      "  ";
+    /* clang-format on */
+    bool first = true;
+    for (auto const& name : this->AndroidExecutableWarnings) {
+      if (!first) {
+        e << ", ";
+      }
+      first = false;
+      e << name;
+    }
+    this->CMakeInstance->IssueMessage(MessageType::WARNING, e.str());
+  }
   if (this->LongestSource.Length > 0) {
     cmLocalGenerator* lg = this->LongestSource.Target->GetLocalGenerator();
     std::ostringstream e;
@@ -663,8 +706,14 @@
   if (!this->GeneratorToolset.empty()) {
     return this->GeneratorToolset;
   }
-  if (!this->DefaultPlatformToolset.empty()) {
-    return this->DefaultPlatformToolset;
+  if (this->SystemIsAndroid) {
+    if (!this->DefaultAndroidToolset.empty()) {
+      return this->DefaultAndroidToolset;
+    }
+  } else {
+    if (!this->DefaultPlatformToolset.empty()) {
+      return this->DefaultPlatformToolset;
+    }
   }
   static std::string const empty;
   return empty;
@@ -878,7 +927,10 @@
       epg.Attribute("Label", "Globals");
       cmXMLElement(epg, "ProjectGuid")
         .Content("{F3FC6D86-508D-3FB1-96D2-995F08B142EC}");
-      cmXMLElement(epg, "Keyword").Content("Win32Proj");
+      cmXMLElement(epg, "Keyword")
+        .Content(mf->GetSafeDefinition("CMAKE_SYSTEM_NAME") == "Android"
+                   ? "Android"
+                   : "Win32Proj");
       cmXMLElement(epg, "Platform").Content(this->GetPlatformName());
       if (this->GetSystemName() == "WindowsPhone") {
         cmXMLElement(epg, "ApplicationType").Content("Windows Phone");
@@ -888,15 +940,21 @@
         cmXMLElement(epg, "ApplicationType").Content("Windows Store");
         cmXMLElement(epg, "ApplicationTypeRevision")
           .Content(this->GetApplicationTypeRevision());
+      } else if (this->GetSystemName() == "Android") {
+        cmXMLElement(epg, "ApplicationType").Content("Android");
+        cmXMLElement(epg, "ApplicationTypeRevision")
+          .Content(this->GetApplicationTypeRevision());
       }
       if (!this->WindowsTargetPlatformVersion.empty()) {
         cmXMLElement(epg, "WindowsTargetPlatformVersion")
           .Content(this->WindowsTargetPlatformVersion);
       }
-      if (this->GetPlatformName() == "ARM64") {
-        cmXMLElement(epg, "WindowsSDKDesktopARM64Support").Content("true");
-      } else if (this->GetPlatformName() == "ARM") {
-        cmXMLElement(epg, "WindowsSDKDesktopARMSupport").Content("true");
+      if (this->GetSystemName() != "Android") {
+        if (this->GetPlatformName() == "ARM64") {
+          cmXMLElement(epg, "WindowsSDKDesktopARM64Support").Content("true");
+        } else if (this->GetPlatformName() == "ARM") {
+          cmXMLElement(epg, "WindowsSDKDesktopARMSupport").Content("true");
+        }
       }
     }
     cmXMLElement(eprj, "Import")
@@ -1208,6 +1266,10 @@
 
 std::string cmGlobalVisualStudio10Generator::GetApplicationTypeRevision() const
 {
+  if (this->GetSystemName() == "Android") {
+    return this->GetAndroidApplicationTypeRevision();
+  }
+
   // Return the first two '.'-separated components of the Windows version.
   std::string::size_type end1 = this->SystemVersion.find('.');
   std::string::size_type end2 =
diff --git a/Source/cmGlobalVisualStudio10Generator.h b/Source/cmGlobalVisualStudio10Generator.h
index f659ff3..0c53537 100644
--- a/Source/cmGlobalVisualStudio10Generator.h
+++ b/Source/cmGlobalVisualStudio10Generator.h
@@ -4,6 +4,7 @@
 #define cmGlobalVisualStudio10Generator_h
 
 #include <memory>
+#include <set>
 
 #include "cmGlobalVisualStudio8Generator.h"
 #include "cmVisualStudio10ToolsetOptions.h"
@@ -43,6 +44,11 @@
   void EnableLanguage(std::vector<std::string> const& languages, cmMakefile*,
                       bool optional) override;
 
+  void AddAndroidExecutableWarning(const std::string& name)
+  {
+    this->AndroidExecutableWarnings.insert(name);
+  }
+
   bool IsCudaEnabled() const { return this->CudaEnabled; }
 
   /** Generating for Nsight Tegra VS plugin?  */
@@ -100,6 +106,9 @@
   /** Return true if building for WindowsStore */
   bool TargetsWindowsStore() const { return this->SystemIsWindowsStore; }
 
+  /** Return true if building for Android */
+  bool TargetsAndroid() const { return this->SystemIsAndroid; }
+
   const char* GetCMakeCFGIntDir() const override { return "$(Configuration)"; }
   bool Find64BitTools(cmMakefile* mf);
 
@@ -121,11 +130,15 @@
 
   bool IsIPOSupported() const override { return true; }
 
+  virtual bool IsStdOutEncodingSupported() const { return false; }
+
   static std::string GetInstalledNsightTegraVersion();
 
   /** Return the first two components of CMAKE_SYSTEM_VERSION.  */
   std::string GetApplicationTypeRevision() const;
 
+  virtual const char* GetAndroidApplicationTypeRevision() const { return ""; }
+
   cmIDEFlagTable const* GetClFlagTable() const;
   cmIDEFlagTable const* GetCSharpFlagTable() const;
   cmIDEFlagTable const* GetRcFlagTable() const;
@@ -146,6 +159,8 @@
   virtual bool InitializeWindowsCE(cmMakefile* mf);
   virtual bool InitializeWindowsPhone(cmMakefile* mf);
   virtual bool InitializeWindowsStore(cmMakefile* mf);
+  virtual bool InitializeTegraAndroid(cmMakefile* mf);
+  virtual bool InitializeAndroid(cmMakefile* mf);
 
   virtual bool ProcessGeneratorToolsetField(std::string const& key,
                                             std::string const& value);
@@ -169,6 +184,7 @@
   std::string GeneratorToolsetCudaCustomDir;
   std::string DefaultPlatformToolset;
   std::string DefaultPlatformToolsetHostArchitecture;
+  std::string DefaultAndroidToolset;
   std::string WindowsTargetPlatformVersion;
   std::string SystemName;
   std::string SystemVersion;
@@ -183,9 +199,10 @@
   std::string DefaultNasmFlagTableName;
   std::string DefaultRCFlagTableName;
   bool SupportsUnityBuilds = false;
-  bool SystemIsWindowsCE;
-  bool SystemIsWindowsPhone;
-  bool SystemIsWindowsStore;
+  bool SystemIsWindowsCE = false;
+  bool SystemIsWindowsPhone = false;
+  bool SystemIsWindowsStore = false;
+  bool SystemIsAndroid = false;
 
 private:
   class Factory;
@@ -209,6 +226,7 @@
   std::string MSBuildCommand;
   bool MSBuildCommandInitialized;
   cmVisualStudio10ToolsetOptions ToolsetOptions;
+  std::set<std::string> AndroidExecutableWarnings;
   virtual std::string FindMSBuildCommand();
   std::string FindDevEnvCommand() override;
   std::string GetVSMakeProgram() override { return this->GetMSBuildCommand(); }
diff --git a/Source/cmGlobalVisualStudio14Generator.cxx b/Source/cmGlobalVisualStudio14Generator.cxx
index f549b6a..451d448 100644
--- a/Source/cmGlobalVisualStudio14Generator.cxx
+++ b/Source/cmGlobalVisualStudio14Generator.cxx
@@ -109,6 +109,7 @@
     "ProductDir",
     vc14Express, cmSystemTools::KeyWOW64_32);
   this->DefaultPlatformToolset = "v140";
+  this->DefaultAndroidToolset = "Clang_3_8";
   this->DefaultCLFlagTableName = "v140";
   this->DefaultCSharpFlagTableName = "v140";
   this->DefaultLibFlagTableName = "v14";
@@ -159,6 +160,11 @@
   return true;
 }
 
+bool cmGlobalVisualStudio14Generator::InitializeAndroid(cmMakefile*)
+{
+  return true;
+}
+
 bool cmGlobalVisualStudio14Generator::SelectWindows10SDK(cmMakefile* mf,
                                                          bool required)
 {
diff --git a/Source/cmGlobalVisualStudio14Generator.h b/Source/cmGlobalVisualStudio14Generator.h
index ccc2917..39353f2 100644
--- a/Source/cmGlobalVisualStudio14Generator.h
+++ b/Source/cmGlobalVisualStudio14Generator.h
@@ -23,12 +23,18 @@
 
   bool MatchesGeneratorName(const std::string& name) const override;
 
+  const char* GetAndroidApplicationTypeRevision() const override
+  {
+    return "2.0";
+  }
+
 protected:
   cmGlobalVisualStudio14Generator(cmake* cm, const std::string& name,
                                   std::string const& platformInGeneratorName);
 
   bool InitializeWindows(cmMakefile* mf) override;
   bool InitializeWindowsStore(cmMakefile* mf) override;
+  bool InitializeAndroid(cmMakefile* mf) override;
   bool SelectWindowsStoreToolset(std::string& toolset) const override;
 
   // These aren't virtual because we need to check if the selected version
diff --git a/Source/cmGlobalVisualStudio71Generator.cxx b/Source/cmGlobalVisualStudio71Generator.cxx
index d0aec61..0083c40 100644
--- a/Source/cmGlobalVisualStudio71Generator.cxx
+++ b/Source/cmGlobalVisualStudio71Generator.cxx
@@ -19,8 +19,8 @@
   std::ostream& fout, cmLocalGenerator* root,
   std::vector<cmLocalGenerator*>& generators)
 {
-  std::vector<std::string> configs;
-  root->GetMakefile()->GetConfigurations(configs);
+  std::vector<std::string> configs =
+    root->GetMakefile()->GetGeneratorConfigs(cmMakefile::ExcludeEmptyConfig);
 
   // Write out the header for a SLN file
   this->WriteSLNHeader(fout);
@@ -91,7 +91,7 @@
                                                    cmGeneratorTarget const* t)
 {
   // check to see if this is a fortran build
-  const char* ext = ".vcproj";
+  std::string ext = ".vcproj";
   const char* project =
     "Project(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \"";
   if (this->TargetIsFortranOnly(t)) {
@@ -102,9 +102,9 @@
     ext = ".csproj";
     project = "Project(\"{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}\") = \"";
   }
-  const char* targetExt = t->GetProperty("GENERATOR_FILE_NAME_EXT");
+  cmProp targetExt = t->GetProperty("GENERATOR_FILE_NAME_EXT");
   if (targetExt) {
-    ext = targetExt;
+    ext = *targetExt;
   }
 
   std::string guid = this->GetGUID(dspname);
@@ -198,9 +198,9 @@
     std::vector<std::string> mapConfig;
     const char* dstConfig = i.c_str();
     if (target.GetProperty("EXTERNAL_MSPROJECT")) {
-      if (const char* m = target.GetProperty("MAP_IMPORTED_CONFIG_" +
-                                             cmSystemTools::UpperCase(i))) {
-        cmExpandList(m, mapConfig);
+      if (cmProp m = target.GetProperty("MAP_IMPORTED_CONFIG_" +
+                                        cmSystemTools::UpperCase(i))) {
+        cmExpandList(*m, mapConfig);
         if (!mapConfig.empty()) {
           dstConfig = mapConfig[0].c_str();
         }
diff --git a/Source/cmGlobalVisualStudio7Generator.cxx b/Source/cmGlobalVisualStudio7Generator.cxx
index 9799124..f8b438a 100644
--- a/Source/cmGlobalVisualStudio7Generator.cxx
+++ b/Source/cmGlobalVisualStudio7Generator.cxx
@@ -128,7 +128,7 @@
   // does not know about.
   std::string extraPath;
   if (cmSystemTools::GetEnv("CMAKE_MSVCIDE_RUN_PATH", extraPath)) {
-    mf->AddCacheDefinition("CMAKE_MSVCIDE_RUN_PATH", extraPath.c_str(),
+    mf->AddCacheDefinition("CMAKE_MSVCIDE_RUN_PATH", extraPath,
                            "Saved environment variable CMAKE_MSVCIDE_RUN_PATH",
                            cmStateEnums::STATIC);
   }
@@ -339,22 +339,22 @@
   // loop over again and write out configurations for each target
   // in the solution
   for (cmGeneratorTarget const* target : projectTargets) {
-    if (target->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
+    if (!target->IsInBuildSystem()) {
       continue;
     }
-    const char* expath = target->GetProperty("EXTERNAL_MSPROJECT");
+    cmProp expath = target->GetProperty("EXTERNAL_MSPROJECT");
     if (expath) {
       std::set<std::string> allConfigurations(configs.begin(), configs.end());
-      const char* mapping = target->GetProperty("VS_PLATFORM_MAPPING");
+      cmProp mapping = target->GetProperty("VS_PLATFORM_MAPPING");
       this->WriteProjectConfigurations(fout, target->GetName(), *target,
                                        configs, allConfigurations,
-                                       mapping ? mapping : "");
+                                       mapping ? *mapping : "");
     } else {
       const std::set<std::string>& configsPartOfDefaultBuild =
         this->IsPartOfDefaultBuild(configs, projectTargets, target);
-      const char* vcprojName = target->GetProperty("GENERATOR_FILE_NAME");
+      cmProp vcprojName = target->GetProperty("GENERATOR_FILE_NAME");
       if (vcprojName) {
-        this->WriteProjectConfigurations(fout, vcprojName, *target, configs,
+        this->WriteProjectConfigurations(fout, *vcprojName, *target, configs,
                                          configsPartOfDefaultBuild);
       }
     }
@@ -369,23 +369,24 @@
 
   std::string rootBinaryDir = root->GetCurrentBinaryDirectory();
   for (cmGeneratorTarget const* target : projectTargets) {
-    if (target->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
+    if (!target->IsInBuildSystem()) {
       continue;
     }
     bool written = false;
 
     // handle external vc project files
-    const char* expath = target->GetProperty("EXTERNAL_MSPROJECT");
+    cmProp expath = target->GetProperty("EXTERNAL_MSPROJECT");
     if (expath) {
       std::string project = target->GetName();
-      std::string location = expath;
+      std::string location = *expath;
 
+      cmProp p = target->GetProperty("VS_PROJECT_TYPE");
       this->WriteExternalProject(fout, project, location,
-                                 target->GetProperty("VS_PROJECT_TYPE"),
+                                 p ? p->c_str() : nullptr,
                                  target->GetUtilities());
       written = true;
     } else {
-      const char* vcprojName = target->GetProperty("GENERATOR_FILE_NAME");
+      cmProp vcprojName = target->GetProperty("GENERATOR_FILE_NAME");
       if (vcprojName) {
         cmLocalGenerator* lg = target->GetLocalGenerator();
         std::string dir = lg->GetCurrentBinaryDirectory();
@@ -393,7 +394,7 @@
         if (dir == ".") {
           dir.clear(); // msbuild cannot handle ".\" prefix
         }
-        this->WriteProject(fout, vcprojName, dir, target);
+        this->WriteProject(fout, *vcprojName, dir, target);
         written = true;
       }
     }
@@ -435,14 +436,14 @@
   std::ostream& fout, OrderedTargetDependSet const& projectTargets)
 {
   for (cmGeneratorTarget const* target : projectTargets) {
-    if (target->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
+    if (!target->IsInBuildSystem()) {
       continue;
     }
-    const char* vcprojName = target->GetProperty("GENERATOR_FILE_NAME");
+    cmProp vcprojName = target->GetProperty("GENERATOR_FILE_NAME");
     if (vcprojName) {
       std::string dir =
         target->GetLocalGenerator()->GetCurrentSourceDirectory();
-      this->WriteProjectDepends(fout, vcprojName, dir.c_str(), target);
+      this->WriteProjectDepends(fout, *vcprojName, dir, target);
     }
   }
 }
@@ -505,13 +506,13 @@
   const std::vector<std::string> propKeys =
     root->GetMakefile()->GetPropertyKeys();
   for (std::string const& it : propKeys) {
-    if (it.find("VS_GLOBAL_SECTION_") == 0) {
+    if (cmHasLiteralPrefix(it, "VS_GLOBAL_SECTION_")) {
       std::string sectionType;
       std::string name = it.substr(18);
-      if (name.find("PRE_") == 0) {
+      if (cmHasLiteralPrefix(name, "PRE_")) {
         name = name.substr(4);
         sectionType = "preSolution";
-      } else if (name.find("POST_") == 0) {
+      } else if (cmHasLiteralPrefix(name, "POST_")) {
         name = name.substr(5);
         sectionType = "postSolution";
       } else
@@ -526,8 +527,8 @@
           extensibilityAddInsOverridden = true;
         }
         fout << "\tGlobalSection(" << name << ") = " << sectionType << "\n";
-        std::vector<std::string> keyValuePairs =
-          cmExpandedList(root->GetMakefile()->GetProperty(it));
+        cmProp p = root->GetMakefile()->GetProperty(it);
+        std::vector<std::string> keyValuePairs = cmExpandedList(p ? *p : "");
         for (std::string const& itPair : keyValuePairs) {
           const std::string::size_type posEqual = itPair.find('=');
           if (posEqual != std::string::npos) {
@@ -567,8 +568,9 @@
 std::string cmGlobalVisualStudio7Generator::WriteUtilityDepend(
   cmGeneratorTarget const* target)
 {
-  std::vector<std::string> configs;
-  target->Target->GetMakefile()->GetConfigurations(configs);
+  std::vector<std::string> configs =
+    target->Target->GetMakefile()->GetGeneratorConfigs(
+      cmMakefile::ExcludeEmptyConfig);
   std::string pname = cmStrCat(target->GetName(), "_UTILITY");
   std::string fname =
     cmStrCat(target->GetLocalGenerator()->GetCurrentBinaryDirectory(), '/',
@@ -676,7 +678,8 @@
         for (std::string const& i : configs) {
           const char* propertyValue =
             target->Target->GetMakefile()->GetDefinition(propertyName);
-          if (cmIsOn(cmGeneratorExpression::Evaluate(
+          if (propertyValue &&
+              cmIsOn(cmGeneratorExpression::Evaluate(
                 propertyValue, target->GetLocalGenerator(), i))) {
             activeConfigs.insert(i);
           }
@@ -691,9 +694,7 @@
   }
   // inspect EXCLUDE_FROM_DEFAULT_BUILD[_<CONFIG>] properties
   for (std::string const& i : configs) {
-    const char* propertyValue =
-      target->GetFeature("EXCLUDE_FROM_DEFAULT_BUILD", i);
-    if (cmIsOff(propertyValue)) {
+    if (cmIsOff(target->GetFeature("EXCLUDE_FROM_DEFAULT_BUILD", i))) {
       activeConfigs.insert(i);
     }
   }
diff --git a/Source/cmGlobalVisualStudio8Generator.cxx b/Source/cmGlobalVisualStudio8Generator.cxx
index 1c62fbd..fcdfc50 100644
--- a/Source/cmGlobalVisualStudio8Generator.cxx
+++ b/Source/cmGlobalVisualStudio8Generator.cxx
@@ -142,6 +142,9 @@
 
   // Add a custom rule to re-run CMake if any input files changed.
   {
+    // The custom rule runs cmake so set UTF-8 pipes.
+    bool stdPipesUTF8 = true;
+
     // Collect the input files used to generate all targets in this
     // project.
     std::vector<std::string> listFiles;
@@ -160,7 +163,7 @@
       lg.AddCustomCommandToTarget(
         CMAKE_CHECK_BUILD_SYSTEM_TARGET, byproducts, no_depends,
         verifyCommandLines, cmCustomCommandType::PRE_BUILD,
-        "Checking File Globs", no_working_directory, false);
+        "Checking File Globs", no_working_directory, stdPipesUTF8);
 
       // Ensure ZERO_CHECK always runs in Visual Studio using MSBuild,
       // otherwise the prebuild command will not be run.
@@ -192,7 +195,8 @@
     if (cmSourceFile* file = lg.AddCustomCommandToOutput(
           stamps, no_byproducts, listFiles, no_main_dependency,
           no_implicit_depends, commandLines, "Checking Build System",
-          no_working_directory, true, false)) {
+          no_working_directory, true, false, false, false, "", "",
+          stdPipesUTF8)) {
       gt->AddSource(file->ResolveFullPath());
     } else {
       cmSystemTools::Error("Error adding rule for " + stamps[0]);
@@ -240,9 +244,9 @@
     std::vector<std::string> mapConfig;
     const char* dstConfig = i.c_str();
     if (target.GetProperty("EXTERNAL_MSPROJECT")) {
-      if (const char* m = target.GetProperty("MAP_IMPORTED_CONFIG_" +
-                                             cmSystemTools::UpperCase(i))) {
-        cmExpandList(m, mapConfig);
+      if (cmProp m = target.GetProperty("MAP_IMPORTED_CONFIG_" +
+                                        cmSystemTools::UpperCase(i))) {
+        cmExpandList(*m, mapConfig);
         if (!mapConfig.empty()) {
           dstConfig = mapConfig[0].c_str();
         }
@@ -275,23 +279,31 @@
 bool cmGlobalVisualStudio8Generator::NeedsDeploy(
   cmGeneratorTarget const& target, const char* config) const
 {
-  cmStateEnums::TargetType type = target.GetType();
-  bool noDeploy = DeployInhibited(target, config);
-  return !noDeploy &&
-    (type == cmStateEnums::EXECUTABLE ||
-     type == cmStateEnums::SHARED_LIBRARY) &&
-    this->TargetSystemSupportsDeployment();
-}
-
-bool cmGlobalVisualStudio8Generator::DeployInhibited(
-  cmGeneratorTarget const& target, const char* config) const
-{
-  bool rVal = false;
-  if (const char* prop = target.GetProperty("VS_NO_SOLUTION_DEPLOY")) {
-    rVal = cmIsOn(
-      cmGeneratorExpression::Evaluate(prop, target.LocalGenerator, config));
+  cmStateEnums::TargetType const type = target.GetType();
+  if (type != cmStateEnums::EXECUTABLE &&
+      type != cmStateEnums::SHARED_LIBRARY) {
+    // deployment only valid on executables and shared libraries.
+    return false;
   }
-  return rVal;
+
+  if (cmProp prop = target.GetProperty("VS_SOLUTION_DEPLOY")) {
+    // If set, it dictates behavior
+    return cmIsOn(
+      cmGeneratorExpression::Evaluate(*prop, target.LocalGenerator, config));
+  }
+
+  // To be deprecated, disable deployment even if target supports it.
+  if (cmProp prop = target.GetProperty("VS_NO_SOLUTION_DEPLOY")) {
+    if (cmIsOn(cmGeneratorExpression::Evaluate(*prop, target.LocalGenerator,
+                                               config))) {
+      // If true, always disable deployment
+      return false;
+    }
+  }
+
+  // Legacy behavior, enabled deployment based on 'hard-coded' target
+  // platforms.
+  return this->TargetSystemSupportsDeployment();
 }
 
 bool cmGlobalVisualStudio8Generator::TargetSystemSupportsDeployment() const
@@ -313,7 +325,7 @@
   TargetDependSet const& unordered = this->GetTargetDirectDepends(gt);
   OrderedTargetDependSet depends(unordered, std::string());
   for (cmTargetDepend const& i : depends) {
-    if (i->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
+    if (!i->IsInBuildSystem()) {
       continue;
     }
     std::string guid = this->GetGUID(i->GetName());
@@ -329,7 +341,7 @@
     if (cmGeneratorTarget* depTarget =
           target->GetLocalGenerator()->FindGeneratorTargetToUse(
             ui.Value.first)) {
-      if (depTarget->GetType() != cmStateEnums::INTERFACE_LIBRARY &&
+      if (depTarget->IsInBuildSystem() &&
           depTarget->GetProperty("EXTERNAL_MSPROJECT")) {
         // This utility dependency names an external .vcproj target.
         // We use LinkLibraryDependencies="true" to link to it without
diff --git a/Source/cmGlobalVisualStudio8Generator.h b/Source/cmGlobalVisualStudio8Generator.h
index 8f8e33b..6ce67d3 100644
--- a/Source/cmGlobalVisualStudio8Generator.h
+++ b/Source/cmGlobalVisualStudio8Generator.h
@@ -57,10 +57,6 @@
   virtual bool NeedsDeploy(cmGeneratorTarget const& target,
                            const char* config) const;
 
-  /** Returns true if deployment has been disabled in cmake file. */
-  bool DeployInhibited(cmGeneratorTarget const& target,
-                       const char* config) const;
-
   /** Returns true if the target system support debugging deployment. */
   virtual bool TargetSystemSupportsDeployment() const;
 
diff --git a/Source/cmGlobalVisualStudioGenerator.cxx b/Source/cmGlobalVisualStudioGenerator.cxx
index 29d3f1a..001d876 100644
--- a/Source/cmGlobalVisualStudioGenerator.cxx
+++ b/Source/cmGlobalVisualStudioGenerator.cxx
@@ -368,7 +368,7 @@
 void cmGlobalVisualStudioGenerator::FollowLinkDepends(
   const cmGeneratorTarget* target, std::set<const cmGeneratorTarget*>& linked)
 {
-  if (target->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
+  if (!target->IsInBuildSystem()) {
     return;
   }
   if (linked.insert(target).second &&
@@ -508,9 +508,9 @@
 std::string cmGlobalVisualStudioGenerator::GetStartupProjectName(
   cmLocalGenerator const* root) const
 {
-  const char* n = root->GetMakefile()->GetProperty("VS_STARTUP_PROJECT");
-  if (n && *n) {
-    std::string startup = n;
+  cmProp n = root->GetMakefile()->GetProperty("VS_STARTUP_PROJECT");
+  if (cmNonempty(n)) {
+    std::string startup = *n;
     if (this->FindTarget(startup)) {
       return startup;
     } else {
@@ -809,9 +809,9 @@
   // This allows the project to control the language choice in
   // a target with none of its own sources, e.g. when also using
   // object libraries.
-  const char* linkLang = gt->GetProperty("LINKER_LANGUAGE");
-  if (linkLang && *linkLang) {
-    languages.insert(linkLang);
+  cmProp linkLang = gt->GetProperty("LINKER_LANGUAGE");
+  if (cmNonempty(linkLang)) {
+    languages.insert(*linkLang);
   }
 
   // Intel Fortran .vfproj files do support the resource compiler.
@@ -933,7 +933,7 @@
     { cmakeCommand, "-E", "__create_def", mdi->DefFile, objs_file });
   cmCustomCommand command(outputs, empty, empty, commandLines,
                           gt->Target->GetMakefile()->GetBacktrace(),
-                          "Auto build dll exports", ".");
+                          "Auto build dll exports", ".", true);
   commands.push_back(std::move(command));
 }
 
diff --git a/Source/cmGlobalVisualStudioVersionedGenerator.cxx b/Source/cmGlobalVisualStudioVersionedGenerator.cxx
index 13ae32a..e2e045c 100644
--- a/Source/cmGlobalVisualStudioVersionedGenerator.cxx
+++ b/Source/cmGlobalVisualStudioVersionedGenerator.cxx
@@ -100,6 +100,24 @@
   return "";
 }
 
+static const char* VSVersionToAndroidToolset(
+  cmGlobalVisualStudioGenerator::VSVersion v)
+{
+  switch (v) {
+    case cmGlobalVisualStudioGenerator::VS9:
+    case cmGlobalVisualStudioGenerator::VS10:
+    case cmGlobalVisualStudioGenerator::VS11:
+    case cmGlobalVisualStudioGenerator::VS12:
+      return "";
+    case cmGlobalVisualStudioGenerator::VS14:
+      return "Clang_3_8";
+    case cmGlobalVisualStudioGenerator::VS15:
+    case cmGlobalVisualStudioGenerator::VS16:
+      return "Clang_5_0";
+  }
+  return "";
+}
+
 static const char vs15generatorName[] = "Visual Studio 15 2017";
 
 // Map generator name without year to name with year.
@@ -284,6 +302,7 @@
   this->Version = version;
   this->ExpressEdition = false;
   this->DefaultPlatformToolset = VSVersionToToolset(this->Version);
+  this->DefaultAndroidToolset = VSVersionToAndroidToolset(this->Version);
   this->DefaultCLFlagTableName = VSVersionToToolset(this->Version);
   this->DefaultCSharpFlagTableName = VSVersionToToolset(this->Version);
   this->DefaultLinkFlagTableName = VSVersionToToolset(this->Version);
@@ -366,6 +385,12 @@
   return vsSetupAPIHelper.GetVSInstanceInfo(dir);
 }
 
+bool cmGlobalVisualStudioVersionedGenerator::GetVSInstanceVersion(
+  unsigned long long& vsInstanceVersion) const
+{
+  return vsSetupAPIHelper.GetVSInstanceVersion(vsInstanceVersion);
+}
+
 bool cmGlobalVisualStudioVersionedGenerator::IsDefaultToolset(
   const std::string& version) const
 {
@@ -387,6 +412,40 @@
   return false;
 }
 
+bool cmGlobalVisualStudioVersionedGenerator::IsStdOutEncodingSupported() const
+{
+  // Supported from Visual Studio 16.7 Preview 3.
+  if (this->Version > cmGlobalVisualStudioGenerator::VSVersion::VS16) {
+    return true;
+  }
+  if (this->Version < cmGlobalVisualStudioGenerator::VSVersion::VS16) {
+    return false;
+  }
+  unsigned long long const vsInstanceVersion16_7_P2 = 4503631666610212;
+  unsigned long long vsInstanceVersion;
+  return (this->GetVSInstanceVersion(vsInstanceVersion) &&
+          vsInstanceVersion > vsInstanceVersion16_7_P2);
+}
+
+const char*
+cmGlobalVisualStudioVersionedGenerator::GetAndroidApplicationTypeRevision()
+  const
+{
+  switch (this->Version) {
+    case cmGlobalVisualStudioGenerator::VS9:
+    case cmGlobalVisualStudioGenerator::VS10:
+    case cmGlobalVisualStudioGenerator::VS11:
+    case cmGlobalVisualStudioGenerator::VS12:
+      return "";
+    case cmGlobalVisualStudioGenerator::VS14:
+      return "2.0";
+    case cmGlobalVisualStudioGenerator::VS15:
+    case cmGlobalVisualStudioGenerator::VS16:
+      return "3.0";
+  }
+  return "";
+}
+
 std::string cmGlobalVisualStudioVersionedGenerator::GetAuxiliaryToolset() const
 {
   const char* version = this->GetPlatformToolsetVersion();
diff --git a/Source/cmGlobalVisualStudioVersionedGenerator.h b/Source/cmGlobalVisualStudioVersionedGenerator.h
index abb6095..d5b8337 100644
--- a/Source/cmGlobalVisualStudioVersionedGenerator.h
+++ b/Source/cmGlobalVisualStudioVersionedGenerator.h
@@ -29,9 +29,15 @@
 
   bool GetVSInstance(std::string& dir) const;
 
+  bool GetVSInstanceVersion(unsigned long long& vsInstanceVersion) const;
+
   bool IsDefaultToolset(const std::string& version) const override;
   std::string GetAuxiliaryToolset() const override;
 
+  bool IsStdOutEncodingSupported() const override;
+
+  const char* GetAndroidApplicationTypeRevision() const override;
+
 protected:
   cmGlobalVisualStudioVersionedGenerator(
     VSVersion version, cmake* cm, const std::string& name,
diff --git a/Source/cmGlobalWatcomWMakeGenerator.cxx b/Source/cmGlobalWatcomWMakeGenerator.cxx
index 308ddda..d6a7afa 100644
--- a/Source/cmGlobalWatcomWMakeGenerator.cxx
+++ b/Source/cmGlobalWatcomWMakeGenerator.cxx
@@ -19,7 +19,7 @@
 #endif
   this->ToolSupportsColor = true;
   this->NeedSymbolicMark = true;
-  this->EmptyRuleHackCommand = "@cd .";
+  this->EmptyRuleHackCommand = "@%null";
 #ifdef _WIN32
   cm->GetState()->SetWindowsShell(true);
 #endif
@@ -44,6 +44,16 @@
   this->cmGlobalUnixMakefileGenerator3::EnableLanguage(l, mf, optional);
 }
 
+bool cmGlobalWatcomWMakeGenerator::SetSystemName(std::string const& s,
+                                                 cmMakefile* mf)
+{
+  if (mf->GetSafeDefinition("CMAKE_SYSTEM_PROCESSOR") == "I86") {
+    mf->AddDefinition("CMAKE_GENERATOR_CC", "wcl");
+    mf->AddDefinition("CMAKE_GENERATOR_CXX", "wcl");
+  }
+  return this->cmGlobalUnixMakefileGenerator3::SetSystemName(s, mf);
+}
+
 void cmGlobalWatcomWMakeGenerator::GetDocumentation(
   cmDocumentationEntry& entry)
 {
diff --git a/Source/cmGlobalWatcomWMakeGenerator.h b/Source/cmGlobalWatcomWMakeGenerator.h
index c0daf8a..c47127f 100644
--- a/Source/cmGlobalWatcomWMakeGenerator.h
+++ b/Source/cmGlobalWatcomWMakeGenerator.h
@@ -41,6 +41,9 @@
   /** Get the documentation entry for this generator.  */
   static void GetDocumentation(cmDocumentationEntry& entry);
 
+  /** Tell the generator about the target system.  */
+  bool SetSystemName(std::string const& s, cmMakefile* mf) override;
+
   /**
    * Try to determine system information such as shared library
    * extension, pthreads, byte order etc.
diff --git a/Source/cmGlobalXCodeGenerator.cxx b/Source/cmGlobalXCodeGenerator.cxx
index e0005a4..793f6f7 100644
--- a/Source/cmGlobalXCodeGenerator.cxx
+++ b/Source/cmGlobalXCodeGenerator.cxx
@@ -8,13 +8,14 @@
 #include <cstring>
 #include <iomanip>
 #include <sstream>
+#include <utility>
 
 #include <cm/memory>
 #include <cmext/algorithm>
+#include <cmext/string_view>
 
 #include "cmsys/RegularExpression.hxx"
 
-#include "cmAlgorithms.h"
 #include "cmComputeLinkInformation.h"
 #include "cmCustomCommand.h"
 #include "cmCustomCommandGenerator.h"
@@ -33,6 +34,7 @@
 #include "cmSourceGroup.h"
 #include "cmState.h"
 #include "cmStateTypes.h"
+#include "cmStringAlgorithms.h"
 #include "cmSystemTools.h"
 #include "cmTarget.h"
 #include "cmXCode21Object.h"
@@ -171,6 +173,7 @@
 
   this->RootObject = nullptr;
   this->MainGroupChildren = nullptr;
+  this->FrameworkGroup = nullptr;
   this->CurrentMakefile = nullptr;
   this->CurrentLocalGenerator = nullptr;
   this->XcodeBuildCommandInitialized = false;
@@ -270,6 +273,13 @@
   return makeProgram;
 }
 
+bool cmGlobalXCodeGenerator::SetSystemName(std::string const& s,
+                                           cmMakefile* mf)
+{
+  this->SystemName = s;
+  return this->cmGlobalGenerator::SetSystemName(s, mf);
+}
+
 bool cmGlobalXCodeGenerator::SetGeneratorToolset(std::string const& ts,
                                                  bool build, cmMakefile* mf)
 {
@@ -361,7 +371,7 @@
     std::string projectArg = cmStrCat(projectName, ".xcodeproj");
     makeCommand.Add(projectArg);
   }
-  if (cmContains(targetNames, "clean")) {
+  if (cm::contains(targetNames, "clean")) {
     makeCommand.Add("clean");
     makeCommand.Add("-target", "ALL_BUILD");
   } else {
@@ -467,6 +477,9 @@
       }
     }
 
+    // cache the enabled languages for source file type queries
+    this->GetEnabledLanguages(this->EnabledLangs);
+
     this->SetGenerationRoot(root);
     // now create the project
     this->OutputXCodeProject(root, keyVal.second);
@@ -642,7 +655,8 @@
                  << "\n";
 }
 
-static bool objectIdLessThan(cmXCodeObject* l, cmXCodeObject* r)
+static bool objectIdLessThan(const std::unique_ptr<cmXCodeObject>& l,
+                             const std::unique_ptr<cmXCodeObject>& r)
 {
   return l->GetId() < r->GetId();
 }
@@ -656,9 +670,6 @@
 void cmGlobalXCodeGenerator::ClearXCodeObjects()
 {
   this->TargetDoneSet.clear();
-  for (auto& obj : this->XCodeObjects) {
-    delete obj;
-  }
   this->XCodeObjects.clear();
   this->XCodeObjectIDs.clear();
   this->XCodeObjectMap.clear();
@@ -666,9 +677,10 @@
   this->GroupNameMap.clear();
   this->TargetGroup.clear();
   this->FileRefs.clear();
+  this->ExternalLibRefs.clear();
 }
 
-void cmGlobalXCodeGenerator::addObject(cmXCodeObject* obj)
+void cmGlobalXCodeGenerator::addObject(std::unique_ptr<cmXCodeObject> obj)
 {
   if (obj->GetType() == cmXCodeObject::OBJECT) {
     const std::string& id = obj->GetId();
@@ -683,22 +695,24 @@
     this->XCodeObjectIDs.insert(id);
   }
 
-  this->XCodeObjects.push_back(obj);
+  this->XCodeObjects.push_back(std::move(obj));
 }
 
 cmXCodeObject* cmGlobalXCodeGenerator::CreateObject(
   cmXCodeObject::PBXType ptype)
 {
-  cmXCodeObject* obj = new cmXCode21Object(ptype, cmXCodeObject::OBJECT);
-  this->addObject(obj);
-  return obj;
+  auto obj = cm::make_unique<cmXCode21Object>(ptype, cmXCodeObject::OBJECT);
+  auto ptr = obj.get();
+  this->addObject(std::move(obj));
+  return ptr;
 }
 
 cmXCodeObject* cmGlobalXCodeGenerator::CreateObject(cmXCodeObject::Type type)
 {
-  cmXCodeObject* obj = new cmXCodeObject(cmXCodeObject::None, type);
-  this->addObject(obj);
-  return obj;
+  auto obj = cm::make_unique<cmXCodeObject>(cmXCodeObject::None, type);
+  auto ptr = obj.get();
+  this->addObject(std::move(obj));
+  return ptr;
 }
 
 cmXCodeObject* cmGlobalXCodeGenerator::CreateString(const std::string& s)
@@ -732,7 +746,7 @@
   return key;
 }
 
-cmXCodeObject* cmGlobalXCodeGenerator::CreateXCodeSourceFileFromPath(
+cmXCodeObject* cmGlobalXCodeGenerator::CreateXCodeBuildFileFromPath(
   const std::string& fullpath, cmGeneratorTarget* target,
   const std::string& lang, cmSourceFile* sf)
 {
@@ -768,11 +782,15 @@
   XCodeGeneratorExpressionInterpreter& operator=(
     XCodeGeneratorExpressionInterpreter const&) = delete;
 
-  using cmGeneratorExpressionInterpreter::Evaluate;
-
   const std::string& Evaluate(const char* expression,
                               const std::string& property)
   {
+    return this->Evaluate(std::string(expression ? expression : ""), property);
+  }
+
+  const std::string& Evaluate(const std::string& expression,
+                              const std::string& property)
+  {
     const std::string& processed =
       this->cmGeneratorExpressionInterpreter::Evaluate(expression, property);
     if (this->CompiledGeneratorExpression->GetHadContextSensitiveCondition()) {
@@ -803,7 +821,7 @@
 
   // Add flags from target and source file properties.
   std::string flags;
-  const char* srcfmt = sf->GetProperty("Fortran_FORMAT");
+  std::string const& srcfmt = sf->GetSafeProperty("Fortran_FORMAT");
   switch (cmOutputConverter::GetFortranFormat(srcfmt)) {
     case cmOutputConverter::FortranFormatFixed:
       flags = "-fixed " + flags;
@@ -814,23 +832,31 @@
     default:
       break;
   }
+
+  // explicitly add the explicit language flag before any other flag
+  // this way backwards compatibility with user flags is maintained
+  if (sf->GetProperty("LANGUAGE")) {
+    this->CurrentLocalGenerator->AppendFeatureOptions(flags, lang,
+                                                      "EXPLICIT_LANGUAGE");
+  }
+
   const std::string COMPILE_FLAGS("COMPILE_FLAGS");
-  if (const char* cflags = sf->GetProperty(COMPILE_FLAGS)) {
-    lg->AppendFlags(flags, genexInterpreter.Evaluate(cflags, COMPILE_FLAGS));
+  if (cmProp cflags = sf->GetProperty(COMPILE_FLAGS)) {
+    lg->AppendFlags(flags, genexInterpreter.Evaluate(*cflags, COMPILE_FLAGS));
   }
   const std::string COMPILE_OPTIONS("COMPILE_OPTIONS");
-  if (const char* coptions = sf->GetProperty(COMPILE_OPTIONS)) {
+  if (cmProp coptions = sf->GetProperty(COMPILE_OPTIONS)) {
     lg->AppendCompileOptions(
-      flags, genexInterpreter.Evaluate(coptions, COMPILE_OPTIONS));
+      flags, genexInterpreter.Evaluate(*coptions, COMPILE_OPTIONS));
   }
 
   // Add per-source definitions.
   BuildObjectListOrString flagsBuild(this, false);
   const std::string COMPILE_DEFINITIONS("COMPILE_DEFINITIONS");
-  if (const char* compile_defs = sf->GetProperty(COMPILE_DEFINITIONS)) {
+  if (cmProp compile_defs = sf->GetProperty(COMPILE_DEFINITIONS)) {
     this->AppendDefines(
       flagsBuild,
-      genexInterpreter.Evaluate(compile_defs, COMPILE_DEFINITIONS).c_str(),
+      genexInterpreter.Evaluate(*compile_defs, COMPILE_DEFINITIONS).c_str(),
       true);
   }
 
@@ -848,15 +874,15 @@
   // Add per-source include directories.
   std::vector<std::string> includes;
   const std::string INCLUDE_DIRECTORIES("INCLUDE_DIRECTORIES");
-  if (const char* cincludes = sf->GetProperty(INCLUDE_DIRECTORIES)) {
+  if (cmProp cincludes = sf->GetProperty(INCLUDE_DIRECTORIES)) {
     lg->AppendIncludeDirectories(
-      includes, genexInterpreter.Evaluate(cincludes, INCLUDE_DIRECTORIES),
+      includes, genexInterpreter.Evaluate(*cincludes, INCLUDE_DIRECTORIES),
       *sf);
   }
   lg->AppendFlags(flags, lg->GetIncludeFlags(includes, gtgt, lang, true));
 
   cmXCodeObject* buildFile =
-    this->CreateXCodeSourceFileFromPath(sf->ResolveFullPath(), gtgt, lang, sf);
+    this->CreateXCodeBuildFileFromPath(sf->ResolveFullPath(), gtgt, lang, sf);
 
   cmXCodeObject* settings = this->CreateObject(cmXCodeObject::ATTRIBUTE_GROUP);
   settings->AddAttributeIfNotEmpty("COMPILER_FLAGS",
@@ -879,10 +905,10 @@
   }
 
   // Add user-specified file attributes.
-  const char* extraFileAttributes = sf->GetProperty("XCODE_FILE_ATTRIBUTES");
+  cmProp extraFileAttributes = sf->GetProperty("XCODE_FILE_ATTRIBUTES");
   if (extraFileAttributes) {
     // Expand the list of attributes.
-    std::vector<std::string> attributes = cmExpandedList(extraFileAttributes);
+    std::vector<std::string> attributes = cmExpandedList(*extraFileAttributes);
 
     // Store the attributes.
     for (const auto& attribute : attributes) {
@@ -904,19 +930,45 @@
              "/CMakeLists.txt");
   cmSourceFile* srcCMakeLists = target->Makefile->GetOrCreateSource(
     listfile, false, cmSourceFileLocationKind::Known);
-  if (!cmContains(sources, srcCMakeLists)) {
+  if (!cm::contains(sources, srcCMakeLists)) {
     sources.push_back(srcCMakeLists);
   }
 }
 
-std::string GetSourcecodeValueFromFileExtension(const std::string& _ext,
-                                                const std::string& lang,
-                                                bool& keepLastKnownFileType)
+bool IsLibraryExtension(const std::string& fileExt)
+{
+  return (fileExt == ".framework" || fileExt == ".a" || fileExt == ".o" ||
+          fileExt == ".dylib" || fileExt == ".tbd");
+}
+bool IsLibraryType(const std::string& fileType)
+{
+  return (fileType == "wrapper.framework" || fileType == "archive.ar" ||
+          fileType == "compiled.mach-o.objfile" ||
+          fileType == "compiled.mach-o.dylib" ||
+          fileType == "sourcecode.text-based-dylib-definition");
+}
+
+std::string GetDirectoryValueFromFileExtension(const std::string& dirExt)
+{
+  std::string ext = cmSystemTools::LowerCase(dirExt);
+  if (ext == "framework") {
+    return "wrapper.framework";
+  }
+  if (ext == "xcassets") {
+    return "folder.assetcatalog";
+  }
+  return "folder";
+}
+
+std::string GetSourcecodeValueFromFileExtension(
+  const std::string& _ext, const std::string& lang,
+  bool& keepLastKnownFileType, const std::vector<std::string>& enabled_langs)
 {
   std::string ext = cmSystemTools::LowerCase(_ext);
   std::string sourcecode = "sourcecode";
 
   if (ext == "o") {
+    keepLastKnownFileType = true;
     sourcecode = "compiled.mach-o.objfile";
   } else if (ext == "xctest") {
     sourcecode = "wrapper.cfbundle";
@@ -926,9 +978,9 @@
   } else if (ext == "storyboard") {
     keepLastKnownFileType = true;
     sourcecode = "file.storyboard";
-  } else if (ext == "mm") {
+  } else if (ext == "mm" && !cm::contains(enabled_langs, "OBJCXX")) {
     sourcecode += ".cpp.objcpp";
-  } else if (ext == "m") {
+  } else if (ext == "m" && !cm::contains(enabled_langs, "OBJC")) {
     sourcecode += ".c.objc";
   } else if (ext == "swift") {
     sourcecode += ".swift";
@@ -960,6 +1012,14 @@
     sourcecode += ".metal";
   } else if (ext == "mig") {
     sourcecode += ".mig";
+  } else if (ext == "tbd") {
+    sourcecode += ".text-based-dylib-definition";
+  } else if (ext == "a") {
+    keepLastKnownFileType = true;
+    sourcecode = "archive.ar";
+  } else if (ext == "dylib") {
+    keepLastKnownFileType = true;
+    sourcecode = "compiled.mach-o.dylib";
   }
   // else
   //  {
@@ -976,62 +1036,80 @@
   const std::string& fullpath, cmGeneratorTarget* target,
   const std::string& lang, cmSourceFile* sf)
 {
-  std::string key = GetGroupMapKeyFromPath(target, fullpath);
-  cmXCodeObject* fileRef = this->FileRefs[key];
-  if (!fileRef) {
-    fileRef = this->CreateObject(cmXCodeObject::PBXFileReference);
-    fileRef->SetComment(fullpath);
-    this->FileRefs[key] = fileRef;
-  }
-  cmXCodeObject* group = this->GroupMap[key];
-  cmXCodeObject* children = group->GetObject("children");
-  if (!children->HasObject(fileRef)) {
-    children->AddObject(fileRef);
-  }
-  fileRef->AddAttribute("fileEncoding", this->CreateString("4"));
-
   bool useLastKnownFileType = false;
   std::string fileType;
   if (sf) {
-    if (const char* e = sf->GetProperty("XCODE_EXPLICIT_FILE_TYPE")) {
-      fileType = e;
-    } else if (const char* l = sf->GetProperty("XCODE_LAST_KNOWN_FILE_TYPE")) {
+    if (cmProp e = sf->GetProperty("XCODE_EXPLICIT_FILE_TYPE")) {
+      fileType = *e;
+    } else if (cmProp l = sf->GetProperty("XCODE_LAST_KNOWN_FILE_TYPE")) {
       useLastKnownFileType = true;
-      fileType = l;
+      fileType = *l;
     }
   }
+  // Make a copy so that we can override it later
+  std::string path = fullpath;
+  // Compute the extension without leading '.'.
+  std::string ext = cmSystemTools::GetFilenameLastExtension(path);
+  if (!ext.empty()) {
+    ext = ext.substr(1);
+  }
   if (fileType.empty()) {
-    // Compute the extension without leading '.'.
-    std::string ext = cmSystemTools::GetFilenameLastExtension(fullpath);
-    if (!ext.empty()) {
-      ext = ext.substr(1);
+    // If file has no extension it's either a raw executable or might
+    // be a direct reference to binary within a framework (bad practice!)
+    // so this is where we change the path to the point to framework
+    // directory.
+    if (ext.empty()) {
+      auto parentDir = cmSystemTools::GetParentDirectory(path);
+      auto parentExt = cmSystemTools::GetFilenameLastExtension(parentDir);
+      if (parentExt == ".framework") {
+        path = parentDir;
+        ext = parentExt.substr(1);
+      }
     }
-
     // If fullpath references a directory, then we need to specify
     // lastKnownFileType as folder in order for Xcode to be able to
     // open the contents of the folder.
     // (Xcode 4.6 does not like explicitFileType=folder).
-    if (cmSystemTools::FileIsDirectory(fullpath)) {
-      fileType = (ext == "xcassets" ? "folder.assetcatalog" : "folder");
+    if (cmSystemTools::FileIsDirectory(path)) {
+      fileType = GetDirectoryValueFromFileExtension(ext);
       useLastKnownFileType = true;
     } else {
-      fileType =
-        GetSourcecodeValueFromFileExtension(ext, lang, useLastKnownFileType);
+      fileType = GetSourcecodeValueFromFileExtension(
+        ext, lang, useLastKnownFileType, this->EnabledLangs);
     }
   }
 
+  std::string key = GetGroupMapKeyFromPath(target, path);
+  cmXCodeObject* fileRef = this->FileRefs[key];
+  if (!fileRef) {
+    fileRef = this->CreateObject(cmXCodeObject::PBXFileReference);
+    fileRef->SetComment(path);
+    this->FileRefs[key] = fileRef;
+  }
+  fileRef->AddAttribute("fileEncoding", this->CreateString("4"));
   fileRef->AddAttribute(useLastKnownFileType ? "lastKnownFileType"
                                              : "explicitFileType",
                         this->CreateString(fileType));
-
   // Store the file path relative to the top of the source tree.
-  std::string path = this->RelativeToSource(fullpath);
+  if (!IsLibraryType(fileType)) {
+    path = this->RelativeToSource(path);
+  }
   std::string name = cmSystemTools::GetFilenameName(path);
   const char* sourceTree =
     cmSystemTools::FileIsFullPath(path) ? "<absolute>" : "SOURCE_ROOT";
   fileRef->AddAttribute("name", this->CreateString(name));
   fileRef->AddAttribute("path", this->CreateString(path));
   fileRef->AddAttribute("sourceTree", this->CreateString(sourceTree));
+
+  cmXCodeObject* group = this->GroupMap[key];
+  if (!group && IsLibraryType(fileType)) {
+    group = this->FrameworkGroup;
+    this->GroupMap[key] = group;
+  }
+  cmXCodeObject* children = group->GetObject("children");
+  if (!children->HasObject(fileRef)) {
+    children->AddObject(fileRef);
+  }
   return fileRef;
 }
 
@@ -1064,11 +1142,8 @@
   this->CurrentMakefile = gen->GetMakefile();
 
   // Select the current set of configuration types.
-  this->CurrentConfigurationTypes.clear();
-  this->CurrentMakefile->GetConfigurations(this->CurrentConfigurationTypes);
-  if (this->CurrentConfigurationTypes.empty()) {
-    this->CurrentConfigurationTypes.emplace_back();
-  }
+  this->CurrentConfigurationTypes =
+    this->CurrentMakefile->GetGeneratorConfigs(cmMakefile::IncludeEmptyConfig);
 }
 
 struct cmSourceFilePathCompare
@@ -1124,11 +1199,12 @@
     return true;
   }
 
-  if (gtgt->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
+  if (!gtgt->IsInBuildSystem()) {
     return true;
   }
 
   if (gtgt->GetType() == cmStateEnums::UTILITY ||
+      gtgt->GetType() == cmStateEnums::INTERFACE_LIBRARY ||
       gtgt->GetType() == cmStateEnums::GLOBAL_TARGET) {
     cmXCodeObject* t = this->CreateUtilityTarget(gtgt);
     if (!t) {
@@ -1139,23 +1215,24 @@
   }
 
   // organize the sources
-  std::vector<cmSourceFile*> classes;
-  if (!gtgt->GetConfigCommonSourceFiles(classes)) {
+  std::vector<cmSourceFile*> commonSourceFiles;
+  if (!gtgt->GetConfigCommonSourceFiles(commonSourceFiles)) {
     return false;
   }
 
   // Add CMakeLists.txt file for user convenience.
-  this->AddXCodeProjBuildRule(gtgt, classes);
+  this->AddXCodeProjBuildRule(gtgt, commonSourceFiles);
 
   // Add the Info.plist we are about to generate for an App Bundle.
   if (gtgt->GetPropertyAsBool("MACOSX_BUNDLE")) {
     std::string plist = this->ComputeInfoPListLocation(gtgt);
     cmSourceFile* sf = gtgt->Makefile->GetOrCreateSource(
       plist, true, cmSourceFileLocationKind::Known);
-    classes.push_back(sf);
+    commonSourceFiles.push_back(sf);
   }
 
-  std::sort(classes.begin(), classes.end(), cmSourceFilePathCompare());
+  std::sort(commonSourceFiles.begin(), commonSourceFiles.end(),
+            cmSourceFilePathCompare());
 
   gtgt->ComputeObjectMapping();
 
@@ -1163,16 +1240,19 @@
   std::vector<cmXCodeObject*> headerFiles;
   std::vector<cmXCodeObject*> resourceFiles;
   std::vector<cmXCodeObject*> sourceFiles;
-  for (auto sourceFile : classes) {
+  for (auto sourceFile : commonSourceFiles) {
     cmXCodeObject* xsf = this->CreateXCodeSourceFile(
       this->CurrentLocalGenerator, sourceFile, gtgt);
     cmXCodeObject* fr = xsf->GetObject("fileRef");
     cmXCodeObject* filetype = fr->GetObject()->GetObject("explicitFileType");
+    if (!filetype) {
+      filetype = fr->GetObject()->GetObject("lastKnownFileType");
+    }
 
     cmGeneratorTarget::SourceFileFlags tsFlags =
       gtgt->GetTargetSourceFileFlags(sourceFile);
 
-    if (filetype && filetype->GetString() == "compiled.mach-o.objfile") {
+    if (filetype && IsLibraryType(filetype->GetString())) {
       if (sourceFile->GetObjectLibrary().empty()) {
         externalObjFiles.push_back(xsf);
       }
@@ -1262,7 +1342,7 @@
     using mapOfVectorOfSourceFiles =
       std::map<std::string, std::vector<cmSourceFile*>>;
     mapOfVectorOfSourceFiles bundleFiles;
-    for (auto sourceFile : classes) {
+    for (auto sourceFile : commonSourceFiles) {
       cmGeneratorTarget::SourceFileFlags tsFlags =
         gtgt->GetTargetSourceFileFlags(sourceFile);
       if (tsFlags.Type == cmGeneratorTarget::SourceFileTypeMacContent) {
@@ -1310,7 +1390,7 @@
     using mapOfVectorOfSourceFiles =
       std::map<std::string, std::vector<cmSourceFile*>>;
     mapOfVectorOfSourceFiles bundleFiles;
-    for (auto sourceFile : classes) {
+    for (auto sourceFile : commonSourceFiles) {
       cmGeneratorTarget::SourceFileFlags tsFlags =
         gtgt->GetTargetSourceFileFlags(sourceFile);
       if (tsFlags.Type == cmGeneratorTarget::SourceFileTypeDeepResource) {
@@ -1340,22 +1420,20 @@
     }
   }
 
-  // create framework build phase
+  // always create framework build phase
   cmXCodeObject* frameworkBuildPhase = nullptr;
-  if (!externalObjFiles.empty()) {
-    frameworkBuildPhase =
-      this->CreateObject(cmXCodeObject::PBXFrameworksBuildPhase);
-    frameworkBuildPhase->SetComment("Frameworks");
-    frameworkBuildPhase->AddAttribute("buildActionMask",
-                                      this->CreateString("2147483647"));
-    buildFiles = this->CreateObject(cmXCodeObject::OBJECT_LIST);
-    frameworkBuildPhase->AddAttribute("files", buildFiles);
-    for (auto& externalObjFile : externalObjFiles) {
-      buildFiles->AddObject(externalObjFile);
-    }
-    frameworkBuildPhase->AddAttribute("runOnlyForDeploymentPostprocessing",
-                                      this->CreateString("0"));
+  frameworkBuildPhase =
+    this->CreateObject(cmXCodeObject::PBXFrameworksBuildPhase);
+  frameworkBuildPhase->SetComment("Frameworks");
+  frameworkBuildPhase->AddAttribute("buildActionMask",
+                                    this->CreateString("2147483647"));
+  buildFiles = this->CreateObject(cmXCodeObject::OBJECT_LIST);
+  frameworkBuildPhase->AddAttribute("files", buildFiles);
+  for (auto& externalObjFile : externalObjFiles) {
+    buildFiles->AddObject(externalObjFile);
   }
+  frameworkBuildPhase->AddAttribute("runOnlyForDeploymentPostprocessing",
+                                    this->CreateString("0"));
 
   // create list of build phases and create the Xcode target
   cmXCodeObject* buildPhases = this->CreateObject(cmXCodeObject::OBJECT_LIST);
@@ -1420,8 +1498,8 @@
 
 bool cmGlobalXCodeGenerator::IsHeaderFile(cmSourceFile* sf)
 {
-  return cmContains(this->CMakeInstance->GetHeaderExtensions(),
-                    sf->GetExtension());
+  return cm::contains(this->CMakeInstance->GetHeaderExtensions(),
+                      sf->GetExtension());
 }
 
 cmXCodeObject* cmGlobalXCodeGenerator::CreateBuildPhase(
@@ -1462,6 +1540,7 @@
       cmStrCat("$<TARGET_SONAME_FILE:", gtgt->GetName(), '>');
     std::string str_link_file =
       cmStrCat("$<TARGET_LINKER_FILE:", gtgt->GetName(), '>');
+    bool stdPipesUTF8 = true;
     cmCustomCommandLines cmd = cmMakeSingleCommandLine(
       { cmSystemTools::GetCMakeCommand(), "-E", "cmake_symlink_library",
         str_file, str_so_file, str_link_file });
@@ -1469,7 +1548,7 @@
     cmCustomCommand command(
       std::vector<std::string>(), std::vector<std::string>(),
       std::vector<std::string>(), cmd, this->CurrentMakefile->GetBacktrace(),
-      "Creating symlinks", "");
+      "Creating symlinks", "", stdPipesUTF8);
 
     postbuild.push_back(std::move(command));
   }
@@ -1767,7 +1846,7 @@
                                                  cmXCodeObject* buildSettings,
                                                  const std::string& configName)
 {
-  if (gtgt->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
+  if (!gtgt->IsInBuildSystem()) {
     return;
   }
 
@@ -1859,18 +1938,18 @@
   if (gtgt->GetType() == cmStateEnums::OBJECT_LIBRARY ||
       gtgt->GetType() == cmStateEnums::STATIC_LIBRARY) {
     this->CurrentLocalGenerator->GetStaticLibraryFlags(
-      extraLinkOptions, cmSystemTools::UpperCase(configName), llang, gtgt);
+      extraLinkOptions, configName, llang, gtgt);
   } else {
-    const char* targetLinkFlags = gtgt->GetProperty("LINK_FLAGS");
+    cmProp targetLinkFlags = gtgt->GetProperty("LINK_FLAGS");
     if (targetLinkFlags) {
       this->CurrentLocalGenerator->AppendFlags(extraLinkOptions,
-                                               targetLinkFlags);
+                                               *targetLinkFlags);
     }
     if (!configName.empty()) {
       std::string linkFlagsVar =
         cmStrCat("LINK_FLAGS_", cmSystemTools::UpperCase(configName));
-      if (const char* linkFlags = gtgt->GetProperty(linkFlagsVar)) {
-        this->CurrentLocalGenerator->AppendFlags(extraLinkOptions, linkFlags);
+      if (cmProp linkFlags = gtgt->GetProperty(linkFlagsVar)) {
+        this->CurrentLocalGenerator->AppendFlags(extraLinkOptions, *linkFlags);
       }
     }
     std::vector<std::string> opts;
@@ -1906,8 +1985,8 @@
   std::string pnsuffix;
   gtgt->GetFullNameComponents(pnprefix, pnbase, pnsuffix, configName);
 
-  const char* version = gtgt->GetProperty("VERSION");
-  const char* soversion = gtgt->GetProperty("SOVERSION");
+  cmProp version = gtgt->GetProperty("VERSION");
+  cmProp soversion = gtgt->GetProperty("SOVERSION");
   if (!gtgt->HasSOName(configName) || gtgt->IsFrameworkOnApple()) {
     version = nullptr;
     soversion = nullptr;
@@ -1923,9 +2002,9 @@
   std::string soName = pnbase;
   if (version && soversion) {
     realName += ".";
-    realName += version;
+    realName += *version;
     soName += ".";
-    soName += soversion;
+    soName += *soversion;
   }
 
   // Set attributes to specify the proper name for the target.
@@ -1971,10 +2050,10 @@
         std::string fw_version = gtgt->GetFrameworkVersion();
         buildSettings->AddAttribute("FRAMEWORK_VERSION",
                                     this->CreateString(fw_version));
-        const char* ext = gtgt->GetProperty("BUNDLE_EXTENSION");
+        cmProp ext = gtgt->GetProperty("BUNDLE_EXTENSION");
         if (ext) {
           buildSettings->AddAttribute("WRAPPER_EXTENSION",
-                                      this->CreateString(ext));
+                                      this->CreateString(*ext));
         }
 
         std::string plist = this->ComputeInfoPListLocation(gtgt);
@@ -2012,10 +2091,10 @@
           extraLinkOptions += " ";
           extraLinkOptions += createFlags;
         }
-        const char* ext = gtgt->GetProperty("BUNDLE_EXTENSION");
+        cmProp ext = gtgt->GetProperty("BUNDLE_EXTENSION");
         if (ext) {
           buildSettings->AddAttribute("WRAPPER_EXTENSION",
-                                      this->CreateString(ext));
+                                      this->CreateString(*ext));
         }
         std::string plist = this->ComputeInfoPListLocation(gtgt);
         // Xcode will create the final version of Info.plist at build time,
@@ -2046,10 +2125,10 @@
         std::string fw_version = gtgt->GetFrameworkVersion();
         buildSettings->AddAttribute("FRAMEWORK_VERSION",
                                     this->CreateString(fw_version));
-        const char* ext = gtgt->GetProperty("BUNDLE_EXTENSION");
+        cmProp ext = gtgt->GetProperty("BUNDLE_EXTENSION");
         if (ext) {
           buildSettings->AddAttribute("WRAPPER_EXTENSION",
-                                      this->CreateString(ext));
+                                      this->CreateString(*ext));
         }
 
         std::string plist = this->ComputeInfoPListLocation(gtgt);
@@ -2085,10 +2164,10 @@
 
       // Handle bundles and normal executables separately.
       if (gtgt->GetPropertyAsBool("MACOSX_BUNDLE")) {
-        const char* ext = gtgt->GetProperty("BUNDLE_EXTENSION");
+        cmProp ext = gtgt->GetProperty("BUNDLE_EXTENSION");
         if (ext) {
           buildSettings->AddAttribute("WRAPPER_EXTENSION",
-                                      this->CreateString(ext));
+                                      this->CreateString(*ext));
         }
         std::string plist = this->ComputeInfoPListLocation(gtgt);
         // Xcode will create the final version of Info.plist at build time,
@@ -2283,7 +2362,7 @@
 
   // Add Fortran source format attribute if property is set.
   const char* format = nullptr;
-  const char* tgtfmt = gtgt->GetProperty("Fortran_FORMAT");
+  std::string const& tgtfmt = gtgt->GetSafeProperty("Fortran_FORMAT");
   switch (cmOutputConverter::GetFortranFormat(tgtfmt)) {
     case cmOutputConverter::FortranFormatFixed:
       format = "fixed";
@@ -2406,12 +2485,13 @@
   // Convert "XCODE_ATTRIBUTE_*" properties directly.
   {
     for (auto const& prop : gtgt->GetPropertyKeys()) {
-      if (prop.find("XCODE_ATTRIBUTE_") == 0) {
+      if (cmHasLiteralPrefix(prop, "XCODE_ATTRIBUTE_")) {
         std::string attribute = prop.substr(16);
         this->FilterConfigurationAttribute(configName, attribute);
         if (!attribute.empty()) {
+          std::string const& pr = gtgt->GetSafeProperty(prop);
           std::string processed = cmGeneratorExpression::Evaluate(
-            gtgt->GetProperty(prop), this->CurrentLocalGenerator, configName);
+            pr, this->CurrentLocalGenerator, configName);
           buildSettings->AddAttribute(attribute,
                                       this->CreateString(processed));
         }
@@ -2457,7 +2537,7 @@
   this->XCodeObjectMap[gtgt] = target;
 
   // Add source files without build rules for editing convenience.
-  if (gtgt->GetType() == cmStateEnums::UTILITY &&
+  if (gtgt->GetType() != cmStateEnums::GLOBAL_TARGET &&
       gtgt->GetName() != CMAKE_CHECK_BUILD_SYSTEM_TARGET) {
     std::vector<cmSourceFile*> sources;
     if (!gtgt->GetConfigCommonSourceFiles(sources)) {
@@ -2530,8 +2610,8 @@
 const char* cmGlobalXCodeGenerator::GetTargetFileType(
   cmGeneratorTarget* target)
 {
-  if (const char* e = target->GetProperty("XCODE_EXPLICIT_FILE_TYPE")) {
-    return e;
+  if (cmProp e = target->GetProperty("XCODE_EXPLICIT_FILE_TYPE")) {
+    return e->c_str();
   }
 
   switch (target->GetType()) {
@@ -2563,8 +2643,8 @@
 const char* cmGlobalXCodeGenerator::GetTargetProductType(
   cmGeneratorTarget* target)
 {
-  if (const char* e = target->GetProperty("XCODE_PRODUCT_TYPE")) {
-    return e;
+  if (cmProp e = target->GetProperty("XCODE_PRODUCT_TYPE")) {
+    return e->c_str();
   }
 
   switch (target->GetType()) {
@@ -2599,7 +2679,7 @@
 cmXCodeObject* cmGlobalXCodeGenerator::CreateXCodeTarget(
   cmGeneratorTarget* gtgt, cmXCodeObject* buildPhases)
 {
-  if (gtgt->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
+  if (!gtgt->IsInBuildSystem()) {
     return nullptr;
   }
   cmXCodeObject* target = this->CreateObject(cmXCodeObject::PBXNativeTarget);
@@ -2742,7 +2822,7 @@
     cmSystemTools::Error("Error no target on xobject\n");
     return;
   }
-  if (gt->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
+  if (!gt->IsInBuildSystem()) {
     return;
   }
 
@@ -2753,6 +2833,190 @@
     }
   }
 
+  // Separate libraries into ones that can be linked using "Link Binary With
+  // Libraries" build phase and the ones that can't. Only targets that build
+  // Apple bundles (.app, .framework, .bundle) can use this feature and only
+  // targets that represent actual libraries (static or dynamic, local or
+  // imported) not objects and not executables will be used. These are
+  // limitations imposed by CMake use-cases - otherwise a lot of things break.
+  // The rest will be linked using linker flags (OTHER_LDFLAGS setting in Xcode
+  // project).
+  std::map<std::string, std::vector<cmComputeLinkInformation::Item const*>>
+    configItemMap;
+  auto addToLinkerArguments =
+    [&configItemMap](const std::string& configName,
+                     cmComputeLinkInformation::Item const* libItemPtr) {
+      auto& linkVector = configItemMap[configName];
+      if (std::find_if(linkVector.begin(), linkVector.end(),
+                       [libItemPtr](cmComputeLinkInformation::Item const* p) {
+                         return p == libItemPtr;
+                       }) == linkVector.end()) {
+        linkVector.push_back(libItemPtr);
+      }
+    };
+  std::vector<cmComputeLinkInformation::Item const*> linkPhaseTargetVector;
+  std::map<std::string, std::vector<std::string>> targetConfigMap;
+  using ConfigItemPair =
+    std::pair<std::string, cmComputeLinkInformation::Item const*>;
+  std::map<std::string, std::vector<ConfigItemPair>> targetItemMap;
+  std::map<std::string, std::vector<std::string>> targetProductNameMap;
+  for (auto const& configName : this->CurrentConfigurationTypes) {
+    cmComputeLinkInformation* cli = gt->GetLinkInformation(configName);
+    if (!cli) {
+      continue;
+    }
+    for (auto const& libItem : cli->GetItems()) {
+      if (gt->IsBundleOnApple() &&
+          (gt->GetType() == cmStateEnums::EXECUTABLE ||
+           gt->GetType() == cmStateEnums::SHARED_LIBRARY ||
+           gt->GetType() == cmStateEnums::MODULE_LIBRARY ||
+           gt->GetType() == cmStateEnums::UNKNOWN_LIBRARY) &&
+          ((libItem.Target &&
+            (libItem.Target->GetType() == cmStateEnums::STATIC_LIBRARY ||
+             libItem.Target->GetType() == cmStateEnums::SHARED_LIBRARY ||
+             libItem.Target->GetType() == cmStateEnums::MODULE_LIBRARY)) ||
+           (!libItem.Target && libItem.IsPath))) {
+        // Add unique configuration name to target-config map for later
+        // checks
+        std::string libName;
+        if (libItem.Target) {
+          libName = libItem.Target->GetName();
+        } else {
+          libName = cmSystemTools::GetFilenameName(libItem.Value.Value);
+          const auto libExt = cmSystemTools::GetFilenameExtension(libName);
+          if (!IsLibraryExtension(libExt)) {
+            // Add this library item to a regular linker flag list
+            addToLinkerArguments(configName, &libItem);
+            continue;
+          }
+        }
+        auto& configVector = targetConfigMap[libName];
+        if (std::find(configVector.begin(), configVector.end(), configName) ==
+            configVector.end()) {
+          configVector.push_back(configName);
+        }
+        // Add a pair of config and item to target-item map
+        auto& itemVector = targetItemMap[libName];
+        itemVector.emplace_back(ConfigItemPair(configName, &libItem));
+        // Add product file-name to a lib-product map
+        auto productName = cmSystemTools::GetFilenameName(libItem.Value.Value);
+        auto& productVector = targetProductNameMap[libName];
+        if (std::find(productVector.begin(), productVector.end(),
+                      productName) == productVector.end()) {
+          productVector.push_back(productName);
+        }
+      } else {
+        // Add this library item to a regular linker flag list
+        addToLinkerArguments(configName, &libItem);
+      }
+    }
+  }
+
+  // Go through target library map and separate libraries that are linked
+  // in all configurations and produce only single product, from the rest.
+  // Only these will be linked through "Link Binary With Libraries" build
+  // phase.
+  for (auto const& targetLibConfigs : targetConfigMap) {
+    // Add this library to "Link Binary With Libraries" build phase if it's
+    // linked in all configurations and it has only one product name
+    auto& itemVector = targetItemMap[targetLibConfigs.first];
+    auto& productVector = targetProductNameMap[targetLibConfigs.first];
+    if (targetLibConfigs.second == this->CurrentConfigurationTypes &&
+        productVector.size() == 1) {
+      // Add this library to "Link Binary With Libraries" list
+      linkPhaseTargetVector.push_back(itemVector[0].second);
+    } else {
+      for (auto const& libItem : targetItemMap[targetLibConfigs.first]) {
+        // Add this library item to a regular linker flag list
+        addToLinkerArguments(libItem.first, libItem.second);
+      }
+    }
+  }
+
+  // Add libraries to "Link Binary With Libraries" build phase and collect
+  // their search paths. Xcode does not support per-configuration linking
+  // in this build phase so we don't have to do this for each configuration
+  // separately.
+  std::vector<std::string> linkSearchPaths;
+  for (auto const& libItem : linkPhaseTargetVector) {
+    // Add target output directory as a library search path
+    std::string linkDir;
+    if (libItem->Target) {
+      linkDir = cmSystemTools::GetParentDirectory(
+        libItem->Target->GetLocationForBuild());
+    } else {
+      linkDir = cmSystemTools::GetParentDirectory(libItem->Value.Value);
+    }
+    if (std::find(linkSearchPaths.begin(), linkSearchPaths.end(), linkDir) ==
+        linkSearchPaths.end()) {
+      linkSearchPaths.push_back(linkDir);
+    }
+    // Add target dependency
+    if (libItem->Target && !libItem->Target->IsImported()) {
+      for (auto const& configName : this->CurrentConfigurationTypes) {
+        target->AddDependTarget(configName, libItem->Target->GetName());
+      }
+    }
+    // Get the library target
+    auto* libTarget = FindXCodeTarget(libItem->Target);
+    cmXCodeObject* buildFile;
+    if (!libTarget) {
+      if (libItem->IsPath) {
+        // Get or create a direct file ref in the root project
+        auto it = this->ExternalLibRefs.find(libItem->Value.Value);
+        if (it == this->ExternalLibRefs.end()) {
+          buildFile = CreateXCodeBuildFileFromPath(libItem->Value.Value, gt,
+                                                   "", nullptr);
+          this->ExternalLibRefs.emplace(libItem->Value.Value, buildFile);
+        } else {
+          buildFile = it->second;
+        }
+      } else {
+        // Add this library item back to a regular linker flag list
+        for (const auto& conf : configItemMap) {
+          addToLinkerArguments(conf.first, libItem);
+        }
+        continue;
+      }
+    } else {
+      // Add the target output file as a build reference for other targets
+      // to link against
+      auto* fileRefObject = libTarget->GetObject("productReference");
+      if (!fileRefObject) {
+        // Add this library item back to a regular linker flag list
+        for (const auto& conf : configItemMap) {
+          addToLinkerArguments(conf.first, libItem);
+        }
+        continue;
+      }
+      auto it = FileRefToBuildFileMap.find(fileRefObject);
+      if (it == FileRefToBuildFileMap.end()) {
+        buildFile = this->CreateObject(cmXCodeObject::PBXBuildFile);
+        buildFile->AddAttribute("fileRef", fileRefObject);
+        FileRefToBuildFileMap[fileRefObject] = buildFile;
+      } else {
+        buildFile = it->second;
+      }
+    }
+    // Add this reference to current target
+    auto* buildPhases = target->GetObject("buildPhases");
+    if (!buildPhases) {
+      continue;
+    }
+    auto* frameworkBuildPhase =
+      buildPhases->GetObject(cmXCodeObject::PBXFrameworksBuildPhase);
+    if (!frameworkBuildPhase) {
+      continue;
+    }
+    auto* buildFiles = frameworkBuildPhase->GetObject("files");
+    if (!buildFiles) {
+      continue;
+    }
+    if (!buildFiles->HasObject(buildFile)) {
+      buildFiles->AddObject(buildFile);
+    }
+  }
+
   // Loop over configuration types and set per-configuration info.
   for (auto const& configName : this->CurrentConfigurationTypes) {
     {
@@ -2780,21 +3044,20 @@
     }
 
     // Compute the link library and directory information.
-    cmComputeLinkInformation* pcli = gt->GetLinkInformation(configName);
-    if (!pcli) {
+    cmComputeLinkInformation* cli = gt->GetLinkInformation(configName);
+    if (!cli) {
       continue;
     }
-    cmComputeLinkInformation& cli = *pcli;
 
     // Add dependencies directly on library files.
-    for (auto const& libDep : cli.GetDepends()) {
+    for (auto const& libDep : cli->GetDepends()) {
       target->AddDependLibrary(configName, libDep);
     }
 
     // add the library search paths
     {
       std::string linkDirs;
-      for (auto const& libDir : cli.GetDirectories()) {
+      for (auto const& libDir : cli->GetDirectories()) {
         if (!libDir.empty() && libDir != "/usr/lib") {
           // Now add the same one but append
           // $(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) to it:
@@ -2805,15 +3068,22 @@
           linkDirs += this->XCodeEscapePath(libDir);
         }
       }
+      // Add previously collected paths where to look for libraries
+      // that were added to "Link Binary With Libraries"
+      for (auto& linkDir : linkSearchPaths) {
+        linkDirs += " ";
+        linkDirs += this->XCodeEscapePath(linkDir);
+      }
       this->AppendBuildSettingAttribute(target, "LIBRARY_SEARCH_PATHS",
                                         linkDirs.c_str(), configName);
     }
 
-    // now add the link libraries
+    // now add the left-over link libraries
     {
       std::string linkLibs;
       const char* sep = "";
-      for (auto const& libName : cli.GetItems()) {
+      for (auto const& libItem : configItemMap[configName]) {
+        auto const& libName = *libItem;
         linkLibs += sep;
         sep = " ";
         if (libName.IsPath) {
@@ -2844,13 +3114,9 @@
       // end up with (empty anyhow) ZERO_CHECK, install, or test source
       // groups:
       //
-      if (gtgt->GetType() == cmStateEnums::GLOBAL_TARGET) {
-        continue;
-      }
-      if (gtgt->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
-        continue;
-      }
-      if (gtgt->GetName() == CMAKE_CHECK_BUILD_SYSTEM_TARGET) {
+      if (!gtgt->IsInBuildSystem() ||
+          gtgt->GetType() == cmStateEnums::GLOBAL_TARGET ||
+          gtgt->GetName() == CMAKE_CHECK_BUILD_SYSTEM_TARGET) {
         continue;
       }
 
@@ -2994,6 +3260,7 @@
   this->ClearXCodeObjects();
   this->RootObject = nullptr;
   this->MainGroupChildren = nullptr;
+  this->FrameworkGroup = nullptr;
   cmXCodeObject* group = this->CreateObject(cmXCodeObject::ATTRIBUTE_GROUP);
   group->AddAttribute("COPY_PHASE_STRIP", this->CreateString("NO"));
   cmXCodeObject* listObjs = this->CreateObject(cmXCodeObject::OBJECT_LIST);
@@ -3028,6 +3295,15 @@
   productGroup->AddAttribute("children", productGroupChildren);
   this->MainGroupChildren->AddObject(productGroup);
 
+  this->FrameworkGroup = this->CreateObject(cmXCodeObject::PBXGroup);
+  this->FrameworkGroup->AddAttribute("name", this->CreateString("Frameworks"));
+  this->FrameworkGroup->AddAttribute("sourceTree",
+                                     this->CreateString("<group>"));
+  cmXCodeObject* frameworkGroupChildren =
+    this->CreateObject(cmXCodeObject::OBJECT_LIST);
+  this->FrameworkGroup->AddAttribute("children", frameworkGroupChildren);
+  this->MainGroupChildren->AddObject(this->FrameworkGroup);
+
   this->RootObject = this->CreateObject(cmXCodeObject::PBXProject);
   this->RootObject->SetComment("Project object");
 
@@ -3104,11 +3380,19 @@
   if (archs.empty()) {
     // Tell Xcode to use NATIVE_ARCH instead of ARCHS.
     buildSettings->AddAttribute("ONLY_ACTIVE_ARCH", this->CreateString("YES"));
+    // When targeting macOS, use only the host architecture.
+    if (this->SystemName == "Darwin"_s &&
+        (!cmNonempty(sysroot) ||
+         cmSystemTools::LowerCase(sysroot).find("macos") !=
+           std::string::npos)) {
+      buildSettings->AddAttribute("ARCHS",
+                                  this->CreateString("$(NATIVE_ARCH_ACTUAL)"));
+    }
   } else {
     // Tell Xcode to use ARCHS (ONLY_ACTIVE_ARCH defaults to NO).
     buildSettings->AddAttribute("ARCHS", this->CreateString(archs));
   }
-  if (deploymentTarget && *deploymentTarget) {
+  if (cmNonempty(deploymentTarget)) {
     buildSettings->AddAttribute(GetDeploymentPlatform(root->GetMakefile()),
                                 this->CreateString(deploymentTarget));
   }
@@ -3135,18 +3419,24 @@
   std::string symroot = cmStrCat(root->GetCurrentBinaryDirectory(), "/build");
   buildSettings->AddAttribute("SYMROOT", this->CreateString(symroot));
 
+  // Inside a try_compile project, do not require signing on any platform.
+  if (this->CMakeInstance->GetIsInTryCompile()) {
+    buildSettings->AddAttribute("CODE_SIGNING_ALLOWED",
+                                this->CreateString("NO"));
+  }
+
   for (auto& config : configs) {
     cmXCodeObject* buildSettingsForCfg = this->CreateFlatClone(buildSettings);
 
     // Put this last so it can override existing settings
     // Convert "CMAKE_XCODE_ATTRIBUTE_*" variables directly.
     for (const auto& var : this->CurrentMakefile->GetDefinitions()) {
-      if (var.find("CMAKE_XCODE_ATTRIBUTE_") == 0) {
+      if (cmHasLiteralPrefix(var, "CMAKE_XCODE_ATTRIBUTE_")) {
         std::string attribute = var.substr(22);
         this->FilterConfigurationAttribute(config.first, attribute);
         if (!attribute.empty()) {
           std::string processed = cmGeneratorExpression::Evaluate(
-            this->CurrentMakefile->GetDefinition(var),
+            this->CurrentMakefile->GetSafeDefinition(var),
             this->CurrentLocalGenerator, config.first);
           buildSettingsForCfg->AddAttribute(attribute,
                                             this->CreateString(processed));
@@ -3197,14 +3487,14 @@
 void cmGlobalXCodeGenerator::ComputeArchitectures(cmMakefile* mf)
 {
   this->Architectures.clear();
-  const char* osxArch = mf->GetDefinition("CMAKE_OSX_ARCHITECTURES");
   const char* sysroot = mf->GetDefinition("CMAKE_OSX_SYSROOT");
-  if (osxArch && sysroot) {
-    cmExpandList(std::string(osxArch), this->Architectures);
+  if (sysroot) {
+    mf->GetDefExpandList("CMAKE_OSX_ARCHITECTURES", this->Architectures);
   }
 
   if (this->Architectures.empty()) {
-    // With no ARCHS we use ONLY_ACTIVE_ARCH.
+    // With no ARCHS we use ONLY_ACTIVE_ARCH and possibly a
+    // platform-specific default ARCHS placeholder value.
     // Look up the arch that Xcode chooses in this case.
     if (const char* arch = mf->GetDefinition("CMAKE_XCODE_ARCHS")) {
       this->ObjectDirArchDefault = arch;
@@ -3390,7 +3680,7 @@
   // collect all tests for the targets
   std::map<std::string, cmXCodeScheme::TestObjects> testables;
 
-  for (auto obj : this->XCodeObjects) {
+  for (const auto& obj : this->XCodeObjects) {
     if (obj->GetType() != cmXCodeObject::OBJECT ||
         obj->GetIsA() != cmXCodeObject::PBXNativeTarget) {
       continue;
@@ -3400,12 +3690,12 @@
       continue;
     }
 
-    const char* testee = obj->GetTarget()->GetProperty("XCTEST_TESTEE");
+    cmProp testee = obj->GetTarget()->GetProperty("XCTEST_TESTEE");
     if (!testee) {
       continue;
     }
 
-    testables[testee].push_back(obj);
+    testables[*testee].push_back(obj.get());
   }
 
   // generate scheme
@@ -3414,14 +3704,14 @@
   // Since the lowest available Xcode version for testing was 6.4,
   // I'm setting this as a limit then
   if (this->XcodeVersion >= 64) {
-    for (auto obj : this->XCodeObjects) {
+    for (const auto& obj : this->XCodeObjects) {
       if (obj->GetType() == cmXCodeObject::OBJECT &&
           (obj->GetIsA() == cmXCodeObject::PBXNativeTarget ||
            obj->GetIsA() == cmXCodeObject::PBXAggregateTarget) &&
           (root->GetMakefile()->GetCMakeInstance()->GetIsInTryCompile() ||
            obj->GetTarget()->GetPropertyAsBool("XCODE_GENERATE_SCHEME"))) {
         const std::string& targetName = obj->GetTarget()->GetName();
-        cmXCodeScheme schm(root, obj, testables[targetName],
+        cmXCodeScheme schm(root, obj.get(), testables[targetName],
                            this->CurrentConfigurationTypes,
                            this->XcodeVersion);
         schm.WriteXCodeSharedScheme(xcProjDir,
@@ -3460,6 +3750,8 @@
   if (this->XcodeVersion >= 100) {
     xout.Element("key", "BuildSystemType");
     xout.Element("string", "Original");
+    xout.Element("key", "DisableBuildSystemDeprecationWarning");
+    xout.Element("true");
   }
   if (hasGeneratedSchemes) {
     xout.Element("key",
@@ -3547,7 +3839,7 @@
 
 std::string cmGlobalXCodeGenerator::XCodeEscapePath(const std::string& p)
 {
-  if (p.find(' ') != std::string::npos) {
+  if (p.find_first_of(" []") != std::string::npos) {
     std::string t = cmStrCat('"', p, '"');
     return t;
   }
@@ -3693,15 +3985,14 @@
 
 bool cmGlobalXCodeGenerator::UseEffectivePlatformName(cmMakefile* mf) const
 {
-  const char* epnValue =
-    this->GetCMakeInstance()->GetState()->GetGlobalProperty(
-      "XCODE_EMIT_EFFECTIVE_PLATFORM_NAME");
+  cmProp epnValue = this->GetCMakeInstance()->GetState()->GetGlobalProperty(
+    "XCODE_EMIT_EFFECTIVE_PLATFORM_NAME");
 
   if (!epnValue) {
     return mf->PlatformIsAppleEmbedded();
   }
 
-  return cmIsOn(epnValue);
+  return cmIsOn(*epnValue);
 }
 
 bool cmGlobalXCodeGenerator::ShouldStripResourcePath(cmMakefile*) const
diff --git a/Source/cmGlobalXCodeGenerator.h b/Source/cmGlobalXCodeGenerator.h
index df68f80..7018de7 100644
--- a/Source/cmGlobalXCodeGenerator.h
+++ b/Source/cmGlobalXCodeGenerator.h
@@ -28,7 +28,7 @@
 /** \class cmGlobalXCodeGenerator
  * \brief Write a Unix makefiles.
  *
- * cmGlobalXCodeGenerator manages UNIX build process for a tree
+ * cmGlobalXCodeGenerator manages Xcode build process for a tree
  */
 class cmGlobalXCodeGenerator : public cmGlobalGenerator
 {
@@ -37,6 +37,10 @@
                          unsigned int version_number);
   static std::unique_ptr<cmGlobalGeneratorFactory> NewFactory();
 
+  cmGlobalXCodeGenerator(const cmGlobalXCodeGenerator&) = delete;
+  const cmGlobalXCodeGenerator& operator=(const cmGlobalXCodeGenerator&) =
+    delete;
+
   //! Get the name for the generator.
   std::string GetName() const override
   {
@@ -105,6 +109,7 @@
 
   bool ShouldStripResourcePath(cmMakefile*) const override;
 
+  bool SetSystemName(std::string const& s, cmMakefile* mf) override;
   bool SetGeneratorToolset(std::string const& ts, bool build,
                            cmMakefile* mf) override;
   void AppendFlag(std::string& flags, std::string const& flag) const;
@@ -199,10 +204,10 @@
                                                   cmGeneratorTarget* target,
                                                   const std::string& lang,
                                                   cmSourceFile* sf);
-  cmXCodeObject* CreateXCodeSourceFileFromPath(const std::string& fullpath,
-                                               cmGeneratorTarget* target,
-                                               const std::string& lang,
-                                               cmSourceFile* sf);
+  cmXCodeObject* CreateXCodeBuildFileFromPath(const std::string& fullpath,
+                                              cmGeneratorTarget* target,
+                                              const std::string& lang,
+                                              cmSourceFile* sf);
   cmXCodeObject* CreateXCodeFileReference(cmSourceFile* sf,
                                           cmGeneratorTarget* target);
   cmXCodeObject* CreateXCodeSourceFile(cmLocalGenerator* gen, cmSourceFile* sf,
@@ -249,7 +254,7 @@
   unsigned int XcodeVersion;
   std::string VersionString;
   std::set<std::string> XCodeObjectIDs;
-  std::vector<cmXCodeObject*> XCodeObjects;
+  std::vector<std::unique_ptr<cmXCodeObject>> XCodeObjects;
   cmXCodeObject* RootObject;
 
 private:
@@ -273,10 +278,11 @@
   void ComputeArchitectures(cmMakefile* mf);
   void ComputeObjectDirArch(cmMakefile* mf);
 
-  void addObject(cmXCodeObject* obj);
+  void addObject(std::unique_ptr<cmXCodeObject> obj);
   std::string PostBuildMakeTarget(std::string const& tName,
                                   std::string const& configName);
   cmXCodeObject* MainGroupChildren;
+  cmXCodeObject* FrameworkGroup;
   cmMakefile* CurrentMakefile;
   cmLocalGenerator* CurrentLocalGenerator;
   std::vector<std::string> CurrentConfigurationTypes;
@@ -290,12 +296,16 @@
   std::map<std::string, cmXCodeObject*> GroupNameMap;
   std::map<std::string, cmXCodeObject*> TargetGroup;
   std::map<std::string, cmXCodeObject*> FileRefs;
+  std::map<std::string, cmXCodeObject*> ExternalLibRefs;
   std::map<cmGeneratorTarget const*, cmXCodeObject*> XCodeObjectMap;
+  std::map<cmXCodeObject*, cmXCodeObject*> FileRefToBuildFileMap;
   std::vector<std::string> Architectures;
   std::string ObjectDirArchDefault;
   std::string ObjectDirArch;
+  std::string SystemName;
   std::string GeneratorToolset;
   std::map<cmGeneratorTarget const*, size_t> TargetOrderIndex;
+  std::vector<std::string> EnabledLangs;
 };
 
 #endif
diff --git a/Source/cmGraphVizWriter.cxx b/Source/cmGraphVizWriter.cxx
index e03b2ca..570f4ea 100644
--- a/Source/cmGraphVizWriter.cxx
+++ b/Source/cmGraphVizWriter.cxx
@@ -125,14 +125,6 @@
 cmGraphVizWriter::~cmGraphVizWriter()
 {
   this->WriteFooter(this->GlobalFileStream);
-
-  for (auto& fileStream : this->PerTargetFileStreams) {
-    this->WriteFooter(*fileStream.second);
-  }
-
-  for (auto& fileStream : this->TargetDependersFileStreams) {
-    this->WriteFooter(*fileStream.second);
-  }
 }
 
 void cmGraphVizWriter::VisitGraph(std::string const&)
@@ -151,20 +143,10 @@
   ++NextNodeId;
 
   this->WriteNode(this->GlobalFileStream, item);
-
-  if (this->GeneratePerTarget) {
-    this->CreateTargetFile(this->PerTargetFileStreams, item);
-  }
-
-  if (this->GenerateDependers) {
-    this->CreateTargetFile(this->TargetDependersFileStreams, item,
-                           ".dependers");
-  }
 }
 
-void cmGraphVizWriter::CreateTargetFile(FileStreamMap& fileStreamMap,
-                                        cmLinkItem const& item,
-                                        std::string const& fileNameSuffix)
+std::unique_ptr<cmGeneratedFileStream> cmGraphVizWriter::CreateTargetFile(
+  cmLinkItem const& item, std::string const& fileNameSuffix)
 {
   auto const pathSafeItemName = PathSafeString(item.AsStr());
   auto const perTargetFileName =
@@ -175,7 +157,7 @@
   this->WriteHeader(*perTargetFileStream, item.AsStr());
   this->WriteNode(*perTargetFileStream, item);
 
-  fileStreamMap.emplace(item.AsStr(), std::move(perTargetFileStream));
+  return perTargetFileStream;
 }
 
 void cmGraphVizWriter::OnDirectLink(cmLinkItem const& depender,
@@ -260,7 +242,7 @@
   do {                                                                        \
     const char* value = mf.GetDefinition(cmakeDefinition);                    \
     if (value) {                                                              \
-      (var) = mf.IsOn(cmakeDefinition);                                       \
+      (var) = cmIsOn(value);                                                  \
     }                                                                         \
   } while (false)
 
@@ -323,13 +305,12 @@
   }
 
   if (this->GeneratePerTarget) {
-    WritePerTargetConnections<DependeesDir>(PerTargetConnections,
-                                            PerTargetFileStreams);
+    WritePerTargetConnections<DependeesDir>(PerTargetConnections);
   }
 
   if (this->GenerateDependers) {
     WritePerTargetConnections<DependersDir>(TargetDependersConnections,
-                                            TargetDependersFileStreams);
+                                            ".dependers");
   }
 }
 
@@ -368,7 +349,7 @@
 
 template <typename DirFunc>
 void cmGraphVizWriter::WritePerTargetConnections(
-  const ConnectionsMap& connections, const FileStreamMap& streams)
+  const ConnectionsMap& connections, const std::string& fileNameSuffix)
 {
   // the per target connections must be extended by indirect dependencies
   ConnectionsMap extendedConnections;
@@ -387,7 +368,9 @@
     }
 
     const Connections& cons = conPerTarget.second;
-    auto fileStream = streams.at(rootItem.AsStr()).get();
+
+    std::unique_ptr<cmGeneratedFileStream> fileStream =
+      this->CreateTargetFile(rootItem, fileNameSuffix);
 
     for (const Connection& con : cons) {
       const cmLinkItem& src = DirFunc::src(con);
@@ -395,6 +378,8 @@
       this->WriteNode(*fileStream, con.dst);
       this->WriteConnection(*fileStream, src, dst, con.scopeType);
     }
+
+    this->WriteFooter(*fileStream);
   }
 }
 
@@ -402,13 +387,13 @@
                                    const std::string& name)
 {
   auto const escapedGraphName = EscapeForDotFile(name);
-  fs << "digraph \"" << escapedGraphName << "\" {" << std::endl;
-  fs << this->GraphHeader << std::endl;
+  fs << "digraph \"" << escapedGraphName << "\" {\n"
+     << this->GraphHeader << '\n';
 }
 
 void cmGraphVizWriter::WriteFooter(cmGeneratedFileStream& fs)
 {
-  fs << "}" << std::endl;
+  fs << "}\n";
 }
 
 void cmGraphVizWriter::WriteLegend(cmGeneratedFileStream& fs)
@@ -416,52 +401,46 @@
   // Note that the subgraph name must start with "cluster", as done here, to
   // make Graphviz layout engines do the right thing and keep the nodes
   // together.
-  fs << "subgraph clusterLegend {" << std::endl;
-  fs << "  label = \"Legend\";" << std::endl;
-  // Set the color of the box surrounding the legend.
-  fs << "  color = black;" << std::endl;
-  // We use invisible edges just to enforce the layout.
-  fs << "  edge [ style = invis ];" << std::endl;
-
-  // Nodes.
-  fs << "  legendNode0 [ label = \"Executable\", shape = "
-     << GRAPHVIZ_NODE_SHAPE_EXECUTABLE << " ];" << std::endl;
-
-  fs << "  legendNode1 [ label = \"Static Library\", shape = "
-     << GRAPHVIZ_NODE_SHAPE_LIBRARY_STATIC << " ];" << std::endl;
-  fs << "  legendNode2 [ label = \"Shared Library\", shape = "
-     << GRAPHVIZ_NODE_SHAPE_LIBRARY_SHARED << " ];" << std::endl;
-  fs << "  legendNode3 [ label = \"Module Library\", shape = "
-     << GRAPHVIZ_NODE_SHAPE_LIBRARY_MODULE << " ];" << std::endl;
-
-  fs << "  legendNode4 [ label = \"Interface Library\", shape = "
-     << GRAPHVIZ_NODE_SHAPE_LIBRARY_INTERFACE << " ];" << std::endl;
-  fs << "  legendNode5 [ label = \"Object Library\", shape = "
-     << GRAPHVIZ_NODE_SHAPE_LIBRARY_OBJECT << " ];" << std::endl;
-  fs << "  legendNode6 [ label = \"Unknown Library\", shape = "
-     << GRAPHVIZ_NODE_SHAPE_LIBRARY_UNKNOWN << " ];" << std::endl;
-
-  fs << "  legendNode7 [ label = \"Custom Target\", shape = "
-     << GRAPHVIZ_NODE_SHAPE_UTILITY << " ];" << std::endl;
-
-  // Edges.
-  // Some of those are dummy (invisible) edges to enforce a layout.
-  fs << "  legendNode0 -> legendNode1 [ style = " << GRAPHVIZ_EDGE_STYLE_PUBLIC
-     << " ];" << std::endl;
-  fs << "  legendNode0 -> legendNode2 [ style = " << GRAPHVIZ_EDGE_STYLE_PUBLIC
-     << " ];" << std::endl;
-  fs << "  legendNode0 -> legendNode3;" << std::endl;
-
-  fs << "  legendNode1 -> legendNode4 [ label = \"Interface\", style = "
-     << GRAPHVIZ_EDGE_STYLE_INTERFACE << " ];" << std::endl;
-  fs << "  legendNode2 -> legendNode5 [ label = \"Private\", style = "
-     << GRAPHVIZ_EDGE_STYLE_PRIVATE << " ];" << std::endl;
-  fs << "  legendNode3 -> legendNode6 [ style = " << GRAPHVIZ_EDGE_STYLE_PUBLIC
-     << " ];" << std::endl;
-
-  fs << "  legendNode0 -> legendNode7;" << std::endl;
-
-  fs << "}" << std::endl;
+  /* clang-format off */
+  fs << "subgraph clusterLegend {\n"
+        "  label = \"Legend\";\n"
+        // Set the color of the box surrounding the legend.
+        "  color = black;\n"
+        // We use invisible edges just to enforce the layout.
+        "  edge [ style = invis ];\n"
+        // Nodes.
+        "  legendNode0 [ label = \"Executable\", shape = "
+     << GRAPHVIZ_NODE_SHAPE_EXECUTABLE << " ];\n"
+        "  legendNode1 [ label = \"Static Library\", shape = "
+     << GRAPHVIZ_NODE_SHAPE_LIBRARY_STATIC << " ];\n"
+        "  legendNode2 [ label = \"Shared Library\", shape = "
+     << GRAPHVIZ_NODE_SHAPE_LIBRARY_SHARED << " ];\n"
+        "  legendNode3 [ label = \"Module Library\", shape = "
+     << GRAPHVIZ_NODE_SHAPE_LIBRARY_MODULE << " ];\n"
+        "  legendNode4 [ label = \"Interface Library\", shape = "
+     << GRAPHVIZ_NODE_SHAPE_LIBRARY_INTERFACE << " ];\n"
+        "  legendNode5 [ label = \"Object Library\", shape = "
+     << GRAPHVIZ_NODE_SHAPE_LIBRARY_OBJECT << " ];\n"
+        "  legendNode6 [ label = \"Unknown Library\", shape = "
+     << GRAPHVIZ_NODE_SHAPE_LIBRARY_UNKNOWN << " ];\n"
+        "  legendNode7 [ label = \"Custom Target\", shape = "
+     << GRAPHVIZ_NODE_SHAPE_UTILITY << " ];\n"
+        // Edges.
+        // Some of those are dummy (invisible) edges to enforce a layout.
+        "  legendNode0 -> legendNode1 [ style = "
+     << GRAPHVIZ_EDGE_STYLE_PUBLIC << " ];\n"
+        "  legendNode0 -> legendNode2 [ style = "
+     << GRAPHVIZ_EDGE_STYLE_PUBLIC << " ];\n"
+        "  legendNode0 -> legendNode3;\n"
+        "  legendNode1 -> legendNode4 [ label = \"Interface\", style = "
+     << GRAPHVIZ_EDGE_STYLE_INTERFACE << " ];\n"
+        "  legendNode2 -> legendNode5 [ label = \"Private\", style = "
+     << GRAPHVIZ_EDGE_STYLE_PRIVATE << " ];\n"
+        "  legendNode3 -> legendNode6 [ style = "
+     << GRAPHVIZ_EDGE_STYLE_PUBLIC << " ];\n"
+        "  legendNode0 -> legendNode7;\n"
+        "}\n";
+  /* clang-format off */
 }
 
 void cmGraphVizWriter::WriteNode(cmGeneratedFileStream& fs,
@@ -474,7 +453,7 @@
   auto const escapedLabel = EscapeForDotFile(itemNameWithAliases);
 
   fs << "    \"" << nodeName << "\" [ label = \"" << escapedLabel
-     << "\", shape = " << getShapeForTarget(item) << " ];" << std::endl;
+     << "\", shape = " << getShapeForTarget(item) << " ];\n";
 }
 
 void cmGraphVizWriter::WriteConnection(cmGeneratedFileStream& fs,
@@ -486,11 +465,9 @@
   auto const& dependeeName = dependee.AsStr();
 
   fs << "    \"" << this->NodeNames[dependerName] << "\" -> \""
-     << this->NodeNames[dependeeName] << "\" ";
-
-  fs << edgeStyle;
-
-  fs << " // " << dependerName << " -> " << dependeeName << std::endl;
+     << this->NodeNames[dependeeName] << "\" "
+     << edgeStyle
+     << " // " << dependerName << " -> " << dependeeName << '\n';
 }
 
 bool cmGraphVizWriter::ItemExcluded(cmLinkItem const& item)
@@ -506,9 +483,9 @@
   }
 
   if (item.Target->GetType() == cmStateEnums::UTILITY) {
-    if ((itemName.find("Nightly") == 0) ||
-        (itemName.find("Continuous") == 0) ||
-        (itemName.find("Experimental") == 0)) {
+    if (cmHasLiteralPrefix(itemName, "Nightly") ||
+        cmHasLiteralPrefix(itemName, "Continuous") ||
+        cmHasLiteralPrefix(itemName, "Experimental")) {
       return true;
     }
   }
diff --git a/Source/cmGraphVizWriter.h b/Source/cmGraphVizWriter.h
index 9766068..d1300ac 100644
--- a/Source/cmGraphVizWriter.h
+++ b/Source/cmGraphVizWriter.h
@@ -46,9 +46,6 @@
   void Write();
 
 private:
-  using FileStreamMap =
-    std::map<std::string, std::unique_ptr<cmGeneratedFileStream>>;
-
   struct Connection
   {
     Connection(cmLinkItem s, cmLinkItem d, std::string scope)
@@ -76,8 +73,8 @@
 
   void WriteNode(cmGeneratedFileStream& fs, cmLinkItem const& item);
 
-  void CreateTargetFile(FileStreamMap& fileStreamMap, cmLinkItem const& target,
-                        std::string const& fileNameSuffix = "");
+  std::unique_ptr<cmGeneratedFileStream> CreateTargetFile(
+    cmLinkItem const& target, std::string const& fileNameSuffix = "");
 
   void WriteConnection(cmGeneratedFileStream& fs,
                        cmLinkItem const& dependerTargetName,
@@ -95,7 +92,7 @@
 
   template <typename DirFunc>
   void WritePerTargetConnections(const ConnectionsMap& connections,
-                                 const FileStreamMap& streams);
+                                 const std::string& fileNameSuffix = "");
 
   bool ItemExcluded(cmLinkItem const& item);
   bool ItemNameFilteredOut(std::string const& itemName);
@@ -111,8 +108,6 @@
 
   std::string FileName;
   cmGeneratedFileStream GlobalFileStream;
-  FileStreamMap PerTargetFileStreams;
-  FileStreamMap TargetDependersFileStreams;
 
   ConnectionsMap PerTargetConnections;
   ConnectionsMap TargetDependersConnections;
diff --git a/Source/cmIfCommand.cxx b/Source/cmIfCommand.cxx
index 290e064..5808f90 100644
--- a/Source/cmIfCommand.cxx
+++ b/Source/cmIfCommand.cxx
@@ -7,8 +7,7 @@
 
 #include <cm/memory>
 #include <cm/string_view>
-
-#include "cm_static_string_view.hxx"
+#include <cmext/string_view>
 
 #include "cmConditionEvaluator.h"
 #include "cmExecutionStatus.h"
diff --git a/Source/cmIncludeCommand.cxx b/Source/cmIncludeCommand.cxx
index 14264f4..ae801bb 100644
--- a/Source/cmIncludeCommand.cxx
+++ b/Source/cmIncludeCommand.cxx
@@ -2,7 +2,9 @@
    file Copyright.txt or https://cmake.org/licensing for details.  */
 #include "cmIncludeCommand.h"
 
+#include <map>
 #include <sstream>
+#include <utility>
 
 #include "cmExecutionStatus.h"
 #include "cmGlobalGenerator.h"
@@ -16,6 +18,11 @@
 bool cmIncludeCommand(std::vector<std::string> const& args,
                       cmExecutionStatus& status)
 {
+  static std::map<std::string, cmPolicies::PolicyID> DeprecatedModules;
+  if (DeprecatedModules.empty()) {
+    DeprecatedModules["Documentation"] = cmPolicies::CMP0106;
+  }
+
   if (args.empty() || args.size() > 4) {
     status.SetError("called with wrong number of arguments.  "
                     "include() only takes one file.");
@@ -65,9 +72,35 @@
   }
 
   if (!cmSystemTools::FileIsFullPath(fname)) {
+    bool system = false;
     // Not a path. Maybe module.
     std::string module = cmStrCat(fname, ".cmake");
-    std::string mfile = status.GetMakefile().GetModulesFile(module);
+    std::string mfile = status.GetMakefile().GetModulesFile(module, system);
+
+    if (system) {
+      auto ModulePolicy = DeprecatedModules.find(fname);
+      if (ModulePolicy != DeprecatedModules.end()) {
+        cmPolicies::PolicyStatus PolicyStatus =
+          status.GetMakefile().GetPolicyStatus(ModulePolicy->second);
+        switch (PolicyStatus) {
+          case cmPolicies::WARN: {
+            status.GetMakefile().IssueMessage(
+              MessageType::AUTHOR_WARNING,
+              cmStrCat(cmPolicies::GetPolicyWarning(ModulePolicy->second),
+                       "\n"));
+            CM_FALLTHROUGH;
+          }
+          case cmPolicies::OLD:
+            break;
+          case cmPolicies::REQUIRED_IF_USED:
+          case cmPolicies::REQUIRED_ALWAYS:
+          case cmPolicies::NEW:
+            mfile = "";
+            break;
+        }
+      }
+    }
+
     if (!mfile.empty()) {
       fname = mfile;
     }
diff --git a/Source/cmInstallCommand.cxx b/Source/cmInstallCommand.cxx
index d669ed7..83609e2 100644
--- a/Source/cmInstallCommand.cxx
+++ b/Source/cmInstallCommand.cxx
@@ -8,11 +8,10 @@
 #include <utility>
 
 #include <cm/memory>
+#include <cmext/string_view>
 
 #include "cmsys/Glob.hxx"
 
-#include "cm_static_string_view.hxx"
-
 #include "cmArgumentParser.h"
 #include "cmExecutionStatus.h"
 #include "cmExportSet.h"
@@ -29,6 +28,7 @@
 #include "cmMakefile.h"
 #include "cmMessageType.h"
 #include "cmPolicies.h"
+#include "cmProperty.h"
 #include "cmStateTypes.h"
 #include "cmStringAlgorithms.h"
 #include "cmSubcommandTable.h"
@@ -661,7 +661,6 @@
         // Nothing to do. An INTERFACE_LIBRARY can be installed, but the
         // only effect of that is to make it exportable. It installs no
         // other files itself.
-        break;
       default:
         // This should never happen due to the above type check.
         // Ignore the case.
@@ -680,9 +679,9 @@
     }
 
     if (createInstallGeneratorsForTargetFileSets && !namelinkOnly) {
-      const char* files = target.GetProperty("PRIVATE_HEADER");
-      if ((files) && (*files)) {
-        std::vector<std::string> relFiles = cmExpandedList(files);
+      cmProp files = target.GetProperty("PRIVATE_HEADER");
+      if (cmNonempty(files)) {
+        std::vector<std::string> relFiles = cmExpandedList(*files);
         std::vector<std::string> absFiles;
         if (!helper.MakeFilesFullPath("PRIVATE_HEADER", relFiles, absFiles)) {
           return false;
@@ -703,8 +702,8 @@
       }
 
       files = target.GetProperty("PUBLIC_HEADER");
-      if ((files) && (*files)) {
-        std::vector<std::string> relFiles = cmExpandedList(files);
+      if (cmNonempty(files)) {
+        std::vector<std::string> relFiles = cmExpandedList(*files);
         std::vector<std::string> absFiles;
         if (!helper.MakeFilesFullPath("PUBLIC_HEADER", relFiles, absFiles)) {
           return false;
@@ -725,8 +724,8 @@
       }
 
       files = target.GetProperty("RESOURCE");
-      if ((files) && (*files)) {
-        std::vector<std::string> relFiles = cmExpandedList(files);
+      if (cmNonempty(files)) {
+        std::vector<std::string> relFiles = cmExpandedList(*files);
         std::vector<std::string> absFiles;
         if (!helper.MakeFilesFullPath("RESOURCE", relFiles, absFiles)) {
           return false;
@@ -1158,7 +1157,7 @@
     } else if (doing == DoingRegex) {
       literal_args += " REGEX \"";
 // Match rules are case-insensitive on some platforms.
-#if defined(_WIN32) || defined(__APPLE__) || defined(__CYGWIN__)
+#if defined(_WIN32) || defined(__APPLE__)
       std::string regex = cmSystemTools::LowerCase(args[i]);
 #else
       std::string regex = args[i];
diff --git a/Source/cmInstallCommandArguments.cxx b/Source/cmInstallCommandArguments.cxx
index 31ba63f..a034689 100644
--- a/Source/cmInstallCommandArguments.cxx
+++ b/Source/cmInstallCommandArguments.cxx
@@ -4,7 +4,7 @@
 
 #include <utility>
 
-#include "cm_static_string_view.hxx"
+#include <cmext/string_view>
 
 #include "cmRange.h"
 #include "cmSystemTools.h"
diff --git a/Source/cmInstallExportGenerator.cxx b/Source/cmInstallExportGenerator.cxx
index 2c53a28..6e3508c 100644
--- a/Source/cmInstallExportGenerator.cxx
+++ b/Source/cmInstallExportGenerator.cxx
@@ -7,6 +7,8 @@
 #include <sstream>
 #include <utility>
 
+#include <cm/memory>
+
 #ifndef CMAKE_BOOTSTRAP
 #  include "cmExportInstallAndroidMKGenerator.h"
 #endif
@@ -33,18 +35,15 @@
 {
   if (android) {
 #ifndef CMAKE_BOOTSTRAP
-    this->EFGen = new cmExportInstallAndroidMKGenerator(this);
+    this->EFGen = cm::make_unique<cmExportInstallAndroidMKGenerator>(this);
 #endif
   } else {
-    this->EFGen = new cmExportInstallFileGenerator(this);
+    this->EFGen = cm::make_unique<cmExportInstallFileGenerator>(this);
   }
   exportSet->AddInstallation(this);
 }
 
-cmInstallExportGenerator::~cmInstallExportGenerator()
-{
-  delete this->EFGen;
-}
+cmInstallExportGenerator::~cmInstallExportGenerator() = default;
 
 bool cmInstallExportGenerator::Compute(cmLocalGenerator* lg)
 {
diff --git a/Source/cmInstallExportGenerator.h b/Source/cmInstallExportGenerator.h
index cf28b35..43dd00d 100644
--- a/Source/cmInstallExportGenerator.h
+++ b/Source/cmInstallExportGenerator.h
@@ -7,6 +7,7 @@
 
 #include <cstddef>
 #include <iosfwd>
+#include <memory>
 #include <string>
 #include <vector>
 
@@ -30,8 +31,12 @@
                            bool exclude_from_all, std::string filename,
                            std::string name_space, bool exportOld,
                            bool android);
+  cmInstallExportGenerator(const cmInstallExportGenerator&) = delete;
   ~cmInstallExportGenerator() override;
 
+  cmInstallExportGenerator& operator=(const cmInstallExportGenerator&) =
+    delete;
+
   cmExportSet* GetExportSet() { return this->ExportSet; }
 
   bool Compute(cmLocalGenerator* lg) override;
@@ -61,7 +66,7 @@
 
   std::string TempDir;
   std::string MainImportFile;
-  cmExportInstallFileGenerator* EFGen;
+  std::unique_ptr<cmExportInstallFileGenerator> EFGen;
 };
 
 #endif
diff --git a/Source/cmInstallTargetGenerator.cxx b/Source/cmInstallTargetGenerator.cxx
index e05daa8..178d5df 100644
--- a/Source/cmInstallTargetGenerator.cxx
+++ b/Source/cmInstallTargetGenerator.cxx
@@ -18,6 +18,7 @@
 #include "cmMessageType.h"
 #include "cmOutputConverter.h"
 #include "cmPolicies.h"
+#include "cmProperty.h"
 #include "cmStateTypes.h"
 #include "cmStringAlgorithms.h"
 #include "cmSystemTools.h"
@@ -133,8 +134,10 @@
         cmMakefile const* mf = this->Target->Target->GetMakefile();
 
         // Get App Bundle Extension
-        const char* ext = this->Target->GetProperty("BUNDLE_EXTENSION");
-        if (!ext) {
+        std::string ext;
+        if (cmProp p = this->Target->GetProperty("BUNDLE_EXTENSION")) {
+          ext = *p;
+        } else {
           ext = "app";
         }
 
diff --git a/Source/cmInstalledFile.cxx b/Source/cmInstalledFile.cxx
index a65ae03..32395d1 100644
--- a/Source/cmInstalledFile.cxx
+++ b/Source/cmInstalledFile.cxx
@@ -42,7 +42,8 @@
 }
 
 void cmInstalledFile::SetProperty(cmMakefile const* mf,
-                                  const std::string& prop, const char* value)
+                                  const std::string& prop,
+                                  const std::string& value)
 {
   this->RemoveProperty(prop);
   this->AppendProperty(mf, prop, value);
@@ -50,7 +51,8 @@
 
 void cmInstalledFile::AppendProperty(cmMakefile const* mf,
                                      const std::string& prop,
-                                     const char* value, bool /*asString*/)
+                                     const std::string& value,
+                                     bool /*asString*/)
 {
   cmListFileBacktrace backtrace = mf->GetBacktrace();
   cmGeneratorExpression ge(backtrace);
diff --git a/Source/cmInstalledFile.h b/Source/cmInstalledFile.h
index 698151e..07f7081 100644
--- a/Source/cmInstalledFile.h
+++ b/Source/cmInstalledFile.h
@@ -49,10 +49,10 @@
   void RemoveProperty(const std::string& prop);
 
   void SetProperty(cmMakefile const* mf, const std::string& prop,
-                   const char* value);
+                   const std::string& value);
 
   void AppendProperty(cmMakefile const* mf, const std::string& prop,
-                      const char* value, bool asString = false);
+                      const std::string& value, bool asString = false);
 
   bool HasProperty(const std::string& prop) const;
 
diff --git a/Source/cmJsonObjects.cxx b/Source/cmJsonObjects.cxx
index dd36386..3a2e3be 100644
--- a/Source/cmJsonObjects.cxx
+++ b/Source/cmJsonObjects.cxx
@@ -28,6 +28,7 @@
 #include "cmLinkLineComputer.h"
 #include "cmLocalGenerator.h"
 #include "cmMakefile.h"
+#include "cmProperty.h"
 #include "cmPropertyMap.h"
 #include "cmSourceFile.h"
 #include "cmState.h"
@@ -50,11 +51,7 @@
     return configurations;
   }
 
-  makefiles[0]->GetConfigurations(configurations);
-  if (configurations.empty()) {
-    configurations.emplace_back();
-  }
-  return configurations;
+  return makefiles[0]->GetGeneratorConfigs(cmMakefile::IncludeEmptyConfig);
 }
 
 bool hasString(const Json::Value& v, const std::string& s)
@@ -90,7 +87,8 @@
 
       const std::string startOfFile = lf.substr(0, cmakeRootDir.size());
       const bool isInternal = (startOfFile == cmakeRootDir);
-      const bool isTemporary = !isInternal && (lf.find(buildDir + '/') == 0);
+      const bool isTemporary =
+        !isInternal && (cmHasPrefix(lf, buildDir + '/'));
 
       std::string toAdd = lf;
       if (!sourceDir.empty()) {
@@ -274,14 +272,14 @@
 
       std::string compileFlags = ld.Flags;
       const std::string COMPILE_FLAGS("COMPILE_FLAGS");
-      if (const char* cflags = file->GetProperty(COMPILE_FLAGS)) {
+      if (cmProp cflags = file->GetProperty(COMPILE_FLAGS)) {
         lg->AppendFlags(compileFlags,
-                        genexInterpreter.Evaluate(cflags, COMPILE_FLAGS));
+                        genexInterpreter.Evaluate(*cflags, COMPILE_FLAGS));
       }
       const std::string COMPILE_OPTIONS("COMPILE_OPTIONS");
-      if (const char* coptions = file->GetProperty(COMPILE_OPTIONS)) {
+      if (cmProp coptions = file->GetProperty(COMPILE_OPTIONS)) {
         lg->AppendCompileOptions(
-          compileFlags, genexInterpreter.Evaluate(coptions, COMPILE_OPTIONS));
+          compileFlags, genexInterpreter.Evaluate(*coptions, COMPILE_OPTIONS));
       }
       fileData.Flags = compileFlags;
 
@@ -289,9 +287,9 @@
       std::vector<std::string> includes;
 
       const std::string INCLUDE_DIRECTORIES("INCLUDE_DIRECTORIES");
-      if (const char* cincludes = file->GetProperty(INCLUDE_DIRECTORIES)) {
+      if (cmProp cincludes = file->GetProperty(INCLUDE_DIRECTORIES)) {
         const std::string& evaluatedIncludes =
-          genexInterpreter.Evaluate(cincludes, INCLUDE_DIRECTORIES);
+          genexInterpreter.Evaluate(*cincludes, INCLUDE_DIRECTORIES);
         lg->AppendIncludeDirectories(includes, evaluatedIncludes, *file);
 
         for (const auto& include : includes) {
@@ -308,17 +306,17 @@
 
       const std::string COMPILE_DEFINITIONS("COMPILE_DEFINITIONS");
       std::set<std::string> defines;
-      if (const char* defs = file->GetProperty(COMPILE_DEFINITIONS)) {
+      if (cmProp defs = file->GetProperty(COMPILE_DEFINITIONS)) {
         lg->AppendDefines(
-          defines, genexInterpreter.Evaluate(defs, COMPILE_DEFINITIONS));
+          defines, genexInterpreter.Evaluate(*defs, COMPILE_DEFINITIONS));
       }
 
       const std::string defPropName =
         "COMPILE_DEFINITIONS_" + cmSystemTools::UpperCase(config);
-      if (const char* config_defs = file->GetProperty(defPropName)) {
+      if (cmProp config_defs = file->GetProperty(defPropName)) {
         lg->AppendDefines(
           defines,
-          genexInterpreter.Evaluate(config_defs, COMPILE_DEFINITIONS));
+          genexInterpreter.Evaluate(*config_defs, COMPILE_DEFINITIONS));
       }
 
       defines.insert(ld.Defines.begin(), ld.Defines.end());
diff --git a/Source/cmJsonObjects.h b/Source/cmJsonObjects.h
index 64291cc..2fd4b26 100644
--- a/Source/cmJsonObjects.h
+++ b/Source/cmJsonObjects.h
@@ -8,7 +8,7 @@
 #include <string>
 #include <vector>
 
-#include "cm_jsoncpp_value.h"
+#include <cm3p/json/value.h>
 
 class cmake;
 class cmGlobalGenerator;
diff --git a/Source/cmLinkItem.h b/Source/cmLinkItem.h
index 0ea25c0..3d92935 100644
--- a/Source/cmLinkItem.h
+++ b/Source/cmLinkItem.h
@@ -10,7 +10,8 @@
 #include <string>
 #include <vector>
 
-#include "cmAlgorithms.h"
+#include <cmext/algorithm>
+
 #include "cmListFileCache.h"
 #include "cmSystemTools.h"
 #include "cmTargetLinkLibraryType.h"
@@ -53,6 +54,9 @@
   // Libraries linked directly in other configurations.
   // Needed only for OLD behavior of CMP0003.
   std::vector<cmLinkItem> WrongConfigLibraries;
+
+  // Whether the list depends on a genex referencing the configuration.
+  bool HadContextSensitiveCondition = false;
 };
 
 struct cmLinkInterfaceLibraries
@@ -62,6 +66,9 @@
 
   // Whether the list depends on a genex referencing the head target.
   bool HadHeadSensitiveCondition = false;
+
+  // Whether the list depends on a genex referencing the configuration.
+  bool HadContextSensitiveCondition = false;
 };
 
 struct cmLinkInterface : public cmLinkInterfaceLibraries
@@ -81,6 +88,9 @@
   std::vector<cmLinkItem> WrongConfigLibraries;
 
   bool ImplementationIsInterface = false;
+
+  // Whether the list depends on a link language genex.
+  bool HadLinkLanguageSensitiveCondition = false;
 };
 
 struct cmOptionalLinkInterface : public cmLinkInterface
@@ -100,6 +110,9 @@
 {
   // Languages whose runtime libraries must be linked.
   std::vector<std::string> Languages;
+
+  // Whether the list depends on a link language genex.
+  bool HadLinkLanguageSensitiveCondition = false;
 };
 
 // Cache link implementation computation from each configuration.
@@ -121,7 +134,7 @@
 
   // Check if any entry in the list matches this configuration.
   std::string configUpper = cmSystemTools::UpperCase(config);
-  if (cmContains(debugConfigs, configUpper)) {
+  if (cm::contains(debugConfigs, configUpper)) {
     return DEBUG_LibraryType;
   }
   // The current configuration is not a debug configuration.
diff --git a/Source/cmLinkItemGraphVisitor.cxx b/Source/cmLinkItemGraphVisitor.cxx
index acc23c8..dfdd3ff 100644
--- a/Source/cmLinkItemGraphVisitor.cxx
+++ b/Source/cmLinkItemGraphVisitor.cxx
@@ -24,15 +24,12 @@
 void cmLinkItemGraphVisitor::VisitLinks(cmLinkItem const& item,
                                         cmLinkItem const& rootItem)
 {
-  if (this->LinkVisited(item, rootItem)) {
-    return;
-  }
-
   if (item.Target == nullptr) {
     return;
   }
 
-  for (auto const& config : item.Target->Makefile->GetGeneratorConfigs()) {
+  for (auto const& config : item.Target->Makefile->GetGeneratorConfigs(
+         cmMakefile::IncludeEmptyConfig)) {
     this->VisitLinks(item, rootItem, config);
   }
 }
diff --git a/Source/cmLinkLineDeviceComputer.cxx b/Source/cmLinkLineDeviceComputer.cxx
index 65ed34c..5739fec 100644
--- a/Source/cmLinkLineDeviceComputer.cxx
+++ b/Source/cmLinkLineDeviceComputer.cxx
@@ -6,7 +6,8 @@
 #include <set>
 #include <utility>
 
-#include "cmAlgorithms.h"
+#include <cmext/algorithm>
+
 #include "cmComputeLinkInformation.h"
 #include "cmGeneratorTarget.h"
 #include "cmGlobalGenerator.h"
@@ -14,6 +15,7 @@
 #include "cmListFileCache.h"
 #include "cmLocalGenerator.h"
 #include "cmMakefile.h"
+#include "cmProperty.h"
 #include "cmStateDirectory.h"
 #include "cmStateSnapshot.h"
 #include "cmStateTypes.h"
@@ -176,11 +178,11 @@
     return false;
   }
 
-  if (const char* resolveDeviceSymbols =
+  if (cmProp resolveDeviceSymbols =
         target.GetProperty("CUDA_RESOLVE_DEVICE_SYMBOLS")) {
     // If CUDA_RESOLVE_DEVICE_SYMBOLS has been explicitly set we need
     // to honor the value no matter what it is.
-    return cmIsOn(resolveDeviceSymbols);
+    return cmIsOn(*resolveDeviceSymbols);
   }
 
   // Determine if we have any dependencies that require
@@ -188,22 +190,19 @@
   cmGeneratorTarget::LinkClosure const* closure =
     target.GetLinkClosure(config);
 
-  if (cmContains(closure->Languages, "CUDA")) {
-    if (const char* separableCompilation =
-          target.GetProperty("CUDA_SEPARABLE_COMPILATION")) {
-      if (cmIsOn(separableCompilation)) {
-        bool doDeviceLinking = false;
-        switch (target.GetType()) {
-          case cmStateEnums::SHARED_LIBRARY:
-          case cmStateEnums::MODULE_LIBRARY:
-          case cmStateEnums::EXECUTABLE:
-            doDeviceLinking = true;
-            break;
-          default:
-            break;
-        }
-        return doDeviceLinking;
+  if (cm::contains(closure->Languages, "CUDA")) {
+    if (cmIsOn(target.GetProperty("CUDA_SEPARABLE_COMPILATION"))) {
+      bool doDeviceLinking = false;
+      switch (target.GetType()) {
+        case cmStateEnums::SHARED_LIBRARY:
+        case cmStateEnums::MODULE_LIBRARY:
+        case cmStateEnums::EXECUTABLE:
+          doDeviceLinking = true;
+          break;
+        default:
+          break;
       }
+      return doDeviceLinking;
     }
 
     cmComputeLinkInformation* pcli = target.GetLinkInformation(config);
diff --git a/Source/cmListCommand.cxx b/Source/cmListCommand.cxx
index 5200a16..edec613 100644
--- a/Source/cmListCommand.cxx
+++ b/Source/cmListCommand.cxx
@@ -16,11 +16,11 @@
 #include <vector>
 
 #include <cm/memory>
+#include <cmext/algorithm>
+#include <cmext/string_view>
 
 #include "cmsys/RegularExpression.hxx"
 
-#include "cm_static_string_view.hxx"
-
 #include "cmAlgorithms.h"
 #include "cmExecutionStatus.h"
 #include "cmGeneratorExpression.h"
@@ -66,7 +66,7 @@
   // expand the variable into a list
   cmExpandList(listString, list, true);
   // if no empty elements then just return
-  if (!cmContains(list, std::string())) {
+  if (!cm::contains(list, std::string())) {
     return true;
   }
   // if we have empty elements we need to check policy CMP0007
@@ -1051,6 +1051,7 @@
     UNINITIALIZED,
     STRING,
     FILE_BASENAME,
+    NATURAL,
   };
   enum class CaseSensitivity
   {
@@ -1074,10 +1075,25 @@
       : nullptr;
   }
 
+  using ComparisonFunction =
+    std::function<bool(const std::string&, const std::string&)>;
+  ComparisonFunction GetComparisonFunction(Compare compare)
+  {
+    if (compare == Compare::NATURAL) {
+      return std::function<bool(const std::string&, const std::string&)>(
+        [](const std::string& x, const std::string& y) {
+          return cmSystemTools::strverscmp(x, y) < 0;
+        });
+    }
+    return std::function<bool(const std::string&, const std::string&)>(
+      [](const std::string& x, const std::string& y) { return x < y; });
+  }
+
 public:
   cmStringSorter(Compare compare, CaseSensitivity caseSensitivity,
                  Order desc = Order::ASCENDING)
     : filters{ GetCompareFilter(compare), GetCaseFilter(caseSensitivity) }
+    , sortMethod(GetComparisonFunction(compare))
     , descending(desc == Order::DESCENDING)
   {
   }
@@ -1099,15 +1115,16 @@
     std::string bf = ApplyFilter(b);
     bool result;
     if (descending) {
-      result = bf < af;
+      result = sortMethod(bf, af);
     } else {
-      result = af < bf;
+      result = sortMethod(af, bf);
     }
     return result;
   }
 
 protected:
   StringFilter filters[2] = { nullptr, nullptr };
+  ComparisonFunction sortMethod;
   bool descending;
 };
 
@@ -1142,6 +1159,8 @@
           sortCompare = cmStringSorter::Compare::STRING;
         } else if (argument == "FILE_BASENAME") {
           sortCompare = cmStringSorter::Compare::FILE_BASENAME;
+        } else if (argument == "NATURAL") {
+          sortCompare = cmStringSorter::Compare::NATURAL;
         } else {
           std::string error =
             cmStrCat(messageHint, "value \"", argument, "\" for option \"",
diff --git a/Source/cmListFileCache.cxx b/Source/cmListFileCache.cxx
index 47679c9..7ebb02f 100644
--- a/Source/cmListFileCache.cxx
+++ b/Source/cmListFileCache.cxx
@@ -26,13 +26,15 @@
 struct cmListFileParser
 {
   cmListFileParser(cmListFile* lf, cmListFileBacktrace lfbt,
-                   cmMessenger* messenger, const char* filename);
+                   cmMessenger* messenger);
   ~cmListFileParser();
   cmListFileParser(const cmListFileParser&) = delete;
   cmListFileParser& operator=(const cmListFileParser&) = delete;
   void IssueFileOpenError(std::string const& text) const;
   void IssueError(std::string const& text) const;
-  bool ParseFile();
+  bool ParseFile(const char* filename);
+  bool ParseString(const char* str, const char* virtual_filename);
+  bool Parse();
   bool ParseFunction(const char* name, long line);
   bool AddArgument(cmListFileLexer_Token* token,
                    cmListFileArgument::Delimiter delim);
@@ -51,12 +53,11 @@
 };
 
 cmListFileParser::cmListFileParser(cmListFile* lf, cmListFileBacktrace lfbt,
-                                   cmMessenger* messenger,
-                                   const char* filename)
+                                   cmMessenger* messenger)
   : ListFile(lf)
   , Backtrace(std::move(lfbt))
   , Messenger(messenger)
-  , FileName(filename)
+  , FileName(nullptr)
   , Lexer(cmListFileLexer_New())
 {
 }
@@ -83,8 +84,10 @@
   cmSystemTools::SetFatalErrorOccured();
 }
 
-bool cmListFileParser::ParseFile()
+bool cmListFileParser::ParseFile(const char* filename)
 {
+  this->FileName = filename;
+
   // Open the file.
   cmListFileLexer_BOM bom;
   if (!cmListFileLexer_SetFileName(this->Lexer, this->FileName, &bom)) {
@@ -107,6 +110,24 @@
     return false;
   }
 
+  return Parse();
+}
+
+bool cmListFileParser::ParseString(const char* str,
+                                   const char* virtual_filename)
+{
+  this->FileName = virtual_filename;
+
+  if (!cmListFileLexer_SetString(this->Lexer, str)) {
+    this->IssueFileOpenError("cmListFileCache: cannot allocate buffer.");
+    return false;
+  }
+
+  return Parse();
+}
+
+bool cmListFileParser::Parse()
+{
   // Use a simple recursive-descent parser to process the token
   // stream.
   bool haveNewline = true;
@@ -155,8 +176,22 @@
   bool parseError = false;
 
   {
-    cmListFileParser parser(this, lfbt, messenger, filename);
-    parseError = !parser.ParseFile();
+    cmListFileParser parser(this, lfbt, messenger);
+    parseError = !parser.ParseFile(filename);
+  }
+
+  return !parseError;
+}
+
+bool cmListFile::ParseString(const char* str, const char* virtual_filename,
+                             cmMessenger* messenger,
+                             const cmListFileBacktrace& lfbt)
+{
+  bool parseError = false;
+
+  {
+    cmListFileParser parser(this, lfbt, messenger);
+    parseError = !parser.ParseString(str, virtual_filename);
   }
 
   return !parseError;
diff --git a/Source/cmListFileCache.h b/Source/cmListFileCache.h
index 9cae827..0b4414d 100644
--- a/Source/cmListFileCache.h
+++ b/Source/cmListFileCache.h
@@ -175,6 +175,32 @@
 
 std::ostream& operator<<(std::ostream& os, BT<std::string> const& s);
 
+// Wrap type T as a value with potentially multiple backtraces.  For purposes
+// of ordering and equality comparison, only the original value is used.  The
+// backtrace is considered incidental.
+template <typename T>
+class BTs
+{
+public:
+  BTs(T v = T(), cmListFileBacktrace bt = cmListFileBacktrace())
+    : Value(std::move(v))
+  {
+    Backtraces.emplace_back(std::move(bt));
+  }
+  T Value;
+  std::vector<cmListFileBacktrace> Backtraces;
+  friend bool operator==(BTs<T> const& l, BTs<T> const& r)
+  {
+    return l.Value == r.Value;
+  }
+  friend bool operator<(BTs<T> const& l, BTs<T> const& r)
+  {
+    return l.Value < r.Value;
+  }
+  friend bool operator==(BTs<T> const& l, T const& r) { return l.Value == r; }
+  friend bool operator==(T const& l, BTs<T> const& r) { return l == r.Value; }
+};
+
 std::vector<BT<std::string>> ExpandListWithBacktrace(
   std::string const& list,
   cmListFileBacktrace const& bt = cmListFileBacktrace());
@@ -184,6 +210,9 @@
   bool ParseFile(const char* path, cmMessenger* messenger,
                  cmListFileBacktrace const& lfbt);
 
+  bool ParseString(const char* str, const char* virtual_filename,
+                   cmMessenger* messenger, cmListFileBacktrace const& lfbt);
+
   std::vector<cmListFileFunction> Functions;
 };
 
diff --git a/Source/cmLoadCommandCommand.cxx b/Source/cmLoadCommandCommand.cxx
index 92258e2..5790e16 100644
--- a/Source/cmLoadCommandCommand.cxx
+++ b/Source/cmLoadCommandCommand.cxx
@@ -1,5 +1,15 @@
 /* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
    file Copyright.txt or https://cmake.org/licensing for details.  */
+
+#if !defined(_WIN32) && !defined(__sun)
+// POSIX APIs are needed
+#  define _POSIX_C_SOURCE 200809L
+#endif
+#if defined(__OpenBSD__) || defined(__FreeBSD__) || defined(__NetBSD__)
+// For isascii
+#  define _XOPEN_SOURCE 700
+#endif
+
 #include "cmLoadCommandCommand.h"
 
 #include <csignal>
diff --git a/Source/cmLocalCommonGenerator.cxx b/Source/cmLocalCommonGenerator.cxx
index 025ef7e..44db842 100644
--- a/Source/cmLocalCommonGenerator.cxx
+++ b/Source/cmLocalCommonGenerator.cxx
@@ -17,10 +17,8 @@
   : cmLocalGenerator(gg, mf)
   , WorkingDirectory(std::move(wd))
 {
-  this->Makefile->GetConfigurations(this->ConfigNames);
-  if (this->ConfigNames.empty()) {
-    this->ConfigNames.emplace_back();
-  }
+  this->ConfigNames =
+    this->Makefile->GetGeneratorConfigs(cmMakefile::IncludeEmptyConfig);
 }
 
 cmLocalCommonGenerator::~cmLocalCommonGenerator() = default;
@@ -50,6 +48,15 @@
       this->Makefile->GetRequiredDefinition("CMAKE_Fortran_MODDIR_FLAG"),
       mod_dir);
     this->AppendFlags(flags, modflag);
+    // Some compilers do not search their own module output directory
+    // for using other modules.  Add an include directory explicitly
+    // for consistency with compilers that do search it.
+    std::string incflag =
+      this->Makefile->GetSafeDefinition("CMAKE_Fortran_MODDIR_INCLUDE_FLAG");
+    if (!incflag.empty()) {
+      incflag = cmStrCat(incflag, mod_dir);
+      this->AppendFlags(flags, incflag);
+    }
   }
 
   // If there is a separate module path flag then duplicate the
diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx
index f592b7b..2380cce 100644
--- a/Source/cmLocalGenerator.cxx
+++ b/Source/cmLocalGenerator.cxx
@@ -6,7 +6,6 @@
 #include <cassert>
 #include <cstdio>
 #include <cstdlib>
-#include <cstring>
 #include <initializer_list>
 #include <iterator>
 #include <sstream>
@@ -20,7 +19,6 @@
 
 #include "cmsys/RegularExpression.hxx"
 
-#include "cmAlgorithms.h"
 #include "cmComputeLinkInformation.h"
 #include "cmCustomCommand.h"
 #include "cmCustomCommandGenerator.h"
@@ -35,12 +33,13 @@
 #include "cmInstallScriptGenerator.h"
 #include "cmInstallTargetGenerator.h"
 #include "cmLinkLineComputer.h"
-#include "cmLinkLineDeviceComputer.h"
 #include "cmMakefile.h"
+#include "cmProperty.h"
 #include "cmRulePlaceholderExpander.h"
 #include "cmSourceFile.h"
 #include "cmSourceFileLocation.h"
 #include "cmSourceFileLocationKind.h"
+#include "cmStandardLevelResolver.h"
 #include "cmState.h"
 #include "cmStateDirectory.h"
 #include "cmStateTypes.h"
@@ -131,7 +130,7 @@
     this->LinkerSysroot = this->Makefile->GetSafeDefinition("CMAKE_SYSROOT");
   }
 
-  if (std::string const* appleArchSysroots =
+  if (cmProp appleArchSysroots =
         this->Makefile->GetDef("CMAKE_APPLE_ARCH_SYSROOTS")) {
     std::string const& appleArchs =
       this->Makefile->GetSafeDefinition("CMAKE_OSX_ARCHITECTURES");
@@ -222,7 +221,7 @@
   this->ObjectPathMax = 1000;
 #endif
   const char* plen = this->Makefile->GetDefinition("CMAKE_OBJECT_PATH_MAX");
-  if (plen && *plen) {
+  if (cmNonempty(plen)) {
     unsigned int pmax;
     if (sscanf(plen, "%u", &pmax) == 1) {
       if (pmax >= 128) {
@@ -285,7 +284,7 @@
   // Generate the rule files for each target.
   const auto& targets = this->GetGeneratorTargets();
   for (const auto& target : targets) {
-    if (target->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
+    if (!target->IsInBuildSystem()) {
       continue;
     }
     target->TraceDependencies();
@@ -299,9 +298,9 @@
   }
 
   // Compute the set of configurations.
-  std::vector<std::string> configurationTypes;
-  const std::string& config =
-    this->Makefile->GetConfigurations(configurationTypes, false);
+  std::vector<std::string> configurationTypes =
+    this->Makefile->GetGeneratorConfigs(cmMakefile::OnlyMultiConfig);
+  std::string config = this->Makefile->GetDefaultConfiguration();
 
   std::string file =
     cmStrCat(this->StateSnapshot.GetDirectory().GetCurrentBinary(),
@@ -310,29 +309,35 @@
   cmGeneratedFileStream fout(file);
   fout.SetCopyIfDifferent(true);
 
-  fout << "# CMake generated Testfile for " << std::endl
-       << "# Source directory: "
-       << this->StateSnapshot.GetDirectory().GetCurrentSource() << std::endl
-       << "# Build directory: "
-       << this->StateSnapshot.GetDirectory().GetCurrentBinary() << std::endl
-       << "# " << std::endl
-       << "# This file includes the relevant testing commands "
-       << "required for " << std::endl
-       << "# testing this directory and lists subdirectories to "
-       << "be tested as well." << std::endl;
+  fout << "# CMake generated Testfile for \n"
+          "# Source directory: "
+       << this->StateSnapshot.GetDirectory().GetCurrentSource()
+       << "\n"
+          "# Build directory: "
+       << this->StateSnapshot.GetDirectory().GetCurrentBinary()
+       << "\n"
+          "# \n"
+          "# This file includes the relevant testing commands "
+          "required for \n"
+          "# testing this directory and lists subdirectories to "
+          "be tested as well.\n";
 
-  const char* testIncludeFile =
-    this->Makefile->GetProperty("TEST_INCLUDE_FILE");
-  if (testIncludeFile) {
-    fout << "include(\"" << testIncludeFile << "\")" << std::endl;
+  std::string resourceSpecFile =
+    this->Makefile->GetSafeDefinition("CTEST_RESOURCE_SPEC_FILE");
+  if (!resourceSpecFile.empty()) {
+    fout << "set(CTEST_RESOURCE_SPEC_FILE \"" << resourceSpecFile << "\")\n";
   }
 
-  const char* testIncludeFiles =
-    this->Makefile->GetProperty("TEST_INCLUDE_FILES");
+  cmProp testIncludeFile = this->Makefile->GetProperty("TEST_INCLUDE_FILE");
+  if (testIncludeFile) {
+    fout << "include(\"" << *testIncludeFile << "\")\n";
+  }
+
+  cmProp testIncludeFiles = this->Makefile->GetProperty("TEST_INCLUDE_FILES");
   if (testIncludeFiles) {
-    std::vector<std::string> includesList = cmExpandedList(testIncludeFiles);
+    std::vector<std::string> includesList = cmExpandedList(*testIncludeFiles);
     for (std::string const& i : includesList) {
-      fout << "include(\"" << i << "\")" << std::endl;
+      fout << "include(\"" << i << "\")\n";
     }
   }
 
@@ -349,18 +354,18 @@
     std::string outP = i.GetDirectory().GetCurrentBinary();
     outP = this->MaybeConvertToRelativePath(parentBinDir, outP);
     outP = cmOutputConverter::EscapeForCMake(outP);
-    fout << "subdirs(" << outP << ")" << std::endl;
+    fout << "subdirs(" << outP << ")\n";
   }
 
   // Add directory labels property
   const char* directoryLabels =
     this->Makefile->GetDefinition("CMAKE_DIRECTORY_LABELS");
-  const char* labels = this->Makefile->GetProperty("LABELS");
+  cmProp labels = this->Makefile->GetProperty("LABELS");
 
   if (labels || directoryLabels) {
     fout << "set_directory_properties(PROPERTIES LABELS ";
     if (labels) {
-      fout << cmOutputConverter::EscapeForCMake(labels);
+      fout << cmOutputConverter::EscapeForCMake(*labels);
     }
     if (labels && directoryLabels) {
       fout << ";";
@@ -368,14 +373,14 @@
     if (directoryLabels) {
       fout << cmOutputConverter::EscapeForCMake(directoryLabels);
     }
-    fout << ")" << std::endl;
+    fout << ")\n";
   }
 }
 
 void cmLocalGenerator::CreateEvaluationFileOutputs()
 {
   std::vector<std::string> const& configs =
-    this->Makefile->GetGeneratorConfigs();
+    this->Makefile->GetGeneratorConfigs(cmMakefile::IncludeEmptyConfig);
   for (std::string const& c : configs) {
     this->CreateEvaluationFileOutputs(c);
   }
@@ -429,7 +434,7 @@
       prefix_win32 = "C:";
     }
     const char* project_name = this->Makefile->GetDefinition("PROJECT_NAME");
-    if (project_name && project_name[0]) {
+    if (cmNonempty(project_name)) {
       prefix_win32 += "/Program Files/";
       prefix_win32 += project_name;
     } else {
@@ -458,9 +463,9 @@
   }
 
   // Compute the set of configurations.
-  std::vector<std::string> configurationTypes;
-  const std::string& config =
-    this->Makefile->GetConfigurations(configurationTypes, false);
+  std::vector<std::string> configurationTypes =
+    this->Makefile->GetGeneratorConfigs(cmMakefile::OnlyMultiConfig);
+  std::string config = this->Makefile->GetDefaultConfiguration();
 
   // Choose a default install configuration.
   std::string default_config = config;
@@ -489,16 +494,17 @@
   fout.SetCopyIfDifferent(true);
 
   // Write the header.
+  /* clang-format off */
   fout << "# Install script for directory: "
-       << this->StateSnapshot.GetDirectory().GetCurrentSource() << std::endl
-       << std::endl;
-  fout << "# Set the install prefix" << std::endl
-       << "if(NOT DEFINED CMAKE_INSTALL_PREFIX)" << std::endl
-       << "  set(CMAKE_INSTALL_PREFIX \"" << prefix << "\")" << std::endl
-       << "endif()" << std::endl
+       << this->StateSnapshot.GetDirectory().GetCurrentSource()
+       << "\n\n"
+          "# Set the install prefix\n"
+          "if(NOT DEFINED CMAKE_INSTALL_PREFIX)\n"
+          "  set(CMAKE_INSTALL_PREFIX \"" << prefix << "\")\n"
+          "endif()\n"
        << R"(string(REGEX REPLACE "/$" "" CMAKE_INSTALL_PREFIX )"
-       << "\"${CMAKE_INSTALL_PREFIX}\")" << std::endl
-       << std::endl;
+       << "\"${CMAKE_INSTALL_PREFIX}\")\n\n";
+  /* clang-format on */
 
   // Write support code for generating per-configuration install rules.
   /* clang-format off */
@@ -572,6 +578,71 @@
     /* clang-format on */
   }
 
+  // Write out CMAKE_GET_RUNTIME_DEPENDENCIES_PLATFORM so that
+  // installed code that uses `file(GET_RUNTIME_DEPENDENCIES)`
+  // has same platform variable as when running cmake
+  if (const char* platform = this->Makefile->GetDefinition(
+        "CMAKE_GET_RUNTIME_DEPENDENCIES_PLATFORM")) {
+    /* clang-format off */
+    fout <<
+      "# Set default install directory permissions.\n"
+      "if(NOT DEFINED CMAKE_GET_RUNTIME_DEPENDENCIES_PLATFORM)\n"
+      "  set(CMAKE_GET_RUNTIME_DEPENDENCIES_PLATFORM \""
+         << platform << "\")\n"
+      "endif()\n"
+      "\n";
+    /* clang-format on */
+  }
+
+  // Write out CMAKE_GET_RUNTIME_DEPENDENCIES_TOOL so that
+  // installed code that uses `file(GET_RUNTIME_DEPENDENCIES)`
+  // has same tool selected as when running cmake
+  if (const char* command =
+        this->Makefile->GetDefinition("CMAKE_GET_RUNTIME_DEPENDENCIES_TOOL")) {
+    /* clang-format off */
+    fout <<
+      "# Set default install directory permissions.\n"
+      "if(NOT DEFINED CMAKE_GET_RUNTIME_DEPENDENCIES_TOOL)\n"
+      "  set(CMAKE_GET_RUNTIME_DEPENDENCIES_TOOL \""
+         << command << "\")\n"
+      "endif()\n"
+      "\n";
+    /* clang-format on */
+  }
+
+  // Write out CMAKE_GET_RUNTIME_DEPENDENCIES_COMMAND so that
+  // installed code that uses `file(GET_RUNTIME_DEPENDENCIES)`
+  // has same path to the tool as when running cmake
+  if (const char* command = this->Makefile->GetDefinition(
+        "CMAKE_GET_RUNTIME_DEPENDENCIES_COMMAND")) {
+    /* clang-format off */
+    fout <<
+      "# Set default install directory permissions.\n"
+      "if(NOT DEFINED CMAKE_GET_RUNTIME_DEPENDENCIES_COMMAND)\n"
+      "  set(CMAKE_GET_RUNTIME_DEPENDENCIES_COMMAND \""
+         << command << "\")\n"
+      "endif()\n"
+      "\n";
+    /* clang-format on */
+  }
+
+  // Write out CMAKE_OBJDUMP so that installed code that uses
+  // `file(GET_RUNTIME_DEPENDENCIES)` and hasn't specified
+  // CMAKE_GET_RUNTIME_DEPENDENCIES_COMMAND has consistent
+  // logic to fallback to CMAKE_OBJDUMP when `objdump` is
+  // not on the path
+  if (const char* command = this->Makefile->GetDefinition("CMAKE_OBJDUMP")) {
+    /* clang-format off */
+    fout <<
+      "# Set default install directory permissions.\n"
+      "if(NOT DEFINED CMAKE_OBJDUMP)\n"
+      "  set(CMAKE_OBJDUMP \""
+         << command << "\")\n"
+      "endif()\n"
+      "\n";
+    /* clang-format on */
+  }
+
   // Ask each install generator to write its code.
   cmPolicies::PolicyStatus status = this->GetPolicyStatus(cmPolicies::CMP0082);
   auto const& installers = this->Makefile->GetInstallGenerators();
@@ -613,8 +684,7 @@
           if (!c.GetDirectory().GetPropertyAsBool("EXCLUDE_FROM_ALL")) {
             std::string odir = c.GetDirectory().GetCurrentBinary();
             cmSystemTools::ConvertToUnixSlashes(odir);
-            fout << "  include(\"" << odir << "/cmake_install.cmake\")"
-                 << std::endl;
+            fout << "  include(\"" << odir << "/cmake_install.cmake\")\n";
           }
         }
         fout << "\n";
@@ -684,16 +754,13 @@
 void cmLocalGenerator::ComputeTargetManifest()
 {
   // Collect the set of configuration types.
-  std::vector<std::string> configNames;
-  this->Makefile->GetConfigurations(configNames);
-  if (configNames.empty()) {
-    configNames.emplace_back();
-  }
+  std::vector<std::string> configNames =
+    this->Makefile->GetGeneratorConfigs(cmMakefile::IncludeEmptyConfig);
 
   // Add our targets to the manifest for each configuration.
   const auto& targets = this->GetGeneratorTargets();
   for (const auto& target : targets) {
-    if (target->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
+    if (!target->IsInBuildSystem()) {
       continue;
     }
     for (std::string const& c : configNames) {
@@ -705,11 +772,8 @@
 bool cmLocalGenerator::ComputeTargetCompileFeatures()
 {
   // Collect the set of configuration types.
-  std::vector<std::string> configNames;
-  this->Makefile->GetConfigurations(configNames);
-  if (configNames.empty()) {
-    configNames.emplace_back();
-  }
+  std::vector<std::string> configNames =
+    this->Makefile->GetGeneratorConfigs(cmMakefile::IncludeEmptyConfig);
 
   using LanguagePair = std::pair<std::string, std::string>;
   std::vector<LanguagePair> pairedLanguages{ { "OBJC", "C" },
@@ -733,40 +797,9 @@
 
     // Now that C/C++ _STANDARD values have been computed
     // set the values to ObjC/ObjCXX _STANDARD variables
-    if (target->GetType() != cmStateEnums::INTERFACE_LIBRARY) {
-      auto copyStandardToObjLang = [&](LanguagePair const& lang) -> bool {
-        if (!target->GetProperty(cmStrCat(lang.first, "_STANDARD"))) {
-          auto* standard =
-            target->GetProperty(cmStrCat(lang.second, "_STANDARD"));
-          if (!standard) {
-            standard = this->Makefile->GetDefinition(
-              cmStrCat("CMAKE_", lang.second, "_STANDARD_DEFAULT"));
-          }
-          target->Target->SetProperty(cmStrCat(lang.first, "_STANDARD"),
-                                      standard);
-          return true;
-        }
-        return false;
-      };
-      auto copyPropertyToObjLang = [&](LanguagePair const& lang,
-                                       const char* property) {
-        if (!target->GetProperty(cmStrCat(lang.first, property)) &&
-            target->GetProperty(cmStrCat(lang.second, property))) {
-          target->Target->SetProperty(
-            cmStrCat(lang.first, property),
-            target->GetProperty(cmStrCat(lang.second, property)));
-        }
-      };
-      for (auto const& lang : pairedLanguages) {
-        if (copyStandardToObjLang(lang)) {
-          copyPropertyToObjLang(lang, "_STANDARD_REQUIRED");
-          copyPropertyToObjLang(lang, "_EXTENSIONS");
-        }
-      }
-      if (const char* standard = target->GetProperty("CUDA_STANDARD")) {
-        if (std::string{ standard } == "98") {
-          target->Target->SetProperty("CUDA_STANDARD", "03");
-        }
+    if (target->CanCompileSources()) {
+      for (std::string const& c : configNames) {
+        target->ComputeCompileFeatures(c, inferredEnabledLanguages);
       }
     }
   }
@@ -792,10 +825,13 @@
 const char* cmLocalGenerator::GetRuleLauncher(cmGeneratorTarget* target,
                                               const std::string& prop)
 {
+  cmProp p;
   if (target) {
-    return target->GetProperty(prop);
+    p = target->GetProperty(prop);
+  } else {
+    p = this->Makefile->GetProperty(prop);
   }
-  return this->Makefile->GetProperty(prop);
+  return p ? p->c_str() : nullptr;
 }
 
 std::string cmLocalGenerator::ConvertToIncludeReference(
@@ -857,7 +893,7 @@
   emitted.insert("/System/Library/Frameworks");
 #endif
   for (std::string const& i : includes) {
-    if (fwSearchFlag && *fwSearchFlag && this->Makefile->IsOn("APPLE") &&
+    if (cmNonempty(fwSearchFlag) && this->Makefile->IsOn("APPLE") &&
         cmSystemTools::IsPathToFramework(i)) {
       std::string const frameworkDir =
         cmSystemTools::CollapseFullPath(cmStrCat(i, "/../"));
@@ -899,7 +935,7 @@
   if ((sep[0] != ' ') && !flags.empty() && flags.back() == sep[0]) {
     flags.back() = ' ';
   }
-  return flags;
+  return cmTrimWhitespace(flags);
 }
 
 void cmLocalGenerator::AddCompileOptions(std::string& flags,
@@ -922,9 +958,9 @@
   if (const char* langFlagRegexStr =
         this->Makefile->GetDefinition(langFlagRegexVar)) {
     // Filter flags acceptable to this language.
-    if (const char* targetFlags = target->GetProperty("COMPILE_FLAGS")) {
+    if (cmProp targetFlags = target->GetProperty("COMPILE_FLAGS")) {
       std::vector<std::string> opts;
-      cmSystemTools::ParseWindowsCommandLine(targetFlags, opts);
+      cmSystemTools::ParseWindowsCommandLine(targetFlags->c_str(), opts);
       // Re-escape these flags since COMPILE_FLAGS were already parsed
       // as a command line above.
       std::string compileOpts;
@@ -939,10 +975,10 @@
     this->AppendCompileOptions(flags, targetCompileOpts, langFlagRegexStr);
   } else {
     // Use all flags.
-    if (const char* targetFlags = target->GetProperty("COMPILE_FLAGS")) {
+    if (cmProp targetFlags = target->GetProperty("COMPILE_FLAGS")) {
       // COMPILE_FLAGS are not escaped for historical reasons.
       std::string compileFlags;
-      this->AppendFlags(compileFlags, targetFlags);
+      this->AppendFlags(compileFlags, *targetFlags);
       if (!compileFlags.empty()) {
         flags.emplace_back(std::move(compileFlags));
       }
@@ -953,12 +989,13 @@
     this->AppendCompileOptions(flags, targetCompileOpts);
   }
 
+  cmStandardLevelResolver standardResolver(this->Makefile);
   for (auto const& it : target->GetMaxLanguageStandards()) {
-    const char* standard = target->GetProperty(it.first + "_STANDARD");
+    cmProp standard = target->GetLanguageStandard(it.first, config);
     if (!standard) {
       continue;
     }
-    if (this->Makefile->IsLaterStandard(it.first, standard, it.second)) {
+    if (standardResolver.IsLaterStandard(it.first, *standard, it.second)) {
       std::ostringstream e;
       e << "The COMPILE_FEATURES property of target \"" << target->GetName()
         << "\" was evaluated when computing the link "
@@ -967,19 +1004,18 @@
         << "\" for that computation.  Computing the "
            "COMPILE_FEATURES based on the link implementation resulted in a "
            "higher \""
-        << it.first << "_STANDARD\" \"" << standard
+        << it.first << "_STANDARD\" \"" << *standard
         << "\".  "
            "This is not permitted. The COMPILE_FEATURES may not both depend "
            "on "
-           "and be depended on by the link implementation."
-        << std::endl;
+           "and be depended on by the link implementation.\n";
       this->IssueMessage(MessageType::FATAL_ERROR, e.str());
       return;
     }
   }
 
   std::string compReqFlag;
-  this->AddCompilerRequirementFlag(compReqFlag, target, lang);
+  this->AddCompilerRequirementFlag(compReqFlag, target, lang, config);
   if (!compReqFlag.empty()) {
     flags.emplace_back(std::move(compReqFlag));
   }
@@ -995,10 +1031,10 @@
         cmGeneratorTarget::ManagedType::Managed) {
       // add /JMC flags if target property VS_JUST_MY_CODE_DEBUGGING is set
       // to ON
-      if (char const* jmcExprGen =
+      if (cmProp jmcExprGen =
             target->GetProperty("VS_JUST_MY_CODE_DEBUGGING")) {
         std::string isJMCEnabled =
-          cmGeneratorExpression::Evaluate(jmcExprGen, this, config);
+          cmGeneratorExpression::Evaluate(*jmcExprGen, this, config);
         if (cmIsOn(isJMCEnabled)) {
           std::vector<std::string> optVec = cmExpandedList(jmc);
           std::string jmcFlags;
@@ -1018,7 +1054,8 @@
   const cmCustomCommandLines& commandLines, cmCustomCommandType type,
   const char* comment, const char* workingDir, bool escapeOldStyle,
   bool uses_terminal, const std::string& depfile, const std::string& job_pool,
-  bool command_expand_lists, cmObjectLibraryCommands objLibCommands)
+  bool command_expand_lists, cmObjectLibraryCommands objLibCommands,
+  bool stdPipesUTF8)
 {
   cmTarget* t = this->Makefile->GetCustomCommandTarget(
     target, objLibCommands, this->DirectoryBacktrace);
@@ -1029,7 +1066,7 @@
   detail::AddCustomCommandToTarget(
     *this, this->DirectoryBacktrace, cmCommandOrigin::Generator, t, byproducts,
     depends, commandLines, type, comment, workingDir, escapeOldStyle,
-    uses_terminal, depfile, job_pool, command_expand_lists);
+    uses_terminal, depfile, job_pool, command_expand_lists, stdPipesUTF8);
 
   return t;
 }
@@ -1039,14 +1076,14 @@
   const std::string& main_dependency, const cmCustomCommandLines& commandLines,
   const char* comment, const char* workingDir, bool replace,
   bool escapeOldStyle, bool uses_terminal, bool command_expand_lists,
-  const std::string& depfile, const std::string& job_pool)
+  const std::string& depfile, const std::string& job_pool, bool stdPipesUTF8)
 {
   std::vector<std::string> no_byproducts;
   cmImplicitDependsList no_implicit_depends;
   return this->AddCustomCommandToOutput(
     { output }, no_byproducts, depends, main_dependency, no_implicit_depends,
     commandLines, comment, workingDir, replace, escapeOldStyle, uses_terminal,
-    command_expand_lists, depfile, job_pool);
+    command_expand_lists, depfile, job_pool, stdPipesUTF8);
 }
 
 cmSourceFile* cmLocalGenerator::AddCustomCommandToOutput(
@@ -1057,7 +1094,7 @@
   const cmCustomCommandLines& commandLines, const char* comment,
   const char* workingDir, bool replace, bool escapeOldStyle,
   bool uses_terminal, bool command_expand_lists, const std::string& depfile,
-  const std::string& job_pool)
+  const std::string& job_pool, bool stdPipesUTF8)
 {
   // Make sure there is at least one output.
   if (outputs.empty()) {
@@ -1069,7 +1106,7 @@
     *this, this->DirectoryBacktrace, cmCommandOrigin::Generator, outputs,
     byproducts, depends, main_dependency, implicit_depends, commandLines,
     comment, workingDir, replace, escapeOldStyle, uses_terminal,
-    command_expand_lists, depfile, job_pool);
+    command_expand_lists, depfile, job_pool, stdPipesUTF8);
 }
 
 cmTarget* cmLocalGenerator::AddUtilityCommand(
@@ -1078,7 +1115,7 @@
   const std::vector<std::string>& depends,
   const cmCustomCommandLines& commandLines, bool escapeOldStyle,
   const char* comment, bool uses_terminal, bool command_expand_lists,
-  const std::string& job_pool)
+  const std::string& job_pool, bool stdPipesUTF8)
 {
   cmTarget* target =
     this->Makefile->AddNewUtilityTarget(utilityName, excludeFromAll);
@@ -1092,7 +1129,7 @@
     *this, this->DirectoryBacktrace, cmCommandOrigin::Generator, target,
     this->Makefile->GetUtilityOutput(target), workingDir, byproducts, depends,
     commandLines, escapeOldStyle, comment, uses_terminal, command_expand_lists,
-    job_pool);
+    job_pool, stdPipesUTF8);
 
   return target;
 }
@@ -1164,11 +1201,10 @@
     // * Compilers like gfortran do not search their own implicit include
     //   directories for modules ('.mod' files).
     if (lang != "Fortran") {
-      const char* value = this->Makefile->GetDefinition(
-        cmStrCat("CMAKE_", lang, "_IMPLICIT_INCLUDE_DIRECTORIES"));
-      if (value != nullptr) {
-        size_t const impDirVecOldSize = impDirVec.size();
-        cmExpandList(value, impDirVec);
+      size_t const impDirVecOldSize = impDirVec.size();
+      if (this->Makefile->GetDefExpandList(
+            cmStrCat("CMAKE_", lang, "_IMPLICIT_INCLUDE_DIRECTORIES"),
+            impDirVec)) {
         // FIXME: Use cmRange with 'advance()' when it supports non-const.
         for (size_t i = impDirVecOldSize; i < impDirVec.size(); ++i) {
           cmSystemTools::ConvertToUnixSlashes(impDirVec[i]);
@@ -1183,7 +1219,7 @@
     // directly.  In this case adding -I/usr/include can hide SDK headers so we
     // must still exclude it.
     if ((lang == "C" || lang == "CXX" || lang == "CUDA") &&
-        !cmContains(impDirVec, "/usr/include") &&
+        !cm::contains(impDirVec, "/usr/include") &&
         std::find_if(impDirVec.begin(), impDirVec.end(),
                      [](std::string const& d) {
                        return cmHasLiteralSuffix(d, "/usr/include");
@@ -1204,13 +1240,14 @@
                       &lang](std::string const& dir) {
     return (
       // Do not exclude directories that are not in an excluded set.
-      ((!cmContains(implicitSet, this->GlobalGenerator->GetRealPath(dir))) &&
-       (!cmContains(implicitExclude, dir)))
+      ((!cm::contains(implicitSet, this->GlobalGenerator->GetRealPath(dir))) &&
+       (!cm::contains(implicitExclude, dir)))
       // Do not exclude entries of the CPATH environment variable even though
       // they are implicitly searched by the compiler.  They are meant to be
       // user-specified directories that can be re-ordered or converted to
       // -isystem without breaking real compiler builtin headers.
-      || ((lang == "C" || lang == "CXX") && cmContains(this->EnvCPATH, dir)));
+      ||
+      ((lang == "C" || lang == "CXX") && cm::contains(this->EnvCPATH, dir)));
   };
 
   // Get the target-specific include directories.
@@ -1236,7 +1273,7 @@
     }
   }
 
-  // Emit remaining non implicit user direcories.
+  // Emit remaining non implicit user directories.
   for (BT<std::string> const& udr : userDirs) {
     if (notExcluded(udr.Value)) {
       emitBT(udr);
@@ -1257,7 +1294,7 @@
   if (!stripImplicitDirs) {
     // Append implicit directories that were requested by the user only
     for (BT<std::string> const& udr : userDirs) {
-      if (cmContains(implicitSet, cmSystemTools::GetRealPath(udr.Value))) {
+      if (cm::contains(implicitSet, cmSystemTools::GetRealPath(udr.Value))) {
         emitBT(udr);
       }
     }
@@ -1314,14 +1351,15 @@
   std::string const& config, std::string const& linkLanguage,
   cmGeneratorTarget* target)
 {
+  const std::string configUpper = cmSystemTools::UpperCase(config);
   std::vector<BT<std::string>> flags;
   if (linkLanguage != "Swift") {
     std::string staticLibFlags;
     this->AppendFlags(
       staticLibFlags,
       this->Makefile->GetSafeDefinition("CMAKE_STATIC_LINKER_FLAGS"));
-    if (!config.empty()) {
-      std::string name = "CMAKE_STATIC_LINKER_FLAGS_" + config;
+    if (!configUpper.empty()) {
+      std::string name = "CMAKE_STATIC_LINKER_FLAGS_" + configUpper;
       this->AppendFlags(staticLibFlags,
                         this->Makefile->GetSafeDefinition(name));
     }
@@ -1333,8 +1371,8 @@
   std::string staticLibFlags;
   this->AppendFlags(staticLibFlags,
                     target->GetSafeProperty("STATIC_LIBRARY_FLAGS"));
-  if (!config.empty()) {
-    std::string name = "STATIC_LIBRARY_FLAGS_" + config;
+  if (!configUpper.empty()) {
+    std::string name = "STATIC_LIBRARY_FLAGS_" + configUpper;
     this->AppendFlags(staticLibFlags, target->GetSafeProperty(name));
   }
 
@@ -1350,6 +1388,30 @@
   return flags;
 }
 
+void cmLocalGenerator::GetDeviceLinkFlags(
+  cmLinkLineComputer* linkLineComputer, const std::string& config,
+  std::string& linkLibs, std::string& linkFlags, std::string& frameworkPath,
+  std::string& linkPath, cmGeneratorTarget* target)
+{
+  cmGeneratorTarget::DeviceLinkSetter setter(*target);
+
+  cmComputeLinkInformation* pcli = target->GetLinkInformation(config);
+  const std::string linkLanguage =
+    linkLineComputer->GetLinkerLanguage(target, config);
+
+  if (pcli) {
+    // Compute the required cuda device link libraries when
+    // resolving cuda device symbols
+    this->OutputLinkLibraries(pcli, linkLineComputer, linkLibs, frameworkPath,
+                              linkPath);
+  }
+
+  std::vector<std::string> linkOpts;
+  target->GetLinkOptions(linkOpts, config, linkLanguage);
+  // LINK_OPTIONS are escaped.
+  this->AppendCompileOptions(linkFlags, linkOpts);
+}
+
 void cmLocalGenerator::GetTargetFlags(
   cmLinkLineComputer* linkLineComputer, const std::string& config,
   std::string& linkLibs, std::string& flags, std::string& linkFlags,
@@ -1371,23 +1433,17 @@
   std::vector<BT<std::string>>& linkFlags, std::string& frameworkPath,
   std::vector<BT<std::string>>& linkPath, cmGeneratorTarget* target)
 {
-  const std::string buildType = cmSystemTools::UpperCase(config);
+  const std::string configUpper = cmSystemTools::UpperCase(config);
   cmComputeLinkInformation* pcli = target->GetLinkInformation(config);
   const char* libraryLinkVariable =
     "CMAKE_SHARED_LINKER_FLAGS"; // default to shared library
 
   const std::string linkLanguage =
-    linkLineComputer->GetLinkerLanguage(target, buildType);
+    linkLineComputer->GetLinkerLanguage(target, config);
 
   switch (target->GetType()) {
     case cmStateEnums::STATIC_LIBRARY:
-      linkFlags = this->GetStaticLibraryFlags(buildType, linkLanguage, target);
-      if (pcli && dynamic_cast<cmLinkLineDeviceComputer*>(linkLineComputer)) {
-        // Compute the required cuda device link libraries when
-        // resolving cuda device symbols
-        this->OutputLinkLibraries(pcli, linkLineComputer, linkLibs,
-                                  frameworkPath, linkPath);
-      }
+      linkFlags = this->GetStaticLibraryFlags(config, linkLanguage, target);
       break;
     case cmStateEnums::MODULE_LIBRARY:
       libraryLinkVariable = "CMAKE_MODULE_LINKER_FLAGS";
@@ -1397,8 +1453,8 @@
       if (linkLanguage != "Swift") {
         sharedLibFlags = cmStrCat(
           this->Makefile->GetSafeDefinition(libraryLinkVariable), ' ');
-        if (!buildType.empty()) {
-          std::string build = cmStrCat(libraryLinkVariable, '_', buildType);
+        if (!configUpper.empty()) {
+          std::string build = cmStrCat(libraryLinkVariable, '_', configUpper);
           sharedLibFlags += this->Makefile->GetSafeDefinition(build);
           sharedLibFlags += " ";
         }
@@ -1406,30 +1462,30 @@
             !(this->Makefile->IsOn("CYGWIN") ||
               this->Makefile->IsOn("MINGW"))) {
           std::vector<cmSourceFile*> sources;
-          target->GetSourceFiles(sources, buildType);
+          target->GetSourceFiles(sources, config);
           std::string defFlag =
             this->Makefile->GetSafeDefinition("CMAKE_LINK_DEF_FILE_FLAG");
           for (cmSourceFile* sf : sources) {
             if (sf->GetExtension() == "def") {
               sharedLibFlags += defFlag;
-              sharedLibFlags += this->ConvertToOutputFormat(
-                cmSystemTools::CollapseFullPath(sf->ResolveFullPath()), SHELL);
+              sharedLibFlags +=
+                this->ConvertToOutputFormat(sf->ResolveFullPath(), SHELL);
               sharedLibFlags += " ";
             }
           }
         }
       }
 
-      const char* targetLinkFlags = target->GetProperty("LINK_FLAGS");
+      cmProp targetLinkFlags = target->GetProperty("LINK_FLAGS");
       if (targetLinkFlags) {
-        sharedLibFlags += targetLinkFlags;
+        sharedLibFlags += *targetLinkFlags;
         sharedLibFlags += " ";
       }
-      if (!buildType.empty()) {
+      if (!configUpper.empty()) {
         targetLinkFlags =
-          target->GetProperty(cmStrCat("LINK_FLAGS_", buildType));
+          target->GetProperty(cmStrCat("LINK_FLAGS_", configUpper));
         if (targetLinkFlags) {
-          sharedLibFlags += targetLinkFlags;
+          sharedLibFlags += *targetLinkFlags;
           sharedLibFlags += " ";
         }
       }
@@ -1452,9 +1508,9 @@
       if (linkLanguage != "Swift") {
         exeFlags = this->Makefile->GetSafeDefinition("CMAKE_EXE_LINKER_FLAGS");
         exeFlags += " ";
-        if (!buildType.empty()) {
+        if (!configUpper.empty()) {
           exeFlags += this->Makefile->GetSafeDefinition(
-            cmStrCat("CMAKE_EXE_LINKER_FLAGS_", buildType));
+            cmStrCat("CMAKE_EXE_LINKER_FLAGS_", configUpper));
           exeFlags += " ";
         }
         if (linkLanguage.empty()) {
@@ -1481,15 +1537,14 @@
         }
       }
 
-      this->AddLanguageFlagsForLinking(flags, target, linkLanguage, buildType);
+      this->AddLanguageFlagsForLinking(flags, target, linkLanguage, config);
       if (pcli) {
         this->OutputLinkLibraries(pcli, linkLineComputer, linkLibs,
                                   frameworkPath, linkPath);
       }
 
-      if (cmIsOn(this->Makefile->GetDefinition("BUILD_SHARED_LIBS"))) {
-        std::string sFlagVar = std::string("CMAKE_SHARED_BUILD_") +
-          linkLanguage + std::string("_FLAGS");
+      if (this->Makefile->IsOn("BUILD_SHARED_LIBS")) {
+        std::string sFlagVar = "CMAKE_SHARED_BUILD_" + linkLanguage + "_FLAGS";
         exeFlags += this->Makefile->GetSafeDefinition(sFlagVar);
         exeFlags += " ";
       }
@@ -1501,16 +1556,16 @@
         exeFlags += " ";
       }
 
-      const char* targetLinkFlags = target->GetProperty("LINK_FLAGS");
+      cmProp targetLinkFlags = target->GetProperty("LINK_FLAGS");
       if (targetLinkFlags) {
-        exeFlags += targetLinkFlags;
+        exeFlags += *targetLinkFlags;
         exeFlags += " ";
       }
-      if (!buildType.empty()) {
+      if (!configUpper.empty()) {
         targetLinkFlags =
-          target->GetProperty(cmStrCat("LINK_FLAGS_", buildType));
+          target->GetProperty(cmStrCat("LINK_FLAGS_", configUpper));
         if (targetLinkFlags) {
-          exeFlags += targetLinkFlags;
+          exeFlags += *targetLinkFlags;
           exeFlags += " ";
         }
       }
@@ -1541,16 +1596,17 @@
 void cmLocalGenerator::GetTargetCompileFlags(cmGeneratorTarget* target,
                                              std::string const& config,
                                              std::string const& lang,
-                                             std::string& flags)
+                                             std::string& flags,
+                                             std::string const& arch)
 {
   std::vector<BT<std::string>> tmpFlags =
-    this->GetTargetCompileFlags(target, config, lang);
+    this->GetTargetCompileFlags(target, config, lang, arch);
   this->AppendFlags(flags, tmpFlags);
 }
 
 std::vector<BT<std::string>> cmLocalGenerator::GetTargetCompileFlags(
   cmGeneratorTarget* target, std::string const& config,
-  std::string const& lang)
+  std::string const& lang, std::string const& arch)
 {
   std::vector<BT<std::string>> flags;
   std::string compileFlags;
@@ -1564,7 +1620,7 @@
     this->AppendFeatureOptions(compileFlags, lang, "IPO");
   }
 
-  this->AddArchitectureFlags(compileFlags, target, lang, config);
+  this->AddArchitectureFlags(compileFlags, target, lang, config, arch);
 
   if (lang == "Fortran") {
     this->AppendFlags(compileFlags,
@@ -1597,7 +1653,7 @@
 
   std::string fwSearchFlagVar = "CMAKE_" + lang + "_FRAMEWORK_SEARCH_FLAG";
   const char* fwSearchFlag = mf->GetDefinition(fwSearchFlagVar);
-  if (!(fwSearchFlag && *fwSearchFlag)) {
+  if (!cmNonempty(fwSearchFlag)) {
     return std::string();
   }
 
@@ -1753,10 +1809,10 @@
               "CMAKE_POLICY_WARNING_CMP0065")) {
           std::ostringstream w;
           /* clang-format off */
-          w << cmPolicies::GetPolicyWarning(cmPolicies::CMP0065) << "\n"
-            "For compatibility with older versions of CMake, "
-            "additional flags may be added to export symbols on all "
-            "executables regardless of their ENABLE_EXPORTS property.";
+            w << cmPolicies::GetPolicyWarning(cmPolicies::CMP0065) << "\n"
+              "For compatibility with older versions of CMake, "
+              "additional flags may be added to export symbols on all "
+              "executables regardless of their ENABLE_EXPORTS property.";
           /* clang-format on */
           this->IssueMessage(MessageType::AUTHOR_WARNING, w.str());
         }
@@ -1812,7 +1868,8 @@
 void cmLocalGenerator::AddArchitectureFlags(std::string& flags,
                                             cmGeneratorTarget const* target,
                                             const std::string& lang,
-                                            const std::string& config)
+                                            const std::string& config,
+                                            const std::string& filterArch)
 {
   // Only add Apple specific flags on Apple platforms
   if (this->Makefile->IsOn("APPLE") && this->EmitUniversalBinaryFlags) {
@@ -1821,8 +1878,10 @@
     if (!archs.empty() && !lang.empty() &&
         (lang[0] == 'C' || lang[0] == 'F' || lang[0] == 'O')) {
       for (std::string const& arch : archs) {
-        flags += " -arch ";
-        flags += arch;
+        if (filterArch.empty() || filterArch == arch) {
+          flags += " -arch ";
+          flags += arch;
+        }
       }
     }
 
@@ -1833,7 +1892,7 @@
     std::string sysrootFlagVar =
       std::string("CMAKE_") + lang + "_SYSROOT_FLAG";
     const char* sysrootFlag = this->Makefile->GetDefinition(sysrootFlagVar);
-    if (sysrootFlag && *sysrootFlag) {
+    if (cmNonempty(sysrootFlag)) {
       if (!this->AppleArchSysroots.empty() &&
           !this->AllAppleArchSysrootsAreTheSame(archs, sysroot)) {
         for (std::string const& arch : archs) {
@@ -1841,10 +1900,12 @@
           if (cmIsOff(archSysroot)) {
             continue;
           }
-          flags += " -Xarch_" + arch + " ";
-          // Combine sysroot flag and path to work with -Xarch
-          std::string arch_sysroot = sysrootFlag + archSysroot;
-          flags += this->ConvertToOutputFormat(arch_sysroot, SHELL);
+          if (filterArch.empty() || filterArch == arch) {
+            flags += " -Xarch_" + arch + " ";
+            // Combine sysroot flag and path to work with -Xarch
+            std::string arch_sysroot = sysrootFlag + archSysroot;
+            flags += this->ConvertToOutputFormat(arch_sysroot, SHELL);
+          }
         }
       } else if (sysroot && *sysroot) {
         flags += " ";
@@ -1860,8 +1921,7 @@
       std::string("CMAKE_") + lang + "_OSX_DEPLOYMENT_TARGET_FLAG";
     const char* deploymentTargetFlag =
       this->Makefile->GetDefinition(deploymentTargetFlagVar);
-    if (deploymentTargetFlag && *deploymentTargetFlag && deploymentTarget &&
-        *deploymentTarget) {
+    if (cmNonempty(deploymentTargetFlag) && cmNonempty(deploymentTarget)) {
       flags += " ";
       flags += deploymentTargetFlag;
       flags += deploymentTarget;
@@ -1878,29 +1938,63 @@
   this->AddConfigVariableFlags(flags, cmStrCat("CMAKE_", lang, "_FLAGS"),
                                config);
 
+  std::string const& compiler = this->Makefile->GetSafeDefinition(
+    cmStrCat("CMAKE_", lang, "_COMPILER_ID"));
+
   if (lang == "Swift") {
-    if (const char* v = target->GetProperty("Swift_LANGUAGE_VERSION")) {
+    if (cmProp v = target->GetProperty("Swift_LANGUAGE_VERSION")) {
       if (cmSystemTools::VersionCompare(
             cmSystemTools::OP_GREATER_EQUAL,
             this->Makefile->GetDefinition("CMAKE_Swift_COMPILER_VERSION"),
             "4.2")) {
-        this->AppendFlags(flags, "-swift-version " + std::string(v));
+        this->AppendFlags(flags, "-swift-version " + *v);
+      }
+    }
+  } else if (lang == "CUDA") {
+    target->AddCUDAArchitectureFlags(flags);
+    target->AddCUDAToolkitFlags(flags);
+
+    if (compiler == "Clang") {
+      bool separable = target->GetPropertyAsBool("CUDA_SEPARABLE_COMPILATION");
+
+      if (separable) {
+        this->Makefile->IssueMessage(
+          MessageType::FATAL_ERROR,
+          "CUDA_SEPARABLE_COMPILATION isn't supported on Clang. "
+          "See CMake issue #20726.");
       }
     }
   }
-
+  // Add VFS Overlay for Clang compiliers
+  if (compiler == "Clang") {
+    if (const char* vfsOverlay =
+          this->Makefile->GetDefinition("CMAKE_CLANG_VFS_OVERLAY")) {
+      std::string const& compilerSimulateId =
+        this->Makefile->GetSafeDefinition(
+          cmStrCat("CMAKE_", lang, "_SIMULATE_ID"));
+      if (compilerSimulateId == "MSVC") {
+        this->AppendCompileOptions(
+          flags,
+          std::vector<std::string>{ "-Xclang", "-ivfsoverlay", "-Xclang",
+                                    vfsOverlay });
+      } else {
+        this->AppendCompileOptions(
+          flags, std::vector<std::string>{ "-ivfsoverlay", vfsOverlay });
+      }
+    }
+  }
   // Add MSVC runtime library flags.  This is activated by the presence
   // of a default selection whether or not it is overridden by a property.
-  const char* msvcRuntimeLibraryDefault =
-    this->Makefile->GetDefinition("CMAKE_MSVC_RUNTIME_LIBRARY_DEFAULT");
-  if (msvcRuntimeLibraryDefault && *msvcRuntimeLibraryDefault) {
-    const char* msvcRuntimeLibraryValue =
+  cmProp msvcRuntimeLibraryDefault =
+    this->Makefile->GetDef("CMAKE_MSVC_RUNTIME_LIBRARY_DEFAULT");
+  if (cmNonempty(msvcRuntimeLibraryDefault)) {
+    cmProp msvcRuntimeLibraryValue =
       target->GetProperty("MSVC_RUNTIME_LIBRARY");
     if (!msvcRuntimeLibraryValue) {
       msvcRuntimeLibraryValue = msvcRuntimeLibraryDefault;
     }
     std::string const msvcRuntimeLibrary = cmGeneratorExpression::Evaluate(
-      msvcRuntimeLibraryValue, this, config, target);
+      *msvcRuntimeLibraryValue, this, config, target);
     if (!msvcRuntimeLibrary.empty()) {
       if (const char* msvcRuntimeLibraryOptions =
             this->Makefile->GetDefinition(
@@ -1932,7 +2026,7 @@
     // when linking in order to use the matching standard library.
     // FIXME: If CMake gains an abstraction for standard library
     // selection, this will have to be reconciled with it.
-    this->AddCompilerRequirementFlag(flags, target, lang);
+    this->AddCompilerRequirementFlag(flags, target, lang, config);
   }
 
   this->AddLanguageFlags(flags, target, lang, config);
@@ -1950,6 +2044,15 @@
     return imported->second;
   }
 
+  // find local alias to imported target
+  auto aliased = this->AliasTargets.find(name);
+  if (aliased != this->AliasTargets.end()) {
+    imported = this->ImportedGeneratorTargets.find(aliased->second);
+    if (imported != this->ImportedGeneratorTargets.end()) {
+      return imported->second;
+    }
+  }
+
   if (cmGeneratorTarget* t = this->FindLocalNonAliasGeneratorTarget(name)) {
     return t;
   }
@@ -1973,7 +2076,6 @@
   if (name.empty()) {
     return false;
   }
-
   if (cmSystemTools::GetFilenameLastExtension(name) == ".exe") {
     name = cmSystemTools::GetFilenameWithoutLastExtension(name);
   }
@@ -2013,11 +2115,9 @@
       case cmStateEnums::OBJECT_LIBRARY:
         // An object library has no single file on which to depend.
         // This was listed to get the target-level dependency.
-        return false;
       case cmStateEnums::INTERFACE_LIBRARY:
         // An interface library has no file on which to depend.
         // This was listed to get the target-level dependency.
-        return false;
       case cmStateEnums::UTILITY:
       case cmStateEnums::GLOBAL_TARGET:
         // A utility target has no file on which to depend.  This was listed
@@ -2069,157 +2169,21 @@
 }
 
 void cmLocalGenerator::AddCompilerRequirementFlag(
-  std::string& flags, cmGeneratorTarget const* target, const std::string& lang)
+  std::string& flags, cmGeneratorTarget const* target, const std::string& lang,
+  const std::string& config)
 {
-  if (lang.empty()) {
-    return;
-  }
-  const char* defaultStd =
-    this->Makefile->GetDefinition("CMAKE_" + lang + "_STANDARD_DEFAULT");
-  if (!defaultStd || !*defaultStd) {
-    // This compiler has no notion of language standard levels.
-    return;
-  }
-  std::string extProp = lang + "_EXTENSIONS";
-  bool ext = true;
-  if (const char* extPropValue = target->GetProperty(extProp)) {
-    if (cmIsOff(extPropValue)) {
-      ext = false;
-    }
-  }
-  std::string stdProp = lang + "_STANDARD";
-  const char* standardProp = target->GetProperty(stdProp);
-  if (!standardProp) {
-    if (ext) {
-      // No language standard is specified and extensions are not disabled.
-      // Check if this compiler needs a flag to enable extensions.
-      std::string const option_flag =
-        "CMAKE_" + lang + "_EXTENSION_COMPILE_OPTION";
-      if (const char* opt =
-            target->Target->GetMakefile()->GetDefinition(option_flag)) {
-        std::vector<std::string> optVec = cmExpandedList(opt);
-        for (std::string const& i : optVec) {
-          this->AppendFlagEscape(flags, i);
-        }
-      }
-    }
-    return;
-  }
+  cmStandardLevelResolver standardResolver(this->Makefile);
 
-  std::string const type = ext ? "EXTENSION" : "STANDARD";
-
-  if (target->GetPropertyAsBool(lang + "_STANDARD_REQUIRED")) {
-    std::string option_flag =
-      "CMAKE_" + lang + standardProp + "_" + type + "_COMPILE_OPTION";
-
-    const char* opt =
-      target->Target->GetMakefile()->GetDefinition(option_flag);
-    if (!opt) {
-      std::ostringstream e;
-      e << "Target \"" << target->GetName()
-        << "\" requires the language "
-           "dialect \""
-        << lang << standardProp << "\" "
-        << (ext ? "(with compiler extensions)" : "")
-        << ", but CMake "
-           "does not know the compile flags to use to enable it.";
-      this->IssueMessage(MessageType::FATAL_ERROR, e.str());
-    } else {
+  std::string const& optionFlagDef =
+    standardResolver.GetCompileOptionDef(target, lang, config);
+  if (!optionFlagDef.empty()) {
+    auto opt = target->Target->GetMakefile()->GetDefinition(optionFlagDef);
+    if (opt) {
       std::vector<std::string> optVec = cmExpandedList(opt);
       for (std::string const& i : optVec) {
         this->AppendFlagEscape(flags, i);
       }
     }
-    return;
-  }
-
-  static std::map<std::string, std::vector<std::string>> langStdMap;
-  if (langStdMap.empty()) {
-    // Maintain sorted order, most recent first.
-    langStdMap["CXX"].emplace_back("20");
-    langStdMap["CXX"].emplace_back("17");
-    langStdMap["CXX"].emplace_back("14");
-    langStdMap["CXX"].emplace_back("11");
-    langStdMap["CXX"].emplace_back("98");
-
-    langStdMap["OBJCXX"].emplace_back("20");
-    langStdMap["OBJCXX"].emplace_back("17");
-    langStdMap["OBJCXX"].emplace_back("14");
-    langStdMap["OBJCXX"].emplace_back("11");
-    langStdMap["OBJCXX"].emplace_back("98");
-
-    langStdMap["C"].emplace_back("11");
-    langStdMap["C"].emplace_back("99");
-    langStdMap["C"].emplace_back("90");
-
-    langStdMap["OBJC"].emplace_back("11");
-    langStdMap["OBJC"].emplace_back("99");
-    langStdMap["OBJC"].emplace_back("90");
-
-    langStdMap["CUDA"].emplace_back("20");
-    langStdMap["CUDA"].emplace_back("17");
-    langStdMap["CUDA"].emplace_back("14");
-    langStdMap["CUDA"].emplace_back("11");
-    langStdMap["CUDA"].emplace_back("03");
-  }
-
-  std::string standard(standardProp);
-  if (lang == "CUDA" && standard == "98") {
-    standard = "03";
-  }
-  std::vector<std::string>& stds = langStdMap[lang];
-
-  auto stdIt = std::find(stds.begin(), stds.end(), standard);
-  if (stdIt == stds.end()) {
-
-    std::string e =
-      lang + "_STANDARD is set to invalid value '" + standard + "'";
-    this->GetGlobalGenerator()->GetCMakeInstance()->IssueMessage(
-      MessageType::FATAL_ERROR, e, target->GetBacktrace());
-    return;
-  }
-
-  auto defaultStdIt = std::find(stds.begin(), stds.end(), defaultStd);
-  if (defaultStdIt == stds.end()) {
-    std::string e = "CMAKE_" + lang +
-      "_STANDARD_DEFAULT is set to invalid value '" + std::string(defaultStd) +
-      "'";
-    this->IssueMessage(MessageType::INTERNAL_ERROR, e);
-    return;
-  }
-
-  // If the standard requested is older than the compiler's default
-  // then we need to use a flag to change it.  The comparison is
-  // greater-or-equal because the standards are stored in backward
-  // chronological order.
-  if (stdIt >= defaultStdIt) {
-    std::string option_flag =
-      "CMAKE_" + lang + *stdIt + "_" + type + "_COMPILE_OPTION";
-
-    std::string const& opt =
-      target->Target->GetMakefile()->GetRequiredDefinition(option_flag);
-    std::vector<std::string> optVec = cmExpandedList(opt);
-    for (std::string const& i : optVec) {
-      this->AppendFlagEscape(flags, i);
-    }
-    return;
-  }
-
-  // The standard requested is at least as new as the compiler's default,
-  // and the standard request is not required.  Decay to the newest standard
-  // for which a flag is defined.
-  for (; stdIt < defaultStdIt; ++stdIt) {
-    std::string option_flag =
-      cmStrCat("CMAKE_", lang, *stdIt, "_", type, "_COMPILE_OPTION");
-
-    if (const char* opt =
-          target->Target->GetMakefile()->GetDefinition(option_flag)) {
-      std::vector<std::string> optVec = cmExpandedList(opt);
-      for (std::string const& i : optVec) {
-        this->AppendFlagEscape(flags, i);
-      }
-      return;
-    }
   }
 }
 
@@ -2236,7 +2200,7 @@
   }
   std::string flagDefine = lang + "_VISIBILITY_PRESET";
 
-  const char* prop = target->GetProperty(flagDefine);
+  cmProp prop = target->GetProperty(flagDefine);
   if (!prop) {
     return;
   }
@@ -2244,17 +2208,17 @@
     *warnCMP0063 += "  " + flagDefine + "\n";
     return;
   }
-  if (strcmp(prop, "hidden") != 0 && strcmp(prop, "default") != 0 &&
-      strcmp(prop, "protected") != 0 && strcmp(prop, "internal") != 0) {
+  if ((*prop != "hidden") && (*prop != "default") && (*prop != "protected") &&
+      (*prop != "internal")) {
     std::ostringstream e;
-    e << "Target " << target->GetName() << " uses unsupported value \"" << prop
-      << "\" for " << flagDefine << "."
+    e << "Target " << target->GetName() << " uses unsupported value \""
+      << *prop << "\" for " << flagDefine << "."
       << " The supported values are: default, hidden, protected, and "
          "internal.";
     cmSystemTools::Error(e.str());
     return;
   }
-  std::string option = std::string(opt) + prop;
+  std::string option = opt + *prop;
   lg->AppendFlags(flags, option);
 }
 
@@ -2372,7 +2336,8 @@
           std::ostringstream e;
           e << "Variable " << flagsVar
             << " has been modified. CMake "
-               "will ignore the POSITION_INDEPENDENT_CODE target property for "
+               "will ignore the POSITION_INDEPENDENT_CODE target property "
+               "for "
                "shared libraries and will use the "
             << flagsVar
             << " variable "
@@ -2434,7 +2399,9 @@
 void cmLocalGenerator::AppendFlags(std::string& flags,
                                    const std::string& newFlags) const
 {
-  if (!newFlags.empty()) {
+  bool allSpaces = std::all_of(newFlags.begin(), newFlags.end(), cmIsSpace);
+
+  if (!newFlags.empty() && !allSpaces) {
     if (!flags.empty()) {
       flags += " ";
     }
@@ -2460,17 +2427,17 @@
 
 void cmLocalGenerator::AddPchDependencies(cmGeneratorTarget* target)
 {
-  std::vector<std::string> configsList;
-  std::string configDefault = this->Makefile->GetConfigurations(configsList);
-  if (configsList.empty()) {
-    configsList.push_back(configDefault);
-  }
+  std::vector<std::string> configsList =
+    this->Makefile->GetGeneratorConfigs(cmMakefile::IncludeEmptyConfig);
 
   for (std::string const& config : configsList) {
-    // FIXME: Refactor collection of sources to not evaluate object libraries.
+    // FIXME: Refactor collection of sources to not evaluate object
+    // libraries.
     std::vector<cmSourceFile*> sources;
     target->GetSourceFiles(sources, config);
 
+    const std::string configUpper = cmSystemTools::UpperCase(config);
+
     for (const std::string& lang : { "C", "CXX", "OBJC", "OBJCXX" }) {
       auto langSources = std::count_if(
         sources.begin(), sources.end(), [lang](cmSourceFile* sf) {
@@ -2481,153 +2448,354 @@
         continue;
       }
 
-      const std::string pchSource = target->GetPchSource(config, lang);
-      const std::string pchHeader = target->GetPchHeader(config, lang);
-
-      if (pchSource.empty() || pchHeader.empty()) {
-        continue;
-      }
-
-      const std::string pchExtension =
-        this->Makefile->GetSafeDefinition("CMAKE_PCH_EXTENSION");
-
-      if (pchExtension.empty()) {
-        continue;
-      }
-
-      const char* pchReuseFrom =
-        target->GetProperty("PRECOMPILE_HEADERS_REUSE_FROM");
-
-      auto pch_sf = this->Makefile->GetOrCreateSource(
-        pchSource, false, cmSourceFileLocationKind::Known);
-
+      std::vector<std::string> architectures;
       if (!this->GetGlobalGenerator()->IsXcode()) {
-        if (!pchReuseFrom) {
-          target->AddSource(pchSource, true);
-        }
-
-        const std::string pchFile = target->GetPchFile(config, lang);
-
-        // Exclude the pch files from linking
-        if (this->Makefile->IsOn("CMAKE_LINK_PCH")) {
-          if (!pchReuseFrom) {
-            pch_sf->SetProperty("OBJECT_OUTPUTS", pchFile.c_str());
-          } else {
-            auto reuseTarget =
-              this->GlobalGenerator->FindGeneratorTarget(pchReuseFrom);
-
-            if (this->Makefile->IsOn("CMAKE_PCH_COPY_COMPILE_PDB")) {
-
-              const std::string pdb_prefix =
-                this->GetGlobalGenerator()->IsMultiConfig()
-                ? cmStrCat(this->GlobalGenerator->GetCMakeCFGIntDir(), "/")
-                : "";
-
-              const std::string target_compile_pdb_dir = cmStrCat(
-                target->GetLocalGenerator()->GetCurrentBinaryDirectory(), "/",
-                target->GetName(), ".dir/");
-
-              const std::string copy_script =
-                cmStrCat(target_compile_pdb_dir, "copy_idb_pdb.cmake");
-              cmGeneratedFileStream file(copy_script);
-
-              file << "# CMake generated file\n";
-              for (auto extension : { ".pdb", ".idb" }) {
-                const std::string from_file =
-                  cmStrCat(reuseTarget->GetLocalGenerator()
-                             ->GetCurrentBinaryDirectory(),
-                           "/", pchReuseFrom, ".dir/${PDB_PREFIX}",
-                           pchReuseFrom, extension);
-
-                const std::string to_dir = cmStrCat(
-                  target->GetLocalGenerator()->GetCurrentBinaryDirectory(),
-                  "/", target->GetName(), ".dir/${PDB_PREFIX}");
-
-                const std::string to_file =
-                  cmStrCat(to_dir, pchReuseFrom, extension);
-
-                std::string dest_file = to_file;
-
-                const std::string prefix = target->GetSafeProperty("PREFIX");
-                if (!prefix.empty()) {
-                  dest_file =
-                    cmStrCat(to_dir, prefix, pchReuseFrom, extension);
-                }
-
-                file << "if (EXISTS \"" << from_file << "\" AND \""
-                     << from_file << "\" IS_NEWER_THAN \"" << dest_file
-                     << "\")\n";
-                file << "  file(COPY \"" << from_file << "\""
-                     << " DESTINATION \"" << to_dir << "\")\n";
-                if (!prefix.empty()) {
-                  file << "  file(REMOVE \"" << dest_file << "\")\n";
-                  file << "  file(RENAME \"" << to_file << "\" \"" << dest_file
-                       << "\")\n";
-                }
-                file << "endif()\n";
-              }
-
-              cmCustomCommandLines commandLines = cmMakeSingleCommandLine(
-                { cmSystemTools::GetCMakeCommand(),
-                  cmStrCat("-DPDB_PREFIX=", pdb_prefix), "-P", copy_script });
-
-              const std::string no_main_dependency;
-              const std::vector<std::string> no_deps;
-              const char* no_message = "";
-              const char* no_current_dir = nullptr;
-              std::vector<std::string> no_byproducts;
-
-              std::vector<std::string> outputs;
-              outputs.push_back(cmStrCat(target_compile_pdb_dir, pdb_prefix,
-                                         pchReuseFrom, ".pdb"));
-
-              if (this->GetGlobalGenerator()->IsVisualStudio()) {
-                this->AddCustomCommandToTarget(
-                  target->GetName(), outputs, no_deps, commandLines,
-                  cmCustomCommandType::PRE_BUILD, no_message, no_current_dir);
-              } else {
-                cmImplicitDependsList no_implicit_depends;
-                cmSourceFile* copy_rule = this->AddCustomCommandToOutput(
-                  outputs, no_byproducts, no_deps, no_main_dependency,
-                  no_implicit_depends, commandLines, no_message,
-                  no_current_dir);
-
-                if (copy_rule) {
-                  target->AddSource(copy_rule->ResolveFullPath());
-                }
-              }
-
-              target->Target->SetProperty("COMPILE_PDB_OUTPUT_DIRECTORY",
-                                          target_compile_pdb_dir);
-            }
-
-            std::string pchSourceObj =
-              reuseTarget->GetPchFileObject(config, lang);
-
-            const std::string configUpper = cmSystemTools::UpperCase(config);
-
-            // Link to the pch object file
-            target->Target->AppendProperty(
-              cmStrCat("LINK_FLAGS_", configUpper),
-              cmStrCat(" ", this->ConvertToOutputFormat(pchSourceObj, SHELL)),
-              true);
+        target->GetAppleArchs(config, architectures);
+      }
+      if (architectures.empty()) {
+        architectures.emplace_back();
+      } else {
+        std::string useMultiArchPch;
+        for (const std::string& arch : architectures) {
+          const std::string pchHeader =
+            target->GetPchHeader(config, lang, arch);
+          if (!pchHeader.empty()) {
+            useMultiArchPch = cmStrCat(useMultiArchPch, ";-Xarch_", arch,
+                                       ";-include", pchHeader);
           }
-        } else {
-          pch_sf->SetProperty("PCH_EXTENSION", pchExtension.c_str());
         }
 
-        // Add pchHeader to source files, which will
-        // be grouped as "Precompile Header File"
-        auto pchHeader_sf = this->Makefile->GetOrCreateSource(
-          pchHeader, false, cmSourceFileLocationKind::Known);
-        std::string err;
-        pchHeader_sf->ResolveFullPath(&err);
-        target->AddSource(pchHeader);
+        if (!useMultiArchPch.empty()) {
+          target->Target->SetProperty(
+            cmStrCat(lang, "_COMPILE_OPTIONS_USE_PCH"), useMultiArchPch);
+        }
+      }
+
+      for (const std::string& arch : architectures) {
+        const std::string pchSource = target->GetPchSource(config, lang, arch);
+        const std::string pchHeader = target->GetPchHeader(config, lang, arch);
+
+        if (pchSource.empty() || pchHeader.empty()) {
+          continue;
+        }
+
+        const std::string pchExtension =
+          this->Makefile->GetSafeDefinition("CMAKE_PCH_EXTENSION");
+
+        if (pchExtension.empty()) {
+          continue;
+        }
+
+        cmProp ReuseFrom =
+          target->GetProperty("PRECOMPILE_HEADERS_REUSE_FROM");
+
+        auto pch_sf = this->Makefile->GetOrCreateSource(
+          pchSource, false, cmSourceFileLocationKind::Known);
+
+        if (!this->GetGlobalGenerator()->IsXcode()) {
+          if (!ReuseFrom) {
+            target->AddSource(pchSource, true);
+          }
+
+          const std::string pchFile = target->GetPchFile(config, lang, arch);
+
+          // Exclude the pch files from linking
+          if (this->Makefile->IsOn("CMAKE_LINK_PCH")) {
+            if (!ReuseFrom) {
+              pch_sf->AppendProperty(
+                "OBJECT_OUTPUTS",
+                cmStrCat("$<$<CONFIG:", config, ">:", pchFile, ">"));
+            } else {
+              auto reuseTarget =
+                this->GlobalGenerator->FindGeneratorTarget(*ReuseFrom);
+
+              if (this->Makefile->IsOn("CMAKE_PCH_COPY_COMPILE_PDB")) {
+
+                const std::string compilerId =
+                  this->Makefile->GetSafeDefinition(
+                    cmStrCat("CMAKE_", lang, "_COMPILER_ID"));
+
+                const std::string compilerVersion =
+                  this->Makefile->GetSafeDefinition(
+                    cmStrCat("CMAKE_", lang, "_COMPILER_VERSION"));
+
+                const std::string langFlags =
+                  this->Makefile->GetSafeDefinition(
+                    cmStrCat("CMAKE_", lang, "_FLAGS_", configUpper));
+
+                // MSVC 2008 is producing both .pdb and .idb files with /Zi.
+                if ((langFlags.find("/ZI") != std::string::npos ||
+                     langFlags.find("-ZI") != std::string::npos) ||
+                    (cmSystemTools::VersionCompare(cmSystemTools::OP_LESS,
+                                                   compilerVersion.c_str(),
+                                                   "16.0") &&
+                     compilerId == "MSVC")) {
+                  CopyPchCompilePdb(config, target, *ReuseFrom, reuseTarget,
+                                    { ".pdb", ".idb" });
+                } else if ((langFlags.find("/Zi") != std::string::npos ||
+                            langFlags.find("-Zi") != std::string::npos)) {
+                  CopyPchCompilePdb(config, target, *ReuseFrom, reuseTarget,
+                                    { ".pdb" });
+                }
+              }
+
+              if (reuseTarget->GetType() != cmStateEnums::OBJECT_LIBRARY) {
+                std::string pchSourceObj =
+                  reuseTarget->GetPchFileObject(config, lang, arch);
+
+                // Link to the pch object file
+                target->Target->AppendProperty(
+                  cmStrCat("LINK_FLAGS_", configUpper),
+                  cmStrCat(" ",
+                           this->ConvertToOutputFormat(pchSourceObj, SHELL)),
+                  true);
+              }
+            }
+          } else {
+            pch_sf->SetProperty("PCH_EXTENSION", pchExtension.c_str());
+          }
+
+          // Add pchHeader to source files, which will
+          // be grouped as "Precompile Header File"
+          auto pchHeader_sf = this->Makefile->GetOrCreateSource(
+            pchHeader, true, cmSourceFileLocationKind::Known);
+          std::string err;
+          pchHeader_sf->ResolveFullPath(&err);
+
+          // The pch file is generated, but mark it as not generated
+          // so that a clean operation will not remove it from disk
+          pchHeader_sf->SetProperty("GENERATED", "0");
+
+          target->AddSource(pchHeader);
+        }
       }
     }
   }
 }
 
+void cmLocalGenerator::CopyPchCompilePdb(
+  const std::string& config, cmGeneratorTarget* target,
+  const std::string& ReuseFrom, cmGeneratorTarget* reuseTarget,
+  const std::vector<std::string>& extensions)
+{
+  const std::string pdb_prefix =
+    this->GetGlobalGenerator()->IsMultiConfig() ? cmStrCat(config, "/") : "";
+
+  const std::string target_compile_pdb_dir =
+    cmStrCat(target->GetLocalGenerator()->GetCurrentBinaryDirectory(), "/",
+             target->GetName(), ".dir/");
+
+  const std::string copy_script =
+    cmStrCat(target_compile_pdb_dir, "copy_idb_pdb.cmake");
+  cmGeneratedFileStream file(copy_script);
+
+  file << "# CMake generated file\n";
+
+  file << "# The compiler generated pdb file needs to be written to disk\n"
+       << "# by mspdbsrv. The foreach retry loop is needed to make sure\n"
+       << "# the pdb file is ready to be copied.\n\n";
+
+  for (auto const& extension : extensions) {
+    const std::string from_file =
+      cmStrCat(reuseTarget->GetLocalGenerator()->GetCurrentBinaryDirectory(),
+               "/", ReuseFrom, ".dir/${PDB_PREFIX}", ReuseFrom, extension);
+
+    const std::string to_dir =
+      cmStrCat(target->GetLocalGenerator()->GetCurrentBinaryDirectory(), "/",
+               target->GetName(), ".dir/${PDB_PREFIX}");
+
+    const std::string to_file = cmStrCat(to_dir, ReuseFrom, extension);
+
+    std::string dest_file = to_file;
+
+    std::string const& prefix = target->GetSafeProperty("PREFIX");
+    if (!prefix.empty()) {
+      dest_file = cmStrCat(to_dir, prefix, ReuseFrom, extension);
+    }
+
+    file << "foreach(retry RANGE 1 30)\n";
+    file << "  if (EXISTS \"" << from_file << "\" AND \"" << from_file
+         << "  \" IS_NEWER_THAN \"" << dest_file << "\")\n";
+    file << "    execute_process(COMMAND ${CMAKE_COMMAND} -E copy";
+    file << " \"" << from_file << "\""
+         << " \"" << to_dir << "\" RESULT_VARIABLE result "
+         << " ERROR_QUIET)\n";
+    file << "    if (NOT result EQUAL 0)\n"
+         << "      execute_process(COMMAND ${CMAKE_COMMAND}"
+         << " -E sleep 1)\n"
+         << "    else()\n";
+    if (!prefix.empty()) {
+      file << "  file(REMOVE \"" << dest_file << "\")\n";
+      file << "  file(RENAME \"" << to_file << "\" \"" << dest_file << "\")\n";
+    }
+    file << "      break()\n"
+         << "    endif()\n";
+    file << "  elseif(NOT EXISTS \"" << from_file << "\")\n"
+         << "    execute_process(COMMAND ${CMAKE_COMMAND}"
+         << " -E sleep 1)\n"
+         << "  endif()\n";
+    file << "endforeach()\n";
+  }
+
+  bool stdPipesUTF8 = true;
+
+  auto configGenex = [&](cm::string_view expr) -> std::string {
+    if (this->GetGlobalGenerator()->IsVisualStudio()) {
+      return cmStrCat("$<$<CONFIG:", config, ">:", expr, ">");
+    }
+    return std::string(expr);
+  };
+
+  cmCustomCommandLines commandLines = cmMakeSingleCommandLine(
+    { configGenex(cmSystemTools::GetCMakeCommand()),
+      configGenex(cmStrCat("-DPDB_PREFIX=", pdb_prefix)), configGenex("-P"),
+      configGenex(copy_script) });
+
+  const std::string no_main_dependency;
+  const std::vector<std::string> no_deps;
+  const char* no_message = "";
+  const char* no_current_dir = nullptr;
+  std::vector<std::string> no_byproducts;
+
+  std::vector<std::string> outputs;
+  outputs.push_back(
+    cmStrCat(target_compile_pdb_dir, pdb_prefix, ReuseFrom, ".pdb"));
+
+  if (this->GetGlobalGenerator()->IsVisualStudio()) {
+    this->AddCustomCommandToTarget(
+      target->GetName(), outputs, no_deps, commandLines,
+      cmCustomCommandType::PRE_BUILD, no_message, no_current_dir, true, false,
+      "", "", false, cmObjectLibraryCommands::Reject, stdPipesUTF8);
+  } else {
+    cmImplicitDependsList no_implicit_depends;
+    cmSourceFile* copy_rule = this->AddCustomCommandToOutput(
+      outputs, no_byproducts, no_deps, no_main_dependency, no_implicit_depends,
+      commandLines, no_message, no_current_dir, false, true, false, false, "",
+      "", stdPipesUTF8);
+
+    if (copy_rule) {
+      target->AddSource(copy_rule->ResolveFullPath());
+    }
+  }
+
+  target->Target->SetProperty("COMPILE_PDB_OUTPUT_DIRECTORY",
+                              target_compile_pdb_dir);
+}
+
+namespace {
+
+inline void RegisterUnitySources(cmGeneratorTarget* target, cmSourceFile* sf,
+                                 std::string const& filename)
+{
+  target->AddSourceFileToUnityBatch(sf->ResolveFullPath());
+  sf->SetProperty("UNITY_SOURCE_FILE", filename.c_str());
+}
+
+inline void IncludeFileInUnitySources(cmGeneratedFileStream& unity_file,
+                                      std::string const& sf_full_path,
+                                      cmProp beforeInclude,
+                                      cmProp afterInclude)
+{
+  if (beforeInclude) {
+    unity_file << *beforeInclude << "\n";
+  }
+
+  unity_file << "#include \"" << sf_full_path << "\"\n";
+
+  if (afterInclude) {
+    unity_file << *afterInclude << "\n";
+  }
+}
+
+std::vector<std::string> AddUnityFilesModeAuto(
+  cmGeneratorTarget* target, std::string const& lang,
+  std::vector<cmSourceFile*> const& filtered_sources, cmProp beforeInclude,
+  cmProp afterInclude, std::string const& filename_base, size_t batchSize)
+{
+  if (batchSize == 0) {
+    batchSize = filtered_sources.size();
+  }
+
+  std::vector<std::string> unity_files;
+  for (size_t itemsLeft = filtered_sources.size(), chunk, batch = 0;
+       itemsLeft > 0; itemsLeft -= chunk, ++batch) {
+
+    chunk = std::min(itemsLeft, batchSize);
+
+    std::string filename = cmStrCat(filename_base, "unity_", batch,
+                                    (lang == "C") ? "_c.c" : "_cxx.cxx");
+
+    const std::string filename_tmp = cmStrCat(filename, ".tmp");
+    {
+      size_t begin = batch * batchSize;
+      size_t end = begin + chunk;
+
+      cmGeneratedFileStream file(
+        filename_tmp, false,
+        target->GetGlobalGenerator()->GetMakefileEncoding());
+      file << "/* generated by CMake */\n\n";
+
+      for (; begin != end; ++begin) {
+        cmSourceFile* sf = filtered_sources[begin];
+        RegisterUnitySources(target, sf, filename);
+        IncludeFileInUnitySources(file, sf->ResolveFullPath(), beforeInclude,
+                                  afterInclude);
+      }
+    }
+    cmSystemTools::MoveFileIfDifferent(filename_tmp, filename);
+    unity_files.emplace_back(std::move(filename));
+  }
+  return unity_files;
+}
+
+std::vector<std::string> AddUnityFilesModeGroup(
+  cmGeneratorTarget* target, std::string const& lang,
+  std::vector<cmSourceFile*> const& filtered_sources, cmProp beforeInclude,
+  cmProp afterInclude, std::string const& filename_base)
+{
+  std::vector<std::string> unity_files;
+
+  // sources organized by group name. Drop any source
+  // without a group
+  std::unordered_map<std::string, std::vector<cmSourceFile*>> explicit_mapping;
+  for (cmSourceFile* sf : filtered_sources) {
+    if (cmProp value = sf->GetProperty("UNITY_GROUP")) {
+      auto i = explicit_mapping.find(*value);
+      if (i == explicit_mapping.end()) {
+        std::vector<cmSourceFile*> sources{ sf };
+        explicit_mapping.emplace(*value, sources);
+      } else {
+        i->second.emplace_back(sf);
+      }
+    }
+  }
+
+  for (auto const& item : explicit_mapping) {
+    auto const& name = item.first;
+    std::string filename = cmStrCat(filename_base, "unity_", name,
+                                    (lang == "C") ? "_c.c" : "_cxx.cxx");
+
+    const std::string filename_tmp = cmStrCat(filename, ".tmp");
+    {
+      cmGeneratedFileStream file(
+        filename_tmp, false,
+        target->GetGlobalGenerator()->GetMakefileEncoding());
+      file << "/* generated by CMake */\n\n";
+
+      for (cmSourceFile* sf : item.second) {
+        RegisterUnitySources(target, sf, filename);
+        IncludeFileInUnitySources(file, sf->ResolveFullPath(), beforeInclude,
+                                  afterInclude);
+      }
+    }
+    cmSystemTools::MoveFileIfDifferent(filename_tmp, filename);
+    unity_files.emplace_back(std::move(filename));
+  }
+
+  return unity_files;
+}
+}
+
 void cmLocalGenerator::AddUnityBuild(cmGeneratorTarget* target)
 {
   if (!target->GetPropertyAsBool("UNITY_BUILD")) {
@@ -2648,12 +2816,15 @@
   std::vector<cmSourceFile*> sources;
   target->GetSourceFiles(sources, config);
 
-  auto batchSizeString = target->GetProperty("UNITY_BUILD_BATCH_SIZE");
-  const size_t unityBatchSize =
-    static_cast<size_t>(std::atoi(batchSizeString));
+  cmProp batchSizeString = target->GetProperty("UNITY_BUILD_BATCH_SIZE");
+  const size_t unityBatchSize = batchSizeString
+    ? static_cast<size_t>(std::atoi(batchSizeString->c_str()))
+    : 0;
 
-  auto beforeInclude = target->GetProperty("UNITY_BUILD_CODE_BEFORE_INCLUDE");
-  auto afterInclude = target->GetProperty("UNITY_BUILD_CODE_AFTER_INCLUDE");
+  cmProp beforeInclude =
+    target->GetProperty("UNITY_BUILD_CODE_BEFORE_INCLUDE");
+  cmProp afterInclude = target->GetProperty("UNITY_BUILD_CODE_AFTER_INCLUDE");
+  cmProp unityMode = target->GetProperty("UNITY_BUILD_MODE");
 
   for (std::string lang : { "C", "CXX" }) {
     std::vector<cmSourceFile*> filtered_sources;
@@ -2668,53 +2839,28 @@
                      !sf->GetProperty("INCLUDE_DIRECTORIES");
                  });
 
-    size_t batchSize = unityBatchSize;
-    if (unityBatchSize == 0) {
-      batchSize = filtered_sources.size();
+    std::vector<std::string> unity_files;
+    if (!unityMode || *unityMode == "BATCH") {
+      unity_files =
+        AddUnityFilesModeAuto(target, lang, filtered_sources, beforeInclude,
+                              afterInclude, filename_base, unityBatchSize);
+    } else if (unityMode && *unityMode == "GROUP") {
+      unity_files =
+        AddUnityFilesModeGroup(target, lang, filtered_sources, beforeInclude,
+                               afterInclude, filename_base);
+    } else {
+      // unity mode is set to an unsupported value
+      std::string e("Invalid UNITY_BUILD_MODE value of " + *unityMode +
+                    " assigned to target " + target->GetName() +
+                    ". Acceptable values are BATCH and GROUP.");
+      this->IssueMessage(MessageType::FATAL_ERROR, e);
     }
 
-    for (size_t itemsLeft = filtered_sources.size(), chunk, batch = 0;
-         itemsLeft > 0; itemsLeft -= chunk, ++batch) {
-
-      chunk = std::min(itemsLeft, batchSize);
-
-      std::string filename = cmStrCat(filename_base, "unity_", batch,
-                                      (lang == "C") ? "_c.c" : "_cxx.cxx");
-
-      const std::string filename_tmp = cmStrCat(filename, ".tmp");
-      {
-        size_t begin = batch * batchSize;
-        size_t end = begin + chunk;
-
-        cmGeneratedFileStream file(
-          filename_tmp, false,
-          this->GetGlobalGenerator()->GetMakefileEncoding());
-        file << "/* generated by CMake */\n\n";
-
-        for (; begin != end; ++begin) {
-          cmSourceFile* sf = filtered_sources[begin];
-
-          target->AddSourceFileToUnityBatch(sf->ResolveFullPath());
-          sf->SetProperty("UNITY_SOURCE_FILE", filename.c_str());
-
-          if (beforeInclude) {
-            file << beforeInclude << "\n";
-          }
-
-          file << "#include \"" << sf->ResolveFullPath() << "\"\n";
-
-          if (afterInclude) {
-            file << afterInclude << "\n";
-          }
-        }
-      }
-      cmSystemTools::MoveFileIfDifferent(filename_tmp, filename);
-
-      target->AddSource(filename, true);
-
-      auto unity = this->Makefile->GetOrCreateSource(filename);
+    for (auto const& file : unity_files) {
+      auto unity = this->GetMakefile()->GetOrCreateSource(file);
+      target->AddSource(file, true);
       unity->SetProperty("SKIP_UNITY_BUILD_INCLUSION", "ON");
-      unity->SetProperty("UNITY_SOURCE_FILE", filename.c_str());
+      unity->SetProperty("UNITY_SOURCE_FILE", file.c_str());
     }
   }
 }
@@ -2931,7 +3077,7 @@
   if (!lang.empty()) {
     const char* df =
       this->Makefile->GetDefinition(cmStrCat("CMAKE_", lang, "_DEFINE_FLAG"));
-    if (df && *df) {
+    if (cmNonempty(df)) {
       dflag = df;
     }
   }
@@ -2950,11 +3096,11 @@
       // command line without any escapes.  However we still have to
       // get the '$' and '#' characters through WMake as '$$' and
       // '$#'.
-      for (const char* c = define.c_str(); *c; ++c) {
-        if (*c == '$' || *c == '#') {
+      for (char c : define) {
+        if (c == '$' || c == '#') {
           def += '$';
         }
-        def += *c;
+        def += c;
       }
     } else {
       // Make the definition appear properly on the command line.  Use
@@ -2986,19 +3132,19 @@
   }
 }
 
-const char* cmLocalGenerator::GetFeature(const std::string& feature,
-                                         const std::string& config)
+cmProp cmLocalGenerator::GetFeature(const std::string& feature,
+                                    const std::string& config)
 {
   std::string featureName = feature;
-  // TODO: Define accumulation policy for features (prepend, append, replace).
-  // Currently we always replace.
+  // TODO: Define accumulation policy for features (prepend, append,
+  // replace). Currently we always replace.
   if (!config.empty()) {
     featureName += "_";
     featureName += cmSystemTools::UpperCase(config);
   }
   cmStateSnapshot snp = this->StateSnapshot;
   while (snp.IsValid()) {
-    if (const char* value = snp.GetDirectory().GetProperty(featureName)) {
+    if (cmProp value = snp.GetDirectory().GetProperty(featureName)) {
       return value;
     }
     snp = snp.GetBuildsystemDirectoryParent();
@@ -3064,8 +3210,8 @@
     }
 
     // Include the user-specified pre-install script for this target.
-    if (const char* preinstall = l->GetProperty("PRE_INSTALL_SCRIPT")) {
-      cmInstallScriptGenerator g(preinstall, false, "", false);
+    if (cmProp preinstall = l->GetProperty("PRE_INSTALL_SCRIPT")) {
+      cmInstallScriptGenerator g(*preinstall, false, "", false);
       g.Generate(os, config, configurationTypes);
     }
 
@@ -3117,8 +3263,8 @@
     }
 
     // Include the user-specified post-install script for this target.
-    if (const char* postinstall = l->GetProperty("POST_INSTALL_SCRIPT")) {
-      cmInstallScriptGenerator g(postinstall, false, "", false);
+    if (cmProp postinstall = l->GetProperty("POST_INSTALL_SCRIPT")) {
+      cmInstallScriptGenerator g(*postinstall, false, "", false);
       g.Generate(os, config, configurationTypes);
     }
   }
@@ -3304,11 +3450,12 @@
   // Select a nice-looking reference to the source file to construct
   // the object file name.
   std::string objectName;
+  // XXX(clang-tidy): https://bugs.llvm.org/show_bug.cgi?id=44165
+  // NOLINTNEXTLINE(bugprone-branch-clone)
   if ((relSource && !relBinary) || (subSource && !subBinary)) {
     objectName = relFromSource;
-  } else if ((relBinary && !relSource) || (subBinary && !subSource)) {
-    objectName = relFromBinary;
-  } else if (relFromBinary.length() < relFromSource.length()) {
+  } else if ((relBinary && !relSource) || (subBinary && !subSource) ||
+             relFromBinary.length() < relFromSource.length()) {
     objectName = relFromBinary;
   } else {
     objectName = relFromSource;
@@ -3326,12 +3473,12 @@
   // Ensure that for the CMakeFiles/<target>.dir/generated_source_file
   // we don't end up having:
   // CMakeFiles/<target>.dir/CMakeFiles/<target>.dir/generated_source_file.obj
-  const char* unitySourceFile = source.GetProperty("UNITY_SOURCE_FILE");
-  const char* pchExtension = source.GetProperty("PCH_EXTENSION");
+  cmProp unitySourceFile = source.GetProperty("UNITY_SOURCE_FILE");
+  cmProp psExtension = source.GetProperty("PCH_EXTENSION");
   const bool isPchObject = objectName.find("cmake_pch") != std::string::npos;
-  if (unitySourceFile || pchExtension || isPchObject) {
-    if (pchExtension) {
-      customOutputExtension = pchExtension;
+  if (unitySourceFile || psExtension || isPchObject) {
+    if (psExtension) {
+      customOutputExtension = psExtension->c_str();
     }
 
     cmsys::RegularExpression var("(CMakeFiles/[^/]+.dir/)");
@@ -3467,7 +3614,6 @@
       break;
     case cmPolicies::NEW:
       // New behavior is to ignore the variable.
-      return false;
     case cmPolicies::REQUIRED_IF_USED:
     case cmPolicies::REQUIRED_ALWAYS:
       // This will never be the case because the only way to require
@@ -3529,8 +3675,8 @@
 static void cmLGInfoProp(cmMakefile* mf, cmGeneratorTarget* target,
                          const std::string& prop)
 {
-  if (const char* val = target->GetProperty(prop)) {
-    mf->AddDefinition(prop, val);
+  if (cmProp val = target->GetProperty(prop)) {
+    mf->AddDefinition(prop, *val);
   }
 }
 
@@ -3539,8 +3685,8 @@
                                               const std::string& fname)
 {
   // Find the Info.plist template.
-  const char* in = target->GetProperty("MACOSX_BUNDLE_INFO_PLIST");
-  std::string inFile = (in && *in) ? in : "MacOSXBundleInfo.plist.in";
+  cmProp in = target->GetProperty("MACOSX_BUNDLE_INFO_PLIST");
+  std::string inFile = cmNonempty(in) ? *in : "MacOSXBundleInfo.plist.in";
   if (!cmSystemTools::FileIsFullPath(inFile)) {
     std::string inMod = this->Makefile->GetModulesFile(inFile);
     if (!inMod.empty()) {
@@ -3570,7 +3716,7 @@
   cmLGInfoProp(mf, target, "MACOSX_BUNDLE_SHORT_VERSION_STRING");
   cmLGInfoProp(mf, target, "MACOSX_BUNDLE_BUNDLE_VERSION");
   cmLGInfoProp(mf, target, "MACOSX_BUNDLE_COPYRIGHT");
-  mf->ConfigureFile(inFile, fname, false, false, false);
+  mf->ConfigureFile(inFile, fname, false, false, false, true);
 }
 
 void cmLocalGenerator::GenerateFrameworkInfoPList(
@@ -3578,8 +3724,8 @@
   const std::string& fname)
 {
   // Find the Info.plist template.
-  const char* in = target->GetProperty("MACOSX_FRAMEWORK_INFO_PLIST");
-  std::string inFile = (in && *in) ? in : "MacOSXFrameworkInfo.plist.in";
+  cmProp in = target->GetProperty("MACOSX_FRAMEWORK_INFO_PLIST");
+  std::string inFile = cmNonempty(in) ? *in : "MacOSXFrameworkInfo.plist.in";
   if (!cmSystemTools::FileIsFullPath(inFile)) {
     std::string inMod = this->Makefile->GetModulesFile(inFile);
     if (!inMod.empty()) {
@@ -3605,7 +3751,7 @@
   cmLGInfoProp(mf, target, "MACOSX_FRAMEWORK_IDENTIFIER");
   cmLGInfoProp(mf, target, "MACOSX_FRAMEWORK_SHORT_VERSION_STRING");
   cmLGInfoProp(mf, target, "MACOSX_FRAMEWORK_BUNDLE_VERSION");
-  mf->ConfigureFile(inFile, fname, false, false, false);
+  mf->ConfigureFile(inFile, fname, false, false, false, true);
 }
 
 namespace {
@@ -3647,7 +3793,7 @@
   const cmCustomCommandLines& commandLines, const char* comment,
   const char* workingDir, bool replace, bool escapeOldStyle,
   bool uses_terminal, bool command_expand_lists, const std::string& depfile,
-  const std::string& job_pool)
+  const std::string& job_pool, bool stdPipesUTF8)
 {
   cmMakefile* mf = lg.GetMakefile();
 
@@ -3709,7 +3855,8 @@
     }
 
     std::unique_ptr<cmCustomCommand> cc = cm::make_unique<cmCustomCommand>(
-      outputs, byproducts, depends2, commandLines, lfbt, comment, workingDir);
+      outputs, byproducts, depends2, commandLines, lfbt, comment, workingDir,
+      stdPipesUTF8);
     cc->SetEscapeOldStyle(escapeOldStyle);
     cc->SetEscapeAllowMakeVars(true);
     cc->SetImplicitDepends(implicit_depends);
@@ -3736,7 +3883,7 @@
                               const char* workingDir, bool escapeOldStyle,
                               bool uses_terminal, const std::string& depfile,
                               const std::string& job_pool,
-                              bool command_expand_lists)
+                              bool command_expand_lists, bool stdPipesUTF8)
 {
   cmMakefile* mf = lg.GetMakefile();
 
@@ -3746,7 +3893,7 @@
   // Add the command to the appropriate build step for the target.
   std::vector<std::string> no_output;
   cmCustomCommand cc(no_output, byproducts, depends, commandLines, lfbt,
-                     comment, workingDir);
+                     comment, workingDir, stdPipesUTF8);
   cc.SetEscapeOldStyle(escapeOldStyle);
   cc.SetEscapeAllowMakeVars(true);
   cc.SetUsesTerminal(uses_terminal);
@@ -3777,7 +3924,7 @@
   const cmCustomCommandLines& commandLines, const char* comment,
   const char* workingDir, bool replace, bool escapeOldStyle,
   bool uses_terminal, bool command_expand_lists, const std::string& depfile,
-  const std::string& job_pool)
+  const std::string& job_pool, bool stdPipesUTF8)
 {
   // Always create the output sources and mark them generated.
   CreateGeneratedSources(lg, outputs, origin, lfbt);
@@ -3786,7 +3933,7 @@
   return AddCustomCommand(
     lg, lfbt, outputs, byproducts, depends, main_dependency, implicit_depends,
     commandLines, comment, workingDir, replace, escapeOldStyle, uses_terminal,
-    command_expand_lists, depfile, job_pool);
+    command_expand_lists, depfile, job_pool, stdPipesUTF8);
 }
 
 void AppendCustomCommandToOutput(cmLocalGenerator& lg,
@@ -3822,7 +3969,7 @@
                        const cmCustomCommandLines& commandLines,
                        bool escapeOldStyle, const char* comment,
                        bool uses_terminal, bool command_expand_lists,
-                       const std::string& job_pool)
+                       const std::string& job_pool, bool stdPipesUTF8)
 {
   // Always create the byproduct sources and mark them generated.
   CreateGeneratedSource(lg, force.Name, origin, lfbt);
@@ -3837,9 +3984,9 @@
   cmImplicitDependsList no_implicit_depends;
   cmSourceFile* rule = AddCustomCommand(
     lg, lfbt, { force.Name }, byproducts, depends, no_main_dependency,
-    no_implicit_depends, commandLines, comment, workingDir, /*replace=*/false,
-    escapeOldStyle, uses_terminal, command_expand_lists, /*depfile=*/"",
-    job_pool);
+    no_implicit_depends, commandLines, comment, workingDir,
+    /*replace=*/false, escapeOldStyle, uses_terminal, command_expand_lists,
+    /*depfile=*/"", job_pool, stdPipesUTF8);
   if (rule) {
     lg.GetMakefile()->AddTargetByproducts(target, byproducts);
   }
diff --git a/Source/cmLocalGenerator.h b/Source/cmLocalGenerator.h
index a459384..0c51a65 100644
--- a/Source/cmLocalGenerator.h
+++ b/Source/cmLocalGenerator.h
@@ -13,13 +13,14 @@
 #include <unordered_map>
 #include <vector>
 
-#include "cm_kwiml.h"
+#include <cm3p/kwiml/int.h>
 
 #include "cmCustomCommandTypes.h"
 #include "cmListFileCache.h"
 #include "cmMessageType.h"
 #include "cmOutputConverter.h"
 #include "cmPolicies.h"
+#include "cmProperty.h"
 #include "cmStateSnapshot.h"
 
 class cmComputeLinkInformation;
@@ -105,8 +106,8 @@
 
   void AddArchitectureFlags(std::string& flags,
                             cmGeneratorTarget const* target,
-                            const std::string& lang,
-                            const std::string& config);
+                            const std::string& lang, const std::string& config,
+                            const std::string& filterArch = std::string());
 
   void AddLanguageFlags(std::string& flags, cmGeneratorTarget const* target,
                         const std::string& lang, const std::string& config);
@@ -123,7 +124,8 @@
                               const std::string& config);
   void AddCompilerRequirementFlag(std::string& flags,
                                   cmGeneratorTarget const* target,
-                                  const std::string& lang);
+                                  const std::string& lang,
+                                  const std::string& config);
   //! Append flags to a string.
   virtual void AppendFlags(std::string& flags,
                            const std::string& newFlags) const;
@@ -208,8 +210,7 @@
   void AppendFeatureOptions(std::string& flags, const std::string& lang,
                             const char* feature);
 
-  const char* GetFeature(const std::string& feature,
-                         const std::string& config);
+  cmProp GetFeature(const std::string& feature, const std::string& config);
 
   /** \brief Get absolute path to dependency \a name
    *
@@ -297,7 +298,8 @@
     const char* comment, const char* workingDir, bool escapeOldStyle = true,
     bool uses_terminal = false, const std::string& depfile = "",
     const std::string& job_pool = "", bool command_expand_lists = false,
-    cmObjectLibraryCommands objLibCommands = cmObjectLibraryCommands::Reject);
+    cmObjectLibraryCommands objLibCommands = cmObjectLibraryCommands::Reject,
+    bool stdPipesUTF8 = false);
 
   /**
    * Add a custom command to a source file.
@@ -308,7 +310,8 @@
     const cmCustomCommandLines& commandLines, const char* comment,
     const char* workingDir, bool replace = false, bool escapeOldStyle = true,
     bool uses_terminal = false, bool command_expand_lists = false,
-    const std::string& depfile = "", const std::string& job_pool = "");
+    const std::string& depfile = "", const std::string& job_pool = "",
+    bool stdPipesUTF8 = false);
   cmSourceFile* AddCustomCommandToOutput(
     const std::vector<std::string>& outputs,
     const std::vector<std::string>& byproducts,
@@ -318,7 +321,8 @@
     const cmCustomCommandLines& commandLines, const char* comment,
     const char* workingDir, bool replace = false, bool escapeOldStyle = true,
     bool uses_terminal = false, bool command_expand_lists = false,
-    const std::string& depfile = "", const std::string& job_pool = "");
+    const std::string& depfile = "", const std::string& job_pool = "",
+    bool stdPipesUTF8 = false);
 
   /**
    * Add a utility to the build.  A utility target is a command that is run
@@ -330,7 +334,8 @@
     const std::vector<std::string>& depends,
     const cmCustomCommandLines& commandLines, bool escapeOldStyle = true,
     const char* comment = nullptr, bool uses_terminal = false,
-    bool command_expand_lists = false, const std::string& job_pool = "");
+    bool command_expand_lists = false, const std::string& job_pool = "",
+    bool stdPipesUTF8 = false);
 
   std::string GetProjectName() const;
 
@@ -417,6 +422,11 @@
 
   /** Fill out these strings for the given target.  Libraries to link,
    *  flags, and linkflags. */
+  void GetDeviceLinkFlags(cmLinkLineComputer* linkLineComputer,
+                          const std::string& config, std::string& linkLibs,
+                          std::string& linkFlags, std::string& frameworkPath,
+                          std::string& linkPath, cmGeneratorTarget* target);
+
   void GetTargetFlags(cmLinkLineComputer* linkLineComputer,
                       const std::string& config, std::string& linkLibs,
                       std::string& flags, std::string& linkFlags,
@@ -435,10 +445,11 @@
                                              std::string const& lang) const;
   void GetTargetCompileFlags(cmGeneratorTarget* target,
                              std::string const& config,
-                             std::string const& lang, std::string& flags);
-  std::vector<BT<std::string>> GetTargetCompileFlags(cmGeneratorTarget* target,
-                                                     std::string const& config,
-                                                     std::string const& lang);
+                             std::string const& lang, std::string& flags,
+                             std::string const& arch = std::string());
+  std::vector<BT<std::string>> GetTargetCompileFlags(
+    cmGeneratorTarget* target, std::string const& config,
+    std::string const& lang, std::string const& arch = std::string());
 
   std::string GetFrameworkFlags(std::string const& l,
                                 std::string const& config,
@@ -530,6 +541,11 @@
   void ComputeObjectMaxPath();
   bool AllAppleArchSysrootsAreTheSame(const std::vector<std::string>& archs,
                                       const char* sysroot);
+
+  void CopyPchCompilePdb(const std::string& config, cmGeneratorTarget* target,
+                         const std::string& ReuseFrom,
+                         cmGeneratorTarget* reuseTarget,
+                         std::vector<std::string> const& extensions);
 };
 
 #if !defined(CMAKE_BOOTSTRAP)
@@ -549,7 +565,7 @@
                               const char* workingDir, bool escapeOldStyle,
                               bool uses_terminal, const std::string& depfile,
                               const std::string& job_pool,
-                              bool command_expand_lists);
+                              bool command_expand_lists, bool stdPipesUTF8);
 
 cmSourceFile* AddCustomCommandToOutput(
   cmLocalGenerator& lg, const cmListFileBacktrace& lfbt,
@@ -560,7 +576,7 @@
   const cmCustomCommandLines& commandLines, const char* comment,
   const char* workingDir, bool replace, bool escapeOldStyle,
   bool uses_terminal, bool command_expand_lists, const std::string& depfile,
-  const std::string& job_pool);
+  const std::string& job_pool, bool stdPipesUTF8);
 
 void AppendCustomCommandToOutput(cmLocalGenerator& lg,
                                  const cmListFileBacktrace& lfbt,
@@ -577,7 +593,7 @@
                        const cmCustomCommandLines& commandLines,
                        bool escapeOldStyle, const char* comment,
                        bool uses_terminal, bool command_expand_lists,
-                       const std::string& job_pool);
+                       const std::string& job_pool, bool stdPipesUTF8);
 }
 
 #endif
diff --git a/Source/cmLocalGhsMultiGenerator.cxx b/Source/cmLocalGhsMultiGenerator.cxx
index 098fa5a..a23ad57 100644
--- a/Source/cmLocalGhsMultiGenerator.cxx
+++ b/Source/cmLocalGhsMultiGenerator.cxx
@@ -11,7 +11,6 @@
 #include "cmGhsMultiTargetGenerator.h"
 #include "cmGlobalGenerator.h"
 #include "cmSourceFile.h"
-#include "cmStateTypes.h"
 #include "cmStringAlgorithms.h"
 #include "cmSystemTools.h"
 
@@ -33,7 +32,7 @@
 void cmLocalGhsMultiGenerator::GenerateTargetsDepthFirst(
   cmGeneratorTarget* target, std::vector<cmGeneratorTarget*>& remaining)
 {
-  if (target->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
+  if (!target->IsInBuildSystem()) {
     return;
   }
   // Find this target in the list of remaining targets.
diff --git a/Source/cmLocalNinjaGenerator.cxx b/Source/cmLocalNinjaGenerator.cxx
index 56e9f81..eb841d9 100644
--- a/Source/cmLocalNinjaGenerator.cxx
+++ b/Source/cmLocalNinjaGenerator.cxx
@@ -23,6 +23,7 @@
 #include "cmLocalGenerator.h"
 #include "cmMakefile.h"
 #include "cmNinjaTargetGenerator.h"
+#include "cmProperty.h"
 #include "cmRulePlaceholderExpander.h"
 #include "cmSourceFile.h"
 #include "cmState.h"
@@ -83,13 +84,31 @@
     if (!showIncludesPrefix.empty()) {
       cmGlobalNinjaGenerator::WriteComment(this->GetRulesFileStream(),
                                            "localized /showIncludes string");
-      this->GetRulesFileStream()
-        << "msvc_deps_prefix = " << showIncludesPrefix << "\n\n";
+      this->GetRulesFileStream() << "msvc_deps_prefix = ";
+#ifdef WIN32
+      // Ninja uses the ANSI Windows APIs, so strings in the rules file
+      // typically need to be ANSI encoded. However, in this case the compiler
+      // is being invoked using the UTF-8 codepage so the /showIncludes prefix
+      // will be UTF-8 encoded on stdout. Ninja can't successfully compare this
+      // UTF-8 encoded prefix to the ANSI encoded msvc_deps_prefix if it
+      // contains any non-ASCII characters and dependency checking will fail.
+      // As a workaround, leave the msvc_deps_prefix UTF-8 encoded even though
+      // the rest of the file is ANSI encoded.
+      if (GetConsoleOutputCP() == CP_UTF8 && GetACP() != CP_UTF8) {
+        this->GetRulesFileStream().WriteRaw(showIncludesPrefix);
+      } else {
+        this->GetRulesFileStream() << showIncludesPrefix;
+      }
+#else
+      // It's safe to use the standard encoding on other platforms.
+      this->GetRulesFileStream() << showIncludesPrefix;
+#endif
+      this->GetRulesFileStream() << "\n\n";
     }
   }
 
   for (const auto& target : this->GetGeneratorTargets()) {
-    if (target->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
+    if (!target->IsInBuildSystem()) {
       continue;
     }
     auto tg = cmNinjaTargetGenerator::New(target.get());
@@ -101,9 +120,10 @@
               this->GetGlobalGenerator()->IsMultiConfig()) {
             cmNinjaBuild phonyAlias("phony");
             this->GetGlobalNinjaGenerator()->AppendTargetOutputs(
-              target.get(), phonyAlias.Outputs, "");
+              target.get(), phonyAlias.Outputs, "", DependOnTargetArtifact);
             this->GetGlobalNinjaGenerator()->AppendTargetOutputs(
-              target.get(), phonyAlias.ExplicitDeps, config);
+              target.get(), phonyAlias.ExplicitDeps, config,
+              DependOnTargetArtifact);
             this->GetGlobalNinjaGenerator()->WriteBuild(
               *this->GetGlobalNinjaGenerator()->GetConfigFileStream(config),
               phonyAlias);
@@ -114,11 +134,12 @@
           if (!this->GetGlobalNinjaGenerator()->GetDefaultConfigs().empty()) {
             cmNinjaBuild phonyAlias("phony");
             this->GetGlobalNinjaGenerator()->AppendTargetOutputs(
-              target.get(), phonyAlias.Outputs, "");
+              target.get(), phonyAlias.Outputs, "", DependOnTargetArtifact);
             for (auto const& config :
                  this->GetGlobalNinjaGenerator()->GetDefaultConfigs()) {
               this->GetGlobalNinjaGenerator()->AppendTargetOutputs(
-                target.get(), phonyAlias.ExplicitDeps, config);
+                target.get(), phonyAlias.ExplicitDeps, config,
+                DependOnTargetArtifact);
             }
             this->GetGlobalNinjaGenerator()->WriteBuild(
               *this->GetGlobalNinjaGenerator()->GetDefaultFileStream(),
@@ -126,10 +147,11 @@
           }
           cmNinjaBuild phonyAlias("phony");
           this->GetGlobalNinjaGenerator()->AppendTargetOutputs(
-            target.get(), phonyAlias.Outputs, "all");
+            target.get(), phonyAlias.Outputs, "all", DependOnTargetArtifact);
           for (auto const& config : this->GetConfigNames()) {
             this->GetGlobalNinjaGenerator()->AppendTargetOutputs(
-              target.get(), phonyAlias.ExplicitDeps, config);
+              target.get(), phonyAlias.ExplicitDeps, config,
+              DependOnTargetArtifact);
           }
           this->GetGlobalNinjaGenerator()->WriteBuild(
             *this->GetGlobalNinjaGenerator()->GetDefaultFileStream(),
@@ -181,8 +203,9 @@
   bool forceFullPaths)
 {
   if (forceFullPaths) {
-    return this->ConvertToOutputFormat(cmSystemTools::CollapseFullPath(path),
-                                       format);
+    return this->ConvertToOutputFormat(
+      cmSystemTools::CollapseFullPath(path, this->GetCurrentBinaryDirectory()),
+      format);
   }
   return this->ConvertToOutputFormat(
     this->MaybeConvertToRelativePath(this->GetBinaryDirectory(), path),
@@ -243,9 +266,8 @@
 void cmLocalNinjaGenerator::WriteProjectHeader(std::ostream& os)
 {
   cmGlobalNinjaGenerator::WriteDivider(os);
-  os << "# Project: " << this->GetProjectName() << std::endl
-     << "# Configurations: " << cmJoin(this->GetConfigNames(), ", ")
-     << std::endl;
+  os << "# Project: " << this->GetProjectName() << '\n'
+     << "# Configurations: " << cmJoin(this->GetConfigNames(), ", ") << '\n';
   cmGlobalNinjaGenerator::WriteDivider(os);
 }
 
@@ -272,8 +294,7 @@
 
   cmGlobalNinjaGenerator::WriteComment(
     os, "Minimal version of Ninja required by this file");
-  os << "ninja_required_version = " << requiredVersion << std::endl
-     << std::endl;
+  os << "ninja_required_version = " << requiredVersion << "\n\n";
 }
 
 void cmLocalNinjaGenerator::WriteNinjaConfigurationVariable(
@@ -288,23 +309,22 @@
 {
   cmGlobalNinjaGenerator::WriteDivider(os);
 
-  const char* jobpools =
+  cmProp jobpools =
     this->GetCMakeInstance()->GetState()->GetGlobalProperty("JOB_POOLS");
   if (!jobpools) {
-    jobpools = this->GetMakefile()->GetDefinition("CMAKE_JOB_POOLS");
+    jobpools = this->GetMakefile()->GetDef("CMAKE_JOB_POOLS");
   }
   if (jobpools) {
     cmGlobalNinjaGenerator::WriteComment(
       os, "Pools defined by global property JOB_POOLS");
-    std::vector<std::string> pools = cmExpandedList(jobpools);
+    std::vector<std::string> pools = cmExpandedList(*jobpools);
     for (std::string const& pool : pools) {
       const std::string::size_type eq = pool.find('=');
       unsigned int jobs;
       if (eq != std::string::npos &&
           sscanf(pool.c_str() + eq, "=%u", &jobs) == 1) {
-        os << "pool " << pool.substr(0, eq) << std::endl;
-        os << "  depth = " << jobs << std::endl;
-        os << std::endl;
+        os << "pool " << pool.substr(0, eq) << "\n  depth = " << jobs
+           << "\n\n";
       } else {
         cmSystemTools::Error("Invalid pool defined by property 'JOB_POOLS': " +
                              pool);
@@ -316,8 +336,7 @@
 void cmLocalNinjaGenerator::WriteNinjaFilesInclusionConfig(std::ostream& os)
 {
   cmGlobalNinjaGenerator::WriteDivider(os);
-  os << "# Include auxiliary files.\n"
-     << "\n";
+  os << "# Include auxiliary files.\n\n";
   cmGlobalNinjaGenerator* ng = this->GetGlobalNinjaGenerator();
   std::string const ninjaCommonFile =
     ng->NinjaOutputPath(cmGlobalNinjaMultiGenerator::NINJA_COMMON_FILE);
@@ -330,8 +349,7 @@
 void cmLocalNinjaGenerator::WriteNinjaFilesInclusionCommon(std::ostream& os)
 {
   cmGlobalNinjaGenerator::WriteDivider(os);
-  os << "# Include auxiliary files.\n"
-     << "\n";
+  os << "# Include auxiliary files.\n\n";
   cmGlobalNinjaGenerator* ng = this->GetGlobalNinjaGenerator();
   std::string const ninjaRulesFile =
     ng->NinjaOutputPath(cmGlobalNinjaGenerator::NINJA_RULES_FILE);
@@ -344,22 +362,22 @@
 void cmLocalNinjaGenerator::WriteProcessedMakefile(std::ostream& os)
 {
   cmGlobalNinjaGenerator::WriteDivider(os);
-  os << "# Write statements declared in CMakeLists.txt:" << std::endl
+  os << "# Write statements declared in CMakeLists.txt:\n"
      << "# " << this->Makefile->GetDefinition("CMAKE_CURRENT_LIST_FILE")
-     << std::endl;
+     << '\n';
   if (this->IsRootMakefile()) {
-    os << "# Which is the root file." << std::endl;
+    os << "# Which is the root file.\n";
   }
   cmGlobalNinjaGenerator::WriteDivider(os);
-  os << std::endl;
+  os << '\n';
 }
 
 void cmLocalNinjaGenerator::AppendTargetOutputs(cmGeneratorTarget* target,
                                                 cmNinjaDeps& outputs,
                                                 const std::string& config)
 {
-  this->GetGlobalNinjaGenerator()->AppendTargetOutputs(target, outputs,
-                                                       config);
+  this->GetGlobalNinjaGenerator()->AppendTargetOutputs(target, outputs, config,
+                                                       DependOnTargetArtifact);
 }
 
 void cmLocalNinjaGenerator::AppendTargetDepends(cmGeneratorTarget* target,
@@ -669,10 +687,9 @@
 std::string cmLocalNinjaGenerator::MakeCustomLauncher(
   cmCustomCommandGenerator const& ccg)
 {
-  const char* property_value =
-    this->Makefile->GetProperty("RULE_LAUNCH_CUSTOM");
+  cmProp property_value = this->Makefile->GetProperty("RULE_LAUNCH_CUSTOM");
 
-  if (!property_value || !*property_value) {
+  if (!cmNonempty(property_value)) {
     return std::string();
   }
 
@@ -694,7 +711,7 @@
   std::unique_ptr<cmRulePlaceholderExpander> rulePlaceholderExpander(
     this->CreateRulePlaceholderExpander());
 
-  std::string launcher = property_value;
+  std::string launcher = *property_value;
   rulePlaceholderExpander->ExpandRuleVariables(this, launcher, vars);
   if (!launcher.empty()) {
     launcher += " ";
@@ -705,11 +722,11 @@
 
 void cmLocalNinjaGenerator::AdditionalCleanFiles(const std::string& config)
 {
-  if (const char* prop_value =
+  if (cmProp prop_value =
         this->Makefile->GetProperty("ADDITIONAL_CLEAN_FILES")) {
     std::vector<std::string> cleanFiles;
     {
-      cmExpandList(cmGeneratorExpression::Evaluate(prop_value, this, config),
+      cmExpandList(cmGeneratorExpression::Evaluate(*prop_value, this, config),
                    cleanFiles);
     }
     std::string const& binaryDir = this->GetCurrentBinaryDirectory();
diff --git a/Source/cmLocalNinjaGenerator.h b/Source/cmLocalNinjaGenerator.h
index ef160e7..73c0cde 100644
--- a/Source/cmLocalNinjaGenerator.h
+++ b/Source/cmLocalNinjaGenerator.h
@@ -66,10 +66,10 @@
 
   void AppendTargetOutputs(cmGeneratorTarget* target, cmNinjaDeps& outputs,
                            const std::string& config);
-  void AppendTargetDepends(
-    cmGeneratorTarget* target, cmNinjaDeps& outputs, const std::string& config,
-    const std::string& fileConfig,
-    cmNinjaTargetDepends depends = DependOnTargetArtifact);
+  void AppendTargetDepends(cmGeneratorTarget* target, cmNinjaDeps& outputs,
+                           const std::string& config,
+                           const std::string& fileConfig,
+                           cmNinjaTargetDepends depends);
 
   void AddCustomCommandTarget(cmCustomCommand const* cc,
                               cmGeneratorTarget* target);
diff --git a/Source/cmLocalUnixMakefileGenerator3.cxx b/Source/cmLocalUnixMakefileGenerator3.cxx
index c9c656c..8acd1e3 100644
--- a/Source/cmLocalUnixMakefileGenerator3.cxx
+++ b/Source/cmLocalUnixMakefileGenerator3.cxx
@@ -28,6 +28,7 @@
 #include "cmMakefile.h"
 #include "cmMakefileTargetGenerator.h"
 #include "cmOutputConverter.h"
+#include "cmProperty.h"
 #include "cmRange.h"
 #include "cmRulePlaceholderExpander.h"
 #include "cmSourceFile.h"
@@ -48,37 +49,6 @@
 #  include "cmDependsJava.h"
 #endif
 
-// Escape special characters in Makefile dependency lines
-class cmMakeSafe
-{
-public:
-  cmMakeSafe(const char* s)
-    : Data(s)
-  {
-  }
-  cmMakeSafe(std::string const& s)
-    : Data(s.c_str())
-  {
-  }
-
-private:
-  const char* Data;
-  friend std::ostream& operator<<(std::ostream& os, cmMakeSafe const& self)
-  {
-    for (const char* c = self.Data; *c; ++c) {
-      switch (*c) {
-        case '=':
-          os << "$(EQUALS)";
-          break;
-        default:
-          os << *c;
-          break;
-      }
-    }
-    return os;
-  }
-};
-
 // Helper function used below.
 static std::string cmSplitExtension(std::string const& in, std::string& base)
 {
@@ -131,7 +101,7 @@
   cmGlobalUnixMakefileGenerator3* gg =
     static_cast<cmGlobalUnixMakefileGenerator3*>(this->GlobalGenerator);
   for (const auto& target : this->GetGeneratorTargets()) {
-    if (target->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
+    if (!target->IsInBuildSystem()) {
       continue;
     }
     std::unique_ptr<cmMakefileTargetGenerator> tg(
@@ -167,7 +137,7 @@
   std::map<std::string, LocalObjectInfo>& localObjectFiles)
 {
   for (const auto& gt : this->GetGeneratorTargets()) {
-    if (gt->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
+    if (!gt->CanCompileSources()) {
       continue;
     }
     std::vector<cmSourceFile const*> objectSources;
@@ -498,6 +468,14 @@
   return this->HomeRelativeOutputPath;
 }
 
+std::string cmLocalUnixMakefileGenerator3::ConvertToMakefilePath(
+  std::string const& path) const
+{
+  cmGlobalUnixMakefileGenerator3* gg =
+    static_cast<cmGlobalUnixMakefileGenerator3*>(this->GlobalGenerator);
+  return gg->ConvertToMakefilePath(path);
+}
+
 void cmLocalUnixMakefileGenerator3::WriteMakeRule(
   std::ostream& os, const char* comment, const std::string& target,
   const std::vector<std::string>& depends,
@@ -528,7 +506,7 @@
   }
 
   // Construct the left hand side of the rule.
-  std::string tgt = cmSystemTools::ConvertToOutputPath(
+  std::string tgt = this->ConvertToMakefilePath(
     this->MaybeConvertToRelativePath(this->GetBinaryDirectory(), target));
 
   const char* space = "";
@@ -542,30 +520,30 @@
   if (symbolic) {
     if (const char* sym =
           this->Makefile->GetDefinition("CMAKE_MAKE_SYMBOLIC_RULE")) {
-      os << cmMakeSafe(tgt) << space << ": " << sym << "\n";
+      os << tgt << space << ": " << sym << "\n";
     }
   }
 
   // Write the rule.
   if (depends.empty()) {
     // No dependencies.  The commands will always run.
-    os << cmMakeSafe(tgt) << space << ":\n";
+    os << tgt << space << ":\n";
   } else {
     // Split dependencies into multiple rule lines.  This allows for
     // very long dependency lists even on older make implementations.
     std::string binDir = this->GetBinaryDirectory();
     for (std::string const& depend : depends) {
-      replace = depend;
-      replace = cmSystemTools::ConvertToOutputPath(
-        this->MaybeConvertToRelativePath(binDir, replace));
-      os << cmMakeSafe(tgt) << space << ": " << cmMakeSafe(replace) << "\n";
+      os << tgt << space << ": "
+         << this->ConvertToMakefilePath(
+              this->MaybeConvertToRelativePath(binDir, depend))
+         << '\n';
     }
   }
 
   // Write the list of commands.
   os << cmWrap("\t", commands, "", "\n") << "\n";
   if (symbolic && !this->IsWatcomWMake()) {
-    os << ".PHONY : " << cmMakeSafe(tgt) << "\n";
+    os << ".PHONY : " << tgt << "\n";
   }
   os << "\n";
   // Add the output to the local help if requested.
@@ -623,8 +601,7 @@
     this->MaybeConvertWatcomShellCommand(cmSystemTools::GetCMakeCommand());
   if (cmakeShellCommand.empty()) {
     cmakeShellCommand = this->ConvertToOutputFormat(
-      cmSystemTools::CollapseFullPath(cmSystemTools::GetCMakeCommand()),
-      cmOutputConverter::SHELL);
+      cmSystemTools::GetCMakeCommand(), cmOutputConverter::SHELL);
   }
 
   /* clang-format off */
@@ -648,16 +625,14 @@
     << "# The top-level source directory on which CMake was run.\n"
     << "CMAKE_SOURCE_DIR = "
     << this->ConvertToOutputFormat(
-      cmSystemTools::CollapseFullPath(this->GetSourceDirectory()),
-                     cmOutputConverter::SHELL)
+      this->GetSourceDirectory(), cmOutputConverter::SHELL)
     << "\n"
     << "\n";
   makefileStream
     << "# The top-level build directory on which CMake was run.\n"
     << "CMAKE_BINARY_DIR = "
     << this->ConvertToOutputFormat(
-      cmSystemTools::CollapseFullPath(this->GetBinaryDirectory()),
-                     cmOutputConverter::SHELL)
+      this->GetBinaryDirectory(), cmOutputConverter::SHELL)
     << "\n"
     << "\n";
   /* clang-format on */
@@ -738,9 +713,10 @@
     // "VERBOSE=1" to be added as a make variable which will change the
     // name of this special target.  This gives a make-time choice to
     // the user.
-    this->WriteMakeRule(makefileStream,
-                        "Suppress display of executed commands.",
-                        "$(VERBOSE).SILENT", no_depends, no_commands, false);
+    // Write directly to the stream since WriteMakeRule escapes '$'.
+    makefileStream << "#Suppress display of executed commands.\n"
+                      "$(VERBOSE).SILENT:\n"
+                      "\n";
   }
 
   // Work-around for makes that drop rules that have no dependencies
@@ -974,11 +950,12 @@
       std::string launcher;
       // Short-circuit if there is no launcher.
       const char* val = this->GetRuleLauncher(target, "RULE_LAUNCH_CUSTOM");
-      if (val && *val) {
+      if (cmNonempty(val)) {
         // Expand rule variables referenced in the given launcher command.
         cmRulePlaceholderExpander::RuleVariables vars;
         vars.CMTargetName = target->GetName().c_str();
-        vars.CMTargetType = cmState::GetTargetTypeName(target->GetType());
+        vars.CMTargetType =
+          cmState::GetTargetTypeName(target->GetType()).c_str();
         std::string output;
         const std::vector<std::string>& outputs = ccg.GetOutputs();
         if (!outputs.empty()) {
@@ -1057,10 +1034,9 @@
     cleanfile += filename;
   }
   cleanfile += ".cmake";
-  std::string cleanfilePath = cmSystemTools::CollapseFullPath(cleanfile);
-  cmsys::ofstream fout(cleanfilePath.c_str());
+  cmsys::ofstream fout(cleanfile.c_str());
   if (!fout) {
-    cmSystemTools::Error("Could not create " + cleanfilePath);
+    cmSystemTools::Error("Could not create " + cleanfile);
   }
   if (!files.empty()) {
     fout << "file(REMOVE_RECURSE\n";
@@ -1102,10 +1078,10 @@
 {
   std::vector<std::string> cleanFiles;
   // Look for additional files registered for cleaning in this directory.
-  if (const char* prop_value =
+  if (cmProp prop_value =
         this->Makefile->GetProperty("ADDITIONAL_CLEAN_FILES")) {
     cmExpandList(cmGeneratorExpression::Evaluate(
-                   prop_value, this,
+                   *prop_value, this,
                    this->Makefile->GetSafeDefinition("CMAKE_BUILD_TYPE")),
                  cleanFiles);
   }
@@ -1120,10 +1096,9 @@
     cmStrCat(currentBinaryDir, "/CMakeFiles/cmake_directory_clean.cmake");
   // Write clean script
   {
-    std::string cleanfilePath = cmSystemTools::CollapseFullPath(cleanfile);
-    cmsys::ofstream fout(cleanfilePath.c_str());
+    cmsys::ofstream fout(cleanfile.c_str());
     if (!fout) {
-      cmSystemTools::Error("Could not create " + cleanfilePath);
+      cmSystemTools::Error("Could not create " + cleanfile);
       return;
     }
     fout << "file(REMOVE_RECURSE\n";
@@ -1194,9 +1169,8 @@
             color_name);
           if (progress) {
             cmd += "--progress-dir=";
-            cmd += this->ConvertToOutputFormat(
-              cmSystemTools::CollapseFullPath(progress->Dir),
-              cmOutputConverter::SHELL);
+            cmd += this->ConvertToOutputFormat(progress->Dir,
+                                               cmOutputConverter::SHELL);
             cmd += " ";
             cmd += "--progress-num=";
             cmd += progress->Arg;
@@ -1331,10 +1305,9 @@
     int result;
     if (!ftc->Compare(internalDependFile, tgtInfo, &result) || result < 0) {
       if (verbose) {
-        std::ostringstream msg;
-        msg << "Dependee \"" << tgtInfo << "\" is newer than depender \""
-            << internalDependFile << "\"." << std::endl;
-        cmSystemTools::Stdout(msg.str());
+        cmSystemTools::Stdout(cmStrCat("Dependee \"", tgtInfo,
+                                       "\" is newer than depender \"",
+                                       internalDependFile, "\".\n"));
       }
       needRescanDependInfo = true;
     }
@@ -1351,10 +1324,9 @@
     if (!ftc->Compare(internalDependFile, dirInfoFile, &result) ||
         result < 0) {
       if (verbose) {
-        std::ostringstream msg;
-        msg << "Dependee \"" << dirInfoFile << "\" is newer than depender \""
-            << internalDependFile << "\"." << std::endl;
-        cmSystemTools::Stdout(msg.str());
+        cmSystemTools::Stdout(cmStrCat("Dependee \"", dirInfoFile,
+                                       "\" is newer than depender \"",
+                                       internalDependFile, "\".\n"));
       }
       needRescanDirInfo = true;
     }
@@ -1520,11 +1492,9 @@
     if (cmSystemTools::FileExists(dependee) &&
         !cmSystemTools::FileExists(depender)) {
       if (verbose) {
-        std::ostringstream msg;
-        msg << "Deleting primary custom command output \"" << dependee
-            << "\" because another output \"" << depender
-            << "\" does not exist." << std::endl;
-        cmSystemTools::Stdout(msg.str());
+        cmSystemTools::Stdout(cmStrCat(
+          "Deleting primary custom command output \"", dependee,
+          "\" because another output \"", depender, "\" does not exist.\n"));
       }
       cmSystemTools::RemoveFile(dependee);
     }
@@ -1578,10 +1548,8 @@
       std::vector<std::string> commands;
       std::vector<std::string> depends;
 
-      const char* text = gt->GetProperty("EchoString");
-      if (!text) {
-        text = "Running external command ...";
-      }
+      cmProp p = gt->GetProperty("EchoString");
+      const char* text = p ? p->c_str() : "Running external command ...";
       depends.reserve(gt->GetUtilities().size());
       for (BT<std::pair<std::string, bool>> const& u : gt->GetUtilities()) {
         depends.push_back(u.Value.first);
@@ -1636,15 +1604,14 @@
   {
     std::ostringstream progCmd;
     progCmd << "$(CMAKE_COMMAND) -E cmake_progress_start ";
-    progCmd << this->ConvertToOutputFormat(
-      cmSystemTools::CollapseFullPath(progressDir), cmOutputConverter::SHELL);
+    progCmd << this->ConvertToOutputFormat(progressDir,
+                                           cmOutputConverter::SHELL);
 
     std::string progressFile = "/CMakeFiles/progress.marks";
     std::string progressFileNameFull = this->ConvertToFullPath(progressFile);
     progCmd << " "
-            << this->ConvertToOutputFormat(
-                 cmSystemTools::CollapseFullPath(progressFileNameFull),
-                 cmOutputConverter::SHELL);
+            << this->ConvertToOutputFormat(progressFileNameFull,
+                                           cmOutputConverter::SHELL);
     commands.push_back(progCmd.str());
   }
   std::string mf2Dir = "CMakeFiles/Makefile2";
@@ -1654,8 +1621,8 @@
   {
     std::ostringstream progCmd;
     progCmd << "$(CMAKE_COMMAND) -E cmake_progress_start "; // # 0
-    progCmd << this->ConvertToOutputFormat(
-      cmSystemTools::CollapseFullPath(progressDir), cmOutputConverter::SHELL);
+    progCmd << this->ConvertToOutputFormat(progressDir,
+                                           cmOutputConverter::SHELL);
     progCmd << " 0";
     commands.push_back(progCmd.str());
   }
@@ -1777,7 +1744,7 @@
       return false;
     }
     // If it's an absolute path, check if it starts with the source
-    // direcotory:
+    // directory:
     return (
       !(IsInDirectory(SourceDir, path) || IsInDirectory(BinaryDir, path)));
   }
@@ -1788,7 +1755,7 @@
                             const std::string& testDir)
   {
     // First check if the test directory "starts with" the base directory:
-    if (testDir.find(baseDir) != 0) {
+    if (!cmHasPrefix(testDir, baseDir)) {
       return false;
     }
     // If it does, then check that it's either the same string, or that the
@@ -1840,7 +1807,7 @@
     std::string cidVar =
       cmStrCat("CMAKE_", implicitLang.first, "_COMPILER_ID");
     const char* cid = this->Makefile->GetDefinition(cidVar);
-    if (cid && *cid) {
+    if (cmNonempty(cid)) {
       cmakefileStream << "set(CMAKE_" << implicitLang.first
                       << "_COMPILER_ID \"" << cid << "\")\n";
     }
@@ -1899,13 +1866,13 @@
   // Store include transform rule properties.  Write the directory
   // rules first because they may be overridden by later target rules.
   std::vector<std::string> transformRules;
-  if (const char* xform =
+  if (cmProp xform =
         this->Makefile->GetProperty("IMPLICIT_DEPENDS_INCLUDE_TRANSFORM")) {
-    cmExpandList(xform, transformRules);
+    cmExpandList(*xform, transformRules);
   }
-  if (const char* xform =
+  if (cmProp xform =
         target->GetProperty("IMPLICIT_DEPENDS_INCLUDE_TRANSFORM")) {
-    cmExpandList(xform, transformRules);
+    cmExpandList(*xform, transformRules);
   }
   if (!transformRules.empty()) {
     cmakefileStream << "set(CMAKE_INCLUDE_TRANSFORMS\n";
@@ -1972,7 +1939,7 @@
 void cmLocalUnixMakefileGenerator3::WriteDivider(std::ostream& os)
 {
   os << "#======================================"
-     << "=======================================\n";
+        "=======================================\n";
 }
 
 void cmLocalUnixMakefileGenerator3::WriteCMakeArgument(std::ostream& os,
@@ -1980,7 +1947,7 @@
 {
   // Write the given string to the stream with escaping to get it back
   // into CMake through the lexical scanner.
-  os << "\"";
+  os << '"';
   for (char c : s) {
     if (c == '\\') {
       os << "\\\\";
@@ -1990,7 +1957,7 @@
       os << c;
     }
   }
-  os << "\"";
+  os << '"';
 }
 
 std::string cmLocalUnixMakefileGenerator3::ConvertToQuotedOutputPath(
diff --git a/Source/cmLocalUnixMakefileGenerator3.h b/Source/cmLocalUnixMakefileGenerator3.h
index 68eeb29..2b07952 100644
--- a/Source/cmLocalUnixMakefileGenerator3.h
+++ b/Source/cmLocalUnixMakefileGenerator3.h
@@ -46,6 +46,12 @@
   // local generators StartOutputDirectory
   const std::string& GetHomeRelativeOutputPath();
 
+  /**
+   * Convert a file path to a Makefile target or dependency with
+   * escaping and quoting suitable for the generator's make tool.
+   */
+  std::string ConvertToMakefilePath(std::string const& path) const;
+
   // Write out a make rule
   void WriteMakeRule(std::ostream& os, const char* comment,
                      const std::string& target,
diff --git a/Source/cmLocalVisualStudio10Generator.cxx b/Source/cmLocalVisualStudio10Generator.cxx
index 02e2c6d..6c7d6c6 100644
--- a/Source/cmLocalVisualStudio10Generator.cxx
+++ b/Source/cmLocalVisualStudio10Generator.cxx
@@ -4,7 +4,7 @@
 
 #include <cmext/algorithm>
 
-#include "cm_expat.h"
+#include <cm3p/expat.h>
 
 #include "cmAlgorithms.h"
 #include "cmGeneratorTarget.h"
@@ -69,7 +69,7 @@
 void cmLocalVisualStudio10Generator::GenerateTargetsDepthFirst(
   cmGeneratorTarget* target, std::vector<cmGeneratorTarget*>& remaining)
 {
-  if (target->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
+  if (!target->IsInBuildSystem()) {
     return;
   }
   // Find this target in the list of remaining targets.
diff --git a/Source/cmLocalVisualStudio7Generator.cxx b/Source/cmLocalVisualStudio7Generator.cxx
index 9aa3991..50ffe8d 100644
--- a/Source/cmLocalVisualStudio7Generator.cxx
+++ b/Source/cmLocalVisualStudio7Generator.cxx
@@ -2,12 +2,14 @@
    file Copyright.txt or https://cmake.org/licensing for details.  */
 #include "cmLocalVisualStudio7Generator.h"
 
+#include <cm/memory>
+#include <cmext/algorithm>
+
 #include <windows.h>
 
+#include <cm3p/expat.h>
 #include <ctype.h> // for isspace
 
-#include "cm_expat.h"
-
 #include "cmComputeLinkInformation.h"
 #include "cmCustomCommand.h"
 #include "cmCustomCommandGenerator.h"
@@ -18,6 +20,7 @@
 #include "cmMakefile.h"
 #include "cmMessageType.h"
 #include "cmSourceFile.h"
+#include "cmStringAlgorithms.h"
 #include "cmSystemTools.h"
 #include "cmXMLParser.h"
 #include "cmake.h"
@@ -52,26 +55,23 @@
 cmLocalVisualStudio7Generator::cmLocalVisualStudio7Generator(
   cmGlobalGenerator* gg, cmMakefile* mf)
   : cmLocalVisualStudioGenerator(gg, mf)
+  , Internal(cm::make_unique<cmLocalVisualStudio7GeneratorInternals>(this))
 {
-  this->Internal = new cmLocalVisualStudio7GeneratorInternals(this);
 }
 
-cmLocalVisualStudio7Generator::~cmLocalVisualStudio7Generator()
-{
-  delete this->Internal;
-}
+cmLocalVisualStudio7Generator::~cmLocalVisualStudio7Generator() = default;
 
 void cmLocalVisualStudio7Generator::AddHelperCommands()
 {
   // Now create GUIDs for targets
   const auto& tgts = this->GetGeneratorTargets();
   for (const auto& l : tgts) {
-    if (l->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
+    if (!l->IsInBuildSystem()) {
       continue;
     }
-    const char* path = l->GetProperty("EXTERNAL_MSPROJECT");
+    cmProp path = l->GetProperty("EXTERNAL_MSPROJECT");
     if (path) {
-      this->ReadAndStoreExternalGUID(l->GetName(), path);
+      this->ReadAndStoreExternalGUID(l->GetName(), path->c_str());
     }
   }
 
@@ -129,7 +129,7 @@
 
   // Create the project file for each target.
   for (const auto& l : tgts) {
-    if (l->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
+    if (!l->IsInBuildSystem()) {
       continue;
     }
     // INCLUDE_EXTERNAL_MSPROJECT command only affects the workspace
@@ -226,7 +226,6 @@
 
   std::string makefileIn =
     cmStrCat(this->GetCurrentSourceDirectory(), "/CMakeLists.txt");
-  makefileIn = cmSystemTools::CollapseFullPath(makefileIn);
   if (cmSourceFile* file = this->Makefile->GetSource(makefileIn)) {
     if (file->GetCustomCommand()) {
       return file;
@@ -252,15 +251,15 @@
   std::string argB = cmStrCat("-B", this->GetBinaryDirectory());
   std::string stampName =
     cmStrCat(this->GetCurrentBinaryDirectory(), "/CMakeFiles/generate.stamp");
+  bool stdPipesUTF8 = true;
   cmCustomCommandLines commandLines =
     cmMakeSingleCommandLine({ cmSystemTools::GetCMakeCommand(), argS, argB,
                               "--check-stamp-file", stampName });
   std::string comment = cmStrCat("Building Custom Rule ", makefileIn);
   const char* no_working_directory = nullptr;
-  std::string fullpathStampName = cmSystemTools::CollapseFullPath(stampName);
-  this->AddCustomCommandToOutput(fullpathStampName, listFiles, makefileIn,
-                                 commandLines, comment.c_str(),
-                                 no_working_directory, true, false);
+  this->AddCustomCommandToOutput(
+    stampName, listFiles, makefileIn, commandLines, comment.c_str(),
+    no_working_directory, true, false, false, false, "", "", stdPipesUTF8);
   if (cmSourceFile* file = this->Makefile->GetSource(makefileIn)) {
     // Finalize the source file path now since we're adding this after
     // the generator validated all project-named sources.
@@ -284,6 +283,7 @@
 }
 cmVS7FlagTable cmLocalVisualStudio7GeneratorFortranFlagTable[] = {
   { "Preprocess", "fpp", "Run Preprocessor on files", "preprocessYes", 0 },
+  { "Preprocess", "nofpp", "Run Preprocessor on files", "preprocessNo", 0 },
   { "SuppressStartupBanner", "nologo", "SuppressStartupBanner", "true", 0 },
   { "SourceFileFormat", "fixed", "Use Fixed Format", "fileFormatFixed", 0 },
   { "SourceFileFormat", "free", "Use Free Format", "fileFormatFree", 0 },
@@ -629,9 +629,10 @@
       break;
     case cmStateEnums::UTILITY:
     case cmStateEnums::GLOBAL_TARGET:
+    case cmStateEnums::INTERFACE_LIBRARY:
       configType = "10";
       CM_FALLTHROUGH;
-    default:
+    case cmStateEnums::UNKNOWN_LIBRARY:
       targetBuilds = false;
       break;
   }
@@ -672,7 +673,7 @@
 
   if (this->FortranProject) {
     switch (cmOutputConverter::GetFortranFormat(
-      target->GetProperty("Fortran_FORMAT"))) {
+      target->GetSafeProperty("Fortran_FORMAT"))) {
       case cmOutputConverter::FortranFormatFixed:
         flags += " -fixed";
         break;
@@ -682,6 +683,18 @@
       default:
         break;
     }
+
+    switch (cmOutputConverter::GetFortranPreprocess(
+      target->GetSafeProperty("Fortran_PREPROCESS"))) {
+      case cmOutputConverter::FortranPreprocess::Needed:
+        flags += " -fpp";
+        break;
+      case cmOutputConverter::FortranPreprocess::NotNeeded:
+        flags += " -nofpp";
+        break;
+      default:
+        break;
+    }
   }
 
   // Get preprocessor definitions for this directory.
@@ -778,12 +791,11 @@
   fout << "\t\t\t<Tool\n"
        << "\t\t\t\tName=\"" << tool << "\"\n";
   if (this->FortranProject) {
-    const char* target_mod_dir =
-      target->GetProperty("Fortran_MODULE_DIRECTORY");
+    cmProp target_mod_dir = target->GetProperty("Fortran_MODULE_DIRECTORY");
     std::string modDir;
     if (target_mod_dir) {
       modDir = this->MaybeConvertToRelativePath(
-        this->GetCurrentBinaryDirectory(), target_mod_dir);
+        this->GetCurrentBinaryDirectory(), *target_mod_dir);
     } else {
       modDir = ".";
     }
@@ -937,17 +949,17 @@
       " " + GetBuildTypeLinkerFlags("CMAKE_MODULE_LINKER_FLAGS", configName);
   }
 
-  const char* targetLinkFlags = target->GetProperty("LINK_FLAGS");
+  cmProp targetLinkFlags = target->GetProperty("LINK_FLAGS");
   if (targetLinkFlags) {
     extraLinkOptions += " ";
-    extraLinkOptions += targetLinkFlags;
+    extraLinkOptions += *targetLinkFlags;
   }
   std::string configTypeUpper = cmSystemTools::UpperCase(configName);
   std::string linkFlagsConfig = cmStrCat("LINK_FLAGS_", configTypeUpper);
   targetLinkFlags = target->GetProperty(linkFlagsConfig);
   if (targetLinkFlags) {
     extraLinkOptions += " ";
-    extraLinkOptions += targetLinkFlags;
+    extraLinkOptions += *targetLinkFlags;
   }
 
   std::vector<std::string> opts;
@@ -1006,9 +1018,8 @@
         }
       }
       std::string libflags;
-      this->GetStaticLibraryFlags(libflags, configTypeUpper,
-                                  target->GetLinkerLanguage(configName),
-                                  target);
+      this->GetStaticLibraryFlags(
+        libflags, configName, target->GetLinkerLanguage(configName), target);
       if (!libflags.empty()) {
         fout << "\t\t\t\tAdditionalOptions=\"" << libflags << "\"\n";
       }
@@ -1206,8 +1217,8 @@
   std::ostream& fout, std::string const& config, cmGeneratorTarget* target)
 {
   if (this->WindowsCEProject) {
-    const char* dir = target->GetProperty("DEPLOYMENT_REMOTE_DIRECTORY");
-    const char* additionalFiles =
+    cmProp dir = target->GetProperty("DEPLOYMENT_REMOTE_DIRECTORY");
+    cmProp additionalFiles =
       target->GetProperty("DEPLOYMENT_ADDITIONAL_FILES");
 
     if (dir == nullptr && additionalFiles == nullptr) {
@@ -1217,15 +1228,15 @@
     fout << "\t\t\t<DeploymentTool\n"
             "\t\t\t\tForceDirty=\"-1\"\n"
             "\t\t\t\tRemoteDirectory=\""
-         << GetEscapedPropertyIfValueNotNULL(dir)
+         << GetEscapedPropertyIfValueNotNULL(dir->c_str())
          << "\"\n"
             "\t\t\t\tRegisterOutput=\"0\"\n"
             "\t\t\t\tAdditionalFiles=\""
-         << GetEscapedPropertyIfValueNotNULL(additionalFiles) << "\"/>\n";
+         << GetEscapedPropertyIfValueNotNULL(additionalFiles->c_str())
+         << "\"/>\n";
 
     if (dir != nullptr) {
-      std::string const exe =
-        dir + std::string("\\") + target->GetFullName(config);
+      std::string const exe = *dir + "\\" + target->GetFullName(config);
 
       fout << "\t\t\t<DebuggerTool\n"
               "\t\t\t\tRemoteExecutable=\""
@@ -1321,8 +1332,8 @@
                                                     const std::string& libName,
                                                     cmGeneratorTarget* target)
 {
-  std::vector<std::string> configs;
-  this->Makefile->GetConfigurations(configs);
+  std::vector<std::string> configs =
+    this->Makefile->GetGeneratorConfigs(cmMakefile::ExcludeEmptyConfig);
 
   // We may be modifying the source groups temporarily, so make a copy.
   std::vector<cmSourceGroup> sourceGroups = this->Makefile->GetSourceGroups();
@@ -1448,14 +1459,15 @@
       needfc = true;
     }
     const std::string COMPILE_FLAGS("COMPILE_FLAGS");
-    if (const char* cflags = sf.GetProperty(COMPILE_FLAGS)) {
-      fc.CompileFlags = genexInterpreter.Evaluate(cflags, COMPILE_FLAGS);
+    if (cmProp cflags = sf.GetProperty(COMPILE_FLAGS)) {
+      fc.CompileFlags = genexInterpreter.Evaluate(*cflags, COMPILE_FLAGS);
       needfc = true;
     }
     const std::string COMPILE_OPTIONS("COMPILE_OPTIONS");
-    if (const char* coptions = sf.GetProperty(COMPILE_OPTIONS)) {
+    if (cmProp coptions = sf.GetProperty(COMPILE_OPTIONS)) {
       lg->AppendCompileOptions(
-        fc.CompileFlags, genexInterpreter.Evaluate(coptions, COMPILE_OPTIONS));
+        fc.CompileFlags,
+        genexInterpreter.Evaluate(*coptions, COMPILE_OPTIONS));
       needfc = true;
     }
     // Add precompile headers compile options.
@@ -1475,8 +1487,22 @@
     }
 
     if (lg->FortranProject) {
+      switch (cmOutputConverter::GetFortranPreprocess(
+        sf.GetSafeProperty("Fortran_PREPROCESS"))) {
+        case cmOutputConverter::FortranPreprocess::Needed:
+          fc.CompileFlags = cmStrCat("-fpp ", fc.CompileFlags);
+          needfc = true;
+          break;
+        case cmOutputConverter::FortranPreprocess::NotNeeded:
+          fc.CompileFlags = cmStrCat("-nofpp ", fc.CompileFlags);
+          needfc = true;
+          break;
+        default:
+          break;
+      }
+
       switch (cmOutputConverter::GetFortranFormat(
-        sf.GetProperty("Fortran_FORMAT"))) {
+        sf.GetSafeProperty("Fortran_FORMAT"))) {
         case cmOutputConverter::FortranFormatFixed:
           fc.CompileFlags = "-fixed " + fc.CompileFlags;
           needfc = true;
@@ -1490,31 +1516,30 @@
       }
     }
     const std::string COMPILE_DEFINITIONS("COMPILE_DEFINITIONS");
-    if (const char* cdefs = sf.GetProperty(COMPILE_DEFINITIONS)) {
-      fc.CompileDefs = genexInterpreter.Evaluate(cdefs, COMPILE_DEFINITIONS);
+    if (cmProp cdefs = sf.GetProperty(COMPILE_DEFINITIONS)) {
+      fc.CompileDefs = genexInterpreter.Evaluate(*cdefs, COMPILE_DEFINITIONS);
       needfc = true;
     }
     std::string defPropName = cmStrCat("COMPILE_DEFINITIONS_", configUpper);
-    if (const char* ccdefs = sf.GetProperty(defPropName)) {
+    if (cmProp ccdefs = sf.GetProperty(defPropName)) {
       fc.CompileDefsConfig =
-        genexInterpreter.Evaluate(ccdefs, COMPILE_DEFINITIONS);
+        genexInterpreter.Evaluate(*ccdefs, COMPILE_DEFINITIONS);
       needfc = true;
     }
 
     const std::string INCLUDE_DIRECTORIES("INCLUDE_DIRECTORIES");
-    if (const char* cincs = sf.GetProperty(INCLUDE_DIRECTORIES)) {
-      fc.IncludeDirs = genexInterpreter.Evaluate(cincs, INCLUDE_DIRECTORIES);
+    if (cmProp cincs = sf.GetProperty(INCLUDE_DIRECTORIES)) {
+      fc.IncludeDirs = genexInterpreter.Evaluate(*cincs, INCLUDE_DIRECTORIES);
       needfc = true;
     }
 
     // Check for extra object-file dependencies.
-    if (const char* deps = sf.GetProperty("OBJECT_DEPENDS")) {
-      std::vector<std::string> depends = cmExpandedList(deps);
+    if (cmProp deps = sf.GetProperty("OBJECT_DEPENDS")) {
+      std::vector<std::string> depends = cmExpandedList(*deps);
       const char* sep = "";
-      for (std::vector<std::string>::iterator j = depends.begin();
-           j != depends.end(); ++j) {
+      for (const std::string& d : depends) {
         fc.AdditionalDeps += sep;
-        fc.AdditionalDeps += lg->ConvertToXMLOutputPath(*j);
+        fc.AdditionalDeps += lg->ConvertToXMLOutputPath(d);
         sep = ";";
         needfc = true;
       }
@@ -1524,7 +1549,7 @@
     // If HEADER_FILE_ONLY is set, we must suppress this generation in
     // the project file
     fc.ExcludedFromBuild = sf.GetPropertyAsBool("HEADER_FILE_ONLY") ||
-      !cmContains(acs.Configs, ci) ||
+      !cm::contains(acs.Configs, ci) ||
       (gt->GetPropertyAsBool("UNITY_BUILD") &&
        sf.GetProperty("UNITY_SOURCE_FILE") &&
        !sf.GetPropertyAsBool("SKIP_UNITY_BUILD_INCLUSION"));
@@ -1556,8 +1581,9 @@
 std::string cmLocalVisualStudio7Generator::ComputeLongestObjectDirectory(
   cmGeneratorTarget const* target) const
 {
-  std::vector<std::string> configs;
-  target->Target->GetMakefile()->GetConfigurations(configs);
+  std::vector<std::string> configs =
+    target->Target->GetMakefile()->GetGeneratorConfigs(
+      cmMakefile::ExcludeEmptyConfig);
 
   // Compute the maximum length configuration name.
   std::string config_max;
@@ -1613,7 +1639,8 @@
     std::string source = sf->GetFullPath();
 
     if (source != libName || target->GetType() == cmStateEnums::UTILITY ||
-        target->GetType() == cmStateEnums::GLOBAL_TARGET) {
+        target->GetType() == cmStateEnums::GLOBAL_TARGET ||
+        target->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
       // Look up the source kind and configs.
       std::map<cmSourceFile const*, size_t>::const_iterator map_it =
         sources.Index.find(sf);
@@ -1877,20 +1904,20 @@
 {
   // if we have all the required Source code control tags
   // then add that to the project
-  const char* vsProjectname = target->GetProperty("VS_SCC_PROJECTNAME");
-  const char* vsLocalpath = target->GetProperty("VS_SCC_LOCALPATH");
-  const char* vsProvider = target->GetProperty("VS_SCC_PROVIDER");
+  cmProp vsProjectname = target->GetProperty("VS_SCC_PROJECTNAME");
+  cmProp vsLocalpath = target->GetProperty("VS_SCC_LOCALPATH");
+  cmProp vsProvider = target->GetProperty("VS_SCC_PROVIDER");
 
   if (vsProvider && vsLocalpath && vsProjectname) {
     /* clang-format off */
-    fout << "\tSccProjectName=\"" << vsProjectname << "\"\n"
-         << "\tSccLocalPath=\"" << vsLocalpath << "\"\n"
-         << "\tSccProvider=\"" << vsProvider << "\"\n";
+    fout << "\tSccProjectName=\"" << *vsProjectname << "\"\n"
+         << "\tSccLocalPath=\"" << *vsLocalpath << "\"\n"
+         << "\tSccProvider=\"" << *vsProvider << "\"\n";
     /* clang-format on */
 
-    const char* vsAuxPath = target->GetProperty("VS_SCC_AUXPATH");
+    cmProp vsAuxPath = target->GetProperty("VS_SCC_AUXPATH");
     if (vsAuxPath) {
-      fout << "\tSccAuxPath=\"" << vsAuxPath << "\"\n";
+      fout << "\tSccAuxPath=\"" << *vsAuxPath << "\"\n";
     }
   }
 }
@@ -1908,12 +1935,11 @@
        << "\tProjectCreator=\"Intel Fortran\"\n"
        << "\tVersion=\"" << gg->GetIntelProjectVersion() << "\"\n";
   /* clang-format on */
-  const char* keyword = target->GetProperty("VS_KEYWORD");
-  if (!keyword) {
-    keyword = "Console Application";
-  }
+  cmProp p = target->GetProperty("VS_KEYWORD");
+  const char* keyword = p ? p->c_str() : "Console Application";
   const char* projectType = 0;
   switch (target->GetType()) {
+    case cmStateEnums::OBJECT_LIBRARY:
     case cmStateEnums::STATIC_LIBRARY:
       projectType = "typeStaticLibrary";
       if (keyword) {
@@ -1935,7 +1961,8 @@
       break;
     case cmStateEnums::UTILITY:
     case cmStateEnums::GLOBAL_TARGET:
-    default:
+    case cmStateEnums::INTERFACE_LIBRARY:
+    case cmStateEnums::UNKNOWN_LIBRARY:
       break;
   }
   if (projectType) {
@@ -1970,20 +1997,16 @@
        << "\tProjectType=\"Visual C++\"\n";
   /* clang-format on */
   fout << "\tVersion=\"" << (gg->GetVersion() / 10) << ".00\"\n";
-  const char* projLabel = target->GetProperty("PROJECT_LABEL");
-  if (!projLabel) {
-    projLabel = libName.c_str();
-  }
-  const char* keyword = target->GetProperty("VS_KEYWORD");
-  if (!keyword) {
-    keyword = "Win32Proj";
-  }
+  cmProp p = target->GetProperty("PROJECT_LABEL");
+  const std::string projLabel = p ? *p : libName;
+  p = target->GetProperty("VS_KEYWORD");
+  const std::string keyword = p ? *p : "Win32Proj";
   fout << "\tName=\"" << projLabel << "\"\n";
   fout << "\tProjectGUID=\"{" << gg->GetGUID(libName) << "}\"\n";
   this->WriteProjectSCC(fout, target);
-  if (const char* targetFrameworkVersion =
+  if (cmProp targetFrameworkVersion =
         target->GetProperty("VS_DOTNET_TARGET_FRAMEWORK_VERSION")) {
-    fout << "\tTargetFrameworkVersion=\"" << targetFrameworkVersion << "\"\n";
+    fout << "\tTargetFrameworkVersion=\"" << *targetFrameworkVersion << "\"\n";
   }
   /* clang-format off */
   fout << "\tKeyword=\"" << keyword << "\">\n"
@@ -2010,7 +2033,7 @@
   fout << "\t<Globals>\n";
 
   for (std::string const& key : target->GetPropertyKeys()) {
-    if (key.find("VS_GLOBAL_") == 0) {
+    if (cmHasLiteralPrefix(key, "VS_GLOBAL_")) {
       std::string name = key.substr(10);
       if (!name.empty()) {
         /* clang-format off */
diff --git a/Source/cmLocalVisualStudio7Generator.h b/Source/cmLocalVisualStudio7Generator.h
index 745766c..8b9b8ad 100644
--- a/Source/cmLocalVisualStudio7Generator.h
+++ b/Source/cmLocalVisualStudio7Generator.h
@@ -6,6 +6,7 @@
 #include "cmConfigure.h" // IWYU pragma: keep
 
 #include <iosfwd>
+#include <memory>
 #include <string>
 #include <vector>
 
@@ -48,6 +49,10 @@
 
   virtual ~cmLocalVisualStudio7Generator();
 
+  cmLocalVisualStudio7Generator(const cmLocalVisualStudio7Generator&) = delete;
+  const cmLocalVisualStudio7Generator& operator=(
+    const cmLocalVisualStudio7Generator&) = delete;
+
   void AddHelperCommands() override;
 
   /**
@@ -144,7 +149,7 @@
 
   bool FortranProject;
   bool WindowsCEProject;
-  cmLocalVisualStudio7GeneratorInternals* Internal;
+  std::unique_ptr<cmLocalVisualStudio7GeneratorInternals> Internal;
 };
 
 #endif
diff --git a/Source/cmLocalVisualStudioGenerator.cxx b/Source/cmLocalVisualStudioGenerator.cxx
index 8d50898..ebd4f96 100644
--- a/Source/cmLocalVisualStudioGenerator.cxx
+++ b/Source/cmLocalVisualStudioGenerator.cxx
@@ -102,10 +102,12 @@
   std::vector<std::string> no_output;
   std::vector<std::string> no_byproducts;
   std::vector<std::string> no_depends;
+  bool stdPipesUTF8 = true;
   cmCustomCommandLines commands = cmMakeSingleCommandLine(
     { cmSystemTools::GetCMakeCommand(), "-E", "make_directory", impDir });
   pcc.reset(new cmCustomCommand(no_output, no_byproducts, no_depends, commands,
-                                cmListFileBacktrace(), nullptr, nullptr));
+                                cmListFileBacktrace(), nullptr, nullptr,
+                                stdPipesUTF8));
   pcc->SetEscapeOldStyle(false);
   pcc->SetEscapeAllowMakeVars(true);
   return pcc;
@@ -154,8 +156,7 @@
     script += newline;
     newline = newline_text;
     script += "cd ";
-    script += this->ConvertToOutputFormat(
-      cmSystemTools::CollapseFullPath(workingDirectory), SHELL);
+    script += this->ConvertToOutputFormat(workingDirectory, SHELL);
     script += check_error;
 
     // Change the working drive.
diff --git a/Source/cmMachO.cxx b/Source/cmMachO.cxx
index 6cbed36..53112e0 100644
--- a/Source/cmMachO.cxx
+++ b/Source/cmMachO.cxx
@@ -79,14 +79,14 @@
   // A load_command and its associated data
   struct RawLoadCommand
   {
-    uint32_t type(const cmMachOHeaderAndLoadCommands* m) const
+    uint32_t type(const cmMachOHeaderAndLoadCommands& m) const
     {
       if (this->LoadCommand.size() < sizeof(load_command)) {
         return 0;
       }
       const load_command* cmd =
         reinterpret_cast<const load_command*>(&this->LoadCommand[0]);
-      return m->swap(cmd->cmd);
+      return m.swap(cmd->cmd);
     }
     std::vector<char> LoadCommand;
   };
@@ -186,8 +186,11 @@
 {
 public:
   cmMachOInternal(const char* fname);
+  cmMachOInternal(const cmMachOInternal&) = delete;
   ~cmMachOInternal();
 
+  cmMachOInternal& operator=(const cmMachOInternal&) = delete;
+
   // read a Mach-O file
   bool read_mach_o(uint32_t file_offset);
 
@@ -202,7 +205,7 @@
   std::string ErrorMessage;
 
   // the list of Mach-O's
-  std::vector<cmMachOHeaderAndLoadCommands*> MachOList;
+  std::vector<std::unique_ptr<cmMachOHeaderAndLoadCommands>> MachOList;
 };
 
 cmMachOInternal::cmMachOInternal(const char* fname)
@@ -260,12 +263,7 @@
   }
 }
 
-cmMachOInternal::~cmMachOInternal()
-{
-  for (auto& i : this->MachOList) {
-    delete i;
-  }
-}
+cmMachOInternal::~cmMachOInternal() = default;
 
 bool cmMachOInternal::read_mach_o(uint32_t file_offset)
 {
@@ -280,25 +278,25 @@
     return false;
   }
 
-  cmMachOHeaderAndLoadCommands* f = nullptr;
+  std::unique_ptr<cmMachOHeaderAndLoadCommands> f;
   if (magic == MH_CIGAM || magic == MH_MAGIC) {
     bool swap = false;
     if (magic == MH_CIGAM) {
       swap = true;
     }
-    f = new cmMachOHeaderAndLoadCommandsImpl<mach_header>(swap);
+    f = cm::make_unique<cmMachOHeaderAndLoadCommandsImpl<mach_header>>(swap);
   } else if (magic == MH_CIGAM_64 || magic == MH_MAGIC_64) {
     bool swap = false;
     if (magic == MH_CIGAM_64) {
       swap = true;
     }
-    f = new cmMachOHeaderAndLoadCommandsImpl<mach_header_64>(swap);
+    f =
+      cm::make_unique<cmMachOHeaderAndLoadCommandsImpl<mach_header_64>>(swap);
   }
 
   if (f && f->read_mach_o(this->Fin)) {
-    this->MachOList.push_back(f);
+    this->MachOList.push_back(std::move(f));
   } else {
-    delete f;
     this->ErrorMessage = "Failed to read Mach-O header.";
     return false;
   }
@@ -333,11 +331,12 @@
   }
 
   // grab the first Mach-O and get the install name from that one
-  cmMachOHeaderAndLoadCommands* macho = this->Internal->MachOList[0];
+  std::unique_ptr<cmMachOHeaderAndLoadCommands>& macho =
+    this->Internal->MachOList[0];
   for (size_t i = 0; i < macho->load_commands().size(); i++) {
     const cmMachOHeaderAndLoadCommands::RawLoadCommand& cmd =
       macho->load_commands()[i];
-    uint32_t lc_cmd = cmd.type(macho);
+    uint32_t lc_cmd = cmd.type(*macho);
     if (lc_cmd == LC_ID_DYLIB || lc_cmd == LC_LOAD_WEAK_DYLIB ||
         lc_cmd == LC_LOAD_DYLIB) {
       if (sizeof(dylib_command) < cmd.LoadCommand.size()) {
diff --git a/Source/cmMacroCommand.cxx b/Source/cmMacroCommand.cxx
index 0b0d9ac..c88b343 100644
--- a/Source/cmMacroCommand.cxx
+++ b/Source/cmMacroCommand.cxx
@@ -8,8 +8,7 @@
 #include <cm/memory>
 #include <cm/string_view>
 #include <cmext/algorithm>
-
-#include "cm_static_string_view.hxx"
+#include <cmext/string_view>
 
 #include "cmExecutionStatus.h"
 #include "cmFunctionBlocker.h"
diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx
index 18689fa..5e1f070 100644
--- a/Source/cmMakefile.cxx
+++ b/Source/cmMakefile.cxx
@@ -18,21 +18,23 @@
 #include <cm/optional>
 #include <cm/vector>
 #include <cmext/algorithm>
+#include <cmext/string_view>
+
+#include <cm3p/json/value.h>
+#include <cm3p/json/writer.h>
 
 #include "cmsys/FStream.hxx"
 #include "cmsys/RegularExpression.hxx"
 
-#include "cm_jsoncpp_value.h"
-#include "cm_jsoncpp_writer.h"
 #include "cm_sys_stat.h"
 
-#include "cmAlgorithms.h"
 #include "cmCommandArgumentParserHelper.h"
 #include "cmCustomCommand.h"
 #include "cmCustomCommandLines.h"
 #include "cmExecutionStatus.h"
 #include "cmExpandedCommandArgument.h" // IWYU pragma: keep
 #include "cmExportBuildFileGenerator.h"
+#include "cmFSPermissions.h"
 #include "cmFileLockPool.h"
 #include "cmFunctionBlocker.h"
 #include "cmGeneratedFileStream.h"
@@ -61,11 +63,14 @@
 #include "cmake.h"
 
 #ifndef CMAKE_BOOTSTRAP
+#  include "cmMakefileProfilingData.h"
 #  include "cmVariableWatch.h"
 #endif
 
 class cmMessenger;
 
+using namespace cmFSPermissions;
+
 cmDirectoryId::cmDirectoryId(std::string s)
   : String(std::move(s))
 {
@@ -80,7 +85,6 @@
 {
   this->IsSourceFileTryCompile = false;
 
-  this->WarnUnused = this->GetCMakeInstance()->GetWarnUnused();
   this->CheckSystemVars = this->GetCMakeInstance()->GetCheckSystemVars();
 
   this->SuppressSideEffects = false;
@@ -192,7 +196,7 @@
   std::string env;
   cmSystemTools::GetEnv(varName, env);
 
-  bool const haveVar = var && *var;
+  bool const haveVar = cmNonempty(var);
   bool const haveEnv = !env.empty();
   if ((haveVar || haveEnv) && this->WarnedCMP0074.insert(varName).second) {
     std::ostringstream w;
@@ -373,19 +377,30 @@
 class cmMakefileCall
 {
 public:
-  cmMakefileCall(cmMakefile* mf, cmCommandContext const& cc,
+  cmMakefileCall(cmMakefile* mf, cmListFileFunction const& lff,
                  cmExecutionStatus& status)
     : Makefile(mf)
   {
     cmListFileContext const& lfc = cmListFileContext::FromCommandContext(
-      cc, this->Makefile->StateSnapshot.GetExecutionListFile());
+      lff, this->Makefile->StateSnapshot.GetExecutionListFile());
     this->Makefile->Backtrace = this->Makefile->Backtrace.Push(lfc);
     ++this->Makefile->RecursionDepth;
     this->Makefile->ExecutionStatusStack.push_back(&status);
+#if !defined(CMAKE_BOOTSTRAP)
+    if (this->Makefile->GetCMakeInstance()->IsProfilingEnabled()) {
+      this->Makefile->GetCMakeInstance()->GetProfilingOutput().StartEntry(lff,
+                                                                          lfc);
+    }
+#endif
   }
 
   ~cmMakefileCall()
   {
+#if !defined(CMAKE_BOOTSTRAP)
+    if (this->Makefile->GetCMakeInstance()->IsProfilingEnabled()) {
+      this->Makefile->GetCMakeInstance()->GetProfilingOutput().StopEntry();
+    }
+#endif
     this->Makefile->ExecutionStatusStack.pop_back();
     --this->Makefile->RecursionDepth;
     this->Makefile->Backtrace = this->Makefile->Backtrace.Pop();
@@ -685,6 +700,27 @@
   return true;
 }
 
+bool cmMakefile::ReadListFileAsString(const std::string& content,
+                                      const std::string& virtualFileName)
+{
+  std::string filenametoread = cmSystemTools::CollapseFullPath(
+    virtualFileName, this->GetCurrentSourceDirectory());
+
+  ListFileScope scope(this, filenametoread);
+
+  cmListFile listFile;
+  if (!listFile.ParseString(content.c_str(), virtualFileName.c_str(),
+                            this->GetMessenger(), this->Backtrace)) {
+    return false;
+  }
+
+  this->ReadListFile(listFile, filenametoread);
+  if (cmSystemTools::GetFatalErrorOccured()) {
+    scope.Quiet();
+  }
+  return true;
+}
+
 void cmMakefile::ReadListFile(cmListFile const& listFile,
                               std::string const& filenametoread)
 {
@@ -716,7 +752,6 @@
       break;
     }
   }
-  this->CheckForUnusedVariables();
 
   this->AddDefinition("CMAKE_PARENT_LIST_FILE", currentParentFile);
   this->AddDefinition("CMAKE_CURRENT_LIST_FILE", currentFile);
@@ -988,7 +1023,7 @@
   const cmCustomCommandLines& commandLines, cmCustomCommandType type,
   const char* comment, const char* workingDir, bool escapeOldStyle,
   bool uses_terminal, const std::string& depfile, const std::string& job_pool,
-  bool command_expand_lists)
+  bool command_expand_lists, bool stdPipesUTF8)
 {
   cmTarget* t = this->GetCustomCommandTarget(
     target, cmObjectLibraryCommands::Reject, this->Backtrace);
@@ -1006,14 +1041,15 @@
   cm::optional<std::string> workingStr = MakeOptionalString(workingDir);
 
   // Dispatch command creation to allow generator expressions in outputs.
-  this->AddGeneratorAction([=](cmLocalGenerator& lg,
-                               const cmListFileBacktrace& lfbt) {
-    BacktraceGuard guard(this->Backtrace, lfbt);
-    detail::AddCustomCommandToTarget(
-      lg, lfbt, cmCommandOrigin::Project, t, byproducts, depends, commandLines,
-      type, GetCStrOrNull(commentStr), GetCStrOrNull(workingStr),
-      escapeOldStyle, uses_terminal, depfile, job_pool, command_expand_lists);
-  });
+  this->AddGeneratorAction(
+    [=](cmLocalGenerator& lg, const cmListFileBacktrace& lfbt) {
+      BacktraceGuard guard(this->Backtrace, lfbt);
+      detail::AddCustomCommandToTarget(
+        lg, lfbt, cmCommandOrigin::Project, t, byproducts, depends,
+        commandLines, type, GetCStrOrNull(commentStr),
+        GetCStrOrNull(workingStr), escapeOldStyle, uses_terminal, depfile,
+        job_pool, command_expand_lists, stdPipesUTF8);
+    });
 
   return t;
 }
@@ -1024,14 +1060,14 @@
   const char* comment, const char* workingDir,
   const CommandSourceCallback& callback, bool replace, bool escapeOldStyle,
   bool uses_terminal, bool command_expand_lists, const std::string& depfile,
-  const std::string& job_pool)
+  const std::string& job_pool, bool stdPipesUTF8)
 {
   std::vector<std::string> no_byproducts;
   cmImplicitDependsList no_implicit_depends;
   this->AddCustomCommandToOutput(
     { output }, no_byproducts, depends, main_dependency, no_implicit_depends,
     commandLines, comment, workingDir, callback, replace, escapeOldStyle,
-    uses_terminal, command_expand_lists, depfile, job_pool);
+    uses_terminal, command_expand_lists, depfile, job_pool, stdPipesUTF8);
 }
 
 void cmMakefile::AddCustomCommandToOutput(
@@ -1042,7 +1078,7 @@
   const cmCustomCommandLines& commandLines, const char* comment,
   const char* workingDir, const CommandSourceCallback& callback, bool replace,
   bool escapeOldStyle, bool uses_terminal, bool command_expand_lists,
-  const std::string& depfile, const std::string& job_pool)
+  const std::string& depfile, const std::string& job_pool, bool stdPipesUTF8)
 {
   // Make sure there is at least one output.
   if (outputs.empty()) {
@@ -1064,18 +1100,19 @@
   cm::optional<std::string> workingStr = MakeOptionalString(workingDir);
 
   // Dispatch command creation to allow generator expressions in outputs.
-  this->AddGeneratorAction([=](cmLocalGenerator& lg,
-                               const cmListFileBacktrace& lfbt) {
-    BacktraceGuard guard(this->Backtrace, lfbt);
-    cmSourceFile* sf = detail::AddCustomCommandToOutput(
-      lg, lfbt, cmCommandOrigin::Project, outputs, byproducts, depends,
-      main_dependency, implicit_depends, commandLines,
-      GetCStrOrNull(commentStr), GetCStrOrNull(workingStr), replace,
-      escapeOldStyle, uses_terminal, command_expand_lists, depfile, job_pool);
-    if (callback && sf) {
-      callback(sf);
-    }
-  });
+  this->AddGeneratorAction(
+    [=](cmLocalGenerator& lg, const cmListFileBacktrace& lfbt) {
+      BacktraceGuard guard(this->Backtrace, lfbt);
+      cmSourceFile* sf = detail::AddCustomCommandToOutput(
+        lg, lfbt, cmCommandOrigin::Project, outputs, byproducts, depends,
+        main_dependency, implicit_depends, commandLines,
+        GetCStrOrNull(commentStr), GetCStrOrNull(workingStr), replace,
+        escapeOldStyle, uses_terminal, command_expand_lists, depfile, job_pool,
+        stdPipesUTF8);
+      if (callback && sf) {
+        callback(sf);
+      }
+    });
 }
 
 void cmMakefile::AddCustomCommandOldStyle(
@@ -1191,7 +1228,7 @@
   const std::vector<std::string>& depends,
   const cmCustomCommandLines& commandLines, bool escapeOldStyle,
   const char* comment, bool uses_terminal, bool command_expand_lists,
-  const std::string& job_pool)
+  const std::string& job_pool, bool stdPipesUTF8)
 {
   cmTarget* target = this->AddNewUtilityTarget(utilityName, excludeFromAll);
 
@@ -1220,7 +1257,7 @@
                                 force, GetCStrOrNull(workingStr), byproducts,
                                 depends, commandLines, escapeOldStyle,
                                 GetCStrOrNull(commentStr), uses_terminal,
-                                command_expand_lists, job_pool);
+                                command_expand_lists, job_pool, stdPipesUTF8);
     });
 
   return target;
@@ -1358,9 +1395,9 @@
   const char* define = def.c_str() + 2;
 
   if (remove) {
-    if (const char* cdefs = this->GetProperty("COMPILE_DEFINITIONS")) {
+    if (cmProp cdefs = this->GetProperty("COMPILE_DEFINITIONS")) {
       // Expand the list.
-      std::vector<std::string> defs = cmExpandedList(cdefs);
+      std::vector<std::string> defs = cmExpandedList(*cdefs);
 
       // Recompose the list without the definition.
       auto defEnd = std::remove(defs.begin(), defs.end(), define);
@@ -1389,29 +1426,32 @@
   // Include transform property.  There is no per-config version.
   {
     const char* prop = "IMPLICIT_DEPENDS_INCLUDE_TRANSFORM";
-    this->SetProperty(prop, parent->GetProperty(prop));
+    cmProp p = parent->GetProperty(prop);
+    this->SetProperty(prop, p ? p->c_str() : nullptr);
   }
 
   // compile definitions property and per-config versions
   cmPolicies::PolicyStatus polSt = this->GetPolicyStatus(cmPolicies::CMP0043);
   if (polSt == cmPolicies::WARN || polSt == cmPolicies::OLD) {
-    this->SetProperty("COMPILE_DEFINITIONS",
-                      parent->GetProperty("COMPILE_DEFINITIONS"));
-    std::vector<std::string> configs;
-    this->GetConfigurations(configs);
+    cmProp p = parent->GetProperty("COMPILE_DEFINITIONS");
+    this->SetProperty("COMPILE_DEFINITIONS", p ? p->c_str() : nullptr);
+    std::vector<std::string> configs =
+      this->GetGeneratorConfigs(cmMakefile::ExcludeEmptyConfig);
     for (std::string const& config : configs) {
       std::string defPropName =
         cmStrCat("COMPILE_DEFINITIONS_", cmSystemTools::UpperCase(config));
-      const char* prop = parent->GetProperty(defPropName);
-      this->SetProperty(defPropName, prop);
+      cmProp prop = parent->GetProperty(defPropName);
+      this->SetProperty(defPropName, prop ? prop->c_str() : nullptr);
     }
   }
 
   // labels
-  this->SetProperty("LABELS", parent->GetProperty("LABELS"));
+  cmProp p = parent->GetProperty("LABELS");
+  this->SetProperty("LABELS", p ? p->c_str() : nullptr);
 
   // link libraries
-  this->SetProperty("LINK_LIBRARIES", parent->GetProperty("LINK_LIBRARIES"));
+  p = parent->GetProperty("LINK_LIBRARIES");
+  this->SetProperty("LINK_LIBRARIES", p ? p->c_str() : nullptr);
 
   // the initial project name
   this->StateSnapshot.SetProjectName(parent->StateSnapshot.GetProjectName());
@@ -1422,6 +1462,9 @@
   // Imported targets.
   this->ImportedTargets = parent->ImportedTargets;
 
+  // Non-global Alias targets.
+  this->AliasTargets = parent->AliasTargets;
+
   // Recursion depth.
   this->RecursionDepth = parent->RecursionDepth;
 }
@@ -1471,8 +1514,6 @@
 #endif
 
   this->PopLoopBlockBarrier();
-
-  this->CheckForUnusedVariables();
 }
 
 void cmMakefile::PushMacroScope(std::string const& fileName,
@@ -1606,7 +1647,7 @@
         allowedCommands.insert("message");
         isProblem = false;
         for (cmListFileFunction const& func : listFile.Functions) {
-          if (!cmContains(allowedCommands, func.Name.Lower)) {
+          if (!cm::contains(allowedCommands, func.Name.Lower)) {
             isProblem = true;
             break;
           }
@@ -1619,7 +1660,8 @@
         this->SetCheckCMP0000(true);
 
         // Implicitly set the version for the user.
-        this->SetPolicyVersion("2.4", std::string());
+        cmPolicies::ApplyPolicyVersion(this, 2, 4, 0,
+                                       cmPolicies::WarnCompat::Off);
       }
     }
     bool hasProject = false;
@@ -1818,9 +1860,6 @@
 
 void cmMakefile::AddDefinition(const std::string& name, cm::string_view value)
 {
-  if (this->VariableInitialized(name)) {
-    this->LogUnused("changing definition", name);
-  }
   this->StateSnapshot.SetDefinition(name, value);
 
 #ifndef CMAKE_BOOTSTRAP
@@ -1842,8 +1881,7 @@
                                     cmStateEnums::CacheEntryType type,
                                     bool force)
 {
-  const std::string* existingValue =
-    this->GetState()->GetInitializedCacheValue(name);
+  cmProp existingValue = this->GetState()->GetInitializedCacheValue(name);
   // must be outside the following if() to keep it alive long enough
   std::string nvalue;
 
@@ -1882,16 +1920,6 @@
   this->StateSnapshot.RemoveDefinition(name);
 }
 
-void cmMakefile::CheckForUnusedVariables() const
-{
-  if (!this->WarnUnused) {
-    return;
-  }
-  for (const std::string& key : this->StateSnapshot.UnusedKeys()) {
-    this->LogUnused("out of scope", key);
-  }
-}
-
 void cmMakefile::MarkVariableAsUsed(const std::string& var)
 {
   this->StateSnapshot.GetDefinition(var);
@@ -1919,29 +1947,8 @@
   }
 }
 
-void cmMakefile::LogUnused(const char* reason, const std::string& name) const
-{
-  if (this->WarnUnused) {
-    std::string path;
-    if (!this->ExecutionStatusStack.empty()) {
-      path = this->GetExecutionContext().FilePath;
-    } else {
-      path = cmStrCat(this->GetCurrentSourceDirectory(), "/CMakeLists.txt");
-    }
-
-    if (this->CheckSystemVars || this->IsProjectFile(path.c_str())) {
-      std::ostringstream msg;
-      msg << "unused variable (" << reason << ") \'" << name << "\'";
-      this->IssueMessage(MessageType::AUTHOR_WARNING, msg.str());
-    }
-  }
-}
-
 void cmMakefile::RemoveDefinition(const std::string& name)
 {
-  if (this->VariableInitialized(name)) {
-    this->LogUnused("unsetting", name);
-  }
   this->StateSnapshot.RemoveDefinition(name);
 #ifndef CMAKE_BOOTSTRAP
   cmVariableWatch* vv = this->GetVariableWatch();
@@ -1973,8 +1980,8 @@
     default:;
   }
 
-  if (const char* linkLibsProp = this->GetProperty("LINK_LIBRARIES")) {
-    std::vector<std::string> linkLibs = cmExpandedList(linkLibsProp);
+  if (cmProp linkLibsProp = this->GetProperty("LINK_LIBRARIES")) {
+    std::vector<std::string> linkLibs = cmExpandedList(*linkLibsProp);
 
     for (auto j = linkLibs.begin(); j != linkLibs.end(); ++j) {
       std::string libraryName = *j;
@@ -1997,10 +2004,13 @@
   }
 }
 
-void cmMakefile::AddAlias(const std::string& lname, std::string const& tgtName)
+void cmMakefile::AddAlias(const std::string& lname, std::string const& tgtName,
+                          bool globallyVisible)
 {
   this->AliasTargets[lname] = tgtName;
-  this->GetGlobalGenerator()->AddAlias(lname, tgtName);
+  if (globallyVisible) {
+    this->GetGlobalGenerator()->AddAlias(lname, tgtName);
+  }
 }
 
 cmTarget* cmMakefile::AddLibrary(const std::string& lname,
@@ -2043,11 +2053,11 @@
 cmTarget* cmMakefile::AddNewTarget(cmStateEnums::TargetType type,
                                    const std::string& name)
 {
-  auto it =
-    this->Targets
-      .emplace(name,
-               cmTarget(name, type, cmTarget::VisibilityNormal, this, true))
-      .first;
+  auto it = this->Targets
+              .emplace(name,
+                       cmTarget(name, type, cmTarget::VisibilityNormal, this,
+                                cmTarget::PerConfig::Yes))
+              .first;
   this->OrderedTargets.push_back(&it->second);
   this->GetGlobalGenerator()->IndexTarget(&it->second);
   this->GetStateSnapshot().GetDirectory().AddNormalTargetName(name);
@@ -2366,11 +2376,11 @@
 
 cmSourceGroup* cmMakefile::GetOrCreateSourceGroup(const std::string& name)
 {
-  const char* delimiter = this->GetDefinition("SOURCE_GROUP_DELIMITER");
-  if (delimiter == nullptr) {
-    delimiter = "\\";
+  const char* delimiters = this->GetDefinition("SOURCE_GROUP_DELIMITER");
+  if (delimiters == nullptr) {
+    delimiters = "/\\";
   }
-  return this->GetOrCreateSourceGroup(cmTokenize(name, delimiter));
+  return this->GetOrCreateSourceGroup(cmTokenize(name, delimiters));
 }
 
 /**
@@ -2418,14 +2428,14 @@
   }
   std::ostringstream w;
 
-  const char* includeDirs = this->GetProperty("INCLUDE_DIRECTORIES");
-  if (mightExpandVariablesCMP0019(includeDirs)) {
-    std::string dirs = includeDirs;
+  cmProp includeDirs = this->GetProperty("INCLUDE_DIRECTORIES");
+  if (includeDirs && mightExpandVariablesCMP0019(includeDirs->c_str())) {
+    std::string dirs = *includeDirs;
     this->ExpandVariablesInString(dirs, true, true);
-    if (pol == cmPolicies::WARN && dirs != includeDirs) {
+    if (pol == cmPolicies::WARN && dirs != *includeDirs) {
       /* clang-format off */
       w << "Evaluated directory INCLUDE_DIRECTORIES\n"
-        << "  " << includeDirs << "\n"
+        << "  " << *includeDirs << "\n"
         << "as\n"
         << "  " << dirs << "\n";
       /* clang-format on */
@@ -2441,13 +2451,13 @@
       continue;
     }
     includeDirs = t.GetProperty("INCLUDE_DIRECTORIES");
-    if (mightExpandVariablesCMP0019(includeDirs)) {
-      std::string dirs = includeDirs;
+    if (includeDirs && mightExpandVariablesCMP0019(includeDirs->c_str())) {
+      std::string dirs = *includeDirs;
       this->ExpandVariablesInString(dirs, true, true);
-      if (pol == cmPolicies::WARN && dirs != includeDirs) {
+      if (pol == cmPolicies::WARN && dirs != *includeDirs) {
         /* clang-format off */
         w << "Evaluated target " << t.GetName() << " INCLUDE_DIRECTORIES\n"
-          << "  " << includeDirs << "\n"
+          << "  " << *includeDirs << "\n"
           << "as\n"
           << "  " << dirs << "\n";
         /* clang-format on */
@@ -2456,10 +2466,10 @@
     }
   }
 
-  if (const char* linkDirsProp = this->GetProperty("LINK_DIRECTORIES")) {
-    if (mightExpandVariablesCMP0019(linkDirsProp)) {
-      std::string d = linkDirsProp;
-      std::string orig = linkDirsProp;
+  if (cmProp linkDirsProp = this->GetProperty("LINK_DIRECTORIES")) {
+    if (mightExpandVariablesCMP0019(linkDirsProp->c_str())) {
+      std::string d = *linkDirsProp;
+      const std::string orig = d;
       this->ExpandVariablesInString(d, true, true);
       if (pol == cmPolicies::WARN && d != orig) {
         /* clang-format off */
@@ -2472,20 +2482,17 @@
     }
   }
 
-  if (const char* linkLibsProp = this->GetProperty("LINK_LIBRARIES")) {
-    std::vector<std::string> linkLibs = cmExpandedList(linkLibsProp);
+  if (cmProp linkLibsProp = this->GetProperty("LINK_LIBRARIES")) {
+    std::vector<std::string> linkLibs = cmExpandedList(*linkLibsProp);
 
     for (auto l = linkLibs.begin(); l != linkLibs.end(); ++l) {
       std::string libName = *l;
-      if (libName == "optimized") {
-        ++l;
-        libName = *l;
-      } else if (libName == "debug") {
+      if (libName == "optimized"_s || libName == "debug"_s) {
         ++l;
         libName = *l;
       }
       if (mightExpandVariablesCMP0019(libName.c_str())) {
-        std::string orig = libName;
+        const std::string orig = libName;
         this->ExpandVariablesInString(libName, true, true);
         if (pol == cmPolicies::WARN && libName != orig) {
           /* clang-format off */
@@ -2514,8 +2521,7 @@
 
 bool cmMakefile::IsOn(const std::string& name) const
 {
-  const char* value = this->GetDefinition(name);
-  return cmIsOn(value);
+  return cmIsOn(this->GetDef(name));
 }
 
 bool cmMakefile::IsSet(const std::string& name) const
@@ -2589,7 +2595,7 @@
   };
 
   for (auto const& entry : sdkDatabase) {
-    if (sdkRoot.find(entry.name) == 0 ||
+    if (cmHasPrefix(sdkRoot, entry.name) ||
         sdkRoot.find(std::string("/") + entry.name) != std::string::npos) {
       return entry.sdk;
     }
@@ -2647,7 +2653,7 @@
 
 bool cmMakefile::IsDefinitionSet(const std::string& name) const
 {
-  const std::string* def = this->StateSnapshot.GetDefinition(name);
+  cmProp def = this->StateSnapshot.GetDefinition(name);
   if (!def) {
     def = this->GetState()->GetInitializedCacheValue(name);
   }
@@ -2664,7 +2670,7 @@
 
 const std::string* cmMakefile::GetDef(const std::string& name) const
 {
-  const std::string* def = this->StateSnapshot.GetDefinition(name);
+  cmProp def = this->StateSnapshot.GetDefinition(name);
   if (!def) {
     def = this->GetState()->GetInitializedCacheValue(name);
   }
@@ -2710,6 +2716,18 @@
   return *def;
 }
 
+bool cmMakefile::GetDefExpandList(const std::string& name,
+                                  std::vector<std::string>& out,
+                                  bool emptyArgs) const
+{
+  cmProp def = this->GetDef(name);
+  if (!def) {
+    return false;
+  }
+  cmExpandList(*def, out, emptyArgs);
+  return true;
+}
+
 std::vector<std::string> cmMakefile::GetDefinitions() const
 {
   std::vector<std::string> res = this->StateSnapshot.ClosureKeys();
@@ -2998,7 +3016,7 @@
           openstack.pop_back();
           result.append(last, in - last);
           std::string const& lookup = result.substr(var.loc);
-          const char* value = nullptr;
+          cmProp value = nullptr;
           std::string varresult;
           std::string svalue;
           switch (var.domain) {
@@ -3006,12 +3024,12 @@
               if (filename && lookup == lineVar) {
                 varresult = std::to_string(line);
               } else {
-                value = this->GetDefinition(lookup);
+                value = this->GetDef(lookup);
               }
               break;
             case ENVIRONMENT:
               if (cmSystemTools::GetEnv(lookup, svalue)) {
-                value = svalue.c_str();
+                value = &svalue;
               }
               break;
             case CACHE:
@@ -3021,9 +3039,9 @@
           // Get the string we're meant to append to.
           if (value) {
             if (escapeQuotes) {
-              varresult = cmEscapeQuotes(value);
+              varresult = cmEscapeQuotes(*value);
             } else {
-              varresult = value;
+              varresult = *value;
             }
           } else if (!this->SuppressSideEffects) {
             this->MaybeWarnUninitialized(lookup, filename);
@@ -3234,28 +3252,28 @@
   }
 }
 
-std::string cmMakefile::GetConfigurations(std::vector<std::string>& configs,
-                                          bool singleConfig) const
+std::string cmMakefile::GetDefaultConfiguration() const
 {
   if (this->GetGlobalGenerator()->IsMultiConfig()) {
-    if (const char* configTypes =
-          this->GetDefinition("CMAKE_CONFIGURATION_TYPES")) {
-      cmExpandList(configTypes, configs);
-    }
-    return "";
+    return std::string{};
   }
-  const std::string& buildType = this->GetSafeDefinition("CMAKE_BUILD_TYPE");
-  if (singleConfig && !buildType.empty()) {
-    configs.push_back(buildType);
-  }
-  return buildType;
+  return this->GetSafeDefinition("CMAKE_BUILD_TYPE");
 }
 
-std::vector<std::string> cmMakefile::GetGeneratorConfigs() const
+std::vector<std::string> cmMakefile::GetGeneratorConfigs(
+  GeneratorConfigQuery mode) const
 {
   std::vector<std::string> configs;
-  GetConfigurations(configs);
-  if (configs.empty()) {
+  if (this->GetGlobalGenerator()->IsMultiConfig() ||
+      mode == cmMakefile::OnlyMultiConfig) {
+    this->GetDefExpandList("CMAKE_CONFIGURATION_TYPES", configs);
+  } else {
+    const std::string& buildType = this->GetSafeDefinition("CMAKE_BUILD_TYPE");
+    if (!buildType.empty()) {
+      configs.emplace_back(buildType);
+    }
+  }
+  if (mode == cmMakefile::IncludeEmptyConfig && configs.empty()) {
     configs.emplace_back();
   }
   return configs;
@@ -3675,7 +3693,7 @@
   if (cmakeArgs) {
     // FIXME: Workaround to ignore unused CLI variables in try-compile.
     //
-    // Ideally we should use SetArgs to honor options like --warn-unused-vars.
+    // Ideally we should use SetArgs for options like --no-warn-unused-cli.
     // However, there is a subtle problem when certain arguments are passed to
     // a macro wrapping around try_compile or try_run that does not escape
     // semicolons in its parameters but just passes ${ARGV} or ${ARGN}.  In
@@ -3694,7 +3712,7 @@
     // the value VAR=a is sufficient for the try_compile or try_run to get the
     // correct result.  Calling SetArgs here would break such projects that
     // previously built.  Instead we work around the issue by never reporting
-    // unused arguments and ignoring options such as --warn-unused-vars.
+    // unused arguments and ignoring options such as --no-warn-unused-cli.
     cm.SetWarnUnusedCli(false);
     // cm.SetArgs(*cmakeArgs, true);
 
@@ -3948,6 +3966,7 @@
 int cmMakefile::ConfigureFile(const std::string& infile,
                               const std::string& outfile, bool copyonly,
                               bool atOnly, bool escapeQuotes,
+                              bool use_source_permissions,
                               cmNewLineStyle newLine)
 {
   int res = 1;
@@ -3971,7 +3990,13 @@
   this->AddCMakeOutputFile(soutfile);
 
   mode_t perm = 0;
-  cmSystemTools::GetPermissions(sinfile, perm);
+  if (!use_source_permissions) {
+    perm = perm | mode_owner_read | mode_owner_write | mode_group_read |
+      mode_world_read;
+  } else {
+    cmSystemTools::GetPermissions(sinfile, perm);
+  }
+
   std::string::size_type pos = soutfile.rfind('/');
   if (pos != std::string::npos) {
     std::string path = soutfile.substr(0, pos);
@@ -3980,6 +4005,13 @@
 
   if (copyonly) {
     if (!cmSystemTools::CopyFileIfDifferent(sinfile, soutfile)) {
+      this->IssueMessage(MessageType::FATAL_ERROR,
+                         cmSystemTools::GetLastSystemError());
+      return 0;
+    }
+    if (!cmSystemTools::SetPermissions(soutfile, perm)) {
+      this->IssueMessage(MessageType::FATAL_ERROR,
+                         cmSystemTools::GetLastSystemError());
       return 0;
     }
   } else {
@@ -4030,9 +4062,15 @@
     fin.close();
     fout.close();
     if (!cmSystemTools::CopyFileIfDifferent(tempOutputFile, soutfile)) {
+      this->IssueMessage(MessageType::FATAL_ERROR,
+                         cmSystemTools::GetLastSystemError());
       res = 0;
     } else {
-      cmSystemTools::SetPermissions(soutfile, perm);
+      if (!cmSystemTools::SetPermissions(soutfile, perm)) {
+        this->IssueMessage(MessageType::FATAL_ERROR,
+                           cmSystemTools::GetLastSystemError());
+        res = 0;
+      }
     }
     cmSystemTools::RemoveFile(tempOutputFile);
   }
@@ -4051,7 +4089,7 @@
                                                     this->Backtrace);
 }
 
-const char* cmMakefile::GetProperty(const std::string& prop) const
+cmProp cmMakefile::GetProperty(const std::string& prop) const
 {
   // Check for computed properties.
   static std::string output;
@@ -4064,13 +4102,13 @@
                      return pair.first;
                    });
     output = cmJoin(keys, ";");
-    return output.c_str();
+    return &output;
   }
 
   return this->StateSnapshot.GetDirectory().GetProperty(prop);
 }
 
-const char* cmMakefile::GetProperty(const std::string& prop, bool chain) const
+cmProp cmMakefile::GetProperty(const std::string& prop, bool chain) const
 {
   return this->StateSnapshot.GetDirectory().GetProperty(prop, chain);
 }
@@ -4129,8 +4167,8 @@
 void cmMakefile::AddCMakeDependFilesFromUser()
 {
   std::vector<std::string> deps;
-  if (const char* deps_str = this->GetProperty("CMAKE_CONFIGURE_DEPENDS")) {
-    cmExpandList(deps_str, deps);
+  if (cmProp deps_str = this->GetProperty("CMAKE_CONFIGURE_DEPENDS")) {
+    cmExpandList(*deps_str, deps);
   }
   for (std::string const& dep : deps) {
     if (cmSystemTools::FileIsFullPath(dep)) {
@@ -4189,8 +4227,6 @@
 
   this->PopLoopBlockBarrier();
 
-  this->CheckForUnusedVariables();
-
   this->PopSnapshot();
 }
 
@@ -4225,7 +4261,7 @@
     new cmTarget(name, type,
                  global ? cmTarget::VisibilityImportedGlobally
                         : cmTarget::VisibilityImported,
-                 this, true));
+                 this, cmTarget::PerConfig::Yes));
 
   // Add to the set of available imported targets.
   this->ImportedTargets[name] = target.get();
@@ -4241,7 +4277,15 @@
 {
   // Look for an imported target.  These take priority because they
   // are more local in scope and do not have to be globally unique.
-  auto imported = this->ImportedTargets.find(name);
+  auto targetName = name;
+  if (!excludeAliases) {
+    // Look for local alias targets.
+    auto alias = this->AliasTargets.find(name);
+    if (alias != this->AliasTargets.end()) {
+      targetName = alias->second;
+    }
+  }
+  auto imported = this->ImportedTargets.find(targetName);
   if (imported != this->ImportedTargets.end()) {
     return imported->second;
   }
@@ -4257,7 +4301,7 @@
 
 bool cmMakefile::IsAlias(const std::string& name) const
 {
-  if (cmContains(this->AliasTargets, name)) {
+  if (cm::contains(this->AliasTargets, name)) {
     return true;
   }
   return this->GetGlobalGenerator()->IsAlias(name);
@@ -4498,7 +4542,7 @@
 
   // Deprecate old policies, especially those that require a lot
   // of code to maintain the old behavior.
-  if (status == cmPolicies::OLD && id <= cmPolicies::CMP0069 &&
+  if (status == cmPolicies::OLD && id <= cmPolicies::CMP0072 &&
       !(this->GetCMakeInstance()->GetIsInTryCompile() &&
         (
           // Policies set by cmCoreTryCompile::TryCompileCode.
@@ -4540,7 +4584,7 @@
   // cmStateSnapshot manages nested policy scopes within it.
   // Since the scope corresponding to the snapshot is closing,
   // reject any still-open nested policy scopes with an error.
-  while (!this->StateSnapshot.CanPopPolicyScope()) {
+  while (this->StateSnapshot.CanPopPolicyScope()) {
     if (reportError) {
       this->IssueMessage(MessageType::FATAL_ERROR,
                          "cmake_policy PUSH without matching POP");
@@ -4556,7 +4600,8 @@
 bool cmMakefile::SetPolicyVersion(std::string const& version_min,
                                   std::string const& version_max)
 {
-  return cmPolicies::ApplyPolicyVersion(this, version_min, version_max);
+  return cmPolicies::ApplyPolicyVersion(this, version_min, version_max,
+                                        cmPolicies::WarnCompat::On);
 }
 
 bool cmMakefile::HasCMP0054AlreadyBeenReported(
@@ -4592,676 +4637,6 @@
   return ignoreErrors;
 }
 
-#define FEATURE_STRING(F) , #F
-static const char* const C_FEATURES[] = { nullptr FOR_EACH_C_FEATURE(
-  FEATURE_STRING) };
-
-static const char* const CXX_FEATURES[] = { nullptr FOR_EACH_CXX_FEATURE(
-  FEATURE_STRING) };
-
-static const char* const CUDA_FEATURES[] = { nullptr FOR_EACH_CUDA_FEATURE(
-  FEATURE_STRING) };
-#undef FEATURE_STRING
-
-static const char* const C_STANDARDS[] = { "90", "99", "11" };
-static const char* const CXX_STANDARDS[] = { "98", "11", "14", "17", "20" };
-static const char* const CUDA_STANDARDS[] = { "03", "11", "14", "17", "20" };
-
-bool cmMakefile::AddRequiredTargetFeature(cmTarget* target,
-                                          const std::string& feature,
-                                          std::string* error) const
-{
-  if (cmGeneratorExpression::Find(feature) != std::string::npos) {
-    target->AppendProperty("COMPILE_FEATURES", feature);
-    return true;
-  }
-
-  std::string lang;
-  if (!this->CompileFeatureKnown(target, feature, lang, error)) {
-    return false;
-  }
-
-  const char* features = this->CompileFeaturesAvailable(lang, error);
-  if (!features) {
-    return false;
-  }
-
-  std::vector<std::string> availableFeatures = cmExpandedList(features);
-  if (!cmContains(availableFeatures, feature)) {
-    std::ostringstream e;
-    e << "The compiler feature \"" << feature << "\" is not known to " << lang
-      << " compiler\n\""
-      << this->GetDefinition("CMAKE_" + lang + "_COMPILER_ID")
-      << "\"\nversion "
-      << this->GetDefinition("CMAKE_" + lang + "_COMPILER_VERSION") << ".";
-    if (error) {
-      *error = e.str();
-    } else {
-      this->GetCMakeInstance()->IssueMessage(MessageType::FATAL_ERROR, e.str(),
-                                             this->Backtrace);
-    }
-    return false;
-  }
-
-  target->AppendProperty("COMPILE_FEATURES", feature);
-
-  if (lang == "C" || lang == "OBJC") {
-    return this->AddRequiredTargetCFeature(target, feature, lang, error);
-  }
-  if (lang == "CUDA") {
-    return this->AddRequiredTargetCudaFeature(target, feature, lang, error);
-  }
-  return this->AddRequiredTargetCxxFeature(target, feature, lang, error);
-}
-
-bool cmMakefile::CompileFeatureKnown(cmTarget const* target,
-                                     const std::string& feature,
-                                     std::string& lang,
-                                     std::string* error) const
-{
-  assert(cmGeneratorExpression::Find(feature) == std::string::npos);
-
-  bool isCFeature =
-    std::find_if(cm::cbegin(C_FEATURES) + 1, cm::cend(C_FEATURES),
-                 cmStrCmp(feature)) != cm::cend(C_FEATURES);
-  if (isCFeature) {
-    lang = "C";
-    return true;
-  }
-  bool isCxxFeature =
-    std::find_if(cm::cbegin(CXX_FEATURES) + 1, cm::cend(CXX_FEATURES),
-                 cmStrCmp(feature)) != cm::cend(CXX_FEATURES);
-  if (isCxxFeature) {
-    lang = "CXX";
-    return true;
-  }
-  bool isCudaFeature =
-    std::find_if(cm::cbegin(CUDA_FEATURES) + 1, cm::cend(CUDA_FEATURES),
-                 cmStrCmp(feature)) != cm::cend(CUDA_FEATURES);
-  if (isCudaFeature) {
-    lang = "CUDA";
-    return true;
-  }
-  std::ostringstream e;
-  if (error) {
-    e << "specified";
-  } else {
-    e << "Specified";
-  }
-  e << " unknown feature \"" << feature
-    << "\" for "
-       "target \""
-    << target->GetName() << "\".";
-  if (error) {
-    *error = e.str();
-  } else {
-    this->GetCMakeInstance()->IssueMessage(MessageType::FATAL_ERROR, e.str(),
-                                           this->Backtrace);
-  }
-  return false;
-}
-
-const char* cmMakefile::CompileFeaturesAvailable(const std::string& lang,
-                                                 std::string* error) const
-{
-  if (!this->GlobalGenerator->GetLanguageEnabled(lang)) {
-    std::ostringstream e;
-    if (error) {
-      e << "cannot";
-    } else {
-      e << "Cannot";
-    }
-    e << " use features from non-enabled language " << lang;
-    if (error) {
-      *error = e.str();
-    } else {
-      this->GetCMakeInstance()->IssueMessage(MessageType::FATAL_ERROR, e.str(),
-                                             this->Backtrace);
-    }
-    return nullptr;
-  }
-
-  const char* featuresKnown =
-    this->GetDefinition("CMAKE_" + lang + "_COMPILE_FEATURES");
-
-  if (!featuresKnown || !*featuresKnown) {
-    std::ostringstream e;
-    if (error) {
-      e << "no";
-    } else {
-      e << "No";
-    }
-    e << " known features for " << lang << " compiler\n\""
-      << this->GetSafeDefinition("CMAKE_" + lang + "_COMPILER_ID")
-      << "\"\nversion "
-      << this->GetSafeDefinition("CMAKE_" + lang + "_COMPILER_VERSION") << ".";
-    if (error) {
-      *error = e.str();
-    } else {
-      this->GetCMakeInstance()->IssueMessage(MessageType::FATAL_ERROR, e.str(),
-                                             this->Backtrace);
-    }
-    return nullptr;
-  }
-  return featuresKnown;
-}
-
-bool cmMakefile::HaveStandardAvailable(cmTarget const* target,
-                                       std::string const& lang,
-                                       const std::string& feature) const
-{
-  if (lang == "C" || lang == "OBJC") {
-    return this->HaveCStandardAvailable(target, feature, lang);
-  }
-  if (lang == "CUDA") {
-    return this->HaveCudaStandardAvailable(target, feature, lang);
-  }
-  return this->HaveCxxStandardAvailable(target, feature, lang);
-}
-
-bool cmMakefile::HaveCStandardAvailable(cmTarget const* target,
-                                        const std::string& feature,
-                                        std::string const& lang) const
-{
-  const char* defaultCStandard =
-    this->GetDefinition(cmStrCat("CMAKE_", lang, "_STANDARD_DEFAULT"));
-  if (!defaultCStandard) {
-    this->IssueMessage(
-      MessageType::INTERNAL_ERROR,
-      cmStrCat("CMAKE_", lang,
-               "_STANDARD_DEFAULT is not set.  COMPILE_FEATURES support "
-               "not fully configured for this compiler."));
-    // Return true so the caller does not try to lookup the default standard.
-    return true;
-  }
-  if (std::find_if(cm::cbegin(C_STANDARDS), cm::cend(C_STANDARDS),
-                   cmStrCmp(defaultCStandard)) == cm::cend(C_STANDARDS)) {
-    const std::string e = cmStrCat("The CMAKE_", lang,
-                                   "_STANDARD_DEFAULT variable contains an "
-                                   "invalid value: \"",
-                                   defaultCStandard, "\".");
-    this->IssueMessage(MessageType::INTERNAL_ERROR, e);
-    return false;
-  }
-
-  bool needC90 = false;
-  bool needC99 = false;
-  bool needC11 = false;
-
-  this->CheckNeededCLanguage(feature, lang, needC90, needC99, needC11);
-
-  const char* existingCStandard =
-    target->GetProperty(cmStrCat(lang, "_STANDARD"));
-  if (!existingCStandard) {
-    existingCStandard = defaultCStandard;
-  }
-
-  if (std::find_if(cm::cbegin(C_STANDARDS), cm::cend(C_STANDARDS),
-                   cmStrCmp(existingCStandard)) == cm::cend(C_STANDARDS)) {
-    const std::string e = cmStrCat(
-      "The ", lang, "_STANDARD property on target \"", target->GetName(),
-      "\" contained an invalid value: \"", existingCStandard, "\".");
-    this->IssueMessage(MessageType::FATAL_ERROR, e);
-    return false;
-  }
-
-  const char* const* existingCIt = existingCStandard
-    ? std::find_if(cm::cbegin(C_STANDARDS), cm::cend(C_STANDARDS),
-                   cmStrCmp(existingCStandard))
-    : cm::cend(C_STANDARDS);
-
-  if (needC11 && existingCStandard &&
-      existingCIt < std::find_if(cm::cbegin(C_STANDARDS),
-                                 cm::cend(C_STANDARDS), cmStrCmp("11"))) {
-    return false;
-  }
-  if (needC99 && existingCStandard &&
-      existingCIt < std::find_if(cm::cbegin(C_STANDARDS),
-                                 cm::cend(C_STANDARDS), cmStrCmp("99"))) {
-    return false;
-  }
-  if (needC90 && existingCStandard &&
-      existingCIt < std::find_if(cm::cbegin(C_STANDARDS),
-                                 cm::cend(C_STANDARDS), cmStrCmp("90"))) {
-    return false;
-  }
-  return true;
-}
-
-bool cmMakefile::IsLaterStandard(std::string const& lang,
-                                 std::string const& lhs,
-                                 std::string const& rhs)
-{
-  if (lang == "C" || lang == "OBJC") {
-    const char* const* rhsIt = std::find_if(
-      cm::cbegin(C_STANDARDS), cm::cend(C_STANDARDS), cmStrCmp(rhs));
-
-    return std::find_if(rhsIt, cm::cend(C_STANDARDS), cmStrCmp(lhs)) !=
-      cm::cend(C_STANDARDS);
-  }
-  if (lang == "CUDA") {
-    const char* const* rhsIt = std::find_if(
-      cm::cbegin(CUDA_STANDARDS), cm::cend(CUDA_STANDARDS), cmStrCmp(rhs));
-
-    return std::find_if(rhsIt, cm::cend(CUDA_STANDARDS), cmStrCmp(lhs)) !=
-      cm::cend(CUDA_STANDARDS);
-  }
-
-  const char* const* rhsIt = std::find_if(
-    cm::cbegin(CXX_STANDARDS), cm::cend(CXX_STANDARDS), cmStrCmp(rhs));
-
-  return std::find_if(rhsIt, cm::cend(CXX_STANDARDS), cmStrCmp(lhs)) !=
-    cm::cend(CXX_STANDARDS);
-}
-
-bool cmMakefile::HaveCxxStandardAvailable(cmTarget const* target,
-                                          const std::string& feature,
-                                          std::string const& lang) const
-{
-  const char* defaultCxxStandard =
-    this->GetDefinition(cmStrCat("CMAKE_", lang, "_STANDARD_DEFAULT"));
-  if (!defaultCxxStandard) {
-    this->IssueMessage(
-      MessageType::INTERNAL_ERROR,
-      cmStrCat("CMAKE_", lang,
-               "_STANDARD_DEFAULT is not set.  COMPILE_FEATURES support "
-               "not fully configured for this compiler."));
-    // Return true so the caller does not try to lookup the default standard.
-    return true;
-  }
-  if (std::find_if(cm::cbegin(CXX_STANDARDS), cm::cend(CXX_STANDARDS),
-                   cmStrCmp(defaultCxxStandard)) == cm::cend(CXX_STANDARDS)) {
-    const std::string e =
-      cmStrCat("The CMAKE_", lang, "_STANDARD_DEFAULT variable contains an ",
-               "invalid value: \"", defaultCxxStandard, "\".");
-    this->IssueMessage(MessageType::INTERNAL_ERROR, e);
-    return false;
-  }
-
-  bool needCxx98 = false;
-  bool needCxx11 = false;
-  bool needCxx14 = false;
-  bool needCxx17 = false;
-  bool needCxx20 = false;
-  this->CheckNeededCxxLanguage(feature, lang, needCxx98, needCxx11, needCxx14,
-                               needCxx17, needCxx20);
-
-  const char* existingCxxStandard =
-    target->GetProperty(cmStrCat(lang, "_STANDARD"));
-  if (!existingCxxStandard) {
-    existingCxxStandard = defaultCxxStandard;
-  }
-
-  const char* const* existingCxxLevel =
-    std::find_if(cm::cbegin(CXX_STANDARDS), cm::cend(CXX_STANDARDS),
-                 cmStrCmp(existingCxxStandard));
-  if (existingCxxLevel == cm::cend(CXX_STANDARDS)) {
-    const std::string e = cmStrCat(
-      "The ", lang, "_STANDARD property on target \"", target->GetName(),
-      "\" contained an invalid value: \"", existingCxxStandard, "\".");
-    this->IssueMessage(MessageType::FATAL_ERROR, e);
-    return false;
-  }
-
-  /* clang-format off */
-  const char* const* needCxxLevel =
-    needCxx20 ? &CXX_STANDARDS[4]
-    : needCxx17 ? &CXX_STANDARDS[3]
-    : needCxx14 ? &CXX_STANDARDS[2]
-    : needCxx11 ? &CXX_STANDARDS[1]
-    : needCxx98 ? &CXX_STANDARDS[0]
-    : nullptr;
-  /* clang-format on */
-
-  return !needCxxLevel || needCxxLevel <= existingCxxLevel;
-}
-
-void cmMakefile::CheckNeededCxxLanguage(const std::string& feature,
-                                        std::string const& lang,
-                                        bool& needCxx98, bool& needCxx11,
-                                        bool& needCxx14, bool& needCxx17,
-                                        bool& needCxx20) const
-{
-  if (const char* propCxx98 =
-        this->GetDefinition(cmStrCat("CMAKE_", lang, "98_COMPILE_FEATURES"))) {
-    std::vector<std::string> props = cmExpandedList(propCxx98);
-    needCxx98 = cmContains(props, feature);
-  }
-  if (const char* propCxx11 =
-        this->GetDefinition(cmStrCat("CMAKE_", lang, "11_COMPILE_FEATURES"))) {
-    std::vector<std::string> props = cmExpandedList(propCxx11);
-    needCxx11 = cmContains(props, feature);
-  }
-  if (const char* propCxx14 =
-        this->GetDefinition(cmStrCat("CMAKE_", lang, "14_COMPILE_FEATURES"))) {
-    std::vector<std::string> props = cmExpandedList(propCxx14);
-    needCxx14 = cmContains(props, feature);
-  }
-  if (const char* propCxx17 =
-        this->GetDefinition(cmStrCat("CMAKE_", lang, "17_COMPILE_FEATURES"))) {
-    std::vector<std::string> props = cmExpandedList(propCxx17);
-    needCxx17 = cmContains(props, feature);
-  }
-  if (const char* propCxx20 =
-        this->GetDefinition(cmStrCat("CMAKE_", lang, "20_COMPILE_FEATURES"))) {
-    std::vector<std::string> props = cmExpandedList(propCxx20);
-    needCxx20 = cmContains(props, feature);
-  }
-}
-
-bool cmMakefile::AddRequiredTargetCxxFeature(cmTarget* target,
-                                             const std::string& feature,
-                                             std::string const& lang,
-                                             std::string* error) const
-{
-  bool needCxx98 = false;
-  bool needCxx11 = false;
-  bool needCxx14 = false;
-  bool needCxx17 = false;
-  bool needCxx20 = false;
-
-  this->CheckNeededCxxLanguage(feature, lang, needCxx98, needCxx11, needCxx14,
-                               needCxx17, needCxx20);
-
-  const char* existingCxxStandard =
-    target->GetProperty(cmStrCat(lang, "_STANDARD"));
-  if (existingCxxStandard == nullptr) {
-    const char* defaultCxxStandard =
-      this->GetDefinition(cmStrCat("CMAKE_", lang, "_STANDARD_DEFAULT"));
-    if (defaultCxxStandard && *defaultCxxStandard) {
-      existingCxxStandard = defaultCxxStandard;
-    }
-  }
-  const char* const* existingCxxLevel = nullptr;
-  if (existingCxxStandard) {
-    existingCxxLevel =
-      std::find_if(cm::cbegin(CXX_STANDARDS), cm::cend(CXX_STANDARDS),
-                   cmStrCmp(existingCxxStandard));
-    if (existingCxxLevel == cm::cend(CXX_STANDARDS)) {
-      const std::string e = cmStrCat(
-        "The ", lang, "_STANDARD property on target \"", target->GetName(),
-        "\" contained an invalid value: \"", existingCxxStandard, "\".");
-      if (error) {
-        *error = e;
-      } else {
-        this->GetCMakeInstance()->IssueMessage(MessageType::FATAL_ERROR, e,
-                                               this->Backtrace);
-      }
-      return false;
-    }
-  }
-
-  /* clang-format off */
-  const char* const* needCxxLevel =
-    needCxx20 ? &CXX_STANDARDS[4]
-    : needCxx17 ? &CXX_STANDARDS[3]
-    : needCxx14 ? &CXX_STANDARDS[2]
-    : needCxx11 ? &CXX_STANDARDS[1]
-    : needCxx98 ? &CXX_STANDARDS[0]
-    : nullptr;
-  /* clang-format on */
-
-  if (needCxxLevel) {
-    // Ensure the C++ language level is high enough to support
-    // the needed C++ features.
-    if (!existingCxxLevel || existingCxxLevel < needCxxLevel) {
-      target->SetProperty(cmStrCat(lang, "_STANDARD"), *needCxxLevel);
-    }
-  }
-
-  return true;
-}
-
-bool cmMakefile::HaveCudaStandardAvailable(cmTarget const* target,
-                                           const std::string& feature,
-                                           std::string const& lang) const
-{
-  const char* defaultCudaStandard =
-    this->GetDefinition(cmStrCat("CMAKE_", lang, "_STANDARD_DEFAULT"));
-  if (!defaultCudaStandard) {
-    this->IssueMessage(
-      MessageType::INTERNAL_ERROR,
-      cmStrCat("CMAKE_", lang,
-               "_STANDARD_DEFAULT is not set.  COMPILE_FEATURES support "
-               "not fully configured for this compiler."));
-    // Return true so the caller does not try to lookup the default standard.
-    return true;
-  }
-  if (std::find_if(cm::cbegin(CUDA_STANDARDS), cm::cend(CUDA_STANDARDS),
-                   cmStrCmp(defaultCudaStandard)) ==
-      cm::cend(CUDA_STANDARDS)) {
-    const std::string e =
-      cmStrCat("The CMAKE_", lang, "_STANDARD_DEFAULT variable contains an ",
-               "invalid value: \"", defaultCudaStandard, "\".");
-    this->IssueMessage(MessageType::INTERNAL_ERROR, e);
-    return false;
-  }
-
-  bool needCuda03 = false;
-  bool needCuda11 = false;
-  bool needCuda14 = false;
-  bool needCuda17 = false;
-  bool needCuda20 = false;
-  this->CheckNeededCudaLanguage(feature, lang, needCuda03, needCuda11,
-                                needCuda14, needCuda17, needCuda20);
-
-  const char* existingCudaStandard =
-    target->GetProperty(cmStrCat(lang, "_STANDARD"));
-  if (!existingCudaStandard) {
-    existingCudaStandard = defaultCudaStandard;
-  }
-
-  const char* const* existingCudaLevel =
-    std::find_if(cm::cbegin(CUDA_STANDARDS), cm::cend(CUDA_STANDARDS),
-                 cmStrCmp(existingCudaStandard));
-  if (existingCudaLevel == cm::cend(CUDA_STANDARDS)) {
-    const std::string e = cmStrCat(
-      "The ", lang, "_STANDARD property on target \"", target->GetName(),
-      "\" contained an invalid value: \"", existingCudaStandard, "\".");
-    this->IssueMessage(MessageType::FATAL_ERROR, e);
-    return false;
-  }
-
-  /* clang-format off */
-  const char* const* needCudaLevel =
-    needCuda20 ? &CUDA_STANDARDS[4]
-    : needCuda17 ? &CUDA_STANDARDS[3]
-    : needCuda14 ? &CUDA_STANDARDS[2]
-    : needCuda11 ? &CUDA_STANDARDS[1]
-    : needCuda03 ? &CUDA_STANDARDS[0]
-    : nullptr;
-  /* clang-format on */
-
-  return !needCudaLevel || needCudaLevel <= existingCudaLevel;
-}
-
-void cmMakefile::CheckNeededCudaLanguage(const std::string& feature,
-                                         std::string const& lang,
-                                         bool& needCuda03, bool& needCuda11,
-                                         bool& needCuda14, bool& needCuda17,
-                                         bool& needCuda20) const
-{
-  if (const char* propCuda03 =
-        this->GetDefinition(cmStrCat("CMAKE_", lang, "03_COMPILE_FEATURES"))) {
-    std::vector<std::string> props = cmExpandedList(propCuda03);
-    needCuda03 = cmContains(props, feature);
-  }
-  if (const char* propCuda11 =
-        this->GetDefinition(cmStrCat("CMAKE_", lang, "11_COMPILE_FEATURES"))) {
-    std::vector<std::string> props = cmExpandedList(propCuda11);
-    needCuda11 = cmContains(props, feature);
-  }
-  if (const char* propCuda14 =
-        this->GetDefinition(cmStrCat("CMAKE_", lang, "14_COMPILE_FEATURES"))) {
-    std::vector<std::string> props = cmExpandedList(propCuda14);
-    needCuda14 = cmContains(props, feature);
-  }
-  if (const char* propCuda17 =
-        this->GetDefinition(cmStrCat("CMAKE_", lang, "17_COMPILE_FEATURES"))) {
-    std::vector<std::string> props = cmExpandedList(propCuda17);
-    needCuda17 = cmContains(props, feature);
-  }
-  if (const char* propCuda20 =
-        this->GetDefinition(cmStrCat("CMAKE_", lang, "20_COMPILE_FEATURES"))) {
-    std::vector<std::string> props = cmExpandedList(propCuda20);
-    needCuda20 = cmContains(props, feature);
-  }
-}
-
-bool cmMakefile::AddRequiredTargetCudaFeature(cmTarget* target,
-                                              const std::string& feature,
-                                              std::string const& lang,
-                                              std::string* error) const
-{
-  bool needCuda03 = false;
-  bool needCuda11 = false;
-  bool needCuda14 = false;
-  bool needCuda17 = false;
-  bool needCuda20 = false;
-
-  this->CheckNeededCudaLanguage(feature, lang, needCuda03, needCuda11,
-                                needCuda14, needCuda17, needCuda20);
-
-  const char* existingCudaStandard =
-    target->GetProperty(cmStrCat(lang, "_STANDARD"));
-  if (existingCudaStandard == nullptr) {
-    const char* defaultCudaStandard =
-      this->GetDefinition(cmStrCat("CMAKE_", lang, "_STANDARD_DEFAULT"));
-    if (defaultCudaStandard && *defaultCudaStandard) {
-      existingCudaStandard = defaultCudaStandard;
-    }
-  }
-  const char* const* existingCudaLevel = nullptr;
-  if (existingCudaStandard) {
-    existingCudaLevel =
-      std::find_if(cm::cbegin(CUDA_STANDARDS), cm::cend(CUDA_STANDARDS),
-                   cmStrCmp(existingCudaStandard));
-    if (existingCudaLevel == cm::cend(CUDA_STANDARDS)) {
-      const std::string e = cmStrCat(
-        "The ", lang, "_STANDARD property on target \"", target->GetName(),
-        "\" contained an invalid value: \"", existingCudaStandard, "\".");
-      if (error) {
-        *error = e;
-      } else {
-        this->GetCMakeInstance()->IssueMessage(MessageType::FATAL_ERROR, e,
-                                               this->Backtrace);
-      }
-      return false;
-    }
-  }
-
-  /* clang-format off */
-  const char* const* needCudaLevel =
-    needCuda20 ? &CUDA_STANDARDS[4]
-    : needCuda17 ? &CUDA_STANDARDS[3]
-    : needCuda14 ? &CUDA_STANDARDS[2]
-    : needCuda11 ? &CUDA_STANDARDS[1]
-    : needCuda03 ? &CUDA_STANDARDS[0]
-    : nullptr;
-  /* clang-format on */
-
-  if (needCudaLevel) {
-    // Ensure the CUDA language level is high enough to support
-    // the needed CUDA features.
-    if (!existingCudaLevel || existingCudaLevel < needCudaLevel) {
-      target->SetProperty("CUDA_STANDARD", *needCudaLevel);
-    }
-  }
-
-  return true;
-}
-
-void cmMakefile::CheckNeededCLanguage(const std::string& feature,
-                                      std::string const& lang, bool& needC90,
-                                      bool& needC99, bool& needC11) const
-{
-  if (const char* propC90 =
-        this->GetDefinition(cmStrCat("CMAKE_", lang, "90_COMPILE_FEATURES"))) {
-    std::vector<std::string> props = cmExpandedList(propC90);
-    needC90 = cmContains(props, feature);
-  }
-  if (const char* propC99 =
-        this->GetDefinition(cmStrCat("CMAKE_", lang, "99_COMPILE_FEATURES"))) {
-    std::vector<std::string> props = cmExpandedList(propC99);
-    needC99 = cmContains(props, feature);
-  }
-  if (const char* propC11 =
-        this->GetDefinition(cmStrCat("CMAKE_", lang, "11_COMPILE_FEATURES"))) {
-    std::vector<std::string> props = cmExpandedList(propC11);
-    needC11 = cmContains(props, feature);
-  }
-}
-
-bool cmMakefile::AddRequiredTargetCFeature(cmTarget* target,
-                                           const std::string& feature,
-                                           std::string const& lang,
-                                           std::string* error) const
-{
-  bool needC90 = false;
-  bool needC99 = false;
-  bool needC11 = false;
-
-  this->CheckNeededCLanguage(feature, lang, needC90, needC99, needC11);
-
-  const char* existingCStandard =
-    target->GetProperty(cmStrCat(lang, "_STANDARD"));
-  if (existingCStandard == nullptr) {
-    const char* defaultCStandard =
-      this->GetDefinition(cmStrCat("CMAKE_", lang, "_STANDARD_DEFAULT"));
-    if (defaultCStandard && *defaultCStandard) {
-      existingCStandard = defaultCStandard;
-    }
-  }
-  if (existingCStandard) {
-    if (std::find_if(cm::cbegin(C_STANDARDS), cm::cend(C_STANDARDS),
-                     cmStrCmp(existingCStandard)) == cm::cend(C_STANDARDS)) {
-      const std::string e = cmStrCat(
-        "The ", lang, "_STANDARD property on target \"", target->GetName(),
-        "\" contained an invalid value: \"", existingCStandard, "\".");
-      if (error) {
-        *error = e;
-      } else {
-        this->GetCMakeInstance()->IssueMessage(MessageType::FATAL_ERROR, e,
-                                               this->Backtrace);
-      }
-      return false;
-    }
-  }
-  const char* const* existingCIt = existingCStandard
-    ? std::find_if(cm::cbegin(C_STANDARDS), cm::cend(C_STANDARDS),
-                   cmStrCmp(existingCStandard))
-    : cm::cend(C_STANDARDS);
-
-  bool setC90 = needC90 && !existingCStandard;
-  bool setC99 = needC99 && !existingCStandard;
-  bool setC11 = needC11 && !existingCStandard;
-
-  if (needC11 && existingCStandard &&
-      existingCIt < std::find_if(cm::cbegin(C_STANDARDS),
-                                 cm::cend(C_STANDARDS), cmStrCmp("11"))) {
-    setC11 = true;
-  } else if (needC99 && existingCStandard &&
-             existingCIt < std::find_if(cm::cbegin(C_STANDARDS),
-                                        cm::cend(C_STANDARDS),
-                                        cmStrCmp("99"))) {
-    setC99 = true;
-  } else if (needC90 && existingCStandard &&
-             existingCIt < std::find_if(cm::cbegin(C_STANDARDS),
-                                        cm::cend(C_STANDARDS),
-                                        cmStrCmp("90"))) {
-    setC90 = true;
-  }
-
-  if (setC11) {
-    target->SetProperty(cmStrCat(lang, "_STANDARD"), "11");
-  } else if (setC99) {
-    target->SetProperty(cmStrCat(lang, "_STANDARD"), "99");
-  } else if (setC90) {
-    target->SetProperty(cmStrCat(lang, "_STANDARD"), "90");
-  }
-  return true;
-}
-
 cmMakefile::FunctionPushPop::FunctionPushPop(cmMakefile* mf,
                                              const std::string& fileName,
                                              cmPolicies::PolicyMap const& pm)
diff --git a/Source/cmMakefile.h b/Source/cmMakefile.h
index d918abe..80d80d3 100644
--- a/Source/cmMakefile.h
+++ b/Source/cmMakefile.h
@@ -26,6 +26,7 @@
 #include "cmMessageType.h"
 #include "cmNewLineStyle.h"
 #include "cmPolicies.h"
+#include "cmProperty.h"
 #include "cmSourceFileLocationKind.h"
 #include "cmStateSnapshot.h"
 #include "cmStateTypes.h"
@@ -117,6 +118,9 @@
 
   bool ReadListFile(const std::string& filename);
 
+  bool ReadListFileAsString(const std::string& content,
+                            const std::string& virtualFileName);
+
   bool ReadDependentFile(const std::string& filename,
                          bool noPolicyScope = true);
 
@@ -183,7 +187,8 @@
     const cmCustomCommandLines& commandLines, cmCustomCommandType type,
     const char* comment, const char* workingDir, bool escapeOldStyle = true,
     bool uses_terminal = false, const std::string& depfile = "",
-    const std::string& job_pool = "", bool command_expand_lists = false);
+    const std::string& job_pool = "", bool command_expand_lists = false,
+    bool stdPipesUTF8 = false);
 
   /**
    * Called for each file with custom command.
@@ -200,7 +205,8 @@
     const char* workingDir, const CommandSourceCallback& callback = nullptr,
     bool replace = false, bool escapeOldStyle = true,
     bool uses_terminal = false, bool command_expand_lists = false,
-    const std::string& depfile = "", const std::string& job_pool = "");
+    const std::string& depfile = "", const std::string& job_pool = "",
+    bool stdPipesUTF8 = false);
   void AddCustomCommandToOutput(
     const std::vector<std::string>& outputs,
     const std::vector<std::string>& byproducts,
@@ -211,7 +217,8 @@
     const char* workingDir, const CommandSourceCallback& callback = nullptr,
     bool replace = false, bool escapeOldStyle = true,
     bool uses_terminal = false, bool command_expand_lists = false,
-    const std::string& depfile = "", const std::string& job_pool = "");
+    const std::string& depfile = "", const std::string& job_pool = "",
+    bool stdPipesUTF8 = false);
   void AddCustomCommandOldStyle(const std::string& target,
                                 const std::vector<std::string>& outputs,
                                 const std::vector<std::string>& depends,
@@ -279,7 +286,8 @@
     const std::vector<std::string>& depends,
     const cmCustomCommandLines& commandLines, bool escapeOldStyle = true,
     const char* comment = nullptr, bool uses_terminal = false,
-    bool command_expand_lists = false, const std::string& job_pool = "");
+    bool command_expand_lists = false, const std::string& job_pool = "",
+    bool stdPipesUTF8 = false);
 
   /**
    * Add a subdirectory to the build.
@@ -314,6 +322,12 @@
   void AddCacheDefinition(const std::string& name, const char* value,
                           const char* doc, cmStateEnums::CacheEntryType type,
                           bool force = false);
+  void AddCacheDefinition(const std::string& name, const std::string& value,
+                          const char* doc, cmStateEnums::CacheEntryType type,
+                          bool force = false)
+  {
+    AddCacheDefinition(name, value.c_str(), doc, type, force);
+  }
 
   /**
    * Remove a variable definition from the build.  This is not valid
@@ -328,12 +342,19 @@
    */
   void SetProjectName(std::string const& name);
 
-  /** Get the configurations to be generated.  */
-  std::string GetConfigurations(std::vector<std::string>& configs,
-                                bool single = true) const;
+  /* Get the default configuration */
+  std::string GetDefaultConfiguration() const;
+
+  enum GeneratorConfigQuery
+  {
+    IncludeEmptyConfig, // Include "" aka noconfig
+    ExcludeEmptyConfig, // Exclude "" aka noconfig
+    OnlyMultiConfig,
+  };
 
   /** Get the configurations for dependency checking.  */
-  std::vector<std::string> GetGeneratorConfigs() const;
+  std::vector<std::string> GetGeneratorConfigs(
+    GeneratorConfigQuery mode) const;
 
   /**
    * Set the name of the library.
@@ -342,7 +363,8 @@
                        cmStateEnums::TargetType type,
                        const std::vector<std::string>& srcs,
                        bool excludeFromAll = false);
-  void AddAlias(const std::string& libname, const std::string& tgt);
+  void AddAlias(const std::string& libname, const std::string& tgt,
+                bool globallyVisible = true);
 
   //@{
   /**
@@ -408,7 +430,8 @@
   }
   const char* GetIncludeRegularExpression() const
   {
-    return this->GetProperty("INCLUDE_REGULAR_EXPRESSION");
+    cmProp p = this->GetProperty("INCLUDE_REGULAR_EXPRESSION");
+    return p ? p->c_str() : nullptr;
   }
 
   /**
@@ -497,6 +520,8 @@
   const std::string& GetSafeDefinition(const std::string&) const;
   const std::string& GetRequiredDefinition(const std::string& name) const;
   bool IsDefinitionSet(const std::string&) const;
+  bool GetDefExpandList(const std::string& name, std::vector<std::string>& out,
+                        bool emptyArgs = false) const;
   /**
    * Get the list of all variables in the current space. If argument
    * cacheonly is specified and is greater than 0, then only cache
@@ -668,6 +693,7 @@
    */
   int ConfigureFile(const std::string& infile, const std::string& outfile,
                     bool copyonly, bool atOnly, bool escapeQuotes,
+                    bool use_source_permissions,
                     cmNewLineStyle = cmNewLineStyle());
 
   /**
@@ -786,8 +812,8 @@
   void SetProperty(const std::string& prop, const char* value);
   void AppendProperty(const std::string& prop, const std::string& value,
                       bool asString = false);
-  const char* GetProperty(const std::string& prop) const;
-  const char* GetProperty(const std::string& prop, bool chain) const;
+  cmProp GetProperty(const std::string& prop) const;
+  cmProp GetProperty(const std::string& prop, bool chain) const;
   bool GetPropertyAsBool(const std::string& prop) const;
   std::vector<std::string> GetPropertyKeys() const;
 
@@ -907,21 +933,6 @@
 
   bool PolicyOptionalWarningEnabled(std::string const& var);
 
-  bool AddRequiredTargetFeature(cmTarget* target, const std::string& feature,
-                                std::string* error = nullptr) const;
-
-  bool CompileFeatureKnown(cmTarget const* target, const std::string& feature,
-                           std::string& lang, std::string* error) const;
-
-  const char* CompileFeaturesAvailable(const std::string& lang,
-                                       std::string* error) const;
-
-  bool HaveStandardAvailable(cmTarget const* target, std::string const& lang,
-                             const std::string& feature) const;
-
-  bool IsLaterStandard(std::string const& lang, std::string const& lhs,
-                       std::string const& rhs);
-
   void PushLoopBlock();
   void PopLoopBlock();
   bool IsLoopBlock() const;
@@ -967,9 +978,6 @@
   // add link libraries and directories to the target
   void AddGlobalLinkInformation(cmTarget& target);
 
-  // Check for a an unused variable
-  void LogUnused(const char* reason, const std::string& name) const;
-
   mutable std::set<cmListFileContext> CMP0054ReportedIds;
 
   // libraries, classes, and executables
@@ -1144,44 +1152,6 @@
    */
   bool MightHaveCustomCommand(const std::string& name) const;
 
-  bool AddRequiredTargetCFeature(cmTarget* target, const std::string& feature,
-                                 std::string const& lang,
-                                 std::string* error = nullptr) const;
-  bool AddRequiredTargetCxxFeature(cmTarget* target,
-                                   const std::string& feature,
-                                   std::string const& lang,
-                                   std::string* error = nullptr) const;
-  bool AddRequiredTargetCudaFeature(cmTarget* target,
-                                    const std::string& feature,
-                                    std::string const& lang,
-                                    std::string* error = nullptr) const;
-
-  void CheckNeededCLanguage(const std::string& feature,
-                            std::string const& lang, bool& needC90,
-                            bool& needC99, bool& needC11) const;
-  void CheckNeededCxxLanguage(const std::string& feature,
-                              std::string const& lang, bool& needCxx98,
-                              bool& needCxx11, bool& needCxx14,
-                              bool& needCxx17, bool& needCxx20) const;
-  void CheckNeededCudaLanguage(const std::string& feature,
-                               std::string const& lang, bool& needCuda03,
-                               bool& needCuda11, bool& needCuda14,
-                               bool& needCuda17, bool& needCuda20) const;
-
-  bool HaveCStandardAvailable(cmTarget const* target,
-                              const std::string& feature,
-                              std::string const& lang) const;
-  bool HaveCxxStandardAvailable(cmTarget const* target,
-                                const std::string& feature,
-                                std::string const& lang) const;
-  bool HaveCudaStandardAvailable(cmTarget const* target,
-                                 const std::string& feature,
-                                 std::string const& lang) const;
-
-  void CheckForUnusedVariables() const;
-
-  // Unused variable flags
-  bool WarnUnused;
   bool CheckSystemVars;
   bool CheckCMP0000;
   std::set<std::string> WarnedCMP0074;
diff --git a/Source/cmMakefileExecutableTargetGenerator.cxx b/Source/cmMakefileExecutableTargetGenerator.cxx
index 0471a45..bc288ac 100644
--- a/Source/cmMakefileExecutableTargetGenerator.cxx
+++ b/Source/cmMakefileExecutableTargetGenerator.cxx
@@ -122,31 +122,15 @@
   }
 
   // Build a list of compiler flags and linker flags.
-  std::string flags;
+  std::string langFlags;
   std::string linkFlags;
 
-  // Add flags to create an executable.
-  // Add symbol export flags if necessary.
-  if (this->GeneratorTarget->IsExecutableWithExports()) {
-    std::string export_flag_var =
-      cmStrCat("CMAKE_EXE_EXPORTS_", linkLanguage, "_FLAG");
-    this->LocalGenerator->AppendFlags(
-      linkFlags, this->Makefile->GetSafeDefinition(export_flag_var));
-  }
-
-  this->LocalGenerator->AppendFlags(linkFlags,
-                                    this->LocalGenerator->GetLinkLibsCMP0065(
-                                      linkLanguage, *this->GeneratorTarget));
-
   // Add language feature flags.
   this->LocalGenerator->AddLanguageFlagsForLinking(
-    flags, this->GeneratorTarget, linkLanguage, this->GetConfigName());
+    langFlags, this->GeneratorTarget, linkLanguage, this->GetConfigName());
 
-  this->LocalGenerator->AddArchitectureFlags(
-    flags, this->GeneratorTarget, linkLanguage, this->GetConfigName());
-
-  // Add target-specific linker flags.
-  this->GetTargetLinkFlags(linkFlags, linkLanguage);
+  // Add device-specific linker flags.
+  this->GetDeviceLinkFlags(linkFlags, linkLanguage);
 
   // Construct a list of files associated with this executable that
   // may need to be cleaned.
@@ -226,7 +210,7 @@
     vars.ObjectDir = objectDir.c_str();
     vars.Target = target.c_str();
     vars.LinkLibraries = linkLibs.c_str();
-    vars.Flags = flags.c_str();
+    vars.LanguageCompileFlags = langFlags.c_str();
     vars.LinkFlags = linkFlags.c_str();
     vars.TargetCompilePDB = targetOutPathCompilePDB.c_str();
 
@@ -234,7 +218,7 @@
 
     const char* val = this->LocalGenerator->GetRuleLauncher(
       this->GeneratorTarget, "RULE_LAUNCH_LINK");
-    if (val && *val) {
+    if (cmNonempty(val)) {
       launcher = cmStrCat(val, ' ');
     }
 
@@ -494,9 +478,7 @@
     // add it now.
     std::string implibRuleVar =
       cmStrCat("CMAKE_", linkLanguage, "_CREATE_IMPORT_LIBRARY");
-    if (const char* rule = this->Makefile->GetDefinition(implibRuleVar)) {
-      cmExpandList(rule, real_link_commands);
-    }
+    this->Makefile->GetDefExpandList(implibRuleVar, real_link_commands);
   }
 
   bool useResponseFileForObjects =
@@ -547,7 +529,7 @@
     cmRulePlaceholderExpander::RuleVariables vars;
     vars.CMTargetName = this->GeneratorTarget->GetName().c_str();
     vars.CMTargetType =
-      cmState::GetTargetTypeName(this->GeneratorTarget->GetType());
+      cmState::GetTargetTypeName(this->GeneratorTarget->GetType()).c_str();
     vars.Language = linkLanguage.c_str();
     vars.Objects = buildObjs.c_str();
     std::string objectDir = this->GeneratorTarget->GetSupportDirectory();
@@ -601,7 +583,7 @@
 
     const char* val = this->LocalGenerator->GetRuleLauncher(
       this->GeneratorTarget, "RULE_LAUNCH_LINK");
-    if (val && *val) {
+    if (cmNonempty(val)) {
       launcher = cmStrCat(val, ' ');
     }
 
diff --git a/Source/cmMakefileLibraryTargetGenerator.cxx b/Source/cmMakefileLibraryTargetGenerator.cxx
index d3f3a4f..1c25fc4 100644
--- a/Source/cmMakefileLibraryTargetGenerator.cxx
+++ b/Source/cmMakefileLibraryTargetGenerator.cxx
@@ -141,8 +141,7 @@
 
   std::string extraFlags;
   this->LocalGenerator->GetStaticLibraryFlags(
-    extraFlags, cmSystemTools::UpperCase(this->GetConfigName()), linkLanguage,
-    this->GeneratorTarget);
+    extraFlags, this->GetConfigName(), linkLanguage, this->GeneratorTarget);
   this->WriteLibraryRules(linkRuleVar, extraFlags, false);
 }
 
@@ -250,9 +249,14 @@
   std::vector<std::string> depends;
   this->AppendLinkDepends(depends, linkLanguage);
 
+  // Add language-specific flags.
+  std::string langFlags;
+  this->LocalGenerator->AddLanguageFlagsForLinking(
+    langFlags, this->GeneratorTarget, linkLanguage, this->GetConfigName());
+
   // Create set of linking flags.
   std::string linkFlags;
-  this->GetTargetLinkFlags(linkFlags, linkLanguage);
+  this->GetDeviceLinkFlags(linkFlags, linkLanguage);
 
   // Get the name of the device object to generate.
   std::string const targetOutputReal =
@@ -345,20 +349,14 @@
     vars.Target = target.c_str();
     vars.LinkLibraries = linkLibs.c_str();
     vars.ObjectsQuoted = buildObjs.c_str();
+    vars.LanguageCompileFlags = langFlags.c_str();
     vars.LinkFlags = linkFlags.c_str();
     vars.TargetCompilePDB = targetOutPathCompilePDB.c_str();
 
-    // Add language-specific flags.
-    std::string langFlags;
-    this->LocalGenerator->AddLanguageFlagsForLinking(
-      langFlags, this->GeneratorTarget, linkLanguage, this->GetConfigName());
-
-    vars.LanguageCompileFlags = langFlags.c_str();
-
     std::string launcher;
     const char* val = this->LocalGenerator->GetRuleLauncher(
       this->GeneratorTarget, "RULE_LAUNCH_LINK");
-    if (val && *val) {
+    if (cmNonempty(val)) {
       launcher = cmStrCat(val, ' ');
     }
 
@@ -644,27 +642,21 @@
     arCreateVar = this->GeneratorTarget->GetFeatureSpecificLinkRuleVariable(
       arCreateVar, linkLanguage, this->GetConfigName());
 
-    if (const char* rule = this->Makefile->GetDefinition(arCreateVar)) {
-      cmExpandList(rule, archiveCreateCommands);
-    }
+    this->Makefile->GetDefExpandList(arCreateVar, archiveCreateCommands);
     std::string arAppendVar =
       cmStrCat("CMAKE_", linkLanguage, "_ARCHIVE_APPEND");
 
     arAppendVar = this->GeneratorTarget->GetFeatureSpecificLinkRuleVariable(
       arAppendVar, linkLanguage, this->GetConfigName());
 
-    if (const char* rule = this->Makefile->GetDefinition(arAppendVar)) {
-      cmExpandList(rule, archiveAppendCommands);
-    }
+    this->Makefile->GetDefExpandList(arAppendVar, archiveAppendCommands);
     std::string arFinishVar =
       cmStrCat("CMAKE_", linkLanguage, "_ARCHIVE_FINISH");
 
     arFinishVar = this->GeneratorTarget->GetFeatureSpecificLinkRuleVariable(
       arFinishVar, linkLanguage, this->GetConfigName());
 
-    if (const char* rule = this->Makefile->GetDefinition(arFinishVar)) {
-      cmExpandList(rule, archiveFinishCommands);
-    }
+    this->Makefile->GetDefExpandList(arFinishVar, archiveFinishCommands);
   }
 
   // Decide whether to use archiving rules.
@@ -756,7 +748,7 @@
 
     vars.CMTargetName = this->GeneratorTarget->GetName().c_str();
     vars.CMTargetType =
-      cmState::GetTargetTypeName(this->GeneratorTarget->GetType());
+      cmState::GetTargetTypeName(this->GeneratorTarget->GetType()).c_str();
     vars.Language = linkLanguage.c_str();
     vars.AIXExports = aixExports.c_str();
     vars.Objects = buildObjs.c_str();
@@ -817,7 +809,7 @@
     std::string launcher;
     const char* val = this->LocalGenerator->GetRuleLauncher(
       this->GeneratorTarget, "RULE_LAUNCH_LINK");
-    if (val && *val) {
+    if (cmNonempty(val)) {
       launcher = cmStrCat(val, ' ');
     }
 
diff --git a/Source/cmMakefileProfilingData.cxx b/Source/cmMakefileProfilingData.cxx
new file mode 100644
index 0000000..29fd440
--- /dev/null
+++ b/Source/cmMakefileProfilingData.cxx
@@ -0,0 +1,114 @@
+/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
+   file Copyright.txt or https://cmake.org/licensing for details.  */
+#include "cmMakefileProfilingData.h"
+
+#include <chrono>
+#include <stdexcept>
+#include <vector>
+
+#include <cm3p/json/value.h>
+#include <cm3p/json/writer.h>
+
+#include "cmsys/FStream.hxx"
+#include "cmsys/SystemInformation.hxx"
+
+#include "cmListFileCache.h"
+#include "cmStringAlgorithms.h"
+#include "cmSystemTools.h"
+
+cmMakefileProfilingData::cmMakefileProfilingData(
+  const std::string& profileStream)
+{
+  std::ios::openmode omode = std::ios::out | std::ios::trunc;
+  this->ProfileStream.open(profileStream.c_str(), omode);
+  Json::StreamWriterBuilder wbuilder;
+  this->JsonWriter =
+    std::unique_ptr<Json::StreamWriter>(wbuilder.newStreamWriter());
+  if (!this->ProfileStream.good()) {
+    throw std::runtime_error(std::string("Unable to open: ") + profileStream);
+  }
+
+  this->ProfileStream << "[";
+};
+
+cmMakefileProfilingData::~cmMakefileProfilingData() noexcept
+{
+  if (this->ProfileStream.good()) {
+    try {
+      this->ProfileStream << "]";
+      this->ProfileStream.close();
+    } catch (...) {
+      cmSystemTools::Error("Error writing profiling output!");
+    }
+  }
+}
+
+void cmMakefileProfilingData::StartEntry(const cmListFileFunction& lff,
+                                         cmListFileContext const& lfc)
+{
+  /* Do not try again if we previously failed to write to output. */
+  if (!this->ProfileStream.good()) {
+    return;
+  }
+
+  try {
+    if (this->ProfileStream.tellp() > 1) {
+      this->ProfileStream << ",";
+    }
+    cmsys::SystemInformation info;
+    Json::Value v;
+    v["ph"] = "B";
+    v["name"] = lff.Name.Lower;
+    v["cat"] = "cmake";
+    v["ts"] = Json::Value::UInt64(
+      std::chrono::duration_cast<std::chrono::microseconds>(
+        std::chrono::steady_clock::now().time_since_epoch())
+        .count());
+    v["pid"] = static_cast<int>(info.GetProcessId());
+    v["tid"] = 0;
+    Json::Value argsValue;
+    if (!lff.Arguments.empty()) {
+      std::string args;
+      for (const auto& a : lff.Arguments) {
+        args += (args.empty() ? "" : " ") + a.Value;
+      }
+      argsValue["functionArgs"] = args;
+    }
+    argsValue["location"] = lfc.FilePath + ":" + std::to_string(lfc.Line);
+    v["args"] = argsValue;
+
+    this->JsonWriter->write(v, &this->ProfileStream);
+  } catch (std::ios_base::failure& fail) {
+    cmSystemTools::Error(
+      cmStrCat("Failed to write to profiling output: ", fail.what()));
+  } catch (...) {
+    cmSystemTools::Error("Error writing profiling output!");
+  }
+}
+
+void cmMakefileProfilingData::StopEntry()
+{
+  /* Do not try again if we previously failed to write to output. */
+  if (!this->ProfileStream.good()) {
+    return;
+  }
+
+  try {
+    this->ProfileStream << ",";
+    cmsys::SystemInformation info;
+    Json::Value v;
+    v["ph"] = "E";
+    v["ts"] = Json::Value::UInt64(
+      std::chrono::duration_cast<std::chrono::microseconds>(
+        std::chrono::steady_clock::now().time_since_epoch())
+        .count());
+    v["pid"] = static_cast<int>(info.GetProcessId());
+    v["tid"] = 0;
+    this->JsonWriter->write(v, &this->ProfileStream);
+  } catch (std::ios_base::failure& fail) {
+    cmSystemTools::Error(
+      cmStrCat("Failed to write to profiling output:", fail.what()));
+  } catch (...) {
+    cmSystemTools::Error("Error writing profiling output!");
+  }
+}
diff --git a/Source/cmMakefileProfilingData.h b/Source/cmMakefileProfilingData.h
new file mode 100644
index 0000000..1babd97
--- /dev/null
+++ b/Source/cmMakefileProfilingData.h
@@ -0,0 +1,29 @@
+/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
+   file Copyright.txt or https://cmake.org/licensing for details.  */
+#ifndef cmMakefileProfilingData_h
+#define cmMakefileProfilingData_h
+#include <memory>
+#include <string>
+
+#include "cmsys/FStream.hxx"
+
+namespace Json {
+class StreamWriter;
+}
+
+class cmListFileContext;
+struct cmListFileFunction;
+
+class cmMakefileProfilingData
+{
+public:
+  cmMakefileProfilingData(const std::string&);
+  ~cmMakefileProfilingData() noexcept;
+  void StartEntry(const cmListFileFunction& lff, cmListFileContext const& lfc);
+  void StopEntry();
+
+private:
+  cmsys::ofstream ProfileStream;
+  std::unique_ptr<Json::StreamWriter> JsonWriter;
+};
+#endif
diff --git a/Source/cmMakefileTargetGenerator.cxx b/Source/cmMakefileTargetGenerator.cxx
index a8769d8..fae1d76 100644
--- a/Source/cmMakefileTargetGenerator.cxx
+++ b/Source/cmMakefileTargetGenerator.cxx
@@ -5,6 +5,7 @@
 #include <cassert>
 #include <cstdio>
 #include <sstream>
+#include <unordered_map>
 #include <utility>
 
 #include <cm/memory>
@@ -17,7 +18,7 @@
 #include "cmGeneratorExpression.h"
 #include "cmGeneratorTarget.h"
 #include "cmGlobalUnixMakefileGenerator3.h"
-#include "cmLinkLineComputer.h"
+#include "cmLinkLineComputer.h" // IWYU pragma: keep
 #include "cmLocalCommonGenerator.h"
 #include "cmLocalUnixMakefileGenerator3.h"
 #include "cmMakefile.h"
@@ -25,6 +26,7 @@
 #include "cmMakefileLibraryTargetGenerator.h"
 #include "cmMakefileUtilityTargetGenerator.h"
 #include "cmOutputConverter.h"
+#include "cmProperty.h"
 #include "cmRange.h"
 #include "cmRulePlaceholderExpander.h"
 #include "cmSourceFile.h"
@@ -46,9 +48,8 @@
     this->LocalGenerator->GetGlobalGenerator());
   cmake* cm = this->GlobalGenerator->GetCMakeInstance();
   this->NoRuleMessages = false;
-  if (const char* ruleStatus =
-        cm->GetState()->GetGlobalProperty("RULE_MESSAGES")) {
-    this->NoRuleMessages = cmIsOff(ruleStatus);
+  if (cmProp ruleStatus = cm->GetState()->GetGlobalProperty("RULE_MESSAGES")) {
+    this->NoRuleMessages = cmIsOff(*ruleStatus);
   }
   MacOSXContentGenerator = cm::make_unique<MacOSXContentGeneratorType>(this);
 }
@@ -70,6 +71,7 @@
     case cmStateEnums::OBJECT_LIBRARY:
       result = cm::make_unique<cmMakefileLibraryTargetGenerator>(tgt);
       break;
+    case cmStateEnums::INTERFACE_LIBRARY:
     case cmStateEnums::UTILITY:
       result = cm::make_unique<cmMakefileUtilityTargetGenerator>(tgt);
       break;
@@ -87,6 +89,18 @@
   return configNames.front();
 }
 
+void cmMakefileTargetGenerator::GetDeviceLinkFlags(
+  std::string& linkFlags, const std::string& linkLanguage)
+{
+  cmGeneratorTarget::DeviceLinkSetter setter(*this->GetGeneratorTarget());
+
+  std::vector<std::string> linkOpts;
+  this->GeneratorTarget->GetLinkOptions(linkOpts, this->GetConfigName(),
+                                        linkLanguage);
+  // LINK_OPTIONS are escaped.
+  this->LocalGenerator->AppendCompileOptions(linkFlags, linkOpts);
+}
+
 void cmMakefileTargetGenerator::GetTargetLinkFlags(
   std::string& flags, const std::string& linkLanguage)
 {
@@ -155,7 +169,7 @@
 
   // Evaluates generator expressions and expands prop_value
   auto evaluatedFiles =
-    [this](const char* prop_value) -> std::vector<std::string> {
+    [this](const std::string& prop_value) -> std::vector<std::string> {
     std::vector<std::string> files;
     cmExpandList(cmGeneratorExpression::Evaluate(
                    prop_value, this->LocalGenerator, this->GetConfigName(),
@@ -165,16 +179,16 @@
   };
 
   // Look for additional files registered for cleaning in this directory.
-  if (const char* prop_value =
+  if (cmProp prop_value =
         this->Makefile->GetProperty("ADDITIONAL_MAKE_CLEAN_FILES")) {
-    std::vector<std::string> const files = evaluatedFiles(prop_value);
+    std::vector<std::string> const files = evaluatedFiles(*prop_value);
     this->CleanFiles.insert(files.begin(), files.end());
   }
 
   // Look for additional files registered for cleaning in this target.
-  if (const char* prop_value =
+  if (cmProp prop_value =
         this->GeneratorTarget->GetProperty("ADDITIONAL_CLEAN_FILES")) {
-    std::vector<std::string> const files = evaluatedFiles(prop_value);
+    std::vector<std::string> const files = evaluatedFiles(*prop_value);
     // For relative path support
     std::string const& binaryDir =
       this->LocalGenerator->GetCurrentBinaryDirectory();
@@ -184,8 +198,7 @@
   }
 
   // add custom commands to the clean rules?
-  const char* clean_no_custom = this->Makefile->GetProperty("CLEAN_NO_CUSTOM");
-  bool clean = cmIsOff(clean_no_custom);
+  bool clean = cmIsOff(this->Makefile->GetProperty("CLEAN_NO_CUSTOM"));
 
   // First generate the object rule files.  Save a list of all object
   // files for this target.
@@ -300,8 +313,7 @@
       dependFileNameFull, false, this->GlobalGenerator->GetMakefileEncoding());
     depFileStream << "# Empty dependencies file for "
                   << this->GeneratorTarget->GetName() << ".\n"
-                  << "# This may be replaced when dependencies are built."
-                  << std::endl;
+                  << "# This may be replaced when dependencies are built.\n";
   }
 
   // Open the flags file.  This should be copy-if-different because the
@@ -342,17 +354,32 @@
                           << "\n";
   }
 
+  bool const escapeOctothorpe = this->GlobalGenerator->CanEscapeOctothorpe();
+
   for (std::string const& language : languages) {
-    std::string flags = this->GetFlags(language, this->GetConfigName());
     std::string defines = this->GetDefines(language, this->GetConfigName());
     std::string includes = this->GetIncludes(language, this->GetConfigName());
-    // Escape comment characters so they do not terminate assignment.
-    cmSystemTools::ReplaceString(flags, "#", "\\#");
-    cmSystemTools::ReplaceString(defines, "#", "\\#");
-    cmSystemTools::ReplaceString(includes, "#", "\\#");
-    *this->FlagFileStream << language << "_FLAGS = " << flags << "\n\n";
+    if (escapeOctothorpe) {
+      // Escape comment characters so they do not terminate assignment.
+      cmSystemTools::ReplaceString(defines, "#", "\\#");
+      cmSystemTools::ReplaceString(includes, "#", "\\#");
+    }
     *this->FlagFileStream << language << "_DEFINES = " << defines << "\n\n";
     *this->FlagFileStream << language << "_INCLUDES = " << includes << "\n\n";
+
+    std::vector<std::string> architectures;
+    this->GeneratorTarget->GetAppleArchs(this->GetConfigName(), architectures);
+    architectures.emplace_back();
+
+    for (const std::string& arch : architectures) {
+      std::string flags =
+        this->GetFlags(language, this->GetConfigName(), arch);
+      if (escapeOctothorpe) {
+        cmSystemTools::ReplaceString(flags, "#", "\\#");
+      }
+      *this->FlagFileStream << language << "_FLAGS" << arch << " = " << flags
+                            << "\n\n";
+    }
   }
 }
 
@@ -465,17 +492,37 @@
   std::string configUpper = cmSystemTools::UpperCase(config);
 
   // Add precompile headers dependencies
-  const std::string pchSource =
-    this->GeneratorTarget->GetPchSource(config, lang);
-  if (!pchSource.empty() && !source.GetProperty("SKIP_PRECOMPILE_HEADERS")) {
-    std::string const& pchHeader =
-      this->GeneratorTarget->GetPchHeader(config, lang);
-    depends.push_back(pchHeader);
-    if (source.GetFullPath() != pchSource) {
-      depends.push_back(this->GeneratorTarget->GetPchFile(config, lang));
+  std::vector<std::string> architectures;
+  this->GeneratorTarget->GetAppleArchs(config, architectures);
+  if (architectures.empty()) {
+    architectures.emplace_back();
+  }
+
+  std::string filterArch;
+  std::unordered_map<std::string, std::string> pchSources;
+  for (const std::string& arch : architectures) {
+    const std::string pchSource =
+      this->GeneratorTarget->GetPchSource(config, lang, arch);
+    if (pchSource == source.GetFullPath()) {
+      filterArch = arch;
     }
-    this->LocalGenerator->AddImplicitDepends(this->GeneratorTarget, lang,
-                                             objFullPath, pchHeader);
+    if (!pchSource.empty()) {
+      pchSources.insert(std::make_pair(pchSource, arch));
+    }
+  }
+
+  if (!pchSources.empty() && !source.GetProperty("SKIP_PRECOMPILE_HEADERS")) {
+    for (const std::string& arch : architectures) {
+      std::string const& pchHeader =
+        this->GeneratorTarget->GetPchHeader(config, lang, arch);
+      depends.push_back(pchHeader);
+      if (pchSources.find(source.GetFullPath()) == pchSources.end()) {
+        depends.push_back(
+          this->GeneratorTarget->GetPchFile(config, lang, arch));
+      }
+      this->LocalGenerator->AddImplicitDepends(this->GeneratorTarget, lang,
+                                               objFullPath, pchHeader);
+    }
   }
 
   std::string relativeObj =
@@ -485,8 +532,15 @@
   // Build the set of compiler flags.
   std::string flags;
 
+  // explicitly add the explicit language flag before any other flag
+  // this way backwards compatibility with user flags is maintained
+  if (source.GetProperty("LANGUAGE")) {
+    this->LocalGenerator->AppendFeatureOptions(flags, lang,
+                                               "EXPLICIT_LANGUAGE");
+  }
+
   // Add language-specific flags.
-  std::string langFlags = cmStrCat("$(", lang, "_FLAGS)");
+  std::string langFlags = cmStrCat("$(", lang, "_FLAGS", filterArch, ")");
   this->LocalGenerator->AppendFlags(flags, langFlags);
 
   cmGeneratorExpressionInterpreter genexInterpreter(
@@ -495,13 +549,14 @@
   // Add Fortran format flags.
   if (lang == "Fortran") {
     this->AppendFortranFormatFlags(flags, source);
+    this->AppendFortranPreprocessFlags(flags, source);
   }
 
   // Add flags from source file properties.
   const std::string COMPILE_FLAGS("COMPILE_FLAGS");
-  if (const char* cflags = source.GetProperty(COMPILE_FLAGS)) {
+  if (cmProp cflags = source.GetProperty(COMPILE_FLAGS)) {
     const std::string& evaluatedFlags =
-      genexInterpreter.Evaluate(cflags, COMPILE_FLAGS);
+      genexInterpreter.Evaluate(*cflags, COMPILE_FLAGS);
     this->LocalGenerator->AppendFlags(flags, evaluatedFlags);
     *this->FlagFileStream << "# Custom flags: " << relativeObj
                           << "_FLAGS = " << evaluatedFlags << "\n"
@@ -509,9 +564,9 @@
   }
 
   const std::string COMPILE_OPTIONS("COMPILE_OPTIONS");
-  if (const char* coptions = source.GetProperty(COMPILE_OPTIONS)) {
+  if (cmProp coptions = source.GetProperty(COMPILE_OPTIONS)) {
     const std::string& evaluatedOptions =
-      genexInterpreter.Evaluate(coptions, COMPILE_OPTIONS);
+      genexInterpreter.Evaluate(*coptions, COMPILE_OPTIONS);
     this->LocalGenerator->AppendCompileOptions(flags, evaluatedOptions);
     *this->FlagFileStream << "# Custom options: " << relativeObj
                           << "_OPTIONS = " << evaluatedOptions << "\n"
@@ -519,11 +574,12 @@
   }
 
   // Add precompile headers compile options.
-  if (!pchSource.empty() && !source.GetProperty("SKIP_PRECOMPILE_HEADERS")) {
+  if (!pchSources.empty() && !source.GetProperty("SKIP_PRECOMPILE_HEADERS")) {
     std::string pchOptions;
-    if (source.GetFullPath() == pchSource) {
-      pchOptions =
-        this->GeneratorTarget->GetPchCreateCompileOptions(config, lang);
+    auto pchIt = pchSources.find(source.GetFullPath());
+    if (pchIt != pchSources.end()) {
+      pchOptions = this->GeneratorTarget->GetPchCreateCompileOptions(
+        config, lang, pchIt->second);
     } else {
       pchOptions =
         this->GeneratorTarget->GetPchUseCompileOptions(config, lang);
@@ -542,9 +598,9 @@
   std::vector<std::string> includes;
 
   const std::string INCLUDE_DIRECTORIES("INCLUDE_DIRECTORIES");
-  if (const char* cincludes = source.GetProperty(INCLUDE_DIRECTORIES)) {
+  if (cmProp cincludes = source.GetProperty(INCLUDE_DIRECTORIES)) {
     const std::string& evaluatedIncludes =
-      genexInterpreter.Evaluate(cincludes, INCLUDE_DIRECTORIES);
+      genexInterpreter.Evaluate(*cincludes, INCLUDE_DIRECTORIES);
     this->LocalGenerator->AppendIncludeDirectories(includes, evaluatedIncludes,
                                                    source);
     *this->FlagFileStream << "# Custom include directories: " << relativeObj
@@ -558,18 +614,18 @@
 
   // Add source-specific preprocessor definitions.
   const std::string COMPILE_DEFINITIONS("COMPILE_DEFINITIONS");
-  if (const char* compile_defs = source.GetProperty(COMPILE_DEFINITIONS)) {
+  if (cmProp compile_defs = source.GetProperty(COMPILE_DEFINITIONS)) {
     const std::string& evaluatedDefs =
-      genexInterpreter.Evaluate(compile_defs, COMPILE_DEFINITIONS);
+      genexInterpreter.Evaluate(*compile_defs, COMPILE_DEFINITIONS);
     this->LocalGenerator->AppendDefines(defines, evaluatedDefs);
     *this->FlagFileStream << "# Custom defines: " << relativeObj
                           << "_DEFINES = " << evaluatedDefs << "\n"
                           << "\n";
   }
   std::string defPropName = cmStrCat("COMPILE_DEFINITIONS_", configUpper);
-  if (const char* config_compile_defs = source.GetProperty(defPropName)) {
+  if (cmProp config_compile_defs = source.GetProperty(defPropName)) {
     const std::string& evaluatedDefs =
-      genexInterpreter.Evaluate(config_compile_defs, COMPILE_DEFINITIONS);
+      genexInterpreter.Evaluate(*config_compile_defs, COMPILE_DEFINITIONS);
     this->LocalGenerator->AppendDefines(defines, evaluatedDefs);
     *this->FlagFileStream << "# Custom defines: " << relativeObj << "_DEFINES_"
                           << configUpper << " = " << evaluatedDefs << "\n"
@@ -639,7 +695,7 @@
   cmRulePlaceholderExpander::RuleVariables vars;
   vars.CMTargetName = this->GeneratorTarget->GetName().c_str();
   vars.CMTargetType =
-    cmState::GetTargetTypeName(this->GeneratorTarget->GetType());
+    cmState::GetTargetTypeName(this->GeneratorTarget->GetType()).c_str();
   vars.Language = lang.c_str();
   vars.Target = targetOutPathReal.c_str();
   vars.TargetPDB = targetOutPathPDB.c_str();
@@ -717,8 +773,8 @@
       // no launcher for CMAKE_EXPORT_COMPILE_COMMANDS
       rulePlaceholderExpander->ExpandRuleVariables(this->LocalGenerator,
                                                    compileCommand, vars);
-      std::string workingDirectory = cmSystemTools::CollapseFullPath(
-        this->LocalGenerator->GetCurrentBinaryDirectory());
+      std::string workingDirectory =
+        this->LocalGenerator->GetCurrentBinaryDirectory();
       compileCommand.replace(compileCommand.find(langFlags), langFlags.size(),
                              this->GetFlags(lang, this->GetConfigName()));
       std::string langDefines = std::string("$(") + lang + "_DEFINES)";
@@ -750,25 +806,24 @@
         (lang == "C" || lang == "CXX" || lang == "Fortran" || lang == "CUDA" ||
          lang == "OBJC" || lang == "OBJCXX")) {
       std::string const clauncher_prop = lang + "_COMPILER_LAUNCHER";
-      const char* clauncher =
-        this->GeneratorTarget->GetProperty(clauncher_prop);
-      if (clauncher && *clauncher) {
-        compilerLauncher = clauncher;
+      cmProp clauncher = this->GeneratorTarget->GetProperty(clauncher_prop);
+      if (cmNonempty(clauncher)) {
+        compilerLauncher = *clauncher;
       }
     }
 
     // Maybe insert an include-what-you-use runner.
     if (!compileCommands.empty() && (lang == "C" || lang == "CXX")) {
       std::string const iwyu_prop = lang + "_INCLUDE_WHAT_YOU_USE";
-      const char* iwyu = this->GeneratorTarget->GetProperty(iwyu_prop);
+      cmProp iwyu = this->GeneratorTarget->GetProperty(iwyu_prop);
       std::string const tidy_prop = lang + "_CLANG_TIDY";
-      const char* tidy = this->GeneratorTarget->GetProperty(tidy_prop);
+      cmProp tidy = this->GeneratorTarget->GetProperty(tidy_prop);
       std::string const cpplint_prop = lang + "_CPPLINT";
-      const char* cpplint = this->GeneratorTarget->GetProperty(cpplint_prop);
+      cmProp cpplint = this->GeneratorTarget->GetProperty(cpplint_prop);
       std::string const cppcheck_prop = lang + "_CPPCHECK";
-      const char* cppcheck = this->GeneratorTarget->GetProperty(cppcheck_prop);
-      if ((iwyu && *iwyu) || (tidy && *tidy) || (cpplint && *cpplint) ||
-          (cppcheck && *cppcheck)) {
+      cmProp cppcheck = this->GeneratorTarget->GetProperty(cppcheck_prop);
+      if (cmNonempty(iwyu) || cmNonempty(tidy) || cmNonempty(cpplint) ||
+          cmNonempty(cppcheck)) {
         std::string run_iwyu = "$(CMAKE_COMMAND) -E __run_co_compile";
         if (!compilerLauncher.empty()) {
           // In __run_co_compile case the launcher command is supplied
@@ -777,30 +832,30 @@
           run_iwyu += this->LocalGenerator->EscapeForShell(compilerLauncher);
           compilerLauncher.clear();
         }
-        if (iwyu && *iwyu) {
+        if (cmNonempty(iwyu)) {
           run_iwyu += " --iwyu=";
-          run_iwyu += this->LocalGenerator->EscapeForShell(iwyu);
+          run_iwyu += this->LocalGenerator->EscapeForShell(*iwyu);
         }
-        if (tidy && *tidy) {
+        if (cmNonempty(tidy)) {
           run_iwyu += " --tidy=";
           const char* driverMode = this->Makefile->GetDefinition(
             "CMAKE_" + lang + "_CLANG_TIDY_DRIVER_MODE");
-          if (!(driverMode && *driverMode)) {
+          if (!cmNonempty(driverMode)) {
             driverMode = lang == "C" ? "gcc" : "g++";
           }
           run_iwyu += this->LocalGenerator->EscapeForShell(
-            cmStrCat(tidy, ";--extra-arg-before=--driver-mode=", driverMode));
+            cmStrCat(*tidy, ";--extra-arg-before=--driver-mode=", driverMode));
         }
-        if (cpplint && *cpplint) {
+        if (cmNonempty(cpplint)) {
           run_iwyu += " --cpplint=";
-          run_iwyu += this->LocalGenerator->EscapeForShell(cpplint);
+          run_iwyu += this->LocalGenerator->EscapeForShell(*cpplint);
         }
-        if (cppcheck && *cppcheck) {
+        if (cmNonempty(cppcheck)) {
           run_iwyu += " --cppcheck=";
-          run_iwyu += this->LocalGenerator->EscapeForShell(cppcheck);
+          run_iwyu += this->LocalGenerator->EscapeForShell(*cppcheck);
         }
-        if ((tidy && *tidy) || (cpplint && *cpplint) ||
-            (cppcheck && *cppcheck)) {
+        if (cmNonempty(tidy) || (cmNonempty(cpplint)) ||
+            (cmNonempty(cppcheck))) {
           run_iwyu += " --source=";
           run_iwyu += sourceFile;
         }
@@ -827,7 +882,7 @@
     {
       const char* val = this->LocalGenerator->GetRuleLauncher(
         this->GeneratorTarget, "RULE_LAUNCH_COMPILE");
-      if (val && *val) {
+      if (cmNonempty(val)) {
         launcher = cmStrCat(val, ' ');
       }
     }
@@ -848,10 +903,15 @@
 
   // Check for extra outputs created by the compilation.
   std::vector<std::string> outputs(1, relativeObj);
-  if (const char* extra_outputs_str = source.GetProperty("OBJECT_OUTPUTS")) {
-    // Register these as extra files to clean.
-    cmExpandList(extra_outputs_str, outputs);
-    this->CleanFiles.insert(outputs.begin() + 1, outputs.end());
+  if (cmProp extra_outputs_str = source.GetProperty("OBJECT_OUTPUTS")) {
+    std::string evaluated_outputs = cmGeneratorExpression::Evaluate(
+      *extra_outputs_str, this->LocalGenerator, config);
+
+    if (!evaluated_outputs.empty()) {
+      // Register these as extra files to clean.
+      cmExpandList(evaluated_outputs, outputs);
+      this->CleanFiles.insert(outputs.begin() + 1, outputs.end());
+    }
   }
 
   // Write the rule.
@@ -1130,8 +1190,7 @@
   // translation table for the dependency scanning process.
   depCmd << "cd "
          << (this->LocalGenerator->ConvertToOutputFormat(
-              cmSystemTools::CollapseFullPath(
-                this->LocalGenerator->GetBinaryDirectory()),
+              this->LocalGenerator->GetBinaryDirectory(),
               cmOutputConverter::SHELL))
          << " && ";
 #endif
@@ -1147,23 +1206,19 @@
   depCmd << "$(CMAKE_COMMAND) -E cmake_depends \""
          << this->GlobalGenerator->GetName() << "\" "
          << this->LocalGenerator->ConvertToOutputFormat(
-              cmSystemTools::CollapseFullPath(
-                this->LocalGenerator->GetSourceDirectory()),
+              this->LocalGenerator->GetSourceDirectory(),
               cmOutputConverter::SHELL)
          << " "
          << this->LocalGenerator->ConvertToOutputFormat(
-              cmSystemTools::CollapseFullPath(
-                this->LocalGenerator->GetCurrentSourceDirectory()),
+              this->LocalGenerator->GetCurrentSourceDirectory(),
               cmOutputConverter::SHELL)
          << " "
          << this->LocalGenerator->ConvertToOutputFormat(
-              cmSystemTools::CollapseFullPath(
-                this->LocalGenerator->GetBinaryDirectory()),
+              this->LocalGenerator->GetBinaryDirectory(),
               cmOutputConverter::SHELL)
          << " "
          << this->LocalGenerator->ConvertToOutputFormat(
-              cmSystemTools::CollapseFullPath(
-                this->LocalGenerator->GetCurrentBinaryDirectory()),
+              this->LocalGenerator->GetCurrentBinaryDirectory(),
               cmOutputConverter::SHELL)
          << " "
          << this->LocalGenerator->ConvertToOutputFormat(
@@ -1206,8 +1261,8 @@
   // Create the list of dependencies known at cmake time.  These are
   // shared between the object file and dependency scanning rule.
   depends.push_back(source.GetFullPath());
-  if (const char* objectDeps = source.GetProperty("OBJECT_DEPENDS")) {
-    cmExpandList(objectDeps, depends);
+  if (cmProp objectDeps = source.GetProperty("OBJECT_DEPENDS")) {
+    cmExpandList(*objectDeps, depends);
   }
 }
 
@@ -1251,8 +1306,10 @@
 
   // Setup implicit dependency scanning.
   for (auto const& idi : ccg.GetCC().GetImplicitDepends()) {
-    std::string objFullPath = cmSystemTools::CollapseFullPath(outputs[0]);
-    std::string srcFullPath = cmSystemTools::CollapseFullPath(idi.second);
+    std::string objFullPath = cmSystemTools::CollapseFullPath(
+      outputs[0], this->LocalGenerator->GetCurrentBinaryDirectory());
+    std::string srcFullPath = cmSystemTools::CollapseFullPath(
+      idi.second, this->LocalGenerator->GetCurrentBinaryDirectory());
     this->LocalGenerator->AddImplicitDepends(this->GeneratorTarget, idi.first,
                                              objFullPath, srcFullPath);
   }
@@ -1801,7 +1858,7 @@
       this->LocalGenerator->GetCurrentBinaryDirectory(), objlist_file),
     cmOutputConverter::SHELL);
   const char* nm_executable = this->Makefile->GetDefinition("CMAKE_NM");
-  if (nm_executable && *nm_executable) {
+  if (cmNonempty(nm_executable)) {
     cmd += " --nm=";
     cmd += this->LocalCommonGenerator->ConvertToOutputFormat(
       nm_executable, cmOutputConverter::SHELL);
diff --git a/Source/cmMakefileTargetGenerator.h b/Source/cmMakefileTargetGenerator.h
index ec6b314..f38f862 100644
--- a/Source/cmMakefileTargetGenerator.h
+++ b/Source/cmMakefileTargetGenerator.h
@@ -60,6 +60,8 @@
   std::string GetConfigName();
 
 protected:
+  void GetDeviceLinkFlags(std::string& linkFlags,
+                          const std::string& linkLanguage);
   void GetTargetLinkFlags(std::string& flags, const std::string& linkLanguage);
 
   // create the file and directory etc
diff --git a/Source/cmMathCommand.cxx b/Source/cmMathCommand.cxx
index f11b906..56221bf 100644
--- a/Source/cmMathCommand.cxx
+++ b/Source/cmMathCommand.cxx
@@ -4,7 +4,7 @@
 
 #include <cstdio>
 
-#include "cm_kwiml.h"
+#include <cm3p/kwiml/int.h>
 
 #include "cmExecutionStatus.h"
 #include "cmExprParserHelper.h"
diff --git a/Source/cmMessageCommand.cxx b/Source/cmMessageCommand.cxx
index bf8183b..c7bb9a7 100644
--- a/Source/cmMessageCommand.cxx
+++ b/Source/cmMessageCommand.cxx
@@ -6,8 +6,7 @@
 #include <utility>
 
 #include <cm/string_view>
-
-#include "cm_static_string_view.hxx"
+#include <cmext/string_view>
 
 #include "cmExecutionStatus.h"
 #include "cmMakefile.h"
diff --git a/Source/cmNinjaNormalTargetGenerator.cxx b/Source/cmNinjaNormalTargetGenerator.cxx
index ba2ea5b..bde5ee7 100644
--- a/Source/cmNinjaNormalTargetGenerator.cxx
+++ b/Source/cmNinjaNormalTargetGenerator.cxx
@@ -29,6 +29,7 @@
 #include "cmNinjaTypes.h"
 #include "cmOSXBundleGenerator.h"
 #include "cmOutputConverter.h"
+#include "cmProperty.h"
 #include "cmRulePlaceholderExpander.h"
 #include "cmSourceFile.h"
 #include "cmState.h"
@@ -156,23 +157,25 @@
 std::string cmNinjaNormalTargetGenerator::LanguageLinkerRule(
   const std::string& config) const
 {
-  return this->TargetLinkLanguage(config) + "_" +
-    cmState::GetTargetTypeName(this->GetGeneratorTarget()->GetType()) +
-    "_LINKER__" +
+  return cmStrCat(
+    this->TargetLinkLanguage(config), "_",
+    cmState::GetTargetTypeName(this->GetGeneratorTarget()->GetType()),
+    "_LINKER__",
     cmGlobalNinjaGenerator::EncodeRuleName(
-           this->GetGeneratorTarget()->GetName()) +
-    "_" + config;
+      this->GetGeneratorTarget()->GetName()),
+    "_", config);
 }
 
 std::string cmNinjaNormalTargetGenerator::LanguageLinkerDeviceRule(
   const std::string& config) const
 {
-  return this->TargetLinkLanguage(config) + "_" +
-    cmState::GetTargetTypeName(this->GetGeneratorTarget()->GetType()) +
-    "_DEVICE_LINKER__" +
+  return cmStrCat(
+    this->TargetLinkLanguage(config), "_",
+    cmState::GetTargetTypeName(this->GetGeneratorTarget()->GetType()),
+    "_DEVICE_LINKER__",
     cmGlobalNinjaGenerator::EncodeRuleName(
-           this->GetGeneratorTarget()->GetName()) +
-    "_" + config;
+      this->GetGeneratorTarget()->GetName()),
+    "_", config);
 }
 
 struct cmNinjaRemoveNoOpCommands
@@ -191,7 +194,8 @@
     cmRulePlaceholderExpander::RuleVariables vars;
     vars.CMTargetName = this->GetGeneratorTarget()->GetName().c_str();
     vars.CMTargetType =
-      cmState::GetTargetTypeName(this->GetGeneratorTarget()->GetType());
+      cmState::GetTargetTypeName(this->GetGeneratorTarget()->GetType())
+        .c_str();
 
     vars.Language = "CUDA";
 
@@ -230,16 +234,12 @@
     vars.LinkFlags = "$LINK_FLAGS";
     vars.Manifests = "$MANIFESTS";
 
-    std::string langFlags;
-    if (this->GetGeneratorTarget()->GetType() != cmStateEnums::EXECUTABLE) {
-      langFlags += "$LANGUAGE_COMPILE_FLAGS $ARCH_FLAGS";
-      vars.LanguageCompileFlags = langFlags.c_str();
-    }
+    vars.LanguageCompileFlags = "$LANGUAGE_COMPILE_FLAGS";
 
     std::string launcher;
     const char* val = this->GetLocalGenerator()->GetRuleLauncher(
       this->GetGeneratorTarget(), "RULE_LAUNCH_LINK");
-    if (val && *val) {
+    if (cmNonempty(val)) {
       launcher = cmStrCat(val, ' ');
     }
 
@@ -282,7 +282,7 @@
     cmNinjaRule rule(std::move(linkRuleName));
     cmRulePlaceholderExpander::RuleVariables vars;
     vars.CMTargetName = this->GetGeneratorTarget()->GetName().c_str();
-    vars.CMTargetType = cmState::GetTargetTypeName(targetType);
+    vars.CMTargetType = cmState::GetTargetTypeName(targetType).c_str();
 
     std::string lang = this->TargetLinkLanguage(config);
     vars.Language = config.c_str();
@@ -376,7 +376,7 @@
     std::string launcher;
     const char* val = this->GetLocalGenerator()->GetRuleLauncher(
       this->GetGeneratorTarget(), "RULE_LAUNCH_LINK");
-    if (val && *val) {
+    if (cmNonempty(val)) {
       launcher = cmStrCat(val, ' ');
     }
 
@@ -454,14 +454,12 @@
     case cmStateEnums::STATIC_LIBRARY:
     case cmStateEnums::SHARED_LIBRARY:
     case cmStateEnums::MODULE_LIBRARY: {
-      const std::string cudaLinkCmd(
-        this->GetMakefile()->GetDefinition("CMAKE_CUDA_DEVICE_LINK_LIBRARY"));
-      cmExpandList(cudaLinkCmd, linkCmds);
+      this->GetMakefile()->GetDefExpandList("CMAKE_CUDA_DEVICE_LINK_LIBRARY",
+                                            linkCmds);
     } break;
     case cmStateEnums::EXECUTABLE: {
-      const std::string cudaLinkCmd(this->GetMakefile()->GetDefinition(
-        "CMAKE_CUDA_DEVICE_LINK_EXECUTABLE"));
-      cmExpandList(cudaLinkCmd, linkCmds);
+      this->GetMakefile()->GetDefExpandList(
+        "CMAKE_CUDA_DEVICE_LINK_EXECUTABLE", linkCmds);
     } break;
     default:
       break;
@@ -558,9 +556,8 @@
     case cmStateEnums::EXECUTABLE:
       if (this->TargetLinkLanguage(config) == "Swift") {
         if (this->GeneratorTarget->IsExecutableWithExports()) {
-          const std::string flags =
-            this->Makefile->GetSafeDefinition("CMAKE_EXE_EXPORTS_Swift_FLAG");
-          cmExpandList(flags, linkCmds);
+          this->Makefile->GetDefExpandList("CMAKE_EXE_EXPORTS_Swift_FLAG",
+                                           linkCmds);
         }
       }
       break;
@@ -587,8 +584,6 @@
     return;
   }
 
-  // Now we can do device linking
-
   // First and very important step is to make sure while inside this
   // step our link language is set to CUDA
   std::string cudaLinkLanguage = "CUDA";
@@ -674,9 +669,9 @@
   linkLineComputer->SetUseWatcomQuote(useWatcomQuote);
   linkLineComputer->SetUseNinjaMulti(globalGen->IsMultiConfig());
 
-  localGen.GetTargetFlags(
-    linkLineComputer.get(), config, vars["LINK_LIBRARIES"], vars["FLAGS"],
-    vars["LINK_FLAGS"], frameworkPath, linkPath, genTarget);
+  localGen.GetDeviceLinkFlags(linkLineComputer.get(), config,
+                              vars["LINK_LIBRARIES"], vars["LINK_FLAGS"],
+                              frameworkPath, linkPath, genTarget);
 
   this->addPoolNinjaVariable("JOB_POOL_LINK", genTarget, vars);
 
@@ -686,22 +681,12 @@
 
   vars["LINK_PATH"] = frameworkPath + linkPath;
 
-  // Compute architecture specific link flags.  Yes, these go into a different
-  // variable for executables, probably due to a mistake made when duplicating
-  // code between the Makefile executable and library generators.
-  if (targetType == cmStateEnums::EXECUTABLE) {
-    std::string t = vars["FLAGS"];
-    localGen.AddArchitectureFlags(t, genTarget, cudaLinkLanguage, config);
-    vars["FLAGS"] = t;
-  } else {
-    std::string t = vars["ARCH_FLAGS"];
-    localGen.AddArchitectureFlags(t, genTarget, cudaLinkLanguage, config);
-    vars["ARCH_FLAGS"] = t;
-    t.clear();
-    localGen.AddLanguageFlagsForLinking(t, genTarget, cudaLinkLanguage,
-                                        config);
-    vars["LANGUAGE_COMPILE_FLAGS"] = t;
-  }
+  // Compute language specific link flags.
+  std::string langFlags;
+  localGen.AddLanguageFlagsForLinking(langFlags, genTarget, cudaLinkLanguage,
+                                      config);
+  vars["LANGUAGE_COMPILE_FLAGS"] = langFlags;
+
   auto const tgtNames = this->TargetNames(config);
   if (genTarget->HasSOName(config)) {
     vars["SONAME_FLAG"] =
@@ -754,7 +739,8 @@
 
   // Gather order-only dependencies.
   this->GetLocalGenerator()->AppendTargetDepends(
-    this->GetGeneratorTarget(), build.OrderOnlyDeps, config, config);
+    this->GetGeneratorTarget(), build.OrderOnlyDeps, config, config,
+    DependOnTargetArtifact);
 
   // Write the build statement for this target.
   bool usedResponseFile = false;
@@ -813,8 +799,20 @@
     targetOutputReal = this->ConvertToNinjaPath(targetOutputReal);
   } else if (gt->IsFrameworkOnApple()) {
     // Create the library framework.
+
+    cmOSXBundleGenerator::SkipParts bundleSkipParts;
+    if (globalGen->GetName() == "Ninja Multi-Config") {
+      const auto postFix = this->GeneratorTarget->GetFilePostfix(config);
+      // Skip creating Info.plist when there are multiple configurations, and
+      // the current configuration has a postfix. The non-postfix configuration
+      // Info.plist can be used by all the other configurations.
+      if (!postFix.empty()) {
+        bundleSkipParts.infoPlist = true;
+      }
+    }
+
     this->OSXBundleGenerator->CreateFramework(
-      tgtNames.Output, gt->GetDirectory(config), config);
+      tgtNames.Output, gt->GetDirectory(config), config, bundleSkipParts);
   } else if (gt->IsCFBundleOnApple()) {
     // Create the core foundation bundle.
     this->OSXBundleGenerator->CreateCFBundle(tgtNames.Output,
@@ -849,8 +847,8 @@
     }();
 
     vars["SWIFT_MODULE_NAME"] = [gt]() -> std::string {
-      if (const char* name = gt->GetProperty("Swift_MODULE_NAME")) {
-        return name;
+      if (cmProp name = gt->GetProperty("Swift_MODULE_NAME")) {
+        return *name;
       }
       return gt->GetName();
     }();
@@ -858,15 +856,15 @@
     vars["SWIFT_MODULE"] = [this](const std::string& module) -> std::string {
       std::string directory =
         this->GetLocalGenerator()->GetCurrentBinaryDirectory();
-      if (const char* prop = this->GetGeneratorTarget()->GetProperty(
+      if (cmProp prop = this->GetGeneratorTarget()->GetProperty(
             "Swift_MODULE_DIRECTORY")) {
-        directory = prop;
+        directory = *prop;
       }
 
       std::string name = module + ".swiftmodule";
-      if (const char* prop =
+      if (cmProp prop =
             this->GetGeneratorTarget()->GetProperty("Swift_MODULE")) {
-        name = prop;
+        name = *prop;
       }
 
       return this->GetLocalGenerator()->ConvertToOutputFormat(
@@ -1026,11 +1024,11 @@
     std::string prefix;
     std::string base;
     std::string suffix;
-    gt->GetFullNameComponents(prefix, base, suffix);
+    gt->GetFullNameComponents(prefix, base, suffix, config);
     std::string dbg_suffix = ".dbg";
     // TODO: Where to document?
-    if (mf->GetDefinition("CMAKE_DEBUG_SYMBOL_SUFFIX")) {
-      dbg_suffix = mf->GetDefinition("CMAKE_DEBUG_SYMBOL_SUFFIX");
+    if (auto d = mf->GetDefinition("CMAKE_DEBUG_SYMBOL_SUFFIX")) {
+      dbg_suffix = d;
     }
     vars["TARGET_PDB"] = base + suffix + dbg_suffix;
   }
@@ -1094,7 +1092,7 @@
       obj_list_file, cmOutputConverter::SHELL);
 
     const char* nm_executable = GetMakefile()->GetDefinition("CMAKE_NM");
-    if (nm_executable && *nm_executable) {
+    if (cmNonempty(nm_executable)) {
       cmd += " --nm=";
       cmd += this->LocalCommonGenerator->ConvertToOutputFormat(
         nm_executable, cmOutputConverter::SHELL);
@@ -1163,8 +1161,8 @@
              globalGen->IsMultiConfig() ? cmStrCat('.', config) : "", ".rsp"));
 
   // Gather order-only dependencies.
-  this->GetLocalGenerator()->AppendTargetDepends(gt, linkBuild.OrderOnlyDeps,
-                                                 config, fileConfig);
+  this->GetLocalGenerator()->AppendTargetDepends(
+    gt, linkBuild.OrderOnlyDeps, config, fileConfig, DependOnTargetArtifact);
 
   // Add order-only dependencies on versioning symlinks of shared libs we link.
   if (!this->GeneratorTarget->IsDLLPlatform()) {
diff --git a/Source/cmNinjaTargetGenerator.cxx b/Source/cmNinjaTargetGenerator.cxx
index 486ed8d..57f526e 100644
--- a/Source/cmNinjaTargetGenerator.cxx
+++ b/Source/cmNinjaTargetGenerator.cxx
@@ -7,13 +7,15 @@
 #include <iterator>
 #include <map>
 #include <ostream>
+#include <unordered_map>
+#include <unordered_set>
 #include <utility>
 
 #include <cm/memory>
 #include <cmext/algorithm>
 
-#include "cm_jsoncpp_value.h"
-#include "cm_jsoncpp_writer.h"
+#include <cm3p/json/value.h>
+#include <cm3p/json/writer.h>
 
 #include "cmComputeLinkInformation.h"
 #include "cmCustomCommandGenerator.h"
@@ -27,6 +29,7 @@
 #include "cmNinjaNormalTargetGenerator.h"
 #include "cmNinjaUtilityTargetGenerator.h"
 #include "cmOutputConverter.h"
+#include "cmProperty.h"
 #include "cmRange.h"
 #include "cmRulePlaceholderExpander.h"
 #include "cmSourceFile.h"
@@ -48,6 +51,7 @@
       return cm::make_unique<cmNinjaNormalTargetGenerator>(target);
 
     case cmStateEnums::UTILITY:
+    case cmStateEnums::INTERFACE_LIBRARY:
     case cmStateEnums::GLOBAL_TARGET:
       return cm::make_unique<cmNinjaUtilityTargetGenerator>(target);
 
@@ -62,7 +66,8 @@
   , LocalGenerator(
       static_cast<cmLocalNinjaGenerator*>(target->GetLocalGenerator()))
 {
-  for (auto const& fileConfig : target->Makefile->GetGeneratorConfigs()) {
+  for (auto const& fileConfig :
+       target->Makefile->GetGeneratorConfigs(cmMakefile::IncludeEmptyConfig)) {
     this->Configs[fileConfig].MacOSXContentGenerator =
       cm::make_unique<MacOSXContentGeneratorType>(this, fileConfig);
   }
@@ -94,17 +99,28 @@
 std::string cmNinjaTargetGenerator::LanguageCompilerRule(
   const std::string& lang, const std::string& config) const
 {
-  return lang + "_COMPILER__" +
-    cmGlobalNinjaGenerator::EncodeRuleName(this->GeneratorTarget->GetName()) +
-    "_" + config;
+  return cmStrCat(
+    lang, "_COMPILER__",
+    cmGlobalNinjaGenerator::EncodeRuleName(this->GeneratorTarget->GetName()),
+    '_', config);
 }
 
 std::string cmNinjaTargetGenerator::LanguagePreprocessRule(
   std::string const& lang, const std::string& config) const
 {
-  return lang + "_PREPROCESS__" +
-    cmGlobalNinjaGenerator::EncodeRuleName(this->GeneratorTarget->GetName()) +
-    "_" + config;
+  return cmStrCat(
+    lang, "_PREPROCESS_SCAN__",
+    cmGlobalNinjaGenerator::EncodeRuleName(this->GeneratorTarget->GetName()),
+    '_', config);
+}
+
+std::string cmNinjaTargetGenerator::LanguageDependencyRule(
+  std::string const& lang, const std::string& config) const
+{
+  return cmStrCat(
+    lang, "_SCAN__",
+    cmGlobalNinjaGenerator::EncodeRuleName(this->GeneratorTarget->GetName()),
+    '_', config);
 }
 
 bool cmNinjaTargetGenerator::NeedExplicitPreprocessing(
@@ -129,9 +145,10 @@
 std::string cmNinjaTargetGenerator::LanguageDyndepRule(
   const std::string& lang, const std::string& config) const
 {
-  return lang + "_DYNDEP__" +
-    cmGlobalNinjaGenerator::EncodeRuleName(this->GeneratorTarget->GetName()) +
-    "_" + config;
+  return cmStrCat(
+    lang, "_DYNDEP__",
+    cmGlobalNinjaGenerator::EncodeRuleName(this->GeneratorTarget->GetName()),
+    '_', config);
 }
 
 bool cmNinjaTargetGenerator::NeedDyndep(std::string const& lang) const
@@ -154,11 +171,40 @@
   cmSourceFile const* source, const std::string& language,
   const std::string& config)
 {
-  std::string flags = this->GetFlags(language, config);
+  std::vector<std::string> architectures;
+  std::unordered_map<std::string, std::string> pchSources;
+  this->GeneratorTarget->GetAppleArchs(config, architectures);
+  if (architectures.empty()) {
+    architectures.emplace_back();
+  }
+
+  std::string filterArch;
+  for (const std::string& arch : architectures) {
+    const std::string pchSource =
+      this->GeneratorTarget->GetPchSource(config, language, arch);
+    if (pchSource == source->GetFullPath()) {
+      filterArch = arch;
+    }
+    if (!pchSource.empty()) {
+      pchSources.insert(std::make_pair(pchSource, arch));
+    }
+  }
+
+  std::string flags;
+  // explicitly add the explicit language flag before any other flag
+  // this way backwards compatibility with user flags is maintained
+  if (source->GetProperty("LANGUAGE")) {
+    this->LocalGenerator->AppendFeatureOptions(flags, language,
+                                               "EXPLICIT_LANGUAGE");
+    flags += " ";
+  }
+
+  flags += this->GetFlags(language, config, filterArch);
 
   // Add Fortran format flags.
   if (language == "Fortran") {
     this->AppendFortranFormatFlags(flags, *source);
+    this->AppendFortranPreprocessFlags(flags, *source);
   }
 
   // Add source file specific flags.
@@ -166,26 +212,24 @@
     this->LocalGenerator, config, this->GeneratorTarget, language);
 
   const std::string COMPILE_FLAGS("COMPILE_FLAGS");
-  if (const char* cflags = source->GetProperty(COMPILE_FLAGS)) {
+  if (cmProp cflags = source->GetProperty(COMPILE_FLAGS)) {
     this->LocalGenerator->AppendFlags(
-      flags, genexInterpreter.Evaluate(cflags, COMPILE_FLAGS));
+      flags, genexInterpreter.Evaluate(*cflags, COMPILE_FLAGS));
   }
 
   const std::string COMPILE_OPTIONS("COMPILE_OPTIONS");
-  if (const char* coptions = source->GetProperty(COMPILE_OPTIONS)) {
+  if (cmProp coptions = source->GetProperty(COMPILE_OPTIONS)) {
     this->LocalGenerator->AppendCompileOptions(
-      flags, genexInterpreter.Evaluate(coptions, COMPILE_OPTIONS));
+      flags, genexInterpreter.Evaluate(*coptions, COMPILE_OPTIONS));
   }
 
   // Add precompile headers compile options.
-  const std::string pchSource =
-    this->GeneratorTarget->GetPchSource(config, language);
-
-  if (!pchSource.empty() && !source->GetProperty("SKIP_PRECOMPILE_HEADERS")) {
+  if (!pchSources.empty() && !source->GetProperty("SKIP_PRECOMPILE_HEADERS")) {
     std::string pchOptions;
-    if (source->GetFullPath() == pchSource) {
-      pchOptions =
-        this->GeneratorTarget->GetPchCreateCompileOptions(config, language);
+    auto pchIt = pchSources.find(source->GetFullPath());
+    if (pchIt != pchSources.end()) {
+      pchOptions = this->GeneratorTarget->GetPchCreateCompileOptions(
+        config, language, pchIt->second);
     } else {
       pchOptions =
         this->GeneratorTarget->GetPchUseCompileOptions(config, language);
@@ -219,8 +263,8 @@
 
 bool cmNinjaTargetGenerator::NeedDepTypeMSVC(const std::string& lang) const
 {
-  std::string const& deptype =
-    this->GetMakefile()->GetSafeDefinition("CMAKE_NINJA_DEPTYPE_" + lang);
+  std::string const& deptype = this->GetMakefile()->GetSafeDefinition(
+    cmStrCat("CMAKE_NINJA_DEPTYPE_", lang));
   if (deptype == "msvc") {
     return true;
   }
@@ -259,17 +303,17 @@
   }
 
   const std::string COMPILE_DEFINITIONS("COMPILE_DEFINITIONS");
-  if (const char* compile_defs = source->GetProperty(COMPILE_DEFINITIONS)) {
+  if (cmProp compile_defs = source->GetProperty(COMPILE_DEFINITIONS)) {
     this->LocalGenerator->AppendDefines(
-      defines, genexInterpreter.Evaluate(compile_defs, COMPILE_DEFINITIONS));
+      defines, genexInterpreter.Evaluate(*compile_defs, COMPILE_DEFINITIONS));
   }
 
   std::string defPropName =
     cmStrCat("COMPILE_DEFINITIONS_", cmSystemTools::UpperCase(config));
-  if (const char* config_compile_defs = source->GetProperty(defPropName)) {
+  if (cmProp config_compile_defs = source->GetProperty(defPropName)) {
     this->LocalGenerator->AppendDefines(
       defines,
-      genexInterpreter.Evaluate(config_compile_defs, COMPILE_DEFINITIONS));
+      genexInterpreter.Evaluate(*config_compile_defs, COMPILE_DEFINITIONS));
   }
 
   std::string definesString = this->GetDefines(language, config);
@@ -287,9 +331,9 @@
     this->LocalGenerator, config, this->GeneratorTarget, language);
 
   const std::string INCLUDE_DIRECTORIES("INCLUDE_DIRECTORIES");
-  if (const char* cincludes = source->GetProperty(INCLUDE_DIRECTORIES)) {
+  if (cmProp cincludes = source->GetProperty(INCLUDE_DIRECTORIES)) {
     this->LocalGenerator->AppendIncludeDirectories(
-      includes, genexInterpreter.Evaluate(cincludes, INCLUDE_DIRECTORIES),
+      includes, genexInterpreter.Evaluate(*cincludes, INCLUDE_DIRECTORIES),
       *source);
   }
 
@@ -355,13 +399,12 @@
 {
   std::string path = this->LocalGenerator->GetHomeRelativeOutputPath();
   if (!path.empty()) {
-    path += "/";
+    path += '/';
   }
   std::string const& objectName = this->GeneratorTarget->GetObjectName(source);
-  path += this->LocalGenerator->GetTargetDirectory(this->GeneratorTarget);
-  path += this->GetGlobalGenerator()->ConfigDirectory(config);
-  path += "/";
-  path += objectName;
+  path += cmStrCat(
+    this->LocalGenerator->GetTargetDirectory(this->GeneratorTarget),
+    this->GetGlobalGenerator()->ConfigDirectory(config), '/', objectName);
   return path;
 }
 
@@ -389,16 +432,15 @@
     this->GetGlobalGenerator()->GetLanguageOutputExtension(*source);
   assert(objName.size() >= objExt.size());
   std::string const ppName =
-    objName.substr(0, objName.size() - objExt.size()) + "-pp." + ppExt;
+    cmStrCat(objName.substr(0, objName.size() - objExt.size()), "-pp.", ppExt);
 
   std::string path = this->LocalGenerator->GetHomeRelativeOutputPath();
   if (!path.empty()) {
-    path += "/";
+    path += '/';
   }
-  path += this->LocalGenerator->GetTargetDirectory(this->GeneratorTarget);
-  path += this->GetGlobalGenerator()->ConfigDirectory(config);
-  path += "/";
-  path += ppName;
+  path +=
+    cmStrCat(this->LocalGenerator->GetTargetDirectory(this->GeneratorTarget),
+             this->GetGlobalGenerator()->ConfigDirectory(config), '/', ppName);
   return path;
 }
 
@@ -407,13 +449,11 @@
 {
   std::string path = this->LocalGenerator->GetHomeRelativeOutputPath();
   if (!path.empty()) {
-    path += "/";
+    path += '/';
   }
-  path += this->LocalGenerator->GetTargetDirectory(this->GeneratorTarget);
-  path += this->GetGlobalGenerator()->ConfigDirectory(config);
-  path += "/";
-  path += lang;
-  path += ".dd";
+  path += cmStrCat(
+    this->LocalGenerator->GetTargetDirectory(this->GeneratorTarget),
+    this->GetGlobalGenerator()->ConfigDirectory(config), '/', lang, ".dd");
   return path;
 }
 
@@ -442,8 +482,7 @@
   if (path.empty() || path == ".") {
     return name;
   }
-  path += "/";
-  path += name;
+  path += cmStrCat('/', name);
   return path;
 }
 
@@ -491,13 +530,98 @@
   this->WriteCompileRule(language, config);
 }
 
+namespace {
+// Create the command to run the dependency scanner
+std::string GetScanCommand(const std::string& cmakeCmd, const std::string& tdi,
+                           const std::string& lang, const std::string& ppFile,
+                           bool needDyndep, const std::string& ddiFile)
+{
+  std::string ccmd =
+    cmStrCat(cmakeCmd, " -E cmake_ninja_depends --tdi=", tdi, " --lang=", lang,
+             " --pp=", ppFile, " --dep=$DEP_FILE");
+  if (needDyndep) {
+    ccmd = cmStrCat(ccmd, " --obj=$OBJ_FILE --ddi=", ddiFile);
+  }
+  return ccmd;
+}
+
+// Helper function to create dependency scanning rule, with optional
+// explicit preprocessing step if preprocessCommand is non-empty
+cmNinjaRule GetPreprocessScanRule(
+  const std::string& ruleName, cmRulePlaceholderExpander::RuleVariables& vars,
+  const std::string& responseFlag, const std::string& flags,
+  const std::string& launcher,
+  cmRulePlaceholderExpander* const rulePlaceholderExpander,
+  std::string scanCommand, cmLocalNinjaGenerator* generator,
+  const std::string& preprocessCommand = "")
+{
+  cmNinjaRule rule(ruleName);
+  // Explicit preprocessing always uses a depfile.
+  rule.DepType = ""; // no deps= for multiple outputs
+  rule.DepFile = "$DEP_FILE";
+
+  cmRulePlaceholderExpander::RuleVariables ppVars;
+  ppVars.CMTargetName = vars.CMTargetName;
+  ppVars.CMTargetType = vars.CMTargetType;
+  ppVars.Language = vars.Language;
+  ppVars.Object = "$out"; // for RULE_LAUNCH_COMPILE
+  ppVars.PreprocessedSource = "$out";
+  ppVars.DependencyFile = rule.DepFile.c_str();
+
+  // Preprocessing uses the original source, compilation uses
+  // preprocessed output or original source
+  ppVars.Source = vars.Source;
+  vars.Source = "$in";
+
+  // Copy preprocessor definitions to the preprocessor rule.
+  ppVars.Defines = vars.Defines;
+
+  // Copy include directories to the preprocessor rule.  The Fortran
+  // compilation rule still needs them for the INCLUDE directive.
+  ppVars.Includes = vars.Includes;
+
+  // Preprocessing and compilation use the same flags.
+  std::string ppFlags = flags;
+
+  // If using a response file, move defines, includes, and flags into it.
+  if (!responseFlag.empty()) {
+    rule.RspFile = "$RSP_FILE";
+    rule.RspContent =
+      cmStrCat(' ', ppVars.Defines, ' ', ppVars.Includes, ' ', ppFlags);
+    ppFlags = cmStrCat(responseFlag, rule.RspFile);
+    ppVars.Defines = "";
+    ppVars.Includes = "";
+  }
+
+  ppVars.Flags = ppFlags.c_str();
+
+  // Rule for preprocessing source file.
+  std::vector<std::string> ppCmds;
+
+  if (!preprocessCommand.empty()) {
+    // Lookup the explicit preprocessing rule.
+    cmExpandList(preprocessCommand, ppCmds);
+    for (std::string& i : ppCmds) {
+      i = cmStrCat(launcher, i);
+      rulePlaceholderExpander->ExpandRuleVariables(generator, i, ppVars);
+    }
+  }
+
+  // Run CMake dependency scanner on either preprocessed output or source file
+  ppCmds.emplace_back(std::move(scanCommand));
+  rule.Command = generator->BuildCommandLine(ppCmds);
+
+  return rule;
+}
+}
+
 void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang,
                                               const std::string& config)
 {
   cmRulePlaceholderExpander::RuleVariables vars;
   vars.CMTargetName = this->GetGeneratorTarget()->GetName().c_str();
   vars.CMTargetType =
-    cmState::GetTargetTypeName(this->GetGeneratorTarget()->GetType());
+    cmState::GetTargetTypeName(this->GetGeneratorTarget()->GetType()).c_str();
   vars.Language = lang.c_str();
   vars.Source = "$in";
   vars.Object = "$out";
@@ -522,7 +646,7 @@
   bool const lang_supports_response = lang != "RC";
   if (lang_supports_response && this->ForceResponseFile()) {
     std::string const responseFlagVar =
-      "CMAKE_" + lang + "_RESPONSE_FILE_FLAG";
+      cmStrCat("CMAKE_", lang, "_RESPONSE_FILE_FLAG");
     responseFlag = this->Makefile->GetSafeDefinition(responseFlagVar);
     if (responseFlag.empty() && lang != "CUDA") {
       responseFlag = "@";
@@ -539,7 +663,7 @@
   std::string launcher;
   const char* val = this->GetLocalGenerator()->GetRuleLauncher(
     this->GetGeneratorTarget(), "RULE_LAUNCH_COMPILE");
-  if (val && *val) {
+  if (cmNonempty(val)) {
     launcher = cmStrCat(val, ' ');
   }
 
@@ -548,82 +672,42 @@
       cmSystemTools::GetCMakeCommand(), cmLocalGenerator::SHELL);
 
   if (explicitPP) {
-    cmNinjaRule rule(this->LanguagePreprocessRule(lang, config));
-    // Explicit preprocessing always uses a depfile.
-    rule.DepType = ""; // no deps= for multiple outputs
-    rule.DepFile = "$DEP_FILE";
+    // Combined preprocessing and dependency scanning
+    const auto ppScanCommand = GetScanCommand(
+      cmakeCmd, tdi, lang, "$out", needDyndep, "$DYNDEP_INTERMEDIATE_FILE");
+    const auto ppVar = cmStrCat("CMAKE_", lang, "_PREPROCESS_SOURCE");
 
-    cmRulePlaceholderExpander::RuleVariables ppVars;
-    ppVars.CMTargetName = vars.CMTargetName;
-    ppVars.CMTargetType = vars.CMTargetType;
-    ppVars.Language = vars.Language;
-    ppVars.Object = "$out"; // for RULE_LAUNCH_COMPILE
-    ppVars.PreprocessedSource = "$out";
-    ppVars.DependencyFile = rule.DepFile.c_str();
-
-    // Preprocessing uses the original source,
-    // compilation uses preprocessed output.
-    ppVars.Source = vars.Source;
-    vars.Source = "$in";
-
-    // Preprocessing and compilation use the same flags.
-    std::string ppFlags = flags;
-
-    if (!compilePPWithDefines) {
-      // Move preprocessor definitions to the preprocessor rule.
-      ppVars.Defines = vars.Defines;
-      vars.Defines = "";
-    } else {
-      // Copy preprocessor definitions to the preprocessor rule.
-      ppVars.Defines = vars.Defines;
-    }
-
-    // Copy include directories to the preprocessor rule.  The Fortran
-    // compilation rule still needs them for the INCLUDE directive.
-    ppVars.Includes = vars.Includes;
-
-    // If using a response file, move defines, includes, and flags into it.
-    if (!responseFlag.empty()) {
-      rule.RspFile = "$RSP_FILE";
-      rule.RspContent =
-        cmStrCat(' ', ppVars.Defines, ' ', ppVars.Includes, ' ', ppFlags);
-      ppFlags = responseFlag + rule.RspFile;
-      ppVars.Defines = "";
-      ppVars.Includes = "";
-    }
-
-    ppVars.Flags = ppFlags.c_str();
-
-    // Rule for preprocessing source file.
-    std::vector<std::string> ppCmds;
-    {
-      // Lookup the explicit preprocessing rule.
-      std::string ppVar = cmStrCat("CMAKE_", lang, "_PREPROCESS_SOURCE");
-      cmExpandList(this->GetMakefile()->GetRequiredDefinition(ppVar), ppCmds);
-    }
-
-    for (std::string& i : ppCmds) {
-      i = cmStrCat(launcher, i);
-      rulePlaceholderExpander->ExpandRuleVariables(this->GetLocalGenerator(),
-                                                   i, ppVars);
-    }
-
-    // Run CMake dependency scanner on preprocessed output.
-    {
-      std::string ccmd =
-        cmStrCat(cmakeCmd, " -E cmake_ninja_depends --tdi=", tdi,
-                 " --lang=", lang, " --pp=$out --dep=$DEP_FILE");
-      if (needDyndep) {
-        ccmd += " --obj=$OBJ_FILE --ddi=$DYNDEP_INTERMEDIATE_FILE";
-      }
-      ppCmds.emplace_back(std::move(ccmd));
-    }
-    rule.Command = this->GetLocalGenerator()->BuildCommandLine(ppCmds);
+    auto ppRule = GetPreprocessScanRule(
+      this->LanguagePreprocessRule(lang, config), vars, responseFlag, flags,
+      launcher, rulePlaceholderExpander.get(), ppScanCommand,
+      this->GetLocalGenerator(), mf->GetRequiredDefinition(ppVar));
 
     // Write the rule for preprocessing file of the given language.
-    rule.Comment = cmStrCat("Rule for preprocessing ", lang, " files.");
-    rule.Description = cmStrCat("Building ", lang, " preprocessed $out");
-    this->GetGlobalGenerator()->AddRule(rule);
+    ppRule.Comment = cmStrCat("Rule for preprocessing ", lang, " files.");
+    ppRule.Description = cmStrCat("Building ", lang, " preprocessed $out");
+
+    this->GetGlobalGenerator()->AddRule(ppRule);
+
+    if (!compilePPWithDefines) {
+      // Remove preprocessor definitions from compilation step
+      vars.Defines = "";
+    }
+
+    // Just dependency scanning for files that have preprocessing turned off
+    const auto scanCommand =
+      GetScanCommand(cmakeCmd, tdi, lang, "$in", needDyndep, "$out");
+
+    auto scanRule = GetPreprocessScanRule(
+      this->LanguageDependencyRule(lang, config), vars, "", flags, launcher,
+      rulePlaceholderExpander.get(), scanCommand, this->GetLocalGenerator());
+
+    // Write the rule for generating dependencies for the given language.
+    scanRule.Comment = cmStrCat("Rule for generating ", lang,
+                                " dependencies on non-preprocessed files.");
+    scanRule.Description =
+      cmStrCat("Generating ", lang, " dependencies for $in");
+
+    this->GetGlobalGenerator()->AddRule(scanRule);
   }
 
   if (needDyndep) {
@@ -658,7 +742,7 @@
     rule.RspFile = "$RSP_FILE";
     rule.RspContent =
       cmStrCat(' ', vars.Defines, ' ', vars.Includes, ' ', flags);
-    flags = responseFlag + rule.RspFile;
+    flags = cmStrCat(responseFlag, rule.RspFile);
     vars.Defines = "";
     vars.Includes = "";
   }
@@ -671,15 +755,15 @@
     rule.DepType = "msvc";
     rule.DepFile.clear();
     flags += " /showIncludes";
-  } else if (mf->IsOn("CMAKE_NINJA_CMCLDEPS_" + lang)) {
+  } else if (mf->IsOn(cmStrCat("CMAKE_NINJA_CMCLDEPS_", lang))) {
     // For the MS resource compiler we need cmcldeps, but skip dependencies
     // for source-file try_compile cases because they are always fresh.
     if (!mf->GetIsSourceFileTryCompile()) {
       rule.DepType = "gcc";
       rule.DepFile = "$DEP_FILE";
-      const std::string cl = mf->GetDefinition("CMAKE_C_COMPILER")
-        ? mf->GetSafeDefinition("CMAKE_C_COMPILER")
-        : mf->GetSafeDefinition("CMAKE_CXX_COMPILER");
+      auto d = mf->GetDefinition("CMAKE_C_COMPILER");
+      const std::string cl =
+        d ? d : mf->GetSafeDefinition("CMAKE_CXX_COMPILER");
       cldeps = cmStrCat('"', cmSystemTools::GetCMClDepsCommand(), "\" ", lang,
                         ' ', vars.Source, " $DEP_FILE $out \"",
                         mf->GetSafeDefinition("CMAKE_CL_SHOWINCLUDES_PREFIX"),
@@ -688,14 +772,14 @@
   } else {
     rule.DepType = "gcc";
     rule.DepFile = "$DEP_FILE";
-    const std::string flagsName = "CMAKE_DEPFILE_FLAGS_" + lang;
+    const std::string flagsName = cmStrCat("CMAKE_DEPFILE_FLAGS_", lang);
     std::string depfileFlags = mf->GetSafeDefinition(flagsName);
     if (!depfileFlags.empty()) {
       cmSystemTools::ReplaceString(depfileFlags, "<DEPFILE>", "$DEP_FILE");
       cmSystemTools::ReplaceString(depfileFlags, "<OBJECT>", "$out");
       cmSystemTools::ReplaceString(depfileFlags, "<CMAKE_C_COMPILER>",
                                    mf->GetDefinition("CMAKE_C_COMPILER"));
-      flags += " " + depfileFlags;
+      flags += cmStrCat(' ', depfileFlags);
     }
   }
 
@@ -718,7 +802,7 @@
     const std::string& compileCmd = mf->GetRequiredDefinition(cmdVar);
     cmExpandList(compileCmd, compileCmds);
   } else {
-    const std::string cmdVar = "CMAKE_" + lang + "_COMPILE_OBJECT";
+    const std::string cmdVar = cmStrCat("CMAKE_", lang, "_COMPILE_OBJECT");
     const std::string& compileCmd = mf->GetRequiredDefinition(cmdVar);
     cmExpandList(compileCmd, compileCmds);
   }
@@ -728,57 +812,58 @@
   if (!compileCmds.empty() &&
       (lang == "C" || lang == "CXX" || lang == "Fortran" || lang == "CUDA" ||
        lang == "OBJC" || lang == "OBJCXX")) {
-    std::string const clauncher_prop = lang + "_COMPILER_LAUNCHER";
-    const char* clauncher = this->GeneratorTarget->GetProperty(clauncher_prop);
-    if (clauncher && *clauncher) {
-      compilerLauncher = clauncher;
+    std::string const clauncher_prop = cmStrCat(lang, "_COMPILER_LAUNCHER");
+    cmProp clauncher = this->GeneratorTarget->GetProperty(clauncher_prop);
+    if (cmNonempty(clauncher)) {
+      compilerLauncher = *clauncher;
     }
   }
 
   // Maybe insert an include-what-you-use runner.
   if (!compileCmds.empty() && (lang == "C" || lang == "CXX")) {
-    std::string const iwyu_prop = lang + "_INCLUDE_WHAT_YOU_USE";
-    const char* iwyu = this->GeneratorTarget->GetProperty(iwyu_prop);
-    std::string const tidy_prop = lang + "_CLANG_TIDY";
-    const char* tidy = this->GeneratorTarget->GetProperty(tidy_prop);
-    std::string const cpplint_prop = lang + "_CPPLINT";
-    const char* cpplint = this->GeneratorTarget->GetProperty(cpplint_prop);
-    std::string const cppcheck_prop = lang + "_CPPCHECK";
-    const char* cppcheck = this->GeneratorTarget->GetProperty(cppcheck_prop);
-    if ((iwyu && *iwyu) || (tidy && *tidy) || (cpplint && *cpplint) ||
-        (cppcheck && *cppcheck)) {
+    std::string const iwyu_prop = cmStrCat(lang, "_INCLUDE_WHAT_YOU_USE");
+    cmProp iwyu = this->GeneratorTarget->GetProperty(iwyu_prop);
+    std::string const tidy_prop = cmStrCat(lang, "_CLANG_TIDY");
+    cmProp tidy = this->GeneratorTarget->GetProperty(tidy_prop);
+    std::string const cpplint_prop = cmStrCat(lang, "_CPPLINT");
+    cmProp cpplint = this->GeneratorTarget->GetProperty(cpplint_prop);
+    std::string const cppcheck_prop = cmStrCat(lang, "_CPPCHECK");
+    cmProp cppcheck = this->GeneratorTarget->GetProperty(cppcheck_prop);
+    if (cmNonempty(iwyu) || cmNonempty(tidy) || cmNonempty(cpplint) ||
+        cmNonempty(cppcheck)) {
       std::string run_iwyu = cmStrCat(cmakeCmd, " -E __run_co_compile");
       if (!compilerLauncher.empty()) {
         // In __run_co_compile case the launcher command is supplied
         // via --launcher=<maybe-list> and consumed
-        run_iwyu += " --launcher=";
-        run_iwyu += this->LocalGenerator->EscapeForShell(compilerLauncher);
+        run_iwyu +=
+          cmStrCat(" --launcher=",
+                   this->LocalGenerator->EscapeForShell(compilerLauncher));
         compilerLauncher.clear();
       }
-      if (iwyu && *iwyu) {
-        run_iwyu += " --iwyu=";
-        run_iwyu += this->GetLocalGenerator()->EscapeForShell(iwyu);
+      if (cmNonempty(iwyu)) {
+        run_iwyu += cmStrCat(" --iwyu=",
+                             this->GetLocalGenerator()->EscapeForShell(*iwyu));
       }
-      if (tidy && *tidy) {
+      if (cmNonempty(tidy)) {
         run_iwyu += " --tidy=";
         const char* driverMode = this->Makefile->GetDefinition(
-          "CMAKE_" + lang + "_CLANG_TIDY_DRIVER_MODE");
-        if (!(driverMode && *driverMode)) {
+          cmStrCat("CMAKE_", lang, "_CLANG_TIDY_DRIVER_MODE"));
+        if (!cmNonempty(driverMode)) {
           driverMode = lang == "C" ? "gcc" : "g++";
         }
         run_iwyu += this->GetLocalGenerator()->EscapeForShell(
-          cmStrCat(tidy, ";--extra-arg-before=--driver-mode=", driverMode));
+          cmStrCat(*tidy, ";--extra-arg-before=--driver-mode=", driverMode));
       }
-      if (cpplint && *cpplint) {
-        run_iwyu += " --cpplint=";
-        run_iwyu += this->GetLocalGenerator()->EscapeForShell(cpplint);
+      if (cmNonempty(cpplint)) {
+        run_iwyu += cmStrCat(
+          " --cpplint=", this->GetLocalGenerator()->EscapeForShell(*cpplint));
       }
-      if (cppcheck && *cppcheck) {
-        run_iwyu += " --cppcheck=";
-        run_iwyu += this->GetLocalGenerator()->EscapeForShell(cppcheck);
+      if (cmNonempty(cppcheck)) {
+        run_iwyu +=
+          cmStrCat(" --cppcheck=",
+                   this->GetLocalGenerator()->EscapeForShell(*cppcheck));
       }
-      if ((tidy && *tidy) || (cpplint && *cpplint) ||
-          (cppcheck && *cppcheck)) {
+      if (cmNonempty(tidy) || cmNonempty(cpplint) || cmNonempty(cppcheck)) {
         run_iwyu += " --source=$in";
       }
       run_iwyu += " -- ";
@@ -797,7 +882,7 @@
         i = this->LocalGenerator->EscapeForShell(i);
       }
     }
-    compileCmds.front().insert(0, cmJoin(args, " ") + " ");
+    compileCmds.front().insert(0, cmStrCat(cmJoin(args, " "), ' '));
   }
 
   if (!compileCmds.empty()) {
@@ -872,7 +957,8 @@
 
   {
     cmNinjaBuild build("phony");
-    build.Comment = "Order-only phony target for " + this->GetTargetName();
+    build.Comment =
+      cmStrCat("Order-only phony target for ", this->GetTargetName());
     build.Outputs.push_back(this->OrderDependsTargetForTarget(config));
 
     cmNinjaDeps& orderOnlyDeps = build.OrderOnlyDeps;
@@ -957,12 +1043,12 @@
                "output-file-map.json");
     std::string const targetSwiftDepsPath = [this, config]() -> std::string {
       cmGeneratorTarget const* target = this->GeneratorTarget;
-      if (const char* name = target->GetProperty("Swift_DEPENDENCIES_FILE")) {
-        return name;
+      if (cmProp name = target->GetProperty("Swift_DEPENDENCIES_FILE")) {
+        return *name;
       }
-      return this->ConvertToNinjaPath(target->GetSupportDirectory() + "/" +
-                                      config + "/" + target->GetName() +
-                                      ".swiftdeps");
+      return this->ConvertToNinjaPath(
+        cmStrCat(target->GetSupportDirectory(), '/', config, '/',
+                 target->GetName(), ".swiftdeps"));
     }();
 
     // build the global target dependencies
@@ -976,6 +1062,82 @@
   }
 }
 
+namespace {
+cmNinjaBuild GetPreprocessOrScanBuild(
+  const std::string& ruleName, const std::string& ppFileName, bool compilePP,
+  bool compilePPWithDefines, cmNinjaBuild& objBuild, cmNinjaVars& vars,
+  const std::string& depFileName, bool needDyndep,
+  const std::string& objectFileName)
+{
+  // Explicit preprocessing and dependency
+  cmNinjaBuild ppBuild(ruleName);
+
+  if (!ppFileName.empty()) {
+    ppBuild.Outputs.push_back(ppFileName);
+    ppBuild.RspFile = cmStrCat(ppFileName, ".rsp");
+  } else {
+    ppBuild.RspFile = "$out.rsp";
+  }
+
+  if (compilePP) {
+    // Move compilation dependencies to the preprocessing build statement.
+    std::swap(ppBuild.ExplicitDeps, objBuild.ExplicitDeps);
+    std::swap(ppBuild.ImplicitDeps, objBuild.ImplicitDeps);
+    std::swap(ppBuild.OrderOnlyDeps, objBuild.OrderOnlyDeps);
+    std::swap(ppBuild.Variables["IN_ABS"], vars["IN_ABS"]);
+
+    // The actual compilation will now use the preprocessed source.
+    objBuild.ExplicitDeps.push_back(ppFileName);
+  } else {
+    // Copy compilation dependencies to the preprocessing build statement.
+    ppBuild.ExplicitDeps = objBuild.ExplicitDeps;
+    ppBuild.ImplicitDeps = objBuild.ImplicitDeps;
+    ppBuild.OrderOnlyDeps = objBuild.OrderOnlyDeps;
+    ppBuild.Variables["IN_ABS"] = vars["IN_ABS"];
+  }
+
+  // Preprocessing and compilation generally use the same flags.
+  ppBuild.Variables["FLAGS"] = vars["FLAGS"];
+
+  if (compilePP && !compilePPWithDefines) {
+    // Move preprocessor definitions to the preprocessor build statement.
+    std::swap(ppBuild.Variables["DEFINES"], vars["DEFINES"]);
+  } else {
+    // Copy preprocessor definitions to the preprocessor build statement.
+    ppBuild.Variables["DEFINES"] = vars["DEFINES"];
+  }
+
+  // Copy include directories to the preprocessor build statement.  The
+  // Fortran compilation build statement still needs them for the INCLUDE
+  // directive.
+  ppBuild.Variables["INCLUDES"] = vars["INCLUDES"];
+
+  // Explicit preprocessing always uses a depfile.
+  ppBuild.Variables["DEP_FILE"] = depFileName;
+  if (compilePP) {
+    // The actual compilation does not need a depfile because it
+    // depends on the already-preprocessed source.
+    vars.erase("DEP_FILE");
+  }
+
+  if (needDyndep) {
+    // Tell dependency scanner the object file that will result from
+    // compiling the source.
+    ppBuild.Variables["OBJ_FILE"] = objectFileName;
+
+    // Tell dependency scanner where to store dyndep intermediate results.
+    std::string const ddiFile = cmStrCat(objectFileName, ".ddi");
+    if (ppFileName.empty()) {
+      ppBuild.Outputs.push_back(ddiFile);
+    } else {
+      ppBuild.Variables["DYNDEP_INTERMEDIATE_FILE"] = ddiFile;
+      ppBuild.ImplicitOuts.push_back(ddiFile);
+    }
+  }
+  return ppBuild;
+}
+}
+
 void cmNinjaTargetGenerator::WriteObjectBuildStatement(
   cmSourceFile const* source, const std::string& config,
   const std::string& fileConfig, bool firstForConfig)
@@ -994,7 +1156,7 @@
   std::string cmakeVarLang = cmStrCat("CMAKE_", language);
 
   // build response file name
-  std::string cmakeLinkVar = cmakeVarLang + "_RESPONSE_FILE_FLAG";
+  std::string cmakeLinkVar = cmStrCat(cmakeVarLang, "_RESPONSE_FILE_FLAG");
 
   const char* flag = GetMakefile()->GetDefinition(cmakeLinkVar);
 
@@ -1019,14 +1181,15 @@
     if (!replaceExt) {
       // use original code
       vars["DEP_FILE"] = this->GetLocalGenerator()->ConvertToOutputFormat(
-        objectFileName + ".d", cmOutputConverter::SHELL);
+        cmStrCat(objectFileName, ".d"), cmOutputConverter::SHELL);
     } else {
       // Replace the original source file extension with the
       // depend file extension.
-      std::string dependFileName =
-        cmSystemTools::GetFilenameWithoutLastExtension(objectFileName) + ".d";
+      std::string dependFileName = cmStrCat(
+        cmSystemTools::GetFilenameWithoutLastExtension(objectFileName), ".d");
       vars["DEP_FILE"] = this->GetLocalGenerator()->ConvertToOutputFormat(
-        objectFileDir + "/" + dependFileName, cmOutputConverter::SHELL);
+        cmStrCat(objectFileDir, '/', dependFileName),
+        cmOutputConverter::SHELL);
     }
   }
 
@@ -1049,17 +1212,35 @@
   // Add precompile headers dependencies
   std::vector<std::string> depList;
 
-  const std::string pchSource =
-    this->GeneratorTarget->GetPchSource(config, language);
-  if (!pchSource.empty() && !source->GetProperty("SKIP_PRECOMPILE_HEADERS")) {
-    depList.push_back(this->GeneratorTarget->GetPchHeader(config, language));
-    if (source->GetFullPath() != pchSource) {
-      depList.push_back(this->GeneratorTarget->GetPchFile(config, language));
+  std::vector<std::string> architectures;
+  this->GeneratorTarget->GetAppleArchs(config, architectures);
+  if (architectures.empty()) {
+    architectures.emplace_back();
+  }
+
+  std::unordered_set<std::string> pchSources;
+  for (const std::string& arch : architectures) {
+    const std::string pchSource =
+      this->GeneratorTarget->GetPchSource(config, language, arch);
+
+    if (!pchSource.empty()) {
+      pchSources.insert(pchSource);
     }
   }
 
-  if (const char* objectDeps = source->GetProperty("OBJECT_DEPENDS")) {
-    std::vector<std::string> objDepList = cmExpandedList(objectDeps);
+  if (!pchSources.empty() && !source->GetProperty("SKIP_PRECOMPILE_HEADERS")) {
+    for (const std::string& arch : architectures) {
+      depList.push_back(
+        this->GeneratorTarget->GetPchHeader(config, language, arch));
+      if (pchSources.find(source->GetFullPath()) == pchSources.end()) {
+        depList.push_back(
+          this->GeneratorTarget->GetPchFile(config, language, arch));
+      }
+    }
+  }
+
+  if (cmProp objectDeps = source->GetProperty("OBJECT_DEPENDS")) {
+    std::vector<std::string> objDepList = cmExpandedList(*objectDeps);
     std::copy(objDepList.begin(), objDepList.end(),
               std::back_inserter(depList));
   }
@@ -1095,59 +1276,47 @@
   // For some cases we do an explicit preprocessor invocation.
   bool const explicitPP = this->NeedExplicitPreprocessing(language);
   if (explicitPP) {
-    cmNinjaBuild ppBuild(this->LanguagePreprocessRule(language, config));
 
-    std::string const ppFileName =
-      this->ConvertToNinjaPath(this->GetPreprocessedFilePath(source, config));
-    ppBuild.Outputs.push_back(ppFileName);
-
-    ppBuild.RspFile = ppFileName + ".rsp";
-
-    bool const compilePP = this->UsePreprocessedSource(language);
-    bool const compilePPWithDefines =
-      compilePP && this->CompilePreprocessedSourceWithDefines(language);
-    if (compilePP) {
-      // Move compilation dependencies to the preprocessing build statement.
-      std::swap(ppBuild.ExplicitDeps, objBuild.ExplicitDeps);
-      std::swap(ppBuild.ImplicitDeps, objBuild.ImplicitDeps);
-      std::swap(ppBuild.OrderOnlyDeps, objBuild.OrderOnlyDeps);
-      std::swap(ppBuild.Variables["IN_ABS"], vars["IN_ABS"]);
-
-      // The actual compilation will now use the preprocessed source.
-      objBuild.ExplicitDeps.push_back(ppFileName);
-    } else {
-      // Copy compilation dependencies to the preprocessing build statement.
-      ppBuild.ExplicitDeps = objBuild.ExplicitDeps;
-      ppBuild.ImplicitDeps = objBuild.ImplicitDeps;
-      ppBuild.OrderOnlyDeps = objBuild.OrderOnlyDeps;
-      ppBuild.Variables["IN_ABS"] = vars["IN_ABS"];
+    // If source/target has preprocessing turned off, we still need to
+    // generate an explicit dependency step
+    const auto srcpp = source->GetSafeProperty("Fortran_PREPROCESS");
+    cmOutputConverter::FortranPreprocess preprocess =
+      cmOutputConverter::GetFortranPreprocess(srcpp);
+    if (preprocess == cmOutputConverter::FortranPreprocess::Unset) {
+      const auto& tgtpp =
+        this->GeneratorTarget->GetSafeProperty("Fortran_PREPROCESS");
+      preprocess = cmOutputConverter::GetFortranPreprocess(tgtpp);
     }
 
-    // Preprocessing and compilation generally use the same flags.
-    ppBuild.Variables["FLAGS"] = vars["FLAGS"];
+    bool const compilePP = this->UsePreprocessedSource(language) &&
+      (preprocess != cmOutputConverter::FortranPreprocess::NotNeeded);
+    bool const compilePPWithDefines =
+      compilePP && this->CompilePreprocessedSourceWithDefines(language);
+
+    std::string const ppFileName = compilePP
+      ? this->ConvertToNinjaPath(this->GetPreprocessedFilePath(source, config))
+      : "";
+
+    std::string const buildName = compilePP
+      ? this->LanguagePreprocessRule(language, config)
+      : this->LanguageDependencyRule(language, config);
+
+    const auto depExtension = compilePP ? ".pp.d" : ".d";
+    const std::string depFileName =
+      this->GetLocalGenerator()->ConvertToOutputFormat(
+        cmStrCat(objectFileName, depExtension), cmOutputConverter::SHELL);
+
+    cmNinjaBuild ppBuild = GetPreprocessOrScanBuild(
+      buildName, ppFileName, compilePP, compilePPWithDefines, objBuild, vars,
+      depFileName, needDyndep, objectFileName);
 
     if (compilePP) {
       // In case compilation requires flags that are incompatible with
       // preprocessing, include them here.
       std::string const& postFlag = this->Makefile->GetSafeDefinition(
-        "CMAKE_" + language + "_POSTPROCESS_FLAG");
+        cmStrCat("CMAKE_", language, "_POSTPROCESS_FLAG"));
       this->LocalGenerator->AppendFlags(vars["FLAGS"], postFlag);
-    }
 
-    if (compilePP && !compilePPWithDefines) {
-      // Move preprocessor definitions to the preprocessor build statement.
-      std::swap(ppBuild.Variables["DEFINES"], vars["DEFINES"]);
-    } else {
-      // Copy preprocessor definitions to the preprocessor build statement.
-      ppBuild.Variables["DEFINES"] = vars["DEFINES"];
-    }
-
-    // Copy include directories to the preprocessor build statement.  The
-    // Fortran compilation build statement still needs them for the INCLUDE
-    // directive.
-    ppBuild.Variables["INCLUDES"] = vars["INCLUDES"];
-
-    if (compilePP) {
       // Prepend source file's original directory as an include directory
       // so e.g. Fortran INCLUDE statements can look for files in it.
       std::vector<std::string> sourceDirectory;
@@ -1158,31 +1327,12 @@
         sourceDirectory, this->GeneratorTarget, language, false, false,
         config);
 
-      vars["INCLUDES"] = sourceDirectoryFlag + " " + vars["INCLUDES"];
+      vars["INCLUDES"] = cmStrCat(sourceDirectoryFlag, ' ', vars["INCLUDES"]);
     }
 
-    // Explicit preprocessing always uses a depfile.
-    ppBuild.Variables["DEP_FILE"] =
-      this->GetLocalGenerator()->ConvertToOutputFormat(
-        objectFileName + ".pp.d", cmOutputConverter::SHELL);
-    if (compilePP) {
-      // The actual compilation does not need a depfile because it
-      // depends on the already-preprocessed source.
-      vars.erase("DEP_FILE");
-    }
-
-    if (needDyndep) {
-      // Tell dependency scanner the object file that will result from
-      // compiling the source.
-      ppBuild.Variables["OBJ_FILE"] = objectFileName;
-
-      // Tell dependency scanner where to store dyndep intermediate results.
-      std::string const ddiFile = objectFileName + ".ddi";
-      ppBuild.Variables["DYNDEP_INTERMEDIATE_FILE"] = ddiFile;
-      ppBuild.ImplicitOuts.push_back(ddiFile);
-      if (firstForConfig) {
-        this->Configs[config].DDIFiles[language].push_back(ddiFile);
-      }
+    if (firstForConfig && needDyndep) {
+      std::string const ddiFile = cmStrCat(objectFileName, ".ddi");
+      this->Configs[config].DDIFiles[language].push_back(ddiFile);
     }
 
     this->addPoolNinjaVariable("JOB_POOL_COMPILE", this->GetGeneratorTarget(),
@@ -1207,8 +1357,9 @@
   this->addPoolNinjaVariable("JOB_POOL_COMPILE", this->GetGeneratorTarget(),
                              vars);
 
-  if (!pchSource.empty() && !source->GetProperty("SKIP_PRECOMPILE_HEADERS")) {
-    if (source->GetFullPath() == pchSource) {
+  if (!pchSources.empty() && !source->GetProperty("SKIP_PRECOMPILE_HEADERS")) {
+    auto pchIt = pchSources.find(source->GetFullPath());
+    if (pchIt != pchSources.end()) {
       this->addPoolNinjaVariable("JOB_POOL_PRECOMPILE_HEADER",
                                  this->GetGeneratorTarget(), vars);
     }
@@ -1216,7 +1367,7 @@
 
   this->SetMsvcTargetPdbVariable(vars, config);
 
-  objBuild.RspFile = objectFileName + ".rsp";
+  objBuild.RspFile = cmStrCat(objectFileName, ".rsp");
 
   if (language == "Swift") {
     this->EmitSwiftDependencyInfo(source, config);
@@ -1225,15 +1376,20 @@
                                            objBuild, commandLineLengthLimit);
   }
 
-  if (const char* objectOutputs = source->GetProperty("OBJECT_OUTPUTS")) {
-    cmNinjaBuild build("phony");
-    build.Comment = "Additional output files.";
-    build.Outputs = cmExpandedList(objectOutputs);
-    std::transform(build.Outputs.begin(), build.Outputs.end(),
-                   build.Outputs.begin(), MapToNinjaPath());
-    build.ExplicitDeps = objBuild.Outputs;
-    this->GetGlobalGenerator()->WriteBuild(this->GetImplFileStream(fileConfig),
-                                           build);
+  if (cmProp objectOutputs = source->GetProperty("OBJECT_OUTPUTS")) {
+    std::string evaluatedObjectOutputs = cmGeneratorExpression::Evaluate(
+      *objectOutputs, this->LocalGenerator, config);
+
+    if (!evaluatedObjectOutputs.empty()) {
+      cmNinjaBuild build("phony");
+      build.Comment = "Additional output files.";
+      build.Outputs = cmExpandedList(evaluatedObjectOutputs);
+      std::transform(build.Outputs.begin(), build.Outputs.end(),
+                     build.Outputs.begin(), MapToNinjaPath());
+      build.ExplicitDeps = objBuild.Outputs;
+      this->GetGlobalGenerator()->WriteBuild(
+        this->GetImplFileStream(fileConfig), build);
+    }
   }
 }
 
@@ -1242,8 +1398,8 @@
 {
   Json::Value tdi(Json::objectValue);
   tdi["language"] = lang;
-  tdi["compiler-id"] =
-    this->Makefile->GetSafeDefinition("CMAKE_" + lang + "_COMPILER_ID");
+  tdi["compiler-id"] = this->Makefile->GetSafeDefinition(
+    cmStrCat("CMAKE_", lang, "_COMPILER_ID"));
 
   if (lang == "Fortran") {
     std::string mod_dir = this->GeneratorTarget->GetFortranModuleDirectory(
@@ -1292,16 +1448,16 @@
   std::string const objectFilePath =
     this->ConvertToNinjaPath(this->GetObjectFilePath(source, config));
   std::string const swiftDepsPath = [source, objectFilePath]() -> std::string {
-    if (const char* name = source->GetProperty("Swift_DEPENDENCIES_FILE")) {
-      return name;
+    if (cmProp name = source->GetProperty("Swift_DEPENDENCIES_FILE")) {
+      return *name;
     }
-    return objectFilePath + ".swiftdeps";
+    return cmStrCat(objectFilePath, ".swiftdeps");
   }();
   std::string const swiftDiaPath = [source, objectFilePath]() -> std::string {
-    if (const char* name = source->GetProperty("Swift_DIAGNOSTICS_FILE")) {
-      return name;
+    if (cmProp name = source->GetProperty("Swift_DIAGNOSTICS_FILE")) {
+      return *name;
     }
-    return objectFilePath + ".dia";
+    return cmStrCat(objectFilePath, ".dia");
   }();
   std::string const makeDepsPath = [this, source, config]() -> std::string {
     cmLocalNinjaGenerator const* local = this->GetLocalGenerator();
@@ -1311,12 +1467,13 @@
       cmSystemTools::GetFilenamePath(objectFileName);
 
     if (this->Makefile->IsOn("CMAKE_Swift_DEPFLE_EXTNSION_REPLACE")) {
-      std::string dependFileName =
-        cmSystemTools::GetFilenameWithoutLastExtension(objectFileName) + ".d";
-      return local->ConvertToOutputFormat(objectFileDir + "/" + dependFileName,
-                                          cmOutputConverter::SHELL);
+      std::string dependFileName = cmStrCat(
+        cmSystemTools::GetFilenameWithoutLastExtension(objectFileName), ".d");
+      return local->ConvertToOutputFormat(
+        cmStrCat(objectFileDir, '/', dependFileName),
+        cmOutputConverter::SHELL);
     }
-    return local->ConvertToOutputFormat(objectFileName + ".d",
+    return local->ConvertToOutputFormat(cmStrCat(objectFileName, ".d"),
                                         cmOutputConverter::SHELL);
   }();
 
@@ -1381,7 +1538,7 @@
       this->GetMakefile()->GetRequiredDefinition(cmdVar);
     cmExpandList(compileCmd, compileCmds);
   } else {
-    const std::string cmdVar = "CMAKE_" + language + "_COMPILE_OBJECT";
+    const std::string cmdVar = cmStrCat("CMAKE_", language, "_COMPILE_OBJECT");
     const std::string& compileCmd =
       this->GetMakefile()->GetRequiredDefinition(cmdVar);
     cmExpandList(compileCmd, compileCmds);
@@ -1404,11 +1561,11 @@
 
 void cmNinjaTargetGenerator::AdditionalCleanFiles(const std::string& config)
 {
-  if (const char* prop_value =
+  if (cmProp prop_value =
         this->GeneratorTarget->GetProperty("ADDITIONAL_CLEAN_FILES")) {
     cmLocalNinjaGenerator* lg = this->LocalGenerator;
     std::vector<std::string> cleanFiles;
-    cmExpandList(cmGeneratorExpression::Evaluate(prop_value, lg, config,
+    cmExpandList(cmGeneratorExpression::Evaluate(*prop_value, lg, config,
                                                  this->GeneratorTarget),
                  cleanFiles);
     std::string const& binaryDir = lg->GetCurrentBinaryDirectory();
@@ -1494,9 +1651,9 @@
   const std::string& pool_property, cmGeneratorTarget* target,
   cmNinjaVars& vars)
 {
-  const char* pool = target->GetProperty(pool_property);
+  cmProp pool = target->GetProperty(pool_property);
   if (pool) {
-    vars["pool"] = pool;
+    vars["pool"] = *pool;
   }
 }
 
diff --git a/Source/cmNinjaTargetGenerator.h b/Source/cmNinjaTargetGenerator.h
index 8678dc3..8d4372e 100644
--- a/Source/cmNinjaTargetGenerator.h
+++ b/Source/cmNinjaTargetGenerator.h
@@ -12,7 +12,7 @@
 #include <utility>
 #include <vector>
 
-#include "cm_jsoncpp_value.h"
+#include <cm3p/json/value.h>
 
 #include "cmCommonTargetGenerator.h"
 #include "cmGlobalNinjaGenerator.h"
@@ -70,6 +70,8 @@
                                    const std::string& config) const;
   std::string LanguagePreprocessRule(std::string const& lang,
                                      const std::string& config) const;
+  std::string LanguageDependencyRule(std::string const& lang,
+                                     const std::string& config) const;
   bool NeedExplicitPreprocessing(std::string const& lang) const;
   std::string LanguageDyndepRule(std::string const& lang,
                                  const std::string& config) const;
diff --git a/Source/cmNinjaUtilityTargetGenerator.cxx b/Source/cmNinjaUtilityTargetGenerator.cxx
index 6e39242..9508bb9 100644
--- a/Source/cmNinjaUtilityTargetGenerator.cxx
+++ b/Source/cmNinjaUtilityTargetGenerator.cxx
@@ -17,6 +17,7 @@
 #include "cmLocalNinjaGenerator.h"
 #include "cmNinjaTypes.h"
 #include "cmOutputConverter.h"
+#include "cmProperty.h"
 #include "cmSourceFile.h"
 #include "cmStateTypes.h"
 #include "cmStringAlgorithms.h"
@@ -100,7 +101,8 @@
     lg->AppendTargetOutputs(genTarget, gg->GetByproductsForCleanTarget(),
                             config);
   }
-  lg->AppendTargetDepends(genTarget, deps, config, config);
+  lg->AppendTargetDepends(genTarget, deps, config, config,
+                          DependOnTargetArtifact);
 
   if (commands.empty()) {
     phonyBuild.Comment = "Utility command for " + this->GetTargetName();
@@ -110,9 +112,9 @@
     std::string command =
       lg->BuildCommandLine(commands, "utility", this->GeneratorTarget);
     std::string desc;
-    const char* echoStr = genTarget->GetProperty("EchoString");
+    cmProp echoStr = genTarget->GetProperty("EchoString");
     if (echoStr) {
-      desc = echoStr;
+      desc = *echoStr;
     } else {
       desc = "Running utility command for " + this->GetTargetName();
     }
diff --git a/Source/cmOSXBundleGenerator.cxx b/Source/cmOSXBundleGenerator.cxx
index 382b563..7eea4b2 100644
--- a/Source/cmOSXBundleGenerator.cxx
+++ b/Source/cmOSXBundleGenerator.cxx
@@ -56,9 +56,9 @@
   outpath = out;
 }
 
-void cmOSXBundleGenerator::CreateFramework(const std::string& targetName,
-                                           const std::string& outpath,
-                                           const std::string& config)
+void cmOSXBundleGenerator::CreateFramework(
+  const std::string& targetName, const std::string& outpath,
+  const std::string& config, const cmOSXBundleGenerator::SkipParts& skipParts)
 {
   if (this->MustSkip()) {
     return;
@@ -77,16 +77,18 @@
 
   std::string frameworkVersion = this->GT->GetFrameworkVersion();
 
-  // Configure the Info.plist file
-  std::string plist = newoutpath;
-  if (!this->Makefile->PlatformIsAppleEmbedded()) {
-    // Put the Info.plist file into the Resources directory.
-    this->MacContentFolders->insert("Resources");
-    plist += "/Resources";
-  }
-  plist += "/Info.plist";
   std::string name = cmSystemTools::GetFilenameName(targetName);
-  this->LocalGenerator->GenerateFrameworkInfoPList(this->GT, name, plist);
+  if (!skipParts.infoPlist) {
+    // Configure the Info.plist file
+    std::string plist = newoutpath;
+    if (!this->Makefile->PlatformIsAppleEmbedded()) {
+      // Put the Info.plist file into the Resources directory.
+      this->MacContentFolders->insert("Resources");
+      plist += "/Resources";
+    }
+    plist += "/Info.plist";
+    this->LocalGenerator->GenerateFrameworkInfoPList(this->GT, name, plist);
+  }
 
   // Generate Versions directory only for MacOSX frameworks
   if (this->Makefile->PlatformIsAppleEmbedded()) {
diff --git a/Source/cmOSXBundleGenerator.h b/Source/cmOSXBundleGenerator.h
index 232be48..5bf1d98 100644
--- a/Source/cmOSXBundleGenerator.h
+++ b/Source/cmOSXBundleGenerator.h
@@ -19,6 +19,15 @@
 public:
   cmOSXBundleGenerator(cmGeneratorTarget* target);
 
+  struct SkipParts
+  {
+    SkipParts()
+      : infoPlist(false)
+    {
+    }
+    bool infoPlist; // NOLINT(modernize-use-default-member-init)
+  };
+
   // create an app bundle at a given root, and return
   // the directory within the bundle that contains the executable
   void CreateAppBundle(const std::string& targetName, std::string& root,
@@ -26,7 +35,8 @@
 
   // create a framework at a given root
   void CreateFramework(const std::string& targetName, const std::string& root,
-                       const std::string& config);
+                       const std::string& config,
+                       const SkipParts& skipParts = SkipParts());
 
   // create a cf bundle at a given root
   void CreateCFBundle(const std::string& targetName, const std::string& root,
diff --git a/Source/cmOptionCommand.cxx b/Source/cmOptionCommand.cxx
index 22e59ac..a58e2f8 100644
--- a/Source/cmOptionCommand.cxx
+++ b/Source/cmOptionCommand.cxx
@@ -6,6 +6,7 @@
 #include "cmMakefile.h"
 #include "cmMessageType.h"
 #include "cmPolicies.h"
+#include "cmProperty.h"
 #include "cmState.h"
 #include "cmStateSnapshot.h"
 #include "cmStateTypes.h"
@@ -52,7 +53,7 @@
   // See if a cache variable with this name already exists
   // If so just make sure the doc state is correct
   cmState* state = status.GetMakefile().GetState();
-  const char* existingValue = state->GetCacheEntryValue(args[0]);
+  cmProp existingValue = state->GetCacheEntryValue(args[0]);
   if (existingValue &&
       (state->GetCacheEntryType(args[0]) != cmStateEnums::UNINITIALIZED)) {
     state->SetCacheEntryProperty(args[0], "HELPSTRING", args[1]);
@@ -60,7 +61,7 @@
   }
 
   // Nothing in the cache so add it
-  std::string initialValue = existingValue ? existingValue : "Off";
+  std::string initialValue = existingValue ? *existingValue : "Off";
   if (args.size() == 3) {
     initialValue = args[2];
   }
diff --git a/Source/cmOutputConverter.cxx b/Source/cmOutputConverter.cxx
index 1c6fad1..359e9f5 100644
--- a/Source/cmOutputConverter.cxx
+++ b/Source/cmOutputConverter.cxx
@@ -26,7 +26,7 @@
   // already exists, we can use a short-path to reference it without a
   // space.
   if (this->GetState()->UseWindowsShell() &&
-      remote.find(' ') != std::string::npos &&
+      remote.find_first_of(" #") != std::string::npos &&
       cmSystemTools::FileExists(remote)) {
     std::string tmp;
     if (cmSystemTools::GetShortPath(remote, tmp)) {
@@ -170,13 +170,15 @@
   return format;
 }
 
-cmOutputConverter::FortranFormat cmOutputConverter::GetFortranFormat(
-  const char* value)
+cmOutputConverter::FortranPreprocess cmOutputConverter::GetFortranPreprocess(
+  cm::string_view value)
 {
-  if (!value) {
-    return FortranFormatNone;
+  if (value.empty()) {
+    return FortranPreprocess::Unset;
   }
-  return GetFortranFormat(cm::string_view(value));
+
+  return cmIsOn(value) ? FortranPreprocess::Needed
+                       : FortranPreprocess::NotNeeded;
 }
 
 void cmOutputConverter::SetLinkScriptShell(bool linkScriptShell)
diff --git a/Source/cmOutputConverter.h b/Source/cmOutputConverter.h
index 6583ab5..a8b4528 100644
--- a/Source/cmOutputConverter.h
+++ b/Source/cmOutputConverter.h
@@ -94,7 +94,14 @@
     FortranFormatFree
   };
   static FortranFormat GetFortranFormat(cm::string_view value);
-  static FortranFormat GetFortranFormat(const char* value);
+
+  enum class FortranPreprocess
+  {
+    Unset,
+    NotNeeded,
+    Needed
+  };
+  static FortranPreprocess GetFortranPreprocess(cm::string_view value);
 
 private:
   cmState* GetState() const;
diff --git a/Source/cmOutputRequiredFilesCommand.cxx b/Source/cmOutputRequiredFilesCommand.cxx
index 147f97f..aa5abcb 100644
--- a/Source/cmOutputRequiredFilesCommand.cxx
+++ b/Source/cmOutputRequiredFilesCommand.cxx
@@ -15,6 +15,7 @@
 #include "cmExecutionStatus.h"
 #include "cmGeneratorExpression.h"
 #include "cmMakefile.h"
+#include "cmProperty.h"
 #include "cmSourceFile.h"
 #include "cmStringAlgorithms.h"
 #include "cmSystemTools.h"
@@ -117,14 +118,13 @@
     std::set<std::string> uniqueIncludes;
     std::vector<std::string> orderedAndUniqueIncludes;
     for (auto const& target : this->Makefile->GetTargets()) {
-      const char* incDirProp =
-        target.second.GetProperty("INCLUDE_DIRECTORIES");
+      cmProp incDirProp = target.second.GetProperty("INCLUDE_DIRECTORIES");
       if (!incDirProp) {
         continue;
       }
 
       std::string incDirs = cmGeneratorExpression::Preprocess(
-        incDirProp, cmGeneratorExpression::StripAllGeneratorExpressions);
+        *incDirProp, cmGeneratorExpression::StripAllGeneratorExpressions);
 
       std::vector<std::string> includes = cmExpandedList(incDirs);
 
diff --git a/Source/cmPipeConnection.h b/Source/cmPipeConnection.h
index 81f8a49..1215716 100644
--- a/Source/cmPipeConnection.h
+++ b/Source/cmPipeConnection.h
@@ -6,7 +6,7 @@
 
 #include <string>
 
-#include "cm_uv.h"
+#include <cm3p/uv.h>
 
 #include "cmConnection.h"
 #include "cmUVHandlePtr.h"
diff --git a/Source/cmPolicies.cxx b/Source/cmPolicies.cxx
index 5c8bc98..01e8c04 100644
--- a/Source/cmPolicies.cxx
+++ b/Source/cmPolicies.cxx
@@ -7,9 +7,11 @@
 #include <sstream>
 #include <vector>
 
+#include "cmListFileCache.h"
 #include "cmMakefile.h"
 #include "cmMessageType.h"
 #include "cmState.h"
+#include "cmStateSnapshot.h"
 #include "cmStateTypes.h"
 #include "cmStringAlgorithms.h"
 #include "cmSystemTools.h"
@@ -72,6 +74,7 @@
 #define POLICY_CASE(ID, V_MAJOR, V_MINOR, V_PATCH)                            \
   case cmPolicies::ID:                                                        \
     return #V_MAJOR "." #V_MINOR "." #V_PATCH;
+    // NOLINTNEXTLINE(bugprone-branch-clone)
     CM_FOR_EACH_POLICY_ID_VERSION(POLICY_CASE)
 #undef POLICY_CASE
     case cmPolicies::CMPCOUNT:
@@ -90,6 +93,7 @@
             (majorV == (V_MAJOR) && minorV + 1 < (V_MINOR) + 1) ||            \
             (majorV == (V_MAJOR) && minorV == (V_MINOR) &&                    \
              patchV + 1 < (V_PATCH) + 1));
+    // NOLINTNEXTLINE(bugprone-branch-clone)
     CM_FOR_EACH_POLICY_ID_VERSION(POLICY_CASE)
 #undef POLICY_CASE
     case cmPolicies::CMPCOUNT:
@@ -155,7 +159,8 @@
 
 bool cmPolicies::ApplyPolicyVersion(cmMakefile* mf,
                                     std::string const& version_min,
-                                    std::string const& version_max)
+                                    std::string const& version_max,
+                                    WarnCompat warnCompat)
 {
   // Parse components of the minimum version.
   unsigned int minMajor = 2;
@@ -242,13 +247,34 @@
     polPatch = maxPatch;
   }
 
-  return cmPolicies::ApplyPolicyVersion(mf, polMajor, polMinor, polPatch);
+  return cmPolicies::ApplyPolicyVersion(mf, polMajor, polMinor, polPatch,
+                                        warnCompat);
 }
 
 bool cmPolicies::ApplyPolicyVersion(cmMakefile* mf, unsigned int majorVer,
                                     unsigned int minorVer,
-                                    unsigned int patchVer)
+                                    unsigned int patchVer,
+                                    WarnCompat warnCompat)
 {
+  // Warn about policy versions for which support will be removed.
+  if (warnCompat == WarnCompat::On &&
+      (majorVer < 2 || (majorVer == 2 && minorVer < 8) ||
+       (majorVer == 2 && minorVer == 8 && patchVer < 12)) &&
+      // Avoid warning on calls generated by install(EXPORT)
+      // in CMake versions prior to 3.18.
+      !(majorVer == 2 && minorVer == 6 && patchVer == 0 &&
+        mf->GetStateSnapshot().CanPopPolicyScope() &&
+        cmSystemTools::Strucmp(mf->GetBacktrace().Top().Name.c_str(),
+                               "cmake_policy") == 0)) {
+    mf->IssueMessage(
+      MessageType::DEPRECATION_WARNING,
+      "Compatibility with CMake < 2.8.12 will be removed from "
+      "a future version of CMake.\n"
+      "Update the VERSION argument <min> value or use a ...<max> suffix "
+      "to tell CMake that the project does not need compatibility with "
+      "older versions.");
+  }
+
   // now loop over all the policies and set them as appropriate
   std::vector<cmPolicies::PolicyID> ancientPolicies;
   for (PolicyID pid = cmPolicies::CMP0000; pid != cmPolicies::CMPCOUNT;
diff --git a/Source/cmPolicies.h b/Source/cmPolicies.h
index 1366ff0..bba8b03 100644
--- a/Source/cmPolicies.h
+++ b/Source/cmPolicies.h
@@ -305,7 +305,25 @@
          17, 0, cmPolicies::WARN)                                             \
   SELECT(POLICY, CMP0102,                                                     \
          "mark_as_advanced() does nothing if a cache entry does not exist.",  \
-         3, 17, 0, cmPolicies::WARN)
+         3, 17, 0, cmPolicies::WARN)                                          \
+  SELECT(POLICY, CMP0103,                                                     \
+         "Multiple export() with same FILE without APPEND is not allowed.",   \
+         3, 18, 0, cmPolicies::WARN)                                          \
+  SELECT(POLICY, CMP0104,                                                     \
+         "CMAKE_CUDA_ARCHITECTURES now detected for NVCC, empty "             \
+         "CUDA_ARCHITECTURES not allowed.",                                   \
+         3, 18, 0, cmPolicies::WARN)                                          \
+  SELECT(POLICY, CMP0105, "Device link step uses the link options.", 3, 18,   \
+         0, cmPolicies::WARN)                                                 \
+  SELECT(POLICY, CMP0106, "The Documentation module is removed.", 3, 18, 0,   \
+         cmPolicies::WARN)                                                    \
+  SELECT(POLICY, CMP0107, "An ALIAS target cannot overwrite another target.", \
+         3, 18, 0, cmPolicies::WARN)                                          \
+  SELECT(POLICY, CMP0108, "A target cannot link to itself through an alias.", \
+         3, 18, 0, cmPolicies::WARN)                                          \
+  SELECT(POLICY, CMP0109,                                                     \
+         "find_program() requires permission to execute but not to read.", 3, \
+         19, 0, cmPolicies::WARN)
 
 #define CM_SELECT_ID(F, A1, A2, A3, A4, A5, A6) F(A1)
 #define CM_FOR_EACH_POLICY_ID(POLICY)                                         \
@@ -335,7 +353,10 @@
   F(CMP0081)                                                                  \
   F(CMP0083)                                                                  \
   F(CMP0095)                                                                  \
-  F(CMP0099)
+  F(CMP0099)                                                                  \
+  F(CMP0104)                                                                  \
+  F(CMP0105)                                                                  \
+  F(CMP0108)
 
 /** \class cmPolicies
  * \brief Handles changes in CMake behavior and policies
@@ -378,12 +399,20 @@
   //! Get the default status for a policy
   static cmPolicies::PolicyStatus GetPolicyStatus(cmPolicies::PolicyID id);
 
+  enum class WarnCompat
+  {
+    Off,
+    On
+  };
+
   //! Set a policy level for this listfile
   static bool ApplyPolicyVersion(cmMakefile* mf,
                                  std::string const& version_min,
-                                 std::string const& version_max);
+                                 std::string const& version_max,
+                                 WarnCompat warnCompat);
   static bool ApplyPolicyVersion(cmMakefile* mf, unsigned int majorVer,
-                                 unsigned int minorVer, unsigned int patchVer);
+                                 unsigned int minorVer, unsigned int patchVer,
+                                 WarnCompat warnCompat);
 
   //! return a warning string for a given policy
   static std::string GetPolicyWarning(cmPolicies::PolicyID id);
diff --git a/Source/cmProcessOutput.cxx b/Source/cmProcessOutput.cxx
index e80ea5c..0fb4ff7 100644
--- a/Source/cmProcessOutput.cxx
+++ b/Source/cmProcessOutput.cxx
@@ -4,7 +4,10 @@
 #include "cmProcessOutput.h"
 
 #if defined(_WIN32)
+#  include <cm/memory>
+
 #  include <windows.h>
+
 unsigned int cmProcessOutput::defaultCodepage =
   KWSYS_ENCODING_DEFAULT_CODEPAGE;
 #endif
@@ -143,9 +146,9 @@
   bool success = false;
   const int wlength =
     MultiByteToWideChar(codepage, 0, raw.c_str(), int(raw.size()), NULL, 0);
-  wchar_t* wdata = new wchar_t[wlength];
-  int r = MultiByteToWideChar(codepage, 0, raw.c_str(), int(raw.size()), wdata,
-                              wlength);
+  auto wdata = cm::make_unique<wchar_t[]>(wlength);
+  int r = MultiByteToWideChar(codepage, 0, raw.c_str(), int(raw.size()),
+                              wdata.get(), wlength);
   if (r > 0) {
     if (lastChar) {
       *lastChar = 0;
@@ -154,18 +157,16 @@
         *lastChar = wdata[wlength - 1];
       }
     }
-    int length = WideCharToMultiByte(defaultCodepage, 0, wdata, wlength, NULL,
-                                     0, NULL, NULL);
-    char* data = new char[length];
-    r = WideCharToMultiByte(defaultCodepage, 0, wdata, wlength, data, length,
-                            NULL, NULL);
+    int length = WideCharToMultiByte(defaultCodepage, 0, wdata.get(), wlength,
+                                     NULL, 0, NULL, NULL);
+    auto data = cm::make_unique<char[]>(length);
+    r = WideCharToMultiByte(defaultCodepage, 0, wdata.get(), wlength,
+                            data.get(), length, NULL, NULL);
     if (r > 0) {
-      decoded = std::string(data, length);
+      decoded = std::string(data.get(), length);
       success = true;
     }
-    delete[] data;
   }
-  delete[] wdata;
   return success;
 }
 #endif
diff --git a/Source/cmProjectCommand.cxx b/Source/cmProjectCommand.cxx
index a25fd42..bb6db92 100644
--- a/Source/cmProjectCommand.cxx
+++ b/Source/cmProjectCommand.cxx
@@ -47,10 +47,10 @@
   mf.SetProjectName(projectName);
 
   mf.AddCacheDefinition(projectName + "_BINARY_DIR",
-                        mf.GetCurrentBinaryDirectory().c_str(),
+                        mf.GetCurrentBinaryDirectory(),
                         "Value Computed by CMake", cmStateEnums::STATIC);
   mf.AddCacheDefinition(projectName + "_SOURCE_DIR",
-                        mf.GetCurrentSourceDirectory().c_str(),
+                        mf.GetCurrentSourceDirectory(),
                         "Value Computed by CMake", cmStateEnums::STATIC);
 
   mf.AddDefinition("PROJECT_BINARY_DIR", mf.GetCurrentBinaryDirectory());
@@ -66,7 +66,7 @@
   // will work.
   if (!mf.GetDefinition("CMAKE_PROJECT_NAME") || mf.IsRootMakefile()) {
     mf.AddDefinition("CMAKE_PROJECT_NAME", projectName);
-    mf.AddCacheDefinition("CMAKE_PROJECT_NAME", projectName.c_str(),
+    mf.AddCacheDefinition("CMAKE_PROJECT_NAME", projectName,
                           "Value Computed by CMake", cmStateEnums::STATIC);
   }
 
@@ -303,7 +303,7 @@
     std::string vw;
     for (std::string const& i : vv) {
       const char* const v = mf.GetDefinition(i);
-      if (v && *v) {
+      if (cmNonempty(v)) {
         if (cmp0048 == cmPolicies::WARN) {
           if (!injectedProjectCommand) {
             vw += "\n  ";
@@ -379,7 +379,7 @@
   // CMakeLists.txt file, then go with the last one.
   if (!mf.GetDefinition(name) || mf.IsRootMakefile()) {
     mf.AddDefinition(name, value);
-    mf.AddCacheDefinition(name, value.c_str(), "Value Computed by CMake",
+    mf.AddCacheDefinition(name, value, "Value Computed by CMake",
                           cmStateEnums::STATIC);
   }
 }
diff --git a/Source/cmProperty.h b/Source/cmProperty.h
index 80f131a..b0fcce7 100644
--- a/Source/cmProperty.h
+++ b/Source/cmProperty.h
@@ -5,6 +5,8 @@
 
 #include "cmConfigure.h" // IWYU pragma: keep
 
+#include <string>
+
 class cmProperty
 {
 public:
@@ -22,4 +24,6 @@
   };
 };
 
+using cmProp = const std::string*;
+
 #endif
diff --git a/Source/cmPropertyDefinition.cxx b/Source/cmPropertyDefinition.cxx
index 6a3174c..1796bb8 100644
--- a/Source/cmPropertyDefinition.cxx
+++ b/Source/cmPropertyDefinition.cxx
@@ -2,19 +2,38 @@
    file Copyright.txt or https://cmake.org/licensing for details.  */
 #include "cmPropertyDefinition.h"
 
-void cmPropertyDefinition::DefineProperty(const std::string& name,
-                                          cmProperty::ScopeType scope,
-                                          const char* shortDescription,
-                                          const char* fullDescription,
-                                          bool chain)
+#include <tuple>
+
+cmPropertyDefinition::cmPropertyDefinition(std::string shortDescription,
+                                           std::string fullDescription,
+                                           bool chained)
+  : ShortDescription(std::move(shortDescription))
+  , FullDescription(std::move(fullDescription))
+  , Chained(chained)
 {
-  this->Name = name;
-  this->Scope = scope;
-  this->Chained = chain;
-  if (shortDescription) {
-    this->ShortDescription = shortDescription;
+}
+
+void cmPropertyDefinitionMap::DefineProperty(
+  const std::string& name, cmProperty::ScopeType scope,
+  const std::string& ShortDescription, const std::string& FullDescription,
+  bool chain)
+{
+  auto it = this->Map_.find(key_type(name, scope));
+  if (it == this->Map_.end()) {
+    // try_emplace() since C++17
+    this->Map_.emplace(
+      std::piecewise_construct, std::forward_as_tuple(name, scope),
+      std::forward_as_tuple(ShortDescription, FullDescription, chain));
   }
-  if (fullDescription) {
-    this->FullDescription = fullDescription;
+}
+
+cmPropertyDefinition const* cmPropertyDefinitionMap::GetPropertyDefinition(
+  const std::string& name, cmProperty::ScopeType scope) const
+{
+  auto it = this->Map_.find(key_type(name, scope));
+  if (it != this->Map_.end()) {
+    return &it->second;
   }
+
+  return nullptr;
 }
diff --git a/Source/cmPropertyDefinition.h b/Source/cmPropertyDefinition.h
index 0d68c32..f83bc4f 100644
--- a/Source/cmPropertyDefinition.h
+++ b/Source/cmPropertyDefinition.h
@@ -5,7 +5,9 @@
 
 #include "cmConfigure.h" // IWYU pragma: keep
 
+#include <map>
 #include <string>
+#include <utility>
 
 #include "cmProperty.h"
 
@@ -13,28 +15,19 @@
  * \brief Property meta-information
  *
  * This class contains the following meta-information about property:
- * - Name;
  * - Various documentation strings;
- * - The scope of the property;
  * - If the property is chained.
  */
 class cmPropertyDefinition
 {
 public:
-  /// Define this property
-  void DefineProperty(const std::string& name, cmProperty::ScopeType scope,
-                      const char* ShortDescription,
-                      const char* FullDescription, bool chained);
-
-  /// Default constructor
-  cmPropertyDefinition() { this->Chained = false; }
+  /// Constructor
+  cmPropertyDefinition(std::string shortDescription,
+                       std::string fullDescription, bool chained);
 
   /// Is the property chained?
   bool IsChained() const { return this->Chained; }
 
-  /// Get the scope
-  cmProperty::ScopeType GetScope() const { return this->Scope; }
-
   /// Get the documentation (short version)
   const std::string& GetShortDescription() const
   {
@@ -47,12 +40,30 @@
     return this->FullDescription;
   }
 
-protected:
-  std::string Name;
+private:
   std::string ShortDescription;
   std::string FullDescription;
-  cmProperty::ScopeType Scope;
   bool Chained;
 };
 
+/** \class cmPropertyDefinitionMap
+ * \brief Map property name and scope to their definition
+ */
+class cmPropertyDefinitionMap
+{
+public:
+  // define the property
+  void DefineProperty(const std::string& name, cmProperty::ScopeType scope,
+                      const std::string& ShortDescription,
+                      const std::string& FullDescription, bool chain);
+
+  // get the property definition if present, otherwise nullptr
+  cmPropertyDefinition const* GetPropertyDefinition(
+    const std::string& name, cmProperty::ScopeType scope) const;
+
+private:
+  using key_type = std::pair<std::string, cmProperty::ScopeType>;
+  std::map<key_type, cmPropertyDefinition> Map_;
+};
+
 #endif
diff --git a/Source/cmPropertyDefinitionMap.cxx b/Source/cmPropertyDefinitionMap.cxx
deleted file mode 100644
index f752ed7..0000000
--- a/Source/cmPropertyDefinitionMap.cxx
+++ /dev/null
@@ -1,35 +0,0 @@
-/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
-   file Copyright.txt or https://cmake.org/licensing for details.  */
-#include "cmPropertyDefinitionMap.h"
-
-#include <utility>
-
-void cmPropertyDefinitionMap::DefineProperty(const std::string& name,
-                                             cmProperty::ScopeType scope,
-                                             const char* ShortDescription,
-                                             const char* FullDescription,
-                                             bool chain)
-{
-  auto it = this->find(name);
-  cmPropertyDefinition* prop;
-  if (it == this->end()) {
-    prop = &(*this)[name];
-    prop->DefineProperty(name, scope, ShortDescription, FullDescription,
-                         chain);
-  }
-}
-
-bool cmPropertyDefinitionMap::IsPropertyDefined(const std::string& name) const
-{
-  return this->find(name) != this->end();
-}
-
-bool cmPropertyDefinitionMap::IsPropertyChained(const std::string& name) const
-{
-  auto it = this->find(name);
-  if (it == this->end()) {
-    return false;
-  }
-
-  return it->second.IsChained();
-}
diff --git a/Source/cmPropertyDefinitionMap.h b/Source/cmPropertyDefinitionMap.h
deleted file mode 100644
index 8ec7910..0000000
--- a/Source/cmPropertyDefinitionMap.h
+++ /dev/null
@@ -1,30 +0,0 @@
-/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
-   file Copyright.txt or https://cmake.org/licensing for details.  */
-#ifndef cmPropertyDefinitionMap_h
-#define cmPropertyDefinitionMap_h
-
-#include "cmConfigure.h" // IWYU pragma: keep
-
-#include <map>
-#include <string>
-
-#include "cmProperty.h"
-#include "cmPropertyDefinition.h"
-
-class cmPropertyDefinitionMap
-  : public std::map<std::string, cmPropertyDefinition>
-{
-public:
-  // define the property
-  void DefineProperty(const std::string& name, cmProperty::ScopeType scope,
-                      const char* ShortDescription,
-                      const char* FullDescription, bool chain);
-
-  // has a named property been defined
-  bool IsPropertyDefined(const std::string& name) const;
-
-  // is a named property set to chain
-  bool IsPropertyChained(const std::string& name) const;
-};
-
-#endif
diff --git a/Source/cmPropertyMap.cxx b/Source/cmPropertyMap.cxx
index d4b3552..f22f36d 100644
--- a/Source/cmPropertyMap.cxx
+++ b/Source/cmPropertyMap.cxx
@@ -42,13 +42,11 @@
   Map_.erase(name);
 }
 
-const char* cmPropertyMap::GetPropertyValue(const std::string& name) const
+cmProp cmPropertyMap::GetPropertyValue(const std::string& name) const
 {
-  {
-    auto it = Map_.find(name);
-    if (it != Map_.end()) {
-      return it->second.c_str();
-    }
+  auto it = Map_.find(name);
+  if (it != Map_.end()) {
+    return &it->second;
   }
   return nullptr;
 }
diff --git a/Source/cmPropertyMap.h b/Source/cmPropertyMap.h
index bea4372..5fc46a2 100644
--- a/Source/cmPropertyMap.h
+++ b/Source/cmPropertyMap.h
@@ -10,6 +10,8 @@
 #include <utility>
 #include <vector>
 
+#include "cmProperty.h"
+
 /** \class cmPropertyMap
  * \brief String property map.
  */
@@ -31,7 +33,7 @@
                       bool asString = false);
 
   //! Get the property value
-  const char* GetPropertyValue(const std::string& name) const;
+  cmProp GetPropertyValue(const std::string& name) const;
 
   //! Remove the property @a name from the map
   void RemoveProperty(const std::string& name);
diff --git a/Source/cmQTWrapCPPCommand.cxx b/Source/cmQTWrapCPPCommand.cxx
index cc4df8f..795c2ee 100644
--- a/Source/cmQTWrapCPPCommand.cxx
+++ b/Source/cmQTWrapCPPCommand.cxx
@@ -5,6 +5,7 @@
 #include "cmCustomCommandLines.h"
 #include "cmExecutionStatus.h"
 #include "cmMakefile.h"
+#include "cmProperty.h"
 #include "cmRange.h"
 #include "cmSourceFile.h"
 #include "cmStringAlgorithms.h"
@@ -39,7 +40,8 @@
         cmStrCat(mf.GetCurrentBinaryDirectory(), "/moc_", srcName, ".cxx");
       cmSourceFile* sf = mf.GetOrCreateSource(newName, true);
       if (curr) {
-        sf->SetProperty("ABSTRACT", curr->GetProperty("ABSTRACT"));
+        cmProp p = curr->GetProperty("ABSTRACT");
+        sf->SetProperty("ABSTRACT", p ? p->c_str() : nullptr);
       }
 
       // Compute the name of the header from which to generate the file.
diff --git a/Source/cmQtAutoGen.cxx b/Source/cmQtAutoGen.cxx
index d5891c4..57fcd2d 100644
--- a/Source/cmQtAutoGen.cxx
+++ b/Source/cmQtAutoGen.cxx
@@ -13,7 +13,6 @@
 #include "cmsys/FStream.hxx"
 #include "cmsys/RegularExpression.hxx"
 
-#include "cmAlgorithms.h"
 #include "cmDuration.h"
 #include "cmProcessOutput.h"
 #include "cmStringAlgorithms.h"
@@ -55,7 +54,7 @@
           }
         }
         // Test if this is a value option and change the existing value
-        if (!optName.empty() && cmContains(valueOpts, optName)) {
+        if (!optName.empty() && cm::contains(valueOpts, optName)) {
           const auto existItNext(existIt + 1);
           const auto fitNext(fit + 1);
           if ((existItNext != baseOpts.end()) && (fitNext != fitEnd)) {
diff --git a/Source/cmQtAutoGenGlobalInitializer.cxx b/Source/cmQtAutoGenGlobalInitializer.cxx
index 7a6cb42..fac2bbf 100644
--- a/Source/cmQtAutoGenGlobalInitializer.cxx
+++ b/Source/cmQtAutoGenGlobalInitializer.cxx
@@ -13,6 +13,7 @@
 #include "cmMakefile.h"
 #include "cmMessageType.h"
 #include "cmProcessOutput.h"
+#include "cmProperty.h"
 #include "cmQtAutoGen.h"
 #include "cmQtAutoGenInitializer.h"
 #include "cmState.h"
@@ -49,7 +50,7 @@
     {
       cmMakefile* makefile = localGen->GetMakefile();
       // Detect global autogen target name
-      if (cmIsOn(makefile->GetSafeDefinition("CMAKE_GLOBAL_AUTOGEN_TARGET"))) {
+      if (makefile->IsOn("CMAKE_GLOBAL_AUTOGEN_TARGET")) {
         std::string targetName =
           makefile->GetSafeDefinition("CMAKE_GLOBAL_AUTOGEN_TARGET_NAME");
         if (targetName.empty()) {
@@ -60,7 +61,7 @@
       }
 
       // Detect global autorcc target name
-      if (cmIsOn(makefile->GetSafeDefinition("CMAKE_GLOBAL_AUTORCC_TARGET"))) {
+      if (makefile->IsOn("CMAKE_GLOBAL_AUTORCC_TARGET")) {
         std::string targetName =
           makefile->GetSafeDefinition("CMAKE_GLOBAL_AUTORCC_TARGET_NAME");
         if (targetName.empty()) {
@@ -95,11 +96,11 @@
       bool const uic = target->GetPropertyAsBool(kw().AUTOUIC);
       bool const rcc = target->GetPropertyAsBool(kw().AUTORCC);
       if (moc || uic || rcc) {
-        std::string const mocExec =
+        std::string const& mocExec =
           target->GetSafeProperty(kw().AUTOMOC_EXECUTABLE);
-        std::string const uicExec =
+        std::string const& uicExec =
           target->GetSafeProperty(kw().AUTOUIC_EXECUTABLE);
-        std::string const rccExec =
+        std::string const& rccExec =
           target->GetSafeProperty(kw().AUTORCC_EXECUTABLE);
 
         // We support Qt4, Qt5 and Qt6
@@ -164,10 +165,10 @@
 
     // Set FOLDER property in the target
     {
-      char const* folder =
+      cmProp folder =
         makefile->GetState()->GetGlobalProperty("AUTOGEN_TARGETS_FOLDER");
       if (folder != nullptr) {
-        target->SetProperty("FOLDER", folder);
+        target->SetProperty("FOLDER", *folder);
       }
     }
   }
diff --git a/Source/cmQtAutoGenInitializer.cxx b/Source/cmQtAutoGenInitializer.cxx
index c8caddf..06957b0 100644
--- a/Source/cmQtAutoGenInitializer.cxx
+++ b/Source/cmQtAutoGenInitializer.cxx
@@ -16,13 +16,13 @@
 #include <cm/algorithm>
 #include <cm/iterator>
 #include <cm/memory>
+#include <cmext/algorithm>
+
+#include <cm3p/json/value.h>
+#include <cm3p/json/writer.h>
 
 #include "cmsys/SystemInformation.hxx"
 
-#include "cm_jsoncpp_value.h"
-#include "cm_jsoncpp_writer.h"
-
-#include "cmAlgorithms.h"
 #include "cmCustomCommand.h"
 #include "cmCustomCommandLines.h"
 #include "cmGeneratedFileStream.h"
@@ -35,6 +35,7 @@
 #include "cmMakefile.h"
 #include "cmMessageType.h"
 #include "cmPolicies.h"
+#include "cmProperty.h"
 #include "cmQtAutoGen.h"
 #include "cmQtAutoGenGlobalInitializer.h"
 #include "cmSourceFile.h"
@@ -314,10 +315,9 @@
 {
   // Configurations
   this->MultiConfig = this->GlobalGen->IsMultiConfig();
-  this->ConfigDefault = this->Makefile->GetConfigurations(this->ConfigsList);
-  if (this->ConfigsList.empty()) {
-    this->ConfigsList.push_back(this->ConfigDefault);
-  }
+  this->ConfigDefault = this->Makefile->GetDefaultConfiguration();
+  this->ConfigsList =
+    this->Makefile->GetGeneratorConfigs(cmMakefile::IncludeEmptyConfig);
 
   // Verbosity
   {
@@ -339,7 +339,7 @@
 
   // Targets FOLDER
   {
-    const char* folder =
+    cmProp folder =
       this->Makefile->GetState()->GetGlobalProperty("AUTOMOC_TARGETS_FOLDER");
     if (folder == nullptr) {
       folder = this->Makefile->GetState()->GetGlobalProperty(
@@ -350,7 +350,7 @@
       folder = this->GenTarget->GetProperty("FOLDER");
     }
     if (folder != nullptr) {
-      this->TargetsFolder = folder;
+      this->TargetsFolder = *folder;
     }
   }
 
@@ -440,7 +440,8 @@
 
     // Autogen target parallel processing
     {
-      std::string prop = this->GenTarget->GetSafeProperty("AUTOGEN_PARALLEL");
+      std::string const& prop =
+        this->GenTarget->GetSafeProperty("AUTOGEN_PARALLEL");
       if (prop.empty() || (prop == "AUTO")) {
         // Autodetect number of CPUs
         this->AutogenTarget.Parallel = GetParallelCPUCount();
@@ -471,7 +472,7 @@
       this->AutogenTarget.DependOrigin =
         this->GenTarget->GetPropertyAsBool("AUTOGEN_ORIGIN_DEPENDS");
 
-      std::string const deps =
+      std::string const& deps =
         this->GenTarget->GetSafeProperty("AUTOGEN_TARGET_DEPENDS");
       if (!deps.empty()) {
         for (std::string const& depName : cmExpandedList(deps)) {
@@ -488,7 +489,7 @@
 
     if (this->Moc.Enabled) {
       // Path prefix
-      if (cmIsOn(this->GenTarget->GetSafeProperty("AUTOMOC_PATH_PREFIX"))) {
+      if (cmIsOn(this->GenTarget->GetProperty("AUTOMOC_PATH_PREFIX"))) {
         this->Moc.PathPrefix = true;
       }
 
@@ -569,9 +570,8 @@
   if (this->GenTarget->GetPropertyAsBool("AUTOMOC_COMPILER_PREDEFINES") &&
       (this->QtVersion >= IntegerVersion(5, 8))) {
     // Command
-    cmExpandList(this->Makefile->GetSafeDefinition(
-                   "CMAKE_CXX_COMPILER_PREDEFINES_COMMAND"),
-                 this->Moc.PredefsCmd);
+    this->Makefile->GetDefExpandList("CMAKE_CXX_COMPILER_PREDEFINES_COMMAND",
+                                     this->Moc.PredefsCmd);
     // Header
     if (!this->Moc.PredefsCmd.empty()) {
       ConfigFileNames(this->Moc.PredefsFile,
@@ -654,7 +654,7 @@
 {
   // Uic search paths
   {
-    std::string const usp =
+    std::string const& usp =
       this->GenTarget->GetSafeProperty("AUTOUIC_SEARCH_PATHS");
     if (!usp.empty()) {
       this->Uic.SearchPaths =
@@ -788,9 +788,9 @@
 
       // Register files that will be scanned by moc or uic
       if (this->MocOrUicEnabled()) {
-        if (cm->IsHeaderExtension(extLower)) {
+        if (cm->IsAHeaderExtension(extLower)) {
           addMUHeader(makeMUFile(sf, fullPath, true), extLower);
-        } else if (cm->IsSourceExtension(extLower)) {
+        } else if (cm->IsACLikeSourceExtension(extLower)) {
           addMUSource(makeMUFile(sf, fullPath, true));
         }
       }
@@ -847,7 +847,7 @@
               this->Makefile->GetSource(fullPath, locationKind);
             if (sf != nullptr) {
               // Check if we know about this header already
-              if (cmContains(this->AutogenTarget.Headers, sf)) {
+              if (cm::contains(this->AutogenTarget.Headers, sf)) {
                 continue;
               }
               // We only accept not-GENERATED files that do exist.
@@ -862,7 +862,7 @@
 
             if (sf != nullptr) {
               auto eMuf = makeMUFile(sf, fullPath, true);
-              // Ony process moc/uic when the parent is processed as well
+              // Only process moc/uic when the parent is processed as well
               if (!muf.MocIt) {
                 eMuf->MocIt = false;
               }
@@ -894,15 +894,15 @@
       std::string const& extLower =
         cmSystemTools::LowerCase(sf->GetExtension());
 
-      if (cm->IsHeaderExtension(extLower)) {
-        if (!cmContains(this->AutogenTarget.Headers, sf.get())) {
+      if (cm->IsAHeaderExtension(extLower)) {
+        if (!cm::contains(this->AutogenTarget.Headers, sf.get())) {
           auto muf = makeMUFile(sf.get(), fullPath, false);
           if (muf->SkipMoc || muf->SkipUic) {
             addMUHeader(std::move(muf), extLower);
           }
         }
-      } else if (cm->IsSourceExtension(extLower)) {
-        if (!cmContains(this->AutogenTarget.Sources, sf.get())) {
+      } else if (cm->IsACLikeSourceExtension(extLower)) {
+        if (!cm::contains(this->AutogenTarget.Sources, sf.get())) {
           auto muf = makeMUFile(sf.get(), fullPath, false);
           if (muf->SkipMoc || muf->SkipUic) {
             addMUSource(std::move(muf));
@@ -1094,6 +1094,7 @@
   // of fiddling with the include directories
   std::vector<std::string> configs;
   this->GlobalGen->GetQtAutoGenConfigs(configs);
+  bool stdPipesUTF8 = true;
   cmCustomCommandLines commandLines;
   for (auto const& config : configs) {
     commandLines.push_back(cmMakeCommandLine(
@@ -1138,7 +1139,7 @@
     const std::vector<std::string> no_deps;
     cmCustomCommand cc(no_output, autogenProvides, no_deps, commandLines,
                        this->Makefile->GetBacktrace(), autogenComment.c_str(),
-                       this->Dir.Work.c_str());
+                       this->Dir.Work.c_str(), stdPipesUTF8);
     cc.SetEscapeOldStyle(false);
     cc.SetEscapeAllowMakeVars(true);
     this->GenTarget->Target->AddPreBuildCommand(std::move(cc));
@@ -1251,7 +1252,8 @@
         autogenComment.c_str(), this->Dir.Work.c_str(), /*replace=*/false,
         /*escapeOldStyle=*/false,
         /*uses_terminal=*/false,
-        /*command_expand_lists=*/false, this->AutogenTarget.DepFile);
+        /*command_expand_lists=*/false, this->AutogenTarget.DepFile, "",
+        stdPipesUTF8);
 
       // Alter variables for the autogen target which now merely wraps the
       // custom command
@@ -1322,6 +1324,7 @@
     ccDepends.push_back(qrc.QrcFile);
     ccDepends.push_back(qrc.InfoFile);
 
+    bool stdPipesUTF8 = true;
     cmCustomCommandLines commandLines;
     if (this->MultiConfig) {
       // Build for all configurations
@@ -1350,7 +1353,8 @@
 
         cmTarget* autoRccTarget = this->LocalGen->AddUtilityCommand(
           ccName, true, this->Dir.Work.c_str(), ccOutput, ccDepends,
-          commandLines, false, ccComment.c_str());
+          commandLines, false, ccComment.c_str(), false, false, "",
+          stdPipesUTF8);
 
         // Create autogen generator target
         this->LocalGen->AddGeneratorTarget(
@@ -1390,7 +1394,8 @@
         this->LocalGen->AddCustomCommandToOutput(
           ccOutput, ccByproducts, ccDepends, no_main_dependency,
           no_implicit_depends, commandLines, ccComment.c_str(),
-          this->Dir.Work.c_str());
+          this->Dir.Work.c_str(), false, true, false, false, "", "",
+          stdPipesUTF8);
       }
       // Reconfigure when .qrc file changes
       this->Makefile->AddCMakeDependFile(qrc.QrcFile);
@@ -1647,10 +1652,9 @@
         cmStrCat(genNameUpper, "_SOURCE_GROUP"), "AUTOGEN_SOURCE_GROUP"
       };
       for (std::string const& prop : props) {
-        const char* propName =
-          this->Makefile->GetState()->GetGlobalProperty(prop);
-        if ((propName != nullptr) && (*propName != '\0')) {
-          groupName = propName;
+        cmProp propName = this->Makefile->GetState()->GetGlobalProperty(prop);
+        if (cmNonempty(propName)) {
+          groupName = *propName;
           property = prop;
           break;
         }
@@ -1711,6 +1715,13 @@
     }
     return 0u;
   };
+  auto toUInt2 = [](cmProp input) -> unsigned int {
+    unsigned long tmp = 0;
+    if (input != nullptr && cmStrToULong(*input, &tmp)) {
+      return static_cast<unsigned int>(tmp);
+    }
+    return 0u;
+  };
 
   // Initialize return value to a default
   std::pair<IntegerVersion, unsigned int> res(
@@ -1732,9 +1743,9 @@
     knownQtVersions.reserve(keys.size() * 2);
 
     // Adds a version to the result (nullptr safe)
-    auto addVersion = [&knownQtVersions, &toUInt](const char* major,
-                                                  const char* minor) {
-      cmQtAutoGen::IntegerVersion ver(toUInt(major), toUInt(minor));
+    auto addVersion = [&knownQtVersions, &toUInt2](cmProp major,
+                                                   cmProp minor) {
+      cmQtAutoGen::IntegerVersion ver(toUInt2(major), toUInt2(minor));
       if (ver.Major != 0) {
         knownQtVersions.emplace_back(ver);
       }
@@ -1742,8 +1753,8 @@
 
     // Read versions from variables
     for (auto const& keyPair : keys) {
-      addVersion(target->Makefile->GetDefinition(std::string(keyPair.first)),
-                 target->Makefile->GetDefinition(std::string(keyPair.second)));
+      addVersion(target->Makefile->GetDef(std::string(keyPair.first)),
+                 target->Makefile->GetDef(std::string(keyPair.second)));
     }
 
     // Read versions from directory properties
@@ -1826,7 +1837,7 @@
   // Custom executable
   {
     std::string const prop = cmStrCat(genVars.GenNameUpper, "_EXECUTABLE");
-    std::string const val = this->GenTarget->Target->GetSafeProperty(prop);
+    std::string const& val = this->GenTarget->Target->GetSafeProperty(prop);
     if (!val.empty()) {
       // Evaluate generator expression
       {
diff --git a/Source/cmQtAutoGenerator.cxx b/Source/cmQtAutoGenerator.cxx
index da96305..ee2bc09 100644
--- a/Source/cmQtAutoGenerator.cxx
+++ b/Source/cmQtAutoGenerator.cxx
@@ -2,9 +2,9 @@
    file Copyright.txt or https://cmake.org/licensing for details.  */
 #include "cmQtAutoGenerator.h"
 
-#include "cmsys/FStream.hxx"
+#include <cm3p/json/reader.h>
 
-#include "cm_jsoncpp_reader.h"
+#include "cmsys/FStream.hxx"
 
 #include "cmQtAutoGen.h"
 #include "cmStringAlgorithms.h"
diff --git a/Source/cmQtAutoGenerator.h b/Source/cmQtAutoGenerator.h
index bbe6dd0..83fb3ed 100644
--- a/Source/cmQtAutoGenerator.h
+++ b/Source/cmQtAutoGenerator.h
@@ -13,7 +13,7 @@
 
 #include <cm/string_view>
 
-#include "cm_jsoncpp_value.h"
+#include <cm3p/json/value.h>
 
 #include "cmFileTime.h"
 #include "cmQtAutoGen.h"
diff --git a/Source/cmQtAutoMocUic.cxx b/Source/cmQtAutoMocUic.cxx
index f159a3d..f6cccfb 100644
--- a/Source/cmQtAutoMocUic.cxx
+++ b/Source/cmQtAutoMocUic.cxx
@@ -18,11 +18,11 @@
 #include <cm/string_view>
 #include <cmext/algorithm>
 
+#include <cm3p/json/value.h>
+
 #include "cmsys/FStream.hxx"
 #include "cmsys/RegularExpression.hxx"
 
-#include "cm_jsoncpp_value.h"
-
 #include "cmCryptoHash.h"
 #include "cmFileTime.h"
 #include "cmGccDepfileReader.h"
@@ -700,27 +700,27 @@
   if (!ofs) {
     return false;
   }
-  ofs << "# Generated by CMake. Changes will be overwritten." << std::endl;
+  ofs << "# Generated by CMake. Changes will be overwritten.\n";
   for (auto const& pair : Map_) {
-    ofs << pair.first << std::endl;
+    ofs << pair.first << '\n';
     FileT const& file = *pair.second;
     if (!file.Moc.Macro.empty()) {
-      ofs << " mmc:" << file.Moc.Macro << std::endl;
+      ofs << " mmc:" << file.Moc.Macro << '\n';
     }
     for (IncludeKeyT const& item : file.Moc.Include.Underscore) {
-      ofs << " miu:" << item.Key << std::endl;
+      ofs << " miu:" << item.Key << '\n';
     }
     for (IncludeKeyT const& item : file.Moc.Include.Dot) {
-      ofs << " mid:" << item.Key << std::endl;
+      ofs << " mid:" << item.Key << '\n';
     }
     for (std::string const& item : file.Moc.Depends) {
-      ofs << " mdp:" << item << std::endl;
+      ofs << " mdp:" << item << '\n';
     }
     for (IncludeKeyT const& item : file.Uic.Include) {
-      ofs << " uic:" << item.Key << std::endl;
+      ofs << " uic:" << item.Key << '\n';
     }
     for (std::string const& item : file.Uic.Depends) {
-      ofs << " udp:" << item << std::endl;
+      ofs << " udp:" << item << '\n';
     }
   }
   return ofs.Close();
@@ -2213,9 +2213,9 @@
                       " for writing."));
     return;
   }
-  ofs << BaseConst().DepFileRuleName << ": \\" << std::endl;
+  ofs << BaseConst().DepFileRuleName << ": \\\n";
   for (const std::string& file : dependencies) {
-    ofs << '\t' << escapeDependencyPath(file) << " \\" << std::endl;
+    ofs << '\t' << escapeDependencyPath(file) << " \\\n";
     if (!ofs.good()) {
       LogError(GenT::GEN,
                cmStrCat("Writing depfile", MessagePath(BaseConst().DepFile),
@@ -2226,8 +2226,7 @@
 
   // Add the CMake executable to re-new cache data if necessary.
   // Also, this is the last entry, so don't add a backslash.
-  ofs << '\t' << escapeDependencyPath(BaseConst().CMakeExecutable)
-      << std::endl;
+  ofs << '\t' << escapeDependencyPath(BaseConst().CMakeExecutable) << '\n';
 }
 
 void cmQtAutoMocUicT::JobFinishT::Process()
diff --git a/Source/cmRST.cxx b/Source/cmRST.cxx
index 7f4abf9..26e93bb 100644
--- a/Source/cmRST.cxx
+++ b/Source/cmRST.cxx
@@ -89,7 +89,8 @@
         this->ProcessLine(line);
       } else {
         if (line[0] != '#') {
-          this->ProcessLine(line.substr(0, pos));
+          line.resize(pos);
+          this->ProcessLine(line);
         }
         rst.clear();
         this->Reset();
@@ -102,8 +103,9 @@
           this->ProcessLine("");
           continue;
         }
-        if (line.substr(0, 2) == "# ") {
-          this->ProcessLine(line.substr(2));
+        if (cmHasLiteralPrefix(line, "# ")) {
+          line.erase(0, 2);
+          this->ProcessLine(line);
           continue;
         }
         rst.clear();
@@ -164,6 +166,8 @@
     this->Markup =
       (line.find_first_not_of(" \t", 2) == std::string::npos ? MarkupEmpty
                                                              : MarkupNormal);
+    // XXX(clang-tidy): https://bugs.llvm.org/show_bug.cgi?id=44165
+    // NOLINTNEXTLINE(bugprone-branch-clone)
     if (this->CMakeDirective.find(line)) {
       // Output cmake domain directives and their content normally.
       this->NormalLine(line);
diff --git a/Source/cmRulePlaceholderExpander.cxx b/Source/cmRulePlaceholderExpander.cxx
index 5ab1b3a..4ff81c1 100644
--- a/Source/cmRulePlaceholderExpander.cxx
+++ b/Source/cmRulePlaceholderExpander.cxx
@@ -236,8 +236,7 @@
   }
   if (variable == "CMAKE_COMMAND") {
     return outputConverter->ConvertToOutputFormat(
-      cmSystemTools::CollapseFullPath(cmSystemTools::GetCMakeCommand()),
-      cmOutputConverter::SHELL);
+      cmSystemTools::GetCMakeCommand(), cmOutputConverter::SHELL);
   }
 
   auto compIt = this->Compilers.find(variable);
@@ -262,7 +261,7 @@
       this->VariableMappings["CMAKE_" + compIt->second +
                              "_COMPILE_OPTIONS_SYSROOT"];
 
-    // if there is a required first argument to the compiler add it
+    // if there are required arguments to the compiler add it
     // to the compiler string
     if (!compilerArg1.empty()) {
       ret += " ";
@@ -334,7 +333,17 @@
       std::string replace =
         this->ExpandRuleVariable(outputConverter, var, replaceValues);
       expandedInput += s.substr(pos, start - pos);
+
+      // Prevent consecutive whitespace in the output if the rule variable
+      // expands to an empty string.
+      bool consecutive = replace.empty() && start > 0 && s[start - 1] == ' ' &&
+        end + 1 < s.size() && s[end + 1] == ' ';
+      if (consecutive) {
+        expandedInput.pop_back();
+      }
+
       expandedInput += replace;
+
       // move to next one
       start = s.find('<', start + var.size() + 2);
       pos = end + 1;
diff --git a/Source/cmRuntimeDependencyArchive.cxx b/Source/cmRuntimeDependencyArchive.cxx
index 7a987c2..0781d29 100644
--- a/Source/cmRuntimeDependencyArchive.cxx
+++ b/Source/cmRuntimeDependencyArchive.cxx
@@ -39,7 +39,7 @@
   std::string vsloc;
   bool found = false;
 #  ifndef CMAKE_BOOTSTRAP
-  if (gg->GetName().find(prefix) == 0) {
+  if (cmHasPrefix(gg->GetName(), prefix)) {
     cmGlobalVisualStudioVersionedGenerator* vsgen =
       static_cast<cmGlobalVisualStudioVersionedGenerator*>(gg);
     if (vsgen->GetVSInstance(vsloc)) {
@@ -218,6 +218,9 @@
   // First see if it was supplied by the user
   std::string toolCommand = this->GetMakefile()->GetSafeDefinition(
     "CMAKE_GET_RUNTIME_DEPENDENCIES_COMMAND");
+  if (toolCommand.empty() && search == "objdump") {
+    toolCommand = this->GetMakefile()->GetSafeDefinition("CMAKE_OBJDUMP");
+  }
   if (!toolCommand.empty()) {
     cmExpandList(toolCommand, command);
     return true;
diff --git a/Source/cmSearchPath.cxx b/Source/cmSearchPath.cxx
index 766d347..eb8fcaf 100644
--- a/Source/cmSearchPath.cxx
+++ b/Source/cmSearchPath.cxx
@@ -180,7 +180,7 @@
     if (subdir == "include" || subdir == "lib") {
       const char* arch =
         this->FC->Makefile->GetDefinition("CMAKE_LIBRARY_ARCHITECTURE");
-      if (arch && *arch) {
+      if (cmNonempty(arch)) {
         if (this->FC->Makefile->IsDefinitionSet("CMAKE_SYSROOT") &&
             this->FC->Makefile->IsDefinitionSet(
               "CMAKE_PREFIX_LIBRARY_ARCHITECTURE")) {
diff --git a/Source/cmSeparateArgumentsCommand.cxx b/Source/cmSeparateArgumentsCommand.cxx
index 52bde7c..cfe3087 100644
--- a/Source/cmSeparateArgumentsCommand.cxx
+++ b/Source/cmSeparateArgumentsCommand.cxx
@@ -39,6 +39,8 @@
     if (doing == DoingVariable) {
       var = arg;
       doing = DoingMode;
+      // This will always clone one of the other blocks.
+      // NOLINTNEXTLINE(bugprone-branch-clone)
     } else if (doing == DoingMode && arg == "NATIVE_COMMAND") {
 #ifdef _WIN32
       mode = ModeWindows;
diff --git a/Source/cmServer.cxx b/Source/cmServer.cxx
index 3b2e5f3..7f97406 100644
--- a/Source/cmServer.cxx
+++ b/Source/cmServer.cxx
@@ -4,6 +4,7 @@
 
 #include <algorithm>
 #include <cassert>
+#include <csignal>
 #include <cstdint>
 #include <iostream>
 #include <mutex>
@@ -12,10 +13,10 @@
 #include <cm/memory>
 #include <cm/shared_mutex>
 
-#include "cmsys/FStream.hxx"
+#include <cm3p/json/reader.h>
+#include <cm3p/json/writer.h>
 
-#include "cm_jsoncpp_reader.h"
-#include "cm_jsoncpp_writer.h"
+#include "cmsys/FStream.hxx"
 
 #include "cmConnection.h"
 #include "cmFileMonitor.h"
@@ -59,16 +60,12 @@
   , SupportExperimental(supportExperimental)
 {
   // Register supported protocols:
-  this->RegisterProtocol(new cmServerProtocol1);
+  this->RegisterProtocol(cm::make_unique<cmServerProtocol1>());
 }
 
 cmServer::~cmServer()
 {
   Close();
-
-  for (cmServerProtocol* p : this->SupportedProtocols) {
-    delete p;
-  }
 }
 
 void cmServer::ProcessRequest(cmConnection* connection,
@@ -117,22 +114,22 @@
   }
 }
 
-void cmServer::RegisterProtocol(cmServerProtocol* protocol)
+void cmServer::RegisterProtocol(std::unique_ptr<cmServerProtocol> protocol)
 {
   if (protocol->IsExperimental() && !this->SupportExperimental) {
-    delete protocol;
+    protocol.reset();
     return;
   }
   auto version = protocol->ProtocolVersion();
   assert(version.first >= 0);
   assert(version.second >= 0);
-  auto it = std::find_if(this->SupportedProtocols.begin(),
-                         this->SupportedProtocols.end(),
-                         [version](cmServerProtocol* p) {
-                           return p->ProtocolVersion() == version;
-                         });
+  auto it = std::find_if(
+    this->SupportedProtocols.begin(), this->SupportedProtocols.end(),
+    [version](const std::unique_ptr<cmServerProtocol>& p) {
+      return p->ProtocolVersion() == version;
+    });
   if (it == this->SupportedProtocols.end()) {
-    this->SupportedProtocols.push_back(protocol);
+    this->SupportedProtocols.push_back(std::move(protocol));
   }
 }
 
@@ -297,19 +294,20 @@
 }
 
 cmServerProtocol* cmServer::FindMatchingProtocol(
-  const std::vector<cmServerProtocol*>& protocols, int major, int minor)
+  const std::vector<std::unique_ptr<cmServerProtocol>>& protocols, int major,
+  int minor)
 {
   cmServerProtocol* bestMatch = nullptr;
-  for (auto protocol : protocols) {
+  for (const auto& protocol : protocols) {
     auto version = protocol->ProtocolVersion();
     if (major != version.first) {
       continue;
     }
     if (minor == version.second) {
-      return protocol;
+      return protocol.get();
     }
     if (!bestMatch || bestMatch->ProtocolVersion().second < version.second) {
-      bestMatch = protocol;
+      bestMatch = protocol.get();
     }
   }
   return minor < 0 ? bestMatch : nullptr;
diff --git a/Source/cmServer.h b/Source/cmServer.h
index 3d7027b..9543329 100644
--- a/Source/cmServer.h
+++ b/Source/cmServer.h
@@ -10,8 +10,8 @@
 
 #include <cm/shared_mutex>
 
-#include "cm_jsoncpp_value.h"
-#include "cm_uv.h"
+#include <cm3p/json/value.h>
+#include <cm3p/uv.h>
 
 #include "cmUVHandlePtr.h"
 
@@ -103,7 +103,7 @@
   cmFileMonitor* FileMonitor() const;
 
 private:
-  void RegisterProtocol(cmServerProtocol* protocol);
+  void RegisterProtocol(std::unique_ptr<cmServerProtocol> protocol);
 
   // Callbacks from cmServerConnection:
 
@@ -149,12 +149,13 @@
                        const DebugInfo* debug) const;
 
   static cmServerProtocol* FindMatchingProtocol(
-    const std::vector<cmServerProtocol*>& protocols, int major, int minor);
+    const std::vector<std::unique_ptr<cmServerProtocol>>& protocols, int major,
+    int minor);
 
   const bool SupportExperimental;
 
   cmServerProtocol* Protocol = nullptr;
-  std::vector<cmServerProtocol*> SupportedProtocols;
+  std::vector<std::unique_ptr<cmServerProtocol>> SupportedProtocols;
 
   friend class cmServerProtocol;
   friend class cmServerRequest;
diff --git a/Source/cmServerConnection.cxx b/Source/cmServerConnection.cxx
index 2791972..b4f41a0 100644
--- a/Source/cmServerConnection.cxx
+++ b/Source/cmServerConnection.cxx
@@ -4,7 +4,7 @@
 
 #include "cmServerConnection.h"
 
-#include "cm_uv.h"
+#include <cm3p/uv.h>
 
 #include "cmServer.h"
 #include "cmServerDictionary.h"
diff --git a/Source/cmServerProtocol.cxx b/Source/cmServerProtocol.cxx
index 1d4ea01..e586fd9 100644
--- a/Source/cmServerProtocol.cxx
+++ b/Source/cmServerProtocol.cxx
@@ -10,16 +10,17 @@
 #include <vector>
 
 #include <cm/memory>
+#include <cmext/algorithm>
 
-#include "cm_uv.h"
+#include <cm3p/uv.h>
 
-#include "cmAlgorithms.h"
 #include "cmExternalMakefileProjectGenerator.h"
 #include "cmFileMonitor.h"
 #include "cmGlobalGenerator.h"
 #include "cmJsonObjectDictionary.h"
 #include "cmJsonObjects.h"
 #include "cmMessageType.h"
+#include "cmProperty.h"
 #include "cmServer.h"
 #include "cmServerDictionary.h"
 #include "cmState.h"
@@ -135,6 +136,7 @@
   this->m_Server = server;
   this->m_CMakeInstance =
     cm::make_unique<cmake>(cmake::RoleProject, cmState::Project);
+  this->m_WarnUnused = false;
   const bool result = this->DoActivate(request, errorMessage);
   if (!result) {
     this->m_CMakeInstance = nullptr;
@@ -182,7 +184,7 @@
                                    std::string* errorMessage)
 {
   const std::string cachedValue =
-    std::string(state->GetCacheEntryValue("CMAKE_HOME_DIRECTORY"));
+    *state->GetCacheEntryValue("CMAKE_HOME_DIRECTORY");
   if (value.empty()) {
     value = cachedValue;
     return true;
@@ -205,9 +207,7 @@
                            const std::string& keyDescription,
                            std::string* errorMessage)
 {
-  const char* entry = state->GetCacheEntryValue(key);
-  const std::string cachedValue =
-    entry == nullptr ? std::string() : std::string(entry);
+  const std::string cachedValue = state->GetSafeCacheEntryValue(key);
   if (value.empty()) {
     value = cachedValue;
   }
@@ -435,7 +435,7 @@
     keys = allKeys;
   } else {
     for (auto const& i : keys) {
-      if (!cmContains(allKeys, i)) {
+      if (!cm::contains(allKeys, i)) {
         return request.ReportError("Key \"" + i + "\" not found in cache.");
       }
     }
@@ -446,13 +446,13 @@
     entry[kKEY_KEY] = key;
     entry[kTYPE_KEY] =
       cmState::CacheEntryTypeToString(state->GetCacheEntryType(key));
-    entry[kVALUE_KEY] = state->GetCacheEntryValue(key);
+    entry[kVALUE_KEY] = *state->GetCacheEntryValue(key);
 
     Json::Value props = Json::objectValue;
     bool haveProperties = false;
     for (auto const& prop : state->GetCacheEntryPropertyList(key)) {
       haveProperties = true;
-      props[prop] = state->GetCacheEntryProperty(key, prop);
+      props[prop] = *state->GetCacheEntryProperty(key, prop);
     }
     if (haveProperties) {
       entry[kPROPERTIES_KEY] = props;
@@ -564,7 +564,7 @@
 
   if (cm->LoadCache(buildDir)) {
     // build directory has been set up before
-    const std::string* cachedSourceDir =
+    cmProp cachedSourceDir =
       cm->GetState()->GetInitializedCacheValue("CMAKE_HOME_DIRECTORY");
     if (!cachedSourceDir) {
       return request.ReportError("No CMAKE_HOME_DIRECTORY found in cache.");
@@ -574,7 +574,7 @@
       cm->SetHomeDirectory(sourceDir);
     }
 
-    const std::string* cachedGenerator =
+    cmProp cachedGenerator =
       cm->GetState()->GetInitializedCacheValue("CMAKE_GENERATOR");
     if (cachedGenerator) {
       if (gg && gg->GetName() != *cachedGenerator) {
@@ -637,7 +637,7 @@
   obj[kTRACE_KEY] = cm->GetTrace();
   obj[kTRACE_EXPAND_KEY] = cm->GetTraceExpand();
   obj[kWARN_UNINITIALIZED_KEY] = cm->GetWarnUninitialized();
-  obj[kWARN_UNUSED_KEY] = cm->GetWarnUnused();
+  obj[kWARN_UNUSED_KEY] = m_WarnUnused;
   obj[kWARN_UNUSED_CLI_KEY] = cm->GetWarnUnusedCli();
   obj[kCHECK_SYSTEM_VARS_KEY] = cm->GetCheckSystemVars();
 
@@ -683,7 +683,7 @@
   setBool(request, kTRACE_EXPAND_KEY, [cm](bool e) { cm->SetTraceExpand(e); });
   setBool(request, kWARN_UNINITIALIZED_KEY,
           [cm](bool e) { cm->SetWarnUninitialized(e); });
-  setBool(request, kWARN_UNUSED_KEY, [cm](bool e) { cm->SetWarnUnused(e); });
+  setBool(request, kWARN_UNUSED_KEY, [this](bool e) { m_WarnUnused = e; });
   setBool(request, kWARN_UNUSED_CLI_KEY,
           [cm](bool e) { cm->SetWarnUnusedCli(e); });
   setBool(request, kCHECK_SYSTEM_VARS_KEY,
diff --git a/Source/cmServerProtocol.h b/Source/cmServerProtocol.h
index 8446c3e..6009e23 100644
--- a/Source/cmServerProtocol.h
+++ b/Source/cmServerProtocol.h
@@ -8,7 +8,7 @@
 #include <string>
 #include <utility>
 
-#include "cm_jsoncpp_value.h"
+#include <cm3p/json/value.h>
 
 #include "cmake.h"
 
@@ -94,6 +94,7 @@
   // Implement protocol specific activation tasks here. Called from Activate().
   virtual bool DoActivate(const cmServerRequest& request,
                           std::string* errorMessage);
+  bool m_WarnUnused = false; // storage for legacy option
 
 private:
   std::unique_ptr<cmake> m_CMakeInstance;
diff --git a/Source/cmSetCommand.cxx b/Source/cmSetCommand.cxx
index 5e2a146..354b4c3 100644
--- a/Source/cmSetCommand.cxx
+++ b/Source/cmSetCommand.cxx
@@ -5,6 +5,7 @@
 #include "cmExecutionStatus.h"
 #include "cmMakefile.h"
 #include "cmMessageType.h"
+#include "cmProperty.h"
 #include "cmRange.h"
 #include "cmState.h"
 #include "cmStateTypes.h"
@@ -135,7 +136,7 @@
 
   // see if this is already in the cache
   cmState* state = status.GetMakefile().GetState();
-  const char* existingValue = state->GetCacheEntryValue(variable);
+  cmProp existingValue = state->GetCacheEntryValue(variable);
   if (existingValue &&
       (state->GetCacheEntryType(variable) != cmStateEnums::UNINITIALIZED)) {
     // if the set is trying to CACHE the value but the value
@@ -149,8 +150,8 @@
 
   // if it is meant to be in the cache then define it in the cache
   if (cache) {
-    status.GetMakefile().AddCacheDefinition(variable, value.c_str(), docstring,
-                                            type, force);
+    status.GetMakefile().AddCacheDefinition(variable, value, docstring, type,
+                                            force);
   } else {
     // add the definition
     status.GetMakefile().AddDefinition(variable, value);
diff --git a/Source/cmSetDirectoryPropertiesCommand.cxx b/Source/cmSetDirectoryPropertiesCommand.cxx
index 35daca6..07ad246 100644
--- a/Source/cmSetDirectoryPropertiesCommand.cxx
+++ b/Source/cmSetDirectoryPropertiesCommand.cxx
@@ -5,12 +5,6 @@
 #include "cmExecutionStatus.h"
 #include "cmMakefile.h"
 
-namespace {
-bool RunCommand(cmMakefile& mf, std::vector<std::string>::const_iterator ait,
-                std::vector<std::string>::const_iterator aitend,
-                std::string& errors);
-}
-
 // cmSetDirectoryPropertiesCommand
 bool cmSetDirectoryPropertiesCommand(std::vector<std::string> const& args,
                                      cmExecutionStatus& status)
@@ -20,38 +14,26 @@
     return false;
   }
 
-  std::string errors;
-  bool ret =
-    RunCommand(status.GetMakefile(), args.begin() + 1, args.end(), errors);
-  if (!ret) {
-    status.SetError(errors);
+  // PROPERTIES followed by prop value pairs
+  if (args.size() % 2 != 1) {
+    status.SetError("Wrong number of arguments");
+    return false;
   }
-  return ret;
-}
 
-namespace {
-bool RunCommand(cmMakefile& mf, std::vector<std::string>::const_iterator ait,
-                std::vector<std::string>::const_iterator aitend,
-                std::string& errors)
-{
-  for (; ait != aitend; ait += 2) {
-    if (ait + 1 == aitend) {
-      errors = "Wrong number of arguments";
-      return false;
-    }
-    const std::string& prop = *ait;
-    const std::string& value = *(ait + 1);
+  for (auto iter = args.begin() + 1; iter != args.end(); iter += 2) {
+    const std::string& prop = *iter;
     if (prop == "VARIABLES") {
-      errors = "Variables and cache variables should be set using SET command";
+      status.SetError(
+        "Variables and cache variables should be set using SET command");
       return false;
     }
     if (prop == "MACROS") {
-      errors = "Commands and macros cannot be set using SET_CMAKE_PROPERTIES";
+      status.SetError(
+        "Commands and macros cannot be set using SET_CMAKE_PROPERTIES");
       return false;
     }
-    mf.SetProperty(prop, value.c_str());
+    status.GetMakefile().SetProperty(prop, (iter + 1)->c_str());
   }
 
   return true;
 }
-}
diff --git a/Source/cmSetPropertyCommand.cxx b/Source/cmSetPropertyCommand.cxx
index 3705727..6ca763b 100644
--- a/Source/cmSetPropertyCommand.cxx
+++ b/Source/cmSetPropertyCommand.cxx
@@ -4,6 +4,7 @@
 
 #include <set>
 #include <sstream>
+#include <unordered_set>
 
 #include "cmExecutionStatus.h"
 #include "cmGlobalGenerator.h"
@@ -43,7 +44,9 @@
                       const std::set<std::string>& names,
                       const std::string& propertyName,
                       const std::string& propertyValue, bool appendAsString,
-                      bool appendMode, bool remove);
+                      bool appendMode, bool remove,
+                      const std::vector<cmMakefile*>& directory_makefiles,
+                      bool source_file_paths_should_be_absolute);
 bool HandleSource(cmSourceFile* sf, const std::string& propertyName,
                   const std::string& propertyValue, bool appendAsString,
                   bool appendMode, bool remove);
@@ -74,6 +77,147 @@
                    bool appendMode, bool remove);
 }
 
+namespace SetPropertyCommand {
+bool HandleSourceFileDirectoryScopes(
+  cmExecutionStatus& status, std::vector<std::string>& source_file_directories,
+  std::vector<std::string>& source_file_target_directories,
+  std::vector<cmMakefile*>& directory_makefiles)
+{
+  std::unordered_set<cmMakefile*> directory_makefiles_set;
+
+  cmMakefile* current_dir_mf = &status.GetMakefile();
+  if (!source_file_directories.empty()) {
+    for (const std::string& dir_path : source_file_directories) {
+      const std::string absolute_dir_path = cmSystemTools::CollapseFullPath(
+        dir_path, current_dir_mf->GetCurrentSourceDirectory());
+      cmMakefile* dir_mf =
+        status.GetMakefile().GetGlobalGenerator()->FindMakefile(
+          absolute_dir_path);
+      if (!dir_mf) {
+        status.SetError(cmStrCat("given non-existent DIRECTORY ", dir_path));
+        return false;
+      }
+      if (directory_makefiles_set.find(dir_mf) ==
+          directory_makefiles_set.end()) {
+        directory_makefiles.push_back(dir_mf);
+        directory_makefiles_set.insert(dir_mf);
+      }
+    }
+  }
+
+  if (!source_file_target_directories.empty()) {
+    for (const std::string& target_name : source_file_target_directories) {
+      cmTarget* target = current_dir_mf->FindTargetToUse(target_name);
+      if (!target) {
+        status.SetError(cmStrCat(
+          "given non-existent target for TARGET_DIRECTORY ", target_name));
+        return false;
+      }
+      cmProp target_source_dir = target->GetProperty("SOURCE_DIR");
+      cmMakefile* target_dir_mf =
+        status.GetMakefile().GetGlobalGenerator()->FindMakefile(
+          *target_source_dir);
+
+      if (directory_makefiles_set.find(target_dir_mf) ==
+          directory_makefiles_set.end()) {
+        directory_makefiles.push_back(target_dir_mf);
+        directory_makefiles_set.insert(target_dir_mf);
+      }
+    }
+  }
+
+  if (source_file_directories.empty() &&
+      source_file_target_directories.empty()) {
+    directory_makefiles.push_back(current_dir_mf);
+  }
+  return true;
+}
+
+bool HandleSourceFileDirectoryScopeValidation(
+  cmExecutionStatus& status, bool source_file_directory_option_enabled,
+  bool source_file_target_option_enabled,
+  std::vector<std::string>& source_file_directories,
+  std::vector<std::string>& source_file_target_directories)
+{
+  // Validate source file directory scopes.
+  if (source_file_directory_option_enabled &&
+      source_file_directories.empty()) {
+    std::string errors = "called with incorrect number of arguments "
+                         "no value provided to the DIRECTORY option";
+    status.SetError(errors);
+    return false;
+  }
+  if (source_file_target_option_enabled &&
+      source_file_target_directories.empty()) {
+    std::string errors = "called with incorrect number of arguments "
+                         "no value provided to the TARGET_DIRECTORY option";
+    status.SetError(errors);
+    return false;
+  }
+  return true;
+}
+
+bool HandleAndValidateSourceFileDirectortoryScopes(
+  cmExecutionStatus& status, bool source_file_directory_option_enabled,
+  bool source_file_target_option_enabled,
+  std::vector<std::string>& source_file_directories,
+  std::vector<std::string>& source_file_target_directories,
+  std::vector<cmMakefile*>& source_file_directory_makefiles)
+{
+  bool scope_options_valid =
+    SetPropertyCommand::HandleSourceFileDirectoryScopeValidation(
+      status, source_file_directory_option_enabled,
+      source_file_target_option_enabled, source_file_directories,
+      source_file_target_directories);
+  if (!scope_options_valid) {
+    return false;
+  }
+
+  scope_options_valid = SetPropertyCommand::HandleSourceFileDirectoryScopes(
+    status, source_file_directories, source_file_target_directories,
+    source_file_directory_makefiles);
+  return scope_options_valid;
+}
+
+std::string MakeSourceFilePathAbsoluteIfNeeded(
+  cmExecutionStatus& status, const std::string& source_file_path,
+  const bool needed)
+{
+  if (!needed) {
+    return source_file_path;
+  }
+  const std::string absolute_file_path = cmSystemTools::CollapseFullPath(
+    source_file_path, status.GetMakefile().GetCurrentSourceDirectory());
+  return absolute_file_path;
+}
+
+void MakeSourceFilePathsAbsoluteIfNeeded(
+  cmExecutionStatus& status,
+  std::vector<std::string>& source_files_absolute_paths,
+  std::vector<std::string>::const_iterator files_it_begin,
+  std::vector<std::string>::const_iterator files_it_end, const bool needed)
+{
+
+  // Make the file paths absolute, so that relative source file paths are
+  // picked up relative to the command calling site, regardless of the
+  // directory scope.
+  std::vector<std::string>::difference_type num_files =
+    files_it_end - files_it_begin;
+  source_files_absolute_paths.reserve(num_files);
+
+  if (!needed) {
+    source_files_absolute_paths.assign(files_it_begin, files_it_end);
+    return;
+  }
+
+  for (; files_it_begin != files_it_end; ++files_it_begin) {
+    const std::string absolute_file_path =
+      MakeSourceFilePathAbsoluteIfNeeded(status, *files_it_begin, true);
+    source_files_absolute_paths.push_back(absolute_file_path);
+  }
+}
+}
+
 bool cmSetPropertyCommand(std::vector<std::string> const& args,
                           cmExecutionStatus& status)
 {
@@ -114,13 +258,20 @@
   std::string propertyName;
   std::string propertyValue;
 
+  std::vector<std::string> source_file_directories;
+  std::vector<std::string> source_file_target_directories;
+  bool source_file_directory_option_enabled = false;
+  bool source_file_target_option_enabled = false;
+
   // Parse the rest of the arguments up to the values.
   enum Doing
   {
     DoingNone,
     DoingNames,
     DoingProperty,
-    DoingValues
+    DoingValues,
+    DoingSourceDirectory,
+    DoingSourceTargetDirectory
   };
   Doing doing = DoingNames;
   const char* sep = "";
@@ -137,8 +288,20 @@
       appendMode = true;
       remove = false;
       appendAsString = true;
+    } else if (doing != DoingProperty && doing != DoingValues &&
+               scope == cmProperty::SOURCE_FILE && arg == "DIRECTORY") {
+      doing = DoingSourceDirectory;
+      source_file_directory_option_enabled = true;
+    } else if (doing != DoingProperty && doing != DoingValues &&
+               scope == cmProperty::SOURCE_FILE && arg == "TARGET_DIRECTORY") {
+      doing = DoingSourceTargetDirectory;
+      source_file_target_option_enabled = true;
     } else if (doing == DoingNames) {
       names.insert(arg);
+    } else if (doing == DoingSourceDirectory) {
+      source_file_directories.push_back(arg);
+    } else if (doing == DoingSourceTargetDirectory) {
+      source_file_target_directories.push_back(arg);
     } else if (doing == DoingProperty) {
       propertyName = arg;
       doing = DoingValues;
@@ -159,6 +322,18 @@
     return false;
   }
 
+  std::vector<cmMakefile*> source_file_directory_makefiles;
+  bool file_scopes_handled =
+    SetPropertyCommand::HandleAndValidateSourceFileDirectortoryScopes(
+      status, source_file_directory_option_enabled,
+      source_file_target_option_enabled, source_file_directories,
+      source_file_target_directories, source_file_directory_makefiles);
+  if (!file_scopes_handled) {
+    return false;
+  }
+  bool source_file_paths_should_be_absolute =
+    source_file_directory_option_enabled || source_file_target_option_enabled;
+
   // Dispatch property setting.
   switch (scope) {
     case cmProperty::GLOBAL:
@@ -172,7 +347,9 @@
                               appendAsString, appendMode, remove);
     case cmProperty::SOURCE_FILE:
       return HandleSourceMode(status, names, propertyName, propertyValue,
-                              appendAsString, appendMode, remove);
+                              appendAsString, appendMode, remove,
+                              source_file_directory_makefiles,
+                              source_file_paths_should_be_absolute);
     case cmProperty::TEST:
       return HandleTestMode(status, names, propertyName, propertyValue,
                             appendAsString, appendMode, remove);
@@ -235,14 +412,8 @@
   if (!names.empty()) {
     // Construct the directory name.  Interpret relative paths with
     // respect to the current directory.
-    std::string dir = *names.begin();
-    if (!cmSystemTools::FileIsFullPath(dir)) {
-      dir = cmStrCat(status.GetMakefile().GetCurrentSourceDirectory(), '/',
-                     *names.begin());
-    }
-
-    // The local generators are associated with collapsed paths.
-    dir = cmSystemTools::CollapseFullPath(dir);
+    std::string dir = cmSystemTools::CollapseFullPath(
+      *names.begin(), status.GetMakefile().GetCurrentSourceDirectory());
 
     mf = status.GetMakefile().GetGlobalGenerator()->FindMakefile(dir);
     if (!mf) {
@@ -307,7 +478,7 @@
     if (remove) {
       target->SetProperty(propertyName, nullptr);
     } else {
-      target->SetProperty(propertyName, propertyValue.c_str());
+      target->SetProperty(propertyName, propertyValue);
     }
   }
 
@@ -321,21 +492,32 @@
                       const std::set<std::string>& names,
                       const std::string& propertyName,
                       const std::string& propertyValue, bool appendAsString,
-                      bool appendMode, bool remove)
+                      bool appendMode, bool remove,
+                      const std::vector<cmMakefile*>& directory_makefiles,
+                      const bool source_file_paths_should_be_absolute)
 {
-  for (std::string const& name : names) {
-    // Get the source file.
-    if (cmSourceFile* sf = status.GetMakefile().GetOrCreateSource(name)) {
-      if (!HandleSource(sf, propertyName, propertyValue, appendAsString,
-                        appendMode, remove)) {
+  std::vector<std::string> files_absolute;
+  std::vector<std::string> unique_files(names.begin(), names.end());
+  SetPropertyCommand::MakeSourceFilePathsAbsoluteIfNeeded(
+    status, files_absolute, unique_files.begin(), unique_files.end(),
+    source_file_paths_should_be_absolute);
+
+  for (const auto mf : directory_makefiles) {
+    for (std::string const& name : files_absolute) {
+      // Get the source file.
+      if (cmSourceFile* sf = mf->GetOrCreateSource(name)) {
+        if (!HandleSource(sf, propertyName, propertyValue, appendAsString,
+                          appendMode, remove)) {
+          return false;
+        }
+      } else {
+        status.SetError(cmStrCat(
+          "given SOURCE name that could not be found or created: ", name));
         return false;
       }
-    } else {
-      status.SetError(cmStrCat(
-        "given SOURCE name that could not be found or created: ", name));
-      return false;
     }
   }
+
   return true;
 }
 
@@ -438,7 +620,7 @@
   for (std::string const& name : names) {
     // Get the source file.
     cmake* cm = status.GetMakefile().GetCMakeInstance();
-    const char* existingValue = cm->GetState()->GetCacheEntryValue(name);
+    cmProp existingValue = cm->GetState()->GetCacheEntryValue(name);
     if (existingValue) {
       if (!HandleCacheEntry(name, status.GetMakefile(), propertyName,
                             propertyValue, appendAsString, appendMode,
@@ -460,16 +642,15 @@
                       bool appendMode, bool remove)
 {
   // Set or append the property.
-  const char* value = propertyValue.c_str();
   cmState* state = makefile.GetState();
   if (remove) {
     state->RemoveCacheEntryProperty(cacheKey, propertyName);
   }
   if (appendMode) {
-    state->AppendCacheEntryProperty(cacheKey, propertyName, value,
+    state->AppendCacheEntryProperty(cacheKey, propertyName, propertyValue,
                                     appendAsString);
   } else {
-    state->SetCacheEntryProperty(cacheKey, propertyName, value);
+    state->SetCacheEntryProperty(cacheKey, propertyName, propertyValue);
   }
 
   return true;
@@ -505,13 +686,13 @@
                    bool appendMode, bool remove)
 {
   // Set or append the property.
-  const char* value = propertyValue.c_str();
   if (remove) {
     file->RemoveProperty(propertyName);
   } else if (appendMode) {
-    file->AppendProperty(&makefile, propertyName, value, appendAsString);
+    file->AppendProperty(&makefile, propertyName, propertyValue,
+                         appendAsString);
   } else {
-    file->SetProperty(&makefile, propertyName, value);
+    file->SetProperty(&makefile, propertyName, propertyValue);
   }
   return true;
 }
diff --git a/Source/cmSetPropertyCommand.h b/Source/cmSetPropertyCommand.h
index ec36f84..af566a3 100644
--- a/Source/cmSetPropertyCommand.h
+++ b/Source/cmSetPropertyCommand.h
@@ -8,9 +8,38 @@
 #include <string>
 #include <vector>
 
+class cmMakefile;
 class cmExecutionStatus;
 
 bool cmSetPropertyCommand(std::vector<std::string> const& args,
                           cmExecutionStatus& status);
 
+namespace SetPropertyCommand {
+bool HandleSourceFileDirectoryScopes(
+  cmExecutionStatus& status, std::vector<std::string>& source_file_directories,
+  std::vector<std::string>& source_file_target_directories,
+  std::vector<cmMakefile*>& directory_makefiles);
+
+bool HandleSourceFileDirectoryScopeValidation(
+  cmExecutionStatus& status, bool source_file_directory_option_enabled,
+  bool source_file_target_option_enabled,
+  std::vector<std::string>& source_file_directories,
+  std::vector<std::string>& source_file_target_directories);
+
+bool HandleAndValidateSourceFileDirectortoryScopes(
+  cmExecutionStatus& status, bool source_directories_option_encountered,
+  bool source_target_directories_option_encountered,
+  std::vector<std::string>& source_directories,
+  std::vector<std::string>& source_target_directories,
+  std::vector<cmMakefile*>& source_file_directory_makefiles);
+
+std::string MakeSourceFilePathAbsoluteIfNeeded(
+  cmExecutionStatus& status, const std::string& source_file_path, bool needed);
+void MakeSourceFilePathsAbsoluteIfNeeded(
+  cmExecutionStatus& status,
+  std::vector<std::string>& source_files_absolute_paths,
+  std::vector<std::string>::const_iterator files_it_begin,
+  std::vector<std::string>::const_iterator files_it_end, bool needed);
+}
+
 #endif
diff --git a/Source/cmSetSourceFilesPropertiesCommand.cxx b/Source/cmSetSourceFilesPropertiesCommand.cxx
index 7ff604b..c1b0c28 100644
--- a/Source/cmSetSourceFilesPropertiesCommand.cxx
+++ b/Source/cmSetSourceFilesPropertiesCommand.cxx
@@ -2,17 +2,23 @@
    file Copyright.txt or https://cmake.org/licensing for details.  */
 #include "cmSetSourceFilesPropertiesCommand.h"
 
+#include <algorithm>
+#include <iterator>
+
+#include <cm/string_view>
+#include <cmext/algorithm>
+
 #include "cmExecutionStatus.h"
 #include "cmMakefile.h"
+#include "cmSetPropertyCommand.h"
 #include "cmSourceFile.h"
 #include "cmStringAlgorithms.h"
 
-static bool RunCommand(cmMakefile* mf,
-                       std::vector<std::string>::const_iterator filebeg,
-                       std::vector<std::string>::const_iterator fileend,
-                       std::vector<std::string>::const_iterator propbeg,
-                       std::vector<std::string>::const_iterator propend,
-                       std::string& errors);
+static bool RunCommandForScope(
+  cmMakefile* mf, std::vector<std::string>::const_iterator file_begin,
+  std::vector<std::string>::const_iterator file_end,
+  std::vector<std::string>::const_iterator prop_begin,
+  std::vector<std::string>::const_iterator prop_end, std::string& errors);
 
 bool cmSetSourceFilesPropertiesCommand(std::vector<std::string> const& args,
                                        cmExecutionStatus& status)
@@ -23,56 +29,106 @@
   }
 
   // break the arguments into source file names and properties
-  int numFiles = 0;
-  std::vector<std::string>::const_iterator j;
-  j = args.begin();
   // old style allows for specifier before PROPERTIES keyword
-  while (j != args.end() && *j != "ABSTRACT" && *j != "WRAP_EXCLUDE" &&
-         *j != "GENERATED" && *j != "COMPILE_FLAGS" &&
-         *j != "OBJECT_DEPENDS" && *j != "PROPERTIES") {
-    numFiles++;
-    ++j;
+  static const cm::string_view prop_names[] = {
+    "ABSTRACT",       "GENERATED",  "WRAP_EXCLUDE", "COMPILE_FLAGS",
+    "OBJECT_DEPENDS", "PROPERTIES", "DIRECTORY",    "TARGET_DIRECTORY"
+  };
+
+  auto isAPropertyKeyword =
+    [](const std::vector<std::string>::const_iterator& arg_it) {
+      return std::any_of(
+        std::begin(prop_names), std::end(prop_names),
+        [&arg_it](cm::string_view prop_name) { return *arg_it == prop_name; });
+    };
+
+  auto options_begin = std::find_first_of(
+    args.begin(), args.end(), std::begin(prop_names), std::end(prop_names));
+  auto options_it = options_begin;
+
+  // Handle directory options.
+  std::vector<std::string> source_file_directories;
+  std::vector<std::string> source_file_target_directories;
+  bool source_file_directory_option_enabled = false;
+  bool source_file_target_option_enabled = false;
+  std::vector<cmMakefile*> source_file_directory_makefiles;
+
+  enum Doing
+  {
+    DoingNone,
+    DoingSourceDirectory,
+    DoingSourceTargetDirectory
+  };
+  Doing doing = DoingNone;
+  for (; options_it != args.end(); ++options_it) {
+    if (*options_it == "DIRECTORY") {
+      doing = DoingSourceDirectory;
+      source_file_directory_option_enabled = true;
+    } else if (*options_it == "TARGET_DIRECTORY") {
+      doing = DoingSourceTargetDirectory;
+      source_file_target_option_enabled = true;
+    } else if (isAPropertyKeyword(options_it)) {
+      break;
+    } else if (doing == DoingSourceDirectory) {
+      source_file_directories.push_back(*options_it);
+    } else if (doing == DoingSourceTargetDirectory) {
+      source_file_target_directories.push_back(*options_it);
+    } else {
+      status.SetError(
+        cmStrCat("given invalid argument \"", *options_it, "\"."));
+    }
   }
 
-  cmMakefile& mf = status.GetMakefile();
+  const auto props_begin = options_it;
 
-  // now call the worker function
+  bool file_scopes_handled =
+    SetPropertyCommand::HandleAndValidateSourceFileDirectortoryScopes(
+      status, source_file_directory_option_enabled,
+      source_file_target_option_enabled, source_file_directories,
+      source_file_target_directories, source_file_directory_makefiles);
+  if (!file_scopes_handled) {
+    return false;
+  }
+
+  std::vector<std::string> files;
+  bool source_file_paths_should_be_absolute =
+    source_file_directory_option_enabled || source_file_target_option_enabled;
+  SetPropertyCommand::MakeSourceFilePathsAbsoluteIfNeeded(
+    status, files, args.begin(), options_begin,
+    source_file_paths_should_be_absolute);
+
+  // Now call the worker function for each directory scope represented by a
+  // cmMakefile instance.
   std::string errors;
-  bool ret = RunCommand(&mf, args.begin(), args.begin() + numFiles,
-                        args.begin() + numFiles, args.end(), errors);
-  if (!ret) {
-    status.SetError(errors);
+  for (const auto mf : source_file_directory_makefiles) {
+    bool ret = RunCommandForScope(mf, files.begin(), files.end(), props_begin,
+                                  args.end(), errors);
+    if (!ret) {
+      status.SetError(errors);
+      return ret;
+    }
   }
-  return ret;
+
+  return true;
 }
 
-static bool RunCommand(cmMakefile* mf,
-                       std::vector<std::string>::const_iterator filebeg,
-                       std::vector<std::string>::const_iterator fileend,
-                       std::vector<std::string>::const_iterator propbeg,
-                       std::vector<std::string>::const_iterator propend,
-                       std::string& errors)
+static bool RunCommandForScope(
+  cmMakefile* mf, std::vector<std::string>::const_iterator file_begin,
+  std::vector<std::string>::const_iterator file_end,
+  std::vector<std::string>::const_iterator prop_begin,
+  std::vector<std::string>::const_iterator prop_end, std::string& errors)
 {
   std::vector<std::string> propertyPairs;
-  bool generated = false;
-  std::vector<std::string>::const_iterator j;
   // build the property pairs
-  for (j = propbeg; j != propend; ++j) {
-    // old style allows for specifier before PROPERTIES keyword
-    if (*j == "ABSTRACT") {
-      propertyPairs.emplace_back("ABSTRACT");
-      propertyPairs.emplace_back("1");
-    } else if (*j == "WRAP_EXCLUDE") {
-      propertyPairs.emplace_back("WRAP_EXCLUDE");
-      propertyPairs.emplace_back("1");
-    } else if (*j == "GENERATED") {
-      generated = true;
-      propertyPairs.emplace_back("GENERATED");
+  for (auto j = prop_begin; j != prop_end; ++j) {
+    // consume old style options
+    if (*j == "ABSTRACT" || *j == "GENERATED" || *j == "WRAP_EXCLUDE") {
+      propertyPairs.emplace_back(*j);
       propertyPairs.emplace_back("1");
     } else if (*j == "COMPILE_FLAGS") {
       propertyPairs.emplace_back("COMPILE_FLAGS");
       ++j;
-      if (j == propend) {
+      if (j == prop_end) {
         errors = "called with incorrect number of arguments "
                  "COMPILE_FLAGS with no flags";
         return false;
@@ -81,33 +137,22 @@
     } else if (*j == "OBJECT_DEPENDS") {
       propertyPairs.emplace_back("OBJECT_DEPENDS");
       ++j;
-      if (j == propend) {
+      if (j == prop_end) {
         errors = "called with incorrect number of arguments "
                  "OBJECT_DEPENDS with no dependencies";
         return false;
       }
       propertyPairs.push_back(*j);
     } else if (*j == "PROPERTIES") {
-      // now loop through the rest of the arguments, new style
-      ++j;
-      while (j != propend) {
-        propertyPairs.push_back(*j);
-        if (*j == "GENERATED") {
-          ++j;
-          if (j != propend && cmIsOn(*j)) {
-            generated = true;
-          }
-        } else {
-          ++j;
-        }
-        if (j == propend) {
-          errors = "called with incorrect number of arguments.";
-          return false;
-        }
-        propertyPairs.push_back(*j);
-        ++j;
+      // PROPERTIES is followed by new style prop value pairs
+      cmStringRange newStyleProps{ j + 1, prop_end };
+      if (newStyleProps.size() % 2 != 0) {
+        errors = "called with incorrect number of arguments.";
+        return false;
       }
-      // break out of the loop because j is already == end
+      // set newStyleProps as is.
+      cm::append(propertyPairs, newStyleProps);
+      // break out of the loop.
       break;
     } else {
       errors = "called with illegal arguments, maybe missing a "
@@ -116,15 +161,13 @@
     }
   }
 
-  // now loop over all the files
-  for (j = filebeg; j != fileend; ++j) {
+  // loop over all the files
+  for (const std::string& sfname : cmStringRange{ file_begin, file_end }) {
     // get the source file
-    cmSourceFile* sf = mf->GetOrCreateSource(*j, generated);
-    if (sf) {
-      // now loop through all the props and set them
-      unsigned int k;
-      for (k = 0; k < propertyPairs.size(); k = k + 2) {
-        sf->SetProperty(propertyPairs[k], propertyPairs[k + 1].c_str());
+    if (cmSourceFile* sf = mf->GetOrCreateSource(sfname)) {
+      // loop through the props and set them
+      for (auto k = propertyPairs.begin(); k != propertyPairs.end(); k += 2) {
+        sf->SetProperty(*k, (k + 1)->c_str());
       }
     }
   }
diff --git a/Source/cmSetTargetPropertiesCommand.cxx b/Source/cmSetTargetPropertiesCommand.cxx
index cd0fa40..bdc84af 100644
--- a/Source/cmSetTargetPropertiesCommand.cxx
+++ b/Source/cmSetTargetPropertiesCommand.cxx
@@ -2,19 +2,14 @@
    file Copyright.txt or https://cmake.org/licensing for details.  */
 #include "cmSetTargetPropertiesCommand.h"
 
+#include <algorithm>
 #include <iterator>
 
-#include <cmext/algorithm>
-
 #include "cmExecutionStatus.h"
 #include "cmMakefile.h"
 #include "cmStringAlgorithms.h"
 #include "cmTarget.h"
 
-static bool SetOneTarget(const std::string& tname,
-                         std::vector<std::string>& propertyPairs,
-                         cmMakefile* mf);
-
 bool cmSetTargetPropertiesCommand(std::vector<std::string> const& args,
                                   cmExecutionStatus& status)
 {
@@ -23,61 +18,38 @@
     return false;
   }
 
-  // first collect up the list of files
-  std::vector<std::string> propertyPairs;
-  int numFiles = 0;
-  for (auto j = args.begin(); j != args.end(); ++j) {
-    if (*j == "PROPERTIES") {
-      // now loop through the rest of the arguments, new style
-      ++j;
-      if (std::distance(j, args.end()) % 2 != 0) {
-        status.SetError("called with incorrect number of arguments.");
-        return false;
-      }
-      cm::append(propertyPairs, j, args.end());
-      break;
-    }
-    numFiles++;
+  // first identify the properties arguments
+  auto propsIter = std::find(args.begin(), args.end(), "PROPERTIES");
+  if (propsIter == args.end() || propsIter + 1 == args.end()) {
+    status.SetError("called with illegal arguments, maybe missing a "
+                    "PROPERTIES specifier?");
+    return false;
   }
-  if (propertyPairs.empty()) {
-    status.SetError("called with illegal arguments, maybe missing "
-                    "a PROPERTIES specifier?");
+
+  if (std::distance(propsIter, args.end()) % 2 != 1) {
+    status.SetError("called with incorrect number of arguments.");
     return false;
   }
 
   cmMakefile& mf = status.GetMakefile();
 
-  // now loop over all the targets
-  for (int i = 0; i < numFiles; ++i) {
-    if (mf.IsAlias(args[i])) {
+  // loop over all the targets
+  for (const std::string& tname : cmStringRange{ args.begin(), propsIter }) {
+    if (mf.IsAlias(tname)) {
       status.SetError("can not be used on an ALIAS target.");
       return false;
     }
-    bool ret = SetOneTarget(args[i], propertyPairs, &mf);
-    if (!ret) {
+    if (cmTarget* target = mf.FindTargetToUse(tname)) {
+      // loop through all the props and set them
+      for (auto k = propsIter + 1; k != args.end(); k += 2) {
+        target->SetProperty(*k, *(k + 1));
+        target->CheckProperty(*k, &mf);
+      }
+    } else {
       status.SetError(
-        cmStrCat("Can not find target to add properties to: ", args[i]));
+        cmStrCat("Can not find target to add properties to: ", tname));
       return false;
     }
   }
   return true;
 }
-
-static bool SetOneTarget(const std::string& tname,
-                         std::vector<std::string>& propertyPairs,
-                         cmMakefile* mf)
-{
-  if (cmTarget* target = mf->FindTargetToUse(tname)) {
-    // now loop through all the props and set them
-    unsigned int k;
-    for (k = 0; k < propertyPairs.size(); k = k + 2) {
-      target->SetProperty(propertyPairs[k], propertyPairs[k + 1]);
-      target->CheckProperty(propertyPairs[k], mf);
-    }
-  }
-  // if file is not already in the makefile, then add it
-  else {
-    return false;
-  }
-  return true;
-}
diff --git a/Source/cmSetTestsPropertiesCommand.cxx b/Source/cmSetTestsPropertiesCommand.cxx
index 2e7aeca..c4bff76 100644
--- a/Source/cmSetTestsPropertiesCommand.cxx
+++ b/Source/cmSetTestsPropertiesCommand.cxx
@@ -2,19 +2,14 @@
    file Copyright.txt or https://cmake.org/licensing for details.  */
 #include "cmSetTestsPropertiesCommand.h"
 
+#include <algorithm>
 #include <iterator>
 
-#include <cmext/algorithm>
-
 #include "cmExecutionStatus.h"
 #include "cmMakefile.h"
 #include "cmStringAlgorithms.h"
 #include "cmTest.h"
 
-static bool SetOneTest(const std::string& tname,
-                       std::vector<std::string>& propertyPairs, cmMakefile* mf,
-                       std::string& errors);
-
 bool cmSetTestsPropertiesCommand(std::vector<std::string> const& args,
                                  cmExecutionStatus& status)
 {
@@ -23,61 +18,33 @@
     return false;
   }
 
-  cmMakefile& mf = status.GetMakefile();
-
-  // first collect up the list of files
-  std::vector<std::string> propertyPairs;
-  int numFiles = 0;
-  std::vector<std::string>::const_iterator j;
-  for (j = args.begin(); j != args.end(); ++j) {
-    if (*j == "PROPERTIES") {
-      // now loop through the rest of the arguments, new style
-      ++j;
-      if (std::distance(j, args.end()) % 2 != 0) {
-        status.SetError("called with incorrect number of arguments.");
-        return false;
-      }
-      cm::append(propertyPairs, j, args.end());
-      break;
-    }
-    numFiles++;
-  }
-  if (propertyPairs.empty()) {
-    status.SetError("called with illegal arguments, maybe "
-                    "missing a PROPERTIES specifier?");
+  // first identify the properties arguments
+  auto propsIter = std::find(args.begin(), args.end(), "PROPERTIES");
+  if (propsIter == args.end() || propsIter + 1 == args.end()) {
+    status.SetError("called with illegal arguments, maybe missing a "
+                    "PROPERTIES specifier?");
     return false;
   }
 
-  // now loop over all the targets
-  int i;
-  for (i = 0; i < numFiles; ++i) {
-    std::string errors;
-    bool ret = SetOneTest(args[i], propertyPairs, &mf, errors);
-    if (!ret) {
-      status.SetError(errors);
-      return ret;
-    }
-  }
-
-  return true;
-}
-
-static bool SetOneTest(const std::string& tname,
-                       std::vector<std::string>& propertyPairs, cmMakefile* mf,
-                       std::string& errors)
-{
-  if (cmTest* test = mf->GetTest(tname)) {
-    // now loop through all the props and set them
-    unsigned int k;
-    for (k = 0; k < propertyPairs.size(); k = k + 2) {
-      if (!propertyPairs[k].empty()) {
-        test->SetProperty(propertyPairs[k], propertyPairs[k + 1].c_str());
-      }
-    }
-  } else {
-    errors = cmStrCat("Can not find test to add properties to: ", tname);
+  if (std::distance(propsIter, args.end()) % 2 != 1) {
+    status.SetError("called with incorrect number of arguments.");
     return false;
   }
 
+  // loop over all the tests
+  for (const std::string& tname : cmStringRange{ args.begin(), propsIter }) {
+    if (cmTest* test = status.GetMakefile().GetTest(tname)) {
+      // loop through all the props and set them
+      for (auto k = propsIter + 1; k != args.end(); k += 2) {
+        if (!k->empty()) {
+          test->SetProperty(*k, (k + 1)->c_str());
+        }
+      }
+    } else {
+      status.SetError(
+        cmStrCat("Can not find test to add properties to: ", tname));
+      return false;
+    }
+  }
   return true;
 }
diff --git a/Source/cmSiteNameCommand.cxx b/Source/cmSiteNameCommand.cxx
index d47f121..b2d905e 100644
--- a/Source/cmSiteNameCommand.cxx
+++ b/Source/cmSiteNameCommand.cxx
@@ -72,8 +72,7 @@
   }
 #endif
   status.GetMakefile().AddCacheDefinition(
-    args[0], siteName.c_str(),
-    "Name of the computer/site where compile is being run",
+    args[0], siteName, "Name of the computer/site where compile is being run",
     cmStateEnums::STRING);
 
   return true;
diff --git a/Source/cmSourceFile.cxx b/Source/cmSourceFile.cxx
index fd9cacd..ef44a57 100644
--- a/Source/cmSourceFile.cxx
+++ b/Source/cmSourceFile.cxx
@@ -2,7 +2,6 @@
    file Copyright.txt or https://cmake.org/licensing for details.  */
 #include "cmSourceFile.h"
 
-#include <array>
 #include <utility>
 
 #include "cmGlobalGenerator.h"
@@ -48,9 +47,9 @@
 std::string const& cmSourceFile::GetOrDetermineLanguage()
 {
   // If the language was set explicitly by the user then use it.
-  if (const char* lang = this->GetProperty(propLANGUAGE)) {
+  if (cmProp lang = this->GetProperty(propLANGUAGE)) {
     // Assign to member in order to return a reference.
-    this->Language = lang;
+    this->Language = *lang;
     return this->Language;
   }
 
@@ -81,8 +80,8 @@
 std::string cmSourceFile::GetLanguage() const
 {
   // If the language was set explicitly by the user then use it.
-  if (const char* lang = this->GetProperty(propLANGUAGE)) {
-    return lang;
+  if (cmProp lang = this->GetProperty(propLANGUAGE)) {
+    return *lang;
   }
 
   // Use the language determined from the file extension.
@@ -130,13 +129,11 @@
   // Location path
   std::string const& lPath = this->Location.GetFullPath();
   // List of extension lists
-  std::array<std::vector<std::string> const*, 2> const extsLists = {
-    { &makefile->GetCMakeInstance()->GetSourceExtensions(),
-      &makefile->GetCMakeInstance()->GetHeaderExtensions() }
-  };
+  std::vector<std::string> exts =
+    makefile->GetCMakeInstance()->GetAllExtensions();
 
   // Tries to find the file in a given directory
-  auto findInDir = [this, &extsLists, &lPath](std::string const& dir) -> bool {
+  auto findInDir = [this, &exts, &lPath](std::string const& dir) -> bool {
     // Compute full path
     std::string const fullPath = cmSystemTools::CollapseFullPath(lPath, dir);
     // Try full path
@@ -145,14 +142,12 @@
       return true;
     }
     // Try full path with extension
-    for (auto& exts : extsLists) {
-      for (std::string const& ext : *exts) {
-        if (!ext.empty()) {
-          std::string extPath = cmStrCat(fullPath, '.', ext);
-          if (cmSystemTools::FileExists(extPath)) {
-            this->FullPath = extPath;
-            return true;
-          }
+    for (std::string const& ext : exts) {
+      if (!ext.empty()) {
+        std::string extPath = cmStrCat(fullPath, '.', ext);
+        if (cmSystemTools::FileExists(extPath)) {
+          this->FullPath = extPath;
+          return true;
         }
       }
     }
@@ -175,11 +170,9 @@
   // Compose error
   std::string err =
     cmStrCat("Cannot find source file:\n  ", lPath, "\nTried extensions");
-  for (auto exts : extsLists) {
-    for (std::string const& ext : *exts) {
-      err += " .";
-      err += ext;
-    }
+  for (std::string const& ext : exts) {
+    err += " .";
+    err += ext;
   }
   if (error != nullptr) {
     *error = std::move(err);
@@ -317,17 +310,18 @@
   }
 
   // Perform the normal property lookup.
-  return this->GetProperty(prop);
+  cmProp p = this->GetProperty(prop);
+  return p ? p->c_str() : nullptr;
 }
 
-const char* cmSourceFile::GetProperty(const std::string& prop) const
+cmProp cmSourceFile::GetProperty(const std::string& prop) const
 {
   // Check for computed properties.
   if (prop == propLOCATION) {
     if (this->FullPath.empty()) {
       return nullptr;
     }
-    return this->FullPath.c_str();
+    return &this->FullPath;
   }
 
   // Check for the properties with backtraces.
@@ -338,7 +332,7 @@
 
     static std::string output;
     output = cmJoin(this->IncludeDirectories, ";");
-    return output.c_str();
+    return &output;
   }
 
   if (prop == propCOMPILE_OPTIONS) {
@@ -348,7 +342,7 @@
 
     static std::string output;
     output = cmJoin(this->CompileOptions, ";");
-    return output.c_str();
+    return &output;
   }
 
   if (prop == propCOMPILE_DEFINITIONS) {
@@ -358,10 +352,10 @@
 
     static std::string output;
     output = cmJoin(this->CompileDefinitions, ";");
-    return output.c_str();
+    return &output;
   }
 
-  const char* retVal = this->Properties.GetPropertyValue(prop);
+  cmProp retVal = this->Properties.GetPropertyValue(prop);
   if (!retVal) {
     cmMakefile const* mf = this->Location.GetMakefile();
     const bool chain =
@@ -369,6 +363,7 @@
     if (chain) {
       return mf->GetProperty(prop, chain);
     }
+    return nullptr;
   }
 
   return retVal;
@@ -376,11 +371,11 @@
 
 const char* cmSourceFile::GetSafeProperty(const std::string& prop) const
 {
-  const char* ret = this->GetProperty(prop);
+  cmProp ret = this->GetProperty(prop);
   if (!ret) {
     return "";
   }
-  return ret;
+  return ret->c_str();
 }
 
 bool cmSourceFile::GetPropertyAsBool(const std::string& prop) const
diff --git a/Source/cmSourceFile.h b/Source/cmSourceFile.h
index e22829f..e669015 100644
--- a/Source/cmSourceFile.h
+++ b/Source/cmSourceFile.h
@@ -11,6 +11,7 @@
 
 #include "cmCustomCommand.h"
 #include "cmListFileCache.h"
+#include "cmProperty.h"
 #include "cmPropertyMap.h"
 #include "cmSourceFileLocation.h"
 #include "cmSourceFileLocationKind.h"
@@ -45,7 +46,7 @@
   void AppendProperty(const std::string& prop, const std::string& value,
                       bool asString = false);
   //! Might return a nullptr if the property is not set or invalid
-  const char* GetProperty(const std::string& prop) const;
+  cmProp GetProperty(const std::string& prop) const;
   //! Always returns a valid pointer
   const char* GetSafeProperty(const std::string& prop) const;
   bool GetPropertyAsBool(const std::string& prop) const;
@@ -157,7 +158,7 @@
   "\\.(C|F|M|c|c\\+\\+|cc|cpp|cxx|cu|f|f90|for|fpp|ftn|m|mm|"                 \
   "rc|def|r|odl|idl|hpj|bat)$"
 
-#define CM_PCH_REGEX "cmake_pch\\.(h|hxx)$"
+#define CM_PCH_REGEX "cmake_pch(_[^.]+)?\\.(h|hxx)$"
 
 #define CM_RESOURCE_REGEX "\\.(pdf|plist|png|jpeg|jpg|storyboard|xcassets)$"
 
diff --git a/Source/cmSourceFileLocation.cxx b/Source/cmSourceFileLocation.cxx
index 5f807b8..222bafa 100644
--- a/Source/cmSourceFileLocation.cxx
+++ b/Source/cmSourceFileLocation.cxx
@@ -4,6 +4,8 @@
 
 #include <cassert>
 
+#include <cm/string_view>
+
 #include "cmGlobalGenerator.h"
 #include "cmMakefile.h"
 #include "cmMessageType.h"
@@ -99,7 +101,7 @@
   cmMakefile const* mf = this->Makefile;
   auto cm = mf->GetCMakeInstance();
   if (!gg->GetLanguageFromExtension(ext.c_str()).empty() ||
-      cm->IsSourceExtension(ext) || cm->IsHeaderExtension(ext)) {
+      cm->IsAKnownExtension(ext)) {
     // This is a known extension.  Use the given filename with extension.
     this->Name = cmSystemTools::GetFilenameName(name);
     this->AmbiguousExtension = false;
@@ -152,10 +154,10 @@
 
   // Only a fixed set of extensions will be tried to match a file on
   // disk.  One of these must match if loc refers to this source file.
-  std::string const& ext = this->Name.substr(loc.Name.size() + 1);
+  auto ext = cm::string_view(this->Name).substr(loc.Name.size() + 1);
   cmMakefile const* mf = this->Makefile;
   auto cm = mf->GetCMakeInstance();
-  return cm->IsSourceExtension(ext) || cm->IsHeaderExtension(ext);
+  return cm->IsAKnownExtension(ext);
 }
 
 bool cmSourceFileLocation::Matches(cmSourceFileLocation const& loc)
diff --git a/Source/cmSourceGroup.cxx b/Source/cmSourceGroup.cxx
index 8c3ec9f..155068cb 100644
--- a/Source/cmSourceGroup.cxx
+++ b/Source/cmSourceGroup.cxx
@@ -4,6 +4,8 @@
 
 #include <utility>
 
+#include <cm/memory>
+
 #include "cmStringAlgorithms.h"
 
 class cmSourceGroupInternals
@@ -16,7 +18,7 @@
                              const char* parentName)
   : Name(std::move(name))
 {
-  this->Internal = new cmSourceGroupInternals;
+  this->Internal = cm::make_unique<cmSourceGroupInternals>();
   this->SetGroupRegex(regex);
   if (parentName) {
     this->FullName = cmStrCat(parentName, '\\');
@@ -24,10 +26,7 @@
   this->FullName += this->Name;
 }
 
-cmSourceGroup::~cmSourceGroup()
-{
-  delete this->Internal;
-}
+cmSourceGroup::~cmSourceGroup() = default;
 
 cmSourceGroup::cmSourceGroup(cmSourceGroup const& r)
 {
@@ -36,7 +35,7 @@
   this->GroupRegex = r.GroupRegex;
   this->GroupFiles = r.GroupFiles;
   this->SourceFiles = r.SourceFiles;
-  this->Internal = new cmSourceGroupInternals(*r.Internal);
+  this->Internal = cm::make_unique<cmSourceGroupInternals>(*r.Internal);
 }
 
 cmSourceGroup& cmSourceGroup::operator=(cmSourceGroup const& r)
diff --git a/Source/cmSourceGroup.h b/Source/cmSourceGroup.h
index 581dc5d..623cded 100644
--- a/Source/cmSourceGroup.h
+++ b/Source/cmSourceGroup.h
@@ -5,6 +5,7 @@
 
 #include "cmConfigure.h" // IWYU pragma: keep
 
+#include <memory>
 #include <set>
 #include <string>
 #include <vector>
@@ -122,7 +123,7 @@
    */
   std::vector<const cmSourceFile*> SourceFiles;
 
-  cmSourceGroupInternals* Internal;
+  std::unique_ptr<cmSourceGroupInternals> Internal;
 };
 
 #endif
diff --git a/Source/cmSourceGroupCommand.cxx b/Source/cmSourceGroupCommand.cxx
index cc62952..bb75a14 100644
--- a/Source/cmSourceGroupCommand.cxx
+++ b/Source/cmSourceGroupCommand.cxx
@@ -7,7 +7,8 @@
 #include <set>
 #include <utility>
 
-#include "cmAlgorithms.h"
+#include <cmext/algorithm>
+
 #include "cmExecutionStatus.h"
 #include "cmMakefile.h"
 #include "cmSourceGroup.h"
@@ -30,18 +31,6 @@
   return cmTokenize(path, "\\/");
 }
 
-std::string getFullFilePath(const std::string& currentPath,
-                            const std::string& path)
-{
-  std::string fullPath = path;
-
-  if (!cmSystemTools::FileIsFullPath(path)) {
-    fullPath = cmStrCat(currentPath, '/', path);
-  }
-
-  return cmSystemTools::CollapseFullPath(fullPath);
-}
-
 std::set<std::string> getSourceGroupFilesPaths(
   const std::string& root, const std::vector<std::string>& files)
 {
@@ -124,7 +113,8 @@
         errorMsg = "Could not create source group for file: " + sgFilesPath;
         return false;
       }
-      const std::string fullPath = getFullFilePath(root, sgFilesPath);
+      const std::string fullPath =
+        cmSystemTools::CollapseFullPath(sgFilesPath, root);
       sg->AddGroupFile(fullPath);
     }
   }
@@ -147,7 +137,7 @@
 bool isExpectedOption(const std::string& argument,
                       const ExpectedOptions& expectedOptions)
 {
-  return cmContains(expectedOptions, argument);
+  return cm::contains(expectedOptions, argument);
 }
 
 void parseArguments(const std::vector<std::string>& args,
@@ -255,10 +245,8 @@
       parsedArguments[kFilesOptionName];
     for (auto const& filesArg : filesArguments) {
       std::string src = filesArg;
-      if (!cmSystemTools::FileIsFullPath(src)) {
-        src = cmStrCat(mf.GetCurrentSourceDirectory(), '/', filesArg);
-      }
-      src = cmSystemTools::CollapseFullPath(src);
+      src =
+        cmSystemTools::CollapseFullPath(src, mf.GetCurrentSourceDirectory());
       sg->AddGroupFile(src);
     }
   }
diff --git a/Source/cmStandardLevelResolver.cxx b/Source/cmStandardLevelResolver.cxx
new file mode 100644
index 0000000..6dbab98
--- /dev/null
+++ b/Source/cmStandardLevelResolver.cxx
@@ -0,0 +1,538 @@
+/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
+   file Copyright.txt or https://cmake.org/licensing for details.  */
+
+#include "cmStandardLevelResolver.h"
+
+#include <algorithm>
+#include <cassert>
+#include <cstddef>
+#include <sstream>
+#include <stdexcept>
+#include <unordered_map>
+#include <utility>
+#include <vector>
+
+#include <cm/iterator>
+#include <cmext/algorithm>
+
+#include "cmGeneratorExpression.h"
+#include "cmGeneratorTarget.h"
+#include "cmGlobalGenerator.h"
+#include "cmMakefile.h"
+#include "cmMessageType.h"
+#include "cmProperty.h"
+#include "cmStringAlgorithms.h"
+#include "cmTarget.h"
+#include "cmake.h"
+
+namespace {
+
+#define FEATURE_STRING(F) , #F
+const char* const C_FEATURES[] = { nullptr FOR_EACH_C_FEATURE(
+  FEATURE_STRING) };
+
+const char* const CXX_FEATURES[] = { nullptr FOR_EACH_CXX_FEATURE(
+  FEATURE_STRING) };
+
+const char* const CUDA_FEATURES[] = { nullptr FOR_EACH_CUDA_FEATURE(
+  FEATURE_STRING) };
+#undef FEATURE_STRING
+
+struct StandardNeeded
+{
+  int index;
+  int value;
+};
+
+struct StanardLevelComputer
+{
+  explicit StanardLevelComputer(std::string lang, std::vector<int> levels,
+                                std::vector<std::string> levelsStr)
+    : Language(std::move(lang))
+    , Levels(std::move(levels))
+    , LevelsAsStrings(std::move(levelsStr))
+  {
+    assert(levels.size() == levelsStr.size());
+  }
+
+  std::string GetCompileOptionDef(cmMakefile* makefile,
+                                  cmGeneratorTarget const* target,
+                                  std::string const& config) const
+  {
+
+    const auto& stds = this->Levels;
+    const auto& stdsStrings = this->LevelsAsStrings;
+
+    const char* defaultStd = makefile->GetDefinition(
+      cmStrCat("CMAKE_", this->Language, "_STANDARD_DEFAULT"));
+    if (!cmNonempty(defaultStd)) {
+      // this compiler has no notion of language standard levels
+      return std::string{};
+    }
+
+    bool ext = true;
+    if (cmProp extPropValue = target->GetLanguageExtensions(this->Language)) {
+      if (cmIsOff(*extPropValue)) {
+        ext = false;
+      }
+    }
+
+    cmProp standardProp = target->GetLanguageStandard(this->Language, config);
+    if (!standardProp) {
+      if (ext) {
+        // No language standard is specified and extensions are not disabled.
+        // Check if this compiler needs a flag to enable extensions.
+        return cmStrCat("CMAKE_", this->Language, "_EXTENSION_COMPILE_OPTION");
+      }
+      return std::string{};
+    }
+
+    std::string const type = ext ? "EXTENSION" : "STANDARD";
+
+    if (target->GetLanguageStandardRequired(this->Language)) {
+      std::string option_flag = cmStrCat(
+        "CMAKE_", this->Language, *standardProp, "_", type, "_COMPILE_OPTION");
+
+      const char* opt =
+        target->Target->GetMakefile()->GetDefinition(option_flag);
+      if (!opt) {
+        std::ostringstream e;
+        e << "Target \"" << target->GetName()
+          << "\" requires the language "
+             "dialect \""
+          << this->Language << *standardProp << "\" "
+          << (ext ? "(with compiler extensions)" : "")
+          << ", but CMake "
+             "does not know the compile flags to use to enable it.";
+        makefile->IssueMessage(MessageType::FATAL_ERROR, e.str());
+      }
+      return option_flag;
+    }
+
+    std::string standardStr(*standardProp);
+    if (this->Language == "CUDA" && standardStr == "98") {
+      standardStr = "03";
+    }
+
+    int standardValue = -1;
+    int defaultValue = -1;
+    try {
+      standardValue = std::stoi(standardStr);
+      defaultValue = std::stoi(defaultStd);
+    } catch (std::invalid_argument&) {
+      // fall through as we want an error
+      // when we can't find the bad value in the `stds` vector
+    }
+
+    auto stdIt = std::find(cm::cbegin(stds), cm::cend(stds), standardValue);
+    if (stdIt == cm::cend(stds)) {
+      std::string e =
+        cmStrCat(this->Language, "_STANDARD is set to invalid value '",
+                 standardStr, "'");
+      makefile->GetCMakeInstance()->IssueMessage(MessageType::FATAL_ERROR, e,
+                                                 target->GetBacktrace());
+      return std::string{};
+    }
+
+    auto defaultStdIt =
+      std::find(cm::cbegin(stds), cm::cend(stds), defaultValue);
+    if (defaultStdIt == cm::cend(stds)) {
+      std::string e = cmStrCat("CMAKE_", this->Language,
+                               "_STANDARD_DEFAULT is set to invalid value '",
+                               defaultStd, "'");
+      makefile->IssueMessage(MessageType::INTERNAL_ERROR, e);
+      return std::string{};
+    }
+
+    // If the standard requested is older than the compiler's default
+    // then we need to use a flag to change it.
+    if (stdIt <= defaultStdIt) {
+      auto offset = std::distance(cm::cbegin(stds), stdIt);
+      return cmStrCat("CMAKE_", this->Language, stdsStrings[offset], "_", type,
+                      "_COMPILE_OPTION");
+    }
+
+    // The standard requested is at least as new as the compiler's default,
+    // and the standard request is not required.  Decay to the newest standard
+    // for which a flag is defined.
+    for (; defaultStdIt < stdIt; --stdIt) {
+      auto offset = std::distance(cm::cbegin(stds), stdIt);
+      std::string option_flag =
+        cmStrCat("CMAKE_", this->Language, stdsStrings[offset], "_", type,
+                 "_COMPILE_OPTION");
+      if (target->Target->GetMakefile()->GetDefinition(option_flag)) {
+        return option_flag;
+      }
+    }
+
+    return std::string{};
+  }
+
+  bool GetNewRequiredStandard(cmMakefile* makefile,
+                              std::string const& targetName,
+                              const std::string& feature,
+                              cmProp currentLangStandardValue,
+                              std::string& newRequiredStandard,
+                              std::string* error) const
+  {
+    if (currentLangStandardValue) {
+      newRequiredStandard = *currentLangStandardValue;
+    } else {
+      newRequiredStandard.clear();
+    }
+
+    auto needed = this->HighestStandardNeeded(makefile, feature);
+
+    cmProp existingStandard = currentLangStandardValue;
+    if (existingStandard == nullptr) {
+      cmProp defaultStandard = makefile->GetDef(
+        cmStrCat("CMAKE_", this->Language, "_STANDARD_DEFAULT"));
+      if (cmNonempty(defaultStandard)) {
+        existingStandard = defaultStandard;
+      }
+    }
+
+    auto existingLevelIter = cm::cend(this->Levels);
+    if (existingStandard) {
+      existingLevelIter =
+        std::find(cm::cbegin(this->Levels), cm::cend(this->Levels),
+                  std::stoi(*existingStandard));
+      if (existingLevelIter == cm::cend(this->Levels)) {
+        const std::string e =
+          cmStrCat("The ", this->Language, "_STANDARD property on target \"",
+                   targetName, "\" contained an invalid value: \"",
+                   *existingStandard, "\".");
+        if (error) {
+          *error = e;
+        } else {
+          makefile->IssueMessage(MessageType::FATAL_ERROR, e);
+        }
+        return false;
+      }
+    }
+
+    if (needed.index != -1) {
+      // Ensure the C++ language level is high enough to support
+      // the needed C++ features.
+      if (existingLevelIter == cm::cend(this->Levels) ||
+          existingLevelIter < this->Levels.begin() + needed.index) {
+        newRequiredStandard = this->LevelsAsStrings[needed.index];
+      }
+    }
+
+    return true;
+  }
+
+  bool HaveStandardAvailable(cmMakefile* makefile,
+                             cmGeneratorTarget const* target,
+                             std::string const& config,
+                             std::string const& feature) const
+  {
+    cmProp defaultStandard = makefile->GetDef(
+      cmStrCat("CMAKE_", this->Language, "_STANDARD_DEFAULT"));
+    if (!defaultStandard) {
+      makefile->IssueMessage(
+        MessageType::INTERNAL_ERROR,
+        cmStrCat("CMAKE_", this->Language,
+                 "_STANDARD_DEFAULT is not set.  COMPILE_FEATURES support "
+                 "not fully configured for this compiler."));
+      // Return true so the caller does not try to lookup the default standard.
+      return true;
+    }
+    // convert defaultStandard to an integer
+    if (std::find(cm::cbegin(this->Levels), cm::cend(this->Levels),
+                  std::stoi(*defaultStandard)) == cm::cend(this->Levels)) {
+      const std::string e = cmStrCat("The CMAKE_", this->Language,
+                                     "_STANDARD_DEFAULT variable contains an "
+                                     "invalid value: \"",
+                                     *defaultStandard, "\".");
+      makefile->IssueMessage(MessageType::INTERNAL_ERROR, e);
+      return false;
+    }
+
+    cmProp existingStandard =
+      target->GetLanguageStandard(this->Language, config);
+    if (!existingStandard) {
+      existingStandard = defaultStandard;
+    }
+
+    auto existingLevelIter =
+      std::find(cm::cbegin(this->Levels), cm::cend(this->Levels),
+                std::stoi(*existingStandard));
+    if (existingLevelIter == cm::cend(this->Levels)) {
+      const std::string e =
+        cmStrCat("The ", this->Language, "_STANDARD property on target \"",
+                 target->GetName(), "\" contained an invalid value: \"",
+                 *existingStandard, "\".");
+      makefile->IssueMessage(MessageType::FATAL_ERROR, e);
+      return false;
+    }
+
+    auto needed = this->HighestStandardNeeded(makefile, feature);
+
+    return (needed.index == -1) ||
+      (this->Levels.begin() + needed.index) <= existingLevelIter;
+  }
+
+  StandardNeeded HighestStandardNeeded(cmMakefile* makefile,
+                                       std::string const& feature) const
+  {
+    std::string prefix = cmStrCat("CMAKE_", this->Language);
+    StandardNeeded maxLevel = { -1, -1 };
+    for (size_t i = 0; i < this->Levels.size(); ++i) {
+      if (const char* prop = makefile->GetDefinition(
+            cmStrCat(prefix, this->LevelsAsStrings[i], "_COMPILE_FEATURES"))) {
+        std::vector<std::string> props = cmExpandedList(prop);
+        if (cm::contains(props, feature)) {
+          maxLevel = { static_cast<int>(i), this->Levels[i] };
+        }
+      }
+    }
+    return maxLevel;
+  }
+
+  bool IsLaterStandard(int lhs, int rhs) const
+  {
+    auto rhsIt =
+      std::find(cm::cbegin(this->Levels), cm::cend(this->Levels), rhs);
+
+    return std::find(rhsIt, cm::cend(this->Levels), lhs) !=
+      cm::cend(this->Levels);
+  }
+
+  std::string Language;
+  std::vector<int> Levels;
+  std::vector<std::string> LevelsAsStrings;
+};
+
+std::unordered_map<std::string, StanardLevelComputer> StandardComputerMapping =
+  {
+    { "C",
+      StanardLevelComputer{ "C", std::vector<int>{ 90, 99, 11 },
+                            std::vector<std::string>{ "90", "99", "11" } } },
+    { "CXX",
+      StanardLevelComputer{
+        "CXX", std::vector<int>{ 98, 11, 14, 17, 20 },
+        std::vector<std::string>{ "98", "11", "14", "17", "20" } } },
+    { "CUDA",
+      StanardLevelComputer{
+        "CUDA", std::vector<int>{ 03, 11, 14, 17, 20 },
+        std::vector<std::string>{ "03", "11", "14", "17", "20" } } },
+    { "OBJC",
+      StanardLevelComputer{ "OBJC", std::vector<int>{ 90, 99, 11 },
+                            std::vector<std::string>{ "90", "99", "11" } } },
+    { "OBJCXX",
+      StanardLevelComputer{
+        "OBJCXX", std::vector<int>{ 98, 11, 14, 17, 20 },
+        std::vector<std::string>{ "98", "11", "14", "17", "20" } } },
+  };
+}
+
+std::string cmStandardLevelResolver::GetCompileOptionDef(
+  cmGeneratorTarget const* target, std::string const& lang,
+  std::string const& config) const
+{
+  const auto& mapping = StandardComputerMapping.find(lang);
+  if (mapping == cm::cend(StandardComputerMapping)) {
+    return std::string{};
+  }
+
+  return mapping->second.GetCompileOptionDef(this->Makefile, target, config);
+}
+
+bool cmStandardLevelResolver::AddRequiredTargetFeature(
+  cmTarget* target, const std::string& feature, std::string* error) const
+{
+  if (cmGeneratorExpression::Find(feature) != std::string::npos) {
+    target->AppendProperty("COMPILE_FEATURES", feature);
+    return true;
+  }
+
+  std::string lang;
+  if (!this->CheckCompileFeaturesAvailable(target->GetName(), feature, lang,
+                                           error)) {
+    return false;
+  }
+
+  target->AppendProperty("COMPILE_FEATURES", feature);
+
+  // FIXME: Add a policy to avoid updating the <LANG>_STANDARD target
+  // property due to COMPILE_FEATURES.  The language standard selection
+  // should be done purely at generate time based on whatever the project
+  // code put in these properties explicitly.  That is mostly true now,
+  // but for compatibility we need to continue updating the property here.
+  std::string newRequiredStandard;
+  bool newRequired = this->GetNewRequiredStandard(
+    target->GetName(), feature,
+    target->GetProperty(cmStrCat(lang, "_STANDARD")), newRequiredStandard,
+    error);
+  if (!newRequiredStandard.empty()) {
+    target->SetProperty(cmStrCat(lang, "_STANDARD"), newRequiredStandard);
+  }
+  return newRequired;
+}
+
+bool cmStandardLevelResolver::CheckCompileFeaturesAvailable(
+  const std::string& targetName, const std::string& feature, std::string& lang,
+  std::string* error) const
+{
+  if (!this->CompileFeatureKnown(targetName, feature, lang, error)) {
+    return false;
+  }
+
+  const char* features = this->CompileFeaturesAvailable(lang, error);
+  if (!features) {
+    return false;
+  }
+
+  std::vector<std::string> availableFeatures = cmExpandedList(features);
+  if (!cm::contains(availableFeatures, feature)) {
+    std::ostringstream e;
+    e << "The compiler feature \"" << feature << "\" is not known to " << lang
+      << " compiler\n\""
+      << this->Makefile->GetDefinition("CMAKE_" + lang + "_COMPILER_ID")
+      << "\"\nversion "
+      << this->Makefile->GetDefinition("CMAKE_" + lang + "_COMPILER_VERSION")
+      << ".";
+    if (error) {
+      *error = e.str();
+    } else {
+      this->Makefile->IssueMessage(MessageType::FATAL_ERROR, e.str());
+    }
+    return false;
+  }
+
+  return true;
+}
+
+bool cmStandardLevelResolver::CompileFeatureKnown(
+  const std::string& targetName, const std::string& feature, std::string& lang,
+  std::string* error) const
+{
+  assert(cmGeneratorExpression::Find(feature) == std::string::npos);
+
+  bool isCFeature =
+    std::find_if(cm::cbegin(C_FEATURES) + 1, cm::cend(C_FEATURES),
+                 cmStrCmp(feature)) != cm::cend(C_FEATURES);
+  if (isCFeature) {
+    lang = "C";
+    return true;
+  }
+  bool isCxxFeature =
+    std::find_if(cm::cbegin(CXX_FEATURES) + 1, cm::cend(CXX_FEATURES),
+                 cmStrCmp(feature)) != cm::cend(CXX_FEATURES);
+  if (isCxxFeature) {
+    lang = "CXX";
+    return true;
+  }
+  bool isCudaFeature =
+    std::find_if(cm::cbegin(CUDA_FEATURES) + 1, cm::cend(CUDA_FEATURES),
+                 cmStrCmp(feature)) != cm::cend(CUDA_FEATURES);
+  if (isCudaFeature) {
+    lang = "CUDA";
+    return true;
+  }
+  std::ostringstream e;
+  if (error) {
+    e << "specified";
+  } else {
+    e << "Specified";
+  }
+  e << " unknown feature \"" << feature
+    << "\" for "
+       "target \""
+    << targetName << "\".";
+  if (error) {
+    *error = e.str();
+  } else {
+    this->Makefile->IssueMessage(MessageType::FATAL_ERROR, e.str());
+  }
+  return false;
+}
+
+const char* cmStandardLevelResolver::CompileFeaturesAvailable(
+  const std::string& lang, std::string* error) const
+{
+  if (!this->Makefile->GetGlobalGenerator()->GetLanguageEnabled(lang)) {
+    std::ostringstream e;
+    if (error) {
+      e << "cannot";
+    } else {
+      e << "Cannot";
+    }
+    e << " use features from non-enabled language " << lang;
+    if (error) {
+      *error = e.str();
+    } else {
+      this->Makefile->IssueMessage(MessageType::FATAL_ERROR, e.str());
+    }
+    return nullptr;
+  }
+
+  const char* featuresKnown =
+    this->Makefile->GetDefinition("CMAKE_" + lang + "_COMPILE_FEATURES");
+
+  if (!cmNonempty(featuresKnown)) {
+    std::ostringstream e;
+    if (error) {
+      e << "no";
+    } else {
+      e << "No";
+    }
+    e << " known features for " << lang << " compiler\n\""
+      << this->Makefile->GetSafeDefinition("CMAKE_" + lang + "_COMPILER_ID")
+      << "\"\nversion "
+      << this->Makefile->GetSafeDefinition("CMAKE_" + lang +
+                                           "_COMPILER_VERSION")
+      << ".";
+    if (error) {
+      *error = e.str();
+    } else {
+      this->Makefile->IssueMessage(MessageType::FATAL_ERROR, e.str());
+    }
+    return nullptr;
+  }
+  return featuresKnown;
+}
+
+bool cmStandardLevelResolver::GetNewRequiredStandard(
+  const std::string& targetName, const std::string& feature,
+  cmProp currentLangStandardValue, std::string& newRequiredStandard,
+  std::string* error) const
+{
+  std::string lang;
+  if (!this->CheckCompileFeaturesAvailable(targetName, feature, lang, error)) {
+    return false;
+  }
+
+  auto mapping = StandardComputerMapping.find(lang);
+  if (mapping != cm::cend(StandardComputerMapping)) {
+    return mapping->second.GetNewRequiredStandard(
+      this->Makefile, targetName, feature, currentLangStandardValue,
+      newRequiredStandard, error);
+  }
+  return false;
+}
+
+bool cmStandardLevelResolver::HaveStandardAvailable(
+  cmGeneratorTarget const* target, std::string const& lang,
+  std::string const& config, const std::string& feature) const
+{
+  auto mapping = StandardComputerMapping.find(lang);
+  if (mapping != cm::cend(StandardComputerMapping)) {
+    return mapping->second.HaveStandardAvailable(this->Makefile, target,
+                                                 config, feature);
+  }
+  return false;
+}
+
+bool cmStandardLevelResolver::IsLaterStandard(std::string const& lang,
+                                              std::string const& lhs,
+                                              std::string const& rhs) const
+{
+  auto mapping = StandardComputerMapping.find(lang);
+  if (mapping != cm::cend(StandardComputerMapping)) {
+    return mapping->second.IsLaterStandard(std::stoi(lhs), std::stoi(rhs));
+  }
+  return false;
+}
diff --git a/Source/cmStandardLevelResolver.h b/Source/cmStandardLevelResolver.h
new file mode 100644
index 0000000..959a5f9
--- /dev/null
+++ b/Source/cmStandardLevelResolver.h
@@ -0,0 +1,59 @@
+/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
+   file Copyright.txt or https://cmake.org/licensing for details.  */
+#ifndef cmStandardLevelResolver_h
+#define cmStandardLevelResolver_h
+
+#include <string>
+
+#include "cmProperty.h"
+
+class cmMakefile;
+class cmGeneratorTarget;
+class cmTarget;
+
+class cmStandardLevelResolver
+{
+
+public:
+  explicit cmStandardLevelResolver(cmMakefile* makefile)
+    : Makefile(makefile)
+  {
+  }
+
+  std::string GetCompileOptionDef(cmGeneratorTarget const* target,
+                                  std::string const& lang,
+                                  std::string const& config) const;
+
+  bool AddRequiredTargetFeature(cmTarget* target, const std::string& feature,
+                                std::string* error = nullptr) const;
+
+  bool CompileFeatureKnown(const std::string& targetName,
+                           const std::string& feature, std::string& lang,
+                           std::string* error) const;
+
+  const char* CompileFeaturesAvailable(const std::string& lang,
+                                       std::string* error) const;
+
+  bool GetNewRequiredStandard(const std::string& targetName,
+                              const std::string& feature,
+                              cmProp currentLangStandardValue,
+                              std::string& newRequiredStandard,
+                              std::string* error = nullptr) const;
+
+  bool HaveStandardAvailable(cmGeneratorTarget const* target,
+                             std::string const& lang,
+                             std::string const& config,
+                             const std::string& feature) const;
+
+  bool IsLaterStandard(std::string const& lang, std::string const& lhs,
+                       std::string const& rhs) const;
+
+private:
+  bool CheckCompileFeaturesAvailable(const std::string& targetName,
+                                     const std::string& feature,
+                                     std::string& lang,
+                                     std::string* error) const;
+
+  cmMakefile* Makefile;
+};
+#endif
diff --git a/Source/cmStandardLexer.h b/Source/cmStandardLexer.h
index 13f7622..e0b2116 100644
--- a/Source/cmStandardLexer.h
+++ b/Source/cmStandardLexer.h
@@ -3,6 +3,23 @@
 #ifndef cmStandardLexer_h
 #define cmStandardLexer_h
 
+#if defined(__linux)
+/* Needed for glibc < 2.12 */
+#  define _XOPEN_SOURCE 600
+#endif
+#if !defined(_WIN32) && !defined(__sun)
+/* POSIX APIs are needed */
+#  define _POSIX_C_SOURCE 200809L
+#endif
+#if defined(__sun) && defined(__GNUC__) && !defined(__cplusplus)
+/* C sources: for fileno and strdup */
+#  define _XOPEN_SOURCE 600
+#endif
+#if defined(__OpenBSD__) || defined(__FreeBSD__) || defined(__NetBSD__)
+/* For isascii */
+#  define _XOPEN_SOURCE 700
+#endif
+
 #include "cmsys/Configure.h" // IWYU pragma: keep
 
 /* Disable some warnings.  */
@@ -50,7 +67,7 @@
 #define YY_NO_UNPUT 1
 #define ECHO
 
-#include "cm_kwiml.h"
+#include <cm3p/kwiml/int.h>
 typedef KWIML_INT_int8_t flex_int8_t;
 typedef KWIML_INT_uint8_t flex_uint8_t;
 typedef KWIML_INT_int16_t flex_int16_t;
diff --git a/Source/cmState.cxx b/Source/cmState.cxx
index 9fc7615..73f166c 100644
--- a/Source/cmState.cxx
+++ b/Source/cmState.cxx
@@ -34,30 +34,44 @@
 
 cmState::~cmState() = default;
 
-const char* cmState::GetTargetTypeName(cmStateEnums::TargetType targetType)
+const std::string& cmState::GetTargetTypeName(
+  cmStateEnums::TargetType targetType)
 {
+#define MAKE_STATIC_PROP(PROP) static const std::string prop##PROP = #PROP
+  MAKE_STATIC_PROP(STATIC_LIBRARY);
+  MAKE_STATIC_PROP(MODULE_LIBRARY);
+  MAKE_STATIC_PROP(SHARED_LIBRARY);
+  MAKE_STATIC_PROP(OBJECT_LIBRARY);
+  MAKE_STATIC_PROP(EXECUTABLE);
+  MAKE_STATIC_PROP(UTILITY);
+  MAKE_STATIC_PROP(GLOBAL_TARGET);
+  MAKE_STATIC_PROP(INTERFACE_LIBRARY);
+  MAKE_STATIC_PROP(UNKNOWN_LIBRARY);
+  static const std::string propEmpty;
+#undef MAKE_STATIC_PROP
+
   switch (targetType) {
     case cmStateEnums::STATIC_LIBRARY:
-      return "STATIC_LIBRARY";
+      return propSTATIC_LIBRARY;
     case cmStateEnums::MODULE_LIBRARY:
-      return "MODULE_LIBRARY";
+      return propMODULE_LIBRARY;
     case cmStateEnums::SHARED_LIBRARY:
-      return "SHARED_LIBRARY";
+      return propSHARED_LIBRARY;
     case cmStateEnums::OBJECT_LIBRARY:
-      return "OBJECT_LIBRARY";
+      return propOBJECT_LIBRARY;
     case cmStateEnums::EXECUTABLE:
-      return "EXECUTABLE";
+      return propEXECUTABLE;
     case cmStateEnums::UTILITY:
-      return "UTILITY";
+      return propUTILITY;
     case cmStateEnums::GLOBAL_TARGET:
-      return "GLOBAL_TARGET";
+      return propGLOBAL_TARGET;
     case cmStateEnums::INTERFACE_LIBRARY:
-      return "INTERFACE_LIBRARY";
+      return propINTERFACE_LIBRARY;
     case cmStateEnums::UNKNOWN_LIBRARY:
-      return "UNKNOWN_LIBRARY";
+      return propUNKNOWN_LIBRARY;
   }
   assert(false && "Unexpected target type");
-  return nullptr;
+  return propEmpty;
 }
 
 static const std::array<std::string, 7> cmCacheEntryTypes = {
@@ -123,36 +137,23 @@
 
 std::vector<std::string> cmState::GetCacheEntryKeys() const
 {
-  std::vector<std::string> definitions;
-  definitions.reserve(this->CacheManager->GetSize());
-  cmCacheManager::CacheIterator cit = this->CacheManager->GetCacheIterator();
-  for (cit.Begin(); !cit.IsAtEnd(); cit.Next()) {
-    definitions.push_back(cit.GetName());
-  }
-  return definitions;
+  return this->CacheManager->GetCacheEntryKeys();
 }
 
-const char* cmState::GetCacheEntryValue(std::string const& key) const
+cmProp cmState::GetCacheEntryValue(std::string const& key) const
 {
-  cmCacheManager::CacheEntry* e = this->CacheManager->GetCacheEntry(key);
-  if (!e) {
-    return nullptr;
-  }
-  return e->Value.c_str();
+  return this->CacheManager->GetCacheEntryValue(key);
 }
 
 std::string cmState::GetSafeCacheEntryValue(std::string const& key) const
 {
-  std::string retval;
-  auto val = this->GetCacheEntryValue(key);
-  if (val) {
-    retval = val;
+  if (cmProp val = this->GetCacheEntryValue(key)) {
+    return *val;
   }
-  return retval;
+  return std::string();
 }
 
-const std::string* cmState::GetInitializedCacheValue(
-  std::string const& key) const
+cmProp cmState::GetInitializedCacheValue(std::string const& key) const
 {
   return this->CacheManager->GetInitializedCacheValue(key);
 }
@@ -160,8 +161,7 @@
 cmStateEnums::CacheEntryType cmState::GetCacheEntryType(
   std::string const& key) const
 {
-  cmCacheManager::CacheIterator it = this->CacheManager->GetCacheIterator(key);
-  return it.GetType();
+  return this->CacheManager->GetCacheEntryType(key);
 }
 
 void cmState::SetCacheEntryValue(std::string const& key,
@@ -174,40 +174,32 @@
                                     std::string const& propertyName,
                                     std::string const& value)
 {
-  cmCacheManager::CacheIterator it = this->CacheManager->GetCacheIterator(key);
-  it.SetProperty(propertyName, value.c_str());
+  this->CacheManager->SetCacheEntryProperty(key, propertyName, value);
 }
 
 void cmState::SetCacheEntryBoolProperty(std::string const& key,
                                         std::string const& propertyName,
                                         bool value)
 {
-  cmCacheManager::CacheIterator it = this->CacheManager->GetCacheIterator(key);
-  it.SetProperty(propertyName, value);
+  this->CacheManager->SetCacheEntryBoolProperty(key, propertyName, value);
 }
 
 std::vector<std::string> cmState::GetCacheEntryPropertyList(
   const std::string& key)
 {
-  cmCacheManager::CacheIterator it = this->CacheManager->GetCacheIterator(key);
-  return it.GetPropertyList();
+  return this->CacheManager->GetCacheEntryPropertyList(key);
 }
 
-const char* cmState::GetCacheEntryProperty(std::string const& key,
-                                           std::string const& propertyName)
+cmProp cmState::GetCacheEntryProperty(std::string const& key,
+                                      std::string const& propertyName)
 {
-  cmCacheManager::CacheIterator it = this->CacheManager->GetCacheIterator(key);
-  if (!it.PropertyExists(propertyName)) {
-    return nullptr;
-  }
-  return it.GetProperty(propertyName);
+  return this->CacheManager->GetCacheEntryProperty(key, propertyName);
 }
 
 bool cmState::GetCacheEntryPropertyAsBool(std::string const& key,
                                           std::string const& propertyName)
 {
-  return this->CacheManager->GetCacheIterator(key).GetPropertyAsBool(
-    propertyName);
+  return this->CacheManager->GetCacheEntryPropertyAsBool(key, propertyName);
 }
 
 void cmState::AddCacheEntry(const std::string& key, const char* value,
@@ -259,20 +251,19 @@
                                        const std::string& property,
                                        const std::string& value, bool asString)
 {
-  this->CacheManager->GetCacheIterator(key).AppendProperty(property, value,
-                                                           asString);
+  this->CacheManager->AppendCacheEntryProperty(key, property, value, asString);
 }
 
 void cmState::RemoveCacheEntryProperty(std::string const& key,
                                        std::string const& propertyName)
 {
-  this->CacheManager->GetCacheIterator(key).SetProperty(propertyName, nullptr);
+  this->CacheManager->RemoveCacheEntryProperty(key, propertyName);
 }
 
 cmStateSnapshot cmState::Reset()
 {
   this->GlobalProperties.Clear();
-  this->PropertyDefinitions.clear();
+  this->PropertyDefinitions = {};
   this->GlobVerificationManager->Reset();
 
   cmStateDetail::PositionType pos = this->SnapshotData.Truncate();
@@ -335,42 +326,26 @@
 
 void cmState::DefineProperty(const std::string& name,
                              cmProperty::ScopeType scope,
-                             const char* ShortDescription,
-                             const char* FullDescription, bool chained)
+                             const std::string& ShortDescription,
+                             const std::string& FullDescription, bool chained)
 {
-  this->PropertyDefinitions[scope].DefineProperty(
-    name, scope, ShortDescription, FullDescription, chained);
+  this->PropertyDefinitions.DefineProperty(name, scope, ShortDescription,
+                                           FullDescription, chained);
 }
 
 cmPropertyDefinition const* cmState::GetPropertyDefinition(
   const std::string& name, cmProperty::ScopeType scope) const
 {
-  if (this->IsPropertyDefined(name, scope)) {
-    cmPropertyDefinitionMap const& defs =
-      this->PropertyDefinitions.find(scope)->second;
-    return &defs.find(name)->second;
-  }
-  return nullptr;
-}
-
-bool cmState::IsPropertyDefined(const std::string& name,
-                                cmProperty::ScopeType scope) const
-{
-  auto it = this->PropertyDefinitions.find(scope);
-  if (it == this->PropertyDefinitions.end()) {
-    return false;
-  }
-  return it->second.IsPropertyDefined(name);
+  return this->PropertyDefinitions.GetPropertyDefinition(name, scope);
 }
 
 bool cmState::IsPropertyChained(const std::string& name,
                                 cmProperty::ScopeType scope) const
 {
-  auto it = this->PropertyDefinitions.find(scope);
-  if (it == this->PropertyDefinitions.end()) {
-    return false;
+  if (auto def = this->GetPropertyDefinition(name, scope)) {
+    return def->IsChained();
   }
-  return it->second.IsPropertyChained(name);
+  return false;
 }
 
 void cmState::SetLanguageEnabled(std::string const& l)
@@ -573,7 +548,7 @@
   this->GlobalProperties.AppendProperty(prop, value, asString);
 }
 
-const char* cmState::GetGlobalProperty(const std::string& prop)
+cmProp cmState::GetGlobalProperty(const std::string& prop)
 {
   if (prop == "CACHE_VARIABLES") {
     std::vector<std::string> cacheKeys = this->GetCacheEntryKeys();
@@ -597,31 +572,49 @@
   }
 #define STRING_LIST_ELEMENT(F) ";" #F
   if (prop == "CMAKE_C_KNOWN_FEATURES") {
-    return &FOR_EACH_C_FEATURE(STRING_LIST_ELEMENT)[1];
+    static const std::string s_out(
+      &FOR_EACH_C_FEATURE(STRING_LIST_ELEMENT)[1]);
+    return &s_out;
   }
   if (prop == "CMAKE_C90_KNOWN_FEATURES") {
-    return &FOR_EACH_C90_FEATURE(STRING_LIST_ELEMENT)[1];
+    static const std::string s_out(
+      &FOR_EACH_C90_FEATURE(STRING_LIST_ELEMENT)[1]);
+    return &s_out;
   }
   if (prop == "CMAKE_C99_KNOWN_FEATURES") {
-    return &FOR_EACH_C99_FEATURE(STRING_LIST_ELEMENT)[1];
+    static const std::string s_out(
+      &FOR_EACH_C99_FEATURE(STRING_LIST_ELEMENT)[1]);
+    return &s_out;
   }
   if (prop == "CMAKE_C11_KNOWN_FEATURES") {
-    return &FOR_EACH_C11_FEATURE(STRING_LIST_ELEMENT)[1];
+    static const std::string s_out(
+      &FOR_EACH_C11_FEATURE(STRING_LIST_ELEMENT)[1]);
+    return &s_out;
   }
   if (prop == "CMAKE_CXX_KNOWN_FEATURES") {
-    return &FOR_EACH_CXX_FEATURE(STRING_LIST_ELEMENT)[1];
+    static const std::string s_out(
+      &FOR_EACH_CXX_FEATURE(STRING_LIST_ELEMENT)[1]);
+    return &s_out;
   }
   if (prop == "CMAKE_CXX98_KNOWN_FEATURES") {
-    return &FOR_EACH_CXX98_FEATURE(STRING_LIST_ELEMENT)[1];
+    static const std::string s_out(
+      &FOR_EACH_CXX98_FEATURE(STRING_LIST_ELEMENT)[1]);
+    return &s_out;
   }
   if (prop == "CMAKE_CXX11_KNOWN_FEATURES") {
-    return &FOR_EACH_CXX11_FEATURE(STRING_LIST_ELEMENT)[1];
+    static const std::string s_out(
+      &FOR_EACH_CXX11_FEATURE(STRING_LIST_ELEMENT)[1]);
+    return &s_out;
   }
   if (prop == "CMAKE_CXX14_KNOWN_FEATURES") {
-    return &FOR_EACH_CXX14_FEATURE(STRING_LIST_ELEMENT)[1];
+    static const std::string s_out(
+      &FOR_EACH_CXX14_FEATURE(STRING_LIST_ELEMENT)[1]);
+    return &s_out;
   }
   if (prop == "CMAKE_CUDA_KNOWN_FEATURES") {
-    return &FOR_EACH_CUDA_FEATURE(STRING_LIST_ELEMENT)[1];
+    static const std::string s_out(
+      &FOR_EACH_CUDA_FEATURE(STRING_LIST_ELEMENT)[1]);
+    return &s_out;
   }
 
 #undef STRING_LIST_ELEMENT
diff --git a/Source/cmState.h b/Source/cmState.h
index 6ee2b0c..885496a 100644
--- a/Source/cmState.h
+++ b/Source/cmState.h
@@ -17,7 +17,7 @@
 #include "cmListFileCache.h"
 #include "cmPolicies.h"
 #include "cmProperty.h"
-#include "cmPropertyDefinitionMap.h"
+#include "cmPropertyDefinition.h"
 #include "cmPropertyMap.h"
 #include "cmStatePrivate.h"
 #include "cmStateTypes.h"
@@ -25,7 +25,6 @@
 class cmCacheManager;
 class cmCommand;
 class cmGlobVerificationManager;
-class cmPropertyDefinition;
 class cmStateSnapshot;
 class cmMessenger;
 class cmExecutionStatus;
@@ -51,7 +50,8 @@
     CPack,
   };
 
-  static const char* GetTargetTypeName(cmStateEnums::TargetType targetType);
+  static const std::string& GetTargetTypeName(
+    cmStateEnums::TargetType targetType);
 
   cmStateSnapshot CreateBaseSnapshot();
   cmStateSnapshot CreateBuildsystemDirectorySnapshot(
@@ -87,12 +87,11 @@
   bool DeleteCache(const std::string& path);
 
   std::vector<std::string> GetCacheEntryKeys() const;
-  const char* GetCacheEntryValue(std::string const& key) const;
+  cmProp GetCacheEntryValue(std::string const& key) const;
   std::string GetSafeCacheEntryValue(std::string const& key) const;
-  const std::string* GetInitializedCacheValue(std::string const& key) const;
+  cmProp GetInitializedCacheValue(std::string const& key) const;
   cmStateEnums::CacheEntryType GetCacheEntryType(std::string const& key) const;
   void SetCacheEntryValue(std::string const& key, std::string const& value);
-  void SetCacheValue(std::string const& key, std::string const& value);
 
   void RemoveCacheEntry(std::string const& key);
 
@@ -102,8 +101,8 @@
   void SetCacheEntryBoolProperty(std::string const& key,
                                  std::string const& propertyName, bool value);
   std::vector<std::string> GetCacheEntryPropertyList(std::string const& key);
-  const char* GetCacheEntryProperty(std::string const& key,
-                                    std::string const& propertyName);
+  cmProp GetCacheEntryProperty(std::string const& key,
+                               std::string const& propertyName);
   bool GetCacheEntryPropertyAsBool(std::string const& key,
                                    std::string const& propertyName);
   void AppendCacheEntryProperty(std::string const& key,
@@ -121,16 +120,13 @@
   cmStateSnapshot Reset();
   // Define a property
   void DefineProperty(const std::string& name, cmProperty::ScopeType scope,
-                      const char* ShortDescription,
-                      const char* FullDescription, bool chain = false);
+                      const std::string& ShortDescription,
+                      const std::string& FullDescription, bool chain = false);
 
   // get property definition
   cmPropertyDefinition const* GetPropertyDefinition(
     const std::string& name, cmProperty::ScopeType scope) const;
 
-  // Is a property defined?
-  bool IsPropertyDefined(const std::string& name,
-                         cmProperty::ScopeType scope) const;
   bool IsPropertyChained(const std::string& name,
                          cmProperty::ScopeType scope) const;
 
@@ -171,7 +167,7 @@
   void SetGlobalProperty(const std::string& prop, const char* value);
   void AppendGlobalProperty(const std::string& prop, const std::string& value,
                             bool asString = false);
-  const char* GetGlobalProperty(const std::string& prop);
+  cmProp GetGlobalProperty(const std::string& prop);
   bool GetGlobalPropertyAsBool(const std::string& prop);
 
   std::string const& GetSourceDirectory() const;
@@ -222,7 +218,7 @@
                          const std::string& variable,
                          cmListFileBacktrace const& bt);
 
-  std::map<cmProperty::ScopeType, cmPropertyDefinitionMap> PropertyDefinitions;
+  cmPropertyDefinitionMap PropertyDefinitions;
   std::vector<std::string> EnabledLanguages;
   std::map<std::string, Command> BuiltinCommands;
   std::map<std::string, Command> ScriptedCommands;
diff --git a/Source/cmStateDirectory.cxx b/Source/cmStateDirectory.cxx
index 4f003ed..796bb1f 100644
--- a/Source/cmStateDirectory.cxx
+++ b/Source/cmStateDirectory.cxx
@@ -548,32 +548,31 @@
   this->DirectoryState->Properties.AppendProperty(prop, value, asString);
 }
 
-const char* cmStateDirectory::GetProperty(const std::string& prop) const
+cmProp cmStateDirectory::GetProperty(const std::string& prop) const
 {
   const bool chain =
     this->Snapshot_.State->IsPropertyChained(prop, cmProperty::DIRECTORY);
   return this->GetProperty(prop, chain);
 }
 
-const char* cmStateDirectory::GetProperty(const std::string& prop,
-                                          bool chain) const
+cmProp cmStateDirectory::GetProperty(const std::string& prop, bool chain) const
 {
   static std::string output;
   output.clear();
   if (prop == "PARENT_DIRECTORY") {
     cmStateSnapshot parent = this->Snapshot_.GetBuildsystemDirectoryParent();
     if (parent.IsValid()) {
-      return parent.GetDirectory().GetCurrentSource().c_str();
+      return &parent.GetDirectory().GetCurrentSource();
     }
-    return "";
+    return &output;
   }
   if (prop == kBINARY_DIR) {
     output = this->GetCurrentBinary();
-    return output.c_str();
+    return &output;
   }
   if (prop == kSOURCE_DIR) {
     output = this->GetCurrentSource();
-    return output.c_str();
+    return &output;
   }
   if (prop == kSUBDIRECTORIES) {
     std::vector<std::string> child_dirs;
@@ -584,11 +583,11 @@
       child_dirs.push_back(ci.GetDirectory().GetCurrentSource());
     }
     output = cmJoin(child_dirs, ";");
-    return output.c_str();
+    return &output;
   }
   if (prop == kBUILDSYSTEM_TARGETS) {
     output = cmJoin(this->DirectoryState->NormalTargetNames, ";");
-    return output.c_str();
+    return &output;
   }
 
   if (prop == "LISTFILE_STACK") {
@@ -600,41 +599,41 @@
     }
     std::reverse(listFiles.begin(), listFiles.end());
     output = cmJoin(listFiles, ";");
-    return output.c_str();
+    return &output;
   }
   if (prop == "CACHE_VARIABLES") {
     output = cmJoin(this->Snapshot_.State->GetCacheEntryKeys(), ";");
-    return output.c_str();
+    return &output;
   }
   if (prop == "VARIABLES") {
     std::vector<std::string> res = this->Snapshot_.ClosureKeys();
     cm::append(res, this->Snapshot_.State->GetCacheEntryKeys());
     std::sort(res.begin(), res.end());
     output = cmJoin(res, ";");
-    return output.c_str();
+    return &output;
   }
   if (prop == "INCLUDE_DIRECTORIES") {
     output = cmJoin(this->GetIncludeDirectoriesEntries(), ";");
-    return output.c_str();
+    return &output;
   }
   if (prop == "COMPILE_OPTIONS") {
     output = cmJoin(this->GetCompileOptionsEntries(), ";");
-    return output.c_str();
+    return &output;
   }
   if (prop == "COMPILE_DEFINITIONS") {
     output = cmJoin(this->GetCompileDefinitionsEntries(), ";");
-    return output.c_str();
+    return &output;
   }
   if (prop == "LINK_OPTIONS") {
     output = cmJoin(this->GetLinkOptionsEntries(), ";");
-    return output.c_str();
+    return &output;
   }
   if (prop == "LINK_DIRECTORIES") {
     output = cmJoin(this->GetLinkDirectoriesEntries(), ";");
-    return output.c_str();
+    return &output;
   }
 
-  const char* retVal = this->DirectoryState->Properties.GetPropertyValue(prop);
+  cmProp retVal = this->DirectoryState->Properties.GetPropertyValue(prop);
   if (!retVal && chain) {
     cmStateSnapshot parentSnapshot =
       this->Snapshot_.GetBuildsystemDirectoryParent();
diff --git a/Source/cmStateDirectory.h b/Source/cmStateDirectory.h
index 53a2d54..765af6f 100644
--- a/Source/cmStateDirectory.h
+++ b/Source/cmStateDirectory.h
@@ -12,6 +12,7 @@
 #include "cmAlgorithms.h"
 #include "cmLinkedTree.h"
 #include "cmListFileCache.h"
+#include "cmProperty.h"
 #include "cmStatePrivate.h"
 #include "cmStateSnapshot.h"
 #include "cmStringAlgorithms.h"
@@ -86,8 +87,8 @@
                    cmListFileBacktrace const& lfbt);
   void AppendProperty(const std::string& prop, const std::string& value,
                       bool asString, cmListFileBacktrace const& lfbt);
-  const char* GetProperty(const std::string& prop) const;
-  const char* GetProperty(const std::string& prop, bool chain) const;
+  cmProp GetProperty(const std::string& prop) const;
+  cmProp GetProperty(const std::string& prop, bool chain) const;
   bool GetPropertyAsBool(const std::string& prop) const;
   std::vector<std::string> GetPropertyKeys() const;
 
diff --git a/Source/cmStateSnapshot.cxx b/Source/cmStateSnapshot.cxx
index 832e74e..bf8e331 100644
--- a/Source/cmStateSnapshot.cxx
+++ b/Source/cmStateSnapshot.cxx
@@ -11,6 +11,7 @@
 
 #include "cmDefinitions.h"
 #include "cmListFileCache.h"
+#include "cmProperty.h"
 #include "cmPropertyMap.h"
 #include "cmState.h"
 #include "cmStateDirectory.h"
@@ -147,7 +148,7 @@
 
 bool cmStateSnapshot::CanPopPolicyScope()
 {
-  return this->Position->Policies == this->Position->PolicyScope;
+  return this->Position->Policies != this->Position->PolicyScope;
 }
 
 void cmStateSnapshot::SetPolicy(cmPolicies::PolicyID id,
@@ -231,11 +232,6 @@
   this->Position->Vars->Unset(name);
 }
 
-std::vector<std::string> cmStateSnapshot::UnusedKeys() const
-{
-  return this->Position->Vars->UnusedKeys();
-}
-
 std::vector<std::string> cmStateSnapshot::ClosureKeys() const
 {
   return cmDefinitions::ClosureKeys(this->Position->Vars,
@@ -327,7 +323,7 @@
 #if defined(__CYGWIN__)
   std::string legacy;
   if (cmSystemTools::GetEnv("CMAKE_LEGACY_CYGWIN_WIN32", legacy) &&
-      cmIsOn(legacy.c_str())) {
+      cmIsOn(legacy)) {
     this->SetDefinition("WIN32", "1");
     this->SetDefinition("CMAKE_HOST_WIN32", "1");
   }
@@ -411,11 +407,12 @@
     this->Position->BuildSystemDirectory->LinkDirectoriesBacktraces,
     this->Position->LinkDirectoriesPosition);
 
-  const char* include_regex =
+  cmProp include_regex =
     parent->BuildSystemDirectory->Properties.GetPropertyValue(
       "INCLUDE_REGULAR_EXPRESSION");
   this->Position->BuildSystemDirectory->Properties.SetProperty(
-    "INCLUDE_REGULAR_EXPRESSION", include_regex);
+    "INCLUDE_REGULAR_EXPRESSION",
+    include_regex ? include_regex->c_str() : nullptr);
 }
 
 cmState* cmStateSnapshot::GetState() const
diff --git a/Source/cmStateSnapshot.h b/Source/cmStateSnapshot.h
index 021fd53..c19f174 100644
--- a/Source/cmStateSnapshot.h
+++ b/Source/cmStateSnapshot.h
@@ -28,7 +28,6 @@
   bool IsInitialized(std::string const& name) const;
   void SetDefinition(std::string const& name, cm::string_view value);
   void RemoveDefinition(std::string const& name);
-  std::vector<std::string> UnusedKeys() const;
   std::vector<std::string> ClosureKeys() const;
   bool RaiseScope(std::string const& var, const char* varDef);
 
diff --git a/Source/cmString.cxx b/Source/cmString.cxx
index 2a0c125..898b828 100644
--- a/Source/cmString.cxx
+++ b/Source/cmString.cxx
@@ -17,7 +17,7 @@
 void String::internally_mutate_to_stable_string()
 {
   // We assume that only one thread mutates this instance at
-  // a time even if we point to a shared string buffer refernced
+  // a time even if we point to a shared string buffer referenced
   // by other threads.
   *this = String(data(), size());
 }
diff --git a/Source/cmString.hxx b/Source/cmString.hxx
index 9e91986..40fe20d 100644
--- a/Source/cmString.hxx
+++ b/Source/cmString.hxx
@@ -16,8 +16,7 @@
 #include <utility>
 
 #include <cm/string_view>
-
-#include "cm_static_string_view.hxx"
+#include <cmext/string_view>
 
 namespace cm {
 
@@ -384,7 +383,7 @@
       instance is mutated or destroyed.  */
   std::string const* str_if_stable() const;
 
-  /** Get a refernce to a normal std::string.  The reference
+  /** Get a reference to a normal std::string.  The reference
       is valid until this instance is mutated or destroyed.  */
   std::string const& str();
 
diff --git a/Source/cmStringAlgorithms.cxx b/Source/cmStringAlgorithms.cxx
index bb6dcd7..71d28a4 100644
--- a/Source/cmStringAlgorithms.cxx
+++ b/Source/cmStringAlgorithms.cxx
@@ -4,7 +4,7 @@
 
 #include <algorithm>
 #include <cerrno>
-#include <cstddef>
+#include <cstddef> // IWYU pragma: keep
 #include <cstdio>
 #include <cstdlib>
 
diff --git a/Source/cmStringAlgorithms.h b/Source/cmStringAlgorithms.h
index 0e405de..4b0090b 100644
--- a/Source/cmStringAlgorithms.h
+++ b/Source/cmStringAlgorithms.h
@@ -20,6 +20,20 @@
 /** String range type.  */
 using cmStringRange = cmRange<std::vector<std::string>::const_iterator>;
 
+/** Check for non-empty string.  */
+inline bool cmNonempty(const char* str)
+{
+  return str && *str;
+}
+inline bool cmNonempty(cm::string_view str)
+{
+  return !str.empty();
+}
+inline bool cmNonempty(std::string const* str)
+{
+  return str && !str->empty();
+}
+
 /** Callable string comparison struct.  */
 struct cmStrCmp
 {
@@ -87,7 +101,7 @@
                    std::vector<std::string>& argsOut)
 {
   for (; first != last; ++first) {
-    ExpandList(*first, argsOut);
+    cmExpandList(*first, argsOut);
   }
 }
 
@@ -205,10 +219,11 @@
 bool cmIsOn(cm::string_view val);
 inline bool cmIsOn(const char* val)
 {
-  if (!val) {
-    return false;
-  }
-  return cmIsOn(cm::string_view(val));
+  return val && cmIsOn(cm::string_view(val));
+}
+inline bool cmIsOn(std::string const* val)
+{
+  return val && cmIsOn(*val);
 }
 
 /**
@@ -221,10 +236,11 @@
 bool cmIsOff(cm::string_view val);
 inline bool cmIsOff(const char* val)
 {
-  if (!val) {
-    return true;
-  }
-  return cmIsOff(cm::string_view(val));
+  return !val || cmIsOff(cm::string_view(val));
+}
+inline bool cmIsOff(std::string const* val)
+{
+  return !val || cmIsOff(*val);
 }
 
 /** Returns true if string @a str starts with the character @a prefix.  */
diff --git a/Source/cmStringCommand.cxx b/Source/cmStringCommand.cxx
index 9212195..a7c21cc 100644
--- a/Source/cmStringCommand.cxx
+++ b/Source/cmStringCommand.cxx
@@ -11,11 +11,10 @@
 #include <memory>
 
 #include <cm/iterator>
+#include <cmext/string_view>
 
 #include "cmsys/RegularExpression.hxx"
 
-#include "cm_static_string_view.hxx"
-
 #include "cmCryptoHash.h"
 #include "cmExecutionStatus.h"
 #include "cmGeneratorExpression.h"
@@ -124,6 +123,27 @@
   return true;
 }
 
+bool HandleHexCommand(std::vector<std::string> const& args,
+                      cmExecutionStatus& status)
+{
+  if (args.size() != 3) {
+    status.SetError("Incorrect number of arguments");
+    return false;
+  }
+  auto const& instr = args[1];
+  auto const& outvar = args[2];
+  std::string output(instr.size() * 2, ' ');
+
+  std::string::size_type hexIndex = 0;
+  for (auto const& c : instr) {
+    sprintf(&output[hexIndex], "%.2x", static_cast<unsigned char>(c) & 0xFF);
+    hexIndex += 2;
+  }
+
+  status.GetMakefile().AddDefinition(outvar, output);
+  return true;
+}
+
 bool HandleConfigureCommand(std::vector<std::string> const& args,
                             cmExecutionStatus& status)
 {
@@ -936,6 +956,7 @@
     { "TOUPPER"_s, HandleToUpperCommand },
     { "COMPARE"_s, HandleCompareCommand },
     { "ASCII"_s, HandleAsciiCommand },
+    { "HEX"_s, HandleHexCommand },
     { "CONFIGURE"_s, HandleConfigureCommand },
     { "LENGTH"_s, HandleLengthCommand },
     { "APPEND"_s, HandleAppendCommand },
diff --git a/Source/cmSubcommandTable.h b/Source/cmSubcommandTable.h
index 65eb8c7..7deaaed 100644
--- a/Source/cmSubcommandTable.h
+++ b/Source/cmSubcommandTable.h
@@ -11,8 +11,7 @@
 #include <vector>
 
 #include <cm/string_view>
-
-#include "cm_static_string_view.hxx"
+#include <cmext/string_view>
 
 class cmExecutionStatus;
 
diff --git a/Source/cmSystemTools.cxx b/Source/cmSystemTools.cxx
index 9127c50..798c29a 100644
--- a/Source/cmSystemTools.cxx
+++ b/Source/cmSystemTools.cxx
@@ -1,10 +1,20 @@
 /* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
    file Copyright.txt or https://cmake.org/licensing for details.  */
+
+#if !defined(_WIN32) && !defined(__sun)
+// POSIX APIs are needed
+#  define _POSIX_C_SOURCE 200809L
+#endif
+#if defined(__OpenBSD__) || defined(__FreeBSD__) || defined(__NetBSD__)
+// For isascii
+#  define _XOPEN_SOURCE 700
+#endif
+
 #include "cmSystemTools.h"
 
 #include <cmext/algorithm>
 
-#include "cm_uv.h"
+#include <cm3p/uv.h>
 
 #include "cmDuration.h"
 #include "cmProcessOutput.h"
@@ -12,7 +22,8 @@
 #include "cmStringAlgorithms.h"
 
 #if !defined(CMAKE_BOOTSTRAP)
-#  include "cm_libarchive.h"
+#  include <cm3p/archive.h>
+#  include <cm3p/archive_entry.h>
 
 #  include "cmArchiveWrite.h"
 #  include "cmLocale.h"
@@ -25,6 +36,9 @@
 #endif
 
 #if !defined(CMAKE_BOOTSTRAP)
+#  if defined(_WIN32)
+#    include <cm/memory>
+#  endif
 #  include "cmCryptoHash.h"
 #endif
 
@@ -809,7 +823,9 @@
   // Perform libuv one-time initialization now, and then un-do its
   // global _fmode setting so that using libuv does not change the
   // default file text/binary mode.  See libuv issue 840.
-  uv_loop_close(uv_default_loop());
+  if (uv_loop_t* loop = uv_default_loop()) {
+    uv_loop_close(loop);
+  }
 #  ifdef _MSC_VER
   _set_fmode(_O_TEXT);
 #  else
@@ -908,7 +924,6 @@
   std::string thumbprint;
 
 #if !defined(CMAKE_BOOTSTRAP) && defined(_WIN32)
-  BYTE* certData = NULL;
   CRYPT_INTEGER_BLOB cryptBlob;
   HCERTSTORE certStore = NULL;
   PCCERT_CONTEXT certContext = NULL;
@@ -920,12 +935,12 @@
   if (certFile != INVALID_HANDLE_VALUE && certFile != NULL) {
     DWORD fileSize = GetFileSize(certFile, NULL);
     if (fileSize != INVALID_FILE_SIZE) {
-      certData = new BYTE[fileSize];
+      auto certData = cm::make_unique<BYTE[]>(fileSize);
       if (certData != NULL) {
         DWORD dwRead = 0;
-        if (ReadFile(certFile, certData, fileSize, &dwRead, NULL)) {
+        if (ReadFile(certFile, certData.get(), fileSize, &dwRead, NULL)) {
           cryptBlob.cbData = fileSize;
-          cryptBlob.pbData = certData;
+          cryptBlob.pbData = certData.get();
 
           // Verify that this is a valid cert
           if (PFXIsPFXBlob(&cryptBlob)) {
@@ -961,7 +976,6 @@
             }
           }
         }
-        delete[] certData;
       }
     }
     CloseHandle(certFile);
@@ -1054,8 +1068,7 @@
         if (type < 0 && !cmSystemTools::FileIsDirectory(fname)) {
           continue;
         }
-        if (sfname.size() >= ppath.size() &&
-            sfname.substr(0, ppath.size()) == ppath) {
+        if (cmHasPrefix(sfname, ppath)) {
           files.push_back(fname);
           res = true;
         }
@@ -1200,7 +1213,7 @@
 {
 #  if !defined(HAVE_UNSETENV)
   std::string var = cmStrCat(value, '=');
-  return cmSystemTools::PutEnv(var.c_str());
+  return cmSystemTools::PutEnv(var);
 #  else
   unsetenv(value);
   return true;
@@ -1311,6 +1324,7 @@
 
   cmArchiveWrite a(fout, compress, format.empty() ? "paxr" : format);
 
+  a.Open();
   a.SetMTime(mtime);
   a.SetVerbose(verbose);
   bool tarCreatedSuccessfully = true;
@@ -2068,6 +2082,12 @@
   return cmSystemToolsCMakeRoot;
 }
 
+std::string cmSystemTools::GetCurrentWorkingDirectory()
+{
+  return cmSystemTools::CollapseFullPath(
+    cmsys::SystemTools::GetCurrentWorkingDirectory());
+}
+
 void cmSystemTools::MakefileColorEcho(int color, const char* message,
                                       bool newline, bool enabled)
 {
diff --git a/Source/cmSystemTools.h b/Source/cmSystemTools.h
index ee149a0..b886c58 100644
--- a/Source/cmSystemTools.h
+++ b/Source/cmSystemTools.h
@@ -390,6 +390,9 @@
   static std::string const& GetCMClDepsCommand();
   static std::string const& GetCMakeRoot();
 
+  /** Get the CWD mapped through the KWSys translation map.  */
+  static std::string GetCurrentWorkingDirectory();
+
   /** Echo a message in color using KWSys's Terminal cprintf.  */
   static void MakefileColorEcho(int color, const char* message, bool newLine,
                                 bool enabled);
diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index 1ad9fd1..51b4e9e 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -7,6 +7,7 @@
 #include <cstring>
 #include <initializer_list>
 #include <iterator>
+#include <map>
 #include <set>
 #include <sstream>
 #include <unordered_set>
@@ -78,7 +79,7 @@
 }
 
 template <>
-const char* cmTargetPropertyComputer::GetSources<cmTarget>(
+cmProp cmTargetPropertyComputer::GetSources<cmTarget>(
   cmTarget const* tgt, cmMessenger* messenger,
   cmListFileBacktrace const& context)
 {
@@ -156,7 +157,7 @@
   }
   static std::string srcs;
   srcs = ss.str();
-  return srcs.c_str();
+  return &srcs;
 }
 
 class cmTargetInternals
@@ -185,6 +186,7 @@
   std::vector<cmInstallTargetGenerator*> InstallGenerators;
   std::set<std::string> SystemIncludeDirectories;
   cmTarget::LinkLibraryVectorType OriginalLinkLibraries;
+  std::map<std::string, BTs<std::string>> LanguageStandardProperties;
   std::vector<std::string> IncludeDirectoriesEntries;
   std::vector<cmListFileBacktrace> IncludeDirectoriesBacktraces;
   std::vector<std::string> CompileOptionsEntries;
@@ -214,8 +216,17 @@
   std::string ProcessSourceItemCMP0049(const std::string& s);
 };
 
+namespace {
+#define SETUP_COMMON_LANGUAGE_PROPERTIES(lang)                                \
+  initProp(#lang "_COMPILER_LAUNCHER");                                       \
+  initProp(#lang "_STANDARD");                                                \
+  initProp(#lang "_STANDARD_REQUIRED");                                       \
+  initProp(#lang "_EXTENSIONS");                                              \
+  initProp(#lang "_VISIBILITY_PRESET")
+}
+
 cmTarget::cmTarget(std::string const& name, cmStateEnums::TargetType type,
-                   Visibility vis, cmMakefile* mf, bool perConfig)
+                   Visibility vis, cmMakefile* mf, PerConfig perConfig)
   : impl(cm::make_unique<cmTargetInternals>())
 {
   assert(mf);
@@ -231,7 +242,7 @@
     (vis == VisibilityImported || vis == VisibilityImportedGlobally);
   impl->ImportedGloballyVisible = vis == VisibilityImportedGlobally;
   impl->BuildInterfaceIncludesAppended = false;
-  impl->PerConfig = perConfig;
+  impl->PerConfig = (perConfig == PerConfig::Yes);
 
   // Check whether this is a DLL platform.
   impl->IsDLLPlatform =
@@ -270,8 +281,14 @@
   };
 
   // Setup default property values.
-  if (this->GetType() != cmStateEnums::INTERFACE_LIBRARY &&
-      this->GetType() != cmStateEnums::UTILITY) {
+  if (this->CanCompileSources()) {
+
+    SETUP_COMMON_LANGUAGE_PROPERTIES(C);
+    SETUP_COMMON_LANGUAGE_PROPERTIES(OBJC);
+    SETUP_COMMON_LANGUAGE_PROPERTIES(CXX);
+    SETUP_COMMON_LANGUAGE_PROPERTIES(OBJCXX);
+    SETUP_COMMON_LANGUAGE_PROPERTIES(CUDA);
+
     initProp("ANDROID_API");
     initProp("ANDROID_API_MIN");
     initProp("ANDROID_ARCH");
@@ -303,9 +320,11 @@
     initProp("PDB_OUTPUT_DIRECTORY");
     initProp("COMPILE_PDB_OUTPUT_DIRECTORY");
     initProp("FRAMEWORK");
+    initProp("FRAMEWORK_MULTI_CONFIG_POSTFIX");
     initProp("Fortran_FORMAT");
     initProp("Fortran_MODULE_DIRECTORY");
     initProp("Fortran_COMPILER_LAUNCHER");
+    initProp("Fortran_PREPROCESS");
     initProp("GNUtoMS");
     initProp("OSX_ARCHITECTURES");
     initProp("IOS_INSTALL_COMBINED");
@@ -331,37 +350,22 @@
     initProp("NO_SYSTEM_FROM_IMPORTED");
     initProp("BUILD_WITH_INSTALL_NAME_DIR");
     initProp("C_CLANG_TIDY");
-    initProp("C_COMPILER_LAUNCHER");
     initProp("C_CPPLINT");
     initProp("C_CPPCHECK");
     initProp("C_INCLUDE_WHAT_YOU_USE");
     initProp("LINK_WHAT_YOU_USE");
-    initProp("C_STANDARD");
-    initProp("C_STANDARD_REQUIRED");
-    initProp("C_EXTENSIONS");
-    initProp("OBJC_COMPILER_LAUNCHER");
-    initProp("OBJC_STANDARD");
-    initProp("OBJC_STANDARD_REQUIRED");
-    initProp("OBJC_EXTENSIONS");
     initProp("CXX_CLANG_TIDY");
-    initProp("CXX_COMPILER_LAUNCHER");
     initProp("CXX_CPPLINT");
     initProp("CXX_CPPCHECK");
     initProp("CXX_INCLUDE_WHAT_YOU_USE");
-    initProp("CXX_STANDARD");
-    initProp("CXX_STANDARD_REQUIRED");
-    initProp("CXX_EXTENSIONS");
-    initProp("OBJCXX_COMPILER_LAUNCHER");
-    initProp("OBJCXX_STANDARD");
-    initProp("OBJCXX_STANDARD_REQUIRED");
-    initProp("OBJCXX_EXTENSIONS");
-    initProp("CUDA_STANDARD");
-    initProp("CUDA_STANDARD_REQUIRED");
-    initProp("CUDA_EXTENSIONS");
-    initProp("CUDA_COMPILER_LAUNCHER");
     initProp("CUDA_SEPARABLE_COMPILATION");
     initProp("CUDA_RESOLVE_DEVICE_SYMBOLS");
     initProp("CUDA_RUNTIME_LIBRARY");
+    initProp("CUDA_ARCHITECTURES");
+    initProp("VISIBILITY_INLINES_HIDDEN");
+    initProp("JOB_POOL_COMPILE");
+    initProp("JOB_POOL_LINK");
+    initProp("JOB_POOL_PRECOMPILE_HEADER");
     initProp("LINK_SEARCH_START_STATIC");
     initProp("LINK_SEARCH_END_STATIC");
     initProp("Swift_LANGUAGE_VERSION");
@@ -370,6 +374,9 @@
     initProp("DISABLE_PRECOMPILE_HEADERS");
     initProp("UNITY_BUILD");
     initPropValue("UNITY_BUILD_BATCH_SIZE", "8");
+    initPropValue("UNITY_BUILD_MODE", "BATCH");
+    initPropValue("PCH_WARN_INVALID", "ON");
+
 #ifdef __APPLE__
     if (this->GetGlobalGenerator()->IsXcode()) {
       initProp("XCODE_SCHEME_ADDRESS_SANITIZER");
@@ -394,16 +401,15 @@
 #endif
   }
 
-  if (this->GetType() != cmStateEnums::INTERFACE_LIBRARY) {
-    initProp("FOLDER");
+  initProp("FOLDER");
 
-    if (this->GetGlobalGenerator()->IsXcode()) {
-      initProp("XCODE_GENERATE_SCHEME");
-    }
+  if (this->GetGlobalGenerator()->IsXcode()) {
+    initProp("XCODE_GENERATE_SCHEME");
   }
 
   // Setup per-configuration property default values.
-  if (this->GetType() != cmStateEnums::UTILITY) {
+  if (this->GetType() != cmStateEnums::UTILITY &&
+      this->GetType() != cmStateEnums::GLOBAL_TARGET) {
     static const auto configProps = {
       /* clang-format needs this comment to break after the opening brace */
       "ARCHIVE_OUTPUT_DIRECTORY_",     "LIBRARY_OUTPUT_DIRECTORY_",
@@ -412,8 +418,8 @@
       "INTERPROCEDURAL_OPTIMIZATION_"
     };
     // Collect the set of configuration types.
-    std::vector<std::string> configNames;
-    mf->GetConfigurations(configNames);
+    std::vector<std::string> configNames =
+      mf->GetGeneratorConfigs(cmMakefile::ExcludeEmptyConfig);
     for (std::string const& configName : configNames) {
       std::string configUpper = cmSystemTools::UpperCase(configName);
       for (auto const& prop : configProps) {
@@ -438,6 +444,13 @@
           cmStrCat(cmSystemTools::UpperCase(configName), "_POSTFIX");
         initProp(property);
       }
+
+      if (impl->TargetType == cmStateEnums::SHARED_LIBRARY ||
+          impl->TargetType == cmStateEnums::STATIC_LIBRARY) {
+        std::string property = cmStrCat("FRAMEWORK_MULTI_CONFIG_POSTFIX_",
+                                        cmSystemTools::UpperCase(configName));
+        initProp(property);
+      }
     }
   }
 
@@ -473,16 +486,6 @@
                impl->Makefile->GetLinkDirectoriesBacktraces());
   }
 
-  if (this->GetType() != cmStateEnums::INTERFACE_LIBRARY &&
-      this->GetType() != cmStateEnums::UTILITY) {
-    initProp("C_VISIBILITY_PRESET");
-    initProp("CXX_VISIBILITY_PRESET");
-    initProp("OBJC_VISIBILITY_PRESET");
-    initProp("OBJCXX_VISIBILITY_PRESET");
-    initProp("CUDA_VISIBILITY_PRESET");
-    initProp("VISIBILITY_INLINES_HIDDEN");
-  }
-
   if (impl->TargetType == cmStateEnums::EXECUTABLE) {
     initProp("ANDROID_GUI");
     initProp("CROSSCOMPILING_EMULATOR");
@@ -491,6 +494,8 @@
   if (impl->TargetType == cmStateEnums::SHARED_LIBRARY ||
       impl->TargetType == cmStateEnums::MODULE_LIBRARY) {
     this->SetProperty("POSITION_INDEPENDENT_CODE", "True");
+  } else if (this->CanCompileSources()) {
+    initProp("POSITION_INDEPENDENT_CODE");
   }
   if (impl->TargetType == cmStateEnums::SHARED_LIBRARY ||
       impl->TargetType == cmStateEnums::EXECUTABLE) {
@@ -498,11 +503,6 @@
     initProp("WINDOWS_EXPORT_ALL_SYMBOLS");
   }
 
-  if (this->GetType() != cmStateEnums::INTERFACE_LIBRARY &&
-      this->GetType() != cmStateEnums::UTILITY) {
-    initProp("POSITION_INDEPENDENT_CODE");
-  }
-
   // Record current policies for later use.
   impl->Makefile->RecordPolicies(impl->PolicyMap);
 
@@ -514,36 +514,26 @@
     impl->PolicyMap.Set(cmPolicies::CMP0022, cmPolicies::NEW);
   }
 
-  if (this->GetType() != cmStateEnums::INTERFACE_LIBRARY &&
-      this->GetType() != cmStateEnums::UTILITY) {
-    initProp("JOB_POOL_COMPILE");
-    initProp("JOB_POOL_LINK");
-    initProp("JOB_POOL_PRECOMPILE_HEADER");
-  }
-
-  if (impl->TargetType <= cmStateEnums::UTILITY) {
+  if (impl->TargetType <= cmStateEnums::GLOBAL_TARGET) {
     initProp("DOTNET_TARGET_FRAMEWORK");
     initProp("DOTNET_TARGET_FRAMEWORK_VERSION");
   }
 
-  if (this->GetType() != cmStateEnums::INTERFACE_LIBRARY) {
-
-    // check for "CMAKE_VS_GLOBALS" variable and set up target properties
-    // if any
-    const char* globals = mf->GetDefinition("CMAKE_VS_GLOBALS");
-    if (globals) {
-      const std::string genName = mf->GetGlobalGenerator()->GetName();
-      if (cmHasLiteralPrefix(genName, "Visual Studio")) {
-        std::vector<std::string> props = cmExpandedList(globals);
-        const std::string vsGlobal = "VS_GLOBAL_";
-        for (const std::string& i : props) {
-          // split NAME=VALUE
-          const std::string::size_type assignment = i.find('=');
-          if (assignment != std::string::npos) {
-            const std::string propName = vsGlobal + i.substr(0, assignment);
-            const std::string propValue = i.substr(assignment + 1);
-            initPropValue(propName, propValue.c_str());
-          }
+  // check for "CMAKE_VS_GLOBALS" variable and set up target properties
+  // if any
+  const char* globals = mf->GetDefinition("CMAKE_VS_GLOBALS");
+  if (globals) {
+    const std::string genName = mf->GetGlobalGenerator()->GetName();
+    if (cmHasLiteralPrefix(genName, "Visual Studio")) {
+      std::vector<std::string> props = cmExpandedList(globals);
+      const std::string vsGlobal = "VS_GLOBAL_";
+      for (const std::string& i : props) {
+        // split NAME=VALUE
+        const std::string::size_type assignment = i.find('=');
+        if (assignment != std::string::npos) {
+          const std::string propName = vsGlobal + i.substr(0, assignment);
+          const std::string propValue = i.substr(assignment + 1);
+          initPropValue(propName, propValue.c_str());
         }
       }
     }
@@ -586,6 +576,40 @@
   return impl->Makefile->GetGlobalGenerator();
 }
 
+BTs<std::string> const* cmTarget::GetLanguageStandardProperty(
+  const std::string& propertyName) const
+{
+  auto entry = impl->LanguageStandardProperties.find(propertyName);
+  if (entry != impl->LanguageStandardProperties.end()) {
+    return &entry->second;
+  }
+
+  return nullptr;
+}
+
+void cmTarget::SetLanguageStandardProperty(std::string const& lang,
+                                           std::string const& value,
+                                           const std::string& feature)
+{
+  cmListFileBacktrace featureBacktrace;
+  for (size_t i = 0; i < impl->CompileFeaturesEntries.size(); i++) {
+    if (impl->CompileFeaturesEntries[i] == feature) {
+      if (i < impl->CompileFeaturesBacktraces.size()) {
+        featureBacktrace = impl->CompileFeaturesBacktraces[i];
+      }
+      break;
+    }
+  }
+
+  BTs<std::string>& languageStandardProperty =
+    impl->LanguageStandardProperties[cmStrCat(lang, "_STANDARD")];
+  if (languageStandardProperty.Value != value) {
+    languageStandardProperty.Value = value;
+    languageStandardProperty.Backtraces.clear();
+  }
+  languageStandardProperty.Backtraces.emplace_back(featureBacktrace);
+}
+
 void cmTarget::AddUtility(std::string const& name, bool cross, cmMakefile* mf)
 {
   impl->Utilities.insert(BT<std::pair<std::string, bool>>(
@@ -624,6 +648,12 @@
           this->GetPropertyAsBool("MACOSX_BUNDLE"));
 }
 
+bool cmTarget::IsAndroidGuiExecutable() const
+{
+  return (this->GetType() == cmStateEnums::EXECUTABLE && impl->IsAndroid &&
+          this->GetPropertyAsBool("ANDROID_GUI"));
+}
+
 std::vector<cmCustomCommand> const& cmTarget::GetPreBuildCommands() const
 {
   return impl->PreBuildCommands;
@@ -883,7 +913,7 @@
       cmListFileContext lfc = cmd.second;
       lfc.FilePath = cmDir.ConvertToRelPathIfNotContained(
         impl->Makefile->GetState()->GetSourceDirectory(), lfc.FilePath);
-      s << " * " << lfc << std::endl;
+      s << " * " << lfc << '\n';
     }
   }
 }
@@ -1002,7 +1032,7 @@
     dependencies += ";";
     dependencies += lib;
     dependencies += ";";
-    mf.AddCacheDefinition(targetEntry, dependencies.c_str(),
+    mf.AddCacheDefinition(targetEntry, dependencies,
                           "Dependencies for the target", cmStateEnums::STATIC);
   }
 }
@@ -1109,12 +1139,12 @@
 
 void cmTarget::SetProperty(const std::string& prop, const char* value)
 {
-  if (!cmTargetPropertyComputer::PassesWhitelist(
-        this->GetType(), prop, impl->Makefile->GetMessenger(),
-        impl->Makefile->GetBacktrace())) {
-    return;
-  }
 #define MAKE_STATIC_PROP(PROP) static const std::string prop##PROP = #PROP
+  MAKE_STATIC_PROP(C_STANDARD);
+  MAKE_STATIC_PROP(CXX_STANDARD);
+  MAKE_STATIC_PROP(CUDA_STANDARD);
+  MAKE_STATIC_PROP(OBJC_STANDARD);
+  MAKE_STATIC_PROP(OBJCXX_STANDARD);
   MAKE_STATIC_PROP(COMPILE_DEFINITIONS);
   MAKE_STATIC_PROP(COMPILE_FEATURES);
   MAKE_STATIC_PROP(COMPILE_OPTIONS);
@@ -1295,9 +1325,18 @@
     reusedTarget->SetProperty("COMPILE_PDB_OUTPUT_DIRECTORY",
                               cmStrCat(reusedFrom, ".dir/"));
 
-    this->SetProperty("COMPILE_PDB_NAME",
-                      reusedTarget->GetProperty("COMPILE_PDB_NAME"));
+    cmProp tmp = reusedTarget->GetProperty("COMPILE_PDB_NAME");
+    this->SetProperty("COMPILE_PDB_NAME", tmp ? tmp->c_str() : nullptr);
     this->AddUtility(reusedFrom, false, impl->Makefile);
+  } else if (prop == propC_STANDARD || prop == propCXX_STANDARD ||
+             prop == propCUDA_STANDARD || prop == propOBJC_STANDARD ||
+             prop == propOBJCXX_STANDARD) {
+    if (value) {
+      impl->LanguageStandardProperties[prop] =
+        BTs<std::string>(value, impl->Makefile->GetBacktrace());
+    } else {
+      impl->LanguageStandardProperties.erase(prop);
+    }
   } else {
     impl->Properties.SetProperty(prop, value);
   }
@@ -1306,11 +1345,6 @@
 void cmTarget::AppendProperty(const std::string& prop,
                               const std::string& value, bool asString)
 {
-  if (!cmTargetPropertyComputer::PassesWhitelist(
-        this->GetType(), prop, impl->Makefile->GetMessenger(),
-        impl->Makefile->GetBacktrace())) {
-    return;
-  }
   if (prop == "NAME") {
     impl->Makefile->IssueMessage(MessageType::FATAL_ERROR,
                                  "NAME property is read-only\n");
@@ -1401,6 +1435,11 @@
   } else if (cmHasLiteralPrefix(prop, "IMPORTED_LIBNAME")) {
     impl->Makefile->IssueMessage(MessageType::FATAL_ERROR,
                                  prop + " property may not be APPENDed.");
+  } else if (prop == "C_STANDARD" || prop == "CXX_STANDARD" ||
+             prop == "CUDA_STANDARD" || prop == "OBJC_STANDARD" ||
+             prop == "OBJCXX_STANDARD") {
+    impl->Makefile->IssueMessage(MessageType::FATAL_ERROR,
+                                 prop + " property may not be appended.");
   } else {
     impl->Properties.AppendProperty(prop, value, asString);
   }
@@ -1500,7 +1539,7 @@
 }
 
 static void cmTargetCheckLINK_INTERFACE_LIBRARIES(const std::string& prop,
-                                                  const char* value,
+                                                  const std::string& value,
                                                   cmMakefile* context,
                                                   bool imported)
 {
@@ -1538,7 +1577,7 @@
   context->IssueMessage(MessageType::FATAL_ERROR, e.str());
 }
 
-static void cmTargetCheckINTERFACE_LINK_LIBRARIES(const char* value,
+static void cmTargetCheckINTERFACE_LINK_LIBRARIES(const std::string& value,
                                                   cmMakefile* context)
 {
   // Look for link-type keywords in the value.
@@ -1583,18 +1622,18 @@
 {
   // Certain properties need checking.
   if (cmHasLiteralPrefix(prop, "LINK_INTERFACE_LIBRARIES")) {
-    if (const char* value = this->GetProperty(prop)) {
-      cmTargetCheckLINK_INTERFACE_LIBRARIES(prop, value, context, false);
+    if (cmProp value = this->GetProperty(prop)) {
+      cmTargetCheckLINK_INTERFACE_LIBRARIES(prop, *value, context, false);
     }
   }
   if (cmHasLiteralPrefix(prop, "IMPORTED_LINK_INTERFACE_LIBRARIES")) {
-    if (const char* value = this->GetProperty(prop)) {
-      cmTargetCheckLINK_INTERFACE_LIBRARIES(prop, value, context, true);
+    if (cmProp value = this->GetProperty(prop)) {
+      cmTargetCheckLINK_INTERFACE_LIBRARIES(prop, *value, context, true);
     }
   }
   if (prop == "INTERFACE_LINK_LIBRARIES") {
-    if (const char* value = this->GetProperty(prop)) {
-      cmTargetCheckINTERFACE_LINK_LIBRARIES(value, context);
+    if (cmProp value = this->GetProperty(prop)) {
+      cmTargetCheckINTERFACE_LINK_LIBRARIES(*value, context);
     }
   }
   if (prop == "IMPORTED_GLOBAL") {
@@ -1604,16 +1643,21 @@
   }
 }
 
-const char* cmTarget::GetComputedProperty(
-  const std::string& prop, cmMessenger* messenger,
-  cmListFileBacktrace const& context) const
+cmProp cmTarget::GetComputedProperty(const std::string& prop,
+                                     cmMessenger* messenger,
+                                     cmListFileBacktrace const& context) const
 {
   return cmTargetPropertyComputer::GetProperty(this, prop, messenger, context);
 }
 
-const char* cmTarget::GetProperty(const std::string& prop) const
+cmProp cmTarget::GetProperty(const std::string& prop) const
 {
 #define MAKE_STATIC_PROP(PROP) static const std::string prop##PROP = #PROP
+  MAKE_STATIC_PROP(C_STANDARD);
+  MAKE_STATIC_PROP(CXX_STANDARD);
+  MAKE_STATIC_PROP(CUDA_STANDARD);
+  MAKE_STATIC_PROP(OBJC_STANDARD);
+  MAKE_STATIC_PROP(OBJCXX_STANDARD);
   MAKE_STATIC_PROP(LINK_LIBRARIES);
   MAKE_STATIC_PROP(TYPE);
   MAKE_STATIC_PROP(INCLUDE_DIRECTORIES);
@@ -1630,8 +1674,15 @@
   MAKE_STATIC_PROP(BINARY_DIR);
   MAKE_STATIC_PROP(SOURCE_DIR);
   MAKE_STATIC_PROP(SOURCES);
+  MAKE_STATIC_PROP(FALSE);
+  MAKE_STATIC_PROP(TRUE);
 #undef MAKE_STATIC_PROP
   static std::unordered_set<std::string> const specialProps{
+    propC_STANDARD,
+    propCXX_STANDARD,
+    propCUDA_STANDARD,
+    propOBJC_STANDARD,
+    propOBJCXX_STANDARD,
     propLINK_LIBRARIES,
     propTYPE,
     propINCLUDE_DIRECTORIES,
@@ -1650,6 +1701,15 @@
     propSOURCES
   };
   if (specialProps.count(prop)) {
+    if (prop == propC_STANDARD || prop == propCXX_STANDARD ||
+        prop == propCUDA_STANDARD || prop == propOBJC_STANDARD ||
+        prop == propOBJCXX_STANDARD) {
+      auto propertyIter = impl->LanguageStandardProperties.find(prop);
+      if (propertyIter == impl->LanguageStandardProperties.end()) {
+        return nullptr;
+      }
+      return &(propertyIter->second.Value);
+    }
     if (prop == propLINK_LIBRARIES) {
       if (impl->LinkImplementationPropertyEntries.empty()) {
         return nullptr;
@@ -1657,11 +1717,11 @@
 
       static std::string output;
       output = cmJoin(impl->LinkImplementationPropertyEntries, ";");
-      return output.c_str();
+      return &output;
     }
     // the type property returns what type the target is
     if (prop == propTYPE) {
-      return cmState::GetTargetTypeName(this->GetType());
+      return &cmState::GetTargetTypeName(this->GetType());
     }
     if (prop == propINCLUDE_DIRECTORIES) {
       if (impl->IncludeDirectoriesEntries.empty()) {
@@ -1670,7 +1730,7 @@
 
       static std::string output;
       output = cmJoin(impl->IncludeDirectoriesEntries, ";");
-      return output.c_str();
+      return &output;
     }
     if (prop == propCOMPILE_FEATURES) {
       if (impl->CompileFeaturesEntries.empty()) {
@@ -1679,7 +1739,7 @@
 
       static std::string output;
       output = cmJoin(impl->CompileFeaturesEntries, ";");
-      return output.c_str();
+      return &output;
     }
     if (prop == propCOMPILE_OPTIONS) {
       if (impl->CompileOptionsEntries.empty()) {
@@ -1688,7 +1748,7 @@
 
       static std::string output;
       output = cmJoin(impl->CompileOptionsEntries, ";");
-      return output.c_str();
+      return &output;
     }
     if (prop == propCOMPILE_DEFINITIONS) {
       if (impl->CompileDefinitionsEntries.empty()) {
@@ -1697,7 +1757,7 @@
 
       static std::string output;
       output = cmJoin(impl->CompileDefinitionsEntries, ";");
-      return output.c_str();
+      return &output;
     }
     if (prop == propLINK_OPTIONS) {
       if (impl->LinkOptionsEntries.empty()) {
@@ -1706,7 +1766,7 @@
 
       static std::string output;
       output = cmJoin(impl->LinkOptionsEntries, ";");
-      return output.c_str();
+      return &output;
     }
     if (prop == propLINK_DIRECTORIES) {
       if (impl->LinkDirectoriesEntries.empty()) {
@@ -1716,7 +1776,7 @@
       static std::string output;
       output = cmJoin(impl->LinkDirectoriesEntries, ";");
 
-      return output.c_str();
+      return &output;
     }
     if (prop == propMANUALLY_ADDED_DEPENDENCIES) {
       if (impl->Utilities.empty()) {
@@ -1732,7 +1792,7 @@
           return item.Value.first;
         });
       output = cmJoin(utilities, ";");
-      return output.c_str();
+      return &output;
     }
     if (prop == propPRECOMPILE_HEADERS) {
       if (impl->PrecompileHeadersEntries.empty()) {
@@ -1741,32 +1801,30 @@
 
       static std::string output;
       output = cmJoin(impl->PrecompileHeadersEntries, ";");
-      return output.c_str();
+      return &output;
     }
     if (prop == propIMPORTED) {
-      return this->IsImported() ? "TRUE" : "FALSE";
+      return this->IsImported() ? &propTRUE : &propFALSE;
     }
     if (prop == propIMPORTED_GLOBAL) {
-      return this->IsImportedGloballyVisible() ? "TRUE" : "FALSE";
+      return this->IsImportedGloballyVisible() ? &propTRUE : &propFALSE;
     }
     if (prop == propNAME) {
-      return this->GetName().c_str();
+      return &this->GetName();
     }
     if (prop == propBINARY_DIR) {
-      return impl->Makefile->GetStateSnapshot()
-        .GetDirectory()
-        .GetCurrentBinary()
-        .c_str();
+      return &impl->Makefile->GetStateSnapshot()
+                .GetDirectory()
+                .GetCurrentBinary();
     }
     if (prop == propSOURCE_DIR) {
-      return impl->Makefile->GetStateSnapshot()
-        .GetDirectory()
-        .GetCurrentSource()
-        .c_str();
+      return &impl->Makefile->GetStateSnapshot()
+                .GetDirectory()
+                .GetCurrentSource();
     }
   }
 
-  const char* retVal = impl->Properties.GetPropertyValue(prop);
+  cmProp retVal = impl->Properties.GetPropertyValue(prop);
   if (!retVal) {
     const bool chain =
       impl->Makefile->GetState()->IsPropertyChained(prop, cmProperty::TARGET);
@@ -1774,17 +1832,20 @@
       return impl->Makefile->GetStateSnapshot().GetDirectory().GetProperty(
         prop, chain);
     }
+    return nullptr;
   }
   return retVal;
 }
 
-const char* cmTarget::GetSafeProperty(const std::string& prop) const
+std::string const& cmTarget::GetSafeProperty(std::string const& prop) const
 {
-  const char* ret = this->GetProperty(prop);
-  if (!ret) {
-    return "";
+  cmProp ret = this->GetProperty(prop);
+  if (ret) {
+    return *ret;
   }
-  return ret;
+
+  static std::string const s_empty;
+  return s_empty;
 }
 
 bool cmTarget::GetPropertyAsBool(const std::string& prop) const
@@ -1822,6 +1883,27 @@
   return impl->PerConfig;
 }
 
+bool cmTarget::CanCompileSources() const
+{
+  if (this->IsImported()) {
+    return false;
+  }
+  switch (this->GetType()) {
+    case cmStateEnums::EXECUTABLE:
+    case cmStateEnums::STATIC_LIBRARY:
+    case cmStateEnums::SHARED_LIBRARY:
+    case cmStateEnums::MODULE_LIBRARY:
+    case cmStateEnums::OBJECT_LIBRARY:
+      return true;
+    case cmStateEnums::UTILITY:
+    case cmStateEnums::INTERFACE_LIBRARY:
+    case cmStateEnums::GLOBAL_TARGET:
+    case cmStateEnums::UNKNOWN_LIBRARY:
+      break;
+  }
+  return false;
+}
+
 const char* cmTarget::GetSuffixVariableInternal(
   cmStateEnums::ArtifactType artifact) const
 {
@@ -1849,7 +1931,7 @@
         case cmStateEnums::RuntimeBinaryArtifact:
           // Android GUI application packages store the native
           // binary as a shared library.
-          return (impl->IsAndroid && this->GetPropertyAsBool("ANDROID_GUI")
+          return (this->IsAndroidGuiExecutable()
                     ? "CMAKE_SHARED_LIBRARY_SUFFIX"
                     : "CMAKE_EXECUTABLE_SUFFIX");
         case cmStateEnums::ImportLibraryArtifact:
@@ -1890,7 +1972,7 @@
         case cmStateEnums::RuntimeBinaryArtifact:
           // Android GUI application packages store the native
           // binary as a shared library.
-          return (impl->IsAndroid && this->GetPropertyAsBool("ANDROID_GUI")
+          return (this->IsAndroidGuiExecutable()
                     ? "CMAKE_SHARED_LIBRARY_PREFIX"
                     : "");
         case cmStateEnums::ImportLibraryArtifact:
@@ -1918,38 +2000,37 @@
 
   std::string result;
 
-  const char* loc = nullptr;
-  const char* imp = nullptr;
+  cmProp loc = nullptr;
+  cmProp imp = nullptr;
   std::string suffix;
 
   if (this->GetType() != cmStateEnums::INTERFACE_LIBRARY &&
-      this->GetMappedConfig(desired_config, &loc, &imp, suffix)) {
+      this->GetMappedConfig(desired_config, loc, imp, suffix)) {
     switch (artifact) {
       case cmStateEnums::RuntimeBinaryArtifact:
         if (loc) {
-          result = loc;
+          result = *loc;
         } else {
           std::string impProp = cmStrCat("IMPORTED_LOCATION", suffix);
-          if (const char* config_location = this->GetProperty(impProp)) {
-            result = config_location;
-          } else if (const char* location =
+          if (cmProp config_location = this->GetProperty(impProp)) {
+            result = *config_location;
+          } else if (cmProp location =
                        this->GetProperty("IMPORTED_LOCATION")) {
-            result = location;
+            result = *location;
           }
         }
         break;
 
       case cmStateEnums::ImportLibraryArtifact:
         if (imp) {
-          result = imp;
+          result = *imp;
         } else if (this->GetType() == cmStateEnums::SHARED_LIBRARY ||
                    this->IsExecutableWithExports()) {
           std::string impProp = cmStrCat("IMPORTED_IMPLIB", suffix);
-          if (const char* config_implib = this->GetProperty(impProp)) {
-            result = config_implib;
-          } else if (const char* implib =
-                       this->GetProperty("IMPORTED_IMPLIB")) {
-            result = implib;
+          if (cmProp config_implib = this->GetProperty(impProp)) {
+            result = *config_implib;
+          } else if (cmProp implib = this->GetProperty("IMPORTED_IMPLIB")) {
+            result = *implib;
           }
         }
         break;
@@ -1992,9 +2073,8 @@
   return true;
 }
 
-bool cmTarget::GetMappedConfig(std::string const& desired_config,
-                               const char** loc, const char** imp,
-                               std::string& suffix) const
+bool cmTarget::GetMappedConfig(std::string const& desired_config, cmProp& loc,
+                               cmProp& imp, std::string& suffix) const
 {
   std::string config_upper;
   if (!desired_config.empty()) {
@@ -2016,8 +2096,8 @@
   std::vector<std::string> mappedConfigs;
   {
     std::string mapProp = cmStrCat("MAP_IMPORTED_CONFIG_", config_upper);
-    if (const char* mapValue = this->GetProperty(mapProp)) {
-      cmExpandList(mapValue, mappedConfigs, true);
+    if (cmProp mapValue = this->GetProperty(mapProp)) {
+      cmExpandList(*mapValue, mappedConfigs, true);
     }
   }
 
@@ -2031,30 +2111,30 @@
 
   // If a mapping was found, check its configurations.
   for (auto mci = mappedConfigs.begin();
-       !*loc && !*imp && mci != mappedConfigs.end(); ++mci) {
+       !loc && !imp && mci != mappedConfigs.end(); ++mci) {
     // Look for this configuration.
     if (mci->empty()) {
       // An empty string in the mapping has a special meaning:
       // look up the config-less properties.
-      *loc = this->GetProperty(locPropBase);
+      loc = this->GetProperty(locPropBase);
       if (allowImp) {
-        *imp = this->GetProperty("IMPORTED_IMPLIB");
+        imp = this->GetProperty("IMPORTED_IMPLIB");
       }
       // If it was found, set the suffix.
-      if (*loc || *imp) {
+      if (loc || imp) {
         suffix.clear();
       }
     } else {
       std::string mcUpper = cmSystemTools::UpperCase(*mci);
       std::string locProp = cmStrCat(locPropBase, '_', mcUpper);
-      *loc = this->GetProperty(locProp);
+      loc = this->GetProperty(locProp);
       if (allowImp) {
         std::string impProp = cmStrCat("IMPORTED_IMPLIB_", mcUpper);
-        *imp = this->GetProperty(impProp);
+        imp = this->GetProperty(impProp);
       }
 
       // If it was found, use it for all properties below.
-      if (*loc || *imp) {
+      if (loc || imp) {
         suffix = cmStrCat('_', mcUpper);
       }
     }
@@ -2063,59 +2143,59 @@
   // If we needed to find one of the mapped configurations but did not
   // then the target location is not found.  The project does not want
   // any other configuration.
-  if (!mappedConfigs.empty() && !*loc && !*imp) {
+  if (!mappedConfigs.empty() && !loc && !imp) {
     // Interface libraries are always available because their
-    // library name is optional so it is okay to leave *loc empty.
+    // library name is optional so it is okay to leave loc empty.
     return this->GetType() == cmStateEnums::INTERFACE_LIBRARY;
   }
 
   // If we have not yet found it then there are no mapped
   // configurations.  Look for an exact-match.
-  if (!*loc && !*imp) {
+  if (!loc && !imp) {
     std::string locProp = cmStrCat(locPropBase, suffix);
-    *loc = this->GetProperty(locProp);
+    loc = this->GetProperty(locProp);
     if (allowImp) {
       std::string impProp = cmStrCat("IMPORTED_IMPLIB", suffix);
-      *imp = this->GetProperty(impProp);
+      imp = this->GetProperty(impProp);
     }
   }
 
   // If we have not yet found it then there are no mapped
   // configurations and no exact match.
-  if (!*loc && !*imp) {
+  if (!loc && !imp) {
     // The suffix computed above is not useful.
     suffix.clear();
 
     // Look for a configuration-less location.  This may be set by
     // manually-written code.
-    *loc = this->GetProperty(locPropBase);
+    loc = this->GetProperty(locPropBase);
     if (allowImp) {
-      *imp = this->GetProperty("IMPORTED_IMPLIB");
+      imp = this->GetProperty("IMPORTED_IMPLIB");
     }
   }
 
   // If we have not yet found it then the project is willing to try
   // any available configuration.
-  if (!*loc && !*imp) {
+  if (!loc && !imp) {
     std::vector<std::string> availableConfigs;
-    if (const char* iconfigs = this->GetProperty("IMPORTED_CONFIGURATIONS")) {
-      cmExpandList(iconfigs, availableConfigs);
+    if (cmProp iconfigs = this->GetProperty("IMPORTED_CONFIGURATIONS")) {
+      cmExpandList(*iconfigs, availableConfigs);
     }
     for (auto aci = availableConfigs.begin();
-         !*loc && !*imp && aci != availableConfigs.end(); ++aci) {
+         !loc && !imp && aci != availableConfigs.end(); ++aci) {
       suffix = cmStrCat('_', cmSystemTools::UpperCase(*aci));
       std::string locProp = cmStrCat(locPropBase, suffix);
-      *loc = this->GetProperty(locProp);
+      loc = this->GetProperty(locProp);
       if (allowImp) {
         std::string impProp = cmStrCat("IMPORTED_IMPLIB", suffix);
-        *imp = this->GetProperty(impProp);
+        imp = this->GetProperty(impProp);
       }
     }
   }
   // If we have not yet found it then the target location is not available.
-  if (!*loc && !*imp) {
+  if (!loc && !imp) {
     // Interface libraries are always available because their
-    // library name is optional so it is okay to leave *loc empty.
+    // library name is optional so it is okay to leave loc empty.
     return this->GetType() == cmStateEnums::INTERFACE_LIBRARY;
   }
 
diff --git a/Source/cmTarget.h b/Source/cmTarget.h
index 286933b..43f1887 100644
--- a/Source/cmTarget.h
+++ b/Source/cmTarget.h
@@ -15,6 +15,7 @@
 #include "cmAlgorithms.h"
 #include "cmListFileCache.h"
 #include "cmPolicies.h"
+#include "cmProperty.h"
 #include "cmStateTypes.h"
 #include "cmStringAlgorithms.h"
 #include "cmTargetLinkLibraryType.h"
@@ -43,8 +44,14 @@
     VisibilityImportedGlobally
   };
 
+  enum class PerConfig
+  {
+    Yes,
+    No
+  };
+
   cmTarget(std::string const& name, cmStateEnums::TargetType type,
-           Visibility vis, cmMakefile* mf, bool perConfig);
+           Visibility vis, cmMakefile* mf, PerConfig perConfig);
 
   cmTarget(cmTarget const&) = delete;
   cmTarget(cmTarget&&) noexcept;
@@ -170,14 +177,13 @@
   void AppendProperty(const std::string& prop, const std::string& value,
                       bool asString = false);
   //! Might return a nullptr if the property is not set or invalid
-  const char* GetProperty(const std::string& prop) const;
+  cmProp GetProperty(const std::string& prop) const;
   //! Always returns a valid pointer
-  const char* GetSafeProperty(const std::string& prop) const;
+  std::string const& GetSafeProperty(std::string const& prop) const;
   bool GetPropertyAsBool(const std::string& prop) const;
   void CheckProperty(const std::string& prop, cmMakefile* context) const;
-  const char* GetComputedProperty(const std::string& prop,
-                                  cmMessenger* messenger,
-                                  cmListFileBacktrace const& context) const;
+  cmProp GetComputedProperty(const std::string& prop, cmMessenger* messenger,
+                             cmListFileBacktrace const& context) const;
   //! Get all properties
   cmPropertyMap const& GetProperties() const;
 
@@ -190,9 +196,10 @@
   bool IsImported() const;
   bool IsImportedGloballyVisible() const;
   bool IsPerConfig() const;
+  bool CanCompileSources() const;
 
-  bool GetMappedConfig(std::string const& desired_config, const char** loc,
-                       const char** imp, std::string& suffix) const;
+  bool GetMappedConfig(std::string const& desired_config, cmProp& loc,
+                       cmProp& imp, std::string& suffix) const;
 
   //! Return whether this target is an executable with symbol exports enabled.
   bool IsExecutableWithExports() const;
@@ -203,6 +210,9 @@
   //! Return whether this target is an executable Bundle on Apple.
   bool IsAppBundleOnApple() const;
 
+  //! Return whether this target is a GUI executable on Android.
+  bool IsAndroidGuiExecutable() const;
+
   //! Get a backtrace from the creation of the target.
   cmListFileBacktrace const& GetBacktrace() const;
 
@@ -227,6 +237,13 @@
   void AddSystemIncludeDirectories(std::set<std::string> const& incs);
   std::set<std::string> const& GetSystemIncludeDirectories() const;
 
+  BTs<std::string> const* GetLanguageStandardProperty(
+    const std::string& propertyName) const;
+
+  void SetLanguageStandardProperty(std::string const& lang,
+                                   std::string const& value,
+                                   const std::string& feature);
+
   cmStringRange GetIncludeDirectoriesEntries() const;
   cmBacktraceRange GetIncludeDirectoriesBacktraces() const;
 
diff --git a/Source/cmTargetCompileFeaturesCommand.cxx b/Source/cmTargetCompileFeaturesCommand.cxx
index 06be4f0..aa1abdd 100644
--- a/Source/cmTargetCompileFeaturesCommand.cxx
+++ b/Source/cmTargetCompileFeaturesCommand.cxx
@@ -4,6 +4,7 @@
 
 #include "cmMakefile.h"
 #include "cmMessageType.h"
+#include "cmStandardLevelResolver.h"
 #include "cmStringAlgorithms.h"
 #include "cmTargetPropCommandBase.h"
 
@@ -29,9 +30,10 @@
                            const std::vector<std::string>& content,
                            bool /*prepend*/, bool /*system*/) override
   {
+    cmStandardLevelResolver standardResolver(this->Makefile);
     for (std::string const& it : content) {
       std::string error;
-      if (!this->Makefile->AddRequiredTargetFeature(tgt, it, &error)) {
+      if (!standardResolver.AddRequiredTargetFeature(tgt, it, &error)) {
         this->SetError(error);
         return false; // Not (successfully) handled.
       }
diff --git a/Source/cmTargetPropCommandBase.cxx b/Source/cmTargetPropCommandBase.cxx
index 0de8d6d..9e30136 100644
--- a/Source/cmTargetPropCommandBase.cxx
+++ b/Source/cmTargetPropCommandBase.cxx
@@ -5,6 +5,7 @@
 #include "cmExecutionStatus.h"
 #include "cmGlobalGenerator.h"
 #include "cmMakefile.h"
+#include "cmProperty.h"
 #include "cmStateTypes.h"
 #include "cmTarget.h"
 #include "cmake.h"
@@ -122,7 +123,7 @@
   }
   if (!content.empty()) {
     if (this->Target->GetType() == cmStateEnums::INTERFACE_LIBRARY &&
-        scope != "INTERFACE") {
+        scope != "INTERFACE" && this->Property != "SOURCES") {
       this->SetError("may only set INTERFACE properties on INTERFACE targets");
       return false;
     }
@@ -157,9 +158,9 @@
 {
   if (prepend) {
     const std::string propName = std::string("INTERFACE_") + this->Property;
-    const char* propValue = tgt->GetProperty(propName);
-    const std::string totalContent = this->Join(content) +
-      (propValue ? std::string(";") + propValue : std::string());
+    cmProp propValue = tgt->GetProperty(propName);
+    const std::string totalContent =
+      this->Join(content) + (propValue ? (";" + *propValue) : std::string());
     tgt->SetProperty(propName, totalContent);
   } else {
     tgt->AppendProperty("INTERFACE_" + this->Property, this->Join(content));
diff --git a/Source/cmTargetPropertyComputer.cxx b/Source/cmTargetPropertyComputer.cxx
index f37995c..b9c9365 100644
--- a/Source/cmTargetPropertyComputer.cxx
+++ b/Source/cmTargetPropertyComputer.cxx
@@ -3,15 +3,12 @@
 
 #include "cmTargetPropertyComputer.h"
 
-#include <cctype>
 #include <sstream>
-#include <unordered_set>
 
 #include "cmMessageType.h"
 #include "cmMessenger.h"
 #include "cmPolicies.h"
 #include "cmStateSnapshot.h"
-#include "cmStringAlgorithms.h"
 
 bool cmTargetPropertyComputer::HandleLocationPropertyPolicy(
   std::string const& tgtName, cmMessenger* messenger,
@@ -44,69 +41,3 @@
 
   return messageType != MessageType::FATAL_ERROR;
 }
-
-bool cmTargetPropertyComputer::WhiteListedInterfaceProperty(
-  const std::string& prop)
-{
-  if (cmHasLiteralPrefix(prop, "INTERFACE_")) {
-    return true;
-  }
-  if (cmHasLiteralPrefix(prop, "_")) {
-    return true;
-  }
-  if (std::islower(prop[0])) {
-    return true;
-  }
-  static std::unordered_set<std::string> const builtIns{
-    "COMPATIBLE_INTERFACE_BOOL",
-    "COMPATIBLE_INTERFACE_NUMBER_MAX",
-    "COMPATIBLE_INTERFACE_NUMBER_MIN",
-    "COMPATIBLE_INTERFACE_STRING",
-    "DEPRECATION",
-    "EXPORT_NAME",
-    "EXPORT_PROPERTIES",
-    "IMPORTED",
-    "IMPORTED_GLOBAL",
-    "MANUALLY_ADDED_DEPENDENCIES",
-    "NAME",
-    "PRIVATE_HEADER",
-    "PUBLIC_HEADER",
-    "TYPE"
-  };
-
-  if (builtIns.count(prop)) {
-    return true;
-  }
-
-  if (prop == "IMPORTED_CONFIGURATIONS" || prop == "IMPORTED_LIBNAME" ||
-      cmHasLiteralPrefix(prop, "IMPORTED_LIBNAME_") ||
-      cmHasLiteralPrefix(prop, "MAP_IMPORTED_CONFIG_")) {
-    return true;
-  }
-
-  // This property should not be allowed but was incorrectly added in
-  // CMake 3.8.  We can't remove it from the whitelist without breaking
-  // projects that try to set it.  One day we could warn about this, but
-  // for now silently accept it.
-  if (prop == "NO_SYSTEM_FROM_IMPORTED") {
-    return true;
-  }
-
-  return false;
-}
-
-bool cmTargetPropertyComputer::PassesWhitelist(
-  cmStateEnums::TargetType tgtType, std::string const& prop,
-  cmMessenger* messenger, cmListFileBacktrace const& context)
-{
-  if (tgtType == cmStateEnums::INTERFACE_LIBRARY &&
-      !WhiteListedInterfaceProperty(prop)) {
-    std::ostringstream e;
-    e << "INTERFACE_LIBRARY targets may only have whitelisted properties.  "
-         "The property \""
-      << prop << "\" is not allowed.";
-    messenger->IssueMessage(MessageType::FATAL_ERROR, e.str(), context);
-    return false;
-  }
-  return true;
-}
diff --git a/Source/cmTargetPropertyComputer.h b/Source/cmTargetPropertyComputer.h
index df34f18..bafa43b 100644
--- a/Source/cmTargetPropertyComputer.h
+++ b/Source/cmTargetPropertyComputer.h
@@ -8,6 +8,7 @@
 #include <string>
 
 #include "cmListFileCache.h"
+#include "cmProperty.h"
 #include "cmStateTypes.h"
 #include "cmStringAlgorithms.h"
 #include "cmSystemTools.h"
@@ -18,11 +19,11 @@
 {
 public:
   template <typename Target>
-  static const char* GetProperty(Target const* tgt, const std::string& prop,
-                                 cmMessenger* messenger,
-                                 cmListFileBacktrace const& context)
+  static cmProp GetProperty(Target const* tgt, const std::string& prop,
+                            cmMessenger* messenger,
+                            cmListFileBacktrace const& context)
   {
-    if (const char* loc = GetLocation(tgt, prop, messenger, context)) {
+    if (cmProp loc = GetLocation(tgt, prop, messenger, context)) {
       return loc;
     }
     if (cmSystemTools::GetFatalErrorOccured()) {
@@ -34,12 +35,6 @@
     return nullptr;
   }
 
-  static bool WhiteListedInterfaceProperty(const std::string& prop);
-
-  static bool PassesWhitelist(cmStateEnums::TargetType tgtType,
-                              std::string const& prop, cmMessenger* messenger,
-                              cmListFileBacktrace const& context);
-
 private:
   static bool HandleLocationPropertyPolicy(std::string const& tgtName,
                                            cmMessenger* messenger,
@@ -52,9 +47,9 @@
                                             std::string const& config);
 
   template <typename Target>
-  static const char* GetLocation(Target const* tgt, std::string const& prop,
-                                 cmMessenger* messenger,
-                                 cmListFileBacktrace const& context)
+  static cmProp GetLocation(Target const* tgt, std::string const& prop,
+                            cmMessenger* messenger,
+                            cmListFileBacktrace const& context)
 
   {
     // Watch for special "computed" properties that are dependent on
@@ -71,7 +66,7 @@
                                           context)) {
           return nullptr;
         }
-        return ComputeLocationForBuild(tgt).c_str();
+        return &ComputeLocationForBuild(tgt);
       }
 
       // Support "LOCATION_<CONFIG>".
@@ -82,7 +77,7 @@
           return nullptr;
         }
         std::string configName = prop.substr(9);
-        return ComputeLocation(tgt, configName).c_str();
+        return &ComputeLocation(tgt, configName);
       }
 
       // Support "<CONFIG>_LOCATION".
@@ -95,7 +90,7 @@
                                             context)) {
             return nullptr;
           }
-          return ComputeLocation(tgt, configName).c_str();
+          return &ComputeLocation(tgt, configName);
         }
       }
     }
@@ -103,8 +98,8 @@
   }
 
   template <typename Target>
-  static const char* GetSources(Target const* tgt, cmMessenger* messenger,
-                                cmListFileBacktrace const& context);
+  static cmProp GetSources(Target const* tgt, cmMessenger* messenger,
+                           cmListFileBacktrace const& context);
 };
 
 #endif
diff --git a/Source/cmTest.cxx b/Source/cmTest.cxx
index 3b731cc..a26bef3 100644
--- a/Source/cmTest.cxx
+++ b/Source/cmTest.cxx
@@ -34,15 +34,18 @@
 
 const char* cmTest::GetProperty(const std::string& prop) const
 {
-  const char* retVal = this->Properties.GetPropertyValue(prop);
+  cmProp retVal = this->Properties.GetPropertyValue(prop);
   if (!retVal) {
     const bool chain =
       this->Makefile->GetState()->IsPropertyChained(prop, cmProperty::TEST);
     if (chain) {
-      return this->Makefile->GetProperty(prop, chain);
+      if (cmProp p = this->Makefile->GetProperty(prop, chain)) {
+        return p->c_str();
+      }
     }
+    return nullptr;
   }
-  return retVal;
+  return retVal->c_str();
 }
 
 bool cmTest::GetPropertyAsBool(const std::string& prop) const
diff --git a/Source/cmTestGenerator.cxx b/Source/cmTestGenerator.cxx
index 333d4d5..78b230c 100644
--- a/Source/cmTestGenerator.cxx
+++ b/Source/cmTestGenerator.cxx
@@ -12,6 +12,7 @@
 #include "cmListFileCache.h"
 #include "cmLocalGenerator.h"
 #include "cmOutputConverter.h"
+#include "cmProperty.h"
 #include "cmPropertyMap.h"
 #include "cmRange.h"
 #include "cmStateTypes.h"
@@ -100,9 +101,9 @@
     exe = target->GetFullPath(config);
 
     // Prepend with the emulator when cross compiling if required.
-    const char* emulator = target->GetProperty("CROSSCOMPILING_EMULATOR");
-    if (emulator != nullptr && *emulator) {
-      std::vector<std::string> emulatorWithArgs = cmExpandedList(emulator);
+    cmProp emulator = target->GetProperty("CROSSCOMPILING_EMULATOR");
+    if (cmNonempty(emulator)) {
+      std::vector<std::string> emulatorWithArgs = cmExpandedList(*emulator);
       std::string emulatorExe(emulatorWithArgs[0]);
       cmSystemTools::ConvertToUnixSlashes(emulatorExe);
       os << cmOutputConverter::EscapeForCMake(emulatorExe) << " ";
@@ -134,7 +135,7 @@
             ge.Parse(i.second)->Evaluate(this->LG, config));
   }
   this->GenerateInternalProperties(os);
-  os << ")" << std::endl;
+  os << ")\n";
 }
 
 void cmTestGenerator::GenerateScriptNoConfig(std::ostream& os, Indent indent)
@@ -176,9 +177,9 @@
       }
       fout << c;
     }
-    fout << "\"";
+    fout << '"';
   }
-  fout << ")" << std::endl;
+  fout << ")\n";
 
   // Output properties for the test.
   fout << indent << "set_tests_properties(" << this->Test->GetName()
@@ -188,7 +189,7 @@
          << cmOutputConverter::EscapeForCMake(i.second);
   }
   this->GenerateInternalProperties(fout);
-  fout << ")" << std::endl;
+  fout << ")\n";
 }
 
 void cmTestGenerator::GenerateInternalProperties(std::ostream& os)
@@ -213,7 +214,7 @@
     prependTripleSeparator = true;
   }
 
-  os << "\"";
+  os << '"';
 }
 
 std::vector<std::string> cmTestGenerator::EvaluateCommandLineArguments(
diff --git a/Source/cmTimestamp.cxx b/Source/cmTimestamp.cxx
index 390fd16..bd6bb3d 100644
--- a/Source/cmTimestamp.cxx
+++ b/Source/cmTimestamp.cxx
@@ -1,5 +1,15 @@
 /* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
    file Copyright.txt or https://cmake.org/licensing for details.  */
+
+#if !defined(_WIN32) && !defined(__sun)
+// POSIX APIs are needed
+#  define _POSIX_C_SOURCE 200809L
+#endif
+#if defined(__OpenBSD__) || defined(__FreeBSD__) || defined(__NetBSD__)
+// For isascii
+#  define _XOPEN_SOURCE 700
+#endif
+
 #include "cmTimestamp.h"
 
 #include <cstdlib>
@@ -154,7 +164,7 @@
       break;
     case 's': // Seconds since UNIX epoch (midnight 1-jan-1970)
     {
-      // Build a time_t for UNIX epoch and substract from the input "timeT":
+      // Build a time_t for UNIX epoch and subtract from the input "timeT":
       struct tm tmUnixEpoch;
       memset(&tmUnixEpoch, 0, sizeof(tmUnixEpoch));
       tmUnixEpoch.tm_mday = 1;
diff --git a/Source/cmTryRunCommand.cxx b/Source/cmTryRunCommand.cxx
index 0e8e986..64d71bc 100644
--- a/Source/cmTryRunCommand.cxx
+++ b/Source/cmTryRunCommand.cxx
@@ -9,6 +9,7 @@
 #include "cmDuration.h"
 #include "cmMakefile.h"
 #include "cmMessageType.h"
+#include "cmProperty.h"
 #include "cmRange.h"
 #include "cmState.h"
 #include "cmStateTypes.h"
@@ -242,8 +243,7 @@
                                        comment.c_str(), cmStateEnums::STRING);
 
     cmState* state = this->Makefile->GetState();
-    const char* existingValue =
-      state->GetCacheEntryValue(this->RunResultVariable);
+    cmProp existingValue = state->GetCacheEntryValue(this->RunResultVariable);
     if (existingValue) {
       state->SetCacheEntryProperty(this->RunResultVariable, "ADVANCED", "1");
     }
@@ -265,7 +265,7 @@
         internalRunOutputName, "PLEASE_FILL_OUT-NOTFOUND", comment.c_str(),
         cmStateEnums::STRING);
       cmState* state = this->Makefile->GetState();
-      const char* existing = state->GetCacheEntryValue(internalRunOutputName);
+      cmProp existing = state->GetCacheEntryValue(internalRunOutputName);
       if (existing) {
         state->SetCacheEntryProperty(internalRunOutputName, "ADVANCED", "1");
       }
diff --git a/Source/cmUVHandlePtr.cxx b/Source/cmUVHandlePtr.cxx
index 23dabb7..df2f64e 100644
--- a/Source/cmUVHandlePtr.cxx
+++ b/Source/cmUVHandlePtr.cxx
@@ -7,7 +7,7 @@
 #include <cstdlib>
 #include <mutex>
 
-#include "cm_uv.h"
+#include <cm3p/uv.h>
 
 namespace cm {
 
diff --git a/Source/cmUVHandlePtr.h b/Source/cmUVHandlePtr.h
index 3083b60..d9de7f3 100644
--- a/Source/cmUVHandlePtr.h
+++ b/Source/cmUVHandlePtr.h
@@ -8,7 +8,7 @@
 #include <memory>
 #include <type_traits>
 
-#include "cm_uv.h"
+#include <cm3p/uv.h>
 
 #if defined(__SUNPRO_CC)
 
diff --git a/Source/cmUVProcessChain.cxx b/Source/cmUVProcessChain.cxx
index 543c330..6040fd8 100644
--- a/Source/cmUVProcessChain.cxx
+++ b/Source/cmUVProcessChain.cxx
@@ -9,7 +9,7 @@
 
 #include <cm/memory>
 
-#include "cm_uv.h"
+#include <cm3p/uv.h>
 
 #include "cmGetPipes.h"
 #include "cmUVHandlePtr.h"
diff --git a/Source/cmUVProcessChain.h b/Source/cmUVProcessChain.h
index 05a7cc8..b5ccb19 100644
--- a/Source/cmUVProcessChain.h
+++ b/Source/cmUVProcessChain.h
@@ -4,14 +4,14 @@
 #define cmUVProcessChain_h
 
 #include <array>
-#include <cstddef>
+#include <cstddef> // IWYU pragma: keep
 #include <cstdint>
 #include <iosfwd>
 #include <memory>
 #include <string>
 #include <vector>
 
-#include "cm_uv.h"
+#include <cm3p/uv.h>
 
 class cmUVProcessChain;
 
diff --git a/Source/cmUVSignalHackRAII.h b/Source/cmUVSignalHackRAII.h
index 63599db..60e4ca8 100644
--- a/Source/cmUVSignalHackRAII.h
+++ b/Source/cmUVSignalHackRAII.h
@@ -3,7 +3,7 @@
 #pragma once
 #include "cmConfigure.h" // IWYU pragma: keep
 
-#include "cm_uv.h"
+#include <cm3p/uv.h>
 
 #if defined(CMAKE_USE_SYSTEM_LIBUV) && !defined(_WIN32) &&                    \
   UV_VERSION_MAJOR == 1 && UV_VERSION_MINOR < 19
diff --git a/Source/cmUVStreambuf.h b/Source/cmUVStreambuf.h
index 1c8a771..50faede 100644
--- a/Source/cmUVStreambuf.h
+++ b/Source/cmUVStreambuf.h
@@ -8,7 +8,7 @@
 #include <streambuf>
 #include <vector>
 
-#include "cm_uv.h"
+#include <cm3p/uv.h>
 
 #include "cmUVHandlePtr.h"
 
diff --git a/Source/cmUtilitySourceCommand.cxx b/Source/cmUtilitySourceCommand.cxx
index a43165c..6de78ff 100644
--- a/Source/cmUtilitySourceCommand.cxx
+++ b/Source/cmUtilitySourceCommand.cxx
@@ -84,8 +84,8 @@
   std::string utilityDirectory =
     status.GetMakefile().GetCurrentBinaryDirectory();
   std::string exePath;
-  if (status.GetMakefile().GetDefinition("EXECUTABLE_OUTPUT_PATH")) {
-    exePath = status.GetMakefile().GetDefinition("EXECUTABLE_OUTPUT_PATH");
+  if (auto d = status.GetMakefile().GetDefinition("EXECUTABLE_OUTPUT_PATH")) {
+    exePath = d;
   }
   if (!exePath.empty()) {
     utilityDirectory = exePath;
@@ -102,15 +102,15 @@
   cmSystemTools::ReplaceString(utilityExecutable, "/./", "/");
 
   // Enter the value into the cache.
-  status.GetMakefile().AddCacheDefinition(
-    cacheEntry, utilityExecutable.c_str(), "Path to an internal program.",
-    cmStateEnums::FILEPATH);
+  status.GetMakefile().AddCacheDefinition(cacheEntry, utilityExecutable,
+                                          "Path to an internal program.",
+                                          cmStateEnums::FILEPATH);
   // add a value into the cache that maps from the
   // full path to the name of the project
   cmSystemTools::ConvertToUnixSlashes(utilityExecutable);
-  status.GetMakefile().AddCacheDefinition(
-    utilityExecutable, utilityName.c_str(), "Executable to project name.",
-    cmStateEnums::INTERNAL);
+  status.GetMakefile().AddCacheDefinition(utilityExecutable, utilityName,
+                                          "Executable to project name.",
+                                          cmStateEnums::INTERNAL);
 
   return true;
 }
diff --git a/Source/cmVSSetupHelper.cxx b/Source/cmVSSetupHelper.cxx
index dd9f058..9626599 100644
--- a/Source/cmVSSetupHelper.cxx
+++ b/Source/cmVSSetupHelper.cxx
@@ -258,6 +258,20 @@
   return isInstalled;
 }
 
+bool cmVSSetupAPIHelper::GetVSInstanceVersion(
+  unsigned long long& vsInstanceVersion)
+{
+  vsInstanceVersion = 0;
+  bool isInstalled = this->EnumerateAndChooseVSInstance();
+
+  if (isInstalled) {
+    vsInstanceVersion =
+      static_cast<unsigned long long>(chosenInstanceInfo.ullVersion);
+  }
+
+  return isInstalled;
+}
+
 bool cmVSSetupAPIHelper::GetVCToolsetVersion(std::string& vsToolsetVersion)
 {
   vsToolsetVersion.clear();
diff --git a/Source/cmVSSetupHelper.h b/Source/cmVSSetupHelper.h
index 0980cef..a926eee 100644
--- a/Source/cmVSSetupHelper.h
+++ b/Source/cmVSSetupHelper.h
@@ -8,13 +8,12 @@
 #endif
 
 // Published by Visual Studio Setup team
+#include <cm3p/Setup.Configuration.h>
 #include <string>
 #include <vector>
 
 #include <windows.h>
 
-#include "cmvssetup/Setup.Configuration.h"
-
 template <class T>
 class SmartCOMPtr
 {
@@ -107,6 +106,7 @@
 
   bool IsVSInstalled();
   bool GetVSInstanceInfo(std::string& vsInstallLocation);
+  bool GetVSInstanceVersion(unsigned long long& vsInstanceVersion);
   bool GetVCToolsetVersion(std::string& vsToolsetVersion);
   bool IsWin10SDKInstalled();
   bool IsWin81SDKInstalled();
diff --git a/Source/cmVariableWatchCommand.cxx b/Source/cmVariableWatchCommand.cxx
index 35b9a1d..ecae16d 100644
--- a/Source/cmVariableWatchCommand.cxx
+++ b/Source/cmVariableWatchCommand.cxx
@@ -42,7 +42,7 @@
   /// Ultra bad!!
   cmMakefile* makefile = const_cast<cmMakefile*>(mf);
 
-  std::string stack = makefile->GetProperty("LISTFILE_STACK");
+  std::string stack = *mf->GetProperty("LISTFILE_STACK");
   if (!data->Command.empty()) {
     cmListFileFunction newLFF;
     const char* const currentListFile =
diff --git a/Source/cmVersion.h b/Source/cmVersion.h
index bfd994d..932ef04 100644
--- a/Source/cmVersion.h
+++ b/Source/cmVersion.h
@@ -3,7 +3,7 @@
 #ifndef cmVersion_h
 #define cmVersion_h
 
-#include "cm_kwiml.h"
+#include <cm3p/kwiml/int.h>
 
 /** \class cmVersion
  * \brief Helper class for providing CMake and CTest version information.
diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx
index 163ff19..db9dc53 100644
--- a/Source/cmVisualStudio10TargetGenerator.cxx
+++ b/Source/cmVisualStudio10TargetGenerator.cxx
@@ -6,11 +6,12 @@
 #include <set>
 
 #include <cm/memory>
+#include <cm/string_view>
 #include <cm/vector>
+#include <cmext/algorithm>
 
 #include "windows.h"
 
-#include "cmAlgorithms.h"
 #include "cmComputeLinkInformation.h"
 #include "cmCustomCommand.h"
 #include "cmCustomCommandGenerator.h"
@@ -18,10 +19,12 @@
 #include "cmGeneratorExpression.h"
 #include "cmGeneratorTarget.h"
 #include "cmGlobalVisualStudio10Generator.h"
+#include "cmGlobalVisualStudioVersionedGenerator.h"
 #include "cmLinkLineDeviceComputer.h"
 #include "cmLocalVisualStudio10Generator.h"
 #include "cmMakefile.h"
 #include "cmSourceFile.h"
+#include "cmStringAlgorithms.h"
 #include "cmSystemTools.h"
 #include "cmVisualStudioGeneratorOptions.h"
 
@@ -61,10 +64,10 @@
     this->StartElement();
   }
   Elem(const Elem&) = delete;
-  Elem(Elem& par, const std::string& tag)
+  Elem(Elem& par, cm::string_view tag)
     : S(par.S)
     , Indent(par.Indent + 1)
-    , Tag(tag)
+    , Tag(std::string(tag))
   {
     par.SetHasElements();
     this->StartElement();
@@ -78,22 +81,22 @@
   }
   std::ostream& WriteString(const char* line);
   void StartElement() { this->WriteString("<") << this->Tag; }
-  void Element(const std::string& tag, const std::string& val)
+  void Element(cm::string_view tag, std::string val)
   {
-    Elem(*this, tag).Content(val);
+    Elem(*this, tag).Content(std::move(val));
   }
-  Elem& Attribute(const char* an, const std::string& av)
+  Elem& Attribute(const char* an, std::string av)
   {
-    this->S << " " << an << "=\"" << cmVS10EscapeAttr(av) << "\"";
+    this->S << " " << an << "=\"" << cmVS10EscapeAttr(std::move(av)) << "\"";
     return *this;
   }
-  void Content(const std::string& val)
+  void Content(std::string val)
   {
     if (!this->HasContent) {
       this->S << ">";
       this->HasContent = true;
     }
-    this->S << cmVS10EscapeXML(val);
+    this->S << cmVS10EscapeXML(std::move(val));
   }
   ~Elem()
   {
@@ -229,15 +232,17 @@
   , LocalGenerator(
       (cmLocalVisualStudio10Generator*)target->GetLocalGenerator())
 {
-  this->Makefile->GetConfigurations(this->Configurations);
+  this->Configurations =
+    this->Makefile->GetGeneratorConfigs(cmMakefile::ExcludeEmptyConfig);
   this->NsightTegra = gg->IsNsightTegra();
+  this->Android = gg->TargetsAndroid();
   for (int i = 0; i < 4; ++i) {
     this->NsightTegraVersion[i] = 0;
   }
   sscanf(gg->GetNsightTegraVersion().c_str(), "%u.%u.%u.%u",
          &this->NsightTegraVersion[0], &this->NsightTegraVersion[1],
          &this->NsightTegraVersion[2], &this->NsightTegraVersion[3]);
-  this->MSTools = !this->NsightTegra;
+  this->MSTools = !this->NsightTegra && !this->Android;
   this->Managed = false;
   this->TargetCompileAsWinRT = false;
   this->IsMissingFiles = false;
@@ -246,6 +251,7 @@
     this->LocalGenerator->GetTargetDirectory(this->GeneratorTarget);
   this->InSourceBuild = (this->Makefile->GetCurrentSourceDirectory() ==
                          this->Makefile->GetCurrentBinaryDirectory());
+  this->ClassifyAllConfigSources();
 }
 
 cmVisualStudio10TargetGenerator::~cmVisualStudio10TargetGenerator()
@@ -309,8 +315,7 @@
 void cmVisualStudio10TargetGenerator::Generate()
 {
   // do not generate external ms projects
-  if (this->GeneratorTarget->GetType() == cmStateEnums::INTERFACE_LIBRARY ||
-      this->GeneratorTarget->GetProperty("EXTERNAL_MSPROJECT")) {
+  if (this->GeneratorTarget->GetProperty("EXTERNAL_MSPROJECT")) {
     return;
   }
   const std::string ProjectFileExtension =
@@ -329,6 +334,13 @@
     this->ProjectType = csproj;
     this->Managed = true;
   }
+
+  if (this->Android &&
+      this->GeneratorTarget->GetType() == cmStateEnums::EXECUTABLE &&
+      !this->GeneratorTarget->Target->IsAndroidGuiExecutable()) {
+    this->GlobalGenerator->AddAndroidExecutableWarning(this->Name);
+  }
+
   // Tell the global generator the name of the project file
   this->GeneratorTarget->Target->SetProperty("GENERATOR_FILE_NAME",
                                              this->Name);
@@ -423,38 +435,38 @@
       e1.Attribute("Label", "Globals");
       e1.Element("ProjectGuid", "{" + this->GUID + "}");
 
-      if (this->MSTools &&
-          this->GeneratorTarget->GetType() <= cmStateEnums::GLOBAL_TARGET) {
+      if ((this->MSTools || this->Android) &&
+          this->GeneratorTarget->IsInBuildSystem()) {
         this->WriteApplicationTypeSettings(e1);
         this->VerifyNecessaryFiles();
       }
 
-      const char* vsProjectTypes =
+      cmProp vsProjectTypes =
         this->GeneratorTarget->GetProperty("VS_GLOBAL_PROJECT_TYPES");
       if (vsProjectTypes) {
         const char* tagName = "ProjectTypes";
         if (this->ProjectType == csproj) {
           tagName = "ProjectTypeGuids";
         }
-        e1.Element(tagName, vsProjectTypes);
+        e1.Element(tagName, *vsProjectTypes);
       }
 
-      const char* vsProjectName =
+      cmProp vsProjectName =
         this->GeneratorTarget->GetProperty("VS_SCC_PROJECTNAME");
-      const char* vsLocalPath =
+      cmProp vsLocalPath =
         this->GeneratorTarget->GetProperty("VS_SCC_LOCALPATH");
-      const char* vsProvider =
+      cmProp vsProvider =
         this->GeneratorTarget->GetProperty("VS_SCC_PROVIDER");
 
       if (vsProjectName && vsLocalPath && vsProvider) {
-        e1.Element("SccProjectName", vsProjectName);
-        e1.Element("SccLocalPath", vsLocalPath);
-        e1.Element("SccProvider", vsProvider);
+        e1.Element("SccProjectName", *vsProjectName);
+        e1.Element("SccLocalPath", *vsLocalPath);
+        e1.Element("SccProvider", *vsProvider);
 
-        const char* vsAuxPath =
+        cmProp vsAuxPath =
           this->GeneratorTarget->GetProperty("VS_SCC_AUXPATH");
         if (vsAuxPath) {
-          e1.Element("SccAuxPath", vsAuxPath);
+          e1.Element("SccAuxPath", *vsAuxPath);
         }
       }
 
@@ -462,45 +474,48 @@
         e1.Element("WinMDAssembly", "true");
       }
 
-      const char* vsGlobalKeyword =
+      cmProp vsGlobalKeyword =
         this->GeneratorTarget->GetProperty("VS_GLOBAL_KEYWORD");
       if (!vsGlobalKeyword) {
-        e1.Element("Keyword", "Win32Proj");
+        if (this->GlobalGenerator->TargetsAndroid()) {
+          e1.Element("Keyword", "Android");
+        } else {
+          e1.Element("Keyword", "Win32Proj");
+        }
       } else {
-        e1.Element("Keyword", vsGlobalKeyword);
+        e1.Element("Keyword", *vsGlobalKeyword);
       }
 
-      const char* vsGlobalRootNamespace =
+      cmProp vsGlobalRootNamespace =
         this->GeneratorTarget->GetProperty("VS_GLOBAL_ROOTNAMESPACE");
       if (vsGlobalRootNamespace) {
-        e1.Element("RootNamespace", vsGlobalRootNamespace);
+        e1.Element("RootNamespace", *vsGlobalRootNamespace);
       }
 
       e1.Element("Platform", this->Platform);
-      const char* projLabel =
-        this->GeneratorTarget->GetProperty("PROJECT_LABEL");
+      cmProp projLabel = this->GeneratorTarget->GetProperty("PROJECT_LABEL");
       if (!projLabel) {
-        projLabel = this->Name.c_str();
+        projLabel = &this->Name;
       }
-      e1.Element("ProjectName", projLabel);
+      e1.Element("ProjectName", *projLabel);
       {
-        const char* targetFramework =
+        cmProp targetFramework =
           this->GeneratorTarget->GetProperty("DOTNET_TARGET_FRAMEWORK");
         if (targetFramework) {
-          if (std::strchr(targetFramework, ';') != nullptr) {
-            e1.Element("TargetFrameworks", targetFramework);
+          if (std::strchr(targetFramework->c_str(), ';') != nullptr) {
+            e1.Element("TargetFrameworks", *targetFramework);
           } else {
-            e1.Element("TargetFramework", targetFramework);
+            e1.Element("TargetFramework", *targetFramework);
           }
         } else {
           // TODO: add deprecation warning for VS_* property?
-          const char* targetFrameworkVersion =
-            this->GeneratorTarget->GetProperty(
-              "VS_DOTNET_TARGET_FRAMEWORK_VERSION");
-          if (!targetFrameworkVersion) {
-            targetFrameworkVersion = this->GeneratorTarget->GetProperty(
+          cmProp p = this->GeneratorTarget->GetProperty(
+            "VS_DOTNET_TARGET_FRAMEWORK_VERSION");
+          if (!p) {
+            p = this->GeneratorTarget->GetProperty(
               "DOTNET_TARGET_FRAMEWORK_VERSION");
           }
+          const char* targetFrameworkVersion = p ? p->c_str() : nullptr;
           if (!targetFrameworkVersion && this->ProjectType == csproj &&
               this->GlobalGenerator->TargetsWindowsCE() &&
               this->GlobalGenerator->GetVersion() ==
@@ -519,18 +534,15 @@
         }
         if (this->ProjectType == csproj &&
             this->GlobalGenerator->TargetsWindowsCE()) {
-          const char* targetFrameworkId = this->GeneratorTarget->GetProperty(
+          cmProp targetFrameworkId = this->GeneratorTarget->GetProperty(
             "VS_TARGET_FRAMEWORK_IDENTIFIER");
-          if (!targetFrameworkId) {
-            targetFrameworkId = "WindowsEmbeddedCompact";
-          }
-          e1.Element("TargetFrameworkIdentifier", targetFrameworkId);
-          const char* targetFrameworkVer = this->GeneratorTarget->GetProperty(
+          e1.Element("TargetFrameworkIdentifier",
+                     targetFrameworkId ? *targetFrameworkId
+                                       : "WindowsEmbeddedCompact");
+          cmProp targetFrameworkVer = this->GeneratorTarget->GetProperty(
             "VS_TARGET_FRAMEWORKS_TARGET_VERSION");
-          if (!targetFrameworkVer) {
-            targetFrameworkVer = "v8.0";
-          }
-          e1.Element("TargetFrameworkTargetsVersion", targetFrameworkVer);
+          e1.Element("TargetFrameworkTargetsVersion",
+                     targetFrameworkVer ? *targetFrameworkVer : "v8.0");
         }
         if (!this->GlobalGenerator->GetPlatformToolsetCudaCustomDirString()
                .empty()) {
@@ -556,19 +568,20 @@
 
       std::vector<std::string> keys = this->GeneratorTarget->GetPropertyKeys();
       for (std::string const& keyIt : keys) {
-        static const char* prefix = "VS_GLOBAL_";
-        if (keyIt.find(prefix) != 0)
+        static const cm::string_view prefix = "VS_GLOBAL_";
+        if (!cmHasPrefix(keyIt, prefix))
           continue;
-        std::string globalKey = keyIt.substr(strlen(prefix));
+        cm::string_view globalKey =
+          cm::string_view(keyIt).substr(prefix.length());
         // Skip invalid or separately-handled properties.
         if (globalKey.empty() || globalKey == "PROJECT_TYPES" ||
             globalKey == "ROOTNAMESPACE" || globalKey == "KEYWORD") {
           continue;
         }
-        const char* value = this->GeneratorTarget->GetProperty(keyIt);
+        cmProp value = this->GeneratorTarget->GetProperty(keyIt);
         if (!value)
           continue;
-        e1.Element(globalKey, value);
+        e1.Element(globalKey, *value);
       }
 
       if (this->Managed) {
@@ -591,11 +604,11 @@
             }
             break;
           case cmStateEnums::UTILITY:
+          case cmStateEnums::INTERFACE_LIBRARY:
           case cmStateEnums::GLOBAL_TARGET:
             outputType = "Utility";
             break;
           case cmStateEnums::UNKNOWN_LIBRARY:
-          case cmStateEnums::INTERFACE_LIBRARY:
             break;
         }
         e1.Element("OutputType", outputType);
@@ -657,7 +670,7 @@
           cmStrCat(this->DefaultArtifactDir, "\\nasm.props");
         ConvertToWindowsSlash(propsLocal);
         this->Makefile->ConfigureFile(propsTemplate, propsLocal, false, true,
-                                      true);
+                                      true, true);
         Elem(e1, "Import").Attribute("Project", propsLocal);
       }
     }
@@ -673,9 +686,8 @@
           props = VS10_CSharp_USER_PROPS;
           break;
       }
-      if (const char* p =
-            this->GeneratorTarget->GetProperty("VS_USER_PROPS")) {
-        props = p;
+      if (cmProp p = this->GeneratorTarget->GetProperty("VS_USER_PROPS")) {
+        props = *p;
       }
       if (!props.empty()) {
         ConvertToWindowsSlash(props);
@@ -781,50 +793,41 @@
 void cmVisualStudio10TargetGenerator::WritePackageReferences(Elem& e0)
 {
   std::vector<std::string> packageReferences;
-  if (const char* vsPackageReferences =
+  if (cmProp vsPackageReferences =
         this->GeneratorTarget->GetProperty("VS_PACKAGE_REFERENCES")) {
-    cmExpandList(vsPackageReferences, packageReferences);
+    cmExpandList(*vsPackageReferences, packageReferences);
   }
   if (!packageReferences.empty()) {
     Elem e1(e0, "ItemGroup");
     for (std::string const& ri : packageReferences) {
       size_t versionIndex = ri.find_last_of('_');
       if (versionIndex != std::string::npos) {
-        WritePackageReference(e1, ri.substr(0, versionIndex),
-                              ri.substr(versionIndex + 1));
+        Elem e2(e1, "PackageReference");
+        e2.Attribute("Include", ri.substr(0, versionIndex));
+        e2.Attribute("Version", ri.substr(versionIndex + 1));
       }
     }
   }
 }
 
-void cmVisualStudio10TargetGenerator::WritePackageReference(
-  Elem& e1, std::string const& ref, std::string const& version)
-{
-  Elem e2(e1, "PackageReference");
-  e2.Attribute("Include", ref);
-  e2.Attribute("Version", version);
-}
-
 void cmVisualStudio10TargetGenerator::WriteDotNetReferences(Elem& e0)
 {
   std::vector<std::string> references;
-  if (const char* vsDotNetReferences =
+  if (cmProp vsDotNetReferences =
         this->GeneratorTarget->GetProperty("VS_DOTNET_REFERENCES")) {
-    cmExpandList(vsDotNetReferences, references);
+    cmExpandList(*vsDotNetReferences, references);
   }
   cmPropertyMap const& props = this->GeneratorTarget->Target->GetProperties();
   for (auto const& i : props.GetList()) {
-    if (i.first.find("VS_DOTNET_REFERENCE_") == 0) {
-      std::string name = i.first.substr(20);
-      if (!name.empty()) {
-        std::string path = i.second;
-        if (!cmsys::SystemTools::FileIsFullPath(path)) {
-          path = this->Makefile->GetCurrentSourceDirectory() + "/" + path;
-        }
-        ConvertToWindowsSlash(path);
-        this->DotNetHintReferences[""].push_back(
-          DotNetHintReference(name, path));
+    static const cm::string_view vsDnRef = "VS_DOTNET_REFERENCE_";
+    if (cmHasPrefix(i.first, vsDnRef)) {
+      std::string path = i.second;
+      if (!cmsys::SystemTools::FileIsFullPath(path)) {
+        path = this->Makefile->GetCurrentSourceDirectory() + "/" + path;
       }
+      ConvertToWindowsSlash(path);
+      this->DotNetHintReferences[""].emplace_back(
+        DotNetHintReference(i.first.substr(vsDnRef.length()), path));
     }
   }
   if (!references.empty() || !this->DotNetHintReferences.empty()) {
@@ -837,7 +840,7 @@
           cmsys::SystemTools::GetFilenameWithoutLastExtension(ri);
         std::string path = ri;
         ConvertToWindowsSlash(path);
-        this->DotNetHintReferences[""].push_back(
+        this->DotNetHintReferences[""].emplace_back(
           DotNetHintReference(name, path));
       } else {
         this->WriteDotNetReference(e1, ri, "", "");
@@ -869,9 +872,9 @@
   e2.Element("ReferenceOutputAssembly", "true");
   if (!hint.empty()) {
     const char* privateReference = "True";
-    if (const char* value = this->GeneratorTarget->GetProperty(
+    if (cmProp value = this->GeneratorTarget->GetProperty(
           "VS_DOTNET_REFERENCES_COPY_LOCAL")) {
-      if (cmIsOff(value)) {
+      if (cmIsOff(*value)) {
         privateReference = "False";
       }
     }
@@ -883,11 +886,10 @@
 
 void cmVisualStudio10TargetGenerator::WriteImports(Elem& e0)
 {
-  const char* imports =
+  cmProp imports =
     this->GeneratorTarget->Target->GetProperty("VS_PROJECT_IMPORT");
   if (imports) {
-    std::vector<std::string> argsSplit =
-      cmExpandedList(std::string(imports), false);
+    std::vector<std::string> argsSplit = cmExpandedList(*imports, false);
     for (auto& path : argsSplit) {
       if (!cmsys::SystemTools::FileIsFullPath(path)) {
         path = this->Makefile->GetCurrentSourceDirectory() + "/" + path;
@@ -910,12 +912,8 @@
   CustomTags tags;
   cmPropertyMap const& props = this->GeneratorTarget->Target->GetProperties();
   for (const auto& i : props.GetList()) {
-    if (i.first.find(refPropFullPrefix) == 0) {
-      std::string refTag = i.first.substr(refPropFullPrefix.length());
-      std::string refVal = i.second;
-      if (!refTag.empty() && !refVal.empty()) {
-        tags[refTag] = refVal;
-      }
+    if (cmHasPrefix(i.first, refPropFullPrefix) && !i.second.empty()) {
+      tags[i.first.substr(refPropFullPrefix.length())] = i.second;
     }
   }
   for (auto const& tag : tags) {
@@ -925,7 +923,7 @@
 
 void cmVisualStudio10TargetGenerator::WriteDotNetDocumentationFile(Elem& e0)
 {
-  std::string const documentationFile =
+  std::string const& documentationFile =
     this->GeneratorTarget->GetSafeProperty("VS_DOTNET_DOCUMENTATION_FILE");
 
   if (this->ProjectType == csproj && !documentationFile.empty()) {
@@ -937,13 +935,11 @@
 
 void cmVisualStudio10TargetGenerator::WriteEmbeddedResourceGroup(Elem& e0)
 {
-  std::vector<cmSourceFile const*> resxObjs;
-  this->GeneratorTarget->GetResxSources(resxObjs, "");
-  if (!resxObjs.empty()) {
+  if (!this->ResxObjs.empty()) {
     Elem e1(e0, "ItemGroup");
     std::string srcDir = this->Makefile->GetCurrentSourceDirectory();
     ConvertToWindowsSlash(srcDir);
-    for (cmSourceFile const* oi : resxObjs) {
+    for (cmSourceFile const* oi : this->ResxObjs) {
       std::string obj = oi->GetFullPath();
       ConvertToWindowsSlash(obj);
       bool useRelativePath = false;
@@ -952,7 +948,7 @@
         // subdirectory
         // of the .csproj file, we have to use relative pathnames, otherwise
         // visual studio does not show the file in the IDE. Sorry.
-        if (obj.find(srcDir) == 0) {
+        if (cmHasPrefix(obj, srcDir)) {
           obj = this->ConvertPath(obj, true);
           ConvertToWindowsSlash(obj);
           useRelativePath = true;
@@ -981,17 +977,11 @@
         // If the resource was NOT added using a relative path (which should
         // be the default), we have to provide a link here
         if (!useRelativePath) {
-          std::string link;
-          if (obj.find(srcDir) == 0) {
-            link = obj.substr(srcDir.length() + 1);
-          } else if (obj.find(binDir) == 0) {
-            link = obj.substr(binDir.length() + 1);
-          } else {
+          std::string link = this->GetCSharpSourceLink(oi);
+          if (link.empty()) {
             link = cmsys::SystemTools::GetFilenameName(obj);
           }
-          if (!link.empty()) {
-            e2.Element("Link", link);
-          }
+          e2.Element("Link", link);
         }
         // Determine if this is a generated resource from a .Designer.cs file
         std::string designerResource =
@@ -1000,15 +990,15 @@
           ".Designer.cs";
         if (cmsys::SystemTools::FileExists(designerResource)) {
           std::string generator = "PublicResXFileCodeGenerator";
-          if (const char* g = oi->GetProperty("VS_RESOURCE_GENERATOR")) {
-            generator = g;
+          if (cmProp g = oi->GetProperty("VS_RESOURCE_GENERATOR")) {
+            generator = *g;
           }
           if (!generator.empty()) {
             e2.Element("Generator", generator);
-            if (designerResource.find(srcDir) == 0) {
-              designerResource = designerResource.substr(srcDir.length() + 1);
-            } else if (designerResource.find(binDir) == 0) {
-              designerResource = designerResource.substr(binDir.length() + 1);
+            if (cmHasPrefix(designerResource, srcDir)) {
+              designerResource.erase(0, srcDir.length());
+            } else if (cmHasPrefix(designerResource, binDir)) {
+              designerResource.erase(0, binDir.length());
             } else {
               designerResource =
                 cmsys::SystemTools::GetFilenameName(designerResource);
@@ -1019,11 +1009,12 @@
         }
         const cmPropertyMap& props = oi->GetProperties();
         for (const std::string& p : props.GetKeys()) {
-          static const std::string propNamePrefix = "VS_CSHARP_";
-          if (p.find(propNamePrefix) == 0) {
-            std::string tagName = p.substr(propNamePrefix.length());
+          static const cm::string_view propNamePrefix = "VS_CSHARP_";
+          if (cmHasPrefix(p, propNamePrefix)) {
+            cm::string_view tagName =
+              cm::string_view(p).substr(propNamePrefix.length());
             if (!tagName.empty()) {
-              std::string value = props.GetPropertyValue(p);
+              const std::string& value = *props.GetPropertyValue(p);
               if (!value.empty()) {
                 e2.Element(tagName, value);
               }
@@ -1037,16 +1028,14 @@
 
 void cmVisualStudio10TargetGenerator::WriteXamlFilesGroup(Elem& e0)
 {
-  std::vector<cmSourceFile const*> xamlObjs;
-  this->GeneratorTarget->GetXamlSources(xamlObjs, "");
-  if (!xamlObjs.empty()) {
+  if (!this->XamlObjs.empty()) {
     Elem e1(e0, "ItemGroup");
-    for (cmSourceFile const* oi : xamlObjs) {
+    for (cmSourceFile const* oi : this->XamlObjs) {
       std::string obj = oi->GetFullPath();
-      const char* xamlType;
-      const char* xamlTypeProperty = oi->GetProperty("VS_XAML_TYPE");
+      std::string xamlType;
+      cmProp xamlTypeProperty = oi->GetProperty("VS_XAML_TYPE");
       if (xamlTypeProperty) {
-        xamlType = xamlTypeProperty;
+        xamlType = *xamlTypeProperty;
       } else {
         xamlType = "Page";
       }
@@ -1054,25 +1043,6 @@
       Elem e2(e1, xamlType);
       this->WriteSource(e2, oi);
       e2.SetHasElements();
-      if (this->ProjectType == csproj && !this->InSourceBuild) {
-        // add <Link> tag to written XAML source if necessary
-        const std::string& srcDir =
-          this->Makefile->GetCurrentSourceDirectory();
-        const std::string& binDir =
-          this->Makefile->GetCurrentBinaryDirectory();
-        std::string link;
-        if (obj.find(srcDir) == 0) {
-          link = obj.substr(srcDir.length() + 1);
-        } else if (obj.find(binDir) == 0) {
-          link = obj.substr(binDir.length() + 1);
-        } else {
-          link = cmsys::SystemTools::GetFilenameName(obj);
-        }
-        if (!link.empty()) {
-          ConvertToWindowsSlash(link);
-          e2.Element("Link", link);
-        }
-      }
       e2.Element("SubType", "Designer");
     }
   }
@@ -1117,9 +1087,9 @@
 void cmVisualStudio10TargetGenerator::WriteWinRTReferences(Elem& e0)
 {
   std::vector<std::string> references;
-  if (const char* vsWinRTReferences =
+  if (cmProp vsWinRTReferences =
         this->GeneratorTarget->GetProperty("VS_WINRT_REFERENCES")) {
-    cmExpandList(vsWinRTReferences, references);
+    cmExpandList(*vsWinRTReferences, references);
   }
 
   if (this->GlobalGenerator->TargetsWindowsPhone() &&
@@ -1160,9 +1130,9 @@
 
     if (this->ProjectType != csproj) {
       std::string configType;
-      if (const char* vsConfigurationType =
+      if (cmProp vsConfigurationType =
             this->GeneratorTarget->GetProperty("VS_CONFIGURATION_TYPE")) {
-        configType = cmGeneratorExpression::Evaluate(vsConfigurationType,
+        configType = cmGeneratorExpression::Evaluate(*vsConfigurationType,
                                                      this->LocalGenerator, c);
       } else {
         switch (this->GeneratorTarget->GetType()) {
@@ -1176,14 +1146,17 @@
             break;
           case cmStateEnums::EXECUTABLE:
             if (this->NsightTegra &&
-                !this->GeneratorTarget->GetPropertyAsBool("ANDROID_GUI")) {
+                !this->GeneratorTarget->Target->IsAndroidGuiExecutable()) {
               // Android executables are .so too.
               configType = "DynamicLibrary";
+            } else if (this->Android) {
+              configType = "DynamicLibrary";
             } else {
               configType = "Application";
             }
             break;
           case cmStateEnums::UTILITY:
+          case cmStateEnums::INTERFACE_LIBRARY:
           case cmStateEnums::GLOBAL_TARGET:
             if (this->NsightTegra) {
               // Tegra-Android platform does not understand "Utility".
@@ -1193,7 +1166,6 @@
             }
             break;
           case cmStateEnums::UNKNOWN_LIBRARY:
-          case cmStateEnums::INTERFACE_LIBRARY:
             break;
         }
       }
@@ -1208,6 +1180,8 @@
       }
     } else if (this->NsightTegra) {
       this->WriteNsightTegraConfigurationValues(e1, c);
+    } else if (this->Android) {
+      this->WriteAndroidConfigurationValues(e1, c);
     }
   }
 }
@@ -1218,9 +1192,9 @@
   if (!this->GlobalGenerator->TargetsWindowsCE()) {
     return;
   }
-  const char* additionalFiles =
+  cmProp additionalFiles =
     this->GeneratorTarget->GetProperty("DEPLOYMENT_ADDITIONAL_FILES");
-  const char* remoteDirectory =
+  cmProp remoteDirectory =
     this->GeneratorTarget->GetProperty("DEPLOYMENT_REMOTE_DIRECTORY");
   if (!(additionalFiles || remoteDirectory)) {
     return;
@@ -1230,10 +1204,10 @@
     e1.Attribute("Condition", this->CalcCondition(c));
 
     if (remoteDirectory) {
-      e1.Element("RemoteDirectory", remoteDirectory);
+      e1.Element("RemoteDirectory", *remoteDirectory);
     }
     if (additionalFiles) {
-      e1.Element("CEAdditionalFiles", additionalFiles);
+      e1.Element("CEAdditionalFiles", *additionalFiles);
     }
   }
 }
@@ -1271,7 +1245,10 @@
   } else {
     e1.Element("CharacterSet", "MultiByte");
   }
-  if (const char* toolset = gg->GetPlatformToolset()) {
+  if (cmProp projectToolsetOverride =
+        this->GeneratorTarget->GetProperty("VS_PLATFORM_TOOLSET")) {
+    e1.Element("PlatformToolset", *projectToolsetOverride);
+  } else if (const char* toolset = gg->GetPlatformToolset()) {
     e1.Element("PlatformToolset", toolset);
   }
   if (this->GeneratorTarget->GetPropertyAsBool("VS_WINRT_COMPONENT") ||
@@ -1314,7 +1291,10 @@
     o.RemoveFlag("Platform");
   }
 
-  if (const char* toolset = gg->GetPlatformToolset()) {
+  if (cmProp projectToolsetOverride =
+        this->GeneratorTarget->GetProperty("VS_PLATFORM_TOOLSET")) {
+    e1.Element("PlatformToolset", *projectToolsetOverride);
+  } else if (const char* toolset = gg->GetPlatformToolset()) {
     e1.Element("PlatformToolset", toolset);
   }
 
@@ -1322,8 +1302,8 @@
     cmStrCat(cmSystemTools::UpperCase(config), "_POSTFIX");
   std::string assemblyName = this->GeneratorTarget->GetOutputName(
     config, cmStateEnums::RuntimeBinaryArtifact);
-  if (const char* postfix = this->GeneratorTarget->GetProperty(postfixName)) {
-    assemblyName += postfix;
+  if (cmProp postfix = this->GeneratorTarget->GetProperty(postfixName)) {
+    assemblyName += *postfix;
   }
   e1.Element("AssemblyName", assemblyName);
 
@@ -1343,43 +1323,65 @@
   cmGlobalVisualStudio10Generator* gg = this->GlobalGenerator;
   const char* toolset = gg->GetPlatformToolset();
   e1.Element("NdkToolchainVersion", toolset ? toolset : "Default");
-  if (const char* minApi =
-        this->GeneratorTarget->GetProperty("ANDROID_API_MIN")) {
-    e1.Element("AndroidMinAPI", "android-" + std::string(minApi));
+  if (cmProp minApi = this->GeneratorTarget->GetProperty("ANDROID_API_MIN")) {
+    e1.Element("AndroidMinAPI", "android-" + *minApi);
   }
-  if (const char* api = this->GeneratorTarget->GetProperty("ANDROID_API")) {
-    e1.Element("AndroidTargetAPI", "android-" + std::string(api));
+  if (cmProp api = this->GeneratorTarget->GetProperty("ANDROID_API")) {
+    e1.Element("AndroidTargetAPI", "android-" + *api);
   }
 
-  if (const char* cpuArch =
-        this->GeneratorTarget->GetProperty("ANDROID_ARCH")) {
-    e1.Element("AndroidArch", cpuArch);
+  if (cmProp cpuArch = this->GeneratorTarget->GetProperty("ANDROID_ARCH")) {
+    e1.Element("AndroidArch", *cpuArch);
   }
 
-  if (const char* stlType =
+  if (cmProp stlType =
         this->GeneratorTarget->GetProperty("ANDROID_STL_TYPE")) {
-    e1.Element("AndroidStlType", stlType);
+    e1.Element("AndroidStlType", *stlType);
+  }
+}
+
+void cmVisualStudio10TargetGenerator::WriteAndroidConfigurationValues(
+  Elem& e1, std::string const&)
+{
+  cmGlobalVisualStudio10Generator* gg = this->GlobalGenerator;
+  if (cmProp projectToolsetOverride =
+        this->GeneratorTarget->GetProperty("VS_PLATFORM_TOOLSET")) {
+    e1.Element("PlatformToolset", *projectToolsetOverride);
+  } else if (const char* toolset = gg->GetPlatformToolset()) {
+    e1.Element("PlatformToolset", toolset);
+  }
+  if (cmProp stlType =
+        this->GeneratorTarget->GetProperty("ANDROID_STL_TYPE")) {
+    if (*stlType != "none") {
+      e1.Element("UseOfStl", *stlType);
+    }
   }
 }
 
 void cmVisualStudio10TargetGenerator::WriteCustomCommands(Elem& e0)
 {
   this->CSharpCustomCommandNames.clear();
-  std::vector<cmSourceFile const*> customCommands;
-  this->GeneratorTarget->GetCustomCommands(customCommands, "");
-  for (cmSourceFile const* si : customCommands) {
-    this->WriteCustomCommand(e0, si);
+
+  cmSourceFile const* srcCMakeLists =
+    this->LocalGenerator->CreateVCProjBuildRule();
+
+  for (cmGeneratorTarget::AllConfigSource const& si :
+       this->GeneratorTarget->GetAllConfigSources()) {
+    if (si.Source == srcCMakeLists) {
+      // Skip explicit reference to CMakeLists.txt source.
+      continue;
+    }
+    this->WriteCustomCommand(e0, si.Source);
   }
 
   // Add CMakeLists.txt file with rule to re-run CMake for user convenience.
   if (this->GeneratorTarget->GetType() != cmStateEnums::GLOBAL_TARGET &&
       this->GeneratorTarget->GetName() != CMAKE_CHECK_BUILD_SYSTEM_TARGET) {
-    if (cmSourceFile const* sf =
-          this->LocalGenerator->CreateVCProjBuildRule()) {
+    if (srcCMakeLists) {
       // Write directly rather than through WriteCustomCommand because
       // we do not want the de-duplication and it has no dependencies.
-      if (cmCustomCommand const* command = sf->GetCustomCommand()) {
-        this->WriteCustomRule(e0, sf, *command);
+      if (cmCustomCommand const* command = srcCMakeLists->GetCustomCommand()) {
+        this->WriteCustomRule(e0, srcCMakeLists, *command);
       }
     }
   }
@@ -1439,16 +1441,14 @@
     spe2 = cm::make_unique<Elem>(*spe1, "CustomBuild");
     this->WriteSource(*spe2, source);
     spe2->SetHasElements();
+    if (command.GetStdPipesUTF8()) {
+      this->WriteStdOutEncodingUtf8(*spe2);
+    }
   } else {
     Elem e1(e0, "ItemGroup");
     Elem e2(e1, "None");
-    std::string link;
-    this->GetCSharpSourceLink(source, link);
     this->WriteSource(e2, source);
     e2.SetHasElements();
-    if (!link.empty()) {
-      e2.Element("Link", link);
-    }
   }
   for (std::string const& c : this->Configurations) {
     cmCustomCommandGenerator ccg(command, c, lg);
@@ -1662,11 +1662,9 @@
       }
     }
 
-    std::vector<cmSourceFile const*> resxObjs;
-    this->GeneratorTarget->GetResxSources(resxObjs, "");
-    if (!resxObjs.empty()) {
+    if (!this->ResxObjs.empty()) {
       Elem e1(e0, "ItemGroup");
-      for (cmSourceFile const* oi : resxObjs) {
+      for (cmSourceFile const* oi : this->ResxObjs) {
         std::string obj = oi->GetFullPath();
         ConvertToWindowsSlash(obj);
         Elem e2(e1, "EmbeddedResource");
@@ -1694,7 +1692,7 @@
         }
       }
 
-      if (!resxObjs.empty() || !this->AddedFiles.empty()) {
+      if (!this->ResxObjs.empty() || !this->AddedFiles.empty()) {
         std::string guidName = "SG_Filter_Resource Files";
         std::string guid = this->GlobalGenerator->GetGUID(guidName);
         Elem e2(e1, "Filter");
@@ -1779,25 +1777,70 @@
   if (this->IsResxHeader(fileName)) {
     e2.Element("FileType", "CppForm");
   } else if (this->IsXamlHeader(fileName)) {
-    std::string xamlFileName = fileName.substr(0, fileName.find_last_of("."));
-    e2.Element("DependentUpon", xamlFileName);
+    e2.Element("DependentUpon",
+               fileName.substr(0, fileName.find_last_of(".")));
   }
 }
 
+void cmVisualStudio10TargetGenerator::ParseSettingsProperty(
+  const std::string& settingsPropertyValue, ConfigToSettings& toolSettings)
+{
+  if (!settingsPropertyValue.empty()) {
+    cmGeneratorExpression ge;
+
+    std::unique_ptr<cmCompiledGeneratorExpression> cge =
+      ge.Parse(settingsPropertyValue);
+
+    for (const std::string& config : this->Configurations) {
+      std::string evaluated = cge->Evaluate(this->LocalGenerator, config);
+
+      std::vector<std::string> settings = cmExpandedList(evaluated);
+      for (const std::string& setting : settings) {
+        const std::string::size_type assignment = setting.find('=');
+        if (assignment != std::string::npos) {
+          const std::string propName = setting.substr(0, assignment);
+          const std::string propValue = setting.substr(assignment + 1);
+
+          if (!propValue.empty()) {
+            toolSettings[config][propName] = propValue;
+          }
+        }
+      }
+    }
+  }
+}
+
+bool cmVisualStudio10TargetGenerator::PropertyIsSameInAllConfigs(
+  const ConfigToSettings& toolSettings, const std::string& propName)
+{
+  std::string firstPropValue = "";
+  for (const auto& configToSettings : toolSettings) {
+    const std::unordered_map<std::string, std::string>& settings =
+      configToSettings.second;
+
+    if (firstPropValue.empty()) {
+      if (settings.find(propName) != settings.end()) {
+        firstPropValue = settings.find(propName)->second;
+      }
+    }
+
+    if (settings.find(propName) == settings.end()) {
+      return false;
+    }
+
+    if (settings.find(propName)->second != firstPropValue) {
+      return false;
+    }
+  }
+
+  return true;
+}
+
 void cmVisualStudio10TargetGenerator::WriteExtraSource(Elem& e1,
                                                        cmSourceFile const* sf)
 {
   bool toolHasSettings = false;
   const char* tool = "None";
-  std::string shaderType;
-  std::string shaderEntryPoint;
-  std::string shaderModel;
-  std::string shaderAdditionalFlags;
-  std::string shaderDisableOptimizations;
-  std::string shaderEnableDebug;
-  std::string shaderObjectFileName;
-  std::string outputHeaderFile;
-  std::string variableName;
   std::string settingsGenerator;
   std::string settingsLastGenOutput;
   std::string sourceLink;
@@ -1805,76 +1848,84 @@
   std::string copyToOutDir;
   std::string includeInVsix;
   std::string ext = cmSystemTools::LowerCase(sf->GetExtension());
-  if (this->ProjectType == csproj) {
-    // EVERY extra source file must have a <Link>, otherwise it might not
-    // be visible in Visual Studio at all. The path relative to current
-    // source- or binary-dir is used within the link, if the file is
-    // in none of these paths, it is added with the plain filename without
-    // any path. This means the file will show up at root-level of the csproj
-    // (where CMakeLists.txt etc. are).
-    if (!this->InSourceBuild) {
-      toolHasSettings = true;
-      std::string fullFileName = sf->GetFullPath();
-      std::string srcDir = this->Makefile->GetCurrentSourceDirectory();
-      std::string binDir = this->Makefile->GetCurrentBinaryDirectory();
-      if (fullFileName.find(binDir) != std::string::npos) {
-        sourceLink.clear();
-      } else if (fullFileName.find(srcDir) != std::string::npos) {
-        sourceLink = fullFileName.substr(srcDir.length() + 1);
-      } else {
-        // fallback: add plain filename without any path
-        sourceLink = cmsys::SystemTools::GetFilenameName(fullFileName);
-      }
-      if (!sourceLink.empty()) {
-        ConvertToWindowsSlash(sourceLink);
-      }
-    }
+  ConfigToSettings toolSettings;
+  for (const auto& config : this->Configurations) {
+    toolSettings[config];
+  }
+
+  if (this->ProjectType == csproj && !this->InSourceBuild) {
+    toolHasSettings = true;
   }
   if (ext == "hlsl") {
     tool = "FXCompile";
     // Figure out the type of shader compiler to use.
-    if (const char* st = sf->GetProperty("VS_SHADER_TYPE")) {
-      shaderType = st;
-      toolHasSettings = true;
+    if (cmProp st = sf->GetProperty("VS_SHADER_TYPE")) {
+      for (const std::string& config : this->Configurations) {
+        toolSettings[config]["ShaderType"] = *st;
+      }
     }
     // Figure out which entry point to use if any
-    if (const char* se = sf->GetProperty("VS_SHADER_ENTRYPOINT")) {
-      shaderEntryPoint = se;
-      toolHasSettings = true;
+    if (cmProp se = sf->GetProperty("VS_SHADER_ENTRYPOINT")) {
+      for (const std::string& config : this->Configurations) {
+        toolSettings[config]["EntryPointName"] = *se;
+      }
     }
     // Figure out which shader model to use if any
-    if (const char* sm = sf->GetProperty("VS_SHADER_MODEL")) {
-      shaderModel = sm;
-      toolHasSettings = true;
+    if (cmProp sm = sf->GetProperty("VS_SHADER_MODEL")) {
+      for (const std::string& config : this->Configurations) {
+        toolSettings[config]["ShaderModel"] = *sm;
+      }
     }
     // Figure out which output header file to use if any
-    if (const char* ohf = sf->GetProperty("VS_SHADER_OUTPUT_HEADER_FILE")) {
-      outputHeaderFile = ohf;
-      toolHasSettings = true;
+    if (cmProp ohf = sf->GetProperty("VS_SHADER_OUTPUT_HEADER_FILE")) {
+      for (const std::string& config : this->Configurations) {
+        toolSettings[config]["HeaderFileOutput"] = *ohf;
+      }
     }
     // Figure out which variable name to use if any
-    if (const char* vn = sf->GetProperty("VS_SHADER_VARIABLE_NAME")) {
-      variableName = vn;
-      toolHasSettings = true;
+    if (cmProp vn = sf->GetProperty("VS_SHADER_VARIABLE_NAME")) {
+      for (const std::string& config : this->Configurations) {
+        toolSettings[config]["VariableName"] = *vn;
+      }
     }
     // Figure out if there's any additional flags to use
-    if (const char* saf = sf->GetProperty("VS_SHADER_FLAGS")) {
-      shaderAdditionalFlags = saf;
-      toolHasSettings = true;
+    if (cmProp saf = sf->GetProperty("VS_SHADER_FLAGS")) {
+      for (const std::string& config : this->Configurations) {
+        toolSettings[config]["AdditionalOptions"] = *saf;
+      }
     }
     // Figure out if debug information should be generated
-    if (const char* sed = sf->GetProperty("VS_SHADER_ENABLE_DEBUG")) {
-      shaderEnableDebug = sed;
-      toolHasSettings = true;
+    if (cmProp sed = sf->GetProperty("VS_SHADER_ENABLE_DEBUG")) {
+      cmGeneratorExpression ge;
+      std::unique_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(*sed);
+
+      for (const std::string& config : this->Configurations) {
+        std::string evaluated = cge->Evaluate(this->LocalGenerator, config);
+
+        if (!evaluated.empty()) {
+          toolSettings[config]["EnableDebuggingInformation"] =
+            cmIsOn(evaluated) ? "true" : "false";
+        }
+      }
     }
     // Figure out if optimizations should be disabled
-    if (const char* sdo = sf->GetProperty("VS_SHADER_DISABLE_OPTIMIZATIONS")) {
-      shaderDisableOptimizations = sdo;
-      toolHasSettings = true;
+    if (cmProp sdo = sf->GetProperty("VS_SHADER_DISABLE_OPTIMIZATIONS")) {
+      cmGeneratorExpression ge;
+      std::unique_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(*sdo);
+
+      for (const std::string& config : this->Configurations) {
+        std::string evaluated = cge->Evaluate(this->LocalGenerator, config);
+
+        if (!evaluated.empty()) {
+          toolSettings[config]["DisableOptimizations"] =
+            cmIsOn(evaluated) ? "true" : "false";
+        }
+      }
     }
-    if (const char* sofn = sf->GetProperty("VS_SHADER_OBJECT_FILE_NAME")) {
-      shaderObjectFileName = sofn;
-      toolHasSettings = true;
+    if (cmProp sofn = sf->GetProperty("VS_SHADER_OBJECT_FILE_NAME")) {
+      for (const std::string& config : this->Configurations) {
+        toolSettings[config]["ObjectFileOutput"] = *sofn;
+      }
     }
   } else if (ext == "jpg" || ext == "png") {
     tool = "Image";
@@ -1894,9 +1945,9 @@
   } else if (ext == "vsixmanifest") {
     subType = "Designer";
   }
-  if (const char* c = sf->GetProperty("VS_COPY_TO_OUT_DIR")) {
+  if (cmProp c = sf->GetProperty("VS_COPY_TO_OUT_DIR")) {
     tool = "Content";
-    copyToOutDir = c;
+    copyToOutDir = *c;
     toolHasSettings = true;
   }
   if (sf->GetPropertyAsBool("VS_INCLUDE_IN_VSIX")) {
@@ -1923,32 +1974,79 @@
     }
   }
 
-  const char* toolOverride = sf->GetProperty("VS_TOOL_OVERRIDE");
-  if (toolOverride && *toolOverride) {
-    tool = toolOverride;
+  cmProp toolOverride = sf->GetProperty("VS_TOOL_OVERRIDE");
+  if (cmNonempty(toolOverride)) {
+    tool = toolOverride->c_str();
   }
 
   std::string deployContent;
   std::string deployLocation;
   if (this->GlobalGenerator->TargetsWindowsPhone() ||
       this->GlobalGenerator->TargetsWindowsStore()) {
-    const char* content = sf->GetProperty("VS_DEPLOYMENT_CONTENT");
-    if (content && *content) {
+    cmProp content = sf->GetProperty("VS_DEPLOYMENT_CONTENT");
+    if (cmNonempty(content)) {
       toolHasSettings = true;
-      deployContent = content;
+      deployContent = *content;
 
-      const char* location = sf->GetProperty("VS_DEPLOYMENT_LOCATION");
-      if (location && *location) {
-        deployLocation = location;
+      cmProp location = sf->GetProperty("VS_DEPLOYMENT_LOCATION");
+      if (cmNonempty(location)) {
+        deployLocation = *location;
       }
     }
   }
 
+  if (ParsedToolTargetSettings.find(tool) == ParsedToolTargetSettings.end()) {
+    cmProp toolTargetProperty = this->GeneratorTarget->Target->GetProperty(
+      "VS_SOURCE_SETTINGS_" + std::string(tool));
+    ConfigToSettings toolTargetSettings;
+    if (toolTargetProperty) {
+      ParseSettingsProperty(*toolTargetProperty, toolTargetSettings);
+    }
+
+    ParsedToolTargetSettings[tool] = toolTargetSettings;
+  }
+
+  for (const auto& configToSetting : ParsedToolTargetSettings[tool]) {
+    for (const auto& setting : configToSetting.second) {
+      toolSettings[configToSetting.first][setting.first] = setting.second;
+    }
+  }
+
+  if (cmProp p = sf->GetProperty("VS_SETTINGS")) {
+    ParseSettingsProperty(*p, toolSettings);
+  }
+
+  if (!toolSettings.empty()) {
+    toolHasSettings = true;
+  }
+
   Elem e2(e1, tool);
   this->WriteSource(e2, sf);
   if (toolHasSettings) {
     e2.SetHasElements();
 
+    std::vector<std::string> writtenSettings;
+    for (const auto& configSettings : toolSettings) {
+      for (const auto& setting : configSettings.second) {
+
+        if (std::find(writtenSettings.begin(), writtenSettings.end(),
+                      setting.first) != writtenSettings.end()) {
+          continue;
+        }
+
+        if (PropertyIsSameInAllConfigs(toolSettings, setting.first)) {
+          e2.Element(setting.first, setting.second);
+          writtenSettings.push_back(setting.first);
+        } else {
+          e2.WritePlatformConfigTag(setting.first,
+                                    "'$(Configuration)|$(Platform)'=='" +
+                                      configSettings.first + "|" +
+                                      this->Platform + "'",
+                                    setting.second);
+        }
+      }
+    }
+
     if (!deployContent.empty()) {
       cmGeneratorExpression ge;
       std::unique_ptr<cmCompiledGeneratorExpression> cge =
@@ -1974,82 +2072,13 @@
         }
       }
     }
-    if (!shaderType.empty()) {
-      e2.Element("ShaderType", shaderType);
-    }
-    if (!shaderEntryPoint.empty()) {
-      e2.Element("EntryPointName", shaderEntryPoint);
-    }
-    if (!shaderModel.empty()) {
-      e2.Element("ShaderModel", shaderModel);
-    }
-    if (!outputHeaderFile.empty()) {
-      for (size_t i = 0; i != this->Configurations.size(); ++i) {
-        e2.WritePlatformConfigTag("HeaderFileOutput",
-                                  "'$(Configuration)|$(Platform)'=='" +
-                                    this->Configurations[i] + "|" +
-                                    this->Platform + "'",
-                                  outputHeaderFile);
-      }
-    }
-    if (!variableName.empty()) {
-      for (size_t i = 0; i != this->Configurations.size(); ++i) {
-        e2.WritePlatformConfigTag("VariableName",
-                                  "'$(Configuration)|$(Platform)'=='" +
-                                    this->Configurations[i] + "|" +
-                                    this->Platform + "'",
-                                  variableName);
-      }
-    }
-    if (!shaderEnableDebug.empty()) {
-      cmGeneratorExpression ge;
-      std::unique_ptr<cmCompiledGeneratorExpression> cge =
-        ge.Parse(shaderEnableDebug);
 
-      for (size_t i = 0; i != this->Configurations.size(); ++i) {
-        const std::string& enableDebug =
-          cge->Evaluate(this->LocalGenerator, this->Configurations[i]);
-        if (!enableDebug.empty()) {
-          e2.WritePlatformConfigTag("EnableDebuggingInformation",
-                                    "'$(Configuration)|$(Platform)'=='" +
-                                      this->Configurations[i] + "|" +
-                                      this->Platform + "'",
-                                    cmIsOn(enableDebug) ? "true" : "false");
-        }
-      }
-    }
-    if (!shaderDisableOptimizations.empty()) {
-      cmGeneratorExpression ge;
-      std::unique_ptr<cmCompiledGeneratorExpression> cge =
-        ge.Parse(shaderDisableOptimizations);
-
-      for (size_t i = 0; i != this->Configurations.size(); ++i) {
-        const std::string& disableOptimizations =
-          cge->Evaluate(this->LocalGenerator, this->Configurations[i]);
-        if (!disableOptimizations.empty()) {
-          e2.WritePlatformConfigTag(
-            "DisableOptimizations",
-            "'$(Configuration)|$(Platform)'=='" + this->Configurations[i] +
-              "|" + this->Platform + "'",
-            (cmIsOn(disableOptimizations) ? "true" : "false"));
-        }
-      }
-    }
-    if (!shaderObjectFileName.empty()) {
-      e2.Element("ObjectFileOutput", shaderObjectFileName);
-    }
-    if (!shaderAdditionalFlags.empty()) {
-      e2.Element("AdditionalOptions", shaderAdditionalFlags);
-    }
     if (!settingsGenerator.empty()) {
       e2.Element("Generator", settingsGenerator);
     }
     if (!settingsLastGenOutput.empty()) {
       e2.Element("LastGenOutput", settingsLastGenOutput);
     }
-    if (!sourceLink.empty()) {
-      e2.Element("Link", sourceLink);
-    }
     if (!subType.empty()) {
       e2.Element("SubType", subType);
     }
@@ -2102,13 +2131,27 @@
   ConvertToWindowsSlash(sourceFile);
   e2.Attribute("Include", sourceFile);
 
+  if (this->ProjectType == csproj && !this->InSourceBuild) {
+    // For out of source projects we have to provide a link (if not specified
+    // via property) for every source file (besides .cs files) otherwise they
+    // will not be visible in VS at all.
+    // First we check if the file is in a source group, then we check if the
+    // file path is relative to current source- or binary-dir, otherwise it is
+    // added with the plain filename without any path. This means the file will
+    // show up at root-level of the csproj (where CMakeLists.txt etc. are).
+    std::string link = this->GetCSharpSourceLink(sf);
+    if (link.empty())
+      link = cmsys::SystemTools::GetFilenameName(sf->GetFullPath());
+    e2.Element("Link", link);
+  }
+
   ToolSource toolSource = { sf, forceRelative };
   this->Tools[e2.Tag].push_back(toolSource);
 }
 
 void cmVisualStudio10TargetGenerator::WriteAllSources(Elem& e0)
 {
-  if (this->GeneratorTarget->GetType() > cmStateEnums::UTILITY) {
+  if (this->GeneratorTarget->GetType() == cmStateEnums::GLOBAL_TARGET) {
     return;
   }
 
@@ -2202,10 +2245,10 @@
         }
       } break;
       case cmGeneratorTarget::SourceKindResx:
-        // Handled elsewhere.
+        this->ResxObjs.push_back(si.Source);
         break;
       case cmGeneratorTarget::SourceKindXaml:
-        // Handled elsewhere.
+        this->XamlObjs.push_back(si.Source);
         break;
     }
 
@@ -2245,11 +2288,11 @@
           e2.Attribute("CustomUnityFile", "true");
 
           std::string unityDir = cmSystemTools::GetFilenamePath(
-            si.Source->GetProperty("UNITY_SOURCE_FILE"));
+            *si.Source->GetProperty("UNITY_SOURCE_FILE"));
           e2.Attribute("UnityFilesDirectory", unityDir);
         } else {
           // Visual Studio versions prior to 2017 15.8 do not know about unity
-          // builds, thus we exclude the files alredy part of unity sources.
+          // builds, thus we exclude the files already part of unity sources.
           if (!si.Source->GetPropertyAsBool("SKIP_UNITY_BUILD_INCLUSION")) {
             exclude_configs = si.Configs;
           }
@@ -2290,41 +2333,36 @@
   bool configDependentDefines = false;
   std::string includes;
   bool configDependentIncludes = false;
-  if (const char* cflags = sf.GetProperty("COMPILE_FLAGS")) {
+  if (cmProp cflags = sf.GetProperty("COMPILE_FLAGS")) {
     configDependentFlags =
-      cmGeneratorExpression::Find(cflags) != std::string::npos;
-    flags += cflags;
+      cmGeneratorExpression::Find(*cflags) != std::string::npos;
+    flags += *cflags;
   }
-  if (const char* coptions = sf.GetProperty("COMPILE_OPTIONS")) {
+  if (cmProp coptions = sf.GetProperty("COMPILE_OPTIONS")) {
     configDependentOptions =
-      cmGeneratorExpression::Find(coptions) != std::string::npos;
-    options += coptions;
+      cmGeneratorExpression::Find(*coptions) != std::string::npos;
+    options += *coptions;
   }
-  if (const char* cdefs = sf.GetProperty("COMPILE_DEFINITIONS")) {
+  if (cmProp cdefs = sf.GetProperty("COMPILE_DEFINITIONS")) {
     configDependentDefines =
-      cmGeneratorExpression::Find(cdefs) != std::string::npos;
-    defines += cdefs;
+      cmGeneratorExpression::Find(*cdefs) != std::string::npos;
+    defines += *cdefs;
   }
-  if (const char* cincludes = sf.GetProperty("INCLUDE_DIRECTORIES")) {
+  if (cmProp cincludes = sf.GetProperty("INCLUDE_DIRECTORIES")) {
     configDependentIncludes =
-      cmGeneratorExpression::Find(cincludes) != std::string::npos;
-    includes += cincludes;
+      cmGeneratorExpression::Find(*cincludes) != std::string::npos;
+    includes += *cincludes;
   }
-  std::string lang =
-    this->GlobalGenerator->GetLanguageFromExtension(sf.GetExtension().c_str());
-  std::string sourceLang = this->LocalGenerator->GetSourceFileLanguage(sf);
-  const std::string& linkLanguage =
-    this->GeneratorTarget->GetLinkerLanguage("");
-  bool needForceLang = false;
-  // source file does not match its extension language
-  if (lang != sourceLang) {
-    needForceLang = true;
-    lang = sourceLang;
-  }
-  // if the source file does not match the linker language
-  // then force c or c++
+
+  // Force language if the file extension does not match.
+  // Note that MSVC treats the upper-case '.C' extension as C and not C++.
+  std::string const ext = sf.GetExtension();
+  std::string const extLang = ext == "C"
+    ? "C"
+    : this->GlobalGenerator->GetLanguageFromExtension(ext.c_str());
+  std::string lang = this->LocalGenerator->GetSourceFileLanguage(sf);
   const char* compileAs = 0;
-  if (needForceLang || (linkLanguage != lang)) {
+  if (lang != extLang) {
     if (lang == "CXX") {
       // force a C++ file type
       compileAs = "CompileAsCpp";
@@ -2333,6 +2371,7 @@
       compileAs = "CompileAsC";
     }
   }
+
   bool noWinRT = this->TargetCompileAsWinRT && lang == "C";
   // for the first time we need a new line if there is something
   // produced here.
@@ -2347,13 +2386,13 @@
     std::string configUpper = cmSystemTools::UpperCase(config);
     std::string configDefines = defines;
     std::string defPropName = cmStrCat("COMPILE_DEFINITIONS_", configUpper);
-    if (const char* ccdefs = sf.GetProperty(defPropName)) {
+    if (cmProp ccdefs = sf.GetProperty(defPropName)) {
       if (!configDefines.empty()) {
         configDefines += ";";
       }
       configDependentDefines |=
-        cmGeneratorExpression::Find(ccdefs) != std::string::npos;
-      configDefines += ccdefs;
+        cmGeneratorExpression::Find(*ccdefs) != std::string::npos;
+      configDefines += *ccdefs;
     }
 
     // Add precompile headers compile options.
@@ -2454,19 +2493,13 @@
   }
   if (this->IsXamlSource(source->GetFullPath())) {
     const std::string& fileName = source->GetFullPath();
-    std::string xamlFileName = fileName.substr(0, fileName.find_last_of("."));
-    e2.Element("DependentUpon", xamlFileName);
+    e2.Element("DependentUpon",
+               fileName.substr(0, fileName.find_last_of(".")));
   }
   if (this->ProjectType == csproj) {
     std::string f = source->GetFullPath();
     using CsPropMap = std::map<std::string, std::string>;
     CsPropMap sourceFileTags;
-    // set <Link> tag if necessary
-    std::string link;
-    this->GetCSharpSourceLink(source, link);
-    if (!link.empty()) {
-      sourceFileTags["Link"] = link;
-    }
     this->GetCSharpSourceProperties(&sf, sourceFileTags);
     // write source file specific tags
     if (!sourceFileTags.empty()) {
@@ -2504,34 +2537,34 @@
     const std::string cond = this->CalcCondition(config);
 
     if (ttype <= cmStateEnums::UTILITY) {
-      if (const char* workingDir = this->GeneratorTarget->GetProperty(
+      if (cmProp workingDir = this->GeneratorTarget->GetProperty(
             "VS_DEBUGGER_WORKING_DIRECTORY")) {
         std::string genWorkingDir = cmGeneratorExpression::Evaluate(
-          workingDir, this->LocalGenerator, config);
+          *workingDir, this->LocalGenerator, config);
         e1.WritePlatformConfigTag("LocalDebuggerWorkingDirectory", cond,
                                   genWorkingDir);
       }
 
-      if (const char* environment =
+      if (cmProp environment =
             this->GeneratorTarget->GetProperty("VS_DEBUGGER_ENVIRONMENT")) {
         std::string genEnvironment = cmGeneratorExpression::Evaluate(
-          environment, this->LocalGenerator, config);
+          *environment, this->LocalGenerator, config);
         e1.WritePlatformConfigTag("LocalDebuggerEnvironment", cond,
                                   genEnvironment);
       }
 
-      if (const char* debuggerCommand =
+      if (cmProp debuggerCommand =
             this->GeneratorTarget->GetProperty("VS_DEBUGGER_COMMAND")) {
         std::string genDebuggerCommand = cmGeneratorExpression::Evaluate(
-          debuggerCommand, this->LocalGenerator, config);
+          *debuggerCommand, this->LocalGenerator, config);
         e1.WritePlatformConfigTag("LocalDebuggerCommand", cond,
                                   genDebuggerCommand);
       }
 
-      if (const char* commandArguments = this->GeneratorTarget->GetProperty(
+      if (cmProp commandArguments = this->GeneratorTarget->GetProperty(
             "VS_DEBUGGER_COMMAND_ARGUMENTS")) {
         std::string genCommandArguments = cmGeneratorExpression::Evaluate(
-          commandArguments, this->LocalGenerator, config);
+          *commandArguments, this->LocalGenerator, config);
         e1.WritePlatformConfigTag("LocalDebuggerCommandArguments", cond,
                                   genCommandArguments);
       }
@@ -2716,7 +2749,7 @@
   std::string langForClCompile;
   if (this->ProjectType == csproj) {
     langForClCompile = "CSharp";
-  } else if (cmContains(clLangs, linkLanguage)) {
+  } else if (cm::contains(clLangs, linkLanguage)) {
     langForClCompile = linkLanguage;
   } else {
     std::set<std::string> languages;
@@ -2735,13 +2768,6 @@
     this->LocalGenerator->AddCompileOptions(flags, this->GeneratorTarget,
                                             langForClCompile, configName);
   }
-  // set the correct language
-  if (linkLanguage == "C") {
-    clOptions.AddFlag("CompileAs", "CompileAsC");
-  }
-  if (linkLanguage == "CXX") {
-    clOptions.AddFlag("CompileAs", "CompileAsCpp");
-  }
 
   // Put the IPO enabled configurations into a set.
   if (this->GeneratorTarget->IsIPOEnabled(linkLanguage, configName)) {
@@ -2791,9 +2817,9 @@
         this->Makefile->IssueMessage(MessageType::WARNING, message);
       }
     }
-    if (auto* clr =
+    if (cmProp clr =
           this->GeneratorTarget->GetProperty("COMMON_LANGUAGE_RUNTIME")) {
-      std::string clrString = clr;
+      std::string clrString = *clr;
       if (!clrString.empty()) {
         clrString = ":" + clrString;
       }
@@ -2892,6 +2918,12 @@
     clOptions.RemoveFlag("SpectreMitigation");
   }
 
+  // Remove any target-wide -TC or -TP flag added by the project.
+  // Such flags are unnecessary and break our model of language selection.
+  if (langForClCompile == "C" || langForClCompile == "CXX") {
+    clOptions.RemoveFlag("CompileAs");
+  }
+
   this->ClOptions[configName] = std::move(pOptions);
   return true;
 }
@@ -2911,13 +2943,15 @@
   oh.OutputPreprocessorDefinitions(this->LangForClCompile);
 
   if (this->NsightTegra) {
-    if (const char* processMax =
+    if (cmProp processMax =
           this->GeneratorTarget->GetProperty("ANDROID_PROCESS_MAX")) {
-      e2.Element("ProcessMax", processMax);
+      e2.Element("ProcessMax", *processMax);
     }
   }
 
-  if (this->MSTools) {
+  if (this->Android) {
+    e2.Element("ObjectFileName", "$(IntDir)%(filename).o");
+  } else if (this->MSTools) {
     cmsys::RegularExpression clangToolset("v[0-9]+_clang_.*");
     const char* toolset = this->GlobalGenerator->GetPlatformToolset();
     if (toolset && clangToolset.find(toolset)) {
@@ -3142,6 +3176,17 @@
   cudaOptions.AddIncludes(this->GetIncludes(configName, "CUDA"));
   cudaOptions.AddFlag("UseHostInclude", "false");
 
+  // Add runtime library selection flag.
+  std::string const& cudaRuntime =
+    this->GeneratorTarget->GetRuntimeLinkLibrary("CUDA", configName);
+  if (cudaRuntime == "STATIC") {
+    cudaOptions.AddFlag("CudaRuntime", "Static");
+  } else if (cudaRuntime == "SHARED") {
+    cudaOptions.AddFlag("CudaRuntime", "Shared");
+  } else if (cudaRuntime == "NONE") {
+    cudaOptions.AddFlag("CudaRuntime", "None");
+  }
+
   this->CudaOptions[configName] = std::move(pOptions);
   return true;
 }
@@ -3182,6 +3227,8 @@
     this->LocalGenerator, Options::CudaCompiler, gg->GetCudaFlagTable());
   Options& cudaLinkOptions = *pOptions;
 
+  cmGeneratorTarget::DeviceLinkSetter setter(*this->GeneratorTarget);
+
   // Determine if we need to do a device link
   const bool doDeviceLinking = requireDeviceLinking(
     *this->GeneratorTarget, *this->LocalGenerator, configName);
@@ -3189,12 +3236,20 @@
   cudaLinkOptions.AddFlag("PerformDeviceLink",
                           doDeviceLinking ? "true" : "false");
 
-  // Suppress deprecation warnings for default GPU targets during device link.
-  if (cmSystemTools::VersionCompareGreaterEq(
-        this->GlobalGenerator->GetPlatformToolsetCudaString(), "8.0")) {
-    cudaLinkOptions.AppendFlagString("AdditionalOptions",
-                                     "-Wno-deprecated-gpu-targets");
-  }
+  // Add extra flags for device linking
+  cudaLinkOptions.AppendFlagString(
+    "AdditionalOptions",
+    this->Makefile->GetSafeDefinition("_CMAKE_CUDA_EXTRA_FLAGS"));
+  cudaLinkOptions.AppendFlagString(
+    "AdditionalOptions",
+    this->Makefile->GetSafeDefinition("_CMAKE_CUDA_EXTRA_DEVICE_LINK_FLAGS"));
+
+  std::vector<std::string> linkOpts;
+  std::string linkFlags;
+  this->GeneratorTarget->GetLinkOptions(linkOpts, configName, "CUDA");
+  // LINK_OPTIONS are escaped.
+  this->LocalGenerator->AppendCompileOptions(linkFlags, linkOpts);
+  cudaLinkOptions.AppendFlagString("AdditionalOptions", linkFlags);
 
   // For static libraries that have device linking enabled compute
   // the  libraries
@@ -3412,9 +3467,8 @@
     this->GeneratorTarget->GetLinkClosure(config)->LinkerLanguage;
 
   std::string libflags;
-  this->LocalGenerator->GetStaticLibraryFlags(
-    libflags, cmSystemTools::UpperCase(config), linkLanguage,
-    this->GeneratorTarget);
+  this->LocalGenerator->GetStaticLibraryFlags(libflags, config, linkLanguage,
+                                              this->GeneratorTarget);
   if (!libflags.empty()) {
     Elem e2(e1, "Lib");
     cmGlobalVisualStudio10Generator* gg = this->GlobalGenerator;
@@ -3449,7 +3503,7 @@
   std::vector<cmSourceFile const*> manifest_srcs;
   this->GeneratorTarget->GetManifests(manifest_srcs, config);
 
-  const char* dpiAware = this->GeneratorTarget->GetProperty("VS_DPI_AWARE");
+  cmProp dpiAware = this->GeneratorTarget->GetProperty("VS_DPI_AWARE");
 
   if (!manifest_srcs.empty() || dpiAware) {
     Elem e2(e1, "Manifest");
@@ -3463,15 +3517,14 @@
       e2.Element("AdditionalManifestFiles", oss.str());
     }
     if (dpiAware) {
-      if (!strcmp(dpiAware, "PerMonitor")) {
+      if (*dpiAware == "PerMonitor") {
         e2.Element("EnableDpiAwareness", "PerMonitorHighDPIAware");
-      } else if (cmIsOn(dpiAware)) {
+      } else if (cmIsOn(*dpiAware)) {
         e2.Element("EnableDpiAwareness", "true");
-      } else if (cmIsOff(dpiAware)) {
+      } else if (cmIsOff(*dpiAware)) {
         e2.Element("EnableDpiAwareness", "false");
       } else {
-        cmSystemTools::Error("Bad parameter for VS_DPI_AWARE: " +
-                             std::string(dpiAware));
+        cmSystemTools::Error("Bad parameter for VS_DPI_AWARE: " + *dpiAware);
       }
     }
   }
@@ -3484,12 +3537,12 @@
   // its location as the root source directory.
   std::string rootDir = this->LocalGenerator->GetCurrentSourceDirectory();
   {
-    std::vector<cmSourceFile const*> extraSources;
-    this->GeneratorTarget->GetExtraSources(extraSources, "");
-    for (cmSourceFile const* si : extraSources) {
-      if ("androidmanifest.xml" ==
-          cmSystemTools::LowerCase(si->GetLocation().GetName())) {
-        rootDir = si->GetLocation().GetDirectory();
+    for (cmGeneratorTarget::AllConfigSource const& source :
+         this->GeneratorTarget->GetAllConfigSources()) {
+      if (source.Kind == cmGeneratorTarget::SourceKindExtra &&
+          "androidmanifest.xml" ==
+            cmSystemTools::LowerCase(source.Source->GetLocation().GetName())) {
+        rootDir = source.Source->GetLocation().GetDirectory();
         break;
       }
     }
@@ -3511,51 +3564,51 @@
     e2.Element("EnableProGuard", "true");
   }
 
-  if (const char* proGuardConfigLocation =
+  if (cmProp proGuardConfigLocation =
         this->GeneratorTarget->GetProperty("ANDROID_PROGUARD_CONFIG_PATH")) {
-    e2.Element("ProGuardConfigLocation", proGuardConfigLocation);
+    e2.Element("ProGuardConfigLocation", *proGuardConfigLocation);
   }
 
-  if (const char* securePropertiesLocation =
+  if (cmProp securePropertiesLocation =
         this->GeneratorTarget->GetProperty("ANDROID_SECURE_PROPS_PATH")) {
-    e2.Element("SecurePropertiesLocation", securePropertiesLocation);
+    e2.Element("SecurePropertiesLocation", *securePropertiesLocation);
   }
 
-  if (const char* nativeLibDirectoriesExpression =
+  if (cmProp nativeLibDirectoriesExpression =
         this->GeneratorTarget->GetProperty("ANDROID_NATIVE_LIB_DIRECTORIES")) {
     std::string nativeLibDirs = cmGeneratorExpression::Evaluate(
-      nativeLibDirectoriesExpression, this->LocalGenerator, configName);
+      *nativeLibDirectoriesExpression, this->LocalGenerator, configName);
     e2.Element("NativeLibDirectories", nativeLibDirs);
   }
 
-  if (const char* nativeLibDependenciesExpression =
+  if (cmProp nativeLibDependenciesExpression =
         this->GeneratorTarget->GetProperty(
           "ANDROID_NATIVE_LIB_DEPENDENCIES")) {
     std::string nativeLibDeps = cmGeneratorExpression::Evaluate(
-      nativeLibDependenciesExpression, this->LocalGenerator, configName);
+      *nativeLibDependenciesExpression, this->LocalGenerator, configName);
     e2.Element("NativeLibDependencies", nativeLibDeps);
   }
 
-  if (const char* javaSourceDir =
+  if (cmProp javaSourceDir =
         this->GeneratorTarget->GetProperty("ANDROID_JAVA_SOURCE_DIR")) {
-    e2.Element("JavaSourceDir", javaSourceDir);
+    e2.Element("JavaSourceDir", *javaSourceDir);
   }
 
-  if (const char* jarDirectoriesExpression =
+  if (cmProp jarDirectoriesExpression =
         this->GeneratorTarget->GetProperty("ANDROID_JAR_DIRECTORIES")) {
     std::string jarDirectories = cmGeneratorExpression::Evaluate(
-      jarDirectoriesExpression, this->LocalGenerator, configName);
+      *jarDirectoriesExpression, this->LocalGenerator, configName);
     e2.Element("JarDirectories", jarDirectories);
   }
 
-  if (const char* jarDeps =
+  if (cmProp jarDeps =
         this->GeneratorTarget->GetProperty("ANDROID_JAR_DEPENDENCIES")) {
-    e2.Element("JarDependencies", jarDeps);
+    e2.Element("JarDependencies", *jarDeps);
   }
 
-  if (const char* assetsDirectories =
+  if (cmProp assetsDirectories =
         this->GeneratorTarget->GetProperty("ANDROID_ASSETS_DIRECTORIES")) {
-    e2.Element("AssetsDirectories", assetsDirectories);
+    e2.Element("AssetsDirectories", *assetsDirectories);
   }
 
   {
@@ -3564,10 +3617,10 @@
     e2.Element("AndroidManifestLocation", manifest_xml);
   }
 
-  if (const char* antAdditionalOptions =
+  if (cmProp antAdditionalOptions =
         this->GeneratorTarget->GetProperty("ANDROID_ANT_ADDITIONAL_OPTIONS")) {
     e2.Element("AdditionalOptions",
-               std::string(antAdditionalOptions) + " %(AdditionalOptions)");
+               *antAdditionalOptions + " %(AdditionalOptions)");
   }
 }
 
@@ -3619,17 +3672,15 @@
   std::string linkFlagVar = linkFlagVarBase + "_" + CONFIG;
   flags += " ";
   flags += this->Makefile->GetRequiredDefinition(linkFlagVar);
-  const char* targetLinkFlags =
-    this->GeneratorTarget->GetProperty("LINK_FLAGS");
+  cmProp targetLinkFlags = this->GeneratorTarget->GetProperty("LINK_FLAGS");
   if (targetLinkFlags) {
     flags += " ";
-    flags += targetLinkFlags;
+    flags += *targetLinkFlags;
   }
   std::string flagsProp = cmStrCat("LINK_FLAGS_", CONFIG);
-  if (const char* flagsConfig =
-        this->GeneratorTarget->GetProperty(flagsProp)) {
+  if (cmProp flagsConfig = this->GeneratorTarget->GetProperty(flagsProp)) {
     flags += " ";
-    flags += flagsConfig;
+    flags += *flagsConfig;
   }
 
   std::vector<std::string> opts;
@@ -3650,10 +3701,6 @@
   std::vector<std::string> libVec;
   std::vector<std::string> vsTargetVec;
   this->AddLibraries(cli, libVec, vsTargetVec, config);
-  if (cmContains(linkClosure->Languages, "CUDA") &&
-      this->CudaOptions[config] != nullptr) {
-    this->CudaOptions[config]->FixCudaRuntime(this->GeneratorTarget);
-  }
   std::string standardLibsVar =
     cmStrCat("CMAKE_", linkLanguage, "_STANDARD_LIBRARIES");
   std::string const& libs = this->Makefile->GetSafeDefinition(standardLibsVar);
@@ -3924,7 +3971,7 @@
 {
   for (TargetsFileAndConfigs& i : this->TargetsFileAndConfigsVec) {
     if (cmSystemTools::ComparePath(targetsFile, i.File)) {
-      if (!cmContains(i.Configs, config)) {
+      if (!cm::contains(i.Configs, config)) {
         i.Configs.push_back(config);
       }
       return;
@@ -4010,8 +4057,7 @@
     //    output manifest flags  <Manifest></Manifest>
     this->WriteManifestOptions(e1, c);
     if (this->NsightTegra &&
-        this->GeneratorTarget->GetType() == cmStateEnums::EXECUTABLE &&
-        this->GeneratorTarget->GetPropertyAsBool("ANDROID_GUI")) {
+        this->GeneratorTarget->Target->IsAndroidGuiExecutable()) {
       this->WriteAntBuildOptions(e1, c);
     }
   }
@@ -4052,6 +4098,7 @@
   std::string script;
   const char* pre = "";
   std::string comment;
+  bool stdPipesUTF8 = false;
   for (cmCustomCommand const& cc : commands) {
     cmCustomCommandGenerator ccg(cc, configName, lg);
     if (!ccg.HasOnlyEmptyCommandLines()) {
@@ -4060,11 +4107,16 @@
       script += pre;
       pre = "\n";
       script += lg->ConstructScript(ccg);
+
+      stdPipesUTF8 = stdPipesUTF8 || cc.GetStdPipesUTF8();
     }
   }
   comment = cmVS10EscapeComment(comment);
   if (this->ProjectType != csproj) {
     Elem e2(e1, name);
+    if (stdPipesUTF8) {
+      this->WriteStdOutEncodingUtf8(e2);
+    }
     e2.Element("Message", comment);
     e2.Element("Command", script);
   } else {
@@ -4091,7 +4143,7 @@
   Elem e1(e0, "ItemGroup");
   e1.SetHasElements();
   for (cmGeneratorTarget const* dt : depends) {
-    if (dt->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
+    if (!dt->IsInBuildSystem()) {
       continue;
     }
     // skip fortran targets as they can not be processed by MSBuild
@@ -4102,9 +4154,9 @@
     cmLocalGenerator* lg = dt->GetLocalGenerator();
     std::string name = dt->GetName();
     std::string path;
-    const char* p = dt->GetProperty("EXTERNAL_MSPROJECT");
+    cmProp p = dt->GetProperty("EXTERNAL_MSPROJECT");
     if (p) {
-      path = p;
+      path = *p;
     } else {
       path = cmStrCat(lg->GetCurrentBinaryDirectory(), '/', dt->GetName(),
                       computeProjectFileExtension(dt));
@@ -4120,7 +4172,9 @@
     }
 
     // Don't reference targets that don't produce any output.
-    if (dt->GetManagedType("") == cmGeneratorTarget::ManagedType::Undefined) {
+    if (this->Configurations.empty() ||
+        dt->GetManagedType(this->Configurations[0]) ==
+          cmGeneratorTarget::ManagedType::Undefined) {
       e2.Element("ReferenceOutputAssembly", "false");
       e2.Element("CopyToOutputDirectory", "Never");
     }
@@ -4132,17 +4186,17 @@
   // This only applies to Windows 10 apps
   if (this->GlobalGenerator->TargetsWindowsStore() &&
       cmHasLiteralPrefix(this->GlobalGenerator->GetSystemVersion(), "10.0")) {
-    const char* desktopExtensionsVersion =
+    cmProp desktopExtensionsVersion =
       this->GeneratorTarget->GetProperty("VS_DESKTOP_EXTENSIONS_VERSION");
     if (desktopExtensionsVersion) {
       this->WriteSinglePlatformExtension(e1, "WindowsDesktop",
-                                         desktopExtensionsVersion);
+                                         *desktopExtensionsVersion);
     }
-    const char* mobileExtensionsVersion =
+    cmProp mobileExtensionsVersion =
       this->GeneratorTarget->GetProperty("VS_MOBILE_EXTENSIONS_VERSION");
     if (mobileExtensionsVersion) {
       this->WriteSinglePlatformExtension(e1, "WindowsMobile",
-                                         mobileExtensionsVersion);
+                                         *mobileExtensionsVersion);
     }
   }
 }
@@ -4167,9 +4221,9 @@
 {
   std::vector<std::string> sdkReferences;
   std::unique_ptr<Elem> spe1;
-  if (const char* vsSDKReferences =
+  if (cmProp vsSDKReferences =
         this->GeneratorTarget->GetProperty("VS_SDK_REFERENCES")) {
-    cmExpandList(vsSDKReferences, sdkReferences);
+    cmExpandList(*vsSDKReferences, sdkReferences);
     spe1 = cm::make_unique<Elem>(e0, "ItemGroup");
     for (std::string const& ri : sdkReferences) {
       Elem(*spe1, "SDKReference").Attribute("Include", ri);
@@ -4179,11 +4233,11 @@
   // This only applies to Windows 10 apps
   if (this->GlobalGenerator->TargetsWindowsStore() &&
       cmHasLiteralPrefix(this->GlobalGenerator->GetSystemVersion(), "10.0")) {
-    const char* desktopExtensionsVersion =
+    cmProp desktopExtensionsVersion =
       this->GeneratorTarget->GetProperty("VS_DESKTOP_EXTENSIONS_VERSION");
-    const char* mobileExtensionsVersion =
+    cmProp mobileExtensionsVersion =
       this->GeneratorTarget->GetProperty("VS_MOBILE_EXTENSIONS_VERSION");
-    const char* iotExtensionsVersion =
+    cmProp iotExtensionsVersion =
       this->GeneratorTarget->GetProperty("VS_IOT_EXTENSIONS_VERSION");
 
     if (desktopExtensionsVersion || mobileExtensionsVersion ||
@@ -4193,15 +4247,15 @@
       }
       if (desktopExtensionsVersion) {
         this->WriteSingleSDKReference(*spe1, "WindowsDesktop",
-                                      desktopExtensionsVersion);
+                                      *desktopExtensionsVersion);
       }
       if (mobileExtensionsVersion) {
         this->WriteSingleSDKReference(*spe1, "WindowsMobile",
-                                      mobileExtensionsVersion);
+                                      *mobileExtensionsVersion);
       }
       if (iotExtensionsVersion) {
         this->WriteSingleSDKReference(*spe1, "WindowsIoT",
-                                      iotExtensionsVersion);
+                                      *iotExtensionsVersion);
       }
     }
   }
@@ -4221,12 +4275,13 @@
        this->GlobalGenerator->TargetsWindowsPhone()) &&
       (cmStateEnums::EXECUTABLE == this->GeneratorTarget->GetType())) {
     std::string pfxFile;
-    std::vector<cmSourceFile const*> certificates;
-    this->GeneratorTarget->GetCertificates(certificates, "");
-    for (cmSourceFile const* si : certificates) {
-      pfxFile = this->ConvertPath(si->GetFullPath(), false);
-      ConvertToWindowsSlash(pfxFile);
-      break;
+    for (cmGeneratorTarget::AllConfigSource const& source :
+         this->GeneratorTarget->GetAllConfigSources()) {
+      if (source.Kind == cmGeneratorTarget::SourceKindCertificate) {
+        pfxFile = this->ConvertPath(source.Source->GetFullPath(), false);
+        ConvertToWindowsSlash(pfxFile);
+        break;
+      }
     }
 
     if (this->IsMissingFiles &&
@@ -4272,28 +4327,61 @@
   }
 }
 
+void cmVisualStudio10TargetGenerator::ClassifyAllConfigSources()
+{
+  for (cmGeneratorTarget::AllConfigSource const& source :
+       this->GeneratorTarget->GetAllConfigSources()) {
+    this->ClassifyAllConfigSource(source);
+  }
+}
+
+void cmVisualStudio10TargetGenerator::ClassifyAllConfigSource(
+  cmGeneratorTarget::AllConfigSource const& acs)
+{
+  switch (acs.Kind) {
+    case cmGeneratorTarget::SourceKindResx: {
+      // Build and save the name of the corresponding .h file
+      // This relationship will be used later when building the project files.
+      // Both names would have been auto generated from Visual Studio
+      // where the user supplied the file name and Visual Studio
+      // appended the suffix.
+      std::string resx = acs.Source->ResolveFullPath();
+      std::string hFileName = resx.substr(0, resx.find_last_of('.')) + ".h";
+      this->ExpectedResxHeaders.insert(hFileName);
+    } break;
+    case cmGeneratorTarget::SourceKindXaml: {
+      // Build and save the name of the corresponding .h and .cpp file
+      // This relationship will be used later when building the project files.
+      // Both names would have been auto generated from Visual Studio
+      // where the user supplied the file name and Visual Studio
+      // appended the suffix.
+      std::string xaml = acs.Source->ResolveFullPath();
+      std::string hFileName = xaml + ".h";
+      std::string cppFileName = xaml + ".cpp";
+      this->ExpectedXamlHeaders.insert(hFileName);
+      this->ExpectedXamlSources.insert(cppFileName);
+    } break;
+    default:
+      break;
+  }
+}
+
 bool cmVisualStudio10TargetGenerator::IsResxHeader(
   const std::string& headerFile)
 {
-  std::set<std::string> expectedResxHeaders;
-  this->GeneratorTarget->GetExpectedResxHeaders(expectedResxHeaders, "");
-  return expectedResxHeaders.count(headerFile) > 0;
+  return this->ExpectedResxHeaders.count(headerFile) > 0;
 }
 
 bool cmVisualStudio10TargetGenerator::IsXamlHeader(
   const std::string& headerFile)
 {
-  std::set<std::string> expectedXamlHeaders;
-  this->GeneratorTarget->GetExpectedXamlHeaders(expectedXamlHeaders, "");
-  return expectedXamlHeaders.count(headerFile) > 0;
+  return this->ExpectedXamlHeaders.count(headerFile) > 0;
 }
 
 bool cmVisualStudio10TargetGenerator::IsXamlSource(
   const std::string& sourceFile)
 {
-  std::set<std::string> expectedXamlSources;
-  this->GeneratorTarget->GetExpectedXamlSources(expectedXamlSources, "");
-  return expectedXamlSources.count(sourceFile) > 0;
+  return this->ExpectedXamlSources.count(sourceFile) > 0;
 }
 
 void cmVisualStudio10TargetGenerator::WriteApplicationTypeSettings(Elem& e1)
@@ -4302,6 +4390,7 @@
   bool isAppContainer = false;
   bool const isWindowsPhone = this->GlobalGenerator->TargetsWindowsPhone();
   bool const isWindowsStore = this->GlobalGenerator->TargetsWindowsStore();
+  bool const isAndroid = this->GlobalGenerator->TargetsAndroid();
   std::string const& rev = this->GlobalGenerator->GetApplicationTypeRevision();
   if (isWindowsPhone || isWindowsStore) {
     e1.Element("ApplicationType",
@@ -4339,23 +4428,29 @@
                    this->Name + "_$(Configuration)_$(Platform).xap");
       }
     }
+  } else if (isAndroid) {
+    e1.Element("ApplicationType", "Android");
+    e1.Element("ApplicationTypeRevision",
+               gg->GetAndroidApplicationTypeRevision());
   }
   if (isAppContainer) {
     e1.Element("AppContainerApplication", "true");
-  } else if (this->Platform == "ARM64") {
-    e1.Element("WindowsSDKDesktopARM64Support", "true");
-  } else if (this->Platform == "ARM") {
-    e1.Element("WindowsSDKDesktopARMSupport", "true");
+  } else if (!isAndroid) {
+    if (this->Platform == "ARM64") {
+      e1.Element("WindowsSDKDesktopARM64Support", "true");
+    } else if (this->Platform == "ARM") {
+      e1.Element("WindowsSDKDesktopARMSupport", "true");
+    }
   }
   std::string const& targetPlatformVersion =
     gg->GetWindowsTargetPlatformVersion();
   if (!targetPlatformVersion.empty()) {
     e1.Element("WindowsTargetPlatformVersion", targetPlatformVersion);
   }
-  const char* targetPlatformMinVersion = this->GeneratorTarget->GetProperty(
+  cmProp targetPlatformMinVersion = this->GeneratorTarget->GetProperty(
     "VS_WINDOWS_TARGET_PLATFORM_MIN_VERSION");
   if (targetPlatformMinVersion) {
-    e1.Element("WindowsTargetPlatformMinVersion", targetPlatformMinVersion);
+    e1.Element("WindowsTargetPlatformMinVersion", *targetPlatformMinVersion);
   } else if (isWindowsStore && rev == "10.0") {
     // If the min version is not set, then use the TargetPlatformVersion
     if (!targetPlatformVersion.empty()) {
@@ -4374,39 +4469,38 @@
   // For Windows and Windows Phone executables, we will assume that if a
   // manifest is not present that we need to add all the necessary files
   if (this->GeneratorTarget->GetType() == cmStateEnums::EXECUTABLE) {
-    std::vector<cmSourceFile const*> manifestSources;
-    this->GeneratorTarget->GetAppManifest(manifestSources, "");
-    {
-      std::string const& v = this->GlobalGenerator->GetSystemVersion();
-      if (this->GlobalGenerator->TargetsWindowsPhone()) {
-        if (v == "8.0") {
-          // Look through the sources for WMAppManifest.xml
-          std::vector<cmSourceFile const*> extraSources;
-          this->GeneratorTarget->GetExtraSources(extraSources, "");
-          bool foundManifest = false;
-          for (cmSourceFile const* si : extraSources) {
-            // Need to do a lowercase comparison on the filename
-            if ("wmappmanifest.xml" ==
-                cmSystemTools::LowerCase(si->GetLocation().GetName())) {
-              foundManifest = true;
-              break;
-            }
-          }
-          if (!foundManifest) {
-            this->IsMissingFiles = true;
-          }
-        } else if (v == "8.1") {
-          if (manifestSources.empty()) {
-            this->IsMissingFiles = true;
+    std::vector<cmGeneratorTarget::AllConfigSource> manifestSources =
+      this->GeneratorTarget->GetAllConfigSources(
+        cmGeneratorTarget::SourceKindAppManifest);
+    std::string const& v = this->GlobalGenerator->GetSystemVersion();
+    if (this->GlobalGenerator->TargetsWindowsPhone()) {
+      if (v == "8.0") {
+        // Look through the sources for WMAppManifest.xml
+        bool foundManifest = false;
+        for (cmGeneratorTarget::AllConfigSource const& source :
+             this->GeneratorTarget->GetAllConfigSources()) {
+          if (source.Kind == cmGeneratorTarget::SourceKindExtra &&
+              "wmappmanifest.xml" ==
+                cmSystemTools::LowerCase(
+                  source.Source->GetLocation().GetName())) {
+            foundManifest = true;
+            break;
           }
         }
-      } else if (this->GlobalGenerator->TargetsWindowsStore()) {
+        if (!foundManifest) {
+          this->IsMissingFiles = true;
+        }
+      } else if (v == "8.1") {
         if (manifestSources.empty()) {
-          if (v == "8.0") {
-            this->IsMissingFiles = true;
-          } else if (v == "8.1" || cmHasLiteralPrefix(v, "10.0")) {
-            this->IsMissingFiles = true;
-          }
+          this->IsMissingFiles = true;
+        }
+      }
+    } else if (this->GlobalGenerator->TargetsWindowsStore()) {
+      if (manifestSources.empty()) {
+        if (v == "8.0") {
+          this->IsMissingFiles = true;
+        } else if (v == "8.1" || cmHasLiteralPrefix(v, "10.0")) {
+          this->IsMissingFiles = true;
         }
       }
     }
@@ -4845,11 +4939,11 @@
   if (this->ProjectType == csproj) {
     const cmPropertyMap& props = sf->GetProperties();
     for (const std::string& p : props.GetKeys()) {
-      static const std::string propNamePrefix = "VS_CSHARP_";
-      if (p.find(propNamePrefix) == 0) {
+      static const cm::string_view propNamePrefix = "VS_CSHARP_";
+      if (cmHasPrefix(p, propNamePrefix)) {
         std::string tagName = p.substr(propNamePrefix.length());
         if (!tagName.empty()) {
-          const std::string val = props.GetPropertyValue(p);
+          const std::string& val = *props.GetPropertyValue(p);
           if (!val.empty()) {
             tags[tagName] = val;
           } else {
@@ -4869,24 +4963,34 @@
   }
 }
 
-void cmVisualStudio10TargetGenerator::GetCSharpSourceLink(
-  cmSourceFile const* sf, std::string& link)
+std::string cmVisualStudio10TargetGenerator::GetCSharpSourceLink(
+  cmSourceFile const* source)
 {
-  std::string const& sourceFilePath = sf->GetFullPath();
-  std::string const& binaryDir = LocalGenerator->GetCurrentBinaryDirectory();
-
-  if (!cmSystemTools::IsSubDirectory(sourceFilePath, binaryDir)) {
-    const std::string& stripFromPath =
-      this->Makefile->GetCurrentSourceDirectory();
-    if (sourceFilePath.find(stripFromPath) == 0) {
-      if (const char* l = sf->GetProperty("VS_CSHARP_Link")) {
-        link = l;
-      } else {
-        link = sourceFilePath.substr(stripFromPath.length() + 1);
-      }
-      ConvertToWindowsSlash(link);
-    }
+  // For out of source files, we first check if a matching source group
+  // for this file exists, otherwise we check if the path relative to current
+  // source- or binary-dir is used within the link and return that
+  std::string link;
+  std::string const& fullFileName = source->GetFullPath();
+  std::string const& srcDir = this->Makefile->GetCurrentSourceDirectory();
+  std::string const& binDir = this->Makefile->GetCurrentBinaryDirectory();
+  // unfortunately we have to copy the source groups, because
+  // FindSourceGroup uses a regex which is modifying the group
+  std::vector<cmSourceGroup> sourceGroups = this->Makefile->GetSourceGroups();
+  cmSourceGroup* sourceGroup =
+    this->Makefile->FindSourceGroup(fullFileName, sourceGroups);
+  if (sourceGroup && !sourceGroup->GetFullName().empty()) {
+    link = sourceGroup->GetFullName() + "/" +
+      cmsys::SystemTools::GetFilenameName(fullFileName);
+  } else if (cmHasPrefix(fullFileName, srcDir)) {
+    link = fullFileName.substr(srcDir.length() + 1);
+  } else if (cmHasPrefix(fullFileName, binDir)) {
+    link = fullFileName.substr(binDir.length() + 1);
+  } else if (cmProp l = source->GetProperty("VS_CSHARP_Link")) {
+    link = *l;
   }
+
+  ConvertToWindowsSlash(link);
+  return link;
 }
 
 std::string cmVisualStudio10TargetGenerator::GetCMakeFilePath(
@@ -4899,3 +5003,10 @@
 
   return path;
 }
+
+void cmVisualStudio10TargetGenerator::WriteStdOutEncodingUtf8(Elem& e1)
+{
+  if (this->GlobalGenerator->IsStdOutEncodingSupported()) {
+    e1.Element("StdOutEncoding", "UTF-8");
+  }
+}
diff --git a/Source/cmVisualStudio10TargetGenerator.h b/Source/cmVisualStudio10TargetGenerator.h
index 30027c9..c54057a 100644
--- a/Source/cmVisualStudio10TargetGenerator.h
+++ b/Source/cmVisualStudio10TargetGenerator.h
@@ -10,12 +10,14 @@
 #include <memory>
 #include <set>
 #include <string>
+#include <unordered_map>
 #include <vector>
 
+#include "cmGeneratorTarget.h"
+
 class cmComputeLinkInformation;
 class cmCustomCommand;
 class cmGeneratedFileStream;
-class cmGeneratorTarget;
 class cmGlobalVisualStudio10Generator;
 class cmLocalVisualStudio10Generator;
 class cmMakefile;
@@ -68,13 +70,12 @@
   void WriteExtraSource(Elem& e1, cmSourceFile const* sf);
   void WriteNsightTegraConfigurationValues(Elem& e1,
                                            std::string const& config);
+  void WriteAndroidConfigurationValues(Elem& e1, std::string const& config);
   void WriteSource(Elem& e2, cmSourceFile const* sf);
   void WriteExcludeFromBuild(Elem& e2,
                              std::vector<size_t> const& exclude_configs);
   void WriteAllSources(Elem& e0);
   void WritePackageReferences(Elem& e0);
-  void WritePackageReference(Elem& e1, std::string const& ref,
-                             std::string const& version);
   void WriteDotNetReferences(Elem& e0);
   void WriteDotNetReference(Elem& e1, std::string const& ref,
                             std::string const& hint,
@@ -183,7 +184,9 @@
                                  std::map<std::string, std::string>& tags);
   void WriteCSharpSourceProperties(
     Elem& e2, const std::map<std::string, std::string>& tags);
-  void GetCSharpSourceLink(cmSourceFile const* sf, std::string& link);
+  std::string GetCSharpSourceLink(cmSourceFile const* source);
+
+  void WriteStdOutEncodingUtf8(Elem& e1);
 
 private:
   friend class cmVS10GeneratorOptions;
@@ -213,6 +216,7 @@
   bool MSTools;
   bool Managed;
   bool NsightTegra;
+  bool Android;
   unsigned int NsightTegraVersion[4];
   bool TargetCompileAsWinRT;
   std::set<std::string> IPOEnabledConfigurations;
@@ -236,6 +240,23 @@
 
   using ToolSourceMap = std::map<std::string, ToolSources>;
   ToolSourceMap Tools;
+
+  std::set<std::string> ExpectedResxHeaders;
+  std::set<std::string> ExpectedXamlHeaders;
+  std::set<std::string> ExpectedXamlSources;
+  std::vector<cmSourceFile const*> ResxObjs;
+  std::vector<cmSourceFile const*> XamlObjs;
+  void ClassifyAllConfigSources();
+  void ClassifyAllConfigSource(cmGeneratorTarget::AllConfigSource const& acs);
+
+  using ConfigToSettings =
+    std::unordered_map<std::string,
+                       std::unordered_map<std::string, std::string>>;
+  std::unordered_map<std::string, ConfigToSettings> ParsedToolTargetSettings;
+  bool PropertyIsSameInAllConfigs(const ConfigToSettings& toolSettings,
+                                  const std::string& propName);
+  void ParseSettingsProperty(const std::string& settingsPropertyValue,
+                             ConfigToSettings& toolSettings);
   std::string GetCMakeFilePath(const char* name) const;
 };
 
diff --git a/Source/cmVisualStudioGeneratorOptions.cxx b/Source/cmVisualStudioGeneratorOptions.cxx
index 4004b66..937b4ce 100644
--- a/Source/cmVisualStudioGeneratorOptions.cxx
+++ b/Source/cmVisualStudioGeneratorOptions.cxx
@@ -151,35 +151,6 @@
   return false;
 }
 
-void cmVisualStudioGeneratorOptions::FixCudaRuntime(cmGeneratorTarget* target)
-{
-  std::map<std::string, FlagValue>::const_iterator i =
-    this->FlagMap.find("CudaRuntime");
-  if (i == this->FlagMap.end()) {
-    // User didn't provide am override so get the property value
-    const char* runtimeLibraryValue =
-      target->GetProperty("CUDA_RUNTIME_LIBRARY");
-    if (runtimeLibraryValue) {
-      std::string cudaRuntime =
-        cmSystemTools::UpperCase(cmGeneratorExpression::Evaluate(
-          runtimeLibraryValue, this->LocalGenerator, this->Configuration,
-          target));
-      if (cudaRuntime == "STATIC") {
-        this->AddFlag("CudaRuntime", "Static");
-      }
-      if (cudaRuntime == "SHARED") {
-        this->AddFlag("CudaRuntime", "Shared");
-      }
-      if (cudaRuntime == "NONE") {
-        this->AddFlag("CudaRuntime", "None");
-      }
-    } else {
-      // nvcc default is static
-      this->AddFlag("CudaRuntime", "Static");
-    }
-  }
-}
-
 void cmVisualStudioGeneratorOptions::FixCudaCodeGeneration()
 {
   // Extract temporary values stored by our flag table.
diff --git a/Source/cmVisualStudioGeneratorOptions.h b/Source/cmVisualStudioGeneratorOptions.h
index b335694..f9b50a7 100644
--- a/Source/cmVisualStudioGeneratorOptions.h
+++ b/Source/cmVisualStudioGeneratorOptions.h
@@ -63,7 +63,6 @@
   bool UsingSBCS() const;
 
   void FixCudaCodeGeneration();
-  void FixCudaRuntime(cmGeneratorTarget* target);
 
   void FixManifestUACFlags();
 
diff --git a/Source/cmVisualStudioSlnParser.cxx b/Source/cmVisualStudioSlnParser.cxx
index 4533e9b..d7822b1 100644
--- a/Source/cmVisualStudioSlnParser.cxx
+++ b/Source/cmVisualStudioSlnParser.cxx
@@ -517,7 +517,7 @@
                                                  State& state)
 {
   size_t idxEqualSign = line.find('=');
-  const std::string& fullTag = line.substr(0, idxEqualSign);
+  auto fullTag = cm::string_view(line).substr(0, idxEqualSign);
   if (!this->ParseTag(fullTag, parsedLine, state))
     return false;
   if (idxEqualSign != line.npos) {
@@ -560,7 +560,7 @@
                                                   State& state)
 {
   size_t idxEqualSign = line.find('=');
-  const std::string& fullTag = line.substr(0, idxEqualSign);
+  auto fullTag = cm::string_view(line).substr(0, idxEqualSign);
   if (!this->ParseTag(fullTag, parsedLine, state))
     return false;
   if (idxEqualSign != line.npos) {
@@ -586,17 +586,17 @@
   return true;
 }
 
-bool cmVisualStudioSlnParser::ParseTag(const std::string& fullTag,
+bool cmVisualStudioSlnParser::ParseTag(cm::string_view fullTag,
                                        ParsedLine& parsedLine, State& state)
 {
   size_t idxLeftParen = fullTag.find('(');
-  if (idxLeftParen == fullTag.npos) {
+  if (idxLeftParen == cm::string_view::npos) {
     parsedLine.SetTag(cmTrimWhitespace(fullTag));
     return true;
   }
   parsedLine.SetTag(cmTrimWhitespace(fullTag.substr(0, idxLeftParen)));
   size_t idxRightParen = fullTag.rfind(')');
-  if (idxRightParen == fullTag.npos) {
+  if (idxRightParen == cm::string_view::npos) {
     this->LastResult.SetError(ResultErrorInputStructure,
                               state.GetCurrentLine());
     return false;
diff --git a/Source/cmVisualStudioSlnParser.h b/Source/cmVisualStudioSlnParser.h
index 6c05633..4557cdb 100644
--- a/Source/cmVisualStudioSlnParser.h
+++ b/Source/cmVisualStudioSlnParser.h
@@ -9,6 +9,8 @@
 #include <iosfwd>
 #include <string>
 
+#include <cm/string_view>
+
 #include <stddef.h>
 
 class cmSlnData;
@@ -97,8 +99,7 @@
   bool ParseKeyValuePair(const std::string& line, ParsedLine& parsedLine,
                          State& state);
 
-  bool ParseTag(const std::string& fullTag, ParsedLine& parsedLine,
-                State& state);
+  bool ParseTag(cm::string_view fullTag, ParsedLine& parsedLine, State& state);
 
   bool ParseValue(const std::string& value, ParsedLine& parsedLine);
 };
diff --git a/Source/cmWhileCommand.cxx b/Source/cmWhileCommand.cxx
index 26e7c75..0d8e894 100644
--- a/Source/cmWhileCommand.cxx
+++ b/Source/cmWhileCommand.cxx
@@ -7,8 +7,7 @@
 
 #include <cm/memory>
 #include <cm/string_view>
-
-#include "cm_static_string_view.hxx"
+#include <cmext/string_view>
 
 #include "cmConditionEvaluator.h"
 #include "cmExecutionStatus.h"
diff --git a/Source/cmWorkerPool.cxx b/Source/cmWorkerPool.cxx
index aa0d6b3..12aba4f 100644
--- a/Source/cmWorkerPool.cxx
+++ b/Source/cmWorkerPool.cxx
@@ -13,7 +13,7 @@
 
 #include <cm/memory>
 
-#include "cm_uv.h"
+#include <cm3p/uv.h>
 
 #include "cmRange.h"
 #include "cmStringAlgorithms.h"
@@ -469,11 +469,9 @@
 
 void cmWorkerPoolWorker::UVProcessFinished()
 {
-  {
-    std::lock_guard<std::mutex> lock(Proc_.Mutex);
-    if (Proc_.ROP && (Proc_.ROP->IsFinished() || !Proc_.ROP->IsStarted())) {
-      Proc_.ROP.reset();
-    }
+  std::lock_guard<std::mutex> lock(Proc_.Mutex);
+  if (Proc_.ROP && (Proc_.ROP->IsFinished() || !Proc_.ROP->IsStarted())) {
+    Proc_.ROP.reset();
   }
   // Notify idling thread
   Proc_.Condition.notify_one();
@@ -532,6 +530,7 @@
   unsigned int JobsProcessing = 0;
   std::deque<cmWorkerPool::JobHandleT> Queue;
   std::condition_variable Condition;
+  std::condition_variable ConditionFence;
   std::vector<std::unique_ptr<cmWorkerPoolWorker>> Workers;
 
   // -- References
@@ -593,19 +592,12 @@
 
 void cmWorkerPoolInternal::Abort()
 {
-  bool notifyThreads = false;
   // Clear all jobs and set abort flag
-  {
-    std::lock_guard<std::mutex> guard(Mutex);
-    if (Processing && !Aborting) {
-      // Register abort and clear queue
-      Aborting = true;
-      Queue.clear();
-      notifyThreads = true;
-    }
-  }
-  if (notifyThreads) {
-    // Wake threads
+  std::lock_guard<std::mutex> guard(Mutex);
+  if (!Aborting) {
+    // Register abort and clear queue
+    Aborting = true;
+    Queue.clear();
     Condition.notify_all();
   }
 }
@@ -669,7 +661,7 @@
     if (Aborting) {
       break;
     }
-    // Wait for new jobs
+    // Wait for new jobs on the main CV
     if (Queue.empty()) {
       ++WorkersIdle;
       Condition.wait(uLock);
@@ -677,20 +669,34 @@
       continue;
     }
 
-    // Check for fence jobs
-    if (FenceProcessing || Queue.front()->IsFence()) {
-      if (JobsProcessing != 0) {
-        Condition.wait(uLock);
-        continue;
-      }
-      // No jobs get processed. Set the fence job processing flag.
-      FenceProcessing = true;
+    // If there is a fence currently active or waiting,
+    // sleep on the main CV and try again.
+    if (FenceProcessing) {
+      Condition.wait(uLock);
+      continue;
     }
 
     // Pop next job from queue
     jobHandle = std::move(Queue.front());
     Queue.pop_front();
 
+    // Check for fence jobs
+    bool raisedFence = false;
+    if (jobHandle->IsFence()) {
+      FenceProcessing = true;
+      raisedFence = true;
+      // Wait on the Fence CV until all pending jobs are done.
+      while (JobsProcessing != 0 && !Aborting) {
+        ConditionFence.wait(uLock);
+      }
+      // When aborting, explicitly kick all threads alive once more.
+      if (Aborting) {
+        FenceProcessing = false;
+        Condition.notify_all();
+        break;
+      }
+    }
+
     // Unlocked scope for job processing
     ++JobsProcessing;
     {
@@ -701,11 +707,18 @@
     }
     --JobsProcessing;
 
-    // Was this a fence job?
-    if (FenceProcessing) {
+    // If this was the thread that entered fence processing
+    // originally, notify all idling workers that the fence
+    // is done.
+    if (raisedFence) {
       FenceProcessing = false;
       Condition.notify_all();
     }
+    // If fence processing is still not done, notify the
+    // the fencing worker when all active jobs are done.
+    if (FenceProcessing && JobsProcessing == 0) {
+      ConditionFence.notify_all();
+    }
   }
 
   // Decrement running workers count
diff --git a/Source/cmWorkingDirectory.h b/Source/cmWorkingDirectory.h
index d4a164d..4c7576d 100644
--- a/Source/cmWorkingDirectory.h
+++ b/Source/cmWorkingDirectory.h
@@ -37,6 +37,8 @@
    */
   int GetLastResult() const { return ResultCode; }
 
+  std::string const& GetOldDirectory() const { return this->OldDir; }
+
 private:
   std::string OldDir;
   int ResultCode;
diff --git a/Source/cmWriteFileCommand.cxx b/Source/cmWriteFileCommand.cxx
index 34e21b2..666ba87 100644
--- a/Source/cmWriteFileCommand.cxx
+++ b/Source/cmWriteFileCommand.cxx
@@ -72,7 +72,7 @@
     status.SetError(error);
     return false;
   }
-  file << message << std::endl;
+  file << message << '\n';
   file.close();
   if (mode && !writable) {
     cmSystemTools::SetPermissions(fileName.c_str(), mode);
diff --git a/Source/cmXCode21Object.cxx b/Source/cmXCode21Object.cxx
index a9bb2ef..6b133a9 100644
--- a/Source/cmXCode21Object.cxx
+++ b/Source/cmXCode21Object.cxx
@@ -30,11 +30,12 @@
   out << " */";
 }
 
-void cmXCode21Object::PrintList(std::vector<cmXCodeObject*> const& v,
-                                std::ostream& out, PBXType t)
+void cmXCode21Object::PrintList(
+  std::vector<std::unique_ptr<cmXCodeObject>> const& v, std::ostream& out,
+  PBXType t)
 {
   bool hasOne = false;
-  for (auto obj : v) {
+  for (const auto& obj : v) {
     if (obj->GetType() == OBJECT && obj->GetIsA() == t) {
       hasOne = true;
       break;
@@ -44,7 +45,7 @@
     return;
   }
   out << "\n/* Begin " << PBXTypeNames[t] << " section */\n";
-  for (auto obj : v) {
+  for (const auto& obj : v) {
     if (obj->GetType() == OBJECT && obj->GetIsA() == t) {
       obj->Print(out);
     }
@@ -52,8 +53,8 @@
   out << "/* End " << PBXTypeNames[t] << " section */\n";
 }
 
-void cmXCode21Object::PrintList(std::vector<cmXCodeObject*> const& v,
-                                std::ostream& out)
+void cmXCode21Object::PrintList(
+  std::vector<std::unique_ptr<cmXCodeObject>> const& v, std::ostream& out)
 {
   cmXCodeObject::Indent(1, out);
   out << "objects = {\n";
diff --git a/Source/cmXCode21Object.h b/Source/cmXCode21Object.h
index 8e4b80f..76fad23 100644
--- a/Source/cmXCode21Object.h
+++ b/Source/cmXCode21Object.h
@@ -6,6 +6,7 @@
 #include "cmConfigure.h" // IWYU pragma: keep
 
 #include <iosfwd>
+#include <memory>
 #include <vector>
 
 #include "cmXCodeObject.h"
@@ -15,8 +16,9 @@
 public:
   cmXCode21Object(PBXType ptype, Type type);
   void PrintComment(std::ostream&) override;
-  static void PrintList(std::vector<cmXCodeObject*> const&, std::ostream& out,
-                        PBXType t);
-  static void PrintList(std::vector<cmXCodeObject*> const&, std::ostream& out);
+  static void PrintList(std::vector<std::unique_ptr<cmXCodeObject>> const&,
+                        std::ostream& out, PBXType t);
+  static void PrintList(std::vector<std::unique_ptr<cmXCodeObject>> const&,
+                        std::ostream& out);
 };
 #endif
diff --git a/Source/cmXCodeObject.h b/Source/cmXCodeObject.h
index d9be3d2..24ecaa2 100644
--- a/Source/cmXCodeObject.h
+++ b/Source/cmXCodeObject.h
@@ -12,7 +12,7 @@
 #include <utility>
 #include <vector>
 
-#include "cmAlgorithms.h"
+#include <cmext/algorithm>
 
 class cmGeneratorTarget;
 
@@ -82,10 +82,13 @@
   void SetObject(cmXCodeObject* value) { this->Object = value; }
   cmXCodeObject* GetObject() { return this->Object; }
   void AddObject(cmXCodeObject* value) { this->List.push_back(value); }
-  bool HasObject(cmXCodeObject* o) const { return cmContains(this->List, o); }
+  bool HasObject(cmXCodeObject* o) const
+  {
+    return cm::contains(this->List, o);
+  }
   void AddUniqueObject(cmXCodeObject* value)
   {
-    if (!cmContains(this->List, value)) {
+    if (!cm::contains(this->List, value)) {
       this->List.push_back(value);
     }
   }
diff --git a/Source/cmXCodeScheme.cxx b/Source/cmXCodeScheme.cxx
index b34c2f6..55e941d 100644
--- a/Source/cmXCodeScheme.cxx
+++ b/Source/cmXCodeScheme.cxx
@@ -7,6 +7,8 @@
 #include <sstream>
 #include <utility>
 
+#include <cmext/algorithm>
+
 #include "cmGeneratedFileStream.h"
 #include "cmGeneratorExpression.h"
 #include "cmGeneratorTarget.h"
@@ -31,7 +33,7 @@
   // Create shared scheme sub-directory tree
   //
   std::string xcodeSchemeDir = cmStrCat(xcProjDir, "/xcshareddata/xcschemes");
-  cmSystemTools::MakeDirectory(xcodeSchemeDir.c_str());
+  cmSystemTools::MakeDirectory(xcodeSchemeDir);
 
   std::string xcodeSchemeFile =
     cmStrCat(xcodeSchemeDir, '/', this->TargetName, ".xcscheme");
@@ -202,14 +204,14 @@
 
   // Info tab begin
 
-  if (const char* exe =
+  if (cmProp exe =
         this->Target->GetTarget()->GetProperty("XCODE_SCHEME_EXECUTABLE")) {
 
     xout.StartElement("PathRunnable");
     xout.BreakAttributes();
 
     xout.Attribute("runnableDebuggingMode", "0");
-    xout.Attribute("FilePath", exe);
+    xout.Attribute("FilePath", *exe);
 
     xout.EndElement(); // PathRunnable
   }
@@ -218,9 +220,9 @@
 
   // Arguments tab begin
 
-  if (const char* argList =
+  if (cmProp argList =
         this->Target->GetTarget()->GetProperty("XCODE_SCHEME_ARGUMENTS")) {
-    std::vector<std::string> arguments = cmExpandedList(argList);
+    std::vector<std::string> arguments = cmExpandedList(*argList);
     if (!arguments.empty()) {
       xout.StartElement("CommandLineArguments");
 
@@ -238,9 +240,9 @@
     }
   }
 
-  if (const char* envList =
+  if (cmProp envList =
         this->Target->GetTarget()->GetProperty("XCODE_SCHEME_ENVIRONMENT")) {
-    std::vector<std::string> envs = cmExpandedList(envList);
+    std::vector<std::string> envs = cmExpandedList(*envList);
     if (!envs.empty()) {
       xout.StartElement("EnvironmentVariables");
 
@@ -321,7 +323,7 @@
   cmXMLWriter& xout, const std::string& attrName, const std::string& varName,
   bool defaultValue)
 {
-  auto property = Target->GetTarget()->GetProperty(varName);
+  cmProp property = Target->GetTarget()->GetProperty(varName);
   bool isOn = (property == nullptr && defaultValue) || cmIsOn(property);
 
   if (isOn) {
@@ -393,7 +395,8 @@
   xout.BreakAttributes();
   xout.Attribute("BuildableIdentifier", "primary");
   xout.Attribute("BlueprintIdentifier", xcObj->GetId());
-  xout.Attribute("BuildableName", xcObj->GetTarget()->GetFullName());
+  std::string const noConfig; // FIXME: What config to use here?
+  xout.Attribute("BuildableName", xcObj->GetTarget()->GetFullName(noConfig));
   xout.Attribute("BlueprintName", xcObj->GetTarget()->GetName());
   xout.Attribute("ReferencedContainer", "container:" + container);
   xout.EndElement();
@@ -402,8 +405,9 @@
 void cmXCodeScheme::WriteCustomWorkingDirectory(
   cmXMLWriter& xout, const std::string& configuration)
 {
-  std::string propertyValue = this->Target->GetTarget()->GetSafeProperty(
-    "XCODE_SCHEME_WORKING_DIRECTORY");
+  std::string const& propertyValue =
+    this->Target->GetTarget()->GetSafeProperty(
+      "XCODE_SCHEME_WORKING_DIRECTORY");
   if (propertyValue.empty()) {
     xout.Attribute("useCustomWorkingDirectory", "NO");
   } else {
@@ -427,7 +431,7 @@
   // Try to find the desired configuration by name,
   // and if it's not found return first from the list
   //
-  if (!cmContains(this->ConfigList, name) && !this->ConfigList.empty()) {
+  if (!cm::contains(this->ConfigList, name) && !this->ConfigList.empty()) {
     return this->ConfigList[0];
   }
 
diff --git a/Source/cmXMLParser.cxx b/Source/cmXMLParser.cxx
index ad5c4ba..24da8c6 100644
--- a/Source/cmXMLParser.cxx
+++ b/Source/cmXMLParser.cxx
@@ -7,9 +7,9 @@
 #include <iostream>
 #include <sstream>
 
-#include "cmsys/FStream.hxx"
+#include <cm3p/expat.h>
 
-#include "cm_expat.h"
+#include "cmsys/FStream.hxx"
 
 cmXMLParser::cmXMLParser()
 {
diff --git a/Source/cmXMLWriter.h b/Source/cmXMLWriter.h
index bc445aa..00ea08c 100644
--- a/Source/cmXMLWriter.h
+++ b/Source/cmXMLWriter.h
@@ -6,7 +6,7 @@
 #include "cmConfigure.h" // IWYU pragma: keep
 
 #include <chrono>
-#include <cstddef>
+#include <cstddef> // IWYU pragma: keep
 #include <ctime>
 #include <ostream>
 #include <stack>
diff --git a/Source/cm_get_date.c b/Source/cm_get_date.c
index 4bef803..49f5577 100644
--- a/Source/cm_get_date.c
+++ b/Source/cm_get_date.c
@@ -2,6 +2,10 @@
    file Copyright.txt or https://cmake.org/licensing for details.  */
 #include "cm_get_date.h"
 
+// FIXME: This suppresses use of localtime_r because archive_getdate.c
+// depends the rest of libarchive's checks for that.
+#define CM_GET_DATE
+
 #define __archive_get_date cm_get_date
 
 #include "../Utilities/cmlibarchive/libarchive/archive_getdate.c"
diff --git a/Source/cm_static_string_view.hxx b/Source/cm_static_string_view.hxx
deleted file mode 100644
index 708ac95..0000000
--- a/Source/cm_static_string_view.hxx
+++ /dev/null
@@ -1,41 +0,0 @@
-/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
-   file Copyright.txt or https://cmake.org/licensing for details.  */
-#ifndef cm_static_string_view_hxx
-#define cm_static_string_view_hxx
-
-#include "cmConfigure.h" // IWYU pragma: keep
-
-#include <cstddef>
-
-#include <cm/string_view>
-
-namespace cm {
-
-/** A string_view that only binds to static storage.
- *
- * This is used together with the `""_s` user-defined literal operator
- * to construct a type-safe abstraction of a string_view that only views
- * statically allocated strings.  These strings are const and available
- * for the entire lifetime of the program.
- */
-class static_string_view : public string_view
-{
-  static_string_view(string_view v)
-    : string_view(v)
-  {
-  }
-
-  friend static_string_view operator"" _s(const char* data, size_t size);
-};
-
-/** Create a static_string_view using `""_s` literal syntax.  */
-inline static_string_view operator"" _s(const char* data, size_t size)
-{
-  return string_view(data, size);
-}
-
-} // namespace cm
-
-using cm::operator"" _s;
-
-#endif
diff --git a/Source/cmake.cxx b/Source/cmake.cxx
index a99d9a6..dcb96f8 100644
--- a/Source/cmake.cxx
+++ b/Source/cmake.cxx
@@ -9,6 +9,7 @@
 #include <initializer_list>
 #include <iostream>
 #include <sstream>
+#include <stdexcept>
 #include <utility>
 
 #include <cm/memory>
@@ -18,6 +19,7 @@
 #endif
 
 #include <cmext/algorithm>
+#include <cmext/string_view>
 
 #include "cmsys/FStream.hxx"
 #include "cmsys/Glob.hxx"
@@ -25,7 +27,6 @@
 
 #include "cm_sys_stat.h"
 
-#include "cmAlgorithms.h"
 #include "cmCommands.h"
 #include "cmDocumentation.h"
 #include "cmDocumentationEntry.h"
@@ -39,6 +40,9 @@
 #include "cmLinkLineComputer.h"
 #include "cmLocalGenerator.h"
 #include "cmMakefile.h"
+#if !defined(CMAKE_BOOTSTRAP)
+#  include "cmMakefileProfilingData.h"
+#endif
 #include "cmMessenger.h"
 #include "cmState.h"
 #include "cmStateDirectory.h"
@@ -53,17 +57,13 @@
 #if !defined(CMAKE_BOOTSTRAP)
 #  include <unordered_map>
 
-#  include "cm_jsoncpp_writer.h"
+#  include <cm3p/json/writer.h>
 
 #  include "cmFileAPI.h"
 #  include "cmGraphVizWriter.h"
 #  include "cmVariableWatch.h"
 #endif
 
-#if !defined(CMAKE_BOOTSTRAP)
-#  define CMAKE_USE_ECLIPSE
-#endif
-
 #if defined(__MINGW32__) && defined(CMAKE_BOOTSTRAP)
 #  define CMAKE_BOOT_MINGW
 #endif
@@ -97,16 +97,13 @@
 #if !defined(CMAKE_BOOTSTRAP)
 #  include "cmGlobalNinjaGenerator.h"
 #endif
-#include "cmExtraCodeLiteGenerator.h"
 
-#if !defined(CMAKE_BOOT_MINGW)
+#if !defined(CMAKE_BOOTSTRAP)
 #  include "cmExtraCodeBlocksGenerator.h"
-#endif
-#include "cmExtraKateGenerator.h"
-#include "cmExtraSublimeTextGenerator.h"
-
-#ifdef CMAKE_USE_ECLIPSE
+#  include "cmExtraCodeLiteGenerator.h"
 #  include "cmExtraEclipseCDT4Generator.h"
+#  include "cmExtraKateGenerator.h"
+#  include "cmExtraSublimeTextGenerator.h"
 #endif
 
 #if defined(__linux__) || defined(_WIN32)
@@ -134,6 +131,7 @@
 static bool cmakeCheckStampFile(const std::string& stampName);
 static bool cmakeCheckStampList(const std::string& stampList);
 
+#ifndef CMAKE_BOOTSTRAP
 static void cmWarnUnusedCliWarning(const std::string& variable, int /*unused*/,
                                    void* ctx, const char* /*unused*/,
                                    const cmMakefile* /*unused*/)
@@ -141,6 +139,7 @@
   cmake* cm = reinterpret_cast<cmake*>(ctx);
   cm->MarkCliAsUsed(variable);
 }
+#endif
 
 cmake::cmake(Role role, cmState::Mode mode)
   : FileTimeCache(cm::make_unique<cmFileTimeCache>())
@@ -195,7 +194,7 @@
     };
 
     // The "c" extension MUST precede the "C" extension.
-    setupExts(this->SourceFileExtensions,
+    setupExts(this->CLikeSourceFileExtensions,
               { "c", "C", "c++", "cc", "cpp", "cxx", "cu", "m", "M", "mm" });
     setupExts(this->HeaderFileExtensions,
               { "h", "hh", "h++", "hm", "hpp", "hxx", "in", "txx" });
@@ -285,10 +284,11 @@
 // Parse the args
 bool cmake::SetCacheArgs(const std::vector<std::string>& args)
 {
-  bool findPackageMode = false;
+  auto findPackageMode = false;
+  auto seenScriptOption = false;
   for (unsigned int i = 1; i < args.size(); ++i) {
     std::string const& arg = args[i];
-    if (arg.find("-D", 0) == 0) {
+    if (cmHasLiteralPrefix(arg, "-D")) {
       std::string entry = arg.substr(2);
       if (entry.empty()) {
         ++i;
@@ -309,8 +309,7 @@
         bool haveValue = false;
         std::string cachedValue;
         if (this->WarnUnusedCli) {
-          if (const std::string* v =
-                this->State->GetInitializedCacheValue(var)) {
+          if (cmProp v = this->State->GetInitializedCacheValue(var)) {
             haveValue = true;
             cachedValue = *v;
           }
@@ -377,7 +376,7 @@
         // -Wno-error=<name>
         this->DiagLevels[name] = std::min(this->DiagLevels[name], DIAG_WARN);
       }
-    } else if (arg.find("-U", 0) == 0) {
+    } else if (cmHasLiteralPrefix(arg, "-U")) {
       std::string entryPattern = arg.substr(2);
       if (entryPattern.empty()) {
         ++i;
@@ -407,7 +406,7 @@
       for (std::string const& currentEntry : entriesToDelete) {
         this->State->RemoveCacheEntry(currentEntry);
       }
-    } else if (arg.find("-C", 0) == 0) {
+    } else if (cmHasLiteralPrefix(arg, "-C")) {
       std::string path = arg.substr(2);
       if (path.empty()) {
         ++i;
@@ -422,7 +421,7 @@
       // Resolve script path specified on command line relative to $PWD.
       path = cmSystemTools::CollapseFullPath(path);
       this->ReadListFile(args, path);
-    } else if (arg.find("-P", 0) == 0) {
+    } else if (cmHasLiteralPrefix(arg, "-P")) {
       i++;
       if (i >= args.size()) {
         cmSystemTools::Error("-P must be followed by a file name.");
@@ -441,7 +440,12 @@
       this->SetHomeOutputDirectory(
         cmSystemTools::GetCurrentWorkingDirectory());
       this->ReadListFile(args, path);
-    } else if (arg.find("--find-package", 0) == 0) {
+      seenScriptOption = true;
+    } else if (arg == "--" && seenScriptOption) {
+      // Stop processing CMake args and avoid possible errors
+      // when arbitrary args are given to CMake script.
+      break;
+    } else if (cmHasLiteralPrefix(arg, "--find-package")) {
       findPackageMode = true;
     }
   }
@@ -520,11 +524,11 @@
     if (!quiet) {
       printf("%s not found.\n", packageName.c_str());
     }
-  } else if (mode == "EXIST") {
+  } else if (mode == "EXIST"_s) {
     if (!quiet) {
       printf("%s found.\n", packageName.c_str());
     }
-  } else if (mode == "COMPILE") {
+  } else if (mode == "COMPILE"_s) {
     std::string includes = mf->GetSafeDefinition("PACKAGE_INCLUDE_DIRS");
     std::vector<std::string> includeDirs = cmExpandedList(includes);
 
@@ -535,7 +539,7 @@
 
     std::string definitions = mf->GetSafeDefinition("PACKAGE_DEFINITIONS");
     printf("%s %s\n", includeFlags.c_str(), definitions.c_str());
-  } else if (mode == "LINK") {
+  } else if (mode == "LINK"_s) {
     const char* targetName = "dummy";
     std::vector<std::string> srcs;
     cmTarget* tgt = mf->AddExecutable(targetName, srcs, true);
@@ -613,9 +617,13 @@
 {
   bool haveToolset = false;
   bool havePlatform = false;
+#if !defined(CMAKE_BOOTSTRAP)
+  std::string profilingFormat;
+  std::string profilingOutput;
+#endif
   for (unsigned int i = 1; i < args.size(); ++i) {
     std::string const& arg = args[i];
-    if (arg.find("-H", 0) == 0 || arg.find("-S", 0) == 0) {
+    if (cmHasLiteralPrefix(arg, "-H") || cmHasLiteralPrefix(arg, "-S")) {
       std::string path = arg.substr(2);
       if (path.empty()) {
         ++i;
@@ -633,9 +641,11 @@
       path = cmSystemTools::CollapseFullPath(path);
       cmSystemTools::ConvertToUnixSlashes(path);
       this->SetHomeDirectory(path);
-    } else if (arg.find("-O", 0) == 0) {
+      // XXX(clang-tidy): https://bugs.llvm.org/show_bug.cgi?id=44165
+      // NOLINTNEXTLINE(bugprone-branch-clone)
+    } else if (cmHasLiteralPrefix(arg, "-O")) {
       // There is no local generate anymore.  Ignore -O option.
-    } else if (arg.find("-B", 0) == 0) {
+    } else if (cmHasLiteralPrefix(arg, "-B")) {
       std::string path = arg.substr(2);
       if (path.empty()) {
         ++i;
@@ -654,54 +664,43 @@
       cmSystemTools::ConvertToUnixSlashes(path);
       this->SetHomeOutputDirectory(path);
     } else if ((i < args.size() - 2) &&
-               (arg.find("--check-build-system", 0) == 0)) {
+               cmHasLiteralPrefix(arg, "--check-build-system")) {
       this->CheckBuildSystemArgument = args[++i];
       this->ClearBuildSystem = (atoi(args[++i].c_str()) > 0);
     } else if ((i < args.size() - 1) &&
-               (arg.find("--check-stamp-file", 0) == 0)) {
+               cmHasLiteralPrefix(arg, "--check-stamp-file")) {
       this->CheckStampFile = args[++i];
     } else if ((i < args.size() - 1) &&
-               (arg.find("--check-stamp-list", 0) == 0)) {
+               cmHasLiteralPrefix(arg, "--check-stamp-list")) {
       this->CheckStampList = args[++i];
-    } else if (arg == "--regenerate-during-build") {
+    } else if (arg == "--regenerate-during-build"_s) {
       this->RegenerateDuringBuild = true;
     }
 #if defined(CMAKE_HAVE_VS_GENERATORS)
     else if ((i < args.size() - 1) &&
-             (arg.find("--vs-solution-file", 0) == 0)) {
+             cmHasLiteralPrefix(arg, "--vs-solution-file")) {
       this->VSSolutionFile = args[++i];
     }
 #endif
-    else if (arg.find("-D", 0) == 0) {
+    else if (cmHasLiteralPrefix(arg, "-D") || cmHasLiteralPrefix(arg, "-U") ||
+             cmHasLiteralPrefix(arg, "-C")) {
       // skip for now
-      // in case '-D var=val' is given, also skip the next
-      // in case '-Dvar=val' is given, don't skip the next
+      // in case '-[DUC] argval' var' is given, also skip the next
+      // in case '-[DUC]argval' is given, don't skip the next
       if (arg.size() == 2) {
         ++i;
       }
-    } else if (arg.find("-U", 0) == 0) {
-      // skip for now
-      // in case '-U var' is given, also skip the next
-      // in case '-Uvar' is given, don't skip the next
-      if (arg.size() == 2) {
-        ++i;
-      }
-    } else if (arg.find("-C", 0) == 0) {
-      // skip for now
-      // in case '-C path' is given, also skip the next
-      // in case '-Cpath' is given, don't skip the next
-      if (arg.size() == 2) {
-        ++i;
-      }
-    } else if (arg.find("-P", 0) == 0) {
+      // XXX(clang-tidy): https://bugs.llvm.org/show_bug.cgi?id=44165
+      // NOLINTNEXTLINE(bugprone-branch-clone)
+    } else if (cmHasLiteralPrefix(arg, "-P")) {
       // skip for now
       i++;
-    } else if (arg.find("--find-package", 0) == 0) {
+    } else if (cmHasLiteralPrefix(arg, "--find-package")) {
       // skip for now
       i++;
-    } else if (arg.find("-W", 0) == 0) {
+    } else if (cmHasLiteralPrefix(arg, "-W")) {
       // skip for now
-    } else if (arg.find("--graphviz=", 0) == 0) {
+    } else if (cmHasLiteralPrefix(arg, "--graphviz=")) {
       std::string path = arg.substr(strlen("--graphviz="));
       path = cmSystemTools::CollapseFullPath(path);
       cmSystemTools::ConvertToUnixSlashes(path);
@@ -710,13 +709,13 @@
         cmSystemTools::Error("No file specified for --graphviz");
         return;
       }
-    } else if (arg.find("--debug-trycompile", 0) == 0) {
+    } else if (cmHasLiteralPrefix(arg, "--debug-trycompile")) {
       std::cout << "debug trycompile on\n";
       this->DebugTryCompileOn();
-    } else if (arg.find("--debug-output", 0) == 0) {
+    } else if (cmHasLiteralPrefix(arg, "--debug-output")) {
       std::cout << "Running with debug output on.\n";
       this->SetDebugOutputOn(true);
-    } else if (arg.find("--log-level=", 0) == 0) {
+    } else if (cmHasLiteralPrefix(arg, "--log-level=")) {
       const auto logLevel =
         StringToLogLevel(arg.substr(sizeof("--log-level=") - 1));
       if (logLevel == LogLevel::LOG_UNDEFINED) {
@@ -725,7 +724,7 @@
       }
       this->SetLogLevel(logLevel);
       this->LogLevelWasSetViaCLI = true;
-    } else if (arg.find("--loglevel=", 0) == 0) {
+    } else if (cmHasLiteralPrefix(arg, "--loglevel=")) {
       // This is supported for backward compatibility. This option only
       // appeared in the 3.15.x release series and was renamed to
       // --log-level in 3.16.0
@@ -737,16 +736,16 @@
       }
       this->SetLogLevel(logLevel);
       this->LogLevelWasSetViaCLI = true;
-    } else if (arg == "--log-context") {
+    } else if (arg == "--log-context"_s) {
       this->SetShowLogContext(true);
-    } else if (arg.find("--debug-find", 0) == 0) {
+    } else if (cmHasLiteralPrefix(arg, "--debug-find")) {
       std::cout << "Running with debug output on for the `find` commands.\n";
       this->SetDebugFindOutputOn(true);
-    } else if (arg.find("--trace-expand", 0) == 0) {
+    } else if (cmHasLiteralPrefix(arg, "--trace-expand")) {
       std::cout << "Running with expanded trace output on.\n";
       this->SetTrace(true);
       this->SetTraceExpand(true);
-    } else if (arg.find("--trace-format=", 0) == 0) {
+    } else if (cmHasLiteralPrefix(arg, "--trace-format=")) {
       this->SetTrace(true);
       const auto traceFormat =
         StringToTraceFormat(arg.substr(strlen("--trace-format=")));
@@ -756,35 +755,34 @@
         return;
       }
       this->SetTraceFormat(traceFormat);
-    } else if (arg.find("--trace-source=", 0) == 0) {
+    } else if (cmHasLiteralPrefix(arg, "--trace-source=")) {
       std::string file = arg.substr(strlen("--trace-source="));
       cmSystemTools::ConvertToUnixSlashes(file);
       this->AddTraceSource(file);
       this->SetTrace(true);
-    } else if (arg.find("--trace-redirect=", 0) == 0) {
+    } else if (cmHasLiteralPrefix(arg, "--trace-redirect=")) {
       std::string file = arg.substr(strlen("--trace-redirect="));
       cmSystemTools::ConvertToUnixSlashes(file);
       this->SetTraceFile(file);
       this->SetTrace(true);
-    } else if (arg.find("--trace", 0) == 0) {
+    } else if (cmHasLiteralPrefix(arg, "--trace")) {
       std::cout << "Running with trace output on.\n";
       this->SetTrace(true);
       this->SetTraceExpand(false);
-    } else if (arg.find("--warn-uninitialized", 0) == 0) {
+    } else if (cmHasLiteralPrefix(arg, "--warn-uninitialized")) {
       std::cout << "Warn about uninitialized values.\n";
       this->SetWarnUninitialized(true);
-    } else if (arg.find("--warn-unused-vars", 0) == 0) {
-      std::cout << "Finding unused variables.\n";
-      this->SetWarnUnused(true);
-    } else if (arg.find("--no-warn-unused-cli", 0) == 0) {
+    } else if (cmHasLiteralPrefix(arg, "--warn-unused-vars")) {
+      // Option was removed.
+    } else if (cmHasLiteralPrefix(arg, "--no-warn-unused-cli")) {
       std::cout << "Not searching for unused variables given on the "
                 << "command line.\n";
       this->SetWarnUnusedCli(false);
-    } else if (arg.find("--check-system-vars", 0) == 0) {
+    } else if (cmHasLiteralPrefix(arg, "--check-system-vars")) {
       std::cout << "Also check system files when warning about unused and "
                 << "uninitialized variables.\n";
       this->SetCheckSystemVars(true);
-    } else if (arg.find("-A", 0) == 0) {
+    } else if (cmHasLiteralPrefix(arg, "-A")) {
       std::string value = arg.substr(2);
       if (value.empty()) {
         ++i;
@@ -800,7 +798,7 @@
       }
       this->SetGeneratorPlatform(value);
       havePlatform = true;
-    } else if (arg.find("-T", 0) == 0) {
+    } else if (cmHasLiteralPrefix(arg, "-T")) {
       std::string value = arg.substr(2);
       if (value.empty()) {
         ++i;
@@ -816,7 +814,7 @@
       }
       this->SetGeneratorToolset(value);
       haveToolset = true;
-    } else if (arg.find("-G", 0) == 0) {
+    } else if (cmHasLiteralPrefix(arg, "-G")) {
       std::string value = arg.substr(2);
       if (value.empty()) {
         ++i;
@@ -840,6 +838,20 @@
         return;
       }
       this->SetGlobalGenerator(std::move(gen));
+#if !defined(CMAKE_BOOTSTRAP)
+    } else if (cmHasLiteralPrefix(arg, "--profiling-format")) {
+      profilingFormat = arg.substr(strlen("--profiling-format="));
+      if (profilingFormat.empty()) {
+        cmSystemTools::Error("No format specified for --profiling-format");
+      }
+    } else if (cmHasLiteralPrefix(arg, "--profiling-output")) {
+      profilingOutput = arg.substr(strlen("--profiling-output="));
+      profilingOutput = cmSystemTools::CollapseFullPath(profilingOutput);
+      cmSystemTools::ConvertToUnixSlashes(profilingOutput);
+      if (profilingOutput.empty()) {
+        cmSystemTools::Error("No path specified for --profiling-output");
+      }
+#endif
     }
     // no option assume it is the path to the source or an existing build
     else {
@@ -857,6 +869,29 @@
     }
   }
 
+#if !defined(CMAKE_BOOTSTRAP)
+  if (!profilingOutput.empty() || !profilingFormat.empty()) {
+    if (profilingOutput.empty()) {
+      cmSystemTools::Error(
+        "--profiling-format specified but no --profiling-output!");
+      return;
+    }
+    if (profilingFormat == "google-trace"_s) {
+      try {
+        this->ProfilingOutput =
+          cm::make_unique<cmMakefileProfilingData>(profilingOutput);
+      } catch (std::runtime_error& e) {
+        cmSystemTools::Error(
+          cmStrCat("Could not start profiling: ", e.what()));
+        return;
+      }
+    } else {
+      cmSystemTools::Error("Invalid format specified for --profiling-format");
+      return;
+    }
+  }
+#endif
+
   const bool haveSourceDir = !this->GetHomeDirectory().empty();
   const bool haveBinaryDir = !this->GetHomeOutputDirectory().empty();
 
@@ -992,9 +1027,9 @@
     std::string fullPath = cmSystemTools::CollapseFullPath(arg);
     std::string name = cmSystemTools::GetFilenameName(fullPath);
     name = cmSystemTools::LowerCase(name);
-    if (name == "cmakecache.txt") {
+    if (name == "cmakecache.txt"_s) {
       cachePath = cmSystemTools::GetFilenamePath(fullPath);
-    } else if (name == "cmakelists.txt") {
+    } else if (name == "cmakelists.txt"_s) {
       listPath = cmSystemTools::GetFilenamePath(fullPath);
     }
   } else {
@@ -1003,7 +1038,7 @@
     std::string fullPath = cmSystemTools::CollapseFullPath(arg);
     std::string name = cmSystemTools::GetFilenameName(fullPath);
     name = cmSystemTools::LowerCase(name);
-    if (name == "cmakecache.txt" || name == "cmakelists.txt") {
+    if (name == "cmakecache.txt"_s || name == "cmakelists.txt"_s) {
       argIsFile = true;
       listPath = cmSystemTools::GetFilenamePath(fullPath);
     } else {
@@ -1014,11 +1049,11 @@
   // If there is a CMakeCache.txt file, use its settings.
   if (!cachePath.empty()) {
     if (this->LoadCache(cachePath)) {
-      const char* existingValue =
+      cmProp existingValue =
         this->State->GetCacheEntryValue("CMAKE_HOME_DIRECTORY");
       if (existingValue) {
         this->SetHomeOutputDirectory(cachePath);
-        this->SetHomeDirectory(existingValue);
+        this->SetHomeDirectory(*existingValue);
         return;
       }
     }
@@ -1094,13 +1129,9 @@
 #if !defined(CMAKE_BOOTSTRAP)
   this->ExtraGenerators.push_back(cmExtraCodeBlocksGenerator::GetFactory());
   this->ExtraGenerators.push_back(cmExtraCodeLiteGenerator::GetFactory());
-  this->ExtraGenerators.push_back(cmExtraSublimeTextGenerator::GetFactory());
-  this->ExtraGenerators.push_back(cmExtraKateGenerator::GetFactory());
-
-#  ifdef CMAKE_USE_ECLIPSE
   this->ExtraGenerators.push_back(cmExtraEclipseCDT4Generator::GetFactory());
-#  endif
-
+  this->ExtraGenerators.push_back(cmExtraKateGenerator::GetFactory());
+  this->ExtraGenerators.push_back(cmExtraSublimeTextGenerator::GetFactory());
 #endif
 }
 
@@ -1340,7 +1371,7 @@
 
 int cmake::HandleDeleteCacheVariables(const std::string& var)
 {
-  std::vector<std::string> argsSplit = cmExpandedList(std::string(var), true);
+  std::vector<std::string> argsSplit = cmExpandedList(var, true);
   // erase the property to avoid infinite recursion
   this->State->SetGlobalProperty("__CMAKE_DELETE_CACHE_CHANGE_VARS_", "");
   if (this->State->GetIsInTryCompile()) {
@@ -1359,14 +1390,19 @@
     save.key = *i;
     warning << *i << "= ";
     i++;
-    save.value = *i;
-    warning << *i << "\n";
-    const char* existingValue = this->State->GetCacheEntryValue(save.key);
+    if (i != argsSplit.end()) {
+      save.value = *i;
+      warning << *i << "\n";
+    } else {
+      warning << "\n";
+      i -= 1;
+    }
+    cmProp existingValue = this->State->GetCacheEntryValue(save.key);
     if (existingValue) {
       save.type = this->State->GetCacheEntryType(save.key);
-      if (const char* help =
+      if (cmProp help =
             this->State->GetCacheEntryProperty(save.key, "HELPSTRING")) {
-        save.help = help;
+        save.help = *help;
       }
     }
     saved.push_back(std::move(save));
@@ -1411,9 +1447,9 @@
   if (this->DiagLevels.count("dev") == 1) {
     bool setDeprecatedVariables = false;
 
-    const char* cachedWarnDeprecated =
+    cmProp cachedWarnDeprecated =
       this->State->GetCacheEntryValue("CMAKE_WARN_DEPRECATED");
-    const char* cachedErrorDeprecated =
+    cmProp cachedErrorDeprecated =
       this->State->GetCacheEntryValue("CMAKE_ERROR_DEPRECATED");
 
     // don't overwrite deprecated warning setting from a previous invocation
@@ -1452,8 +1488,8 @@
   // Cache variables may have already been set by a previous invocation,
   // so we cannot rely on command line options alone. Always ensure our
   // messenger is in sync with the cache.
-  const char* value = this->State->GetCacheEntryValue("CMAKE_WARN_DEPRECATED");
-  this->Messenger->SetSuppressDeprecatedWarnings(value && cmIsOff(value));
+  cmProp value = this->State->GetCacheEntryValue("CMAKE_WARN_DEPRECATED");
+  this->Messenger->SetSuppressDeprecatedWarnings(value && cmIsOff(*value));
 
   value = this->State->GetCacheEntryValue("CMAKE_ERROR_DEPRECATED");
   this->Messenger->SetDeprecatedWarningsAsErrors(cmIsOn(value));
@@ -1462,13 +1498,13 @@
   this->Messenger->SetSuppressDevWarnings(cmIsOn(value));
 
   value = this->State->GetCacheEntryValue("CMAKE_SUPPRESS_DEVELOPER_ERRORS");
-  this->Messenger->SetDevWarningsAsErrors(value && cmIsOff(value));
+  this->Messenger->SetDevWarningsAsErrors(value && cmIsOff(*value));
 
   int ret = this->ActualConfigure();
-  const char* delCacheVars =
+  cmProp delCacheVars =
     this->State->GetGlobalProperty("__CMAKE_DELETE_CACHE_CHANGE_VARS_");
-  if (delCacheVars && delCacheVars[0] != 0) {
-    return this->HandleDeleteCacheVariables(delCacheVars);
+  if (delCacheVars && !delCacheVars->empty()) {
+    return this->HandleDeleteCacheVariables(*delCacheVars);
   }
   return ret;
 }
@@ -1493,9 +1529,8 @@
 
   // no generator specified on the command line
   if (!this->GlobalGenerator) {
-    const std::string* genName =
-      this->State->GetInitializedCacheValue("CMAKE_GENERATOR");
-    const std::string* extraGenName =
+    cmProp genName = this->State->GetInitializedCacheValue("CMAKE_GENERATOR");
+    cmProp extraGenName =
       this->State->GetInitializedCacheValue("CMAKE_EXTRA_GENERATOR");
     if (genName) {
       std::string fullName =
@@ -1518,8 +1553,7 @@
     }
   }
 
-  const std::string* genName =
-    this->State->GetInitializedCacheValue("CMAKE_GENERATOR");
+  cmProp genName = this->State->GetInitializedCacheValue("CMAKE_GENERATOR");
   if (genName) {
     if (!this->GlobalGenerator->MatchesGeneratorName(*genName)) {
       std::string message =
@@ -1541,7 +1575,7 @@
                         cmStateEnums::INTERNAL);
   }
 
-  if (const std::string* instance =
+  if (cmProp instance =
         this->State->GetInitializedCacheValue("CMAKE_GENERATOR_INSTANCE")) {
     if (this->GeneratorInstanceSet && this->GeneratorInstance != *instance) {
       std::string message =
@@ -1558,7 +1592,7 @@
       "Generator instance identifier.", cmStateEnums::INTERNAL);
   }
 
-  if (const std::string* platformName =
+  if (cmProp platformName =
         this->State->GetInitializedCacheValue("CMAKE_GENERATOR_PLATFORM")) {
     if (this->GeneratorPlatformSet &&
         this->GeneratorPlatform != *platformName) {
@@ -1576,7 +1610,7 @@
                         "Name of generator platform.", cmStateEnums::INTERNAL);
   }
 
-  if (const std::string* tsName =
+  if (cmProp tsName =
         this->State->GetInitializedCacheValue("CMAKE_GENERATOR_TOOLSET")) {
     if (this->GeneratorToolsetSet && this->GeneratorToolset != *tsName) {
       std::string message =
@@ -1891,13 +1925,13 @@
                              cmStateEnums::CacheEntryType(type));
   this->UnwatchUnusedCli(key);
 
-  if (key == "CMAKE_WARN_DEPRECATED") {
+  if (key == "CMAKE_WARN_DEPRECATED"_s) {
     this->Messenger->SetSuppressDeprecatedWarnings(value && cmIsOff(value));
-  } else if (key == "CMAKE_ERROR_DEPRECATED") {
+  } else if (key == "CMAKE_ERROR_DEPRECATED"_s) {
     this->Messenger->SetDeprecatedWarningsAsErrors(cmIsOn(value));
-  } else if (key == "CMAKE_SUPPRESS_DEVELOPER_WARNINGS") {
+  } else if (key == "CMAKE_SUPPRESS_DEVELOPER_WARNINGS"_s) {
     this->Messenger->SetSuppressDevWarnings(cmIsOn(value));
-  } else if (key == "CMAKE_SUPPRESS_DEVELOPER_ERRORS") {
+  } else if (key == "CMAKE_SUPPRESS_DEVELOPER_ERRORS"_s) {
     this->Messenger->SetDevWarningsAsErrors(value && cmIsOff(value));
   }
 }
@@ -1929,15 +1963,27 @@
                                  backtrace);
 }
 
+std::vector<std::string> cmake::GetAllExtensions() const
+{
+  std::vector<std::string> allExt = this->CLikeSourceFileExtensions.ordered;
+  allExt.insert(allExt.end(), this->HeaderFileExtensions.ordered.begin(),
+                this->HeaderFileExtensions.ordered.end());
+  // cuda extensions are also in SourceFileExtensions so we ignore it here
+  allExt.insert(allExt.end(), this->FortranFileExtensions.ordered.begin(),
+                this->FortranFileExtensions.ordered.end());
+  return allExt;
+}
+
 std::string cmake::StripExtension(const std::string& file) const
 {
   auto dotpos = file.rfind('.');
   if (dotpos != std::string::npos) {
-    auto ext = file.substr(dotpos + 1);
 #if defined(_WIN32) || defined(__APPLE__)
-    ext = cmSystemTools::LowerCase(ext);
+    auto ext = cmSystemTools::LowerCase(file.substr(dotpos + 1));
+#else
+    auto ext = cm::string_view(file).substr(dotpos + 1);
 #endif
-    if (this->IsSourceExtension(ext) || this->IsHeaderExtension(ext)) {
+    if (this->IsAKnownExtension(ext)) {
       return file.substr(0, dotpos);
     }
   }
@@ -1946,7 +1992,7 @@
 
 const char* cmake::GetCacheDefinition(const std::string& name) const
 {
-  const std::string* p = this->State->GetInitializedCacheValue(name);
+  cmProp p = this->State->GetInitializedCacheValue(name);
   return p ? p->c_str() : nullptr;
 }
 
@@ -2153,7 +2199,7 @@
 void cmake::UpdateConversionPathTable()
 {
   // Update the path conversion table with any specified file:
-  const std::string* tablepath =
+  cmProp tablepath =
     this->State->GetInitializedCacheValue("CMAKE_PATH_TRANSLATION_FILE");
 
   if (tablepath) {
@@ -2227,7 +2273,7 @@
   if (this->ClearBuildSystem) {
     // Get the generator used for this build system.
     const char* genName = mf.GetDefinition("CMAKE_DEPENDS_GENERATOR");
-    if (!genName || genName[0] == '\0') {
+    if (!cmNonempty(genName)) {
       genName = "Unix Makefiles";
     }
 
@@ -2244,9 +2290,7 @@
 
   // If any byproduct of makefile generation is missing we must re-run.
   std::vector<std::string> products;
-  if (const char* productStr = mf.GetDefinition("CMAKE_MAKEFILE_PRODUCTS")) {
-    cmExpandList(productStr, products);
-  }
+  mf.GetDefExpandList("CMAKE_MAKEFILE_PRODUCTS", products);
   for (std::string const& p : products) {
     if (!(cmSystemTools::FileExists(p) || cmSystemTools::FileIsSymlink(p))) {
       if (verbose) {
@@ -2261,11 +2305,8 @@
   // Get the set of dependencies and outputs.
   std::vector<std::string> depends;
   std::vector<std::string> outputs;
-  const char* dependsStr = mf.GetDefinition("CMAKE_MAKEFILE_DEPENDS");
-  const char* outputsStr = mf.GetDefinition("CMAKE_MAKEFILE_OUTPUTS");
-  if (dependsStr && outputsStr) {
-    cmExpandList(dependsStr, depends);
-    cmExpandList(outputsStr, outputs);
+  if (mf.GetDefExpandList("CMAKE_MAKEFILE_DEPENDS", depends)) {
+    mf.GetDefExpandList("CMAKE_MAKEFILE_OUTPUTS", outputs);
   }
   if (depends.empty() || outputs.empty()) {
     // Not enough information was provided to do the test.  Just rerun.
@@ -2383,7 +2424,7 @@
   this->State->AppendGlobalProperty(prop, value, asString);
 }
 
-const char* cmake::GetProperty(const std::string& prop)
+cmProp cmake::GetProperty(const std::string& prop)
 {
   return this->State->GetGlobalProperty(prop);
 }
@@ -2435,7 +2476,7 @@
   bool writeToStdout = true;
   for (unsigned int i = 1; i < args.size(); ++i) {
     std::string const& arg = args[i];
-    if (arg.find("-G", 0) == 0) {
+    if (cmHasLiteralPrefix(arg, "-G")) {
       std::string value = arg.substr(2);
       if (value.empty()) {
         ++i;
@@ -2624,10 +2665,10 @@
 std::vector<std::string> cmake::GetDebugConfigs()
 {
   std::vector<std::string> configs;
-  if (const char* config_list =
+  if (cmProp config_list =
         this->State->GetGlobalProperty("DEBUG_CONFIGURATIONS")) {
     // Expand the specified list and convert to upper-case.
-    cmExpandList(config_list, configs);
+    cmExpandList(*config_list, configs);
     std::transform(configs.begin(), configs.end(), configs.begin(),
                    cmSystemTools::UpperCase);
   }
@@ -2657,59 +2698,56 @@
     std::cerr << "Error: could not load cache\n";
     return 1;
   }
-  const char* cachedGenerator =
-    this->State->GetCacheEntryValue("CMAKE_GENERATOR");
+  cmProp cachedGenerator = this->State->GetCacheEntryValue("CMAKE_GENERATOR");
   if (!cachedGenerator) {
     std::cerr << "Error: could not find CMAKE_GENERATOR in Cache\n";
     return 1;
   }
-  auto gen = this->CreateGlobalGenerator(cachedGenerator);
+  auto gen = this->CreateGlobalGenerator(*cachedGenerator);
   if (!gen) {
-    std::cerr << "Error: could create CMAKE_GENERATOR \"" << cachedGenerator
+    std::cerr << "Error: could create CMAKE_GENERATOR \"" << *cachedGenerator
               << "\"\n";
     return 1;
   }
   this->SetGlobalGenerator(std::move(gen));
-  const char* cachedGeneratorInstance =
+  cmProp cachedGeneratorInstance =
     this->State->GetCacheEntryValue("CMAKE_GENERATOR_INSTANCE");
   if (cachedGeneratorInstance) {
     cmMakefile mf(this->GetGlobalGenerator(), this->GetCurrentSnapshot());
-    if (!this->GlobalGenerator->SetGeneratorInstance(cachedGeneratorInstance,
+    if (!this->GlobalGenerator->SetGeneratorInstance(*cachedGeneratorInstance,
                                                      &mf)) {
       return 1;
     }
   }
-  const char* cachedGeneratorPlatform =
+  cmProp cachedGeneratorPlatform =
     this->State->GetCacheEntryValue("CMAKE_GENERATOR_PLATFORM");
   if (cachedGeneratorPlatform) {
     cmMakefile mf(this->GetGlobalGenerator(), this->GetCurrentSnapshot());
-    if (!this->GlobalGenerator->SetGeneratorPlatform(cachedGeneratorPlatform,
+    if (!this->GlobalGenerator->SetGeneratorPlatform(*cachedGeneratorPlatform,
                                                      &mf)) {
       return 1;
     }
   }
-  const char* cachedGeneratorToolset =
+  cmProp cachedGeneratorToolset =
     this->State->GetCacheEntryValue("CMAKE_GENERATOR_TOOLSET");
   if (cachedGeneratorToolset) {
     cmMakefile mf(this->GetGlobalGenerator(), this->GetCurrentSnapshot());
-    if (!this->GlobalGenerator->SetGeneratorToolset(cachedGeneratorToolset,
+    if (!this->GlobalGenerator->SetGeneratorToolset(*cachedGeneratorToolset,
                                                     true, &mf)) {
       return 1;
     }
   }
   std::string output;
   std::string projName;
-  const char* cachedProjectName =
+  cmProp cachedProjectName =
     this->State->GetCacheEntryValue("CMAKE_PROJECT_NAME");
   if (!cachedProjectName) {
     std::cerr << "Error: could not find CMAKE_PROJECT_NAME in Cache\n";
     return 1;
   }
-  projName = cachedProjectName;
+  projName = *cachedProjectName;
 
-  const char* cachedVerbose =
-    this->State->GetCacheEntryValue("CMAKE_VERBOSE_MAKEFILE");
-  if (cmIsOn(cachedVerbose)) {
+  if (cmIsOn(this->State->GetCacheEntryValue("CMAKE_VERBOSE_MAKEFILE"))) {
     verbose = true;
   }
 
@@ -2793,16 +2831,16 @@
     std::cerr << "Error: could not load cache\n";
     return false;
   }
-  const char* genName = this->State->GetCacheEntryValue("CMAKE_GENERATOR");
+  cmProp genName = this->State->GetCacheEntryValue("CMAKE_GENERATOR");
   if (!genName) {
     std::cerr << "Error: could not find CMAKE_GENERATOR in Cache\n";
     return false;
   }
-  const std::string* extraGenName =
+  cmProp extraGenName =
     this->State->GetInitializedCacheValue("CMAKE_EXTRA_GENERATOR");
   std::string fullName =
     cmExternalMakefileProjectGenerator::CreateFullGeneratorName(
-      genName, extraGenName ? *extraGenName : "");
+      *genName, extraGenName ? *extraGenName : "");
 
   std::unique_ptr<cmGlobalGenerator> gen =
     this->CreateGlobalGenerator(fullName);
@@ -2812,21 +2850,21 @@
     return false;
   }
 
-  const char* cachedProjectName =
+  cmProp cachedProjectName =
     this->State->GetCacheEntryValue("CMAKE_PROJECT_NAME");
   if (!cachedProjectName) {
     std::cerr << "Error: could not find CMAKE_PROJECT_NAME in Cache\n";
     return false;
   }
 
-  return gen->Open(dir, cachedProjectName, dryRun);
+  return gen->Open(dir, *cachedProjectName, dryRun);
 }
 
 void cmake::WatchUnusedCli(const std::string& var)
 {
 #ifndef CMAKE_BOOTSTRAP
   this->VariableWatch->AddWatch(var, cmWarnUnusedCliWarning, this);
-  if (!cmContains(this->UsedCliVariables, var)) {
+  if (!cm::contains(this->UsedCliVariables, var)) {
     this->UsedCliVariables[var] = false;
   }
 #endif
@@ -2953,3 +2991,15 @@
                       " and functions.",
                       cmStateEnums::INTERNAL);
 }
+
+#if !defined(CMAKE_BOOTSTRAP)
+cmMakefileProfilingData& cmake::GetProfilingOutput()
+{
+  return *(this->ProfilingOutput);
+}
+
+bool cmake::IsProfilingEnabled() const
+{
+  return static_cast<bool>(this->ProfilingOutput);
+}
+#endif
diff --git a/Source/cmake.h b/Source/cmake.h
index 35425ec..0c4f429 100644
--- a/Source/cmake.h
+++ b/Source/cmake.h
@@ -16,16 +16,19 @@
 #include <utility>
 #include <vector>
 
+#include <cm/string_view>
+
 #include "cmGeneratedFileStream.h"
 #include "cmInstalledFile.h"
 #include "cmListFileCache.h"
 #include "cmMessageType.h"
+#include "cmProperty.h"
 #include "cmState.h"
 #include "cmStateSnapshot.h"
 #include "cmStateTypes.h"
 
 #if !defined(CMAKE_BOOTSTRAP)
-#  include "cm_jsoncpp_value.h"
+#  include <cm3p/json/value.h>
 #endif
 
 class cmExternalMakefileProjectGeneratorFactory;
@@ -34,6 +37,9 @@
 class cmGlobalGenerator;
 class cmGlobalGeneratorFactory;
 class cmMakefile;
+#if !defined(CMAKE_BOOTSTRAP)
+class cmMakefileProfilingData;
+#endif
 class cmMessenger;
 class cmVariableWatch;
 struct cmDocumentationEntry;
@@ -135,13 +141,13 @@
 
   struct FileExtensions
   {
-    bool Test(std::string const& ext) const
+    bool Test(cm::string_view ext) const
     {
       return (this->unordered.find(ext) != this->unordered.end());
     }
 
     std::vector<std::string> ordered;
-    std::unordered_set<std::string> unordered;
+    std::unordered_set<cm::string_view> unordered;
   };
 
   using InstalledFilesMap = std::map<std::string, cmInstalledFile>;
@@ -258,46 +264,35 @@
     this->GeneratorToolsetSet = true;
   }
 
-  const std::vector<std::string>& GetSourceExtensions() const
+  bool IsAKnownSourceExtension(cm::string_view ext) const
   {
-    return this->SourceFileExtensions.ordered;
+    return this->CLikeSourceFileExtensions.Test(ext) ||
+      this->CudaFileExtensions.Test(ext) ||
+      this->FortranFileExtensions.Test(ext);
   }
 
-  bool IsSourceExtension(const std::string& ext) const
+  bool IsACLikeSourceExtension(cm::string_view ext) const
   {
-    return this->SourceFileExtensions.Test(ext);
+    return this->CLikeSourceFileExtensions.Test(ext);
   }
 
+  bool IsAKnownExtension(cm::string_view ext) const
+  {
+    return this->IsAKnownSourceExtension(ext) || this->IsAHeaderExtension(ext);
+  }
+
+  std::vector<std::string> GetAllExtensions() const;
+
   const std::vector<std::string>& GetHeaderExtensions() const
   {
     return this->HeaderFileExtensions.ordered;
   }
 
-  bool IsHeaderExtension(const std::string& ext) const
+  bool IsAHeaderExtension(cm::string_view ext) const
   {
     return this->HeaderFileExtensions.Test(ext);
   }
 
-  const std::vector<std::string>& GetCudaExtensions() const
-  {
-    return this->CudaFileExtensions.ordered;
-  }
-
-  bool IsCudaExtension(const std::string& ext) const
-  {
-    return this->CudaFileExtensions.Test(ext);
-  }
-
-  const std::vector<std::string>& GetFortranExtensions() const
-  {
-    return this->FortranFileExtensions.ordered;
-  }
-
-  bool IsFortranExtension(const std::string& ext) const
-  {
-    return this->FortranFileExtensions.Test(ext);
-  }
-
   // Strips the extension (if present and known) from a filename
   std::string StripExtension(const std::string& file) const;
 
@@ -361,7 +356,7 @@
   void SetProperty(const std::string& prop, const char* value);
   void AppendProperty(const std::string& prop, const std::string& value,
                       bool asString = false);
-  const char* GetProperty(const std::string& prop);
+  cmProp GetProperty(const std::string& prop);
   bool GetPropertyAsBool(const std::string& prop);
 
   //! Get or create an cmInstalledFile instance and return a pointer to it
@@ -455,8 +450,6 @@
 
   bool GetWarnUninitialized() { return this->WarnUninitialized; }
   void SetWarnUninitialized(bool b) { this->WarnUninitialized = b; }
-  bool GetWarnUnused() { return this->WarnUnused; }
-  void SetWarnUnused(bool b) { this->WarnUnused = b; }
   bool GetWarnUnusedCli() { return this->WarnUnusedCli; }
   void SetWarnUnusedCli(bool b) { this->WarnUnusedCli = b; }
   bool GetCheckSystemVars() { return this->CheckSystemVars; }
@@ -549,6 +542,11 @@
 
   bool GetRegenerateDuringBuild() const { return this->RegenerateDuringBuild; }
 
+#if !defined(CMAKE_BOOTSTRAP)
+  cmMakefileProfilingData& GetProfilingOutput();
+  bool IsProfilingEnabled() const;
+#endif
+
 protected:
   void RunCheckForUnusedVariables();
   int HandleDeleteCacheVariables(const std::string& var);
@@ -605,7 +603,6 @@
   TraceFormat TraceFormatVar = TRACE_HUMAN;
   cmGeneratedFileStream TraceFile;
   bool WarnUninitialized = false;
-  bool WarnUnused = false;
   bool WarnUnusedCli = true;
   bool CheckSystemVars = false;
   std::map<std::string, bool> UsedCliVariables;
@@ -617,7 +614,7 @@
   std::string CheckStampList;
   std::string VSSolutionFile;
   std::string EnvironmentGenerator;
-  FileExtensions SourceFileExtensions;
+  FileExtensions CLikeSourceFileExtensions;
   FileExtensions HeaderFileExtensions;
   FileExtensions CudaFileExtensions;
   FileExtensions FortranFileExtensions;
@@ -657,6 +654,10 @@
 
   void AppendGlobalGeneratorsDocumentation(std::vector<cmDocumentationEntry>&);
   void AppendExtraGeneratorsDocumentation(std::vector<cmDocumentationEntry>&);
+
+#if !defined(CMAKE_BOOTSTRAP)
+  std::unique_ptr<cmMakefileProfilingData> ProfilingOutput;
+#endif
 };
 
 #define CMAKE_STANDARD_OPTIONS_TABLE                                          \
diff --git a/Source/cmakemain.cxx b/Source/cmakemain.cxx
index 494d5d9..4600fc5 100644
--- a/Source/cmakemain.cxx
+++ b/Source/cmakemain.cxx
@@ -1,19 +1,26 @@
 /* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
    file Copyright.txt or https://cmake.org/licensing for details.  */
 
+#include "cmConfigure.h" // IWYU pragma: keep
+
+#include <algorithm>
 #include <cassert>
 #include <cctype>
 #include <climits>
 #include <cstring>
 #include <iostream>
+#include <sstream>
 #include <string>
 #include <vector>
 
 #include <cmext/algorithm>
 
+#include <cm3p/uv.h>
+
 #include "cmDocumentationEntry.h" // IWYU pragma: keep
 #include "cmGlobalGenerator.h"
 #include "cmMakefile.h"
+#include "cmProperty.h"
 #include "cmState.h"
 #include "cmStateTypes.h"
 #include "cmStringAlgorithms.h"
@@ -27,8 +34,6 @@
 #endif
 
 #include "cmsys/Encoding.hxx"
-
-#include "cm_uv.h"
 #if defined(_WIN32) && !defined(CMAKE_BOOTSTRAP)
 #  include "cmsys/ConsoleBuf.hxx"
 #endif
@@ -66,7 +71,7 @@
   { "--open <dir>", "Open generated project in the associated application." },
   { "-N", "View mode only." },
   { "-P <file>", "Process script mode." },
-  { "--find-package", "Run in pkg-config like mode." },
+  { "--find-package", "Legacy pkg-config like mode.  Do not use." },
   { "--graphviz=[file]",
     "Generate graphviz of dependencies, see "
     "CMakeGraphVizOptions.cmake for more." },
@@ -88,11 +93,18 @@
   { "--trace-redirect=<file>",
     "Redirect trace output to a file instead of stderr." },
   { "--warn-uninitialized", "Warn about uninitialized values." },
-  { "--warn-unused-vars", "Warn about unused variables." },
   { "--no-warn-unused-cli", "Don't warn about command line options." },
   { "--check-system-vars",
     "Find problems with variable usage in system "
     "files." },
+#  if !defined(CMAKE_BOOTSTRAP)
+  { "--profiling-format=<fmt>",
+    "Output data for profiling CMake scripts. Supported formats: "
+    "google-trace" },
+  { "--profiling-output=<file>",
+    "Select an output path for the profiling data enabled through "
+    "--profiling-format." },
+#  endif
   { nullptr, nullptr }
 };
 
@@ -286,16 +298,16 @@
       cmStateEnums::CacheEntryType t = cm.GetState()->GetCacheEntryType(k);
       if (t != cmStateEnums::INTERNAL && t != cmStateEnums::STATIC &&
           t != cmStateEnums::UNINITIALIZED) {
-        const char* advancedProp =
+        cmProp advancedProp =
           cm.GetState()->GetCacheEntryProperty(k, "ADVANCED");
         if (list_all_cached || !advancedProp) {
           if (list_help) {
-            std::cout << "// "
-                      << cm.GetState()->GetCacheEntryProperty(k, "HELPSTRING")
-                      << std::endl;
+            cmProp help =
+              cm.GetState()->GetCacheEntryProperty(k, "HELPSTRING");
+            std::cout << "// " << (help ? *help : "") << std::endl;
           }
           std::cout << k << ":" << cmState::CacheEntryTypeToString(t) << "="
-                    << cm.GetState()->GetCacheEntryValue(k) << std::endl;
+                    << cm.GetState()->GetSafeCacheEntryValue(k) << std::endl;
           if (list_help) {
             std::cout << std::endl;
           }
@@ -312,6 +324,7 @@
   return 0;
 }
 
+#ifndef CMAKE_BOOTSTRAP
 int extract_job_number(int& index, char const* current, char const* next,
                        int len_of_flag)
 {
@@ -341,6 +354,7 @@
   }
   return jobs;
 }
+#endif
 
 int do_build(int ac, char const* const* av)
 {
@@ -506,6 +520,121 @@
 #endif
 }
 
+bool parse_default_directory_permissions(const std::string& permissions,
+                                         std::string& parsedPermissionsVar)
+{
+  std::vector<std::string> parsedPermissions;
+  enum Doing
+  {
+    DoingNone,
+    DoingOwner,
+    DoingGroup,
+    DoingWorld,
+    DoingOwnerAssignment,
+    DoingGroupAssignment,
+    DoingWorldAssignment,
+  };
+  Doing doing = DoingNone;
+
+  auto uniquePushBack = [&parsedPermissions](const std::string& e) {
+    if (std::find(parsedPermissions.begin(), parsedPermissions.end(), e) ==
+        parsedPermissions.end()) {
+      parsedPermissions.push_back(e);
+    }
+  };
+
+  for (auto const& e : permissions) {
+    switch (doing) {
+      case DoingNone:
+        if (e == 'u') {
+          doing = DoingOwner;
+        } else if (e == 'g') {
+          doing = DoingGroup;
+        } else if (e == 'o') {
+          doing = DoingWorld;
+        } else {
+          return false;
+        }
+        break;
+      case DoingOwner:
+        if (e == '=') {
+          doing = DoingOwnerAssignment;
+        } else {
+          return false;
+        }
+        break;
+      case DoingGroup:
+        if (e == '=') {
+          doing = DoingGroupAssignment;
+        } else {
+          return false;
+        }
+        break;
+      case DoingWorld:
+        if (e == '=') {
+          doing = DoingWorldAssignment;
+        } else {
+          return false;
+        }
+        break;
+      case DoingOwnerAssignment:
+        if (e == 'r') {
+          uniquePushBack("OWNER_READ");
+        } else if (e == 'w') {
+          uniquePushBack("OWNER_WRITE");
+        } else if (e == 'x') {
+          uniquePushBack("OWNER_EXECUTE");
+        } else if (e == ',') {
+          doing = DoingNone;
+        } else {
+          return false;
+        }
+        break;
+      case DoingGroupAssignment:
+        if (e == 'r') {
+          uniquePushBack("GROUP_READ");
+        } else if (e == 'w') {
+          uniquePushBack("GROUP_WRITE");
+        } else if (e == 'x') {
+          uniquePushBack("GROUP_EXECUTE");
+        } else if (e == ',') {
+          doing = DoingNone;
+        } else {
+          return false;
+        }
+        break;
+      case DoingWorldAssignment:
+        if (e == 'r') {
+          uniquePushBack("WORLD_READ");
+        } else if (e == 'w') {
+          uniquePushBack("WORLD_WRITE");
+        } else if (e == 'x') {
+          uniquePushBack("WORLD_EXECUTE");
+        } else if (e == ',') {
+          doing = DoingNone;
+        } else {
+          return false;
+        }
+        break;
+    }
+  }
+  if (doing != DoingOwnerAssignment && doing != DoingGroupAssignment &&
+      doing != DoingWorldAssignment) {
+    return false;
+  }
+
+  std::ostringstream oss;
+  for (auto i = 0u; i < parsedPermissions.size(); i++) {
+    if (i != 0) {
+      oss << ";";
+    }
+    oss << parsedPermissions[i];
+  }
+
+  parsedPermissionsVar = oss.str();
+  return true;
+}
+
 int do_install(int ac, char const* const* av)
 {
 #ifdef CMAKE_BOOTSTRAP
@@ -516,6 +645,7 @@
 
   std::string config;
   std::string component;
+  std::string defaultDirectoryPermissions;
   std::string prefix;
   std::string dir;
   bool strip = false;
@@ -528,6 +658,7 @@
     DoingConfig,
     DoingComponent,
     DoingPrefix,
+    DoingDefaultDirectoryPermissions,
   };
 
   Doing doing = DoingDir;
@@ -546,6 +677,8 @@
                (strcmp(av[i], "-v") == 0)) {
       verbose = true;
       doing = DoingNone;
+    } else if (strcmp(av[i], "--default-directory-permissions") == 0) {
+      doing = DoingDefaultDirectoryPermissions;
     } else {
       switch (doing) {
         case DoingDir:
@@ -564,6 +697,10 @@
           prefix = av[i];
           doing = DoingNone;
           break;
+        case DoingDefaultDirectoryPermissions:
+          defaultDirectoryPermissions = av[i];
+          doing = DoingNone;
+          break;
         default:
           std::cerr << "Unknown argument " << av[i] << std::endl;
           dir.clear();
@@ -580,6 +717,8 @@
       "  <dir>              = Project binary directory to install.\n"
       "  --config <cfg>     = For multi-configuration tools, choose <cfg>.\n"
       "  --component <comp> = Component-based install. Only install <comp>.\n"
+      "  --default-directory-permissions <permission> \n"
+      "     Default install permission. Use default permission <permission>.\n"
       "  --prefix <prefix>  = The installation prefix CMAKE_INSTALL_PREFIX.\n"
       "  --strip            = Performing install/strip.\n"
       "  -v --verbose       = Enable verbose output.\n"
@@ -620,6 +759,18 @@
     args.emplace_back("-DCMAKE_INSTALL_CONFIG_NAME=" + config);
   }
 
+  if (!defaultDirectoryPermissions.empty()) {
+    std::string parsedPermissionsVar;
+    if (!parse_default_directory_permissions(defaultDirectoryPermissions,
+                                             parsedPermissionsVar)) {
+      std::cerr << "--default-directory-permissions is in incorrect format"
+                << std::endl;
+      return 1;
+    }
+    args.emplace_back("-DCMAKE_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS=" +
+                      parsedPermissionsVar);
+  }
+
   args.emplace_back("-P");
   args.emplace_back(dir + "/cmake_install.cmake");
 
@@ -706,6 +857,8 @@
 #ifndef CMAKE_BOOTSTRAP
   cmDynamicLoader::FlushCache();
 #endif
-  uv_loop_close(uv_default_loop());
+  if (uv_loop_t* loop = uv_default_loop()) {
+    uv_loop_close(loop);
+  }
   return ret;
 }
diff --git a/Source/cmcldeps.cxx b/Source/cmcldeps.cxx
index caf6453..5c27ac1 100644
--- a/Source/cmcldeps.cxx
+++ b/Source/cmcldeps.cxx
@@ -25,6 +25,7 @@
 
 #include "cmsys/Encoding.hxx"
 
+#include "cmStringAlgorithms.h"
 #include "cmSystemTools.h"
 
 // We don't want any wildcard expansion.
@@ -63,7 +64,7 @@
         msg);
 }
 
-static std::string trimLeadingSpace(const std::string& cmdline)
+static cm::string_view trimLeadingSpace(cm::string_view cmdline)
 {
   int i = 0;
   for (; cmdline[i] == ' '; ++i)
@@ -81,34 +82,30 @@
   }
 }
 
-bool startsWith(const std::string& str, const std::string& what)
-{
-  return str.compare(0, what.size(), what) == 0;
-}
-
 // Strips one argument from the cmdline and returns it. "surrounding quotes"
 // are removed from the argument if there were any.
 static std::string getArg(std::string& cmdline)
 {
-  std::string ret;
   bool in_quoted = false;
   unsigned int i = 0;
 
-  cmdline = trimLeadingSpace(cmdline);
+  cm::string_view cmdview = trimLeadingSpace(cmdline);
+  size_t spaceCnt = cmdline.size() - cmdview.size();
 
   for (;; ++i) {
-    if (i >= cmdline.size())
+    if (i >= cmdview.size())
       usage("Couldn't parse arguments.");
-    if (!in_quoted && cmdline[i] == ' ')
+    if (!in_quoted && cmdview[i] == ' ')
       break; // "a b" "x y"
-    if (cmdline[i] == '"')
+    if (cmdview[i] == '"')
       in_quoted = !in_quoted;
   }
 
-  ret = cmdline.substr(0, i);
-  if (ret[0] == '"' && ret[i - 1] == '"')
-    ret = ret.substr(1, ret.size() - 2);
-  cmdline = cmdline.substr(i);
+  cmdview = cmdview.substr(0, i);
+  if (cmdview[0] == '"' && cmdview[i - 1] == '"')
+    cmdview = cmdview.substr(1, i - 2);
+  std::string ret(cmdview);
+  cmdline.erase(0, spaceCnt + i);
   return ret;
 }
 
@@ -127,7 +124,7 @@
   prefix = getArg(cmdline);
   clpath = getArg(cmdline);
   binpath = getArg(cmdline);
-  rest = trimLeadingSpace(cmdline);
+  rest = std::string(trimLeadingSpace(cmdline));
 }
 
 // Not all backslashes need to be escaped in a depfile, but it's easier that
@@ -169,8 +166,8 @@
     // build.ninja file.  Therefore we need to canonicalize the path to use
     // backward slashes and relativize the path to the build directory.
     replaceAll(tmp, "/", "\\");
-    if (startsWith(tmp, cwd))
-      tmp = tmp.substr(cwd.size());
+    if (cmHasPrefix(tmp, cwd))
+      tmp.erase(0, cwd.size());
     escapePath(tmp);
     fprintf(out, "%s \\\n", tmp.c_str());
   }
@@ -194,7 +191,7 @@
   return replaced.replace(pos, what.size(), replacement);
 }
 
-static int process(const std::string& srcfilename, const std::string& dfile,
+static int process(cm::string_view srcfilename, const std::string& dfile,
                    const std::string& objfile, const std::string& prefix,
                    const std::string& cmd, const std::string& dir = "",
                    bool quiet = false)
@@ -221,13 +218,14 @@
   std::vector<std::string> includes;
   bool isFirstLine = true; // cl prints always first the source filename
   while (std::getline(ss, line)) {
-    if (startsWith(line, prefix)) {
-      std::string inc = trimLeadingSpace(line.substr(prefix.size()).c_str());
+    cm::string_view inc(line);
+    if (cmHasPrefix(inc, prefix)) {
+      inc = trimLeadingSpace(inc.substr(prefix.size()));
       if (inc.back() == '\r') // blech, stupid \r\n
         inc = inc.substr(0, inc.size() - 1);
-      includes.push_back(inc);
+      includes.emplace_back(std::string(inc));
     } else {
-      if (!isFirstLine || !startsWith(line, srcfilename)) {
+      if (!isFirstLine || !cmHasPrefix(inc, srcfilename)) {
         if (!quiet || exit_code != 0) {
           fprintf(stdout, "%s\n", line.c_str());
         }
@@ -258,14 +256,10 @@
                    cl, binpath, rest);
 
   // needed to suppress filename output of msvc tools
-  std::string srcfilename;
-  {
-    std::string::size_type pos = srcfile.rfind('\\');
-    if (pos == std::string::npos) {
-      srcfilename = srcfile;
-    } else {
-      srcfilename = srcfile.substr(pos + 1);
-    }
+  cm::string_view srcfilename(srcfile);
+  std::string::size_type pos = srcfile.rfind('\\');
+  if (pos != std::string::npos) {
+    srcfilename = srcfilename.substr(pos + 1);
   }
 
   std::string nol = " /nologo ";
@@ -286,7 +280,7 @@
     // call cl in object dir so the .i is generated there
     std::string objdir;
     {
-      std::string::size_type pos = objfile.rfind("\\");
+      pos = objfile.rfind("\\");
       if (pos != std::string::npos) {
         objdir = objfile.substr(0, pos);
       }
diff --git a/Source/cmcmd.cxx b/Source/cmcmd.cxx
index 2b8ea24..a1c6771 100644
--- a/Source/cmcmd.cxx
+++ b/Source/cmcmd.cxx
@@ -4,11 +4,9 @@
 
 #include <cmext/algorithm>
 
+#include <cm3p/uv.h>
 #include <fcntl.h>
 
-#include "cm_uv.h"
-
-#include "cmAlgorithms.h"
 #include "cmDuration.h"
 #include "cmGlobalGenerator.h"
 #include "cmLocalGenerator.h"
@@ -90,6 +88,7 @@
     << "Available commands: \n"
     << "  capabilities              - Report capabilities built into cmake "
        "in JSON format\n"
+    << "  cat <files>...            - concat the files and print them to the standard output\n"
     << "  chdir dir cmd [args...]   - run command in a given directory\n"
     << "  compare_files [--ignore-eol] file1 file2\n"
     << "                              - check if file1 is same as file2\n"
@@ -127,6 +126,7 @@
     << "  touch <file>...           - touch a <file>.\n"
     << "  touch_nocreate <file>...  - touch a <file> but do not create it.\n"
     << "  create_symlink old new    - create a symbolic link new -> old\n"
+    << "  create_hardlink old new   - create a hard link new -> old\n"
     << "  true                      - do nothing with an exit code of 0\n"
     << "  false                     - do nothing with an exit code of 1\n"
 #if defined(_WIN32) && !defined(__CYGWIN__)
@@ -180,6 +180,13 @@
   return true;
 }
 
+static void cmCatFile(const std::string& fileToAppend)
+{
+  cmsys::ifstream source(fileToAppend.c_str(),
+                         (std::ios::binary | std::ios::in));
+  std::cout << source.rdbuf();
+}
+
 static bool cmRemoveDirectory(const std::string& dir, bool recursive = true)
 {
   if (cmSystemTools::FileIsSymlink(dir)) {
@@ -576,12 +583,10 @@
         filesDiffer = cmsys::SystemTools::TextFilesDiffer(args[3], args[4]);
       } else {
         ::CMakeCommandUsage(args[0].c_str());
-        return 1;
+        return 2;
       }
 
       if (filesDiffer) {
-        std::cerr << "Files \"" << args[args.size() - 2] << "\" to \""
-                  << args[args.size() - 1] << "\" are different.\n";
         return 1;
       }
       return 0;
@@ -596,8 +601,7 @@
       }
       cmsys::ifstream fin(args[3].c_str(), std::ios::in | std::ios::binary);
       if (!fin) {
-        std::cerr << "could not open object list file: " << args[3].c_str()
-                  << "\n";
+        std::cerr << "could not open object list file: " << args[3] << "\n";
         return 1;
       }
       std::vector<std::string> files;
@@ -620,13 +624,12 @@
       }
       FILE* fout = cmsys::SystemTools::Fopen(args[2], "w+");
       if (!fout) {
-        std::cerr << "could not open output .def file: " << args[2].c_str()
-                  << "\n";
+        std::cerr << "could not open output .def file: " << args[2] << "\n";
         return 1;
       }
       bindexplib deffile;
       if (args.size() >= 5) {
-        auto a = args[4];
+        std::string const& a = args[4];
         if (cmHasLiteralPrefix(a, "--nm=")) {
           deffile.SetNmPath(a.substr(5));
           std::cerr << a.substr(5) << "\n";
@@ -634,7 +637,7 @@
           std::cerr << "unknown argument: " << a << "\n";
         }
       }
-      for (auto const& file : files) {
+      for (std::string const& file : files) {
         std::string const& ext = cmSystemTools::GetFilenameLastExtension(file);
         if (cmSystemTools::LowerCase(ext) == ".def") {
           if (!deffile.AddDefinitionFile(file.c_str())) {
@@ -678,7 +681,7 @@
         } else if (!a.empty() && a[0] == '-') {
           // Environment variable and command names cannot start in '-',
           // so this must be an unknown option.
-          std::cerr << "cmake -E env: unknown option '" << a << "'"
+          std::cerr << "cmake -E env: unknown option '" << a << '\''
                     << std::endl;
           return 1;
         } else if (a.find('=') != std::string::npos) {
@@ -927,6 +930,33 @@
       return HashSumFile(args, cmCryptoHash::AlgoSHA512);
     }
 
+    // Command to concat files into one
+    if (args[1] == "cat" && args.size() >= 3) {
+      int return_value = 0;
+      for (auto const& arg : cmMakeRange(args).advance(2)) {
+        if (cmHasLiteralPrefix(arg, "-")) {
+          if (arg != "--") {
+            cmSystemTools::Error(arg + ": option not handled");
+            return_value = 1;
+          }
+        } else if (!cmSystemTools::TestFileAccess(arg,
+                                                  cmsys::TEST_FILE_READ) &&
+                   cmSystemTools::TestFileAccess(arg, cmsys::TEST_FILE_OK)) {
+          cmSystemTools::Error(arg + ": permission denied (ignoring)");
+          return_value = 1;
+        } else if (cmSystemTools::FileIsDirectory(arg)) {
+          cmSystemTools::Error(arg + ": is a directory (ignoring)");
+          return_value = 1;
+        } else if (!cmSystemTools::FileExists(arg)) {
+          cmSystemTools::Error(arg + ": no such file or directory (ignoring)");
+          return_value = 1;
+        } else {
+          cmCatFile(arg);
+        }
+      }
+      return return_value;
+    }
+
     // Command to change directory and run a program.
     if (args[1] == "chdir" && args.size() >= 4) {
       std::string const& directory = args[2];
@@ -989,7 +1019,7 @@
     // Command to create a symbolic link.  Fails on platforms not
     // supporting them.
     if (args[1] == "create_symlink" && args.size() == 4) {
-      const char* destinationFileName = args[3].c_str();
+      std::string const& destinationFileName = args[3];
       if ((cmSystemTools::FileExists(destinationFileName) ||
            cmSystemTools::FileIsSymlink(destinationFileName)) &&
           !cmSystemTools::RemoveFile(destinationFileName)) {
@@ -1005,6 +1035,34 @@
       return 0;
     }
 
+    // Command to create a hard link.  Fails on platforms not
+    // supporting them.
+    if (args[1] == "create_hardlink" && args.size() == 4) {
+      const char* SouceFileName = args[2].c_str();
+      const char* destinationFileName = args[3].c_str();
+
+      if (!cmSystemTools::FileExists(SouceFileName)) {
+        std::cerr << "failed to create hard link because source path '"
+                  << SouceFileName << "' does not exist \n";
+        return 1;
+      }
+
+      if ((cmSystemTools::FileExists(destinationFileName) ||
+           cmSystemTools::FileIsSymlink(destinationFileName)) &&
+          !cmSystemTools::RemoveFile(destinationFileName)) {
+        std::string emsg = cmSystemTools::GetLastSystemError();
+        std::cerr << "failed to create hard link '" << destinationFileName
+                  << "' because existing path cannot be removed: " << emsg
+                  << "\n";
+        return 1;
+      }
+
+      if (!cmSystemTools::CreateLink(args[2], args[3])) {
+        return 1;
+      }
+      return 0;
+    }
+
     // Command to do nothing with an exit code of 0.
     if (args[1] == "true") {
       return 0;
@@ -1054,8 +1112,7 @@
         homeOutDir = args[5];
         startOutDir = args[6];
         depInfo = args[7];
-        if (args.size() >= 9 && args[8].length() >= 8 &&
-            args[8].substr(0, 8) == "--color=") {
+        if (args.size() >= 9 && cmHasLiteralPrefix(args[8], "--color=")) {
           // Enable or disable color based on the switch value.
           color = (args[8].size() == 8 || cmIsOn(args[8].substr(8)));
         }
@@ -1186,7 +1243,7 @@
             }
           } else if (cmHasLiteralPrefix(arg, "--format=")) {
             format = arg.substr(9);
-            if (!cmContains(knownFormats, format)) {
+            if (!cm::contains(knownFormats, format)) {
               cmSystemTools::Error("Unknown -E tar --format= argument: " +
                                    format);
               return 1;
@@ -1304,7 +1361,7 @@
         } else if (arg == "--debug") {
           pipe.clear();
           isDebug = true;
-        } else if (arg.substr(0, pipePrefix.size()) == pipePrefix) {
+        } else if (cmHasPrefix(arg, pipePrefix)) {
           isDebug = false;
           pipe = arg.substr(pipePrefix.size());
           if (pipe.empty()) {
@@ -1347,15 +1404,12 @@
 #if defined(_WIN32) && !defined(__CYGWIN__)
     // Write registry value
     if (args[1] == "write_regv" && args.size() > 3) {
-      return cmSystemTools::WriteRegistryValue(args[2].c_str(),
-                                               args[3].c_str())
-        ? 0
-        : 1;
+      return cmSystemTools::WriteRegistryValue(args[2], args[3]) ? 0 : 1;
     }
 
     // Delete registry value
     if (args[1] == "delete_regv" && args.size() > 2) {
-      return cmSystemTools::DeleteRegistryValue(args[2].c_str()) ? 0 : 1;
+      return cmSystemTools::DeleteRegistryValue(args[2]) ? 0 : 1;
     }
 
     // Remove file
@@ -1511,7 +1565,7 @@
   bool newline = true;
   std::string progressDir;
   for (auto const& arg : cmMakeRange(args).advance(2)) {
-    if (arg.find("--switch=") == 0) {
+    if (cmHasLiteralPrefix(arg, "--switch=")) {
       // Enable or disable color based on the switch value.
       std::string value = arg.substr(9);
       if (!value.empty()) {
@@ -1566,7 +1620,7 @@
   //   args[3] == --verbose=?
   bool verbose = false;
   if (args.size() >= 4) {
-    if (args[3].find("--verbose=") == 0) {
+    if (cmHasLiteralPrefix(args[3], "--verbose=")) {
       if (!cmIsOff(args[3].substr(10))) {
         verbose = true;
       }
@@ -1654,11 +1708,13 @@
   cmVisualStudioWCEPlatformParser parser(name.c_str());
   parser.ParseVersion(version);
   if (parser.Found()) {
-    std::cout << "@echo off" << std::endl;
-    std::cout << "echo Environment Selection: " << name << std::endl;
-    std::cout << "set PATH=" << parser.GetPathDirectories() << std::endl;
-    std::cout << "set INCLUDE=" << parser.GetIncludeDirectories() << std::endl;
-    std::cout << "set LIB=" << parser.GetLibraryDirectories() << std::endl;
+    /* clang-format off */
+    std::cout << "@echo off\n"
+                 "echo Environment Selection: " << name << "\n"
+                 "set PATH=" << parser.GetPathDirectories() << "\n"
+                 "set INCLUDE=" << parser.GetIncludeDirectories() << "\n"
+                 "set LIB=" << parser.GetLibraryDirectories() << std::endl;
+    /* clang-format on */
     return 0;
   }
 #else
@@ -1716,7 +1772,7 @@
   //   args[2] == source_file_path
   //   args[3] == intermediate_file
   //   args[4..n] == preprocess+args
-  //   args[n+1] == --
+  //   args[n+1] == ++
   //   args[n+2...] == llvm-rc+args
   if (args.size() < 3) {
     std::cerr << "Invalid cmake_llvm_rc arguments";
@@ -1728,7 +1784,11 @@
   std::vector<std::string> resource_compile;
   std::vector<std::string>* pArgTgt = &preprocess;
   for (std::string const& arg : cmMakeRange(args).advance(4)) {
-    if (arg == "--") {
+    // We use ++ as seperator between the preprocessing step definition and the
+    // rc compilation step becase we need to prepend a -- to seperate the
+    // source file properly from other options when using clang-cl for
+    // preprocessing.
+    if (arg == "++") {
       pArgTgt = &resource_compile;
     } else {
       if (arg.find("SOURCE_DIR") != std::string::npos) {
@@ -1845,7 +1905,7 @@
   std::vector<std::string> expandedArgs;
   for (std::string const& i : args) {
     // check for nmake temporary files
-    if (i[0] == '@' && i.find("@CMakeFiles") != 0) {
+    if (i[0] == '@' && !cmHasLiteralPrefix(i, "@CMakeFiles")) {
       cmsys::ifstream fin(i.substr(1).c_str());
       std::string line;
       while (cmSystemTools::GetLineFromStream(fin, line)) {
@@ -1971,9 +2031,8 @@
 
   // Parse the link command to extract information we need.
   for (; arg != argEnd; ++arg) {
-    if (cmSystemTools::Strucmp(arg->c_str(), "/INCREMENTAL:YES") == 0) {
-      this->Incremental = true;
-    } else if (cmSystemTools::Strucmp(arg->c_str(), "/INCREMENTAL") == 0) {
+    if (cmSystemTools::Strucmp(arg->c_str(), "/INCREMENTAL:YES") == 0 ||
+        cmSystemTools::Strucmp(arg->c_str(), "/INCREMENTAL") == 0) {
       this->Incremental = true;
     } else if (cmSystemTools::Strucmp(arg->c_str(), "/MANIFEST:NO") == 0) {
       this->LinkGeneratesManifest = false;
@@ -2083,12 +2142,18 @@
   }
 
   // If we have not previously generated a manifest file,
-  // generate an empty one so the resource compiler succeeds.
+  // generate a manifest file so the resource compiler succeeds.
   if (!cmSystemTools::FileExists(this->ManifestFile)) {
     if (this->Verbose) {
       std::cout << "Create empty: " << this->ManifestFile << "\n";
     }
-    cmsys::ofstream foutTmp(this->ManifestFile.c_str());
+    if (this->UserManifests.empty()) {
+      // generate an empty manifest because there are no user provided
+      // manifest files.
+      cmsys::ofstream foutTmp(this->ManifestFile.c_str());
+    } else {
+      this->RunMT("/out:" + this->ManifestFile, false);
+    }
   }
 
   // Compile the resource file.
@@ -2156,7 +2221,10 @@
   mtCommand.push_back(this->MtPath.empty() ? "mt" : this->MtPath);
   mtCommand.emplace_back("/nologo");
   mtCommand.emplace_back("/manifest");
-  if (this->LinkGeneratesManifest) {
+
+  // add the linker generated manifest if the file exists.
+  if (this->LinkGeneratesManifest &&
+      cmSystemTools::FileExists(this->LinkerManifestFile)) {
     mtCommand.push_back(this->LinkerManifestFile);
   }
   cm::append(mtCommand, this->UserManifests);
diff --git a/Source/ctest.cxx b/Source/ctest.cxx
index fbdf75a..3b5bf8c 100644
--- a/Source/ctest.cxx
+++ b/Source/ctest.cxx
@@ -35,6 +35,7 @@
   { "--output-on-failure",
     "Output anything outputted by the test program "
     "if the test should fail." },
+  { "--stop-on-failure", "Stop running the tests after one has failed." },
   { "--test-output-size-passed <size>",
     "Limit the output for passed tests "
     "to <size> bytes" },
diff --git a/Source/kwsys/Base64.c b/Source/kwsys/Base64.c
index bf876f2..4265018 100644
--- a/Source/kwsys/Base64.c
+++ b/Source/kwsys/Base64.c
@@ -130,7 +130,10 @@
 /* Decode 4 bytes into a 3 byte string. */
 int kwsysBase64_Decode3(const unsigned char* src, unsigned char* dest)
 {
-  unsigned char d0, d1, d2, d3;
+  unsigned char d0;
+  unsigned char d1;
+  unsigned char d2;
+  unsigned char d3;
 
   d0 = kwsysBase64DecodeChar(src[0]);
   d1 = kwsysBase64DecodeChar(src[1]);
diff --git a/Source/kwsys/CMakeLists.txt b/Source/kwsys/CMakeLists.txt
index 09bcdb9..b0a8542 100644
--- a/Source/kwsys/CMakeLists.txt
+++ b/Source/kwsys/CMakeLists.txt
@@ -11,9 +11,9 @@
 # be used.  All classes are disabled by default.  The CMake listfile
 # above this one configures the library as follows:
 #
-#  SET(KWSYS_NAMESPACE foosys)
-#  SET(KWSYS_USE_Directory 1)    # Enable Directory class.
-#  SUBDIRS(kwsys)
+#  set(KWSYS_NAMESPACE foosys)
+#  set(KWSYS_USE_Directory 1)    # Enable Directory class.
+#  add_subdirectory(kwsys)
 #
 # Optional settings are as follows:
 #
@@ -39,8 +39,8 @@
 #
 #    Example:
 #
-#      SET(KWSYS_HEADER_ROOT ${PROJECT_BINARY_DIR})
-#      INCLUDE_DIRECTORIES(${PROJECT_BINARY_DIR})
+#      set(KWSYS_HEADER_ROOT ${PROJECT_BINARY_DIR})
+#      include_directories(${PROJECT_BINARY_DIR})
 #
 #  KWSYS_CXX_STANDARD         = A value for CMAKE_CXX_STANDARD within KWSys.
 #                               Set to empty string to use no default value.
@@ -65,11 +65,11 @@
 #
 #    Example:
 #
-#      SET(KWSYS_INSTALL_BIN_DIR bin)
-#      SET(KWSYS_INSTALL_LIB_DIR lib)
-#      SET(KWSYS_INSTALL_INCLUDE_DIR include)
-#      SET(KWSYS_INSTALL_COMPONENT_NAME_RUNTIME Runtime)
-#      SET(KWSYS_INSTALL_COMPONENT_NAME_DEVELOPMENT Development)
+#      set(KWSYS_INSTALL_BIN_DIR bin)
+#      set(KWSYS_INSTALL_LIB_DIR lib)
+#      set(KWSYS_INSTALL_INCLUDE_DIR include)
+#      set(KWSYS_INSTALL_COMPONENT_NAME_RUNTIME Runtime)
+#      set(KWSYS_INSTALL_COMPONENT_NAME_DEVELOPMENT Development)
 
 # Once configured, kwsys should be used as follows from C or C++ code:
 #
@@ -86,33 +86,33 @@
 # any outside mailing list and no documentation of the change will be
 # written.
 
-CMAKE_MINIMUM_REQUIRED(VERSION 3.1 FATAL_ERROR)
-FOREACH(p
+cmake_minimum_required(VERSION 3.1 FATAL_ERROR)
+foreach(p
     CMP0056 # CMake 3.2, Honor link flags in try_compile() source-file signature.
     CMP0063 # CMake 3.3, Honor visibility properties for all target types.
     CMP0067 # CMake 3.8, Honor language standard in try_compile source-file signature.
     CMP0069 # CMake 3.9, INTERPROCEDURAL_OPTIMIZATION is enforced when enabled.
     )
-  IF(POLICY ${p})
-    CMAKE_POLICY(SET ${p} NEW)
-  ENDIF()
-ENDFOREACH()
+  if(POLICY ${p})
+    cmake_policy(SET ${p} NEW)
+  endif()
+endforeach()
 
 #-----------------------------------------------------------------------------
 # If a namespace is not specified, use "kwsys" and enable testing.
 # This should be the case only when kwsys is not included inside
 # another project and is being tested.
-IF(NOT KWSYS_NAMESPACE)
-  SET(KWSYS_NAMESPACE "kwsys")
-  SET(KWSYS_STANDALONE 1)
-ENDIF()
+if(NOT KWSYS_NAMESPACE)
+  set(KWSYS_NAMESPACE "kwsys")
+  set(KWSYS_STANDALONE 1)
+endif()
 
 #-----------------------------------------------------------------------------
 # The project name is that of the specified namespace.
-PROJECT(${KWSYS_NAMESPACE})
+project(${KWSYS_NAMESPACE})
 
 # Tell CMake how to follow dependencies of sources in this directory.
-SET_PROPERTY(DIRECTORY
+set_property(DIRECTORY
   PROPERTY IMPLICIT_DEPENDS_INCLUDE_TRANSFORM
   "KWSYS_HEADER(%)=<${KWSYS_NAMESPACE}/%>"
   )
@@ -131,309 +131,253 @@
 endif()
 
 # Select library components.
-IF(KWSYS_STANDALONE OR CMake_SOURCE_DIR)
-  SET(KWSYS_ENABLE_C 1)
+if(KWSYS_STANDALONE OR CMake_SOURCE_DIR)
+  set(KWSYS_ENABLE_C 1)
   # Enable all components.
-  SET(KWSYS_USE_Base64 1)
-  SET(KWSYS_USE_Directory 1)
-  SET(KWSYS_USE_DynamicLoader 1)
-  SET(KWSYS_USE_Encoding 1)
-  SET(KWSYS_USE_Glob 1)
-  SET(KWSYS_USE_MD5 1)
-  SET(KWSYS_USE_Process 1)
-  SET(KWSYS_USE_RegularExpression 1)
-  SET(KWSYS_USE_System 1)
-  SET(KWSYS_USE_SystemTools 1)
-  SET(KWSYS_USE_CommandLineArguments 1)
-  SET(KWSYS_USE_Terminal 1)
-  SET(KWSYS_USE_IOStream 1)
-  SET(KWSYS_USE_FStream 1)
-  SET(KWSYS_USE_String 1)
-  SET(KWSYS_USE_SystemInformation 1)
-  SET(KWSYS_USE_ConsoleBuf 1)
-ENDIF()
+  set(KWSYS_USE_Base64 1)
+  set(KWSYS_USE_Directory 1)
+  set(KWSYS_USE_DynamicLoader 1)
+  set(KWSYS_USE_Encoding 1)
+  set(KWSYS_USE_Glob 1)
+  set(KWSYS_USE_MD5 1)
+  set(KWSYS_USE_Process 1)
+  set(KWSYS_USE_RegularExpression 1)
+  set(KWSYS_USE_System 1)
+  set(KWSYS_USE_SystemTools 1)
+  set(KWSYS_USE_CommandLineArguments 1)
+  set(KWSYS_USE_Terminal 1)
+  set(KWSYS_USE_FStream 1)
+  set(KWSYS_USE_String 1)
+  set(KWSYS_USE_SystemInformation 1)
+  set(KWSYS_USE_ConsoleBuf 1)
+endif()
 
 # Enforce component dependencies.
-IF(KWSYS_USE_SystemTools)
-  SET(KWSYS_USE_Directory 1)
-  SET(KWSYS_USE_FStream 1)
-  SET(KWSYS_USE_Encoding 1)
-ENDIF()
-IF(KWSYS_USE_Glob)
-  SET(KWSYS_USE_Directory 1)
-  SET(KWSYS_USE_SystemTools 1)
-  SET(KWSYS_USE_RegularExpression 1)
-  SET(KWSYS_USE_FStream 1)
-  SET(KWSYS_USE_Encoding 1)
-ENDIF()
-IF(KWSYS_USE_Process)
-  SET(KWSYS_USE_System 1)
-  SET(KWSYS_USE_Encoding 1)
-ENDIF()
-IF(KWSYS_USE_SystemInformation)
-  SET(KWSYS_USE_Process 1)
-ENDIF()
-IF(KWSYS_USE_System)
-  SET(KWSYS_USE_Encoding 1)
-ENDIF()
-IF(KWSYS_USE_Directory)
-  SET(KWSYS_USE_Encoding 1)
-ENDIF()
-IF(KWSYS_USE_DynamicLoader)
-  SET(KWSYS_USE_Encoding 1)
-ENDIF()
-IF(KWSYS_USE_FStream)
-  SET(KWSYS_USE_Encoding 1)
-ENDIF()
-IF(KWSYS_USE_ConsoleBuf)
-  SET(KWSYS_USE_Encoding 1)
-ENDIF()
+if(KWSYS_USE_SystemTools)
+  set(KWSYS_USE_Directory 1)
+  set(KWSYS_USE_FStream 1)
+  set(KWSYS_USE_Encoding 1)
+endif()
+if(KWSYS_USE_Glob)
+  set(KWSYS_USE_Directory 1)
+  set(KWSYS_USE_SystemTools 1)
+  set(KWSYS_USE_RegularExpression 1)
+  set(KWSYS_USE_FStream 1)
+  set(KWSYS_USE_Encoding 1)
+endif()
+if(KWSYS_USE_Process)
+  set(KWSYS_USE_System 1)
+  set(KWSYS_USE_Encoding 1)
+endif()
+if(KWSYS_USE_SystemInformation)
+  set(KWSYS_USE_Process 1)
+endif()
+if(KWSYS_USE_System)
+  set(KWSYS_USE_Encoding 1)
+endif()
+if(KWSYS_USE_Directory)
+  set(KWSYS_USE_Encoding 1)
+endif()
+if(KWSYS_USE_DynamicLoader)
+  set(KWSYS_USE_Encoding 1)
+endif()
+if(KWSYS_USE_FStream)
+  set(KWSYS_USE_Encoding 1)
+endif()
+if(KWSYS_USE_ConsoleBuf)
+  set(KWSYS_USE_Encoding 1)
+endif()
 
 # Specify default 8 bit encoding for Windows
-IF(NOT KWSYS_ENCODING_DEFAULT_CODEPAGE)
-  SET(KWSYS_ENCODING_DEFAULT_CODEPAGE CP_ACP)
-ENDIF()
+if(NOT KWSYS_ENCODING_DEFAULT_CODEPAGE)
+  set(KWSYS_ENCODING_DEFAULT_CODEPAGE CP_ACP)
+endif()
 
 # Enable testing if building standalone.
-IF(KWSYS_STANDALONE)
-  INCLUDE(Dart)
-  MARK_AS_ADVANCED(BUILD_TESTING DART_ROOT TCL_TCLSH)
-  IF(BUILD_TESTING)
-    ENABLE_TESTING()
-  ENDIF()
-ENDIF()
+if(KWSYS_STANDALONE)
+  include(Dart)
+  mark_as_advanced(BUILD_TESTING DART_ROOT TCL_TCLSH)
+  if(BUILD_TESTING)
+    enable_testing()
+  endif()
+endif()
 
 # Choose default shared/static build if not specified.
-IF(NOT DEFINED KWSYS_BUILD_SHARED)
-  SET(KWSYS_BUILD_SHARED ${BUILD_SHARED_LIBS})
-ENDIF()
+if(NOT DEFINED KWSYS_BUILD_SHARED)
+  set(KWSYS_BUILD_SHARED ${BUILD_SHARED_LIBS})
+endif()
 
 # Include helper macros.
-INCLUDE(${CMAKE_CURRENT_SOURCE_DIR}/kwsysPlatformTests.cmake)
-INCLUDE(CheckTypeSize)
+include(${CMAKE_CURRENT_SOURCE_DIR}/kwsysPlatformTests.cmake)
+include(CheckTypeSize)
 
 # Do full dependency headers.
-INCLUDE_REGULAR_EXPRESSION("^.*$")
+include_regular_expression("^.*$")
 
 # Use new KWSYS_INSTALL_*_DIR variable names to control installation.
 # Take defaults from the old names.  Note that there was no old name
 # for the bin dir, so we take the old lib dir name so DLLs will be
 # installed in a compatible way for old code.
-IF(NOT KWSYS_INSTALL_INCLUDE_DIR)
-  STRING(REGEX REPLACE "^/" "" KWSYS_INSTALL_INCLUDE_DIR
+if(NOT KWSYS_INSTALL_INCLUDE_DIR)
+  string(REGEX REPLACE "^/" "" KWSYS_INSTALL_INCLUDE_DIR
     "${KWSYS_HEADER_INSTALL_DIR}")
-ENDIF()
-IF(NOT KWSYS_INSTALL_LIB_DIR)
-  STRING(REGEX REPLACE "^/" "" KWSYS_INSTALL_LIB_DIR
+endif()
+if(NOT KWSYS_INSTALL_LIB_DIR)
+  string(REGEX REPLACE "^/" "" KWSYS_INSTALL_LIB_DIR
     "${KWSYS_LIBRARY_INSTALL_DIR}")
-ENDIF()
-IF(NOT KWSYS_INSTALL_BIN_DIR)
-  STRING(REGEX REPLACE "^/" "" KWSYS_INSTALL_BIN_DIR
+endif()
+if(NOT KWSYS_INSTALL_BIN_DIR)
+  string(REGEX REPLACE "^/" "" KWSYS_INSTALL_BIN_DIR
     "${KWSYS_LIBRARY_INSTALL_DIR}")
-ENDIF()
+endif()
 
 # Setup header install rules.
-SET(KWSYS_INSTALL_INCLUDE_OPTIONS)
-IF(KWSYS_INSTALL_COMPONENT_NAME_DEVELOPMENT)
-  SET(KWSYS_INSTALL_INCLUDE_OPTIONS ${KWSYS_INSTALL_INCLUDE_OPTIONS}
+set(KWSYS_INSTALL_INCLUDE_OPTIONS)
+if(KWSYS_INSTALL_COMPONENT_NAME_DEVELOPMENT)
+  set(KWSYS_INSTALL_INCLUDE_OPTIONS ${KWSYS_INSTALL_INCLUDE_OPTIONS}
     COMPONENT ${KWSYS_INSTALL_COMPONENT_NAME_DEVELOPMENT}
     )
-ENDIF()
+endif()
 
 # Setup library install rules.
-SET(KWSYS_INSTALL_LIBRARY_RULE)
-SET(KWSYS_INSTALL_NAMELINK_RULE)
-IF(KWSYS_INSTALL_LIB_DIR)
-  IF(KWSYS_INSTALL_EXPORT_NAME)
-    LIST(APPEND KWSYS_INSTALL_LIBRARY_RULE EXPORT ${KWSYS_INSTALL_EXPORT_NAME})
-  ENDIF()
+set(KWSYS_INSTALL_LIBRARY_RULE)
+set(KWSYS_INSTALL_NAMELINK_RULE)
+if(KWSYS_INSTALL_LIB_DIR)
+  if(KWSYS_INSTALL_EXPORT_NAME)
+    list(APPEND KWSYS_INSTALL_LIBRARY_RULE EXPORT ${KWSYS_INSTALL_EXPORT_NAME})
+  endif()
   # Install the shared library to the lib directory.
-  SET(KWSYS_INSTALL_LIBRARY_RULE ${KWSYS_INSTALL_LIBRARY_RULE}
+  set(KWSYS_INSTALL_LIBRARY_RULE ${KWSYS_INSTALL_LIBRARY_RULE}
     LIBRARY DESTINATION ${KWSYS_INSTALL_LIB_DIR} NAMELINK_SKIP
     )
   # Assign the shared library to the runtime component.
-  IF(KWSYS_INSTALL_COMPONENT_NAME_RUNTIME)
-    SET(KWSYS_INSTALL_LIBRARY_RULE ${KWSYS_INSTALL_LIBRARY_RULE}
+  if(KWSYS_INSTALL_COMPONENT_NAME_RUNTIME)
+    set(KWSYS_INSTALL_LIBRARY_RULE ${KWSYS_INSTALL_LIBRARY_RULE}
       COMPONENT ${KWSYS_INSTALL_COMPONENT_NAME_RUNTIME}
       )
-  ENDIF()
-  IF(KWSYS_BUILD_SHARED)
-    SET(KWSYS_INSTALL_NAMELINK_RULE ${KWSYS_INSTALL_NAMELINK_RULE}
+  endif()
+  if(KWSYS_BUILD_SHARED)
+    set(KWSYS_INSTALL_NAMELINK_RULE ${KWSYS_INSTALL_NAMELINK_RULE}
       LIBRARY DESTINATION ${KWSYS_INSTALL_LIB_DIR} NAMELINK_ONLY
       )
     # Assign the namelink to the development component.
-    IF(KWSYS_INSTALL_COMPONENT_NAME_DEVELOPMENT)
-      SET(KWSYS_INSTALL_NAMELINK_RULE ${KWSYS_INSTALL_NAMELINK_RULE}
+    if(KWSYS_INSTALL_COMPONENT_NAME_DEVELOPMENT)
+      set(KWSYS_INSTALL_NAMELINK_RULE ${KWSYS_INSTALL_NAMELINK_RULE}
         COMPONENT ${KWSYS_INSTALL_COMPONENT_NAME_DEVELOPMENT}
         )
-    ENDIF()
-  ENDIF()
+    endif()
+  endif()
 
   # Install the archive to the lib directory.
-  SET(KWSYS_INSTALL_LIBRARY_RULE ${KWSYS_INSTALL_LIBRARY_RULE}
+  set(KWSYS_INSTALL_LIBRARY_RULE ${KWSYS_INSTALL_LIBRARY_RULE}
     ARCHIVE DESTINATION ${KWSYS_INSTALL_LIB_DIR}
     )
   # Assign the archive to the development component.
-  IF(KWSYS_INSTALL_COMPONENT_NAME_DEVELOPMENT)
-    SET(KWSYS_INSTALL_LIBRARY_RULE ${KWSYS_INSTALL_LIBRARY_RULE}
+  if(KWSYS_INSTALL_COMPONENT_NAME_DEVELOPMENT)
+    set(KWSYS_INSTALL_LIBRARY_RULE ${KWSYS_INSTALL_LIBRARY_RULE}
       COMPONENT ${KWSYS_INSTALL_COMPONENT_NAME_DEVELOPMENT}
       )
-  ENDIF()
-ENDIF()
-IF(KWSYS_INSTALL_BIN_DIR)
+  endif()
+endif()
+if(KWSYS_INSTALL_BIN_DIR)
   # Install the runtime library to the bin directory.
-  SET(KWSYS_INSTALL_LIBRARY_RULE ${KWSYS_INSTALL_LIBRARY_RULE}
+  set(KWSYS_INSTALL_LIBRARY_RULE ${KWSYS_INSTALL_LIBRARY_RULE}
     RUNTIME DESTINATION ${KWSYS_INSTALL_BIN_DIR}
     )
   # Assign the runtime library to the runtime component.
-  IF(KWSYS_INSTALL_COMPONENT_NAME_RUNTIME)
-    SET(KWSYS_INSTALL_LIBRARY_RULE ${KWSYS_INSTALL_LIBRARY_RULE}
+  if(KWSYS_INSTALL_COMPONENT_NAME_RUNTIME)
+    set(KWSYS_INSTALL_LIBRARY_RULE ${KWSYS_INSTALL_LIBRARY_RULE}
       COMPONENT ${KWSYS_INSTALL_COMPONENT_NAME_RUNTIME}
       )
-  ENDIF()
-ENDIF()
+  endif()
+endif()
 
 # Do not support old KWSYS_*a_INSTALL_DIR variable names.
-SET(KWSYS_HEADER_INSTALL_DIR)
-SET(KWSYS_LIBRARY_INSTALL_DIR)
+set(KWSYS_HEADER_INSTALL_DIR)
+set(KWSYS_LIBRARY_INSTALL_DIR)
 
 # Generated source files will need this header.
-STRING(COMPARE EQUAL "${PROJECT_SOURCE_DIR}" "${PROJECT_BINARY_DIR}"
+string(COMPARE EQUAL "${PROJECT_SOURCE_DIR}" "${PROJECT_BINARY_DIR}"
   KWSYS_IN_SOURCE_BUILD)
-IF(NOT KWSYS_IN_SOURCE_BUILD)
-  CONFIGURE_FILE(${PROJECT_SOURCE_DIR}/kwsysPrivate.h
+if(NOT KWSYS_IN_SOURCE_BUILD)
+  configure_file(${PROJECT_SOURCE_DIR}/kwsysPrivate.h
     ${PROJECT_BINARY_DIR}/kwsysPrivate.h COPYONLY IMMEDIATE)
-ENDIF()
+endif()
 
 # Select plugin module file name convention.
-IF(NOT KWSYS_DynamicLoader_PREFIX)
-  SET(KWSYS_DynamicLoader_PREFIX ${CMAKE_SHARED_MODULE_PREFIX})
-ENDIF()
-IF(NOT KWSYS_DynamicLoader_SUFFIX)
-  SET(KWSYS_DynamicLoader_SUFFIX ${CMAKE_SHARED_MODULE_SUFFIX})
-ENDIF()
+if(NOT KWSYS_DynamicLoader_PREFIX)
+  set(KWSYS_DynamicLoader_PREFIX ${CMAKE_SHARED_MODULE_PREFIX})
+endif()
+if(NOT KWSYS_DynamicLoader_SUFFIX)
+  set(KWSYS_DynamicLoader_SUFFIX ${CMAKE_SHARED_MODULE_SUFFIX})
+endif()
 
 #-----------------------------------------------------------------------------
 # We require ANSI support from the C compiler.  Add any needed flags.
-IF(CMAKE_ANSI_CFLAGS)
-  SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${CMAKE_ANSI_CFLAGS}")
-ENDIF()
+if(CMAKE_ANSI_CFLAGS)
+  set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${CMAKE_ANSI_CFLAGS}")
+endif()
 
 #-----------------------------------------------------------------------------
 # Adjust compiler flags for some platforms.
-IF(NOT CMAKE_COMPILER_IS_GNUCXX)
-  IF(CMAKE_SYSTEM MATCHES "OSF1-V.*")
-    STRING(REGEX MATCH "-timplicit_local"
+if(NOT CMAKE_COMPILER_IS_GNUCXX)
+  if(CMAKE_SYSTEM MATCHES "OSF1-V.*")
+    string(REGEX MATCH "-timplicit_local"
       KWSYS_CXX_FLAGS_HAVE_IMPLICIT_LOCAL "${CMAKE_CXX_FLAGS}")
-    STRING(REGEX MATCH "-no_implicit_include"
+    string(REGEX MATCH "-no_implicit_include"
       KWSYS_CXX_FLAGS_HAVE_NO_IMPLICIT_INCLUDE "${CMAKE_CXX_FLAGS}")
-    IF(NOT KWSYS_CXX_FLAGS_HAVE_IMPLICIT_LOCAL)
-      SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -timplicit_local")
-    ENDIF()
-    IF(NOT KWSYS_CXX_FLAGS_HAVE_NO_IMPLICIT_INCLUDE)
-      SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -no_implicit_include")
-    ENDIF()
-  ENDIF()
-  IF(CMAKE_SYSTEM MATCHES "HP-UX")
-    SET(KWSYS_PLATFORM_CXX_TEST_EXTRA_FLAGS "+p")
-    IF(CMAKE_CXX_COMPILER_ID MATCHES "HP")
+    if(NOT KWSYS_CXX_FLAGS_HAVE_IMPLICIT_LOCAL)
+      set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -timplicit_local")
+    endif()
+    if(NOT KWSYS_CXX_FLAGS_HAVE_NO_IMPLICIT_INCLUDE)
+      set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -no_implicit_include")
+    endif()
+  endif()
+  if(CMAKE_SYSTEM MATCHES "HP-UX")
+    set(KWSYS_PLATFORM_CXX_TEST_EXTRA_FLAGS "+p")
+    if(CMAKE_CXX_COMPILER_ID MATCHES "HP")
       # it is known that version 3.85 fails and 6.25 works without these flags
-      IF(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4)
+      if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4)
         # use new C++ library and improved template support
-        SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -AA +hpxstd98")
-      ENDIF()
-    ENDIF()
-  ENDIF()
-ENDIF()
-IF(KWSYS_STANDALONE)
-  IF(CMAKE_CXX_COMPILER_ID STREQUAL SunPro)
-    IF(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.13)
-      SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++03")
-    ELSE()
-      SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -library=stlport4")
-    ENDIF()
-  ENDIF()
-ENDIF()
+        set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -AA +hpxstd98")
+      endif()
+    endif()
+  endif()
+endif()
+if(KWSYS_STANDALONE)
+  if(CMAKE_CXX_COMPILER_ID STREQUAL SunPro)
+    if(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.13)
+      set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++03")
+    else()
+      set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -library=stlport4")
+    endif()
+  endif()
+endif()
 
 #-----------------------------------------------------------------------------
 # Configure the standard library header wrappers based on compiler's
 # capabilities and parent project's request.  Enforce 0/1 as only
 # possible values for configuration into Configure.hxx.
 
-# Check existence and uniqueness of long long and __int64.
-KWSYS_PLATFORM_CXX_TEST(KWSYS_CXX_HAS_LONG_LONG
-  "Checking whether C++ compiler has 'long long'" DIRECT)
-KWSYS_PLATFORM_CXX_TEST(KWSYS_CXX_HAS___INT64
-  "Checking whether C++ compiler has '__int64'" DIRECT)
-IF(KWSYS_CXX_HAS___INT64)
-  KWSYS_PLATFORM_CXX_TEST(KWSYS_CXX_SAME_LONG_AND___INT64
-    "Checking whether long and __int64 are the same type" DIRECT)
-  IF(KWSYS_CXX_HAS_LONG_LONG)
-    KWSYS_PLATFORM_CXX_TEST(KWSYS_CXX_SAME_LONG_LONG_AND___INT64
-      "Checking whether long long and __int64 are the same type" DIRECT)
-  ENDIF()
-ENDIF()
-
-# Enable the "long long" type if it is available.  It is standard in
-# C99 and C++03 but not in earlier standards.
-IF(KWSYS_CXX_HAS_LONG_LONG)
-  SET(KWSYS_USE_LONG_LONG 1)
-ELSE()
-  SET(KWSYS_USE_LONG_LONG 0)
-ENDIF()
-
-# Enable the "__int64" type if it is available and unique.  It is not
-# standard.
-SET(KWSYS_USE___INT64 0)
-IF(KWSYS_CXX_HAS___INT64)
-  IF(NOT KWSYS_CXX_SAME_LONG_AND___INT64)
-    IF(NOT KWSYS_CXX_SAME_LONG_LONG_AND___INT64)
-      SET(KWSYS_USE___INT64 1)
-    ENDIF()
-  ENDIF()
-ENDIF()
-
-IF(KWSYS_USE_Encoding)
+if(KWSYS_USE_Encoding)
   # Look for type size helper macros.
   KWSYS_PLATFORM_CXX_TEST(KWSYS_STL_HAS_WSTRING
     "Checking whether wstring is available" DIRECT)
-ENDIF()
+endif()
 
-IF(KWSYS_USE_IOStream)
-  # Determine whether iostreams support long long.
-  IF(KWSYS_CXX_HAS_LONG_LONG)
-    KWSYS_PLATFORM_CXX_TEST(KWSYS_IOS_HAS_ISTREAM_LONG_LONG
-      "Checking if istream supports long long" DIRECT)
-    KWSYS_PLATFORM_CXX_TEST(KWSYS_IOS_HAS_OSTREAM_LONG_LONG
-      "Checking if ostream supports long long" DIRECT)
-  ELSE()
-    SET(KWSYS_IOS_HAS_ISTREAM_LONG_LONG 0)
-    SET(KWSYS_IOS_HAS_OSTREAM_LONG_LONG 0)
-  ENDIF()
-  IF(KWSYS_CXX_HAS___INT64)
-    KWSYS_PLATFORM_CXX_TEST(KWSYS_IOS_HAS_ISTREAM___INT64
-      "Checking if istream supports __int64" DIRECT)
-    KWSYS_PLATFORM_CXX_TEST(KWSYS_IOS_HAS_OSTREAM___INT64
-      "Checking if ostream supports __int64" DIRECT)
-  ELSE()
-    SET(KWSYS_IOS_HAS_ISTREAM___INT64 0)
-    SET(KWSYS_IOS_HAS_OSTREAM___INT64 0)
-  ENDIF()
-ENDIF()
+if(KWSYS_NAMESPACE MATCHES "^kwsys$")
+  set(KWSYS_NAME_IS_KWSYS 1)
+else()
+  set(KWSYS_NAME_IS_KWSYS 0)
+endif()
 
-IF(KWSYS_NAMESPACE MATCHES "^kwsys$")
-  SET(KWSYS_NAME_IS_KWSYS 1)
-ELSE()
-  SET(KWSYS_NAME_IS_KWSYS 0)
-ENDIF()
-
-IF(KWSYS_BUILD_SHARED)
-  SET(KWSYS_BUILD_SHARED 1)
-  SET(KWSYS_LIBRARY_TYPE SHARED)
-ELSE()
-  SET(KWSYS_BUILD_SHARED 0)
-  SET(KWSYS_LIBRARY_TYPE STATIC)
-ENDIF()
+if(KWSYS_BUILD_SHARED)
+  set(KWSYS_BUILD_SHARED 1)
+  set(KWSYS_LIBRARY_TYPE SHARED)
+else()
+  set(KWSYS_BUILD_SHARED 0)
+  set(KWSYS_LIBRARY_TYPE STATIC)
+endif()
 
 if(NOT DEFINED KWSYS_BUILD_PIC)
   set(KWSYS_BUILD_PIC 0)
@@ -446,32 +390,32 @@
   "Checking whether C compiler has ptrdiff_t in stddef.h" DIRECT)
 KWSYS_PLATFORM_C_TEST(KWSYS_C_HAS_SSIZE_T
   "Checking whether C compiler has ssize_t in unistd.h" DIRECT)
-IF(KWSYS_USE_Process)
+if(KWSYS_USE_Process)
   KWSYS_PLATFORM_C_TEST(KWSYS_C_HAS_CLOCK_GETTIME_MONOTONIC
     "Checking whether C compiler has clock_gettime" DIRECT)
-ENDIF()
+endif()
 
-SET_SOURCE_FILES_PROPERTIES(ProcessUNIX.c System.c PROPERTIES
+set_source_files_properties(ProcessUNIX.c System.c PROPERTIES
   COMPILE_FLAGS "-DKWSYS_C_HAS_PTRDIFF_T=${KWSYS_C_HAS_PTRDIFF_T} -DKWSYS_C_HAS_SSIZE_T=${KWSYS_C_HAS_SSIZE_T} -DKWSYS_C_HAS_CLOCK_GETTIME_MONOTONIC=${KWSYS_C_HAS_CLOCK_GETTIME_MONOTONIC}"
   )
 
-IF(DEFINED KWSYS_PROCESS_USE_SELECT)
-  GET_PROPERTY(ProcessUNIX_FLAGS SOURCE ProcessUNIX.c PROPERTY COMPILE_FLAGS)
-  SET_PROPERTY(SOURCE ProcessUNIX.c PROPERTY COMPILE_FLAGS "${ProcessUNIX_FLAGS} -DKWSYSPE_USE_SELECT=${KWSYSPE_USE_SELECT}")
-ENDIF()
+if(DEFINED KWSYS_PROCESS_USE_SELECT)
+  get_property(ProcessUNIX_FLAGS SOURCE ProcessUNIX.c PROPERTY COMPILE_FLAGS)
+  set_property(SOURCE ProcessUNIX.c PROPERTY COMPILE_FLAGS "${ProcessUNIX_FLAGS} -DKWSYSPE_USE_SELECT=${KWSYSPE_USE_SELECT}")
+endif()
 
-IF(KWSYS_USE_DynamicLoader)
-  GET_PROPERTY(KWSYS_SUPPORTS_SHARED_LIBS GLOBAL PROPERTY TARGET_SUPPORTS_SHARED_LIBS)
-  IF(KWSYS_SUPPORTS_SHARED_LIBS)
-    SET(KWSYS_SUPPORTS_SHARED_LIBS 1)
-  ELSE()
-    SET(KWSYS_SUPPORTS_SHARED_LIBS 0)
-  ENDIF()
-  SET_PROPERTY(SOURCE DynamicLoader.cxx APPEND PROPERTY COMPILE_DEFINITIONS
+if(KWSYS_USE_DynamicLoader)
+  get_property(KWSYS_SUPPORTS_SHARED_LIBS GLOBAL PROPERTY TARGET_SUPPORTS_SHARED_LIBS)
+  if(KWSYS_SUPPORTS_SHARED_LIBS)
+    set(KWSYS_SUPPORTS_SHARED_LIBS 1)
+  else()
+    set(KWSYS_SUPPORTS_SHARED_LIBS 0)
+  endif()
+  set_property(SOURCE DynamicLoader.cxx APPEND PROPERTY COMPILE_DEFINITIONS
     KWSYS_SUPPORTS_SHARED_LIBS=${KWSYS_SUPPORTS_SHARED_LIBS})
-ENDIF()
+endif()
 
-IF(KWSYS_USE_SystemTools)
+if(KWSYS_USE_SystemTools)
   if (NOT DEFINED KWSYS_SYSTEMTOOLS_USE_TRANSLATION_MAP)
     set(KWSYS_SYSTEMTOOLS_USE_TRANSLATION_MAP 1)
   endif ()
@@ -494,7 +438,7 @@
     "Checking whether CXX compiler struct stat has st_mtim member" DIRECT)
   KWSYS_PLATFORM_CXX_TEST(KWSYS_CXX_STAT_HAS_ST_MTIMESPEC
     "Checking whether CXX compiler struct stat has st_mtimespec member" DIRECT)
-  SET_PROPERTY(SOURCE SystemTools.cxx APPEND PROPERTY COMPILE_DEFINITIONS
+  set_property(SOURCE SystemTools.cxx APPEND PROPERTY COMPILE_DEFINITIONS
     KWSYS_CXX_HAS_SETENV=${KWSYS_CXX_HAS_SETENV}
     KWSYS_CXX_HAS_UNSETENV=${KWSYS_CXX_HAS_UNSETENV}
     KWSYS_CXX_HAS_ENVIRON_IN_STDLIB_H=${KWSYS_CXX_HAS_ENVIRON_IN_STDLIB_H}
@@ -503,623 +447,564 @@
     KWSYS_CXX_STAT_HAS_ST_MTIM=${KWSYS_CXX_STAT_HAS_ST_MTIM}
     KWSYS_CXX_STAT_HAS_ST_MTIMESPEC=${KWSYS_CXX_STAT_HAS_ST_MTIMESPEC}
     )
-  IF(NOT WIN32)
-    IF(KWSYS_STANDALONE)
-      OPTION(KWSYS_SYSTEMTOOLS_SUPPORT_WINDOWS_SLASHES "If true, Windows paths will be supported on Unix as well" ON)
-    ENDIF()
-    IF(KWSYS_SYSTEMTOOLS_SUPPORT_WINDOWS_SLASHES)
-      SET_PROPERTY(SOURCE SystemTools.cxx testSystemTools.cxx APPEND PROPERTY COMPILE_DEFINITIONS
+  if(NOT WIN32)
+    if(KWSYS_STANDALONE)
+      option(KWSYS_SYSTEMTOOLS_SUPPORT_WINDOWS_SLASHES "If true, Windows paths will be supported on Unix as well" ON)
+    endif()
+    if(KWSYS_SYSTEMTOOLS_SUPPORT_WINDOWS_SLASHES)
+      set_property(SOURCE SystemTools.cxx testSystemTools.cxx APPEND PROPERTY COMPILE_DEFINITIONS
         KWSYS_SYSTEMTOOLS_SUPPORT_WINDOWS_SLASHES
         )
-    ENDIF()
-  ENDIF()
+    endif()
+  endif()
 
   # Disable getpwnam for static linux builds since it depends on shared glibc
-  GET_PROPERTY(SHARED_LIBS_SUPPORTED GLOBAL PROPERTY TARGET_SUPPORTS_SHARED_LIBS)
-  IF(CMAKE_SYSTEM_NAME MATCHES "Linux" AND NOT SHARED_LIBS_SUPPORTED)
-    SET_PROPERTY(SOURCE SystemTools.cxx APPEND PROPERTY COMPILE_DEFINITIONS
+  get_property(SHARED_LIBS_SUPPORTED GLOBAL PROPERTY TARGET_SUPPORTS_SHARED_LIBS)
+  if(CMAKE_SYSTEM_NAME MATCHES "Linux" AND NOT SHARED_LIBS_SUPPORTED)
+    set_property(SOURCE SystemTools.cxx APPEND PROPERTY COMPILE_DEFINITIONS
       HAVE_GETPWNAM=0
       )
-  ENDIF()
-ENDIF()
+  endif()
+endif()
 
-IF(KWSYS_USE_SystemInformation)
-  SET_PROPERTY(SOURCE SystemInformation.cxx APPEND PROPERTY
+if(KWSYS_USE_SystemInformation)
+  set_property(SOURCE SystemInformation.cxx APPEND PROPERTY
     COMPILE_DEFINITIONS SIZEOF_VOID_P=${CMAKE_SIZEOF_VOID_P})
-  IF(NOT CYGWIN)
-    INCLUDE(CheckIncludeFiles)
+  if(NOT CYGWIN)
+    include(CheckIncludeFiles)
     CHECK_INCLUDE_FILES("sys/types.h;ifaddrs.h" KWSYS_SYS_HAS_IFADDRS_H)
-    IF(KWSYS_SYS_HAS_IFADDRS_H)
-      SET_PROPERTY(SOURCE SystemInformation.cxx APPEND PROPERTY
+    if(KWSYS_SYS_HAS_IFADDRS_H)
+      set_property(SOURCE SystemInformation.cxx APPEND PROPERTY
         COMPILE_DEFINITIONS KWSYS_SYS_HAS_IFADDRS_H=1)
-    ENDIF()
-  ENDIF()
-  IF(WIN32)
-    INCLUDE(CheckSymbolExists)
-    SET(CMAKE_REQUIRED_LIBRARIES Psapi)
+    endif()
+  endif()
+  if(WIN32)
+    include(CheckSymbolExists)
+    set(CMAKE_REQUIRED_LIBRARIES psapi)
     CHECK_SYMBOL_EXISTS(GetProcessMemoryInfo "windows.h;psapi.h" KWSYS_SYS_HAS_PSAPI)
-    UNSET(CMAKE_REQUIRED_LIBRARIES)
-    IF(KWSYS_SYS_HAS_PSAPI)
-      SET_PROPERTY(SOURCE SystemInformation.cxx APPEND PROPERTY
+    unset(CMAKE_REQUIRED_LIBRARIES)
+    if(KWSYS_SYS_HAS_PSAPI)
+      set_property(SOURCE SystemInformation.cxx APPEND PROPERTY
         COMPILE_DEFINITIONS KWSYS_SYS_HAS_PSAPI=1)
-      IF(MSVC70 OR MSVC71)
+      if(MSVC70 OR MSVC71)
         # Suppress LNK4089: all references to 'PSAPI.DLL' discarded by /OPT:REF
-        SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /IGNORE:4089")
-      ENDIF()
-    ENDIF()
-  ENDIF()
-  IF(CMAKE_SYSTEM MATCHES "HP-UX")
+        set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /IGNORE:4089")
+      endif()
+    endif()
+  endif()
+  if(CMAKE_SYSTEM MATCHES "HP-UX")
     CHECK_INCLUDE_FILES("sys/mpctl.h" KWSYS_SYS_HAS_MPCTL_H)
-    IF(KWSYS_SYS_HAS_MPCTL_H)
-      SET_PROPERTY(SOURCE SystemInformation.cxx APPEND PROPERTY
+    if(KWSYS_SYS_HAS_MPCTL_H)
+      set_property(SOURCE SystemInformation.cxx APPEND PROPERTY
         COMPILE_DEFINITIONS KWSYS_SYS_HAS_MPCTL_H=1)
-    ENDIF()
-  ENDIF()
-  IF(CMAKE_SYSTEM MATCHES "BSD")
+    endif()
+  endif()
+  if(CMAKE_SYSTEM MATCHES "BSD")
     CHECK_INCLUDE_FILES("machine/cpu.h" KWSYS_SYS_HAS_MACHINE_CPU_H)
-    IF(KWSYS_SYS_HAS_MACHINE_CPU_H)
-      SET_PROPERTY(SOURCE SystemInformation.cxx APPEND PROPERTY
+    if(KWSYS_SYS_HAS_MACHINE_CPU_H)
+      set_property(SOURCE SystemInformation.cxx APPEND PROPERTY
         COMPILE_DEFINITIONS KWSYS_SYS_HAS_MACHINE_CPU_H=1)
-    ENDIF()
-  ENDIF()
+    endif()
+  endif()
   KWSYS_PLATFORM_CXX_TEST(KWSYS_CXX_HAS_RLIMIT64
     "Checking whether CXX compiler has rlimit64" DIRECT)
-  SET(KWSYS_PLATFORM_CXX_TEST_DEFINES)
-  IF(KWSYS_CXX_HAS_RLIMIT64)
-    SET_PROPERTY(SOURCE SystemInformation.cxx APPEND PROPERTY
+  set(KWSYS_PLATFORM_CXX_TEST_DEFINES)
+  if(KWSYS_CXX_HAS_RLIMIT64)
+    set_property(SOURCE SystemInformation.cxx APPEND PROPERTY
       COMPILE_DEFINITIONS KWSYS_CXX_HAS_RLIMIT64=1)
-  ENDIF()
-  KWSYS_PLATFORM_CXX_TEST(KWSYS_CXX_HAS_ATOL
-    "Checking whether CXX compiler has atol" DIRECT)
-  IF(KWSYS_CXX_HAS_ATOL)
-    SET_PROPERTY(SOURCE SystemInformation.cxx APPEND PROPERTY
-      COMPILE_DEFINITIONS KWSYS_CXX_HAS_ATOL=1)
-  ENDIF()
-  KWSYS_PLATFORM_CXX_TEST(KWSYS_CXX_HAS_ATOLL
-    "Checking whether CXX compiler has atoll" DIRECT)
-  IF(KWSYS_CXX_HAS_ATOLL)
-    SET_PROPERTY(SOURCE SystemInformation.cxx APPEND PROPERTY
-      COMPILE_DEFINITIONS KWSYS_CXX_HAS_ATOLL=1)
-  ENDIF()
-  KWSYS_PLATFORM_CXX_TEST(KWSYS_CXX_HAS__ATOI64
-    "Checking whether CXX compiler has _atoi64" DIRECT)
-  IF(KWSYS_CXX_HAS__ATOI64)
-    SET_PROPERTY(SOURCE SystemInformation.cxx APPEND PROPERTY
-      COMPILE_DEFINITIONS KWSYS_CXX_HAS__ATOI64=1)
-  ENDIF()
-  IF(UNIX)
-    INCLUDE(CheckIncludeFileCXX)
+  endif()
+  if(UNIX)
+    include(CheckIncludeFileCXX)
     # check for simple stack trace
     # usually it's in libc but on FreeBSD
     # it's in libexecinfo
-    FIND_LIBRARY(EXECINFO_LIB "execinfo")
-    MARK_AS_ADVANCED(EXECINFO_LIB)
-    IF (NOT EXECINFO_LIB)
-      SET(EXECINFO_LIB "")
-    ENDIF()
+    find_library(EXECINFO_LIB "execinfo")
+    mark_as_advanced(EXECINFO_LIB)
+    if (NOT EXECINFO_LIB)
+      set(EXECINFO_LIB "")
+    endif()
     CHECK_INCLUDE_FILE_CXX("execinfo.h" KWSYS_CXX_HAS_EXECINFOH)
-    IF (KWSYS_CXX_HAS_EXECINFOH)
+    if (KWSYS_CXX_HAS_EXECINFOH)
       # we have the backtrace header check if it
       # can be used with this compiler
-      SET(KWSYS_PLATFORM_CXX_TEST_LINK_LIBRARIES ${EXECINFO_LIB})
+      set(KWSYS_PLATFORM_CXX_TEST_LINK_LIBRARIES ${EXECINFO_LIB})
       KWSYS_PLATFORM_CXX_TEST(KWSYS_CXX_HAS_BACKTRACE
          "Checking whether backtrace works with this C++ compiler" DIRECT)
-      SET(KWSYS_PLATFORM_CXX_TEST_LINK_LIBRARIES)
-      IF (KWSYS_CXX_HAS_BACKTRACE)
+      set(KWSYS_PLATFORM_CXX_TEST_LINK_LIBRARIES)
+      if (KWSYS_CXX_HAS_BACKTRACE)
         # backtrace is supported by this system and compiler.
         # now check for the more advanced capabilities.
-        SET_PROPERTY(SOURCE SystemInformation.cxx APPEND PROPERTY
+        set_property(SOURCE SystemInformation.cxx APPEND PROPERTY
           COMPILE_DEFINITIONS KWSYS_SYSTEMINFORMATION_HAS_BACKTRACE=1)
         # check for symbol lookup using dladdr
         CHECK_INCLUDE_FILE_CXX("dlfcn.h" KWSYS_CXX_HAS_DLFCNH)
-        IF (KWSYS_CXX_HAS_DLFCNH)
+        if (KWSYS_CXX_HAS_DLFCNH)
           # we have symbol lookup libraries and headers
           # check if they can be used with this compiler
-          SET(KWSYS_PLATFORM_CXX_TEST_LINK_LIBRARIES ${CMAKE_DL_LIBS})
+          set(KWSYS_PLATFORM_CXX_TEST_LINK_LIBRARIES ${CMAKE_DL_LIBS})
             KWSYS_PLATFORM_CXX_TEST(KWSYS_CXX_HAS_DLADDR
             "Checking whether dladdr works with this C++ compiler" DIRECT)
-          SET(KWSYS_PLATFORM_CXX_TEST_LINK_LIBRARIES)
-          IF (KWSYS_CXX_HAS_DLADDR)
+          set(KWSYS_PLATFORM_CXX_TEST_LINK_LIBRARIES)
+          if (KWSYS_CXX_HAS_DLADDR)
             # symbol lookup is supported by this system
             # and compiler.
-            SET_PROPERTY(SOURCE SystemInformation.cxx APPEND PROPERTY
+            set_property(SOURCE SystemInformation.cxx APPEND PROPERTY
               COMPILE_DEFINITIONS KWSYS_SYSTEMINFORMATION_HAS_SYMBOL_LOOKUP=1)
-          ENDIF()
-        ENDIF()
+          endif()
+        endif()
         # c++ demangling support
         # check for cxxabi headers
         CHECK_INCLUDE_FILE_CXX("cxxabi.h" KWSYS_CXX_HAS_CXXABIH)
-        IF (KWSYS_CXX_HAS_CXXABIH)
+        if (KWSYS_CXX_HAS_CXXABIH)
           # check if cxxabi can be used with this
           # system and compiler.
           KWSYS_PLATFORM_CXX_TEST(KWSYS_CXX_HAS_CXXABI
             "Checking whether cxxabi works with this C++ compiler" DIRECT)
-          IF (KWSYS_CXX_HAS_CXXABI)
+          if (KWSYS_CXX_HAS_CXXABI)
             # c++ demangle using cxxabi is supported with
             # this system and compiler
-            SET_PROPERTY(SOURCE SystemInformation.cxx APPEND PROPERTY
+            set_property(SOURCE SystemInformation.cxx APPEND PROPERTY
               COMPILE_DEFINITIONS KWSYS_SYSTEMINFORMATION_HAS_CPP_DEMANGLE=1)
-          ENDIF()
-        ENDIF()
+          endif()
+        endif()
         # basic backtrace works better with release build
         # don't bother with advanced features for release
-        SET_PROPERTY(SOURCE SystemInformation.cxx APPEND PROPERTY
+        set_property(SOURCE SystemInformation.cxx APPEND PROPERTY
           COMPILE_DEFINITIONS_DEBUG KWSYS_SYSTEMINFORMATION_HAS_DEBUG_BUILD=1)
-        SET_PROPERTY(SOURCE SystemInformation.cxx APPEND PROPERTY
+        set_property(SOURCE SystemInformation.cxx APPEND PROPERTY
           COMPILE_DEFINITIONS_RELWITHDEBINFO KWSYS_SYSTEMINFORMATION_HAS_DEBUG_BUILD=1)
-      ENDIF()
-    ENDIF()
-  ENDIF()
-  IF(BORLAND)
-    KWSYS_PLATFORM_CXX_TEST(KWSYS_CXX_HAS_BORLAND_ASM
-      "Checking whether Borland CXX compiler supports assembler instructions" DIRECT)
-    IF(KWSYS_CXX_HAS_BORLAND_ASM)
-      SET_PROPERTY(SOURCE SystemInformation.cxx APPEND PROPERTY
-        COMPILE_DEFINITIONS KWSYS_CXX_HAS_BORLAND_ASM=1)
-      KWSYS_PLATFORM_CXX_TEST(KWSYS_CXX_HAS_BORLAND_ASM_CPUID
-        "Checking whether Borland CXX compiler supports CPUID assembler instruction" DIRECT)
-      IF(KWSYS_CXX_HAS_BORLAND_ASM_CPUID)
-        SET_PROPERTY(SOURCE SystemInformation.cxx APPEND PROPERTY
-          COMPILE_DEFINITIONS KWSYS_CXX_HAS_BORLAND_ASM_CPUID=1)
-      ENDIF()
-    ENDIF()
-  ENDIF()
-  IF(KWSYS_USE___INT64)
-    SET_PROPERTY(SOURCE SystemInformation.cxx testSystemInformation.cxx APPEND PROPERTY
-      COMPILE_DEFINITIONS KWSYS_USE___INT64=1)
-  ENDIF()
-  IF(KWSYS_USE_LONG_LONG)
-    SET_PROPERTY(SOURCE SystemInformation.cxx testSystemInformation.cxx APPEND PROPERTY
-      COMPILE_DEFINITIONS KWSYS_USE_LONG_LONG=1)
-  ENDIF()
-  IF(KWSYS_IOS_HAS_OSTREAM_LONG_LONG)
-    SET_PROPERTY(SOURCE SystemInformation.cxx testSystemInformation.cxx APPEND PROPERTY
-      COMPILE_DEFINITIONS KWSYS_IOS_HAS_OSTREAM_LONG_LONG=1)
-  ENDIF()
-  IF(KWSYS_IOS_HAS_OSTREAM___INT64)
-    SET_PROPERTY(SOURCE SystemInformation.cxx testSystemInformation.cxx APPEND PROPERTY
-      COMPILE_DEFINITIONS KWSYS_IOS_HAS_OSTREAM___INT64=1)
-  ENDIF()
-  IF(KWSYS_BUILD_SHARED)
-    SET_PROPERTY(SOURCE SystemInformation.cxx APPEND PROPERTY
+      endif()
+    endif()
+  endif()
+  if(KWSYS_BUILD_SHARED)
+    set_property(SOURCE SystemInformation.cxx APPEND PROPERTY
       COMPILE_DEFINITIONS KWSYS_BUILD_SHARED=1)
-  ENDIF()
+  endif()
 
-  IF(UNIX AND NOT CYGWIN)
+  if(UNIX AND NOT CYGWIN)
     KWSYS_PLATFORM_CXX_TEST(KWSYS_CXX_HAS_GETLOADAVG
       "Checking whether CXX compiler has getloadavg" DIRECT)
-    IF(KWSYS_CXX_HAS_GETLOADAVG)
-      SET_PROPERTY(SOURCE SystemInformation.cxx APPEND PROPERTY
+    if(KWSYS_CXX_HAS_GETLOADAVG)
+      set_property(SOURCE SystemInformation.cxx APPEND PROPERTY
         COMPILE_DEFINITIONS KWSYS_CXX_HAS_GETLOADAVG=1)
-    ENDIF()
-  ENDIF()
-ENDIF()
+    endif()
+  endif()
+endif()
 
-IF(KWSYS_USE_FStream)
+if(KWSYS_USE_FStream)
   KWSYS_PLATFORM_CXX_TEST(KWSYS_CXX_HAS_EXT_STDIO_FILEBUF_H
     "Checking whether <ext/stdio_filebuf.h> is available" DIRECT)
-ENDIF()
+endif()
 
 #-----------------------------------------------------------------------------
 # Choose a directory for the generated headers.
-IF(NOT KWSYS_HEADER_ROOT)
-  SET(KWSYS_HEADER_ROOT "${PROJECT_BINARY_DIR}")
-ENDIF()
-SET(KWSYS_HEADER_DIR "${KWSYS_HEADER_ROOT}/${KWSYS_NAMESPACE}")
-INCLUDE_DIRECTORIES(${KWSYS_HEADER_ROOT})
+if(NOT KWSYS_HEADER_ROOT)
+  set(KWSYS_HEADER_ROOT "${PROJECT_BINARY_DIR}")
+endif()
+set(KWSYS_HEADER_DIR "${KWSYS_HEADER_ROOT}/${KWSYS_NAMESPACE}")
+include_directories(${KWSYS_HEADER_ROOT})
 
 #-----------------------------------------------------------------------------
-IF(KWSYS_INSTALL_DOC_DIR)
+if(KWSYS_INSTALL_DOC_DIR)
   # Assign the license to the runtime component since it must be
   # distributed with binary forms of this software.
-  IF(KWSYS_INSTALL_COMPONENT_NAME_RUNTIME)
-    SET(KWSYS_INSTALL_LICENSE_OPTIONS ${KWSYS_INSTALL_LICENSE_OPTIONS}
+  if(KWSYS_INSTALL_COMPONENT_NAME_RUNTIME)
+    set(KWSYS_INSTALL_LICENSE_OPTIONS ${KWSYS_INSTALL_LICENSE_OPTIONS}
       COMPONENT ${KWSYS_INSTALL_COMPONENT_NAME_RUNTIME}
       )
-  ENDIF()
+  endif()
 
   # Install the license under the documentation directory.
-  INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/Copyright.txt
+  install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/Copyright.txt
     DESTINATION ${KWSYS_INSTALL_DOC_DIR}/${KWSYS_NAMESPACE}
     ${KWSYS_INSTALL_LICENSE_OPTIONS})
-ENDIF()
+endif()
 
 #-----------------------------------------------------------------------------
 # Build a list of classes and headers we need to implement the
 # selected components.  Initialize with required components.
-SET(KWSYS_CLASSES)
-SET(KWSYS_H_FILES Configure SharedForward)
-SET(KWSYS_HXX_FILES Configure String)
-
-IF(NOT CMake_SOURCE_DIR)
-  SET(KWSYS_HXX_FILES ${KWSYS_HXX_FILES}
-    hashtable hash_fun hash_map hash_set
-    )
-ENDIF()
+set(KWSYS_CLASSES)
+set(KWSYS_H_FILES Configure SharedForward)
+set(KWSYS_HXX_FILES Configure String)
 
 # Add selected C++ classes.
-SET(cppclasses
+set(cppclasses
   Directory DynamicLoader Encoding Glob RegularExpression SystemTools
-  CommandLineArguments IOStream FStream SystemInformation ConsoleBuf
+  CommandLineArguments FStream SystemInformation ConsoleBuf
   )
-FOREACH(cpp ${cppclasses})
-  IF(KWSYS_USE_${cpp})
+foreach(cpp ${cppclasses})
+  if(KWSYS_USE_${cpp})
     # Use the corresponding class.
-    SET(KWSYS_CLASSES ${KWSYS_CLASSES} ${cpp})
+    set(KWSYS_CLASSES ${KWSYS_CLASSES} ${cpp})
 
     # Load component-specific CMake code.
-    IF(EXISTS ${PROJECT_SOURCE_DIR}/kwsys${cpp}.cmake)
-      INCLUDE(${PROJECT_SOURCE_DIR}/kwsys${cpp}.cmake)
-    ENDIF()
-  ENDIF()
-ENDFOREACH()
+    if(EXISTS ${PROJECT_SOURCE_DIR}/kwsys${cpp}.cmake)
+      include(${PROJECT_SOURCE_DIR}/kwsys${cpp}.cmake)
+    endif()
+  endif()
+endforeach()
 
 # Add selected C components.
-FOREACH(c
+foreach(c
     Process Base64 Encoding MD5 Terminal System String
     )
-  IF(KWSYS_USE_${c})
+  if(KWSYS_USE_${c})
     # Use the corresponding header file.
-    SET(KWSYS_H_FILES ${KWSYS_H_FILES} ${c})
+    set(KWSYS_H_FILES ${KWSYS_H_FILES} ${c})
 
     # Load component-specific CMake code.
-    IF(EXISTS ${PROJECT_SOURCE_DIR}/kwsys${c}.cmake)
-      INCLUDE(${PROJECT_SOURCE_DIR}/kwsys${c}.cmake)
-    ENDIF()
-  ENDIF()
-ENDFOREACH()
+    if(EXISTS ${PROJECT_SOURCE_DIR}/kwsys${c}.cmake)
+      include(${PROJECT_SOURCE_DIR}/kwsys${c}.cmake)
+    endif()
+  endif()
+endforeach()
 
 #-----------------------------------------------------------------------------
 # Build a list of sources for the library based on components that are
 # included.
-SET(KWSYS_C_SRCS)
-SET(KWSYS_CXX_SRCS)
+set(KWSYS_C_SRCS)
+set(KWSYS_CXX_SRCS)
 
 # Add the proper sources for this platform's Process implementation.
-IF(KWSYS_USE_Process)
-  IF(NOT UNIX)
+if(KWSYS_USE_Process)
+  if(NOT UNIX)
     # Use the Windows implementation.
-    SET(KWSYS_C_SRCS ${KWSYS_C_SRCS} ProcessWin32.c)
-  ELSE()
+    set(KWSYS_C_SRCS ${KWSYS_C_SRCS} ProcessWin32.c)
+  else()
     # Use the UNIX implementation.
-    SET(KWSYS_C_SRCS ${KWSYS_C_SRCS} ProcessUNIX.c)
-  ENDIF()
-ENDIF()
+    set(KWSYS_C_SRCS ${KWSYS_C_SRCS} ProcessUNIX.c)
+  endif()
+endif()
 
 # Add selected C sources.
-FOREACH(c Base64 Encoding MD5 Terminal System String)
-  IF(KWSYS_USE_${c})
-    IF(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${c}C.c)
-      LIST(APPEND KWSYS_C_SRCS ${c}C.c)
-    ELSE()
-      LIST(APPEND KWSYS_C_SRCS ${c}.c)
-    ENDIF()
-  ENDIF()
-ENDFOREACH()
+foreach(c Base64 Encoding MD5 Terminal System String)
+  if(KWSYS_USE_${c})
+    if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${c}C.c)
+      list(APPEND KWSYS_C_SRCS ${c}C.c)
+    else()
+      list(APPEND KWSYS_C_SRCS ${c}.c)
+    endif()
+  endif()
+endforeach()
 
 # Configure headers of C++ classes and construct the list of sources.
-FOREACH(c ${KWSYS_CLASSES})
+foreach(c ${KWSYS_CLASSES})
   # Add this source to the list of source files for the library.
-  IF(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${c}CXX.cxx)
-    LIST(APPEND KWSYS_CXX_SRCS ${c}CXX.cxx)
-  ELSEIF(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${c}.cxx)
-    LIST(APPEND KWSYS_CXX_SRCS ${c}.cxx)
-  ENDIF()
+  if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${c}CXX.cxx)
+    list(APPEND KWSYS_CXX_SRCS ${c}CXX.cxx)
+  elseif(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${c}.cxx)
+    list(APPEND KWSYS_CXX_SRCS ${c}.cxx)
+  endif()
 
   # Configure the header for this class.
-  CONFIGURE_FILE(${PROJECT_SOURCE_DIR}/${c}.hxx.in ${KWSYS_HEADER_DIR}/${c}.hxx
+  configure_file(${PROJECT_SOURCE_DIR}/${c}.hxx.in ${KWSYS_HEADER_DIR}/${c}.hxx
                  @ONLY IMMEDIATE)
-  SET(KWSYS_CXX_SRCS ${KWSYS_CXX_SRCS} ${KWSYS_HEADER_DIR}/${c}.hxx)
+  set(KWSYS_CXX_SRCS ${KWSYS_CXX_SRCS} ${KWSYS_HEADER_DIR}/${c}.hxx)
 
   # Create an install target for the header.
-  IF(KWSYS_INSTALL_INCLUDE_DIR)
-    INSTALL(FILES ${KWSYS_HEADER_DIR}/${c}.hxx
+  if(KWSYS_INSTALL_INCLUDE_DIR)
+    install(FILES ${KWSYS_HEADER_DIR}/${c}.hxx
       DESTINATION ${KWSYS_INSTALL_INCLUDE_DIR}/${KWSYS_NAMESPACE}
       ${KWSYS_INSTALL_INCLUDE_OPTIONS})
-  ENDIF()
-ENDFOREACH()
+  endif()
+endforeach()
 
 # Configure C headers.
-FOREACH(h ${KWSYS_H_FILES})
+foreach(h ${KWSYS_H_FILES})
   # Configure the header into the given directory.
-  CONFIGURE_FILE(${PROJECT_SOURCE_DIR}/${h}.h.in ${KWSYS_HEADER_DIR}/${h}.h
+  configure_file(${PROJECT_SOURCE_DIR}/${h}.h.in ${KWSYS_HEADER_DIR}/${h}.h
                  @ONLY IMMEDIATE)
-  SET(KWSYS_C_SRCS ${KWSYS_C_SRCS} ${KWSYS_HEADER_DIR}/${h}.h)
+  set(KWSYS_C_SRCS ${KWSYS_C_SRCS} ${KWSYS_HEADER_DIR}/${h}.h)
 
   # Create an install target for the header.
-  IF(KWSYS_INSTALL_INCLUDE_DIR)
-    INSTALL(FILES ${KWSYS_HEADER_DIR}/${h}.h
+  if(KWSYS_INSTALL_INCLUDE_DIR)
+    install(FILES ${KWSYS_HEADER_DIR}/${h}.h
       DESTINATION ${KWSYS_INSTALL_INCLUDE_DIR}/${KWSYS_NAMESPACE}
       ${KWSYS_INSTALL_INCLUDE_OPTIONS})
-  ENDIF()
-ENDFOREACH()
+  endif()
+endforeach()
 
 # Configure other C++ headers.
-FOREACH(h ${KWSYS_HXX_FILES})
+foreach(h ${KWSYS_HXX_FILES})
   # Configure the header into the given directory.
-  CONFIGURE_FILE(${PROJECT_SOURCE_DIR}/${h}.hxx.in ${KWSYS_HEADER_DIR}/${h}.hxx
+  configure_file(${PROJECT_SOURCE_DIR}/${h}.hxx.in ${KWSYS_HEADER_DIR}/${h}.hxx
                  @ONLY IMMEDIATE)
-  SET(KWSYS_CXX_SRCS ${KWSYS_CXX_SRCS} ${KWSYS_HEADER_DIR}/${h}.hxx)
+  set(KWSYS_CXX_SRCS ${KWSYS_CXX_SRCS} ${KWSYS_HEADER_DIR}/${h}.hxx)
 
   # Create an install target for the header.
-  IF(KWSYS_INSTALL_INCLUDE_DIR)
-    INSTALL(FILES ${KWSYS_HEADER_DIR}/${h}.hxx
+  if(KWSYS_INSTALL_INCLUDE_DIR)
+    install(FILES ${KWSYS_HEADER_DIR}/${h}.hxx
       DESTINATION ${KWSYS_INSTALL_INCLUDE_DIR}/${KWSYS_NAMESPACE}
       ${KWSYS_INSTALL_INCLUDE_OPTIONS})
-  ENDIF()
-ENDFOREACH()
+  endif()
+endforeach()
 
 #-----------------------------------------------------------------------------
 # Add the library with the configured name and list of sources.
-IF(KWSYS_C_SRCS OR KWSYS_CXX_SRCS)
-  IF(KWSYS_SPLIT_OBJECTS_FROM_INTERFACE)
-    SET(KWSYS_TARGET_INTERFACE ${KWSYS_NAMESPACE})
-    SET(KWSYS_TARGET_OBJECT ${KWSYS_NAMESPACE}_objects)
-    SET(KWSYS_TARGET_LINK ${KWSYS_NAMESPACE}_private)
-    SET(KWSYS_TARGET_INSTALL ${KWSYS_TARGET_INTERFACE} ${KWSYS_TARGET_LINK})
-    SET(KWSYS_LINK_DEPENDENCY INTERFACE)
-    ADD_LIBRARY(${KWSYS_TARGET_OBJECT} OBJECT
+if(KWSYS_C_SRCS OR KWSYS_CXX_SRCS)
+  if(KWSYS_SPLIT_OBJECTS_FROM_INTERFACE)
+    set(KWSYS_TARGET_INTERFACE ${KWSYS_NAMESPACE})
+    set(KWSYS_TARGET_OBJECT ${KWSYS_NAMESPACE}_objects)
+    set(KWSYS_TARGET_LINK ${KWSYS_NAMESPACE}_private)
+    set(KWSYS_TARGET_INSTALL ${KWSYS_TARGET_INTERFACE} ${KWSYS_TARGET_LINK})
+    set(KWSYS_LINK_DEPENDENCY INTERFACE)
+    add_library(${KWSYS_TARGET_OBJECT} OBJECT
       ${KWSYS_C_SRCS} ${KWSYS_CXX_SRCS})
-    IF(KWSYS_BUILD_SHARED OR KWSYS_BUILD_PIC)
-      SET_PROPERTY(TARGET ${KWSYS_TARGET_OBJECT} PROPERTY
+    if(KWSYS_BUILD_SHARED OR KWSYS_BUILD_PIC)
+      set_property(TARGET ${KWSYS_TARGET_OBJECT} PROPERTY
         POSITION_INDEPENDENT_CODE TRUE)
-    ENDIF()
-    ADD_LIBRARY(${KWSYS_TARGET_INTERFACE} INTERFACE)
-    ADD_LIBRARY(${KWSYS_TARGET_LINK} INTERFACE)
-    TARGET_LINK_LIBRARIES(${KWSYS_TARGET_LINK} INTERFACE
+    endif()
+    add_library(${KWSYS_TARGET_INTERFACE} INTERFACE)
+    add_library(${KWSYS_TARGET_LINK} INTERFACE)
+    target_link_libraries(${KWSYS_TARGET_LINK} INTERFACE
       ${KWSYS_TARGET_INTERFACE})
-    TARGET_SOURCES(${KWSYS_TARGET_LINK} INTERFACE
+    target_sources(${KWSYS_TARGET_LINK} INTERFACE
       $<TARGET_OBJECTS:${KWSYS_TARGET_OBJECT}>)
     target_compile_features(${KWSYS_TARGET_OBJECT} PRIVATE ${KWSYS_CXX_COMPILE_FEATURES})
     target_compile_features(${KWSYS_TARGET_INTERFACE} INTERFACE ${KWSYS_CXX_COMPILE_FEATURES})
-  ELSE()
-    SET(KWSYS_TARGET_INTERFACE ${KWSYS_NAMESPACE})
-    SET(KWSYS_TARGET_OBJECT ${KWSYS_NAMESPACE})
-    SET(KWSYS_TARGET_LINK ${KWSYS_NAMESPACE})
+  else()
+    set(KWSYS_TARGET_INTERFACE ${KWSYS_NAMESPACE})
+    set(KWSYS_TARGET_OBJECT ${KWSYS_NAMESPACE})
+    set(KWSYS_TARGET_LINK ${KWSYS_NAMESPACE})
     set(KWSYS_TARGET_INSTALL ${KWSYS_TARGET_LINK})
-    SET(KWSYS_LINK_DEPENDENCY PUBLIC)
-    ADD_LIBRARY(${KWSYS_TARGET_INTERFACE} ${KWSYS_LIBRARY_TYPE}
+    set(KWSYS_LINK_DEPENDENCY PUBLIC)
+    add_library(${KWSYS_TARGET_INTERFACE} ${KWSYS_LIBRARY_TYPE}
       ${KWSYS_C_SRCS} ${KWSYS_CXX_SRCS})
     target_compile_features(${KWSYS_TARGET_INTERFACE} PUBLIC ${KWSYS_CXX_COMPILE_FEATURES})
-  ENDIF()
+  endif()
   if (KWSYS_ALIAS_TARGET)
     add_library(${KWSYS_ALIAS_TARGET} ALIAS ${KWSYS_TARGET_INTERFACE})
   endif ()
-  SET_TARGET_PROPERTIES(${KWSYS_TARGET_OBJECT} PROPERTIES
+  set_target_properties(${KWSYS_TARGET_OBJECT} PROPERTIES
     C_CLANG_TIDY ""
     CXX_CLANG_TIDY ""
     C_INCLUDE_WHAT_YOU_USE ""
     CXX_INCLUDE_WHAT_YOU_USE ""
     LABELS "${KWSYS_LABELS_LIB}")
-  IF(KWSYS_USE_DynamicLoader)
-    IF(UNIX)
-      TARGET_LINK_LIBRARIES(${KWSYS_TARGET_INTERFACE} ${KWSYS_LINK_DEPENDENCY}
+  if(KWSYS_USE_DynamicLoader)
+    if(UNIX)
+      target_link_libraries(${KWSYS_TARGET_INTERFACE} ${KWSYS_LINK_DEPENDENCY}
         ${CMAKE_DL_LIBS})
-    ENDIF()
-  ENDIF()
+    endif()
+  endif()
 
-  IF(KWSYS_USE_SystemInformation)
-    IF(WIN32)
-      TARGET_LINK_LIBRARIES(${KWSYS_TARGET_INTERFACE} ${KWSYS_LINK_DEPENDENCY} ws2_32)
+  if(KWSYS_USE_SystemInformation)
+    if(WIN32)
+      target_link_libraries(${KWSYS_TARGET_INTERFACE} ${KWSYS_LINK_DEPENDENCY} ws2_32)
       # link in dbghelp.dll for symbol lookup if MSVC 1800 or later
       # Note that the dbghelp runtime is part of MS Windows OS
-      IF(MSVC_VERSION AND NOT MSVC_VERSION VERSION_LESS 1800)
-        TARGET_LINK_LIBRARIES(${KWSYS_TARGET_INTERFACE} ${KWSYS_LINK_DEPENDENCY} dbghelp)
-      ENDIF()
-      IF(KWSYS_SYS_HAS_PSAPI)
-        TARGET_LINK_LIBRARIES(${KWSYS_TARGET_INTERFACE} ${KWSYS_LINK_DEPENDENCY}
-          Psapi)
-      ENDIF()
-    ELSEIF(UNIX)
-      IF (EXECINFO_LIB AND KWSYS_CXX_HAS_BACKTRACE)
+      if(MSVC_VERSION AND NOT MSVC_VERSION VERSION_LESS 1800)
+        target_link_libraries(${KWSYS_TARGET_INTERFACE} ${KWSYS_LINK_DEPENDENCY} dbghelp)
+      endif()
+      if(KWSYS_SYS_HAS_PSAPI)
+        target_link_libraries(${KWSYS_TARGET_INTERFACE} ${KWSYS_LINK_DEPENDENCY}
+          psapi)
+      endif()
+    elseif(UNIX)
+      if (EXECINFO_LIB AND KWSYS_CXX_HAS_BACKTRACE)
         # backtrace on FreeBSD is not in libc
-        TARGET_LINK_LIBRARIES(${KWSYS_TARGET_INTERFACE} ${KWSYS_LINK_DEPENDENCY}
+        target_link_libraries(${KWSYS_TARGET_INTERFACE} ${KWSYS_LINK_DEPENDENCY}
           ${EXECINFO_LIB})
-      ENDIF()
-      IF (KWSYS_CXX_HAS_DLADDR)
+      endif()
+      if (KWSYS_CXX_HAS_DLADDR)
         # for symbol lookup using dladdr
-        TARGET_LINK_LIBRARIES(${KWSYS_TARGET_INTERFACE} ${KWSYS_LINK_DEPENDENCY}
+        target_link_libraries(${KWSYS_TARGET_INTERFACE} ${KWSYS_LINK_DEPENDENCY}
           ${CMAKE_DL_LIBS})
-      ENDIF()
-      IF (CMAKE_SYSTEM_NAME STREQUAL "SunOS")
-        TARGET_LINK_LIBRARIES(${KWSYS_TARGET_INTERFACE} ${KWSYS_LINK_DEPENDENCY}
+      endif()
+      if (CMAKE_SYSTEM_NAME STREQUAL "SunOS")
+        target_link_libraries(${KWSYS_TARGET_INTERFACE} ${KWSYS_LINK_DEPENDENCY}
           socket)
-      ENDIF()
-    ENDIF()
-  ENDIF()
+      endif()
+    endif()
+  endif()
 
   # Apply user-defined target properties to the library.
-  IF(KWSYS_PROPERTIES_CXX)
-    SET_TARGET_PROPERTIES(${KWSYS_TARGET_INTERFACE} PROPERTIES
+  if(KWSYS_PROPERTIES_CXX)
+    set_target_properties(${KWSYS_TARGET_INTERFACE} PROPERTIES
       ${KWSYS_PROPERTIES_CXX})
-  ENDIF()
+  endif()
 
   # Set up include usage requirement
-  IF(COMMAND TARGET_INCLUDE_DIRECTORIES)
-    TARGET_INCLUDE_DIRECTORIES(${KWSYS_TARGET_INTERFACE} INTERFACE
+  if(COMMAND TARGET_INCLUDE_DIRECTORIES)
+    target_include_directories(${KWSYS_TARGET_INTERFACE} INTERFACE
       $<BUILD_INTERFACE:${KWSYS_HEADER_ROOT}>)
-    IF(KWSYS_INSTALL_INCLUDE_DIR)
-      TARGET_INCLUDE_DIRECTORIES(${KWSYS_TARGET_INTERFACE} INTERFACE
+    if(KWSYS_INSTALL_INCLUDE_DIR)
+      target_include_directories(${KWSYS_TARGET_INTERFACE} INTERFACE
         $<INSTALL_INTERFACE:${KWSYS_INSTALL_INCLUDE_DIR}>)
-    ENDIF()
-  ENDIF()
+    endif()
+  endif()
 
   # Create an install target for the library.
-  IF(KWSYS_INSTALL_LIBRARY_RULE)
-    INSTALL(TARGETS ${KWSYS_TARGET_INSTALL} ${KWSYS_INSTALL_LIBRARY_RULE})
-  ENDIF()
-  IF(KWSYS_INSTALL_NAMELINK_RULE)
-    INSTALL(TARGETS ${KWSYS_TARGET_INSTALL} ${KWSYS_INSTALL_NAMELINK_RULE})
-  ENDIF()
-ENDIF()
+  if(KWSYS_INSTALL_LIBRARY_RULE)
+    install(TARGETS ${KWSYS_TARGET_INSTALL} ${KWSYS_INSTALL_LIBRARY_RULE})
+  endif()
+  if(KWSYS_INSTALL_NAMELINK_RULE)
+    install(TARGETS ${KWSYS_TARGET_INSTALL} ${KWSYS_INSTALL_NAMELINK_RULE})
+  endif()
+endif()
 
 # Add a C-only library if requested.
-IF(KWSYS_ENABLE_C AND KWSYS_C_SRCS)
- IF(KWSYS_SPLIT_OBJECTS_FROM_INTERFACE)
-    SET(KWSYS_TARGET_C_INTERFACE ${KWSYS_NAMESPACE}_c)
-    SET(KWSYS_TARGET_C_OBJECT ${KWSYS_NAMESPACE}_c_objects)
-    SET(KWSYS_TARGET_C_LINK ${KWSYS_NAMESPACE}_c_private)
-    SET(KWSYS_TARGET_C_INSTALL
+if(KWSYS_ENABLE_C AND KWSYS_C_SRCS)
+ if(KWSYS_SPLIT_OBJECTS_FROM_INTERFACE)
+    set(KWSYS_TARGET_C_INTERFACE ${KWSYS_NAMESPACE}_c)
+    set(KWSYS_TARGET_C_OBJECT ${KWSYS_NAMESPACE}_c_objects)
+    set(KWSYS_TARGET_C_LINK ${KWSYS_NAMESPACE}_c_private)
+    set(KWSYS_TARGET_C_INSTALL
       ${KWSYS_TARGET_C_INTERFACE} ${KWSYS_TARGET_C_LINK})
-    SET(KWSYS_LINK_DEPENDENCY INTERFACE)
-    ADD_LIBRARY(${KWSYS_TARGET_C_OBJECT} OBJECT ${KWSYS_C_SRCS})
-    IF(KWSYS_BUILD_SHARED OR KWSYS_BUILD_PIC)
-      SET_PROPERTY(TARGET ${KWSYS_TARGET_C_OBJECT} PROPERTY
+    set(KWSYS_LINK_DEPENDENCY INTERFACE)
+    add_library(${KWSYS_TARGET_C_OBJECT} OBJECT ${KWSYS_C_SRCS})
+    if(KWSYS_BUILD_SHARED OR KWSYS_BUILD_PIC)
+      set_property(TARGET ${KWSYS_TARGET_C_OBJECT} PROPERTY
         POSITION_INDEPENDENT_CODE TRUE)
-    ENDIF()
-    ADD_LIBRARY(${KWSYS_TARGET_C_INTERFACE} INTERFACE)
-    ADD_LIBRARY(${KWSYS_TARGET_C_LINK} INTERFACE)
-    TARGET_LINK_LIBRARIES(${KWSYS_TARGET_C_LINK} INTERFACE
+    endif()
+    add_library(${KWSYS_TARGET_C_INTERFACE} INTERFACE)
+    add_library(${KWSYS_TARGET_C_LINK} INTERFACE)
+    target_link_libraries(${KWSYS_TARGET_C_LINK} INTERFACE
       ${KWSYS_TARGET_C_INTERFACE})
-    TARGET_SOURCES(${KWSYS_TARGET_C_LINK} INTERFACE
+    target_sources(${KWSYS_TARGET_C_LINK} INTERFACE
       $<TARGET_OBJECTS:${KWSYS_TARGET_C_OBJECT}>)
-  ELSE()
-    SET(KWSYS_TARGET_C_INTERFACE ${KWSYS_NAMESPACE}_c)
-    SET(KWSYS_TARGET_C_OBJECT ${KWSYS_NAMESPACE}_c)
-    SET(KWSYS_TARGET_C_LINK ${KWSYS_NAMESPACE}_c)
-    SET(KWSYS_TARGET_C_INSTALL ${KWSYS_TARGET_C_LINK})
-    SET(KWSYS_LINK_DEPENDENCY PUBLIC)
-    ADD_LIBRARY(${KWSYS_TARGET_C_INTERFACE} ${KWSYS_LIBRARY_TYPE}
+  else()
+    set(KWSYS_TARGET_C_INTERFACE ${KWSYS_NAMESPACE}_c)
+    set(KWSYS_TARGET_C_OBJECT ${KWSYS_NAMESPACE}_c)
+    set(KWSYS_TARGET_C_LINK ${KWSYS_NAMESPACE}_c)
+    set(KWSYS_TARGET_C_INSTALL ${KWSYS_TARGET_C_LINK})
+    set(KWSYS_LINK_DEPENDENCY PUBLIC)
+    add_library(${KWSYS_TARGET_C_INTERFACE} ${KWSYS_LIBRARY_TYPE}
       ${KWSYS_C_SRCS})
-  ENDIF()
-  SET_TARGET_PROPERTIES(${KWSYS_TARGET_C_OBJECT} PROPERTIES
+  endif()
+  set_target_properties(${KWSYS_TARGET_C_OBJECT} PROPERTIES
     LABELS "${KWSYS_LABELS_LIB}")
 
   # Apply user-defined target properties to the library.
-  IF(KWSYS_PROPERTIES_C)
-    SET_TARGET_PROPERTIES(${KWSYS_TARGET_C_INTERFACE} PROPERTIES
+  if(KWSYS_PROPERTIES_C)
+    set_target_properties(${KWSYS_TARGET_C_INTERFACE} PROPERTIES
       ${KWSYS_PROPERTIES_C})
-  ENDIF()
+  endif()
 
   # Set up include usage requirement
-  IF(COMMAND TARGET_INCLUDE_DIRECTORIES)
-    TARGET_INCLUDE_DIRECTORIES(${KWSYS_TARGET_C_INTERFACE} INTERFACE
+  if(COMMAND TARGET_INCLUDE_DIRECTORIES)
+    target_include_directories(${KWSYS_TARGET_C_INTERFACE} INTERFACE
       $<BUILD_INTERFACE:${KWSYS_HEADER_ROOT}>)
-    IF(KWSYS_INSTALL_INCLUDE_DIR)
-      TARGET_INCLUDE_DIRECTORIES(${KWSYS_TARGET_C_INTERFACE} INTERFACE
+    if(KWSYS_INSTALL_INCLUDE_DIR)
+      target_include_directories(${KWSYS_TARGET_C_INTERFACE} INTERFACE
         $<INSTALL_INTERFACE:${KWSYS_INSTALL_INCLUDE_DIR}>)
-    ENDIF()
-  ENDIF()
+    endif()
+  endif()
 
   # Create an install target for the library.
-  IF(KWSYS_INSTALL_LIBRARY_RULE)
-    INSTALL(TARGETS ${KWSYS_TARGET_C_INSTALL})
-  ENDIF()
-ENDIF()
+  if(KWSYS_INSTALL_LIBRARY_RULE)
+    install(TARGETS ${KWSYS_TARGET_C_INSTALL})
+  endif()
+endif()
 
 # For building kwsys itself, we use a macro defined on the command
 # line to configure the namespace in the C and C++ source files.
-ADD_DEFINITIONS("-DKWSYS_NAMESPACE=${KWSYS_NAMESPACE}")
+add_definitions("-DKWSYS_NAMESPACE=${KWSYS_NAMESPACE}")
 
 # Disable deprecation warnings for standard C functions.
-IF(MSVC OR (WIN32 AND (CMAKE_C_COMPILER_ID STREQUAL "Intel" OR
+if(MSVC OR (WIN32 AND (CMAKE_C_COMPILER_ID STREQUAL "Intel" OR
    (CMAKE_C_COMPILER_ID STREQUAL "Clang" AND CMAKE_CXX_SIMULATE_ID STREQUAL "MSVC"))))
-  ADD_DEFINITIONS(
+  add_definitions(
     -D_CRT_NONSTDC_NO_DEPRECATE
     -D_CRT_SECURE_NO_DEPRECATE
     -D_CRT_SECURE_NO_WARNINGS
     -D_SCL_SECURE_NO_DEPRECATE
     )
-ENDIF()
+endif()
 
-IF(WIN32)
+if(WIN32)
   # Help enforce the use of wide Windows apis.
-  ADD_DEFINITIONS(-DUNICODE -D_UNICODE)
-ENDIF()
+  add_definitions(-DUNICODE -D_UNICODE)
+endif()
 
-IF(KWSYS_USE_String)
+if(KWSYS_USE_String)
   # Activate code in "String.c".  See the comment in the source.
-  SET_SOURCE_FILES_PROPERTIES(String.c PROPERTIES
+  set_source_files_properties(String.c PROPERTIES
     COMPILE_FLAGS "-DKWSYS_STRING_C")
-ENDIF()
+endif()
 
-IF(KWSYS_USE_Encoding)
+if(KWSYS_USE_Encoding)
   # Set default 8 bit encoding in "EndcodingC.c".
-  SET_PROPERTY(SOURCE EncodingC.c EncodingCXX.cxx APPEND PROPERTY COMPILE_DEFINITIONS
+  set_property(SOURCE EncodingC.c EncodingCXX.cxx APPEND PROPERTY COMPILE_DEFINITIONS
     KWSYS_ENCODING_DEFAULT_CODEPAGE=${KWSYS_ENCODING_DEFAULT_CODEPAGE})
-ENDIF()
+endif()
 
 #-----------------------------------------------------------------------------
 # Setup testing if not being built as part of another project.
-IF(KWSYS_STANDALONE OR CMake_SOURCE_DIR)
-  IF(BUILD_TESTING)
+if(KWSYS_STANDALONE OR CMake_SOURCE_DIR)
+  if(BUILD_TESTING)
     # Compute the location of executables.
-    SET(EXEC_DIR "${CMAKE_CURRENT_BINARY_DIR}")
-    IF(EXECUTABLE_OUTPUT_PATH)
-      SET(EXEC_DIR "${EXECUTABLE_OUTPUT_PATH}")
-    ENDIF()
+    set(EXEC_DIR "${CMAKE_CURRENT_BINARY_DIR}")
+    if(CMAKE_RUNTIME_OUTPUT_DIRECTORY)
+      set(EXEC_DIR "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}")
+    endif()
 
     # C tests
-    SET(KWSYS_C_TESTS
+    set(KWSYS_C_TESTS
       testEncode.c
       testTerminal.c
       )
-    IF(KWSYS_STANDALONE)
-      SET(KWSYS_C_TESTS ${KWSYS_C_TESTS} testFail.c)
-    ENDIF()
-    CREATE_TEST_SOURCELIST(
+    if(KWSYS_STANDALONE)
+      set(KWSYS_C_TESTS ${KWSYS_C_TESTS} testFail.c)
+    endif()
+    create_test_sourcelist(
       KWSYS_C_TEST_SRCS ${KWSYS_NAMESPACE}TestsC.c
       ${KWSYS_C_TESTS}
       )
-    ADD_EXECUTABLE(${KWSYS_NAMESPACE}TestsC ${KWSYS_C_TEST_SRCS})
-    SET_PROPERTY(TARGET ${KWSYS_NAMESPACE}TestsC PROPERTY LABELS ${KWSYS_LABELS_EXE})
-    TARGET_LINK_LIBRARIES(${KWSYS_NAMESPACE}TestsC ${KWSYS_TARGET_C_LINK})
-    FOREACH(testfile ${KWSYS_C_TESTS})
+    add_executable(${KWSYS_NAMESPACE}TestsC ${KWSYS_C_TEST_SRCS})
+    set_property(TARGET ${KWSYS_NAMESPACE}TestsC PROPERTY LABELS ${KWSYS_LABELS_EXE})
+    target_link_libraries(${KWSYS_NAMESPACE}TestsC ${KWSYS_TARGET_C_LINK})
+    foreach(testfile ${KWSYS_C_TESTS})
       get_filename_component(test "${testfile}" NAME_WE)
-      ADD_TEST(kwsys.${test} ${EXEC_DIR}/${KWSYS_NAMESPACE}TestsC ${test} ${KWSYS_TEST_ARGS_${test}})
-      SET_PROPERTY(TEST kwsys.${test} PROPERTY LABELS ${KWSYS_LABELS_TEST})
-    ENDFOREACH()
+      add_test(kwsys.${test} ${EXEC_DIR}/${KWSYS_NAMESPACE}TestsC ${test} ${KWSYS_TEST_ARGS_${test}})
+      set_property(TEST kwsys.${test} PROPERTY LABELS ${KWSYS_LABELS_TEST})
+    endforeach()
 
     # C++ tests
-    IF(NOT WATCOM AND NOT CMake_SOURCE_DIR)
-      SET(KWSYS_CXX_TESTS
-        testHashSTL.cxx
-        )
-    ENDIF()
-    SET(KWSYS_CXX_TESTS ${KWSYS_CXX_TESTS}
+    set(KWSYS_CXX_TESTS ${KWSYS_CXX_TESTS}
       testConfigure.cxx
       testSystemTools.cxx
       testCommandLineArguments.cxx
       testCommandLineArguments1.cxx
       testDirectory.cxx
       )
-    IF(KWSYS_STL_HAS_WSTRING)
-      SET(KWSYS_CXX_TESTS ${KWSYS_CXX_TESTS}
+    if(KWSYS_STL_HAS_WSTRING)
+      set(KWSYS_CXX_TESTS ${KWSYS_CXX_TESTS}
         testEncoding.cxx
         )
-    ENDIF()
-    IF(KWSYS_USE_FStream)
-      SET(KWSYS_CXX_TESTS ${KWSYS_CXX_TESTS}
+    endif()
+    if(KWSYS_USE_FStream)
+      set(KWSYS_CXX_TESTS ${KWSYS_CXX_TESTS}
         testFStream.cxx
         )
-    ENDIF()
-    IF(KWSYS_USE_ConsoleBuf)
-      ADD_EXECUTABLE(testConsoleBufChild testConsoleBufChild.cxx)
-      SET_PROPERTY(TARGET testConsoleBufChild PROPERTY C_CLANG_TIDY "")
-      SET_PROPERTY(TARGET testConsoleBufChild PROPERTY CXX_CLANG_TIDY "")
-      SET_PROPERTY(TARGET testConsoleBufChild PROPERTY C_INCLUDE_WHAT_YOU_USE "")
-      SET_PROPERTY(TARGET testConsoleBufChild PROPERTY CXX_INCLUDE_WHAT_YOU_USE "")
-      SET_PROPERTY(TARGET testConsoleBufChild PROPERTY LABELS ${KWSYS_LABELS_EXE})
-      TARGET_LINK_LIBRARIES(testConsoleBufChild ${KWSYS_TARGET_LINK})
-      SET(KWSYS_CXX_TESTS ${KWSYS_CXX_TESTS}
+    endif()
+    if(KWSYS_USE_ConsoleBuf)
+      add_executable(testConsoleBufChild testConsoleBufChild.cxx)
+      set_property(TARGET testConsoleBufChild PROPERTY C_CLANG_TIDY "")
+      set_property(TARGET testConsoleBufChild PROPERTY CXX_CLANG_TIDY "")
+      set_property(TARGET testConsoleBufChild PROPERTY C_INCLUDE_WHAT_YOU_USE "")
+      set_property(TARGET testConsoleBufChild PROPERTY CXX_INCLUDE_WHAT_YOU_USE "")
+      set_property(TARGET testConsoleBufChild PROPERTY LABELS ${KWSYS_LABELS_EXE})
+      target_link_libraries(testConsoleBufChild ${KWSYS_TARGET_LINK})
+      set(KWSYS_CXX_TESTS ${KWSYS_CXX_TESTS}
         testConsoleBuf.cxx
         )
-      IF(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC" AND
+      if(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC" AND
          CMAKE_CXX_COMPILER_VERSION VERSION_GREATER "19.0.23506")
         set_property(SOURCE testConsoleBuf.cxx testConsoleBufChild.cxx PROPERTY COMPILE_FLAGS /utf-8)
-      ENDIF()
-      SET_PROPERTY(SOURCE testConsoleBuf.cxx APPEND PROPERTY COMPILE_DEFINITIONS
+      endif()
+      set_property(SOURCE testConsoleBuf.cxx APPEND PROPERTY COMPILE_DEFINITIONS
         KWSYS_ENCODING_DEFAULT_CODEPAGE=${KWSYS_ENCODING_DEFAULT_CODEPAGE})
-    ENDIF()
-    IF(KWSYS_USE_SystemInformation)
-      SET(KWSYS_CXX_TESTS ${KWSYS_CXX_TESTS} testSystemInformation.cxx)
-    ENDIF()
-    IF(KWSYS_USE_DynamicLoader)
-      SET(KWSYS_CXX_TESTS ${KWSYS_CXX_TESTS} testDynamicLoader.cxx)
+    endif()
+    if(KWSYS_USE_SystemInformation)
+      set(KWSYS_CXX_TESTS ${KWSYS_CXX_TESTS} testSystemInformation.cxx)
+    endif()
+    if(KWSYS_USE_DynamicLoader)
+      set(KWSYS_CXX_TESTS ${KWSYS_CXX_TESTS} testDynamicLoader.cxx)
       # If kwsys contains the DynamicLoader, need extra library
-      ADD_LIBRARY(${KWSYS_NAMESPACE}TestDynload MODULE testDynload.c)
-      SET_PROPERTY(TARGET ${KWSYS_NAMESPACE}TestDynload PROPERTY LABELS ${KWSYS_LABELS_LIB})
-      ADD_DEPENDENCIES(${KWSYS_NAMESPACE}TestDynload ${KWSYS_TARGET_INTERFACE})
+      add_library(${KWSYS_NAMESPACE}TestDynload MODULE testDynload.c)
+      set_property(TARGET ${KWSYS_NAMESPACE}TestDynload PROPERTY LABELS ${KWSYS_LABELS_LIB})
+      add_dependencies(${KWSYS_NAMESPACE}TestDynload ${KWSYS_TARGET_INTERFACE})
 
       if (WIN32)
         # Windows tests supported flags.
@@ -1134,33 +1019,33 @@
         add_dependencies(${KWSYS_NAMESPACE}TestDynloadUse ${KWSYS_TARGET_INTERFACE})
         target_link_libraries(${KWSYS_NAMESPACE}TestDynloadUse PRIVATE ${KWSYS_NAMESPACE}TestDynloadImpl)
       endif ()
-    ENDIF()
-    CREATE_TEST_SOURCELIST(
+    endif()
+    create_test_sourcelist(
       KWSYS_CXX_TEST_SRCS ${KWSYS_NAMESPACE}TestsCxx.cxx
       ${KWSYS_CXX_TESTS}
       )
-    ADD_EXECUTABLE(${KWSYS_NAMESPACE}TestsCxx ${KWSYS_CXX_TEST_SRCS})
-    SET_PROPERTY(TARGET ${KWSYS_NAMESPACE}TestsCxx PROPERTY C_CLANG_TIDY "")
-    SET_PROPERTY(TARGET ${KWSYS_NAMESPACE}TestsCxx PROPERTY CXX_CLANG_TIDY "")
-    SET_PROPERTY(TARGET ${KWSYS_NAMESPACE}TestsCxx PROPERTY C_INCLUDE_WHAT_YOU_USE "")
-    SET_PROPERTY(TARGET ${KWSYS_NAMESPACE}TestsCxx PROPERTY CXX_INCLUDE_WHAT_YOU_USE "")
-    SET_PROPERTY(TARGET ${KWSYS_NAMESPACE}TestsCxx PROPERTY LABELS ${KWSYS_LABELS_EXE})
-    TARGET_LINK_LIBRARIES(${KWSYS_NAMESPACE}TestsCxx ${KWSYS_TARGET_LINK})
+    add_executable(${KWSYS_NAMESPACE}TestsCxx ${KWSYS_CXX_TEST_SRCS})
+    set_property(TARGET ${KWSYS_NAMESPACE}TestsCxx PROPERTY C_CLANG_TIDY "")
+    set_property(TARGET ${KWSYS_NAMESPACE}TestsCxx PROPERTY CXX_CLANG_TIDY "")
+    set_property(TARGET ${KWSYS_NAMESPACE}TestsCxx PROPERTY C_INCLUDE_WHAT_YOU_USE "")
+    set_property(TARGET ${KWSYS_NAMESPACE}TestsCxx PROPERTY CXX_INCLUDE_WHAT_YOU_USE "")
+    set_property(TARGET ${KWSYS_NAMESPACE}TestsCxx PROPERTY LABELS ${KWSYS_LABELS_EXE})
+    target_link_libraries(${KWSYS_NAMESPACE}TestsCxx ${KWSYS_TARGET_LINK})
 
-    SET(TEST_SYSTEMTOOLS_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}")
-    SET(TEST_SYSTEMTOOLS_BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}")
-    CONFIGURE_FILE(
+    set(TEST_SYSTEMTOOLS_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}")
+    set(TEST_SYSTEMTOOLS_BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}")
+    configure_file(
       ${PROJECT_SOURCE_DIR}/testSystemTools.h.in
       ${PROJECT_BINARY_DIR}/testSystemTools.h)
-    INCLUDE_DIRECTORIES(${PROJECT_BINARY_DIR})
+    include_directories(${PROJECT_BINARY_DIR})
 
-    IF(CTEST_TEST_KWSYS)
-      CONFIGURE_FILE("${CMAKE_CURRENT_SOURCE_DIR}/ExtraTest.cmake.in"
+    if(CTEST_TEST_KWSYS)
+      configure_file("${CMAKE_CURRENT_SOURCE_DIR}/ExtraTest.cmake.in"
         "${CMAKE_CURRENT_BINARY_DIR}/ExtraTest.cmake")
-      SET_DIRECTORY_PROPERTIES(PROPERTIES TEST_INCLUDE_FILE "${CMAKE_CURRENT_BINARY_DIR}/ExtraTest.cmake")
-    ENDIF()
+      set_directory_properties(PROPERTIES TEST_INCLUDE_FILE "${CMAKE_CURRENT_BINARY_DIR}/ExtraTest.cmake")
+    endif()
 
-    SET(KWSYS_TEST_ARGS_testCommandLineArguments
+    set(KWSYS_TEST_ARGS_testCommandLineArguments
       --another-bool-variable
       --long3=opt
       --set-bool-arg1
@@ -1179,7 +1064,7 @@
       -C=test
       --long2 hello
       )
-    SET(KWSYS_TEST_ARGS_testCommandLineArguments1
+    set(KWSYS_TEST_ARGS_testCommandLineArguments1
       --ignored
       -n 24
       --second-ignored
@@ -1188,73 +1073,71 @@
       -p
       some junk at the end
       )
-    FOREACH(testfile ${KWSYS_CXX_TESTS})
+    foreach(testfile ${KWSYS_CXX_TESTS})
       get_filename_component(test "${testfile}" NAME_WE)
-      ADD_TEST(kwsys.${test} ${EXEC_DIR}/${KWSYS_NAMESPACE}TestsCxx ${test} ${KWSYS_TEST_ARGS_${test}})
-      SET_PROPERTY(TEST kwsys.${test} PROPERTY LABELS ${KWSYS_LABELS_TEST})
-    ENDFOREACH()
+      add_test(kwsys.${test} ${EXEC_DIR}/${KWSYS_NAMESPACE}TestsCxx ${test} ${KWSYS_TEST_ARGS_${test}})
+      set_property(TEST kwsys.${test} PROPERTY LABELS ${KWSYS_LABELS_TEST})
+    endforeach()
 
     # Process tests.
-    ADD_EXECUTABLE(${KWSYS_NAMESPACE}TestProcess testProcess.c)
-    SET_PROPERTY(TARGET ${KWSYS_NAMESPACE}TestProcess PROPERTY LABELS ${KWSYS_LABELS_EXE})
-    TARGET_LINK_LIBRARIES(${KWSYS_NAMESPACE}TestProcess ${KWSYS_TARGET_C_LINK})
-    IF(NOT CYGWIN)
-      SET(KWSYS_TEST_PROCESS_7 7)
-    ENDIF()
-    FOREACH(n 1 2 3 4 5 6 ${KWSYS_TEST_PROCESS_7} 9 10)
-      ADD_TEST(kwsys.testProcess-${n} ${EXEC_DIR}/${KWSYS_NAMESPACE}TestProcess ${n})
-      SET_PROPERTY(TEST kwsys.testProcess-${n} PROPERTY LABELS ${KWSYS_LABELS_TEST})
-      SET_TESTS_PROPERTIES(kwsys.testProcess-${n} PROPERTIES TIMEOUT 120)
-    ENDFOREACH()
+    add_executable(${KWSYS_NAMESPACE}TestProcess testProcess.c)
+    set_property(TARGET ${KWSYS_NAMESPACE}TestProcess PROPERTY LABELS ${KWSYS_LABELS_EXE})
+    target_link_libraries(${KWSYS_NAMESPACE}TestProcess ${KWSYS_TARGET_C_LINK})
+    #set(KWSYS_TEST_PROCESS_7 7) # uncomment to run timing-sensitive test locally
+    foreach(n 1 2 3 4 5 6 ${KWSYS_TEST_PROCESS_7} 9 10)
+      add_test(kwsys.testProcess-${n} ${EXEC_DIR}/${KWSYS_NAMESPACE}TestProcess ${n})
+      set_property(TEST kwsys.testProcess-${n} PROPERTY LABELS ${KWSYS_LABELS_TEST})
+      set_tests_properties(kwsys.testProcess-${n} PROPERTIES TIMEOUT 120)
+    endforeach()
 
-    SET(testProcess_COMPILE_FLAGS "")
+    set(testProcess_COMPILE_FLAGS "")
     # Some Apple compilers produce bad optimizations in this source.
-    IF(APPLE AND CMAKE_C_COMPILER_ID MATCHES "^(GNU|LLVM)$")
-      SET(testProcess_COMPILE_FLAGS "${testProcess_COMPILE_FLAGS} -O0")
-    ELSEIF(CMAKE_C_COMPILER_ID STREQUAL "XL")
+    if(APPLE AND CMAKE_C_COMPILER_ID MATCHES "^(GNU|LLVM)$")
+      set(testProcess_COMPILE_FLAGS "${testProcess_COMPILE_FLAGS} -O0")
+    elseif(CMAKE_C_COMPILER_ID STREQUAL "XL")
       # Tell IBM XL not to warn about our test infinite loop
-      IF(CMAKE_SYSTEM MATCHES "Linux.*ppc64le"
+      if(CMAKE_SYSTEM MATCHES "Linux.*ppc64le"
          AND CMAKE_C_COMPILER_VERSION VERSION_LESS "16.1.0"
          AND NOT CMAKE_C_COMPILER_VERSION VERSION_LESS "13.1.1")
         # v13.1.[1-6] on Linux ppc64le is clang based and does not accept
         # the -qsuppress option, so just suppress all warnings.
-        SET(testProcess_COMPILE_FLAGS "${testProcess_COMPILE_FLAGS} -w")
-      ELSE()
-        SET(testProcess_COMPILE_FLAGS "${testProcess_COMPILE_FLAGS} -qsuppress=1500-010")
-      ENDIF()
-    ENDIF()
-    IF(CMAKE_C_FLAGS MATCHES "-fsanitize=")
-      SET(testProcess_COMPILE_FLAGS "${testProcess_COMPILE_FLAGS} -DCRASH_USING_ABORT")
-    ENDIF()
-    SET_PROPERTY(SOURCE testProcess.c PROPERTY COMPILE_FLAGS "${testProcess_COMPILE_FLAGS}")
+        set(testProcess_COMPILE_FLAGS "${testProcess_COMPILE_FLAGS} -w")
+      else()
+        set(testProcess_COMPILE_FLAGS "${testProcess_COMPILE_FLAGS} -qsuppress=1500-010")
+      endif()
+    endif()
+    if(CMAKE_C_FLAGS MATCHES "-fsanitize=")
+      set(testProcess_COMPILE_FLAGS "${testProcess_COMPILE_FLAGS} -DCRASH_USING_ABORT")
+    endif()
+    set_property(SOURCE testProcess.c PROPERTY COMPILE_FLAGS "${testProcess_COMPILE_FLAGS}")
 
     # Test SharedForward
-    CONFIGURE_FILE(${PROJECT_SOURCE_DIR}/testSharedForward.c.in
+    configure_file(${PROJECT_SOURCE_DIR}/testSharedForward.c.in
                    ${PROJECT_BINARY_DIR}/testSharedForward.c @ONLY IMMEDIATE)
-    ADD_EXECUTABLE(${KWSYS_NAMESPACE}TestSharedForward
+    add_executable(${KWSYS_NAMESPACE}TestSharedForward
                    ${PROJECT_BINARY_DIR}/testSharedForward.c)
-    SET_PROPERTY(TARGET ${KWSYS_NAMESPACE}TestSharedForward PROPERTY LABELS ${KWSYS_LABELS_EXE})
-    ADD_DEPENDENCIES(${KWSYS_NAMESPACE}TestSharedForward ${KWSYS_TARGET_C_LINK})
-    ADD_TEST(kwsys.testSharedForward ${EXEC_DIR}/${KWSYS_NAMESPACE}TestSharedForward 1)
-    SET_PROPERTY(TEST kwsys.testSharedForward PROPERTY LABELS ${KWSYS_LABELS_TEST})
+    set_property(TARGET ${KWSYS_NAMESPACE}TestSharedForward PROPERTY LABELS ${KWSYS_LABELS_EXE})
+    add_dependencies(${KWSYS_NAMESPACE}TestSharedForward ${KWSYS_TARGET_C_LINK})
+    add_test(kwsys.testSharedForward ${EXEC_DIR}/${KWSYS_NAMESPACE}TestSharedForward 1)
+    set_property(TEST kwsys.testSharedForward PROPERTY LABELS ${KWSYS_LABELS_TEST})
 
     # Configure some test properties.
-    IF(KWSYS_STANDALONE)
+    if(KWSYS_STANDALONE)
       # We expect test to fail
-      SET_TESTS_PROPERTIES(kwsys.testFail PROPERTIES WILL_FAIL ON)
-      GET_TEST_PROPERTY(kwsys.testFail WILL_FAIL wfv)
-      SET_TESTS_PROPERTIES(kwsys.testFail PROPERTIES MEASUREMENT "Some Key=Some Value")
-      MESSAGE(STATUS "GET_TEST_PROPERTY returned: ${wfv}")
-    ENDIF()
+      set_tests_properties(kwsys.testFail PROPERTIES WILL_FAIL ON)
+      get_test_property(kwsys.testFail WILL_FAIL wfv)
+      set_tests_properties(kwsys.testFail PROPERTIES MEASUREMENT "Some Key=Some Value")
+      message(STATUS "GET_TEST_PROPERTY returned: ${wfv}")
+    endif()
 
     # Set up ctest custom configuration file.
-    CONFIGURE_FILE(${PROJECT_SOURCE_DIR}/CTestCustom.cmake.in
+    configure_file(${PROJECT_SOURCE_DIR}/CTestCustom.cmake.in
                    ${PROJECT_BINARY_DIR}/CTestCustom.cmake @ONLY)
 
     # Suppress known consistent failures on buggy systems.
-    IF(KWSYS_TEST_BOGUS_FAILURES)
-      SET_TESTS_PROPERTIES(${KWSYS_TEST_BOGUS_FAILURES} PROPERTIES WILL_FAIL ON)
-    ENDIF()
+    if(KWSYS_TEST_BOGUS_FAILURES)
+      set_tests_properties(${KWSYS_TEST_BOGUS_FAILURES} PROPERTIES WILL_FAIL ON)
+    endif()
 
-  ENDIF()
-ENDIF()
+  endif()
+endif()
diff --git a/Source/kwsys/CTestConfig.cmake b/Source/kwsys/CTestConfig.cmake
index 33ea84c..12347b6 100644
--- a/Source/kwsys/CTestConfig.cmake
+++ b/Source/kwsys/CTestConfig.cmake
@@ -3,7 +3,9 @@
 
 set(CTEST_PROJECT_NAME "KWSys")
 set(CTEST_NIGHTLY_START_TIME "21:00:00 EDT")
-set(CTEST_DROP_METHOD "http")
+if (NOT CTEST_DROP_METHOD STREQUAL "https")
+  set(CTEST_DROP_METHOD "http")
+endif ()
 set(CTEST_DROP_SITE "open.cdash.org")
 set(CTEST_DROP_LOCATION "/submit.php?project=PublicDashboard")
 set(CTEST_DROP_SITE_CDASH TRUE)
diff --git a/Source/kwsys/CommandLineArguments.cxx b/Source/kwsys/CommandLineArguments.cxx
index 3fd1955..e45db36 100644
--- a/Source/kwsys/CommandLineArguments.cxx
+++ b/Source/kwsys/CommandLineArguments.cxx
@@ -20,9 +20,9 @@
 #include <sstream>
 #include <vector>
 
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
+#include <cstdio>
+#include <cstdlib>
+#include <cstring>
 
 #ifdef _MSC_VER
 #  pragma warning(disable : 4786)
@@ -66,26 +66,21 @@
 class CommandLineArgumentsInternal
 {
 public:
-  CommandLineArgumentsInternal()
-    : UnknownArgumentCallback{ nullptr }
-    , ClientData{ nullptr }
-    , LastArgument{ 0 }
-  {
-  }
+  CommandLineArgumentsInternal() = default;
 
-  typedef CommandLineArgumentsVectorOfStrings VectorOfStrings;
-  typedef CommandLineArgumentsMapOfStrucs CallbacksMap;
-  typedef kwsys::String String;
-  typedef CommandLineArgumentsSetOfStrings SetOfStrings;
+  using VectorOfStrings = CommandLineArgumentsVectorOfStrings;
+  using CallbacksMap = CommandLineArgumentsMapOfStrucs;
+  using String = kwsys::String;
+  using SetOfStrings = CommandLineArgumentsSetOfStrings;
 
   VectorOfStrings Argv;
   String Argv0;
   CallbacksMap Callbacks;
 
-  CommandLineArguments::ErrorCallbackType UnknownArgumentCallback;
-  void* ClientData;
+  CommandLineArguments::ErrorCallbackType UnknownArgumentCallback{ nullptr };
+  void* ClientData{ nullptr };
 
-  VectorOfStrings::size_type LastArgument;
+  VectorOfStrings::size_type LastArgument{ 0 };
 
   VectorOfStrings UnusedArguments;
 };
@@ -424,8 +419,7 @@
 
 const char* CommandLineArguments::GetHelp(const char* arg)
 {
-  CommandLineArguments::Internal::CallbacksMap::iterator it =
-    this->Internals->Callbacks.find(arg);
+  auto it = this->Internals->Callbacks.find(arg);
   if (it == this->Internals->Callbacks.end()) {
     return nullptr;
   }
@@ -434,8 +428,7 @@
   // one point to if this one is pointing to another argument.
   CommandLineArgumentsCallbackStructure* cs = &(it->second);
   for (;;) {
-    CommandLineArguments::Internal::CallbacksMap::iterator hit =
-      this->Internals->Callbacks.find(cs->Help);
+    auto hit = this->Internals->Callbacks.find(cs->Help);
     if (hit == this->Internals->Callbacks.end()) {
       break;
     }
@@ -470,9 +463,8 @@
   // Collapse all arguments into the map of vectors of all arguments that do
   // the same thing.
   CommandLineArguments::Internal::CallbacksMap::iterator it;
-  typedef std::map<CommandLineArguments::Internal::String,
-                   CommandLineArguments::Internal::SetOfStrings>
-    MapArgs;
+  using MapArgs = std::map<CommandLineArguments::Internal::String,
+                           CommandLineArguments::Internal::SetOfStrings>;
   MapArgs mp;
   MapArgs::iterator mpit, smpit;
   for (it = this->Internals->Callbacks.begin();
@@ -709,7 +701,7 @@
   if (cs->Callback) {
     if (!cs->Callback(cs->Argument, value, cs->CallData)) {
       this->Internals->LastArgument--;
-      return 0;
+      return false;
     }
   }
   CommandLineArguments_DEBUG("Set argument: " << cs->Argument << " to "
@@ -759,10 +751,10 @@
         std::cerr << "Got unknown variable type: \"" << cs->VariableType
                   << "\"" << std::endl;
         this->Internals->LastArgument--;
-        return 0;
+        return false;
     }
   }
-  return 1;
+  return true;
 }
 
 } // namespace KWSYS_NAMESPACE
diff --git a/Source/kwsys/Configure.h.in b/Source/kwsys/Configure.h.in
index 5323c57..8a237ce 100644
--- a/Source/kwsys/Configure.h.in
+++ b/Source/kwsys/Configure.h.in
@@ -13,9 +13,6 @@
 
 /* Disable some warnings inside kwsys source files.  */
 #if defined(KWSYS_NAMESPACE)
-#  if defined(__BORLANDC__)
-#    pragma warn - 8027 /* function not inlined.  */
-#  endif
 #  if defined(__INTEL_COMPILER)
 #    pragma warning(disable : 1572) /* floating-point equality test */
 #  endif
@@ -68,11 +65,6 @@
 #    pragma warning(disable : 4710) /* function not inlined */
 #    pragma warning(disable : 4786) /* identifier truncated in debug info */
 #  endif
-#  if defined(__BORLANDC__) && !defined(__cplusplus)
-/* Code has no effect; raised by winnt.h in C (not C++) when ignoring an
-   unused parameter using "(param)" syntax (i.e. no cast to void).  */
-#    pragma warn - 8019
-#  endif
 #endif
 
 /* MSVC 6.0 in release mode will warn about code it produces with its
diff --git a/Source/kwsys/Directory.cxx b/Source/kwsys/Directory.cxx
index e379182..0c2190a 100644
--- a/Source/kwsys/Directory.cxx
+++ b/Source/kwsys/Directory.cxx
@@ -35,6 +35,18 @@
   this->Internal = new DirectoryInternals;
 }
 
+Directory::Directory(Directory&& other)
+{
+  this->Internal = other.Internal;
+  other.Internal = nullptr;
+}
+
+Directory& Directory::operator=(Directory&& other)
+{
+  std::swap(this->Internal, other.Internal);
+  return *this;
+}
+
 Directory::~Directory()
 {
   delete this->Internal;
@@ -80,26 +92,12 @@
 #  include <sys/stat.h>
 #  include <sys/types.h>
 
-// Wide function names can vary depending on compiler:
-#  ifdef __BORLANDC__
-#    define _wfindfirst_func __wfindfirst
-#    define _wfindnext_func __wfindnext
-#  else
-#    define _wfindfirst_func _wfindfirst
-#    define _wfindnext_func _wfindnext
-#  endif
-
 namespace KWSYS_NAMESPACE {
 
-bool Directory::Load(const std::string& name)
+bool Directory::Load(const std::string& name, std::string* errorMessage)
 {
   this->Clear();
-#  if (defined(_MSC_VER) && _MSC_VER < 1300) || defined(__BORLANDC__)
-  // Older Visual C++ and Embarcadero compilers.
-  long srchHandle;
-#  else // Newer Visual C++
   intptr_t srchHandle;
-#  endif
   char* buf;
   size_t n = name.size();
   if (name.back() == '/' || name.back() == '\\') {
@@ -118,8 +116,8 @@
   struct _wfinddata_t data; // data of current file
 
   // Now put them into the file array
-  srchHandle = _wfindfirst_func(
-    (wchar_t*)Encoding::ToWindowsExtendedPath(buf).c_str(), &data);
+  srchHandle =
+    _wfindfirst((wchar_t*)Encoding::ToWindowsExtendedPath(buf).c_str(), &data);
   delete[] buf;
 
   if (srchHandle == -1) {
@@ -129,19 +127,15 @@
   // Loop through names
   do {
     this->Internal->Files.push_back(Encoding::ToNarrow(data.name));
-  } while (_wfindnext_func(srchHandle, &data) != -1);
+  } while (_wfindnext(srchHandle, &data) != -1);
   this->Internal->Path = name;
   return _findclose(srchHandle) != -1;
 }
 
-unsigned long Directory::GetNumberOfFilesInDirectory(const std::string& name)
+unsigned long Directory::GetNumberOfFilesInDirectory(const std::string& name,
+                                                     std::string* errorMessage)
 {
-#  if (defined(_MSC_VER) && _MSC_VER < 1300) || defined(__BORLANDC__)
-  // Older Visual C++ and Embarcadero compilers.
-  long srchHandle;
-#  else // Newer Visual C++
   intptr_t srchHandle;
-#  endif
   char* buf;
   size_t n = name.size();
   if (name.back() == '/') {
@@ -154,8 +148,7 @@
   struct _wfinddata_t data; // data of current file
 
   // Now put them into the file array
-  srchHandle =
-    _wfindfirst_func((wchar_t*)Encoding::ToWide(buf).c_str(), &data);
+  srchHandle = _wfindfirst((wchar_t*)Encoding::ToWide(buf).c_str(), &data);
   delete[] buf;
 
   if (srchHandle == -1) {
@@ -166,7 +159,7 @@
   unsigned long count = 0;
   do {
     count++;
-  } while (_wfindnext_func(srchHandle, &data) != -1);
+  } while (_wfindnext(srchHandle, &data) != -1);
   _findclose(srchHandle);
   return count;
 }
@@ -180,6 +173,8 @@
 #  include <sys/types.h>
 
 #  include <dirent.h>
+#  include <errno.h>
+#  include <string.h>
 
 // PGI with glibc has trouble with dirent and large file support:
 //  http://www.pgroup.com/userforum/viewtopic.php?
@@ -197,29 +192,46 @@
 
 namespace KWSYS_NAMESPACE {
 
-bool Directory::Load(const std::string& name)
+bool Directory::Load(const std::string& name, std::string* errorMessage)
 {
   this->Clear();
 
+  errno = 0;
   DIR* dir = opendir(name.c_str());
 
   if (!dir) {
-    return 0;
+    if (errorMessage != nullptr) {
+      *errorMessage = std::string(strerror(errno));
+    }
+    return false;
   }
 
+  errno = 0;
   for (kwsys_dirent* d = readdir(dir); d; d = readdir(dir)) {
-    this->Internal->Files.push_back(d->d_name);
+    this->Internal->Files.emplace_back(d->d_name);
   }
+  if (errno != 0) {
+    if (errorMessage != nullptr) {
+      *errorMessage = std::string(strerror(errno));
+    }
+    return false;
+  }
+
   this->Internal->Path = name;
   closedir(dir);
-  return 1;
+  return true;
 }
 
-unsigned long Directory::GetNumberOfFilesInDirectory(const std::string& name)
+unsigned long Directory::GetNumberOfFilesInDirectory(const std::string& name,
+                                                     std::string* errorMessage)
 {
+  errno = 0;
   DIR* dir = opendir(name.c_str());
 
   if (!dir) {
+    if (errorMessage != nullptr) {
+      *errorMessage = std::string(strerror(errno));
+    }
     return 0;
   }
 
@@ -227,6 +239,13 @@
   for (kwsys_dirent* d = readdir(dir); d; d = readdir(dir)) {
     count++;
   }
+  if (errno != 0) {
+    if (errorMessage != nullptr) {
+      *errorMessage = std::string(strerror(errno));
+    }
+    return false;
+  }
+
   closedir(dir);
   return count;
 }
diff --git a/Source/kwsys/Directory.hxx.in b/Source/kwsys/Directory.hxx.in
index ad8c51b..7bc9db0 100644
--- a/Source/kwsys/Directory.hxx.in
+++ b/Source/kwsys/Directory.hxx.in
@@ -23,6 +23,11 @@
 {
 public:
   Directory();
+  Directory(Directory&& other);
+  Directory(const Directory&) = delete;
+  Directory& operator=(const Directory&) = delete;
+  Directory& operator=(Directory&& other);
+  bool operator==(const Directory&) = delete;
   ~Directory();
 
   /**
@@ -30,7 +35,7 @@
    * in that directory. 0 is returned if the directory can not be
    * opened, 1 if it is opened.
    */
-  bool Load(const std::string&);
+  bool Load(const std::string&, std::string* errorMessage = nullptr);
 
   /**
    * Return the number of files in the current directory.
@@ -41,7 +46,8 @@
    * Return the number of files in the specified directory.
    * A higher performance static method.
    */
-  static unsigned long GetNumberOfFilesInDirectory(const std::string&);
+  static unsigned long GetNumberOfFilesInDirectory(
+    const std::string&, std::string* errorMessage = nullptr);
 
   /**
    * Return the file at the given index, the indexing is 0 based
@@ -62,10 +68,7 @@
 private:
   // Private implementation details.
   DirectoryInternals* Internal;
-
-  Directory(const Directory&);      // Not implemented.
-  void operator=(const Directory&); // Not implemented.
-};                                  // End Class: Directory
+}; // End Class: Directory
 
 } // namespace @KWSYS_NAMESPACE@
 
diff --git a/Source/kwsys/DynamicLoader.cxx b/Source/kwsys/DynamicLoader.cxx
index a4b8641..66ee9ea 100644
--- a/Source/kwsys/DynamicLoader.cxx
+++ b/Source/kwsys/DynamicLoader.cxx
@@ -246,17 +246,6 @@
   // should have a tool to help get the symbol with the desired
   // calling convention.  Currently we assume cdecl.
   //
-  // Borland:
-  //   __cdecl    = "_func" (default)
-  //   __fastcall = "@_func"
-  //   __stdcall  = "func"
-  //
-  // Watcom:
-  //   __cdecl    = "_func"
-  //   __fastcall = "@_func@X"
-  //   __stdcall  = "_func@X"
-  //   __watcall  = "func_" (default)
-  //
   // MSVC:
   //   __cdecl    = "func" (default)
   //   __fastcall = "@_func@X"
@@ -265,20 +254,9 @@
   // Note that the "@X" part of the name above is the total size (in
   // bytes) of the arguments on the stack.
   void* result;
-#  if defined(__BORLANDC__) || defined(__WATCOMC__)
-  // Need to prepend symbols with '_'
-  std::string ssym = '_' + sym;
-  const char* rsym = ssym.c_str();
-#  else
   const char* rsym = sym.c_str();
-#  endif
   result = (void*)GetProcAddress(lib, rsym);
-// Hack to cast pointer-to-data to pointer-to-function.
-#  ifdef __WATCOMC__
-  return *(DynamicLoader::SymbolPointer*)(&result);
-#  else
   return *reinterpret_cast<DynamicLoader::SymbolPointer*>(&result);
-#  endif
 }
 
 #  define DYNLOAD_ERROR_BUFFER_SIZE 1024
diff --git a/Source/kwsys/EncodingCXX.cxx b/Source/kwsys/EncodingCXX.cxx
index 5cad934..c68c73c 100644
--- a/Source/kwsys/EncodingCXX.cxx
+++ b/Source/kwsys/EncodingCXX.cxx
@@ -17,8 +17,8 @@
 #  include "Encoding.hxx.in"
 #endif
 
-#include <stdlib.h>
-#include <string.h>
+#include <cstdlib>
+#include <cstring>
 #include <vector>
 
 #ifdef _MSC_VER
diff --git a/Source/kwsys/ExtraTest.cmake.in b/Source/kwsys/ExtraTest.cmake.in
index e8c0a1c..4cec9e2 100644
--- a/Source/kwsys/ExtraTest.cmake.in
+++ b/Source/kwsys/ExtraTest.cmake.in
@@ -1 +1 @@
-MESSAGE("*** This message is generated by message inside a file that is included in DartTestfile.txt ***")
+message("*** This message is generated by message inside a file that is included in DartTestfile.txt ***")
diff --git a/Source/kwsys/Glob.cxx b/Source/kwsys/Glob.cxx
index 34bb0d0..c6d4b19 100644
--- a/Source/kwsys/Glob.cxx
+++ b/Source/kwsys/Glob.cxx
@@ -23,11 +23,11 @@
 #include <string>
 #include <vector>
 
-#include <ctype.h>
-#include <stdio.h>
-#include <string.h>
+#include <cctype>
+#include <cstdio>
+#include <cstring>
 namespace KWSYS_NAMESPACE {
-#if defined(_WIN32) || defined(__APPLE__) || defined(__CYGWIN__)
+#if defined(_WIN32) || defined(__APPLE__)
 // On Windows and Apple, no difference between lower and upper case
 #  define KWSYS_GLOB_CASE_INDEPENDENT
 #endif
@@ -182,7 +182,15 @@
                             const std::string& dir, GlobMessages* messages)
 {
   kwsys::Directory d;
-  if (!d.Load(dir)) {
+  std::string errorMessage;
+  if (!d.Load(dir, &errorMessage)) {
+    if (messages) {
+      if (!errorMessage.empty()) {
+        messages->push_back(Message(Glob::warning,
+                                    "Error listing directory '" + dir +
+                                      "'! Reason: '" + errorMessage + "'"));
+      }
+    }
     return true;
   }
   unsigned long cc;
@@ -278,7 +286,9 @@
   // std::cout << "ProcessDirectory: " << dir << std::endl;
   bool last = (start == this->Internals->Expressions.size() - 1);
   if (last && this->Recurse) {
-    this->RecurseDirectory(start, dir, messages);
+    if (kwsys::SystemTools::FileIsDirectory(dir)) {
+      this->RecurseDirectory(start, dir, messages);
+    }
     return;
   }
 
@@ -385,10 +395,9 @@
   }
 
   if (skip > 0) {
-    expr = expr.substr(skip);
+    expr.erase(0, skip);
   }
 
-  cexpr = "";
   for (cc = 0; cc < expr.size(); cc++) {
     int ch = expr[cc];
     if (ch == '/') {
@@ -415,8 +424,7 @@
 
 void Glob::AddExpression(const std::string& expr)
 {
-  this->Internals->Expressions.push_back(
-    kwsys::RegularExpression(this->PatternToRegex(expr)));
+  this->Internals->Expressions.emplace_back(this->PatternToRegex(expr));
 }
 
 void Glob::SetRelative(const char* dir)
diff --git a/Source/kwsys/Glob.hxx.in b/Source/kwsys/Glob.hxx.in
index 170766f..e8474e2 100644
--- a/Source/kwsys/Glob.hxx.in
+++ b/Source/kwsys/Glob.hxx.in
@@ -28,6 +28,7 @@
   enum MessageType
   {
     error,
+    warning,
     cyclicRecursion
   };
 
@@ -125,8 +126,8 @@
   bool RecurseListDirs;
 
 private:
-  Glob(const Glob&);           // Not implemented.
-  void operator=(const Glob&); // Not implemented.
+  Glob(const Glob&) = delete;
+  void operator=(const Glob&) = delete;
 };
 
 } // namespace @KWSYS_NAMESPACE@
diff --git a/Source/kwsys/IOStream.cxx b/Source/kwsys/IOStream.cxx
deleted file mode 100644
index e21f87d..0000000
--- a/Source/kwsys/IOStream.cxx
+++ /dev/null
@@ -1,255 +0,0 @@
-/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
-   file Copyright.txt or https://cmake.org/licensing#kwsys for details.  */
-#include "kwsysPrivate.h"
-#include KWSYS_HEADER(Configure.hxx)
-
-// Include the streams library.
-#include <iostream>
-#include KWSYS_HEADER(IOStream.hxx)
-
-// Work-around CMake dependency scanning limitation.  This must
-// duplicate the above list of headers.
-#if 0
-#  include "Configure.hxx.in"
-#  include "IOStream.hxx.in"
-#endif
-
-// Implement the rest of this file only if it is needed.
-#if KWSYS_IOS_NEED_OPERATORS_LL
-
-#  include <stdio.h>  // sscanf, sprintf
-#  include <string.h> // memchr
-
-#  if defined(_MAX_INT_DIG)
-#    define KWSYS_IOS_INT64_MAX_DIG _MAX_INT_DIG
-#  else
-#    define KWSYS_IOS_INT64_MAX_DIG 32
-#  endif
-
-namespace KWSYS_NAMESPACE {
-
-// Scan an input stream for an integer value.
-static int IOStreamScanStream(std::istream& is, char* buffer)
-{
-  // Prepare to write to buffer.
-  char* out = buffer;
-  char* end = buffer + KWSYS_IOS_INT64_MAX_DIG - 1;
-
-  // Look for leading sign.
-  if (is.peek() == '+') {
-    *out++ = '+';
-    is.ignore();
-  } else if (is.peek() == '-') {
-    *out++ = '-';
-    is.ignore();
-  }
-
-  // Determine the base.  If not specified in the stream, try to
-  // detect it from the input.  A leading 0x means hex, and a leading
-  // 0 alone means octal.
-  int base = 0;
-  int flags = is.flags() & std::ios_base::basefield;
-  if (flags == std::ios_base::oct) {
-    base = 8;
-  } else if (flags == std::ios_base::dec) {
-    base = 10;
-  } else if (flags == std::ios_base::hex) {
-    base = 16;
-  }
-  bool foundDigit = false;
-  bool foundNonZero = false;
-  if (is.peek() == '0') {
-    foundDigit = true;
-    is.ignore();
-    if ((is.peek() == 'x' || is.peek() == 'X') && (base == 0 || base == 16)) {
-      base = 16;
-      foundDigit = false;
-      is.ignore();
-    } else if (base == 0) {
-      base = 8;
-    }
-  }
-
-  // Determine the range of digits allowed for this number.
-  const char* digits = "0123456789abcdefABCDEF";
-  int maxDigitIndex = 10;
-  if (base == 8) {
-    maxDigitIndex = 8;
-  } else if (base == 16) {
-    maxDigitIndex = 10 + 6 + 6;
-  }
-
-  // Scan until an invalid digit is found.
-  for (; is.peek() != EOF; is.ignore()) {
-    if (memchr(digits, *out = (char)is.peek(), maxDigitIndex) != 0) {
-      if ((foundNonZero || *out != '0') && out < end) {
-        ++out;
-        foundNonZero = true;
-      }
-      foundDigit = true;
-    } else {
-      break;
-    }
-  }
-
-  // Correct the buffer contents for degenerate cases.
-  if (foundDigit && !foundNonZero) {
-    *out++ = '0';
-  } else if (!foundDigit) {
-    out = buffer;
-  }
-
-  // Terminate the string in the buffer.
-  *out = '\0';
-
-  return base;
-}
-
-// Read an integer value from an input stream.
-template <class T>
-std::istream& IOStreamScanTemplate(std::istream& is, T& value, char type)
-{
-  int state = std::ios_base::goodbit;
-
-  // Skip leading whitespace.
-  std::istream::sentry okay(is);
-
-  if (okay) {
-    try {
-      // Copy the string to a buffer and construct the format string.
-      char buffer[KWSYS_IOS_INT64_MAX_DIG];
-#  if defined(_MSC_VER)
-      char format[] = "%I64_";
-      const int typeIndex = 4;
-#  else
-      char format[] = "%ll_";
-      const int typeIndex = 3;
-#  endif
-      switch (IOStreamScanStream(is, buffer)) {
-        case 8:
-          format[typeIndex] = 'o';
-          break;
-        case 0: // Default to decimal if not told otherwise.
-        case 10:
-          format[typeIndex] = type;
-          break;
-        case 16:
-          format[typeIndex] = 'x';
-          break;
-      };
-
-      // Use sscanf to parse the number from the buffer.
-      T result;
-      int success = (sscanf(buffer, format, &result) == 1) ? 1 : 0;
-
-      // Set flags for resulting state.
-      if (is.peek() == EOF) {
-        state |= std::ios_base::eofbit;
-      }
-      if (!success) {
-        state |= std::ios_base::failbit;
-      } else {
-        value = result;
-      }
-    } catch (...) {
-      state |= std::ios_base::badbit;
-    }
-  }
-
-  is.setstate(std::ios_base::iostate(state));
-  return is;
-}
-
-// Print an integer value to an output stream.
-template <class T>
-std::ostream& IOStreamPrintTemplate(std::ostream& os, T value, char type)
-{
-  std::ostream::sentry okay(os);
-  if (okay) {
-    try {
-      // Construct the format string.
-      char format[8];
-      char* f = format;
-      *f++ = '%';
-      if (os.flags() & std::ios_base::showpos) {
-        *f++ = '+';
-      }
-      if (os.flags() & std::ios_base::showbase) {
-        *f++ = '#';
-      }
-#  if defined(_MSC_VER)
-      *f++ = 'I';
-      *f++ = '6';
-      *f++ = '4';
-#  else
-      *f++ = 'l';
-      *f++ = 'l';
-#  endif
-      long bflags = os.flags() & std::ios_base::basefield;
-      if (bflags == std::ios_base::oct) {
-        *f++ = 'o';
-      } else if (bflags != std::ios_base::hex) {
-        *f++ = type;
-      } else if (os.flags() & std::ios_base::uppercase) {
-        *f++ = 'X';
-      } else {
-        *f++ = 'x';
-      }
-      *f = '\0';
-
-      // Use sprintf to print to a buffer and then write the
-      // buffer to the stream.
-      char buffer[2 * KWSYS_IOS_INT64_MAX_DIG];
-      sprintf(buffer, format, value);
-      os << buffer;
-    } catch (...) {
-      os.clear(os.rdstate() | std::ios_base::badbit);
-    }
-  }
-  return os;
-}
-
-#  if !KWSYS_IOS_HAS_ISTREAM_LONG_LONG
-// Implement input stream operator for IOStreamSLL.
-std::istream& IOStreamScan(std::istream& is, IOStreamSLL& value)
-{
-  return IOStreamScanTemplate(is, value, 'd');
-}
-
-// Implement input stream operator for IOStreamULL.
-std::istream& IOStreamScan(std::istream& is, IOStreamULL& value)
-{
-  return IOStreamScanTemplate(is, value, 'u');
-}
-#  endif
-
-#  if !KWSYS_IOS_HAS_OSTREAM_LONG_LONG
-// Implement output stream operator for IOStreamSLL.
-std::ostream& IOStreamPrint(std::ostream& os, IOStreamSLL value)
-{
-  return IOStreamPrintTemplate(os, value, 'd');
-}
-
-// Implement output stream operator for IOStreamULL.
-std::ostream& IOStreamPrint(std::ostream& os, IOStreamULL value)
-{
-  return IOStreamPrintTemplate(os, value, 'u');
-}
-#  endif
-
-} // namespace KWSYS_NAMESPACE
-
-#else
-
-namespace KWSYS_NAMESPACE {
-
-// Create one public symbol in this object file to avoid warnings from
-// archivers.
-void IOStreamSymbolToAvoidWarning();
-void IOStreamSymbolToAvoidWarning()
-{
-}
-
-} // namespace KWSYS_NAMESPACE
-
-#endif // KWSYS_IOS_NEED_OPERATORS_LL
diff --git a/Source/kwsys/IOStream.hxx.in b/Source/kwsys/IOStream.hxx.in
deleted file mode 100644
index db8a23e..0000000
--- a/Source/kwsys/IOStream.hxx.in
+++ /dev/null
@@ -1,126 +0,0 @@
-/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
-   file Copyright.txt or https://cmake.org/licensing#kwsys for details.  */
-#ifndef @KWSYS_NAMESPACE@_IOStream_hxx
-#define @KWSYS_NAMESPACE@_IOStream_hxx
-
-#include <iosfwd>
-
-/* Define these macros temporarily to keep the code readable.  */
-#if !defined(KWSYS_NAMESPACE) && !@KWSYS_NAMESPACE@_NAME_IS_KWSYS
-#  define kwsysEXPORT @KWSYS_NAMESPACE@_EXPORT
-#endif
-
-/* Whether istream supports long long.  */
-#define @KWSYS_NAMESPACE@_IOS_HAS_ISTREAM_LONG_LONG                           \
-  @KWSYS_IOS_HAS_ISTREAM_LONG_LONG@
-
-/* Whether ostream supports long long.  */
-#define @KWSYS_NAMESPACE@_IOS_HAS_OSTREAM_LONG_LONG                           \
-  @KWSYS_IOS_HAS_OSTREAM_LONG_LONG@
-
-/* Determine whether we need to define the streaming operators for
-   long long or __int64.  */
-#if @KWSYS_USE_LONG_LONG@
-#  if !@KWSYS_NAMESPACE@_IOS_HAS_ISTREAM_LONG_LONG ||                         \
-    !@KWSYS_NAMESPACE@_IOS_HAS_OSTREAM_LONG_LONG
-#    define @KWSYS_NAMESPACE@_IOS_NEED_OPERATORS_LL 1
-namespace @KWSYS_NAMESPACE@ {
-typedef long long IOStreamSLL;
-typedef unsigned long long IOStreamULL;
-}
-#  endif
-#elif defined(_MSC_VER) && _MSC_VER < 1300
-#  define @KWSYS_NAMESPACE@_IOS_NEED_OPERATORS_LL 1
-namespace @KWSYS_NAMESPACE@ {
-typedef __int64 IOStreamSLL;
-typedef unsigned __int64 IOStreamULL;
-}
-#endif
-#if !defined(@KWSYS_NAMESPACE@_IOS_NEED_OPERATORS_LL)
-#  define @KWSYS_NAMESPACE@_IOS_NEED_OPERATORS_LL 0
-#endif
-
-#if @KWSYS_NAMESPACE@_IOS_NEED_OPERATORS_LL
-#  if !@KWSYS_NAMESPACE@_IOS_HAS_ISTREAM_LONG_LONG
-
-/* Input stream operator implementation functions.  */
-namespace @KWSYS_NAMESPACE@ {
-kwsysEXPORT std::istream& IOStreamScan(std::istream&, IOStreamSLL&);
-kwsysEXPORT std::istream& IOStreamScan(std::istream&, IOStreamULL&);
-}
-
-/* Provide input stream operator for long long.  */
-#    if !defined(@KWSYS_NAMESPACE@_IOS_NO_ISTREAM_LONG_LONG) &&               \
-      !defined(KWSYS_IOS_ISTREAM_LONG_LONG_DEFINED)
-#      define KWSYS_IOS_ISTREAM_LONG_LONG_DEFINED
-#      define @KWSYS_NAMESPACE@_IOS_ISTREAM_LONG_LONG_DEFINED
-inline std::istream& operator>>(std::istream& is,
-                                @KWSYS_NAMESPACE@::IOStreamSLL& value)
-{
-  return @KWSYS_NAMESPACE@::IOStreamScan(is, value);
-}
-#    endif
-
-/* Provide input stream operator for unsigned long long.  */
-#    if !defined(@KWSYS_NAMESPACE@_IOS_NO_ISTREAM_UNSIGNED_LONG_LONG) &&      \
-      !defined(KWSYS_IOS_ISTREAM_UNSIGNED_LONG_LONG_DEFINED)
-#      define KWSYS_IOS_ISTREAM_UNSIGNED_LONG_LONG_DEFINED
-#      define @KWSYS_NAMESPACE@_IOS_ISTREAM_UNSIGNED_LONG_LONG_DEFINED
-inline std::istream& operator>>(std::istream& is,
-                                @KWSYS_NAMESPACE@::IOStreamULL& value)
-{
-  return @KWSYS_NAMESPACE@::IOStreamScan(is, value);
-}
-#    endif
-#  endif /* !@KWSYS_NAMESPACE@_IOS_HAS_ISTREAM_LONG_LONG */
-
-#  if !@KWSYS_NAMESPACE@_IOS_HAS_OSTREAM_LONG_LONG
-
-/* Output stream operator implementation functions.  */
-namespace @KWSYS_NAMESPACE@ {
-kwsysEXPORT std::ostream& IOStreamPrint(std::ostream&, IOStreamSLL);
-kwsysEXPORT std::ostream& IOStreamPrint(std::ostream&, IOStreamULL);
-}
-
-/* Provide output stream operator for long long.  */
-#    if !defined(@KWSYS_NAMESPACE@_IOS_NO_OSTREAM_LONG_LONG) &&               \
-      !defined(KWSYS_IOS_OSTREAM_LONG_LONG_DEFINED)
-#      define KWSYS_IOS_OSTREAM_LONG_LONG_DEFINED
-#      define @KWSYS_NAMESPACE@_IOS_OSTREAM_LONG_LONG_DEFINED
-inline std::ostream& operator<<(std::ostream& os,
-                                @KWSYS_NAMESPACE@::IOStreamSLL value)
-{
-  return @KWSYS_NAMESPACE@::IOStreamPrint(os, value);
-}
-#    endif
-
-/* Provide output stream operator for unsigned long long.  */
-#    if !defined(@KWSYS_NAMESPACE@_IOS_NO_OSTREAM_UNSIGNED_LONG_LONG) &&      \
-      !defined(KWSYS_IOS_OSTREAM_UNSIGNED_LONG_LONG_DEFINED)
-#      define KWSYS_IOS_OSTREAM_UNSIGNED_LONG_LONG_DEFINED
-#      define @KWSYS_NAMESPACE@_IOS_OSTREAM_UNSIGNED_LONG_LONG_DEFINED
-inline std::ostream& operator<<(std::ostream& os,
-                                @KWSYS_NAMESPACE@::IOStreamULL value)
-{
-  return @KWSYS_NAMESPACE@::IOStreamPrint(os, value);
-}
-#    endif
-#  endif /* !@KWSYS_NAMESPACE@_IOS_HAS_OSTREAM_LONG_LONG */
-#endif   /* @KWSYS_NAMESPACE@_IOS_NEED_OPERATORS_LL */
-
-/* Undefine temporary macros.  */
-#if !defined(KWSYS_NAMESPACE) && !@KWSYS_NAMESPACE@_NAME_IS_KWSYS
-#  undef kwsysEXPORT
-#endif
-
-/* If building a C++ file in kwsys itself, give the source file
-   access to the macros without a configured namespace.  */
-#if defined(KWSYS_NAMESPACE)
-#  define KWSYS_IOS_HAS_ISTREAM_LONG_LONG                                     \
-    @KWSYS_NAMESPACE@_IOS_HAS_ISTREAM_LONG_LONG
-#  define KWSYS_IOS_HAS_OSTREAM_LONG_LONG                                     \
-    @KWSYS_NAMESPACE@_IOS_HAS_OSTREAM_LONG_LONG
-#  define KWSYS_IOS_NEED_OPERATORS_LL @KWSYS_NAMESPACE@_IOS_NEED_OPERATORS_LL
-#endif
-
-#endif
diff --git a/Source/kwsys/MD5.c b/Source/kwsys/MD5.c
index 97cf9ba..fb18a5b 100644
--- a/Source/kwsys/MD5.c
+++ b/Source/kwsys/MD5.c
@@ -171,8 +171,10 @@
 
 static void md5_process(md5_state_t* pms, const md5_byte_t* data /*[64]*/)
 {
-  md5_word_t a = pms->abcd[0], b = pms->abcd[1], c = pms->abcd[2],
-             d = pms->abcd[3];
+  md5_word_t a = pms->abcd[0];
+  md5_word_t b = pms->abcd[1];
+  md5_word_t c = pms->abcd[2];
+  md5_word_t d = pms->abcd[3];
   md5_word_t t;
 #if BYTE_ORDER > 0
   /* Define storage only for big-endian CPUs. */
@@ -227,9 +229,10 @@
 #  else
 #    define xbuf X /* (static only) */
 #  endif
-      for (i = 0; i < 16; ++i, xp += 4)
+      for (i = 0; i < 16; ++i, xp += 4) {
         xbuf[i] =
           (md5_word_t)(xp[0] + (xp[1] << 8) + (xp[2] << 16) + (xp[3] << 24));
+      }
     }
 #endif
   }
@@ -367,34 +370,39 @@
   size_t offset = (pms->count[0] >> 3) & 63;
   md5_word_t nbits = (md5_word_t)(nbytes << 3);
 
-  if (nbytes <= 0)
+  if (nbytes <= 0) {
     return;
+  }
 
   /* Update the message length. */
   pms->count[1] += (md5_word_t)(nbytes >> 29);
   pms->count[0] += nbits;
-  if (pms->count[0] < nbits)
+  if (pms->count[0] < nbits) {
     pms->count[1]++;
+  }
 
   /* Process an initial partial block. */
   if (offset) {
     size_t copy = (offset + nbytes > 64 ? 64 - offset : nbytes);
 
     memcpy(pms->buf + offset, p, copy);
-    if (offset + copy < 64)
+    if (offset + copy < 64) {
       return;
+    }
     p += copy;
     left -= copy;
     md5_process(pms, pms->buf);
   }
 
   /* Process full blocks. */
-  for (; left >= 64; p += 64, left -= 64)
+  for (; left >= 64; p += 64, left -= 64) {
     md5_process(pms, p);
+  }
 
   /* Process a final partial block. */
-  if (left)
+  if (left) {
     memcpy(pms->buf, p, left);
+  }
 }
 
 /* Finish the message and return the digest. */
@@ -409,14 +417,16 @@
   int i;
 
   /* Save the length before padding. */
-  for (i = 0; i < 8; ++i)
+  for (i = 0; i < 8; ++i) {
     data[i] = (md5_byte_t)(pms->count[i >> 2] >> ((i & 3) << 3));
+  }
   /* Pad to 56 bytes mod 64. */
   md5_append(pms, pad, ((55 - (pms->count[0] >> 3)) & 63) + 1);
   /* Append the length. */
   md5_append(pms, data, 8);
-  for (i = 0; i < 16; ++i)
+  for (i = 0; i < 16; ++i) {
     digest[i] = (md5_byte_t)(pms->abcd[i >> 2] >> ((i & 3) << 3));
+  }
 }
 
 #if defined(__clang__) && !defined(__INTEL_COMPILER)
diff --git a/Source/kwsys/Process.h.in b/Source/kwsys/Process.h.in
index 73ea9db..9f2162b 100644
--- a/Source/kwsys/Process.h.in
+++ b/Source/kwsys/Process.h.in
@@ -180,8 +180,8 @@
  * write end of the pipe will be closed in the parent process and the
  * read end will be closed in the child process.
  */
-kwsysEXPORT void kwsysProcess_SetPipeNative(kwsysProcess* cp, int pipe,
-                                            kwsysProcess_Pipe_Handle p[2]);
+kwsysEXPORT void kwsysProcess_SetPipeNative(
+  kwsysProcess* cp, int pipe, const kwsysProcess_Pipe_Handle p[2]);
 
 /**
  * Get/Set a possibly platform-specific option.  Possible options are:
diff --git a/Source/kwsys/ProcessUNIX.c b/Source/kwsys/ProcessUNIX.c
index f65690b..e1e7721 100644
--- a/Source/kwsys/ProcessUNIX.c
+++ b/Source/kwsys/ProcessUNIX.c
@@ -152,10 +152,11 @@
 static void kwsysProcessDestroy(kwsysProcess* cp);
 static int kwsysProcessSetupOutputPipeFile(int* p, const char* name);
 static int kwsysProcessSetupOutputPipeNative(int* p, int des[2]);
-static int kwsysProcessGetTimeoutTime(kwsysProcess* cp, double* userTimeout,
+static int kwsysProcessGetTimeoutTime(kwsysProcess* cp,
+                                      const double* userTimeout,
                                       kwsysProcessTime* timeoutTime);
 static int kwsysProcessGetTimeoutLeft(kwsysProcessTime* timeoutTime,
-                                      double* userTimeout,
+                                      const double* userTimeout,
                                       kwsysProcessTimeNative* timeoutLength,
                                       int zeroIsExpired);
 static kwsysProcessTime kwsysProcessTimeGetCurrent(void);
@@ -431,8 +432,8 @@
     char const* const* c = command;
     kwsysProcess_ptrdiff_t n = 0;
     kwsysProcess_ptrdiff_t i = 0;
-    while (*c++)
-      ;
+    while (*c++) {
+    }
     n = c - command - 1;
     newCommands[cp->NumberOfCommands] =
       (char**)malloc((size_t)(n + 1) * sizeof(char*));
@@ -571,7 +572,7 @@
   }
 }
 
-void kwsysProcess_SetPipeNative(kwsysProcess* cp, int prPipe, int p[2])
+void kwsysProcess_SetPipeNative(kwsysProcess* cp, int prPipe, const int p[2])
 {
   int* pPipeNative = 0;
 
@@ -684,7 +685,8 @@
 {
   if (!cp) {
     return "Process management structure could not be allocated";
-  } else if (cp->State == kwsysProcess_State_Error) {
+  }
+  if (cp->State == kwsysProcess_State_Error) {
     return cp->ErrorMessage;
   }
   return "Success";
@@ -694,7 +696,8 @@
 {
   if (!(cp && cp->ProcessResults && (cp->NumberOfCommands > 0))) {
     return "GetExceptionString called with NULL process management structure";
-  } else if (cp->State == kwsysProcess_State_Exception) {
+  }
+  if (cp->State == kwsysProcess_State_Exception) {
     return cp->ProcessResults[cp->NumberOfCommands - 1].ExitExceptionString;
   }
   return "No exception";
@@ -786,8 +789,8 @@
 
     /* Some platforms specify that the chdir call may be
        interrupted.  Repeat the call until it finishes.  */
-    while (((r = chdir(cp->WorkingDirectory)) < 0) && (errno == EINTR))
-      ;
+    while (((r = chdir(cp->WorkingDirectory)) < 0) && (errno == EINTR)) {
+    }
     if (r < 0) {
       kwsysProcessCleanup(cp, 1);
       return;
@@ -1013,8 +1016,8 @@
   if (cp->RealWorkingDirectory) {
     /* Some platforms specify that the chdir call may be
        interrupted.  Repeat the call until it finishes.  */
-    while ((chdir(cp->RealWorkingDirectory) < 0) && (errno == EINTR))
-      ;
+    while ((chdir(cp->RealWorkingDirectory) < 0) && (errno == EINTR)) {
+    }
     free(cp->RealWorkingDirectory);
     cp->RealWorkingDirectory = 0;
   }
@@ -1099,22 +1102,22 @@
   if (wd.PipeId) {
     /* Data are ready on a pipe.  */
     return wd.PipeId;
-  } else if (wd.Expired) {
+  }
+  if (wd.Expired) {
     /* A timeout has expired.  */
     if (wd.User) {
       /* The user timeout has expired.  It has no time left.  */
       return kwsysProcess_Pipe_Timeout;
-    } else {
-      /* The process timeout has expired.  Kill the children now.  */
-      kwsysProcess_Kill(cp);
-      cp->Killed = 0;
-      cp->TimeoutExpired = 1;
-      return kwsysProcess_Pipe_None;
     }
-  } else {
-    /* No pipes are left open.  */
+
+    /* The process timeout has expired.  Kill the children now.  */
+    kwsysProcess_Kill(cp);
+    cp->Killed = 0;
+    cp->TimeoutExpired = 1;
     return kwsysProcess_Pipe_None;
   }
+  /* No pipes are left open.  */
+  return kwsysProcess_Pipe_None;
 }
 
 static int kwsysProcessWaitForPipe(kwsysProcess* cp, char** data, int* length,
@@ -1144,8 +1147,8 @@
          read until the operation is not interrupted.  */
       while (((n = read(cp->PipeReadEnds[i], cp->PipeBuffer,
                         KWSYSPE_PIPE_BUFFER_SIZE)) < 0) &&
-             (errno == EINTR))
-        ;
+             (errno == EINTR)) {
+      }
       if (n > 0) {
         /* We have data on this pipe.  */
         if (i == KWSYSPE_PIPE_SIGNAL) {
@@ -1183,7 +1186,7 @@
 
   /* Make sure the set is empty (it should always be empty here
      anyway).  */
-  FD_ZERO(&cp->PipeSet);
+  FD_ZERO(&cp->PipeSet); // NOLINT(readability-isolate-declaration)
 
   /* Setup a timeout if required.  */
   if (wd->TimeoutTime.tv_sec < 0) {
@@ -1218,15 +1221,16 @@
   /* Run select to block until data are available.  Repeat call
      until it is not interrupted.  */
   while (((numReady = select(max + 1, &cp->PipeSet, 0, 0, timeout)) < 0) &&
-         (errno == EINTR))
-    ;
+         (errno == EINTR)) {
+  }
 
   /* Check result of select.  */
   if (numReady == 0) {
     /* Select's timeout expired.  */
     wd->Expired = 1;
     return 1;
-  } else if (numReady < 0) {
+  }
+  if (numReady < 0) {
     /* Select returned an error.  Leave the error description in the
        pipe buffer.  */
     strncpy(cp->ErrorMessage, strerror(errno), KWSYSPE_PIPE_BUFFER_SIZE);
@@ -1366,11 +1370,13 @@
         cp->ProcessResults[prPipe].State = kwsysProcess_StateByIndex_Exited;
         cp->ProcessResults[prPipe].ExitException = kwsysProcess_Exception_None;
         cp->ProcessResults[prPipe].ExitValue =
+          // NOLINTNEXTLINE(google-readability-casting)
           (int)WEXITSTATUS(cp->ProcessResults[prPipe].ExitCode);
       } else if (WIFSIGNALED(cp->ProcessResults[prPipe].ExitCode)) {
         /* The child received an unhandled signal.  */
         cp->ProcessResults[prPipe].State = kwsysProcess_State_Exception;
         kwsysProcessSetExitExceptionByIndex(
+          // NOLINTNEXTLINE(google-readability-casting)
           cp, (int)WTERMSIG(cp->ProcessResults[prPipe].ExitCode), prPipe);
       } else {
         /* Error getting the child return code.  */
@@ -1449,8 +1455,8 @@
 
       /* Reap the child.  Keep trying until the call is not
          interrupted.  */
-      while ((waitpid(cp->ForkPIDs[i], &status, 0) < 0) && (errno == EINTR))
-        ;
+      while ((waitpid(cp->ForkPIDs[i], &status, 0) < 0) && (errno == EINTR)) {
+      }
     }
   }
 
@@ -1501,7 +1507,7 @@
   cp->PipesLeft = 0;
   cp->CommandsLeft = 0;
 #if KWSYSPE_USE_SELECT
-  FD_ZERO(&cp->PipeSet);
+  FD_ZERO(&cp->PipeSet); // NOLINT(readability-isolate-declaration)
 #endif
   cp->State = kwsysProcess_State_Starting;
   cp->Killed = 0;
@@ -1590,16 +1596,16 @@
           /* Reap the child.  Keep trying until the call is not
              interrupted.  */
           while ((waitpid(cp->ForkPIDs[i], &status, 0) < 0) &&
-                 (errno == EINTR))
-            ;
+                 (errno == EINTR)) {
+          }
         }
       }
     }
 
     /* Restore the working directory.  */
     if (cp->RealWorkingDirectory) {
-      while ((chdir(cp->RealWorkingDirectory) < 0) && (errno == EINTR))
-        ;
+      while ((chdir(cp->RealWorkingDirectory) < 0) && (errno == EINTR)) {
+      }
     }
   }
 
@@ -1635,8 +1641,8 @@
   if (pfd && *pfd > 2) {
     /* Keep trying to close until it is not interrupted by a
      * signal.  */
-    while ((close(*pfd) < 0) && (errno == EINTR))
-      ;
+    while ((close(*pfd) < 0) && (errno == EINTR)) {
+    }
     *pfd = -1;
   }
 }
@@ -1661,8 +1667,8 @@
            read until the operation is not interrupted.  */
         while ((read(cp->PipeReadEnds[i], cp->PipeBuffer,
                      KWSYSPE_PIPE_BUFFER_SIZE) < 0) &&
-               (errno == EINTR))
-          ;
+               (errno == EINTR)) {
+        }
       }
 #endif
 
@@ -1689,7 +1695,8 @@
 static int kwsysProcessCreate(kwsysProcess* cp, int prIndex,
                               kwsysProcessCreateInformation* si)
 {
-  sigset_t mask, old_mask;
+  sigset_t mask;
+  sigset_t old_mask;
   int pgidPipe[2];
   char tmp;
   ssize_t readRes;
@@ -1817,8 +1824,8 @@
   /* Make sure the child is in the process group before we proceed.  This
      avoids race conditions with calls to the kill function that we make for
      signalling process groups.  */
-  while ((readRes = read(pgidPipe[0], &tmp, 1)) > 0)
-    ;
+  while ((readRes = read(pgidPipe[0], &tmp, 1)) > 0) {
+  }
   if (readRes < 0) {
     sigprocmask(SIG_SETMASK, &old_mask, 0);
     kwsysProcessCleanupDescriptor(&si->ErrorPipe[0]);
@@ -1846,8 +1853,8 @@
       /* Keep trying to read until the operation is not interrupted.  */
       while (((n = read(si->ErrorPipe[0], cp->ErrorMessage + total,
                         (size_t)(KWSYSPE_PIPE_BUFFER_SIZE - total))) < 0) &&
-             (errno == EINTR))
-        ;
+             (errno == EINTR)) {
+      }
       if (n > 0) {
         total += n;
       }
@@ -1872,7 +1879,8 @@
   int i;
   /* Temporarily disable signals that access ForkPIDs.  We don't want them to
      read a reaped PID, and writes to ForkPIDs are not atomic.  */
-  sigset_t mask, old_mask;
+  sigset_t mask;
+  sigset_t old_mask;
   sigemptyset(&mask);
   sigaddset(&mask, SIGINT);
   sigaddset(&mask, SIGTERM);
@@ -1885,8 +1893,8 @@
       int result;
       while (((result = waitpid(cp->ForkPIDs[i], &cp->CommandExitCodes[i],
                                 WNOHANG)) < 0) &&
-             (errno == EINTR))
-        ;
+             (errno == EINTR)) {
+      }
       if (result > 0) {
         /* This child has termianted.  */
         cp->ForkPIDs[i] = 0;
@@ -1959,7 +1967,8 @@
 
 /* Get the time at which either the process or user timeout will
    expire.  Returns 1 if the user timeout is first, and 0 otherwise.  */
-static int kwsysProcessGetTimeoutTime(kwsysProcess* cp, double* userTimeout,
+static int kwsysProcessGetTimeoutTime(kwsysProcess* cp,
+                                      const double* userTimeout,
                                       kwsysProcessTime* timeoutTime)
 {
   /* The first time this is called, we need to calculate the time at
@@ -1991,35 +2000,33 @@
 /* Get the length of time before the given timeout time arrives.
    Returns 1 if the time has already arrived, and 0 otherwise.  */
 static int kwsysProcessGetTimeoutLeft(kwsysProcessTime* timeoutTime,
-                                      double* userTimeout,
+                                      const double* userTimeout,
                                       kwsysProcessTimeNative* timeoutLength,
                                       int zeroIsExpired)
 {
   if (timeoutTime->tv_sec < 0) {
     /* No timeout time has been requested.  */
     return 0;
-  } else {
-    /* Calculate the remaining time.  */
-    kwsysProcessTime currentTime = kwsysProcessTimeGetCurrent();
-    kwsysProcessTime timeLeft =
-      kwsysProcessTimeSubtract(*timeoutTime, currentTime);
-    if (timeLeft.tv_sec < 0 && userTimeout && *userTimeout <= 0) {
-      /* Caller has explicitly requested a zero timeout.  */
-      timeLeft.tv_sec = 0;
-      timeLeft.tv_usec = 0;
-    }
-
-    if (timeLeft.tv_sec < 0 ||
-        (timeLeft.tv_sec == 0 && timeLeft.tv_usec == 0 && zeroIsExpired)) {
-      /* Timeout has already expired.  */
-      return 1;
-    } else {
-      /* There is some time left.  */
-      timeoutLength->tv_sec = timeLeft.tv_sec;
-      timeoutLength->tv_usec = timeLeft.tv_usec;
-      return 0;
-    }
   }
+  /* Calculate the remaining time.  */
+  kwsysProcessTime currentTime = kwsysProcessTimeGetCurrent();
+  kwsysProcessTime timeLeft =
+    kwsysProcessTimeSubtract(*timeoutTime, currentTime);
+  if (timeLeft.tv_sec < 0 && userTimeout && *userTimeout <= 0) {
+    /* Caller has explicitly requested a zero timeout.  */
+    timeLeft.tv_sec = 0;
+    timeLeft.tv_usec = 0;
+  }
+
+  if (timeLeft.tv_sec < 0 ||
+      (timeLeft.tv_sec == 0 && timeLeft.tv_usec == 0 && zeroIsExpired)) {
+    /* Timeout has already expired.  */
+    return 1;
+  }
+  /* There is some time left.  */
+  timeoutLength->tv_sec = timeLeft.tv_sec;
+  timeoutLength->tv_usec = timeLeft.tv_usec;
+  return 0;
 }
 
 static kwsysProcessTime kwsysProcessTimeGetCurrent(void)
@@ -2121,17 +2128,17 @@
 #endif
 #ifdef SIGABRT
     case SIGABRT:
-      KWSYSPE_CASE(Other, "Child aborted");
+      KWSYSPE_CASE(Other, "Subprocess aborted");
       break;
 #endif
 #ifdef SIGKILL
     case SIGKILL:
-      KWSYSPE_CASE(Other, "Child killed");
+      KWSYSPE_CASE(Other, "Subprocess killed");
       break;
 #endif
 #ifdef SIGTERM
     case SIGTERM:
-      KWSYSPE_CASE(Other, "Child terminated");
+      KWSYSPE_CASE(Other, "Subprocess terminated");
       break;
 #endif
 #ifdef SIGHUP
@@ -2424,41 +2431,39 @@
     if (middle_pid < 0) {
       /* Fork failed.  Return as if we were not detaching.  */
       return middle_pid;
-    } else if (middle_pid == 0) {
+    }
+    if (middle_pid == 0) {
       /* This is the intermediate process.  Create the real child.  */
       pid_t child_pid = fork();
       if (child_pid == 0) {
         /* This is the real child process.  There is nothing to do here.  */
         return 0;
-      } else {
-        /* Use the error pipe to report the pid to the real parent.  */
-        while ((write(si->ErrorPipe[1], &child_pid, sizeof(child_pid)) < 0) &&
-               (errno == EINTR))
-          ;
-
-        /* Exit without cleanup.  The parent holds all resources.  */
-        kwsysProcessExit();
-        return 0; /* Never reached, but avoids SunCC warning.  */
       }
-    } else {
-      /* This is the original parent process.  The intermediate
-         process will use the error pipe to report the pid of the
-         detached child.  */
-      pid_t child_pid;
-      int status;
-      while ((read(si->ErrorPipe[0], &child_pid, sizeof(child_pid)) < 0) &&
-             (errno == EINTR))
-        ;
+      /* Use the error pipe to report the pid to the real parent.  */
+      while ((write(si->ErrorPipe[1], &child_pid, sizeof(child_pid)) < 0) &&
+             (errno == EINTR)) {
+      }
 
-      /* Wait for the intermediate process to exit and clean it up.  */
-      while ((waitpid(middle_pid, &status, 0) < 0) && (errno == EINTR))
-        ;
-      return child_pid;
+      /* Exit without cleanup.  The parent holds all resources.  */
+      kwsysProcessExit();
+      return 0; /* Never reached, but avoids SunCC warning.  */
     }
-  } else {
-    /* Not creating a detached process.  Use normal fork.  */
-    return fork();
+    /* This is the original parent process.  The intermediate
+        process will use the error pipe to report the pid of the
+        detached child.  */
+    pid_t child_pid;
+    int status;
+    while ((read(si->ErrorPipe[0], &child_pid, sizeof(child_pid)) < 0) &&
+           (errno == EINTR)) {
+    }
+
+    /* Wait for the intermediate process to exit and clean it up.  */
+    while ((waitpid(middle_pid, &status, 0) < 0) && (errno == EINTR)) {
+    }
+    return child_pid;
   }
+  /* Not creating a detached process.  Use normal fork.  */
+  return fork();
 }
 #endif
 
@@ -2563,7 +2568,8 @@
     /* Make sure the process started and provided a valid header.  */
     if (ps && fscanf(ps, "%*[^\n]\n") != EOF) {
       /* Look for processes whose parent is the process being killed.  */
-      int pid, ppid;
+      int pid;
+      int ppid;
       while (fscanf(ps, KWSYSPE_PS_FORMAT, &pid, &ppid) == 2) {
         if (ppid == process_id) {
           /* Recursively kill this child and its children.  */
@@ -2725,8 +2731,8 @@
       sigemptyset(&newSigAction.sa_mask);
       while ((sigaction(SIGCHLD, &newSigAction,
                         &kwsysProcessesOldSigChldAction) < 0) &&
-             (errno == EINTR))
-        ;
+             (errno == EINTR)) {
+      }
 
       /* Install our handler for SIGINT / SIGTERM.  Repeat call until
          it is not interrupted.  */
@@ -2734,15 +2740,15 @@
       sigaddset(&newSigAction.sa_mask, SIGTERM);
       while ((sigaction(SIGINT, &newSigAction,
                         &kwsysProcessesOldSigIntAction) < 0) &&
-             (errno == EINTR))
-        ;
+             (errno == EINTR)) {
+      }
 
       sigemptyset(&newSigAction.sa_mask);
       sigaddset(&newSigAction.sa_mask, SIGINT);
       while ((sigaction(SIGTERM, &newSigAction,
                         &kwsysProcessesOldSigIntAction) < 0) &&
-             (errno == EINTR))
-        ;
+             (errno == EINTR)) {
+      }
     }
   }
 
@@ -2773,14 +2779,14 @@
         /* Restore the signal handlers.  Repeat call until it is not
            interrupted.  */
         while ((sigaction(SIGCHLD, &kwsysProcessesOldSigChldAction, 0) < 0) &&
-               (errno == EINTR))
-          ;
+               (errno == EINTR)) {
+        }
         while ((sigaction(SIGINT, &kwsysProcessesOldSigIntAction, 0) < 0) &&
-               (errno == EINTR))
-          ;
+               (errno == EINTR)) {
+        }
         while ((sigaction(SIGTERM, &kwsysProcessesOldSigTermAction, 0) < 0) &&
-               (errno == EINTR))
-          ;
+               (errno == EINTR)) {
+        }
 
         /* Free the table of process pointers since it is now empty.
            This is safe because the signal handler has been removed.  */
@@ -2806,7 +2812,10 @@
 #endif
 )
 {
-  int i, j, procStatus, old_errno = errno;
+  int i;
+  int j;
+  int procStatus;
+  int old_errno = errno;
 #if KWSYSPE_USE_SIGINFO
   (void)info;
   (void)ucontext;
@@ -2863,8 +2872,8 @@
         memset(&defSigAction, 0, sizeof(defSigAction));
         defSigAction.sa_handler = SIG_DFL;
         sigemptyset(&defSigAction.sa_mask);
-        while ((sigaction(signum, &defSigAction, 0) < 0) && (errno == EINTR))
-          ;
+        while ((sigaction(signum, &defSigAction, 0) < 0) && (errno == EINTR)) {
+        }
         /* Unmask the signal.  */
         sigemptyset(&unblockSet);
         sigaddset(&unblockSet, signum);
diff --git a/Source/kwsys/ProcessWin32.c b/Source/kwsys/ProcessWin32.c
index 68c5218..1267076 100644
--- a/Source/kwsys/ProcessWin32.c
+++ b/Source/kwsys/ProcessWin32.c
@@ -31,9 +31,6 @@
 #include <io.h>     /* _unlink */
 #include <stdio.h>  /* sprintf */
 #include <string.h> /* strlen, strdup */
-#ifdef __WATCOMC__
-#  define _unlink unlink
-#endif
 
 #ifndef _MAX_FNAME
 #  define _MAX_FNAME 4096
@@ -48,11 +45,6 @@
 #  pragma warning(disable : 4706)
 #endif
 
-#if defined(__BORLANDC__)
-#  pragma warn - 8004 /* assigned a value that is never used  */
-#  pragma warn - 8060 /* Assignment inside if() condition.  */
-#endif
-
 /* There are pipes for the process pipeline's stdout and stderr.  */
 #define KWSYSPE_PIPE_COUNT 2
 #define KWSYSPE_PIPE_STDOUT 0
@@ -761,7 +753,7 @@
   }
 }
 
-void kwsysProcess_SetPipeNative(kwsysProcess* cp, int pipe, HANDLE p[2])
+void kwsysProcess_SetPipeNative(kwsysProcess* cp, int pipe, const HANDLE p[2])
 {
   HANDLE* pPipeNative = 0;
 
diff --git a/Source/kwsys/RegularExpression.cxx b/Source/kwsys/RegularExpression.cxx
index 5e6f8da..4f74eba 100644
--- a/Source/kwsys/RegularExpression.cxx
+++ b/Source/kwsys/RegularExpression.cxx
@@ -28,8 +28,8 @@
 #  include "RegularExpression.hxx.in"
 #endif
 
-#include <stdio.h>
-#include <string.h>
+#include <cstdio>
+#include <cstring>
 
 namespace KWSYS_NAMESPACE {
 
@@ -367,8 +367,7 @@
 
   // Allocate space.
   //#ifndef _WIN32
-  if (this->program != nullptr)
-    delete[] this->program;
+  delete[] this->program;
   //#endif
   this->program = new char[comp.regsize];
   this->progsize = static_cast<int>(comp.regsize);
diff --git a/Source/kwsys/RegularExpression.hxx.in b/Source/kwsys/RegularExpression.hxx.in
index d11db88..2709cde 100644
--- a/Source/kwsys/RegularExpression.hxx.in
+++ b/Source/kwsys/RegularExpression.hxx.in
@@ -26,12 +26,6 @@
 
 #include <string>
 
-/* Disable useless Borland warnings.  KWSys tries not to force things
-   on its includers, but there is no choice here.  */
-#if defined(__BORLANDC__)
-#  pragma warn - 8027 /* function not inlined.  */
-#endif
-
 namespace @KWSYS_NAMESPACE@ {
 
 // Forward declaration
diff --git a/Source/kwsys/SharedForward.h.in b/Source/kwsys/SharedForward.h.in
index 5716cd4..091334b 100644
--- a/Source/kwsys/SharedForward.h.in
+++ b/Source/kwsys/SharedForward.h.in
@@ -66,12 +66,6 @@
 #    endif
 #  endif
 
-#  if defined(__BORLANDC__) && !defined(__cplusplus)
-/* Code has no effect; raised by winnt.h in C (not C++) when ignoring an
-   unused parameter using "(param)" syntax (i.e. no cast to void).  */
-#    pragma warn - 8019
-#  endif
-
 /* Full path to the directory in which this executable is built.  Do
    not include a trailing slash.  */
 #  if !defined(@KWSYS_NAMESPACE@_SHARED_FORWARD_DIR_BUILD)
diff --git a/Source/kwsys/String.hxx.in b/Source/kwsys/String.hxx.in
index db1cf22..c36f4ce 100644
--- a/Source/kwsys/String.hxx.in
+++ b/Source/kwsys/String.hxx.in
@@ -52,14 +52,6 @@
   }
 }; // End Class: String
 
-#if defined(__WATCOMC__)
-inline bool operator<(String const& l, String const& r)
-{
-  return (static_cast<std::string const&>(l) <
-          static_cast<std::string const&>(r));
-}
-#endif
-
 } // namespace @KWSYS_NAMESPACE@
 
 #endif
diff --git a/Source/kwsys/System.c b/Source/kwsys/System.c
index d43cc6f..dbfd2fd 100644
--- a/Source/kwsys/System.c
+++ b/Source/kwsys/System.c
@@ -22,7 +22,7 @@
 typedef int kwsysSystem_ptrdiff_t;
 #endif
 
-static int kwsysSystem__AppendByte(char* local, char** begin, char** end,
+static int kwsysSystem__AppendByte(const char* local, char** begin, char** end,
                                    int* size, char c)
 {
   /* Allocate space for the character.  */
diff --git a/Source/kwsys/SystemInformation.cxx b/Source/kwsys/SystemInformation.cxx
index 6ec6e48..9c34a56 100644
--- a/Source/kwsys/SystemInformation.cxx
+++ b/Source/kwsys/SystemInformation.cxx
@@ -64,9 +64,9 @@
 #else
 #  include <sys/types.h>
 
-#  include <errno.h> // extern int errno;
+#  include <cerrno> // extern int errno;
+#  include <csignal>
 #  include <fcntl.h>
-#  include <signal.h>
 #  include <sys/resource.h> // getrlimit
 #  include <sys/time.h>
 #  include <sys/utsname.h> // int uname(struct utsname *buf);
@@ -132,7 +132,7 @@
 #    endif
 #  endif
 #  if defined(KWSYS_CXX_HAS_RLIMIT64)
-typedef struct rlimit64 ResourceLimitType;
+using ResourceLimitType = struct rlimit64;
 #    define GetResourceLimit getrlimit64
 #  else
 typedef struct rlimit ResourceLimitType;
@@ -163,39 +163,11 @@
 #  undef KWSYS_SYSTEMINFORMATION_HAS_SYMBOL_LOOKUP
 #endif
 
-#include <ctype.h> // int isdigit(int c);
+#include <cctype> // int isdigit(int c);
+#include <cstdio>
+#include <cstdlib>
+#include <cstring>
 #include <memory.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#if defined(KWSYS_USE_LONG_LONG)
-#  if defined(KWSYS_IOS_HAS_OSTREAM_LONG_LONG)
-#    define iostreamLongLong(x) (x)
-#  else
-#    define iostreamLongLong(x) ((long)(x))
-#  endif
-#elif defined(KWSYS_USE___INT64)
-#  if defined(KWSYS_IOS_HAS_OSTREAM___INT64)
-#    define iostreamLongLong(x) (x)
-#  else
-#    define iostreamLongLong(x) ((long)(x))
-#  endif
-#else
-#  error "No Long Long"
-#endif
-
-#if defined(KWSYS_CXX_HAS_ATOLL)
-#  define atoLongLong atoll
-#else
-#  if defined(KWSYS_CXX_HAS__ATOI64)
-#    define atoLongLong _atoi64
-#  elif defined(KWSYS_CXX_HAS_ATOL)
-#    define atoLongLong atol
-#  else
-#    define atoLongLong atoi
-#  endif
-#endif
 
 #if defined(_MSC_VER) && (_MSC_VER >= 1300) && !defined(_WIN64) &&            \
   !defined(__clang__)
@@ -204,15 +176,15 @@
 #  define USE_ASM_INSTRUCTIONS 0
 #endif
 
-#if defined(_MSC_VER) && (_MSC_VER >= 1400) && !defined(__clang__)
+#if defined(_MSC_VER) && (_MSC_VER >= 1400) && !defined(__clang__) &&         \
+  !defined(_M_ARM64)
 #  include <intrin.h>
 #  define USE_CPUID_INTRINSICS 1
 #else
 #  define USE_CPUID_INTRINSICS 0
 #endif
 
-#if USE_ASM_INSTRUCTIONS || USE_CPUID_INTRINSICS ||                           \
-  defined(KWSYS_CXX_HAS_BORLAND_ASM_CPUID)
+#if USE_ASM_INSTRUCTIONS || USE_CPUID_INTRINSICS
 #  define USE_CPUID 1
 #else
 #  define USE_CPUID 0
@@ -272,21 +244,6 @@
   }
 
   memcpy(result, tmp, sizeof(tmp));
-#    elif defined(KWSYS_CXX_HAS_BORLAND_ASM_CPUID)
-  unsigned int a, b, c, d;
-  __asm {
-    mov EAX, select;
-    cpuid
-    mov a, EAX;
-    mov b, EBX;
-    mov c, ECX;
-    mov d, EDX;
-  }
-
-  result[0] = a;
-  result[1] = b;
-  result[2] = c;
-  result[3] = d;
 #    endif
 
   // The cpuid instruction succeeded.
@@ -303,34 +260,33 @@
 }
 
 extern "C" {
-typedef void (*SigAction)(int, siginfo_t*, void*);
+using SigAction = void (*)(int, siginfo_t*, void*);
 }
 
 //  Define SystemInformationImplementation class
-typedef void (*DELAY_FUNC)(unsigned int uiMS);
+using DELAY_FUNC = void (*)(unsigned int);
 
 class SystemInformationImplementation
 {
 public:
-  typedef SystemInformation::LongLong LongLong;
   SystemInformationImplementation();
-  ~SystemInformationImplementation();
+  ~SystemInformationImplementation() = default;
 
-  const char* GetVendorString();
+  const char* GetVendorString() const;
   const char* GetVendorID();
-  std::string GetTypeID();
-  std::string GetFamilyID();
-  std::string GetModelID();
-  std::string GetModelName();
-  std::string GetSteppingCode();
-  const char* GetExtendedProcessorName();
-  const char* GetProcessorSerialNumber();
-  int GetProcessorCacheSize();
-  unsigned int GetLogicalProcessorsPerPhysical();
-  float GetProcessorClockFrequency();
-  int GetProcessorAPICID();
-  int GetProcessorCacheXSize(long int);
-  bool DoesCPUSupportFeature(long int);
+  std::string GetTypeID() const;
+  std::string GetFamilyID() const;
+  std::string GetModelID() const;
+  std::string GetModelName() const;
+  std::string GetSteppingCode() const;
+  const char* GetExtendedProcessorName() const;
+  const char* GetProcessorSerialNumber() const;
+  int GetProcessorCacheSize() const;
+  unsigned int GetLogicalProcessorsPerPhysical() const;
+  float GetProcessorClockFrequency() const;
+  int GetProcessorAPICID() const;
+  int GetProcessorCacheXSize(long int) const;
+  bool DoesCPUSupportFeature(long int) const;
 
   const char* GetOSName();
   const char* GetHostname();
@@ -339,29 +295,29 @@
   const char* GetOSVersion();
   const char* GetOSPlatform();
 
-  bool Is64Bits();
+  bool Is64Bits() const;
 
-  unsigned int GetNumberOfLogicalCPU(); // per physical cpu
-  unsigned int GetNumberOfPhysicalCPU();
+  unsigned int GetNumberOfLogicalCPU() const; // per physical cpu
+  unsigned int GetNumberOfPhysicalCPU() const;
 
   bool DoesCPUSupportCPUID();
 
   // Retrieve memory information in MiB.
-  size_t GetTotalVirtualMemory();
-  size_t GetAvailableVirtualMemory();
-  size_t GetTotalPhysicalMemory();
-  size_t GetAvailablePhysicalMemory();
+  size_t GetTotalVirtualMemory() const;
+  size_t GetAvailableVirtualMemory() const;
+  size_t GetTotalPhysicalMemory() const;
+  size_t GetAvailablePhysicalMemory() const;
 
-  LongLong GetProcessId();
+  long long GetProcessId();
 
   // Retrieve memory information in KiB.
-  LongLong GetHostMemoryTotal();
-  LongLong GetHostMemoryAvailable(const char* envVarName);
-  LongLong GetHostMemoryUsed();
+  long long GetHostMemoryTotal();
+  long long GetHostMemoryAvailable(const char* hostLimitEnvVarName);
+  long long GetHostMemoryUsed();
 
-  LongLong GetProcMemoryAvailable(const char* hostLimitEnvVarName,
-                                  const char* procLimitEnvVarName);
-  LongLong GetProcMemoryUsed();
+  long long GetProcMemoryAvailable(const char* hostLimitEnvVarName,
+                                   const char* procLimitEnvVarName);
+  long long GetProcMemoryUsed();
 
   double GetLoadAverage();
 
@@ -377,60 +333,103 @@
   void RunMemoryCheck();
 
 public:
-  typedef struct tagID
+  using ID = struct tagID
+
   {
+
     int Type;
+
     int Family;
+
     int Model;
+
     int Revision;
+
     int ExtendedFamily;
+
     int ExtendedModel;
+
     std::string ProcessorName;
+
     std::string Vendor;
+
     std::string SerialNumber;
+
     std::string ModelName;
-  } ID;
+  };
 
-  typedef struct tagCPUPowerManagement
+  using CPUPowerManagement = struct tagCPUPowerManagement
+
   {
+
     bool HasVoltageID;
+
     bool HasFrequencyID;
+
     bool HasTempSenseDiode;
-  } CPUPowerManagement;
+  };
 
-  typedef struct tagCPUExtendedFeatures
+  using CPUExtendedFeatures = struct tagCPUExtendedFeatures
+
   {
+
     bool Has3DNow;
-    bool Has3DNowPlus;
-    bool SupportsMP;
-    bool HasMMXPlus;
-    bool HasSSEMMX;
-    unsigned int LogicalProcessorsPerPhysical;
-    int APIC_ID;
-    CPUPowerManagement PowerManagement;
-  } CPUExtendedFeatures;
 
-  typedef struct CPUtagFeatures
+    bool Has3DNowPlus;
+
+    bool SupportsMP;
+
+    bool HasMMXPlus;
+
+    bool HasSSEMMX;
+
+    unsigned int LogicalProcessorsPerPhysical;
+
+    int APIC_ID;
+
+    CPUPowerManagement PowerManagement;
+  };
+
+  using CPUFeatures = struct CPUtagFeatures
+
   {
+
     bool HasFPU;
+
     bool HasTSC;
+
     bool HasMMX;
+
     bool HasSSE;
+
     bool HasSSEFP;
+
     bool HasSSE2;
+
     bool HasIA64;
+
     bool HasAPIC;
+
     bool HasCMOV;
+
     bool HasMTRR;
+
     bool HasACPI;
+
     bool HasSerial;
+
     bool HasThermal;
+
     int CPUSpeed;
+
     int L1CacheSize;
+
     int L2CacheSize;
+
     int L3CacheSize;
+
     CPUExtendedFeatures ExtendedFeatures;
-  } CPUFeatures;
+  };
 
   enum Manufacturer
   {
@@ -476,8 +475,9 @@
 
   void CPUCountWindows();    // For windows
   unsigned char GetAPICId(); // For windows
-  bool IsSMTSupported();
-  static LongLong GetCyclesDifference(DELAY_FUNC, unsigned int); // For windows
+  bool IsSMTSupported() const;
+  static long long GetCyclesDifference(DELAY_FUNC,
+                                       unsigned int); // For windows
 
   // For Linux and Cygwin, /proc/cpuinfo formats are slightly different
   bool RetreiveInformationFromCpuInfoFile();
@@ -768,42 +768,41 @@
   const char* hostLimitEnvVarName, const char* procLimitEnvVarName)
 {
   std::ostringstream oss;
-  oss << "Host Total: " << iostreamLongLong(this->GetHostMemoryTotal())
+  oss << "Host Total: " << this->GetHostMemoryTotal()
       << " KiB, Host Available: "
-      << iostreamLongLong(this->GetHostMemoryAvailable(hostLimitEnvVarName))
+      << this->GetHostMemoryAvailable(hostLimitEnvVarName)
       << " KiB, Process Available: "
-      << iostreamLongLong(this->GetProcMemoryAvailable(hostLimitEnvVarName,
-                                                       procLimitEnvVarName))
+      << this->GetProcMemoryAvailable(hostLimitEnvVarName, procLimitEnvVarName)
       << " KiB";
   return oss.str();
 }
 
 // host memory info in units of KiB.
-SystemInformation::LongLong SystemInformation::GetHostMemoryTotal()
+long long SystemInformation::GetHostMemoryTotal()
 {
   return this->Implementation->GetHostMemoryTotal();
 }
 
-SystemInformation::LongLong SystemInformation::GetHostMemoryAvailable(
+long long SystemInformation::GetHostMemoryAvailable(
   const char* hostLimitEnvVarName)
 {
   return this->Implementation->GetHostMemoryAvailable(hostLimitEnvVarName);
 }
 
-SystemInformation::LongLong SystemInformation::GetHostMemoryUsed()
+long long SystemInformation::GetHostMemoryUsed()
 {
   return this->Implementation->GetHostMemoryUsed();
 }
 
 // process memory info in units of KiB.
-SystemInformation::LongLong SystemInformation::GetProcMemoryAvailable(
+long long SystemInformation::GetProcMemoryAvailable(
   const char* hostLimitEnvVarName, const char* procLimitEnvVarName)
 {
   return this->Implementation->GetProcMemoryAvailable(hostLimitEnvVarName,
                                                       procLimitEnvVarName);
 }
 
-SystemInformation::LongLong SystemInformation::GetProcMemoryUsed()
+long long SystemInformation::GetProcMemoryUsed()
 {
   return this->Implementation->GetProcMemoryUsed();
 }
@@ -813,7 +812,7 @@
   return this->Implementation->GetLoadAverage();
 }
 
-SystemInformation::LongLong SystemInformation::GetProcessId()
+long long SystemInformation::GetProcessId()
 {
   return this->Implementation->GetProcessId();
 }
@@ -864,7 +863,7 @@
 // Hide implementation details in an anonymous namespace.
 namespace {
 // *****************************************************************************
-#if defined(__linux) || defined(__APPLE__)
+#if defined(__linux) || defined(__APPLE__) || defined(__CYGWIN__)
 int LoadLines(FILE* file, std::vector<std::string>& lines)
 {
   // Load each line in the given file into a the vector.
@@ -885,7 +884,7 @@
         *pBuf = '\0';
       pBuf += 1;
     }
-    lines.push_back(buf);
+    lines.emplace_back(buf);
     ++nRead;
   }
   if (ferror(file)) {
@@ -894,12 +893,12 @@
   return nRead;
 }
 
-#  if defined(__linux)
+#  if defined(__linux) || defined(__CYGWIN__)
 // *****************************************************************************
 int LoadLines(const char* fileName, std::vector<std::string>& lines)
 {
   FILE* file = fopen(fileName, "r");
-  if (file == 0) {
+  if (file == nullptr) {
     return 0;
   }
   int nRead = LoadLines(file, lines);
@@ -927,7 +926,7 @@
 }
 #endif
 
-#if defined(__linux)
+#if defined(__linux) || defined(__CYGWIN__)
 // ****************************************************************************
 template <typename T>
 int GetFieldsFromFile(const char* fileName, const char** fieldNames, T* values)
@@ -1322,9 +1321,9 @@
 {
   std::string file(path);
   if (!this->ReportPath) {
-    size_t at = file.rfind("/");
+    size_t at = file.rfind('/');
     if (at != std::string::npos) {
-      file = file.substr(at + 1);
+      file.erase(0, at + 1);
     }
   }
   return file;
@@ -1464,10 +1463,6 @@
   this->OSIs64Bit = (sizeof(void*) == 8);
 }
 
-SystemInformationImplementation::~SystemInformationImplementation()
-{
-}
-
 void SystemInformationImplementation::RunCPUCheck()
 {
 #ifdef _WIN32
@@ -1564,7 +1559,7 @@
 }
 
 /** Get the vendor string */
-const char* SystemInformationImplementation::GetVendorString()
+const char* SystemInformationImplementation::GetVendorString() const
 {
   return this->ChipID.Vendor.c_str();
 }
@@ -1760,7 +1755,7 @@
 }
 
 /** Return the type ID of the CPU */
-std::string SystemInformationImplementation::GetTypeID()
+std::string SystemInformationImplementation::GetTypeID() const
 {
   std::ostringstream str;
   str << this->ChipID.Type;
@@ -1768,7 +1763,7 @@
 }
 
 /** Return the family of the CPU present */
-std::string SystemInformationImplementation::GetFamilyID()
+std::string SystemInformationImplementation::GetFamilyID() const
 {
   std::ostringstream str;
   str << this->ChipID.Family;
@@ -1776,7 +1771,7 @@
 }
 
 // Return the model of CPU present */
-std::string SystemInformationImplementation::GetModelID()
+std::string SystemInformationImplementation::GetModelID() const
 {
   std::ostringstream str;
   str << this->ChipID.Model;
@@ -1784,13 +1779,13 @@
 }
 
 // Return the model name of CPU present */
-std::string SystemInformationImplementation::GetModelName()
+std::string SystemInformationImplementation::GetModelName() const
 {
   return this->ChipID.ModelName;
 }
 
 /** Return the stepping code of the CPU present. */
-std::string SystemInformationImplementation::GetSteppingCode()
+std::string SystemInformationImplementation::GetSteppingCode() const
 {
   std::ostringstream str;
   str << this->ChipID.Revision;
@@ -1798,44 +1793,46 @@
 }
 
 /** Return the stepping code of the CPU present. */
-const char* SystemInformationImplementation::GetExtendedProcessorName()
+const char* SystemInformationImplementation::GetExtendedProcessorName() const
 {
   return this->ChipID.ProcessorName.c_str();
 }
 
 /** Return the serial number of the processor
  *  in hexadecimal: xxxx-xxxx-xxxx-xxxx-xxxx-xxxx. */
-const char* SystemInformationImplementation::GetProcessorSerialNumber()
+const char* SystemInformationImplementation::GetProcessorSerialNumber() const
 {
   return this->ChipID.SerialNumber.c_str();
 }
 
 /** Return the logical processors per physical */
 unsigned int SystemInformationImplementation::GetLogicalProcessorsPerPhysical()
+  const
 {
   return this->Features.ExtendedFeatures.LogicalProcessorsPerPhysical;
 }
 
 /** Return the processor clock frequency. */
-float SystemInformationImplementation::GetProcessorClockFrequency()
+float SystemInformationImplementation::GetProcessorClockFrequency() const
 {
   return this->CPUSpeedInMHz;
 }
 
 /**  Return the APIC ID. */
-int SystemInformationImplementation::GetProcessorAPICID()
+int SystemInformationImplementation::GetProcessorAPICID() const
 {
   return this->Features.ExtendedFeatures.APIC_ID;
 }
 
 /** Return the L1 cache size. */
-int SystemInformationImplementation::GetProcessorCacheSize()
+int SystemInformationImplementation::GetProcessorCacheSize() const
 {
   return this->Features.L1CacheSize;
 }
 
 /** Return the chosen cache size. */
-int SystemInformationImplementation::GetProcessorCacheXSize(long int dwCacheID)
+int SystemInformationImplementation::GetProcessorCacheXSize(
+  long int dwCacheID) const
 {
   switch (dwCacheID) {
     case SystemInformation::CPU_FEATURE_L1CACHE:
@@ -1848,7 +1845,8 @@
   return -1;
 }
 
-bool SystemInformationImplementation::DoesCPUSupportFeature(long int dwFeature)
+bool SystemInformationImplementation::DoesCPUSupportFeature(
+  long int dwFeature) const
 {
   bool bHasFeature = false;
 
@@ -2128,7 +2126,7 @@
     this->ChipManufacturer = HP; // Hewlett-Packard
   else if (this->ChipID.Vendor == "Motorola")
     this->ChipManufacturer = Motorola; // Motorola Microelectronics
-  else if (family.substr(0, 7) == "PA-RISC")
+  else if (family.compare(0, 7, "PA-RISC") == 0)
     this->ChipManufacturer = HP; // Hewlett-Packard
   else
     this->ChipManufacturer = UnknownManufacturer; // Unknown manufacturer
@@ -2843,7 +2841,7 @@
   // post-process the name.
   std::string::size_type pos = str.find_first_not_of(" ");
   if (pos != std::string::npos) {
-    str = str.substr(pos);
+    str.erase(0, pos);
   }
 }
 #endif
@@ -3344,8 +3342,8 @@
   size_t pos = buffer.find(word, init);
   if (pos != std::string::npos) {
     this->CurrentPositionInFile = pos;
-    pos = buffer.find(":", pos);
-    size_t pos2 = buffer.find("\n", pos);
+    pos = buffer.find(':', pos);
+    size_t pos2 = buffer.find('\n', pos);
     if (pos != std::string::npos && pos2 != std::string::npos) {
       // It may happen that the beginning matches, but this is still not the
       // requested key.
@@ -3358,7 +3356,9 @@
           return this->ExtractValueFromCpuInfoFile(buffer, word, pos2);
         }
       }
-      return buffer.substr(pos + 2, pos2 - pos - 2);
+      buffer.erase(0, pos + 2);
+      buffer.resize(pos2 - pos - 2);
+      return buffer;
     }
   }
   this->CurrentPositionInFile = std::string::npos;
@@ -3393,7 +3393,7 @@
     pos = buffer.find("processor\t", pos + 1);
   }
 
-#ifdef __linux
+#if defined(__linux) || defined(__CYGWIN__)
   // Count sockets.
   std::set<int> PhysicalIDs;
   std::string idc = this->ExtractValueFromCpuInfoFile(buffer, "physical id");
@@ -3409,13 +3409,13 @@
   // We want to record the total number of cores in this->NumberOfPhysicalCPU
   // (checking only the first proc)
   std::string Cores = this->ExtractValueFromCpuInfoFile(buffer, "cpu cores");
-  unsigned int NumberOfCoresPerSocket = (unsigned int)atoi(Cores.c_str());
+  auto NumberOfCoresPerSocket = (unsigned int)atoi(Cores.c_str());
   NumberOfCoresPerSocket = std::max(NumberOfCoresPerSocket, 1u);
   this->NumberOfPhysicalCPU =
     NumberOfCoresPerSocket * (unsigned int)NumberOfSockets;
 
-#else // __CYGWIN__
-  // does not have "physical id" entries, neither "cpu cores"
+#else
+  // For systems which do not have "physical id" entries, neither "cpu cores"
   // this has to be fixed for hyper-threading.
   std::string cpucount =
     this->ExtractValueFromCpuInfoFile(buffer, "cpu count");
@@ -3441,7 +3441,7 @@
     // Linux Sparc: CPU speed is in Hz and encoded in hexadecimal
     CPUSpeed = this->ExtractValueFromCpuInfoFile(buffer, "Cpu0ClkTck");
     this->CPUSpeedInMHz =
-      static_cast<float>(strtoull(CPUSpeed.c_str(), 0, 16)) / 1000000.0f;
+      static_cast<float>(strtoull(CPUSpeed.c_str(), nullptr, 16)) / 1000000.0f;
   }
 #endif
 
@@ -3502,13 +3502,12 @@
   cachename.push_back("D-cache");    // e.g. PA-RISC
 
   this->Features.L1CacheSize = 0;
-  for (size_t index = 0; index < cachename.size(); index++) {
-    std::string cacheSize =
-      this->ExtractValueFromCpuInfoFile(buffer, cachename[index]);
+  for (auto& index : cachename) {
+    std::string cacheSize = this->ExtractValueFromCpuInfoFile(buffer, index);
     if (!cacheSize.empty()) {
       pos = cacheSize.find(" KB");
       if (pos != std::string::npos) {
-        cacheSize = cacheSize.substr(0, pos);
+        cacheSize.resize(pos);
       }
       this->Features.L1CacheSize += atoi(cacheSize.c_str());
     }
@@ -3584,8 +3583,7 @@
 /**
 Get total system RAM in units of KiB.
 */
-SystemInformation::LongLong
-SystemInformationImplementation::GetHostMemoryTotal()
+long long SystemInformationImplementation::GetHostMemoryTotal()
 {
 #if defined(_WIN32)
 #  if defined(_MSC_VER) && _MSC_VER < 1300
@@ -3599,8 +3597,8 @@
   GlobalMemoryStatusEx(&statex);
   return statex.ullTotalPhys / 1024;
 #  endif
-#elif defined(__linux)
-  SystemInformation::LongLong memTotal = 0;
+#elif defined(__linux) || defined(__CYGWIN__)
+  long long memTotal = 0;
   int ierr = GetFieldFromFile("/proc/meminfo", "MemTotal:", memTotal);
   if (ierr) {
     return -1;
@@ -3623,11 +3621,10 @@
 Get total system RAM in units of KiB. This may differ from the
 host total if a host-wide resource limit is applied.
 */
-SystemInformation::LongLong
-SystemInformationImplementation::GetHostMemoryAvailable(
+long long SystemInformationImplementation::GetHostMemoryAvailable(
   const char* hostLimitEnvVarName)
 {
-  SystemInformation::LongLong memTotal = this->GetHostMemoryTotal();
+  long long memTotal = this->GetHostMemoryTotal();
 
   // the following mechanism is provided for systems that
   // apply resource limits across groups of processes.
@@ -3638,8 +3635,7 @@
   if (hostLimitEnvVarName) {
     const char* hostLimitEnvVarValue = getenv(hostLimitEnvVarName);
     if (hostLimitEnvVarValue) {
-      SystemInformation::LongLong hostLimit =
-        atoLongLong(hostLimitEnvVarValue);
+      long long hostLimit = std::atoll(hostLimitEnvVarValue);
       if (hostLimit > 0) {
         memTotal = min(hostLimit, memTotal);
       }
@@ -3653,20 +3649,17 @@
 Get total system RAM in units of KiB. This may differ from the
 host total if a per-process resource limit is applied.
 */
-SystemInformation::LongLong
-SystemInformationImplementation::GetProcMemoryAvailable(
+long long SystemInformationImplementation::GetProcMemoryAvailable(
   const char* hostLimitEnvVarName, const char* procLimitEnvVarName)
 {
-  SystemInformation::LongLong memAvail =
-    this->GetHostMemoryAvailable(hostLimitEnvVarName);
+  long long memAvail = this->GetHostMemoryAvailable(hostLimitEnvVarName);
 
   // the following mechanism is provide for systems where rlimits
   // are not employed. Units are in KiB.
   if (procLimitEnvVarName) {
     const char* procLimitEnvVarValue = getenv(procLimitEnvVarName);
     if (procLimitEnvVarValue) {
-      SystemInformation::LongLong procLimit =
-        atoLongLong(procLimitEnvVarValue);
+      long long procLimit = std::atoll(procLimitEnvVarValue);
       if (procLimit > 0) {
         memAvail = min(procLimit, memAvail);
       }
@@ -3678,28 +3671,24 @@
   ResourceLimitType rlim;
   ierr = GetResourceLimit(RLIMIT_DATA, &rlim);
   if ((ierr == 0) && (rlim.rlim_cur != RLIM_INFINITY)) {
-    memAvail =
-      min((SystemInformation::LongLong)rlim.rlim_cur / 1024, memAvail);
+    memAvail = min((long long)rlim.rlim_cur / 1024, memAvail);
   }
 
   ierr = GetResourceLimit(RLIMIT_AS, &rlim);
   if ((ierr == 0) && (rlim.rlim_cur != RLIM_INFINITY)) {
-    memAvail =
-      min((SystemInformation::LongLong)rlim.rlim_cur / 1024, memAvail);
+    memAvail = min((long long)rlim.rlim_cur / 1024, memAvail);
   }
 #elif defined(__APPLE__)
   struct rlimit rlim;
   int ierr;
   ierr = getrlimit(RLIMIT_DATA, &rlim);
   if ((ierr == 0) && (rlim.rlim_cur != RLIM_INFINITY)) {
-    memAvail =
-      min((SystemInformation::LongLong)rlim.rlim_cur / 1024, memAvail);
+    memAvail = min((long long)rlim.rlim_cur / 1024, memAvail);
   }
 
   ierr = getrlimit(RLIMIT_RSS, &rlim);
   if ((ierr == 0) && (rlim.rlim_cur != RLIM_INFINITY)) {
-    memAvail =
-      min((SystemInformation::LongLong)rlim.rlim_cur / 1024, memAvail);
+    memAvail = min((long long)rlim.rlim_cur / 1024, memAvail);
   }
 #endif
 
@@ -3709,8 +3698,7 @@
 /**
 Get RAM used by all processes in the host, in units of KiB.
 */
-SystemInformation::LongLong
-SystemInformationImplementation::GetHostMemoryUsed()
+long long SystemInformationImplementation::GetHostMemoryUsed()
 {
 #if defined(_WIN32)
 #  if defined(_MSC_VER) && _MSC_VER < 1300
@@ -3724,42 +3712,51 @@
   GlobalMemoryStatusEx(&statex);
   return (statex.ullTotalPhys - statex.ullAvailPhys) / 1024;
 #  endif
+#elif defined(__CYGWIN__)
+  const char* names[3] = { "MemTotal:", "MemFree:", nullptr };
+  long long values[2] = { 0 };
+  int ierr = GetFieldsFromFile("/proc/meminfo", names, values);
+  if (ierr) {
+    return ierr;
+  }
+  long long& memTotal = values[0];
+  long long& memFree = values[1];
+  return memTotal - memFree;
 #elif defined(__linux)
   // First try to use MemAvailable, but it only works on newer kernels
   const char* names2[3] = { "MemTotal:", "MemAvailable:", nullptr };
-  SystemInformation::LongLong values2[2] = { SystemInformation::LongLong(0) };
+  long long values2[2] = { 0 };
   int ierr = GetFieldsFromFile("/proc/meminfo", names2, values2);
   if (ierr) {
     const char* names4[5] = { "MemTotal:", "MemFree:", "Buffers:", "Cached:",
                               nullptr };
-    SystemInformation::LongLong values4[4] = { SystemInformation::LongLong(
-      0) };
+    long long values4[4] = { 0 };
     ierr = GetFieldsFromFile("/proc/meminfo", names4, values4);
     if (ierr) {
       return ierr;
     }
-    SystemInformation::LongLong& memTotal = values4[0];
-    SystemInformation::LongLong& memFree = values4[1];
-    SystemInformation::LongLong& memBuffers = values4[2];
-    SystemInformation::LongLong& memCached = values4[3];
+    long long& memTotal = values4[0];
+    long long& memFree = values4[1];
+    long long& memBuffers = values4[2];
+    long long& memCached = values4[3];
     return memTotal - memFree - memBuffers - memCached;
   }
-  SystemInformation::LongLong& memTotal = values2[0];
-  SystemInformation::LongLong& memAvail = values2[1];
+  long long& memTotal = values2[0];
+  long long& memAvail = values2[1];
   return memTotal - memAvail;
 #elif defined(__APPLE__)
-  SystemInformation::LongLong psz = getpagesize();
+  long long psz = getpagesize();
   if (psz < 1) {
     return -1;
   }
   const char* names[3] = { "Pages wired down:", "Pages active:", nullptr };
-  SystemInformation::LongLong values[2] = { SystemInformation::LongLong(0) };
+  long long values[2] = { 0 };
   int ierr = GetFieldsFromCommand("vm_stat", names, values);
   if (ierr) {
     return -1;
   }
-  SystemInformation::LongLong& vmWired = values[0];
-  SystemInformation::LongLong& vmActive = values[1];
+  long long& vmWired = values[0];
+  long long& vmActive = values[1];
   return ((vmActive + vmWired) * psz) / 1024;
 #else
   return 0;
@@ -3770,8 +3767,7 @@
 Get system RAM used by the process associated with the given
 process id in units of KiB.
 */
-SystemInformation::LongLong
-SystemInformationImplementation::GetProcMemoryUsed()
+long long SystemInformationImplementation::GetProcMemoryUsed()
 {
 #if defined(_WIN32) && defined(KWSYS_SYS_HAS_PSAPI)
   long pid = GetCurrentProcessId();
@@ -3787,15 +3783,15 @@
     return -2;
   }
   return pmc.WorkingSetSize / 1024;
-#elif defined(__linux)
-  SystemInformation::LongLong memUsed = 0;
+#elif defined(__linux) || defined(__CYGWIN__)
+  long long memUsed = 0;
   int ierr = GetFieldFromFile("/proc/self/status", "VmRSS:", memUsed);
   if (ierr) {
     return -1;
   }
   return memUsed;
 #elif defined(__APPLE__)
-  SystemInformation::LongLong memUsed = 0;
+  long long memUsed = 0;
   pid_t pid = getpid();
   std::ostringstream oss;
   oss << "ps -o rss= -p " << pid;
@@ -3859,12 +3855,13 @@
 /**
 Get the process id of the running process.
 */
-SystemInformation::LongLong SystemInformationImplementation::GetProcessId()
+long long SystemInformationImplementation::GetProcessId()
 {
 #if defined(_WIN32)
   return GetCurrentProcessId();
 #elif defined(__linux) || defined(__APPLE__) || defined(__OpenBSD__) ||       \
-  defined(__FreeBSD__) || defined(__NetBSD__) || defined(__DragonFly__)
+  defined(__FreeBSD__) || defined(__NetBSD__) || defined(__DragonFly__) ||    \
+  defined(__CYGWIN__)
   return getpid();
 #else
   return -1;
@@ -3893,7 +3890,7 @@
                                                              int wholePath)
 {
   std::ostringstream oss;
-  std::string programStack = "";
+  std::string programStack;
 
 #ifdef KWSYS_SYSTEMINFORMATION_HAS_DBGHELP
   (void)wholePath;
@@ -4249,39 +4246,44 @@
 }
 
 /** */
-size_t SystemInformationImplementation::GetTotalVirtualMemory()
+size_t SystemInformationImplementation::GetTotalVirtualMemory() const
 {
   return this->TotalVirtualMemory;
 }
 
 /** */
-size_t SystemInformationImplementation::GetAvailableVirtualMemory()
+size_t SystemInformationImplementation::GetAvailableVirtualMemory() const
 {
   return this->AvailableVirtualMemory;
 }
 
-size_t SystemInformationImplementation::GetTotalPhysicalMemory()
+size_t SystemInformationImplementation::GetTotalPhysicalMemory() const
 {
   return this->TotalPhysicalMemory;
 }
 
 /** */
-size_t SystemInformationImplementation::GetAvailablePhysicalMemory()
+size_t SystemInformationImplementation::GetAvailablePhysicalMemory() const
 {
   return this->AvailablePhysicalMemory;
 }
 
 /** Get Cycle differences */
-SystemInformation::LongLong
-SystemInformationImplementation::GetCyclesDifference(DELAY_FUNC DelayFunction,
-                                                     unsigned int uiParameter)
+long long SystemInformationImplementation::GetCyclesDifference(
+  DELAY_FUNC DelayFunction, unsigned int uiParameter)
 {
 #if defined(_MSC_VER) && (_MSC_VER >= 1400)
   unsigned __int64 stamp1, stamp2;
 
+#  ifdef _M_ARM64
+  stamp1 = _ReadStatusReg(ARM64_PMCCNTR_EL0);
+  DelayFunction(uiParameter);
+  stamp2 = _ReadStatusReg(ARM64_PMCCNTR_EL0);
+#  else
   stamp1 = __rdtsc();
   DelayFunction(uiParameter);
   stamp2 = __rdtsc();
+#  endif
 
   return stamp2 - stamp1;
 #elif USE_ASM_INSTRUCTIONS
@@ -4350,7 +4352,7 @@
 }
 
 /** Works only for windows */
-bool SystemInformationImplementation::IsSMTSupported()
+bool SystemInformationImplementation::IsSMTSupported() const
 {
   return this->Features.ExtendedFeatures.LogicalProcessorsPerPhysical > 1;
 }
@@ -4399,12 +4401,12 @@
     DWORD Length = 0;
     DWORD rc = pGetLogicalProcessorInformation(nullptr, &Length);
     assert(FALSE == rc);
-    (void)rc; // Silence unused variable warning in Borland C++ 5.81
+    (void)rc; // Silence unused variable warning
     assert(GetLastError() == ERROR_INSUFFICIENT_BUFFER);
     ProcInfo.resize(Length / sizeof(SYSTEM_LOGICAL_PROCESSOR_INFORMATION));
     rc = pGetLogicalProcessorInformation(&ProcInfo[0], &Length);
     assert(rc != FALSE);
-    (void)rc; // Silence unused variable warning in Borland C++ 5.81
+    (void)rc; // Silence unused variable warning
   }
 
   typedef std::vector<SYSTEM_LOGICAL_PROCESSOR_INFORMATION>::iterator
@@ -4432,13 +4434,13 @@
 }
 
 /** Return the number of logical CPUs on the system */
-unsigned int SystemInformationImplementation::GetNumberOfLogicalCPU()
+unsigned int SystemInformationImplementation::GetNumberOfLogicalCPU() const
 {
   return this->NumberOfLogicalCPU;
 }
 
 /** Return the number of physical CPUs on the system */
-unsigned int SystemInformationImplementation::GetNumberOfPhysicalCPU()
+unsigned int SystemInformationImplementation::GetNumberOfPhysicalCPU() const
 {
   return this->NumberOfPhysicalCPU;
 }
@@ -4638,7 +4640,7 @@
   size_t pos = this->SysCtlBuffer.find(word);
   if (pos != std::string::npos) {
     pos = this->SysCtlBuffer.find(": ", pos);
-    size_t pos2 = this->SysCtlBuffer.find("\n", pos);
+    size_t pos2 = this->SysCtlBuffer.find('\n', pos);
     if (pos != std::string::npos && pos2 != std::string::npos) {
       return this->SysCtlBuffer.substr(pos + 2, pos2 - pos - 2);
     }
@@ -4733,14 +4735,15 @@
     }
     pos = command.find(' ', pos + 1);
   }
-  args_string.push_back(command.substr(start + 1, command.size() - start - 1));
+  command.erase(0, start + 1);
+  args_string.push_back(command);
 
   std::vector<const char*> args;
   args.reserve(3 + args_string.size());
   args.push_back("kstat");
   args.push_back("-p");
-  for (size_t i = 0; i < args_string.size(); ++i) {
-    args.push_back(args_string[i].c_str());
+  for (auto& i : args_string) {
+    args.push_back(i.c_str());
   }
   args.push_back(nullptr);
 
@@ -4922,7 +4925,9 @@
   while (buffer[pos] == ' ')
     pos++;
 
-  this->TotalPhysicalMemory = atoi(buffer.substr(pos, pos2 - pos).c_str());
+  buffer.erase(0, pos);
+  buffer.resize(pos2);
+  this->TotalPhysicalMemory = atoi(buffer.c_str());
   return true;
 #endif
   return false;
@@ -5447,19 +5452,19 @@
 {
   // remove \r
   std::string::size_type pos = 0;
-  while ((pos = output.find("\r", pos)) != std::string::npos) {
+  while ((pos = output.find('\r', pos)) != std::string::npos) {
     output.erase(pos);
   }
 
   // remove \n
   pos = 0;
-  while ((pos = output.find("\n", pos)) != std::string::npos) {
+  while ((pos = output.find('\n', pos)) != std::string::npos) {
     output.erase(pos);
   }
 }
 
 /** Return true if the machine is 64 bits */
-bool SystemInformationImplementation::Is64Bits()
+bool SystemInformationImplementation::Is64Bits() const
 {
   return this->OSIs64Bit;
 }
diff --git a/Source/kwsys/SystemInformation.hxx.in b/Source/kwsys/SystemInformation.hxx.in
index fc42e9d..c8efd51 100644
--- a/Source/kwsys/SystemInformation.hxx.in
+++ b/Source/kwsys/SystemInformation.hxx.in
@@ -15,13 +15,6 @@
 
 class @KWSYS_NAMESPACE@_EXPORT SystemInformation
 {
-#if @KWSYS_USE_LONG_LONG@
-  typedef long long LongLong;
-#elif @KWSYS_USE___INT64@
-  typedef __int64 LongLong;
-#else
-#  error "No Long Long"
-#endif
   friend class SystemInformationImplementation;
   SystemInformationImplementation* Implementation;
 
@@ -104,7 +97,7 @@
   bool DoesCPUSupportCPUID();
 
   // Retrieve id of the current running process
-  LongLong GetProcessId();
+  long long GetProcessId();
 
   // Retrieve memory information in MiB.
   size_t GetTotalVirtualMemory();
@@ -120,7 +113,7 @@
 
   // Retrieve amount of physical memory installed on the system in KiB
   // units.
-  LongLong GetHostMemoryTotal();
+  long long GetHostMemoryTotal();
 
   // Get total system RAM in units of KiB available colectivley to all
   // processes in a process group. An example of a process group
@@ -128,7 +121,7 @@
   // parallel. The amount of memory reported may differ from the host
   // total if a host wide resource limit is applied. Such reource limits
   // are reported to us via an application specified environment variable.
-  LongLong GetHostMemoryAvailable(const char* hostLimitEnvVarName = nullptr);
+  long long GetHostMemoryAvailable(const char* hostLimitEnvVarName = nullptr);
 
   // Get total system RAM in units of KiB available to this process.
   // This may differ from the host available if a per-process resource
@@ -136,14 +129,14 @@
   // system via rlimit API. Resource limits that are not imposed via
   // rlimit API may be reported to us via an application specified
   // environment variable.
-  LongLong GetProcMemoryAvailable(const char* hostLimitEnvVarName = nullptr,
-                                  const char* procLimitEnvVarName = nullptr);
+  long long GetProcMemoryAvailable(const char* hostLimitEnvVarName = nullptr,
+                                   const char* procLimitEnvVarName = nullptr);
 
   // Get the system RAM used by all processes on the host, in units of KiB.
-  LongLong GetHostMemoryUsed();
+  long long GetHostMemoryUsed();
 
   // Get system RAM used by this process id in units of KiB.
-  LongLong GetProcMemoryUsed();
+  long long GetProcMemoryUsed();
 
   // Return the load average of the machine or -0.0 if it cannot
   // be determined.
diff --git a/Source/kwsys/SystemTools.cxx b/Source/kwsys/SystemTools.cxx
index d27081b..6144d9c 100644
--- a/Source/kwsys/SystemTools.cxx
+++ b/Source/kwsys/SystemTools.cxx
@@ -6,9 +6,7 @@
 #  define _XOPEN_SOURCE_EXTENDED
 #endif
 
-#if defined(_WIN32) &&                                                        \
-  (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__) ||      \
-   defined(__MINGW32__))
+#if defined(_WIN32) && (defined(_MSC_VER) || defined(__MINGW32__))
 #  define KWSYS_WINDOWS_DIRS
 #else
 #  if defined(__SUNPRO_CC)
@@ -24,6 +22,7 @@
 #include KWSYS_HEADER(Encoding.h)
 #include KWSYS_HEADER(Encoding.hxx)
 
+#include <algorithm>
 #include <fstream>
 #include <iostream>
 #include <set>
@@ -49,27 +48,27 @@
 #  pragma set woff 1375 /* base class destructor not virtual */
 #endif
 
-#include <ctype.h>
-#include <errno.h>
+#include <cctype>
+#include <cerrno>
 #ifdef __QNX__
 #  include <malloc.h> /* for malloc/free on QNX */
 #endif
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <time.h>
+#include <cstdio>
+#include <cstdlib>
+#include <cstring>
+#include <ctime>
 
 #if defined(_WIN32) && !defined(_MSC_VER) && defined(__GNUC__)
 #  include <strings.h> /* for strcasecmp */
 #endif
 
 #ifdef _MSC_VER
-#  define umask _umask // Note this is still umask on Borland
+#  define umask _umask
 #endif
 
 // support for realpath call
 #ifndef _WIN32
-#  include <limits.h>
+#  include <climits>
 #  include <pwd.h>
 #  include <sys/ioctl.h>
 #  include <sys/time.h>
@@ -80,7 +79,7 @@
 #    include <sys/param.h>
 #    include <termios.h>
 #  endif
-#  include <signal.h> /* sigprocmask */
+#  include <csignal> /* sigprocmask */
 #endif
 
 #ifdef __linux
@@ -97,19 +96,12 @@
 #  if defined(_MSC_VER) && _MSC_VER >= 1800
 #    define KWSYS_WINDOWS_DEPRECATED_GetVersionEx
 #  endif
-#elif defined(__CYGWIN__)
-#  include <windows.h>
-#  undef _WIN32
 #endif
 
 #if !KWSYS_CXX_HAS_ENVIRON_IN_STDLIB_H
 extern char** environ;
 #endif
 
-#ifdef __CYGWIN__
-#  include <sys/cygwin.h>
-#endif
-
 // getpwnam doesn't exist on Windows and Cray Xt3/Catamount
 // same for TIOCGWINSZ
 #if defined(_WIN32) || defined(__LIBCATAMOUNT__) ||                           \
@@ -123,9 +115,9 @@
 
 #define VTK_URL_PROTOCOL_REGEX "([a-zA-Z0-9]*)://(.*)"
 #define VTK_URL_REGEX                                                         \
-  "([a-zA-Z0-9]*)://(([A-Za-z0-9]+)(:([^:@]+))?@)?([^:@/]+)(:([0-9]+))?/"     \
+  "([a-zA-Z0-9]*)://(([A-Za-z0-9]+)(:([^:@]+))?@)?([^:@/]*)(:([0-9]+))?/"     \
   "(.+)?"
-
+#define VTK_URL_BYTE_REGEX "%[0-9a-fA-F][0-9a-fA-F]"
 #ifdef _MSC_VER
 #  include <sys/utime.h>
 #else
@@ -153,9 +145,7 @@
 }
 #endif
 
-#if defined(_WIN32) &&                                                        \
-  (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__) ||      \
-   defined(__MINGW32__))
+#if defined(_WIN32) && (defined(_MSC_VER) || defined(__MINGW32__))
 #  include <direct.h>
 #  include <io.h>
 #  define _unlink unlink
@@ -169,13 +159,6 @@
 #else
 #  define KWSYS_SYSTEMTOOLS_MAXPATH 16384
 #endif
-#if defined(__WATCOMC__)
-#  include <direct.h>
-#  define _mkdir mkdir
-#  define _rmdir rmdir
-#  define _getcwd getcwd
-#  define _chdir chdir
-#endif
 
 #if defined(__BEOS__) && !defined(__ZETA__)
 #  include <be/kernel/OS.h>
@@ -221,11 +204,17 @@
 
 #ifdef KWSYS_WINDOWS_DIRS
 #  include <wctype.h>
+#  ifdef _MSC_VER
+typedef KWSYS_NAMESPACE::SystemTools::mode_t mode_t;
+#  endif
 
-inline int Mkdir(const std::string& dir)
+inline int Mkdir(const std::string& dir, const mode_t* mode)
 {
-  return _wmkdir(
-    KWSYS_NAMESPACE::Encoding::ToWindowsExtendedPath(dir).c_str());
+  int ret =
+    _wmkdir(KWSYS_NAMESPACE::Encoding::ToWindowsExtendedPath(dir).c_str());
+  if (ret == 0 && mode)
+    KWSYS_NAMESPACE::SystemTools::SetPermissions(dir, *mode);
+  return ret;
 }
 inline int Rmdir(const std::string& dir)
 {
@@ -252,11 +241,7 @@
 }
 inline int Chdir(const std::string& dir)
 {
-#  if defined(__BORLANDC__)
-  return chdir(dir.c_str());
-#  else
   return _wchdir(KWSYS_NAMESPACE::Encoding::ToWide(dir).c_str());
-#  endif
 }
 inline void Realpath(const std::string& path, std::string& resolved_path,
                      std::string* errorMessage = 0)
@@ -295,9 +280,9 @@
 
 #  include <fcntl.h>
 #  include <unistd.h>
-inline int Mkdir(const std::string& dir)
+inline int Mkdir(const std::string& dir, const mode_t* mode)
 {
-  return mkdir(dir.c_str(), 00777);
+  return mkdir(dir.c_str(), mode ? *mode : 00777);
 }
 inline int Rmdir(const std::string& dir)
 {
@@ -350,7 +335,7 @@
 
 namespace KWSYS_NAMESPACE {
 
-double SystemTools::GetTime(void)
+double SystemTools::GetTime()
 {
 #if defined(_WIN32) && !defined(__CYGWIN__)
   FILETIME ft;
@@ -368,7 +353,7 @@
 #if defined(_WIN32)
 typedef wchar_t envchar;
 #else
-typedef char envchar;
+using envchar = char;
 #endif
 
 /* Order by environment key only (VAR from VAR=VALUE).  */
@@ -421,7 +406,7 @@
   const envchar* Release(const envchar* env)
   {
     const envchar* old = nullptr;
-    iterator i = this->find(env);
+    auto i = this->find(env);
     if (i != this->end()) {
       old = *i;
       this->erase(i);
@@ -452,7 +437,7 @@
 class SystemToolsStatic
 {
 public:
-  typedef std::map<std::string, std::string> StringMap;
+  using StringMap = std::map<std::string, std::string>;
 #if KWSYS_SYSTEMTOOLS_USE_TRANSLATION_MAP
   /**
    * Path translation table from dir to refdir
@@ -488,10 +473,13 @@
    */
   static std::string FindName(
     const std::string& name,
-    const std::vector<std::string>& path = std::vector<std::string>(),
+    const std::vector<std::string>& userPaths = std::vector<std::string>(),
     bool no_system_path = false);
 };
 
+// Do NOT initialize.  Default initialization to zero is necessary.
+static SystemToolsStatic* SystemToolsStatics;
+
 #ifdef _WIN32
 std::string SystemToolsStatic::GetCasePathName(std::string const& pathIn)
 {
@@ -566,7 +554,7 @@
 {
   // Check to see if actual case has already been called
   // for this path, and the result is stored in the PathCaseMap
-  auto& pcm = SystemTools::Statics->PathCaseMap;
+  auto& pcm = SystemToolsStatics->PathCaseMap;
   {
     auto itr = pcm.find(p);
     if (itr != pcm.end()) {
@@ -613,8 +601,7 @@
       done = true;
     }
   }
-  for (std::vector<std::string>::iterator i = path.begin() + old_size;
-       i != path.end(); ++i) {
+  for (auto i = path.begin() + old_size; i != path.end(); ++i) {
     SystemTools::ConvertToUnixSlashes(*i);
   }
 }
@@ -624,7 +611,7 @@
 {
   std::string env;
   if (SystemTools::GetEnv(key, env)) {
-    std::string& menv = SystemTools::Statics->EnvMap[key];
+    std::string& menv = SystemToolsStatics->EnvMap[key];
     if (menv != env) {
       menv = std::move(env);
     }
@@ -884,8 +871,12 @@
 FILE* SystemTools::Fopen(const std::string& file, const char* mode)
 {
 #ifdef _WIN32
+  // Remove any 'e', which is supported on UNIX, but not Windows.
+  std::wstring trimmedMode = Encoding::ToWide(mode);
+  trimmedMode.erase(std::remove(trimmedMode.begin(), trimmedMode.end(), L'e'),
+                    trimmedMode.end());
   return _wfopen(Encoding::ToWindowsExtendedPath(file).c_str(),
-                 Encoding::ToWide(mode).c_str());
+                 trimmedMode.c_str());
 #else
   return fopen(file.c_str(), mode);
 #endif
@@ -913,29 +904,22 @@
   std::string::size_type pos = 0;
   std::string topdir;
   while ((pos = dir.find('/', pos)) != std::string::npos) {
-    topdir = dir.substr(0, pos);
+    // all underlying functions use C strings, so temporarily
+    // end the string here
+    dir[pos] = '\0';
 
-    if (Mkdir(topdir) == 0 && mode != nullptr) {
-      SystemTools::SetPermissions(topdir, *mode);
-    }
+    Mkdir(dir, mode);
+    dir[pos] = '/';
 
     ++pos;
   }
   topdir = dir;
-  if (Mkdir(topdir) != 0) {
-    // There is a bug in the Borland Run time library which makes MKDIR
-    // return EACCES when it should return EEXISTS
+  if (Mkdir(topdir, mode) != 0) {
     // if it is some other error besides directory exists
     // then return false
-    if ((errno != EEXIST)
-#ifdef __BORLANDC__
-        && (errno != EACCES)
-#endif
-    ) {
+    if (errno != EEXIST) {
       return false;
     }
-  } else if (mode != nullptr) {
-    SystemTools::SetPermissions(topdir, *mode);
   }
 
   return true;
@@ -1011,38 +995,40 @@
 #    define KWSYS_ST_KEY_WOW64_64KEY 0x0100
 #  endif
 
-static bool SystemToolsParseRegistryKey(const std::string& key,
-                                        HKEY& primaryKey, std::string& second,
-                                        std::string& valuename)
+static bool hasPrefix(const std::string& s, const char* pattern,
+                      std::string::size_type spos)
 {
-  std::string primary = key;
+  size_t plen = strlen(pattern);
+  if (spos != plen)
+    return false;
+  return s.compare(0, plen, pattern) == 0;
+}
 
-  size_t start = primary.find('\\');
+static bool SystemToolsParseRegistryKey(const std::string& key,
+                                        HKEY& primaryKey, std::wstring& second,
+                                        std::string* valuename)
+{
+  size_t start = key.find('\\');
   if (start == std::string::npos) {
     return false;
   }
 
-  size_t valuenamepos = primary.find(';');
-  if (valuenamepos != std::string::npos) {
-    valuename = primary.substr(valuenamepos + 1);
+  size_t valuenamepos = key.find(';');
+  if (valuenamepos != std::string::npos && valuename) {
+    *valuename = key.substr(valuenamepos + 1);
   }
 
-  second = primary.substr(start + 1, valuenamepos - start - 1);
-  primary = primary.substr(0, start);
+  second = Encoding::ToWide(key.substr(start + 1, valuenamepos - start - 1));
 
-  if (primary == "HKEY_CURRENT_USER") {
+  if (hasPrefix(key, "HKEY_CURRENT_USER", start)) {
     primaryKey = HKEY_CURRENT_USER;
-  }
-  if (primary == "HKEY_CURRENT_CONFIG") {
+  } else if (hasPrefix(key, "HKEY_CURRENT_CONFIG", start)) {
     primaryKey = HKEY_CURRENT_CONFIG;
-  }
-  if (primary == "HKEY_CLASSES_ROOT") {
+  } else if (hasPrefix(key, "HKEY_CLASSES_ROOT", start)) {
     primaryKey = HKEY_CLASSES_ROOT;
-  }
-  if (primary == "HKEY_LOCAL_MACHINE") {
+  } else if (hasPrefix(key, "HKEY_LOCAL_MACHINE", start)) {
     primaryKey = HKEY_LOCAL_MACHINE;
-  }
-  if (primary == "HKEY_USERS") {
+  } else if (hasPrefix(key, "HKEY_USERS", start)) {
     primaryKey = HKEY_USERS;
   }
 
@@ -1074,14 +1060,13 @@
                                      KeyWOW64 view)
 {
   HKEY primaryKey = HKEY_CURRENT_USER;
-  std::string second;
-  std::string valuename;
-  if (!SystemToolsParseRegistryKey(key, primaryKey, second, valuename)) {
+  std::wstring second;
+  if (!SystemToolsParseRegistryKey(key, primaryKey, second, nullptr)) {
     return false;
   }
 
   HKEY hKey;
-  if (RegOpenKeyExW(primaryKey, Encoding::ToWide(second).c_str(), 0,
+  if (RegOpenKeyExW(primaryKey, second.c_str(), 0,
                     SystemToolsMakeRegistryMode(KEY_READ, view),
                     &hKey) != ERROR_SUCCESS) {
     return false;
@@ -1121,14 +1106,14 @@
 {
   bool valueset = false;
   HKEY primaryKey = HKEY_CURRENT_USER;
-  std::string second;
+  std::wstring second;
   std::string valuename;
-  if (!SystemToolsParseRegistryKey(key, primaryKey, second, valuename)) {
+  if (!SystemToolsParseRegistryKey(key, primaryKey, second, &valuename)) {
     return false;
   }
 
   HKEY hKey;
-  if (RegOpenKeyExW(primaryKey, Encoding::ToWide(second).c_str(), 0,
+  if (RegOpenKeyExW(primaryKey, second.c_str(), 0,
                     SystemToolsMakeRegistryMode(KEY_READ, view),
                     &hKey) != ERROR_SUCCESS) {
     return false;
@@ -1175,16 +1160,16 @@
                                      const std::string& value, KeyWOW64 view)
 {
   HKEY primaryKey = HKEY_CURRENT_USER;
-  std::string second;
+  std::wstring second;
   std::string valuename;
-  if (!SystemToolsParseRegistryKey(key, primaryKey, second, valuename)) {
+  if (!SystemToolsParseRegistryKey(key, primaryKey, second, &valuename)) {
     return false;
   }
 
   HKEY hKey;
   DWORD dwDummy;
   wchar_t lpClass[] = L"";
-  if (RegCreateKeyExW(primaryKey, Encoding::ToWide(second).c_str(), 0, lpClass,
+  if (RegCreateKeyExW(primaryKey, second.c_str(), 0, lpClass,
                       REG_OPTION_NON_VOLATILE,
                       SystemToolsMakeRegistryMode(KEY_WRITE, view), nullptr,
                       &hKey, &dwDummy) != ERROR_SUCCESS) {
@@ -1219,14 +1204,14 @@
 bool SystemTools::DeleteRegistryValue(const std::string& key, KeyWOW64 view)
 {
   HKEY primaryKey = HKEY_CURRENT_USER;
-  std::string second;
+  std::wstring second;
   std::string valuename;
-  if (!SystemToolsParseRegistryKey(key, primaryKey, second, valuename)) {
+  if (!SystemToolsParseRegistryKey(key, primaryKey, second, &valuename)) {
     return false;
   }
 
   HKEY hKey;
-  if (RegOpenKeyExW(primaryKey, Encoding::ToWide(second).c_str(), 0,
+  if (RegOpenKeyExW(primaryKey, second.c_str(), 0,
                     SystemToolsMakeRegistryMode(KEY_WRITE, view),
                     &hKey) != ERROR_SUCCESS) {
     return false;
@@ -1298,15 +1283,7 @@
   if (path.empty()) {
     return false;
   }
-#if defined(__CYGWIN__)
-  // Convert path to native windows path if possible.
-  char winpath[MAX_PATH];
-  if (SystemTools::PathCygwinToWin32(path.c_str(), winpath)) {
-    return (GetFileAttributesA(winpath) != INVALID_FILE_ATTRIBUTES);
-  }
-  struct stat st;
-  return lstat(path.c_str(), &st) == 0;
-#elif defined(_WIN32)
+#if defined(_WIN32)
   return (GetFileAttributesW(Encoding::ToWindowsExtendedPath(path).c_str()) !=
           INVALID_FILE_ATTRIBUTES);
 #else
@@ -1328,14 +1305,7 @@
   if (filename.empty()) {
     return false;
   }
-#if defined(__CYGWIN__)
-  // Convert filename to native windows path if possible.
-  char winpath[MAX_PATH];
-  if (SystemTools::PathCygwinToWin32(filename.c_str(), winpath)) {
-    return (GetFileAttributesA(winpath) != INVALID_FILE_ATTRIBUTES);
-  }
-  return access(filename.c_str(), R_OK) == 0;
-#elif defined(_WIN32)
+#if defined(_WIN32)
   DWORD attr =
     GetFileAttributesW(Encoding::ToWindowsExtendedPath(filename).c_str());
   if (attr == INVALID_FILE_ATTRIBUTES) {
@@ -1435,37 +1405,15 @@
   // long paths, but _wstat64 rejects paths with '?' in them, thinking
   // they are wildcards.
   std::wstring const& wpath = Encoding::ToWide(path);
-#  if defined(__BORLANDC__)
-  return _wstati64(wpath.c_str(), buf);
-#  else
   return _wstat64(wpath.c_str(), buf);
-#  endif
 #else
   return stat(path.c_str(), buf);
 #endif
 }
 
-#ifdef __CYGWIN__
-bool SystemTools::PathCygwinToWin32(const char* path, char* win32_path)
-{
-  auto itr = SystemTools::Statics->Cyg2Win32Map.find(path);
-  if (itr != SystemTools::Statics->Cyg2Win32Map.end()) {
-    strncpy(win32_path, itr->second.c_str(), MAX_PATH);
-  } else {
-    if (cygwin_conv_path(CCP_POSIX_TO_WIN_A, path, win32_path, MAX_PATH) !=
-        0) {
-      win32_path[0] = 0;
-    }
-    SystemTools::Statics->Cyg2Win32Map.insert(
-      SystemToolsStatic::StringMap::value_type(path, win32_path));
-  }
-  return win32_path[0] != 0;
-}
-#endif
-
 bool SystemTools::Touch(const std::string& filename, bool create)
 {
-  if (!SystemTools::PathExists(filename)) {
+  if (!SystemTools::FileExists(filename)) {
     if (create) {
       FILE* file = Fopen(filename, "a+b");
       if (file) {
@@ -1858,7 +1806,7 @@
 // Return a cropped string
 std::string SystemTools::CropString(const std::string& s, size_t max_len)
 {
-  if (!s.size() || max_len == 0 || max_len >= s.size()) {
+  if (s.empty() || max_len == 0 || max_len >= s.size()) {
     return s;
   }
 
@@ -1867,7 +1815,7 @@
 
   size_t middle = max_len / 2;
 
-  n += s.substr(0, middle);
+  n.assign(s, 0, middle);
   n += s.substr(s.size() - (max_len - middle));
 
   if (max_len > 2) {
@@ -1893,10 +1841,10 @@
   }
   if (isPath && path[0] == '/') {
     path.erase(path.begin());
-    paths.push_back("/");
+    paths.emplace_back("/");
   }
   std::string::size_type pos1 = 0;
-  std::string::size_type pos2 = path.find(sep, pos1 + 1);
+  std::string::size_type pos2 = path.find(sep, pos1);
   while (pos2 != std::string::npos) {
     paths.push_back(path.substr(pos1, pos2 - pos1));
     pos1 = pos2 + 1;
@@ -2065,8 +2013,10 @@
 #ifdef HAVE_GETPWNAM
   else if (pathCString[0] == '~') {
     std::string::size_type idx = path.find_first_of("/\0");
-    std::string user = path.substr(1, idx - 1);
-    passwd* pw = getpwnam(user.c_str());
+    char oldch = path[idx];
+    path[idx] = '\0';
+    passwd* pw = getpwnam(path.c_str() + 1);
+    path[idx] = oldch;
     if (pw) {
       path.replace(0, idx, pw->pw_dir);
     }
@@ -2103,7 +2053,7 @@
     ret.erase(pos, 1);
   }
   // escape spaces and () in the path
-  if (ret.find_first_of(" ") != std::string::npos) {
+  if (ret.find_first_of(' ') != std::string::npos) {
     std::string result;
     char lastch = 1;
     for (const char* ch = ret.c_str(); *ch != '\0'; ++ch) {
@@ -2501,8 +2451,8 @@
     return false;
   }
   for (fileNum = 0; fileNum < dir.GetNumberOfFiles(); ++fileNum) {
-    if (strcmp(dir.GetFile(static_cast<unsigned long>(fileNum)), ".") &&
-        strcmp(dir.GetFile(static_cast<unsigned long>(fileNum)), "..")) {
+    if (strcmp(dir.GetFile(static_cast<unsigned long>(fileNum)), ".") != 0 &&
+        strcmp(dir.GetFile(static_cast<unsigned long>(fileNum)), "..") != 0) {
       std::string fullPath = source;
       fullPath += "/";
       fullPath += dir.GetFile(static_cast<unsigned long>(fileNum));
@@ -2664,8 +2614,8 @@
   dir.Load(source);
   size_t fileNum;
   for (fileNum = 0; fileNum < dir.GetNumberOfFiles(); ++fileNum) {
-    if (strcmp(dir.GetFile(static_cast<unsigned long>(fileNum)), ".") &&
-        strcmp(dir.GetFile(static_cast<unsigned long>(fileNum)), "..")) {
+    if (strcmp(dir.GetFile(static_cast<unsigned long>(fileNum)), ".") != 0 &&
+        strcmp(dir.GetFile(static_cast<unsigned long>(fileNum)), "..") != 0) {
       std::string fullPath = source;
       fullPath += "/";
       fullPath += dir.GetFile(static_cast<unsigned long>(fileNum));
@@ -2797,7 +2747,7 @@
     for (std::string const& ext : extensions) {
       tryPath = name;
       tryPath += ext;
-      if (SystemTools::FileExists(tryPath, true)) {
+      if (SystemTools::FileIsExecutable(tryPath)) {
         return SystemTools::CollapseFullPath(tryPath);
       }
     }
@@ -2805,7 +2755,7 @@
 #endif
 
   // now try just the name
-  if (SystemTools::FileExists(name, true)) {
+  if (SystemTools::FileIsExecutable(name)) {
     return SystemTools::CollapseFullPath(name);
   }
   // now construct the path
@@ -2835,7 +2785,7 @@
       tryPath = p;
       tryPath += name;
       tryPath += ext;
-      if (SystemTools::FileExists(tryPath, true)) {
+      if (SystemTools::FileIsExecutable(tryPath)) {
         return SystemTools::CollapseFullPath(tryPath);
       }
     }
@@ -2843,7 +2793,7 @@
     // now try it without them
     tryPath = p;
     tryPath += name;
-    if (SystemTools::FileExists(tryPath, true)) {
+    if (SystemTools::FileIsExecutable(tryPath)) {
       return SystemTools::CollapseFullPath(tryPath);
     }
   }
@@ -2998,6 +2948,15 @@
   }
 }
 
+bool SystemTools::FileIsExecutable(const std::string& name)
+{
+#if defined(_WIN32)
+  return SystemTools::FileExists(name, true);
+#else
+  return !FileIsDirectory(name) && TestFileAccess(name, TEST_FILE_EXECUTE);
+#endif
+}
+
 bool SystemTools::FileIsSymlink(const std::string& name)
 {
 #if defined(_WIN32)
@@ -3107,16 +3066,14 @@
   return Chdir(dir);
 }
 
-std::string SystemTools::GetCurrentWorkingDirectory(bool collapse)
+std::string SystemTools::GetCurrentWorkingDirectory()
 {
   char buf[2048];
   const char* cwd = Getcwd(buf, 2048);
   std::string path;
   if (cwd) {
     path = cwd;
-  }
-  if (collapse) {
-    return SystemTools::CollapseFullPath(path);
+    SystemTools::ConvertToUnixSlashes(path);
   }
   return path;
 }
@@ -3132,17 +3089,17 @@
                                    std::string& dir, std::string& file, bool)
 {
   dir = in_name;
-  file = "";
+  file.clear();
   SystemTools::ConvertToUnixSlashes(dir);
 
   if (!SystemTools::FileIsDirectory(dir)) {
-    std::string::size_type slashPos = dir.rfind("/");
+    std::string::size_type slashPos = dir.rfind('/');
     if (slashPos != std::string::npos) {
       file = dir.substr(slashPos + 1);
-      dir = dir.substr(0, slashPos);
+      dir.resize(slashPos);
     } else {
       file = dir;
-      dir = "";
+      dir.clear();
     }
   }
   if (!(dir.empty()) && !SystemTools::FileIsDirectory(dir)) {
@@ -3164,7 +3121,7 @@
   failures.push_back(self);
   SystemTools::ConvertToUnixSlashes(self);
   self = SystemTools::FindProgram(self);
-  if (!SystemTools::FileExists(self)) {
+  if (!SystemTools::FileIsExecutable(self)) {
     if (buildDir) {
       std::string intdir = ".";
 #ifdef CMAKE_INTDIR
@@ -3179,14 +3136,14 @@
     }
   }
   if (installPrefix) {
-    if (!SystemTools::FileExists(self)) {
+    if (!SystemTools::FileIsExecutable(self)) {
       failures.push_back(self);
       self = installPrefix;
       self += "/bin/";
       self += exeName;
     }
   }
-  if (!SystemTools::FileExists(self)) {
+  if (!SystemTools::FileIsExecutable(self)) {
     failures.push_back(self);
     std::ostringstream msg;
     msg << "Can not find the command line program ";
@@ -3208,11 +3165,6 @@
   return true;
 }
 
-std::string SystemTools::CollapseFullPath(const std::string& in_relative)
-{
-  return SystemTools::CollapseFullPath(in_relative, nullptr);
-}
-
 #if KWSYS_SYSTEMTOOLS_USE_TRANSLATION_MAP
 void SystemTools::AddTranslationPath(const std::string& a,
                                      const std::string& b)
@@ -3237,7 +3189,7 @@
         path_b += '/';
       }
       if (!(path_a == path_b)) {
-        SystemTools::Statics->TranslationMap.insert(
+        SystemToolsStatics->TranslationMap.insert(
           SystemToolsStatic::StringMap::value_type(std::move(path_a),
                                                    std::move(path_b)));
       }
@@ -3267,9 +3219,9 @@
 
   // In case a file was specified we still have to go through this:
   // Now convert any path found in the table back to the one desired:
-  for (auto const& pair : SystemTools::Statics->TranslationMap) {
+  for (auto const& pair : SystemToolsStatics->TranslationMap) {
     // We need to check of the path is a substring of the other path
-    if (path.find(pair.first) == 0) {
+    if (path.compare(0, pair.first.size(), pair.first) == 0) {
       path = path.replace(0, pair.first.size(), pair.second);
     }
   }
@@ -3302,25 +3254,10 @@
   }
 }
 
-std::string SystemTools::CollapseFullPath(const std::string& in_path,
-                                          const char* in_base)
-{
-  // Use the current working directory as a base path.
-  char buf[2048];
-  const char* res_in_base = in_base;
-  if (!res_in_base) {
-    if (const char* cwd = Getcwd(buf, 2048)) {
-      res_in_base = cwd;
-    } else {
-      res_in_base = "";
-    }
-  }
+namespace {
 
-  return SystemTools::CollapseFullPath(in_path, std::string(res_in_base));
-}
-
-std::string SystemTools::CollapseFullPath(const std::string& in_path,
-                                          const std::string& in_base)
+std::string CollapseFullPathImpl(std::string const& in_path,
+                                 std::string const* in_base)
 {
   // Collect the output path components.
   std::vector<std::string> out_components;
@@ -3333,8 +3270,15 @@
   // If the input path is relative, start with a base path.
   if (path_components[0].empty()) {
     std::vector<std::string> base_components;
-    // Use the given base path.
-    SystemTools::SplitPath(in_base, base_components);
+
+    if (in_base) {
+      // Use the given base path.
+      SystemTools::SplitPath(*in_base, base_components);
+    } else {
+      // Use the current working directory as a base path.
+      std::string cwd = SystemTools::GetCurrentWorkingDirectory();
+      SystemTools::SplitPath(cwd, base_components);
+    }
 
     // Append base path components to the output path.
     out_components.push_back(base_components[0]);
@@ -3367,12 +3311,34 @@
   SystemTools::CheckTranslationPath(newPath);
 #endif
 #ifdef _WIN32
-  newPath = SystemTools::Statics->GetActualCaseForPathCached(newPath);
+  newPath = SystemToolsStatics->GetActualCaseForPathCached(newPath);
   SystemTools::ConvertToUnixSlashes(newPath);
 #endif
   // Return the reconstructed path.
   return newPath;
 }
+}
+
+std::string SystemTools::CollapseFullPath(std::string const& in_path)
+{
+  return CollapseFullPathImpl(in_path, nullptr);
+}
+
+std::string SystemTools::CollapseFullPath(std::string const& in_path,
+                                          const char* in_base)
+{
+  if (!in_base) {
+    return CollapseFullPathImpl(in_path, nullptr);
+  }
+  std::string tmp_base = in_base;
+  return CollapseFullPathImpl(in_path, &tmp_base);
+}
+
+std::string SystemTools::CollapseFullPath(std::string const& in_path,
+                                          std::string const& in_base)
+{
+  return CollapseFullPathImpl(in_path, &in_base);
+}
 
 // compute the relative path from here to there
 std::string SystemTools::RelativePath(const std::string& local,
@@ -3541,7 +3507,7 @@
     // Expand home directory references if requested.
     if (expand_home_dir && !root.empty() && root[0] == '~') {
       std::string homedir;
-      root = root.substr(0, root.size() - 1);
+      root.resize(root.size() - 1);
       if (root.size() == 1) {
 #if defined(_WIN32) && !defined(__CYGWIN__)
         if (!SystemTools::GetEnv("USERPROFILE", homedir))
@@ -3571,14 +3537,14 @@
   for (; *last; ++last) {
     if (*last == '/' || *last == '\\') {
       // End of a component.  Save it.
-      components.push_back(std::string(first, last));
+      components.emplace_back(first, last);
       first = last + 1;
     }
   }
 
   // Save the last component unless there were no components.
   if (last != c) {
-    components.push_back(std::string(first, last));
+    components.emplace_back(first, last);
   }
 }
 
@@ -3594,7 +3560,7 @@
   // Construct result in a single string.
   std::string result;
   size_t len = 0;
-  for (std::vector<std::string>::const_iterator i = first; i != last; ++i) {
+  for (auto i = first; i != last; ++i) {
     len += 1 + i->size();
   }
   result.reserve(len);
@@ -3685,19 +3651,20 @@
   std::string fn = filename;
   SystemTools::ConvertToUnixSlashes(fn);
 
-  std::string::size_type slash_pos = fn.rfind("/");
-  if (slash_pos != std::string::npos) {
-    std::string ret = fn.substr(0, slash_pos);
-    if (ret.size() == 2 && ret[1] == ':') {
-      return ret + '/';
-    }
-    if (ret.empty()) {
-      return "/";
-    }
-    return ret;
-  } else {
+  std::string::size_type slash_pos = fn.rfind('/');
+  if (slash_pos == 0) {
+    return "/";
+  }
+  if (slash_pos == 2 && fn[1] == ':') {
+    // keep the / after a drive letter
+    fn.resize(3);
+    return fn;
+  }
+  if (slash_pos == std::string::npos) {
     return "";
   }
+  fn.resize(slash_pos);
+  return fn;
 }
 
 /**
@@ -3727,7 +3694,8 @@
   std::string name = SystemTools::GetFilenameName(filename);
   std::string::size_type dot_pos = name.find('.');
   if (dot_pos != std::string::npos) {
-    return name.substr(dot_pos);
+    name.erase(0, dot_pos);
+    return name;
   } else {
     return "";
   }
@@ -3742,7 +3710,8 @@
   std::string name = SystemTools::GetFilenameName(filename);
   std::string::size_type dot_pos = name.rfind('.');
   if (dot_pos != std::string::npos) {
-    return name.substr(dot_pos);
+    name.erase(0, dot_pos);
+    return name;
   } else {
     return "";
   }
@@ -3758,10 +3727,9 @@
   std::string name = SystemTools::GetFilenameName(filename);
   std::string::size_type dot_pos = name.find('.');
   if (dot_pos != std::string::npos) {
-    return name.substr(0, dot_pos);
-  } else {
-    return name;
+    name.resize(dot_pos);
   }
+  return name;
 }
 
 /**
@@ -3775,10 +3743,9 @@
   std::string name = SystemTools::GetFilenameName(filename);
   std::string::size_type dot_pos = name.rfind('.');
   if (dot_pos != std::string::npos) {
-    return name.substr(0, dot_pos);
-  } else {
-    return name;
+    name.resize(dot_pos);
   }
+  return name;
 }
 
 bool SystemTools::FileHasSignature(const char* filename, const char* signature,
@@ -3828,7 +3795,7 @@
 
   // Allocate buffer and read bytes
 
-  unsigned char* buffer = new unsigned char[length];
+  auto* buffer = new unsigned char[length];
   size_t read_length = fread(buffer, 1, length, fp);
   fclose(fp);
   if (read_length == 0) {
@@ -4000,7 +3967,8 @@
 
   // if the path passed in has quotes around it, first remove the quotes
   if (!path.empty() && path[0] == '"' && path.back() == '"') {
-    tempPath = path.substr(1, path.length() - 2);
+    tempPath.resize(path.length() - 1);
+    tempPath.erase(0, 1);
   }
 
   std::wstring wtempPath = Encoding::ToWide(tempPath);
@@ -4219,8 +4187,8 @@
   if (subdir[expectedSlashPosition] != '/') {
     return false;
   }
-  std::string s = subdir.substr(0, dir.size());
-  return SystemTools::ComparePath(s, dir);
+  subdir.resize(dir.size());
+  return SystemTools::ComparePath(subdir, dir);
 }
 
 void SystemTools::Delay(unsigned int msec)
@@ -4516,7 +4484,7 @@
 
 bool SystemTools::ParseURLProtocol(const std::string& URL,
                                    std::string& protocol,
-                                   std::string& dataglom)
+                                   std::string& dataglom, bool decode)
 {
   // match 0 entire url
   // match 1 protocol
@@ -4529,13 +4497,17 @@
   protocol = urlRe.match(1);
   dataglom = urlRe.match(2);
 
+  if (decode) {
+    dataglom = DecodeURL(dataglom);
+  }
+
   return true;
 }
 
 bool SystemTools::ParseURL(const std::string& URL, std::string& protocol,
                            std::string& username, std::string& password,
                            std::string& hostname, std::string& dataport,
-                           std::string& database)
+                           std::string& database, bool decode)
 {
   kwsys::RegularExpression urlRe(VTK_URL_REGEX);
   if (!urlRe.find(URL))
@@ -4559,13 +4531,37 @@
   dataport = urlRe.match(8);
   database = urlRe.match(9);
 
+  if (decode) {
+    username = DecodeURL(username);
+    password = DecodeURL(password);
+    hostname = DecodeURL(hostname);
+    dataport = DecodeURL(dataport);
+    database = DecodeURL(database);
+  }
+
   return true;
 }
 
-// These must NOT be initialized.  Default initialization to zero is
-// necessary.
+// ----------------------------------------------------------------------
+std::string SystemTools::DecodeURL(const std::string& url)
+{
+  kwsys::RegularExpression urlByteRe(VTK_URL_BYTE_REGEX);
+  std::string ret;
+  for (size_t i = 0; i < url.length(); i++) {
+    if (urlByteRe.find(url.substr(i, 3))) {
+      char bytes[] = { url[i + 1], url[i + 2], '\0' };
+      ret += static_cast<char>(strtoul(bytes, nullptr, 16));
+      i += 2;
+    } else {
+      ret += url[i];
+    }
+  }
+  return ret;
+}
+
+// ----------------------------------------------------------------------
+// Do NOT initialize.  Default initialization to zero is necessary.
 static unsigned int SystemToolsManagerCount;
-SystemToolsStatic* SystemTools::Statics;
 
 // SystemToolsManager manages the SystemTools singleton.
 // SystemToolsManager should be included in any translation unit
@@ -4608,7 +4604,7 @@
 #endif
 
   // Create statics singleton instance
-  SystemTools::Statics = new SystemToolsStatic;
+  SystemToolsStatics = new SystemToolsStatic;
 
 #if KWSYS_SYSTEMTOOLS_USE_TRANSLATION_MAP
 // Add some special translation paths for unix.  These are not added
@@ -4658,7 +4654,7 @@
 
 void SystemTools::ClassFinalize()
 {
-  delete SystemTools::Statics;
+  delete SystemToolsStatics;
 }
 
 } // namespace KWSYS_NAMESPACE
diff --git a/Source/kwsys/SystemTools.hxx.in b/Source/kwsys/SystemTools.hxx.in
index c4ab9d4..74dc176 100644
--- a/Source/kwsys/SystemTools.hxx.in
+++ b/Source/kwsys/SystemTools.hxx.in
@@ -67,7 +67,7 @@
 // combined using the | operator.
 typedef int TestFilePermissions;
 #if defined(_WIN32) && !defined(__CYGWIN__)
-// On Windows (VC and Borland), no system header defines these constants...
+// On Windows (VC), no system header defines these constants...
 static const TestFilePermissions TEST_FILE_OK = 0;
 static const TestFilePermissions TEST_FILE_READ = 4;
 static const TestFilePermissions TEST_FILE_WRITE = 2;
@@ -317,11 +317,7 @@
  * Cross platform wrapper for stat struct
  */
 #if defined(_WIN32) && !defined(__CYGWIN__)
-#  if defined(__BORLANDC__)
-  typedef struct stati64 Stat_t;
-#  else
   typedef struct _stat64 Stat_t;
-#  endif
 #else
   typedef struct stat Stat_t;
 #endif
@@ -335,15 +331,6 @@
   static int Stat(const char* path, Stat_t* buf);
   static int Stat(const std::string& path, Stat_t* buf);
 
-/**
- * Converts Cygwin path to Win32 path. Uses dictionary container for
- * caching and calls to cygwin_conv_to_win32_path from Cygwin dll
- * for actual translation.  Returns true on success, else false.
- */
-#ifdef __CYGWIN__
-  static bool PathCygwinToWin32(const char* path, char* win32_path);
-#endif
-
   /**
    * Return file length
    */
@@ -411,11 +398,11 @@
    * (which defaults to the current working directory).  The full path
    * is returned.
    */
-  static std::string CollapseFullPath(const std::string& in_relative);
-  static std::string CollapseFullPath(const std::string& in_relative,
+  static std::string CollapseFullPath(std::string const& in_path);
+  static std::string CollapseFullPath(std::string const& in_path,
                                       const char* in_base);
-  static std::string CollapseFullPath(const std::string& in_relative,
-                                      const std::string& in_base);
+  static std::string CollapseFullPath(std::string const& in_path,
+                                      std::string const& in_base);
 
   /**
    * Get the real path for a given path, removing all symlinks.  In
@@ -549,12 +536,13 @@
    */
 
   /**
-   * Open a file considering unicode.
+   * Open a file considering unicode. On Windows, if 'e' is present in
+   * mode it is first discarded.
    */
   static FILE* Fopen(const std::string& file, const char* mode);
 
 /**
- * Visual C++ does not define mode_t (note that Borland does, however).
+ * Visual C++ does not define mode_t.
  */
 #if defined(_MSC_VER)
   typedef unsigned short mode_t;
@@ -677,6 +665,11 @@
   static bool FileIsDirectory(const std::string& name);
 
   /**
+   * Return true if the file is an executable
+   */
+  static bool FileIsExecutable(const std::string& name);
+
+  /**
    * Return true if the file is a symlink
    */
   static bool FileIsSymlink(const std::string& name);
@@ -869,7 +862,7 @@
   /**
    * Get current working directory CWD
    */
-  static std::string GetCurrentWorkingDirectory(bool collapse = true);
+  static std::string GetCurrentWorkingDirectory();
 
   /**
    * Change directory to the directory specified
@@ -935,22 +928,32 @@
    * Parse a character string :
    *       protocol://dataglom
    * and fill protocol as appropriate.
+   * decode the dataglom using DecodeURL if set to true.
    * Return false if the URL does not have the required form, true otherwise.
    */
   static bool ParseURLProtocol(const std::string& URL, std::string& protocol,
-                               std::string& dataglom);
+                               std::string& dataglom, bool decode = false);
 
   /**
    * Parse a string (a URL without protocol prefix) with the form:
    *  protocol://[[username[':'password]'@']hostname[':'dataport]]'/'[datapath]
    * and fill protocol, username, password, hostname, dataport, and datapath
    * when values are found.
+   * decode all string except the protocol using DecodeUrl if set to true.
    * Return true if the string matches the format; false otherwise.
    */
   static bool ParseURL(const std::string& URL, std::string& protocol,
                        std::string& username, std::string& password,
                        std::string& hostname, std::string& dataport,
-                       std::string& datapath);
+                       std::string& datapath, bool decode = false);
+
+  /**
+   * Decode the percent-encoded string from an URL or an URI
+   * into their correct char values.
+   * Does not perform any other sort of validation.
+   * Return the decoded string
+   */
+  static std::string DecodeURL(const std::string& url);
 
 private:
   /**
@@ -971,7 +974,6 @@
     return &SystemToolsManagerInstance;
   }
 
-  static SystemToolsStatic* Statics;
   friend class SystemToolsStatic;
   friend class SystemToolsManager;
 };
diff --git a/Source/kwsys/hash_fun.hxx.in b/Source/kwsys/hash_fun.hxx.in
deleted file mode 100644
index 8626c2a..0000000
--- a/Source/kwsys/hash_fun.hxx.in
+++ /dev/null
@@ -1,166 +0,0 @@
-/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
-   file Copyright.txt or https://cmake.org/licensing#kwsys for details.  */
-/*
- * Copyright (c) 1996
- * Silicon Graphics Computer Systems, Inc.
- *
- * Permission to use, copy, modify, distribute and sell this software
- * and its documentation for any purpose is hereby granted without fee,
- * provided that the above copyright notice appear in all copies and
- * that both that copyright notice and this permission notice appear
- * in supporting documentation.  Silicon Graphics makes no
- * representations about the suitability of this software for any
- * purpose.  It is provided "as is" without express or implied warranty.
- *
- *
- * Copyright (c) 1994
- * Hewlett-Packard Company
- *
- * Permission to use, copy, modify, distribute and sell this software
- * and its documentation for any purpose is hereby granted without fee,
- * provided that the above copyright notice appear in all copies and
- * that both that copyright notice and this permission notice appear
- * in supporting documentation.  Hewlett-Packard Company makes no
- * representations about the suitability of this software for any
- * purpose.  It is provided "as is" without express or implied warranty.
- *
- */
-#ifndef @KWSYS_NAMESPACE@_hash_fun_hxx
-#define @KWSYS_NAMESPACE@_hash_fun_hxx
-
-#include <@KWSYS_NAMESPACE@/Configure.hxx>
-
-#include <stddef.h> // size_t
-#include <string>
-
-namespace @KWSYS_NAMESPACE@ {
-
-template <class _Key>
-struct hash
-{
-};
-
-inline size_t _stl_hash_string(const char* __s)
-{
-  unsigned long __h = 0;
-  for (; *__s; ++__s)
-    __h = 5 * __h + *__s;
-
-  return size_t(__h);
-}
-
-template <>
-struct hash<char*>
-{
-  size_t operator()(const char* __s) const { return _stl_hash_string(__s); }
-};
-
-template <>
-struct hash<const char*>
-{
-  size_t operator()(const char* __s) const { return _stl_hash_string(__s); }
-};
-
-template <>
-struct hash<std::string>
-{
-  size_t operator()(const std::string& __s) const
-  {
-    return _stl_hash_string(__s.c_str());
-  }
-};
-
-#if !defined(__BORLANDC__)
-template <>
-struct hash<const std::string>
-{
-  size_t operator()(const std::string& __s) const
-  {
-    return _stl_hash_string(__s.c_str());
-  }
-};
-#endif
-
-template <>
-struct hash<char>
-{
-  size_t operator()(char __x) const { return __x; }
-};
-
-template <>
-struct hash<unsigned char>
-{
-  size_t operator()(unsigned char __x) const { return __x; }
-};
-
-template <>
-struct hash<signed char>
-{
-  size_t operator()(unsigned char __x) const { return __x; }
-};
-
-template <>
-struct hash<short>
-{
-  size_t operator()(short __x) const { return __x; }
-};
-
-template <>
-struct hash<unsigned short>
-{
-  size_t operator()(unsigned short __x) const { return __x; }
-};
-
-template <>
-struct hash<int>
-{
-  size_t operator()(int __x) const { return __x; }
-};
-
-template <>
-struct hash<unsigned int>
-{
-  size_t operator()(unsigned int __x) const { return __x; }
-};
-
-template <>
-struct hash<long>
-{
-  size_t operator()(long __x) const { return __x; }
-};
-
-template <>
-struct hash<unsigned long>
-{
-  size_t operator()(unsigned long __x) const { return __x; }
-};
-
-// use long long or __int64
-#if @KWSYS_USE_LONG_LONG@
-template <>
-struct hash<long long>
-{
-  size_t operator()(long long __x) const { return __x; }
-};
-
-template <>
-struct hash<unsigned long long>
-{
-  size_t operator()(unsigned long long __x) const { return __x; }
-};
-#elif @KWSYS_USE___INT64@
-template <>
-struct hash<__int64>
-{
-  size_t operator()(__int64 __x) const { return __x; }
-};
-template <>
-struct hash<unsigned __int64>
-{
-  size_t operator()(unsigned __int64 __x) const { return __x; }
-};
-#endif // use long long or __int64
-
-} // namespace @KWSYS_NAMESPACE@
-
-#endif
diff --git a/Source/kwsys/hash_map.hxx.in b/Source/kwsys/hash_map.hxx.in
deleted file mode 100644
index 5f04e9c..0000000
--- a/Source/kwsys/hash_map.hxx.in
+++ /dev/null
@@ -1,423 +0,0 @@
-/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
-   file Copyright.txt or https://cmake.org/licensing#kwsys for details.  */
-/*
- * Copyright (c) 1996
- * Silicon Graphics Computer Systems, Inc.
- *
- * Permission to use, copy, modify, distribute and sell this software
- * and its documentation for any purpose is hereby granted without fee,
- * provided that the above copyright notice appear in all copies and
- * that both that copyright notice and this permission notice appear
- * in supporting documentation.  Silicon Graphics makes no
- * representations about the suitability of this software for any
- * purpose.  It is provided "as is" without express or implied warranty.
- *
- *
- * Copyright (c) 1994
- * Hewlett-Packard Company
- *
- * Permission to use, copy, modify, distribute and sell this software
- * and its documentation for any purpose is hereby granted without fee,
- * provided that the above copyright notice appear in all copies and
- * that both that copyright notice and this permission notice appear
- * in supporting documentation.  Hewlett-Packard Company makes no
- * representations about the suitability of this software for any
- * purpose.  It is provided "as is" without express or implied warranty.
- *
- */
-#ifndef @KWSYS_NAMESPACE@_hash_map_hxx
-#define @KWSYS_NAMESPACE@_hash_map_hxx
-
-#include <@KWSYS_NAMESPACE@/hashtable.hxx>
-
-#include <@KWSYS_NAMESPACE@/hash_fun.hxx>
-
-#include <functional> // equal_to
-
-#if defined(_MSC_VER)
-#  pragma warning(push)
-#  pragma warning(disable : 4284)
-#  pragma warning(disable : 4786)
-#endif
-
-#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32)
-#  pragma set woff 1174
-#  pragma set woff 1375
-#endif
-
-namespace @KWSYS_NAMESPACE@ {
-
-// select1st is an extension: it is not part of the standard.
-template <class T1, class T2>
-struct hash_select1st
-{
-  const T1& operator()(const std::pair<T1, T2>& __x) const
-  {
-    return __x.first;
-  }
-};
-
-// Forward declaration of equality operator; needed for friend declaration.
-
-template <class _Key, class _Tp, class _HashFcn = hash<_Key>,
-          class _EqualKey = std::equal_to<_Key>,
-          class _Alloc = std::allocator<char> >
-class hash_map;
-
-template <class _Key, class _Tp, class _HashFn, class _EqKey, class _Alloc>
-bool operator==(const hash_map<_Key, _Tp, _HashFn, _EqKey, _Alloc>&,
-                const hash_map<_Key, _Tp, _HashFn, _EqKey, _Alloc>&);
-
-template <class _Key, class _Tp, class _HashFcn, class _EqualKey, class _Alloc>
-class hash_map
-{
-private:
-  typedef hashtable<std::pair<const _Key, _Tp>, _Key, _HashFcn,
-                    hash_select1st<const _Key, _Tp>, _EqualKey, _Alloc>
-    _Ht;
-  _Ht _M_ht;
-
-public:
-  typedef typename _Ht::key_type key_type;
-  typedef _Tp data_type;
-  typedef _Tp mapped_type;
-  typedef typename _Ht::value_type value_type;
-  typedef typename _Ht::hasher hasher;
-  typedef typename _Ht::key_equal key_equal;
-
-  typedef typename _Ht::size_type size_type;
-  typedef typename _Ht::difference_type difference_type;
-  typedef typename _Ht::pointer pointer;
-  typedef typename _Ht::const_pointer const_pointer;
-  typedef typename _Ht::reference reference;
-  typedef typename _Ht::const_reference const_reference;
-
-  typedef typename _Ht::iterator iterator;
-  typedef typename _Ht::const_iterator const_iterator;
-
-  typedef typename _Ht::allocator_type allocator_type;
-
-  hasher hash_funct() const { return _M_ht.hash_funct(); }
-  key_equal key_eq() const { return _M_ht.key_eq(); }
-  allocator_type get_allocator() const { return _M_ht.get_allocator(); }
-
-public:
-  hash_map()
-    : _M_ht(100, hasher(), key_equal(), allocator_type())
-  {
-  }
-  explicit hash_map(size_type __n)
-    : _M_ht(__n, hasher(), key_equal(), allocator_type())
-  {
-  }
-  hash_map(size_type __n, const hasher& __hf)
-    : _M_ht(__n, __hf, key_equal(), allocator_type())
-  {
-  }
-  hash_map(size_type __n, const hasher& __hf, const key_equal& __eql,
-           const allocator_type& __a = allocator_type())
-    : _M_ht(__n, __hf, __eql, __a)
-  {
-  }
-
-  template <class _InputIterator>
-  hash_map(_InputIterator __f, _InputIterator __l)
-    : _M_ht(100, hasher(), key_equal(), allocator_type())
-  {
-    _M_ht.insert_unique(__f, __l);
-  }
-  template <class _InputIterator>
-  hash_map(_InputIterator __f, _InputIterator __l, size_type __n)
-    : _M_ht(__n, hasher(), key_equal(), allocator_type())
-  {
-    _M_ht.insert_unique(__f, __l);
-  }
-  template <class _InputIterator>
-  hash_map(_InputIterator __f, _InputIterator __l, size_type __n,
-           const hasher& __hf)
-    : _M_ht(__n, __hf, key_equal(), allocator_type())
-  {
-    _M_ht.insert_unique(__f, __l);
-  }
-  template <class _InputIterator>
-  hash_map(_InputIterator __f, _InputIterator __l, size_type __n,
-           const hasher& __hf, const key_equal& __eql,
-           const allocator_type& __a = allocator_type())
-    : _M_ht(__n, __hf, __eql, __a)
-  {
-    _M_ht.insert_unique(__f, __l);
-  }
-
-public:
-  size_type size() const { return _M_ht.size(); }
-  size_type max_size() const { return _M_ht.max_size(); }
-  bool empty() const { return _M_ht.empty(); }
-  void swap(hash_map& __hs) { _M_ht.swap(__hs._M_ht); }
-
-  friend bool operator==<>(const hash_map&, const hash_map&);
-
-  iterator begin() { return _M_ht.begin(); }
-  iterator end() { return _M_ht.end(); }
-  const_iterator begin() const { return _M_ht.begin(); }
-  const_iterator end() const { return _M_ht.end(); }
-
-public:
-  std::pair<iterator, bool> insert(const value_type& __obj)
-  {
-    return _M_ht.insert_unique(__obj);
-  }
-  template <class _InputIterator>
-  void insert(_InputIterator __f, _InputIterator __l)
-  {
-    _M_ht.insert_unique(__f, __l);
-  }
-  std::pair<iterator, bool> insert_noresize(const value_type& __obj)
-  {
-    return _M_ht.insert_unique_noresize(__obj);
-  }
-
-  iterator find(const key_type& __key) { return _M_ht.find(__key); }
-  const_iterator find(const key_type& __key) const
-  {
-    return _M_ht.find(__key);
-  }
-
-  _Tp& operator[](const key_type& __key)
-  {
-    return _M_ht.find_or_insert(value_type(__key, _Tp())).second;
-  }
-
-  size_type count(const key_type& __key) const { return _M_ht.count(__key); }
-
-  std::pair<iterator, iterator> equal_range(const key_type& __key)
-  {
-    return _M_ht.equal_range(__key);
-  }
-  std::pair<const_iterator, const_iterator> equal_range(
-    const key_type& __key) const
-  {
-    return _M_ht.equal_range(__key);
-  }
-
-  size_type erase(const key_type& __key) { return _M_ht.erase(__key); }
-  void erase(iterator __it) { _M_ht.erase(__it); }
-  void erase(iterator __f, iterator __l) { _M_ht.erase(__f, __l); }
-  void clear() { _M_ht.clear(); }
-
-  void resize(size_type __hint) { _M_ht.resize(__hint); }
-  size_type bucket_count() const { return _M_ht.bucket_count(); }
-  size_type max_bucket_count() const { return _M_ht.max_bucket_count(); }
-  size_type elems_in_bucket(size_type __n) const
-  {
-    return _M_ht.elems_in_bucket(__n);
-  }
-};
-
-template <class _Key, class _Tp, class _HashFcn, class _EqlKey, class _Alloc>
-bool operator==(const hash_map<_Key, _Tp, _HashFcn, _EqlKey, _Alloc>& __hm1,
-                const hash_map<_Key, _Tp, _HashFcn, _EqlKey, _Alloc>& __hm2)
-{
-  return __hm1._M_ht == __hm2._M_ht;
-}
-
-template <class _Key, class _Tp, class _HashFcn, class _EqlKey, class _Alloc>
-inline bool operator!=(
-  const hash_map<_Key, _Tp, _HashFcn, _EqlKey, _Alloc>& __hm1,
-  const hash_map<_Key, _Tp, _HashFcn, _EqlKey, _Alloc>& __hm2)
-{
-  return !(__hm1 == __hm2);
-}
-
-template <class _Key, class _Tp, class _HashFcn, class _EqlKey, class _Alloc>
-inline void swap(hash_map<_Key, _Tp, _HashFcn, _EqlKey, _Alloc>& __hm1,
-                 hash_map<_Key, _Tp, _HashFcn, _EqlKey, _Alloc>& __hm2)
-{
-  __hm1.swap(__hm2);
-}
-
-// Forward declaration of equality operator; needed for friend declaration.
-
-template <class _Key, class _Tp, class _HashFcn = hash<_Key>,
-          class _EqualKey = std::equal_to<_Key>,
-          class _Alloc = std::allocator<char> >
-class hash_multimap;
-
-template <class _Key, class _Tp, class _HF, class _EqKey, class _Alloc>
-bool operator==(const hash_multimap<_Key, _Tp, _HF, _EqKey, _Alloc>& __hm1,
-                const hash_multimap<_Key, _Tp, _HF, _EqKey, _Alloc>& __hm2);
-
-template <class _Key, class _Tp, class _HashFcn, class _EqualKey, class _Alloc>
-class hash_multimap
-{
-private:
-  typedef hashtable<std::pair<const _Key, _Tp>, _Key, _HashFcn,
-                    hash_select1st<const _Key, _Tp>, _EqualKey, _Alloc>
-    _Ht;
-  _Ht _M_ht;
-
-public:
-  typedef typename _Ht::key_type key_type;
-  typedef _Tp data_type;
-  typedef _Tp mapped_type;
-  typedef typename _Ht::value_type value_type;
-  typedef typename _Ht::hasher hasher;
-  typedef typename _Ht::key_equal key_equal;
-
-  typedef typename _Ht::size_type size_type;
-  typedef typename _Ht::difference_type difference_type;
-  typedef typename _Ht::pointer pointer;
-  typedef typename _Ht::const_pointer const_pointer;
-  typedef typename _Ht::reference reference;
-  typedef typename _Ht::const_reference const_reference;
-
-  typedef typename _Ht::iterator iterator;
-  typedef typename _Ht::const_iterator const_iterator;
-
-  typedef typename _Ht::allocator_type allocator_type;
-
-  hasher hash_funct() const { return _M_ht.hash_funct(); }
-  key_equal key_eq() const { return _M_ht.key_eq(); }
-  allocator_type get_allocator() const { return _M_ht.get_allocator(); }
-
-public:
-  hash_multimap()
-    : _M_ht(100, hasher(), key_equal(), allocator_type())
-  {
-  }
-  explicit hash_multimap(size_type __n)
-    : _M_ht(__n, hasher(), key_equal(), allocator_type())
-  {
-  }
-  hash_multimap(size_type __n, const hasher& __hf)
-    : _M_ht(__n, __hf, key_equal(), allocator_type())
-  {
-  }
-  hash_multimap(size_type __n, const hasher& __hf, const key_equal& __eql,
-                const allocator_type& __a = allocator_type())
-    : _M_ht(__n, __hf, __eql, __a)
-  {
-  }
-
-  template <class _InputIterator>
-  hash_multimap(_InputIterator __f, _InputIterator __l)
-    : _M_ht(100, hasher(), key_equal(), allocator_type())
-  {
-    _M_ht.insert_equal(__f, __l);
-  }
-  template <class _InputIterator>
-  hash_multimap(_InputIterator __f, _InputIterator __l, size_type __n)
-    : _M_ht(__n, hasher(), key_equal(), allocator_type())
-  {
-    _M_ht.insert_equal(__f, __l);
-  }
-  template <class _InputIterator>
-  hash_multimap(_InputIterator __f, _InputIterator __l, size_type __n,
-                const hasher& __hf)
-    : _M_ht(__n, __hf, key_equal(), allocator_type())
-  {
-    _M_ht.insert_equal(__f, __l);
-  }
-  template <class _InputIterator>
-  hash_multimap(_InputIterator __f, _InputIterator __l, size_type __n,
-                const hasher& __hf, const key_equal& __eql,
-                const allocator_type& __a = allocator_type())
-    : _M_ht(__n, __hf, __eql, __a)
-  {
-    _M_ht.insert_equal(__f, __l);
-  }
-
-public:
-  size_type size() const { return _M_ht.size(); }
-  size_type max_size() const { return _M_ht.max_size(); }
-  bool empty() const { return _M_ht.empty(); }
-  void swap(hash_multimap& __hs) { _M_ht.swap(__hs._M_ht); }
-
-  friend bool operator==<>(const hash_multimap&, const hash_multimap&);
-
-  iterator begin() { return _M_ht.begin(); }
-  iterator end() { return _M_ht.end(); }
-  const_iterator begin() const { return _M_ht.begin(); }
-  const_iterator end() const { return _M_ht.end(); }
-
-public:
-  iterator insert(const value_type& __obj)
-  {
-    return _M_ht.insert_equal(__obj);
-  }
-  template <class _InputIterator>
-  void insert(_InputIterator __f, _InputIterator __l)
-  {
-    _M_ht.insert_equal(__f, __l);
-  }
-  iterator insert_noresize(const value_type& __obj)
-  {
-    return _M_ht.insert_equal_noresize(__obj);
-  }
-
-  iterator find(const key_type& __key) { return _M_ht.find(__key); }
-  const_iterator find(const key_type& __key) const
-  {
-    return _M_ht.find(__key);
-  }
-
-  size_type count(const key_type& __key) const { return _M_ht.count(__key); }
-
-  std::pair<iterator, iterator> equal_range(const key_type& __key)
-  {
-    return _M_ht.equal_range(__key);
-  }
-  std::pair<const_iterator, const_iterator> equal_range(
-    const key_type& __key) const
-  {
-    return _M_ht.equal_range(__key);
-  }
-
-  size_type erase(const key_type& __key) { return _M_ht.erase(__key); }
-  void erase(iterator __it) { _M_ht.erase(__it); }
-  void erase(iterator __f, iterator __l) { _M_ht.erase(__f, __l); }
-  void clear() { _M_ht.clear(); }
-
-public:
-  void resize(size_type __hint) { _M_ht.resize(__hint); }
-  size_type bucket_count() const { return _M_ht.bucket_count(); }
-  size_type max_bucket_count() const { return _M_ht.max_bucket_count(); }
-  size_type elems_in_bucket(size_type __n) const
-  {
-    return _M_ht.elems_in_bucket(__n);
-  }
-};
-
-template <class _Key, class _Tp, class _HF, class _EqKey, class _Alloc>
-bool operator==(const hash_multimap<_Key, _Tp, _HF, _EqKey, _Alloc>& __hm1,
-                const hash_multimap<_Key, _Tp, _HF, _EqKey, _Alloc>& __hm2)
-{
-  return __hm1._M_ht == __hm2._M_ht;
-}
-
-template <class _Key, class _Tp, class _HF, class _EqKey, class _Alloc>
-inline bool operator!=(
-  const hash_multimap<_Key, _Tp, _HF, _EqKey, _Alloc>& __hm1,
-  const hash_multimap<_Key, _Tp, _HF, _EqKey, _Alloc>& __hm2)
-{
-  return !(__hm1 == __hm2);
-}
-
-template <class _Key, class _Tp, class _HashFcn, class _EqlKey, class _Alloc>
-inline void swap(hash_multimap<_Key, _Tp, _HashFcn, _EqlKey, _Alloc>& __hm1,
-                 hash_multimap<_Key, _Tp, _HashFcn, _EqlKey, _Alloc>& __hm2)
-{
-  __hm1.swap(__hm2);
-}
-
-} // namespace @KWSYS_NAMESPACE@
-
-#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32)
-#  pragma reset woff 1174
-#  pragma reset woff 1375
-#endif
-
-#if defined(_MSC_VER)
-#  pragma warning(pop)
-#endif
-
-#endif
diff --git a/Source/kwsys/hash_set.hxx.in b/Source/kwsys/hash_set.hxx.in
deleted file mode 100644
index f4a37ee..0000000
--- a/Source/kwsys/hash_set.hxx.in
+++ /dev/null
@@ -1,392 +0,0 @@
-/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
-   file Copyright.txt or https://cmake.org/licensing#kwsys for details.  */
-/*
- * Copyright (c) 1996
- * Silicon Graphics Computer Systems, Inc.
- *
- * Permission to use, copy, modify, distribute and sell this software
- * and its documentation for any purpose is hereby granted without fee,
- * provided that the above copyright notice appear in all copies and
- * that both that copyright notice and this permission notice appear
- * in supporting documentation.  Silicon Graphics makes no
- * representations about the suitability of this software for any
- * purpose.  It is provided "as is" without express or implied warranty.
- *
- *
- * Copyright (c) 1994
- * Hewlett-Packard Company
- *
- * Permission to use, copy, modify, distribute and sell this software
- * and its documentation for any purpose is hereby granted without fee,
- * provided that the above copyright notice appear in all copies and
- * that both that copyright notice and this permission notice appear
- * in supporting documentation.  Hewlett-Packard Company makes no
- * representations about the suitability of this software for any
- * purpose.  It is provided "as is" without express or implied warranty.
- *
- */
-#ifndef @KWSYS_NAMESPACE@_hash_set_hxx
-#define @KWSYS_NAMESPACE@_hash_set_hxx
-
-#include <@KWSYS_NAMESPACE@/hashtable.hxx>
-
-#include <@KWSYS_NAMESPACE@/hash_fun.hxx>
-
-#include <functional> // equal_to
-
-#if defined(_MSC_VER)
-#  pragma warning(push)
-#  pragma warning(disable : 4284)
-#  pragma warning(disable : 4786)
-#endif
-
-#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32)
-#  pragma set woff 1174
-#  pragma set woff 1375
-#endif
-
-namespace @KWSYS_NAMESPACE@ {
-
-// identity is an extension: it is not part of the standard.
-template <class _Tp>
-struct _Identity
-{
-  const _Tp& operator()(const _Tp& __x) const { return __x; }
-};
-
-// Forward declaration of equality operator; needed for friend declaration.
-
-template <class _Value, class _HashFcn = hash<_Value>,
-          class _EqualKey = std::equal_to<_Value>,
-          class _Alloc = std::allocator<char> >
-class hash_set;
-
-template <class _Value, class _HashFcn, class _EqualKey, class _Alloc>
-bool operator==(const hash_set<_Value, _HashFcn, _EqualKey, _Alloc>& __hs1,
-                const hash_set<_Value, _HashFcn, _EqualKey, _Alloc>& __hs2);
-
-template <class _Value, class _HashFcn, class _EqualKey, class _Alloc>
-class hash_set
-{
-private:
-  typedef hashtable<_Value, _Value, _HashFcn, _Identity<_Value>, _EqualKey,
-                    _Alloc>
-    _Ht;
-  _Ht _M_ht;
-
-public:
-  typedef typename _Ht::key_type key_type;
-  typedef typename _Ht::value_type value_type;
-  typedef typename _Ht::hasher hasher;
-  typedef typename _Ht::key_equal key_equal;
-
-  typedef typename _Ht::size_type size_type;
-  typedef typename _Ht::difference_type difference_type;
-  typedef typename _Ht::const_pointer pointer;
-  typedef typename _Ht::const_pointer const_pointer;
-  typedef typename _Ht::const_reference reference;
-  typedef typename _Ht::const_reference const_reference;
-
-  typedef typename _Ht::const_iterator iterator;
-  typedef typename _Ht::const_iterator const_iterator;
-
-  typedef typename _Ht::allocator_type allocator_type;
-
-  hasher hash_funct() const { return _M_ht.hash_funct(); }
-  key_equal key_eq() const { return _M_ht.key_eq(); }
-  allocator_type get_allocator() const { return _M_ht.get_allocator(); }
-
-public:
-  hash_set()
-    : _M_ht(100, hasher(), key_equal(), allocator_type())
-  {
-  }
-  explicit hash_set(size_type __n)
-    : _M_ht(__n, hasher(), key_equal(), allocator_type())
-  {
-  }
-  hash_set(size_type __n, const hasher& __hf)
-    : _M_ht(__n, __hf, key_equal(), allocator_type())
-  {
-  }
-  hash_set(size_type __n, const hasher& __hf, const key_equal& __eql,
-           const allocator_type& __a = allocator_type())
-    : _M_ht(__n, __hf, __eql, __a)
-  {
-  }
-
-  template <class _InputIterator>
-  hash_set(_InputIterator __f, _InputIterator __l)
-    : _M_ht(100, hasher(), key_equal(), allocator_type())
-  {
-    _M_ht.insert_unique(__f, __l);
-  }
-  template <class _InputIterator>
-  hash_set(_InputIterator __f, _InputIterator __l, size_type __n)
-    : _M_ht(__n, hasher(), key_equal(), allocator_type())
-  {
-    _M_ht.insert_unique(__f, __l);
-  }
-  template <class _InputIterator>
-  hash_set(_InputIterator __f, _InputIterator __l, size_type __n,
-           const hasher& __hf)
-    : _M_ht(__n, __hf, key_equal(), allocator_type())
-  {
-    _M_ht.insert_unique(__f, __l);
-  }
-  template <class _InputIterator>
-  hash_set(_InputIterator __f, _InputIterator __l, size_type __n,
-           const hasher& __hf, const key_equal& __eql,
-           const allocator_type& __a = allocator_type())
-    : _M_ht(__n, __hf, __eql, __a)
-  {
-    _M_ht.insert_unique(__f, __l);
-  }
-
-public:
-  size_type size() const { return _M_ht.size(); }
-  size_type max_size() const { return _M_ht.max_size(); }
-  bool empty() const { return _M_ht.empty(); }
-  void swap(hash_set& __hs) { _M_ht.swap(__hs._M_ht); }
-
-  friend bool operator==<>(const hash_set&, const hash_set&);
-
-  iterator begin() const { return _M_ht.begin(); }
-  iterator end() const { return _M_ht.end(); }
-
-public:
-  std::pair<iterator, bool> insert(const value_type& __obj)
-  {
-    typedef typename _Ht::iterator _Ht_iterator;
-    std::pair<_Ht_iterator, bool> __p = _M_ht.insert_unique(__obj);
-    return std::pair<iterator, bool>(__p.first, __p.second);
-  }
-  template <class _InputIterator>
-  void insert(_InputIterator __f, _InputIterator __l)
-  {
-    _M_ht.insert_unique(__f, __l);
-  }
-  std::pair<iterator, bool> insert_noresize(const value_type& __obj)
-  {
-    typedef typename _Ht::iterator _Ht_iterator;
-    std::pair<_Ht_iterator, bool> __p = _M_ht.insert_unique_noresize(__obj);
-    return std::pair<iterator, bool>(__p.first, __p.second);
-  }
-
-  iterator find(const key_type& __key) const { return _M_ht.find(__key); }
-
-  size_type count(const key_type& __key) const { return _M_ht.count(__key); }
-
-  std::pair<iterator, iterator> equal_range(const key_type& __key) const
-  {
-    return _M_ht.equal_range(__key);
-  }
-
-  size_type erase(const key_type& __key) { return _M_ht.erase(__key); }
-  void erase(iterator __it) { _M_ht.erase(__it); }
-  void erase(iterator __f, iterator __l) { _M_ht.erase(__f, __l); }
-  void clear() { _M_ht.clear(); }
-
-public:
-  void resize(size_type __hint) { _M_ht.resize(__hint); }
-  size_type bucket_count() const { return _M_ht.bucket_count(); }
-  size_type max_bucket_count() const { return _M_ht.max_bucket_count(); }
-  size_type elems_in_bucket(size_type __n) const
-  {
-    return _M_ht.elems_in_bucket(__n);
-  }
-};
-
-template <class _Value, class _HashFcn, class _EqualKey, class _Alloc>
-bool operator==(const hash_set<_Value, _HashFcn, _EqualKey, _Alloc>& __hs1,
-                const hash_set<_Value, _HashFcn, _EqualKey, _Alloc>& __hs2)
-{
-  return __hs1._M_ht == __hs2._M_ht;
-}
-
-template <class _Value, class _HashFcn, class _EqualKey, class _Alloc>
-inline bool operator!=(
-  const hash_set<_Value, _HashFcn, _EqualKey, _Alloc>& __hs1,
-  const hash_set<_Value, _HashFcn, _EqualKey, _Alloc>& __hs2)
-{
-  return !(__hs1 == __hs2);
-}
-
-template <class _Val, class _HashFcn, class _EqualKey, class _Alloc>
-inline void swap(hash_set<_Val, _HashFcn, _EqualKey, _Alloc>& __hs1,
-                 hash_set<_Val, _HashFcn, _EqualKey, _Alloc>& __hs2)
-{
-  __hs1.swap(__hs2);
-}
-
-template <class _Value, class _HashFcn = hash<_Value>,
-          class _EqualKey = std::equal_to<_Value>,
-          class _Alloc = std::allocator<char> >
-class hash_multiset;
-
-template <class _Val, class _HashFcn, class _EqualKey, class _Alloc>
-bool operator==(const hash_multiset<_Val, _HashFcn, _EqualKey, _Alloc>& __hs1,
-                const hash_multiset<_Val, _HashFcn, _EqualKey, _Alloc>& __hs2);
-
-template <class _Value, class _HashFcn, class _EqualKey, class _Alloc>
-class hash_multiset
-{
-private:
-  typedef hashtable<_Value, _Value, _HashFcn, _Identity<_Value>, _EqualKey,
-                    _Alloc>
-    _Ht;
-  _Ht _M_ht;
-
-public:
-  typedef typename _Ht::key_type key_type;
-  typedef typename _Ht::value_type value_type;
-  typedef typename _Ht::hasher hasher;
-  typedef typename _Ht::key_equal key_equal;
-
-  typedef typename _Ht::size_type size_type;
-  typedef typename _Ht::difference_type difference_type;
-  typedef typename _Ht::const_pointer pointer;
-  typedef typename _Ht::const_pointer const_pointer;
-  typedef typename _Ht::const_reference reference;
-  typedef typename _Ht::const_reference const_reference;
-
-  typedef typename _Ht::const_iterator iterator;
-  typedef typename _Ht::const_iterator const_iterator;
-
-  typedef typename _Ht::allocator_type allocator_type;
-
-  hasher hash_funct() const { return _M_ht.hash_funct(); }
-  key_equal key_eq() const { return _M_ht.key_eq(); }
-  allocator_type get_allocator() const { return _M_ht.get_allocator(); }
-
-public:
-  hash_multiset()
-    : _M_ht(100, hasher(), key_equal(), allocator_type())
-  {
-  }
-  explicit hash_multiset(size_type __n)
-    : _M_ht(__n, hasher(), key_equal(), allocator_type())
-  {
-  }
-  hash_multiset(size_type __n, const hasher& __hf)
-    : _M_ht(__n, __hf, key_equal(), allocator_type())
-  {
-  }
-  hash_multiset(size_type __n, const hasher& __hf, const key_equal& __eql,
-                const allocator_type& __a = allocator_type())
-    : _M_ht(__n, __hf, __eql, __a)
-  {
-  }
-
-  template <class _InputIterator>
-  hash_multiset(_InputIterator __f, _InputIterator __l)
-    : _M_ht(100, hasher(), key_equal(), allocator_type())
-  {
-    _M_ht.insert_equal(__f, __l);
-  }
-  template <class _InputIterator>
-  hash_multiset(_InputIterator __f, _InputIterator __l, size_type __n)
-    : _M_ht(__n, hasher(), key_equal(), allocator_type())
-  {
-    _M_ht.insert_equal(__f, __l);
-  }
-  template <class _InputIterator>
-  hash_multiset(_InputIterator __f, _InputIterator __l, size_type __n,
-                const hasher& __hf)
-    : _M_ht(__n, __hf, key_equal(), allocator_type())
-  {
-    _M_ht.insert_equal(__f, __l);
-  }
-  template <class _InputIterator>
-  hash_multiset(_InputIterator __f, _InputIterator __l, size_type __n,
-                const hasher& __hf, const key_equal& __eql,
-                const allocator_type& __a = allocator_type())
-    : _M_ht(__n, __hf, __eql, __a)
-  {
-    _M_ht.insert_equal(__f, __l);
-  }
-
-public:
-  size_type size() const { return _M_ht.size(); }
-  size_type max_size() const { return _M_ht.max_size(); }
-  bool empty() const { return _M_ht.empty(); }
-  void swap(hash_multiset& hs) { _M_ht.swap(hs._M_ht); }
-
-  friend bool operator==<>(const hash_multiset&, const hash_multiset&);
-
-  iterator begin() const { return _M_ht.begin(); }
-  iterator end() const { return _M_ht.end(); }
-
-public:
-  iterator insert(const value_type& __obj)
-  {
-    return _M_ht.insert_equal(__obj);
-  }
-  template <class _InputIterator>
-  void insert(_InputIterator __f, _InputIterator __l)
-  {
-    _M_ht.insert_equal(__f, __l);
-  }
-  iterator insert_noresize(const value_type& __obj)
-  {
-    return _M_ht.insert_equal_noresize(__obj);
-  }
-
-  iterator find(const key_type& __key) const { return _M_ht.find(__key); }
-
-  size_type count(const key_type& __key) const { return _M_ht.count(__key); }
-
-  std::pair<iterator, iterator> equal_range(const key_type& __key) const
-  {
-    return _M_ht.equal_range(__key);
-  }
-
-  size_type erase(const key_type& __key) { return _M_ht.erase(__key); }
-  void erase(iterator __it) { _M_ht.erase(__it); }
-  void erase(iterator __f, iterator __l) { _M_ht.erase(__f, __l); }
-  void clear() { _M_ht.clear(); }
-
-public:
-  void resize(size_type __hint) { _M_ht.resize(__hint); }
-  size_type bucket_count() const { return _M_ht.bucket_count(); }
-  size_type max_bucket_count() const { return _M_ht.max_bucket_count(); }
-  size_type elems_in_bucket(size_type __n) const
-  {
-    return _M_ht.elems_in_bucket(__n);
-  }
-};
-
-template <class _Val, class _HashFcn, class _EqualKey, class _Alloc>
-bool operator==(const hash_multiset<_Val, _HashFcn, _EqualKey, _Alloc>& __hs1,
-                const hash_multiset<_Val, _HashFcn, _EqualKey, _Alloc>& __hs2)
-{
-  return __hs1._M_ht == __hs2._M_ht;
-}
-
-template <class _Val, class _HashFcn, class _EqualKey, class _Alloc>
-inline bool operator!=(
-  const hash_multiset<_Val, _HashFcn, _EqualKey, _Alloc>& __hs1,
-  const hash_multiset<_Val, _HashFcn, _EqualKey, _Alloc>& __hs2)
-{
-  return !(__hs1 == __hs2);
-}
-
-template <class _Val, class _HashFcn, class _EqualKey, class _Alloc>
-inline void swap(hash_multiset<_Val, _HashFcn, _EqualKey, _Alloc>& __hs1,
-                 hash_multiset<_Val, _HashFcn, _EqualKey, _Alloc>& __hs2)
-{
-  __hs1.swap(__hs2);
-}
-
-} // namespace @KWSYS_NAMESPACE@
-
-#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32)
-#  pragma reset woff 1174
-#  pragma reset woff 1375
-#endif
-
-#if defined(_MSC_VER)
-#  pragma warning(pop)
-#endif
-
-#endif
diff --git a/Source/kwsys/hashtable.hxx.in b/Source/kwsys/hashtable.hxx.in
deleted file mode 100644
index 8c4b002..0000000
--- a/Source/kwsys/hashtable.hxx.in
+++ /dev/null
@@ -1,995 +0,0 @@
-/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
-   file Copyright.txt or https://cmake.org/licensing#kwsys for details.  */
-/*
- * Copyright (c) 1996
- * Silicon Graphics Computer Systems, Inc.
- *
- * Permission to use, copy, modify, distribute and sell this software
- * and its documentation for any purpose is hereby granted without fee,
- * provided that the above copyright notice appear in all copies and
- * that both that copyright notice and this permission notice appear
- * in supporting documentation.  Silicon Graphics makes no
- * representations about the suitability of this software for any
- * purpose.  It is provided "as is" without express or implied warranty.
- *
- *
- * Copyright (c) 1994
- * Hewlett-Packard Company
- *
- * Permission to use, copy, modify, distribute and sell this software
- * and its documentation for any purpose is hereby granted without fee,
- * provided that the above copyright notice appear in all copies and
- * that both that copyright notice and this permission notice appear
- * in supporting documentation.  Hewlett-Packard Company makes no
- * representations about the suitability of this software for any
- * purpose.  It is provided "as is" without express or implied warranty.
- *
- */
-#ifdef __BORLANDC__
-#  pragma warn - 8027 /* 'for' not inlined.  */
-#  pragma warn - 8026 /* 'exception' not inlined.  */
-#endif
-
-#ifndef @KWSYS_NAMESPACE@_hashtable_hxx
-#  define @KWSYS_NAMESPACE@_hashtable_hxx
-
-#  include <@KWSYS_NAMESPACE@/Configure.hxx>
-
-#  include <algorithm> // lower_bound
-#  include <iterator>  // iterator_traits
-#  include <memory>    // allocator
-#  include <stddef.h>  // size_t
-#  include <utility>   // pair
-#  include <vector>    // vector
-
-#  if defined(_MSC_VER)
-#    pragma warning(push)
-#    pragma warning(disable : 4284)
-#    pragma warning(disable : 4786)
-#    pragma warning(disable : 4512) /* no assignment operator for class */
-#  endif
-#  if defined(__sgi) && !defined(__GNUC__)
-#    pragma set woff 3970 /* pointer to int conversion */ 3321 3968
-#  endif
-
-// In C++11, clang will warn about using dynamic exception specifications
-// as they are deprecated.  But as this class is trying to faithfully
-// mimic unordered_set and unordered_map, we want to keep the 'throw()'
-// decorations below.  So we suppress the warning.
-#  if defined(__clang__) && defined(__has_warning)
-#    if __has_warning("-Wdeprecated")
-#      pragma clang diagnostic push
-#      pragma clang diagnostic ignored "-Wdeprecated"
-#    endif
-#  endif
-
-namespace @KWSYS_NAMESPACE@ {
-
-template <class _Val>
-struct _Hashtable_node
-{
-  _Hashtable_node* _M_next;
-  _Val _M_val;
-  void public_method_to_quiet_warning_about_all_methods_private();
-
-private:
-  void operator=(_Hashtable_node<_Val> const&) = delete;
-};
-
-template <class _Val, class _Key, class _HashFcn, class _ExtractKey,
-          class _EqualKey, class _Alloc = std::allocator<char> >
-class hashtable;
-
-template <class _Val, class _Key, class _HashFcn, class _ExtractKey,
-          class _EqualKey, class _Alloc>
-struct _Hashtable_iterator;
-
-template <class _Val, class _Key, class _HashFcn, class _ExtractKey,
-          class _EqualKey, class _Alloc>
-struct _Hashtable_const_iterator;
-
-template <class _Val, class _Key, class _HashFcn, class _ExtractKey,
-          class _EqualKey, class _Alloc>
-struct _Hashtable_iterator
-{
-  typedef hashtable<_Val, _Key, _HashFcn, _ExtractKey, _EqualKey, _Alloc>
-    _Hashtable;
-  typedef _Hashtable_iterator<_Val, _Key, _HashFcn, _ExtractKey, _EqualKey,
-                              _Alloc>
-    iterator;
-  typedef _Hashtable_const_iterator<_Val, _Key, _HashFcn, _ExtractKey,
-                                    _EqualKey, _Alloc>
-    const_iterator;
-  typedef _Hashtable_node<_Val> _Node;
-
-  typedef std::forward_iterator_tag iterator_category;
-  typedef _Val value_type;
-  typedef ptrdiff_t difference_type;
-  typedef size_t size_type;
-  typedef _Val& reference;
-  typedef _Val* pointer;
-
-  _Node* _M_cur;
-  _Hashtable* _M_ht;
-
-  _Hashtable_iterator(_Node* __n, _Hashtable* __tab)
-    : _M_cur(__n)
-    , _M_ht(__tab)
-  {
-  }
-  _Hashtable_iterator() {}
-  reference operator*() const { return _M_cur->_M_val; }
-  pointer operator->() const { return &(operator*()); }
-  iterator& operator++();
-  iterator operator++(int);
-  bool operator==(const iterator& __it) const { return _M_cur == __it._M_cur; }
-  bool operator!=(const iterator& __it) const { return _M_cur != __it._M_cur; }
-};
-
-template <class _Val, class _Key, class _HashFcn, class _ExtractKey,
-          class _EqualKey, class _Alloc>
-struct _Hashtable_const_iterator
-{
-  typedef hashtable<_Val, _Key, _HashFcn, _ExtractKey, _EqualKey, _Alloc>
-    _Hashtable;
-  typedef _Hashtable_iterator<_Val, _Key, _HashFcn, _ExtractKey, _EqualKey,
-                              _Alloc>
-    iterator;
-  typedef _Hashtable_const_iterator<_Val, _Key, _HashFcn, _ExtractKey,
-                                    _EqualKey, _Alloc>
-    const_iterator;
-  typedef _Hashtable_node<_Val> _Node;
-
-  typedef std::forward_iterator_tag iterator_category;
-  typedef _Val value_type;
-  typedef ptrdiff_t difference_type;
-  typedef size_t size_type;
-  typedef const _Val& reference;
-  typedef const _Val* pointer;
-
-  const _Node* _M_cur;
-  const _Hashtable* _M_ht;
-
-  _Hashtable_const_iterator(const _Node* __n, const _Hashtable* __tab)
-    : _M_cur(__n)
-    , _M_ht(__tab)
-  {
-  }
-  _Hashtable_const_iterator() {}
-  _Hashtable_const_iterator(const iterator& __it)
-    : _M_cur(__it._M_cur)
-    , _M_ht(__it._M_ht)
-  {
-  }
-  reference operator*() const { return _M_cur->_M_val; }
-  pointer operator->() const { return &(operator*()); }
-  const_iterator& operator++();
-  const_iterator operator++(int);
-  bool operator==(const const_iterator& __it) const
-  {
-    return _M_cur == __it._M_cur;
-  }
-  bool operator!=(const const_iterator& __it) const
-  {
-    return _M_cur != __it._M_cur;
-  }
-};
-
-// Note: assumes long is at least 32 bits.
-enum
-{
-  _stl_num_primes = 31
-};
-
-// create a function with a static local to that function that returns
-// the static
-static inline const unsigned long* get_stl_prime_list()
-{
-
-  static const unsigned long _stl_prime_list[_stl_num_primes] = {
-    5ul,         11ul,        23ul,        53ul,         97ul,
-    193ul,       389ul,       769ul,       1543ul,       3079ul,
-    6151ul,      12289ul,     24593ul,     49157ul,      98317ul,
-    196613ul,    393241ul,    786433ul,    1572869ul,    3145739ul,
-    6291469ul,   12582917ul,  25165843ul,  50331653ul,   100663319ul,
-    201326611ul, 402653189ul, 805306457ul, 1610612741ul, 3221225473ul,
-    4294967291ul
-  };
-
-  return &_stl_prime_list[0];
-}
-
-static inline size_t _stl_next_prime(size_t __n)
-{
-  const unsigned long* __first = get_stl_prime_list();
-  const unsigned long* __last = get_stl_prime_list() + (int)_stl_num_primes;
-  const unsigned long* pos = std::lower_bound(__first, __last, __n);
-  return pos == __last ? *(__last - 1) : *pos;
-}
-
-// Forward declaration of operator==.
-
-template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
-class hashtable;
-
-template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
-bool operator==(const hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>& __ht1,
-                const hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>& __ht2);
-
-// Hashtables handle allocators a bit differently than other containers
-//  do.  If we're using standard-conforming allocators, then a hashtable
-//  unconditionally has a member variable to hold its allocator, even if
-//  it so happens that all instances of the allocator type are identical.
-// This is because, for hashtables, this extra storage is negligible.
-//  Additionally, a base class wouldn't serve any other purposes; it
-//  wouldn't, for example, simplify the exception-handling code.
-
-template <class _Val, class _Key, class _HashFcn, class _ExtractKey,
-          class _EqualKey, class _Alloc>
-class hashtable
-{
-public:
-  typedef _Key key_type;
-  typedef _Val value_type;
-  typedef _HashFcn hasher;
-  typedef _EqualKey key_equal;
-
-  typedef size_t size_type;
-  typedef ptrdiff_t difference_type;
-  typedef value_type* pointer;
-  typedef const value_type* const_pointer;
-  typedef value_type& reference;
-  typedef const value_type& const_reference;
-
-  hasher hash_funct() const { return _M_hash; }
-  key_equal key_eq() const { return _M_equals; }
-
-private:
-  typedef _Hashtable_node<_Val> _Node;
-
-public:
-  typedef typename _Alloc::template rebind<_Val>::other allocator_type;
-  allocator_type get_allocator() const { return _M_node_allocator; }
-
-private:
-  typedef
-    typename _Alloc::template rebind<_Node>::other _M_node_allocator_type;
-  typedef
-    typename _Alloc::template rebind<_Node*>::other _M_node_ptr_allocator_type;
-  typedef std::vector<_Node*, _M_node_ptr_allocator_type> _M_buckets_type;
-
-private:
-  _M_node_allocator_type _M_node_allocator;
-  hasher _M_hash;
-  key_equal _M_equals;
-  _ExtractKey _M_get_key;
-  _M_buckets_type _M_buckets;
-  size_type _M_num_elements;
-
-  _Node* _M_get_node() { return _M_node_allocator.allocate(1); }
-  void _M_put_node(_Node* __p) { _M_node_allocator.deallocate(__p, 1); }
-
-public:
-  typedef _Hashtable_iterator<_Val, _Key, _HashFcn, _ExtractKey, _EqualKey,
-                              _Alloc>
-    iterator;
-  typedef _Hashtable_const_iterator<_Val, _Key, _HashFcn, _ExtractKey,
-                                    _EqualKey, _Alloc>
-    const_iterator;
-
-  friend struct _Hashtable_iterator<_Val, _Key, _HashFcn, _ExtractKey,
-                                    _EqualKey, _Alloc>;
-  friend struct _Hashtable_const_iterator<_Val, _Key, _HashFcn, _ExtractKey,
-                                          _EqualKey, _Alloc>;
-
-public:
-  hashtable(size_type __n, const _HashFcn& __hf, const _EqualKey& __eql,
-            const _ExtractKey& __ext,
-            const allocator_type& __a = allocator_type())
-    : _M_node_allocator(__a)
-    , _M_hash(__hf)
-    , _M_equals(__eql)
-    , _M_get_key(__ext)
-    , _M_buckets(__a)
-    , _M_num_elements(0)
-  {
-    _M_initialize_buckets(__n);
-  }
-
-  hashtable(size_type __n, const _HashFcn& __hf, const _EqualKey& __eql,
-            const allocator_type& __a = allocator_type())
-    : _M_node_allocator(__a)
-    , _M_hash(__hf)
-    , _M_equals(__eql)
-    , _M_get_key(_ExtractKey())
-    , _M_buckets(__a)
-    , _M_num_elements(0)
-  {
-    _M_initialize_buckets(__n);
-  }
-
-  hashtable(const hashtable& __ht)
-    : _M_node_allocator(__ht.get_allocator())
-    , _M_hash(__ht._M_hash)
-    , _M_equals(__ht._M_equals)
-    , _M_get_key(__ht._M_get_key)
-    , _M_buckets(__ht.get_allocator())
-    , _M_num_elements(0)
-  {
-    _M_copy_from(__ht);
-  }
-
-  hashtable& operator=(const hashtable& __ht)
-  {
-    if (&__ht != this) {
-      clear();
-      _M_hash = __ht._M_hash;
-      _M_equals = __ht._M_equals;
-      _M_get_key = __ht._M_get_key;
-      _M_copy_from(__ht);
-    }
-    return *this;
-  }
-
-  ~hashtable() { clear(); }
-
-  size_type size() const { return _M_num_elements; }
-  size_type max_size() const { return size_type(-1); }
-  bool empty() const { return size() == 0; }
-
-  void swap(hashtable& __ht)
-  {
-    std::swap(_M_hash, __ht._M_hash);
-    std::swap(_M_equals, __ht._M_equals);
-    std::swap(_M_get_key, __ht._M_get_key);
-    _M_buckets.swap(__ht._M_buckets);
-    std::swap(_M_num_elements, __ht._M_num_elements);
-  }
-
-  iterator begin()
-  {
-    for (size_type __n = 0; __n < _M_buckets.size(); ++__n)
-      if (_M_buckets[__n])
-        return iterator(_M_buckets[__n], this);
-    return end();
-  }
-
-  iterator end() { return iterator(nullptr, this); }
-
-  const_iterator begin() const
-  {
-    for (size_type __n = 0; __n < _M_buckets.size(); ++__n)
-      if (_M_buckets[__n])
-        return const_iterator(_M_buckets[__n], this);
-    return end();
-  }
-
-  const_iterator end() const { return const_iterator(nullptr, this); }
-
-  friend bool operator==<>(const hashtable&, const hashtable&);
-
-public:
-  size_type bucket_count() const { return _M_buckets.size(); }
-
-  size_type max_bucket_count() const
-  {
-    return get_stl_prime_list()[(int)_stl_num_primes - 1];
-  }
-
-  size_type elems_in_bucket(size_type __bucket) const
-  {
-    size_type __result = 0;
-    for (_Node* __cur = _M_buckets[__bucket]; __cur; __cur = __cur->_M_next)
-      __result += 1;
-    return __result;
-  }
-
-  std::pair<iterator, bool> insert_unique(const value_type& __obj)
-  {
-    resize(_M_num_elements + 1);
-    return insert_unique_noresize(__obj);
-  }
-
-  iterator insert_equal(const value_type& __obj)
-  {
-    resize(_M_num_elements + 1);
-    return insert_equal_noresize(__obj);
-  }
-
-  std::pair<iterator, bool> insert_unique_noresize(const value_type& __obj);
-  iterator insert_equal_noresize(const value_type& __obj);
-
-  template <class _InputIterator>
-  void insert_unique(_InputIterator __f, _InputIterator __l)
-  {
-    insert_unique(
-      __f, __l,
-      typename std::iterator_traits<_InputIterator>::iterator_category());
-  }
-
-  template <class _InputIterator>
-  void insert_equal(_InputIterator __f, _InputIterator __l)
-  {
-    insert_equal(
-      __f, __l,
-      typename std::iterator_traits<_InputIterator>::iterator_category());
-  }
-
-  template <class _InputIterator>
-  void insert_unique(_InputIterator __f, _InputIterator __l,
-                     std::input_iterator_tag)
-  {
-    for (; __f != __l; ++__f)
-      insert_unique(*__f);
-  }
-
-  template <class _InputIterator>
-  void insert_equal(_InputIterator __f, _InputIterator __l,
-                    std::input_iterator_tag)
-  {
-    for (; __f != __l; ++__f)
-      insert_equal(*__f);
-  }
-
-  template <class _ForwardIterator>
-  void insert_unique(_ForwardIterator __f, _ForwardIterator __l,
-                     std::forward_iterator_tag)
-  {
-    size_type __n = 0;
-    std::distance(__f, __l, __n);
-    resize(_M_num_elements + __n);
-    for (; __n > 0; --__n, ++__f)
-      insert_unique_noresize(*__f);
-  }
-
-  template <class _ForwardIterator>
-  void insert_equal(_ForwardIterator __f, _ForwardIterator __l,
-                    std::forward_iterator_tag)
-  {
-    size_type __n = 0;
-    std::distance(__f, __l, __n);
-    resize(_M_num_elements + __n);
-    for (; __n > 0; --__n, ++__f)
-      insert_equal_noresize(*__f);
-  }
-
-  reference find_or_insert(const value_type& __obj);
-
-  iterator find(const key_type& __key)
-  {
-    size_type __n = _M_bkt_num_key(__key);
-    _Node* __first;
-    for (__first = _M_buckets[__n];
-         __first && !_M_equals(_M_get_key(__first->_M_val), __key);
-         __first = __first->_M_next) {
-    }
-    return iterator(__first, this);
-  }
-
-  const_iterator find(const key_type& __key) const
-  {
-    size_type __n = _M_bkt_num_key(__key);
-    const _Node* __first;
-    for (__first = _M_buckets[__n];
-         __first && !_M_equals(_M_get_key(__first->_M_val), __key);
-         __first = __first->_M_next) {
-    }
-    return const_iterator(__first, this);
-  }
-
-  size_type count(const key_type& __key) const
-  {
-    const size_type __n = _M_bkt_num_key(__key);
-    size_type __result = 0;
-
-    for (const _Node* __cur = _M_buckets[__n]; __cur; __cur = __cur->_M_next)
-      if (_M_equals(_M_get_key(__cur->_M_val), __key))
-        ++__result;
-    return __result;
-  }
-
-  std::pair<iterator, iterator> equal_range(const key_type& __key);
-
-  std::pair<const_iterator, const_iterator> equal_range(
-    const key_type& __key) const;
-
-  size_type erase(const key_type& __key);
-  void erase(const iterator& __it);
-  void erase(iterator __first, iterator __last);
-
-  void erase(const const_iterator& __it);
-  void erase(const_iterator __first, const_iterator __last);
-
-  void resize(size_type __num_elements_hint);
-  void clear();
-
-private:
-  size_type _M_next_size(size_type __n) const { return _stl_next_prime(__n); }
-
-  void _M_initialize_buckets(size_type __n)
-  {
-    const size_type __n_buckets = _M_next_size(__n);
-    _M_buckets.reserve(__n_buckets);
-    _M_buckets.insert(_M_buckets.end(), __n_buckets, (_Node*)nullptr);
-    _M_num_elements = 0;
-  }
-
-  size_type _M_bkt_num_key(const key_type& __key) const
-  {
-    return _M_bkt_num_key(__key, _M_buckets.size());
-  }
-
-  size_type _M_bkt_num(const value_type& __obj) const
-  {
-    return _M_bkt_num_key(_M_get_key(__obj));
-  }
-
-  size_type _M_bkt_num_key(const key_type& __key, size_t __n) const
-  {
-    return _M_hash(__key) % __n;
-  }
-
-  size_type _M_bkt_num(const value_type& __obj, size_t __n) const
-  {
-    return _M_bkt_num_key(_M_get_key(__obj), __n);
-  }
-
-  void construct(_Val* p, const _Val& v) { new (p) _Val(v); }
-  void destroy(_Val* p)
-  {
-    (void)p;
-    p->~_Val();
-  }
-
-  _Node* _M_new_node(const value_type& __obj)
-  {
-    _Node* __n = _M_get_node();
-    __n->_M_next = nullptr;
-    try {
-      construct(&__n->_M_val, __obj);
-      return __n;
-    } catch (...) {
-      _M_put_node(__n);
-      throw;
-    }
-  }
-
-  void _M_delete_node(_Node* __n)
-  {
-    destroy(&__n->_M_val);
-    _M_put_node(__n);
-  }
-
-  void _M_erase_bucket(const size_type __n, _Node* __first, _Node* __last);
-  void _M_erase_bucket(const size_type __n, _Node* __last);
-
-  void _M_copy_from(const hashtable& __ht);
-};
-
-template <class _Val, class _Key, class _HF, class _ExK, class _EqK,
-          class _All>
-_Hashtable_iterator<_Val, _Key, _HF, _ExK, _EqK, _All>&
-_Hashtable_iterator<_Val, _Key, _HF, _ExK, _EqK, _All>::operator++()
-{
-  const _Node* __old = _M_cur;
-  _M_cur = _M_cur->_M_next;
-  if (!_M_cur) {
-    size_type __bucket = _M_ht->_M_bkt_num(__old->_M_val);
-    while (!_M_cur && ++__bucket < _M_ht->_M_buckets.size())
-      _M_cur = _M_ht->_M_buckets[__bucket];
-  }
-  return *this;
-}
-
-template <class _Val, class _Key, class _HF, class _ExK, class _EqK,
-          class _All>
-inline _Hashtable_iterator<_Val, _Key, _HF, _ExK, _EqK, _All>
-_Hashtable_iterator<_Val, _Key, _HF, _ExK, _EqK, _All>::operator++(int)
-{
-  iterator __tmp = *this;
-  ++*this;
-  return __tmp;
-}
-
-template <class _Val, class _Key, class _HF, class _ExK, class _EqK,
-          class _All>
-_Hashtable_const_iterator<_Val, _Key, _HF, _ExK, _EqK, _All>&
-_Hashtable_const_iterator<_Val, _Key, _HF, _ExK, _EqK, _All>::operator++()
-{
-  const _Node* __old = _M_cur;
-  _M_cur = _M_cur->_M_next;
-  if (!_M_cur) {
-    size_type __bucket = _M_ht->_M_bkt_num(__old->_M_val);
-    while (!_M_cur && ++__bucket < _M_ht->_M_buckets.size())
-      _M_cur = _M_ht->_M_buckets[__bucket];
-  }
-  return *this;
-}
-
-template <class _Val, class _Key, class _HF, class _ExK, class _EqK,
-          class _All>
-inline _Hashtable_const_iterator<_Val, _Key, _HF, _ExK, _EqK, _All>
-_Hashtable_const_iterator<_Val, _Key, _HF, _ExK, _EqK, _All>::operator++(int)
-{
-  const_iterator __tmp = *this;
-  ++*this;
-  return __tmp;
-}
-
-template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
-bool operator==(const hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>& __ht1,
-                const hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>& __ht2)
-{
-  typedef typename hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::_Node _Node;
-  if (__ht1._M_buckets.size() != __ht2._M_buckets.size())
-    return false;
-  for (int __n = 0; __n < __ht1._M_buckets.size(); ++__n) {
-    _Node* __cur1 = __ht1._M_buckets[__n];
-    _Node* __cur2 = __ht2._M_buckets[__n];
-    for (; __cur1 && __cur2 && __cur1->_M_val == __cur2->_M_val;
-         __cur1 = __cur1->_M_next, __cur2 = __cur2->_M_next) {
-    }
-    if (__cur1 || __cur2)
-      return false;
-  }
-  return true;
-}
-
-template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
-inline bool operator!=(const hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>& __ht1,
-                       const hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>& __ht2)
-{
-  return !(__ht1 == __ht2);
-}
-
-template <class _Val, class _Key, class _HF, class _Extract, class _EqKey,
-          class _All>
-inline void swap(hashtable<_Val, _Key, _HF, _Extract, _EqKey, _All>& __ht1,
-                 hashtable<_Val, _Key, _HF, _Extract, _EqKey, _All>& __ht2)
-{
-  __ht1.swap(__ht2);
-}
-
-template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
-std::pair<typename hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::iterator, bool>
-hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::insert_unique_noresize(
-  const value_type& __obj)
-{
-  const size_type __n = _M_bkt_num(__obj);
-  _Node* __first = _M_buckets[__n];
-
-  for (_Node* __cur = __first; __cur; __cur = __cur->_M_next)
-    if (_M_equals(_M_get_key(__cur->_M_val), _M_get_key(__obj)))
-      return std::pair<iterator, bool>(iterator(__cur, this), false);
-
-  _Node* __tmp = _M_new_node(__obj);
-  __tmp->_M_next = __first;
-  _M_buckets[__n] = __tmp;
-  ++_M_num_elements;
-  return std::pair<iterator, bool>(iterator(__tmp, this), true);
-}
-
-template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
-typename hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::iterator
-hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::insert_equal_noresize(
-  const value_type& __obj)
-{
-  const size_type __n = _M_bkt_num(__obj);
-  _Node* __first = _M_buckets[__n];
-
-  for (_Node* __cur = __first; __cur; __cur = __cur->_M_next)
-    if (_M_equals(_M_get_key(__cur->_M_val), _M_get_key(__obj))) {
-      _Node* __tmp = _M_new_node(__obj);
-      __tmp->_M_next = __cur->_M_next;
-      __cur->_M_next = __tmp;
-      ++_M_num_elements;
-      return iterator(__tmp, this);
-    }
-
-  _Node* __tmp = _M_new_node(__obj);
-  __tmp->_M_next = __first;
-  _M_buckets[__n] = __tmp;
-  ++_M_num_elements;
-  return iterator(__tmp, this);
-}
-
-template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
-typename hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::reference
-hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::find_or_insert(
-  const value_type& __obj)
-{
-  resize(_M_num_elements + 1);
-
-  size_type __n = _M_bkt_num(__obj);
-  _Node* __first = _M_buckets[__n];
-
-  for (_Node* __cur = __first; __cur; __cur = __cur->_M_next)
-    if (_M_equals(_M_get_key(__cur->_M_val), _M_get_key(__obj)))
-      return __cur->_M_val;
-
-  _Node* __tmp = _M_new_node(__obj);
-  __tmp->_M_next = __first;
-  _M_buckets[__n] = __tmp;
-  ++_M_num_elements;
-  return __tmp->_M_val;
-}
-
-template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
-std::pair<typename hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::iterator,
-          typename hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::iterator>
-hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::equal_range(const key_type& __key)
-{
-  typedef std::pair<iterator, iterator> _Pii;
-  const size_type __n = _M_bkt_num_key(__key);
-
-  for (_Node* __first = _M_buckets[__n]; __first; __first = __first->_M_next)
-    if (_M_equals(_M_get_key(__first->_M_val), __key)) {
-      for (_Node* __cur = __first->_M_next; __cur; __cur = __cur->_M_next)
-        if (!_M_equals(_M_get_key(__cur->_M_val), __key))
-          return _Pii(iterator(__first, this), iterator(__cur, this));
-      for (size_type __m = __n + 1; __m < _M_buckets.size(); ++__m)
-        if (_M_buckets[__m])
-          return _Pii(iterator(__first, this),
-                      iterator(_M_buckets[__m], this));
-      return _Pii(iterator(__first, this), end());
-    }
-  return _Pii(end(), end());
-}
-
-template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
-std::pair<typename hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::const_iterator,
-          typename hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::const_iterator>
-hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::equal_range(
-  const key_type& __key) const
-{
-  typedef std::pair<const_iterator, const_iterator> _Pii;
-  const size_type __n = _M_bkt_num_key(__key);
-
-  for (const _Node* __first = _M_buckets[__n]; __first;
-       __first = __first->_M_next) {
-    if (_M_equals(_M_get_key(__first->_M_val), __key)) {
-      for (const _Node* __cur = __first->_M_next; __cur;
-           __cur = __cur->_M_next)
-        if (!_M_equals(_M_get_key(__cur->_M_val), __key))
-          return _Pii(const_iterator(__first, this),
-                      const_iterator(__cur, this));
-      for (size_type __m = __n + 1; __m < _M_buckets.size(); ++__m)
-        if (_M_buckets[__m])
-          return _Pii(const_iterator(__first, this),
-                      const_iterator(_M_buckets[__m], this));
-      return _Pii(const_iterator(__first, this), end());
-    }
-  }
-  return _Pii(end(), end());
-}
-
-template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
-typename hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::size_type
-hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::erase(const key_type& __key)
-{
-  const size_type __n = _M_bkt_num_key(__key);
-  _Node* __first = _M_buckets[__n];
-  size_type __erased = 0;
-
-  if (__first) {
-    _Node* __cur = __first;
-    _Node* __next = __cur->_M_next;
-    while (__next) {
-      if (_M_equals(_M_get_key(__next->_M_val), __key)) {
-        __cur->_M_next = __next->_M_next;
-        _M_delete_node(__next);
-        __next = __cur->_M_next;
-        ++__erased;
-        --_M_num_elements;
-      } else {
-        __cur = __next;
-        __next = __cur->_M_next;
-      }
-    }
-    if (_M_equals(_M_get_key(__first->_M_val), __key)) {
-      _M_buckets[__n] = __first->_M_next;
-      _M_delete_node(__first);
-      ++__erased;
-      --_M_num_elements;
-    }
-  }
-  return __erased;
-}
-
-template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
-void hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::erase(const iterator& __it)
-{
-  _Node* __p = __it._M_cur;
-  if (__p) {
-    const size_type __n = _M_bkt_num(__p->_M_val);
-    _Node* __cur = _M_buckets[__n];
-
-    if (__cur == __p) {
-      _M_buckets[__n] = __cur->_M_next;
-      _M_delete_node(__cur);
-      --_M_num_elements;
-    } else {
-      _Node* __next = __cur->_M_next;
-      while (__next) {
-        if (__next == __p) {
-          __cur->_M_next = __next->_M_next;
-          _M_delete_node(__next);
-          --_M_num_elements;
-          break;
-        } else {
-          __cur = __next;
-          __next = __cur->_M_next;
-        }
-      }
-    }
-  }
-}
-
-template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
-void hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::erase(iterator __first,
-                                                       iterator __last)
-{
-  size_type __f_bucket =
-    __first._M_cur ? _M_bkt_num(__first._M_cur->_M_val) : _M_buckets.size();
-  size_type __l_bucket =
-    __last._M_cur ? _M_bkt_num(__last._M_cur->_M_val) : _M_buckets.size();
-
-  if (__first._M_cur == __last._M_cur)
-    return;
-  else if (__f_bucket == __l_bucket)
-    _M_erase_bucket(__f_bucket, __first._M_cur, __last._M_cur);
-  else {
-    _M_erase_bucket(__f_bucket, __first._M_cur, nullptr);
-    for (size_type __n = __f_bucket + 1; __n < __l_bucket; ++__n)
-      _M_erase_bucket(__n, nullptr);
-    if (__l_bucket != _M_buckets.size())
-      _M_erase_bucket(__l_bucket, __last._M_cur);
-  }
-}
-
-template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
-inline void hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::erase(
-  const_iterator __first, const_iterator __last)
-{
-  erase(iterator(const_cast<_Node*>(__first._M_cur),
-                 const_cast<hashtable*>(__first._M_ht)),
-        iterator(const_cast<_Node*>(__last._M_cur),
-                 const_cast<hashtable*>(__last._M_ht)));
-}
-
-template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
-inline void hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::erase(
-  const const_iterator& __it)
-{
-  erase(iterator(const_cast<_Node*>(__it._M_cur),
-                 const_cast<hashtable*>(__it._M_ht)));
-}
-
-template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
-void hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::resize(
-  size_type __num_elements_hint)
-{
-  const size_type __old_n = _M_buckets.size();
-  if (__num_elements_hint > __old_n) {
-    const size_type __n = _M_next_size(__num_elements_hint);
-    if (__n > __old_n) {
-      _M_buckets_type __tmp(__n, (_Node*)(nullptr),
-                            _M_buckets.get_allocator());
-      try {
-        for (size_type __bucket = 0; __bucket < __old_n; ++__bucket) {
-          _Node* __first = _M_buckets[__bucket];
-          while (__first) {
-            size_type __new_bucket = _M_bkt_num(__first->_M_val, __n);
-            _M_buckets[__bucket] = __first->_M_next;
-            __first->_M_next = __tmp[__new_bucket];
-            __tmp[__new_bucket] = __first;
-            __first = _M_buckets[__bucket];
-          }
-        }
-        _M_buckets.swap(__tmp);
-      } catch (...) {
-        for (size_type __bucket = 0; __bucket < __tmp.size(); ++__bucket) {
-          while (__tmp[__bucket]) {
-            _Node* __next = __tmp[__bucket]->_M_next;
-            _M_delete_node(__tmp[__bucket]);
-            __tmp[__bucket] = __next;
-          }
-        }
-        throw;
-      }
-    }
-  }
-}
-
-template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
-void hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::_M_erase_bucket(
-  const size_type __n, _Node* __first, _Node* __last)
-{
-  _Node* __cur = _M_buckets[__n];
-  if (__cur == __first)
-    _M_erase_bucket(__n, __last);
-  else {
-    _Node* __next;
-    for (__next = __cur->_M_next; __next != __first;
-         __cur = __next, __next = __cur->_M_next)
-      ;
-    while (__next != __last) {
-      __cur->_M_next = __next->_M_next;
-      _M_delete_node(__next);
-      __next = __cur->_M_next;
-      --_M_num_elements;
-    }
-  }
-}
-
-template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
-void hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::_M_erase_bucket(
-  const size_type __n, _Node* __last)
-{
-  _Node* __cur = _M_buckets[__n];
-  while (__cur != __last) {
-    _Node* __next = __cur->_M_next;
-    _M_delete_node(__cur);
-    __cur = __next;
-    _M_buckets[__n] = __cur;
-    --_M_num_elements;
-  }
-}
-
-template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
-void hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::clear()
-{
-  for (size_type __i = 0; __i < _M_buckets.size(); ++__i) {
-    _Node* __cur = _M_buckets[__i];
-    while (__cur != nullptr) {
-      _Node* __next = __cur->_M_next;
-      _M_delete_node(__cur);
-      __cur = __next;
-    }
-    _M_buckets[__i] = nullptr;
-  }
-  _M_num_elements = 0;
-}
-
-template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
-void hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::_M_copy_from(
-  const hashtable& __ht)
-{
-  _M_buckets.clear();
-  _M_buckets.reserve(__ht._M_buckets.size());
-  _M_buckets.insert(_M_buckets.end(), __ht._M_buckets.size(), (_Node*)nullptr);
-  try {
-    for (size_type __i = 0; __i < __ht._M_buckets.size(); ++__i) {
-      const _Node* __cur = __ht._M_buckets[__i];
-      if (__cur) {
-        _Node* __copy = _M_new_node(__cur->_M_val);
-        _M_buckets[__i] = __copy;
-
-        for (_Node* __next = __cur->_M_next; __next;
-             __cur = __next, __next = __cur->_M_next) {
-          __copy->_M_next = _M_new_node(__next->_M_val);
-          __copy = __copy->_M_next;
-        }
-      }
-    }
-    _M_num_elements = __ht._M_num_elements;
-  } catch (...) {
-    clear();
-    throw;
-  }
-}
-
-} // namespace @KWSYS_NAMESPACE@
-
-// Undo warning suppression.
-#  if defined(__clang__) && defined(__has_warning)
-#    if __has_warning("-Wdeprecated")
-#      pragma clang diagnostic pop
-#    endif
-#  endif
-
-#  if defined(_MSC_VER)
-#    pragma warning(pop)
-#  endif
-
-#endif
diff --git a/Source/kwsys/kwsysPlatformTests.cmake b/Source/kwsys/kwsysPlatformTests.cmake
index 28d3f68..89be4b8 100644
--- a/Source/kwsys/kwsysPlatformTests.cmake
+++ b/Source/kwsys/kwsysPlatformTests.cmake
@@ -1,185 +1,185 @@
 # Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
 # file Copyright.txt or https://cmake.org/licensing#kwsys for details.
 
-SET(KWSYS_PLATFORM_TEST_FILE_C kwsysPlatformTestsC.c)
-SET(KWSYS_PLATFORM_TEST_FILE_CXX kwsysPlatformTestsCXX.cxx)
+set(KWSYS_PLATFORM_TEST_FILE_C kwsysPlatformTestsC.c)
+set(KWSYS_PLATFORM_TEST_FILE_CXX kwsysPlatformTestsCXX.cxx)
 
-MACRO(KWSYS_PLATFORM_TEST lang var description invert)
-  IF(NOT DEFINED ${var}_COMPILED)
-    MESSAGE(STATUS "${description}")
+macro(KWSYS_PLATFORM_TEST lang var description invert)
+  if(NOT DEFINED ${var}_COMPILED)
+    message(STATUS "${description}")
     set(maybe_cxx_standard "")
     if(CMAKE_VERSION VERSION_LESS 3.8 AND CMAKE_CXX_STANDARD)
       set(maybe_cxx_standard "-DCMAKE_CXX_STANDARD=${CMAKE_CXX_STANDARD}")
     endif()
-    TRY_COMPILE(${var}_COMPILED
+    try_compile(${var}_COMPILED
       ${CMAKE_CURRENT_BINARY_DIR}
       ${CMAKE_CURRENT_SOURCE_DIR}/${KWSYS_PLATFORM_TEST_FILE_${lang}}
       COMPILE_DEFINITIONS -DTEST_${var} ${KWSYS_PLATFORM_TEST_DEFINES} ${KWSYS_PLATFORM_TEST_EXTRA_FLAGS}
       CMAKE_FLAGS "-DLINK_LIBRARIES:STRING=${KWSYS_PLATFORM_TEST_LINK_LIBRARIES}"
                   ${maybe_cxx_standard}
       OUTPUT_VARIABLE OUTPUT)
-    IF(${var}_COMPILED)
-      FILE(APPEND
+    if(${var}_COMPILED)
+      file(APPEND
         ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
         "${description} compiled with the following output:\n${OUTPUT}\n\n")
-    ELSE()
-      FILE(APPEND
+    else()
+      file(APPEND
         ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
         "${description} failed to compile with the following output:\n${OUTPUT}\n\n")
-    ENDIF()
-    IF(${invert} MATCHES INVERT)
-      IF(${var}_COMPILED)
-        MESSAGE(STATUS "${description} - no")
-      ELSE()
-        MESSAGE(STATUS "${description} - yes")
-      ENDIF()
-    ELSE()
-      IF(${var}_COMPILED)
-        MESSAGE(STATUS "${description} - yes")
-      ELSE()
-        MESSAGE(STATUS "${description} - no")
-      ENDIF()
-    ENDIF()
-  ENDIF()
-  IF(${invert} MATCHES INVERT)
-    IF(${var}_COMPILED)
-      SET(${var} 0)
-    ELSE()
-      SET(${var} 1)
-    ENDIF()
-  ELSE()
-    IF(${var}_COMPILED)
-      SET(${var} 1)
-    ELSE()
-      SET(${var} 0)
-    ENDIF()
-  ENDIF()
-ENDMACRO()
+    endif()
+    if(${invert} MATCHES INVERT)
+      if(${var}_COMPILED)
+        message(STATUS "${description} - no")
+      else()
+        message(STATUS "${description} - yes")
+      endif()
+    else()
+      if(${var}_COMPILED)
+        message(STATUS "${description} - yes")
+      else()
+        message(STATUS "${description} - no")
+      endif()
+    endif()
+  endif()
+  if(${invert} MATCHES INVERT)
+    if(${var}_COMPILED)
+      set(${var} 0)
+    else()
+      set(${var} 1)
+    endif()
+  else()
+    if(${var}_COMPILED)
+      set(${var} 1)
+    else()
+      set(${var} 0)
+    endif()
+  endif()
+endmacro()
 
-MACRO(KWSYS_PLATFORM_TEST_RUN lang var description invert)
-  IF(NOT DEFINED ${var})
-    MESSAGE(STATUS "${description}")
-    TRY_RUN(${var} ${var}_COMPILED
+macro(KWSYS_PLATFORM_TEST_RUN lang var description invert)
+  if(NOT DEFINED ${var})
+    message(STATUS "${description}")
+    try_run(${var} ${var}_COMPILED
       ${CMAKE_CURRENT_BINARY_DIR}
       ${CMAKE_CURRENT_SOURCE_DIR}/${KWSYS_PLATFORM_TEST_FILE_${lang}}
       COMPILE_DEFINITIONS -DTEST_${var} ${KWSYS_PLATFORM_TEST_DEFINES} ${KWSYS_PLATFORM_TEST_EXTRA_FLAGS}
       OUTPUT_VARIABLE OUTPUT)
 
     # Note that ${var} will be a 0 return value on success.
-    IF(${var}_COMPILED)
-      IF(${var})
-        FILE(APPEND
+    if(${var}_COMPILED)
+      if(${var})
+        file(APPEND
           ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
           "${description} compiled but failed to run with the following output:\n${OUTPUT}\n\n")
-      ELSE()
-        FILE(APPEND
+      else()
+        file(APPEND
           ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
           "${description} compiled and ran with the following output:\n${OUTPUT}\n\n")
-      ENDIF()
-    ELSE()
-      FILE(APPEND
+      endif()
+    else()
+      file(APPEND
         ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
         "${description} failed to compile with the following output:\n${OUTPUT}\n\n")
-      SET(${var} -1 CACHE INTERNAL "${description} failed to compile.")
-    ENDIF()
+      set(${var} -1 CACHE INTERNAL "${description} failed to compile.")
+    endif()
 
-    IF(${invert} MATCHES INVERT)
-      IF(${var}_COMPILED)
-        IF(${var})
-          MESSAGE(STATUS "${description} - yes")
-        ELSE()
-          MESSAGE(STATUS "${description} - no")
-        ENDIF()
-      ELSE()
-        MESSAGE(STATUS "${description} - failed to compile")
-      ENDIF()
-    ELSE()
-      IF(${var}_COMPILED)
-        IF(${var})
-          MESSAGE(STATUS "${description} - no")
-        ELSE()
-          MESSAGE(STATUS "${description} - yes")
-        ENDIF()
-      ELSE()
-        MESSAGE(STATUS "${description} - failed to compile")
-      ENDIF()
-    ENDIF()
-  ENDIF()
+    if(${invert} MATCHES INVERT)
+      if(${var}_COMPILED)
+        if(${var})
+          message(STATUS "${description} - yes")
+        else()
+          message(STATUS "${description} - no")
+        endif()
+      else()
+        message(STATUS "${description} - failed to compile")
+      endif()
+    else()
+      if(${var}_COMPILED)
+        if(${var})
+          message(STATUS "${description} - no")
+        else()
+          message(STATUS "${description} - yes")
+        endif()
+      else()
+        message(STATUS "${description} - failed to compile")
+      endif()
+    endif()
+  endif()
 
-  IF(${invert} MATCHES INVERT)
-    IF(${var}_COMPILED)
-      IF(${var})
-        SET(${var} 1)
-      ELSE()
-        SET(${var} 0)
-      ENDIF()
-    ELSE()
-      SET(${var} 1)
-    ENDIF()
-  ELSE()
-    IF(${var}_COMPILED)
-      IF(${var})
-        SET(${var} 0)
-      ELSE()
-        SET(${var} 1)
-      ENDIF()
-    ELSE()
-      SET(${var} 0)
-    ENDIF()
-  ENDIF()
-ENDMACRO()
+  if(${invert} MATCHES INVERT)
+    if(${var}_COMPILED)
+      if(${var})
+        set(${var} 1)
+      else()
+        set(${var} 0)
+      endif()
+    else()
+      set(${var} 1)
+    endif()
+  else()
+    if(${var}_COMPILED)
+      if(${var})
+        set(${var} 0)
+      else()
+        set(${var} 1)
+      endif()
+    else()
+      set(${var} 0)
+    endif()
+  endif()
+endmacro()
 
-MACRO(KWSYS_PLATFORM_C_TEST var description invert)
-  SET(KWSYS_PLATFORM_TEST_DEFINES ${KWSYS_PLATFORM_C_TEST_DEFINES})
-  SET(KWSYS_PLATFORM_TEST_EXTRA_FLAGS ${KWSYS_PLATFORM_C_TEST_EXTRA_FLAGS})
+macro(KWSYS_PLATFORM_C_TEST var description invert)
+  set(KWSYS_PLATFORM_TEST_DEFINES ${KWSYS_PLATFORM_C_TEST_DEFINES})
+  set(KWSYS_PLATFORM_TEST_EXTRA_FLAGS ${KWSYS_PLATFORM_C_TEST_EXTRA_FLAGS})
   KWSYS_PLATFORM_TEST(C "${var}" "${description}" "${invert}")
-  SET(KWSYS_PLATFORM_TEST_DEFINES)
-  SET(KWSYS_PLATFORM_TEST_EXTRA_FLAGS)
-ENDMACRO()
+  set(KWSYS_PLATFORM_TEST_DEFINES)
+  set(KWSYS_PLATFORM_TEST_EXTRA_FLAGS)
+endmacro()
 
-MACRO(KWSYS_PLATFORM_C_TEST_RUN var description invert)
-  SET(KWSYS_PLATFORM_TEST_DEFINES ${KWSYS_PLATFORM_C_TEST_DEFINES})
-  SET(KWSYS_PLATFORM_TEST_EXTRA_FLAGS ${KWSYS_PLATFORM_C_TEST_EXTRA_FLAGS})
+macro(KWSYS_PLATFORM_C_TEST_RUN var description invert)
+  set(KWSYS_PLATFORM_TEST_DEFINES ${KWSYS_PLATFORM_C_TEST_DEFINES})
+  set(KWSYS_PLATFORM_TEST_EXTRA_FLAGS ${KWSYS_PLATFORM_C_TEST_EXTRA_FLAGS})
   KWSYS_PLATFORM_TEST_RUN(C "${var}" "${description}" "${invert}")
-  SET(KWSYS_PLATFORM_TEST_DEFINES)
-  SET(KWSYS_PLATFORM_TEST_EXTRA_FLAGS)
-ENDMACRO()
+  set(KWSYS_PLATFORM_TEST_DEFINES)
+  set(KWSYS_PLATFORM_TEST_EXTRA_FLAGS)
+endmacro()
 
-MACRO(KWSYS_PLATFORM_CXX_TEST var description invert)
-  SET(KWSYS_PLATFORM_TEST_DEFINES ${KWSYS_PLATFORM_CXX_TEST_DEFINES})
-  SET(KWSYS_PLATFORM_TEST_EXTRA_FLAGS ${KWSYS_PLATFORM_CXX_TEST_EXTRA_FLAGS})
-  SET(KWSYS_PLATFORM_TEST_LINK_LIBRARIES ${KWSYS_PLATFORM_CXX_TEST_LINK_LIBRARIES})
+macro(KWSYS_PLATFORM_CXX_TEST var description invert)
+  set(KWSYS_PLATFORM_TEST_DEFINES ${KWSYS_PLATFORM_CXX_TEST_DEFINES})
+  set(KWSYS_PLATFORM_TEST_EXTRA_FLAGS ${KWSYS_PLATFORM_CXX_TEST_EXTRA_FLAGS})
+  set(KWSYS_PLATFORM_TEST_LINK_LIBRARIES ${KWSYS_PLATFORM_CXX_TEST_LINK_LIBRARIES})
   KWSYS_PLATFORM_TEST(CXX "${var}" "${description}" "${invert}")
-  SET(KWSYS_PLATFORM_TEST_DEFINES)
-  SET(KWSYS_PLATFORM_TEST_EXTRA_FLAGS)
-  SET(KWSYS_PLATFORM_TEST_LINK_LIBRARIES)
-ENDMACRO()
+  set(KWSYS_PLATFORM_TEST_DEFINES)
+  set(KWSYS_PLATFORM_TEST_EXTRA_FLAGS)
+  set(KWSYS_PLATFORM_TEST_LINK_LIBRARIES)
+endmacro()
 
-MACRO(KWSYS_PLATFORM_CXX_TEST_RUN var description invert)
-  SET(KWSYS_PLATFORM_TEST_DEFINES ${KWSYS_PLATFORM_CXX_TEST_DEFINES})
-  SET(KWSYS_PLATFORM_TEST_EXTRA_FLAGS ${KWSYS_PLATFORM_CXX_TEST_EXTRA_FLAGS})
+macro(KWSYS_PLATFORM_CXX_TEST_RUN var description invert)
+  set(KWSYS_PLATFORM_TEST_DEFINES ${KWSYS_PLATFORM_CXX_TEST_DEFINES})
+  set(KWSYS_PLATFORM_TEST_EXTRA_FLAGS ${KWSYS_PLATFORM_CXX_TEST_EXTRA_FLAGS})
   KWSYS_PLATFORM_TEST_RUN(CXX "${var}" "${description}" "${invert}")
-  SET(KWSYS_PLATFORM_TEST_DEFINES)
-  SET(KWSYS_PLATFORM_TEST_EXTRA_FLAGS)
-ENDMACRO()
+  set(KWSYS_PLATFORM_TEST_DEFINES)
+  set(KWSYS_PLATFORM_TEST_EXTRA_FLAGS)
+endmacro()
 
 #-----------------------------------------------------------------------------
 # KWSYS_PLATFORM_INFO_TEST(lang var description)
 #
 # Compile test named by ${var} and store INFO strings extracted from binary.
-MACRO(KWSYS_PLATFORM_INFO_TEST lang var description)
+macro(KWSYS_PLATFORM_INFO_TEST lang var description)
   # We can implement this macro on CMake 2.6 and above.
-  IF("${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}" LESS 2.6)
-    SET(${var} "")
-  ELSE()
+  if("${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}" LESS 2.6)
+    set(${var} "")
+  else()
     # Choose a location for the result binary.
-    SET(KWSYS_PLATFORM_INFO_FILE
+    set(KWSYS_PLATFORM_INFO_FILE
       ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_FILES_DIRECTORY}/${var}.bin)
 
     # Compile the test binary.
-    IF(NOT EXISTS ${KWSYS_PLATFORM_INFO_FILE})
-      MESSAGE(STATUS "${description}")
-      TRY_COMPILE(${var}_COMPILED
+    if(NOT EXISTS ${KWSYS_PLATFORM_INFO_FILE})
+      message(STATUS "${description}")
+      try_compile(${var}_COMPILED
         ${CMAKE_CURRENT_BINARY_DIR}
         ${CMAKE_CURRENT_SOURCE_DIR}/${KWSYS_PLATFORM_TEST_FILE_${lang}}
         COMPILE_DEFINITIONS -DTEST_${var}
@@ -188,29 +188,29 @@
         OUTPUT_VARIABLE OUTPUT
         COPY_FILE ${KWSYS_PLATFORM_INFO_FILE}
         )
-      IF(${var}_COMPILED)
-        FILE(APPEND
+      if(${var}_COMPILED)
+        file(APPEND
           ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
           "${description} compiled with the following output:\n${OUTPUT}\n\n")
-      ELSE()
-        FILE(APPEND
+      else()
+        file(APPEND
           ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
           "${description} failed to compile with the following output:\n${OUTPUT}\n\n")
-      ENDIF()
-      IF(${var}_COMPILED)
-        MESSAGE(STATUS "${description} - compiled")
-      ELSE()
-        MESSAGE(STATUS "${description} - failed")
-      ENDIF()
-    ENDIF()
+      endif()
+      if(${var}_COMPILED)
+        message(STATUS "${description} - compiled")
+      else()
+        message(STATUS "${description} - failed")
+      endif()
+    endif()
 
     # Parse info strings out of the compiled binary.
-    IF(${var}_COMPILED)
-      FILE(STRINGS ${KWSYS_PLATFORM_INFO_FILE} ${var} REGEX "INFO:[A-Za-z0-9]+\\[[^]]*\\]")
-    ELSE()
-      SET(${var} "")
-    ENDIF()
+    if(${var}_COMPILED)
+      file(STRINGS ${KWSYS_PLATFORM_INFO_FILE} ${var} REGEX "INFO:[A-Za-z0-9]+\\[[^]]*\\]")
+    else()
+      set(${var} "")
+    endif()
 
-    SET(KWSYS_PLATFORM_INFO_FILE)
-  ENDIF()
-ENDMACRO()
+    set(KWSYS_PLATFORM_INFO_FILE)
+  endif()
+endmacro()
diff --git a/Source/kwsys/kwsysPlatformTestsC.c b/Source/kwsys/kwsysPlatformTestsC.c
index b0cf7ad..d44f7eb 100644
--- a/Source/kwsys/kwsysPlatformTestsC.c
+++ b/Source/kwsys/kwsysPlatformTestsC.c
@@ -69,40 +69,3 @@
   return clock_gettime(CLOCK_MONOTONIC, &ts);
 }
 #endif
-
-#ifdef TEST_KWSYS_C_TYPE_MACROS
-char* info_macros =
-#  if defined(__SIZEOF_SHORT__)
-  "INFO:macro[__SIZEOF_SHORT__]\n"
-#  endif
-#  if defined(__SIZEOF_INT__)
-  "INFO:macro[__SIZEOF_INT__]\n"
-#  endif
-#  if defined(__SIZEOF_LONG__)
-  "INFO:macro[__SIZEOF_LONG__]\n"
-#  endif
-#  if defined(__SIZEOF_LONG_LONG__)
-  "INFO:macro[__SIZEOF_LONG_LONG__]\n"
-#  endif
-#  if defined(__SHORT_MAX__)
-  "INFO:macro[__SHORT_MAX__]\n"
-#  endif
-#  if defined(__INT_MAX__)
-  "INFO:macro[__INT_MAX__]\n"
-#  endif
-#  if defined(__LONG_MAX__)
-  "INFO:macro[__LONG_MAX__]\n"
-#  endif
-#  if defined(__LONG_LONG_MAX__)
-  "INFO:macro[__LONG_LONG_MAX__]\n"
-#  endif
-  "";
-
-int KWSYS_PLATFORM_TEST_C_MAIN_ARGS(argc, argv)
-{
-  int require = 0;
-  require += info_macros[argc];
-  (void)argv;
-  return require;
-}
-#endif
diff --git a/Source/kwsys/kwsysPlatformTestsCXX.cxx b/Source/kwsys/kwsysPlatformTestsCXX.cxx
index cfd5666..0bfa20e 100644
--- a/Source/kwsys/kwsysPlatformTestsCXX.cxx
+++ b/Source/kwsys/kwsysPlatformTestsCXX.cxx
@@ -1,36 +1,5 @@
 /* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
    file Copyright.txt or https://cmake.org/licensing#kwsys for details.  */
-#ifdef TEST_KWSYS_CXX_HAS_CSTDIO
-#  include <cstdio>
-int main()
-{
-  return 0;
-}
-#endif
-
-#ifdef TEST_KWSYS_CXX_HAS_LONG_LONG
-long long f(long long n)
-{
-  return n;
-}
-int main()
-{
-  long long n = 0;
-  return static_cast<int>(f(n));
-}
-#endif
-
-#ifdef TEST_KWSYS_CXX_HAS___INT64
-__int64 f(__int64 n)
-{
-  return n;
-}
-int main()
-{
-  __int64 n = 0;
-  return static_cast<int>(f(n));
-}
-#endif
 
 #ifdef TEST_KWSYS_CXX_STAT_HAS_ST_MTIM
 #  include <sys/types.h>
@@ -60,82 +29,6 @@
 }
 #endif
 
-#ifdef TEST_KWSYS_CXX_SAME_LONG_AND___INT64
-void function(long**)
-{
-}
-int main()
-{
-  __int64** p = 0;
-  function(p);
-  return 0;
-}
-#endif
-
-#ifdef TEST_KWSYS_CXX_SAME_LONG_LONG_AND___INT64
-void function(long long**)
-{
-}
-int main()
-{
-  __int64** p = 0;
-  function(p);
-  return 0;
-}
-#endif
-
-#ifdef TEST_KWSYS_IOS_HAS_ISTREAM_LONG_LONG
-#  include <iostream>
-int test_istream(std::istream& is, long long& x)
-{
-  return (is >> x) ? 1 : 0;
-}
-int main()
-{
-  long long x = 0;
-  return test_istream(std::cin, x);
-}
-#endif
-
-#ifdef TEST_KWSYS_IOS_HAS_OSTREAM_LONG_LONG
-#  include <iostream>
-int test_ostream(std::ostream& os, long long x)
-{
-  return (os << x) ? 1 : 0;
-}
-int main()
-{
-  long long x = 0;
-  return test_ostream(std::cout, x);
-}
-#endif
-
-#ifdef TEST_KWSYS_IOS_HAS_ISTREAM___INT64
-#  include <iostream>
-int test_istream(std::istream& is, __int64& x)
-{
-  return (is >> x) ? 1 : 0;
-}
-int main()
-{
-  __int64 x = 0;
-  return test_istream(std::cin, x);
-}
-#endif
-
-#ifdef TEST_KWSYS_IOS_HAS_OSTREAM___INT64
-#  include <iostream>
-int test_ostream(std::ostream& os, __int64 x)
-{
-  return (os << x) ? 1 : 0;
-}
-int main()
-{
-  __int64 x = 0;
-  return test_ostream(std::cout, x);
-}
-#endif
-
 #ifdef TEST_KWSYS_CXX_HAS_SETENV
 #  include <stdlib.h>
 int main()
@@ -184,33 +77,6 @@
 }
 #endif
 
-#ifdef TEST_KWSYS_CXX_HAS_ATOLL
-#  include <stdlib.h>
-int main()
-{
-  const char* str = "1024";
-  return static_cast<int>(atoll(str));
-}
-#endif
-
-#ifdef TEST_KWSYS_CXX_HAS_ATOL
-#  include <stdlib.h>
-int main()
-{
-  const char* str = "1024";
-  return static_cast<int>(atol(str));
-}
-#endif
-
-#ifdef TEST_KWSYS_CXX_HAS__ATOI64
-#  include <stdlib.h>
-int main()
-{
-  const char* str = "1024";
-  return static_cast<int>(_atoi64(str));
-}
-#endif
-
 #ifdef TEST_KWSYS_CXX_HAS_UTIMES
 #  include <sys/time.h>
 int main()
@@ -288,33 +154,6 @@
 }
 #endif
 
-#ifdef TEST_KWSYS_CXX_HAS_BORLAND_ASM
-int main()
-{
-  int a = 1;
-  __asm {
-    xor EBX, EBX;
-    mov a, EBX;
-  }
-
-  return a;
-}
-#endif
-
-#ifdef TEST_KWSYS_CXX_HAS_BORLAND_ASM_CPUID
-int main()
-{
-  int a = 0;
-  __asm {
-    xor EAX, EAX;
-    cpuid;
-    mov a, EAX;
-  }
-
-  return a;
-}
-#endif
-
 #ifdef TEST_KWSYS_STL_HAS_WSTRING
 #  include <string>
 void f(std::wstring*)
diff --git a/Source/kwsys/testCommandLineArguments.cxx b/Source/kwsys/testCommandLineArguments.cxx
index 1778a9b..0786751 100644
--- a/Source/kwsys/testCommandLineArguments.cxx
+++ b/Source/kwsys/testCommandLineArguments.cxx
@@ -12,8 +12,8 @@
 #include <iostream>
 #include <vector>
 
-#include <stddef.h> /* size_t */
-#include <string.h> /* strcmp */
+#include <cstddef> /* size_t */
+#include <cstring> /* strcmp */
 
 static void* random_ptr = reinterpret_cast<void*>(0x123);
 
@@ -98,7 +98,7 @@
   std::vector<std::string> stl_strings_argument;
   std::string valid_stl_strings[] = { "ken", "brad", "bill", "andy" };
 
-  typedef kwsys::CommandLineArguments argT;
+  using argT = kwsys::CommandLineArguments;
 
   arg.AddArgument("--some-int-variable", argT::SPACE_ARGUMENT,
                   &some_int_variable, "Set some random int variable");
diff --git a/Source/kwsys/testCommandLineArguments1.cxx b/Source/kwsys/testCommandLineArguments1.cxx
index 64561b1..2f6b735 100644
--- a/Source/kwsys/testCommandLineArguments1.cxx
+++ b/Source/kwsys/testCommandLineArguments1.cxx
@@ -12,8 +12,8 @@
 #include <iostream>
 #include <vector>
 
-#include <assert.h> /* assert */
-#include <string.h> /* strcmp */
+#include <cassert> /* assert */
+#include <cstring> /* strcmp */
 
 int testCommandLineArguments1(int argc, char* argv[])
 {
@@ -25,7 +25,7 @@
   std::string p;
   int res = 0;
 
-  typedef kwsys::CommandLineArguments argT;
+  using argT = kwsys::CommandLineArguments;
   arg.AddArgument("-n", argT::SPACE_ARGUMENT, &n, "Argument N");
   arg.AddArgument("-m", argT::EQUAL_ARGUMENT, &m, "Argument M");
   arg.AddBooleanArgument("-p", &p, "Argument P");
@@ -51,9 +51,7 @@
   std::cout << "Value of N: " << n << std::endl;
   std::cout << "Value of M: " << m << std::endl;
   std::cout << "Value of P: " << p << std::endl;
-  if (m) {
-    delete[] m;
-  }
+  delete[] m;
 
   char** newArgv = nullptr;
   int newArgc = 0;
diff --git a/Source/kwsys/testDirectory.cxx b/Source/kwsys/testDirectory.cxx
index b1ab0c8..eb3ca32 100644
--- a/Source/kwsys/testDirectory.cxx
+++ b/Source/kwsys/testDirectory.cxx
@@ -57,7 +57,11 @@
 
     Directory testdir;
     // Set res to failure if the directory doesn't load
-    res += !testdir.Load(testdirpath);
+    std::string errorMessage = "";
+    res += !testdir.Load(testdirpath, &errorMessage);
+    if (errorMessage != "") {
+      std::cerr << "Failed to list directory: " << errorMessage << std::endl;
+    }
     // Increment res failure if the directory appears empty
     res += testdir.GetNumberOfFiles() == 0;
     // Increment res failures if the path has changed from
@@ -73,6 +77,34 @@
   return res;
 }
 
+int _nonExistentDirectoryTest()
+{
+  using namespace kwsys;
+  int res = 0;
+  std::string testdirpath(TEST_SYSTEMTOOLS_BINARY_DIR
+                          "/directory_testing/doesnt_exist/");
+  std::string errorMessage;
+  Directory testdir;
+
+  errorMessage = "foo";
+  // Increment res failure if directory lists
+  res += testdir.Load(testdirpath, &errorMessage);
+#if !defined(_WIN32) || defined(__CYGWIN__)
+  // Increment res failure if errorMessage is unmodified
+  res += (errorMessage == "foo");
+#endif
+
+  errorMessage = "foo";
+  // Increment res failure if directory has files
+  res += (testdir.GetNumberOfFilesInDirectory(testdirpath, &errorMessage) > 0);
+#if !defined(_WIN32) || defined(__CYGWIN__)
+  // Increment res failure if errorMessage is unmodified
+  res += (errorMessage == "foo");
+#endif
+
+  return res;
+}
+
 int _copyDirectoryTest()
 {
   using namespace kwsys;
@@ -106,5 +138,6 @@
 
 int testDirectory(int, char* [])
 {
-  return _doLongPathTest() + _copyDirectoryTest();
+  return _doLongPathTest() + _nonExistentDirectoryTest() +
+    _copyDirectoryTest();
 }
diff --git a/Source/kwsys/testDynamicLoader.cxx b/Source/kwsys/testDynamicLoader.cxx
index 2421ac0..703ad4d 100644
--- a/Source/kwsys/testDynamicLoader.cxx
+++ b/Source/kwsys/testDynamicLoader.cxx
@@ -25,7 +25,7 @@
 {
   // Construct proper name of lib
   std::string slname;
-  slname = EXECUTABLE_OUTPUT_PATH;
+  slname = RUNTIME_OUTPUT_DIRECTORY;
   if (subdir) {
     slname += "/";
     slname += subdir;
diff --git a/Source/kwsys/testDynload.c b/Source/kwsys/testDynload.c
index c49f747..33a431e 100644
--- a/Source/kwsys/testDynload.c
+++ b/Source/kwsys/testDynload.c
@@ -8,6 +8,6 @@
 
 DL_EXPORT int TestDynamicLoaderData = 0;
 
-DL_EXPORT void TestDynamicLoaderSymbolPointer()
+DL_EXPORT void TestDynamicLoaderSymbolPointer(void)
 {
 }
diff --git a/Source/kwsys/testEncoding.cxx b/Source/kwsys/testEncoding.cxx
index 988697b..ee93e8d 100644
--- a/Source/kwsys/testEncoding.cxx
+++ b/Source/kwsys/testEncoding.cxx
@@ -10,10 +10,10 @@
 #include KWSYS_HEADER(Encoding.h)
 
 #include <algorithm>
+#include <clocale>
+#include <cstdlib>
+#include <cstring>
 #include <iostream>
-#include <locale.h>
-#include <stdlib.h>
-#include <string.h>
 
 // Work-around CMake dependency scanning limitation.  This must
 // duplicate the above list of headers.
@@ -59,7 +59,7 @@
     std::string str2 = kwsys::Encoding::ToNarrow(wstr);
     wchar_t* c_wstr = kwsysEncoding_DupToWide(str.c_str());
     char* c_str2 = kwsysEncoding_DupToNarrow(c_wstr);
-    if (!wstr.empty() && (str != str2 || strcmp(c_str2, str.c_str()))) {
+    if (!wstr.empty() && (str != str2 || strcmp(c_str2, str.c_str()) != 0)) {
       std::cout << "converted string was different: " << str2 << std::endl;
       std::cout << "converted string was different: " << c_str2 << std::endl;
       ret++;
@@ -85,7 +85,7 @@
   std::wstring wstr = kwsys::Encoding::ToWide(cstr);
 
   wstr = kwsys::Encoding::ToWide(nullptr);
-  if (wstr != L"") {
+  if (!wstr.empty()) {
     const wchar_t* wcstr = wstr.c_str();
     std::cout << "ToWide(NULL) returned";
     for (size_t i = 0; i < wstr.size(); i++) {
@@ -95,7 +95,7 @@
     ret++;
   }
   wstr = kwsys::Encoding::ToWide("");
-  if (wstr != L"") {
+  if (!wstr.empty()) {
     const wchar_t* wcstr = wstr.c_str();
     std::cout << "ToWide(\"\") returned";
     for (size_t i = 0; i < wstr.size(); i++) {
@@ -113,13 +113,13 @@
 #endif
 
   std::string str = kwsys::Encoding::ToNarrow(nullptr);
-  if (str != "") {
+  if (!str.empty()) {
     std::cout << "ToNarrow(NULL) returned " << str << std::endl;
     ret++;
   }
 
   str = kwsys::Encoding::ToNarrow(L"");
-  if (wstr != L"") {
+  if (!wstr.empty()) {
     std::cout << "ToNarrow(\"\") returned " << str << std::endl;
     ret++;
   }
@@ -140,14 +140,13 @@
   strings.push_back(std::string("k") + '\0' + '\0');
   strings.push_back(std::string("\0\0\0\0", 4) + "lmn" +
                     std::string("\0\0\0\0", 4));
-  for (std::vector<std::string>::iterator it = strings.begin();
-       it != strings.end(); ++it) {
-    std::wstring wstr = kwsys::Encoding::ToWide(*it);
+  for (auto& string : strings) {
+    std::wstring wstr = kwsys::Encoding::ToWide(string);
     std::string str = kwsys::Encoding::ToNarrow(wstr);
-    std::string s(*it);
+    std::string s(string);
     std::replace(s.begin(), s.end(), '\0', ' ');
-    std::cout << "'" << s << "' (" << it->size() << ")" << std::endl;
-    if (str != *it) {
+    std::cout << "'" << s << "' (" << string.size() << ")" << std::endl;
+    if (str != string) {
       std::replace(str.begin(), str.end(), '\0', ' ');
       std::cout << "string with null was different: '" << str << "' ("
                 << str.size() << ")" << std::endl;
diff --git a/Source/kwsys/testFStream.cxx b/Source/kwsys/testFStream.cxx
index 5009e98..afba953 100644
--- a/Source/kwsys/testFStream.cxx
+++ b/Source/kwsys/testFStream.cxx
@@ -7,10 +7,7 @@
 #endif
 
 #include KWSYS_HEADER(FStream.hxx)
-#include <string.h>
-#ifdef __BORLANDC__
-#  include <mem.h> /* memcmp */
-#endif
+#include <cstring>
 
 // Work-around CMake dependency scanning limitation.  This must
 // duplicate the above list of headers.
diff --git a/Source/kwsys/testHashSTL.cxx b/Source/kwsys/testHashSTL.cxx
deleted file mode 100644
index 4ed2f89..0000000
--- a/Source/kwsys/testHashSTL.cxx
+++ /dev/null
@@ -1,64 +0,0 @@
-/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
-   file Copyright.txt or https://cmake.org/licensing#kwsys for details.  */
-#include "kwsysPrivate.h"
-#include KWSYS_HEADER(hash_map.hxx)
-#include KWSYS_HEADER(hash_set.hxx)
-
-// Work-around CMake dependency scanning limitation.  This must
-// duplicate the above list of headers.
-#if 0
-#  include "hash_map.hxx.in"
-#  include "hash_set.hxx.in"
-#endif
-
-#include <iostream>
-
-#if defined(_MSC_VER)
-#  pragma warning(disable : 4786)
-#endif
-
-#if defined(__sgi) && !defined(__GNUC__)
-#  pragma set woff 1468 /* inline function cannot be explicitly instantiated  \
-                         */
-#endif
-
-template class kwsys::hash_map<const char*, int>;
-template class kwsys::hash_set<int>;
-
-static bool test_hash_map()
-{
-  typedef kwsys::hash_map<const char*, int> mtype;
-  mtype m;
-  const char* keys[] = { "hello", "world" };
-  m[keys[0]] = 1;
-  m.insert(mtype::value_type(keys[1], 2));
-  int sum = 0;
-  for (mtype::iterator mi = m.begin(); mi != m.end(); ++mi) {
-    std::cout << "Found entry [" << mi->first << "," << mi->second << "]"
-              << std::endl;
-    sum += mi->second;
-  }
-  return sum == 3;
-}
-
-static bool test_hash_set()
-{
-  typedef kwsys::hash_set<int> stype;
-  stype s;
-  s.insert(1);
-  s.insert(2);
-  int sum = 0;
-  for (stype::iterator si = s.begin(); si != s.end(); ++si) {
-    std::cout << "Found entry [" << *si << "]" << std::endl;
-    sum += *si;
-  }
-  return sum == 3;
-}
-
-int testHashSTL(int, char* [])
-{
-  bool result = true;
-  result = test_hash_map() && result;
-  result = test_hash_set() && result;
-  return result ? 0 : 1;
-}
diff --git a/Source/kwsys/testProcess.c b/Source/kwsys/testProcess.c
index 39aaa23..eed770c 100644
--- a/Source/kwsys/testProcess.c
+++ b/Source/kwsys/testProcess.c
@@ -24,10 +24,6 @@
 #  include <unistd.h>
 #endif
 
-#if defined(__BORLANDC__)
-#  pragma warn - 8060 /* possibly incorrect assignment */
-#endif
-
 /* Platform-specific sleep functions. */
 
 #if defined(__BEOS__) && !defined(__ZETA__)
@@ -454,24 +450,25 @@
       printf("The process is still executing.\n");
       break;
     case kwsysProcess_State_Expired:
-      printf("Child was killed when timeout expired.\n");
+      printf("Subprocess was killed when timeout expired.\n");
       break;
     case kwsysProcess_State_Exited:
-      printf("Child exited with value = %d\n", kwsysProcess_GetExitValue(kp));
+      printf("Subprocess exited with value = %d\n",
+             kwsysProcess_GetExitValue(kp));
       result = ((exception != kwsysProcess_GetExitException(kp)) ||
                 (value != kwsysProcess_GetExitValue(kp)));
       break;
     case kwsysProcess_State_Killed:
-      printf("Child was killed by parent.\n");
+      printf("Subprocess was killed by parent.\n");
       break;
     case kwsysProcess_State_Exception:
-      printf("Child terminated abnormally: %s\n",
+      printf("Subprocess terminated abnormally: %s\n",
              kwsysProcess_GetExceptionString(kp));
       result = ((exception != kwsysProcess_GetExitException(kp)) ||
                 (value != kwsysProcess_GetExitValue(kp)));
       break;
     case kwsysProcess_State_Disowned:
-      printf("Child was disowned.\n");
+      printf("Subprocess was disowned.\n");
       break;
     case kwsysProcess_State_Error:
       printf("Error in administrating child process: [%s]\n",
@@ -631,7 +628,8 @@
     }
     fprintf(stderr, "Invalid test number %d.\n", n);
     return 1;
-  } else if (n >= 1 && n <= 10) {
+  }
+  if (n >= 1 && n <= 10) {
     /* This is the parent process for a requested test number.  */
     int states[10] = {
       kwsysProcess_State_Exited,   kwsysProcess_State_Exited,
@@ -709,7 +707,8 @@
     free(argv0);
 #endif
     return r;
-  } else if (argc > 2 && strcmp(argv[1], "0") == 0) {
+  }
+  if (argc > 2 && strcmp(argv[1], "0") == 0) {
     /* This is the special debugging test to run a given command
        line.  */
     const char** cmd = argv + 2;
@@ -720,9 +719,8 @@
     int r =
       runChild(cmd, state, exception, value, 0, 1, 0, timeout, 0, 1, 0, 0, 0);
     return r;
-  } else {
-    /* Improper usage.  */
-    fprintf(stdout, "Usage: %s <test number>\n", argv[0]);
-    return 1;
   }
+  /* Improper usage.  */
+  fprintf(stdout, "Usage: %s <test number>\n", argv[0]);
+  return 1;
 }
diff --git a/Source/kwsys/testSystemInformation.cxx b/Source/kwsys/testSystemInformation.cxx
index 154517e..4f0c522 100644
--- a/Source/kwsys/testSystemInformation.cxx
+++ b/Source/kwsys/testSystemInformation.cxx
@@ -11,29 +11,13 @@
 
 #include <iostream>
 
-#if defined(KWSYS_USE_LONG_LONG)
-#  if defined(KWSYS_IOS_HAS_OSTREAM_LONG_LONG)
-#    define iostreamLongLong(x) (x)
-#  else
-#    define iostreamLongLong(x) ((long)x)
-#  endif
-#elif defined(KWSYS_USE___INT64)
-#  if defined(KWSYS_IOS_HAS_OSTREAM___INT64)
-#    define iostreamLongLong(x) (x)
-#  else
-#    define iostreamLongLong(x) ((long)x)
-#  endif
-#else
-#  error "No Long Long"
-#endif
-
 #define printMethod(info, m) std::cout << #m << ": " << info.m() << "\n"
 
 #define printMethod2(info, m, unit)                                           \
   std::cout << #m << ": " << info.m() << " " << unit << "\n"
 
 #define printMethod3(info, m, unit)                                           \
-  std::cout << #m << ": " << iostreamLongLong(info.m) << " " << unit << "\n"
+  std::cout << #m << ": " << info.m << " " << unit << "\n"
 
 int testSystemInformation(int, char* [])
 {
diff --git a/Source/kwsys/testSystemTools.cxx b/Source/kwsys/testSystemTools.cxx
index 3f6eeb8..cfa420d 100644
--- a/Source/kwsys/testSystemTools.cxx
+++ b/Source/kwsys/testSystemTools.cxx
@@ -20,18 +20,18 @@
 // left on disk.
 #include <testSystemTools.h>
 
+#include <cstdlib> /* free */
+#include <cstring> /* strcmp */
 #include <iostream>
 #include <sstream>
-#include <stdlib.h> /* free */
-#include <string.h> /* strcmp */
 #if defined(_WIN32) && !defined(__CYGWIN__)
-#  include <io.h> /* _umask (MSVC) / umask (Borland) */
+#  include <io.h> /* _umask (MSVC) */
 #  ifdef _MSC_VER
-#    define umask _umask // Note this is still umask on Borland
+#    define umask _umask
 #  endif
 #endif
 #include <sys/stat.h> /* umask (POSIX), _S_I* constants (Windows) */
-// Visual C++ does not define mode_t (note that Borland does, however).
+// Visual C++ does not define mode_t.
 #if defined(_MSC_VER)
 typedef unsigned short mode_t;
 #endif
@@ -328,7 +328,14 @@
   }
 
   // While we're at it, check proper TestFileAccess functionality.
-  if (kwsys::SystemTools::TestFileAccess(testNewFile,
+  bool do_write_test = true;
+#if defined(__linux__)
+  // If we are running as root on linux ignore this check, as
+  // root can always write to files
+  do_write_test = (getuid() != 0);
+#endif
+  if (do_write_test &&
+      kwsys::SystemTools::TestFileAccess(testNewFile,
                                          kwsys::TEST_FILE_WRITE)) {
     std::cerr
       << "TestFileAccess incorrectly indicated that this is a writable file:"
@@ -415,6 +422,28 @@
     res = false;
   }
 
+#if !defined(_WIN32)
+  std::string const testBadSymlink(testNewDir + "/badSymlink.txt");
+  std::string const testBadSymlinkTgt(testNewDir + "/missing/symlinkTgt.txt");
+  if (!kwsys::SystemTools::CreateSymlink(testBadSymlinkTgt, testBadSymlink)) {
+    std::cerr << "Problem with CreateSymlink for: " << testBadSymlink << " -> "
+              << testBadSymlinkTgt << std::endl;
+    res = false;
+  }
+
+  if (!kwsys::SystemTools::Touch(testBadSymlink, false)) {
+    std::cerr << "Problem with Touch (no create) for: " << testBadSymlink
+              << std::endl;
+    res = false;
+  }
+#endif
+
+  if (!kwsys::SystemTools::Touch(testNewDir, false)) {
+    std::cerr << "Problem with Touch (no create) for: " << testNewDir
+              << std::endl;
+    res = false;
+  }
+
   kwsys::SystemTools::Touch(testNewFile, true);
   if (!kwsys::SystemTools::RemoveADirectory(testNewDir)) {
     std::cerr << "Problem with RemoveADirectory for: " << testNewDir
@@ -500,7 +529,7 @@
 
   char* cres =
     kwsys::SystemTools::AppendStrings("Mary Had A", " Little Lamb.");
-  if (strcmp(cres, "Mary Had A Little Lamb.")) {
+  if (strcmp(cres, "Mary Had A Little Lamb.") != 0) {
     std::cerr << "Problem with AppendStrings "
               << "\"Mary Had A\" \" Little Lamb.\"" << std::endl;
     res = false;
@@ -508,7 +537,7 @@
   delete[] cres;
 
   cres = kwsys::SystemTools::AppendStrings("Mary Had", " A ", "Little Lamb.");
-  if (strcmp(cres, "Mary Had A Little Lamb.")) {
+  if (strcmp(cres, "Mary Had A Little Lamb.") != 0) {
     std::cerr << "Problem with AppendStrings "
               << "\"Mary Had\" \" A \" \"Little Lamb.\"" << std::endl;
     res = false;
@@ -522,7 +551,7 @@
   }
 
   cres = kwsys::SystemTools::RemoveChars("Mary Had A Little Lamb.", "aeiou");
-  if (strcmp(cres, "Mry Hd A Lttl Lmb.")) {
+  if (strcmp(cres, "Mry Hd A Lttl Lmb.") != 0) {
     std::cerr << "Problem with RemoveChars "
               << "\"Mary Had A Little Lamb.\"" << std::endl;
     res = false;
@@ -530,7 +559,7 @@
   delete[] cres;
 
   cres = kwsys::SystemTools::RemoveCharsButUpperHex("Mary Had A Little Lamb.");
-  if (strcmp(cres, "A")) {
+  if (strcmp(cres, "A") != 0) {
     std::cerr << "Problem with RemoveCharsButUpperHex "
               << "\"Mary Had A Little Lamb.\"" << std::endl;
     res = false;
@@ -539,7 +568,7 @@
 
   char* cres2 = strdup("Mary Had A Little Lamb.");
   kwsys::SystemTools::ReplaceChars(cres2, "aeiou", 'X');
-  if (strcmp(cres2, "MXry HXd A LXttlX LXmb.")) {
+  if (strcmp(cres2, "MXry HXd A LXttlX LXmb.") != 0) {
     std::cerr << "Problem with ReplaceChars "
               << "\"Mary Had A Little Lamb.\"" << std::endl;
     res = false;
@@ -561,7 +590,7 @@
   }
 
   cres = kwsys::SystemTools::DuplicateString("Mary Had A Little Lamb.");
-  if (strcmp(cres, "Mary Had A Little Lamb.")) {
+  if (strcmp(cres, "Mary Had A Little Lamb.") != 0) {
     std::cerr << "Problem with DuplicateString "
               << "\"Mary Had A Little Lamb.\"" << std::endl;
     res = false;
@@ -721,8 +750,7 @@
 {
   std::stringstream ss;
   ss << "vector(";
-  for (std::vector<std::string>::const_iterator i = vec.begin();
-       i != vec.end(); ++i) {
+  for (auto i = vec.begin(); i != vec.end(); ++i) {
     if (i != vec.begin()) {
       ss << ", ";
     }
@@ -743,16 +771,16 @@
   const char* registryPath = "[HKEY_LOCAL_MACHINE\\SOFTWARE\\MyApp; MyKey]";
 
   std::vector<std::string> originalPaths;
-  originalPaths.push_back(registryPath);
+  originalPaths.emplace_back(registryPath);
 
   std::vector<std::string> expectedPaths;
-  expectedPaths.push_back(registryPath);
+  expectedPaths.emplace_back(registryPath);
 #ifdef _WIN32
   expectedPaths.push_back("C:/Somewhere/something");
   expectedPaths.push_back("D:/Temp");
 #else
-  expectedPaths.push_back("/Somewhere/something");
-  expectedPaths.push_back("/tmp");
+  expectedPaths.emplace_back("/Somewhere/something");
+  expectedPaths.emplace_back("/tmp");
 #endif
 
   bool res = true;
@@ -817,7 +845,7 @@
   }
 
   std::vector<std::string> searchPaths;
-  searchPaths.push_back(TEST_SYSTEMTOOLS_BINARY_DIR);
+  searchPaths.emplace_back(TEST_SYSTEMTOOLS_BINARY_DIR);
   if (kwsys::SystemTools::FindFile(testFindFileName, searchPaths, true)
         .empty()) {
     std::cerr << "Problem with FindFile without system paths for: "
@@ -1086,6 +1114,70 @@
   return ret;
 }
 
+static bool CheckURLParsing()
+{
+  bool ret = true;
+  std::string url = "http://user:pw@hostname:42/full/url.com";
+
+  std::string protocol, username, password, hostname, dataport, database;
+  kwsys::SystemTools::ParseURL(url, protocol, username, password, hostname,
+                               dataport, database);
+  if (protocol != "http" || username != "user" || password != "pw" ||
+      hostname != "hostname" || dataport != "42" ||
+      database != "full/url.com") {
+    std::cerr << "Incorrect URL parsing" << std::endl;
+    ret = false;
+  }
+
+  std::string uri =
+    "file://hostname/path/to/"
+    "a%20file%20with%20str%C3%A0ng%C3%A8%20ch%40r%20and%20s%C2%B5aces";
+  kwsys::SystemTools::ParseURL(uri, protocol, username, password, hostname,
+                               dataport, database, true);
+  if (protocol != "file" || hostname != "hostname" ||
+      database != "path/to/a file with stràngè ch@r and sµaces") {
+    std::cerr << "Incorrect URL parsing or decoding" << std::endl;
+    ret = false;
+  }
+  return ret;
+}
+
+static bool CheckSplitString()
+{
+  bool ret = true;
+
+  auto check_split = [](std::string const& input,
+                        std::initializer_list<const char*> expected) -> bool {
+    auto const components = kwsys::SystemTools::SplitString(input, '/');
+    if (components.size() != expected.size()) {
+      std::cerr << "Incorrect split count for " << input << ": "
+                << components.size() << std::endl;
+      return false;
+    }
+    size_t i = 0;
+    for (auto& part : expected) {
+      if (components[i] != part) {
+        std::cerr << "Incorrect split component " << i << " for " << input
+                  << ": " << components[i] << std::endl;
+        return false;
+      }
+      ++i;
+    }
+    return true;
+  };
+
+  // No separators
+  ret &= check_split("nosep", { "nosep" });
+  // Simple
+  ret &= check_split("first/second", { "first", "second" });
+  // Separator at beginning
+  ret &= check_split("/starts/sep", { "", "starts", "sep" });
+  // Separator at end
+  ret &= check_split("ends/sep/", { "ends", "sep", "" });
+
+  return ret;
+}
+
 int testSystemTools(int, char* [])
 {
   bool res = true;
@@ -1133,5 +1225,9 @@
 
   res &= CheckCopyFileIfDifferent();
 
+  res &= CheckURLParsing();
+
+  res &= CheckSplitString();
+
   return res ? 0 : 1;
 }
diff --git a/Source/kwsys/testSystemTools.h.in b/Source/kwsys/testSystemTools.h.in
index 022e36e..e4b89a7 100644
--- a/Source/kwsys/testSystemTools.h.in
+++ b/Source/kwsys/testSystemTools.h.in
@@ -3,7 +3,7 @@
 #ifndef @KWSYS_NAMESPACE@_testSystemtools_h
 #define @KWSYS_NAMESPACE@_testSystemtools_h
 
-#define EXECUTABLE_OUTPUT_PATH "@CMAKE_CURRENT_BINARY_DIR@"
+#define RUNTIME_OUTPUT_DIRECTORY "@CMAKE_CURRENT_BINARY_DIR@"
 
 #define TEST_SYSTEMTOOLS_SOURCE_DIR "@TEST_SYSTEMTOOLS_SOURCE_DIR@"
 #define TEST_SYSTEMTOOLS_BINARY_DIR "@TEST_SYSTEMTOOLS_BINARY_DIR@"
diff --git a/Templates/TestDriver.cxx.in b/Templates/TestDriver.cxx.in
index 846a828..053f1ee 100644
--- a/Templates/TestDriver.cxx.in
+++ b/Templates/TestDriver.cxx.in
@@ -45,7 +45,8 @@
    (note that it has to be free'd manually) */
 static char* lowercase(const char* string)
 {
-  char *new_string, *p;
+  char *new_string;
+  char *p;
   size_t stringSize;
 
   stringSize = CM_CAST(size_t, strlen(string) + 1);
@@ -63,7 +64,9 @@
 
 int main(int ac, char* av[])
 {
-  int i, testNum = 0, partial_match;
+  int i;
+  int testNum = 0;
+  int partial_match;
   char *arg;
   int testToRun = -1;
 
diff --git a/Tests/BuildDepends/CMakeLists.txt b/Tests/BuildDepends/CMakeLists.txt
index c1ad17c..5ddae83 100644
--- a/Tests/BuildDepends/CMakeLists.txt
+++ b/Tests/BuildDepends/CMakeLists.txt
@@ -368,6 +368,28 @@
   ${TEST_LINK_DEPENDS}
 ")
   endif()
+
+  set(linkdep3 ${BuildDepends_BINARY_DIR}/Project/linkdep3${CMAKE_EXECUTABLE_SUFFIX})
+  if(${linkdep3} IS_NEWER_THAN ${TEST_LINK_DEPENDS})
+    message("$<LINK_LANGUAGE> in LINK_DEPENDS worked")
+  else()
+    message(SEND_ERROR "$<LINK_LANGUAGE> in LINK_DEPENDS failed.  Executable
+  ${linkdep3}
+is not newer than dependency
+  ${TEST_LINK_DEPENDS}
+")
+  endif()
+
+  set(linkdep4 ${BuildDepends_BINARY_DIR}/Project/linkdep4${CMAKE_EXECUTABLE_SUFFIX})
+  if(${linkdep4} IS_NEWER_THAN ${TEST_LINK_DEPENDS})
+    message("$<LINK_LANGUAGE> in INTERFACE_LINK_DEPENDS worked")
+  else()
+    message(SEND_ERROR "$<LINK_LANGUAGE> in INTERFACE_LINK_DEPENDS failed.  Executable
+  ${linkdep4}
+is not newer than dependency
+  ${TEST_LINK_DEPENDS}
+")
+  endif()
 endif()
 
 if(EXISTS "${link_depends_no_shared_check_txt}")
diff --git a/Tests/BuildDepends/Project/CMakeLists.txt b/Tests/BuildDepends/Project/CMakeLists.txt
index 8338800..83583c9 100644
--- a/Tests/BuildDepends/Project/CMakeLists.txt
+++ b/Tests/BuildDepends/Project/CMakeLists.txt
@@ -118,6 +118,14 @@
   set_property(TARGET foo_interface PROPERTY INTERFACE_LINK_DEPENDS $<1:${TEST_LINK_DEPENDS}>)
   add_executable(linkdep2 linkdep.cxx)
   target_link_libraries(linkdep2 PRIVATE foo_interface)
+
+  add_executable(linkdep3 linkdep.cxx)
+  set_property(TARGET linkdep3 PROPERTY LINK_DEPENDS $<$<LINK_LANGUAGE:CXX>:${TEST_LINK_DEPENDS}>)
+
+  add_library(foo_interface2 INTERFACE)
+  set_property(TARGET foo_interface2 PROPERTY INTERFACE_LINK_DEPENDS $<$<LINK_LANGUAGE:CXX>:${TEST_LINK_DEPENDS}>)
+  add_executable(linkdep4 linkdep.cxx)
+  target_link_libraries(linkdep4 PRIVATE foo_interface2)
 endif()
 
 add_library(link_depends_no_shared_lib SHARED link_depends_no_shared_lib.c
diff --git a/Tests/CMakeLib/CMakeLists.txt b/Tests/CMakeLib/CMakeLists.txt
index bb50d76..0b2c8f6 100644
--- a/Tests/CMakeLib/CMakeLists.txt
+++ b/Tests/CMakeLib/CMakeLists.txt
@@ -29,6 +29,9 @@
   testCMExtMemory.cxx
   testCMExtAlgorithm.cxx
   )
+if (CMake_TEST_FILESYSTEM_PATH OR NOT CMake_HAVE_CXX_FILESYSTEM)
+  list(APPEND CMakeLib_TESTS testCMFilesystemPath.cxx)
+endif()
 
 add_executable(testUVProcessChainHelper testUVProcessChainHelper.cxx)
 
diff --git a/Tests/CMakeLib/PseudoMemcheck/CMakeLists.txt b/Tests/CMakeLib/PseudoMemcheck/CMakeLists.txt
index 7c84ee1..4bef6c5 100644
--- a/Tests/CMakeLib/PseudoMemcheck/CMakeLists.txt
+++ b/Tests/CMakeLib/PseudoMemcheck/CMakeLists.txt
@@ -15,6 +15,9 @@
 add_executable(pseudo_BC "${CMAKE_CURRENT_BINARY_DIR}/ret0.cxx")
 set_target_properties(pseudo_BC PROPERTIES OUTPUT_NAME BC)
 target_link_libraries(pseudo_BC CMakeLib)
+add_executable(pseudo_cuda-memcheck "${CMAKE_CURRENT_BINARY_DIR}/ret0.cxx")
+set_target_properties(pseudo_cuda-memcheck PROPERTIES OUTPUT_NAME cuda-memcheck)
+target_link_libraries(pseudo_cuda-memcheck CMakeLib)
 
 # binary to be used as pre- and post-memcheck command that fails
 add_executable(memcheck_fail "${CMAKE_CURRENT_BINARY_DIR}/ret1.cxx")
diff --git a/Tests/CMakeLib/PseudoMemcheck/memtester.cxx.in b/Tests/CMakeLib/PseudoMemcheck/memtester.cxx.in
index 3183bc0..f37ad59 100644
--- a/Tests/CMakeLib/PseudoMemcheck/memtester.cxx.in
+++ b/Tests/CMakeLib/PseudoMemcheck/memtester.cxx.in
@@ -1,8 +1,14 @@
-#include <cmSystemTools.h>
-#include "cmsys/Encoding.hxx"
 #include <string>
+#include <vector>
 
+#include "cmsys/Encoding.hxx"
+
+#include <cmSystemTools.h>
+
+// clang-format off
 #define RETVAL @_retval@
+#define CMAKE_COMMAND "@CMAKE_COMMAND@"
+// clang-format on
 
 int main(int ac, char** av)
 {
@@ -14,6 +20,9 @@
   std::string exename = argv[0];
   std::string logarg;
   bool nextarg = false;
+  // execute the part after the last argument?
+  // the logfile path gets passed as environment variable PSEUDO_LOGFILE
+  bool exec = false;
 
   if (exename.find("valgrind") != std::string::npos) {
     logarg = "--log-file=";
@@ -26,6 +35,10 @@
   } else if (exename.find("BC") != std::string::npos) {
     nextarg = true;
     logarg = "/X";
+  } else if (exename.find("cuda-memcheck") != std::string::npos) {
+    nextarg = true;
+    exec = true;
+    logarg = "--log-file";
   }
 
   if (!logarg.empty()) {
@@ -45,8 +58,25 @@
       }
     }
 
+    // find the last argument position
+    int lastarg_pos = 1;
+    for (int i = 1; i < argc; ++i) {
+      std::string arg = argv[i];
+      if (arg.find("--") == 0) {
+        lastarg_pos = i;
+      }
+    }
+
     if (!logfile.empty()) {
       cmSystemTools::Touch(logfile, true);
+      // execute everything after the last argument with additional environment
+      int callarg_pos = lastarg_pos + (nextarg ? 2 : 1);
+      if (exec && callarg_pos < argc) {
+        std::vector<std::string> callargs{ CMAKE_COMMAND, "-E", "env",
+                                           "PSEUDO_LOGFILE=" + logfile };
+        callargs.insert(callargs.end(), &argv[callarg_pos], &argv[argc]);
+        cmSystemTools::RunSingleCommand(callargs);
+      }
     }
   }
 
diff --git a/Tests/CMakeLib/testArgumentParser.cxx b/Tests/CMakeLib/testArgumentParser.cxx
index 20f98c2..965690c 100644
--- a/Tests/CMakeLib/testArgumentParser.cxx
+++ b/Tests/CMakeLib/testArgumentParser.cxx
@@ -7,8 +7,7 @@
 #include <vector>
 
 #include <cm/string_view>
-
-#include "cm_static_string_view.hxx"
+#include <cmext/string_view>
 
 #include "cmArgumentParser.h"
 
diff --git a/Tests/CMakeLib/testCMExtMemory.cxx b/Tests/CMakeLib/testCMExtMemory.cxx
index 6663c17..2aeaf7f 100644
--- a/Tests/CMakeLib/testCMExtMemory.cxx
+++ b/Tests/CMakeLib/testCMExtMemory.cxx
@@ -13,7 +13,7 @@
 class Derived : public Base
 {
 public:
-  ~Derived() = default;
+  ~Derived() override = default;
 
   void method() {}
 };
diff --git a/Tests/CMakeLib/testCMFilesystemPath.cxx b/Tests/CMakeLib/testCMFilesystemPath.cxx
new file mode 100644
index 0000000..1e84520
--- /dev/null
+++ b/Tests/CMakeLib/testCMFilesystemPath.cxx
@@ -0,0 +1,1006 @@
+/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
+   file Copyright.txt or https://cmake.org/licensing for details.  */
+
+#include <algorithm>
+#include <iostream>
+#include <sstream>
+#include <string>
+#include <vector>
+
+#include <cm/filesystem>
+#include <cm/iomanip>
+
+namespace {
+
+namespace fs = cm::filesystem;
+
+void checkResult(bool success)
+{
+  if (!success) {
+    std::cout << " => failed";
+  }
+  std::cout << std::endl;
+}
+
+bool testConstructors()
+{
+  std::cout << "testConstructors()";
+
+  bool result = true;
+
+  {
+    fs::path p;
+    if (p != fs::path()) {
+      result = false;
+    }
+  }
+  {
+    fs::path p1("/a/b/c");
+    fs::path p2("/a/b/c");
+    if (p1 != p2) {
+      result = false;
+    }
+    if (p1.string() != p2.string()) {
+      result = false;
+    }
+    if (p1.string() != "/a/b/c") {
+      result = false;
+    }
+  }
+  {
+    std::string s("/a/b/c");
+    fs::path p1(s);
+    fs::path p2(s.begin(), s.end());
+    if (p1 != p2) {
+      result = false;
+    }
+    if (p1.string() != s || p2.string() != s) {
+      result = false;
+    }
+#if CM_FILESYSTEM_SOURCE_TRAITS_ITERATOR
+    std::string s2(s);
+    s2 += '\0';
+    fs::path p3(s2.begin());
+    if (p1 != p3 || p3.string() != s) {
+      result = false;
+    }
+#endif
+  }
+  {
+    std::wstring s(L"/a/b/c");
+    fs::path p1(s);
+    fs::path p2(s.begin(), s.end());
+    if (p1 != p2) {
+      result = false;
+    }
+    if (p1.wstring() != s || p2.wstring() != s) {
+      result = false;
+    }
+#if CM_FILESYSTEM_SOURCE_TRAITS_ITERATOR
+    std::wstring s2(s);
+    s2 += L'\0';
+    fs::path p3(s2.begin());
+    if (p1 != p3 || p3.wstring() != s) {
+      result = false;
+    }
+#endif
+  }
+  {
+    std::string s("/a/b/c");
+    fs::path::string_type ws;
+    for (auto c : s) {
+      ws += fs::path::value_type(c);
+    }
+    fs::path p1(ws);
+    fs::path p2(ws.begin(), ws.end());
+    if (p1 != p2) {
+      result = false;
+    }
+    if (p1.native() != ws || p2.native() != ws) {
+      result = false;
+    }
+#if CM_FILESYSTEM_SOURCE_TRAITS_ITERATOR
+    fs::path::string_type ws2(ws);
+    ws2 += fs::path::value_type('\0');
+    fs::path p3(ws2.begin());
+    if (p1 != p3 || p3.native() != ws) {
+      result = false;
+    }
+#endif
+  }
+
+  checkResult(result);
+
+  return result;
+}
+
+bool testConcatenation()
+{
+  std::cout << "testConcatenation()";
+
+  bool result = true;
+
+  {
+    fs::path p("/a/b");
+    p /= "c";
+    if (!(p.string() == "/a/b/c" || p.string() == "/a/b\\c")) {
+      result = false;
+    }
+    p += "d";
+    if (!(p.string() == "/a/b/cd" || p.string() == "/a/b\\cd")) {
+      result = false;
+    }
+    fs::path p2("x/y");
+    p /= p2;
+    if (!(p.string() == "/a/b/cd/x/y" || p.string() == "/a/b\\cd\\x/y")) {
+      result = false;
+    }
+    p = p / p2;
+    if (!(p.string() == "/a/b/cd/x/y/x/y" ||
+          p.string() == "/a/b\\cd\\x/y\\x/y")) {
+      result = false;
+    }
+  }
+  {
+    fs::path p("a");
+    p /= "";
+    if (!(p.string() == "a/" || p.string() == "a\\")) {
+      result = false;
+    }
+    p /= "/b";
+    if (p.string() != "/b") {
+      result = false;
+    }
+  }
+#if defined(_WIN32)
+  {
+    fs::path p("a");
+    p /= "c:/b";
+    if (p.string() != "c:/b") {
+      result = false;
+    }
+    p = fs::path("a") / "c:";
+    if (p.string() != "c:") {
+      result = false;
+    }
+    p = fs::path("c:") / "";
+    if (p.string() != "c:") {
+      result = false;
+    }
+    p = fs::path("c:a") / "/b";
+    if (p.string() != "c:/b") {
+      result = false;
+    }
+    p = fs::path("c:a") / "c:b";
+    if (p.string() != "c:a\\b") {
+      result = false;
+    }
+    p = fs::path("//host") / "b";
+    if (p.string() != "//host\\b") {
+      result = false;
+    }
+    p = fs::path("//host/") / "b";
+    if (p.string() != "//host/b") {
+      result = false;
+    }
+  }
+#endif
+
+  checkResult(result);
+
+  return result;
+}
+
+bool testModifiers()
+{
+  std::cout << "testModifiers()";
+
+  bool result = true;
+
+  {
+    std::string s("a///b/");
+    fs::path p(s);
+    std::replace(
+      s.begin(), s.end(), '/',
+      static_cast<std::string::value_type>(fs::path::preferred_separator));
+    p.make_preferred();
+    if (p.string() != s) {
+      result = false;
+    }
+  }
+  {
+    fs::path p("a/b/c.e.f");
+    p.remove_filename();
+    if (p.string() != "a/b/") {
+      result = false;
+    }
+    p.remove_filename();
+    if (p.string() != "a/b/") {
+      result = false;
+    }
+  }
+  {
+    fs::path p("a/b/c.e.f");
+    p.replace_filename("x.y");
+    if (p.string() != "a/b/x.y") {
+      result = false;
+    }
+  }
+  {
+    fs::path p("a/b/c.e.f");
+    p.replace_extension(".x");
+    if (p.string() != "a/b/c.e.x") {
+      result = false;
+    }
+    p.replace_extension(".y");
+    if (p.string() != "a/b/c.e.y") {
+      result = false;
+    }
+    p.replace_extension();
+    if (p.string() != "a/b/c.e") {
+      result = false;
+    }
+    p = "/a/b";
+    p.replace_extension(".x");
+    if (p.string() != "/a/b.x") {
+      result = false;
+    }
+    p = "/a/b/";
+    p.replace_extension(".x");
+    if (p.string() != "/a/b/.x") {
+      result = false;
+    }
+  }
+
+  checkResult(result);
+
+  return result;
+}
+
+bool testObservers()
+{
+  std::cout << "testObservers()";
+
+  bool result = true;
+
+  {
+    std::string s("a/b/c");
+    fs::path p(s);
+    fs::path::string_type st;
+    for (auto c : s) {
+      st += static_cast<fs::path::value_type>(c);
+    }
+    if (p.native() != st || static_cast<fs::path::string_type>(p) != st ||
+        p.c_str() != st) {
+      result = false;
+    }
+  }
+  {
+    std::string s("a//b//c");
+    std::wstring ws(L"a//b//c");
+    fs::path p(s);
+    if (p.string() != s || p.wstring() != ws) {
+      result = false;
+    }
+  }
+  {
+    std::string s("a/b/c");
+    std::wstring ws;
+    for (auto c : s) {
+      ws += static_cast<std::wstring::value_type>(c);
+    }
+    std::string ns(s);
+    std::replace(
+      ns.begin(), ns.end(), '/',
+      static_cast<std::string::value_type>(fs::path::preferred_separator));
+    fs::path p(ns);
+    if (p.generic_string() != s || p.generic_wstring() != ws) {
+      result = false;
+    }
+  }
+
+  checkResult(result);
+
+  return result;
+}
+
+bool testCompare()
+{
+  std::cout << "testCompare()";
+
+  bool result = true;
+
+  {
+    std::string s("a/b/c");
+    fs::path p1(s);
+    fs::path p2(s);
+    if (p1.compare(p2) != 0) {
+      result = false;
+    }
+    p2 = "a/b";
+    if (p1.compare(p2) <= 0) {
+      result = false;
+    }
+    p2 = "a/d";
+    if (p1.compare(p2) >= 0) {
+      result = false;
+    }
+    p2 = "a/b/d";
+    if (p1.compare(p2) >= 0) {
+      result = false;
+    }
+    p2 = "a/b/a";
+    if (p1.compare(p2) <= 0) {
+      result = false;
+    }
+    p2 = "a/b/c/d";
+    if (p1.compare(p2) >= 0) {
+      result = false;
+    }
+    p1 = "a";
+    p2 = "b";
+    if (p1.compare(p2) == 0) {
+      result = false;
+    }
+  }
+  {
+    // LWG 3096 (https://cplusplus.github.io/LWG/issue3096)
+    // fs::path p1("/a/");
+    // fs::path p2("/a/.");
+    // if (p1.compare(p2) != 0) {
+    //   result = false;
+    // }
+  }
+
+  checkResult(result);
+
+  return result;
+}
+
+bool testGeneration()
+{
+  std::cout << "testGeneration()";
+
+  bool result = true;
+
+  {
+    fs::path p("a/./b/..");
+    if (p.lexically_normal().generic_string() != "a/") {
+      result = false;
+    }
+    p = "a/.///b/../";
+    if (p.lexically_normal().generic_string() != "a/") {
+      result = false;
+    }
+  }
+#if defined(_WIN32)
+  {
+    fs::path p("//host/./b/..");
+    if (p.lexically_normal().string() != "\\\\host\\") {
+      result = false;
+    }
+    p = "//host/.///b/../";
+    if (p.lexically_normal().string() != "\\\\host\\") {
+      result = false;
+    }
+    p = "c://a/.///b/../";
+    if (p.lexically_normal().string() != "c:\\a\\") {
+      result = false;
+    }
+  }
+#endif
+
+  {
+    if (fs::path("/a//d").lexically_relative("/a/b/c") != "../../d") {
+      result = false;
+    }
+    if (fs::path("/a//b///c").lexically_relative("/a/d") != "../b/c") {
+      result = false;
+    }
+    if (fs::path("a/b/c").lexically_relative("a") != "b/c") {
+      result = false;
+    }
+    if (fs::path("a/b/c").lexically_relative("a/b/c/x/y") != "../..") {
+      result = false;
+    }
+    if (fs::path("a/b/c").lexically_relative("a/b/c") != ".") {
+      result = false;
+    }
+    if (fs::path("a/b").lexically_relative("c/d") != "../../a/b") {
+      result = false;
+    }
+  }
+  {
+#if defined(_WIN32)
+    if (fs::path("/a/d").lexically_relative("e/d/c") != "/a/d") {
+      result = false;
+    }
+    if (!fs::path("c:/a/d").lexically_relative("e/d/c").empty()) {
+      result = false;
+    }
+#else
+    if (!fs::path("/a/d").lexically_relative("e/d/c").empty()) {
+      result = false;
+    }
+#endif
+  }
+  {
+#if defined(_WIN32)
+    if (fs::path("c:/a/d").lexically_proximate("e/d/c") != "c:/a/d") {
+      result = false;
+    }
+#else
+    if (fs::path("/a/d").lexically_proximate("e/d/c") != "/a/d") {
+      result = false;
+    }
+#endif
+    if (fs::path("/a/d").lexically_proximate("/a/b/c") != "../../d") {
+      result = false;
+    }
+  }
+  // LWG 3070
+  {
+#if defined(_WIN32)
+    if (!fs::path("/a:/b:").lexically_relative("/a:/c:").empty()) {
+      result = false;
+    }
+    if (fs::path("c:/a/b").lexically_relative("c:/a/d") != "../b") {
+      result = false;
+    }
+    if (!fs::path("c:/a/b:").lexically_relative("c:/a/d").empty()) {
+      result = false;
+    }
+    if (!fs::path("c:/a/b").lexically_relative("c:/a/d:").empty()) {
+      result = false;
+    }
+#else
+    if (fs::path("/a:/b:").lexically_relative("/a:/c:") != "../b:") {
+      result = false;
+    }
+#endif
+  }
+  // LWG 3096
+  {
+    if (fs::path("/a").lexically_relative("/a/.") != ".") {
+      result = false;
+    }
+    if (fs::path("/a").lexically_relative("/a/") != ".") {
+      result = false;
+    }
+    if (fs::path("a/b/c").lexically_relative("a/b/c") != ".") {
+      result = false;
+    }
+    if (fs::path("a/b/c").lexically_relative("a/b/c/") != ".") {
+      result = false;
+    }
+    if (fs::path("a/b/c").lexically_relative("a/b/c/.") != ".") {
+      result = false;
+    }
+    if (fs::path("a/b/c/").lexically_relative("a/b/c") != ".") {
+      result = false;
+    }
+    if (fs::path("a/b/c/.").lexically_relative("a/b/c") != ".") {
+      result = false;
+    }
+    if (fs::path("a/b/c/.").lexically_relative("a/b/c/") != ".") {
+      result = false;
+    }
+  }
+
+  checkResult(result);
+
+  return result;
+}
+
+bool testDecomposition()
+{
+  std::cout << "testDecomposition()";
+
+  bool result = true;
+
+  {
+    if (!fs::path("/a/b").root_name().empty()) {
+      result = false;
+    }
+#if defined(_WIN32)
+    if (fs::path("c:/a/b").root_name() != "c:") {
+      result = false;
+    }
+    if (fs::path("c:a/b").root_name() != "c:") {
+      result = false;
+    }
+    if (fs::path("c:").root_name() != "c:") {
+      result = false;
+    }
+    if (fs::path("//host/b").root_name() != "//host") {
+      result = false;
+    }
+    if (fs::path("//host").root_name() != "//host") {
+      result = false;
+    }
+#endif
+  }
+  {
+    if (!fs::path("a/b").root_directory().empty()) {
+      result = false;
+    }
+    if (fs::path("/a/b").root_directory() != "/") {
+      result = false;
+    }
+#if defined(_WIN32)
+    if (!fs::path("c:a/b").root_directory().empty()) {
+      result = false;
+    }
+    if (fs::path("/a/b").root_directory() != "/") {
+      result = false;
+    }
+    if (fs::path("c:/a/b").root_directory() != "/") {
+      result = false;
+    }
+    if (fs::path("//host/b").root_directory() != "/") {
+      result = false;
+    }
+#endif
+  }
+  {
+    if (!fs::path("a/b").root_path().empty()) {
+      result = false;
+    }
+    if (fs::path("/a/b").root_path() != "/") {
+      result = false;
+    }
+#if defined(_WIN32)
+    if (fs::path("c:a/b").root_path() != "c:") {
+      result = false;
+    }
+    if (fs::path("/a/b").root_path() != "/") {
+      result = false;
+    }
+    if (fs::path("c:/a/b").root_path() != "c:/") {
+      result = false;
+    }
+    if (fs::path("//host/b").root_path() != "//host/") {
+      result = false;
+    }
+#endif
+  }
+  {
+    if (!fs::path("/").relative_path().empty()) {
+      result = false;
+    }
+    if (fs::path("a/b").relative_path() != "a/b") {
+      result = false;
+    }
+    if (fs::path("/a/b").relative_path() != "a/b") {
+      result = false;
+    }
+#if defined(_WIN32)
+    if (fs::path("c:a/b").relative_path() != "a/b") {
+      result = false;
+    }
+    if (fs::path("/a/b").relative_path() != "a/b") {
+      result = false;
+    }
+    if (fs::path("c:/a/b").relative_path() != "a/b") {
+      result = false;
+    }
+    if (fs::path("//host/b").relative_path() != "b") {
+      result = false;
+    }
+#endif
+  }
+  {
+    if (fs::path("/a/b").parent_path() != "/a") {
+      result = false;
+    }
+    if (fs::path("/a/b/").parent_path() != "/a/b") {
+      result = false;
+    }
+    if (fs::path("/a/b/.").parent_path() != "/a/b") {
+      result = false;
+    }
+    if (fs::path("/").parent_path() != "/") {
+      result = false;
+    }
+#if defined(_WIN32)
+    if (fs::path("c:/a/b").parent_path() != "c:/a") {
+      result = false;
+    }
+    if (fs::path("c:/").parent_path() != "c:/") {
+      result = false;
+    }
+    if (fs::path("c:").parent_path() != "c:") {
+      result = false;
+    }
+    if (fs::path("//host/").parent_path() != "//host/") {
+      result = false;
+    }
+    if (fs::path("//host").parent_path() != "//host") {
+      result = false;
+    }
+#endif
+  }
+  {
+    if (fs::path("/a/b.txt").filename() != "b.txt") {
+      result = false;
+    }
+    if (fs::path("/a/.b").filename() != ".b") {
+      result = false;
+    }
+    if (fs::path("/foo/bar/").filename() != "") {
+      result = false;
+    }
+    if (fs::path("/foo/.").filename() != ".") {
+      result = false;
+    }
+    if (fs::path("/foo/..").filename() != "..") {
+      result = false;
+    }
+    if (fs::path(".").filename() != ".") {
+      result = false;
+    }
+    if (fs::path("..").filename() != "..") {
+      result = false;
+    }
+    if (!fs::path("/").filename().empty()) {
+      result = false;
+    }
+#if defined(_WIN32)
+    if (fs::path("c:a").filename() != "a") {
+      result = false;
+    }
+    if (fs::path("c:/a").filename() != "a") {
+      result = false;
+    }
+    if (!fs::path("c:").filename().empty()) {
+      result = false;
+    }
+    if (!fs::path("c:/").filename().empty()) {
+      result = false;
+    }
+    if (!fs::path("//host").filename().empty()) {
+      result = false;
+    }
+#endif
+  }
+  {
+    if (fs::path("/a/b.txt").stem() != "b") {
+      result = false;
+    }
+    if (fs::path("/a/b.c.txt").stem() != "b.c") {
+      result = false;
+    }
+    if (fs::path("/a/.b").stem() != ".b") {
+      result = false;
+    }
+    if (fs::path("/a/b").stem() != "b") {
+      result = false;
+    }
+    if (fs::path("/a/b/.").stem() != ".") {
+      result = false;
+    }
+    if (fs::path("/a/b/..").stem() != "..") {
+      result = false;
+    }
+    if (!fs::path("/a/b/").stem().empty()) {
+      result = false;
+    }
+#if defined(_WIN32)
+    if (!fs::path("c:/a/b/").stem().empty()) {
+      result = false;
+    }
+    if (!fs::path("c:/").stem().empty()) {
+      result = false;
+    }
+    if (!fs::path("c:").stem().empty()) {
+      result = false;
+    }
+    if (!fs::path("//host/").stem().empty()) {
+      result = false;
+    }
+    if (!fs::path("//host").stem().empty()) {
+      result = false;
+    }
+#endif
+  }
+  {
+    if (fs::path("/a/b.txt").extension() != ".txt") {
+      result = false;
+    }
+    if (fs::path("/a/b.").extension() != ".") {
+      result = false;
+    }
+    if (!fs::path("/a/b").extension().empty()) {
+      result = false;
+    }
+    if (fs::path("/a/b.txt/b.cc").extension() != ".cc") {
+      result = false;
+    }
+    if (fs::path("/a/b.txt/b.").extension() != ".") {
+      result = false;
+    }
+    if (!fs::path("/a/b.txt/b").extension().empty()) {
+      result = false;
+    }
+    if (!fs::path("/a/.").extension().empty()) {
+      result = false;
+    }
+    if (!fs::path("/a/..").extension().empty()) {
+      result = false;
+    }
+    if (!fs::path("/a/.hidden").extension().empty()) {
+      result = false;
+    }
+    if (fs::path("/a/..b").extension() != ".b") {
+      result = false;
+    }
+  }
+
+  checkResult(result);
+
+  return result;
+}
+
+bool testQueries()
+{
+  std::cout << "testQueries()";
+
+  bool result = true;
+
+  {
+    if (fs::path("/a/b").has_root_name()) {
+      result = false;
+    }
+    fs::path p("/a/b");
+    if (!p.has_root_directory() || !p.has_root_path()) {
+      result = false;
+    }
+    if (!fs::path("/a/b").has_root_path() || fs::path("a/b").has_root_path()) {
+      result = false;
+    }
+    if (!fs::path("/a/b").has_relative_path() ||
+        fs::path("/").has_relative_path()) {
+      result = false;
+    }
+    if (!fs::path("/a/b").has_parent_path() ||
+        !fs::path("/").has_parent_path() || fs::path("a").has_parent_path()) {
+      result = false;
+    }
+    if (!fs::path("/a/b").has_filename() || !fs::path("a.b").has_filename() ||
+        fs::path("/a/").has_filename() || fs::path("/").has_filename()) {
+      result = false;
+    }
+    if (!fs::path("/a/b").has_stem() || !fs::path("a.b").has_stem() ||
+        !fs::path("/.a").has_stem() || fs::path("/a/").has_stem() ||
+        fs::path("/").has_stem()) {
+      result = false;
+    }
+    if (!fs::path("/a/b.c").has_extension() ||
+        !fs::path("a.b").has_extension() || fs::path("/.a").has_extension() ||
+        fs::path("/a/").has_extension() || fs::path("/").has_extension()) {
+      result = false;
+    }
+#if defined(_WIN32)
+    p = "c:/a/b";
+    if (!fs::path("c:/a/b").has_root_name() || !p.has_root_directory() ||
+        !p.has_root_path()) {
+      result = false;
+    }
+    p = "c:a/b";
+    if (!p.has_root_name() || p.has_root_directory() || !p.has_root_path()) {
+      result = false;
+    }
+    p = "//host/b";
+    if (!p.has_root_name() || !p.has_root_directory() || !p.has_root_path()) {
+      result = false;
+    }
+    p = "//host";
+    if (!p.has_root_name() || p.has_root_directory() || !p.has_root_path()) {
+      result = false;
+    }
+    if (!fs::path("c:/a/b").has_relative_path() ||
+        !fs::path("c:a/b").has_relative_path() ||
+        !fs::path("//host/b").has_relative_path()) {
+      result = false;
+    }
+    if (!fs::path("c:/a/b").has_parent_path() ||
+        !fs::path("c:/").has_parent_path() ||
+        !fs::path("c:").has_parent_path() ||
+        !fs::path("//host/").has_parent_path() ||
+        !fs::path("//host").has_parent_path()) {
+      result = false;
+    }
+#endif
+  }
+  {
+#if defined(_WIN32)
+    fs::path p("c:/a");
+#else
+    fs::path p("/a");
+#endif
+    if (!p.is_absolute() || p.is_relative()) {
+      result = false;
+    }
+    p = "a/b";
+    if (p.is_absolute() || !p.is_relative()) {
+      result = false;
+    }
+#if defined(_WIN32)
+    p = "c:/a/b";
+    if (!p.is_absolute() || p.is_relative()) {
+      result = false;
+    }
+    p = "//host/b";
+    if (!p.is_absolute() || p.is_relative()) {
+      result = false;
+    }
+    p = "/a";
+    if (p.is_absolute() || !p.is_relative()) {
+      result = false;
+    }
+    p = "c:a";
+    if (p.is_absolute() || !p.is_relative()) {
+      result = false;
+    }
+#endif
+  }
+
+  checkResult(result);
+
+  return result;
+}
+
+bool testIterators()
+{
+  std::cout << "testIterators()";
+
+  bool result = true;
+
+  {
+    fs::path p("/a/b/");
+#if defined(_WIN32)
+    std::vector<fs::path::string_type> ref{ L"/", L"a", L"b", L"" };
+#else
+    std::vector<fs::path::string_type> ref{ "/", "a", "b", "" };
+#endif
+    std::vector<fs::path::string_type> res;
+    for (auto i = p.begin(), e = p.end(); i != e; ++i) {
+      res.push_back(*i);
+    }
+    if (res != ref) {
+      result = false;
+    }
+    res.clear();
+    for (const auto& e : p) {
+      res.push_back(e);
+    }
+    if (res != ref) {
+      result = false;
+    }
+  }
+  {
+    fs::path p("/a/b/");
+#if defined(_WIN32)
+    std::vector<fs::path::string_type> ref{ L"", L"b", L"a", L"/" };
+#else
+    std::vector<fs::path::string_type> ref{ "", "b", "a", "/" };
+#endif
+    std::vector<fs::path::string_type> res;
+    auto i = p.end(), b = p.begin();
+    do {
+      res.push_back(*--i);
+    } while (i != b);
+    if (res != ref) {
+      result = false;
+    }
+  }
+
+  checkResult(result);
+
+  return result;
+}
+
+bool testNonMemberFunctions()
+{
+  std::cout << "testNonMemberFunctions()";
+
+  bool result = true;
+
+  {
+    fs::path p1("/a/b/");
+    fs::path p2("/c/d");
+    fs::swap(p1, p2);
+    if (p1.string() != "/c/d" || p2.string() != "/a/b/")
+      result = false;
+  }
+  {
+    auto h1 = fs::hash_value(fs::path("/a//b//"));
+    auto h2 = fs::hash_value(fs::path("/a/b/"));
+    if (h1 != h2)
+      result = false;
+  }
+  {
+    fs::path p1("/a/b/");
+    fs::path p2("/c/d");
+    if (p1 == p2)
+      result = false;
+    p1 = "/a//b//";
+    p2 = "/a/b/";
+    if (p1 != p2)
+      result = false;
+  }
+  {
+    fs::path p = "/a";
+    p = p / "b" / "c";
+    if (p.generic_string() != "/a/b/c") {
+      result = false;
+    }
+    fs::path::string_type ref;
+    ref += fs::path::value_type('/');
+    ref += fs::path::value_type('a');
+    ref += fs::path::preferred_separator;
+    ref += fs::path::value_type('b');
+    ref += fs::path::preferred_separator;
+    ref += fs::path::value_type('c');
+    if (p.native() != ref) {
+      result = false;
+    }
+  }
+  {
+    fs::path p("/a b\\c/");
+    std::ostringstream oss;
+    oss << p;
+    if (oss.str() != "\"/a b\\\\c/\"") {
+      result = false;
+    }
+    std::istringstream iss(oss.str());
+    fs::path p2;
+    iss >> p2;
+    if (p2 != p) {
+      result = false;
+    }
+  }
+
+  checkResult(result);
+
+  return result;
+}
+}
+
+int testCMFilesystemPath(int /*unused*/, char* /*unused*/ [])
+{
+  int result = 0;
+
+  if (!testConstructors()) {
+    result = 1;
+  }
+  if (!testConcatenation()) {
+    result = 1;
+  }
+  if (!testModifiers()) {
+    result = 1;
+  }
+  if (!testObservers()) {
+    result = 1;
+  }
+  if (!testCompare()) {
+    result = 1;
+  }
+  if (!testGeneration()) {
+    result = 1;
+  }
+  if (!testDecomposition()) {
+    result = 1;
+  }
+  if (!testQueries()) {
+    result = 1;
+  }
+  if (!testIterators()) {
+    result = 1;
+  }
+  if (!testNonMemberFunctions()) {
+    result = 1;
+  }
+
+  return result;
+}
diff --git a/Tests/CMakeLib/testCTestBinPacker.cxx b/Tests/CMakeLib/testCTestBinPacker.cxx
index 6f09af2..abdbefb 100644
--- a/Tests/CMakeLib/testCTestBinPacker.cxx
+++ b/Tests/CMakeLib/testCTestBinPacker.cxx
@@ -1,4 +1,4 @@
-#include <cstddef>
+#include <cstddef> // IWYU pragma: keep
 #include <iostream>
 #include <map>
 #include <string>
diff --git a/Tests/CMakeLib/testGccDepfileReader.cxx b/Tests/CMakeLib/testGccDepfileReader.cxx
index 924d87b..e79f047 100644
--- a/Tests/CMakeLib/testGccDepfileReader.cxx
+++ b/Tests/CMakeLib/testGccDepfileReader.cxx
@@ -1,4 +1,4 @@
-#include <cstddef>
+#include <cstddef> // IWYU pragma: keep
 #include <iostream>
 #include <memory>
 #include <string>
diff --git a/Tests/CMakeLib/testRST.expect b/Tests/CMakeLib/testRST.expect
index c19ee94..970adaa 100644
--- a/Tests/CMakeLib/testRST.expect
+++ b/Tests/CMakeLib/testRST.expect
@@ -5,7 +5,7 @@
 Command ``some_cmd()`` without target.
 Command ``some_cmd`` with target.
 Command ``some_cmd_<cmd>()`` placeholder without target.
-Command ``some_cmd_<cmd>`` placholder with target.
+Command ``some_cmd_<cmd>`` placeholder with target.
 Command ``some_cmd()`` with parens.
 Command ``some_cmd(SUB)`` with subcommand.
 Command ``some_cmd(SUB)`` with subcommand and target.
diff --git a/Tests/CMakeLib/testRST.rst b/Tests/CMakeLib/testRST.rst
index d2d1140..6462f1b 100644
--- a/Tests/CMakeLib/testRST.rst
+++ b/Tests/CMakeLib/testRST.rst
@@ -12,7 +12,7 @@
 Command :command:`some_cmd` without target.
 Command :command:`some_cmd <some_cmd>` with target.
 Command :command:`some_cmd_<cmd>` placeholder without target.
-Command :command:`some_cmd_<cmd> <some_cmd>` placholder with target.
+Command :command:`some_cmd_<cmd> <some_cmd>` placeholder with target.
 Command :command:`some_cmd()` with parens.
 Command :command:`some_cmd(SUB)` with subcommand.
 Command :command:`some_cmd(SUB) <some_cmd>` with subcommand and target.
diff --git a/Tests/CMakeLib/testString.cxx b/Tests/CMakeLib/testString.cxx
index 1fd3f38..ad800cf 100644
--- a/Tests/CMakeLib/testString.cxx
+++ b/Tests/CMakeLib/testString.cxx
@@ -1,7 +1,7 @@
 /* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
    file Copyright.txt or https://cmake.org/licensing for details.  */
 
-#include <cstddef>
+#include <cstddef> // IWYU pragma: keep
 #include <cstring>
 #include <iostream>
 #include <iterator>
@@ -12,8 +12,7 @@
 #include <utility>
 
 #include <cm/string_view>
-
-#include "cm_static_string_view.hxx"
+#include <cmext/string_view>
 
 #include "cmString.hxx"
 
diff --git a/Tests/CMakeLib/testUVProcessChain.cxx b/Tests/CMakeLib/testUVProcessChain.cxx
index 71a1764..61a77cf 100644
--- a/Tests/CMakeLib/testUVProcessChain.cxx
+++ b/Tests/CMakeLib/testUVProcessChain.cxx
@@ -8,7 +8,7 @@
 
 #include <cm/memory>
 
-#include "cm_uv.h"
+#include <cm3p/uv.h>
 
 #include "cmGetPipes.h"
 #include "cmUVHandlePtr.h"
diff --git a/Tests/CMakeLib/testUVRAII.cxx b/Tests/CMakeLib/testUVRAII.cxx
index cb05ace..0607f44 100644
--- a/Tests/CMakeLib/testUVRAII.cxx
+++ b/Tests/CMakeLib/testUVRAII.cxx
@@ -3,7 +3,7 @@
 #include <thread>
 #include <utility>
 
-#include "cm_uv.h"
+#include <cm3p/uv.h>
 
 #include "cmUVHandlePtr.h"
 
diff --git a/Tests/CMakeLib/testUVStreambuf.cxx b/Tests/CMakeLib/testUVStreambuf.cxx
index cd9c9d4..b86ed76 100644
--- a/Tests/CMakeLib/testUVStreambuf.cxx
+++ b/Tests/CMakeLib/testUVStreambuf.cxx
@@ -3,10 +3,9 @@
 #include <string>
 #include <vector>
 
+#include <cm3p/uv.h>
 #include <stdint.h>
 
-#include "cm_uv.h"
-
 #include "cmGetPipes.h"
 #include "cmUVHandlePtr.h"
 #include "cmUVStreambuf.h"
diff --git a/Tests/CMakeLists.txt b/Tests/CMakeLists.txt
index aff7383..4a774dd 100644
--- a/Tests/CMakeLists.txt
+++ b/Tests/CMakeLists.txt
@@ -206,6 +206,26 @@
         set(${reg} 0)
       endif()
     endforeach()
+    if(COMMAND cmake_host_system_information)
+      set(info_vs15 "VS_15_DIR")
+      set(info_vs16 "VS_16_DIR")
+      set(vs_versions)
+      if(WIN32)
+        if(NOT CMAKE_VERSION VERSION_LESS 3.14)
+          set(vs_versions vs15 vs16)
+        elseif(NOT CMAKE_VERSION VERSION_LESS 3.8)
+          set(vs_versions vs15)
+        endif()
+      endif()
+      foreach(info ${vs_versions})
+        cmake_host_system_information(RESULT found QUERY "${info_${info}}")
+        if(found)
+          set(${info} 1)
+        else()
+          set(${info} 0)
+        endif()
+      endforeach()
+    endif()
   endif()
 
   #---------------------------------------------------------------------------
@@ -349,7 +369,6 @@
   # add a bunch of standard build-and-test style tests
   ADD_TEST_MACRO(CommandLineTest CommandLineTest)
   ADD_TEST_MACRO(FindPackageTest FindPackageTest)
-  ADD_TEST_MACRO(FindModulesExecuteAll FindModulesExecuteAll)
   ADD_TEST_MACRO(StringFileTest StringFileTest)
   ADD_TEST_MACRO(TryCompile TryCompile)
   ADD_TEST_MACRO(SystemInformation SystemInformation)
@@ -363,7 +382,10 @@
       add_test_macro(VSResourceNinjaForceRSP VSResourceNinjaForceRSP)
     endif ()
   endif()
-  ADD_TEST_MACRO(MSManifest MSManifest)
+  if(_isMultiConfig)
+    set(MSManifest_CTEST_OPTIONS -C $<CONFIGURATION>)
+  endif()
+  ADD_TEST_MACRO(MSManifest ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>)
   ADD_TEST_MACRO(Simple Simple)
   ADD_TEST_MACRO(PreOrder PreOrder)
   ADD_TEST_MACRO(MissingSourceFile MissingSourceFile)
@@ -447,6 +469,8 @@
                                  -DCMake_TEST_CUDA:BOOL=${CMake_TEST_CUDA}
                                  )
   ADD_TEST_MACRO(ExportImport ExportImport)
+  set_property(TEST ExportImport APPEND
+    PROPERTY LABELS "CUDA")
   ADD_TEST_MACRO(Unset Unset)
   ADD_TEST_MACRO(PolicyScope PolicyScope)
   ADD_TEST_MACRO(EmptyLibrary EmptyLibrary)
@@ -693,38 +717,28 @@
   # build the "Simple" test with the ExtraGenerators, if available
   # This doesn't test whether the generated project files work (unfortunately),
   # mainly it tests that cmake doesn't crash when generating these project files.
-  if(${CMAKE_GENERATOR} MATCHES "Unix Makefiles" OR ${CMAKE_GENERATOR} MATCHES "Ninja")
-
-    # check which generators we have
-    execute_process(COMMAND ${CMAKE_CMAKE_COMMAND} --help
-      OUTPUT_VARIABLE cmakeOutput ERROR_VARIABLE cmakeOutput)
-
-    set(extraGenerators
-      "CodeBlocks"
-      "CodeLite"
-      "Eclipse CDT4"
-      "Kate"
-      "Sublime Text 2")
-
-    foreach(extraGenerator ${extraGenerators})
-      if ("${cmakeOutput}" MATCHES "${extraGenerator} - ${CMAKE_GENERATOR}")
-        set(extraGeneratorTestName "Simple_${extraGenerator}Generator")
-        string(REPLACE " " "" extraGeneratorTestName ${extraGeneratorTestName})
-
-        add_test(${extraGeneratorTestName} ${CMAKE_CTEST_COMMAND}
-          --build-and-test
-          "${CMake_SOURCE_DIR}/Tests/Simple"
-          "${CMake_BINARY_DIR}/Tests/${extraGeneratorTestName}"
-          --build-two-config
-          --build-generator "${extraGenerator} - ${CMAKE_GENERATOR}"
-          --build-generator-platform "${CMAKE_GENERATOR_PLATFORM}"
-          --build-generator-toolset "${CMAKE_GENERATOR_TOOLSET}"
-          --build-project Simple
-          --test-command Simple)
-        list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/${extraGeneratorTestName}")
-      endif ()
-    endforeach(extraGenerator)
-
+  if(CMAKE_GENERATOR MATCHES "^(Unix Makefiles|Ninja)$"
+      AND NOT "${CMAKE_CURRENT_BINARY_DIR}" STREQUAL "${CMAKE_CURRENT_SOURCE_DIR}")
+    foreach(extraGenerator
+        "CodeBlocks"
+        "CodeLite"
+        "Eclipse CDT4"
+        "Kate"
+        "Sublime Text 2"
+        )
+      string(REPLACE " " "" extraGeneratorTestName "Simple_${extraGenerator}Generator")
+      add_test(${extraGeneratorTestName} ${CMAKE_CTEST_COMMAND}
+        --build-and-test
+        "${CMake_SOURCE_DIR}/Tests/Simple"
+        "${CMake_BINARY_DIR}/Tests/${extraGeneratorTestName}"
+        --build-two-config
+        --build-generator "${extraGenerator} - ${CMAKE_GENERATOR}"
+        --build-generator-platform "${CMAKE_GENERATOR_PLATFORM}"
+        --build-generator-toolset "${CMAKE_GENERATOR_TOOLSET}"
+        --build-project Simple
+        --test-command Simple)
+      list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/${extraGeneratorTestName}")
+    endforeach()
   endif()
 
   # test for correct sub-project generation
@@ -787,13 +801,8 @@
     endif()
   endmacro()
   if(CMake_BUILD_NIGHTLY_RELEASES)
-    ADD_NIGHTLY_BUILD_TEST(CMakeNightlyWin32
-      win32_release.cmake)
-    ADD_NIGHTLY_BUILD_TEST(CMakeNightlyWin64
-      win64_release.cmake)
     ADD_NIGHTLY_BUILD_TEST(CMakeNightlyOSX
       osx_release.cmake)
-    set_property(TEST CMakeNightlyWin64 PROPERTY DEPENDS CMakeNightlyWin32)
   endif()
 
   # add tests with more complex invocations
@@ -980,6 +989,7 @@
         --build-options
         --test-command ${CMAKE_CMAKE_COMMAND}
           "-DCPackWiXGenerator_BINARY_DIR:PATH=${CMake_BINARY_DIR}/Tests/CPackWiXGenerator"
+          "-Dno_verify:BOOL=${CMake_TEST_WIX_NO_VERIFY}"
           "-Dconfig=\${CTEST_CONFIGURATION_TYPE}"
           -P "${CMake_SOURCE_DIR}/Tests/CPackWiXGenerator/RunCPackVerifyResult.cmake")
 
@@ -1411,6 +1421,7 @@
   foreach(_mod IN ITEMS
             ALSA
             Boost
+            BLAS
             BZip2
             CURL
             Cups
@@ -1430,12 +1441,14 @@
             ICU
             JPEG
             JsonCpp
+            LAPACK
             LibArchive
             LibLZMA
             LibRHash
             Libinput
             LibUV
             LibXml2
+            LibXslt
             LTTngUST
             ODBC
             OpenACC
@@ -1448,6 +1461,7 @@
             Patch
             PostgreSQL
             Protobuf
+            SDL
             SQLite3
             TIFF
             Vulkan
@@ -1471,7 +1485,7 @@
   endif()
 
   if(CMake_TEST_FindPython OR CMake_TEST_FindPython_NumPy
-      OR CMake_TEST_FindPython_Conda OR CMake_TEST_FindPython_IronPython)
+      OR CMake_TEST_FindPython_Conda OR CMake_TEST_FindPython_IronPython OR CMake_TEST_FindPython_PyPy)
     add_subdirectory(FindPython)
   endif()
 
@@ -1479,6 +1493,10 @@
     add_subdirectory(UseSWIG)
   endif()
 
+  if(CMake_TEST_FindRuby)
+    add_subdirectory(FindRuby)
+  endif()
+
   add_subdirectory(FindThreads)
 
   # Matlab module
@@ -1606,7 +1624,7 @@
     DEPENDS ExternalProjectUpdateSetup )
 
   # do each of the tutorial steps
-  function(add_tutorial_test step_name use_mymath)
+  function(add_tutorial_test step_name use_mymath tutorial_arg pass_regex)
     set(tutorial_test_name Tutorial${step_name})
     set(tutorial_build_dir "${CMake_BINARY_DIR}/Tests/Tutorial/${step_name}")
     if (use_mymath)
@@ -1624,19 +1642,28 @@
       ${build_generator_args}
       --build-project Tutorial
       --build-options ${tutorial_build_options}
-      --test-command Tutorial 25.0)
+      --test-command Tutorial ${tutorial_arg})
+    set_tests_properties(${tutorial_test_name} PROPERTIES
+      PASS_REGULAR_EXPRESSION ${pass_regex})
+
     list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/${tutorial_build_dir}_Build")
   endfunction()
 
   if(NOT CMake_TEST_EXTERNAL_CMAKE)
     foreach(STP RANGE 2 12)
-      add_tutorial_test(Step${STP} TRUE)
+      if (STP EQUAL 6)
+        set(pass_regex ".*using log and exp")
+      else()
+        set(pass_regex "The square root of 25 is 5")
+      endif()
+      add_tutorial_test(Step${STP} TRUE 25 ${pass_regex})
     endforeach()
-    add_tutorial_test(Complete TRUE)
+    set(pass_regex "The square root of 25 is 5")
+    add_tutorial_test(Complete TRUE 25 ${pass_regex})
     foreach(STP RANGE 3 12)
-      add_tutorial_test(Step${STP} FALSE)
+      add_tutorial_test(Step${STP} FALSE 25 ${pass_regex})
     endforeach()
-    add_tutorial_test(Complete FALSE)
+    add_tutorial_test(Complete FALSE 25 ${pass_regex})
   endif()
 
   add_test(testing ${CMAKE_CTEST_COMMAND} -C \${CTEST_CONFIGURATION_TYPE}
@@ -1881,6 +1908,8 @@
     endif()
     set(MSVCRuntimeLibrary_BUILD_OPTIONS -DCMake_TEST_CUDA=${CMake_TEST_CUDA})
     ADD_TEST_MACRO(MSVCRuntimeLibrary)
+    set_property(TEST MSVCRuntimeLibrary APPEND
+      PROPERTY LABELS "CUDA")
     if(CMAKE_Fortran_COMPILER)
       ADD_TEST_MACRO(MSVCRuntimeLibrary.Fortran)
     endif()
@@ -2297,32 +2326,41 @@
     endforeach()
   endif()
 
+  macro(add_test_VSAndroid name generator platform)
+    add_test(NAME "VSAndroid.${name}.${platform}" COMMAND ${CMAKE_CTEST_COMMAND}
+      --build-and-test
+      "${CMake_SOURCE_DIR}/Tests/VSAndroid"
+      "${CMake_BINARY_DIR}/Tests/VSAndroid/${name}/${platform}"
+      --build-generator "${generator}"
+      --build-project VSAndroid
+      --build-config $<CONFIGURATION>
+      --build-options -DCMAKE_SYSTEM_NAME=Android "-A${platform}"
+      )
+    list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/VSAndroid/${name}")
+  endmacro()
   if(tegra AND NOT "${CMake_SOURCE_DIR};${CMake_BINARY_DIR}" MATCHES " ")
-    macro(add_test_VSNsightTegra name generator)
-      add_test(NAME VSNsightTegra.${name} COMMAND ${CMAKE_CTEST_COMMAND}
-        --build-and-test
-        "${CMake_SOURCE_DIR}/Tests/VSNsightTegra"
-        "${CMake_BINARY_DIR}/Tests/VSNsightTegra/${name}"
-        --build-generator "${generator}"
-        --build-project VSNsightTegra
-        --build-config $<CONFIGURATION>
-        --build-options -DCMAKE_SYSTEM_NAME=Android
-        )
-      list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/VSNsightTegra/${name}")
-    endmacro()
     if(vs10)
-      add_test_VSNsightTegra(vs10 "Visual Studio 10 2010")
+      add_test_VSAndroid(vs10 "Visual Studio 10 2010" "Tegra-Android")
     endif()
     if(vs11)
-      add_test_VSNsightTegra(vs11 "Visual Studio 11 2012")
+      add_test_VSAndroid(vs11 "Visual Studio 11 2012" "Tegra-Android")
     endif()
     if(vs12)
-      add_test_VSNsightTegra(vs12 "Visual Studio 12 2013")
+      add_test_VSAndroid(vs12 "Visual Studio 12 2013" "Tegra-Android")
     endif()
     if(vs14)
-      add_test_VSNsightTegra(vs14 "Visual Studio 14 2015")
+      add_test_VSAndroid(vs14 "Visual Studio 14 2015" "Tegra-Android")
     endif()
   endif()
+  if(vs14 AND CMake_TEST_ANDROID_VS14)
+    add_test_VSAndroid(vs14 "Visual Studio 14 2015" "ARM")
+  endif()
+  if(vs15 AND CMake_TEST_ANDROID_VS15)
+    add_test_VSAndroid(vs15 "Visual Studio 15 2017" "ARM")
+  endif()
+  if(vs16 AND CMake_TEST_ANDROID_VS16)
+    add_test_VSAndroid(vs16 "Visual Studio 16 2019" "ARM")
+  endif()
 
   if (APPLE)
     if (CMAKE_COMPILER_IS_GNUCXX OR "${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang")
@@ -2379,36 +2417,6 @@
     list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/BundleGeneratorTest")
   endif()
 
-  add_test(WarnUnusedUnusedViaSet ${CMAKE_CTEST_COMMAND}
-    --build-and-test
-    "${CMake_SOURCE_DIR}/Tests/VariableUnusedViaSet"
-    "${CMake_BINARY_DIR}/Tests/WarnUnusedUnusedViaSet"
-    ${build_generator_args}
-    --build-noclean
-    --build-project WarnUnusedUnusedViaSet
-    --build-options
-      "--warn-unused-vars")
-  set_tests_properties(WarnUnusedUnusedViaSet PROPERTIES
-    PASS_REGULAR_EXPRESSION "unused variable \\(changing definition\\) 'UNUSED_VARIABLE'")
-  set_tests_properties(WarnUnusedUnusedViaSet PROPERTIES
-    FAIL_REGULAR_EXPRESSION "unused variable \\(unsetting\\) 'UNUSED_VARIABLE'")
-  list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/WarnUnusedUnusedViaSet")
-
-  add_test(WarnUnusedUnusedViaUnset ${CMAKE_CTEST_COMMAND}
-    --build-and-test
-    "${CMake_SOURCE_DIR}/Tests/VariableUnusedViaUnset"
-    "${CMake_BINARY_DIR}/Tests/WarnUnusedUnusedViaUnset"
-    ${build_generator_args}
-    --build-noclean
-    --build-project WarnUnusedUnusedViaUnset
-    --build-options
-      "--warn-unused-vars")
-  set_tests_properties(WarnUnusedUnusedViaUnset PROPERTIES
-    PASS_REGULAR_EXPRESSION "CMake Warning \\(dev\\) at CMakeLists.txt:7 \\(set\\):")
-  set_tests_properties(WarnUnusedUnusedViaUnset PROPERTIES
-    FAIL_REGULAR_EXPRESSION "CMakeLists.txt:5 \\(set\\):")
-  list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/WarnUnusedUnusedViaUnset")
-
   add_test(WarnUnusedCliUnused ${CMAKE_CTEST_COMMAND}
     --build-and-test
     "${CMake_SOURCE_DIR}/Tests/WarnUnusedCliUnused"
@@ -2676,9 +2684,6 @@
     -S "${CMake_BINARY_DIR}/Tests/CTestCoverageCollectGCOV/test.cmake" -VV
     --output-log "${CMake_BINARY_DIR}/Tests/CTestCoverageCollectGCOV/testOut.log"
     )
-  set_tests_properties(CTestCoverageCollectGCOV PROPERTIES
-    PASS_REGULAR_EXPRESSION
-    "PASSED with correct output.*Testing/CoverageInfo/main.cpp.gcov")
   set_property(TEST CTestCoverageCollectGCOV PROPERTY ENVIRONMENT CTEST_PARALLEL_LEVEL=)
 
   configure_file(
@@ -2901,7 +2906,7 @@
       PASS_REGULAR_EXPRESSION "Failed")
   else()
     set_tests_properties(CTestTestCrash PROPERTIES
-      PASS_REGULAR_EXPRESSION "(Illegal|SegFault|Child aborted)")
+      PASS_REGULAR_EXPRESSION "(Illegal|SegFault|Subprocess aborted)")
   endif()
 
   configure_file(
@@ -3465,6 +3470,8 @@
     --build-two-config
     ${build_generator_args}
     --build-project IncludeDirectories
+    --build-options
+      -DMAKE_SUPPORTS_SPACES=${MAKE_SUPPORTS_SPACES}
     --test-command IncludeDirectories)
   list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/IncludeDirectories")
 
diff --git a/Tests/CMakeOnly/AllFindModules/CMakeLists.txt b/Tests/CMakeOnly/AllFindModules/CMakeLists.txt
index a53e441..49a4041 100644
--- a/Tests/CMakeOnly/AllFindModules/CMakeLists.txt
+++ b/Tests/CMakeOnly/AllFindModules/CMakeLists.txt
@@ -86,7 +86,7 @@
 endforeach()
 
 foreach(VTEST BISON Boost CUDA DOXYGEN FLEX GIF GTK2
-        HDF5 JPEG LibArchive OPENSCENEGRAPH RUBY SWIG Protobuf)
+        HDF5 JPEG LibArchive OPENSCENEGRAPH Ruby RUBY SWIG Protobuf)
     check_version_string(${VTEST} ${VTEST}_VERSION)
 endforeach()
 
diff --git a/Tests/CMakeTests/CMakeLists.txt b/Tests/CMakeTests/CMakeLists.txt
index e32d693..348e6d0 100644
--- a/Tests/CMakeTests/CMakeLists.txt
+++ b/Tests/CMakeTests/CMakeLists.txt
@@ -35,7 +35,7 @@
 AddCMakeTest(FileDownload "")
 set_tests_properties(CMake.FileDownload PROPERTIES
   PASS_REGULAR_EXPRESSION "file already exists with expected MD5 sum"
-  FAIL_REGULAR_EXPRESSION "Unexpected status"
+  FAIL_REGULAR_EXPRESSION "Unexpected status|incorrectly interpreted"
   )
 AddCMakeTest(FileDownloadBadHash "")
 set_property(TEST CMake.FileDownloadBadHash PROPERTY
diff --git a/Tests/CMakeTests/FileDownloadTest.cmake.in b/Tests/CMakeTests/FileDownloadTest.cmake.in
index 76c0000..69d9a14 100644
--- a/Tests/CMakeTests/FileDownloadTest.cmake.in
+++ b/Tests/CMakeTests/FileDownloadTest.cmake.in
@@ -163,3 +163,16 @@
 if(NOT EXISTS file12.png)
   message(SEND_ERROR "file12.png not downloaded: ${status}")
 endif()
+
+message(STATUS "FileDownload:13")
+file(DOWNLOAD
+  ${url}
+  TIMEOUT ${timeout}
+  STATUS status
+  )
+__reportIfWrongStatus("${status}" 0)
+if(EXISTS TIMEOUT)
+  file(REMOVE TIMEOUT)
+  message(SEND_ERROR "TIMEOUT argument was incorrectly interpreted as a filename")
+endif()
+message(STATUS "${status}")
diff --git a/Tests/CMakeTests/FileTestScript.cmake b/Tests/CMakeTests/FileTestScript.cmake
index 145f28a..fc3c28a 100644
--- a/Tests/CMakeTests/FileTestScript.cmake
+++ b/Tests/CMakeTests/FileTestScript.cmake
@@ -10,7 +10,7 @@
   file(DIFFERENT ffff)
 
 elseif(testname STREQUAL download_not_enough_args) # fail
-  file(DOWNLOAD ffff)
+  file(DOWNLOAD)
 
 elseif(testname STREQUAL read_not_enough_args) # fail
   file(READ ffff)
@@ -181,7 +181,7 @@
   message("v='${v}'")
 
 elseif(testname STREQUAL download_wrong_number_of_args) # fail
-  file(DOWNLOAD zzzz://bogus/ffff)
+  file(DOWNLOAD)
 
 elseif(testname STREQUAL download_file_with_no_path) # pass
   file(DOWNLOAD zzzz://bogus/ffff ffff)
diff --git a/Tests/CMakeTests/ListTest.cmake.in b/Tests/CMakeTests/ListTest.cmake.in
index f517e64..785f41d 100644
--- a/Tests/CMakeTests/ListTest.cmake.in
+++ b/Tests/CMakeTests/ListTest.cmake.in
@@ -85,6 +85,9 @@
 list(SORT result)
 TEST("SORT result" "andy;bill;brad;ken")
 
+list(SORT result COMPARE NATURAL)
+TEST("SORT result COMPARE NATURAL" "andy;bill;brad;ken")
+
 set(result andy bill brad ken)
 list(REVERSE result)
 TEST("REVERSE result" "ken;brad;bill;andy")
@@ -104,6 +107,26 @@
 list(SORT result)
 TEST("SORT empty result" "")
 
+list(SORT result COMPARE NATURAL)
+TEST("SORT result COMPARE NATURAL" "")
+
+set(result 1.1 10.0 11.0 12.0 12.1 2.0 2.1 3.0 3.1 3.2 8.0 9.0)
+
+list(SORT result COMPARE NATURAL)
+TEST("SORT result COMPARE NATURAL" "1.1;2.0;2.1;3.0;3.1;3.2;8.0;9.0;10.0;11.0;12.0;12.1")
+
+list(SORT result)
+TEST("SORT result" "1.1;10.0;11.0;12.0;12.1;2.0;2.1;3.0;3.1;3.2;8.0;9.0")
+
+list(SORT result COMPARE NATURAL ORDER DESCENDING)
+TEST("SORT result COMPARE NATURAL ORDER DESCENDING" "12.1;12.0;11.0;10.0;9.0;8.0;3.2;3.1;3.0;2.1;2.0;1.1")
+
+set(result b-1.1 a-10.0 c-2.0 d 1 00 0)
+
+list(SORT result COMPARE NATURAL)
+TEST("SORT result COMPARE NATURAL" "00;0;1;a-10.0;b-1.1;c-2.0;d")
+
+
 # these trigger top-level condition
 foreach(cmd IN ITEMS Append Find Get Insert Length Reverse Remove_At Remove_Duplicates Remove_Item Sort)
   set(${cmd}-No-Arguments-RESULT 1)
diff --git a/Tests/COnly/CMakeLists.txt b/Tests/COnly/CMakeLists.txt
index 20615fe..1c24017 100644
--- a/Tests/COnly/CMakeLists.txt
+++ b/Tests/COnly/CMakeLists.txt
@@ -1,5 +1,5 @@
 # a simple C only test case
-cmake_minimum_required (VERSION 2.6)
+cmake_minimum_required(VERSION 2.8.12)
 project (COnly C)
 
 set(CMAKE_DEBUG_POSTFIX "_test_debug_postfix")
diff --git a/Tests/CPackComponents/Issue 7470.html b/Tests/CPackComponents/Issue 7470.html
index c2a1688..59fbee7 100644
--- a/Tests/CPackComponents/Issue 7470.html
+++ b/Tests/CPackComponents/Issue 7470.html
@@ -3,7 +3,7 @@
 The install rule for this file demonstrates the problem described in<br/>
 CMake issue #7470:<br/>
 <br/>
-<a href="https://gitlab.kitware.com/cmake/cmake/issues/7470">
-https://gitlab.kitware.com/cmake/cmake/issues/7470</a><br/>
+<a href="https://gitlab.kitware.com/cmake/cmake/-/issues/7470">
+https://gitlab.kitware.com/cmake/cmake/-/issues/7470</a><br/>
 </body>
 </html>
diff --git a/Tests/CPackComponentsForAll/RunCPackVerifyResult.cmake b/Tests/CPackComponentsForAll/RunCPackVerifyResult.cmake
index 253d128..f3d3ad0 100644
--- a/Tests/CPackComponentsForAll/RunCPackVerifyResult.cmake
+++ b/Tests/CPackComponentsForAll/RunCPackVerifyResult.cmake
@@ -88,12 +88,14 @@
     set(expected_file_mask "${CPackComponentsForAll_BINARY_DIR}/MyLib-*.dmg")
     if(${CPackComponentWay} STREQUAL "default")
         set(expected_count 1)
+        set(expect_dmg_sla 1)
     elseif(${CPackComponentWay} STREQUAL "OnePackPerGroup")
         set(expected_count 3)
     elseif(${CPackComponentWay} STREQUAL "IgnoreGroup")
         set(expected_count 4)
     elseif(${CPackComponentWay} STREQUAL "AllInOne")
         set(expected_count 1)
+        set(expect_dmg_sla 1)
     endif()
 endif()
 
@@ -138,6 +140,36 @@
   if(NOT actual_count EQUAL expected_count)
     message(FATAL_ERROR "error: expected_count=${expected_count} does not match actual_count=${actual_count}: CPackComponents test fails. (CPack_output=${CPack_output}, CPack_error=${CPack_error})")
   endif()
+
+  if(expect_dmg_sla)
+    execute_process(COMMAND hdiutil udifderez -xml "${expected_file}" OUTPUT_VARIABLE out ERROR_VARIABLE err RESULT_VARIABLE res)
+    if(NOT res EQUAL 0)
+      string(REPLACE "\n" "\n  " err "  ${err}")
+      message(FATAL_ERROR "error: running 'hdiutil udifderez -xml' on\n  ${expected_file}\nfailed with:\n${err}")
+    endif()
+    foreach(key "LPic" "STR#" "TEXT")
+      if(NOT out MATCHES "<key>${key}</key>")
+        string(REPLACE "\n" "\n  " out "  ${out}")
+        message(FATAL_ERROR "error: running 'hdiutil udifderez -xml' on\n  ${expected_file}\ndid not show '${key}' key:\n${out}")
+      endif()
+    endforeach()
+    foreach(line
+        # LPic first and last base64 lines
+        "\tAAIAEQADAAEAAAAAAAIAAAAIAAMAAAABAAQAAAAEAAUAAAAOAAYA\n"
+        "\tAA0AAABbAAQAAAAzAA8AAQAMABAAAAALAA4AAA==\n"
+        # STR# first and last base64 lines
+        "\tAAkHRW5nbGlzaAVBZ3JlZQhEaXNhZ3JlZQVQcmludAdTYXZlLi4u\n"
+        "\tdGVkIGEgcHJpbnRlci4=\n"
+        # TEXT first and last base64 lines
+        "\tTElDRU5TRQ0tLS0tLS0tDVRoaXMgaXMgYW4gaW5zdGFsbGVyIGNy\n"
+        "\tTm8gbGljZW5zZSBwcm92aWRlZC4NDQ==\n"
+        )
+      if(NOT out MATCHES "${line}")
+        string(REPLACE "\n" "\n  " out "  ${out}")
+        message(FATAL_ERROR "error: running 'hdiutil udifderez -xml' on\n  ${expected_file}\ndid not show '${line}':\n${out}")
+      endif()
+    endforeach()
+  endif()
 endif()
 
 # Validate content
diff --git a/Tests/CPackNSISGenerator/CMakeLists.txt b/Tests/CPackNSISGenerator/CMakeLists.txt
index b8b2ed6..8ed4d59 100644
--- a/Tests/CPackNSISGenerator/CMakeLists.txt
+++ b/Tests/CPackNSISGenerator/CMakeLists.txt
@@ -16,5 +16,6 @@
 set(CPACK_NSIS_MUI_UNIICON "${PROJECT_SOURCE_DIR}\\\\uninstall.ico")
 set(CPACK_GENERATOR "NSIS")
 set(CPACK_NSIS_ENABLE_UNINSTALL_BEFORE_INSTALL ON)
+set(CPACK_NSIS_MANIFEST_DPI_AWARE ON)
 
 include(CPack)
diff --git a/Tests/CPackNSISGenerator/RunCPackVerifyResult.cmake b/Tests/CPackNSISGenerator/RunCPackVerifyResult.cmake
index 01b37c5..bfbcf9c 100644
--- a/Tests/CPackNSISGenerator/RunCPackVerifyResult.cmake
+++ b/Tests/CPackNSISGenerator/RunCPackVerifyResult.cmake
@@ -44,3 +44,11 @@
 if("${output_index}" EQUAL "-1")
   message(FATAL_ERROR "MUI_HEADERIMAGE_BITMAP not found in the project")
 endif()
+
+file(STRINGS "${project_file}" line REGEX "^ManifestDPIAware true")
+string(FIND "${line}" "true" output_index)
+if("${output_index}" EQUAL "-1")
+  message(FATAL_ERROR "ManifestDPIAware true not found in the project")
+else()
+  message(STATUS "Found DPI-aware")
+endif()
diff --git a/Tests/CPackWiXGenerator/CMakeLists.txt b/Tests/CPackWiXGenerator/CMakeLists.txt
index 73eaf4f..940e849 100644
--- a/Tests/CPackWiXGenerator/CMakeLists.txt
+++ b/Tests/CPackWiXGenerator/CMakeLists.txt
@@ -49,6 +49,9 @@
 set(CPACK_WIX_UPGRADE_GUID "BF20CE5E-7F7C-401D-8F7C-AB45E8D170E6")
 set(CPACK_WIX_UNINSTALL "1")
 
+# Support non-interactive sessions (like CI).
+set(CPACK_WIX_LIGHT_EXTRA_FLAGS "-sval")
+
 set(CPACK_PACKAGE_EXECUTABLES
   "my-libapp" "CPack WiX Test"
   "my-other-app" "Second CPack WiX Test"
diff --git a/Tests/CPackWiXGenerator/RunCPackVerifyResult.cmake b/Tests/CPackWiXGenerator/RunCPackVerifyResult.cmake
index ca9fd90..c549e61 100644
--- a/Tests/CPackWiXGenerator/RunCPackVerifyResult.cmake
+++ b/Tests/CPackWiXGenerator/RunCPackVerifyResult.cmake
@@ -74,4 +74,6 @@
 # error SMOK1076 : ICE61: This product should remove only older
 # versions of itself. The Maximum version is not less
 # than the current product. (1.0.0 1.0.0)
-run_wix_command(smoke -nologo -wx -sw1076 "${installer_file}")
+if (NOT no_verify)
+  run_wix_command(smoke -nologo -wx -sw1076 "${installer_file}")
+endif ()
diff --git a/Tests/CPackWiXGenerator/myotherapp.cpp b/Tests/CPackWiXGenerator/myotherapp.cpp
index 0eefc1c..5047a34 100644
--- a/Tests/CPackWiXGenerator/myotherapp.cpp
+++ b/Tests/CPackWiXGenerator/myotherapp.cpp
@@ -1,3 +1,3 @@
 int main()
 {
-}
\ No newline at end of file
+}
diff --git a/Tests/CSharpOnly/CMakeLists.txt b/Tests/CSharpOnly/CMakeLists.txt
index 82049c7..195af05 100644
--- a/Tests/CSharpOnly/CMakeLists.txt
+++ b/Tests/CSharpOnly/CMakeLists.txt
@@ -1,8 +1,11 @@
+cmake_minimum_required(VERSION 3.3)
 # a simple CSharp only test case
 project (CSharpOnly CSharp)
 
 # C# does not make any difference between STATIC and SHARED libs
-add_library(lib1 STATIC lib1.cs)
+add_library(lib1 STATIC lib1.cs nested/lib1.cs)
+#without the source group this test will fail to compile
+source_group(nested FILES nested/lib1.cs)
 add_library(lib2 SHARED lib2.cs)
 
 add_executable(CSharpOnly csharponly.cs)
diff --git a/Tests/CSharpOnly/csharponly.cs b/Tests/CSharpOnly/csharponly.cs
index ad4641a..3890c82 100644
--- a/Tests/CSharpOnly/csharponly.cs
+++ b/Tests/CSharpOnly/csharponly.cs
@@ -5,10 +5,8 @@
         public static void Main(string[] args)
         {
             int val = Lib1.getResult();
-
             Lib2 l = new Lib2();
-            val = l.myVal;
-
+            val = val +  l.myVal + nested.Lib1.getResult();
             return;
         }
     }
diff --git a/Tests/CSharpOnly/nested/lib1.cs b/Tests/CSharpOnly/nested/lib1.cs
new file mode 100644
index 0000000..c2fde4b
--- /dev/null
+++ b/Tests/CSharpOnly/nested/lib1.cs
@@ -0,0 +1,13 @@
+namespace CSharpOnly
+{
+    namespace nested
+    {
+        public class Lib1
+        {
+            public static int getResult()
+            {
+                return 23;
+            }
+        }
+    }
+}
diff --git a/Tests/CTestCoverageCollectGCOV/test.cmake.in b/Tests/CTestCoverageCollectGCOV/test.cmake.in
index 2c98876..1818888 100644
--- a/Tests/CTestCoverageCollectGCOV/test.cmake.in
+++ b/Tests/CTestCoverageCollectGCOV/test.cmake.in
@@ -3,13 +3,15 @@
 set(CTEST_BINARY_DIRECTORY "@CMake_BINARY_DIR@/Tests/CTestCoverageCollectGCOV/TestProject")
 set(CTEST_CMAKE_GENERATOR "@CMAKE_GENERATOR@")
 
-ctest_empty_binary_directory(${CTEST_BINARY_DIRECTORY})
-
 ctest_start(Experimental)
 ctest_configure()
 ctest_build()
 ctest_test()
 
+#------------------------------------------------------------------------------#
+# Common setup for all tests.
+#------------------------------------------------------------------------------#
+
 list(APPEND CTEST_CUSTOM_COVERAGE_EXCLUDE
   "/foo/something"
   "/3rdparty/"
@@ -17,15 +19,28 @@
   "/CMakeFiles/"
 )
 list(APPEND CTEST_EXTRA_COVERAGE_GLOB "*.cpp")
-
 include(CTestCoverageCollectGCOV)
-set(tar_file ${CTEST_BINARY_DIRECTORY}/gcov.tar)
+set(expected_out
+  CMakeFiles/myexecutable.dir/Labels.json
+  Testing/CoverageInfo/data.json
+  Testing/CoverageInfo/extra.cpp.gcov
+  Testing/CoverageInfo/main.cpp.gcov
+  uncovered/extra/uncovered1.cpp
+  uncovered/uncovered2.cpp
+)
+
+#------------------------------------------------------------------------------#
+# Test 1: with standard arguments
+#------------------------------------------------------------------------------#
+
+set(tar_file ${CTEST_BINARY_DIRECTORY}/gcov.tbz)
 ctest_coverage_collect_gcov(
   TARBALL "${tar_file}"
   SOURCE "${CTEST_SOURCE_DIRECTORY}"
   BUILD "${CTEST_BINARY_DIRECTORY}"
   GCOV_COMMAND "${CMAKE_COMMAND}"
   GCOV_OPTIONS -P "@CMake_SOURCE_DIR@/Tests/CTestCoverageCollectGCOV/fakegcov.cmake")
+file(REMOVE_RECURSE "${CTEST_BINARY_DIRECTORY}/uncovered")
 
 execute_process(COMMAND
   ${CMAKE_COMMAND} -E tar tf ${tar_file}
@@ -37,15 +52,126 @@
 string(REPLACE "\n" ";" out "${out}")
 list(SORT out)
 
-set(expected_out
-  CMakeFiles/myexecutable.dir/Labels.json
-  Testing/CoverageInfo/data.json
-  Testing/CoverageInfo/extra.cpp.gcov
-  Testing/CoverageInfo/main.cpp.gcov
-  uncovered/extra/uncovered1.cpp
-  uncovered/uncovered2.cpp
+if("${out}" STREQUAL "${expected_out}")
+  message("PASSED with correct output: ${out}")
+else()
+  message(FATAL_ERROR "FAILED: expected:\n${expected_out}\nGot:\n${out}")
+endif()
+
+#------------------------------------------------------------------------------#
+# Test 2: with optional argument: TARBALL_COMPRESSION "GZIP"
+#------------------------------------------------------------------------------#
+
+set(tar_file ${CTEST_BINARY_DIRECTORY}/gcov.tgz)
+ctest_coverage_collect_gcov(
+  TARBALL "${tar_file}"
+  TARBALL_COMPRESSION "GZIP"
+  SOURCE "${CTEST_SOURCE_DIRECTORY}"
+  BUILD "${CTEST_BINARY_DIRECTORY}"
+  GCOV_COMMAND "${CMAKE_COMMAND}"
+  GCOV_OPTIONS -P "@CMake_SOURCE_DIR@/Tests/CTestCoverageCollectGCOV/fakegcov.cmake")
+file(REMOVE_RECURSE "${CTEST_BINARY_DIRECTORY}/uncovered")
+
+execute_process(COMMAND
+  ${CMAKE_COMMAND} -E tar tf ${tar_file}
+  OUTPUT_VARIABLE out
+  WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}
+  OUTPUT_STRIP_TRAILING_WHITESPACE
 )
 
+string(REPLACE "\n" ";" out "${out}")
+list(SORT out)
+
+if("${out}" STREQUAL "${expected_out}")
+  message("PASSED with correct output: ${out}")
+else()
+  message(FATAL_ERROR "FAILED: expected:\n${expected_out}\nGot:\n${out}")
+endif()
+
+#------------------------------------------------------------------------------#
+# Test 3: with optional argument: TARBALL_COMPRESSION "FROM_EXT"
+#------------------------------------------------------------------------------#
+
+set(tar_file ${CTEST_BINARY_DIRECTORY}/gcov.txz)
+ctest_coverage_collect_gcov(
+  TARBALL "${tar_file}"
+  TARBALL_COMPRESSION "FROM_EXT"
+  SOURCE "${CTEST_SOURCE_DIRECTORY}"
+  BUILD "${CTEST_BINARY_DIRECTORY}"
+  GCOV_COMMAND "${CMAKE_COMMAND}"
+  GCOV_OPTIONS -P "@CMake_SOURCE_DIR@/Tests/CTestCoverageCollectGCOV/fakegcov.cmake")
+file(REMOVE_RECURSE "${CTEST_BINARY_DIRECTORY}/uncovered")
+
+execute_process(COMMAND
+  ${CMAKE_COMMAND} -E tar tf ${tar_file}
+  OUTPUT_VARIABLE out
+  WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}
+  OUTPUT_STRIP_TRAILING_WHITESPACE
+)
+
+string(REPLACE "\n" ";" out "${out}")
+list(SORT out)
+
+if("${out}" STREQUAL "${expected_out}")
+  message("PASSED with correct output: ${out}")
+else()
+  message(FATAL_ERROR "FAILED: expected:\n${expected_out}\nGot:\n${out}")
+endif()
+
+#------------------------------------------------------------------------------#
+# Test 4: with optional argument: TARBALL_COMPRESSION "FALSE"
+#------------------------------------------------------------------------------#
+
+set(tar_file ${CTEST_BINARY_DIRECTORY}/gcov.tar)
+ctest_coverage_collect_gcov(
+  TARBALL "${tar_file}"
+  TARBALL_COMPRESSION "FALSE"
+  SOURCE "${CTEST_SOURCE_DIRECTORY}"
+  BUILD "${CTEST_BINARY_DIRECTORY}"
+  GCOV_COMMAND "${CMAKE_COMMAND}"
+  GCOV_OPTIONS -P "@CMake_SOURCE_DIR@/Tests/CTestCoverageCollectGCOV/fakegcov.cmake")
+file(REMOVE_RECURSE "${CTEST_BINARY_DIRECTORY}/uncovered")
+
+execute_process(COMMAND
+  ${CMAKE_COMMAND} -E tar tf ${tar_file}
+  OUTPUT_VARIABLE out
+  WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}
+  OUTPUT_STRIP_TRAILING_WHITESPACE
+)
+
+string(REPLACE "\n" ";" out "${out}")
+list(SORT out)
+
+if("${out}" STREQUAL "${expected_out}")
+  message("PASSED with correct output: ${out}")
+else()
+  message(FATAL_ERROR "FAILED: expected:\n${expected_out}\nGot:\n${out}")
+endif()
+
+#------------------------------------------------------------------------------#
+# Test 5: with optional argument: TARBALL_COMPRESSION "ZSTD"
+#------------------------------------------------------------------------------#
+
+set(tar_file ${CTEST_BINARY_DIRECTORY}/gcov.zstd)
+ctest_coverage_collect_gcov(
+  TARBALL "${tar_file}"
+  TARBALL_COMPRESSION "ZSTD"
+  SOURCE "${CTEST_SOURCE_DIRECTORY}"
+  BUILD "${CTEST_BINARY_DIRECTORY}"
+  GCOV_COMMAND "${CMAKE_COMMAND}"
+  GCOV_OPTIONS -P "@CMake_SOURCE_DIR@/Tests/CTestCoverageCollectGCOV/fakegcov.cmake")
+file(REMOVE_RECURSE "${CTEST_BINARY_DIRECTORY}/uncovered")
+
+execute_process(COMMAND
+  ${CMAKE_COMMAND} -E tar tf ${tar_file}
+  OUTPUT_VARIABLE out
+  WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}
+  OUTPUT_STRIP_TRAILING_WHITESPACE
+)
+
+string(REPLACE "\n" ";" out "${out}")
+list(SORT out)
+
 if("${out}" STREQUAL "${expected_out}")
   message("PASSED with correct output: ${out}")
 else()
diff --git a/Tests/CTestLimitDashJ/CMakeLists.txt b/Tests/CTestLimitDashJ/CMakeLists.txt
index 92d743f..5208d2d 100644
--- a/Tests/CTestLimitDashJ/CMakeLists.txt
+++ b/Tests/CTestLimitDashJ/CMakeLists.txt
@@ -1,7 +1,7 @@
 cmake_minimum_required(VERSION 2.8)
 project(CTestLimitDashJ NONE)
 
-# This file demonstrates https://gitlab.kitware.com/cmake/cmake/issues/12904
+# This file demonstrates https://gitlab.kitware.com/cmake/cmake/-/issues/12904
 # when configured with CMake 2.8.10.2 and earlier, and when running
 # "ctest -j 4" in the resulting build tree. This example is hard-coded
 # to assume -j 4 just to reproduce the issue easily. Adjust the
diff --git a/Tests/CheckFortran.cmake b/Tests/CheckFortran.cmake
index 16a8ed2..33e1bfb 100644
--- a/Tests/CheckFortran.cmake
+++ b/Tests/CheckFortran.cmake
@@ -11,6 +11,7 @@
 project(CheckFortran Fortran)
 file(WRITE \"\${CMAKE_CURRENT_BINARY_DIR}/result.cmake\"
   \"set(CMAKE_Fortran_COMPILER \\\"\${CMAKE_Fortran_COMPILER}\\\")\\n\"
+  \"set(CMAKE_Fortran_COMPILER_ID \\\"\${CMAKE_Fortran_COMPILER_ID}\\\")\\n\"
   \"set(CMAKE_Fortran_FLAGS \\\"\${CMAKE_Fortran_FLAGS}\\\")\\n\"
   \"set(CMAKE_Fortran_COMPILER_SUPPORTS_F90 \\\"\${CMAKE_Fortran_COMPILER_SUPPORTS_F90}\\\")\\n\"
   )
@@ -45,6 +46,8 @@
   message(STATUS "${_desc} - ${CMAKE_Fortran_COMPILER}")
   set(CMAKE_Fortran_COMPILER "${CMAKE_Fortran_COMPILER}" CACHE FILEPATH "Fortran compiler")
   mark_as_advanced(CMAKE_Fortran_COMPILER)
+  set(CMAKE_Fortran_COMPILER_ID "${CMAKE_Fortran_COMPILER_ID}" CACHE STRING "Fortran compiler Id")
+  mark_as_advanced(CMAKE_Fortran_COMPILER_ID)
   set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS}" CACHE STRING "Fortran flags")
   mark_as_advanced(CMAKE_Fortran_FLAGS)
   set(CMAKE_Fortran_COMPILER_SUPPORTS_F90 "${CMAKE_Fortran_COMPILER_SUPPORTS_F90}" CACHE BOOL "Fortran compiler supports F90")
diff --git a/Tests/ConfigSources/CMakeLists.txt b/Tests/ConfigSources/CMakeLists.txt
index f5dd276..6e69e8b 100644
--- a/Tests/ConfigSources/CMakeLists.txt
+++ b/Tests/ConfigSources/CMakeLists.txt
@@ -1,6 +1,17 @@
 cmake_minimum_required(VERSION 3.0)
+get_property(_isMultiConfig GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
+if(NOT _isMultiConfig AND NOT CMAKE_BUILD_TYPE)
+  set(CMAKE_BUILD_TYPE Debug CACHE STRING "Choose the type of build")
+endif()
 project(ConfigSources CXX)
 
+# Source file(s) named with the configuration(s).
+file(GENERATE
+  OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/config_$<CONFIG>.cpp"
+  CONTENT "void config_$<CONFIG>() {}\n"
+  )
+
+# Per-config sources via INTERFACE_SOURCES.
 add_library(iface INTERFACE)
 target_sources(iface INTERFACE
   "${CMAKE_CURRENT_SOURCE_DIR}/iface_src.cpp"
@@ -12,10 +23,56 @@
   "$<$<CONFIG:Debug>:CFG_DEBUG>"
   "$<$<NOT:$<CONFIG:Debug>>:CFG_OTHER>"
   )
-
 add_executable(ConfigSources
   $<$<CONFIG:Debug>:main_debug.cpp>
   $<$<NOT:$<CONFIG:Debug>>:main_other.cpp>
   $<$<CONFIG:NotAConfig>:does_not_exist.cpp>
+  ${CMAKE_CURRENT_BINARY_DIR}/config_$<CONFIG>.cpp
   )
 target_link_libraries(ConfigSources iface)
+
+# Per-config sources via LINK_LIBRARIES.
+add_library(iface_debug INTERFACE)
+target_sources(iface_debug INTERFACE
+  "${CMAKE_CURRENT_SOURCE_DIR}/iface_src.cpp"
+  "${CMAKE_CURRENT_SOURCE_DIR}/iface_debug_src.cpp"
+  )
+add_library(iface_other INTERFACE)
+target_sources(iface_other INTERFACE
+  "${CMAKE_CURRENT_SOURCE_DIR}/iface_src.cpp"
+  "${CMAKE_CURRENT_SOURCE_DIR}/iface_other_src.cpp"
+  )
+add_executable(ConfigSourcesLink main.cpp)
+target_compile_definitions(ConfigSourcesLink PRIVATE
+  "$<$<CONFIG:Debug>:CFG_DEBUG>"
+  "$<$<NOT:$<CONFIG:Debug>>:CFG_OTHER>"
+  )
+target_link_libraries(ConfigSourcesLink PRIVATE
+  "$<$<CONFIG:Debug>:iface_debug>"
+  "$<$<NOT:$<CONFIG:Debug>>:iface_other>"
+  "$<$<CONFIG:NotAConfig>:iface_does_not_exist>"
+  )
+
+# Per-config sources via INTERFACE_LINK_LIBRARIES.
+add_library(ConfigSourcesIface INTERFACE)
+target_link_libraries(ConfigSourcesIface INTERFACE
+  "$<$<CONFIG:Debug>:iface_debug>"
+  "$<$<NOT:$<CONFIG:Debug>>:iface_other>"
+  "$<$<CONFIG:NotAConfig>:iface_does_not_exist>"
+  )
+add_executable(ConfigSourcesLinkIface main.cpp)
+target_compile_definitions(ConfigSourcesLinkIface PRIVATE
+  "$<$<CONFIG:Debug>:CFG_DEBUG>"
+  "$<$<NOT:$<CONFIG:Debug>>:CFG_OTHER>"
+  )
+target_link_libraries(ConfigSourcesLinkIface ConfigSourcesIface)
+
+# A target with sources in only one configuration that is not the
+# first in CMAKE_CONFIGURATION_TYPES.
+if(CMAKE_CONFIGURATION_TYPES MATCHES ";([^;]+)")
+  set(one_config "${CMAKE_MATCH_1}")
+else()
+  set(one_config "${CMAKE_BUILD_TYPE}")
+endif()
+add_library(OneConfigOnly OBJECT "$<$<CONFIG:${one_config}>:${CMAKE_CURRENT_SOURCE_DIR}/iface_src.cpp>")
+set_property(TARGET OneConfigOnly PROPERTY LINKER_LANGUAGE CXX)
diff --git a/Tests/ConfigSources/main.cpp b/Tests/ConfigSources/main.cpp
new file mode 100644
index 0000000..c1cd3b2
--- /dev/null
+++ b/Tests/ConfigSources/main.cpp
@@ -0,0 +1,9 @@
+#if !defined(CFG_DEBUG) && !defined(CFG_OTHER)
+#  error "Neither CFG_DEBUG or CFG_OTHER is defined."
+#endif
+#ifdef CFG_DEBUG
+#  include "main_debug.cpp"
+#endif
+#ifdef CFG_OTHER
+#  include "main_other.cpp"
+#endif
diff --git a/Tests/Contracts/VTK/Dashboard.cmake.in b/Tests/Contracts/VTK/Dashboard.cmake.in
index c3d10f4..ae760bc 100644
--- a/Tests/Contracts/VTK/Dashboard.cmake.in
+++ b/Tests/Contracts/VTK/Dashboard.cmake.in
@@ -24,8 +24,8 @@
 ctest_empty_binary_directory(${CTEST_BINARY_DIRECTORY})
 
 file(WRITE "${CTEST_BINARY_DIRECTORY}/CMakeCache.txt" "
-  BUILD_EXAMPLES:BOOL=ON
-  BUILD_TESTING:BOOL=ON
+  VTK_BUILD_EXAMPLES:BOOL=ON
+  VTK_BUILD_TESTING:STRING=WANT
   VTK_WRAP_PYTHON:BOOL=ON
   ExternalData_OBJECT_STORES:FILEPATH=@base_dir@/ExternalData
 ")
diff --git a/Tests/Cuda/CMakeLists.txt b/Tests/Cuda/CMakeLists.txt
index 58b9b03..35ceb33 100644
--- a/Tests/Cuda/CMakeLists.txt
+++ b/Tests/Cuda/CMakeLists.txt
@@ -1,25 +1,35 @@
+macro (add_cuda_test_macro name)
+  add_test_macro("${name}" ${ARGN})
+  set_property(TEST "${name}" APPEND
+    PROPERTY LABELS "CUDA")
+endmacro ()
 
-ADD_TEST_MACRO(Cuda.Complex CudaComplex)
-ADD_TEST_MACRO(Cuda.ConsumeCompileFeatures CudaConsumeCompileFeatures)
-ADD_TEST_MACRO(Cuda.CXXStandardSetTwice CXXStandardSetTwice)
-ADD_TEST_MACRO(Cuda.ObjectLibrary CudaObjectLibrary)
-ADD_TEST_MACRO(Cuda.MixedStandardLevels1 MixedStandardLevels1)
-ADD_TEST_MACRO(Cuda.MixedStandardLevels2 MixedStandardLevels2)
-ADD_TEST_MACRO(Cuda.MixedStandardLevels3 MixedStandardLevels3)
-ADD_TEST_MACRO(Cuda.MixedStandardLevels4 MixedStandardLevels4)
-ADD_TEST_MACRO(Cuda.MixedStandardLevels5 MixedStandardLevels5)
-ADD_TEST_MACRO(Cuda.NotEnabled CudaNotEnabled)
-ADD_TEST_MACRO(Cuda.SeparableCompCXXOnly SeparableCompCXXOnly)
-ADD_TEST_MACRO(Cuda.Toolkit Toolkit)
-ADD_TEST_MACRO(Cuda.IncludePathNoToolkit IncludePathNoToolkit)
-ADD_TEST_MACRO(Cuda.ProperDeviceLibraries ProperDeviceLibraries)
-ADD_TEST_MACRO(Cuda.ProperLinkFlags ProperLinkFlags)
-ADD_TEST_MACRO(Cuda.SharedRuntimePlusToolkit SharedRuntimePlusToolkit)
+add_cuda_test_macro(Cuda.ConsumeCompileFeatures CudaConsumeCompileFeatures)
+add_cuda_test_macro(Cuda.CXXStandardSetTwice CXXStandardSetTwice)
+add_cuda_test_macro(Cuda.ObjectLibrary CudaObjectLibrary)
+add_cuda_test_macro(Cuda.MixedStandardLevels1 MixedStandardLevels1)
+add_cuda_test_macro(Cuda.MixedStandardLevels2 MixedStandardLevels2)
+add_cuda_test_macro(Cuda.MixedStandardLevels3 MixedStandardLevels3)
+add_cuda_test_macro(Cuda.MixedStandardLevels4 MixedStandardLevels4)
+add_cuda_test_macro(Cuda.MixedStandardLevels5 MixedStandardLevels5)
+add_cuda_test_macro(Cuda.NotEnabled CudaNotEnabled)
+add_cuda_test_macro(Cuda.SeparableCompCXXOnly SeparableCompCXXOnly)
+add_cuda_test_macro(Cuda.Toolkit Toolkit)
+add_cuda_test_macro(Cuda.IncludePathNoToolkit IncludePathNoToolkit)
+add_cuda_test_macro(Cuda.SharedRuntimePlusToolkit SharedRuntimePlusToolkit)
+
+# Separable compilation is currently only supported on NVCC. Disable tests
+# using it for other compilers.
+if(CMake_TEST_CUDA AND NOT CMake_TEST_CUDA STREQUAL "Clang")
+  add_cuda_test_macro(Cuda.Complex CudaComplex)
+  add_cuda_test_macro(Cuda.ProperDeviceLibraries ProperDeviceLibraries)
+  add_cuda_test_macro(Cuda.ProperLinkFlags ProperLinkFlags)
+endif()
 
 # The CUDA only ships the shared version of the toolkit libraries
 # on windows
 if(NOT WIN32)
-  ADD_TEST_MACRO(Cuda.StaticRuntimePlusToolkit StaticRuntimePlusToolkit)
+  add_cuda_test_macro(Cuda.StaticRuntimePlusToolkit StaticRuntimePlusToolkit)
 endif()
 
-ADD_TEST_MACRO(Cuda.WithC CudaWithC)
+add_cuda_test_macro(Cuda.WithC CudaWithC)
diff --git a/Tests/Cuda/CXXStandardSetTwice/CMakeLists.txt b/Tests/Cuda/CXXStandardSetTwice/CMakeLists.txt
index 1941c49..f4ad83a 100644
--- a/Tests/Cuda/CXXStandardSetTwice/CMakeLists.txt
+++ b/Tests/Cuda/CXXStandardSetTwice/CMakeLists.txt
@@ -1,9 +1,8 @@
 cmake_minimum_required(VERSION 3.7)
 project(CXXStandardSetTwice CXX CUDA)
 
-string(APPEND CMAKE_CUDA_FLAGS " -gencode arch=compute_30,code=compute_30")
-
 set(CMAKE_CXX_STANDARD 11)
+set(CMAKE_CUDA_ARCHITECTURES 30)
 
 add_executable(CXXStandardSetTwice main.cu)
 target_compile_features(CXXStandardSetTwice PUBLIC cxx_std_11)
diff --git a/Tests/Cuda/Complex/CMakeLists.txt b/Tests/Cuda/Complex/CMakeLists.txt
index 08d1e16..265bd85 100644
--- a/Tests/Cuda/Complex/CMakeLists.txt
+++ b/Tests/Cuda/Complex/CMakeLists.txt
@@ -15,7 +15,7 @@
 #and also building cpp targets that need cuda implicit libraries
 
 #verify that we can pass explicit cuda arch flags
-string(APPEND CMAKE_CUDA_FLAGS " -gencode arch=compute_30,code=compute_30")
+set(CMAKE_CUDA_ARCHITECTURES 30)
 set(CMAKE_CUDA_STANDARD 11)
 set(CMAKE_CXX_STANDARD 11)
 set(CMAKE_CUDA_STANDARD_REQUIRED TRUE)
diff --git a/Tests/Cuda/MixedStandardLevels1/CMakeLists.txt b/Tests/Cuda/MixedStandardLevels1/CMakeLists.txt
index b03e51e..e40ffa6 100644
--- a/Tests/Cuda/MixedStandardLevels1/CMakeLists.txt
+++ b/Tests/Cuda/MixedStandardLevels1/CMakeLists.txt
@@ -1,10 +1,9 @@
 cmake_minimum_required(VERSION 3.7)
 project(MixedStandardLevels1 CXX CUDA)
 
-string(APPEND CMAKE_CUDA_FLAGS " -gencode arch=compute_30,code=compute_30")
-
 set(CMAKE_CXX_STANDARD 14)
 set(CMAKE_CUDA_STANDARD 11)
+set(CMAKE_CUDA_ARCHITECTURES 30)
 
 add_executable(MixedStandardLevels1 main.cu lib.cpp)
 
diff --git a/Tests/Cuda/MixedStandardLevels2/CMakeLists.txt b/Tests/Cuda/MixedStandardLevels2/CMakeLists.txt
index 12dd328..7af8081 100644
--- a/Tests/Cuda/MixedStandardLevels2/CMakeLists.txt
+++ b/Tests/Cuda/MixedStandardLevels2/CMakeLists.txt
@@ -1,9 +1,8 @@
 cmake_minimum_required(VERSION 3.7)
 project(MixedStandardLevels2 CXX CUDA)
 
-string(APPEND CMAKE_CUDA_FLAGS " -gencode arch=compute_30,code=compute_30")
-
 set(CMAKE_CXX_STANDARD 17) #this can decay
+set(CMAKE_CUDA_ARCHITECTURES 30)
 
 add_executable(MixedStandardLevels2 main.cu lib.cpp)
 target_compile_features(MixedStandardLevels2 PUBLIC cuda_std_11)
diff --git a/Tests/Cuda/MixedStandardLevels3/CMakeLists.txt b/Tests/Cuda/MixedStandardLevels3/CMakeLists.txt
index 2b611be..2c42003 100644
--- a/Tests/Cuda/MixedStandardLevels3/CMakeLists.txt
+++ b/Tests/Cuda/MixedStandardLevels3/CMakeLists.txt
@@ -1,7 +1,7 @@
 cmake_minimum_required(VERSION 3.7)
 project(MixedStandardLevels3 CXX CUDA)
 
-string(APPEND CMAKE_CUDA_FLAGS " -gencode arch=compute_30,code=compute_30")
+set(CMAKE_CUDA_ARCHITECTURES 30)
 
 add_executable(MixedStandardLevels3 main.cu lib.cpp)
 target_compile_features(MixedStandardLevels3 PUBLIC cuda_std_03 cxx_std_14)
diff --git a/Tests/Cuda/MixedStandardLevels4/CMakeLists.txt b/Tests/Cuda/MixedStandardLevels4/CMakeLists.txt
index faf6869..230230d 100644
--- a/Tests/Cuda/MixedStandardLevels4/CMakeLists.txt
+++ b/Tests/Cuda/MixedStandardLevels4/CMakeLists.txt
@@ -1,9 +1,8 @@
 cmake_minimum_required(VERSION 3.7)
 project(MixedStandardLevels4 CXX CUDA)
 
-string(APPEND CMAKE_CUDA_FLAGS " -gencode arch=compute_30,code=compute_30")
-
 set(CMAKE_CUDA_STANDARD 03)
+set(CMAKE_CUDA_ARCHITECTURES 30)
 
 add_executable(MixedStandardLevels4 main.cu lib.cpp)
 target_compile_features(MixedStandardLevels4 PUBLIC cxx_std_14)
diff --git a/Tests/Cuda/MixedStandardLevels4/lib.cpp b/Tests/Cuda/MixedStandardLevels4/lib.cpp
index ef6fc20..2a65c77 100644
--- a/Tests/Cuda/MixedStandardLevels4/lib.cpp
+++ b/Tests/Cuda/MixedStandardLevels4/lib.cpp
@@ -3,7 +3,7 @@
 constexpr int func(int A, int B)
 {
 #if defined(_MSC_VER) && _MSC_VER < 1913
-  // no suppport for extended constexpr
+  // no support for extended constexpr
   return B * A;
 #else
   // Verify that we have at least c++14
diff --git a/Tests/Cuda/MixedStandardLevels5/CMakeLists.txt b/Tests/Cuda/MixedStandardLevels5/CMakeLists.txt
index 7209f60..5f5ee06 100644
--- a/Tests/Cuda/MixedStandardLevels5/CMakeLists.txt
+++ b/Tests/Cuda/MixedStandardLevels5/CMakeLists.txt
@@ -1,9 +1,8 @@
 cmake_minimum_required(VERSION 3.7)
 project(MixedStandardLevels5 CXX CUDA)
 
-string(APPEND CMAKE_CUDA_FLAGS " -gencode arch=compute_30,code=compute_30")
-
 set(CMAKE_CXX_STANDARD 98)
+set(CMAKE_CUDA_ARCHITECTURES 30)
 
 add_executable(MixedStandardLevels5 main.cu lib.cpp)
 
diff --git a/Tests/Cuda/ProperDeviceLibraries/CMakeLists.txt b/Tests/Cuda/ProperDeviceLibraries/CMakeLists.txt
index cb47b09..fe28c3e 100644
--- a/Tests/Cuda/ProperDeviceLibraries/CMakeLists.txt
+++ b/Tests/Cuda/ProperDeviceLibraries/CMakeLists.txt
@@ -1,8 +1,8 @@
 cmake_minimum_required(VERSION 3.13)
 project(ProperDeviceLibraries CXX CUDA)
 
-string(APPEND CMAKE_CUDA_FLAGS " -gencode arch=compute_35,code=compute_35 -gencode arch=compute_35,code=sm_35")
 set(CMAKE_CUDA_STANDARD 11)
+set(CMAKE_CUDA_ARCHITECTURES 35)
 
 set(THREADS_PREFER_PTHREAD_FLAG ON)
 find_package(Threads)
diff --git a/Tests/Cuda/ProperLinkFlags/CMakeLists.txt b/Tests/Cuda/ProperLinkFlags/CMakeLists.txt
index b6e0e39..d38da6d 100644
--- a/Tests/Cuda/ProperLinkFlags/CMakeLists.txt
+++ b/Tests/Cuda/ProperLinkFlags/CMakeLists.txt
@@ -9,11 +9,17 @@
 
 #Specify a set of valid CUDA flags and an invalid set of CXX flags ( for CUDA )
 #to make sure we don't use the CXX flags when linking CUDA executables
-string(APPEND CMAKE_CUDA_FLAGS " -arch=sm_35 --use_fast_math")
+if(CMAKE_CUDA_COMPILER_ID STREQUAL "NVIDIA")
+  string(APPEND CMAKE_CUDA_FLAGS "--use_fast_math")
+elseif(CMAKE_CUDA_COMPILER_ID STREQUAL "Clang")
+  string(APPEND CMAKE_CUDA_FLAGS "-ffast-math")
+endif()
+
 set(CMAKE_CXX_FLAGS "-Wall")
 
 set(CMAKE_CXX_STANDARD 11)
 set(CMAKE_CUDA_STANDARD 11)
+set(CMAKE_CUDA_ARCHITECTURES 35)
 add_executable(ProperLinkFlags file1.cu main.cxx)
 
 set_target_properties( ProperLinkFlags
diff --git a/Tests/Cuda/Toolkit/CMakeLists.txt b/Tests/Cuda/Toolkit/CMakeLists.txt
index 86b4652..00125e3 100644
--- a/Tests/Cuda/Toolkit/CMakeLists.txt
+++ b/Tests/Cuda/Toolkit/CMakeLists.txt
@@ -14,15 +14,29 @@
 message(STATUS "CUDAToolkit_LIBRARY_DIR: ${CUDAToolkit_LIBRARY_DIR}")
 message(STATUS "CUDAToolkit_NVCC_EXECUTABLE ${CUDAToolkit_NVCC_EXECUTABLE}")
 
-# Verify that all the CUDA:: targets exist even when the CUDA language isn't enabled
+set(cuda_libs cudart cuda_driver cublas cufft cufftw curand cusolver cusparse)
+if(CUDAToolkit_VERSION VERSION_GREATER_EQUAL 10.1)
+  list(APPEND cuda_libs cublasLt)
+endif()
+if(CUDAToolkit_VERSION_MAJOR VERSION_LESS 11)
+  list(APPEND cuda_libs nvgraph)
+endif()
 
-foreach (cuda_lib cudart cuda_driver cublas cufft cufftw curand cusolver cusparse nvgraph)
+# Verify that all the CUDA:: targets exist even when the CUDA language isn't enabled
+foreach (cuda_lib IN LISTS cuda_libs)
+  if(NOT CUDA_${cuda_lib}_LIBRARY)
+    message(FATAL_ERROR "expected CUDAToolkit variable CUDA_${cuda_lib}_LIBRARY not found")
+  endif()
   if(NOT TARGET CUDA::${cuda_lib})
-    message(FATAL_ERROR "The CUDA::${cuda_lib} target was expected but couldn't be found")
+    message(FATAL_ERROR "expected CUDAToolkit target CUDA::${cuda_lib} not found")
   endif()
 endforeach()
 
-foreach (cuda_lib nppc nppial nppicc nppidei nppif nppig nppim nppist nppitc npps nppicom nppisu)
+set(npp_libs nppc nppial nppicc nppidei nppif nppig nppim nppist nppitc npps nppisu)
+if(CUDAToolkit_VERSION_MAJOR VERSION_LESS 11)
+  list(APPEND npp_libs nppicom)
+endif()
+foreach (cuda_lib IN LISTS npp_libs)
   if(NOT TARGET CUDA::${cuda_lib})
     message(FATAL_ERROR "The CUDA::${cuda_lib} target was expected but couldn't be found")
   endif()
diff --git a/Tests/Cuda/WithC/CMakeLists.txt b/Tests/Cuda/WithC/CMakeLists.txt
index 69aa3f9..049cbce 100644
--- a/Tests/Cuda/WithC/CMakeLists.txt
+++ b/Tests/Cuda/WithC/CMakeLists.txt
@@ -1,7 +1,7 @@
 cmake_minimum_required(VERSION 3.7)
 project(WithC CUDA C)
 
-string(APPEND CMAKE_CUDA_FLAGS " -gencode arch=compute_30,code=compute_30")
+set(CMAKE_CUDA_ARCHITECTURES 30)
 
 add_executable(CudaWithC main.c cuda.cu)
 
diff --git a/Tests/CudaOnly/Architecture/CMakeLists.txt b/Tests/CudaOnly/Architecture/CMakeLists.txt
new file mode 100644
index 0000000..03e972f
--- /dev/null
+++ b/Tests/CudaOnly/Architecture/CMakeLists.txt
@@ -0,0 +1,15 @@
+cmake_minimum_required(VERSION 3.18)
+project(Architecture CUDA)
+
+add_executable(Architecture main.cu)
+set_property(TARGET Architecture PROPERTY CUDA_ARCHITECTURES 52)
+
+# Make sure CMake doesn't pass architectures if CUDA_ARCHITECTURES is OFF.
+if(CMAKE_CUDA_COMPILER_ID STREQUAL "NVIDIA")
+  set(CMAKE_CUDA_FLAGS "${CMAKE_CUDA_FLAGS} -arch=sm_52")
+elseif(CMAKE_CUDA_COMPILER_ID STREQUAL "Clang")
+  set(CMAKE_CUDA_FLAGS "${CMAKE_CUDA_FLAGS} --cuda-gpu-arch=sm_52")
+endif()
+
+add_executable(ArchitectureOff main.cu)
+set_property(TARGET ArchitectureOff PROPERTY CUDA_ARCHITECTURES OFF)
diff --git a/Tests/CudaOnly/Architecture/main.cu b/Tests/CudaOnly/Architecture/main.cu
new file mode 100644
index 0000000..8c817d5
--- /dev/null
+++ b/Tests/CudaOnly/Architecture/main.cu
@@ -0,0 +1,9 @@
+#ifdef __CUDA_ARCH__
+#  if __CUDA_ARCH__ != 520
+#    error "Passed architecture 52, but got something else."
+#  endif
+#endif
+
+int main()
+{
+}
diff --git a/Tests/CudaOnly/CMakeLists.txt b/Tests/CudaOnly/CMakeLists.txt
index 3e3e44c..7376a73 100644
--- a/Tests/CudaOnly/CMakeLists.txt
+++ b/Tests/CudaOnly/CMakeLists.txt
@@ -1,37 +1,54 @@
+macro (add_cuda_test_macro name)
+  add_test_macro("${name}" ${ARGN})
+  set_property(TEST "${name}" APPEND
+    PROPERTY LABELS "CUDA")
+endmacro ()
 
-ADD_TEST_MACRO(CudaOnly.CircularLinkLine CudaOnlyCircularLinkLine)
-ADD_TEST_MACRO(CudaOnly.EnableStandard CudaOnlyEnableStandard)
-ADD_TEST_MACRO(CudaOnly.ExportPTX CudaOnlyExportPTX)
-ADD_TEST_MACRO(CudaOnly.GPUDebugFlag CudaOnlyGPUDebugFlag)
-ADD_TEST_MACRO(CudaOnly.ResolveDeviceSymbols CudaOnlyResolveDeviceSymbols)
-ADD_TEST_MACRO(CudaOnly.SeparateCompilation CudaOnlySeparateCompilation)
-ADD_TEST_MACRO(CudaOnly.SharedRuntimePlusToolkit CudaOnlySharedRuntimePlusToolkit)
-ADD_TEST_MACRO(CudaOnly.SharedRuntimeViaCUDAFlags CudaOnlySharedRuntimeViaCUDAFlags)
-ADD_TEST_MACRO(CudaOnly.Standard98 CudaOnlyStandard98)
-ADD_TEST_MACRO(CudaOnly.Toolkit CudaOnlyToolkit)
-ADD_TEST_MACRO(CudaOnly.WithDefs CudaOnlyWithDefs)
+add_cuda_test_macro(CudaOnly.Architecture Architecture)
+add_cuda_test_macro(CudaOnly.CompileFlags CudaOnlyCompileFlags)
+add_cuda_test_macro(CudaOnly.EnableStandard CudaOnlyEnableStandard)
+add_cuda_test_macro(CudaOnly.ExportPTX CudaOnlyExportPTX)
+add_cuda_test_macro(CudaOnly.SharedRuntimePlusToolkit CudaOnlySharedRuntimePlusToolkit)
+add_cuda_test_macro(CudaOnly.Standard98 CudaOnlyStandard98)
+add_cuda_test_macro(CudaOnly.Toolkit CudaOnlyToolkit)
+add_cuda_test_macro(CudaOnly.WithDefs CudaOnlyWithDefs)
+
+if(CMake_TEST_CUDA AND NOT CMake_TEST_CUDA STREQUAL "Clang")
+  add_cuda_test_macro(CudaOnly.SharedRuntimeViaCUDAFlags CudaOnlySharedRuntimeViaCUDAFlags)
+
+  # Separable compilation is currently only supported on NVCC. Disable tests
+  # using it for other compilers.
+  add_cuda_test_macro(CudaOnly.CircularLinkLine CudaOnlyCircularLinkLine)
+  add_cuda_test_macro(CudaOnly.ResolveDeviceSymbols CudaOnlyResolveDeviceSymbols)
+  add_cuda_test_macro(CudaOnly.SeparateCompilation CudaOnlySeparateCompilation)
+
+  add_test(NAME CudaOnly.DontResolveDeviceSymbols COMMAND
+    ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
+    --build-and-test
+    "${CMAKE_CURRENT_SOURCE_DIR}/DontResolveDeviceSymbols/"
+    "${CMAKE_CURRENT_BINARY_DIR}/DontResolveDeviceSymbols/"
+    ${build_generator_args}
+    --build-project DontResolveDeviceSymbols
+    --build-options ${build_options}
+    --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
+  )
+  set_property(TEST "CudaOnly.DontResolveDeviceSymbols" APPEND
+    PROPERTY LABELS "CUDA")
+
+  # Only NVCC defines __CUDACC_DEBUG__ when compiling in debug mode.
+  add_cuda_test_macro(CudaOnly.GPUDebugFlag CudaOnlyGPUDebugFlag)
+endif()
 
 # The CUDA only ships the shared version of the toolkit libraries
 # on windows
 if(NOT WIN32)
-  ADD_TEST_MACRO(Cuda.StaticRuntimePlusToolkit StaticRuntimePlusToolkit)
+  add_cuda_test_macro(CudaOnly.StaticRuntimePlusToolkit CudaOnlyStaticRuntimePlusToolkit)
 endif()
 
 if(MSVC)
-  ADD_TEST_MACRO(CudaOnly.PDB CudaOnlyPDB)
+  add_cuda_test_macro(CudaOnly.PDB CudaOnlyPDB)
 endif()
 
-add_test(NAME CudaOnly.DontResolveDeviceSymbols COMMAND
-  ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
-  --build-and-test
-  "${CMAKE_CURRENT_SOURCE_DIR}/DontResolveDeviceSymbols/"
-  "${CMAKE_CURRENT_BINARY_DIR}/DontResolveDeviceSymbols/"
-  ${build_generator_args}
-  --build-project DontResolveDeviceSymbols
-  --build-options ${build_options}
-  --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
-  )
-
 add_test(NAME CudaOnly.RuntimeControls COMMAND
   ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
   --build-and-test
@@ -43,3 +60,5 @@
   --build-options ${build_options}
   --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
   )
+set_property(TEST "CudaOnly.RuntimeControls" APPEND
+  PROPERTY LABELS "CUDA")
diff --git a/Tests/CudaOnly/CircularLinkLine/CMakeLists.txt b/Tests/CudaOnly/CircularLinkLine/CMakeLists.txt
index 5e6f7ab..e10a348 100644
--- a/Tests/CudaOnly/CircularLinkLine/CMakeLists.txt
+++ b/Tests/CudaOnly/CircularLinkLine/CMakeLists.txt
@@ -5,9 +5,9 @@
 # Verify that we de-duplicate the device link line
 # Verify that a de-duplicated link line still works with circular static libraries
 
-string(APPEND CMAKE_CUDA_FLAGS " -gencode arch=compute_30,code=[compute_30]")
 set(CMAKE_CXX_STANDARD 11)
 set(CMAKE_CUDA_STANDARD 11)
+set(CMAKE_CUDA_ARCHITECTURES 30)
 
 add_library(CUDACircularDeviceLinking1 STATIC file1.cu)
 add_library(CUDACircularDeviceLinking2 STATIC file2.cu)
diff --git a/Tests/CudaOnly/CompileFlags/CMakeLists.txt b/Tests/CudaOnly/CompileFlags/CMakeLists.txt
new file mode 100644
index 0000000..5e8a8e4
--- /dev/null
+++ b/Tests/CudaOnly/CompileFlags/CMakeLists.txt
@@ -0,0 +1,15 @@
+cmake_minimum_required(VERSION 3.17)
+project(CompileFlags CUDA)
+
+add_executable(CudaOnlyCompileFlags main.cu)
+
+# Try passing CUDA architecture flags explicitly.
+if(CMAKE_CUDA_COMPILER_ID STREQUAL "NVIDIA")
+  target_compile_options(CudaOnlyCompileFlags PRIVATE
+    -gencode arch=compute_50,code=compute_50
+  )
+else()
+  set_property(TARGET CudaOnlyCompileFlags PROPERTY CUDA_ARCHITECTURES 50-real)
+endif()
+
+target_compile_options(CudaOnlyCompileFlags PRIVATE -DALWAYS_DEFINE)
diff --git a/Tests/CudaOnly/CompileFlags/main.cu b/Tests/CudaOnly/CompileFlags/main.cu
new file mode 100644
index 0000000..999c056
--- /dev/null
+++ b/Tests/CudaOnly/CompileFlags/main.cu
@@ -0,0 +1,13 @@
+#ifdef __CUDA_ARCH__
+#  if __CUDA_ARCH__ != 500
+#    error "Passed architecture 50, but got something else."
+#  endif
+#endif
+
+#ifndef ALWAYS_DEFINE
+#  error "ALWAYS_DEFINE not defined!"
+#endif
+
+int main()
+{
+}
diff --git a/Tests/CudaOnly/DontResolveDeviceSymbols/CMakeLists.txt b/Tests/CudaOnly/DontResolveDeviceSymbols/CMakeLists.txt
index 6e3697f..1265660 100644
--- a/Tests/CudaOnly/DontResolveDeviceSymbols/CMakeLists.txt
+++ b/Tests/CudaOnly/DontResolveDeviceSymbols/CMakeLists.txt
@@ -24,9 +24,9 @@
 # Don't resolve the device symbols in the static library
 # Don't resolve the device symbols in the executable library
 # Verify that we can't use those device symbols from anything
-string(APPEND CMAKE_CUDA_FLAGS " -gencode arch=compute_30,code=[compute_30] -gencode arch=compute_50,code=\\\"compute_50\\\"")
 set(CMAKE_CXX_STANDARD 11)
 set(CMAKE_CUDA_STANDARD 11)
+set(CMAKE_CUDA_ARCHITECTURES 30 50)
 set(CMAKE_CUDA_RESOLVE_DEVICE_SYMBOLS OFF)
 
 add_library(CUDANoDeviceResolve SHARED file1.cu)
diff --git a/Tests/CudaOnly/DontResolveDeviceSymbols/file1.cu b/Tests/CudaOnly/DontResolveDeviceSymbols/file1.cu
index 3924f67..90c70e2 100644
--- a/Tests/CudaOnly/DontResolveDeviceSymbols/file1.cu
+++ b/Tests/CudaOnly/DontResolveDeviceSymbols/file1.cu
@@ -61,7 +61,7 @@
   err = cudaGetLastError();
   std::cout << err << " " << cudaGetErrorString(err) << std::endl;
   if (err == cudaSuccess) {
-    // This kernel launch should failed as the device linking never occured
+    // This kernel launch should failed as the device linking never occurred
     std::cerr << "file1_kernel: kernel launch should have failed" << std::endl;
     return 1;
   }
diff --git a/Tests/CudaOnly/ExportPTX/CMakeLists.txt b/Tests/CudaOnly/ExportPTX/CMakeLists.txt
index ff6e77c..ee5f54d 100644
--- a/Tests/CudaOnly/ExportPTX/CMakeLists.txt
+++ b/Tests/CudaOnly/ExportPTX/CMakeLists.txt
@@ -34,16 +34,15 @@
 # need to also pass the --name option
 set(output_file ${CMAKE_CURRENT_BINARY_DIR}/embedded_objs.h)
 
-get_filename_component(cuda_compiler_bin "${CMAKE_CUDA_COMPILER}" DIRECTORY)
+find_package(CUDAToolkit REQUIRED)
 find_program(bin_to_c
   NAMES bin2c
-  PATHS ${cuda_compiler_bin}
+  PATHS ${CUDAToolkit_BIN_DIR}
   )
 if(NOT bin_to_c)
   message(FATAL_ERROR
     "bin2c not found:\n"
-    "  CMAKE_CUDA_COMPILER='${CMAKE_CUDA_COMPILER}'\n"
-    "  cuda_compiler_bin='${cuda_compiler_bin}'\n"
+    "  CUDAToolkit_BIN_DIR='${CUDAToolkit_BIN_DIR}'\n"
     )
 endif()
 
diff --git a/Tests/CudaOnly/GPUDebugFlag/CMakeLists.txt b/Tests/CudaOnly/GPUDebugFlag/CMakeLists.txt
index fbef15f..6675655 100644
--- a/Tests/CudaOnly/GPUDebugFlag/CMakeLists.txt
+++ b/Tests/CudaOnly/GPUDebugFlag/CMakeLists.txt
@@ -2,18 +2,19 @@
 cmake_minimum_required(VERSION 3.7)
 project (GPUDebugFlag CUDA)
 
-#Goal for this example:
-#verify that -G enables gpu debug flags
-string(APPEND CMAKE_CUDA_FLAGS " -gencode=arch=compute_30,code=compute_30")
-string(APPEND CMAKE_CUDA_FLAGS " -G")
 set(CMAKE_CUDA_STANDARD 11)
+set(CMAKE_CUDA_ARCHITECTURES 30)
+
+# Goal for this example:
+# Verify that enabling device debug works.
+string(APPEND CMAKE_CUDA_FLAGS " -G")
 
 add_executable(CudaOnlyGPUDebugFlag main.cu)
 
+#CUDA's __CUDACC_DEBUG__ define was added in NVCC 9.0
+#so if we are below 9.0.0 we will manually add the define so that the test
+#passes
 if(CMAKE_CUDA_COMPILER_VERSION VERSION_LESS 9.0.0)
-  #CUDA's __CUDACC_DEBUG__ define was added in 9.0
-  #so if we are below 9.0.0 we will manually add the define so that the test
-  #passes
   target_compile_definitions(CudaOnlyGPUDebugFlag PRIVATE "__CUDACC_DEBUG__")
 endif()
 
diff --git a/Tests/CudaOnly/ResolveDeviceSymbols/CMakeLists.txt b/Tests/CudaOnly/ResolveDeviceSymbols/CMakeLists.txt
index 57aa0b9..bd94ec8 100644
--- a/Tests/CudaOnly/ResolveDeviceSymbols/CMakeLists.txt
+++ b/Tests/CudaOnly/ResolveDeviceSymbols/CMakeLists.txt
@@ -21,7 +21,7 @@
 # confirming that the first static library is on the device link line
 # 3. Verify that we can't use those device symbols from anything that links
 # to the static library
-string(APPEND CMAKE_CUDA_FLAGS " -gencode arch=compute_30,code=[sm_30] -gencode arch=compute_50,code=\\\"compute_50\\\"")
+set(CMAKE_CUDA_ARCHITECTURES 30 50)
 
 add_library(CUDAResolveDeviceDepsA STATIC file1.cu)
 add_library(CUDAResolveDeviceDepsB STATIC file2.cu)
diff --git a/Tests/CudaOnly/RuntimeControls/CMakeLists.txt b/Tests/CudaOnly/RuntimeControls/CMakeLists.txt
index 8b58fec..0da5739 100644
--- a/Tests/CudaOnly/RuntimeControls/CMakeLists.txt
+++ b/Tests/CudaOnly/RuntimeControls/CMakeLists.txt
@@ -15,9 +15,8 @@
   endif()
 endif()
 
-string(APPEND CMAKE_CUDA_FLAGS " -gencode arch=compute_30,code=[compute_30]")
-
 set(CMAKE_CUDA_STANDARD 11)
+set(CMAKE_CUDA_ARCHITECTURES 30)
 set(CMAKE_CUDA_RUNTIME_LIBRARY static)
 
 if(NOT "x${CMAKE_CUDA_SIMULATE_ID}" STREQUAL "xMSVC")
diff --git a/Tests/CudaOnly/SeparateCompilation/CMakeLists.txt b/Tests/CudaOnly/SeparateCompilation/CMakeLists.txt
index c1bd64a..586be81 100644
--- a/Tests/CudaOnly/SeparateCompilation/CMakeLists.txt
+++ b/Tests/CudaOnly/SeparateCompilation/CMakeLists.txt
@@ -9,9 +9,7 @@
 #and executables.
 #We complicate the matter by also testing that multiple static libraries
 #all containing cuda separable compilation code links properly
-string(APPEND CMAKE_CUDA_FLAGS " -gencode arch=compute_30,code=\\\"compute_30,sm_30,sm_35\\\"")
-string(APPEND CMAKE_CUDA_FLAGS " --generate-code=arch=compute_50,code=[compute_50,sm_50,sm_52]")
-
+set(CMAKE_CUDA_ARCHITECTURES 30 35 50 52)
 set(CMAKE_CUDA_SEPARABLE_COMPILATION ON)
 add_library(CUDASeparateLibA STATIC file1.cu file2.cu file3.cu)
 target_compile_features(CUDASeparateLibA PRIVATE cuda_std_11)
diff --git a/Tests/CudaOnly/Standard98/CMakeLists.txt b/Tests/CudaOnly/Standard98/CMakeLists.txt
index ef9a685..3ba0360 100644
--- a/Tests/CudaOnly/Standard98/CMakeLists.txt
+++ b/Tests/CudaOnly/Standard98/CMakeLists.txt
@@ -1,7 +1,7 @@
 cmake_minimum_required(VERSION 3.7)
 project(CudaOnlyStandard98 CUDA)
 
-string(APPEND CMAKE_CUDA_FLAGS " -gencode arch=compute_30,code=compute_30")
+set(CMAKE_CUDA_ARCHITECTURES 30)
 
 # Support setting CUDA Standard to 98 which internally gets transformed to
 # CUDA03
diff --git a/Tests/CudaOnly/StaticRuntimePlusToolkit/CMakeLists.txt b/Tests/CudaOnly/StaticRuntimePlusToolkit/CMakeLists.txt
index 97ac229..708a352 100644
--- a/Tests/CudaOnly/StaticRuntimePlusToolkit/CMakeLists.txt
+++ b/Tests/CudaOnly/StaticRuntimePlusToolkit/CMakeLists.txt
@@ -27,3 +27,9 @@
 
 add_executable(CudaOnlyStaticRuntimePlusToolkit main.cu)
 target_link_libraries(CudaOnlyStaticRuntimePlusToolkit PRIVATE SharedToolkit StaticToolkit MixedToolkit)
+
+if(UNIX)
+  # Help the shared cuda runtime find libcurand and libnppif when they are not located
+  # in a default system searched location
+  set_property(TARGET CudaOnlyStaticRuntimePlusToolkit PROPERTY BUILD_RPATH ${CMAKE_CUDA_IMPLICIT_LINK_DIRECTORIES})
+endif()
diff --git a/Tests/CudaOnly/Toolkit/CMakeLists.txt b/Tests/CudaOnly/Toolkit/CMakeLists.txt
index 0d5d574..bb06ba8 100644
--- a/Tests/CudaOnly/Toolkit/CMakeLists.txt
+++ b/Tests/CudaOnly/Toolkit/CMakeLists.txt
@@ -11,8 +11,17 @@
 message(STATUS "CUDAToolkit_LIBRARY_DIR: ${CUDAToolkit_LIBRARY_DIR}")
 message(STATUS "CUDAToolkit_NVCC_EXECUTABLE ${CUDAToolkit_NVCC_EXECUTABLE}")
 
+
+set(cuda_libs cudart cuda_driver cublas cufft cufftw curand cusolver cusparse)
+if(CUDAToolkit_VERSION VERSION_GREATER_EQUAL 10.1)
+  list(APPEND cuda_libs cublasLt)
+endif()
+if(CUDAToolkit_VERSION_MAJOR VERSION_LESS 11)
+  list(APPEND cuda_libs nvgraph)
+endif()
+
 # Verify that all the CUDA:: targets and variables exist
-foreach (cuda_lib cudart cuda_driver cublas cufft cufftw curand cusolver cusparse nvgraph)
+foreach (cuda_lib IN LISTS cuda_libs)
   if(NOT CUDA_${cuda_lib}_LIBRARY)
     message(FATAL_ERROR "expected CUDAToolkit variable CUDA_${cuda_lib}_LIBRARY not found")
   endif()
@@ -21,7 +30,11 @@
   endif()
 endforeach()
 
-foreach (cuda_lib nppc nppial nppicc nppidei nppif nppig nppim nppist nppitc npps nppicom nppisu)
+set(npp_libs nppc nppial nppicc nppidei nppif nppig nppim nppist nppitc npps nppisu)
+if(CUDAToolkit_VERSION_MAJOR VERSION_LESS 11)
+  list(APPEND npp_libs nppicom)
+endif()
+foreach (cuda_lib )
   if(NOT CUDA_${cuda_lib}_LIBRARY)
     message(FATAL_ERROR "expected CUDAToolkit variable CUDA_${cuda_lib}_LIBRARY not found")
   endif()
diff --git a/Tests/CudaOnly/WithDefs/CMakeLists.txt b/Tests/CudaOnly/WithDefs/CMakeLists.txt
index ba9bf04..0ed81d8 100644
--- a/Tests/CudaOnly/WithDefs/CMakeLists.txt
+++ b/Tests/CudaOnly/WithDefs/CMakeLists.txt
@@ -3,17 +3,7 @@
 project (WithDefs CUDA)
 
 #verify that we can pass explicit cuda arch flags
-string(APPEND CMAKE_CUDA_FLAGS " -gencode arch=compute_30,code=compute_30")
-if(CMAKE_CUDA_COMPILER_VERSION VERSION_GREATER_EQUAL 9)
-  set(debug_compile_flags --generate-code arch=compute_32,code=sm_32)
-else()
-  set(debug_compile_flags --generate-code arch=compute_20,code=sm_20)
-endif()
-if(CMAKE_CUDA_SIMULATE_ID STREQUAL "MSVC")
-  list(APPEND debug_compile_flags -Xcompiler=-WX)
-else()
-  list(APPEND debug_compile_flags -Xcompiler=-Werror)
-endif()
+set(CMAKE_CUDA_ARCHITECTURES 30)
 set(release_compile_defs DEFREL)
 
 #Goal for this example:
@@ -28,8 +18,7 @@
   PRIVATE
     -DFLAG_COMPILE_LANG_$<COMPILE_LANGUAGE>
     -DFLAG_LANG_IS_CUDA=$<COMPILE_LANGUAGE:CUDA>
-    --compiler-options=-DHOST_DEFINE
-    $<$<CONFIG:DEBUG>:$<BUILD_INTERFACE:${debug_compile_flags}>>
+    $<$<CUDA_COMPILER_ID:NVIDIA>:--compiler-options=-DHOST_DEFINE> # Host-only defines are possible only on NVCC.
   )
 
 target_compile_definitions(CudaOnlyWithDefs
diff --git a/Tests/CudaOnly/WithDefs/main.notcu b/Tests/CudaOnly/WithDefs/main.notcu
index a5f4ed6..9119eba 100644
--- a/Tests/CudaOnly/WithDefs/main.notcu
+++ b/Tests/CudaOnly/WithDefs/main.notcu
@@ -7,8 +7,10 @@
 #  error "INC_CUDA not defined!"
 #endif
 
-#ifndef HOST_DEFINE
-#  error "HOST_DEFINE not defined!"
+#ifdef __NVCC__
+#  ifndef HOST_DEFINE
+#    error "HOST_DEFINE not defined!"
+#  endif
 #endif
 
 #ifndef PACKED_DEFINE
diff --git a/Tests/CxxOnly/CMakeLists.txt b/Tests/CxxOnly/CMakeLists.txt
index e62f3c7..09689cb 100644
--- a/Tests/CxxOnly/CMakeLists.txt
+++ b/Tests/CxxOnly/CMakeLists.txt
@@ -1,11 +1,12 @@
 # a simple CXX only test case
+cmake_minimum_required(VERSION 2.8.12)
 project (CxxOnly CXX)
 
 set(CMAKE_DEBUG_POSTFIX "_test_debug_postfix")
 if(WIN32)
   set(EXTRA_SRCS test.CPP)
 endif()
-add_library(testcxx1.my STATIC libcxx1.cxx ${EXTRA_SRCS})
+add_library(testcxx1.my STATIC libcxx1.cxx test.C ${EXTRA_SRCS})
 add_library(testcxx2 SHARED libcxx2.cxx)
 add_executable (CxxOnly cxxonly.cxx)
 target_link_libraries(CxxOnly testcxx1.my testcxx2)
diff --git a/Tests/CxxOnly/cxxonly.cxx b/Tests/CxxOnly/cxxonly.cxx
index 0911a07..8bd1637 100644
--- a/Tests/CxxOnly/cxxonly.cxx
+++ b/Tests/CxxOnly/cxxonly.cxx
@@ -1,5 +1,6 @@
 #include "libcxx1.h"
 #include "libcxx2.h"
+extern int testC;
 #ifdef _MSC_VER
 extern int testCPP;
 #endif
@@ -8,6 +9,7 @@
 
 int main()
 {
+  testC = 1;
 #ifdef _MSC_VER
   testCPP = 1;
 #endif
diff --git a/Tests/CxxOnly/test.C b/Tests/CxxOnly/test.C
new file mode 100644
index 0000000..e87e6c0
--- /dev/null
+++ b/Tests/CxxOnly/test.C
@@ -0,0 +1 @@
+int testC;
diff --git a/Tests/ExportImport/Export/Interface/CMakeLists.txt b/Tests/ExportImport/Export/Interface/CMakeLists.txt
index 43b7217..ba2164b 100644
--- a/Tests/ExportImport/Export/Interface/CMakeLists.txt
+++ b/Tests/ExportImport/Export/Interface/CMakeLists.txt
@@ -1,11 +1,26 @@
-
-add_library(headeronly INTERFACE)
+set(headeronly_headers headeronly/headeronly.h)
+add_library(headeronly INTERFACE ${headeronly_headers})
 set_property(TARGET headeronly PROPERTY INTERFACE_INCLUDE_DIRECTORIES
   "$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/headeronly>"
   "$<INSTALL_INTERFACE:${CMAKE_INSTALL_PREFIX}/include/headeronly>"
 )
 set_property(TARGET headeronly PROPERTY INTERFACE_COMPILE_DEFINITIONS "HEADERONLY_DEFINE")
 
+add_custom_command(OUTPUT headergen/headergen.h
+  COMMAND ${CMAKE_COMMAND} -E copy
+    ${CMAKE_CURRENT_SOURCE_DIR}/headergen.h.in
+    ${CMAKE_CURRENT_BINARY_DIR}/headergen/headergen.h
+  DEPENDS
+    ${CMAKE_CURRENT_SOURCE_DIR}/headergen.h.in
+  VERBATIM)
+
+add_library(headergen INTERFACE headergen/headergen.h)
+set_property(TARGET headergen PROPERTY INTERFACE_INCLUDE_DIRECTORIES
+  "$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}/headergen>"
+)
+set_property(TARGET headergen PROPERTY PUBLIC_HEADER
+  ${CMAKE_CURRENT_BINARY_DIR}/headergen/headergen.h)
+
 add_library(pch_iface INTERFACE)
 target_precompile_headers(pch_iface INTERFACE
   "$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/pch/pch.h>"
@@ -54,6 +69,11 @@
                 pch_iface cmakeonly
   EXPORT expInterface
 )
+install(TARGETS headergen
+  EXPORT expInterface
+  PUBLIC_HEADER DESTINATION include/headergen
+  INCLUDES DESTINATION include/headergen
+)
 install(TARGETS sharedlib
   EXPORT expInterface
   RUNTIME DESTINATION bin
@@ -63,7 +83,7 @@
   BUNDLE DESTINATION Applications
 )
 install(FILES
-  headeronly/headeronly.h
+  ${headeronly_headers}
   DESTINATION include/headeronly
 )
 install(FILES
diff --git a/Tests/ExportImport/Export/Interface/headergen.h.in b/Tests/ExportImport/Export/Interface/headergen.h.in
new file mode 100644
index 0000000..bda2b81
--- /dev/null
+++ b/Tests/ExportImport/Export/Interface/headergen.h.in
@@ -0,0 +1 @@
+#define HEADERGEN_H
diff --git a/Tests/ExportImport/Import/Interface/CMakeLists.txt b/Tests/ExportImport/Import/Interface/CMakeLists.txt
index ef666b1..202c23e 100644
--- a/Tests/ExportImport/Import/Interface/CMakeLists.txt
+++ b/Tests/ExportImport/Import/Interface/CMakeLists.txt
@@ -12,6 +12,9 @@
 add_executable(headeronlytest_bld headeronlytest.cpp)
 target_link_libraries(headeronlytest_bld bld::headeronly)
 
+add_executable(headergentest_bld headergentest.cpp)
+target_link_libraries(headergentest_bld bld::headergen)
+
 set_property(TARGET bld::sharediface APPEND PROPERTY INTERFACE_LINK_LIBRARIES define_iface)
 
 add_executable(interfacetest_bld interfacetest.cpp)
@@ -93,6 +96,9 @@
 add_executable(headeronlytest_exp headeronlytest.cpp)
 target_link_libraries(headeronlytest_exp exp::headeronly)
 
+add_executable(headergentest_exp headergentest.cpp)
+target_link_libraries(headergentest_exp exp::headergen)
+
 set_property(TARGET exp::sharediface APPEND PROPERTY INTERFACE_LINK_LIBRARIES define_iface)
 
 add_executable(interfacetest_exp interfacetest.cpp)
diff --git a/Tests/ExportImport/Import/Interface/headergentest.cpp b/Tests/ExportImport/Import/Interface/headergentest.cpp
new file mode 100644
index 0000000..88ff7f1
--- /dev/null
+++ b/Tests/ExportImport/Import/Interface/headergentest.cpp
@@ -0,0 +1,11 @@
+
+#include "headergen.h"
+
+#ifndef HEADERGEN_H
+#  error Expected HEADERGEN_H
+#endif
+
+int main()
+{
+  return 0;
+}
diff --git a/Tests/ExternalProjectUpdate/CMakeLists.txt b/Tests/ExternalProjectUpdate/CMakeLists.txt
index dbf26c8..9dddae2 100644
--- a/Tests/ExternalProjectUpdate/CMakeLists.txt
+++ b/Tests/ExternalProjectUpdate/CMakeLists.txt
@@ -78,6 +78,8 @@
   ExternalProject_Add(${proj}
     GIT_REPOSITORY "${local_git_repo}"
     GIT_TAG ${TEST_GIT_TAG}
+    GIT_CONFIG "user.email=testauthor@cmake.org"
+               "user.name=testauthor"
     CMAKE_GENERATOR "${CMAKE_GENERATOR}"
     CMAKE_ARGS -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR>
     INSTALL_COMMAND ""
diff --git a/Tests/ExternalProjectUpdate/ExternalProjectUpdateTest.cmake b/Tests/ExternalProjectUpdate/ExternalProjectUpdateTest.cmake
index 8ea4452..ddc513f 100644
--- a/Tests/ExternalProjectUpdate/ExternalProjectUpdateTest.cmake
+++ b/Tests/ExternalProjectUpdate/ExternalProjectUpdateTest.cmake
@@ -2,7 +2,7 @@
 # resulting checked out version is resulting_sha and rebuild.
 # This check's the correct behavior of the ExternalProject UPDATE_COMMAND.
 # Also verify that a fetch only occurs when fetch_expected is 1.
-macro(check_a_tag desired_tag resulting_sha fetch_expected)
+macro(check_a_tag desired_tag resulting_sha fetch_expected update_strategy)
   message( STATUS "Checking ExternalProjectUpdate to tag: ${desired_tag}" )
 
   # Remove the FETCH_HEAD file, so we can check if it gets replaced with a 'git
@@ -10,11 +10,16 @@
   set( FETCH_HEAD_file ${ExternalProjectUpdate_BINARY_DIR}/CMakeExternals/Source/TutorialStep1-GIT/.git/FETCH_HEAD )
   file( REMOVE ${FETCH_HEAD_file} )
 
+  # Give ourselves a marker in the output. It is difficult to tell where we
+  # are up to without this
+  message(STATUS "===> check_a_tag ${desired_tag} ${resulting_sha} ${fetch_expected} ${update_strategy}")
+
   # Configure
   execute_process(COMMAND ${CMAKE_COMMAND}
     -G ${CMAKE_GENERATOR} -T "${CMAKE_GENERATOR_TOOLSET}"
     -A "${CMAKE_GENERATOR_PLATFORM}"
     -DTEST_GIT_TAG:STRING=${desired_tag}
+    -DCMAKE_EP_GIT_REMOTE_UPDATE_STRATEGY:STRING=${update_strategy}
     ${ExternalProjectUpdate_SOURCE_DIR}
     WORKING_DIRECTORY ${ExternalProjectUpdate_BINARY_DIR}
     RESULT_VARIABLE error_code
@@ -176,16 +181,55 @@
   endif()
 endif()
 
+# When re-running tests locally, this ensures we always start afresh
+file(REMOVE_RECURSE ${ExternalProjectUpdate_BINARY_DIR}/CMakeExternals)
+
 if(do_git_tests)
-  check_a_tag(origin/master 5842b503ba4113976d9bb28d57b5aee1ad2736b7 1)
-  check_a_tag(tag1          d1970730310fe8bc07e73f15dc570071f9f9654a 1)
+  check_a_tag(origin/master 5842b503ba4113976d9bb28d57b5aee1ad2736b7 1 REBASE)
+  check_a_tag(tag1          d1970730310fe8bc07e73f15dc570071f9f9654a 1 REBASE)
   # With the Git UPDATE_COMMAND performance patch, this will not required a
   # 'git fetch'
-  check_a_tag(tag1          d1970730310fe8bc07e73f15dc570071f9f9654a 0)
-  check_a_tag(tag2          5842b503ba4113976d9bb28d57b5aee1ad2736b7 1)
-  check_a_tag(d19707303     d1970730310fe8bc07e73f15dc570071f9f9654a 1)
-  check_a_tag(d19707303     d1970730310fe8bc07e73f15dc570071f9f9654a 0)
-  check_a_tag(origin/master 5842b503ba4113976d9bb28d57b5aee1ad2736b7 1)
+  check_a_tag(tag1          d1970730310fe8bc07e73f15dc570071f9f9654a 0 REBASE)
+  check_a_tag(tag2          5842b503ba4113976d9bb28d57b5aee1ad2736b7 1 REBASE)
+  check_a_tag(d19707303     d1970730310fe8bc07e73f15dc570071f9f9654a 1 REBASE)
+  check_a_tag(d19707303     d1970730310fe8bc07e73f15dc570071f9f9654a 0 REBASE)
+  check_a_tag(origin/master 5842b503ba4113976d9bb28d57b5aee1ad2736b7 1 REBASE)
   # This is a remote symbolic ref, so it will always trigger a 'git fetch'
-  check_a_tag(origin/master 5842b503ba4113976d9bb28d57b5aee1ad2736b7 1)
+  check_a_tag(origin/master 5842b503ba4113976d9bb28d57b5aee1ad2736b7 1 REBASE)
+
+  foreach(strategy IN ITEMS CHECKOUT REBASE_CHECKOUT)
+    # Move local master back, then apply a change that will cause a conflict
+    # during rebase
+    execute_process(COMMAND ${GIT_EXECUTABLE} checkout master
+      WORKING_DIRECTORY ${ExternalProjectUpdate_BINARY_DIR}/CMakeExternals/Source/TutorialStep1-GIT
+      RESULT_VARIABLE error_code
+      )
+    if(error_code)
+      message(FATAL_ERROR "Could not reset local master back to tag1.")
+    endif()
+    execute_process(COMMAND ${GIT_EXECUTABLE} reset --hard tag1
+      WORKING_DIRECTORY ${ExternalProjectUpdate_BINARY_DIR}/CMakeExternals/Source/TutorialStep1-GIT
+      RESULT_VARIABLE error_code
+      )
+    if(error_code)
+      message(FATAL_ERROR "Could not reset local master back to tag1.")
+    endif()
+
+    set(cmlFile ${ExternalProjectUpdate_BINARY_DIR}/CMakeExternals/Source/TutorialStep1-GIT/CMakeLists.txt)
+    file(READ ${cmlFile} contents)
+    string(REPLACE "find TutorialConfig.h" "find TutorialConfig.h (conflict here)"
+      conflictingContent "${contents}"
+      )
+    file(WRITE ${cmlFile} "${conflictingContent}")
+    execute_process(COMMAND ${GIT_EXECUTABLE} commit -a -m "This should cause a conflict"
+      WORKING_DIRECTORY ${ExternalProjectUpdate_BINARY_DIR}/CMakeExternals/Source/TutorialStep1-GIT
+      RESULT_VARIABLE error_code
+      )
+    if(error_code)
+      message(FATAL_ERROR "Could not commit conflicting change.")
+    endif()
+    # This should discard our commit but leave behind an annotated tag
+    check_a_tag(origin/master 5842b503ba4113976d9bb28d57b5aee1ad2736b7 1 ${strategy})
+  endforeach()
+
 endif()
diff --git a/Tests/FindBLAS/CMakeLists.txt b/Tests/FindBLAS/CMakeLists.txt
new file mode 100644
index 0000000..667195d
--- /dev/null
+++ b/Tests/FindBLAS/CMakeLists.txt
@@ -0,0 +1,10 @@
+add_test(NAME FindBLAS.Test COMMAND
+  ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
+  --build-and-test
+  "${CMake_SOURCE_DIR}/Tests/FindBLAS/Test"
+  "${CMake_BINARY_DIR}/Tests/FindBLAS/Test"
+  ${build_generator_args}
+  --build-project TestFindBLAS
+  --build-options ${build_options}
+  --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
+  )
diff --git a/Tests/FindBLAS/Test/CMakeLists.txt b/Tests/FindBLAS/Test/CMakeLists.txt
new file mode 100644
index 0000000..59418f3
--- /dev/null
+++ b/Tests/FindBLAS/Test/CMakeLists.txt
@@ -0,0 +1,13 @@
+cmake_minimum_required(VERSION 3.4)
+project(TestFindBLAS C)
+include(CTest)
+
+find_package(BLAS REQUIRED)
+
+add_executable(test_tgt main.c)
+target_link_libraries(test_tgt BLAS::BLAS)
+add_test(NAME test_tgt COMMAND test_tgt)
+
+add_executable(test_var main.c)
+target_link_libraries(test_var PRIVATE ${BLAS_LIBRARIES})
+add_test(NAME test_var COMMAND test_var)
diff --git a/Tests/FindBLAS/Test/main.c b/Tests/FindBLAS/Test/main.c
new file mode 100644
index 0000000..7360dee
--- /dev/null
+++ b/Tests/FindBLAS/Test/main.c
@@ -0,0 +1,14 @@
+#include <assert.h>
+#include <string.h>
+
+// declare what parts of the blas C-API we need
+void cblas_dswap(const int N, double* X, const int incX, double* Y,
+                 const int incY);
+
+int main()
+{
+  double x[4] = { 1, 2, 3, 4 };
+  double y[4] = { 8, 7, 7, 6 };
+  cblas_dswap(4, x, 1, y, 1);
+  return 0;
+}
diff --git a/Tests/FindDoxygen/SimpleTest/CMakeLists.txt b/Tests/FindDoxygen/SimpleTest/CMakeLists.txt
index 332cecc..deec4fd 100644
--- a/Tests/FindDoxygen/SimpleTest/CMakeLists.txt
+++ b/Tests/FindDoxygen/SimpleTest/CMakeLists.txt
@@ -22,6 +22,7 @@
     message(FATAL_ERROR "Import target Doxygen::doxygen not defined")
 endif()
 
+set(DOXYGEN_OUTPUT_DIRECTORY noArgs)
 doxygen_add_docs(docsNoArgs)
 if(NOT EXISTS "${PROJECT_BINARY_DIR}/Doxyfile.docsNoArgs")
     message(FATAL_ERROR "Missing generated file: Doxyfile.docsNoArgs")
@@ -30,6 +31,7 @@
     message(FATAL_ERROR "Target docsNoArgs not created")
 endif()
 
+set(DOXYGEN_OUTPUT_DIRECTORY withArgs)
 configure_file(spaces_in_name.cpp.in "spaces in name.cpp" COPYONLY)
 doxygen_add_docs(docsWithArgs
     "${CMAKE_CURRENT_BINARY_DIR}/spaces in name.cpp"
diff --git a/Tests/FindDoxygen/StampFile/CMakeLists.txt b/Tests/FindDoxygen/StampFile/CMakeLists.txt
index 2d06540..ed2bfbb 100644
--- a/Tests/FindDoxygen/StampFile/CMakeLists.txt
+++ b/Tests/FindDoxygen/StampFile/CMakeLists.txt
@@ -3,22 +3,41 @@
 
 find_package(Doxygen REQUIRED)
 
+set(DOXYGEN_OUTPUT_DIRECTORY noFiles)
 doxygen_add_docs(docsWithoutFilesWithStamp USE_STAMP_FILE)
 if(NOT EXISTS "${PROJECT_BINARY_DIR}/Doxyfile.docsWithoutFilesWithStamp")
-    message(FATAL_ERROR "Missing generated file: Doxyfile.docsWithoutFilesWithStamp")
+  message(FATAL_ERROR "Missing generated file: Doxyfile.docsWithoutFilesWithStamp")
 endif()
 if(NOT TARGET docsWithoutFilesWithStamp)
-    message(FATAL_ERROR "Target docsWithoutFilesWithStamp not created")
+  message(FATAL_ERROR "Target docsWithoutFilesWithStamp not created")
 endif()
 
+set(DOXYGEN_OUTPUT_DIRECTORY withFiles)
 doxygen_add_docs(docsWithFilesWithStamp main.cpp main2.cpp USE_STAMP_FILE)
 if(NOT EXISTS "${PROJECT_BINARY_DIR}/Doxyfile.docsWithFilesWithStamp")
-    message(FATAL_ERROR "Missing generated file: Doxyfile.docsWithFilesWithStamp")
+  message(FATAL_ERROR "Missing generated file: Doxyfile.docsWithFilesWithStamp")
 endif()
 if(NOT TARGET docsWithFilesWithStamp)
-    message(FATAL_ERROR "Target docsWithFilesWithStamp not created")
+  message(FATAL_ERROR "Target docsWithFilesWithStamp not created")
 endif()
 
+# Confirm that doxygen_add_docs() doesn't cause a fatal error if given a
+# source file that is generated at build time
+file(REMOVE ${CMAKE_CURRENT_BINARY_DIR}/genDox.cpp)
+add_custom_command(OUTPUT genDox.cpp
+  COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/main2.cpp genDox.cpp
+  DEPENDS main2.cpp
+)
+set(DOXYGEN_OUTPUT_DIRECTORY withGenFiles)
+doxygen_add_docs(docsWithGenFilesWithStamp
+  main.cpp
+  ${CMAKE_CURRENT_BINARY_DIR}/genDox.cpp
+  USE_STAMP_FILE
+)
 
 add_custom_target(allDocTargets)
-add_dependencies(allDocTargets docsWithoutFilesWithStamp docsWithFilesWithStamp)
+add_dependencies(allDocTargets
+  docsWithoutFilesWithStamp
+  docsWithFilesWithStamp
+  docsWithGenFilesWithStamp
+)
diff --git a/Tests/FindLAPACK/CMakeLists.txt b/Tests/FindLAPACK/CMakeLists.txt
new file mode 100644
index 0000000..2081d59
--- /dev/null
+++ b/Tests/FindLAPACK/CMakeLists.txt
@@ -0,0 +1,10 @@
+add_test(NAME FindLAPACK.Test COMMAND
+  ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
+  --build-and-test
+  "${CMake_SOURCE_DIR}/Tests/FindLAPACK/Test"
+  "${CMake_BINARY_DIR}/Tests/FindLAPACK/Test"
+  ${build_generator_args}
+  --build-project TestFindLAPACK
+  --build-options ${build_options}
+  --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
+  )
diff --git a/Tests/FindLAPACK/Test/CMakeLists.txt b/Tests/FindLAPACK/Test/CMakeLists.txt
new file mode 100644
index 0000000..8afa36a
--- /dev/null
+++ b/Tests/FindLAPACK/Test/CMakeLists.txt
@@ -0,0 +1,13 @@
+cmake_minimum_required(VERSION 3.4)
+project(TestFindLAPACK C)
+include(CTest)
+
+find_package(LAPACK REQUIRED)
+
+add_executable(test_tgt main.c)
+target_link_libraries(test_tgt LAPACK::LAPACK)
+add_test(NAME test_tgt COMMAND test_tgt)
+
+add_executable(test_var main.c)
+target_link_libraries(test_var PRIVATE ${LAPACK_LIBRARIES})
+add_test(NAME test_var COMMAND test_var)
diff --git a/Tests/FindLAPACK/Test/main.c b/Tests/FindLAPACK/Test/main.c
new file mode 100644
index 0000000..5873e7b
--- /dev/null
+++ b/Tests/FindLAPACK/Test/main.c
@@ -0,0 +1,20 @@
+#include <assert.h>
+#include <string.h>
+
+// declare what parts of the lapack C-API we need
+void dgesv_(int*, int*, double*, int*, int*, double*, int*, int*);
+
+int main()
+{
+  double A[8] = {
+    0, 1, 2, 3, 4, 5, 6, 7,
+  };
+  double B[2] = { 0, 5 };
+  int ipiv[2] = { 0, 0 };
+  int info = 0;
+
+  int dim = 2;
+  int numCols = 1;
+  dgesv_(&dim, &numCols, A, &dim, ipiv, B, &dim, &info);
+  return 0;
+}
diff --git a/Tests/FindLibXslt/CMakeLists.txt b/Tests/FindLibXslt/CMakeLists.txt
new file mode 100644
index 0000000..8a550b2
--- /dev/null
+++ b/Tests/FindLibXslt/CMakeLists.txt
@@ -0,0 +1,10 @@
+add_test(NAME FindLibXslt.Test COMMAND
+  ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
+  --build-and-test
+  "${CMake_SOURCE_DIR}/Tests/FindLibXslt/Test"
+  "${CMake_BINARY_DIR}/Tests/FindLibXslt/Test"
+  ${build_generator_args}
+  --build-project TestFindLibXslt
+  --build-options ${build_options}
+  --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
+)
diff --git a/Tests/FindLibXslt/Test/CMakeLists.txt b/Tests/FindLibXslt/Test/CMakeLists.txt
new file mode 100644
index 0000000..e932661
--- /dev/null
+++ b/Tests/FindLibXslt/Test/CMakeLists.txt
@@ -0,0 +1,45 @@
+cmake_minimum_required(VERSION 3.4)
+project(TestFindLibXslt C)
+include(CTest)
+
+find_package(Iconv)
+find_package(LibXml2 REQUIRED)
+find_package(LibXslt REQUIRED)
+
+add_definitions(-DCMAKE_EXPECTED_LibXslt_VERSION="${LIBXSLT_VERSION_STRING}")
+
+add_executable(libxslt_tgt libxslt.c)
+if(Iconv_FOUND)
+  target_link_libraries(libxslt_tgt Iconv::Iconv)
+endif()
+target_link_libraries(libxslt_tgt LibXml2::LibXml2 LibXslt::LibXslt)
+add_test(NAME libxslt_tgt COMMAND libxslt_tgt)
+
+add_executable(libxslt_var libxslt.c)
+if(Iconv_FOUND)
+  target_include_directories(libxslt_var PRIVATE ${Iconv_INCLUDE_DIRS})
+  target_link_libraries(libxslt_var PRIVATE ${Iconv_LIBRARIES})
+endif()
+target_include_directories(libxslt_var PRIVATE ${LIBXML2_INCLUDE_DIRS} ${LIBXSLT_INCLUDE_DIR})
+target_link_libraries(libxslt_var PRIVATE ${LIBXML2_LIBRARIES} ${LIBXSLT_LIBRARIES})
+add_test(NAME libxslt_var COMMAND libxslt_var)
+
+add_executable(libexslt_tgt libexslt.c)
+if(Iconv_FOUND)
+  target_link_libraries(libexslt_tgt Iconv::Iconv)
+endif()
+target_link_libraries(libexslt_tgt LibXml2::LibXml2 LibXslt::LibXslt LibXslt::LibExslt)
+add_test(NAME libexslt_tgt COMMAND libexslt_tgt)
+
+add_executable(libexslt_var libexslt.c)
+if(Iconv_FOUND)
+  target_include_directories(libexslt_var PRIVATE ${Iconv_INCLUDE_DIRS})
+  target_link_libraries(libexslt_var PRIVATE ${Iconv_LIBRARIES})
+endif()
+target_include_directories(libexslt_var PRIVATE ${LIBXML2_INCLUDE_DIRS} ${LIBXSLT_INCLUDE_DIR} ${LIBXSLT_EXSLT_INCLUDE_DIR})
+target_link_libraries(libexslt_var PRIVATE ${LIBXML2_LIBRARIES} ${LIBXSLT_LIBRARIES} ${LIBXSLT_EXSLT_LIBRARIES})
+add_test(NAME libexslt_var COMMAND libexslt_var)
+
+add_test(NAME xsltproc_tgt COMMAND LibXslt::xsltproc --version)
+
+add_test(NAME xsltproc_var COMMAND ${LIBXSLT_XSLTPROC_EXECUTABLE} --version)
diff --git a/Tests/FindLibXslt/Test/libexslt.c b/Tests/FindLibXslt/Test/libexslt.c
new file mode 100644
index 0000000..ea6eb3d
--- /dev/null
+++ b/Tests/FindLibXslt/Test/libexslt.c
@@ -0,0 +1,16 @@
+#include <libexslt/exslt.h>
+#include <libxslt/xslt.h>
+#include <libxslt/xsltInternals.h>
+
+int main()
+{
+  xsltInit();
+
+  xsltStylesheet* style = xsltNewStylesheet();
+  exsltRegisterAll();
+  xsltFreeStylesheet(style);
+
+  xsltCleanupGlobals();
+
+  return 0;
+}
diff --git a/Tests/FindLibXslt/Test/libxslt.c b/Tests/FindLibXslt/Test/libxslt.c
new file mode 100644
index 0000000..5b3d766
--- /dev/null
+++ b/Tests/FindLibXslt/Test/libxslt.c
@@ -0,0 +1,24 @@
+#include <libxslt/xslt.h>
+#include <libxslt/xsltInternals.h>
+#include <libxslt/xsltconfig.h>
+#include <stdio.h>
+#include <string.h>
+
+int main()
+{
+  xsltInit();
+
+  xsltStylesheet* style = xsltNewStylesheet();
+  xsltFreeStylesheet(style);
+
+  if (0 != strcmp(CMAKE_EXPECTED_LibXslt_VERSION, LIBXSLT_DOTTED_VERSION)) {
+    printf("CMAKE_EXPECTED_LibXslt_VERSION: '%s'\n",
+           CMAKE_EXPECTED_LibXslt_VERSION);
+    printf("LIBXSLT_DOTTED_VERSION: '%s'\n", LIBXSLT_DOTTED_VERSION);
+    return 1;
+  }
+
+  xsltCleanupGlobals();
+
+  return 0;
+}
diff --git a/Tests/FindModulesExecuteAll/CMakeLists.txt b/Tests/FindModulesExecuteAll/CMakeLists.txt
deleted file mode 100644
index 4893bb3..0000000
--- a/Tests/FindModulesExecuteAll/CMakeLists.txt
+++ /dev/null
@@ -1,30 +0,0 @@
-# This file includes all FindXXX.cmake modules, so they are all executed.
-# As it is it doesn't test a lot.
-# It makes sure that the modules don't contain basic syntax errors.
-# It also makes sure that modules don't fail with an error if something
-# wasn't found but REQUIRED was not given.
-#
-# I guess more things could be added, like checking whether variables are
-# defined after running the modules (e.g. FOO_FOUND etc.).
-cmake_minimum_required(VERSION 2.8.4) # new enough for CMP0017
-project(FindModulesExecuteAll)
-
-file(GLOB all_modules "${CMAKE_CURRENT_SOURCE_DIR}/../../Modules/Find*cmake")
-
-foreach(module ${all_modules})
-  message(STATUS "module: ${module}")
-  include("${module}")
-
-  # get the "basename" of the package, so the existence of variables like
-  # FOO_FOUND could be tested later on, Alex
-  string(REGEX REPLACE ".+Find([^\\.]+)\\.cmake" "\\1" packageName "${module}")
-  string(TOUPPER "${packageName}" packageNameUpper)
-
-# disabled for now, since too many modules break:
-#  if(NOT DEFINED ${packageNameUpper}_FOUND)
-#    message(SEND_ERROR "${packageNameUpper}_FOUND not defined !")
-#  endif()
-
-endforeach()
-
-add_executable(FindModulesExecuteAll main.c)
diff --git a/Tests/FindPackageModeMakefileTest/Makefile.in b/Tests/FindPackageModeMakefileTest/Makefile.in
index 5ef67d0..af9fa96 100644
--- a/Tests/FindPackageModeMakefileTest/Makefile.in
+++ b/Tests/FindPackageModeMakefileTest/Makefile.in
@@ -24,7 +24,7 @@
 pngtest: main.o
 	@$(CMAKE_FOO) -DMODE=LINK >$(tmp)
 	@foo="`cat $(tmp)`"; \
-	 printf '"%s" %s %s -o pngtest main.o %s\n' $(CMAKE_CXX_COMPILER) "$(CMAKE_CXX_FLAGS)" "$(LDFLAGS)" "$$foo" >$(tmp)
+	 printf '"%s" %s %s %s -o pngtest main.o %s\n' $(CMAKE_CXX_COMPILER) "$(CMAKE_CXX_FLAGS)" "$(__EXTRA_OSX_SYSROOT_FLAGS)" "$(LDFLAGS)" "$$foo" >$(tmp)
 	@cat $(tmp)
 	@sh $(tmp)
 	@rm -f $(tmp)
diff --git a/Tests/FindPython/ArtifactsInteractive/CMakeLists.txt b/Tests/FindPython/ArtifactsInteractive/CMakeLists.txt
new file mode 100644
index 0000000..524be92
--- /dev/null
+++ b/Tests/FindPython/ArtifactsInteractive/CMakeLists.txt
@@ -0,0 +1,24 @@
+cmake_minimum_required(VERSION 3.1)
+
+project(TestArtifactsInteractive LANGUAGES C)
+
+set (components Interpreter Development)
+if (CMake_TEST_FindPython_NumPy)
+  list (APPEND components NumPy)
+endif()
+
+find_package(Python3 REQUIRED COMPONENTS ${components})
+
+if (Python3_ARTIFACTS_INTERACTIVE)
+  if (NOT DEFINED CACHE{Python3_EXECUTABLE}
+      OR NOT DEFINED CACHE{Python3_LIBRARY} OR NOT DEFINED CACHE{Python3_INCLUDE_DIR}
+      OR (CMake_TEST_FindPython_NumPy AND NOT DEFINED CACHE{Python3_NumPy_INCLUDE_DIR}))
+    message (FATAL_ERROR "Python3_ARTIFACTS_INTERACTIVE=ON Failed.")
+  endif()
+else()
+  if (DEFINED CACHE{Python3_EXECUTABLE}
+      OR DEFINED CACHE{Python3_LIBRARY} OR DEFINED CACHE{Python3_INCLUDE_DIR}
+      OR (CMake_TEST_FindPython_NumPy AND DEFINED CACHE{Python3_NumPy_INCLUDE_DIR}))
+    message (FATAL_ERROR "Python3_ARTIFACTS_INTERACTIVE=OFF Failed.")
+  endif()
+endif()
diff --git a/Tests/FindPython/CMakeLists.txt b/Tests/FindPython/CMakeLists.txt
index 9b89832..fdfa36e 100644
--- a/Tests/FindPython/CMakeLists.txt
+++ b/Tests/FindPython/CMakeLists.txt
@@ -20,6 +20,17 @@
     --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
     )
 
+  add_test(NAME FindPython.Python2.Development.Module COMMAND
+    ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
+    --build-and-test
+    "${CMake_SOURCE_DIR}/Tests/FindPython/Python2Module"
+    "${CMake_BINARY_DIR}/Tests/FindPython/Python2Module"
+    ${build_generator_args}
+    --build-project TestPython2Module
+    --build-options ${build_options}
+    --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
+    )
+
   add_test(NAME FindPython.Python2Fail COMMAND
     ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
     --build-and-test
@@ -54,6 +65,17 @@
     --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
     )
 
+  add_test(NAME FindPython.Python3.Development.Module COMMAND
+    ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
+    --build-and-test
+    "${CMake_SOURCE_DIR}/Tests/FindPython/Python3Module"
+    "${CMake_BINARY_DIR}/Tests/FindPython/Python3Module"
+    ${build_generator_args}
+    --build-project TestPython3Module
+    --build-options ${build_options}
+    --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
+    )
+
   add_test(NAME FindPython.Python3Fail COMMAND
     ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
     --build-and-test
@@ -277,6 +299,35 @@
     --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
     )
 
+  add_test(NAME FindPython.ArtifactsInteractive.ON COMMAND
+    ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
+    --build-and-test
+    "${CMake_SOURCE_DIR}/Tests/FindPython/ArtifactsInteractive"
+    "${CMake_BINARY_DIR}/Tests/FindPython/ArtifactsInteractive.ON"
+    ${build_generator_args}
+    --build-project TestArtifactsScope
+    --build-options ${build_options} "-Dbuild_generator_args=${build_generator_args}"
+    "-DCMake_SOURCE_DIR=${CMake_SOURCE_DIR}"
+    "-DCMake_BINARY_DIR=${CMake_BINARY_DIR}"
+    "-DCMake_TEST_FindPython_NumPy=${CMake_TEST_FindPython_NumPy}"
+    "-DPython3_ARTIFACTS_INTERACTIVE=ON"
+    --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
+    )
+  add_test(NAME FindPython.ArtifactsInteractive.OFF COMMAND
+    ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
+    --build-and-test
+    "${CMake_SOURCE_DIR}/Tests/FindPython/ArtifactsInteractive"
+    "${CMake_BINARY_DIR}/Tests/FindPython/ArtifactsInteractive.OFF"
+    ${build_generator_args}
+    --build-project TestArtifactsScope
+    --build-options ${build_options} "-Dbuild_generator_args=${build_generator_args}"
+    "-DCMake_SOURCE_DIR=${CMake_SOURCE_DIR}"
+    "-DCMake_BINARY_DIR=${CMake_BINARY_DIR}"
+    "-DCMake_TEST_FindPython_NumPy=${CMake_TEST_FindPython_NumPy}"
+    "-DPython3_ARTIFACTS_INTERACTIVE=OFF"
+    --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
+    )
+
   add_test(NAME FindPython.CustomFailureMessage COMMAND
     ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
     --build-and-test
@@ -340,7 +391,6 @@
     ${build_generator_args}
     --build-project TestNumPyOnly
     --build-options ${build_options}
-    --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
   )
 endif()
 
@@ -357,6 +407,29 @@
     )
 endif()
 
+if (CMake_TEST_FindPython AND CMake_TEST_FindPython_IronPython)
+  add_test(NAME FindPython.Implementation.CPython COMMAND
+    ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
+    --build-and-test
+    "${CMake_SOURCE_DIR}/Tests/FindPython/Implementation"
+    "${CMake_BINARY_DIR}/Tests/FindPython/Implementation.CPython"
+    ${build_generator_args}
+    --build-project TestImplementationCPython
+    --build-options ${build_options} -DPython_REQUESTED_VERSION=2 -DPython_REQUESTED_IMPLEMENTATIONS=CPython
+    --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
+    )
+  add_test(NAME FindPython.Implementation.IronPython COMMAND
+    ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
+    --build-and-test
+    "${CMake_SOURCE_DIR}/Tests/FindPython/Implementation"
+    "${CMake_BINARY_DIR}/Tests/FindPython/Implementation.IronPython"
+    ${build_generator_args}
+    --build-project TestImplementationIronPython
+    --build-options ${build_options} -DPython_REQUESTED_VERSION=2 -DPython_REQUESTED_IMPLEMENTATION=IronPython
+    --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
+    )
+endif()
+
 if(CMake_TEST_FindPython_IronPython)
   add_test(NAME FindPython.IronPython2.LOCATION COMMAND
     ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
@@ -420,3 +493,108 @@
     --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
     )
 endif()
+
+if(CMake_TEST_FindPython_PyPy)
+  add_test(NAME FindPython.PyPy2.LOCATION COMMAND
+    ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
+    --build-and-test
+    "${CMake_SOURCE_DIR}/Tests/FindPython/PyPy2"
+    "${CMake_BINARY_DIR}/Tests/FindPython/PyPy2.LOCATION"
+    ${build_generator_args}
+    --build-project TestPyPy2
+    --build-options ${build_options} -DPython2_FIND_STRATEGY=LOCATION
+    --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
+    )
+  add_test(NAME FindPython.PyPy2.VERSION COMMAND
+    ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
+    --build-and-test
+    "${CMake_SOURCE_DIR}/Tests/FindPython/PyPy2"
+    "${CMake_BINARY_DIR}/Tests/FindPython/PyPy2.VERSION"
+    ${build_generator_args}
+    --build-project TestPyPy2
+    --build-options ${build_options} -DPython2_FIND_STRATEGY=VERSION
+    --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
+    )
+
+  add_test(NAME FindPython.PyPy3.LOCATION COMMAND
+    ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
+    --build-and-test
+    "${CMake_SOURCE_DIR}/Tests/FindPython/PyPy3"
+    "${CMake_BINARY_DIR}/Tests/FindPython/PyPy3.LOCATION"
+    ${build_generator_args}
+    --build-project TestPyPy3
+    --build-options ${build_options} -DPython3_FIND_STRATEGY=LOCATION
+    --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
+    )
+  add_test(NAME FindPython.PyPy3.VERSION COMMAND
+    ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
+    --build-and-test
+    "${CMake_SOURCE_DIR}/Tests/FindPython/PyPy3"
+    "${CMake_BINARY_DIR}/Tests/FindPython/PyPy3.VERSION"
+    ${build_generator_args}
+    --build-project TestPyPy3
+    --build-options ${build_options} -DPython3_FIND_STRATEGY=VERSION
+    --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
+    )
+
+  add_test(NAME FindPython.PyPy.LOCATION COMMAND
+    ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
+    --build-and-test
+    "${CMake_SOURCE_DIR}/Tests/FindPython/PyPy"
+    "${CMake_BINARY_DIR}/Tests/FindPython/PyPy.LOCATION"
+    ${build_generator_args}
+    --build-project TestPyPy
+    --build-options ${build_options} -DPython_FIND_STRATEGY=LOCATION
+    --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
+    )
+  add_test(NAME FindPython.PyPy.VERSION COMMAND
+    ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
+    --build-and-test
+    "${CMake_SOURCE_DIR}/Tests/FindPython/PyPy"
+    "${CMake_BINARY_DIR}/Tests/FindPython/PyPy.VERSION"
+    ${build_generator_args}
+    --build-project TestPyPy
+    --build-options ${build_options} -DPython_FIND_STRATEGY=VERSION
+    --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
+    )
+  add_test(NAME FindPython.PyPy.V2.LOCATION COMMAND
+    ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
+    --build-and-test
+    "${CMake_SOURCE_DIR}/Tests/FindPython/PyPy"
+    "${CMake_BINARY_DIR}/Tests/FindPython/PyPy.V2.LOCATION"
+    ${build_generator_args}
+    --build-project TestPyPy
+    --build-options ${build_options} -DPython_REQUESTED_VERSION=2 -DPython_FIND_STRATEGY=LOCATION
+    --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
+    )
+  add_test(NAME FindPython.PyPy.V2.VERSION COMMAND
+    ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
+    --build-and-test
+    "${CMake_SOURCE_DIR}/Tests/FindPython/PyPy"
+    "${CMake_BINARY_DIR}/Tests/FindPython/PyPy.V2.VERSION"
+    ${build_generator_args}
+    --build-project TestPyPy
+    --build-options ${build_options} -DPython_REQUESTED_VERSION=2 -DPython_FIND_STRATEGY=VERSION
+    --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
+    )
+  add_test(NAME FindPython.PyPy.V3.LOCATION COMMAND
+    ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
+    --build-and-test
+    "${CMake_SOURCE_DIR}/Tests/FindPython/PyPy"
+    "${CMake_BINARY_DIR}/Tests/FindPython/PyPy.V3.LOCATION"
+    ${build_generator_args}
+    --build-project TestPyPy
+    --build-options ${build_options} -DPython_REQUESTED_VERSION=3 -DPython_FIND_STRATEGY=LOCATION
+    --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
+    )
+  add_test(NAME FindPython.PyPy.V3.VERSION COMMAND
+    ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
+    --build-and-test
+    "${CMake_SOURCE_DIR}/Tests/FindPython/PyPy"
+    "${CMake_BINARY_DIR}/Tests/FindPython/PyPy.V3.VERSION"
+    ${build_generator_args}
+    --build-project TestPyPy
+    --build-options ${build_options} -DPython_REQUESTED_VERSION=3 -DPython_FIND_STRATEGY=VERSION
+    --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
+    )
+endif()
diff --git a/Tests/FindPython/FindPythonScript.cmake b/Tests/FindPython/FindPythonScript.cmake
index bc7e0d1..808496e 100644
--- a/Tests/FindPython/FindPythonScript.cmake
+++ b/Tests/FindPython/FindPythonScript.cmake
@@ -1,4 +1,4 @@
-
+cmake_minimum_required(VERSION 3.12)
 if (PYTHON_MUST_NOT_BE_FOUND)
   find_package(${PYTHON_PACKAGE_NAME} QUIET)
   if (${PYTHON_PACKAGE_NAME}_FOUND)
diff --git a/Tests/FindPython/Implementation/CMakeLists.txt b/Tests/FindPython/Implementation/CMakeLists.txt
new file mode 100644
index 0000000..d64fa1e
--- /dev/null
+++ b/Tests/FindPython/Implementation/CMakeLists.txt
@@ -0,0 +1,37 @@
+cmake_minimum_required(VERSION 3.1)
+
+project(TestImplementation${Python_REQUESTED_IMPLEMENTATION} C)
+
+
+set (Python${Python_REQUESTED_VERSION}_FIND_IMPLEMENTATIONS ${Python_REQUESTED_IMPLEMENTATION})
+
+find_package(Python${Python_REQUESTED_VERSION} COMPONENTS Interpreter)
+if (NOT Python${Python_REQUESTED_VERSION}_FOUND OR NOT Python${Python_REQUESTED_VERSION}_Interpreter_FOUND)
+  message (FATAL_ERROR "Fail to found Python${Python_REQUESTED_VERSION}")
+endif()
+
+if (Python_REQUESTED_IMPLEMENTATION STREQUAL "IronPython"
+    AND NOT Python${Python_REQUESTED_VERSION}_INTERPRETER_ID STREQUAL "IronPython")
+  message (FATAL_ERROR "Erroneous interpreter ID (${Python${Python_REQUESTED_VERSION}_INTERPRETER_ID})")
+endif()
+if (Python_REQUESTED_IMPLEMENTATION STREQUAL "CPython"
+    AND Python${Python_REQUESTED_VERSION}_INTERPRETER_ID STREQUAL "IronPython")
+  message (FATAL_ERROR "Erroneous interpreter ID (${Python${Python_REQUESTED_VERSION}_INTERPRETER_ID})")
+endif()
+
+
+set (Python_FIND_IMPLEMENTATIONS ${Python_REQUESTED_IMPLEMENTATION})
+
+find_package(Python ${Python_REQUESTED_VERSION} REQUIRED COMPONENTS Interpreter)
+if (NOT Python_FOUND OR NOT Python_Interpreter_FOUND)
+  message (FATAL_ERROR "Fail to found Python ${Python_REQUESTED_VERSION}")
+endif()
+
+if (Python_REQUESTED_IMPLEMENTATION STREQUAL "IronPython"
+    AND NOT Python_INTERPRETER_ID STREQUAL "IronPython")
+  message (FATAL_ERROR "Erroneous interpreter ID (${Python_INTERPRETER_ID})")
+endif()
+if (Python_REQUESTED_IMPLEMENTATION STREQUAL "CPython"
+    AND Python_INTERPRETER_ID STREQUAL "IronPython")
+  message (FATAL_ERROR "Erroneous interpreter ID (${Python_INTERPRETER_ID})")
+endif()
diff --git a/Tests/FindPython/IronPython/CMakeLists.txt b/Tests/FindPython/IronPython/CMakeLists.txt
index c96a3e0..3493c29 100644
--- a/Tests/FindPython/IronPython/CMakeLists.txt
+++ b/Tests/FindPython/IronPython/CMakeLists.txt
@@ -2,11 +2,20 @@
 
 project(TestIronPython C)
 
-find_package(Python ${Python_REQUESTED_VERSION} REQUIRED COMPONENTS Interpreter Compiler)
+set (Python_FIND_IMPLEMENTATIONS IronPython)
+
+find_package(Python ${Python_REQUESTED_VERSION} COMPONENTS Interpreter Compiler)
 if (NOT Python_FOUND)
   message (FATAL_ERROR "Fail to found Python ${Python_REQUESTED_VERSION}")
 endif()
 
+if (NOT Python_Interpreter_FOUND)
+  message (FATAL_ERROR "Fail to found Python Interpreter")
+endif()
+if (NOT Python_INTERPRETER_ID STREQUAL "IronPython")
+  message (FATAL_ERROR "Erroneous interpreter ID (${Python_INTERPRETER_ID})")
+endif()
+
 if (NOT Python_Compiler_FOUND)
   message (FATAL_ERROR "Fail to found Python Compiler")
 endif()
diff --git a/Tests/FindPython/IronPython2/CMakeLists.txt b/Tests/FindPython/IronPython2/CMakeLists.txt
index 43ec309..1db798c 100644
--- a/Tests/FindPython/IronPython2/CMakeLists.txt
+++ b/Tests/FindPython/IronPython2/CMakeLists.txt
@@ -2,11 +2,20 @@
 
 project(TestIronPython2 C)
 
-find_package(Python2 REQUIRED COMPONENTS Interpreter Compiler)
+set (Python2_FIND_IMPLEMENTATIONS "IronPython")
+
+find_package(Python2 COMPONENTS Interpreter Compiler)
 if (NOT Python2_FOUND)
   message (FATAL_ERROR "Fail to found Python 2")
 endif()
 
+if (NOT Python2_Interpreter_FOUND)
+  message (FATAL_ERROR "Fail to found Python 2 Interpreter")
+endif()
+if (NOT Python2_INTERPRETER_ID STREQUAL "IronPython")
+  message (FATAL_ERROR "Erroneous interpreter ID (${Python2_INTERPRETER_ID})")
+endif()
+
 if (NOT Python2_Compiler_FOUND)
   message (FATAL_ERROR "Fail to found Python 2 Compiler")
 endif()
diff --git a/Tests/FindPython/PyPy/CMakeLists.txt b/Tests/FindPython/PyPy/CMakeLists.txt
new file mode 100644
index 0000000..b4ade8c
--- /dev/null
+++ b/Tests/FindPython/PyPy/CMakeLists.txt
@@ -0,0 +1,37 @@
+cmake_minimum_required(VERSION 3.1)
+
+project(TestPyPy C)
+
+set (Python_FIND_IMPLEMENTATIONS PyPy)
+
+find_package(Python ${Python_REQUESTED_VERSION} COMPONENTS Interpreter Development)
+if (NOT Python_FOUND)
+  message (FATAL_ERROR "Fail to found Python PyPy ${Python_REQUESTED_VERSION}")
+endif()
+
+if (NOT Python_Interpreter_FOUND)
+  message (FATAL_ERROR "Fail to found Python PyPy Interpreter")
+endif()
+if (NOT Python_INTERPRETER_ID STREQUAL "PyPy")
+  message (FATAL_ERROR "Erroneous interpreter ID (${Python_INTERPRETER_ID})")
+endif()
+
+if (NOT Python_Development.Module_FOUND)
+  message (FATAL_ERROR "Fail to found Python PyPy ${Python_REQUESTED_VERSION} Development.Module")
+endif()
+if (NOT Python_Development.Embed_FOUND)
+  message (FATAL_ERROR "Fail to found Python PyPy ${Python_REQUESTED_VERSION} Development.Embed")
+endif()
+if (NOT Python_Development_FOUND)
+  message (FATAL_ERROR "Fail to found Python PyPy ${Python_REQUESTED_VERSION} Development")
+endif()
+
+if(NOT TARGET Python::Interpreter)
+  message(SEND_ERROR "Python::Interpreter not found")
+endif()
+if(NOT TARGET Python::Module)
+  message(SEND_ERROR "Python::Module not found")
+endif()
+if(NOT TARGET Python::Python)
+  message(SEND_ERROR "Python::Python not found")
+endif()
diff --git a/Tests/FindPython/PyPy2/CMakeLists.txt b/Tests/FindPython/PyPy2/CMakeLists.txt
new file mode 100644
index 0000000..2f0ddc9
--- /dev/null
+++ b/Tests/FindPython/PyPy2/CMakeLists.txt
@@ -0,0 +1,37 @@
+cmake_minimum_required(VERSION 3.1)
+
+project(TestPyPy2 C)
+
+set (Python2_FIND_IMPLEMENTATIONS "PyPy")
+
+find_package(Python2 COMPONENTS Interpreter Development)
+if (NOT Python2_FOUND)
+  message (FATAL_ERROR "Fail to found Python PyPy 2")
+endif()
+
+if (NOT Python2_Interpreter_FOUND)
+  message (FATAL_ERROR "Fail to found Python PyPy 2 Interpreter")
+endif()
+if (NOT Python2_INTERPRETER_ID STREQUAL "PyPy")
+  message (FATAL_ERROR "Erroneous interpreter ID (${Python2_INTERPRETER_ID})")
+endif()
+
+if (NOT Python2_Development.Module_FOUND)
+  message (FATAL_ERROR "Fail to found Python PyPy 2 Development.Module")
+endif()
+if (NOT Python2_Development.Embed_FOUND)
+  message (FATAL_ERROR "Fail to found Python PyPy 2 Development.Embed")
+endif()
+if (NOT Python2_Development_FOUND)
+  message (FATAL_ERROR "Fail to found Python PyPy 2 Development")
+endif()
+
+if(NOT TARGET Python2::Interpreter)
+  message(SEND_ERROR "Python2::Interpreter not found")
+endif()
+if(NOT TARGET Python2::Module)
+  message(SEND_ERROR "Python2::Module not found")
+endif()
+if(NOT TARGET Python2::Python)
+  message(SEND_ERROR "Python2::Python not found")
+endif()
diff --git a/Tests/FindPython/PyPy3/CMakeLists.txt b/Tests/FindPython/PyPy3/CMakeLists.txt
new file mode 100644
index 0000000..5562d57
--- /dev/null
+++ b/Tests/FindPython/PyPy3/CMakeLists.txt
@@ -0,0 +1,37 @@
+cmake_minimum_required(VERSION 3.1)
+
+project(TestPyPy3 C)
+
+set (Python3_FIND_IMPLEMENTATIONS "PyPy")
+
+find_package(Python3 COMPONENTS Interpreter Development)
+if (NOT Python3_FOUND)
+  message (FATAL_ERROR "Fail to found Python PyPy 3")
+endif()
+
+if (NOT Python3_Interpreter_FOUND)
+  message (FATAL_ERROR "Fail to found Python PyPy 3 Interpreter")
+endif()
+if (NOT Python3_INTERPRETER_ID STREQUAL "PyPy")
+  message (FATAL_ERROR "Erroneous interpreter ID (${Python3_INTERPRETER_ID})")
+endif()
+
+if (NOT Python3_Development.Module_FOUND)
+  message (FATAL_ERROR "Fail to found Python PyPy 3 Development.Module")
+endif()
+if (NOT Python3_Development.Embed_FOUND)
+  message (FATAL_ERROR "Fail to found Python PyPy 3 Development.Embed")
+endif()
+if (NOT Python3_Development_FOUND)
+  message (FATAL_ERROR "Fail to found Python PyPy 3 Development")
+endif()
+
+if(NOT TARGET Python3::Interpreter)
+  message(SEND_ERROR "Python3::Interpreter not found")
+endif()
+if(NOT TARGET Python3::Module)
+  message(SEND_ERROR "Python3::Module not found")
+endif()
+if(NOT TARGET Python3::Python)
+  message(SEND_ERROR "Python3::Python not found")
+endif()
diff --git a/Tests/FindPython/Python/CMakeLists.txt b/Tests/FindPython/Python/CMakeLists.txt
index 3ee38e3..e8828a2 100644
--- a/Tests/FindPython/Python/CMakeLists.txt
+++ b/Tests/FindPython/Python/CMakeLists.txt
@@ -8,6 +8,12 @@
 if (NOT Python_FOUND)
   message (FATAL_ERROR "Fail to found Python ${Python_REQUESTED_VERSION}")
 endif()
+if (NOT Python_Development.Module_FOUND)
+  message (FATAL_ERROR "Fail to found Python ${Python_REQUESTED_VERSION}, COMPONENT 'Development.Module'")
+endif()
+if (NOT Python_Development.Embed_FOUND)
+  message (FATAL_ERROR "Fail to found Python ${Python_REQUESTED_VERSION}, COMPOENENT 'Development.Embed'")
+endif()
 
 if(NOT TARGET Python::Interpreter)
   message(SEND_ERROR "Python::Interpreter not found")
diff --git a/Tests/FindPython/Python2/CMakeLists.txt b/Tests/FindPython/Python2/CMakeLists.txt
index cf77ca2..609d80f 100644
--- a/Tests/FindPython/Python2/CMakeLists.txt
+++ b/Tests/FindPython/Python2/CMakeLists.txt
@@ -13,6 +13,15 @@
 if (NOT Python2_FOUND)
   message (FATAL_ERROR "Fail to found Python 2")
 endif()
+if (NOT Python2_Development_FOUND)
+  message (FATAL_ERROR "Fail to found Python 2 'Development' component")
+endif()
+if (NOT Python2_Development.Module_FOUND)
+  message (FATAL_ERROR "Fail to found Python 2 'Development.Module' component")
+endif()
+if (NOT Python2_Development.Embed_FOUND)
+  message (FATAL_ERROR "Fail to found Python 2 'Development.Embed' component")
+endif()
 
 if(NOT TARGET Python2::Interpreter)
   message(SEND_ERROR "Python2::Interpreter not found")
diff --git a/Tests/FindPython/Python2Embedded/CMakeLists.txt b/Tests/FindPython/Python2Embedded/CMakeLists.txt
index 0115dea..1cf6034 100644
--- a/Tests/FindPython/Python2Embedded/CMakeLists.txt
+++ b/Tests/FindPython/Python2Embedded/CMakeLists.txt
@@ -4,10 +4,23 @@
 
 include(CTest)
 
-find_package(Python2 REQUIRED COMPONENTS Development)
+find_package(Python2 REQUIRED COMPONENTS Development.Embed)
 if (NOT Python2_FOUND)
   message (FATAL_ERROR "Fail to found Python 2")
 endif()
+if (Python2_Development_FOUND)
+  message (FATAL_ERROR "Python 2, COMPONENT 'Development' unexpectedly found")
+endif()
+if (Python2_Development.Module_FOUND)
+  message (FATAL_ERROR "Python 2, COMPONENT 'Development.Module' unexpectedly found")
+endif()
+if (NOT Python2_Development.Embed_FOUND)
+  message (FATAL_ERROR "Python 2, COMPONENT 'Development.Embed' not found")
+endif()
+
+if(TARGET Python2::Module)
+  message(SEND_ERROR "Python2::Module unexpectedly found")
+endif()
 
 if(NOT TARGET Python2::Python)
   message(SEND_ERROR "Python2::Python not found")
diff --git a/Tests/FindPython/Python2Module/CMakeLists.txt b/Tests/FindPython/Python2Module/CMakeLists.txt
new file mode 100644
index 0000000..0bc3390
--- /dev/null
+++ b/Tests/FindPython/Python2Module/CMakeLists.txt
@@ -0,0 +1,37 @@
+cmake_minimum_required(VERSION 3.1)
+
+project(TestPython2Module C)
+
+include(CTest)
+
+find_package(Python2 REQUIRED COMPONENTS Interpreter Development.Module)
+if (NOT Python2_FOUND)
+  message (FATAL_ERROR "Fail to found Python 2")
+endif()
+if (Python2_Development_FOUND)
+  message (FATAL_ERROR "Python 2, COMPONENT 'Development' unexpectedly found")
+endif()
+if (Python2_Development.Embed_FOUND)
+  message (FATAL_ERROR "Python 2, COMPONENT 'Development.Embed' unexpectedly found")
+endif()
+if (NOT Python2_Development.Module_FOUND)
+  message (FATAL_ERROR "Python 2, COMPONENT 'Development.Module' not found")
+endif()
+
+if(NOT TARGET Python2::Interpreter)
+  message(SEND_ERROR "Python2::Interpreter not found")
+endif()
+
+if(TARGET Python2::Python)
+  message(SEND_ERROR "Python2::Python unexpectedly found")
+endif()
+if(NOT TARGET Python2::Module)
+  message(SEND_ERROR "Python2::Module not found")
+endif()
+
+Python2_add_library (spam2 MODULE ../spam.c)
+target_compile_definitions (spam2 PRIVATE PYTHON2)
+
+add_test (NAME python2_spam2
+          COMMAND "${CMAKE_COMMAND}" -E env "PYTHONPATH=$<TARGET_FILE_DIR:spam2>"
+          "${Python2_EXECUTABLE}" -c "import spam2; spam2.system(\"cd\")")
diff --git a/Tests/FindPython/Python3/CMakeLists.txt b/Tests/FindPython/Python3/CMakeLists.txt
index 6691a48..d6e5fdb 100644
--- a/Tests/FindPython/Python3/CMakeLists.txt
+++ b/Tests/FindPython/Python3/CMakeLists.txt
@@ -13,16 +13,25 @@
 if (NOT Python3_FOUND)
   message (FATAL_ERROR "Fail to found Python 3")
 endif()
+if (NOT Python3_Development_FOUND)
+  message (FATAL_ERROR "Fail to found Python 3 'Development' component")
+endif()
+if (NOT Python3_Development.Module_FOUND)
+  message (FATAL_ERROR "Fail to found Python 3 'Development.Module' component")
+endif()
+if (NOT Python3_Development.Embed_FOUND)
+  message (FATAL_ERROR "Fail to found Python 3 'Development.Embed' component")
+endif()
 
 if(NOT TARGET Python3::Interpreter)
-  message(SEND_ERROR "Python2::Interpreter not found")
+  message(SEND_ERROR "Python3::Interpreter not found")
 endif()
 
 if(NOT TARGET Python3::Python)
-  message(SEND_ERROR "Python2::Python not found")
+  message(SEND_ERROR "Python3::Python not found")
 endif()
 if(NOT TARGET Python3::Module)
-  message(SEND_ERROR "Python2::Module not found")
+  message(SEND_ERROR "Python3::Module not found")
 endif()
 
 Python3_add_library (spam3 MODULE ../spam.c)
diff --git a/Tests/FindPython/Python3Embedded/CMakeLists.txt b/Tests/FindPython/Python3Embedded/CMakeLists.txt
index 4eb7ebc..184c0b4 100644
--- a/Tests/FindPython/Python3Embedded/CMakeLists.txt
+++ b/Tests/FindPython/Python3Embedded/CMakeLists.txt
@@ -4,10 +4,23 @@
 
 include(CTest)
 
-find_package(Python3 REQUIRED COMPONENTS Development)
+find_package(Python3 REQUIRED COMPONENTS Development.Embed)
 if (NOT Python3_FOUND)
   message (FATAL_ERROR "Fail to found Python 3")
 endif()
+if (Python3_Development_FOUND)
+  message (FATAL_ERROR "Python 3, COMPONENT 'Development' unexpectedly found")
+endif()
+if (Python3_Development.Module_FOUND)
+  message (FATAL_ERROR "Python 3, COMPONENT 'Development.Module' unexpectedly found")
+endif()
+if (NOT Python3_Development.Embed_FOUND)
+  message (FATAL_ERROR "Python 3, COMPONENT 'Development.Embed' not found")
+endif()
+
+if(TARGET Python3::Module)
+  message(SEND_ERROR "Python3::Module unexpectedly found")
+endif()
 
 if(NOT TARGET Python3::Python)
   message(SEND_ERROR "Python3::Python not found")
diff --git a/Tests/FindPython/Python3Module/CMakeLists.txt b/Tests/FindPython/Python3Module/CMakeLists.txt
new file mode 100644
index 0000000..676f4c8
--- /dev/null
+++ b/Tests/FindPython/Python3Module/CMakeLists.txt
@@ -0,0 +1,37 @@
+cmake_minimum_required(VERSION 3.1)
+
+project(TestPython3Module C)
+
+include(CTest)
+
+find_package(Python3 REQUIRED COMPONENTS Interpreter Development.Module)
+if (NOT Python3_FOUND)
+  message (FATAL_ERROR "Fail to found Python 3")
+endif()
+if (Python3_Development_FOUND)
+  message (FATAL_ERROR "Python 3, COMPONENT 'Development' unexpectedly found")
+endif()
+if (Python3_Development.Embed_FOUND)
+  message (FATAL_ERROR "Python 3, COMPONENT 'Development.Embed' unexpectedly found")
+endif()
+if (NOT Python3_Development.Module_FOUND)
+  message (FATAL_ERROR "Python 3, COMPONENT 'Development.Module' not found")
+endif()
+
+if(NOT TARGET Python3::Interpreter)
+  message(SEND_ERROR "Python3::Interpreter not found")
+endif()
+
+if(TARGET Python3::Python)
+  message(SEND_ERROR "Python3::Python unexpectedly found")
+endif()
+if(NOT TARGET Python3::Module)
+  message(SEND_ERROR "Python3::Module not found")
+endif()
+
+Python3_add_library (spam3 MODULE ../spam.c)
+target_compile_definitions (spam3 PRIVATE PYTHON3)
+
+add_test (NAME python3_spam3
+          COMMAND "${CMAKE_COMMAND}" -E env "PYTHONPATH=$<TARGET_FILE_DIR:spam3>"
+          "${Python3_EXECUTABLE}" -c "import spam3; spam3.system(\"cd\")")
diff --git a/Tests/FindRuby/CMakeLists.txt b/Tests/FindRuby/CMakeLists.txt
new file mode 100644
index 0000000..3f4807c
--- /dev/null
+++ b/Tests/FindRuby/CMakeLists.txt
@@ -0,0 +1,57 @@
+if(CMake_TEST_FindRuby)
+
+  # Looks for ruby >=1.9.9, which is true on any Ubuntu (that installs it) or macOS (> 10.9)
+  add_test(NAME FindRuby.Test COMMAND
+    ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
+    --build-and-test
+    "${CMake_SOURCE_DIR}/Tests/FindRuby/Test"
+    "${CMake_BINARY_DIR}/Tests/FindRuby/Test"
+    ${build_generator_args}
+    --build-project TestRuby
+    --build-options ${build_options}
+    --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
+    )
+
+  # Looks for ruby >= 50.1.0, which should logically fail
+  add_test(NAME FindRuby.Fail COMMAND
+    ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
+    --build-and-test
+    "${CMake_SOURCE_DIR}/Tests/FindRuby/Fail"
+    "${CMake_BINARY_DIR}/Tests/FindRuby/Fail"
+    ${build_generator_args}
+    --build-project TestRubyFail
+    --build-options ${build_options}
+    --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
+    )
+  set_tests_properties(FindRuby.Fail PROPERTIES
+    PASS_REGULAR_EXPRESSION "Could NOT find Ruby.*(Required is at least version \"[0-9]+\\.[0-9]+\\.[0-9]+\")")
+
+  # Looks for 1.9.9 EXACTLY, which unlike the "FindRuby" test above will fail on every machine
+  # since this version doesn't exist (ruby goes from 1.9.3 to 2.0.0)
+  add_test(NAME FindRuby.FailExact COMMAND
+    ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
+    --build-and-test
+    "${CMake_SOURCE_DIR}/Tests/FindRuby/FailExact"
+    "${CMake_BINARY_DIR}/Tests/FindRuby/FailExact"
+    ${build_generator_args}
+    --build-project TestRubyFailExact
+    --build-options ${build_options}
+    --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
+    )
+  set_tests_properties(FindRuby.FailExact PROPERTIES
+    PASS_REGULAR_EXPRESSION "Could NOT find Ruby: Found unsuitable version \".*\", but required is.*exact version \"[0-9]+\\.[0-9]+\\.[0-9]+\" \\(found .*\\)")
+
+  # RVM specific test
+  if(CMake_TEST_FindRuby_RVM)
+    add_test(NAME FindRuby.Rvm COMMAND
+      ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
+      --build-and-test
+      "${CMake_SOURCE_DIR}/Tests/FindRuby/Rvm"
+      "${CMake_BINARY_DIR}/Tests/FindRuby/Rvm"
+      ${build_generator_args}
+      --build-project TestRVM
+      --build-options ${build_options}
+      --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
+      )
+  endif()
+endif()
diff --git a/Tests/FindRuby/Fail/CMakeLists.txt b/Tests/FindRuby/Fail/CMakeLists.txt
new file mode 100644
index 0000000..9185ba5
--- /dev/null
+++ b/Tests/FindRuby/Fail/CMakeLists.txt
@@ -0,0 +1,5 @@
+cmake_minimum_required(VERSION 3.17)
+project(TestRubyFail LANGUAGES NONE)
+
+# Should always fail since there is NO ruby 50.1.0 yet.
+find_package(Ruby 50.1.0 REQUIRED)
diff --git a/Tests/FindRuby/FailExact/CMakeLists.txt b/Tests/FindRuby/FailExact/CMakeLists.txt
new file mode 100644
index 0000000..1ebc0ae
--- /dev/null
+++ b/Tests/FindRuby/FailExact/CMakeLists.txt
@@ -0,0 +1,8 @@
+cmake_minimum_required(VERSION 3.17)
+project(TestRubyFailExact LANGUAGES NONE)
+
+# Should always fail since there is NO ruby 1.9.9 (goes from 1.9.3 to 2.0.0)
+find_package(Ruby 1.9.9 EXACT REQUIRED)
+if (NOT Ruby_FOUND)
+  message (FATAL_ERROR "Failed to find Ruby 1.9.9")
+endif()
diff --git a/Tests/FindRuby/Rvm/CMakeLists.txt b/Tests/FindRuby/Rvm/CMakeLists.txt
new file mode 100644
index 0000000..545fc94
--- /dev/null
+++ b/Tests/FindRuby/Rvm/CMakeLists.txt
@@ -0,0 +1,75 @@
+cmake_minimum_required(VERSION 3.17)
+project(TestRVM LANGUAGES NONE)
+
+include(CTest)
+
+# To run this test, you need to have at least one RVM ruby installed
+# and to ensure that the env variable 'MY_RUBY_HOME' is set to a valid RVM ruby when you run the test
+# (which is the case if you have done `rvm use x.y.z`, but could be manually set too)
+
+# Properly using rvm would require sourcing a shell script, eg `source "$HOME/.rvm/scripts/rvm"`
+# Instead, I'll just rely on the env variable MY_RUBY_HOME
+set(MY_RUBY_HOME "$ENV{MY_RUBY_HOME}")
+if(NOT MY_RUBY_HOME)
+  message(FATAL_ERROR "Env variable MY_RUBY_HOME should be set to a valid RVM ruby location, or you should call `rvm use x.y.z` before")
+endif()
+execute_process (COMMAND "${MY_RUBY_HOME}/bin/ruby" -e "puts RUBY_VERSION"
+                 RESULT_VARIABLE result
+                 OUTPUT_VARIABLE RVM_RUBY_VERSION
+                 ERROR_QUIET
+                 OUTPUT_STRIP_TRAILING_WHITESPACE)
+
+if (result)
+  message (FATAL_ERROR "Unable to detect RVM ruby version from `${MY_RUBY_HOME}/bin/ruby`: ${RVM_RUBY_VERSION}")
+endif()
+
+execute_process(COMMAND "${CMAKE_COMMAND}" -E env --unset=MY_RUBY_HOME --unset=PATH
+                        "which" "ruby"
+                 RESULT_VARIABLE result
+                 OUTPUT_VARIABLE SYSTEM_RUBY
+                 ERROR_QUIET
+                 OUTPUT_STRIP_TRAILING_WHITESPACE)
+
+if (SYSTEM_RUBY MATCHES "^${MY_RUBY_HOME}/.+")
+  message(FATAL_ERROR "Unable to find system ruby, found ${SYSTEM_RUBY} which is part of MY_RUBY_HOME=${MY_RUBY_HOME}")
+endif()
+
+# Check version of the system ruby executable.
+execute_process (COMMAND "${SYSTEM_RUBY}" -e "puts RUBY_VERSION"
+                 RESULT_VARIABLE result
+                 OUTPUT_VARIABLE SYSTEM_RUBY_VERSION
+                 ERROR_QUIET
+                 OUTPUT_STRIP_TRAILING_WHITESPACE)
+
+if (result)
+  message (FATAL_ERROR "Unable to detect system ruby version from '${SYSTEM_RUBY}': ${SYSTEM_RUBY_VERSION}")
+endif()
+
+if(SYSTEM_RUBY_VERSION VERSION_EQUAL RVM_RUBY_VERSION)
+  message(FATAL_ERROR "Your RVM Ruby Version and your System ruby version are the same (${RVM_RUBY_VERSION}).")
+endif()
+
+message("Found System Ruby (${SYSTEM_RUBY_VERSION}): ${SYSTEM_RUBY}")
+message("Found  RVM   Ruby (${RVM_RUBY_VERSION}): ${MY_RUBY_HOME}/bin/ruby")
+
+add_test(NAME FindRuby.RvmDefault
+         COMMAND "${CMAKE_COMMAND}" -E env "MY_RUBY_HOME=${MY_RUBY_HOME}"
+                 "${CMAKE_COMMAND}" "-DRUBY_HOME=${MY_RUBY_HOME}"
+                 -P "${CMAKE_CURRENT_LIST_DIR}/RvmDefault.cmake")
+
+add_test(NAME FindRuby.RvmOnly
+  COMMAND "${CMAKE_COMMAND}" -E env --unset=PATH
+                                    "MY_RUBY_HOME=${MY_RUBY_HOME}"
+          "${CMAKE_COMMAND}" "-DRUBY_HOME=${MY_RUBY_HOME}"
+                 "-DRVM_RUBY_VERSION=${RVM_RUBY_VERSION}" "-DSYSTEM_RUBY_VERSION=${SYSTEM_RUBY_VERSION}"
+                 -P "${CMAKE_CURRENT_LIST_DIR}/RvmOnly.cmake")
+add_test(NAME FindRuby.UnsetRvmOnly
+         COMMAND "${CMAKE_COMMAND}" -E env --unset=MY_RUBY_HOME "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin"
+                 "${CMAKE_COMMAND}" "-DRVM_RUBY_VERSION=${RVM_RUBY_VERSION}" "-DSYSTEM_RUBY_VERSION=${SYSTEM_RUBY_VERSION}"
+                 -P "${CMAKE_CURRENT_LIST_DIR}/RvmOnly.cmake")
+
+add_test(NAME FindRuby.RvmStandard
+         COMMAND "${CMAKE_COMMAND}" -E env "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin"
+                                           "MY_RUBY_HOME=${MY_RUBY_HOME}"
+                 "${CMAKE_COMMAND}" "-DRUBY_HOME=${MY_RUBY_HOME}"
+                 -P "${CMAKE_CURRENT_LIST_DIR}/RvmStandard.cmake")
diff --git a/Tests/FindRuby/Rvm/RvmDefault.cmake b/Tests/FindRuby/Rvm/RvmDefault.cmake
new file mode 100644
index 0000000..a66b911
--- /dev/null
+++ b/Tests/FindRuby/Rvm/RvmDefault.cmake
@@ -0,0 +1,17 @@
+set(CMAKE_FIND_LIBRARY_PREFIXES "")
+set(CMAKE_FIND_LIBRARY_SUFFIXES "")
+
+find_package (Ruby 2.1.1 REQUIRED)
+if (NOT RUBY_EXECUTABLE MATCHES "^${RUBY_HOME}/.+")
+  message (FATAL_ERROR "Failed to use RVM environment: ${RUBY_EXECUTABLE}, ${RUBY_HOME}")
+endif()
+
+find_package (Ruby 2.1 REQUIRED)
+if (NOT RUBY_EXECUTABLE MATCHES "^${RUBY_HOME}/.+")
+  message (FATAL_ERROR "Failed to use RVM environment: ${RUBY_EXECUTABLE}, ${RUBY_HOME}")
+endif()
+
+find_package (Ruby REQUIRED)
+if (NOT RUBY_EXECUTABLE MATCHES "^${RUBY_HOME}/.+")
+  message (FATAL_ERROR "Failed to use RVM environment: ${RUBY_EXECUTABLE}, ${RUBY_HOME}")
+endif()
diff --git a/Tests/FindRuby/Rvm/RvmOnly.cmake b/Tests/FindRuby/Rvm/RvmOnly.cmake
new file mode 100644
index 0000000..3851a7c
--- /dev/null
+++ b/Tests/FindRuby/Rvm/RvmOnly.cmake
@@ -0,0 +1,41 @@
+set(CMAKE_FIND_LIBRARY_PREFIXES "")
+set(CMAKE_FIND_LIBRARY_SUFFIXES "")
+
+set(Ruby_FIND_VIRTUALENV ONLY)
+
+# Test: FindRuby.RvmOnly
+if (RUBY_HOME)
+  # => Trying to find exactly system ruby using ONLY virtual environment should fail
+  find_package (Ruby ${SYSTEM_RUBY_VERSION} EXACT QUIET)
+  if(Ruby_FOUND)
+    message (FATAL_ERROR "Ruby unexpectedly found.")
+  endif()
+  # And should work to find the rvm version
+  find_package (Ruby ${RVM_RUBY_VERSION} EXACT QUIET)
+  if(Ruby_FOUND)
+    message (FATAL_ERROR "Ruby unexpectedly found.")
+  endif()
+endif()
+
+
+# Test: FindRuby.UnsetRvmOnly
+if (NOT RUBY_HOME)
+
+  # If ENV{MY_RUBY_HOME} isn't defined, it should default back to "STANDARD"
+  # At which point:
+
+  # It shouldn't find the RVM ruby
+  find_package (Ruby ${RVM_RUBY_VERSION} EXACT QUIET)
+  if(Ruby_FOUND)
+    message(FATAL_ERROR "Found RVM ruby when expecting system")
+  endif()
+
+  # it should find the system ruby
+  find_package (Ruby ${SYSTEM_RUBY_VERSION} EXACT QUIET)
+  if(NOT Ruby_FOUND)
+    message (FATAL_ERROR "Ruby not found.")
+  endif()
+  if (Ruby_FOUND MATCHES "^${RUBY_HOME}/.+")
+    message(FATAL_ERROR "Failed to find system ruby")
+  endif()
+endif()
diff --git a/Tests/FindRuby/Rvm/RvmStandard.cmake b/Tests/FindRuby/Rvm/RvmStandard.cmake
new file mode 100644
index 0000000..26befdb
--- /dev/null
+++ b/Tests/FindRuby/Rvm/RvmStandard.cmake
@@ -0,0 +1,9 @@
+set(CMAKE_FIND_LIBRARY_PREFIXES "")
+set(CMAKE_FIND_LIBRARY_SUFFIXES "")
+
+set (Ruby_FIND_VIRTUALENV STANDARD)
+find_package (Ruby REQUIRED)
+
+if (RUBY_EXECUTABLE MATCHES "^${RUBY_HOME}/.+")
+  message (FATAL_ERROR "RVM ruby unexpectedly found at ${RUBY_EXECUTABLE}, matches ${RUBY_HOME}")
+endif()
diff --git a/Tests/FindRuby/Test/CMakeLists.txt b/Tests/FindRuby/Test/CMakeLists.txt
new file mode 100644
index 0000000..dcf3ec3
--- /dev/null
+++ b/Tests/FindRuby/Test/CMakeLists.txt
@@ -0,0 +1,14 @@
+cmake_minimum_required(VERSION 3.17)
+project(TestRuby LANGUAGES C)
+include(CTest)
+
+find_package(Ruby 1.9.9 REQUIRED)
+if (NOT Ruby_FOUND)
+  message (FATAL_ERROR "Failed to find Ruby >=1.9.9")
+endif()
+
+add_executable(ruby_version ruby_version.c)
+target_include_directories(ruby_version PRIVATE ${Ruby_INCLUDE_DIRS})
+target_link_libraries(ruby_version PRIVATE ${Ruby_LIBRARIES})
+
+add_test(NAME ruby_version COMMAND ruby_version)
diff --git a/Tests/FindRuby/Test/ruby_version.c b/Tests/FindRuby/Test/ruby_version.c
new file mode 100644
index 0000000..8800436
--- /dev/null
+++ b/Tests/FindRuby/Test/ruby_version.c
@@ -0,0 +1,7 @@
+#include "ruby.h"
+
+int main(void)
+{
+  ruby_show_version();
+  return 0;
+}
diff --git a/Tests/FindSDL/CMakeLists.txt b/Tests/FindSDL/CMakeLists.txt
new file mode 100644
index 0000000..e786204
--- /dev/null
+++ b/Tests/FindSDL/CMakeLists.txt
@@ -0,0 +1,10 @@
+add_test(NAME FindSDL.Test COMMAND
+  ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
+  --build-and-test
+  "${CMake_SOURCE_DIR}/Tests/FindSDL/Test"
+  "${CMake_BINARY_DIR}/Tests/FindSDL/Test"
+  ${build_generator_args}
+  --build-project TestFindSDL
+  --build-options ${build_options}
+  --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
+  )
diff --git a/Tests/FindSDL/Test/CMakeLists.txt b/Tests/FindSDL/Test/CMakeLists.txt
new file mode 100644
index 0000000..61d4f4b
--- /dev/null
+++ b/Tests/FindSDL/Test/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 3.1)
+project(TestFindSDL C)
+include(CTest)
+
+find_package(SDL)
+
+add_definitions(
+  -DCMAKE_EXPECTED_SDL_VERSION_MAJOR=${SDL_VERSION_MAJOR}
+  -DCMAKE_EXPECTED_SDL_VERSION_MINOR=${SDL_VERSION_MINOR}
+  -DCMAKE_EXPECTED_SDL_VERSION_PATCH=${SDL_VERSION_PATCH})
+
+add_executable(test_sdl_tgt main.c)
+target_link_libraries(test_sdl_tgt SDL::SDL)
+add_test(NAME test_sdl_tgt COMMAND test_sdl_tgt)
+
+add_executable(test_sdl_var main.c)
+target_include_directories(test_sdl_var PRIVATE ${SDL_INCLUDE_DIRS})
+target_link_libraries(test_sdl_var PRIVATE ${SDL_LIBRARIES})
+add_test(NAME test_sdl_var COMMAND test_sdl_var)
diff --git a/Tests/FindSDL/Test/main.c b/Tests/FindSDL/Test/main.c
new file mode 100644
index 0000000..057289c
--- /dev/null
+++ b/Tests/FindSDL/Test/main.c
@@ -0,0 +1,18 @@
+#include <SDL.h>
+
+int main()
+{
+  // Test 1 requires headers only.
+  SDL_version compiled;
+  SDL_VERSION(&compiled);
+  if (compiled.major != CMAKE_EXPECTED_SDL_VERSION_MAJOR ||
+      compiled.minor != CMAKE_EXPECTED_SDL_VERSION_MINOR ||
+      compiled.patch != CMAKE_EXPECTED_SDL_VERSION_PATCH)
+    return 1;
+
+  // Test 2 requires to link to the library.
+  if (SDL_WasInit(SDL_INIT_VIDEO | SDL_INIT_AUDIO) != 0)
+    return 2;
+
+  return 0;
+}
diff --git a/Tests/FindTIFF/Test/CMakeLists.txt b/Tests/FindTIFF/Test/CMakeLists.txt
index 85453ed..e235db3 100644
--- a/Tests/FindTIFF/Test/CMakeLists.txt
+++ b/Tests/FindTIFF/Test/CMakeLists.txt
@@ -1,14 +1,23 @@
 cmake_minimum_required(VERSION 3.1)
-project(TestFindTIFF C)
+project(TestFindTIFF)
 include(CTest)
 
-find_package(TIFF REQUIRED)
+find_package(TIFF REQUIRED COMPONENTS CXX)
 
 add_executable(test_tiff_tgt main.c)
 target_link_libraries(test_tiff_tgt TIFF::TIFF)
 add_test(NAME test_tiff_tgt COMMAND test_tiff_tgt)
 
+add_executable(test_tiffxx_tgt main.cxx)
+target_link_libraries(test_tiffxx_tgt TIFF::CXX)
+add_test(NAME test_tiffxx_tgt COMMAND test_tiffxx_tgt)
+
 add_executable(test_tiff_var main.c)
 target_include_directories(test_tiff_var PRIVATE ${TIFF_INCLUDE_DIRS})
 target_link_libraries(test_tiff_var PRIVATE ${TIFF_LIBRARIES})
 add_test(NAME test_tiff_var COMMAND test_tiff_var)
+
+add_executable(test_tiffxx_var main.cxx)
+target_include_directories(test_tiffxx_var PRIVATE ${TIFF_INCLUDE_DIRS})
+target_link_libraries(test_tiffxx_var PRIVATE ${TIFF_LIBRARIES})
+add_test(NAME test_tiffxx_var COMMAND test_tiffxx_var)
diff --git a/Tests/FindTIFF/Test/main.cxx b/Tests/FindTIFF/Test/main.cxx
new file mode 100644
index 0000000..f80a31f
--- /dev/null
+++ b/Tests/FindTIFF/Test/main.cxx
@@ -0,0 +1,16 @@
+#include <fstream>
+
+#include <assert.h>
+#include <tiffio.hxx>
+
+int main()
+{
+  /* Without any TIFF file to open, test that the call fails as
+     expected.  This tests that linking worked. */
+  TIFF* tiff = TIFFOpen("invalid.tiff", "r");
+  assert(!tiff);
+
+  std::ifstream s;
+  TIFF* tiffxx = TIFFStreamOpen("invalid.tiff", &s);
+  return 0;
+}
diff --git a/Tests/FindVulkan/Test/CMakeLists.txt b/Tests/FindVulkan/Test/CMakeLists.txt
index 0b13d53..9d36a0d 100644
--- a/Tests/FindVulkan/Test/CMakeLists.txt
+++ b/Tests/FindVulkan/Test/CMakeLists.txt
@@ -13,3 +13,12 @@
 target_include_directories(test_var PRIVATE ${Vulkan_INCLUDE_DIRS})
 target_link_libraries(test_var PRIVATE ${Vulkan_LIBRARIES})
 add_test(NAME test_var COMMAND test_var)
+
+if(Vulkan_GLSLC_EXECUTABLE)
+  add_test(NAME test_glslc
+    COMMAND ${CMAKE_COMMAND}
+    "-DVULKAN_GLSLC_EXECUTABLE=${Vulkan_GLSLC_EXECUTABLE}"
+    "-DVULKAN_GLSLC_EXECUTABLE_TARGET=$<TARGET_FILE:Vulkan::glslc>"
+    -P "${CMAKE_CURRENT_LIST_DIR}/Run-glslc.cmake"
+    )
+endif()
diff --git a/Tests/FindVulkan/Test/Run-glslc.cmake b/Tests/FindVulkan/Test/Run-glslc.cmake
new file mode 100644
index 0000000..086eb9d
--- /dev/null
+++ b/Tests/FindVulkan/Test/Run-glslc.cmake
@@ -0,0 +1,20 @@
+cmake_minimum_required(VERSION 3.12)
+
+function(run_glslc exe exe_display)
+  execute_process(COMMAND ${exe} --help
+    OUTPUT_VARIABLE output
+    OUTPUT_STRIP_TRAILING_WHITESPACE
+    RESULT_VARIABLE result
+    )
+
+  if(NOT result EQUAL 0)
+    message(SEND_ERROR "Result of ${exe_display} --help is ${result}, should be 0")
+  endif()
+
+  if(NOT output MATCHES "^glslc - Compile shaders into SPIR-V")
+    message(SEND_ERROR "Output of ${exe_display} --help is \"${output}\", should begin with \"glslc - Compile shaders into SPIR-V\"")
+  endif()
+endfunction()
+
+run_glslc("${VULKAN_GLSLC_EXECUTABLE}" "\${VULKAN_GLSLC_EXECUTABLE}")
+run_glslc("${VULKAN_GLSLC_EXECUTABLE_TARGET}" "Vulkan::glslc")
diff --git a/Tests/FindVulkan/Test/main.c b/Tests/FindVulkan/Test/main.c
index b29c9ec..1bff651 100644
--- a/Tests/FindVulkan/Test/main.c
+++ b/Tests/FindVulkan/Test/main.c
@@ -2,10 +2,10 @@
 
 int main()
 {
-  VkInstanceCreateInfo instanceCreateInfo = {};
+  VkInstanceCreateInfo instanceCreateInfo = { 0 };
   instanceCreateInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
 
-  VkApplicationInfo applicationInfo = {};
+  VkApplicationInfo applicationInfo = { 0 };
   applicationInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
   applicationInfo.apiVersion = VK_API_VERSION_1_0;
   applicationInfo.applicationVersion = VK_MAKE_VERSION(1, 0, 0);
diff --git a/Tests/FindX11/Test/CMakeLists.txt b/Tests/FindX11/Test/CMakeLists.txt
index 769271f..7325b32 100644
--- a/Tests/FindX11/Test/CMakeLists.txt
+++ b/Tests/FindX11/Test/CMakeLists.txt
@@ -29,6 +29,11 @@
 set(X11_X11_FOUND ${X11_FOUND})
 test_x11_component(x11_components X11)
 test_x11_component(x11_components Xau)
+test_x11_component(x11_components Xaw)
+test_x11_component(x11_components xcb)
+test_x11_component(x11_components X11_xcb)
+test_x11_component(x11_components xcb_icccm)
+test_x11_component(x11_components xcb_xkb)
 test_x11_component(x11_components Xcomposite)
 test_x11_component(x11_components Xdamage)
 test_x11_component(x11_components Xdmcp)
@@ -41,6 +46,8 @@
 test_x11_component(x11_components_ignore Xft)
 test_x11_component(x11_components Xi)
 test_x11_component(x11_components Xinerama)
+test_x11_component(x11_components xkbcommon)
+test_x11_component(x11_components xkbcommon_X11)
 test_x11_component(x11_components Xkb)
 test_x11_component(x11_components xkbfile)
 test_x11_component(x11_components Xmu)
@@ -61,6 +68,10 @@
 # Not included in X11_LIBRARIES.
 foreach(lib
     Xau
+    Xaw
+    xcb
+    X11_xcb
+    xcb_icccm
     Xcomposite
     Xdamage
     Xdmcp
@@ -69,6 +80,8 @@
     Xfixes
     Xi
     Xinerama
+    xkbcommon
+    xkbcommon_X11
     Xkb
     xkbfile
     Xmu
diff --git a/Tests/FindX11/Test/main.c b/Tests/FindX11/Test/main.c
index c8144e0..f8c723c 100644
--- a/Tests/FindX11/Test/main.c
+++ b/Tests/FindX11/Test/main.c
@@ -308,6 +308,24 @@
 }
 #endif
 
+#ifdef HAVE_X11_Xaw
+#  include <X11/Intrinsic.h>
+#  include <X11/Xaw/Box.h>
+
+static void test_Xaw(void)
+{
+  XrmOptionDescRec opt_table[] = { { NULL } };
+
+  Widget toplevel;
+  toplevel =
+    XtInitialize("test", "test", opt_table, XtNumber(opt_table), NULL, NULL);
+  Widget box =
+    XtCreateManagedWidget("testbox", boxWidgetClass, toplevel, NULL, 0);
+  return;
+}
+
+#endif
+
 #include <stddef.h>
 
 int main(int argc, char* argv[])
@@ -392,6 +410,9 @@
 #ifdef HAVE_X11_Xv
     test_Xv,
 #endif
+#ifdef HAVE_X11_Xaw
+    test_Xaw,
+#endif
     NULL,
   };
 
diff --git a/Tests/FortranModules/CMakeLists.txt b/Tests/FortranModules/CMakeLists.txt
index d056b43..b7a6f68 100644
--- a/Tests/FortranModules/CMakeLists.txt
+++ b/Tests/FortranModules/CMakeLists.txt
@@ -21,7 +21,7 @@
 submodule ( parent ) child
 contains
   module procedure id
-    f = x
+    id = x
   end procedure id
 end submodule child
 program main
diff --git a/Tests/FortranOnly/CMakeLists.txt b/Tests/FortranOnly/CMakeLists.txt
index d945375..637f581 100644
--- a/Tests/FortranOnly/CMakeLists.txt
+++ b/Tests/FortranOnly/CMakeLists.txt
@@ -1,4 +1,4 @@
-cmake_minimum_required (VERSION 2.8)
+cmake_minimum_required(VERSION 2.8.12)
 project(FortranOnly Fortran)
 message("CTEST_FULL_OUTPUT ")
 
@@ -51,40 +51,36 @@
   )
 add_dependencies(checksayhello sayhello)
 
-# Exclude this test on IBM XL for now because the check strangely
-# fails with 'ld: 0706-029 Use a number with the -H flag'.
-if(NOT CMAKE_Fortran_COMPILER_ID STREQUAL XL)
-  set(err_log ${CMAKE_BINARY_DIR}/CMakeFiles/CMakeError.log)
-  file(REMOVE "${err_log}")
-  include(CheckFortranSourceCompiles)
-  unset(HAVE_PRINT CACHE)
-  CHECK_Fortran_SOURCE_COMPILES([[
+set(err_log ${CMAKE_BINARY_DIR}/CMakeFiles/CMakeError.log)
+file(REMOVE "${err_log}")
+include(CheckFortranSourceCompiles)
+unset(HAVE_PRINT CACHE)
+CHECK_Fortran_SOURCE_COMPILES([[
       PROGRAM TEST_HAVE_PRINT
         PRINT *, 'Hello'
       END
 ]] HAVE_PRINT)
-  if(NOT HAVE_PRINT)
-    if(EXISTS "${err_log}")
-      file(READ "${err_log}" err)
-    endif()
-    string(REPLACE "\n" "\n  " err "  ${err}")
-    message(SEND_ERROR "CHECK_Fortran_SOURCE_COMPILES for HAVE_PRINT failed:\n"
-      "${err}")
+if(NOT HAVE_PRINT)
+  if(EXISTS "${err_log}")
+    file(READ "${err_log}" err)
   endif()
+  string(REPLACE "\n" "\n  " err "  ${err}")
+  message(SEND_ERROR "CHECK_Fortran_SOURCE_COMPILES for HAVE_PRINT failed:\n"
+    "${err}")
+endif()
 
-  unset(Fortran_BOGUS_FLAG CACHE)
-  include(CheckFortranCompilerFlag)
-  CHECK_Fortran_COMPILER_FLAG(-_this_is_not_a_flag_ Fortran_BOGUS_FLAG)
-  if (Fortran_BOGUS_FLAG)
-    message(SEND_ERROR "CHECK_Fortran_COMPILER_FLAG() succeeded, but should have failed")
-  endif()
+unset(Fortran_BOGUS_FLAG CACHE)
+include(CheckFortranCompilerFlag)
+CHECK_Fortran_COMPILER_FLAG(-_this_is_not_a_flag_ Fortran_BOGUS_FLAG)
+if (Fortran_BOGUS_FLAG)
+  message(SEND_ERROR "CHECK_Fortran_COMPILER_FLAG() succeeded, but should have failed")
+endif()
 
-  unset(Fortran_RUN_FLAG CACHE)
-  include(CheckFortranSourceRuns)
-  check_fortran_source_runs("program a; end program" Fortran_RUN_FLAG SRC_EXT F90)
-  if(NOT Fortran_RUN_FLAG)
-    message(SEND_ERROR "CHECK_Fortran_SOURCE_RUNS() failed")
-  endif()
+unset(Fortran_RUN_FLAG CACHE)
+include(CheckFortranSourceRuns)
+check_fortran_source_runs("program a; end program" Fortran_RUN_FLAG SRC_EXT F90)
+if(NOT Fortran_RUN_FLAG)
+  message(SEND_ERROR "CHECK_Fortran_SOURCE_RUNS() failed")
 endif()
 
 # Test generation of preprocessed sources.
@@ -120,3 +116,46 @@
   set_property(TARGET IntelIfDef PROPERTY Fortran_FORMAT FIXED)
   target_compile_definitions(IntelIfDef PRIVATE SOME_DEF)
 endif()
+
+# Skip these tests if compiler/version doesn't have preprocessing flags
+if((CMAKE_Fortran_COMPILER_ID STREQUAL "GNU" AND CMAKE_Fortran_COMPILER_VERSION VERSION_LESS 4.4)
+  OR (CMAKE_Fortran_COMPILER_ID STREQUAL "XL" AND CMAKE_Fortran_COMPILER_VERSION VERSION_LESS 15.1.6))
+  set(test_pp_flags 0)
+else()
+  set(test_pp_flags 1)
+endif()
+
+if(test_pp_flags)
+  # Test that we can always preprocess a target
+  add_executable(preprocess_target preprocess2.f)
+  set_property(TARGET preprocess_target PROPERTY Fortran_PREPROCESS ON)
+
+  # Test that we can preprocess a single source file
+  add_executable(preprocess_source preprocess3.f)
+  set_property(SOURCE preprocess3.f PROPERTY Fortran_PREPROCESS ON)
+endif()
+
+# Test that neither the compiler nor CMake performs unnecessary preprocessing.
+add_library(no_preprocess_target_lower STATIC no_preprocess_target_lower.f)
+target_compile_options(no_preprocess_target_lower PRIVATE -DINTEGER=nonsense)
+set_property(TARGET no_preprocess_target_lower PROPERTY Fortran_PREPROCESS OFF)
+add_library(no_preprocess_source_lower STATIC no_preprocess_source_lower.f)
+target_compile_options(no_preprocess_source_lower PRIVATE -DINTEGER=nonsense)
+set_property(SOURCE no_preprocess_source_lower.f PROPERTY Fortran_PREPROCESS OFF)
+
+# Test that we can explicitly not preprocess a target or source.
+# This will not work on certain compilers due to either missing a
+# "don't preprocess" flag, or due to choice of file extension.
+if(test_pp_flags AND NOT CMAKE_Fortran_COMPILER_ID MATCHES "(Flang|NAG|PGI|SunPro|XL)")
+  add_library(no_preprocess_target STATIC no_preprocess_target_upper.F)
+  target_compile_options(no_preprocess_target PRIVATE -DINTEGER=nonsense)
+  add_library(no_preprocess_source STATIC no_preprocess_source_upper.F)
+  target_compile_options(no_preprocess_source PRIVATE -DINTEGER=nonsense)
+  if(NOT CMAKE_Fortran_COMPILER_ID STREQUAL "Cray"
+      AND NOT "${CMAKE_Fortran_COMPILER_ID};${CMAKE_Fortran_SIMULATE_ID}" STREQUAL "Intel;MSVC")
+    target_sources(no_preprocess_target PRIVATE no_preprocess_target_fpp.fpp)
+    target_sources(no_preprocess_source PRIVATE no_preprocess_source_fpp.fpp)
+  endif()
+  set_property(TARGET no_preprocess_target PROPERTY Fortran_PREPROCESS OFF)
+  set_property(SOURCE no_preprocess_source_upper.F no_preprocess_source_fpp.fpp PROPERTY Fortran_PREPROCESS OFF)
+endif()
diff --git a/Tests/FortranOnly/no_preprocess_source_fpp.fpp b/Tests/FortranOnly/no_preprocess_source_fpp.fpp
new file mode 100644
index 0000000..8e48902
--- /dev/null
+++ b/Tests/FortranOnly/no_preprocess_source_fpp.fpp
@@ -0,0 +1,3 @@
+      SUBROUTINE NOPREPROCESS_SOURCE_FPP
+      INTEGER F
+      END
diff --git a/Tests/FortranOnly/no_preprocess_source_lower.f b/Tests/FortranOnly/no_preprocess_source_lower.f
new file mode 100644
index 0000000..3b08782
--- /dev/null
+++ b/Tests/FortranOnly/no_preprocess_source_lower.f
@@ -0,0 +1,3 @@
+      SUBROUTINE NOPREPROCESS_SOURCE_LOWER
+      INTEGER F
+      END
diff --git a/Tests/FortranOnly/no_preprocess_source_upper.F b/Tests/FortranOnly/no_preprocess_source_upper.F
new file mode 100644
index 0000000..02485c9
--- /dev/null
+++ b/Tests/FortranOnly/no_preprocess_source_upper.F
@@ -0,0 +1,3 @@
+      SUBROUTINE NOPREPROCESS_SOURCE_UPPER
+      INTEGER F
+      END
diff --git a/Tests/FortranOnly/no_preprocess_target_fpp.fpp b/Tests/FortranOnly/no_preprocess_target_fpp.fpp
new file mode 100644
index 0000000..f9e6e3b
--- /dev/null
+++ b/Tests/FortranOnly/no_preprocess_target_fpp.fpp
@@ -0,0 +1,3 @@
+      SUBROUTINE NOPREPROCESS_TARGET_FPP
+      INTEGER F
+      END
diff --git a/Tests/FortranOnly/no_preprocess_target_lower.f b/Tests/FortranOnly/no_preprocess_target_lower.f
new file mode 100644
index 0000000..ea23a70
--- /dev/null
+++ b/Tests/FortranOnly/no_preprocess_target_lower.f
@@ -0,0 +1,3 @@
+      SUBROUTINE NOPREPROCESS_TARGET_LOWER
+      INTEGER F
+      END
diff --git a/Tests/FortranOnly/no_preprocess_target_upper.F b/Tests/FortranOnly/no_preprocess_target_upper.F
new file mode 100644
index 0000000..34ee04d
--- /dev/null
+++ b/Tests/FortranOnly/no_preprocess_target_upper.F
@@ -0,0 +1,3 @@
+      SUBROUTINE NOPREPROCESS_TARGET_UPPER
+      INTEGER F
+      END
diff --git a/Tests/FortranOnly/preprocess2.f b/Tests/FortranOnly/preprocess2.f
new file mode 100644
index 0000000..6595d62
--- /dev/null
+++ b/Tests/FortranOnly/preprocess2.f
@@ -0,0 +1,4 @@
+#define int INTEGER
+       PROGRAM PREPRO
+       int f
+       END
diff --git a/Tests/FortranOnly/preprocess3.f b/Tests/FortranOnly/preprocess3.f
new file mode 100644
index 0000000..6595d62
--- /dev/null
+++ b/Tests/FortranOnly/preprocess3.f
@@ -0,0 +1,4 @@
+#define int INTEGER
+       PROGRAM PREPRO
+       int f
+       END
diff --git a/Tests/GeneratorExpression/CMakeLists.txt b/Tests/GeneratorExpression/CMakeLists.txt
index 9d51342..ebbe288 100644
--- a/Tests/GeneratorExpression/CMakeLists.txt
+++ b/Tests/GeneratorExpression/CMakeLists.txt
@@ -40,9 +40,9 @@
     -Dtest_and_0_invalidcontent=$<AND:0,invalidcontent>
     -Dtest_config_0=$<CONFIG:$<CONFIGURATION>x>
     -Dtest_config_1=$<CONFIG:$<CONFIGURATION>>
-    -Dtest_config_debug=$<CONFIG:Debug>$<CONFIG:DEBUG>$<CONFIG:DeBuG>
-    -Dtest_config_release=$<CONFIG:Release>$<CONFIG:RELEASE>$<CONFIG:ReLeAsE>
-    -Dtest_config_relwithdebinfo=$<CONFIG:RelWithDebInfo>$<CONFIG:RELWITHDEBINFO>$<CONFIG:relwithdebinfo>
+    -Dtest_config_debug=$<CONFIG:Debug,DEBUG,DeBuG>
+    -Dtest_config_release=$<CONFIG:Release>$<CONFIG:RELEASE,ReLeAsE>
+    -Dtest_config_relwithdebinfo=$<CONFIG:RelWithDebInfo,RELWITHDEBINFO>$<CONFIG:relwithdebinfo>
     -Dtest_config_minsizerel=$<CONFIG:MinSizeRel>$<CONFIG:MINSIZEREL>$<CONFIG:minsizerel>
     -Dtest_not_0=$<NOT:0>
     -Dtest_not_1=$<NOT:1>
@@ -180,9 +180,7 @@
 set_property(TARGET imported3 APPEND PROPERTY
   INTERFACE_INCLUDE_DIRECTORIES $<$<CONFIG:DEBUG>:$<TARGET_PROPERTY:imported1,INTERFACE_INCLUDE_DIRECTORIES>>)
 set_property(TARGET imported3 APPEND PROPERTY
-  INTERFACE_INCLUDE_DIRECTORIES $<$<CONFIG:RELEASE>:$<TARGET_PROPERTY:imported2,INTERFACE_INCLUDE_DIRECTORIES>>)
-set_property(TARGET imported3 APPEND PROPERTY
-  INTERFACE_INCLUDE_DIRECTORIES $<$<CONFIG:RELWITHDEBINFO>:$<TARGET_PROPERTY:imported2,INTERFACE_INCLUDE_DIRECTORIES>>)
+  INTERFACE_INCLUDE_DIRECTORIES $<$<CONFIG:RELEASE,RELWITHDEBINFO>:$<TARGET_PROPERTY:imported2,INTERFACE_INCLUDE_DIRECTORIES>>)
 set_property(TARGET imported3 APPEND PROPERTY
   INTERFACE_INCLUDE_DIRECTORIES $<$<CONFIG:MINSIZEREL>:$<TARGET_PROPERTY:imported2,INTERFACE_INCLUDE_DIRECTORIES>>)
 
diff --git a/Tests/GeneratorExpression/check-part3.cmake b/Tests/GeneratorExpression/check-part3.cmake
index 4fb7308..5571c3d 100644
--- a/Tests/GeneratorExpression/check-part3.cmake
+++ b/Tests/GeneratorExpression/check-part3.cmake
@@ -9,11 +9,11 @@
 check(test_version_equal_2 "1")
 
 if(config AND NOT config STREQUAL NoConfig)
-  if(NOT "${test_imported_includes}" MATCHES "^;*/imported[12]/include/with space;*$")
+  if(NOT "${test_imported_includes}" MATCHES "^[^;]*/imported[12]/include/with space$")
     message(SEND_ERROR "test_imported_includes is not correct: ${test_imported_includes}")
   endif()
 else()
-  if(NOT "${test_imported_includes}" MATCHES "^;;;$")
+  if(NOT "${test_imported_includes}" MATCHES "^$")
     message(SEND_ERROR "test_imported_includes is not an empty list: ${test_imported_includes}")
   endif()
 endif()
diff --git a/Tests/GhsMulti/GhsMultiSrcGroups/standard.h b/Tests/GhsMulti/GhsMultiSrcGroups/standard.h
index 2773a55..66522d5 100644
--- a/Tests/GhsMulti/GhsMultiSrcGroups/standard.h
+++ b/Tests/GhsMulti/GhsMultiSrcGroups/standard.h
@@ -1 +1 @@
-#define somthing
+#define something
diff --git a/Tests/GhsMulti/GhsMultiSrcGroups/test3.h b/Tests/GhsMulti/GhsMultiSrcGroups/test3.h
index 2773a55..66522d5 100644
--- a/Tests/GhsMulti/GhsMultiSrcGroups/test3.h
+++ b/Tests/GhsMulti/GhsMultiSrcGroups/test3.h
@@ -1 +1 @@
-#define somthing
+#define something
diff --git a/Tests/IncludeDirectories/CMakeLists.txt b/Tests/IncludeDirectories/CMakeLists.txt
index fa3309f..eb08676 100644
--- a/Tests/IncludeDirectories/CMakeLists.txt
+++ b/Tests/IncludeDirectories/CMakeLists.txt
@@ -65,6 +65,39 @@
     PROPERTIES COMPILE_FLAGS "-ITarProp")
 endif()
 
+# Test escaping of special characters in include directory paths.
+set(special_chars "~@%&{}()!'")
+if(NOT CMAKE_GENERATOR STREQUAL "Watcom WMake")
+  # Watcom seems to have no way to encode these characters.
+  string(APPEND special_chars "#=[]")
+endif()
+if(NOT (MINGW AND CMAKE_GENERATOR MATCHES "(Unix|MSYS) Makefiles"))
+  # FIXME: Dependencies work but command-line generation does not handle '$'.
+  string(APPEND special_chars "$")
+endif()
+if(NOT CMAKE_GENERATOR MATCHES "(Borland|NMake) Makefiles")
+  # NMake and Borland seem to have no way to encode a single '^'.
+  string(APPEND special_chars "^")
+endif()
+if(NOT CMAKE_GENERATOR MATCHES "Visual Studio 9 2008|Watcom WMake")
+  # The vcproj format separates values with ','.
+  string(APPEND special_chars ",")
+endif()
+if(NOT WIN32 AND NOT CYGWIN)
+  string(APPEND special_chars "*?<>")
+endif()
+set(special_dir "${CMAKE_CURRENT_BINARY_DIR}/special-${special_chars}-include")
+file(WRITE "${special_dir}/SpecialDir.h" "#define SPECIAL_DIR_H\n")
+target_include_directories(IncludeDirectories PRIVATE "${special_dir}")
+target_compile_definitions(IncludeDirectories PRIVATE INCLUDE_SPECIAL_DIR)
+
+if(MAKE_SUPPORTS_SPACES)
+  set(special_space_dir "${CMAKE_CURRENT_BINARY_DIR}/special-space ${special_chars}-include")
+  file(WRITE "${special_space_dir}/SpecialSpaceDir.h" "#define SPECIAL_SPACE_DIR_H\n")
+  target_include_directories(IncludeDirectories PRIVATE "${special_space_dir}")
+  target_compile_definitions(IncludeDirectories PRIVATE INCLUDE_SPECIAL_SPACE_DIR)
+endif()
+
 add_library(ordertest ordertest.cpp)
 target_include_directories(ordertest SYSTEM PUBLIC SystemIncludeDirectories/systemlib)
 target_include_directories(ordertest PUBLIC SystemIncludeDirectories/userlib)
diff --git a/Tests/IncludeDirectories/main.cpp b/Tests/IncludeDirectories/main.cpp
index a59d27c..6dc88e2 100644
--- a/Tests/IncludeDirectories/main.cpp
+++ b/Tests/IncludeDirectories/main.cpp
@@ -3,6 +3,20 @@
 #include "SrcProp.h"
 #include "TarProp.h"
 
+#ifdef INCLUDE_SPECIAL_DIR
+#  include "SpecialDir.h"
+#  ifndef SPECIAL_DIR_H
+#    error "SPECIAL_DIR_H not defined"
+#  endif
+#endif
+
+#ifdef INCLUDE_SPECIAL_SPACE_DIR
+#  include "SpecialSpaceDir.h"
+#  ifndef SPECIAL_SPACE_DIR_H
+#    error "SPECIAL_SPACE_DIR_H not defined"
+#  endif
+#endif
+
 int main(int argc, char** argv)
 {
   return 0;
diff --git a/Tests/InterfaceLibrary/CMakeLists.txt b/Tests/InterfaceLibrary/CMakeLists.txt
index 311ca2a..ec0a604 100644
--- a/Tests/InterfaceLibrary/CMakeLists.txt
+++ b/Tests/InterfaceLibrary/CMakeLists.txt
@@ -44,6 +44,7 @@
 target_link_libraries(InterfaceLibrary
   iface_nodepends
   headeriface
+  iface_genheader
   subiface
   intermediate
 
diff --git a/Tests/InterfaceLibrary/definetestexe.cpp b/Tests/InterfaceLibrary/definetestexe.cpp
index 9156426..6c53840 100644
--- a/Tests/InterfaceLibrary/definetestexe.cpp
+++ b/Tests/InterfaceLibrary/definetestexe.cpp
@@ -15,6 +15,12 @@
 #  error Expected IFACE_HEADER_BUILDDIR
 #endif
 
+#include "iface_genheader.h"
+
+#ifndef IFACE_GENHEADER
+#  error Expected IFACE_GENHEADER
+#endif
+
 extern int obj();
 extern int sub();
 extern int item();
diff --git a/Tests/InterfaceLibrary/headerdir/CMakeLists.txt b/Tests/InterfaceLibrary/headerdir/CMakeLists.txt
index 826a9ed..ae030d7 100644
--- a/Tests/InterfaceLibrary/headerdir/CMakeLists.txt
+++ b/Tests/InterfaceLibrary/headerdir/CMakeLists.txt
@@ -11,3 +11,12 @@
   VERBATIM
   )
 add_dependencies(headeriface headeriface_gen)
+
+add_custom_command(OUTPUT iface_genheader.h
+  COMMAND ${CMAKE_COMMAND} -E copy
+    ${CMAKE_CURRENT_SOURCE_DIR}/iface_genheader.h.in
+    ${CMAKE_CURRENT_BINARY_DIR}/iface_genheader.h
+  DEPENDS
+    ${CMAKE_CURRENT_SOURCE_DIR}/iface_genheader.h.in
+  VERBATIM)
+add_library(iface_genheader INTERFACE iface_genheader.h)
diff --git a/Tests/InterfaceLibrary/headerdir/iface_genheader.h.in b/Tests/InterfaceLibrary/headerdir/iface_genheader.h.in
new file mode 100644
index 0000000..0a21b62
--- /dev/null
+++ b/Tests/InterfaceLibrary/headerdir/iface_genheader.h.in
@@ -0,0 +1 @@
+#define IFACE_GENHEADER
diff --git a/Tests/LoadCommand/CMakeCommands/cmTestCommand.c b/Tests/LoadCommand/CMakeCommands/cmTestCommand.c
index 99f0de9..af7b092 100644
--- a/Tests/LoadCommand/CMakeCommands/cmTestCommand.c
+++ b/Tests/LoadCommand/CMakeCommands/cmTestCommand.c
@@ -91,7 +91,7 @@
 
   source_file = info->CAPI->CreateNewSourceFile(mf);
   cstr = info->CAPI->SourceFileGetSourceName(source_file);
-  sprintf(buffer, "Shold be empty (source file name): [%s]", cstr);
+  sprintf(buffer, "Should be empty (source file name): [%s]", cstr);
   info->CAPI->DisplaySatus(mf, buffer);
   cstr = info->CAPI->SourceFileGetFullPath(source_file);
   sprintf(buffer, "Should be empty (source file full path): [%s]", cstr);
diff --git a/Tests/LoadCommandOneConfig/CMakeCommands/cmTestCommand.c b/Tests/LoadCommandOneConfig/CMakeCommands/cmTestCommand.c
index 99f0de9..af7b092 100644
--- a/Tests/LoadCommandOneConfig/CMakeCommands/cmTestCommand.c
+++ b/Tests/LoadCommandOneConfig/CMakeCommands/cmTestCommand.c
@@ -91,7 +91,7 @@
 
   source_file = info->CAPI->CreateNewSourceFile(mf);
   cstr = info->CAPI->SourceFileGetSourceName(source_file);
-  sprintf(buffer, "Shold be empty (source file name): [%s]", cstr);
+  sprintf(buffer, "Should be empty (source file name): [%s]", cstr);
   info->CAPI->DisplaySatus(mf, buffer);
   cstr = info->CAPI->SourceFileGetFullPath(source_file);
   sprintf(buffer, "Should be empty (source file full path): [%s]", cstr);
diff --git a/Tests/MSManifest/CMakeLists.txt b/Tests/MSManifest/CMakeLists.txt
index 300cfa6..631c598 100644
--- a/Tests/MSManifest/CMakeLists.txt
+++ b/Tests/MSManifest/CMakeLists.txt
@@ -1,5 +1,8 @@
 cmake_minimum_required(VERSION 3.3)
 project(MSManifest C)
 
+include(CTest)
+
 set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
 add_subdirectory(Subdir)
+add_subdirectory(Subdir2)
diff --git a/Tests/MSManifest/Subdir/CMakeLists.txt b/Tests/MSManifest/Subdir/CMakeLists.txt
index 11272bb..8664572 100644
--- a/Tests/MSManifest/Subdir/CMakeLists.txt
+++ b/Tests/MSManifest/Subdir/CMakeLists.txt
@@ -2,10 +2,9 @@
 add_executable(MSManifest main.c ${CMAKE_CURRENT_BINARY_DIR}/test.manifest)
 
 if(MSVC AND NOT MSVC_VERSION LESS 1400)
-  add_custom_command(TARGET MSManifest POST_BUILD VERBATIM
-    COMMAND ${CMAKE_COMMAND} -Dexe=$<TARGET_FILE:MSManifest>
-            -P ${CMAKE_CURRENT_SOURCE_DIR}/check.cmake
-    )
+  add_test(NAME MSManifest.Single COMMAND
+    ${CMAKE_COMMAND} -Dexe=$<TARGET_FILE:MSManifest>
+    -P ${CMAKE_CURRENT_SOURCE_DIR}/check.cmake)
   add_executable(MSManifestNone main.c)
   set_property(TARGET MSManifestNone PROPERTY LINK_FLAGS "/MANIFEST:NO")
 endif()
diff --git a/Tests/MSManifest/Subdir2/CMakeLists.txt b/Tests/MSManifest/Subdir2/CMakeLists.txt
new file mode 100644
index 0000000..19d8de7
--- /dev/null
+++ b/Tests/MSManifest/Subdir2/CMakeLists.txt
@@ -0,0 +1,13 @@
+configure_file(test_manifest1.in test_manifest1.manifest)
+configure_file(test_manifest2.in test_manifest2.manifest)
+configure_file(test_manifest3.in test_manifest3.manifest)
+add_executable(MSMultipleManifest main.c
+ ${CMAKE_CURRENT_BINARY_DIR}/test_manifest1.manifest
+ ${CMAKE_CURRENT_BINARY_DIR}/test_manifest2.manifest
+ ${CMAKE_CURRENT_BINARY_DIR}/test_manifest3.manifest)
+
+if(MSVC AND NOT MSVC_VERSION LESS 1400)
+  add_test(NAME MSManifest.Multiple COMMAND
+    ${CMAKE_COMMAND} -Dexe=$<TARGET_FILE:MSMultipleManifest>
+    -P ${CMAKE_CURRENT_SOURCE_DIR}/check.cmake)
+endif()
diff --git a/Tests/MSManifest/Subdir2/check.cmake b/Tests/MSManifest/Subdir2/check.cmake
new file mode 100644
index 0000000..4a1705b
--- /dev/null
+++ b/Tests/MSManifest/Subdir2/check.cmake
@@ -0,0 +1,22 @@
+file(STRINGS "${exe}" manifest_content1 REGEX "name=\"Kitware.CMake.MSMultipleManifest\"")
+if(manifest_content1)
+  message(STATUS "Expected manifest content found:\n ${manifest_content1}")
+else()
+  message(FATAL_ERROR "Expected manifest content not found in\n ${exe}")
+endif()
+
+# Verify Second Manifest Content is inside Executable.
+file(STRINGS "${exe}" manifest_content2 REGEX "8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a")
+if(manifest_content2)
+  message(STATUS "Expected manifest content found:\n ${manifest_content2}")
+else()
+  message(FATAL_ERROR "Expected manifest content not found in\n ${exe}")
+endif()
+
+# Verify Third Manifest Content is inside Executable.
+file(STRINGS "${exe}" manifest_content3 REGEX "<dpiAware>true</dpiAware>")
+if(manifest_content3)
+  message(STATUS "Expected manifest content found:\n ${manifest_content3}")
+else()
+  message(FATAL_ERROR "Expected manifest content not found in\n ${exe}")
+endif()
diff --git a/Tests/MSManifest/Subdir2/main.c b/Tests/MSManifest/Subdir2/main.c
new file mode 100644
index 0000000..8488f4e
--- /dev/null
+++ b/Tests/MSManifest/Subdir2/main.c
@@ -0,0 +1,4 @@
+int main(void)
+{
+  return 0;
+}
diff --git a/Tests/MSManifest/Subdir2/test_manifest1.in b/Tests/MSManifest/Subdir2/test_manifest1.in
new file mode 100644
index 0000000..f36eead
--- /dev/null
+++ b/Tests/MSManifest/Subdir2/test_manifest1.in
@@ -0,0 +1,5 @@
+<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
+  <assemblyIdentity type="win32" version="1.0.0.0"
+                    name="Kitware.CMake.MSMultipleManifest"/>
+	<description>CMake Multiple Manifest Test Application</description>
+</assembly>
diff --git a/Tests/MSManifest/Subdir2/test_manifest2.in b/Tests/MSManifest/Subdir2/test_manifest2.in
new file mode 100644
index 0000000..ec96f11
--- /dev/null
+++ b/Tests/MSManifest/Subdir2/test_manifest2.in
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0" xmlns:asmv3="urn:schemas-microsoft-com:asm.v3">
+	<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
+		<application>
+			<supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}"></supportedOS>
+			<supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"></supportedOS>
+			<supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"></supportedOS>
+			<supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"></supportedOS>
+			<supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}"></supportedOS>
+		</application>
+	</compatibility>
+</assembly>
diff --git a/Tests/MSManifest/Subdir2/test_manifest3.in b/Tests/MSManifest/Subdir2/test_manifest3.in
new file mode 100644
index 0000000..0770e11
--- /dev/null
+++ b/Tests/MSManifest/Subdir2/test_manifest3.in
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0" xmlns:asmv3="urn:schemas-microsoft-com:asm.v3" >
+  <asmv3:application>
+    <asmv3:windowsSettings xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">
+      <dpiAware>true</dpiAware>
+      <dpiAwareness xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">PerMonitorV2</dpiAwareness>
+    </asmv3:windowsSettings>
+  </asmv3:application>
+</assembly>
diff --git a/Tests/Module/CheckTypeSize/CMakeLists.txt b/Tests/Module/CheckTypeSize/CMakeLists.txt
index 16989fe2..102cf0c 100644
--- a/Tests/Module/CheckTypeSize/CMakeLists.txt
+++ b/Tests/Module/CheckTypeSize/CMakeLists.txt
@@ -21,6 +21,8 @@
 
 # Check CXX types
 check_type_size(bool        SIZEOF_BOOL LANGUAGE CXX)
+check_type_size(uint8_t     SIZEOF_UINT8_T LANGUAGE CXX)
+check_type_size(std::uint8_t SIZEOF_STD_UINT8_T LANGUAGE CXX)
 
 set(CMAKE_EXTRA_INCLUDE_FILES someclass.hxx)
 check_type_size("((ns::someclass*)0)->someint" SIZEOF_NS_CLASSMEMBER_INT LANGUAGE CXX)
diff --git a/Tests/Module/CheckTypeSize/CheckTypeSize.cxx b/Tests/Module/CheckTypeSize/CheckTypeSize.cxx
index 15dc890..45cd393 100644
--- a/Tests/Module/CheckTypeSize/CheckTypeSize.cxx
+++ b/Tests/Module/CheckTypeSize/CheckTypeSize.cxx
@@ -11,6 +11,12 @@
 #ifdef HAVE_STDDEF_H
 #  include <stddef.h>
 #endif
+#ifdef HAVE_CSTDINT
+#  include <cstdint>
+#endif
+#ifdef HAVE_CSTDDEF
+#  include <cstddef>
+#endif
 
 #include <stdio.h>
 
@@ -122,6 +128,26 @@
   NODEF(SIZEOF_SSIZE_T);
 #endif
 
+/* uint8_t */
+#if defined(SIZEOF_UINT8_T)
+  CHECK(uint8_t, SIZEOF_UINT8_T);
+#  if !defined(HAVE_SIZEOF_UINT8_T)
+  NODEF(HAVE_SIZEOF_UINT8_T);
+#  endif
+#elif defined(HAVE_SIZEOF_UINT8_T)
+  NODEF(SIZEOF_UINT8_T);
+#endif
+
+/* std::uint8_t */
+#if defined(SIZEOF_STD_UINT8_T)
+  CHECK(std::uint8_t, SIZEOF_STD_UINT8_T);
+#  if !defined(HAVE_SIZEOF_STD_UINT8_T)
+  NODEF(HAVE_SIZEOF_STD_UINT8_T);
+#  endif
+#elif defined(HAVE_SIZEOF_STD_UINT8_T)
+  NODEF(SIZEOF_STD_UINT8_T);
+#endif
+
 /* ns::someclass::someint */
 #if defined(SIZEOF_NS_CLASSMEMBER_INT)
   CHECK(y.someint, SIZEOF_NS_CLASSMEMBER_INT);
diff --git a/Tests/Module/CheckTypeSize/config.hxx.in b/Tests/Module/CheckTypeSize/config.hxx.in
index 8c66ade..9a80689 100644
--- a/Tests/Module/CheckTypeSize/config.hxx.in
+++ b/Tests/Module/CheckTypeSize/config.hxx.in
@@ -1,11 +1,21 @@
 #cmakedefine HAVE_SYS_TYPES_H
 #cmakedefine HAVE_STDINT_H
 #cmakedefine HAVE_STDDEF_H
+#cmakedefine HAVE_CSTDINT
+#cmakedefine HAVE_CSTDDEF
 
 /* bool */
 #cmakedefine HAVE_SIZEOF_BOOL
 @SIZEOF_BOOL_CODE@
 
+/* uint8_t */
+#cmakedefine HAVE_SIZEOF_UINT8_T
+@SIZEOF_UINT8_T_CODE@
+
+/* std::uint8_t */
+#cmakedefine HAVE_SIZEOF_STD_UINT8_T
+@SIZEOF_STD_UINT8_T_CODE@
+
 /* struct ns::somestruct::someint */
 #cmakedefine HAVE_SIZEOF_NS_STRUCTMEMBER_INT
 @SIZEOF_NS_STRUCTMEMBER_INT_CODE@
diff --git a/Tests/ObjectLibrary/CMakeLists.txt b/Tests/ObjectLibrary/CMakeLists.txt
index 7897ab9..fca5f41 100644
--- a/Tests/ObjectLibrary/CMakeLists.txt
+++ b/Tests/ObjectLibrary/CMakeLists.txt
@@ -73,3 +73,5 @@
 target_link_libraries(UseABstaticObjs ABstatic)
 
 add_subdirectory(ExportLanguages)
+
+add_subdirectory(Transitive)
diff --git a/Tests/ObjectLibrary/Transitive/CMakeLists.txt b/Tests/ObjectLibrary/Transitive/CMakeLists.txt
new file mode 100644
index 0000000..d616cda
--- /dev/null
+++ b/Tests/ObjectLibrary/Transitive/CMakeLists.txt
@@ -0,0 +1,12 @@
+cmake_policy(SET CMP0022 NEW)
+add_library(FooStatic STATIC FooStatic.c)
+
+add_library(FooObject1 OBJECT FooObject.c)
+target_link_libraries(FooObject1 PRIVATE FooStatic)
+add_executable(Transitive1 Transitive.c)
+target_link_libraries(Transitive1 PRIVATE FooObject1)
+
+add_library(FooObject2 OBJECT FooObject.c)
+target_link_libraries(FooObject2 INTERFACE FooStatic)
+add_executable(Transitive2 Transitive.c)
+target_link_libraries(Transitive2 PRIVATE FooObject2)
diff --git a/Tests/ObjectLibrary/Transitive/FooObject.c b/Tests/ObjectLibrary/Transitive/FooObject.c
new file mode 100644
index 0000000..54c1f29
--- /dev/null
+++ b/Tests/ObjectLibrary/Transitive/FooObject.c
@@ -0,0 +1,4 @@
+int FooObject(void)
+{
+  return 0;
+}
diff --git a/Tests/ObjectLibrary/Transitive/FooStatic.c b/Tests/ObjectLibrary/Transitive/FooStatic.c
new file mode 100644
index 0000000..84649c7
--- /dev/null
+++ b/Tests/ObjectLibrary/Transitive/FooStatic.c
@@ -0,0 +1,4 @@
+int FooStatic(void)
+{
+  return 0;
+}
diff --git a/Tests/ObjectLibrary/Transitive/Transitive.c b/Tests/ObjectLibrary/Transitive/Transitive.c
new file mode 100644
index 0000000..43089b8
--- /dev/null
+++ b/Tests/ObjectLibrary/Transitive/Transitive.c
@@ -0,0 +1,7 @@
+extern int FooObject(void);
+extern int FooStatic(void);
+
+int main(void)
+{
+  return FooObject() + FooStatic();
+}
diff --git a/Tests/Preprocess/preprocess.c b/Tests/Preprocess/preprocess.c
index 958c77e..b3117da 100644
--- a/Tests/Preprocess/preprocess.c
+++ b/Tests/Preprocess/preprocess.c
@@ -15,21 +15,21 @@
     result = 0;
   }
   if (strcmp(TARGET_STRING, STRING_VALUE) != 0) {
-    fprintf(stderr, "TARGET_STRING has wrong value in C [%s]\n",
-            TARGET_STRING);
+    fprintf(stderr, "TARGET_STRING has wrong value in C [%s] vs [%s]\n",
+            TARGET_STRING, STRING_VALUE);
     result = 0;
   }
   {
     int x = 2;
     int y = 3;
     if ((FILE_EXPR) != (EXPR)) {
-      fprintf(stderr, "FILE_EXPR did not work in C [%s]\n",
-              TO_STRING(FILE_EXPR));
+      fprintf(stderr, "FILE_EXPR did not work in C [%s] vs [%s]\n",
+              TO_STRING(FILE_EXPR), TO_STRING(EXPR));
       result = 0;
     }
     if ((TARGET_EXPR) != (EXPR)) {
-      fprintf(stderr, "TARGET_EXPR did not work in C [%s]\n",
-              TO_STRING(FILE_EXPR));
+      fprintf(stderr, "TARGET_EXPR did not work in C [%s] vs [%s]\n",
+              TO_STRING(TARGET_EXPR), TO_STRING(EXPR));
       result = 0;
     }
   }
diff --git a/Tests/Preprocess/preprocess.cxx b/Tests/Preprocess/preprocess.cxx
index 34a69c6..f2fffef 100644
--- a/Tests/Preprocess/preprocess.cxx
+++ b/Tests/Preprocess/preprocess.cxx
@@ -12,25 +12,26 @@
 {
   int result = 1;
   if (strcmp(FILE_STRING, STRING_VALUE) != 0) {
-    fprintf(stderr, "FILE_STRING has wrong value in CXX [%s]\n", FILE_STRING);
+    fprintf(stderr, "FILE_STRING has wrong value in CXX [%s] vs [%s]\n",
+            FILE_STRING, STRING_VALUE);
     result = 0;
   }
   if (strcmp(TARGET_STRING, STRING_VALUE) != 0) {
-    fprintf(stderr, "TARGET_STRING has wrong value in CXX [%s]\n",
-            TARGET_STRING);
+    fprintf(stderr, "TARGET_STRING has wrong value in CXX [%s] vs [%s]\n",
+            TARGET_STRING, STRING_VALUE);
     result = 0;
   }
   {
     int x = 2;
     int y = 3;
     if ((FILE_EXPR) != (EXPR)) {
-      fprintf(stderr, "FILE_EXPR did not work in CXX [%s]\n",
-              TO_STRING(FILE_EXPR));
+      fprintf(stderr, "FILE_EXPR did not work in CXX [%s] vs [%s]\n",
+              TO_STRING(FILE_EXPR), TO_STRING(EXPR));
       result = 0;
     }
     if ((TARGET_EXPR) != (EXPR)) {
-      fprintf(stderr, "TARGET_EXPR did not work in CXX [%s]\n",
-              TO_STRING(FILE_EXPR));
+      fprintf(stderr, "TARGET_EXPR did not work in CXX [%s] vs [%s]\n",
+              TO_STRING(TARGET_EXPR), TO_STRING(EXPR));
       result = 0;
     }
   }
diff --git a/Tests/Properties/CMakeLists.txt b/Tests/Properties/CMakeLists.txt
index a263061..162a178 100644
--- a/Tests/Properties/CMakeLists.txt
+++ b/Tests/Properties/CMakeLists.txt
@@ -144,4 +144,182 @@
 set_property(CACHE SOME_ENTRY PROPERTY STRINGS "${expect_STRINGS}")
 check_cache_props()
 
+function(generate_file_for_set_property_test i target_name)
+    set(src_path "${CMAKE_CURRENT_BINARY_DIR}/src${i}.cpp")
+    file(CONFIGURE OUTPUT "${src_path}" CONTENT
+        "#ifndef def${i}\n\
+        #error Expected def${i}\n\
+        #endif\n\
+        #ifdef _WIN32\n\
+        __declspec(dllexport)\n\
+        #endif\n\
+        void dummy_symbol${i}() {}\n"
+        NEWLINE_STYLE UNIX)
+    target_sources(${target_name} PRIVATE "${src_path}")
+endfunction()
+
+add_library(maindirtest SHARED)
+
+# Generate file to be used with both DIRECTORY and TARGET_DIRECTORY options in
+# set_source_files_properties and set_property().
+generate_file_for_set_property_test(32 maindirtest)
+generate_file_for_set_property_test(33 maindirtest)
+
 add_subdirectory(SubDir2)
+
+set(src_prefix "${CMAKE_CURRENT_BINARY_DIR}/SubDir2/")
+
+# Set property + target directory
+set_property(SOURCE "${src_prefix}/src1.cpp"
+             TARGET_DIRECTORY set_prop_lib_1
+             PROPERTY COMPILE_DEFINITIONS def1)
+
+# Append property + target directory
+set_property(SOURCE "${src_prefix}/src2.cpp"
+             TARGET_DIRECTORY set_prop_lib_1
+             APPEND PROPERTY COMPILE_DEFINITIONS def2)
+
+# Set property + relative directory path
+set_property(SOURCE "${src_prefix}/src3.cpp"
+             DIRECTORY SubDir2
+             PROPERTY COMPILE_DEFINITIONS def3)
+
+# Set property + absolute directory path
+set_property(SOURCE "${src_prefix}/src4.cpp"
+             DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/SubDir2"
+             PROPERTY COMPILE_DEFINITIONS def4)
+
+# Append property + relative directory path
+set_property(SOURCE "${src_prefix}/src5.cpp"
+             DIRECTORY SubDir2
+             APPEND PROPERTY COMPILE_DEFINITIONS def5)
+
+# Append property + absolute directory path
+set_property(SOURCE "${src_prefix}/src6.cpp"
+             DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/SubDir2"
+             APPEND PROPERTY COMPILE_DEFINITIONS def6)
+
+
+# Target directory
+set_source_files_properties("${CMAKE_CURRENT_BINARY_DIR}/SubDir2/src10.cpp"
+                             TARGET_DIRECTORY set_prop_lib_1
+                             PROPERTIES COMPILE_DEFINITIONS def10)
+
+# Relative directory path
+set_source_files_properties("${CMAKE_CURRENT_BINARY_DIR}/SubDir2/src11.cpp"
+                            DIRECTORY SubDir2
+                            PROPERTIES COMPILE_DEFINITIONS def11)
+
+# Absolute directory path
+set_source_files_properties("${CMAKE_CURRENT_BINARY_DIR}/SubDir2/src12.cpp"
+                            DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/SubDir2"
+                            PROPERTIES COMPILE_DEFINITIONS def12)
+
+
+# Multiple files + absolute directory path
+set_source_files_properties("${CMAKE_CURRENT_BINARY_DIR}/SubDir2/src20.cpp"
+                            "${CMAKE_CURRENT_BINARY_DIR}/SubDir2/src21.cpp"
+                            DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/SubDir2"
+                            PROPERTIES COMPILE_DEFINITIONS "def20;def21")
+
+# Multiple files + multiple target directories
+set_source_files_properties("${CMAKE_CURRENT_BINARY_DIR}/SubDir2/src22.cpp"
+                            "${CMAKE_CURRENT_BINARY_DIR}/SubDir2/src23.cpp"
+                            TARGET_DIRECTORY set_prop_lib_2 set_prop_lib_3
+                            PROPERTIES COMPILE_DEFINITIONS "def22;def23")
+
+
+# Multiple files in multiple relative directories
+generate_file_for_set_property_test(30 maindirtest)
+set_source_files_properties("${CMAKE_CURRENT_BINARY_DIR}/src30.cpp"
+                            "${CMAKE_CURRENT_BINARY_DIR}/SubDir2/src31.cpp"
+                            DIRECTORY . SubDir2
+                            PROPERTIES COMPILE_DEFINITIONS "def30;def31")
+
+# Check that specifying files without any properties doesn't crash.
+set_source_files_properties("${CMAKE_CURRENT_BINARY_DIR}/src30.cpp"
+                            "${CMAKE_CURRENT_BINARY_DIR}/SubDir2/src31.cpp")
+
+
+# Check that specifying both DIRECTORY and TARGET_DIRECTORY works.
+set_source_files_properties("${CMAKE_CURRENT_BINARY_DIR}/src32.cpp"
+                            DIRECTORY .
+                            TARGET_DIRECTORY set_prop_lib_3
+                            PROPERTIES COMPILE_DEFINITIONS "def32")
+
+set_property(SOURCE "${CMAKE_CURRENT_BINARY_DIR}/src33.cpp"
+             DIRECTORY SubDir2
+             TARGET_DIRECTORY maindirtest
+             PROPERTY COMPILE_DEFINITIONS "def33")
+
+
+function(check_get_property_value expected)
+    if(NOT actual STREQUAL expected)
+        message(SEND_ERROR "Error: get_property returned unexpected value\n"
+                "actual: ${actual}\n"
+                "expected: ${expected}")
+    endif()
+endfunction()
+
+# Check that source file directory scopes are deduplicated.
+set_property(SOURCE "${CMAKE_CURRENT_BINARY_DIR}/src32.cpp"
+    DIRECTORY SubDir2 SubDir2 SubDir2
+    TARGET_DIRECTORY set_prop_lib_3 set_prop_lib_3 set_prop_lib_3
+    APPEND
+    PROPERTY NON_DUPLICATED_CUSTOM_PROP 1
+)
+
+get_property(actual
+             SOURCE "${CMAKE_CURRENT_BINARY_DIR}/src32.cpp"
+             DIRECTORY SubDir2
+             PROPERTY NON_DUPLICATED_CUSTOM_PROP)
+check_get_property_value("1")
+
+get_source_file_property(actual "${CMAKE_CURRENT_BINARY_DIR}/src32.cpp"
+                         TARGET_DIRECTORY set_prop_lib_3
+                         NON_DUPLICATED_CUSTOM_PROP)
+check_get_property_value("1")
+
+# Get property + target directory
+get_property(actual
+             SOURCE "${src_prefix}/src1.cpp"
+             TARGET_DIRECTORY set_prop_lib_1
+             PROPERTY COMPILE_DEFINITIONS)
+check_get_property_value("def1")
+
+# Get property + relative directory path
+get_property(actual
+             SOURCE "${src_prefix}/src3.cpp"
+             DIRECTORY SubDir2
+             PROPERTY COMPILE_DEFINITIONS)
+check_get_property_value("def3")
+
+# Get property + absolute directory path
+get_property(actual
+             SOURCE "${src_prefix}/src4.cpp"
+             DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/SubDir2"
+             PROPERTY COMPILE_DEFINITIONS)
+check_get_property_value("def4")
+
+
+# Get property + target directory
+unset(actual)
+get_source_file_property(actual
+                         "${CMAKE_CURRENT_BINARY_DIR}/SubDir2/src10.cpp"
+                         TARGET_DIRECTORY set_prop_lib_1
+                         COMPILE_DEFINITIONS)
+check_get_property_value("def10")
+
+# Get property + relative directory path
+get_source_file_property(actual
+                         "${CMAKE_CURRENT_BINARY_DIR}/SubDir2/src11.cpp"
+                         DIRECTORY SubDir2
+                         COMPILE_DEFINITIONS)
+check_get_property_value("def11")
+
+# Get property + absolute directory path
+get_source_file_property(actual
+                         "${CMAKE_CURRENT_BINARY_DIR}/SubDir2/src12.cpp"
+                         DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/SubDir2"
+                         COMPILE_DEFINITIONS)
+check_get_property_value("def12")
diff --git a/Tests/Properties/SubDir2/CMakeLists.txt b/Tests/Properties/SubDir2/CMakeLists.txt
index 377dc83..88e5531 100644
--- a/Tests/Properties/SubDir2/CMakeLists.txt
+++ b/Tests/Properties/SubDir2/CMakeLists.txt
@@ -3,3 +3,32 @@
   PROPERTIES COMPILE_DEFINITIONS SUBDIR_TEST)
 
 add_executable(subdirtest "${CMAKE_CURRENT_SOURCE_DIR}/../subdirtest.cxx")
+
+# For set_property
+add_library(set_prop_lib_1 SHARED)
+foreach(i RANGE 1 6)
+    generate_file_for_set_property_test(${i} set_prop_lib_1)
+endforeach()
+
+# For set_source_files_properties
+foreach(i RANGE 10 12)
+    generate_file_for_set_property_test(${i} set_prop_lib_1)
+endforeach()
+
+# For set_source_files_properties + multiple files + absolute directory path
+add_library(set_prop_lib_2 SHARED)
+foreach(i RANGE 20 21)
+    generate_file_for_set_property_test(${i} set_prop_lib_1)
+endforeach()
+
+# For set_source_files_properties + multiple files + multiple target directories
+add_library(set_prop_lib_3 SHARED)
+generate_file_for_set_property_test(22 set_prop_lib_2)
+generate_file_for_set_property_test(23 set_prop_lib_3)
+
+# For set_source_files_properties + multiple files in multiple directories
+generate_file_for_set_property_test(31 set_prop_lib_3)
+
+# For specifying both DIRECTORY and TARGET_DIRECTORY
+target_sources(set_prop_lib_3 PRIVATE "${CMAKE_CURRENT_BINARY_DIR}/../src32.cpp")
+target_sources(set_prop_lib_3 PRIVATE "${CMAKE_CURRENT_BINARY_DIR}/../src33.cpp")
diff --git a/Tests/QtAutogen/Complex/codeeditor.cpp b/Tests/QtAutogen/Complex/codeeditor.cpp
index bb6f405..80d6a55 100644
--- a/Tests/QtAutogen/Complex/codeeditor.cpp
+++ b/Tests/QtAutogen/Complex/codeeditor.cpp
@@ -40,7 +40,10 @@
 
 #include "codeeditor.h"
 
-#include <QtGui>
+#include <QPainter>
+#include <QSize>
+#include <QTextBlock>
+#include <QWidget>
 
 CodeEditor::CodeEditor(QWidget* parent)
   : QPlainTextEdit(parent)
diff --git a/Tests/QtAutogen/RerunMocPlugin/CMakeLists.txt b/Tests/QtAutogen/RerunMocPlugin/CMakeLists.txt
index e1951f1..a7fb2d7 100644
--- a/Tests/QtAutogen/RerunMocPlugin/CMakeLists.txt
+++ b/Tests/QtAutogen/RerunMocPlugin/CMakeLists.txt
@@ -104,7 +104,7 @@
 require_change(C)
 require_change(D)
 # There's a bug in Ninja on Windows:
-# https://gitlab.kitware.com/cmake/cmake/issues/16776
+# https://gitlab.kitware.com/cmake/cmake/-/issues/16776
 if(NOT ("${CMAKE_GENERATOR}" MATCHES "Ninja"))
   require_change(E)
 endif()
@@ -128,7 +128,7 @@
 require_change(C)
 require_change(D)
 # There's a bug in Ninja on Windows
-# https://gitlab.kitware.com/cmake/cmake/issues/16776
+# https://gitlab.kitware.com/cmake/cmake/-/issues/16776
 if(NOT ("${CMAKE_GENERATOR}" MATCHES "Ninja"))
   require_change(E)
 endif()
diff --git a/Tests/QtAutogen/Tests.cmake b/Tests/QtAutogen/Tests.cmake
index a19a9ae..dfa5ea0 100644
--- a/Tests/QtAutogen/Tests.cmake
+++ b/Tests/QtAutogen/Tests.cmake
@@ -29,6 +29,7 @@
 ADD_AUTOGEN_TEST(UicNoGui uicNoGui)
 ADD_AUTOGEN_TEST(UicOnly uicOnly)
 ADD_AUTOGEN_TEST(UicSkipSource)
+ADD_AUTOGEN_TEST(UnityMocSource)
 
 if(QT_TEST_ALLOW_QT_MACROS)
   ADD_AUTOGEN_TEST(MocCMP0071)
diff --git a/Tests/QtAutogen/UnityMocSource/CMakeLists.txt b/Tests/QtAutogen/UnityMocSource/CMakeLists.txt
new file mode 100644
index 0000000..d472319
--- /dev/null
+++ b/Tests/QtAutogen/UnityMocSource/CMakeLists.txt
@@ -0,0 +1,12 @@
+cmake_minimum_required(VERSION 3.16)
+project(UnityMocSource)
+include("../AutogenGuiTest.cmake")
+
+set(CMAKE_AUTOMOC ON)
+set(CMAKE_UNITY_BUILD ON)
+
+add_library(library library.cpp)
+target_link_libraries(library ${QT_LIBRARIES})
+
+add_executable(unityMocSource main.cpp)
+target_link_libraries(unityMocSource PRIVATE library)
diff --git a/Tests/QtAutogen/UnityMocSource/library.cpp b/Tests/QtAutogen/UnityMocSource/library.cpp
new file mode 100644
index 0000000..1e30d4b
--- /dev/null
+++ b/Tests/QtAutogen/UnityMocSource/library.cpp
@@ -0,0 +1,6 @@
+#include <QObject>
+class Test : public QObject
+{
+  Q_OBJECT
+};
+#include "library.moc"
diff --git a/Tests/FindModulesExecuteAll/main.c b/Tests/QtAutogen/UnityMocSource/main.cpp
similarity index 100%
copy from Tests/FindModulesExecuteAll/main.c
copy to Tests/QtAutogen/UnityMocSource/main.cpp
diff --git a/Tests/RunCMake/Android/RunCMakeTest.cmake b/Tests/RunCMake/Android/RunCMakeTest.cmake
index 45798ce..81dd090 100644
--- a/Tests/RunCMake/Android/RunCMakeTest.cmake
+++ b/Tests/RunCMake/Android/RunCMakeTest.cmake
@@ -18,15 +18,33 @@
   file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}")
   file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}")
   run_cmake(${case})
-  run_cmake_command(${case}-build ${CMAKE_COMMAND} --build .)
+  set(configs ".")
+  if(RunCMake_GENERATOR_IS_MULTI_CONFIG)
+    set(configs Release Debug)
+  endif()
+  foreach(config IN LISTS configs)
+    set(build_suffix)
+    set(config_arg)
+    if(RunCMake_GENERATOR_IS_MULTI_CONFIG)
+      set(build_suffix "-${config}")
+      set(config_arg --config "${config}")
+    endif()
+    run_cmake_command(${case}-build${build_suffix} ${CMAKE_COMMAND} --build . ${config_arg})
+  endforeach()
 endfunction()
 
+set(RunCMake_GENERATOR_PLATFORM_OLD "${RunCMake_GENERATOR_PLATFORM}")
+
+if(RunCMake_GENERATOR MATCHES "Visual Studio")
+  set(RunCMake_GENERATOR_PLATFORM "ARM")
+endif()
 set(RunCMake_TEST_OPTIONS
   -DCMAKE_SYSTEM_NAME=Android
   -DCMAKE_SYSROOT=${CMAKE_CURRENT_SOURCE_DIR}
   )
 run_cmake(BadSYSROOT)
 unset(RunCMake_TEST_OPTIONS)
+set(RunCMake_GENERATOR_PLATFORM "${RunCMake_GENERATOR_PLATFORM_OLD}")
 
 foreach(ndk IN LISTS TEST_ANDROID_NDK)
   # Load available toolchain versions and abis.
@@ -70,6 +88,9 @@
   if(_versions MATCHES "clang")
     set(_versions "clang" ${_versions})
   endif()
+  if(RunCMake_GENERATOR MATCHES "Visual Studio")
+    set(_versions "clang")
+  endif()
   list(REMOVE_DUPLICATES _versions)
   list(SORT _versions)
   set(_versions ";${_versions}")
@@ -77,44 +98,58 @@
     list(REMOVE_DUPLICATES _abis_${vers})
   endforeach()
 
+  set(ndk_arg -DCMAKE_ANDROID_NDK=${ndk})
+  if(RunCMake_GENERATOR MATCHES "Visual Studio")
+    set(ndk_arg)
+  endif()
+
   # Test failure cases.
   message(STATUS "ndk='${ndk}'")
+  if(RunCMake_GENERATOR MATCHES "Visual Studio")
+    set(RunCMake_GENERATOR_PLATFORM "ARM")
+  endif()
   set(RunCMake_TEST_OPTIONS
     -DCMAKE_SYSTEM_NAME=Android
-    -DCMAKE_ANDROID_NDK=${ndk}
+    ${ndk_arg}
     -DCMAKE_ANDROID_ARCH_ABI=badabi
     )
   run_cmake(ndk-badabi)
+  if(RunCMake_GENERATOR MATCHES "Visual Studio")
+    set(RunCMake_GENERATOR_PLATFORM "x86")
+  endif()
   set(RunCMake_TEST_OPTIONS
     -DCMAKE_SYSTEM_NAME=Android
-    -DCMAKE_ANDROID_NDK=${ndk}
+    ${ndk_arg}
     -DCMAKE_ANDROID_ARCH_ABI=x86
     -DCMAKE_ANDROID_ARM_MODE=0
     )
   run_cmake(ndk-badarm)
+  if(RunCMake_GENERATOR MATCHES "Visual Studio")
+    set(RunCMake_GENERATOR_PLATFORM "ARM")
+  endif()
   if("armeabi" IN_LIST _abis_)
     set(RunCMake_TEST_OPTIONS
       -DCMAKE_SYSTEM_NAME=Android
-      -DCMAKE_ANDROID_NDK=${ndk}
+      ${ndk_arg}
       -DCMAKE_ANDROID_ARM_NEON=0
       )
     run_cmake(ndk-badneon)
   endif()
   set(RunCMake_TEST_OPTIONS
     -DCMAKE_SYSTEM_NAME=Android
-    -DCMAKE_ANDROID_NDK=${ndk}
+    ${ndk_arg}
     -DCMAKE_ANDROID_NDK_TOOLCHAIN_VERSION=badver
     )
   run_cmake(ndk-badver)
   set(RunCMake_TEST_OPTIONS
     -DCMAKE_SYSTEM_NAME=Android
-    -DCMAKE_ANDROID_NDK=${ndk}
+    ${ndk_arg}
     -DCMAKE_ANDROID_NDK_TOOLCHAIN_VERSION=1.0
     )
   run_cmake(ndk-badvernum)
   set(RunCMake_TEST_OPTIONS
     -DCMAKE_SYSTEM_NAME=Android
-    -DCMAKE_ANDROID_NDK=${ndk}
+    ${ndk_arg}
     -DCMAKE_ANDROID_STL_TYPE=badstl
     )
   run_cmake(ndk-badstl)
@@ -131,6 +166,7 @@
     run_cmake(ndk-sysroot-armeabi)
     unset(RunCMake_TEST_OPTIONS)
   endif()
+  set(RunCMake_GENERATOR_PLATFORM "${RunCMake_GENERATOR_PLATFORM_OLD}")
 
   # Find available STLs.
   set(stl_types
@@ -157,23 +193,41 @@
     armeabi-v6
     armeabi-v7a
     arm64-v8a
-    mips
-    mips64
     x86
     x86_64
     )
+  if(NOT RunCMake_GENERATOR MATCHES "Visual Studio")
+    list(APPEND abi_names mips mips64)
+  endif()
+  set(abi_to_arch_armeabi ARM)
+  set(abi_to_arch_armeabi-v6 ARM)
+  set(abi_to_arch_armeabi-v7a ARM)
+  set(abi_to_arch_arm64-v8a ARM64)
+  set(abi_to_arch_x86 x86)
+  set(abi_to_arch_x86_64 x64)
 
   # Test all combinations.
   foreach(vers IN LISTS _versions)
     foreach(stl IN LISTS stl_types)
-      foreach(config Release Debug)
+      set(configs Release Debug)
+      set(foreach_list "${configs}")
+      if(RunCMake_GENERATOR_IS_MULTI_CONFIG)
+        set(foreach_list ".")
+      endif()
+      foreach(config IN LISTS foreach_list)
         # Test this combination for all available abis.
-        message(STATUS "ndk='${ndk}' vers='${vers}' stl='${stl}' config='${config}'")
+        set(config_status " config='${config}'")
+        set(build_type_arg "-DCMAKE_BUILD_TYPE=${config}")
+        if(RunCMake_GENERATOR_IS_MULTI_CONFIG)
+          set(config_status)
+          string(REPLACE ";" "\\\\;" build_type_arg "-DCMAKE_CONFIGURATION_TYPES=${configs}")
+        endif()
+        message(STATUS "ndk='${ndk}' vers='${vers}' stl='${stl}'${config_status}")
         set(RunCMake_TEST_OPTIONS
-          -DCMAKE_ANDROID_NDK=${ndk}
+          ${ndk_arg}
           -DCMAKE_ANDROID_NDK_TOOLCHAIN_VERSION=${vers}
           -DCMAKE_ANDROID_STL_TYPE=${stl}
-          -DCMAKE_BUILD_TYPE=${config}
+          "${build_type_arg}"
           )
         foreach(abi IN LISTS abi_names)
           # Skip ABIs not supported by this compiler.
@@ -182,6 +236,9 @@
           endif()
 
           # Run the tests for this combination.
+          if(RunCMake_GENERATOR MATCHES "Visual Studio")
+            set(RunCMake_GENERATOR_PLATFORM "${abi_to_arch_${abi}}")
+          endif()
           if("${abi}" STREQUAL "armeabi")
             run_Android(ndk-armeabi-thumb) # default: -DCMAKE_ANDROID_ARCH_ABI=armeabi -DCMAKE_ANDROID_ARM_MODE=0
             run_Android(ndk-armeabi-arm -DCMAKE_ANDROID_ARM_MODE=1) # default: -DCMAKE_ANDROID_ARCH_ABI=armeabi
@@ -191,6 +248,7 @@
               run_Android(ndk-${abi}-neon -DCMAKE_ANDROID_ARCH_ABI=${abi} -DCMAKE_ANDROID_ARM_NEON=1)
             endif()
           endif()
+          set(RunCMake_GENERATOR_PLATFORM "${RunCMake_GENERATOR_PLATFORM_OLD}")
         endforeach()
         unset(RunCMake_TEST_OPTIONS)
       endforeach()
diff --git a/Tests/RunCMake/Android/common.cmake b/Tests/RunCMake/Android/common.cmake
index d96ab86..32412aa 100644
--- a/Tests/RunCMake/Android/common.cmake
+++ b/Tests/RunCMake/Android/common.cmake
@@ -96,7 +96,7 @@
 add_executable(android_cxx android.cxx)
 add_library(android_cxx_lib SHARED android_lib.cxx)
 
-set(objdump "${CMAKE_CXX_ANDROID_TOOLCHAIN_PREFIX}objdump")
+set(objdump "${CMAKE_CXX_ANDROID_TOOLCHAIN_PREFIX}objdump${CMAKE_CXX_ANDROID_TOOLCHAIN_SUFFIX}")
 if(NOT EXISTS "${objdump}")
   message(FATAL_ERROR "Expected tool missing:\n  ${objdump}")
 endif()
diff --git a/Tests/RunCMake/Android/ndk-arm64-v8a-stderr.txt b/Tests/RunCMake/Android/ndk-arm64-v8a-stderr.txt
new file mode 100644
index 0000000..a3b3634
--- /dev/null
+++ b/Tests/RunCMake/Android/ndk-arm64-v8a-stderr.txt
@@ -0,0 +1,7 @@
+^(CMake Warning:
+  You are using Visual Studio tools for Android, which does not support
+  standalone executables\.  However, the following executable targets do not
+  have the ANDROID_GUI property set, and thus will not be built as expected\.
+  They will be built as shared libraries with executable filenames:
+
+    android_c, android_cxx, android_sysinc_c, android_sysinc_cxx)?$
diff --git a/Tests/RunCMake/Android/ndk-armeabi-arm-stderr.txt b/Tests/RunCMake/Android/ndk-armeabi-arm-stderr.txt
new file mode 100644
index 0000000..a3b3634
--- /dev/null
+++ b/Tests/RunCMake/Android/ndk-armeabi-arm-stderr.txt
@@ -0,0 +1,7 @@
+^(CMake Warning:
+  You are using Visual Studio tools for Android, which does not support
+  standalone executables\.  However, the following executable targets do not
+  have the ANDROID_GUI property set, and thus will not be built as expected\.
+  They will be built as shared libraries with executable filenames:
+
+    android_c, android_cxx, android_sysinc_c, android_sysinc_cxx)?$
diff --git a/Tests/RunCMake/Android/ndk-armeabi-thumb-stderr.txt b/Tests/RunCMake/Android/ndk-armeabi-thumb-stderr.txt
new file mode 100644
index 0000000..a3b3634
--- /dev/null
+++ b/Tests/RunCMake/Android/ndk-armeabi-thumb-stderr.txt
@@ -0,0 +1,7 @@
+^(CMake Warning:
+  You are using Visual Studio tools for Android, which does not support
+  standalone executables\.  However, the following executable targets do not
+  have the ANDROID_GUI property set, and thus will not be built as expected\.
+  They will be built as shared libraries with executable filenames:
+
+    android_c, android_cxx, android_sysinc_c, android_sysinc_cxx)?$
diff --git a/Tests/RunCMake/Android/ndk-armeabi-v7a-neon-stderr.txt b/Tests/RunCMake/Android/ndk-armeabi-v7a-neon-stderr.txt
new file mode 100644
index 0000000..a3b3634
--- /dev/null
+++ b/Tests/RunCMake/Android/ndk-armeabi-v7a-neon-stderr.txt
@@ -0,0 +1,7 @@
+^(CMake Warning:
+  You are using Visual Studio tools for Android, which does not support
+  standalone executables\.  However, the following executable targets do not
+  have the ANDROID_GUI property set, and thus will not be built as expected\.
+  They will be built as shared libraries with executable filenames:
+
+    android_c, android_cxx, android_sysinc_c, android_sysinc_cxx)?$
diff --git a/Tests/RunCMake/Android/ndk-armeabi-v7a-stderr.txt b/Tests/RunCMake/Android/ndk-armeabi-v7a-stderr.txt
new file mode 100644
index 0000000..a3b3634
--- /dev/null
+++ b/Tests/RunCMake/Android/ndk-armeabi-v7a-stderr.txt
@@ -0,0 +1,7 @@
+^(CMake Warning:
+  You are using Visual Studio tools for Android, which does not support
+  standalone executables\.  However, the following executable targets do not
+  have the ANDROID_GUI property set, and thus will not be built as expected\.
+  They will be built as shared libraries with executable filenames:
+
+    android_c, android_cxx, android_sysinc_c, android_sysinc_cxx)?$
diff --git a/Tests/RunCMake/Android/ndk-x86-stderr.txt b/Tests/RunCMake/Android/ndk-x86-stderr.txt
new file mode 100644
index 0000000..a3b3634
--- /dev/null
+++ b/Tests/RunCMake/Android/ndk-x86-stderr.txt
@@ -0,0 +1,7 @@
+^(CMake Warning:
+  You are using Visual Studio tools for Android, which does not support
+  standalone executables\.  However, the following executable targets do not
+  have the ANDROID_GUI property set, and thus will not be built as expected\.
+  They will be built as shared libraries with executable filenames:
+
+    android_c, android_cxx, android_sysinc_c, android_sysinc_cxx)?$
diff --git a/Tests/RunCMake/Android/ndk-x86_64-stderr.txt b/Tests/RunCMake/Android/ndk-x86_64-stderr.txt
new file mode 100644
index 0000000..a3b3634
--- /dev/null
+++ b/Tests/RunCMake/Android/ndk-x86_64-stderr.txt
@@ -0,0 +1,7 @@
+^(CMake Warning:
+  You are using Visual Studio tools for Android, which does not support
+  standalone executables\.  However, the following executable targets do not
+  have the ANDROID_GUI property set, and thus will not be built as expected\.
+  They will be built as shared libraries with executable filenames:
+
+    android_c, android_cxx, android_sysinc_c, android_sysinc_cxx)?$
diff --git a/Tests/RunCMake/AutoExportDll/AutoExport.cmake b/Tests/RunCMake/AutoExportDll/AutoExport.cmake
index a550005..85eff7e 100644
--- a/Tests/RunCMake/AutoExportDll/AutoExport.cmake
+++ b/Tests/RunCMake/AutoExportDll/AutoExport.cmake
@@ -5,6 +5,10 @@
 add_library(objlib OBJECT objlib.c)
 set_property(TARGET objlib PROPERTY POSITION_INDEPENDENT_CODE 1)
 add_library(autoexport SHARED hello.cxx world.cxx foo.c $<TARGET_OBJECTS:objlib>)
+add_library(autoexport3 SHARED cppCLI.cxx)
+if(MSVC AND NOT MSVC_VERSION VERSION_LESS 1600)
+  set_property(TARGET autoexport3 PROPERTY COMMON_LANGUAGE_RUNTIME "")
+endif()
 
 add_executable(say say.cxx)
 if(MSVC)
@@ -18,4 +22,4 @@
     target_compile_definitions(say PRIVATE HAS_JUSTNOP)
   endif()
 endif()
-target_link_libraries(say autoexport autoexport2)
+target_link_libraries(say autoexport autoexport2 autoexport3)
diff --git a/Tests/RunCMake/AutoExportDll/cppCLI.cxx b/Tests/RunCMake/AutoExportDll/cppCLI.cxx
new file mode 100644
index 0000000..816bb6e
--- /dev/null
+++ b/Tests/RunCMake/AutoExportDll/cppCLI.cxx
@@ -0,0 +1,22 @@
+#include <stdio.h>
+
+#ifdef __cplusplus_cli
+#  include <msclr\marshal_cppstd.h>
+
+void cliFunction()
+{
+  System::String ^ result = "cliFunction";
+  result = result->Trim();
+  printf(msclr::interop::marshal_as<std::string>(result).c_str());
+}
+#else
+void cliFunction()
+{
+  printf("cliFunction (but /cli was not passed to the compiler)");
+}
+#endif
+
+void nonCliFunction()
+{
+  printf("nonCliFunction");
+}
diff --git a/Tests/RunCMake/AutoExportDll/say.cxx b/Tests/RunCMake/AutoExportDll/say.cxx
index 654b5e0..8fc768a 100644
--- a/Tests/RunCMake/AutoExportDll/say.cxx
+++ b/Tests/RunCMake/AutoExportDll/say.cxx
@@ -17,9 +17,11 @@
 }
 
 // test c++ functions
-// forward declare hello and world
+// forward declare hello, world, cliFunction and nonCliFunction
 void hello();
 void world();
+void cliFunction();
+void nonCliFunction();
 
 // test exports for executable target
 extern "C" {
@@ -44,6 +46,10 @@
   bar();
   objlib();
   printf("\n");
+  cliFunction();
+  printf("\n");
+  nonCliFunction();
+  printf("\n");
 #ifdef HAS_JUSTNOP
   justnop();
 #endif
diff --git a/Tests/RunCMake/BuildDepends/GNU-AS-stdout.txt b/Tests/RunCMake/BuildDepends/GNU-AS-stdout.txt
new file mode 100644
index 0000000..c4326ae
--- /dev/null
+++ b/Tests/RunCMake/BuildDepends/GNU-AS-stdout.txt
@@ -0,0 +1,4 @@
+-- The ASM compiler identification is GNU
+-- Found assembler: [^
+]*/as(\.exe)?
+-- CMAKE_ASM_COMPILER_ID_VENDOR_MATCH='GNU assembler'
diff --git a/Tests/RunCMake/BuildDepends/GNU-AS.cmake b/Tests/RunCMake/BuildDepends/GNU-AS.cmake
new file mode 100644
index 0000000..0c7249a
--- /dev/null
+++ b/Tests/RunCMake/BuildDepends/GNU-AS.cmake
@@ -0,0 +1,14 @@
+enable_language(ASM)
+
+# Validate undocumented implementation detail.
+message(STATUS "CMAKE_ASM${ASM_DIALECT}_COMPILER_ID_VENDOR_MATCH='${CMAKE_ASM${ASM_DIALECT}_COMPILER_ID_VENDOR_MATCH}'")
+
+add_library(gnu_as STATIC gnu_as.s)
+target_include_directories(gnu_as PRIVATE ${CMAKE_CURRENT_BINARY_DIR})
+target_compile_definitions(gnu_as PRIVATE "TEST_DEF=Hello")
+
+file(GENERATE OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/check-$<LOWER_CASE:$<CONFIG>>.cmake CONTENT "
+set(check_pairs
+  \"$<TARGET_FILE:gnu_as>|${CMAKE_CURRENT_BINARY_DIR}/gnu_as.inc\"
+  )
+")
diff --git a/Tests/RunCMake/BuildDepends/GNU-AS.step1.cmake b/Tests/RunCMake/BuildDepends/GNU-AS.step1.cmake
new file mode 100644
index 0000000..15a5e96
--- /dev/null
+++ b/Tests/RunCMake/BuildDepends/GNU-AS.step1.cmake
@@ -0,0 +1 @@
+file(WRITE "${RunCMake_TEST_BINARY_DIR}/gnu_as.inc" "")
diff --git a/Tests/RunCMake/BuildDepends/GNU-AS.step2.cmake b/Tests/RunCMake/BuildDepends/GNU-AS.step2.cmake
new file mode 100644
index 0000000..15a5e96
--- /dev/null
+++ b/Tests/RunCMake/BuildDepends/GNU-AS.step2.cmake
@@ -0,0 +1 @@
+file(WRITE "${RunCMake_TEST_BINARY_DIR}/gnu_as.inc" "")
diff --git a/Tests/RunCMake/BuildDepends/RunCMakeTest.cmake b/Tests/RunCMake/BuildDepends/RunCMakeTest.cmake
index e4d7177..7a68c4b 100644
--- a/Tests/RunCMake/BuildDepends/RunCMakeTest.cmake
+++ b/Tests/RunCMake/BuildDepends/RunCMakeTest.cmake
@@ -108,3 +108,8 @@
 if(RunCMake_GENERATOR STREQUAL "Xcode")
   run_ReGeneration(regenerate-project)
 endif()
+
+if(CMake_TEST_BuildDepends_GNU_AS)
+  set(ENV{ASM} "${CMake_TEST_BuildDepends_GNU_AS}")
+  run_BuildDepends(GNU-AS)
+endif()
diff --git a/Tests/RunCMake/BuildDepends/gnu_as.s b/Tests/RunCMake/BuildDepends/gnu_as.s
new file mode 100644
index 0000000..a2e7dfb
--- /dev/null
+++ b/Tests/RunCMake/BuildDepends/gnu_as.s
@@ -0,0 +1 @@
+.include "gnu_as.inc"
diff --git a/Tests/RunCMake/BundleUtilities/ExecutableScripts.cmake b/Tests/RunCMake/BundleUtilities/ExecutableScripts.cmake
new file mode 100644
index 0000000..78a9b66
--- /dev/null
+++ b/Tests/RunCMake/BundleUtilities/ExecutableScripts.cmake
@@ -0,0 +1,18 @@
+include(BundleUtilities)
+
+set(BU_CHMOD_BUNDLE_ITEMS ON)
+
+function(check_script script)
+  fixup_bundle_item(${script} ${script} "" "")
+endfunction()
+
+# Should not throw any errors
+# Shell script
+set(script_sh_EMBEDDED_ITEM ${CMAKE_CURRENT_LIST_DIR}/test.app/script.sh)
+check_script(${CMAKE_CURRENT_LIST_DIR}/test.app/script.sh)
+# Batch script
+set(script_bat_EMBEDDED_ITEM ${CMAKE_CURRENT_LIST_DIR}/test.app/script.bat)
+check_script(${CMAKE_CURRENT_LIST_DIR}/test.app/script.bat)
+# Shell script without extension
+set(script_EMBEDDED_ITEM ${CMAKE_CURRENT_LIST_DIR}/test.app/script)
+check_script(${CMAKE_CURRENT_LIST_DIR}/test.app/script)
diff --git a/Tests/RunCMake/BundleUtilities/RunCMakeTest.cmake b/Tests/RunCMake/BundleUtilities/RunCMakeTest.cmake
index 14aaff1..df28102 100644
--- a/Tests/RunCMake/BundleUtilities/RunCMakeTest.cmake
+++ b/Tests/RunCMake/BundleUtilities/RunCMakeTest.cmake
@@ -9,3 +9,4 @@
 run_cmake_command(CMP0080-COMMAND-OLD ${CMAKE_COMMAND} -DCMP0080_VALUE:STRING=OLD -P ${RunCMake_SOURCE_DIR}/CMP0080-COMMAND.cmake)
 run_cmake_command(CMP0080-COMMAND-NEW ${CMAKE_COMMAND} -DCMP0080_VALUE:STRING=NEW -P ${RunCMake_SOURCE_DIR}/CMP0080-COMMAND.cmake)
 run_cmake_command(CMP0080-COMMAND-WARN ${CMAKE_COMMAND} -P ${RunCMake_SOURCE_DIR}/CMP0080-COMMAND.cmake)
+run_cmake_command(ExecutableScripts ${CMAKE_COMMAND} -P ${RunCMake_SOURCE_DIR}/ExecutableScripts.cmake)
diff --git a/Tests/RunCMake/BundleUtilities/test.app/script b/Tests/RunCMake/BundleUtilities/test.app/script
new file mode 100755
index 0000000..23bf47c
--- /dev/null
+++ b/Tests/RunCMake/BundleUtilities/test.app/script
@@ -0,0 +1,3 @@
+#!/bin/bash
+
+echo "Hello World"
diff --git a/Tests/RunCMake/BundleUtilities/test.app/script.bat b/Tests/RunCMake/BundleUtilities/test.app/script.bat
new file mode 100755
index 0000000..dbb0ec2
--- /dev/null
+++ b/Tests/RunCMake/BundleUtilities/test.app/script.bat
@@ -0,0 +1,3 @@
+@echo off
+
+echo "Hello world"
diff --git a/Tests/RunCMake/BundleUtilities/test.app/script.sh b/Tests/RunCMake/BundleUtilities/test.app/script.sh
new file mode 100755
index 0000000..23bf47c
--- /dev/null
+++ b/Tests/RunCMake/BundleUtilities/test.app/script.sh
@@ -0,0 +1,3 @@
+#!/bin/bash
+
+echo "Hello World"
diff --git a/Tests/RunCMake/CMP0019/CMP0019-NEW-stderr.txt b/Tests/RunCMake/CMP0019/CMP0019-NEW-stderr.txt
new file mode 100644
index 0000000..66a58fb
--- /dev/null
+++ b/Tests/RunCMake/CMP0019/CMP0019-NEW-stderr.txt
@@ -0,0 +1,6 @@
+^CMake Deprecation Warning at CMakeLists.txt:1 \(cmake_minimum_required\):
+  Compatibility with CMake < 2.8.12 will be removed from a future version of
+  CMake.
+
+  Update the VERSION argument <min> value or use a ...<max> suffix to tell
+  CMake that the project does not need compatibility with older versions.$
diff --git a/Tests/RunCMake/CMP0019/CMP0019-OLD-stderr.txt b/Tests/RunCMake/CMP0019/CMP0019-OLD-stderr.txt
index 048762d..a446211 100644
--- a/Tests/RunCMake/CMP0019/CMP0019-OLD-stderr.txt
+++ b/Tests/RunCMake/CMP0019/CMP0019-OLD-stderr.txt
@@ -1,4 +1,11 @@
-^CMake Deprecation Warning at CMP0019-OLD.cmake:[0-9]+ \(cmake_policy\):
+^CMake Deprecation Warning at CMakeLists.txt:1 \(cmake_minimum_required\):
+  Compatibility with CMake < 2.8.12 will be removed from a future version of
+  CMake.
+
+  Update the VERSION argument <min> value or use a ...<max> suffix to tell
+  CMake that the project does not need compatibility with older versions.
++
+CMake Deprecation Warning at CMP0019-OLD.cmake:[0-9]+ \(cmake_policy\):
   The OLD behavior for policy CMP0019 will be removed from a future version
   of CMake.
 
diff --git a/Tests/RunCMake/CMP0019/CMP0019-WARN-stderr.txt b/Tests/RunCMake/CMP0019/CMP0019-WARN-stderr.txt
index 1e4b47d..f7b9c0e 100644
--- a/Tests/RunCMake/CMP0019/CMP0019-WARN-stderr.txt
+++ b/Tests/RunCMake/CMP0019/CMP0019-WARN-stderr.txt
@@ -1,3 +1,10 @@
+^CMake Deprecation Warning at CMakeLists.txt:1 \(cmake_minimum_required\):
+  Compatibility with CMake < 2.8.12 will be removed from a future version of
+  CMake.
+
+  Update the VERSION argument <min> value or use a ...<max> suffix to tell
+  CMake that the project does not need compatibility with older versions.
++
 CMake Warning \(dev\) in CMakeLists.txt:
   Policy CMP0019 is not set: Do not re-expand variables in include and link
   information.  Run "cmake --help-policy CMP0019" for policy details.  Use
diff --git a/Tests/RunCMake/CMP0022/CMP0022-NOWARN-exe-stderr.txt b/Tests/RunCMake/CMP0022/CMP0022-NOWARN-exe-stderr.txt
new file mode 100644
index 0000000..66a58fb
--- /dev/null
+++ b/Tests/RunCMake/CMP0022/CMP0022-NOWARN-exe-stderr.txt
@@ -0,0 +1,6 @@
+^CMake Deprecation Warning at CMakeLists.txt:1 \(cmake_minimum_required\):
+  Compatibility with CMake < 2.8.12 will be removed from a future version of
+  CMake.
+
+  Update the VERSION argument <min> value or use a ...<max> suffix to tell
+  CMake that the project does not need compatibility with older versions.$
diff --git a/Tests/RunCMake/CMP0022/CMP0022-NOWARN-shared-stderr.txt b/Tests/RunCMake/CMP0022/CMP0022-NOWARN-shared-stderr.txt
new file mode 100644
index 0000000..66a58fb
--- /dev/null
+++ b/Tests/RunCMake/CMP0022/CMP0022-NOWARN-shared-stderr.txt
@@ -0,0 +1,6 @@
+^CMake Deprecation Warning at CMakeLists.txt:1 \(cmake_minimum_required\):
+  Compatibility with CMake < 2.8.12 will be removed from a future version of
+  CMake.
+
+  Update the VERSION argument <min> value or use a ...<max> suffix to tell
+  CMake that the project does not need compatibility with older versions.$
diff --git a/Tests/RunCMake/CMP0022/CMP0022-NOWARN-static-NEW-stderr.txt b/Tests/RunCMake/CMP0022/CMP0022-NOWARN-static-NEW-stderr.txt
new file mode 100644
index 0000000..66a58fb
--- /dev/null
+++ b/Tests/RunCMake/CMP0022/CMP0022-NOWARN-static-NEW-stderr.txt
@@ -0,0 +1,6 @@
+^CMake Deprecation Warning at CMakeLists.txt:1 \(cmake_minimum_required\):
+  Compatibility with CMake < 2.8.12 will be removed from a future version of
+  CMake.
+
+  Update the VERSION argument <min> value or use a ...<max> suffix to tell
+  CMake that the project does not need compatibility with older versions.$
diff --git a/Tests/RunCMake/CMP0022/CMP0022-NOWARN-static-link_libraries-stderr.txt b/Tests/RunCMake/CMP0022/CMP0022-NOWARN-static-link_libraries-stderr.txt
new file mode 100644
index 0000000..66a58fb
--- /dev/null
+++ b/Tests/RunCMake/CMP0022/CMP0022-NOWARN-static-link_libraries-stderr.txt
@@ -0,0 +1,6 @@
+^CMake Deprecation Warning at CMakeLists.txt:1 \(cmake_minimum_required\):
+  Compatibility with CMake < 2.8.12 will be removed from a future version of
+  CMake.
+
+  Update the VERSION argument <min> value or use a ...<max> suffix to tell
+  CMake that the project does not need compatibility with older versions.$
diff --git a/Tests/RunCMake/CMP0022/CMP0022-NOWARN-static-stderr.txt b/Tests/RunCMake/CMP0022/CMP0022-NOWARN-static-stderr.txt
new file mode 100644
index 0000000..66a58fb
--- /dev/null
+++ b/Tests/RunCMake/CMP0022/CMP0022-NOWARN-static-stderr.txt
@@ -0,0 +1,6 @@
+^CMake Deprecation Warning at CMakeLists.txt:1 \(cmake_minimum_required\):
+  Compatibility with CMake < 2.8.12 will be removed from a future version of
+  CMake.
+
+  Update the VERSION argument <min> value or use a ...<max> suffix to tell
+  CMake that the project does not need compatibility with older versions.$
diff --git a/Tests/RunCMake/CMP0022/CMP0022-WARN-empty-old-stderr.txt b/Tests/RunCMake/CMP0022/CMP0022-WARN-empty-old-stderr.txt
index 6a6a0c7..87404d3 100644
--- a/Tests/RunCMake/CMP0022/CMP0022-WARN-empty-old-stderr.txt
+++ b/Tests/RunCMake/CMP0022/CMP0022-WARN-empty-old-stderr.txt
@@ -1,3 +1,10 @@
+^CMake Deprecation Warning at CMakeLists.txt:1 \(cmake_minimum_required\):
+  Compatibility with CMake < 2.8.12 will be removed from a future version of
+  CMake.
+
+  Update the VERSION argument <min> value or use a ...<max> suffix to tell
+  CMake that the project does not need compatibility with older versions.
++
 CMake Warning \(dev\) in CMakeLists.txt:
   Policy CMP0022 is not set: INTERFACE_LINK_LIBRARIES defines the link
   interface.  Run "cmake --help-policy CMP0022" for policy details.  Use the
diff --git a/Tests/RunCMake/CMP0022/CMP0022-WARN-stderr.txt b/Tests/RunCMake/CMP0022/CMP0022-WARN-stderr.txt
index 2f7dfbf..5d75720 100644
--- a/Tests/RunCMake/CMP0022/CMP0022-WARN-stderr.txt
+++ b/Tests/RunCMake/CMP0022/CMP0022-WARN-stderr.txt
@@ -1,4 +1,11 @@
-^CMake Warning \(dev\) in CMakeLists.txt:
+^CMake Deprecation Warning at CMakeLists.txt:1 \(cmake_minimum_required\):
+  Compatibility with CMake < 2.8.12 will be removed from a future version of
+  CMake.
+
+  Update the VERSION argument <min> value or use a ...<max> suffix to tell
+  CMake that the project does not need compatibility with older versions.
++
+CMake Warning \(dev\) in CMakeLists.txt:
   Policy CMP0022 is not set: INTERFACE_LINK_LIBRARIES defines the link
   interface.  Run "cmake --help-policy CMP0022" for policy details.  Use the
   cmake_policy command to set the policy and suppress this warning.
diff --git a/Tests/RunCMake/CMP0022/CMP0022-export-exe-stderr.txt b/Tests/RunCMake/CMP0022/CMP0022-export-exe-stderr.txt
new file mode 100644
index 0000000..66a58fb
--- /dev/null
+++ b/Tests/RunCMake/CMP0022/CMP0022-export-exe-stderr.txt
@@ -0,0 +1,6 @@
+^CMake Deprecation Warning at CMakeLists.txt:1 \(cmake_minimum_required\):
+  Compatibility with CMake < 2.8.12 will be removed from a future version of
+  CMake.
+
+  Update the VERSION argument <min> value or use a ...<max> suffix to tell
+  CMake that the project does not need compatibility with older versions.$
diff --git a/Tests/RunCMake/CMP0026/CMakeLists.txt b/Tests/RunCMake/CMP0026/CMakeLists.txt
index 12cd3c7..4b3de84 100644
--- a/Tests/RunCMake/CMP0026/CMakeLists.txt
+++ b/Tests/RunCMake/CMP0026/CMakeLists.txt
@@ -1,3 +1,3 @@
-cmake_minimum_required(VERSION 2.8.4)
+cmake_minimum_required(VERSION 2.8.12)
 project(${RunCMake_TEST} NONE)
 include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/CMP0027/CMakeLists.txt b/Tests/RunCMake/CMP0027/CMakeLists.txt
index 12cd3c7..4b3de84 100644
--- a/Tests/RunCMake/CMP0027/CMakeLists.txt
+++ b/Tests/RunCMake/CMP0027/CMakeLists.txt
@@ -1,3 +1,3 @@
-cmake_minimum_required(VERSION 2.8.4)
+cmake_minimum_required(VERSION 2.8.12)
 project(${RunCMake_TEST} NONE)
 include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/CMP0028/CMakeLists.txt b/Tests/RunCMake/CMP0028/CMakeLists.txt
index 144cdb4..4f867df 100644
--- a/Tests/RunCMake/CMP0028/CMakeLists.txt
+++ b/Tests/RunCMake/CMP0028/CMakeLists.txt
@@ -1,3 +1,3 @@
-cmake_minimum_required(VERSION 2.8.4)
+cmake_minimum_required(VERSION 2.8.12)
 project(${RunCMake_TEST} CXX)
 include(${RunCMake_TEST}.cmake NO_POLICY_SCOPE) # policy used at end of dir
diff --git a/Tests/RunCMake/CMP0037/CMakeLists.txt b/Tests/RunCMake/CMP0037/CMakeLists.txt
index 12cd3c7..4b3de84 100644
--- a/Tests/RunCMake/CMP0037/CMakeLists.txt
+++ b/Tests/RunCMake/CMP0037/CMakeLists.txt
@@ -1,3 +1,3 @@
-cmake_minimum_required(VERSION 2.8.4)
+cmake_minimum_required(VERSION 2.8.12)
 project(${RunCMake_TEST} NONE)
 include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/CMP0041/CMakeLists.txt b/Tests/RunCMake/CMP0041/CMakeLists.txt
index f452db1..a06591c 100644
--- a/Tests/RunCMake/CMP0041/CMakeLists.txt
+++ b/Tests/RunCMake/CMP0041/CMakeLists.txt
@@ -1,3 +1,3 @@
-cmake_minimum_required(VERSION 2.8.4)
+cmake_minimum_required(VERSION 2.8.12)
 project(${RunCMake_TEST} CXX)
 include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/CMP0042/CMakeLists.txt b/Tests/RunCMake/CMP0042/CMakeLists.txt
index f452db1..a06591c 100644
--- a/Tests/RunCMake/CMP0042/CMakeLists.txt
+++ b/Tests/RunCMake/CMP0042/CMakeLists.txt
@@ -1,3 +1,3 @@
-cmake_minimum_required(VERSION 2.8.4)
+cmake_minimum_required(VERSION 2.8.12)
 project(${RunCMake_TEST} CXX)
 include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/CMP0043/CMakeLists.txt b/Tests/RunCMake/CMP0043/CMakeLists.txt
index d027f3e..cc8a6f8 100644
--- a/Tests/RunCMake/CMP0043/CMakeLists.txt
+++ b/Tests/RunCMake/CMP0043/CMakeLists.txt
@@ -1,4 +1,4 @@
-cmake_minimum_required(VERSION 2.8.4)
+cmake_minimum_required(VERSION 2.8.12)
 project(${RunCMake_TEST} CXX)
 include(${RunCMake_TEST}.cmake NO_POLICY_SCOPE) # policy used at end of dir
 
diff --git a/Tests/RunCMake/CMP0045/CMakeLists.txt b/Tests/RunCMake/CMP0045/CMakeLists.txt
index f452db1..a06591c 100644
--- a/Tests/RunCMake/CMP0045/CMakeLists.txt
+++ b/Tests/RunCMake/CMP0045/CMakeLists.txt
@@ -1,3 +1,3 @@
-cmake_minimum_required(VERSION 2.8.4)
+cmake_minimum_required(VERSION 2.8.12)
 project(${RunCMake_TEST} CXX)
 include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/CMP0104/CMP0104-Common.cmake b/Tests/RunCMake/CMP0104/CMP0104-Common.cmake
new file mode 100644
index 0000000..b3568f1
--- /dev/null
+++ b/Tests/RunCMake/CMP0104/CMP0104-Common.cmake
@@ -0,0 +1,2 @@
+enable_language(CUDA)
+add_library(cuda main.cu)
diff --git a/Tests/RunCMake/CMP0104/CMP0104-NEW.cmake b/Tests/RunCMake/CMP0104/CMP0104-NEW.cmake
new file mode 100644
index 0000000..732ab77
--- /dev/null
+++ b/Tests/RunCMake/CMP0104/CMP0104-NEW.cmake
@@ -0,0 +1,6 @@
+cmake_policy(SET CMP0104 NEW)
+include(CMP0104-Common.cmake)
+
+if(NOT CMAKE_CUDA_ARCHITECTURES)
+  message(FATAL_ERROR "CMAKE_CUDA_ARCHITECTURES is empty with CMP0104 enabled.")
+endif()
diff --git a/Tests/RunCMake/CMP0104/CMP0104-OFF.cmake b/Tests/RunCMake/CMP0104/CMP0104-OFF.cmake
new file mode 100644
index 0000000..f3b6682
--- /dev/null
+++ b/Tests/RunCMake/CMP0104/CMP0104-OFF.cmake
@@ -0,0 +1,3 @@
+include(CMP0104-Common.cmake)
+
+set_property(TARGET cuda PROPERTY CUDA_ARCHITECTURES OFF)
diff --git a/Tests/RunCMake/CMP0104/CMP0104-OLD.cmake b/Tests/RunCMake/CMP0104/CMP0104-OLD.cmake
new file mode 100644
index 0000000..415eecc
--- /dev/null
+++ b/Tests/RunCMake/CMP0104/CMP0104-OLD.cmake
@@ -0,0 +1,12 @@
+cmake_policy(SET CMP0104 OLD)
+include(CMP0104-Common.cmake)
+
+if(CMAKE_CUDA_COMPILER_ID STREQUAL "NVIDIA")
+  if(CMAKE_CUDA_ARCHITECTURES)
+    message(FATAL_ERROR "CMAKE_CUDA_ARCHITECTURES isn't empty for NVIDIA with CMP0104 OLD.")
+  endif()
+else(NOT CMAKE_CUDA_COMPILER_ID STREQUAL "Unknown")
+  if(NOT CMAKE_CUDA_ARCHITECTURES)
+    message(FATAL_ERROR "CMAKE_CUDA_ARCHITECTURES isn't non-empty for non-NVIDIA with CMP0104 OLD.")
+  endif()
+endif()
diff --git a/Tests/RunCMake/CMP0104/CMP0104-WARN-stderr.txt b/Tests/RunCMake/CMP0104/CMP0104-WARN-stderr.txt
new file mode 100644
index 0000000..2c9b7d7
--- /dev/null
+++ b/Tests/RunCMake/CMP0104/CMP0104-WARN-stderr.txt
@@ -0,0 +1,8 @@
+CMake Warning \(dev\) in CMakeLists.txt:
+  Policy CMP0104 is not set: CMAKE_CUDA_ARCHITECTURES now detected for NVCC,
+  empty CUDA_ARCHITECTURES not allowed.  Run "cmake --help-policy CMP0104"
+  for policy details.  Use the cmake_policy command to set the policy and
+  suppress this warning.
+
+  CUDA_ARCHITECTURES is empty for target "cuda".
+This warning is for project developers.  Use -Wno-dev to suppress it.
diff --git a/Tests/RunCMake/CMP0104/CMP0104-WARN.cmake b/Tests/RunCMake/CMP0104/CMP0104-WARN.cmake
new file mode 100644
index 0000000..2b4a8f5
--- /dev/null
+++ b/Tests/RunCMake/CMP0104/CMP0104-WARN.cmake
@@ -0,0 +1,2 @@
+include(CMP0104-Common.cmake)
+set_property(TARGET cuda PROPERTY CUDA_ARCHITECTURES)
diff --git a/Tests/RunCMake/CMP0104/CMakeLists.txt b/Tests/RunCMake/CMP0104/CMakeLists.txt
new file mode 100644
index 0000000..2632ffa
--- /dev/null
+++ b/Tests/RunCMake/CMP0104/CMakeLists.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 3.16)
+project(${RunCMake_TEST} NONE)
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/CMP0104/RunCMakeTest.cmake b/Tests/RunCMake/CMP0104/RunCMakeTest.cmake
new file mode 100644
index 0000000..b26f72a
--- /dev/null
+++ b/Tests/RunCMake/CMP0104/RunCMakeTest.cmake
@@ -0,0 +1,6 @@
+include(RunCMake)
+
+run_cmake(CMP0104-OLD)
+run_cmake(CMP0104-NEW)
+run_cmake(CMP0104-OFF)
+run_cmake(CMP0104-WARN)
diff --git a/Tests/RunCMake/CMP0104/main.cu b/Tests/RunCMake/CMP0104/main.cu
new file mode 100644
index 0000000..5047a34
--- /dev/null
+++ b/Tests/RunCMake/CMP0104/main.cu
@@ -0,0 +1,3 @@
+int main()
+{
+}
diff --git a/Tests/RunCMake/CMP0106/CMP0106-Common.cmake b/Tests/RunCMake/CMP0106/CMP0106-Common.cmake
new file mode 100644
index 0000000..a1f7908
--- /dev/null
+++ b/Tests/RunCMake/CMP0106/CMP0106-Common.cmake
@@ -0,0 +1,10 @@
+include(Documentation OPTIONAL RESULT_VARIABLE found)
+if (NOT should_find AND found)
+  message(FATAL_ERROR
+    "The Documentation module should not have been found, but it was.")
+endif ()
+if (should_find AND NOT found)
+  message(FATAL_ERROR
+    "The Documentation module should have been found, but it was not.")
+endif ()
+include(${CMAKE_ROOT}/Modules/Documentation.cmake)
diff --git a/Tests/RunCMake/interface_library/whitelist-result.txt b/Tests/RunCMake/CMP0106/CMP0106-NEW-result.txt
similarity index 100%
copy from Tests/RunCMake/interface_library/whitelist-result.txt
copy to Tests/RunCMake/CMP0106/CMP0106-NEW-result.txt
diff --git a/Tests/RunCMake/CMP0106/CMP0106-NEW-stderr.txt b/Tests/RunCMake/CMP0106/CMP0106-NEW-stderr.txt
new file mode 100644
index 0000000..7ad774e
--- /dev/null
+++ b/Tests/RunCMake/CMP0106/CMP0106-NEW-stderr.txt
@@ -0,0 +1,9 @@
+CMake Error at .*/Modules/Documentation.cmake:15 \(message\):
+  Documentation.cmake is VTK-specific code and should not be used in non-VTK
+  projects.  This logic in this module is best shipped with the project using
+  it rather than with CMake.  This is now an error according to policy
+  CMP0106.
+Call Stack \(most recent call first\):
+  CMP0106-Common.cmake:10 \(include\)
+  CMP0106-NEW.cmake:4 \(include\)
+  CMakeLists.txt:7 \(include\)
diff --git a/Tests/RunCMake/CMP0106/CMP0106-NEW.cmake b/Tests/RunCMake/CMP0106/CMP0106-NEW.cmake
new file mode 100644
index 0000000..e7d5bd1
--- /dev/null
+++ b/Tests/RunCMake/CMP0106/CMP0106-NEW.cmake
@@ -0,0 +1,4 @@
+cmake_policy(SET CMP0106 NEW)
+
+set(should_find OFF)
+include(CMP0106-Common.cmake)
diff --git a/Tests/RunCMake/CMP0106/CMP0106-OLD.cmake b/Tests/RunCMake/CMP0106/CMP0106-OLD.cmake
new file mode 100644
index 0000000..730e846
--- /dev/null
+++ b/Tests/RunCMake/CMP0106/CMP0106-OLD.cmake
@@ -0,0 +1,9 @@
+cmake_policy(SET CMP0106 OLD)
+
+set(should_find ON)
+include(CMP0106-Common.cmake)
+if (NOT DEFINED BUILD_DOCUMENTATION)
+  message(FATAL_ERROR
+    "Cache variables seem to have not been made with a `OLD` policy "
+    "setting.")
+endif ()
diff --git a/Tests/RunCMake/CMP0106/CMP0106-WARN-ParaView-stderr.txt b/Tests/RunCMake/CMP0106/CMP0106-WARN-ParaView-stderr.txt
new file mode 100644
index 0000000..b61889b
--- /dev/null
+++ b/Tests/RunCMake/CMP0106/CMP0106-WARN-ParaView-stderr.txt
@@ -0,0 +1,8 @@
+CMake Warning \(dev\) at CMP0106-Common.cmake:1 \(include\):
+  Policy CMP0106 is not set: The Documentation module is removed.  Run "cmake
+  --help-policy CMP0106" for policy details.  Use the cmake_policy command to
+  set the policy and suppress this warning.
+
+Call Stack \(most recent call first\):
+  subdir/CMakeLists.txt:2 \(include\)
+This warning is for project developers.  Use -Wno-dev to suppress it.
diff --git a/Tests/RunCMake/CMP0106/CMP0106-WARN-ParaView.cmake b/Tests/RunCMake/CMP0106/CMP0106-WARN-ParaView.cmake
new file mode 100644
index 0000000..309abcc
--- /dev/null
+++ b/Tests/RunCMake/CMP0106/CMP0106-WARN-ParaView.cmake
@@ -0,0 +1,2 @@
+set(should_find ON)
+add_subdirectory(subdir)
diff --git a/Tests/RunCMake/CMP0106/CMP0106-WARN-VTK-stderr.txt b/Tests/RunCMake/CMP0106/CMP0106-WARN-VTK-stderr.txt
new file mode 100644
index 0000000..f8a754e
--- /dev/null
+++ b/Tests/RunCMake/CMP0106/CMP0106-WARN-VTK-stderr.txt
@@ -0,0 +1,9 @@
+CMake Warning \(dev\) at CMP0106-Common.cmake:1 \(include\):
+  Policy CMP0106 is not set: The Documentation module is removed.  Run "cmake
+  --help-policy CMP0106" for policy details.  Use the cmake_policy command to
+  set the policy and suppress this warning.
+
+Call Stack \(most recent call first\):
+  CMP0106-WARN-VTK.cmake:2 \(include\)
+  CMakeLists.txt:7 \(include\)
+This warning is for project developers.  Use -Wno-dev to suppress it.
diff --git a/Tests/RunCMake/CMP0106/CMP0106-WARN-VTK.cmake b/Tests/RunCMake/CMP0106/CMP0106-WARN-VTK.cmake
new file mode 100644
index 0000000..99f6c39
--- /dev/null
+++ b/Tests/RunCMake/CMP0106/CMP0106-WARN-VTK.cmake
@@ -0,0 +1,2 @@
+set(should_find ON)
+include(CMP0106-Common.cmake)
diff --git a/Tests/RunCMake/CMP0106/CMP0106-WARN-stderr.txt b/Tests/RunCMake/CMP0106/CMP0106-WARN-stderr.txt
new file mode 100644
index 0000000..d0d48d0
--- /dev/null
+++ b/Tests/RunCMake/CMP0106/CMP0106-WARN-stderr.txt
@@ -0,0 +1,37 @@
+CMake Warning \(dev\) at CMP0106-Common.cmake:1 \(include\):
+  Policy CMP0106 is not set: The Documentation module is removed.  Run "cmake
+  --help-policy CMP0106" for policy details.  Use the cmake_policy command to
+  set the policy and suppress this warning.
+
+Call Stack \(most recent call first\):
+  CMP0106-WARN.cmake:2 \(include\)
+  CMakeLists.txt:7 \(include\)
+This warning is for project developers.  Use -Wno-dev to suppress it.
+
+CMake Warning \(dev\) at .*/Modules/Documentation.cmake:27 \(message\):
+  Policy CMP0106 is not set: The Documentation module is removed.  Run "cmake
+  --help-policy CMP0106" for policy details.  Use the cmake_policy command to
+  set the policy and suppress this warning.
+
+  Documentation.cmake is VTK-specific code and should not be used in non-VTK
+  projects.  This logic in this module is best shipped with the project using
+  it rather than with CMake.
+Call Stack \(most recent call first\):
+  CMP0106-Common.cmake:1 \(include\)
+  CMP0106-WARN.cmake:2 \(include\)
+  CMakeLists.txt:7 \(include\)
+This warning is for project developers.  Use -Wno-dev to suppress it.
+
+CMake Warning \(dev\) at .*/Modules/Documentation.cmake:27 \(message\):
+  Policy CMP0106 is not set: The Documentation module is removed.  Run "cmake
+  --help-policy CMP0106" for policy details.  Use the cmake_policy command to
+  set the policy and suppress this warning.
+
+  Documentation.cmake is VTK-specific code and should not be used in non-VTK
+  projects.  This logic in this module is best shipped with the project using
+  it rather than with CMake.
+Call Stack \(most recent call first\):
+  CMP0106-Common.cmake:10 \(include\)
+  CMP0106-WARN.cmake:2 \(include\)
+  CMakeLists.txt:7 \(include\)
+This warning is for project developers.  Use -Wno-dev to suppress it.
diff --git a/Tests/RunCMake/CMP0106/CMP0106-WARN.cmake b/Tests/RunCMake/CMP0106/CMP0106-WARN.cmake
new file mode 100644
index 0000000..99f6c39
--- /dev/null
+++ b/Tests/RunCMake/CMP0106/CMP0106-WARN.cmake
@@ -0,0 +1,2 @@
+set(should_find ON)
+include(CMP0106-Common.cmake)
diff --git a/Tests/RunCMake/CMP0106/CMakeLists.txt b/Tests/RunCMake/CMP0106/CMakeLists.txt
new file mode 100644
index 0000000..eafa642
--- /dev/null
+++ b/Tests/RunCMake/CMP0106/CMakeLists.txt
@@ -0,0 +1,7 @@
+cmake_minimum_required(VERSION 3.1)
+if (RunCMake_TEST STREQUAL "CMP0106-WARN-VTK")
+  project(VTK NONE)
+else ()
+  project(${RunCMake_TEST} NONE)
+endif ()
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/CMP0106/RunCMakeTest.cmake b/Tests/RunCMake/CMP0106/RunCMakeTest.cmake
new file mode 100644
index 0000000..acec054
--- /dev/null
+++ b/Tests/RunCMake/CMP0106/RunCMakeTest.cmake
@@ -0,0 +1,7 @@
+include(RunCMake)
+
+run_cmake(CMP0106-OLD)
+run_cmake(CMP0106-NEW)
+run_cmake(CMP0106-WARN)
+run_cmake(CMP0106-WARN-VTK)
+run_cmake(CMP0106-WARN-ParaView)
diff --git a/Tests/RunCMake/CMP0106/subdir/CMakeLists.txt b/Tests/RunCMake/CMP0106/subdir/CMakeLists.txt
new file mode 100644
index 0000000..ed1dd05
--- /dev/null
+++ b/Tests/RunCMake/CMP0106/subdir/CMakeLists.txt
@@ -0,0 +1,2 @@
+project(VTK NONE)
+include(${CMAKE_CURRENT_SOURCE_DIR}/../CMP0106-Common.cmake)
diff --git a/Tests/RunCMake/CMakeLists.txt b/Tests/RunCMake/CMakeLists.txt
index 0b2ef6a..e08b30a 100644
--- a/Tests/RunCMake/CMakeLists.txt
+++ b/Tests/RunCMake/CMakeLists.txt
@@ -81,7 +81,9 @@
 # Test MSVC for older host CMake versions, and test
 # WIN32/CMAKE_C_COMPILER_ID to fix check on Intel for Windows.
 if(MSVC OR (WIN32 AND CMAKE_C_COMPILER_ID MATCHES "MSVC|Intel"))
-  set(GeneratorExpression_ARGS -DLINKER_SUPPORTS_PDB=1)
+  set(LINKER_SUPPORTS_PDB 1)
+else()
+  set(LINKER_SUPPORTS_PDB 0)
 endif()
 
 add_RunCMake_test(CMP0019)
@@ -116,6 +118,12 @@
 add_RunCMake_test(CMP0069)
 add_RunCMake_test(CMP0081)
 add_RunCMake_test(CMP0102)
+if(CMake_TEST_CUDA)
+  add_RunCMake_test(CMP0104)
+  set_property(TEST RunCMake.CMP0104 APPEND
+    PROPERTY LABELS "CUDA")
+endif()
+add_RunCMake_test(CMP0106)
 
 # The test for Policy 65 requires the use of the
 # CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS variable, which both the VS and Xcode
@@ -148,6 +156,8 @@
     list(APPEND NinjaMultiConfig_ARGS -DCMake_TEST_CUDA=${CMake_TEST_CUDA})
   endif()
   add_RunCMake_test(NinjaMultiConfig)
+  set_property(TEST RunCMake.NinjaMultiConfig APPEND
+    PROPERTY LABELS "CUDA")
 endif()
 add_RunCMake_test(CTest)
 
@@ -156,6 +166,7 @@
     -DPSEUDO_BC=$<TARGET_FILE:pseudo_BC>
     -DPSEUDO_PURIFY=$<TARGET_FILE:pseudo_purify>
     -DPSEUDO_VALGRIND=$<TARGET_FILE:pseudo_valgrind>
+    -DPSEUDO_CUDA_MEMCHECK=$<TARGET_FILE:pseudo_cuda-memcheck>
     -DPSEUDO_BC_NOLOG=$<TARGET_FILE:pseudonl_BC>
     -DPSEUDO_PURIFY_NOLOG=$<TARGET_FILE:pseudonl_purify>
     -DPSEUDO_VALGRIND_NOLOG=$<TARGET_FILE:pseudonl_valgrind>
@@ -172,7 +183,20 @@
   set(autogen_with_qt5 TRUE)
 endif ()
 add_RunCMake_test(Autogen -Dwith_qt5=${autogen_with_qt5})
-add_RunCMake_test(BuildDepends)
+if(NOT DEFINED CMake_TEST_BuildDepends_GNU_AS
+    AND CMAKE_C_COMPILER_ID STREQUAL "GNU"
+    AND CMAKE_GENERATOR MATCHES "^Ninja"
+    )
+  execute_process(COMMAND "${CMAKE_C_COMPILER}" -print-prog-name=as
+    RESULT_VARIABLE _gnu_res
+    OUTPUT_VARIABLE _gnu_as OUTPUT_STRIP_TRAILING_WHITESPACE ERROR_QUIET)
+  if(_gnu_res EQUAL 0 AND _gnu_as)
+    set(CMake_TEST_BuildDepends_GNU_AS "${_gnu_as}")
+  endif()
+endif()
+add_RunCMake_test(BuildDepends
+  -DCMake_TEST_BuildDepends_GNU_AS=${CMake_TEST_BuildDepends_GNU_AS}
+  )
 if(UNIX AND "${CMAKE_GENERATOR}" MATCHES "Unix Makefiles|Ninja")
   add_RunCMake_test(Byproducts)
 endif()
@@ -183,19 +207,33 @@
 add_RunCMake_test(CompilerNotFound)
 add_RunCMake_test(Configure -DMSVC_IDE=${MSVC_IDE})
 add_RunCMake_test(DisallowedCommands)
+if("${CMAKE_GENERATOR}" MATCHES "Unix Makefiles|Ninja")
+  add_RunCMake_test(ExportCompileCommands)
+endif()
+add_RunCMake_test(ExcludeFromAll)
 add_RunCMake_test(ExternalData)
 add_RunCMake_test(FeatureSummary)
 add_RunCMake_test(FPHSA)
-add_RunCMake_test(FileAPI -DPYTHON_EXECUTABLE=${PYTHON_EXECUTABLE})
+add_RunCMake_test(FileAPI -DPYTHON_EXECUTABLE=${PYTHON_EXECUTABLE}
+                          -DCMAKE_CXX_COMPILER_ID=${CMAKE_CXX_COMPILER_ID})
 add_RunCMake_test(FindBoost)
 add_RunCMake_test(FindLua)
 add_RunCMake_test(FindOpenGL)
 if(CMake_TEST_UseSWIG)
+  add_RunCMake_test(FindSWIG)
   add_RunCMake_test(UseSWIG -DCMake_TEST_FindPython=${CMake_TEST_FindPython})
 endif()
 if(NOT CMAKE_C_COMPILER_ID MATCHES "Watcom")
   add_RunCMake_test(GenerateExportHeader)
 endif()
+add_RunCMake_test(GenEx-COMPILE_LANGUAGE)
+add_RunCMake_test(GenEx-COMPILE_LANG_AND_ID)
+add_RunCMake_test(GenEx-LINK_LANGUAGE)
+add_RunCMake_test(GenEx-LINK_LANG_AND_ID)
+add_RunCMake_test(GenEx-HOST_LINK)
+add_RunCMake_test(GenEx-DEVICE_LINK)
+add_RunCMake_test(GenEx-TARGET_FILE -DLINKER_SUPPORTS_PDB=${LINKER_SUPPORTS_PDB})
+add_RunCMake_test(GenEx-GENEX_EVAL)
 add_RunCMake_test(GeneratorExpression)
 add_RunCMake_test(GeneratorInstance)
 add_RunCMake_test(GeneratorPlatform)
@@ -262,6 +300,7 @@
 endif()
 add_RunCMake_test(execute_process)
 add_RunCMake_test(export)
+add_RunCMake_test(cmake_language)
 add_RunCMake_test(cmake_minimum_required)
 add_RunCMake_test(cmake_parse_arguments)
 add_RunCMake_test(continue)
@@ -282,7 +321,7 @@
 add_RunCMake_test(ctest_fixtures)
 add_RunCMake_test(file)
 add_RunCMake_test(find_file)
-add_RunCMake_test(find_library)
+add_RunCMake_test(find_library -DCYGWIN=${CYGWIN})
 add_RunCMake_test(find_package)
 add_RunCMake_test(find_path)
 add_RunCMake_test(find_program -DCMAKE_SYSTEM_NAME=${CMAKE_SYSTEM_NAME})
@@ -335,6 +374,7 @@
       CMAKE_CXX_COMPILER_VERSION
       CMAKE_CXX_STANDARD_DEFAULT
       CMake_TEST_CUDA
+      CMake_TEST_FILESYSTEM_1S
       CMAKE_OBJC_STANDARD_DEFAULT
       CMAKE_OBJCXX_STANDARD_DEFAULT
       )
@@ -343,6 +383,8 @@
     endif()
   endforeach()
   add_RunCMake_test(try_compile)
+  set_property(TEST RunCMake.try_compile APPEND
+    PROPERTY LABELS "CUDA")
 endfunction()
 add_RunCMake_test_try_compile()
 
@@ -354,7 +396,7 @@
 add_RunCMake_test(CMP0004)
 add_RunCMake_test(TargetPolicies)
 add_RunCMake_test(alias_targets)
-add_RunCMake_test(interface_library)
+add_RunCMake_test(InterfaceLibrary)
 add_RunCMake_test(no_install_prefix)
 add_RunCMake_test(configure_file)
 add_RunCMake_test(CTestTimeout -DTIMEOUT=${CTestTestTimeout_TIME})
@@ -395,9 +437,13 @@
 if(TARGET ctresalloc)
   add_RunCMake_test(CTestResourceAllocation -DCTRESALLOC_COMMAND=$<TARGET_FILE:ctresalloc>)
 else()
-  message(WARNING "Could not find or build ctresalloc")
+  message(STATUS "Could not find ctresalloc")
 endif()
 
+if(NOT WIN32)
+  add_RunCMake_test(SymlinkTrees)
+endif ()
+
 find_package(Qt4 QUIET)
 find_package(Qt5Core QUIET)
 if (QT4_FOUND AND Qt5Core_FOUND AND NOT Qt5Core_VERSION VERSION_LESS 5.1.0)
@@ -450,12 +496,20 @@
   add_RunCMake_test(Framework)
 endif()
 
+add_RunCMake_test(File_Archive)
+add_RunCMake_test(File_Configure)
 add_RunCMake_test(File_Generate)
 add_RunCMake_test(ExportWithoutLanguage)
 add_RunCMake_test(target_link_directories)
 add_RunCMake_test(target_link_libraries)
+add_RunCMake_test(target_link_libraries-ALIAS)
+add_RunCMake_test(target_link_libraries-LINK_LANGUAGE)
+add_RunCMake_test(target_link_libraries-LINK_LANG_AND_ID)
 add_RunCMake_test(add_link_options -DCMAKE_C_COMPILER_ID=${CMAKE_C_COMPILER_ID})
-add_RunCMake_test(target_link_options -DCMAKE_C_COMPILER_ID=${CMAKE_C_COMPILER_ID})
+add_RunCMake_test(target_link_options -DCMAKE_C_COMPILER_ID=${CMAKE_C_COMPILER_ID}
+                                      -DCMake_TEST_CUDA=${CMake_TEST_CUDA})
+set_property(TEST RunCMake.target_link_options APPEND
+  PROPERTY LABELS "CUDA")
 
 add_RunCMake_test(target_compile_definitions)
 add_RunCMake_test(target_compile_features)
@@ -464,6 +518,12 @@
 add_RunCMake_test(target_sources)
 add_RunCMake_test(CheckModules)
 add_RunCMake_test(CheckIPOSupported)
+if (CMAKE_SYSTEM_NAME MATCHES "(Linux|Darwin)"
+    AND (CMAKE_C_COMPILER_ID MATCHES "Clang|GNU" OR CMAKE_Fortran_COMPILER_ID MATCHES "GNU"))
+  add_RunCMake_test(CheckLinkerFlag -DCMAKE_C_COMPILER_ID=${CMAKE_C_COMPILER_ID}
+                                    -DCMAKE_Fortran_COMPILER_ID=${CMAKE_Fortran_COMPILER_ID})
+endif()
+
 add_RunCMake_test(CommandLine -DCMAKE_SYSTEM_NAME=${CMAKE_SYSTEM_NAME} -DCYGWIN=${CYGWIN} -DPYTHON_EXECUTABLE=${PYTHON_EXECUTABLE})
 add_RunCMake_test(CommandLineTar)
 
@@ -473,11 +533,15 @@
   set(NO_NAMELINK 0)
 endif()
 
-add_RunCMake_test(install -DNO_NAMELINK=${NO_NAMELINK} -DCYGWIN=${CYGWIN} -DCMAKE_C_COMPILER_ID=${CMAKE_C_COMPILER_ID}
+add_RunCMake_test(install -DNO_NAMELINK=${NO_NAMELINK} -DCYGWIN=${CYGWIN}
   -DCMAKE_SHARED_LIBRARY_RPATH_ORIGIN_TOKEN=${CMAKE_SHARED_LIBRARY_RPATH_ORIGIN_TOKEN}
   -DCMAKE_SYSTEM_NAME=${CMAKE_SYSTEM_NAME}
   -DCMAKE_SHARED_LIBRARY_RUNTIME_C_FLAG=${CMAKE_SHARED_LIBRARY_RUNTIME_C_FLAG}
   -DCMAKE_EXECUTABLE_FORMAT=${CMAKE_EXECUTABLE_FORMAT}
+  )
+
+add_RunCMake_test(file-GET_RUNTIME_DEPENDENCIES
+  -DCMAKE_C_COMPILER_ID=${CMAKE_C_COMPILER_ID}
   -DCMake_INSTALL_NAME_TOOL_BUG=${CMake_INSTALL_NAME_TOOL_BUG}
   )
 
@@ -559,7 +623,10 @@
     list(APPEND CompilerLauncher_ARGS -DCMake_TEST_OBJC=1)
   endif()
   add_RunCMake_test(CompilerLauncher)
+  set_property(TEST RunCMake.CompilerLauncher APPEND
+    PROPERTY LABELS "CUDA")
   add_RunCMake_test(ctest_labels_for_subprojects)
+  add_RunCMake_test(CompilerArgs)
 endif()
 
 set(cpack_tests
@@ -625,8 +692,8 @@
 add_RunCMake_test(AndroidMK)
 
 if(CMake_TEST_ANDROID_NDK OR CMake_TEST_ANDROID_STANDALONE_TOOLCHAIN)
-  if(NOT "${CMAKE_GENERATOR}" MATCHES "Make|Ninja")
-    message(FATAL_ERROR "Android tests supported only by Makefile and Ninja generators")
+  if(NOT "${CMAKE_GENERATOR}" MATCHES "Make|Ninja|Visual Studio 1[456]")
+    message(FATAL_ERROR "Android tests supported only by Makefile, Ninja, and Visual Studio >= 14 generators")
   endif()
   foreach(v TEST_ANDROID_NDK TEST_ANDROID_STANDALONE_TOOLCHAIN)
     if(CMake_${v})
@@ -652,5 +719,5 @@
 
 add_RunCMake_test("CTestCommandExpandLists")
 
-add_RunCMake_test(PrecompileHeaders)
+add_RunCMake_test(PrecompileHeaders -DCMAKE_C_COMPILER_ID=${CMAKE_C_COMPILER_ID})
 add_RunCMake_test("UnityBuild")
diff --git a/Tests/RunCMake/CPack/DragNDrop/Accept.txt b/Tests/RunCMake/CPack/DragNDrop/Accept.txt
new file mode 100644
index 0000000..975fbec
--- /dev/null
+++ b/Tests/RunCMake/CPack/DragNDrop/Accept.txt
@@ -0,0 +1 @@
+y
diff --git a/Tests/RunCMake/CPack/DragNDrop/Helpers.cmake b/Tests/RunCMake/CPack/DragNDrop/Helpers.cmake
index 023e597..896fba7 100644
--- a/Tests/RunCMake/CPack/DragNDrop/Helpers.cmake
+++ b/Tests/RunCMake/CPack/DragNDrop/Helpers.cmake
@@ -5,6 +5,7 @@
   file(REMOVE_RECURSE "${path_}/content")
   file(MAKE_DIRECTORY "${path_}/content")
   execute_process(COMMAND ${HDIUTIL_EXECUTABLE} attach -mountroot ${path_}/content -nobrowse ${FILE}
+          INPUT_FILE "${src_dir}/DragNDrop/Accept.txt"
           RESULT_VARIABLE attach_result_
           ERROR_VARIABLE attach_error_
           OUTPUT_STRIP_TRAILING_WHITESPACE)
diff --git a/Tests/RunCMake/CPack/DragNDrop/packaging_MONOLITHIC_default.cmake b/Tests/RunCMake/CPack/DragNDrop/packaging_MONOLITHIC_default.cmake
new file mode 100644
index 0000000..ca27890
--- /dev/null
+++ b/Tests/RunCMake/CPack/DragNDrop/packaging_MONOLITHIC_default.cmake
@@ -0,0 +1,2 @@
+set(CPACK_DMG_DISABLE_APPLICATIONS_SYMLINK ON)
+set(CPACK_DMG_VOLUME_NAME "volume-name")
diff --git a/Tests/RunCMake/CPack/RunCMakeTest.cmake b/Tests/RunCMake/CPack/RunCMakeTest.cmake
index 3be1fd0..530bcdf 100644
--- a/Tests/RunCMake/CPack/RunCMakeTest.cmake
+++ b/Tests/RunCMake/CPack/RunCMakeTest.cmake
@@ -10,6 +10,7 @@
 run_cpack_test_subtests(DEFAULT_PERMISSIONS "CMAKE_var_set;CPACK_var_set;both_set;invalid_CMAKE_var;invalid_CPACK_var" "RPM.DEFAULT_PERMISSIONS;DEB.DEFAULT_PERMISSIONS" false "MONOLITHIC;COMPONENT")
 run_cpack_test(DEPENDENCIES "RPM.DEPENDENCIES;DEB.DEPENDENCIES" true "COMPONENT")
 run_cpack_test(DIST "RPM.DIST" false "MONOLITHIC")
+run_cpack_test(DMG_SLA "DragNDrop" false "MONOLITHIC")
 run_cpack_test(EMPTY_DIR "RPM.EMPTY_DIR;DEB.EMPTY_DIR;TGZ" true "MONOLITHIC;COMPONENT")
 run_cpack_test(VERSION "RPM.VERSION;DEB.VERSION" false "MONOLITHIC;COMPONENT")
 run_cpack_test(EXTRA "DEB.EXTRA" false "COMPONENT")
@@ -20,6 +21,8 @@
 run_cpack_test_subtests(MAIN_COMPONENT "invalid;found" "RPM.MAIN_COMPONENT" false "COMPONENT")
 run_cpack_test(MINIMAL "RPM.MINIMAL;DEB.MINIMAL;7Z;TBZ2;TGZ;TXZ;TZ;ZIP;STGZ;External" false "MONOLITHIC;COMPONENT")
 run_cpack_test_package_target(MINIMAL "RPM.MINIMAL;DEB.MINIMAL;7Z;TBZ2;TGZ;TXZ;TZ;ZIP;STGZ;External" false "MONOLITHIC;COMPONENT")
+run_cpack_test_package_target(THREADED_ALL "TXZ" false "MONOLITHIC;COMPONENT")
+run_cpack_test_package_target(THREADED "TXZ" false "MONOLITHIC;COMPONENT")
 run_cpack_test_subtests(PACKAGE_CHECKSUM "invalid;MD5;SHA1;SHA224;SHA256;SHA384;SHA512" "TGZ" false "MONOLITHIC")
 run_cpack_test(PARTIALLY_RELOCATABLE_WARNING "RPM.PARTIALLY_RELOCATABLE_WARNING" false "COMPONENT")
 run_cpack_test(PER_COMPONENT_FIELDS "RPM.PER_COMPONENT_FIELDS;DEB.PER_COMPONENT_FIELDS" false "COMPONENT")
@@ -44,3 +47,4 @@
   "MONOLITHIC;COMPONENT"
 )
 run_cpack_test(PROJECT_META "RPM.PROJECT_META;DEB.PROJECT_META" false "MONOLITHIC;COMPONENT")
+run_cpack_test_package_target(PRE_POST_SCRIPTS "ZIP" false "MONOLITHIC;COMPONENT")
diff --git a/Tests/RunCMake/CPack/tests/DEB_DESCRIPTION/VerifyResult.cmake b/Tests/RunCMake/CPack/tests/DEB_DESCRIPTION/VerifyResult.cmake
index 70ad48b..6e841fc 100644
--- a/Tests/RunCMake/CPack/tests/DEB_DESCRIPTION/VerifyResult.cmake
+++ b/Tests/RunCMake/CPack/tests/DEB_DESCRIPTION/VerifyResult.cmake
@@ -34,7 +34,7 @@
   This is the Debian package multiline description.
   .
   It must be formatted properly! Otherwise, the result `*.deb`
-  package become broken and cant be installed!
+  package become broken and cannot be installed!
   .
   It may contains `;` characters (even like this `;;;;`). Example:
   .
diff --git a/Tests/RunCMake/CPack/tests/DEB_DESCRIPTION/test.cmake b/Tests/RunCMake/CPack/tests/DEB_DESCRIPTION/test.cmake
index 893eb01..2a27b46 100644
--- a/Tests/RunCMake/CPack/tests/DEB_DESCRIPTION/test.cmake
+++ b/Tests/RunCMake/CPack/tests/DEB_DESCRIPTION/test.cmake
@@ -5,7 +5,7 @@
 set(_description [[This is the Debian package multiline description.
 
 It must be formatted properly! Otherwise, the result `*.deb`
-package become broken and cant be installed!
+package become broken and cannot be installed!
 
 It may contains `;` characters (even like this `;;;;`). Example:
 
diff --git a/Tests/RunCMake/CPack/tests/DMG_SLA/English.license.rtf b/Tests/RunCMake/CPack/tests/DMG_SLA/English.license.rtf
new file mode 100644
index 0000000..c1da711
--- /dev/null
+++ b/Tests/RunCMake/CPack/tests/DMG_SLA/English.license.rtf
@@ -0,0 +1,7 @@
+{\rtf1\ansi\ansicpg1252\deff0\nouicompat\deflang1033{\fonttbl{\f0\fnil\fcharset0 Calibri;}}
+{\colortbl ;\red0\green0\blue255;}
+{\*\generator Riched20 10.0.18362}\viewkind4\uc1
+\pard\sa200\sl276\slmult1\b\f0\fs22\lang9 LICENSE\b0\par
+This is an installer created using CPack ({{\field{\*\fldinst{HYPERLINK https://cmake.org }}{\fldrslt{https://cmake.org\ul0\cf0}}}}\f0\fs22 ). No license provided.\par
+\par
+}
diff --git a/Tests/RunCMake/CPack/tests/DMG_SLA/English.menu.txt b/Tests/RunCMake/CPack/tests/DMG_SLA/English.menu.txt
new file mode 100644
index 0000000..b2cbc25
--- /dev/null
+++ b/Tests/RunCMake/CPack/tests/DMG_SLA/English.menu.txt
@@ -0,0 +1,9 @@
+English
+Agree
+Disagree
+Print
+Save...
+You agree to the License Agreement terms when you click the "Agree" button.
+Software License Agreement
+This text cannot be saved. This disk may be full or locked or the file may be locked.
+Unable to print.  Make sure you have selected a printer.
diff --git a/Tests/RunCMake/CPack/tests/DMG_SLA/ExpectedFiles.cmake b/Tests/RunCMake/CPack/tests/DMG_SLA/ExpectedFiles.cmake
new file mode 100644
index 0000000..d1a3a5f
--- /dev/null
+++ b/Tests/RunCMake/CPack/tests/DMG_SLA/ExpectedFiles.cmake
@@ -0,0 +1,2 @@
+set(EXPECTED_FILES_COUNT "1")
+set(EXPECTED_FILE_CONTENT_1_LIST "/foo;/foo/CMakeLists.txt")
diff --git a/Tests/RunCMake/CPack/tests/DMG_SLA/German.license.txt b/Tests/RunCMake/CPack/tests/DMG_SLA/German.license.txt
new file mode 100644
index 0000000..0edd1f2
--- /dev/null
+++ b/Tests/RunCMake/CPack/tests/DMG_SLA/German.license.txt
@@ -0,0 +1,3 @@
+LIZENZ
+------
+Dies ist ein Installationsprogramm, das mit erstellt wurde CPack (https://cmake.org). Keine Lizenz angegeben.
diff --git a/Tests/RunCMake/CPack/tests/DMG_SLA/German.menu.txt b/Tests/RunCMake/CPack/tests/DMG_SLA/German.menu.txt
new file mode 100644
index 0000000..7724818
--- /dev/null
+++ b/Tests/RunCMake/CPack/tests/DMG_SLA/German.menu.txt
@@ -0,0 +1,9 @@
+German
+Akzeptieren
+Ablehnen
+Drucken
+Speichern...
+Klicken Sie auf "Akzeptieren", wenn Sie mit den Bestimmungen des Software-Lizenzvertrages einverstanden sind.
+Software-Lizenzvertrag
+Dieser Text kann nicht gesichert werden. Diese Festplatte ist mšglicherweise voll oder geschŸtzt oder der Ordner ist geschŸtzt.
+Es kann nicht gedruckt werden. Bitte stellen Sie sicher, dass ein Drucker ausgewŠhlt ist.
diff --git a/Tests/RunCMake/CPack/tests/DMG_SLA/VerifyResult.cmake b/Tests/RunCMake/CPack/tests/DMG_SLA/VerifyResult.cmake
new file mode 100644
index 0000000..010e14c
--- /dev/null
+++ b/Tests/RunCMake/CPack/tests/DMG_SLA/VerifyResult.cmake
@@ -0,0 +1,33 @@
+set(dmg "${bin_dir}/${FOUND_FILE_1}")
+execute_process(COMMAND hdiutil udifderez -xml "${dmg}" OUTPUT_VARIABLE out ERROR_VARIABLE err RESULT_VARIABLE res)
+if(NOT res EQUAL 0)
+  string(REPLACE "\n" "\n  " err "  ${err}")
+  message(FATAL_ERROR "Running 'hdiutil udifderez -xml' on\n  ${dmg}\nfailed with:\n${err}")
+endif()
+foreach(key "LPic" "STR#" "TEXT" "RTF ")
+  if(NOT out MATCHES "<key>${key}</key>")
+    string(REPLACE "\n" "\n  " out "  ${out}")
+    message(FATAL_ERROR "error: running 'hdiutil udifderez -xml' on\n  ${dmg}\ndid not show '${key}' key:\n${out}")
+  endif()
+endforeach()
+foreach(line
+    # LPic
+    "\tAAAAAgAAAAAAAAADAAEAAA==\n"
+    # STR# English first and last base64 lines
+    "\tAAkHRW5nbGlzaAVBZ3JlZQhEaXNhZ3JlZQVQcmludAdTYXZlLi4u\n"
+    "\tZCBhIHByaW50ZXIu\n"
+    # STR# German first and last base64 lines
+    "\tAAkGR2VybWFuC0FremVwdGllcmVuCEFibGVobmVuB0RydWNrZW4M\n"
+    "\tYXVzZ2V3wopobHQgaXN0Lg==\n"
+    # RTF English first and last base64 lines
+    "\te1xydGYxXGFuc2lcYW5zaWNwZzEyNTJcZGVmZjBcbm91aWNvbXBh\n"
+    "\tdmlkZWQuXHBhcg1ccGFyDX0NDQ==\n"
+    # TEXT German first and last base64 lines
+    "\tTElaRU5aDS0tLS0tLQ1EaWVzIGlzdCBlaW4gSW5zdGFsbGF0aW9u\n"
+    "\tZ2ViZW4uDQ0=\n"
+    )
+  if(NOT out MATCHES "${line}")
+    string(REPLACE "\n" "\n  " out "  ${out}")
+    message(FATAL_ERROR "error: running 'hdiutil udifderez -xml' on\n  ${dmg}\ndid not show '${line}':\n${out}")
+  endif()
+endforeach()
diff --git a/Tests/RunCMake/CPack/tests/DMG_SLA/test.cmake b/Tests/RunCMake/CPack/tests/DMG_SLA/test.cmake
new file mode 100644
index 0000000..2804b0b
--- /dev/null
+++ b/Tests/RunCMake/CPack/tests/DMG_SLA/test.cmake
@@ -0,0 +1,3 @@
+install(FILES CMakeLists.txt DESTINATION foo)
+set(CPACK_DMG_SLA_DIR "${CMAKE_CURRENT_LIST_DIR}")
+set(CPACK_DMG_SLA_LANGUAGES English German)
diff --git a/Tests/RunCMake/CPack/tests/EXTERNAL/create_package.cmake b/Tests/RunCMake/CPack/tests/EXTERNAL/create_package.cmake
index 6f7c4c2..3db8014 100644
--- a/Tests/RunCMake/CPack/tests/EXTERNAL/create_package.cmake
+++ b/Tests/RunCMake/CPack/tests/EXTERNAL/create_package.cmake
@@ -29,3 +29,11 @@
 expect_file(${CPACK_TEMPORARY_DIRECTORY}/f4/share/cpack-test/f4.txt)
 
 message(STATUS "This status message is expected to be visible")
+
+set(
+    CPACK_EXTERNAL_BUILT_PACKAGES
+    ${CPACK_TEMPORARY_DIRECTORY}/f1/share/cpack-test/f1.txt
+    ${CPACK_TEMPORARY_DIRECTORY}/f2/share/cpack-test/f2.txt
+    ${CPACK_TEMPORARY_DIRECTORY}/f3/share/cpack-test/f3.txt
+    ${CPACK_TEMPORARY_DIRECTORY}/f4/share/cpack-test/f4.txt
+  )
diff --git a/Tests/RunCMake/CPack/tests/EXTERNAL/stage_and_package-stdout.txt b/Tests/RunCMake/CPack/tests/EXTERNAL/stage_and_package-stdout.txt
index 37d635f..587b2e8 100644
--- a/Tests/RunCMake/CPack/tests/EXTERNAL/stage_and_package-stdout.txt
+++ b/Tests/RunCMake/CPack/tests/EXTERNAL/stage_and_package-stdout.txt
@@ -1 +1,11 @@
 -- This status message is expected to be visible
+CPack: - package: .*/Tests/RunCMake/External/CPack/EXTERNAL-build-stage_and_package-subtest/external-0\.1\.1-.*\.json generated\.
+CPack: - checksum file: .*/Tests/RunCMake/External/CPack/EXTERNAL-build-stage_and_package-subtest/external-0\.1\.1-.*\.json\.sha1 generated\.
+CPack: - package: .*/Tests/RunCMake/External/CPack/EXTERNAL-build-stage_and_package-subtest/f1\.txt generated\.
+CPack: - checksum file: .*/Tests/RunCMake/External/CPack/EXTERNAL-build-stage_and_package-subtest/f1\.txt\.sha1 generated\.
+CPack: - package: .*/Tests/RunCMake/External/CPack/EXTERNAL-build-stage_and_package-subtest/f2\.txt generated\.
+CPack: - checksum file: .*/Tests/RunCMake/External/CPack/EXTERNAL-build-stage_and_package-subtest/f2\.txt\.sha1 generated\.
+CPack: - package: .*/Tests/RunCMake/External/CPack/EXTERNAL-build-stage_and_package-subtest/f3\.txt generated\.
+CPack: - checksum file: .*/Tests/RunCMake/External/CPack/EXTERNAL-build-stage_and_package-subtest/f3\.txt\.sha1 generated\.
+CPack: - package: .*/Tests/RunCMake/External/CPack/EXTERNAL-build-stage_and_package-subtest/f4\.txt generated\.
+CPack: - checksum file: .*/Tests/RunCMake/External/CPack/EXTERNAL-build-stage_and_package-subtest/f4\.txt\.sha1 generated\.
diff --git a/Tests/RunCMake/CPack/tests/EXTERNAL/test.cmake b/Tests/RunCMake/CPack/tests/EXTERNAL/test.cmake
index bc9766b..d4781ba 100644
--- a/Tests/RunCMake/CPack/tests/EXTERNAL/test.cmake
+++ b/Tests/RunCMake/CPack/tests/EXTERNAL/test.cmake
@@ -17,6 +17,7 @@
 elseif(RunCMake_SUBTEST_SUFFIX STREQUAL "stage_and_package")
   set(CPACK_EXTERNAL_ENABLE_STAGING 1)
   set(CPACK_EXTERNAL_PACKAGE_SCRIPT "${CMAKE_CURRENT_LIST_DIR}/create_package.cmake")
+  set(CPACK_PACKAGE_CHECKSUM SHA1)
 endif()
 
 file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/f1.txt" test1)
diff --git a/Tests/RunCMake/CPack/tests/INSTALL_SCRIPTS/VerifyResult.cmake b/Tests/RunCMake/CPack/tests/INSTALL_SCRIPTS/VerifyResult.cmake
index d7d82f2..1a1e983 100644
--- a/Tests/RunCMake/CPack/tests/INSTALL_SCRIPTS/VerifyResult.cmake
+++ b/Tests/RunCMake/CPack/tests/INSTALL_SCRIPTS/VerifyResult.cmake
@@ -25,5 +25,5 @@
   endforeach()
 endfunction()
 
-checkScripts_("${FOUND_FILE_1}" "echo \"pre install foo\";echo \"post install foo\";echo \"pre uninstall foo\";echo \"post uninstall foo\"")
-checkScripts_("${FOUND_FILE_2}" "echo \"pre install\";echo \"post install\";echo \"pre uninstall\";echo \"post uninstall\"")
+checkScripts_("${FOUND_FILE_1}" "echo \"pre install foo\";echo \"post install foo\";echo \"pre uninstall foo\";echo \"post uninstall foo\";echo \"pre trans foo\";echo \"post trans foo\"")
+checkScripts_("${FOUND_FILE_2}" "echo \"pre install\";echo \"post install\";echo \"pre uninstall\";echo \"post uninstall\";echo \"pre trans\";echo \"post trans\"")
diff --git a/Tests/RunCMake/CPack/tests/INSTALL_SCRIPTS/test.cmake b/Tests/RunCMake/CPack/tests/INSTALL_SCRIPTS/test.cmake
index fb1b8de..c200fa5 100644
--- a/Tests/RunCMake/CPack/tests/INSTALL_SCRIPTS/test.cmake
+++ b/Tests/RunCMake/CPack/tests/INSTALL_SCRIPTS/test.cmake
@@ -7,6 +7,10 @@
     "${CMAKE_CURRENT_BINARY_DIR}/pre_uninstall.sh")
   set(CPACK_RPM_POST_UNINSTALL_SCRIPT_FILE
     "${CMAKE_CURRENT_BINARY_DIR}/post_uninstall.sh")
+  set(CPACK_RPM_PRE_TRANS_SCRIPT_FILE
+    "${CMAKE_CURRENT_BINARY_DIR}/pre_trans.sh")
+  set(CPACK_RPM_POST_TRANS_SCRIPT_FILE
+    "${CMAKE_CURRENT_BINARY_DIR}/post_trans.sh")
 
   set(CPACK_RPM_foo_PRE_INSTALL_SCRIPT_FILE
     "${CMAKE_CURRENT_BINARY_DIR}/pre_install_foo.sh")
@@ -16,6 +20,10 @@
     "${CMAKE_CURRENT_BINARY_DIR}/pre_uninstall_foo.sh")
   set(CPACK_RPM_foo_POST_UNINSTALL_SCRIPT_FILE
     "${CMAKE_CURRENT_BINARY_DIR}/post_uninstall_foo.sh")
+  set(CPACK_RPM_foo_PRE_TRANS_SCRIPT_FILE
+    "${CMAKE_CURRENT_BINARY_DIR}/pre_trans_foo.sh")
+  set(CPACK_RPM_foo_POST_TRANS_SCRIPT_FILE
+    "${CMAKE_CURRENT_BINARY_DIR}/post_trans_foo.sh")
 endif()
 
 set(CMAKE_BUILD_WITH_INSTALL_RPATH 1)
@@ -29,6 +37,10 @@
     "echo \"pre uninstall\"\n")
 file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/post_uninstall.sh"
     "echo \"post uninstall\"\n")
+file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/pre_trans.sh"
+    "echo \"pre trans\"\n")
+file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/post_trans.sh"
+    "echo \"post trans\"\n")
 
 # specific
 file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/pre_install_foo.sh"
@@ -39,6 +51,10 @@
     "echo \"pre uninstall foo\"\n")
 file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/post_uninstall_foo.sh"
     "echo \"post uninstall foo\"\n")
+file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/pre_trans_foo.sh"
+    "echo \"pre trans foo\"\n")
+file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/post_trans_foo.sh"
+    "echo \"post trans foo\"\n")
 
 install(FILES CMakeLists.txt DESTINATION foo COMPONENT foo)
 install(FILES CMakeLists.txt DESTINATION bar COMPONENT bar)
diff --git a/Tests/RunCMake/CPack/tests/PRE_POST_SCRIPTS/ExpectedFiles.cmake b/Tests/RunCMake/CPack/tests/PRE_POST_SCRIPTS/ExpectedFiles.cmake
new file mode 100644
index 0000000..63a36a3
--- /dev/null
+++ b/Tests/RunCMake/CPack/tests/PRE_POST_SCRIPTS/ExpectedFiles.cmake
@@ -0,0 +1,19 @@
+set(SATU "/satu;/satu/CMakeLists.txt")
+set(DUA "/dua;/dua/CMakeLists.txt")
+
+if(GENERATOR_TYPE STREQUAL ZIP)
+    set(_ext "zip")
+elseif(GENERATOR_TYPE STREQUAL TGZ)
+    set(_ext "tar.gz")
+endif()
+
+if(PACKAGING_TYPE STREQUAL "COMPONENT")
+    set(EXPECTED_FILES_COUNT "2")
+    set(EXPECTED_FILE_1 "*-satu.${_ext}")
+    set(EXPECTED_FILE_CONTENT_1_LIST ${SATU})
+    set(EXPECTED_FILE_2 "*-dua.${_ext}")
+    set(EXPECTED_FILE_CONTENT_2_LIST ${DUA})
+else()
+    set(EXPECTED_FILES_COUNT "1")
+    set(EXPECTED_FILE_CONTENT_1_LIST ${SATU} ${DUA})
+endif()
diff --git a/Tests/RunCMake/CPack/tests/PRE_POST_SCRIPTS/ZIP_COMPONENT-stdout.txt b/Tests/RunCMake/CPack/tests/PRE_POST_SCRIPTS/ZIP_COMPONENT-stdout.txt
new file mode 100644
index 0000000..319d0da
--- /dev/null
+++ b/Tests/RunCMake/CPack/tests/PRE_POST_SCRIPTS/ZIP_COMPONENT-stdout.txt
@@ -0,0 +1,4 @@
+-- The message from .*/Tests/RunCMake/CPack/tests/PRE_POST_SCRIPTS/pre\.cmake and generator ZIP
+.*
+-- The message from .*/Tests/RunCMake/CPack/tests/PRE_POST_SCRIPTS/post\.cmake and generator ZIP
+-- Built packages: .*/_CPack_Packages/.*/pre_post_scripts-.*-dua.zip;.*/_CPack_Packages/.*/pre_post_scripts-.*-satu.zip
diff --git a/Tests/RunCMake/CPack/tests/PRE_POST_SCRIPTS/ZIP_MONOLITHIC-stdout.txt b/Tests/RunCMake/CPack/tests/PRE_POST_SCRIPTS/ZIP_MONOLITHIC-stdout.txt
new file mode 100644
index 0000000..632c4d1
--- /dev/null
+++ b/Tests/RunCMake/CPack/tests/PRE_POST_SCRIPTS/ZIP_MONOLITHIC-stdout.txt
@@ -0,0 +1,4 @@
+-- The message from .*/Tests/RunCMake/CPack/tests/PRE_POST_SCRIPTS/pre\.cmake and generator ZIP
+.*
+-- The message from .*/Tests/RunCMake/CPack/tests/PRE_POST_SCRIPTS/post\.cmake and generator ZIP
+-- Built packages: .*/_CPack_Packages/.*/pre_post_scripts-0\.1\.1-.*\.zip
diff --git a/Tests/RunCMake/CPack/tests/PRE_POST_SCRIPTS/post.cmake b/Tests/RunCMake/CPack/tests/PRE_POST_SCRIPTS/post.cmake
new file mode 100644
index 0000000..cf0b149
--- /dev/null
+++ b/Tests/RunCMake/CPack/tests/PRE_POST_SCRIPTS/post.cmake
@@ -0,0 +1,2 @@
+message(STATUS "The message from ${CMAKE_CURRENT_LIST_FILE} and generator ${CPACK_GENERATOR}")
+message(STATUS "Built packages: ${CPACK_PACKAGE_FILES}")
diff --git a/Tests/RunCMake/CPack/tests/PRE_POST_SCRIPTS/pre.cmake b/Tests/RunCMake/CPack/tests/PRE_POST_SCRIPTS/pre.cmake
new file mode 100644
index 0000000..b04aa6b
--- /dev/null
+++ b/Tests/RunCMake/CPack/tests/PRE_POST_SCRIPTS/pre.cmake
@@ -0,0 +1 @@
+message(STATUS "The message from ${CMAKE_CURRENT_LIST_FILE} and generator ${CPACK_GENERATOR}")
diff --git a/Tests/RunCMake/CPack/tests/PRE_POST_SCRIPTS/test.cmake b/Tests/RunCMake/CPack/tests/PRE_POST_SCRIPTS/test.cmake
new file mode 100644
index 0000000..f1b6d5f
--- /dev/null
+++ b/Tests/RunCMake/CPack/tests/PRE_POST_SCRIPTS/test.cmake
@@ -0,0 +1,9 @@
+install(FILES CMakeLists.txt DESTINATION satu COMPONENT satu)
+install(FILES CMakeLists.txt DESTINATION dua COMPONENT dua)
+
+set(CPACK_PRE_BUILD_SCRIPTS "${CMAKE_CURRENT_LIST_DIR}/pre.cmake")
+set(CPACK_POST_BUILD_SCRIPTS "${CMAKE_CURRENT_LIST_DIR}/post.cmake")
+
+if(PACKAGING_TYPE STREQUAL "COMPONENT")
+  set(CPACK_COMPONENTS_ALL satu dua)
+endif()
diff --git a/Tests/RunCMake/CPack/tests/PROJECT_META/VerifyResult.cmake b/Tests/RunCMake/CPack/tests/PROJECT_META/VerifyResult.cmake
index b3accb5..35a93d6 100644
--- a/Tests/RunCMake/CPack/tests/PROJECT_META/VerifyResult.cmake
+++ b/Tests/RunCMake/CPack/tests/PROJECT_META/VerifyResult.cmake
@@ -13,7 +13,7 @@
     endif()
   endforeach()
   if(NOT _seen_url)
-    message(FATAL_ERROR "The packge `${FILE}` do not have URL as expected")
+    message(FATAL_ERROR "The package `${FILE}` do not have URL as expected")
   endif()
 endfunction()
 
diff --git a/Tests/RunCMake/CPack/tests/THREADED/ExpectedFiles.cmake b/Tests/RunCMake/CPack/tests/THREADED/ExpectedFiles.cmake
new file mode 100644
index 0000000..d1a3a5f
--- /dev/null
+++ b/Tests/RunCMake/CPack/tests/THREADED/ExpectedFiles.cmake
@@ -0,0 +1,2 @@
+set(EXPECTED_FILES_COUNT "1")
+set(EXPECTED_FILE_CONTENT_1_LIST "/foo;/foo/CMakeLists.txt")
diff --git a/Tests/RunCMake/CPack/tests/THREADED/test.cmake b/Tests/RunCMake/CPack/tests/THREADED/test.cmake
new file mode 100644
index 0000000..78fc9e9
--- /dev/null
+++ b/Tests/RunCMake/CPack/tests/THREADED/test.cmake
@@ -0,0 +1,7 @@
+install(FILES CMakeLists.txt DESTINATION foo COMPONENT test)
+
+set(CPACK_ARCHIVE_THREADS 2)
+
+if(PACKAGING_TYPE STREQUAL "COMPONENT")
+  set(CPACK_COMPONENTS_ALL test)
+endif()
diff --git a/Tests/RunCMake/CPack/tests/THREADED_ALL/ExpectedFiles.cmake b/Tests/RunCMake/CPack/tests/THREADED_ALL/ExpectedFiles.cmake
new file mode 100644
index 0000000..d1a3a5f
--- /dev/null
+++ b/Tests/RunCMake/CPack/tests/THREADED_ALL/ExpectedFiles.cmake
@@ -0,0 +1,2 @@
+set(EXPECTED_FILES_COUNT "1")
+set(EXPECTED_FILE_CONTENT_1_LIST "/foo;/foo/CMakeLists.txt")
diff --git a/Tests/RunCMake/CPack/tests/THREADED_ALL/test.cmake b/Tests/RunCMake/CPack/tests/THREADED_ALL/test.cmake
new file mode 100644
index 0000000..34051b8
--- /dev/null
+++ b/Tests/RunCMake/CPack/tests/THREADED_ALL/test.cmake
@@ -0,0 +1,7 @@
+install(FILES CMakeLists.txt DESTINATION foo COMPONENT test)
+
+set(CPACK_ARCHIVE_THREADS 0)
+
+if(PACKAGING_TYPE STREQUAL "COMPONENT")
+  set(CPACK_COMPONENTS_ALL test)
+endif()
diff --git a/Tests/RunCMake/CTest/CMakeLists.txt b/Tests/RunCMake/CTest/CMakeLists.txt
index 73e6a78..f1a83e8 100644
--- a/Tests/RunCMake/CTest/CMakeLists.txt
+++ b/Tests/RunCMake/CTest/CMakeLists.txt
@@ -1,4 +1,4 @@
-cmake_minimum_required(VERSION 2.8.4)
+cmake_minimum_required(VERSION 3.3)
 if(NOT NoProject)
   project(${RunCMake_TEST} NONE)
 endif()
diff --git a/Tests/RunCMake/CTestCommandLine/MemCheckSan.cmake b/Tests/RunCMake/CTestCommandLine/MemCheckSan.cmake
new file mode 100644
index 0000000..192c30c
--- /dev/null
+++ b/Tests/RunCMake/CTestCommandLine/MemCheckSan.cmake
@@ -0,0 +1,7 @@
+set(MEMORYCHECK_COMMAND "")
+include(CTest)
+add_test(
+  NAME TestSan
+  COMMAND ${CMAKE_COMMAND}
+    -P ${CMAKE_CURRENT_LIST_DIR}/../ctest_memcheck/test${MEMORYCHECK_TYPE}.cmake
+  )
diff --git a/Tests/RunCMake/CTestCommandLine/RunCMakeTest.cmake b/Tests/RunCMake/CTestCommandLine/RunCMakeTest.cmake
index 9b9ae65..e05ad79 100644
--- a/Tests/RunCMake/CTestCommandLine/RunCMakeTest.cmake
+++ b/Tests/RunCMake/CTestCommandLine/RunCMakeTest.cmake
@@ -242,6 +242,20 @@
 endfunction()
 run_TestOutputSize()
 
+# Test --stop-on-failure
+function(run_stop_on_failure)
+  set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/stop-on-failure)
+  set(RunCMake_TEST_NO_CLEAN 1)
+  file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}")
+  file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}")
+  file(WRITE "${RunCMake_TEST_BINARY_DIR}/CTestTestfile.cmake" "
+add_test(test1 \"${CMAKE_COMMAND}\" -E false)
+add_test(test2 \"${CMAKE_COMMAND}\" -E echo \"not running\")
+")
+  run_cmake_command(stop-on-failure ${CMAKE_CTEST_COMMAND} --stop-on-failure)
+endfunction()
+run_stop_on_failure()
+
 function(run_TestAffinity)
   set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/TestAffinity)
   set(RunCMake_TEST_NO_CLEAN 1)
@@ -345,3 +359,24 @@
 
 # Check the configuration type variable is passed
 run_ctest(check-configuration-type)
+
+function(run_MemCheckSan case opts)
+  # Use a single build tree for a few tests without cleaning.
+  set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/MemCheckSan${case}-build)
+  set(RunCMake_TEST_OPTIONS
+    "-DMEMORYCHECK_TYPE=${case}Sanitizer"
+    "-DMEMORYCHECK_SANITIZER_OPTIONS=${opts}"
+    )
+  run_cmake(MemCheckSan)
+  unset(RunCMake_TEST_OPTIONS)
+  set(RunCMake_TEST_NO_CLEAN 1)
+  set(RunCMake-stdout-file "../ctest_memcheck/Dummy${case}Sanitizer-stdout.txt")
+  run_cmake_command(MemCheckSan${case}-ctest
+    ${CMAKE_CTEST_COMMAND} -C Debug -M Experimental -T MemCheck -V
+    )
+endfunction()
+run_MemCheckSan(Address "simulate_sanitizer=1:report_bugs=1:history_size=5:exitcode=55")
+run_MemCheckSan(Leak "simulate_sanitizer=1:report_bugs=1:history_size=5:exitcode=55")
+run_MemCheckSan(Memory "simulate_sanitizer=1:report_bugs=1:history_size=5:exitcode=55")
+run_MemCheckSan(Thread "report_bugs=1:history_size=5:exitcode=55")
+run_MemCheckSan(UndefinedBehavior "simulate_sanitizer=1")
diff --git a/Tests/RunCMake/CTestCommandLine/stop-on-failure-result.txt b/Tests/RunCMake/CTestCommandLine/stop-on-failure-result.txt
new file mode 100644
index 0000000..45a4fb7
--- /dev/null
+++ b/Tests/RunCMake/CTestCommandLine/stop-on-failure-result.txt
@@ -0,0 +1 @@
+8
diff --git a/Tests/RunCMake/CTestCommandLine/stop-on-failure-stderr.txt b/Tests/RunCMake/CTestCommandLine/stop-on-failure-stderr.txt
new file mode 100644
index 0000000..ba4235d
--- /dev/null
+++ b/Tests/RunCMake/CTestCommandLine/stop-on-failure-stderr.txt
@@ -0,0 +1 @@
+Errors while running CTest
diff --git a/Tests/RunCMake/CTestCommandLine/stop-on-failure-stdout.txt b/Tests/RunCMake/CTestCommandLine/stop-on-failure-stdout.txt
new file mode 100644
index 0000000..12c77d0
--- /dev/null
+++ b/Tests/RunCMake/CTestCommandLine/stop-on-failure-stdout.txt
@@ -0,0 +1,10 @@
+^Test project .*/Tests/RunCMake/CTestCommandLine/stop-on-failure
+    Start 1: test1
+1/2 Test #1: test1 ............................\*\*\*Failed +[0-9.]+ sec
++
+0% tests passed, 1 tests failed out of 1
++
+Total Test time \(real\) = +[0-9.]+ sec
++
+The following tests FAILED:
+[	 ]+1 - test1 \(Failed\)$
diff --git a/Tests/RunCMake/CTestResourceAllocation/RunCMakeTest.cmake b/Tests/RunCMake/CTestResourceAllocation/RunCMakeTest.cmake
index 8584786..f5f0699 100644
--- a/Tests/RunCMake/CTestResourceAllocation/RunCMakeTest.cmake
+++ b/Tests/RunCMake/CTestResourceAllocation/RunCMakeTest.cmake
@@ -38,6 +38,13 @@
   run_cmake_command(${name} "${CTRESALLOC_COMMAND}" verify "${RunCMake_SOURCE_DIR}/${name}.log" "${CMAKE_CURRENT_LIST_DIR}/resspec.json" "${tests}")
 endfunction()
 
+function(read_testing_file filename variable)
+  file(READ "${RunCMake_TEST_BINARY_DIR}/Testing/TAG" _tag)
+  string(REGEX REPLACE "^([^\n]*)\n.*$" "\\1" _date "${_tag}")
+  file(READ "${RunCMake_TEST_BINARY_DIR}/Testing/${_date}/${filename}" _contents)
+  set("${variable}" "${_contents}" PARENT_SCOPE)
+endfunction()
+
 unset(ENV{CTEST_RESOURCE_GROUP_COUNT})
 set(RunCMake_TEST_NO_CLEAN 1)
 file(REMOVE_RECURSE "${RunCMake_BINARY_DIR}/ctresalloc-write-proc-good1-build")
@@ -140,9 +147,14 @@
 # Now test the resource allocation feature of CTest
 ###############################################################################
 
-function(run_ctest_resource name parallel random)
-  run_ctest("${name}-ctest-s-res" "-DCTEST_RESOURCE_ALLOC_ENABLED=1" "-DCTRESALLOC_COMMAND=${CTRESALLOC_COMMAND}" "-DCTEST_PARALLEL=${parallel}" "-DCTEST_RANDOM=${random}")
-  run_ctest("${name}-ctest-s-nores" "-DCTEST_RESOURCE_ALLOC_ENABLED=0" "-DCTRESALLOC_COMMAND=${CTRESALLOC_COMMAND}" "-DCTEST_PARALLEL=${parallel}" "-DCTEST_RANDOM=${random}")
+function(run_ctest_resource name parallel random extra)
+  run_ctest("${name}-ctest-s-res" "-DCTEST_RESOURCE_ALLOC_ENABLED=1" "-DCTEST_RESOURCE_SPEC_SOURCE=ARG" "-DCTRESALLOC_COMMAND=${CTRESALLOC_COMMAND}" "-DCTEST_PARALLEL=${parallel}" "-DCTEST_RANDOM=${random}")
+  run_ctest("${name}-ctest-s-nores" "-DCTEST_RESOURCE_ALLOC_ENABLED=0" "-DCTEST_RESOURCE_SPEC_SOURCE=NONE" "-DCTRESALLOC_COMMAND=${CTRESALLOC_COMMAND}" "-DCTEST_PARALLEL=${parallel}" "-DCTEST_RANDOM=${random}")
+  if(extra)
+    run_ctest("${name}-ctest-s-res-variable" "-DCTEST_RESOURCE_ALLOC_ENABLED=1" "-DCTEST_RESOURCE_SPEC_SOURCE=VARIABLE" "-DCTRESALLOC_COMMAND=${CTRESALLOC_COMMAND}" "-DCTEST_PARALLEL=${parallel}" "-DCTEST_RANDOM=${random}")
+    run_ctest("${name}-ctest-s-res-cache" "-DCTEST_RESOURCE_ALLOC_ENABLED=1" "-DCTEST_RESOURCE_SPEC_SOURCE=CACHE" "-DCTRESALLOC_COMMAND=${CTRESALLOC_COMMAND}" "-DCTEST_PARALLEL=${parallel}" "-DCTEST_RANDOM=${random}")
+    run_ctest("${name}-ctest-s-res-cmdline" "-DCTEST_RESOURCE_ALLOC_ENABLED=1" "-DCTEST_RESOURCE_SPEC_SOURCE=CMDLINE" "-DCTRESALLOC_COMMAND=${CTRESALLOC_COMMAND}" "-DCTEST_PARALLEL=${parallel}" "-DCTEST_RANDOM=${random}" --resource-spec-file "${RunCMake_SOURCE_DIR}/resspec.json")
+  endif()
 endfunction()
 
 function(verify_ctest_resources)
@@ -155,15 +167,15 @@
   endif()
 endfunction()
 
-run_ctest_resource(lotsoftests 10 1)
-run_ctest_resource(checkfree1 2 0)
-run_ctest_resource(checkfree2 1 0)
-run_ctest_resource(notenough1 1 0)
-run_ctest_resource(notenough2 1 0)
-run_ctest_resource(notenough3 1 0)
-run_ctest_resource(combine 1 0)
-run_ctest_resource(ensure_parallel 2 0)
+run_ctest_resource(lotsoftests 10 1 0)
+run_ctest_resource(checkfree1 2 0 1)
+run_ctest_resource(checkfree2 1 0 0)
+run_ctest_resource(notenough1 1 0 1)
+run_ctest_resource(notenough2 1 0 0)
+run_ctest_resource(notenough3 1 0 0)
+run_ctest_resource(combine 1 0 0)
+run_ctest_resource(ensure_parallel 2 0 0)
 
 set(ENV{CTEST_RESOURCE_GROUP_COUNT} 2)
-run_ctest_resource(process_count 1 0)
+run_ctest_resource(process_count 1 0 0)
 unset(ENV{CTEST_RESOURCE_GROUP_COUNT})
diff --git a/Tests/RunCMake/CTestResourceAllocation/checkfree1-ctest-s-res-cache-check.cmake b/Tests/RunCMake/CTestResourceAllocation/checkfree1-ctest-s-res-cache-check.cmake
new file mode 100644
index 0000000..ceda72e
--- /dev/null
+++ b/Tests/RunCMake/CTestResourceAllocation/checkfree1-ctest-s-res-cache-check.cmake
@@ -0,0 +1 @@
+verify_ctest_resources()
diff --git a/Tests/RunCMake/CTestResourceAllocation/checkfree1-ctest-s-res-cmdline-check.cmake b/Tests/RunCMake/CTestResourceAllocation/checkfree1-ctest-s-res-cmdline-check.cmake
new file mode 100644
index 0000000..ceda72e
--- /dev/null
+++ b/Tests/RunCMake/CTestResourceAllocation/checkfree1-ctest-s-res-cmdline-check.cmake
@@ -0,0 +1 @@
+verify_ctest_resources()
diff --git a/Tests/RunCMake/CTestResourceAllocation/checkfree1-ctest-s-res-variable-check.cmake b/Tests/RunCMake/CTestResourceAllocation/checkfree1-ctest-s-res-variable-check.cmake
new file mode 100644
index 0000000..ceda72e
--- /dev/null
+++ b/Tests/RunCMake/CTestResourceAllocation/checkfree1-ctest-s-res-variable-check.cmake
@@ -0,0 +1 @@
+verify_ctest_resources()
diff --git a/Tests/RunCMake/CTestResourceAllocation/ctresalloc.cxx b/Tests/RunCMake/CTestResourceAllocation/ctresalloc.cxx
index 80db05e..daf8a2d 100644
--- a/Tests/RunCMake/CTestResourceAllocation/ctresalloc.cxx
+++ b/Tests/RunCMake/CTestResourceAllocation/ctresalloc.cxx
@@ -1,6 +1,6 @@
 #include <cassert>
 #include <chrono>
-#include <cstddef>
+#include <cstddef> // IWYU pragma: keep
 #include <cstdlib>
 #include <iostream>
 #include <map>
diff --git a/Tests/RunCMake/CTestResourceAllocation/notenough1-ctest-s-res-cache-check.cmake b/Tests/RunCMake/CTestResourceAllocation/notenough1-ctest-s-res-cache-check.cmake
new file mode 100644
index 0000000..321e9a2
--- /dev/null
+++ b/Tests/RunCMake/CTestResourceAllocation/notenough1-ctest-s-res-cache-check.cmake
@@ -0,0 +1,3 @@
+if(EXISTS "${RunCMake_TEST_BINARY_DIR}/ctresalloc.log")
+  set(RunCMake_TEST_FAILED "ctresalloc.log should not exist")
+endif()
diff --git a/Tests/RunCMake/CTestResourceAllocation/notenough1-ctest-s-res-cache-result.txt b/Tests/RunCMake/CTestResourceAllocation/notenough1-ctest-s-res-cache-result.txt
new file mode 100644
index 0000000..b57e2de
--- /dev/null
+++ b/Tests/RunCMake/CTestResourceAllocation/notenough1-ctest-s-res-cache-result.txt
@@ -0,0 +1 @@
+(-1|255)
diff --git a/Tests/RunCMake/CTestResourceAllocation/notenough1-ctest-s-res-cache-stderr.txt b/Tests/RunCMake/CTestResourceAllocation/notenough1-ctest-s-res-cache-stderr.txt
new file mode 100644
index 0000000..521a34b
--- /dev/null
+++ b/Tests/RunCMake/CTestResourceAllocation/notenough1-ctest-s-res-cache-stderr.txt
@@ -0,0 +1,14 @@
+^Insufficient resources for test Test1:
+
+  Test requested resources of type 'fluxcapacitors' in the following amounts:
+    200 slots
+  but only the following units were available:
+    'outatime': 121 slots
+
+Resource spec file:
+
+  [^
+]*/Tests/RunCMake/CTestResourceAllocation/resspec.json
+CMake Error at [^
+]*/Tests/RunCMake/CTestResourceAllocation/notenough1-ctest-s-res-cache/test\.cmake:[0-9]+ \(message\):
+  Tests did not pass$
diff --git a/Tests/RunCMake/CTestResourceAllocation/notenough1-ctest-s-res-cmdline-check.cmake b/Tests/RunCMake/CTestResourceAllocation/notenough1-ctest-s-res-cmdline-check.cmake
new file mode 100644
index 0000000..321e9a2
--- /dev/null
+++ b/Tests/RunCMake/CTestResourceAllocation/notenough1-ctest-s-res-cmdline-check.cmake
@@ -0,0 +1,3 @@
+if(EXISTS "${RunCMake_TEST_BINARY_DIR}/ctresalloc.log")
+  set(RunCMake_TEST_FAILED "ctresalloc.log should not exist")
+endif()
diff --git a/Tests/RunCMake/CTestResourceAllocation/notenough1-ctest-s-res-cmdline-result.txt b/Tests/RunCMake/CTestResourceAllocation/notenough1-ctest-s-res-cmdline-result.txt
new file mode 100644
index 0000000..b57e2de
--- /dev/null
+++ b/Tests/RunCMake/CTestResourceAllocation/notenough1-ctest-s-res-cmdline-result.txt
@@ -0,0 +1 @@
+(-1|255)
diff --git a/Tests/RunCMake/CTestResourceAllocation/notenough1-ctest-s-res-cmdline-stderr.txt b/Tests/RunCMake/CTestResourceAllocation/notenough1-ctest-s-res-cmdline-stderr.txt
new file mode 100644
index 0000000..c6f9cfc
--- /dev/null
+++ b/Tests/RunCMake/CTestResourceAllocation/notenough1-ctest-s-res-cmdline-stderr.txt
@@ -0,0 +1,14 @@
+^Insufficient resources for test Test1:
+
+  Test requested resources of type 'fluxcapacitors' in the following amounts:
+    200 slots
+  but only the following units were available:
+    'outatime': 121 slots
+
+Resource spec file:
+
+  [^
+]*/Tests/RunCMake/CTestResourceAllocation/resspec.json
+CMake Error at [^
+]*/Tests/RunCMake/CTestResourceAllocation/notenough1-ctest-s-res-cmdline/test\.cmake:[0-9]+ \(message\):
+  Tests did not pass$
diff --git a/Tests/RunCMake/CTestResourceAllocation/notenough1-ctest-s-res-variable-check.cmake b/Tests/RunCMake/CTestResourceAllocation/notenough1-ctest-s-res-variable-check.cmake
new file mode 100644
index 0000000..321e9a2
--- /dev/null
+++ b/Tests/RunCMake/CTestResourceAllocation/notenough1-ctest-s-res-variable-check.cmake
@@ -0,0 +1,3 @@
+if(EXISTS "${RunCMake_TEST_BINARY_DIR}/ctresalloc.log")
+  set(RunCMake_TEST_FAILED "ctresalloc.log should not exist")
+endif()
diff --git a/Tests/RunCMake/CTestResourceAllocation/notenough1-ctest-s-res-variable-result.txt b/Tests/RunCMake/CTestResourceAllocation/notenough1-ctest-s-res-variable-result.txt
new file mode 100644
index 0000000..b57e2de
--- /dev/null
+++ b/Tests/RunCMake/CTestResourceAllocation/notenough1-ctest-s-res-variable-result.txt
@@ -0,0 +1 @@
+(-1|255)
diff --git a/Tests/RunCMake/CTestResourceAllocation/notenough1-ctest-s-res-variable-stderr.txt b/Tests/RunCMake/CTestResourceAllocation/notenough1-ctest-s-res-variable-stderr.txt
new file mode 100644
index 0000000..dcf13e0
--- /dev/null
+++ b/Tests/RunCMake/CTestResourceAllocation/notenough1-ctest-s-res-variable-stderr.txt
@@ -0,0 +1,14 @@
+^Insufficient resources for test Test1:
+
+  Test requested resources of type 'fluxcapacitors' in the following amounts:
+    200 slots
+  but only the following units were available:
+    'outatime': 121 slots
+
+Resource spec file:
+
+  [^
+]*/Tests/RunCMake/CTestResourceAllocation/resspec.json
+CMake Error at [^
+]*/Tests/RunCMake/CTestResourceAllocation/notenough1-ctest-s-res-variable/test\.cmake:[0-9]+ \(message\):
+  Tests did not pass$
diff --git a/Tests/RunCMake/CTestResourceAllocation/process_count-ctest-s-nores-check.cmake b/Tests/RunCMake/CTestResourceAllocation/process_count-ctest-s-nores-check.cmake
new file mode 100644
index 0000000..c6e72bd
--- /dev/null
+++ b/Tests/RunCMake/CTestResourceAllocation/process_count-ctest-s-nores-check.cmake
@@ -0,0 +1,4 @@
+read_testing_file("Test.xml" _test_contents)
+if(NOT _test_contents MATCHES "#CTEST_RESOURCE_GROUP_COUNT=")
+  string(APPEND RunCMake_TEST_FAILED "Could not find unset variable CTEST_RESOURCE_GROUP_COUNT in test measurements\n")
+endif()
diff --git a/Tests/RunCMake/CTestResourceAllocation/process_count-ctest-s-res-check.cmake b/Tests/RunCMake/CTestResourceAllocation/process_count-ctest-s-res-check.cmake
index ceda72e..585c36b 100644
--- a/Tests/RunCMake/CTestResourceAllocation/process_count-ctest-s-res-check.cmake
+++ b/Tests/RunCMake/CTestResourceAllocation/process_count-ctest-s-res-check.cmake
@@ -1 +1,9 @@
 verify_ctest_resources()
+
+read_testing_file("Test.xml" _test_contents)
+if(NOT _test_contents MATCHES "\nCTEST_RESOURCE_GROUP_0=widgets")
+  string(APPEND RunCMake_TEST_FAILED "Could not find variable CTEST_RESOURCE_GROUP_0 in test measurements\n")
+endif()
+if(NOT _test_contents MATCHES "\nCTEST_RESOURCE_GROUP_0_WIDGETS=id:")
+  string(APPEND RunCMake_TEST_FAILED "Could not find variable CTEST_RESOURCE_GROUP_0_WIDGETS in test measurements\n")
+endif()
diff --git a/Tests/RunCMake/CTestResourceAllocation/test.cmake.in b/Tests/RunCMake/CTestResourceAllocation/test.cmake.in
index 4b426f1..9ad9ac8 100644
--- a/Tests/RunCMake/CTestResourceAllocation/test.cmake.in
+++ b/Tests/RunCMake/CTestResourceAllocation/test.cmake.in
@@ -8,15 +8,26 @@
 set(CTEST_BUILD_CONFIGURATION "$ENV{CMAKE_CONFIG_TYPE}")
 set(CTEST_NIGHTLY_START_TIME "01:00:00 UTC")
 
-ctest_start(Experimental QUIET)
-ctest_configure(OPTIONS
+set(config_options
   "-DCTEST_RESOURCE_ALLOC_ENABLED=${CTEST_RESOURCE_ALLOC_ENABLED};-DCTRESALLOC_COMMAND=${CTRESALLOC_COMMAND}"
   )
-ctest_build()
 
-if(CTEST_RESOURCE_ALLOC_ENABLED)
+if(CTEST_RESOURCE_SPEC_SOURCE STREQUAL "CMDLINE")
+  list(APPEND config_options "-DCTEST_RESOURCE_SPEC_FILE=@RunCMake_SOURCE_DIR@/noexist.json")
+elseif(CTEST_RESOURCE_SPEC_SOURCE STREQUAL "ARG")
   set(resspec RESOURCE_SPEC_FILE "@RunCMake_SOURCE_DIR@/resspec.json")
+  set(CTEST_RESOURCE_SPEC_FILE "@RunCMake_SOURCE_DIR@/noexist.json")
+  list(APPEND config_options "-DCTEST_RESOURCE_SPEC_FILE=@RunCMake_SOURCE_DIR@/noexist.json")
+elseif(CTEST_RESOURCE_SPEC_SOURCE STREQUAL "VARIABLE")
+  set(CTEST_RESOURCE_SPEC_FILE "@RunCMake_SOURCE_DIR@/resspec.json")
+  list(APPEND config_options "-DCTEST_RESOURCE_SPEC_FILE=@RunCMake_SOURCE_DIR@/noexist.json")
+elseif(CTEST_RESOURCE_SPEC_SOURCE STREQUAL "CACHE")
+  list(APPEND config_options "-DCTEST_RESOURCE_SPEC_FILE=@RunCMake_SOURCE_DIR@/resspec.json")
 endif()
+
+ctest_start(Experimental QUIET)
+ctest_configure(OPTIONS "${config_options}")
+ctest_build()
 ctest_test(${resspec} RETURN_VALUE retval PARALLEL_LEVEL ${CTEST_PARALLEL} SCHEDULE_RANDOM ${CTEST_RANDOM})
 if(retval)
   message(FATAL_ERROR "Tests did not pass")
diff --git a/Tests/RunCMake/CheckLinkerFlag/CMakeLists.txt b/Tests/RunCMake/CheckLinkerFlag/CMakeLists.txt
new file mode 100644
index 0000000..0421e28
--- /dev/null
+++ b/Tests/RunCMake/CheckLinkerFlag/CMakeLists.txt
@@ -0,0 +1,5 @@
+cmake_minimum_required(VERSION 3.13)
+
+project(${RunCMake_TEST} LANGUAGES NONE)
+
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/CheckLinkerFlag/CheckCLinkerFlag.cmake b/Tests/RunCMake/CheckLinkerFlag/CheckCLinkerFlag.cmake
new file mode 100644
index 0000000..c8e87a4
--- /dev/null
+++ b/Tests/RunCMake/CheckLinkerFlag/CheckCLinkerFlag.cmake
@@ -0,0 +1,3 @@
+
+set (CHECK_LANGUAGE C)
+include ("${CMAKE_CURRENT_SOURCE_DIR}/CheckLinkerFlag.cmake")
diff --git a/Tests/RunCMake/CheckLinkerFlag/CheckCXXLinkerFlag.cmake b/Tests/RunCMake/CheckLinkerFlag/CheckCXXLinkerFlag.cmake
new file mode 100644
index 0000000..4e299b9
--- /dev/null
+++ b/Tests/RunCMake/CheckLinkerFlag/CheckCXXLinkerFlag.cmake
@@ -0,0 +1,3 @@
+
+set (CHECK_LANGUAGE CXX)
+include ("${CMAKE_CURRENT_SOURCE_DIR}/CheckLinkerFlag.cmake")
diff --git a/Tests/RunCMake/CheckLinkerFlag/CheckFortranLinkerFlag.cmake b/Tests/RunCMake/CheckLinkerFlag/CheckFortranLinkerFlag.cmake
new file mode 100644
index 0000000..bca288e
--- /dev/null
+++ b/Tests/RunCMake/CheckLinkerFlag/CheckFortranLinkerFlag.cmake
@@ -0,0 +1,3 @@
+
+set (CHECK_LANGUAGE Fortran)
+include ("${CMAKE_CURRENT_SOURCE_DIR}/CheckLinkerFlag.cmake")
diff --git a/Tests/RunCMake/CheckLinkerFlag/CheckLinkerFlag.cmake b/Tests/RunCMake/CheckLinkerFlag/CheckLinkerFlag.cmake
new file mode 100644
index 0000000..c3bd465
--- /dev/null
+++ b/Tests/RunCMake/CheckLinkerFlag/CheckLinkerFlag.cmake
@@ -0,0 +1,14 @@
+
+enable_language (${CHECK_LANGUAGE})
+
+include(CheckLinkerFlag)
+
+check_linker_flag(${CHECK_LANGUAGE} "LINKER:-L,/dir" VALID_LINKER_FLAG)
+if(NOT VALID_LINKER_FLAG)
+  message(SEND_ERROR "Test fail for valid linker flag.")
+endif()
+
+check_linker_flag(${CHECK_LANGUAGE} "LINKER:-D" INVALID_LINKER_FLAG)
+if(INVALID_LINKER_FLAG)
+  message(SEND_ERROR "Test fail for invalid linker flag.")
+endif()
diff --git a/Tests/RunCMake/CheckLinkerFlag/CheckOBJCLinkerFlag.cmake b/Tests/RunCMake/CheckLinkerFlag/CheckOBJCLinkerFlag.cmake
new file mode 100644
index 0000000..fa1d18e
--- /dev/null
+++ b/Tests/RunCMake/CheckLinkerFlag/CheckOBJCLinkerFlag.cmake
@@ -0,0 +1,3 @@
+
+set (CHECK_LANGUAGE OBJC)
+include ("${CMAKE_CURRENT_SOURCE_DIR}/CheckLinkerFlag.cmake")
diff --git a/Tests/RunCMake/CheckLinkerFlag/CheckOBJCXXLinkerFlag.cmake b/Tests/RunCMake/CheckLinkerFlag/CheckOBJCXXLinkerFlag.cmake
new file mode 100644
index 0000000..414efb8
--- /dev/null
+++ b/Tests/RunCMake/CheckLinkerFlag/CheckOBJCXXLinkerFlag.cmake
@@ -0,0 +1,3 @@
+
+set (CHECK_LANGUAGE OBJCXX)
+include ("${CMAKE_CURRENT_SOURCE_DIR}/CheckLinkerFlag.cmake")
diff --git a/Tests/RunCMake/CheckLinkerFlag/RunCMakeTest.cmake b/Tests/RunCMake/CheckLinkerFlag/RunCMakeTest.cmake
new file mode 100644
index 0000000..224a2a3
--- /dev/null
+++ b/Tests/RunCMake/CheckLinkerFlag/RunCMakeTest.cmake
@@ -0,0 +1,14 @@
+include(RunCMake)
+
+if (CMAKE_C_COMPILER_ID MATCHES "Clang|GNU")
+  run_cmake(CheckCLinkerFlag)
+  run_cmake(CheckCXXLinkerFlag)
+  if (APPLE)
+    run_cmake(CheckOBJCLinkerFlag)
+    run_cmake(CheckOBJCXXLinkerFlag)
+  endif()
+endif()
+
+if (CMAKE_Fortran_COMPILER_ID MATCHES "GNU")
+  run_cmake(CheckFortranLinkerFlag)
+endif()
diff --git a/Tests/RunCMake/CheckModules/CMakeLists.txt b/Tests/RunCMake/CheckModules/CMakeLists.txt
index 9872df2..842c5cf 100644
--- a/Tests/RunCMake/CheckModules/CMakeLists.txt
+++ b/Tests/RunCMake/CheckModules/CMakeLists.txt
@@ -1,4 +1,4 @@
-cmake_minimum_required(VERSION 2.8.11)
+cmake_minimum_required(VERSION 2.8.12)
 cmake_policy(SET CMP0054 NEW)
 project(${RunCMake_TEST} NONE)
 include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/GoogleTest/GoogleTest-discovery-timeout-result.txt b/Tests/RunCMake/CommandLine/BuildDir--build-multiple-targets-fail-result.txt
similarity index 100%
copy from Tests/RunCMake/GoogleTest/GoogleTest-discovery-timeout-result.txt
copy to Tests/RunCMake/CommandLine/BuildDir--build-multiple-targets-fail-result.txt
diff --git a/Tests/RunCMake/CommandLine/BuildDir--build-multiple-targets-fail-stderr.txt b/Tests/RunCMake/CommandLine/BuildDir--build-multiple-targets-fail-stderr.txt
new file mode 100644
index 0000000..8d98f9d
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/BuildDir--build-multiple-targets-fail-stderr.txt
@@ -0,0 +1 @@
+.*
diff --git a/Tests/RunCMake/CommandLine/BuildDir/CMakeLists.txt b/Tests/RunCMake/CommandLine/BuildDir/CMakeLists.txt
index d2a2831..cf2c087 100644
--- a/Tests/RunCMake/CommandLine/BuildDir/CMakeLists.txt
+++ b/Tests/RunCMake/CommandLine/BuildDir/CMakeLists.txt
@@ -5,3 +5,4 @@
 add_custom_target(CustomTarget ALL DEPENDS output.txt)
 add_custom_target(CustomTarget2 ALL DEPENDS output.txt)
 add_custom_target(CustomTarget3 ALL DEPENDS output.txt)
+add_custom_target(CustomTargetFail COMMAND DoesNotExist)
diff --git a/Tests/RunCMake/CommandLine/E_capabilities-stdout.txt b/Tests/RunCMake/CommandLine/E_capabilities-stdout.txt
index b4b170e..e24e131 100644
--- a/Tests/RunCMake/CommandLine/E_capabilities-stdout.txt
+++ b/Tests/RunCMake/CommandLine/E_capabilities-stdout.txt
@@ -1 +1 @@
-^{"fileApi":{"requests":\[{"kind":"codemodel","version":\[{"major":2,"minor":0}]},{"kind":"cache","version":\[{"major":2,"minor":0}]},{"kind":"cmakeFiles","version":\[{"major":1,"minor":0}]}]},"generators":\[.*\],"serverMode":true,"version":{.*}}$
+^{"fileApi":{"requests":\[{"kind":"codemodel","version":\[{"major":2,"minor":2}]},{"kind":"cache","version":\[{"major":2,"minor":0}]},{"kind":"cmakeFiles","version":\[{"major":1,"minor":0}]}]},"generators":\[.*\],"serverMode":true,"version":{.*}}$
diff --git a/Tests/RunCMake/alias_targets/imported-target-result.txt b/Tests/RunCMake/CommandLine/E_cat_directory-result.txt
similarity index 100%
copy from Tests/RunCMake/alias_targets/imported-target-result.txt
copy to Tests/RunCMake/CommandLine/E_cat_directory-result.txt
diff --git a/Tests/RunCMake/CommandLine/E_cat_directory-stderr.txt b/Tests/RunCMake/CommandLine/E_cat_directory-stderr.txt
new file mode 100644
index 0000000..c4d0d48
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/E_cat_directory-stderr.txt
@@ -0,0 +1 @@
+^CMake Error: .* is a directory
diff --git a/Tests/RunCMake/CommandLine/E_cat_good_cat-stdout.txt b/Tests/RunCMake/CommandLine/E_cat_good_cat-stdout.txt
new file mode 100644
index 0000000..aae90e6
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/E_cat_good_cat-stdout.txt
@@ -0,0 +1,3 @@
+first file to append
+second file to append
+àéùç - 한국어
diff --git a/Tests/RunCMake/Languages/LINK_LANGUAGE-genex-result.txt b/Tests/RunCMake/CommandLine/E_cat_non_existing_file-result.txt
similarity index 100%
copy from Tests/RunCMake/Languages/LINK_LANGUAGE-genex-result.txt
copy to Tests/RunCMake/CommandLine/E_cat_non_existing_file-result.txt
diff --git a/Tests/RunCMake/CommandLine/E_cat_non_existing_file-stderr.txt b/Tests/RunCMake/CommandLine/E_cat_non_existing_file-stderr.txt
new file mode 100644
index 0000000..0d8fc4b
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/E_cat_non_existing_file-stderr.txt
@@ -0,0 +1 @@
+^CMake Error: .*: no such file or directory \(ignoring\)
diff --git a/Tests/RunCMake/Languages/LINK_LANGUAGE-genex-result.txt b/Tests/RunCMake/CommandLine/E_cat_non_readable_file-result.txt
similarity index 100%
copy from Tests/RunCMake/Languages/LINK_LANGUAGE-genex-result.txt
copy to Tests/RunCMake/CommandLine/E_cat_non_readable_file-result.txt
diff --git a/Tests/RunCMake/CommandLine/E_cat_non_readable_file-stderr.txt b/Tests/RunCMake/CommandLine/E_cat_non_readable_file-stderr.txt
new file mode 100644
index 0000000..97ec822
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/E_cat_non_readable_file-stderr.txt
@@ -0,0 +1 @@
+^CMake Error: .*: permission denied \(ignoring\)
diff --git a/Tests/RunCMake/Languages/LINK_LANGUAGE-genex-result.txt b/Tests/RunCMake/CommandLine/E_cat_option_not_handled-result.txt
similarity index 100%
copy from Tests/RunCMake/Languages/LINK_LANGUAGE-genex-result.txt
copy to Tests/RunCMake/CommandLine/E_cat_option_not_handled-result.txt
diff --git a/Tests/RunCMake/CommandLine/E_cat_option_not_handled-stderr.txt b/Tests/RunCMake/CommandLine/E_cat_option_not_handled-stderr.txt
new file mode 100644
index 0000000..92f7acf
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/E_cat_option_not_handled-stderr.txt
@@ -0,0 +1 @@
+^CMake Error: -f: option not handled
diff --git a/Tests/RunCMake/CommandLine/E_compare_files-different-eol-stderr.txt b/Tests/RunCMake/CommandLine/E_compare_files-different-eol-stderr.txt
deleted file mode 100644
index 4729ccb..0000000
--- a/Tests/RunCMake/CommandLine/E_compare_files-different-eol-stderr.txt
+++ /dev/null
@@ -1 +0,0 @@
-^Files ".*/compare_files/lf" to ".*/compare_files/crlf" are different.$
diff --git a/Tests/RunCMake/CommandLine/E_compare_files-ignore-eol-nonexistent-stderr.txt b/Tests/RunCMake/CommandLine/E_compare_files-ignore-eol-nonexistent-stderr.txt
deleted file mode 100644
index 8a9ca81..0000000
--- a/Tests/RunCMake/CommandLine/E_compare_files-ignore-eol-nonexistent-stderr.txt
+++ /dev/null
@@ -1 +0,0 @@
-^Files "nonexistent_a" to "nonexistent_b" are different.$
diff --git a/Tests/RunCMake/CommandLine/E_compare_files-invalid-arguments-result.txt b/Tests/RunCMake/CommandLine/E_compare_files-invalid-arguments-result.txt
new file mode 100644
index 0000000..0cfbf08
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/E_compare_files-invalid-arguments-result.txt
@@ -0,0 +1 @@
+2
diff --git a/Tests/RunCMake/CommandLine/E_compare_files-invalid-arguments-stderr.txt b/Tests/RunCMake/CommandLine/E_compare_files-invalid-arguments-stderr.txt
new file mode 100644
index 0000000..8d98f9d
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/E_compare_files-invalid-arguments-stderr.txt
@@ -0,0 +1 @@
+.*
diff --git a/Tests/RunCMake/GeneratorExpression/TARGET_GENEX_EVAL-no-arg-result.txt b/Tests/RunCMake/CommandLine/E_create_hardlink-no-arg-result.txt
similarity index 100%
copy from Tests/RunCMake/GeneratorExpression/TARGET_GENEX_EVAL-no-arg-result.txt
copy to Tests/RunCMake/CommandLine/E_create_hardlink-no-arg-result.txt
diff --git a/Tests/RunCMake/CommandLine/E_create_hardlink-no-arg-stderr.txt b/Tests/RunCMake/CommandLine/E_create_hardlink-no-arg-stderr.txt
new file mode 100644
index 0000000..50d9b03
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/E_create_hardlink-no-arg-stderr.txt
@@ -0,0 +1,3 @@
+^CMake Error: cmake version .*
+Usage: .* -E <command> \[arguments\.\.\.\]
+Available commands:
diff --git a/Tests/RunCMake/Languages/LINK_LANGUAGE-genex-result.txt b/Tests/RunCMake/CommandLine/E_create_hardlink-no-directory-result.txt
similarity index 100%
copy from Tests/RunCMake/Languages/LINK_LANGUAGE-genex-result.txt
copy to Tests/RunCMake/CommandLine/E_create_hardlink-no-directory-result.txt
diff --git a/Tests/RunCMake/CommandLine/E_create_hardlink-no-directory-stderr.txt b/Tests/RunCMake/CommandLine/E_create_hardlink-no-directory-stderr.txt
new file mode 100644
index 0000000..21e60ee
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/E_create_hardlink-no-directory-stderr.txt
@@ -0,0 +1 @@
+^CMake Error: failed to create link .* no such file or directory
diff --git a/Tests/RunCMake/Languages/LINK_LANGUAGE-genex-result.txt b/Tests/RunCMake/CommandLine/E_create_hardlink-non-existent-source-result.txt
similarity index 100%
copy from Tests/RunCMake/Languages/LINK_LANGUAGE-genex-result.txt
copy to Tests/RunCMake/CommandLine/E_create_hardlink-non-existent-source-result.txt
diff --git a/Tests/RunCMake/CommandLine/E_create_hardlink-non-existent-source-stderr.txt b/Tests/RunCMake/CommandLine/E_create_hardlink-non-existent-source-stderr.txt
new file mode 100644
index 0000000..a334571
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/E_create_hardlink-non-existent-source-stderr.txt
@@ -0,0 +1 @@
+^failed to create hard link because source path .* does not exist
diff --git a/Tests/RunCMake/CommandLine/E_create_hardlink-unresolved-symlink-prereq-check.cmake b/Tests/RunCMake/CommandLine/E_create_hardlink-unresolved-symlink-prereq-check.cmake
new file mode 100644
index 0000000..5b97aec
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/E_create_hardlink-unresolved-symlink-prereq-check.cmake
@@ -0,0 +1,3 @@
+if(${actual_stderr_var} MATCHES "operation not permitted")
+  unset(msg)
+endif()
diff --git a/Tests/RunCMake/Languages/LINK_LANGUAGE-genex-result.txt b/Tests/RunCMake/CommandLine/E_create_hardlink-unresolved-symlink-result.txt
similarity index 100%
copy from Tests/RunCMake/Languages/LINK_LANGUAGE-genex-result.txt
copy to Tests/RunCMake/CommandLine/E_create_hardlink-unresolved-symlink-result.txt
diff --git a/Tests/RunCMake/CommandLine/E_create_hardlink-unresolved-symlink-stderr.txt b/Tests/RunCMake/CommandLine/E_create_hardlink-unresolved-symlink-stderr.txt
new file mode 100644
index 0000000..a334571
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/E_create_hardlink-unresolved-symlink-stderr.txt
@@ -0,0 +1 @@
+^failed to create hard link because source path .* does not exist
diff --git a/Tests/RunCMake/CommandLine/P_arbitrary_args.cmake b/Tests/RunCMake/CommandLine/P_arbitrary_args.cmake
new file mode 100644
index 0000000..29faae3
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/P_arbitrary_args.cmake
@@ -0,0 +1,3 @@
+if(NOT ("${CMAKE_ARGV3}" STREQUAL "--" AND "${CMAKE_ARGV4}" STREQUAL "-DFOO"))
+    message(FATAL_ERROR "`-DFOO` shouldn't trigger an error after `--`")
+endif()
diff --git a/Tests/RunCMake/CommandLine/ProfilingTest-check.cmake b/Tests/RunCMake/CommandLine/ProfilingTest-check.cmake
new file mode 100644
index 0000000..2e8eac1
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/ProfilingTest-check.cmake
@@ -0,0 +1,31 @@
+if (NOT EXISTS ${ProfilingTestOutput})
+  set(RunCMake_TEST_FAILED "Expected ${ProfilingTestOutput} to exists")
+endif()
+
+file(READ "${ProfilingTestOutput}" JSON_HEADER LIMIT 2)
+if (NOT JSON_HEADER MATCHES "^\\[{")
+  set(RunCMake_TEST_FAILED "Expected valid JSON start")
+  return()
+endif()
+
+file(SIZE "${ProfilingTestOutput}" OUTPUT_SIZE)
+math(EXPR END_OFFSET "${OUTPUT_SIZE} -2 ")
+
+file(READ "${ProfilingTestOutput}" JSON_TRAILER OFFSET ${END_OFFSET})
+if (NOT JSON_TRAILER MATCHES "^}]$")
+  set(RunCMake_TEST_FAILED "Expected valid JSON end")
+  return()
+endif()
+
+file(STRINGS ${ProfilingTestOutput} upperCaseCommand
+  REGEX [["name"[ ]*:[ ]*"__TESTING_COMMAND_CASE"]])
+if (NOT "${upperCaseCommand}" STREQUAL "")
+  set(RunCMake_TEST_FAILED "Command name not stored in lowercase")
+endif()
+file(STRINGS ${ProfilingTestOutput} lowerCaseCommand
+  REGEX [["name"[ ]*:[ ]*"__testing_command_case"]])
+list(LENGTH lowerCaseCommand numInvocations)
+if (NOT numInvocations EQUAL 1)
+  set(RunCMake_TEST_FAILED
+      "Unexpected number of lowercase command names: ${numInvocations}")
+endif()
diff --git a/Tests/RunCMake/CommandLine/ProfilingTest.cmake b/Tests/RunCMake/CommandLine/ProfilingTest.cmake
new file mode 100644
index 0000000..4cf0c30
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/ProfilingTest.cmake
@@ -0,0 +1,5 @@
+function(__testing_command_case)
+endfunction()
+
+# This must not appear in the profiling output as uppercase
+__TESTING_COMMAND_CASE()
diff --git a/Tests/RunCMake/CommandLine/RunCMakeTest.cmake b/Tests/RunCMake/CommandLine/RunCMakeTest.cmake
index 8930721..2a5d5d3 100644
--- a/Tests/RunCMake/CommandLine/RunCMakeTest.cmake
+++ b/Tests/RunCMake/CommandLine/RunCMakeTest.cmake
@@ -22,6 +22,7 @@
 run_cmake_command(E_compare_files-ignore-eol-same ${CMAKE_COMMAND} -E compare_files --ignore-eol ${RunCMake_SOURCE_DIR}/compare_files/lf ${RunCMake_SOURCE_DIR}/compare_files/crlf)
 run_cmake_command(E_compare_files-ignore-eol-empty ${CMAKE_COMMAND} -E compare_files --ignore-eol ${RunCMake_SOURCE_DIR}/compare_files/empty1 ${RunCMake_SOURCE_DIR}/compare_files/empty2)
 run_cmake_command(E_compare_files-ignore-eol-nonexistent ${CMAKE_COMMAND} -E compare_files --ignore-eol nonexistent_a nonexistent_b)
+run_cmake_command(E_compare_files-invalid-arguments ${CMAKE_COMMAND} -E compare_files file1.txt file2.txt file3.txt)
 run_cmake_command(E_echo_append ${CMAKE_COMMAND} -E echo_append)
 run_cmake_command(E_rename-no-arg ${CMAKE_COMMAND} -E rename)
 run_cmake_command(E_server-arg ${CMAKE_COMMAND} -E server --extra-arg)
@@ -46,6 +47,7 @@
 run_cmake_command(G_bad-arg ${CMAKE_COMMAND} -B DummyBuildDir -G NoSuchGenerator)
 run_cmake_command(P_no-arg ${CMAKE_COMMAND} -P)
 run_cmake_command(P_no-file ${CMAKE_COMMAND} -P nosuchscriptfile.cmake)
+run_cmake_command(P_arbitrary_args ${CMAKE_COMMAND} -P "${RunCMake_SOURCE_DIR}/P_arbitrary_args.cmake" -- -DFOO)
 
 run_cmake_command(build-no-dir
   ${CMAKE_COMMAND} --build)
@@ -65,6 +67,32 @@
 run_cmake_command(install-options-to-vars
   ${CMAKE_COMMAND} --install ${RunCMake_SOURCE_DIR}/dir-install-options-to-vars
   --strip --prefix /var/test --config sample --component pack)
+run_cmake_command(install-default-dir-permissions-all
+  ${CMAKE_COMMAND} --install ${RunCMake_SOURCE_DIR}/dir-permissions-install-options-to-vars
+  --default-directory-permissions u=rwx,g=rx,o=rx)
+run_cmake_command(install-default-dir-permissions-afew
+  ${CMAKE_COMMAND} --install ${RunCMake_SOURCE_DIR}/dir-permissions-install-options-to-vars
+  --default-directory-permissions u=rwx,g=rx)
+run_cmake_command(install-default-dir-permissions-none
+  ${CMAKE_COMMAND} --install ${RunCMake_SOURCE_DIR}/dir-permissions-install-options-to-vars)
+run_cmake_command(install-default-dir-permissions-invalid-comma1
+  ${CMAKE_COMMAND} --install ${RunCMake_SOURCE_DIR}/dir-permissions-install-options-to-vars
+  --default-directory-permissions u=rwxg=,x)
+run_cmake_command(install-default-dir-permissions-invalid-comma2
+  ${CMAKE_COMMAND} --install ${RunCMake_SOURCE_DIR}/dir-permissions-install-options-to-vars
+  --default-directory-permissions u=rwxg,=x)
+run_cmake_command(install-default-dir-permissions-comma-at-the-end
+  ${CMAKE_COMMAND} --install ${RunCMake_SOURCE_DIR}/dir-permissions-install-options-to-vars
+  --default-directory-permissions u=rwx,)
+run_cmake_command(install-default-dir-permissions-invalid-assignment
+  ${CMAKE_COMMAND} --install ${RunCMake_SOURCE_DIR}/dir-permissions-install-options-to-vars
+  --default-directory-permissions u=rwx,=x)
+run_cmake_command(install-default-dir-permissions-assignment-at-the-end
+  ${CMAKE_COMMAND} --install ${RunCMake_SOURCE_DIR}/dir-permissions-install-options-to-vars
+  --default-directory-permissions u=rwx,g=)
+run_cmake_command(install-default-dir-permissions-assignment-at-the-beginning
+  ${CMAKE_COMMAND} --install ${RunCMake_SOURCE_DIR}/dir-permissions-install-options-to-vars
+  --default-directory-permissions =u=rwx,g=rx)
 
 run_cmake_command(cache-bad-entry
   ${CMAKE_COMMAND} --build ${RunCMake_SOURCE_DIR}/cache-bad-entry/)
@@ -133,6 +161,8 @@
     ${CMAKE_COMMAND} --build BuildDir-build --target CustomTarget)
   run_cmake_command(BuildDir--build-multiple-targets ${CMAKE_COMMAND} -E chdir ..
     ${CMAKE_COMMAND} --build BuildDir-build -t CustomTarget2 --target CustomTarget3)
+  run_cmake_command(BuildDir--build-multiple-targets-fail ${CMAKE_COMMAND} -E chdir ..
+    ${CMAKE_COMMAND} --build BuildDir-build -t CustomTargetFail --target CustomTarget3)
   run_cmake_command(BuildDir--build-multiple-targets-jobs ${CMAKE_COMMAND} -E chdir ..
     ${CMAKE_COMMAND} --build BuildDir-build --target CustomTarget CustomTarget2 -j2 --target CustomTarget3)
   run_cmake_command(BuildDir--build-multiple-targets-with-clean-first ${CMAKE_COMMAND} -E chdir ..
@@ -318,6 +348,42 @@
   ${CMAKE_COMMAND} -E create_symlink T .
   )
 
+#create hard link tests
+run_cmake_command(E_create_hardlink-no-arg
+  ${CMAKE_COMMAND} -E create_hardlink
+  )
+
+set(dir ${RunCMake_BINARY_DIR}/hardlink_tests)
+file(REMOVE_RECURSE "${dir}")
+file(MAKE_DIRECTORY ${dir})
+
+run_cmake_command(E_create_hardlink-non-existent-source
+  ${CMAKE_COMMAND} -E create_hardlink ${dir}/I_dont_exist ${dir}/link
+  )
+
+file(TOUCH ${dir}/1)
+
+run_cmake_command(E_create_hardlink-ok
+  ${CMAKE_COMMAND} -E create_hardlink ${dir}/1 ${dir}/1-link
+  )
+
+run_cmake_command(E_create_hardlink-no-directory
+  ${CMAKE_COMMAND} -E create_hardlink ${dir}/1 ${dir}/a/1-link
+  )
+
+#On Windows, if the user does not have sufficient privileges
+#don't fail this test
+set(RunCMake_DEFAULT_stderr "(operation not permitted)?")
+run_cmake_command(E_create_hardlink-unresolved-symlink-prereq
+  ${CMAKE_COMMAND} -E create_symlink ${dir}/1 ${dir}/1-symlink
+  )
+file(REMOVE ${dir}/1)
+
+run_cmake_command(E_create_hardlink-unresolved-symlink
+  ${CMAKE_COMMAND} -E create_hardlink ${dir}/1-symlink ${dir}/1s-link
+  )
+unset(RunCMake_DEFAULT_stderr)
+
 set(in ${RunCMake_SOURCE_DIR}/copy_input)
 set(out ${RunCMake_BINARY_DIR}/copy_output)
 file(REMOVE_RECURSE "${out}")
@@ -459,6 +525,44 @@
 endif()
 unset(out)
 
+# cat tests
+set(out ${RunCMake_BINARY_DIR}/cat_tests)
+file(REMOVE_RECURSE "${out}")
+file(MAKE_DIRECTORY ${out})
+run_cmake_command(E_cat_non_existing_file
+  ${CMAKE_COMMAND} -E cat ${out}/non-existing-file.txt)
+
+if(UNIX)
+  # test non readable file only if not root
+  execute_process(
+    COMMAND id -u $ENV{USER}
+    OUTPUT_VARIABLE uid
+    OUTPUT_STRIP_TRAILING_WHITESPACE)
+
+  if(NOT "${uid}" STREQUAL "0")
+    # Create non readable file
+    set(inside_folder "${out}/in")
+    file(MAKE_DIRECTORY ${inside_folder})
+    file(WRITE "${inside_folder}/non_readable_file.txt" "first file to append\n")
+    file(COPY "${inside_folder}/non_readable_file.txt" DESTINATION "${out}" FILE_PERMISSIONS OWNER_WRITE)
+    run_cmake_command(E_cat_non_readable_file
+      ${CMAKE_COMMAND} -E cat "${out}/non_readable_file.txt")
+  endif()
+endif()
+
+run_cmake_command(E_cat_option_not_handled
+  ${CMAKE_COMMAND} -E cat -f)
+
+run_cmake_command(E_cat_directory
+  ${CMAKE_COMMAND} -E cat ${out})
+
+file(WRITE "${out}/first_file.txt" "first file to append\n")
+file(WRITE "${out}/second_file.txt" "second file to append\n")
+file(WRITE "${out}/unicode_file.txt" "àéùç - 한국어") # Korean in Korean
+run_cmake_command(E_cat_good_cat
+  ${CMAKE_COMMAND} -E cat "${out}/first_file.txt" "${out}/second_file.txt" "${out}/unicode_file.txt")
+unset(out)
+
 run_cmake_command(E_env-no-command0 ${CMAKE_COMMAND} -E env)
 run_cmake_command(E_env-no-command1 ${CMAKE_COMMAND} -E env TEST_ENV=1)
 run_cmake_command(E_env-bad-arg1 ${CMAKE_COMMAND} -E env -bad-arg1)
@@ -675,15 +779,15 @@
   file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}")
   run_cmake_command(llvm_rc_no_args ${CMAKE_COMMAND} -E cmake_llvm_rc)
   run_cmake_command(llvm_rc_no_-- ${CMAKE_COMMAND} -E cmake_llvm_rc ${RunCMake_TEST_BINARY_DIR}/source_file test.tmp ${CMAKE_COMMAND} -E echo "This is a test")
-  run_cmake_command(llvm_rc_empty_preprocessor ${CMAKE_COMMAND} -E cmake_llvm_rc ${RunCMake_TEST_BINARY_DIR}/source_file test.tmp -- ${CMAKE_COMMAND} -E echo "This is a test")
-  run_cmake_command(llvm_rc_failing_first_command ${CMAKE_COMMAND} -E cmake_llvm_rc ${RunCMake_TEST_BINARY_DIR}/source_file test.tmp ${CMAKE_COMMAND} -P FailedProgram.cmake -- ${CMAKE_COMMAND} -E echo "This is a test")
-  run_cmake_command(llvm_rc_failing_second_command ${CMAKE_COMMAND} -E cmake_llvm_rc ${RunCMake_TEST_BINARY_DIR}/source_file test.tmp ${CMAKE_COMMAND} -E echo "This is a test" -- ${CMAKE_COMMAND} -P FailedProgram.cmake )
+  run_cmake_command(llvm_rc_empty_preprocessor ${CMAKE_COMMAND} -E cmake_llvm_rc ${RunCMake_TEST_BINARY_DIR}/source_file test.tmp ++ ${CMAKE_COMMAND} -E echo "This is a test")
+  run_cmake_command(llvm_rc_failing_first_command ${CMAKE_COMMAND} -E cmake_llvm_rc ${RunCMake_TEST_BINARY_DIR}/source_file test.tmp ${CMAKE_COMMAND} -P FailedProgram.cmake ++ ${CMAKE_COMMAND} -E echo "This is a test")
+  run_cmake_command(llvm_rc_failing_second_command ${CMAKE_COMMAND} -E cmake_llvm_rc ${RunCMake_TEST_BINARY_DIR}/source_file test.tmp ${CMAKE_COMMAND} -E echo "This is a test" ++ ${CMAKE_COMMAND} -P FailedProgram.cmake )
   if(EXISTS ${RunCMake_TEST_BINARY_DIR}/test.tmp)
       message(SEND_ERROR "${test} - FAILED:\n"
         "test.tmp was not deleted")
   endif()
   file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}/ExpandSourceDir")
-  run_cmake_command(llvm_rc_full_run ${CMAKE_COMMAND} -E cmake_llvm_rc ${RunCMake_TEST_BINARY_DIR}/ExpandSourceDir/source_file test.tmp ${CMAKE_COMMAND} -E echo "This is a test" -- ${CMAKE_COMMAND} -E copy test.tmp SOURCE_DIR/llvmrc.result )
+  run_cmake_command(llvm_rc_full_run ${CMAKE_COMMAND} -E cmake_llvm_rc ${RunCMake_TEST_BINARY_DIR}/ExpandSourceDir/source_file test.tmp ${CMAKE_COMMAND} -E echo "This is a test" ++ ${CMAKE_COMMAND} -E copy test.tmp SOURCE_DIR/llvmrc.result )
   if(EXISTS ${RunCMake_TEST_BINARY_DIR}/ExpandSourceDir/test.tmp)
       message(SEND_ERROR "${test} - FAILED:\n"
         "test.tmp was not deleted")
@@ -696,3 +800,25 @@
   unset(LLVMRC_RESULT)
 endfunction()
 run_llvm_rc()
+
+set(RunCMake_TEST_OPTIONS --profiling-output=/no/such/file.txt --profiling-format=google-trace)
+run_cmake(profiling-all-params)
+unset(RunCMake_TEST_OPTIONS)
+
+set(RunCMake_TEST_OPTIONS --profiling-output=/no/such/file.txt --profiling-format=invalid-format)
+run_cmake(profiling-invalid-format)
+unset(RunCMake_TEST_OPTIONS)
+
+set(RunCMake_TEST_OPTIONS --profiling-output=/no/such/file.txt)
+run_cmake(profiling-missing-format)
+unset(RunCMake_TEST_OPTIONS)
+
+set(RunCMake_TEST_OPTIONS --profiling-format=google-trace)
+run_cmake(profiling-missing-output)
+unset(RunCMake_TEST_OPTIONS)
+
+set(RunCMake_TEST_BINARY_DIR "${RunCMake_BINARY_DIR}/profiling-test")
+set(ProfilingTestOutput ${RunCMake_TEST_BINARY_DIR}/output.json)
+set(RunCMake_TEST_OPTIONS --profiling-format=google-trace --profiling-output=${ProfilingTestOutput})
+run_cmake(ProfilingTest)
+unset(RunCMake_TEST_OPTIONS)
diff --git a/Tests/RunCMake/CommandLine/cmake_depends/test_UTF-16LE.h b/Tests/RunCMake/CommandLine/cmake_depends/test_UTF-16LE.h
index bf56ec6..2d39178 100644
--- a/Tests/RunCMake/CommandLine/cmake_depends/test_UTF-16LE.h
+++ b/Tests/RunCMake/CommandLine/cmake_depends/test_UTF-16LE.h
Binary files differ
diff --git a/Tests/RunCMake/CommandLine/dir-permissions-install-options-to-vars/cmake_install.cmake b/Tests/RunCMake/CommandLine/dir-permissions-install-options-to-vars/cmake_install.cmake
new file mode 100644
index 0000000..42ef745
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/dir-permissions-install-options-to-vars/cmake_install.cmake
@@ -0,0 +1,3 @@
+if(CMAKE_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS)
+  message("CMAKE_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS is ${CMAKE_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS}")
+endif()
diff --git a/Tests/RunCMake/interface_library/genex_link-result.txt b/Tests/RunCMake/CommandLine/install-default-dir-permissions-afew-result.txt
similarity index 100%
copy from Tests/RunCMake/interface_library/genex_link-result.txt
copy to Tests/RunCMake/CommandLine/install-default-dir-permissions-afew-result.txt
diff --git a/Tests/RunCMake/CommandLine/install-default-dir-permissions-afew-stderr.txt b/Tests/RunCMake/CommandLine/install-default-dir-permissions-afew-stderr.txt
new file mode 100644
index 0000000..42f4b3f
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/install-default-dir-permissions-afew-stderr.txt
@@ -0,0 +1 @@
+CMAKE_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS is OWNER_READ;OWNER_WRITE;OWNER_EXECUTE;GROUP_READ;GROUP_EXECUTE
diff --git a/Tests/RunCMake/interface_library/genex_link-result.txt b/Tests/RunCMake/CommandLine/install-default-dir-permissions-all-result.txt
similarity index 100%
copy from Tests/RunCMake/interface_library/genex_link-result.txt
copy to Tests/RunCMake/CommandLine/install-default-dir-permissions-all-result.txt
diff --git a/Tests/RunCMake/CommandLine/install-default-dir-permissions-all-stderr.txt b/Tests/RunCMake/CommandLine/install-default-dir-permissions-all-stderr.txt
new file mode 100644
index 0000000..813d9c3
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/install-default-dir-permissions-all-stderr.txt
@@ -0,0 +1 @@
+CMAKE_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS is OWNER_READ;OWNER_WRITE;OWNER_EXECUTE;GROUP_READ;GROUP_EXECUTE;WORLD_READ;WORLD_EXECUTE
diff --git a/Tests/RunCMake/Languages/LINK_LANGUAGE-genex-result.txt b/Tests/RunCMake/CommandLine/install-default-dir-permissions-assignment-at-the-beginning-result.txt
similarity index 100%
copy from Tests/RunCMake/Languages/LINK_LANGUAGE-genex-result.txt
copy to Tests/RunCMake/CommandLine/install-default-dir-permissions-assignment-at-the-beginning-result.txt
diff --git a/Tests/RunCMake/CommandLine/install-default-dir-permissions-assignment-at-the-beginning-stderr.txt b/Tests/RunCMake/CommandLine/install-default-dir-permissions-assignment-at-the-beginning-stderr.txt
new file mode 100644
index 0000000..1b80952
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/install-default-dir-permissions-assignment-at-the-beginning-stderr.txt
@@ -0,0 +1 @@
+--default-directory-permissions is in incorrect format
diff --git a/Tests/RunCMake/interface_library/genex_link-result.txt b/Tests/RunCMake/CommandLine/install-default-dir-permissions-assignment-at-the-end-result.txt
similarity index 100%
copy from Tests/RunCMake/interface_library/genex_link-result.txt
copy to Tests/RunCMake/CommandLine/install-default-dir-permissions-assignment-at-the-end-result.txt
diff --git a/Tests/RunCMake/CommandLine/install-default-dir-permissions-assignment-at-the-end-stderr.txt b/Tests/RunCMake/CommandLine/install-default-dir-permissions-assignment-at-the-end-stderr.txt
new file mode 100644
index 0000000..6680932
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/install-default-dir-permissions-assignment-at-the-end-stderr.txt
@@ -0,0 +1 @@
+CMAKE_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS is OWNER_READ;OWNER_WRITE;OWNER_EXECUTE
diff --git a/Tests/RunCMake/install/file-GET_RUNTIME_DEPENDENCIES-unsupported-result.txt b/Tests/RunCMake/CommandLine/install-default-dir-permissions-comma-at-the-end-result.txt
similarity index 100%
rename from Tests/RunCMake/install/file-GET_RUNTIME_DEPENDENCIES-unsupported-result.txt
rename to Tests/RunCMake/CommandLine/install-default-dir-permissions-comma-at-the-end-result.txt
diff --git a/Tests/RunCMake/CommandLine/install-default-dir-permissions-comma-at-the-end-stderr.txt b/Tests/RunCMake/CommandLine/install-default-dir-permissions-comma-at-the-end-stderr.txt
new file mode 100644
index 0000000..1b80952
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/install-default-dir-permissions-comma-at-the-end-stderr.txt
@@ -0,0 +1 @@
+--default-directory-permissions is in incorrect format
diff --git a/Tests/RunCMake/Languages/LINK_LANGUAGE-genex-result.txt b/Tests/RunCMake/CommandLine/install-default-dir-permissions-invalid-assignment-result.txt
similarity index 100%
copy from Tests/RunCMake/Languages/LINK_LANGUAGE-genex-result.txt
copy to Tests/RunCMake/CommandLine/install-default-dir-permissions-invalid-assignment-result.txt
diff --git a/Tests/RunCMake/CommandLine/install-default-dir-permissions-invalid-assignment-stderr.txt b/Tests/RunCMake/CommandLine/install-default-dir-permissions-invalid-assignment-stderr.txt
new file mode 100644
index 0000000..1b80952
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/install-default-dir-permissions-invalid-assignment-stderr.txt
@@ -0,0 +1 @@
+--default-directory-permissions is in incorrect format
diff --git a/Tests/RunCMake/install/file-GET_RUNTIME_DEPENDENCIES-badargs1-result.txt b/Tests/RunCMake/CommandLine/install-default-dir-permissions-invalid-comma1-result.txt
similarity index 100%
rename from Tests/RunCMake/install/file-GET_RUNTIME_DEPENDENCIES-badargs1-result.txt
rename to Tests/RunCMake/CommandLine/install-default-dir-permissions-invalid-comma1-result.txt
diff --git a/Tests/RunCMake/CommandLine/install-default-dir-permissions-invalid-comma1-stderr.txt b/Tests/RunCMake/CommandLine/install-default-dir-permissions-invalid-comma1-stderr.txt
new file mode 100644
index 0000000..1b80952
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/install-default-dir-permissions-invalid-comma1-stderr.txt
@@ -0,0 +1 @@
+--default-directory-permissions is in incorrect format
diff --git a/Tests/RunCMake/install/file-GET_RUNTIME_DEPENDENCIES-badargs2-result.txt b/Tests/RunCMake/CommandLine/install-default-dir-permissions-invalid-comma2-result.txt
similarity index 100%
rename from Tests/RunCMake/install/file-GET_RUNTIME_DEPENDENCIES-badargs2-result.txt
rename to Tests/RunCMake/CommandLine/install-default-dir-permissions-invalid-comma2-result.txt
diff --git a/Tests/RunCMake/CommandLine/install-default-dir-permissions-invalid-comma2-stderr.txt b/Tests/RunCMake/CommandLine/install-default-dir-permissions-invalid-comma2-stderr.txt
new file mode 100644
index 0000000..1b80952
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/install-default-dir-permissions-invalid-comma2-stderr.txt
@@ -0,0 +1 @@
+--default-directory-permissions is in incorrect format
diff --git a/Tests/RunCMake/interface_library/genex_link-result.txt b/Tests/RunCMake/CommandLine/install-default-dir-permissions-none-result.txt
similarity index 100%
copy from Tests/RunCMake/interface_library/genex_link-result.txt
copy to Tests/RunCMake/CommandLine/install-default-dir-permissions-none-result.txt
diff --git a/Tests/RunCMake/CommandLine/install-default-dir-permissions-none-stderr.txt b/Tests/RunCMake/CommandLine/install-default-dir-permissions-none-stderr.txt
new file mode 100644
index 0000000..10f3293
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/install-default-dir-permissions-none-stderr.txt
@@ -0,0 +1 @@
+^$
diff --git a/Tests/RunCMake/Languages/LINK_LANGUAGE-genex-result.txt b/Tests/RunCMake/CommandLine/profiling-all-params-result.txt
similarity index 100%
copy from Tests/RunCMake/Languages/LINK_LANGUAGE-genex-result.txt
copy to Tests/RunCMake/CommandLine/profiling-all-params-result.txt
diff --git a/Tests/RunCMake/CommandLine/profiling-all-params-stderr.txt b/Tests/RunCMake/CommandLine/profiling-all-params-stderr.txt
new file mode 100644
index 0000000..6b5c373
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/profiling-all-params-stderr.txt
@@ -0,0 +1 @@
+^.*Could not start profiling: Unable to open: /no/such/file.txt$
diff --git a/Tests/RunCMake/Languages/LINK_LANGUAGE-genex-result.txt b/Tests/RunCMake/CommandLine/profiling-invalid-format-result.txt
similarity index 100%
copy from Tests/RunCMake/Languages/LINK_LANGUAGE-genex-result.txt
copy to Tests/RunCMake/CommandLine/profiling-invalid-format-result.txt
diff --git a/Tests/RunCMake/CommandLine/profiling-invalid-format-stderr.txt b/Tests/RunCMake/CommandLine/profiling-invalid-format-stderr.txt
new file mode 100644
index 0000000..459bc3a
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/profiling-invalid-format-stderr.txt
@@ -0,0 +1 @@
+^.*Invalid format specified for --profiling-format$
diff --git a/Tests/RunCMake/Languages/LINK_LANGUAGE-genex-result.txt b/Tests/RunCMake/CommandLine/profiling-missing-format-result.txt
similarity index 100%
copy from Tests/RunCMake/Languages/LINK_LANGUAGE-genex-result.txt
copy to Tests/RunCMake/CommandLine/profiling-missing-format-result.txt
diff --git a/Tests/RunCMake/CommandLine/profiling-missing-format-stderr.txt b/Tests/RunCMake/CommandLine/profiling-missing-format-stderr.txt
new file mode 100644
index 0000000..459bc3a
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/profiling-missing-format-stderr.txt
@@ -0,0 +1 @@
+^.*Invalid format specified for --profiling-format$
diff --git a/Tests/RunCMake/Languages/LINK_LANGUAGE-genex-result.txt b/Tests/RunCMake/CommandLine/profiling-missing-output-result.txt
similarity index 100%
copy from Tests/RunCMake/Languages/LINK_LANGUAGE-genex-result.txt
copy to Tests/RunCMake/CommandLine/profiling-missing-output-result.txt
diff --git a/Tests/RunCMake/CommandLine/profiling-missing-output-stderr.txt b/Tests/RunCMake/CommandLine/profiling-missing-output-stderr.txt
new file mode 100644
index 0000000..9ab0c8f
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/profiling-missing-output-stderr.txt
@@ -0,0 +1 @@
+^.*--profiling-format specified but no --profiling-output!$
diff --git a/Tests/RunCMake/CompatibleInterface/CMakeLists.txt b/Tests/RunCMake/CompatibleInterface/CMakeLists.txt
index f452db1..ebab7a3 100644
--- a/Tests/RunCMake/CompatibleInterface/CMakeLists.txt
+++ b/Tests/RunCMake/CompatibleInterface/CMakeLists.txt
@@ -1,3 +1,3 @@
-cmake_minimum_required(VERSION 2.8.4)
+cmake_minimum_required(VERSION 3.3)
 project(${RunCMake_TEST} CXX)
 include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/CompatibleInterface/DebugProperties.cmake b/Tests/RunCMake/CompatibleInterface/DebugProperties.cmake
index 0196611..64b52d9 100644
--- a/Tests/RunCMake/CompatibleInterface/DebugProperties.cmake
+++ b/Tests/RunCMake/CompatibleInterface/DebugProperties.cmake
@@ -1,5 +1,5 @@
 
-cmake_minimum_required(VERSION 2.8)
+cmake_minimum_required(VERSION 3.3)
 
 project(CompatibleInterface)
 
diff --git a/Tests/RunCMake/CompatibleInterface/InterfaceString-builtin-prop.cmake b/Tests/RunCMake/CompatibleInterface/InterfaceString-builtin-prop.cmake
index 5772856..f072eb0 100644
--- a/Tests/RunCMake/CompatibleInterface/InterfaceString-builtin-prop.cmake
+++ b/Tests/RunCMake/CompatibleInterface/InterfaceString-builtin-prop.cmake
@@ -5,5 +5,5 @@
 set_property(TARGET foo APPEND PROPERTY COMPATIBLE_INTERFACE_STRING INCLUDE_DIRECTORIES)
 
 add_executable(user main.cpp)
-set_property(TARGET user PROPERTY INCLUDE_DIRECTORIES bar_inc)
+set_property(TARGET user PROPERTY INCLUDE_DIRECTORIES ${CMAKE_CURRENT_SOURCE_DIR}/bar_inc)
 target_link_libraries(user foo bar)
diff --git a/Tests/RunCMake/CompilerArgs/C.cmake b/Tests/RunCMake/CompilerArgs/C.cmake
new file mode 100644
index 0000000..96b004b
--- /dev/null
+++ b/Tests/RunCMake/CompilerArgs/C.cmake
@@ -0,0 +1,3 @@
+enable_language(C)
+set(CMAKE_VERBOSE_MAKEFILE TRUE)
+add_executable(main main.c)
diff --git a/Tests/RunCMake/CompilerArgs/CMakeLists.txt b/Tests/RunCMake/CompilerArgs/CMakeLists.txt
new file mode 100644
index 0000000..18dfd26
--- /dev/null
+++ b/Tests/RunCMake/CompilerArgs/CMakeLists.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 3.2)
+project(${RunCMake_TEST} NONE)
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/CompilerArgs/CXX.cmake b/Tests/RunCMake/CompilerArgs/CXX.cmake
new file mode 100644
index 0000000..3d2ee00
--- /dev/null
+++ b/Tests/RunCMake/CompilerArgs/CXX.cmake
@@ -0,0 +1,3 @@
+enable_language(CXX)
+set(CMAKE_VERBOSE_MAKEFILE TRUE)
+add_executable(main main.cxx)
diff --git a/Tests/RunCMake/CompilerArgs/FindCCompiler.cmake b/Tests/RunCMake/CompilerArgs/FindCCompiler.cmake
new file mode 100644
index 0000000..aeaaf7f
--- /dev/null
+++ b/Tests/RunCMake/CompilerArgs/FindCCompiler.cmake
@@ -0,0 +1,2 @@
+enable_language(C)
+file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/C_comp.cmake" "set(temp_CMAKE_C_COMPILER \"${CMAKE_C_COMPILER}\")\n")
diff --git a/Tests/RunCMake/CompilerArgs/FindCXXCompiler.cmake b/Tests/RunCMake/CompilerArgs/FindCXXCompiler.cmake
new file mode 100644
index 0000000..663ac83
--- /dev/null
+++ b/Tests/RunCMake/CompilerArgs/FindCXXCompiler.cmake
@@ -0,0 +1,2 @@
+enable_language(CXX)
+file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/CXX_comp.cmake" "set(temp_CMAKE_CXX_COMPILER \"${CMAKE_CXX_COMPILER}\")\n")
diff --git a/Tests/RunCMake/CompilerArgs/RunCMakeTest.cmake b/Tests/RunCMake/CompilerArgs/RunCMakeTest.cmake
new file mode 100644
index 0000000..9e5a18a
--- /dev/null
+++ b/Tests/RunCMake/CompilerArgs/RunCMakeTest.cmake
@@ -0,0 +1,58 @@
+include(RunCMake)
+
+function(find_compiler lang)
+  # Detect the compiler in use in the current environment.
+  run_cmake(Find${lang}Compiler)
+  # Use the detected compiler
+  include(${RunCMake_BINARY_DIR}/Find${lang}Compiler-build/${lang}_comp.cmake)
+  if(NOT temp_CMAKE_${lang}_COMPILER)
+    message(FATAL_ERROR "FindCompiler provided no compiler!")
+  endif()
+  # Create a toolchain file
+  set(__test_compiler_var CMAKE_${lang}_COMPILER)
+  set(__test_compiler "${temp_CMAKE_${lang}_COMPILER}")
+  configure_file(${RunCMake_SOURCE_DIR}/toolchain.cmake.in
+      ${RunCMake_BINARY_DIR}/Find${lang}Compiler-build/toolchain_${lang}_comp.cmake @ONLY)
+endfunction()
+
+function(run_compiler_env lang)
+  # Use the correct compiler
+  include(${RunCMake_BINARY_DIR}/Find${lang}Compiler-build/${lang}_comp.cmake)
+
+  # Use a single build tree for tests without cleaning.
+  set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/${lang}-env-build)
+  set(RunCMake_TEST_NO_CLEAN 1)
+  file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}")
+  file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}")
+
+  # Set the compiler
+  if(lang STREQUAL "C")
+    set(ENV{CC} "'${temp_CMAKE_${lang}_COMPILER}' -DFOO1 -DFOO2")
+  else()
+    set(ENV{${lang}} "'${temp_CMAKE_${lang}_COMPILER}' -DFOO1 -DFOO2")
+  endif()
+
+  run_cmake(${lang})
+  run_cmake_command(${lang}-Build ${CMAKE_COMMAND} --build . ${verbose_args})
+endfunction()
+
+function(run_compiler_tc lang)
+  # Use a single build tree for tests without cleaning.
+  set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/${lang}-tc-build)
+  set(RunCMake_TEST_NO_CLEAN 1)
+  file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}")
+  file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}")
+
+  set(RunCMake_TEST_OPTIONS
+      -DCMAKE_TOOLCHAIN_FILE=${RunCMake_BINARY_DIR}/Find${lang}Compiler-build/toolchain_${lang}_comp.cmake)
+  run_cmake(${lang})
+  run_cmake_command(${lang}-Build ${CMAKE_COMMAND} --build . ${verbose_args})
+endfunction()
+
+set(langs C CXX)
+
+foreach(lang ${langs})
+  find_compiler(${lang})
+  run_compiler_env(${lang})
+  run_compiler_tc(${lang})
+endforeach()
diff --git a/Tests/RunCMake/CompilerArgs/main.c b/Tests/RunCMake/CompilerArgs/main.c
new file mode 100644
index 0000000..b526135
--- /dev/null
+++ b/Tests/RunCMake/CompilerArgs/main.c
@@ -0,0 +1,10 @@
+#ifndef FOO1
+#  error Missing FOO1
+#endif
+#ifndef FOO2
+#  error Missing FOO2
+#endif
+int main(void)
+{
+  return 0;
+}
diff --git a/Tests/RunCMake/CompilerArgs/main.cxx b/Tests/RunCMake/CompilerArgs/main.cxx
new file mode 100644
index 0000000..db90e93
--- /dev/null
+++ b/Tests/RunCMake/CompilerArgs/main.cxx
@@ -0,0 +1,10 @@
+#ifndef FOO1
+#  error Missing FOO1
+#endif
+#ifndef FOO2
+#  error Missing FOO2
+#endif
+int main()
+{
+  return 0;
+}
diff --git a/Tests/RunCMake/CompilerArgs/toolchain.cmake.in b/Tests/RunCMake/CompilerArgs/toolchain.cmake.in
new file mode 100644
index 0000000..ff77639
--- /dev/null
+++ b/Tests/RunCMake/CompilerArgs/toolchain.cmake.in
@@ -0,0 +1 @@
+set(@__test_compiler_var@ "@__test_compiler@" -DFOO1 -DFOO2)
diff --git a/Tests/RunCMake/CompilerChange/CMakeLists.txt b/Tests/RunCMake/CompilerChange/CMakeLists.txt
index b4b3016..14c47ad 100644
--- a/Tests/RunCMake/CompilerChange/CMakeLists.txt
+++ b/Tests/RunCMake/CompilerChange/CMakeLists.txt
@@ -1,4 +1,4 @@
-cmake_minimum_required(VERSION 2.8.4)
+cmake_minimum_required(VERSION 3.3)
 if(NOT RunCMake_TEST)
   set(RunCMake_TEST "$ENV{RunCMake_TEST}") # needed when cache is deleted
 endif()
diff --git a/Tests/RunCMake/CompilerLauncher/CUDA-common.cmake b/Tests/RunCMake/CompilerLauncher/CUDA-common.cmake
index 6f7fc86..ca25b2a 100644
--- a/Tests/RunCMake/CompilerLauncher/CUDA-common.cmake
+++ b/Tests/RunCMake/CompilerLauncher/CUDA-common.cmake
@@ -1,3 +1,4 @@
+cmake_policy(SET CMP0104 NEW)
 enable_language(CUDA)
 set(CMAKE_VERBOSE_MAKEFILE TRUE)
 add_executable(main main.cu)
diff --git a/Tests/RunCMake/CompilerNotFound/CMakeLists.txt b/Tests/RunCMake/CompilerNotFound/CMakeLists.txt
index 12cd3c7..74b3ff8 100644
--- a/Tests/RunCMake/CompilerNotFound/CMakeLists.txt
+++ b/Tests/RunCMake/CompilerNotFound/CMakeLists.txt
@@ -1,3 +1,3 @@
-cmake_minimum_required(VERSION 2.8.4)
+cmake_minimum_required(VERSION 3.3)
 project(${RunCMake_TEST} NONE)
 include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/Configure/CMakeLists.txt b/Tests/RunCMake/Configure/CMakeLists.txt
index 12cd3c7..74b3ff8 100644
--- a/Tests/RunCMake/Configure/CMakeLists.txt
+++ b/Tests/RunCMake/Configure/CMakeLists.txt
@@ -1,3 +1,3 @@
-cmake_minimum_required(VERSION 2.8.4)
+cmake_minimum_required(VERSION 3.3)
 project(${RunCMake_TEST} NONE)
 include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/DisallowedCommands/CMakeLists.txt b/Tests/RunCMake/DisallowedCommands/CMakeLists.txt
index 12cd3c7..4b3de84 100644
--- a/Tests/RunCMake/DisallowedCommands/CMakeLists.txt
+++ b/Tests/RunCMake/DisallowedCommands/CMakeLists.txt
@@ -1,3 +1,3 @@
-cmake_minimum_required(VERSION 2.8.4)
+cmake_minimum_required(VERSION 2.8.12)
 project(${RunCMake_TEST} NONE)
 include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/ExcludeFromAll/CMakeLists.txt b/Tests/RunCMake/ExcludeFromAll/CMakeLists.txt
new file mode 100644
index 0000000..74b3ff8
--- /dev/null
+++ b/Tests/RunCMake/ExcludeFromAll/CMakeLists.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 3.3)
+project(${RunCMake_TEST} NONE)
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/ExcludeFromAll/RunCMakeTest.cmake b/Tests/RunCMake/ExcludeFromAll/RunCMakeTest.cmake
new file mode 100644
index 0000000..2b4fc89
--- /dev/null
+++ b/Tests/RunCMake/ExcludeFromAll/RunCMakeTest.cmake
@@ -0,0 +1,26 @@
+include(RunCMake)
+
+function(run_single_config_test label config exclude_from_all_value expectation)
+    set(case single-config)
+    message("-- Starting ${case} test: ${label}")
+    set(full_case_name "${case}-build-${config}")
+    set(RunCMake_TEST_BINARY_DIR "${RunCMake_BINARY_DIR}/${full_case_name}/")
+    run_cmake_with_options(${case}
+        -DCMAKE_BUILD_TYPE=${config}
+        -DTOOL_EXCLUDE_FROM_ALL=${exclude_from_all_value})
+    set(RunCMake_TEST_NO_CLEAN 1)
+    include(${RunCMake_TEST_BINARY_DIR}/target_files_${config}.cmake)
+    run_cmake_command(${case}-build ${CMAKE_COMMAND} --build . --config ${config})
+endfunction()
+
+run_single_config_test("explictly not excluded" Debug 0 "should_exist")
+run_single_config_test("excluded" Debug 1 "should_not_exist")
+
+if(RunCMake_GENERATOR MATCHES "^(Xcode|Visual Studio)")
+    run_cmake(error-on-mixed-config)
+else()
+    run_single_config_test("explicitly not excluded with genex"
+        Release $<CONFIG:Debug> "should_exist")
+    run_single_config_test("excluded with genex"
+        Debug $<CONFIG:Debug> "should_not_exist")
+endif()
diff --git a/Tests/RunCMake/Languages/LINK_LANGUAGE-genex-result.txt b/Tests/RunCMake/ExcludeFromAll/error-on-mixed-config-result.txt
similarity index 100%
copy from Tests/RunCMake/Languages/LINK_LANGUAGE-genex-result.txt
copy to Tests/RunCMake/ExcludeFromAll/error-on-mixed-config-result.txt
diff --git a/Tests/RunCMake/ExcludeFromAll/error-on-mixed-config-stderr.txt b/Tests/RunCMake/ExcludeFromAll/error-on-mixed-config-stderr.txt
new file mode 100644
index 0000000..6dc785f
--- /dev/null
+++ b/Tests/RunCMake/ExcludeFromAll/error-on-mixed-config-stderr.txt
@@ -0,0 +1,3 @@
+CMake Error in CMakeLists.txt:
+  The EXCLUDE_FROM_ALL property of target "release_only_tool" varies by
+  configuration.  This is not supported by the "[^"]+"
diff --git a/Tests/RunCMake/ExcludeFromAll/error-on-mixed-config.cmake b/Tests/RunCMake/ExcludeFromAll/error-on-mixed-config.cmake
new file mode 100644
index 0000000..6c0ed1d
--- /dev/null
+++ b/Tests/RunCMake/ExcludeFromAll/error-on-mixed-config.cmake
@@ -0,0 +1,6 @@
+enable_language(C)
+
+set(CMAKE_CONFIGURATION_TYPES "Release;Debug" CACHE STRING "")
+
+add_executable(release_only_tool main.c)
+set_property(TARGET release_only_tool PROPERTY EXCLUDE_FROM_ALL "$<NOT:$<CONFIG:Release>>")
diff --git a/Tests/FindModulesExecuteAll/main.c b/Tests/RunCMake/ExcludeFromAll/main.c
similarity index 100%
rename from Tests/FindModulesExecuteAll/main.c
rename to Tests/RunCMake/ExcludeFromAll/main.c
diff --git a/Tests/RunCMake/ExcludeFromAll/single-config-build-check.cmake b/Tests/RunCMake/ExcludeFromAll/single-config-build-check.cmake
new file mode 100644
index 0000000..1c455f2
--- /dev/null
+++ b/Tests/RunCMake/ExcludeFromAll/single-config-build-check.cmake
@@ -0,0 +1,17 @@
+if(expectation STREQUAL "should_not_exist")
+    set(should_exist FALSE)
+elseif(expectation STREQUAL "should_exist")
+    set(should_exist TRUE)
+else()
+    message(FATAL_ERROR "Encountered unknown expectation: ${expectation}")
+endif()
+
+if(EXISTS "${TARGET_FILE_tool_${config}}")
+    if(NOT should_exist)
+        message(FATAL_ERROR "${TARGET_FILE_tool_${config}} should not exist.")
+    endif()
+else()
+    if(should_exist)
+        message(FATAL_ERROR "${TARGET_FILE_tool_${config}} should exist.")
+    endif()
+endif()
diff --git a/Tests/RunCMake/ExcludeFromAll/single-config.cmake b/Tests/RunCMake/ExcludeFromAll/single-config.cmake
new file mode 100644
index 0000000..aa49c21
--- /dev/null
+++ b/Tests/RunCMake/ExcludeFromAll/single-config.cmake
@@ -0,0 +1,7 @@
+enable_language(C)
+add_executable(tool main.c)
+set_property(TARGET tool PROPERTY EXCLUDE_FROM_ALL "${TOOL_EXCLUDE_FROM_ALL}")
+
+file(GENERATE OUTPUT "${CMAKE_BINARY_DIR}/target_files_$<CONFIG>.cmake" CONTENT [[
+set(TARGET_FILE_tool_$<CONFIG> [==[$<TARGET_FILE:tool>]==])
+]])
diff --git a/Tests/RunCMake/ExportCompileCommands/BeforeProject-check.cmake b/Tests/RunCMake/ExportCompileCommands/BeforeProject-check.cmake
new file mode 100644
index 0000000..87058e2
--- /dev/null
+++ b/Tests/RunCMake/ExportCompileCommands/BeforeProject-check.cmake
@@ -0,0 +1,4 @@
+if(NOT EXISTS "${RunCMake_TEST_BINARY_DIR}/compile_commands.json")
+  set(RunCMake_TEST_FAILED "compile_commands.json not generated")
+  return()
+endif()
diff --git a/Tests/RunCMake/ExportCompileCommands/BeforeProject.cmake b/Tests/RunCMake/ExportCompileCommands/BeforeProject.cmake
new file mode 100644
index 0000000..b8cbdef
--- /dev/null
+++ b/Tests/RunCMake/ExportCompileCommands/BeforeProject.cmake
@@ -0,0 +1,3 @@
+enable_language(C)
+add_library(empty STATIC empty.c)
+message(STATUS "CMAKE_EXPORT_COMPILE_COMMANDS='${CMAKE_EXPORT_COMPILE_COMMANDS}'")
diff --git a/Tests/RunCMake/ExportCompileCommands/BeforeProjectBEFORE.cmake b/Tests/RunCMake/ExportCompileCommands/BeforeProjectBEFORE.cmake
new file mode 100644
index 0000000..87f9c87
--- /dev/null
+++ b/Tests/RunCMake/ExportCompileCommands/BeforeProjectBEFORE.cmake
@@ -0,0 +1 @@
+set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
diff --git a/Tests/RunCMake/ExportCompileCommands/CMakeLists.txt b/Tests/RunCMake/ExportCompileCommands/CMakeLists.txt
new file mode 100644
index 0000000..b7117bd
--- /dev/null
+++ b/Tests/RunCMake/ExportCompileCommands/CMakeLists.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 3.17)
+project(${RunCMake_TEST} NONE)
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/ExportCompileCommands/RunCMakeTest.cmake b/Tests/RunCMake/ExportCompileCommands/RunCMakeTest.cmake
new file mode 100644
index 0000000..b540a04
--- /dev/null
+++ b/Tests/RunCMake/ExportCompileCommands/RunCMakeTest.cmake
@@ -0,0 +1,3 @@
+include(RunCMake)
+
+run_cmake_with_options(BeforeProject -DCMAKE_PROJECT_INCLUDE_BEFORE=BeforeProjectBEFORE.cmake)
diff --git a/Tests/RunCMake/ExportCompileCommands/empty.c b/Tests/RunCMake/ExportCompileCommands/empty.c
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/Tests/RunCMake/ExportCompileCommands/empty.c
diff --git a/Tests/RunCMake/ExportWithoutLanguage/CMakeLists.txt b/Tests/RunCMake/ExportWithoutLanguage/CMakeLists.txt
index 12cd3c7..74b3ff8 100644
--- a/Tests/RunCMake/ExportWithoutLanguage/CMakeLists.txt
+++ b/Tests/RunCMake/ExportWithoutLanguage/CMakeLists.txt
@@ -1,3 +1,3 @@
-cmake_minimum_required(VERSION 2.8.4)
+cmake_minimum_required(VERSION 3.3)
 project(${RunCMake_TEST} NONE)
 include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/ExternalData/CMakeLists.txt b/Tests/RunCMake/ExternalData/CMakeLists.txt
index 12cd3c7..74b3ff8 100644
--- a/Tests/RunCMake/ExternalData/CMakeLists.txt
+++ b/Tests/RunCMake/ExternalData/CMakeLists.txt
@@ -1,3 +1,3 @@
-cmake_minimum_required(VERSION 2.8.4)
+cmake_minimum_required(VERSION 3.3)
 project(${RunCMake_TEST} NONE)
 include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/ExternalProject/Add_StepDependencies_iface_step-stderr.txt b/Tests/RunCMake/ExternalProject/Add_StepDependencies_iface_step-stderr.txt
index 22e13bf..5fa75e8 100644
--- a/Tests/RunCMake/ExternalProject/Add_StepDependencies_iface_step-stderr.txt
+++ b/Tests/RunCMake/ExternalProject/Add_StepDependencies_iface_step-stderr.txt
@@ -1,5 +1,5 @@
 ^CMake Error at .*/Modules/ExternalProject.cmake:[0-9]+ \(message\):
-  Target "MyProj-IFace" was not generated by ExternalProject_Add_StepTargets.
+  External project "MyProj" does not have a step "IFace".
 Call Stack \(most recent call first\):
   Add_StepDependencies_iface_step.cmake:[0-9]+ \(ExternalProject_Add_StepDependencies\)
   CMakeLists.txt:[0-9]+ \(include\)$
diff --git a/Tests/RunCMake/ExternalProject/NO_DEPENDS-stderr.txt b/Tests/RunCMake/ExternalProject/NO_DEPENDS-stderr.txt
index 4cb051d..928d88a 100644
--- a/Tests/RunCMake/ExternalProject/NO_DEPENDS-stderr.txt
+++ b/Tests/RunCMake/ExternalProject/NO_DEPENDS-stderr.txt
@@ -2,7 +2,7 @@
   Using NO_DEPENDS for "configure" step might break parallel builds
 Call Stack \(most recent call first\):
   .*/Modules/ExternalProject.cmake:[0-9]+ \(ExternalProject_Add_StepTargets\)
-  .*/Modules/ExternalProject.cmake:[0-9]+ \(ExternalProject_Add_Step\)
+  .*/Modules/ExternalProject.cmake:[0-9]+:EVAL:2 \(ExternalProject_Add_Step\)
   .*/Modules/ExternalProject.cmake:[0-9]+ \(_ep_add_configure_command\)
   NO_DEPENDS.cmake:[0-9]+ \(ExternalProject_Add\)
   CMakeLists.txt:[0-9]+ \(include\)
@@ -12,7 +12,7 @@
   Using NO_DEPENDS for "build" step might break parallel builds
 Call Stack \(most recent call first\):
   .*/Modules/ExternalProject.cmake:[0-9]+ \(ExternalProject_Add_StepTargets\)
-  .*/Modules/ExternalProject.cmake:[0-9]+ \(ExternalProject_Add_Step\)
+  .*/Modules/ExternalProject.cmake:[0-9]+:EVAL:2 \(ExternalProject_Add_Step\)
   .*/Modules/ExternalProject.cmake:[0-9]+ \(_ep_add_build_command\)
   NO_DEPENDS.cmake:[0-9]+ \(ExternalProject_Add\)
   CMakeLists.txt:[0-9]+ \(include\)
@@ -22,7 +22,7 @@
   Using NO_DEPENDS for "install" step might break parallel builds
 Call Stack \(most recent call first\):
   .*/Modules/ExternalProject.cmake:[0-9]+ \(ExternalProject_Add_StepTargets\)
-  .*/Modules/ExternalProject.cmake:[0-9]+ \(ExternalProject_Add_Step\)
+  .*/Modules/ExternalProject.cmake:[0-9]+:EVAL:2 \(ExternalProject_Add_Step\)
   .*/Modules/ExternalProject.cmake:[0-9]+ \(_ep_add_install_command\)
   NO_DEPENDS.cmake:[0-9]+ \(ExternalProject_Add\)
   CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/ExternalProject/PreserveEmptyArgs-build-stdout.txt b/Tests/RunCMake/ExternalProject/PreserveEmptyArgs-build-stdout.txt
new file mode 100644
index 0000000..0e21b8f
--- /dev/null
+++ b/Tests/RunCMake/ExternalProject/PreserveEmptyArgs-build-stdout.txt
@@ -0,0 +1,21 @@
+.*-- Number of arguments for download: 6
+.*-- download argument 4: ''
+.*-- download argument 5: 'after'
+.*-- Number of arguments for update: 6
+.*-- update argument 4: ''
+.*-- update argument 5: 'after'
+.*-- Number of arguments for patch: 6
+.*-- patch argument 4: ''
+.*-- patch argument 5: 'after'
+.*-- Number of arguments for configure: 6
+.*-- configure argument 4: ''
+.*-- configure argument 5: 'after'
+.*-- Number of arguments for build: 6
+.*-- build argument 4: ''
+.*-- build argument 5: 'after'
+.*-- Number of arguments for install: 6
+.*-- install argument 4: ''
+.*-- install argument 5: 'after'
+.*-- Number of arguments for test: 6
+.*-- test argument 4: ''
+.*-- test argument 5: 'after'
diff --git a/Tests/RunCMake/ExternalProject/PreserveEmptyArgs.cmake b/Tests/RunCMake/ExternalProject/PreserveEmptyArgs.cmake
new file mode 100644
index 0000000..ded1000
--- /dev/null
+++ b/Tests/RunCMake/ExternalProject/PreserveEmptyArgs.cmake
@@ -0,0 +1,13 @@
+include(ExternalProject)
+
+set(script "${CMAKE_CURRENT_LIST_DIR}/countArgs.cmake")
+ExternalProject_Add(
+  blankChecker
+  DOWNLOAD_COMMAND  ${CMAKE_COMMAND} -P "${script}" download  "" after
+  UPDATE_COMMAND    ${CMAKE_COMMAND} -P "${script}" update    "" after
+  PATCH_COMMAND     ${CMAKE_COMMAND} -P "${script}" patch     "" after
+  CONFIGURE_COMMAND ${CMAKE_COMMAND} -P "${script}" configure "" after
+  BUILD_COMMAND     ${CMAKE_COMMAND} -P "${script}" build     "" after
+  INSTALL_COMMAND   ${CMAKE_COMMAND} -P "${script}" install   "" after
+  TEST_COMMAND      ${CMAKE_COMMAND} -P "${script}" test      "" after
+)
diff --git a/Tests/RunCMake/ExternalProject/RunCMakeTest.cmake b/Tests/RunCMake/ExternalProject/RunCMakeTest.cmake
index caaf0d2..0d1da26 100644
--- a/Tests/RunCMake/ExternalProject/RunCMakeTest.cmake
+++ b/Tests/RunCMake/ExternalProject/RunCMakeTest.cmake
@@ -29,6 +29,10 @@
 
 __ep_test_with_build(MultiCommand)
 
+set(RunCMake_TEST_OUTPUT_MERGE 1)
+__ep_test_with_build(PreserveEmptyArgs)
+set(RunCMake_TEST_OUTPUT_MERGE 0)
+
 # Output is not predictable enough to be able to verify it reliably
 # when using the various different Visual Studio generators
 if(NOT RunCMake_GENERATOR MATCHES "Visual Studio")
diff --git a/Tests/RunCMake/ExternalProject/countArgs.cmake b/Tests/RunCMake/ExternalProject/countArgs.cmake
new file mode 100644
index 0000000..ee6429a
--- /dev/null
+++ b/Tests/RunCMake/ExternalProject/countArgs.cmake
@@ -0,0 +1,5 @@
+message(STATUS "Number of arguments for ${CMAKE_ARGV3}: ${CMAKE_ARGC}")
+math(EXPR last "${CMAKE_ARGC} - 1")
+foreach(n RANGE 4 ${last})
+  message(STATUS "${CMAKE_ARGV3} argument ${n}: '${CMAKE_ARGV${n}}'")
+endforeach()
diff --git a/Tests/RunCMake/FPHSA/CMakeLists.txt b/Tests/RunCMake/FPHSA/CMakeLists.txt
index 12cd3c7..74b3ff8 100644
--- a/Tests/RunCMake/FPHSA/CMakeLists.txt
+++ b/Tests/RunCMake/FPHSA/CMakeLists.txt
@@ -1,3 +1,3 @@
-cmake_minimum_required(VERSION 2.8.4)
+cmake_minimum_required(VERSION 3.3)
 project(${RunCMake_TEST} NONE)
 include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/FPHSA/FindUseComponents.cmake b/Tests/RunCMake/FPHSA/FindUseComponents.cmake
new file mode 100644
index 0000000..4168f1d
--- /dev/null
+++ b/Tests/RunCMake/FPHSA/FindUseComponents.cmake
@@ -0,0 +1,15 @@
+# pseudo find_module
+
+if (UseComponents_REQUIRE_VARS)
+  set(FOOBAR TRUE)
+  set(REQUIRED_VARS REQUIRED_VARS  FOOBAR)
+endif()
+
+set (UseComponents_Comp1_FOUND TRUE)
+set (UseComponents_Comp2_FOUND TRUE)
+set (UseComponents_Comp3_FOUND FALSE)
+
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(UseComponents ${REQUIRED_VARS}
+                                                VERSION_VAR Pseudo_VERSION
+                                                HANDLE_COMPONENTS)
diff --git a/Tests/RunCMake/FPHSA/RunCMakeTest.cmake b/Tests/RunCMake/FPHSA/RunCMakeTest.cmake
index 286915d..8e39090 100644
--- a/Tests/RunCMake/FPHSA/RunCMakeTest.cmake
+++ b/Tests/RunCMake/FPHSA/RunCMakeTest.cmake
@@ -47,3 +47,11 @@
 set(RunCMake_TEST_OPTIONS "-DCMAKE_MODULE_PATH=${CMAKE_CURRENT_LIST_DIR}" "-DCONFIG_MODE=TRUE")
 run_cmake(custom_message_2)
 run_cmake(custom_message_3)
+
+# check handling of components
+set(RunCMake_TEST_OPTIONS "-DCMAKE_MODULE_PATH=${CMAKE_CURRENT_LIST_DIR}" "-DUseComponents_VERSION=1.2.3.4")
+run_cmake(required_components)
+run_cmake(required_and_optional_components)
+run_cmake(all_optional_components)
+list(APPEND RunCMake_TEST_OPTIONS "-DUseComponents_REQUIRE_VARS=TRUE")
+run_cmake(required_components_with_vars)
diff --git a/Tests/RunCMake/FPHSA/all_optional_components.cmake b/Tests/RunCMake/FPHSA/all_optional_components.cmake
new file mode 100644
index 0000000..f4d8b5e
--- /dev/null
+++ b/Tests/RunCMake/FPHSA/all_optional_components.cmake
@@ -0,0 +1,14 @@
+find_package(UseComponents OPTIONAL_COMPONENTS Comp1 Comp2 Comp3)
+
+if (NOT UseComponents_FOUND)
+  message (FATAL_ERROR "package UseComponents Not Found.")
+endif()
+if (NOT UseComponents_Comp1_FOUND)
+  message (FATAL_ERROR "package UseComponents, component Comp1 not found.")
+endif()
+if (NOT UseComponents_Comp2_FOUND)
+  message (FATAL_ERROR "package UseComponents, component Comp2 not found.")
+endif()
+if (UseComponents_Comp3_FOUND)
+  message (FATAL_ERROR "package UseComponents, component Comp2 unexpectedly found.")
+endif()
diff --git a/Tests/RunCMake/FPHSA/required_and_optional_components.cmake b/Tests/RunCMake/FPHSA/required_and_optional_components.cmake
new file mode 100644
index 0000000..836dcac
--- /dev/null
+++ b/Tests/RunCMake/FPHSA/required_and_optional_components.cmake
@@ -0,0 +1,14 @@
+find_package(UseComponents COMPONENTS Comp1 Comp2 OPTIONAL_COMPONENTS Comp3)
+
+if (NOT UseComponents_FOUND)
+  message (FATAL_ERROR "package UseComponents Not Found.")
+endif()
+if (NOT UseComponents_Comp1_FOUND)
+  message (FATAL_ERROR "package UseComponents, component Comp1 not found.")
+endif()
+if (NOT UseComponents_Comp2_FOUND)
+  message (FATAL_ERROR "package UseComponents, component Comp2 not found.")
+endif()
+if (UseComponents_Comp3_FOUND)
+  message (FATAL_ERROR "package UseComponents, component Comp2 unexpectedly found.")
+endif()
diff --git a/Tests/RunCMake/FPHSA/required_components.cmake b/Tests/RunCMake/FPHSA/required_components.cmake
new file mode 100644
index 0000000..0dd8e9c
--- /dev/null
+++ b/Tests/RunCMake/FPHSA/required_components.cmake
@@ -0,0 +1,11 @@
+find_package(UseComponents COMPONENTS Comp1 Comp2)
+
+if (NOT UseComponents_FOUND)
+  message (FATAL_ERROR "package UseComponents Not Found.")
+endif()
+if (NOT UseComponents_Comp1_FOUND)
+  message (FATAL_ERROR "package UseComponents, component Comp1 Not Found.")
+endif()
+if (NOT UseComponents_Comp2_FOUND)
+  message (FATAL_ERROR "package UseComponents, component Comp2 Not Found.")
+endif()
diff --git a/Tests/RunCMake/FPHSA/required_components_with_vars.cmake b/Tests/RunCMake/FPHSA/required_components_with_vars.cmake
new file mode 100644
index 0000000..842ef15
--- /dev/null
+++ b/Tests/RunCMake/FPHSA/required_components_with_vars.cmake
@@ -0,0 +1 @@
+include ("required_components.cmake")
diff --git a/Tests/RunCMake/FeatureSummary/CMakeLists.txt b/Tests/RunCMake/FeatureSummary/CMakeLists.txt
index 72abfc8..74b3ff8 100644
--- a/Tests/RunCMake/FeatureSummary/CMakeLists.txt
+++ b/Tests/RunCMake/FeatureSummary/CMakeLists.txt
@@ -1,3 +1,3 @@
-cmake_minimum_required(VERSION 2.8.11)
+cmake_minimum_required(VERSION 3.3)
 project(${RunCMake_TEST} NONE)
 include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/FetchContent/DownloadFile.cmake b/Tests/RunCMake/FetchContent/DownloadFile.cmake
new file mode 100644
index 0000000..741b6d3
--- /dev/null
+++ b/Tests/RunCMake/FetchContent/DownloadFile.cmake
@@ -0,0 +1,9 @@
+include(FetchContent)
+
+FetchContent_Declare(
+  t1
+  URL ${CMAKE_CURRENT_LIST_DIR}/dummyFile.txt
+  DOWNLOAD_NO_EXTRACT YES
+)
+
+FetchContent_Populate(t1)
diff --git a/Tests/RunCMake/FetchContent/MakeAvailable-stdout.txt b/Tests/RunCMake/FetchContent/MakeAvailable-stdout.txt
index 6e6c730..711de6b 100644
--- a/Tests/RunCMake/FetchContent/MakeAvailable-stdout.txt
+++ b/Tests/RunCMake/FetchContent/MakeAvailable-stdout.txt
@@ -1,2 +1,3 @@
 Confirmation project has been added
+.*Confirmation subproject has been added
 .*Confirmation script has been called
diff --git a/Tests/RunCMake/FetchContent/MakeAvailable.cmake b/Tests/RunCMake/FetchContent/MakeAvailable.cmake
index a93f1f7..d7fc55c 100644
--- a/Tests/RunCMake/FetchContent/MakeAvailable.cmake
+++ b/Tests/RunCMake/FetchContent/MakeAvailable.cmake
@@ -8,13 +8,22 @@
   WithoutProject
   SOURCE_DIR ${CMAKE_CURRENT_LIST_DIR}/WithoutProject
 )
+FetchContent_Declare(
+  ProjectSubdir
+  SOURCE_DIR ${CMAKE_CURRENT_LIST_DIR}/WithoutProject
+  SOURCE_SUBDIR ProjectSubdir
+)
 
 # Order is important and will be verified by test output
-FetchContent_MakeAvailable(WithProject WithoutProject)
+FetchContent_MakeAvailable(WithProject WithoutProject ProjectSubdir)
 
 get_property(addedWith GLOBAL PROPERTY FetchWithProject SET)
 if(NOT addedWith)
-  message(SEND_ERROR "Subdir with CMakeLists.txt not added")
+  message(SEND_ERROR "Project with top level CMakeLists.txt not added")
+endif()
+get_property(addedSubdir GLOBAL PROPERTY FetchWithSubProject SET)
+if(NOT addedSubdir)
+  message(SEND_ERROR "Project with CMakeLists.txt in subdir not added")
 endif()
 
 include(${withoutproject_SOURCE_DIR}/confirmMessage.cmake)
diff --git a/Tests/RunCMake/FetchContent/PreserveEmptyArgs-stdout.txt b/Tests/RunCMake/FetchContent/PreserveEmptyArgs-stdout.txt
new file mode 100644
index 0000000..a72d914
--- /dev/null
+++ b/Tests/RunCMake/FetchContent/PreserveEmptyArgs-stdout.txt
@@ -0,0 +1,4 @@
+.*-- Number of arguments: 6
+.*-- Argument 3: 'before'
+.*-- Argument 4: ''
+.*-- Argument 5: 'after'
diff --git a/Tests/RunCMake/FetchContent/PreserveEmptyArgs.cmake b/Tests/RunCMake/FetchContent/PreserveEmptyArgs.cmake
new file mode 100644
index 0000000..4f35448
--- /dev/null
+++ b/Tests/RunCMake/FetchContent/PreserveEmptyArgs.cmake
@@ -0,0 +1,13 @@
+include(FetchContent)
+
+# Need to see the download command output
+set(FETCHCONTENT_QUIET OFF)
+
+FetchContent_Declare(
+  t1
+  DOWNLOAD_COMMAND ${CMAKE_COMMAND} -P
+                   ${CMAKE_CURRENT_LIST_DIR}/countArgs.cmake
+                   before "" after
+)
+
+FetchContent_Populate(t1)
diff --git a/Tests/RunCMake/FetchContent/RunCMakeTest.cmake b/Tests/RunCMake/FetchContent/RunCMakeTest.cmake
index e28ae96..f3ed3e2 100644
--- a/Tests/RunCMake/FetchContent/RunCMakeTest.cmake
+++ b/Tests/RunCMake/FetchContent/RunCMakeTest.cmake
@@ -6,6 +6,7 @@
 run_cmake(DirectIgnoresDetails)
 run_cmake(FirstDetailsWin)
 run_cmake(DownloadTwice)
+run_cmake(DownloadFile)
 run_cmake(SameGenerator)
 run_cmake(VarDefinitions)
 run_cmake(GetProperties)
@@ -15,6 +16,10 @@
 run_cmake(MakeAvailableTwice)
 run_cmake(MakeAvailableUndeclared)
 
+set(RunCMake_TEST_OUTPUT_MERGE 1)
+run_cmake(PreserveEmptyArgs)
+set(RunCMake_TEST_OUTPUT_MERGE 0)
+
 # We need to pass through CMAKE_GENERATOR and CMAKE_MAKE_PROGRAM
 # to ensure the test can run on machines where the build tool
 # isn't on the PATH. Some build slaves explicitly test with such
diff --git a/Tests/RunCMake/FetchContent/WithoutProject/ProjectSubdir/CMakeLists.txt b/Tests/RunCMake/FetchContent/WithoutProject/ProjectSubdir/CMakeLists.txt
new file mode 100644
index 0000000..216eeb1
--- /dev/null
+++ b/Tests/RunCMake/FetchContent/WithoutProject/ProjectSubdir/CMakeLists.txt
@@ -0,0 +1,5 @@
+cmake_minimum_required(VERSION 3.13)
+project(ProjectSubdir LANGUAGES NONE)
+
+set_property(GLOBAL PROPERTY FetchWithSubProject YES)
+message(STATUS "Confirmation subproject has been added")
diff --git a/Tests/RunCMake/FetchContent/countArgs.cmake b/Tests/RunCMake/FetchContent/countArgs.cmake
new file mode 100644
index 0000000..7542af4
--- /dev/null
+++ b/Tests/RunCMake/FetchContent/countArgs.cmake
@@ -0,0 +1,5 @@
+message(STATUS "Number of arguments: ${CMAKE_ARGC}")
+math(EXPR last "${CMAKE_ARGC} - 1")
+foreach(n RANGE 3 ${last})
+  message(STATUS "Argument ${n}: '${CMAKE_ARGV${n}}'")
+endforeach()
diff --git a/Tests/RunCMake/FetchContent/dummyFile.txt b/Tests/RunCMake/FetchContent/dummyFile.txt
new file mode 100644
index 0000000..0a12ce1
--- /dev/null
+++ b/Tests/RunCMake/FetchContent/dummyFile.txt
@@ -0,0 +1 @@
+# This file is used to verify fetching a single file directly
diff --git a/Tests/RunCMake/FileAPI/RunCMakeTest.cmake b/Tests/RunCMake/FileAPI/RunCMakeTest.cmake
index 8cdc00c..4449ff1 100644
--- a/Tests/RunCMake/FileAPI/RunCMakeTest.cmake
+++ b/Tests/RunCMake/FileAPI/RunCMakeTest.cmake
@@ -23,7 +23,7 @@
   endif()
   file(GLOB index ${RunCMake_TEST_BINARY_DIR}/.cmake/api/v1/reply/index-*.json)
   execute_process(
-    COMMAND ${PYTHON_EXECUTABLE} "${RunCMake_SOURCE_DIR}/${case}-check.py" "${index}"
+    COMMAND ${PYTHON_EXECUTABLE} "${RunCMake_SOURCE_DIR}/${case}-check.py" "${index}" "${CMAKE_CXX_COMPILER_ID}"
     RESULT_VARIABLE result
     OUTPUT_VARIABLE output
     ERROR_VARIABLE output
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-check.py b/Tests/RunCMake/FileAPI/codemodel-v2-check.py
index de6253f..c66757f 100644
--- a/Tests/RunCMake/FileAPI/codemodel-v2-check.py
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-check.py
@@ -1,12 +1,18 @@
 from check_index import *
 
+import json
 import sys
 import os
 
+def read_codemodel_json_data(filename):
+    abs_filename = os.path.join(os.path.dirname(os.path.realpath(__file__)), "codemodel-v2-data", filename)
+    with open(abs_filename, "r") as f:
+        return json.load(f)
+
 def check_objects(o, g):
     assert is_list(o)
     assert len(o) == 1
-    check_index_object(o[0], "codemodel", 2, 0, check_object_codemodel(g))
+    check_index_object(o[0], "codemodel", 2, 2, check_object_codemodel(g))
 
 def check_backtrace(t, b, backtrace):
     btg = t["backtraceGraph"]
@@ -36,6 +42,16 @@
 
     assert b is None
 
+def check_backtraces(t, actual, expected):
+    assert is_list(actual)
+    assert is_list(expected)
+    assert len(actual) == len(expected)
+
+    i = 0
+    while i < len(actual):
+        check_backtrace(t, actual[i], expected[i])
+        i += 1
+
 def check_directory(c):
     def _check(actual, expected):
         assert is_dict(actual)
@@ -398,6 +414,36 @@
                                      missing_exception=lambda e: "Include path: %s" % e["path"],
                                      extra_exception=lambda a: "Include path: %s" % a["path"])
 
+                if "precompileHeaders" in expected:
+                    expected_keys.append("precompileHeaders")
+
+                    def check_precompile_header(actual, expected):
+                        assert is_dict(actual)
+                        expected_keys = ["backtrace", "header"]
+                        check_backtrace(obj, actual["backtrace"], expected["backtrace"])
+
+                        assert sorted(actual.keys()) == sorted(expected_keys)
+
+                    check_list_match(lambda a, e: matches(a["header"], e["header"]),
+                                     actual["precompileHeaders"], expected["precompileHeaders"],
+                                     check=check_precompile_header,
+                                     check_exception=lambda a, e: "Precompile header: %s" % a["header"],
+                                     missing_exception=lambda e: "Precompile header: %s" % e["header"],
+                                     extra_exception=lambda a: "Precompile header: %s" % a["header"])
+
+                if "languageStandard" in expected:
+                    expected_keys.append("languageStandard")
+
+                    def check_language_standard(actual, expected):
+                        assert is_dict(actual)
+                        expected_keys = ["backtraces", "standard"]
+                        assert actual["standard"] == expected["standard"]
+                        check_backtraces(obj, actual["backtraces"], expected["backtraces"])
+
+                        assert sorted(actual.keys()) == sorted(expected_keys)
+
+                    check_language_standard(actual["languageStandard"], expected["languageStandard"])
+
                 if expected["defines"] is not None:
                     expected_keys.append("defines")
 
@@ -471,154 +517,16 @@
 
 def gen_check_directories(c, g):
     expected = [
-        {
-            "source": "^\\.$",
-            "build": "^\\.$",
-            "parentSource": None,
-            "childSources": [
-                "^alias$",
-                "^custom$",
-                "^cxx$",
-                "^imported$",
-                "^object$",
-                "^.*/Tests/RunCMake/FileAPIExternalSource$",
-                "^dir$",
-            ],
-            "targetIds": [
-                "^ALL_BUILD::@6890427a1f51a3e7e1df$",
-                "^ZERO_CHECK::@6890427a1f51a3e7e1df$",
-                "^c_exe::@6890427a1f51a3e7e1df$",
-                "^c_lib::@6890427a1f51a3e7e1df$",
-                "^c_shared_exe::@6890427a1f51a3e7e1df$",
-                "^c_shared_lib::@6890427a1f51a3e7e1df$",
-                "^c_static_exe::@6890427a1f51a3e7e1df$",
-                "^c_static_lib::@6890427a1f51a3e7e1df$",
-                "^interface_exe::@6890427a1f51a3e7e1df$",
-            ],
-            "projectName": "codemodel-v2",
-            "minimumCMakeVersion": "3.12",
-            "hasInstallRule": True,
-        },
-        {
-            "source": "^alias$",
-            "build": "^alias$",
-            "parentSource": "^\\.$",
-            "childSources": None,
-            "targetIds": [
-                "^ALL_BUILD::@53632cba2752272bb008$",
-                "^ZERO_CHECK::@53632cba2752272bb008$",
-                "^c_alias_exe::@53632cba2752272bb008$",
-                "^cxx_alias_exe::@53632cba2752272bb008$",
-            ],
-            "projectName": "Alias",
-            "minimumCMakeVersion": "3.12",
-            "hasInstallRule": None,
-        },
-        {
-            "source": "^custom$",
-            "build": "^custom$",
-            "parentSource": "^\\.$",
-            "childSources": None,
-            "targetIds": [
-                "^ALL_BUILD::@c11385ffed57b860da63$",
-                "^ZERO_CHECK::@c11385ffed57b860da63$",
-                "^custom_exe::@c11385ffed57b860da63$",
-                "^custom_tgt::@c11385ffed57b860da63$",
-            ],
-            "projectName": "Custom",
-            "minimumCMakeVersion": "3.12",
-            "hasInstallRule": None,
-        },
-        {
-            "source": "^cxx$",
-            "build": "^cxx$",
-            "parentSource": "^\\.$",
-            "childSources": None,
-            "targetIds": [
-                "^ALL_BUILD::@a56b12a3f5c0529fb296$",
-                "^ZERO_CHECK::@a56b12a3f5c0529fb296$",
-                "^cxx_exe::@a56b12a3f5c0529fb296$",
-                "^cxx_lib::@a56b12a3f5c0529fb296$",
-                "^cxx_shared_exe::@a56b12a3f5c0529fb296$",
-                "^cxx_shared_lib::@a56b12a3f5c0529fb296$",
-                "^cxx_static_exe::@a56b12a3f5c0529fb296$",
-                "^cxx_static_lib::@a56b12a3f5c0529fb296$",
-            ],
-            "projectName": "Cxx",
-            "minimumCMakeVersion": "3.12",
-            "hasInstallRule": None,
-        },
-        {
-            "source": "^imported$",
-            "build": "^imported$",
-            "parentSource": "^\\.$",
-            "childSources": None,
-            "targetIds": [
-                "^ALL_BUILD::@ba7eb709d0b48779c6c8$",
-                "^ZERO_CHECK::@ba7eb709d0b48779c6c8$",
-                "^link_imported_exe::@ba7eb709d0b48779c6c8$",
-                "^link_imported_interface_exe::@ba7eb709d0b48779c6c8$",
-                "^link_imported_object_exe::@ba7eb709d0b48779c6c8$",
-                "^link_imported_shared_exe::@ba7eb709d0b48779c6c8$",
-                "^link_imported_static_exe::@ba7eb709d0b48779c6c8$",
-            ],
-            "projectName": "Imported",
-            "minimumCMakeVersion": "3.12",
-            "hasInstallRule": None,
-        },
-        {
-            "source": "^object$",
-            "build": "^object$",
-            "parentSource": "^\\.$",
-            "childSources": None,
-            "targetIds": [
-                "^ALL_BUILD::@5ed5358f70faf8d8af7a$",
-                "^ZERO_CHECK::@5ed5358f70faf8d8af7a$",
-                "^c_object_exe::@5ed5358f70faf8d8af7a$",
-                "^c_object_lib::@5ed5358f70faf8d8af7a$",
-                "^cxx_object_exe::@5ed5358f70faf8d8af7a$",
-                "^cxx_object_lib::@5ed5358f70faf8d8af7a$",
-            ],
-            "projectName": "Object",
-            "minimumCMakeVersion": "3.13",
-            "hasInstallRule": True,
-        },
-        {
-            "source": "^dir$",
-            "build": "^dir$",
-            "parentSource": "^\\.$",
-            "childSources": [
-                "^dir/dir$",
-            ],
-            "targetIds": None,
-            "projectName": "codemodel-v2",
-            "minimumCMakeVersion": "3.12",
-            "hasInstallRule": None,
-        },
-        {
-            "source": "^dir/dir$",
-            "build": "^dir/dir$",
-            "parentSource": "^dir$",
-            "childSources": None,
-            "targetIds": None,
-            "projectName": "codemodel-v2",
-            "minimumCMakeVersion": "3.12",
-            "hasInstallRule": None,
-        },
-        {
-            "source": "^.*/Tests/RunCMake/FileAPIExternalSource$",
-            "build": "^.*/Tests/RunCMake/FileAPI/FileAPIExternalBuild$",
-            "parentSource": "^\\.$",
-            "childSources": None,
-            "targetIds": [
-                "^ALL_BUILD::@[0-9a-f]+$",
-                "^ZERO_CHECK::@[0-9a-f]+$",
-                "^generated_exe::@[0-9a-f]+$",
-            ],
-            "projectName": "External",
-            "minimumCMakeVersion": "3.12",
-            "hasInstallRule": None,
-        },
+        read_codemodel_json_data("directories/top.json"),
+        read_codemodel_json_data("directories/alias.json"),
+        read_codemodel_json_data("directories/custom.json"),
+        read_codemodel_json_data("directories/cxx.json"),
+        read_codemodel_json_data("directories/imported.json"),
+        read_codemodel_json_data("directories/interface.json"),
+        read_codemodel_json_data("directories/object.json"),
+        read_codemodel_json_data("directories/dir.json"),
+        read_codemodel_json_data("directories/dir_dir.json"),
+        read_codemodel_json_data("directories/external.json"),
     ]
 
     if matches(g["name"], "^Visual Studio "):
@@ -646,4430 +554,80 @@
 
 def gen_check_targets(c, g, inSource):
     expected = [
-        {
-            "name": "ALL_BUILD",
-            "id": "^ALL_BUILD::@6890427a1f51a3e7e1df$",
-            "directorySource": "^\\.$",
-            "projectName": "codemodel-v2",
-            "type": "UTILITY",
-            "isGeneratorProvided": True,
-            "sources": [
-                {
-                    "path": "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/CMakeFiles/ALL_BUILD$",
-                    "isGenerated": True,
-                    "sourceGroupName": "",
-                    "compileGroupLanguage": None,
-                    "backtrace": [
-                        {
-                            "file": "^CMakeLists\\.txt$",
-                            "line": None,
-                            "command": None,
-                            "hasParent": False,
-                        },
-                    ],
-                },
-                {
-                    "path": "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/CMakeFiles/ALL_BUILD\\.rule$",
-                    "isGenerated": True,
-                    "sourceGroupName": "CMake Rules",
-                    "compileGroupLanguage": None,
-                    "backtrace": [
-                        {
-                            "file": "^CMakeLists\\.txt$",
-                            "line": None,
-                            "command": None,
-                            "hasParent": False,
-                        },
-                    ],
-                },
-            ],
-            "sourceGroups": [
-                {
-                    "name": "",
-                    "sourcePaths": [
-                        "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/CMakeFiles/ALL_BUILD$",
-                    ],
-                },
-                {
-                    "name": "CMake Rules",
-                    "sourcePaths": [
-                        "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/CMakeFiles/ALL_BUILD\\.rule$",
-                    ],
-                },
-            ],
-            "compileGroups": None,
-            "backtrace": [
-                {
-                    "file": "^CMakeLists\\.txt$",
-                    "line": None,
-                    "command": None,
-                    "hasParent": False,
-                },
-            ],
-            "folder": None,
-            "nameOnDisk": None,
-            "artifacts": None,
-            "build": "^\\.$",
-            "source": "^\\.$",
-            "install": None,
-            "link": None,
-            "archive": None,
-            "dependencies": [
-                {
-                    "id": "^ZERO_CHECK::@6890427a1f51a3e7e1df$",
-                    "backtrace": None,
-                },
-                {
-                    "id": "^interface_exe::@6890427a1f51a3e7e1df$",
-                    "backtrace": None,
-                },
-                {
-                    "id": "^c_lib::@6890427a1f51a3e7e1df$",
-                    "backtrace": None,
-                },
-                {
-                    "id": "^c_exe::@6890427a1f51a3e7e1df$",
-                    "backtrace": None,
-                },
-                {
-                    "id": "^c_shared_lib::@6890427a1f51a3e7e1df$",
-                    "backtrace": None,
-                },
-                {
-                    "id": "^c_shared_exe::@6890427a1f51a3e7e1df$",
-                    "backtrace": None,
-                },
-                {
-                    "id": "^c_static_lib::@6890427a1f51a3e7e1df$",
-                    "backtrace": None,
-                },
-                {
-                    "id": "^c_static_exe::@6890427a1f51a3e7e1df$",
-                    "backtrace": None,
-                },
-                {
-                    "id": "^c_alias_exe::@53632cba2752272bb008$",
-                    "backtrace": None,
-                },
-                {
-                    "id": "^cxx_alias_exe::@53632cba2752272bb008$",
-                    "backtrace": None,
-                },
-                {
-                    "id": "^cxx_lib::@a56b12a3f5c0529fb296$",
-                    "backtrace": None,
-                },
-                {
-                    "id": "^cxx_exe::@a56b12a3f5c0529fb296$",
-                    "backtrace": None,
-                },
-                {
-                    "id": "^cxx_shared_lib::@a56b12a3f5c0529fb296$",
-                    "backtrace": None,
-                },
-                {
-                    "id": "^cxx_shared_exe::@a56b12a3f5c0529fb296$",
-                    "backtrace": None,
-                },
-                {
-                    "id": "^cxx_static_lib::@a56b12a3f5c0529fb296$",
-                    "backtrace": None,
-                },
-                {
-                    "id": "^cxx_static_exe::@a56b12a3f5c0529fb296$",
-                    "backtrace": None,
-                },
-                {
-                    "id": "^c_object_lib::@5ed5358f70faf8d8af7a$",
-                    "backtrace": None,
-                },
-                {
-                    "id": "^c_object_exe::@5ed5358f70faf8d8af7a$",
-                    "backtrace": None,
-                },
-                {
-                    "id": "^cxx_object_lib::@5ed5358f70faf8d8af7a$",
-                    "backtrace": None,
-                },
-                {
-                    "id": "^cxx_object_exe::@5ed5358f70faf8d8af7a$",
-                    "backtrace": None,
-                },
-                {
-                    "id": "^link_imported_exe::@ba7eb709d0b48779c6c8$",
-                    "backtrace": None,
-                },
-                {
-                    "id": "^link_imported_shared_exe::@ba7eb709d0b48779c6c8$",
-                    "backtrace": None,
-                },
-                {
-                    "id": "^link_imported_static_exe::@ba7eb709d0b48779c6c8$",
-                    "backtrace": None,
-                },
-                {
-                    "id": "^link_imported_object_exe::@ba7eb709d0b48779c6c8$",
-                    "backtrace": None,
-                },
-                {
-                    "id": "^link_imported_interface_exe::@ba7eb709d0b48779c6c8$",
-                    "backtrace": None,
-                },
-                {
-                    "id": "^custom_exe::@c11385ffed57b860da63$",
-                    "backtrace": None,
-                },
-                {
-                    "id": "^generated_exe::@[0-9a-f]+$",
-                    "backtrace": None,
-                },
-            ],
-        },
-        {
-            "name": "ZERO_CHECK",
-            "id": "^ZERO_CHECK::@6890427a1f51a3e7e1df$",
-            "directorySource": "^\\.$",
-            "projectName": "codemodel-v2",
-            "type": "UTILITY",
-            "isGeneratorProvided": True,
-            "sources": [
-                {
-                    "path": "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/CMakeFiles/ZERO_CHECK$",
-                    "isGenerated": True,
-                    "sourceGroupName": "",
-                    "compileGroupLanguage": None,
-                    "backtrace": [
-                        {
-                            "file": "^CMakeLists\\.txt$",
-                            "line": None,
-                            "command": None,
-                            "hasParent": False,
-                        },
-                    ],
-                },
-                {
-                    "path": "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/CMakeFiles/ZERO_CHECK\\.rule$",
-                    "isGenerated": True,
-                    "sourceGroupName": "CMake Rules",
-                    "compileGroupLanguage": None,
-                    "backtrace": [
-                        {
-                            "file": "^CMakeLists\\.txt$",
-                            "line": None,
-                            "command": None,
-                            "hasParent": False,
-                        },
-                    ],
-                },
-            ],
-            "sourceGroups": [
-                {
-                    "name": "",
-                    "sourcePaths": [
-                        "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/CMakeFiles/ZERO_CHECK$",
-                    ],
-                },
-                {
-                    "name": "CMake Rules",
-                    "sourcePaths": [
-                        "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/CMakeFiles/ZERO_CHECK\\.rule$",
-                    ],
-                },
-            ],
-            "compileGroups": None,
-            "backtrace": [
-                {
-                    "file": "^CMakeLists\\.txt$",
-                    "line": None,
-                    "command": None,
-                    "hasParent": False,
-                },
-            ],
-            "folder": None,
-            "nameOnDisk": None,
-            "artifacts": None,
-            "build": "^\\.$",
-            "source": "^\\.$",
-            "install": None,
-            "link": None,
-            "archive": None,
-            "dependencies": None,
-        },
-        {
-            "name": "interface_exe",
-            "id": "^interface_exe::@6890427a1f51a3e7e1df$",
-            "directorySource": "^\\.$",
-            "projectName": "codemodel-v2",
-            "type": "EXECUTABLE",
-            "isGeneratorProvided": None,
-            "sources": [
-                {
-                    "path": "^empty\\.c$",
-                    "isGenerated": None,
-                    "sourceGroupName": "Source Files",
-                    "compileGroupLanguage": "C",
-                    "backtrace": [
-                        {
-                            "file": "^include_test\\.cmake$",
-                            "line": 3,
-                            "command": "add_executable",
-                            "hasParent": True,
-                        },
-                        {
-                            "file": "^include_test\\.cmake$",
-                            "line": None,
-                            "command": None,
-                            "hasParent": True,
-                        },
-                        {
-                            "file": "^codemodel-v2\\.cmake$",
-                            "line": 3,
-                            "command": "include",
-                            "hasParent": True,
-                        },
-                        {
-                            "file": "^codemodel-v2\\.cmake$",
-                            "line": None,
-                            "command": None,
-                            "hasParent": True,
-                        },
-                        {
-                            "file": "^CMakeLists\\.txt$",
-                            "line": 3,
-                            "command": "include",
-                            "hasParent": True,
-                        },
-                        {
-                            "file": "^CMakeLists\\.txt$",
-                            "line": None,
-                            "command": None,
-                            "hasParent": False,
-                        },
-                    ],
-                },
-            ],
-            "sourceGroups": [
-                {
-                    "name": "Source Files",
-                    "sourcePaths": [
-                        "^empty\\.c$",
-                    ],
-                },
-            ],
-            "compileGroups": [
-                {
-                    "language": "C",
-                    "sourcePaths": [
-                        "^empty\\.c$",
-                    ],
-                    "includes": None,
-                    "defines": [
-                        {
-                            "define": "interface_exe_EXPORTS",
-                            "backtrace": None,
-                        },
-                    ],
-                    "compileCommandFragments": None,
-                },
-            ],
-            "backtrace": [
-                {
-                    "file": "^include_test\\.cmake$",
-                    "line": 3,
-                    "command": "add_executable",
-                    "hasParent": True,
-                },
-                {
-                    "file": "^include_test\\.cmake$",
-                    "line": None,
-                    "command": None,
-                    "hasParent": True,
-                },
-                {
-                    "file": "^codemodel-v2\\.cmake$",
-                    "line": 3,
-                    "command": "include",
-                    "hasParent": True,
-                },
-                {
-                    "file": "^codemodel-v2\\.cmake$",
-                    "line": None,
-                    "command": None,
-                    "hasParent": True,
-                },
-                {
-                    "file": "^CMakeLists\\.txt$",
-                    "line": 3,
-                    "command": "include",
-                    "hasParent": True,
-                },
-                {
-                    "file": "^CMakeLists\\.txt$",
-                    "line": None,
-                    "command": None,
-                    "hasParent": False,
-                },
-            ],
-            "folder": None,
-            "nameOnDisk": "^my_interface_exe\\.myexe$",
-            "artifacts": [
-                {
-                    "path": "^bin/((Debug|Release|RelWithDebInfo|MinSizeRel)/)?my_interface_exe\\.myexe$",
-                    "_dllExtra": False,
-                },
-                {
-                    "path": "^lib/my_interface_exe\\.imp$",
-                    "_aixExtra": True,
-                    "_dllExtra": False,
-                },
-                {
-                    "path": "^lib/((Debug|Release|RelWithDebInfo|MinSizeRel)/)?(lib)?my_interface_exe\\.(dll\\.a|lib)$",
-                    "_dllExtra": True,
-                },
-                {
-                    "path": "^bin/((Debug|Release|RelWithDebInfo|MinSizeRel)/)?my_interface_exe\\.pdb$",
-                    "_dllExtra": True,
-                },
-            ],
-            "build": "^\\.$",
-            "source": "^\\.$",
-            "install": None,
-            "link": {
-                "language": "C",
-                "lto": None,
-                "commandFragments": None,
-            },
-            "archive": None,
-            "dependencies": [
-                {
-                    "id": "^ZERO_CHECK::@6890427a1f51a3e7e1df$",
-                    "backtrace": None,
-                },
-            ],
-        },
-        {
-            "name": "c_lib",
-            "id": "^c_lib::@6890427a1f51a3e7e1df$",
-            "directorySource": "^\\.$",
-            "projectName": "codemodel-v2",
-            "type": "STATIC_LIBRARY",
-            "isGeneratorProvided": None,
-            "sources": [
-                {
-                    "path": "^empty\\.c$",
-                    "isGenerated": None,
-                    "sourceGroupName": "Source Files",
-                    "compileGroupLanguage": "C",
-                    "backtrace": [
-                        {
-                            "file": "^codemodel-v2\\.cmake$",
-                            "line": 5,
-                            "command": "add_library",
-                            "hasParent": True,
-                        },
-                        {
-                            "file": "^codemodel-v2\\.cmake$",
-                            "line": None,
-                            "command": None,
-                            "hasParent": True,
-                        },
-                        {
-                            "file": "^CMakeLists\\.txt$",
-                            "line": 3,
-                            "command": "include",
-                            "hasParent": True,
-                        },
-                        {
-                            "file": "^CMakeLists\\.txt$",
-                            "line": None,
-                            "command": None,
-                            "hasParent": False,
-                        },
-                    ],
-                },
-            ],
-            "sourceGroups": [
-                {
-                    "name": "Source Files",
-                    "sourcePaths": [
-                        "^empty\\.c$",
-                    ],
-                },
-            ],
-            "compileGroups": [
-                {
-                    "language": "C",
-                    "sourcePaths": [
-                        "^empty\\.c$",
-                    ],
-                    "includes": None,
-                    "defines": None,
-                    "compileCommandFragments": None,
-                },
-            ],
-            "backtrace": [
-                {
-                    "file": "^codemodel-v2\\.cmake$",
-                    "line": 5,
-                    "command": "add_library",
-                    "hasParent": True,
-                },
-                {
-                    "file": "^codemodel-v2\\.cmake$",
-                    "line": None,
-                    "command": None,
-                    "hasParent": True,
-                },
-                {
-                    "file": "^CMakeLists\\.txt$",
-                    "line": 3,
-                    "command": "include",
-                    "hasParent": True,
-                },
-                {
-                    "file": "^CMakeLists\\.txt$",
-                    "line": None,
-                    "command": None,
-                    "hasParent": False,
-                },
-            ],
-            "folder": None,
-            "nameOnDisk": "^(lib)?c_lib\\.(a|lib)$",
-            "artifacts": [
-                {
-                    "path": "^((Debug|Release|RelWithDebInfo|MinSizeRel)/)?(lib)?c_lib\\.(a|lib)$",
-                    "_dllExtra": False,
-                },
-            ],
-            "build": "^\\.$",
-            "source": "^\\.$",
-            "install": None,
-            "link": None,
-            "archive": {
-                "lto": None,
-            },
-            "dependencies": [
-                {
-                    "id": "^ZERO_CHECK::@6890427a1f51a3e7e1df$",
-                    "backtrace": None,
-                },
-            ],
-        },
-        {
-            "name": "c_exe",
-            "id": "^c_exe::@6890427a1f51a3e7e1df$",
-            "directorySource": "^\\.$",
-            "projectName": "codemodel-v2",
-            "type": "EXECUTABLE",
-            "isGeneratorProvided": None,
-            "sources": [
-                {
-                    "path": "^empty\\.c$",
-                    "isGenerated": None,
-                    "sourceGroupName": "Source Files",
-                    "compileGroupLanguage": "C",
-                    "backtrace": [
-                        {
-                            "file": "^codemodel-v2\\.cmake$",
-                            "line": 6,
-                            "command": "add_executable",
-                            "hasParent": True,
-                        },
-                        {
-                            "file": "^codemodel-v2\\.cmake$",
-                            "line": None,
-                            "command": None,
-                            "hasParent": True,
-                        },
-                        {
-                            "file": "^CMakeLists\\.txt$",
-                            "line": 3,
-                            "command": "include",
-                            "hasParent": True,
-                        },
-                        {
-                            "file": "^CMakeLists\\.txt$",
-                            "line": None,
-                            "command": None,
-                            "hasParent": False,
-                        },
-                    ],
-                },
-            ],
-            "sourceGroups": [
-                {
-                    "name": "Source Files",
-                    "sourcePaths": [
-                        "^empty\\.c$",
-                    ],
-                },
-            ],
-            "compileGroups": [
-                {
-                    "language": "C",
-                    "sourcePaths": [
-                        "^empty\\.c$",
-                    ],
-                    "includes": None,
-                    "defines": None,
-                    "compileCommandFragments": None,
-                },
-            ],
-            "backtrace": [
-                {
-                    "file": "^codemodel-v2\\.cmake$",
-                    "line": 6,
-                    "command": "add_executable",
-                    "hasParent": True,
-                },
-                {
-                    "file": "^codemodel-v2\\.cmake$",
-                    "line": None,
-                    "command": None,
-                    "hasParent": True,
-                },
-                {
-                    "file": "^CMakeLists\\.txt$",
-                    "line": 3,
-                    "command": "include",
-                    "hasParent": True,
-                },
-                {
-                    "file": "^CMakeLists\\.txt$",
-                    "line": None,
-                    "command": None,
-                    "hasParent": False,
-                },
-            ],
-            "folder": None,
-            "nameOnDisk": "^c_exe(\\.exe)?$",
-            "artifacts": [
-                {
-                    "path": "^((Debug|Release|RelWithDebInfo|MinSizeRel)/)?c_exe(\\.exe)?$",
-                    "_dllExtra": False,
-                },
-                {
-                    "path": "^((Debug|Release|RelWithDebInfo|MinSizeRel)/)?c_exe\\.pdb$",
-                    "_dllExtra": True,
-                },
-            ],
-            "build": "^\\.$",
-            "source": "^\\.$",
-            "install": None,
-            "link": {
-                "language": "C",
-                "lto": None,
-                "commandFragments": None,
-            },
-            "archive": None,
-            "dependencies": [
-                {
-                    "id": "^c_lib::@6890427a1f51a3e7e1df$",
-                    "backtrace": [
-                        {
-                            "file": "^codemodel-v2\\.cmake$",
-                            "line": 7,
-                            "command": "target_link_libraries",
-                            "hasParent": True,
-                        },
-                        {
-                            "file": "^codemodel-v2\\.cmake$",
-                            "line": None,
-                            "command": None,
-                            "hasParent": True,
-                        },
-                        {
-                            "file": "^CMakeLists\\.txt$",
-                            "line": 3,
-                            "command": "include",
-                            "hasParent": True,
-                        },
-                        {
-                            "file": "^CMakeLists\\.txt$",
-                            "line": None,
-                            "command": None,
-                            "hasParent": False,
-                        },
-                    ],
-                },
-                {
-                    "id": "^ZERO_CHECK::@6890427a1f51a3e7e1df$",
-                    "backtrace": None,
-                },
-            ],
-        },
-        {
-            "name": "c_shared_lib",
-            "id": "^c_shared_lib::@6890427a1f51a3e7e1df$",
-            "directorySource": "^\\.$",
-            "projectName": "codemodel-v2",
-            "type": "SHARED_LIBRARY",
-            "isGeneratorProvided": None,
-            "sources": [
-                {
-                    "path": "^empty\\.c$",
-                    "isGenerated": None,
-                    "sourceGroupName": "Source Files",
-                    "compileGroupLanguage": "C",
-                    "backtrace": [
-                        {
-                            "file": "^codemodel-v2\\.cmake$",
-                            "line": 9,
-                            "command": "add_library",
-                            "hasParent": True,
-                        },
-                        {
-                            "file": "^codemodel-v2\\.cmake$",
-                            "line": None,
-                            "command": None,
-                            "hasParent": True,
-                        },
-                        {
-                            "file": "^CMakeLists\\.txt$",
-                            "line": 3,
-                            "command": "include",
-                            "hasParent": True,
-                        },
-                        {
-                            "file": "^CMakeLists\\.txt$",
-                            "line": None,
-                            "command": None,
-                            "hasParent": False,
-                        },
-                    ],
-                },
-            ],
-            "sourceGroups": [
-                {
-                    "name": "Source Files",
-                    "sourcePaths": [
-                        "^empty\\.c$",
-                    ],
-                },
-            ],
-            "compileGroups": [
-                {
-                    "language": "C",
-                    "sourcePaths": [
-                        "^empty\\.c$",
-                    ],
-                    "includes": None,
-                    "defines": [
-                        {
-                            "define": "c_shared_lib_EXPORTS",
-                            "backtrace": None,
-                        },
-                    ],
-                    "compileCommandFragments": None,
-                },
-            ],
-            "backtrace": [
-                {
-                    "file": "^codemodel-v2\\.cmake$",
-                    "line": 9,
-                    "command": "add_library",
-                    "hasParent": True,
-                },
-                {
-                    "file": "^codemodel-v2\\.cmake$",
-                    "line": None,
-                    "command": None,
-                    "hasParent": True,
-                },
-                {
-                    "file": "^CMakeLists\\.txt$",
-                    "line": 3,
-                    "command": "include",
-                    "hasParent": True,
-                },
-                {
-                    "file": "^CMakeLists\\.txt$",
-                    "line": None,
-                    "command": None,
-                    "hasParent": False,
-                },
-            ],
-            "folder": None,
-            "nameOnDisk": "^(lib|cyg)?c_shared_lib\\.(so|dylib|dll)$",
-            "artifacts": [
-                {
-                    "path": "^lib/((Debug|Release|RelWithDebInfo|MinSizeRel)/)?(lib|cyg)?c_shared_lib\\.(so|dylib|dll)$",
-                    "_dllExtra": False,
-                },
-                {
-                    "path": "^((Debug|Release|RelWithDebInfo|MinSizeRel)/)?(lib)?c_shared_lib\\.(dll\\.a|lib)$",
-                    "_dllExtra": True,
-                },
-                {
-                    "path": "^lib/((Debug|Release|RelWithDebInfo|MinSizeRel)/)?(lib|cyg)?c_shared_lib\\.pdb$",
-                    "_dllExtra": True,
-                },
-            ],
-            "build": "^\\.$",
-            "source": "^\\.$",
-            "install": None,
-            "link": {
-                "language": "C",
-                "lto": True,
-                "commandFragments": None,
-            },
-            "archive": None,
-            "dependencies": [
-                {
-                    "id": "^ZERO_CHECK::@6890427a1f51a3e7e1df$",
-                    "backtrace": None,
-                },
-            ],
-        },
-        {
-            "name": "c_shared_exe",
-            "id": "^c_shared_exe::@6890427a1f51a3e7e1df$",
-            "directorySource": "^\\.$",
-            "projectName": "codemodel-v2",
-            "type": "EXECUTABLE",
-            "isGeneratorProvided": None,
-            "sources": [
-                {
-                    "path": "^empty\\.c$",
-                    "isGenerated": None,
-                    "sourceGroupName": "Source Files",
-                    "compileGroupLanguage": "C",
-                    "backtrace": [
-                        {
-                            "file": "^codemodel-v2\\.cmake$",
-                            "line": 10,
-                            "command": "add_executable",
-                            "hasParent": True,
-                        },
-                        {
-                            "file": "^codemodel-v2\\.cmake$",
-                            "line": None,
-                            "command": None,
-                            "hasParent": True,
-                        },
-                        {
-                            "file": "^CMakeLists\\.txt$",
-                            "line": 3,
-                            "command": "include",
-                            "hasParent": True,
-                        },
-                        {
-                            "file": "^CMakeLists\\.txt$",
-                            "line": None,
-                            "command": None,
-                            "hasParent": False,
-                        },
-                    ],
-                },
-            ],
-            "sourceGroups": [
-                {
-                    "name": "Source Files",
-                    "sourcePaths": [
-                        "^empty\\.c$",
-                    ],
-                },
-            ],
-            "compileGroups": [
-                {
-                    "language": "C",
-                    "sourcePaths": [
-                        "^empty\\.c$",
-                    ],
-                    "includes": None,
-                    "defines": None,
-					"compileCommandFragments": None,
-                },
-            ],
-            "backtrace": [
-                {
-                    "file": "^codemodel-v2\\.cmake$",
-                    "line": 10,
-                    "command": "add_executable",
-                    "hasParent": True,
-                },
-                {
-                    "file": "^codemodel-v2\\.cmake$",
-                    "line": None,
-                    "command": None,
-                    "hasParent": True,
-                },
-                {
-                    "file": "^CMakeLists\\.txt$",
-                    "line": 3,
-                    "command": "include",
-                    "hasParent": True,
-                },
-                {
-                    "file": "^CMakeLists\\.txt$",
-                    "line": None,
-                    "command": None,
-                    "hasParent": False,
-                },
-            ],
-            "folder": None,
-            "nameOnDisk": "^c_shared_exe(\\.exe)?$",
-            "artifacts": [
-                {
-                    "path": "^((Debug|Release|RelWithDebInfo|MinSizeRel)/)?c_shared_exe(\\.exe)?$",
-                    "_dllExtra": False,
-                },
-                {
-                    "path": "^((Debug|Release|RelWithDebInfo|MinSizeRel)/)?c_shared_exe\\.pdb$",
-                    "_dllExtra": True,
-                },
-            ],
-            "build": "^\\.$",
-            "source": "^\\.$",
-            "install": None,
-            "link": {
-                "language": "C",
-                "lto": True,
-                "commandFragments": None,
-            },
-            "archive": None,
-            "dependencies": [
-                {
-                    "id": "^c_shared_lib::@6890427a1f51a3e7e1df$",
-                    "backtrace": [
-                        {
-                            "file": "^codemodel-v2\\.cmake$",
-                            "line": 11,
-                            "command": "target_link_libraries",
-                            "hasParent": True,
-                        },
-                        {
-                            "file": "^codemodel-v2\\.cmake$",
-                            "line": None,
-                            "command": None,
-                            "hasParent": True,
-                        },
-                        {
-                            "file": "^CMakeLists\\.txt$",
-                            "line": 3,
-                            "command": "include",
-                            "hasParent": True,
-                        },
-                        {
-                            "file": "^CMakeLists\\.txt$",
-                            "line": None,
-                            "command": None,
-                            "hasParent": False,
-                        },
-                    ],
-                },
-                {
-                    "id": "^ZERO_CHECK::@6890427a1f51a3e7e1df$",
-                    "backtrace": None,
-                },
-            ],
-        },
-        {
-            "name": "c_static_lib",
-            "id": "^c_static_lib::@6890427a1f51a3e7e1df$",
-            "directorySource": "^\\.$",
-            "projectName": "codemodel-v2",
-            "type": "STATIC_LIBRARY",
-            "isGeneratorProvided": None,
-            "sources": [
-                {
-                    "path": "^empty\\.c$",
-                    "isGenerated": None,
-                    "sourceGroupName": "Source Files",
-                    "compileGroupLanguage": "C",
-                    "backtrace": [
-                        {
-                            "file": "^codemodel-v2\\.cmake$",
-                            "line": 13,
-                            "command": "add_library",
-                            "hasParent": True,
-                        },
-                        {
-                            "file": "^codemodel-v2\\.cmake$",
-                            "line": None,
-                            "command": None,
-                            "hasParent": True,
-                        },
-                        {
-                            "file": "^CMakeLists\\.txt$",
-                            "line": 3,
-                            "command": "include",
-                            "hasParent": True,
-                        },
-                        {
-                            "file": "^CMakeLists\\.txt$",
-                            "line": None,
-                            "command": None,
-                            "hasParent": False,
-                        },
-                    ],
-                },
-            ],
-            "sourceGroups": [
-                {
-                    "name": "Source Files",
-                    "sourcePaths": [
-                        "^empty\\.c$",
-                    ],
-                },
-            ],
-            "compileGroups": [
-                {
-                    "language": "C",
-                    "sourcePaths": [
-                        "^empty\\.c$",
-                    ],
-                    "includes": None,
-                    "defines": None,
-                    "compileCommandFragments": None,
-                },
-            ],
-            "backtrace": [
-                {
-                    "file": "^codemodel-v2\\.cmake$",
-                    "line": 13,
-                    "command": "add_library",
-                    "hasParent": True,
-                },
-                {
-                    "file": "^codemodel-v2\\.cmake$",
-                    "line": None,
-                    "command": None,
-                    "hasParent": True,
-                },
-                {
-                    "file": "^CMakeLists\\.txt$",
-                    "line": 3,
-                    "command": "include",
-                    "hasParent": True,
-                },
-                {
-                    "file": "^CMakeLists\\.txt$",
-                    "line": None,
-                    "command": None,
-                    "hasParent": False,
-                },
-            ],
-            "folder": None,
-            "nameOnDisk": "^(lib)?c_static_lib\\.(a|lib)$",
-            "artifacts": [
-                {
-                    "path": "^((Debug|Release|RelWithDebInfo|MinSizeRel)/)?(lib)?c_static_lib\\.(a|lib)$",
-                    "_dllExtra": False,
-                },
-            ],
-            "build": "^\\.$",
-            "source": "^\\.$",
-            "install": None,
-            "link": None,
-            "archive": {
-                "lto": True,
-            },
-            "dependencies": [
-                {
-                    "id": "^ZERO_CHECK::@6890427a1f51a3e7e1df$",
-                    "backtrace": None,
-                },
-            ],
-        },
-        {
-            "name": "c_static_exe",
-            "id": "^c_static_exe::@6890427a1f51a3e7e1df$",
-            "directorySource": "^\\.$",
-            "projectName": "codemodel-v2",
-            "type": "EXECUTABLE",
-            "isGeneratorProvided": None,
-            "sources": [
-                {
-                    "path": "^empty\\.c$",
-                    "isGenerated": None,
-                    "sourceGroupName": "Source Files",
-                    "compileGroupLanguage": "C",
-                    "backtrace": [
-                        {
-                            "file": "^codemodel-v2\\.cmake$",
-                            "line": 14,
-                            "command": "add_executable",
-                            "hasParent": True,
-                        },
-                        {
-                            "file": "^codemodel-v2\\.cmake$",
-                            "line": None,
-                            "command": None,
-                            "hasParent": True,
-                        },
-                        {
-                            "file": "^CMakeLists\\.txt$",
-                            "line": 3,
-                            "command": "include",
-                            "hasParent": True,
-                        },
-                        {
-                            "file": "^CMakeLists\\.txt$",
-                            "line": None,
-                            "command": None,
-                            "hasParent": False,
-                        },
-                    ],
-                },
-            ],
-            "sourceGroups": [
-                {
-                    "name": "Source Files",
-                    "sourcePaths": [
-                        "^empty\\.c$",
-                    ],
-                },
-            ],
-            "compileGroups": [
-                {
-                    "language": "C",
-                    "sourcePaths": [
-                        "^empty\\.c$",
-                    ],
-                    "includes": None,
-                    "defines": None,
-                    "compileCommandFragments": None,
-                },
-            ],
-            "backtrace": [
-                {
-                    "file": "^codemodel-v2\\.cmake$",
-                    "line": 14,
-                    "command": "add_executable",
-                    "hasParent": True,
-                },
-                {
-                    "file": "^codemodel-v2\\.cmake$",
-                    "line": None,
-                    "command": None,
-                    "hasParent": True,
-                },
-                {
-                    "file": "^CMakeLists\\.txt$",
-                    "line": 3,
-                    "command": "include",
-                    "hasParent": True,
-                },
-                {
-                    "file": "^CMakeLists\\.txt$",
-                    "line": None,
-                    "command": None,
-                    "hasParent": False,
-                },
-            ],
-            "folder": None,
-            "nameOnDisk": "^c_static_exe(\\.exe)?$",
-            "artifacts": [
-                {
-                    "path": "^((Debug|Release|RelWithDebInfo|MinSizeRel)/)?c_static_exe(\\.exe)?$",
-                    "_dllExtra": False,
-                },
-                {
-                    "path": "^((Debug|Release|RelWithDebInfo|MinSizeRel)/)?c_static_exe\\.pdb$",
-                    "_dllExtra": True,
-                },
-            ],
-            "build": "^\\.$",
-            "source": "^\\.$",
-            "install": None,
-            "link": {
-                "language": "C",
-                "lto": None,
-                "commandFragments": None,
-            },
-            "archive": None,
-            "dependencies": [
-                {
-                    "id": "^c_static_lib::@6890427a1f51a3e7e1df$",
-                    "backtrace": [
-                        {
-                            "file": "^codemodel-v2\\.cmake$",
-                            "line": 15,
-                            "command": "target_link_libraries",
-                            "hasParent": True,
-                        },
-                        {
-                            "file": "^codemodel-v2\\.cmake$",
-                            "line": None,
-                            "command": None,
-                            "hasParent": True,
-                        },
-                        {
-                            "file": "^CMakeLists\\.txt$",
-                            "line": 3,
-                            "command": "include",
-                            "hasParent": True,
-                        },
-                        {
-                            "file": "^CMakeLists\\.txt$",
-                            "line": None,
-                            "command": None,
-                            "hasParent": False,
-                        },
-                    ],
-                },
-                {
-                    "id": "^ZERO_CHECK::@6890427a1f51a3e7e1df$",
-                    "backtrace": None,
-                },
-            ],
-        },
-        {
-            "name": "ALL_BUILD",
-            "id": "^ALL_BUILD::@a56b12a3f5c0529fb296$",
-            "directorySource": "^cxx$",
-            "projectName": "Cxx",
-            "type": "UTILITY",
-            "isGeneratorProvided": True,
-            "sources": [
-                {
-                    "path": "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/cxx/CMakeFiles/ALL_BUILD$",
-                    "isGenerated": True,
-                    "sourceGroupName": "",
-                    "compileGroupLanguage": None,
-                    "backtrace": [
-                        {
-                            "file": "^cxx/CMakeLists\\.txt$",
-                            "line": None,
-                            "command": None,
-                            "hasParent": False,
-                        },
-                    ],
-                },
-                {
-                    "path": "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/cxx/CMakeFiles/ALL_BUILD\\.rule$",
-                    "isGenerated": True,
-                    "sourceGroupName": "CMake Rules",
-                    "compileGroupLanguage": None,
-                    "backtrace": [
-                        {
-                            "file": "^cxx/CMakeLists\\.txt$",
-                            "line": None,
-                            "command": None,
-                            "hasParent": False,
-                        },
-                    ],
-                },
-            ],
-            "sourceGroups": [
-                {
-                    "name": "",
-                    "sourcePaths": [
-                        "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/cxx/CMakeFiles/ALL_BUILD$",
-                    ],
-                },
-                {
-                    "name": "CMake Rules",
-                    "sourcePaths": [
-                        "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/cxx/CMakeFiles/ALL_BUILD\\.rule$",
-                    ],
-                },
-            ],
-            "compileGroups": None,
-            "backtrace": [
-                {
-                    "file": "^cxx/CMakeLists\\.txt$",
-                    "line": None,
-                    "command": None,
-                    "hasParent": False,
-                },
-            ],
-            "folder": None,
-            "nameOnDisk": None,
-            "artifacts": None,
-            "build": "^cxx$",
-            "source": "^cxx$",
-            "install": None,
-            "link": None,
-            "archive": None,
-            "dependencies": [
-                {
-                    "id": "^ZERO_CHECK::@a56b12a3f5c0529fb296$",
-                    "backtrace": None,
-                },
-                {
-                    "id": "^cxx_lib::@a56b12a3f5c0529fb296$",
-                    "backtrace": None,
-                },
-                {
-                    "id": "^cxx_exe::@a56b12a3f5c0529fb296$",
-                    "backtrace": None,
-                },
-                {
-                    "id": "^cxx_shared_lib::@a56b12a3f5c0529fb296$",
-                    "backtrace": None,
-                },
-                {
-                    "id": "^cxx_shared_exe::@a56b12a3f5c0529fb296$",
-                    "backtrace": None,
-                },
-                {
-                    "id": "^cxx_static_lib::@a56b12a3f5c0529fb296$",
-                    "backtrace": None,
-                },
-                {
-                    "id": "^cxx_static_exe::@a56b12a3f5c0529fb296$",
-                    "backtrace": None,
-                },
-            ],
-        },
-        {
-            "name": "ZERO_CHECK",
-            "id": "^ZERO_CHECK::@a56b12a3f5c0529fb296$",
-            "directorySource": "^cxx$",
-            "projectName": "Cxx",
-            "type": "UTILITY",
-            "isGeneratorProvided": True,
-            "sources": [
-                {
-                    "path": "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/cxx/CMakeFiles/ZERO_CHECK$",
-                    "isGenerated": True,
-                    "sourceGroupName": "",
-                    "compileGroupLanguage": None,
-                    "backtrace": [
-                        {
-                            "file": "^cxx/CMakeLists\\.txt$",
-                            "line": None,
-                            "command": None,
-                            "hasParent": False,
-                        },
-                    ],
-                },
-                {
-                    "path": "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/cxx/CMakeFiles/ZERO_CHECK\\.rule$",
-                    "isGenerated": True,
-                    "sourceGroupName": "CMake Rules",
-                    "compileGroupLanguage": None,
-                    "backtrace": [
-                        {
-                            "file": "^cxx/CMakeLists\\.txt$",
-                            "line": None,
-                            "command": None,
-                            "hasParent": False,
-                        },
-                    ],
-                },
-            ],
-            "sourceGroups": [
-                {
-                    "name": "",
-                    "sourcePaths": [
-                        "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/cxx/CMakeFiles/ZERO_CHECK$",
-                    ],
-                },
-                {
-                    "name": "CMake Rules",
-                    "sourcePaths": [
-                        "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/cxx/CMakeFiles/ZERO_CHECK\\.rule$",
-                    ],
-                },
-            ],
-            "compileGroups": None,
-            "backtrace": [
-                {
-                    "file": "^cxx/CMakeLists\\.txt$",
-                    "line": None,
-                    "command": None,
-                    "hasParent": False,
-                },
-            ],
-            "folder": None,
-            "nameOnDisk": None,
-            "artifacts": None,
-            "build": "^cxx$",
-            "source": "^cxx$",
-            "install": None,
-            "link": None,
-            "archive": None,
-            "dependencies": None,
-        },
-        {
-            "name": "cxx_lib",
-            "id": "^cxx_lib::@a56b12a3f5c0529fb296$",
-            "directorySource": "^cxx$",
-            "projectName": "Cxx",
-            "type": "STATIC_LIBRARY",
-            "isGeneratorProvided": None,
-            "sources": [
-                {
-                    "path": "^empty\\.cxx$",
-                    "isGenerated": None,
-                    "sourceGroupName": "Source Files",
-                    "compileGroupLanguage": "CXX",
-                    "backtrace": [
-                        {
-                            "file": "^cxx/CMakeLists\\.txt$",
-                            "line": 4,
-                            "command": "add_library",
-                            "hasParent": True,
-                        },
-                        {
-                            "file": "^cxx/CMakeLists\\.txt$",
-                            "line": None,
-                            "command": None,
-                            "hasParent": False,
-                        },
-                    ],
-                },
-            ],
-            "sourceGroups": [
-                {
-                    "name": "Source Files",
-                    "sourcePaths": [
-                        "^empty\\.cxx$",
-                    ],
-                },
-            ],
-            "compileGroups": [
-                {
-                    "language": "CXX",
-                    "sourcePaths": [
-                        "^empty\\.cxx$",
-                    ],
-                    "includes": None,
-                    "defines": None,
-                    "compileCommandFragments": None,
-                },
-            ],
-            "backtrace": [
-                {
-                    "file": "^cxx/CMakeLists\\.txt$",
-                    "line": 4,
-                    "command": "add_library",
-                    "hasParent": True,
-                },
-                {
-                    "file": "^cxx/CMakeLists\\.txt$",
-                    "line": None,
-                    "command": None,
-                    "hasParent": False,
-                },
-            ],
-            "folder": None,
-            "nameOnDisk": "^(lib)?cxx_lib\\.(a|lib)$",
-            "artifacts": [
-                {
-                    "path": "^cxx/((Debug|Release|RelWithDebInfo|MinSizeRel)/)?(lib)?cxx_lib\\.(a|lib)$",
-                    "_dllExtra": False,
-                },
-            ],
-            "build": "^cxx$",
-            "source": "^cxx$",
-            "install": None,
-            "link": None,
-            "archive": {
-                "lto": None,
-            },
-            "dependencies": [
-                {
-                    "id": "^ZERO_CHECK::@a56b12a3f5c0529fb296$",
-                    "backtrace": None,
-                },
-            ],
-        },
-        {
-            "name": "cxx_exe",
-            "id": "^cxx_exe::@a56b12a3f5c0529fb296$",
-            "directorySource": "^cxx$",
-            "projectName": "Cxx",
-            "type": "EXECUTABLE",
-            "isGeneratorProvided": None,
-            "sources": [
-                {
-                    "path": "^empty\\.cxx$",
-                    "isGenerated": None,
-                    "sourceGroupName": "Source Files",
-                    "compileGroupLanguage": "CXX",
-                    "backtrace": [
-                        {
-                            "file": "^cxx/CMakeLists\\.txt$",
-                            "line": 5,
-                            "command": "add_executable",
-                            "hasParent": True,
-                        },
-                        {
-                            "file": "^cxx/CMakeLists\\.txt$",
-                            "line": None,
-                            "command": None,
-                            "hasParent": False,
-                        },
-                    ],
-                },
-            ],
-            "sourceGroups": [
-                {
-                    "name": "Source Files",
-                    "sourcePaths": [
-                        "^empty\\.cxx$",
-                    ],
-                },
-            ],
-            "compileGroups": [
-                {
-                    "language": "CXX",
-                    "sourcePaths": [
-                        "^empty\\.cxx$",
-                    ],
-                    "includes": None,
-                    "defines": None,
-                    "compileCommandFragments": [
-                        {
-                            "fragment" : "TargetCompileOptions",
-							"backtrace": [
-                                {
-                                    "file": "^cxx/CMakeLists\\.txt$",
-                                    "line": 17,
-                                    "command": "target_compile_options",
-                                    "hasParent": True,
-                                },
-								{
-                                    "file" : "^cxx/CMakeLists\\.txt$",
-                                    "line": None,
-                                    "command": None,
-                                    "hasParent": False,
-                                },
-                            ],
-                        }
-                    ],
-                },
-            ],
-            "backtrace": [
-                {
-                    "file": "^cxx/CMakeLists\\.txt$",
-                    "line": 5,
-                    "command": "add_executable",
-                    "hasParent": True,
-                },
-                {
-                    "file": "^cxx/CMakeLists\\.txt$",
-                    "line": None,
-                    "command": None,
-                    "hasParent": False,
-                },
-            ],
-            "folder": "bin",
-            "nameOnDisk": "^cxx_exe(\\.exe)?$",
-            "artifacts": [
-                {
-                    "path": "^cxx/((Debug|Release|RelWithDebInfo|MinSizeRel)/)?cxx_exe(\\.exe)?$",
-                    "_dllExtra": False,
-                },
-                {
-                    "path": "^cxx/((Debug|Release|RelWithDebInfo|MinSizeRel)/)?cxx_exe\\.pdb$",
-                    "_dllExtra": True,
-                },
-            ],
-            "build": "^cxx$",
-            "source": "^cxx$",
-            "install": {
-                "prefix": "^(/usr/local|[A-Za-z]:.*/codemodel-v2)$",
-                "destinations": [
-                    {
-                        "path": "bin",
-                        "backtrace": [
-                            {
-                                "file": "^codemodel-v2\\.cmake$",
-                                "line": 37,
-                                "command": "install",
-                                "hasParent": True,
-                            },
-                            {
-                                "file": "^codemodel-v2\\.cmake$",
-                                "line": None,
-                                "command": None,
-                                "hasParent": True,
-                            },
-                            {
-                                "file": "^CMakeLists\\.txt$",
-                                "line": 3,
-                                "command": "include",
-                                "hasParent": True,
-                            },
-                            {
-                                "file": "^CMakeLists\\.txt$",
-                                "line": None,
-                                "command": None,
-                                "hasParent": False,
-                            },
-                        ],
-                    },
-                ],
-            },
-            "link": {
-                "language": "CXX",
-                "lto": None,
-                "commandFragments": [
-                    {
-                        "fragment" : "TargetLinkOptions",
-                        "role" : "flags",
-                        "backtrace": [
-                            {
-                                "file": "^cxx/CMakeLists\\.txt$",
-                                "line": 18,
-                                "command": "target_link_options",
-                                "hasParent": True,
-                            },
-                            {
-                                "file" : "^cxx/CMakeLists\\.txt$",
-                                "line": None,
-                                "command": None,
-                                "hasParent": False,
-                            },
-                        ],
-                    },
-                    {
-                        "fragment" : ".*TargetLinkDir\\\"?$",
-                        "role" : "libraryPath",
-                        "backtrace": [
-                            {
-                                "file": "^cxx/CMakeLists\\.txt$",
-                                "line": 19,
-                                "command": "target_link_directories",
-                                "hasParent": True,
-                            },
-                            {
-                                "file" : "^cxx/CMakeLists\\.txt$",
-                                "line": None,
-                                "command": None,
-                                "hasParent": False,
-                            },
-                        ],
-                    },
-                    {
-                        "fragment" : ".*cxx_lib.*",
-                        "role" : "libraries",
-                        "backtrace": [
-                            {
-                                "file": "^cxx/CMakeLists\\.txt$",
-                                "line": 6,
-                                "command": "target_link_libraries",
-                                "hasParent": True,
-                            },
-                            {
-                                "file" : "^cxx/CMakeLists\\.txt$",
-                                "line": None,
-                                "command": None,
-                                "hasParent": False,
-                            },
-                        ],
-                    },
-                ],
-            },
-            "archive": None,
-            "dependencies": [
-                {
-                    "id": "^cxx_lib::@a56b12a3f5c0529fb296$",
-                    "backtrace": [
-                        {
-                            "file": "^cxx/CMakeLists\\.txt$",
-                            "line": 6,
-                            "command": "target_link_libraries",
-                            "hasParent": True,
-                        },
-                        {
-                            "file": "^cxx/CMakeLists\\.txt$",
-                            "line": None,
-                            "command": None,
-                            "hasParent": False,
-                        },
-                    ],
-                },
-                {
-                    "id": "^ZERO_CHECK::@a56b12a3f5c0529fb296$",
-                    "backtrace": None,
-                },
-            ],
-        },
-        {
-            "name": "cxx_shared_lib",
-            "id": "^cxx_shared_lib::@a56b12a3f5c0529fb296$",
-            "directorySource": "^cxx$",
-            "projectName": "Cxx",
-            "type": "SHARED_LIBRARY",
-            "isGeneratorProvided": None,
-            "sources": [
-                {
-                    "path": "^empty\\.cxx$",
-                    "isGenerated": None,
-                    "sourceGroupName": "Source Files",
-                    "compileGroupLanguage": "CXX",
-                    "backtrace": [
-                        {
-                            "file": "^cxx/CMakeLists\\.txt$",
-                            "line": 9,
-                            "command": "add_library",
-                            "hasParent": True,
-                        },
-                        {
-                            "file": "^cxx/CMakeLists\\.txt$",
-                            "line": None,
-                            "command": None,
-                            "hasParent": False,
-                        },
-                    ],
-                },
-            ],
-            "sourceGroups": [
-                {
-                    "name": "Source Files",
-                    "sourcePaths": [
-                        "^empty\\.cxx$",
-                    ],
-                },
-            ],
-            "compileGroups": [
-                {
-                    "language": "CXX",
-                    "sourcePaths": [
-                        "^empty\\.cxx$",
-                    ],
-                    "includes": None,
-                    "defines": [
-                        {
-                            "define": "cxx_shared_lib_EXPORTS",
-                            "backtrace": None,
-                        },
-                    ],
-                    "compileCommandFragments": None,
-                },
-            ],
-            "backtrace": [
-                {
-                    "file": "^cxx/CMakeLists\\.txt$",
-                    "line": 9,
-                    "command": "add_library",
-                    "hasParent": True,
-                },
-                {
-                    "file": "^cxx/CMakeLists\\.txt$",
-                    "line": None,
-                    "command": None,
-                    "hasParent": False,
-                },
-            ],
-            "folder": None,
-            "nameOnDisk": "^(lib|cyg)?cxx_shared_lib\\.(so|dylib|dll)$",
-            "artifacts": [
-                {
-                    "path": "^cxx/((Debug|Release|RelWithDebInfo|MinSizeRel)/)?(lib|cyg)?cxx_shared_lib\\.(so|dylib|dll)$",
-                    "_dllExtra": False,
-                },
-                {
-                    "path": "^cxx/((Debug|Release|RelWithDebInfo|MinSizeRel)/)?(lib)?cxx_shared_lib\\.(dll\\.a|lib)$",
-                    "_dllExtra": True,
-                },
-                {
-                    "path": "^cxx/((Debug|Release|RelWithDebInfo|MinSizeRel)/)?(lib|cyg)?cxx_shared_lib\\.pdb$",
-                    "_dllExtra": True,
-                },
-            ],
-            "build": "^cxx$",
-            "source": "^cxx$",
-            "install": None,
-            "link": {
-                "language": "CXX",
-                "lto": None,
-                "commandFragments": None,
-            },
-            "archive": None,
-            "dependencies": [
-                {
-                    "id": "^ZERO_CHECK::@a56b12a3f5c0529fb296$",
-                    "backtrace": None,
-                },
-            ],
-        },
-        {
-            "name": "cxx_shared_exe",
-            "id": "^cxx_shared_exe::@a56b12a3f5c0529fb296$",
-            "directorySource": "^cxx$",
-            "projectName": "Cxx",
-            "type": "EXECUTABLE",
-            "isGeneratorProvided": None,
-            "sources": [
-                {
-                    "path": "^empty\\.cxx$",
-                    "isGenerated": None,
-                    "sourceGroupName": "Source Files",
-                    "compileGroupLanguage": "CXX",
-                    "backtrace": [
-                        {
-                            "file": "^cxx/CMakeLists\\.txt$",
-                            "line": 10,
-                            "command": "add_executable",
-                            "hasParent": True,
-                        },
-                        {
-                            "file": "^cxx/CMakeLists\\.txt$",
-                            "line": None,
-                            "command": None,
-                            "hasParent": False,
-                        },
-                    ],
-                },
-            ],
-            "sourceGroups": [
-                {
-                    "name": "Source Files",
-                    "sourcePaths": [
-                        "^empty\\.cxx$",
-                    ],
-                },
-            ],
-            "compileGroups": [
-                {
-                    "language": "CXX",
-                    "sourcePaths": [
-                        "^empty\\.cxx$",
-                    ],
-                    "includes": None,
-                    "defines": None,
-                    "compileCommandFragments": None,
-                },
-            ],
-            "backtrace": [
-                {
-                    "file": "^cxx/CMakeLists\\.txt$",
-                    "line": 10,
-                    "command": "add_executable",
-                    "hasParent": True,
-                },
-                {
-                    "file": "^cxx/CMakeLists\\.txt$",
-                    "line": None,
-                    "command": None,
-                    "hasParent": False,
-                },
-            ],
-            "folder": None,
-            "nameOnDisk": "^cxx_shared_exe(\\.exe)?$",
-            "artifacts": [
-                {
-                    "path": "^cxx/((Debug|Release|RelWithDebInfo|MinSizeRel)/)?cxx_shared_exe(\\.exe)?$",
-                    "_dllExtra": False,
-                },
-                {
-                    "path": "^cxx/((Debug|Release|RelWithDebInfo|MinSizeRel)/)?cxx_shared_exe\\.pdb$",
-                    "_dllExtra": True,
-                },
-            ],
-            "build": "^cxx$",
-            "source": "^cxx$",
-            "install": None,
-            "link": {
-                "language": "CXX",
-                "lto": None,
-                "commandFragments": None,
-            },
-            "archive": None,
-            "dependencies": [
-                {
-                    "id": "^cxx_shared_lib::@a56b12a3f5c0529fb296$",
-                    "backtrace": [
-                        {
-                            "file": "^cxx/CMakeLists\\.txt$",
-                            "line": 11,
-                            "command": "target_link_libraries",
-                            "hasParent": True,
-                        },
-                        {
-                            "file": "^cxx/CMakeLists\\.txt$",
-                            "line": None,
-                            "command": None,
-                            "hasParent": False,
-                        },
-                    ],
-                },
-                {
-                    "id": "^ZERO_CHECK::@a56b12a3f5c0529fb296$",
-                    "backtrace": None,
-                },
-            ],
-        },
-        {
-            "name": "cxx_static_lib",
-            "id": "^cxx_static_lib::@a56b12a3f5c0529fb296$",
-            "directorySource": "^cxx$",
-            "projectName": "Cxx",
-            "type": "STATIC_LIBRARY",
-            "isGeneratorProvided": None,
-            "sources": [
-                {
-                    "path": "^empty\\.cxx$",
-                    "isGenerated": None,
-                    "sourceGroupName": "Source Files",
-                    "compileGroupLanguage": "CXX",
-                    "backtrace": [
-                        {
-                            "file": "^cxx/CMakeLists\\.txt$",
-                            "line": 13,
-                            "command": "add_library",
-                            "hasParent": True,
-                        },
-                        {
-                            "file": "^cxx/CMakeLists\\.txt$",
-                            "line": None,
-                            "command": None,
-                            "hasParent": False,
-                        },
-                    ],
-                },
-            ],
-            "sourceGroups": [
-                {
-                    "name": "Source Files",
-                    "sourcePaths": [
-                        "^empty\\.cxx$",
-                    ],
-                },
-            ],
-            "compileGroups": [
-                {
-                    "language": "CXX",
-                    "sourcePaths": [
-                        "^empty\\.cxx$",
-                    ],
-                    "includes": None,
-                    "defines": None,
-                    "compileCommandFragments": None,
-                },
-            ],
-            "backtrace": [
-                {
-                    "file": "^cxx/CMakeLists\\.txt$",
-                    "line": 13,
-                    "command": "add_library",
-                    "hasParent": True,
-                },
-                {
-                    "file": "^cxx/CMakeLists\\.txt$",
-                    "line": None,
-                    "command": None,
-                    "hasParent": False,
-                },
-            ],
-            "folder": None,
-            "nameOnDisk": "^(lib)?cxx_static_lib\\.(a|lib)$",
-            "artifacts": [
-                {
-                    "path": "^cxx/((Debug|Release|RelWithDebInfo|MinSizeRel)/)?(lib)?cxx_static_lib\\.(a|lib)$",
-                    "_dllExtra": False,
-                },
-            ],
-            "build": "^cxx$",
-            "source": "^cxx$",
-            "install": None,
-            "link": None,
-            "archive": {
-                "lto": None,
-            },
-            "dependencies": [
-                {
-                    "id": "^ZERO_CHECK::@a56b12a3f5c0529fb296$",
-                    "backtrace": None,
-                },
-            ],
-        },
-        {
-            "name": "cxx_static_exe",
-            "id": "^cxx_static_exe::@a56b12a3f5c0529fb296$",
-            "directorySource": "^cxx$",
-            "projectName": "Cxx",
-            "type": "EXECUTABLE",
-            "isGeneratorProvided": None,
-            "sources": [
-                {
-                    "path": "^empty\\.cxx$",
-                    "isGenerated": None,
-                    "sourceGroupName": "Source Files",
-                    "compileGroupLanguage": "CXX",
-                    "backtrace": [
-                        {
-                            "file": "^cxx/CMakeLists\\.txt$",
-                            "line": 14,
-                            "command": "add_executable",
-                            "hasParent": True,
-                        },
-                        {
-                            "file": "^cxx/CMakeLists\\.txt$",
-                            "line": None,
-                            "command": None,
-                            "hasParent": False,
-                        },
-                    ],
-                },
-            ],
-            "sourceGroups": [
-                {
-                    "name": "Source Files",
-                    "sourcePaths": [
-                        "^empty\\.cxx$",
-                    ],
-                },
-            ],
-            "compileGroups": [
-                {
-                    "language": "CXX",
-                    "sourcePaths": [
-                        "^empty\\.cxx$",
-                    ],
-                    "includes": None,
-                    "defines": None,
-                    "compileCommandFragments": None,
-                },
-            ],
-            "backtrace": [
-                {
-                    "file": "^cxx/CMakeLists\\.txt$",
-                    "line": 14,
-                    "command": "add_executable",
-                    "hasParent": True,
-                },
-                {
-                    "file": "^cxx/CMakeLists\\.txt$",
-                    "line": None,
-                    "command": None,
-                    "hasParent": False,
-                },
-            ],
-            "folder": None,
-            "nameOnDisk": "^cxx_static_exe(\\.exe)?$",
-            "artifacts": [
-                {
-                    "path": "^cxx/((Debug|Release|RelWithDebInfo|MinSizeRel)/)?cxx_static_exe(\\.exe)?$",
-                    "_dllExtra": False,
-                },
-                {
-                    "path": "^cxx/((Debug|Release|RelWithDebInfo|MinSizeRel)/)?cxx_static_exe\\.pdb$",
-                    "_dllExtra": True,
-                },
-            ],
-            "build": "^cxx$",
-            "source": "^cxx$",
-            "install": None,
-            "link": {
-                "language": "CXX",
-                "lto": None,
-                "commandFragments": None,
-            },
-            "archive": None,
-            "dependencies": [
-                {
-                    "id": "^cxx_static_lib::@a56b12a3f5c0529fb296$",
-                    "backtrace": [
-                        {
-                            "file": "^cxx/CMakeLists\\.txt$",
-                            "line": 15,
-                            "command": "target_link_libraries",
-                            "hasParent": True,
-                        },
-                        {
-                            "file": "^cxx/CMakeLists\\.txt$",
-                            "line": None,
-                            "command": None,
-                            "hasParent": False,
-                        },
-                    ],
-                },
-                {
-                    "id": "^ZERO_CHECK::@a56b12a3f5c0529fb296$",
-                    "backtrace": None,
-                },
-            ],
-        },
-        {
-            "name": "ALL_BUILD",
-            "id": "^ALL_BUILD::@53632cba2752272bb008$",
-            "directorySource": "^alias$",
-            "projectName": "Alias",
-            "type": "UTILITY",
-            "isGeneratorProvided": True,
-            "sources": [
-                {
-                    "path": "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/alias/CMakeFiles/ALL_BUILD$",
-                    "isGenerated": True,
-                    "sourceGroupName": "",
-                    "compileGroupLanguage": None,
-                    "backtrace": [
-                        {
-                            "file": "^alias/CMakeLists\\.txt$",
-                            "line": None,
-                            "command": None,
-                            "hasParent": False,
-                        },
-                    ],
-                },
-                {
-                    "path": "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/alias/CMakeFiles/ALL_BUILD\\.rule$",
-                    "isGenerated": True,
-                    "sourceGroupName": "CMake Rules",
-                    "compileGroupLanguage": None,
-                    "backtrace": [
-                        {
-                            "file": "^alias/CMakeLists\\.txt$",
-                            "line": None,
-                            "command": None,
-                            "hasParent": False,
-                        },
-                    ],
-                },
-            ],
-            "sourceGroups": [
-                {
-                    "name": "",
-                    "sourcePaths": [
-                        "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/alias/CMakeFiles/ALL_BUILD$",
-                    ],
-                },
-                {
-                    "name": "CMake Rules",
-                    "sourcePaths": [
-                        "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/alias/CMakeFiles/ALL_BUILD\\.rule$",
-                    ],
-                },
-            ],
-            "compileGroups": None,
-            "backtrace": [
-                {
-                    "file": "^alias/CMakeLists\\.txt$",
-                    "line": None,
-                    "command": None,
-                    "hasParent": False,
-                },
-            ],
-            "folder": None,
-            "nameOnDisk": None,
-            "artifacts": None,
-            "build": "^alias$",
-            "source": "^alias$",
-            "install": None,
-            "link": None,
-            "archive": None,
-            "dependencies": [
-                {
-                    "id": "^ZERO_CHECK::@53632cba2752272bb008$",
-                    "backtrace": None,
-                },
-                {
-                    "id": "^c_alias_exe::@53632cba2752272bb008$",
-                    "backtrace": None,
-                },
-                {
-                    "id": "^cxx_alias_exe::@53632cba2752272bb008$",
-                    "backtrace": None,
-                },
-            ],
-        },
-        {
-            "name": "ZERO_CHECK",
-            "id": "^ZERO_CHECK::@53632cba2752272bb008$",
-            "directorySource": "^alias$",
-            "projectName": "Alias",
-            "type": "UTILITY",
-            "isGeneratorProvided": True,
-            "sources": [
-                {
-                    "path": "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/alias/CMakeFiles/ZERO_CHECK$",
-                    "isGenerated": True,
-                    "sourceGroupName": "",
-                    "compileGroupLanguage": None,
-                    "backtrace": [
-                        {
-                            "file": "^alias/CMakeLists\\.txt$",
-                            "line": None,
-                            "command": None,
-                            "hasParent": False,
-                        },
-                    ],
-                },
-                {
-                    "path": "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/alias/CMakeFiles/ZERO_CHECK\\.rule$",
-                    "isGenerated": True,
-                    "sourceGroupName": "CMake Rules",
-                    "compileGroupLanguage": None,
-                    "backtrace": [
-                        {
-                            "file": "^alias/CMakeLists\\.txt$",
-                            "line": None,
-                            "command": None,
-                            "hasParent": False,
-                        },
-                    ],
-                },
-            ],
-            "sourceGroups": [
-                {
-                    "name": "",
-                    "sourcePaths": [
-                        "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/alias/CMakeFiles/ZERO_CHECK$",
-                    ],
-                },
-                {
-                    "name": "CMake Rules",
-                    "sourcePaths": [
-                        "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/alias/CMakeFiles/ZERO_CHECK\\.rule$",
-                    ],
-                },
-            ],
-            "compileGroups": None,
-            "backtrace": [
-                {
-                    "file": "^alias/CMakeLists\\.txt$",
-                    "line": None,
-                    "command": None,
-                    "hasParent": False,
-                },
-            ],
-            "folder": None,
-            "nameOnDisk": None,
-            "artifacts": None,
-            "build": "^alias$",
-            "source": "^alias$",
-            "install": None,
-            "link": None,
-            "archive": None,
-            "dependencies": None,
-        },
-        {
-            "name": "c_alias_exe",
-            "id": "^c_alias_exe::@53632cba2752272bb008$",
-            "directorySource": "^alias$",
-            "projectName": "Alias",
-            "type": "EXECUTABLE",
-            "isGeneratorProvided": None,
-            "sources": [
-                {
-                    "path": "^empty\\.c$",
-                    "isGenerated": None,
-                    "sourceGroupName": "Source Files",
-                    "compileGroupLanguage": "C",
-                    "backtrace": [
-                        {
-                            "file": "^alias/CMakeLists\\.txt$",
-                            "line": 5,
-                            "command": "add_executable",
-                            "hasParent": True,
-                        },
-                        {
-                            "file": "^alias/CMakeLists\\.txt$",
-                            "line": None,
-                            "command": None,
-                            "hasParent": False,
-                        },
-                    ],
-                },
-            ],
-            "sourceGroups": [
-                {
-                    "name": "Source Files",
-                    "sourcePaths": [
-                        "^empty\\.c$",
-                    ],
-                },
-            ],
-            "compileGroups": [
-                {
-                    "language": "C",
-                    "sourcePaths": [
-                        "^empty\\.c$",
-                    ],
-                    "includes": None,
-                    "defines": None,
-                    "compileCommandFragments": None,
-                },
-            ],
-            "backtrace": [
-                {
-                    "file": "^alias/CMakeLists\\.txt$",
-                    "line": 5,
-                    "command": "add_executable",
-                    "hasParent": True,
-                },
-                {
-                    "file": "^alias/CMakeLists\\.txt$",
-                    "line": None,
-                    "command": None,
-                    "hasParent": False,
-                },
-            ],
-            "folder": None,
-            "nameOnDisk": "^c_alias_exe(\\.exe)?$",
-            "artifacts": [
-                {
-                    "path": "^alias/((Debug|Release|RelWithDebInfo|MinSizeRel)/)?c_alias_exe(\\.exe)?$",
-                    "_dllExtra": False,
-                },
-                {
-                    "path": "^alias/((Debug|Release|RelWithDebInfo|MinSizeRel)/)?c_alias_exe\\.pdb$",
-                    "_dllExtra": True,
-                },
-            ],
-            "build": "^alias$",
-            "source": "^alias$",
-            "install": None,
-            "link": {
-                "language": "C",
-                "lto": None,
-                "commandFragments": None,
-            },
-            "archive": None,
-            "dependencies": [
-                {
-                    "id": "^c_lib::@6890427a1f51a3e7e1df$",
-                    "backtrace": [
-                        {
-                            "file": "^alias/CMakeLists\\.txt$",
-                            "line": 6,
-                            "command": "target_link_libraries",
-                            "hasParent": True,
-                        },
-                        {
-                            "file": "^alias/CMakeLists\\.txt$",
-                            "line": None,
-                            "command": None,
-                            "hasParent": False,
-                        },
-                    ],
-                },
-                {
-                    "id": "^ZERO_CHECK::@53632cba2752272bb008$",
-                    "backtrace": None,
-                },
-            ],
-        },
-        {
-            "name": "cxx_alias_exe",
-            "id": "^cxx_alias_exe::@53632cba2752272bb008$",
-            "directorySource": "^alias$",
-            "projectName": "Alias",
-            "type": "EXECUTABLE",
-            "isGeneratorProvided": None,
-            "sources": [
-                {
-                    "path": "^empty\\.cxx$",
-                    "isGenerated": None,
-                    "sourceGroupName": "Source Files",
-                    "compileGroupLanguage": "CXX",
-                    "backtrace": [
-                        {
-                            "file": "^alias/CMakeLists\\.txt$",
-                            "line": 9,
-                            "command": "add_executable",
-                            "hasParent": True,
-                        },
-                        {
-                            "file": "^alias/CMakeLists\\.txt$",
-                            "line": None,
-                            "command": None,
-                            "hasParent": False,
-                        },
-                    ],
-                },
-            ],
-            "sourceGroups": [
-                {
-                    "name": "Source Files",
-                    "sourcePaths": [
-                        "^empty\\.cxx$",
-                    ],
-                },
-            ],
-            "compileGroups": [
-                {
-                    "language": "CXX",
-                    "sourcePaths": [
-                        "^empty\\.cxx$",
-                    ],
-                    "includes": None,
-                    "defines": None,
-                    "compileCommandFragments": None,
-                },
-            ],
-            "backtrace": [
-                {
-                    "file": "^alias/CMakeLists\\.txt$",
-                    "line": 9,
-                    "command": "add_executable",
-                    "hasParent": True,
-                },
-                {
-                    "file": "^alias/CMakeLists\\.txt$",
-                    "line": None,
-                    "command": None,
-                    "hasParent": False,
-                },
-            ],
-            "folder": None,
-            "nameOnDisk": "^cxx_alias_exe(\\.exe)?$",
-            "artifacts": [
-                {
-                    "path": "^alias/((Debug|Release|RelWithDebInfo|MinSizeRel)/)?cxx_alias_exe(\\.exe)?$",
-                    "_dllExtra": False,
-                },
-                {
-                    "path": "^alias/((Debug|Release|RelWithDebInfo|MinSizeRel)/)?cxx_alias_exe\\.pdb$",
-                    "_dllExtra": True,
-                },
-            ],
-            "build": "^alias$",
-            "source": "^alias$",
-            "install": None,
-            "link": {
-                "language": "CXX",
-                "lto": None,
-                "commandFragments": None,
-            },
-            "archive": None,
-            "dependencies": [
-                {
-                    "id": "^cxx_lib::@a56b12a3f5c0529fb296$",
-                    "backtrace": [
-                        {
-                            "file": "^alias/CMakeLists\\.txt$",
-                            "line": 10,
-                            "command": "target_link_libraries",
-                            "hasParent": True,
-                        },
-                        {
-                            "file": "^alias/CMakeLists\\.txt$",
-                            "line": None,
-                            "command": None,
-                            "hasParent": False,
-                        },
-                    ],
-                },
-                {
-                    "id": "^ZERO_CHECK::@53632cba2752272bb008$",
-                    "backtrace": None,
-                },
-            ],
-        },
-        {
-            "name": "ALL_BUILD",
-            "id": "^ALL_BUILD::@5ed5358f70faf8d8af7a$",
-            "directorySource": "^object$",
-            "projectName": "Object",
-            "type": "UTILITY",
-            "isGeneratorProvided": True,
-            "sources": [
-                {
-                    "path": "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/object/CMakeFiles/ALL_BUILD$",
-                    "isGenerated": True,
-                    "sourceGroupName": "",
-                    "compileGroupLanguage": None,
-                    "backtrace": [
-                        {
-                            "file": "^object/CMakeLists\\.txt$",
-                            "line": None,
-                            "command": None,
-                            "hasParent": False,
-                        },
-                    ],
-                },
-                {
-                    "path": "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/object/CMakeFiles/ALL_BUILD\\.rule$",
-                    "isGenerated": True,
-                    "sourceGroupName": "CMake Rules",
-                    "compileGroupLanguage": None,
-                    "backtrace": [
-                        {
-                            "file": "^object/CMakeLists\\.txt$",
-                            "line": None,
-                            "command": None,
-                            "hasParent": False,
-                        },
-                    ],
-                },
-            ],
-            "sourceGroups": [
-                {
-                    "name": "",
-                    "sourcePaths": [
-                        "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/object/CMakeFiles/ALL_BUILD$",
-                    ],
-                },
-                {
-                    "name": "CMake Rules",
-                    "sourcePaths": [
-                        "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/object/CMakeFiles/ALL_BUILD\\.rule$",
-                    ],
-                },
-            ],
-            "compileGroups": None,
-            "backtrace": [
-                {
-                    "file": "^object/CMakeLists\\.txt$",
-                    "line": None,
-                    "command": None,
-                    "hasParent": False,
-                },
-            ],
-            "folder": None,
-            "nameOnDisk": None,
-            "artifacts": None,
-            "build": "^object$",
-            "source": "^object$",
-            "install": None,
-            "link": None,
-            "archive": None,
-            "dependencies": [
-                {
-                    "id": "^ZERO_CHECK::@5ed5358f70faf8d8af7a$",
-                    "backtrace": None,
-                },
-                {
-                    "id": "^c_object_lib::@5ed5358f70faf8d8af7a$",
-                    "backtrace": None,
-                },
-                {
-                    "id": "^c_object_exe::@5ed5358f70faf8d8af7a$",
-                    "backtrace": None,
-                },
-                {
-                    "id": "^cxx_object_lib::@5ed5358f70faf8d8af7a$",
-                    "backtrace": None,
-                },
-                {
-                    "id": "^cxx_object_exe::@5ed5358f70faf8d8af7a$",
-                    "backtrace": None,
-                },
-            ],
-        },
-        {
-            "name": "ZERO_CHECK",
-            "id": "^ZERO_CHECK::@5ed5358f70faf8d8af7a$",
-            "directorySource": "^object$",
-            "projectName": "Object",
-            "type": "UTILITY",
-            "isGeneratorProvided": True,
-            "sources": [
-                {
-                    "path": "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/object/CMakeFiles/ZERO_CHECK$",
-                    "isGenerated": True,
-                    "sourceGroupName": "",
-                    "compileGroupLanguage": None,
-                    "backtrace": [
-                        {
-                            "file": "^object/CMakeLists\\.txt$",
-                            "line": None,
-                            "command": None,
-                            "hasParent": False,
-                        },
-                    ],
-                },
-                {
-                    "path": "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/object/CMakeFiles/ZERO_CHECK\\.rule$",
-                    "isGenerated": True,
-                    "sourceGroupName": "CMake Rules",
-                    "compileGroupLanguage": None,
-                    "backtrace": [
-                        {
-                            "file": "^object/CMakeLists\\.txt$",
-                            "line": None,
-                            "command": None,
-                            "hasParent": False,
-                        },
-                    ],
-                },
-            ],
-            "sourceGroups": [
-                {
-                    "name": "",
-                    "sourcePaths": [
-                        "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/object/CMakeFiles/ZERO_CHECK$",
-                    ],
-                },
-                {
-                    "name": "CMake Rules",
-                    "sourcePaths": [
-                        "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/object/CMakeFiles/ZERO_CHECK\\.rule$",
-                    ],
-                },
-            ],
-            "compileGroups": None,
-            "backtrace": [
-                {
-                    "file": "^object/CMakeLists\\.txt$",
-                    "line": None,
-                    "command": None,
-                    "hasParent": False,
-                },
-            ],
-            "folder": None,
-            "nameOnDisk": None,
-            "artifacts": None,
-            "build": "^object$",
-            "source": "^object$",
-            "install": None,
-            "link": None,
-            "archive": None,
-            "dependencies": None,
-        },
-        {
-            "name": "c_object_lib",
-            "id": "^c_object_lib::@5ed5358f70faf8d8af7a$",
-            "directorySource": "^object$",
-            "projectName": "Object",
-            "type": "OBJECT_LIBRARY",
-            "isGeneratorProvided": None,
-            "sources": [
-                {
-                    "path": "^empty\\.c$",
-                    "isGenerated": None,
-                    "sourceGroupName": "Source Files",
-                    "compileGroupLanguage": "C",
-                    "backtrace": [
-                        {
-                            "file": "^object/CMakeLists\\.txt$",
-                            "line": 5,
-                            "command": "add_library",
-                            "hasParent": True,
-                        },
-                        {
-                            "file": "^object/CMakeLists\\.txt$",
-                            "line": None,
-                            "command": None,
-                            "hasParent": False,
-                        },
-                    ],
-                },
-            ],
-            "sourceGroups": [
-                {
-                    "name": "Source Files",
-                    "sourcePaths": [
-                        "^empty\\.c$",
-                    ],
-                },
-            ],
-            "compileGroups": [
-                {
-                    "language": "C",
-                    "sourcePaths": [
-                        "^empty\\.c$",
-                    ],
-                    "includes": None,
-                    "defines": None,
-                    "compileCommandFragments": None,
-                },
-            ],
-            "backtrace": [
-                {
-                    "file": "^object/CMakeLists\\.txt$",
-                    "line": 5,
-                    "command": "add_library",
-                    "hasParent": True,
-                },
-                {
-                    "file": "^object/CMakeLists\\.txt$",
-                    "line": None,
-                    "command": None,
-                    "hasParent": False,
-                },
-            ],
-            "folder": None,
-            "nameOnDisk": None,
-            "artifacts": [
-                {
-                    "path": "^object/.*/empty(\\.c)?\\.o(bj)?$",
-                    "_dllExtra": False,
-                },
-            ],
-            "build": "^object$",
-            "source": "^object$",
-            "install": None,
-            "link": None,
-            "archive": None,
-            "dependencies": [
-                {
-                    "id": "^ZERO_CHECK::@5ed5358f70faf8d8af7a$",
-                    "backtrace": None,
-                },
-            ],
-        },
-        {
-            "name": "c_object_exe",
-            "id": "^c_object_exe::@5ed5358f70faf8d8af7a$",
-            "directorySource": "^object$",
-            "projectName": "Object",
-            "type": "EXECUTABLE",
-            "isGeneratorProvided": None,
-            "sources": [
-                {
-                    "path": "^empty\\.c$",
-                    "isGenerated": None,
-                    "sourceGroupName": "Source Files",
-                    "compileGroupLanguage": "C",
-                    "backtrace": [
-                        {
-                            "file": "^object/CMakeLists\\.txt$",
-                            "line": 6,
-                            "command": "add_executable",
-                            "hasParent": True,
-                        },
-                        {
-                            "file": "^object/CMakeLists\\.txt$",
-                            "line": None,
-                            "command": None,
-                            "hasParent": False,
-                        },
-                    ],
-                },
-                {
-                    "path": "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/object/.*/empty(\\.c)?\\.o(bj)?$",
-                    "isGenerated": True,
-                    "sourceGroupName": "Object Libraries",
-                    "compileGroupLanguage": None,
-                    "backtrace": [
-                        {
-                            "file": "^object/CMakeLists\\.txt$",
-                            "line": 7,
-                            "command": "target_link_libraries",
-                            "hasParent": True,
-                        },
-                        {
-                            "file": "^object/CMakeLists\\.txt$",
-                            "line": None,
-                            "command": None,
-                            "hasParent": False,
-                        },
-                    ],
-                },
-            ],
-            "sourceGroups": [
-                {
-                    "name": "Source Files",
-                    "sourcePaths": [
-                        "^empty\\.c$",
-                    ],
-                },
-                {
-                    "name": "Object Libraries",
-                    "sourcePaths": [
-                        "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/object/.*/empty(\\.c)?\\.o(bj)?$",
-                    ],
-                },
-            ],
-            "compileGroups": [
-                {
-                    "language": "C",
-                    "sourcePaths": [
-                        "^empty\\.c$",
-                    ],
-                    "includes": None,
-                    "defines": None,
-                    "compileCommandFragments": None,
-                },
-            ],
-            "backtrace": [
-                {
-                    "file": "^object/CMakeLists\\.txt$",
-                    "line": 6,
-                    "command": "add_executable",
-                    "hasParent": True,
-                },
-                {
-                    "file": "^object/CMakeLists\\.txt$",
-                    "line": None,
-                    "command": None,
-                    "hasParent": False,
-                },
-            ],
-            "folder": None,
-            "nameOnDisk": "^c_object_exe(\\.exe)?$",
-            "artifacts": [
-                {
-                    "path": "^object/((Debug|Release|RelWithDebInfo|MinSizeRel)/)?c_object_exe(\\.exe)?$",
-                    "_dllExtra": False,
-                },
-                {
-                    "path": "^object/((Debug|Release|RelWithDebInfo|MinSizeRel)/)?c_object_exe\\.pdb$",
-                    "_dllExtra": True,
-                },
-            ],
-            "build": "^object$",
-            "source": "^object$",
-            "install": {
-                "prefix": "^(/usr/local|[A-Za-z]:.*/codemodel-v2)$",
-                "destinations": [
-                    {
-                        "path": "bin",
-                        "backtrace": [
-                            {
-                                "file": "^object/CMakeLists\\.txt$",
-                                "line": 13,
-                                "command": "install",
-                                "hasParent": True,
-                            },
-                            {
-                                "file": "^object/CMakeLists\\.txt$",
-                                "line": None,
-                                "command": None,
-                                "hasParent": False,
-                            },
-                        ],
-                    },
-                ],
-            },
-            "link": {
-                "language": "C",
-                "lto": None,
-                "commandFragments": None,
-            },
-            "archive": None,
-            "dependencies": [
-                {
-                    "id": "^c_object_lib::@5ed5358f70faf8d8af7a$",
-                    # FIXME: Add a backtrace here when it becomes available.
-                    # You'll know when it's available, because this test will
-                    # fail.
-                    "backtrace": None,
-                },
-                {
-                    "id": "^ZERO_CHECK::@5ed5358f70faf8d8af7a$",
-                    "backtrace": None,
-                },
-            ],
-        },
-        {
-            "name": "cxx_object_lib",
-            "id": "^cxx_object_lib::@5ed5358f70faf8d8af7a$",
-            "directorySource": "^object$",
-            "projectName": "Object",
-            "type": "OBJECT_LIBRARY",
-            "isGeneratorProvided": None,
-            "sources": [
-                {
-                    "path": "^empty\\.cxx$",
-                    "isGenerated": None,
-                    "sourceGroupName": "Source Files",
-                    "compileGroupLanguage": "CXX",
-                    "backtrace": [
-                        {
-                            "file": "^object/CMakeLists\\.txt$",
-                            "line": 9,
-                            "command": "add_library",
-                            "hasParent": True,
-                        },
-                        {
-                            "file": "^object/CMakeLists\\.txt$",
-                            "line": None,
-                            "command": None,
-                            "hasParent": False,
-                        },
-                    ],
-                },
-            ],
-            "sourceGroups": [
-                {
-                    "name": "Source Files",
-                    "sourcePaths": [
-                        "^empty\\.cxx$",
-                    ],
-                },
-            ],
-            "compileGroups": [
-                {
-                    "language": "CXX",
-                    "sourcePaths": [
-                        "^empty\\.cxx$",
-                    ],
-                    "includes": None,
-                    "defines": None,
-                    "compileCommandFragments": None,
-                },
-            ],
-            "backtrace": [
-                {
-                    "file": "^object/CMakeLists\\.txt$",
-                    "line": 9,
-                    "command": "add_library",
-                    "hasParent": True,
-                },
-                {
-                    "file": "^object/CMakeLists\\.txt$",
-                    "line": None,
-                    "command": None,
-                    "hasParent": False,
-                },
-            ],
-            "folder": None,
-            "nameOnDisk": None,
-            "artifacts": [
-                {
-                    "path": "^object/.*/empty(\\.cxx)?\\.o(bj)?$",
-                    "_dllExtra": False,
-                },
-            ],
-            "build": "^object$",
-            "source": "^object$",
-            "install": None,
-            "link": None,
-            "archive": None,
-            "dependencies": [
-                {
-                    "id": "^ZERO_CHECK::@5ed5358f70faf8d8af7a$",
-                    "backtrace": None,
-                },
-            ],
-        },
-        {
-            "name": "cxx_object_exe",
-            "id": "^cxx_object_exe::@5ed5358f70faf8d8af7a$",
-            "directorySource": "^object$",
-            "projectName": "Object",
-            "type": "EXECUTABLE",
-            "isGeneratorProvided": None,
-            "sources": [
-                {
-                    "path": "^empty\\.cxx$",
-                    "isGenerated": None,
-                    "sourceGroupName": "Source Files",
-                    "compileGroupLanguage": "CXX",
-                    "backtrace": [
-                        {
-                            "file": "^object/CMakeLists\\.txt$",
-                            "line": 10,
-                            "command": "add_executable",
-                            "hasParent": True,
-                        },
-                        {
-                            "file": "^object/CMakeLists\\.txt$",
-                            "line": None,
-                            "command": None,
-                            "hasParent": False,
-                        },
-                    ],
-                },
-                {
-                    "path": "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/object/.*/empty(\\.cxx)?\\.o(bj)?$",
-                    "isGenerated": True,
-                    "sourceGroupName": "Object Libraries",
-                    "compileGroupLanguage": None,
-                    "backtrace": [
-                        {
-                            "file": "^object/CMakeLists\\.txt$",
-                            "line": 11,
-                            "command": "target_link_libraries",
-                            "hasParent": True,
-                        },
-                        {
-                            "file": "^object/CMakeLists\\.txt$",
-                            "line": None,
-                            "command": None,
-                            "hasParent": False,
-                        },
-                    ],
-                },
-            ],
-            "sourceGroups": [
-                {
-                    "name": "Source Files",
-                    "sourcePaths": [
-                        "^empty\\.cxx$",
-                    ],
-                },
-                {
-                    "name": "Object Libraries",
-                    "sourcePaths": [
-                        "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/object/.*/empty(\\.cxx)?\\.o(bj)?$",
-                    ],
-                },
-            ],
-            "compileGroups": [
-                {
-                    "language": "CXX",
-                    "sourcePaths": [
-                        "^empty\\.cxx$",
-                    ],
-                    "includes": None,
-                    "defines": None,
-                    "compileCommandFragments": None,
-                },
-            ],
-            "backtrace": [
-                {
-                    "file": "^object/CMakeLists\\.txt$",
-                    "line": 10,
-                    "command": "add_executable",
-                    "hasParent": True,
-                },
-                {
-                    "file": "^object/CMakeLists\\.txt$",
-                    "line": None,
-                    "command": None,
-                    "hasParent": False,
-                },
-            ],
-            "folder": None,
-            "nameOnDisk": "^cxx_object_exe(\\.exe)?$",
-            "artifacts": [
-                {
-                    "path": "^object/((Debug|Release|RelWithDebInfo|MinSizeRel)/)?cxx_object_exe(\\.exe)?$",
-                    "_dllExtra": False,
-                },
-                {
-                    "path": "^object/((Debug|Release|RelWithDebInfo|MinSizeRel)/)?cxx_object_exe\\.pdb$",
-                    "_dllExtra": True,
-                },
-            ],
-            "build": "^object$",
-            "source": "^object$",
-            "install": {
-                "prefix": "^(/usr/local|[A-Za-z]:.*/codemodel-v2)$",
-                "destinations": [
-                    {
-                        "path": "bin",
-                        "backtrace": [
-                            {
-                                "file": "^object/CMakeLists\\.txt$",
-                                "line": 13,
-                                "command": "install",
-                                "hasParent": True,
-                            },
-                            {
-                                "file": "^object/CMakeLists\\.txt$",
-                                "line": None,
-                                "command": None,
-                                "hasParent": False,
-                            },
-                        ],
-                    },
-                ],
-            },
-            "link": {
-                "language": "CXX",
-                "lto": None,
-                "commandFragments": None,
-            },
-            "archive": None,
-            "dependencies": [
-                {
-                    "id": "^cxx_object_lib::@5ed5358f70faf8d8af7a$",
-                    # FIXME: Add a backtrace here when it becomes available.
-                    # You'll know when it's available, because this test will
-                    # fail.
-                    "backtrace": None,
-                },
-                {
-                    "id": "^ZERO_CHECK::@5ed5358f70faf8d8af7a$",
-                    "backtrace": None,
-                },
-            ],
-        },
-        {
-            "name": "ALL_BUILD",
-            "id": "^ALL_BUILD::@ba7eb709d0b48779c6c8$",
-            "directorySource": "^imported$",
-            "projectName": "Imported",
-            "type": "UTILITY",
-            "isGeneratorProvided": True,
-            "sources": [
-                {
-                    "path": "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/imported/CMakeFiles/ALL_BUILD$",
-                    "isGenerated": True,
-                    "sourceGroupName": "",
-                    "compileGroupLanguage": None,
-                    "backtrace": [
-                        {
-                            "file": "^imported/CMakeLists\\.txt$",
-                            "line": None,
-                            "command": None,
-                            "hasParent": False,
-                        },
-                    ],
-                },
-                {
-                    "path": "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/imported/CMakeFiles/ALL_BUILD\\.rule$",
-                    "isGenerated": True,
-                    "sourceGroupName": "CMake Rules",
-                    "compileGroupLanguage": None,
-                    "backtrace": [
-                        {
-                            "file": "^imported/CMakeLists\\.txt$",
-                            "line": None,
-                            "command": None,
-                            "hasParent": False,
-                        },
-                    ],
-                },
-            ],
-            "sourceGroups": [
-                {
-                    "name": "",
-                    "sourcePaths": [
-                        "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/imported/CMakeFiles/ALL_BUILD$",
-                    ],
-                },
-                {
-                    "name": "CMake Rules",
-                    "sourcePaths": [
-                        "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/imported/CMakeFiles/ALL_BUILD\\.rule$",
-                    ],
-                },
-            ],
-            "compileGroups": None,
-            "backtrace": [
-                {
-                    "file": "^imported/CMakeLists\\.txt$",
-                    "line": None,
-                    "command": None,
-                    "hasParent": False,
-                },
-            ],
-            "folder": None,
-            "nameOnDisk": None,
-            "artifacts": None,
-            "build": "^imported$",
-            "source": "^imported$",
-            "install": None,
-            "link": None,
-            "archive": None,
-            "dependencies": [
-                {
-                    "id": "^ZERO_CHECK::@ba7eb709d0b48779c6c8$",
-                    "backtrace": None,
-                },
-                {
-                    "id": "^link_imported_exe::@ba7eb709d0b48779c6c8$",
-                    "backtrace": None,
-                },
-                {
-                    "id": "^link_imported_shared_exe::@ba7eb709d0b48779c6c8$",
-                    "backtrace": None,
-                },
-                {
-                    "id": "^link_imported_static_exe::@ba7eb709d0b48779c6c8$",
-                    "backtrace": None,
-                },
-                {
-                    "id": "^link_imported_object_exe::@ba7eb709d0b48779c6c8$",
-                    "backtrace": None,
-                },
-                {
-                    "id": "^link_imported_interface_exe::@ba7eb709d0b48779c6c8$",
-                    "backtrace": None,
-                },
-            ],
-        },
-        {
-            "name": "ZERO_CHECK",
-            "id": "^ZERO_CHECK::@ba7eb709d0b48779c6c8$",
-            "directorySource": "^imported$",
-            "projectName": "Imported",
-            "type": "UTILITY",
-            "isGeneratorProvided": True,
-            "sources": [
-                {
-                    "path": "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/imported/CMakeFiles/ZERO_CHECK$",
-                    "isGenerated": True,
-                    "sourceGroupName": "",
-                    "compileGroupLanguage": None,
-                    "backtrace": [
-                        {
-                            "file": "^imported/CMakeLists\\.txt$",
-                            "line": None,
-                            "command": None,
-                            "hasParent": False,
-                        },
-                    ],
-                },
-                {
-                    "path": "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/imported/CMakeFiles/ZERO_CHECK\\.rule$",
-                    "isGenerated": True,
-                    "sourceGroupName": "CMake Rules",
-                    "compileGroupLanguage": None,
-                    "backtrace": [
-                        {
-                            "file": "^imported/CMakeLists\\.txt$",
-                            "line": None,
-                            "command": None,
-                            "hasParent": False,
-                        },
-                    ],
-                },
-            ],
-            "sourceGroups": [
-                {
-                    "name": "",
-                    "sourcePaths": [
-                        "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/imported/CMakeFiles/ZERO_CHECK$",
-                    ],
-                },
-                {
-                    "name": "CMake Rules",
-                    "sourcePaths": [
-                        "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/imported/CMakeFiles/ZERO_CHECK\\.rule$",
-                    ],
-                },
-            ],
-            "compileGroups": None,
-            "backtrace": [
-                {
-                    "file": "^imported/CMakeLists\\.txt$",
-                    "line": None,
-                    "command": None,
-                    "hasParent": False,
-                },
-            ],
-            "folder": None,
-            "nameOnDisk": None,
-            "artifacts": None,
-            "build": "^imported$",
-            "source": "^imported$",
-            "install": None,
-            "link": None,
-            "archive": None,
-            "dependencies": None,
-        },
-        {
-            "name": "link_imported_exe",
-            "id": "^link_imported_exe::@ba7eb709d0b48779c6c8$",
-            "directorySource": "^imported$",
-            "projectName": "Imported",
-            "type": "EXECUTABLE",
-            "isGeneratorProvided": None,
-            "sources": [
-                {
-                    "path": "^empty\\.c$",
-                    "isGenerated": None,
-                    "sourceGroupName": "Source Files",
-                    "compileGroupLanguage": "C",
-                    "backtrace": [
-                        {
-                            "file": "^imported/CMakeLists\\.txt$",
-                            "line": 5,
-                            "command": "add_executable",
-                            "hasParent": True,
-                        },
-                        {
-                            "file": "^imported/CMakeLists\\.txt$",
-                            "line": None,
-                            "command": None,
-                            "hasParent": False,
-                        },
-                    ],
-                },
-            ],
-            "sourceGroups": [
-                {
-                    "name": "Source Files",
-                    "sourcePaths": [
-                        "^empty\\.c$",
-                    ],
-                },
-            ],
-            "compileGroups": [
-                {
-                    "language": "C",
-                    "sourcePaths": [
-                        "^empty\\.c$",
-                    ],
-                    "includes": None,
-                    "defines": None,
-                    "compileCommandFragments": None,
-                },
-            ],
-            "backtrace": [
-                {
-                    "file": "^imported/CMakeLists\\.txt$",
-                    "line": 5,
-                    "command": "add_executable",
-                    "hasParent": True,
-                },
-                {
-                    "file": "^imported/CMakeLists\\.txt$",
-                    "line": None,
-                    "command": None,
-                    "hasParent": False,
-                },
-            ],
-            "folder": None,
-            "nameOnDisk": "^link_imported_exe(\\.exe)?$",
-            "artifacts": [
-                {
-                    "path": "^imported/((Debug|Release|RelWithDebInfo|MinSizeRel)/)?link_imported_exe(\\.exe)?$",
-                    "_dllExtra": False,
-                },
-                {
-                    "path": "^imported/((Debug|Release|RelWithDebInfo|MinSizeRel)/)?link_imported_exe\\.pdb$",
-                    "_dllExtra": True,
-                },
-            ],
-            "build": "^imported$",
-            "source": "^imported$",
-            "install": None,
-            "link": {
-                "language": "C",
-                "lto": None,
-                "commandFragments": None,
-            },
-            "archive": None,
-            "dependencies": [
-                {
-                    "id": "^ZERO_CHECK::@ba7eb709d0b48779c6c8$",
-                    "backtrace": None,
-                },
-            ],
-        },
-        {
-            "name": "link_imported_shared_exe",
-            "id": "^link_imported_shared_exe::@ba7eb709d0b48779c6c8$",
-            "directorySource": "^imported$",
-            "projectName": "Imported",
-            "type": "EXECUTABLE",
-            "isGeneratorProvided": None,
-            "sources": [
-                {
-                    "path": "^empty\\.c$",
-                    "isGenerated": None,
-                    "sourceGroupName": "Source Files",
-                    "compileGroupLanguage": "C",
-                    "backtrace": [
-                        {
-                            "file": "^imported/CMakeLists\\.txt$",
-                            "line": 9,
-                            "command": "add_executable",
-                            "hasParent": True,
-                        },
-                        {
-                            "file": "^imported/CMakeLists\\.txt$",
-                            "line": None,
-                            "command": None,
-                            "hasParent": False,
-                        },
-                    ],
-                },
-            ],
-            "sourceGroups": [
-                {
-                    "name": "Source Files",
-                    "sourcePaths": [
-                        "^empty\\.c$",
-                    ],
-                },
-            ],
-            "compileGroups": [
-                {
-                    "language": "C",
-                    "sourcePaths": [
-                        "^empty\\.c$",
-                    ],
-                    "includes": None,
-                    "defines": None,
-                    "compileCommandFragments": None,
-                },
-            ],
-            "backtrace": [
-                {
-                    "file": "^imported/CMakeLists\\.txt$",
-                    "line": 9,
-                    "command": "add_executable",
-                    "hasParent": True,
-                },
-                {
-                    "file": "^imported/CMakeLists\\.txt$",
-                    "line": None,
-                    "command": None,
-                    "hasParent": False,
-                },
-            ],
-            "folder": None,
-            "nameOnDisk": "^link_imported_shared_exe(\\.exe)?$",
-            "artifacts": [
-                {
-                    "path": "^imported/((Debug|Release|RelWithDebInfo|MinSizeRel)/)?link_imported_shared_exe(\\.exe)?$",
-                    "_dllExtra": False,
-                },
-                {
-                    "path": "^imported/((Debug|Release|RelWithDebInfo|MinSizeRel)/)?link_imported_shared_exe\\.pdb$",
-                    "_dllExtra": True,
-                },
-            ],
-            "build": "^imported$",
-            "source": "^imported$",
-            "install": None,
-            "link": {
-                "language": "C",
-                "lto": None,
-                "commandFragments": None,
-            },
-            "archive": None,
-            "dependencies": [
-                {
-                    "id": "^ZERO_CHECK::@ba7eb709d0b48779c6c8$",
-                    "backtrace": None,
-                },
-            ],
-        },
-        {
-            "name": "link_imported_static_exe",
-            "id": "^link_imported_static_exe::@ba7eb709d0b48779c6c8$",
-            "directorySource": "^imported$",
-            "projectName": "Imported",
-            "type": "EXECUTABLE",
-            "isGeneratorProvided": None,
-            "sources": [
-                {
-                    "path": "^empty\\.c$",
-                    "isGenerated": None,
-                    "sourceGroupName": "Source Files",
-                    "compileGroupLanguage": "C",
-                    "backtrace": [
-                        {
-                            "file": "^imported/CMakeLists\\.txt$",
-                            "line": 13,
-                            "command": "add_executable",
-                            "hasParent": True,
-                        },
-                        {
-                            "file": "^imported/CMakeLists\\.txt$",
-                            "line": None,
-                            "command": None,
-                            "hasParent": False,
-                        },
-                    ],
-                },
-            ],
-            "sourceGroups": [
-                {
-                    "name": "Source Files",
-                    "sourcePaths": [
-                        "^empty\\.c$",
-                    ],
-                },
-            ],
-            "compileGroups": [
-                {
-                    "language": "C",
-                    "sourcePaths": [
-                        "^empty\\.c$",
-                    ],
-                    "includes": None,
-                    "defines": None,
-                    "compileCommandFragments": None,
-                },
-            ],
-            "backtrace": [
-                {
-                    "file": "^imported/CMakeLists\\.txt$",
-                    "line": 13,
-                    "command": "add_executable",
-                    "hasParent": True,
-                },
-                {
-                    "file": "^imported/CMakeLists\\.txt$",
-                    "line": None,
-                    "command": None,
-                    "hasParent": False,
-                },
-            ],
-            "folder": None,
-            "nameOnDisk": "^link_imported_static_exe(\\.exe)?$",
-            "artifacts": [
-                {
-                    "path": "^imported/((Debug|Release|RelWithDebInfo|MinSizeRel)/)?link_imported_static_exe(\\.exe)?$",
-                    "_dllExtra": False,
-                },
-                {
-                    "path": "^imported/((Debug|Release|RelWithDebInfo|MinSizeRel)/)?link_imported_static_exe\\.pdb$",
-                    "_dllExtra": True,
-                },
-            ],
-            "build": "^imported$",
-            "source": "^imported$",
-            "install": None,
-            "link": {
-                "language": "C",
-                "lto": None,
-                "commandFragments": None,
-            },
-            "archive": None,
-            "dependencies": [
-                {
-                    "id": "^ZERO_CHECK::@ba7eb709d0b48779c6c8$",
-                    "backtrace": None,
-                },
-            ],
-        },
-        {
-            "name": "link_imported_object_exe",
-            "id": "^link_imported_object_exe::@ba7eb709d0b48779c6c8$",
-            "directorySource": "^imported$",
-            "projectName": "Imported",
-            "type": "EXECUTABLE",
-            "isGeneratorProvided": None,
-            "sources": [
-                {
-                    "path": "^empty\\.c$",
-                    "isGenerated": None,
-                    "sourceGroupName": "Source Files",
-                    "compileGroupLanguage": "C",
-                    "backtrace": [
-                        {
-                            "file": "^imported/CMakeLists\\.txt$",
-                            "line": 18,
-                            "command": "add_executable",
-                            "hasParent": True,
-                        },
-                        {
-                            "file": "^imported/CMakeLists\\.txt$",
-                            "line": None,
-                            "command": None,
-                            "hasParent": False,
-                        },
-                    ],
-                },
-            ],
-            "sourceGroups": [
-                {
-                    "name": "Source Files",
-                    "sourcePaths": [
-                        "^empty\\.c$",
-                    ],
-                },
-            ],
-            "compileGroups": [
-                {
-                    "language": "C",
-                    "sourcePaths": [
-                        "^empty\\.c$",
-                    ],
-                    "includes": None,
-                    "defines": None,
-                    "compileCommandFragments": None,
-                },
-            ],
-            "backtrace": [
-                {
-                    "file": "^imported/CMakeLists\\.txt$",
-                    "line": 18,
-                    "command": "add_executable",
-                    "hasParent": True,
-                },
-                {
-                    "file": "^imported/CMakeLists\\.txt$",
-                    "line": None,
-                    "command": None,
-                    "hasParent": False,
-                },
-            ],
-            "folder": None,
-            "nameOnDisk": "^link_imported_object_exe(\\.exe)?$",
-            "artifacts": [
-                {
-                    "path": "^imported/((Debug|Release|RelWithDebInfo|MinSizeRel)/)?link_imported_object_exe(\\.exe)?$",
-                    "_dllExtra": False,
-                },
-                {
-                    "path": "^imported/((Debug|Release|RelWithDebInfo|MinSizeRel)/)?link_imported_object_exe\\.pdb$",
-                    "_dllExtra": True,
-                },
-            ],
-            "build": "^imported$",
-            "source": "^imported$",
-            "install": None,
-            "link": {
-                "language": "C",
-                "lto": None,
-                "commandFragments": None,
-            },
-            "archive": None,
-            "dependencies": [
-                {
-                    "id": "^ZERO_CHECK::@ba7eb709d0b48779c6c8$",
-                    "backtrace": None,
-                },
-            ],
-        },
-        {
-            "name": "link_imported_interface_exe",
-            "id": "^link_imported_interface_exe::@ba7eb709d0b48779c6c8$",
-            "directorySource": "^imported$",
-            "projectName": "Imported",
-            "type": "EXECUTABLE",
-            "isGeneratorProvided": None,
-            "sources": [
-                {
-                    "path": "^empty\\.c$",
-                    "isGenerated": None,
-                    "sourceGroupName": "Source Files",
-                    "compileGroupLanguage": "C",
-                    "backtrace": [
-                        {
-                            "file": "^imported/CMakeLists\\.txt$",
-                            "line": 23,
-                            "command": "add_executable",
-                            "hasParent": True,
-                        },
-                        {
-                            "file": "^imported/CMakeLists\\.txt$",
-                            "line": None,
-                            "command": None,
-                            "hasParent": False,
-                        },
-                    ],
-                },
-            ],
-            "sourceGroups": [
-                {
-                    "name": "Source Files",
-                    "sourcePaths": [
-                        "^empty\\.c$",
-                    ],
-                },
-            ],
-            "compileGroups": [
-                {
-                    "language": "C",
-                    "sourcePaths": [
-                        "^empty\\.c$",
-                    ],
-                    "includes": None,
-                    "defines": None,
-                    "compileCommandFragments": None,
-                },
-            ],
-            "backtrace": [
-                {
-                    "file": "^imported/CMakeLists\\.txt$",
-                    "line": 23,
-                    "command": "add_executable",
-                    "hasParent": True,
-                },
-                {
-                    "file": "^imported/CMakeLists\\.txt$",
-                    "line": None,
-                    "command": None,
-                    "hasParent": False,
-                },
-            ],
-            "folder": None,
-            "nameOnDisk": "^link_imported_interface_exe(\\.exe)?$",
-            "artifacts": [
-                {
-                    "path": "^imported/((Debug|Release|RelWithDebInfo|MinSizeRel)/)?link_imported_interface_exe(\\.exe)?$",
-                    "_dllExtra": False,
-                },
-                {
-                    "path": "^imported/((Debug|Release|RelWithDebInfo|MinSizeRel)/)?link_imported_interface_exe\\.pdb$",
-                    "_dllExtra": True,
-                },
-            ],
-            "build": "^imported$",
-            "source": "^imported$",
-            "install": None,
-            "link": {
-                "language": "C",
-                "lto": None,
-                "commandFragments": None,
-            },
-            "archive": None,
-            "dependencies": [
-                {
-                    "id": "^ZERO_CHECK::@ba7eb709d0b48779c6c8$",
-                    "backtrace": None,
-                },
-            ],
-        },
-        {
-            "name": "ALL_BUILD",
-            "id": "^ALL_BUILD::@c11385ffed57b860da63$",
-            "directorySource": "^custom$",
-            "projectName": "Custom",
-            "type": "UTILITY",
-            "isGeneratorProvided": True,
-            "sources": [
-                {
-                    "path": "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/custom/CMakeFiles/ALL_BUILD$",
-                    "isGenerated": True,
-                    "sourceGroupName": "",
-                    "compileGroupLanguage": None,
-                    "backtrace": [
-                        {
-                            "file": "^custom/CMakeLists\\.txt$",
-                            "line": None,
-                            "command": None,
-                            "hasParent": False,
-                        },
-                    ],
-                },
-                {
-                    "path": "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/custom/CMakeFiles/ALL_BUILD\\.rule$",
-                    "isGenerated": True,
-                    "sourceGroupName": "CMake Rules",
-                    "compileGroupLanguage": None,
-                    "backtrace": [
-                        {
-                            "file": "^custom/CMakeLists\\.txt$",
-                            "line": None,
-                            "command": None,
-                            "hasParent": False,
-                        },
-                    ],
-                },
-            ],
-            "sourceGroups": [
-                {
-                    "name": "",
-                    "sourcePaths": [
-                        "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/custom/CMakeFiles/ALL_BUILD$",
-                    ],
-                },
-                {
-                    "name": "CMake Rules",
-                    "sourcePaths": [
-                        "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/custom/CMakeFiles/ALL_BUILD\\.rule$",
-                    ],
-                },
-            ],
-            "compileGroups": None,
-            "backtrace": [
-                {
-                    "file": "^custom/CMakeLists\\.txt$",
-                    "line": None,
-                    "command": None,
-                    "hasParent": False,
-                },
-            ],
-            "folder": None,
-            "nameOnDisk": None,
-            "artifacts": None,
-            "build": "^custom$",
-            "source": "^custom$",
-            "install": None,
-            "link": None,
-            "archive": None,
-            "dependencies": [
-                {
-                    "id": "^ZERO_CHECK::@c11385ffed57b860da63$",
-                    "backtrace": None,
-                },
-                {
-                    "id": "^custom_exe::@c11385ffed57b860da63$",
-                    "backtrace": None,
-                },
-            ],
-        },
-        {
-            "name": "ZERO_CHECK",
-            "id": "^ZERO_CHECK::@c11385ffed57b860da63$",
-            "directorySource": "^custom$",
-            "projectName": "Custom",
-            "type": "UTILITY",
-            "isGeneratorProvided": True,
-            "sources": [
-                {
-                    "path": "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/custom/CMakeFiles/ZERO_CHECK$",
-                    "isGenerated": True,
-                    "sourceGroupName": "",
-                    "compileGroupLanguage": None,
-                    "backtrace": [
-                        {
-                            "file": "^custom/CMakeLists\\.txt$",
-                            "line": None,
-                            "command": None,
-                            "hasParent": False,
-                        },
-                    ],
-                },
-                {
-                    "path": "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/custom/CMakeFiles/ZERO_CHECK\\.rule$",
-                    "isGenerated": True,
-                    "sourceGroupName": "CMake Rules",
-                    "compileGroupLanguage": None,
-                    "backtrace": [
-                        {
-                            "file": "^custom/CMakeLists\\.txt$",
-                            "line": None,
-                            "command": None,
-                            "hasParent": False,
-                        },
-                    ],
-                },
-            ],
-            "sourceGroups": [
-                {
-                    "name": "",
-                    "sourcePaths": [
-                        "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/custom/CMakeFiles/ZERO_CHECK$",
-                    ],
-                },
-                {
-                    "name": "CMake Rules",
-                    "sourcePaths": [
-                        "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/custom/CMakeFiles/ZERO_CHECK\\.rule$",
-                    ],
-                },
-            ],
-            "compileGroups": None,
-            "backtrace": [
-                {
-                    "file": "^custom/CMakeLists\\.txt$",
-                    "line": None,
-                    "command": None,
-                    "hasParent": False,
-                },
-            ],
-            "folder": None,
-            "nameOnDisk": None,
-            "artifacts": None,
-            "build": "^custom$",
-            "source": "^custom$",
-            "install": None,
-            "link": None,
-            "archive": None,
-            "dependencies": None,
-        },
-        {
-            "name": "custom_tgt",
-            "id": "^custom_tgt::@c11385ffed57b860da63$",
-            "directorySource": "^custom$",
-            "projectName": "Custom",
-            "type": "UTILITY",
-            "isGeneratorProvided": None,
-            "sources": [
-                {
-                    "path": "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/custom/CMakeFiles/custom_tgt$",
-                    "isGenerated": True,
-                    "sourceGroupName": "",
-                    "compileGroupLanguage": None,
-                    "backtrace": [
-                        {
-                            "file": "^custom/CMakeLists\\.txt$",
-                            "line": 3,
-                            "command": "add_custom_target",
-                            "hasParent": True,
-                        },
-                        {
-                            "file": "^custom/CMakeLists\\.txt$",
-                            "line": None,
-                            "command": None,
-                            "hasParent": False,
-                        },
-                    ],
-                },
-                {
-                    "path": "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/(custom/)?CMakeFiles/([0-9a-f]+/)?custom_tgt\\.rule$",
-                    "isGenerated": True,
-                    "sourceGroupName": "CMake Rules",
-                    "compileGroupLanguage": None,
-                    "backtrace": [
-                        {
-                            "file": "^custom/CMakeLists\\.txt$",
-                            "line": None,
-                            "command": None,
-                            "hasParent": False,
-                        },
-                    ],
-                },
-            ],
-            "sourceGroups": [
-                {
-                    "name": "",
-                    "sourcePaths": [
-                        "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/custom/CMakeFiles/custom_tgt$",
-                    ],
-                },
-                {
-                    "name": "CMake Rules",
-                    "sourcePaths": [
-                        "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/(custom/)?CMakeFiles/([0-9a-f]+/)?custom_tgt\\.rule$",
-                    ],
-                },
-            ],
-            "compileGroups": None,
-            "backtrace": [
-                {
-                    "file": "^custom/CMakeLists\\.txt$",
-                    "line": 3,
-                    "command": "add_custom_target",
-                    "hasParent": True,
-                },
-                {
-                    "file": "^custom/CMakeLists\\.txt$",
-                    "line": None,
-                    "command": None,
-                    "hasParent": False,
-                },
-            ],
-            "folder": None,
-            "nameOnDisk": None,
-            "artifacts": None,
-            "build": "^custom$",
-            "source": "^custom$",
-            "install": None,
-            "link": None,
-            "archive": None,
-            "dependencies": [
-                {
-                    "id": "^ZERO_CHECK::@c11385ffed57b860da63$",
-                    "backtrace": None,
-                },
-            ],
-        },
-        {
-            "name": "custom_exe",
-            "id": "^custom_exe::@c11385ffed57b860da63$",
-            "directorySource": "^custom$",
-            "projectName": "Custom",
-            "type": "EXECUTABLE",
-            "isGeneratorProvided": None,
-            "sources": [
-                {
-                    "path": "^empty\\.c$",
-                    "isGenerated": None,
-                    "sourceGroupName": "Source Files",
-                    "compileGroupLanguage": "C",
-                    "backtrace": [
-                        {
-                            "file": "^custom/CMakeLists\\.txt$",
-                            "line": 4,
-                            "command": "add_executable",
-                            "hasParent": True,
-                        },
-                        {
-                            "file": "^custom/CMakeLists\\.txt$",
-                            "line": None,
-                            "command": None,
-                            "hasParent": False,
-                        },
-                    ],
-                },
-            ],
-            "sourceGroups": [
-                {
-                    "name": "Source Files",
-                    "sourcePaths": [
-                        "^empty\\.c$",
-                    ],
-                },
-            ],
-            "compileGroups": [
-                {
-                    "language": "C",
-                    "sourcePaths": [
-                        "^empty\\.c$",
-                    ],
-                    "includes": None,
-                    "defines": None,
-                    "compileCommandFragments": None,
-                },
-            ],
-            "backtrace": [
-                {
-                    "file": "^custom/CMakeLists\\.txt$",
-                    "line": 4,
-                    "command": "add_executable",
-                    "hasParent": True,
-                },
-                {
-                    "file": "^custom/CMakeLists\\.txt$",
-                    "line": None,
-                    "command": None,
-                    "hasParent": False,
-                },
-            ],
-            "folder": None,
-            "nameOnDisk": "^custom_exe(\\.exe)?$",
-            "artifacts": [
-                {
-                    "path": "^custom/((Debug|Release|RelWithDebInfo|MinSizeRel)/)?custom_exe(\\.exe)?$",
-                    "_dllExtra": False,
-                },
-                {
-                    "path": "^custom/((Debug|Release|RelWithDebInfo|MinSizeRel)/)?custom_exe\\.pdb$",
-                    "_dllExtra": True,
-                },
-            ],
-            "build": "^custom$",
-            "source": "^custom$",
-            "install": None,
-            "link": {
-                "language": "C",
-                "lto": None,
-                "commandFragments": None,
-            },
-            "archive": None,
-            "dependencies": [
-                {
-                    "id": "^custom_tgt::@c11385ffed57b860da63$",
-                    "backtrace": [
-                        {
-                            "file": "^custom/CMakeLists\\.txt$",
-                            "line": 5,
-                            "command": "add_dependencies",
-                            "hasParent": True,
-                        },
-                        {
-                            "file": "^custom/CMakeLists\\.txt$",
-                            "line": None,
-                            "command": None,
-                            "hasParent": False,
-                        },
-                    ],
-                },
-                {
-                    "id": "^ZERO_CHECK::@c11385ffed57b860da63$",
-                    "backtrace": None,
-                },
-            ],
-        },
-        {
-            "name": "ALL_BUILD",
-            "id": "^ALL_BUILD::@[0-9a-f]+$",
-            "directorySource": "^.*/Tests/RunCMake/FileAPIExternalSource$",
-            "projectName": "External",
-            "type": "UTILITY",
-            "isGeneratorProvided": True,
-            "sources": [
-                {
-                    "path": "^.*/Tests/RunCMake/FileAPI/FileAPIExternalBuild/CMakeFiles/ALL_BUILD$",
-                    "isGenerated": True,
-                    "sourceGroupName": "",
-                    "compileGroupLanguage": None,
-                    "backtrace": [
-                        {
-                            "file": "^.*/Tests/RunCMake/FileAPIExternalSource/CMakeLists\\.txt$",
-                            "line": None,
-                            "command": None,
-                            "hasParent": False,
-                        },
-                    ],
-                },
-                {
-                    "path": "^.*/Tests/RunCMake/FileAPI/FileAPIExternalBuild/CMakeFiles/ALL_BUILD\\.rule$",
-                    "isGenerated": True,
-                    "sourceGroupName": "CMake Rules",
-                    "compileGroupLanguage": None,
-                    "backtrace": [
-                        {
-                            "file": "^.*/Tests/RunCMake/FileAPIExternalSource/CMakeLists\\.txt$",
-                            "line": None,
-                            "command": None,
-                            "hasParent": False,
-                        },
-                    ],
-                },
-            ],
-            "sourceGroups": [
-                {
-                    "name": "",
-                    "sourcePaths": [
-                        "^.*/Tests/RunCMake/FileAPI/FileAPIExternalBuild/CMakeFiles/ALL_BUILD$",
-                    ],
-                },
-                {
-                    "name": "CMake Rules",
-                    "sourcePaths": [
-                        "^.*/Tests/RunCMake/FileAPI/FileAPIExternalBuild/CMakeFiles/ALL_BUILD\\.rule$",
-                    ],
-                },
-            ],
-            "compileGroups": None,
-            "backtrace": [
-                {
-                    "file": "^.*/Tests/RunCMake/FileAPIExternalSource/CMakeLists\\.txt$",
-                    "line": None,
-                    "command": None,
-                    "hasParent": False,
-                },
-            ],
-            "folder": None,
-            "nameOnDisk": None,
-            "artifacts": None,
-            "build": "^.*/Tests/RunCMake/FileAPI/FileAPIExternalBuild$",
-            "source": "^.*/Tests/RunCMake/FileAPIExternalSource$",
-            "install": None,
-            "link": None,
-            "archive": None,
-            "dependencies": [
-                {
-                    "id": "^ZERO_CHECK::@[0-9a-f]+$",
-                    "backtrace": None,
-                },
-                {
-                    "id": "^generated_exe::@[0-9a-f]+$",
-                    "backtrace": None,
-                },
-            ],
-        },
-        {
-            "name": "ZERO_CHECK",
-            "id": "^ZERO_CHECK::@[0-9a-f]+$",
-            "directorySource": "^.*/Tests/RunCMake/FileAPIExternalSource$",
-            "projectName": "External",
-            "type": "UTILITY",
-            "isGeneratorProvided": True,
-            "sources": [
-                {
-                    "path": "^.*/Tests/RunCMake/FileAPI/FileAPIExternalBuild/CMakeFiles/ZERO_CHECK$",
-                    "isGenerated": True,
-                    "sourceGroupName": "",
-                    "compileGroupLanguage": None,
-                    "backtrace": [
-                        {
-                            "file": "^.*/Tests/RunCMake/FileAPIExternalSource/CMakeLists\\.txt$",
-                            "line": None,
-                            "command": None,
-                            "hasParent": False,
-                        },
-                    ],
-                },
-                {
-                    "path": "^.*/Tests/RunCMake/FileAPI/FileAPIExternalBuild/CMakeFiles/ZERO_CHECK\\.rule$",
-                    "isGenerated": True,
-                    "sourceGroupName": "CMake Rules",
-                    "compileGroupLanguage": None,
-                    "backtrace": [
-                        {
-                            "file": "^.*/Tests/RunCMake/FileAPIExternalSource/CMakeLists\\.txt$",
-                            "line": None,
-                            "command": None,
-                            "hasParent": False,
-                        },
-                    ],
-                },
-            ],
-            "sourceGroups": [
-                {
-                    "name": "",
-                    "sourcePaths": [
-                        "^.*/Tests/RunCMake/FileAPI/FileAPIExternalBuild/CMakeFiles/ZERO_CHECK$",
-                    ],
-                },
-                {
-                    "name": "CMake Rules",
-                    "sourcePaths": [
-                        "^.*/Tests/RunCMake/FileAPI/FileAPIExternalBuild/CMakeFiles/ZERO_CHECK\\.rule$",
-                    ],
-                },
-            ],
-            "compileGroups": None,
-            "backtrace": [
-                {
-                    "file": "^.*/Tests/RunCMake/FileAPIExternalSource/CMakeLists\\.txt$",
-                    "line": None,
-                    "command": None,
-                    "hasParent": False,
-                },
-            ],
-            "folder": None,
-            "nameOnDisk": None,
-            "artifacts": None,
-            "build": "^.*/Tests/RunCMake/FileAPI/FileAPIExternalBuild$",
-            "source": "^.*/Tests/RunCMake/FileAPIExternalSource$",
-            "install": None,
-            "link": None,
-            "archive": None,
-            "dependencies": None,
-        },
-        {
-            "name": "generated_exe",
-            "id": "^generated_exe::@[0-9a-f]+$",
-            "directorySource": "^.*/Tests/RunCMake/FileAPIExternalSource$",
-            "projectName": "External",
-            "type": "EXECUTABLE",
-            "isGeneratorProvided": None,
-            "sources": [
-                {
-                    "path": "^.*/Tests/RunCMake/FileAPIExternalSource/empty\\.c$",
-                    "isGenerated": None,
-                    "sourceGroupName": "Source Files",
-                    "compileGroupLanguage": "C",
-                    "backtrace": [
-                        {
-                            "file": "^.*/Tests/RunCMake/FileAPIExternalSource/CMakeLists\\.txt$",
-                            "line": 5,
-                            "command": "add_executable",
-                            "hasParent": True,
-                        },
-                        {
-                            "file": "^.*/Tests/RunCMake/FileAPIExternalSource/CMakeLists\\.txt$",
-                            "line": None,
-                            "command": None,
-                            "hasParent": False,
-                        },
-                    ],
-                },
-                {
-                    "path": "^.*/Tests/RunCMake/FileAPI/FileAPIExternalBuild/generated\\.cxx$",
-                    "isGenerated": True,
-                    "sourceGroupName": "Generated Source Files",
-                    "compileGroupLanguage": "CXX",
-                    "backtrace": [
-                        {
-                            "file": "^.*/Tests/RunCMake/FileAPIExternalSource/CMakeLists\\.txt$",
-                            "line": 6,
-                            "command": "target_sources",
-                            "hasParent": True,
-                        },
-                        {
-                            "file": "^.*/Tests/RunCMake/FileAPIExternalSource/CMakeLists\\.txt$",
-                            "line": None,
-                            "command": None,
-                            "hasParent": False,
-                        },
-                    ],
-                },
-            ],
-            "sourceGroups": [
-                {
-                    "name": "Source Files",
-                    "sourcePaths": [
-                        "^.*/Tests/RunCMake/FileAPIExternalSource/empty\\.c$",
-                    ],
-                },
-                {
-                    "name": "Generated Source Files",
-                    "sourcePaths": [
-                        "^.*/Tests/RunCMake/FileAPI/FileAPIExternalBuild/generated\\.cxx$",
-                    ],
-                },
-            ],
-            "compileGroups": [
-                {
-                    "language": "C",
-                    "sourcePaths": [
-                        "^.*/Tests/RunCMake/FileAPIExternalSource/empty\\.c$",
-                    ],
-                    "includes": [
-                        {
-                            "path": "^.*/Tests/RunCMake/FileAPI/FileAPIExternalBuild$",
-                            "isSystem": None,
-                            "backtrace": [
-                                {
-                                    "file": "^.*/Tests/RunCMake/FileAPIExternalSource/CMakeLists\\.txt$",
-                                    "line": 10,
-                                    "command": "set_property",
-                                    "hasParent": True,
-                                },
-                                {
-                                    "file": "^.*/Tests/RunCMake/FileAPIExternalSource/CMakeLists\\.txt$",
-                                    "line": None,
-                                    "command": None,
-                                    "hasParent": False,
-                                },
-                            ],
-                        },
-                        {
-                            "path": "^.*/Tests/RunCMake/FileAPIExternalSource$",
-                            "isSystem": True,
-                            "backtrace": [
-                                {
-                                    "file": "^.*/Tests/RunCMake/FileAPIExternalSource/CMakeLists\\.txt$",
-                                    "line": 11,
-                                    "command": "target_include_directories",
-                                    "hasParent": True,
-                                },
-                                {
-                                    "file": "^.*/Tests/RunCMake/FileAPIExternalSource/CMakeLists\\.txt$",
-                                    "line": None,
-                                    "command": None,
-                                    "hasParent": False,
-                                },
-                            ],
-                        },
-                    ],
-                    "defines": [
-                        {
-                            "define": "EMPTY_C=1",
-                            "backtrace": [
-                                {
-                                    "file": "^.*/Tests/RunCMake/FileAPIExternalSource/CMakeLists\\.txt$",
-                                    "line": 9,
-                                    "command": "set_property",
-                                    "hasParent": True,
-                                },
-                                {
-                                    "file": "^.*/Tests/RunCMake/FileAPIExternalSource/CMakeLists\\.txt$",
-                                    "line": None,
-                                    "command": None,
-                                    "hasParent": False,
-                                },
-                            ],
-                        },
-                        {
-                            "define": "SRC_DUMMY",
-                            "backtrace": [
-                                {
-                                    "file": "^.*/Tests/RunCMake/FileAPIExternalSource/CMakeLists\\.txt$",
-                                    "line": 9,
-                                    "command": "set_property",
-                                    "hasParent": True,
-                                },
-                                {
-                                    "file": "^.*/Tests/RunCMake/FileAPIExternalSource/CMakeLists\\.txt$",
-                                    "line": None,
-                                    "command": None,
-                                    "hasParent": False,
-                                },
-                            ],
-                        },
-                        {
-                            "define": "GENERATED_EXE=1",
-                            "backtrace": [
-                                {
-                                    "file": "^.*/Tests/RunCMake/FileAPIExternalSource/CMakeLists\\.txt$",
-                                    "line": 12,
-                                    "command": "target_compile_definitions",
-                                    "hasParent": True,
-                                },
-                                {
-                                    "file": "^.*/Tests/RunCMake/FileAPIExternalSource/CMakeLists\\.txt$",
-                                    "line": None,
-                                    "command": None,
-                                    "hasParent": False,
-                                },
-                            ],
-                        },
-                        {
-                            "define": "TGT_DUMMY",
-                            "backtrace": [
-                                {
-                                    "file": "^.*/Tests/RunCMake/FileAPIExternalSource/CMakeLists\\.txt$",
-                                    "line": 12,
-                                    "command": "target_compile_definitions",
-                                    "hasParent": True,
-                                },
-                                {
-                                    "file": "^.*/Tests/RunCMake/FileAPIExternalSource/CMakeLists\\.txt$",
-                                    "line": None,
-                                    "command": None,
-                                    "hasParent": False,
-                                },
-                            ],
-                        },
-                    ],
-                    "compileCommandFragments": [
-                        {
-                            "fragment" : "SRC_COMPILE_OPTIONS_DUMMY",
-                            "backtrace": [
-                                {
-                                    "file": "^.*/Tests/RunCMake/FileAPIExternalSource/CMakeLists\\.txt$",
-                                    "line": 13,
-                                    "command": "set_source_files_properties",
-                                    "hasParent": True,
-                                },
-                                {
-                                    "file" : "^.*/Tests/RunCMake/FileAPIExternalSource/CMakeLists\\.txt$",
-                                    "line": None,
-                                    "command": None,
-                                    "hasParent": False,
-                                },
-                            ],
-                        }
-                    ],
-                },
-                {
-                    "language": "CXX",
-                    "sourcePaths": [
-                        "^.*/Tests/RunCMake/FileAPI/FileAPIExternalBuild/generated\\.cxx$",
-                    ],
-                    "includes": [
-                        {
-                            "path": "^.*/Tests/RunCMake/FileAPIExternalSource$",
-                            "isSystem": True,
-                            "backtrace": [
-                                {
-                                    "file": "^.*/Tests/RunCMake/FileAPIExternalSource/CMakeLists\\.txt$",
-                                    "line": 11,
-                                    "command": "target_include_directories",
-                                    "hasParent": True,
-                                },
-                                {
-                                    "file": "^.*/Tests/RunCMake/FileAPIExternalSource/CMakeLists\\.txt$",
-                                    "line": None,
-                                    "command": None,
-                                    "hasParent": False,
-                                },
-                            ],
-                        },
-                    ],
-                    "defines": [
-                        {
-                            "define": "GENERATED_EXE=1",
-                            "backtrace": [
-                                {
-                                    "file": "^.*/Tests/RunCMake/FileAPIExternalSource/CMakeLists\\.txt$",
-                                    "line": 12,
-                                    "command": "target_compile_definitions",
-                                    "hasParent": True,
-                                },
-                                {
-                                    "file": "^.*/Tests/RunCMake/FileAPIExternalSource/CMakeLists\\.txt$",
-                                    "line": None,
-                                    "command": None,
-                                    "hasParent": False,
-                                },
-                            ],
-                        },
-                        {
-                            "define": "TGT_DUMMY",
-                            "backtrace": [
-                                {
-                                    "file": "^.*/Tests/RunCMake/FileAPIExternalSource/CMakeLists\\.txt$",
-                                    "line": 12,
-                                    "command": "target_compile_definitions",
-                                    "hasParent": True,
-                                },
-                                {
-                                    "file": "^.*/Tests/RunCMake/FileAPIExternalSource/CMakeLists\\.txt$",
-                                    "line": None,
-                                    "command": None,
-                                    "hasParent": False,
-                                },
-                            ],
-                        },
-                    ],
-                    "compileCommandFragments": None,
-                },
-            ],
-            "backtrace": [
-                {
-                    "file": "^.*/Tests/RunCMake/FileAPIExternalSource/CMakeLists\\.txt$",
-                    "line": 5,
-                    "command": "add_executable",
-                    "hasParent": True,
-                },
-                {
-                    "file": "^.*/Tests/RunCMake/FileAPIExternalSource/CMakeLists\\.txt$",
-                    "line": None,
-                    "command": None,
-                    "hasParent": False,
-                },
-            ],
-            "folder": None,
-            "nameOnDisk": "^generated_exe(\\.exe)?$",
-            "artifacts": [
-                {
-                    "path": "^.*/Tests/RunCMake/FileAPI/FileAPIExternalBuild/((Debug|Release|RelWithDebInfo|MinSizeRel)/)?generated_exe(\\.exe)?$",
-                    "_dllExtra": False,
-                },
-                {
-                    "path": "^.*/Tests/RunCMake/FileAPI/FileAPIExternalBuild/((Debug|Release|RelWithDebInfo|MinSizeRel)/)?generated_exe\\.pdb$",
-                    "_dllExtra": True,
-                },
-            ],
-            "build": "^.*/Tests/RunCMake/FileAPI/FileAPIExternalBuild$",
-            "source": "^.*/Tests/RunCMake/FileAPIExternalSource$",
-            "install": None,
-            "link": {
-                "language": "CXX",
-                "lto": None,
-                "commandFragments": None,
-            },
-            "archive": None,
-            "dependencies": [
-                {
-                    "id": "^ZERO_CHECK::@[0-9a-f]+$",
-                    "backtrace": None,
-                },
-            ],
-        },
+        read_codemodel_json_data("targets/all_build_top.json"),
+        read_codemodel_json_data("targets/zero_check_top.json"),
+        read_codemodel_json_data("targets/interface_exe.json"),
+        read_codemodel_json_data("targets/c_lib.json"),
+        read_codemodel_json_data("targets/c_exe.json"),
+        read_codemodel_json_data("targets/c_shared_lib.json"),
+        read_codemodel_json_data("targets/c_shared_exe.json"),
+        read_codemodel_json_data("targets/c_static_lib.json"),
+        read_codemodel_json_data("targets/c_static_exe.json"),
+
+        read_codemodel_json_data("targets/all_build_cxx.json"),
+        read_codemodel_json_data("targets/zero_check_cxx.json"),
+        read_codemodel_json_data("targets/cxx_lib.json"),
+        read_codemodel_json_data("targets/cxx_exe.json"),
+        read_codemodel_json_data("targets/cxx_standard_compile_feature_exe.json"),
+        read_codemodel_json_data("targets/cxx_standard_exe.json"),
+        read_codemodel_json_data("targets/cxx_shared_lib.json"),
+        read_codemodel_json_data("targets/cxx_shared_exe.json"),
+        read_codemodel_json_data("targets/cxx_static_lib.json"),
+        read_codemodel_json_data("targets/cxx_static_exe.json"),
+
+        read_codemodel_json_data("targets/all_build_alias.json"),
+        read_codemodel_json_data("targets/zero_check_alias.json"),
+        read_codemodel_json_data("targets/c_alias_exe.json"),
+        read_codemodel_json_data("targets/cxx_alias_exe.json"),
+
+        read_codemodel_json_data("targets/all_build_object.json"),
+        read_codemodel_json_data("targets/zero_check_object.json"),
+        read_codemodel_json_data("targets/c_object_lib.json"),
+        read_codemodel_json_data("targets/c_object_exe.json"),
+        read_codemodel_json_data("targets/cxx_object_lib.json"),
+        read_codemodel_json_data("targets/cxx_object_exe.json"),
+
+        read_codemodel_json_data("targets/all_build_imported.json"),
+        read_codemodel_json_data("targets/zero_check_imported.json"),
+        read_codemodel_json_data("targets/link_imported_exe.json"),
+        read_codemodel_json_data("targets/link_imported_shared_exe.json"),
+        read_codemodel_json_data("targets/link_imported_static_exe.json"),
+        read_codemodel_json_data("targets/link_imported_object_exe.json"),
+        read_codemodel_json_data("targets/link_imported_interface_exe.json"),
+
+        read_codemodel_json_data("targets/all_build_interface.json"),
+        read_codemodel_json_data("targets/zero_check_interface.json"),
+        read_codemodel_json_data("targets/iface_srcs.json"),
+
+        read_codemodel_json_data("targets/all_build_custom.json"),
+        read_codemodel_json_data("targets/zero_check_custom.json"),
+        read_codemodel_json_data("targets/custom_tgt.json"),
+        read_codemodel_json_data("targets/custom_exe.json"),
+        read_codemodel_json_data("targets/all_build_external.json"),
+        read_codemodel_json_data("targets/zero_check_external.json"),
+        read_codemodel_json_data("targets/generated_exe.json"),
     ]
 
+    if cxx_compiler_id in ['Clang', 'AppleClang', 'GNU', 'Intel', 'MSVC', 'Embarcadero'] and g["name"] != "Xcode":
+        for e in expected:
+            if e["name"] == "cxx_exe":
+                if matches(g["name"], "^(Visual Studio |Ninja Multi-Config)"):
+                    precompile_header_data = read_codemodel_json_data("targets/cxx_exe_precompileheader_multigen.json")
+                else:
+                    if ';' in os.environ.get("CMAKE_OSX_ARCHITECTURES", ""):
+                        precompile_header_data = read_codemodel_json_data("targets/cxx_exe_precompileheader_2arch.json")
+                    else:
+                        precompile_header_data = read_codemodel_json_data("targets/cxx_exe_precompileheader.json")
+                e["compileGroups"] = precompile_header_data["compileGroups"]
+                e["sources"] = precompile_header_data["sources"]
+                e["sourceGroups"] = precompile_header_data["sourceGroups"]
+
+    if os.path.exists(os.path.join(reply_dir, "..", "..", "..", "..", "cxx", "cxx_std_11.txt")):
+        for e in expected:
+            if e["name"] == "cxx_standard_compile_feature_exe":
+                language_standard_data = read_codemodel_json_data("targets/cxx_standard_compile_feature_exe_languagestandard.json")
+                e["compileGroups"][0]["languageStandard"] = language_standard_data["languageStandard"]
+
     if not os.path.exists(os.path.join(reply_dir, "..", "..", "..", "..", "ipo_enabled.txt")):
         for e in expected:
             try:
@@ -5164,126 +722,14 @@
 
 def gen_check_projects(c, g):
     expected = [
-        {
-            "name": "codemodel-v2",
-            "parentName": None,
-            "childNames": [
-                "Alias",
-                "Custom",
-                "Cxx",
-                "Imported",
-                "Object",
-                "External",
-            ],
-            "directorySources": [
-                "^\\.$",
-                "^dir$",
-                "^dir/dir$",
-            ],
-            "targetIds": [
-                "^ALL_BUILD::@6890427a1f51a3e7e1df$",
-                "^ZERO_CHECK::@6890427a1f51a3e7e1df$",
-                "^interface_exe::@6890427a1f51a3e7e1df$",
-                "^c_lib::@6890427a1f51a3e7e1df$",
-                "^c_exe::@6890427a1f51a3e7e1df$",
-                "^c_shared_lib::@6890427a1f51a3e7e1df$",
-                "^c_shared_exe::@6890427a1f51a3e7e1df$",
-                "^c_static_lib::@6890427a1f51a3e7e1df$",
-                "^c_static_exe::@6890427a1f51a3e7e1df$",
-            ],
-        },
-        {
-            "name": "Cxx",
-            "parentName": "codemodel-v2",
-            "childNames": None,
-            "directorySources": [
-                "^cxx$",
-            ],
-            "targetIds": [
-                "^ALL_BUILD::@a56b12a3f5c0529fb296$",
-                "^ZERO_CHECK::@a56b12a3f5c0529fb296$",
-                "^cxx_lib::@a56b12a3f5c0529fb296$",
-                "^cxx_exe::@a56b12a3f5c0529fb296$",
-                "^cxx_shared_lib::@a56b12a3f5c0529fb296$",
-                "^cxx_shared_exe::@a56b12a3f5c0529fb296$",
-                "^cxx_static_lib::@a56b12a3f5c0529fb296$",
-                "^cxx_static_exe::@a56b12a3f5c0529fb296$",
-            ],
-        },
-        {
-            "name": "Alias",
-            "parentName": "codemodel-v2",
-            "childNames": None,
-            "directorySources": [
-                "^alias$",
-            ],
-            "targetIds": [
-                "^ALL_BUILD::@53632cba2752272bb008$",
-                "^ZERO_CHECK::@53632cba2752272bb008$",
-                "^c_alias_exe::@53632cba2752272bb008$",
-                "^cxx_alias_exe::@53632cba2752272bb008$",
-            ],
-        },
-        {
-            "name": "Object",
-            "parentName": "codemodel-v2",
-            "childNames": None,
-            "directorySources": [
-                "^object$",
-            ],
-            "targetIds": [
-                "^ALL_BUILD::@5ed5358f70faf8d8af7a$",
-                "^ZERO_CHECK::@5ed5358f70faf8d8af7a$",
-                "^c_object_lib::@5ed5358f70faf8d8af7a$",
-                "^c_object_exe::@5ed5358f70faf8d8af7a$",
-                "^cxx_object_lib::@5ed5358f70faf8d8af7a$",
-                "^cxx_object_exe::@5ed5358f70faf8d8af7a$",
-            ],
-        },
-        {
-            "name": "Imported",
-            "parentName": "codemodel-v2",
-            "childNames": None,
-            "directorySources": [
-                "^imported$",
-            ],
-            "targetIds": [
-                "^ALL_BUILD::@ba7eb709d0b48779c6c8$",
-                "^ZERO_CHECK::@ba7eb709d0b48779c6c8$",
-                "^link_imported_exe::@ba7eb709d0b48779c6c8$",
-                "^link_imported_shared_exe::@ba7eb709d0b48779c6c8$",
-                "^link_imported_static_exe::@ba7eb709d0b48779c6c8$",
-                "^link_imported_object_exe::@ba7eb709d0b48779c6c8$",
-                "^link_imported_interface_exe::@ba7eb709d0b48779c6c8$",
-            ],
-        },
-        {
-            "name": "Custom",
-            "parentName": "codemodel-v2",
-            "childNames": None,
-            "directorySources": [
-                "^custom$",
-            ],
-            "targetIds": [
-                "^ALL_BUILD::@c11385ffed57b860da63$",
-                "^ZERO_CHECK::@c11385ffed57b860da63$",
-                "^custom_tgt::@c11385ffed57b860da63$",
-                "^custom_exe::@c11385ffed57b860da63$",
-            ],
-        },
-        {
-            "name": "External",
-            "parentName": "codemodel-v2",
-            "childNames": None,
-            "directorySources": [
-                "^.*/Tests/RunCMake/FileAPIExternalSource$",
-            ],
-            "targetIds": [
-                "^ALL_BUILD::@[0-9a-f]+$",
-                "^ZERO_CHECK::@[0-9a-f]+$",
-                "^generated_exe::@[0-9a-f]+$",
-            ],
-        },
+        read_codemodel_json_data("projects/codemodel-v2.json"),
+        read_codemodel_json_data("projects/cxx.json"),
+        read_codemodel_json_data("projects/alias.json"),
+        read_codemodel_json_data("projects/object.json"),
+        read_codemodel_json_data("projects/imported.json"),
+        read_codemodel_json_data("projects/interface.json"),
+        read_codemodel_json_data("projects/custom.json"),
+        read_codemodel_json_data("projects/external.json"),
     ]
 
     if matches(g["name"], "^Visual Studio "):
@@ -5337,6 +783,7 @@
             check_object_codemodel_configuration(c, g, inSource)
     return _check
 
+cxx_compiler_id = sys.argv[2]
 assert is_dict(index)
 assert sorted(index.keys()) == ["cmake", "objects", "reply"]
 check_objects(index["objects"], index["cmake"]["generator"])
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/directories/alias.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/directories/alias.json
new file mode 100644
index 0000000..9f0c48a
--- /dev/null
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/directories/alias.json
@@ -0,0 +1,15 @@
+{
+    "source": "^alias$",
+    "build": "^alias$",
+    "parentSource": "^\\.$",
+    "childSources": null,
+    "targetIds": [
+        "^ALL_BUILD::@53632cba2752272bb008$",
+        "^ZERO_CHECK::@53632cba2752272bb008$",
+        "^c_alias_exe::@53632cba2752272bb008$",
+        "^cxx_alias_exe::@53632cba2752272bb008$"
+    ],
+    "projectName": "Alias",
+    "minimumCMakeVersion": "3.12",
+    "hasInstallRule": null
+}
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/directories/custom.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/directories/custom.json
new file mode 100644
index 0000000..afd41f3
--- /dev/null
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/directories/custom.json
@@ -0,0 +1,15 @@
+{
+    "source": "^custom$",
+    "build": "^custom$",
+    "parentSource": "^\\.$",
+    "childSources": null,
+    "targetIds": [
+        "^ALL_BUILD::@c11385ffed57b860da63$",
+        "^ZERO_CHECK::@c11385ffed57b860da63$",
+        "^custom_exe::@c11385ffed57b860da63$",
+        "^custom_tgt::@c11385ffed57b860da63$"
+    ],
+    "projectName": "Custom",
+    "minimumCMakeVersion": "3.12",
+    "hasInstallRule": null
+}
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/directories/cxx.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/directories/cxx.json
new file mode 100644
index 0000000..a51b6eb
--- /dev/null
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/directories/cxx.json
@@ -0,0 +1,21 @@
+{
+    "source": "^cxx$",
+    "build": "^cxx$",
+    "parentSource": "^\\.$",
+    "childSources": null,
+    "targetIds": [
+        "^ALL_BUILD::@a56b12a3f5c0529fb296$",
+        "^ZERO_CHECK::@a56b12a3f5c0529fb296$",
+        "^cxx_exe::@a56b12a3f5c0529fb296$",
+        "^cxx_standard_compile_feature_exe::@a56b12a3f5c0529fb296$",
+        "^cxx_standard_exe::@a56b12a3f5c0529fb296$",
+        "^cxx_lib::@a56b12a3f5c0529fb296$",
+        "^cxx_shared_exe::@a56b12a3f5c0529fb296$",
+        "^cxx_shared_lib::@a56b12a3f5c0529fb296$",
+        "^cxx_static_exe::@a56b12a3f5c0529fb296$",
+        "^cxx_static_lib::@a56b12a3f5c0529fb296$"
+    ],
+    "projectName": "Cxx",
+    "minimumCMakeVersion": "3.12",
+    "hasInstallRule": null
+}
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/directories/dir.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/directories/dir.json
new file mode 100644
index 0000000..afbd43a
--- /dev/null
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/directories/dir.json
@@ -0,0 +1,12 @@
+{
+    "source": "^dir$",
+    "build": "^dir$",
+    "parentSource": "^\\.$",
+    "childSources": [
+        "^dir/dir$"
+    ],
+    "targetIds": null,
+    "projectName": "codemodel-v2",
+    "minimumCMakeVersion": "3.12",
+    "hasInstallRule": null
+}
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/directories/dir_dir.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/directories/dir_dir.json
new file mode 100644
index 0000000..3737ad5
--- /dev/null
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/directories/dir_dir.json
@@ -0,0 +1,10 @@
+{
+    "source": "^dir/dir$",
+    "build": "^dir/dir$",
+    "parentSource": "^dir$",
+    "childSources": null,
+    "targetIds": null,
+    "projectName": "codemodel-v2",
+    "minimumCMakeVersion": "3.12",
+    "hasInstallRule": null
+}
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/directories/external.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/directories/external.json
new file mode 100644
index 0000000..521e3c7
--- /dev/null
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/directories/external.json
@@ -0,0 +1,14 @@
+{
+    "source": "^.*/Tests/RunCMake/FileAPIExternalSource$",
+    "build": "^.*/Tests/RunCMake/FileAPI/FileAPIExternalBuild$",
+    "parentSource": "^\\.$",
+    "childSources": null,
+    "targetIds": [
+        "^ALL_BUILD::@[0-9a-f]+$",
+        "^ZERO_CHECK::@[0-9a-f]+$",
+        "^generated_exe::@[0-9a-f]+$"
+    ],
+    "projectName": "External",
+    "minimumCMakeVersion": "3.12",
+    "hasInstallRule": null
+}
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/directories/imported.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/directories/imported.json
new file mode 100644
index 0000000..a41b79b
--- /dev/null
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/directories/imported.json
@@ -0,0 +1,18 @@
+{
+    "source": "^imported$",
+    "build": "^imported$",
+    "parentSource": "^\\.$",
+    "childSources": null,
+    "targetIds": [
+        "^ALL_BUILD::@ba7eb709d0b48779c6c8$",
+        "^ZERO_CHECK::@ba7eb709d0b48779c6c8$",
+        "^link_imported_exe::@ba7eb709d0b48779c6c8$",
+        "^link_imported_interface_exe::@ba7eb709d0b48779c6c8$",
+        "^link_imported_object_exe::@ba7eb709d0b48779c6c8$",
+        "^link_imported_shared_exe::@ba7eb709d0b48779c6c8$",
+        "^link_imported_static_exe::@ba7eb709d0b48779c6c8$"
+    ],
+    "projectName": "Imported",
+    "minimumCMakeVersion": "3.12",
+    "hasInstallRule": null
+}
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/directories/interface.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/directories/interface.json
new file mode 100644
index 0000000..b10d496
--- /dev/null
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/directories/interface.json
@@ -0,0 +1,14 @@
+{
+    "source": "^interface$",
+    "build": "^interface$",
+    "parentSource": "^\\.$",
+    "childSources": null,
+    "targetIds": [
+        "^ALL_BUILD::@25b7fa8ea00134654b85$",
+        "^ZERO_CHECK::@25b7fa8ea00134654b85$",
+        "^iface_srcs::@25b7fa8ea00134654b85$"
+    ],
+    "projectName": "Interface",
+    "minimumCMakeVersion": "3.12",
+    "hasInstallRule": null
+}
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/directories/object.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/directories/object.json
new file mode 100644
index 0000000..1e647ad
--- /dev/null
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/directories/object.json
@@ -0,0 +1,17 @@
+{
+    "source": "^object$",
+    "build": "^object$",
+    "parentSource": "^\\.$",
+    "childSources": null,
+    "targetIds": [
+        "^ALL_BUILD::@5ed5358f70faf8d8af7a$",
+        "^ZERO_CHECK::@5ed5358f70faf8d8af7a$",
+        "^c_object_exe::@5ed5358f70faf8d8af7a$",
+        "^c_object_lib::@5ed5358f70faf8d8af7a$",
+        "^cxx_object_exe::@5ed5358f70faf8d8af7a$",
+        "^cxx_object_lib::@5ed5358f70faf8d8af7a$"
+    ],
+    "projectName": "Object",
+    "minimumCMakeVersion": "3.13",
+    "hasInstallRule": true
+}
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/directories/top.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/directories/top.json
new file mode 100644
index 0000000..736d1f5
--- /dev/null
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/directories/top.json
@@ -0,0 +1,29 @@
+{
+    "source": "^\\.$",
+    "build": "^\\.$",
+    "parentSource": null,
+    "childSources": [
+        "^alias$",
+        "^custom$",
+        "^cxx$",
+        "^imported$",
+        "^interface$",
+        "^object$",
+        "^.*/Tests/RunCMake/FileAPIExternalSource$",
+        "^dir$"
+    ],
+    "targetIds": [
+        "^ALL_BUILD::@6890427a1f51a3e7e1df$",
+        "^ZERO_CHECK::@6890427a1f51a3e7e1df$",
+        "^c_exe::@6890427a1f51a3e7e1df$",
+        "^c_lib::@6890427a1f51a3e7e1df$",
+        "^c_shared_exe::@6890427a1f51a3e7e1df$",
+        "^c_shared_lib::@6890427a1f51a3e7e1df$",
+        "^c_static_exe::@6890427a1f51a3e7e1df$",
+        "^c_static_lib::@6890427a1f51a3e7e1df$",
+        "^interface_exe::@6890427a1f51a3e7e1df$"
+    ],
+    "projectName": "codemodel-v2",
+    "minimumCMakeVersion": "3.12",
+    "hasInstallRule": true
+}
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/projects/alias.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/projects/alias.json
new file mode 100644
index 0000000..8ede60f
--- /dev/null
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/projects/alias.json
@@ -0,0 +1,14 @@
+{
+    "name": "Alias",
+    "parentName": "codemodel-v2",
+    "childNames": null,
+    "directorySources": [
+        "^alias$"
+    ],
+    "targetIds": [
+        "^ALL_BUILD::@53632cba2752272bb008$",
+        "^ZERO_CHECK::@53632cba2752272bb008$",
+        "^c_alias_exe::@53632cba2752272bb008$",
+        "^cxx_alias_exe::@53632cba2752272bb008$"
+    ]
+}
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/projects/codemodel-v2.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/projects/codemodel-v2.json
new file mode 100644
index 0000000..4d0cdc0
--- /dev/null
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/projects/codemodel-v2.json
@@ -0,0 +1,29 @@
+{
+    "name": "codemodel-v2",
+    "parentName": null,
+    "childNames": [
+        "Alias",
+        "Custom",
+        "Cxx",
+        "Imported",
+        "Interface",
+        "Object",
+        "External"
+    ],
+    "directorySources": [
+        "^\\.$",
+        "^dir$",
+        "^dir/dir$"
+    ],
+    "targetIds": [
+        "^ALL_BUILD::@6890427a1f51a3e7e1df$",
+        "^ZERO_CHECK::@6890427a1f51a3e7e1df$",
+        "^interface_exe::@6890427a1f51a3e7e1df$",
+        "^c_lib::@6890427a1f51a3e7e1df$",
+        "^c_exe::@6890427a1f51a3e7e1df$",
+        "^c_shared_lib::@6890427a1f51a3e7e1df$",
+        "^c_shared_exe::@6890427a1f51a3e7e1df$",
+        "^c_static_lib::@6890427a1f51a3e7e1df$",
+        "^c_static_exe::@6890427a1f51a3e7e1df$"
+    ]
+}
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/projects/custom.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/projects/custom.json
new file mode 100644
index 0000000..0aeb727
--- /dev/null
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/projects/custom.json
@@ -0,0 +1,14 @@
+{
+    "name": "Custom",
+    "parentName": "codemodel-v2",
+    "childNames": null,
+    "directorySources": [
+        "^custom$"
+    ],
+    "targetIds": [
+        "^ALL_BUILD::@c11385ffed57b860da63$",
+        "^ZERO_CHECK::@c11385ffed57b860da63$",
+        "^custom_tgt::@c11385ffed57b860da63$",
+        "^custom_exe::@c11385ffed57b860da63$"
+    ]
+}
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/projects/cxx.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/projects/cxx.json
new file mode 100644
index 0000000..363e853
--- /dev/null
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/projects/cxx.json
@@ -0,0 +1,20 @@
+{
+    "name": "Cxx",
+    "parentName": "codemodel-v2",
+    "childNames": null,
+    "directorySources": [
+        "^cxx$"
+    ],
+    "targetIds": [
+        "^ALL_BUILD::@a56b12a3f5c0529fb296$",
+        "^ZERO_CHECK::@a56b12a3f5c0529fb296$",
+        "^cxx_lib::@a56b12a3f5c0529fb296$",
+        "^cxx_exe::@a56b12a3f5c0529fb296$",
+        "^cxx_standard_compile_feature_exe::@a56b12a3f5c0529fb296$",
+        "^cxx_standard_exe::@a56b12a3f5c0529fb296$",
+        "^cxx_shared_lib::@a56b12a3f5c0529fb296$",
+        "^cxx_shared_exe::@a56b12a3f5c0529fb296$",
+        "^cxx_static_lib::@a56b12a3f5c0529fb296$",
+        "^cxx_static_exe::@a56b12a3f5c0529fb296$"
+    ]
+}
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/projects/external.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/projects/external.json
new file mode 100644
index 0000000..3c9afff
--- /dev/null
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/projects/external.json
@@ -0,0 +1,13 @@
+{
+    "name": "External",
+    "parentName": "codemodel-v2",
+    "childNames": null,
+    "directorySources": [
+        "^.*/Tests/RunCMake/FileAPIExternalSource$"
+    ],
+    "targetIds": [
+        "^ALL_BUILD::@[0-9a-f]+$",
+        "^ZERO_CHECK::@[0-9a-f]+$",
+        "^generated_exe::@[0-9a-f]+$"
+    ]
+}
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/projects/imported.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/projects/imported.json
new file mode 100644
index 0000000..dc40b72
--- /dev/null
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/projects/imported.json
@@ -0,0 +1,17 @@
+{
+    "name": "Imported",
+    "parentName": "codemodel-v2",
+    "childNames": null,
+    "directorySources": [
+        "^imported$"
+    ],
+    "targetIds": [
+        "^ALL_BUILD::@ba7eb709d0b48779c6c8$",
+        "^ZERO_CHECK::@ba7eb709d0b48779c6c8$",
+        "^link_imported_exe::@ba7eb709d0b48779c6c8$",
+        "^link_imported_shared_exe::@ba7eb709d0b48779c6c8$",
+        "^link_imported_static_exe::@ba7eb709d0b48779c6c8$",
+        "^link_imported_object_exe::@ba7eb709d0b48779c6c8$",
+        "^link_imported_interface_exe::@ba7eb709d0b48779c6c8$"
+    ]
+}
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/projects/interface.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/projects/interface.json
new file mode 100644
index 0000000..2a22767
--- /dev/null
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/projects/interface.json
@@ -0,0 +1,13 @@
+{
+    "name": "Interface",
+    "parentName": "codemodel-v2",
+    "childNames": null,
+    "directorySources": [
+        "^interface$"
+    ],
+    "targetIds": [
+        "^ALL_BUILD::@25b7fa8ea00134654b85$",
+        "^ZERO_CHECK::@25b7fa8ea00134654b85$",
+        "^iface_srcs::@25b7fa8ea00134654b85$"
+    ]
+}
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/projects/object.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/projects/object.json
new file mode 100644
index 0000000..219f4eb
--- /dev/null
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/projects/object.json
@@ -0,0 +1,16 @@
+{
+    "name": "Object",
+    "parentName": "codemodel-v2",
+    "childNames": null,
+    "directorySources": [
+        "^object$"
+    ],
+    "targetIds": [
+        "^ALL_BUILD::@5ed5358f70faf8d8af7a$",
+        "^ZERO_CHECK::@5ed5358f70faf8d8af7a$",
+        "^c_object_lib::@5ed5358f70faf8d8af7a$",
+        "^c_object_exe::@5ed5358f70faf8d8af7a$",
+        "^cxx_object_lib::@5ed5358f70faf8d8af7a$",
+        "^cxx_object_exe::@5ed5358f70faf8d8af7a$"
+    ]
+}
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/all_build_alias.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/all_build_alias.json
new file mode 100644
index 0000000..eabf739
--- /dev/null
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/all_build_alias.json
@@ -0,0 +1,83 @@
+{
+    "name": "ALL_BUILD",
+    "id": "^ALL_BUILD::@53632cba2752272bb008$",
+    "directorySource": "^alias$",
+    "projectName": "Alias",
+    "type": "UTILITY",
+    "isGeneratorProvided": true,
+    "sources": [
+        {
+            "path": "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/alias/CMakeFiles/ALL_BUILD$",
+            "isGenerated": true,
+            "sourceGroupName": "",
+            "compileGroupLanguage": null,
+            "backtrace": [
+                {
+                    "file": "^alias/CMakeLists\\.txt$",
+                    "line": null,
+                    "command": null,
+                    "hasParent": false
+                }
+            ]
+        },
+        {
+            "path": "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/alias/CMakeFiles/ALL_BUILD\\.rule$",
+            "isGenerated": true,
+            "sourceGroupName": "CMake Rules",
+            "compileGroupLanguage": null,
+            "backtrace": [
+                {
+                    "file": "^alias/CMakeLists\\.txt$",
+                    "line": null,
+                    "command": null,
+                    "hasParent": false
+                }
+            ]
+        }
+    ],
+    "sourceGroups": [
+        {
+            "name": "",
+            "sourcePaths": [
+                "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/alias/CMakeFiles/ALL_BUILD$"
+            ]
+        },
+        {
+            "name": "CMake Rules",
+            "sourcePaths": [
+                "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/alias/CMakeFiles/ALL_BUILD\\.rule$"
+            ]
+        }
+    ],
+    "compileGroups": null,
+    "backtrace": [
+        {
+            "file": "^alias/CMakeLists\\.txt$",
+            "line": null,
+            "command": null,
+            "hasParent": false
+        }
+    ],
+    "folder": null,
+    "nameOnDisk": null,
+    "artifacts": null,
+    "build": "^alias$",
+    "source": "^alias$",
+    "install": null,
+    "link": null,
+    "archive": null,
+    "dependencies": [
+        {
+            "id": "^ZERO_CHECK::@53632cba2752272bb008$",
+            "backtrace": null
+        },
+        {
+            "id": "^c_alias_exe::@53632cba2752272bb008$",
+            "backtrace": null
+        },
+        {
+            "id": "^cxx_alias_exe::@53632cba2752272bb008$",
+            "backtrace": null
+        }
+    ]
+}
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/all_build_custom.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/all_build_custom.json
new file mode 100644
index 0000000..a5ff686
--- /dev/null
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/all_build_custom.json
@@ -0,0 +1,79 @@
+{
+    "name": "ALL_BUILD",
+    "id": "^ALL_BUILD::@c11385ffed57b860da63$",
+    "directorySource": "^custom$",
+    "projectName": "Custom",
+    "type": "UTILITY",
+    "isGeneratorProvided": true,
+    "sources": [
+        {
+            "path": "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/custom/CMakeFiles/ALL_BUILD$",
+            "isGenerated": true,
+            "sourceGroupName": "",
+            "compileGroupLanguage": null,
+            "backtrace": [
+                {
+                    "file": "^custom/CMakeLists\\.txt$",
+                    "line": null,
+                    "command": null,
+                    "hasParent": false
+                }
+            ]
+        },
+        {
+            "path": "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/custom/CMakeFiles/ALL_BUILD\\.rule$",
+            "isGenerated": true,
+            "sourceGroupName": "CMake Rules",
+            "compileGroupLanguage": null,
+            "backtrace": [
+                {
+                    "file": "^custom/CMakeLists\\.txt$",
+                    "line": null,
+                    "command": null,
+                    "hasParent": false
+                }
+            ]
+        }
+    ],
+    "sourceGroups": [
+        {
+            "name": "",
+            "sourcePaths": [
+                "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/custom/CMakeFiles/ALL_BUILD$"
+            ]
+        },
+        {
+            "name": "CMake Rules",
+            "sourcePaths": [
+                "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/custom/CMakeFiles/ALL_BUILD\\.rule$"
+            ]
+        }
+    ],
+    "compileGroups": null,
+    "backtrace": [
+        {
+            "file": "^custom/CMakeLists\\.txt$",
+            "line": null,
+            "command": null,
+            "hasParent": false
+        }
+    ],
+    "folder": null,
+    "nameOnDisk": null,
+    "artifacts": null,
+    "build": "^custom$",
+    "source": "^custom$",
+    "install": null,
+    "link": null,
+    "archive": null,
+    "dependencies": [
+        {
+            "id": "^ZERO_CHECK::@c11385ffed57b860da63$",
+            "backtrace": null
+        },
+        {
+            "id": "^custom_exe::@c11385ffed57b860da63$",
+            "backtrace": null
+        }
+    ]
+}
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/all_build_cxx.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/all_build_cxx.json
new file mode 100644
index 0000000..1f443b1
--- /dev/null
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/all_build_cxx.json
@@ -0,0 +1,107 @@
+{
+    "name": "ALL_BUILD",
+    "id": "^ALL_BUILD::@a56b12a3f5c0529fb296$",
+    "directorySource": "^cxx$",
+    "projectName": "Cxx",
+    "type": "UTILITY",
+    "isGeneratorProvided": true,
+    "sources": [
+        {
+            "path": "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/cxx/CMakeFiles/ALL_BUILD$",
+            "isGenerated": true,
+            "sourceGroupName": "",
+            "compileGroupLanguage": null,
+            "backtrace": [
+                {
+                    "file": "^cxx/CMakeLists\\.txt$",
+                    "line": null,
+                    "command": null,
+                    "hasParent": false
+                }
+            ]
+        },
+        {
+            "path": "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/cxx/CMakeFiles/ALL_BUILD\\.rule$",
+            "isGenerated": true,
+            "sourceGroupName": "CMake Rules",
+            "compileGroupLanguage": null,
+            "backtrace": [
+                {
+                    "file": "^cxx/CMakeLists\\.txt$",
+                    "line": null,
+                    "command": null,
+                    "hasParent": false
+                }
+            ]
+        }
+    ],
+    "sourceGroups": [
+        {
+            "name": "",
+            "sourcePaths": [
+                "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/cxx/CMakeFiles/ALL_BUILD$"
+            ]
+        },
+        {
+            "name": "CMake Rules",
+            "sourcePaths": [
+                "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/cxx/CMakeFiles/ALL_BUILD\\.rule$"
+            ]
+        }
+    ],
+    "compileGroups": null,
+    "backtrace": [
+        {
+            "file": "^cxx/CMakeLists\\.txt$",
+            "line": null,
+            "command": null,
+            "hasParent": false
+        }
+    ],
+    "folder": null,
+    "nameOnDisk": null,
+    "artifacts": null,
+    "build": "^cxx$",
+    "source": "^cxx$",
+    "install": null,
+    "link": null,
+    "archive": null,
+    "dependencies": [
+        {
+            "id": "^ZERO_CHECK::@a56b12a3f5c0529fb296$",
+            "backtrace": null
+        },
+        {
+            "id": "^cxx_lib::@a56b12a3f5c0529fb296$",
+            "backtrace": null
+        },
+        {
+            "id": "^cxx_exe::@a56b12a3f5c0529fb296$",
+            "backtrace": null
+        },
+        {
+            "id": "^cxx_standard_compile_feature_exe::@a56b12a3f5c0529fb296$",
+            "backtrace": null
+        },
+        {
+            "id": "^cxx_standard_exe::@a56b12a3f5c0529fb296$",
+            "backtrace": null
+        },
+        {
+            "id": "^cxx_shared_lib::@a56b12a3f5c0529fb296$",
+            "backtrace": null
+        },
+        {
+            "id": "^cxx_shared_exe::@a56b12a3f5c0529fb296$",
+            "backtrace": null
+        },
+        {
+            "id": "^cxx_static_lib::@a56b12a3f5c0529fb296$",
+            "backtrace": null
+        },
+        {
+            "id": "^cxx_static_exe::@a56b12a3f5c0529fb296$",
+            "backtrace": null
+        }
+    ]
+}
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/all_build_external.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/all_build_external.json
new file mode 100644
index 0000000..017335c
--- /dev/null
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/all_build_external.json
@@ -0,0 +1,79 @@
+{
+    "name": "ALL_BUILD",
+    "id": "^ALL_BUILD::@[0-9a-f]+$",
+    "directorySource": "^.*/Tests/RunCMake/FileAPIExternalSource$",
+    "projectName": "External",
+    "type": "UTILITY",
+    "isGeneratorProvided": true,
+    "sources": [
+        {
+            "path": "^.*/Tests/RunCMake/FileAPI/FileAPIExternalBuild/CMakeFiles/ALL_BUILD$",
+            "isGenerated": true,
+            "sourceGroupName": "",
+            "compileGroupLanguage": null,
+            "backtrace": [
+                {
+                    "file": "^.*/Tests/RunCMake/FileAPIExternalSource/CMakeLists\\.txt$",
+                    "line": null,
+                    "command": null,
+                    "hasParent": false
+                }
+            ]
+        },
+        {
+            "path": "^.*/Tests/RunCMake/FileAPI/FileAPIExternalBuild/CMakeFiles/ALL_BUILD\\.rule$",
+            "isGenerated": true,
+            "sourceGroupName": "CMake Rules",
+            "compileGroupLanguage": null,
+            "backtrace": [
+                {
+                    "file": "^.*/Tests/RunCMake/FileAPIExternalSource/CMakeLists\\.txt$",
+                    "line": null,
+                    "command": null,
+                    "hasParent": false
+                }
+            ]
+        }
+    ],
+    "sourceGroups": [
+        {
+            "name": "",
+            "sourcePaths": [
+                "^.*/Tests/RunCMake/FileAPI/FileAPIExternalBuild/CMakeFiles/ALL_BUILD$"
+            ]
+        },
+        {
+            "name": "CMake Rules",
+            "sourcePaths": [
+                "^.*/Tests/RunCMake/FileAPI/FileAPIExternalBuild/CMakeFiles/ALL_BUILD\\.rule$"
+            ]
+        }
+    ],
+    "compileGroups": null,
+    "backtrace": [
+        {
+            "file": "^.*/Tests/RunCMake/FileAPIExternalSource/CMakeLists\\.txt$",
+            "line": null,
+            "command": null,
+            "hasParent": false
+        }
+    ],
+    "folder": null,
+    "nameOnDisk": null,
+    "artifacts": null,
+    "build": "^.*/Tests/RunCMake/FileAPI/FileAPIExternalBuild$",
+    "source": "^.*/Tests/RunCMake/FileAPIExternalSource$",
+    "install": null,
+    "link": null,
+    "archive": null,
+    "dependencies": [
+        {
+            "id": "^ZERO_CHECK::@[0-9a-f]+$",
+            "backtrace": null
+        },
+        {
+            "id": "^generated_exe::@[0-9a-f]+$",
+            "backtrace": null
+        }
+    ]
+}
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/all_build_imported.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/all_build_imported.json
new file mode 100644
index 0000000..2de5b15
--- /dev/null
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/all_build_imported.json
@@ -0,0 +1,95 @@
+{
+    "name": "ALL_BUILD",
+    "id": "^ALL_BUILD::@ba7eb709d0b48779c6c8$",
+    "directorySource": "^imported$",
+    "projectName": "Imported",
+    "type": "UTILITY",
+    "isGeneratorProvided": true,
+    "sources": [
+        {
+            "path": "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/imported/CMakeFiles/ALL_BUILD$",
+            "isGenerated": true,
+            "sourceGroupName": "",
+            "compileGroupLanguage": null,
+            "backtrace": [
+                {
+                    "file": "^imported/CMakeLists\\.txt$",
+                    "line": null,
+                    "command": null,
+                    "hasParent": false
+                }
+            ]
+        },
+        {
+            "path": "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/imported/CMakeFiles/ALL_BUILD\\.rule$",
+            "isGenerated": true,
+            "sourceGroupName": "CMake Rules",
+            "compileGroupLanguage": null,
+            "backtrace": [
+                {
+                    "file": "^imported/CMakeLists\\.txt$",
+                    "line": null,
+                    "command": null,
+                    "hasParent": false
+                }
+            ]
+        }
+    ],
+    "sourceGroups": [
+        {
+            "name": "",
+            "sourcePaths": [
+                "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/imported/CMakeFiles/ALL_BUILD$"
+            ]
+        },
+        {
+            "name": "CMake Rules",
+            "sourcePaths": [
+                "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/imported/CMakeFiles/ALL_BUILD\\.rule$"
+            ]
+        }
+    ],
+    "compileGroups": null,
+    "backtrace": [
+        {
+            "file": "^imported/CMakeLists\\.txt$",
+            "line": null,
+            "command": null,
+            "hasParent": false
+        }
+    ],
+    "folder": null,
+    "nameOnDisk": null,
+    "artifacts": null,
+    "build": "^imported$",
+    "source": "^imported$",
+    "install": null,
+    "link": null,
+    "archive": null,
+    "dependencies": [
+        {
+            "id": "^ZERO_CHECK::@ba7eb709d0b48779c6c8$",
+            "backtrace": null
+        },
+        {
+            "id": "^link_imported_exe::@ba7eb709d0b48779c6c8$",
+            "backtrace": null
+        },
+        {
+            "id": "^link_imported_shared_exe::@ba7eb709d0b48779c6c8$",
+            "backtrace": null
+        },
+        {
+            "id": "^link_imported_static_exe::@ba7eb709d0b48779c6c8$",
+            "backtrace": null
+        },
+        {
+            "id": "^link_imported_object_exe::@ba7eb709d0b48779c6c8$",
+            "backtrace": null
+        },
+        {
+            "id": "^link_imported_interface_exe::@ba7eb709d0b48779c6c8$",
+            "backtrace": null
+        }
+    ]
+}
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/all_build_interface.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/all_build_interface.json
new file mode 100644
index 0000000..fa2a6e5
--- /dev/null
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/all_build_interface.json
@@ -0,0 +1,79 @@
+{
+    "name": "ALL_BUILD",
+    "id": "^ALL_BUILD::@25b7fa8ea00134654b85$",
+    "directorySource": "^interface$",
+    "projectName": "Interface",
+    "type": "UTILITY",
+    "isGeneratorProvided": true,
+    "sources": [
+        {
+            "path": "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/interface/CMakeFiles/ALL_BUILD$",
+            "isGenerated": true,
+            "sourceGroupName": "",
+            "compileGroupLanguage": null,
+            "backtrace": [
+                {
+                    "file": "^interface/CMakeLists\\.txt$",
+                    "line": null,
+                    "command": null,
+                    "hasParent": false
+                }
+            ]
+        },
+        {
+            "path": "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/interface/CMakeFiles/ALL_BUILD\\.rule$",
+            "isGenerated": true,
+            "sourceGroupName": "CMake Rules",
+            "compileGroupLanguage": null,
+            "backtrace": [
+                {
+                    "file": "^interface/CMakeLists\\.txt$",
+                    "line": null,
+                    "command": null,
+                    "hasParent": false
+                }
+            ]
+        }
+    ],
+    "sourceGroups": [
+        {
+            "name": "",
+            "sourcePaths": [
+                "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/interface/CMakeFiles/ALL_BUILD$"
+            ]
+        },
+        {
+            "name": "CMake Rules",
+            "sourcePaths": [
+                "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/interface/CMakeFiles/ALL_BUILD\\.rule$"
+            ]
+        }
+    ],
+    "compileGroups": null,
+    "backtrace": [
+        {
+            "file": "^interface/CMakeLists\\.txt$",
+            "line": null,
+            "command": null,
+            "hasParent": false
+        }
+    ],
+    "folder": null,
+    "nameOnDisk": null,
+    "artifacts": null,
+    "build": "^interface$",
+    "source": "^interface$",
+    "install": null,
+    "link": null,
+    "archive": null,
+    "dependencies": [
+        {
+            "id": "^ZERO_CHECK::@25b7fa8ea00134654b85$",
+            "backtrace": null
+        },
+        {
+            "id": "^iface_srcs::@25b7fa8ea00134654b85$",
+            "backtrace": null
+        }
+    ]
+}
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/all_build_object.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/all_build_object.json
new file mode 100644
index 0000000..9d8899a
--- /dev/null
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/all_build_object.json
@@ -0,0 +1,91 @@
+{
+    "name": "ALL_BUILD",
+    "id": "^ALL_BUILD::@5ed5358f70faf8d8af7a$",
+    "directorySource": "^object$",
+    "projectName": "Object",
+    "type": "UTILITY",
+    "isGeneratorProvided": true,
+    "sources": [
+        {
+            "path": "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/object/CMakeFiles/ALL_BUILD$",
+            "isGenerated": true,
+            "sourceGroupName": "",
+            "compileGroupLanguage": null,
+            "backtrace": [
+                {
+                    "file": "^object/CMakeLists\\.txt$",
+                    "line": null,
+                    "command": null,
+                    "hasParent": false
+                }
+            ]
+        },
+        {
+            "path": "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/object/CMakeFiles/ALL_BUILD\\.rule$",
+            "isGenerated": true,
+            "sourceGroupName": "CMake Rules",
+            "compileGroupLanguage": null,
+            "backtrace": [
+                {
+                    "file": "^object/CMakeLists\\.txt$",
+                    "line": null,
+                    "command": null,
+                    "hasParent": false
+                }
+            ]
+        }
+    ],
+    "sourceGroups": [
+        {
+            "name": "",
+            "sourcePaths": [
+                "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/object/CMakeFiles/ALL_BUILD$"
+            ]
+        },
+        {
+            "name": "CMake Rules",
+            "sourcePaths": [
+                "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/object/CMakeFiles/ALL_BUILD\\.rule$"
+            ]
+        }
+    ],
+    "compileGroups": null,
+    "backtrace": [
+        {
+            "file": "^object/CMakeLists\\.txt$",
+            "line": null,
+            "command": null,
+            "hasParent": false
+        }
+    ],
+    "folder": null,
+    "nameOnDisk": null,
+    "artifacts": null,
+    "build": "^object$",
+    "source": "^object$",
+    "install": null,
+    "link": null,
+    "archive": null,
+    "dependencies": [
+        {
+            "id": "^ZERO_CHECK::@5ed5358f70faf8d8af7a$",
+            "backtrace": null
+        },
+        {
+            "id": "^c_object_lib::@5ed5358f70faf8d8af7a$",
+            "backtrace": null
+        },
+        {
+            "id": "^c_object_exe::@5ed5358f70faf8d8af7a$",
+            "backtrace": null
+        },
+        {
+            "id": "^cxx_object_lib::@5ed5358f70faf8d8af7a$",
+            "backtrace": null
+        },
+        {
+            "id": "^cxx_object_exe::@5ed5358f70faf8d8af7a$",
+            "backtrace": null
+        }
+    ]
+}
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/all_build_top.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/all_build_top.json
new file mode 100644
index 0000000..d023f99
--- /dev/null
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/all_build_top.json
@@ -0,0 +1,191 @@
+{
+    "name": "ALL_BUILD",
+    "id": "^ALL_BUILD::@6890427a1f51a3e7e1df$",
+    "directorySource": "^\\.$",
+    "projectName": "codemodel-v2",
+    "type": "UTILITY",
+    "isGeneratorProvided": true,
+    "sources": [
+        {
+            "path": "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/CMakeFiles/ALL_BUILD$",
+            "isGenerated": true,
+            "sourceGroupName": "",
+            "compileGroupLanguage": null,
+            "backtrace": [
+                {
+                    "file": "^CMakeLists\\.txt$",
+                    "line": null,
+                    "command": null,
+                    "hasParent": false
+                }
+            ]
+        },
+        {
+            "path": "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/CMakeFiles/ALL_BUILD\\.rule$",
+            "isGenerated": true,
+            "sourceGroupName": "CMake Rules",
+            "compileGroupLanguage": null,
+            "backtrace": [
+                {
+                    "file": "^CMakeLists\\.txt$",
+                    "line": null,
+                    "command": null,
+                    "hasParent": false
+                }
+            ]
+        }
+    ],
+    "sourceGroups": [
+        {
+            "name": "",
+            "sourcePaths": [
+                "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/CMakeFiles/ALL_BUILD$"
+            ]
+        },
+        {
+            "name": "CMake Rules",
+            "sourcePaths": [
+                "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/CMakeFiles/ALL_BUILD\\.rule$"
+            ]
+        }
+    ],
+    "compileGroups": null,
+    "backtrace": [
+        {
+            "file": "^CMakeLists\\.txt$",
+            "line": null,
+            "command": null,
+            "hasParent": false
+        }
+    ],
+    "folder": null,
+    "nameOnDisk": null,
+    "artifacts": null,
+    "build": "^\\.$",
+    "source": "^\\.$",
+    "install": null,
+    "link": null,
+    "archive": null,
+    "dependencies": [
+        {
+            "id": "^ZERO_CHECK::@6890427a1f51a3e7e1df$",
+            "backtrace": null
+        },
+        {
+            "id": "^interface_exe::@6890427a1f51a3e7e1df$",
+            "backtrace": null
+        },
+        {
+            "id": "^c_lib::@6890427a1f51a3e7e1df$",
+            "backtrace": null
+        },
+        {
+            "id": "^c_exe::@6890427a1f51a3e7e1df$",
+            "backtrace": null
+        },
+        {
+            "id": "^c_shared_lib::@6890427a1f51a3e7e1df$",
+            "backtrace": null
+        },
+        {
+            "id": "^c_shared_exe::@6890427a1f51a3e7e1df$",
+            "backtrace": null
+        },
+        {
+            "id": "^c_static_lib::@6890427a1f51a3e7e1df$",
+            "backtrace": null
+        },
+        {
+            "id": "^c_static_exe::@6890427a1f51a3e7e1df$",
+            "backtrace": null
+        },
+        {
+            "id": "^c_alias_exe::@53632cba2752272bb008$",
+            "backtrace": null
+        },
+        {
+            "id": "^cxx_alias_exe::@53632cba2752272bb008$",
+            "backtrace": null
+        },
+        {
+            "id": "^cxx_lib::@a56b12a3f5c0529fb296$",
+            "backtrace": null
+        },
+        {
+            "id": "^cxx_exe::@a56b12a3f5c0529fb296$",
+            "backtrace": null
+        },
+        {
+            "id": "^cxx_standard_compile_feature_exe::@a56b12a3f5c0529fb296$",
+            "backtrace": null
+        },
+        {
+            "id": "^cxx_standard_exe::@a56b12a3f5c0529fb296$",
+            "backtrace": null
+        },
+        {
+            "id": "^cxx_shared_lib::@a56b12a3f5c0529fb296$",
+            "backtrace": null
+        },
+        {
+            "id": "^cxx_shared_exe::@a56b12a3f5c0529fb296$",
+            "backtrace": null
+        },
+        {
+            "id": "^cxx_static_lib::@a56b12a3f5c0529fb296$",
+            "backtrace": null
+        },
+        {
+            "id": "^cxx_static_exe::@a56b12a3f5c0529fb296$",
+            "backtrace": null
+        },
+        {
+            "id": "^c_object_lib::@5ed5358f70faf8d8af7a$",
+            "backtrace": null
+        },
+        {
+            "id": "^c_object_exe::@5ed5358f70faf8d8af7a$",
+            "backtrace": null
+        },
+        {
+            "id": "^cxx_object_lib::@5ed5358f70faf8d8af7a$",
+            "backtrace": null
+        },
+        {
+            "id": "^cxx_object_exe::@5ed5358f70faf8d8af7a$",
+            "backtrace": null
+        },
+        {
+            "id": "^link_imported_exe::@ba7eb709d0b48779c6c8$",
+            "backtrace": null
+        },
+        {
+            "id": "^link_imported_shared_exe::@ba7eb709d0b48779c6c8$",
+            "backtrace": null
+        },
+        {
+            "id": "^link_imported_static_exe::@ba7eb709d0b48779c6c8$",
+            "backtrace": null
+        },
+        {
+            "id": "^link_imported_object_exe::@ba7eb709d0b48779c6c8$",
+            "backtrace": null
+        },
+        {
+            "id": "^link_imported_interface_exe::@ba7eb709d0b48779c6c8$",
+            "backtrace": null
+        },
+        {
+            "id": "^iface_srcs::@25b7fa8ea00134654b85$",
+            "backtrace": null
+        },
+        {
+            "id": "^custom_exe::@c11385ffed57b860da63$",
+            "backtrace": null
+        },
+        {
+            "id": "^generated_exe::@[0-9a-f]+$",
+            "backtrace": null
+        }
+    ]
+}
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/c_alias_exe.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/c_alias_exe.json
new file mode 100644
index 0000000..ac7c94d
--- /dev/null
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/c_alias_exe.json
@@ -0,0 +1,107 @@
+{
+    "name": "c_alias_exe",
+    "id": "^c_alias_exe::@53632cba2752272bb008$",
+    "directorySource": "^alias$",
+    "projectName": "Alias",
+    "type": "EXECUTABLE",
+    "isGeneratorProvided": null,
+    "sources": [
+        {
+            "path": "^empty\\.c$",
+            "isGenerated": null,
+            "sourceGroupName": "Source Files",
+            "compileGroupLanguage": "C",
+            "backtrace": [
+                {
+                    "file": "^alias/CMakeLists\\.txt$",
+                    "line": 5,
+                    "command": "add_executable",
+                    "hasParent": true
+                },
+                {
+                    "file": "^alias/CMakeLists\\.txt$",
+                    "line": null,
+                    "command": null,
+                    "hasParent": false
+                }
+            ]
+        }
+    ],
+    "sourceGroups": [
+        {
+            "name": "Source Files",
+            "sourcePaths": [
+                "^empty\\.c$"
+            ]
+        }
+    ],
+    "compileGroups": [
+        {
+            "language": "C",
+            "sourcePaths": [
+                "^empty\\.c$"
+            ],
+            "includes": null,
+            "defines": null,
+            "compileCommandFragments": null
+        }
+    ],
+    "backtrace": [
+        {
+            "file": "^alias/CMakeLists\\.txt$",
+            "line": 5,
+            "command": "add_executable",
+            "hasParent": true
+        },
+        {
+            "file": "^alias/CMakeLists\\.txt$",
+            "line": null,
+            "command": null,
+            "hasParent": false
+        }
+    ],
+    "folder": null,
+    "nameOnDisk": "^c_alias_exe(\\.exe)?$",
+    "artifacts": [
+        {
+            "path": "^alias/((Debug|Release|RelWithDebInfo|MinSizeRel)/)?c_alias_exe(\\.exe)?$",
+            "_dllExtra": false
+        },
+        {
+            "path": "^alias/((Debug|Release|RelWithDebInfo|MinSizeRel)/)?c_alias_exe\\.pdb$",
+            "_dllExtra": true
+        }
+    ],
+    "build": "^alias$",
+    "source": "^alias$",
+    "install": null,
+    "link": {
+        "language": "C",
+        "lto": null,
+        "commandFragments": null
+    },
+    "archive": null,
+    "dependencies": [
+        {
+            "id": "^c_lib::@6890427a1f51a3e7e1df$",
+            "backtrace": [
+                {
+                    "file": "^alias/CMakeLists\\.txt$",
+                    "line": 6,
+                    "command": "target_link_libraries",
+                    "hasParent": true
+                },
+                {
+                    "file": "^alias/CMakeLists\\.txt$",
+                    "line": null,
+                    "command": null,
+                    "hasParent": false
+                }
+            ]
+        },
+        {
+            "id": "^ZERO_CHECK::@53632cba2752272bb008$",
+            "backtrace": null
+        }
+    ]
+}
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/c_exe.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/c_exe.json
new file mode 100644
index 0000000..7af74c4
--- /dev/null
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/c_exe.json
@@ -0,0 +1,143 @@
+{
+    "name": "c_exe",
+    "id": "^c_exe::@6890427a1f51a3e7e1df$",
+    "directorySource": "^\\.$",
+    "projectName": "codemodel-v2",
+    "type": "EXECUTABLE",
+    "isGeneratorProvided": null,
+    "sources": [
+        {
+            "path": "^empty\\.c$",
+            "isGenerated": null,
+            "sourceGroupName": "Source Files",
+            "compileGroupLanguage": "C",
+            "backtrace": [
+                {
+                    "file": "^codemodel-v2\\.cmake$",
+                    "line": 6,
+                    "command": "add_executable",
+                    "hasParent": true
+                },
+                {
+                    "file": "^codemodel-v2\\.cmake$",
+                    "line": null,
+                    "command": null,
+                    "hasParent": true
+                },
+                {
+                    "file": "^CMakeLists\\.txt$",
+                    "line": 3,
+                    "command": "include",
+                    "hasParent": true
+                },
+                {
+                    "file": "^CMakeLists\\.txt$",
+                    "line": null,
+                    "command": null,
+                    "hasParent": false
+                }
+            ]
+        }
+    ],
+    "sourceGroups": [
+        {
+            "name": "Source Files",
+            "sourcePaths": [
+                "^empty\\.c$"
+            ]
+        }
+    ],
+    "compileGroups": [
+        {
+            "language": "C",
+            "sourcePaths": [
+                "^empty\\.c$"
+            ],
+            "includes": null,
+            "defines": null,
+            "compileCommandFragments": null
+        }
+    ],
+    "backtrace": [
+        {
+            "file": "^codemodel-v2\\.cmake$",
+            "line": 6,
+            "command": "add_executable",
+            "hasParent": true
+        },
+        {
+            "file": "^codemodel-v2\\.cmake$",
+            "line": null,
+            "command": null,
+            "hasParent": true
+        },
+        {
+            "file": "^CMakeLists\\.txt$",
+            "line": 3,
+            "command": "include",
+            "hasParent": true
+        },
+        {
+            "file": "^CMakeLists\\.txt$",
+            "line": null,
+            "command": null,
+            "hasParent": false
+        }
+    ],
+    "folder": null,
+    "nameOnDisk": "^c_exe(\\.exe)?$",
+    "artifacts": [
+        {
+            "path": "^((Debug|Release|RelWithDebInfo|MinSizeRel)/)?c_exe(\\.exe)?$",
+            "_dllExtra": false
+        },
+        {
+            "path": "^((Debug|Release|RelWithDebInfo|MinSizeRel)/)?c_exe\\.pdb$",
+            "_dllExtra": true
+        }
+    ],
+    "build": "^\\.$",
+    "source": "^\\.$",
+    "install": null,
+    "link": {
+        "language": "C",
+        "lto": null,
+        "commandFragments": null
+    },
+    "archive": null,
+    "dependencies": [
+        {
+            "id": "^c_lib::@6890427a1f51a3e7e1df$",
+            "backtrace": [
+                {
+                    "file": "^codemodel-v2\\.cmake$",
+                    "line": 7,
+                    "command": "target_link_libraries",
+                    "hasParent": true
+                },
+                {
+                    "file": "^codemodel-v2\\.cmake$",
+                    "line": null,
+                    "command": null,
+                    "hasParent": true
+                },
+                {
+                    "file": "^CMakeLists\\.txt$",
+                    "line": 3,
+                    "command": "include",
+                    "hasParent": true
+                },
+                {
+                    "file": "^CMakeLists\\.txt$",
+                    "line": null,
+                    "command": null,
+                    "hasParent": false
+                }
+            ]
+        },
+        {
+            "id": "^ZERO_CHECK::@6890427a1f51a3e7e1df$",
+            "backtrace": null
+        }
+    ]
+}
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/c_lib.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/c_lib.json
new file mode 100644
index 0000000..0ca1962
--- /dev/null
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/c_lib.json
@@ -0,0 +1,108 @@
+{
+    "name": "c_lib",
+    "id": "^c_lib::@6890427a1f51a3e7e1df$",
+    "directorySource": "^\\.$",
+    "projectName": "codemodel-v2",
+    "type": "STATIC_LIBRARY",
+    "isGeneratorProvided": null,
+    "sources": [
+        {
+            "path": "^empty\\.c$",
+            "isGenerated": null,
+            "sourceGroupName": "Source Files",
+            "compileGroupLanguage": "C",
+            "backtrace": [
+                {
+                    "file": "^codemodel-v2\\.cmake$",
+                    "line": 5,
+                    "command": "add_library",
+                    "hasParent": true
+                },
+                {
+                    "file": "^codemodel-v2\\.cmake$",
+                    "line": null,
+                    "command": null,
+                    "hasParent": true
+                },
+                {
+                    "file": "^CMakeLists\\.txt$",
+                    "line": 3,
+                    "command": "include",
+                    "hasParent": true
+                },
+                {
+                    "file": "^CMakeLists\\.txt$",
+                    "line": null,
+                    "command": null,
+                    "hasParent": false
+                }
+            ]
+        }
+    ],
+    "sourceGroups": [
+        {
+            "name": "Source Files",
+            "sourcePaths": [
+                "^empty\\.c$"
+            ]
+        }
+    ],
+    "compileGroups": [
+        {
+            "language": "C",
+            "sourcePaths": [
+                "^empty\\.c$"
+            ],
+            "includes": null,
+            "defines": null,
+            "compileCommandFragments": null
+        }
+    ],
+    "backtrace": [
+        {
+            "file": "^codemodel-v2\\.cmake$",
+            "line": 5,
+            "command": "add_library",
+            "hasParent": true
+        },
+        {
+            "file": "^codemodel-v2\\.cmake$",
+            "line": null,
+            "command": null,
+            "hasParent": true
+        },
+        {
+            "file": "^CMakeLists\\.txt$",
+            "line": 3,
+            "command": "include",
+            "hasParent": true
+        },
+        {
+            "file": "^CMakeLists\\.txt$",
+            "line": null,
+            "command": null,
+            "hasParent": false
+        }
+    ],
+    "folder": null,
+    "nameOnDisk": "^(lib)?c_lib\\.(a|lib)$",
+    "artifacts": [
+        {
+            "path": "^((Debug|Release|RelWithDebInfo|MinSizeRel)/)?(lib)?c_lib\\.(a|lib)$",
+            "_dllExtra": false
+        }
+    ],
+    "build": "^\\.$",
+    "source": "^\\.$",
+    "install": null,
+    "link": null,
+    "archive": {
+        "lto": null
+    },
+    "dependencies": [
+        {
+            "id": "^ZERO_CHECK::@6890427a1f51a3e7e1df$",
+            "backtrace": null
+        }
+    ]
+}
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/c_object_exe.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/c_object_exe.json
new file mode 100644
index 0000000..3c9ace3
--- /dev/null
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/c_object_exe.json
@@ -0,0 +1,154 @@
+{
+    "name": "c_object_exe",
+    "id": "^c_object_exe::@5ed5358f70faf8d8af7a$",
+    "directorySource": "^object$",
+    "projectName": "Object",
+    "type": "EXECUTABLE",
+    "isGeneratorProvided": null,
+    "sources": [
+        {
+            "path": "^empty\\.c$",
+            "isGenerated": null,
+            "sourceGroupName": "Source Files",
+            "compileGroupLanguage": "C",
+            "backtrace": [
+                {
+                    "file": "^object/CMakeLists\\.txt$",
+                    "line": 6,
+                    "command": "add_executable",
+                    "hasParent": true
+                },
+                {
+                    "file": "^object/CMakeLists\\.txt$",
+                    "line": null,
+                    "command": null,
+                    "hasParent": false
+                }
+            ]
+        },
+        {
+            "path": "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/object/.*/empty(\\.c)?\\.o(bj)?$",
+            "isGenerated": true,
+            "sourceGroupName": "Object Libraries",
+            "compileGroupLanguage": null,
+            "backtrace": [
+                {
+                    "file": "^object/CMakeLists\\.txt$",
+                    "line": 7,
+                    "command": "target_link_libraries",
+                    "hasParent": true
+                },
+                {
+                    "file": "^object/CMakeLists\\.txt$",
+                    "line": null,
+                    "command": null,
+                    "hasParent": false
+                }
+            ]
+        }
+    ],
+    "sourceGroups": [
+        {
+            "name": "Source Files",
+            "sourcePaths": [
+                "^empty\\.c$"
+            ]
+        },
+        {
+            "name": "Object Libraries",
+            "sourcePaths": [
+                "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/object/.*/empty(\\.c)?\\.o(bj)?$"
+            ]
+        }
+    ],
+    "compileGroups": [
+        {
+            "language": "C",
+            "sourcePaths": [
+                "^empty\\.c$"
+            ],
+            "includes": null,
+            "defines": null,
+            "compileCommandFragments": null
+        }
+    ],
+    "backtrace": [
+        {
+            "file": "^object/CMakeLists\\.txt$",
+            "line": 6,
+            "command": "add_executable",
+            "hasParent": true
+        },
+        {
+            "file": "^object/CMakeLists\\.txt$",
+            "line": null,
+            "command": null,
+            "hasParent": false
+        }
+    ],
+    "folder": null,
+    "nameOnDisk": "^c_object_exe(\\.exe)?$",
+    "artifacts": [
+        {
+            "path": "^object/((Debug|Release|RelWithDebInfo|MinSizeRel)/)?c_object_exe(\\.exe)?$",
+            "_dllExtra": false
+        },
+        {
+            "path": "^object/((Debug|Release|RelWithDebInfo|MinSizeRel)/)?c_object_exe\\.pdb$",
+            "_dllExtra": true
+        }
+    ],
+    "build": "^object$",
+    "source": "^object$",
+    "install": {
+        "prefix": "^(/usr/local|[A-Za-z]:.*/codemodel-v2)$",
+        "destinations": [
+            {
+                "path": "bin",
+                "backtrace": [
+                    {
+                        "file": "^object/CMakeLists\\.txt$",
+                        "line": 13,
+                        "command": "install",
+                        "hasParent": true
+                    },
+                    {
+                        "file": "^object/CMakeLists\\.txt$",
+                        "line": null,
+                        "command": null,
+                        "hasParent": false
+                    }
+                ]
+            }
+        ]
+    },
+    "link": {
+        "language": "C",
+        "lto": null,
+        "commandFragments": null
+    },
+    "archive": null,
+    "dependencies": [
+        {
+            "id": "^c_object_lib::@5ed5358f70faf8d8af7a$",
+            "backtrace": [
+                {
+                    "file": "^object/CMakeLists\\.txt$",
+                    "line": 7,
+                    "command": "target_link_libraries",
+                    "hasParent": true
+                },
+                {
+                    "file": "^object/CMakeLists\\.txt$",
+                    "line": null,
+                    "command": null,
+                    "hasParent": false
+                }
+            ]
+        },
+        {
+            "id": "^ZERO_CHECK::@5ed5358f70faf8d8af7a$",
+            "backtrace": null
+        }
+    ]
+}
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/c_object_lib.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/c_object_lib.json
new file mode 100644
index 0000000..e3a20df
--- /dev/null
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/c_object_lib.json
@@ -0,0 +1,82 @@
+{
+    "name": "c_object_lib",
+    "id": "^c_object_lib::@5ed5358f70faf8d8af7a$",
+    "directorySource": "^object$",
+    "projectName": "Object",
+    "type": "OBJECT_LIBRARY",
+    "isGeneratorProvided": null,
+    "sources": [
+        {
+            "path": "^empty\\.c$",
+            "isGenerated": null,
+            "sourceGroupName": "Source Files",
+            "compileGroupLanguage": "C",
+            "backtrace": [
+                {
+                    "file": "^object/CMakeLists\\.txt$",
+                    "line": 5,
+                    "command": "add_library",
+                    "hasParent": true
+                },
+                {
+                    "file": "^object/CMakeLists\\.txt$",
+                    "line": null,
+                    "command": null,
+                    "hasParent": false
+                }
+            ]
+        }
+    ],
+    "sourceGroups": [
+        {
+            "name": "Source Files",
+            "sourcePaths": [
+                "^empty\\.c$"
+            ]
+        }
+    ],
+    "compileGroups": [
+        {
+            "language": "C",
+            "sourcePaths": [
+                "^empty\\.c$"
+            ],
+            "includes": null,
+            "defines": null,
+            "compileCommandFragments": null
+        }
+    ],
+    "backtrace": [
+        {
+            "file": "^object/CMakeLists\\.txt$",
+            "line": 5,
+            "command": "add_library",
+            "hasParent": true
+        },
+        {
+            "file": "^object/CMakeLists\\.txt$",
+            "line": null,
+            "command": null,
+            "hasParent": false
+        }
+    ],
+    "folder": null,
+    "nameOnDisk": null,
+    "artifacts": [
+        {
+            "path": "^object/.*/empty(\\.c)?\\.o(bj)?$",
+            "_dllExtra": false
+        }
+    ],
+    "build": "^object$",
+    "source": "^object$",
+    "install": null,
+    "link": null,
+    "archive": null,
+    "dependencies": [
+        {
+            "id": "^ZERO_CHECK::@5ed5358f70faf8d8af7a$",
+            "backtrace": null
+        }
+    ]
+}
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/c_shared_exe.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/c_shared_exe.json
new file mode 100644
index 0000000..0d4018a
--- /dev/null
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/c_shared_exe.json
@@ -0,0 +1,143 @@
+{
+    "name": "c_shared_exe",
+    "id": "^c_shared_exe::@6890427a1f51a3e7e1df$",
+    "directorySource": "^\\.$",
+    "projectName": "codemodel-v2",
+    "type": "EXECUTABLE",
+    "isGeneratorProvided": null,
+    "sources": [
+        {
+            "path": "^empty\\.c$",
+            "isGenerated": null,
+            "sourceGroupName": "Source Files",
+            "compileGroupLanguage": "C",
+            "backtrace": [
+                {
+                    "file": "^codemodel-v2\\.cmake$",
+                    "line": 10,
+                    "command": "add_executable",
+                    "hasParent": true
+                },
+                {
+                    "file": "^codemodel-v2\\.cmake$",
+                    "line": null,
+                    "command": null,
+                    "hasParent": true
+                },
+                {
+                    "file": "^CMakeLists\\.txt$",
+                    "line": 3,
+                    "command": "include",
+                    "hasParent": true
+                },
+                {
+                    "file": "^CMakeLists\\.txt$",
+                    "line": null,
+                    "command": null,
+                    "hasParent": false
+                }
+            ]
+        }
+    ],
+    "sourceGroups": [
+        {
+            "name": "Source Files",
+            "sourcePaths": [
+                "^empty\\.c$"
+            ]
+        }
+    ],
+    "compileGroups": [
+        {
+            "language": "C",
+            "sourcePaths": [
+                "^empty\\.c$"
+            ],
+            "includes": null,
+            "defines": null,
+  "compileCommandFragments": null
+        }
+    ],
+    "backtrace": [
+        {
+            "file": "^codemodel-v2\\.cmake$",
+            "line": 10,
+            "command": "add_executable",
+            "hasParent": true
+        },
+        {
+            "file": "^codemodel-v2\\.cmake$",
+            "line": null,
+            "command": null,
+            "hasParent": true
+        },
+        {
+            "file": "^CMakeLists\\.txt$",
+            "line": 3,
+            "command": "include",
+            "hasParent": true
+        },
+        {
+            "file": "^CMakeLists\\.txt$",
+            "line": null,
+            "command": null,
+            "hasParent": false
+        }
+    ],
+    "folder": null,
+    "nameOnDisk": "^c_shared_exe(\\.exe)?$",
+    "artifacts": [
+        {
+            "path": "^((Debug|Release|RelWithDebInfo|MinSizeRel)/)?c_shared_exe(\\.exe)?$",
+            "_dllExtra": false
+        },
+        {
+            "path": "^((Debug|Release|RelWithDebInfo|MinSizeRel)/)?c_shared_exe\\.pdb$",
+            "_dllExtra": true
+        }
+    ],
+    "build": "^\\.$",
+    "source": "^\\.$",
+    "install": null,
+    "link": {
+        "language": "C",
+        "lto": true,
+        "commandFragments": null
+    },
+    "archive": null,
+    "dependencies": [
+        {
+            "id": "^c_shared_lib::@6890427a1f51a3e7e1df$",
+            "backtrace": [
+                {
+                    "file": "^codemodel-v2\\.cmake$",
+                    "line": 11,
+                    "command": "target_link_libraries",
+                    "hasParent": true
+                },
+                {
+                    "file": "^codemodel-v2\\.cmake$",
+                    "line": null,
+                    "command": null,
+                    "hasParent": true
+                },
+                {
+                    "file": "^CMakeLists\\.txt$",
+                    "line": 3,
+                    "command": "include",
+                    "hasParent": true
+                },
+                {
+                    "file": "^CMakeLists\\.txt$",
+                    "line": null,
+                    "command": null,
+                    "hasParent": false
+                }
+            ]
+        },
+        {
+            "id": "^ZERO_CHECK::@6890427a1f51a3e7e1df$",
+            "backtrace": null
+        }
+    ]
+}
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/c_shared_lib.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/c_shared_lib.json
new file mode 100644
index 0000000..176a857
--- /dev/null
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/c_shared_lib.json
@@ -0,0 +1,123 @@
+{
+    "name": "c_shared_lib",
+    "id": "^c_shared_lib::@6890427a1f51a3e7e1df$",
+    "directorySource": "^\\.$",
+    "projectName": "codemodel-v2",
+    "type": "SHARED_LIBRARY",
+    "isGeneratorProvided": null,
+    "sources": [
+        {
+            "path": "^empty\\.c$",
+            "isGenerated": null,
+            "sourceGroupName": "Source Files",
+            "compileGroupLanguage": "C",
+            "backtrace": [
+                {
+                    "file": "^codemodel-v2\\.cmake$",
+                    "line": 9,
+                    "command": "add_library",
+                    "hasParent": true
+                },
+                {
+                    "file": "^codemodel-v2\\.cmake$",
+                    "line": null,
+                    "command": null,
+                    "hasParent": true
+                },
+                {
+                    "file": "^CMakeLists\\.txt$",
+                    "line": 3,
+                    "command": "include",
+                    "hasParent": true
+                },
+                {
+                    "file": "^CMakeLists\\.txt$",
+                    "line": null,
+                    "command": null,
+                    "hasParent": false
+                }
+            ]
+        }
+    ],
+    "sourceGroups": [
+        {
+            "name": "Source Files",
+            "sourcePaths": [
+                "^empty\\.c$"
+            ]
+        }
+    ],
+    "compileGroups": [
+        {
+            "language": "C",
+            "sourcePaths": [
+                "^empty\\.c$"
+            ],
+            "includes": null,
+            "defines": [
+                {
+                    "define": "c_shared_lib_EXPORTS",
+                    "backtrace": null
+                }
+            ],
+            "compileCommandFragments": null
+        }
+    ],
+    "backtrace": [
+        {
+            "file": "^codemodel-v2\\.cmake$",
+            "line": 9,
+            "command": "add_library",
+            "hasParent": true
+        },
+        {
+            "file": "^codemodel-v2\\.cmake$",
+            "line": null,
+            "command": null,
+            "hasParent": true
+        },
+        {
+            "file": "^CMakeLists\\.txt$",
+            "line": 3,
+            "command": "include",
+            "hasParent": true
+        },
+        {
+            "file": "^CMakeLists\\.txt$",
+            "line": null,
+            "command": null,
+            "hasParent": false
+        }
+    ],
+    "folder": null,
+    "nameOnDisk": "^(lib|cyg)?c_shared_lib\\.(so|dylib|dll)$",
+    "artifacts": [
+        {
+            "path": "^lib/((Debug|Release|RelWithDebInfo|MinSizeRel)/)?(lib|cyg)?c_shared_lib\\.(so|dylib|dll)$",
+            "_dllExtra": false
+        },
+        {
+            "path": "^((Debug|Release|RelWithDebInfo|MinSizeRel)/)?(lib)?c_shared_lib\\.(dll\\.a|lib)$",
+            "_dllExtra": true
+        },
+        {
+            "path": "^lib/((Debug|Release|RelWithDebInfo|MinSizeRel)/)?(lib|cyg)?c_shared_lib\\.pdb$",
+            "_dllExtra": true
+        }
+    ],
+    "build": "^\\.$",
+    "source": "^\\.$",
+    "install": null,
+    "link": {
+        "language": "C",
+        "lto": true,
+        "commandFragments": null
+    },
+    "archive": null,
+    "dependencies": [
+        {
+            "id": "^ZERO_CHECK::@6890427a1f51a3e7e1df$",
+            "backtrace": null
+        }
+    ]
+}
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/c_static_exe.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/c_static_exe.json
new file mode 100644
index 0000000..5542277
--- /dev/null
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/c_static_exe.json
@@ -0,0 +1,143 @@
+{
+    "name": "c_static_exe",
+    "id": "^c_static_exe::@6890427a1f51a3e7e1df$",
+    "directorySource": "^\\.$",
+    "projectName": "codemodel-v2",
+    "type": "EXECUTABLE",
+    "isGeneratorProvided": null,
+    "sources": [
+        {
+            "path": "^empty\\.c$",
+            "isGenerated": null,
+            "sourceGroupName": "Source Files",
+            "compileGroupLanguage": "C",
+            "backtrace": [
+                {
+                    "file": "^codemodel-v2\\.cmake$",
+                    "line": 14,
+                    "command": "add_executable",
+                    "hasParent": true
+                },
+                {
+                    "file": "^codemodel-v2\\.cmake$",
+                    "line": null,
+                    "command": null,
+                    "hasParent": true
+                },
+                {
+                    "file": "^CMakeLists\\.txt$",
+                    "line": 3,
+                    "command": "include",
+                    "hasParent": true
+                },
+                {
+                    "file": "^CMakeLists\\.txt$",
+                    "line": null,
+                    "command": null,
+                    "hasParent": false
+                }
+            ]
+        }
+    ],
+    "sourceGroups": [
+        {
+            "name": "Source Files",
+            "sourcePaths": [
+                "^empty\\.c$"
+            ]
+        }
+    ],
+    "compileGroups": [
+        {
+            "language": "C",
+            "sourcePaths": [
+                "^empty\\.c$"
+            ],
+            "includes": null,
+            "defines": null,
+            "compileCommandFragments": null
+        }
+    ],
+    "backtrace": [
+        {
+            "file": "^codemodel-v2\\.cmake$",
+            "line": 14,
+            "command": "add_executable",
+            "hasParent": true
+        },
+        {
+            "file": "^codemodel-v2\\.cmake$",
+            "line": null,
+            "command": null,
+            "hasParent": true
+        },
+        {
+            "file": "^CMakeLists\\.txt$",
+            "line": 3,
+            "command": "include",
+            "hasParent": true
+        },
+        {
+            "file": "^CMakeLists\\.txt$",
+            "line": null,
+            "command": null,
+            "hasParent": false
+        }
+    ],
+    "folder": null,
+    "nameOnDisk": "^c_static_exe(\\.exe)?$",
+    "artifacts": [
+        {
+            "path": "^((Debug|Release|RelWithDebInfo|MinSizeRel)/)?c_static_exe(\\.exe)?$",
+            "_dllExtra": false
+        },
+        {
+            "path": "^((Debug|Release|RelWithDebInfo|MinSizeRel)/)?c_static_exe\\.pdb$",
+            "_dllExtra": true
+        }
+    ],
+    "build": "^\\.$",
+    "source": "^\\.$",
+    "install": null,
+    "link": {
+        "language": "C",
+        "lto": null,
+        "commandFragments": null
+    },
+    "archive": null,
+    "dependencies": [
+        {
+            "id": "^c_static_lib::@6890427a1f51a3e7e1df$",
+            "backtrace": [
+                {
+                    "file": "^codemodel-v2\\.cmake$",
+                    "line": 15,
+                    "command": "target_link_libraries",
+                    "hasParent": true
+                },
+                {
+                    "file": "^codemodel-v2\\.cmake$",
+                    "line": null,
+                    "command": null,
+                    "hasParent": true
+                },
+                {
+                    "file": "^CMakeLists\\.txt$",
+                    "line": 3,
+                    "command": "include",
+                    "hasParent": true
+                },
+                {
+                    "file": "^CMakeLists\\.txt$",
+                    "line": null,
+                    "command": null,
+                    "hasParent": false
+                }
+            ]
+        },
+        {
+            "id": "^ZERO_CHECK::@6890427a1f51a3e7e1df$",
+            "backtrace": null
+        }
+    ]
+}
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/c_static_lib.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/c_static_lib.json
new file mode 100644
index 0000000..4b63897
--- /dev/null
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/c_static_lib.json
@@ -0,0 +1,108 @@
+{
+    "name": "c_static_lib",
+    "id": "^c_static_lib::@6890427a1f51a3e7e1df$",
+    "directorySource": "^\\.$",
+    "projectName": "codemodel-v2",
+    "type": "STATIC_LIBRARY",
+    "isGeneratorProvided": null,
+    "sources": [
+        {
+            "path": "^empty\\.c$",
+            "isGenerated": null,
+            "sourceGroupName": "Source Files",
+            "compileGroupLanguage": "C",
+            "backtrace": [
+                {
+                    "file": "^codemodel-v2\\.cmake$",
+                    "line": 13,
+                    "command": "add_library",
+                    "hasParent": true
+                },
+                {
+                    "file": "^codemodel-v2\\.cmake$",
+                    "line": null,
+                    "command": null,
+                    "hasParent": true
+                },
+                {
+                    "file": "^CMakeLists\\.txt$",
+                    "line": 3,
+                    "command": "include",
+                    "hasParent": true
+                },
+                {
+                    "file": "^CMakeLists\\.txt$",
+                    "line": null,
+                    "command": null,
+                    "hasParent": false
+                }
+            ]
+        }
+    ],
+    "sourceGroups": [
+        {
+            "name": "Source Files",
+            "sourcePaths": [
+                "^empty\\.c$"
+            ]
+        }
+    ],
+    "compileGroups": [
+        {
+            "language": "C",
+            "sourcePaths": [
+                "^empty\\.c$"
+            ],
+            "includes": null,
+            "defines": null,
+            "compileCommandFragments": null
+        }
+    ],
+    "backtrace": [
+        {
+            "file": "^codemodel-v2\\.cmake$",
+            "line": 13,
+            "command": "add_library",
+            "hasParent": true
+        },
+        {
+            "file": "^codemodel-v2\\.cmake$",
+            "line": null,
+            "command": null,
+            "hasParent": true
+        },
+        {
+            "file": "^CMakeLists\\.txt$",
+            "line": 3,
+            "command": "include",
+            "hasParent": true
+        },
+        {
+            "file": "^CMakeLists\\.txt$",
+            "line": null,
+            "command": null,
+            "hasParent": false
+        }
+    ],
+    "folder": null,
+    "nameOnDisk": "^(lib)?c_static_lib\\.(a|lib)$",
+    "artifacts": [
+        {
+            "path": "^((Debug|Release|RelWithDebInfo|MinSizeRel)/)?(lib)?c_static_lib\\.(a|lib)$",
+            "_dllExtra": false
+        }
+    ],
+    "build": "^\\.$",
+    "source": "^\\.$",
+    "install": null,
+    "link": null,
+    "archive": {
+        "lto": true
+    },
+    "dependencies": [
+        {
+            "id": "^ZERO_CHECK::@6890427a1f51a3e7e1df$",
+            "backtrace": null
+        }
+    ]
+}
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/custom_exe.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/custom_exe.json
new file mode 100644
index 0000000..ab301e9
--- /dev/null
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/custom_exe.json
@@ -0,0 +1,107 @@
+{
+    "name": "custom_exe",
+    "id": "^custom_exe::@c11385ffed57b860da63$",
+    "directorySource": "^custom$",
+    "projectName": "Custom",
+    "type": "EXECUTABLE",
+    "isGeneratorProvided": null,
+    "sources": [
+        {
+            "path": "^empty\\.c$",
+            "isGenerated": null,
+            "sourceGroupName": "Source Files",
+            "compileGroupLanguage": "C",
+            "backtrace": [
+                {
+                    "file": "^custom/CMakeLists\\.txt$",
+                    "line": 4,
+                    "command": "add_executable",
+                    "hasParent": true
+                },
+                {
+                    "file": "^custom/CMakeLists\\.txt$",
+                    "line": null,
+                    "command": null,
+                    "hasParent": false
+                }
+            ]
+        }
+    ],
+    "sourceGroups": [
+        {
+            "name": "Source Files",
+            "sourcePaths": [
+                "^empty\\.c$"
+            ]
+        }
+    ],
+    "compileGroups": [
+        {
+            "language": "C",
+            "sourcePaths": [
+                "^empty\\.c$"
+            ],
+            "includes": null,
+            "defines": null,
+            "compileCommandFragments": null
+        }
+    ],
+    "backtrace": [
+        {
+            "file": "^custom/CMakeLists\\.txt$",
+            "line": 4,
+            "command": "add_executable",
+            "hasParent": true
+        },
+        {
+            "file": "^custom/CMakeLists\\.txt$",
+            "line": null,
+            "command": null,
+            "hasParent": false
+        }
+    ],
+    "folder": null,
+    "nameOnDisk": "^custom_exe(\\.exe)?$",
+    "artifacts": [
+        {
+            "path": "^custom/((Debug|Release|RelWithDebInfo|MinSizeRel)/)?custom_exe(\\.exe)?$",
+            "_dllExtra": false
+        },
+        {
+            "path": "^custom/((Debug|Release|RelWithDebInfo|MinSizeRel)/)?custom_exe\\.pdb$",
+            "_dllExtra": true
+        }
+    ],
+    "build": "^custom$",
+    "source": "^custom$",
+    "install": null,
+    "link": {
+        "language": "C",
+        "lto": null,
+        "commandFragments": null
+    },
+    "archive": null,
+    "dependencies": [
+        {
+            "id": "^custom_tgt::@c11385ffed57b860da63$",
+            "backtrace": [
+                {
+                    "file": "^custom/CMakeLists\\.txt$",
+                    "line": 5,
+                    "command": "add_dependencies",
+                    "hasParent": true
+                },
+                {
+                    "file": "^custom/CMakeLists\\.txt$",
+                    "line": null,
+                    "command": null,
+                    "hasParent": false
+                }
+            ]
+        },
+        {
+            "id": "^ZERO_CHECK::@c11385ffed57b860da63$",
+            "backtrace": null
+        }
+    ]
+}
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/custom_tgt.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/custom_tgt.json
new file mode 100644
index 0000000..a7106fc
--- /dev/null
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/custom_tgt.json
@@ -0,0 +1,87 @@
+{
+    "name": "custom_tgt",
+    "id": "^custom_tgt::@c11385ffed57b860da63$",
+    "directorySource": "^custom$",
+    "projectName": "Custom",
+    "type": "UTILITY",
+    "isGeneratorProvided": null,
+    "sources": [
+        {
+            "path": "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/custom/CMakeFiles/custom_tgt$",
+            "isGenerated": true,
+            "sourceGroupName": "",
+            "compileGroupLanguage": null,
+            "backtrace": [
+                {
+                    "file": "^custom/CMakeLists\\.txt$",
+                    "line": 3,
+                    "command": "add_custom_target",
+                    "hasParent": true
+                },
+                {
+                    "file": "^custom/CMakeLists\\.txt$",
+                    "line": null,
+                    "command": null,
+                    "hasParent": false
+                }
+            ]
+        },
+        {
+            "path": "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/(custom/)?CMakeFiles/([0-9a-f]+/)?custom_tgt\\.rule$",
+            "isGenerated": true,
+            "sourceGroupName": "CMake Rules",
+            "compileGroupLanguage": null,
+            "backtrace": [
+                {
+                    "file": "^custom/CMakeLists\\.txt$",
+                    "line": null,
+                    "command": null,
+                    "hasParent": false
+                }
+            ]
+        }
+    ],
+    "sourceGroups": [
+        {
+            "name": "",
+            "sourcePaths": [
+                "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/custom/CMakeFiles/custom_tgt$"
+            ]
+        },
+        {
+            "name": "CMake Rules",
+            "sourcePaths": [
+                "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/(custom/)?CMakeFiles/([0-9a-f]+/)?custom_tgt\\.rule$"
+            ]
+        }
+    ],
+    "compileGroups": null,
+    "backtrace": [
+        {
+            "file": "^custom/CMakeLists\\.txt$",
+            "line": 3,
+            "command": "add_custom_target",
+            "hasParent": true
+        },
+        {
+            "file": "^custom/CMakeLists\\.txt$",
+            "line": null,
+            "command": null,
+            "hasParent": false
+        }
+    ],
+    "folder": null,
+    "nameOnDisk": null,
+    "artifacts": null,
+    "build": "^custom$",
+    "source": "^custom$",
+    "install": null,
+    "link": null,
+    "archive": null,
+    "dependencies": [
+        {
+            "id": "^ZERO_CHECK::@c11385ffed57b860da63$",
+            "backtrace": null
+        }
+    ]
+}
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_alias_exe.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_alias_exe.json
new file mode 100644
index 0000000..837f252
--- /dev/null
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_alias_exe.json
@@ -0,0 +1,107 @@
+{
+    "name": "cxx_alias_exe",
+    "id": "^cxx_alias_exe::@53632cba2752272bb008$",
+    "directorySource": "^alias$",
+    "projectName": "Alias",
+    "type": "EXECUTABLE",
+    "isGeneratorProvided": null,
+    "sources": [
+        {
+            "path": "^empty\\.cxx$",
+            "isGenerated": null,
+            "sourceGroupName": "Source Files",
+            "compileGroupLanguage": "CXX",
+            "backtrace": [
+                {
+                    "file": "^alias/CMakeLists\\.txt$",
+                    "line": 9,
+                    "command": "add_executable",
+                    "hasParent": true
+                },
+                {
+                    "file": "^alias/CMakeLists\\.txt$",
+                    "line": null,
+                    "command": null,
+                    "hasParent": false
+                }
+            ]
+        }
+    ],
+    "sourceGroups": [
+        {
+            "name": "Source Files",
+            "sourcePaths": [
+                "^empty\\.cxx$"
+            ]
+        }
+    ],
+    "compileGroups": [
+        {
+            "language": "CXX",
+            "sourcePaths": [
+                "^empty\\.cxx$"
+            ],
+            "includes": null,
+            "defines": null,
+            "compileCommandFragments": null
+        }
+    ],
+    "backtrace": [
+        {
+            "file": "^alias/CMakeLists\\.txt$",
+            "line": 9,
+            "command": "add_executable",
+            "hasParent": true
+        },
+        {
+            "file": "^alias/CMakeLists\\.txt$",
+            "line": null,
+            "command": null,
+            "hasParent": false
+        }
+    ],
+    "folder": null,
+    "nameOnDisk": "^cxx_alias_exe(\\.exe)?$",
+    "artifacts": [
+        {
+            "path": "^alias/((Debug|Release|RelWithDebInfo|MinSizeRel)/)?cxx_alias_exe(\\.exe)?$",
+            "_dllExtra": false
+        },
+        {
+            "path": "^alias/((Debug|Release|RelWithDebInfo|MinSizeRel)/)?cxx_alias_exe\\.pdb$",
+            "_dllExtra": true
+        }
+    ],
+    "build": "^alias$",
+    "source": "^alias$",
+    "install": null,
+    "link": {
+        "language": "CXX",
+        "lto": null,
+        "commandFragments": null
+    },
+    "archive": null,
+    "dependencies": [
+        {
+            "id": "^cxx_lib::@a56b12a3f5c0529fb296$",
+            "backtrace": [
+                {
+                    "file": "^alias/CMakeLists\\.txt$",
+                    "line": 10,
+                    "command": "target_link_libraries",
+                    "hasParent": true
+                },
+                {
+                    "file": "^alias/CMakeLists\\.txt$",
+                    "line": null,
+                    "command": null,
+                    "hasParent": false
+                }
+            ]
+        },
+        {
+            "id": "^ZERO_CHECK::@53632cba2752272bb008$",
+            "backtrace": null
+        }
+    ]
+}
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_exe.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_exe.json
new file mode 100644
index 0000000..c9e652b
--- /dev/null
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_exe.json
@@ -0,0 +1,232 @@
+{
+    "name": "cxx_exe",
+    "id": "^cxx_exe::@a56b12a3f5c0529fb296$",
+    "directorySource": "^cxx$",
+    "projectName": "Cxx",
+    "type": "EXECUTABLE",
+    "isGeneratorProvided": null,
+    "sources": [
+        {
+            "path": "^empty\\.cxx$",
+            "isGenerated": null,
+            "sourceGroupName": "Source Files",
+            "compileGroupLanguage": "CXX",
+            "backtrace": [
+                {
+                    "file": "^cxx/CMakeLists\\.txt$",
+                    "line": 5,
+                    "command": "add_executable",
+                    "hasParent": true
+                },
+                {
+                    "file": "^cxx/CMakeLists\\.txt$",
+                    "line": null,
+                    "command": null,
+                    "hasParent": false
+                }
+            ]
+        }
+    ],
+    "sourceGroups": [
+        {
+            "name": "Source Files",
+            "sourcePaths": [
+                "^empty\\.cxx$"
+            ]
+        }
+    ],
+    "compileGroups": [
+        {
+            "language": "CXX",
+            "sourcePaths": [
+                "^empty\\.cxx$"
+            ],
+            "includes": null,
+            "defines": null,
+            "precompileHeaders": [
+              {
+                "header": ".*empty\\.h$",
+                "backtrace": [
+                  {
+                    "file": "^cxx/CMakeLists\\.txt$",
+                    "line": 21,
+                    "command": "target_precompile_headers",
+                    "hasParent": true
+                  },
+                  {
+                    "file": "^cxx/CMakeLists\\.txt$",
+                    "line": null,
+                    "command": null,
+                    "hasParent": false
+                  }
+                ]
+              }
+            ],
+            "compileCommandFragments": [
+                {
+                    "fragment" : "TargetCompileOptions",
+                    "backtrace": [
+                        {
+                            "file": "^cxx/CMakeLists\\.txt$",
+                            "line": 17,
+                            "command": "target_compile_options",
+                            "hasParent": true
+                        },
+                        {
+                            "file" : "^cxx/CMakeLists\\.txt$",
+                            "line": null,
+                            "command": null,
+                            "hasParent": false
+                        }
+                    ]
+                }
+            ]
+        }
+    ],
+    "backtrace": [
+        {
+            "file": "^cxx/CMakeLists\\.txt$",
+            "line": 5,
+            "command": "add_executable",
+            "hasParent": true
+        },
+        {
+            "file": "^cxx/CMakeLists\\.txt$",
+            "line": null,
+            "command": null,
+            "hasParent": false
+        }
+    ],
+    "folder": "bin",
+    "nameOnDisk": "^cxx_exe(\\.exe)?$",
+    "artifacts": [
+        {
+            "path": "^cxx/((Debug|Release|RelWithDebInfo|MinSizeRel)/)?cxx_exe(\\.exe)?$",
+            "_dllExtra": false
+        },
+        {
+            "path": "^cxx/((Debug|Release|RelWithDebInfo|MinSizeRel)/)?cxx_exe\\.pdb$",
+            "_dllExtra": true
+        }
+    ],
+    "build": "^cxx$",
+    "source": "^cxx$",
+    "install": {
+        "prefix": "^(/usr/local|[A-Za-z]:.*/codemodel-v2)$",
+        "destinations": [
+            {
+                "path": "bin",
+                "backtrace": [
+                    {
+                        "file": "^codemodel-v2\\.cmake$",
+                        "line": 38,
+                        "command": "install",
+                        "hasParent": true
+                    },
+                    {
+                        "file": "^codemodel-v2\\.cmake$",
+                        "line": null,
+                        "command": null,
+                        "hasParent": true
+                    },
+                    {
+                        "file": "^CMakeLists\\.txt$",
+                        "line": 3,
+                        "command": "include",
+                        "hasParent": true
+                    },
+                    {
+                        "file": "^CMakeLists\\.txt$",
+                        "line": null,
+                        "command": null,
+                        "hasParent": false
+                    }
+                ]
+            }
+        ]
+    },
+    "link": {
+        "language": "CXX",
+        "lto": null,
+        "commandFragments": [
+            {
+                "fragment" : "TargetLinkOptions",
+                "role" : "flags",
+                "backtrace": [
+                    {
+                        "file": "^cxx/CMakeLists\\.txt$",
+                        "line": 18,
+                        "command": "target_link_options",
+                        "hasParent": true
+                    },
+                    {
+                        "file" : "^cxx/CMakeLists\\.txt$",
+                        "line": null,
+                        "command": null,
+                        "hasParent": false
+                    }
+                ]
+            },
+            {
+                "fragment" : ".*TargetLinkDir\\\"?$",
+                "role" : "libraryPath",
+                "backtrace": [
+                    {
+                        "file": "^cxx/CMakeLists\\.txt$",
+                        "line": 19,
+                        "command": "target_link_directories",
+                        "hasParent": true
+                    },
+                    {
+                        "file" : "^cxx/CMakeLists\\.txt$",
+                        "line": null,
+                        "command": null,
+                        "hasParent": false
+                    }
+                ]
+            },
+            {
+                "fragment" : ".*cxx_lib.*",
+                "role" : "libraries",
+                "backtrace": [
+                    {
+                        "file": "^cxx/CMakeLists\\.txt$",
+                        "line": 6,
+                        "command": "target_link_libraries",
+                        "hasParent": true
+                    },
+                    {
+                        "file" : "^cxx/CMakeLists\\.txt$",
+                        "line": null,
+                        "command": null,
+                        "hasParent": false
+                    }
+                ]
+            }
+        ]
+    },
+    "archive": null,
+    "dependencies": [
+        {
+            "id": "^cxx_lib::@a56b12a3f5c0529fb296$",
+            "backtrace": [
+                {
+                    "file": "^cxx/CMakeLists\\.txt$",
+                    "line": 6,
+                    "command": "target_link_libraries",
+                    "hasParent": true
+                },
+                {
+                    "file": "^cxx/CMakeLists\\.txt$",
+                    "line": null,
+                    "command": null,
+                    "hasParent": false
+                }
+            ]
+        },
+        {
+            "id": "^ZERO_CHECK::@a56b12a3f5c0529fb296$",
+            "backtrace": null
+        }
+    ]
+}
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_exe_precompileheader.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_exe_precompileheader.json
new file mode 100644
index 0000000..5a0f770
--- /dev/null
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_exe_precompileheader.json
@@ -0,0 +1,161 @@
+{
+  "compileGroups": [
+    {
+      "language": "CXX",
+      "sourcePaths": [
+        ".*cmake_pch(_[^.]+)?(\\.hxx)?\\.cxx$"
+      ],
+      "includes": null,
+      "defines": null,
+      "precompileHeaders": [
+        {
+          "header": ".*empty\\.h$",
+          "backtrace": [
+            {
+              "file": "^cxx/CMakeLists\\.txt$",
+              "line": 21,
+              "command": "target_precompile_headers",
+              "hasParent": true
+            },
+            {
+              "file": "^cxx/CMakeLists\\.txt$",
+              "line": null,
+              "command": null,
+              "hasParent": false
+            }
+          ]
+        }
+      ],
+      "compileCommandFragments": [
+        {
+          "fragment": "TargetCompileOptions",
+          "backtrace": [
+            {
+              "file": "^cxx/CMakeLists\\.txt$",
+              "line": 17,
+              "command": "target_compile_options",
+              "hasParent": true
+            },
+            {
+              "file": "^cxx/CMakeLists\\.txt$",
+              "line": null,
+              "command": null,
+              "hasParent": false
+            }
+          ]
+        }
+      ]
+    },
+    {
+      "language": "CXX",
+      "sourcePaths": [
+        "^empty\\.cxx$"
+      ],
+      "includes": null,
+      "defines": null,
+      "precompileHeaders": [
+        {
+          "header": ".*empty\\.h$",
+          "backtrace": [
+            {
+              "file": "^cxx/CMakeLists\\.txt$",
+              "line": 21,
+              "command": "target_precompile_headers",
+              "hasParent": true
+            },
+            {
+              "file": "^cxx/CMakeLists\\.txt$",
+              "line": null,
+              "command": null,
+              "hasParent": false
+            }
+          ]
+        }
+      ],
+      "compileCommandFragments": [
+        {
+          "fragment": "TargetCompileOptions",
+          "backtrace": [
+            {
+              "file": "^cxx/CMakeLists\\.txt$",
+              "line": 17,
+              "command": "target_compile_options",
+              "hasParent": true
+            },
+            {
+              "file": "^cxx/CMakeLists\\.txt$",
+              "line": null,
+              "command": null,
+              "hasParent": false
+            }
+          ]
+        }
+      ]
+    }
+  ],
+  "sources": [
+    {
+      "path": ".*cmake_pch(_[^.]+)?(\\.hxx)?\\.cxx$",
+      "isGenerated": null,
+      "sourceGroupName": "Source Files",
+      "compileGroupLanguage": "CXX",
+      "backtrace": [
+        {
+          "file": "^cxx/CMakeLists\\.txt$",
+          "line": null,
+          "command": null,
+          "hasParent": false
+        }
+      ]
+    },
+    {
+      "path": "^empty\\.cxx$",
+      "isGenerated": null,
+      "sourceGroupName": "Source Files",
+      "compileGroupLanguage": "CXX",
+      "backtrace": [
+        {
+          "file": "^cxx/CMakeLists\\.txt$",
+          "line": 5,
+          "command": "add_executable",
+          "hasParent": true
+        },
+        {
+          "file": "^cxx/CMakeLists\\.txt$",
+          "line": null,
+          "command": null,
+          "hasParent": false
+        }
+      ]
+    },
+    {
+      "path": ".*/cmake_pch(_[^.]+)?\\.hxx$",
+      "isGenerated": null,
+      "sourceGroupName": "Precompile Header File",
+      "compileGroupLanguage": null,
+      "backtrace": [
+        {
+          "file": "^cxx/CMakeLists\\.txt$",
+          "line": null,
+          "command": null,
+          "hasParent": false
+        }
+      ]
+    }
+  ],
+  "sourceGroups": [
+    {
+      "name": "Source Files",
+      "sourcePaths": [
+        ".*cmake_pch(_[^.]+)?(\\.hxx)?\\.cxx$",
+        "^empty\\.cxx$"
+      ]
+    },
+    {
+      "name": "Precompile Header File",
+      "sourcePaths": [
+        ".*/cmake_pch(_[^.]+)?\\.hxx$"
+      ]
+    }
+  ]
+}
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_exe_precompileheader_2arch.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_exe_precompileheader_2arch.json
new file mode 100644
index 0000000..9455748
--- /dev/null
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_exe_precompileheader_2arch.json
@@ -0,0 +1,237 @@
+{
+  "compileGroups": [
+    {
+      "language": "CXX",
+      "sourcePaths": [
+        ".*cmake_pch(_[^.]+)?(\\.hxx)?\\.cxx$"
+      ],
+      "includes": null,
+      "defines": null,
+      "precompileHeaders": [
+        {
+          "header": ".*empty\\.h$",
+          "backtrace": [
+            {
+              "file": "^cxx/CMakeLists\\.txt$",
+              "line": 21,
+              "command": "target_precompile_headers",
+              "hasParent": true
+            },
+            {
+              "file": "^cxx/CMakeLists\\.txt$",
+              "line": null,
+              "command": null,
+              "hasParent": false
+            }
+          ]
+        }
+      ],
+      "compileCommandFragments": [
+        {
+          "fragment": "TargetCompileOptions",
+          "backtrace": [
+            {
+              "file": "^cxx/CMakeLists\\.txt$",
+              "line": 17,
+              "command": "target_compile_options",
+              "hasParent": true
+            },
+            {
+              "file": "^cxx/CMakeLists\\.txt$",
+              "line": null,
+              "command": null,
+              "hasParent": false
+            }
+          ]
+        }
+      ]
+    },
+    {
+      "language": "CXX",
+      "sourcePaths": [
+        ".*cmake_pch(_[^.]+)?(\\.hxx)?\\.cxx$"
+      ],
+      "includes": null,
+      "defines": null,
+      "precompileHeaders": [
+        {
+          "header": ".*empty\\.h$",
+          "backtrace": [
+            {
+              "file": "^cxx/CMakeLists\\.txt$",
+              "line": 21,
+              "command": "target_precompile_headers",
+              "hasParent": true
+            },
+            {
+              "file": "^cxx/CMakeLists\\.txt$",
+              "line": null,
+              "command": null,
+              "hasParent": false
+            }
+          ]
+        }
+      ],
+      "compileCommandFragments": [
+        {
+          "fragment": "TargetCompileOptions",
+          "backtrace": [
+            {
+              "file": "^cxx/CMakeLists\\.txt$",
+              "line": 17,
+              "command": "target_compile_options",
+              "hasParent": true
+            },
+            {
+              "file": "^cxx/CMakeLists\\.txt$",
+              "line": null,
+              "command": null,
+              "hasParent": false
+            }
+          ]
+        }
+      ]
+    },
+    {
+      "language": "CXX",
+      "sourcePaths": [
+        "^empty\\.cxx$"
+      ],
+      "includes": null,
+      "defines": null,
+      "precompileHeaders": [
+        {
+          "header": ".*empty\\.h$",
+          "backtrace": [
+            {
+              "file": "^cxx/CMakeLists\\.txt$",
+              "line": 21,
+              "command": "target_precompile_headers",
+              "hasParent": true
+            },
+            {
+              "file": "^cxx/CMakeLists\\.txt$",
+              "line": null,
+              "command": null,
+              "hasParent": false
+            }
+          ]
+        }
+      ],
+      "compileCommandFragments": [
+        {
+          "fragment": "TargetCompileOptions",
+          "backtrace": [
+            {
+              "file": "^cxx/CMakeLists\\.txt$",
+              "line": 17,
+              "command": "target_compile_options",
+              "hasParent": true
+            },
+            {
+              "file": "^cxx/CMakeLists\\.txt$",
+              "line": null,
+              "command": null,
+              "hasParent": false
+            }
+          ]
+        }
+      ]
+    }
+  ],
+  "sources": [
+    {
+      "path": ".*cmake_pch(_[^.]+)?(\\.hxx)?\\.cxx$",
+      "isGenerated": null,
+      "sourceGroupName": "Source Files",
+      "compileGroupLanguage": "CXX",
+      "backtrace": [
+        {
+          "file": "^cxx/CMakeLists\\.txt$",
+          "line": null,
+          "command": null,
+          "hasParent": false
+        }
+      ]
+    },
+    {
+      "path": ".*cmake_pch(_[^.]+)?(\\.hxx)?\\.cxx$",
+      "isGenerated": null,
+      "sourceGroupName": "Source Files",
+      "compileGroupLanguage": "CXX",
+      "backtrace": [
+        {
+          "file": "^cxx/CMakeLists\\.txt$",
+          "line": null,
+          "command": null,
+          "hasParent": false
+        }
+      ]
+    },
+    {
+      "path": "^empty\\.cxx$",
+      "isGenerated": null,
+      "sourceGroupName": "Source Files",
+      "compileGroupLanguage": "CXX",
+      "backtrace": [
+        {
+          "file": "^cxx/CMakeLists\\.txt$",
+          "line": 5,
+          "command": "add_executable",
+          "hasParent": true
+        },
+        {
+          "file": "^cxx/CMakeLists\\.txt$",
+          "line": null,
+          "command": null,
+          "hasParent": false
+        }
+      ]
+    },
+    {
+      "path": ".*/cmake_pch(_[^.]+)?\\.hxx$",
+      "isGenerated": null,
+      "sourceGroupName": "Precompile Header File",
+      "compileGroupLanguage": null,
+      "backtrace": [
+        {
+          "file": "^cxx/CMakeLists\\.txt$",
+          "line": null,
+          "command": null,
+          "hasParent": false
+        }
+      ]
+    },
+    {
+      "path": ".*/cmake_pch(_[^.]+)?\\.hxx$",
+      "isGenerated": null,
+      "sourceGroupName": "Precompile Header File",
+      "compileGroupLanguage": null,
+      "backtrace": [
+        {
+          "file": "^cxx/CMakeLists\\.txt$",
+          "line": null,
+          "command": null,
+          "hasParent": false
+        }
+      ]
+    }
+  ],
+  "sourceGroups": [
+    {
+      "name": "Source Files",
+      "sourcePaths": [
+        ".*cmake_pch(_[^.]+)?(\\.hxx)?\\.cxx$",
+        ".*cmake_pch(_[^.]+)?(\\.hxx)?\\.cxx$",
+        "^empty\\.cxx$"
+      ]
+    },
+    {
+      "name": "Precompile Header File",
+      "sourcePaths": [
+        ".*/cmake_pch(_[^.]+)?\\.hxx$",
+        ".*/cmake_pch(_[^.]+)?\\.hxx$"
+      ]
+    }
+  ]
+}
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_exe_precompileheader_multigen.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_exe_precompileheader_multigen.json
new file mode 100644
index 0000000..9f6ffcc
--- /dev/null
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_exe_precompileheader_multigen.json
@@ -0,0 +1,206 @@
+{
+  "compileGroups": [
+    {
+      "language": "CXX",
+      "sourcePaths": [
+        ".*cmake_pch(_[^.]+)?(\\.hxx)?\\.cxx$"
+      ],
+      "includes": null,
+      "defines": null,
+      "precompileHeaders": [
+        {
+          "header": ".*empty\\.h$",
+          "backtrace": [
+            {
+              "file": "^cxx/CMakeLists\\.txt$",
+              "line": 21,
+              "command": "target_precompile_headers",
+              "hasParent": true
+            },
+            {
+              "file": "^cxx/CMakeLists\\.txt$",
+              "line": null,
+              "command": null,
+              "hasParent": false
+            }
+          ]
+        }
+      ],
+      "compileCommandFragments": [
+        {
+          "fragment": "TargetCompileOptions",
+          "backtrace": [
+            {
+              "file": "^cxx/CMakeLists\\.txt$",
+              "line": 17,
+              "command": "target_compile_options",
+              "hasParent": true
+            },
+            {
+              "file": "^cxx/CMakeLists\\.txt$",
+              "line": null,
+              "command": null,
+              "hasParent": false
+            }
+          ]
+        }
+      ]
+    },
+    {
+      "language": "CXX",
+      "sourcePaths": [
+        "^empty\\.cxx$"
+      ],
+      "includes": null,
+      "defines": null,
+      "precompileHeaders": [
+        {
+          "header": ".*empty\\.h$",
+          "backtrace": [
+            {
+              "file": "^cxx/CMakeLists\\.txt$",
+              "line": 21,
+              "command": "target_precompile_headers",
+              "hasParent": true
+            },
+            {
+              "file": "^cxx/CMakeLists\\.txt$",
+              "line": null,
+              "command": null,
+              "hasParent": false
+            }
+          ]
+        }
+      ],
+      "compileCommandFragments": [
+        {
+          "fragment": "TargetCompileOptions",
+          "backtrace": [
+            {
+              "file": "^cxx/CMakeLists\\.txt$",
+              "line": 17,
+              "command": "target_compile_options",
+              "hasParent": true
+            },
+            {
+              "file": "^cxx/CMakeLists\\.txt$",
+              "line": null,
+              "command": null,
+              "hasParent": false
+            }
+          ]
+        }
+      ]
+    }
+  ],
+  "sources": [
+    {
+      "path": ".*cmake_pch(_[^.]+)?(\\.hxx)?\\.cxx$",
+      "isGenerated": null,
+      "sourceGroupName": "Source Files",
+      "compileGroupLanguage": "CXX",
+      "backtrace": [
+        {
+          "file": "^cxx/CMakeLists\\.txt$",
+          "line": null,
+          "command": null,
+          "hasParent": false
+        }
+      ]
+    },
+    {
+      "path": "^empty\\.cxx$",
+      "isGenerated": null,
+      "sourceGroupName": "Source Files",
+      "compileGroupLanguage": "CXX",
+      "backtrace": [
+        {
+          "file": "^cxx/CMakeLists\\.txt$",
+          "line": 5,
+          "command": "add_executable",
+          "hasParent": true
+        },
+        {
+          "file": "^cxx/CMakeLists\\.txt$",
+          "line": null,
+          "command": null,
+          "hasParent": false
+        }
+      ]
+    },
+    {
+      "path": ".*/Debug/cmake_pch(_[^.]+)?\\.hxx$",
+      "isGenerated": null,
+      "sourceGroupName": "Precompile Header File",
+      "compileGroupLanguage": null,
+      "backtrace": [
+        {
+          "file": "^cxx/CMakeLists\\.txt$",
+          "line": null,
+          "command": null,
+          "hasParent": false
+        }
+      ]
+    },
+    {
+      "path": ".*/Release/cmake_pch(_[^.]+)?\\.hxx$",
+      "isGenerated": null,
+      "sourceGroupName": "Precompile Header File",
+      "compileGroupLanguage": null,
+      "backtrace": [
+        {
+          "file": "^cxx/CMakeLists\\.txt$",
+          "line": null,
+          "command": null,
+          "hasParent": false
+        }
+      ]
+    },
+    {
+      "path": ".*/MinSizeRel/cmake_pch(_[^.]+)?\\.hxx$",
+      "isGenerated": null,
+      "sourceGroupName": "Precompile Header File",
+      "compileGroupLanguage": null,
+      "backtrace": [
+        {
+          "file": "^cxx/CMakeLists\\.txt$",
+          "line": null,
+          "command": null,
+          "hasParent": false
+        }
+      ]
+    },
+    {
+      "path": ".*/RelWithDebInfo/cmake_pch(_[^.]+)?\\.hxx$",
+      "isGenerated": null,
+      "sourceGroupName": "Precompile Header File",
+      "compileGroupLanguage": null,
+      "backtrace": [
+        {
+          "file": "^cxx/CMakeLists\\.txt$",
+          "line": null,
+          "command": null,
+          "hasParent": false
+        }
+      ]
+    }
+  ],
+  "sourceGroups": [
+    {
+      "name": "Source Files",
+      "sourcePaths": [
+        ".*cmake_pch(_[^.]+)?(\\.hxx)?\\.cxx$",
+        "^empty\\.cxx$"
+      ]
+    },
+    {
+      "name": "Precompile Header File",
+      "sourcePaths": [
+        ".*/Debug/cmake_pch(_[^.]+)?\\.hxx$",
+        ".*/Release/cmake_pch(_[^.]+)?\\.hxx$",
+        ".*/MinSizeRel/cmake_pch(_[^.]+)?\\.hxx$",
+        ".*/RelWithDebInfo/cmake_pch(_[^.]+)?\\.hxx$"
+      ]
+    }
+  ]
+}
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_lib.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_lib.json
new file mode 100644
index 0000000..94ac081
--- /dev/null
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_lib.json
@@ -0,0 +1,84 @@
+{
+    "name": "cxx_lib",
+    "id": "^cxx_lib::@a56b12a3f5c0529fb296$",
+    "directorySource": "^cxx$",
+    "projectName": "Cxx",
+    "type": "STATIC_LIBRARY",
+    "isGeneratorProvided": null,
+    "sources": [
+        {
+            "path": "^empty\\.cxx$",
+            "isGenerated": null,
+            "sourceGroupName": "Source Files",
+            "compileGroupLanguage": "CXX",
+            "backtrace": [
+                {
+                    "file": "^cxx/CMakeLists\\.txt$",
+                    "line": 4,
+                    "command": "add_library",
+                    "hasParent": true
+                },
+                {
+                    "file": "^cxx/CMakeLists\\.txt$",
+                    "line": null,
+                    "command": null,
+                    "hasParent": false
+                }
+            ]
+        }
+    ],
+    "sourceGroups": [
+        {
+            "name": "Source Files",
+            "sourcePaths": [
+                "^empty\\.cxx$"
+            ]
+        }
+    ],
+    "compileGroups": [
+        {
+            "language": "CXX",
+            "sourcePaths": [
+                "^empty\\.cxx$"
+            ],
+            "includes": null,
+            "defines": null,
+            "compileCommandFragments": null
+        }
+    ],
+    "backtrace": [
+        {
+            "file": "^cxx/CMakeLists\\.txt$",
+            "line": 4,
+            "command": "add_library",
+            "hasParent": true
+        },
+        {
+            "file": "^cxx/CMakeLists\\.txt$",
+            "line": null,
+            "command": null,
+            "hasParent": false
+        }
+    ],
+    "folder": null,
+    "nameOnDisk": "^(lib)?cxx_lib\\.(a|lib)$",
+    "artifacts": [
+        {
+            "path": "^cxx/((Debug|Release|RelWithDebInfo|MinSizeRel)/)?(lib)?cxx_lib\\.(a|lib)$",
+            "_dllExtra": false
+        }
+    ],
+    "build": "^cxx$",
+    "source": "^cxx$",
+    "install": null,
+    "link": null,
+    "archive": {
+        "lto": null
+    },
+    "dependencies": [
+        {
+            "id": "^ZERO_CHECK::@a56b12a3f5c0529fb296$",
+            "backtrace": null
+        }
+    ]
+}
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_object_exe.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_object_exe.json
new file mode 100644
index 0000000..119c91d
--- /dev/null
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_object_exe.json
@@ -0,0 +1,154 @@
+{
+    "name": "cxx_object_exe",
+    "id": "^cxx_object_exe::@5ed5358f70faf8d8af7a$",
+    "directorySource": "^object$",
+    "projectName": "Object",
+    "type": "EXECUTABLE",
+    "isGeneratorProvided": null,
+    "sources": [
+        {
+            "path": "^empty\\.cxx$",
+            "isGenerated": null,
+            "sourceGroupName": "Source Files",
+            "compileGroupLanguage": "CXX",
+            "backtrace": [
+                {
+                    "file": "^object/CMakeLists\\.txt$",
+                    "line": 10,
+                    "command": "add_executable",
+                    "hasParent": true
+                },
+                {
+                    "file": "^object/CMakeLists\\.txt$",
+                    "line": null,
+                    "command": null,
+                    "hasParent": false
+                }
+            ]
+        },
+        {
+            "path": "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/object/.*/empty(\\.cxx)?\\.o(bj)?$",
+            "isGenerated": true,
+            "sourceGroupName": "Object Libraries",
+            "compileGroupLanguage": null,
+            "backtrace": [
+                {
+                    "file": "^object/CMakeLists\\.txt$",
+                    "line": 11,
+                    "command": "target_link_libraries",
+                    "hasParent": true
+                },
+                {
+                    "file": "^object/CMakeLists\\.txt$",
+                    "line": null,
+                    "command": null,
+                    "hasParent": false
+                }
+            ]
+        }
+    ],
+    "sourceGroups": [
+        {
+            "name": "Source Files",
+            "sourcePaths": [
+                "^empty\\.cxx$"
+            ]
+        },
+        {
+            "name": "Object Libraries",
+            "sourcePaths": [
+                "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/object/.*/empty(\\.cxx)?\\.o(bj)?$"
+            ]
+        }
+    ],
+    "compileGroups": [
+        {
+            "language": "CXX",
+            "sourcePaths": [
+                "^empty\\.cxx$"
+            ],
+            "includes": null,
+            "defines": null,
+            "compileCommandFragments": null
+        }
+    ],
+    "backtrace": [
+        {
+            "file": "^object/CMakeLists\\.txt$",
+            "line": 10,
+            "command": "add_executable",
+            "hasParent": true
+        },
+        {
+            "file": "^object/CMakeLists\\.txt$",
+            "line": null,
+            "command": null,
+            "hasParent": false
+        }
+    ],
+    "folder": null,
+    "nameOnDisk": "^cxx_object_exe(\\.exe)?$",
+    "artifacts": [
+        {
+            "path": "^object/((Debug|Release|RelWithDebInfo|MinSizeRel)/)?cxx_object_exe(\\.exe)?$",
+            "_dllExtra": false
+        },
+        {
+            "path": "^object/((Debug|Release|RelWithDebInfo|MinSizeRel)/)?cxx_object_exe\\.pdb$",
+            "_dllExtra": true
+        }
+    ],
+    "build": "^object$",
+    "source": "^object$",
+    "install": {
+        "prefix": "^(/usr/local|[A-Za-z]:.*/codemodel-v2)$",
+        "destinations": [
+            {
+                "path": "bin",
+                "backtrace": [
+                    {
+                        "file": "^object/CMakeLists\\.txt$",
+                        "line": 13,
+                        "command": "install",
+                        "hasParent": true
+                    },
+                    {
+                        "file": "^object/CMakeLists\\.txt$",
+                        "line": null,
+                        "command": null,
+                        "hasParent": false
+                    }
+                ]
+            }
+        ]
+    },
+    "link": {
+        "language": "CXX",
+        "lto": null,
+        "commandFragments": null
+    },
+    "archive": null,
+    "dependencies": [
+        {
+            "id": "^cxx_object_lib::@5ed5358f70faf8d8af7a$",
+            "backtrace": [
+                {
+                    "file": "^object/CMakeLists\\.txt$",
+                    "line": 11,
+                    "command": "target_link_libraries",
+                    "hasParent": true
+                },
+                {
+                    "file": "^object/CMakeLists\\.txt$",
+                    "line": null,
+                    "command": null,
+                    "hasParent": false
+                }
+            ]
+        },
+        {
+            "id": "^ZERO_CHECK::@5ed5358f70faf8d8af7a$",
+            "backtrace": null
+        }
+    ]
+}
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_object_lib.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_object_lib.json
new file mode 100644
index 0000000..8e99f7d
--- /dev/null
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_object_lib.json
@@ -0,0 +1,82 @@
+{
+    "name": "cxx_object_lib",
+    "id": "^cxx_object_lib::@5ed5358f70faf8d8af7a$",
+    "directorySource": "^object$",
+    "projectName": "Object",
+    "type": "OBJECT_LIBRARY",
+    "isGeneratorProvided": null,
+    "sources": [
+        {
+            "path": "^empty\\.cxx$",
+            "isGenerated": null,
+            "sourceGroupName": "Source Files",
+            "compileGroupLanguage": "CXX",
+            "backtrace": [
+                {
+                    "file": "^object/CMakeLists\\.txt$",
+                    "line": 9,
+                    "command": "add_library",
+                    "hasParent": true
+                },
+                {
+                    "file": "^object/CMakeLists\\.txt$",
+                    "line": null,
+                    "command": null,
+                    "hasParent": false
+                }
+            ]
+        }
+    ],
+    "sourceGroups": [
+        {
+            "name": "Source Files",
+            "sourcePaths": [
+                "^empty\\.cxx$"
+            ]
+        }
+    ],
+    "compileGroups": [
+        {
+            "language": "CXX",
+            "sourcePaths": [
+                "^empty\\.cxx$"
+            ],
+            "includes": null,
+            "defines": null,
+            "compileCommandFragments": null
+        }
+    ],
+    "backtrace": [
+        {
+            "file": "^object/CMakeLists\\.txt$",
+            "line": 9,
+            "command": "add_library",
+            "hasParent": true
+        },
+        {
+            "file": "^object/CMakeLists\\.txt$",
+            "line": null,
+            "command": null,
+            "hasParent": false
+        }
+    ],
+    "folder": null,
+    "nameOnDisk": null,
+    "artifacts": [
+        {
+            "path": "^object/.*/empty(\\.cxx)?\\.o(bj)?$",
+            "_dllExtra": false
+        }
+    ],
+    "build": "^object$",
+    "source": "^object$",
+    "install": null,
+    "link": null,
+    "archive": null,
+    "dependencies": [
+        {
+            "id": "^ZERO_CHECK::@5ed5358f70faf8d8af7a$",
+            "backtrace": null
+        }
+    ]
+}
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_shared_exe.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_shared_exe.json
new file mode 100644
index 0000000..4421c8f
--- /dev/null
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_shared_exe.json
@@ -0,0 +1,107 @@
+{
+    "name": "cxx_shared_exe",
+    "id": "^cxx_shared_exe::@a56b12a3f5c0529fb296$",
+    "directorySource": "^cxx$",
+    "projectName": "Cxx",
+    "type": "EXECUTABLE",
+    "isGeneratorProvided": null,
+    "sources": [
+        {
+            "path": "^empty\\.cxx$",
+            "isGenerated": null,
+            "sourceGroupName": "Source Files",
+            "compileGroupLanguage": "CXX",
+            "backtrace": [
+                {
+                    "file": "^cxx/CMakeLists\\.txt$",
+                    "line": 10,
+                    "command": "add_executable",
+                    "hasParent": true
+                },
+                {
+                    "file": "^cxx/CMakeLists\\.txt$",
+                    "line": null,
+                    "command": null,
+                    "hasParent": false
+                }
+            ]
+        }
+    ],
+    "sourceGroups": [
+        {
+            "name": "Source Files",
+            "sourcePaths": [
+                "^empty\\.cxx$"
+            ]
+        }
+    ],
+    "compileGroups": [
+        {
+            "language": "CXX",
+            "sourcePaths": [
+                "^empty\\.cxx$"
+            ],
+            "includes": null,
+            "defines": null,
+            "compileCommandFragments": null
+        }
+    ],
+    "backtrace": [
+        {
+            "file": "^cxx/CMakeLists\\.txt$",
+            "line": 10,
+            "command": "add_executable",
+            "hasParent": true
+        },
+        {
+            "file": "^cxx/CMakeLists\\.txt$",
+            "line": null,
+            "command": null,
+            "hasParent": false
+        }
+    ],
+    "folder": null,
+    "nameOnDisk": "^cxx_shared_exe(\\.exe)?$",
+    "artifacts": [
+        {
+            "path": "^cxx/((Debug|Release|RelWithDebInfo|MinSizeRel)/)?cxx_shared_exe(\\.exe)?$",
+            "_dllExtra": false
+        },
+        {
+            "path": "^cxx/((Debug|Release|RelWithDebInfo|MinSizeRel)/)?cxx_shared_exe\\.pdb$",
+            "_dllExtra": true
+        }
+    ],
+    "build": "^cxx$",
+    "source": "^cxx$",
+    "install": null,
+    "link": {
+        "language": "CXX",
+        "lto": null,
+        "commandFragments": null
+    },
+    "archive": null,
+    "dependencies": [
+        {
+            "id": "^cxx_shared_lib::@a56b12a3f5c0529fb296$",
+            "backtrace": [
+                {
+                    "file": "^cxx/CMakeLists\\.txt$",
+                    "line": 11,
+                    "command": "target_link_libraries",
+                    "hasParent": true
+                },
+                {
+                    "file": "^cxx/CMakeLists\\.txt$",
+                    "line": null,
+                    "command": null,
+                    "hasParent": false
+                }
+            ]
+        },
+        {
+            "id": "^ZERO_CHECK::@a56b12a3f5c0529fb296$",
+            "backtrace": null
+        }
+    ]
+}
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_shared_lib.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_shared_lib.json
new file mode 100644
index 0000000..171a4f5
--- /dev/null
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_shared_lib.json
@@ -0,0 +1,99 @@
+{
+    "name": "cxx_shared_lib",
+    "id": "^cxx_shared_lib::@a56b12a3f5c0529fb296$",
+    "directorySource": "^cxx$",
+    "projectName": "Cxx",
+    "type": "SHARED_LIBRARY",
+    "isGeneratorProvided": null,
+    "sources": [
+        {
+            "path": "^empty\\.cxx$",
+            "isGenerated": null,
+            "sourceGroupName": "Source Files",
+            "compileGroupLanguage": "CXX",
+            "backtrace": [
+                {
+                    "file": "^cxx/CMakeLists\\.txt$",
+                    "line": 9,
+                    "command": "add_library",
+                    "hasParent": true
+                },
+                {
+                    "file": "^cxx/CMakeLists\\.txt$",
+                    "line": null,
+                    "command": null,
+                    "hasParent": false
+                }
+            ]
+        }
+    ],
+    "sourceGroups": [
+        {
+            "name": "Source Files",
+            "sourcePaths": [
+                "^empty\\.cxx$"
+            ]
+        }
+    ],
+    "compileGroups": [
+        {
+            "language": "CXX",
+            "sourcePaths": [
+                "^empty\\.cxx$"
+            ],
+            "includes": null,
+            "defines": [
+                {
+                    "define": "cxx_shared_lib_EXPORTS",
+                    "backtrace": null
+                }
+            ],
+            "compileCommandFragments": null
+        }
+    ],
+    "backtrace": [
+        {
+            "file": "^cxx/CMakeLists\\.txt$",
+            "line": 9,
+            "command": "add_library",
+            "hasParent": true
+        },
+        {
+            "file": "^cxx/CMakeLists\\.txt$",
+            "line": null,
+            "command": null,
+            "hasParent": false
+        }
+    ],
+    "folder": null,
+    "nameOnDisk": "^(lib|cyg)?cxx_shared_lib\\.(so|dylib|dll)$",
+    "artifacts": [
+        {
+            "path": "^cxx/((Debug|Release|RelWithDebInfo|MinSizeRel)/)?(lib|cyg)?cxx_shared_lib\\.(so|dylib|dll)$",
+            "_dllExtra": false
+        },
+        {
+            "path": "^cxx/((Debug|Release|RelWithDebInfo|MinSizeRel)/)?(lib)?cxx_shared_lib\\.(dll\\.a|lib)$",
+            "_dllExtra": true
+        },
+        {
+            "path": "^cxx/((Debug|Release|RelWithDebInfo|MinSizeRel)/)?(lib|cyg)?cxx_shared_lib\\.pdb$",
+            "_dllExtra": true
+        }
+    ],
+    "build": "^cxx$",
+    "source": "^cxx$",
+    "install": null,
+    "link": {
+        "language": "CXX",
+        "lto": null,
+        "commandFragments": null
+    },
+    "archive": null,
+    "dependencies": [
+        {
+            "id": "^ZERO_CHECK::@a56b12a3f5c0529fb296$",
+            "backtrace": null
+        }
+    ]
+}
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_standard_compile_feature_exe.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_standard_compile_feature_exe.json
new file mode 100644
index 0000000..d6d573f
--- /dev/null
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_standard_compile_feature_exe.json
@@ -0,0 +1,110 @@
+{
+    "name": "cxx_standard_compile_feature_exe",
+    "id": "^cxx_standard_compile_feature_exe::@a56b12a3f5c0529fb296$",
+    "directorySource": "^cxx$",
+    "projectName": "Cxx",
+    "type": "EXECUTABLE",
+    "isGeneratorProvided": null,
+    "sources": [
+        {
+            "path": "^empty\\.cxx$",
+            "isGenerated": null,
+            "sourceGroupName": "Source Files",
+            "compileGroupLanguage": "CXX",
+            "backtrace": [
+                {
+                    "file": "^cxx/CMakeLists\\.txt$",
+                    "line": 26,
+                    "command": "add_executable",
+                    "hasParent": true
+                },
+                {
+                    "file": "^cxx/CMakeLists\\.txt$",
+                    "line": null,
+                    "command": null,
+                    "hasParent": false
+                }
+            ]
+        }
+    ],
+    "sourceGroups": [
+        {
+            "name": "Source Files",
+            "sourcePaths": [
+                "^empty\\.cxx$"
+            ]
+        }
+    ],
+    "compileGroups": [
+        {
+            "language": "CXX",
+            "languageStandard" :
+            {
+                "backtraces": [
+                    [
+                        {
+                            "file": "^cxx/CMakeLists\\.txt$",
+                            "line": 27,
+                            "command": "set_property",
+                            "hasParent": true
+                        },
+                        {
+                            "file": "^cxx/CMakeLists\\.txt$",
+                            "line": null,
+                            "command": null,
+                            "hasParent": false
+                        }
+                    ]
+                ],
+                "standard" : "98"
+            },
+            "sourcePaths": [
+                "^empty\\.cxx$"
+            ],
+            "includes": null,
+            "defines": null,
+            "compileCommandFragments": null
+        }
+    ],
+    "backtrace": [
+        {
+            "file": "^cxx/CMakeLists\\.txt$",
+            "line": 26,
+            "command": "add_executable",
+            "hasParent": true
+        },
+        {
+            "file": "^cxx/CMakeLists\\.txt$",
+            "line": null,
+            "command": null,
+            "hasParent": false
+        }
+    ],
+    "folder": null,
+    "nameOnDisk": "^cxx_standard_compile_feature_exe(\\.exe)?$",
+    "artifacts": [
+        {
+            "path": "^cxx/((Debug|Release|RelWithDebInfo|MinSizeRel)/)?cxx_standard_compile_feature_exe(\\.exe)?$",
+            "_dllExtra": false
+        },
+        {
+            "path": "^cxx/((Debug|Release|RelWithDebInfo|MinSizeRel)/)?cxx_standard_compile_feature_exe\\.pdb$",
+            "_dllExtra": true
+        }
+    ],
+    "build": "^cxx$",
+    "source": "^cxx$",
+    "install": null,
+    "link": {
+        "language": "CXX",
+        "lto": null,
+        "commandFragments": null
+    },
+    "archive": null,
+    "dependencies": [
+        {
+            "id": "^ZERO_CHECK::@a56b12a3f5c0529fb296$",
+            "backtrace": null
+        }
+    ]
+}
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_standard_compile_feature_exe_languagestandard.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_standard_compile_feature_exe_languagestandard.json
new file mode 100644
index 0000000..0c4eabb
--- /dev/null
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_standard_compile_feature_exe_languagestandard.json
@@ -0,0 +1,36 @@
+{
+    "languageStandard" :
+    {
+      "backtraces": [
+          [
+              {
+                  "file": "^cxx/CMakeLists\\.txt$",
+                  "line": 29,
+                  "command": "target_compile_features",
+                  "hasParent": true
+              },
+              {
+                  "file": "^cxx/CMakeLists\\.txt$",
+                  "line": null,
+                  "command": null,
+                  "hasParent": false
+              }
+          ],
+          [
+              {
+                  "file": "^cxx/CMakeLists\\.txt$",
+                  "line": 30,
+                  "command": "target_compile_features",
+                  "hasParent": true
+              },
+              {
+                  "file": "^cxx/CMakeLists\\.txt$",
+                  "line": null,
+                  "command": null,
+                  "hasParent": false
+              }
+          ]
+      ],
+      "standard" : "11"
+    }
+}
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_standard_exe.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_standard_exe.json
new file mode 100644
index 0000000..9cb2832
--- /dev/null
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_standard_exe.json
@@ -0,0 +1,110 @@
+{
+    "name": "cxx_standard_exe",
+    "id": "^cxx_standard_exe::@a56b12a3f5c0529fb296$",
+    "directorySource": "^cxx$",
+    "projectName": "Cxx",
+    "type": "EXECUTABLE",
+    "isGeneratorProvided": null,
+    "sources": [
+        {
+            "path": "^empty\\.cxx$",
+            "isGenerated": null,
+            "sourceGroupName": "Source Files",
+            "compileGroupLanguage": "CXX",
+            "backtrace": [
+                {
+                    "file": "^cxx/CMakeLists\\.txt$",
+                    "line": 23,
+                    "command": "add_executable",
+                    "hasParent": true
+                },
+                {
+                    "file": "^cxx/CMakeLists\\.txt$",
+                    "line": null,
+                    "command": null,
+                    "hasParent": false
+                }
+            ]
+        }
+    ],
+    "sourceGroups": [
+        {
+            "name": "Source Files",
+            "sourcePaths": [
+                "^empty\\.cxx$"
+            ]
+        }
+    ],
+    "compileGroups": [
+        {
+            "language": "CXX",
+            "languageStandard" :
+            {
+                "backtraces": [
+                    [
+                        {
+                            "file": "^cxx/CMakeLists\\.txt$",
+                            "line": 24,
+                            "command": "set_property",
+                            "hasParent": true
+                        },
+                        {
+                            "file": "^cxx/CMakeLists\\.txt$",
+                            "line": null,
+                            "command": null,
+                            "hasParent": false
+                        }
+                    ]
+                ],
+                "standard" : "17"
+            },
+            "sourcePaths": [
+                "^empty\\.cxx$"
+            ],
+            "includes": null,
+            "defines": null,
+            "compileCommandFragments": null
+        }
+    ],
+    "backtrace": [
+        {
+            "file": "^cxx/CMakeLists\\.txt$",
+            "line": 23,
+            "command": "add_executable",
+            "hasParent": true
+        },
+        {
+            "file": "^cxx/CMakeLists\\.txt$",
+            "line": null,
+            "command": null,
+            "hasParent": false
+        }
+    ],
+    "folder": null,
+    "nameOnDisk": "^cxx_standard_exe(\\.exe)?$",
+    "artifacts": [
+        {
+            "path": "^cxx/((Debug|Release|RelWithDebInfo|MinSizeRel)/)?cxx_standard_exe(\\.exe)?$",
+            "_dllExtra": false
+        },
+        {
+            "path": "^cxx/((Debug|Release|RelWithDebInfo|MinSizeRel)/)?cxx_standard_exe\\.pdb$",
+            "_dllExtra": true
+        }
+    ],
+    "build": "^cxx$",
+    "source": "^cxx$",
+    "install": null,
+    "link": {
+        "language": "CXX",
+        "lto": null,
+        "commandFragments": null
+    },
+    "archive": null,
+    "dependencies": [
+        {
+            "id": "^ZERO_CHECK::@a56b12a3f5c0529fb296$",
+            "backtrace": null
+        }
+    ]
+}
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_static_exe.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_static_exe.json
new file mode 100644
index 0000000..52c42de
--- /dev/null
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_static_exe.json
@@ -0,0 +1,107 @@
+{
+    "name": "cxx_static_exe",
+    "id": "^cxx_static_exe::@a56b12a3f5c0529fb296$",
+    "directorySource": "^cxx$",
+    "projectName": "Cxx",
+    "type": "EXECUTABLE",
+    "isGeneratorProvided": null,
+    "sources": [
+        {
+            "path": "^empty\\.cxx$",
+            "isGenerated": null,
+            "sourceGroupName": "Source Files",
+            "compileGroupLanguage": "CXX",
+            "backtrace": [
+                {
+                    "file": "^cxx/CMakeLists\\.txt$",
+                    "line": 14,
+                    "command": "add_executable",
+                    "hasParent": true
+                },
+                {
+                    "file": "^cxx/CMakeLists\\.txt$",
+                    "line": null,
+                    "command": null,
+                    "hasParent": false
+                }
+            ]
+        }
+    ],
+    "sourceGroups": [
+        {
+            "name": "Source Files",
+            "sourcePaths": [
+                "^empty\\.cxx$"
+            ]
+        }
+    ],
+    "compileGroups": [
+        {
+            "language": "CXX",
+            "sourcePaths": [
+                "^empty\\.cxx$"
+            ],
+            "includes": null,
+            "defines": null,
+            "compileCommandFragments": null
+        }
+    ],
+    "backtrace": [
+        {
+            "file": "^cxx/CMakeLists\\.txt$",
+            "line": 14,
+            "command": "add_executable",
+            "hasParent": true
+        },
+        {
+            "file": "^cxx/CMakeLists\\.txt$",
+            "line": null,
+            "command": null,
+            "hasParent": false
+        }
+    ],
+    "folder": null,
+    "nameOnDisk": "^cxx_static_exe(\\.exe)?$",
+    "artifacts": [
+        {
+            "path": "^cxx/((Debug|Release|RelWithDebInfo|MinSizeRel)/)?cxx_static_exe(\\.exe)?$",
+            "_dllExtra": false
+        },
+        {
+            "path": "^cxx/((Debug|Release|RelWithDebInfo|MinSizeRel)/)?cxx_static_exe\\.pdb$",
+            "_dllExtra": true
+        }
+    ],
+    "build": "^cxx$",
+    "source": "^cxx$",
+    "install": null,
+    "link": {
+        "language": "CXX",
+        "lto": null,
+        "commandFragments": null
+    },
+    "archive": null,
+    "dependencies": [
+        {
+            "id": "^cxx_static_lib::@a56b12a3f5c0529fb296$",
+            "backtrace": [
+                {
+                    "file": "^cxx/CMakeLists\\.txt$",
+                    "line": 15,
+                    "command": "target_link_libraries",
+                    "hasParent": true
+                },
+                {
+                    "file": "^cxx/CMakeLists\\.txt$",
+                    "line": null,
+                    "command": null,
+                    "hasParent": false
+                }
+            ]
+        },
+        {
+            "id": "^ZERO_CHECK::@a56b12a3f5c0529fb296$",
+            "backtrace": null
+        }
+    ]
+}
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_static_lib.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_static_lib.json
new file mode 100644
index 0000000..98298be
--- /dev/null
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_static_lib.json
@@ -0,0 +1,84 @@
+{
+    "name": "cxx_static_lib",
+    "id": "^cxx_static_lib::@a56b12a3f5c0529fb296$",
+    "directorySource": "^cxx$",
+    "projectName": "Cxx",
+    "type": "STATIC_LIBRARY",
+    "isGeneratorProvided": null,
+    "sources": [
+        {
+            "path": "^empty\\.cxx$",
+            "isGenerated": null,
+            "sourceGroupName": "Source Files",
+            "compileGroupLanguage": "CXX",
+            "backtrace": [
+                {
+                    "file": "^cxx/CMakeLists\\.txt$",
+                    "line": 13,
+                    "command": "add_library",
+                    "hasParent": true
+                },
+                {
+                    "file": "^cxx/CMakeLists\\.txt$",
+                    "line": null,
+                    "command": null,
+                    "hasParent": false
+                }
+            ]
+        }
+    ],
+    "sourceGroups": [
+        {
+            "name": "Source Files",
+            "sourcePaths": [
+                "^empty\\.cxx$"
+            ]
+        }
+    ],
+    "compileGroups": [
+        {
+            "language": "CXX",
+            "sourcePaths": [
+                "^empty\\.cxx$"
+            ],
+            "includes": null,
+            "defines": null,
+            "compileCommandFragments": null
+        }
+    ],
+    "backtrace": [
+        {
+            "file": "^cxx/CMakeLists\\.txt$",
+            "line": 13,
+            "command": "add_library",
+            "hasParent": true
+        },
+        {
+            "file": "^cxx/CMakeLists\\.txt$",
+            "line": null,
+            "command": null,
+            "hasParent": false
+        }
+    ],
+    "folder": null,
+    "nameOnDisk": "^(lib)?cxx_static_lib\\.(a|lib)$",
+    "artifacts": [
+        {
+            "path": "^cxx/((Debug|Release|RelWithDebInfo|MinSizeRel)/)?(lib)?cxx_static_lib\\.(a|lib)$",
+            "_dllExtra": false
+        }
+    ],
+    "build": "^cxx$",
+    "source": "^cxx$",
+    "install": null,
+    "link": null,
+    "archive": {
+        "lto": null
+    },
+    "dependencies": [
+        {
+            "id": "^ZERO_CHECK::@a56b12a3f5c0529fb296$",
+            "backtrace": null
+        }
+    ]
+}
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/generated_exe.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/generated_exe.json
new file mode 100644
index 0000000..d41bbb2
--- /dev/null
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/generated_exe.json
@@ -0,0 +1,303 @@
+{
+    "name": "generated_exe",
+    "id": "^generated_exe::@[0-9a-f]+$",
+    "directorySource": "^.*/Tests/RunCMake/FileAPIExternalSource$",
+    "projectName": "External",
+    "type": "EXECUTABLE",
+    "isGeneratorProvided": null,
+    "sources": [
+        {
+            "path": "^.*/Tests/RunCMake/FileAPIExternalSource/empty\\.c$",
+            "isGenerated": null,
+            "sourceGroupName": "Source Files",
+            "compileGroupLanguage": "C",
+            "backtrace": [
+                {
+                    "file": "^.*/Tests/RunCMake/FileAPIExternalSource/CMakeLists\\.txt$",
+                    "line": 5,
+                    "command": "add_executable",
+                    "hasParent": true
+                },
+                {
+                    "file": "^.*/Tests/RunCMake/FileAPIExternalSource/CMakeLists\\.txt$",
+                    "line": null,
+                    "command": null,
+                    "hasParent": false
+                }
+            ]
+        },
+        {
+            "path": "^.*/Tests/RunCMake/FileAPI/FileAPIExternalBuild/generated\\.cxx$",
+            "isGenerated": true,
+            "sourceGroupName": "Generated Source Files",
+            "compileGroupLanguage": "CXX",
+            "backtrace": [
+                {
+                    "file": "^.*/Tests/RunCMake/FileAPIExternalSource/CMakeLists\\.txt$",
+                    "line": 6,
+                    "command": "target_sources",
+                    "hasParent": true
+                },
+                {
+                    "file": "^.*/Tests/RunCMake/FileAPIExternalSource/CMakeLists\\.txt$",
+                    "line": null,
+                    "command": null,
+                    "hasParent": false
+                }
+            ]
+        }
+    ],
+    "sourceGroups": [
+        {
+            "name": "Source Files",
+            "sourcePaths": [
+                "^.*/Tests/RunCMake/FileAPIExternalSource/empty\\.c$"
+            ]
+        },
+        {
+            "name": "Generated Source Files",
+            "sourcePaths": [
+                "^.*/Tests/RunCMake/FileAPI/FileAPIExternalBuild/generated\\.cxx$"
+            ]
+        }
+    ],
+    "compileGroups": [
+        {
+            "language": "C",
+            "sourcePaths": [
+                "^.*/Tests/RunCMake/FileAPIExternalSource/empty\\.c$"
+            ],
+            "includes": [
+                {
+                    "path": "^.*/Tests/RunCMake/FileAPI/FileAPIExternalBuild$",
+                    "isSystem": null,
+                    "backtrace": [
+                        {
+                            "file": "^.*/Tests/RunCMake/FileAPIExternalSource/CMakeLists\\.txt$",
+                            "line": 10,
+                            "command": "set_property",
+                            "hasParent": true
+                        },
+                        {
+                            "file": "^.*/Tests/RunCMake/FileAPIExternalSource/CMakeLists\\.txt$",
+                            "line": null,
+                            "command": null,
+                            "hasParent": false
+                        }
+                    ]
+                },
+                {
+                    "path": "^.*/Tests/RunCMake/FileAPIExternalSource$",
+                    "isSystem": true,
+                    "backtrace": [
+                        {
+                            "file": "^.*/Tests/RunCMake/FileAPIExternalSource/CMakeLists\\.txt$",
+                            "line": 11,
+                            "command": "target_include_directories",
+                            "hasParent": true
+                        },
+                        {
+                            "file": "^.*/Tests/RunCMake/FileAPIExternalSource/CMakeLists\\.txt$",
+                            "line": null,
+                            "command": null,
+                            "hasParent": false
+                        }
+                    ]
+                }
+            ],
+            "defines": [
+                {
+                    "define": "EMPTY_C=1",
+                    "backtrace": [
+                        {
+                            "file": "^.*/Tests/RunCMake/FileAPIExternalSource/CMakeLists\\.txt$",
+                            "line": 9,
+                            "command": "set_property",
+                            "hasParent": true
+                        },
+                        {
+                            "file": "^.*/Tests/RunCMake/FileAPIExternalSource/CMakeLists\\.txt$",
+                            "line": null,
+                            "command": null,
+                            "hasParent": false
+                        }
+                    ]
+                },
+                {
+                    "define": "SRC_DUMMY",
+                    "backtrace": [
+                        {
+                            "file": "^.*/Tests/RunCMake/FileAPIExternalSource/CMakeLists\\.txt$",
+                            "line": 9,
+                            "command": "set_property",
+                            "hasParent": true
+                        },
+                        {
+                            "file": "^.*/Tests/RunCMake/FileAPIExternalSource/CMakeLists\\.txt$",
+                            "line": null,
+                            "command": null,
+                            "hasParent": false
+                        }
+                    ]
+                },
+                {
+                    "define": "GENERATED_EXE=1",
+                    "backtrace": [
+                        {
+                            "file": "^.*/Tests/RunCMake/FileAPIExternalSource/CMakeLists\\.txt$",
+                            "line": 12,
+                            "command": "target_compile_definitions",
+                            "hasParent": true
+                        },
+                        {
+                            "file": "^.*/Tests/RunCMake/FileAPIExternalSource/CMakeLists\\.txt$",
+                            "line": null,
+                            "command": null,
+                            "hasParent": false
+                        }
+                    ]
+                },
+                {
+                    "define": "TGT_DUMMY",
+                    "backtrace": [
+                        {
+                            "file": "^.*/Tests/RunCMake/FileAPIExternalSource/CMakeLists\\.txt$",
+                            "line": 12,
+                            "command": "target_compile_definitions",
+                            "hasParent": true
+                        },
+                        {
+                            "file": "^.*/Tests/RunCMake/FileAPIExternalSource/CMakeLists\\.txt$",
+                            "line": null,
+                            "command": null,
+                            "hasParent": false
+                        }
+                    ]
+                }
+            ],
+            "compileCommandFragments": [
+                {
+                    "fragment" : "SRC_COMPILE_OPTIONS_DUMMY",
+                    "backtrace": [
+                        {
+                            "file": "^.*/Tests/RunCMake/FileAPIExternalSource/CMakeLists\\.txt$",
+                            "line": 13,
+                            "command": "set_source_files_properties",
+                            "hasParent": true
+                        },
+                        {
+                            "file" : "^.*/Tests/RunCMake/FileAPIExternalSource/CMakeLists\\.txt$",
+                            "line": null,
+                            "command": null,
+                            "hasParent": false
+                        }
+                    ]
+                }
+            ]
+        },
+        {
+            "language": "CXX",
+            "sourcePaths": [
+                "^.*/Tests/RunCMake/FileAPI/FileAPIExternalBuild/generated\\.cxx$"
+            ],
+            "includes": [
+                {
+                    "path": "^.*/Tests/RunCMake/FileAPIExternalSource$",
+                    "isSystem": true,
+                    "backtrace": [
+                        {
+                            "file": "^.*/Tests/RunCMake/FileAPIExternalSource/CMakeLists\\.txt$",
+                            "line": 11,
+                            "command": "target_include_directories",
+                            "hasParent": true
+                        },
+                        {
+                            "file": "^.*/Tests/RunCMake/FileAPIExternalSource/CMakeLists\\.txt$",
+                            "line": null,
+                            "command": null,
+                            "hasParent": false
+                        }
+                    ]
+                }
+            ],
+            "defines": [
+                {
+                    "define": "GENERATED_EXE=1",
+                    "backtrace": [
+                        {
+                            "file": "^.*/Tests/RunCMake/FileAPIExternalSource/CMakeLists\\.txt$",
+                            "line": 12,
+                            "command": "target_compile_definitions",
+                            "hasParent": true
+                        },
+                        {
+                            "file": "^.*/Tests/RunCMake/FileAPIExternalSource/CMakeLists\\.txt$",
+                            "line": null,
+                            "command": null,
+                            "hasParent": false
+                        }
+                    ]
+                },
+                {
+                    "define": "TGT_DUMMY",
+                    "backtrace": [
+                        {
+                            "file": "^.*/Tests/RunCMake/FileAPIExternalSource/CMakeLists\\.txt$",
+                            "line": 12,
+                            "command": "target_compile_definitions",
+                            "hasParent": true
+                        },
+                        {
+                            "file": "^.*/Tests/RunCMake/FileAPIExternalSource/CMakeLists\\.txt$",
+                            "line": null,
+                            "command": null,
+                            "hasParent": false
+                        }
+                    ]
+                }
+            ],
+            "compileCommandFragments": null
+        }
+    ],
+    "backtrace": [
+        {
+            "file": "^.*/Tests/RunCMake/FileAPIExternalSource/CMakeLists\\.txt$",
+            "line": 5,
+            "command": "add_executable",
+            "hasParent": true
+        },
+        {
+            "file": "^.*/Tests/RunCMake/FileAPIExternalSource/CMakeLists\\.txt$",
+            "line": null,
+            "command": null,
+            "hasParent": false
+        }
+    ],
+    "folder": null,
+    "nameOnDisk": "^generated_exe(\\.exe)?$",
+    "artifacts": [
+        {
+            "path": "^.*/Tests/RunCMake/FileAPI/FileAPIExternalBuild/((Debug|Release|RelWithDebInfo|MinSizeRel)/)?generated_exe(\\.exe)?$",
+            "_dllExtra": false
+        },
+        {
+            "path": "^.*/Tests/RunCMake/FileAPI/FileAPIExternalBuild/((Debug|Release|RelWithDebInfo|MinSizeRel)/)?generated_exe\\.pdb$",
+            "_dllExtra": true
+        }
+    ],
+    "build": "^.*/Tests/RunCMake/FileAPI/FileAPIExternalBuild$",
+    "source": "^.*/Tests/RunCMake/FileAPIExternalSource$",
+    "install": null,
+    "link": {
+        "language": "CXX",
+        "lto": null,
+        "commandFragments": null
+    },
+    "archive": null,
+    "dependencies": [
+        {
+            "id": "^ZERO_CHECK::@[0-9a-f]+$",
+            "backtrace": null
+        }
+    ]
+}
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/iface_srcs.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/iface_srcs.json
new file mode 100644
index 0000000..97d7ccd
--- /dev/null
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/iface_srcs.json
@@ -0,0 +1,67 @@
+{
+    "name": "iface_srcs",
+    "id": "^iface_srcs::@25b7fa8ea00134654b85$",
+    "directorySource": "^interface$",
+    "projectName": "Interface",
+    "type": "INTERFACE_LIBRARY",
+    "isGeneratorProvided": null,
+    "sources": [
+        {
+            "path": "^empty\\.c$",
+            "isGenerated": null,
+            "sourceGroupName": "Source Files",
+            "compileGroupLanguage": null,
+            "backtrace": [
+                {
+                    "file": "^interface/CMakeLists\\.txt$",
+                    "line": 3,
+                    "command": "add_library",
+                    "hasParent": true
+                },
+                {
+                    "file": "^interface/CMakeLists\\.txt$",
+                    "line": null,
+                    "command": null,
+                    "hasParent": false
+                }
+            ]
+        }
+    ],
+    "sourceGroups": [
+        {
+            "name": "Source Files",
+            "sourcePaths": [
+                "^empty\\.c$"
+            ]
+        }
+    ],
+    "compileGroups": null,
+    "backtrace": [
+        {
+            "file": "^interface/CMakeLists\\.txt$",
+            "line": 3,
+            "command": "add_library",
+            "hasParent": true
+        },
+        {
+            "file": "^interface/CMakeLists\\.txt$",
+            "line": null,
+            "command": null,
+            "hasParent": false
+        }
+    ],
+    "folder": null,
+    "nameOnDisk": null,
+    "artifacts": null,
+    "build": "^interface$",
+    "source": "^interface$",
+    "install": null,
+    "link": null,
+    "archive": null,
+    "dependencies": [
+        {
+            "id": "^ZERO_CHECK::@25b7fa8ea00134654b85$",
+            "backtrace": null
+        }
+    ]
+}
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/interface_exe.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/interface_exe.json
new file mode 100644
index 0000000..fe0524c
--- /dev/null
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/interface_exe.json
@@ -0,0 +1,152 @@
+{
+    "name": "interface_exe",
+    "id": "^interface_exe::@6890427a1f51a3e7e1df$",
+    "directorySource": "^\\.$",
+    "projectName": "codemodel-v2",
+    "type": "EXECUTABLE",
+    "isGeneratorProvided": null,
+    "sources": [
+        {
+            "path": "^empty\\.c$",
+            "isGenerated": null,
+            "sourceGroupName": "Source Files",
+            "compileGroupLanguage": "C",
+            "backtrace": [
+                {
+                    "file": "^include_test\\.cmake$",
+                    "line": 3,
+                    "command": "add_executable",
+                    "hasParent": true
+                },
+                {
+                    "file": "^include_test\\.cmake$",
+                    "line": null,
+                    "command": null,
+                    "hasParent": true
+                },
+                {
+                    "file": "^codemodel-v2\\.cmake$",
+                    "line": 3,
+                    "command": "include",
+                    "hasParent": true
+                },
+                {
+                    "file": "^codemodel-v2\\.cmake$",
+                    "line": null,
+                    "command": null,
+                    "hasParent": true
+                },
+                {
+                    "file": "^CMakeLists\\.txt$",
+                    "line": 3,
+                    "command": "include",
+                    "hasParent": true
+                },
+                {
+                    "file": "^CMakeLists\\.txt$",
+                    "line": null,
+                    "command": null,
+                    "hasParent": false
+                }
+            ]
+        }
+    ],
+    "sourceGroups": [
+        {
+            "name": "Source Files",
+            "sourcePaths": [
+                "^empty\\.c$"
+            ]
+        }
+    ],
+    "compileGroups": [
+        {
+            "language": "C",
+            "sourcePaths": [
+                "^empty\\.c$"
+            ],
+            "includes": null,
+            "defines": [
+                {
+                    "define": "interface_exe_EXPORTS",
+                    "backtrace": null
+                }
+            ],
+            "compileCommandFragments": null
+        }
+    ],
+    "backtrace": [
+        {
+            "file": "^include_test\\.cmake$",
+            "line": 3,
+            "command": "add_executable",
+            "hasParent": true
+        },
+        {
+            "file": "^include_test\\.cmake$",
+            "line": null,
+            "command": null,
+            "hasParent": true
+        },
+        {
+            "file": "^codemodel-v2\\.cmake$",
+            "line": 3,
+            "command": "include",
+            "hasParent": true
+        },
+        {
+            "file": "^codemodel-v2\\.cmake$",
+            "line": null,
+            "command": null,
+            "hasParent": true
+        },
+        {
+            "file": "^CMakeLists\\.txt$",
+            "line": 3,
+            "command": "include",
+            "hasParent": true
+        },
+        {
+            "file": "^CMakeLists\\.txt$",
+            "line": null,
+            "command": null,
+            "hasParent": false
+        }
+    ],
+    "folder": null,
+    "nameOnDisk": "^my_interface_exe\\.myexe$",
+    "artifacts": [
+        {
+            "path": "^bin/((Debug|Release|RelWithDebInfo|MinSizeRel)/)?my_interface_exe\\.myexe$",
+            "_dllExtra": false
+        },
+        {
+            "path": "^lib/my_interface_exe\\.imp$",
+            "_aixExtra": true,
+            "_dllExtra": false
+        },
+        {
+            "path": "^lib/((Debug|Release|RelWithDebInfo|MinSizeRel)/)?(lib)?my_interface_exe\\.(dll\\.a|lib)$",
+            "_dllExtra": true
+        },
+        {
+            "path": "^bin/((Debug|Release|RelWithDebInfo|MinSizeRel)/)?my_interface_exe\\.pdb$",
+            "_dllExtra": true
+        }
+    ],
+    "build": "^\\.$",
+    "source": "^\\.$",
+    "install": null,
+    "link": {
+        "language": "C",
+        "lto": null,
+        "commandFragments": null
+    },
+    "archive": null,
+    "dependencies": [
+        {
+            "id": "^ZERO_CHECK::@6890427a1f51a3e7e1df$",
+            "backtrace": null
+        }
+    ]
+}
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/link_imported_exe.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/link_imported_exe.json
new file mode 100644
index 0000000..312f4c5
--- /dev/null
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/link_imported_exe.json
@@ -0,0 +1,90 @@
+{
+    "name": "link_imported_exe",
+    "id": "^link_imported_exe::@ba7eb709d0b48779c6c8$",
+    "directorySource": "^imported$",
+    "projectName": "Imported",
+    "type": "EXECUTABLE",
+    "isGeneratorProvided": null,
+    "sources": [
+        {
+            "path": "^empty\\.c$",
+            "isGenerated": null,
+            "sourceGroupName": "Source Files",
+            "compileGroupLanguage": "C",
+            "backtrace": [
+                {
+                    "file": "^imported/CMakeLists\\.txt$",
+                    "line": 5,
+                    "command": "add_executable",
+                    "hasParent": true
+                },
+                {
+                    "file": "^imported/CMakeLists\\.txt$",
+                    "line": null,
+                    "command": null,
+                    "hasParent": false
+                }
+            ]
+        }
+    ],
+    "sourceGroups": [
+        {
+            "name": "Source Files",
+            "sourcePaths": [
+                "^empty\\.c$"
+            ]
+        }
+    ],
+    "compileGroups": [
+        {
+            "language": "C",
+            "sourcePaths": [
+                "^empty\\.c$"
+            ],
+            "includes": null,
+            "defines": null,
+            "compileCommandFragments": null
+        }
+    ],
+    "backtrace": [
+        {
+            "file": "^imported/CMakeLists\\.txt$",
+            "line": 5,
+            "command": "add_executable",
+            "hasParent": true
+        },
+        {
+            "file": "^imported/CMakeLists\\.txt$",
+            "line": null,
+            "command": null,
+            "hasParent": false
+        }
+    ],
+    "folder": null,
+    "nameOnDisk": "^link_imported_exe(\\.exe)?$",
+    "artifacts": [
+        {
+            "path": "^imported/((Debug|Release|RelWithDebInfo|MinSizeRel)/)?link_imported_exe(\\.exe)?$",
+            "_dllExtra": false
+        },
+        {
+            "path": "^imported/((Debug|Release|RelWithDebInfo|MinSizeRel)/)?link_imported_exe\\.pdb$",
+            "_dllExtra": true
+        }
+    ],
+    "build": "^imported$",
+    "source": "^imported$",
+    "install": null,
+    "link": {
+        "language": "C",
+        "lto": null,
+        "commandFragments": null
+    },
+    "archive": null,
+    "dependencies": [
+        {
+            "id": "^ZERO_CHECK::@ba7eb709d0b48779c6c8$",
+            "backtrace": null
+        }
+    ]
+}
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/link_imported_interface_exe.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/link_imported_interface_exe.json
new file mode 100644
index 0000000..7d0e6df
--- /dev/null
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/link_imported_interface_exe.json
@@ -0,0 +1,90 @@
+{
+    "name": "link_imported_interface_exe",
+    "id": "^link_imported_interface_exe::@ba7eb709d0b48779c6c8$",
+    "directorySource": "^imported$",
+    "projectName": "Imported",
+    "type": "EXECUTABLE",
+    "isGeneratorProvided": null,
+    "sources": [
+        {
+            "path": "^empty\\.c$",
+            "isGenerated": null,
+            "sourceGroupName": "Source Files",
+            "compileGroupLanguage": "C",
+            "backtrace": [
+                {
+                    "file": "^imported/CMakeLists\\.txt$",
+                    "line": 23,
+                    "command": "add_executable",
+                    "hasParent": true
+                },
+                {
+                    "file": "^imported/CMakeLists\\.txt$",
+                    "line": null,
+                    "command": null,
+                    "hasParent": false
+                }
+            ]
+        }
+    ],
+    "sourceGroups": [
+        {
+            "name": "Source Files",
+            "sourcePaths": [
+                "^empty\\.c$"
+            ]
+        }
+    ],
+    "compileGroups": [
+        {
+            "language": "C",
+            "sourcePaths": [
+                "^empty\\.c$"
+            ],
+            "includes": null,
+            "defines": null,
+            "compileCommandFragments": null
+        }
+    ],
+    "backtrace": [
+        {
+            "file": "^imported/CMakeLists\\.txt$",
+            "line": 23,
+            "command": "add_executable",
+            "hasParent": true
+        },
+        {
+            "file": "^imported/CMakeLists\\.txt$",
+            "line": null,
+            "command": null,
+            "hasParent": false
+        }
+    ],
+    "folder": null,
+    "nameOnDisk": "^link_imported_interface_exe(\\.exe)?$",
+    "artifacts": [
+        {
+            "path": "^imported/((Debug|Release|RelWithDebInfo|MinSizeRel)/)?link_imported_interface_exe(\\.exe)?$",
+            "_dllExtra": false
+        },
+        {
+            "path": "^imported/((Debug|Release|RelWithDebInfo|MinSizeRel)/)?link_imported_interface_exe\\.pdb$",
+            "_dllExtra": true
+        }
+    ],
+    "build": "^imported$",
+    "source": "^imported$",
+    "install": null,
+    "link": {
+        "language": "C",
+        "lto": null,
+        "commandFragments": null
+    },
+    "archive": null,
+    "dependencies": [
+        {
+            "id": "^ZERO_CHECK::@ba7eb709d0b48779c6c8$",
+            "backtrace": null
+        }
+    ]
+}
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/link_imported_object_exe.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/link_imported_object_exe.json
new file mode 100644
index 0000000..4aec524
--- /dev/null
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/link_imported_object_exe.json
@@ -0,0 +1,90 @@
+{
+    "name": "link_imported_object_exe",
+    "id": "^link_imported_object_exe::@ba7eb709d0b48779c6c8$",
+    "directorySource": "^imported$",
+    "projectName": "Imported",
+    "type": "EXECUTABLE",
+    "isGeneratorProvided": null,
+    "sources": [
+        {
+            "path": "^empty\\.c$",
+            "isGenerated": null,
+            "sourceGroupName": "Source Files",
+            "compileGroupLanguage": "C",
+            "backtrace": [
+                {
+                    "file": "^imported/CMakeLists\\.txt$",
+                    "line": 18,
+                    "command": "add_executable",
+                    "hasParent": true
+                },
+                {
+                    "file": "^imported/CMakeLists\\.txt$",
+                    "line": null,
+                    "command": null,
+                    "hasParent": false
+                }
+            ]
+        }
+    ],
+    "sourceGroups": [
+        {
+            "name": "Source Files",
+            "sourcePaths": [
+                "^empty\\.c$"
+            ]
+        }
+    ],
+    "compileGroups": [
+        {
+            "language": "C",
+            "sourcePaths": [
+                "^empty\\.c$"
+            ],
+            "includes": null,
+            "defines": null,
+            "compileCommandFragments": null
+        }
+    ],
+    "backtrace": [
+        {
+            "file": "^imported/CMakeLists\\.txt$",
+            "line": 18,
+            "command": "add_executable",
+            "hasParent": true
+        },
+        {
+            "file": "^imported/CMakeLists\\.txt$",
+            "line": null,
+            "command": null,
+            "hasParent": false
+        }
+    ],
+    "folder": null,
+    "nameOnDisk": "^link_imported_object_exe(\\.exe)?$",
+    "artifacts": [
+        {
+            "path": "^imported/((Debug|Release|RelWithDebInfo|MinSizeRel)/)?link_imported_object_exe(\\.exe)?$",
+            "_dllExtra": false
+        },
+        {
+            "path": "^imported/((Debug|Release|RelWithDebInfo|MinSizeRel)/)?link_imported_object_exe\\.pdb$",
+            "_dllExtra": true
+        }
+    ],
+    "build": "^imported$",
+    "source": "^imported$",
+    "install": null,
+    "link": {
+        "language": "C",
+        "lto": null,
+        "commandFragments": null
+    },
+    "archive": null,
+    "dependencies": [
+        {
+            "id": "^ZERO_CHECK::@ba7eb709d0b48779c6c8$",
+            "backtrace": null
+        }
+    ]
+}
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/link_imported_shared_exe.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/link_imported_shared_exe.json
new file mode 100644
index 0000000..f5846ec
--- /dev/null
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/link_imported_shared_exe.json
@@ -0,0 +1,90 @@
+{
+    "name": "link_imported_shared_exe",
+    "id": "^link_imported_shared_exe::@ba7eb709d0b48779c6c8$",
+    "directorySource": "^imported$",
+    "projectName": "Imported",
+    "type": "EXECUTABLE",
+    "isGeneratorProvided": null,
+    "sources": [
+        {
+            "path": "^empty\\.c$",
+            "isGenerated": null,
+            "sourceGroupName": "Source Files",
+            "compileGroupLanguage": "C",
+            "backtrace": [
+                {
+                    "file": "^imported/CMakeLists\\.txt$",
+                    "line": 9,
+                    "command": "add_executable",
+                    "hasParent": true
+                },
+                {
+                    "file": "^imported/CMakeLists\\.txt$",
+                    "line": null,
+                    "command": null,
+                    "hasParent": false
+                }
+            ]
+        }
+    ],
+    "sourceGroups": [
+        {
+            "name": "Source Files",
+            "sourcePaths": [
+                "^empty\\.c$"
+            ]
+        }
+    ],
+    "compileGroups": [
+        {
+            "language": "C",
+            "sourcePaths": [
+                "^empty\\.c$"
+            ],
+            "includes": null,
+            "defines": null,
+            "compileCommandFragments": null
+        }
+    ],
+    "backtrace": [
+        {
+            "file": "^imported/CMakeLists\\.txt$",
+            "line": 9,
+            "command": "add_executable",
+            "hasParent": true
+        },
+        {
+            "file": "^imported/CMakeLists\\.txt$",
+            "line": null,
+            "command": null,
+            "hasParent": false
+        }
+    ],
+    "folder": null,
+    "nameOnDisk": "^link_imported_shared_exe(\\.exe)?$",
+    "artifacts": [
+        {
+            "path": "^imported/((Debug|Release|RelWithDebInfo|MinSizeRel)/)?link_imported_shared_exe(\\.exe)?$",
+            "_dllExtra": false
+        },
+        {
+            "path": "^imported/((Debug|Release|RelWithDebInfo|MinSizeRel)/)?link_imported_shared_exe\\.pdb$",
+            "_dllExtra": true
+        }
+    ],
+    "build": "^imported$",
+    "source": "^imported$",
+    "install": null,
+    "link": {
+        "language": "C",
+        "lto": null,
+        "commandFragments": null
+    },
+    "archive": null,
+    "dependencies": [
+        {
+            "id": "^ZERO_CHECK::@ba7eb709d0b48779c6c8$",
+            "backtrace": null
+        }
+    ]
+}
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/link_imported_static_exe.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/link_imported_static_exe.json
new file mode 100644
index 0000000..29a1695
--- /dev/null
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/link_imported_static_exe.json
@@ -0,0 +1,90 @@
+{
+    "name": "link_imported_static_exe",
+    "id": "^link_imported_static_exe::@ba7eb709d0b48779c6c8$",
+    "directorySource": "^imported$",
+    "projectName": "Imported",
+    "type": "EXECUTABLE",
+    "isGeneratorProvided": null,
+    "sources": [
+        {
+            "path": "^empty\\.c$",
+            "isGenerated": null,
+            "sourceGroupName": "Source Files",
+            "compileGroupLanguage": "C",
+            "backtrace": [
+                {
+                    "file": "^imported/CMakeLists\\.txt$",
+                    "line": 13,
+                    "command": "add_executable",
+                    "hasParent": true
+                },
+                {
+                    "file": "^imported/CMakeLists\\.txt$",
+                    "line": null,
+                    "command": null,
+                    "hasParent": false
+                }
+            ]
+        }
+    ],
+    "sourceGroups": [
+        {
+            "name": "Source Files",
+            "sourcePaths": [
+                "^empty\\.c$"
+            ]
+        }
+    ],
+    "compileGroups": [
+        {
+            "language": "C",
+            "sourcePaths": [
+                "^empty\\.c$"
+            ],
+            "includes": null,
+            "defines": null,
+            "compileCommandFragments": null
+        }
+    ],
+    "backtrace": [
+        {
+            "file": "^imported/CMakeLists\\.txt$",
+            "line": 13,
+            "command": "add_executable",
+            "hasParent": true
+        },
+        {
+            "file": "^imported/CMakeLists\\.txt$",
+            "line": null,
+            "command": null,
+            "hasParent": false
+        }
+    ],
+    "folder": null,
+    "nameOnDisk": "^link_imported_static_exe(\\.exe)?$",
+    "artifacts": [
+        {
+            "path": "^imported/((Debug|Release|RelWithDebInfo|MinSizeRel)/)?link_imported_static_exe(\\.exe)?$",
+            "_dllExtra": false
+        },
+        {
+            "path": "^imported/((Debug|Release|RelWithDebInfo|MinSizeRel)/)?link_imported_static_exe\\.pdb$",
+            "_dllExtra": true
+        }
+    ],
+    "build": "^imported$",
+    "source": "^imported$",
+    "install": null,
+    "link": {
+        "language": "C",
+        "lto": null,
+        "commandFragments": null
+    },
+    "archive": null,
+    "dependencies": [
+        {
+            "id": "^ZERO_CHECK::@ba7eb709d0b48779c6c8$",
+            "backtrace": null
+        }
+    ]
+}
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/zero_check_alias.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/zero_check_alias.json
new file mode 100644
index 0000000..941c172
--- /dev/null
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/zero_check_alias.json
@@ -0,0 +1,70 @@
+{
+    "name": "ZERO_CHECK",
+    "id": "^ZERO_CHECK::@53632cba2752272bb008$",
+    "directorySource": "^alias$",
+    "projectName": "Alias",
+    "type": "UTILITY",
+    "isGeneratorProvided": true,
+    "sources": [
+        {
+            "path": "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/alias/CMakeFiles/ZERO_CHECK$",
+            "isGenerated": true,
+            "sourceGroupName": "",
+            "compileGroupLanguage": null,
+            "backtrace": [
+                {
+                    "file": "^alias/CMakeLists\\.txt$",
+                    "line": null,
+                    "command": null,
+                    "hasParent": false
+                }
+            ]
+        },
+        {
+            "path": "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/alias/CMakeFiles/ZERO_CHECK\\.rule$",
+            "isGenerated": true,
+            "sourceGroupName": "CMake Rules",
+            "compileGroupLanguage": null,
+            "backtrace": [
+                {
+                    "file": "^alias/CMakeLists\\.txt$",
+                    "line": null,
+                    "command": null,
+                    "hasParent": false
+                }
+            ]
+        }
+    ],
+    "sourceGroups": [
+        {
+            "name": "",
+            "sourcePaths": [
+                "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/alias/CMakeFiles/ZERO_CHECK$"
+            ]
+        },
+        {
+            "name": "CMake Rules",
+            "sourcePaths": [
+                "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/alias/CMakeFiles/ZERO_CHECK\\.rule$"
+            ]
+        }
+    ],
+    "compileGroups": null,
+    "backtrace": [
+        {
+            "file": "^alias/CMakeLists\\.txt$",
+            "line": null,
+            "command": null,
+            "hasParent": false
+        }
+    ],
+    "folder": null,
+    "nameOnDisk": null,
+    "artifacts": null,
+    "build": "^alias$",
+    "source": "^alias$",
+    "install": null,
+    "link": null,
+    "archive": null,
+    "dependencies": null
+}
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/zero_check_custom.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/zero_check_custom.json
new file mode 100644
index 0000000..98c6dd9
--- /dev/null
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/zero_check_custom.json
@@ -0,0 +1,70 @@
+{
+    "name": "ZERO_CHECK",
+    "id": "^ZERO_CHECK::@c11385ffed57b860da63$",
+    "directorySource": "^custom$",
+    "projectName": "Custom",
+    "type": "UTILITY",
+    "isGeneratorProvided": true,
+    "sources": [
+        {
+            "path": "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/custom/CMakeFiles/ZERO_CHECK$",
+            "isGenerated": true,
+            "sourceGroupName": "",
+            "compileGroupLanguage": null,
+            "backtrace": [
+                {
+                    "file": "^custom/CMakeLists\\.txt$",
+                    "line": null,
+                    "command": null,
+                    "hasParent": false
+                }
+            ]
+        },
+        {
+            "path": "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/custom/CMakeFiles/ZERO_CHECK\\.rule$",
+            "isGenerated": true,
+            "sourceGroupName": "CMake Rules",
+            "compileGroupLanguage": null,
+            "backtrace": [
+                {
+                    "file": "^custom/CMakeLists\\.txt$",
+                    "line": null,
+                    "command": null,
+                    "hasParent": false
+                }
+            ]
+        }
+    ],
+    "sourceGroups": [
+        {
+            "name": "",
+            "sourcePaths": [
+                "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/custom/CMakeFiles/ZERO_CHECK$"
+            ]
+        },
+        {
+            "name": "CMake Rules",
+            "sourcePaths": [
+                "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/custom/CMakeFiles/ZERO_CHECK\\.rule$"
+            ]
+        }
+    ],
+    "compileGroups": null,
+    "backtrace": [
+        {
+            "file": "^custom/CMakeLists\\.txt$",
+            "line": null,
+            "command": null,
+            "hasParent": false
+        }
+    ],
+    "folder": null,
+    "nameOnDisk": null,
+    "artifacts": null,
+    "build": "^custom$",
+    "source": "^custom$",
+    "install": null,
+    "link": null,
+    "archive": null,
+    "dependencies": null
+}
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/zero_check_cxx.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/zero_check_cxx.json
new file mode 100644
index 0000000..b72ff82
--- /dev/null
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/zero_check_cxx.json
@@ -0,0 +1,70 @@
+{
+    "name": "ZERO_CHECK",
+    "id": "^ZERO_CHECK::@a56b12a3f5c0529fb296$",
+    "directorySource": "^cxx$",
+    "projectName": "Cxx",
+    "type": "UTILITY",
+    "isGeneratorProvided": true,
+    "sources": [
+        {
+            "path": "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/cxx/CMakeFiles/ZERO_CHECK$",
+            "isGenerated": true,
+            "sourceGroupName": "",
+            "compileGroupLanguage": null,
+            "backtrace": [
+                {
+                    "file": "^cxx/CMakeLists\\.txt$",
+                    "line": null,
+                    "command": null,
+                    "hasParent": false
+                }
+            ]
+        },
+        {
+            "path": "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/cxx/CMakeFiles/ZERO_CHECK\\.rule$",
+            "isGenerated": true,
+            "sourceGroupName": "CMake Rules",
+            "compileGroupLanguage": null,
+            "backtrace": [
+                {
+                    "file": "^cxx/CMakeLists\\.txt$",
+                    "line": null,
+                    "command": null,
+                    "hasParent": false
+                }
+            ]
+        }
+    ],
+    "sourceGroups": [
+        {
+            "name": "",
+            "sourcePaths": [
+                "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/cxx/CMakeFiles/ZERO_CHECK$"
+            ]
+        },
+        {
+            "name": "CMake Rules",
+            "sourcePaths": [
+                "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/cxx/CMakeFiles/ZERO_CHECK\\.rule$"
+            ]
+        }
+    ],
+    "compileGroups": null,
+    "backtrace": [
+        {
+            "file": "^cxx/CMakeLists\\.txt$",
+            "line": null,
+            "command": null,
+            "hasParent": false
+        }
+    ],
+    "folder": null,
+    "nameOnDisk": null,
+    "artifacts": null,
+    "build": "^cxx$",
+    "source": "^cxx$",
+    "install": null,
+    "link": null,
+    "archive": null,
+    "dependencies": null
+}
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/zero_check_external.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/zero_check_external.json
new file mode 100644
index 0000000..9e73806
--- /dev/null
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/zero_check_external.json
@@ -0,0 +1,70 @@
+{
+    "name": "ZERO_CHECK",
+    "id": "^ZERO_CHECK::@[0-9a-f]+$",
+    "directorySource": "^.*/Tests/RunCMake/FileAPIExternalSource$",
+    "projectName": "External",
+    "type": "UTILITY",
+    "isGeneratorProvided": true,
+    "sources": [
+        {
+            "path": "^.*/Tests/RunCMake/FileAPI/FileAPIExternalBuild/CMakeFiles/ZERO_CHECK$",
+            "isGenerated": true,
+            "sourceGroupName": "",
+            "compileGroupLanguage": null,
+            "backtrace": [
+                {
+                    "file": "^.*/Tests/RunCMake/FileAPIExternalSource/CMakeLists\\.txt$",
+                    "line": null,
+                    "command": null,
+                    "hasParent": false
+                }
+            ]
+        },
+        {
+            "path": "^.*/Tests/RunCMake/FileAPI/FileAPIExternalBuild/CMakeFiles/ZERO_CHECK\\.rule$",
+            "isGenerated": true,
+            "sourceGroupName": "CMake Rules",
+            "compileGroupLanguage": null,
+            "backtrace": [
+                {
+                    "file": "^.*/Tests/RunCMake/FileAPIExternalSource/CMakeLists\\.txt$",
+                    "line": null,
+                    "command": null,
+                    "hasParent": false
+                }
+            ]
+        }
+    ],
+    "sourceGroups": [
+        {
+            "name": "",
+            "sourcePaths": [
+                "^.*/Tests/RunCMake/FileAPI/FileAPIExternalBuild/CMakeFiles/ZERO_CHECK$"
+            ]
+        },
+        {
+            "name": "CMake Rules",
+            "sourcePaths": [
+                "^.*/Tests/RunCMake/FileAPI/FileAPIExternalBuild/CMakeFiles/ZERO_CHECK\\.rule$"
+            ]
+        }
+    ],
+    "compileGroups": null,
+    "backtrace": [
+        {
+            "file": "^.*/Tests/RunCMake/FileAPIExternalSource/CMakeLists\\.txt$",
+            "line": null,
+            "command": null,
+            "hasParent": false
+        }
+    ],
+    "folder": null,
+    "nameOnDisk": null,
+    "artifacts": null,
+    "build": "^.*/Tests/RunCMake/FileAPI/FileAPIExternalBuild$",
+    "source": "^.*/Tests/RunCMake/FileAPIExternalSource$",
+    "install": null,
+    "link": null,
+    "archive": null,
+    "dependencies": null
+}
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/zero_check_imported.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/zero_check_imported.json
new file mode 100644
index 0000000..7534c84
--- /dev/null
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/zero_check_imported.json
@@ -0,0 +1,70 @@
+{
+    "name": "ZERO_CHECK",
+    "id": "^ZERO_CHECK::@ba7eb709d0b48779c6c8$",
+    "directorySource": "^imported$",
+    "projectName": "Imported",
+    "type": "UTILITY",
+    "isGeneratorProvided": true,
+    "sources": [
+        {
+            "path": "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/imported/CMakeFiles/ZERO_CHECK$",
+            "isGenerated": true,
+            "sourceGroupName": "",
+            "compileGroupLanguage": null,
+            "backtrace": [
+                {
+                    "file": "^imported/CMakeLists\\.txt$",
+                    "line": null,
+                    "command": null,
+                    "hasParent": false
+                }
+            ]
+        },
+        {
+            "path": "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/imported/CMakeFiles/ZERO_CHECK\\.rule$",
+            "isGenerated": true,
+            "sourceGroupName": "CMake Rules",
+            "compileGroupLanguage": null,
+            "backtrace": [
+                {
+                    "file": "^imported/CMakeLists\\.txt$",
+                    "line": null,
+                    "command": null,
+                    "hasParent": false
+                }
+            ]
+        }
+    ],
+    "sourceGroups": [
+        {
+            "name": "",
+            "sourcePaths": [
+                "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/imported/CMakeFiles/ZERO_CHECK$"
+            ]
+        },
+        {
+            "name": "CMake Rules",
+            "sourcePaths": [
+                "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/imported/CMakeFiles/ZERO_CHECK\\.rule$"
+            ]
+        }
+    ],
+    "compileGroups": null,
+    "backtrace": [
+        {
+            "file": "^imported/CMakeLists\\.txt$",
+            "line": null,
+            "command": null,
+            "hasParent": false
+        }
+    ],
+    "folder": null,
+    "nameOnDisk": null,
+    "artifacts": null,
+    "build": "^imported$",
+    "source": "^imported$",
+    "install": null,
+    "link": null,
+    "archive": null,
+    "dependencies": null
+}
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/zero_check_interface.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/zero_check_interface.json
new file mode 100644
index 0000000..fdd4b2a
--- /dev/null
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/zero_check_interface.json
@@ -0,0 +1,70 @@
+{
+    "name": "ZERO_CHECK",
+    "id": "^ZERO_CHECK::@25b7fa8ea00134654b85$",
+    "directorySource": "^interface$",
+    "projectName": "Interface",
+    "type": "UTILITY",
+    "isGeneratorProvided": true,
+    "sources": [
+        {
+            "path": "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/interface/CMakeFiles/ZERO_CHECK$",
+            "isGenerated": true,
+            "sourceGroupName": "",
+            "compileGroupLanguage": null,
+            "backtrace": [
+                {
+                    "file": "^interface/CMakeLists\\.txt$",
+                    "line": null,
+                    "command": null,
+                    "hasParent": false
+                }
+            ]
+        },
+        {
+            "path": "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/interface/CMakeFiles/ZERO_CHECK\\.rule$",
+            "isGenerated": true,
+            "sourceGroupName": "CMake Rules",
+            "compileGroupLanguage": null,
+            "backtrace": [
+                {
+                    "file": "^interface/CMakeLists\\.txt$",
+                    "line": null,
+                    "command": null,
+                    "hasParent": false
+                }
+            ]
+        }
+    ],
+    "sourceGroups": [
+        {
+            "name": "",
+            "sourcePaths": [
+                "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/interface/CMakeFiles/ZERO_CHECK$"
+            ]
+        },
+        {
+            "name": "CMake Rules",
+            "sourcePaths": [
+                "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/interface/CMakeFiles/ZERO_CHECK\\.rule$"
+            ]
+        }
+    ],
+    "compileGroups": null,
+    "backtrace": [
+        {
+            "file": "^interface/CMakeLists\\.txt$",
+            "line": null,
+            "command": null,
+            "hasParent": false
+        }
+    ],
+    "folder": null,
+    "nameOnDisk": null,
+    "artifacts": null,
+    "build": "^interface$",
+    "source": "^interface$",
+    "install": null,
+    "link": null,
+    "archive": null,
+    "dependencies": null
+}
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/zero_check_object.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/zero_check_object.json
new file mode 100644
index 0000000..bcd7616
--- /dev/null
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/zero_check_object.json
@@ -0,0 +1,70 @@
+{
+    "name": "ZERO_CHECK",
+    "id": "^ZERO_CHECK::@5ed5358f70faf8d8af7a$",
+    "directorySource": "^object$",
+    "projectName": "Object",
+    "type": "UTILITY",
+    "isGeneratorProvided": true,
+    "sources": [
+        {
+            "path": "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/object/CMakeFiles/ZERO_CHECK$",
+            "isGenerated": true,
+            "sourceGroupName": "",
+            "compileGroupLanguage": null,
+            "backtrace": [
+                {
+                    "file": "^object/CMakeLists\\.txt$",
+                    "line": null,
+                    "command": null,
+                    "hasParent": false
+                }
+            ]
+        },
+        {
+            "path": "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/object/CMakeFiles/ZERO_CHECK\\.rule$",
+            "isGenerated": true,
+            "sourceGroupName": "CMake Rules",
+            "compileGroupLanguage": null,
+            "backtrace": [
+                {
+                    "file": "^object/CMakeLists\\.txt$",
+                    "line": null,
+                    "command": null,
+                    "hasParent": false
+                }
+            ]
+        }
+    ],
+    "sourceGroups": [
+        {
+            "name": "",
+            "sourcePaths": [
+                "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/object/CMakeFiles/ZERO_CHECK$"
+            ]
+        },
+        {
+            "name": "CMake Rules",
+            "sourcePaths": [
+                "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/object/CMakeFiles/ZERO_CHECK\\.rule$"
+            ]
+        }
+    ],
+    "compileGroups": null,
+    "backtrace": [
+        {
+            "file": "^object/CMakeLists\\.txt$",
+            "line": null,
+            "command": null,
+            "hasParent": false
+        }
+    ],
+    "folder": null,
+    "nameOnDisk": null,
+    "artifacts": null,
+    "build": "^object$",
+    "source": "^object$",
+    "install": null,
+    "link": null,
+    "archive": null,
+    "dependencies": null
+}
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/zero_check_top.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/zero_check_top.json
new file mode 100644
index 0000000..b3030bd
--- /dev/null
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/zero_check_top.json
@@ -0,0 +1,70 @@
+{
+    "name": "ZERO_CHECK",
+    "id": "^ZERO_CHECK::@6890427a1f51a3e7e1df$",
+    "directorySource": "^\\.$",
+    "projectName": "codemodel-v2",
+    "type": "UTILITY",
+    "isGeneratorProvided": true,
+    "sources": [
+        {
+            "path": "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/CMakeFiles/ZERO_CHECK$",
+            "isGenerated": true,
+            "sourceGroupName": "",
+            "compileGroupLanguage": null,
+            "backtrace": [
+                {
+                    "file": "^CMakeLists\\.txt$",
+                    "line": null,
+                    "command": null,
+                    "hasParent": false
+                }
+            ]
+        },
+        {
+            "path": "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/CMakeFiles/ZERO_CHECK\\.rule$",
+            "isGenerated": true,
+            "sourceGroupName": "CMake Rules",
+            "compileGroupLanguage": null,
+            "backtrace": [
+                {
+                    "file": "^CMakeLists\\.txt$",
+                    "line": null,
+                    "command": null,
+                    "hasParent": false
+                }
+            ]
+        }
+    ],
+    "sourceGroups": [
+        {
+            "name": "",
+            "sourcePaths": [
+                "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/CMakeFiles/ZERO_CHECK$"
+            ]
+        },
+        {
+            "name": "CMake Rules",
+            "sourcePaths": [
+                "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/CMakeFiles/ZERO_CHECK\\.rule$"
+            ]
+        }
+    ],
+    "compileGroups": null,
+    "backtrace": [
+        {
+            "file": "^CMakeLists\\.txt$",
+            "line": null,
+            "command": null,
+            "hasParent": false
+        }
+    ],
+    "folder": null,
+    "nameOnDisk": null,
+    "artifacts": null,
+    "build": "^\\.$",
+    "source": "^\\.$",
+    "install": null,
+    "link": null,
+    "archive": null,
+    "dependencies": null
+}
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2.cmake b/Tests/RunCMake/FileAPI/codemodel-v2.cmake
index c98a84c..2405954 100644
--- a/Tests/RunCMake/FileAPI/codemodel-v2.cmake
+++ b/Tests/RunCMake/FileAPI/codemodel-v2.cmake
@@ -18,6 +18,7 @@
 add_subdirectory(alias)
 add_subdirectory(object)
 add_subdirectory(imported)
+add_subdirectory(interface)
 add_subdirectory(custom)
 add_subdirectory("${CMAKE_CURRENT_SOURCE_DIR}/../FileAPIExternalSource" "${CMAKE_CURRENT_BINARY_DIR}/../FileAPIExternalBuild")
 add_subdirectory(dir)
diff --git a/Tests/RunCMake/FileAPI/cxx/CMakeLists.txt b/Tests/RunCMake/FileAPI/cxx/CMakeLists.txt
index b0564f5..76235f5 100644
--- a/Tests/RunCMake/FileAPI/cxx/CMakeLists.txt
+++ b/Tests/RunCMake/FileAPI/cxx/CMakeLists.txt
@@ -17,3 +17,16 @@
 target_compile_options(cxx_exe PUBLIC TargetCompileOptions)
 target_link_options(cxx_exe PUBLIC TargetLinkOptions)
 target_link_directories(cxx_exe PUBLIC "${CMAKE_BINARY_DIR}/TargetLinkDir")
+
+target_precompile_headers(cxx_exe PUBLIC ../empty.h)
+
+add_executable(cxx_standard_exe ../empty.cxx)
+set_property(TARGET cxx_standard_exe PROPERTY CXX_STANDARD 17)
+
+add_executable(cxx_standard_compile_feature_exe ../empty.cxx)
+set_property(TARGET cxx_standard_compile_feature_exe PROPERTY CXX_STANDARD 98)
+if(CMAKE_CXX_STANDARD_DEFAULT AND DEFINED CMAKE_CXX11_STANDARD_COMPILE_OPTION)
+  target_compile_features(cxx_standard_compile_feature_exe PRIVATE cxx_std_11)
+  target_compile_features(cxx_standard_compile_feature_exe PRIVATE cxx_decltype)
+  file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/cxx_std_11.txt" "")
+endif()
diff --git a/Tests/RunCMake/FileAPI/empty.h b/Tests/RunCMake/FileAPI/empty.h
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/Tests/RunCMake/FileAPI/empty.h
diff --git a/Tests/RunCMake/FileAPI/interface/CMakeLists.txt b/Tests/RunCMake/FileAPI/interface/CMakeLists.txt
new file mode 100644
index 0000000..97948c5
--- /dev/null
+++ b/Tests/RunCMake/FileAPI/interface/CMakeLists.txt
@@ -0,0 +1,3 @@
+project(Interface)
+add_library(iface_none INTERFACE)
+add_library(iface_srcs INTERFACE ../empty.c)
diff --git a/Tests/RunCMake/GeneratorExpression/OUTPUT_NAME-recursion-result.txt b/Tests/RunCMake/File_Archive/7zip-with-bad-compression-result.txt
similarity index 100%
copy from Tests/RunCMake/GeneratorExpression/OUTPUT_NAME-recursion-result.txt
copy to Tests/RunCMake/File_Archive/7zip-with-bad-compression-result.txt
diff --git a/Tests/RunCMake/File_Archive/7zip-with-bad-compression-stderr.txt b/Tests/RunCMake/File_Archive/7zip-with-bad-compression-stderr.txt
new file mode 100644
index 0000000..f6bd1ab
--- /dev/null
+++ b/Tests/RunCMake/File_Archive/7zip-with-bad-compression-stderr.txt
@@ -0,0 +1,5 @@
+CMake Error at roundtrip.cmake:38 \(file\):
+  file archive format 7zip does not support COMPRESSION arguments
+Call Stack \(most recent call first\):
+  7zip-with-bad-compression.cmake:6 \(include\)
+  CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/File_Archive/7zip-with-bad-compression.cmake b/Tests/RunCMake/File_Archive/7zip-with-bad-compression.cmake
new file mode 100644
index 0000000..7461eb8
--- /dev/null
+++ b/Tests/RunCMake/File_Archive/7zip-with-bad-compression.cmake
@@ -0,0 +1,6 @@
+set(OUTPUT_NAME "test.zip")
+
+set(ARCHIVE_FORMAT 7zip)
+set(COMPRESSION_TYPE XZ)
+
+include(${CMAKE_CURRENT_LIST_DIR}/roundtrip.cmake)
diff --git a/Tests/RunCMake/File_Archive/7zip.cmake b/Tests/RunCMake/File_Archive/7zip.cmake
new file mode 100644
index 0000000..530e940
--- /dev/null
+++ b/Tests/RunCMake/File_Archive/7zip.cmake
@@ -0,0 +1,7 @@
+set(OUTPUT_NAME "test.7z")
+
+set(ARCHIVE_FORMAT 7zip)
+
+include(${CMAKE_CURRENT_LIST_DIR}/roundtrip.cmake)
+
+check_magic("377abcaf271c" LIMIT 6 HEX)
diff --git a/Tests/RunCMake/File_Archive/CMakeLists.txt b/Tests/RunCMake/File_Archive/CMakeLists.txt
new file mode 100644
index 0000000..2897109
--- /dev/null
+++ b/Tests/RunCMake/File_Archive/CMakeLists.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 3.0)
+project(${RunCMake_TEST} NONE)
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/File_Archive/RunCMakeTest.cmake b/Tests/RunCMake/File_Archive/RunCMakeTest.cmake
new file mode 100644
index 0000000..2bd0cd8
--- /dev/null
+++ b/Tests/RunCMake/File_Archive/RunCMakeTest.cmake
@@ -0,0 +1,18 @@
+include(RunCMake)
+
+run_cmake(7zip)
+run_cmake(gnutar)
+run_cmake(gnutar-gz)
+run_cmake(pax)
+run_cmake(pax-xz)
+run_cmake(pax-zstd)
+run_cmake(paxr)
+run_cmake(paxr-bz2)
+run_cmake(zip)
+
+# Extracting only selected files or directories
+run_cmake(zip-filtered)
+
+run_cmake(unsupported-format)
+run_cmake(zip-with-bad-compression)
+run_cmake(7zip-with-bad-compression)
diff --git a/Tests/RunCMake/File_Archive/gnutar-gz.cmake b/Tests/RunCMake/File_Archive/gnutar-gz.cmake
new file mode 100644
index 0000000..829022b
--- /dev/null
+++ b/Tests/RunCMake/File_Archive/gnutar-gz.cmake
@@ -0,0 +1,8 @@
+set(OUTPUT_NAME "test.tar.gz")
+
+set(ARCHIVE_FORMAT gnutar)
+set(COMPRESSION_TYPE GZip)
+
+include(${CMAKE_CURRENT_LIST_DIR}/roundtrip.cmake)
+
+check_magic("1f8b" LIMIT 2 HEX)
diff --git a/Tests/RunCMake/File_Archive/gnutar.cmake b/Tests/RunCMake/File_Archive/gnutar.cmake
new file mode 100644
index 0000000..17425c7
--- /dev/null
+++ b/Tests/RunCMake/File_Archive/gnutar.cmake
@@ -0,0 +1,7 @@
+set(OUTPUT_NAME "test.tar")
+
+set(ARCHIVE_FORMAT gnutar)
+
+include(${CMAKE_CURRENT_LIST_DIR}/roundtrip.cmake)
+
+check_magic("7573746172202000" OFFSET 257 LIMIT 8 HEX)
diff --git a/Tests/RunCMake/File_Archive/pax-xz.cmake b/Tests/RunCMake/File_Archive/pax-xz.cmake
new file mode 100644
index 0000000..ae485fd
--- /dev/null
+++ b/Tests/RunCMake/File_Archive/pax-xz.cmake
@@ -0,0 +1,8 @@
+set(OUTPUT_NAME "test.tar.xz")
+
+set(ARCHIVE_FORMAT pax)
+set(COMPRESSION_TYPE XZ)
+
+include(${CMAKE_CURRENT_LIST_DIR}/roundtrip.cmake)
+
+check_magic("fd377a585a00" LIMIT 6 HEX)
diff --git a/Tests/RunCMake/File_Archive/pax-zstd.cmake b/Tests/RunCMake/File_Archive/pax-zstd.cmake
new file mode 100644
index 0000000..ba3036e
--- /dev/null
+++ b/Tests/RunCMake/File_Archive/pax-zstd.cmake
@@ -0,0 +1,8 @@
+set(OUTPUT_NAME "test.tar.zstd")
+
+set(ARCHIVE_FORMAT pax)
+set(COMPRESSION_TYPE Zstd)
+
+include(${CMAKE_CURRENT_LIST_DIR}/roundtrip.cmake)
+
+check_magic("28b52ffd0058" LIMIT 6 HEX)
diff --git a/Tests/RunCMake/File_Archive/pax.cmake b/Tests/RunCMake/File_Archive/pax.cmake
new file mode 100644
index 0000000..46002fb
--- /dev/null
+++ b/Tests/RunCMake/File_Archive/pax.cmake
@@ -0,0 +1,7 @@
+set(OUTPUT_NAME "test.tar")
+
+set(ARCHIVE_FORMAT pax)
+
+include(${CMAKE_CURRENT_LIST_DIR}/roundtrip.cmake)
+
+check_magic("7573746172003030" OFFSET 257 LIMIT 8 HEX)
diff --git a/Tests/RunCMake/File_Archive/paxr-bz2.cmake b/Tests/RunCMake/File_Archive/paxr-bz2.cmake
new file mode 100644
index 0000000..d38f8f3
--- /dev/null
+++ b/Tests/RunCMake/File_Archive/paxr-bz2.cmake
@@ -0,0 +1,8 @@
+set(OUTPUT_NAME "test.tar.bz2")
+
+set(ARCHIVE_FORMAT paxr)
+set(COMPRESSION_TYPE BZip2)
+
+include(${CMAKE_CURRENT_LIST_DIR}/roundtrip.cmake)
+
+check_magic("425a68" LIMIT 3 HEX)
diff --git a/Tests/RunCMake/File_Archive/paxr.cmake b/Tests/RunCMake/File_Archive/paxr.cmake
new file mode 100644
index 0000000..ce44f05
--- /dev/null
+++ b/Tests/RunCMake/File_Archive/paxr.cmake
@@ -0,0 +1,7 @@
+set(OUTPUT_NAME "test.tar")
+
+set(ARCHIVE_FORMAT paxr)
+
+include(${CMAKE_CURRENT_LIST_DIR}/roundtrip.cmake)
+
+check_magic("7573746172003030" OFFSET 257 LIMIT 8 HEX)
diff --git a/Tests/RunCMake/File_Archive/roundtrip.cmake b/Tests/RunCMake/File_Archive/roundtrip.cmake
new file mode 100644
index 0000000..0638367
--- /dev/null
+++ b/Tests/RunCMake/File_Archive/roundtrip.cmake
@@ -0,0 +1,92 @@
+foreach(parameter OUTPUT_NAME ARCHIVE_FORMAT)
+  if(NOT DEFINED ${parameter})
+    message(FATAL_ERROR "missing required parameter ${parameter}")
+  endif()
+endforeach()
+
+set(COMPRESS_DIR compress_dir)
+set(FULL_COMPRESS_DIR ${CMAKE_CURRENT_BINARY_DIR}/${COMPRESS_DIR})
+
+set(DECOMPRESS_DIR decompress_dir)
+set(FULL_DECOMPRESS_DIR ${CMAKE_CURRENT_BINARY_DIR}/${DECOMPRESS_DIR})
+
+set(FULL_OUTPUT_NAME ${CMAKE_CURRENT_BINARY_DIR}/${OUTPUT_NAME})
+
+set(CHECK_FILES
+  "f1.txt"
+  "d1/f1.txt"
+  "d 2/f1.txt"
+  "d + 3/f1.txt"
+  "d_4/f1.txt"
+  "d-4/f1.txt"
+  "My Special Directory/f1.txt"
+)
+
+foreach(file ${CHECK_FILES})
+  configure_file(${CMAKE_CURRENT_LIST_FILE} ${FULL_COMPRESS_DIR}/${file} COPYONLY)
+endforeach()
+
+if(UNIX)
+  execute_process(COMMAND ln -sf f1.txt ${FULL_COMPRESS_DIR}/d1/f2.txt)
+  list(APPEND CHECK_FILES "d1/f2.txt")
+endif()
+
+file(REMOVE ${FULL_OUTPUT_NAME})
+file(REMOVE_RECURSE ${FULL_DECOMPRESS_DIR})
+file(MAKE_DIRECTORY ${FULL_DECOMPRESS_DIR})
+
+file(ARCHIVE_CREATE
+  OUTPUT ${FULL_OUTPUT_NAME}
+  FORMAT "${ARCHIVE_FORMAT}"
+  COMPRESSION "${COMPRESSION_TYPE}"
+  VERBOSE
+  PATHS ${COMPRESS_DIR})
+
+file(ARCHIVE_EXTRACT
+  INPUT ${FULL_OUTPUT_NAME}
+  ${DECOMPRESSION_OPTIONS}
+  DESTINATION ${FULL_DECOMPRESS_DIR}
+  VERBOSE)
+
+if(CUSTOM_CHECK_FILES)
+  set(CHECK_FILES ${CUSTOM_CHECK_FILES})
+endif()
+
+foreach(file ${CHECK_FILES})
+  set(input ${FULL_COMPRESS_DIR}/${file})
+  set(output ${FULL_DECOMPRESS_DIR}/${COMPRESS_DIR}/${file})
+
+  if(NOT EXISTS ${input})
+    message(SEND_ERROR "Cannot find input file ${output}")
+  endif()
+
+  if(NOT EXISTS ${output})
+    message(SEND_ERROR "Cannot find output file ${output}")
+  endif()
+
+  file(MD5 ${input} input_md5)
+  file(MD5 ${output} output_md5)
+
+  if(NOT input_md5 STREQUAL output_md5)
+    message(SEND_ERROR "Files \"${input}\" and \"${output}\" are different")
+  endif()
+endforeach()
+
+foreach(file ${NOT_EXISTING_FILES_CHECK})
+  set(output ${FULL_DECOMPRESS_DIR}/${COMPRESS_DIR}/${file})
+
+  if(EXISTS ${output})
+    message(SEND_ERROR "File ${output} exists but it shouldn't")
+  endif()
+endforeach()
+
+function(check_magic EXPECTED)
+  file(READ ${FULL_OUTPUT_NAME} ACTUAL
+    ${ARGN}
+  )
+
+  if(NOT ACTUAL STREQUAL EXPECTED)
+    message(FATAL_ERROR
+      "Actual [${ACTUAL}] does not match expected [${EXPECTED}]")
+  endif()
+endfunction()
diff --git a/Tests/RunCMake/alias_targets/imported-target-result.txt b/Tests/RunCMake/File_Archive/unsupported-format-result.txt
similarity index 100%
copy from Tests/RunCMake/alias_targets/imported-target-result.txt
copy to Tests/RunCMake/File_Archive/unsupported-format-result.txt
diff --git a/Tests/RunCMake/File_Archive/unsupported-format-stderr.txt b/Tests/RunCMake/File_Archive/unsupported-format-stderr.txt
new file mode 100644
index 0000000..4328022
--- /dev/null
+++ b/Tests/RunCMake/File_Archive/unsupported-format-stderr.txt
@@ -0,0 +1,5 @@
+CMake Error at roundtrip.cmake:38 \(file\):
+  file archive format rar not supported
+Call Stack \(most recent call first\):
+  unsupported-format.cmake:5 \(include\)
+  CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/File_Archive/unsupported-format.cmake b/Tests/RunCMake/File_Archive/unsupported-format.cmake
new file mode 100644
index 0000000..4b41e65
--- /dev/null
+++ b/Tests/RunCMake/File_Archive/unsupported-format.cmake
@@ -0,0 +1,5 @@
+set(OUTPUT_NAME "test.rar")
+
+set(ARCHIVE_FORMAT rar)
+
+include(${CMAKE_CURRENT_LIST_DIR}/roundtrip.cmake)
diff --git a/Tests/RunCMake/File_Archive/zip-filtered.cmake b/Tests/RunCMake/File_Archive/zip-filtered.cmake
new file mode 100644
index 0000000..a4aab8b
--- /dev/null
+++ b/Tests/RunCMake/File_Archive/zip-filtered.cmake
@@ -0,0 +1,26 @@
+set(OUTPUT_NAME "test.zip")
+
+set(ARCHIVE_FORMAT zip)
+
+set(DECOMPRESSION_OPTIONS
+  PATTERNS
+    compress_dir/f1.txt # Decompress only file
+    compress_*/d?       # and whole directory (has only one match)
+)
+
+set(CUSTOM_CHECK_FILES
+  "f1.txt"
+  "d1/f1.txt"
+)
+
+# This files shouldn't exists
+set(NOT_EXISTING_FILES_CHECK
+  "d 2/f1.txt"
+  "d + 3/f1.txt"
+  "d_4/f1.txt"
+  "d-4/f1.txt"
+)
+
+include(${CMAKE_CURRENT_LIST_DIR}/roundtrip.cmake)
+
+check_magic("504b0304" LIMIT 4 HEX)
diff --git a/Tests/RunCMake/GeneratorExpression/OUTPUT_NAME-recursion-result.txt b/Tests/RunCMake/File_Archive/zip-with-bad-compression-result.txt
similarity index 100%
copy from Tests/RunCMake/GeneratorExpression/OUTPUT_NAME-recursion-result.txt
copy to Tests/RunCMake/File_Archive/zip-with-bad-compression-result.txt
diff --git a/Tests/RunCMake/File_Archive/zip-with-bad-compression-stderr.txt b/Tests/RunCMake/File_Archive/zip-with-bad-compression-stderr.txt
new file mode 100644
index 0000000..72ad8c4
--- /dev/null
+++ b/Tests/RunCMake/File_Archive/zip-with-bad-compression-stderr.txt
@@ -0,0 +1,5 @@
+CMake Error at roundtrip.cmake:38 \(file\):
+  file archive format zip does not support COMPRESSION arguments
+Call Stack \(most recent call first\):
+  zip-with-bad-compression.cmake:6 \(include\)
+  CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/File_Archive/zip-with-bad-compression.cmake b/Tests/RunCMake/File_Archive/zip-with-bad-compression.cmake
new file mode 100644
index 0000000..2badd5b
--- /dev/null
+++ b/Tests/RunCMake/File_Archive/zip-with-bad-compression.cmake
@@ -0,0 +1,6 @@
+set(OUTPUT_NAME "test.zip")
+
+set(ARCHIVE_FORMAT zip)
+set(COMPRESSION_TYPE BZip2)
+
+include(${CMAKE_CURRENT_LIST_DIR}/roundtrip.cmake)
diff --git a/Tests/RunCMake/File_Archive/zip.cmake b/Tests/RunCMake/File_Archive/zip.cmake
new file mode 100644
index 0000000..09e84b0
--- /dev/null
+++ b/Tests/RunCMake/File_Archive/zip.cmake
@@ -0,0 +1,7 @@
+set(OUTPUT_NAME "test.zip")
+
+set(ARCHIVE_FORMAT zip)
+
+include(${CMAKE_CURRENT_LIST_DIR}/roundtrip.cmake)
+
+check_magic("504b0304" LIMIT 4 HEX)
diff --git a/Tests/RunCMake/interface_library/whitelist-result.txt b/Tests/RunCMake/File_Configure/BadArg-result.txt
similarity index 100%
copy from Tests/RunCMake/interface_library/whitelist-result.txt
copy to Tests/RunCMake/File_Configure/BadArg-result.txt
diff --git a/Tests/RunCMake/File_Configure/BadArg-stderr.txt b/Tests/RunCMake/File_Configure/BadArg-stderr.txt
new file mode 100644
index 0000000..5423a28
--- /dev/null
+++ b/Tests/RunCMake/File_Configure/BadArg-stderr.txt
@@ -0,0 +1,4 @@
+CMake Error at BadArg.cmake:[0-9]+ \(file\):
+  file Incorrect arguments to CONFIGURE subcommand.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/File_Configure/BadArg.cmake b/Tests/RunCMake/File_Configure/BadArg.cmake
new file mode 100644
index 0000000..7c7fcda
--- /dev/null
+++ b/Tests/RunCMake/File_Configure/BadArg.cmake
@@ -0,0 +1 @@
+file(CONFIGURE OUTPUT)
diff --git a/Tests/RunCMake/alias_targets/imported-target-result.txt b/Tests/RunCMake/File_Configure/BadArgGeneratorExpressionContent-result.txt
similarity index 100%
copy from Tests/RunCMake/alias_targets/imported-target-result.txt
copy to Tests/RunCMake/File_Configure/BadArgGeneratorExpressionContent-result.txt
diff --git a/Tests/RunCMake/File_Configure/BadArgGeneratorExpressionContent-stderr.txt b/Tests/RunCMake/File_Configure/BadArgGeneratorExpressionContent-stderr.txt
new file mode 100644
index 0000000..acda654
--- /dev/null
+++ b/Tests/RunCMake/File_Configure/BadArgGeneratorExpressionContent-stderr.txt
@@ -0,0 +1,5 @@
+CMake Error at BadArgGeneratorExpressionContent.cmake:[0-9]+ \(file\):
+  file CONFIGURE called with CONTENT containing a "<".  This character is not
+  allowed.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/File_Configure/BadArgGeneratorExpressionContent.cmake b/Tests/RunCMake/File_Configure/BadArgGeneratorExpressionContent.cmake
new file mode 100644
index 0000000..75fe9e5
--- /dev/null
+++ b/Tests/RunCMake/File_Configure/BadArgGeneratorExpressionContent.cmake
@@ -0,0 +1,4 @@
+file(CONFIGURE
+    OUTPUT "file.txt"
+    CONTENT "foo-$<CONFIG>"
+)
diff --git a/Tests/RunCMake/alias_targets/imported-target-result.txt b/Tests/RunCMake/File_Configure/BadArgGeneratorExpressionOutput-result.txt
similarity index 100%
copy from Tests/RunCMake/alias_targets/imported-target-result.txt
copy to Tests/RunCMake/File_Configure/BadArgGeneratorExpressionOutput-result.txt
diff --git a/Tests/RunCMake/File_Configure/BadArgGeneratorExpressionOutput-stderr.txt b/Tests/RunCMake/File_Configure/BadArgGeneratorExpressionOutput-stderr.txt
new file mode 100644
index 0000000..329d956
--- /dev/null
+++ b/Tests/RunCMake/File_Configure/BadArgGeneratorExpressionOutput-stderr.txt
@@ -0,0 +1,5 @@
+CMake Error at BadArgGeneratorExpressionOutput.cmake:[0-9]+ \(file\):
+  file CONFIGURE called with OUTPUT containing a "<".  This character is not
+  allowed.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/File_Configure/BadArgGeneratorExpressionOutput.cmake b/Tests/RunCMake/File_Configure/BadArgGeneratorExpressionOutput.cmake
new file mode 100644
index 0000000..31a79a7
--- /dev/null
+++ b/Tests/RunCMake/File_Configure/BadArgGeneratorExpressionOutput.cmake
@@ -0,0 +1,4 @@
+file(CONFIGURE
+    OUTPUT "file-$<CONFIG>.txt"
+    CONTENT "foo"
+)
diff --git a/Tests/RunCMake/File_Configure/CMakeLists.txt b/Tests/RunCMake/File_Configure/CMakeLists.txt
new file mode 100644
index 0000000..b7117bd
--- /dev/null
+++ b/Tests/RunCMake/File_Configure/CMakeLists.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 3.17)
+project(${RunCMake_TEST} NONE)
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/File_Configure/DirOutput-stderr.txt b/Tests/RunCMake/File_Configure/DirOutput-stderr.txt
new file mode 100644
index 0000000..d051f7c
--- /dev/null
+++ b/Tests/RunCMake/File_Configure/DirOutput-stderr.txt
@@ -0,0 +1 @@
+^DirOutput test file$
diff --git a/Tests/RunCMake/File_Configure/DirOutput.cmake b/Tests/RunCMake/File_Configure/DirOutput.cmake
new file mode 100644
index 0000000..aa0fadf
--- /dev/null
+++ b/Tests/RunCMake/File_Configure/DirOutput.cmake
@@ -0,0 +1,4 @@
+file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/DirOutput)
+configure_file(DirOutput.txt DirOutput)
+file(READ ${CMAKE_CURRENT_BINARY_DIR}/DirOutput/DirOutput.txt out)
+message("${out}")
diff --git a/Tests/RunCMake/File_Configure/DirOutput.txt b/Tests/RunCMake/File_Configure/DirOutput.txt
new file mode 100644
index 0000000..16388a6
--- /dev/null
+++ b/Tests/RunCMake/File_Configure/DirOutput.txt
@@ -0,0 +1 @@
+DirOutput test file
diff --git a/Tests/RunCMake/Languages/LINK_LANGUAGE-genex-result.txt b/Tests/RunCMake/File_Configure/NewLineStyle-NoArg-result.txt
similarity index 100%
copy from Tests/RunCMake/Languages/LINK_LANGUAGE-genex-result.txt
copy to Tests/RunCMake/File_Configure/NewLineStyle-NoArg-result.txt
diff --git a/Tests/RunCMake/File_Configure/NewLineStyle-NoArg-stderr.txt b/Tests/RunCMake/File_Configure/NewLineStyle-NoArg-stderr.txt
new file mode 100644
index 0000000..5a8ed2c
--- /dev/null
+++ b/Tests/RunCMake/File_Configure/NewLineStyle-NoArg-stderr.txt
@@ -0,0 +1,5 @@
+CMake Error at NewLineStyle-NoArg.cmake:[0-9]+ \(file\):
+  file CONFIGURE NEWLINE_STYLE must set a style: LF, CRLF, UNIX, DOS, or
+  WIN32
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/File_Configure/NewLineStyle-NoArg.cmake b/Tests/RunCMake/File_Configure/NewLineStyle-NoArg.cmake
new file mode 100644
index 0000000..d6738b4
--- /dev/null
+++ b/Tests/RunCMake/File_Configure/NewLineStyle-NoArg.cmake
@@ -0,0 +1,6 @@
+set(file_name  ${CMAKE_CURRENT_BINARY_DIR}/NewLineStyle.txt)
+file(CONFIGURE
+    OUTPUT ${file_name}
+    CONTENT "Data\n"
+    NEWLINE_STYLE
+)
diff --git a/Tests/RunCMake/File_Configure/NewLineStyle-ValidArg.cmake b/Tests/RunCMake/File_Configure/NewLineStyle-ValidArg.cmake
new file mode 100644
index 0000000..e384873
--- /dev/null
+++ b/Tests/RunCMake/File_Configure/NewLineStyle-ValidArg.cmake
@@ -0,0 +1,20 @@
+set(file_name  ${CMAKE_CURRENT_BINARY_DIR}/NewLineStyle.txt)
+
+function(test_eol style in out)
+    file(CONFIGURE
+        OUTPUT ${file_name}
+        CONTENT "@in@"
+        NEWLINE_STYLE ${style}
+    )
+    file(READ ${file_name} new HEX)
+    if(NOT "${new}" STREQUAL "${out}")
+        message(FATAL_ERROR "No ${style} line endings")
+    endif()
+endfunction()
+
+test_eol(DOS   "a" "610d0a")
+test_eol(WIN32 "b" "620d0a")
+test_eol(CRLF  "c" "630d0a")
+
+test_eol(UNIX  "d" "640a")
+test_eol(LF    "e" "650a")
diff --git a/Tests/RunCMake/Languages/LINK_LANGUAGE-genex-result.txt b/Tests/RunCMake/File_Configure/NewLineStyle-WrongArg-result.txt
similarity index 100%
copy from Tests/RunCMake/Languages/LINK_LANGUAGE-genex-result.txt
copy to Tests/RunCMake/File_Configure/NewLineStyle-WrongArg-result.txt
diff --git a/Tests/RunCMake/File_Configure/NewLineStyle-WrongArg-stderr.txt b/Tests/RunCMake/File_Configure/NewLineStyle-WrongArg-stderr.txt
new file mode 100644
index 0000000..c1bb42c
--- /dev/null
+++ b/Tests/RunCMake/File_Configure/NewLineStyle-WrongArg-stderr.txt
@@ -0,0 +1,5 @@
+CMake Error at NewLineStyle-WrongArg.cmake:[0-9]+ \(file\):
+  file CONFIGURE NEWLINE_STYLE sets an unknown style, only LF, CRLF, UNIX,
+  DOS, and WIN32 are supported
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/File_Configure/NewLineStyle-WrongArg.cmake b/Tests/RunCMake/File_Configure/NewLineStyle-WrongArg.cmake
new file mode 100644
index 0000000..7d38167
--- /dev/null
+++ b/Tests/RunCMake/File_Configure/NewLineStyle-WrongArg.cmake
@@ -0,0 +1,6 @@
+set(file_name  ${CMAKE_CURRENT_BINARY_DIR}/NewLineStyle.txt)
+file(CONFIGURE
+    OUTPUT ${file_name}
+    CONTENT "Data\n"
+    NEWLINE_STYLE FOO
+)
diff --git a/Tests/RunCMake/File_Configure/RunCMakeTest.cmake b/Tests/RunCMake/File_Configure/RunCMakeTest.cmake
new file mode 100644
index 0000000..0337014
--- /dev/null
+++ b/Tests/RunCMake/File_Configure/RunCMakeTest.cmake
@@ -0,0 +1,10 @@
+include(RunCMake)
+
+run_cmake(BadArg)
+run_cmake(BadArgGeneratorExpressionContent)
+run_cmake(BadArgGeneratorExpressionOutput)
+run_cmake(DirOutput)
+run_cmake(NewLineStyle-NoArg)
+run_cmake(NewLineStyle-ValidArg)
+run_cmake(NewLineStyle-WrongArg)
+run_cmake(SubDir)
diff --git a/Tests/RunCMake/File_Configure/SubDir-check.cmake b/Tests/RunCMake/File_Configure/SubDir-check.cmake
new file mode 100644
index 0000000..1e82587
--- /dev/null
+++ b/Tests/RunCMake/File_Configure/SubDir-check.cmake
@@ -0,0 +1,4 @@
+set(expected "${RunCMake_TEST_BINARY_DIR}/SubDir/out.txt")
+if(NOT EXISTS "${expected}")
+  set(RunCMake_TEST_FAILED "Expected file not created:\n  ${expected}")
+endif()
diff --git a/Tests/RunCMake/File_Configure/SubDir.cmake b/Tests/RunCMake/File_Configure/SubDir.cmake
new file mode 100644
index 0000000..fae60fa
--- /dev/null
+++ b/Tests/RunCMake/File_Configure/SubDir.cmake
@@ -0,0 +1 @@
+add_subdirectory(SubDir)
diff --git a/Tests/RunCMake/File_Configure/SubDir/CMakeLists.txt b/Tests/RunCMake/File_Configure/SubDir/CMakeLists.txt
new file mode 100644
index 0000000..6bd962e
--- /dev/null
+++ b/Tests/RunCMake/File_Configure/SubDir/CMakeLists.txt
@@ -0,0 +1 @@
+file(CONFIGURE OUTPUT out.txt CONTENT "")
diff --git a/Tests/RunCMake/File_Generate/AdjacentInOut.cmake b/Tests/RunCMake/File_Generate/AdjacentInOut.cmake
new file mode 100644
index 0000000..828c2ee
--- /dev/null
+++ b/Tests/RunCMake/File_Generate/AdjacentInOut.cmake
@@ -0,0 +1,6 @@
+cmake_policy(SET CMP0070 NEW)
+if(EXISTS "${CMAKE_CURRENT_BINARY_DIR}/AdjacentInOut.txt")
+  message(FATAL_ERROR "CMake should not re-run during the build!")
+endif()
+configure_file(AdjacentInOut.in ${CMAKE_CURRENT_BINARY_DIR}/AdjacentInOut.txt.tmp)
+file(GENERATE OUTPUT AdjacentInOut.txt INPUT ${CMAKE_CURRENT_BINARY_DIR}/AdjacentInOut.txt.tmp)
diff --git a/Tests/RunCMake/File_Generate/AdjacentInOut.in b/Tests/RunCMake/File_Generate/AdjacentInOut.in
new file mode 100644
index 0000000..bfbbda7
--- /dev/null
+++ b/Tests/RunCMake/File_Generate/AdjacentInOut.in
@@ -0,0 +1 @@
+Sample Text File
diff --git a/Tests/RunCMake/File_Generate/CMP0070-OLD-stderr.txt b/Tests/RunCMake/File_Generate/CMP0070-OLD-stderr.txt
new file mode 100644
index 0000000..bb578e5
--- /dev/null
+++ b/Tests/RunCMake/File_Generate/CMP0070-OLD-stderr.txt
@@ -0,0 +1,10 @@
+^CMake Deprecation Warning at CMP0070-OLD.cmake:[0-9]+ \(cmake_policy\):
+  The OLD behavior for policy CMP0070 will be removed from a future version
+  of CMake.
+
+  The cmake-policies\(7\) manual explains that the OLD behaviors of all
+  policies are deprecated and that a policy should be set to OLD only under
+  specific short-term circumstances.  Projects should be ported to the NEW
+  behavior and not rely on setting a policy to OLD.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:[0-9]+ \(include\)$
diff --git a/Tests/RunCMake/File_Generate/CMakeLists.txt b/Tests/RunCMake/File_Generate/CMakeLists.txt
index bc0cf5d..3178de5 100644
--- a/Tests/RunCMake/File_Generate/CMakeLists.txt
+++ b/Tests/RunCMake/File_Generate/CMakeLists.txt
@@ -1,4 +1,4 @@
-cmake_minimum_required(VERSION 2.8.4)
+cmake_minimum_required(VERSION 3.3)
 project(${RunCMake_TEST} NONE)
 if(NOT TEST_FILE)
   set(TEST_FILE ${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/File_Generate/RunCMakeTest.cmake b/Tests/RunCMake/File_Generate/RunCMakeTest.cmake
index 94aaca8..5987417 100644
--- a/Tests/RunCMake/File_Generate/RunCMakeTest.cmake
+++ b/Tests/RunCMake/File_Generate/RunCMakeTest.cmake
@@ -72,6 +72,7 @@
   if (NOT script_output STREQUAL SUCCESS)
     message(SEND_ERROR "Generated script did not execute correctly:\n${script_output}\n====\n${script_error}")
   endif()
+  unset(RunCMake_TEST_NO_CLEAN)
 endif()
 
 if (RunCMake_GENERATOR MATCHES Makefiles)
@@ -104,3 +105,10 @@
     message(SEND_ERROR "File did not re-generate: \"${RunCMake_BINARY_DIR}/ReRunCMake-build/output_file.txt\"")
   endif()
 endif()
+
+set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/AdjacentInOut-build)
+run_cmake(AdjacentInOut)
+set(RunCMake_TEST_NO_CLEAN 1)
+run_cmake_command(AdjacentInOut-nowork ${CMAKE_COMMAND} --build .)
+unset(RunCMake_TEST_BINARY_DIR)
+unset(RunCMake_TEST_NO_CLEAN)
diff --git a/Tests/RunCMake/FindOpenGL/CMP0072-OLD-stderr.txt b/Tests/RunCMake/FindOpenGL/CMP0072-OLD-stderr.txt
new file mode 100644
index 0000000..68d23d4
--- /dev/null
+++ b/Tests/RunCMake/FindOpenGL/CMP0072-OLD-stderr.txt
@@ -0,0 +1,10 @@
+^CMake Deprecation Warning at CMP0072-OLD.cmake:1 \(cmake_policy\):
+  The OLD behavior for policy CMP0072 will be removed from a future version
+  of CMake.
+
+  The cmake-policies\(7\) manual explains that the OLD behaviors of all
+  policies are deprecated and that a policy should be set to OLD only under
+  specific short-term circumstances.  Projects should be ported to the NEW
+  behavior and not rely on setting a policy to OLD.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)$
diff --git a/Tests/RunCMake/FindPkgConfig/CMakeLists.txt b/Tests/RunCMake/FindPkgConfig/CMakeLists.txt
index 72abfc8..74b3ff8 100644
--- a/Tests/RunCMake/FindPkgConfig/CMakeLists.txt
+++ b/Tests/RunCMake/FindPkgConfig/CMakeLists.txt
@@ -1,3 +1,3 @@
-cmake_minimum_required(VERSION 2.8.11)
+cmake_minimum_required(VERSION 3.3)
 project(${RunCMake_TEST} NONE)
 include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/FindPkgConfig/FindPkgConfig_CMAKE_APPBUNDLE_PATH.cmake b/Tests/RunCMake/FindPkgConfig/FindPkgConfig_CMAKE_APPBUNDLE_PATH.cmake
index 2687efe..bf8cd4e 100644
--- a/Tests/RunCMake/FindPkgConfig/FindPkgConfig_CMAKE_APPBUNDLE_PATH.cmake
+++ b/Tests/RunCMake/FindPkgConfig/FindPkgConfig_CMAKE_APPBUNDLE_PATH.cmake
@@ -4,53 +4,13 @@
 # Prepare environment and variables
 set(PKG_CONFIG_USE_CMAKE_PREFIX_PATH TRUE)
 set(CMAKE_APPBUNDLE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/pc-foo")
-if(WIN32)
-    set(PKG_CONFIG_EXECUTABLE "${CMAKE_CURRENT_SOURCE_DIR}\\dummy-pkg-config.bat")
-    set(ENV{CMAKE_APPBUNDLE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}\\pc-bar;X:\\this\\directory\\should\\not\\exist\\in\\the\\filesystem")
-    set(ENV{PKG_CONFIG_PATH} "C:\\baz")
-else()
-    set(PKG_CONFIG_EXECUTABLE "${CMAKE_CURRENT_SOURCE_DIR}/dummy-pkg-config.sh")
-    set(ENV{CMAKE_APPBUNDLE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/pc-bar:/this/directory/should/not/exist/in/the/filesystem")
-    set(ENV{PKG_CONFIG_PATH} "/baz")
-endif()
-
+set(PKG_CONFIG_EXECUTABLE "${CMAKE_CURRENT_SOURCE_DIR}/dummy-pkg-config.sh")
+set(ENV{CMAKE_APPBUNDLE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/pc-bar:/this/directory/should/not/exist/in/the/filesystem")
+set(ENV{PKG_CONFIG_PATH} "/baz")
 
 find_package(PkgConfig)
 
-
-if(NOT DEFINED CMAKE_SYSTEM_NAME
-    OR (CMAKE_SYSTEM_NAME MATCHES "^(Linux|kFreeBSD|GNU)$"
-    AND NOT CMAKE_CROSSCOMPILING))
-  if(EXISTS "/etc/debian_version") # is this a debian system ?
-    if(CMAKE_LIBRARY_ARCHITECTURE MATCHES "^(i386-linux-gnu|x86_64-linux-gnu)$")
-      # Cannot create directories for all the existing architectures...
-      set(expected_path "/baz:${CMAKE_CURRENT_SOURCE_DIR}/pc-foo/lib/${CMAKE_LIBRARY_ARCHITECTURE}/pkgconfig:${CMAKE_CURRENT_SOURCE_DIR}/pc-foo/lib/pkgconfig:${CMAKE_CURRENT_SOURCE_DIR}/pc-bar/lib/${CMAKE_LIBRARY_ARCHITECTURE}/pkgconfig:${CMAKE_CURRENT_SOURCE_DIR}/pc-bar/lib/pkgconfig")
-    else()
-      set(expected_path "/baz:${CMAKE_CURRENT_SOURCE_DIR}/pc-foo/lib/pkgconfig:${CMAKE_CURRENT_SOURCE_DIR}/pc-bar/lib/pkgconfig")
-    endif()
-  else()
-    # not debian, check the FIND_LIBRARY_USE_LIB32_PATHS and FIND_LIBRARY_USE_LIB64_PATHS properties
-    get_property(uselibx32 GLOBAL PROPERTY FIND_LIBRARY_USE_LIBX32_PATHS)
-    get_property(uselib32 GLOBAL PROPERTY FIND_LIBRARY_USE_LIB32_PATHS)
-    get_property(uselib64 GLOBAL PROPERTY FIND_LIBRARY_USE_LIB64_PATHS)
-    if(uselibx32 AND CMAKE_INTERNAL_PLATFORM_ABI STREQUAL "ELF X32")
-      set(expected_path "/baz:${CMAKE_CURRENT_SOURCE_DIR}/pc-foo/libx32/pkgconfig:${CMAKE_CURRENT_SOURCE_DIR}/pc-foo/lib/pkgconfig:${CMAKE_CURRENT_SOURCE_DIR}/pc-bar/libx32/pkgconfig:${CMAKE_CURRENT_SOURCE_DIR}/pc-bar/lib/pkgconfig")
-    elseif(uselib32 AND CMAKE_SIZEOF_VOID_P EQUAL 4)
-      set(expected_path "/baz:${CMAKE_CURRENT_SOURCE_DIR}/pc-foo/lib32/pkgconfig:${CMAKE_CURRENT_SOURCE_DIR}/pc-foo/lib/pkgconfig:${CMAKE_CURRENT_SOURCE_DIR}/pc-bar/lib32/pkgconfig:${CMAKE_CURRENT_SOURCE_DIR}/pc-bar/lib/pkgconfig")
-    elseif(uselib64 AND CMAKE_SIZEOF_VOID_P EQUAL 8)
-      set(expected_path "/baz:${CMAKE_CURRENT_SOURCE_DIR}/pc-foo/lib64/pkgconfig:${CMAKE_CURRENT_SOURCE_DIR}/pc-foo/lib/pkgconfig:${CMAKE_CURRENT_SOURCE_DIR}/pc-bar/lib64/pkgconfig:${CMAKE_CURRENT_SOURCE_DIR}/pc-bar/lib/pkgconfig")
-    else()
-      set(expected_path "/baz:${CMAKE_CURRENT_SOURCE_DIR}/pc-foo/lib/pkgconfig:${CMAKE_CURRENT_SOURCE_DIR}/pc-bar/lib/pkgconfig")
-    endif()
-  endif()
-else()
-  if(WIN32)
-    set(expected_path "C:\\baz;${CMAKE_CURRENT_SOURCE_DIR}\\pc-foo\\lib\\pkgconfig;${CMAKE_CURRENT_SOURCE_DIR}\\pc-bar\\lib\\pkgconfig")
-  else()
-    set(expected_path "/baz:${CMAKE_CURRENT_SOURCE_DIR}/pc-foo/lib/pkgconfig:${CMAKE_CURRENT_SOURCE_DIR}/pc-bar/lib/pkgconfig")
-  endif()
-endif()
-
+set(expected_path "/baz:${CMAKE_CURRENT_SOURCE_DIR}/pc-foo/lib/pkgconfig:${CMAKE_CURRENT_SOURCE_DIR}/pc-bar/lib/pkgconfig")
 
 pkg_check_modules(FOO "${expected_path}")
 
diff --git a/Tests/RunCMake/FindPkgConfig/FindPkgConfig_CMAKE_FRAMEWORK_PATH.cmake b/Tests/RunCMake/FindPkgConfig/FindPkgConfig_CMAKE_FRAMEWORK_PATH.cmake
index 74cda25..37c18fc 100644
--- a/Tests/RunCMake/FindPkgConfig/FindPkgConfig_CMAKE_FRAMEWORK_PATH.cmake
+++ b/Tests/RunCMake/FindPkgConfig/FindPkgConfig_CMAKE_FRAMEWORK_PATH.cmake
@@ -4,53 +4,13 @@
 # Prepare environment and variables
 set(PKG_CONFIG_USE_CMAKE_PREFIX_PATH TRUE)
 set(CMAKE_FRAMEWORK_PATH "${CMAKE_CURRENT_SOURCE_DIR}/pc-foo")
-if(WIN32)
-    set(PKG_CONFIG_EXECUTABLE "${CMAKE_CURRENT_SOURCE_DIR}\\dummy-pkg-config.bat")
-    set(ENV{CMAKE_FRAMEWORK_PATH} "${CMAKE_CURRENT_SOURCE_DIR}\\pc-bar;X:\\this\\directory\\should\\not\\exist\\in\\the\\filesystem")
-    set(ENV{PKG_CONFIG_PATH} "C:\\baz")
-else()
-    set(PKG_CONFIG_EXECUTABLE "${CMAKE_CURRENT_SOURCE_DIR}/dummy-pkg-config.sh")
-    set(ENV{CMAKE_FRAMEWORK_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/pc-bar:/this/directory/should/not/exist/in/the/filesystem")
-    set(ENV{PKG_CONFIG_PATH} "/baz")
-endif()
-
+set(PKG_CONFIG_EXECUTABLE "${CMAKE_CURRENT_SOURCE_DIR}/dummy-pkg-config.sh")
+set(ENV{CMAKE_FRAMEWORK_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/pc-bar:/this/directory/should/not/exist/in/the/filesystem")
+set(ENV{PKG_CONFIG_PATH} "/baz")
 
 find_package(PkgConfig)
 
-
-if(NOT DEFINED CMAKE_SYSTEM_NAME
-    OR (CMAKE_SYSTEM_NAME MATCHES "^(Linux|kFreeBSD|GNU)$"
-    AND NOT CMAKE_CROSSCOMPILING))
-  if(EXISTS "/etc/debian_version") # is this a debian system ?
-    if(CMAKE_LIBRARY_ARCHITECTURE MATCHES "^(i386-linux-gnu|x86_64-linux-gnu)$")
-      # Cannot create directories for all the existing architectures...
-      set(expected_path "/baz:${CMAKE_CURRENT_SOURCE_DIR}/pc-foo/lib/${CMAKE_LIBRARY_ARCHITECTURE}/pkgconfig:${CMAKE_CURRENT_SOURCE_DIR}/pc-foo/lib/pkgconfig:${CMAKE_CURRENT_SOURCE_DIR}/pc-bar/lib/${CMAKE_LIBRARY_ARCHITECTURE}/pkgconfig:${CMAKE_CURRENT_SOURCE_DIR}/pc-bar/lib/pkgconfig")
-    else()
-      set(expected_path "/baz:${CMAKE_CURRENT_SOURCE_DIR}/pc-foo/lib/pkgconfig:${CMAKE_CURRENT_SOURCE_DIR}/pc-bar/lib/pkgconfig")
-    endif()
-  else()
-    # not debian, check the FIND_LIBRARY_USE_LIB64_PATHS and FIND_LIBRARY_USE_LIB64_PATHS properties
-    get_property(uselibx32 GLOBAL PROPERTY FIND_LIBRARY_USE_LIBX32_PATHS)
-    get_property(uselib32 GLOBAL PROPERTY FIND_LIBRARY_USE_LIB32_PATHS)
-    get_property(uselib64 GLOBAL PROPERTY FIND_LIBRARY_USE_LIB64_PATHS)
-    if(uselibx32 AND CMAKE_INTERNAL_PLATFORM_ABI STREQUAL "ELF X32")
-      set(expected_path "/baz:${CMAKE_CURRENT_SOURCE_DIR}/pc-foo/libx32/pkgconfig:${CMAKE_CURRENT_SOURCE_DIR}/pc-foo/lib/pkgconfig:${CMAKE_CURRENT_SOURCE_DIR}/pc-bar/libx32/pkgconfig:${CMAKE_CURRENT_SOURCE_DIR}/pc-bar/lib/pkgconfig")
-    elseif(uselib32 AND CMAKE_SIZEOF_VOID_P EQUAL 4)
-      set(expected_path "/baz:${CMAKE_CURRENT_SOURCE_DIR}/pc-foo/lib32/pkgconfig:${CMAKE_CURRENT_SOURCE_DIR}/pc-foo/lib/pkgconfig:${CMAKE_CURRENT_SOURCE_DIR}/pc-bar/lib32/pkgconfig:${CMAKE_CURRENT_SOURCE_DIR}/pc-bar/lib/pkgconfig")
-    elseif(uselib64 AND CMAKE_SIZEOF_VOID_P EQUAL 8)
-      set(expected_path "/baz:${CMAKE_CURRENT_SOURCE_DIR}/pc-foo/lib64/pkgconfig:${CMAKE_CURRENT_SOURCE_DIR}/pc-foo/lib/pkgconfig:${CMAKE_CURRENT_SOURCE_DIR}/pc-bar/lib64/pkgconfig:${CMAKE_CURRENT_SOURCE_DIR}/pc-bar/lib/pkgconfig")
-    else()
-      set(expected_path "/baz:${CMAKE_CURRENT_SOURCE_DIR}/pc-foo/lib/pkgconfig:${CMAKE_CURRENT_SOURCE_DIR}/pc-bar/lib/pkgconfig")
-    endif()
-  endif()
-else()
-  if(WIN32)
-    set(expected_path "C:\\baz;${CMAKE_CURRENT_SOURCE_DIR}\\pc-foo\\lib\\pkgconfig;${CMAKE_CURRENT_SOURCE_DIR}\\pc-bar\\lib\\pkgconfig")
-  else()
-    set(expected_path "/baz:${CMAKE_CURRENT_SOURCE_DIR}/pc-foo/lib/pkgconfig:${CMAKE_CURRENT_SOURCE_DIR}/pc-bar/lib/pkgconfig")
-  endif()
-endif()
-
+set(expected_path "/baz:${CMAKE_CURRENT_SOURCE_DIR}/pc-foo/lib/pkgconfig:${CMAKE_CURRENT_SOURCE_DIR}/pc-bar/lib/pkgconfig")
 
 pkg_check_modules(FOO "${expected_path}")
 
diff --git a/Tests/RunCMake/FindPkgConfig/FindPkgConfig_GET_MATCHING_MODULE_NAME.cmake b/Tests/RunCMake/FindPkgConfig/FindPkgConfig_GET_MATCHING_MODULE_NAME.cmake
index fc3a766..aa293d5 100644
--- a/Tests/RunCMake/FindPkgConfig/FindPkgConfig_GET_MATCHING_MODULE_NAME.cmake
+++ b/Tests/RunCMake/FindPkgConfig/FindPkgConfig_GET_MATCHING_MODULE_NAME.cmake
@@ -20,7 +20,7 @@
 
 unset(FOO_MODULE_NAME)
 
-# verify variable get's also set on subsequent run
+# verify variable gets also set on subsequent run
 pkg_search_module(FOO REQUIRED foo bletch bar)
 
 if(NOT FOO_MODULE_NAME STREQUAL "bletch")
diff --git a/Tests/RunCMake/FindPkgConfig/FindPkgConfig_extract_frameworks.cmake b/Tests/RunCMake/FindPkgConfig/FindPkgConfig_extract_frameworks.cmake
new file mode 100644
index 0000000..fde886d
--- /dev/null
+++ b/Tests/RunCMake/FindPkgConfig/FindPkgConfig_extract_frameworks.cmake
@@ -0,0 +1,13 @@
+find_package(PkgConfig)
+
+set(foobar_LDFLAGS_OTHER "-Wl,xy;-framework;bar;-Wl,other-framework;-framework;baz;-Wl,abc;-framework;gosh;-frameworkcrap;-frame;j;-framework;nix;-Wl,def")
+set(foobar_LIBRARIES "-lz;-lm")
+
+_pkgconfig_extract_frameworks("foobar")
+
+if (NOT foobar_LDFLAGS_OTHER STREQUAL "-Wl,xy;-Wl,other-framework;-Wl,abc;-frameworkcrap;-frame;j;-Wl,def")
+  message(SEND_ERROR "foobar_LDFLAGS_OTHER did not match: ${foobar_LDFLAGS_OTHER}")
+endif ()
+if (NOT foobar_LIBRARIES STREQUAL "-lz;-lm;-framework bar;-framework baz;-framework gosh;-framework nix")
+  message(SEND_ERROR "foobar_LIBRARIES did not match: ${foobar_LIBRARIES}")
+endif ()
diff --git a/Tests/RunCMake/FindPkgConfig/FindPkgConfig_extract_frameworks_target.cmake b/Tests/RunCMake/FindPkgConfig/FindPkgConfig_extract_frameworks_target.cmake
new file mode 100644
index 0000000..5501d9f
--- /dev/null
+++ b/Tests/RunCMake/FindPkgConfig/FindPkgConfig_extract_frameworks_target.cmake
@@ -0,0 +1,29 @@
+# Prepare environment to reuse bletch.pc
+file(TO_NATIVE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/pc-bletch/lib/pkgconfig" PC_PATH)
+if(UNIX)
+  string(REPLACE "\\ " " " PC_PATH "${PC_PATH}")
+endif()
+set(ENV{PKG_CONFIG_PATH} "${PC_PATH}")
+
+find_package(PkgConfig REQUIRED)
+pkg_check_modules(Bletch IMPORTED_TARGET REQUIRED bletch-framework)
+
+if (Bletch_LDFLAGS_OTHER)
+  message(SEND_ERROR "Bletch_LDFLAGS_OTHER should be empty, but is '${Bletch_LDFLAGS_OTHER}'")
+endif ()
+
+if (NOT Bletch_LINK_LIBRARIES STREQUAL "-framework foo;-framework bar;bletch;-framework baz")
+  message(SEND_ERROR "Bletch_LINK_LIBRARIES has wrong value '${Bletch_LINK_LIBRARIES}'")
+endif ()
+
+foreach (prop IN ITEMS INTERFACE_INCLUDE_DIRECTORIES INTERFACE_LINK_OPTIONS INTERFACE_COMPILE_OPTIONS)
+  get_target_property(prop_value PkgConfig::Bletch ${prop})
+  if (prop_value)
+    message(SEND_ERROR "target property ${prop} should not be set, but is '${prop_value}'")
+  endif ()
+endforeach ()
+
+get_target_property(prop_value PkgConfig::Bletch INTERFACE_LINK_LIBRARIES)
+if (NOT prop_value STREQUAL Bletch_LINK_LIBRARIES)
+  message(SEND_ERROR "target property INTERFACE_LINK_LIBRARIES has wrong value '${prop_value}'")
+endif ()
diff --git a/Tests/RunCMake/FindPkgConfig/PkgConfigDoesNotExist-stdout.txt b/Tests/RunCMake/FindPkgConfig/PkgConfigDoesNotExist-stdout.txt
new file mode 100644
index 0000000..ef5f7f6
--- /dev/null
+++ b/Tests/RunCMake/FindPkgConfig/PkgConfigDoesNotExist-stdout.txt
@@ -0,0 +1,6 @@
+-- Could NOT find PkgConfig \(missing: PKG_CONFIG_EXECUTABLE\) *
+    Reason given by package: The command
+      "pkg-config-does-not-exist" --version
+    failed with output.*
+-- PKG_CONFIG_FOUND='FALSE'
+-- PKG_CONFIG_EXECUTABLE=''
diff --git a/Tests/RunCMake/FindPkgConfig/PkgConfigDoesNotExist.cmake b/Tests/RunCMake/FindPkgConfig/PkgConfigDoesNotExist.cmake
new file mode 100644
index 0000000..a4fabde
--- /dev/null
+++ b/Tests/RunCMake/FindPkgConfig/PkgConfigDoesNotExist.cmake
@@ -0,0 +1,4 @@
+set(PKG_CONFIG_EXECUTABLE "pkg-config-does-not-exist" CACHE FILEPATH "")
+find_package(PkgConfig)
+message(STATUS "PKG_CONFIG_FOUND='${PKG_CONFIG_FOUND}'")
+message(STATUS "PKG_CONFIG_EXECUTABLE='${PKG_CONFIG_EXECUTABLE}'")
diff --git a/Tests/RunCMake/FindPkgConfig/RunCMakeTest.cmake b/Tests/RunCMake/FindPkgConfig/RunCMakeTest.cmake
index 7b479f1..4e6eef6 100644
--- a/Tests/RunCMake/FindPkgConfig/RunCMakeTest.cmake
+++ b/Tests/RunCMake/FindPkgConfig/RunCMakeTest.cmake
@@ -5,12 +5,16 @@
 set(ENV{CMAKE_APPBUNDLE_PATH} "")
 set(ENV{CMAKE_FRAMEWORK_PATH} "")
 
+run_cmake(PkgConfigDoesNotExist)
+
 run_cmake(FindPkgConfig_NO_PKGCONFIG_PATH)
 run_cmake(FindPkgConfig_PKGCONFIG_PATH)
 run_cmake(FindPkgConfig_PKGCONFIG_PATH_NO_CMAKE_PATH)
 run_cmake(FindPkgConfig_PKGCONFIG_PATH_NO_CMAKE_ENVIRONMENT_PATH)
+run_cmake(FindPkgConfig_extract_frameworks)
 
 if(APPLE)
+  run_cmake(FindPkgConfig_extract_frameworks_target)
   run_cmake(FindPkgConfig_CMAKE_FRAMEWORK_PATH)
   run_cmake(FindPkgConfig_CMAKE_APPBUNDLE_PATH)
 endif()
diff --git a/Tests/RunCMake/FindPkgConfig/pc-bletch/lib/pkgconfig/bletch-framework.pc b/Tests/RunCMake/FindPkgConfig/pc-bletch/lib/pkgconfig/bletch-framework.pc
new file mode 100644
index 0000000..cc680ae
--- /dev/null
+++ b/Tests/RunCMake/FindPkgConfig/pc-bletch/lib/pkgconfig/bletch-framework.pc
@@ -0,0 +1,9 @@
+prefix=/opt/bletch
+exec_prefix=${prefix}
+libdir=${exec_prefix}/lib
+includedir=${prefix}/include
+
+Name: Bletch
+Description: Dummy packaget to test variable support
+Version: 1.3
+Libs: -L${libdir} -framework foo -framework bar -lbletch -framework baz
diff --git a/Tests/RunCMake/FindSWIG/CMakeLists.txt b/Tests/RunCMake/FindSWIG/CMakeLists.txt
new file mode 100644
index 0000000..d1b0d2c
--- /dev/null
+++ b/Tests/RunCMake/FindSWIG/CMakeLists.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 3.10)
+project(${RunCMake_TEST} C)
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/FindSWIG/RunCMakeTest.cmake b/Tests/RunCMake/FindSWIG/RunCMakeTest.cmake
new file mode 100644
index 0000000..5f5f7f5
--- /dev/null
+++ b/Tests/RunCMake/FindSWIG/RunCMakeTest.cmake
@@ -0,0 +1,4 @@
+include(RunCMake)
+
+run_cmake(components)
+run_cmake(missing-components)
diff --git a/Tests/RunCMake/FindSWIG/components-stdout.txt b/Tests/RunCMake/FindSWIG/components-stdout.txt
new file mode 100644
index 0000000..3977b08
--- /dev/null
+++ b/Tests/RunCMake/FindSWIG/components-stdout.txt
@@ -0,0 +1,6 @@
+-- Found SWIG: [^ ]+ \(found version "[0-9.]+"\) found components: java python missing components: PERL
+-- SWIG_VERSION='[0-9.]+'
+-- SWIG_java_FOUND=TRUE
+-- SWIG_python_FOUND=TRUE
+-- SWIG_PERL_FOUND=
+-- Configuring done
diff --git a/Tests/RunCMake/FindSWIG/components.cmake b/Tests/RunCMake/FindSWIG/components.cmake
new file mode 100644
index 0000000..b79a81e
--- /dev/null
+++ b/Tests/RunCMake/FindSWIG/components.cmake
@@ -0,0 +1,9 @@
+# Note that 'perl' will not be found because it is not lowercase.
+find_package(SWIG REQUIRED
+  COMPONENTS java
+  OPTIONAL_COMPONENTS python PERL)
+
+message(STATUS "SWIG_VERSION='${SWIG_VERSION}'")
+foreach(_lang java python PERL)
+  message(STATUS "SWIG_${_lang}_FOUND=${SWIG_${_lang}_FOUND}")
+endforeach()
diff --git a/Tests/RunCMake/Languages/LINK_LANGUAGE-genex-result.txt b/Tests/RunCMake/FindSWIG/missing-components-result.txt
similarity index 100%
copy from Tests/RunCMake/Languages/LINK_LANGUAGE-genex-result.txt
copy to Tests/RunCMake/FindSWIG/missing-components-result.txt
diff --git a/Tests/RunCMake/FindSWIG/missing-components-stderr.txt b/Tests/RunCMake/FindSWIG/missing-components-stderr.txt
new file mode 100644
index 0000000..c937532
--- /dev/null
+++ b/Tests/RunCMake/FindSWIG/missing-components-stderr.txt
@@ -0,0 +1 @@
+Could NOT find SWIG \(missing: invalid\)
diff --git a/Tests/RunCMake/FindSWIG/missing-components.cmake b/Tests/RunCMake/FindSWIG/missing-components.cmake
new file mode 100644
index 0000000..1d05ae4
--- /dev/null
+++ b/Tests/RunCMake/FindSWIG/missing-components.cmake
@@ -0,0 +1,3 @@
+find_package(SWIG REQUIRED
+  COMPONENTS invalid
+  OPTIONAL_COMPONENTS alsoinvalid)
diff --git a/Tests/RunCMake/Framework/FrameworkMultiConfigPostfix-build-final-check.cmake b/Tests/RunCMake/Framework/FrameworkMultiConfigPostfix-build-final-check.cmake
new file mode 100644
index 0000000..76fe6b8
--- /dev/null
+++ b/Tests/RunCMake/Framework/FrameworkMultiConfigPostfix-build-final-check.cmake
@@ -0,0 +1,45 @@
+include("${RunCMake_TEST_BINARY_DIR}/FrameworkMultiConfigPostfixInfo.cmake")
+
+get_filename_component(framework_location "${framework_dir}" DIRECTORY)
+set(non_existent_debug_framework_dir "${framework_location}/${target_file_name}_debug.framework")
+set(framework_resources "${framework_dir}/Resources")
+set(plist_file "${framework_resources}/Info.plist")
+
+set(symlink_release_path "${framework_dir}/${target_file_name}")
+set(framework_release_path "${framework_dir}/Versions/A/${target_file_name}")
+
+# When using a multi config generator (like Ninja Multi-Config and Xcode),
+# the postfix will be applied to the debug framework library name and the symlink name.
+# For single config generators, the name stays the same as the the release framework.
+if(is_multi_config)
+    set(symlink_debug_path "${framework_dir}/${target_file_name}_debug")
+    set(framework_debug_path "${framework_dir}/Versions/A/${target_file_name}_debug")
+else()
+    set(symlink_debug_path "${framework_dir}/${target_file_name}")
+    set(framework_debug_path "${framework_dir}/Versions/A/${target_file_name}")
+endif()
+
+if(NOT IS_DIRECTORY ${framework_dir})
+  message(SEND_ERROR "Framework dir not found at ${framework_dir}")
+endif()
+
+if(IS_DIRECTORY ${non_existent_debug_framework_dir})
+  message(SEND_ERROR
+      "A framework dir with a debug suffix should not exist at ${non_existent_debug_framework_dir}")
+endif()
+
+if(NOT IS_SYMLINK "${symlink_release_path}")
+  message(SEND_ERROR "Release framework symlink not found at ${symlink_release_path}")
+endif()
+
+if(NOT IS_SYMLINK "${symlink_debug_path}")
+  message(SEND_ERROR "Debug framework symlink not found at ${symlink_debug_path}")
+endif()
+
+if(NOT EXISTS "${framework_release_path}")
+  message(SEND_ERROR "Release framework not found at ${framework_release_path}")
+endif()
+
+if(NOT EXISTS "${framework_debug_path}")
+  message(SEND_ERROR "Debug framework not found at ${framework_debug_path}")
+endif()
diff --git a/Tests/RunCMake/Framework/FrameworkMultiConfigPostfix.cmake b/Tests/RunCMake/Framework/FrameworkMultiConfigPostfix.cmake
new file mode 100644
index 0000000..51e627d
--- /dev/null
+++ b/Tests/RunCMake/Framework/FrameworkMultiConfigPostfix.cmake
@@ -0,0 +1,25 @@
+enable_language(C)
+
+set(CMAKE_FRAMEWORK_MULTI_CONFIG_POSTFIX_DEBUG "_debug")
+
+set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/lib)
+set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_DEBUG ${CMAKE_CURRENT_BINARY_DIR}/lib)
+set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_RELEASE ${CMAKE_CURRENT_BINARY_DIR}/lib)
+set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/bin)
+set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG ${CMAKE_CURRENT_BINARY_DIR}/bin)
+set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE ${CMAKE_CURRENT_BINARY_DIR}/bin)
+set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/lib)
+set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_DEBUG ${CMAKE_CURRENT_BINARY_DIR}/lib)
+set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_RELEASE ${CMAKE_CURRENT_BINARY_DIR}/lib)
+
+set(target_name "mylib")
+add_library(${target_name} SHARED foo.c)
+set_property(TARGET ${target_name} PROPERTY FRAMEWORK ON)
+get_property(is_multi_config GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
+
+string(APPEND content
+       "set(is_multi_config \"${is_multi_config}\")\n"
+       "set(framework_dir \"$<TARGET_BUNDLE_DIR:${target_name}>\")\n"
+       "set(target_file_name ${target_name})\n")
+file(GENERATE OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/FrameworkMultiConfigPostfixInfo.cmake
+     CONTENT "${content}")
diff --git a/Tests/RunCMake/Framework/RunCMakeTest.cmake b/Tests/RunCMake/Framework/RunCMakeTest.cmake
index 965fbf4..6ee61a3 100644
--- a/Tests/RunCMake/Framework/RunCMakeTest.cmake
+++ b/Tests/RunCMake/Framework/RunCMakeTest.cmake
@@ -45,3 +45,39 @@
 framework_type_test(ios STATIC YES)
 framework_type_test(osx SHARED YES)
 framework_type_test(osx STATIC YES)
+
+function(framework_multi_config_postfix_test)
+    set(configure_name "FrameworkMultiConfigPostfix")
+    set(build_name "${configure_name}-build-intermediate")
+    set(build_name_final "${configure_name}-build-final")
+
+    if(RunCMake_GENERATOR MATCHES "Ninja Multi-Config")
+        set(RunCMake_TEST_OPTIONS
+            "-DCMAKE_CONFIGURATION_TYPES=Debug\\;Release;-DCMAKE_CROSS_CONFIGS=all")
+    elseif(RunCMake_GENERATOR MATCHES "Xcode")
+        set(RunCMake_TEST_OPTIONS
+            "-DCMAKE_CONFIGURATION_TYPES=Debug\\;Release")
+    else()
+        set(RunCMake_TEST_OPTIONS "-DCMAKE_BUILD_TYPE=Debug")
+    endif()
+
+    set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/${configure_name})
+    set(RunCMake_TEST_NO_CLEAN 1)
+
+    file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}")
+    file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}")
+    run_cmake(${configure_name})
+    unset(RunCMake_TEST_OPTIONS)
+
+    if(RunCMake_GENERATOR MATCHES "Ninja Multi-Config")
+        run_cmake_command(${build_name_final} ${CMAKE_COMMAND} --build . --target all:all)
+    elseif(RunCMake_GENERATOR MATCHES "Xcode")
+        run_cmake_command(${build_name} ${CMAKE_COMMAND} --build . --config Release)
+        run_cmake_command(${build_name} ${CMAKE_COMMAND} --build . --config Debug)
+        run_cmake_command(${build_name_final} ${CMAKE_COMMAND} --build . --config Debug)
+    else()
+        run_cmake_command(${build_name_final} ${CMAKE_COMMAND} --build .)
+    endif()
+endfunction()
+
+framework_multi_config_postfix_test()
diff --git a/Tests/RunCMake/GenEx-COMPILE_LANGUAGE/CMakeLists.txt b/Tests/RunCMake/GenEx-COMPILE_LANGUAGE/CMakeLists.txt
new file mode 100644
index 0000000..74b3ff8
--- /dev/null
+++ b/Tests/RunCMake/GenEx-COMPILE_LANGUAGE/CMakeLists.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 3.3)
+project(${RunCMake_TEST} NONE)
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/GenEx-COMPILE_LANGUAGE/COMPILE_LANGUAGE-TARGET_PROPERTY.cmake b/Tests/RunCMake/GenEx-COMPILE_LANGUAGE/COMPILE_LANGUAGE-TARGET_PROPERTY.cmake
new file mode 100644
index 0000000..293ddda
--- /dev/null
+++ b/Tests/RunCMake/GenEx-COMPILE_LANGUAGE/COMPILE_LANGUAGE-TARGET_PROPERTY.cmake
@@ -0,0 +1,17 @@
+enable_language(C)
+
+add_library (lib SHARED empty.c)
+set_target_properties(lib PROPERTIES
+  INCLUDE_DIRECTORIES "$<$<COMPILE_LANGUAGE:C>:/usr/include>"
+  COMPILE_DEFINITIONS "$<$<COMPILE_LANGUAGE:C>:DEF>"
+  COMPILE_OPTIONS "$<$<COMPILE_LANGUAGE:C>:-O>")
+
+add_custom_target(drive
+  COMMAND ${CMAKE_COMMAND} -E echo $<TARGET_PROPERTY:lib,INCLUDE_DIRECTORIES>
+                                   $<TARGET_PROPERTY:lib,COMPILE_DEFINITIONS>
+                                   $<TARGET_PROPERTY:lib,COMPILE_OPTIONS>)
+
+add_custom_command(TARGET drive PRE_BUILD
+  COMMAND ${CMAKE_COMMAND} -E echo $<TARGET_PROPERTY:lib,INCLUDE_DIRECTORIES>
+                                   $<TARGET_PROPERTY:lib,COMPILE_DEFINITIONS>
+                                   $<TARGET_PROPERTY:lib,COMPILE_OPTIONS>)
diff --git a/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_custom_command-result.txt b/Tests/RunCMake/GenEx-COMPILE_LANGUAGE/COMPILE_LANGUAGE-add_custom_command-result.txt
similarity index 100%
rename from Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_custom_command-result.txt
rename to Tests/RunCMake/GenEx-COMPILE_LANGUAGE/COMPILE_LANGUAGE-add_custom_command-result.txt
diff --git a/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_custom_command-stderr.txt b/Tests/RunCMake/GenEx-COMPILE_LANGUAGE/COMPILE_LANGUAGE-add_custom_command-stderr.txt
similarity index 100%
rename from Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_custom_command-stderr.txt
rename to Tests/RunCMake/GenEx-COMPILE_LANGUAGE/COMPILE_LANGUAGE-add_custom_command-stderr.txt
diff --git a/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_custom_command.cmake b/Tests/RunCMake/GenEx-COMPILE_LANGUAGE/COMPILE_LANGUAGE-add_custom_command.cmake
similarity index 100%
rename from Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_custom_command.cmake
rename to Tests/RunCMake/GenEx-COMPILE_LANGUAGE/COMPILE_LANGUAGE-add_custom_command.cmake
diff --git a/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_custom_target-result.txt b/Tests/RunCMake/GenEx-COMPILE_LANGUAGE/COMPILE_LANGUAGE-add_custom_target-result.txt
similarity index 100%
rename from Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_custom_target-result.txt
rename to Tests/RunCMake/GenEx-COMPILE_LANGUAGE/COMPILE_LANGUAGE-add_custom_target-result.txt
diff --git a/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_custom_target-stderr.txt b/Tests/RunCMake/GenEx-COMPILE_LANGUAGE/COMPILE_LANGUAGE-add_custom_target-stderr.txt
similarity index 100%
rename from Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_custom_target-stderr.txt
rename to Tests/RunCMake/GenEx-COMPILE_LANGUAGE/COMPILE_LANGUAGE-add_custom_target-stderr.txt
diff --git a/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_custom_target.cmake b/Tests/RunCMake/GenEx-COMPILE_LANGUAGE/COMPILE_LANGUAGE-add_custom_target.cmake
similarity index 100%
rename from Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_custom_target.cmake
rename to Tests/RunCMake/GenEx-COMPILE_LANGUAGE/COMPILE_LANGUAGE-add_custom_target.cmake
diff --git a/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_executable-result.txt b/Tests/RunCMake/GenEx-COMPILE_LANGUAGE/COMPILE_LANGUAGE-add_executable-result.txt
similarity index 100%
rename from Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_executable-result.txt
rename to Tests/RunCMake/GenEx-COMPILE_LANGUAGE/COMPILE_LANGUAGE-add_executable-result.txt
diff --git a/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_executable-stderr.txt b/Tests/RunCMake/GenEx-COMPILE_LANGUAGE/COMPILE_LANGUAGE-add_executable-stderr.txt
similarity index 100%
rename from Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_executable-stderr.txt
rename to Tests/RunCMake/GenEx-COMPILE_LANGUAGE/COMPILE_LANGUAGE-add_executable-stderr.txt
diff --git a/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_executable.cmake b/Tests/RunCMake/GenEx-COMPILE_LANGUAGE/COMPILE_LANGUAGE-add_executable.cmake
similarity index 100%
rename from Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_executable.cmake
rename to Tests/RunCMake/GenEx-COMPILE_LANGUAGE/COMPILE_LANGUAGE-add_executable.cmake
diff --git a/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_library-result.txt b/Tests/RunCMake/GenEx-COMPILE_LANGUAGE/COMPILE_LANGUAGE-add_library-result.txt
similarity index 100%
rename from Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_library-result.txt
rename to Tests/RunCMake/GenEx-COMPILE_LANGUAGE/COMPILE_LANGUAGE-add_library-result.txt
diff --git a/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_library-stderr.txt b/Tests/RunCMake/GenEx-COMPILE_LANGUAGE/COMPILE_LANGUAGE-add_library-stderr.txt
similarity index 100%
rename from Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_library-stderr.txt
rename to Tests/RunCMake/GenEx-COMPILE_LANGUAGE/COMPILE_LANGUAGE-add_library-stderr.txt
diff --git a/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_library.cmake b/Tests/RunCMake/GenEx-COMPILE_LANGUAGE/COMPILE_LANGUAGE-add_library.cmake
similarity index 100%
rename from Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_library.cmake
rename to Tests/RunCMake/GenEx-COMPILE_LANGUAGE/COMPILE_LANGUAGE-add_library.cmake
diff --git a/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_test-result.txt b/Tests/RunCMake/GenEx-COMPILE_LANGUAGE/COMPILE_LANGUAGE-add_test-result.txt
similarity index 100%
rename from Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_test-result.txt
rename to Tests/RunCMake/GenEx-COMPILE_LANGUAGE/COMPILE_LANGUAGE-add_test-result.txt
diff --git a/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_test-stderr.txt b/Tests/RunCMake/GenEx-COMPILE_LANGUAGE/COMPILE_LANGUAGE-add_test-stderr.txt
similarity index 100%
rename from Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_test-stderr.txt
rename to Tests/RunCMake/GenEx-COMPILE_LANGUAGE/COMPILE_LANGUAGE-add_test-stderr.txt
diff --git a/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_test.cmake b/Tests/RunCMake/GenEx-COMPILE_LANGUAGE/COMPILE_LANGUAGE-add_test.cmake
similarity index 100%
rename from Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_test.cmake
rename to Tests/RunCMake/GenEx-COMPILE_LANGUAGE/COMPILE_LANGUAGE-add_test.cmake
diff --git a/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-install-result.txt b/Tests/RunCMake/GenEx-COMPILE_LANGUAGE/COMPILE_LANGUAGE-install-result.txt
similarity index 100%
rename from Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-install-result.txt
rename to Tests/RunCMake/GenEx-COMPILE_LANGUAGE/COMPILE_LANGUAGE-install-result.txt
diff --git a/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-install-stderr.txt b/Tests/RunCMake/GenEx-COMPILE_LANGUAGE/COMPILE_LANGUAGE-install-stderr.txt
similarity index 100%
rename from Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-install-stderr.txt
rename to Tests/RunCMake/GenEx-COMPILE_LANGUAGE/COMPILE_LANGUAGE-install-stderr.txt
diff --git a/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-install.cmake b/Tests/RunCMake/GenEx-COMPILE_LANGUAGE/COMPILE_LANGUAGE-install.cmake
similarity index 100%
rename from Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-install.cmake
rename to Tests/RunCMake/GenEx-COMPILE_LANGUAGE/COMPILE_LANGUAGE-install.cmake
diff --git a/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-target_sources-result.txt b/Tests/RunCMake/GenEx-COMPILE_LANGUAGE/COMPILE_LANGUAGE-target_sources-result.txt
similarity index 100%
rename from Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-target_sources-result.txt
rename to Tests/RunCMake/GenEx-COMPILE_LANGUAGE/COMPILE_LANGUAGE-target_sources-result.txt
diff --git a/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-target_sources-stderr.txt b/Tests/RunCMake/GenEx-COMPILE_LANGUAGE/COMPILE_LANGUAGE-target_sources-stderr.txt
similarity index 100%
rename from Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-target_sources-stderr.txt
rename to Tests/RunCMake/GenEx-COMPILE_LANGUAGE/COMPILE_LANGUAGE-target_sources-stderr.txt
diff --git a/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-target_sources.cmake b/Tests/RunCMake/GenEx-COMPILE_LANGUAGE/COMPILE_LANGUAGE-target_sources.cmake
similarity index 100%
rename from Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-target_sources.cmake
rename to Tests/RunCMake/GenEx-COMPILE_LANGUAGE/COMPILE_LANGUAGE-target_sources.cmake
diff --git a/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-unknown-lang.cmake b/Tests/RunCMake/GenEx-COMPILE_LANGUAGE/COMPILE_LANGUAGE-unknown-lang.cmake
similarity index 100%
rename from Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-unknown-lang.cmake
rename to Tests/RunCMake/GenEx-COMPILE_LANGUAGE/COMPILE_LANGUAGE-unknown-lang.cmake
diff --git a/Tests/RunCMake/GenEx-COMPILE_LANGUAGE/RunCMakeTest.cmake b/Tests/RunCMake/GenEx-COMPILE_LANGUAGE/RunCMakeTest.cmake
new file mode 100644
index 0000000..15a5e79
--- /dev/null
+++ b/Tests/RunCMake/GenEx-COMPILE_LANGUAGE/RunCMakeTest.cmake
@@ -0,0 +1,11 @@
+include(RunCMake)
+
+run_cmake(COMPILE_LANGUAGE-add_custom_target)
+run_cmake(COMPILE_LANGUAGE-add_custom_command)
+run_cmake(COMPILE_LANGUAGE-install)
+run_cmake(COMPILE_LANGUAGE-target_sources)
+run_cmake(COMPILE_LANGUAGE-add_executable)
+run_cmake(COMPILE_LANGUAGE-add_library)
+run_cmake(COMPILE_LANGUAGE-add_test)
+run_cmake(COMPILE_LANGUAGE-unknown-lang)
+run_cmake(COMPILE_LANGUAGE-TARGET_PROPERTY)
diff --git a/Tests/RunCMake/GenEx-COMPILE_LANGUAGE/empty.c b/Tests/RunCMake/GenEx-COMPILE_LANGUAGE/empty.c
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/Tests/RunCMake/GenEx-COMPILE_LANGUAGE/empty.c
diff --git a/Tests/RunCMake/GenEx-COMPILE_LANG_AND_ID/CMakeLists.txt b/Tests/RunCMake/GenEx-COMPILE_LANG_AND_ID/CMakeLists.txt
new file mode 100644
index 0000000..77030d6
--- /dev/null
+++ b/Tests/RunCMake/GenEx-COMPILE_LANG_AND_ID/CMakeLists.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 3.15)
+project(${RunCMake_TEST} NONE)
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/GenEx-COMPILE_LANG_AND_ID/COMPILE_LANG_AND_ID-TARGET_PROPERTY.cmake b/Tests/RunCMake/GenEx-COMPILE_LANG_AND_ID/COMPILE_LANG_AND_ID-TARGET_PROPERTY.cmake
new file mode 100644
index 0000000..6a718d6
--- /dev/null
+++ b/Tests/RunCMake/GenEx-COMPILE_LANG_AND_ID/COMPILE_LANG_AND_ID-TARGET_PROPERTY.cmake
@@ -0,0 +1,17 @@
+enable_language(C)
+
+add_library (lib SHARED empty.c)
+set_target_properties(lib PROPERTIES
+  INCLUDE_DIRECTORIES "$<$<COMPILE_LANG_AND_ID:C,GNU>:/usr/include>"
+  COMPILE_DEFINITIONS "$<$<COMPILE_LANG_AND_ID:C,GNU>:DEF>"
+  COMPILE_OPTIONS "$<$<COMPILE_LANG_AND_ID:C,GNU>:-O>")
+
+add_custom_target(drive
+  COMMAND ${CMAKE_COMMAND} -E echo $<TARGET_PROPERTY:lib,INCLUDE_DIRECTORIES>
+                                   $<TARGET_PROPERTY:lib,COMPILE_DEFINITIONS>
+                                   $<TARGET_PROPERTY:lib,COMPILE_OPTIONS>)
+
+add_custom_command(TARGET drive PRE_BUILD
+  COMMAND ${CMAKE_COMMAND} -E echo $<TARGET_PROPERTY:lib,INCLUDE_DIRECTORIES>
+                                   $<TARGET_PROPERTY:lib,COMPILE_DEFINITIONS>
+                                   $<TARGET_PROPERTY:lib,COMPILE_OPTIONS>)
diff --git a/Tests/RunCMake/GeneratorExpression/COMPILE_LANG_AND_ID-add_custom_command-result.txt b/Tests/RunCMake/GenEx-COMPILE_LANG_AND_ID/COMPILE_LANG_AND_ID-add_custom_command-result.txt
similarity index 100%
rename from Tests/RunCMake/GeneratorExpression/COMPILE_LANG_AND_ID-add_custom_command-result.txt
rename to Tests/RunCMake/GenEx-COMPILE_LANG_AND_ID/COMPILE_LANG_AND_ID-add_custom_command-result.txt
diff --git a/Tests/RunCMake/GeneratorExpression/COMPILE_LANG_AND_ID-add_custom_command-stderr.txt b/Tests/RunCMake/GenEx-COMPILE_LANG_AND_ID/COMPILE_LANG_AND_ID-add_custom_command-stderr.txt
similarity index 100%
rename from Tests/RunCMake/GeneratorExpression/COMPILE_LANG_AND_ID-add_custom_command-stderr.txt
rename to Tests/RunCMake/GenEx-COMPILE_LANG_AND_ID/COMPILE_LANG_AND_ID-add_custom_command-stderr.txt
diff --git a/Tests/RunCMake/GeneratorExpression/COMPILE_LANG_AND_ID-add_custom_command.cmake b/Tests/RunCMake/GenEx-COMPILE_LANG_AND_ID/COMPILE_LANG_AND_ID-add_custom_command.cmake
similarity index 100%
rename from Tests/RunCMake/GeneratorExpression/COMPILE_LANG_AND_ID-add_custom_command.cmake
rename to Tests/RunCMake/GenEx-COMPILE_LANG_AND_ID/COMPILE_LANG_AND_ID-add_custom_command.cmake
diff --git a/Tests/RunCMake/GeneratorExpression/COMPILE_LANG_AND_ID-add_custom_target-result.txt b/Tests/RunCMake/GenEx-COMPILE_LANG_AND_ID/COMPILE_LANG_AND_ID-add_custom_target-result.txt
similarity index 100%
rename from Tests/RunCMake/GeneratorExpression/COMPILE_LANG_AND_ID-add_custom_target-result.txt
rename to Tests/RunCMake/GenEx-COMPILE_LANG_AND_ID/COMPILE_LANG_AND_ID-add_custom_target-result.txt
diff --git a/Tests/RunCMake/GeneratorExpression/COMPILE_LANG_AND_ID-add_custom_target-stderr.txt b/Tests/RunCMake/GenEx-COMPILE_LANG_AND_ID/COMPILE_LANG_AND_ID-add_custom_target-stderr.txt
similarity index 100%
rename from Tests/RunCMake/GeneratorExpression/COMPILE_LANG_AND_ID-add_custom_target-stderr.txt
rename to Tests/RunCMake/GenEx-COMPILE_LANG_AND_ID/COMPILE_LANG_AND_ID-add_custom_target-stderr.txt
diff --git a/Tests/RunCMake/GeneratorExpression/COMPILE_LANG_AND_ID-add_custom_target.cmake b/Tests/RunCMake/GenEx-COMPILE_LANG_AND_ID/COMPILE_LANG_AND_ID-add_custom_target.cmake
similarity index 100%
rename from Tests/RunCMake/GeneratorExpression/COMPILE_LANG_AND_ID-add_custom_target.cmake
rename to Tests/RunCMake/GenEx-COMPILE_LANG_AND_ID/COMPILE_LANG_AND_ID-add_custom_target.cmake
diff --git a/Tests/RunCMake/GeneratorExpression/COMPILE_LANG_AND_ID-add_executable-result.txt b/Tests/RunCMake/GenEx-COMPILE_LANG_AND_ID/COMPILE_LANG_AND_ID-add_executable-result.txt
similarity index 100%
rename from Tests/RunCMake/GeneratorExpression/COMPILE_LANG_AND_ID-add_executable-result.txt
rename to Tests/RunCMake/GenEx-COMPILE_LANG_AND_ID/COMPILE_LANG_AND_ID-add_executable-result.txt
diff --git a/Tests/RunCMake/GeneratorExpression/COMPILE_LANG_AND_ID-add_executable-stderr.txt b/Tests/RunCMake/GenEx-COMPILE_LANG_AND_ID/COMPILE_LANG_AND_ID-add_executable-stderr.txt
similarity index 100%
rename from Tests/RunCMake/GeneratorExpression/COMPILE_LANG_AND_ID-add_executable-stderr.txt
rename to Tests/RunCMake/GenEx-COMPILE_LANG_AND_ID/COMPILE_LANG_AND_ID-add_executable-stderr.txt
diff --git a/Tests/RunCMake/GeneratorExpression/COMPILE_LANG_AND_ID-add_executable.cmake b/Tests/RunCMake/GenEx-COMPILE_LANG_AND_ID/COMPILE_LANG_AND_ID-add_executable.cmake
similarity index 100%
rename from Tests/RunCMake/GeneratorExpression/COMPILE_LANG_AND_ID-add_executable.cmake
rename to Tests/RunCMake/GenEx-COMPILE_LANG_AND_ID/COMPILE_LANG_AND_ID-add_executable.cmake
diff --git a/Tests/RunCMake/GeneratorExpression/COMPILE_LANG_AND_ID-add_library-result.txt b/Tests/RunCMake/GenEx-COMPILE_LANG_AND_ID/COMPILE_LANG_AND_ID-add_library-result.txt
similarity index 100%
rename from Tests/RunCMake/GeneratorExpression/COMPILE_LANG_AND_ID-add_library-result.txt
rename to Tests/RunCMake/GenEx-COMPILE_LANG_AND_ID/COMPILE_LANG_AND_ID-add_library-result.txt
diff --git a/Tests/RunCMake/GeneratorExpression/COMPILE_LANG_AND_ID-add_library-stderr.txt b/Tests/RunCMake/GenEx-COMPILE_LANG_AND_ID/COMPILE_LANG_AND_ID-add_library-stderr.txt
similarity index 100%
rename from Tests/RunCMake/GeneratorExpression/COMPILE_LANG_AND_ID-add_library-stderr.txt
rename to Tests/RunCMake/GenEx-COMPILE_LANG_AND_ID/COMPILE_LANG_AND_ID-add_library-stderr.txt
diff --git a/Tests/RunCMake/GeneratorExpression/COMPILE_LANG_AND_ID-add_library.cmake b/Tests/RunCMake/GenEx-COMPILE_LANG_AND_ID/COMPILE_LANG_AND_ID-add_library.cmake
similarity index 100%
rename from Tests/RunCMake/GeneratorExpression/COMPILE_LANG_AND_ID-add_library.cmake
rename to Tests/RunCMake/GenEx-COMPILE_LANG_AND_ID/COMPILE_LANG_AND_ID-add_library.cmake
diff --git a/Tests/RunCMake/GeneratorExpression/COMPILE_LANG_AND_ID-add_test-result.txt b/Tests/RunCMake/GenEx-COMPILE_LANG_AND_ID/COMPILE_LANG_AND_ID-add_test-result.txt
similarity index 100%
rename from Tests/RunCMake/GeneratorExpression/COMPILE_LANG_AND_ID-add_test-result.txt
rename to Tests/RunCMake/GenEx-COMPILE_LANG_AND_ID/COMPILE_LANG_AND_ID-add_test-result.txt
diff --git a/Tests/RunCMake/GeneratorExpression/COMPILE_LANG_AND_ID-add_test-stderr.txt b/Tests/RunCMake/GenEx-COMPILE_LANG_AND_ID/COMPILE_LANG_AND_ID-add_test-stderr.txt
similarity index 100%
rename from Tests/RunCMake/GeneratorExpression/COMPILE_LANG_AND_ID-add_test-stderr.txt
rename to Tests/RunCMake/GenEx-COMPILE_LANG_AND_ID/COMPILE_LANG_AND_ID-add_test-stderr.txt
diff --git a/Tests/RunCMake/GeneratorExpression/COMPILE_LANG_AND_ID-add_test.cmake b/Tests/RunCMake/GenEx-COMPILE_LANG_AND_ID/COMPILE_LANG_AND_ID-add_test.cmake
similarity index 100%
rename from Tests/RunCMake/GeneratorExpression/COMPILE_LANG_AND_ID-add_test.cmake
rename to Tests/RunCMake/GenEx-COMPILE_LANG_AND_ID/COMPILE_LANG_AND_ID-add_test.cmake
diff --git a/Tests/RunCMake/GeneratorExpression/COMPILE_LANG_AND_ID-install-result.txt b/Tests/RunCMake/GenEx-COMPILE_LANG_AND_ID/COMPILE_LANG_AND_ID-install-result.txt
similarity index 100%
rename from Tests/RunCMake/GeneratorExpression/COMPILE_LANG_AND_ID-install-result.txt
rename to Tests/RunCMake/GenEx-COMPILE_LANG_AND_ID/COMPILE_LANG_AND_ID-install-result.txt
diff --git a/Tests/RunCMake/GeneratorExpression/COMPILE_LANG_AND_ID-install-stderr.txt b/Tests/RunCMake/GenEx-COMPILE_LANG_AND_ID/COMPILE_LANG_AND_ID-install-stderr.txt
similarity index 100%
rename from Tests/RunCMake/GeneratorExpression/COMPILE_LANG_AND_ID-install-stderr.txt
rename to Tests/RunCMake/GenEx-COMPILE_LANG_AND_ID/COMPILE_LANG_AND_ID-install-stderr.txt
diff --git a/Tests/RunCMake/GeneratorExpression/COMPILE_LANG_AND_ID-install.cmake b/Tests/RunCMake/GenEx-COMPILE_LANG_AND_ID/COMPILE_LANG_AND_ID-install.cmake
similarity index 100%
rename from Tests/RunCMake/GeneratorExpression/COMPILE_LANG_AND_ID-install.cmake
rename to Tests/RunCMake/GenEx-COMPILE_LANG_AND_ID/COMPILE_LANG_AND_ID-install.cmake
diff --git a/Tests/RunCMake/GeneratorExpression/COMPILE_LANG_AND_ID-target_sources-result.txt b/Tests/RunCMake/GenEx-COMPILE_LANG_AND_ID/COMPILE_LANG_AND_ID-target_sources-result.txt
similarity index 100%
rename from Tests/RunCMake/GeneratorExpression/COMPILE_LANG_AND_ID-target_sources-result.txt
rename to Tests/RunCMake/GenEx-COMPILE_LANG_AND_ID/COMPILE_LANG_AND_ID-target_sources-result.txt
diff --git a/Tests/RunCMake/GeneratorExpression/COMPILE_LANG_AND_ID-target_sources-stderr.txt b/Tests/RunCMake/GenEx-COMPILE_LANG_AND_ID/COMPILE_LANG_AND_ID-target_sources-stderr.txt
similarity index 100%
rename from Tests/RunCMake/GeneratorExpression/COMPILE_LANG_AND_ID-target_sources-stderr.txt
rename to Tests/RunCMake/GenEx-COMPILE_LANG_AND_ID/COMPILE_LANG_AND_ID-target_sources-stderr.txt
diff --git a/Tests/RunCMake/GeneratorExpression/COMPILE_LANG_AND_ID-target_sources.cmake b/Tests/RunCMake/GenEx-COMPILE_LANG_AND_ID/COMPILE_LANG_AND_ID-target_sources.cmake
similarity index 100%
rename from Tests/RunCMake/GeneratorExpression/COMPILE_LANG_AND_ID-target_sources.cmake
rename to Tests/RunCMake/GenEx-COMPILE_LANG_AND_ID/COMPILE_LANG_AND_ID-target_sources.cmake
diff --git a/Tests/RunCMake/GeneratorExpression/COMPILE_LANG_AND_ID-unknown-lang.cmake b/Tests/RunCMake/GenEx-COMPILE_LANG_AND_ID/COMPILE_LANG_AND_ID-unknown-lang.cmake
similarity index 100%
rename from Tests/RunCMake/GeneratorExpression/COMPILE_LANG_AND_ID-unknown-lang.cmake
rename to Tests/RunCMake/GenEx-COMPILE_LANG_AND_ID/COMPILE_LANG_AND_ID-unknown-lang.cmake
diff --git a/Tests/RunCMake/GenEx-COMPILE_LANG_AND_ID/RunCMakeTest.cmake b/Tests/RunCMake/GenEx-COMPILE_LANG_AND_ID/RunCMakeTest.cmake
new file mode 100644
index 0000000..68bd05d
--- /dev/null
+++ b/Tests/RunCMake/GenEx-COMPILE_LANG_AND_ID/RunCMakeTest.cmake
@@ -0,0 +1,11 @@
+include(RunCMake)
+
+run_cmake(COMPILE_LANG_AND_ID-add_custom_target)
+run_cmake(COMPILE_LANG_AND_ID-add_custom_command)
+run_cmake(COMPILE_LANG_AND_ID-install)
+run_cmake(COMPILE_LANG_AND_ID-target_sources)
+run_cmake(COMPILE_LANG_AND_ID-add_executable)
+run_cmake(COMPILE_LANG_AND_ID-add_library)
+run_cmake(COMPILE_LANG_AND_ID-add_test)
+run_cmake(COMPILE_LANG_AND_ID-unknown-lang)
+run_cmake(COMPILE_LANG_AND_ID-TARGET_PROPERTY)
diff --git a/Tests/RunCMake/GenEx-COMPILE_LANG_AND_ID/empty.c b/Tests/RunCMake/GenEx-COMPILE_LANG_AND_ID/empty.c
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/Tests/RunCMake/GenEx-COMPILE_LANG_AND_ID/empty.c
diff --git a/Tests/RunCMake/GenEx-DEVICE_LINK/CMakeLists.txt b/Tests/RunCMake/GenEx-DEVICE_LINK/CMakeLists.txt
new file mode 100644
index 0000000..b646c4a
--- /dev/null
+++ b/Tests/RunCMake/GenEx-DEVICE_LINK/CMakeLists.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 3.18)
+project(${RunCMake_TEST} NONE)
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_custom_command-result.txt b/Tests/RunCMake/GenEx-DEVICE_LINK/DEVICE_LINK-add_custom_command-result.txt
similarity index 100%
copy from Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_custom_command-result.txt
copy to Tests/RunCMake/GenEx-DEVICE_LINK/DEVICE_LINK-add_custom_command-result.txt
diff --git a/Tests/RunCMake/GenEx-DEVICE_LINK/DEVICE_LINK-add_custom_command-stderr.txt b/Tests/RunCMake/GenEx-DEVICE_LINK/DEVICE_LINK-add_custom_command-stderr.txt
new file mode 100644
index 0000000..eb15834
--- /dev/null
+++ b/Tests/RunCMake/GenEx-DEVICE_LINK/DEVICE_LINK-add_custom_command-stderr.txt
@@ -0,0 +1,9 @@
+CMake Error at DEVICE_LINK-add_custom_command.cmake:[0-9]+ \(add_custom_command\):
+  Error evaluating generator expression:
+
+    \$<DEVICE_LINK>
+
+  \$<DEVICE_LINK:...> may only be used with binary targets to specify link
+  options.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/GenEx-DEVICE_LINK/DEVICE_LINK-add_custom_command.cmake b/Tests/RunCMake/GenEx-DEVICE_LINK/DEVICE_LINK-add_custom_command.cmake
new file mode 100644
index 0000000..01b3784
--- /dev/null
+++ b/Tests/RunCMake/GenEx-DEVICE_LINK/DEVICE_LINK-add_custom_command.cmake
@@ -0,0 +1,4 @@
+add_custom_target(drive)
+add_custom_command(TARGET drive PRE_BUILD
+  COMMAND ${CMAKE_COMMAND} -E echo $<DEVICE_LINK>
+)
diff --git a/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_custom_target-result.txt b/Tests/RunCMake/GenEx-DEVICE_LINK/DEVICE_LINK-add_custom_target-result.txt
similarity index 100%
copy from Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_custom_target-result.txt
copy to Tests/RunCMake/GenEx-DEVICE_LINK/DEVICE_LINK-add_custom_target-result.txt
diff --git a/Tests/RunCMake/GenEx-DEVICE_LINK/DEVICE_LINK-add_custom_target-stderr.txt b/Tests/RunCMake/GenEx-DEVICE_LINK/DEVICE_LINK-add_custom_target-stderr.txt
new file mode 100644
index 0000000..cdd3043
--- /dev/null
+++ b/Tests/RunCMake/GenEx-DEVICE_LINK/DEVICE_LINK-add_custom_target-stderr.txt
@@ -0,0 +1,9 @@
+CMake Error at DEVICE_LINK-add_custom_target.cmake:[0-9]+ \(add_custom_target\):
+  Error evaluating generator expression:
+
+    \$<DEVICE_LINK>
+
+  \$<DEVICE_LINK:...> may only be used with binary targets to specify link
+  options.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/GenEx-DEVICE_LINK/DEVICE_LINK-add_custom_target.cmake b/Tests/RunCMake/GenEx-DEVICE_LINK/DEVICE_LINK-add_custom_target.cmake
new file mode 100644
index 0000000..35728e9
--- /dev/null
+++ b/Tests/RunCMake/GenEx-DEVICE_LINK/DEVICE_LINK-add_custom_target.cmake
@@ -0,0 +1,3 @@
+add_custom_target(drive
+  COMMAND ${CMAKE_COMMAND} -E echo $<DEVICE_LINK>
+)
diff --git a/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_executable-result.txt b/Tests/RunCMake/GenEx-DEVICE_LINK/DEVICE_LINK-add_executable-result.txt
similarity index 100%
copy from Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_executable-result.txt
copy to Tests/RunCMake/GenEx-DEVICE_LINK/DEVICE_LINK-add_executable-result.txt
diff --git a/Tests/RunCMake/GenEx-DEVICE_LINK/DEVICE_LINK-add_executable-stderr.txt b/Tests/RunCMake/GenEx-DEVICE_LINK/DEVICE_LINK-add_executable-stderr.txt
new file mode 100644
index 0000000..56b595c
--- /dev/null
+++ b/Tests/RunCMake/GenEx-DEVICE_LINK/DEVICE_LINK-add_executable-stderr.txt
@@ -0,0 +1,9 @@
+CMake Error at DEVICE_LINK-add_executable.cmake:[0-9]+ \(add_executable\):
+  Error evaluating generator expression:
+
+    \$<DEVICE_LINK:empty.c>
+
+  \$<DEVICE_LINK:...> may only be used with binary targets to specify link
+  options.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/GenEx-DEVICE_LINK/DEVICE_LINK-add_executable.cmake b/Tests/RunCMake/GenEx-DEVICE_LINK/DEVICE_LINK-add_executable.cmake
new file mode 100644
index 0000000..899f8f6
--- /dev/null
+++ b/Tests/RunCMake/GenEx-DEVICE_LINK/DEVICE_LINK-add_executable.cmake
@@ -0,0 +1 @@
+add_executable(empty $<DEVICE_LINK:empty.c>)
diff --git a/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_library-result.txt b/Tests/RunCMake/GenEx-DEVICE_LINK/DEVICE_LINK-add_library-result.txt
similarity index 100%
copy from Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_library-result.txt
copy to Tests/RunCMake/GenEx-DEVICE_LINK/DEVICE_LINK-add_library-result.txt
diff --git a/Tests/RunCMake/GenEx-DEVICE_LINK/DEVICE_LINK-add_library-stderr.txt b/Tests/RunCMake/GenEx-DEVICE_LINK/DEVICE_LINK-add_library-stderr.txt
new file mode 100644
index 0000000..4477e00
--- /dev/null
+++ b/Tests/RunCMake/GenEx-DEVICE_LINK/DEVICE_LINK-add_library-stderr.txt
@@ -0,0 +1,9 @@
+CMake Error at DEVICE_LINK-add_library.cmake:[0-9]+ \(add_library\):
+  Error evaluating generator expression:
+
+    \$<DEVICE_LINK:empty.c>
+
+  \$<DEVICE_LINK:...> may only be used with binary targets to specify link
+  options.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/GenEx-DEVICE_LINK/DEVICE_LINK-add_library.cmake b/Tests/RunCMake/GenEx-DEVICE_LINK/DEVICE_LINK-add_library.cmake
new file mode 100644
index 0000000..fc8547b
--- /dev/null
+++ b/Tests/RunCMake/GenEx-DEVICE_LINK/DEVICE_LINK-add_library.cmake
@@ -0,0 +1 @@
+add_library(empty $<DEVICE_LINK:empty.c>)
diff --git a/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_test-result.txt b/Tests/RunCMake/GenEx-DEVICE_LINK/DEVICE_LINK-add_test-result.txt
similarity index 100%
copy from Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_test-result.txt
copy to Tests/RunCMake/GenEx-DEVICE_LINK/DEVICE_LINK-add_test-result.txt
diff --git a/Tests/RunCMake/GenEx-DEVICE_LINK/DEVICE_LINK-add_test-stderr.txt b/Tests/RunCMake/GenEx-DEVICE_LINK/DEVICE_LINK-add_test-stderr.txt
new file mode 100644
index 0000000..99561fe
--- /dev/null
+++ b/Tests/RunCMake/GenEx-DEVICE_LINK/DEVICE_LINK-add_test-stderr.txt
@@ -0,0 +1,9 @@
+CMake Error at DEVICE_LINK-add_test.cmake:[0-9]+ \(add_test\):
+  Error evaluating generator expression:
+
+    \$<DEVICE_LINK>
+
+  \$<DEVICE_LINK:...> may only be used with binary targets to specify link
+  options.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/GenEx-DEVICE_LINK/DEVICE_LINK-add_test.cmake b/Tests/RunCMake/GenEx-DEVICE_LINK/DEVICE_LINK-add_test.cmake
new file mode 100644
index 0000000..87d6ba1
--- /dev/null
+++ b/Tests/RunCMake/GenEx-DEVICE_LINK/DEVICE_LINK-add_test.cmake
@@ -0,0 +1,5 @@
+
+include(CTest)
+enable_testing()
+
+add_test(NAME dummy COMMAND ${CMAKE_COMMAND} -E echo $<DEVICE_LINK>)
diff --git a/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-install-result.txt b/Tests/RunCMake/GenEx-DEVICE_LINK/DEVICE_LINK-install-result.txt
similarity index 100%
copy from Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-install-result.txt
copy to Tests/RunCMake/GenEx-DEVICE_LINK/DEVICE_LINK-install-result.txt
diff --git a/Tests/RunCMake/GenEx-DEVICE_LINK/DEVICE_LINK-install-stderr.txt b/Tests/RunCMake/GenEx-DEVICE_LINK/DEVICE_LINK-install-stderr.txt
new file mode 100644
index 0000000..afb3090
--- /dev/null
+++ b/Tests/RunCMake/GenEx-DEVICE_LINK/DEVICE_LINK-install-stderr.txt
@@ -0,0 +1,7 @@
+CMake Error:
+  Error evaluating generator expression:
+
+    \$<DEVICE_LINK:empty>
+
+  \$<DEVICE_LINK:...> may only be used with binary targets to specify link
+  options.
diff --git a/Tests/RunCMake/GenEx-DEVICE_LINK/DEVICE_LINK-install.cmake b/Tests/RunCMake/GenEx-DEVICE_LINK/DEVICE_LINK-install.cmake
new file mode 100644
index 0000000..4b6dbef
--- /dev/null
+++ b/Tests/RunCMake/GenEx-DEVICE_LINK/DEVICE_LINK-install.cmake
@@ -0,0 +1,5 @@
+
+install(FILES
+  $<DEVICE_LINK:empty>
+  DESTINATION src
+)
diff --git a/Tests/RunCMake/interface_library/target_commands-result.txt b/Tests/RunCMake/GenEx-DEVICE_LINK/DEVICE_LINK-link_depends-result.txt
similarity index 100%
copy from Tests/RunCMake/interface_library/target_commands-result.txt
copy to Tests/RunCMake/GenEx-DEVICE_LINK/DEVICE_LINK-link_depends-result.txt
diff --git a/Tests/RunCMake/GenEx-DEVICE_LINK/DEVICE_LINK-link_depends-stderr.txt b/Tests/RunCMake/GenEx-DEVICE_LINK/DEVICE_LINK-link_depends-stderr.txt
new file mode 100644
index 0000000..4fa0522
--- /dev/null
+++ b/Tests/RunCMake/GenEx-DEVICE_LINK/DEVICE_LINK-link_depends-stderr.txt
@@ -0,0 +1,7 @@
+CMake Error:
+  Error evaluating generator expression:
+
+    \$<DEVICE_LINK:lib>
+
+  \$<DEVICE_LINK:...> may only be used with binary targets to specify link
+  options.
diff --git a/Tests/RunCMake/GenEx-DEVICE_LINK/DEVICE_LINK-link_depends.cmake b/Tests/RunCMake/GenEx-DEVICE_LINK/DEVICE_LINK-link_depends.cmake
new file mode 100644
index 0000000..8129514
--- /dev/null
+++ b/Tests/RunCMake/GenEx-DEVICE_LINK/DEVICE_LINK-link_depends.cmake
@@ -0,0 +1,7 @@
+
+enable_language(C)
+
+add_library(lib empty.c)
+
+add_executable(empty empty.c)
+set_property(TARGET empty PROPERTY LINK_DEPENDS $<DEVICE_LINK:lib>)
diff --git a/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-target_sources-result.txt b/Tests/RunCMake/GenEx-DEVICE_LINK/DEVICE_LINK-target_compile_definitions-result.txt
similarity index 100%
copy from Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-target_sources-result.txt
copy to Tests/RunCMake/GenEx-DEVICE_LINK/DEVICE_LINK-target_compile_definitions-result.txt
diff --git a/Tests/RunCMake/GenEx-DEVICE_LINK/DEVICE_LINK-target_compile_definitions-stderr.txt b/Tests/RunCMake/GenEx-DEVICE_LINK/DEVICE_LINK-target_compile_definitions-stderr.txt
new file mode 100644
index 0000000..c0185e3
--- /dev/null
+++ b/Tests/RunCMake/GenEx-DEVICE_LINK/DEVICE_LINK-target_compile_definitions-stderr.txt
@@ -0,0 +1,9 @@
+CMake Error at DEVICE_LINK-target_compile_definitions.cmake:[0-9]+ \(target_compile_definitions\):
+  Error evaluating generator expression:
+
+    \$<DEVICE_LINK:DEF>
+
+  \$<DEVICE_LINK:...> may only be used with binary targets to specify link
+  options.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/GenEx-DEVICE_LINK/DEVICE_LINK-target_compile_definitions.cmake b/Tests/RunCMake/GenEx-DEVICE_LINK/DEVICE_LINK-target_compile_definitions.cmake
new file mode 100644
index 0000000..aaa8efc
--- /dev/null
+++ b/Tests/RunCMake/GenEx-DEVICE_LINK/DEVICE_LINK-target_compile_definitions.cmake
@@ -0,0 +1,4 @@
+
+enable_language(C)
+add_executable(empty empty.c)
+target_compile_definitions(empty PRIVATE $<DEVICE_LINK:DEF>)
diff --git a/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-target_sources-result.txt b/Tests/RunCMake/GenEx-DEVICE_LINK/DEVICE_LINK-target_compile_options-result.txt
similarity index 100%
copy from Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-target_sources-result.txt
copy to Tests/RunCMake/GenEx-DEVICE_LINK/DEVICE_LINK-target_compile_options-result.txt
diff --git a/Tests/RunCMake/GenEx-DEVICE_LINK/DEVICE_LINK-target_compile_options-stderr.txt b/Tests/RunCMake/GenEx-DEVICE_LINK/DEVICE_LINK-target_compile_options-stderr.txt
new file mode 100644
index 0000000..34ca4f2
--- /dev/null
+++ b/Tests/RunCMake/GenEx-DEVICE_LINK/DEVICE_LINK-target_compile_options-stderr.txt
@@ -0,0 +1,9 @@
+CMake Error at DEVICE_LINK-target_compile_options.cmake:[0-9]+ \(target_compile_options\):
+  Error evaluating generator expression:
+
+    \$<DEVICE_LINK:-OPT>
+
+  \$<DEVICE_LINK:...> may only be used with binary targets to specify link
+  options.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/GenEx-DEVICE_LINK/DEVICE_LINK-target_compile_options.cmake b/Tests/RunCMake/GenEx-DEVICE_LINK/DEVICE_LINK-target_compile_options.cmake
new file mode 100644
index 0000000..a9cb7fd
--- /dev/null
+++ b/Tests/RunCMake/GenEx-DEVICE_LINK/DEVICE_LINK-target_compile_options.cmake
@@ -0,0 +1,4 @@
+
+enable_language(C)
+add_executable(empty empty.c)
+target_compile_options(empty PRIVATE $<DEVICE_LINK:-OPT>)
diff --git a/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-target_sources-result.txt b/Tests/RunCMake/GenEx-DEVICE_LINK/DEVICE_LINK-target_include_directories-result.txt
similarity index 100%
copy from Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-target_sources-result.txt
copy to Tests/RunCMake/GenEx-DEVICE_LINK/DEVICE_LINK-target_include_directories-result.txt
diff --git a/Tests/RunCMake/GenEx-DEVICE_LINK/DEVICE_LINK-target_include_directories-stderr.txt b/Tests/RunCMake/GenEx-DEVICE_LINK/DEVICE_LINK-target_include_directories-stderr.txt
new file mode 100644
index 0000000..4d1642d
--- /dev/null
+++ b/Tests/RunCMake/GenEx-DEVICE_LINK/DEVICE_LINK-target_include_directories-stderr.txt
@@ -0,0 +1,9 @@
+CMake Error at DEVICE_LINK-target_include_directories.cmake:[0-9]+ \(target_include_directories\):
+  Error evaluating generator expression:
+
+    \$<DEVICE_LINK:/DIR>
+
+  \$<DEVICE_LINK:...> may only be used with binary targets to specify link
+  options.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/GenEx-DEVICE_LINK/DEVICE_LINK-target_include_directories.cmake b/Tests/RunCMake/GenEx-DEVICE_LINK/DEVICE_LINK-target_include_directories.cmake
new file mode 100644
index 0000000..03cc413
--- /dev/null
+++ b/Tests/RunCMake/GenEx-DEVICE_LINK/DEVICE_LINK-target_include_directories.cmake
@@ -0,0 +1,4 @@
+
+enable_language(C)
+add_executable(empty empty.c)
+target_include_directories(empty PRIVATE $<DEVICE_LINK:/DIR>)
diff --git a/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-target_sources-result.txt b/Tests/RunCMake/GenEx-DEVICE_LINK/DEVICE_LINK-target_link_directories-result.txt
similarity index 100%
copy from Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-target_sources-result.txt
copy to Tests/RunCMake/GenEx-DEVICE_LINK/DEVICE_LINK-target_link_directories-result.txt
diff --git a/Tests/RunCMake/GenEx-DEVICE_LINK/DEVICE_LINK-target_link_directories-stderr.txt b/Tests/RunCMake/GenEx-DEVICE_LINK/DEVICE_LINK-target_link_directories-stderr.txt
new file mode 100644
index 0000000..d924916
--- /dev/null
+++ b/Tests/RunCMake/GenEx-DEVICE_LINK/DEVICE_LINK-target_link_directories-stderr.txt
@@ -0,0 +1,9 @@
+CMake Error at DEVICE_LINK-target_link_directories.cmake:[0-9]+ \(target_link_directories\):
+  Error evaluating generator expression:
+
+    \$<DEVICE_LINK:/DIR>
+
+  \$<DEVICE_LINK:...> may only be used with binary targets to specify link
+  options.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/GenEx-DEVICE_LINK/DEVICE_LINK-target_link_directories.cmake b/Tests/RunCMake/GenEx-DEVICE_LINK/DEVICE_LINK-target_link_directories.cmake
new file mode 100644
index 0000000..e50d27d
--- /dev/null
+++ b/Tests/RunCMake/GenEx-DEVICE_LINK/DEVICE_LINK-target_link_directories.cmake
@@ -0,0 +1,7 @@
+
+enable_language(C)
+
+add_library(lib empty.c)
+
+add_executable(empty empty.c)
+target_link_directories(empty PRIVATE $<DEVICE_LINK:/DIR>)
diff --git a/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-target_sources-result.txt b/Tests/RunCMake/GenEx-DEVICE_LINK/DEVICE_LINK-target_link_libraries-result.txt
similarity index 100%
copy from Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-target_sources-result.txt
copy to Tests/RunCMake/GenEx-DEVICE_LINK/DEVICE_LINK-target_link_libraries-result.txt
diff --git a/Tests/RunCMake/GenEx-DEVICE_LINK/DEVICE_LINK-target_link_libraries-stderr.txt b/Tests/RunCMake/GenEx-DEVICE_LINK/DEVICE_LINK-target_link_libraries-stderr.txt
new file mode 100644
index 0000000..1436fa8
--- /dev/null
+++ b/Tests/RunCMake/GenEx-DEVICE_LINK/DEVICE_LINK-target_link_libraries-stderr.txt
@@ -0,0 +1,9 @@
+CMake Error at DEVICE_LINK-target_link_libraries.cmake:[0-9]+ \(target_link_libraries\):
+  Error evaluating generator expression:
+
+    \$<DEVICE_LINK:lib>
+
+  \$<DEVICE_LINK:...> may only be used with binary targets to specify link
+  options.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/GenEx-DEVICE_LINK/DEVICE_LINK-target_link_libraries.cmake b/Tests/RunCMake/GenEx-DEVICE_LINK/DEVICE_LINK-target_link_libraries.cmake
new file mode 100644
index 0000000..971f562
--- /dev/null
+++ b/Tests/RunCMake/GenEx-DEVICE_LINK/DEVICE_LINK-target_link_libraries.cmake
@@ -0,0 +1,7 @@
+
+enable_language(C)
+
+add_library(lib empty.c)
+
+add_executable(empty empty.c)
+target_link_libraries(empty PRIVATE $<DEVICE_LINK:lib>)
diff --git a/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-target_sources-result.txt b/Tests/RunCMake/GenEx-DEVICE_LINK/DEVICE_LINK-target_sources-result.txt
similarity index 100%
copy from Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-target_sources-result.txt
copy to Tests/RunCMake/GenEx-DEVICE_LINK/DEVICE_LINK-target_sources-result.txt
diff --git a/Tests/RunCMake/GenEx-DEVICE_LINK/DEVICE_LINK-target_sources-stderr.txt b/Tests/RunCMake/GenEx-DEVICE_LINK/DEVICE_LINK-target_sources-stderr.txt
new file mode 100644
index 0000000..c9b602d
--- /dev/null
+++ b/Tests/RunCMake/GenEx-DEVICE_LINK/DEVICE_LINK-target_sources-stderr.txt
@@ -0,0 +1,9 @@
+CMake Error at DEVICE_LINK-target_sources.cmake:[0-9]+ \(target_sources\):
+  Error evaluating generator expression:
+
+    \$<DEVICE_LINK:empty.c>
+
+  \$<DEVICE_LINK:...> may only be used with binary targets to specify link
+  options.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/GenEx-DEVICE_LINK/DEVICE_LINK-target_sources.cmake b/Tests/RunCMake/GenEx-DEVICE_LINK/DEVICE_LINK-target_sources.cmake
new file mode 100644
index 0000000..94bac9e
--- /dev/null
+++ b/Tests/RunCMake/GenEx-DEVICE_LINK/DEVICE_LINK-target_sources.cmake
@@ -0,0 +1,2 @@
+add_library(empty)
+target_sources(empty PRIVATE $<DEVICE_LINK:empty.c>)
diff --git a/Tests/RunCMake/GenEx-DEVICE_LINK/RunCMakeTest.cmake b/Tests/RunCMake/GenEx-DEVICE_LINK/RunCMakeTest.cmake
new file mode 100644
index 0000000..1e44601
--- /dev/null
+++ b/Tests/RunCMake/GenEx-DEVICE_LINK/RunCMakeTest.cmake
@@ -0,0 +1,17 @@
+include(RunCMake)
+
+run_cmake(DEVICE_LINK-add_custom_target)
+run_cmake(DEVICE_LINK-add_custom_command)
+run_cmake(DEVICE_LINK-install)
+run_cmake(DEVICE_LINK-add_executable)
+run_cmake(DEVICE_LINK-add_library)
+run_cmake(DEVICE_LINK-add_test)
+run_cmake(DEVICE_LINK-target_sources)
+run_cmake(DEVICE_LINK-target_compile_definitions)
+run_cmake(DEVICE_LINK-target_compile_options)
+run_cmake(DEVICE_LINK-target_include_directories)
+run_cmake(DEVICE_LINK-target_link_libraries)
+run_cmake(DEVICE_LINK-target_link_directories)
+if(RunCMake_GENERATOR MATCHES "(Ninja|Makefile)")
+  run_cmake(DEVICE_LINK-link_depends)
+endif()
diff --git a/Tests/RunCMake/GenEx-DEVICE_LINK/empty.c b/Tests/RunCMake/GenEx-DEVICE_LINK/empty.c
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/Tests/RunCMake/GenEx-DEVICE_LINK/empty.c
diff --git a/Tests/RunCMake/GenEx-GENEX_EVAL/CMakeLists.txt b/Tests/RunCMake/GenEx-GENEX_EVAL/CMakeLists.txt
new file mode 100644
index 0000000..44025d3
--- /dev/null
+++ b/Tests/RunCMake/GenEx-GENEX_EVAL/CMakeLists.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 3.12)
+project(${RunCMake_TEST} NONE)
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/GeneratorExpression/GENEX_EVAL-check.cmake b/Tests/RunCMake/GenEx-GENEX_EVAL/GENEX_EVAL-check.cmake
similarity index 100%
rename from Tests/RunCMake/GeneratorExpression/GENEX_EVAL-check.cmake
rename to Tests/RunCMake/GenEx-GENEX_EVAL/GENEX_EVAL-check.cmake
diff --git a/Tests/RunCMake/GeneratorExpression/GENEX_EVAL-recursion1-result.txt b/Tests/RunCMake/GenEx-GENEX_EVAL/GENEX_EVAL-recursion1-result.txt
similarity index 100%
rename from Tests/RunCMake/GeneratorExpression/GENEX_EVAL-recursion1-result.txt
rename to Tests/RunCMake/GenEx-GENEX_EVAL/GENEX_EVAL-recursion1-result.txt
diff --git a/Tests/RunCMake/GeneratorExpression/GENEX_EVAL-recursion1-stderr.txt b/Tests/RunCMake/GenEx-GENEX_EVAL/GENEX_EVAL-recursion1-stderr.txt
similarity index 100%
rename from Tests/RunCMake/GeneratorExpression/GENEX_EVAL-recursion1-stderr.txt
rename to Tests/RunCMake/GenEx-GENEX_EVAL/GENEX_EVAL-recursion1-stderr.txt
diff --git a/Tests/RunCMake/GeneratorExpression/GENEX_EVAL-recursion1.cmake b/Tests/RunCMake/GenEx-GENEX_EVAL/GENEX_EVAL-recursion1.cmake
similarity index 100%
rename from Tests/RunCMake/GeneratorExpression/GENEX_EVAL-recursion1.cmake
rename to Tests/RunCMake/GenEx-GENEX_EVAL/GENEX_EVAL-recursion1.cmake
diff --git a/Tests/RunCMake/GeneratorExpression/GENEX_EVAL-recursion2-result.txt b/Tests/RunCMake/GenEx-GENEX_EVAL/GENEX_EVAL-recursion2-result.txt
similarity index 100%
rename from Tests/RunCMake/GeneratorExpression/GENEX_EVAL-recursion2-result.txt
rename to Tests/RunCMake/GenEx-GENEX_EVAL/GENEX_EVAL-recursion2-result.txt
diff --git a/Tests/RunCMake/GeneratorExpression/GENEX_EVAL-recursion2-stderr.txt b/Tests/RunCMake/GenEx-GENEX_EVAL/GENEX_EVAL-recursion2-stderr.txt
similarity index 100%
rename from Tests/RunCMake/GeneratorExpression/GENEX_EVAL-recursion2-stderr.txt
rename to Tests/RunCMake/GenEx-GENEX_EVAL/GENEX_EVAL-recursion2-stderr.txt
diff --git a/Tests/RunCMake/GeneratorExpression/GENEX_EVAL-recursion2.cmake b/Tests/RunCMake/GenEx-GENEX_EVAL/GENEX_EVAL-recursion2.cmake
similarity index 100%
rename from Tests/RunCMake/GeneratorExpression/GENEX_EVAL-recursion2.cmake
rename to Tests/RunCMake/GenEx-GENEX_EVAL/GENEX_EVAL-recursion2.cmake
diff --git a/Tests/RunCMake/GeneratorExpression/GENEX_EVAL.cmake b/Tests/RunCMake/GenEx-GENEX_EVAL/GENEX_EVAL.cmake
similarity index 100%
rename from Tests/RunCMake/GeneratorExpression/GENEX_EVAL.cmake
rename to Tests/RunCMake/GenEx-GENEX_EVAL/GENEX_EVAL.cmake
diff --git a/Tests/RunCMake/GenEx-GENEX_EVAL/RunCMakeTest.cmake b/Tests/RunCMake/GenEx-GENEX_EVAL/RunCMakeTest.cmake
new file mode 100644
index 0000000..d804a56
--- /dev/null
+++ b/Tests/RunCMake/GenEx-GENEX_EVAL/RunCMakeTest.cmake
@@ -0,0 +1,11 @@
+include(RunCMake)
+
+run_cmake(TARGET_GENEX_EVAL-no-arg)
+run_cmake(TARGET_GENEX_EVAL-no-target)
+run_cmake(TARGET_GENEX_EVAL-non-valid-target)
+run_cmake(TARGET_GENEX_EVAL-recursion1)
+run_cmake(TARGET_GENEX_EVAL-recursion2)
+run_cmake(TARGET_GENEX_EVAL)
+run_cmake(GENEX_EVAL-recursion1)
+run_cmake(GENEX_EVAL-recursion2)
+run_cmake(GENEX_EVAL)
diff --git a/Tests/RunCMake/GeneratorExpression/TARGET_GENEX_EVAL-check.cmake b/Tests/RunCMake/GenEx-GENEX_EVAL/TARGET_GENEX_EVAL-check.cmake
similarity index 100%
rename from Tests/RunCMake/GeneratorExpression/TARGET_GENEX_EVAL-check.cmake
rename to Tests/RunCMake/GenEx-GENEX_EVAL/TARGET_GENEX_EVAL-check.cmake
diff --git a/Tests/RunCMake/GeneratorExpression/TARGET_GENEX_EVAL-no-arg-result.txt b/Tests/RunCMake/GenEx-GENEX_EVAL/TARGET_GENEX_EVAL-no-arg-result.txt
similarity index 100%
rename from Tests/RunCMake/GeneratorExpression/TARGET_GENEX_EVAL-no-arg-result.txt
rename to Tests/RunCMake/GenEx-GENEX_EVAL/TARGET_GENEX_EVAL-no-arg-result.txt
diff --git a/Tests/RunCMake/GeneratorExpression/TARGET_GENEX_EVAL-no-arg-stderr.txt b/Tests/RunCMake/GenEx-GENEX_EVAL/TARGET_GENEX_EVAL-no-arg-stderr.txt
similarity index 100%
rename from Tests/RunCMake/GeneratorExpression/TARGET_GENEX_EVAL-no-arg-stderr.txt
rename to Tests/RunCMake/GenEx-GENEX_EVAL/TARGET_GENEX_EVAL-no-arg-stderr.txt
diff --git a/Tests/RunCMake/GeneratorExpression/TARGET_GENEX_EVAL-no-arg.cmake b/Tests/RunCMake/GenEx-GENEX_EVAL/TARGET_GENEX_EVAL-no-arg.cmake
similarity index 100%
rename from Tests/RunCMake/GeneratorExpression/TARGET_GENEX_EVAL-no-arg.cmake
rename to Tests/RunCMake/GenEx-GENEX_EVAL/TARGET_GENEX_EVAL-no-arg.cmake
diff --git a/Tests/RunCMake/GeneratorExpression/TARGET_GENEX_EVAL-no-target-result.txt b/Tests/RunCMake/GenEx-GENEX_EVAL/TARGET_GENEX_EVAL-no-target-result.txt
similarity index 100%
rename from Tests/RunCMake/GeneratorExpression/TARGET_GENEX_EVAL-no-target-result.txt
rename to Tests/RunCMake/GenEx-GENEX_EVAL/TARGET_GENEX_EVAL-no-target-result.txt
diff --git a/Tests/RunCMake/GeneratorExpression/TARGET_GENEX_EVAL-no-target-stderr.txt b/Tests/RunCMake/GenEx-GENEX_EVAL/TARGET_GENEX_EVAL-no-target-stderr.txt
similarity index 100%
rename from Tests/RunCMake/GeneratorExpression/TARGET_GENEX_EVAL-no-target-stderr.txt
rename to Tests/RunCMake/GenEx-GENEX_EVAL/TARGET_GENEX_EVAL-no-target-stderr.txt
diff --git a/Tests/RunCMake/GeneratorExpression/TARGET_GENEX_EVAL-no-target.cmake b/Tests/RunCMake/GenEx-GENEX_EVAL/TARGET_GENEX_EVAL-no-target.cmake
similarity index 100%
rename from Tests/RunCMake/GeneratorExpression/TARGET_GENEX_EVAL-no-target.cmake
rename to Tests/RunCMake/GenEx-GENEX_EVAL/TARGET_GENEX_EVAL-no-target.cmake
diff --git a/Tests/RunCMake/GeneratorExpression/TARGET_GENEX_EVAL-non-valid-target-result.txt b/Tests/RunCMake/GenEx-GENEX_EVAL/TARGET_GENEX_EVAL-non-valid-target-result.txt
similarity index 100%
rename from Tests/RunCMake/GeneratorExpression/TARGET_GENEX_EVAL-non-valid-target-result.txt
rename to Tests/RunCMake/GenEx-GENEX_EVAL/TARGET_GENEX_EVAL-non-valid-target-result.txt
diff --git a/Tests/RunCMake/GeneratorExpression/TARGET_GENEX_EVAL-non-valid-target-stderr.txt b/Tests/RunCMake/GenEx-GENEX_EVAL/TARGET_GENEX_EVAL-non-valid-target-stderr.txt
similarity index 100%
rename from Tests/RunCMake/GeneratorExpression/TARGET_GENEX_EVAL-non-valid-target-stderr.txt
rename to Tests/RunCMake/GenEx-GENEX_EVAL/TARGET_GENEX_EVAL-non-valid-target-stderr.txt
diff --git a/Tests/RunCMake/GeneratorExpression/TARGET_GENEX_EVAL-non-valid-target.cmake b/Tests/RunCMake/GenEx-GENEX_EVAL/TARGET_GENEX_EVAL-non-valid-target.cmake
similarity index 100%
rename from Tests/RunCMake/GeneratorExpression/TARGET_GENEX_EVAL-non-valid-target.cmake
rename to Tests/RunCMake/GenEx-GENEX_EVAL/TARGET_GENEX_EVAL-non-valid-target.cmake
diff --git a/Tests/RunCMake/GeneratorExpression/TARGET_GENEX_EVAL-recursion1-result.txt b/Tests/RunCMake/GenEx-GENEX_EVAL/TARGET_GENEX_EVAL-recursion1-result.txt
similarity index 100%
rename from Tests/RunCMake/GeneratorExpression/TARGET_GENEX_EVAL-recursion1-result.txt
rename to Tests/RunCMake/GenEx-GENEX_EVAL/TARGET_GENEX_EVAL-recursion1-result.txt
diff --git a/Tests/RunCMake/GeneratorExpression/TARGET_GENEX_EVAL-recursion1-stderr.txt b/Tests/RunCMake/GenEx-GENEX_EVAL/TARGET_GENEX_EVAL-recursion1-stderr.txt
similarity index 100%
rename from Tests/RunCMake/GeneratorExpression/TARGET_GENEX_EVAL-recursion1-stderr.txt
rename to Tests/RunCMake/GenEx-GENEX_EVAL/TARGET_GENEX_EVAL-recursion1-stderr.txt
diff --git a/Tests/RunCMake/GeneratorExpression/TARGET_GENEX_EVAL-recursion1.cmake b/Tests/RunCMake/GenEx-GENEX_EVAL/TARGET_GENEX_EVAL-recursion1.cmake
similarity index 100%
rename from Tests/RunCMake/GeneratorExpression/TARGET_GENEX_EVAL-recursion1.cmake
rename to Tests/RunCMake/GenEx-GENEX_EVAL/TARGET_GENEX_EVAL-recursion1.cmake
diff --git a/Tests/RunCMake/GeneratorExpression/TARGET_GENEX_EVAL-recursion2-result.txt b/Tests/RunCMake/GenEx-GENEX_EVAL/TARGET_GENEX_EVAL-recursion2-result.txt
similarity index 100%
rename from Tests/RunCMake/GeneratorExpression/TARGET_GENEX_EVAL-recursion2-result.txt
rename to Tests/RunCMake/GenEx-GENEX_EVAL/TARGET_GENEX_EVAL-recursion2-result.txt
diff --git a/Tests/RunCMake/GeneratorExpression/TARGET_GENEX_EVAL-recursion2-stderr.txt b/Tests/RunCMake/GenEx-GENEX_EVAL/TARGET_GENEX_EVAL-recursion2-stderr.txt
similarity index 100%
rename from Tests/RunCMake/GeneratorExpression/TARGET_GENEX_EVAL-recursion2-stderr.txt
rename to Tests/RunCMake/GenEx-GENEX_EVAL/TARGET_GENEX_EVAL-recursion2-stderr.txt
diff --git a/Tests/RunCMake/GeneratorExpression/TARGET_GENEX_EVAL-recursion2.cmake b/Tests/RunCMake/GenEx-GENEX_EVAL/TARGET_GENEX_EVAL-recursion2.cmake
similarity index 100%
rename from Tests/RunCMake/GeneratorExpression/TARGET_GENEX_EVAL-recursion2.cmake
rename to Tests/RunCMake/GenEx-GENEX_EVAL/TARGET_GENEX_EVAL-recursion2.cmake
diff --git a/Tests/RunCMake/GeneratorExpression/TARGET_GENEX_EVAL.cmake b/Tests/RunCMake/GenEx-GENEX_EVAL/TARGET_GENEX_EVAL.cmake
similarity index 100%
rename from Tests/RunCMake/GeneratorExpression/TARGET_GENEX_EVAL.cmake
rename to Tests/RunCMake/GenEx-GENEX_EVAL/TARGET_GENEX_EVAL.cmake
diff --git a/Tests/RunCMake/GenEx-GENEX_EVAL/empty.c b/Tests/RunCMake/GenEx-GENEX_EVAL/empty.c
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/Tests/RunCMake/GenEx-GENEX_EVAL/empty.c
diff --git a/Tests/RunCMake/GenEx-HOST_LINK/CMakeLists.txt b/Tests/RunCMake/GenEx-HOST_LINK/CMakeLists.txt
new file mode 100644
index 0000000..b646c4a
--- /dev/null
+++ b/Tests/RunCMake/GenEx-HOST_LINK/CMakeLists.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 3.18)
+project(${RunCMake_TEST} NONE)
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_custom_command-result.txt b/Tests/RunCMake/GenEx-HOST_LINK/HOST_LINK-add_custom_command-result.txt
similarity index 100%
copy from Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_custom_command-result.txt
copy to Tests/RunCMake/GenEx-HOST_LINK/HOST_LINK-add_custom_command-result.txt
diff --git a/Tests/RunCMake/GenEx-HOST_LINK/HOST_LINK-add_custom_command-stderr.txt b/Tests/RunCMake/GenEx-HOST_LINK/HOST_LINK-add_custom_command-stderr.txt
new file mode 100644
index 0000000..5ad41b9
--- /dev/null
+++ b/Tests/RunCMake/GenEx-HOST_LINK/HOST_LINK-add_custom_command-stderr.txt
@@ -0,0 +1,9 @@
+CMake Error at HOST_LINK-add_custom_command.cmake:[0-9]+ \(add_custom_command\):
+  Error evaluating generator expression:
+
+    \$<HOST_LINK>
+
+  \$<HOST_LINK:...> may only be used with binary targets to specify link
+  options.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/GenEx-HOST_LINK/HOST_LINK-add_custom_command.cmake b/Tests/RunCMake/GenEx-HOST_LINK/HOST_LINK-add_custom_command.cmake
new file mode 100644
index 0000000..4d6e305
--- /dev/null
+++ b/Tests/RunCMake/GenEx-HOST_LINK/HOST_LINK-add_custom_command.cmake
@@ -0,0 +1,4 @@
+add_custom_target(drive)
+add_custom_command(TARGET drive PRE_BUILD
+  COMMAND ${CMAKE_COMMAND} -E echo $<HOST_LINK>
+)
diff --git a/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_custom_target-result.txt b/Tests/RunCMake/GenEx-HOST_LINK/HOST_LINK-add_custom_target-result.txt
similarity index 100%
copy from Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_custom_target-result.txt
copy to Tests/RunCMake/GenEx-HOST_LINK/HOST_LINK-add_custom_target-result.txt
diff --git a/Tests/RunCMake/GenEx-HOST_LINK/HOST_LINK-add_custom_target-stderr.txt b/Tests/RunCMake/GenEx-HOST_LINK/HOST_LINK-add_custom_target-stderr.txt
new file mode 100644
index 0000000..c44202a
--- /dev/null
+++ b/Tests/RunCMake/GenEx-HOST_LINK/HOST_LINK-add_custom_target-stderr.txt
@@ -0,0 +1,9 @@
+CMake Error at HOST_LINK-add_custom_target.cmake:[0-9]+ \(add_custom_target\):
+  Error evaluating generator expression:
+
+    \$<HOST_LINK>
+
+  \$<HOST_LINK:...> may only be used with binary targets to specify link
+  options.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/GenEx-HOST_LINK/HOST_LINK-add_custom_target.cmake b/Tests/RunCMake/GenEx-HOST_LINK/HOST_LINK-add_custom_target.cmake
new file mode 100644
index 0000000..eec072a
--- /dev/null
+++ b/Tests/RunCMake/GenEx-HOST_LINK/HOST_LINK-add_custom_target.cmake
@@ -0,0 +1,3 @@
+add_custom_target(drive
+  COMMAND ${CMAKE_COMMAND} -E echo $<HOST_LINK>
+)
diff --git a/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_executable-result.txt b/Tests/RunCMake/GenEx-HOST_LINK/HOST_LINK-add_executable-result.txt
similarity index 100%
copy from Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_executable-result.txt
copy to Tests/RunCMake/GenEx-HOST_LINK/HOST_LINK-add_executable-result.txt
diff --git a/Tests/RunCMake/GenEx-HOST_LINK/HOST_LINK-add_executable-stderr.txt b/Tests/RunCMake/GenEx-HOST_LINK/HOST_LINK-add_executable-stderr.txt
new file mode 100644
index 0000000..b395515
--- /dev/null
+++ b/Tests/RunCMake/GenEx-HOST_LINK/HOST_LINK-add_executable-stderr.txt
@@ -0,0 +1,9 @@
+CMake Error at HOST_LINK-add_executable.cmake:[0-9]+ \(add_executable\):
+  Error evaluating generator expression:
+
+    \$<HOST_LINK:empty.c>
+
+  \$<HOST_LINK:...> may only be used with binary targets to specify link
+  options.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/GenEx-HOST_LINK/HOST_LINK-add_executable.cmake b/Tests/RunCMake/GenEx-HOST_LINK/HOST_LINK-add_executable.cmake
new file mode 100644
index 0000000..c9f74a5
--- /dev/null
+++ b/Tests/RunCMake/GenEx-HOST_LINK/HOST_LINK-add_executable.cmake
@@ -0,0 +1 @@
+add_executable(empty $<HOST_LINK:empty.c>)
diff --git a/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_library-result.txt b/Tests/RunCMake/GenEx-HOST_LINK/HOST_LINK-add_library-result.txt
similarity index 100%
copy from Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_library-result.txt
copy to Tests/RunCMake/GenEx-HOST_LINK/HOST_LINK-add_library-result.txt
diff --git a/Tests/RunCMake/GenEx-HOST_LINK/HOST_LINK-add_library-stderr.txt b/Tests/RunCMake/GenEx-HOST_LINK/HOST_LINK-add_library-stderr.txt
new file mode 100644
index 0000000..4bd27be
--- /dev/null
+++ b/Tests/RunCMake/GenEx-HOST_LINK/HOST_LINK-add_library-stderr.txt
@@ -0,0 +1,9 @@
+CMake Error at HOST_LINK-add_library.cmake:[0-9]+ \(add_library\):
+  Error evaluating generator expression:
+
+    \$<HOST_LINK:empty.c>
+
+  \$<HOST_LINK:...> may only be used with binary targets to specify link
+  options.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/GenEx-HOST_LINK/HOST_LINK-add_library.cmake b/Tests/RunCMake/GenEx-HOST_LINK/HOST_LINK-add_library.cmake
new file mode 100644
index 0000000..44135af
--- /dev/null
+++ b/Tests/RunCMake/GenEx-HOST_LINK/HOST_LINK-add_library.cmake
@@ -0,0 +1 @@
+add_library(empty $<HOST_LINK:empty.c>)
diff --git a/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_test-result.txt b/Tests/RunCMake/GenEx-HOST_LINK/HOST_LINK-add_test-result.txt
similarity index 100%
copy from Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_test-result.txt
copy to Tests/RunCMake/GenEx-HOST_LINK/HOST_LINK-add_test-result.txt
diff --git a/Tests/RunCMake/GenEx-HOST_LINK/HOST_LINK-add_test-stderr.txt b/Tests/RunCMake/GenEx-HOST_LINK/HOST_LINK-add_test-stderr.txt
new file mode 100644
index 0000000..012ad21
--- /dev/null
+++ b/Tests/RunCMake/GenEx-HOST_LINK/HOST_LINK-add_test-stderr.txt
@@ -0,0 +1,9 @@
+CMake Error at HOST_LINK-add_test.cmake:[0-9]+ \(add_test\):
+  Error evaluating generator expression:
+
+    \$<HOST_LINK>
+
+  \$<HOST_LINK:...> may only be used with binary targets to specify link
+  options.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/GenEx-HOST_LINK/HOST_LINK-add_test.cmake b/Tests/RunCMake/GenEx-HOST_LINK/HOST_LINK-add_test.cmake
new file mode 100644
index 0000000..4b472af
--- /dev/null
+++ b/Tests/RunCMake/GenEx-HOST_LINK/HOST_LINK-add_test.cmake
@@ -0,0 +1,5 @@
+
+include(CTest)
+enable_testing()
+
+add_test(NAME dummy COMMAND ${CMAKE_COMMAND} -E echo $<HOST_LINK>)
diff --git a/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-install-result.txt b/Tests/RunCMake/GenEx-HOST_LINK/HOST_LINK-install-result.txt
similarity index 100%
copy from Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-install-result.txt
copy to Tests/RunCMake/GenEx-HOST_LINK/HOST_LINK-install-result.txt
diff --git a/Tests/RunCMake/GenEx-HOST_LINK/HOST_LINK-install-stderr.txt b/Tests/RunCMake/GenEx-HOST_LINK/HOST_LINK-install-stderr.txt
new file mode 100644
index 0000000..c265ec4
--- /dev/null
+++ b/Tests/RunCMake/GenEx-HOST_LINK/HOST_LINK-install-stderr.txt
@@ -0,0 +1,7 @@
+CMake Error:
+  Error evaluating generator expression:
+
+    \$<HOST_LINK:empty>
+
+  \$<HOST_LINK:...> may only be used with binary targets to specify link
+  options.
diff --git a/Tests/RunCMake/GenEx-HOST_LINK/HOST_LINK-install.cmake b/Tests/RunCMake/GenEx-HOST_LINK/HOST_LINK-install.cmake
new file mode 100644
index 0000000..b4dff68
--- /dev/null
+++ b/Tests/RunCMake/GenEx-HOST_LINK/HOST_LINK-install.cmake
@@ -0,0 +1,5 @@
+
+install(FILES
+  $<HOST_LINK:empty>
+  DESTINATION src
+)
diff --git a/Tests/RunCMake/interface_library/target_commands-result.txt b/Tests/RunCMake/GenEx-HOST_LINK/HOST_LINK-link_depends-result.txt
similarity index 100%
copy from Tests/RunCMake/interface_library/target_commands-result.txt
copy to Tests/RunCMake/GenEx-HOST_LINK/HOST_LINK-link_depends-result.txt
diff --git a/Tests/RunCMake/GenEx-HOST_LINK/HOST_LINK-link_depends-stderr.txt b/Tests/RunCMake/GenEx-HOST_LINK/HOST_LINK-link_depends-stderr.txt
new file mode 100644
index 0000000..24b8b82
--- /dev/null
+++ b/Tests/RunCMake/GenEx-HOST_LINK/HOST_LINK-link_depends-stderr.txt
@@ -0,0 +1,7 @@
+CMake Error:
+  Error evaluating generator expression:
+
+    \$<HOST_LINK:lib>
+
+  \$<HOST_LINK:...> may only be used with binary targets to specify link
+  options.
diff --git a/Tests/RunCMake/GenEx-HOST_LINK/HOST_LINK-link_depends.cmake b/Tests/RunCMake/GenEx-HOST_LINK/HOST_LINK-link_depends.cmake
new file mode 100644
index 0000000..0402f43
--- /dev/null
+++ b/Tests/RunCMake/GenEx-HOST_LINK/HOST_LINK-link_depends.cmake
@@ -0,0 +1,7 @@
+
+enable_language(C)
+
+add_library(lib empty.c)
+
+add_executable(empty empty.c)
+set_property(TARGET empty PROPERTY LINK_DEPENDS $<HOST_LINK:lib>)
diff --git a/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-target_sources-result.txt b/Tests/RunCMake/GenEx-HOST_LINK/HOST_LINK-target_compile_definitions-result.txt
similarity index 100%
copy from Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-target_sources-result.txt
copy to Tests/RunCMake/GenEx-HOST_LINK/HOST_LINK-target_compile_definitions-result.txt
diff --git a/Tests/RunCMake/GenEx-HOST_LINK/HOST_LINK-target_compile_definitions-stderr.txt b/Tests/RunCMake/GenEx-HOST_LINK/HOST_LINK-target_compile_definitions-stderr.txt
new file mode 100644
index 0000000..6ab3c14
--- /dev/null
+++ b/Tests/RunCMake/GenEx-HOST_LINK/HOST_LINK-target_compile_definitions-stderr.txt
@@ -0,0 +1,9 @@
+CMake Error at HOST_LINK-target_compile_definitions.cmake:[0-9]+ \(target_compile_definitions\):
+  Error evaluating generator expression:
+
+    \$<HOST_LINK:DEF>
+
+  \$<HOST_LINK:...> may only be used with binary targets to specify link
+  options.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/GenEx-HOST_LINK/HOST_LINK-target_compile_definitions.cmake b/Tests/RunCMake/GenEx-HOST_LINK/HOST_LINK-target_compile_definitions.cmake
new file mode 100644
index 0000000..f6c130d
--- /dev/null
+++ b/Tests/RunCMake/GenEx-HOST_LINK/HOST_LINK-target_compile_definitions.cmake
@@ -0,0 +1,4 @@
+
+enable_language(C)
+add_executable(empty empty.c)
+target_compile_definitions(empty PRIVATE $<HOST_LINK:DEF>)
diff --git a/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-target_sources-result.txt b/Tests/RunCMake/GenEx-HOST_LINK/HOST_LINK-target_compile_options-result.txt
similarity index 100%
copy from Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-target_sources-result.txt
copy to Tests/RunCMake/GenEx-HOST_LINK/HOST_LINK-target_compile_options-result.txt
diff --git a/Tests/RunCMake/GenEx-HOST_LINK/HOST_LINK-target_compile_options-stderr.txt b/Tests/RunCMake/GenEx-HOST_LINK/HOST_LINK-target_compile_options-stderr.txt
new file mode 100644
index 0000000..0f5bbc3
--- /dev/null
+++ b/Tests/RunCMake/GenEx-HOST_LINK/HOST_LINK-target_compile_options-stderr.txt
@@ -0,0 +1,9 @@
+CMake Error at HOST_LINK-target_compile_options.cmake:[0-9]+ \(target_compile_options\):
+  Error evaluating generator expression:
+
+    \$<HOST_LINK:-OPT>
+
+  \$<HOST_LINK:...> may only be used with binary targets to specify link
+  options.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/GenEx-HOST_LINK/HOST_LINK-target_compile_options.cmake b/Tests/RunCMake/GenEx-HOST_LINK/HOST_LINK-target_compile_options.cmake
new file mode 100644
index 0000000..53afea1
--- /dev/null
+++ b/Tests/RunCMake/GenEx-HOST_LINK/HOST_LINK-target_compile_options.cmake
@@ -0,0 +1,4 @@
+
+enable_language(C)
+add_executable(empty empty.c)
+target_compile_options(empty PRIVATE $<HOST_LINK:-OPT>)
diff --git a/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-target_sources-result.txt b/Tests/RunCMake/GenEx-HOST_LINK/HOST_LINK-target_include_directories-result.txt
similarity index 100%
copy from Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-target_sources-result.txt
copy to Tests/RunCMake/GenEx-HOST_LINK/HOST_LINK-target_include_directories-result.txt
diff --git a/Tests/RunCMake/GenEx-HOST_LINK/HOST_LINK-target_include_directories-stderr.txt b/Tests/RunCMake/GenEx-HOST_LINK/HOST_LINK-target_include_directories-stderr.txt
new file mode 100644
index 0000000..9a2634a
--- /dev/null
+++ b/Tests/RunCMake/GenEx-HOST_LINK/HOST_LINK-target_include_directories-stderr.txt
@@ -0,0 +1,9 @@
+CMake Error at HOST_LINK-target_include_directories.cmake:[0-9]+ \(target_include_directories\):
+  Error evaluating generator expression:
+
+    \$<HOST_LINK:/DIR>
+
+  \$<HOST_LINK:...> may only be used with binary targets to specify link
+  options.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/GenEx-HOST_LINK/HOST_LINK-target_include_directories.cmake b/Tests/RunCMake/GenEx-HOST_LINK/HOST_LINK-target_include_directories.cmake
new file mode 100644
index 0000000..aff1009
--- /dev/null
+++ b/Tests/RunCMake/GenEx-HOST_LINK/HOST_LINK-target_include_directories.cmake
@@ -0,0 +1,4 @@
+
+enable_language(C)
+add_executable(empty empty.c)
+target_include_directories(empty PRIVATE $<HOST_LINK:/DIR>)
diff --git a/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-target_sources-result.txt b/Tests/RunCMake/GenEx-HOST_LINK/HOST_LINK-target_link_directories-result.txt
similarity index 100%
copy from Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-target_sources-result.txt
copy to Tests/RunCMake/GenEx-HOST_LINK/HOST_LINK-target_link_directories-result.txt
diff --git a/Tests/RunCMake/GenEx-HOST_LINK/HOST_LINK-target_link_directories-stderr.txt b/Tests/RunCMake/GenEx-HOST_LINK/HOST_LINK-target_link_directories-stderr.txt
new file mode 100644
index 0000000..5225a52
--- /dev/null
+++ b/Tests/RunCMake/GenEx-HOST_LINK/HOST_LINK-target_link_directories-stderr.txt
@@ -0,0 +1,9 @@
+CMake Error at HOST_LINK-target_link_directories.cmake:[0-9]+ \(target_link_directories\):
+  Error evaluating generator expression:
+
+    \$<HOST_LINK:/DIR>
+
+  \$<HOST_LINK:...> may only be used with binary targets to specify link
+  options.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/GenEx-HOST_LINK/HOST_LINK-target_link_directories.cmake b/Tests/RunCMake/GenEx-HOST_LINK/HOST_LINK-target_link_directories.cmake
new file mode 100644
index 0000000..97488ee
--- /dev/null
+++ b/Tests/RunCMake/GenEx-HOST_LINK/HOST_LINK-target_link_directories.cmake
@@ -0,0 +1,7 @@
+
+enable_language(C)
+
+add_library(lib empty.c)
+
+add_executable(empty empty.c)
+target_link_directories(empty PRIVATE $<HOST_LINK:/DIR>)
diff --git a/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-target_sources-result.txt b/Tests/RunCMake/GenEx-HOST_LINK/HOST_LINK-target_link_libraries-result.txt
similarity index 100%
copy from Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-target_sources-result.txt
copy to Tests/RunCMake/GenEx-HOST_LINK/HOST_LINK-target_link_libraries-result.txt
diff --git a/Tests/RunCMake/GenEx-HOST_LINK/HOST_LINK-target_link_libraries-stderr.txt b/Tests/RunCMake/GenEx-HOST_LINK/HOST_LINK-target_link_libraries-stderr.txt
new file mode 100644
index 0000000..6c4441f
--- /dev/null
+++ b/Tests/RunCMake/GenEx-HOST_LINK/HOST_LINK-target_link_libraries-stderr.txt
@@ -0,0 +1,9 @@
+CMake Error at HOST_LINK-target_link_libraries.cmake:[0-9]+ \(target_link_libraries\):
+  Error evaluating generator expression:
+
+    \$<HOST_LINK:lib>
+
+  \$<HOST_LINK:...> may only be used with binary targets to specify link
+  options.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/GenEx-HOST_LINK/HOST_LINK-target_link_libraries.cmake b/Tests/RunCMake/GenEx-HOST_LINK/HOST_LINK-target_link_libraries.cmake
new file mode 100644
index 0000000..d74c92d
--- /dev/null
+++ b/Tests/RunCMake/GenEx-HOST_LINK/HOST_LINK-target_link_libraries.cmake
@@ -0,0 +1,7 @@
+
+enable_language(C)
+
+add_library(lib empty.c)
+
+add_executable(empty empty.c)
+target_link_libraries(empty PRIVATE $<HOST_LINK:lib>)
diff --git a/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-target_sources-result.txt b/Tests/RunCMake/GenEx-HOST_LINK/HOST_LINK-target_sources-result.txt
similarity index 100%
copy from Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-target_sources-result.txt
copy to Tests/RunCMake/GenEx-HOST_LINK/HOST_LINK-target_sources-result.txt
diff --git a/Tests/RunCMake/GenEx-HOST_LINK/HOST_LINK-target_sources-stderr.txt b/Tests/RunCMake/GenEx-HOST_LINK/HOST_LINK-target_sources-stderr.txt
new file mode 100644
index 0000000..0e25568
--- /dev/null
+++ b/Tests/RunCMake/GenEx-HOST_LINK/HOST_LINK-target_sources-stderr.txt
@@ -0,0 +1,9 @@
+CMake Error at HOST_LINK-target_sources.cmake:[0-9]+ \(target_sources\):
+  Error evaluating generator expression:
+
+    \$<HOST_LINK:empty.c>
+
+  \$<HOST_LINK:...> may only be used with binary targets to specify link
+  options.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/GenEx-HOST_LINK/HOST_LINK-target_sources.cmake b/Tests/RunCMake/GenEx-HOST_LINK/HOST_LINK-target_sources.cmake
new file mode 100644
index 0000000..ea7bf55
--- /dev/null
+++ b/Tests/RunCMake/GenEx-HOST_LINK/HOST_LINK-target_sources.cmake
@@ -0,0 +1,2 @@
+add_library(empty)
+target_sources(empty PRIVATE $<HOST_LINK:empty.c>)
diff --git a/Tests/RunCMake/GenEx-HOST_LINK/RunCMakeTest.cmake b/Tests/RunCMake/GenEx-HOST_LINK/RunCMakeTest.cmake
new file mode 100644
index 0000000..329a7c6
--- /dev/null
+++ b/Tests/RunCMake/GenEx-HOST_LINK/RunCMakeTest.cmake
@@ -0,0 +1,17 @@
+include(RunCMake)
+
+run_cmake(HOST_LINK-add_custom_target)
+run_cmake(HOST_LINK-add_custom_command)
+run_cmake(HOST_LINK-install)
+run_cmake(HOST_LINK-add_executable)
+run_cmake(HOST_LINK-add_library)
+run_cmake(HOST_LINK-add_test)
+run_cmake(HOST_LINK-target_sources)
+run_cmake(HOST_LINK-target_compile_definitions)
+run_cmake(HOST_LINK-target_compile_options)
+run_cmake(HOST_LINK-target_include_directories)
+run_cmake(HOST_LINK-target_link_libraries)
+run_cmake(HOST_LINK-target_link_directories)
+if(RunCMake_GENERATOR MATCHES "(Ninja|Makefile)")
+  run_cmake(HOST_LINK-link_depends)
+endif()
diff --git a/Tests/RunCMake/GenEx-HOST_LINK/empty.c b/Tests/RunCMake/GenEx-HOST_LINK/empty.c
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/Tests/RunCMake/GenEx-HOST_LINK/empty.c
diff --git a/Tests/RunCMake/GenEx-LINK_LANGUAGE/CMakeLists.txt b/Tests/RunCMake/GenEx-LINK_LANGUAGE/CMakeLists.txt
new file mode 100644
index 0000000..b646c4a
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LINK_LANGUAGE/CMakeLists.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 3.18)
+project(${RunCMake_TEST} NONE)
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_custom_command-result.txt b/Tests/RunCMake/GenEx-LINK_LANGUAGE/LINK_LANGUAGE-add_custom_command-result.txt
similarity index 100%
copy from Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_custom_command-result.txt
copy to Tests/RunCMake/GenEx-LINK_LANGUAGE/LINK_LANGUAGE-add_custom_command-result.txt
diff --git a/Tests/RunCMake/GenEx-LINK_LANGUAGE/LINK_LANGUAGE-add_custom_command-stderr.txt b/Tests/RunCMake/GenEx-LINK_LANGUAGE/LINK_LANGUAGE-add_custom_command-stderr.txt
new file mode 100644
index 0000000..0b0d458
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LINK_LANGUAGE/LINK_LANGUAGE-add_custom_command-stderr.txt
@@ -0,0 +1,9 @@
+CMake Error at LINK_LANGUAGE-add_custom_command.cmake:2 \(add_custom_command\):
+  Error evaluating generator expression:
+
+    \$<LINK_LANGUAGE>
+
+  \$<LINK_LANGUAGE:...> may only be used with binary targets to specify link
+  libraries, link directories, link options and link depends.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/GenEx-LINK_LANGUAGE/LINK_LANGUAGE-add_custom_command.cmake b/Tests/RunCMake/GenEx-LINK_LANGUAGE/LINK_LANGUAGE-add_custom_command.cmake
new file mode 100644
index 0000000..a378c1c
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LINK_LANGUAGE/LINK_LANGUAGE-add_custom_command.cmake
@@ -0,0 +1,4 @@
+add_custom_target(drive)
+add_custom_command(TARGET drive PRE_BUILD
+  COMMAND ${CMAKE_COMMAND} -E echo $<LINK_LANGUAGE>
+)
diff --git a/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_custom_target-result.txt b/Tests/RunCMake/GenEx-LINK_LANGUAGE/LINK_LANGUAGE-add_custom_target-result.txt
similarity index 100%
copy from Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_custom_target-result.txt
copy to Tests/RunCMake/GenEx-LINK_LANGUAGE/LINK_LANGUAGE-add_custom_target-result.txt
diff --git a/Tests/RunCMake/GenEx-LINK_LANGUAGE/LINK_LANGUAGE-add_custom_target-stderr.txt b/Tests/RunCMake/GenEx-LINK_LANGUAGE/LINK_LANGUAGE-add_custom_target-stderr.txt
new file mode 100644
index 0000000..92da634
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LINK_LANGUAGE/LINK_LANGUAGE-add_custom_target-stderr.txt
@@ -0,0 +1,9 @@
+CMake Error at LINK_LANGUAGE-add_custom_target.cmake:1 \(add_custom_target\):
+  Error evaluating generator expression:
+
+    \$<LINK_LANGUAGE>
+
+  \$<LINK_LANGUAGE:...> may only be used with binary targets to specify link
+  libraries, link directories, link options and link depends.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/GenEx-LINK_LANGUAGE/LINK_LANGUAGE-add_custom_target.cmake b/Tests/RunCMake/GenEx-LINK_LANGUAGE/LINK_LANGUAGE-add_custom_target.cmake
new file mode 100644
index 0000000..60b6c75
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LINK_LANGUAGE/LINK_LANGUAGE-add_custom_target.cmake
@@ -0,0 +1,3 @@
+add_custom_target(drive
+  COMMAND ${CMAKE_COMMAND} -E echo $<LINK_LANGUAGE>
+)
diff --git a/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_executable-result.txt b/Tests/RunCMake/GenEx-LINK_LANGUAGE/LINK_LANGUAGE-add_executable-result.txt
similarity index 100%
copy from Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_executable-result.txt
copy to Tests/RunCMake/GenEx-LINK_LANGUAGE/LINK_LANGUAGE-add_executable-result.txt
diff --git a/Tests/RunCMake/GenEx-LINK_LANGUAGE/LINK_LANGUAGE-add_executable-stderr.txt b/Tests/RunCMake/GenEx-LINK_LANGUAGE/LINK_LANGUAGE-add_executable-stderr.txt
new file mode 100644
index 0000000..3bdc8e4
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LINK_LANGUAGE/LINK_LANGUAGE-add_executable-stderr.txt
@@ -0,0 +1,9 @@
+CMake Error at LINK_LANGUAGE-add_executable.cmake:1 \(add_executable\):
+  Error evaluating generator expression:
+
+    \$<LINK_LANGUAGE>
+
+  \$<LINK_LANGUAGE:...> may only be used with binary targets to specify link
+  libraries, link directories, link options and link depends.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/GenEx-LINK_LANGUAGE/LINK_LANGUAGE-add_executable.cmake b/Tests/RunCMake/GenEx-LINK_LANGUAGE/LINK_LANGUAGE-add_executable.cmake
new file mode 100644
index 0000000..2176b39
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LINK_LANGUAGE/LINK_LANGUAGE-add_executable.cmake
@@ -0,0 +1 @@
+add_executable(empty empty.$<LINK_LANGUAGE>)
diff --git a/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_library-result.txt b/Tests/RunCMake/GenEx-LINK_LANGUAGE/LINK_LANGUAGE-add_library-result.txt
similarity index 100%
copy from Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_library-result.txt
copy to Tests/RunCMake/GenEx-LINK_LANGUAGE/LINK_LANGUAGE-add_library-result.txt
diff --git a/Tests/RunCMake/GenEx-LINK_LANGUAGE/LINK_LANGUAGE-add_library-stderr.txt b/Tests/RunCMake/GenEx-LINK_LANGUAGE/LINK_LANGUAGE-add_library-stderr.txt
new file mode 100644
index 0000000..1bacdeb
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LINK_LANGUAGE/LINK_LANGUAGE-add_library-stderr.txt
@@ -0,0 +1,9 @@
+CMake Error at LINK_LANGUAGE-add_library.cmake:1 \(add_library\):
+  Error evaluating generator expression:
+
+    \$<LINK_LANGUAGE>
+
+  \$<LINK_LANGUAGE:...> may only be used with binary targets to specify link
+  libraries, link directories, link options and link depends.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/GenEx-LINK_LANGUAGE/LINK_LANGUAGE-add_library.cmake b/Tests/RunCMake/GenEx-LINK_LANGUAGE/LINK_LANGUAGE-add_library.cmake
new file mode 100644
index 0000000..253f82a
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LINK_LANGUAGE/LINK_LANGUAGE-add_library.cmake
@@ -0,0 +1 @@
+add_library(empty empty.$<LINK_LANGUAGE>)
diff --git a/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_test-result.txt b/Tests/RunCMake/GenEx-LINK_LANGUAGE/LINK_LANGUAGE-add_test-result.txt
similarity index 100%
copy from Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_test-result.txt
copy to Tests/RunCMake/GenEx-LINK_LANGUAGE/LINK_LANGUAGE-add_test-result.txt
diff --git a/Tests/RunCMake/GenEx-LINK_LANGUAGE/LINK_LANGUAGE-add_test-stderr.txt b/Tests/RunCMake/GenEx-LINK_LANGUAGE/LINK_LANGUAGE-add_test-stderr.txt
new file mode 100644
index 0000000..f22efde
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LINK_LANGUAGE/LINK_LANGUAGE-add_test-stderr.txt
@@ -0,0 +1,9 @@
+CMake Error at LINK_LANGUAGE-add_test.cmake:5 \(add_test\):
+  Error evaluating generator expression:
+
+    \$<LINK_LANGUAGE>
+
+  \$<LINK_LANGUAGE:...> may only be used with binary targets to specify link
+  libraries, link directories, link options and link depends.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/GenEx-LINK_LANGUAGE/LINK_LANGUAGE-add_test.cmake b/Tests/RunCMake/GenEx-LINK_LANGUAGE/LINK_LANGUAGE-add_test.cmake
new file mode 100644
index 0000000..4fd547d
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LINK_LANGUAGE/LINK_LANGUAGE-add_test.cmake
@@ -0,0 +1,5 @@
+
+include(CTest)
+enable_testing()
+
+add_test(NAME dummy COMMAND ${CMAKE_COMMAND} -E echo $<LINK_LANGUAGE>)
diff --git a/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_executable-result.txt b/Tests/RunCMake/GenEx-LINK_LANGUAGE/LINK_LANGUAGE-file_generate-result.txt
similarity index 100%
copy from Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_executable-result.txt
copy to Tests/RunCMake/GenEx-LINK_LANGUAGE/LINK_LANGUAGE-file_generate-result.txt
diff --git a/Tests/RunCMake/GenEx-LINK_LANGUAGE/LINK_LANGUAGE-file_generate-stderr.txt b/Tests/RunCMake/GenEx-LINK_LANGUAGE/LINK_LANGUAGE-file_generate-stderr.txt
new file mode 100644
index 0000000..21d26de
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LINK_LANGUAGE/LINK_LANGUAGE-file_generate-stderr.txt
@@ -0,0 +1,9 @@
+CMake Error at LINK_LANGUAGE-file_generate.cmake:3 \(file\):
+  Error evaluating generator expression:
+
+    \$<LINK_LANGUAGE>
+
+  \$<LINK_LANGUAGE:...> may only be used with binary targets to specify link
+  libraries, link directories, link options and link depends.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/GenEx-LINK_LANGUAGE/LINK_LANGUAGE-file_generate.cmake b/Tests/RunCMake/GenEx-LINK_LANGUAGE/LINK_LANGUAGE-file_generate.cmake
new file mode 100644
index 0000000..519b883
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LINK_LANGUAGE/LINK_LANGUAGE-file_generate.cmake
@@ -0,0 +1,6 @@
+enable_language(CXX C)
+
+file(GENERATE
+  OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/output.txt
+  CONTENT "LANG_IS_$<LINK_LANGUAGE>\n"
+)
diff --git a/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-install-result.txt b/Tests/RunCMake/GenEx-LINK_LANGUAGE/LINK_LANGUAGE-install-result.txt
similarity index 100%
copy from Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-install-result.txt
copy to Tests/RunCMake/GenEx-LINK_LANGUAGE/LINK_LANGUAGE-install-result.txt
diff --git a/Tests/RunCMake/GenEx-LINK_LANGUAGE/LINK_LANGUAGE-install-stderr.txt b/Tests/RunCMake/GenEx-LINK_LANGUAGE/LINK_LANGUAGE-install-stderr.txt
new file mode 100644
index 0000000..73afc33
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LINK_LANGUAGE/LINK_LANGUAGE-install-stderr.txt
@@ -0,0 +1,10 @@
+CMake Error:
+  Error evaluating generator expression:
+
+    \$<LINK_LANGUAGE>
+
+  \$<LINK_LANGUAGE:...> may only be used with binary targets to specify link
+  libraries, link directories, link options and link depends.
+
+
+CMake Generate step failed.  Build files cannot be regenerated correctly.
diff --git a/Tests/RunCMake/GenEx-LINK_LANGUAGE/LINK_LANGUAGE-install.cmake b/Tests/RunCMake/GenEx-LINK_LANGUAGE/LINK_LANGUAGE-install.cmake
new file mode 100644
index 0000000..533c0b4
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LINK_LANGUAGE/LINK_LANGUAGE-install.cmake
@@ -0,0 +1,5 @@
+
+install(FILES
+  empty.$<LINK_LANGUAGE>
+  DESTINATION src
+)
diff --git a/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-target_sources-result.txt b/Tests/RunCMake/GenEx-LINK_LANGUAGE/LINK_LANGUAGE-target_sources-result.txt
similarity index 100%
copy from Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-target_sources-result.txt
copy to Tests/RunCMake/GenEx-LINK_LANGUAGE/LINK_LANGUAGE-target_sources-result.txt
diff --git a/Tests/RunCMake/GenEx-LINK_LANGUAGE/LINK_LANGUAGE-target_sources-stderr.txt b/Tests/RunCMake/GenEx-LINK_LANGUAGE/LINK_LANGUAGE-target_sources-stderr.txt
new file mode 100644
index 0000000..d8121cc
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LINK_LANGUAGE/LINK_LANGUAGE-target_sources-stderr.txt
@@ -0,0 +1,9 @@
+CMake Error at LINK_LANGUAGE-target_sources.cmake:2 \(target_sources\):
+  Error evaluating generator expression:
+
+    \$<LINK_LANGUAGE>
+
+  \$<LINK_LANGUAGE:...> may only be used with binary targets to specify link
+  libraries, link directories, link options and link depends.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/GenEx-LINK_LANGUAGE/LINK_LANGUAGE-target_sources.cmake b/Tests/RunCMake/GenEx-LINK_LANGUAGE/LINK_LANGUAGE-target_sources.cmake
new file mode 100644
index 0000000..c134c01
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LINK_LANGUAGE/LINK_LANGUAGE-target_sources.cmake
@@ -0,0 +1,2 @@
+add_library(empty)
+target_sources(empty PRIVATE empty.$<LINK_LANGUAGE>)
diff --git a/Tests/RunCMake/GenEx-LINK_LANGUAGE/LINK_LANGUAGE-unknown-lang.cmake b/Tests/RunCMake/GenEx-LINK_LANGUAGE/LINK_LANGUAGE-unknown-lang.cmake
new file mode 100644
index 0000000..0ba472d
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LINK_LANGUAGE/LINK_LANGUAGE-unknown-lang.cmake
@@ -0,0 +1,4 @@
+
+enable_language(C)
+add_executable(empty empty.c)
+target_link_options(empty PRIVATE $<$<LINK_LANGUAGE:CXX>:$<TARGET_EXISTS:too,many,parameters>>)
diff --git a/Tests/RunCMake/GeneratorExpression/GENEX_EVAL-recursion1-result.txt b/Tests/RunCMake/GenEx-LINK_LANGUAGE/LINK_LANGUAGE-wrong-usage1-result.txt
similarity index 100%
copy from Tests/RunCMake/GeneratorExpression/GENEX_EVAL-recursion1-result.txt
copy to Tests/RunCMake/GenEx-LINK_LANGUAGE/LINK_LANGUAGE-wrong-usage1-result.txt
diff --git a/Tests/RunCMake/GenEx-LINK_LANGUAGE/LINK_LANGUAGE-wrong-usage1-stderr.txt b/Tests/RunCMake/GenEx-LINK_LANGUAGE/LINK_LANGUAGE-wrong-usage1-stderr.txt
new file mode 100644
index 0000000..1e3a83b
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LINK_LANGUAGE/LINK_LANGUAGE-wrong-usage1-stderr.txt
@@ -0,0 +1,9 @@
+CMake Error at LINK_LANGUAGE-wrong-usage1.cmake:4 \(target_compile_definitions\):
+  Error evaluating generator expression:
+
+    \$<LINK_LANGUAGE:C>
+
+  \$<LINK_LANGUAGE:...> may only be used with binary targets to specify link
+  libraries, link directories, link options and link depends.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/GenEx-LINK_LANGUAGE/LINK_LANGUAGE-wrong-usage1.cmake b/Tests/RunCMake/GenEx-LINK_LANGUAGE/LINK_LANGUAGE-wrong-usage1.cmake
new file mode 100644
index 0000000..90b7ce0
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LINK_LANGUAGE/LINK_LANGUAGE-wrong-usage1.cmake
@@ -0,0 +1,4 @@
+
+enable_language(C)
+add_executable(empty empty.c)
+target_compile_definitions(empty PRIVATE $<$<LINK_LANGUAGE:C>:DEF>)
diff --git a/Tests/RunCMake/GeneratorExpression/GENEX_EVAL-recursion2-result.txt b/Tests/RunCMake/GenEx-LINK_LANGUAGE/LINK_LANGUAGE-wrong-usage2-result.txt
similarity index 100%
copy from Tests/RunCMake/GeneratorExpression/GENEX_EVAL-recursion2-result.txt
copy to Tests/RunCMake/GenEx-LINK_LANGUAGE/LINK_LANGUAGE-wrong-usage2-result.txt
diff --git a/Tests/RunCMake/GenEx-LINK_LANGUAGE/LINK_LANGUAGE-wrong-usage2-stderr.txt b/Tests/RunCMake/GenEx-LINK_LANGUAGE/LINK_LANGUAGE-wrong-usage2-stderr.txt
new file mode 100644
index 0000000..7fe4310
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LINK_LANGUAGE/LINK_LANGUAGE-wrong-usage2-stderr.txt
@@ -0,0 +1,9 @@
+CMake Error at LINK_LANGUAGE-wrong-usage2.cmake:4 \(target_compile_options\):
+  Error evaluating generator expression:
+
+    \$<LINK_LANGUAGE:C>
+
+  \$<LINK_LANGUAGE:...> may only be used with binary targets to specify link
+  libraries, link directories, link options and link depends.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/GenEx-LINK_LANGUAGE/LINK_LANGUAGE-wrong-usage2.cmake b/Tests/RunCMake/GenEx-LINK_LANGUAGE/LINK_LANGUAGE-wrong-usage2.cmake
new file mode 100644
index 0000000..e761897
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LINK_LANGUAGE/LINK_LANGUAGE-wrong-usage2.cmake
@@ -0,0 +1,4 @@
+
+enable_language(C)
+add_executable(empty empty.c)
+target_compile_options(empty PRIVATE $<$<LINK_LANGUAGE:C>:-OPT>)
diff --git a/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_library-result.txt b/Tests/RunCMake/GenEx-LINK_LANGUAGE/LINK_LANGUAGE-wrong-usage3-result.txt
similarity index 100%
copy from Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_library-result.txt
copy to Tests/RunCMake/GenEx-LINK_LANGUAGE/LINK_LANGUAGE-wrong-usage3-result.txt
diff --git a/Tests/RunCMake/GenEx-LINK_LANGUAGE/LINK_LANGUAGE-wrong-usage3-stderr.txt b/Tests/RunCMake/GenEx-LINK_LANGUAGE/LINK_LANGUAGE-wrong-usage3-stderr.txt
new file mode 100644
index 0000000..cb20e99
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LINK_LANGUAGE/LINK_LANGUAGE-wrong-usage3-stderr.txt
@@ -0,0 +1,9 @@
+CMake Error at LINK_LANGUAGE-wrong-usage3.cmake:4 \(target_include_directories\):
+  Error evaluating generator expression:
+
+    \$<LINK_LANGUAGE:C>
+
+  \$<LINK_LANGUAGE:...> may only be used with binary targets to specify link
+  libraries, link directories, link options and link depends.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/GenEx-LINK_LANGUAGE/LINK_LANGUAGE-wrong-usage3.cmake b/Tests/RunCMake/GenEx-LINK_LANGUAGE/LINK_LANGUAGE-wrong-usage3.cmake
new file mode 100644
index 0000000..96a72a1
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LINK_LANGUAGE/LINK_LANGUAGE-wrong-usage3.cmake
@@ -0,0 +1,4 @@
+
+enable_language(C)
+add_executable(empty empty.c)
+target_include_directories(empty PRIVATE $<$<LINK_LANGUAGE:C>:/DIR>)
diff --git a/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_library-result.txt b/Tests/RunCMake/GenEx-LINK_LANGUAGE/LINK_LANGUAGE-wrong-usage4-result.txt
similarity index 100%
copy from Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_library-result.txt
copy to Tests/RunCMake/GenEx-LINK_LANGUAGE/LINK_LANGUAGE-wrong-usage4-result.txt
diff --git a/Tests/RunCMake/GenEx-LINK_LANGUAGE/LINK_LANGUAGE-wrong-usage4-stderr.txt b/Tests/RunCMake/GenEx-LINK_LANGUAGE/LINK_LANGUAGE-wrong-usage4-stderr.txt
new file mode 100644
index 0000000..ee36912
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LINK_LANGUAGE/LINK_LANGUAGE-wrong-usage4-stderr.txt
@@ -0,0 +1,8 @@
+CMake Error at LINK_LANGUAGE-wrong-usage4.cmake:7 \(target_link_libraries\):
+  Error evaluating generator expression:
+
+    \$<LINK_LANGUAGE>
+
+  \$<LINK_LANGUAGE> is not supported in link libraries expression.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/GenEx-LINK_LANGUAGE/LINK_LANGUAGE-wrong-usage4.cmake b/Tests/RunCMake/GenEx-LINK_LANGUAGE/LINK_LANGUAGE-wrong-usage4.cmake
new file mode 100644
index 0000000..3ecaabb
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LINK_LANGUAGE/LINK_LANGUAGE-wrong-usage4.cmake
@@ -0,0 +1,7 @@
+
+enable_language(C)
+
+add_library(libC empty.c)
+
+add_executable(empty empty.c)
+target_link_libraries(empty PRIVATE lib$<LINK_LANGUAGE>)
diff --git a/Tests/RunCMake/GenEx-LINK_LANGUAGE/RunCMakeTest.cmake b/Tests/RunCMake/GenEx-LINK_LANGUAGE/RunCMakeTest.cmake
new file mode 100644
index 0000000..4cf0c04
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LINK_LANGUAGE/RunCMakeTest.cmake
@@ -0,0 +1,15 @@
+include(RunCMake)
+
+run_cmake(LINK_LANGUAGE-add_custom_target)
+run_cmake(LINK_LANGUAGE-add_custom_command)
+run_cmake(LINK_LANGUAGE-install)
+run_cmake(LINK_LANGUAGE-target_sources)
+run_cmake(LINK_LANGUAGE-add_executable)
+run_cmake(LINK_LANGUAGE-add_library)
+run_cmake(LINK_LANGUAGE-add_test)
+run_cmake(LINK_LANGUAGE-unknown-lang)
+run_cmake(LINK_LANGUAGE-wrong-usage1)
+run_cmake(LINK_LANGUAGE-wrong-usage2)
+run_cmake(LINK_LANGUAGE-wrong-usage3)
+run_cmake(LINK_LANGUAGE-wrong-usage4)
+run_cmake(LINK_LANGUAGE-file_generate)
diff --git a/Tests/RunCMake/GenEx-LINK_LANGUAGE/empty.c b/Tests/RunCMake/GenEx-LINK_LANGUAGE/empty.c
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LINK_LANGUAGE/empty.c
diff --git a/Tests/RunCMake/GenEx-LINK_LANG_AND_ID/CMakeLists.txt b/Tests/RunCMake/GenEx-LINK_LANG_AND_ID/CMakeLists.txt
new file mode 100644
index 0000000..b646c4a
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LINK_LANG_AND_ID/CMakeLists.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 3.18)
+project(${RunCMake_TEST} NONE)
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/GeneratorExpression/COMPILE_LANG_AND_ID-add_custom_command-result.txt b/Tests/RunCMake/GenEx-LINK_LANG_AND_ID/LINK_LANG_AND_ID-add_custom_command-result.txt
similarity index 100%
copy from Tests/RunCMake/GeneratorExpression/COMPILE_LANG_AND_ID-add_custom_command-result.txt
copy to Tests/RunCMake/GenEx-LINK_LANG_AND_ID/LINK_LANG_AND_ID-add_custom_command-result.txt
diff --git a/Tests/RunCMake/GenEx-LINK_LANG_AND_ID/LINK_LANG_AND_ID-add_custom_command-stderr.txt b/Tests/RunCMake/GenEx-LINK_LANG_AND_ID/LINK_LANG_AND_ID-add_custom_command-stderr.txt
new file mode 100644
index 0000000..2ff62bc
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LINK_LANG_AND_ID/LINK_LANG_AND_ID-add_custom_command-stderr.txt
@@ -0,0 +1,9 @@
+CMake Error at LINK_LANG_AND_ID-add_custom_command.cmake:2 \(add_custom_command\):
+  Error evaluating generator expression:
+
+    \$<LINK_LANG_AND_ID:LANG,ID>
+
+  \$<LINK_LANG_AND_ID:lang,id> may only be used with binary targets to specify
+  link libraries, link directories, link options, and link depends.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/GenEx-LINK_LANG_AND_ID/LINK_LANG_AND_ID-add_custom_command.cmake b/Tests/RunCMake/GenEx-LINK_LANG_AND_ID/LINK_LANG_AND_ID-add_custom_command.cmake
new file mode 100644
index 0000000..9df9232
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LINK_LANG_AND_ID/LINK_LANG_AND_ID-add_custom_command.cmake
@@ -0,0 +1,4 @@
+add_custom_target(drive)
+add_custom_command(TARGET drive PRE_BUILD
+  COMMAND ${CMAKE_COMMAND} -E echo $<LINK_LANG_AND_ID:LANG,ID>
+)
diff --git a/Tests/RunCMake/GeneratorExpression/COMPILE_LANG_AND_ID-add_custom_target-result.txt b/Tests/RunCMake/GenEx-LINK_LANG_AND_ID/LINK_LANG_AND_ID-add_custom_target-result.txt
similarity index 100%
copy from Tests/RunCMake/GeneratorExpression/COMPILE_LANG_AND_ID-add_custom_target-result.txt
copy to Tests/RunCMake/GenEx-LINK_LANG_AND_ID/LINK_LANG_AND_ID-add_custom_target-result.txt
diff --git a/Tests/RunCMake/GenEx-LINK_LANG_AND_ID/LINK_LANG_AND_ID-add_custom_target-stderr.txt b/Tests/RunCMake/GenEx-LINK_LANG_AND_ID/LINK_LANG_AND_ID-add_custom_target-stderr.txt
new file mode 100644
index 0000000..0749c44
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LINK_LANG_AND_ID/LINK_LANG_AND_ID-add_custom_target-stderr.txt
@@ -0,0 +1,9 @@
+CMake Error at LINK_LANG_AND_ID-add_custom_target.cmake:2 \(add_custom_target\):
+  Error evaluating generator expression:
+
+    \$<LINK_LANG_AND_ID:LANG,ID>
+
+  \$<LINK_LANG_AND_ID:lang,id> may only be used with binary targets to specify
+  link libraries, link directories, link options, and link depends.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/GenEx-LINK_LANG_AND_ID/LINK_LANG_AND_ID-add_custom_target.cmake b/Tests/RunCMake/GenEx-LINK_LANG_AND_ID/LINK_LANG_AND_ID-add_custom_target.cmake
new file mode 100644
index 0000000..e5f76bc
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LINK_LANG_AND_ID/LINK_LANG_AND_ID-add_custom_target.cmake
@@ -0,0 +1,4 @@
+
+add_custom_target(drive
+  COMMAND ${CMAKE_COMMAND} -E echo $<LINK_LANG_AND_ID:LANG,ID>
+)
diff --git a/Tests/RunCMake/GeneratorExpression/COMPILE_LANG_AND_ID-add_executable-result.txt b/Tests/RunCMake/GenEx-LINK_LANG_AND_ID/LINK_LANG_AND_ID-add_executable-result.txt
similarity index 100%
copy from Tests/RunCMake/GeneratorExpression/COMPILE_LANG_AND_ID-add_executable-result.txt
copy to Tests/RunCMake/GenEx-LINK_LANG_AND_ID/LINK_LANG_AND_ID-add_executable-result.txt
diff --git a/Tests/RunCMake/GenEx-LINK_LANG_AND_ID/LINK_LANG_AND_ID-add_executable-stderr.txt b/Tests/RunCMake/GenEx-LINK_LANG_AND_ID/LINK_LANG_AND_ID-add_executable-stderr.txt
new file mode 100644
index 0000000..595312a
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LINK_LANG_AND_ID/LINK_LANG_AND_ID-add_executable-stderr.txt
@@ -0,0 +1,9 @@
+CMake Error at LINK_LANG_AND_ID-add_executable.cmake:1 \(add_executable\):
+  Error evaluating generator expression:
+
+    \$<LINK_LANG_AND_ID:C,MSVC>
+
+  \$<LINK_LANG_AND_ID:lang,id> may only be used with binary targets to specify
+  link libraries, link directories, link options, and link depends.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/GenEx-LINK_LANG_AND_ID/LINK_LANG_AND_ID-add_executable.cmake b/Tests/RunCMake/GenEx-LINK_LANG_AND_ID/LINK_LANG_AND_ID-add_executable.cmake
new file mode 100644
index 0000000..4d6c674
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LINK_LANG_AND_ID/LINK_LANG_AND_ID-add_executable.cmake
@@ -0,0 +1,5 @@
+add_executable(empty main.c
+        $<$<LINK_LANG_AND_ID:C,MSVC>:empty.c>
+        $<$<LINK_LANG_AND_ID:C,GNU>:empty2.c>
+        $<$<LINK_LANG_AND_ID:C,Clang>:empty3.c>
+        )
diff --git a/Tests/RunCMake/GeneratorExpression/COMPILE_LANG_AND_ID-add_library-result.txt b/Tests/RunCMake/GenEx-LINK_LANG_AND_ID/LINK_LANG_AND_ID-add_library-result.txt
similarity index 100%
copy from Tests/RunCMake/GeneratorExpression/COMPILE_LANG_AND_ID-add_library-result.txt
copy to Tests/RunCMake/GenEx-LINK_LANG_AND_ID/LINK_LANG_AND_ID-add_library-result.txt
diff --git a/Tests/RunCMake/GenEx-LINK_LANG_AND_ID/LINK_LANG_AND_ID-add_library-stderr.txt b/Tests/RunCMake/GenEx-LINK_LANG_AND_ID/LINK_LANG_AND_ID-add_library-stderr.txt
new file mode 100644
index 0000000..be46e28
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LINK_LANG_AND_ID/LINK_LANG_AND_ID-add_library-stderr.txt
@@ -0,0 +1,9 @@
+CMake Error at LINK_LANG_AND_ID-add_library.cmake:2 \(add_library\):
+  Error evaluating generator expression:
+
+    \$<LINK_LANG_AND_ID:C,MSVC>
+
+  \$<LINK_LANG_AND_ID:lang,id> may only be used with binary targets to specify
+  link libraries, link directories, link options, and link depends.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/GenEx-LINK_LANG_AND_ID/LINK_LANG_AND_ID-add_library.cmake b/Tests/RunCMake/GenEx-LINK_LANG_AND_ID/LINK_LANG_AND_ID-add_library.cmake
new file mode 100644
index 0000000..a8199cf
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LINK_LANG_AND_ID/LINK_LANG_AND_ID-add_library.cmake
@@ -0,0 +1,2 @@
+
+add_library(empty empty.$<LINK_LANG_AND_ID:C,MSVC>)
diff --git a/Tests/RunCMake/GeneratorExpression/COMPILE_LANG_AND_ID-add_test-result.txt b/Tests/RunCMake/GenEx-LINK_LANG_AND_ID/LINK_LANG_AND_ID-add_test-result.txt
similarity index 100%
copy from Tests/RunCMake/GeneratorExpression/COMPILE_LANG_AND_ID-add_test-result.txt
copy to Tests/RunCMake/GenEx-LINK_LANG_AND_ID/LINK_LANG_AND_ID-add_test-result.txt
diff --git a/Tests/RunCMake/GenEx-LINK_LANG_AND_ID/LINK_LANG_AND_ID-add_test-stderr.txt b/Tests/RunCMake/GenEx-LINK_LANG_AND_ID/LINK_LANG_AND_ID-add_test-stderr.txt
new file mode 100644
index 0000000..2a29492
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LINK_LANG_AND_ID/LINK_LANG_AND_ID-add_test-stderr.txt
@@ -0,0 +1,9 @@
+CMake Error at LINK_LANG_AND_ID-add_test.cmake:5 \(add_test\):
+  Error evaluating generator expression:
+
+    \$<LINK_LANG_AND_ID:CXX,GNU>
+
+  \$<LINK_LANG_AND_ID:lang,id> may only be used with binary targets to specify
+  link libraries, link directories, link options, and link depends.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/GenEx-LINK_LANG_AND_ID/LINK_LANG_AND_ID-add_test.cmake b/Tests/RunCMake/GenEx-LINK_LANG_AND_ID/LINK_LANG_AND_ID-add_test.cmake
new file mode 100644
index 0000000..fd700d7
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LINK_LANG_AND_ID/LINK_LANG_AND_ID-add_test.cmake
@@ -0,0 +1,5 @@
+
+include(CTest)
+enable_testing()
+
+add_test(NAME dummy COMMAND ${CMAKE_COMMAND} -E echo $<LINK_LANG_AND_ID:CXX,GNU>)
diff --git a/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_executable-result.txt b/Tests/RunCMake/GenEx-LINK_LANG_AND_ID/LINK_LANG_AND_ID-file_generate-result.txt
similarity index 100%
copy from Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_executable-result.txt
copy to Tests/RunCMake/GenEx-LINK_LANG_AND_ID/LINK_LANG_AND_ID-file_generate-result.txt
diff --git a/Tests/RunCMake/GenEx-LINK_LANG_AND_ID/LINK_LANG_AND_ID-file_generate-stderr.txt b/Tests/RunCMake/GenEx-LINK_LANG_AND_ID/LINK_LANG_AND_ID-file_generate-stderr.txt
new file mode 100644
index 0000000..e57b55c
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LINK_LANG_AND_ID/LINK_LANG_AND_ID-file_generate-stderr.txt
@@ -0,0 +1,9 @@
+CMake Error at LINK_LANG_AND_ID-file_generate.cmake:3 \(file\):
+  Error evaluating generator expression:
+
+    \$<LINK_LANG_AND_ID:C,GNU>
+
+  \$<LINK_LANG_AND_ID:lang,id> may only be used with binary targets to specify
+  link libraries, link directories, link options, and link depends.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/GenEx-LINK_LANG_AND_ID/LINK_LANG_AND_ID-file_generate.cmake b/Tests/RunCMake/GenEx-LINK_LANG_AND_ID/LINK_LANG_AND_ID-file_generate.cmake
new file mode 100644
index 0000000..67c1bda
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LINK_LANG_AND_ID/LINK_LANG_AND_ID-file_generate.cmake
@@ -0,0 +1,6 @@
+enable_language(CXX C)
+
+file(GENERATE
+  OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/output.txt
+  CONTENT "LANG_IS_$<$<LINK_LANG_AND_ID:C,GNU>:C>\n"
+)
diff --git a/Tests/RunCMake/GeneratorExpression/COMPILE_LANG_AND_ID-install-result.txt b/Tests/RunCMake/GenEx-LINK_LANG_AND_ID/LINK_LANG_AND_ID-install-result.txt
similarity index 100%
copy from Tests/RunCMake/GeneratorExpression/COMPILE_LANG_AND_ID-install-result.txt
copy to Tests/RunCMake/GenEx-LINK_LANG_AND_ID/LINK_LANG_AND_ID-install-result.txt
diff --git a/Tests/RunCMake/GenEx-LINK_LANG_AND_ID/LINK_LANG_AND_ID-install-stderr.txt b/Tests/RunCMake/GenEx-LINK_LANG_AND_ID/LINK_LANG_AND_ID-install-stderr.txt
new file mode 100644
index 0000000..965f974
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LINK_LANG_AND_ID/LINK_LANG_AND_ID-install-stderr.txt
@@ -0,0 +1,10 @@
+CMake Error:
+  Error evaluating generator expression:
+
+    \$<LINK_LANG_AND_ID:C,MSVC>
+
+  \$<LINK_LANG_AND_ID:lang,id> may only be used with binary targets to specify
+  link libraries, link directories, link options, and link depends.
+
+
+CMake Generate step failed.  Build files cannot be regenerated correctly.
diff --git a/Tests/RunCMake/GenEx-LINK_LANG_AND_ID/LINK_LANG_AND_ID-install.cmake b/Tests/RunCMake/GenEx-LINK_LANG_AND_ID/LINK_LANG_AND_ID-install.cmake
new file mode 100644
index 0000000..b8f9323
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LINK_LANG_AND_ID/LINK_LANG_AND_ID-install.cmake
@@ -0,0 +1,5 @@
+
+install(FILES
+  empty.$<LINK_LANG_AND_ID:C,MSVC>
+  DESTINATION src
+)
diff --git a/Tests/RunCMake/GeneratorExpression/COMPILE_LANG_AND_ID-target_sources-result.txt b/Tests/RunCMake/GenEx-LINK_LANG_AND_ID/LINK_LANG_AND_ID-target_sources-result.txt
similarity index 100%
copy from Tests/RunCMake/GeneratorExpression/COMPILE_LANG_AND_ID-target_sources-result.txt
copy to Tests/RunCMake/GenEx-LINK_LANG_AND_ID/LINK_LANG_AND_ID-target_sources-result.txt
diff --git a/Tests/RunCMake/GenEx-LINK_LANG_AND_ID/LINK_LANG_AND_ID-target_sources-stderr.txt b/Tests/RunCMake/GenEx-LINK_LANG_AND_ID/LINK_LANG_AND_ID-target_sources-stderr.txt
new file mode 100644
index 0000000..e86602a
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LINK_LANG_AND_ID/LINK_LANG_AND_ID-target_sources-stderr.txt
@@ -0,0 +1,8 @@
+CMake Error at LINK_LANG_AND_ID-target_sources.cmake:2 \(target_sources\):
+  Error evaluating generator expression:
+
+    \$<LINK_LANG_AND_ID>
+
+  \$<LINK_LANG_AND_ID> expression requires at least two parameters.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/GenEx-LINK_LANG_AND_ID/LINK_LANG_AND_ID-target_sources.cmake b/Tests/RunCMake/GenEx-LINK_LANG_AND_ID/LINK_LANG_AND_ID-target_sources.cmake
new file mode 100644
index 0000000..da5faf4
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LINK_LANG_AND_ID/LINK_LANG_AND_ID-target_sources.cmake
@@ -0,0 +1,2 @@
+add_library(empty)
+target_sources(empty PRIVATE empty.$<LINK_LANG_AND_ID>)
diff --git a/Tests/RunCMake/GenEx-LINK_LANG_AND_ID/LINK_LANG_AND_ID-unknown-lang.cmake b/Tests/RunCMake/GenEx-LINK_LANG_AND_ID/LINK_LANG_AND_ID-unknown-lang.cmake
new file mode 100644
index 0000000..99dd337
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LINK_LANG_AND_ID/LINK_LANG_AND_ID-unknown-lang.cmake
@@ -0,0 +1,4 @@
+
+enable_language(C)
+add_executable(empty empty.c)
+target_link_options(empty PRIVATE $<$<LINK_LANG_AND_ID:CXX,GNU>:$<TARGET_EXISTS:too,many,parameters>>)
diff --git a/Tests/RunCMake/GeneratorExpression/GENEX_EVAL-recursion1-result.txt b/Tests/RunCMake/GenEx-LINK_LANG_AND_ID/LINK_LANG_AND_ID-wrong-usage1-result.txt
similarity index 100%
copy from Tests/RunCMake/GeneratorExpression/GENEX_EVAL-recursion1-result.txt
copy to Tests/RunCMake/GenEx-LINK_LANG_AND_ID/LINK_LANG_AND_ID-wrong-usage1-result.txt
diff --git a/Tests/RunCMake/GenEx-LINK_LANG_AND_ID/LINK_LANG_AND_ID-wrong-usage1-stderr.txt b/Tests/RunCMake/GenEx-LINK_LANG_AND_ID/LINK_LANG_AND_ID-wrong-usage1-stderr.txt
new file mode 100644
index 0000000..95611c3
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LINK_LANG_AND_ID/LINK_LANG_AND_ID-wrong-usage1-stderr.txt
@@ -0,0 +1,9 @@
+CMake Error at LINK_LANG_AND_ID-wrong-usage1.cmake:4 \(target_compile_definitions\):
+  Error evaluating generator expression:
+
+    \$<LINK_LANG_AND_ID:C,GNU>
+
+  \$<LINK_LANG_AND_ID:lang,id> may only be used with binary targets to specify
+  link libraries, link directories, link options, and link depends.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/GenEx-LINK_LANG_AND_ID/LINK_LANG_AND_ID-wrong-usage1.cmake b/Tests/RunCMake/GenEx-LINK_LANG_AND_ID/LINK_LANG_AND_ID-wrong-usage1.cmake
new file mode 100644
index 0000000..e58e3b44
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LINK_LANG_AND_ID/LINK_LANG_AND_ID-wrong-usage1.cmake
@@ -0,0 +1,4 @@
+
+enable_language(C)
+add_executable(empty empty.c)
+target_compile_definitions(empty PRIVATE $<$<LINK_LANG_AND_ID:C,GNU>:DEF>)
diff --git a/Tests/RunCMake/GeneratorExpression/GENEX_EVAL-recursion2-result.txt b/Tests/RunCMake/GenEx-LINK_LANG_AND_ID/LINK_LANG_AND_ID-wrong-usage2-result.txt
similarity index 100%
copy from Tests/RunCMake/GeneratorExpression/GENEX_EVAL-recursion2-result.txt
copy to Tests/RunCMake/GenEx-LINK_LANG_AND_ID/LINK_LANG_AND_ID-wrong-usage2-result.txt
diff --git a/Tests/RunCMake/GenEx-LINK_LANG_AND_ID/LINK_LANG_AND_ID-wrong-usage2-stderr.txt b/Tests/RunCMake/GenEx-LINK_LANG_AND_ID/LINK_LANG_AND_ID-wrong-usage2-stderr.txt
new file mode 100644
index 0000000..53bdcb2
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LINK_LANG_AND_ID/LINK_LANG_AND_ID-wrong-usage2-stderr.txt
@@ -0,0 +1,9 @@
+CMake Error at LINK_LANG_AND_ID-wrong-usage2.cmake:4 \(target_compile_options\):
+  Error evaluating generator expression:
+
+    \$<LINK_LANG_AND_ID:C,GNU>
+
+  \$<LINK_LANG_AND_ID:lang,id> may only be used with binary targets to specify
+  link libraries, link directories, link options, and link depends.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/GenEx-LINK_LANG_AND_ID/LINK_LANG_AND_ID-wrong-usage2.cmake b/Tests/RunCMake/GenEx-LINK_LANG_AND_ID/LINK_LANG_AND_ID-wrong-usage2.cmake
new file mode 100644
index 0000000..998daa9
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LINK_LANG_AND_ID/LINK_LANG_AND_ID-wrong-usage2.cmake
@@ -0,0 +1,4 @@
+
+enable_language(C)
+add_executable(empty empty.c)
+target_compile_options(empty PRIVATE $<$<LINK_LANG_AND_ID:C,GNU>:-OPT>)
diff --git a/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_executable-result.txt b/Tests/RunCMake/GenEx-LINK_LANG_AND_ID/LINK_LANG_AND_ID-wrong-usage3-result.txt
similarity index 100%
copy from Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_executable-result.txt
copy to Tests/RunCMake/GenEx-LINK_LANG_AND_ID/LINK_LANG_AND_ID-wrong-usage3-result.txt
diff --git a/Tests/RunCMake/GenEx-LINK_LANG_AND_ID/LINK_LANG_AND_ID-wrong-usage3-stderr.txt b/Tests/RunCMake/GenEx-LINK_LANG_AND_ID/LINK_LANG_AND_ID-wrong-usage3-stderr.txt
new file mode 100644
index 0000000..a34a2ea
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LINK_LANG_AND_ID/LINK_LANG_AND_ID-wrong-usage3-stderr.txt
@@ -0,0 +1,9 @@
+CMake Error at LINK_LANG_AND_ID-wrong-usage3.cmake:4 \(target_include_directories\):
+  Error evaluating generator expression:
+
+    \$<LINK_LANG_AND_ID:C,GNU>
+
+  \$<LINK_LANG_AND_ID:lang,id> may only be used with binary targets to specify
+  link libraries, link directories, link options, and link depends.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/GenEx-LINK_LANG_AND_ID/LINK_LANG_AND_ID-wrong-usage3.cmake b/Tests/RunCMake/GenEx-LINK_LANG_AND_ID/LINK_LANG_AND_ID-wrong-usage3.cmake
new file mode 100644
index 0000000..0543056
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LINK_LANG_AND_ID/LINK_LANG_AND_ID-wrong-usage3.cmake
@@ -0,0 +1,4 @@
+
+enable_language(C)
+add_executable(empty empty.c)
+target_include_directories(empty PRIVATE $<$<LINK_LANG_AND_ID:C,GNU>:/DIR>)
diff --git a/Tests/RunCMake/GenEx-LINK_LANG_AND_ID/RunCMakeTest.cmake b/Tests/RunCMake/GenEx-LINK_LANG_AND_ID/RunCMakeTest.cmake
new file mode 100644
index 0000000..5bb6590
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LINK_LANG_AND_ID/RunCMakeTest.cmake
@@ -0,0 +1,14 @@
+include(RunCMake)
+
+run_cmake(LINK_LANG_AND_ID-add_custom_target)
+run_cmake(LINK_LANG_AND_ID-add_custom_command)
+run_cmake(LINK_LANG_AND_ID-install)
+run_cmake(LINK_LANG_AND_ID-target_sources)
+run_cmake(LINK_LANG_AND_ID-add_executable)
+run_cmake(LINK_LANG_AND_ID-add_library)
+run_cmake(LINK_LANG_AND_ID-add_test)
+run_cmake(LINK_LANG_AND_ID-unknown-lang)
+run_cmake(LINK_LANG_AND_ID-wrong-usage1)
+run_cmake(LINK_LANG_AND_ID-wrong-usage2)
+run_cmake(LINK_LANG_AND_ID-wrong-usage3)
+run_cmake(LINK_LANG_AND_ID-file_generate)
diff --git a/Tests/RunCMake/GenEx-LINK_LANG_AND_ID/empty.c b/Tests/RunCMake/GenEx-LINK_LANG_AND_ID/empty.c
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LINK_LANG_AND_ID/empty.c
diff --git a/Tests/RunCMake/GenEx-TARGET_FILE/CMakeLists.txt b/Tests/RunCMake/GenEx-TARGET_FILE/CMakeLists.txt
new file mode 100644
index 0000000..4b3de84
--- /dev/null
+++ b/Tests/RunCMake/GenEx-TARGET_FILE/CMakeLists.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 2.8.12)
+project(${RunCMake_TEST} NONE)
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/GeneratorExpression/ImportedTarget-TARGET_BUNDLE_CONTENT_DIR-result.txt b/Tests/RunCMake/GenEx-TARGET_FILE/ImportedTarget-TARGET_BUNDLE_CONTENT_DIR-result.txt
similarity index 100%
rename from Tests/RunCMake/GeneratorExpression/ImportedTarget-TARGET_BUNDLE_CONTENT_DIR-result.txt
rename to Tests/RunCMake/GenEx-TARGET_FILE/ImportedTarget-TARGET_BUNDLE_CONTENT_DIR-result.txt
diff --git a/Tests/RunCMake/GeneratorExpression/ImportedTarget-TARGET_BUNDLE_CONTENT_DIR-stderr.txt b/Tests/RunCMake/GenEx-TARGET_FILE/ImportedTarget-TARGET_BUNDLE_CONTENT_DIR-stderr.txt
similarity index 100%
rename from Tests/RunCMake/GeneratorExpression/ImportedTarget-TARGET_BUNDLE_CONTENT_DIR-stderr.txt
rename to Tests/RunCMake/GenEx-TARGET_FILE/ImportedTarget-TARGET_BUNDLE_CONTENT_DIR-stderr.txt
diff --git a/Tests/RunCMake/GeneratorExpression/ImportedTarget-TARGET_BUNDLE_CONTENT_DIR.cmake b/Tests/RunCMake/GenEx-TARGET_FILE/ImportedTarget-TARGET_BUNDLE_CONTENT_DIR.cmake
similarity index 100%
rename from Tests/RunCMake/GeneratorExpression/ImportedTarget-TARGET_BUNDLE_CONTENT_DIR.cmake
rename to Tests/RunCMake/GenEx-TARGET_FILE/ImportedTarget-TARGET_BUNDLE_CONTENT_DIR.cmake
diff --git a/Tests/RunCMake/GeneratorExpression/ImportedTarget-TARGET_BUNDLE_DIR-result.txt b/Tests/RunCMake/GenEx-TARGET_FILE/ImportedTarget-TARGET_BUNDLE_DIR-result.txt
similarity index 100%
rename from Tests/RunCMake/GeneratorExpression/ImportedTarget-TARGET_BUNDLE_DIR-result.txt
rename to Tests/RunCMake/GenEx-TARGET_FILE/ImportedTarget-TARGET_BUNDLE_DIR-result.txt
diff --git a/Tests/RunCMake/GeneratorExpression/ImportedTarget-TARGET_BUNDLE_DIR-stderr.txt b/Tests/RunCMake/GenEx-TARGET_FILE/ImportedTarget-TARGET_BUNDLE_DIR-stderr.txt
similarity index 100%
rename from Tests/RunCMake/GeneratorExpression/ImportedTarget-TARGET_BUNDLE_DIR-stderr.txt
rename to Tests/RunCMake/GenEx-TARGET_FILE/ImportedTarget-TARGET_BUNDLE_DIR-stderr.txt
diff --git a/Tests/RunCMake/GeneratorExpression/ImportedTarget-TARGET_BUNDLE_DIR.cmake b/Tests/RunCMake/GenEx-TARGET_FILE/ImportedTarget-TARGET_BUNDLE_DIR.cmake
similarity index 100%
rename from Tests/RunCMake/GeneratorExpression/ImportedTarget-TARGET_BUNDLE_DIR.cmake
rename to Tests/RunCMake/GenEx-TARGET_FILE/ImportedTarget-TARGET_BUNDLE_DIR.cmake
diff --git a/Tests/RunCMake/GeneratorExpression/ImportedTarget-TARGET_PDB_FILE-result.txt b/Tests/RunCMake/GenEx-TARGET_FILE/ImportedTarget-TARGET_PDB_FILE-result.txt
similarity index 100%
rename from Tests/RunCMake/GeneratorExpression/ImportedTarget-TARGET_PDB_FILE-result.txt
rename to Tests/RunCMake/GenEx-TARGET_FILE/ImportedTarget-TARGET_PDB_FILE-result.txt
diff --git a/Tests/RunCMake/GeneratorExpression/ImportedTarget-TARGET_PDB_FILE-stderr.txt b/Tests/RunCMake/GenEx-TARGET_FILE/ImportedTarget-TARGET_PDB_FILE-stderr.txt
similarity index 100%
rename from Tests/RunCMake/GeneratorExpression/ImportedTarget-TARGET_PDB_FILE-stderr.txt
rename to Tests/RunCMake/GenEx-TARGET_FILE/ImportedTarget-TARGET_PDB_FILE-stderr.txt
diff --git a/Tests/RunCMake/GeneratorExpression/ImportedTarget-TARGET_PDB_FILE.cmake b/Tests/RunCMake/GenEx-TARGET_FILE/ImportedTarget-TARGET_PDB_FILE.cmake
similarity index 100%
rename from Tests/RunCMake/GeneratorExpression/ImportedTarget-TARGET_PDB_FILE.cmake
rename to Tests/RunCMake/GenEx-TARGET_FILE/ImportedTarget-TARGET_PDB_FILE.cmake
diff --git a/Tests/RunCMake/GeneratorExpression/ImportedTarget-TARGET_PDB_FILE_BASE_NAME-result.txt b/Tests/RunCMake/GenEx-TARGET_FILE/ImportedTarget-TARGET_PDB_FILE_BASE_NAME-result.txt
similarity index 100%
rename from Tests/RunCMake/GeneratorExpression/ImportedTarget-TARGET_PDB_FILE_BASE_NAME-result.txt
rename to Tests/RunCMake/GenEx-TARGET_FILE/ImportedTarget-TARGET_PDB_FILE_BASE_NAME-result.txt
diff --git a/Tests/RunCMake/GeneratorExpression/ImportedTarget-TARGET_PDB_FILE_BASE_NAME-stderr.txt b/Tests/RunCMake/GenEx-TARGET_FILE/ImportedTarget-TARGET_PDB_FILE_BASE_NAME-stderr.txt
similarity index 100%
rename from Tests/RunCMake/GeneratorExpression/ImportedTarget-TARGET_PDB_FILE_BASE_NAME-stderr.txt
rename to Tests/RunCMake/GenEx-TARGET_FILE/ImportedTarget-TARGET_PDB_FILE_BASE_NAME-stderr.txt
diff --git a/Tests/RunCMake/GeneratorExpression/ImportedTarget-TARGET_PDB_FILE_BASE_NAME.cmake b/Tests/RunCMake/GenEx-TARGET_FILE/ImportedTarget-TARGET_PDB_FILE_BASE_NAME.cmake
similarity index 100%
rename from Tests/RunCMake/GeneratorExpression/ImportedTarget-TARGET_PDB_FILE_BASE_NAME.cmake
rename to Tests/RunCMake/GenEx-TARGET_FILE/ImportedTarget-TARGET_PDB_FILE_BASE_NAME.cmake
diff --git a/Tests/RunCMake/GeneratorExpression/NonValidCompiler-TARGET_PDB_FILE-result.txt b/Tests/RunCMake/GenEx-TARGET_FILE/NonValidCompiler-TARGET_PDB_FILE-result.txt
similarity index 100%
rename from Tests/RunCMake/GeneratorExpression/NonValidCompiler-TARGET_PDB_FILE-result.txt
rename to Tests/RunCMake/GenEx-TARGET_FILE/NonValidCompiler-TARGET_PDB_FILE-result.txt
diff --git a/Tests/RunCMake/GeneratorExpression/NonValidCompiler-TARGET_PDB_FILE-stderr.txt b/Tests/RunCMake/GenEx-TARGET_FILE/NonValidCompiler-TARGET_PDB_FILE-stderr.txt
similarity index 100%
rename from Tests/RunCMake/GeneratorExpression/NonValidCompiler-TARGET_PDB_FILE-stderr.txt
rename to Tests/RunCMake/GenEx-TARGET_FILE/NonValidCompiler-TARGET_PDB_FILE-stderr.txt
diff --git a/Tests/RunCMake/GeneratorExpression/NonValidCompiler-TARGET_PDB_FILE.cmake b/Tests/RunCMake/GenEx-TARGET_FILE/NonValidCompiler-TARGET_PDB_FILE.cmake
similarity index 100%
rename from Tests/RunCMake/GeneratorExpression/NonValidCompiler-TARGET_PDB_FILE.cmake
rename to Tests/RunCMake/GenEx-TARGET_FILE/NonValidCompiler-TARGET_PDB_FILE.cmake
diff --git a/Tests/RunCMake/GeneratorExpression/NonValidCompiler-TARGET_PDB_FILE_BASE_NAME-result.txt b/Tests/RunCMake/GenEx-TARGET_FILE/NonValidCompiler-TARGET_PDB_FILE_BASE_NAME-result.txt
similarity index 100%
rename from Tests/RunCMake/GeneratorExpression/NonValidCompiler-TARGET_PDB_FILE_BASE_NAME-result.txt
rename to Tests/RunCMake/GenEx-TARGET_FILE/NonValidCompiler-TARGET_PDB_FILE_BASE_NAME-result.txt
diff --git a/Tests/RunCMake/GeneratorExpression/NonValidCompiler-TARGET_PDB_FILE_BASE_NAME-stderr.txt b/Tests/RunCMake/GenEx-TARGET_FILE/NonValidCompiler-TARGET_PDB_FILE_BASE_NAME-stderr.txt
similarity index 100%
rename from Tests/RunCMake/GeneratorExpression/NonValidCompiler-TARGET_PDB_FILE_BASE_NAME-stderr.txt
rename to Tests/RunCMake/GenEx-TARGET_FILE/NonValidCompiler-TARGET_PDB_FILE_BASE_NAME-stderr.txt
diff --git a/Tests/RunCMake/GeneratorExpression/NonValidCompiler-TARGET_PDB_FILE_BASE_NAME.cmake b/Tests/RunCMake/GenEx-TARGET_FILE/NonValidCompiler-TARGET_PDB_FILE_BASE_NAME.cmake
similarity index 100%
rename from Tests/RunCMake/GeneratorExpression/NonValidCompiler-TARGET_PDB_FILE_BASE_NAME.cmake
rename to Tests/RunCMake/GenEx-TARGET_FILE/NonValidCompiler-TARGET_PDB_FILE_BASE_NAME.cmake
diff --git a/Tests/RunCMake/GeneratorExpression/NonValidTarget-TARGET_BUNDLE_CONTENT_DIR-result.txt b/Tests/RunCMake/GenEx-TARGET_FILE/NonValidTarget-TARGET_BUNDLE_CONTENT_DIR-result.txt
similarity index 100%
rename from Tests/RunCMake/GeneratorExpression/NonValidTarget-TARGET_BUNDLE_CONTENT_DIR-result.txt
rename to Tests/RunCMake/GenEx-TARGET_FILE/NonValidTarget-TARGET_BUNDLE_CONTENT_DIR-result.txt
diff --git a/Tests/RunCMake/GeneratorExpression/NonValidTarget-TARGET_BUNDLE_CONTENT_DIR-stderr.txt b/Tests/RunCMake/GenEx-TARGET_FILE/NonValidTarget-TARGET_BUNDLE_CONTENT_DIR-stderr.txt
similarity index 100%
rename from Tests/RunCMake/GeneratorExpression/NonValidTarget-TARGET_BUNDLE_CONTENT_DIR-stderr.txt
rename to Tests/RunCMake/GenEx-TARGET_FILE/NonValidTarget-TARGET_BUNDLE_CONTENT_DIR-stderr.txt
diff --git a/Tests/RunCMake/GeneratorExpression/NonValidTarget-TARGET_BUNDLE_CONTENT_DIR.cmake b/Tests/RunCMake/GenEx-TARGET_FILE/NonValidTarget-TARGET_BUNDLE_CONTENT_DIR.cmake
similarity index 100%
rename from Tests/RunCMake/GeneratorExpression/NonValidTarget-TARGET_BUNDLE_CONTENT_DIR.cmake
rename to Tests/RunCMake/GenEx-TARGET_FILE/NonValidTarget-TARGET_BUNDLE_CONTENT_DIR.cmake
diff --git a/Tests/RunCMake/GeneratorExpression/NonValidTarget-TARGET_BUNDLE_DIR-result.txt b/Tests/RunCMake/GenEx-TARGET_FILE/NonValidTarget-TARGET_BUNDLE_DIR-result.txt
similarity index 100%
rename from Tests/RunCMake/GeneratorExpression/NonValidTarget-TARGET_BUNDLE_DIR-result.txt
rename to Tests/RunCMake/GenEx-TARGET_FILE/NonValidTarget-TARGET_BUNDLE_DIR-result.txt
diff --git a/Tests/RunCMake/GeneratorExpression/NonValidTarget-TARGET_BUNDLE_DIR-stderr.txt b/Tests/RunCMake/GenEx-TARGET_FILE/NonValidTarget-TARGET_BUNDLE_DIR-stderr.txt
similarity index 100%
rename from Tests/RunCMake/GeneratorExpression/NonValidTarget-TARGET_BUNDLE_DIR-stderr.txt
rename to Tests/RunCMake/GenEx-TARGET_FILE/NonValidTarget-TARGET_BUNDLE_DIR-stderr.txt
diff --git a/Tests/RunCMake/GeneratorExpression/NonValidTarget-TARGET_BUNDLE_DIR.cmake b/Tests/RunCMake/GenEx-TARGET_FILE/NonValidTarget-TARGET_BUNDLE_DIR.cmake
similarity index 100%
rename from Tests/RunCMake/GeneratorExpression/NonValidTarget-TARGET_BUNDLE_DIR.cmake
rename to Tests/RunCMake/GenEx-TARGET_FILE/NonValidTarget-TARGET_BUNDLE_DIR.cmake
diff --git a/Tests/RunCMake/GeneratorExpression/NonValidTarget-TARGET_PDB_FILE-result.txt b/Tests/RunCMake/GenEx-TARGET_FILE/NonValidTarget-TARGET_PDB_FILE-result.txt
similarity index 100%
rename from Tests/RunCMake/GeneratorExpression/NonValidTarget-TARGET_PDB_FILE-result.txt
rename to Tests/RunCMake/GenEx-TARGET_FILE/NonValidTarget-TARGET_PDB_FILE-result.txt
diff --git a/Tests/RunCMake/GeneratorExpression/NonValidTarget-TARGET_PDB_FILE-stderr.txt b/Tests/RunCMake/GenEx-TARGET_FILE/NonValidTarget-TARGET_PDB_FILE-stderr.txt
similarity index 100%
rename from Tests/RunCMake/GeneratorExpression/NonValidTarget-TARGET_PDB_FILE-stderr.txt
rename to Tests/RunCMake/GenEx-TARGET_FILE/NonValidTarget-TARGET_PDB_FILE-stderr.txt
diff --git a/Tests/RunCMake/GeneratorExpression/NonValidTarget-TARGET_PDB_FILE.cmake b/Tests/RunCMake/GenEx-TARGET_FILE/NonValidTarget-TARGET_PDB_FILE.cmake
similarity index 100%
rename from Tests/RunCMake/GeneratorExpression/NonValidTarget-TARGET_PDB_FILE.cmake
rename to Tests/RunCMake/GenEx-TARGET_FILE/NonValidTarget-TARGET_PDB_FILE.cmake
diff --git a/Tests/RunCMake/GeneratorExpression/NonValidTarget-TARGET_PDB_FILE_BASE_NAME-result.txt b/Tests/RunCMake/GenEx-TARGET_FILE/NonValidTarget-TARGET_PDB_FILE_BASE_NAME-result.txt
similarity index 100%
rename from Tests/RunCMake/GeneratorExpression/NonValidTarget-TARGET_PDB_FILE_BASE_NAME-result.txt
rename to Tests/RunCMake/GenEx-TARGET_FILE/NonValidTarget-TARGET_PDB_FILE_BASE_NAME-result.txt
diff --git a/Tests/RunCMake/GeneratorExpression/NonValidTarget-TARGET_PDB_FILE_BASE_NAME-stderr.txt b/Tests/RunCMake/GenEx-TARGET_FILE/NonValidTarget-TARGET_PDB_FILE_BASE_NAME-stderr.txt
similarity index 100%
rename from Tests/RunCMake/GeneratorExpression/NonValidTarget-TARGET_PDB_FILE_BASE_NAME-stderr.txt
rename to Tests/RunCMake/GenEx-TARGET_FILE/NonValidTarget-TARGET_PDB_FILE_BASE_NAME-stderr.txt
diff --git a/Tests/RunCMake/GeneratorExpression/NonValidTarget-TARGET_PDB_FILE_BASE_NAME.cmake b/Tests/RunCMake/GenEx-TARGET_FILE/NonValidTarget-TARGET_PDB_FILE_BASE_NAME.cmake
similarity index 100%
rename from Tests/RunCMake/GeneratorExpression/NonValidTarget-TARGET_PDB_FILE_BASE_NAME.cmake
rename to Tests/RunCMake/GenEx-TARGET_FILE/NonValidTarget-TARGET_PDB_FILE_BASE_NAME.cmake
diff --git a/Tests/RunCMake/GeneratorExpression/OUTPUT_NAME-recursion-result.txt b/Tests/RunCMake/GenEx-TARGET_FILE/OUTPUT_NAME-recursion-result.txt
similarity index 100%
rename from Tests/RunCMake/GeneratorExpression/OUTPUT_NAME-recursion-result.txt
rename to Tests/RunCMake/GenEx-TARGET_FILE/OUTPUT_NAME-recursion-result.txt
diff --git a/Tests/RunCMake/GeneratorExpression/OUTPUT_NAME-recursion-stderr.txt b/Tests/RunCMake/GenEx-TARGET_FILE/OUTPUT_NAME-recursion-stderr.txt
similarity index 100%
rename from Tests/RunCMake/GeneratorExpression/OUTPUT_NAME-recursion-stderr.txt
rename to Tests/RunCMake/GenEx-TARGET_FILE/OUTPUT_NAME-recursion-stderr.txt
diff --git a/Tests/RunCMake/GeneratorExpression/OUTPUT_NAME-recursion.cmake b/Tests/RunCMake/GenEx-TARGET_FILE/OUTPUT_NAME-recursion.cmake
similarity index 100%
rename from Tests/RunCMake/GeneratorExpression/OUTPUT_NAME-recursion.cmake
rename to Tests/RunCMake/GenEx-TARGET_FILE/OUTPUT_NAME-recursion.cmake
diff --git a/Tests/RunCMake/GenEx-TARGET_FILE/RunCMakeTest.cmake b/Tests/RunCMake/GenEx-TARGET_FILE/RunCMakeTest.cmake
new file mode 100644
index 0000000..ccec633
--- /dev/null
+++ b/Tests/RunCMake/GenEx-TARGET_FILE/RunCMakeTest.cmake
@@ -0,0 +1,31 @@
+include(RunCMake)
+
+run_cmake(TARGET_FILE-recursion)
+run_cmake(OUTPUT_NAME-recursion)
+run_cmake(TARGET_FILE_PREFIX)
+run_cmake(TARGET_FILE_PREFIX-imported-target)
+run_cmake(TARGET_FILE_PREFIX-non-valid-target)
+run_cmake(TARGET_LINKER_FILE_PREFIX-non-valid-target)
+run_cmake(TARGET_FILE_SUFFIX)
+run_cmake(TARGET_FILE_SUFFIX-imported-target)
+run_cmake(TARGET_FILE_SUFFIX-non-valid-target)
+run_cmake(TARGET_LINKER_FILE_SUFFIX-non-valid-target)
+run_cmake_with_options(TARGET_FILE_BASE_NAME -DCMAKE_BUILD_TYPE:STRING=Debug)
+run_cmake_with_options(TARGET_FILE_BASE_NAME-imported-target -DCMAKE_BUILD_TYPE:STRING=Debug)
+run_cmake(TARGET_FILE_BASE_NAME-non-valid-target)
+run_cmake(TARGET_LINKER_FILE_BASE_NAME-non-valid-target)
+run_cmake(NonValidTarget-TARGET_BUNDLE_DIR)
+run_cmake(NonValidTarget-TARGET_BUNDLE_CONTENT_DIR)
+run_cmake(ImportedTarget-TARGET_BUNDLE_DIR)
+run_cmake(ImportedTarget-TARGET_BUNDLE_CONTENT_DIR)
+run_cmake(ImportedTarget-TARGET_PDB_FILE)
+run_cmake(ImportedTarget-TARGET_PDB_FILE_BASE_NAME)
+if(LINKER_SUPPORTS_PDB)
+  run_cmake(NonValidTarget-TARGET_PDB_FILE)
+  run_cmake(ValidTarget-TARGET_PDB_FILE)
+  run_cmake(NonValidTarget-TARGET_PDB_FILE_BASE_NAME)
+  run_cmake(ValidTarget-TARGET_PDB_FILE_BASE_NAME)
+else()
+  run_cmake(NonValidCompiler-TARGET_PDB_FILE)
+  run_cmake(NonValidCompiler-TARGET_PDB_FILE_BASE_NAME)
+endif()
diff --git a/Tests/RunCMake/GeneratorExpression/TARGET_FILE-recursion-result.txt b/Tests/RunCMake/GenEx-TARGET_FILE/TARGET_FILE-recursion-result.txt
similarity index 100%
rename from Tests/RunCMake/GeneratorExpression/TARGET_FILE-recursion-result.txt
rename to Tests/RunCMake/GenEx-TARGET_FILE/TARGET_FILE-recursion-result.txt
diff --git a/Tests/RunCMake/GeneratorExpression/TARGET_FILE-recursion-stderr.txt b/Tests/RunCMake/GenEx-TARGET_FILE/TARGET_FILE-recursion-stderr.txt
similarity index 100%
rename from Tests/RunCMake/GeneratorExpression/TARGET_FILE-recursion-stderr.txt
rename to Tests/RunCMake/GenEx-TARGET_FILE/TARGET_FILE-recursion-stderr.txt
diff --git a/Tests/RunCMake/GeneratorExpression/TARGET_FILE-recursion.cmake b/Tests/RunCMake/GenEx-TARGET_FILE/TARGET_FILE-recursion.cmake
similarity index 100%
rename from Tests/RunCMake/GeneratorExpression/TARGET_FILE-recursion.cmake
rename to Tests/RunCMake/GenEx-TARGET_FILE/TARGET_FILE-recursion.cmake
diff --git a/Tests/RunCMake/GeneratorExpression/TARGET_FILE_BASE_NAME-check.cmake b/Tests/RunCMake/GenEx-TARGET_FILE/TARGET_FILE_BASE_NAME-check.cmake
similarity index 100%
rename from Tests/RunCMake/GeneratorExpression/TARGET_FILE_BASE_NAME-check.cmake
rename to Tests/RunCMake/GenEx-TARGET_FILE/TARGET_FILE_BASE_NAME-check.cmake
diff --git a/Tests/RunCMake/GeneratorExpression/TARGET_FILE_BASE_NAME-imported-target-check.cmake b/Tests/RunCMake/GenEx-TARGET_FILE/TARGET_FILE_BASE_NAME-imported-target-check.cmake
similarity index 100%
rename from Tests/RunCMake/GeneratorExpression/TARGET_FILE_BASE_NAME-imported-target-check.cmake
rename to Tests/RunCMake/GenEx-TARGET_FILE/TARGET_FILE_BASE_NAME-imported-target-check.cmake
diff --git a/Tests/RunCMake/GeneratorExpression/TARGET_FILE_BASE_NAME-imported-target.cmake b/Tests/RunCMake/GenEx-TARGET_FILE/TARGET_FILE_BASE_NAME-imported-target.cmake
similarity index 100%
rename from Tests/RunCMake/GeneratorExpression/TARGET_FILE_BASE_NAME-imported-target.cmake
rename to Tests/RunCMake/GenEx-TARGET_FILE/TARGET_FILE_BASE_NAME-imported-target.cmake
diff --git a/Tests/RunCMake/GeneratorExpression/TARGET_FILE_BASE_NAME-non-valid-target-result.txt b/Tests/RunCMake/GenEx-TARGET_FILE/TARGET_FILE_BASE_NAME-non-valid-target-result.txt
similarity index 100%
rename from Tests/RunCMake/GeneratorExpression/TARGET_FILE_BASE_NAME-non-valid-target-result.txt
rename to Tests/RunCMake/GenEx-TARGET_FILE/TARGET_FILE_BASE_NAME-non-valid-target-result.txt
diff --git a/Tests/RunCMake/GeneratorExpression/TARGET_FILE_BASE_NAME-non-valid-target-stderr.txt b/Tests/RunCMake/GenEx-TARGET_FILE/TARGET_FILE_BASE_NAME-non-valid-target-stderr.txt
similarity index 100%
rename from Tests/RunCMake/GeneratorExpression/TARGET_FILE_BASE_NAME-non-valid-target-stderr.txt
rename to Tests/RunCMake/GenEx-TARGET_FILE/TARGET_FILE_BASE_NAME-non-valid-target-stderr.txt
diff --git a/Tests/RunCMake/GeneratorExpression/TARGET_FILE_BASE_NAME-non-valid-target.cmake b/Tests/RunCMake/GenEx-TARGET_FILE/TARGET_FILE_BASE_NAME-non-valid-target.cmake
similarity index 100%
rename from Tests/RunCMake/GeneratorExpression/TARGET_FILE_BASE_NAME-non-valid-target.cmake
rename to Tests/RunCMake/GenEx-TARGET_FILE/TARGET_FILE_BASE_NAME-non-valid-target.cmake
diff --git a/Tests/RunCMake/GeneratorExpression/TARGET_FILE_BASE_NAME.cmake b/Tests/RunCMake/GenEx-TARGET_FILE/TARGET_FILE_BASE_NAME.cmake
similarity index 100%
rename from Tests/RunCMake/GeneratorExpression/TARGET_FILE_BASE_NAME.cmake
rename to Tests/RunCMake/GenEx-TARGET_FILE/TARGET_FILE_BASE_NAME.cmake
diff --git a/Tests/RunCMake/GeneratorExpression/TARGET_FILE_PREFIX-check.cmake b/Tests/RunCMake/GenEx-TARGET_FILE/TARGET_FILE_PREFIX-check.cmake
similarity index 100%
rename from Tests/RunCMake/GeneratorExpression/TARGET_FILE_PREFIX-check.cmake
rename to Tests/RunCMake/GenEx-TARGET_FILE/TARGET_FILE_PREFIX-check.cmake
diff --git a/Tests/RunCMake/GeneratorExpression/TARGET_FILE_PREFIX-imported-target-check.cmake b/Tests/RunCMake/GenEx-TARGET_FILE/TARGET_FILE_PREFIX-imported-target-check.cmake
similarity index 100%
rename from Tests/RunCMake/GeneratorExpression/TARGET_FILE_PREFIX-imported-target-check.cmake
rename to Tests/RunCMake/GenEx-TARGET_FILE/TARGET_FILE_PREFIX-imported-target-check.cmake
diff --git a/Tests/RunCMake/GeneratorExpression/TARGET_FILE_PREFIX-imported-target.cmake b/Tests/RunCMake/GenEx-TARGET_FILE/TARGET_FILE_PREFIX-imported-target.cmake
similarity index 100%
rename from Tests/RunCMake/GeneratorExpression/TARGET_FILE_PREFIX-imported-target.cmake
rename to Tests/RunCMake/GenEx-TARGET_FILE/TARGET_FILE_PREFIX-imported-target.cmake
diff --git a/Tests/RunCMake/GeneratorExpression/TARGET_FILE_PREFIX-non-valid-target-result.txt b/Tests/RunCMake/GenEx-TARGET_FILE/TARGET_FILE_PREFIX-non-valid-target-result.txt
similarity index 100%
rename from Tests/RunCMake/GeneratorExpression/TARGET_FILE_PREFIX-non-valid-target-result.txt
rename to Tests/RunCMake/GenEx-TARGET_FILE/TARGET_FILE_PREFIX-non-valid-target-result.txt
diff --git a/Tests/RunCMake/GeneratorExpression/TARGET_FILE_PREFIX-non-valid-target-stderr.txt b/Tests/RunCMake/GenEx-TARGET_FILE/TARGET_FILE_PREFIX-non-valid-target-stderr.txt
similarity index 100%
rename from Tests/RunCMake/GeneratorExpression/TARGET_FILE_PREFIX-non-valid-target-stderr.txt
rename to Tests/RunCMake/GenEx-TARGET_FILE/TARGET_FILE_PREFIX-non-valid-target-stderr.txt
diff --git a/Tests/RunCMake/GeneratorExpression/TARGET_FILE_PREFIX-non-valid-target.cmake b/Tests/RunCMake/GenEx-TARGET_FILE/TARGET_FILE_PREFIX-non-valid-target.cmake
similarity index 100%
rename from Tests/RunCMake/GeneratorExpression/TARGET_FILE_PREFIX-non-valid-target.cmake
rename to Tests/RunCMake/GenEx-TARGET_FILE/TARGET_FILE_PREFIX-non-valid-target.cmake
diff --git a/Tests/RunCMake/GeneratorExpression/TARGET_FILE_PREFIX.cmake b/Tests/RunCMake/GenEx-TARGET_FILE/TARGET_FILE_PREFIX.cmake
similarity index 100%
rename from Tests/RunCMake/GeneratorExpression/TARGET_FILE_PREFIX.cmake
rename to Tests/RunCMake/GenEx-TARGET_FILE/TARGET_FILE_PREFIX.cmake
diff --git a/Tests/RunCMake/GeneratorExpression/TARGET_FILE_SUFFIX-check.cmake b/Tests/RunCMake/GenEx-TARGET_FILE/TARGET_FILE_SUFFIX-check.cmake
similarity index 100%
rename from Tests/RunCMake/GeneratorExpression/TARGET_FILE_SUFFIX-check.cmake
rename to Tests/RunCMake/GenEx-TARGET_FILE/TARGET_FILE_SUFFIX-check.cmake
diff --git a/Tests/RunCMake/GeneratorExpression/TARGET_FILE_SUFFIX-imported-target-check.cmake b/Tests/RunCMake/GenEx-TARGET_FILE/TARGET_FILE_SUFFIX-imported-target-check.cmake
similarity index 100%
rename from Tests/RunCMake/GeneratorExpression/TARGET_FILE_SUFFIX-imported-target-check.cmake
rename to Tests/RunCMake/GenEx-TARGET_FILE/TARGET_FILE_SUFFIX-imported-target-check.cmake
diff --git a/Tests/RunCMake/GeneratorExpression/TARGET_FILE_SUFFIX-imported-target.cmake b/Tests/RunCMake/GenEx-TARGET_FILE/TARGET_FILE_SUFFIX-imported-target.cmake
similarity index 100%
rename from Tests/RunCMake/GeneratorExpression/TARGET_FILE_SUFFIX-imported-target.cmake
rename to Tests/RunCMake/GenEx-TARGET_FILE/TARGET_FILE_SUFFIX-imported-target.cmake
diff --git a/Tests/RunCMake/GeneratorExpression/TARGET_FILE_SUFFIX-non-valid-target-result.txt b/Tests/RunCMake/GenEx-TARGET_FILE/TARGET_FILE_SUFFIX-non-valid-target-result.txt
similarity index 100%
rename from Tests/RunCMake/GeneratorExpression/TARGET_FILE_SUFFIX-non-valid-target-result.txt
rename to Tests/RunCMake/GenEx-TARGET_FILE/TARGET_FILE_SUFFIX-non-valid-target-result.txt
diff --git a/Tests/RunCMake/GeneratorExpression/TARGET_FILE_SUFFIX-non-valid-target-stderr.txt b/Tests/RunCMake/GenEx-TARGET_FILE/TARGET_FILE_SUFFIX-non-valid-target-stderr.txt
similarity index 100%
rename from Tests/RunCMake/GeneratorExpression/TARGET_FILE_SUFFIX-non-valid-target-stderr.txt
rename to Tests/RunCMake/GenEx-TARGET_FILE/TARGET_FILE_SUFFIX-non-valid-target-stderr.txt
diff --git a/Tests/RunCMake/GeneratorExpression/TARGET_FILE_SUFFIX-non-valid-target.cmake b/Tests/RunCMake/GenEx-TARGET_FILE/TARGET_FILE_SUFFIX-non-valid-target.cmake
similarity index 100%
rename from Tests/RunCMake/GeneratorExpression/TARGET_FILE_SUFFIX-non-valid-target.cmake
rename to Tests/RunCMake/GenEx-TARGET_FILE/TARGET_FILE_SUFFIX-non-valid-target.cmake
diff --git a/Tests/RunCMake/GeneratorExpression/TARGET_FILE_SUFFIX.cmake b/Tests/RunCMake/GenEx-TARGET_FILE/TARGET_FILE_SUFFIX.cmake
similarity index 100%
rename from Tests/RunCMake/GeneratorExpression/TARGET_FILE_SUFFIX.cmake
rename to Tests/RunCMake/GenEx-TARGET_FILE/TARGET_FILE_SUFFIX.cmake
diff --git a/Tests/RunCMake/GeneratorExpression/TARGET_LINKER_FILE_BASE_NAME-non-valid-target-result.txt b/Tests/RunCMake/GenEx-TARGET_FILE/TARGET_LINKER_FILE_BASE_NAME-non-valid-target-result.txt
similarity index 100%
rename from Tests/RunCMake/GeneratorExpression/TARGET_LINKER_FILE_BASE_NAME-non-valid-target-result.txt
rename to Tests/RunCMake/GenEx-TARGET_FILE/TARGET_LINKER_FILE_BASE_NAME-non-valid-target-result.txt
diff --git a/Tests/RunCMake/GeneratorExpression/TARGET_LINKER_FILE_BASE_NAME-non-valid-target-stderr.txt b/Tests/RunCMake/GenEx-TARGET_FILE/TARGET_LINKER_FILE_BASE_NAME-non-valid-target-stderr.txt
similarity index 100%
rename from Tests/RunCMake/GeneratorExpression/TARGET_LINKER_FILE_BASE_NAME-non-valid-target-stderr.txt
rename to Tests/RunCMake/GenEx-TARGET_FILE/TARGET_LINKER_FILE_BASE_NAME-non-valid-target-stderr.txt
diff --git a/Tests/RunCMake/GeneratorExpression/TARGET_LINKER_FILE_BASE_NAME-non-valid-target.cmake b/Tests/RunCMake/GenEx-TARGET_FILE/TARGET_LINKER_FILE_BASE_NAME-non-valid-target.cmake
similarity index 100%
rename from Tests/RunCMake/GeneratorExpression/TARGET_LINKER_FILE_BASE_NAME-non-valid-target.cmake
rename to Tests/RunCMake/GenEx-TARGET_FILE/TARGET_LINKER_FILE_BASE_NAME-non-valid-target.cmake
diff --git a/Tests/RunCMake/GeneratorExpression/TARGET_LINKER_FILE_PREFIX-non-valid-target-result.txt b/Tests/RunCMake/GenEx-TARGET_FILE/TARGET_LINKER_FILE_PREFIX-non-valid-target-result.txt
similarity index 100%
rename from Tests/RunCMake/GeneratorExpression/TARGET_LINKER_FILE_PREFIX-non-valid-target-result.txt
rename to Tests/RunCMake/GenEx-TARGET_FILE/TARGET_LINKER_FILE_PREFIX-non-valid-target-result.txt
diff --git a/Tests/RunCMake/GeneratorExpression/TARGET_LINKER_FILE_PREFIX-non-valid-target-stderr.txt b/Tests/RunCMake/GenEx-TARGET_FILE/TARGET_LINKER_FILE_PREFIX-non-valid-target-stderr.txt
similarity index 100%
rename from Tests/RunCMake/GeneratorExpression/TARGET_LINKER_FILE_PREFIX-non-valid-target-stderr.txt
rename to Tests/RunCMake/GenEx-TARGET_FILE/TARGET_LINKER_FILE_PREFIX-non-valid-target-stderr.txt
diff --git a/Tests/RunCMake/GeneratorExpression/TARGET_LINKER_FILE_PREFIX-non-valid-target.cmake b/Tests/RunCMake/GenEx-TARGET_FILE/TARGET_LINKER_FILE_PREFIX-non-valid-target.cmake
similarity index 100%
rename from Tests/RunCMake/GeneratorExpression/TARGET_LINKER_FILE_PREFIX-non-valid-target.cmake
rename to Tests/RunCMake/GenEx-TARGET_FILE/TARGET_LINKER_FILE_PREFIX-non-valid-target.cmake
diff --git a/Tests/RunCMake/GeneratorExpression/TARGET_LINKER_FILE_SUFFIX-non-valid-target-result.txt b/Tests/RunCMake/GenEx-TARGET_FILE/TARGET_LINKER_FILE_SUFFIX-non-valid-target-result.txt
similarity index 100%
rename from Tests/RunCMake/GeneratorExpression/TARGET_LINKER_FILE_SUFFIX-non-valid-target-result.txt
rename to Tests/RunCMake/GenEx-TARGET_FILE/TARGET_LINKER_FILE_SUFFIX-non-valid-target-result.txt
diff --git a/Tests/RunCMake/GeneratorExpression/TARGET_LINKER_FILE_SUFFIX-non-valid-target-stderr.txt b/Tests/RunCMake/GenEx-TARGET_FILE/TARGET_LINKER_FILE_SUFFIX-non-valid-target-stderr.txt
similarity index 100%
rename from Tests/RunCMake/GeneratorExpression/TARGET_LINKER_FILE_SUFFIX-non-valid-target-stderr.txt
rename to Tests/RunCMake/GenEx-TARGET_FILE/TARGET_LINKER_FILE_SUFFIX-non-valid-target-stderr.txt
diff --git a/Tests/RunCMake/GeneratorExpression/TARGET_LINKER_FILE_SUFFIX-non-valid-target.cmake b/Tests/RunCMake/GenEx-TARGET_FILE/TARGET_LINKER_FILE_SUFFIX-non-valid-target.cmake
similarity index 100%
rename from Tests/RunCMake/GeneratorExpression/TARGET_LINKER_FILE_SUFFIX-non-valid-target.cmake
rename to Tests/RunCMake/GenEx-TARGET_FILE/TARGET_LINKER_FILE_SUFFIX-non-valid-target.cmake
diff --git a/Tests/RunCMake/GeneratorExpression/ValidTarget-TARGET_PDB_FILE-check.cmake b/Tests/RunCMake/GenEx-TARGET_FILE/ValidTarget-TARGET_PDB_FILE-check.cmake
similarity index 100%
rename from Tests/RunCMake/GeneratorExpression/ValidTarget-TARGET_PDB_FILE-check.cmake
rename to Tests/RunCMake/GenEx-TARGET_FILE/ValidTarget-TARGET_PDB_FILE-check.cmake
diff --git a/Tests/RunCMake/GeneratorExpression/ValidTarget-TARGET_PDB_FILE.cmake b/Tests/RunCMake/GenEx-TARGET_FILE/ValidTarget-TARGET_PDB_FILE.cmake
similarity index 100%
rename from Tests/RunCMake/GeneratorExpression/ValidTarget-TARGET_PDB_FILE.cmake
rename to Tests/RunCMake/GenEx-TARGET_FILE/ValidTarget-TARGET_PDB_FILE.cmake
diff --git a/Tests/RunCMake/GeneratorExpression/ValidTarget-TARGET_PDB_FILE_BASE_NAME-check.cmake b/Tests/RunCMake/GenEx-TARGET_FILE/ValidTarget-TARGET_PDB_FILE_BASE_NAME-check.cmake
similarity index 100%
rename from Tests/RunCMake/GeneratorExpression/ValidTarget-TARGET_PDB_FILE_BASE_NAME-check.cmake
rename to Tests/RunCMake/GenEx-TARGET_FILE/ValidTarget-TARGET_PDB_FILE_BASE_NAME-check.cmake
diff --git a/Tests/RunCMake/GeneratorExpression/ValidTarget-TARGET_PDB_FILE_BASE_NAME.cmake b/Tests/RunCMake/GenEx-TARGET_FILE/ValidTarget-TARGET_PDB_FILE_BASE_NAME.cmake
similarity index 100%
rename from Tests/RunCMake/GeneratorExpression/ValidTarget-TARGET_PDB_FILE_BASE_NAME.cmake
rename to Tests/RunCMake/GenEx-TARGET_FILE/ValidTarget-TARGET_PDB_FILE_BASE_NAME.cmake
diff --git a/Tests/RunCMake/GenEx-TARGET_FILE/empty.c b/Tests/RunCMake/GenEx-TARGET_FILE/empty.c
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/Tests/RunCMake/GenEx-TARGET_FILE/empty.c
diff --git a/Tests/RunCMake/GenerateExportHeader/RunCMakeTest.cmake b/Tests/RunCMake/GenerateExportHeader/RunCMakeTest.cmake
index 18c3340..5a5a7bf 100644
--- a/Tests/RunCMake/GenerateExportHeader/RunCMakeTest.cmake
+++ b/Tests/RunCMake/GenerateExportHeader/RunCMakeTest.cmake
@@ -26,4 +26,12 @@
   endforeach()
 endfunction()
 
+# remove these flags from the environment if they have been set
+# so the tests run the correct env
+set(env_cxx_flags $ENV{CXXFLAGS})
+if(env_cxx_flags)
+  string(REPLACE "-fvisibility=hidden" "" env_cxx_flags "${env_cxx_flags}")
+  string(REPLACE "-fvisibility-inlines-hidden" "" env_cxx_flags "${env_cxx_flags}")
+  set(ENV{CXXFLAGS} "${env_cxx_flags}")
+endif()
 run_GEH()
diff --git a/Tests/RunCMake/GenerateExportHeader/exportheader_test.cpp b/Tests/RunCMake/GenerateExportHeader/exportheader_test.cpp
index ba77679..dcaa4f2 100644
--- a/Tests/RunCMake/GenerateExportHeader/exportheader_test.cpp
+++ b/Tests/RunCMake/GenerateExportHeader/exportheader_test.cpp
@@ -32,14 +32,14 @@
     // trailing null to the string that we need to strip before testing for a
     // trailing space.
     if (refLine.size() && refLine[refLine.size() - 1] == 0) {
-      refLine = refLine.substr(0, refLine.size() - 1);
+      refLine.resize(refLine.size() - 1);
     }
     if (testLine.size() && testLine[testLine.size() - 1] == 0) {
-      testLine = testLine.substr(0, testLine.size() - 1);
+      testLine.resize(testLine.size() - 1);
     }
     // The reference files never have trailing spaces:
     if (testLine.size() && testLine[testLine.size() - 1] == ' ') {
-      testLine = testLine.substr(0, testLine.size() - 1);
+      testLine.resize(testLine.size() - 1);
     }
     if (refLine != testLine) {
       std::cout << "Ref and test are not the same:\n  Ref:  \"" << refLine
diff --git a/Tests/RunCMake/GeneratorExpression/BadCONFIG-stderr.txt b/Tests/RunCMake/GeneratorExpression/BadCONFIG-stderr.txt
index 42dd0ce..130de2b 100644
--- a/Tests/RunCMake/GeneratorExpression/BadCONFIG-stderr.txt
+++ b/Tests/RunCMake/GeneratorExpression/BadCONFIG-stderr.txt
@@ -10,15 +10,6 @@
 CMake Error at BadCONFIG.cmake:1 \(add_custom_target\):
   Error evaluating generator expression:
 
-    \$<CONFIG:Foo,Bar>
-
-  \$<CONFIG> expression requires one or zero parameters.
-Call Stack \(most recent call first\):
-  CMakeLists.txt:3 \(include\)
-+
-CMake Error at BadCONFIG.cmake:1 \(add_custom_target\):
-  Error evaluating generator expression:
-
     \$<CONFIG:Foo-Bar>
 
   Expression syntax not recognized.
diff --git a/Tests/RunCMake/GeneratorExpression/BadCONFIG.cmake b/Tests/RunCMake/GeneratorExpression/BadCONFIG.cmake
index 5c22aaa..1735ab7 100644
--- a/Tests/RunCMake/GeneratorExpression/BadCONFIG.cmake
+++ b/Tests/RunCMake/GeneratorExpression/BadCONFIG.cmake
@@ -1,6 +1,5 @@
 add_custom_target(check ALL COMMAND check
   $<CONFIG:.>
-  $<CONFIG:Foo,Bar>
   $<CONFIG:Foo-Bar>
   $<$<CONFIG:Foo-Nested>:foo>
   VERBATIM)
diff --git a/Tests/RunCMake/GeneratorExpression/CMakeLists.txt b/Tests/RunCMake/GeneratorExpression/CMakeLists.txt
index 12cd3c7..4b3de84 100644
--- a/Tests/RunCMake/GeneratorExpression/CMakeLists.txt
+++ b/Tests/RunCMake/GeneratorExpression/CMakeLists.txt
@@ -1,3 +1,3 @@
-cmake_minimum_required(VERSION 2.8.4)
+cmake_minimum_required(VERSION 2.8.12)
 project(${RunCMake_TEST} NONE)
 include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/GeneratorExpression/CONFIG-empty-entries-check.cmake b/Tests/RunCMake/GeneratorExpression/CONFIG-empty-entries-check.cmake
new file mode 100644
index 0000000..b43256b
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/CONFIG-empty-entries-check.cmake
@@ -0,0 +1,6 @@
+file(READ "${RunCMake_TEST_BINARY_DIR}/CONFIG-empty-entries-generated.txt" content)
+
+set(expected "1234")
+if(NOT content STREQUAL expected)
+  set(RunCMake_TEST_FAILED "actual content:\n [[${content}]]\nbut expected:\n [[${expected}]]")
+endif()
diff --git a/Tests/RunCMake/GeneratorExpression/CONFIG-empty-entries.cmake b/Tests/RunCMake/GeneratorExpression/CONFIG-empty-entries.cmake
new file mode 100644
index 0000000..a4d53f9
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/CONFIG-empty-entries.cmake
@@ -0,0 +1,9 @@
+cmake_policy(SET CMP0070 NEW)
+
+set(text)
+string(APPEND text "$<$<CONFIG:>:1>")
+string(APPEND text "$<$<CONFIG:Release,>:2>")
+string(APPEND text "$<$<CONFIG:,Release>:3>")
+string(APPEND text "$<$<CONFIG:Release,,Debug>:4>")
+string(APPEND text "$<$<CONFIG:Release,Debug>:5>")
+file(GENERATE OUTPUT CONFIG-empty-entries-generated.txt CONTENT  ${text})
diff --git a/Tests/RunCMake/GeneratorExpression/CONFIG-multiple-entries-check.cmake b/Tests/RunCMake/GeneratorExpression/CONFIG-multiple-entries-check.cmake
new file mode 100644
index 0000000..66f42c7
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/CONFIG-multiple-entries-check.cmake
@@ -0,0 +1,6 @@
+file(READ "${RunCMake_TEST_BINARY_DIR}/CONFIG-multiple-entries-generated.txt" content)
+
+set(expected "14")
+if(NOT content STREQUAL expected)
+  set(RunCMake_TEST_FAILED "actual content:\n [[${content}]]\nbut expected:\n [[${expected}]]")
+endif()
diff --git a/Tests/RunCMake/GeneratorExpression/CONFIG-multiple-entries.cmake b/Tests/RunCMake/GeneratorExpression/CONFIG-multiple-entries.cmake
new file mode 100644
index 0000000..6829282
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/CONFIG-multiple-entries.cmake
@@ -0,0 +1,8 @@
+cmake_policy(SET CMP0070 NEW)
+
+set(text)
+string(APPEND text "$<$<CONFIG:CustomConfig>:1>")
+string(APPEND text "$<$<CONFIG:Release>:2>")
+string(APPEND text "$<$<CONFIG:Debug,Release>:3>")
+string(APPEND text "$<$<CONFIG:Release,CustomConfig,Debug>:4>")
+file(GENERATE OUTPUT CONFIG-multiple-entries-generated.txt CONTENT "${text}")
diff --git a/Tests/RunCMake/GeneratorExpression/RunCMakeTest.cmake b/Tests/RunCMake/GeneratorExpression/RunCMakeTest.cmake
index 68a0172..6349112 100644
--- a/Tests/RunCMake/GeneratorExpression/RunCMakeTest.cmake
+++ b/Tests/RunCMake/GeneratorExpression/RunCMakeTest.cmake
@@ -12,6 +12,7 @@
 run_cmake(BadTargetTypeObject)
 run_cmake(BadInstallPrefix)
 run_cmake(BadSHELL_PATH)
+run_cmake(BadCONFIG)
 run_cmake(CMP0044-WARN)
 run_cmake(NonValidTarget-C_COMPILER_ID)
 run_cmake(NonValidTarget-CXX_COMPILER_ID)
@@ -19,43 +20,12 @@
 run_cmake(NonValidTarget-C_COMPILER_VERSION)
 run_cmake(NonValidTarget-CXX_COMPILER_VERSION)
 run_cmake(NonValidTarget-Fortran_COMPILER_VERSION)
-run_cmake(NonValidTarget-TARGET_BUNDLE_DIR)
-run_cmake(NonValidTarget-TARGET_BUNDLE_CONTENT_DIR)
 run_cmake(NonValidTarget-TARGET_PROPERTY)
 run_cmake(NonValidTarget-TARGET_POLICY)
-run_cmake(COMPILE_LANGUAGE-add_custom_target)
-run_cmake(COMPILE_LANGUAGE-add_custom_command)
-run_cmake(COMPILE_LANGUAGE-install)
-run_cmake(COMPILE_LANGUAGE-target_sources)
-run_cmake(COMPILE_LANGUAGE-add_executable)
-run_cmake(COMPILE_LANGUAGE-add_library)
-run_cmake(COMPILE_LANGUAGE-add_test)
-run_cmake(COMPILE_LANGUAGE-unknown-lang)
-run_cmake(COMPILE_LANG_AND_ID-add_custom_target)
-run_cmake(COMPILE_LANG_AND_ID-add_custom_command)
-run_cmake(COMPILE_LANG_AND_ID-install)
-run_cmake(COMPILE_LANG_AND_ID-target_sources)
-run_cmake(COMPILE_LANG_AND_ID-add_executable)
-run_cmake(COMPILE_LANG_AND_ID-add_library)
-run_cmake(COMPILE_LANG_AND_ID-add_test)
-run_cmake(COMPILE_LANG_AND_ID-unknown-lang)
-run_cmake(TARGET_FILE-recursion)
-run_cmake(OUTPUT_NAME-recursion)
-run_cmake(TARGET_FILE_PREFIX)
-run_cmake(TARGET_FILE_PREFIX-imported-target)
-run_cmake(TARGET_FILE_PREFIX-non-valid-target)
-run_cmake(TARGET_LINKER_FILE_PREFIX-non-valid-target)
-run_cmake(TARGET_FILE_SUFFIX)
-run_cmake(TARGET_FILE_SUFFIX-imported-target)
-run_cmake(TARGET_FILE_SUFFIX-non-valid-target)
-run_cmake(TARGET_LINKER_FILE_SUFFIX-non-valid-target)
-run_cmake_with_options(TARGET_FILE_BASE_NAME -DCMAKE_BUILD_TYPE:STRING=Debug)
-run_cmake_with_options(TARGET_FILE_BASE_NAME-imported-target -DCMAKE_BUILD_TYPE:STRING=Debug)
-run_cmake(TARGET_FILE_BASE_NAME-non-valid-target)
-run_cmake(TARGET_LINKER_FILE_BASE_NAME-non-valid-target)
 run_cmake(TARGET_PROPERTY-INCLUDE_DIRECTORIES)
 run_cmake(TARGET_PROPERTY-LOCATION)
 run_cmake(TARGET_PROPERTY-SOURCES)
+run_cmake(TARGET_PROPERTY-ALIAS_GLOBAL)
 run_cmake(LINK_ONLY-not-linking)
 run_cmake(TARGET_EXISTS-no-arg)
 run_cmake(TARGET_EXISTS-empty-arg)
@@ -65,15 +35,6 @@
 run_cmake(TARGET_NAME_IF_EXISTS-empty-arg)
 run_cmake(TARGET_NAME_IF_EXISTS)
 run_cmake(TARGET_NAME_IF_EXISTS-not-a-target)
-run_cmake(TARGET_GENEX_EVAL-no-arg)
-run_cmake(TARGET_GENEX_EVAL-no-target)
-run_cmake(TARGET_GENEX_EVAL-non-valid-target)
-run_cmake(TARGET_GENEX_EVAL-recursion1)
-run_cmake(TARGET_GENEX_EVAL-recursion2)
-run_cmake(TARGET_GENEX_EVAL)
-run_cmake(GENEX_EVAL-recursion1)
-run_cmake(GENEX_EVAL-recursion2)
-run_cmake(GENEX_EVAL)
 run_cmake(REMOVE_DUPLICATES-empty)
 run_cmake(REMOVE_DUPLICATES-1)
 run_cmake(REMOVE_DUPLICATES-2)
@@ -84,19 +45,18 @@
 run_cmake(FILTER-Exclude)
 run_cmake(FILTER-Include)
 
-run_cmake(ImportedTarget-TARGET_BUNDLE_DIR)
-run_cmake(ImportedTarget-TARGET_BUNDLE_CONTENT_DIR)
-run_cmake(ImportedTarget-TARGET_PDB_FILE)
-run_cmake(ImportedTarget-TARGET_PDB_FILE_BASE_NAME)
-if(LINKER_SUPPORTS_PDB)
-  run_cmake(NonValidTarget-TARGET_PDB_FILE)
-  run_cmake(ValidTarget-TARGET_PDB_FILE)
-  run_cmake(NonValidTarget-TARGET_PDB_FILE_BASE_NAME)
-  run_cmake(ValidTarget-TARGET_PDB_FILE_BASE_NAME)
+if(RunCMake_GENERATOR_IS_MULTI_CONFIG)
+  set(RunCMake_TEST_OPTIONS [==[-DCMAKE_CONFIGURATION_TYPES=CustomConfig]==])
 else()
-  run_cmake(NonValidCompiler-TARGET_PDB_FILE)
-  run_cmake(NonValidCompiler-TARGET_PDB_FILE_BASE_NAME)
+  set(RunCMake_TEST_OPTIONS [==[-DCMAKE_BUILD_TYPE=CustomConfig]==])
 endif()
+run_cmake(CONFIG-multiple-entries)
+if(RunCMake_GENERATOR_IS_MULTI_CONFIG)
+  set(RunCMake_TEST_OPTIONS [==[-DCMAKE_CONFIGURATION_TYPES=]==])
+else()
+  set(RunCMake_TEST_OPTIONS [==[-DCMAKE_BUILD_TYPE=]==])
+endif()
+run_cmake(CONFIG-empty-entries)
 
 set(RunCMake_TEST_OPTIONS -DCMAKE_POLICY_DEFAULT_CMP0085:STRING=OLD)
 run_cmake(CMP0085-OLD)
diff --git a/Tests/RunCMake/GeneratorExpression/TARGET_PROPERTY-ALIAS_GLOBAL-check.cmake b/Tests/RunCMake/GeneratorExpression/TARGET_PROPERTY-ALIAS_GLOBAL-check.cmake
new file mode 100644
index 0000000..0fbf837
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/TARGET_PROPERTY-ALIAS_GLOBAL-check.cmake
@@ -0,0 +1,6 @@
+file(STRINGS ${RunCMake_TEST_BINARY_DIR}/alias_global.txt alias_global)
+
+set(expected "TRUE(lib-global):TRUE;FALSE(lib-local):FALSE;TRUE(lib):FALSE")
+if(NOT alias_global STREQUAL expected)
+  set(RunCMake_TEST_FAILED "ALIAS_GLOBAL was:\n [[${alias_global}]]\nbut expected:\n [[${expected}]]")
+endif()
diff --git a/Tests/RunCMake/GeneratorExpression/TARGET_PROPERTY-ALIAS_GLOBAL.cmake b/Tests/RunCMake/GeneratorExpression/TARGET_PROPERTY-ALIAS_GLOBAL.cmake
new file mode 100644
index 0000000..212c034
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/TARGET_PROPERTY-ALIAS_GLOBAL.cmake
@@ -0,0 +1,16 @@
+
+cmake_minimum_required(VERSION 3.17)
+
+add_library(lib-global SHARED IMPORTED GLOBAL)
+add_library(alias-lib-global ALIAS lib-global)
+
+add_library(lib-local SHARED IMPORTED)
+add_library(alias-lib-local ALIAS lib-local)
+
+add_library(lib SHARED IMPORTED)
+add_library(alias-lib ALIAS lib)
+# switch from local to global
+set_property (TARGET lib PROPERTY IMPORTED_GLOBAL TRUE)
+
+
+file(GENERATE OUTPUT alias_global.txt CONTENT "$<TARGET_PROPERTY:lib-global,IMPORTED_GLOBAL>($<TARGET_PROPERTY:alias-lib-global,ALIASED_TARGET>):$<TARGET_PROPERTY:alias-lib-global,ALIAS_GLOBAL>\n$<TARGET_PROPERTY:lib-local,IMPORTED_GLOBAL>($<TARGET_PROPERTY:alias-lib-local,ALIASED_TARGET>):$<TARGET_PROPERTY:alias-lib-local,ALIAS_GLOBAL>\n$<TARGET_PROPERTY:lib,IMPORTED_GLOBAL>($<TARGET_PROPERTY:alias-lib,ALIASED_TARGET>):$<TARGET_PROPERTY:alias-lib,ALIAS_GLOBAL>\n")
diff --git a/Tests/RunCMake/GeneratorExpression/TARGET_PROPERTY-INCLUDE_DIRECTORIES-check.cmake b/Tests/RunCMake/GeneratorExpression/TARGET_PROPERTY-INCLUDE_DIRECTORIES-check.cmake
new file mode 100644
index 0000000..ecf7bfe
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/TARGET_PROPERTY-INCLUDE_DIRECTORIES-check.cmake
@@ -0,0 +1,17 @@
+file(READ "${RunCMake_TEST_BINARY_DIR}/out.txt" content)
+
+unset(RunCMake_TEST_FAILED)
+
+if (NOT content MATCHES "(INCLUDES1:${RunCMake_TEST_SOURCE_DIR}/include)")
+  string(APPEND RunCMake_TEST_FAILED "wrong content for INCLUDES1: \"${CMAKE_MATCH_1}\"\n")
+endif()
+
+if (NOT content MATCHES "(INCLUDES2:><)")
+  string(APPEND RunCMake_TEST_FAILED "wrong content for INCLUDES2: \"${CMAKE_MATCH_1}\"\n")
+endif()
+if (NOT content MATCHES "(INCLUDES3:><)")
+  string(APPEND RunCMake_TEST_FAILED "wrong content for INCLUDES3: \"${CMAKE_MATCH_1}\"\n")
+endif()
+if (NOT content MATCHES "(CUSTOM:>;;<)")
+  string(APPEND RunCMake_TEST_FAILED "wrong content for CUSTOM: \"${CMAKE_MATCH_1}\"\n")
+endif()
diff --git a/Tests/RunCMake/GeneratorExpression/TARGET_PROPERTY-INCLUDE_DIRECTORIES.cmake b/Tests/RunCMake/GeneratorExpression/TARGET_PROPERTY-INCLUDE_DIRECTORIES.cmake
index cb6f4d8..e9855be 100644
--- a/Tests/RunCMake/GeneratorExpression/TARGET_PROPERTY-INCLUDE_DIRECTORIES.cmake
+++ b/Tests/RunCMake/GeneratorExpression/TARGET_PROPERTY-INCLUDE_DIRECTORIES.cmake
@@ -14,5 +14,10 @@
 add_library(foo4 STATIC empty.c)
 target_include_directories(foo4 PUBLIC $<TARGET_PROPERTY:foo3,INCLUDE_DIRECTORIES>)
 
+add_library (foo5 SHARED empty.c)
+set_property(TARGET foo5 PROPERTY INCLUDE_DIRECTORIES "$<$<COMPILE_LANGUAGE:CUDA>:/include/CUDA>" "$<$<COMPILE_LANGUAGE:Fortran>:/include/Fortran>")
+set_property(TARGET foo5 PROPERTY INTERFACE_INCLUDE_DIRECTORIES "$<$<COMPILE_LANGUAGE:CUDA>:/include/CUDA>" "$<$<COMPILE_LANGUAGE:Fortran>:/include/Fortran>")
+set_property(TARGET foo5 PROPERTY CUSTOM ";;")
+
 # Evaluate a genex that looks up INCLUDE_DIRECTORIES on multiple targets.
-file(GENERATE OUTPUT out.txt CONTENT "$<TARGET_PROPERTY:foo4,INCLUDE_DIRECTORIES>")
+file(GENERATE OUTPUT out.txt CONTENT "INCLUDES1:$<TARGET_PROPERTY:foo4,INCLUDE_DIRECTORIES>\nINCLUDES2:>$<TARGET_PROPERTY:foo5,INTERFACE_INCLUDE_DIRECTORIES><\nINCLUDES3:>$<TARGET_PROPERTY:foo5,INCLUDE_DIRECTORIES><\nCUSTOM:>$<TARGET_PROPERTY:foo5,CUSTOM><\n")
diff --git a/Tests/RunCMake/GeneratorPlatform/CMakeLists.txt b/Tests/RunCMake/GeneratorPlatform/CMakeLists.txt
index 12cd3c7..74b3ff8 100644
--- a/Tests/RunCMake/GeneratorPlatform/CMakeLists.txt
+++ b/Tests/RunCMake/GeneratorPlatform/CMakeLists.txt
@@ -1,3 +1,3 @@
-cmake_minimum_required(VERSION 2.8.4)
+cmake_minimum_required(VERSION 3.3)
 project(${RunCMake_TEST} NONE)
 include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/GeneratorToolset/CMakeLists.txt b/Tests/RunCMake/GeneratorToolset/CMakeLists.txt
index 12cd3c7..74b3ff8 100644
--- a/Tests/RunCMake/GeneratorToolset/CMakeLists.txt
+++ b/Tests/RunCMake/GeneratorToolset/CMakeLists.txt
@@ -1,3 +1,3 @@
-cmake_minimum_required(VERSION 2.8.4)
+cmake_minimum_required(VERSION 3.3)
 project(${RunCMake_TEST} NONE)
 include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/GoogleTest/GoogleTest-configuration-debug-stdout.txt b/Tests/RunCMake/GoogleTest/GoogleTest-configuration-debug-stdout.txt
new file mode 100644
index 0000000..1f5d1a5
--- /dev/null
+++ b/Tests/RunCMake/GoogleTest/GoogleTest-configuration-debug-stdout.txt
@@ -0,0 +1,5 @@
+Test project .*GoogleTest-discovery-multi-config
+[ \t]*Test #[0-9]+: configuration\.case_release \(Disabled\)
+[ \t]*Test #[0-9]+: configuration\.case_debug
++
+Total Tests: 2
diff --git a/Tests/RunCMake/GoogleTest/GoogleTest-configuration-release-stdout.txt b/Tests/RunCMake/GoogleTest/GoogleTest-configuration-release-stdout.txt
new file mode 100644
index 0000000..4f91664
--- /dev/null
+++ b/Tests/RunCMake/GoogleTest/GoogleTest-configuration-release-stdout.txt
@@ -0,0 +1,5 @@
+Test project .*GoogleTest-discovery-multi-config
+[ \t]*Test #[0-9]+: configuration\.case_release
+[ \t]*Test #[0-9]+: configuration\.case_debug \(Disabled\)
++
+Total Tests: 2
diff --git a/Tests/RunCMake/GoogleTest/GoogleTest-discovery-timeout-result.txt b/Tests/RunCMake/GoogleTest/GoogleTest-discovery-POST_BUILD-timeout-build-result.txt
similarity index 100%
copy from Tests/RunCMake/GoogleTest/GoogleTest-discovery-timeout-result.txt
copy to Tests/RunCMake/GoogleTest/GoogleTest-discovery-POST_BUILD-timeout-build-result.txt
diff --git a/Tests/RunCMake/GoogleTest/GoogleTest-discovery-timeout-stdout.txt b/Tests/RunCMake/GoogleTest/GoogleTest-discovery-POST_BUILD-timeout-build-stdout.txt
similarity index 100%
rename from Tests/RunCMake/GoogleTest/GoogleTest-discovery-timeout-stdout.txt
rename to Tests/RunCMake/GoogleTest/GoogleTest-discovery-POST_BUILD-timeout-build-stdout.txt
diff --git a/Tests/RunCMake/GoogleTest/GoogleTest-discovery-timeout-result.txt b/Tests/RunCMake/GoogleTest/GoogleTest-discovery-POST_BUILD-timeout-test-result.txt
similarity index 100%
rename from Tests/RunCMake/GoogleTest/GoogleTest-discovery-timeout-result.txt
rename to Tests/RunCMake/GoogleTest/GoogleTest-discovery-POST_BUILD-timeout-test-result.txt
diff --git a/Tests/RunCMake/GoogleTest/GoogleTest-discovery-POST_BUILD-timeout-test-stderr.txt b/Tests/RunCMake/GoogleTest/GoogleTest-discovery-POST_BUILD-timeout-test-stderr.txt
new file mode 100644
index 0000000..f6be939
--- /dev/null
+++ b/Tests/RunCMake/GoogleTest/GoogleTest-discovery-POST_BUILD-timeout-test-stderr.txt
@@ -0,0 +1,2 @@
+Unable to find executable: discovery_timeout_test_NOT_BUILT
+Errors while running CTest
diff --git a/Tests/RunCMake/GoogleTest/GoogleTest-discovery-POST_BUILD-timeout-test-stdout.txt b/Tests/RunCMake/GoogleTest/GoogleTest-discovery-POST_BUILD-timeout-test-stdout.txt
new file mode 100644
index 0000000..d9de3f8
--- /dev/null
+++ b/Tests/RunCMake/GoogleTest/GoogleTest-discovery-POST_BUILD-timeout-test-stdout.txt
@@ -0,0 +1,18 @@
+Test project .*GoogleTest-discovery-timeout
+[ \t]*Start [0-9]+: discovery_timeout_test_NOT_BUILT
+Could not find executable discovery_timeout_test_NOT_BUILT
+Looked in the following places:
+discovery_timeout_test_NOT_BUILT
+discovery_timeout_test_NOT_BUILT(\.exe)?
+Debug/discovery_timeout_test_NOT_BUILT
+Debug/discovery_timeout_test_NOT_BUILT(\.exe)?
+Debug/discovery_timeout_test_NOT_BUILT
+Debug/discovery_timeout_test_NOT_BUILT(\.exe)?
+[^\n]+discovery_timeout_test_NOT_BUILT +\.+\*\*\*Not Run +[0-9.]+ sec
++
+0% tests passed, 1 tests failed out of 1
++
+Total Test time \(real\) =   +[0-9.]+ sec
++
+The following tests FAILED:
+[^\n]+discovery_timeout_test_NOT_BUILT \(Not Run\)
diff --git a/Tests/RunCMake/GoogleTest/GoogleTest-discovery-PRE_TEST-timeout-test-stderr.txt b/Tests/RunCMake/GoogleTest/GoogleTest-discovery-PRE_TEST-timeout-test-stderr.txt
new file mode 100644
index 0000000..75afe4a
--- /dev/null
+++ b/Tests/RunCMake/GoogleTest/GoogleTest-discovery-PRE_TEST-timeout-test-stderr.txt
@@ -0,0 +1,8 @@
+CMake Error at .*GoogleTestAddTests.cmake:[0-9]+ \(message\):
+[ \t]*Error running test executable.
++
+[ \t]*Path: '.*discovery_timeout_test(\.exe)?'
+[ \t]*Result: Process terminated due to timeout
+[ \t]*Output:
+[ \t]*timeout.
+[ \t]*case
diff --git a/Tests/RunCMake/GoogleTest/GoogleTest-discovery-PRE_TEST-timeout-test-stdout.txt b/Tests/RunCMake/GoogleTest/GoogleTest-discovery-PRE_TEST-timeout-test-stdout.txt
new file mode 100644
index 0000000..d65061f
--- /dev/null
+++ b/Tests/RunCMake/GoogleTest/GoogleTest-discovery-PRE_TEST-timeout-test-stdout.txt
@@ -0,0 +1 @@
+Test project .*GoogleTest-discovery-timeout
diff --git a/Tests/RunCMake/GoogleTest/GoogleTest-skip-timeout-stdout.txt b/Tests/RunCMake/GoogleTest/GoogleTest-skip-timeout-stdout.txt
new file mode 100644
index 0000000..eeecb6a
--- /dev/null
+++ b/Tests/RunCMake/GoogleTest/GoogleTest-skip-timeout-stdout.txt
@@ -0,0 +1,10 @@
+Test project .*
+    Start 20: skip_test.test1
+1/1 Test #20: skip_test.test1 \.+\*\*\*Skipped +[0-9.]+ sec
+
+100% tests passed, 0 tests failed out of 1
+
+Total Test time \(real\) = +[0-9.]+ sec
+
+The following tests did not run:
+.*20 - skip_test\.test1 \(Skipped\)
diff --git a/Tests/RunCMake/GoogleTest/GoogleTest-test1-stdout.txt b/Tests/RunCMake/GoogleTest/GoogleTest-test1-stdout.txt
index 5f7753d..7fb3919 100644
--- a/Tests/RunCMake/GoogleTest/GoogleTest-test1-stdout.txt
+++ b/Tests/RunCMake/GoogleTest/GoogleTest-test1-stdout.txt
@@ -1,22 +1,28 @@
 Test project .*
-    Start 1: TEST:basic\.case_foo!1
-1/8 Test #1: TEST:basic\.case_foo!1 \.+ +Passed +[0-9.]+ sec
-    Start 2: TEST:basic\.case_bar!1
-2/8 Test #2: TEST:basic\.case_bar!1 \.+ +Passed +[0-9.]+ sec
-    Start 3: TEST:basic\.disabled_case!1
-3/8 Test #3: TEST:basic\.disabled_case!1 \.+\*+Not Run \(Disabled\) +[0-9.]+ sec
-    Start 4: TEST:disabled\.case!1
-4/8 Test #4: TEST:disabled\.case!1 \.+\*+Not Run \(Disabled\) +[0-9.]+ sec
-    Start 5: TEST:typed/short\.case!1
-5/8 Test #5: TEST:typed/short\.case!1 \.+ +Passed +[0-9.]+ sec
-    Start 6: TEST:typed/float\.case!1
-6/8 Test #6: TEST:typed/float\.case!1 \.+ +Passed +[0-9.]+ sec
-    Start 7: TEST:value/test\.case/1!1
-7/8 Test #7: TEST:value/test\.case/1!1 \.+ +Passed +[0-9.]+ sec
-    Start 8: TEST:value/test\.case/"foo"!1
-8/8 Test #8: TEST:value/test\.case/"foo"!1 \.+ +Passed +[0-9.]+ sec
+      Start  1: TEST:basic\.case_foo!1
+ 1/11 Test  #1: TEST:basic\.case_foo!1 \.+ +Passed +[0-9.]+ sec
+      Start  2: TEST:basic\.case_bar!1
+ 2/11 Test  #2: TEST:basic\.case_bar!1 \.+ +Passed +[0-9.]+ sec
+      Start  3: TEST:basic\.disabled_case!1
+ 3/11 Test  #3: TEST:basic\.disabled_case!1 \.+\*+Not Run \(Disabled\) +[0-9.]+ sec
+      Start  4: TEST:disabled\.case!1
+ 4/11 Test  #4: TEST:disabled\.case!1 \.+\*+Not Run \(Disabled\) +[0-9.]+ sec
+      Start  5: TEST:typed/short\.case!1
+ 5/11 Test  #5: TEST:typed/short\.case!1 \.+ +Passed +[0-9.]+ sec
+      Start  6: TEST:typed/float\.case!1
+ 6/11 Test  #6: TEST:typed/float\.case!1 \.+ +Passed +[0-9.]+ sec
+      Start  7: TEST:value/test\.case/1!1
+ 7/11 Test  #7: TEST:value/test\.case/1!1 \.+ +Passed +[0-9.]+ sec
+      Start  8: TEST:value/test\.case/"foo"!1
+ 8/11 Test  #8: TEST:value/test\.case/"foo"!1 \.+ +Passed +[0-9.]+ sec
+      Start  9: TEST:param/special\.case/"semicolon;"!1
+ 9/11 Test  #9: TEST:param/special\.case/"semicolon;"!1 \.+ +Passed +[0-9.]+ sec
+      Start 10: TEST:param/special\.case/"backslash\\"!1
+10/11 Test #10: TEST:param/special\.case/"backslash\\"!1 \.+ +Passed +[0-9.]+ sec
+      Start 11: TEST:param/special\.case/"\$\{var\}"!1
+11/11 Test #11: TEST:param/special\.case/"\$\{var\}"!1 \.+ +Passed +[0-9.]+ sec
 
-100% tests passed, 0 tests failed out of 6
+100% tests passed, 0 tests failed out of 9
 
 Total Test time \(real\) = +[0-9.]+ sec
 
diff --git a/Tests/RunCMake/GoogleTest/GoogleTest-test2-stdout.txt b/Tests/RunCMake/GoogleTest/GoogleTest-test2-stdout.txt
index 960c0b9..58c4d10 100644
--- a/Tests/RunCMake/GoogleTest/GoogleTest-test2-stdout.txt
+++ b/Tests/RunCMake/GoogleTest/GoogleTest-test2-stdout.txt
@@ -1,25 +1,31 @@
 Test project .*
-    Start  9: TEST:basic\.case_foo!2
-1/8 Test  #9: TEST:basic\.case_foo!2 \.+ +Passed +[0-9.]+ sec
-    Start 10: TEST:basic\.case_bar!2
-2/8 Test #10: TEST:basic\.case_bar!2 \.+ +Passed +[0-9.]+ sec
-    Start 11: TEST:basic\.disabled_case!2
-3/8 Test #11: TEST:basic\.disabled_case!2 \.+\*+Not Run \(Disabled\) +[0-9.]+ sec
-    Start 12: TEST:disabled\.case!2
-4/8 Test #12: TEST:disabled\.case!2 \.+\*+Not Run \(Disabled\) +[0-9.]+ sec
-    Start 13: TEST:typed/short\.case!2
-5/8 Test #13: TEST:typed/short\.case!2 \.+ +Passed +[0-9.]+ sec
-    Start 14: TEST:typed/float\.case!2
-6/8 Test #14: TEST:typed/float\.case!2 \.+ +Passed +[0-9.]+ sec
-    Start 15: TEST:value/test\.case/1!2
-7/8 Test #15: TEST:value/test\.case/1!2 \.+ +Passed +[0-9.]+ sec
-    Start 16: TEST:value/test\.case/"foo"!2
-8/8 Test #16: TEST:value/test\.case/"foo"!2 \.+ +Passed +[0-9.]+ sec
+      Start 12: TEST:basic\.case_foo!2
+ 1/11 Test #12: TEST:basic\.case_foo!2 \.+ +Passed +[0-9.]+ sec
+      Start 13: TEST:basic\.case_bar!2
+ 2/11 Test #13: TEST:basic\.case_bar!2 \.+ +Passed +[0-9.]+ sec
+      Start 14: TEST:basic\.disabled_case!2
+ 3/11 Test #14: TEST:basic\.disabled_case!2 \.+\*+Not Run \(Disabled\) +[0-9.]+ sec
+      Start 15: TEST:disabled\.case!2
+ 4/11 Test #15: TEST:disabled\.case!2 \.+\*+Not Run \(Disabled\) +[0-9.]+ sec
+      Start 16: TEST:typed/short\.case!2
+ 5/11 Test #16: TEST:typed/short\.case!2 \.+ +Passed +[0-9.]+ sec
+      Start 17: TEST:typed/float\.case!2
+ 6/11 Test #17: TEST:typed/float\.case!2 \.+ +Passed +[0-9.]+ sec
+      Start 18: TEST:value/test\.case/1!2
+ 7/11 Test #18: TEST:value/test\.case/1!2 \.+ +Passed +[0-9.]+ sec
+      Start 19: TEST:value/test\.case/"foo"!2
+ 8/11 Test #19: TEST:value/test\.case/"foo"!2 \.+ +Passed +[0-9.]+ sec
+      Start 20: TEST:param/special\.case/"semicolon;"!2
+ 9/11 Test #20: TEST:param/special\.case/"semicolon;"!2 \.+ +Passed +[0-9.]+ sec
+      Start 21: TEST:param/special\.case/"backslash\\"!2
+10/11 Test #21: TEST:param/special\.case/"backslash\\"!2 \.+ +Passed +[0-9.]+ sec
+      Start 22: TEST:param/special\.case/"\$\{var\}"!2
+11/11 Test #22: TEST:param/special\.case/"\$\{var\}"!2 \.+ +Passed +[0-9.]+ sec
 
-100% tests passed, 0 tests failed out of 6
+100% tests passed, 0 tests failed out of 9
 
 Total Test time \(real\) = +[0-9.]+ sec
 
 The following tests did not run:
-.*11 - TEST:basic\.disabled_case!2 \(Disabled\)
-.*12 - TEST:disabled\.case!2 \(Disabled\)
+.*14 - TEST:basic\.disabled_case!2 \(Disabled\)
+.*15 - TEST:disabled\.case!2 \(Disabled\)
diff --git a/Tests/RunCMake/GoogleTest/GoogleTest.cmake b/Tests/RunCMake/GoogleTest/GoogleTest.cmake
index 31808c6..6aa2658 100644
--- a/Tests/RunCMake/GoogleTest/GoogleTest.cmake
+++ b/Tests/RunCMake/GoogleTest/GoogleTest.cmake
@@ -1,5 +1,4 @@
-project(test_include_dirs)
-include(CTest)
+project(test_include_dirs LANGUAGES CXX)
 include(GoogleTest)
 
 enable_testing()
@@ -50,10 +49,8 @@
   PROPERTIES TIMEOUT 2
 )
 
-add_executable(discovery_timeout_test timeout_test.cpp)
-target_compile_definitions(discovery_timeout_test PRIVATE discoverySleepSec=10)
+add_executable(skip_test skip_test.cpp)
+
 gtest_discover_tests(
-  discovery_timeout_test
-  TEST_PREFIX discovery_
-  DISCOVERY_TIMEOUT 2
+  skip_test
 )
diff --git a/Tests/RunCMake/GoogleTest/GoogleTestDiscoveryMultiConfig.cmake b/Tests/RunCMake/GoogleTest/GoogleTestDiscoveryMultiConfig.cmake
new file mode 100644
index 0000000..df784fe
--- /dev/null
+++ b/Tests/RunCMake/GoogleTest/GoogleTestDiscoveryMultiConfig.cmake
@@ -0,0 +1,13 @@
+project(test_include_dirs LANGUAGES CXX)
+include(GoogleTest)
+
+enable_testing()
+
+add_executable(configuration_gtest configuration_gtest.cpp)
+target_compile_definitions(configuration_gtest PRIVATE $<$<CONFIG:Debug>:DEBUG=1>)
+
+gtest_discover_tests(
+  configuration_gtest
+  PROPERTIES LABELS CONFIG
+  DISCOVERY_MODE PRE_TEST
+)
diff --git a/Tests/RunCMake/GoogleTest/GoogleTestDiscoveryTimeout.cmake b/Tests/RunCMake/GoogleTest/GoogleTestDiscoveryTimeout.cmake
new file mode 100644
index 0000000..20e9d65
--- /dev/null
+++ b/Tests/RunCMake/GoogleTest/GoogleTestDiscoveryTimeout.cmake
@@ -0,0 +1,13 @@
+project(test_include_dirs LANGUAGES CXX)
+include(GoogleTest)
+
+enable_testing()
+
+add_executable(discovery_timeout_test timeout_test.cpp)
+target_compile_definitions(discovery_timeout_test PRIVATE discoverySleepSec=10)
+gtest_discover_tests(
+  discovery_timeout_test
+  TEST_PREFIX discovery_
+  DISCOVERY_TIMEOUT 2
+  DISCOVERY_MODE ${DISCOVERY_MODE}
+)
diff --git a/Tests/RunCMake/GoogleTest/GoogleTestXML-result-check.cmake b/Tests/RunCMake/GoogleTest/GoogleTestXML-result-check.cmake
new file mode 100644
index 0000000..3bfdac3
--- /dev/null
+++ b/Tests/RunCMake/GoogleTest/GoogleTestXML-result-check.cmake
@@ -0,0 +1,4 @@
+set(RESULT_FILE "${RunCMake_TEST_BINARY_DIR}/GoogleTestXML.Foo.xml")
+if(NOT EXISTS ${RESULT_FILE})
+  set(RunCMake_TEST_FAILED "Result XML file ${RESULT_FILE} was not created")
+endif()
diff --git a/Tests/RunCMake/GoogleTest/GoogleTestXML-special-result-check.cmake b/Tests/RunCMake/GoogleTest/GoogleTestXML-special-result-check.cmake
new file mode 100644
index 0000000..fea0a6b
--- /dev/null
+++ b/Tests/RunCMake/GoogleTest/GoogleTestXML-special-result-check.cmake
@@ -0,0 +1,28 @@
+set(RESULT_FILES
+  "${RunCMake_TEST_BINARY_DIR}/GoogleTestXMLSpecial/cases.case/0.xml"
+  "${RunCMake_TEST_BINARY_DIR}/GoogleTestXMLSpecial/cases.case/1.xml"
+  "${RunCMake_TEST_BINARY_DIR}/GoogleTestXMLSpecial/cases.case/2.xml"
+)
+
+# Check result files exist
+foreach(file ${RESULT_FILES})
+  if(NOT EXISTS ${file})
+    if(NOT ${RunCMake_TEST_FAILED} STREQUAL "")
+      set(RunCMake_TEST_FAILED "${RunCMake_TEST_FAILED}\n")
+    endif()
+    set(RunCMake_TEST_FAILED "${RunCMake_TEST_FAILED}Result XML file ${file} was not created")
+  endif()
+endforeach()
+
+# and no other xml files are created
+file(GLOB_RECURSE file_list "${RunCMake_TEST_BINARY_DIR}/GoogleTestXMLSpecial/*/*.xml" LIST_DIRECTORIES false)
+
+foreach(file ${file_list})
+  list(FIND RESULT_FILES "${file}" idx)
+  if(-1 EQUAL ${idx})
+    if(NOT ${RunCMake_TEST_FAILED} STREQUAL "")
+      set(RunCMake_TEST_FAILED "${RunCMake_TEST_FAILED}\n")
+    endif()
+    set(RunCMake_TEST_FAILED "${RunCMake_TEST_FAILED}Invalid file ${file} was created")
+  endif()
+endforeach()
diff --git a/Tests/RunCMake/GoogleTest/GoogleTestXML.cmake b/Tests/RunCMake/GoogleTest/GoogleTestXML.cmake
new file mode 100644
index 0000000..fb91c0e
--- /dev/null
+++ b/Tests/RunCMake/GoogleTest/GoogleTestXML.cmake
@@ -0,0 +1,21 @@
+project(test_include_dirs LANGUAGES CXX)
+include(GoogleTest)
+
+enable_testing()
+
+# This creates the folder structure for the paramterized tests
+# to avoid handling missing folders in C++
+#
+# This must match the match the name defined in xml_output.cpp
+# for every instance of tests with GetParam.
+#
+# The folder name is created fom the test name (output of the line
+# without leading spaces: "GoogleTestXMLSpecial/cases.") and
+# the parts until the last slash ("case/"). These parts are concatenated.
+file(MAKE_DIRECTORY "${CMAKE_BINARY_DIR}/GoogleTestXMLSpecial/cases.case")
+
+add_executable(xml_output xml_output.cpp)
+gtest_discover_tests(
+  xml_output
+  XML_OUTPUT_DIR ${CMAKE_BINARY_DIR}
+)
diff --git a/Tests/RunCMake/GoogleTest/RunCMakeTest.cmake b/Tests/RunCMake/GoogleTest/RunCMakeTest.cmake
index 0fa4e2a..530c8ab 100644
--- a/Tests/RunCMake/GoogleTest/RunCMakeTest.cmake
+++ b/Tests/RunCMake/GoogleTest/RunCMakeTest.cmake
@@ -1,6 +1,6 @@
 include(RunCMake)
 
-function(run_GoogleTest)
+function(run_GoogleTest DISCOVERY_MODE)
   # Use a single build tree for a few tests without cleaning.
   set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/GoogleTest-build)
   set(RunCMake_TEST_NO_CLEAN 1)
@@ -10,7 +10,7 @@
   file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}")
   file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}")
 
-  run_cmake(GoogleTest)
+  run_cmake_with_options(GoogleTest -DCMAKE_GTEST_DISCOVER_TESTS_DISCOVERY_MODE=${DISCOVERY_MODE})
 
   run_cmake_command(GoogleTest-build
     ${CMAKE_COMMAND}
@@ -26,15 +26,6 @@
     --target property_timeout_test
   )
 
-  set(RunCMake_TEST_OUTPUT_MERGE 1)
-  run_cmake_command(GoogleTest-discovery-timeout
-    ${CMAKE_COMMAND}
-    --build .
-    --config Debug
-    --target discovery_timeout_test
-  )
-  set(RunCMake_TEST_OUTPUT_MERGE 0)
-
   run_cmake_command(GoogleTest-test1
     ${CMAKE_CTEST_COMMAND}
     -C Debug
@@ -69,6 +60,130 @@
     -R property_timeout\\.case_with_discovery
     --no-label-summary
   )
+
+  run_cmake_command(GoogleTest-build
+    ${CMAKE_COMMAND}
+    --build .
+    --config Debug
+    --target skip_test
+  )
+
+  run_cmake_command(GoogleTest-skip-test
+    ${CMAKE_CTEST_COMMAND}
+    -C Debug
+    -R skip_test
+    --no-label-summary
+  )
 endfunction()
 
-run_GoogleTest()
+function(run_GoogleTestXML DISCOVERY_MODE)
+  # Use a single build tree for a few tests without cleaning.
+  set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/GoogleTestXML-build)
+  set(RunCMake_TEST_NO_CLEAN 1)
+  if(NOT RunCMake_GENERATOR_IS_MULTI_CONFIG)
+    set(RunCMake_TEST_OPTIONS -DCMAKE_BUILD_TYPE=Debug)
+  endif()
+  file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}")
+  file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}")
+
+  run_cmake_with_options(GoogleTestXML -DCMAKE_GTEST_DISCOVER_TESTS_DISCOVERY_MODE=${DISCOVERY_MODE})
+
+  run_cmake_command(GoogleTestXML-discovery
+  ${CMAKE_COMMAND}
+  --build .
+  --config Debug
+  --target xml_output
+  )
+
+  run_cmake_command(GoogleTestXML-result
+  ${CMAKE_CTEST_COMMAND}
+  -C Debug
+  -R GoogleTestXML
+  --no-label-summary
+  )
+
+  run_cmake_command(GoogleTestXML-special-result
+  ${CMAKE_CTEST_COMMAND}
+  -C Debug
+  -R GoogleTestXMLSpecial
+  --no-label-summary
+  )
+endfunction()
+
+function(run_GoogleTest_discovery_timeout DISCOVERY_MODE)
+  # Use a single build tree for a few tests without cleaning.
+  set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/GoogleTest-discovery-timeout)
+  set(RunCMake_TEST_NO_CLEAN 1)
+  if(NOT RunCMake_GENERATOR_IS_MULTI_CONFIG)
+    set(RunCMake_TEST_OPTIONS -DCMAKE_BUILD_TYPE=Debug)
+  endif()
+  file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}")
+  file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}")
+
+  run_cmake_with_options(GoogleTestDiscoveryTimeout -DDISCOVERY_MODE=${DISCOVERY_MODE})
+
+  set(RunCMake_TEST_OUTPUT_MERGE 1)
+  run_cmake_command(GoogleTest-discovery-${DISCOVERY_MODE}-timeout-build
+    ${CMAKE_COMMAND}
+    --build .
+    --config Debug
+    --target discovery_timeout_test
+  )
+  set(RunCMake_TEST_OUTPUT_MERGE 0)
+
+  run_cmake_command(GoogleTest-discovery-${DISCOVERY_MODE}-timeout-test
+    ${CMAKE_CTEST_COMMAND}
+    -C Debug
+    -R discovery_timeout_test
+    --no-label-sumary
+  )
+endfunction()
+
+function(run_GoogleTest_discovery_multi_config)
+  # Use a single build tree for a few tests without cleaning.
+  set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/GoogleTest-discovery-multi-config)
+  set(RunCMake_TEST_NO_CLEAN 1)
+  file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}")
+  file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}")
+
+  run_cmake(GoogleTestDiscoveryMultiConfig)
+
+  run_cmake_command(GoogleTest-build-release
+    ${CMAKE_COMMAND}
+    --build .
+    --config Release
+    --target configuration_gtest
+  )
+  run_cmake_command(GoogleTest-build-debug
+    ${CMAKE_COMMAND}
+    --build .
+    --config Debug
+    --target configuration_gtest
+  )
+  run_cmake_command(GoogleTest-configuration-release
+    ${CMAKE_CTEST_COMMAND}
+    -C Release
+    -L CONFIG
+    -N
+  )
+  run_cmake_command(GoogleTest-configuration-debug
+    ${CMAKE_CTEST_COMMAND}
+    -C Debug
+    -L CONFIG
+    -N
+  )
+
+endfunction()
+
+foreach(DISCOVERY_MODE POST_BUILD PRE_TEST)
+  message("Testing ${DISCOVERY_MODE} discovery mode via CMAKE_GTEST_DISCOVER_TESTS_DISCOVERY_MODE global override...")
+  run_GoogleTest(${DISCOVERY_MODE})
+  run_GoogleTestXML(${DISCOVERY_MODE})
+  message("Testing ${DISCOVERY_MODE} discovery mode via DISCOVERY_MODE option...")
+  run_GoogleTest_discovery_timeout(${DISCOVERY_MODE})
+endforeach()
+
+if(RunCMake_GENERATOR_IS_MULTI_CONFIG)
+  message("Testing PRE_TEST discovery multi configuration...")
+  run_GoogleTest_discovery_multi_config()
+endif()
diff --git a/Tests/RunCMake/GoogleTest/configuration_gtest.cpp b/Tests/RunCMake/GoogleTest/configuration_gtest.cpp
new file mode 100644
index 0000000..3cbb134
--- /dev/null
+++ b/Tests/RunCMake/GoogleTest/configuration_gtest.cpp
@@ -0,0 +1,23 @@
+#include <iostream>
+#include <string>
+
+int main(int argc, char** argv)
+{
+  // Note: GoogleTest.cmake doesn't actually depend on Google Test as such;
+  // it only requires that we produces output in the expected format when
+  // invoked with --gtest_list_tests. Thus, we fake that here. This allows us
+  // to test the module without actually needing Google Test.
+  if (argc > 1 && std::string(argv[1]) == "--gtest_list_tests") {
+    std::cout << "configuration." << std::endl;
+#ifdef DEBUG
+    std::cout << "  DISABLED_case_release" << std::endl;
+    std::cout << "  case_debug" << std::endl;
+#else
+    std::cout << "  case_release" << std::endl;
+    std::cout << "  DISABLED_case_debug" << std::endl;
+#endif
+    return 0;
+  }
+
+  return 1;
+}
diff --git a/Tests/RunCMake/GoogleTest/fake_gtest.cpp b/Tests/RunCMake/GoogleTest/fake_gtest.cpp
index f1bd7ef..a8127bf 100644
--- a/Tests/RunCMake/GoogleTest/fake_gtest.cpp
+++ b/Tests/RunCMake/GoogleTest/fake_gtest.cpp
@@ -21,6 +21,10 @@
     std::cout << "value/test." << std::endl;
     std::cout << "  case/0  # GetParam() = 1" << std::endl;
     std::cout << "  case/1  # GetParam() = \"foo\"" << std::endl;
+    std::cout << "param/special." << std::endl;
+    std::cout << "  case/0  # GetParam() = \"semicolon;\"" << std::endl;
+    std::cout << "  case/1  # GetParam() = \"backslash\\\"" << std::endl;
+    std::cout << "  case/2  # GetParam() = \"${var}\"" << std::endl;
     return 0;
   }
 
diff --git a/Tests/RunCMake/GoogleTest/skip_test.cpp b/Tests/RunCMake/GoogleTest/skip_test.cpp
new file mode 100644
index 0000000..2bc9fe1
--- /dev/null
+++ b/Tests/RunCMake/GoogleTest/skip_test.cpp
@@ -0,0 +1,18 @@
+#include <iostream>
+#include <string>
+
+int main(int argc, char** argv)
+{
+  // Note: GoogleTest.cmake doesn't actually depend on Google Test as such;
+  // it only requires that we produces output in the expected format when
+  // invoked with --gtest_list_tests. Thus, we fake that here. This allows us
+  // to test the module without actually needing Google Test.
+  if (argc > 1 && std::string(argv[1]) == "--gtest_list_tests") {
+    std::cout << "skip_test." << std::endl;
+    std::cout << "  test1" << std::endl;
+    return 0;
+  }
+
+  std::cout << "[  SKIPPED ] skip_test.test1" << std::endl;
+  return 0;
+}
diff --git a/Tests/RunCMake/GoogleTest/timeout_test.cpp b/Tests/RunCMake/GoogleTest/timeout_test.cpp
index b8ad055..5506269 100644
--- a/Tests/RunCMake/GoogleTest/timeout_test.cpp
+++ b/Tests/RunCMake/GoogleTest/timeout_test.cpp
@@ -4,9 +4,10 @@
 #  include <unistd.h>
 #endif
 
-#include <iostream>
 #include <string>
 
+#include <stdio.h>
+
 void sleepFor(unsigned seconds)
 {
 #if defined(_WIN32)
@@ -23,8 +24,8 @@
   // invoked with --gtest_list_tests. Thus, we fake that here. This allows us
   // to test the module without actually needing Google Test.
   if (argc > 1 && std::string(argv[1]) == "--gtest_list_tests") {
-    std::cout << "timeout." << std::endl;
-    std::cout << "  case" << std::endl;
+    printf("timeout.\n  case\n");
+    fflush(stdout);
 #ifdef discoverySleepSec
     sleepFor(discoverySleepSec);
 #endif
diff --git a/Tests/RunCMake/GoogleTest/xml_output.cpp b/Tests/RunCMake/GoogleTest/xml_output.cpp
new file mode 100644
index 0000000..82f0d02
--- /dev/null
+++ b/Tests/RunCMake/GoogleTest/xml_output.cpp
@@ -0,0 +1,37 @@
+#include <fstream>
+#include <iostream>
+#include <string>
+
+int main(int argc, char** argv)
+{
+  // Note: GoogleTestXML.cmake doesn't actually depend on Google Test as such;
+  // it only mimicks the output file creation using the path passed to this
+  // test without any content
+  for (int i = 0; i < argc; i++) {
+    std::string param(argv[i]);
+    if (param.find("--gtest_list_tests") != std::string::npos) {
+      // This actually defines the name of the file passed in the 2nd run
+      std::cout << "GoogleTestXML." << std::endl;
+      std::cout << "  Foo" << std::endl;
+      // When changing these names, make sure to adapt the folder creation
+      // in GoogleTestXML.cmake
+      std::cout << "GoogleTestXMLSpecial/cases." << std::endl;
+      std::cout << "  case/0  # GetParam() = 42" << std::endl;
+      std::cout << "  case/1  # GetParam() = \"string\"" << std::endl;
+      std::cout << "  case/2  # GetParam() = \"path/like\"" << std::endl;
+    } else if (param.find("--gtest_output=xml:") != std::string::npos) {
+      std::string::size_type split = param.find(":");
+      std::string filepath = param.substr(split + 1);
+      // The full file path is passed
+      std::ofstream ostrm(filepath.c_str(), std::ios::binary);
+      if (!ostrm) {
+        std::cerr << "Failed to create file: " << filepath.c_str()
+                  << std::endl;
+        return 1;
+      }
+      ostrm << "--gtest_output=xml: mockup file\n";
+    }
+  }
+
+  return 0;
+}
diff --git a/Tests/RunCMake/Graphviz/GraphvizTestProject.cmake b/Tests/RunCMake/Graphviz/GraphvizTestProject.cmake
index 772f312..4ce6b5c 100644
--- a/Tests/RunCMake/Graphviz/GraphvizTestProject.cmake
+++ b/Tests/RunCMake/Graphviz/GraphvizTestProject.cmake
@@ -9,6 +9,7 @@
 #   - All library depend on a common INTERFACE library holding compiler flags
 #   - We have a custom target to generate a man page
 #   - Someone has added an UNKNOWN, IMPORTED crypto mining library!
+#   - We have a circular dependency between two libraries
 
 add_subdirectory(test_project/third_party_project)
 
@@ -23,6 +24,13 @@
 
 target_link_libraries(CoreLibrary PRIVATE SeriousLoggingLibrary)
 
+add_library(SystemLibrary STATIC test_project/system_library.c)
+
+# Create a circular dependency.
+# See https://gitlab.kitware.com/cmake/cmake/issues/20720
+target_link_libraries(CoreLibrary PRIVATE SystemLibrary)
+target_link_libraries(SystemLibrary PRIVATE CoreLibrary)
+
 add_library(GraphicLibraryObjects OBJECT test_project/graphic_library.c)
 
 add_library(GraphicLibrary SHARED)
@@ -32,7 +40,7 @@
 
 # Test target labels with quotes in them; they should be escaped in the dot
 # file.
-# See https://gitlab.kitware.com/cmake/cmake/issues/19746
+# See https://gitlab.kitware.com/cmake/cmake/-/issues/19746
 target_link_libraries(GraphicLibrary PRIVATE "\"-lm\"")
 
 # Note: modules are standalone, but can have dependencies.
diff --git a/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_custom_targets.dot b/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_custom_targets.dot
index 8b0365a..31d88df 100644
--- a/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_custom_targets.dot
+++ b/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_custom_targets.dot
@@ -28,25 +28,28 @@
     "node2" -> "node0"  // CoreLibrary -> CompilerFlags
     "node3" [ label = "GoofyLoggingLibrary\n(SeriousLoggingLibrary)\n(TheBestLoggingLibrary)", shape = pentagon ];
     "node2" -> "node3" [ style = dotted ] // CoreLibrary -> GoofyLoggingLibrary
+    "node4" [ label = "SystemLibrary", shape = octagon ];
+    "node4" -> "node2" [ style = dotted ] // SystemLibrary -> CoreLibrary
+    "node2" -> "node4" [ style = dotted ] // CoreLibrary -> SystemLibrary
     "node1" -> "node2" [ style = dotted ] // ConsoleApplication -> CoreLibrary
-    "node4" [ label = "CryptoCurrencyMiningLibrary", shape = septagon ];
-    "node1" -> "node4" [ style = dotted ] // ConsoleApplication -> CryptoCurrencyMiningLibrary
-    "node5" [ label = "GenerateManPage", shape = box ];
-    "node1" -> "node5"  // ConsoleApplication -> GenerateManPage
-    "node6" [ label = "GraphicApplication", shape = egg ];
-    "node6" -> "node2" [ style = dotted ] // GraphicApplication -> CoreLibrary
-    "node7" [ label = "GraphicLibrary", shape = doubleoctagon ];
-    "node8" [ label = "\"-lm\"", shape = septagon ];
-    "node7" -> "node8" [ style = dotted ] // GraphicLibrary -> "-lm"
-    "node7" -> "node0"  // GraphicLibrary -> CompilerFlags
-    "node7" -> "node2" [ style = dotted ] // GraphicLibrary -> CoreLibrary
-    "node9" [ label = "GraphicLibraryObjects", shape = hexagon ];
-    "node7" -> "node9" [ style = dotted ] // GraphicLibrary -> GraphicLibraryObjects
-    "node6" -> "node7" [ style = dotted ] // GraphicApplication -> GraphicLibrary
-    "node10" [ label = "GraphicDriverOpenGL", shape = tripleoctagon ];
-    "node10" -> "node0" [ style = dotted ] // GraphicDriverOpenGL -> CompilerFlags
-    "node10" -> "node2" [ style = dotted ] // GraphicDriverOpenGL -> CoreLibrary
-    "node11" [ label = "GraphicDriverVulkan", shape = tripleoctagon ];
-    "node11" -> "node0" [ style = dotted ] // GraphicDriverVulkan -> CompilerFlags
-    "node11" -> "node2" [ style = dotted ] // GraphicDriverVulkan -> CoreLibrary
+    "node5" [ label = "CryptoCurrencyMiningLibrary", shape = septagon ];
+    "node1" -> "node5" [ style = dotted ] // ConsoleApplication -> CryptoCurrencyMiningLibrary
+    "node6" [ label = "GenerateManPage", shape = box ];
+    "node1" -> "node6"  // ConsoleApplication -> GenerateManPage
+    "node7" [ label = "GraphicApplication", shape = egg ];
+    "node7" -> "node2" [ style = dotted ] // GraphicApplication -> CoreLibrary
+    "node8" [ label = "GraphicLibrary", shape = doubleoctagon ];
+    "node9" [ label = "\"-lm\"", shape = septagon ];
+    "node8" -> "node9" [ style = dotted ] // GraphicLibrary -> "-lm"
+    "node8" -> "node0"  // GraphicLibrary -> CompilerFlags
+    "node8" -> "node2" [ style = dotted ] // GraphicLibrary -> CoreLibrary
+    "node10" [ label = "GraphicLibraryObjects", shape = hexagon ];
+    "node8" -> "node10" [ style = dotted ] // GraphicLibrary -> GraphicLibraryObjects
+    "node7" -> "node8" [ style = dotted ] // GraphicApplication -> GraphicLibrary
+    "node11" [ label = "GraphicDriverOpenGL", shape = tripleoctagon ];
+    "node11" -> "node0" [ style = dotted ] // GraphicDriverOpenGL -> CompilerFlags
+    "node11" -> "node2" [ style = dotted ] // GraphicDriverOpenGL -> CoreLibrary
+    "node12" [ label = "GraphicDriverVulkan", shape = tripleoctagon ];
+    "node12" -> "node0" [ style = dotted ] // GraphicDriverVulkan -> CompilerFlags
+    "node12" -> "node2" [ style = dotted ] // GraphicDriverVulkan -> CoreLibrary
 }
diff --git a/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_default_options.dot b/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_default_options.dot
index 1bbf25a..26f2f64 100644
--- a/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_default_options.dot
+++ b/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_default_options.dot
@@ -28,23 +28,26 @@
     "node2" -> "node0"  // CoreLibrary -> CompilerFlags
     "node3" [ label = "GoofyLoggingLibrary\n(SeriousLoggingLibrary)\n(TheBestLoggingLibrary)", shape = pentagon ];
     "node2" -> "node3" [ style = dotted ] // CoreLibrary -> GoofyLoggingLibrary
+    "node4" [ label = "SystemLibrary", shape = octagon ];
+    "node4" -> "node2" [ style = dotted ] // SystemLibrary -> CoreLibrary
+    "node2" -> "node4" [ style = dotted ] // CoreLibrary -> SystemLibrary
     "node1" -> "node2" [ style = dotted ] // ConsoleApplication -> CoreLibrary
-    "node4" [ label = "CryptoCurrencyMiningLibrary", shape = septagon ];
-    "node1" -> "node4" [ style = dotted ] // ConsoleApplication -> CryptoCurrencyMiningLibrary
-    "node5" [ label = "GraphicApplication", shape = egg ];
-    "node5" -> "node2" [ style = dotted ] // GraphicApplication -> CoreLibrary
-    "node6" [ label = "GraphicLibrary", shape = doubleoctagon ];
-    "node7" [ label = "\"-lm\"", shape = septagon ];
-    "node6" -> "node7" [ style = dotted ] // GraphicLibrary -> "-lm"
-    "node6" -> "node0"  // GraphicLibrary -> CompilerFlags
-    "node6" -> "node2" [ style = dotted ] // GraphicLibrary -> CoreLibrary
-    "node8" [ label = "GraphicLibraryObjects", shape = hexagon ];
-    "node6" -> "node8" [ style = dotted ] // GraphicLibrary -> GraphicLibraryObjects
-    "node5" -> "node6" [ style = dotted ] // GraphicApplication -> GraphicLibrary
-    "node9" [ label = "GraphicDriverOpenGL", shape = tripleoctagon ];
-    "node9" -> "node0" [ style = dotted ] // GraphicDriverOpenGL -> CompilerFlags
-    "node9" -> "node2" [ style = dotted ] // GraphicDriverOpenGL -> CoreLibrary
-    "node10" [ label = "GraphicDriverVulkan", shape = tripleoctagon ];
-    "node10" -> "node0" [ style = dotted ] // GraphicDriverVulkan -> CompilerFlags
-    "node10" -> "node2" [ style = dotted ] // GraphicDriverVulkan -> CoreLibrary
+    "node5" [ label = "CryptoCurrencyMiningLibrary", shape = septagon ];
+    "node1" -> "node5" [ style = dotted ] // ConsoleApplication -> CryptoCurrencyMiningLibrary
+    "node6" [ label = "GraphicApplication", shape = egg ];
+    "node6" -> "node2" [ style = dotted ] // GraphicApplication -> CoreLibrary
+    "node7" [ label = "GraphicLibrary", shape = doubleoctagon ];
+    "node8" [ label = "\"-lm\"", shape = septagon ];
+    "node7" -> "node8" [ style = dotted ] // GraphicLibrary -> "-lm"
+    "node7" -> "node0"  // GraphicLibrary -> CompilerFlags
+    "node7" -> "node2" [ style = dotted ] // GraphicLibrary -> CoreLibrary
+    "node9" [ label = "GraphicLibraryObjects", shape = hexagon ];
+    "node7" -> "node9" [ style = dotted ] // GraphicLibrary -> GraphicLibraryObjects
+    "node6" -> "node7" [ style = dotted ] // GraphicApplication -> GraphicLibrary
+    "node10" [ label = "GraphicDriverOpenGL", shape = tripleoctagon ];
+    "node10" -> "node0" [ style = dotted ] // GraphicDriverOpenGL -> CompilerFlags
+    "node10" -> "node2" [ style = dotted ] // GraphicDriverOpenGL -> CoreLibrary
+    "node11" [ label = "GraphicDriverVulkan", shape = tripleoctagon ];
+    "node11" -> "node0" [ style = dotted ] // GraphicDriverVulkan -> CompilerFlags
+    "node11" -> "node2" [ style = dotted ] // GraphicDriverVulkan -> CoreLibrary
 }
diff --git a/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_dependers_files.dot b/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_dependers_files.dot
index 1bbf25a..26f2f64 100644
--- a/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_dependers_files.dot
+++ b/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_dependers_files.dot
@@ -28,23 +28,26 @@
     "node2" -> "node0"  // CoreLibrary -> CompilerFlags
     "node3" [ label = "GoofyLoggingLibrary\n(SeriousLoggingLibrary)\n(TheBestLoggingLibrary)", shape = pentagon ];
     "node2" -> "node3" [ style = dotted ] // CoreLibrary -> GoofyLoggingLibrary
+    "node4" [ label = "SystemLibrary", shape = octagon ];
+    "node4" -> "node2" [ style = dotted ] // SystemLibrary -> CoreLibrary
+    "node2" -> "node4" [ style = dotted ] // CoreLibrary -> SystemLibrary
     "node1" -> "node2" [ style = dotted ] // ConsoleApplication -> CoreLibrary
-    "node4" [ label = "CryptoCurrencyMiningLibrary", shape = septagon ];
-    "node1" -> "node4" [ style = dotted ] // ConsoleApplication -> CryptoCurrencyMiningLibrary
-    "node5" [ label = "GraphicApplication", shape = egg ];
-    "node5" -> "node2" [ style = dotted ] // GraphicApplication -> CoreLibrary
-    "node6" [ label = "GraphicLibrary", shape = doubleoctagon ];
-    "node7" [ label = "\"-lm\"", shape = septagon ];
-    "node6" -> "node7" [ style = dotted ] // GraphicLibrary -> "-lm"
-    "node6" -> "node0"  // GraphicLibrary -> CompilerFlags
-    "node6" -> "node2" [ style = dotted ] // GraphicLibrary -> CoreLibrary
-    "node8" [ label = "GraphicLibraryObjects", shape = hexagon ];
-    "node6" -> "node8" [ style = dotted ] // GraphicLibrary -> GraphicLibraryObjects
-    "node5" -> "node6" [ style = dotted ] // GraphicApplication -> GraphicLibrary
-    "node9" [ label = "GraphicDriverOpenGL", shape = tripleoctagon ];
-    "node9" -> "node0" [ style = dotted ] // GraphicDriverOpenGL -> CompilerFlags
-    "node9" -> "node2" [ style = dotted ] // GraphicDriverOpenGL -> CoreLibrary
-    "node10" [ label = "GraphicDriverVulkan", shape = tripleoctagon ];
-    "node10" -> "node0" [ style = dotted ] // GraphicDriverVulkan -> CompilerFlags
-    "node10" -> "node2" [ style = dotted ] // GraphicDriverVulkan -> CoreLibrary
+    "node5" [ label = "CryptoCurrencyMiningLibrary", shape = septagon ];
+    "node1" -> "node5" [ style = dotted ] // ConsoleApplication -> CryptoCurrencyMiningLibrary
+    "node6" [ label = "GraphicApplication", shape = egg ];
+    "node6" -> "node2" [ style = dotted ] // GraphicApplication -> CoreLibrary
+    "node7" [ label = "GraphicLibrary", shape = doubleoctagon ];
+    "node8" [ label = "\"-lm\"", shape = septagon ];
+    "node7" -> "node8" [ style = dotted ] // GraphicLibrary -> "-lm"
+    "node7" -> "node0"  // GraphicLibrary -> CompilerFlags
+    "node7" -> "node2" [ style = dotted ] // GraphicLibrary -> CoreLibrary
+    "node9" [ label = "GraphicLibraryObjects", shape = hexagon ];
+    "node7" -> "node9" [ style = dotted ] // GraphicLibrary -> GraphicLibraryObjects
+    "node6" -> "node7" [ style = dotted ] // GraphicApplication -> GraphicLibrary
+    "node10" [ label = "GraphicDriverOpenGL", shape = tripleoctagon ];
+    "node10" -> "node0" [ style = dotted ] // GraphicDriverOpenGL -> CompilerFlags
+    "node10" -> "node2" [ style = dotted ] // GraphicDriverOpenGL -> CoreLibrary
+    "node11" [ label = "GraphicDriverVulkan", shape = tripleoctagon ];
+    "node11" -> "node0" [ style = dotted ] // GraphicDriverVulkan -> CompilerFlags
+    "node11" -> "node2" [ style = dotted ] // GraphicDriverVulkan -> CoreLibrary
 }
diff --git a/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_executables.dot b/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_executables.dot
index 558a470..7f2e01c 100644
--- a/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_executables.dot
+++ b/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_executables.dot
@@ -27,18 +27,21 @@
     "node1" -> "node0"  // CoreLibrary -> CompilerFlags
     "node2" [ label = "GoofyLoggingLibrary\n(SeriousLoggingLibrary)\n(TheBestLoggingLibrary)", shape = pentagon ];
     "node1" -> "node2" [ style = dotted ] // CoreLibrary -> GoofyLoggingLibrary
-    "node3" [ label = "CryptoCurrencyMiningLibrary", shape = septagon ];
-    "node4" [ label = "GraphicLibrary", shape = doubleoctagon ];
-    "node5" [ label = "\"-lm\"", shape = septagon ];
-    "node4" -> "node5" [ style = dotted ] // GraphicLibrary -> "-lm"
-    "node4" -> "node0"  // GraphicLibrary -> CompilerFlags
-    "node4" -> "node1" [ style = dotted ] // GraphicLibrary -> CoreLibrary
-    "node6" [ label = "GraphicLibraryObjects", shape = hexagon ];
-    "node4" -> "node6" [ style = dotted ] // GraphicLibrary -> GraphicLibraryObjects
-    "node7" [ label = "GraphicDriverOpenGL", shape = tripleoctagon ];
-    "node7" -> "node0" [ style = dotted ] // GraphicDriverOpenGL -> CompilerFlags
-    "node7" -> "node1" [ style = dotted ] // GraphicDriverOpenGL -> CoreLibrary
-    "node8" [ label = "GraphicDriverVulkan", shape = tripleoctagon ];
-    "node8" -> "node0" [ style = dotted ] // GraphicDriverVulkan -> CompilerFlags
-    "node8" -> "node1" [ style = dotted ] // GraphicDriverVulkan -> CoreLibrary
+    "node3" [ label = "SystemLibrary", shape = octagon ];
+    "node3" -> "node1" [ style = dotted ] // SystemLibrary -> CoreLibrary
+    "node1" -> "node3" [ style = dotted ] // CoreLibrary -> SystemLibrary
+    "node4" [ label = "CryptoCurrencyMiningLibrary", shape = septagon ];
+    "node5" [ label = "GraphicLibrary", shape = doubleoctagon ];
+    "node6" [ label = "\"-lm\"", shape = septagon ];
+    "node5" -> "node6" [ style = dotted ] // GraphicLibrary -> "-lm"
+    "node5" -> "node0"  // GraphicLibrary -> CompilerFlags
+    "node5" -> "node1" [ style = dotted ] // GraphicLibrary -> CoreLibrary
+    "node7" [ label = "GraphicLibraryObjects", shape = hexagon ];
+    "node5" -> "node7" [ style = dotted ] // GraphicLibrary -> GraphicLibraryObjects
+    "node8" [ label = "GraphicDriverOpenGL", shape = tripleoctagon ];
+    "node8" -> "node0" [ style = dotted ] // GraphicDriverOpenGL -> CompilerFlags
+    "node8" -> "node1" [ style = dotted ] // GraphicDriverOpenGL -> CoreLibrary
+    "node9" [ label = "GraphicDriverVulkan", shape = tripleoctagon ];
+    "node9" -> "node0" [ style = dotted ] // GraphicDriverVulkan -> CompilerFlags
+    "node9" -> "node1" [ style = dotted ] // GraphicDriverVulkan -> CoreLibrary
 }
diff --git a/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_external_libs.dot b/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_external_libs.dot
index 660af37..db675a8 100644
--- a/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_external_libs.dot
+++ b/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_external_libs.dot
@@ -28,19 +28,22 @@
     "node2" -> "node0"  // CoreLibrary -> CompilerFlags
     "node3" [ label = "GoofyLoggingLibrary\n(SeriousLoggingLibrary)\n(TheBestLoggingLibrary)", shape = pentagon ];
     "node2" -> "node3" [ style = dotted ] // CoreLibrary -> GoofyLoggingLibrary
+    "node4" [ label = "SystemLibrary", shape = octagon ];
+    "node4" -> "node2" [ style = dotted ] // SystemLibrary -> CoreLibrary
+    "node2" -> "node4" [ style = dotted ] // CoreLibrary -> SystemLibrary
     "node1" -> "node2" [ style = dotted ] // ConsoleApplication -> CoreLibrary
-    "node4" [ label = "GraphicApplication", shape = egg ];
-    "node4" -> "node2" [ style = dotted ] // GraphicApplication -> CoreLibrary
-    "node5" [ label = "GraphicLibrary", shape = doubleoctagon ];
-    "node5" -> "node0"  // GraphicLibrary -> CompilerFlags
-    "node5" -> "node2" [ style = dotted ] // GraphicLibrary -> CoreLibrary
-    "node6" [ label = "GraphicLibraryObjects", shape = hexagon ];
-    "node5" -> "node6" [ style = dotted ] // GraphicLibrary -> GraphicLibraryObjects
-    "node4" -> "node5" [ style = dotted ] // GraphicApplication -> GraphicLibrary
-    "node7" [ label = "GraphicDriverOpenGL", shape = tripleoctagon ];
-    "node7" -> "node0" [ style = dotted ] // GraphicDriverOpenGL -> CompilerFlags
-    "node7" -> "node2" [ style = dotted ] // GraphicDriverOpenGL -> CoreLibrary
-    "node8" [ label = "GraphicDriverVulkan", shape = tripleoctagon ];
-    "node8" -> "node0" [ style = dotted ] // GraphicDriverVulkan -> CompilerFlags
-    "node8" -> "node2" [ style = dotted ] // GraphicDriverVulkan -> CoreLibrary
+    "node5" [ label = "GraphicApplication", shape = egg ];
+    "node5" -> "node2" [ style = dotted ] // GraphicApplication -> CoreLibrary
+    "node6" [ label = "GraphicLibrary", shape = doubleoctagon ];
+    "node6" -> "node0"  // GraphicLibrary -> CompilerFlags
+    "node6" -> "node2" [ style = dotted ] // GraphicLibrary -> CoreLibrary
+    "node7" [ label = "GraphicLibraryObjects", shape = hexagon ];
+    "node6" -> "node7" [ style = dotted ] // GraphicLibrary -> GraphicLibraryObjects
+    "node5" -> "node6" [ style = dotted ] // GraphicApplication -> GraphicLibrary
+    "node8" [ label = "GraphicDriverOpenGL", shape = tripleoctagon ];
+    "node8" -> "node0" [ style = dotted ] // GraphicDriverOpenGL -> CompilerFlags
+    "node8" -> "node2" [ style = dotted ] // GraphicDriverOpenGL -> CoreLibrary
+    "node9" [ label = "GraphicDriverVulkan", shape = tripleoctagon ];
+    "node9" -> "node0" [ style = dotted ] // GraphicDriverVulkan -> CompilerFlags
+    "node9" -> "node2" [ style = dotted ] // GraphicDriverVulkan -> CoreLibrary
 }
diff --git a/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_graphic_libs.dot b/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_graphic_libs.dot
index 5af7fec..234ee39 100644
--- a/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_graphic_libs.dot
+++ b/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_graphic_libs.dot
@@ -28,8 +28,11 @@
     "node2" -> "node0"  // CoreLibrary -> CompilerFlags
     "node3" [ label = "GoofyLoggingLibrary\n(SeriousLoggingLibrary)\n(TheBestLoggingLibrary)", shape = pentagon ];
     "node2" -> "node3" [ style = dotted ] // CoreLibrary -> GoofyLoggingLibrary
+    "node4" [ label = "SystemLibrary", shape = octagon ];
+    "node4" -> "node2" [ style = dotted ] // SystemLibrary -> CoreLibrary
+    "node2" -> "node4" [ style = dotted ] // CoreLibrary -> SystemLibrary
     "node1" -> "node2" [ style = dotted ] // ConsoleApplication -> CoreLibrary
-    "node4" [ label = "CryptoCurrencyMiningLibrary", shape = septagon ];
-    "node1" -> "node4" [ style = dotted ] // ConsoleApplication -> CryptoCurrencyMiningLibrary
-    "node5" [ label = "\"-lm\"", shape = septagon ];
+    "node5" [ label = "CryptoCurrencyMiningLibrary", shape = septagon ];
+    "node1" -> "node5" [ style = dotted ] // ConsoleApplication -> CryptoCurrencyMiningLibrary
+    "node6" [ label = "\"-lm\"", shape = septagon ];
 }
diff --git a/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_interface_libs.dot b/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_interface_libs.dot
index 94ec41c..6dea88c 100644
--- a/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_interface_libs.dot
+++ b/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_interface_libs.dot
@@ -24,20 +24,23 @@
 }
     "node0" [ label = "ConsoleApplication", shape = egg ];
     "node1" [ label = "CoreLibrary", shape = octagon ];
+    "node2" [ label = "SystemLibrary", shape = octagon ];
+    "node2" -> "node1" [ style = dotted ] // SystemLibrary -> CoreLibrary
+    "node1" -> "node2" [ style = dotted ] // CoreLibrary -> SystemLibrary
     "node0" -> "node1" [ style = dotted ] // ConsoleApplication -> CoreLibrary
-    "node2" [ label = "CryptoCurrencyMiningLibrary", shape = septagon ];
-    "node0" -> "node2" [ style = dotted ] // ConsoleApplication -> CryptoCurrencyMiningLibrary
-    "node3" [ label = "GraphicApplication", shape = egg ];
-    "node3" -> "node1" [ style = dotted ] // GraphicApplication -> CoreLibrary
-    "node4" [ label = "GraphicLibrary", shape = doubleoctagon ];
-    "node5" [ label = "\"-lm\"", shape = septagon ];
-    "node4" -> "node5" [ style = dotted ] // GraphicLibrary -> "-lm"
-    "node4" -> "node1" [ style = dotted ] // GraphicLibrary -> CoreLibrary
-    "node6" [ label = "GraphicLibraryObjects", shape = hexagon ];
-    "node4" -> "node6" [ style = dotted ] // GraphicLibrary -> GraphicLibraryObjects
-    "node3" -> "node4" [ style = dotted ] // GraphicApplication -> GraphicLibrary
-    "node7" [ label = "GraphicDriverOpenGL", shape = tripleoctagon ];
-    "node7" -> "node1" [ style = dotted ] // GraphicDriverOpenGL -> CoreLibrary
-    "node8" [ label = "GraphicDriverVulkan", shape = tripleoctagon ];
-    "node8" -> "node1" [ style = dotted ] // GraphicDriverVulkan -> CoreLibrary
+    "node3" [ label = "CryptoCurrencyMiningLibrary", shape = septagon ];
+    "node0" -> "node3" [ style = dotted ] // ConsoleApplication -> CryptoCurrencyMiningLibrary
+    "node4" [ label = "GraphicApplication", shape = egg ];
+    "node4" -> "node1" [ style = dotted ] // GraphicApplication -> CoreLibrary
+    "node5" [ label = "GraphicLibrary", shape = doubleoctagon ];
+    "node6" [ label = "\"-lm\"", shape = septagon ];
+    "node5" -> "node6" [ style = dotted ] // GraphicLibrary -> "-lm"
+    "node5" -> "node1" [ style = dotted ] // GraphicLibrary -> CoreLibrary
+    "node7" [ label = "GraphicLibraryObjects", shape = hexagon ];
+    "node5" -> "node7" [ style = dotted ] // GraphicLibrary -> GraphicLibraryObjects
+    "node4" -> "node5" [ style = dotted ] // GraphicApplication -> GraphicLibrary
+    "node8" [ label = "GraphicDriverOpenGL", shape = tripleoctagon ];
+    "node8" -> "node1" [ style = dotted ] // GraphicDriverOpenGL -> CoreLibrary
+    "node9" [ label = "GraphicDriverVulkan", shape = tripleoctagon ];
+    "node9" -> "node1" [ style = dotted ] // GraphicDriverVulkan -> CoreLibrary
 }
diff --git a/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_module_libs.dot b/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_module_libs.dot
index 65b7a71..df3d10a 100644
--- a/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_module_libs.dot
+++ b/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_module_libs.dot
@@ -28,17 +28,20 @@
     "node2" -> "node0"  // CoreLibrary -> CompilerFlags
     "node3" [ label = "GoofyLoggingLibrary\n(SeriousLoggingLibrary)\n(TheBestLoggingLibrary)", shape = pentagon ];
     "node2" -> "node3" [ style = dotted ] // CoreLibrary -> GoofyLoggingLibrary
+    "node4" [ label = "SystemLibrary", shape = octagon ];
+    "node4" -> "node2" [ style = dotted ] // SystemLibrary -> CoreLibrary
+    "node2" -> "node4" [ style = dotted ] // CoreLibrary -> SystemLibrary
     "node1" -> "node2" [ style = dotted ] // ConsoleApplication -> CoreLibrary
-    "node4" [ label = "CryptoCurrencyMiningLibrary", shape = septagon ];
-    "node1" -> "node4" [ style = dotted ] // ConsoleApplication -> CryptoCurrencyMiningLibrary
-    "node5" [ label = "GraphicApplication", shape = egg ];
-    "node5" -> "node2" [ style = dotted ] // GraphicApplication -> CoreLibrary
-    "node6" [ label = "GraphicLibrary", shape = doubleoctagon ];
-    "node7" [ label = "\"-lm\"", shape = septagon ];
-    "node6" -> "node7" [ style = dotted ] // GraphicLibrary -> "-lm"
-    "node6" -> "node0"  // GraphicLibrary -> CompilerFlags
-    "node6" -> "node2" [ style = dotted ] // GraphicLibrary -> CoreLibrary
-    "node8" [ label = "GraphicLibraryObjects", shape = hexagon ];
-    "node6" -> "node8" [ style = dotted ] // GraphicLibrary -> GraphicLibraryObjects
-    "node5" -> "node6" [ style = dotted ] // GraphicApplication -> GraphicLibrary
+    "node5" [ label = "CryptoCurrencyMiningLibrary", shape = septagon ];
+    "node1" -> "node5" [ style = dotted ] // ConsoleApplication -> CryptoCurrencyMiningLibrary
+    "node6" [ label = "GraphicApplication", shape = egg ];
+    "node6" -> "node2" [ style = dotted ] // GraphicApplication -> CoreLibrary
+    "node7" [ label = "GraphicLibrary", shape = doubleoctagon ];
+    "node8" [ label = "\"-lm\"", shape = septagon ];
+    "node7" -> "node8" [ style = dotted ] // GraphicLibrary -> "-lm"
+    "node7" -> "node0"  // GraphicLibrary -> CompilerFlags
+    "node7" -> "node2" [ style = dotted ] // GraphicLibrary -> CoreLibrary
+    "node9" [ label = "GraphicLibraryObjects", shape = hexagon ];
+    "node7" -> "node9" [ style = dotted ] // GraphicLibrary -> GraphicLibraryObjects
+    "node6" -> "node7" [ style = dotted ] // GraphicApplication -> GraphicLibrary
 }
diff --git a/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_object_libs.dot b/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_object_libs.dot
index 8116bc9..8f832a8 100644
--- a/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_object_libs.dot
+++ b/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_object_libs.dot
@@ -28,21 +28,24 @@
     "node2" -> "node0"  // CoreLibrary -> CompilerFlags
     "node3" [ label = "GoofyLoggingLibrary\n(SeriousLoggingLibrary)\n(TheBestLoggingLibrary)", shape = pentagon ];
     "node2" -> "node3" [ style = dotted ] // CoreLibrary -> GoofyLoggingLibrary
+    "node4" [ label = "SystemLibrary", shape = octagon ];
+    "node4" -> "node2" [ style = dotted ] // SystemLibrary -> CoreLibrary
+    "node2" -> "node4" [ style = dotted ] // CoreLibrary -> SystemLibrary
     "node1" -> "node2" [ style = dotted ] // ConsoleApplication -> CoreLibrary
-    "node4" [ label = "CryptoCurrencyMiningLibrary", shape = septagon ];
-    "node1" -> "node4" [ style = dotted ] // ConsoleApplication -> CryptoCurrencyMiningLibrary
-    "node5" [ label = "GraphicApplication", shape = egg ];
-    "node5" -> "node2" [ style = dotted ] // GraphicApplication -> CoreLibrary
-    "node6" [ label = "GraphicLibrary", shape = doubleoctagon ];
-    "node7" [ label = "\"-lm\"", shape = septagon ];
-    "node6" -> "node7" [ style = dotted ] // GraphicLibrary -> "-lm"
-    "node6" -> "node0"  // GraphicLibrary -> CompilerFlags
-    "node6" -> "node2" [ style = dotted ] // GraphicLibrary -> CoreLibrary
-    "node5" -> "node6" [ style = dotted ] // GraphicApplication -> GraphicLibrary
-    "node8" [ label = "GraphicDriverOpenGL", shape = tripleoctagon ];
-    "node8" -> "node0" [ style = dotted ] // GraphicDriverOpenGL -> CompilerFlags
-    "node8" -> "node2" [ style = dotted ] // GraphicDriverOpenGL -> CoreLibrary
-    "node9" [ label = "GraphicDriverVulkan", shape = tripleoctagon ];
-    "node9" -> "node0" [ style = dotted ] // GraphicDriverVulkan -> CompilerFlags
-    "node9" -> "node2" [ style = dotted ] // GraphicDriverVulkan -> CoreLibrary
+    "node5" [ label = "CryptoCurrencyMiningLibrary", shape = septagon ];
+    "node1" -> "node5" [ style = dotted ] // ConsoleApplication -> CryptoCurrencyMiningLibrary
+    "node6" [ label = "GraphicApplication", shape = egg ];
+    "node6" -> "node2" [ style = dotted ] // GraphicApplication -> CoreLibrary
+    "node7" [ label = "GraphicLibrary", shape = doubleoctagon ];
+    "node8" [ label = "\"-lm\"", shape = septagon ];
+    "node7" -> "node8" [ style = dotted ] // GraphicLibrary -> "-lm"
+    "node7" -> "node0"  // GraphicLibrary -> CompilerFlags
+    "node7" -> "node2" [ style = dotted ] // GraphicLibrary -> CoreLibrary
+    "node6" -> "node7" [ style = dotted ] // GraphicApplication -> GraphicLibrary
+    "node9" [ label = "GraphicDriverOpenGL", shape = tripleoctagon ];
+    "node9" -> "node0" [ style = dotted ] // GraphicDriverOpenGL -> CompilerFlags
+    "node9" -> "node2" [ style = dotted ] // GraphicDriverOpenGL -> CoreLibrary
+    "node10" [ label = "GraphicDriverVulkan", shape = tripleoctagon ];
+    "node10" -> "node0" [ style = dotted ] // GraphicDriverVulkan -> CompilerFlags
+    "node10" -> "node2" [ style = dotted ] // GraphicDriverVulkan -> CoreLibrary
 }
diff --git a/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_per_target_files.dot b/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_per_target_files.dot
index 1bbf25a..26f2f64 100644
--- a/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_per_target_files.dot
+++ b/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_per_target_files.dot
@@ -28,23 +28,26 @@
     "node2" -> "node0"  // CoreLibrary -> CompilerFlags
     "node3" [ label = "GoofyLoggingLibrary\n(SeriousLoggingLibrary)\n(TheBestLoggingLibrary)", shape = pentagon ];
     "node2" -> "node3" [ style = dotted ] // CoreLibrary -> GoofyLoggingLibrary
+    "node4" [ label = "SystemLibrary", shape = octagon ];
+    "node4" -> "node2" [ style = dotted ] // SystemLibrary -> CoreLibrary
+    "node2" -> "node4" [ style = dotted ] // CoreLibrary -> SystemLibrary
     "node1" -> "node2" [ style = dotted ] // ConsoleApplication -> CoreLibrary
-    "node4" [ label = "CryptoCurrencyMiningLibrary", shape = septagon ];
-    "node1" -> "node4" [ style = dotted ] // ConsoleApplication -> CryptoCurrencyMiningLibrary
-    "node5" [ label = "GraphicApplication", shape = egg ];
-    "node5" -> "node2" [ style = dotted ] // GraphicApplication -> CoreLibrary
-    "node6" [ label = "GraphicLibrary", shape = doubleoctagon ];
-    "node7" [ label = "\"-lm\"", shape = septagon ];
-    "node6" -> "node7" [ style = dotted ] // GraphicLibrary -> "-lm"
-    "node6" -> "node0"  // GraphicLibrary -> CompilerFlags
-    "node6" -> "node2" [ style = dotted ] // GraphicLibrary -> CoreLibrary
-    "node8" [ label = "GraphicLibraryObjects", shape = hexagon ];
-    "node6" -> "node8" [ style = dotted ] // GraphicLibrary -> GraphicLibraryObjects
-    "node5" -> "node6" [ style = dotted ] // GraphicApplication -> GraphicLibrary
-    "node9" [ label = "GraphicDriverOpenGL", shape = tripleoctagon ];
-    "node9" -> "node0" [ style = dotted ] // GraphicDriverOpenGL -> CompilerFlags
-    "node9" -> "node2" [ style = dotted ] // GraphicDriverOpenGL -> CoreLibrary
-    "node10" [ label = "GraphicDriverVulkan", shape = tripleoctagon ];
-    "node10" -> "node0" [ style = dotted ] // GraphicDriverVulkan -> CompilerFlags
-    "node10" -> "node2" [ style = dotted ] // GraphicDriverVulkan -> CoreLibrary
+    "node5" [ label = "CryptoCurrencyMiningLibrary", shape = septagon ];
+    "node1" -> "node5" [ style = dotted ] // ConsoleApplication -> CryptoCurrencyMiningLibrary
+    "node6" [ label = "GraphicApplication", shape = egg ];
+    "node6" -> "node2" [ style = dotted ] // GraphicApplication -> CoreLibrary
+    "node7" [ label = "GraphicLibrary", shape = doubleoctagon ];
+    "node8" [ label = "\"-lm\"", shape = septagon ];
+    "node7" -> "node8" [ style = dotted ] // GraphicLibrary -> "-lm"
+    "node7" -> "node0"  // GraphicLibrary -> CompilerFlags
+    "node7" -> "node2" [ style = dotted ] // GraphicLibrary -> CoreLibrary
+    "node9" [ label = "GraphicLibraryObjects", shape = hexagon ];
+    "node7" -> "node9" [ style = dotted ] // GraphicLibrary -> GraphicLibraryObjects
+    "node6" -> "node7" [ style = dotted ] // GraphicApplication -> GraphicLibrary
+    "node10" [ label = "GraphicDriverOpenGL", shape = tripleoctagon ];
+    "node10" -> "node0" [ style = dotted ] // GraphicDriverOpenGL -> CompilerFlags
+    "node10" -> "node2" [ style = dotted ] // GraphicDriverOpenGL -> CoreLibrary
+    "node11" [ label = "GraphicDriverVulkan", shape = tripleoctagon ];
+    "node11" -> "node0" [ style = dotted ] // GraphicDriverVulkan -> CompilerFlags
+    "node11" -> "node2" [ style = dotted ] // GraphicDriverVulkan -> CoreLibrary
 }
diff --git a/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_shared_libs.dot b/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_shared_libs.dot
index 439d1f7..e127daa 100644
--- a/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_shared_libs.dot
+++ b/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_shared_libs.dot
@@ -28,17 +28,20 @@
     "node2" -> "node0"  // CoreLibrary -> CompilerFlags
     "node3" [ label = "GoofyLoggingLibrary\n(SeriousLoggingLibrary)\n(TheBestLoggingLibrary)", shape = pentagon ];
     "node2" -> "node3" [ style = dotted ] // CoreLibrary -> GoofyLoggingLibrary
+    "node4" [ label = "SystemLibrary", shape = octagon ];
+    "node4" -> "node2" [ style = dotted ] // SystemLibrary -> CoreLibrary
+    "node2" -> "node4" [ style = dotted ] // CoreLibrary -> SystemLibrary
     "node1" -> "node2" [ style = dotted ] // ConsoleApplication -> CoreLibrary
-    "node4" [ label = "CryptoCurrencyMiningLibrary", shape = septagon ];
-    "node1" -> "node4" [ style = dotted ] // ConsoleApplication -> CryptoCurrencyMiningLibrary
-    "node5" [ label = "GraphicApplication", shape = egg ];
-    "node5" -> "node2" [ style = dotted ] // GraphicApplication -> CoreLibrary
-    "node6" [ label = "\"-lm\"", shape = septagon ];
-    "node7" [ label = "GraphicLibraryObjects", shape = hexagon ];
-    "node8" [ label = "GraphicDriverOpenGL", shape = tripleoctagon ];
-    "node8" -> "node0" [ style = dotted ] // GraphicDriverOpenGL -> CompilerFlags
-    "node8" -> "node2" [ style = dotted ] // GraphicDriverOpenGL -> CoreLibrary
-    "node9" [ label = "GraphicDriverVulkan", shape = tripleoctagon ];
-    "node9" -> "node0" [ style = dotted ] // GraphicDriverVulkan -> CompilerFlags
-    "node9" -> "node2" [ style = dotted ] // GraphicDriverVulkan -> CoreLibrary
+    "node5" [ label = "CryptoCurrencyMiningLibrary", shape = septagon ];
+    "node1" -> "node5" [ style = dotted ] // ConsoleApplication -> CryptoCurrencyMiningLibrary
+    "node6" [ label = "GraphicApplication", shape = egg ];
+    "node6" -> "node2" [ style = dotted ] // GraphicApplication -> CoreLibrary
+    "node7" [ label = "\"-lm\"", shape = septagon ];
+    "node8" [ label = "GraphicLibraryObjects", shape = hexagon ];
+    "node9" [ label = "GraphicDriverOpenGL", shape = tripleoctagon ];
+    "node9" -> "node0" [ style = dotted ] // GraphicDriverOpenGL -> CompilerFlags
+    "node9" -> "node2" [ style = dotted ] // GraphicDriverOpenGL -> CoreLibrary
+    "node10" [ label = "GraphicDriverVulkan", shape = tripleoctagon ];
+    "node10" -> "node0" [ style = dotted ] // GraphicDriverVulkan -> CompilerFlags
+    "node10" -> "node2" [ style = dotted ] // GraphicDriverVulkan -> CoreLibrary
 }
diff --git a/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_unknown_libs.dot b/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_unknown_libs.dot
index 1be6550..4f242bb 100644
--- a/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_unknown_libs.dot
+++ b/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_unknown_libs.dot
@@ -28,21 +28,24 @@
     "node2" -> "node0"  // CoreLibrary -> CompilerFlags
     "node3" [ label = "GoofyLoggingLibrary\n(SeriousLoggingLibrary)\n(TheBestLoggingLibrary)", shape = pentagon ];
     "node2" -> "node3" [ style = dotted ] // CoreLibrary -> GoofyLoggingLibrary
+    "node4" [ label = "SystemLibrary", shape = octagon ];
+    "node4" -> "node2" [ style = dotted ] // SystemLibrary -> CoreLibrary
+    "node2" -> "node4" [ style = dotted ] // CoreLibrary -> SystemLibrary
     "node1" -> "node2" [ style = dotted ] // ConsoleApplication -> CoreLibrary
-    "node4" [ label = "GraphicApplication", shape = egg ];
-    "node4" -> "node2" [ style = dotted ] // GraphicApplication -> CoreLibrary
-    "node5" [ label = "GraphicLibrary", shape = doubleoctagon ];
-    "node6" [ label = "\"-lm\"", shape = septagon ];
-    "node5" -> "node6" [ style = dotted ] // GraphicLibrary -> "-lm"
-    "node5" -> "node0"  // GraphicLibrary -> CompilerFlags
-    "node5" -> "node2" [ style = dotted ] // GraphicLibrary -> CoreLibrary
-    "node7" [ label = "GraphicLibraryObjects", shape = hexagon ];
-    "node5" -> "node7" [ style = dotted ] // GraphicLibrary -> GraphicLibraryObjects
-    "node4" -> "node5" [ style = dotted ] // GraphicApplication -> GraphicLibrary
-    "node8" [ label = "GraphicDriverOpenGL", shape = tripleoctagon ];
-    "node8" -> "node0" [ style = dotted ] // GraphicDriverOpenGL -> CompilerFlags
-    "node8" -> "node2" [ style = dotted ] // GraphicDriverOpenGL -> CoreLibrary
-    "node9" [ label = "GraphicDriverVulkan", shape = tripleoctagon ];
-    "node9" -> "node0" [ style = dotted ] // GraphicDriverVulkan -> CompilerFlags
-    "node9" -> "node2" [ style = dotted ] // GraphicDriverVulkan -> CoreLibrary
+    "node5" [ label = "GraphicApplication", shape = egg ];
+    "node5" -> "node2" [ style = dotted ] // GraphicApplication -> CoreLibrary
+    "node6" [ label = "GraphicLibrary", shape = doubleoctagon ];
+    "node7" [ label = "\"-lm\"", shape = septagon ];
+    "node6" -> "node7" [ style = dotted ] // GraphicLibrary -> "-lm"
+    "node6" -> "node0"  // GraphicLibrary -> CompilerFlags
+    "node6" -> "node2" [ style = dotted ] // GraphicLibrary -> CoreLibrary
+    "node8" [ label = "GraphicLibraryObjects", shape = hexagon ];
+    "node6" -> "node8" [ style = dotted ] // GraphicLibrary -> GraphicLibraryObjects
+    "node5" -> "node6" [ style = dotted ] // GraphicApplication -> GraphicLibrary
+    "node9" [ label = "GraphicDriverOpenGL", shape = tripleoctagon ];
+    "node9" -> "node0" [ style = dotted ] // GraphicDriverOpenGL -> CompilerFlags
+    "node9" -> "node2" [ style = dotted ] // GraphicDriverOpenGL -> CoreLibrary
+    "node10" [ label = "GraphicDriverVulkan", shape = tripleoctagon ];
+    "node10" -> "node0" [ style = dotted ] // GraphicDriverVulkan -> CompilerFlags
+    "node10" -> "node2" [ style = dotted ] // GraphicDriverVulkan -> CoreLibrary
 }
diff --git a/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_set_graph_header.dot b/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_set_graph_header.dot
index 1cfbe0f..c664af8 100644
--- a/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_set_graph_header.dot
+++ b/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_set_graph_header.dot
@@ -28,23 +28,26 @@
     "node2" -> "node0"  // CoreLibrary -> CompilerFlags
     "node3" [ label = "GoofyLoggingLibrary\n(SeriousLoggingLibrary)\n(TheBestLoggingLibrary)", shape = pentagon ];
     "node2" -> "node3" [ style = dotted ] // CoreLibrary -> GoofyLoggingLibrary
+    "node4" [ label = "SystemLibrary", shape = octagon ];
+    "node4" -> "node2" [ style = dotted ] // SystemLibrary -> CoreLibrary
+    "node2" -> "node4" [ style = dotted ] // CoreLibrary -> SystemLibrary
     "node1" -> "node2" [ style = dotted ] // ConsoleApplication -> CoreLibrary
-    "node4" [ label = "CryptoCurrencyMiningLibrary", shape = septagon ];
-    "node1" -> "node4" [ style = dotted ] // ConsoleApplication -> CryptoCurrencyMiningLibrary
-    "node5" [ label = "GraphicApplication", shape = egg ];
-    "node5" -> "node2" [ style = dotted ] // GraphicApplication -> CoreLibrary
-    "node6" [ label = "GraphicLibrary", shape = doubleoctagon ];
-    "node7" [ label = "\"-lm\"", shape = septagon ];
-    "node6" -> "node7" [ style = dotted ] // GraphicLibrary -> "-lm"
-    "node6" -> "node0"  // GraphicLibrary -> CompilerFlags
-    "node6" -> "node2" [ style = dotted ] // GraphicLibrary -> CoreLibrary
-    "node8" [ label = "GraphicLibraryObjects", shape = hexagon ];
-    "node6" -> "node8" [ style = dotted ] // GraphicLibrary -> GraphicLibraryObjects
-    "node5" -> "node6" [ style = dotted ] // GraphicApplication -> GraphicLibrary
-    "node9" [ label = "GraphicDriverOpenGL", shape = tripleoctagon ];
-    "node9" -> "node0" [ style = dotted ] // GraphicDriverOpenGL -> CompilerFlags
-    "node9" -> "node2" [ style = dotted ] // GraphicDriverOpenGL -> CoreLibrary
-    "node10" [ label = "GraphicDriverVulkan", shape = tripleoctagon ];
-    "node10" -> "node0" [ style = dotted ] // GraphicDriverVulkan -> CompilerFlags
-    "node10" -> "node2" [ style = dotted ] // GraphicDriverVulkan -> CoreLibrary
+    "node5" [ label = "CryptoCurrencyMiningLibrary", shape = septagon ];
+    "node1" -> "node5" [ style = dotted ] // ConsoleApplication -> CryptoCurrencyMiningLibrary
+    "node6" [ label = "GraphicApplication", shape = egg ];
+    "node6" -> "node2" [ style = dotted ] // GraphicApplication -> CoreLibrary
+    "node7" [ label = "GraphicLibrary", shape = doubleoctagon ];
+    "node8" [ label = "\"-lm\"", shape = septagon ];
+    "node7" -> "node8" [ style = dotted ] // GraphicLibrary -> "-lm"
+    "node7" -> "node0"  // GraphicLibrary -> CompilerFlags
+    "node7" -> "node2" [ style = dotted ] // GraphicLibrary -> CoreLibrary
+    "node9" [ label = "GraphicLibraryObjects", shape = hexagon ];
+    "node7" -> "node9" [ style = dotted ] // GraphicLibrary -> GraphicLibraryObjects
+    "node6" -> "node7" [ style = dotted ] // GraphicApplication -> GraphicLibrary
+    "node10" [ label = "GraphicDriverOpenGL", shape = tripleoctagon ];
+    "node10" -> "node0" [ style = dotted ] // GraphicDriverOpenGL -> CompilerFlags
+    "node10" -> "node2" [ style = dotted ] // GraphicDriverOpenGL -> CoreLibrary
+    "node11" [ label = "GraphicDriverVulkan", shape = tripleoctagon ];
+    "node11" -> "node0" [ style = dotted ] // GraphicDriverVulkan -> CompilerFlags
+    "node11" -> "node2" [ style = dotted ] // GraphicDriverVulkan -> CoreLibrary
 }
diff --git a/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_set_graph_name.dot b/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_set_graph_name.dot
index 9653c33..5579306 100644
--- a/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_set_graph_name.dot
+++ b/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_set_graph_name.dot
@@ -28,23 +28,26 @@
     "node2" -> "node0"  // CoreLibrary -> CompilerFlags
     "node3" [ label = "GoofyLoggingLibrary\n(SeriousLoggingLibrary)\n(TheBestLoggingLibrary)", shape = pentagon ];
     "node2" -> "node3" [ style = dotted ] // CoreLibrary -> GoofyLoggingLibrary
+    "node4" [ label = "SystemLibrary", shape = octagon ];
+    "node4" -> "node2" [ style = dotted ] // SystemLibrary -> CoreLibrary
+    "node2" -> "node4" [ style = dotted ] // CoreLibrary -> SystemLibrary
     "node1" -> "node2" [ style = dotted ] // ConsoleApplication -> CoreLibrary
-    "node4" [ label = "CryptoCurrencyMiningLibrary", shape = septagon ];
-    "node1" -> "node4" [ style = dotted ] // ConsoleApplication -> CryptoCurrencyMiningLibrary
-    "node5" [ label = "GraphicApplication", shape = egg ];
-    "node5" -> "node2" [ style = dotted ] // GraphicApplication -> CoreLibrary
-    "node6" [ label = "GraphicLibrary", shape = doubleoctagon ];
-    "node7" [ label = "\"-lm\"", shape = septagon ];
-    "node6" -> "node7" [ style = dotted ] // GraphicLibrary -> "-lm"
-    "node6" -> "node0"  // GraphicLibrary -> CompilerFlags
-    "node6" -> "node2" [ style = dotted ] // GraphicLibrary -> CoreLibrary
-    "node8" [ label = "GraphicLibraryObjects", shape = hexagon ];
-    "node6" -> "node8" [ style = dotted ] // GraphicLibrary -> GraphicLibraryObjects
-    "node5" -> "node6" [ style = dotted ] // GraphicApplication -> GraphicLibrary
-    "node9" [ label = "GraphicDriverOpenGL", shape = tripleoctagon ];
-    "node9" -> "node0" [ style = dotted ] // GraphicDriverOpenGL -> CompilerFlags
-    "node9" -> "node2" [ style = dotted ] // GraphicDriverOpenGL -> CoreLibrary
-    "node10" [ label = "GraphicDriverVulkan", shape = tripleoctagon ];
-    "node10" -> "node0" [ style = dotted ] // GraphicDriverVulkan -> CompilerFlags
-    "node10" -> "node2" [ style = dotted ] // GraphicDriverVulkan -> CoreLibrary
+    "node5" [ label = "CryptoCurrencyMiningLibrary", shape = septagon ];
+    "node1" -> "node5" [ style = dotted ] // ConsoleApplication -> CryptoCurrencyMiningLibrary
+    "node6" [ label = "GraphicApplication", shape = egg ];
+    "node6" -> "node2" [ style = dotted ] // GraphicApplication -> CoreLibrary
+    "node7" [ label = "GraphicLibrary", shape = doubleoctagon ];
+    "node8" [ label = "\"-lm\"", shape = septagon ];
+    "node7" -> "node8" [ style = dotted ] // GraphicLibrary -> "-lm"
+    "node7" -> "node0"  // GraphicLibrary -> CompilerFlags
+    "node7" -> "node2" [ style = dotted ] // GraphicLibrary -> CoreLibrary
+    "node9" [ label = "GraphicLibraryObjects", shape = hexagon ];
+    "node7" -> "node9" [ style = dotted ] // GraphicLibrary -> GraphicLibraryObjects
+    "node6" -> "node7" [ style = dotted ] // GraphicApplication -> GraphicLibrary
+    "node10" [ label = "GraphicDriverOpenGL", shape = tripleoctagon ];
+    "node10" -> "node0" [ style = dotted ] // GraphicDriverOpenGL -> CompilerFlags
+    "node10" -> "node2" [ style = dotted ] // GraphicDriverOpenGL -> CoreLibrary
+    "node11" [ label = "GraphicDriverVulkan", shape = tripleoctagon ];
+    "node11" -> "node0" [ style = dotted ] // GraphicDriverVulkan -> CompilerFlags
+    "node11" -> "node2" [ style = dotted ] // GraphicDriverVulkan -> CoreLibrary
 }
diff --git a/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_set_node_prefix.dot b/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_set_node_prefix.dot
index 82d96d0..3bf20ec 100644
--- a/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_set_node_prefix.dot
+++ b/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_set_node_prefix.dot
@@ -28,23 +28,26 @@
     "point2" -> "point0"  // CoreLibrary -> CompilerFlags
     "point3" [ label = "GoofyLoggingLibrary\n(SeriousLoggingLibrary)\n(TheBestLoggingLibrary)", shape = pentagon ];
     "point2" -> "point3" [ style = dotted ] // CoreLibrary -> GoofyLoggingLibrary
+    "point4" [ label = "SystemLibrary", shape = octagon ];
+    "point4" -> "point2" [ style = dotted ] // SystemLibrary -> CoreLibrary
+    "point2" -> "point4" [ style = dotted ] // CoreLibrary -> SystemLibrary
     "point1" -> "point2" [ style = dotted ] // ConsoleApplication -> CoreLibrary
-    "point4" [ label = "CryptoCurrencyMiningLibrary", shape = septagon ];
-    "point1" -> "point4" [ style = dotted ] // ConsoleApplication -> CryptoCurrencyMiningLibrary
-    "point5" [ label = "GraphicApplication", shape = egg ];
-    "point5" -> "point2" [ style = dotted ] // GraphicApplication -> CoreLibrary
-    "point6" [ label = "GraphicLibrary", shape = doubleoctagon ];
-    "point7" [ label = "\"-lm\"", shape = septagon ];
-    "point6" -> "point7" [ style = dotted ] // GraphicLibrary -> "-lm"
-    "point6" -> "point0"  // GraphicLibrary -> CompilerFlags
-    "point6" -> "point2" [ style = dotted ] // GraphicLibrary -> CoreLibrary
-    "point8" [ label = "GraphicLibraryObjects", shape = hexagon ];
-    "point6" -> "point8" [ style = dotted ] // GraphicLibrary -> GraphicLibraryObjects
-    "point5" -> "point6" [ style = dotted ] // GraphicApplication -> GraphicLibrary
-    "point9" [ label = "GraphicDriverOpenGL", shape = tripleoctagon ];
-    "point9" -> "point0" [ style = dotted ] // GraphicDriverOpenGL -> CompilerFlags
-    "point9" -> "point2" [ style = dotted ] // GraphicDriverOpenGL -> CoreLibrary
-    "point10" [ label = "GraphicDriverVulkan", shape = tripleoctagon ];
-    "point10" -> "point0" [ style = dotted ] // GraphicDriverVulkan -> CompilerFlags
-    "point10" -> "point2" [ style = dotted ] // GraphicDriverVulkan -> CoreLibrary
+    "point5" [ label = "CryptoCurrencyMiningLibrary", shape = septagon ];
+    "point1" -> "point5" [ style = dotted ] // ConsoleApplication -> CryptoCurrencyMiningLibrary
+    "point6" [ label = "GraphicApplication", shape = egg ];
+    "point6" -> "point2" [ style = dotted ] // GraphicApplication -> CoreLibrary
+    "point7" [ label = "GraphicLibrary", shape = doubleoctagon ];
+    "point8" [ label = "\"-lm\"", shape = septagon ];
+    "point7" -> "point8" [ style = dotted ] // GraphicLibrary -> "-lm"
+    "point7" -> "point0"  // GraphicLibrary -> CompilerFlags
+    "point7" -> "point2" [ style = dotted ] // GraphicLibrary -> CoreLibrary
+    "point9" [ label = "GraphicLibraryObjects", shape = hexagon ];
+    "point7" -> "point9" [ style = dotted ] // GraphicLibrary -> GraphicLibraryObjects
+    "point6" -> "point7" [ style = dotted ] // GraphicApplication -> GraphicLibrary
+    "point10" [ label = "GraphicDriverOpenGL", shape = tripleoctagon ];
+    "point10" -> "point0" [ style = dotted ] // GraphicDriverOpenGL -> CompilerFlags
+    "point10" -> "point2" [ style = dotted ] // GraphicDriverOpenGL -> CoreLibrary
+    "point11" [ label = "GraphicDriverVulkan", shape = tripleoctagon ];
+    "point11" -> "point0" [ style = dotted ] // GraphicDriverVulkan -> CompilerFlags
+    "point11" -> "point2" [ style = dotted ] // GraphicDriverVulkan -> CoreLibrary
 }
diff --git a/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_target_dependencies.dot.GraphicApplication b/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_target_dependencies.dot.GraphicApplication
index 6893fd1..92fe609 100644
--- a/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_target_dependencies.dot.GraphicApplication
+++ b/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_target_dependencies.dot.GraphicApplication
@@ -2,21 +2,25 @@
 node [
   fontsize = "12"
 ];
-    "node5" [ label = "GraphicApplication", shape = egg ];
+    "node6" [ label = "GraphicApplication", shape = egg ];
     "node2" [ label = "CoreLibrary", shape = octagon ];
-    "node5" -> "node2" [ style = dotted ] // GraphicApplication -> CoreLibrary
+    "node6" -> "node2" [ style = dotted ] // GraphicApplication -> CoreLibrary
     "node0" [ label = "CompilerFlags", shape = pentagon ];
     "node2" -> "node0"  // CoreLibrary -> CompilerFlags
     "node3" [ label = "GoofyLoggingLibrary\n(SeriousLoggingLibrary)\n(TheBestLoggingLibrary)", shape = pentagon ];
     "node2" -> "node3" [ style = dotted ] // CoreLibrary -> GoofyLoggingLibrary
-    "node6" [ label = "GraphicLibrary", shape = doubleoctagon ];
-    "node5" -> "node6" [ style = dotted ] // GraphicApplication -> GraphicLibrary
-    "node7" [ label = "\"-lm\"", shape = septagon ];
-    "node6" -> "node7" [ style = dotted ] // GraphicLibrary -> "-lm"
-    "node0" [ label = "CompilerFlags", shape = pentagon ];
-    "node6" -> "node0"  // GraphicLibrary -> CompilerFlags
+    "node4" [ label = "SystemLibrary", shape = octagon ];
+    "node2" -> "node4" [ style = dotted ] // CoreLibrary -> SystemLibrary
     "node2" [ label = "CoreLibrary", shape = octagon ];
-    "node6" -> "node2" [ style = dotted ] // GraphicLibrary -> CoreLibrary
-    "node8" [ label = "GraphicLibraryObjects", shape = hexagon ];
-    "node6" -> "node8" [ style = dotted ] // GraphicLibrary -> GraphicLibraryObjects
+    "node4" -> "node2" [ style = dotted ] // SystemLibrary -> CoreLibrary
+    "node7" [ label = "GraphicLibrary", shape = doubleoctagon ];
+    "node6" -> "node7" [ style = dotted ] // GraphicApplication -> GraphicLibrary
+    "node8" [ label = "\"-lm\"", shape = septagon ];
+    "node7" -> "node8" [ style = dotted ] // GraphicLibrary -> "-lm"
+    "node0" [ label = "CompilerFlags", shape = pentagon ];
+    "node7" -> "node0"  // GraphicLibrary -> CompilerFlags
+    "node2" [ label = "CoreLibrary", shape = octagon ];
+    "node7" -> "node2" [ style = dotted ] // GraphicLibrary -> CoreLibrary
+    "node9" [ label = "GraphicLibraryObjects", shape = hexagon ];
+    "node7" -> "node9" [ style = dotted ] // GraphicLibrary -> GraphicLibraryObjects
 }
diff --git a/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_target_dependers.dot.CompilerFlags.dependers b/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_target_dependers.dot.CompilerFlags.dependers
index 3352b1a..82a2efe 100644
--- a/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_target_dependers.dot.CompilerFlags.dependers
+++ b/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_target_dependers.dot.CompilerFlags.dependers
@@ -5,22 +5,26 @@
     "node0" [ label = "CompilerFlags", shape = pentagon ];
     "node2" [ label = "CoreLibrary", shape = octagon ];
     "node2" -> "node0"  // CoreLibrary -> CompilerFlags
+    "node4" [ label = "SystemLibrary", shape = octagon ];
+    "node4" -> "node2" [ style = dotted ] // SystemLibrary -> CoreLibrary
+    "node2" [ label = "CoreLibrary", shape = octagon ];
+    "node2" -> "node4" [ style = dotted ] // CoreLibrary -> SystemLibrary
     "node1" [ label = "ConsoleApplication", shape = egg ];
     "node1" -> "node2" [ style = dotted ] // ConsoleApplication -> CoreLibrary
-    "node5" [ label = "GraphicApplication", shape = egg ];
-    "node5" -> "node2" [ style = dotted ] // GraphicApplication -> CoreLibrary
-    "node6" [ label = "GraphicLibrary", shape = doubleoctagon ];
-    "node6" -> "node2" [ style = dotted ] // GraphicLibrary -> CoreLibrary
-    "node5" [ label = "GraphicApplication", shape = egg ];
-    "node5" -> "node6" [ style = dotted ] // GraphicApplication -> GraphicLibrary
-    "node9" [ label = "GraphicDriverOpenGL", shape = tripleoctagon ];
-    "node9" -> "node2" [ style = dotted ] // GraphicDriverOpenGL -> CoreLibrary
-    "node10" [ label = "GraphicDriverVulkan", shape = tripleoctagon ];
-    "node10" -> "node2" [ style = dotted ] // GraphicDriverVulkan -> CoreLibrary
-    "node6" [ label = "GraphicLibrary", shape = doubleoctagon ];
-    "node6" -> "node0"  // GraphicLibrary -> CompilerFlags
-    "node9" [ label = "GraphicDriverOpenGL", shape = tripleoctagon ];
-    "node9" -> "node0" [ style = dotted ] // GraphicDriverOpenGL -> CompilerFlags
-    "node10" [ label = "GraphicDriverVulkan", shape = tripleoctagon ];
-    "node10" -> "node0" [ style = dotted ] // GraphicDriverVulkan -> CompilerFlags
+    "node6" [ label = "GraphicApplication", shape = egg ];
+    "node6" -> "node2" [ style = dotted ] // GraphicApplication -> CoreLibrary
+    "node7" [ label = "GraphicLibrary", shape = doubleoctagon ];
+    "node7" -> "node2" [ style = dotted ] // GraphicLibrary -> CoreLibrary
+    "node6" [ label = "GraphicApplication", shape = egg ];
+    "node6" -> "node7" [ style = dotted ] // GraphicApplication -> GraphicLibrary
+    "node10" [ label = "GraphicDriverOpenGL", shape = tripleoctagon ];
+    "node10" -> "node2" [ style = dotted ] // GraphicDriverOpenGL -> CoreLibrary
+    "node11" [ label = "GraphicDriverVulkan", shape = tripleoctagon ];
+    "node11" -> "node2" [ style = dotted ] // GraphicDriverVulkan -> CoreLibrary
+    "node7" [ label = "GraphicLibrary", shape = doubleoctagon ];
+    "node7" -> "node0"  // GraphicLibrary -> CompilerFlags
+    "node10" [ label = "GraphicDriverOpenGL", shape = tripleoctagon ];
+    "node10" -> "node0" [ style = dotted ] // GraphicDriverOpenGL -> CompilerFlags
+    "node11" [ label = "GraphicDriverVulkan", shape = tripleoctagon ];
+    "node11" -> "node0" [ style = dotted ] // GraphicDriverVulkan -> CompilerFlags
 }
diff --git a/Tests/RunCMake/Graphviz/test_project/system_library.c b/Tests/RunCMake/Graphviz/test_project/system_library.c
new file mode 100644
index 0000000..5d67079
--- /dev/null
+++ b/Tests/RunCMake/Graphviz/test_project/system_library.c
@@ -0,0 +1,3 @@
+void initialize_system()
+{
+}
diff --git a/Tests/RunCMake/IncompatibleQt/CMakeLists.txt b/Tests/RunCMake/IncompatibleQt/CMakeLists.txt
index f452db1..ebab7a3 100644
--- a/Tests/RunCMake/IncompatibleQt/CMakeLists.txt
+++ b/Tests/RunCMake/IncompatibleQt/CMakeLists.txt
@@ -1,3 +1,3 @@
-cmake_minimum_required(VERSION 2.8.4)
+cmake_minimum_required(VERSION 3.3)
 project(${RunCMake_TEST} CXX)
 include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/InterfaceLibrary/CMakeLists.txt b/Tests/RunCMake/InterfaceLibrary/CMakeLists.txt
new file mode 100644
index 0000000..74b3ff8
--- /dev/null
+++ b/Tests/RunCMake/InterfaceLibrary/CMakeLists.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 3.3)
+project(${RunCMake_TEST} NONE)
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/InterfaceLibrary/ConfigSources.cmake b/Tests/RunCMake/InterfaceLibrary/ConfigSources.cmake
new file mode 100644
index 0000000..631a845
--- /dev/null
+++ b/Tests/RunCMake/InterfaceLibrary/ConfigSources.cmake
@@ -0,0 +1,2 @@
+# Test an interface library added to the build system by a per-config source.
+add_library(iface INTERFACE $<$<CONFIG:NotAConfig>:${CMAKE_CURRENT_SOURCE_DIR}/iface.c>)
diff --git a/Tests/RunCMake/GoogleTest/GoogleTest-discovery-timeout-result.txt b/Tests/RunCMake/InterfaceLibrary/EmptySources-build2-result.txt
similarity index 100%
copy from Tests/RunCMake/GoogleTest/GoogleTest-discovery-timeout-result.txt
copy to Tests/RunCMake/InterfaceLibrary/EmptySources-build2-result.txt
diff --git a/Tests/RunCMake/InterfaceLibrary/EmptySources-build2-stdout.txt b/Tests/RunCMake/InterfaceLibrary/EmptySources-build2-stdout.txt
new file mode 100644
index 0000000..aac9172
--- /dev/null
+++ b/Tests/RunCMake/InterfaceLibrary/EmptySources-build2-stdout.txt
@@ -0,0 +1 @@
+iface2|Invalid project
diff --git a/Tests/RunCMake/InterfaceLibrary/EmptySources.cmake b/Tests/RunCMake/InterfaceLibrary/EmptySources.cmake
new file mode 100644
index 0000000..f452394
--- /dev/null
+++ b/Tests/RunCMake/InterfaceLibrary/EmptySources.cmake
@@ -0,0 +1,8 @@
+# Test an interface library added to the build system by empty SOURCES.
+add_library(iface INTERFACE)
+set_property(TARGET iface PROPERTY SOURCES "")
+
+# ...but not added by unset SOURCES.
+add_library(iface2 INTERFACE)
+set_property(TARGET iface2 PROPERTY SOURCES "")
+set_property(TARGET iface2 PROPERTY SOURCES)
diff --git a/Tests/RunCMake/InterfaceLibrary/ExcludeFromAll-build1-check.cmake b/Tests/RunCMake/InterfaceLibrary/ExcludeFromAll-build1-check.cmake
new file mode 100644
index 0000000..6500e48
--- /dev/null
+++ b/Tests/RunCMake/InterfaceLibrary/ExcludeFromAll-build1-check.cmake
@@ -0,0 +1,4 @@
+if(EXISTS "${RunCMake_TEST_BINARY_DIR}/iface.txt")
+  set(RunCMake_TEST_FAILED "iface target built as part of 'all'")
+  return()
+endif()
diff --git a/Tests/RunCMake/InterfaceLibrary/ExcludeFromAll-build2-check.cmake b/Tests/RunCMake/InterfaceLibrary/ExcludeFromAll-build2-check.cmake
new file mode 100644
index 0000000..0977c24
--- /dev/null
+++ b/Tests/RunCMake/InterfaceLibrary/ExcludeFromAll-build2-check.cmake
@@ -0,0 +1,4 @@
+if(NOT EXISTS "${RunCMake_TEST_BINARY_DIR}/iface.txt")
+  set(RunCMake_TEST_FAILED "iface target not built")
+  return()
+endif()
diff --git a/Tests/RunCMake/GoogleTest/GoogleTest-discovery-timeout-result.txt b/Tests/RunCMake/InterfaceLibrary/ExcludeFromAll-build3-result.txt
similarity index 100%
copy from Tests/RunCMake/GoogleTest/GoogleTest-discovery-timeout-result.txt
copy to Tests/RunCMake/InterfaceLibrary/ExcludeFromAll-build3-result.txt
diff --git a/Tests/RunCMake/InterfaceLibrary/ExcludeFromAll-build3-stdout.txt b/Tests/RunCMake/InterfaceLibrary/ExcludeFromAll-build3-stdout.txt
new file mode 100644
index 0000000..aac9172
--- /dev/null
+++ b/Tests/RunCMake/InterfaceLibrary/ExcludeFromAll-build3-stdout.txt
@@ -0,0 +1 @@
+iface2|Invalid project
diff --git a/Tests/RunCMake/InterfaceLibrary/ExcludeFromAll.cmake b/Tests/RunCMake/InterfaceLibrary/ExcludeFromAll.cmake
new file mode 100644
index 0000000..714161d
--- /dev/null
+++ b/Tests/RunCMake/InterfaceLibrary/ExcludeFromAll.cmake
@@ -0,0 +1,7 @@
+# Test an interface library with a custom command, but excluded from all.
+add_custom_command(OUTPUT iface.txt COMMAND ${CMAKE_COMMAND} -E touch iface.txt)
+add_library(iface INTERFACE EXCLUDE_FROM_ALL iface.txt)
+
+# Test that EXCLUDE_FROM_ALL is allowed even if the interface library has
+# no sources, and does not cause it to appear in the build system.
+add_library(iface2 INTERFACE EXCLUDE_FROM_ALL)
diff --git a/Tests/RunCMake/interface_library/IMPORTED_LIBNAME-bad-value-result.txt b/Tests/RunCMake/InterfaceLibrary/IMPORTED_LIBNAME-bad-value-result.txt
similarity index 100%
rename from Tests/RunCMake/interface_library/IMPORTED_LIBNAME-bad-value-result.txt
rename to Tests/RunCMake/InterfaceLibrary/IMPORTED_LIBNAME-bad-value-result.txt
diff --git a/Tests/RunCMake/interface_library/IMPORTED_LIBNAME-bad-value-stderr.txt b/Tests/RunCMake/InterfaceLibrary/IMPORTED_LIBNAME-bad-value-stderr.txt
similarity index 100%
rename from Tests/RunCMake/interface_library/IMPORTED_LIBNAME-bad-value-stderr.txt
rename to Tests/RunCMake/InterfaceLibrary/IMPORTED_LIBNAME-bad-value-stderr.txt
diff --git a/Tests/RunCMake/interface_library/IMPORTED_LIBNAME-bad-value.cmake b/Tests/RunCMake/InterfaceLibrary/IMPORTED_LIBNAME-bad-value.cmake
similarity index 100%
rename from Tests/RunCMake/interface_library/IMPORTED_LIBNAME-bad-value.cmake
rename to Tests/RunCMake/InterfaceLibrary/IMPORTED_LIBNAME-bad-value.cmake
diff --git a/Tests/RunCMake/interface_library/IMPORTED_LIBNAME-non-iface-result.txt b/Tests/RunCMake/InterfaceLibrary/IMPORTED_LIBNAME-non-iface-result.txt
similarity index 100%
rename from Tests/RunCMake/interface_library/IMPORTED_LIBNAME-non-iface-result.txt
rename to Tests/RunCMake/InterfaceLibrary/IMPORTED_LIBNAME-non-iface-result.txt
diff --git a/Tests/RunCMake/interface_library/IMPORTED_LIBNAME-non-iface-stderr.txt b/Tests/RunCMake/InterfaceLibrary/IMPORTED_LIBNAME-non-iface-stderr.txt
similarity index 100%
rename from Tests/RunCMake/interface_library/IMPORTED_LIBNAME-non-iface-stderr.txt
rename to Tests/RunCMake/InterfaceLibrary/IMPORTED_LIBNAME-non-iface-stderr.txt
diff --git a/Tests/RunCMake/interface_library/IMPORTED_LIBNAME-non-iface.cmake b/Tests/RunCMake/InterfaceLibrary/IMPORTED_LIBNAME-non-iface.cmake
similarity index 100%
rename from Tests/RunCMake/interface_library/IMPORTED_LIBNAME-non-iface.cmake
rename to Tests/RunCMake/InterfaceLibrary/IMPORTED_LIBNAME-non-iface.cmake
diff --git a/Tests/RunCMake/interface_library/IMPORTED_LIBNAME-non-imported-result.txt b/Tests/RunCMake/InterfaceLibrary/IMPORTED_LIBNAME-non-imported-result.txt
similarity index 100%
rename from Tests/RunCMake/interface_library/IMPORTED_LIBNAME-non-imported-result.txt
rename to Tests/RunCMake/InterfaceLibrary/IMPORTED_LIBNAME-non-imported-result.txt
diff --git a/Tests/RunCMake/interface_library/IMPORTED_LIBNAME-non-imported-stderr.txt b/Tests/RunCMake/InterfaceLibrary/IMPORTED_LIBNAME-non-imported-stderr.txt
similarity index 100%
rename from Tests/RunCMake/interface_library/IMPORTED_LIBNAME-non-imported-stderr.txt
rename to Tests/RunCMake/InterfaceLibrary/IMPORTED_LIBNAME-non-imported-stderr.txt
diff --git a/Tests/RunCMake/interface_library/IMPORTED_LIBNAME-non-imported.cmake b/Tests/RunCMake/InterfaceLibrary/IMPORTED_LIBNAME-non-imported.cmake
similarity index 100%
rename from Tests/RunCMake/interface_library/IMPORTED_LIBNAME-non-imported.cmake
rename to Tests/RunCMake/InterfaceLibrary/IMPORTED_LIBNAME-non-imported.cmake
diff --git a/Tests/RunCMake/GoogleTest/GoogleTest-discovery-timeout-result.txt b/Tests/RunCMake/InterfaceLibrary/PublicSources-build3-result.txt
similarity index 100%
copy from Tests/RunCMake/GoogleTest/GoogleTest-discovery-timeout-result.txt
copy to Tests/RunCMake/InterfaceLibrary/PublicSources-build3-result.txt
diff --git a/Tests/RunCMake/InterfaceLibrary/PublicSources-build3-stdout.txt b/Tests/RunCMake/InterfaceLibrary/PublicSources-build3-stdout.txt
new file mode 100644
index 0000000..aac9172
--- /dev/null
+++ b/Tests/RunCMake/InterfaceLibrary/PublicSources-build3-stdout.txt
@@ -0,0 +1 @@
+iface2|Invalid project
diff --git a/Tests/RunCMake/InterfaceLibrary/PublicSources.cmake b/Tests/RunCMake/InterfaceLibrary/PublicSources.cmake
new file mode 100644
index 0000000..24785bb
--- /dev/null
+++ b/Tests/RunCMake/InterfaceLibrary/PublicSources.cmake
@@ -0,0 +1,20 @@
+cmake_policy(SET CMP0076 NEW)
+enable_language(C)
+
+# Test that an interface library can have PUBLIC sources.
+# This causes the target to appear in the build system
+# *and* causes consumers to use the source.
+add_library(iface INTERFACE)
+target_sources(iface
+  PUBLIC iface.c
+  # Private sources do not compile here or propagate.
+  PRIVATE iface_broken.c
+  )
+
+# Test that an intermediate interface library does not get the
+# sources and does not appear in the build system.
+add_library(iface2 INTERFACE)
+target_link_libraries(iface2 INTERFACE iface)
+
+add_executable(use_iface use_iface.c)
+target_link_libraries(use_iface PRIVATE iface2)
diff --git a/Tests/RunCMake/InterfaceLibrary/RunCMakeTest.cmake b/Tests/RunCMake/InterfaceLibrary/RunCMakeTest.cmake
new file mode 100644
index 0000000..834b3c8
--- /dev/null
+++ b/Tests/RunCMake/InterfaceLibrary/RunCMakeTest.cmake
@@ -0,0 +1,36 @@
+include(RunCMake)
+
+run_cmake(invalid_name)
+run_cmake(target_commands)
+run_cmake(no_shared_libs)
+run_cmake(invalid_signature)
+run_cmake(global-interface)
+run_cmake(genex_link)
+run_cmake(add_custom_command-TARGET)
+run_cmake(IMPORTED_LIBNAME-bad-value)
+run_cmake(IMPORTED_LIBNAME-non-iface)
+run_cmake(IMPORTED_LIBNAME-non-imported)
+
+function(run_WithSources CASE)
+  if(NOT RunCMake_GENERATOR_IS_MULTI_CONFIG)
+    set(RunCMake_TEST_OPTIONS -DCMAKE_BUILD_TYPE=Debug)
+  endif()
+  set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/${CASE}-build)
+  run_cmake(${CASE})
+  set(RunCMake_TEST_NO_CLEAN 1)
+  foreach(build IN LISTS ARGN)
+    if(build MATCHES "^([^:]+)$")
+      run_cmake_command(${CASE}-${CMAKE_MATCH_1} ${CMAKE_COMMAND} --build . --config Debug)
+    elseif(build MATCHES "^([^:]+):([^:,]+)(,merge)?$")
+      if(CMAKE_MATCH_3 STREQUAL ",merge")
+        set(RunCMake_TEST_OUTPUT_MERGE 1)
+      endif()
+      run_cmake_command(${CASE}-${CMAKE_MATCH_1} ${CMAKE_COMMAND} --build . --config Debug --target ${CMAKE_MATCH_2})
+    endif()
+  endforeach()
+endfunction()
+
+run_WithSources(ConfigSources "build1:iface")
+run_WithSources(EmptySources "build1:iface" "build2:iface2,merge")
+run_WithSources(ExcludeFromAll "build1" "build2:iface" "build3:iface2,merge")
+run_WithSources(PublicSources "build1" "build2:iface" "build3:iface2,merge")
diff --git a/Tests/RunCMake/interface_library/add_custom_command-TARGET-result.txt b/Tests/RunCMake/InterfaceLibrary/add_custom_command-TARGET-result.txt
similarity index 100%
rename from Tests/RunCMake/interface_library/add_custom_command-TARGET-result.txt
rename to Tests/RunCMake/InterfaceLibrary/add_custom_command-TARGET-result.txt
diff --git a/Tests/RunCMake/interface_library/add_custom_command-TARGET-stderr.txt b/Tests/RunCMake/InterfaceLibrary/add_custom_command-TARGET-stderr.txt
similarity index 100%
rename from Tests/RunCMake/interface_library/add_custom_command-TARGET-stderr.txt
rename to Tests/RunCMake/InterfaceLibrary/add_custom_command-TARGET-stderr.txt
diff --git a/Tests/RunCMake/interface_library/add_custom_command-TARGET.cmake b/Tests/RunCMake/InterfaceLibrary/add_custom_command-TARGET.cmake
similarity index 100%
rename from Tests/RunCMake/interface_library/add_custom_command-TARGET.cmake
rename to Tests/RunCMake/InterfaceLibrary/add_custom_command-TARGET.cmake
diff --git a/Tests/RunCMake/interface_library/genex_link-result.txt b/Tests/RunCMake/InterfaceLibrary/genex_link-result.txt
similarity index 100%
rename from Tests/RunCMake/interface_library/genex_link-result.txt
rename to Tests/RunCMake/InterfaceLibrary/genex_link-result.txt
diff --git a/Tests/RunCMake/interface_library/genex_link.cmake b/Tests/RunCMake/InterfaceLibrary/genex_link.cmake
similarity index 100%
rename from Tests/RunCMake/interface_library/genex_link.cmake
rename to Tests/RunCMake/InterfaceLibrary/genex_link.cmake
diff --git a/Tests/RunCMake/interface_library/global-interface-result.txt b/Tests/RunCMake/InterfaceLibrary/global-interface-result.txt
similarity index 100%
rename from Tests/RunCMake/interface_library/global-interface-result.txt
rename to Tests/RunCMake/InterfaceLibrary/global-interface-result.txt
diff --git a/Tests/RunCMake/InterfaceLibrary/global-interface-stderr.txt b/Tests/RunCMake/InterfaceLibrary/global-interface-stderr.txt
new file mode 100644
index 0000000..38585eb
--- /dev/null
+++ b/Tests/RunCMake/InterfaceLibrary/global-interface-stderr.txt
@@ -0,0 +1,9 @@
+CMake Error at global-interface.cmake:2 \(add_library\):
+  Cannot find source file:
+
+    GLOBAL
+
+  Tried extensions \.c \.C .*
+.*
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/interface_library/global-interface.cmake b/Tests/RunCMake/InterfaceLibrary/global-interface.cmake
similarity index 100%
rename from Tests/RunCMake/interface_library/global-interface.cmake
rename to Tests/RunCMake/InterfaceLibrary/global-interface.cmake
diff --git a/Tests/RunCMake/InterfaceLibrary/iface.c b/Tests/RunCMake/InterfaceLibrary/iface.c
new file mode 100644
index 0000000..c7e7372
--- /dev/null
+++ b/Tests/RunCMake/InterfaceLibrary/iface.c
@@ -0,0 +1,4 @@
+int iface(void)
+{
+  return 0;
+}
diff --git a/Tests/RunCMake/InterfaceLibrary/iface_broken.c b/Tests/RunCMake/InterfaceLibrary/iface_broken.c
new file mode 100644
index 0000000..4ff7f31
--- /dev/null
+++ b/Tests/RunCMake/InterfaceLibrary/iface_broken.c
@@ -0,0 +1 @@
+#error This file should not compile
diff --git a/Tests/RunCMake/interface_library/invalid_name-result.txt b/Tests/RunCMake/InterfaceLibrary/invalid_name-result.txt
similarity index 100%
rename from Tests/RunCMake/interface_library/invalid_name-result.txt
rename to Tests/RunCMake/InterfaceLibrary/invalid_name-result.txt
diff --git a/Tests/RunCMake/interface_library/invalid_name-stderr.txt b/Tests/RunCMake/InterfaceLibrary/invalid_name-stderr.txt
similarity index 100%
rename from Tests/RunCMake/interface_library/invalid_name-stderr.txt
rename to Tests/RunCMake/InterfaceLibrary/invalid_name-stderr.txt
diff --git a/Tests/RunCMake/InterfaceLibrary/invalid_name.cmake b/Tests/RunCMake/InterfaceLibrary/invalid_name.cmake
new file mode 100644
index 0000000..575fcc6
--- /dev/null
+++ b/Tests/RunCMake/InterfaceLibrary/invalid_name.cmake
@@ -0,0 +1,6 @@
+cmake_minimum_required(VERSION 2.8.12)
+add_library(if$ace INTERFACE)
+
+add_library(iface::target INTERFACE)
+
+add_library(if$target_imported INTERFACE IMPORTED)
diff --git a/Tests/RunCMake/interface_library/invalid_signature-result.txt b/Tests/RunCMake/InterfaceLibrary/invalid_signature-result.txt
similarity index 100%
rename from Tests/RunCMake/interface_library/invalid_signature-result.txt
rename to Tests/RunCMake/InterfaceLibrary/invalid_signature-result.txt
diff --git a/Tests/RunCMake/InterfaceLibrary/invalid_signature-stderr.txt b/Tests/RunCMake/InterfaceLibrary/invalid_signature-stderr.txt
new file mode 100644
index 0000000..763f9f8
--- /dev/null
+++ b/Tests/RunCMake/InterfaceLibrary/invalid_signature-stderr.txt
@@ -0,0 +1,74 @@
+CMake Error at invalid_signature.cmake:3 \(add_library\):
+  add_library INTERFACE library specified with conflicting/multiple types.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)
++
+CMake Error at invalid_signature.cmake:4 \(add_library\):
+  add_library INTERFACE library specified with conflicting/multiple types.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)
++
+CMake Error at invalid_signature.cmake:5 \(add_library\):
+  add_library INTERFACE library specified with conflicting/multiple types.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)
++
+CMake Error at invalid_signature.cmake:6 \(add_library\):
+  add_library INTERFACE library specified with conflicting/multiple types.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)
++
+CMake Error at invalid_signature.cmake:7 \(add_library\):
+  add_library INTERFACE library specified with conflicting/multiple types.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)
++
+CMake Error at invalid_signature.cmake:8 \(add_library\):
+  add_library INTERFACE library specified with conflicting/multiple types.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)
++
+CMake Error at invalid_signature.cmake:9 \(add_library\):
+  add_library INTERFACE library specified with conflicting STATIC type.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)
++
+CMake Error at invalid_signature.cmake:10 \(add_library\):
+  add_library INTERFACE library specified with conflicting SHARED type.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)
++
+CMake Error at invalid_signature.cmake:11 \(add_library\):
+  add_library INTERFACE library specified with conflicting MODULE type.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)
++
+CMake Error at invalid_signature.cmake:12 \(add_library\):
+  add_library INTERFACE library specified with conflicting OBJECT type.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)
++
+CMake Error at invalid_signature.cmake:13 \(add_library\):
+  add_library INTERFACE library specified with conflicting UNKNOWN type.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)
++
+CMake Error at invalid_signature.cmake:14 \(add_library\):
+  add_library INTERFACE library specified with conflicting ALIAS type.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)
++
+CMake Error at invalid_signature.cmake:15 \(add_library\):
+  add_library INTERFACE library specified with conflicting ALIAS type.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)
++
+CMake Error at invalid_signature.cmake:16 \(add_library\):
+  add_library INTERFACE library specified with conflicting/multiple types.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)
++
+CMake Error at invalid_signature.cmake:20 \(add_library\):
+  add_library GLOBAL option may only be used with IMPORTED libraries.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/InterfaceLibrary/invalid_signature.cmake b/Tests/RunCMake/InterfaceLibrary/invalid_signature.cmake
new file mode 100644
index 0000000..2a575b5
--- /dev/null
+++ b/Tests/RunCMake/InterfaceLibrary/invalid_signature.cmake
@@ -0,0 +1,20 @@
+
+
+add_library(iface3 STATIC INTERFACE)
+add_library(iface4 STATIC INTERFACE empty.cpp)
+add_library(iface5 SHARED INTERFACE)
+add_library(iface6 MODULE INTERFACE)
+add_library(iface7 OBJECT INTERFACE)
+add_library(iface8 UNKNOWN INTERFACE)
+add_library(iface9 INTERFACE STATIC)
+add_library(iface10 INTERFACE SHARED)
+add_library(iface11 INTERFACE MODULE)
+add_library(iface12 INTERFACE OBJECT)
+add_library(iface13 INTERFACE UNKNOWN)
+add_library(iface14 INTERFACE ALIAS)
+add_library(iface15 ALIAS INTERFACE)
+add_library(iface16 INTERFACE INTERFACE)
+
+
+# add_library(iface19 GLOBAL INTERFACE) Tested separately
+add_library(iface20 INTERFACE GLOBAL)
diff --git a/Tests/RunCMake/interface_library/no_shared_libs.cmake b/Tests/RunCMake/InterfaceLibrary/no_shared_libs.cmake
similarity index 100%
rename from Tests/RunCMake/interface_library/no_shared_libs.cmake
rename to Tests/RunCMake/InterfaceLibrary/no_shared_libs.cmake
diff --git a/Tests/RunCMake/interface_library/target_commands-result.txt b/Tests/RunCMake/InterfaceLibrary/target_commands-result.txt
similarity index 100%
rename from Tests/RunCMake/interface_library/target_commands-result.txt
rename to Tests/RunCMake/InterfaceLibrary/target_commands-result.txt
diff --git a/Tests/RunCMake/interface_library/target_commands-stderr.txt b/Tests/RunCMake/InterfaceLibrary/target_commands-stderr.txt
similarity index 100%
rename from Tests/RunCMake/interface_library/target_commands-stderr.txt
rename to Tests/RunCMake/InterfaceLibrary/target_commands-stderr.txt
diff --git a/Tests/RunCMake/interface_library/target_commands.cmake b/Tests/RunCMake/InterfaceLibrary/target_commands.cmake
similarity index 100%
rename from Tests/RunCMake/interface_library/target_commands.cmake
rename to Tests/RunCMake/InterfaceLibrary/target_commands.cmake
diff --git a/Tests/RunCMake/InterfaceLibrary/use_iface.c b/Tests/RunCMake/InterfaceLibrary/use_iface.c
new file mode 100644
index 0000000..66293e4
--- /dev/null
+++ b/Tests/RunCMake/InterfaceLibrary/use_iface.c
@@ -0,0 +1,6 @@
+extern int iface(void);
+
+int main(void)
+{
+  return iface();
+}
diff --git a/Tests/RunCMake/Languages/CMakeLists.txt b/Tests/RunCMake/Languages/CMakeLists.txt
index 8996fef..74b3ff8 100644
--- a/Tests/RunCMake/Languages/CMakeLists.txt
+++ b/Tests/RunCMake/Languages/CMakeLists.txt
@@ -1,4 +1,3 @@
-cmake_minimum_required(VERSION 2.8.4)
-cmake_policy(SET CMP0042 NEW)
+cmake_minimum_required(VERSION 3.3)
 project(${RunCMake_TEST} NONE)
 include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/Languages/LINK_LANGUAGE-genex-result.txt b/Tests/RunCMake/Languages/LINKER_LANGUAGE-genex-result.txt
similarity index 100%
rename from Tests/RunCMake/Languages/LINK_LANGUAGE-genex-result.txt
rename to Tests/RunCMake/Languages/LINKER_LANGUAGE-genex-result.txt
diff --git a/Tests/RunCMake/Languages/LINKER_LANGUAGE-genex-stderr.txt b/Tests/RunCMake/Languages/LINKER_LANGUAGE-genex-stderr.txt
new file mode 100644
index 0000000..7abf76a
--- /dev/null
+++ b/Tests/RunCMake/Languages/LINKER_LANGUAGE-genex-stderr.txt
@@ -0,0 +1,9 @@
+CMake Error at LINKER_LANGUAGE-genex.cmake:[0-9]+ \(target_link_libraries\):
+  Error evaluating generator expression:
+
+    \$<TARGET_PROPERTY:LINKER_LANGUAGE>
+
+  LINKER_LANGUAGE target property can not be used while evaluating link
+  libraries for a static library
+Call Stack \(most recent call first\):
+  CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/Languages/LINK_LANGUAGE-genex.cmake b/Tests/RunCMake/Languages/LINKER_LANGUAGE-genex.cmake
similarity index 100%
rename from Tests/RunCMake/Languages/LINK_LANGUAGE-genex.cmake
rename to Tests/RunCMake/Languages/LINKER_LANGUAGE-genex.cmake
diff --git a/Tests/RunCMake/Languages/LINK_LANGUAGE-genex-stderr.txt b/Tests/RunCMake/Languages/LINK_LANGUAGE-genex-stderr.txt
deleted file mode 100644
index 03c002e..0000000
--- a/Tests/RunCMake/Languages/LINK_LANGUAGE-genex-stderr.txt
+++ /dev/null
@@ -1,9 +0,0 @@
-CMake Error at LINK_LANGUAGE-genex.cmake:[0-9]+ \(target_link_libraries\):
-  Error evaluating generator expression:
-
-    \$<TARGET_PROPERTY:LINKER_LANGUAGE>
-
-  LINKER_LANGUAGE target property can not be used while evaluating link
-  libraries for a static library
-Call Stack \(most recent call first\):
-  CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/Languages/RunCMakeTest.cmake b/Tests/RunCMake/Languages/RunCMakeTest.cmake
index 2a534b3..48216e9 100644
--- a/Tests/RunCMake/Languages/RunCMakeTest.cmake
+++ b/Tests/RunCMake/Languages/RunCMakeTest.cmake
@@ -1,7 +1,7 @@
 include(RunCMake)
 
 run_cmake(NoLangSHARED)
-run_cmake(LINK_LANGUAGE-genex)
+run_cmake(LINKER_LANGUAGE-genex)
 run_cmake(link-libraries-TARGET_FILE-genex)
 run_cmake(link-libraries-TARGET_FILE-genex-ok)
 
diff --git a/Tests/RunCMake/Make/RunCMakeTest.cmake b/Tests/RunCMake/Make/RunCMakeTest.cmake
index 6b2721c..32aafca 100644
--- a/Tests/RunCMake/Make/RunCMakeTest.cmake
+++ b/Tests/RunCMake/Make/RunCMakeTest.cmake
@@ -27,12 +27,15 @@
   run_cmake_command(VerboseBuild-build ${CMAKE_COMMAND} --build . -v --clean-first)
   unset(RunCMake-stdout-file)
   set(_backup_lang "$ENV{LANG}")
+  set(_backup_lc_Messages "$ENV{LC_MESSAGES}")
   if(MAKE_IS_GNU)
     set(RunCMake-stdout-file VerboseBuild-nowork-gnu-stdout.txt)
     set(ENV{LANG} "C")
+    set(ENV{LC_MESSAGES} "C")
   endif()
   run_cmake_command(VerboseBuild-nowork ${CMAKE_COMMAND} --build . --verbose)
   set(ENV{LANG} "${_backup_lang}")
+  set(ENV{LC_MESSAGES} "${_backup_lc_messages}")
 endfunction()
 run_VerboseBuild()
 
diff --git a/Tests/RunCMake/Ninja/RunCMakeTest.cmake b/Tests/RunCMake/Ninja/RunCMakeTest.cmake
index c1f6346..d43023b 100644
--- a/Tests/RunCMake/Ninja/RunCMakeTest.cmake
+++ b/Tests/RunCMake/Ninja/RunCMakeTest.cmake
@@ -18,6 +18,12 @@
   message(FATAL_ERROR "'ninja --version' reported:\n${ninja_out}")
 endif()
 
+if(CMAKE_HOST_WIN32)
+  run_cmake(SelectCompilerWindows)
+else()
+  run_cmake(SelectCompilerUNIX)
+endif()
+
 function(run_NinjaToolMissing)
   set(RunCMake_MAKE_PROGRAM ninja-tool-missing)
   run_cmake(NinjaToolMissing)
diff --git a/Tests/RunCMake/Ninja/SelectCompiler/1/gcc b/Tests/RunCMake/Ninja/SelectCompiler/1/gcc
new file mode 100755
index 0000000..151dfa6
--- /dev/null
+++ b/Tests/RunCMake/Ninja/SelectCompiler/1/gcc
@@ -0,0 +1,2 @@
+#!/bin/sh
+false
diff --git a/Tests/RunCMake/Ninja/SelectCompiler/2/cc b/Tests/RunCMake/Ninja/SelectCompiler/2/cc
new file mode 100755
index 0000000..151dfa6
--- /dev/null
+++ b/Tests/RunCMake/Ninja/SelectCompiler/2/cc
@@ -0,0 +1,2 @@
+#!/bin/sh
+false
diff --git a/Tests/RunCMake/Languages/LINK_LANGUAGE-genex-result.txt b/Tests/RunCMake/Ninja/SelectCompilerUNIX-result.txt
similarity index 100%
copy from Tests/RunCMake/Languages/LINK_LANGUAGE-genex-result.txt
copy to Tests/RunCMake/Ninja/SelectCompilerUNIX-result.txt
diff --git a/Tests/RunCMake/Ninja/SelectCompilerUNIX-stderr.txt b/Tests/RunCMake/Ninja/SelectCompilerUNIX-stderr.txt
new file mode 100644
index 0000000..a2baa48
--- /dev/null
+++ b/Tests/RunCMake/Ninja/SelectCompilerUNIX-stderr.txt
@@ -0,0 +1,6 @@
+^CMake Error at .*/Modules/CMakeTestCCompiler.cmake:[0-9]+ \(message\):
+  The C compiler
+
+    "[^"]*/Tests/RunCMake/Ninja/SelectCompiler/2/cc"
+
+  is not able to compile a simple test program.
diff --git a/Tests/RunCMake/Ninja/SelectCompilerUNIX.cmake b/Tests/RunCMake/Ninja/SelectCompilerUNIX.cmake
new file mode 100644
index 0000000..02c8439
--- /dev/null
+++ b/Tests/RunCMake/Ninja/SelectCompilerUNIX.cmake
@@ -0,0 +1,3 @@
+set(ENV{PATH} "${CMAKE_CURRENT_SOURCE_DIR}/SelectCompiler/1:${CMAKE_CURRENT_SOURCE_DIR}/SelectCompiler/2:$ENV{PATH}")
+unset(ENV{CC})
+enable_language(C)
diff --git a/Tests/RunCMake/Languages/LINK_LANGUAGE-genex-result.txt b/Tests/RunCMake/Ninja/SelectCompilerWindows-result.txt
similarity index 100%
copy from Tests/RunCMake/Languages/LINK_LANGUAGE-genex-result.txt
copy to Tests/RunCMake/Ninja/SelectCompilerWindows-result.txt
diff --git a/Tests/RunCMake/Ninja/SelectCompilerWindows-stderr.txt b/Tests/RunCMake/Ninja/SelectCompilerWindows-stderr.txt
new file mode 100644
index 0000000..e4b506e
--- /dev/null
+++ b/Tests/RunCMake/Ninja/SelectCompilerWindows-stderr.txt
@@ -0,0 +1,6 @@
+^CMake Error at .*/Modules/CMakeTestCCompiler.cmake:[0-9]+ \(message\):
+  The C compiler
+
+    "[^"]*/Tests/RunCMake/Ninja/SelectCompiler/1/gcc"
+
+  is not able to compile a simple test program.
diff --git a/Tests/RunCMake/Ninja/SelectCompilerWindows.cmake b/Tests/RunCMake/Ninja/SelectCompilerWindows.cmake
new file mode 100644
index 0000000..f5a7e2b
--- /dev/null
+++ b/Tests/RunCMake/Ninja/SelectCompilerWindows.cmake
@@ -0,0 +1,3 @@
+set(ENV{PATH} "${CMAKE_CURRENT_SOURCE_DIR}/SelectCompiler/1;${CMAKE_CURRENT_SOURCE_DIR}/SelectCompiler/2;$ENV{PATH}")
+unset(ENV{CC})
+enable_language(C)
diff --git a/Tests/RunCMake/NinjaMultiConfig/CudaSimple.cmake b/Tests/RunCMake/NinjaMultiConfig/CudaSimple.cmake
index 2e9b1cb..00d8a1b 100644
--- a/Tests/RunCMake/NinjaMultiConfig/CudaSimple.cmake
+++ b/Tests/RunCMake/NinjaMultiConfig/CudaSimple.cmake
@@ -1,3 +1,4 @@
+cmake_policy(SET CMP0104 NEW)
 enable_language(CUDA)
 file(TOUCH ${CMAKE_BINARY_DIR}/empty.cmake)
 
diff --git a/Tests/RunCMake/NinjaMultiConfig/ExcludeFromAll-all-build-check.cmake b/Tests/RunCMake/NinjaMultiConfig/ExcludeFromAll-all-build-check.cmake
new file mode 100644
index 0000000..a4d2758
--- /dev/null
+++ b/Tests/RunCMake/NinjaMultiConfig/ExcludeFromAll-all-build-check.cmake
@@ -0,0 +1,9 @@
+check_files("${RunCMake_TEST_BINARY_DIR}"
+  INCLUDE
+    ${TARGET_FILE_release_only_tool_Release}
+    ${TARGET_EXE_FILE_release_only_tool_Release}
+
+  EXCLUDE
+    ${TARGET_FILE_release_only_tool_Debug}
+    ${TARGET_EXE_FILE_release_only_tool_Debug}
+  )
diff --git a/Tests/RunCMake/NinjaMultiConfig/ExcludeFromAll.cmake b/Tests/RunCMake/NinjaMultiConfig/ExcludeFromAll.cmake
new file mode 100644
index 0000000..52f84ea
--- /dev/null
+++ b/Tests/RunCMake/NinjaMultiConfig/ExcludeFromAll.cmake
@@ -0,0 +1,12 @@
+enable_language(C)
+
+set(CMAKE_CONFIGURATION_TYPES "Release;Debug" CACHE STRING "")
+set(CMAKE_DEFAULT_BUILD_TYPE "Release" CACHE STRING "")
+set(CMAKE_CROSS_CONFIGS "all" CACHE STRING "")
+set(CMAKE_DEFAULT_CONFIGS "all" CACHE STRING "")
+
+add_executable(release_only_tool main.c)
+set_property(TARGET release_only_tool PROPERTY EXCLUDE_FROM_ALL "$<NOT:$<CONFIG:Release>>")
+
+include(${CMAKE_CURRENT_LIST_DIR}/Common.cmake)
+generate_output_files(release_only_tool)
diff --git a/Tests/RunCMake/NinjaMultiConfig/RunCMakeTest.cmake b/Tests/RunCMake/NinjaMultiConfig/RunCMakeTest.cmake
index d4a08a9..9249724 100644
--- a/Tests/RunCMake/NinjaMultiConfig/RunCMakeTest.cmake
+++ b/Tests/RunCMake/NinjaMultiConfig/RunCMakeTest.cmake
@@ -274,6 +274,11 @@
 file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}/install")
 run_ninja(Install all-install build.ninja install:all)
 
+set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/ExcludeFromAll-build)
+run_cmake_configure(ExcludeFromAll)
+include(${RunCMake_TEST_BINARY_DIR}/target_files.cmake)
+run_cmake_build(ExcludeFromAll all "" all:all)
+
 # FIXME Get this working
 #set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/AutoMocExecutable-build)
 #run_cmake_configure(AutoMocExecutable)
@@ -289,7 +294,8 @@
   "-DCMAKE_DEFAULT_CONFIGS=all"
   )
 
-if(CMake_TEST_CUDA)
+# CudaSimple uses separable compilation, which is currently only supported on NVCC.
+if(CMake_TEST_CUDA AND NOT CMake_TEST_CUDA STREQUAL "Clang")
   set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/CudaSimple-build)
   run_cmake_configure(CudaSimple)
   include(${RunCMake_TEST_BINARY_DIR}/target_files.cmake)
diff --git a/Tests/RunCMake/ObjectLibrary/MissingSource-stderr.txt b/Tests/RunCMake/ObjectLibrary/MissingSource-stderr.txt
index 411cd7c..5c7882d 100644
--- a/Tests/RunCMake/ObjectLibrary/MissingSource-stderr.txt
+++ b/Tests/RunCMake/ObjectLibrary/MissingSource-stderr.txt
@@ -3,7 +3,7 @@
 
     missing.c
 
-  Tried extensions( \.[A-Za-z+]+|
- )*
+  Tried extensions \.c \.C .*
+.*
 Call Stack \(most recent call first\):
   CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/ObjectLibrary/b.c b/Tests/RunCMake/ObjectLibrary/b.c
index 220ce03..2c65a2b 100644
--- a/Tests/RunCMake/ObjectLibrary/b.c
+++ b/Tests/RunCMake/ObjectLibrary/b.c
@@ -5,7 +5,7 @@
 #endif
 
 extern int a(void);
-EXPORT int b()
+EXPORT int b(void)
 {
   return a();
 }
diff --git a/Tests/RunCMake/ObjectLibrary/requires.c b/Tests/RunCMake/ObjectLibrary/requires.c
index 685632b..a5b429a 100644
--- a/Tests/RunCMake/ObjectLibrary/requires.c
+++ b/Tests/RunCMake/ObjectLibrary/requires.c
@@ -1,5 +1,5 @@
 #ifdef REQUIRED
-int required()
+int required(void)
 {
   return 0;
 }
diff --git a/Tests/RunCMake/ObsoleteQtMacros/CMakeLists.txt b/Tests/RunCMake/ObsoleteQtMacros/CMakeLists.txt
index 65ac8e8..44b5d30 100644
--- a/Tests/RunCMake/ObsoleteQtMacros/CMakeLists.txt
+++ b/Tests/RunCMake/ObsoleteQtMacros/CMakeLists.txt
@@ -1,3 +1,3 @@
-cmake_minimum_required(VERSION 2.8.11)
+cmake_minimum_required(VERSION 3.3)
 project(${RunCMake_TEST})
 include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/PositionIndependentCode/CMakeLists.txt b/Tests/RunCMake/PositionIndependentCode/CMakeLists.txt
index 90afc12..c3922d6 100644
--- a/Tests/RunCMake/PositionIndependentCode/CMakeLists.txt
+++ b/Tests/RunCMake/PositionIndependentCode/CMakeLists.txt
@@ -1,5 +1,5 @@
 
-cmake_minimum_required(VERSION 2.8.4)
+cmake_minimum_required(VERSION 3.3)
 project(${RunCMake_TEST} CXX)
 
 # MSVC creates extra targets which pollute the stderr unless we set this.
diff --git a/Tests/RunCMake/PrecompileHeaders/PchWarnInvalid-check.cmake b/Tests/RunCMake/PrecompileHeaders/PchWarnInvalid-check.cmake
new file mode 100644
index 0000000..3e7fb30
--- /dev/null
+++ b/Tests/RunCMake/PrecompileHeaders/PchWarnInvalid-check.cmake
@@ -0,0 +1,22 @@
+if (NOT CMAKE_C_COMPILER_ID MATCHES "GNU|Intel" OR
+   (CMAKE_C_COMPILER_ID STREQUAL "Intel" AND CMAKE_HOST_WIN32))
+  return()
+endif()
+
+file(STRINGS ${RunCMake_TEST_BINARY_DIR}/compile_commands.json empty_dir_commands
+     REGEX "command.*-Winvalid-pch.*empty.dir/cmake_pch.h")
+file(STRINGS ${RunCMake_TEST_BINARY_DIR}/compile_commands.json foo_dir_commands
+     REGEX "command.*-Winvalid-pch.*foo.dir/cmake_pch.h")
+
+list(LENGTH empty_dir_commands empty_dir_commands_size)
+list(LENGTH foo_dir_commands foo_dir_commands_size)
+
+if (empty_dir_commands_size EQUAL 0)
+  set(RunCMake_TEST_FAILED "empty target should have -Winvalid-pch compile option present")
+  return()
+endif()
+
+if (foo_dir_commands_size GREATER 0)
+  set(RunCMake_TEST_FAILED "foo target should not have -Winvalid-pch compile option present")
+  return()
+endif()
diff --git a/Tests/RunCMake/PrecompileHeaders/PchWarnInvalid.cmake b/Tests/RunCMake/PrecompileHeaders/PchWarnInvalid.cmake
new file mode 100644
index 0000000..4525664
--- /dev/null
+++ b/Tests/RunCMake/PrecompileHeaders/PchWarnInvalid.cmake
@@ -0,0 +1,16 @@
+enable_language(C)
+
+set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
+
+add_library(empty empty.c)
+target_precompile_headers(empty PUBLIC
+  <stdio.h>
+  <string.h>
+)
+
+add_library(foo foo.c)
+target_precompile_headers(foo PUBLIC
+  <stdio.h>
+  <string.h>
+)
+set_target_properties(foo PROPERTIES PCH_WARN_INVALID OFF)
diff --git a/Tests/RunCMake/PrecompileHeaders/RunCMakeTest.cmake b/Tests/RunCMake/PrecompileHeaders/RunCMakeTest.cmake
index f587c7d..381b800 100644
--- a/Tests/RunCMake/PrecompileHeaders/RunCMakeTest.cmake
+++ b/Tests/RunCMake/PrecompileHeaders/RunCMakeTest.cmake
@@ -4,12 +4,9 @@
 function(run_test name)
   set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/${name}-build)
   run_cmake(${name})
-  # Precompiled headers are not supported with multiple architectures.
-  if(NOT "$ENV{CMAKE_OSX_ARCHITECTURES}" MATCHES "[;$]")
-    set(RunCMake_TEST_NO_CLEAN 1)
-    run_cmake_command(${name}-build ${CMAKE_COMMAND} --build . --config Debug)
-    run_cmake_command(${name}-test ${CMAKE_CTEST_COMMAND} -C Debug)
-  endif()
+  set(RunCMake_TEST_NO_CLEAN 1)
+  run_cmake_command(${name}-build ${CMAKE_COMMAND} --build . --config Debug)
+  run_cmake_command(${name}-test ${CMAKE_CTEST_COMMAND} -C Debug)
 endfunction()
 
 run_cmake(DisabledPch)
@@ -21,3 +18,6 @@
 run_test(PchReuseFromPrefixed)
 run_test(PchReuseFromSubdir)
 run_cmake(PchMultilanguage)
+if(RunCMake_GENERATOR MATCHES "Make|Ninja")
+  run_cmake(PchWarnInvalid)
+endif()
diff --git a/Tests/RunCMake/PrecompileHeaders/empty.c b/Tests/RunCMake/PrecompileHeaders/empty.c
index 30ae1c4..2a51ebc 100644
--- a/Tests/RunCMake/PrecompileHeaders/empty.c
+++ b/Tests/RunCMake/PrecompileHeaders/empty.c
@@ -1,3 +1,3 @@
-void nothing()
+void nothing(void)
 {
 }
diff --git a/Tests/RunCMake/RunCMake.cmake b/Tests/RunCMake/RunCMake.cmake
index cb20fb1..c13c694 100644
--- a/Tests/RunCMake/RunCMake.cmake
+++ b/Tests/RunCMake/RunCMake.cmake
@@ -154,6 +154,7 @@
 
     "|[^\n]*xcodebuild[^\n]*warning: file type[^\n]*is based on missing file type"
     "|[^\n]*is a member of multiple groups"
+    "|[^\n]*offset in archive not a multiple of 8"
     "|[^\n]*from Time Machine by path"
     "|[^\n]*Bullseye Testing Technology"
     ")[^\n]*\n)+"
diff --git a/Tests/RunCMake/SourceProperties/CMakeLists.txt b/Tests/RunCMake/SourceProperties/CMakeLists.txt
index a17c8cd..e93f0b6 100644
--- a/Tests/RunCMake/SourceProperties/CMakeLists.txt
+++ b/Tests/RunCMake/SourceProperties/CMakeLists.txt
@@ -1,3 +1,3 @@
-cmake_minimum_required(VERSION 2.8.4)
+cmake_minimum_required(VERSION 3.3)
 project(${RunCMake_TEST} C)
 include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/SymlinkTrees/CMakeLists.txt b/Tests/RunCMake/SymlinkTrees/CMakeLists.txt
new file mode 100644
index 0000000..d6fea2c
--- /dev/null
+++ b/Tests/RunCMake/SymlinkTrees/CMakeLists.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 2.8.12)
+project(${RunCMake_TEST} NONE)
+include("${include_dir}/${RunCMake_TEST}.cmake")
diff --git a/Tests/RunCMake/SymlinkTrees/PrintTrees.cmake b/Tests/RunCMake/SymlinkTrees/PrintTrees.cmake
new file mode 100644
index 0000000..aa99127
--- /dev/null
+++ b/Tests/RunCMake/SymlinkTrees/PrintTrees.cmake
@@ -0,0 +1,6 @@
+message(STATUS "source: '${CMAKE_SOURCE_DIR}'")
+message(STATUS "binary: '${CMAKE_BINARY_DIR}'")
+get_filename_component(real_source "${CMAKE_SOURCE_DIR}" REALPATH)
+get_filename_component(real_binary "${CMAKE_BINARY_DIR}" REALPATH)
+message(STATUS "real source: '${real_source}'")
+message(STATUS "real binary: '${real_binary}'")
diff --git a/Tests/RunCMake/SymlinkTrees/RunCMakeTest.cmake b/Tests/RunCMake/SymlinkTrees/RunCMakeTest.cmake
new file mode 100644
index 0000000..e5f1f7f
--- /dev/null
+++ b/Tests/RunCMake/SymlinkTrees/RunCMakeTest.cmake
@@ -0,0 +1,34 @@
+include(RunCMake)
+
+# This function assumes that ``${RunCMake_BINARY_DIR}/${name}/source`` and
+# ``${RunCMake_BINARY_DIR}/${name}/binary`` are set up properly prior to
+# calling it.
+function (run_symlink_test name)
+  set(RunCMake_TEST_NO_CLEAN TRUE)
+  configure_file(
+    "${CMAKE_CURRENT_LIST_DIR}/CMakeLists.txt"
+    "${RunCMake_BINARY_DIR}/${name}/source/CMakeLists.txt"
+    COPYONLY)
+  set(RunCMake_TEST_SOURCE_DIR "${RunCMake_BINARY_DIR}/${name}/source")
+  set(RunCMake_TEST_BINARY_DIR "${RunCMake_BINARY_DIR}/${name}/binary")
+  # Emulate a shell using this directory.
+  set(ENV{PWD} "${RunCMake_TEST_BINARY_DIR}")
+  set(RunCMake_TEST_OPTIONS
+    "-Dinclude_dir:PATH=${CMAKE_CURRENT_LIST_DIR}")
+  run_cmake("${name}_symlinks")
+endfunction ()
+
+# Create the following structure:
+#
+#   .../common_real/source
+#   .../common_real/binary
+#   .../common -> common_real
+#
+# In this case, CMake should act as if .../common *is* .../common_real for all
+# computations except ``REALPATH``.  This supports the case where a system has
+# a stable *symlink*, but not a stable target for that symlink.
+file(REMOVE_RECURSE "${RunCMake_BINARY_DIR}/common_real")
+file(REMOVE "${RunCMake_BINARY_DIR}/common")
+file(MAKE_DIRECTORY "${RunCMake_BINARY_DIR}/common_real/source")
+file(CREATE_LINK "common_real" "${RunCMake_BINARY_DIR}/common" SYMBOLIC)
+run_symlink_test(common)
diff --git a/Tests/RunCMake/SymlinkTrees/common_symlinks-stdout.txt b/Tests/RunCMake/SymlinkTrees/common_symlinks-stdout.txt
new file mode 100644
index 0000000..bb04450
--- /dev/null
+++ b/Tests/RunCMake/SymlinkTrees/common_symlinks-stdout.txt
@@ -0,0 +1,4 @@
+-- source: '[^']*/Tests/RunCMake/SymlinkTrees/common/source'
+-- binary: '[^']*/Tests/RunCMake/SymlinkTrees/common/binary'
+-- real source: '[^']*/Tests/RunCMake/SymlinkTrees/common_real/source'
+-- real binary: '[^']*/Tests/RunCMake/SymlinkTrees/common_real/binary'
diff --git a/Tests/RunCMake/SymlinkTrees/common_symlinks.cmake b/Tests/RunCMake/SymlinkTrees/common_symlinks.cmake
new file mode 100644
index 0000000..5eafe26
--- /dev/null
+++ b/Tests/RunCMake/SymlinkTrees/common_symlinks.cmake
@@ -0,0 +1 @@
+include("${CMAKE_CURRENT_LIST_DIR}/PrintTrees.cmake")
diff --git a/Tests/RunCMake/Syntax/CommandEOF-stderr.txt b/Tests/RunCMake/Syntax/CommandEOF-stderr.txt
index 31cbc08..b9f8fd1 100644
--- a/Tests/RunCMake/Syntax/CommandEOF-stderr.txt
+++ b/Tests/RunCMake/Syntax/CommandEOF-stderr.txt
@@ -1,4 +1,4 @@
-^CMake Error in CommandEOF.cmake:
+^CMake Error at CommandEOF.cmake:1:
   Unexpected end of file.
 
   Parse error.  Function missing opening "\(".
diff --git a/Tests/RunCMake/TargetObjects/CMakeLists.txt b/Tests/RunCMake/TargetObjects/CMakeLists.txt
index be9d403..44b5d30 100644
--- a/Tests/RunCMake/TargetObjects/CMakeLists.txt
+++ b/Tests/RunCMake/TargetObjects/CMakeLists.txt
@@ -1,3 +1,3 @@
-cmake_minimum_required(VERSION 2.8.4)
+cmake_minimum_required(VERSION 3.3)
 project(${RunCMake_TEST})
 include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/TargetPolicies/CMakeLists.txt b/Tests/RunCMake/TargetPolicies/CMakeLists.txt
index 12cd3c7..74b3ff8 100644
--- a/Tests/RunCMake/TargetPolicies/CMakeLists.txt
+++ b/Tests/RunCMake/TargetPolicies/CMakeLists.txt
@@ -1,3 +1,3 @@
-cmake_minimum_required(VERSION 2.8.4)
+cmake_minimum_required(VERSION 3.3)
 project(${RunCMake_TEST} NONE)
 include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/TargetPolicies/PolicyList-stderr.txt b/Tests/RunCMake/TargetPolicies/PolicyList-stderr.txt
index 9a1e027..2454f25 100644
--- a/Tests/RunCMake/TargetPolicies/PolicyList-stderr.txt
+++ b/Tests/RunCMake/TargetPolicies/PolicyList-stderr.txt
@@ -29,6 +29,9 @@
    \* CMP0083
    \* CMP0095
    \* CMP0099
+   \* CMP0104
+   \* CMP0105
+   \* CMP0108
 
 Call Stack \(most recent call first\):
   CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/TargetProperties/CMakeLists.txt b/Tests/RunCMake/TargetProperties/CMakeLists.txt
index be9d403..44b5d30 100644
--- a/Tests/RunCMake/TargetProperties/CMakeLists.txt
+++ b/Tests/RunCMake/TargetProperties/CMakeLists.txt
@@ -1,3 +1,3 @@
-cmake_minimum_required(VERSION 2.8.4)
+cmake_minimum_required(VERSION 3.3)
 project(${RunCMake_TEST})
 include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/TargetPropertyGeneratorExpressions/CMakeLists.txt b/Tests/RunCMake/TargetPropertyGeneratorExpressions/CMakeLists.txt
index 90afc12..c3922d6 100644
--- a/Tests/RunCMake/TargetPropertyGeneratorExpressions/CMakeLists.txt
+++ b/Tests/RunCMake/TargetPropertyGeneratorExpressions/CMakeLists.txt
@@ -1,5 +1,5 @@
 
-cmake_minimum_required(VERSION 2.8.4)
+cmake_minimum_required(VERSION 3.3)
 project(${RunCMake_TEST} CXX)
 
 # MSVC creates extra targets which pollute the stderr unless we set this.
diff --git a/Tests/RunCMake/TargetSources/CMakeLists.txt b/Tests/RunCMake/TargetSources/CMakeLists.txt
index f452db1..a06591c 100644
--- a/Tests/RunCMake/TargetSources/CMakeLists.txt
+++ b/Tests/RunCMake/TargetSources/CMakeLists.txt
@@ -1,3 +1,3 @@
-cmake_minimum_required(VERSION 2.8.4)
+cmake_minimum_required(VERSION 2.8.12)
 project(${RunCMake_TEST} CXX)
 include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/UnityBuild/RunCMakeTest.cmake b/Tests/RunCMake/UnityBuild/RunCMakeTest.cmake
index 24daa64..9ba3c85 100644
--- a/Tests/RunCMake/UnityBuild/RunCMakeTest.cmake
+++ b/Tests/RunCMake/UnityBuild/RunCMakeTest.cmake
@@ -1,14 +1,20 @@
 include(RunCMake)
 
 run_cmake(unitybuild_c)
+run_cmake(unitybuild_c_batch)
+run_cmake(unitybuild_c_group)
 run_cmake(unitybuild_cxx)
+run_cmake(unitybuild_cxx_group)
 run_cmake(unitybuild_c_and_cxx)
+run_cmake(unitybuild_c_and_cxx_group)
 run_cmake(unitybuild_batchsize)
 run_cmake(unitybuild_default_batchsize)
 run_cmake(unitybuild_skip)
 run_cmake(unitybuild_code_before_and_after_include)
 run_cmake(unitybuild_c_no_unity_build)
+run_cmake(unitybuild_c_no_unity_build_group)
 run_cmake(unitybuild_order)
+run_cmake(unitybuild_invalid_mode)
 
 function(run_test name)
   set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/${name}-build)
diff --git a/Tests/RunCMake/UnityBuild/f.c b/Tests/RunCMake/UnityBuild/f.c
new file mode 100644
index 0000000..d5813c6
--- /dev/null
+++ b/Tests/RunCMake/UnityBuild/f.c
@@ -0,0 +1,5 @@
+int f(int x)
+{
+  (void)x;
+  return 0;
+}
diff --git a/Tests/RunCMake/UnityBuild/unitybuild_c_and_cxx_group-check.cmake b/Tests/RunCMake/UnityBuild/unitybuild_c_and_cxx_group-check.cmake
new file mode 100644
index 0000000..b027682
--- /dev/null
+++ b/Tests/RunCMake/UnityBuild/unitybuild_c_and_cxx_group-check.cmake
@@ -0,0 +1,42 @@
+set(unitybuild_a_c "${RunCMake_TEST_BINARY_DIR}/CMakeFiles/tgt.dir/Unity/unity_a_c.c")
+if(NOT EXISTS "${unitybuild_a_c}")
+  set(RunCMake_TEST_FAILED "Generated unity source files ${unitybuild_a_c} does not exist.")
+  return()
+else()
+  #verify that the 4 c file is part of this grouping and therefore UNITY_BUILD_BATCH_SIZE
+  #was ignored
+  file(STRINGS ${unitybuild_a_c} unitybuild_a_c_strings)
+  string(REGEX MATCH ".*#include.*s1.c.*#include.*s2.c.*#include.*s3.c.*#include.*s4.c.*" matched_code ${unitybuild_a_c_strings})
+  if(NOT matched_code)
+    set(RunCMake_TEST_FAILED "Generated unity file doesn't include expected source files")
+    return()
+  endif()
+endif()
+
+set(unitybuild_b_c "${RunCMake_TEST_BINARY_DIR}/CMakeFiles/tgt.dir/Unity/unity_b_c.c")
+if(NOT EXISTS "${unitybuild_b_c}")
+  set(RunCMake_TEST_FAILED "Generated unity source files ${unitybuild_b_c} does not exist.")
+  return()
+endif()
+
+
+set(unitybuild_a_cxx "${RunCMake_TEST_BINARY_DIR}/CMakeFiles/tgt.dir/Unity/unity_a_cxx.cxx")
+if(NOT EXISTS "${unitybuild_a_cxx}")
+  set(RunCMake_TEST_FAILED "Generated unity source files ${unitybuild_a_cxx} does not exist.")
+  return()
+else()
+  #verify that the 4 cxx file are part of this grouping and therefore UNITY_BUILD_BATCH_SIZE
+  #was ignored
+  file(STRINGS ${unitybuild_a_cxx} unitybuild_a_cxx_strings)
+  string(REGEX MATCH ".*#include.*s1.cxx.*#include.*s2.cxx.*#include.*s3.cxx.*#include.*s4.cxx.*" matched_code ${unitybuild_a_cxx_strings})
+  if(NOT matched_code)
+    set(RunCMake_TEST_FAILED "Generated unity file doesn't include expected source files")
+    return()
+  endif()
+endif()
+
+set(unitybuild_b_cxx "${RunCMake_TEST_BINARY_DIR}/CMakeFiles/tgt.dir/Unity/unity_b_cxx.cxx")
+if(NOT EXISTS "${unitybuild_b_cxx}")
+  set(RunCMake_TEST_FAILED "Generated unity source files ${unitybuild_b_cxx} does not exist.")
+  return()
+endif()
diff --git a/Tests/RunCMake/UnityBuild/unitybuild_c_and_cxx_group.cmake b/Tests/RunCMake/UnityBuild/unitybuild_c_and_cxx_group.cmake
new file mode 100644
index 0000000..7bf3f4b
--- /dev/null
+++ b/Tests/RunCMake/UnityBuild/unitybuild_c_and_cxx_group.cmake
@@ -0,0 +1,39 @@
+project(unitybuild_c_and_cxx C CXX)
+
+set(srcs f.c)
+foreach(s RANGE 1 8)
+  set(src_c "${CMAKE_CURRENT_BINARY_DIR}/s${s}.c")
+  file(WRITE "${src_c}" "
+int f(int);\n
+int s${s}(void) { return f(${s}); }\n"
+  )
+
+  set(src_cxx "${CMAKE_CURRENT_BINARY_DIR}/s${s}.cxx")
+  file(WRITE "${src_cxx}" "
+extern \"C\" { \n
+  int f(int); \n
+}\n
+  int s${s}(void) { return f(${s}); }\n"
+  )
+
+  list(APPEND srcs "${src_c}")
+  list(APPEND srcs "${src_cxx}")
+endforeach()
+
+
+
+add_library(tgt SHARED ${srcs})
+
+set_target_properties(tgt PROPERTIES UNITY_BUILD ON
+                          UNITY_BUILD_MODE GROUP
+                          #UNITY_BUILD_BATCH_SIZE will be ignored
+                          UNITY_BUILD_BATCH_SIZE 2)
+
+set_source_files_properties(s1.c s2.c s3.c s4.c
+                            s1.cxx s2.cxx s3.cxx s4.cxx
+                            PROPERTIES UNITY_GROUP "a"
+                            )
+set_source_files_properties(s5.c s6.c s7.c s8.c
+                            s5.cxx s6.cxx s7.cxx s8.cxx
+                            PROPERTIES UNITY_GROUP "b"
+                            )
diff --git a/Tests/RunCMake/UnityBuild/unitybuild_c_batch-check.cmake b/Tests/RunCMake/UnityBuild/unitybuild_c_batch-check.cmake
new file mode 100644
index 0000000..024286d
--- /dev/null
+++ b/Tests/RunCMake/UnityBuild/unitybuild_c_batch-check.cmake
@@ -0,0 +1,5 @@
+set(unitybuild_c "${RunCMake_TEST_BINARY_DIR}/CMakeFiles/tgt.dir/Unity/unity_0_c.c")
+if(NOT EXISTS "${unitybuild_c}")
+  set(RunCMake_TEST_FAILED "Generated unity source files ${unitybuild_c} does not exist.")
+  return()
+endif()
diff --git a/Tests/RunCMake/UnityBuild/unitybuild_c_batch.cmake b/Tests/RunCMake/UnityBuild/unitybuild_c_batch.cmake
new file mode 100644
index 0000000..33873b6
--- /dev/null
+++ b/Tests/RunCMake/UnityBuild/unitybuild_c_batch.cmake
@@ -0,0 +1,15 @@
+project(unitybuild_c C)
+
+set(srcs "")
+foreach(s RANGE 1 8)
+  set(src "${CMAKE_CURRENT_BINARY_DIR}/s${s}.c")
+  file(WRITE "${src}" "int s${s}(void) { return 0; }\n")
+  list(APPEND srcs "${src}")
+endforeach()
+
+add_library(tgt SHARED ${srcs})
+
+set_target_properties(tgt PROPERTIES
+                          UNITY_BUILD ON
+                          UNITY_BUILD_MODE BATCH
+                          )
diff --git a/Tests/RunCMake/UnityBuild/unitybuild_c_group-check.cmake b/Tests/RunCMake/UnityBuild/unitybuild_c_group-check.cmake
new file mode 100644
index 0000000..0b9ea15
--- /dev/null
+++ b/Tests/RunCMake/UnityBuild/unitybuild_c_group-check.cmake
@@ -0,0 +1,11 @@
+set(unitybuild_a_c "${RunCMake_TEST_BINARY_DIR}/CMakeFiles/tgt.dir/Unity/unity_a_c.c")
+if(NOT EXISTS "${unitybuild_a_c}")
+  set(RunCMake_TEST_FAILED "Generated unity source files ${unitybuild_a_c} does not exist.")
+  return()
+endif()
+
+set(unitybuild_b_c "${RunCMake_TEST_BINARY_DIR}/CMakeFiles/tgt.dir/Unity/unity_b_c.c")
+if(NOT EXISTS "${unitybuild_b_c}")
+  set(RunCMake_TEST_FAILED "Generated unity source files ${unitybuild_b_c} does not exist.")
+  return()
+endif()
diff --git a/Tests/RunCMake/UnityBuild/unitybuild_c_group.cmake b/Tests/RunCMake/UnityBuild/unitybuild_c_group.cmake
new file mode 100644
index 0000000..1fa17f3
--- /dev/null
+++ b/Tests/RunCMake/UnityBuild/unitybuild_c_group.cmake
@@ -0,0 +1,17 @@
+project(unitybuild_c C)
+
+set(srcs "")
+foreach(s RANGE 1 8)
+  set(src "${CMAKE_CURRENT_BINARY_DIR}/s${s}.c")
+  file(WRITE "${src}" "int s${s}(void) { return 0; }\n")
+  list(APPEND srcs "${src}")
+endforeach()
+
+add_library(tgt SHARED ${srcs})
+
+set_target_properties(tgt PROPERTIES UNITY_BUILD ON
+                                     UNITY_BUILD_MODE GROUP)
+
+set_source_files_properties(s1.c PROPERTIES UNITY_GROUP "a")
+set_source_files_properties(s2.c PROPERTIES UNITY_GROUP "a")
+set_source_files_properties(s3.c s4.c PROPERTIES UNITY_GROUP "b")
diff --git a/Tests/RunCMake/UnityBuild/unitybuild_c_no_unity_build_group-check.cmake b/Tests/RunCMake/UnityBuild/unitybuild_c_no_unity_build_group-check.cmake
new file mode 100644
index 0000000..e344627
--- /dev/null
+++ b/Tests/RunCMake/UnityBuild/unitybuild_c_no_unity_build_group-check.cmake
@@ -0,0 +1,5 @@
+set(unitybuild_c "${RunCMake_TEST_BINARY_DIR}/CMakeFiles/tgt.dir/Unity/unity_a_c.c")
+if(EXISTS "${unitybuild_c}")
+  set(RunCMake_TEST_FAILED "Generated unity source files ${unitybuild_c} should not exist.")
+  return()
+endif()
diff --git a/Tests/RunCMake/UnityBuild/unitybuild_c_no_unity_build_group.cmake b/Tests/RunCMake/UnityBuild/unitybuild_c_no_unity_build_group.cmake
new file mode 100644
index 0000000..7b26dc1
--- /dev/null
+++ b/Tests/RunCMake/UnityBuild/unitybuild_c_no_unity_build_group.cmake
@@ -0,0 +1,16 @@
+project(unitybuild_c_no_unity_build C)
+
+set(srcs "")
+foreach(s RANGE 1 8)
+  set(src "${CMAKE_CURRENT_BINARY_DIR}/s${s}.c")
+  file(WRITE "${src}" "int s${s}(void) { return 0; }\n")
+  list(APPEND srcs "${src}")
+endforeach()
+
+add_library(tgt SHARED ${srcs})
+
+#These should be ignored as UNITY_BUILD is off
+set_target_properties(tgt PROPERTIES UNITY_BUILD_MODE GROUP)
+set_source_files_properties(s1.c s2.c s3.c s4.c s5.c s6.c s7.c s8.c
+                            PROPERTIES UNITY_GROUP "a"
+                            )
diff --git a/Tests/RunCMake/UnityBuild/unitybuild_cxx_group-check.cmake b/Tests/RunCMake/UnityBuild/unitybuild_cxx_group-check.cmake
new file mode 100644
index 0000000..ecef3a3
--- /dev/null
+++ b/Tests/RunCMake/UnityBuild/unitybuild_cxx_group-check.cmake
@@ -0,0 +1,27 @@
+set(unitybuild_a_cxx "${RunCMake_TEST_BINARY_DIR}/CMakeFiles/tgt.dir/Unity/unity_a_cxx.cxx")
+if(NOT EXISTS "${unitybuild_a_cxx}")
+  set(RunCMake_TEST_FAILED "Generated unity source files ${unitybuild_a_cxx} does not exist.")
+  return()
+else()
+  #verify that odr2 is not part of this source set
+  file(STRINGS ${unitybuild_a_cxx} unitybuild_a_cxx_strings)
+  string(REGEX MATCH ".*#include.*odr2.cxx" matched_code ${unitybuild_a_cxx_strings})
+  if(matched_code)
+    set(RunCMake_TEST_FAILED "Generated unity file includes un-expected ord2.cxx source file")
+    return()
+  endif()
+endif()
+
+set(unitybuild_b_cxx "${RunCMake_TEST_BINARY_DIR}/CMakeFiles/tgt.dir/Unity/unity_b_cxx.cxx")
+if(NOT EXISTS "${unitybuild_b_cxx}")
+  set(RunCMake_TEST_FAILED "Generated unity source files ${unitybuild_b_cxx} does not exist.")
+  return()
+else()
+  #verify that odr1 is not part of this source set
+  file(STRINGS ${unitybuild_b_cxx} unitybuild_b_cxx_strings)
+  string(REGEX MATCH ".*#include.*odr1.cxx" matched_code ${unitybuild_b_cxx_strings})
+  if(matched_code)
+    set(RunCMake_TEST_FAILED "Generated unity file includes un-expected ord1.cxx source file")
+    return()
+  endif()
+endif()
diff --git a/Tests/RunCMake/UnityBuild/unitybuild_cxx_group.cmake b/Tests/RunCMake/UnityBuild/unitybuild_cxx_group.cmake
new file mode 100644
index 0000000..9804289
--- /dev/null
+++ b/Tests/RunCMake/UnityBuild/unitybuild_cxx_group.cmake
@@ -0,0 +1,27 @@
+project(unitybuild_cxx CXX)
+
+set(srcs "")
+foreach(s RANGE 1 4)
+  set(src "${CMAKE_CURRENT_BINARY_DIR}/s${s}.cxx")
+  file(WRITE "${src}" "int s${s}(void) { return 0; }\n")
+  list(APPEND srcs "${src}")
+endforeach()
+
+foreach(s RANGE 1 2)
+  set(src "${CMAKE_CURRENT_BINARY_DIR}/odr${s}.cxx")
+  file(WRITE "${src}" "namespace odr { int s${s}(void) { return 0; } }\n")
+  list(APPEND srcs "${src}")
+endforeach()
+
+add_library(tgt SHARED ${srcs})
+
+set_target_properties(tgt PROPERTIES UNITY_BUILD ON
+                          UNITY_BUILD_MODE GROUP
+                          )
+
+set_source_files_properties(s1.cxx s2.cxx odr1.cxx
+                            PROPERTIES UNITY_GROUP "a"
+                            )
+set_source_files_properties(s3.cxx s4.cxx odr2.cxx
+                            PROPERTIES UNITY_GROUP "b"
+                            )
diff --git a/Tests/RunCMake/Languages/LINK_LANGUAGE-genex-result.txt b/Tests/RunCMake/UnityBuild/unitybuild_invalid_mode-result.txt
similarity index 100%
copy from Tests/RunCMake/Languages/LINK_LANGUAGE-genex-result.txt
copy to Tests/RunCMake/UnityBuild/unitybuild_invalid_mode-result.txt
diff --git a/Tests/RunCMake/UnityBuild/unitybuild_invalid_mode-stderr.txt b/Tests/RunCMake/UnityBuild/unitybuild_invalid_mode-stderr.txt
new file mode 100644
index 0000000..b1b17a0
--- /dev/null
+++ b/Tests/RunCMake/UnityBuild/unitybuild_invalid_mode-stderr.txt
@@ -0,0 +1,5 @@
+^CMake Error in CMakeLists.txt:
+  Invalid UNITY_BUILD_MODE value of INVALID assigned to target tgt\.
+  Acceptable values are BATCH and GROUP\.
+.*
+CMake Generate step failed\.  Build files cannot be regenerated correctly\.$
diff --git a/Tests/RunCMake/UnityBuild/unitybuild_invalid_mode.cmake b/Tests/RunCMake/UnityBuild/unitybuild_invalid_mode.cmake
new file mode 100644
index 0000000..0212200
--- /dev/null
+++ b/Tests/RunCMake/UnityBuild/unitybuild_invalid_mode.cmake
@@ -0,0 +1,12 @@
+project(unitybuild_c C)
+
+set(srcs "")
+foreach(s RANGE 1 8)
+  set(src "${CMAKE_CURRENT_BINARY_DIR}/s${s}.c")
+  file(WRITE "${src}" "int s${s}(void) { return 0; }\n")
+  list(APPEND srcs "${src}")
+endforeach()
+
+add_library(tgt SHARED ${srcs})
+
+set_target_properties(tgt PROPERTIES UNITY_BUILD ON UNITY_BUILD_MODE INVALID)
diff --git a/Tests/RunCMake/UnityBuild/unitybuild_order-check.cmake b/Tests/RunCMake/UnityBuild/unitybuild_order-check.cmake
index f26ec2e..85e6587 100644
--- a/Tests/RunCMake/UnityBuild/unitybuild_order-check.cmake
+++ b/Tests/RunCMake/UnityBuild/unitybuild_order-check.cmake
@@ -2,6 +2,6 @@
 file(STRINGS ${unitybuild_c} unitybuild_c_strings)
 string(REGEX MATCH ".*#include.*s3.c.*#include.*s1.c.*#include.*s2.c.*" matched_code ${unitybuild_c_strings})
 if(NOT matched_code)
-  set(RunCMake_TEST_FAILED "Generated unity file doesn't include expected oder of source files")
+  set(RunCMake_TEST_FAILED "Generated unity file doesn't include expected order of source files")
   return()
 endif()
diff --git a/Tests/RunCMake/VS10Project/CSharpSourceGroup/foo.cs b/Tests/RunCMake/VS10Project/CSharpSourceGroup/foo.cs
new file mode 100644
index 0000000..3695dc9
--- /dev/null
+++ b/Tests/RunCMake/VS10Project/CSharpSourceGroup/foo.cs
@@ -0,0 +1,3 @@
+void foo()
+{
+}
diff --git a/Tests/RunCMake/VS10Project/CSharpSourceGroup/images/empty.bmp b/Tests/RunCMake/VS10Project/CSharpSourceGroup/images/empty.bmp
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/Tests/RunCMake/VS10Project/CSharpSourceGroup/images/empty.bmp
diff --git a/Tests/RunCMake/VS10Project/CSharpSourceGroup/nested/baz.cs b/Tests/RunCMake/VS10Project/CSharpSourceGroup/nested/baz.cs
new file mode 100644
index 0000000..d5d334a
--- /dev/null
+++ b/Tests/RunCMake/VS10Project/CSharpSourceGroup/nested/baz.cs
@@ -0,0 +1,3 @@
+void baz()
+{
+}
diff --git a/Tests/RunCMake/VS10Project/InterfaceLibSources-check.cmake b/Tests/RunCMake/VS10Project/InterfaceLibSources-check.cmake
new file mode 100644
index 0000000..bcdc101
--- /dev/null
+++ b/Tests/RunCMake/VS10Project/InterfaceLibSources-check.cmake
@@ -0,0 +1,25 @@
+set(vcProjectFile "${RunCMake_TEST_BINARY_DIR}/iface.vcxproj")
+if(NOT EXISTS "${vcProjectFile}")
+  set(RunCMake_TEST_FAILED "Project file ${vcProjectFile} does not exist.")
+  return()
+endif()
+
+set(found_iface_h 0)
+file(STRINGS "${vcProjectFile}" lines)
+foreach(line IN LISTS lines)
+  if(line MATCHES "<([A-Za-z0-9_]+) +Include=.*iface\\.h")
+    set(rule "${CMAKE_MATCH_1}")
+    if(NOT rule STREQUAL "None")
+      set(RunCMake_TEST_FAILED "iface.h referenced as ${rule} instead of None in\n  ${vcProjectFile}")
+      return()
+    endif()
+    if(found_iface_h)
+      set(RunCMake_TEST_FAILED "iface.h referenced multiple times in\n  ${vcProjectFile}")
+      return()
+    endif()
+    set(found_iface_h 1)
+  endif()
+endforeach()
+if(NOT found_iface_h)
+  set(RunCMake_TEST_FAILED "iface.h not referenced in\n  ${vcProjectFile}")
+endif()
diff --git a/Tests/RunCMake/VS10Project/InterfaceLibSources.cmake b/Tests/RunCMake/VS10Project/InterfaceLibSources.cmake
new file mode 100644
index 0000000..3672be1
--- /dev/null
+++ b/Tests/RunCMake/VS10Project/InterfaceLibSources.cmake
@@ -0,0 +1 @@
+add_library(iface INTERFACE iface.h)
diff --git a/Tests/RunCMake/VS10Project/RunCMakeTest.cmake b/Tests/RunCMake/VS10Project/RunCMakeTest.cmake
index 8a04f78..e9f251a 100644
--- a/Tests/RunCMake/VS10Project/RunCMakeTest.cmake
+++ b/Tests/RunCMake/VS10Project/RunCMakeTest.cmake
@@ -3,12 +3,13 @@
 include(RunCMake)
 cmake_policy(SET CMP0054 NEW)
 
+run_cmake(VsCsharpSourceGroup)
 run_cmake(VsCSharpCompilerOpts)
 run_cmake(ExplicitCMakeLists)
+run_cmake(InterfaceLibSources)
 run_cmake(RuntimeLibrary)
 run_cmake(SourceGroupCMakeLists)
 run_cmake(SourceGroupTreeCMakeLists)
-
 run_cmake(VsConfigurationType)
 run_cmake(VsTargetsFileReferences)
 run_cmake(VsCustomProps)
@@ -30,6 +31,10 @@
 run_cmake(VsDpiAwareBadParam)
 run_cmake(VsPrecompileHeaders)
 run_cmake(VsPrecompileHeadersReuseFromCompilePDBName)
+run_cmake(VsDeployEnabled)
+run_cmake(VsSettings)
+run_cmake(VsSourceSettingsTool)
+run_cmake(VsPlatformToolset)
 
 run_cmake(VsWinRTByDefault)
 
@@ -52,6 +57,7 @@
   run_cmake(UnityBuildPre2017)
 else()
   run_cmake(UnityBuildNative)
+  run_cmake(UnityBuildNativeGrouped)
 endif()
 
 run_cmake(VsDotnetTargetFramework)
diff --git a/Tests/RunCMake/VS10Project/UnityBuildNativeGrouped-check.cmake b/Tests/RunCMake/VS10Project/UnityBuildNativeGrouped-check.cmake
new file mode 100644
index 0000000..d6380da
--- /dev/null
+++ b/Tests/RunCMake/VS10Project/UnityBuildNativeGrouped-check.cmake
@@ -0,0 +1,56 @@
+set(unitybuild_c0 "${RunCMake_TEST_BINARY_DIR}/CMakeFiles/tgt.dir/Unity/unity_poolA_c.c")
+if(NOT EXISTS "${unitybuild_c0}")
+  set(RunCMake_TEST_FAILED "Generated unity source files ${unitybuild_c0} does not exist.")
+  return()
+endif()
+
+set(unitybuild_c1 "${RunCMake_TEST_BINARY_DIR}/CMakeFiles/tgt.dir/Unity/unity_poolB_c.c")
+if(NOT EXISTS "${unitybuild_c1}")
+  set(RunCMake_TEST_FAILED "Generated unity source files ${unitybuild_c1} does not exist.")
+  return()
+endif()
+
+set(tgt_project "${RunCMake_TEST_BINARY_DIR}/tgt.vcxproj")
+if (NOT EXISTS "${tgt_project}")
+  set(RunCMake_TEST_FAILED "Generated project file ${tgt_project} doesn't exist.")
+  return()
+endif()
+
+file(STRINGS ${tgt_project} tgt_projects_strings)
+
+foreach(line IN LISTS tgt_projects_strings)
+  if (line MATCHES "<EnableUnitySupport>true</EnableUnitySupport>")
+    set(have_unity_support ON)
+  endif()
+
+  if (line MATCHES "<ClCompile Include=.*IncludeInUnityFile=\"false\" CustomUnityFile=\"true\"")
+    list(APPEND unity_source_lines ${line})
+  endif()
+
+  if (line MATCHES "<ClCompile Include=.*IncludeInUnityFile=\"true\" CustomUnityFile=\"true\"")
+    list(APPEND sources_list ${line})
+  endif()
+endforeach()
+
+if (NOT have_unity_support)
+  set(RunCMake_TEST_FAILED "Generated project should include the <EnableUnitySupport> block.")
+  return()
+endif()
+
+string(REPLACE "\\" "/" unity_source_lines "${unity_source_lines}")
+string(FIND "${unity_source_lines}" "CMakeFiles/tgt.dir/Unity/unity_poolA_c.c" unity_source_file_position)
+if (unity_source_file_position EQUAL "-1")
+  set(RunCMake_TEST_FAILED "Generated project should include the generated unity source file 'poolA'.")
+  return()
+endif()
+string(FIND "${unity_source_lines}" "CMakeFiles/tgt.dir/Unity/unity_poolB_c.c" unity_source_file_position)
+if (unity_source_file_position EQUAL "-1")
+  set(RunCMake_TEST_FAILED "Generated project should include the generated unity source file 'poolB'.")
+  return()
+endif()
+
+list(LENGTH sources_list number_of_sources)
+if(NOT number_of_sources EQUAL 7)
+  set(RunCMake_TEST_FAILED "Generated project doesn't include the expect number of files.")
+  return()
+endif()
diff --git a/Tests/RunCMake/VS10Project/UnityBuildNativeGrouped.cmake b/Tests/RunCMake/VS10Project/UnityBuildNativeGrouped.cmake
new file mode 100644
index 0000000..b740e3b
--- /dev/null
+++ b/Tests/RunCMake/VS10Project/UnityBuildNativeGrouped.cmake
@@ -0,0 +1,20 @@
+project(unitybuild_c C)
+
+set(srcs "")
+foreach(s RANGE 1 8)
+  set(src "${CMAKE_CURRENT_BINARY_DIR}/s${s}.c")
+  file(WRITE "${src}" "int s${s}(void) { return 0; }\n")
+  list(APPEND srcs "${src}")
+endforeach()
+
+add_library(tgt SHARED ${srcs})
+
+set_target_properties(tgt PROPERTIES UNITY_BUILD ON UNITY_BUILD_MODE GROUP)
+
+set_source_files_properties(s1.c s2.c s3.c s4.c
+                            PROPERTIES UNITY_GROUP "poolA"
+                            )
+
+set_source_files_properties(s5.c s6.c s7.c
+                            PROPERTIES UNITY_GROUP "poolB"
+                            )
diff --git a/Tests/RunCMake/VS10Project/UnityBuildPre2017Grouped-check.cmake b/Tests/RunCMake/VS10Project/UnityBuildPre2017Grouped-check.cmake
new file mode 100644
index 0000000..d9b8c01
--- /dev/null
+++ b/Tests/RunCMake/VS10Project/UnityBuildPre2017Grouped-check.cmake
@@ -0,0 +1,59 @@
+set(unitybuild_c0 "${RunCMake_TEST_BINARY_DIR}/CMakeFiles/tgt.dir/Unity/unity_poolA.c")
+if(NOT EXISTS "${unitybuild_c0}")
+  set(RunCMake_TEST_FAILED "Generated unity source files ${unitybuild_c0} does not exist.")
+  return()
+endif()
+
+set(unitybuild_c1 "${RunCMake_TEST_BINARY_DIR}/CMakeFiles/tgt.dir/Unity/unity_poolB.c")
+if(NOT EXISTS "${unitybuild_c1}")
+  set(RunCMake_TEST_FAILED "Generated unity source files ${unitybuild_c1} does not exist.")
+  return()
+endif()
+
+set(tgt_project "${RunCMake_TEST_BINARY_DIR}/tgt.vcxproj")
+if (NOT EXISTS "${tgt_project}")
+  set(RunCMake_TEST_FAILED "Generated project file ${tgt_project} doesn't exist.")
+  return()
+endif()
+
+file(STRINGS ${tgt_project} tgt_projects_strings)
+
+foreach(line IN LISTS tgt_projects_strings)
+  if (line MATCHES "<ClCompile Include=.*/>")
+    set(unity_source_line ${line})
+  endif()
+
+  if (line MATCHES "<ClCompile Include=\"[^\"]*\">")
+    string(REGEX MATCH "<ClCompile Include=\"([^\"]*)\">" source_file ${line})
+    list(APPEND sources_list ${source_file})
+  endif()
+
+  if (line MATCHES "<ExcludedFromBuild.*</ExcludedFromBuild>")
+    list(APPEND excluded_sources_list ${source_file})
+  endif()
+endforeach()
+
+string(REPLACE "\\" "/" unity_source_line ${unity_source_line})
+string(FIND "${unity_source_line}" "CMakeFiles/tgt.dir/Unity/unity_poolA.c" unity_source_file_position)
+if (unity_source_file_position EQUAL "-1")
+  set(RunCMake_TEST_FAILED "Generated project should include the generated unity source file.")
+  return()
+endif()
+string(FIND "${unity_source_line}" "CMakeFiles/tgt.dir/Unity/unity_poolB.c" unity_source_file_position)
+if (unity_source_file_position EQUAL "-1")
+  set(RunCMake_TEST_FAILED "Generated project should include the generated unity source file.")
+  return()
+endif()
+
+list(LENGTH sources_list number_of_sources)
+if(NOT number_of_sources EQUAL 7)
+  set(RunCMake_TEST_FAILED "Generated project doesn't include the expect number of files.")
+  return()
+endif()
+
+# Exclusions for Debug|Release|MinSizeRel|RelWithDebInfo
+list(LENGTH excluded_sources_list number_of_excluded_sources)
+if(NOT number_of_excluded_sources EQUAL 28)
+  set(RunCMake_TEST_FAILED "Generated project doesn't exclude the source files for all configurations.")
+  return()
+endif()
diff --git a/Tests/RunCMake/VS10Project/UnityBuildPre2017Grouped.cmake b/Tests/RunCMake/VS10Project/UnityBuildPre2017Grouped.cmake
new file mode 100644
index 0000000..b740e3b
--- /dev/null
+++ b/Tests/RunCMake/VS10Project/UnityBuildPre2017Grouped.cmake
@@ -0,0 +1,20 @@
+project(unitybuild_c C)
+
+set(srcs "")
+foreach(s RANGE 1 8)
+  set(src "${CMAKE_CURRENT_BINARY_DIR}/s${s}.c")
+  file(WRITE "${src}" "int s${s}(void) { return 0; }\n")
+  list(APPEND srcs "${src}")
+endforeach()
+
+add_library(tgt SHARED ${srcs})
+
+set_target_properties(tgt PROPERTIES UNITY_BUILD ON UNITY_BUILD_MODE GROUP)
+
+set_source_files_properties(s1.c s2.c s3.c s4.c
+                            PROPERTIES UNITY_GROUP "poolA"
+                            )
+
+set_source_files_properties(s5.c s6.c s7.c
+                            PROPERTIES UNITY_GROUP "poolB"
+                            )
diff --git a/Tests/RunCMake/VS10Project/VsCsharpSourceGroup-check.cmake b/Tests/RunCMake/VS10Project/VsCsharpSourceGroup-check.cmake
new file mode 100644
index 0000000..3b5c70f
--- /dev/null
+++ b/Tests/RunCMake/VS10Project/VsCsharpSourceGroup-check.cmake
@@ -0,0 +1,22 @@
+set(csProjFile "${RunCMake_TEST_BINARY_DIR}/VsCsharpSourceGroup.csproj")
+if(NOT EXISTS "${csProjFile}")
+  set(RunCMake_TEST_FAILED "Project file ${csProjFile} does not exist.")
+  return()
+endif()
+
+file(STRINGS "${csProjFile}" lines)
+
+include(${RunCMake_TEST_SOURCE_DIR}/VsCsharpSourceGroupHelpers.cmake)
+
+set(SOURCE_GROUPS_TO_FIND
+  "CSharpSourceGroup"
+  "CSharpSourceGroup/nested"
+  "Images"
+)
+
+foreach(GROUP_NAME IN LISTS ${SOURCE_GROUPS_TO_FIND})
+  find_source_group("${lines}" ${GROUP_NAME})
+  if(NOT ${SOURCE_GROUP_FOUND})
+    return()
+  endif()
+endforeach()
diff --git a/Tests/RunCMake/VS10Project/VsCsharpSourceGroup.cmake b/Tests/RunCMake/VS10Project/VsCsharpSourceGroup.cmake
new file mode 100644
index 0000000..024993c
--- /dev/null
+++ b/Tests/RunCMake/VS10Project/VsCsharpSourceGroup.cmake
@@ -0,0 +1,16 @@
+enable_language(CSharp)
+set(CMAKE_CONFIGURATION_TYPES Debug)
+
+set(SRC_FILES
+  ${CMAKE_CURRENT_SOURCE_DIR}/CSharpSourceGroup/foo.cs
+  ${CMAKE_CURRENT_SOURCE_DIR}/CSharpSourceGroup/nested/baz.cs
+)
+
+set(IMAGE_FILES
+  ${CMAKE_CURRENT_SOURCE_DIR}/CSharpSourceGroup/Images/empty.bmp
+)
+
+add_library(VsCsharpSourceGroup SHARED ${SRC_FILES} ${IMAGE_FILES})
+source_group("CSharpSourceGroup" FILES ${CMAKE_CURRENT_SOURCE_DIR}/CSharpSourceGroup/foo.cs)
+source_group("CSharpSourceGroup/nested" FILES ${CMAKE_CURRENT_SOURCE_DIR}/CSharpSourceGroup/nested/baz.cs)
+source_group("Images" FILES ${IMAGE_FILES})
diff --git a/Tests/RunCMake/VS10Project/VsCsharpSourceGroupHelpers.cmake b/Tests/RunCMake/VS10Project/VsCsharpSourceGroupHelpers.cmake
new file mode 100644
index 0000000..bfa9a67
--- /dev/null
+++ b/Tests/RunCMake/VS10Project/VsCsharpSourceGroupHelpers.cmake
@@ -0,0 +1,15 @@
+function(find_source_group LINES NAME)
+  set(foundSourceGroupLink 0)
+  foreach(line IN LISTS LINES)
+    if(line MATCHES "<Link>${NAME}</Link>")
+      set(foundSourceGroupLink 1)
+    endif()
+  endforeach()
+
+  if(NOT foundSourceGroupLink)
+    set(RunCMake_TEST_FAILED "Source group link for ${NAME} not found." PARENT_SCOPE)
+    set(SOURCE_GROUP_FOUND 0 PARENT_SCOPE)
+    return()
+  endif()
+  set(SOURCE_GROUP_FOUND 1 PARENT_SCOPE)
+endfunction()
diff --git a/Tests/RunCMake/VS10Project/VsDeployEnabled-check.cmake b/Tests/RunCMake/VS10Project/VsDeployEnabled-check.cmake
new file mode 100644
index 0000000..0ff8678
--- /dev/null
+++ b/Tests/RunCMake/VS10Project/VsDeployEnabled-check.cmake
@@ -0,0 +1,58 @@
+set(vcProjectFile "${RunCMake_TEST_BINARY_DIR}/foo.vcxproj")
+if(NOT EXISTS "${vcProjectFile}")
+  set(RunCMake_TEST_FAILED "Project file ${vcProjectFile} does not exist.")
+  return()
+endif()
+#
+# Test solution file for deployment.
+#
+
+set(vcSlnFile "${RunCMake_TEST_BINARY_DIR}/VsDeployEnabled.sln")
+if(NOT EXISTS "${vcSlnFile}")
+  set(RunCMake_TEST_FAILED "Solution file ${vcSlnFile} does not exist.")
+  return()
+endif()
+
+
+
+set(FooProjGUID "")
+set(FoundFooProj FALSE)
+set(InFooProj FALSE)
+set(FoundReleaseDeploy FALSE)
+set(DeployConfigs Debug MinSizeRel RelWithDebInfo )
+
+file(STRINGS "${vcSlnFile}" lines)
+foreach(line IN LISTS lines)
+#message(STATUS "${line}")
+  if( (NOT InFooProj ) AND (line MATCHES "^[ \\t]*Project\\(\"{[A-F0-9-]+}\"\\) = \"foo\", \"foo.vcxproj\", \"({[A-F0-9-]+})\"[ \\t]*$"))
+    # First, identify the GUID for the foo project, and record it.
+    set(FoundFooProj TRUE)
+    set(InFooProj TRUE)
+    set(FooProjGUID ${CMAKE_MATCH_1})
+  elseif(InFooProj AND line MATCHES "EndProject")
+    set(InFooProj FALSE)
+  elseif((NOT InFooProj) AND line MATCHES "${FooProjGUID}\\.Release.*\\.Deploy\\.0")
+    # If foo's Release configuration is set to deploy, this is the error.
+    set(FoundReleaseDeploy TRUE)
+  endif()
+  if( line MATCHES "{[A-F0-9-]+}\\.([^\\|]+).*\\.Deploy\\.0" )
+    # Check that the other configurations ARE set to deploy.
+    list( REMOVE_ITEM DeployConfigs ${CMAKE_MATCH_1})
+  endif()
+endforeach()
+
+if(FoundReleaseDeploy)
+  set(RunCMake_TEST_FAILED "Release deployment enabled.")
+  return()
+endif()
+
+if(NOT FoundFooProj)
+  set(RunCMake_TEST_FAILED "Failed to find foo project in the solution.")
+  return()
+endif()
+
+list(LENGTH DeployConfigs length)
+if(  length GREATER 0 )
+  set(RunCMake_TEST_FAILED "Failed to find Deploy lines for non-Release configurations. (${length})")
+  return()
+endif()
diff --git a/Tests/RunCMake/VS10Project/VsDeployEnabled.cmake b/Tests/RunCMake/VS10Project/VsDeployEnabled.cmake
new file mode 100644
index 0000000..02b42b2
--- /dev/null
+++ b/Tests/RunCMake/VS10Project/VsDeployEnabled.cmake
@@ -0,0 +1,12 @@
+enable_language(CXX)
+
+set(DEPLOY_DIR
+   "temp\\foodir"
+)
+
+add_library(foo SHARED foo.cpp)
+
+set_target_properties(foo
+ PROPERTIES
+  VS_SOLUTION_DEPLOY $<NOT:$<CONFIG:Release>>
+)
diff --git a/Tests/RunCMake/VS10Project/VsPackageReferences-check.cmake b/Tests/RunCMake/VS10Project/VsPackageReferences-check.cmake
index 512a1c9..9c0f6e6 100644
--- a/Tests/RunCMake/VS10Project/VsPackageReferences-check.cmake
+++ b/Tests/RunCMake/VS10Project/VsPackageReferences-check.cmake
@@ -4,6 +4,12 @@
   return()
 endif()
 
+set(installProjectFile "${RunCMake_TEST_BINARY_DIR}/INSTALL.vcxproj")
+if(NOT EXISTS "${installProjectFile}")
+  set(RunCMake_TEST_FAILED "Install file INSTALL.vcxproj does not exist.")
+  return()
+endif()
+
 
 set(test1Library "boost")
 set(test1Version "1.7.0")
@@ -37,3 +43,19 @@
   set(RunCMake_TEST_FAILED "Failed to find package references")
   return()
 endif()
+
+set(DOT_NET_FRAMEWORK_VERSION_FOUND FALSE)
+
+file(STRINGS "${installProjectFile}" installlines)
+foreach(line IN LISTS lines)
+  if(line MATCHES "^ *<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>$")
+    set(DOT_NET_FRAMEWORK_VERSION_FOUND TRUE)
+    message(STATUS "The install target contains the correct TargetFrameworkVersion.")
+    break()
+  endif()
+endforeach()
+
+if(NOT DOT_NET_FRAMEWORK_VERSION_FOUND)
+  set(RunCMake_TEST_FAILED "Failed to find TargetFrameworkVersion in the install target")
+  return()
+endif()
diff --git a/Tests/RunCMake/VS10Project/VsPackageReferences.cmake b/Tests/RunCMake/VS10Project/VsPackageReferences.cmake
index 224ab18..30e8fd4 100644
--- a/Tests/RunCMake/VS10Project/VsPackageReferences.cmake
+++ b/Tests/RunCMake/VS10Project/VsPackageReferences.cmake
@@ -1,4 +1,13 @@
 enable_language(CXX)
+set(CMAKE_DOTNET_TARGET_FRAMEWORK_VERSION "v4.7.2")
+
 add_library(foo foo.cpp)
 
 set_property(TARGET foo PROPERTY VS_PACKAGE_REFERENCES "boost_1.7.0;SFML_2.2.0")
+
+# install and export the targets to test the correct behavior
+# nuget restore will only work with an install target when the correct
+# target framework version is set
+set(INSTALL_CMAKE_DIR CMake)
+install(TARGETS foo EXPORT foo_Export_Target)
+install(EXPORT foo_Export_Target DESTINATION ${INSTALL_CMAKE_DIR} FILE fooConfig.cmake)
diff --git a/Tests/RunCMake/VS10Project/VsPlatformToolset-check.cmake b/Tests/RunCMake/VS10Project/VsPlatformToolset-check.cmake
new file mode 100644
index 0000000..0d82d3f
--- /dev/null
+++ b/Tests/RunCMake/VS10Project/VsPlatformToolset-check.cmake
@@ -0,0 +1,36 @@
+macro(ReadPlatformToolset tgt outvar)
+  set(vcProjectFile "${RunCMake_TEST_BINARY_DIR}/${tgt}.vcxproj")
+  if(NOT EXISTS "${vcProjectFile}")
+    set(RunCMake_TEST_FAILED "Project file ${tgt}.vcxproj does not exist.")
+    return()
+  endif()
+
+  set(HAVE_PlatformToolset 0)
+
+  file(STRINGS "${vcProjectFile}" lines)
+  foreach(line IN LISTS lines)
+    if(line MATCHES "^ *<PlatformToolset>([^<>]+)</PlatformToolset>")
+      set(${outvar} "${CMAKE_MATCH_1}")
+      set(HAVE_PlatformToolset 1)
+      break()
+    endif()
+  endforeach()
+
+  if(NOT HAVE_PlatformToolset)
+    set(RunCMake_TEST_FAILED "Project file ${tgt}.vcxproj does not have a <PlatformToolset> field.")
+    return()
+  endif()
+endmacro()
+
+ReadPlatformToolset(NormalPlatformToolset NORMAL_TOOLSET)
+ReadPlatformToolset(OverridenPlatformToolset OVERRIDEN_TOOLSET)
+
+if (NOT "${OVERRIDEN_TOOLSET}" STREQUAL "MyCustomToolset")
+  set(RunCMake_TEST_FAILED "Failed to override the platform toolset")
+  return()
+endif()
+
+if ("${NORMAL_TOOLSET}" STREQUAL "MyCustomToolset")
+  set(RunCMake_TEST_FAILED "Main toolset was overridden (it shouldn't)")
+  return()
+endif()
diff --git a/Tests/RunCMake/VS10Project/VsPlatformToolset.cmake b/Tests/RunCMake/VS10Project/VsPlatformToolset.cmake
new file mode 100644
index 0000000..dce9717
--- /dev/null
+++ b/Tests/RunCMake/VS10Project/VsPlatformToolset.cmake
@@ -0,0 +1,6 @@
+enable_language(CXX)
+
+add_library(NormalPlatformToolset foo.cpp)
+add_library(OverridenPlatformToolset foo.cpp)
+set_target_properties(OverridenPlatformToolset
+                      PROPERTIES VS_PLATFORM_TOOLSET MyCustomToolset)
diff --git a/Tests/RunCMake/VS10Project/VsSettings-check.cmake b/Tests/RunCMake/VS10Project/VsSettings-check.cmake
new file mode 100644
index 0000000..0f8b26c
--- /dev/null
+++ b/Tests/RunCMake/VS10Project/VsSettings-check.cmake
@@ -0,0 +1,23 @@
+macro(ensure_props_set projectFile)
+  if(NOT EXISTS "${projectFile}")
+    set(RunCMake_TEST_FAILED "Project file ${projectFile} does not exist.")
+    return()
+  endif()
+
+  set(SettingFound FALSE)
+
+  file(STRINGS "${projectFile}" lines)
+  foreach(line IN LISTS lines)
+    if(line MATCHES "<SourceProperty1.*Debug.*>SourceProperty1Value</SourceProperty1>")
+      message("SourceProperty1 setting found")
+      set(SettingFound TRUE)
+    endif()
+  endforeach()
+
+  if (NOT SettingFound)
+    set(RunCMake_TEST_FAILED "SourceProperty1 setting was not found")
+    return()
+  endif()
+endmacro()
+
+ensure_props_set("${RunCMake_TEST_BINARY_DIR}/foo.vcxproj")
diff --git a/Tests/RunCMake/VS10Project/VsSettings.cmake b/Tests/RunCMake/VS10Project/VsSettings.cmake
new file mode 100644
index 0000000..a4b321b
--- /dev/null
+++ b/Tests/RunCMake/VS10Project/VsSettings.cmake
@@ -0,0 +1,5 @@
+enable_language(CXX)
+
+add_library(foo foo.cpp shader.hlsl)
+set_property(SOURCE shader.hlsl PROPERTY VS_SETTINGS
+  "$<$<CONFIG:DEBUG>:SourceProperty1=SourceProperty1Value>")
diff --git a/Tests/RunCMake/VS10Project/VsSourceSettingsTool-check.cmake b/Tests/RunCMake/VS10Project/VsSourceSettingsTool-check.cmake
new file mode 100644
index 0000000..29a89c3
--- /dev/null
+++ b/Tests/RunCMake/VS10Project/VsSourceSettingsTool-check.cmake
@@ -0,0 +1,34 @@
+macro(ensure_props_set projectFile)
+  if(NOT EXISTS "${projectFile}")
+    set(RunCMake_TEST_FAILED "Project file ${projectFile} does not exist.")
+    return()
+  endif()
+
+  set(FirstSettingFound FALSE)
+  set(SecondSettingFound FALSE)
+
+  file(STRINGS "${projectFile}" lines)
+  foreach(line IN LISTS lines)
+    if(line MATCHES "<TargetProperty1.*Debug.*>TargetProperty1ValueDebug</TargetProperty1>")
+      if (FirstSettingFound)
+        message("TargetProperty1 setting found twice")
+        set(SecondSettingFound TRUE)
+      else()
+        message("TargetProperty1 setting found once")
+        set(FirstSettingFound TRUE)
+      endif()
+    endif()
+  endforeach()
+
+  if (NOT FirstSettingFound)
+    set(RunCMake_TEST_FAILED "TargetProperty1 setting not found at all")
+    return()
+  endif()
+
+  if (NOT SecondSettingFound)
+    set(RunCMake_TEST_FAILED "TargetProperty1 setting found once when it should be found twice")
+    return()
+  endif()
+endmacro()
+
+ensure_props_set("${RunCMake_TEST_BINARY_DIR}/foo.vcxproj")
diff --git a/Tests/RunCMake/VS10Project/VsSourceSettingsTool.cmake b/Tests/RunCMake/VS10Project/VsSourceSettingsTool.cmake
new file mode 100644
index 0000000..498962f
--- /dev/null
+++ b/Tests/RunCMake/VS10Project/VsSourceSettingsTool.cmake
@@ -0,0 +1,5 @@
+enable_language(CXX)
+
+add_library(foo foo.cpp shader.hlsl shader2.hlsl)
+set_property(TARGET foo PROPERTY VS_SOURCE_SETTINGS_FXCompile
+  "$<$<CONFIG:DEBUG>:TargetProperty1=TargetProperty1ValueDebug>")
diff --git a/Tests/RunCMake/VS10Project/iface.h b/Tests/RunCMake/VS10Project/iface.h
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/Tests/RunCMake/VS10Project/iface.h
diff --git a/Tests/RunCMake/VS10Project/shader.hlsl b/Tests/RunCMake/VS10Project/shader.hlsl
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/Tests/RunCMake/VS10Project/shader.hlsl
@@ -0,0 +1 @@
+
diff --git a/Tests/RunCMake/VS10Project/shader2.hlsl b/Tests/RunCMake/VS10Project/shader2.hlsl
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/Tests/RunCMake/VS10Project/shader2.hlsl
@@ -0,0 +1 @@
+
diff --git a/Tests/RunCMake/VSSolution/CMakeLists.txt b/Tests/RunCMake/VSSolution/CMakeLists.txt
index 12cd3c7..74b3ff8 100644
--- a/Tests/RunCMake/VSSolution/CMakeLists.txt
+++ b/Tests/RunCMake/VSSolution/CMakeLists.txt
@@ -1,3 +1,3 @@
-cmake_minimum_required(VERSION 2.8.4)
+cmake_minimum_required(VERSION 3.3)
 project(${RunCMake_TEST} NONE)
 include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/XcodeProject/CMakeLists.txt b/Tests/RunCMake/XcodeProject/CMakeLists.txt
index 12cd3c7..74b3ff8 100644
--- a/Tests/RunCMake/XcodeProject/CMakeLists.txt
+++ b/Tests/RunCMake/XcodeProject/CMakeLists.txt
@@ -1,3 +1,3 @@
-cmake_minimum_required(VERSION 2.8.4)
+cmake_minimum_required(VERSION 3.3)
 project(${RunCMake_TEST} NONE)
 include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/XcodeProject/InterfaceLibSources-check.cmake b/Tests/RunCMake/XcodeProject/InterfaceLibSources-check.cmake
new file mode 100644
index 0000000..613951a
--- /dev/null
+++ b/Tests/RunCMake/XcodeProject/InterfaceLibSources-check.cmake
@@ -0,0 +1,16 @@
+set(xcProjectFile "${RunCMake_TEST_BINARY_DIR}/InterfaceLibSources.xcodeproj/project.pbxproj")
+if(NOT EXISTS "${xcProjectFile}")
+  set(RunCMake_TEST_FAILED "Project file ${xcProjectFile} does not exist.")
+  return()
+endif()
+
+set(found_iface_h 0)
+file(STRINGS "${xcProjectFile}" lines)
+foreach(line IN LISTS lines)
+  if(line MATCHES "PBXFileReference.*explicitFileType.*sourcecode\\.c\\.h.*iface\\.h")
+    set(found_iface_h 1)
+  endif()
+endforeach()
+if(NOT found_iface_h)
+  set(RunCMake_TEST_FAILED "iface.h not referenced in\n  ${xcProjectFile}")
+endif()
diff --git a/Tests/RunCMake/XcodeProject/InterfaceLibSources.cmake b/Tests/RunCMake/XcodeProject/InterfaceLibSources.cmake
new file mode 100644
index 0000000..3672be1
--- /dev/null
+++ b/Tests/RunCMake/XcodeProject/InterfaceLibSources.cmake
@@ -0,0 +1 @@
+add_library(iface INTERFACE iface.h)
diff --git a/Tests/RunCMake/XcodeProject/RunCMakeTest.cmake b/Tests/RunCMake/XcodeProject/RunCMakeTest.cmake
index 342dbbc..cd6fd06 100644
--- a/Tests/RunCMake/XcodeProject/RunCMakeTest.cmake
+++ b/Tests/RunCMake/XcodeProject/RunCMakeTest.cmake
@@ -2,6 +2,7 @@
 
 run_cmake(ExplicitCMakeLists)
 run_cmake(ImplicitCMakeLists)
+run_cmake(InterfaceLibSources)
 
 run_cmake(XcodeFileType)
 run_cmake(XcodeAttributeLocation)
diff --git a/Tests/RunCMake/XcodeProject/XcodeInstallIOS.cmake b/Tests/RunCMake/XcodeProject/XcodeInstallIOS.cmake
index ab31387..75da7b1 100644
--- a/Tests/RunCMake/XcodeProject/XcodeInstallIOS.cmake
+++ b/Tests/RunCMake/XcodeProject/XcodeInstallIOS.cmake
@@ -1,4 +1,4 @@
-cmake_minimum_required(VERSION 2.8.5)
+cmake_minimum_required(VERSION 3.3)
 
 project(XcodeInstallIOS)
 
diff --git a/Tests/RunCMake/XcodeProject/iface.h b/Tests/RunCMake/XcodeProject/iface.h
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/Tests/RunCMake/XcodeProject/iface.h
diff --git a/Tests/RunCMake/add_dependencies/CMakeLists.txt b/Tests/RunCMake/add_dependencies/CMakeLists.txt
index 12cd3c7..74b3ff8 100644
--- a/Tests/RunCMake/add_dependencies/CMakeLists.txt
+++ b/Tests/RunCMake/add_dependencies/CMakeLists.txt
@@ -1,3 +1,3 @@
-cmake_minimum_required(VERSION 2.8.4)
+cmake_minimum_required(VERSION 3.3)
 project(${RunCMake_TEST} NONE)
 include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/add_link_options/GENEX_LINK_LANG.cmake b/Tests/RunCMake/add_link_options/GENEX_LINK_LANG.cmake
new file mode 100644
index 0000000..cc4ce4c
--- /dev/null
+++ b/Tests/RunCMake/add_link_options/GENEX_LINK_LANG.cmake
@@ -0,0 +1,16 @@
+
+enable_language(C)
+
+set(obj "${CMAKE_C_OUTPUT_EXTENSION}")
+if(BORLAND)
+  set(pre -)
+endif()
+
+add_link_options ($<$<LINK_LANGUAGE:C>:${pre}BADFLAG_LANG_C${obj}>
+                  $<$<LINK_LANGUAGE:CXX>:${pre}BADFLAG_LANG_CXX${obj}>)
+
+add_library(LinkOptions_shared SHARED LinkOptionsLib.c)
+
+add_library(LinkOptions_mod MODULE LinkOptionsLib.c)
+
+add_executable(LinkOptions_exe LinkOptionsExe.c)
diff --git a/Tests/RunCMake/add_link_options/LINKER_expansion-validation.cmake b/Tests/RunCMake/add_link_options/LINKER_expansion-validation.cmake
index bebd6c7..ece3ba0 100644
--- a/Tests/RunCMake/add_link_options/LINKER_expansion-validation.cmake
+++ b/Tests/RunCMake/add_link_options/LINKER_expansion-validation.cmake
@@ -11,5 +11,8 @@
 file(READ "${RunCMake_TEST_BINARY_DIR}/LINKER.txt" linker_flag)
 
 if (NOT actual_stdout MATCHES "${linker_flag}")
-  set (RunCMake_TEST_FAILED "LINKER: was not expanded correctly.")
+  if (RunCMake_TEST_FAILED)
+    string (APPEND RunCMake_TEST_FAILED "\n")
+  endif()
+  string (APPEND RunCMake_TEST_FAILED "LINKER: was not expanded correctly.")
 endif()
diff --git a/Tests/RunCMake/add_link_options/LINK_OPTIONS-exe-check.cmake b/Tests/RunCMake/add_link_options/LINK_OPTIONS-exe-check.cmake
index 4a22d7e..127a2f5 100644
--- a/Tests/RunCMake/add_link_options/LINK_OPTIONS-exe-check.cmake
+++ b/Tests/RunCMake/add_link_options/LINK_OPTIONS-exe-check.cmake
@@ -3,5 +3,8 @@
   set (RunCMake_TEST_FAILED "Not found expected 'BADFLAG_EXECUTABLE_RELEASE'.")
 endif()
 if (actual_stdout MATCHES "BADFLAG_(SHARED|MODULE)_RELEASE")
-  set (RunCMake_TEST_FAILED "Found unexpected 'BADFLAG_(SHARED|MODULE)_RELEASE'.")
+  if (RunCMake_TEST_FAILED)
+    string (APPEND RunCMake_TEST_FAILED "\n")
+  endif()
+  string (APPEND RunCMake_TEST_FAILED "Found unexpected 'BADFLAG_(SHARED|MODULE)_RELEASE'.")
 endif()
diff --git a/Tests/RunCMake/add_link_options/LINK_OPTIONS-mod-check.cmake b/Tests/RunCMake/add_link_options/LINK_OPTIONS-mod-check.cmake
index d695761..874e0ad 100644
--- a/Tests/RunCMake/add_link_options/LINK_OPTIONS-mod-check.cmake
+++ b/Tests/RunCMake/add_link_options/LINK_OPTIONS-mod-check.cmake
@@ -3,5 +3,8 @@
   set (RunCMake_TEST_FAILED "Not found expected 'BADFLAG_MODULE_RELEASE'.")
 endif()
 if (actual_stdout MATCHES "BADFLAG_(SHARED|EXECUTABLE)_RELEASE")
-  set (RunCMake_TEST_FAILED "Found unexpected 'BADFLAG_(SHARED|EXECUTABLE)_RELEASE'.")
+  if (RunCMake_TEST_FAILED)
+    string (APPEND RunCMake_TEST_FAILED "\n")
+  endif()
+  string (APPEND RunCMake_TEST_FAILED "Found unexpected 'BADFLAG_(SHARED|EXECUTABLE)_RELEASE'.")
 endif()
diff --git a/Tests/RunCMake/add_link_options/LINK_OPTIONS-shared-check.cmake b/Tests/RunCMake/add_link_options/LINK_OPTIONS-shared-check.cmake
index eaac8e3..ecba17e 100644
--- a/Tests/RunCMake/add_link_options/LINK_OPTIONS-shared-check.cmake
+++ b/Tests/RunCMake/add_link_options/LINK_OPTIONS-shared-check.cmake
@@ -3,5 +3,8 @@
   set (RunCMake_TEST_FAILED "Not found expected 'BADFLAG_SHARED_RELEASE'.")
 endif()
 if (actual_stdout MATCHES "BADFLAG_(MODULE|EXECUTABLE)_RELEASE")
-  set (RunCMake_TEST_FAILED "Found unexpected 'BADFLAG_(MODULE|EXECUTABLE)_RELEASE'.")
+  if (RunCMake_TEST_FAILED)
+    string (APPEND RunCMake_TEST_FAILED "\n")
+  endif()
+  string (APPEND RunCMake_TEST_FAILED "Found unexpected 'BADFLAG_(MODULE|EXECUTABLE)_RELEASE'.")
 endif()
diff --git a/Tests/RunCMake/add_link_options/LinkOptionsLib.cxx b/Tests/RunCMake/add_link_options/LinkOptionsLib.cxx
new file mode 100644
index 0000000..9bbd24c
--- /dev/null
+++ b/Tests/RunCMake/add_link_options/LinkOptionsLib.cxx
@@ -0,0 +1,7 @@
+#if defined(_WIN32)
+__declspec(dllexport)
+#endif
+  int flags_lib(void)
+{
+  return 0;
+}
diff --git a/Tests/RunCMake/add_link_options/RunCMakeTest.cmake b/Tests/RunCMake/add_link_options/RunCMakeTest.cmake
index 4f5df72..465ff85 100644
--- a/Tests/RunCMake/add_link_options/RunCMakeTest.cmake
+++ b/Tests/RunCMake/add_link_options/RunCMakeTest.cmake
@@ -23,6 +23,21 @@
   run_cmake_target(LINK_OPTIONS mod LinkOptions_mod --config Release)
   run_cmake_target(LINK_OPTIONS exe LinkOptions_exe --config Release)
 
+
+  run_cmake(genex_LINK_LANGUAGE)
+
+  run_cmake_target(genex_LINK_LANGUAGE shared_c LinkOptions_shared_c --config Release)
+  run_cmake_target(genex_LINK_LANGUAGE shared_cxx LinkOptions_shared_cxx --config Release)
+  run_cmake_target(genex_LINK_LANGUAGE mod LinkOptions_mod --config Release)
+  run_cmake_target(genex_LINK_LANGUAGE exe LinkOptions_exe --config Release)
+
+  run_cmake(genex_LINK_LANG_AND_ID)
+
+  run_cmake_target(genex_LINK_LANG_AND_ID shared_c LinkOptions_shared_c --config Release)
+  run_cmake_target(genex_LINK_LANG_AND_ID shared_cxx LinkOptions_shared_cxx --config Release)
+  run_cmake_target(genex_LINK_LANG_AND_ID mod LinkOptions_mod --config Release)
+  run_cmake_target(genex_LINK_LANG_AND_ID exe LinkOptions_exe --config Release)
+
   unset(RunCMake_TEST_OPTIONS)
   unset(RunCMake_TEST_OUTPUT_MERGE)
 endif()
diff --git a/Tests/RunCMake/add_link_options/genex_LINK_LANGUAGE-exe-check.cmake b/Tests/RunCMake/add_link_options/genex_LINK_LANGUAGE-exe-check.cmake
new file mode 100644
index 0000000..71f641d
--- /dev/null
+++ b/Tests/RunCMake/add_link_options/genex_LINK_LANGUAGE-exe-check.cmake
@@ -0,0 +1,2 @@
+
+include ("${CMAKE_CURRENT_LIST_DIR}/genex_LINK_LANGUAGE-validation.cmake")
diff --git a/Tests/RunCMake/add_link_options/genex_LINK_LANGUAGE-exe-result.txt b/Tests/RunCMake/add_link_options/genex_LINK_LANGUAGE-exe-result.txt
new file mode 100644
index 0000000..8d98f9d
--- /dev/null
+++ b/Tests/RunCMake/add_link_options/genex_LINK_LANGUAGE-exe-result.txt
@@ -0,0 +1 @@
+.*
diff --git a/Tests/RunCMake/add_link_options/genex_LINK_LANGUAGE-mod-check.cmake b/Tests/RunCMake/add_link_options/genex_LINK_LANGUAGE-mod-check.cmake
new file mode 100644
index 0000000..71f641d
--- /dev/null
+++ b/Tests/RunCMake/add_link_options/genex_LINK_LANGUAGE-mod-check.cmake
@@ -0,0 +1,2 @@
+
+include ("${CMAKE_CURRENT_LIST_DIR}/genex_LINK_LANGUAGE-validation.cmake")
diff --git a/Tests/RunCMake/add_link_options/genex_LINK_LANGUAGE-mod-result.txt b/Tests/RunCMake/add_link_options/genex_LINK_LANGUAGE-mod-result.txt
new file mode 100644
index 0000000..8d98f9d
--- /dev/null
+++ b/Tests/RunCMake/add_link_options/genex_LINK_LANGUAGE-mod-result.txt
@@ -0,0 +1 @@
+.*
diff --git a/Tests/RunCMake/add_link_options/genex_LINK_LANGUAGE-shared_c-check.cmake b/Tests/RunCMake/add_link_options/genex_LINK_LANGUAGE-shared_c-check.cmake
new file mode 100644
index 0000000..ba0120c
--- /dev/null
+++ b/Tests/RunCMake/add_link_options/genex_LINK_LANGUAGE-shared_c-check.cmake
@@ -0,0 +1,5 @@
+
+set (VALID_LANG C)
+set (INVALID_LANG CXX)
+
+include ("${CMAKE_CURRENT_LIST_DIR}/genex_LINK_LANGUAGE-validation.cmake")
diff --git a/Tests/RunCMake/add_link_options/genex_LINK_LANGUAGE-shared_c-result.txt b/Tests/RunCMake/add_link_options/genex_LINK_LANGUAGE-shared_c-result.txt
new file mode 100644
index 0000000..8d98f9d
--- /dev/null
+++ b/Tests/RunCMake/add_link_options/genex_LINK_LANGUAGE-shared_c-result.txt
@@ -0,0 +1 @@
+.*
diff --git a/Tests/RunCMake/add_link_options/genex_LINK_LANGUAGE-shared_cxx-check.cmake b/Tests/RunCMake/add_link_options/genex_LINK_LANGUAGE-shared_cxx-check.cmake
new file mode 100644
index 0000000..aa39810
--- /dev/null
+++ b/Tests/RunCMake/add_link_options/genex_LINK_LANGUAGE-shared_cxx-check.cmake
@@ -0,0 +1,5 @@
+
+set (VALID_LANG CXX)
+set (INVALID_LANG C)
+
+include ("${CMAKE_CURRENT_LIST_DIR}/genex_LINK_LANGUAGE-validation.cmake")
diff --git a/Tests/RunCMake/add_link_options/genex_LINK_LANGUAGE-shared_cxx-result.txt b/Tests/RunCMake/add_link_options/genex_LINK_LANGUAGE-shared_cxx-result.txt
new file mode 100644
index 0000000..8d98f9d
--- /dev/null
+++ b/Tests/RunCMake/add_link_options/genex_LINK_LANGUAGE-shared_cxx-result.txt
@@ -0,0 +1 @@
+.*
diff --git a/Tests/RunCMake/add_link_options/genex_LINK_LANGUAGE-validation.cmake b/Tests/RunCMake/add_link_options/genex_LINK_LANGUAGE-validation.cmake
new file mode 100644
index 0000000..f0237ab
--- /dev/null
+++ b/Tests/RunCMake/add_link_options/genex_LINK_LANGUAGE-validation.cmake
@@ -0,0 +1,17 @@
+
+if (NOT DEFINED VALID_LANG)
+  set (VALID_LANG C)
+endif()
+if (NOT DEFINED INVALID_LANG)
+  set (INVALID_LANG CXX)
+endif()
+
+if (NOT actual_stdout MATCHES "BADFLAG_${VALID_LANG}_LANG")
+  set (RunCMake_TEST_FAILED "Not found expected 'BADFLAG_${VALID_LANG}_LANG'.")
+endif()
+if (actual_stdout MATCHES "BADFLAG_${INVALID_LANG}_LANG")
+  if (RunCMake_TEST_FAILED)
+    string (APPEND RunCMake_TEST_FAILED "\n")
+  endif()
+  string (APPEND RunCMake_TEST_FAILED "Found unexpected 'BADFLAG_${INVALID_LANG}_LANG'.")
+endif()
diff --git a/Tests/RunCMake/add_link_options/genex_LINK_LANGUAGE.cmake b/Tests/RunCMake/add_link_options/genex_LINK_LANGUAGE.cmake
new file mode 100644
index 0000000..d74d448
--- /dev/null
+++ b/Tests/RunCMake/add_link_options/genex_LINK_LANGUAGE.cmake
@@ -0,0 +1,17 @@
+
+enable_language(C)
+enable_language(CXX)
+
+if(BORLAND)
+  set(pre -)
+endif()
+
+add_link_options ($<$<LINK_LANGUAGE:C>:${pre}BADFLAG_$<LINK_LANGUAGE>_LANG${CMAKE_C_OUTPUT_EXTENSION}>
+                  $<$<LINK_LANGUAGE:CXX>:${pre}BADFLAG_$<LINK_LANGUAGE>_LANG${CMAKE_CXX_OUTPUT_EXTENSION}>)
+
+add_library(LinkOptions_shared_c SHARED LinkOptionsLib.c)
+add_library(LinkOptions_shared_cxx SHARED LinkOptionsLib.cxx)
+
+add_library(LinkOptions_mod MODULE LinkOptionsLib.c)
+
+add_executable(LinkOptions_exe LinkOptionsExe.c)
diff --git a/Tests/RunCMake/add_link_options/genex_LINK_LANG_AND_ID-exe-check.cmake b/Tests/RunCMake/add_link_options/genex_LINK_LANG_AND_ID-exe-check.cmake
new file mode 100644
index 0000000..6bddee1
--- /dev/null
+++ b/Tests/RunCMake/add_link_options/genex_LINK_LANG_AND_ID-exe-check.cmake
@@ -0,0 +1,2 @@
+
+include ("${CMAKE_CURRENT_LIST_DIR}/genex_LINK_LANG_AND_ID-validation.cmake")
diff --git a/Tests/RunCMake/add_link_options/genex_LINK_LANG_AND_ID-exe-result.txt b/Tests/RunCMake/add_link_options/genex_LINK_LANG_AND_ID-exe-result.txt
new file mode 100644
index 0000000..8d98f9d
--- /dev/null
+++ b/Tests/RunCMake/add_link_options/genex_LINK_LANG_AND_ID-exe-result.txt
@@ -0,0 +1 @@
+.*
diff --git a/Tests/RunCMake/add_link_options/genex_LINK_LANG_AND_ID-mod-check.cmake b/Tests/RunCMake/add_link_options/genex_LINK_LANG_AND_ID-mod-check.cmake
new file mode 100644
index 0000000..6bddee1
--- /dev/null
+++ b/Tests/RunCMake/add_link_options/genex_LINK_LANG_AND_ID-mod-check.cmake
@@ -0,0 +1,2 @@
+
+include ("${CMAKE_CURRENT_LIST_DIR}/genex_LINK_LANG_AND_ID-validation.cmake")
diff --git a/Tests/RunCMake/add_link_options/genex_LINK_LANG_AND_ID-mod-result.txt b/Tests/RunCMake/add_link_options/genex_LINK_LANG_AND_ID-mod-result.txt
new file mode 100644
index 0000000..8d98f9d
--- /dev/null
+++ b/Tests/RunCMake/add_link_options/genex_LINK_LANG_AND_ID-mod-result.txt
@@ -0,0 +1 @@
+.*
diff --git a/Tests/RunCMake/add_link_options/genex_LINK_LANG_AND_ID-shared_c-check.cmake b/Tests/RunCMake/add_link_options/genex_LINK_LANG_AND_ID-shared_c-check.cmake
new file mode 100644
index 0000000..cf498d9
--- /dev/null
+++ b/Tests/RunCMake/add_link_options/genex_LINK_LANG_AND_ID-shared_c-check.cmake
@@ -0,0 +1,5 @@
+
+set (VALID_LANG C)
+set (INVALID_LANG CXX)
+
+include ("${CMAKE_CURRENT_LIST_DIR}/genex_LINK_LANG_AND_ID-validation.cmake")
diff --git a/Tests/RunCMake/add_link_options/genex_LINK_LANG_AND_ID-shared_c-result.txt b/Tests/RunCMake/add_link_options/genex_LINK_LANG_AND_ID-shared_c-result.txt
new file mode 100644
index 0000000..8d98f9d
--- /dev/null
+++ b/Tests/RunCMake/add_link_options/genex_LINK_LANG_AND_ID-shared_c-result.txt
@@ -0,0 +1 @@
+.*
diff --git a/Tests/RunCMake/add_link_options/genex_LINK_LANG_AND_ID-shared_cxx-check.cmake b/Tests/RunCMake/add_link_options/genex_LINK_LANG_AND_ID-shared_cxx-check.cmake
new file mode 100644
index 0000000..ed4f851
--- /dev/null
+++ b/Tests/RunCMake/add_link_options/genex_LINK_LANG_AND_ID-shared_cxx-check.cmake
@@ -0,0 +1,5 @@
+
+set (VALID_LANG CXX)
+set (INVALID_LANG C)
+
+include ("${CMAKE_CURRENT_LIST_DIR}/genex_LINK_LANG_AND_ID-validation.cmake")
diff --git a/Tests/RunCMake/add_link_options/genex_LINK_LANG_AND_ID-shared_cxx-result.txt b/Tests/RunCMake/add_link_options/genex_LINK_LANG_AND_ID-shared_cxx-result.txt
new file mode 100644
index 0000000..8d98f9d
--- /dev/null
+++ b/Tests/RunCMake/add_link_options/genex_LINK_LANG_AND_ID-shared_cxx-result.txt
@@ -0,0 +1 @@
+.*
diff --git a/Tests/RunCMake/add_link_options/genex_LINK_LANG_AND_ID-validation.cmake b/Tests/RunCMake/add_link_options/genex_LINK_LANG_AND_ID-validation.cmake
new file mode 100644
index 0000000..a5dc27f
--- /dev/null
+++ b/Tests/RunCMake/add_link_options/genex_LINK_LANG_AND_ID-validation.cmake
@@ -0,0 +1,23 @@
+
+if (NOT VALID_LANG)
+  set (VALID_LANG C)
+endif()
+if (NOT INVALID_LANG)
+  set (INVALID_LANG CXX)
+endif()
+
+if (NOT actual_stdout MATCHES "BADFLAG_${VALID_LANG}_LANG_ID")
+  set (RunCMake_TEST_FAILED "Not found expected 'BADFLAG_${VALID_LANG}_LANG_ID'.\n")
+endif()
+if (actual_stdout MATCHES "BADFLAG_${INVALID_LANG}_LANG_ID")
+  if (RunCMake_TEST_FAILED)
+    string (APPEND RunCMake_TEST_FAILED "\n")
+  endif()
+  string (APPEND RunCMake_TEST_FAILED "Found unexpected 'BADFLAG_${INVALID_LANG}_LANG_ID '.")
+endif()
+if (actual_stdout MATCHES "BADFLAG_(${VALID_LANG}|${INVALID_LANG})_BADID")
+  if (RunCMake_TEST_FAILED)
+    string (APPEND RunCMake_TEST_FAILED "\n")
+  endif()
+  string (APPEND RunCMake_TEST_FAILED "Found unexpected 'BADFLAG_(${VALID_LANG}|${INVALID_LANG})_BADID'.")
+endif()
diff --git a/Tests/RunCMake/add_link_options/genex_LINK_LANG_AND_ID.cmake b/Tests/RunCMake/add_link_options/genex_LINK_LANG_AND_ID.cmake
new file mode 100644
index 0000000..c807050
--- /dev/null
+++ b/Tests/RunCMake/add_link_options/genex_LINK_LANG_AND_ID.cmake
@@ -0,0 +1,19 @@
+
+enable_language(C)
+enable_language(CXX)
+
+if(BORLAND)
+  set(pre -)
+endif()
+
+add_link_options ($<$<LINK_LANG_AND_ID:C,${CMAKE_C_COMPILER_ID}>:${pre}BADFLAG_C_LANG_ID${CMAKE_C_OUTPUT_EXTENSION}>
+                  $<$<LINK_LANG_AND_ID:CXX,${CMAKE_CXX_COMPILER_ID}>:${pre}BADFLAG_CXX_LANG_ID${CMAKE_CXX_OUTPUT_EXTENSION}>
+                  $<$<LINK_LANG_AND_ID:C,BADID>:${pre}BADFLAG_C_BADID${CMAKE_C_OUTPUT_EXTENSION}>
+                  $<$<LINK_LANG_AND_ID:CXX,BADID>:${pre}BADFLAG_CXX_BADID${CMAKE_CXX_OUTPUT_EXTENSION}>)
+
+add_library(LinkOptions_shared_c SHARED LinkOptionsLib.c)
+add_library(LinkOptions_shared_cxx SHARED LinkOptionsLib.cxx)
+
+add_library(LinkOptions_mod MODULE LinkOptionsLib.c)
+
+add_executable(LinkOptions_exe LinkOptionsExe.c)
diff --git a/Tests/RunCMake/alias_targets/CMakeLists.txt b/Tests/RunCMake/alias_targets/CMakeLists.txt
index 12cd3c7..74b3ff8 100644
--- a/Tests/RunCMake/alias_targets/CMakeLists.txt
+++ b/Tests/RunCMake/alias_targets/CMakeLists.txt
@@ -1,3 +1,3 @@
-cmake_minimum_required(VERSION 2.8.4)
+cmake_minimum_required(VERSION 3.3)
 project(${RunCMake_TEST} NONE)
 include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/alias_targets/RunCMakeTest.cmake b/Tests/RunCMake/alias_targets/RunCMakeTest.cmake
index dded248..4be1b9d 100644
--- a/Tests/RunCMake/alias_targets/RunCMakeTest.cmake
+++ b/Tests/RunCMake/alias_targets/RunCMakeTest.cmake
@@ -2,6 +2,8 @@
 
 run_cmake(no-targets)
 run_cmake(multiple-targets)
+run_cmake(duplicate-target-CMP0107-OLD)
+run_cmake(duplicate-target-CMP0107-NEW)
 run_cmake(exclude-from-all)
 run_cmake(imported)
 run_cmake(invalid-name)
@@ -10,6 +12,7 @@
 run_cmake(imported-target)
 run_cmake(alias-target)
 run_cmake(set_property)
+run_cmake(get_property)
 run_cmake(set_target_properties)
 run_cmake(target_link_libraries)
 run_cmake(target_include_directories)
diff --git a/Tests/RunCMake/alias_targets/imported-target-result.txt b/Tests/RunCMake/alias_targets/duplicate-target-CMP0107-NEW-result.txt
similarity index 100%
rename from Tests/RunCMake/alias_targets/imported-target-result.txt
rename to Tests/RunCMake/alias_targets/duplicate-target-CMP0107-NEW-result.txt
diff --git a/Tests/RunCMake/alias_targets/duplicate-target-CMP0107-NEW-stderr.txt b/Tests/RunCMake/alias_targets/duplicate-target-CMP0107-NEW-stderr.txt
new file mode 100644
index 0000000..03ba5a6
--- /dev/null
+++ b/Tests/RunCMake/alias_targets/duplicate-target-CMP0107-NEW-stderr.txt
@@ -0,0 +1,30 @@
+CMake Error at duplicate-target.cmake:[0-9]+ \(add_library\):
+  add_library cannot create ALIAS target "alias1" because another target with
+  the same name already exists.
+Call Stack \(most recent call first\):
+  duplicate-target-CMP0107-NEW.cmake:[0-9]+ \(include\)
+  CMakeLists.txt:[0-9]+ \(include\)
+
+
+CMake Error at duplicate-target.cmake:[0-9]+ \(add_library\):
+  add_library cannot create ALIAS target "alias1" because another target with
+  the same name already exists.
+Call Stack \(most recent call first\):
+  duplicate-target-CMP0107-NEW.cmake:[0-9]+ \(include\)
+  CMakeLists.txt:[0-9]+ \(include\)
+
+
+CMake Error at duplicate-target.cmake:[0-9]+ \(add_library\):
+  add_library cannot create ALIAS target "alias2" because another target with
+  the same name already exists.
+Call Stack \(most recent call first\):
+  duplicate-target-CMP0107-NEW.cmake:[0-9]+ \(include\)
+  CMakeLists.txt:[0-9]+ \(include\)
+
+
+CMake Error at duplicate-target.cmake:[0-9]+ \(add_library\):
+  add_library cannot create ALIAS target "alias2" because another target with
+  the same name already exists.
+Call Stack \(most recent call first\):
+  duplicate-target-CMP0107-NEW.cmake:[0-9]+ \(include\)
+  CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/alias_targets/duplicate-target-CMP0107-NEW.cmake b/Tests/RunCMake/alias_targets/duplicate-target-CMP0107-NEW.cmake
new file mode 100644
index 0000000..609857f
--- /dev/null
+++ b/Tests/RunCMake/alias_targets/duplicate-target-CMP0107-NEW.cmake
@@ -0,0 +1,4 @@
+
+cmake_policy (SET CMP0107 NEW)
+
+include (duplicate-target.cmake)
diff --git a/Tests/RunCMake/alias_targets/duplicate-target-CMP0107-OLD.cmake b/Tests/RunCMake/alias_targets/duplicate-target-CMP0107-OLD.cmake
new file mode 100644
index 0000000..d5bc998
--- /dev/null
+++ b/Tests/RunCMake/alias_targets/duplicate-target-CMP0107-OLD.cmake
@@ -0,0 +1,4 @@
+
+cmake_policy (SET CMP0107 OLD)
+
+include (duplicate-target.cmake)
diff --git a/Tests/RunCMake/alias_targets/duplicate-target.cmake b/Tests/RunCMake/alias_targets/duplicate-target.cmake
new file mode 100644
index 0000000..f81921b
--- /dev/null
+++ b/Tests/RunCMake/alias_targets/duplicate-target.cmake
@@ -0,0 +1,20 @@
+
+add_library (foo1 INTERFACE)
+add_library (foo2 INTERFACE)
+
+add_library (imp1 SHARED IMPORTED GLOBAL)
+add_library (imp2 SHARED IMPORTED GLOBAL)
+
+
+add_library (alias1 ALIAS foo1)
+# same alias to different library
+add_library (alias1 ALIAS foo2)
+# same alias to different imported library
+add_library (alias1 ALIAS imp1)
+
+
+add_library (alias2 ALIAS imp1)
+# same alias to different imported library
+add_library (alias2 ALIAS imp2)
+# same alias to different library
+add_library (alias2 ALIAS foo1)
diff --git a/Tests/RunCMake/alias_targets/get_property-subdir/CMakeLists.txt b/Tests/RunCMake/alias_targets/get_property-subdir/CMakeLists.txt
new file mode 100644
index 0000000..b114b75
--- /dev/null
+++ b/Tests/RunCMake/alias_targets/get_property-subdir/CMakeLists.txt
@@ -0,0 +1,15 @@
+
+
+add_library(alias::import-local-subdir ALIAS import-local)
+
+check_property (alias::import-local-subdir ALIASED_TARGET "import-local")
+check_property (alias::import-local-subdir IMPORTED "TRUE")
+check_property (alias::import-local-subdir ALIAS_GLOBAL "FALSE")
+check_property (alias::import-local-subdir IMPORT_LOCAL_PROPERTY "IMPORT_LOCAL")
+
+
+# non-global alias defined in parent directory must be visible in sub-directory
+check_property (alias::import-local ALIASED_TARGET "import-local")
+check_property (alias::import-local IMPORTED "TRUE")
+check_property (alias::import-local ALIAS_GLOBAL "FALSE")
+check_property (alias::import-local IMPORT_LOCAL_PROPERTY "IMPORT_LOCAL")
diff --git a/Tests/RunCMake/alias_targets/get_property.cmake b/Tests/RunCMake/alias_targets/get_property.cmake
new file mode 100644
index 0000000..8a01c6f
--- /dev/null
+++ b/Tests/RunCMake/alias_targets/get_property.cmake
@@ -0,0 +1,59 @@
+
+enable_language(CXX)
+
+function (check_property alias property value)
+  get_property (data TARGET ${alias} PROPERTY ${property})
+  if (NOT "${value}" STREQUAL "${data}")
+    message (SEND_ERROR "get_property(): Target property '${property}' from ALIAS '${alias}' has wrong value: '${data}' instead of '${value}'.")
+  endif()
+  get_target_property (data ${alias} ${property})
+  if (NOT "${value}" STREQUAL "${data}")
+    message (SEND_ERROR "get_target_property(): Target property '${property}' from ALIAS '${alias}' has wrong value: '${data}' instead of '${value}'.")
+  endif()
+endfunction()
+
+
+add_library(lib empty.cpp)
+set_property (TARGET lib PROPERTY LIB_PROPERTY "LIB")
+
+add_library(alias::lib ALIAS lib)
+
+check_property (alias::lib ALIASED_TARGET "lib")
+check_property (alias::lib IMPORTED "FALSE")
+check_property (alias::lib ALIAS_GLOBAL "TRUE")
+check_property (alias::lib LIB_PROPERTY "LIB")
+
+
+add_library(import-global SHARED IMPORTED GLOBAL)
+set_property (TARGET import-global PROPERTY IMPORT_GLOBAL_PROPERTY "IMPORT_GLOBAL")
+
+add_library(alias::import-global ALIAS import-global)
+
+check_property (alias::import-global ALIASED_TARGET "import-global")
+check_property (alias::import-global IMPORTED "TRUE")
+check_property (alias::import-global ALIAS_GLOBAL "TRUE")
+check_property (alias::import-global IMPORT_GLOBAL_PROPERTY "IMPORT_GLOBAL")
+
+
+add_library(import-local SHARED IMPORTED)
+set_property (TARGET import-local PROPERTY IMPORT_LOCAL_PROPERTY "IMPORT_LOCAL")
+
+add_library(alias::import-local ALIAS import-local)
+
+check_property (alias::import-local ALIASED_TARGET "import-local")
+check_property (alias::import-local IMPORTED "TRUE")
+check_property (alias::import-local ALIAS_GLOBAL "FALSE")
+check_property (alias::import-local IMPORT_LOCAL_PROPERTY "IMPORT_LOCAL")
+
+
+## upgrade imported target from local to global, alias stay local
+add_library(import-lib SHARED IMPORTED)
+add_library(alias::import-lib ALIAS import-lib)
+check_property (alias::import-lib IMPORTED_GLOBAL "FALSE")
+check_property (alias::import-lib ALIAS_GLOBAL "FALSE")
+set_property (TARGET import-lib PROPERTY IMPORTED_GLOBAL "TRUE")
+check_property (alias::import-lib IMPORTED_GLOBAL "TRUE")
+check_property (alias::import-lib ALIAS_GLOBAL "FALSE")
+
+
+add_subdirectory (get_property-subdir)
diff --git a/Tests/RunCMake/alias_targets/imported-target-stderr.txt b/Tests/RunCMake/alias_targets/imported-target-stderr.txt
index 465de03..8259c80 100644
--- a/Tests/RunCMake/alias_targets/imported-target-stderr.txt
+++ b/Tests/RunCMake/alias_targets/imported-target-stderr.txt
@@ -1,15 +1,2 @@
-^CMake Error at imported-target.cmake:[0-9]+ \(add_executable\):
-  add_executable cannot create ALIAS target \"alias-test-exe\" because target
-  \"test-exe\" is imported but not globally visible.
-Call Stack \(most recent call first\):
-  CMakeLists.txt:[0-9]+ \(include\)
-+
-'alias-test-exe' does not exist![?]
-*
-CMake Error at imported-target.cmake:[0-9]+ \(add_library\):
-  add_library cannot create ALIAS target "alias-test-lib" because target
-  "test-lib" is imported but not globally visible.
-Call Stack \(most recent call first\):
-  CMakeLists.txt:[0-9]+ \(include\)
-+
-'alias-test-lib' does not exist![?]$
+^'alias-test-exe' is an alias for 'test-exe' and its name-property contains 'test-exe'.
+'alias-test-lib' is an alias for 'test-lib' and its name-property contains 'test-lib'.$
diff --git a/Tests/RunCMake/alias_targets/imported-target-subdir1/CMakeLists.txt b/Tests/RunCMake/alias_targets/imported-target-subdir1/CMakeLists.txt
new file mode 100644
index 0000000..bec05b3
--- /dev/null
+++ b/Tests/RunCMake/alias_targets/imported-target-subdir1/CMakeLists.txt
@@ -0,0 +1,6 @@
+
+add_executable(alias-test-exe-subdir1 ALIAS test-exe)
+add_executable(alias-test-exe-local ALIAS test-exe)
+
+add_library(alias-test-lib-subdir1 ALIAS test-lib)
+add_library(alias-test-lib-local ALIAS test-lib)
diff --git a/Tests/RunCMake/alias_targets/imported-target-subdir2/CMakeLists.txt b/Tests/RunCMake/alias_targets/imported-target-subdir2/CMakeLists.txt
new file mode 100644
index 0000000..23c85ba
--- /dev/null
+++ b/Tests/RunCMake/alias_targets/imported-target-subdir2/CMakeLists.txt
@@ -0,0 +1,20 @@
+
+add_executable(alias-test-exe-subdir2 ALIAS test-exe)
+add_executable(alias-test-exe-local ALIAS test-exe)
+
+add_library(alias-test-lib-subdir2 ALIAS test-lib)
+add_library(alias-test-lib-local ALIAS test-lib)
+
+
+foreach (item IN ITEMS exe lib)
+  get_property (aliasedTarget TARGET alias-test-${item}-local PROPERTY ALIASED_TARGET)
+  if (NOT aliasedTarget STREQUAL "test-${item}")
+    message (SEND_ERROR "Wrong aliased target '${aliasedTarget}' for ALIAS 'alias-test-${item}-local'.")
+  endif()
+endforeach()
+
+foreach (item IN ITEMS exe lib)
+  if (TARGET alias-test-${item}-subdir1)
+    message (SEND_ERROR "ALIAS 'alias-test-${item}-subdir1' unexpectedly defined.")
+  endif()
+endforeach()
diff --git a/Tests/RunCMake/alias_targets/imported-target.cmake b/Tests/RunCMake/alias_targets/imported-target.cmake
index bb682fe..fa6f8d3 100644
--- a/Tests/RunCMake/alias_targets/imported-target.cmake
+++ b/Tests/RunCMake/alias_targets/imported-target.cmake
@@ -44,3 +44,14 @@
 else()
     message("'alias-test-lib' does not exist!?")
 endif()
+
+add_subdirectory (imported-target-subdir1)
+add_subdirectory (imported-target-subdir2)
+
+foreach (alias IN ITEMS exe-local lib-local
+                        exe-subdir1 lib-subdir1
+                        exe-subdir2 lib-subdir2)
+  if (TARGET alias-test-${alias})
+    message (SEND_ERROR "ALIAS 'alias-test-${alias}' unexpectedly defined.")
+  endif()
+endforeach()
diff --git a/Tests/RunCMake/alias_targets/invalid-name.cmake b/Tests/RunCMake/alias_targets/invalid-name.cmake
index bbd39e3..01983e5 100644
--- a/Tests/RunCMake/alias_targets/invalid-name.cmake
+++ b/Tests/RunCMake/alias_targets/invalid-name.cmake
@@ -1,4 +1,4 @@
-
+cmake_minimum_required(VERSION 2.8.12)
 enable_language(CXX)
 
 add_library(foo empty.cpp)
diff --git a/Tests/RunCMake/build_command/CMakeLists.txt b/Tests/RunCMake/build_command/CMakeLists.txt
index 73e6a78..f1a83e8 100644
--- a/Tests/RunCMake/build_command/CMakeLists.txt
+++ b/Tests/RunCMake/build_command/CMakeLists.txt
@@ -1,4 +1,4 @@
-cmake_minimum_required(VERSION 2.8.4)
+cmake_minimum_required(VERSION 3.3)
 if(NOT NoProject)
   project(${RunCMake_TEST} NONE)
 endif()
diff --git a/Tests/RunCMake/cmake_language/CMakeLists.txt b/Tests/RunCMake/cmake_language/CMakeLists.txt
new file mode 100644
index 0000000..2632ffa
--- /dev/null
+++ b/Tests/RunCMake/cmake_language/CMakeLists.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 3.16)
+project(${RunCMake_TEST} NONE)
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/cmake_language/CallInvalidCommand.cmake b/Tests/RunCMake/cmake_language/CallInvalidCommand.cmake
new file mode 100644
index 0000000..8bee6f2
--- /dev/null
+++ b/Tests/RunCMake/cmake_language/CallInvalidCommand.cmake
@@ -0,0 +1,2 @@
+
+cmake_language(CALL ${COMMAND})
diff --git a/Tests/RunCMake/cmake_language/CheckIncludeGuard.cmake b/Tests/RunCMake/cmake_language/CheckIncludeGuard.cmake
new file mode 100644
index 0000000..902c1e4
--- /dev/null
+++ b/Tests/RunCMake/cmake_language/CheckIncludeGuard.cmake
@@ -0,0 +1,4 @@
+
+cmake_language (CALL "include_guard")
+
+set (GUARD_VALUE 1)
diff --git a/Tests/RunCMake/cmake_language/CheckProject/CMakeLists.txt b/Tests/RunCMake/cmake_language/CheckProject/CMakeLists.txt
new file mode 100644
index 0000000..9a27692
--- /dev/null
+++ b/Tests/RunCMake/cmake_language/CheckProject/CMakeLists.txt
@@ -0,0 +1,19 @@
+
+cmake_language (CALL cmake_minimum_required VERSION 3.17...3.18)
+
+cmake_language (CALL project CheckProject VERSION 1.2.3 LANGUAGES C)
+
+if (NOT PROJECT_NAME STREQUAL "CheckProject")
+  message (SEND_ERROR "error on project() usage.")
+endif()
+
+if (NOT CheckProject_VERSION VERSION_EQUAL "1.2.3")
+  message (SEND_ERROR "error on project() usage.")
+endif()
+
+get_property (languages GLOBAL PROPERTY ENABLED_LANGUAGES)
+if (NOT "C" IN_LIST languages)
+  message (SEND_ERROR "error on project() usage.")
+endif()
+
+add_library (lib SHARED lib.c)
diff --git a/Tests/RunCMake/cmake_language/CheckProject/lib.c b/Tests/RunCMake/cmake_language/CheckProject/lib.c
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/Tests/RunCMake/cmake_language/CheckProject/lib.c
diff --git a/Tests/RunCMake/cmake_language/RunCMakeTest.cmake b/Tests/RunCMake/cmake_language/RunCMakeTest.cmake
new file mode 100644
index 0000000..5fb93c8
--- /dev/null
+++ b/Tests/RunCMake/cmake_language/RunCMakeTest.cmake
@@ -0,0 +1,25 @@
+include(RunCMake)
+
+run_cmake(no_parameters)
+run_cmake(unknown_meta_operation)
+run_cmake(call_invalid_command)
+run_cmake(call_valid_command)
+run_cmake(call_double_evaluation)
+run_cmake(call_expanded_command)
+run_cmake(call_expanded_command_and_arguments)
+run_cmake(call_expanded_command_with_explicit_argument)
+run_cmake(call_expand_command_name)
+run_cmake(call_expand_function_name)
+run_cmake(call_message)
+run_cmake(call_message_fatal_error)
+run_cmake(call_no_parameters)
+run_cmake(call_preserve_arguments)
+run_cmake(call_unknown_function)
+run_cmake(eval_expand_command_name)
+run_cmake(eval_expanded_command_and_arguments)
+run_cmake(eval_extra_parameters_between_eval_and_code)
+run_cmake(eval_message)
+run_cmake(eval_message_fatal_error)
+run_cmake(eval_no_code)
+run_cmake(eval_no_parameters)
+run_cmake(eval_variable_outside_message)
diff --git a/Tests/RunCMake/cmake_language/call_double_evaluation-stderr.txt b/Tests/RunCMake/cmake_language/call_double_evaluation-stderr.txt
new file mode 100644
index 0000000..59a70bd
--- /dev/null
+++ b/Tests/RunCMake/cmake_language/call_double_evaluation-stderr.txt
@@ -0,0 +1 @@
+var='\${foo}'
diff --git a/Tests/RunCMake/cmake_language/call_double_evaluation.cmake b/Tests/RunCMake/cmake_language/call_double_evaluation.cmake
new file mode 100644
index 0000000..cf8fc91
--- /dev/null
+++ b/Tests/RunCMake/cmake_language/call_double_evaluation.cmake
@@ -0,0 +1,2 @@
+set(var [[${foo}]])
+cmake_language(CALL cmake_language CALL message "var='${var}'")
diff --git a/Tests/RunCMake/cmake_language/call_expand_command_name-stderr.txt b/Tests/RunCMake/cmake_language/call_expand_command_name-stderr.txt
new file mode 100644
index 0000000..d640661
--- /dev/null
+++ b/Tests/RunCMake/cmake_language/call_expand_command_name-stderr.txt
@@ -0,0 +1 @@
+OK!
diff --git a/Tests/RunCMake/cmake_language/call_expand_command_name.cmake b/Tests/RunCMake/cmake_language/call_expand_command_name.cmake
new file mode 100644
index 0000000..e03bb1f
--- /dev/null
+++ b/Tests/RunCMake/cmake_language/call_expand_command_name.cmake
@@ -0,0 +1,2 @@
+set (my_call "CALL")
+cmake_language (${my_call} message "OK!")
diff --git a/Tests/RunCMake/Languages/LINK_LANGUAGE-genex-result.txt b/Tests/RunCMake/cmake_language/call_expand_function_name-stderr.txt
similarity index 100%
copy from Tests/RunCMake/Languages/LINK_LANGUAGE-genex-result.txt
copy to Tests/RunCMake/cmake_language/call_expand_function_name-stderr.txt
diff --git a/Tests/RunCMake/cmake_language/call_expand_function_name.cmake b/Tests/RunCMake/cmake_language/call_expand_function_name.cmake
new file mode 100644
index 0000000..565a7df
--- /dev/null
+++ b/Tests/RunCMake/cmake_language/call_expand_function_name.cmake
@@ -0,0 +1,11 @@
+function(some_function_1)
+  message(1)
+endfunction()
+
+function(some_function_2)
+  message(2)
+endfunction()
+
+set(function_version 1)
+
+cmake_language(CALL some_function_${function_version})
diff --git a/Tests/RunCMake/cmake_language/call_expanded_command-stderr.txt b/Tests/RunCMake/cmake_language/call_expanded_command-stderr.txt
new file mode 100644
index 0000000..d640661
--- /dev/null
+++ b/Tests/RunCMake/cmake_language/call_expanded_command-stderr.txt
@@ -0,0 +1 @@
+OK!
diff --git a/Tests/RunCMake/cmake_language/call_expanded_command.cmake b/Tests/RunCMake/cmake_language/call_expanded_command.cmake
new file mode 100644
index 0000000..e76e612
--- /dev/null
+++ b/Tests/RunCMake/cmake_language/call_expanded_command.cmake
@@ -0,0 +1,6 @@
+function (itsok)
+  message(OK!)
+endfunction()
+
+set (cmd CALL itsok)
+cmake_language (${cmd})
diff --git a/Tests/RunCMake/interface_library/target_commands-result.txt b/Tests/RunCMake/cmake_language/call_expanded_command_and_arguments-result.txt
similarity index 100%
copy from Tests/RunCMake/interface_library/target_commands-result.txt
copy to Tests/RunCMake/cmake_language/call_expanded_command_and_arguments-result.txt
diff --git a/Tests/RunCMake/cmake_language/call_expanded_command_and_arguments-stderr.txt b/Tests/RunCMake/cmake_language/call_expanded_command_and_arguments-stderr.txt
new file mode 100644
index 0000000..e87e9bc
--- /dev/null
+++ b/Tests/RunCMake/cmake_language/call_expanded_command_and_arguments-stderr.txt
@@ -0,0 +1,4 @@
+CMake Error at call_expanded_command_and_arguments.cmake:2 \(cmake_language\):
+  cmake_language called with incorrect number of arguments
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/cmake_language/call_expanded_command_and_arguments.cmake b/Tests/RunCMake/cmake_language/call_expanded_command_and_arguments.cmake
new file mode 100644
index 0000000..4ce6b34
--- /dev/null
+++ b/Tests/RunCMake/cmake_language/call_expanded_command_and_arguments.cmake
@@ -0,0 +1,2 @@
+set(call_message CALL message a b)
+cmake_language(${call_message})
diff --git a/Tests/RunCMake/cmake_language/call_expanded_command_with_explicit_argument-stderr.txt b/Tests/RunCMake/cmake_language/call_expanded_command_with_explicit_argument-stderr.txt
new file mode 100644
index 0000000..d640661
--- /dev/null
+++ b/Tests/RunCMake/cmake_language/call_expanded_command_with_explicit_argument-stderr.txt
@@ -0,0 +1 @@
+OK!
diff --git a/Tests/RunCMake/cmake_language/call_expanded_command_with_explicit_argument.cmake b/Tests/RunCMake/cmake_language/call_expanded_command_with_explicit_argument.cmake
new file mode 100644
index 0000000..0563400
--- /dev/null
+++ b/Tests/RunCMake/cmake_language/call_expanded_command_with_explicit_argument.cmake
@@ -0,0 +1,2 @@
+set (cmd CALL message)
+cmake_language (${cmd} "OK!")
diff --git a/Tests/RunCMake/cmake_language/call_invalid_command.cmake b/Tests/RunCMake/cmake_language/call_invalid_command.cmake
new file mode 100644
index 0000000..585aad4
--- /dev/null
+++ b/Tests/RunCMake/cmake_language/call_invalid_command.cmake
@@ -0,0 +1,14 @@
+
+foreach (command IN ITEMS "function" "ENDFUNCTION"
+                          "macro" "endMACRO"
+                          "if" "elseif" "else" "endif"
+                          "while" "endwhile"
+                          "foreach" "endforeach")
+  execute_process(COMMAND "${CMAKE_COMMAND}" -DCOMMAND=${command}
+    -P "${CMAKE_CURRENT_SOURCE_DIR}/CallInvalidCommand.cmake"
+    OUTPUT_QUIET ERROR_QUIET
+    RESULT_VARIABLE result)
+  if (NOT result)
+    message (SEND_ERROR "cmake_language(CALL ${command}) unexpectedly successful.")
+  endif()
+endforeach()
diff --git a/Tests/RunCMake/cmake_language/call_message-stderr.txt b/Tests/RunCMake/cmake_language/call_message-stderr.txt
new file mode 100644
index 0000000..cfc8694
--- /dev/null
+++ b/Tests/RunCMake/cmake_language/call_message-stderr.txt
@@ -0,0 +1 @@
+WORKS!
diff --git a/Tests/RunCMake/cmake_language/call_message.cmake b/Tests/RunCMake/cmake_language/call_message.cmake
new file mode 100644
index 0000000..31aefdf
--- /dev/null
+++ b/Tests/RunCMake/cmake_language/call_message.cmake
@@ -0,0 +1 @@
+cmake_language(CALL message WORKS!)
diff --git a/Tests/RunCMake/Languages/LINK_LANGUAGE-genex-result.txt b/Tests/RunCMake/cmake_language/call_message_fatal_error-result.txt
similarity index 100%
copy from Tests/RunCMake/Languages/LINK_LANGUAGE-genex-result.txt
copy to Tests/RunCMake/cmake_language/call_message_fatal_error-result.txt
diff --git a/Tests/RunCMake/cmake_language/call_message_fatal_error-stderr.txt b/Tests/RunCMake/cmake_language/call_message_fatal_error-stderr.txt
new file mode 100644
index 0000000..83eb3d8
--- /dev/null
+++ b/Tests/RunCMake/cmake_language/call_message_fatal_error-stderr.txt
@@ -0,0 +1,5 @@
+CMake Error at call_message_fatal_error.cmake:1 \(message\):
+  error!
+Call Stack \(most recent call first\):
+  call_message_fatal_error.cmake:1 \(cmake_language\)
+  CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/cmake_language/call_message_fatal_error.cmake b/Tests/RunCMake/cmake_language/call_message_fatal_error.cmake
new file mode 100644
index 0000000..935b437
--- /dev/null
+++ b/Tests/RunCMake/cmake_language/call_message_fatal_error.cmake
@@ -0,0 +1 @@
+cmake_language(CALL message FATAL_ERROR error!)
diff --git a/Tests/RunCMake/interface_library/target_commands-result.txt b/Tests/RunCMake/cmake_language/call_no_parameters-result.txt
similarity index 100%
copy from Tests/RunCMake/interface_library/target_commands-result.txt
copy to Tests/RunCMake/cmake_language/call_no_parameters-result.txt
diff --git a/Tests/RunCMake/cmake_language/call_no_parameters-stderr.txt b/Tests/RunCMake/cmake_language/call_no_parameters-stderr.txt
new file mode 100644
index 0000000..9e2c08f
--- /dev/null
+++ b/Tests/RunCMake/cmake_language/call_no_parameters-stderr.txt
@@ -0,0 +1,2 @@
+CMake Error at call_no_parameters.cmake:1 \(cmake_language\):
+  cmake_language called with incorrect number of arguments
diff --git a/Tests/RunCMake/cmake_language/call_no_parameters.cmake b/Tests/RunCMake/cmake_language/call_no_parameters.cmake
new file mode 100644
index 0000000..8353e08
--- /dev/null
+++ b/Tests/RunCMake/cmake_language/call_no_parameters.cmake
@@ -0,0 +1 @@
+cmake_language(CALL)
diff --git a/Tests/RunCMake/cmake_language/call_preserve_arguments-stderr.txt b/Tests/RunCMake/cmake_language/call_preserve_arguments-stderr.txt
new file mode 100644
index 0000000..8ec5483
--- /dev/null
+++ b/Tests/RunCMake/cmake_language/call_preserve_arguments-stderr.txt
@@ -0,0 +1,6 @@
+foo\(...\)
+\[a;b\]
+\[c;d\]
+cmake_language\(CALL foo ...\)
+\[a;b\]
+\[c;d\]
diff --git a/Tests/RunCMake/cmake_language/call_preserve_arguments.cmake b/Tests/RunCMake/cmake_language/call_preserve_arguments.cmake
new file mode 100644
index 0000000..bfef0fd
--- /dev/null
+++ b/Tests/RunCMake/cmake_language/call_preserve_arguments.cmake
@@ -0,0 +1,12 @@
+function(foo arg1 arg2)
+  math(EXPR last "${ARGC} - 1")
+  foreach(i RANGE 0 ${last})
+    message("[${ARGV${i}}]")
+  endforeach()
+endfunction()
+
+message("foo(...)")
+foo("a;b" "c;d")
+
+message("cmake_language(CALL foo ...)")
+cmake_language(CALL foo "a;b" "c;d")
diff --git a/Tests/RunCMake/GeneratorExpression/OUTPUT_NAME-recursion-result.txt b/Tests/RunCMake/cmake_language/call_unknown_function-result.txt
similarity index 100%
copy from Tests/RunCMake/GeneratorExpression/OUTPUT_NAME-recursion-result.txt
copy to Tests/RunCMake/cmake_language/call_unknown_function-result.txt
diff --git a/Tests/RunCMake/cmake_language/call_unknown_function-stderr.txt b/Tests/RunCMake/cmake_language/call_unknown_function-stderr.txt
new file mode 100644
index 0000000..d09e708
--- /dev/null
+++ b/Tests/RunCMake/cmake_language/call_unknown_function-stderr.txt
@@ -0,0 +1,2 @@
+CMake Error at call_unknown_function.cmake:1 \(unknown\):
+  Unknown CMake command "unknown".
diff --git a/Tests/RunCMake/cmake_language/call_unknown_function.cmake b/Tests/RunCMake/cmake_language/call_unknown_function.cmake
new file mode 100644
index 0000000..efd6baf
--- /dev/null
+++ b/Tests/RunCMake/cmake_language/call_unknown_function.cmake
@@ -0,0 +1 @@
+cmake_language(CALL unknown)
diff --git a/Tests/RunCMake/cmake_language/call_valid_command.cmake b/Tests/RunCMake/cmake_language/call_valid_command.cmake
new file mode 100644
index 0000000..2e965dc
--- /dev/null
+++ b/Tests/RunCMake/cmake_language/call_valid_command.cmake
@@ -0,0 +1,99 @@
+
+## check continue() usage
+set (VALUE 0)
+foreach (i RANGE 1 4)
+  set (VALUE "${i}")
+  cmake_language (CALL "continue")
+  set (VALUE "0")
+endforeach()
+if (NOT VALUE EQUAL "4")
+  message (SEND_ERROR "error on continue() usage.")
+endif()
+
+
+## check break() usage
+set (VALUE 0)
+foreach (i RANGE 1 4)
+  set (VALUE "${i}")
+  cmake_language (CALL "break")
+  set (VALUE 0)
+endforeach()
+if (NOT VALUE EQUAL "1")
+  message (SEND_ERROR "error on break() usage.")
+endif()
+
+
+## check return() usage in macro
+macro (call_return_in_macro)
+  cmake_language (CALL "return")
+  set (VALUE 1)
+endmacro()
+function (wrapper)
+  call_return_in_macro()
+  set (VALUE 1 PARENT_SCOPE)
+endfunction()
+
+set (VALUE 0)
+wrapper()
+if (NOT VALUE EQUAL "0")
+  message (SEND_ERROR "error on return() usage in macro.")
+endif()
+
+set (VALUE 0)
+cmake_language (CALL "wrapper")
+if (NOT VALUE EQUAL "0")
+  message (SEND_ERROR "error on return() usage in macro.")
+endif()
+
+function (wrapper2)
+  cmake_language (CALL "call_return_in_macro")
+  set (VALUE 1 PARENT_SCOPE)
+endfunction()
+
+set (VALUE 0)
+wrapper2()
+if (NOT VALUE EQUAL "0")
+  message (SEND_ERROR "error on return() usage in macro.")
+endif()
+
+set (VALUE 0)
+cmake_language (CALL "wrapper2")
+if (NOT VALUE EQUAL "0")
+  message (SEND_ERROR "error on return() usage in macro.")
+endif()
+
+## check return() usage in function
+function (call_return_in_function)
+  cmake_language (CALL "return")
+  set (VALUE 1 PARENT_SCOPE)
+endfunction()
+
+set (VALUE 0)
+call_return_in_function()
+if (NOT VALUE EQUAL "0")
+  message (SEND_ERROR "error on return() usage in function.")
+endif()
+
+set (VALUE 0)
+cmake_language (CALL "call_return_in_function")
+if (NOT VALUE EQUAL "0")
+  message (SEND_ERROR "error on return() usage in function.")
+endif()
+
+
+## check usage of include_guard()
+set (GUARD_VALUE 0)
+include ("${CMAKE_CURRENT_SOURCE_DIR}/CheckIncludeGuard.cmake")
+if (NOT GUARD_VALUE EQUAL "1")
+  message (SEND_ERROR "error on include_guard() on first include.")
+endif()
+
+set (GUARD_VALUE 0)
+include ("${CMAKE_CURRENT_SOURCE_DIR}/CheckIncludeGuard.cmake")
+if (NOT GUARD_VALUE EQUAL "0")
+  message (SEND_ERROR "error on include_guard() on second include.")
+endif()
+
+
+## check usage of cmake_minimum_required() and project()
+add_subdirectory (CheckProject)
diff --git a/Tests/RunCMake/cmake_language/eval_expand_command_name-stderr.txt b/Tests/RunCMake/cmake_language/eval_expand_command_name-stderr.txt
new file mode 100644
index 0000000..d640661
--- /dev/null
+++ b/Tests/RunCMake/cmake_language/eval_expand_command_name-stderr.txt
@@ -0,0 +1 @@
+OK!
diff --git a/Tests/RunCMake/cmake_language/eval_expand_command_name.cmake b/Tests/RunCMake/cmake_language/eval_expand_command_name.cmake
new file mode 100644
index 0000000..2397232
--- /dev/null
+++ b/Tests/RunCMake/cmake_language/eval_expand_command_name.cmake
@@ -0,0 +1,2 @@
+set (my_eval "EVAL")
+cmake_language (${my_eval} CODE message("OK!"))
diff --git a/Tests/RunCMake/cmake_language/eval_expanded_command_and_arguments-stderr.txt b/Tests/RunCMake/cmake_language/eval_expanded_command_and_arguments-stderr.txt
new file mode 100644
index 0000000..d640661
--- /dev/null
+++ b/Tests/RunCMake/cmake_language/eval_expanded_command_and_arguments-stderr.txt
@@ -0,0 +1 @@
+OK!
diff --git a/Tests/RunCMake/cmake_language/eval_expanded_command_and_arguments.cmake b/Tests/RunCMake/cmake_language/eval_expanded_command_and_arguments.cmake
new file mode 100644
index 0000000..f7d2d51
--- /dev/null
+++ b/Tests/RunCMake/cmake_language/eval_expanded_command_and_arguments.cmake
@@ -0,0 +1,2 @@
+set(cmd EVAL CODE [[message("OK!")]])
+cmake_language(${cmd})
diff --git a/Tests/RunCMake/Languages/LINK_LANGUAGE-genex-result.txt b/Tests/RunCMake/cmake_language/eval_extra_parameters_between_eval_and_code-result.txt
similarity index 100%
copy from Tests/RunCMake/Languages/LINK_LANGUAGE-genex-result.txt
copy to Tests/RunCMake/cmake_language/eval_extra_parameters_between_eval_and_code-result.txt
diff --git a/Tests/RunCMake/cmake_language/eval_extra_parameters_between_eval_and_code-stderr.txt b/Tests/RunCMake/cmake_language/eval_extra_parameters_between_eval_and_code-stderr.txt
new file mode 100644
index 0000000..d32054f
--- /dev/null
+++ b/Tests/RunCMake/cmake_language/eval_extra_parameters_between_eval_and_code-stderr.txt
@@ -0,0 +1,5 @@
+CMake Error at eval_extra_parameters_between_eval_and_code.cmake:1 \(cmake_language\):
+  cmake_language called with unsupported arguments between EVAL and CODE
+  arguments
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/cmake_language/eval_extra_parameters_between_eval_and_code.cmake b/Tests/RunCMake/cmake_language/eval_extra_parameters_between_eval_and_code.cmake
new file mode 100644
index 0000000..7c004d7
--- /dev/null
+++ b/Tests/RunCMake/cmake_language/eval_extra_parameters_between_eval_and_code.cmake
@@ -0,0 +1 @@
+cmake_language(EVAL BAD CODE "message(BAD CODE)")
diff --git a/Tests/RunCMake/cmake_language/eval_message-stderr.txt b/Tests/RunCMake/cmake_language/eval_message-stderr.txt
new file mode 100644
index 0000000..cfc8694
--- /dev/null
+++ b/Tests/RunCMake/cmake_language/eval_message-stderr.txt
@@ -0,0 +1 @@
+WORKS!
diff --git a/Tests/RunCMake/cmake_language/eval_message.cmake b/Tests/RunCMake/cmake_language/eval_message.cmake
new file mode 100644
index 0000000..91edcdd
--- /dev/null
+++ b/Tests/RunCMake/cmake_language/eval_message.cmake
@@ -0,0 +1 @@
+cmake_language(EVAL CODE message(WORKS!))
diff --git a/Tests/RunCMake/Languages/LINK_LANGUAGE-genex-result.txt b/Tests/RunCMake/cmake_language/eval_message_fatal_error-result.txt
similarity index 100%
copy from Tests/RunCMake/Languages/LINK_LANGUAGE-genex-result.txt
copy to Tests/RunCMake/cmake_language/eval_message_fatal_error-result.txt
diff --git a/Tests/RunCMake/cmake_language/eval_message_fatal_error-stderr.txt b/Tests/RunCMake/cmake_language/eval_message_fatal_error-stderr.txt
new file mode 100644
index 0000000..5cf11e3
--- /dev/null
+++ b/Tests/RunCMake/cmake_language/eval_message_fatal_error-stderr.txt
@@ -0,0 +1,5 @@
+CMake Error at eval_message_fatal_error.cmake:1:EVAL:2 \(message\):
+  error!
+Call Stack \(most recent call first\):
+  eval_message_fatal_error.cmake:1 \(cmake_language\)
+  CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/cmake_language/eval_message_fatal_error.cmake b/Tests/RunCMake/cmake_language/eval_message_fatal_error.cmake
new file mode 100644
index 0000000..72e155d
--- /dev/null
+++ b/Tests/RunCMake/cmake_language/eval_message_fatal_error.cmake
@@ -0,0 +1,5 @@
+cmake_language(EVAL CODE
+"
+  message(FATAL_ERROR error!)
+"
+)
diff --git a/Tests/RunCMake/interface_library/invalid_name-result.txt b/Tests/RunCMake/cmake_language/eval_no_code-result.txt
similarity index 100%
copy from Tests/RunCMake/interface_library/invalid_name-result.txt
copy to Tests/RunCMake/cmake_language/eval_no_code-result.txt
diff --git a/Tests/RunCMake/cmake_language/eval_no_code-stderr.txt b/Tests/RunCMake/cmake_language/eval_no_code-stderr.txt
new file mode 100644
index 0000000..608ba88
--- /dev/null
+++ b/Tests/RunCMake/cmake_language/eval_no_code-stderr.txt
@@ -0,0 +1,2 @@
+CMake Error at eval_no_code.cmake:1 \(cmake_language\):
+  cmake_language called without CODE argument
diff --git a/Tests/RunCMake/cmake_language/eval_no_code.cmake b/Tests/RunCMake/cmake_language/eval_no_code.cmake
new file mode 100644
index 0000000..7f5bc21
--- /dev/null
+++ b/Tests/RunCMake/cmake_language/eval_no_code.cmake
@@ -0,0 +1 @@
+cmake_language(EVAL message "too many parameters")
diff --git a/Tests/RunCMake/interface_library/target_commands-result.txt b/Tests/RunCMake/cmake_language/eval_no_parameters-result.txt
similarity index 100%
copy from Tests/RunCMake/interface_library/target_commands-result.txt
copy to Tests/RunCMake/cmake_language/eval_no_parameters-result.txt
diff --git a/Tests/RunCMake/cmake_language/eval_no_parameters-stderr.txt b/Tests/RunCMake/cmake_language/eval_no_parameters-stderr.txt
new file mode 100644
index 0000000..6166898
--- /dev/null
+++ b/Tests/RunCMake/cmake_language/eval_no_parameters-stderr.txt
@@ -0,0 +1,2 @@
+CMake Error at eval_no_parameters.cmake:1 \(cmake_language\):
+  cmake_language called with incorrect number of arguments
diff --git a/Tests/RunCMake/cmake_language/eval_no_parameters.cmake b/Tests/RunCMake/cmake_language/eval_no_parameters.cmake
new file mode 100644
index 0000000..e7ae808
--- /dev/null
+++ b/Tests/RunCMake/cmake_language/eval_no_parameters.cmake
@@ -0,0 +1 @@
+cmake_language(EVAL)
diff --git a/Tests/RunCMake/cmake_language/eval_variable_outside_message-stderr.txt b/Tests/RunCMake/cmake_language/eval_variable_outside_message-stderr.txt
new file mode 100644
index 0000000..cfc8694
--- /dev/null
+++ b/Tests/RunCMake/cmake_language/eval_variable_outside_message-stderr.txt
@@ -0,0 +1 @@
+WORKS!
diff --git a/Tests/RunCMake/cmake_language/eval_variable_outside_message.cmake b/Tests/RunCMake/cmake_language/eval_variable_outside_message.cmake
new file mode 100644
index 0000000..71f0457
--- /dev/null
+++ b/Tests/RunCMake/cmake_language/eval_variable_outside_message.cmake
@@ -0,0 +1,2 @@
+cmake_language(EVAL CODE "set(phrase \"WORKS!\")")
+message(${phrase})
diff --git a/Tests/RunCMake/interface_library/target_commands-result.txt b/Tests/RunCMake/cmake_language/no_parameters-result.txt
similarity index 100%
copy from Tests/RunCMake/interface_library/target_commands-result.txt
copy to Tests/RunCMake/cmake_language/no_parameters-result.txt
diff --git a/Tests/RunCMake/cmake_language/no_parameters-stderr.txt b/Tests/RunCMake/cmake_language/no_parameters-stderr.txt
new file mode 100644
index 0000000..194bbe3
--- /dev/null
+++ b/Tests/RunCMake/cmake_language/no_parameters-stderr.txt
@@ -0,0 +1,2 @@
+CMake Error at no_parameters.cmake:1 \(cmake_language\):
+  cmake_language called with incorrect number of arguments
diff --git a/Tests/RunCMake/cmake_language/no_parameters.cmake b/Tests/RunCMake/cmake_language/no_parameters.cmake
new file mode 100644
index 0000000..8353e08
--- /dev/null
+++ b/Tests/RunCMake/cmake_language/no_parameters.cmake
@@ -0,0 +1 @@
+cmake_language(CALL)
diff --git a/Tests/RunCMake/GeneratorExpression/OUTPUT_NAME-recursion-result.txt b/Tests/RunCMake/cmake_language/unknown_meta_operation-result.txt
similarity index 100%
copy from Tests/RunCMake/GeneratorExpression/OUTPUT_NAME-recursion-result.txt
copy to Tests/RunCMake/cmake_language/unknown_meta_operation-result.txt
diff --git a/Tests/RunCMake/cmake_language/unknown_meta_operation-stderr.txt b/Tests/RunCMake/cmake_language/unknown_meta_operation-stderr.txt
new file mode 100644
index 0000000..6a1d4fd
--- /dev/null
+++ b/Tests/RunCMake/cmake_language/unknown_meta_operation-stderr.txt
@@ -0,0 +1,2 @@
+CMake Error at unknown_meta_operation.cmake:1 \(cmake_language\):
+  cmake_language called with unknown meta-operation
diff --git a/Tests/RunCMake/cmake_language/unknown_meta_operation.cmake b/Tests/RunCMake/cmake_language/unknown_meta_operation.cmake
new file mode 100644
index 0000000..699f36f
--- /dev/null
+++ b/Tests/RunCMake/cmake_language/unknown_meta_operation.cmake
@@ -0,0 +1 @@
+cmake_language(UNKNOWN)
diff --git a/Tests/RunCMake/cmake_minimum_required/Before2812-stderr.txt b/Tests/RunCMake/cmake_minimum_required/Before2812-stderr.txt
new file mode 100644
index 0000000..7d40dcb
--- /dev/null
+++ b/Tests/RunCMake/cmake_minimum_required/Before2812-stderr.txt
@@ -0,0 +1,26 @@
+^CMake Deprecation Warning at Before2812.cmake:1 \(cmake_minimum_required\):
+  Compatibility with CMake < 2.8.12 will be removed from a future version of
+  CMake.
+
+  Update the VERSION argument <min> value or use a ...<max> suffix to tell
+  CMake that the project does not need compatibility with older versions.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)
++
+CMake Deprecation Warning at Before2812.cmake:2 \(cmake_policy\):
+  Compatibility with CMake < 2.8.12 will be removed from a future version of
+  CMake.
+
+  Update the VERSION argument <min> value or use a ...<max> suffix to tell
+  CMake that the project does not need compatibility with older versions.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)
++
+CMake Deprecation Warning at Before2812.cmake:6 \(cmake_policy\):
+  Compatibility with CMake < 2.8.12 will be removed from a future version of
+  CMake.
+
+  Update the VERSION argument <min> value or use a ...<max> suffix to tell
+  CMake that the project does not need compatibility with older versions.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)$
diff --git a/Tests/RunCMake/cmake_minimum_required/Before2812.cmake b/Tests/RunCMake/cmake_minimum_required/Before2812.cmake
new file mode 100644
index 0000000..220e359
--- /dev/null
+++ b/Tests/RunCMake/cmake_minimum_required/Before2812.cmake
@@ -0,0 +1,6 @@
+cmake_minimum_required(VERSION 2.8.11)
+cmake_policy(VERSION 2.6)
+cmake_policy(PUSH)
+cmake_policy(VERSION 2.6) # simulate pre-3.18 install(EXPORT)-generated call
+cmake_policy(POP)
+cmake_policy(VERSION 2.8.11)
diff --git a/Tests/RunCMake/cmake_minimum_required/CMakeLists.txt b/Tests/RunCMake/cmake_minimum_required/CMakeLists.txt
index e8db6b0..667561e 100644
--- a/Tests/RunCMake/cmake_minimum_required/CMakeLists.txt
+++ b/Tests/RunCMake/cmake_minimum_required/CMakeLists.txt
@@ -1,3 +1,3 @@
-cmake_minimum_required(VERSION 2.8)
+cmake_minimum_required(VERSION 2.8.12)
 project(${RunCMake_TEST} NONE)
-include(${RunCMake_TEST}.cmake)
+include(${RunCMake_TEST}.cmake NO_POLICY_SCOPE)
diff --git a/Tests/RunCMake/cmake_minimum_required/CompatBefore24-stderr.txt b/Tests/RunCMake/cmake_minimum_required/CompatBefore24-stderr.txt
index a874466..81d26d2 100644
--- a/Tests/RunCMake/cmake_minimum_required/CompatBefore24-stderr.txt
+++ b/Tests/RunCMake/cmake_minimum_required/CompatBefore24-stderr.txt
@@ -1,3 +1,12 @@
+^CMake Deprecation Warning at CompatBefore24.cmake:1 \(cmake_minimum_required\):
+  Compatibility with CMake < 2.8.12 will be removed from a future version of
+  CMake.
+
+  Update the VERSION argument <min> value or use a ...<max> suffix to tell
+  CMake that the project does not need compatibility with older versions.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)
++
 CMake Error in CMakeLists.txt:
   You have set CMAKE_BACKWARDS_COMPATIBILITY to a CMake version less than
   2.4.  This version of CMake only supports backwards compatibility with
diff --git a/Tests/RunCMake/cmake_minimum_required/RunCMakeTest.cmake b/Tests/RunCMake/cmake_minimum_required/RunCMakeTest.cmake
index 1030211..3a959bb 100644
--- a/Tests/RunCMake/cmake_minimum_required/RunCMakeTest.cmake
+++ b/Tests/RunCMake/cmake_minimum_required/RunCMakeTest.cmake
@@ -4,6 +4,7 @@
 run_cmake(CompatBefore24)
 run_cmake(Future)
 run_cmake(PolicyBefore24)
+run_cmake(Before2812)
 run_cmake(Range)
 run_cmake(RangeBad)
 run_cmake(Unknown)
diff --git a/Tests/RunCMake/configure_file/NoSourcePermissions.cmake b/Tests/RunCMake/configure_file/NoSourcePermissions.cmake
new file mode 100644
index 0000000..c6ad131
--- /dev/null
+++ b/Tests/RunCMake/configure_file/NoSourcePermissions.cmake
@@ -0,0 +1,10 @@
+configure_file(NoSourcePermissions.sh NoSourcePermissions.sh.out
+               NO_SOURCE_PERMISSIONS)
+
+if (UNIX)
+  execute_process(COMMAND ${CMAKE_CURRENT_BINARY_DIR}/NoSourcePermissions.sh.out
+                  RESULT_VARIABLE result)
+  if (result EQUAL "0")
+    message(FATAL_ERROR "Copied file has executable permissions")
+  endif()
+endif()
diff --git a/Tests/RunCMake/configure_file/NoSourcePermissions.sh b/Tests/RunCMake/configure_file/NoSourcePermissions.sh
new file mode 100755
index 0000000..0aa8f41
--- /dev/null
+++ b/Tests/RunCMake/configure_file/NoSourcePermissions.sh
@@ -0,0 +1,3 @@
+#!/bin/sh
+
+#Testing NO_SOURCE_PERMISSIONS option of configure_file.
diff --git a/Tests/RunCMake/configure_file/RerunCMake.cmake b/Tests/RunCMake/configure_file/RerunCMake.cmake
index 890cc1f..98387d0 100644
--- a/Tests/RunCMake/configure_file/RerunCMake.cmake
+++ b/Tests/RunCMake/configure_file/RerunCMake.cmake
@@ -1,8 +1,4 @@
 message("Running CMake on RerunCMake") # write to stderr if cmake reruns
-configure_file(
-  "${CMAKE_CURRENT_BINARY_DIR}/ConfigureFileInput.txt.in"
-  "${CMAKE_CURRENT_BINARY_DIR}/ConfigureFileOutput.txt"
-  @ONLY
-  )
+add_subdirectory(RerunCMake)
 # make sure CMakeCache.txt is newer than ConfigureFileOutput.txt
 execute_process(COMMAND ${CMAKE_COMMAND} -E sleep 1)
diff --git a/Tests/RunCMake/configure_file/RerunCMake/CMakeLists.txt b/Tests/RunCMake/configure_file/RerunCMake/CMakeLists.txt
new file mode 100644
index 0000000..c9681c7
--- /dev/null
+++ b/Tests/RunCMake/configure_file/RerunCMake/CMakeLists.txt
@@ -0,0 +1,5 @@
+configure_file(
+  "${CMAKE_CURRENT_BINARY_DIR}/ConfigureFileInput.txt.in"
+  "${CMAKE_CURRENT_BINARY_DIR}/ConfigureFileOutput.txt"
+  @ONLY
+  )
diff --git a/Tests/RunCMake/configure_file/RunCMakeTest.cmake b/Tests/RunCMake/configure_file/RunCMakeTest.cmake
index de14468..71694fb 100644
--- a/Tests/RunCMake/configure_file/RunCMakeTest.cmake
+++ b/Tests/RunCMake/configure_file/RunCMakeTest.cmake
@@ -15,6 +15,7 @@
 run_cmake(NewLineStyle-WrongArg)
 run_cmake(NewLineStyle-ValidArg)
 run_cmake(NewLineStyle-COPYONLY)
+run_cmake(NoSourcePermissions)
 
 if(RunCMake_GENERATOR MATCHES "Make")
   # Use a single build tree for a few tests without cleaning.
@@ -22,7 +23,7 @@
   set(RunCMake_TEST_NO_CLEAN 1)
   file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}")
   file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}")
-  set(in_conf  "${RunCMake_TEST_BINARY_DIR}/ConfigureFileInput.txt.in")
+  set(in_conf  "${RunCMake_TEST_BINARY_DIR}/RerunCMake/ConfigureFileInput.txt.in")
   file(WRITE "${in_conf}" "1")
 
   message(STATUS "RerunCMake: first configuration...")
@@ -42,7 +43,7 @@
   run_cmake_command(RerunCMake-nowork ${CMAKE_COMMAND} --build .)
 
   message(STATUS "RerunCMake: remove configure_file output...")
-  file(REMOVE "${RunCMake_TEST_BINARY_DIR}/ConfigureFileOutput.txt")
+  file(REMOVE "${RunCMake_TEST_BINARY_DIR}/RerunCMake/ConfigureFileOutput.txt")
   run_cmake_command(RerunCMake-rerun ${CMAKE_COMMAND} --build .)
   run_cmake_command(RerunCMake-nowork ${CMAKE_COMMAND} --build .)
 
diff --git a/Tests/RunCMake/ctest_memcheck/CMakeLists.txt.in b/Tests/RunCMake/ctest_memcheck/CMakeLists.txt.in
index 3b8edf4..68a0fcb 100644
--- a/Tests/RunCMake/ctest_memcheck/CMakeLists.txt.in
+++ b/Tests/RunCMake/ctest_memcheck/CMakeLists.txt.in
@@ -1,4 +1,4 @@
-cmake_minimum_required(VERSION 2.8.9)
+cmake_minimum_required(VERSION 3.3)
 project(CTestTestMemcheck@CASE_NAME@ NONE)
 include(CTest)
 
diff --git a/Tests/RunCMake/interface_library/genex_link-result.txt b/Tests/RunCMake/ctest_memcheck/DummyCudaMemcheck-result.txt
similarity index 100%
copy from Tests/RunCMake/interface_library/genex_link-result.txt
copy to Tests/RunCMake/ctest_memcheck/DummyCudaMemcheck-result.txt
diff --git a/Tests/RunCMake/ctest_memcheck/DummyCudaMemcheck-stderr.txt b/Tests/RunCMake/ctest_memcheck/DummyCudaMemcheck-stderr.txt
new file mode 100644
index 0000000..d302b5c
--- /dev/null
+++ b/Tests/RunCMake/ctest_memcheck/DummyCudaMemcheck-stderr.txt
@@ -0,0 +1 @@
+Defect count: 23
diff --git a/Tests/RunCMake/ctest_memcheck/DummyCudaMemcheck-stdout.txt b/Tests/RunCMake/ctest_memcheck/DummyCudaMemcheck-stdout.txt
new file mode 100644
index 0000000..034ee1e
--- /dev/null
+++ b/Tests/RunCMake/ctest_memcheck/DummyCudaMemcheck-stdout.txt
@@ -0,0 +1,13 @@
+Memory checking results:
+Uninitialized __global__ memory read - 1
+Unused memory - 1
+Host API memory access error - 1
+Barrier error - 2
+Invalid __global__ read - 1
+cudaErrorLaunchFailure - 2
+Fatal UVM GPU fault - 1
+Fatal UVM CPU fault - 1
+Memory leak - 1
+Potential WAR hazard detected - 4
+Potential RAW hazard detected - 4
+Race reported - 4
diff --git a/Tests/RunCMake/ctest_memcheck/RunCMakeTest.cmake b/Tests/RunCMake/ctest_memcheck/RunCMakeTest.cmake
index ab4c5ab..2b3165b 100644
--- a/Tests/RunCMake/ctest_memcheck/RunCMakeTest.cmake
+++ b/Tests/RunCMake/ctest_memcheck/RunCMakeTest.cmake
@@ -175,3 +175,15 @@
 unset(CTEST_EXTRA_CODE)
 unset(CTEST_MEMCHECK_ARGS)
 unset(CTEST_SUFFIX_CODE)
+
+#-----------------------------------------------------------------------------
+set(CMAKELISTS_EXTRA_CODE
+"add_test(NAME TestSan COMMAND \"${CMAKE_COMMAND}\"
+-P \"${RunCMake_SOURCE_DIR}/testCudaMemcheck.cmake\")
+")
+set(CTEST_SUFFIX_CODE "message(\"Defect count: \${defect_count}\")")
+set(CTEST_MEMCHECK_ARGS "DEFECT_COUNT defect_count")
+run_mc_test(DummyCudaMemcheck "${PSEUDO_CUDA_MEMCHECK}")
+unset(CTEST_MEMCHECK_ARGS)
+unset(CTEST_SUFFIX_CODE)
+unset(CTEST_EXTRA_CODE)
diff --git a/Tests/RunCMake/ctest_memcheck/test.cmake.in b/Tests/RunCMake/ctest_memcheck/test.cmake.in
index 50b4b6a..eedf080 100644
--- a/Tests/RunCMake/ctest_memcheck/test.cmake.in
+++ b/Tests/RunCMake/ctest_memcheck/test.cmake.in
@@ -1,4 +1,4 @@
-cmake_minimum_required(VERSION 2.8.9)
+cmake_minimum_required(VERSION 3.3)
 
 # Settings:
 set(CTEST_SITE                          "@SITE@")
diff --git a/Tests/RunCMake/ctest_memcheck/testAddressLeakSanitizer.cmake b/Tests/RunCMake/ctest_memcheck/testAddressLeakSanitizer.cmake
index ca36a7c..58c94d7 100644
--- a/Tests/RunCMake/ctest_memcheck/testAddressLeakSanitizer.cmake
+++ b/Tests/RunCMake/ctest_memcheck/testAddressLeakSanitizer.cmake
@@ -2,7 +2,7 @@
 # options
 
 message("ASAN_OPTIONS = [$ENV{ASAN_OPTIONS}]")
-string(REGEX REPLACE ".*log_path=\'([^\']*)\'.*" "\\1" LOG_FILE "$ENV{ASAN_OPTIONS}")
+string(REGEX REPLACE ".*log_path='([^']*)'.*" "\\1" LOG_FILE "$ENV{ASAN_OPTIONS}")
 message("LOG_FILE=[${LOG_FILE}]")
 
 # if we are not asked to simulate AddressSanitizer don't do it
diff --git a/Tests/RunCMake/ctest_memcheck/testAddressSanitizer.cmake b/Tests/RunCMake/ctest_memcheck/testAddressSanitizer.cmake
index 1219666..8f18cd0 100644
--- a/Tests/RunCMake/ctest_memcheck/testAddressSanitizer.cmake
+++ b/Tests/RunCMake/ctest_memcheck/testAddressSanitizer.cmake
@@ -2,7 +2,7 @@
 # options
 
 message("ASAN_OPTIONS = [$ENV{ASAN_OPTIONS}]")
-string(REGEX REPLACE ".*log_path=\'([^\']*)\'.*" "\\1" LOG_FILE "$ENV{ASAN_OPTIONS}")
+string(REGEX REPLACE ".*log_path='([^']*)'.*" "\\1" LOG_FILE "$ENV{ASAN_OPTIONS}")
 message("LOG_FILE=[${LOG_FILE}]")
 
 # if we are not asked to simulate address sanitizer don't do it
diff --git a/Tests/RunCMake/ctest_memcheck/testCudaMemcheck.cmake b/Tests/RunCMake/ctest_memcheck/testCudaMemcheck.cmake
new file mode 100644
index 0000000..adc7a1a
--- /dev/null
+++ b/Tests/RunCMake/ctest_memcheck/testCudaMemcheck.cmake
@@ -0,0 +1,279 @@
+# this file simulates an execution of cuda-memcheck
+
+set(LOG_FILE "$ENV{PSEUDO_LOGFILE}")
+message("LOG_FILE=[${LOG_FILE}]")
+
+# clear the log file
+file(REMOVE "${LOG_FILE}")
+
+# create an error of each type of sanitizer tool and failure
+
+# initcheck
+file(APPEND "${LOG_FILE}"
+"========= CUDA-MEMCHECK
+========= Uninitialized __global__ memory read of size 4
+=========     at 0x00000020 in test(int*, int*)
+=========     by thread (0,0,0) in block (0,0,0)
+=========     Address 0x1303d80000
+=========     Saved host backtrace up to driver entry point
+=========     Host Frame:/lib64/libcuda.so.1 (cuLaunchKernel + 0x346) [0x297db6]
+=========     Host Frame:./uninit-read [0x101d9]
+=========     Host Frame:./uninit-read [0x10267]
+=========     Host Frame:./uninit-read [0x465b5]
+=========     Host Frame:./uninit-read [0x3342]
+=========     Host Frame:./uninit-read [0x3143]
+=========     Host Frame:/lib64/libc.so.6 (__libc_start_main + 0xf5) [0x22505]
+=========     Host Frame:./uninit-read [0x31e2]
+=========
+========= Unused memory in allocation 0x1303d80000 of size 16 bytes
+=========     Not written any memory.
+=========     100.00% of allocation were unused.
+=========     Saved host backtrace up to driver entry point
+=========     Host Frame:/lib64/libcuda.so.1 (cuMemAlloc_v2 + 0x1b7) [0x26ec97]
+=========     Host Frame:./uninit-read [0x2bbd3]
+=========     Host Frame:./uninit-read [0x71ab]
+=========     Host Frame:./uninit-read [0x3c84f]
+=========     Host Frame:./uninit-read [0x3111]
+=========     Host Frame:/lib64/libc.so.6 (__libc_start_main + 0xf5) [0x22505]
+=========     Host Frame:./uninit-read [0x31e2]
+=========
+========= Host API memory access error at host access to 0x1303fd1400 of size 25600 bytes
+=========     Uninitialized access at 0x1303fd4600 on access by cudaMemcopy source.
+=========     Saved host backtrace up to driver entry point at error
+=========     Host Frame:/usr/lib/x86_64-linux-gnu/libcuda.so.1 (cuMemcpyDtoH_v2 + 0x1ec) [0x29200c]
+=========     Host Frame:/usr/local/cuda/targets/x86_64-linux/lib/libcudart.so.10.1 [0x38aaa]
+=========     Host Frame:/usr/local/cuda/targets/x86_64-linux/lib/libcudart.so.10.1 [0x18946]
+=========     Host Frame:/usr/local/cuda/targets/x86_64-linux/lib/libcudart.so.10.1 (cudaMemcpy + 0x1a2) [0x3b8c2]
+=========     Host Frame:/something/somewhere [0xcafe]
+=========
+========= ERROR SUMMARY: 2 errors
+")
+
+
+# synccheck
+file(APPEND "${LOG_FILE}"
+"========= CUDA-MEMCHECK
+========= Barrier error detected. Divergent thread(s) in warp
+=========     at 0x00000058 in test(int*, int*)
+=========     by thread (1,0,0) in block (0,0,0)
+=========     Device Frame:test(int*, int*) (test(int*, int*) : 0x60)
+=========     Saved host backtrace up to driver entry point at kernel launch time
+=========     Host Frame:/lib64/libcuda.so.1 (cuLaunchKernel + 0x346) [0x297db6]
+=========     Host Frame:./sync [0x101d9]
+=========     Host Frame:./sync [0x10267]
+=========     Host Frame:./sync [0x465b5]
+=========     Host Frame:./sync [0x3342]
+=========     Host Frame:./sync [0x314a]
+=========     Host Frame:/lib64/libc.so.6 (__libc_start_main + 0xf5) [0x22505]
+=========     Host Frame:./sync [0x31e2]
+=========
+========= Barrier error detected. Divergent thread(s) in warp
+=========     at 0x00000058 in test(int*, int*)
+=========     by thread (0,0,0) in block (0,0,0)
+=========     Device Frame:test(int*, int*) (test(int*, int*) : 0x60)
+=========     Saved host backtrace up to driver entry point at kernel launch time
+=========     Host Frame:/lib64/libcuda.so.1 (cuLaunchKernel + 0x346) [0x297db6]
+=========     Host Frame:./sync [0x101d9]
+=========     Host Frame:./sync [0x10267]
+=========     Host Frame:./sync [0x465b5]
+=========     Host Frame:./sync [0x3342]
+=========     Host Frame:./sync [0x314a]
+=========     Host Frame:/lib64/libc.so.6 (__libc_start_main + 0xf5) [0x22505]
+=========     Host Frame:./sync [0x31e2]
+=========
+========= ERROR SUMMARY: 2 errors
+")
+
+# memcheck
+file(APPEND "${LOG_FILE}"
+"========= CUDA-MEMCHECK
+========= Invalid __global__ read of size 4
+=========     at 0x00000020 in test(int*, int*)
+=========     by thread (0,0,0) in block (0,0,0)
+=========     Address 0x00000000 is out of bounds
+=========     Saved host backtrace up to driver entry point at kernel launch time
+=========     Host Frame:/lib64/libcuda.so.1 (cuLaunchKernel + 0x346) [0x297db6]
+=========     Host Frame:./invalid-read [0x101d9]
+=========     Host Frame:./invalid-read [0x10267]
+=========     Host Frame:./invalid-read [0x465b5]
+=========     Host Frame:./invalid-read [0x3342]
+=========     Host Frame:./invalid-read [0x3142]
+=========     Host Frame:/lib64/libc.so.6 (__libc_start_main + 0xf5) [0x22505]
+=========     Host Frame:./invalid-read [0x31e2]
+=========
+========= Program hit cudaErrorLaunchFailure (error 719) due to \"unspecified launch failure\" on CUDA API call to cudaDeviceSynchronize.
+=========     Saved host backtrace up to driver entry point at error
+=========     Host Frame:/lib64/libcuda.so.1 [0x3ac5a3]
+=========     Host Frame:./invalid-read [0x2e576]
+=========     Host Frame:./invalid-read [0x3147]
+=========     Host Frame:/lib64/libc.so.6 (__libc_start_main + 0xf5) [0x22505]
+=========     Host Frame:./invalid-read [0x31e2]
+=========
+========= Program hit cudaErrorLaunchFailure (error 719) due to \"unspecified launch failure\" on CUDA API call to cudaFree.
+=========     Saved host backtrace up to driver entry point at error
+=========     Host Frame:/lib64/libcuda.so.1 [0x3ac5a3]
+=========     Host Frame:./invalid-read [0x3c106]
+=========     Host Frame:./invalid-read [0x3150]
+=========     Host Frame:/lib64/libc.so.6 (__libc_start_main + 0xf5) [0x22505]
+=========     Host Frame:./invalid-read [0x31e2]
+=========
+========= Fatal UVM GPU fault of type invalid pde due to invalid address
+=========     during atomic access to address 0x20be00000
+=========
+========= Fatal UVM CPU fault due to invalid operation
+=========     during read access to address 0x1357c92000
+=========
+========= LEAK SUMMARY: 0 bytes leaked in 0 allocations
+========= ERROR SUMMARY: 3 errors
+")
+
+# memcheck with leak-check full
+file(APPEND "${LOG_FILE}"
+"========= CUDA-MEMCHECK
+========= Leaked 10 bytes at 0x1303d80000
+=========     Saved host backtrace up to driver entry point at cudaMalloc time
+=========     Host Frame:/lib64/libcuda.so.1 (cuMemAlloc_v2 + 0x1b7) [0x26ec97]
+=========     Host Frame:./leak [0x2bab3]
+=========     Host Frame:./leak [0x708b]
+=========     Host Frame:./leak [0x3c72f]
+=========     Host Frame:./leak [0x3113]
+=========     Host Frame:/lib64/libc.so.6 (__libc_start_main + 0xf5) [0x22505]
+=========     Host Frame:./leak [0x3174]
+=========
+========= LEAK SUMMARY: 10 bytes leaked in 1 allocations
+========= ERROR SUMMARY: 1 error
+")
+
+# racecheck with racecheck-report all
+file(APPEND "${LOG_FILE}"
+"========= CUDA-MEMCHECK
+========= WARN:(Warp Level Programming) Potential WAR hazard detected at __shared__ 0x3 in block (0, 0, 0) :
+=========     Read Thread (31, 0, 0) at 0x00000170 in ./race.cu:4:test(int*, int*)
+=========     Write Thread (0, 0, 0) at 0x000001a8 in ./race.cu:4:test(int*, int*)
+=========     Current Value : 0, Incoming Value : 0
+=========     Saved host backtrace up to driver entry point at kernel launch time
+=========     Host Frame:/lib64/libcuda.so.1 (cuLaunchKernel + 0x346) [0x297db6]
+=========     Host Frame:./race [0x101d9]
+=========     Host Frame:./race [0x10267]
+=========     Host Frame:./race [0x465b5]
+=========     Host Frame:./race [0x3342]
+=========     Host Frame:./race [0x314a]
+=========     Host Frame:/lib64/libc.so.6 (__libc_start_main + 0xf5) [0x22505]
+=========     Host Frame:./race [0x31e2]
+=========
+========= WARN:(Warp Level Programming) Potential WAR hazard detected at __shared__ 0x2 in block (0, 0, 0) :
+=========     Read Thread (31, 0, 0) at 0x00000170 in ./race.cu:4:test(int*, int*)
+=========     Write Thread (0, 0, 0) at 0x000001a8 in ./race.cu:4:test(int*, int*)
+=========     Current Value : 0, Incoming Value : 0
+=========     Saved host backtrace up to driver entry point at kernel launch time
+=========     Host Frame:/lib64/libcuda.so.1 (cuLaunchKernel + 0x346) [0x297db6]
+=========     Host Frame:./race [0x101d9]
+=========     Host Frame:./race [0x10267]
+=========     Host Frame:./race [0x465b5]
+=========     Host Frame:./race [0x3342]
+=========     Host Frame:./race [0x314a]
+=========     Host Frame:/lib64/libc.so.6 (__libc_start_main + 0xf5) [0x22505]
+=========     Host Frame:./race [0x31e2]
+=========
+========= WARN:(Warp Level Programming) Potential WAR hazard detected at __shared__ 0x1 in block (0, 0, 0) :
+=========     Read Thread (31, 0, 0) at 0x00000170 in ./race.cu:4:test(int*, int*)
+=========     Write Thread (0, 0, 0) at 0x000001a8 in ./race.cu:4:test(int*, int*)
+=========     Current Value : 0, Incoming Value : 0
+=========     Saved host backtrace up to driver entry point at kernel launch time
+=========     Host Frame:/lib64/libcuda.so.1 (cuLaunchKernel + 0x346) [0x297db6]
+=========     Host Frame:./race [0x101d9]
+=========     Host Frame:./race [0x10267]
+=========     Host Frame:./race [0x465b5]
+=========     Host Frame:./race [0x3342]
+=========     Host Frame:./race [0x314a]
+=========     Host Frame:/lib64/libc.so.6 (__libc_start_main + 0xf5) [0x22505]
+=========     Host Frame:./race [0x31e2]
+=========
+========= WARN:(Warp Level Programming) Potential WAR hazard detected at __shared__ 0x0 in block (0, 0, 0) :
+=========     Read Thread (31, 0, 0) at 0x00000170 in ./race.cu:4:test(int*, int*)
+=========     Write Thread (0, 0, 0) at 0x000001a8 in ./race.cu:4:test(int*, int*)
+=========     Current Value : 0, Incoming Value : 1
+=========     Saved host backtrace up to driver entry point at kernel launch time
+=========     Host Frame:/lib64/libcuda.so.1 (cuLaunchKernel + 0x346) [0x297db6]
+=========     Host Frame:./race [0x101d9]
+=========     Host Frame:./race [0x10267]
+=========     Host Frame:./race [0x465b5]
+=========     Host Frame:./race [0x3342]
+=========     Host Frame:./race [0x314a]
+=========     Host Frame:/lib64/libc.so.6 (__libc_start_main + 0xf5) [0x22505]
+=========     Host Frame:./race [0x31e2]
+=========
+========= WARN:(Warp Level Programming) Potential RAW hazard detected at __shared__ 0x3 in block (0, 0, 0) :
+=========     Write Thread (31, 0, 0) at 0x00000148 in ./race.cu:3:test(int*, int*)
+=========     Read Thread (0, 0, 0) at 0x00000170 in ./race.cu:4:test(int*, int*)
+=========     Current Value : 0
+=========     Saved host backtrace up to driver entry point at kernel launch time
+=========     Host Frame:/lib64/libcuda.so.1 (cuLaunchKernel + 0x346) [0x297db6]
+=========     Host Frame:./race [0x101d9]
+=========     Host Frame:./race [0x10267]
+=========     Host Frame:./race [0x465b5]
+=========     Host Frame:./race [0x3342]
+=========     Host Frame:./race [0x314a]
+=========     Host Frame:/lib64/libc.so.6 (__libc_start_main + 0xf5) [0x22505]
+=========     Host Frame:./race [0x31e2]
+=========
+========= WARN:(Warp Level Programming) Potential RAW hazard detected at __shared__ 0x2 in block (0, 0, 0) :
+=========     Write Thread (31, 0, 0) at 0x00000148 in ./race.cu:3:test(int*, int*)
+=========     Read Thread (0, 0, 0) at 0x00000170 in ./race.cu:4:test(int*, int*)
+=========     Current Value : 0
+=========     Saved host backtrace up to driver entry point at kernel launch time
+=========     Host Frame:/lib64/libcuda.so.1 (cuLaunchKernel + 0x346) [0x297db6]
+=========     Host Frame:./race [0x101d9]
+=========     Host Frame:./race [0x10267]
+=========     Host Frame:./race [0x465b5]
+=========     Host Frame:./race [0x3342]
+=========     Host Frame:./race [0x314a]
+=========     Host Frame:/lib64/libc.so.6 (__libc_start_main + 0xf5) [0x22505]
+=========     Host Frame:./race [0x31e2]
+=========
+========= WARN:(Warp Level Programming) Potential RAW hazard detected at __shared__ 0x1 in block (0, 0, 0) :
+=========     Write Thread (31, 0, 0) at 0x00000148 in ./race.cu:3:test(int*, int*)
+=========     Read Thread (0, 0, 0) at 0x00000170 in ./race.cu:4:test(int*, int*)
+=========     Current Value : 0
+=========     Saved host backtrace up to driver entry point at kernel launch time
+=========     Host Frame:/lib64/libcuda.so.1 (cuLaunchKernel + 0x346) [0x297db6]
+=========     Host Frame:./race [0x101d9]
+=========     Host Frame:./race [0x10267]
+=========     Host Frame:./race [0x465b5]
+=========     Host Frame:./race [0x3342]
+=========     Host Frame:./race [0x314a]
+=========     Host Frame:/lib64/libc.so.6 (__libc_start_main + 0xf5) [0x22505]
+=========     Host Frame:./race [0x31e2]
+=========
+========= WARN:(Warp Level Programming) Potential RAW hazard detected at __shared__ 0x0 in block (0, 0, 0) :
+=========     Write Thread (31, 0, 0) at 0x00000148 in ./race.cu:3:test(int*, int*)
+=========     Read Thread (0, 0, 0) at 0x00000170 in ./race.cu:4:test(int*, int*)
+=========     Current Value : 0
+=========     Saved host backtrace up to driver entry point at kernel launch time
+=========     Host Frame:/lib64/libcuda.so.1 (cuLaunchKernel + 0x346) [0x297db6]
+=========     Host Frame:./race [0x101d9]
+=========     Host Frame:./race [0x10267]
+=========     Host Frame:./race [0x465b5]
+=========     Host Frame:./race [0x3342]
+=========     Host Frame:./race [0x314a]
+=========     Host Frame:/lib64/libc.so.6 (__libc_start_main + 0xf5) [0x22505]
+=========     Host Frame:./race [0x31e2]
+=========
+========= WARN: Race reported between Read access at 0x00000170 in ./race.cu:4:test(int*, int*)
+=========     and Write access at 0x00000148 in ./race.cu:3:test(int*, int*) [4 hazards]
+=========     and Write access at 0x000001a8 in ./race.cu:4:test(int*, int*) [4 hazards]
+=========
+========= WARN: Race reported between Write access at 0x00000148 in ./race.cu:3:test(int*, int*)
+=========     and Write access at 0x00000148 in ./race.cu:3:test(int*, int*) [124 hazards]
+=========     and Read access at 0x00000170 in ./race.cu:4:test(int*, int*) [4 hazards]
+=========
+========= WARN: Race reported between Write access at 0x000001a8 in ./race.cu:4:test(int*, int*)
+=========     and Write access at 0x000001a8 in ./race.cu:4:test(int*, int*) [124 hazards]
+=========     and Read access at 0x00000170 in ./race.cu:4:test(int*, int*) [4 hazards]
+=========
+========= WARN: Race reported between Write access at 0x00000148 in ./race.cu:3:test(int*, int*)
+=========     and Write access at 0x00000148 in ./race.cu:3:test(int*, int*) [124 hazards]
+=========     and Read access at 0x00000170 in ./race.cu:4:test(int*, int*) [4 hazards]
+=========
+========= RACECHECK SUMMARY: 12 hazards displayed (0 errors, 12 warnings)
+")
diff --git a/Tests/RunCMake/ctest_memcheck/testLeakSanitizer.cmake b/Tests/RunCMake/ctest_memcheck/testLeakSanitizer.cmake
index 6d51f83..4990792 100644
--- a/Tests/RunCMake/ctest_memcheck/testLeakSanitizer.cmake
+++ b/Tests/RunCMake/ctest_memcheck/testLeakSanitizer.cmake
@@ -2,7 +2,7 @@
 # options
 
 message("LSAN_OPTIONS = [$ENV{LSAN_OPTIONS}]")
-string(REGEX REPLACE ".*log_path=\'([^\']*)\'.*" "\\1" LOG_FILE "$ENV{LSAN_OPTIONS}")
+string(REGEX REPLACE ".*log_path='([^']*)'.*" "\\1" LOG_FILE "$ENV{LSAN_OPTIONS}")
 message("LOG_FILE=[${LOG_FILE}]")
 
 # if we are not asked to simulate LeakSanitizer don't do it
diff --git a/Tests/RunCMake/ctest_memcheck/testMemorySanitizer.cmake b/Tests/RunCMake/ctest_memcheck/testMemorySanitizer.cmake
index 3b3ac22..4a6adb1 100644
--- a/Tests/RunCMake/ctest_memcheck/testMemorySanitizer.cmake
+++ b/Tests/RunCMake/ctest_memcheck/testMemorySanitizer.cmake
@@ -2,7 +2,7 @@
 # options
 
 message("MSAN_OPTIONS = [$ENV{MSAN_OPTIONS}]")
-string(REGEX REPLACE ".*log_path=\'([^\']*)\'.*" "\\1" LOG_FILE "$ENV{MSAN_OPTIONS}")
+string(REGEX REPLACE ".*log_path='([^']*)'.*" "\\1" LOG_FILE "$ENV{MSAN_OPTIONS}")
 message("LOG_FILE=[${LOG_FILE}]")
 
 # if we are not asked to simulate address sanitizer don't do it
diff --git a/Tests/RunCMake/ctest_memcheck/testThreadSanitizer.cmake b/Tests/RunCMake/ctest_memcheck/testThreadSanitizer.cmake
index e7a5c9f..96251c3 100644
--- a/Tests/RunCMake/ctest_memcheck/testThreadSanitizer.cmake
+++ b/Tests/RunCMake/ctest_memcheck/testThreadSanitizer.cmake
@@ -2,7 +2,7 @@
 # options
 
 message("TSAN_OPTIONS = [$ENV{TSAN_OPTIONS}]")
-string(REGEX REPLACE ".*log_path=\'([^\']*)\'.*" "\\1" LOG_FILE "$ENV{TSAN_OPTIONS}")
+string(REGEX REPLACE ".*log_path='([^']*)'.*" "\\1" LOG_FILE "$ENV{TSAN_OPTIONS}")
 message("LOG_FILE=[${LOG_FILE}]")
 
 set(error_types
diff --git a/Tests/RunCMake/ctest_memcheck/testUndefinedBehaviorSanitizer.cmake b/Tests/RunCMake/ctest_memcheck/testUndefinedBehaviorSanitizer.cmake
index ba6122d..7160280 100644
--- a/Tests/RunCMake/ctest_memcheck/testUndefinedBehaviorSanitizer.cmake
+++ b/Tests/RunCMake/ctest_memcheck/testUndefinedBehaviorSanitizer.cmake
@@ -2,7 +2,7 @@
 # UndefinedBehaviorSanitizer options
 
 message("UBSAN_OPTIONS = [$ENV{UBSAN_OPTIONS}]")
-string(REGEX REPLACE ".*log_path=\'([^\']*)\'.*" "\\1" LOG_FILE "$ENV{UBSAN_OPTIONS}")
+string(REGEX REPLACE ".*log_path='([^']*)'.*" "\\1" LOG_FILE "$ENV{UBSAN_OPTIONS}")
 message("LOG_FILE=[${LOG_FILE}]")
 
 # if we are not asked to simulate address sanitizer don't do it
diff --git a/Tests/RunCMake/ctest_start/NoStartTimeNightly-result.txt b/Tests/RunCMake/ctest_start/NoStartTimeNightly-result.txt
new file mode 100644
index 0000000..b57e2de
--- /dev/null
+++ b/Tests/RunCMake/ctest_start/NoStartTimeNightly-result.txt
@@ -0,0 +1 @@
+(-1|255)
diff --git a/Tests/RunCMake/ctest_start/NoStartTimeNightly-stderr.txt b/Tests/RunCMake/ctest_start/NoStartTimeNightly-stderr.txt
new file mode 100644
index 0000000..79756eb
--- /dev/null
+++ b/Tests/RunCMake/ctest_start/NoStartTimeNightly-stderr.txt
@@ -0,0 +1,4 @@
+^WARNING: No nightly start time found please set in CTestConfig\.cmake or DartConfig\.cmake
+CMake Error at [^
+]*/Tests/RunCMake/ctest_start/NoStartTimeNightly/test\.cmake:[0-9]+ \(ctest_start\):
+  ctest_start unknown error\.$
diff --git a/Tests/RunCMake/ctest_start/RunCMakeTest.cmake b/Tests/RunCMake/ctest_start/RunCMakeTest.cmake
index da85b39..f11f1ec 100644
--- a/Tests/RunCMake/ctest_start/RunCMakeTest.cmake
+++ b/Tests/RunCMake/ctest_start/RunCMakeTest.cmake
@@ -48,6 +48,8 @@
                 ${RunCMake_BINARY_DIR}/TooManyArgs-build
                 ${RunCMake_BINARY_DIR}/TooManyArgs-build
                 ${RunCMake_BINARY_DIR}/TooManyArgs-build)
+run_ctest_start(NoStartTimeExperimental Experimental)
+run_ctest_start(NoStartTimeNightly Nightly)
 
 function(run_ConfigInBuild)
   set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/ConfigInBuild-build)
diff --git a/Tests/RunCMake/ctest_start/test.cmake.in b/Tests/RunCMake/ctest_start/test.cmake.in
index 8cd3cff..4063ece 100644
--- a/Tests/RunCMake/ctest_start/test.cmake.in
+++ b/Tests/RunCMake/ctest_start/test.cmake.in
@@ -8,7 +8,9 @@
 set(CTEST_CMAKE_GENERATOR_PLATFORM      "@RunCMake_GENERATOR_PLATFORM@")
 set(CTEST_CMAKE_GENERATOR_TOOLSET       "@RunCMake_GENERATOR_TOOLSET@")
 set(CTEST_BUILD_CONFIGURATION           "$ENV{CMAKE_CONFIG_TYPE}")
-set(CTEST_NIGHTLY_START_TIME            "01:00:00 UTC")
+if(NOT "@CASE_NAME@" MATCHES "^NoStartTime")
+  set(CTEST_NIGHTLY_START_TIME            "01:00:00 UTC")
+endif()
 
 function(setup_tests)
   ctest_start(${ctest_start_args})
diff --git a/Tests/RunCMake/ctest_test/RunCMakeTest.cmake b/Tests/RunCMake/ctest_test/RunCMakeTest.cmake
index d0a6e5f..b82335f 100644
--- a/Tests/RunCMake/ctest_test/RunCMakeTest.cmake
+++ b/Tests/RunCMake/ctest_test/RunCMakeTest.cmake
@@ -121,3 +121,26 @@
   ]])
 run_TestRepeat(NotRun RETURN_VALUE:1 REPEAT UNTIL_PASS:3)
 unset(CASE_CMAKELISTS_SUFFIX_CODE)
+
+# test --stop-on-failure
+function(run_stop_on_failure)
+  set(CASE_CTEST_TEST_ARGS EXCLUDE RunCMakeVersion)
+  set(CASE_CMAKELISTS_SUFFIX_CODE [[
+add_test(NAME StoppingTest COMMAND ${CMAKE_COMMAND} -E false)
+add_test(NAME NotRunTest COMMAND ${CMAKE_COMMAND} -E true)
+  ]])
+
+  run_ctest_test(stop-on-failure STOP_ON_FAILURE)
+endfunction()
+run_stop_on_failure()
+
+# Make sure environment gets logged
+function(run_environment)
+  set(ENV{BAD_ENVIRONMENT_VARIABLE} "Bad environment variable")
+  set(CASE_CMAKELISTS_SUFFIX_CODE [[
+set_property(TEST RunCMakeVersion PROPERTY ENVIRONMENT "ENV1=env1;ENV2=env2")
+  ]])
+
+  run_ctest(TestEnvironment)
+endfunction()
+run_environment()
diff --git a/Tests/RunCMake/ctest_test/TestEnvironment-check.cmake b/Tests/RunCMake/ctest_test/TestEnvironment-check.cmake
new file mode 100644
index 0000000..91c9731
--- /dev/null
+++ b/Tests/RunCMake/ctest_test/TestEnvironment-check.cmake
@@ -0,0 +1,10 @@
+file(READ "${RunCMake_TEST_BINARY_DIR}/Testing/TAG" _tag)
+string(REGEX REPLACE "^([^\n]*)\n.*$" "\\1" _date "${_tag}")
+file(READ "${RunCMake_TEST_BINARY_DIR}/Testing/${_date}/Test.xml" _test_contents)
+
+if(NOT _test_contents MATCHES "<Value>ENV1=env1\nENV2=env2\n#CTEST_RESOURCE_GROUP_COUNT=</Value>")
+  string(APPEND RunCMake_TEST_FAILED "Could not find expected environment variables in Test.xml")
+endif()
+if(_test_contents MATCHES "BAD_ENVIRONMENT_VARIABLE")
+  string(APPEND RunCMake_TEST_FAILED "Found BAD_ENVIRONMENT_VARIABLE in Test.xml")
+endif()
diff --git a/Tests/RunCMake/ctest_test/stop-on-failure-stdout.txt b/Tests/RunCMake/ctest_test/stop-on-failure-stdout.txt
new file mode 100644
index 0000000..fa4bce0
--- /dev/null
+++ b/Tests/RunCMake/ctest_test/stop-on-failure-stdout.txt
@@ -0,0 +1,13 @@
+Test project [^
+]*/Tests/RunCMake/ctest_test/stop-on-failure-build
+    Start 1: RunCMakeVersion
+1/3 Test #1: RunCMakeVersion ..................   Passed    +[0-9.]+ sec
+    Start 2: StoppingTest
+2/3 Test #2: StoppingTest .....................\*\*\*Failed    +[0-9.]+ sec
++
+50% tests passed, 1 tests failed out of 2
++
+Total Test time \(real\) = +[0-9.]+ sec
++
+The following tests FAILED:
+[	 ]+2 - StoppingTest \(Failed\)$
diff --git a/Tests/RunCMake/ctest_update/test.cmake.in b/Tests/RunCMake/ctest_update/test.cmake.in
index 25b8423..01aab26 100644
--- a/Tests/RunCMake/ctest_update/test.cmake.in
+++ b/Tests/RunCMake/ctest_update/test.cmake.in
@@ -10,7 +10,7 @@
 set(CTEST_CMAKE_GENERATOR_TOOLSET       "@RunCMake_GENERATOR_TOOLSET@")
 set(CTEST_BUILD_CONFIGURATION           "$ENV{CMAKE_CONFIG_TYPE}")
 
-# FIXME: update test to do someting meaningful with this.
+# FIXME: update test to do something meaningful with this.
 set(CTEST_UPDATE_COMMAND                "not-actually-used")
 
 set(ctest_test_args "@CASE_CTEST_UPDATE_ARGS@")
diff --git a/Tests/RunCMake/execute_process/EchoVariable-stderr.txt b/Tests/RunCMake/execute_process/EchoVariable-stderr.txt
new file mode 100644
index 0000000..d927553
--- /dev/null
+++ b/Tests/RunCMake/execute_process/EchoVariable-stderr.txt
@@ -0,0 +1,3 @@
+CMake Error at [^
+]*EchoVariableOutput.cmake:2 \(message\):
+  Text to stderr
diff --git a/Tests/RunCMake/execute_process/EchoVariable-stdout.txt b/Tests/RunCMake/execute_process/EchoVariable-stdout.txt
new file mode 100644
index 0000000..7c868bd
--- /dev/null
+++ b/Tests/RunCMake/execute_process/EchoVariable-stdout.txt
@@ -0,0 +1 @@
+-- Text to stdout
diff --git a/Tests/RunCMake/execute_process/EchoVariable.cmake b/Tests/RunCMake/execute_process/EchoVariable.cmake
new file mode 100644
index 0000000..99999c7
--- /dev/null
+++ b/Tests/RunCMake/execute_process/EchoVariable.cmake
@@ -0,0 +1,23 @@
+execute_process(
+  COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_LIST_DIR}/EchoVariableOutput.cmake
+  OUTPUT_VARIABLE stdout
+  ERROR_QUIET
+  ECHO_OUTPUT_VARIABLE
+)
+
+file(READ ${CMAKE_CURRENT_LIST_DIR}/EchoVariable-stdout.txt expected_stdout)
+if (NOT stdout MATCHES "${expected_stdout}")
+  message(FATAL_ERROR "stdout differs from the expected stdout")
+endif()
+
+execute_process(
+  COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_LIST_DIR}/EchoVariableOutput.cmake
+  ERROR_VARIABLE stderr
+  OUTPUT_QUIET
+  ECHO_ERROR_VARIABLE
+)
+
+file(READ ${CMAKE_CURRENT_LIST_DIR}/EchoVariable-stderr.txt expected_stderr)
+if (NOT stderr MATCHES "${expected_stderr}")
+  message(FATAL_ERROR "stderr differs from the expected stderr")
+endif()
diff --git a/Tests/RunCMake/execute_process/EchoVariableOutput.cmake b/Tests/RunCMake/execute_process/EchoVariableOutput.cmake
new file mode 100644
index 0000000..e636567
--- /dev/null
+++ b/Tests/RunCMake/execute_process/EchoVariableOutput.cmake
@@ -0,0 +1,2 @@
+message(STATUS "Text to stdout")
+message(FATAL_ERROR "Text to stderr")
diff --git a/Tests/RunCMake/execute_process/RunCMakeTest.cmake b/Tests/RunCMake/execute_process/RunCMakeTest.cmake
index b203aab..89ad6b2 100644
--- a/Tests/RunCMake/execute_process/RunCMakeTest.cmake
+++ b/Tests/RunCMake/execute_process/RunCMakeTest.cmake
@@ -24,3 +24,5 @@
 run_cmake_command(EchoCommand3 ${CMAKE_COMMAND}
   -DCHECK_ERROR_OUTPUT_LOCATION=TRUE -P
   ${RunCMake_SOURCE_DIR}/EchoCommand.cmake)
+
+run_cmake_command(EchoVariable ${CMAKE_COMMAND} -P ${RunCMake_SOURCE_DIR}/EchoVariable.cmake)
diff --git a/Tests/RunCMake/exit_code.c b/Tests/RunCMake/exit_code.c
index 3eba019..9fa8eca 100644
--- a/Tests/RunCMake/exit_code.c
+++ b/Tests/RunCMake/exit_code.c
@@ -21,7 +21,8 @@
   }
   if (strcmp(str, substring_success) == 0) {
     return EXIT_SUCCESS;
-  } else if (strcmp(str, substring_failure) == 0) {
+  }
+  if (strcmp(str, substring_failure) == 0) {
     return EXIT_FAILURE;
   }
   fprintf(stderr, "Failed to find string '%s' in '%s'\n", substring_success,
diff --git a/Tests/RunCMake/export/CMakeLists.txt b/Tests/RunCMake/export/CMakeLists.txt
index 12cd3c7..74b3ff8 100644
--- a/Tests/RunCMake/export/CMakeLists.txt
+++ b/Tests/RunCMake/export/CMakeLists.txt
@@ -1,3 +1,3 @@
-cmake_minimum_required(VERSION 2.8.4)
+cmake_minimum_required(VERSION 3.3)
 project(${RunCMake_TEST} NONE)
 include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/export/DependOnDoubleExport-stderr.txt b/Tests/RunCMake/export/DependOnDoubleExport-stderr.txt
index b78c7e4..e8f8a09 100644
--- a/Tests/RunCMake/export/DependOnDoubleExport-stderr.txt
+++ b/Tests/RunCMake/export/DependOnDoubleExport-stderr.txt
@@ -3,8 +3,7 @@
   that is not in this export set, but in multiple other export sets:
   .*/Tests/RunCMake/export/DependOnDoubleExport-build/exportset.cmake,
   .*/Tests/RunCMake/export/DependOnDoubleExport-build/manual.cmake.
-
-
++
   An exported target cannot depend upon another target which is exported
   multiple times.  Consider consolidating the exports of the "doubleexported"
   target to a single export.
diff --git a/Tests/RunCMake/Languages/LINK_LANGUAGE-genex-result.txt b/Tests/RunCMake/export/Repeat-CMP0103-NEW-result.txt
similarity index 100%
copy from Tests/RunCMake/Languages/LINK_LANGUAGE-genex-result.txt
copy to Tests/RunCMake/export/Repeat-CMP0103-NEW-result.txt
diff --git a/Tests/RunCMake/export/Repeat-CMP0103-NEW-stderr.txt b/Tests/RunCMake/export/Repeat-CMP0103-NEW-stderr.txt
new file mode 100644
index 0000000..48ab7b1
--- /dev/null
+++ b/Tests/RunCMake/export/Repeat-CMP0103-NEW-stderr.txt
@@ -0,0 +1,17 @@
+CMake Error at Repeat.cmake:[0-9]+ \(export\):
+  export command already specified for the file
+
+    foo.cmake
+
+  Did you miss 'APPEND' keyword\?
+Call Stack \(most recent call first\):
+  Repeat-CMP0103-NEW.cmake:[0-9]+ \(include\)
+  CMakeLists.txt:[0-9]+ \(include\)
+
+
+CMake Error at Repeat/CMakeLists.txt:[0-9]+ \(export\):
+  export command already specified for the file
+
+    .+/foo.cmake
+
+  Did you miss 'APPEND' keyword\?
diff --git a/Tests/RunCMake/export/Repeat-CMP0103-NEW.cmake b/Tests/RunCMake/export/Repeat-CMP0103-NEW.cmake
new file mode 100644
index 0000000..69381df
--- /dev/null
+++ b/Tests/RunCMake/export/Repeat-CMP0103-NEW.cmake
@@ -0,0 +1,2 @@
+cmake_policy(SET CMP0103 NEW)
+include(Repeat.cmake)
diff --git a/Tests/RunCMake/export/Repeat-CMP0103-OLD.cmake b/Tests/RunCMake/export/Repeat-CMP0103-OLD.cmake
new file mode 100644
index 0000000..25134d6
--- /dev/null
+++ b/Tests/RunCMake/export/Repeat-CMP0103-OLD.cmake
@@ -0,0 +1,2 @@
+cmake_policy(SET CMP0103 OLD)
+include(Repeat.cmake)
diff --git a/Tests/RunCMake/export/Repeat-CMP0103-WARN-stderr.txt b/Tests/RunCMake/export/Repeat-CMP0103-WARN-stderr.txt
new file mode 100644
index 0000000..28e849d
--- /dev/null
+++ b/Tests/RunCMake/export/Repeat-CMP0103-WARN-stderr.txt
@@ -0,0 +1,26 @@
+CMake Warning \(dev\) at Repeat.cmake:[0-9]+ \(export\):
+  Policy CMP0103 is not set: Multiple export\(\) with same FILE without APPEND
+  is not allowed.  Run "cmake --help-policy CMP0103" for policy details.  Use
+  the cmake_policy command to set the policy and suppress this warning.
+
+  export\(\) command already specified for the file
+
+    foo.cmake
+
+  Did you miss 'APPEND' keyword\?
+Call Stack \(most recent call first\):
+  Repeat-CMP0103-WARN.cmake:[0-9]+ \(include\)
+  CMakeLists.txt:[0-9]+ \(include\)
+This warning is for project developers.  Use -Wno-dev to suppress it.
+
+CMake Warning \(dev\) at Repeat/CMakeLists.txt:[0-9]+ \(export\):
+  Policy CMP0103 is not set: Multiple export\(\) with same FILE without APPEND
+  is not allowed.  Run "cmake --help-policy CMP0103" for policy details.  Use
+  the cmake_policy command to set the policy and suppress this warning.
+
+  export\(\) command already specified for the file
+
+    .+/foo.cmake
+
+  Did you miss 'APPEND' keyword\?
+This warning is for project developers.  Use -Wno-dev to suppress it.
diff --git a/Tests/RunCMake/export/Repeat-CMP0103-WARN.cmake b/Tests/RunCMake/export/Repeat-CMP0103-WARN.cmake
new file mode 100644
index 0000000..3a630c5
--- /dev/null
+++ b/Tests/RunCMake/export/Repeat-CMP0103-WARN.cmake
@@ -0,0 +1 @@
+include(Repeat.cmake)
diff --git a/Tests/RunCMake/export/RunCMakeTest.cmake b/Tests/RunCMake/export/RunCMakeTest.cmake
index df35d95..1c74762 100644
--- a/Tests/RunCMake/export/RunCMakeTest.cmake
+++ b/Tests/RunCMake/export/RunCMakeTest.cmake
@@ -2,7 +2,9 @@
 
 run_cmake(CustomTarget)
 run_cmake(Empty)
-run_cmake(Repeat)
+run_cmake(Repeat-CMP0103-WARN)
+run_cmake(Repeat-CMP0103-OLD)
+run_cmake(Repeat-CMP0103-NEW)
 run_cmake(TargetNotFound)
 run_cmake(AppendExport)
 run_cmake(OldIface)
diff --git a/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/CMakeLists.txt b/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/CMakeLists.txt
new file mode 100644
index 0000000..2632ffa
--- /dev/null
+++ b/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/CMakeLists.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 3.16)
+project(${RunCMake_TEST} NONE)
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/RunCMakeTest.cmake b/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/RunCMakeTest.cmake
new file mode 100644
index 0000000..763d57c
--- /dev/null
+++ b/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/RunCMakeTest.cmake
@@ -0,0 +1,55 @@
+cmake_minimum_required(VERSION 3.16)
+include(RunCMake)
+
+# Function to build and install a project.
+function(run_install_test case)
+  set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/${case}-build)
+  set(RunCMake_TEST_NO_CLEAN 1)
+  file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}")
+  file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}")
+  run_cmake(${case})
+  run_cmake_command(${case}-build ${CMAKE_COMMAND} --build . --config Debug)
+  # Check "all" components.
+  set(CMAKE_INSTALL_PREFIX ${RunCMake_TEST_BINARY_DIR}/root-all)
+  run_cmake_command(${case}-all ${CMAKE_COMMAND} -DCMAKE_INSTALL_PREFIX=${CMAKE_INSTALL_PREFIX} -DBUILD_TYPE=Debug -P cmake_install.cmake)
+endfunction()
+
+if(CMAKE_HOST_SYSTEM_NAME STREQUAL "Darwin")
+  if(NOT CMake_INSTALL_NAME_TOOL_BUG)
+    run_install_test(macos)
+    run_install_test(macos-unresolved)
+    run_install_test(macos-conflict)
+    run_install_test(macos-notfile)
+  endif()
+  run_cmake(project)
+  run_cmake(badargs1)
+  run_cmake(badargs2)
+elseif(CMAKE_HOST_SYSTEM_NAME STREQUAL "Windows")
+  run_install_test(windows)
+  run_install_test(windows-unresolved)
+  run_install_test(windows-conflict)
+  run_install_test(windows-notfile)
+  run_cmake(project)
+  run_cmake(badargs1)
+  run_cmake(badargs2)
+elseif(CMAKE_HOST_SYSTEM_NAME STREQUAL "Linux")
+  if(DEFINED ENV{LDFLAGS})
+    # Some setups prebake disable-new-dtags into LDFLAGS
+    string(REPLACE "-Wl,--disable-new-dtags" "" new_ldflags "$ENV{LDFLAGS}")
+    set(ENV{LDFLAGS} "${new_ldflags}")
+  endif()
+
+  if(NOT CMAKE_C_COMPILER_ID MATCHES "^XL")
+    run_install_test(linux)
+  endif()
+  run_install_test(linux-unresolved)
+  run_install_test(linux-conflict)
+  run_install_test(linux-notfile)
+  run_cmake(project)
+  run_cmake(badargs1)
+  run_cmake(badargs2)
+else()
+  run_cmake(unsupported)
+endif()
+
+run_install_test(variable-propagation)
diff --git a/Tests/RunCMake/interface_library/whitelist-result.txt b/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/badargs1-result.txt
similarity index 100%
copy from Tests/RunCMake/interface_library/whitelist-result.txt
copy to Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/badargs1-result.txt
diff --git a/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/badargs1-stderr.txt b/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/badargs1-stderr.txt
new file mode 100644
index 0000000..0874473
--- /dev/null
+++ b/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/badargs1-stderr.txt
@@ -0,0 +1,18 @@
+^CMake Warning \(dev\) at badargs1\.cmake:[0-9]+ \(file\):
+  You have used file\(GET_RUNTIME_DEPENDENCIES\) in project mode\.  This is
+  probably not what you intended to do\.  Instead, please consider using it in
+  an install\(CODE\) or install\(SCRIPT\) command\.  For example:
+
+    install\(CODE \[\[
+      file\(GET_RUNTIME_DEPENDENCIES
+        # \.\.\.
+        \)
+      ]]\)
+Call Stack \(most recent call first\):
+  CMakeLists\.txt:[0-9]+ \(include\)
+This warning is for project developers\.  Use -Wno-dev to suppress it\.
+
+CMake Error at badargs1\.cmake:[0-9]+ \(file\):
+  file Unrecognized argument: "invalid"
+Call Stack \(most recent call first\):
+  CMakeLists\.txt:[0-9]+ \(include\)$
diff --git a/Tests/RunCMake/install/file-GET_RUNTIME_DEPENDENCIES-badargs1.cmake b/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/badargs1.cmake
similarity index 100%
rename from Tests/RunCMake/install/file-GET_RUNTIME_DEPENDENCIES-badargs1.cmake
rename to Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/badargs1.cmake
diff --git a/Tests/RunCMake/interface_library/whitelist-result.txt b/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/badargs2-result.txt
similarity index 100%
copy from Tests/RunCMake/interface_library/whitelist-result.txt
copy to Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/badargs2-result.txt
diff --git a/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/badargs2-stderr.txt b/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/badargs2-stderr.txt
new file mode 100644
index 0000000..c6ad3d0
--- /dev/null
+++ b/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/badargs2-stderr.txt
@@ -0,0 +1,23 @@
+^CMake Warning \(dev\) at badargs2\.cmake:[0-9]+ \(file\):
+  You have used file\(GET_RUNTIME_DEPENDENCIES\) in project mode\.  This is
+  probably not what you intended to do\.  Instead, please consider using it in
+  an install\(CODE\) or install\(SCRIPT\) command\.  For example:
+
+    install\(CODE \[\[
+      file\(GET_RUNTIME_DEPENDENCIES
+        # \.\.\.
+        \)
+      ]]\)
+Call Stack \(most recent call first\):
+  CMakeLists\.txt:[0-9]+ \(include\)
+This warning is for project developers\.  Use -Wno-dev to suppress it\.
+
+CMake Error at badargs2\.cmake:[0-9]+ \(file\):
+  file Keywords missing values:
+
+    RESOLVED_DEPENDENCIES_VAR
+    UNRESOLVED_DEPENDENCIES_VAR
+    CONFLICTING_DEPENDENCIES_PREFIX
+    BUNDLE_EXECUTABLE
+Call Stack \(most recent call first\):
+  CMakeLists\.txt:[0-9]+ \(include\)$
diff --git a/Tests/RunCMake/install/file-GET_RUNTIME_DEPENDENCIES-badargs2.cmake b/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/badargs2.cmake
similarity index 100%
rename from Tests/RunCMake/install/file-GET_RUNTIME_DEPENDENCIES-badargs2.cmake
rename to Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/badargs2.cmake
diff --git a/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/linux-all-check.cmake b/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/linux-all-check.cmake
new file mode 100644
index 0000000..381b602
--- /dev/null
+++ b/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/linux-all-check.cmake
@@ -0,0 +1,44 @@
+function(check_contents filename contents_regex)
+  if(EXISTS "${CMAKE_INSTALL_PREFIX}/${filename}")
+    file(READ "${CMAKE_INSTALL_PREFIX}/${filename}" contents)
+    if(NOT contents MATCHES "${contents_regex}")
+      string(APPEND RunCMake_TEST_FAILED "File contents:
+  ${contents}
+do not match what we expected:
+  ${contents_regex}
+in file:
+  ${CMAKE_INSTALL_PREFIX}/${filename}\n")
+      set(RunCMake_TEST_FAILED "${RunCMake_TEST_FAILED}" PARENT_SCOPE)
+    endif()
+  else()
+    string(APPEND RunCMake_TEST_FAILED "File ${CMAKE_INSTALL_PREFIX}/${filename} does not exist")
+    set(RunCMake_TEST_FAILED "${RunCMake_TEST_FAILED}" PARENT_SCOPE)
+  endif()
+endfunction()
+
+set(_check
+  [[[^;]*/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/linux-build/root-all/lib/libtest_rpath\.so]]
+  [[[^;]*/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/linux-build/root-all/lib/libtest_runpath\.so]]
+  [[[^;]*/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/linux-build/root-all/lib/rpath/librpath\.so]]
+  [[[^;]*/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/linux-build/root-all/lib/rpath_parent/librpath_parent\.so]]
+  [[[^;]*/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/linux-build/root-all/lib/rpath_search/librpath_search\.so]]
+  [[[^;]*/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/linux-build/root-all/lib/runpath/librunpath\.so]]
+  [[[^;]*/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/linux-build/root-all/lib/runpath_search/librunpath_search\.so]]
+  )
+check_contents(deps/deps1.txt "^${_check}$")
+check_contents(deps/deps2.txt "^${_check}$")
+check_contents(deps/deps3.txt "^${_check}$")
+set(_check
+  [[librpath_unresolved\.so]]
+  [[librunpath_parent_unresolved\.so]]
+  [[librunpath_unresolved\.so]]
+  )
+check_contents(deps/udeps1.txt "^${_check}$")
+check_contents(deps/udeps2.txt "^${_check}$")
+check_contents(deps/udeps3.txt "^${_check}$")
+set(_check
+  "^libconflict\\.so:[^;]*/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/linux-build/root-all/lib/conflict/libconflict\\.so;[^;]*/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/linux-build/root-all/lib/conflict2/libconflict\\.so\n$"
+  )
+check_contents(deps/cdeps1.txt "${_check}")
+check_contents(deps/cdeps2.txt "${_check}")
+check_contents(deps/cdeps3.txt "${_check}")
diff --git a/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/linux-all-stderr.txt b/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/linux-all-stderr.txt
new file mode 100644
index 0000000..aeb5736
--- /dev/null
+++ b/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/linux-all-stderr.txt
@@ -0,0 +1,119 @@
+^CMake Warning at cmake_install\.cmake:[0-9]+ \(file\):
+  Dependency librpath_search_postexcluded\.so found in search directory:
+
+    [^
+]*/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/linux-build/root-all/lib/rpath_search_postexcluded
+
+  See file\(GET_RUNTIME_DEPENDENCIES\) documentation for more information\.
+Call Stack \(most recent call first\):
+  cmake_install\.cmake:[0-9]+ \(exec_get_runtime_dependencies\)
+
+*CMake Warning at cmake_install\.cmake:[0-9]+ \(file\):
+  Dependency librpath_search\.so found in search directory:
+
+    [^
+]*/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/linux-build/root-all/lib/rpath_search
+
+  See file\(GET_RUNTIME_DEPENDENCIES\) documentation for more information\.
+Call Stack \(most recent call first\):
+  cmake_install\.cmake:[0-9]+ \(exec_get_runtime_dependencies\)
+
+*CMake Warning at cmake_install\.cmake:[0-9]+ \(file\):
+  Dependency librunpath_search_postexcluded\.so found in search directory:
+
+    [^
+]*/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/linux-build/root-all/lib/runpath_search_postexcluded
+
+  See file\(GET_RUNTIME_DEPENDENCIES\) documentation for more information\.
+Call Stack \(most recent call first\):
+  cmake_install\.cmake:[0-9]+ \(exec_get_runtime_dependencies\)
+
+*CMake Warning at cmake_install\.cmake:[0-9]+ \(file\):
+  Dependency librunpath_search\.so found in search directory:
+
+    [^
+]*/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/linux-build/root-all/lib/runpath_search
+
+  See file\(GET_RUNTIME_DEPENDENCIES\) documentation for more information\.
+Call Stack \(most recent call first\):
+  cmake_install\.cmake:[0-9]+ \(exec_get_runtime_dependencies\)
+
+*CMake Warning at cmake_install\.cmake:[0-9]+ \(file\):
+  Dependency librpath_search_postexcluded\.so found in search directory:
+
+    [^
+]*/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/linux-build/root-all/lib/rpath_search_postexcluded
+
+  See file\(GET_RUNTIME_DEPENDENCIES\) documentation for more information\.
+Call Stack \(most recent call first\):
+  cmake_install\.cmake:[0-9]+ \(exec_get_runtime_dependencies\)
+
+*CMake Warning at cmake_install\.cmake:[0-9]+ \(file\):
+  Dependency librpath_search\.so found in search directory:
+
+    [^
+]*/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/linux-build/root-all/lib/rpath_search
+
+  See file\(GET_RUNTIME_DEPENDENCIES\) documentation for more information\.
+Call Stack \(most recent call first\):
+  cmake_install\.cmake:[0-9]+ \(exec_get_runtime_dependencies\)
+
+*CMake Warning at cmake_install\.cmake:[0-9]+ \(file\):
+  Dependency librunpath_search_postexcluded\.so found in search directory:
+
+    [^
+]*/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/linux-build/root-all/lib/runpath_search_postexcluded
+
+  See file\(GET_RUNTIME_DEPENDENCIES\) documentation for more information\.
+Call Stack \(most recent call first\):
+  cmake_install\.cmake:[0-9]+ \(exec_get_runtime_dependencies\)
+
+*CMake Warning at cmake_install\.cmake:[0-9]+ \(file\):
+  Dependency librunpath_search\.so found in search directory:
+
+    [^
+]*/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/linux-build/root-all/lib/runpath_search
+
+  See file\(GET_RUNTIME_DEPENDENCIES\) documentation for more information\.
+Call Stack \(most recent call first\):
+  cmake_install\.cmake:[0-9]+ \(exec_get_runtime_dependencies\)
+
+*CMake Warning at cmake_install\.cmake:[0-9]+ \(file\):
+  Dependency librpath_search_postexcluded\.so found in search directory:
+
+    [^
+]*/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/linux-build/root-all/lib/rpath_search_postexcluded
+
+  See file\(GET_RUNTIME_DEPENDENCIES\) documentation for more information\.
+Call Stack \(most recent call first\):
+  cmake_install\.cmake:[0-9]+ \(exec_get_runtime_dependencies\)
+
+*CMake Warning at cmake_install\.cmake:[0-9]+ \(file\):
+  Dependency librpath_search\.so found in search directory:
+
+    [^
+]*/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/linux-build/root-all/lib/rpath_search
+
+  See file\(GET_RUNTIME_DEPENDENCIES\) documentation for more information\.
+Call Stack \(most recent call first\):
+  cmake_install\.cmake:[0-9]+ \(exec_get_runtime_dependencies\)
+
+*CMake Warning at cmake_install\.cmake:[0-9]+ \(file\):
+  Dependency librunpath_search_postexcluded\.so found in search directory:
+
+    [^
+]*/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/linux-build/root-all/lib/runpath_search_postexcluded
+
+  See file\(GET_RUNTIME_DEPENDENCIES\) documentation for more information\.
+Call Stack \(most recent call first\):
+  cmake_install\.cmake:[0-9]+ \(exec_get_runtime_dependencies\)
+
+*CMake Warning at cmake_install\.cmake:[0-9]+ \(file\):
+  Dependency librunpath_search\.so found in search directory:
+
+    [^
+]*/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/linux-build/root-all/lib/runpath_search
+
+  See file\(GET_RUNTIME_DEPENDENCIES\) documentation for more information\.
+Call Stack \(most recent call first\):
+  cmake_install\.cmake:[0-9]+ \(exec_get_runtime_dependencies\)$
diff --git a/Tests/RunCMake/install/file-GET_RUNTIME_DEPENDENCIES-linux-conflict-all-result.txt b/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/linux-conflict-all-result.txt
similarity index 100%
rename from Tests/RunCMake/install/file-GET_RUNTIME_DEPENDENCIES-linux-conflict-all-result.txt
rename to Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/linux-conflict-all-result.txt
diff --git a/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/linux-conflict-all-stderr.txt b/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/linux-conflict-all-stderr.txt
new file mode 100644
index 0000000..a6b65df
--- /dev/null
+++ b/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/linux-conflict-all-stderr.txt
@@ -0,0 +1,7 @@
+^CMake Error at cmake_install\.cmake:[0-9]+ \(file\):
+  file Multiple conflicting paths found for librpath\.so:
+
+    [^
+]*/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/linux-conflict-build/root-all/lib/rpath1/librpath\.so
+    [^
+]*/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/linux-conflict-build/root-all/lib/rpath2/librpath\.so$
diff --git a/Tests/RunCMake/install/file-GET_RUNTIME_DEPENDENCIES-linux-conflict.cmake b/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/linux-conflict.cmake
similarity index 100%
rename from Tests/RunCMake/install/file-GET_RUNTIME_DEPENDENCIES-linux-conflict.cmake
rename to Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/linux-conflict.cmake
diff --git a/Tests/RunCMake/install/file-GET_RUNTIME_DEPENDENCIES-linux-notfile-all-result.txt b/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/linux-notfile-all-result.txt
similarity index 100%
rename from Tests/RunCMake/install/file-GET_RUNTIME_DEPENDENCIES-linux-notfile-all-result.txt
rename to Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/linux-notfile-all-result.txt
diff --git a/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/linux-notfile-all-stderr.txt b/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/linux-notfile-all-stderr.txt
new file mode 100644
index 0000000..d9758c5
--- /dev/null
+++ b/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/linux-notfile-all-stderr.txt
@@ -0,0 +1,5 @@
+^CMake Error at cmake_install\.cmake:[0-9]+ \(file\):
+  file Failed to run objdump on:
+
+    [^
+]*/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/linux-notfile-build/root-all/bin/\.\./lib/libtest\.so$
diff --git a/Tests/RunCMake/install/file-GET_RUNTIME_DEPENDENCIES-linux-notfile.cmake b/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/linux-notfile.cmake
similarity index 100%
rename from Tests/RunCMake/install/file-GET_RUNTIME_DEPENDENCIES-linux-notfile.cmake
rename to Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/linux-notfile.cmake
diff --git a/Tests/RunCMake/install/file-GET_RUNTIME_DEPENDENCIES-linux-unresolved-all-result.txt b/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/linux-unresolved-all-result.txt
similarity index 100%
rename from Tests/RunCMake/install/file-GET_RUNTIME_DEPENDENCIES-linux-unresolved-all-result.txt
rename to Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/linux-unresolved-all-result.txt
diff --git a/Tests/RunCMake/install/file-GET_RUNTIME_DEPENDENCIES-linux-unresolved-all-stderr.txt b/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/linux-unresolved-all-stderr.txt
similarity index 100%
rename from Tests/RunCMake/install/file-GET_RUNTIME_DEPENDENCIES-linux-unresolved-all-stderr.txt
rename to Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/linux-unresolved-all-stderr.txt
diff --git a/Tests/RunCMake/install/file-GET_RUNTIME_DEPENDENCIES-linux-unresolved.cmake b/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/linux-unresolved.cmake
similarity index 100%
rename from Tests/RunCMake/install/file-GET_RUNTIME_DEPENDENCIES-linux-unresolved.cmake
rename to Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/linux-unresolved.cmake
diff --git a/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/linux.cmake b/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/linux.cmake
new file mode 100644
index 0000000..d82d8fb
--- /dev/null
+++ b/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/linux.cmake
@@ -0,0 +1,169 @@
+enable_language(C)
+cmake_policy(SET CMP0095 NEW)
+
+set(test_rpath_names
+  preexcluded
+  rpath_postexcluded
+  rpath
+  rpath_parent_postexcluded
+  rpath_parent
+  rpath_origin_postexcluded
+  rpath_origin
+  rpath_search_postexcluded
+  rpath_search
+  rpath_unresolved
+  conflict
+  )
+set(test_runpath_names
+  runpath_postexcluded
+  runpath
+  runpath_origin_postexcluded
+  runpath_origin
+  runpath_parent_unresolved
+  runpath_search_postexcluded
+  runpath_search
+  runpath_unresolved
+  )
+
+file(REMOVE "${CMAKE_BINARY_DIR}/test_rpath.c")
+add_library(test_rpath SHARED "${CMAKE_BINARY_DIR}/test_rpath.c")
+foreach(name ${test_rpath_names})
+  file(WRITE "${CMAKE_BINARY_DIR}/${name}.c" "void ${name}(void) {}\n")
+  add_library(${name} SHARED "${CMAKE_BINARY_DIR}/${name}.c")
+
+  file(APPEND "${CMAKE_BINARY_DIR}/test_rpath.c" "extern void ${name}(void);\n")
+endforeach()
+file(APPEND "${CMAKE_BINARY_DIR}/test_rpath.c" "void test_rpath(void)\n{\n")
+foreach(name ${test_rpath_names})
+  file(APPEND "${CMAKE_BINARY_DIR}/test_rpath.c" "  ${name}();\n")
+endforeach()
+file(APPEND "${CMAKE_BINARY_DIR}/test_rpath.c" "}\n")
+
+install(TARGETS rpath_postexcluded DESTINATION lib/rpath_postexcluded)
+install(TARGETS rpath DESTINATION lib/rpath)
+install(TARGETS rpath_origin_postexcluded DESTINATION lib/rpath_origin_postexcluded)
+install(TARGETS rpath_origin DESTINATION lib/rpath_origin)
+install(TARGETS rpath_parent_postexcluded DESTINATION lib/rpath_parent_postexcluded)
+install(TARGETS rpath rpath_origin rpath_parent DESTINATION lib/rpath_parent)
+install(TARGETS rpath_search_postexcluded DESTINATION lib/rpath_search_postexcluded)
+install(TARGETS rpath rpath_origin rpath_parent rpath_search DESTINATION lib/rpath_search)
+install(TARGETS conflict DESTINATION lib/conflict)
+
+target_link_libraries(test_rpath PRIVATE ${test_rpath_names})
+set_property(TARGET test_rpath PROPERTY INSTALL_RPATH
+  "${CMAKE_BINARY_DIR}/root-all/lib/rpath_postexcluded"
+  "${CMAKE_BINARY_DIR}/root-all/lib/rpath"
+  "\$ORIGIN/rpath_origin_postexcluded"
+  "\${ORIGIN}/rpath_origin"
+  "${CMAKE_BINARY_DIR}/root-all/lib/conflict"
+  )
+target_link_options(test_rpath PRIVATE -Wl,--disable-new-dtags)
+
+file(REMOVE "${CMAKE_BINARY_DIR}/test_runpath.c")
+add_library(test_runpath SHARED "${CMAKE_BINARY_DIR}/test_runpath.c")
+foreach(name ${test_runpath_names} rpath conflict)
+  file(WRITE "${CMAKE_BINARY_DIR}/${name}.c" "void ${name}(void) {}\n")
+  if(NOT name MATCHES "^(rpath|conflict)$")
+    add_library(${name} SHARED "${CMAKE_BINARY_DIR}/${name}.c")
+  endif()
+
+  file(APPEND "${CMAKE_BINARY_DIR}/test_runpath.c" "extern void ${name}(void);\n")
+endforeach()
+file(APPEND "${CMAKE_BINARY_DIR}/test_runpath.c" "void test_runpath(void)\n{\n")
+foreach(name ${test_runpath_names} rpath conflict)
+  file(APPEND "${CMAKE_BINARY_DIR}/test_runpath.c" "  ${name}();\n")
+endforeach()
+file(APPEND "${CMAKE_BINARY_DIR}/test_runpath.c" "}\n")
+
+install(TARGETS runpath_postexcluded DESTINATION lib/runpath_postexcluded)
+install(TARGETS runpath DESTINATION lib/runpath)
+install(TARGETS runpath_origin_postexcluded DESTINATION lib/runpath_origin_postexcluded)
+install(TARGETS runpath_origin DESTINATION lib/runpath_origin)
+install(TARGETS runpath_parent_unresolved DESTINATION lib/runpath_parent_unresolved)
+install(TARGETS runpath_search_postexcluded DESTINATION lib/runpath_search_postexcluded)
+install(TARGETS runpath runpath_origin runpath_search DESTINATION lib/runpath_search)
+install(TARGETS conflict DESTINATION lib/conflict2)
+
+target_link_libraries(test_runpath PRIVATE ${test_runpath_names} rpath conflict)
+set_property(TARGET test_runpath PROPERTY INSTALL_RPATH
+  "${CMAKE_BINARY_DIR}/root-all/lib/runpath/../rpath" # Ensure that files that don't conflict are treated correctly
+  "${CMAKE_BINARY_DIR}/root-all/lib/runpath_postexcluded"
+  "${CMAKE_BINARY_DIR}/root-all/lib/runpath"
+  "\${ORIGIN}/runpath_origin_postexcluded"
+  "\$ORIGIN/runpath_origin"
+  "${CMAKE_BINARY_DIR}/root-all/lib/conflict2"
+  )
+target_link_options(test_runpath PRIVATE -Wl,--enable-new-dtags)
+
+set_property(TARGET test_rpath ${test_rpath_names} test_runpath ${test_runpath_names} PROPERTY LIBRARY_OUTPUT_DIRECTORY lib)
+install(TARGETS test_rpath test_runpath DESTINATION lib)
+
+add_executable(topexe linux/topexe.c)
+add_library(toplib SHARED linux/toplib.c)
+add_library(topmod MODULE linux/toplib.c)
+target_link_libraries(topexe PRIVATE test_rpath test_runpath)
+target_link_libraries(toplib PRIVATE test_rpath test_runpath)
+target_link_libraries(topmod PRIVATE test_rpath test_runpath)
+set_property(TARGET topexe toplib topmod PROPERTY INSTALL_RPATH
+  "${CMAKE_BINARY_DIR}/root-all/lib"
+  "${CMAKE_BINARY_DIR}/root-all/lib/rpath_parent_postexcluded"
+  "${CMAKE_BINARY_DIR}/root-all/lib/rpath_parent"
+  "${CMAKE_BINARY_DIR}/root-all/lib/runpath_parent_unresolved"
+  )
+target_link_options(topexe PRIVATE -Wl,--disable-new-dtags)
+target_link_options(toplib PRIVATE -Wl,--disable-new-dtags)
+target_link_options(topmod PRIVATE -Wl,--disable-new-dtags)
+
+install(TARGETS topexe toplib RUNTIME DESTINATION bin LIBRARY DESTINATION lib)
+install(TARGETS topmod LIBRARY DESTINATION lib/modules)
+
+install(CODE [[
+  function(exec_get_runtime_dependencies depsfile udepsfile cdepsfile)
+    file(GET_RUNTIME_DEPENDENCIES
+      RESOLVED_DEPENDENCIES_VAR deps
+      UNRESOLVED_DEPENDENCIES_VAR udeps
+      CONFLICTING_DEPENDENCIES_PREFIX cdeps
+      PRE_INCLUDE_REGEXES
+        "^lib(test_rpath|rpath_postexcluded|rpath|rpath_parent_postexcluded|rpath_parent|rpath_origin_postexcluded|rpath_origin|rpath_search_postexcluded|rpath_search|rpath_unresolved|test_runpath|runpath_postexcluded|runpath|runpath_origin_postexcluded|runpath_origin|runpath_parent_unresolved|runpath_search_postexcluded|runpath_search|runpath_unresolved|conflict)\\.so$"
+        "^libc\\.so"
+      PRE_EXCLUDE_REGEXES ".*"
+      POST_INCLUDE_REGEXES "^.*/(libtest_rpath|rpath/librpath|rpath_parent/librpath_parent|rpath_search/librpath_search|libtest_runpath|runpath/librunpath|runpath_origin_postexcluded|runpath_origin|runpath_search/librunpath_search|conflict2?/libconflict)\\.so$"
+      POST_EXCLUDE_REGEXES ".*"
+      DIRECTORIES
+        "${CMAKE_INSTALL_PREFIX}/lib/rpath_search_postexcluded"
+        "${CMAKE_INSTALL_PREFIX}/lib/rpath_search"
+        "${CMAKE_INSTALL_PREFIX}/lib/runpath_search_postexcluded"
+        "${CMAKE_INSTALL_PREFIX}/lib/runpath_search"
+      ${ARGN}
+      )
+    list(SORT deps)
+    list(SORT udeps)
+    list(SORT cdeps_FILENAMES)
+    file(WRITE "${CMAKE_INSTALL_PREFIX}/deps/${depsfile}" "${deps}")
+    file(WRITE "${CMAKE_INSTALL_PREFIX}/deps/${udepsfile}" "${udeps}")
+    file(WRITE "${CMAKE_INSTALL_PREFIX}/deps/${cdepsfile}" "")
+    foreach(cdep IN LISTS cdeps_FILENAMES)
+      set(cdep_values ${cdeps_${cdep}})
+      list(SORT cdep_values)
+      file(APPEND "${CMAKE_INSTALL_PREFIX}/deps/${cdepsfile}" "${cdep}:${cdep_values}\n")
+    endforeach()
+  endfunction()
+
+  exec_get_runtime_dependencies(
+    deps1.txt udeps1.txt cdeps1.txt
+    EXECUTABLES
+      "${CMAKE_INSTALL_PREFIX}/bin/$<TARGET_FILE_NAME:topexe>"
+    )
+
+  exec_get_runtime_dependencies(
+    deps2.txt udeps2.txt cdeps2.txt
+    LIBRARIES
+      "${CMAKE_INSTALL_PREFIX}/lib/$<TARGET_FILE_NAME:toplib>"
+    )
+
+  exec_get_runtime_dependencies(
+    deps3.txt udeps3.txt cdeps3.txt
+    MODULES
+      "${CMAKE_INSTALL_PREFIX}/lib/modules/$<TARGET_FILE_NAME:topmod>"
+    )
+  ]])
diff --git a/Tests/RunCMake/install/file-GET_RUNTIME_DEPENDENCIES-linux/topexe.c b/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/linux/topexe.c
similarity index 100%
rename from Tests/RunCMake/install/file-GET_RUNTIME_DEPENDENCIES-linux/topexe.c
rename to Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/linux/topexe.c
diff --git a/Tests/RunCMake/install/file-GET_RUNTIME_DEPENDENCIES-linux/toplib.c b/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/linux/toplib.c
similarity index 100%
rename from Tests/RunCMake/install/file-GET_RUNTIME_DEPENDENCIES-linux/toplib.c
rename to Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/linux/toplib.c
diff --git a/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/macos-all-check.cmake b/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/macos-all-check.cmake
new file mode 100644
index 0000000..e6f2623
--- /dev/null
+++ b/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/macos-all-check.cmake
@@ -0,0 +1,159 @@
+function(check_contents filename contents_regex)
+  if(EXISTS "${CMAKE_INSTALL_PREFIX}/${filename}")
+    file(READ "${CMAKE_INSTALL_PREFIX}/${filename}" contents)
+    if(NOT contents MATCHES "${contents_regex}")
+      string(APPEND RunCMake_TEST_FAILED "File contents:
+  ${contents}
+do not match what we expected:
+  ${contents_regex}
+in file:
+  ${CMAKE_INSTALL_PREFIX}/${filename}\n")
+      set(RunCMake_TEST_FAILED "${RunCMake_TEST_FAILED}" PARENT_SCOPE)
+    endif()
+  else()
+    string(APPEND RunCMake_TEST_FAILED "File ${CMAKE_INSTALL_PREFIX}/${filename} does not exist")
+    set(RunCMake_TEST_FAILED "${RunCMake_TEST_FAILED}" PARENT_SCOPE)
+  endif()
+endfunction()
+
+function(set_with_libsystem var)
+  set(_tmp "${ARGN}")
+  if(EXISTS "/usr/lib/libSystem.B.dylib")
+    list(APPEND _tmp [[/usr/lib/libSystem\.B\.dylib]])
+  endif()
+  set("${var}" "${_tmp}" PARENT_SCOPE)
+endfunction()
+
+set_with_libsystem(_check
+  [[[^;]*/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/macos-build/root-all/executable/bin/../lib/executable_path/libexecutable_path\.dylib]]
+  [[[^;]*/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/macos-build/root-all/executable/bin/../lib/rpath_executable_path/librpath_executable_path\.dylib]]
+  [[[^;]*/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/macos-build/root-all/executable/lib/libtestlib\.dylib]]
+  [[[^;]*/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/macos-build/root-all/executable/lib/loader_path/libloader_path\.dylib]]
+  [[[^;]*/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/macos-build/root-all/executable/lib/normal/../rpath/librpath\.dylib]]
+  [[[^;]*/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/macos-build/root-all/executable/lib/normal/libnormal\.dylib]]
+  [[[^;]*/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/macos-build/root-all/executable/lib/rpath_loader_path/librpath_loader_path\.dylib]]
+  )
+check_contents(deps/deps1.txt "^${_check}$")
+
+set(_check
+  [[@executable_path/../lib/executable_path_bundle/libexecutable_path_bundle\.dylib]]
+  [[@loader_path/loader_path_unresolved/libloader_path_unresolved\.dylib]]
+  [[@rpath/librpath_executable_path_bundle\.dylib]]
+  [[@rpath/librpath_loader_path_unresolved\.dylib]]
+  [[@rpath/librpath_unresolved\.dylib]]
+  )
+check_contents(deps/udeps1.txt "^${_check}$")
+
+set_with_libsystem(_check
+  [[[^;]*/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/macos-build/root-all/executable/lib/libtestlib\.dylib]]
+  [[[^;]*/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/macos-build/root-all/executable/lib/loader_path/libloader_path\.dylib]]
+  [[[^;]*/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/macos-build/root-all/executable/lib/normal/../rpath/librpath\.dylib]]
+  [[[^;]*/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/macos-build/root-all/executable/lib/normal/libnormal\.dylib]]
+  [[[^;]*/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/macos-build/root-all/executable/lib/rpath_loader_path/librpath_loader_path\.dylib]]
+  )
+check_contents(deps/deps2.txt "^${_check}$")
+
+set(_check
+  [[@executable_path/../lib/executable_path/libexecutable_path\.dylib]]
+  [[@executable_path/../lib/executable_path_bundle/libexecutable_path_bundle\.dylib]]
+  [[@executable_path/../lib/executable_path_postexcluded/libexecutable_path_postexcluded\.dylib]]
+  [[@loader_path/loader_path_unresolved/libloader_path_unresolved\.dylib]]
+  [[@rpath/librpath_executable_path\.dylib]]
+  [[@rpath/librpath_executable_path_bundle\.dylib]]
+  [[@rpath/librpath_executable_path_postexcluded\.dylib]]
+  [[@rpath/librpath_loader_path_unresolved\.dylib]]
+  [[@rpath/librpath_unresolved\.dylib]]
+  )
+check_contents(deps/udeps2.txt "^${_check}$")
+
+set_with_libsystem(_check
+  [[[^;]*/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/macos-build/root-all/executable/lib/libtestlib\.dylib]]
+  [[[^;]*/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/macos-build/root-all/executable/lib/loader_path/libloader_path\.dylib]]
+  [[[^;]*/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/macos-build/root-all/executable/lib/normal/../rpath/librpath\.dylib]]
+  [[[^;]*/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/macos-build/root-all/executable/lib/normal/libnormal\.dylib]]
+  [[[^;]*/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/macos-build/root-all/executable/lib/rpath_loader_path/librpath_loader_path\.dylib]]
+  )
+check_contents(deps/deps3.txt "^${_check}$")
+
+set(_check
+  [[@executable_path/../lib/executable_path/libexecutable_path\.dylib]]
+  [[@executable_path/../lib/executable_path_bundle/libexecutable_path_bundle\.dylib]]
+  [[@executable_path/../lib/executable_path_postexcluded/libexecutable_path_postexcluded\.dylib]]
+  [[@loader_path/loader_path_unresolved/libloader_path_unresolved\.dylib]]
+  [[@rpath/librpath_executable_path\.dylib]]
+  [[@rpath/librpath_executable_path_bundle\.dylib]]
+  [[@rpath/librpath_executable_path_postexcluded\.dylib]]
+  [[@rpath/librpath_loader_path_unresolved\.dylib]]
+  [[@rpath/librpath_unresolved\.dylib]]
+  )
+check_contents(deps/udeps3.txt "^${_check}$")
+
+set_with_libsystem(_check
+  [[[^;]*/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/macos-build/root-all/executable/bin/../lib/executable_path/libexecutable_path\.dylib]]
+  [[[^;]*/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/macos-build/root-all/executable/bin/../lib/rpath_executable_path/librpath_executable_path\.dylib]]
+  [[[^;]*/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/macos-build/root-all/executable/lib/libtestlib\.dylib]]
+  [[[^;]*/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/macos-build/root-all/executable/lib/loader_path/libloader_path\.dylib]]
+  [[[^;]*/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/macos-build/root-all/executable/lib/normal/../rpath/librpath\.dylib]]
+  [[[^;]*/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/macos-build/root-all/executable/lib/normal/libnormal\.dylib]]
+  [[[^;]*/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/macos-build/root-all/executable/lib/rpath_loader_path/librpath_loader_path\.dylib]]
+  )
+check_contents(deps/deps4.txt "^${_check}$")
+
+set(_check
+  [[@executable_path/../lib/executable_path_bundle/libexecutable_path_bundle\.dylib]]
+  [[@loader_path/loader_path_unresolved/libloader_path_unresolved\.dylib]]
+  [[@rpath/librpath_executable_path_bundle\.dylib]]
+  [[@rpath/librpath_loader_path_unresolved\.dylib]]
+  [[@rpath/librpath_unresolved\.dylib]]
+  )
+check_contents(deps/udeps4.txt "^${_check}$")
+
+set_with_libsystem(_check
+  [[[^;]*/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/macos-build/root-all/bundle_executable/bin/../lib/executable_path_bundle/libexecutable_path_bundle\.dylib]]
+  [[[^;]*/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/macos-build/root-all/executable/lib/libtestlib\.dylib]]
+  [[[^;]*/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/macos-build/root-all/executable/lib/loader_path/libloader_path\.dylib]]
+  [[[^;]*/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/macos-build/root-all/executable/lib/normal/../rpath/librpath\.dylib]]
+  [[[^;]*/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/macos-build/root-all/executable/lib/normal/libnormal\.dylib]]
+  [[[^;]*/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/macos-build/root-all/executable/lib/rpath_loader_path/librpath_loader_path\.dylib]]
+  )
+check_contents(deps/deps5.txt "^${_check}$")
+
+set(_check
+  [[@executable_path/../lib/executable_path/libexecutable_path\.dylib]]
+  [[@loader_path/loader_path_unresolved/libloader_path_unresolved\.dylib]]
+  [[@rpath/librpath_executable_path\.dylib]]
+  [[@rpath/librpath_executable_path_bundle\.dylib]]
+  [[@rpath/librpath_loader_path_unresolved\.dylib]]
+  [[@rpath/librpath_unresolved\.dylib]]
+  )
+check_contents(deps/udeps5.txt "^${_check}$")
+
+set_with_libsystem(_check
+  [[[^;]*/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/macos-build/root-all/bundle_executable/bin/../lib/executable_path_bundle/libexecutable_path_bundle\.dylib]]
+  [[[^;]*/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/macos-build/root-all/executable/lib/libtestlib\.dylib]]
+  [[[^;]*/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/macos-build/root-all/executable/lib/loader_path/libloader_path\.dylib]]
+  [[[^;]*/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/macos-build/root-all/executable/lib/normal/../rpath/librpath\.dylib]]
+  [[[^;]*/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/macos-build/root-all/executable/lib/normal/libnormal\.dylib]]
+  [[[^;]*/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/macos-build/root-all/executable/lib/rpath_loader_path/librpath_loader_path\.dylib]]
+  )
+check_contents(deps/deps6.txt "^${_check}$")
+
+set(_check
+  [[@executable_path/../lib/executable_path/libexecutable_path\.dylib]]
+  [[@loader_path/loader_path_unresolved/libloader_path_unresolved\.dylib]]
+  [[@rpath/librpath_executable_path\.dylib]]
+  [[@rpath/librpath_executable_path_bundle\.dylib]]
+  [[@rpath/librpath_loader_path_unresolved\.dylib]]
+  [[@rpath/librpath_unresolved\.dylib]]
+  )
+check_contents(deps/udeps6.txt "^${_check}$")
+
+set(_check
+  "^libconflict\\.dylib:[^;]*/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/macos-build/root-all/executable/lib/conflict/libconflict\\.dylib;[^;]*/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/macos-build/root-all/executable/lib/conflict2/libconflict\\.dylib\n$"
+  )
+check_contents(deps/cdeps1.txt "${_check}")
+check_contents(deps/cdeps2.txt "${_check}")
+check_contents(deps/cdeps3.txt "${_check}")
+check_contents(deps/cdeps4.txt "${_check}")
+check_contents(deps/cdeps5.txt "${_check}")
+check_contents(deps/cdeps6.txt "${_check}")
diff --git a/Tests/RunCMake/install/file-GET_RUNTIME_DEPENDENCIES-macos-conflict-all-result.txt b/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/macos-conflict-all-result.txt
similarity index 100%
rename from Tests/RunCMake/install/file-GET_RUNTIME_DEPENDENCIES-macos-conflict-all-result.txt
rename to Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/macos-conflict-all-result.txt
diff --git a/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/macos-conflict-all-stderr.txt b/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/macos-conflict-all-stderr.txt
new file mode 100644
index 0000000..d8323a8
--- /dev/null
+++ b/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/macos-conflict-all-stderr.txt
@@ -0,0 +1,7 @@
+^CMake Error at cmake_install\.cmake:[0-9]+ \(file\):
+  file Multiple conflicting paths found for librpath\.dylib:
+
+    [^
+]*/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/macos-conflict-build/root-all/lib/rpath1/librpath\.dylib
+    [^
+]*/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/macos-conflict-build/root-all/lib/rpath2/librpath\.dylib$
diff --git a/Tests/RunCMake/install/file-GET_RUNTIME_DEPENDENCIES-macos-conflict.cmake b/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/macos-conflict.cmake
similarity index 100%
rename from Tests/RunCMake/install/file-GET_RUNTIME_DEPENDENCIES-macos-conflict.cmake
rename to Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/macos-conflict.cmake
diff --git a/Tests/RunCMake/install/file-GET_RUNTIME_DEPENDENCIES-macos-notfile-all-result.txt b/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/macos-notfile-all-result.txt
similarity index 100%
rename from Tests/RunCMake/install/file-GET_RUNTIME_DEPENDENCIES-macos-notfile-all-result.txt
rename to Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/macos-notfile-all-result.txt
diff --git a/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/macos-notfile-all-stderr.txt b/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/macos-notfile-all-stderr.txt
new file mode 100644
index 0000000..1afc1b1
--- /dev/null
+++ b/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/macos-notfile-all-stderr.txt
@@ -0,0 +1,5 @@
+^CMake Error at cmake_install\.cmake:[0-9]+ \(file\):
+  file Failed to run otool on:
+
+    [^
+]*/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/macos-notfile-build/root-all/bin/\.\./lib/libtest\.dylib$
diff --git a/Tests/RunCMake/install/file-GET_RUNTIME_DEPENDENCIES-macos-notfile.cmake b/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/macos-notfile.cmake
similarity index 100%
rename from Tests/RunCMake/install/file-GET_RUNTIME_DEPENDENCIES-macos-notfile.cmake
rename to Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/macos-notfile.cmake
diff --git a/Tests/RunCMake/install/file-GET_RUNTIME_DEPENDENCIES-macos-unresolved-all-result.txt b/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/macos-unresolved-all-result.txt
similarity index 100%
rename from Tests/RunCMake/install/file-GET_RUNTIME_DEPENDENCIES-macos-unresolved-all-result.txt
rename to Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/macos-unresolved-all-result.txt
diff --git a/Tests/RunCMake/install/file-GET_RUNTIME_DEPENDENCIES-macos-unresolved-all-stderr.txt b/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/macos-unresolved-all-stderr.txt
similarity index 100%
rename from Tests/RunCMake/install/file-GET_RUNTIME_DEPENDENCIES-macos-unresolved-all-stderr.txt
rename to Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/macos-unresolved-all-stderr.txt
diff --git a/Tests/RunCMake/install/file-GET_RUNTIME_DEPENDENCIES-macos-unresolved.cmake b/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/macos-unresolved.cmake
similarity index 100%
rename from Tests/RunCMake/install/file-GET_RUNTIME_DEPENDENCIES-macos-unresolved.cmake
rename to Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/macos-unresolved.cmake
diff --git a/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/macos.cmake b/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/macos.cmake
new file mode 100644
index 0000000..c56a14b
--- /dev/null
+++ b/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/macos.cmake
@@ -0,0 +1,216 @@
+enable_language(C)
+
+set(testlib_names
+  preexcluded
+  executable_path
+  executable_path_bundle
+  executable_path_postexcluded
+  loader_path
+  loader_path_unresolved
+  loader_path_postexcluded
+  rpath
+  rpath_unresolved
+  rpath_postexcluded
+  rpath_executable_path
+  rpath_executable_path_bundle
+  rpath_executable_path_postexcluded
+  rpath_loader_path
+  rpath_loader_path_unresolved
+  rpath_loader_path_postexcluded
+  normal
+  normal_unresolved
+  normal_postexcluded
+  conflict
+  )
+
+file(REMOVE "${CMAKE_BINARY_DIR}/testlib.c")
+add_library(testlib SHARED "${CMAKE_BINARY_DIR}/testlib.c")
+foreach(name ${testlib_names})
+  if(name STREQUAL "normal")
+    file(WRITE "${CMAKE_BINARY_DIR}/normal.c" "extern void rpath(void);\nvoid normal(void)\n{\n  rpath();\n}\n")
+  else()
+    file(WRITE "${CMAKE_BINARY_DIR}/${name}.c" "void ${name}(void) {}\n")
+  endif()
+  add_library(${name} SHARED "${CMAKE_BINARY_DIR}/${name}.c")
+
+  file(APPEND "${CMAKE_BINARY_DIR}/testlib.c" "extern void ${name}(void);\n")
+endforeach()
+file(APPEND "${CMAKE_BINARY_DIR}/testlib.c" "void testlib(void)\n{\n")
+foreach(name ${testlib_names})
+  file(APPEND "${CMAKE_BINARY_DIR}/testlib.c" "  ${name}();\n")
+endforeach()
+file(APPEND "${CMAKE_BINARY_DIR}/testlib.c" "}\n")
+set_property(TARGET ${testlib_names} PROPERTY BUILD_WITH_INSTALL_NAME_DIR 1)
+target_link_libraries(normal PRIVATE rpath)
+set_property(TARGET normal PROPERTY INSTALL_RPATH
+  "${CMAKE_BINARY_DIR}/root-all/executable/lib/normal/../rpath"
+  )
+
+file(WRITE "${CMAKE_BINARY_DIR}/testlib_conflict.c" "extern void conflict(void);\nvoid testlib_conflict(void)\n{\n  conflict();\n}\n")
+add_library(testlib_conflict SHARED "${CMAKE_BINARY_DIR}/testlib_conflict.c")
+target_link_libraries(testlib_conflict PRIVATE conflict)
+
+set_property(TARGET testlib PROPERTY INSTALL_RPATH
+  "${CMAKE_BINARY_DIR}/root-all/executable/lib/rpath"
+  "${CMAKE_BINARY_DIR}/root-all/executable/lib/rpath_unresolved"
+  "${CMAKE_BINARY_DIR}/root-all/executable/lib/rpath_postexcluded"
+  "${CMAKE_BINARY_DIR}/root-all/executable/lib/conflict"
+  @executable_path/../lib/rpath_executable_path
+  @executable_path/../lib/rpath_executable_path_unresolved
+  @executable_path/../lib/rpath_executable_path_postexcluded
+  @loader_path/rpath_loader_path
+  @loader_path/rpath_loader_path_unresolved
+  @loader_path/rpath_loader_path_postexcluded
+  )
+set_property(TARGET testlib_conflict PROPERTY INSTALL_RPATH
+  "${CMAKE_BINARY_DIR}/root-all/executable/lib/conflict2"
+  )
+
+foreach(t
+  executable_path
+  executable_path_postexcluded
+  loader_path
+  loader_path_postexcluded
+  rpath
+  rpath_postexcluded
+  rpath_executable_path
+  rpath_executable_path_postexcluded
+  rpath_loader_path
+  rpath_loader_path_postexcluded
+  conflict
+  )
+  install(TARGETS ${t} DESTINATION executable/lib/${t})
+endforeach()
+install(TARGETS conflict DESTINATION executable/lib/conflict2)
+
+foreach(t
+  executable_path_bundle
+  executable_path_postexcluded
+  loader_path_postexcluded
+  rpath_postexcluded
+  rpath_executable_path_bundle
+  rpath_executable_path_postexcluded
+  rpath_loader_path_postexcluded
+  )
+  install(TARGETS ${t} DESTINATION bundle_executable/lib/${t})
+endforeach()
+
+foreach(t executable_path executable_path_bundle executable_path_postexcluded)
+  set_property(TARGET ${t} PROPERTY INSTALL_NAME_DIR @executable_path/../lib/${t})
+endforeach()
+
+foreach(t loader_path loader_path_unresolved loader_path_postexcluded)
+  set_property(TARGET ${t} PROPERTY INSTALL_NAME_DIR @loader_path/${t})
+endforeach()
+
+foreach(t
+  rpath
+  rpath_unresolved
+  rpath_postexcluded
+  rpath_executable_path
+  rpath_executable_path_bundle
+  rpath_executable_path_postexcluded
+  rpath_loader_path
+  rpath_loader_path_unresolved
+  rpath_loader_path_postexcluded
+  conflict
+  )
+  set_property(TARGET ${t} PROPERTY INSTALL_NAME_DIR @rpath)
+endforeach()
+
+foreach(t normal normal_unresolved normal_postexcluded)
+  set_property(TARGET ${t} PROPERTY INSTALL_NAME_DIR "${CMAKE_BINARY_DIR}/root-all/executable/lib/${t}")
+  if(NOT t STREQUAL "normal_unresolved")
+    install(TARGETS ${t} DESTINATION executable/lib/${t})
+  endif()
+endforeach()
+
+target_link_libraries(testlib PRIVATE ${testlib_names})
+
+add_executable(topexe macos/topexe.c)
+add_library(toplib SHARED macos/toplib.c)
+add_library(topmod MODULE macos/toplib.c)
+target_link_libraries(topexe PRIVATE testlib)
+target_link_libraries(toplib PRIVATE testlib)
+target_link_libraries(topmod PRIVATE testlib)
+
+set_property(TARGET topexe toplib topmod PROPERTY INSTALL_RPATH "${CMAKE_BINARY_DIR}/root-all/executable/lib")
+
+install(TARGETS topexe toplib topmod testlib testlib_conflict RUNTIME DESTINATION executable/bin LIBRARY DESTINATION executable/lib)
+install(TARGETS topexe toplib topmod testlib testlib_conflict RUNTIME DESTINATION bundle_executable/bin LIBRARY DESTINATION bundle_executable/lib)
+
+install(CODE [[
+  function(exec_get_runtime_dependencies depsfile udepsfile cdepsfile)
+    file(GET_RUNTIME_DEPENDENCIES
+      RESOLVED_DEPENDENCIES_VAR deps
+      UNRESOLVED_DEPENDENCIES_VAR udeps
+      CONFLICTING_DEPENDENCIES_PREFIX cdeps
+      PRE_INCLUDE_REGEXES "^.*/lib(testlib|executable_path|executable_path_bundle|executable_path_postexcluded|loader_path|loader_path_unresolved|loader_path_postexcluded|rpath|rpath_unresolved|rpath_postexcluded|rpath_executable_path|rpath_executable_path_bundle|rpath_executable_path_postexcluded|rpath_loader_path|rpath_loader_path_unresolved|rpath_loader_path_postexcluded|normal|normal_unresolved|normal_postexcluded|conflict|System\\.B)\\.dylib$"
+      PRE_EXCLUDE_REGEXES ".*"
+      POST_INCLUDE_REGEXES "^.*/lib(testlib|executable_path|executable_path_bundle|loader_path|rpath|rpath_executable_path|rpath_executable_path_bundle|rpath_loader_path|normal|conflict|System\\.B)\\.dylib$"
+      POST_EXCLUDE_REGEXES ".*"
+      ${ARGN}
+      )
+    list(SORT deps)
+    list(SORT udeps)
+    list(SORT cdeps_FILENAMES)
+    file(WRITE "${CMAKE_INSTALL_PREFIX}/deps/${depsfile}" "${deps}")
+    file(WRITE "${CMAKE_INSTALL_PREFIX}/deps/${udepsfile}" "${udeps}")
+    file(WRITE "${CMAKE_INSTALL_PREFIX}/deps/${cdepsfile}" "")
+    foreach(cdep IN LISTS cdeps_FILENAMES)
+      set(cdep_values ${cdeps_${cdep}})
+      list(SORT cdep_values)
+      file(APPEND "${CMAKE_INSTALL_PREFIX}/deps/${cdepsfile}" "${cdep}:${cdep_values}\n")
+    endforeach()
+  endfunction()
+
+  exec_get_runtime_dependencies(
+    deps1.txt udeps1.txt cdeps1.txt
+    EXECUTABLES
+      "${CMAKE_INSTALL_PREFIX}/executable/bin/$<TARGET_FILE_NAME:topexe>"
+    LIBRARIES
+      "${CMAKE_INSTALL_PREFIX}/executable/lib/$<TARGET_FILE_NAME:testlib_conflict>"
+    )
+
+  exec_get_runtime_dependencies(
+    deps2.txt udeps2.txt cdeps2.txt
+    LIBRARIES
+      "${CMAKE_INSTALL_PREFIX}/executable/lib/$<TARGET_FILE_NAME:toplib>"
+      "${CMAKE_INSTALL_PREFIX}/executable/lib/$<TARGET_FILE_NAME:testlib_conflict>"
+    )
+
+  exec_get_runtime_dependencies(
+    deps3.txt udeps3.txt cdeps3.txt
+    MODULES
+      "${CMAKE_INSTALL_PREFIX}/executable/lib/$<TARGET_FILE_NAME:topmod>"
+    LIBRARIES
+      "${CMAKE_INSTALL_PREFIX}/executable/lib/$<TARGET_FILE_NAME:testlib_conflict>"
+    )
+
+  exec_get_runtime_dependencies(
+    deps4.txt udeps4.txt cdeps4.txt
+    EXECUTABLES
+      "${CMAKE_INSTALL_PREFIX}/executable/bin/$<TARGET_FILE_NAME:topexe>"
+    LIBRARIES
+      "${CMAKE_INSTALL_PREFIX}/executable/lib/$<TARGET_FILE_NAME:testlib_conflict>"
+    BUNDLE_EXECUTABLE
+      "${CMAKE_INSTALL_PREFIX}/bundle_executable/bin/$<TARGET_FILE_NAME:topexe>"
+    )
+
+  exec_get_runtime_dependencies(
+    deps5.txt udeps5.txt cdeps5.txt
+    LIBRARIES
+      "${CMAKE_INSTALL_PREFIX}/executable/lib/$<TARGET_FILE_NAME:toplib>"
+      "${CMAKE_INSTALL_PREFIX}/executable/lib/$<TARGET_FILE_NAME:testlib_conflict>"
+    BUNDLE_EXECUTABLE "${CMAKE_INSTALL_PREFIX}/bundle_executable/bin/$<TARGET_FILE_NAME:topexe>"
+    )
+
+  exec_get_runtime_dependencies(
+    deps6.txt udeps6.txt cdeps6.txt
+    MODULES
+      "${CMAKE_INSTALL_PREFIX}/executable/lib/$<TARGET_FILE_NAME:topmod>"
+    LIBRARIES
+      "${CMAKE_INSTALL_PREFIX}/executable/lib/$<TARGET_FILE_NAME:testlib_conflict>"
+    BUNDLE_EXECUTABLE "${CMAKE_INSTALL_PREFIX}/bundle_executable/bin/$<TARGET_FILE_NAME:topexe>"
+    )
+  ]])
diff --git a/Tests/RunCMake/install/file-GET_RUNTIME_DEPENDENCIES-macos/topexe.c b/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/macos/topexe.c
similarity index 100%
rename from Tests/RunCMake/install/file-GET_RUNTIME_DEPENDENCIES-macos/topexe.c
rename to Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/macos/topexe.c
diff --git a/Tests/RunCMake/install/file-GET_RUNTIME_DEPENDENCIES-macos/toplib.c b/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/macos/toplib.c
similarity index 100%
rename from Tests/RunCMake/install/file-GET_RUNTIME_DEPENDENCIES-macos/toplib.c
rename to Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/macos/toplib.c
diff --git a/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/project-stderr.txt b/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/project-stderr.txt
new file mode 100644
index 0000000..f14a10d
--- /dev/null
+++ b/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/project-stderr.txt
@@ -0,0 +1,13 @@
+^CMake Warning \(dev\) at project\.cmake:[0-9]+ \(file\):
+  You have used file\(GET_RUNTIME_DEPENDENCIES\) in project mode\.  This is
+  probably not what you intended to do\.  Instead, please consider using it in
+  an install\(CODE\) or install\(SCRIPT\) command\.  For example:
+
+    install\(CODE \[\[
+      file\(GET_RUNTIME_DEPENDENCIES
+        # \.\.\.
+        \)
+      ]]\)
+Call Stack \(most recent call first\):
+  CMakeLists\.txt:[0-9]+ \(include\)
+This warning is for project developers\.  Use -Wno-dev to suppress it\.$
diff --git a/Tests/RunCMake/install/file-GET_RUNTIME_DEPENDENCIES-project.cmake b/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/project.cmake
similarity index 100%
rename from Tests/RunCMake/install/file-GET_RUNTIME_DEPENDENCIES-project.cmake
rename to Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/project.cmake
diff --git a/Tests/RunCMake/interface_library/whitelist-result.txt b/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/unsupported-result.txt
similarity index 100%
copy from Tests/RunCMake/interface_library/whitelist-result.txt
copy to Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/unsupported-result.txt
diff --git a/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/unsupported-stderr.txt b/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/unsupported-stderr.txt
new file mode 100644
index 0000000..000159f
--- /dev/null
+++ b/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/unsupported-stderr.txt
@@ -0,0 +1,5 @@
+^CMake Error at unsupported\.cmake:[0-9]+ \(file\):
+  file GET_RUNTIME_DEPENDENCIES is not supported on system "[^
+ ]+"
+Call Stack \(most recent call first\):
+  CMakeLists\.txt:[0-9]+ \(include\)$
diff --git a/Tests/RunCMake/install/file-GET_RUNTIME_DEPENDENCIES-unsupported.cmake b/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/unsupported.cmake
similarity index 100%
rename from Tests/RunCMake/install/file-GET_RUNTIME_DEPENDENCIES-unsupported.cmake
rename to Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/unsupported.cmake
diff --git a/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-install-result.txt b/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/variable-propagation-all-result.txt
similarity index 100%
copy from Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-install-result.txt
copy to Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/variable-propagation-all-result.txt
diff --git a/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/variable-propagation-all-stderr.txt b/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/variable-propagation-all-stderr.txt
new file mode 100644
index 0000000..591a5e7
--- /dev/null
+++ b/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/variable-propagation-all-stderr.txt
@@ -0,0 +1,6 @@
+^CMake Error at cmake_install\.cmake:[0-9]+ \(message\):
+.*
+.*CMAKE_GET_RUNTIME_DEPENDENCIES_PLATFORM: custom-platform.*
+.*CMAKE_GET_RUNTIME_DEPENDENCIES_TOOL: custom-platform-objdump.*
+.*CMAKE_GET_RUNTIME_DEPENDENCIES_COMMAND: path/to/custom-objdump.*
+.*CMAKE_OBJDUMP: custom-objdump.*
diff --git a/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-install-result.txt b/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/variable-propagation-dev-result.txt
similarity index 100%
copy from Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-install-result.txt
copy to Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/variable-propagation-dev-result.txt
diff --git a/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/variable-propagation-dev-stderr.txt b/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/variable-propagation-dev-stderr.txt
new file mode 100644
index 0000000..591a5e7
--- /dev/null
+++ b/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/variable-propagation-dev-stderr.txt
@@ -0,0 +1,6 @@
+^CMake Error at cmake_install\.cmake:[0-9]+ \(message\):
+.*
+.*CMAKE_GET_RUNTIME_DEPENDENCIES_PLATFORM: custom-platform.*
+.*CMAKE_GET_RUNTIME_DEPENDENCIES_TOOL: custom-platform-objdump.*
+.*CMAKE_GET_RUNTIME_DEPENDENCIES_COMMAND: path/to/custom-objdump.*
+.*CMAKE_OBJDUMP: custom-objdump.*
diff --git a/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/variable-propagation.cmake b/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/variable-propagation.cmake
new file mode 100644
index 0000000..07bbc5e
--- /dev/null
+++ b/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/variable-propagation.cmake
@@ -0,0 +1,17 @@
+enable_language(C)
+
+set(CMAKE_GET_RUNTIME_DEPENDENCIES_PLATFORM "custom-platform")
+set(CMAKE_GET_RUNTIME_DEPENDENCIES_TOOL "custom-platform-objdump")
+set(CMAKE_GET_RUNTIME_DEPENDENCIES_COMMAND "path/to/custom-objdump")
+set(CMAKE_OBJDUMP "custom-objdump")
+
+install(CODE [[
+message(FATAL_ERROR "
+  CMAKE_GET_RUNTIME_DEPENDENCIES_PLATFORM: ${CMAKE_GET_RUNTIME_DEPENDENCIES_PLATFORM}
+  CMAKE_GET_RUNTIME_DEPENDENCIES_TOOL: ${CMAKE_GET_RUNTIME_DEPENDENCIES_TOOL}
+  CMAKE_GET_RUNTIME_DEPENDENCIES_COMMAND: ${CMAKE_GET_RUNTIME_DEPENDENCIES_COMMAND}
+  CMAKE_OBJDUMP: ${CMAKE_OBJDUMP}
+")
+]]
+COMPONENT dev
+)
diff --git a/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/windows-all-check.cmake b/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/windows-all-check.cmake
new file mode 100644
index 0000000..f1d70a1
--- /dev/null
+++ b/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/windows-all-check.cmake
@@ -0,0 +1,38 @@
+function(check_contents filename contents_regex)
+  if(EXISTS "${CMAKE_INSTALL_PREFIX}/${filename}")
+    file(READ "${CMAKE_INSTALL_PREFIX}/${filename}" contents)
+    if(NOT contents MATCHES "${contents_regex}")
+      string(APPEND RunCMake_TEST_FAILED "File contents:
+  ${contents}
+do not match what we expected:
+  ${contents_regex}
+in file:
+  ${CMAKE_INSTALL_PREFIX}/${filename}\n")
+      set(RunCMake_TEST_FAILED "${RunCMake_TEST_FAILED}" PARENT_SCOPE)
+    endif()
+  else()
+    string(APPEND RunCMake_TEST_FAILED "File ${CMAKE_INSTALL_PREFIX}/${filename} does not exist")
+    set(RunCMake_TEST_FAILED "${RunCMake_TEST_FAILED}" PARENT_SCOPE)
+  endif()
+endfunction()
+
+set(_check
+  [=[[^;]*/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/windows-build/root-all/bin/\.conflict/\.\./(lib)?libdir\.dll]=]
+  [=[[^;]*/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/windows-build/root-all/bin/\.search/(lib)?search\.dll]=]
+  [=[[^;]*/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/windows-build/root-all/bin/(lib)?testlib\.dll]=]
+  )
+check_contents(deps/deps1.txt "^${_check}$")
+check_contents(deps/deps2.txt "^${_check}$")
+check_contents(deps/deps3.txt "^${_check}$")
+set(_check
+  [=[(lib)?unresolved\.dll]=]
+  )
+check_contents(deps/udeps1.txt "^${_check}$")
+check_contents(deps/udeps2.txt "^${_check}$")
+check_contents(deps/udeps3.txt "^${_check}$")
+set(_check
+  "^(lib)?conflict\\.dll:[^;]*/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/windows-build/root-all/bin/\\.conflict/(lib)?conflict\\.dll;[^;]*/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/windows-build/root-all/bin/(lib)?conflict\\.dll\n$"
+  )
+check_contents(deps/cdeps1.txt "${_check}")
+check_contents(deps/cdeps2.txt "${_check}")
+check_contents(deps/cdeps3.txt "${_check}")
diff --git a/Tests/RunCMake/install/file-GET_RUNTIME_DEPENDENCIES-windows-conflict-all-result.txt b/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/windows-conflict-all-result.txt
similarity index 100%
rename from Tests/RunCMake/install/file-GET_RUNTIME_DEPENDENCIES-windows-conflict-all-result.txt
rename to Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/windows-conflict-all-result.txt
diff --git a/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/windows-conflict-all-stderr.txt b/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/windows-conflict-all-stderr.txt
new file mode 100644
index 0000000..c48c55d
--- /dev/null
+++ b/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/windows-conflict-all-stderr.txt
@@ -0,0 +1,7 @@
+^CMake Error at cmake_install\.cmake:[0-9]+ \(file\):
+  file Multiple conflicting paths found for (lib)?path\.dll:
+
+    [^
+]*/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/windows-conflict-build/root-all/lib/test1/(lib)?path\.dll
+    [^
+]*/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/windows-conflict-build/root-all/lib/test2/(lib)?path\.dll$
diff --git a/Tests/RunCMake/install/file-GET_RUNTIME_DEPENDENCIES-windows-conflict.cmake b/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/windows-conflict.cmake
similarity index 100%
rename from Tests/RunCMake/install/file-GET_RUNTIME_DEPENDENCIES-windows-conflict.cmake
rename to Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/windows-conflict.cmake
diff --git a/Tests/RunCMake/install/file-GET_RUNTIME_DEPENDENCIES-windows-notfile-all-result.txt b/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/windows-notfile-all-result.txt
similarity index 100%
rename from Tests/RunCMake/install/file-GET_RUNTIME_DEPENDENCIES-windows-notfile-all-result.txt
rename to Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/windows-notfile-all-result.txt
diff --git a/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/windows-notfile-all-stderr.txt b/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/windows-notfile-all-stderr.txt
new file mode 100644
index 0000000..33c0390
--- /dev/null
+++ b/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/windows-notfile-all-stderr.txt
@@ -0,0 +1,5 @@
+^CMake Error at cmake_install\.cmake:[0-9]+ \(file\):
+  file Failed to run (dumpbin|objdump) on:
+
+    [^
+]*/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/windows-notfile-build/root-all/bin/(lib)?test\.dll$
diff --git a/Tests/RunCMake/install/file-GET_RUNTIME_DEPENDENCIES-windows-notfile.cmake b/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/windows-notfile.cmake
similarity index 100%
rename from Tests/RunCMake/install/file-GET_RUNTIME_DEPENDENCIES-windows-notfile.cmake
rename to Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/windows-notfile.cmake
diff --git a/Tests/RunCMake/install/file-GET_RUNTIME_DEPENDENCIES-windows-unresolved-all-result.txt b/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/windows-unresolved-all-result.txt
similarity index 100%
rename from Tests/RunCMake/install/file-GET_RUNTIME_DEPENDENCIES-windows-unresolved-all-result.txt
rename to Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/windows-unresolved-all-result.txt
diff --git a/Tests/RunCMake/install/file-GET_RUNTIME_DEPENDENCIES-windows-unresolved-all-stderr.txt b/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/windows-unresolved-all-stderr.txt
similarity index 100%
rename from Tests/RunCMake/install/file-GET_RUNTIME_DEPENDENCIES-windows-unresolved-all-stderr.txt
rename to Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/windows-unresolved-all-stderr.txt
diff --git a/Tests/RunCMake/install/file-GET_RUNTIME_DEPENDENCIES-windows-unresolved.cmake b/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/windows-unresolved.cmake
similarity index 100%
rename from Tests/RunCMake/install/file-GET_RUNTIME_DEPENDENCIES-windows-unresolved.cmake
rename to Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/windows-unresolved.cmake
diff --git a/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/windows.cmake b/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/windows.cmake
new file mode 100644
index 0000000..9160ce5
--- /dev/null
+++ b/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/windows.cmake
@@ -0,0 +1,114 @@
+enable_language(C)
+
+set(testlib_names
+  preexcluded
+  libdir_postexcluded
+  libdir
+  search_postexcluded
+  search
+  unresolved
+  conflict
+  )
+
+file(REMOVE "${CMAKE_BINARY_DIR}/testlib.c")
+add_library(testlib SHARED "${CMAKE_BINARY_DIR}/testlib.c")
+foreach(name ${testlib_names})
+  file(WRITE "${CMAKE_BINARY_DIR}/${name}.c" "__declspec(dllexport) void ${name}(void) {}\n")
+  add_library(${name} SHARED "${CMAKE_BINARY_DIR}/${name}.c")
+
+  file(APPEND "${CMAKE_BINARY_DIR}/testlib.c" "__declspec(dllimport) extern void ${name}(void);\n")
+endforeach()
+file(APPEND "${CMAKE_BINARY_DIR}/testlib.c" "__declspec(dllexport) void testlib(void)\n{\n")
+foreach(name ${testlib_names})
+  file(APPEND "${CMAKE_BINARY_DIR}/testlib.c" "  ${name}();\n")
+endforeach()
+file(APPEND "${CMAKE_BINARY_DIR}/testlib.c" "}\n")
+
+target_link_libraries(testlib PRIVATE ${testlib_names})
+
+file(WRITE "${CMAKE_BINARY_DIR}/testlib_conflict.c" "__declspec(dllimport) extern void conflict(void);\n__declspec(dllexport) void testlib_conflict(void)\n{\n  conflict();\n}\n")
+add_library(testlib_conflict SHARED "${CMAKE_BINARY_DIR}/testlib_conflict.c")
+target_link_libraries(testlib_conflict PRIVATE conflict)
+
+file(WRITE "${CMAKE_BINARY_DIR}/testlib_noconflict.c" "__declspec(dllimport) extern void libdir(void);\n__declspec(dllexport) void testlib_noconflict(void)\n{\n  libdir();\n}\n")
+add_library(testlib_noconflict SHARED "${CMAKE_BINARY_DIR}/testlib_noconflict.c")
+target_link_libraries(testlib_noconflict PRIVATE libdir)
+
+install(TARGETS testlib libdir_postexcluded libdir conflict testlib_noconflict DESTINATION bin)
+install(TARGETS libdir search_postexcluded search DESTINATION bin/.search) # Prefixing with "." ensures it is the first item after list(SORT)
+install(TARGETS testlib_conflict conflict DESTINATION bin/.conflict)
+
+add_executable(topexe windows/topexe.c)
+add_library(toplib SHARED windows/toplib.c)
+add_library(topmod MODULE windows/toplib.c)
+target_link_libraries(topexe PRIVATE testlib)
+target_link_libraries(toplib PRIVATE testlib)
+target_link_libraries(topmod PRIVATE testlib)
+
+install(TARGETS topexe toplib topmod DESTINATION bin)
+
+install(CODE [[
+  function(exec_get_runtime_dependencies depsfile udepsfile cdepsfile)
+    file(GET_RUNTIME_DEPENDENCIES
+      RESOLVED_DEPENDENCIES_VAR deps
+      UNRESOLVED_DEPENDENCIES_VAR udeps
+      CONFLICTING_DEPENDENCIES_PREFIX cdeps
+      PRE_INCLUDE_REGEXES
+        "^(lib)?testlib\\.dll$"
+        "^(lib)?libdir_postexcluded\\.dll$"
+        "^(lib)?libdir\\.dll$"
+        "^(lib)?search_postexcluded\\.dll$"
+        "^(lib)?search\\.dll$"
+        "^(lib)?unresolved\\.dll$"
+        "^(lib)?conflict\\.dll$"
+        "^kernel32\\.dll$"
+      PRE_EXCLUDE_REGEXES ".*"
+      POST_INCLUDE_REGEXES
+        "^.*/(lib)?testlib\\.dll$"
+        "^.*/(lib)?libdir\\.dll$"
+        "^.*/(lib)?search\\.dll$"
+        "^.*/(lib)?conflict\\.dll$"
+      POST_EXCLUDE_REGEXES ".*"
+      DIRECTORIES
+        "${CMAKE_INSTALL_PREFIX}/bin/.search"
+      ${ARGN}
+      )
+    list(SORT deps)
+    list(SORT udeps)
+    list(SORT cdeps_FILENAMES)
+    file(WRITE "${CMAKE_INSTALL_PREFIX}/deps/${depsfile}" "${deps}")
+    file(WRITE "${CMAKE_INSTALL_PREFIX}/deps/${udepsfile}" "${udeps}")
+    file(WRITE "${CMAKE_INSTALL_PREFIX}/deps/${cdepsfile}" "")
+    foreach(cdep IN LISTS cdeps_FILENAMES)
+      set(cdep_values ${cdeps_${cdep}})
+      list(SORT cdep_values)
+      file(APPEND "${CMAKE_INSTALL_PREFIX}/deps/${cdepsfile}" "${cdep}:${cdep_values}\n")
+    endforeach()
+  endfunction()
+
+  exec_get_runtime_dependencies(
+    deps1.txt udeps1.txt cdeps1.txt
+    EXECUTABLES
+      "${CMAKE_INSTALL_PREFIX}/bin/$<TARGET_FILE_NAME:topexe>"
+    LIBRARIES
+      "${CMAKE_INSTALL_PREFIX}/bin/.conflict/$<TARGET_FILE_NAME:testlib_conflict>"
+      "${CMAKE_INSTALL_PREFIX}/bin/.conflict/../$<TARGET_FILE_NAME:testlib_noconflict>"
+    )
+
+  exec_get_runtime_dependencies(
+    deps2.txt udeps2.txt cdeps2.txt
+    LIBRARIES
+      "${CMAKE_INSTALL_PREFIX}/bin/$<TARGET_FILE_NAME:toplib>"
+      "${CMAKE_INSTALL_PREFIX}/bin/.conflict/$<TARGET_FILE_NAME:testlib_conflict>"
+      "${CMAKE_INSTALL_PREFIX}/bin/.conflict/../$<TARGET_FILE_NAME:testlib_noconflict>"
+    )
+
+  exec_get_runtime_dependencies(
+    deps3.txt udeps3.txt cdeps3.txt
+    MODULES
+      "${CMAKE_INSTALL_PREFIX}/bin/$<TARGET_FILE_NAME:topmod>"
+    LIBRARIES
+      "${CMAKE_INSTALL_PREFIX}/bin/.conflict/$<TARGET_FILE_NAME:testlib_conflict>"
+      "${CMAKE_INSTALL_PREFIX}/bin/.conflict/../$<TARGET_FILE_NAME:testlib_noconflict>"
+    )
+  ]])
diff --git a/Tests/RunCMake/install/file-GET_RUNTIME_DEPENDENCIES-windows/topexe.c b/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/windows/topexe.c
similarity index 100%
rename from Tests/RunCMake/install/file-GET_RUNTIME_DEPENDENCIES-windows/topexe.c
rename to Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/windows/topexe.c
diff --git a/Tests/RunCMake/install/file-GET_RUNTIME_DEPENDENCIES-windows/toplib.c b/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/windows/toplib.c
similarity index 100%
rename from Tests/RunCMake/install/file-GET_RUNTIME_DEPENDENCIES-windows/toplib.c
rename to Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/windows/toplib.c
diff --git a/Tests/RunCMake/Languages/LINK_LANGUAGE-genex-result.txt b/Tests/RunCMake/file/DOWNLOAD-no-save-hash-result.txt
similarity index 100%
copy from Tests/RunCMake/Languages/LINK_LANGUAGE-genex-result.txt
copy to Tests/RunCMake/file/DOWNLOAD-no-save-hash-result.txt
diff --git a/Tests/RunCMake/file/DOWNLOAD-no-save-hash-stderr.txt b/Tests/RunCMake/file/DOWNLOAD-no-save-hash-stderr.txt
new file mode 100644
index 0000000..b0f0d19
--- /dev/null
+++ b/Tests/RunCMake/file/DOWNLOAD-no-save-hash-stderr.txt
@@ -0,0 +1,4 @@
+^CMake Error at DOWNLOAD-no-save-hash\.cmake:[0-9]+ \(file\):
+  file DOWNLOAD cannot calculate hash if file is not saved\.
+Call Stack \(most recent call first\):
+  CMakeLists\.txt:[0-9]+ \(include\)$
diff --git a/Tests/RunCMake/file/DOWNLOAD-no-save-hash.cmake b/Tests/RunCMake/file/DOWNLOAD-no-save-hash.cmake
new file mode 100644
index 0000000..ce959a7
--- /dev/null
+++ b/Tests/RunCMake/file/DOWNLOAD-no-save-hash.cmake
@@ -0,0 +1,8 @@
+if(NOT "${CMAKE_CURRENT_SOURCE_DIR}" MATCHES "^/")
+  set(slash /)
+endif()
+file(DOWNLOAD
+  "file://${slash}${CMAKE_CURRENT_SOURCE_DIR}/DOWNLOAD-no-save-md5.txt"
+  EXPECTED_HASH MD5=55555555555555555555555555555555
+  STATUS status
+  )
diff --git a/Tests/RunCMake/file/DOWNLOAD-no-save-hash.txt b/Tests/RunCMake/file/DOWNLOAD-no-save-hash.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/Tests/RunCMake/file/DOWNLOAD-no-save-hash.txt
diff --git a/Tests/RunCMake/Languages/LINK_LANGUAGE-genex-result.txt b/Tests/RunCMake/file/DOWNLOAD-tls-cainfo-not-set-result.txt
similarity index 100%
copy from Tests/RunCMake/Languages/LINK_LANGUAGE-genex-result.txt
copy to Tests/RunCMake/file/DOWNLOAD-tls-cainfo-not-set-result.txt
diff --git a/Tests/RunCMake/file/DOWNLOAD-tls-cainfo-not-set-stderr.txt b/Tests/RunCMake/file/DOWNLOAD-tls-cainfo-not-set-stderr.txt
new file mode 100644
index 0000000..1552baa
--- /dev/null
+++ b/Tests/RunCMake/file/DOWNLOAD-tls-cainfo-not-set-stderr.txt
@@ -0,0 +1,4 @@
+^CMake Error at DOWNLOAD-tls-cainfo-not-set.cmake:[0-9]+ \(file\):
+  file DOWNLOAD missing file value for TLS_CAINFO.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:[0-9]+ \(include\)$
diff --git a/Tests/RunCMake/file/DOWNLOAD-tls-cainfo-not-set.cmake b/Tests/RunCMake/file/DOWNLOAD-tls-cainfo-not-set.cmake
new file mode 100644
index 0000000..b476425
--- /dev/null
+++ b/Tests/RunCMake/file/DOWNLOAD-tls-cainfo-not-set.cmake
@@ -0,0 +1 @@
+file(DOWNLOAD "" "" TLS_CAINFO)
diff --git a/Tests/RunCMake/Languages/LINK_LANGUAGE-genex-result.txt b/Tests/RunCMake/file/DOWNLOAD-tls-verify-not-set-result.txt
similarity index 100%
copy from Tests/RunCMake/Languages/LINK_LANGUAGE-genex-result.txt
copy to Tests/RunCMake/file/DOWNLOAD-tls-verify-not-set-result.txt
diff --git a/Tests/RunCMake/file/DOWNLOAD-tls-verify-not-set-stderr.txt b/Tests/RunCMake/file/DOWNLOAD-tls-verify-not-set-stderr.txt
new file mode 100644
index 0000000..2f46c0c
--- /dev/null
+++ b/Tests/RunCMake/file/DOWNLOAD-tls-verify-not-set-stderr.txt
@@ -0,0 +1,4 @@
+^CMake Error at DOWNLOAD-tls-verify-not-set.cmake:[0-9]+ \(file\):
+  file DOWNLOAD missing bool value for TLS_VERIFY.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:[0-9]+ \(include\)$
diff --git a/Tests/RunCMake/file/DOWNLOAD-tls-verify-not-set.cmake b/Tests/RunCMake/file/DOWNLOAD-tls-verify-not-set.cmake
new file mode 100644
index 0000000..919368c
--- /dev/null
+++ b/Tests/RunCMake/file/DOWNLOAD-tls-verify-not-set.cmake
@@ -0,0 +1 @@
+file(DOWNLOAD "" "" TLS_VERIFY)
diff --git a/Tests/RunCMake/file/RunCMakeTest.cmake b/Tests/RunCMake/file/RunCMakeTest.cmake
index f5461ad..8d84943 100644
--- a/Tests/RunCMake/file/RunCMakeTest.cmake
+++ b/Tests/RunCMake/file/RunCMakeTest.cmake
@@ -8,13 +8,18 @@
 run_cmake(DOWNLOAD-unused-argument)
 run_cmake(DOWNLOAD-httpheader-not-set)
 run_cmake(DOWNLOAD-netrc-bad)
+run_cmake(DOWNLOAD-tls-cainfo-not-set)
+run_cmake(DOWNLOAD-tls-verify-not-set)
 run_cmake(DOWNLOAD-pass-not-set)
+run_cmake(DOWNLOAD-no-save-hash)
 run_cmake(TOUCH)
 run_cmake(TOUCH-error-in-source-directory)
 run_cmake(TOUCH-error-missing-directory)
 run_cmake(UPLOAD-unused-argument)
 run_cmake(UPLOAD-httpheader-not-set)
 run_cmake(UPLOAD-netrc-bad)
+run_cmake(UPLOAD-tls-cainfo-not-set)
+run_cmake(UPLOAD-tls-verify-not-set)
 run_cmake(UPLOAD-pass-not-set)
 run_cmake(INSTALL-DIRECTORY)
 run_cmake(INSTALL-FILES_FROM_DIR)
diff --git a/Tests/RunCMake/Languages/LINK_LANGUAGE-genex-result.txt b/Tests/RunCMake/file/UPLOAD-tls-cainfo-not-set-result.txt
similarity index 100%
copy from Tests/RunCMake/Languages/LINK_LANGUAGE-genex-result.txt
copy to Tests/RunCMake/file/UPLOAD-tls-cainfo-not-set-result.txt
diff --git a/Tests/RunCMake/file/UPLOAD-tls-cainfo-not-set-stderr.txt b/Tests/RunCMake/file/UPLOAD-tls-cainfo-not-set-stderr.txt
new file mode 100644
index 0000000..a5fa4e8
--- /dev/null
+++ b/Tests/RunCMake/file/UPLOAD-tls-cainfo-not-set-stderr.txt
@@ -0,0 +1,4 @@
+^CMake Error at UPLOAD-tls-cainfo-not-set.cmake:[0-9]+ \(file\):
+  file UPLOAD missing file value for TLS_CAINFO.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:[0-9]+ \(include\)$
diff --git a/Tests/RunCMake/file/UPLOAD-tls-cainfo-not-set.cmake b/Tests/RunCMake/file/UPLOAD-tls-cainfo-not-set.cmake
new file mode 100644
index 0000000..8eb7c83
--- /dev/null
+++ b/Tests/RunCMake/file/UPLOAD-tls-cainfo-not-set.cmake
@@ -0,0 +1 @@
+file(UPLOAD "" "" TLS_CAINFO)
diff --git a/Tests/RunCMake/Languages/LINK_LANGUAGE-genex-result.txt b/Tests/RunCMake/file/UPLOAD-tls-verify-not-set-result.txt
similarity index 100%
copy from Tests/RunCMake/Languages/LINK_LANGUAGE-genex-result.txt
copy to Tests/RunCMake/file/UPLOAD-tls-verify-not-set-result.txt
diff --git a/Tests/RunCMake/file/UPLOAD-tls-verify-not-set-stderr.txt b/Tests/RunCMake/file/UPLOAD-tls-verify-not-set-stderr.txt
new file mode 100644
index 0000000..c4dffcd
--- /dev/null
+++ b/Tests/RunCMake/file/UPLOAD-tls-verify-not-set-stderr.txt
@@ -0,0 +1,4 @@
+^CMake Error at UPLOAD-tls-verify-not-set.cmake:[0-9]+ \(file\):
+  file UPLOAD missing bool value for TLS_VERIFY.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:[0-9]+ \(include\)$
diff --git a/Tests/RunCMake/file/UPLOAD-tls-verify-not-set.cmake b/Tests/RunCMake/file/UPLOAD-tls-verify-not-set.cmake
new file mode 100644
index 0000000..8b9d293
--- /dev/null
+++ b/Tests/RunCMake/file/UPLOAD-tls-verify-not-set.cmake
@@ -0,0 +1 @@
+file(UPLOAD "" "" TLS_VERIFY)
diff --git a/Tests/RunCMake/find_dependency/CMakeLists.txt b/Tests/RunCMake/find_dependency/CMakeLists.txt
index 12cd3c7..74b3ff8 100644
--- a/Tests/RunCMake/find_dependency/CMakeLists.txt
+++ b/Tests/RunCMake/find_dependency/CMakeLists.txt
@@ -1,3 +1,3 @@
-cmake_minimum_required(VERSION 2.8.4)
+cmake_minimum_required(VERSION 3.3)
 project(${RunCMake_TEST} NONE)
 include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/interface_library/whitelist-result.txt b/Tests/RunCMake/find_file/Required-result.txt
similarity index 100%
copy from Tests/RunCMake/interface_library/whitelist-result.txt
copy to Tests/RunCMake/find_file/Required-result.txt
diff --git a/Tests/RunCMake/find_file/Required-stderr.txt b/Tests/RunCMake/find_file/Required-stderr.txt
new file mode 100644
index 0000000..f9c337c
--- /dev/null
+++ b/Tests/RunCMake/find_file/Required-stderr.txt
@@ -0,0 +1,4 @@
+CMake Error at Required.cmake:9 \(find_file\):
+  Could not find FILE_doNotExists using the following files: doNotExists.h
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/find_file/Required-stdout.txt b/Tests/RunCMake/find_file/Required-stdout.txt
new file mode 100644
index 0000000..87a8e86
--- /dev/null
+++ b/Tests/RunCMake/find_file/Required-stdout.txt
@@ -0,0 +1 @@
+-- FILE_exists='[^']*/Tests/RunCMake/find_file/include/PrefixInPATH.h'
diff --git a/Tests/RunCMake/find_file/Required.cmake b/Tests/RunCMake/find_file/Required.cmake
new file mode 100644
index 0000000..9cf0927
--- /dev/null
+++ b/Tests/RunCMake/find_file/Required.cmake
@@ -0,0 +1,12 @@
+find_file(FILE_exists
+  NAMES PrefixInPATH.h
+  PATHS ${CMAKE_CURRENT_SOURCE_DIR}/include
+  NO_DEFAULT_PATH
+  REQUIRED
+  )
+message(STATUS "FILE_exists='${FILE_exists}'")
+
+find_file(FILE_doNotExists
+  NAMES doNotExists.h
+  REQUIRED
+  )
diff --git a/Tests/RunCMake/find_file/RunCMakeTest.cmake b/Tests/RunCMake/find_file/RunCMakeTest.cmake
index 9f56a57..93dfb78 100644
--- a/Tests/RunCMake/find_file/RunCMakeTest.cmake
+++ b/Tests/RunCMake/find_file/RunCMakeTest.cmake
@@ -3,3 +3,4 @@
 run_cmake(FromPATHEnv)
 run_cmake(FromPrefixPath)
 run_cmake(PrefixInPATH)
+run_cmake(Required)
diff --git a/Tests/RunCMake/find_library/LibSymLink-stderr.txt b/Tests/RunCMake/find_library/LibSymLink-stderr.txt
new file mode 100644
index 0000000..8a2f088
--- /dev/null
+++ b/Tests/RunCMake/find_library/LibSymLink-stderr.txt
@@ -0,0 +1,2 @@
+^SYMLINK_LIBRARY='SYMLINK_LIBRARY-NOTFOUND'
+SYMLINK_LIBRARY='[^']*/Tests/RunCMake/find_library/LibSymLink-build/lib/libsymlink.a'$
diff --git a/Tests/RunCMake/find_library/LibSymLink.cmake b/Tests/RunCMake/find_library/LibSymLink.cmake
new file mode 100644
index 0000000..8ee4b75
--- /dev/null
+++ b/Tests/RunCMake/find_library/LibSymLink.cmake
@@ -0,0 +1,17 @@
+list(APPEND CMAKE_FIND_LIBRARY_PREFIXES lib)
+list(APPEND CMAKE_FIND_LIBRARY_SUFFIXES .a)
+file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/lib)
+file(CREATE_LINK "libsymlinked.a" "${CMAKE_CURRENT_BINARY_DIR}/lib/libsymlink.a" SYMBOLIC)
+find_library(SYMLINK_LIBRARY
+  NAMES symlink
+  PATHS ${CMAKE_CURRENT_BINARY_DIR}/lib
+  NO_DEFAULT_PATH
+  )
+message("SYMLINK_LIBRARY='${SYMLINK_LIBRARY}'")
+file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/lib/libsymlinked.a" "symlinked")
+find_library(SYMLINK_LIBRARY
+  NAMES symlink
+  PATHS ${CMAKE_CURRENT_BINARY_DIR}/lib
+  NO_DEFAULT_PATH
+  )
+message("SYMLINK_LIBRARY='${SYMLINK_LIBRARY}'")
diff --git a/Tests/RunCMake/interface_library/whitelist-result.txt b/Tests/RunCMake/find_library/Required-result.txt
similarity index 100%
rename from Tests/RunCMake/interface_library/whitelist-result.txt
rename to Tests/RunCMake/find_library/Required-result.txt
diff --git a/Tests/RunCMake/find_library/Required-stderr.txt b/Tests/RunCMake/find_library/Required-stderr.txt
new file mode 100644
index 0000000..545d164
--- /dev/null
+++ b/Tests/RunCMake/find_library/Required-stderr.txt
@@ -0,0 +1,4 @@
+CMake Error at Required.cmake:11 \(find_library\):
+  Could not find LIB_doNotExists using the following names: doNotExists
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/find_library/Required-stdout.txt b/Tests/RunCMake/find_library/Required-stdout.txt
new file mode 100644
index 0000000..b88ab79
--- /dev/null
+++ b/Tests/RunCMake/find_library/Required-stdout.txt
@@ -0,0 +1 @@
+-- LIB_exists='[^']*/Tests/RunCMake/find_library/lib/libPrefixInPATH.a'
diff --git a/Tests/RunCMake/find_library/Required.cmake b/Tests/RunCMake/find_library/Required.cmake
new file mode 100644
index 0000000..78c9f87
--- /dev/null
+++ b/Tests/RunCMake/find_library/Required.cmake
@@ -0,0 +1,14 @@
+list(APPEND CMAKE_FIND_LIBRARY_PREFIXES lib)
+list(APPEND CMAKE_FIND_LIBRARY_SUFFIXES .a)
+find_library(LIB_exists
+  NAMES PrefixInPATH
+  PATHS ${CMAKE_CURRENT_SOURCE_DIR}/lib
+  NO_DEFAULT_PATH
+  REQUIRED
+  )
+message(STATUS "LIB_exists='${LIB_exists}'")
+
+find_library(LIB_doNotExists
+  NAMES doNotExists
+  REQUIRED
+  )
diff --git a/Tests/RunCMake/find_library/RunCMakeTest.cmake b/Tests/RunCMake/find_library/RunCMakeTest.cmake
index 643a5b9..c7d69e4 100644
--- a/Tests/RunCMake/find_library/RunCMakeTest.cmake
+++ b/Tests/RunCMake/find_library/RunCMakeTest.cmake
@@ -3,7 +3,9 @@
 run_cmake(Created)
 run_cmake(FromPrefixPath)
 run_cmake(FromPATHEnv)
-if(CMAKE_HOST_UNIX)
+if(UNIX AND NOT CYGWIN)
   run_cmake(LibArchLink)
+  run_cmake(LibSymLink)
 endif()
 run_cmake(PrefixInPATH)
+run_cmake(Required)
diff --git a/Tests/RunCMake/find_package/CMakeLists.txt b/Tests/RunCMake/find_package/CMakeLists.txt
index 12cd3c7..74b3ff8 100644
--- a/Tests/RunCMake/find_package/CMakeLists.txt
+++ b/Tests/RunCMake/find_package/CMakeLists.txt
@@ -1,3 +1,3 @@
-cmake_minimum_required(VERSION 2.8.4)
+cmake_minimum_required(VERSION 3.3)
 project(${RunCMake_TEST} NONE)
 include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/find_package/MissingNormalWarnNoModuleOld-stderr.txt b/Tests/RunCMake/find_package/MissingNormalWarnNoModuleOld-stderr.txt
index b336b56..ebfd7d0 100644
--- a/Tests/RunCMake/find_package/MissingNormalWarnNoModuleOld-stderr.txt
+++ b/Tests/RunCMake/find_package/MissingNormalWarnNoModuleOld-stderr.txt
@@ -1,9 +1,10 @@
 CMake Warning \(dev\) at MissingNormalWarnNoModuleOld.cmake:2 \(find_package\):
-  find_package called without NO_MODULE option and no FindNotHere.cmake
-  module is in CMAKE_MODULE_PATH.  Add NO_MODULE to exclusively request
-  Config mode and search for a package configuration file provided by NotHere
-  \(NotHereConfig.cmake or nothere-config.cmake\).  Otherwise make
-  FindNotHere.cmake available in CMAKE_MODULE_PATH.
+  find_package called without either MODULE or CONFIG option and no
+  FindNotHere.cmake module is in CMAKE_MODULE_PATH.  Add MODULE to
+  exclusively request Module mode and fail if FindNotHere.cmake is missing.
+  Add CONFIG to exclusively request Config mode and search for a package
+  configuration file provided by NotHere \(NotHereConfig.cmake or
+  nothere-config.cmake\).
 
   \(Variable CMAKE_FIND_PACKAGE_WARN_NO_MODULE enabled this warning.\)
 Call Stack \(most recent call first\):
diff --git a/Tests/RunCMake/interface_library/whitelist-result.txt b/Tests/RunCMake/find_path/Required-result.txt
similarity index 100%
copy from Tests/RunCMake/interface_library/whitelist-result.txt
copy to Tests/RunCMake/find_path/Required-result.txt
diff --git a/Tests/RunCMake/find_path/Required-stderr.txt b/Tests/RunCMake/find_path/Required-stderr.txt
new file mode 100644
index 0000000..db65c2f
--- /dev/null
+++ b/Tests/RunCMake/find_path/Required-stderr.txt
@@ -0,0 +1,4 @@
+CMake Error at Required.cmake:9 \(find_path\):
+  Could not find PATH_doNotExists using the following files: doNotExists.h
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/find_path/Required-stdout.txt b/Tests/RunCMake/find_path/Required-stdout.txt
new file mode 100644
index 0000000..225fcab
--- /dev/null
+++ b/Tests/RunCMake/find_path/Required-stdout.txt
@@ -0,0 +1 @@
+-- PATH_exists='[^']*/Tests/RunCMake/find_path/include'
diff --git a/Tests/RunCMake/find_path/Required.cmake b/Tests/RunCMake/find_path/Required.cmake
new file mode 100644
index 0000000..172dc11
--- /dev/null
+++ b/Tests/RunCMake/find_path/Required.cmake
@@ -0,0 +1,12 @@
+find_path(PATH_exists
+  NAMES PrefixInPATH.h
+  PATHS ${CMAKE_CURRENT_SOURCE_DIR}/include
+  NO_DEFAULT_PATH
+  REQUIRED
+  )
+message(STATUS "PATH_exists='${PATH_exists}'")
+
+find_path(PATH_doNotExists
+  NAMES doNotExists.h
+  REQUIRED
+  )
diff --git a/Tests/RunCMake/find_path/RunCMakeTest.cmake b/Tests/RunCMake/find_path/RunCMakeTest.cmake
index ed55f51..5c919bb 100644
--- a/Tests/RunCMake/find_path/RunCMakeTest.cmake
+++ b/Tests/RunCMake/find_path/RunCMakeTest.cmake
@@ -3,6 +3,7 @@
 run_cmake(EmptyOldStyle)
 run_cmake(FromPATHEnv)
 run_cmake(PrefixInPATH)
+run_cmake(Required)
 
 if(APPLE)
   run_cmake(FrameworksWithSubdirs)
diff --git a/Tests/RunCMake/find_program/BundleSpaceInName-stdout.txt b/Tests/RunCMake/find_program/BundleSpaceInName-stdout.txt
new file mode 100644
index 0000000..331d465
--- /dev/null
+++ b/Tests/RunCMake/find_program/BundleSpaceInName-stdout.txt
@@ -0,0 +1 @@
+-- FakeApp_EXECUTABLE='.*/Tests/RunCMake/find_program/BundleSpaceInName-build/Fake app.app/Contents/MacOS/Fake app'
diff --git a/Tests/RunCMake/find_program/BundleSpaceInName.cmake b/Tests/RunCMake/find_program/BundleSpaceInName.cmake
new file mode 100644
index 0000000..9152d5b
--- /dev/null
+++ b/Tests/RunCMake/find_program/BundleSpaceInName.cmake
@@ -0,0 +1,8 @@
+set(fakeApp "${CMAKE_CURRENT_BINARY_DIR}/Fake app.app/Contents/MacOS/Fake app")
+file(WRITE "${fakeApp}" "#!/bin/sh\n")
+execute_process(COMMAND chmod a+rx "${fakeApp}")
+
+find_program(FakeApp_EXECUTABLE NAMES "Fake app" NO_DEFAULT_PATH
+  PATHS "${CMAKE_CURRENT_BINARY_DIR}"
+)
+message(STATUS "FakeApp_EXECUTABLE='${FakeApp_EXECUTABLE}'")
diff --git a/Tests/RunCMake/find_program/CMP0109-Common.cmake b/Tests/RunCMake/find_program/CMP0109-Common.cmake
new file mode 100644
index 0000000..525413a
--- /dev/null
+++ b/Tests/RunCMake/find_program/CMP0109-Common.cmake
@@ -0,0 +1,7 @@
+file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/ExeNoRead" "#!/bin/sh\n")
+file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/ReadNoExe" "#ReadNoExe")
+execute_process(COMMAND chmod -r+x "${CMAKE_CURRENT_BINARY_DIR}/ExeNoRead")
+find_program(ExeNoRead_EXECUTABLE NAMES ExeNoRead NO_DEFAULT_PATH PATHS "${CMAKE_CURRENT_BINARY_DIR}")
+message(STATUS "ExeNoRead_EXECUTABLE='${ExeNoRead_EXECUTABLE}'")
+find_program(ReadNoExe_EXECUTABLE NAMES ReadNoExe NO_DEFAULT_PATH PATHS "${CMAKE_CURRENT_BINARY_DIR}")
+message(STATUS "ReadNoExe_EXECUTABLE='${ReadNoExe_EXECUTABLE}'")
diff --git a/Tests/RunCMake/find_program/CMP0109-NEW-stdout.txt b/Tests/RunCMake/find_program/CMP0109-NEW-stdout.txt
new file mode 100644
index 0000000..2744463
--- /dev/null
+++ b/Tests/RunCMake/find_program/CMP0109-NEW-stdout.txt
@@ -0,0 +1,2 @@
+-- ExeNoRead_EXECUTABLE='.*/Tests/RunCMake/find_program/CMP0109-NEW-build/ExeNoRead'
+-- ReadNoExe_EXECUTABLE='ReadNoExe_EXECUTABLE-NOTFOUND'
diff --git a/Tests/RunCMake/find_program/CMP0109-NEW.cmake b/Tests/RunCMake/find_program/CMP0109-NEW.cmake
new file mode 100644
index 0000000..b4a4033
--- /dev/null
+++ b/Tests/RunCMake/find_program/CMP0109-NEW.cmake
@@ -0,0 +1,2 @@
+cmake_policy(SET CMP0109 NEW)
+include(CMP0109-Common.cmake)
diff --git a/Tests/RunCMake/find_program/CMP0109-OLD-stdout.txt b/Tests/RunCMake/find_program/CMP0109-OLD-stdout.txt
new file mode 100644
index 0000000..1a0e2a8
--- /dev/null
+++ b/Tests/RunCMake/find_program/CMP0109-OLD-stdout.txt
@@ -0,0 +1,2 @@
+-- ExeNoRead_EXECUTABLE='ExeNoRead_EXECUTABLE-NOTFOUND'
+-- ReadNoExe_EXECUTABLE='.*/Tests/RunCMake/find_program/CMP0109-OLD-build/ReadNoExe'
diff --git a/Tests/RunCMake/find_program/CMP0109-OLD.cmake b/Tests/RunCMake/find_program/CMP0109-OLD.cmake
new file mode 100644
index 0000000..8260161
--- /dev/null
+++ b/Tests/RunCMake/find_program/CMP0109-OLD.cmake
@@ -0,0 +1,2 @@
+cmake_policy(SET CMP0109 OLD)
+include(CMP0109-Common.cmake)
diff --git a/Tests/RunCMake/find_program/CMP0109-WARN-stderr.txt b/Tests/RunCMake/find_program/CMP0109-WARN-stderr.txt
new file mode 100644
index 0000000..202fc6d
--- /dev/null
+++ b/Tests/RunCMake/find_program/CMP0109-WARN-stderr.txt
@@ -0,0 +1,29 @@
+^CMake Warning \(dev\) at CMP0109-Common.cmake:4 \(find_program\):
+  Policy CMP0109 is not set: find_program\(\) requires permission to execute
+  but not to read.  Run "cmake --help-policy CMP0109" for policy details.
+  Use the cmake_policy command to set the policy and suppress this warning.
+
+  The file
+
+    .*/Tests/RunCMake/find_program/CMP0109-WARN-build/ExeNoRead
+
+  is executable but not readable.  CMake is ignoring it for compatibility.
+Call Stack \(most recent call first\):
+  CMP0109-WARN.cmake:1 \(include\)
+  CMakeLists.txt:3 \(include\)
+This warning is for project developers.  Use -Wno-dev to suppress it.
++
+CMake Warning \(dev\) at CMP0109-Common.cmake:6 \(find_program\):
+  Policy CMP0109 is not set: find_program\(\) requires permission to execute
+  but not to read.  Run "cmake --help-policy CMP0109" for policy details.
+  Use the cmake_policy command to set the policy and suppress this warning.
+
+  The file
+
+    .*/Tests/RunCMake/find_program/CMP0109-WARN-build/ReadNoExe
+
+  is readable but not executable.  CMake is using it for compatibility.
+Call Stack \(most recent call first\):
+  CMP0109-WARN.cmake:1 \(include\)
+  CMakeLists.txt:3 \(include\)
+This warning is for project developers.  Use -Wno-dev to suppress it.$
diff --git a/Tests/RunCMake/find_program/CMP0109-WARN-stdout.txt b/Tests/RunCMake/find_program/CMP0109-WARN-stdout.txt
new file mode 100644
index 0000000..baf560f
--- /dev/null
+++ b/Tests/RunCMake/find_program/CMP0109-WARN-stdout.txt
@@ -0,0 +1,2 @@
+-- ExeNoRead_EXECUTABLE='ExeNoRead_EXECUTABLE-NOTFOUND'
+-- ReadNoExe_EXECUTABLE='.*/Tests/RunCMake/find_program/CMP0109-WARN-build/ReadNoExe'
diff --git a/Tests/RunCMake/find_program/CMP0109-WARN.cmake b/Tests/RunCMake/find_program/CMP0109-WARN.cmake
new file mode 100644
index 0000000..a3d59af
--- /dev/null
+++ b/Tests/RunCMake/find_program/CMP0109-WARN.cmake
@@ -0,0 +1 @@
+include(CMP0109-Common.cmake)
diff --git a/Tests/RunCMake/interface_library/whitelist-result.txt b/Tests/RunCMake/find_program/Required-result.txt
similarity index 100%
copy from Tests/RunCMake/interface_library/whitelist-result.txt
copy to Tests/RunCMake/find_program/Required-result.txt
diff --git a/Tests/RunCMake/find_program/Required-stderr.txt b/Tests/RunCMake/find_program/Required-stderr.txt
new file mode 100644
index 0000000..214a8d4
--- /dev/null
+++ b/Tests/RunCMake/find_program/Required-stderr.txt
@@ -0,0 +1,4 @@
+CMake Error at Required.cmake:9 \(find_program\):
+  Could not find PROG_AandB using the following names: testAandB
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/find_program/Required-stdout.txt b/Tests/RunCMake/find_program/Required-stdout.txt
new file mode 100644
index 0000000..3c8f1b5
--- /dev/null
+++ b/Tests/RunCMake/find_program/Required-stdout.txt
@@ -0,0 +1 @@
+-- PROG_A='[^']*/Tests/RunCMake/find_program/A/testA'
diff --git a/Tests/RunCMake/find_program/Required.cmake b/Tests/RunCMake/find_program/Required.cmake
new file mode 100644
index 0000000..a75aa53
--- /dev/null
+++ b/Tests/RunCMake/find_program/Required.cmake
@@ -0,0 +1,12 @@
+find_program(PROG_A
+  NAMES testA
+  PATHS ${CMAKE_CURRENT_SOURCE_DIR}/A
+  NO_DEFAULT_PATH
+  REQUIRED
+  )
+message(STATUS "PROG_A='${PROG_A}'")
+
+find_program(PROG_AandB
+  NAMES testAandB
+  REQUIRED
+  )
diff --git a/Tests/RunCMake/find_program/RunCMakeTest.cmake b/Tests/RunCMake/find_program/RunCMakeTest.cmake
index 6903f05..3e23920 100644
--- a/Tests/RunCMake/find_program/RunCMakeTest.cmake
+++ b/Tests/RunCMake/find_program/RunCMakeTest.cmake
@@ -4,8 +4,25 @@
 run_cmake(DirsPerName)
 run_cmake(NamesPerDir)
 run_cmake(RelAndAbsPath)
+run_cmake(Required)
 
 if(CMAKE_SYSTEM_NAME MATCHES "^(Windows|CYGWIN)$")
   run_cmake(WindowsCom)
   run_cmake(WindowsExe)
+else()
+  # test non readable file only if not root
+  execute_process(
+    COMMAND id -u $ENV{USER}
+    OUTPUT_VARIABLE uid
+    OUTPUT_STRIP_TRAILING_WHITESPACE)
+
+  if(NOT "${uid}" STREQUAL "0")
+    run_cmake(CMP0109-WARN)
+    run_cmake(CMP0109-OLD)
+    run_cmake(CMP0109-NEW)
+  endif()
+endif()
+
+if(APPLE)
+  run_cmake(BundleSpaceInName)
 endif()
diff --git a/Tests/RunCMake/foreach/foreach-ZIP_LISTS-multiple-iter-vars-test.cmake b/Tests/RunCMake/foreach/foreach-ZIP_LISTS-multiple-iter-vars-test.cmake
index 9647dea..3b03ed7 100644
--- a/Tests/RunCMake/foreach/foreach-ZIP_LISTS-multiple-iter-vars-test.cmake
+++ b/Tests/RunCMake/foreach/foreach-ZIP_LISTS-multiple-iter-vars-test.cmake
@@ -8,13 +8,13 @@
     list(APPEND CMAKE_MESSAGE_INDENT "| ")
     foreach(first second third IN ZIP_LISTS ${list_var_1} ${list_var_2} ${list_var_3})
         if(NOT first)
-            set(first "[undefiend]")
+            set(first "[undefined]")
         endif()
         if(NOT second)
-            set(second "[undefiend]")
+            set(second "[undefined]")
         endif()
         if(NOT third)
-            set(third "[undefiend]")
+            set(third "[undefined]")
         endif()
         if(NOT _arg_MUTE)
             message(STATUS "${first}, ${second}, ${third}")
diff --git a/Tests/RunCMake/foreach/foreach-ZIP_LISTS-test-stdout.txt b/Tests/RunCMake/foreach/foreach-ZIP_LISTS-test-stdout.txt
index 25433fd..4730a86 100644
--- a/Tests/RunCMake/foreach/foreach-ZIP_LISTS-test-stdout.txt
+++ b/Tests/RunCMake/foreach/foreach-ZIP_LISTS-test-stdout.txt
@@ -14,6 +14,6 @@
 --     | one, satu, raz
 --     | two, dua, dva
 --     | three, tiga, tri
---     | \[undefiend\], empat, \[undefiend\]
+--     | \[undefined\], empat, \[undefined\]
 --     End output
 --   <<< test variable value restored -- PASSED >>>
diff --git a/Tests/RunCMake/foreach/foreach-ZIP_LISTS-test.cmake b/Tests/RunCMake/foreach/foreach-ZIP_LISTS-test.cmake
index 56cfe64..aa0ed07 100644
--- a/Tests/RunCMake/foreach/foreach-ZIP_LISTS-test.cmake
+++ b/Tests/RunCMake/foreach/foreach-ZIP_LISTS-test.cmake
@@ -9,7 +9,7 @@
     foreach(num IN ZIP_LISTS ${list_var_1} ${list_var_2} ${list_var_3})
         foreach(i RANGE 2)
             if(NOT num_${i})
-                set(num_${i} "[undefiend]")
+                set(num_${i} "[undefined]")
             endif()
         endforeach()
         if(NOT _arg_MUTE)
diff --git a/Tests/RunCMake/interface_library/target_commands-result.txt b/Tests/RunCMake/get_filename_component/IncorrectArguments-result.txt
similarity index 100%
copy from Tests/RunCMake/interface_library/target_commands-result.txt
copy to Tests/RunCMake/get_filename_component/IncorrectArguments-result.txt
diff --git a/Tests/RunCMake/get_filename_component/IncorrectArguments-stderr.txt b/Tests/RunCMake/get_filename_component/IncorrectArguments-stderr.txt
new file mode 100644
index 0000000..af08afa
--- /dev/null
+++ b/Tests/RunCMake/get_filename_component/IncorrectArguments-stderr.txt
@@ -0,0 +1,4 @@
+^CMake Error at IncorrectArguments.cmake:1 \(get_filename_component\):
+  get_filename_component called with incorrect number of arguments
+Call Stack \(most recent call first\):
+  CMakeLists.txt:[0-9]+ \(include\)$
diff --git a/Tests/RunCMake/get_filename_component/IncorrectArguments.cmake b/Tests/RunCMake/get_filename_component/IncorrectArguments.cmake
new file mode 100644
index 0000000..e329e29
--- /dev/null
+++ b/Tests/RunCMake/get_filename_component/IncorrectArguments.cmake
@@ -0,0 +1,2 @@
+get_filename_component(var)
+message("The error is fatal, so this should not print")
diff --git a/Tests/RunCMake/get_filename_component/KnownComponents.cmake b/Tests/RunCMake/get_filename_component/KnownComponents.cmake
index 54b858f..c2762ad 100644
--- a/Tests/RunCMake/get_filename_component/KnownComponents.cmake
+++ b/Tests/RunCMake/get_filename_component/KnownComponents.cmake
@@ -85,12 +85,12 @@
 get_filename_component(test_program_name " " PROGRAM)
 check("PROGRAM with just a space" "${test_program_name}" "")
 
-get_filename_component(test_program_name "${CMAKE_CURRENT_LIST_FILE}" PROGRAM)
-check("PROGRAM specified explicitly without quoting" "${test_program_name}" "${CMAKE_CURRENT_LIST_FILE}")
+get_filename_component(test_program_name "${CMAKE_CURRENT_LIST_DIR}/KnownComponents.sh" PROGRAM)
+check("PROGRAM specified explicitly without quoting" "${test_program_name}" "${CMAKE_CURRENT_LIST_DIR}/KnownComponents.sh")
 
-get_filename_component(test_program_name "\"${CMAKE_CURRENT_LIST_FILE}\" arg1 arg2" PROGRAM
+get_filename_component(test_program_name "\"${CMAKE_CURRENT_LIST_DIR}/KnownComponents.sh\" arg1 arg2" PROGRAM
   PROGRAM_ARGS test_program_args)
-check("PROGRAM specified explicitly with arguments: name" "${test_program_name}" "${CMAKE_CURRENT_LIST_FILE}")
+check("PROGRAM specified explicitly with arguments: name" "${test_program_name}" "${CMAKE_CURRENT_LIST_DIR}/KnownComponents.sh")
 check("PROGRAM specified explicitly with arguments: args" "${test_program_args}" " arg1 arg2")
 
 list(APPEND non_cache_vars test_program_name)
diff --git a/Tests/RunCMake/get_filename_component/KnownComponents.sh b/Tests/RunCMake/get_filename_component/KnownComponents.sh
new file mode 100755
index 0000000..1a24852
--- /dev/null
+++ b/Tests/RunCMake/get_filename_component/KnownComponents.sh
@@ -0,0 +1 @@
+#!/bin/sh
diff --git a/Tests/RunCMake/get_filename_component/RunCMakeTest.cmake b/Tests/RunCMake/get_filename_component/RunCMakeTest.cmake
index 156fc8f..a7820a0 100644
--- a/Tests/RunCMake/get_filename_component/RunCMakeTest.cmake
+++ b/Tests/RunCMake/get_filename_component/RunCMakeTest.cmake
@@ -1,4 +1,5 @@
 include(RunCMake)
 
+run_cmake(IncorrectArguments)
 run_cmake(KnownComponents)
 run_cmake(UnknownComponent)
diff --git a/Tests/RunCMake/get_filename_component/UnknownComponent-stderr.txt b/Tests/RunCMake/get_filename_component/UnknownComponent-stderr.txt
index b146e5b..f86a688 100644
--- a/Tests/RunCMake/get_filename_component/UnknownComponent-stderr.txt
+++ b/Tests/RunCMake/get_filename_component/UnknownComponent-stderr.txt
@@ -1,4 +1,4 @@
-CMake Error at UnknownComponent.cmake:1 \(get_filename_component\):
+^CMake Error at UnknownComponent.cmake:1 \(get_filename_component\):
   get_filename_component unknown component BOGUS
 Call Stack \(most recent call first\):
-  CMakeLists.txt:[0-9]+ \(include\)
+  CMakeLists.txt:[0-9]+ \(include\)$
diff --git a/Tests/RunCMake/get_filename_component/UnknownComponent.cmake b/Tests/RunCMake/get_filename_component/UnknownComponent.cmake
index 06abc51..19521ba 100644
--- a/Tests/RunCMake/get_filename_component/UnknownComponent.cmake
+++ b/Tests/RunCMake/get_filename_component/UnknownComponent.cmake
@@ -1 +1,2 @@
 get_filename_component(var "/path/to/filename.ext.in" BOGUS)
+message("The error is fatal, so this should not print")
diff --git a/Tests/RunCMake/get_property/CMakeLists.txt b/Tests/RunCMake/get_property/CMakeLists.txt
index 12cd3c7..74b3ff8 100644
--- a/Tests/RunCMake/get_property/CMakeLists.txt
+++ b/Tests/RunCMake/get_property/CMakeLists.txt
@@ -1,3 +1,3 @@
-cmake_minimum_required(VERSION 2.8.4)
+cmake_minimum_required(VERSION 3.3)
 project(${RunCMake_TEST} NONE)
 include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/get_property/RunCMakeTest.cmake b/Tests/RunCMake/get_property/RunCMakeTest.cmake
index 6e36473..c4ee53d 100644
--- a/Tests/RunCMake/get_property/RunCMakeTest.cmake
+++ b/Tests/RunCMake/get_property/RunCMakeTest.cmake
@@ -5,6 +5,7 @@
 run_cmake(global_properties)
 run_cmake(install_properties)
 run_cmake(source_properties)
+run_cmake(source_properties_failures)
 run_cmake(target_properties)
 run_cmake(test_properties)
 run_cmake(DebugConfigurations)
diff --git a/Tests/RunCMake/Languages/LINK_LANGUAGE-genex-result.txt b/Tests/RunCMake/get_property/source_properties_failures-result.txt
similarity index 100%
copy from Tests/RunCMake/Languages/LINK_LANGUAGE-genex-result.txt
copy to Tests/RunCMake/get_property/source_properties_failures-result.txt
diff --git a/Tests/RunCMake/get_property/source_properties_failures-stderr.txt b/Tests/RunCMake/get_property/source_properties_failures-stderr.txt
new file mode 100644
index 0000000..0accb8f
--- /dev/null
+++ b/Tests/RunCMake/get_property/source_properties_failures-stderr.txt
@@ -0,0 +1,66 @@
+^CMake Error at source_properties_failures.cmake:1 \(set_source_files_properties\):
+  set_source_files_properties called with incorrect number of arguments no
+  value provided to the DIRECTORY option
+Call Stack \(most recent call first\):
+  CMakeLists\.txt:[0-9]+ \(include\)
++
+CMake Error at source_properties_failures.cmake:2 \(set_source_files_properties\):
+  set_source_files_properties given non-existent DIRECTORY non_existing_dir
+Call Stack \(most recent call first\):
+  CMakeLists\.txt:[0-9]+ \(include\)
++
+CMake Error at source_properties_failures.cmake:3 \(set_source_files_properties\):
+  set_source_files_properties called with incorrect number of arguments no
+  value provided to the TARGET_DIRECTORY option
+Call Stack \(most recent call first\):
+  CMakeLists\.txt:[0-9]+ \(include\)
++
+CMake Error at source_properties_failures.cmake:4 \(set_source_files_properties\):
+  set_source_files_properties given non-existent target for TARGET_DIRECTORY
+  non_existing_target
+Call Stack \(most recent call first\):
+  CMakeLists\.txt:[0-9]+ \(include\)
++
+CMake Error at source_properties_failures.cmake:6 \(get_property\):
+  get_property called with incorrect number of arguments no value provided to
+  the DIRECTORY option
+Call Stack \(most recent call first\):
+  CMakeLists\.txt:[0-9]+ \(include\)
++
+CMake Error at source_properties_failures.cmake:7 \(get_property\):
+  get_property given non-existent DIRECTORY non_existing_dir
+Call Stack \(most recent call first\):
+  CMakeLists\.txt:[0-9]+ \(include\)
++
+CMake Error at source_properties_failures.cmake:8 \(get_property\):
+  get_property called with incorrect number of arguments no value provided to
+  the TARGET_DIRECTORY option
+Call Stack \(most recent call first\):
+  CMakeLists\.txt:[0-9]+ \(include\)
++
+CMake Error at source_properties_failures.cmake:9 \(get_property\):
+  get_property given non-existent target for TARGET_DIRECTORY
+  non_existing_dir
+Call Stack \(most recent call first\):
+  CMakeLists\.txt:[0-9]+ \(include\)
++
+CMake Error at source_properties_failures.cmake:11 \(get_source_file_property\):
+  get_source_file_property given non-existent DIRECTORY PROPERTY
+Call Stack \(most recent call first\):
+  CMakeLists\.txt:[0-9]+ \(include\)
++
+CMake Error at source_properties_failures.cmake:12 \(get_source_file_property\):
+  get_source_file_property called with incorrect number of arguments
+Call Stack \(most recent call first\):
+  CMakeLists\.txt:[0-9]+ \(include\)
++
+CMake Error at source_properties_failures.cmake:13 \(get_source_file_property\):
+  get_source_file_property given non-existent target for TARGET_DIRECTORY
+  PROPERTY
+Call Stack \(most recent call first\):
+  CMakeLists\.txt:[0-9]+ \(include\)
++
+CMake Error at source_properties_failures.cmake:14 \(get_source_file_property\):
+  get_source_file_property called with incorrect number of arguments
+Call Stack \(most recent call first\):
+  CMakeLists\.txt:[0-9]+ \(include\)$
diff --git a/Tests/RunCMake/get_property/source_properties_failures.cmake b/Tests/RunCMake/get_property/source_properties_failures.cmake
new file mode 100644
index 0000000..f4b87f9
--- /dev/null
+++ b/Tests/RunCMake/get_property/source_properties_failures.cmake
@@ -0,0 +1,14 @@
+set_source_files_properties(a.txt DIRECTORY PROPERTIES COMPILE_DEFINITIONS "def")
+set_source_files_properties(a.txt DIRECTORY non_existing_dir PROPERTIES COMPILE_DEFINITIONS "def")
+set_source_files_properties(a.txt TARGET_DIRECTORY PROPERTIES COMPILE_DEFINITIONS "def")
+set_source_files_properties(a.txt TARGET_DIRECTORY non_existing_target PROPERTIES COMPILE_DEFINITIONS "def")
+
+get_property(in_var SOURCE a.txt DIRECTORY PROPERTY COMPILE_DEFINITIONS)
+get_property(in_var SOURCE a.txt DIRECTORY non_existing_dir PROPERTY COMPILE_DEFINITIONS)
+get_property(in_var SOURCE a.txt TARGET_DIRECTORY PROPERTY COMPILE_DEFINITIONS)
+get_property(in_var SOURCE a.txt TARGET_DIRECTORY non_existing_dir PROPERTY COMPILE_DEFINITIONS)
+
+get_source_file_property(in_var a.txt DIRECTORY PROPERTY COMPILE_DEFINITIONS)
+get_source_file_property(in_var a.txt DIRECTORY non_existing_dir PROPERTY COMPILE_DEFINITIONS)
+get_source_file_property(in_var a.txt TARGET_DIRECTORY PROPERTY COMPILE_DEFINITIONS)
+get_source_file_property(in_var a.txt TARGET_DIRECTORY non_existing_dir PROPERTY COMPILE_DEFINITIONS)
diff --git a/Tests/RunCMake/if/CMakeLists.txt b/Tests/RunCMake/if/CMakeLists.txt
index 12cd3c7..74b3ff8 100644
--- a/Tests/RunCMake/if/CMakeLists.txt
+++ b/Tests/RunCMake/if/CMakeLists.txt
@@ -1,3 +1,3 @@
-cmake_minimum_required(VERSION 2.8.4)
+cmake_minimum_required(VERSION 3.3)
 project(${RunCMake_TEST} NONE)
 include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/include/CMakeLists.txt b/Tests/RunCMake/include/CMakeLists.txt
index 12cd3c7..4b3de84 100644
--- a/Tests/RunCMake/include/CMakeLists.txt
+++ b/Tests/RunCMake/include/CMakeLists.txt
@@ -1,3 +1,3 @@
-cmake_minimum_required(VERSION 2.8.4)
+cmake_minimum_required(VERSION 2.8.12)
 project(${RunCMake_TEST} NONE)
 include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/include_external_msproject/CMakeLists.txt b/Tests/RunCMake/include_external_msproject/CMakeLists.txt
index 12cd3c7..74b3ff8 100644
--- a/Tests/RunCMake/include_external_msproject/CMakeLists.txt
+++ b/Tests/RunCMake/include_external_msproject/CMakeLists.txt
@@ -1,3 +1,3 @@
-cmake_minimum_required(VERSION 2.8.4)
+cmake_minimum_required(VERSION 3.3)
 project(${RunCMake_TEST} NONE)
 include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/include_external_msproject/check_utils.cmake b/Tests/RunCMake/include_external_msproject/check_utils.cmake
index 0a2ba63..0162519 100644
--- a/Tests/RunCMake/include_external_msproject/check_utils.cmake
+++ b/Tests/RunCMake/include_external_msproject/check_utils.cmake
@@ -63,7 +63,7 @@
     return()
   endif()
 
-  # probably whould be better to use configuration name
+  # probably would be better to use configuration name
   # extracted from CMAKE_CONFIGURATION_TYPES than just hardcoded "Debug" instead
   set(REG_EXP "^(\t)*\\{${FOUND_GUID}\\}\\.Debug[^ ]*\\.ActiveCfg = Debug\\|${PLATFORM_NAME}$")
   check_line_exists(${TARGET_FILE} REG_EXP)
diff --git a/Tests/RunCMake/install/CMakeLists.txt b/Tests/RunCMake/install/CMakeLists.txt
index c7e99ad..6dd8cdf 100644
--- a/Tests/RunCMake/install/CMakeLists.txt
+++ b/Tests/RunCMake/install/CMakeLists.txt
@@ -1,6 +1,3 @@
 cmake_minimum_required(VERSION 3.4)
-if(RunCMake_TEST MATCHES "^file-GET_RUNTIME_DEPENDENCIES")
-  cmake_policy(SET CMP0087 NEW)
-endif()
 project(${RunCMake_TEST} NONE)
 include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/install/RunCMakeTest.cmake b/Tests/RunCMake/install/RunCMakeTest.cmake
index 70570b7..d83a07c 100644
--- a/Tests/RunCMake/install/RunCMakeTest.cmake
+++ b/Tests/RunCMake/install/RunCMakeTest.cmake
@@ -155,38 +155,6 @@
 run_install_test(TARGETS-RPATH)
 run_install_test(InstallRequiredSystemLibraries)
 
-if(CMAKE_HOST_SYSTEM_NAME STREQUAL "Darwin")
-  if(NOT CMake_INSTALL_NAME_TOOL_BUG)
-    run_install_test(file-GET_RUNTIME_DEPENDENCIES-macos)
-    run_install_test(file-GET_RUNTIME_DEPENDENCIES-macos-unresolved)
-    run_install_test(file-GET_RUNTIME_DEPENDENCIES-macos-conflict)
-    run_install_test(file-GET_RUNTIME_DEPENDENCIES-macos-notfile)
-  endif()
-  run_cmake(file-GET_RUNTIME_DEPENDENCIES-project)
-  run_cmake(file-GET_RUNTIME_DEPENDENCIES-badargs1)
-  run_cmake(file-GET_RUNTIME_DEPENDENCIES-badargs2)
-elseif(CMAKE_HOST_SYSTEM_NAME STREQUAL "Windows")
-  run_install_test(file-GET_RUNTIME_DEPENDENCIES-windows)
-  run_install_test(file-GET_RUNTIME_DEPENDENCIES-windows-unresolved)
-  run_install_test(file-GET_RUNTIME_DEPENDENCIES-windows-conflict)
-  run_install_test(file-GET_RUNTIME_DEPENDENCIES-windows-notfile)
-  run_cmake(file-GET_RUNTIME_DEPENDENCIES-project)
-  run_cmake(file-GET_RUNTIME_DEPENDENCIES-badargs1)
-  run_cmake(file-GET_RUNTIME_DEPENDENCIES-badargs2)
-elseif(CMAKE_HOST_SYSTEM_NAME STREQUAL "Linux")
-  if(NOT CMAKE_C_COMPILER_ID MATCHES "^XL")
-    run_install_test(file-GET_RUNTIME_DEPENDENCIES-linux)
-  endif()
-  run_install_test(file-GET_RUNTIME_DEPENDENCIES-linux-unresolved)
-  run_install_test(file-GET_RUNTIME_DEPENDENCIES-linux-conflict)
-  run_install_test(file-GET_RUNTIME_DEPENDENCIES-linux-notfile)
-  run_cmake(file-GET_RUNTIME_DEPENDENCIES-project)
-  run_cmake(file-GET_RUNTIME_DEPENDENCIES-badargs1)
-  run_cmake(file-GET_RUNTIME_DEPENDENCIES-badargs2)
-else()
-  run_cmake(file-GET_RUNTIME_DEPENDENCIES-unsupported)
-endif()
-
 set(run_install_test_components 1)
 run_install_test(FILES-EXCLUDE_FROM_ALL)
 run_install_test(TARGETS-EXCLUDE_FROM_ALL)
diff --git a/Tests/RunCMake/install/file-GET_RUNTIME_DEPENDENCIES-badargs1-stderr.txt b/Tests/RunCMake/install/file-GET_RUNTIME_DEPENDENCIES-badargs1-stderr.txt
deleted file mode 100644
index b66d1fe..0000000
--- a/Tests/RunCMake/install/file-GET_RUNTIME_DEPENDENCIES-badargs1-stderr.txt
+++ /dev/null
@@ -1,18 +0,0 @@
-^CMake Warning \(dev\) at file-GET_RUNTIME_DEPENDENCIES-badargs1\.cmake:[0-9]+ \(file\):
-  You have used file\(GET_RUNTIME_DEPENDENCIES\) in project mode\.  This is
-  probably not what you intended to do\.  Instead, please consider using it in
-  an install\(CODE\) or install\(SCRIPT\) command\.  For example:
-
-    install\(CODE \[\[
-      file\(GET_RUNTIME_DEPENDENCIES
-        # \.\.\.
-        \)
-      ]]\)
-Call Stack \(most recent call first\):
-  CMakeLists\.txt:[0-9]+ \(include\)
-This warning is for project developers\.  Use -Wno-dev to suppress it\.
-
-CMake Error at file-GET_RUNTIME_DEPENDENCIES-badargs1\.cmake:[0-9]+ \(file\):
-  file Unrecognized argument: "invalid"
-Call Stack \(most recent call first\):
-  CMakeLists\.txt:[0-9]+ \(include\)$
diff --git a/Tests/RunCMake/install/file-GET_RUNTIME_DEPENDENCIES-badargs2-stderr.txt b/Tests/RunCMake/install/file-GET_RUNTIME_DEPENDENCIES-badargs2-stderr.txt
deleted file mode 100644
index 50fa81f..0000000
--- a/Tests/RunCMake/install/file-GET_RUNTIME_DEPENDENCIES-badargs2-stderr.txt
+++ /dev/null
@@ -1,23 +0,0 @@
-^CMake Warning \(dev\) at file-GET_RUNTIME_DEPENDENCIES-badargs2\.cmake:[0-9]+ \(file\):
-  You have used file\(GET_RUNTIME_DEPENDENCIES\) in project mode\.  This is
-  probably not what you intended to do\.  Instead, please consider using it in
-  an install\(CODE\) or install\(SCRIPT\) command\.  For example:
-
-    install\(CODE \[\[
-      file\(GET_RUNTIME_DEPENDENCIES
-        # \.\.\.
-        \)
-      ]]\)
-Call Stack \(most recent call first\):
-  CMakeLists\.txt:[0-9]+ \(include\)
-This warning is for project developers\.  Use -Wno-dev to suppress it\.
-
-CMake Error at file-GET_RUNTIME_DEPENDENCIES-badargs2\.cmake:[0-9]+ \(file\):
-  file Keywords missing values:
-
-    RESOLVED_DEPENDENCIES_VAR
-    UNRESOLVED_DEPENDENCIES_VAR
-    CONFLICTING_DEPENDENCIES_PREFIX
-    BUNDLE_EXECUTABLE
-Call Stack \(most recent call first\):
-  CMakeLists\.txt:[0-9]+ \(include\)$
diff --git a/Tests/RunCMake/install/file-GET_RUNTIME_DEPENDENCIES-linux-all-check.cmake b/Tests/RunCMake/install/file-GET_RUNTIME_DEPENDENCIES-linux-all-check.cmake
deleted file mode 100644
index ab630f0..0000000
--- a/Tests/RunCMake/install/file-GET_RUNTIME_DEPENDENCIES-linux-all-check.cmake
+++ /dev/null
@@ -1,44 +0,0 @@
-function(check_contents filename contents_regex)
-  if(EXISTS "${CMAKE_INSTALL_PREFIX}/${filename}")
-    file(READ "${CMAKE_INSTALL_PREFIX}/${filename}" contents)
-    if(NOT contents MATCHES "${contents_regex}")
-      string(APPEND RunCMake_TEST_FAILED "File contents:
-  ${contents}
-do not match what we expected:
-  ${contents_regex}
-in file:
-  ${CMAKE_INSTALL_PREFIX}/${filename}\n")
-      set(RunCMake_TEST_FAILED "${RunCMake_TEST_FAILED}" PARENT_SCOPE)
-    endif()
-  else()
-    string(APPEND RunCMake_TEST_FAILED "File ${CMAKE_INSTALL_PREFIX}/${filename} does not exist")
-    set(RunCMake_TEST_FAILED "${RunCMake_TEST_FAILED}" PARENT_SCOPE)
-  endif()
-endfunction()
-
-set(_check
-  [[[^;]*/Tests/RunCMake/install/file-GET_RUNTIME_DEPENDENCIES-linux-build/root-all/lib/libtest_rpath\.so]]
-  [[[^;]*/Tests/RunCMake/install/file-GET_RUNTIME_DEPENDENCIES-linux-build/root-all/lib/libtest_runpath\.so]]
-  [[[^;]*/Tests/RunCMake/install/file-GET_RUNTIME_DEPENDENCIES-linux-build/root-all/lib/rpath/librpath\.so]]
-  [[[^;]*/Tests/RunCMake/install/file-GET_RUNTIME_DEPENDENCIES-linux-build/root-all/lib/rpath_parent/librpath_parent\.so]]
-  [[[^;]*/Tests/RunCMake/install/file-GET_RUNTIME_DEPENDENCIES-linux-build/root-all/lib/rpath_search/librpath_search\.so]]
-  [[[^;]*/Tests/RunCMake/install/file-GET_RUNTIME_DEPENDENCIES-linux-build/root-all/lib/runpath/librunpath\.so]]
-  [[[^;]*/Tests/RunCMake/install/file-GET_RUNTIME_DEPENDENCIES-linux-build/root-all/lib/runpath_search/librunpath_search\.so]]
-  )
-check_contents(deps/deps1.txt "^${_check}$")
-check_contents(deps/deps2.txt "^${_check}$")
-check_contents(deps/deps3.txt "^${_check}$")
-set(_check
-  [[librpath_unresolved\.so]]
-  [[librunpath_parent_unresolved\.so]]
-  [[librunpath_unresolved\.so]]
-  )
-check_contents(deps/udeps1.txt "^${_check}$")
-check_contents(deps/udeps2.txt "^${_check}$")
-check_contents(deps/udeps3.txt "^${_check}$")
-set(_check
-  "^libconflict\\.so:[^;]*/Tests/RunCMake/install/file-GET_RUNTIME_DEPENDENCIES-linux-build/root-all/lib/conflict/libconflict\\.so;[^;]*/Tests/RunCMake/install/file-GET_RUNTIME_DEPENDENCIES-linux-build/root-all/lib/conflict2/libconflict\\.so\n$"
-  )
-check_contents(deps/cdeps1.txt "${_check}")
-check_contents(deps/cdeps2.txt "${_check}")
-check_contents(deps/cdeps3.txt "${_check}")
diff --git a/Tests/RunCMake/install/file-GET_RUNTIME_DEPENDENCIES-linux-all-stderr.txt b/Tests/RunCMake/install/file-GET_RUNTIME_DEPENDENCIES-linux-all-stderr.txt
deleted file mode 100644
index 123ae48..0000000
--- a/Tests/RunCMake/install/file-GET_RUNTIME_DEPENDENCIES-linux-all-stderr.txt
+++ /dev/null
@@ -1,119 +0,0 @@
-^CMake Warning at cmake_install\.cmake:[0-9]+ \(file\):
-  Dependency librpath_search_postexcluded\.so found in search directory:
-
-    [^
-]*/Tests/RunCMake/install/file-GET_RUNTIME_DEPENDENCIES-linux-build/root-all/lib/rpath_search_postexcluded
-
-  See file\(GET_RUNTIME_DEPENDENCIES\) documentation for more information\.
-Call Stack \(most recent call first\):
-  cmake_install\.cmake:[0-9]+ \(exec_get_runtime_dependencies\)
-
-*CMake Warning at cmake_install\.cmake:[0-9]+ \(file\):
-  Dependency librpath_search\.so found in search directory:
-
-    [^
-]*/Tests/RunCMake/install/file-GET_RUNTIME_DEPENDENCIES-linux-build/root-all/lib/rpath_search
-
-  See file\(GET_RUNTIME_DEPENDENCIES\) documentation for more information\.
-Call Stack \(most recent call first\):
-  cmake_install\.cmake:[0-9]+ \(exec_get_runtime_dependencies\)
-
-*CMake Warning at cmake_install\.cmake:[0-9]+ \(file\):
-  Dependency librunpath_search_postexcluded\.so found in search directory:
-
-    [^
-]*/Tests/RunCMake/install/file-GET_RUNTIME_DEPENDENCIES-linux-build/root-all/lib/runpath_search_postexcluded
-
-  See file\(GET_RUNTIME_DEPENDENCIES\) documentation for more information\.
-Call Stack \(most recent call first\):
-  cmake_install\.cmake:[0-9]+ \(exec_get_runtime_dependencies\)
-
-*CMake Warning at cmake_install\.cmake:[0-9]+ \(file\):
-  Dependency librunpath_search\.so found in search directory:
-
-    [^
-]*/Tests/RunCMake/install/file-GET_RUNTIME_DEPENDENCIES-linux-build/root-all/lib/runpath_search
-
-  See file\(GET_RUNTIME_DEPENDENCIES\) documentation for more information\.
-Call Stack \(most recent call first\):
-  cmake_install\.cmake:[0-9]+ \(exec_get_runtime_dependencies\)
-
-*CMake Warning at cmake_install\.cmake:[0-9]+ \(file\):
-  Dependency librpath_search_postexcluded\.so found in search directory:
-
-    [^
-]*/Tests/RunCMake/install/file-GET_RUNTIME_DEPENDENCIES-linux-build/root-all/lib/rpath_search_postexcluded
-
-  See file\(GET_RUNTIME_DEPENDENCIES\) documentation for more information\.
-Call Stack \(most recent call first\):
-  cmake_install\.cmake:[0-9]+ \(exec_get_runtime_dependencies\)
-
-*CMake Warning at cmake_install\.cmake:[0-9]+ \(file\):
-  Dependency librpath_search\.so found in search directory:
-
-    [^
-]*/Tests/RunCMake/install/file-GET_RUNTIME_DEPENDENCIES-linux-build/root-all/lib/rpath_search
-
-  See file\(GET_RUNTIME_DEPENDENCIES\) documentation for more information\.
-Call Stack \(most recent call first\):
-  cmake_install\.cmake:[0-9]+ \(exec_get_runtime_dependencies\)
-
-*CMake Warning at cmake_install\.cmake:[0-9]+ \(file\):
-  Dependency librunpath_search_postexcluded\.so found in search directory:
-
-    [^
-]*/Tests/RunCMake/install/file-GET_RUNTIME_DEPENDENCIES-linux-build/root-all/lib/runpath_search_postexcluded
-
-  See file\(GET_RUNTIME_DEPENDENCIES\) documentation for more information\.
-Call Stack \(most recent call first\):
-  cmake_install\.cmake:[0-9]+ \(exec_get_runtime_dependencies\)
-
-*CMake Warning at cmake_install\.cmake:[0-9]+ \(file\):
-  Dependency librunpath_search\.so found in search directory:
-
-    [^
-]*/Tests/RunCMake/install/file-GET_RUNTIME_DEPENDENCIES-linux-build/root-all/lib/runpath_search
-
-  See file\(GET_RUNTIME_DEPENDENCIES\) documentation for more information\.
-Call Stack \(most recent call first\):
-  cmake_install\.cmake:[0-9]+ \(exec_get_runtime_dependencies\)
-
-*CMake Warning at cmake_install\.cmake:[0-9]+ \(file\):
-  Dependency librpath_search_postexcluded\.so found in search directory:
-
-    [^
-]*/Tests/RunCMake/install/file-GET_RUNTIME_DEPENDENCIES-linux-build/root-all/lib/rpath_search_postexcluded
-
-  See file\(GET_RUNTIME_DEPENDENCIES\) documentation for more information\.
-Call Stack \(most recent call first\):
-  cmake_install\.cmake:[0-9]+ \(exec_get_runtime_dependencies\)
-
-*CMake Warning at cmake_install\.cmake:[0-9]+ \(file\):
-  Dependency librpath_search\.so found in search directory:
-
-    [^
-]*/Tests/RunCMake/install/file-GET_RUNTIME_DEPENDENCIES-linux-build/root-all/lib/rpath_search
-
-  See file\(GET_RUNTIME_DEPENDENCIES\) documentation for more information\.
-Call Stack \(most recent call first\):
-  cmake_install\.cmake:[0-9]+ \(exec_get_runtime_dependencies\)
-
-*CMake Warning at cmake_install\.cmake:[0-9]+ \(file\):
-  Dependency librunpath_search_postexcluded\.so found in search directory:
-
-    [^
-]*/Tests/RunCMake/install/file-GET_RUNTIME_DEPENDENCIES-linux-build/root-all/lib/runpath_search_postexcluded
-
-  See file\(GET_RUNTIME_DEPENDENCIES\) documentation for more information\.
-Call Stack \(most recent call first\):
-  cmake_install\.cmake:[0-9]+ \(exec_get_runtime_dependencies\)
-
-*CMake Warning at cmake_install\.cmake:[0-9]+ \(file\):
-  Dependency librunpath_search\.so found in search directory:
-
-    [^
-]*/Tests/RunCMake/install/file-GET_RUNTIME_DEPENDENCIES-linux-build/root-all/lib/runpath_search
-
-  See file\(GET_RUNTIME_DEPENDENCIES\) documentation for more information\.
-Call Stack \(most recent call first\):
-  cmake_install\.cmake:[0-9]+ \(exec_get_runtime_dependencies\)$
diff --git a/Tests/RunCMake/install/file-GET_RUNTIME_DEPENDENCIES-linux-conflict-all-stderr.txt b/Tests/RunCMake/install/file-GET_RUNTIME_DEPENDENCIES-linux-conflict-all-stderr.txt
deleted file mode 100644
index 1692348..0000000
--- a/Tests/RunCMake/install/file-GET_RUNTIME_DEPENDENCIES-linux-conflict-all-stderr.txt
+++ /dev/null
@@ -1,7 +0,0 @@
-^CMake Error at cmake_install\.cmake:[0-9]+ \(file\):
-  file Multiple conflicting paths found for librpath\.so:
-
-    [^
-]*/Tests/RunCMake/install/file-GET_RUNTIME_DEPENDENCIES-linux-conflict-build/root-all/lib/rpath1/librpath\.so
-    [^
-]*/Tests/RunCMake/install/file-GET_RUNTIME_DEPENDENCIES-linux-conflict-build/root-all/lib/rpath2/librpath\.so$
diff --git a/Tests/RunCMake/install/file-GET_RUNTIME_DEPENDENCIES-linux-notfile-all-stderr.txt b/Tests/RunCMake/install/file-GET_RUNTIME_DEPENDENCIES-linux-notfile-all-stderr.txt
deleted file mode 100644
index 83a87c9..0000000
--- a/Tests/RunCMake/install/file-GET_RUNTIME_DEPENDENCIES-linux-notfile-all-stderr.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-^CMake Error at cmake_install\.cmake:[0-9]+ \(file\):
-  file Failed to run objdump on:
-
-    [^
-]*/Tests/RunCMake/install/file-GET_RUNTIME_DEPENDENCIES-linux-notfile-build/root-all/bin/\.\./lib/libtest\.so$
diff --git a/Tests/RunCMake/install/file-GET_RUNTIME_DEPENDENCIES-linux.cmake b/Tests/RunCMake/install/file-GET_RUNTIME_DEPENDENCIES-linux.cmake
deleted file mode 100644
index bd0f9f1..0000000
--- a/Tests/RunCMake/install/file-GET_RUNTIME_DEPENDENCIES-linux.cmake
+++ /dev/null
@@ -1,169 +0,0 @@
-enable_language(C)
-cmake_policy(SET CMP0095 NEW)
-
-set(test_rpath_names
-  preexcluded
-  rpath_postexcluded
-  rpath
-  rpath_parent_postexcluded
-  rpath_parent
-  rpath_origin_postexcluded
-  rpath_origin
-  rpath_search_postexcluded
-  rpath_search
-  rpath_unresolved
-  conflict
-  )
-set(test_runpath_names
-  runpath_postexcluded
-  runpath
-  runpath_origin_postexcluded
-  runpath_origin
-  runpath_parent_unresolved
-  runpath_search_postexcluded
-  runpath_search
-  runpath_unresolved
-  )
-
-file(REMOVE "${CMAKE_BINARY_DIR}/test_rpath.c")
-add_library(test_rpath SHARED "${CMAKE_BINARY_DIR}/test_rpath.c")
-foreach(name ${test_rpath_names})
-  file(WRITE "${CMAKE_BINARY_DIR}/${name}.c" "void ${name}(void) {}\n")
-  add_library(${name} SHARED "${CMAKE_BINARY_DIR}/${name}.c")
-
-  file(APPEND "${CMAKE_BINARY_DIR}/test_rpath.c" "extern void ${name}(void);\n")
-endforeach()
-file(APPEND "${CMAKE_BINARY_DIR}/test_rpath.c" "void test_rpath(void)\n{\n")
-foreach(name ${test_rpath_names})
-  file(APPEND "${CMAKE_BINARY_DIR}/test_rpath.c" "  ${name}();\n")
-endforeach()
-file(APPEND "${CMAKE_BINARY_DIR}/test_rpath.c" "}\n")
-
-install(TARGETS rpath_postexcluded DESTINATION lib/rpath_postexcluded)
-install(TARGETS rpath DESTINATION lib/rpath)
-install(TARGETS rpath_origin_postexcluded DESTINATION lib/rpath_origin_postexcluded)
-install(TARGETS rpath_origin DESTINATION lib/rpath_origin)
-install(TARGETS rpath_parent_postexcluded DESTINATION lib/rpath_parent_postexcluded)
-install(TARGETS rpath rpath_origin rpath_parent DESTINATION lib/rpath_parent)
-install(TARGETS rpath_search_postexcluded DESTINATION lib/rpath_search_postexcluded)
-install(TARGETS rpath rpath_origin rpath_parent rpath_search DESTINATION lib/rpath_search)
-install(TARGETS conflict DESTINATION lib/conflict)
-
-target_link_libraries(test_rpath PRIVATE ${test_rpath_names})
-set_property(TARGET test_rpath PROPERTY INSTALL_RPATH
-  "${CMAKE_BINARY_DIR}/root-all/lib/rpath_postexcluded"
-  "${CMAKE_BINARY_DIR}/root-all/lib/rpath"
-  "\$ORIGIN/rpath_origin_postexcluded"
-  "\${ORIGIN}/rpath_origin"
-  "${CMAKE_BINARY_DIR}/root-all/lib/conflict"
-  )
-target_link_options(test_rpath PRIVATE -Wl,--disable-new-dtags)
-
-file(REMOVE "${CMAKE_BINARY_DIR}/test_runpath.c")
-add_library(test_runpath SHARED "${CMAKE_BINARY_DIR}/test_runpath.c")
-foreach(name ${test_runpath_names} rpath conflict)
-  file(WRITE "${CMAKE_BINARY_DIR}/${name}.c" "void ${name}(void) {}\n")
-  if(NOT name MATCHES "^(rpath|conflict)$")
-    add_library(${name} SHARED "${CMAKE_BINARY_DIR}/${name}.c")
-  endif()
-
-  file(APPEND "${CMAKE_BINARY_DIR}/test_runpath.c" "extern void ${name}(void);\n")
-endforeach()
-file(APPEND "${CMAKE_BINARY_DIR}/test_runpath.c" "void test_runpath(void)\n{\n")
-foreach(name ${test_runpath_names} rpath conflict)
-  file(APPEND "${CMAKE_BINARY_DIR}/test_runpath.c" "  ${name}();\n")
-endforeach()
-file(APPEND "${CMAKE_BINARY_DIR}/test_runpath.c" "}\n")
-
-install(TARGETS runpath_postexcluded DESTINATION lib/runpath_postexcluded)
-install(TARGETS runpath DESTINATION lib/runpath)
-install(TARGETS runpath_origin_postexcluded DESTINATION lib/runpath_origin_postexcluded)
-install(TARGETS runpath_origin DESTINATION lib/runpath_origin)
-install(TARGETS runpath_parent_unresolved DESTINATION lib/runpath_parent_unresolved)
-install(TARGETS runpath_search_postexcluded DESTINATION lib/runpath_search_postexcluded)
-install(TARGETS runpath runpath_origin runpath_search DESTINATION lib/runpath_search)
-install(TARGETS conflict DESTINATION lib/conflict2)
-
-target_link_libraries(test_runpath PRIVATE ${test_runpath_names} rpath conflict)
-set_property(TARGET test_runpath PROPERTY INSTALL_RPATH
-  "${CMAKE_BINARY_DIR}/root-all/lib/runpath/../rpath" # Ensure that files that don't conflict are treated correctly
-  "${CMAKE_BINARY_DIR}/root-all/lib/runpath_postexcluded"
-  "${CMAKE_BINARY_DIR}/root-all/lib/runpath"
-  "\${ORIGIN}/runpath_origin_postexcluded"
-  "\$ORIGIN/runpath_origin"
-  "${CMAKE_BINARY_DIR}/root-all/lib/conflict2"
-  )
-target_link_options(test_runpath PRIVATE -Wl,--enable-new-dtags)
-
-set_property(TARGET test_rpath ${test_rpath_names} test_runpath ${test_runpath_names} PROPERTY LIBRARY_OUTPUT_DIRECTORY lib)
-install(TARGETS test_rpath test_runpath DESTINATION lib)
-
-add_executable(topexe file-GET_RUNTIME_DEPENDENCIES-linux/topexe.c)
-add_library(toplib SHARED file-GET_RUNTIME_DEPENDENCIES-linux/toplib.c)
-add_library(topmod MODULE file-GET_RUNTIME_DEPENDENCIES-linux/toplib.c)
-target_link_libraries(topexe PRIVATE test_rpath test_runpath)
-target_link_libraries(toplib PRIVATE test_rpath test_runpath)
-target_link_libraries(topmod PRIVATE test_rpath test_runpath)
-set_property(TARGET topexe toplib topmod PROPERTY INSTALL_RPATH
-  "${CMAKE_BINARY_DIR}/root-all/lib"
-  "${CMAKE_BINARY_DIR}/root-all/lib/rpath_parent_postexcluded"
-  "${CMAKE_BINARY_DIR}/root-all/lib/rpath_parent"
-  "${CMAKE_BINARY_DIR}/root-all/lib/runpath_parent_unresolved"
-  )
-target_link_options(topexe PRIVATE -Wl,--disable-new-dtags)
-target_link_options(toplib PRIVATE -Wl,--disable-new-dtags)
-target_link_options(topmod PRIVATE -Wl,--disable-new-dtags)
-
-install(TARGETS topexe toplib RUNTIME DESTINATION bin LIBRARY DESTINATION lib)
-install(TARGETS topmod LIBRARY DESTINATION lib/modules)
-
-install(CODE [[
-  function(exec_get_runtime_dependencies depsfile udepsfile cdepsfile)
-    file(GET_RUNTIME_DEPENDENCIES
-      RESOLVED_DEPENDENCIES_VAR deps
-      UNRESOLVED_DEPENDENCIES_VAR udeps
-      CONFLICTING_DEPENDENCIES_PREFIX cdeps
-      PRE_INCLUDE_REGEXES
-        "^lib(test_rpath|rpath_postexcluded|rpath|rpath_parent_postexcluded|rpath_parent|rpath_origin_postexcluded|rpath_origin|rpath_search_postexcluded|rpath_search|rpath_unresolved|test_runpath|runpath_postexcluded|runpath|runpath_origin_postexcluded|runpath_origin|runpath_parent_unresolved|runpath_search_postexcluded|runpath_search|runpath_unresolved|conflict)\\.so$"
-        "^libc\\.so"
-      PRE_EXCLUDE_REGEXES ".*"
-      POST_INCLUDE_REGEXES "^.*/(libtest_rpath|rpath/librpath|rpath_parent/librpath_parent|rpath_search/librpath_search|libtest_runpath|runpath/librunpath|runpath_origin_postexcluded|runpath_origin|runpath_search/librunpath_search|conflict2?/libconflict)\\.so$"
-      POST_EXCLUDE_REGEXES ".*"
-      DIRECTORIES
-        "${CMAKE_INSTALL_PREFIX}/lib/rpath_search_postexcluded"
-        "${CMAKE_INSTALL_PREFIX}/lib/rpath_search"
-        "${CMAKE_INSTALL_PREFIX}/lib/runpath_search_postexcluded"
-        "${CMAKE_INSTALL_PREFIX}/lib/runpath_search"
-      ${ARGN}
-      )
-    list(SORT deps)
-    list(SORT udeps)
-    list(SORT cdeps_FILENAMES)
-    file(WRITE "${CMAKE_INSTALL_PREFIX}/deps/${depsfile}" "${deps}")
-    file(WRITE "${CMAKE_INSTALL_PREFIX}/deps/${udepsfile}" "${udeps}")
-    file(WRITE "${CMAKE_INSTALL_PREFIX}/deps/${cdepsfile}" "")
-    foreach(cdep IN LISTS cdeps_FILENAMES)
-      set(cdep_values ${cdeps_${cdep}})
-      list(SORT cdep_values)
-      file(APPEND "${CMAKE_INSTALL_PREFIX}/deps/${cdepsfile}" "${cdep}:${cdep_values}\n")
-    endforeach()
-  endfunction()
-
-  exec_get_runtime_dependencies(
-    deps1.txt udeps1.txt cdeps1.txt
-    EXECUTABLES
-      "${CMAKE_INSTALL_PREFIX}/bin/$<TARGET_FILE_NAME:topexe>"
-    )
-
-  exec_get_runtime_dependencies(
-    deps2.txt udeps2.txt cdeps2.txt
-    LIBRARIES
-      "${CMAKE_INSTALL_PREFIX}/lib/$<TARGET_FILE_NAME:toplib>"
-    )
-
-  exec_get_runtime_dependencies(
-    deps3.txt udeps3.txt cdeps3.txt
-    MODULES
-      "${CMAKE_INSTALL_PREFIX}/lib/modules/$<TARGET_FILE_NAME:topmod>"
-    )
-  ]])
diff --git a/Tests/RunCMake/install/file-GET_RUNTIME_DEPENDENCIES-macos-all-check.cmake b/Tests/RunCMake/install/file-GET_RUNTIME_DEPENDENCIES-macos-all-check.cmake
deleted file mode 100644
index 4d6dde1..0000000
--- a/Tests/RunCMake/install/file-GET_RUNTIME_DEPENDENCIES-macos-all-check.cmake
+++ /dev/null
@@ -1,157 +0,0 @@
-function(check_contents filename contents_regex)
-  if(EXISTS "${CMAKE_INSTALL_PREFIX}/${filename}")
-    file(READ "${CMAKE_INSTALL_PREFIX}/${filename}" contents)
-    if(NOT contents MATCHES "${contents_regex}")
-      string(APPEND RunCMake_TEST_FAILED "File contents:
-  ${contents}
-do not match what we expected:
-  ${contents_regex}
-in file:
-  ${CMAKE_INSTALL_PREFIX}/${filename}\n")
-      set(RunCMake_TEST_FAILED "${RunCMake_TEST_FAILED}" PARENT_SCOPE)
-    endif()
-  else()
-    string(APPEND RunCMake_TEST_FAILED "File ${CMAKE_INSTALL_PREFIX}/${filename} does not exist")
-    set(RunCMake_TEST_FAILED "${RunCMake_TEST_FAILED}" PARENT_SCOPE)
-  endif()
-endfunction()
-
-set(_check
-  [[[^;]*/Tests/RunCMake/install/file-GET_RUNTIME_DEPENDENCIES-macos-build/root-all/executable/bin/../lib/executable_path/libexecutable_path\.dylib]]
-  [[[^;]*/Tests/RunCMake/install/file-GET_RUNTIME_DEPENDENCIES-macos-build/root-all/executable/bin/../lib/rpath_executable_path/librpath_executable_path\.dylib]]
-  [[[^;]*/Tests/RunCMake/install/file-GET_RUNTIME_DEPENDENCIES-macos-build/root-all/executable/lib/libtestlib\.dylib]]
-  [[[^;]*/Tests/RunCMake/install/file-GET_RUNTIME_DEPENDENCIES-macos-build/root-all/executable/lib/loader_path/libloader_path\.dylib]]
-  [[[^;]*/Tests/RunCMake/install/file-GET_RUNTIME_DEPENDENCIES-macos-build/root-all/executable/lib/normal/../rpath/librpath\.dylib]]
-  [[[^;]*/Tests/RunCMake/install/file-GET_RUNTIME_DEPENDENCIES-macos-build/root-all/executable/lib/normal/libnormal\.dylib]]
-  [[[^;]*/Tests/RunCMake/install/file-GET_RUNTIME_DEPENDENCIES-macos-build/root-all/executable/lib/rpath_loader_path/librpath_loader_path\.dylib]]
-  [[/usr/lib/libSystem\.B\.dylib]]
-  )
-check_contents(deps/deps1.txt "^${_check}$")
-
-set(_check
-  [[@executable_path/../lib/executable_path_bundle/libexecutable_path_bundle\.dylib]]
-  [[@loader_path/loader_path_unresolved/libloader_path_unresolved\.dylib]]
-  [[@rpath/librpath_executable_path_bundle\.dylib]]
-  [[@rpath/librpath_loader_path_unresolved\.dylib]]
-  [[@rpath/librpath_unresolved\.dylib]]
-  )
-check_contents(deps/udeps1.txt "^${_check}$")
-
-set(_check
-  [[[^;]*/Tests/RunCMake/install/file-GET_RUNTIME_DEPENDENCIES-macos-build/root-all/executable/lib/libtestlib\.dylib]]
-  [[[^;]*/Tests/RunCMake/install/file-GET_RUNTIME_DEPENDENCIES-macos-build/root-all/executable/lib/loader_path/libloader_path\.dylib]]
-  [[[^;]*/Tests/RunCMake/install/file-GET_RUNTIME_DEPENDENCIES-macos-build/root-all/executable/lib/normal/../rpath/librpath\.dylib]]
-  [[[^;]*/Tests/RunCMake/install/file-GET_RUNTIME_DEPENDENCIES-macos-build/root-all/executable/lib/normal/libnormal\.dylib]]
-  [[[^;]*/Tests/RunCMake/install/file-GET_RUNTIME_DEPENDENCIES-macos-build/root-all/executable/lib/rpath_loader_path/librpath_loader_path\.dylib]]
-  [[/usr/lib/libSystem\.B\.dylib]]
-  )
-check_contents(deps/deps2.txt "^${_check}$")
-
-set(_check
-  [[@executable_path/../lib/executable_path/libexecutable_path\.dylib]]
-  [[@executable_path/../lib/executable_path_bundle/libexecutable_path_bundle\.dylib]]
-  [[@executable_path/../lib/executable_path_postexcluded/libexecutable_path_postexcluded\.dylib]]
-  [[@loader_path/loader_path_unresolved/libloader_path_unresolved\.dylib]]
-  [[@rpath/librpath_executable_path\.dylib]]
-  [[@rpath/librpath_executable_path_bundle\.dylib]]
-  [[@rpath/librpath_executable_path_postexcluded\.dylib]]
-  [[@rpath/librpath_loader_path_unresolved\.dylib]]
-  [[@rpath/librpath_unresolved\.dylib]]
-  )
-check_contents(deps/udeps2.txt "^${_check}$")
-
-set(_check
-  [[[^;]*/Tests/RunCMake/install/file-GET_RUNTIME_DEPENDENCIES-macos-build/root-all/executable/lib/libtestlib\.dylib]]
-  [[[^;]*/Tests/RunCMake/install/file-GET_RUNTIME_DEPENDENCIES-macos-build/root-all/executable/lib/loader_path/libloader_path\.dylib]]
-  [[[^;]*/Tests/RunCMake/install/file-GET_RUNTIME_DEPENDENCIES-macos-build/root-all/executable/lib/normal/../rpath/librpath\.dylib]]
-  [[[^;]*/Tests/RunCMake/install/file-GET_RUNTIME_DEPENDENCIES-macos-build/root-all/executable/lib/normal/libnormal\.dylib]]
-  [[[^;]*/Tests/RunCMake/install/file-GET_RUNTIME_DEPENDENCIES-macos-build/root-all/executable/lib/rpath_loader_path/librpath_loader_path\.dylib]]
-  [[/usr/lib/libSystem\.B\.dylib]]
-  )
-check_contents(deps/deps3.txt "^${_check}$")
-
-set(_check
-  [[@executable_path/../lib/executable_path/libexecutable_path\.dylib]]
-  [[@executable_path/../lib/executable_path_bundle/libexecutable_path_bundle\.dylib]]
-  [[@executable_path/../lib/executable_path_postexcluded/libexecutable_path_postexcluded\.dylib]]
-  [[@loader_path/loader_path_unresolved/libloader_path_unresolved\.dylib]]
-  [[@rpath/librpath_executable_path\.dylib]]
-  [[@rpath/librpath_executable_path_bundle\.dylib]]
-  [[@rpath/librpath_executable_path_postexcluded\.dylib]]
-  [[@rpath/librpath_loader_path_unresolved\.dylib]]
-  [[@rpath/librpath_unresolved\.dylib]]
-  )
-check_contents(deps/udeps3.txt "^${_check}$")
-
-set(_check
-  [[[^;]*/Tests/RunCMake/install/file-GET_RUNTIME_DEPENDENCIES-macos-build/root-all/executable/bin/../lib/executable_path/libexecutable_path\.dylib]]
-  [[[^;]*/Tests/RunCMake/install/file-GET_RUNTIME_DEPENDENCIES-macos-build/root-all/executable/bin/../lib/rpath_executable_path/librpath_executable_path\.dylib]]
-  [[[^;]*/Tests/RunCMake/install/file-GET_RUNTIME_DEPENDENCIES-macos-build/root-all/executable/lib/libtestlib\.dylib]]
-  [[[^;]*/Tests/RunCMake/install/file-GET_RUNTIME_DEPENDENCIES-macos-build/root-all/executable/lib/loader_path/libloader_path\.dylib]]
-  [[[^;]*/Tests/RunCMake/install/file-GET_RUNTIME_DEPENDENCIES-macos-build/root-all/executable/lib/normal/../rpath/librpath\.dylib]]
-  [[[^;]*/Tests/RunCMake/install/file-GET_RUNTIME_DEPENDENCIES-macos-build/root-all/executable/lib/normal/libnormal\.dylib]]
-  [[[^;]*/Tests/RunCMake/install/file-GET_RUNTIME_DEPENDENCIES-macos-build/root-all/executable/lib/rpath_loader_path/librpath_loader_path\.dylib]]
-  [[/usr/lib/libSystem\.B\.dylib]]
-  )
-check_contents(deps/deps4.txt "^${_check}$")
-
-set(_check
-  [[@executable_path/../lib/executable_path_bundle/libexecutable_path_bundle\.dylib]]
-  [[@loader_path/loader_path_unresolved/libloader_path_unresolved\.dylib]]
-  [[@rpath/librpath_executable_path_bundle\.dylib]]
-  [[@rpath/librpath_loader_path_unresolved\.dylib]]
-  [[@rpath/librpath_unresolved\.dylib]]
-  )
-check_contents(deps/udeps4.txt "^${_check}$")
-
-set(_check
-  [[[^;]*/Tests/RunCMake/install/file-GET_RUNTIME_DEPENDENCIES-macos-build/root-all/bundle_executable/bin/../lib/executable_path_bundle/libexecutable_path_bundle\.dylib]]
-  [[[^;]*/Tests/RunCMake/install/file-GET_RUNTIME_DEPENDENCIES-macos-build/root-all/executable/lib/libtestlib\.dylib]]
-  [[[^;]*/Tests/RunCMake/install/file-GET_RUNTIME_DEPENDENCIES-macos-build/root-all/executable/lib/loader_path/libloader_path\.dylib]]
-  [[[^;]*/Tests/RunCMake/install/file-GET_RUNTIME_DEPENDENCIES-macos-build/root-all/executable/lib/normal/../rpath/librpath\.dylib]]
-  [[[^;]*/Tests/RunCMake/install/file-GET_RUNTIME_DEPENDENCIES-macos-build/root-all/executable/lib/normal/libnormal\.dylib]]
-  [[[^;]*/Tests/RunCMake/install/file-GET_RUNTIME_DEPENDENCIES-macos-build/root-all/executable/lib/rpath_loader_path/librpath_loader_path\.dylib]]
-  [[/usr/lib/libSystem\.B\.dylib]]
-  )
-check_contents(deps/deps5.txt "^${_check}$")
-
-set(_check
-  [[@executable_path/../lib/executable_path/libexecutable_path\.dylib]]
-  [[@loader_path/loader_path_unresolved/libloader_path_unresolved\.dylib]]
-  [[@rpath/librpath_executable_path\.dylib]]
-  [[@rpath/librpath_executable_path_bundle\.dylib]]
-  [[@rpath/librpath_loader_path_unresolved\.dylib]]
-  [[@rpath/librpath_unresolved\.dylib]]
-  )
-check_contents(deps/udeps5.txt "^${_check}$")
-
-set(_check
-  [[[^;]*/Tests/RunCMake/install/file-GET_RUNTIME_DEPENDENCIES-macos-build/root-all/bundle_executable/bin/../lib/executable_path_bundle/libexecutable_path_bundle\.dylib]]
-  [[[^;]*/Tests/RunCMake/install/file-GET_RUNTIME_DEPENDENCIES-macos-build/root-all/executable/lib/libtestlib\.dylib]]
-  [[[^;]*/Tests/RunCMake/install/file-GET_RUNTIME_DEPENDENCIES-macos-build/root-all/executable/lib/loader_path/libloader_path\.dylib]]
-  [[[^;]*/Tests/RunCMake/install/file-GET_RUNTIME_DEPENDENCIES-macos-build/root-all/executable/lib/normal/../rpath/librpath\.dylib]]
-  [[[^;]*/Tests/RunCMake/install/file-GET_RUNTIME_DEPENDENCIES-macos-build/root-all/executable/lib/normal/libnormal\.dylib]]
-  [[[^;]*/Tests/RunCMake/install/file-GET_RUNTIME_DEPENDENCIES-macos-build/root-all/executable/lib/rpath_loader_path/librpath_loader_path\.dylib]]
-  [[/usr/lib/libSystem\.B\.dylib]]
-  )
-check_contents(deps/deps6.txt "^${_check}$")
-
-set(_check
-  [[@executable_path/../lib/executable_path/libexecutable_path\.dylib]]
-  [[@loader_path/loader_path_unresolved/libloader_path_unresolved\.dylib]]
-  [[@rpath/librpath_executable_path\.dylib]]
-  [[@rpath/librpath_executable_path_bundle\.dylib]]
-  [[@rpath/librpath_loader_path_unresolved\.dylib]]
-  [[@rpath/librpath_unresolved\.dylib]]
-  )
-check_contents(deps/udeps6.txt "^${_check}$")
-
-set(_check
-  "^libconflict\\.dylib:[^;]*/Tests/RunCMake/install/file-GET_RUNTIME_DEPENDENCIES-macos-build/root-all/executable/lib/conflict/libconflict\\.dylib;[^;]*/Tests/RunCMake/install/file-GET_RUNTIME_DEPENDENCIES-macos-build/root-all/executable/lib/conflict2/libconflict\\.dylib\n$"
-  )
-check_contents(deps/cdeps1.txt "${_check}")
-check_contents(deps/cdeps2.txt "${_check}")
-check_contents(deps/cdeps3.txt "${_check}")
-check_contents(deps/cdeps4.txt "${_check}")
-check_contents(deps/cdeps5.txt "${_check}")
-check_contents(deps/cdeps6.txt "${_check}")
diff --git a/Tests/RunCMake/install/file-GET_RUNTIME_DEPENDENCIES-macos-conflict-all-stderr.txt b/Tests/RunCMake/install/file-GET_RUNTIME_DEPENDENCIES-macos-conflict-all-stderr.txt
deleted file mode 100644
index bc9e97a..0000000
--- a/Tests/RunCMake/install/file-GET_RUNTIME_DEPENDENCIES-macos-conflict-all-stderr.txt
+++ /dev/null
@@ -1,7 +0,0 @@
-^CMake Error at cmake_install\.cmake:[0-9]+ \(file\):
-  file Multiple conflicting paths found for librpath\.dylib:
-
-    [^
-]*/Tests/RunCMake/install/file-GET_RUNTIME_DEPENDENCIES-macos-conflict-build/root-all/lib/rpath1/librpath\.dylib
-    [^
-]*/Tests/RunCMake/install/file-GET_RUNTIME_DEPENDENCIES-macos-conflict-build/root-all/lib/rpath2/librpath\.dylib$
diff --git a/Tests/RunCMake/install/file-GET_RUNTIME_DEPENDENCIES-macos-notfile-all-stderr.txt b/Tests/RunCMake/install/file-GET_RUNTIME_DEPENDENCIES-macos-notfile-all-stderr.txt
deleted file mode 100644
index 73ab9f1..0000000
--- a/Tests/RunCMake/install/file-GET_RUNTIME_DEPENDENCIES-macos-notfile-all-stderr.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-^CMake Error at cmake_install\.cmake:[0-9]+ \(file\):
-  file Failed to run otool on:
-
-    [^
-]*/Tests/RunCMake/install/file-GET_RUNTIME_DEPENDENCIES-macos-notfile-build/root-all/bin/\.\./lib/libtest\.dylib$
diff --git a/Tests/RunCMake/install/file-GET_RUNTIME_DEPENDENCIES-macos.cmake b/Tests/RunCMake/install/file-GET_RUNTIME_DEPENDENCIES-macos.cmake
deleted file mode 100644
index 6db05b3..0000000
--- a/Tests/RunCMake/install/file-GET_RUNTIME_DEPENDENCIES-macos.cmake
+++ /dev/null
@@ -1,216 +0,0 @@
-enable_language(C)
-
-set(testlib_names
-  preexcluded
-  executable_path
-  executable_path_bundle
-  executable_path_postexcluded
-  loader_path
-  loader_path_unresolved
-  loader_path_postexcluded
-  rpath
-  rpath_unresolved
-  rpath_postexcluded
-  rpath_executable_path
-  rpath_executable_path_bundle
-  rpath_executable_path_postexcluded
-  rpath_loader_path
-  rpath_loader_path_unresolved
-  rpath_loader_path_postexcluded
-  normal
-  normal_unresolved
-  normal_postexcluded
-  conflict
-  )
-
-file(REMOVE "${CMAKE_BINARY_DIR}/testlib.c")
-add_library(testlib SHARED "${CMAKE_BINARY_DIR}/testlib.c")
-foreach(name ${testlib_names})
-  if(name STREQUAL "normal")
-    file(WRITE "${CMAKE_BINARY_DIR}/normal.c" "extern void rpath(void);\nvoid normal(void)\n{\n  rpath();\n}\n")
-  else()
-    file(WRITE "${CMAKE_BINARY_DIR}/${name}.c" "void ${name}(void) {}\n")
-  endif()
-  add_library(${name} SHARED "${CMAKE_BINARY_DIR}/${name}.c")
-
-  file(APPEND "${CMAKE_BINARY_DIR}/testlib.c" "extern void ${name}(void);\n")
-endforeach()
-file(APPEND "${CMAKE_BINARY_DIR}/testlib.c" "void testlib(void)\n{\n")
-foreach(name ${testlib_names})
-  file(APPEND "${CMAKE_BINARY_DIR}/testlib.c" "  ${name}();\n")
-endforeach()
-file(APPEND "${CMAKE_BINARY_DIR}/testlib.c" "}\n")
-set_property(TARGET ${testlib_names} PROPERTY BUILD_WITH_INSTALL_NAME_DIR 1)
-target_link_libraries(normal PRIVATE rpath)
-set_property(TARGET normal PROPERTY INSTALL_RPATH
-  "${CMAKE_BINARY_DIR}/root-all/executable/lib/normal/../rpath"
-  )
-
-file(WRITE "${CMAKE_BINARY_DIR}/testlib_conflict.c" "extern void conflict(void);\nvoid testlib_conflict(void)\n{\n  conflict();\n}\n")
-add_library(testlib_conflict SHARED "${CMAKE_BINARY_DIR}/testlib_conflict.c")
-target_link_libraries(testlib_conflict PRIVATE conflict)
-
-set_property(TARGET testlib PROPERTY INSTALL_RPATH
-  "${CMAKE_BINARY_DIR}/root-all/executable/lib/rpath"
-  "${CMAKE_BINARY_DIR}/root-all/executable/lib/rpath_unresolved"
-  "${CMAKE_BINARY_DIR}/root-all/executable/lib/rpath_postexcluded"
-  "${CMAKE_BINARY_DIR}/root-all/executable/lib/conflict"
-  @executable_path/../lib/rpath_executable_path
-  @executable_path/../lib/rpath_executable_path_unresolved
-  @executable_path/../lib/rpath_executable_path_postexcluded
-  @loader_path/rpath_loader_path
-  @loader_path/rpath_loader_path_unresolved
-  @loader_path/rpath_loader_path_postexcluded
-  )
-set_property(TARGET testlib_conflict PROPERTY INSTALL_RPATH
-  "${CMAKE_BINARY_DIR}/root-all/executable/lib/conflict2"
-  )
-
-foreach(t
-  executable_path
-  executable_path_postexcluded
-  loader_path
-  loader_path_postexcluded
-  rpath
-  rpath_postexcluded
-  rpath_executable_path
-  rpath_executable_path_postexcluded
-  rpath_loader_path
-  rpath_loader_path_postexcluded
-  conflict
-  )
-  install(TARGETS ${t} DESTINATION executable/lib/${t})
-endforeach()
-install(TARGETS conflict DESTINATION executable/lib/conflict2)
-
-foreach(t
-  executable_path_bundle
-  executable_path_postexcluded
-  loader_path_postexcluded
-  rpath_postexcluded
-  rpath_executable_path_bundle
-  rpath_executable_path_postexcluded
-  rpath_loader_path_postexcluded
-  )
-  install(TARGETS ${t} DESTINATION bundle_executable/lib/${t})
-endforeach()
-
-foreach(t executable_path executable_path_bundle executable_path_postexcluded)
-  set_property(TARGET ${t} PROPERTY INSTALL_NAME_DIR @executable_path/../lib/${t})
-endforeach()
-
-foreach(t loader_path loader_path_unresolved loader_path_postexcluded)
-  set_property(TARGET ${t} PROPERTY INSTALL_NAME_DIR @loader_path/${t})
-endforeach()
-
-foreach(t
-  rpath
-  rpath_unresolved
-  rpath_postexcluded
-  rpath_executable_path
-  rpath_executable_path_bundle
-  rpath_executable_path_postexcluded
-  rpath_loader_path
-  rpath_loader_path_unresolved
-  rpath_loader_path_postexcluded
-  conflict
-  )
-  set_property(TARGET ${t} PROPERTY INSTALL_NAME_DIR @rpath)
-endforeach()
-
-foreach(t normal normal_unresolved normal_postexcluded)
-  set_property(TARGET ${t} PROPERTY INSTALL_NAME_DIR "${CMAKE_BINARY_DIR}/root-all/executable/lib/${t}")
-  if(NOT t STREQUAL "normal_unresolved")
-    install(TARGETS ${t} DESTINATION executable/lib/${t})
-  endif()
-endforeach()
-
-target_link_libraries(testlib PRIVATE ${testlib_names})
-
-add_executable(topexe file-GET_RUNTIME_DEPENDENCIES-macos/topexe.c)
-add_library(toplib SHARED file-GET_RUNTIME_DEPENDENCIES-macos/toplib.c)
-add_library(topmod MODULE file-GET_RUNTIME_DEPENDENCIES-macos/toplib.c)
-target_link_libraries(topexe PRIVATE testlib)
-target_link_libraries(toplib PRIVATE testlib)
-target_link_libraries(topmod PRIVATE testlib)
-
-set_property(TARGET topexe toplib topmod PROPERTY INSTALL_RPATH "${CMAKE_BINARY_DIR}/root-all/executable/lib")
-
-install(TARGETS topexe toplib topmod testlib testlib_conflict RUNTIME DESTINATION executable/bin LIBRARY DESTINATION executable/lib)
-install(TARGETS topexe toplib topmod testlib testlib_conflict RUNTIME DESTINATION bundle_executable/bin LIBRARY DESTINATION bundle_executable/lib)
-
-install(CODE [[
-  function(exec_get_runtime_dependencies depsfile udepsfile cdepsfile)
-    file(GET_RUNTIME_DEPENDENCIES
-      RESOLVED_DEPENDENCIES_VAR deps
-      UNRESOLVED_DEPENDENCIES_VAR udeps
-      CONFLICTING_DEPENDENCIES_PREFIX cdeps
-      PRE_INCLUDE_REGEXES "^.*/lib(testlib|executable_path|executable_path_bundle|executable_path_postexcluded|loader_path|loader_path_unresolved|loader_path_postexcluded|rpath|rpath_unresolved|rpath_postexcluded|rpath_executable_path|rpath_executable_path_bundle|rpath_executable_path_postexcluded|rpath_loader_path|rpath_loader_path_unresolved|rpath_loader_path_postexcluded|normal|normal_unresolved|normal_postexcluded|conflict|System\\.B)\\.dylib$"
-      PRE_EXCLUDE_REGEXES ".*"
-      POST_INCLUDE_REGEXES "^.*/lib(testlib|executable_path|executable_path_bundle|loader_path|rpath|rpath_executable_path|rpath_executable_path_bundle|rpath_loader_path|normal|conflict|System\\.B)\\.dylib$"
-      POST_EXCLUDE_REGEXES ".*"
-      ${ARGN}
-      )
-    list(SORT deps)
-    list(SORT udeps)
-    list(SORT cdeps_FILENAMES)
-    file(WRITE "${CMAKE_INSTALL_PREFIX}/deps/${depsfile}" "${deps}")
-    file(WRITE "${CMAKE_INSTALL_PREFIX}/deps/${udepsfile}" "${udeps}")
-    file(WRITE "${CMAKE_INSTALL_PREFIX}/deps/${cdepsfile}" "")
-    foreach(cdep IN LISTS cdeps_FILENAMES)
-      set(cdep_values ${cdeps_${cdep}})
-      list(SORT cdep_values)
-      file(APPEND "${CMAKE_INSTALL_PREFIX}/deps/${cdepsfile}" "${cdep}:${cdep_values}\n")
-    endforeach()
-  endfunction()
-
-  exec_get_runtime_dependencies(
-    deps1.txt udeps1.txt cdeps1.txt
-    EXECUTABLES
-      "${CMAKE_INSTALL_PREFIX}/executable/bin/$<TARGET_FILE_NAME:topexe>"
-    LIBRARIES
-      "${CMAKE_INSTALL_PREFIX}/executable/lib/$<TARGET_FILE_NAME:testlib_conflict>"
-    )
-
-  exec_get_runtime_dependencies(
-    deps2.txt udeps2.txt cdeps2.txt
-    LIBRARIES
-      "${CMAKE_INSTALL_PREFIX}/executable/lib/$<TARGET_FILE_NAME:toplib>"
-      "${CMAKE_INSTALL_PREFIX}/executable/lib/$<TARGET_FILE_NAME:testlib_conflict>"
-    )
-
-  exec_get_runtime_dependencies(
-    deps3.txt udeps3.txt cdeps3.txt
-    MODULES
-      "${CMAKE_INSTALL_PREFIX}/executable/lib/$<TARGET_FILE_NAME:topmod>"
-    LIBRARIES
-      "${CMAKE_INSTALL_PREFIX}/executable/lib/$<TARGET_FILE_NAME:testlib_conflict>"
-    )
-
-  exec_get_runtime_dependencies(
-    deps4.txt udeps4.txt cdeps4.txt
-    EXECUTABLES
-      "${CMAKE_INSTALL_PREFIX}/executable/bin/$<TARGET_FILE_NAME:topexe>"
-    LIBRARIES
-      "${CMAKE_INSTALL_PREFIX}/executable/lib/$<TARGET_FILE_NAME:testlib_conflict>"
-    BUNDLE_EXECUTABLE
-      "${CMAKE_INSTALL_PREFIX}/bundle_executable/bin/$<TARGET_FILE_NAME:topexe>"
-    )
-
-  exec_get_runtime_dependencies(
-    deps5.txt udeps5.txt cdeps5.txt
-    LIBRARIES
-      "${CMAKE_INSTALL_PREFIX}/executable/lib/$<TARGET_FILE_NAME:toplib>"
-      "${CMAKE_INSTALL_PREFIX}/executable/lib/$<TARGET_FILE_NAME:testlib_conflict>"
-    BUNDLE_EXECUTABLE "${CMAKE_INSTALL_PREFIX}/bundle_executable/bin/$<TARGET_FILE_NAME:topexe>"
-    )
-
-  exec_get_runtime_dependencies(
-    deps6.txt udeps6.txt cdeps6.txt
-    MODULES
-      "${CMAKE_INSTALL_PREFIX}/executable/lib/$<TARGET_FILE_NAME:topmod>"
-    LIBRARIES
-      "${CMAKE_INSTALL_PREFIX}/executable/lib/$<TARGET_FILE_NAME:testlib_conflict>"
-    BUNDLE_EXECUTABLE "${CMAKE_INSTALL_PREFIX}/bundle_executable/bin/$<TARGET_FILE_NAME:topexe>"
-    )
-  ]])
diff --git a/Tests/RunCMake/install/file-GET_RUNTIME_DEPENDENCIES-project-stderr.txt b/Tests/RunCMake/install/file-GET_RUNTIME_DEPENDENCIES-project-stderr.txt
deleted file mode 100644
index d506645..0000000
--- a/Tests/RunCMake/install/file-GET_RUNTIME_DEPENDENCIES-project-stderr.txt
+++ /dev/null
@@ -1,13 +0,0 @@
-^CMake Warning \(dev\) at file-GET_RUNTIME_DEPENDENCIES-project\.cmake:[0-9]+ \(file\):
-  You have used file\(GET_RUNTIME_DEPENDENCIES\) in project mode\.  This is
-  probably not what you intended to do\.  Instead, please consider using it in
-  an install\(CODE\) or install\(SCRIPT\) command\.  For example:
-
-    install\(CODE \[\[
-      file\(GET_RUNTIME_DEPENDENCIES
-        # \.\.\.
-        \)
-      ]]\)
-Call Stack \(most recent call first\):
-  CMakeLists\.txt:[0-9]+ \(include\)
-This warning is for project developers\.  Use -Wno-dev to suppress it\.$
diff --git a/Tests/RunCMake/install/file-GET_RUNTIME_DEPENDENCIES-unsupported-stderr.txt b/Tests/RunCMake/install/file-GET_RUNTIME_DEPENDENCIES-unsupported-stderr.txt
deleted file mode 100644
index 3db835c..0000000
--- a/Tests/RunCMake/install/file-GET_RUNTIME_DEPENDENCIES-unsupported-stderr.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-^CMake Error at file-GET_RUNTIME_DEPENDENCIES-unsupported\.cmake:[0-9]+ \(file\):
-  file GET_RUNTIME_DEPENDENCIES is not supported on system "[^
- ]+"
-Call Stack \(most recent call first\):
-  CMakeLists\.txt:[0-9]+ \(include\)$
diff --git a/Tests/RunCMake/install/file-GET_RUNTIME_DEPENDENCIES-windows-all-check.cmake b/Tests/RunCMake/install/file-GET_RUNTIME_DEPENDENCIES-windows-all-check.cmake
deleted file mode 100644
index c120ce4..0000000
--- a/Tests/RunCMake/install/file-GET_RUNTIME_DEPENDENCIES-windows-all-check.cmake
+++ /dev/null
@@ -1,38 +0,0 @@
-function(check_contents filename contents_regex)
-  if(EXISTS "${CMAKE_INSTALL_PREFIX}/${filename}")
-    file(READ "${CMAKE_INSTALL_PREFIX}/${filename}" contents)
-    if(NOT contents MATCHES "${contents_regex}")
-      string(APPEND RunCMake_TEST_FAILED "File contents:
-  ${contents}
-do not match what we expected:
-  ${contents_regex}
-in file:
-  ${CMAKE_INSTALL_PREFIX}/${filename}\n")
-      set(RunCMake_TEST_FAILED "${RunCMake_TEST_FAILED}" PARENT_SCOPE)
-    endif()
-  else()
-    string(APPEND RunCMake_TEST_FAILED "File ${CMAKE_INSTALL_PREFIX}/${filename} does not exist")
-    set(RunCMake_TEST_FAILED "${RunCMake_TEST_FAILED}" PARENT_SCOPE)
-  endif()
-endfunction()
-
-set(_check
-  [=[[^;]*/Tests/RunCMake/install/file-GET_RUNTIME_DEPENDENCIES-windows-build/root-all/bin/\.conflict/\.\./(lib)?libdir\.dll]=]
-  [=[[^;]*/Tests/RunCMake/install/file-GET_RUNTIME_DEPENDENCIES-windows-build/root-all/bin/\.search/(lib)?search\.dll]=]
-  [=[[^;]*/Tests/RunCMake/install/file-GET_RUNTIME_DEPENDENCIES-windows-build/root-all/bin/(lib)?testlib\.dll]=]
-  )
-check_contents(deps/deps1.txt "^${_check}$")
-check_contents(deps/deps2.txt "^${_check}$")
-check_contents(deps/deps3.txt "^${_check}$")
-set(_check
-  [=[(lib)?unresolved\.dll]=]
-  )
-check_contents(deps/udeps1.txt "^${_check}$")
-check_contents(deps/udeps2.txt "^${_check}$")
-check_contents(deps/udeps3.txt "^${_check}$")
-set(_check
-  "^(lib)?conflict\\.dll:[^;]*/Tests/RunCMake/install/file-GET_RUNTIME_DEPENDENCIES-windows-build/root-all/bin/\\.conflict/(lib)?conflict\\.dll;[^;]*/Tests/RunCMake/install/file-GET_RUNTIME_DEPENDENCIES-windows-build/root-all/bin/(lib)?conflict\\.dll\n$"
-  )
-check_contents(deps/cdeps1.txt "${_check}")
-check_contents(deps/cdeps2.txt "${_check}")
-check_contents(deps/cdeps3.txt "${_check}")
diff --git a/Tests/RunCMake/install/file-GET_RUNTIME_DEPENDENCIES-windows-conflict-all-stderr.txt b/Tests/RunCMake/install/file-GET_RUNTIME_DEPENDENCIES-windows-conflict-all-stderr.txt
deleted file mode 100644
index 66ecb93..0000000
--- a/Tests/RunCMake/install/file-GET_RUNTIME_DEPENDENCIES-windows-conflict-all-stderr.txt
+++ /dev/null
@@ -1,7 +0,0 @@
-^CMake Error at cmake_install\.cmake:[0-9]+ \(file\):
-  file Multiple conflicting paths found for (lib)?path\.dll:
-
-    [^
-]*/Tests/RunCMake/install/file-GET_RUNTIME_DEPENDENCIES-windows-conflict-build/root-all/lib/test1/(lib)?path\.dll
-    [^
-]*/Tests/RunCMake/install/file-GET_RUNTIME_DEPENDENCIES-windows-conflict-build/root-all/lib/test2/(lib)?path\.dll$
diff --git a/Tests/RunCMake/install/file-GET_RUNTIME_DEPENDENCIES-windows-notfile-all-stderr.txt b/Tests/RunCMake/install/file-GET_RUNTIME_DEPENDENCIES-windows-notfile-all-stderr.txt
deleted file mode 100644
index f921409..0000000
--- a/Tests/RunCMake/install/file-GET_RUNTIME_DEPENDENCIES-windows-notfile-all-stderr.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-^CMake Error at cmake_install\.cmake:[0-9]+ \(file\):
-  file Failed to run (dumpbin|objdump) on:
-
-    [^
-]*/Tests/RunCMake/install/file-GET_RUNTIME_DEPENDENCIES-windows-notfile-build/root-all/bin/(lib)?test\.dll$
diff --git a/Tests/RunCMake/install/file-GET_RUNTIME_DEPENDENCIES-windows.cmake b/Tests/RunCMake/install/file-GET_RUNTIME_DEPENDENCIES-windows.cmake
deleted file mode 100644
index 19288d8..0000000
--- a/Tests/RunCMake/install/file-GET_RUNTIME_DEPENDENCIES-windows.cmake
+++ /dev/null
@@ -1,114 +0,0 @@
-enable_language(C)
-
-set(testlib_names
-  preexcluded
-  libdir_postexcluded
-  libdir
-  search_postexcluded
-  search
-  unresolved
-  conflict
-  )
-
-file(REMOVE "${CMAKE_BINARY_DIR}/testlib.c")
-add_library(testlib SHARED "${CMAKE_BINARY_DIR}/testlib.c")
-foreach(name ${testlib_names})
-  file(WRITE "${CMAKE_BINARY_DIR}/${name}.c" "__declspec(dllexport) void ${name}(void) {}\n")
-  add_library(${name} SHARED "${CMAKE_BINARY_DIR}/${name}.c")
-
-  file(APPEND "${CMAKE_BINARY_DIR}/testlib.c" "__declspec(dllimport) extern void ${name}(void);\n")
-endforeach()
-file(APPEND "${CMAKE_BINARY_DIR}/testlib.c" "__declspec(dllexport) void testlib(void)\n{\n")
-foreach(name ${testlib_names})
-  file(APPEND "${CMAKE_BINARY_DIR}/testlib.c" "  ${name}();\n")
-endforeach()
-file(APPEND "${CMAKE_BINARY_DIR}/testlib.c" "}\n")
-
-target_link_libraries(testlib PRIVATE ${testlib_names})
-
-file(WRITE "${CMAKE_BINARY_DIR}/testlib_conflict.c" "__declspec(dllimport) extern void conflict(void);\n__declspec(dllexport) void testlib_conflict(void)\n{\n  conflict();\n}\n")
-add_library(testlib_conflict SHARED "${CMAKE_BINARY_DIR}/testlib_conflict.c")
-target_link_libraries(testlib_conflict PRIVATE conflict)
-
-file(WRITE "${CMAKE_BINARY_DIR}/testlib_noconflict.c" "__declspec(dllimport) extern void libdir(void);\n__declspec(dllexport) void testlib_noconflict(void)\n{\n  libdir();\n}\n")
-add_library(testlib_noconflict SHARED "${CMAKE_BINARY_DIR}/testlib_noconflict.c")
-target_link_libraries(testlib_noconflict PRIVATE libdir)
-
-install(TARGETS testlib libdir_postexcluded libdir conflict testlib_noconflict DESTINATION bin)
-install(TARGETS libdir search_postexcluded search DESTINATION bin/.search) # Prefixing with "." ensures it is the first item after list(SORT)
-install(TARGETS testlib_conflict conflict DESTINATION bin/.conflict)
-
-add_executable(topexe file-GET_RUNTIME_DEPENDENCIES-windows/topexe.c)
-add_library(toplib SHARED file-GET_RUNTIME_DEPENDENCIES-windows/toplib.c)
-add_library(topmod MODULE file-GET_RUNTIME_DEPENDENCIES-windows/toplib.c)
-target_link_libraries(topexe PRIVATE testlib)
-target_link_libraries(toplib PRIVATE testlib)
-target_link_libraries(topmod PRIVATE testlib)
-
-install(TARGETS topexe toplib topmod DESTINATION bin)
-
-install(CODE [[
-  function(exec_get_runtime_dependencies depsfile udepsfile cdepsfile)
-    file(GET_RUNTIME_DEPENDENCIES
-      RESOLVED_DEPENDENCIES_VAR deps
-      UNRESOLVED_DEPENDENCIES_VAR udeps
-      CONFLICTING_DEPENDENCIES_PREFIX cdeps
-      PRE_INCLUDE_REGEXES
-        "^(lib)?testlib\\.dll$"
-        "^(lib)?libdir_postexcluded\\.dll$"
-        "^(lib)?libdir\\.dll$"
-        "^(lib)?search_postexcluded\\.dll$"
-        "^(lib)?search\\.dll$"
-        "^(lib)?unresolved\\.dll$"
-        "^(lib)?conflict\\.dll$"
-        "^kernel32\\.dll$"
-      PRE_EXCLUDE_REGEXES ".*"
-      POST_INCLUDE_REGEXES
-        "^.*/(lib)?testlib\\.dll$"
-        "^.*/(lib)?libdir\\.dll$"
-        "^.*/(lib)?search\\.dll$"
-        "^.*/(lib)?conflict\\.dll$"
-      POST_EXCLUDE_REGEXES ".*"
-      DIRECTORIES
-        "${CMAKE_INSTALL_PREFIX}/bin/.search"
-      ${ARGN}
-      )
-    list(SORT deps)
-    list(SORT udeps)
-    list(SORT cdeps_FILENAMES)
-    file(WRITE "${CMAKE_INSTALL_PREFIX}/deps/${depsfile}" "${deps}")
-    file(WRITE "${CMAKE_INSTALL_PREFIX}/deps/${udepsfile}" "${udeps}")
-    file(WRITE "${CMAKE_INSTALL_PREFIX}/deps/${cdepsfile}" "")
-    foreach(cdep IN LISTS cdeps_FILENAMES)
-      set(cdep_values ${cdeps_${cdep}})
-      list(SORT cdep_values)
-      file(APPEND "${CMAKE_INSTALL_PREFIX}/deps/${cdepsfile}" "${cdep}:${cdep_values}\n")
-    endforeach()
-  endfunction()
-
-  exec_get_runtime_dependencies(
-    deps1.txt udeps1.txt cdeps1.txt
-    EXECUTABLES
-      "${CMAKE_INSTALL_PREFIX}/bin/$<TARGET_FILE_NAME:topexe>"
-    LIBRARIES
-      "${CMAKE_INSTALL_PREFIX}/bin/.conflict/$<TARGET_FILE_NAME:testlib_conflict>"
-      "${CMAKE_INSTALL_PREFIX}/bin/.conflict/../$<TARGET_FILE_NAME:testlib_noconflict>"
-    )
-
-  exec_get_runtime_dependencies(
-    deps2.txt udeps2.txt cdeps2.txt
-    LIBRARIES
-      "${CMAKE_INSTALL_PREFIX}/bin/$<TARGET_FILE_NAME:toplib>"
-      "${CMAKE_INSTALL_PREFIX}/bin/.conflict/$<TARGET_FILE_NAME:testlib_conflict>"
-      "${CMAKE_INSTALL_PREFIX}/bin/.conflict/../$<TARGET_FILE_NAME:testlib_noconflict>"
-    )
-
-  exec_get_runtime_dependencies(
-    deps3.txt udeps3.txt cdeps3.txt
-    MODULES
-      "${CMAKE_INSTALL_PREFIX}/bin/$<TARGET_FILE_NAME:topmod>"
-    LIBRARIES
-      "${CMAKE_INSTALL_PREFIX}/bin/.conflict/$<TARGET_FILE_NAME:testlib_conflict>"
-      "${CMAKE_INSTALL_PREFIX}/bin/.conflict/../$<TARGET_FILE_NAME:testlib_noconflict>"
-    )
-  ]])
diff --git a/Tests/RunCMake/interface_library/CMakeLists.txt b/Tests/RunCMake/interface_library/CMakeLists.txt
deleted file mode 100644
index 12cd3c7..0000000
--- a/Tests/RunCMake/interface_library/CMakeLists.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-cmake_minimum_required(VERSION 2.8.4)
-project(${RunCMake_TEST} NONE)
-include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/interface_library/RunCMakeTest.cmake b/Tests/RunCMake/interface_library/RunCMakeTest.cmake
deleted file mode 100644
index 5a6af1d..0000000
--- a/Tests/RunCMake/interface_library/RunCMakeTest.cmake
+++ /dev/null
@@ -1,13 +0,0 @@
-include(RunCMake)
-
-run_cmake(invalid_name)
-run_cmake(target_commands)
-run_cmake(no_shared_libs)
-run_cmake(whitelist)
-run_cmake(invalid_signature)
-run_cmake(global-interface)
-run_cmake(genex_link)
-run_cmake(add_custom_command-TARGET)
-run_cmake(IMPORTED_LIBNAME-bad-value)
-run_cmake(IMPORTED_LIBNAME-non-iface)
-run_cmake(IMPORTED_LIBNAME-non-imported)
diff --git a/Tests/RunCMake/interface_library/global-interface-stderr.txt b/Tests/RunCMake/interface_library/global-interface-stderr.txt
deleted file mode 100644
index 23b45d9..0000000
--- a/Tests/RunCMake/interface_library/global-interface-stderr.txt
+++ /dev/null
@@ -1,9 +0,0 @@
-CMake Error at global-interface.cmake:2 \(add_library\):
-  Cannot find source file:
-
-    GLOBAL
-
-  Tried extensions( \.[A-Za-z+]+|
- )*
-Call Stack \(most recent call first\):
-  CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/interface_library/invalid_name.cmake b/Tests/RunCMake/interface_library/invalid_name.cmake
deleted file mode 100644
index 9a965aa..0000000
--- a/Tests/RunCMake/interface_library/invalid_name.cmake
+++ /dev/null
@@ -1,6 +0,0 @@
-
-add_library(if$ace INTERFACE)
-
-add_library(iface::target INTERFACE)
-
-add_library(if$target_imported INTERFACE IMPORTED)
diff --git a/Tests/RunCMake/interface_library/invalid_signature-stderr.txt b/Tests/RunCMake/interface_library/invalid_signature-stderr.txt
deleted file mode 100644
index 6374b33..0000000
--- a/Tests/RunCMake/interface_library/invalid_signature-stderr.txt
+++ /dev/null
@@ -1,89 +0,0 @@
-CMake Error at invalid_signature.cmake:2 \(add_library\):
-  add_library INTERFACE library requires no source arguments.
-Call Stack \(most recent call first\):
-  CMakeLists.txt:3 \(include\)
-+
-CMake Error at invalid_signature.cmake:3 \(add_library\):
-  add_library INTERFACE library specified with conflicting/multiple types.
-Call Stack \(most recent call first\):
-  CMakeLists.txt:3 \(include\)
-+
-CMake Error at invalid_signature.cmake:4 \(add_library\):
-  add_library INTERFACE library specified with conflicting/multiple types.
-Call Stack \(most recent call first\):
-  CMakeLists.txt:3 \(include\)
-+
-CMake Error at invalid_signature.cmake:5 \(add_library\):
-  add_library INTERFACE library specified with conflicting/multiple types.
-Call Stack \(most recent call first\):
-  CMakeLists.txt:3 \(include\)
-+
-CMake Error at invalid_signature.cmake:6 \(add_library\):
-  add_library INTERFACE library specified with conflicting/multiple types.
-Call Stack \(most recent call first\):
-  CMakeLists.txt:3 \(include\)
-+
-CMake Error at invalid_signature.cmake:7 \(add_library\):
-  add_library INTERFACE library specified with conflicting/multiple types.
-Call Stack \(most recent call first\):
-  CMakeLists.txt:3 \(include\)
-+
-CMake Error at invalid_signature.cmake:8 \(add_library\):
-  add_library INTERFACE library specified with conflicting/multiple types.
-Call Stack \(most recent call first\):
-  CMakeLists.txt:3 \(include\)
-+
-CMake Error at invalid_signature.cmake:9 \(add_library\):
-  add_library INTERFACE library specified with conflicting STATIC type.
-Call Stack \(most recent call first\):
-  CMakeLists.txt:3 \(include\)
-+
-CMake Error at invalid_signature.cmake:10 \(add_library\):
-  add_library INTERFACE library specified with conflicting SHARED type.
-Call Stack \(most recent call first\):
-  CMakeLists.txt:3 \(include\)
-+
-CMake Error at invalid_signature.cmake:11 \(add_library\):
-  add_library INTERFACE library specified with conflicting MODULE type.
-Call Stack \(most recent call first\):
-  CMakeLists.txt:3 \(include\)
-+
-CMake Error at invalid_signature.cmake:12 \(add_library\):
-  add_library INTERFACE library specified with conflicting OBJECT type.
-Call Stack \(most recent call first\):
-  CMakeLists.txt:3 \(include\)
-+
-CMake Error at invalid_signature.cmake:13 \(add_library\):
-  add_library INTERFACE library specified with conflicting UNKNOWN type.
-Call Stack \(most recent call first\):
-  CMakeLists.txt:3 \(include\)
-+
-CMake Error at invalid_signature.cmake:14 \(add_library\):
-  add_library INTERFACE library specified with conflicting ALIAS type.
-Call Stack \(most recent call first\):
-  CMakeLists.txt:3 \(include\)
-+
-CMake Error at invalid_signature.cmake:15 \(add_library\):
-  add_library INTERFACE library specified with conflicting ALIAS type.
-Call Stack \(most recent call first\):
-  CMakeLists.txt:3 \(include\)
-+
-CMake Error at invalid_signature.cmake:16 \(add_library\):
-  add_library INTERFACE library specified with conflicting/multiple types.
-Call Stack \(most recent call first\):
-  CMakeLists.txt:3 \(include\)
-+
-CMake Error at invalid_signature.cmake:17 \(add_library\):
-  add_library INTERFACE library may not be used with EXCLUDE_FROM_ALL.
-Call Stack \(most recent call first\):
-  CMakeLists.txt:3 \(include\)
-+
-CMake Error at invalid_signature.cmake:18 \(add_library\):
-  add_library INTERFACE library may not be used with EXCLUDE_FROM_ALL.
-Call Stack \(most recent call first\):
-  CMakeLists.txt:3 \(include\)
-+
-CMake Error at invalid_signature.cmake:20 \(add_library\):
-  add_library GLOBAL option may only be used with IMPORTED libraries.
-Call Stack \(most recent call first\):
-  CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/interface_library/invalid_signature.cmake b/Tests/RunCMake/interface_library/invalid_signature.cmake
deleted file mode 100644
index 4e53534..0000000
--- a/Tests/RunCMake/interface_library/invalid_signature.cmake
+++ /dev/null
@@ -1,20 +0,0 @@
-
-add_library(iface1 INTERFACE empty.cpp)
-add_library(iface3 STATIC INTERFACE)
-add_library(iface4 STATIC INTERFACE empty.cpp)
-add_library(iface5 SHARED INTERFACE)
-add_library(iface6 MODULE INTERFACE)
-add_library(iface7 OBJECT INTERFACE)
-add_library(iface8 UNKNOWN INTERFACE)
-add_library(iface9 INTERFACE STATIC)
-add_library(iface10 INTERFACE SHARED)
-add_library(iface11 INTERFACE MODULE)
-add_library(iface12 INTERFACE OBJECT)
-add_library(iface13 INTERFACE UNKNOWN)
-add_library(iface14 INTERFACE ALIAS)
-add_library(iface15 ALIAS INTERFACE)
-add_library(iface16 INTERFACE INTERFACE)
-add_library(iface17 INTERFACE EXCLUDE_FROM_ALL)
-add_library(iface18 EXCLUDE_FROM_ALL INTERFACE)
-# add_library(iface19 GLOBAL INTERFACE) Tested separately
-add_library(iface20 INTERFACE GLOBAL)
diff --git a/Tests/RunCMake/interface_library/whitelist-stderr.txt b/Tests/RunCMake/interface_library/whitelist-stderr.txt
deleted file mode 100644
index 577c0cc..0000000
--- a/Tests/RunCMake/interface_library/whitelist-stderr.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-CMake Error at whitelist.cmake:4 \(set_property\):
-  INTERFACE_LIBRARY targets may only have whitelisted properties.  The
-  property "OUTPUT_NAME" is not allowed.
-Call Stack \(most recent call first\):
-  CMakeLists.txt:3 \(include\)
-
-
-CMake Error at whitelist.cmake:5 \(set_property\):
-  INTERFACE_LIBRARY targets may only have whitelisted properties.  The
-  property "OUTPUT_NAME" is not allowed.
-Call Stack \(most recent call first\):
-  CMakeLists.txt:3 \(include\)
-
-
-CMake Error at whitelist.cmake:6 \(get_target_property\):
-  INTERFACE_LIBRARY targets may only have whitelisted properties.  The
-  property "OUTPUT_NAME" is not allowed.
-Call Stack \(most recent call first\):
-  CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/interface_library/whitelist.cmake b/Tests/RunCMake/interface_library/whitelist.cmake
deleted file mode 100644
index 0db6375..0000000
--- a/Tests/RunCMake/interface_library/whitelist.cmake
+++ /dev/null
@@ -1,25 +0,0 @@
-
-add_library(iface INTERFACE)
-
-set_property(TARGET iface PROPERTY OUTPUT_NAME output)
-set_property(TARGET iface APPEND PROPERTY OUTPUT_NAME append)
-get_target_property(outname iface OUTPUT_NAME)
-
-# Properties starting with `_` are allowed.
-set_property(TARGET iface PROPERTY "_custom_property" output)
-set_property(TARGET iface APPEND PROPERTY "_custom_property" append)
-get_target_property(outname iface "_custom_property")
-
-# Properties starting with a lowercase letter are allowed.
-set_property(TARGET iface PROPERTY "custom_property" output)
-set_property(TARGET iface APPEND PROPERTY "custom_property" append)
-get_target_property(outname iface "custom_property")
-
-# PUBLIC_HEADER / PRIVATE_HEADER properties are allowed
-set_property(TARGET iface PROPERTY PUBLIC_HEADER foo.h)
-set_property(TARGET iface APPEND PROPERTY PUBLIC_HEADER bar.h)
-get_target_property(outname iface PUBLIC_HEADER)
-
-set_property(TARGET iface PROPERTY PRIVATE_HEADER foo.h)
-set_property(TARGET iface APPEND PROPERTY PRIVATE_HEADER bar.h)
-get_target_property(outname iface PRIVATE_HEADER)
diff --git a/Tests/RunCMake/list/CMakeLists.txt b/Tests/RunCMake/list/CMakeLists.txt
index 12cd3c7..4b3de84 100644
--- a/Tests/RunCMake/list/CMakeLists.txt
+++ b/Tests/RunCMake/list/CMakeLists.txt
@@ -1,3 +1,3 @@
-cmake_minimum_required(VERSION 2.8.4)
+cmake_minimum_required(VERSION 2.8.12)
 project(${RunCMake_TEST} NONE)
 include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/list/GET-CMP0007-WARN-stderr.txt b/Tests/RunCMake/list/GET-CMP0007-WARN-stderr.txt
index a0f8837..9103bd2 100644
--- a/Tests/RunCMake/list/GET-CMP0007-WARN-stderr.txt
+++ b/Tests/RunCMake/list/GET-CMP0007-WARN-stderr.txt
@@ -1,4 +1,13 @@
-^CMake Warning \(dev\) at GET-CMP0007-WARN.cmake:4 \(list\):
+^CMake Deprecation Warning at GET-CMP0007-WARN.cmake:1 \(cmake_policy\):
+  Compatibility with CMake < 2.8.12 will be removed from a future version of
+  CMake.
+
+  Update the VERSION argument <min> value or use a ...<max> suffix to tell
+  CMake that the project does not need compatibility with older versions.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)
++
+CMake Warning \(dev\) at GET-CMP0007-WARN.cmake:4 \(list\):
   Policy CMP0007 is not set: list command no longer ignores empty elements.
   Run "cmake --help-policy CMP0007" for policy details.  Use the cmake_policy
   command to set the policy and suppress this warning.  List has value =
diff --git a/Tests/RunCMake/math/CMakeLists.txt b/Tests/RunCMake/math/CMakeLists.txt
index 12cd3c7..74b3ff8 100644
--- a/Tests/RunCMake/math/CMakeLists.txt
+++ b/Tests/RunCMake/math/CMakeLists.txt
@@ -1,3 +1,3 @@
-cmake_minimum_required(VERSION 2.8.4)
+cmake_minimum_required(VERSION 3.3)
 project(${RunCMake_TEST} NONE)
 include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/message/CMakeLists.txt b/Tests/RunCMake/message/CMakeLists.txt
index 12cd3c7..74b3ff8 100644
--- a/Tests/RunCMake/message/CMakeLists.txt
+++ b/Tests/RunCMake/message/CMakeLists.txt
@@ -1,3 +1,3 @@
-cmake_minimum_required(VERSION 2.8.4)
+cmake_minimum_required(VERSION 3.3)
 project(${RunCMake_TEST} NONE)
 include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/message/message-indent-multiline.cmake b/Tests/RunCMake/message/message-indent-multiline.cmake
index 0f789bf..3815569 100644
--- a/Tests/RunCMake/message/message-indent-multiline.cmake
+++ b/Tests/RunCMake/message/message-indent-multiline.cmake
@@ -9,5 +9,5 @@
 message(STATUS "${msg}\n\n")
 message(STATUS "${msg}")
 # This is just to make sure NOTICE messages are also get indented:
-# https://gitlab.kitware.com/cmake/cmake/issues/19418#note_588011
+# https://gitlab.kitware.com/cmake/cmake/-/issues/19418#note_588011
 message(NOTICE "${msg}")
diff --git a/Tests/RunCMake/no_install_prefix/CMakeLists.txt b/Tests/RunCMake/no_install_prefix/CMakeLists.txt
index 12cd3c7..74b3ff8 100644
--- a/Tests/RunCMake/no_install_prefix/CMakeLists.txt
+++ b/Tests/RunCMake/no_install_prefix/CMakeLists.txt
@@ -1,3 +1,3 @@
-cmake_minimum_required(VERSION 2.8.4)
+cmake_minimum_required(VERSION 3.3)
 project(${RunCMake_TEST} NONE)
 include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/project/CMakeLists.txt b/Tests/RunCMake/project/CMakeLists.txt
index 12cd3c7..4b3de84 100644
--- a/Tests/RunCMake/project/CMakeLists.txt
+++ b/Tests/RunCMake/project/CMakeLists.txt
@@ -1,3 +1,3 @@
-cmake_minimum_required(VERSION 2.8.4)
+cmake_minimum_required(VERSION 2.8.12)
 project(${RunCMake_TEST} NONE)
 include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/pseudo_cppcheck.c b/Tests/RunCMake/pseudo_cppcheck.c
index 5b1531b..e80620c 100644
--- a/Tests/RunCMake/pseudo_cppcheck.c
+++ b/Tests/RunCMake/pseudo_cppcheck.c
@@ -11,7 +11,8 @@
       fprintf(stdout, "stdout from bad command line arg '-bad'\n");
       fprintf(stderr, "stderr from bad command line arg '-bad'\n");
       return 1;
-    } else if (strcmp(argv[i], "-error") == 0) {
+    }
+    if (strcmp(argv[i], "-error") == 0) {
       // The real cppcheck allows to set the exitcode with --error-exitcode
       result = 5;
     }
diff --git a/Tests/RunCMake/set_property/RunCMakeTest.cmake b/Tests/RunCMake/set_property/RunCMakeTest.cmake
index 8d4614c..692c6b9 100644
--- a/Tests/RunCMake/set_property/RunCMakeTest.cmake
+++ b/Tests/RunCMake/set_property/RunCMakeTest.cmake
@@ -9,6 +9,7 @@
 run_cmake(LINK_DIRECTORIES)
 run_cmake(LINK_LIBRARIES)
 run_cmake(SOURCES)
+run_cmake(SOURCE_FILE)
 run_cmake(TYPE)
 run_cmake(USER_PROP)
 run_cmake(USER_PROP_INHERITED)
diff --git a/Tests/RunCMake/interface_library/whitelist-result.txt b/Tests/RunCMake/set_property/SOURCE_FILE-result.txt
similarity index 100%
copy from Tests/RunCMake/interface_library/whitelist-result.txt
copy to Tests/RunCMake/set_property/SOURCE_FILE-result.txt
diff --git a/Tests/RunCMake/set_property/SOURCE_FILE-stderr.txt b/Tests/RunCMake/set_property/SOURCE_FILE-stderr.txt
new file mode 100644
index 0000000..a2b6cf4
--- /dev/null
+++ b/Tests/RunCMake/set_property/SOURCE_FILE-stderr.txt
@@ -0,0 +1,22 @@
+^CMake Error at SOURCE_FILE.cmake:1 \(set_property\):
+  set_property called with incorrect number of arguments no value provided to
+  the DIRECTORY option
+Call Stack \(most recent call first\):
+  CMakeLists\.txt:[0-9]+ \(include\)
++
+CMake Error at SOURCE_FILE.cmake:2 \(set_property\):
+  set_property given non-existent DIRECTORY non_existing_dir
+Call Stack \(most recent call first\):
+  CMakeLists\.txt:[0-9]+ \(include\)
++
+CMake Error at SOURCE_FILE.cmake:3 \(set_property\):
+  set_property called with incorrect number of arguments no value provided to
+  the TARGET_DIRECTORY option
+Call Stack \(most recent call first\):
+  CMakeLists\.txt:[0-9]+ \(include\)
++
+CMake Error at SOURCE_FILE.cmake:4 \(set_property\):
+  set_property given non-existent target for TARGET_DIRECTORY
+  non_existing_target
+Call Stack \(most recent call first\):
+  CMakeLists\.txt:[0-9]+ \(include\)$
diff --git a/Tests/RunCMake/set_property/SOURCE_FILE.cmake b/Tests/RunCMake/set_property/SOURCE_FILE.cmake
new file mode 100644
index 0000000..b1d78bd
--- /dev/null
+++ b/Tests/RunCMake/set_property/SOURCE_FILE.cmake
@@ -0,0 +1,4 @@
+set_property(SOURCE a.txt DIRECTORY PROPERTY COMPILE_DEFINITIONS "def")
+set_property(SOURCE a.txt DIRECTORY non_existing_dir PROPERTY COMPILE_DEFINITIONS "def")
+set_property(SOURCE a.txt TARGET_DIRECTORY PROPERTY COMPILE_DEFINITIONS "def")
+set_property(SOURCE a.txt TARGET_DIRECTORY non_existing_target PROPERTY COMPILE_DEFINITIONS "def")
diff --git a/Tests/RunCMake/string/CMakeLists.txt b/Tests/RunCMake/string/CMakeLists.txt
index 12cd3c7..74b3ff8 100644
--- a/Tests/RunCMake/string/CMakeLists.txt
+++ b/Tests/RunCMake/string/CMakeLists.txt
@@ -1,3 +1,3 @@
-cmake_minimum_required(VERSION 2.8.4)
+cmake_minimum_required(VERSION 3.3)
 project(${RunCMake_TEST} NONE)
 include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/string/Hex.cmake b/Tests/RunCMake/string/Hex.cmake
new file mode 100644
index 0000000..1c5aaa1
--- /dev/null
+++ b/Tests/RunCMake/string/Hex.cmake
@@ -0,0 +1,20 @@
+function(assert_strequal input actual expected)
+  if(NOT expected STREQUAL actual)
+    message(SEND_ERROR "Output did not match expected\nInput string:\n  ${input}\nExpected:\n  ${expected}\nActual:\n  ${actual}")
+  endif()
+endfunction()
+
+set(_input1 "The quick brown fox jumps over the lazy dog.")
+string(HEX "${_input1}" _result1)
+assert_strequal("${_input1}" "${_result1}" "54686520717569636b2062726f776e20666f78206a756d7073206f76657220746865206c617a7920646f672e")
+
+set(_input2 "Hello world!")
+string(HEX "${_input2}" _result2)
+assert_strequal("${_input2}" "${_result2}" "48656c6c6f20776f726c6421")
+
+set(_input3 "Ash nazg durbatulûk\nAsh nazg gimbatul\nAsh nazg thrakatulûk\nAgh burzum-ishi krimpatul")
+string(HEX "${_input3}" _result3)
+assert_strequal("${_input3}" "${_result3}" "417368206e617a6720647572626174756cc3bb6b0a417368206e617a672067696d626174756c0a417368206e617a6720746872616b6174756cc3bb6b0a416768206275727a756d2d69736869206b72696d706174756c")
+
+string(HEX "" _result_empty)
+assert_strequal("" "${_result_empty}" "")
diff --git a/Tests/RunCMake/Languages/LINK_LANGUAGE-genex-result.txt b/Tests/RunCMake/string/HexNotEnoughArgs-result.txt
similarity index 100%
copy from Tests/RunCMake/Languages/LINK_LANGUAGE-genex-result.txt
copy to Tests/RunCMake/string/HexNotEnoughArgs-result.txt
diff --git a/Tests/RunCMake/string/HexNotEnoughArgs-stderr.txt b/Tests/RunCMake/string/HexNotEnoughArgs-stderr.txt
new file mode 100644
index 0000000..444f79d
--- /dev/null
+++ b/Tests/RunCMake/string/HexNotEnoughArgs-stderr.txt
@@ -0,0 +1,4 @@
+^CMake Error at HexNotEnoughArgs\.cmake:[0-9]+ \(string\):
+  string Incorrect number of arguments
+Call Stack \(most recent call first\):
+  CMakeLists\.txt:3 \(include\)$
diff --git a/Tests/RunCMake/string/HexNotEnoughArgs.cmake b/Tests/RunCMake/string/HexNotEnoughArgs.cmake
new file mode 100644
index 0000000..7002af0
--- /dev/null
+++ b/Tests/RunCMake/string/HexNotEnoughArgs.cmake
@@ -0,0 +1 @@
+string(HEX "Hello world!")
diff --git a/Tests/RunCMake/interface_library/target_commands-result.txt b/Tests/RunCMake/string/HexTooManyArgs-result.txt
similarity index 100%
copy from Tests/RunCMake/interface_library/target_commands-result.txt
copy to Tests/RunCMake/string/HexTooManyArgs-result.txt
diff --git a/Tests/RunCMake/string/HexTooManyArgs-stderr.txt b/Tests/RunCMake/string/HexTooManyArgs-stderr.txt
new file mode 100644
index 0000000..91b40ed
--- /dev/null
+++ b/Tests/RunCMake/string/HexTooManyArgs-stderr.txt
@@ -0,0 +1,4 @@
+^CMake Error at HexTooManyArgs\.cmake:[0-9]+ \(string\):
+  string Incorrect number of arguments
+Call Stack \(most recent call first\):
+  CMakeLists\.txt:3 \(include\)$
diff --git a/Tests/RunCMake/string/HexTooManyArgs.cmake b/Tests/RunCMake/string/HexTooManyArgs.cmake
new file mode 100644
index 0000000..8986cf8
--- /dev/null
+++ b/Tests/RunCMake/string/HexTooManyArgs.cmake
@@ -0,0 +1 @@
+string(HEX "Hello world!" _output bad)
diff --git a/Tests/RunCMake/string/RunCMakeTest.cmake b/Tests/RunCMake/string/RunCMakeTest.cmake
index c432b4e..bb7cb17 100644
--- a/Tests/RunCMake/string/RunCMakeTest.cmake
+++ b/Tests/RunCMake/string/RunCMakeTest.cmake
@@ -37,3 +37,7 @@
 run_cmake(Repeat)
 run_cmake(RepeatNoArgs)
 run_cmake(RepeatNegativeCount)
+
+run_cmake(Hex)
+run_cmake(HexTooManyArgs)
+run_cmake(HexNotEnoughArgs)
diff --git a/Tests/RunCMake/target_link_directories/CMP0099.cmake b/Tests/RunCMake/target_link_directories/CMP0099.cmake
index a2be279..aff1e33 100644
--- a/Tests/RunCMake/target_link_directories/CMP0099.cmake
+++ b/Tests/RunCMake/target_link_directories/CMP0099.cmake
@@ -5,7 +5,7 @@
 set(CMAKE_C_USE_RESPONSE_FILE_FOR_LIBRARIES FALSE)
 
 add_library(LinkDirs_interface INTERFACE)
-target_link_directories (LinkDirs_interface INTERFACE "/DIR_INTERFACE"})
+target_link_directories (LinkDirs_interface INTERFACE "/DIR_INTERFACE")
 
 add_library(LinkDirs_static STATIC lib.c)
 target_link_libraries (LinkDirs_static PRIVATE LinkDirs_interface)
diff --git a/Tests/RunCMake/target_link_directories/RunCMakeTest.cmake b/Tests/RunCMake/target_link_directories/RunCMakeTest.cmake
index a74ee25..699e871 100644
--- a/Tests/RunCMake/target_link_directories/RunCMakeTest.cmake
+++ b/Tests/RunCMake/target_link_directories/RunCMakeTest.cmake
@@ -21,10 +21,21 @@
     set(VERBOSE -- -v)
   endif()
 
+  run_cmake(genex_LINK_LANGUAGE)
+  run_cmake_target(genex_LINK_LANGUAGE interface LinkDirs_exe_interface --config Release ${VERBOSE})
+  run_cmake_target(genex_LINK_LANGUAGE basic LinkDirs_exe_c --config Release ${VERBOSE})
+  run_cmake_target(genex_LINK_LANGUAGE LINKER_LANGUAGE LinkDirs_exe_cxx --config Release ${VERBOSE})
+
+  run_cmake(genex_LINK_LANG_AND_ID)
+
+  run_cmake_target(genex_LINK_LANG_AND_ID interface LinkDirs_exe_interface --config Release ${VERBOSE})
+  run_cmake_target(genex_LINK_LANG_AND_ID basic LinkDirs_exe_c --config Release ${VERBOSE})
+  run_cmake_target(genex_LINK_LANG_AND_ID LINKER_LANGUAGE LinkDirs_exe_cxx --config Release ${VERBOSE})
+
+
   run_cmake(CMP0099-NEW)
   run_cmake_target(CMP0099-NEW basic LinkDirs_exe ${VERBOSE})
 
-
   run_cmake(CMP0099-OLD)
   run_cmake_target(CMP0099-OLD basic LinkDirs_exe ${VERBOSE})
 
diff --git a/Tests/RunCMake/target_link_directories/genex_LINK_LANGUAGE-LINKER_LANGUAGE-check.cmake b/Tests/RunCMake/target_link_directories/genex_LINK_LANGUAGE-LINKER_LANGUAGE-check.cmake
new file mode 100644
index 0000000..aa39810
--- /dev/null
+++ b/Tests/RunCMake/target_link_directories/genex_LINK_LANGUAGE-LINKER_LANGUAGE-check.cmake
@@ -0,0 +1,5 @@
+
+set (VALID_LANG CXX)
+set (INVALID_LANG C)
+
+include ("${CMAKE_CURRENT_LIST_DIR}/genex_LINK_LANGUAGE-validation.cmake")
diff --git a/Tests/RunCMake/target_link_directories/genex_LINK_LANGUAGE-LINKER_LANGUAGE-result.txt b/Tests/RunCMake/target_link_directories/genex_LINK_LANGUAGE-LINKER_LANGUAGE-result.txt
new file mode 100644
index 0000000..8d98f9d
--- /dev/null
+++ b/Tests/RunCMake/target_link_directories/genex_LINK_LANGUAGE-LINKER_LANGUAGE-result.txt
@@ -0,0 +1 @@
+.*
diff --git a/Tests/RunCMake/target_link_directories/genex_LINK_LANGUAGE-basic-check.cmake b/Tests/RunCMake/target_link_directories/genex_LINK_LANGUAGE-basic-check.cmake
new file mode 100644
index 0000000..71f641d
--- /dev/null
+++ b/Tests/RunCMake/target_link_directories/genex_LINK_LANGUAGE-basic-check.cmake
@@ -0,0 +1,2 @@
+
+include ("${CMAKE_CURRENT_LIST_DIR}/genex_LINK_LANGUAGE-validation.cmake")
diff --git a/Tests/RunCMake/target_link_directories/genex_LINK_LANGUAGE-basic-result.txt b/Tests/RunCMake/target_link_directories/genex_LINK_LANGUAGE-basic-result.txt
new file mode 100644
index 0000000..8d98f9d
--- /dev/null
+++ b/Tests/RunCMake/target_link_directories/genex_LINK_LANGUAGE-basic-result.txt
@@ -0,0 +1 @@
+.*
diff --git a/Tests/RunCMake/target_link_directories/genex_LINK_LANGUAGE-interface-check.cmake b/Tests/RunCMake/target_link_directories/genex_LINK_LANGUAGE-interface-check.cmake
new file mode 100644
index 0000000..8313de6
--- /dev/null
+++ b/Tests/RunCMake/target_link_directories/genex_LINK_LANGUAGE-interface-check.cmake
@@ -0,0 +1,4 @@
+
+set (TYPE INTERFACE)
+
+include ("${CMAKE_CURRENT_LIST_DIR}/genex_LINK_LANGUAGE-validation.cmake")
diff --git a/Tests/RunCMake/target_link_directories/genex_LINK_LANGUAGE-interface-result.txt b/Tests/RunCMake/target_link_directories/genex_LINK_LANGUAGE-interface-result.txt
new file mode 100644
index 0000000..8d98f9d
--- /dev/null
+++ b/Tests/RunCMake/target_link_directories/genex_LINK_LANGUAGE-interface-result.txt
@@ -0,0 +1 @@
+.*
diff --git a/Tests/RunCMake/target_link_directories/genex_LINK_LANGUAGE-validation.cmake b/Tests/RunCMake/target_link_directories/genex_LINK_LANGUAGE-validation.cmake
new file mode 100644
index 0000000..298564e
--- /dev/null
+++ b/Tests/RunCMake/target_link_directories/genex_LINK_LANGUAGE-validation.cmake
@@ -0,0 +1,20 @@
+
+if (NOT VALID_LANG)
+  set (VALID_LANG C)
+endif()
+if (NOT INVALID_LANG)
+  set (INVALID_LANG CXX)
+endif()
+if (NOT TYPE)
+  set (TYPE EXE)
+endif()
+
+if (NOT actual_stdout MATCHES "DIR_${VALID_LANG}_${TYPE}")
+  set (RunCMake_TEST_FAILED "Not found expected 'DIR_${VALID_LANG}_${TYPE}'.")
+endif()
+if (actual_stdout MATCHES "DIR_${INVALID_LANG}_${TYPE}")
+  if (RunCMake_TEST_FAILED)
+    string (APPEND RunCMake_TEST_FAILED "\n")
+  endif()
+  string (APPEND RunCMake_TEST_FAILED "Found unexpected 'DIR_${INVALID_LANG}_${TYPE}'.")
+endif()
diff --git a/Tests/RunCMake/target_link_directories/genex_LINK_LANGUAGE.cmake b/Tests/RunCMake/target_link_directories/genex_LINK_LANGUAGE.cmake
new file mode 100644
index 0000000..1f266b1
--- /dev/null
+++ b/Tests/RunCMake/target_link_directories/genex_LINK_LANGUAGE.cmake
@@ -0,0 +1,23 @@
+
+enable_language(C)
+enable_language(CXX)
+
+set(CMAKE_VERBOSE_MAKEFILE TRUE)
+set(CMAKE_C_USE_RESPONSE_FILE_FOR_LIBRARIES FALSE)
+set(CMAKE_CXX_USE_RESPONSE_FILE_FOR_LIBRARIES FALSE)
+
+add_library(LinkDirs_interface INTERFACE)
+target_link_directories (LinkDirs_interface INTERFACE "$<$<LINK_LANGUAGE:C>:/DIR_C_INTERFACE>"
+                                                      "$<$<LINK_LANGUAGE:CXX>:/DIR_CXX_INTERFACE>")
+
+add_executable(LinkDirs_exe_interface exe.c)
+target_link_libraries (LinkDirs_exe_interface PRIVATE LinkDirs_interface)
+
+add_executable(LinkDirs_exe_c exe.c)
+target_link_directories (LinkDirs_exe_c PRIVATE "$<$<LINK_LANGUAGE:C>:/DIR_C_EXE>"
+                                                "$<$<LINK_LANGUAGE:CXX>:/DIR_CXX_EXE>")
+
+add_executable(LinkDirs_exe_cxx exe.c)
+target_link_directories (LinkDirs_exe_cxx PRIVATE "$<$<LINK_LANGUAGE:C>:/DIR_C_EXE>"
+                                                 "$<$<LINK_LANGUAGE:CXX>:/DIR_CXX_EXE>")
+set_property (TARGET LinkDirs_exe_cxx PROPERTY LINKER_LANGUAGE CXX)
diff --git a/Tests/RunCMake/target_link_directories/genex_LINK_LANG_AND_ID-LINKER_LANGUAGE-check.cmake b/Tests/RunCMake/target_link_directories/genex_LINK_LANG_AND_ID-LINKER_LANGUAGE-check.cmake
new file mode 100644
index 0000000..ed4f851
--- /dev/null
+++ b/Tests/RunCMake/target_link_directories/genex_LINK_LANG_AND_ID-LINKER_LANGUAGE-check.cmake
@@ -0,0 +1,5 @@
+
+set (VALID_LANG CXX)
+set (INVALID_LANG C)
+
+include ("${CMAKE_CURRENT_LIST_DIR}/genex_LINK_LANG_AND_ID-validation.cmake")
diff --git a/Tests/RunCMake/target_link_directories/genex_LINK_LANG_AND_ID-LINKER_LANGUAGE-result.txt b/Tests/RunCMake/target_link_directories/genex_LINK_LANG_AND_ID-LINKER_LANGUAGE-result.txt
new file mode 100644
index 0000000..8d98f9d
--- /dev/null
+++ b/Tests/RunCMake/target_link_directories/genex_LINK_LANG_AND_ID-LINKER_LANGUAGE-result.txt
@@ -0,0 +1 @@
+.*
diff --git a/Tests/RunCMake/target_link_directories/genex_LINK_LANG_AND_ID-basic-check.cmake b/Tests/RunCMake/target_link_directories/genex_LINK_LANG_AND_ID-basic-check.cmake
new file mode 100644
index 0000000..6bddee1
--- /dev/null
+++ b/Tests/RunCMake/target_link_directories/genex_LINK_LANG_AND_ID-basic-check.cmake
@@ -0,0 +1,2 @@
+
+include ("${CMAKE_CURRENT_LIST_DIR}/genex_LINK_LANG_AND_ID-validation.cmake")
diff --git a/Tests/RunCMake/target_link_directories/genex_LINK_LANG_AND_ID-basic-result.txt b/Tests/RunCMake/target_link_directories/genex_LINK_LANG_AND_ID-basic-result.txt
new file mode 100644
index 0000000..8d98f9d
--- /dev/null
+++ b/Tests/RunCMake/target_link_directories/genex_LINK_LANG_AND_ID-basic-result.txt
@@ -0,0 +1 @@
+.*
diff --git a/Tests/RunCMake/target_link_directories/genex_LINK_LANG_AND_ID-interface-check.cmake b/Tests/RunCMake/target_link_directories/genex_LINK_LANG_AND_ID-interface-check.cmake
new file mode 100644
index 0000000..a328738
--- /dev/null
+++ b/Tests/RunCMake/target_link_directories/genex_LINK_LANG_AND_ID-interface-check.cmake
@@ -0,0 +1,4 @@
+
+set (TYPE INTERFACE)
+
+include ("${CMAKE_CURRENT_LIST_DIR}/genex_LINK_LANG_AND_ID-validation.cmake")
diff --git a/Tests/RunCMake/target_link_directories/genex_LINK_LANG_AND_ID-interface-result.txt b/Tests/RunCMake/target_link_directories/genex_LINK_LANG_AND_ID-interface-result.txt
new file mode 100644
index 0000000..8d98f9d
--- /dev/null
+++ b/Tests/RunCMake/target_link_directories/genex_LINK_LANG_AND_ID-interface-result.txt
@@ -0,0 +1 @@
+.*
diff --git a/Tests/RunCMake/target_link_directories/genex_LINK_LANG_AND_ID-validation.cmake b/Tests/RunCMake/target_link_directories/genex_LINK_LANG_AND_ID-validation.cmake
new file mode 100644
index 0000000..9872953
--- /dev/null
+++ b/Tests/RunCMake/target_link_directories/genex_LINK_LANG_AND_ID-validation.cmake
@@ -0,0 +1,26 @@
+
+if (NOT VALID_LANG)
+  set (VALID_LANG C)
+endif()
+if (NOT INVALID_LANG)
+  set (INVALID_LANG CXX)
+endif()
+if (NOT TYPE)
+  set (TYPE EXE)
+endif()
+
+if (NOT actual_stdout MATCHES "DIR_${VALID_LANG}_${TYPE}")
+  set (RunCMake_TEST_FAILED "Not found expected 'DIR_${VALID_LANG}_${TYPE}'.\n")
+endif()
+if (actual_stdout MATCHES "DIR_${INVALID_LANG}_${TYPE}")
+  if (RunCMake_TEST_FAILED)
+    string (APPEND RunCMake_TEST_FAILED "\n")
+  endif()
+  string (APPEND RunCMake_TEST_FAILED "Found unexpected 'DIR_${INVALID_LANG}_${TYPE} '.")
+endif()
+if (actual_stdout MATCHES "DIR_(${VALID_LANG}|${INVALID_LANG})_BADID_${TYPE}")
+  if (RunCMake_TEST_FAILED)
+    string (APPEND RunCMake_TEST_FAILED "\n")
+  endif()
+  string (APPEND RunCMake_TEST_FAILED "Found unexpected 'DIR_(${VALID_LANG}|${INVALID_LANG})_BADID_${TYPE}'.")
+endif()
diff --git a/Tests/RunCMake/target_link_directories/genex_LINK_LANG_AND_ID.cmake b/Tests/RunCMake/target_link_directories/genex_LINK_LANG_AND_ID.cmake
new file mode 100644
index 0000000..eb3b342
--- /dev/null
+++ b/Tests/RunCMake/target_link_directories/genex_LINK_LANG_AND_ID.cmake
@@ -0,0 +1,29 @@
+
+enable_language(C)
+enable_language(CXX)
+
+set(CMAKE_VERBOSE_MAKEFILE TRUE)
+set(CMAKE_C_USE_RESPONSE_FILE_FOR_LIBRARIES FALSE)
+set(CMAKE_CXX_USE_RESPONSE_FILE_FOR_LIBRARIES FALSE)
+
+add_library(LinkDirs_interface INTERFACE)
+target_link_directories (LinkDirs_interface INTERFACE $<$<LINK_LANG_AND_ID:C,${CMAKE_C_COMPILER_ID}>:/DIR_C_INTERFACE>
+                                                      $<$<LINK_LANG_AND_ID:CXX,${CMAKE_CXX_COMPILER_ID}>:/DIR_CXX_INTERFACE>
+                                                      $<$<LINK_LANG_AND_ID:C,BADID>:/DIR_C_BADID_INTERFACE>
+                                                      $<$<LINK_LANG_AND_ID:CXX,BADID>:/DIR_CXX_BADID_INTERFACE>)
+
+add_executable(LinkDirs_exe_interface exe.c)
+target_link_libraries (LinkDirs_exe_interface PRIVATE LinkDirs_interface)
+
+add_executable(LinkDirs_exe_c exe.c)
+target_link_options (LinkDirs_exe_c PRIVATE $<$<LINK_LANG_AND_ID:C,${CMAKE_C_COMPILER_ID}>:/DIR_C_EXE>
+                                            $<$<LINK_LANG_AND_ID:CXX,${CMAKE_CXX_COMPILER_ID}>:/DIR_CXX_EXE>
+                                            $<$<LINK_LANG_AND_ID:C,BADID>:/DIR_C_BADID_EXE>
+                                            $<$<LINK_LANG_AND_ID:CXX,BADID>:/DIR_CXX_BADID_EXE>)
+
+add_executable(LinkDirs_exe_cxx exe.c)
+target_link_directories (LinkDirs_exe_cxx PRIVATE $<$<LINK_LANG_AND_ID:C,${CMAKE_C_COMPILER_ID}>:/DIR_C_EXE>
+                                                  $<$<LINK_LANG_AND_ID:CXX,${CMAKE_CXX_COMPILER_ID}>:/DIR_CXX_EXE>
+                                                  $<$<LINK_LANG_AND_ID:C,BADID>:/DIR_C_BADID_EXE>
+                                                  $<$<LINK_LANG_AND_ID:CXX,BADID>:/DIR_CXX_BADID_EXE>)
+set_property (TARGET LinkDirs_exe_cxx PROPERTY LINKER_LANGUAGE CXX)
diff --git a/Tests/RunCMake/target_link_libraries-ALIAS/AliasTargets.cmake b/Tests/RunCMake/target_link_libraries-ALIAS/AliasTargets.cmake
new file mode 100644
index 0000000..316b74b
--- /dev/null
+++ b/Tests/RunCMake/target_link_libraries-ALIAS/AliasTargets.cmake
@@ -0,0 +1,39 @@
+
+cmake_minimum_required(VERSION 3.16...3.17)
+
+enable_language(C)
+
+add_library (func SHARED func.c)
+
+set (binary_dir "${CMAKE_BINARY_DIR}")
+get_property (is_multi_config GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
+if (is_multi_config)
+  string (APPEND binary_dir "/Release")
+endif()
+
+
+add_library(import-local SHARED IMPORTED)
+set_property(TARGET import-local PROPERTY IMPORTED_LOCATION "${binary_dir}/${CMAKE_STATIC_LIBRARY_PREFIX}func${CMAKE_SHARED_LIBRARY_SUFFIX}")
+set_property(TARGET import-local PROPERTY IMPORTED_IMPLIB "${binary_dir}/${CMAKE_STATIC_LIBRARY_PREFIX}func${CMAKE_IMPORT_LIBRARY_SUFFIX}")
+add_library(alias::local ALIAS import-local)
+
+add_library (lib-local SHARED lib.c)
+target_link_libraries (lib-local PRIVATE alias::local)
+
+add_executable (main-local main.c)
+target_link_libraries (main-local PRIVATE alias::local)
+
+
+add_library(import-global SHARED IMPORTED GLOBAL)
+set_property(TARGET import-global PROPERTY IMPORTED_LOCATION "${binary_dir}/${CMAKE_STATIC_LIBRARY_PREFIX}func${CMAKE_SHARED_LIBRARY_SUFFIX}")
+set_property(TARGET import-global PROPERTY IMPORTED_IMPLIB "${binary_dir}/${CMAKE_STATIC_LIBRARY_PREFIX}func${CMAKE_IMPORT_LIBRARY_SUFFIX}")
+add_library(alias::global ALIAS import-global)
+
+add_library (lib-global SHARED lib.c)
+target_link_libraries (lib-global PRIVATE alias::global)
+
+add_executable (main-global main.c)
+target_link_libraries (main-global PRIVATE alias::global)
+
+
+add_subdirectory(sub_dir)
diff --git a/Tests/RunCMake/target_link_libraries-ALIAS/CMakeLists.txt b/Tests/RunCMake/target_link_libraries-ALIAS/CMakeLists.txt
new file mode 100644
index 0000000..9cf020f
--- /dev/null
+++ b/Tests/RunCMake/target_link_libraries-ALIAS/CMakeLists.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 3.1)
+project(${RunCMake_TEST} NONE)
+include(${RunCMake_TEST}.cmake NO_POLICY_SCOPE)
diff --git a/Tests/RunCMake/target_link_libraries-ALIAS/RunCMakeTest.cmake b/Tests/RunCMake/target_link_libraries-ALIAS/RunCMakeTest.cmake
new file mode 100644
index 0000000..42ec47e
--- /dev/null
+++ b/Tests/RunCMake/target_link_libraries-ALIAS/RunCMakeTest.cmake
@@ -0,0 +1,25 @@
+include(RunCMake)
+
+macro(run_cmake_target test subtest target)
+  set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/${test}-build)
+  set(RunCMake_TEST_NO_CLEAN 1)
+  run_cmake_command(${test}-${subtest} ${CMAKE_COMMAND} --build . --target ${target} ${ARGN})
+
+  unset(RunCMake_TEST_BINARY_DIR)
+  unset(RunCMake_TEST_NO_CLEAN)
+endmacro()
+
+set(RunCMake_TEST_OUTPUT_MERGE TRUE)
+if (NOT RunCMake_GENERATOR_IS_MULTI_CONFIG)
+  set(RunCMake_TEST_OPTIONS -DCMAKE_BUILD_TYPE=Release)
+endif()
+run_cmake(AliasTargets)
+run_cmake_target(AliasTargets func func --config Release)
+run_cmake_target(AliasTargets lib-local lib-local --config Release)
+run_cmake_target(AliasTargets main-local main-local --config Release)
+run_cmake_target(AliasTargets lib-global lib-global --config Release)
+run_cmake_target(AliasTargets main-global main-global --config Release)
+run_cmake_target(AliasTargets lib-sub lib-sub --config Release)
+run_cmake_target(AliasTargets main-sub main-sub --config Release)
+unset(RunCMake_TEST_OPTIONS)
+unset(RunCMake_TEST_OUTPUT_MERGE)
diff --git a/Tests/RunCMake/target_link_libraries-ALIAS/func.c b/Tests/RunCMake/target_link_libraries-ALIAS/func.c
new file mode 100644
index 0000000..415a9bf
--- /dev/null
+++ b/Tests/RunCMake/target_link_libraries-ALIAS/func.c
@@ -0,0 +1,7 @@
+
+#if defined(_WIN32)
+__declspec(dllexport)
+#endif
+  void func_c()
+{
+}
diff --git a/Tests/RunCMake/target_link_libraries-ALIAS/lib.c b/Tests/RunCMake/target_link_libraries-ALIAS/lib.c
new file mode 100644
index 0000000..b2d1b66
--- /dev/null
+++ b/Tests/RunCMake/target_link_libraries-ALIAS/lib.c
@@ -0,0 +1,10 @@
+
+#if defined(_WIN32)
+__declspec(dllimport)
+#endif
+  void func_c();
+
+void lib()
+{
+  func_c();
+}
diff --git a/Tests/RunCMake/target_link_libraries-ALIAS/main.c b/Tests/RunCMake/target_link_libraries-ALIAS/main.c
new file mode 100644
index 0000000..a908dea
--- /dev/null
+++ b/Tests/RunCMake/target_link_libraries-ALIAS/main.c
@@ -0,0 +1,12 @@
+
+#if defined(_WIN32)
+__declspec(dllimport)
+#endif
+  void func_c();
+
+int main()
+{
+  func_c();
+
+  return 0;
+}
diff --git a/Tests/RunCMake/target_link_libraries-ALIAS/sub_dir/CMakeLists.txt b/Tests/RunCMake/target_link_libraries-ALIAS/sub_dir/CMakeLists.txt
new file mode 100644
index 0000000..326e964
--- /dev/null
+++ b/Tests/RunCMake/target_link_libraries-ALIAS/sub_dir/CMakeLists.txt
@@ -0,0 +1,7 @@
+
+
+add_library (lib-sub SHARED ../lib.c)
+target_link_libraries (lib-sub PRIVATE alias::local)
+
+add_executable (main-sub ../main.c)
+target_link_libraries (main-sub PRIVATE alias::local)
diff --git a/Tests/RunCMake/target_link_libraries-LINK_LANGUAGE/CMakeLists.txt b/Tests/RunCMake/target_link_libraries-LINK_LANGUAGE/CMakeLists.txt
new file mode 100644
index 0000000..9cf020f
--- /dev/null
+++ b/Tests/RunCMake/target_link_libraries-LINK_LANGUAGE/CMakeLists.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 3.1)
+project(${RunCMake_TEST} NONE)
+include(${RunCMake_TEST}.cmake NO_POLICY_SCOPE)
diff --git a/Tests/RunCMake/target_link_libraries-LINK_LANGUAGE/RunCMakeTest.cmake b/Tests/RunCMake/target_link_libraries-LINK_LANGUAGE/RunCMakeTest.cmake
new file mode 100644
index 0000000..0f0e5d8
--- /dev/null
+++ b/Tests/RunCMake/target_link_libraries-LINK_LANGUAGE/RunCMakeTest.cmake
@@ -0,0 +1,41 @@
+include(RunCMake)
+
+macro(run_cmake_target test subtest target)
+  set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/${test}-build)
+  set(RunCMake_TEST_NO_CLEAN 1)
+  run_cmake_command(${test}-${subtest} ${CMAKE_COMMAND} --build . --target ${target} ${ARGN})
+
+  unset(RunCMake_TEST_BINARY_DIR)
+  unset(RunCMake_TEST_NO_CLEAN)
+endmacro()
+
+run_cmake(bad-usage)
+
+if (RunCMake_GENERATOR MATCHES "Makefiles|Ninja|Visual Studio|Xcode|Watcom WMake")
+
+  run_cmake(bad-mix-lang)
+
+  set(RunCMake_TEST_OUTPUT_MERGE TRUE)
+  if (NOT RunCMake_GENERATOR_IS_MULTI_CONFIG)
+    set(RunCMake_TEST_OPTIONS -DCMAKE_BUILD_TYPE=Release)
+  endif()
+
+  run_cmake(genex)
+
+  run_cmake_target(genex lib LinkLibraries_lib --config Release)
+  run_cmake_target(genex lib2 LinkLibraries_lib2 --config Release)
+  run_cmake_target(genex lib3 LinkLibraries_lib3 --config Release)
+  run_cmake_target(genex exe LinkLibraries_exe --config Release)
+  run_cmake_target(genex C_import LinkLibraries_C_import --config Release)
+  run_cmake_target(genex CXX_import LinkLibraries_CXX_import --config Release)
+  run_cmake_target(genex C_interface LinkLibraries_C_interface --config Release)
+  run_cmake_target(genex CXX_interface LinkLibraries_CXX_interface --config Release)
+  run_cmake_target(genex C_interface2 LinkLibraries_C_interface2 --config Release)
+  run_cmake_target(genex CXX_interface2 LinkLibraries_CXX_interface2 --config Release)
+  run_cmake_target(genex C_static LinkLibraries_C_static --config Release)
+  run_cmake_target(genex CXX_static LinkLibraries_CXX_static --config Release)
+
+  unset(RunCMake_TEST_OPTIONS)
+  unset(RunCMake_TEST_OUTPUT_MERGE)
+
+endif()
diff --git a/Tests/RunCMake/interface_library/invalid_name-result.txt b/Tests/RunCMake/target_link_libraries-LINK_LANGUAGE/bad-mix-lang-result.txt
similarity index 100%
copy from Tests/RunCMake/interface_library/invalid_name-result.txt
copy to Tests/RunCMake/target_link_libraries-LINK_LANGUAGE/bad-mix-lang-result.txt
diff --git a/Tests/RunCMake/target_link_libraries-LINK_LANGUAGE/bad-mix-lang-stderr.txt b/Tests/RunCMake/target_link_libraries-LINK_LANGUAGE/bad-mix-lang-stderr.txt
new file mode 100644
index 0000000..2ecdc0c
--- /dev/null
+++ b/Tests/RunCMake/target_link_libraries-LINK_LANGUAGE/bad-mix-lang-stderr.txt
@@ -0,0 +1,2 @@
+CMake Error: Evaluation of \$<LINK_LANGUAGE:...> or \$<LINK_LAND_AND_ID:...> changes
+the linker language for target "LinkLibraries_bad_mix_languages" \(from 'C' to 'CXX'\) which is invalid.
diff --git a/Tests/RunCMake/target_link_libraries-LINK_LANGUAGE/bad-mix-lang.cmake b/Tests/RunCMake/target_link_libraries-LINK_LANGUAGE/bad-mix-lang.cmake
new file mode 100644
index 0000000..e8efa75
--- /dev/null
+++ b/Tests/RunCMake/target_link_libraries-LINK_LANGUAGE/bad-mix-lang.cmake
@@ -0,0 +1,8 @@
+
+enable_language(C)
+enable_language(CXX)
+
+add_library(static_CXX STATIC func.cxx)
+
+add_executable(LinkLibraries_bad_mix_languages main.c)
+target_link_libraries (LinkLibraries_bad_mix_languages PRIVATE $<$<LINK_LANGUAGE:C>:static_CXX>)
diff --git a/Tests/RunCMake/interface_library/whitelist-result.txt b/Tests/RunCMake/target_link_libraries-LINK_LANGUAGE/bad-usage-result.txt
similarity index 100%
copy from Tests/RunCMake/interface_library/whitelist-result.txt
copy to Tests/RunCMake/target_link_libraries-LINK_LANGUAGE/bad-usage-result.txt
diff --git a/Tests/RunCMake/target_link_libraries-LINK_LANGUAGE/bad-usage-stderr.txt b/Tests/RunCMake/target_link_libraries-LINK_LANGUAGE/bad-usage-stderr.txt
new file mode 100644
index 0000000..d61f789
--- /dev/null
+++ b/Tests/RunCMake/target_link_libraries-LINK_LANGUAGE/bad-usage-stderr.txt
@@ -0,0 +1,8 @@
+CMake Error at bad-usage.cmake:4 \(target_link_libraries\):
+  Error evaluating generator expression:
+
+    \$<LINK_LANGUAGE>
+
+  \$<LINK_LANGUAGE> is not supported in link libraries expression.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/target_link_libraries-LINK_LANGUAGE/bad-usage.cmake b/Tests/RunCMake/target_link_libraries-LINK_LANGUAGE/bad-usage.cmake
new file mode 100644
index 0000000..81cfb0c
--- /dev/null
+++ b/Tests/RunCMake/target_link_libraries-LINK_LANGUAGE/bad-usage.cmake
@@ -0,0 +1,4 @@
+enable_language(C)
+
+add_library(simple SHARED empty.c)
+target_link_libraries(simple PRIVATE lib$<LINK_LANGUAGE>)
diff --git a/Tests/RunCMake/target_link_libraries-LINK_LANGUAGE/empty.c b/Tests/RunCMake/target_link_libraries-LINK_LANGUAGE/empty.c
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/Tests/RunCMake/target_link_libraries-LINK_LANGUAGE/empty.c
diff --git a/Tests/RunCMake/target_link_libraries-LINK_LANGUAGE/func.c b/Tests/RunCMake/target_link_libraries-LINK_LANGUAGE/func.c
new file mode 100644
index 0000000..415a9bf
--- /dev/null
+++ b/Tests/RunCMake/target_link_libraries-LINK_LANGUAGE/func.c
@@ -0,0 +1,7 @@
+
+#if defined(_WIN32)
+__declspec(dllexport)
+#endif
+  void func_c()
+{
+}
diff --git a/Tests/RunCMake/target_link_libraries-LINK_LANGUAGE/func.cxx b/Tests/RunCMake/target_link_libraries-LINK_LANGUAGE/func.cxx
new file mode 100644
index 0000000..a12caca
--- /dev/null
+++ b/Tests/RunCMake/target_link_libraries-LINK_LANGUAGE/func.cxx
@@ -0,0 +1,7 @@
+
+#if defined(_WIN32)
+__declspec(dllexport)
+#endif
+  void func_cxx()
+{
+}
diff --git a/Tests/RunCMake/target_link_libraries-LINK_LANGUAGE/genex.cmake b/Tests/RunCMake/target_link_libraries-LINK_LANGUAGE/genex.cmake
new file mode 100644
index 0000000..f3fe955
--- /dev/null
+++ b/Tests/RunCMake/target_link_libraries-LINK_LANGUAGE/genex.cmake
@@ -0,0 +1,72 @@
+
+cmake_minimum_required(VERSION 3.16...3.17)
+
+enable_language(C)
+enable_language(CXX)
+
+add_library(shared_C SHARED func.c)
+add_library(shared_CXX SHARED func.cxx)
+
+
+add_library(static1_C STATIC empty.c)
+target_link_libraries (static1_C INTERFACE $<$<LINK_LANGUAGE:C>:shared_C>)
+
+add_library(static2_C STATIC empty.c)
+target_link_libraries (static2_C PRIVATE $<$<LINK_LANGUAGE:C>:shared_C>)
+
+
+set (binary_dir "${CMAKE_BINARY_DIR}")
+get_property (is_multi_config GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
+if (is_multi_config)
+  string (APPEND binary_dir "/Release")
+endif()
+add_library(import STATIC IMPORTED)
+set_property(TARGET import PROPERTY IMPORTED_LOCATION "${binary_dir}/${CMAKE_STATIC_LIBRARY_PREFIX}static1_C${CMAKE_STATIC_LIBRARY_SUFFIX}")
+target_link_libraries (import INTERFACE $<$<LINK_LANGUAGE:C>:shared_C>)
+target_link_libraries (import INTERFACE $<$<LINK_LANGUAGE:CXX>:shared_CXX>)
+
+
+add_library(interface INTERFACE)
+target_link_libraries (interface INTERFACE $<$<LINK_LANGUAGE:C>:shared_C>
+                                           $<$<LINK_LANGUAGE:CXX>:shared_CXX>)
+
+
+add_library(interface2 INTERFACE)
+target_link_libraries (interface2 INTERFACE import)
+
+
+add_library(static3 STATIC empty.c)
+target_link_libraries (static3 PRIVATE interface)
+
+
+add_library(LinkLibraries_lib SHARED lib.c)
+target_link_libraries (LinkLibraries_lib PRIVATE $<$<LINK_LANGUAGE:C>:shared_C>)
+
+add_library(LinkLibraries_lib2 SHARED lib.c)
+target_link_libraries (LinkLibraries_lib2 PRIVATE $<$<LINK_LANGUAGE:C>:static1_C>)
+
+add_library(LinkLibraries_lib3 SHARED lib.c)
+target_link_libraries (LinkLibraries_lib3 PRIVATE $<$<LINK_LANGUAGE:C>:static2_C>)
+
+add_executable(LinkLibraries_exe main.c)
+target_link_libraries (LinkLibraries_exe PRIVATE $<$<LINK_LANGUAGE:C>:shared_C>)
+
+add_executable(LinkLibraries_C_import main.c)
+target_link_libraries (LinkLibraries_C_import PRIVATE import)
+add_executable(LinkLibraries_CXX_import main.cxx)
+target_link_libraries (LinkLibraries_CXX_import PRIVATE import)
+
+add_executable(LinkLibraries_C_interface main.c)
+target_link_libraries (LinkLibraries_C_interface PRIVATE interface)
+add_executable(LinkLibraries_CXX_interface main.cxx)
+target_link_libraries (LinkLibraries_CXX_interface PRIVATE interface)
+
+add_executable(LinkLibraries_C_interface2 main.c)
+target_link_libraries (LinkLibraries_C_interface2 PRIVATE interface2)
+add_executable(LinkLibraries_CXX_interface2 main.cxx)
+target_link_libraries (LinkLibraries_CXX_interface2 PRIVATE interface2)
+
+add_executable(LinkLibraries_C_static main.c)
+target_link_libraries (LinkLibraries_C_static PRIVATE static3)
+add_executable(LinkLibraries_CXX_static main.cxx)
+target_link_libraries (LinkLibraries_CXX_static PRIVATE static3)
diff --git a/Tests/RunCMake/target_link_libraries-LINK_LANGUAGE/lib.c b/Tests/RunCMake/target_link_libraries-LINK_LANGUAGE/lib.c
new file mode 100644
index 0000000..b2d1b66
--- /dev/null
+++ b/Tests/RunCMake/target_link_libraries-LINK_LANGUAGE/lib.c
@@ -0,0 +1,10 @@
+
+#if defined(_WIN32)
+__declspec(dllimport)
+#endif
+  void func_c();
+
+void lib()
+{
+  func_c();
+}
diff --git a/Tests/RunCMake/target_link_libraries-LINK_LANGUAGE/main.c b/Tests/RunCMake/target_link_libraries-LINK_LANGUAGE/main.c
new file mode 100644
index 0000000..a908dea
--- /dev/null
+++ b/Tests/RunCMake/target_link_libraries-LINK_LANGUAGE/main.c
@@ -0,0 +1,12 @@
+
+#if defined(_WIN32)
+__declspec(dllimport)
+#endif
+  void func_c();
+
+int main()
+{
+  func_c();
+
+  return 0;
+}
diff --git a/Tests/RunCMake/target_link_libraries-LINK_LANGUAGE/main.cxx b/Tests/RunCMake/target_link_libraries-LINK_LANGUAGE/main.cxx
new file mode 100644
index 0000000..ffaa3b4
--- /dev/null
+++ b/Tests/RunCMake/target_link_libraries-LINK_LANGUAGE/main.cxx
@@ -0,0 +1,12 @@
+
+#if defined(_WIN32)
+__declspec(dllimport)
+#endif
+  void func_cxx();
+
+int main()
+{
+  func_cxx();
+
+  return 0;
+}
diff --git a/Tests/RunCMake/target_link_libraries-LINK_LANG_AND_ID/CMakeLists.txt b/Tests/RunCMake/target_link_libraries-LINK_LANG_AND_ID/CMakeLists.txt
new file mode 100644
index 0000000..9cf020f
--- /dev/null
+++ b/Tests/RunCMake/target_link_libraries-LINK_LANG_AND_ID/CMakeLists.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 3.1)
+project(${RunCMake_TEST} NONE)
+include(${RunCMake_TEST}.cmake NO_POLICY_SCOPE)
diff --git a/Tests/RunCMake/target_link_libraries-LINK_LANG_AND_ID/RunCMakeTest.cmake b/Tests/RunCMake/target_link_libraries-LINK_LANG_AND_ID/RunCMakeTest.cmake
new file mode 100644
index 0000000..3b16f9e
--- /dev/null
+++ b/Tests/RunCMake/target_link_libraries-LINK_LANG_AND_ID/RunCMakeTest.cmake
@@ -0,0 +1,38 @@
+include(RunCMake)
+
+macro(run_cmake_target test subtest target)
+  set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/${test}-build)
+  set(RunCMake_TEST_NO_CLEAN 1)
+  run_cmake_command(${test}-${subtest} ${CMAKE_COMMAND} --build . --target ${target} ${ARGN})
+
+  unset(RunCMake_TEST_BINARY_DIR)
+  unset(RunCMake_TEST_NO_CLEAN)
+endmacro()
+
+if (RunCMake_GENERATOR MATCHES "Makefiles|Ninja|Visual Studio|Xcode|Watcom WMake")
+
+  run_cmake(bad-mix-lang)
+
+  set(RunCMake_TEST_OUTPUT_MERGE TRUE)
+  if (NOT RunCMake_GENERATOR_IS_MULTI_CONFIG)
+    set(RunCMake_TEST_OPTIONS -DCMAKE_BUILD_TYPE=Release)
+  endif()
+
+  run_cmake(genex)
+
+  run_cmake_target(genex lib LinkLibraries_lib --config Release)
+  run_cmake_target(genex lib2 LinkLibraries_lib2 --config Release)
+  run_cmake_target(genex lib3 LinkLibraries_lib3 --config Release)
+  run_cmake_target(genex exe LinkLibraries_exe --config Release)
+  run_cmake_target(genex C_import LinkLibraries_C_import --config Release)
+  run_cmake_target(genex CXX_import LinkLibraries_CXX_import --config Release)
+  run_cmake_target(genex C_interface LinkLibraries_C_interface --config Release)
+  run_cmake_target(genex CXX_interface LinkLibraries_CXX_interface --config Release)
+  run_cmake_target(genex C_interface2 LinkLibraries_C_interface2 --config Release)
+  run_cmake_target(genex CXX_interface2 LinkLibraries_CXX_interface2 --config Release)
+  run_cmake_target(genex CXX_static LinkLibraries_CXX_static --config Release)
+
+  unset(RunCMake_TEST_OPTIONS)
+  unset(RunCMake_TEST_OUTPUT_MERGE)
+
+endif()
diff --git a/Tests/RunCMake/interface_library/invalid_name-result.txt b/Tests/RunCMake/target_link_libraries-LINK_LANG_AND_ID/bad-mix-lang-result.txt
similarity index 100%
copy from Tests/RunCMake/interface_library/invalid_name-result.txt
copy to Tests/RunCMake/target_link_libraries-LINK_LANG_AND_ID/bad-mix-lang-result.txt
diff --git a/Tests/RunCMake/target_link_libraries-LINK_LANG_AND_ID/bad-mix-lang-stderr.txt b/Tests/RunCMake/target_link_libraries-LINK_LANG_AND_ID/bad-mix-lang-stderr.txt
new file mode 100644
index 0000000..2ecdc0c
--- /dev/null
+++ b/Tests/RunCMake/target_link_libraries-LINK_LANG_AND_ID/bad-mix-lang-stderr.txt
@@ -0,0 +1,2 @@
+CMake Error: Evaluation of \$<LINK_LANGUAGE:...> or \$<LINK_LAND_AND_ID:...> changes
+the linker language for target "LinkLibraries_bad_mix_languages" \(from 'C' to 'CXX'\) which is invalid.
diff --git a/Tests/RunCMake/target_link_libraries-LINK_LANG_AND_ID/bad-mix-lang.cmake b/Tests/RunCMake/target_link_libraries-LINK_LANG_AND_ID/bad-mix-lang.cmake
new file mode 100644
index 0000000..f80010a
--- /dev/null
+++ b/Tests/RunCMake/target_link_libraries-LINK_LANG_AND_ID/bad-mix-lang.cmake
@@ -0,0 +1,8 @@
+
+enable_language(C)
+enable_language(CXX)
+
+add_library(static_CXX STATIC func.cxx)
+
+add_executable(LinkLibraries_bad_mix_languages main.c)
+target_link_libraries (LinkLibraries_bad_mix_languages PRIVATE $<$<LINK_LANG_AND_ID:C,${CMAKE_C_COMPILER_ID}>:static_CXX>)
diff --git a/Tests/RunCMake/target_link_libraries-LINK_LANG_AND_ID/basic-result.txt b/Tests/RunCMake/target_link_libraries-LINK_LANG_AND_ID/basic-result.txt
new file mode 100644
index 0000000..8d98f9d
--- /dev/null
+++ b/Tests/RunCMake/target_link_libraries-LINK_LANG_AND_ID/basic-result.txt
@@ -0,0 +1 @@
+.*
diff --git a/Tests/RunCMake/target_link_libraries-LINK_LANG_AND_ID/empty.c b/Tests/RunCMake/target_link_libraries-LINK_LANG_AND_ID/empty.c
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/Tests/RunCMake/target_link_libraries-LINK_LANG_AND_ID/empty.c
diff --git a/Tests/RunCMake/target_link_libraries-LINK_LANG_AND_ID/exe_c-result.txt b/Tests/RunCMake/target_link_libraries-LINK_LANG_AND_ID/exe_c-result.txt
new file mode 100644
index 0000000..8d98f9d
--- /dev/null
+++ b/Tests/RunCMake/target_link_libraries-LINK_LANG_AND_ID/exe_c-result.txt
@@ -0,0 +1 @@
+.*
diff --git a/Tests/RunCMake/target_link_libraries-LINK_LANG_AND_ID/exe_cxx-result.txt b/Tests/RunCMake/target_link_libraries-LINK_LANG_AND_ID/exe_cxx-result.txt
new file mode 100644
index 0000000..8d98f9d
--- /dev/null
+++ b/Tests/RunCMake/target_link_libraries-LINK_LANG_AND_ID/exe_cxx-result.txt
@@ -0,0 +1 @@
+.*
diff --git a/Tests/RunCMake/target_link_libraries-LINK_LANG_AND_ID/func.c b/Tests/RunCMake/target_link_libraries-LINK_LANG_AND_ID/func.c
new file mode 100644
index 0000000..415a9bf
--- /dev/null
+++ b/Tests/RunCMake/target_link_libraries-LINK_LANG_AND_ID/func.c
@@ -0,0 +1,7 @@
+
+#if defined(_WIN32)
+__declspec(dllexport)
+#endif
+  void func_c()
+{
+}
diff --git a/Tests/RunCMake/target_link_libraries-LINK_LANG_AND_ID/func.cxx b/Tests/RunCMake/target_link_libraries-LINK_LANG_AND_ID/func.cxx
new file mode 100644
index 0000000..a12caca
--- /dev/null
+++ b/Tests/RunCMake/target_link_libraries-LINK_LANG_AND_ID/func.cxx
@@ -0,0 +1,7 @@
+
+#if defined(_WIN32)
+__declspec(dllexport)
+#endif
+  void func_cxx()
+{
+}
diff --git a/Tests/RunCMake/target_link_libraries-LINK_LANG_AND_ID/genex.cmake b/Tests/RunCMake/target_link_libraries-LINK_LANG_AND_ID/genex.cmake
new file mode 100644
index 0000000..9feccd0
--- /dev/null
+++ b/Tests/RunCMake/target_link_libraries-LINK_LANG_AND_ID/genex.cmake
@@ -0,0 +1,73 @@
+
+cmake_minimum_required(VERSION 3.16...3.17)
+
+enable_language(C)
+enable_language(CXX)
+
+
+add_library(shared_C SHARED func.c)
+add_library(shared_CXX SHARED func.cxx)
+
+
+add_library(static1_C STATIC empty.c)
+target_link_libraries (static1_C INTERFACE $<$<LINK_LANG_AND_ID:C,${CMAKE_C_COMPILER_ID}>:shared_C>)
+
+add_library(static2_C STATIC empty.c)
+target_link_libraries (static2_C PRIVATE $<$<LINK_LANG_AND_ID:C,${CMAKE_C_COMPILER_ID}>:shared_C>)
+
+
+set (binary_dir "${CMAKE_BINARY_DIR}")
+get_property (is_multi_config GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
+if (is_multi_config)
+  string (APPEND binary_dir "/Release")
+endif()
+add_library(import STATIC IMPORTED)
+set_property(TARGET import PROPERTY IMPORTED_LOCATION "${binary_dir}/${CMAKE_STATIC_LIBRARY_PREFIX}static1_C${CMAKE_STATIC_LIBRARY_SUFFIX}")
+target_link_libraries (import INTERFACE $<$<LINK_LANG_AND_ID:C,${CMAKE_C_COMPILER_ID}>:shared_C>)
+target_link_libraries (import INTERFACE $<$<LINK_LANG_AND_ID:CXX,${CMAKE_CXX_COMPILER_ID}>:shared_CXX>)
+
+
+add_library(interface INTERFACE)
+target_link_libraries (interface INTERFACE $<$<LINK_LANG_AND_ID:C,${CMAKE_C_COMPILER_ID}>:shared_C>
+                                           $<$<LINK_LANG_AND_ID:CXX,${CMAKE_CXX_COMPILER_ID}>:shared_CXX>)
+
+
+add_library(interface2 INTERFACE)
+target_link_libraries (interface2 INTERFACE import)
+
+
+add_library(static3 STATIC empty.c)
+target_link_libraries (static3 PRIVATE interface)
+
+
+add_library(LinkLibraries_lib SHARED lib.c)
+target_link_libraries (LinkLibraries_lib PRIVATE $<$<LINK_LANG_AND_ID:C,${CMAKE_C_COMPILER_ID}>:shared_C>)
+
+add_library(LinkLibraries_lib2 SHARED lib.c)
+target_link_libraries (LinkLibraries_lib2 PRIVATE $<$<LINK_LANG_AND_ID:C,${CMAKE_C_COMPILER_ID}>:static1_C>)
+
+add_library(LinkLibraries_lib3 SHARED lib.c)
+target_link_libraries (LinkLibraries_lib3 PRIVATE $<$<LINK_LANG_AND_ID:C,${CMAKE_C_COMPILER_ID}>:static2_C>)
+
+add_executable(LinkLibraries_exe main.c)
+target_link_libraries (LinkLibraries_exe PRIVATE $<$<LINK_LANG_AND_ID:C,${CMAKE_C_COMPILER_ID}>:shared_C>)
+
+add_executable(LinkLibraries_C_import main.c)
+target_link_libraries (LinkLibraries_C_import PRIVATE import)
+add_executable(LinkLibraries_CXX_import main.cxx)
+target_link_libraries (LinkLibraries_CXX_import PRIVATE import)
+
+add_executable(LinkLibraries_C_interface main.c)
+target_link_libraries (LinkLibraries_C_interface PRIVATE interface)
+add_executable(LinkLibraries_CXX_interface main.cxx)
+target_link_libraries (LinkLibraries_CXX_interface PRIVATE interface)
+
+add_executable(LinkLibraries_C_interface2 main.c)
+target_link_libraries (LinkLibraries_C_interface2 PRIVATE interface2)
+add_executable(LinkLibraries_CXX_interface2 main.cxx)
+target_link_libraries (LinkLibraries_CXX_interface2 PRIVATE interface2)
+
+add_executable(LinkLibraries_C_static main.c)
+target_link_libraries (LinkLibraries_C_static PRIVATE static3)
+add_executable(LinkLibraries_CXX_static main.cxx)
+target_link_libraries (LinkLibraries_CXX_static PRIVATE static3)
diff --git a/Tests/RunCMake/target_link_libraries-LINK_LANG_AND_ID/interface-result.txt b/Tests/RunCMake/target_link_libraries-LINK_LANG_AND_ID/interface-result.txt
new file mode 100644
index 0000000..8d98f9d
--- /dev/null
+++ b/Tests/RunCMake/target_link_libraries-LINK_LANG_AND_ID/interface-result.txt
@@ -0,0 +1 @@
+.*
diff --git a/Tests/RunCMake/target_link_libraries-LINK_LANG_AND_ID/lib.c b/Tests/RunCMake/target_link_libraries-LINK_LANG_AND_ID/lib.c
new file mode 100644
index 0000000..b2d1b66
--- /dev/null
+++ b/Tests/RunCMake/target_link_libraries-LINK_LANG_AND_ID/lib.c
@@ -0,0 +1,10 @@
+
+#if defined(_WIN32)
+__declspec(dllimport)
+#endif
+  void func_c();
+
+void lib()
+{
+  func_c();
+}
diff --git a/Tests/RunCMake/target_link_libraries-LINK_LANG_AND_ID/main.c b/Tests/RunCMake/target_link_libraries-LINK_LANG_AND_ID/main.c
new file mode 100644
index 0000000..a908dea
--- /dev/null
+++ b/Tests/RunCMake/target_link_libraries-LINK_LANG_AND_ID/main.c
@@ -0,0 +1,12 @@
+
+#if defined(_WIN32)
+__declspec(dllimport)
+#endif
+  void func_c();
+
+int main()
+{
+  func_c();
+
+  return 0;
+}
diff --git a/Tests/RunCMake/target_link_libraries-LINK_LANG_AND_ID/main.cxx b/Tests/RunCMake/target_link_libraries-LINK_LANG_AND_ID/main.cxx
new file mode 100644
index 0000000..ffaa3b4
--- /dev/null
+++ b/Tests/RunCMake/target_link_libraries-LINK_LANG_AND_ID/main.cxx
@@ -0,0 +1,12 @@
+
+#if defined(_WIN32)
+__declspec(dllimport)
+#endif
+  void func_cxx();
+
+int main()
+{
+  func_cxx();
+
+  return 0;
+}
diff --git a/Tests/RunCMake/interface_library/genex_link-result.txt b/Tests/RunCMake/target_link_libraries-LINK_LANG_AND_ID/no_language-result.txt
similarity index 100%
copy from Tests/RunCMake/interface_library/genex_link-result.txt
copy to Tests/RunCMake/target_link_libraries-LINK_LANG_AND_ID/no_language-result.txt
diff --git a/Tests/RunCMake/target_link_libraries/CMP0023-WARN-2.cmake b/Tests/RunCMake/target_link_libraries/CMP0023-WARN-2.cmake
index 2e9cba8..6c72546 100644
--- a/Tests/RunCMake/target_link_libraries/CMP0023-WARN-2.cmake
+++ b/Tests/RunCMake/target_link_libraries/CMP0023-WARN-2.cmake
@@ -1,4 +1,4 @@
-
+cmake_minimum_required(VERSION 2.8.11)
 project(CMP0022-WARN)
 
 add_library(foo SHARED empty_vs6_1.cpp)
diff --git a/Tests/RunCMake/target_link_libraries/CMP0023-WARN.cmake b/Tests/RunCMake/target_link_libraries/CMP0023-WARN.cmake
index fcc8da0..dfdf70b 100644
--- a/Tests/RunCMake/target_link_libraries/CMP0023-WARN.cmake
+++ b/Tests/RunCMake/target_link_libraries/CMP0023-WARN.cmake
@@ -1,4 +1,4 @@
-
+cmake_minimum_required(VERSION 2.8.11)
 project(CMP0022-WARN)
 
 add_library(foo SHARED empty_vs6_1.cpp)
diff --git a/Tests/RunCMake/Languages/LINK_LANGUAGE-genex-result.txt b/Tests/RunCMake/target_link_libraries/CMP0108-NEW-self-link-result.txt
similarity index 100%
copy from Tests/RunCMake/Languages/LINK_LANGUAGE-genex-result.txt
copy to Tests/RunCMake/target_link_libraries/CMP0108-NEW-self-link-result.txt
diff --git a/Tests/RunCMake/target_link_libraries/CMP0108-NEW-self-link-stderr.txt b/Tests/RunCMake/target_link_libraries/CMP0108-NEW-self-link-stderr.txt
new file mode 100644
index 0000000..7389eff
--- /dev/null
+++ b/Tests/RunCMake/target_link_libraries/CMP0108-NEW-self-link-stderr.txt
@@ -0,0 +1,5 @@
+CMake Error at CMP0108-self-link.cmake:[0-9]+ \(add_library\):
+  Target "foo" links to itself.
+Call Stack \(most recent call first\):
+  CMP0108-NEW-self-link.cmake:[0-9]+ \(include\)
+  CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/target_link_libraries/CMP0108-NEW-self-link.cmake b/Tests/RunCMake/target_link_libraries/CMP0108-NEW-self-link.cmake
new file mode 100644
index 0000000..4ee9621
--- /dev/null
+++ b/Tests/RunCMake/target_link_libraries/CMP0108-NEW-self-link.cmake
@@ -0,0 +1,4 @@
+
+cmake_policy (SET CMP0108 NEW)
+
+include (CMP0108-self-link.cmake)
diff --git a/Tests/RunCMake/target_link_libraries/CMP0108-OLD-self-link.cmake b/Tests/RunCMake/target_link_libraries/CMP0108-OLD-self-link.cmake
new file mode 100644
index 0000000..813104a
--- /dev/null
+++ b/Tests/RunCMake/target_link_libraries/CMP0108-OLD-self-link.cmake
@@ -0,0 +1,4 @@
+
+cmake_policy (SET CMP0108 OLD)
+
+include (CMP0108-self-link.cmake)
diff --git a/Tests/RunCMake/target_link_libraries/CMP0108-self-link.cmake b/Tests/RunCMake/target_link_libraries/CMP0108-self-link.cmake
new file mode 100644
index 0000000..07a3490
--- /dev/null
+++ b/Tests/RunCMake/target_link_libraries/CMP0108-self-link.cmake
@@ -0,0 +1,9 @@
+
+cmake_policy (SET CMP0038 NEW)
+cmake_policy (SET CMP0042 NEW)
+
+enable_language(C)
+
+add_library(foo SHARED lib.c)
+add_library(Bar::foo ALIAS foo)
+target_link_libraries(foo PRIVATE Bar::foo)
diff --git a/Tests/RunCMake/target_link_libraries/CMakeLists.txt b/Tests/RunCMake/target_link_libraries/CMakeLists.txt
index 8f85fbf..667561e 100644
--- a/Tests/RunCMake/target_link_libraries/CMakeLists.txt
+++ b/Tests/RunCMake/target_link_libraries/CMakeLists.txt
@@ -1,3 +1,3 @@
-cmake_minimum_required(VERSION 2.8.4)
+cmake_minimum_required(VERSION 2.8.12)
 project(${RunCMake_TEST} NONE)
 include(${RunCMake_TEST}.cmake NO_POLICY_SCOPE)
diff --git a/Tests/RunCMake/target_link_libraries/RunCMakeTest.cmake b/Tests/RunCMake/target_link_libraries/RunCMakeTest.cmake
index 8eed986..189592d 100644
--- a/Tests/RunCMake/target_link_libraries/RunCMakeTest.cmake
+++ b/Tests/RunCMake/target_link_libraries/RunCMakeTest.cmake
@@ -19,6 +19,8 @@
 run_cmake(CMP0079-link-OLD)
 run_cmake(CMP0079-link-NEW)
 run_cmake(CMP0079-link-NEW-bogus)
+run_cmake(CMP0108-OLD-self-link)
+run_cmake(CMP0108-NEW-self-link)
 run_cmake(ImportedTarget)
 run_cmake(ImportedTargetFailure)
 run_cmake(MixedSignature)
diff --git a/Tests/RunCMake/target_link_libraries/StaticPrivateDepNotExported.cmake b/Tests/RunCMake/target_link_libraries/StaticPrivateDepNotExported.cmake
index 9b97918..9f86b18 100644
--- a/Tests/RunCMake/target_link_libraries/StaticPrivateDepNotExported.cmake
+++ b/Tests/RunCMake/target_link_libraries/StaticPrivateDepNotExported.cmake
@@ -1,4 +1,3 @@
-cmake_policy(SET CMP0022 NEW)
 enable_language(C)
 add_library(foo STATIC empty.c)
 add_library(not_exported STATIC empty.c)
diff --git a/Tests/RunCMake/target_link_libraries/StaticPrivateDepNotTarget.cmake b/Tests/RunCMake/target_link_libraries/StaticPrivateDepNotTarget.cmake
index 7122ae9..20ec438 100644
--- a/Tests/RunCMake/target_link_libraries/StaticPrivateDepNotTarget.cmake
+++ b/Tests/RunCMake/target_link_libraries/StaticPrivateDepNotTarget.cmake
@@ -1,4 +1,3 @@
-cmake_policy(SET CMP0022 NEW)
 enable_language(C)
 add_library(foo STATIC empty.c)
 target_link_libraries(foo PRIVATE not_a_target)
diff --git a/Tests/RunCMake/target_link_libraries/lib.c b/Tests/RunCMake/target_link_libraries/lib.c
new file mode 100644
index 0000000..b2d1b66
--- /dev/null
+++ b/Tests/RunCMake/target_link_libraries/lib.c
@@ -0,0 +1,10 @@
+
+#if defined(_WIN32)
+__declspec(dllimport)
+#endif
+  void func_c();
+
+void lib()
+{
+  func_c();
+}
diff --git a/Tests/RunCMake/target_link_options/LinkOptionsDevice.cu b/Tests/RunCMake/target_link_options/LinkOptionsDevice.cu
new file mode 100644
index 0000000..96504e1
--- /dev/null
+++ b/Tests/RunCMake/target_link_options/LinkOptionsDevice.cu
@@ -0,0 +1,14 @@
+#include <cuda.h>
+
+#ifdef _WIN32
+__declspec(dllexport)
+#endif
+  int simplelib()
+{
+  return 0;
+}
+
+int main(void)
+{
+  return simplelib();
+}
diff --git a/Tests/RunCMake/target_link_options/RunCMakeTest.cmake b/Tests/RunCMake/target_link_options/RunCMakeTest.cmake
index cdfdd7b..8ef13f9 100644
--- a/Tests/RunCMake/target_link_options/RunCMakeTest.cmake
+++ b/Tests/RunCMake/target_link_options/RunCMakeTest.cmake
@@ -13,8 +13,9 @@
 if (NOT CMAKE_C_COMPILER_ID STREQUAL "Intel")
   # Intel compiler does not reject bad flags or objects!
   set(RunCMake_TEST_OUTPUT_MERGE TRUE)
+  set(RunCMake_TEST_OPTIONS -DCMake_TEST_CUDA=${CMake_TEST_CUDA})
   if (NOT RunCMake_GENERATOR_IS_MULTI_CONFIG)
-    set(RunCMake_TEST_OPTIONS -DCMAKE_BUILD_TYPE=Release)
+    list(APPEND RunCMake_TEST_OPTIONS -DCMAKE_BUILD_TYPE=Release)
   endif()
 
   run_cmake(LINK_OPTIONS)
@@ -27,6 +28,39 @@
   run_cmake_target(LINK_OPTIONS mod LinkOptions_mod --config Release)
   run_cmake_target(LINK_OPTIONS exe LinkOptions_exe --config Release)
 
+
+  run_cmake(genex_LINK_LANGUAGE)
+
+  run_cmake_target(genex_LINK_LANGUAGE interface LinkOptions_shared_interface --config Release)
+  run_cmake_target(genex_LINK_LANGUAGE shared_c LinkOptions_shared_c --config Release)
+  run_cmake_target(genex_LINK_LANGUAGE LINKER_LANGUAGE LinkOptions_shared_cxx --config Release)
+  run_cmake_target(genex_LINK_LANGUAGE mod LinkOptions_mod --config Release)
+  run_cmake_target(genex_LINK_LANGUAGE exe LinkOptions_exe --config Release)
+
+  run_cmake(genex_LINK_LANG_AND_ID)
+
+  run_cmake_target(genex_LINK_LANG_AND_ID interface LinkOptions_shared_interface --config Release)
+  run_cmake_target(genex_LINK_LANG_AND_ID shared_c LinkOptions_shared_c --config Release)
+  run_cmake_target(genex_LINK_LANG_AND_ID LINKER_LANGUAGE LinkOptions_shared_cxx --config Release)
+  run_cmake_target(genex_LINK_LANG_AND_ID mod LinkOptions_mod --config Release)
+  run_cmake_target(genex_LINK_LANG_AND_ID exe LinkOptions_exe --config Release)
+
+  run_cmake(genex_DEVICE_LINK)
+
+  run_cmake_target(genex_DEVICE_LINK interface LinkOptions_shared_interface --config Release)
+  run_cmake_target(genex_DEVICE_LINK private LinkOptions_private --config Release)
+  if (CMake_TEST_CUDA)
+    # Separable compilation is only supported on NVCC.
+    if(NOT CMake_TEST_CUDA STREQUAL "Clang")
+      run_cmake_target(genex_DEVICE_LINK CMP0105_UNSET LinkOptions_CMP0105_UNSET --config Release)
+      run_cmake_target(genex_DEVICE_LINK CMP0105_OLD LinkOptions_CMP0105_OLD --config Release)
+      run_cmake_target(genex_DEVICE_LINK CMP0105_NEW LinkOptions_CMP0105_NEW --config Release)
+      run_cmake_target(genex_DEVICE_LINK device LinkOptions_device --config Release)
+    endif()
+
+    run_cmake_target(genex_DEVICE_LINK no_device LinkOptions_no_device --config Release)
+  endif()
+
   unset(RunCMake_TEST_OPTIONS)
   unset(RunCMake_TEST_OUTPUT_MERGE)
 endif()
diff --git a/Tests/RunCMake/target_link_options/genex_DEVICE_LINK-CMP0105_NEW-check.cmake b/Tests/RunCMake/target_link_options/genex_DEVICE_LINK-CMP0105_NEW-check.cmake
new file mode 100644
index 0000000..20c4fab
--- /dev/null
+++ b/Tests/RunCMake/target_link_options/genex_DEVICE_LINK-CMP0105_NEW-check.cmake
@@ -0,0 +1,4 @@
+
+if (NOT actual_stdout MATCHES "BADFLAG_DEVICE_LINK")
+  set (RunCMake_TEST_FAILED "Not found expected 'BADFLAG_DEVICE_LINK'.")
+endif()
diff --git a/Tests/RunCMake/target_link_options/genex_DEVICE_LINK-CMP0105_NEW-result.txt b/Tests/RunCMake/target_link_options/genex_DEVICE_LINK-CMP0105_NEW-result.txt
new file mode 100644
index 0000000..8d98f9d
--- /dev/null
+++ b/Tests/RunCMake/target_link_options/genex_DEVICE_LINK-CMP0105_NEW-result.txt
@@ -0,0 +1 @@
+.*
diff --git a/Tests/RunCMake/target_link_options/genex_DEVICE_LINK-device-check.cmake b/Tests/RunCMake/target_link_options/genex_DEVICE_LINK-device-check.cmake
new file mode 100644
index 0000000..23c3b46
--- /dev/null
+++ b/Tests/RunCMake/target_link_options/genex_DEVICE_LINK-device-check.cmake
@@ -0,0 +1,3 @@
+set (DEVICE_LINK TRUE)
+
+include ("${CMAKE_CURRENT_LIST_DIR}/genex_DEVICE_LINK-validation.cmake")
diff --git a/Tests/RunCMake/target_link_options/genex_DEVICE_LINK-device-result.txt b/Tests/RunCMake/target_link_options/genex_DEVICE_LINK-device-result.txt
new file mode 100644
index 0000000..8d98f9d
--- /dev/null
+++ b/Tests/RunCMake/target_link_options/genex_DEVICE_LINK-device-result.txt
@@ -0,0 +1 @@
+.*
diff --git a/Tests/RunCMake/target_link_options/genex_DEVICE_LINK-interface-check.cmake b/Tests/RunCMake/target_link_options/genex_DEVICE_LINK-interface-check.cmake
new file mode 100644
index 0000000..8431e22
--- /dev/null
+++ b/Tests/RunCMake/target_link_options/genex_DEVICE_LINK-interface-check.cmake
@@ -0,0 +1,3 @@
+set (DEVICE_LINK FALSE)
+
+include ("${CMAKE_CURRENT_LIST_DIR}/genex_DEVICE_LINK-validation.cmake")
diff --git a/Tests/RunCMake/target_link_options/genex_DEVICE_LINK-interface-result.txt b/Tests/RunCMake/target_link_options/genex_DEVICE_LINK-interface-result.txt
new file mode 100644
index 0000000..8d98f9d
--- /dev/null
+++ b/Tests/RunCMake/target_link_options/genex_DEVICE_LINK-interface-result.txt
@@ -0,0 +1 @@
+.*
diff --git a/Tests/RunCMake/target_link_options/genex_DEVICE_LINK-no_device-check.cmake b/Tests/RunCMake/target_link_options/genex_DEVICE_LINK-no_device-check.cmake
new file mode 100644
index 0000000..8431e22
--- /dev/null
+++ b/Tests/RunCMake/target_link_options/genex_DEVICE_LINK-no_device-check.cmake
@@ -0,0 +1,3 @@
+set (DEVICE_LINK FALSE)
+
+include ("${CMAKE_CURRENT_LIST_DIR}/genex_DEVICE_LINK-validation.cmake")
diff --git a/Tests/RunCMake/target_link_options/genex_DEVICE_LINK-no_device-result.txt b/Tests/RunCMake/target_link_options/genex_DEVICE_LINK-no_device-result.txt
new file mode 100644
index 0000000..8d98f9d
--- /dev/null
+++ b/Tests/RunCMake/target_link_options/genex_DEVICE_LINK-no_device-result.txt
@@ -0,0 +1 @@
+.*
diff --git a/Tests/RunCMake/target_link_options/genex_DEVICE_LINK-private-check.cmake b/Tests/RunCMake/target_link_options/genex_DEVICE_LINK-private-check.cmake
new file mode 100644
index 0000000..8431e22
--- /dev/null
+++ b/Tests/RunCMake/target_link_options/genex_DEVICE_LINK-private-check.cmake
@@ -0,0 +1,3 @@
+set (DEVICE_LINK FALSE)
+
+include ("${CMAKE_CURRENT_LIST_DIR}/genex_DEVICE_LINK-validation.cmake")
diff --git a/Tests/RunCMake/target_link_options/genex_DEVICE_LINK-private-result.txt b/Tests/RunCMake/target_link_options/genex_DEVICE_LINK-private-result.txt
new file mode 100644
index 0000000..8d98f9d
--- /dev/null
+++ b/Tests/RunCMake/target_link_options/genex_DEVICE_LINK-private-result.txt
@@ -0,0 +1 @@
+.*
diff --git a/Tests/RunCMake/target_link_options/genex_DEVICE_LINK-validation.cmake b/Tests/RunCMake/target_link_options/genex_DEVICE_LINK-validation.cmake
new file mode 100644
index 0000000..28f5d01
--- /dev/null
+++ b/Tests/RunCMake/target_link_options/genex_DEVICE_LINK-validation.cmake
@@ -0,0 +1,22 @@
+
+if (NOT DEFINED DEVICE_LINK)
+  set (DEVICE_LINK FALSE)
+endif()
+
+if (DEVICE_LINK)
+  set (VALID_ID DEVICE_LINK)
+  set (INVALID_ID NORMAL_LINK)
+else()
+  set (VALID_ID NORMAL_LINK)
+  set (INVALID_ID DEVICE_LINK)
+endif()
+
+if (NOT actual_stdout MATCHES "BADFLAG_${VALID_ID}")
+  set (RunCMake_TEST_FAILED "Not found expected 'BADFLAG_${VALID_ID}'.")
+endif()
+if (actual_stdout MATCHES "BADFLAG_${INVALID_ID}")
+  if (RunCMake_TEST_FAILED)
+    string (APPEND RunCMake_TEST_FAILED "\n")
+  endif()
+  string (APPEND RunCMake_TEST_FAILED "Found unexpected 'BADFLAG_${INVALID_ID}'.")
+endif()
diff --git a/Tests/RunCMake/target_link_options/genex_DEVICE_LINK.cmake b/Tests/RunCMake/target_link_options/genex_DEVICE_LINK.cmake
new file mode 100644
index 0000000..0126080
--- /dev/null
+++ b/Tests/RunCMake/target_link_options/genex_DEVICE_LINK.cmake
@@ -0,0 +1,51 @@
+
+enable_language(C)
+
+set (obj "${CMAKE_C_OUTPUT_EXTENSION}")
+if(BORLAND)
+  set(pre -)
+endif()
+
+add_library(LinkOptions_interface INTERFACE)
+target_link_options (LinkOptions_interface INTERFACE $<DEVICE_LINK:${pre}BADFLAG_DEVICE_LINK${obj}>
+                                                     $<HOST_LINK:${pre}BADFLAG_NORMAL_LINK${obj}>)
+
+add_library(LinkOptions_shared_interface SHARED LinkOptionsLib.c)
+target_link_libraries (LinkOptions_shared_interface PRIVATE LinkOptions_interface)
+
+
+add_library(LinkOptions_private SHARED LinkOptionsLib.c)
+target_link_options (LinkOptions_private PRIVATE $<DEVICE_LINK:${pre}BADFLAG_DEVICE_LINK${obj}>
+                                                 $<HOST_LINK:${pre}BADFLAG_NORMAL_LINK${obj}>)
+
+if (CMake_TEST_CUDA)
+  enable_language(CUDA)
+
+  # Separable compilation is only supported on NVCC.
+  if(NOT CMake_TEST_CUDA STREQUAL "Clang")
+    add_executable(LinkOptions_CMP0105_UNSET LinkOptionsDevice.cu)
+    set_property(TARGET LinkOptions_CMP0105_UNSET PROPERTY CUDA_SEPARABLE_COMPILATION ON)
+    target_link_options(LinkOptions_CMP0105_UNSET PRIVATE $<DEVICE_LINK:${pre}BADFLAG_DEVICE_LINK${obj}>)
+
+    cmake_policy(SET CMP0105 OLD)
+
+    add_executable(LinkOptions_CMP0105_OLD LinkOptionsDevice.cu)
+    set_property(TARGET LinkOptions_CMP0105_OLD PROPERTY CUDA_SEPARABLE_COMPILATION ON)
+    target_link_options(LinkOptions_CMP0105_OLD PRIVATE $<DEVICE_LINK:${pre}BADFLAG_DEVICE_LINK${obj}>)
+
+    cmake_policy(SET CMP0105 NEW)
+
+    add_executable(LinkOptions_CMP0105_NEW LinkOptionsDevice.cu)
+    set_property(TARGET LinkOptions_CMP0105_NEW PROPERTY CUDA_SEPARABLE_COMPILATION ON)
+    target_link_options(LinkOptions_CMP0105_NEW PRIVATE $<DEVICE_LINK:${pre}BADFLAG_DEVICE_LINK${obj}>)
+
+    add_executable(LinkOptions_device LinkOptionsDevice.cu)
+    set_property(TARGET LinkOptions_device PROPERTY CUDA_SEPARABLE_COMPILATION ON)
+    target_link_options(LinkOptions_device PRIVATE $<DEVICE_LINK:${pre}BADFLAG_DEVICE_LINK${obj}>
+                                                  $<HOST_LINK:${pre}BADFLAG_NORMAL_LINK${obj}>)
+  endif()
+
+  add_executable(LinkOptions_no_device LinkOptionsDevice.cu)
+  target_link_options(LinkOptions_no_device PRIVATE $<DEVICE_LINK:${pre}BADFLAG_DEVICE_LINK${obj}>
+                                                    $<HOST_LINK:${pre}BADFLAG_NORMAL_LINK${obj}>)
+endif()
diff --git a/Tests/RunCMake/target_link_options/genex_LINK_LANGUAGE-LINKER_LANGUAGE-check.cmake b/Tests/RunCMake/target_link_options/genex_LINK_LANGUAGE-LINKER_LANGUAGE-check.cmake
new file mode 100644
index 0000000..aa39810
--- /dev/null
+++ b/Tests/RunCMake/target_link_options/genex_LINK_LANGUAGE-LINKER_LANGUAGE-check.cmake
@@ -0,0 +1,5 @@
+
+set (VALID_LANG CXX)
+set (INVALID_LANG C)
+
+include ("${CMAKE_CURRENT_LIST_DIR}/genex_LINK_LANGUAGE-validation.cmake")
diff --git a/Tests/RunCMake/target_link_options/genex_LINK_LANGUAGE-LINKER_LANGUAGE-result.txt b/Tests/RunCMake/target_link_options/genex_LINK_LANGUAGE-LINKER_LANGUAGE-result.txt
new file mode 100644
index 0000000..8d98f9d
--- /dev/null
+++ b/Tests/RunCMake/target_link_options/genex_LINK_LANGUAGE-LINKER_LANGUAGE-result.txt
@@ -0,0 +1 @@
+.*
diff --git a/Tests/RunCMake/target_link_options/genex_LINK_LANGUAGE-exe-check.cmake b/Tests/RunCMake/target_link_options/genex_LINK_LANGUAGE-exe-check.cmake
new file mode 100644
index 0000000..71f641d
--- /dev/null
+++ b/Tests/RunCMake/target_link_options/genex_LINK_LANGUAGE-exe-check.cmake
@@ -0,0 +1,2 @@
+
+include ("${CMAKE_CURRENT_LIST_DIR}/genex_LINK_LANGUAGE-validation.cmake")
diff --git a/Tests/RunCMake/target_link_options/genex_LINK_LANGUAGE-exe-result.txt b/Tests/RunCMake/target_link_options/genex_LINK_LANGUAGE-exe-result.txt
new file mode 100644
index 0000000..8d98f9d
--- /dev/null
+++ b/Tests/RunCMake/target_link_options/genex_LINK_LANGUAGE-exe-result.txt
@@ -0,0 +1 @@
+.*
diff --git a/Tests/RunCMake/target_link_options/genex_LINK_LANGUAGE-interface-check.cmake b/Tests/RunCMake/target_link_options/genex_LINK_LANGUAGE-interface-check.cmake
new file mode 100644
index 0000000..ba0120c
--- /dev/null
+++ b/Tests/RunCMake/target_link_options/genex_LINK_LANGUAGE-interface-check.cmake
@@ -0,0 +1,5 @@
+
+set (VALID_LANG C)
+set (INVALID_LANG CXX)
+
+include ("${CMAKE_CURRENT_LIST_DIR}/genex_LINK_LANGUAGE-validation.cmake")
diff --git a/Tests/RunCMake/target_link_options/genex_LINK_LANGUAGE-interface-result.txt b/Tests/RunCMake/target_link_options/genex_LINK_LANGUAGE-interface-result.txt
new file mode 100644
index 0000000..8d98f9d
--- /dev/null
+++ b/Tests/RunCMake/target_link_options/genex_LINK_LANGUAGE-interface-result.txt
@@ -0,0 +1 @@
+.*
diff --git a/Tests/RunCMake/target_link_options/genex_LINK_LANGUAGE-mod-check.cmake b/Tests/RunCMake/target_link_options/genex_LINK_LANGUAGE-mod-check.cmake
new file mode 100644
index 0000000..71f641d
--- /dev/null
+++ b/Tests/RunCMake/target_link_options/genex_LINK_LANGUAGE-mod-check.cmake
@@ -0,0 +1,2 @@
+
+include ("${CMAKE_CURRENT_LIST_DIR}/genex_LINK_LANGUAGE-validation.cmake")
diff --git a/Tests/RunCMake/target_link_options/genex_LINK_LANGUAGE-mod-result.txt b/Tests/RunCMake/target_link_options/genex_LINK_LANGUAGE-mod-result.txt
new file mode 100644
index 0000000..8d98f9d
--- /dev/null
+++ b/Tests/RunCMake/target_link_options/genex_LINK_LANGUAGE-mod-result.txt
@@ -0,0 +1 @@
+.*
diff --git a/Tests/RunCMake/target_link_options/genex_LINK_LANGUAGE-shared_c-check.cmake b/Tests/RunCMake/target_link_options/genex_LINK_LANGUAGE-shared_c-check.cmake
new file mode 100644
index 0000000..ba0120c
--- /dev/null
+++ b/Tests/RunCMake/target_link_options/genex_LINK_LANGUAGE-shared_c-check.cmake
@@ -0,0 +1,5 @@
+
+set (VALID_LANG C)
+set (INVALID_LANG CXX)
+
+include ("${CMAKE_CURRENT_LIST_DIR}/genex_LINK_LANGUAGE-validation.cmake")
diff --git a/Tests/RunCMake/target_link_options/genex_LINK_LANGUAGE-shared_c-result.txt b/Tests/RunCMake/target_link_options/genex_LINK_LANGUAGE-shared_c-result.txt
new file mode 100644
index 0000000..8d98f9d
--- /dev/null
+++ b/Tests/RunCMake/target_link_options/genex_LINK_LANGUAGE-shared_c-result.txt
@@ -0,0 +1 @@
+.*
diff --git a/Tests/RunCMake/target_link_options/genex_LINK_LANGUAGE-validation.cmake b/Tests/RunCMake/target_link_options/genex_LINK_LANGUAGE-validation.cmake
new file mode 100644
index 0000000..f0237ab
--- /dev/null
+++ b/Tests/RunCMake/target_link_options/genex_LINK_LANGUAGE-validation.cmake
@@ -0,0 +1,17 @@
+
+if (NOT DEFINED VALID_LANG)
+  set (VALID_LANG C)
+endif()
+if (NOT DEFINED INVALID_LANG)
+  set (INVALID_LANG CXX)
+endif()
+
+if (NOT actual_stdout MATCHES "BADFLAG_${VALID_LANG}_LANG")
+  set (RunCMake_TEST_FAILED "Not found expected 'BADFLAG_${VALID_LANG}_LANG'.")
+endif()
+if (actual_stdout MATCHES "BADFLAG_${INVALID_LANG}_LANG")
+  if (RunCMake_TEST_FAILED)
+    string (APPEND RunCMake_TEST_FAILED "\n")
+  endif()
+  string (APPEND RunCMake_TEST_FAILED "Found unexpected 'BADFLAG_${INVALID_LANG}_LANG'.")
+endif()
diff --git a/Tests/RunCMake/target_link_options/genex_LINK_LANGUAGE.cmake b/Tests/RunCMake/target_link_options/genex_LINK_LANGUAGE.cmake
new file mode 100644
index 0000000..61e6159
--- /dev/null
+++ b/Tests/RunCMake/target_link_options/genex_LINK_LANGUAGE.cmake
@@ -0,0 +1,32 @@
+
+enable_language(C)
+enable_language(CXX)
+
+set (obj "${CMAKE_C_OUTPUT_EXTENSION}")
+if(BORLAND)
+  set(pre -)
+endif()
+
+add_library(LinkOptions_interface INTERFACE)
+target_link_options (LinkOptions_interface INTERFACE $<$<LINK_LANGUAGE:C>:${pre}BADFLAG_$<LINK_LANGUAGE>_LANG${obj}>
+                                                     $<$<LINK_LANGUAGE:CXX>:${pre}BADFLAG_$<LINK_LANGUAGE>_LANG${obj}>)
+
+add_library(LinkOptions_shared_interface SHARED LinkOptionsLib.c)
+target_link_libraries (LinkOptions_shared_interface PRIVATE LinkOptions_interface)
+
+add_library(LinkOptions_shared_c SHARED LinkOptionsLib.c)
+target_link_options (LinkOptions_shared_c PRIVATE $<$<LINK_LANGUAGE:C>:${pre}BADFLAG_$<LINK_LANGUAGE>_LANG${obj}>
+                                                  $<$<LINK_LANGUAGE:CXX>:${pre}BADFLAG_$<LINK_LANGUAGE>_LANG${obj}>)
+
+add_library(LinkOptions_shared_cxx SHARED LinkOptionsLib.c)
+target_link_options (LinkOptions_shared_cxx PRIVATE $<$<LINK_LANGUAGE:C>:${pre}BADFLAG_$<LINK_LANGUAGE>_LANG${obj}>
+                                                    $<$<LINK_LANGUAGE:CXX>:${pre}BADFLAG_$<LINK_LANGUAGE>_LANG${obj}>)
+set_property (TARGET LinkOptions_shared_cxx PROPERTY LINKER_LANGUAGE CXX)
+
+add_library(LinkOptions_mod MODULE LinkOptionsLib.c)
+target_link_options (LinkOptions_mod PRIVATE $<$<LINK_LANGUAGE:C>:${pre}BADFLAG_$<LINK_LANGUAGE>_LANG${obj}>
+                                             $<$<LINK_LANGUAGE:CXX>:${pre}BADFLAG_$<LINK_LANGUAGE>_LANG${obj}>)
+
+add_executable(LinkOptions_exe LinkOptionsExe.c)
+target_link_options (LinkOptions_exe PRIVATE $<$<LINK_LANGUAGE:C>:${pre}BADFLAG_$<LINK_LANGUAGE>_LANG${obj}>
+                                             $<$<LINK_LANGUAGE:CXX>:${pre}BADFLAG_$<LINK_LANGUAGE>_LANG${obj}>)
diff --git a/Tests/RunCMake/target_link_options/genex_LINK_LANG_AND_ID-LINKER_LANGUAGE-check.cmake b/Tests/RunCMake/target_link_options/genex_LINK_LANG_AND_ID-LINKER_LANGUAGE-check.cmake
new file mode 100644
index 0000000..ed4f851
--- /dev/null
+++ b/Tests/RunCMake/target_link_options/genex_LINK_LANG_AND_ID-LINKER_LANGUAGE-check.cmake
@@ -0,0 +1,5 @@
+
+set (VALID_LANG CXX)
+set (INVALID_LANG C)
+
+include ("${CMAKE_CURRENT_LIST_DIR}/genex_LINK_LANG_AND_ID-validation.cmake")
diff --git a/Tests/RunCMake/target_link_options/genex_LINK_LANG_AND_ID-LINKER_LANGUAGE-result.txt b/Tests/RunCMake/target_link_options/genex_LINK_LANG_AND_ID-LINKER_LANGUAGE-result.txt
new file mode 100644
index 0000000..8d98f9d
--- /dev/null
+++ b/Tests/RunCMake/target_link_options/genex_LINK_LANG_AND_ID-LINKER_LANGUAGE-result.txt
@@ -0,0 +1 @@
+.*
diff --git a/Tests/RunCMake/target_link_options/genex_LINK_LANG_AND_ID-exe-check.cmake b/Tests/RunCMake/target_link_options/genex_LINK_LANG_AND_ID-exe-check.cmake
new file mode 100644
index 0000000..6bddee1
--- /dev/null
+++ b/Tests/RunCMake/target_link_options/genex_LINK_LANG_AND_ID-exe-check.cmake
@@ -0,0 +1,2 @@
+
+include ("${CMAKE_CURRENT_LIST_DIR}/genex_LINK_LANG_AND_ID-validation.cmake")
diff --git a/Tests/RunCMake/target_link_options/genex_LINK_LANG_AND_ID-exe-result.txt b/Tests/RunCMake/target_link_options/genex_LINK_LANG_AND_ID-exe-result.txt
new file mode 100644
index 0000000..8d98f9d
--- /dev/null
+++ b/Tests/RunCMake/target_link_options/genex_LINK_LANG_AND_ID-exe-result.txt
@@ -0,0 +1 @@
+.*
diff --git a/Tests/RunCMake/target_link_options/genex_LINK_LANG_AND_ID-interface-check.cmake b/Tests/RunCMake/target_link_options/genex_LINK_LANG_AND_ID-interface-check.cmake
new file mode 100644
index 0000000..cf498d9
--- /dev/null
+++ b/Tests/RunCMake/target_link_options/genex_LINK_LANG_AND_ID-interface-check.cmake
@@ -0,0 +1,5 @@
+
+set (VALID_LANG C)
+set (INVALID_LANG CXX)
+
+include ("${CMAKE_CURRENT_LIST_DIR}/genex_LINK_LANG_AND_ID-validation.cmake")
diff --git a/Tests/RunCMake/target_link_options/genex_LINK_LANG_AND_ID-interface-result.txt b/Tests/RunCMake/target_link_options/genex_LINK_LANG_AND_ID-interface-result.txt
new file mode 100644
index 0000000..8d98f9d
--- /dev/null
+++ b/Tests/RunCMake/target_link_options/genex_LINK_LANG_AND_ID-interface-result.txt
@@ -0,0 +1 @@
+.*
diff --git a/Tests/RunCMake/target_link_options/genex_LINK_LANG_AND_ID-mod-check.cmake b/Tests/RunCMake/target_link_options/genex_LINK_LANG_AND_ID-mod-check.cmake
new file mode 100644
index 0000000..6bddee1
--- /dev/null
+++ b/Tests/RunCMake/target_link_options/genex_LINK_LANG_AND_ID-mod-check.cmake
@@ -0,0 +1,2 @@
+
+include ("${CMAKE_CURRENT_LIST_DIR}/genex_LINK_LANG_AND_ID-validation.cmake")
diff --git a/Tests/RunCMake/target_link_options/genex_LINK_LANG_AND_ID-mod-result.txt b/Tests/RunCMake/target_link_options/genex_LINK_LANG_AND_ID-mod-result.txt
new file mode 100644
index 0000000..8d98f9d
--- /dev/null
+++ b/Tests/RunCMake/target_link_options/genex_LINK_LANG_AND_ID-mod-result.txt
@@ -0,0 +1 @@
+.*
diff --git a/Tests/RunCMake/target_link_options/genex_LINK_LANG_AND_ID-shared_c-check.cmake b/Tests/RunCMake/target_link_options/genex_LINK_LANG_AND_ID-shared_c-check.cmake
new file mode 100644
index 0000000..cf498d9
--- /dev/null
+++ b/Tests/RunCMake/target_link_options/genex_LINK_LANG_AND_ID-shared_c-check.cmake
@@ -0,0 +1,5 @@
+
+set (VALID_LANG C)
+set (INVALID_LANG CXX)
+
+include ("${CMAKE_CURRENT_LIST_DIR}/genex_LINK_LANG_AND_ID-validation.cmake")
diff --git a/Tests/RunCMake/target_link_options/genex_LINK_LANG_AND_ID-shared_c-result.txt b/Tests/RunCMake/target_link_options/genex_LINK_LANG_AND_ID-shared_c-result.txt
new file mode 100644
index 0000000..8d98f9d
--- /dev/null
+++ b/Tests/RunCMake/target_link_options/genex_LINK_LANG_AND_ID-shared_c-result.txt
@@ -0,0 +1 @@
+.*
diff --git a/Tests/RunCMake/target_link_options/genex_LINK_LANG_AND_ID-validation.cmake b/Tests/RunCMake/target_link_options/genex_LINK_LANG_AND_ID-validation.cmake
new file mode 100644
index 0000000..a5dc27f
--- /dev/null
+++ b/Tests/RunCMake/target_link_options/genex_LINK_LANG_AND_ID-validation.cmake
@@ -0,0 +1,23 @@
+
+if (NOT VALID_LANG)
+  set (VALID_LANG C)
+endif()
+if (NOT INVALID_LANG)
+  set (INVALID_LANG CXX)
+endif()
+
+if (NOT actual_stdout MATCHES "BADFLAG_${VALID_LANG}_LANG_ID")
+  set (RunCMake_TEST_FAILED "Not found expected 'BADFLAG_${VALID_LANG}_LANG_ID'.\n")
+endif()
+if (actual_stdout MATCHES "BADFLAG_${INVALID_LANG}_LANG_ID")
+  if (RunCMake_TEST_FAILED)
+    string (APPEND RunCMake_TEST_FAILED "\n")
+  endif()
+  string (APPEND RunCMake_TEST_FAILED "Found unexpected 'BADFLAG_${INVALID_LANG}_LANG_ID '.")
+endif()
+if (actual_stdout MATCHES "BADFLAG_(${VALID_LANG}|${INVALID_LANG})_BADID")
+  if (RunCMake_TEST_FAILED)
+    string (APPEND RunCMake_TEST_FAILED "\n")
+  endif()
+  string (APPEND RunCMake_TEST_FAILED "Found unexpected 'BADFLAG_(${VALID_LANG}|${INVALID_LANG})_BADID'.")
+endif()
diff --git a/Tests/RunCMake/target_link_options/genex_LINK_LANG_AND_ID.cmake b/Tests/RunCMake/target_link_options/genex_LINK_LANG_AND_ID.cmake
new file mode 100644
index 0000000..db0f500
--- /dev/null
+++ b/Tests/RunCMake/target_link_options/genex_LINK_LANG_AND_ID.cmake
@@ -0,0 +1,41 @@
+
+enable_language(C)
+enable_language(CXX)
+
+if(BORLAND)
+  set(pre -)
+endif()
+
+add_library(LinkOptions_interface INTERFACE)
+target_link_options (LinkOptions_interface INTERFACE $<$<LINK_LANG_AND_ID:C,${CMAKE_C_COMPILER_ID}>:${pre}BADFLAG_C_LANG_ID${CMAKE_C_OUTPUT_EXTENSION}>
+                                                     $<$<LINK_LANG_AND_ID:CXX,${CMAKE_CXX_COMPILER_ID}>:${pre}BADFLAG_CXX_LANG_ID${CMAKE_CXX_OUTPUT_EXTENSION}>
+                                                     $<$<LINK_LANG_AND_ID:C,BADID>:${pre}BADFLAG_C_BADID${CMAKE_C_OUTPUT_EXTENSION}>
+                                                     $<$<LINK_LANG_AND_ID:CXX,BADID>:${pre}BADFLAG_CXX_BADID${CMAKE_CXX_OUTPUT_EXTENSION}>)
+
+add_library(LinkOptions_shared_interface SHARED LinkOptionsLib.c)
+target_link_libraries (LinkOptions_shared_interface PRIVATE LinkOptions_interface)
+
+add_library(LinkOptions_shared_c SHARED LinkOptionsLib.c)
+target_link_options (LinkOptions_shared_c PRIVATE $<$<LINK_LANG_AND_ID:C,${CMAKE_C_COMPILER_ID}>:${pre}BADFLAG_C_LANG_ID${CMAKE_C_OUTPUT_EXTENSION}>
+                                                  $<$<LINK_LANG_AND_ID:CXX,${CMAKE_CXX_COMPILER_ID}>:${pre}BADFLAG_CXX_LANG_ID${CMAKE_CXX_OUTPUT_EXTENSION}>
+                                                  $<$<LINK_LANG_AND_ID:C,BADID>:${pre}BADFLAG_C_BADID${CMAKE_C_OUTPUT_EXTENSION}>
+                                                  $<$<LINK_LANG_AND_ID:CXX,BADID>:${pre}BADFLAG_CXX_BADID${CMAKE_CXX_OUTPUT_EXTENSION}>)
+
+add_library(LinkOptions_shared_cxx SHARED LinkOptionsLib.c)
+target_link_options (LinkOptions_shared_cxx PRIVATE $<$<LINK_LANG_AND_ID:C,${CMAKE_C_COMPILER_ID}>:${pre}BADFLAG_C_LANG_ID${CMAKE_C_OUTPUT_EXTENSION}>
+                                                    $<$<LINK_LANG_AND_ID:CXX,${CMAKE_CXX_COMPILER_ID}>:${pre}BADFLAG_CXX_LANG_ID${CMAKE_CXX_OUTPUT_EXTENSION}>
+                                                    $<$<LINK_LANG_AND_ID:C,BADID>:${pre}BADFLAG_C_BADID${CMAKE_C_OUTPUT_EXTENSION}>
+                                                    $<$<LINK_LANG_AND_ID:CXX,BADID>:${pre}BADFLAG_CXX_BADID${CMAKE_CXX_OUTPUT_EXTENSION}>)
+set_property (TARGET LinkOptions_shared_cxx PROPERTY LINKER_LANGUAGE CXX)
+
+add_library(LinkOptions_mod MODULE LinkOptionsLib.c)
+target_link_options (LinkOptions_mod PRIVATE $<$<LINK_LANG_AND_ID:C,${CMAKE_C_COMPILER_ID}>:${pre}BADFLAG_C_LANG_ID${CMAKE_C_OUTPUT_EXTENSION}>
+                                             $<$<LINK_LANG_AND_ID:CXX,${CMAKE_CXX_COMPILER_ID}>:${pre}BADFLAG_CXX_LANG_ID${CMAKE_CXX_OUTPUT_EXTENSION}>
+                                             $<$<LINK_LANG_AND_ID:C,BADID>:${pre}BADFLAG_C_BADID${CMAKE_C_OUTPUT_EXTENSION}>
+                                             $<$<LINK_LANG_AND_ID:CXX,BADID>:${pre}BADFLAG_CXX_BADID${CMAKE_CXX_OUTPUT_EXTENSION}>)
+
+add_executable(LinkOptions_exe LinkOptionsExe.c)
+target_link_options (LinkOptions_exe PRIVATE $<$<LINK_LANG_AND_ID:C,${CMAKE_C_COMPILER_ID}>:${pre}BADFLAG_C_LANG_ID${CMAKE_C_OUTPUT_EXTENSION}>
+                                             $<$<LINK_LANG_AND_ID:CXX,${CMAKE_CXX_COMPILER_ID}>:${pre}BADFLAG_CXX_LANG_ID${CMAKE_CXX_OUTPUT_EXTENSION}>
+                                             $<$<LINK_LANG_AND_ID:C,BADID>:${pre}BADFLAG_C_BADID${CMAKE_C_OUTPUT_EXTENSION}>
+                                             $<$<LINK_LANG_AND_ID:CXX,BADID>:${pre}BADFLAG_CXX_BADID${CMAKE_CXX_OUTPUT_EXTENSION}>)
diff --git a/Tests/RunCMake/try_compile/CMP0056.cmake b/Tests/RunCMake/try_compile/CMP0056.cmake
index e8d3d4a..2ab79d5 100644
--- a/Tests/RunCMake/try_compile/CMP0056.cmake
+++ b/Tests/RunCMake/try_compile/CMP0056.cmake
@@ -1,3 +1,4 @@
+cmake_minimum_required(VERSION 3.1)
 enable_language(C)
 set(obj "${CMAKE_C_OUTPUT_EXTENSION}")
 if(BORLAND)
diff --git a/Tests/RunCMake/try_compile/CMakeLists.txt b/Tests/RunCMake/try_compile/CMakeLists.txt
index 12cd3c7..74b3ff8 100644
--- a/Tests/RunCMake/try_compile/CMakeLists.txt
+++ b/Tests/RunCMake/try_compile/CMakeLists.txt
@@ -1,3 +1,3 @@
-cmake_minimum_required(VERSION 2.8.4)
+cmake_minimum_required(VERSION 3.3)
 project(${RunCMake_TEST} NONE)
 include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/try_compile/CudaStandard-stderr.txt b/Tests/RunCMake/try_compile/CudaStandard-stderr.txt
index 3c6bdf6..bcf95d5 100644
--- a/Tests/RunCMake/try_compile/CudaStandard-stderr.txt
+++ b/Tests/RunCMake/try_compile/CudaStandard-stderr.txt
@@ -1,5 +1,5 @@
 ^CMake Error at .*/Tests/RunCMake/try_compile/CudaStandard-build/CMakeFiles/CMakeTmp/CMakeLists.txt:[0-9]+ \(add_executable\):
-  CUDA_STANDARD is set to invalid value '3'
+  CUDA_STANDARD is set to invalid value '4'
 +
 CMake Error at CudaStandard.cmake:[0-9]+ \(try_compile\):
   Failed to generate test project build system.
diff --git a/Tests/RunCMake/try_compile/CudaStandard.cmake b/Tests/RunCMake/try_compile/CudaStandard.cmake
index 96da422..a230424 100644
--- a/Tests/RunCMake/try_compile/CudaStandard.cmake
+++ b/Tests/RunCMake/try_compile/CudaStandard.cmake
@@ -1,7 +1,7 @@
 enable_language(CUDA)
 try_compile(result ${CMAKE_CURRENT_BINARY_DIR}
   SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/src.cu
-  CUDA_STANDARD 3
+  CUDA_STANDARD 4
   OUTPUT_VARIABLE out
   )
 message("try_compile output:\n${out}")
diff --git a/Tests/RunCMake/try_compile/RunCMakeTest.cmake b/Tests/RunCMake/try_compile/RunCMakeTest.cmake
index bee9e5b..82c55cc 100644
--- a/Tests/RunCMake/try_compile/RunCMakeTest.cmake
+++ b/Tests/RunCMake/try_compile/RunCMakeTest.cmake
@@ -83,13 +83,17 @@
 
   message(STATUS "RerunCMake: first configuration...")
   run_cmake(RerunCMake)
-  run_cmake_command(RerunCMake-nowork${ninja} ${CMAKE_COMMAND} --build .)
+  if(NOT CMake_TEST_FILESYSTEM_1S)
+    run_cmake_command(RerunCMake-nowork${ninja} ${CMAKE_COMMAND} --build .)
+  endif()
 
   execute_process(COMMAND ${CMAKE_COMMAND} -E sleep 1) # handle 1s resolution
   message(STATUS "RerunCMake: modify try_compile input...")
   file(WRITE "${in_tc}" "does-not-compile\n")
   run_cmake_command(RerunCMake-rerun${ninja} ${CMAKE_COMMAND} --build .)
-  run_cmake_command(RerunCMake-nowork${ninja} ${CMAKE_COMMAND} --build .)
+  if(NOT CMake_TEST_FILESYSTEM_1S)
+    run_cmake_command(RerunCMake-nowork${ninja} ${CMAKE_COMMAND} --build .)
+  endif()
 
   unset(RunCMake_TEST_BINARY_DIR)
   unset(RunCMake_TEST_NO_CLEAN)
diff --git a/Tests/RunCMake/try_compile/proj/CMakeLists.txt b/Tests/RunCMake/try_compile/proj/CMakeLists.txt
index 78a87c0..652f5b6 100644
--- a/Tests/RunCMake/try_compile/proj/CMakeLists.txt
+++ b/Tests/RunCMake/try_compile/proj/CMakeLists.txt
@@ -1,2 +1,2 @@
-cmake_minimum_required(VERSION 2.8.10)
+cmake_minimum_required(VERSION 3.3)
 project(TestProject NONE)
diff --git a/Tests/RunCMake/try_run/CMakeLists.txt b/Tests/RunCMake/try_run/CMakeLists.txt
index e034780..e93f0b6 100644
--- a/Tests/RunCMake/try_run/CMakeLists.txt
+++ b/Tests/RunCMake/try_run/CMakeLists.txt
@@ -1,3 +1,3 @@
-cmake_minimum_required(VERSION 2.8.0)
+cmake_minimum_required(VERSION 3.3)
 project(${RunCMake_TEST} C)
 include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/variable_watch/CMakeLists.txt b/Tests/RunCMake/variable_watch/CMakeLists.txt
index 12cd3c7..74b3ff8 100644
--- a/Tests/RunCMake/variable_watch/CMakeLists.txt
+++ b/Tests/RunCMake/variable_watch/CMakeLists.txt
@@ -1,3 +1,3 @@
-cmake_minimum_required(VERSION 2.8.4)
+cmake_minimum_required(VERSION 3.3)
 project(${RunCMake_TEST} NONE)
 include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/while/CMakeLists.txt b/Tests/RunCMake/while/CMakeLists.txt
index 12cd3c7..74b3ff8 100644
--- a/Tests/RunCMake/while/CMakeLists.txt
+++ b/Tests/RunCMake/while/CMakeLists.txt
@@ -1,3 +1,3 @@
-cmake_minimum_required(VERSION 2.8.4)
+cmake_minimum_required(VERSION 3.3)
 project(${RunCMake_TEST} NONE)
 include(${RunCMake_TEST}.cmake)
diff --git a/Tests/SetLang/CMakeLists.txt b/Tests/SetLang/CMakeLists.txt
index f24e5cb..616421e 100644
--- a/Tests/SetLang/CMakeLists.txt
+++ b/Tests/SetLang/CMakeLists.txt
@@ -8,3 +8,17 @@
 set_source_files_properties(foo.c bar.c PROPERTIES LANGUAGE CXX)
 target_link_libraries(SetLang foo)
 set_target_properties(SetLang PROPERTIES LINKER_LANGUAGE CXX)
+
+# VS generators historically tolerated target-wide -TP flags added
+# by project code, so cover that case to preserve the behavior.
+if(CMAKE_GENERATOR MATCHES "^Visual Studio" AND "x${CMAKE_C_COMPILER_ID}" STREQUAL "xMSVC")
+  add_library(stay stay_c.c stay_cxx.cxx)
+  set_property(TARGET stay PROPERTY COMPILE_OPTIONS "-TP")
+endif()
+
+if((CMAKE_C_COMPILER_ID MATCHES "(GNU|Clang|MSVC|Borland|Embarcadero|Intel|TI|XL)"))
+  add_library(zoom zoom.zzz)
+  set_source_files_properties(zoom.zzz PROPERTIES LANGUAGE CXX)
+  target_link_libraries(SetLang zoom)
+  target_compile_definitions(SetLang PRIVATE WITH_ZOOM)
+endif()
diff --git a/Tests/SetLang/bar.c b/Tests/SetLang/bar.c
index b934356..515e8c2 100644
--- a/Tests/SetLang/bar.c
+++ b/Tests/SetLang/bar.c
@@ -1,10 +1,22 @@
 #include <stdio.h>
 
 int foo();
+
+#ifdef WITH_ZOOM
+int zoom();
+#endif
+
 class A
 {
 public:
-  A() { this->i = foo(); }
+  A()
+  {
+    this->i = foo();
+#ifdef WITH_ZOOM
+    i += zoom();
+    i -= zoom();
+#endif
+  }
   int i;
 };
 
diff --git a/Tests/SetLang/stay_c.c b/Tests/SetLang/stay_c.c
new file mode 100644
index 0000000..70755f3
--- /dev/null
+++ b/Tests/SetLang/stay_c.c
@@ -0,0 +1,8 @@
+#ifdef __cplusplus
+#  error C source incorrectly compiled as C++
+#endif
+
+int stay_c(void)
+{
+  return 0;
+}
diff --git a/Tests/SetLang/stay_cxx.cxx b/Tests/SetLang/stay_cxx.cxx
new file mode 100644
index 0000000..e035260
--- /dev/null
+++ b/Tests/SetLang/stay_cxx.cxx
@@ -0,0 +1,8 @@
+#ifndef __cplusplus
+#  error C++ source incorrectly compiled as C
+#endif
+
+int stay_cxx()
+{
+  return 0;
+}
diff --git a/Tests/SetLang/zoom.zzz b/Tests/SetLang/zoom.zzz
new file mode 100644
index 0000000..a0c8899
--- /dev/null
+++ b/Tests/SetLang/zoom.zzz
@@ -0,0 +1,7 @@
+int zoom()
+{
+  int r = 10;
+  r++;
+  int ret = r + 10;
+  return ret;
+}
diff --git a/Tests/SourceGroups/CMakeLists.txt b/Tests/SourceGroups/CMakeLists.txt
index a5740bb..d726395 100644
--- a/Tests/SourceGroups/CMakeLists.txt
+++ b/Tests/SourceGroups/CMakeLists.txt
@@ -30,6 +30,9 @@
 # a group without files, is currently not created
 source_group(EmptyGroup)
 
+# Forward slashes can be delimiters too
+source_group(Base/Nested FILES nested.c)
+
 set(root ${CMAKE_CURRENT_SOURCE_DIR})
 
 set(tree_files_without_prefix ${root}/sub1/tree_bar.c
@@ -58,4 +61,5 @@
 
 add_executable(SourceGroups main.c bar.c foo.c sub1/foo.c sub1/foobar.c baz.c
                             ${tree_files_with_prefix} ${tree_files_without_prefix}
-                            ${tree_files_with_empty_prefix} README.txt)
+                            ${tree_files_with_empty_prefix} README.txt
+                            nested.c)
diff --git a/Tests/SourceGroups/main.c b/Tests/SourceGroups/main.c
index 87225f5..f646b49 100644
--- a/Tests/SourceGroups/main.c
+++ b/Tests/SourceGroups/main.c
@@ -12,6 +12,7 @@
 extern int tree_bar(void);
 extern int tree_foobar(void);
 extern int tree_baz(void);
+extern int nested(void);
 
 int main()
 {
@@ -23,5 +24,8 @@
          "tree_empty_prefix_bar: %d\n",
          tree_prefix_foo(), tree_prefix_bar(), tree_bar(), tree_foobar(),
          tree_baz(), tree_empty_prefix_foo(), tree_empty_prefix_bar());
+
+  printf("nested: %d\n", nested());
+
   return 0;
 }
diff --git a/Tests/SourceGroups/nested.c b/Tests/SourceGroups/nested.c
new file mode 100644
index 0000000..4e31480
--- /dev/null
+++ b/Tests/SourceGroups/nested.c
@@ -0,0 +1,4 @@
+int nested(void)
+{
+  return 123;
+}
diff --git a/Tests/SwiftOnly/CMakeLists.txt b/Tests/SwiftOnly/CMakeLists.txt
index f4cbac2..41d14ea 100644
--- a/Tests/SwiftOnly/CMakeLists.txt
+++ b/Tests/SwiftOnly/CMakeLists.txt
@@ -1,4 +1,16 @@
 cmake_minimum_required(VERSION 3.3)
+
+# NOTE: Force the Release mode configuration as there are some issues with the
+# debug information handling on macOS on certain Xcode builds.
+if(NOT CMAKE_CONFIGURATION_TYPES)
+  set(CMAKE_BUILD_TYPE Release CACHE STRING "Choose the type of build" FORCE)
+endif()
+
+# NOTE: enable shared libraries by default.  Older Xcode releases do not play
+# well with static libraries, and Windows does not currently support static
+# libraries in Swift.
+set(BUILD_SHARED_LIBS YES)
+
 project(SwiftOnly Swift)
 
 if(NOT XCODE_VERSION VERSION_LESS 10.2)
@@ -7,7 +19,20 @@
   set(CMAKE_Swift_LANGUAGE_VERSION 3.0)
 endif()
 
+set(CMAKE_Swift_MODULE_DIRECTORY ${CMAKE_BINARY_DIR}/swift)
+
 add_executable(SwiftOnly main.swift)
 
+add_library(L L.swift)
+
+add_library(M M.swift)
+target_link_libraries(M PUBLIC
+  L)
+
+add_library(N N.swift)
+target_link_libraries(N PUBLIC
+  M)
+
 # Dummy to make sure generation works with such targets.
 add_library(SwiftIface INTERFACE)
+target_link_libraries(SwiftOnly PRIVATE SwiftIface)
diff --git a/Tests/SwiftOnly/L.swift b/Tests/SwiftOnly/L.swift
new file mode 100644
index 0000000..79ff87e
--- /dev/null
+++ b/Tests/SwiftOnly/L.swift
@@ -0,0 +1 @@
+public let ThirtyTwo: Int = 32
diff --git a/Tests/SwiftOnly/M.swift b/Tests/SwiftOnly/M.swift
new file mode 100644
index 0000000..dd333fe
--- /dev/null
+++ b/Tests/SwiftOnly/M.swift
@@ -0,0 +1,2 @@
+import L
+public let SixtyFour: Int = ThirtyTwo * 2
diff --git a/Tests/SwiftOnly/N.swift b/Tests/SwiftOnly/N.swift
new file mode 100644
index 0000000..990ddf9
--- /dev/null
+++ b/Tests/SwiftOnly/N.swift
@@ -0,0 +1,2 @@
+import M
+public let OneTwentyEight = SixtyFour * 2
diff --git a/Tests/TryCompile/CMakeLists.txt b/Tests/TryCompile/CMakeLists.txt
index 9ec9b70..df921d8 100644
--- a/Tests/TryCompile/CMakeLists.txt
+++ b/Tests/TryCompile/CMakeLists.txt
@@ -187,7 +187,7 @@
 if(SHOULD_FAIL_DUE_TO_BAD_SOURCE AND NOT CMAKE_GENERATOR MATCHES "Watcom WMake|NMake Makefiles")
   string(REPLACE "\n" "\n  " output "  ${output}")
   message(SEND_ERROR "try_compile with bad#source.c did not fail:\n${output}")
-elseif(NOT output MATCHES [[(bad#source\.c|bad\\)]])
+elseif(NOT output MATCHES [[(bad#source\.c|bad\.c|bad')]])
   string(REPLACE "\n" "\n  " output "  ${output}")
   message(SEND_ERROR "try_compile with bad#source.c failed without mentioning bad source:\n${output}")
 else()
diff --git a/Tests/UseSWIG/BasicConfiguration.cmake b/Tests/UseSWIG/BasicConfiguration.cmake
index fd3ac40..d054953 100644
--- a/Tests/UseSWIG/BasicConfiguration.cmake
+++ b/Tests/UseSWIG/BasicConfiguration.cmake
@@ -18,6 +18,9 @@
 if(${language} MATCHES csharp)
   set(SWIG_LANG_TYPE TYPE SHARED)
 endif()
+if(${language} MATCHES fortran)
+  set(SWIG_LANG_TYPE TYPE SHARED)
+endif()
 if(${language} MATCHES python)
   find_package(Python REQUIRED COMPONENTS Interpreter Development)
   set(SWIG_LANG_INCLUDE_DIRECTORIES ${Python_INCLUDE_DIRS})
diff --git a/Tests/UseSWIG/BasicFortran/CMakeLists.txt b/Tests/UseSWIG/BasicFortran/CMakeLists.txt
new file mode 100644
index 0000000..e81fb85
--- /dev/null
+++ b/Tests/UseSWIG/BasicFortran/CMakeLists.txt
@@ -0,0 +1,23 @@
+cmake_minimum_required(VERSION 3.12...3.13)
+
+project(TestBasicFortran CXX Fortran)
+
+include(CTest)
+
+set(language "fortran")
+
+include (../BasicConfiguration.cmake)
+get_target_property(EXAMPLE_PREFIX example PREFIX)
+if (NOT EXAMPLE_PREFIX STREQUAL "${CMAKE_SHARED_LIBRARY_PREFIX}"
+    AND NOT EXAMPLE_PREFIX STREQUAL "EXAMPLE_PREFIX-NOTFOUND")
+  message(FATAL_ERROR "Unexpected library prefix on target: got "
+    "'${EXAMPLE_PREFIX}' but expected '${CMAKE_SHARED_LIBRARY_PREFIX}'")
+endif()
+
+
+add_executable(runme ${CMAKE_CURRENT_SOURCE_DIR}/../runme.f90)
+target_link_libraries(runme example)
+set_target_properties(runme PROPERTIES LINKER_LANGUAGE Fortran)
+
+add_test (NAME BasicFortran
+  COMMAND $<TARGET_FILE:runme>)
diff --git a/Tests/UseSWIG/CMakeLists.txt b/Tests/UseSWIG/CMakeLists.txt
index 3cc910f..7046fab 100644
--- a/Tests/UseSWIG/CMakeLists.txt
+++ b/Tests/UseSWIG/CMakeLists.txt
@@ -33,6 +33,16 @@
     --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
     )
 endif()
+add_test(NAME UseSWIG.NamespaceCsharp COMMAND
+  ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
+  --build-and-test
+  "${CMake_SOURCE_DIR}/Tests/UseSWIG/NamespaceCsharp"
+  "${CMake_BINARY_DIR}/Tests/UseSWIG/NamespaceCsharp"
+  ${build_generator_args}
+  --build-project TestNamespaceCsharp
+  --build-options ${build_options}
+  --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
+  )
 
 add_test(NAME UseSWIG.BasicPython COMMAND
   ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
@@ -55,6 +65,21 @@
   --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
   )
 
+if (CMake_TEST_UseSWIG_Fortran)
+  check_language(Fortran)
+  if (CMAKE_Fortran_COMPILER)
+    add_test(NAME UseSWIG.BasicFortran COMMAND
+      ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
+      --build-and-test
+      "${CMake_SOURCE_DIR}/Tests/UseSWIG/BasicFortran"
+      "${CMake_BINARY_DIR}/Tests/UseSWIG/BasicFortran"
+      ${build_generator_args}
+      --build-project TestBasicFortran
+      --build-options ${build_options}
+      --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
+      )
+  endif()
+endif()
 
 add_test(NAME UseSWIG.MultipleModules COMMAND
   ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
diff --git a/Tests/UseSWIG/NamespaceCsharp/CMakeLists.txt b/Tests/UseSWIG/NamespaceCsharp/CMakeLists.txt
new file mode 100644
index 0000000..39566a8
--- /dev/null
+++ b/Tests/UseSWIG/NamespaceCsharp/CMakeLists.txt
@@ -0,0 +1,25 @@
+cmake_minimum_required(VERSION 3.12...3.13)
+
+project(TestNamsespaceCsharp CXX)
+
+include(CTest)
+
+find_package(SWIG REQUIRED)
+include(${SWIG_USE_FILE})
+
+set(UseSWIG_MODULE_VERSION 2)
+
+
+add_library(ns_example STATIC ns_example.cpp)
+target_include_directories(ns_example PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}")
+
+set_property(SOURCE ns_example.i PROPERTY CPLUSPLUS ON)
+
+swig_add_library(ns_csharp TYPE SHARED LANGUAGE csharp SOURCES ns_example.i)
+set_target_properties(ns_csharp PROPERTIES SWIG_USE_TARGET_INCLUDE_DIRECTORIES TRUE)
+
+target_link_libraries(ns_csharp PRIVATE ns_example)
+
+get_target_property(NS_CSHARP_SUPPORT_FILES_DIR ns_csharp SWIG_SUPPORT_FILES_DIRECTORY)
+
+add_test(NAME NamespaceCsharp COMMAND "${CMAKE_COMMAND}" "-DSUPPORT_FILES_DIRECTORY=${NS_CSHARP_SUPPORT_FILES_DIR}" -P "${CMAKE_CURRENT_SOURCE_DIR}/ValidateSupportFiles.cmake")
diff --git a/Tests/UseSWIG/NamespaceCsharp/ValidateSupportFiles.cmake b/Tests/UseSWIG/NamespaceCsharp/ValidateSupportFiles.cmake
new file mode 100644
index 0000000..828d54c
--- /dev/null
+++ b/Tests/UseSWIG/NamespaceCsharp/ValidateSupportFiles.cmake
@@ -0,0 +1,8 @@
+
+file (GLOB_RECURSE files LIST_DIRECTORIES TRUE RELATIVE "${SUPPORT_FILES_DIRECTORY}" "${SUPPORT_FILES_DIRECTORY}/*")
+
+list(SORT files)
+
+if (NOT files STREQUAL "NSExample.cs;NSExamplePINVOKE.cs;ns;ns/my_class_in_namespace.cs")
+  message (FATAL_ERROR "Support files not correctly collected.")
+endif()
diff --git a/Tests/UseSWIG/NamespaceCsharp/ns_example.cpp b/Tests/UseSWIG/NamespaceCsharp/ns_example.cpp
new file mode 100644
index 0000000..a03dbad
--- /dev/null
+++ b/Tests/UseSWIG/NamespaceCsharp/ns_example.cpp
@@ -0,0 +1,14 @@
+#include "ns_example.hpp"
+
+namespace ns {
+
+void my_class_in_namespace::add(int value)
+{
+  Sum += value;
+}
+
+int my_class_in_namespace::get_sum() const
+{
+  return Sum;
+}
+}
diff --git a/Tests/UseSWIG/NamespaceCsharp/ns_example.hpp b/Tests/UseSWIG/NamespaceCsharp/ns_example.hpp
new file mode 100644
index 0000000..65b9ab5
--- /dev/null
+++ b/Tests/UseSWIG/NamespaceCsharp/ns_example.hpp
@@ -0,0 +1,19 @@
+#pragma once
+
+namespace ns {
+
+class my_class_in_namespace
+{
+public:
+  my_class_in_namespace()
+    : Sum(0)
+  {
+  }
+
+  void add(int value);
+  int get_sum() const;
+
+private:
+  int Sum;
+};
+}
diff --git a/Tests/UseSWIG/NamespaceCsharp/ns_example.i b/Tests/UseSWIG/NamespaceCsharp/ns_example.i
new file mode 100644
index 0000000..036f7ca
--- /dev/null
+++ b/Tests/UseSWIG/NamespaceCsharp/ns_example.i
@@ -0,0 +1,8 @@
+%module NSExample
+
+%{
+#include "ns_example.hpp"
+%}
+
+%nspace ns::my_class_in_namespace;
+%include "ns_example.hpp"
diff --git a/Tests/UseSWIG/runme.f90 b/Tests/UseSWIG/runme.f90
new file mode 100644
index 0000000..1d985d3
--- /dev/null
+++ b/Tests/UseSWIG/runme.f90
@@ -0,0 +1,77 @@
+! File : runme.f90
+program runme
+  use ISO_FORTRAN_ENV
+  implicit none
+  integer, parameter :: STDOUT = OUTPUT_UNIT
+
+  call run()
+contains
+
+subroutine run()
+  use example
+  use iso_c_binding
+  implicit none
+
+  type(Circle)          :: c
+  type(Square), target  :: s ! 'target' allows it to be pointed to
+  class(Shape), pointer :: sh
+  integer(C_INT) :: n_shapes
+
+  ! ----- Object creation -----
+
+  write(STDOUT,*) "Creating some objects"
+  c = Circle(10.0d0)
+  s = Square(10.0d0)
+
+  ! ----- Access a static member -----
+  write(STDOUT,'(a,i2,a)')"A total of", s%get_nshapes(), " shapes were created"
+
+  ! ----- Member data access -----
+
+  ! Notice how we can do this using functions specific to
+  ! the 'Circle' class.
+  call c%set_x(20.0d0)
+  call c%set_y(30.0d0)
+
+  ! Now use the same functions in the base class
+  sh => s
+  call sh%set_x(-10.0d0)
+  call sh%set_y(  5.0d0)
+
+  write(STDOUT,*)"Here is their current position:"
+  write(STDOUT,'(a,f5.1,a,f5.1,a)')"  Circle = (", c%get_x(), ",", c%get_y(), " )"
+  write(STDOUT,'(a,f5.1,a,f5.1,a)')"  Square = (", s%get_x(), ",", s%get_y(), " )"
+
+  ! ----- Call some methods -----
+
+  write(STDOUT,*)"Here are some properties of the shapes:"
+  call print_shape(c)
+  call print_shape(s)
+
+  ! ----- Delete everything -----
+
+  ! Note: this invokes the virtual destructor
+  call c%release()
+  call s%release()
+
+  n_shapes = c%get_nshapes()
+  write(STDOUT,*) n_shapes, "shapes remain"
+  if (n_shapes /= 0) then
+    write(STDOUT,*) "Shapes were not freed properly!"
+    stop 1
+  endif
+
+  write(STDOUT,*) "Goodbye"
+end subroutine
+
+subroutine print_shape(s)
+  use example, only : Shape
+  use iso_c_binding
+  implicit none
+  class(Shape), intent(in) :: s
+
+  write(STDOUT,*)"    area      = ",s%area()
+  write(STDOUT,*)"    perimeter = ",s%perimeter()
+end subroutine
+
+end program
diff --git a/Tests/VSNsightTegra/AndroidManifest.xml b/Tests/VSAndroid/AndroidManifest.xml
similarity index 100%
rename from Tests/VSNsightTegra/AndroidManifest.xml
rename to Tests/VSAndroid/AndroidManifest.xml
diff --git a/Tests/VSAndroid/CMakeLists.txt b/Tests/VSAndroid/CMakeLists.txt
new file mode 100644
index 0000000..73b1e07
--- /dev/null
+++ b/Tests/VSAndroid/CMakeLists.txt
@@ -0,0 +1,57 @@
+cmake_minimum_required(VERSION 3.3)
+project(VSAndroid C CXX)
+
+set(CMAKE_ANDROID_ARCH armv7-a)
+set(CMAKE_ANDROID_STL_TYPE stlport_shared)
+set(CMAKE_ANDROID_API_MIN 9)
+set(CMAKE_ANDROID_API 15)
+set(CMAKE_ANDROID_GUI 1)
+
+set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/bin")
+set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/lib")
+set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/lib")
+
+set(FIRST_C_FILES
+  jni/first.c
+  jni/first.h
+  )
+
+source_group(jni FILES ${FIRST_C_FILES})
+add_library(twolib-first ${FIRST_C_FILES})
+
+set(SECOND_C_FILES
+  jni/second.c
+  )
+set(SECOND_JAVA_FILES
+  src/com/example/twolibs/TwoLibs.java
+  )
+set(SECOND_RES_FILES
+  res/values/strings.xml
+  )
+set(SECOND_ANDROID_FILES
+  AndroidManifest.xml
+  )
+
+source_group(jni FILES ${SECOND_C_FILES})
+source_group(res\\values FILES ${SECOND_RES_FILES})
+source_group(src\\com\\example\\twolibs FILES ${SECOND_JAVA_FILES})
+add_executable(twolib-second
+  ${SECOND_C_FILES}
+  ${SECOND_JAVA_FILES}
+  ${SECOND_RES_FILES}
+  ${SECOND_ANDROID_FILES}
+  )
+target_include_directories(twolib-second PUBLIC jni)
+target_link_libraries(twolib-second twolib-first)
+target_link_libraries(twolib-second m) # test linking to library by name
+
+set_property(TARGET twolib-second PROPERTY C_STANDARD 11)
+set_target_properties(twolib-second PROPERTIES ANDROID_SKIP_ANT_STEP 1)
+set_target_properties(twolib-second PROPERTIES ANDROID_PROGUARD 1)
+set_target_properties(twolib-second PROPERTIES ANDROID_PROGUARD_CONFIG_PATH proguard-android.txt)
+set_target_properties(twolib-second PROPERTIES ANDROID_SECURE_PROPS_PATH /definitely/insecure)
+
+set_property(TARGET twolib-second PROPERTY ANDROID_NATIVE_LIB_DIRECTORIES $<TARGET_FILE_DIR:twolib-second>)
+set_property(TARGET twolib-second PROPERTY ANDROID_NATIVE_LIB_DEPENDENCIES $<TARGET_FILE_NAME:twolib-second>)
+
+set_property(TARGET twolib-second PROPERTY ANDROID_JAR_DIRECTORIES $<TARGET_FILE_DIR:twolib-first>)
diff --git a/Tests/VSNsightTegra/build.xml b/Tests/VSAndroid/build.xml
similarity index 100%
rename from Tests/VSNsightTegra/build.xml
rename to Tests/VSAndroid/build.xml
diff --git a/Tests/VSNsightTegra/jni/first.c b/Tests/VSAndroid/jni/first.c
similarity index 100%
rename from Tests/VSNsightTegra/jni/first.c
rename to Tests/VSAndroid/jni/first.c
diff --git a/Tests/VSNsightTegra/jni/first.h b/Tests/VSAndroid/jni/first.h
similarity index 100%
rename from Tests/VSNsightTegra/jni/first.h
rename to Tests/VSAndroid/jni/first.h
diff --git a/Tests/VSNsightTegra/jni/second.c b/Tests/VSAndroid/jni/second.c
similarity index 100%
rename from Tests/VSNsightTegra/jni/second.c
rename to Tests/VSAndroid/jni/second.c
diff --git a/Tests/VSNsightTegra/proguard-android.txt b/Tests/VSAndroid/proguard-android.txt
similarity index 100%
rename from Tests/VSNsightTegra/proguard-android.txt
rename to Tests/VSAndroid/proguard-android.txt
diff --git a/Tests/VSNsightTegra/res/values/strings.xml b/Tests/VSAndroid/res/values/strings.xml
similarity index 100%
rename from Tests/VSNsightTegra/res/values/strings.xml
rename to Tests/VSAndroid/res/values/strings.xml
diff --git a/Tests/VSNsightTegra/src/com/example/twolibs/TwoLibs.java b/Tests/VSAndroid/src/com/example/twolibs/TwoLibs.java
similarity index 100%
rename from Tests/VSNsightTegra/src/com/example/twolibs/TwoLibs.java
rename to Tests/VSAndroid/src/com/example/twolibs/TwoLibs.java
diff --git a/Tests/VSNsightTegra/CMakeLists.txt b/Tests/VSNsightTegra/CMakeLists.txt
deleted file mode 100644
index 6d74f2f..0000000
--- a/Tests/VSNsightTegra/CMakeLists.txt
+++ /dev/null
@@ -1,57 +0,0 @@
-cmake_minimum_required(VERSION 3.3)
-project(VSNsightTegra C CXX)
-
-set(CMAKE_ANDROID_ARCH armv7-a)
-set(CMAKE_ANDROID_STL_TYPE stlport_shared)
-set(CMAKE_ANDROID_API_MIN 9)
-set(CMAKE_ANDROID_API 15)
-set(CMAKE_ANDROID_GUI 1)
-
-set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/bin")
-set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/lib")
-set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/lib")
-
-set(FIRST_C_FILES
-  jni/first.c
-  jni/first.h
-  )
-
-source_group(jni FILES ${FIRST_C_FILES})
-add_library(twolib-first ${FIRST_C_FILES})
-
-set(SECOND_C_FILES
-  jni/second.c
-  )
-set(SECOND_JAVA_FILES
-  src/com/example/twolibs/TwoLibs.java
-  )
-set(SECOND_RES_FILES
-  res/values/strings.xml
-  )
-set(SECOND_ANDROID_FILES
-  AndroidManifest.xml
-  )
-
-source_group(jni FILES ${SECOND_C_FILES})
-source_group(res\\values FILES ${SECOND_RES_FILES})
-source_group(src\\com\\example\\twolibs FILES ${SECOND_JAVA_FILES})
-add_executable(twolib-second
-  ${SECOND_C_FILES}
-  ${SECOND_JAVA_FILES}
-  ${SECOND_RES_FILES}
-  ${SECOND_ANDROID_FILES}
-  )
-target_include_directories(twolib-second PUBLIC jni)
-target_link_libraries(twolib-second twolib-first)
-target_link_libraries(twolib-second m) # test linking to library by name
-
-set_property(TARGET twolib-second PROPERTY C_STANDARD 11)
-set_target_properties(twolib-second PROPERTIES ANDROID_SKIP_ANT_STEP 1)
-set_target_properties(twolib-second PROPERTIES ANDROID_PROGUARD 1)
-set_target_properties(twolib-second PROPERTIES ANDROID_PROGUARD_CONFIG_PATH proguard-android.txt)
-set_target_properties(twolib-second PROPERTIES ANDROID_SECURE_PROPS_PATH /definitely/insecure)
-
-set_property(TARGET twolib-second PROPERTY ANDROID_NATIVE_LIB_DIRECTORIES $<TARGET_FILE_DIR:twolib-second>)
-set_property(TARGET twolib-second PROPERTY ANDROID_NATIVE_LIB_DEPENDENCIES $<TARGET_FILE_NAME:twolib-second>)
-
-set_property(TARGET twolib-second PROPERTY ANDROID_JAR_DIRECTORIES $<TARGET_FILE_DIR:twolib-first>)
diff --git a/Tests/VSWinStorePhone/CMakeLists.txt b/Tests/VSWinStorePhone/CMakeLists.txt
index b8e157d..56e4c1d 100644
--- a/Tests/VSWinStorePhone/CMakeLists.txt
+++ b/Tests/VSWinStorePhone/CMakeLists.txt
@@ -114,7 +114,7 @@
 set_property(SOURCE ${STRING_FILES} PROPERTY VS_TOOL_OVERRIDE "PRIResource")
 set_property(SOURCE ${DEBUG_CONTENT_FILES} PROPERTY VS_DEPLOYMENT_CONTENT $<CONFIG:Debug>)
 set_property(SOURCE ${RELEASE_CONTENT_FILES} PROPERTY
-  VS_DEPLOYMENT_CONTENT $<OR:$<CONFIG:Release>,$<CONFIG:RelWithDebInfo>,$<CONFIG:MinSizeRel>>)
+  VS_DEPLOYMENT_CONTENT $<CONFIG:Release,RelWithDebInfo,MinSizeRel>)
 
 set_property(SOURCE ${PIXELSHADER_FILES} PROPERTY VS_SHADER_TYPE Pixel)
 set_property(SOURCE ${PIXELSHADER_FILES} PROPERTY VS_SHADER_ENTRYPOINT mainPS)
@@ -127,7 +127,7 @@
 set_property(SOURCE ${VERTEXSHADER_FILES} PROPERTY VS_SHADER_MODEL 4.0_level_9_3)
 set_property(SOURCE ${VERTEXSHADER_FILES} PROPERTY VS_SHADER_FLAGS "/DFLAGS_ADDED")
 set_property(SOURCE ${VERTEXSHADER_FILES} PROPERTY VS_SHADER_OUTPUT_HEADER_FILE "$(OutDir)%(Filename).h")
-
+set_property(SOURCE ${VERTEXSHADER_FILES} PROPERTY VS_SETTINGS "$<$<CONFIG:DEBUG>:SourceProperty1=SourceProperty1Value>")
 
 source_group("Source Files" FILES ${SOURCE_FILES})
 source_group("Header Files" FILES ${HEADER_FILES})
@@ -135,6 +135,11 @@
 
 add_executable(${EXE_NAME} WIN32 ${SOURCE_FILES} ${HEADER_FILES} ${RESOURCE_FILES})
 set_property(TARGET ${EXE_NAME} PROPERTY VS_WINRT_COMPONENT TRUE)
+set_property(TARGET ${EXE_NAME} PROPERTY VS_SOURCE_SETTINGS_FXCompile
+  "TargetProperty1=$<$<CONFIG:DEBUG>:TargetProperty1ValueDebug>$<$<CONFIG:RELEASE>:TargetProperty1ValueRelease>")
+
+add_custom_command(TARGET ${EXE_NAME} POST_BUILD
+  COMMAND ${CMAKE_COMMAND} -Dvcxproj="${CMAKE_CURRENT_BINARY_DIR}/${EXE_NAME}.vcxproj" -P "${CMAKE_CURRENT_SOURCE_DIR}/EnsurePropertiesSet.cmake")
 
 string(SUBSTRING "${CMAKE_SYSTEM_VERSION}" 0, 4, SHORT_VERSION)
 
diff --git a/Tests/VSWinStorePhone/EnsurePropertiesSet.cmake b/Tests/VSWinStorePhone/EnsurePropertiesSet.cmake
new file mode 100644
index 0000000..528c46f
--- /dev/null
+++ b/Tests/VSWinStorePhone/EnsurePropertiesSet.cmake
@@ -0,0 +1,45 @@
+macro(ensure_props_set projectFile)
+  if(NOT EXISTS "${projectFile}")
+    message(FATAL_ERROR "Project file ${projectFile} does not exist.")
+    return()
+  endif()
+
+  set(SourcePropertyFound FALSE)
+  set(DebugTargetPropertyFound FALSE)
+  set(ReleaseTargetPropertyFound FALSE)
+
+  file(STRINGS "${projectFile}" lines)
+  foreach(line IN LISTS lines)
+    if(line MATCHES "<SourceProperty1.*Debug.*>SourceProperty1Value</SourceProperty1>")
+      message("SourceProperty1 setting found")
+      set(SourcePropertyFound TRUE)
+    endif()
+
+    if(line MATCHES "<TargetProperty1.*Debug.*>TargetProperty1ValueDebug</TargetProperty1>")
+      message("Debug TargetProperty1 setting found")
+      set(DebugTargetPropertyFound TRUE)
+    endif()
+
+    if(line MATCHES "<TargetProperty1.*Release.*>TargetProperty1ValueRelease</TargetProperty1>")
+      message("Release TargetProperty1 setting found")
+      set(ReleaseTargetPropertyFound TRUE)
+    endif()
+  endforeach()
+
+  if (NOT SourcePropertyFound)
+    message(FATAL_ERROR "SourceProperty1 setting not found")
+    return()
+  endif()
+
+  if (NOT DebugTargetPropertyFound)
+    message(FATAL_ERROR "Debug TargetProperty1 setting not found")
+    return()
+  endif()
+
+  if (NOT ReleaseTargetPropertyFound)
+    message(FATAL_ERROR "Release TargetProperty1 setting not found")
+    return()
+  endif()
+endmacro()
+
+ensure_props_set("${vcxproj}")
diff --git a/Tests/VSWindowsFormsResx/WindowsFormsResx/MyForm.cpp b/Tests/VSWindowsFormsResx/WindowsFormsResx/MyForm.cpp
index 154e268..0c37370 100644
--- a/Tests/VSWindowsFormsResx/WindowsFormsResx/MyForm.cpp
+++ b/Tests/VSWindowsFormsResx/WindowsFormsResx/MyForm.cpp
@@ -1 +1 @@
-#include "MyForm.h"
\ No newline at end of file
+#include "MyForm.h"
diff --git a/Tests/VariableUnusedViaSet/CMakeLists.txt b/Tests/VariableUnusedViaSet/CMakeLists.txt
deleted file mode 100644
index 0123ab2..0000000
--- a/Tests/VariableUnusedViaSet/CMakeLists.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-set(UNUSED_VARIABLE)
-# Warning should occur here
-set(UNUSED_VARIABLE "Usage")
-message(STATUS "${UNUSED_VARIABLE}")
diff --git a/Tests/VariableUnusedViaUnset/CMakeLists.txt b/Tests/VariableUnusedViaUnset/CMakeLists.txt
deleted file mode 100644
index 4b4031d..0000000
--- a/Tests/VariableUnusedViaUnset/CMakeLists.txt
+++ /dev/null
@@ -1,8 +0,0 @@
-# NOTE: Changing lines in here changes the test results since the first
-# instance shouldn't warn, but the second should and they have the same message
-
-# A warning should NOT be issued for this line:
-set(UNUSED_VARIABLE)
-# Warning should occur here:
-set(UNUSED_VARIABLE)
-message(STATUS "${UNUSED_VARIABLE}")
diff --git a/Tests/XCTest/StaticLibExample/StaticLibExample.c b/Tests/XCTest/StaticLibExample/StaticLibExample.c
index b198f80..8d16eb5 100644
--- a/Tests/XCTest/StaticLibExample/StaticLibExample.c
+++ b/Tests/XCTest/StaticLibExample/StaticLibExample.c
@@ -1,6 +1,6 @@
 #include "StaticLibExample.h"
 
-int FourtyFour()
+int FourtyFour(void)
 {
   return 44;
 }
diff --git a/Tests/XCTest/StaticLibExample/StaticLibExample.h b/Tests/XCTest/StaticLibExample/StaticLibExample.h
index 147a909..88695b1 100644
--- a/Tests/XCTest/StaticLibExample/StaticLibExample.h
+++ b/Tests/XCTest/StaticLibExample/StaticLibExample.h
@@ -1 +1 @@
-int FourtyFour();
+int FourtyFour(void);
diff --git a/Utilities/GitSetup/setup-user b/Utilities/GitSetup/setup-user
index 0b98879..4cbd184 100755
--- a/Utilities/GitSetup/setup-user
+++ b/Utilities/GitSetup/setup-user
@@ -20,7 +20,14 @@
 # Project configuration instructions: NONE
 
 for (( ; ; )); do
-	ident="$(git var GIT_AUTHOR_IDENT 2>/dev/null | rev | cut -d' ' -f3- | rev)"
+	if type -p rev >/dev/null && type -p cut >/dev/null; then
+		ident="$(git var GIT_AUTHOR_IDENT 2>/dev/null | rev | cut -d' ' -f3- | rev)"
+	elif user_name=$(git config --get user.name) &&
+		user_email=$(git config --get user.email); then
+		ident="$user_name <$user_email>"
+	else
+		ident=""
+	fi
 
 	if test -n "$ident"; then
 		echo 'Your commits will record as Author:
diff --git a/Utilities/IWYU/mapping.imp b/Utilities/IWYU/mapping.imp
index 3497b53..66cb282 100644
--- a/Utilities/IWYU/mapping.imp
+++ b/Utilities/IWYU/mapping.imp
@@ -27,6 +27,7 @@
   { include: [ "<bits/std_abs.h>", private, "<stdlib.h>", public ] },
   { include: [ "<bits/stdint-intn.h>", private, "<stdint.h>", public ] },
   { include: [ "<bits/stdint-uintn.h>", private, "<stdint.h>", public ] },
+  { include: [ "<bits/string_view.tcc>", private, "<string_view>", public ] },
   { include: [ "<bits/time.h>", private, "<time.h>", public ] },
   { include: [ "<bits/types/clock_t.h>", private, "<time.h>", public ] },
   { include: [ "<bits/types/mbstate_t.h>", private, "<wchar.h>", public ] },
@@ -77,6 +78,7 @@
   # Use '-Xiwyu -v7' to see the fully qualified names that need this.
   # TODO: Can this be simplified with an @-expression?
   #{ symbol: [ "@std::__decay_and_strip<.*>::__type", private, "\"cmConfigure.h\"", public ] },
+  { symbol: [ "std::__decay_and_strip<bool>::__type", private, "\"cmConfigure.h\"", public ] },
   { symbol: [ "std::__decay_and_strip<char const (&)[1]>::__type", private, "\"cmConfigure.h\"", public ] },
   { symbol: [ "std::__decay_and_strip<cmCommand *&>::__type", private, "\"cmConfigure.h\"", public ] },
   { symbol: [ "std::__decay_and_strip<cmGeneratorTarget *&>::__type", private, "\"cmConfigure.h\"", public ] },
@@ -86,61 +88,24 @@
   { symbol: [ "std::__decay_and_strip<std::basic_string<char> &>::__type", private, "\"cmConfigure.h\"", public ] },
   { symbol: [ "std::__decay_and_strip<const std::basic_string<char> &>::__type", private, "\"cmConfigure.h\"", public ] },
   { symbol: [ "std::__decay_and_strip<cmFindPackageCommand::PathLabel &>::__type", private, "\"cmConfigure.h\"", public ] },
+  { symbol: [ "std::__decay_and_strip<cmGlobalNinjaGenerator::TargetAlias &>::__type", private, "\"cmConfigure.h\"", public ] },
   { symbol: [ "std::__decay_and_strip<__gnu_cxx::__normal_iterator<const cmCTestTestHandler::cmCTestTestProperties *, std::vector<cmCTestTestHandler::cmCTestTestProperties, std::allocator<cmCTestTestHandler::cmCTestTestProperties> > > &>::__type", private, "\"cmConfigure.h\"", public ] },
+  { symbol: [ "std::__decay_and_strip<const __gnu_cxx::__normal_iterator<std::pair<cm::string_view, std::function<void (ArgumentParser::Instance &, void *)> > *, std::vector<std::pair<cm::string_view, std::function<void (ArgumentParser::Instance &, void *)> >, std::allocator<std::pair<cm::string_view, std::function<void (ArgumentParser::Instance &, void *)> > > > > &>::__type", private, "\"cmConfigure.h\"", public ] },
   { symbol: [ "std::__success_type<std::chrono::duration<double, std::ratio<1, 1> > >::type", private, "\"cmConfigure.h\"", public ] },
   { symbol: [ "std::__success_type<std::chrono::duration<long, std::ratio<1, 1000000000> > >::type", private, "\"cmConfigure.h\"", public ] },
   { symbol: [ "std::enable_if<true, std::chrono::duration<long, std::ratio<1, 1> > >::type", private, "\"cmConfigure.h\"", public ] },
   { symbol: [ "std::enable_if<true, std::chrono::duration<long, std::ratio<60, 1> > >::type", private, "\"cmConfigure.h\"", public ] },
   { symbol: [ "std::enable_if<true, std::chrono::duration<long, std::ratio<1, 1000> > >::type", private, "\"cmConfigure.h\"", public ] },
 
-  # KWIML
-  { include: [ "<stdint.h>", public, "\"cm_kwiml.h\"", public ] },
-  { include: [ "<inttypes.h>", public, "\"cm_kwiml.h\"", public ] },
-
-  # Self-sufficient wrapper for <sys/stat.h>
-  { symbol: [ "mode_t", private, "\"cm_sys_stat.h\"", public ] },
-
-  # Wrappers for 3rd-party libraries used from the system.
-  { include: [ "<archive.h>", private, "\"cm_libarchive.h\"", public ] },
-  { include: [ "<archive_entry.h>", private, "\"cm_libarchive.h\"", public ] },
-  { include: [ "@<curl/.+\\.h>", private, "\"cm_curl.h\"", public ] },
-  { include: [ "<expat.h>", private, "\"cm_expat.h\"", public ] },
-  { include: [ "<expat_external.h>", private, "\"cm_expat.h\"", public ] },
-  { include: [ "<json/reader.h>", private, "\"cm_jsoncpp_reader.h\"", public ] },
-  { include: [ "<json/value.h>", private, "\"cm_jsoncpp_value.h\"", public ] },
-  { include: [ "<json/writer.h>", private, "\"cm_jsoncpp_writer.h\"", public ] },
-  { include: [ "<rhash.h>", private, "\"cm_rhash.h\"", public ] },
-  { include: [ "<uv.h>", private, "\"cm_uv.h\"", public ] },
-  { include: [ "@<uv[/-].+\\.h>", private, "\"cm_uv.h\"", public ] },
-  { include: [ "<kwiml/abi.h>", private, "\"cm_kwiml.h\"", public ] },
-  { include: [ "<kwiml/int.h>", private, "\"cm_kwiml.h\"", public ] },
-  { include: [ "<zconf.h>", private, "\"cm_zlib.h\"", public ] },
-  { include: [ "<zlib.h>", private, "\"cm_zlib.h\"", public ] },
-
-  # Wrappers for bundled 3rd-party libraries.
-  { include: [ "\"cmlibarchive/libarchive/archive.h\"", private, "\"cm_libarchive.h\"", public ] },
-  { include: [ "\"cmlibarchive/libarchive/archive_entry.h\"", private, "\"cm_libarchive.h\"", public ] },
-  { include: [ "@\"cmcurl/include/curl/.+\\.h\"", private, "\"cm_curl.h\"", public ] },
-  { include: [ "\"cmexpat/lib/expat.h\"", private, "\"cm_expat.h\"", public ] },
-  { include: [ "\"cmexpat/lib/expat_external.h\"", private, "\"cm_expat.h\"", public ] },
-  { include: [ "\"cmjsoncpp/include/json/reader.h\"", private, "\"cm_jsoncpp_reader.h\"", public ] },
-  { include: [ "\"cmjsoncpp/include/json/value.h\"", private, "\"cm_jsoncpp_value.h\"", public ] },
-  { include: [ "\"cmjsoncpp/include/json/writer.h\"", private, "\"cm_jsoncpp_writer.h\"", public ] },
-  { include: [ "\"cmlibrhash/librhash/rhash.h\"", private, "\"cm_rhash.h\"", public ] },
-  { include: [ "\"cmlibuv/include/uv.h\"", private, "\"cm_uv.h\"", public ] },
-  { include: [ "@\"cmlibuv/include/uv/.+\\.h\"", private, "\"cm_uv.h\"", public ] },
-  { include: [ "\"KWIML/include/kwiml/abi.h\"", private, "\"cm_kwiml.h\"", public ] },
-  { include: [ "\"KWIML/include/kwiml/int.h\"", private, "\"cm_kwiml.h\"", public ] },
-  { include: [ "\"cmzlib/cm_zlib_mangle.h\"", private, "\"cm_zlib.h\"", public ] },
-  { include: [ "\"cmzlib/zconf.h\"", private, "\"cm_zlib.h\"", public ] },
-  { include: [ "\"cmzlib/zlib.h\"", private, "\"cm_zlib.h\"", public ] },
-
-  # System symbols used by libuv
-  { symbol: [ "SIGHUP", private, "\"cm_uv.h\"", public ] },
-  { symbol: [ "SIGINT", private, "\"cm_uv.h\"", public ] },
-  { symbol: [ "ssize_t", private, "\"cm_uv.h\"", public ] },
-
-  { symbol: [ "Json::ArrayIndex", private, "\"cm_jsoncpp_value.h\"", public ] },
+  # Wrappers for 3rd-party libraries
+  { include: [ "@<.*curl/curlver.h>", private, "<cm3p/curl/curl.h>", public ] },
+  { include: [ "@<.*json/forwards.h>", private, "<cm3p/json/value.h>", public ] },
+  { include: [ "@<.*uv/.+\\.h>", private, "<cm3p/uv.h>", public ] },
+  { include: [ "@<.*expat_external.h>", private, "<cm3p/expat.h>", public ] },
+  { include: [ "@<.*zconf.h>", private, "<cm3p/zlib.h>", public ] },
+  { include: [ "@<.*cm_zlib_mangle.h>", private, "<cm3p/zlib.h>", public ] },
+  # # System symbols used by libuv
+  { symbol: [ "ssize_t", private, "<cm3p/uv.h>", public ] },
 
   { symbol: [ "std::ifstream", private, "\"cmsys/FStream.hxx\"", public ] },
   { symbol: [ "std::ofstream", private, "\"cmsys/FStream.hxx\"", public ] },
@@ -152,8 +117,6 @@
   { include: [ "<fstream>", public, "\"cmsys/FStream.hxx\"", public ] },
 
   # major and minor are used as macro arguments. Those are false matches.
-  { symbol: [ "major", private, "\"cm_kwiml.h\"", public ] },
-  { symbol: [ "minor", private, "\"cm_kwiml.h\"", public ] },
   { symbol: [ "major", private, "\"cmVersion.h\"", public ] },
   { symbol: [ "minor", private, "\"cmVersion.h\"", public ] },
 
diff --git a/Utilities/KWIML/CMakeLists.txt b/Utilities/KWIML/CMakeLists.txt
index 15e65e5..1d15884 100644
--- a/Utilities/KWIML/CMakeLists.txt
+++ b/Utilities/KWIML/CMakeLists.txt
@@ -17,7 +17,6 @@
   endif()
   set(KWIML_INCLUDE_PREFIX kwiml)
 else()
-  cmake_minimum_required(VERSION 2.8.2 FATAL_ERROR)
   set(kwiml_standalone 0)
   if(KWIML_INSTALL_INCLUDE_DIR AND NOT DEFINED KWIML_INCLUDE_PREFIX)
     message(FATAL_ERROR "Host project must set KWIML_INCLUDE_PREFIX")
diff --git a/Utilities/KWIML/include/kwiml/abi.h b/Utilities/KWIML/include/kwiml/abi.h
index da525fd..1112cb0 100644
--- a/Utilities/KWIML/include/kwiml/abi.h
+++ b/Utilities/KWIML/include/kwiml/abi.h
@@ -136,6 +136,8 @@
 #  define KWIML_ABI_SIZEOF_DATA_PTR 8
 # elif defined(__i386) || defined(__i386__)
 #  define KWIML_ABI_SIZEOF_DATA_PTR 4
+# elif defined(_M_ARM64)
+#  define KWIML_ABI_SIZEOF_DATA_PTR 8
 # endif
 #endif
 #if !defined(KWIML_ABI_SIZEOF_DATA_PTR)
@@ -461,6 +463,10 @@
 #  define KWIML_ABI_ENDIAN_ID KWIML_ABI_ENDIAN_ID_BIG
 # endif
 
+/* Aarch64 (Windows) */
+#elif defined(_M_ARM64)
+# define KWIML_ABI_ENDIAN_ID KWIML_ABI_ENDIAN_ID_LITTLE
+
 /* Xtensa */
 #elif defined(__XTENSA_EB__)
 # define KWIML_ABI_ENDIAN_ID KWIML_ABI_ENDIAN_ID_BIG
diff --git a/Utilities/Release/.gitattributes b/Utilities/Release/.gitattributes
new file mode 100644
index 0000000..24e115f
--- /dev/null
+++ b/Utilities/Release/.gitattributes
@@ -0,0 +1 @@
+*.patch -whitespace
diff --git a/Utilities/Release/README.rst b/Utilities/Release/README.rst
index de294d1..9993afa 100644
--- a/Utilities/Release/README.rst
+++ b/Utilities/Release/README.rst
@@ -9,49 +9,57 @@
 Docker
 ------
 
-The ``linux/<arch>/`` directories contain Docker specifications that anyone
-may use to produce Linux binaries for CMake:
+The ``<os>/<arch>/`` directories contain Docker specifications that anyone
+may use to produce binaries for CMake on the following platforms:
 
-* ``linux/<arch>/base/Dockerfile``:
+* ``linux/x86_64/``: Linux on ``x86_64`` architectures.
+* ``win/x86/``: Windows on ``x86_64`` and ``i386`` architectures.
+
+Each ``<os>/<arch>/`` directory contains the following:
+
+* ``<os>/<arch>/base/Dockerfile``:
   Produces a base image with a build environment for portable CMake binaries.
   This image is published in the `kitware/cmake Docker Hub Repository`_
-  with tag ``build-linux-<arch>-base-<date>``.
+  with tag ``build-<os>-<arch>-base-<date>``.
 
-* ``linux/<arch>/deps/Dockerfile``:
+* ``<os>/<arch>/deps/Dockerfile``:
   Produces an image with custom-built dependencies for portable CMake binaries.
   This image is published in the `kitware/cmake Docker Hub Repository`_
-  with tag ``build-linux-<arch>-deps-<date>``.
+  with tag ``build-<os>-<arch>-deps-<date>``.
 
-* ``linux/<arch>/Dockerfile``:
-  Produce an image containing a portable CMake binary package for Linux.
+* ``<os>/<arch>/Dockerfile``:
+  Produce an image containing a portable CMake binary package.
   Build this image using the CMake source directory as the build context.
-  The resulting image will have an ``/out`` directory containing the package.
-  For example:
+  The resulting image will have an ``/out`` (or ``c:/out``) directory
+  containing the package.  For example, on Linux ``x86_64``:
 
   .. code-block:: console
 
     $ docker build --tag=cmake:build --network none \
-        -f cmake-src/Utilities/Release/linux/$arch/Dockerfile cmake-src
+        -f cmake-src/Utilities/Release/linux/x86_64/Dockerfile cmake-src
     $ docker container create --name cmake-build cmake:build
     $ docker cp cmake-build:/out .
-    $ ls out/cmake-*-Linux-$arch.*
+    $ ls out/cmake-*-Linux-x86_64.*
 
-* ``linux/<arch>/test/Dockerfile``:
+  On Windows, the ``win/x86`` specifications support both the ``x86_64``
+  and ``i386`` architectures selected via ``--build-arg ARCH=...``.
+
+* ``<os>/<arch>/test/Dockerfile``:
   Produces a base image with a test environment for packaged CMake binaries.
-  For example, build the test base image:
+  For example, on Linux ``x86_64``, one may build the test base image:
 
   .. code-block:: console
 
     $ docker build --tag=cmake:test-base \
-        cmake-src/Utilities/Release/linux/$arch/test
+        cmake-src/Utilities/Release/linux/x86_64/test
 
   Then create a local ``test/Dockerfile`` to prepare an image with both the
   CMake source tree and the above-built package::
 
     FROM cmake:test-base
     COPY cmake-src /opt/cmake/src/cmake
-    ADD out/cmake-<ver>-Linux-<arch>.tar.gz /opt/
-    ENV PATH=/opt/cmake-<ver>-Linux-<arch>/bin:$PATH
+    ADD out/cmake-<ver>-Linux-x86_64.tar.gz /opt/
+    ENV PATH=/opt/cmake-<ver>-Linux-x86_64/bin:$PATH
 
   Build the test image and run it to drive testing:
 
@@ -61,6 +69,10 @@
     $ docker run --network none cmake:test bash test-make.bash
     $ docker run --network none cmake:test bash test-ninja.bash
 
+  On Windows, the test scripts are called ``test-nmake.bat`` and
+  ``test-ninja.bat``.  In the ``x86`` architecture they accept one
+  argument specifying either ``x86_64`` or ``i386``.
+
 .. _`kitware/cmake Docker Hub Repository`: https://hub.docker.com/r/kitware/cmake
 
 Scripts for Kitware
diff --git a/Utilities/Release/create-cmake-release.cmake b/Utilities/Release/create-cmake-release.cmake
index 17a2151..88ac826 100644
--- a/Utilities/Release/create-cmake-release.cmake
+++ b/Utilities/Release/create-cmake-release.cmake
@@ -46,13 +46,9 @@
 
 write_docs_shell_script("create-${CMAKE_CREATE_VERSION}-docs.sh")
 write_rel_shell_script("create-${CMAKE_CREATE_VERSION}-macos.sh"   osx_release    ) # macOS x86_64
-write_rel_shell_script("create-${CMAKE_CREATE_VERSION}-win64.sh"   win64_release  ) # Windows x64
-write_rel_shell_script("create-${CMAKE_CREATE_VERSION}-win32.sh"   win32_release  ) # Windows x86
 
 message("Build docs first and then build for each platform:
  ./create-${CMAKE_CREATE_VERSION}-docs.sh    &&
  ./create-${CMAKE_CREATE_VERSION}-macos.sh   &&
- ./create-${CMAKE_CREATE_VERSION}-win64.sh   &&
- ./create-${CMAKE_CREATE_VERSION}-win32.sh   &&
  echo done
 ")
diff --git a/Utilities/Release/linux/x86_64/Dockerfile b/Utilities/Release/linux/x86_64/Dockerfile
index 41391d2..972913e 100644
--- a/Utilities/Release/linux/x86_64/Dockerfile
+++ b/Utilities/Release/linux/x86_64/Dockerfile
@@ -5,6 +5,7 @@
 # Build using the CMake source directory as the build context.
 # The resulting image will have an '/out' directory containing the package.
 
+# Keep this in sync with the `.gitlab-ci.yml` `release_linux` image.
 ARG FROM_IMAGE_NAME=kitware/cmake:build-linux-x86_64-deps-2020-04-02
 ARG FROM_IMAGE_DIGEST=@sha256:77e9ab183f34680990db9da5945473e288f0d6556bce79ecc1589670d656e157
 ARG FROM_IMAGE=$FROM_IMAGE_NAME$FROM_IMAGE_DIGEST
@@ -20,7 +21,6 @@
  && cp ../cmake/Utilities/Release/linux/x86_64/cache.txt CMakeCache.txt \
  && source /opt/rh/devtoolset-6/enable \
  && source /opt/rh/rh-python36/enable \
- && export LANG=en_US.UTF-8 \
  && set -x \
  && ../cmake/bootstrap --parallel=$(nproc) --docdir=doc/cmake \
  && nice make -j $(nproc) \
diff --git a/Utilities/Release/linux/x86_64/test/cache-ninja.txt b/Utilities/Release/linux/x86_64/test/cache-ninja.txt
deleted file mode 100644
index b00370e..0000000
--- a/Utilities/Release/linux/x86_64/test/cache-ninja.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-CMAKE_Fortran_COMPILER:STRING=
-CMake_TEST_IPO_WORKS_C:BOOL=ON
-CMake_TEST_IPO_WORKS_CXX:BOOL=ON
-CMake_TEST_Qt5:BOOL=ON
diff --git a/Utilities/Release/win/x86/Dockerfile b/Utilities/Release/win/x86/Dockerfile
new file mode 100644
index 0000000..a4f7445
--- /dev/null
+++ b/Utilities/Release/win/x86/Dockerfile
@@ -0,0 +1,23 @@
+# escape=`
+
+# Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
+# file Copyright.txt or https://cmake.org/licensing for details.
+
+# Produce an image containing a portable CMake binary package for Windows.
+# Build using the CMake source directory as the build context.
+# The resulting image will have a 'c:\out' directory containing the package.
+
+ARG FROM_IMAGE_NAME=kitware/cmake:build-win-x86-deps-2020-04-27
+ARG FROM_IMAGE_DIGEST=@sha256:04e229c0c0ba2247855d0e8c0fb87c1686f983adbafa4ce413e61b3905edb76b
+ARG FROM_IMAGE=$FROM_IMAGE_NAME$FROM_IMAGE_DIGEST
+
+FROM $FROM_IMAGE as build
+COPY . C:\cmake\src\cmake
+ARG ARCH="x86_64"
+ARG TEST="true"
+RUN \cmake\src\cmake\Utilities\Release\win\x86\build.bat %ARCH% %TEST%
+
+# Package in a separate stage so the builder can optionally skip it.
+FROM build as pack
+ARG PACK="ZIP WIX"
+RUN \cmake\src\cmake\Utilities\Release\win\x86\pack.bat %PACK%
diff --git a/Utilities/Release/win/x86/base/Dockerfile b/Utilities/Release/win/x86/base/Dockerfile
new file mode 100644
index 0000000..c2c00f8
--- /dev/null
+++ b/Utilities/Release/win/x86/base/Dockerfile
@@ -0,0 +1,30 @@
+# escape=`
+
+# Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
+# file Copyright.txt or https://cmake.org/licensing for details.
+
+# Produce a base image with a build environment for portable CMake binaries.
+# Build using the directory containing this file as its own build context.
+
+ARG FROM_IMAGE_NAME=mcr.microsoft.com/dotnet/framework/sdk:4.8-windowsservercore-ltsc2019
+ARG FROM_IMAGE_DIGEST=@sha256:a94289bfd61ba89cd162f7cf84afe0e307d4d2576b44b9bd277e7b3036ccfa6b
+ARG FROM_IMAGE=$FROM_IMAGE_NAME$FROM_IMAGE_DIGEST
+FROM $FROM_IMAGE
+
+# Use a traditional Windows shell.
+SHELL ["cmd", "/S", "/C"]
+
+# Install Visual Studio Build Tools for desktop development with C++.
+ADD https://aka.ms/vs/16/release/vs_buildtools.exe C:\TEMP\vs_buildtools.exe
+RUN C:\TEMP\vs_buildtools.exe --quiet --wait --norestart --nocache `
+    --installPath C:\BuildTools `
+    --add Microsoft.VisualStudio.Workload.VCTools `
+    --add Microsoft.VisualStudio.Component.VC.Tools.x86.x64 `
+    --add Microsoft.VisualStudio.Component.VC.CLI.Support `
+    --add Microsoft.VisualStudio.Component.VC.ATL `
+    --add Microsoft.VisualStudio.Component.Windows10SDK.18362 `
+ || IF "%ERRORLEVEL%"=="3010" EXIT 0
+RUN del C:\TEMP\vs_buildtools.exe
+
+# Add a toolchain environment loader for each architecture.
+COPY msvc-x86_64.bat msvc-i386.bat C:\
diff --git a/Utilities/Release/win/x86/base/msvc-i386.bat b/Utilities/Release/win/x86/base/msvc-i386.bat
new file mode 100755
index 0000000..a63bdd2
--- /dev/null
+++ b/Utilities/Release/win/x86/base/msvc-i386.bat
@@ -0,0 +1 @@
+@C:\BuildTools\VC\Auxiliary\Build\vcvarsall.bat x86
diff --git a/Utilities/Release/win/x86/base/msvc-x86_64.bat b/Utilities/Release/win/x86/base/msvc-x86_64.bat
new file mode 100755
index 0000000..cffe0e7
--- /dev/null
+++ b/Utilities/Release/win/x86/base/msvc-x86_64.bat
@@ -0,0 +1 @@
+@C:\BuildTools\VC\Auxiliary\Build\vcvarsall.bat x64
diff --git a/Utilities/Release/win/x86/build.bat b/Utilities/Release/win/x86/build.bat
new file mode 100755
index 0000000..2125572
--- /dev/null
+++ b/Utilities/Release/win/x86/build.bat
@@ -0,0 +1,19 @@
+@rem Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
+@rem file Copyright.txt or https://cmake.org/licensing for details.
+
+set ARCH=%1
+set TEST=%2
+
+copy \msvc-%ARCH%.bat \msvc.bat
+call \msvc.bat && @echo on || exit /b
+set PATH=C:\ninja;%PATH%
+
+mkdir \cmake\src\cmake-build && ^
+cd \cmake\src\cmake-build && ^
+copy ..\cmake\Utilities\Release\win\x86\cache-%ARCH%.txt CMakeCache.txt && ^
+\cmake\cmake\bin\cmake ..\cmake -GNinja && ^
+ninja && (
+  if "%TEST%"=="true" (
+    bin\ctest --output-on-failure -j %NUMBER_OF_PROCESSORS% -R "^(CMake\.|CMakeLib\.|CMakeServerLib\.|RunCMake\.ctest_memcheck)"
+  )
+)
diff --git a/Utilities/Release/win/x86/cache-i386.txt b/Utilities/Release/win/x86/cache-i386.txt
new file mode 100644
index 0000000..3c0ecc7
--- /dev/null
+++ b/Utilities/Release/win/x86/cache-i386.txt
@@ -0,0 +1,45 @@
+CMAKE_BUILD_TYPE:STRING=Release
+
+# Use APIs from at most Windows 7
+CMAKE_C_FLAGS:STRING=-D_WIN32_WINNT=0x601 -DNTDDI_VERSION=0x06010000
+CMAKE_CXX_FLAGS:STRING=-GR -EHsc -D_WIN32_WINNT=0x601 -DNTDDI_VERSION=0x06010000
+CMAKE_EXE_LINKER_FLAGS:STRING=-machine:x86 -subsystem:console,6.01
+
+# Link C/C++ runtime library statically.
+CMAKE_MSVC_RUNTIME_LIBRARY:STRING=MultiThreaded$<$<CONFIG:Debug>:Debug>
+
+# No ssl support in curl: use native Windows APIs.
+CMAKE_USE_OPENSSL:BOOL=OFF
+
+# Enable cmake-gui with static qt plugins
+BUILD_QtDialog:BOOL=TRUE
+CMake_GUI_DISTRIBUTE_WITH_Qt_LGPL:STRING=3
+CMAKE_PREFIX_PATH:STRING=C:/qt-i386
+CMake_QT_STATIC_QWindowsIntegrationPlugin_LIBRARIES:STRING=c:/qt-i386/plugins/platforms/qwindows.lib;c:/qt-i386/plugins/styles/qwindowsvistastyle.lib;c:/qt-i386/lib/Qt5EventDispatcherSupport.lib;c:/qt-i386/lib/Qt5FontDatabaseSupport.lib;c:/qt-i386/lib/Qt5ThemeSupport.lib;c:/qt-i386/lib/qtfreetype.lib;c:/qt-i386/lib/qtlibpng.lib;imm32.lib;wtsapi32.lib
+
+# Build documentation.
+CMAKE_DOC_DIR:STRING=doc/cmake
+PYTHON_EXECUTABLE:FILEPATH=C:/python3/python.exe
+SPHINX_EXECUTABLE:FILEPATH=C:/python3/Scripts/sphinx-build.exe
+SPHINX_HTML:BOOL=ON
+SPHINX_MAN:BOOL=ON
+SPHINX_QTHELP:BOOL=ON
+QCOLLECTIONGENERATOR_EXECUTABLE:PATH=C:/qt-i386/bin/qhelpgenerator.exe
+
+# No bootstrap with MSVC tools.
+CMAKE_SKIP_BOOTSTRAP_TEST:STRING=TRUE
+
+# No MFC in base image.
+CTEST_RUN_MFC:BOOL=OFF
+
+# No Fortran compiler.
+CMAKE_Fortran_COMPILER:FILEPATH=FALSE
+
+# No Swift compiler.
+CMAKE_Swift_COMPILER:FILEPATH=FALSE
+
+# Skip Qt5 tests because our Qt is static.
+CMake_TEST_Qt5:BOOL=FALSE
+
+# CPack package file name component for this platform.
+CPACK_SYSTEM_NAME:STRING=win32-x86
diff --git a/Utilities/Release/win/x86/cache-x86_64.txt b/Utilities/Release/win/x86/cache-x86_64.txt
new file mode 100644
index 0000000..2ccf93b
--- /dev/null
+++ b/Utilities/Release/win/x86/cache-x86_64.txt
@@ -0,0 +1,45 @@
+CMAKE_BUILD_TYPE:STRING=Release
+
+# Use APIs from at most Windows 7
+CMAKE_C_FLAGS:STRING=-D_WIN32_WINNT=0x601 -DNTDDI_VERSION=0x06010000
+CMAKE_CXX_FLAGS:STRING=-GR -EHsc -D_WIN32_WINNT=0x601 -DNTDDI_VERSION=0x06010000
+CMAKE_EXE_LINKER_FLAGS:STRING=-machine:x64 -subsystem:console,6.01
+
+# Link C/C++ runtime library statically.
+CMAKE_MSVC_RUNTIME_LIBRARY:STRING=MultiThreaded$<$<CONFIG:Debug>:Debug>
+
+# No ssl support in curl: use native Windows APIs.
+CMAKE_USE_OPENSSL:BOOL=OFF
+
+# Enable cmake-gui with static qt plugins
+BUILD_QtDialog:BOOL=TRUE
+CMake_GUI_DISTRIBUTE_WITH_Qt_LGPL:STRING=3
+CMAKE_PREFIX_PATH:STRING=C:/qt-x86_64
+CMake_QT_STATIC_QWindowsIntegrationPlugin_LIBRARIES:STRING=c:/qt-x86_64/plugins/platforms/qwindows.lib;c:/qt-x86_64/plugins/styles/qwindowsvistastyle.lib;c:/qt-x86_64/lib/Qt5EventDispatcherSupport.lib;c:/qt-x86_64/lib/Qt5FontDatabaseSupport.lib;c:/qt-x86_64/lib/Qt5ThemeSupport.lib;c:/qt-x86_64/lib/qtfreetype.lib;c:/qt-x86_64/lib/qtlibpng.lib;imm32.lib;wtsapi32.lib
+
+# Build documentation.
+CMAKE_DOC_DIR:STRING=doc/cmake
+PYTHON_EXECUTABLE:FILEPATH=C:/python3/python.exe
+SPHINX_EXECUTABLE:FILEPATH=C:/python3/Scripts/sphinx-build.exe
+SPHINX_HTML:BOOL=ON
+SPHINX_MAN:BOOL=ON
+SPHINX_QTHELP:BOOL=ON
+QCOLLECTIONGENERATOR_EXECUTABLE:PATH=C:/qt-x86_64/bin/qhelpgenerator.exe
+
+# No bootstrap with MSVC tools.
+CMAKE_SKIP_BOOTSTRAP_TEST:STRING=TRUE
+
+# No MFC in base image.
+CTEST_RUN_MFC:BOOL=OFF
+
+# No Fortran compiler.
+CMAKE_Fortran_COMPILER:FILEPATH=FALSE
+
+# No Swift compiler.
+CMAKE_Swift_COMPILER:FILEPATH=FALSE
+
+# Skip Qt5 tests because our Qt is static.
+CMake_TEST_Qt5:BOOL=FALSE
+
+# CPack package file name component for this platform.
+CPACK_SYSTEM_NAME:STRING=win64-x64
diff --git a/Utilities/Release/win/x86/deps/Dockerfile b/Utilities/Release/win/x86/deps/Dockerfile
new file mode 100644
index 0000000..4b294c1
--- /dev/null
+++ b/Utilities/Release/win/x86/deps/Dockerfile
@@ -0,0 +1,127 @@
+# escape=`
+
+# Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
+# file Copyright.txt or https://cmake.org/licensing for details.
+
+# Produce an image with custom-built dependencies for portable CMake binaries.
+# Build using the directory containing this file as its own build context.
+
+ARG FROM_IMAGE_NAME=kitware/cmake:build-win-x86-base-2020-04-27
+ARG FROM_IMAGE_DIGEST=@sha256:c5a8948d636319cdac0180266996558bb6fb037125792b5b837f069d02e53d7c
+ARG FROM_IMAGE=$FROM_IMAGE_NAME$FROM_IMAGE_DIGEST
+
+# Qt Source
+FROM $FROM_IMAGE AS qt-src
+
+# JOM
+ADD http://download.qt-project.org/official_releases/jom/unstable-jom.zip C:\jom\jom.zip
+RUN cd \jom `
+ && powershell -Command " `
+    if ($(Get-FileHash jom.zip).Hash -eq '128fdd846fe24f8594eed37d1d8929a0ea78df563537c0c1b1861a635013fff8') {`
+      Expand-Archive -Path jom.zip -DestinationPath .`
+    } else {`
+      exit 1 `
+    }" `
+ && del jom.zip
+
+# XZ
+ADD https://tukaani.org/xz/xz-5.2.5-windows.zip C:\xz\xz.zip
+RUN cd \xz `
+ && powershell -Command " `
+    if ($(Get-FileHash xz.zip).Hash -eq 'd83b82ca75dfab39a13dda364367b34970c781a9df4d41264db922ac3a8f622d') {`
+      Expand-Archive -Path xz.zip -DestinationPath .`
+    } else {`
+      exit 1 `
+    }" `
+ && del xz.zip
+
+# Git
+ADD https://github.com/git-for-windows/git/releases/download/v2.26.2.windows.1/MinGit-2.26.2-busybox-64-bit.zip C:\git\git.zip
+RUN cd \git `
+ && powershell -Command " `
+    if ($(Get-FileHash git.zip).Hash -eq 'e834ea73fe093fb180dc45f67a1f2a7a566dab53d1d45bc3cd150106f5c40520') {`
+      Expand-Archive -Path git.zip -DestinationPath .`
+    } else {`
+      exit 1 `
+    }" `
+ && del git.zip
+
+# Qt Source
+ADD https://download.qt.io/official_releases/qt/5.12/5.12.1/single/qt-everywhere-src-5.12.1.tar.xz C:\qt-src\qt.tar.xz
+RUN cd \qt-src `
+ && powershell -Command " `
+    if ($(Get-FileHash qt.tar.xz).Hash -eq 'caffbd625c7bc10ff8c5c7a27dbc7d84fa4de146975c0e1ffe904b514ccd6da4') {`
+      \xz\bin_x86-64\xz -d qt.tar.xz `
+    } else {`
+      exit 1 `
+    }" `
+ && tar xvf qt.tar `
+ && del qt.tar `
+ && move qt-everywhere-src-5.12.1 qt
+COPY qt-build.bat qt-install.patch C:\qt-src\
+
+# Qt Build i386
+FROM qt-src as qt-i386
+RUN \qt-src\qt-build.bat i386
+
+# Qt Build x86_64
+FROM qt-src as qt-x86_64
+RUN \qt-src\qt-build.bat x86_64
+
+# Output Stage
+FROM $FROM_IMAGE
+
+# Qt
+COPY --from=qt-i386 C:\qt-i386 C:\qt-i386
+COPY --from=qt-x86_64 C:\qt-x86_64 C:\qt-x86_64
+
+# WIX
+ADD https://github.com/wixtoolset/wix3/releases/download/wix3112rtm/wix311-binaries.zip C:\wix\wix.zip
+RUN cd \wix `
+ && powershell -Command " `
+    if ($(Get-FileHash wix.zip).Hash -eq '2c1888d5d1dba377fc7fa14444cf556963747ff9a0a289a3599cf09da03b9e2e') {`
+      Expand-Archive -Path wix.zip -DestinationPath .`
+    } else {`
+      exit 1 `
+    }" `
+ && del wix.zip
+
+# Python and Sphinx
+ADD https://www.python.org/ftp/python/3.8.2/python-3.8.2-embed-amd64.zip C:\python3\python3.zip
+RUN cd \python3 `
+ && powershell -Command " `
+    if ($(Get-FileHash python3.zip).Hash -eq '2927a3a6d0fe1f6e047a86059220aeda374eed23113b9ef5355acb8452d56453') {`
+      Expand-Archive -Path python3.zip -DestinationPath .`
+    } else {`
+      exit 1 `
+    }" `
+ && del python3.zip `
+ && curl -O https://bootstrap.pypa.io/get-pip.py `
+ && python get-pip.py `
+ && del python38._pth `
+ && set "PY_LIBS=C:\python3\Lib;C:\Python3\Lib\site-packages" `
+ && set "PY_PIP=C:\python3\Scripts" `
+ && Scripts\pip install --no-warn-script-location sphinx==2.1.2
+
+# Ninja
+ADD https://github.com/ninja-build/ninja/releases/download/v1.10.0/ninja-win.zip C:\ninja\ninja.zip
+RUN cd \ninja `
+ && powershell -Command " `
+    if ($(Get-FileHash ninja.zip).Hash -eq '919fd158c16bf135e8a850bb4046ec1ce28a7439ee08b977cd0b7f6b3463d178') {`
+      Expand-Archive -Path ninja.zip -DestinationPath .`
+    } else {`
+      exit 1 `
+    }" `
+ && del ninja.zip
+
+# CMake
+ADD https://github.com/Kitware/CMake/releases/download/v3.17.1/cmake-3.17.1-win64-x64.zip C:\cmake\cmake.zip
+RUN cd \cmake `
+ && powershell -Command " `
+    if ($(Get-FileHash cmake.zip).Hash -eq 'a5af7a2fe73f34070456397e940042e4469f072126c82974f44333ac43d478b1') {`
+      Expand-Archive -Path cmake.zip -DestinationPath .`
+    } else {`
+      exit 1 `
+    }" `
+ && move cmake-*-win64-x64 cmake `
+ && del cmake.zip
diff --git a/Utilities/Release/win/x86/deps/qt-build.bat b/Utilities/Release/win/x86/deps/qt-build.bat
new file mode 100755
index 0000000..e8bfa81
--- /dev/null
+++ b/Utilities/Release/win/x86/deps/qt-build.bat
@@ -0,0 +1,47 @@
+set ARCH=%1
+call \msvc-%ARCH%.bat && @echo on || exit /b
+mkdir \qt-src\qt-build && ^
+cd \qt-src\qt-build && ^
+..\qt\configure.bat ^
+  -prefix C:/qt-%ARCH% ^
+  -static ^
+  -static-runtime ^
+  -release ^
+  -opensource -confirm-license ^
+  -platform win32-msvc ^
+  -mp ^
+  -gui ^
+  -widgets ^
+  -qt-pcre ^
+  -qt-zlib ^
+  -qt-libpng ^
+  -qt-libjpeg ^
+  -no-gif ^
+  -no-icu ^
+  -no-pch ^
+  -no-angle ^
+  -no-opengl ^
+  -no-dbus ^
+  -no-harfbuzz ^
+  -no-accessibility ^
+  -skip declarative ^
+  -skip multimedia ^
+  -skip qtcanvas3d ^
+  -skip qtconnectivity ^
+  -skip qtdeclarative ^
+  -skip qtlocation ^
+  -skip qtmultimedia ^
+  -skip qtsensors ^
+  -skip qtserialport ^
+  -skip qtsvg ^
+  -skip qtwayland ^
+  -skip qtwebchannel ^
+  -skip qtwebengine ^
+  -skip qtwebsockets ^
+  -skip qtxmlpatterns ^
+  -nomake examples -nomake tests ^
+  && ^
+\jom\jom.exe -J %NUMBER_OF_PROCESSORS% && ^
+\jom\jom.exe install && ^
+cd \qt-%ARCH% && ^
+\git\cmd\git apply \qt-src\qt-install.patch
diff --git a/Utilities/Release/win/x86/deps/qt-install.patch b/Utilities/Release/win/x86/deps/qt-install.patch
new file mode 100644
index 0000000..39a649e
--- /dev/null
+++ b/Utilities/Release/win/x86/deps/qt-install.patch
@@ -0,0 +1,26 @@
+diff --git a/lib/cmake/Qt5Core/Qt5CoreConfig.cmake b/lib/cmake/Qt5Core/Qt5CoreConfig.cmake
+index 04ec302..75d5596 100644
+--- a/lib/cmake/Qt5Core/Qt5CoreConfig.cmake
++++ b/lib/cmake/Qt5Core/Qt5CoreConfig.cmake
+@@ -118,7 +118,7 @@ if (NOT TARGET Qt5::Core)
+     list(REMOVE_DUPLICATES Qt5Core_COMPILE_DEFINITIONS)
+     list(REMOVE_DUPLICATES Qt5Core_EXECUTABLE_COMPILE_FLAGS)
+ 
+-    set(_Qt5Core_LIB_DEPENDENCIES "")
++    set(_Qt5Core_LIB_DEPENDENCIES "${_qt5Core_install_prefix}/lib/qtpcre2.lib;netapi32.lib;version.lib")
+ 
+ 
+     add_library(Qt5::Core STATIC IMPORTED)
+diff --git a/lib/cmake/Qt5Widgets/Qt5WidgetsConfig.cmake b/lib/cmake/Qt5Widgets/Qt5WidgetsConfig.cmake
+index a07b953..2e07371 100644
+--- a/lib/cmake/Qt5Widgets/Qt5WidgetsConfig.cmake
++++ b/lib/cmake/Qt5Widgets/Qt5WidgetsConfig.cmake
+@@ -118,7 +118,7 @@ if (NOT TARGET Qt5::Widgets)
+     list(REMOVE_DUPLICATES Qt5Widgets_COMPILE_DEFINITIONS)
+     list(REMOVE_DUPLICATES Qt5Widgets_EXECUTABLE_COMPILE_FLAGS)
+ 
+-    set(_Qt5Widgets_LIB_DEPENDENCIES "Qt5::Gui;Qt5::Core")
++    set(_Qt5Widgets_LIB_DEPENDENCIES "Qt5::Gui;Qt5::Core;dwmapi.lib;uxtheme.lib")
+ 
+ 
+     add_library(Qt5::Widgets STATIC IMPORTED)
diff --git a/Utilities/Release/win/x86/pack.bat b/Utilities/Release/win/x86/pack.bat
new file mode 100755
index 0000000..2d37eef
--- /dev/null
+++ b/Utilities/Release/win/x86/pack.bat
@@ -0,0 +1,12 @@
+@rem Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
+@rem file Copyright.txt or https://cmake.org/licensing for details.
+
+call \msvc.bat && @echo on || exit /b
+set PATH=C:\wix;C:\ninja;%PATH%
+cd \cmake\src\cmake-build && (
+  for %%p in (%*) do (
+    bin\cpack -G %%p
+  )
+) && ^
+mkdir \out && ^
+move cmake-*-win* \out
diff --git a/Utilities/Release/win/x86/test/Dockerfile b/Utilities/Release/win/x86/test/Dockerfile
new file mode 100644
index 0000000..15bcd37
--- /dev/null
+++ b/Utilities/Release/win/x86/test/Dockerfile
@@ -0,0 +1,37 @@
+# escape=`
+
+# Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
+# file Copyright.txt or https://cmake.org/licensing for details.
+
+# Produce a base image with a test environment for packaged CMake binaries.
+# Build using the directory containing this file as its own build context.
+
+ARG FROM_IMAGE_NAME=kitware/cmake:build-win-x86-base-2020-04-27
+ARG FROM_IMAGE_DIGEST=@sha256:c5a8948d636319cdac0180266996558bb6fb037125792b5b837f069d02e53d7c
+ARG FROM_IMAGE=$FROM_IMAGE_NAME$FROM_IMAGE_DIGEST
+FROM $FROM_IMAGE
+
+# Python
+ADD https://www.python.org/ftp/python/3.8.2/python-3.8.2-embed-amd64.zip C:\python3\python3.zip
+RUN cd \python3 `
+ && powershell -Command " `
+    if ($(Get-FileHash python3.zip).Hash -eq '2927a3a6d0fe1f6e047a86059220aeda374eed23113b9ef5355acb8452d56453') {`
+      Expand-Archive -Path python3.zip -DestinationPath .`
+    } else {`
+      exit 1 `
+    }" `
+ && del python3.zip `
+ && del python38._pth
+
+# Ninja
+ADD https://github.com/ninja-build/ninja/releases/download/v1.10.0/ninja-win.zip C:\ninja\ninja.zip
+RUN cd \ninja `
+ && powershell -Command " `
+    if ($(Get-FileHash ninja.zip).Hash -eq '919fd158c16bf135e8a850bb4046ec1ce28a7439ee08b977cd0b7f6b3463d178') {`
+      Expand-Archive -Path ninja.zip -DestinationPath .`
+    } else {`
+      exit 1 `
+    }" `
+ && del ninja.zip
+
+COPY test-nmake.bat test-ninja.bat C:\
diff --git a/Utilities/Release/win/x86/test/test-ninja.bat b/Utilities/Release/win/x86/test/test-ninja.bat
new file mode 100755
index 0000000..b8347ef
--- /dev/null
+++ b/Utilities/Release/win/x86/test/test-ninja.bat
@@ -0,0 +1,19 @@
+@rem Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
+@rem file Copyright.txt or https://cmake.org/licensing for details.
+
+set ARCH=%1
+call \msvc-%ARCH%.bat && @echo on || exit /b
+set "PATH=C:\cmake\cmake\bin;C:\ninja;C:\python3;%PATH%"
+mkdir \cmake\src\cmake-ninja && ^
+cd \cmake\src\cmake-ninja && ^
+> CMakeCache.txt (
+  @echo CMAKE_Fortran_COMPILER:STRING=
+  @echo CMAKE_Swift_COMPILER:STRING=
+  @echo CMake_TEST_IPO_WORKS_C:BOOL=ON
+  @echo CMake_TEST_IPO_WORKS_CXX:BOOL=ON
+  @echo CMake_TEST_NO_NETWORK:BOOL=ON
+  @echo CTEST_RUN_MFC:BOOL=OFF
+) && ^
+cmake ..\cmake -DCMake_TEST_HOST_CMAKE=1 -G "Ninja" && ^
+ninja && ^
+ctest --output-on-failure -j %NUMBER_OF_PROCESSORS%
diff --git a/Utilities/Release/win/x86/test/test-nmake.bat b/Utilities/Release/win/x86/test/test-nmake.bat
new file mode 100755
index 0000000..5008711
--- /dev/null
+++ b/Utilities/Release/win/x86/test/test-nmake.bat
@@ -0,0 +1,19 @@
+@rem Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
+@rem file Copyright.txt or https://cmake.org/licensing for details.
+
+set ARCH=%1
+call \msvc-%ARCH%.bat && @echo on || exit /b
+set "PATH=C:\cmake\cmake\bin;C:\python3;%PATH%"
+mkdir \cmake\src\cmake-nmake && ^
+cd \cmake\src\cmake-nmake && ^
+> CMakeCache.txt (
+  @echo CMAKE_Fortran_COMPILER:STRING=
+  @echo CMAKE_Swift_COMPILER:STRING=
+  @echo CMake_TEST_IPO_WORKS_C:BOOL=ON
+  @echo CMake_TEST_IPO_WORKS_CXX:BOOL=ON
+  @echo CMake_TEST_NO_NETWORK:BOOL=ON
+  @echo CTEST_RUN_MFC:BOOL=OFF
+) && ^
+cmake ..\cmake -DCMake_TEST_HOST_CMAKE=1 -G "NMake Makefiles" && ^
+nmake && ^
+ctest --output-on-failure -j %NUMBER_OF_PROCESSORS%
diff --git a/Utilities/Release/win32_release.cmake b/Utilities/Release/win32_release.cmake
deleted file mode 100644
index 14e5cba..0000000
--- a/Utilities/Release/win32_release.cmake
+++ /dev/null
@@ -1,52 +0,0 @@
-set(CMAKE_RELEASE_DIRECTORY "c:/msys64/home/dashboard/CMakeReleaseDirectory32")
-set(CONFIGURE_WITH_CMAKE TRUE)
-set(CMAKE_CONFIGURE_PATH "c:/Program\\ Files/CMake/bin/cmake.exe")
-set(PROCESSORS 16)
-set(HOST win32)
-set(RUN_LAUNCHER ~/rel/run)
-set(CPACK_BINARY_GENERATORS "WIX ZIP")
-set(CPACK_SOURCE_GENERATORS "")
-set(MAKE_PROGRAM "ninja")
-set(MAKE "${MAKE_PROGRAM} -j16")
-set(qt_prefix "c:/Qt/5.12.1/msvc2017-32-w7-mt")
-set(qt_win_libs
-  ${qt_prefix}/plugins/platforms/qwindows.lib
-  ${qt_prefix}/plugins/styles/qwindowsvistastyle.lib
-  ${qt_prefix}/lib/Qt5EventDispatcherSupport.lib
-  ${qt_prefix}/lib/Qt5FontDatabaseSupport.lib
-  ${qt_prefix}/lib/Qt5ThemeSupport.lib
-  ${qt_prefix}/lib/qtfreetype.lib
-  ${qt_prefix}/lib/qtlibpng.lib
-  imm32.lib
-  wtsapi32.lib
-  )
-set(INITIAL_CACHE "CMAKE_BUILD_TYPE:STRING=Release
-CMAKE_DOC_DIR:STRING=doc/cmake
-CMAKE_USE_OPENSSL:BOOL=OFF
-CMAKE_SKIP_BOOTSTRAP_TEST:STRING=TRUE
-CMAKE_Fortran_COMPILER:FILEPATH=FALSE
-CMAKE_GENERATOR:INTERNAL=Ninja
-BUILD_QtDialog:BOOL=TRUE
-CMake_GUI_DISTRIBUTE_WITH_Qt_LGPL:STRING=3
-CMAKE_MSVC_RUNTIME_LIBRARY:STRING=MultiThreaded$<$<CONFIG:Debug>:Debug>
-CMAKE_EXE_LINKER_FLAGS:STRING=-machine:x86 -subsystem:console,6.01
-CMake_QT_STATIC_QWindowsIntegrationPlugin_LIBRARIES:STRING=${qt_win_libs}
-CMAKE_PREFIX_PATH:STRING=${qt_prefix}
-CMake_TEST_Qt4:BOOL=OFF
-CMake_TEST_Qt5:BOOL=OFF
-")
-set(ppflags "-D_WIN32_WINNT=0x601 -DNTDDI_VERSION=0x06010000")
-set(CFLAGS "${ppflags}")
-set(CXXFLAGS "${ppflags}")
-set(ENV ". ~/rel/env32")
-get_filename_component(path "${CMAKE_CURRENT_LIST_FILE}" PATH)
-set(GIT_EXTRA "git config core.autocrlf true")
-if(CMAKE_CREATE_VERSION STREQUAL "nightly")
-  # Some tests fail spuriously too often.
-  set(EXTRA_CTEST_ARGS "-E 'ConsoleBuf|Module.ExternalData'")
-  set(SIGN "")
-else()
-  string(APPEND INITIAL_CACHE "CMake_INSTALL_SIGNTOOL:STRING=signtool\n")
-  set(SIGN [[signtool sign -v -a -tr http://timestamp.digicert.com -fd sha256 -td sha256 -d "CMake Windows Installer" cmake-*.msi]])
-endif()
-include(${path}/release_cmake.cmake)
diff --git a/Utilities/Release/win64_release.cmake b/Utilities/Release/win64_release.cmake
deleted file mode 100644
index 149d378..0000000
--- a/Utilities/Release/win64_release.cmake
+++ /dev/null
@@ -1,52 +0,0 @@
-set(CMAKE_RELEASE_DIRECTORY "c:/msys64/home/dashboard/CMakeReleaseDirectory64")
-set(CONFIGURE_WITH_CMAKE TRUE)
-set(CMAKE_CONFIGURE_PATH "c:/Program\\ Files/CMake/bin/cmake.exe")
-set(PROCESSORS 16)
-set(HOST win64)
-set(RUN_LAUNCHER ~/rel/run)
-set(CPACK_BINARY_GENERATORS "WIX ZIP")
-set(CPACK_SOURCE_GENERATORS "")
-set(MAKE_PROGRAM "ninja")
-set(MAKE "${MAKE_PROGRAM} -j16")
-set(qt_prefix "c:/Qt/5.12.1/msvc2017-64-w7-mt")
-set(qt_win_libs
-  ${qt_prefix}/plugins/platforms/qwindows.lib
-  ${qt_prefix}/plugins/styles/qwindowsvistastyle.lib
-  ${qt_prefix}/lib/Qt5EventDispatcherSupport.lib
-  ${qt_prefix}/lib/Qt5FontDatabaseSupport.lib
-  ${qt_prefix}/lib/Qt5ThemeSupport.lib
-  ${qt_prefix}/lib/qtfreetype.lib
-  ${qt_prefix}/lib/qtlibpng.lib
-  imm32.lib
-  wtsapi32.lib
-  )
-set(INITIAL_CACHE "CMAKE_BUILD_TYPE:STRING=Release
-CMAKE_DOC_DIR:STRING=doc/cmake
-CMAKE_USE_OPENSSL:BOOL=OFF
-CMAKE_SKIP_BOOTSTRAP_TEST:STRING=TRUE
-CMAKE_Fortran_COMPILER:FILEPATH=FALSE
-CMAKE_GENERATOR:INTERNAL=Ninja
-BUILD_QtDialog:BOOL=TRUE
-CMake_GUI_DISTRIBUTE_WITH_Qt_LGPL:STRING=3
-CMAKE_MSVC_RUNTIME_LIBRARY:STRING=MultiThreaded$<$<CONFIG:Debug>:Debug>
-CMAKE_EXE_LINKER_FLAGS:STRING=-machine:x64 -subsystem:console,6.01
-CMake_QT_STATIC_QWindowsIntegrationPlugin_LIBRARIES:STRING=${qt_win_libs}
-CMAKE_PREFIX_PATH:STRING=${qt_prefix}
-CMake_TEST_Qt4:BOOL=OFF
-CMake_TEST_Qt5:BOOL=OFF
-")
-set(ppflags "-D_WIN32_WINNT=0x601 -DNTDDI_VERSION=0x06010000")
-set(CFLAGS "${ppflags}")
-set(CXXFLAGS "${ppflags}")
-set(ENV ". ~/rel/env64")
-get_filename_component(path "${CMAKE_CURRENT_LIST_FILE}" PATH)
-set(GIT_EXTRA "git config core.autocrlf true")
-if(CMAKE_CREATE_VERSION STREQUAL "nightly")
-  # Some tests fail spuriously too often.
-  set(EXTRA_CTEST_ARGS "-E 'ConsoleBuf|Module.ExternalData'")
-  set(SIGN "")
-else()
-  string(APPEND INITIAL_CACHE "CMake_INSTALL_SIGNTOOL:STRING=signtool\n")
-  set(SIGN [[signtool sign -v -a -tr http://timestamp.digicert.com -fd sha256 -td sha256 -d "CMake Windows Installer" cmake-*.msi]])
-endif()
-include(${path}/release_cmake.cmake)
diff --git a/Utilities/Scripts/update-bzip2.bash b/Utilities/Scripts/update-bzip2.bash
new file mode 100755
index 0000000..83439d1
--- /dev/null
+++ b/Utilities/Scripts/update-bzip2.bash
@@ -0,0 +1,27 @@
+#!/usr/bin/env bash
+
+set -e
+set -x
+shopt -s dotglob
+
+readonly name="bzip2"
+readonly ownership="bzip2 upstream <kwrobot@kitware.com>"
+readonly subtree="Utilities/cmbzip2"
+readonly repo="https://sourceware.org/git/bzip2.git"
+readonly tag="bzip2-1.0.8"
+readonly shortlog=false
+readonly paths="
+  LICENSE
+  README
+  *.c
+  *.h
+"
+
+extract_source () {
+    git_archive
+    pushd "${extractdir}/${name}-reduced"
+    echo "* -whitespace" > .gitattributes
+    popd
+}
+
+. "${BASH_SOURCE%/*}/update-third-party.bash"
diff --git a/Utilities/Scripts/update-curl.bash b/Utilities/Scripts/update-curl.bash
index 5c2a331..67e2728 100755
--- a/Utilities/Scripts/update-curl.bash
+++ b/Utilities/Scripts/update-curl.bash
@@ -8,7 +8,7 @@
 readonly ownership="Curl Upstream <curl-library@cool.haxx.se>"
 readonly subtree="Utilities/cmcurl"
 readonly repo="https://github.com/curl/curl.git"
-readonly tag="curl-7_65_0"
+readonly tag="curl-7_71_1"
 readonly shortlog=false
 readonly paths="
   CMake/*
@@ -23,6 +23,10 @@
   lib/libcurl.rc
   lib/vauth/*.c
   lib/vauth/*.h
+  lib/vquic/*.c
+  lib/vquic/*.h
+  lib/vssh/*.c
+  lib/vssh/*.h
   lib/vtls/*.c
   lib/vtls/*.h
 "
diff --git a/Utilities/Scripts/update-libarchive.bash b/Utilities/Scripts/update-libarchive.bash
index 3188658..3db89ff 100755
--- a/Utilities/Scripts/update-libarchive.bash
+++ b/Utilities/Scripts/update-libarchive.bash
@@ -8,7 +8,7 @@
 readonly ownership="LibArchive Upstream <libarchive-discuss@googlegroups.com>"
 readonly subtree="Utilities/cmlibarchive"
 readonly repo="https://github.com/libarchive/libarchive.git"
-readonly tag="v3.3.3"
+readonly tag="v3.4.2"
 readonly shortlog=false
 readonly paths="
   CMakeLists.txt
@@ -25,6 +25,7 @@
     git_archive
     pushd "${extractdir}/${name}-reduced"
     fromdos build/cmake/Find*.cmake
+    echo "* -whitespace" > .gitattributes
     popd
 }
 
diff --git a/Utilities/Scripts/update-librhash.bash b/Utilities/Scripts/update-librhash.bash
index 009ce32..ea7e655 100755
--- a/Utilities/Scripts/update-librhash.bash
+++ b/Utilities/Scripts/update-librhash.bash
@@ -8,11 +8,10 @@
 readonly ownership="librhash upstream <kwrobot@kitware.com>"
 readonly subtree="Utilities/cmlibrhash"
 readonly repo="https://github.com/rhash/rhash.git"
-readonly tag="master"
+readonly tag="v1.3.9"
 readonly shortlog=false
 readonly paths="
   COPYING
-  README
   librhash/algorithms.c
   librhash/algorithms.h
   librhash/byte_order.c
diff --git a/Utilities/Scripts/update-nghttp2.bash b/Utilities/Scripts/update-nghttp2.bash
new file mode 100755
index 0000000..07a8f13
--- /dev/null
+++ b/Utilities/Scripts/update-nghttp2.bash
@@ -0,0 +1,30 @@
+#!/usr/bin/env bash
+
+set -e
+set -x
+shopt -s dotglob
+
+readonly name="nghttp2"
+readonly ownership="nghttp2 upstream <kwrobot@kitware.com>"
+readonly subtree="Utilities/cmnghttp2"
+readonly repo="https://github.com/nghttp2/nghttp2.git"
+readonly tag="v1.40.0"
+readonly shortlog=false
+readonly paths="
+  COPYING
+  lib/*.c
+  lib/*.h
+  lib/includes/nghttp2/nghttp2.h
+  lib/includes/nghttp2/nghttp2ver.h.in
+"
+
+extract_source () {
+    git_archive
+    pushd "${extractdir}/${name}-reduced"
+    echo "* -whitespace" > .gitattributes
+    mv lib/includes/nghttp2/nghttp2ver.h.in lib/includes/nghttp2/nghttp2ver.h
+    sed -i 's/@PACKAGE_VERSION@/1.40.0/;s/@PACKAGE_VERSION_NUM@/0x012800/' lib/includes/nghttp2/nghttp2ver.h
+    popd
+}
+
+. "${BASH_SOURCE%/*}/update-third-party.bash"
diff --git a/Utilities/Sphinx/CMakeLists.txt b/Utilities/Sphinx/CMakeLists.txt
index 17c5018..e5be43a 100644
--- a/Utilities/Sphinx/CMakeLists.txt
+++ b/Utilities/Sphinx/CMakeLists.txt
@@ -89,7 +89,7 @@
   find_package(PythonInterp REQUIRED)
 
   find_program(QCOLLECTIONGENERATOR_EXECUTABLE
-    NAMES qcollectiongenerator
+    NAMES qcollectiongenerator-qt5 qcollectiongenerator
     DOC "qcollectiongenerator tool"
     )
   if (NOT QCOLLECTIONGENERATOR_EXECUTABLE)
diff --git a/Utilities/Sphinx/CTestConfig.cmake b/Utilities/Sphinx/CTestConfig.cmake
new file mode 100644
index 0000000..e5f4260
--- /dev/null
+++ b/Utilities/Sphinx/CTestConfig.cmake
@@ -0,0 +1,16 @@
+# Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
+# file Copyright.txt or https://cmake.org/licensing for details.
+
+# If changing this file, also update CTestConfig.cmake
+
+set(CTEST_PROJECT_NAME "CMake")
+set(CTEST_NIGHTLY_START_TIME "1:00:00 UTC")
+
+if(NOT CTEST_DROP_METHOD STREQUAL "https")
+  set(CTEST_DROP_METHOD "http")
+endif()
+set(CTEST_DROP_SITE "open.cdash.org")
+set(CTEST_DROP_LOCATION "/submit.php?project=CMake")
+set(CTEST_DROP_SITE_CDASH TRUE)
+set(CTEST_CDASH_VERSION "1.6")
+set(CTEST_CDASH_QUERY_VERSION TRUE)
diff --git a/Utilities/Sphinx/create_identifiers.py b/Utilities/Sphinx/create_identifiers.py
index b5cd914..e35f127 100755
--- a/Utilities/Sphinx/create_identifiers.py
+++ b/Utilities/Sphinx/create_identifiers.py
@@ -1,17 +1,17 @@
 #!/usr/bin/env python
 
-import sys, os
+import sys
 
 if len(sys.argv) != 2:
   sys.exit(-1)
 name = sys.argv[1] + "/CMake.qhp"
 
-f = open(name)
+f = open(name, "rb")
 
 if not f:
   sys.exit(-1)
 
-lines = f.read().splitlines()
+lines = f.read().decode("utf-8").splitlines()
 
 if not lines:
   sys.exit(-1)
@@ -38,7 +38,7 @@
 
   for domain_object_string, domain_object_type in mapping:
     if "<keyword name=\"" + domain_object_string + "\"" in line:
-      if not "id=\"" in line and not "#index-" in line:
+      if "id=\"" not in line and "#index-" not in line:
         prefix = "<keyword name=\"" + domain_object_string + "\" "
         part1, part2 = line.split(prefix)
         head, tail = part2.split("#" + domain_object_type + ":")
@@ -46,5 +46,5 @@
         line = part1 + prefix + "id=\"" + domain_object_type + "/" + domain_object + "\" " + part2
   newlines.append(line + "\n")
 
-f = open(name, "w")
-f.writelines(newlines)
+f = open(name, "wb")
+f.writelines(map(lambda line: line.encode("utf-8"), newlines))
diff --git a/Utilities/Sphinx/update_versions.py b/Utilities/Sphinx/update_versions.py
new file mode 100755
index 0000000..893e7a7
--- /dev/null
+++ b/Utilities/Sphinx/update_versions.py
@@ -0,0 +1,115 @@
+#!/usr/bin/env python3
+"""
+This script inserts "versionadded" directive into every .rst document
+and every .cmake module with .rst documentation comment.
+"""
+import re
+import pathlib
+import subprocess
+import argparse
+
+tag_re = re.compile(r'^v3\.(\d+)\.(\d+)(?:-rc(\d+))?$')
+path_re = re.compile(r'Help/(?!dev|guide|manual|cpack_|release).*\.rst|Modules/[^/]*\.cmake$')
+
+def git_root():
+    result = subprocess.run(
+        ['git', 'rev-parse', '--show-toplevel'], check=True, universal_newlines=True, capture_output=True)
+    return pathlib.Path(result.stdout.strip())
+
+def git_tags():
+    result = subprocess.run(['git', 'tag'], check=True, universal_newlines=True, capture_output=True)
+    return [tag for tag in result.stdout.splitlines() if tag_re.match(tag)]
+
+def git_list_tree(ref):
+    result = subprocess.run(
+        ['git', 'ls-tree', '-r', '--full-name', '--name-only', ref, ':/'],
+        check=True, universal_newlines=True, capture_output=True)
+    return [path for path in result.stdout.splitlines() if path_re.match(path)]
+
+def tag_version(tag):
+    return re.sub(r'^v|\.0(-rc\d+)?$', '', tag)
+
+def tag_sortkey(tag):
+    return tuple(int(part or '1000') for part in tag_re.match(tag).groups())
+
+def make_version_map(baseline, since, next_version):
+    versions = {}
+    if next_version:
+        for path in git_list_tree('HEAD'):
+            versions[path] = next_version
+    for tag in sorted(git_tags(), key=tag_sortkey, reverse=True):
+        version = tag_version(tag)
+        for path in git_list_tree(tag):
+            versions[path] = version
+    if baseline:
+        for path in git_list_tree(baseline):
+            versions[path] = None
+    if since:
+        for path in git_list_tree(since):
+            versions.pop(path, None)
+    return versions
+
+cmake_version_re = re.compile(
+    rb'set\(CMake_VERSION_MAJOR\s+(\d+)\)\s+set\(CMake_VERSION_MINOR\s+(\d+)\)\s+set\(CMake_VERSION_PATCH\s+(\d+)\)', re.S)
+
+def cmake_version(path):
+    match = cmake_version_re.search(path.read_bytes())
+    major, minor, patch = map(int, match.groups())
+    minor += patch > 20000000
+    return f'{major}.{minor}'
+
+stamp_re = re.compile(
+    rb'(?P<PREFIX>(^|\[\.rst:\r?\n)[^\r\n]+\r?\n[*^\-=#]+(?P<NL>\r?\n))(?P<STAMP>\s*\.\. versionadded::[^\r\n]*\r?\n)?')
+stamp_pattern_add = rb'\g<PREFIX>\g<NL>.. versionadded:: VERSION\g<NL>'
+stamp_pattern_remove = rb'\g<PREFIX>'
+
+def update_file(path, version, overwrite):
+    try:
+        data = path.read_bytes()
+    except FileNotFoundError as e:
+        return False
+
+    def _replacement(match):
+        if not overwrite and match.start('STAMP') != -1:
+            return match.group()
+        if version:
+            pattern = stamp_pattern_add.replace(b'VERSION', version.encode('utf-8'))
+        else:
+            pattern = stamp_pattern_remove
+        return match.expand(pattern)
+
+    new_data, nrepl = stamp_re.subn(_replacement, data, 1)
+    if nrepl and new_data != data:
+        path.write_bytes(new_data)
+        return True
+    return False
+
+def update_repo(repo_root, version_map, overwrite):
+    total = 0
+    for path, version in version_map.items():
+        if update_file(repo_root / path, version, overwrite):
+            print(f"Version {version or '<none>':6} for {path}")
+            total += 1
+    print(f"Updated {total} file(s)")
+
+def main():
+    parser = argparse.ArgumentParser(allow_abbrev=False)
+    parser.add_argument('--overwrite', action='store_true', help="overwrite existing version tags")
+    parser.add_argument('--baseline', metavar='TAG', default='v3.0.0',
+        help="files present in this tag won't be stamped (default: v3.0.0)")
+    parser.add_argument('--since', metavar='TAG',
+        help="apply changes only to files added after this tag")
+    parser.add_argument('--next-version', metavar='VER',
+        help="version for files not present in any tag (default: from CMakeVersion.cmake)")
+    args = parser.parse_args()
+
+    try:
+        repo_root = git_root()
+        next_version = args.next_version or cmake_version(repo_root / 'Source/CMakeVersion.cmake')
+        version_map = make_version_map(args.baseline, args.since, next_version)
+        update_repo(repo_root, version_map, args.overwrite)
+    except subprocess.CalledProcessError as e:
+        print(f"Command '{' '.join(e.cmd)}' returned code {e.returncode}:\n{e.stderr.strip()}")
+
+if __name__ == '__main__':
+    main()
diff --git a/Utilities/cm3p/Setup.Configuration.h b/Utilities/cm3p/Setup.Configuration.h
new file mode 100644
index 0000000..a5cf058
--- /dev/null
+++ b/Utilities/cm3p/Setup.Configuration.h
@@ -0,0 +1,8 @@
+/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
+   file Copyright.txt or https://cmake.org/licensing for details.  */
+#ifndef cm3p_Setup_Configuration_h
+#define cm3p_Setup_Configuration_h
+
+#include <cmvssetup/Setup.Configuration.h> // IWYU pragma: export
+
+#endif
diff --git a/Utilities/cm3p/archive.h b/Utilities/cm3p/archive.h
new file mode 100644
index 0000000..956b3ab
--- /dev/null
+++ b/Utilities/cm3p/archive.h
@@ -0,0 +1,14 @@
+/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
+   file Copyright.txt or https://cmake.org/licensing for details.  */
+#ifndef cm3p_archive_h
+#define cm3p_archive_h
+
+/* Use the libarchive configured for CMake.  */
+#include "cmThirdParty.h"
+#ifdef CMAKE_USE_SYSTEM_LIBARCHIVE
+#  include <archive.h> // IWYU pragma: export
+#else
+#  include <cmlibarchive/libarchive/archive.h> // IWYU pragma: export
+#endif
+
+#endif
diff --git a/Utilities/cm3p/archive_entry.h b/Utilities/cm3p/archive_entry.h
new file mode 100644
index 0000000..230e87a
--- /dev/null
+++ b/Utilities/cm3p/archive_entry.h
@@ -0,0 +1,14 @@
+/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
+   file Copyright.txt or https://cmake.org/licensing for details.  */
+#ifndef cm3p_archive_entry_h
+#define cm3p_archive_entry_h
+
+/* Use the libarchive configured for CMake.  */
+#include "cmThirdParty.h"
+#ifdef CMAKE_USE_SYSTEM_LIBARCHIVE
+#  include <archive_entry.h> // IWYU pragma: export
+#else
+#  include <cmlibarchive/libarchive/archive_entry.h> // IWYU pragma: export
+#endif
+
+#endif
diff --git a/Utilities/cm3p/bzlib.h b/Utilities/cm3p/bzlib.h
new file mode 100644
index 0000000..2a0f4dd
--- /dev/null
+++ b/Utilities/cm3p/bzlib.h
@@ -0,0 +1,14 @@
+/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
+   file Copyright.txt or https://cmake.org/licensing for details.  */
+#ifndef cm3p_bzlib_h
+#define cm3p_bzlib_h
+
+/* Use the bzip2 library configured for CMake.  */
+#include "cmThirdParty.h"
+#ifdef CMAKE_USE_SYSTEM_BZIP2
+#  include <bzlib.h> // IWYU pragma: export
+#else
+#  include <cmbzip2/bzlib.h> // IWYU pragma: export
+#endif
+
+#endif
diff --git a/Utilities/cm3p/curl/curl.h b/Utilities/cm3p/curl/curl.h
new file mode 100644
index 0000000..6e2b822
--- /dev/null
+++ b/Utilities/cm3p/curl/curl.h
@@ -0,0 +1,14 @@
+/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
+   file Copyright.txt or https://cmake.org/licensing for details.  */
+#ifndef cm3p_curl_curl_h
+#define cm3p_curl_curl_h
+
+/* Use the curl library configured for CMake.  */
+#include "cmThirdParty.h"
+#ifdef CMAKE_USE_SYSTEM_CURL
+#  include <curl/curl.h> // IWYU pragma: export
+#else
+#  include <cmcurl/include/curl/curl.h> // IWYU pragma: export
+#endif
+
+#endif
diff --git a/Utilities/cm3p/expat.h b/Utilities/cm3p/expat.h
new file mode 100644
index 0000000..32e6fd0
--- /dev/null
+++ b/Utilities/cm3p/expat.h
@@ -0,0 +1,14 @@
+/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
+   file Copyright.txt or https://cmake.org/licensing for details.  */
+#ifndef cm3p_expat_h
+#define cm3p_expat_h
+
+/* Use the expat library configured for CMake.  */
+#include "cmThirdParty.h"
+#ifdef CMAKE_USE_SYSTEM_EXPAT
+#  include <expat.h> // IWYU pragma: export
+#else
+#  include <cmexpat/lib/expat.h> // IWYU pragma: export
+#endif
+
+#endif
diff --git a/Utilities/cm3p/json/reader.h b/Utilities/cm3p/json/reader.h
new file mode 100644
index 0000000..0df09ee
--- /dev/null
+++ b/Utilities/cm3p/json/reader.h
@@ -0,0 +1,14 @@
+/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
+   file Copyright.txt or https://cmake.org/licensing for details.  */
+#ifndef cm3p_json_reader_h
+#define cm3p_json_reader_h
+
+/* Use the jsoncpp library configured for CMake.  */
+#include "cmThirdParty.h"
+#ifdef CMAKE_USE_SYSTEM_JSONCPP
+#  include <json/reader.h> // IWYU pragma: export
+#else
+#  include <cmjsoncpp/include/json/reader.h> // IWYU pragma: export
+#endif
+
+#endif
diff --git a/Utilities/cm3p/json/value.h b/Utilities/cm3p/json/value.h
new file mode 100644
index 0000000..f59bed6
--- /dev/null
+++ b/Utilities/cm3p/json/value.h
@@ -0,0 +1,14 @@
+/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
+   file Copyright.txt or https://cmake.org/licensing for details.  */
+#ifndef cm3p_json_value_h
+#define cm3p_json_value_h
+
+/* Use the jsoncpp library configured for CMake.  */
+#include "cmThirdParty.h"
+#ifdef CMAKE_USE_SYSTEM_JSONCPP
+#  include <json/value.h> // IWYU pragma: export
+#else
+#  include <cmjsoncpp/include/json/value.h> // IWYU pragma: export
+#endif
+
+#endif
diff --git a/Utilities/cm3p/json/writer.h b/Utilities/cm3p/json/writer.h
new file mode 100644
index 0000000..7fcc3e2
--- /dev/null
+++ b/Utilities/cm3p/json/writer.h
@@ -0,0 +1,14 @@
+/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
+   file Copyright.txt or https://cmake.org/licensing for details.  */
+#ifndef cm3p_json_writer_h
+#define cm3p_json_writer_h
+
+/* Use the jsoncpp library configured for CMake.  */
+#include "cmThirdParty.h"
+#ifdef CMAKE_USE_SYSTEM_JSONCPP
+#  include <json/writer.h> // IWYU pragma: export
+#else
+#  include <cmjsoncpp/include/json/writer.h> // IWYU pragma: export
+#endif
+
+#endif
diff --git a/Utilities/cm3p/kwiml/abi.h b/Utilities/cm3p/kwiml/abi.h
new file mode 100644
index 0000000..6d0dedf
--- /dev/null
+++ b/Utilities/cm3p/kwiml/abi.h
@@ -0,0 +1,14 @@
+/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
+   file Copyright.txt or https://cmake.org/licensing for details.  */
+#ifndef cm3p_kwiml_abi_h
+#define cm3p_kwiml_abi_h
+
+/* Use the KWIML library configured for CMake.  */
+#include "cmThirdParty.h"
+#ifdef CMAKE_USE_SYSTEM_KWIML
+#  include <kwiml/abi.h> // IWYU pragma: export
+#else
+#  include <KWIML/include/kwiml/abi.h> // IWYU pragma: export
+#endif
+
+#endif
diff --git a/Utilities/cm3p/kwiml/int.h b/Utilities/cm3p/kwiml/int.h
new file mode 100644
index 0000000..4c7c23d
--- /dev/null
+++ b/Utilities/cm3p/kwiml/int.h
@@ -0,0 +1,14 @@
+/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
+   file Copyright.txt or https://cmake.org/licensing for details.  */
+#ifndef cm3p_kwiml_int_h
+#define cm3p_kwiml_int_h
+
+/* Use the KWIML library configured for CMake.  */
+#include "cmThirdParty.h"
+#ifdef CMAKE_USE_SYSTEM_KWIML
+#  include <kwiml/int.h> // IWYU pragma: export
+#else
+#  include <KWIML/include/kwiml/int.h> // IWYU pragma: export
+#endif
+
+#endif
diff --git a/Utilities/cm3p/lzma.h b/Utilities/cm3p/lzma.h
new file mode 100644
index 0000000..abfacf3
--- /dev/null
+++ b/Utilities/cm3p/lzma.h
@@ -0,0 +1,14 @@
+/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
+   file Copyright.txt or https://cmake.org/licensing for details.  */
+#ifndef cm3p_lzma_h
+#define cm3p_lzma_h
+
+/* Use the liblzma configured for CMake.  */
+#include "cmThirdParty.h"
+#ifdef CMAKE_USE_SYSTEM_LIBLZMA
+#  include <lzma.h> // IWYU pragma: export
+#else
+#  include <cmliblzma/liblzma/api/lzma.h> // IWYU pragma: export
+#endif
+
+#endif
diff --git a/Utilities/cm3p/rhash.h b/Utilities/cm3p/rhash.h
new file mode 100644
index 0000000..9d5e411
--- /dev/null
+++ b/Utilities/cm3p/rhash.h
@@ -0,0 +1,14 @@
+/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
+   file Copyright.txt or https://cmake.org/licensing for details.  */
+#ifndef cm3p_rhash_h
+#define cm3p_rhash_h
+
+/* Use the LibRHash library configured for CMake.  */
+#include "cmThirdParty.h"
+#ifdef CMAKE_USE_SYSTEM_LIBRHASH
+#  include <rhash.h> // IWYU pragma: export
+#else
+#  include <cmlibrhash/librhash/rhash.h> // IWYU pragma: export
+#endif
+
+#endif
diff --git a/Utilities/cm3p/uv.h b/Utilities/cm3p/uv.h
new file mode 100644
index 0000000..307a09f
--- /dev/null
+++ b/Utilities/cm3p/uv.h
@@ -0,0 +1,14 @@
+/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
+   file Copyright.txt or https://cmake.org/licensing for details.  */
+#ifndef cm3p_uv_h
+#define cm3p_uv_h
+
+/* Use the libuv library configured for CMake.  */
+#include "cmThirdParty.h"
+#ifdef CMAKE_USE_SYSTEM_LIBUV
+#  include <uv.h> // IWYU pragma: export
+#else
+#  include <cmlibuv/include/uv.h> // IWYU pragma: export
+#endif
+
+#endif
diff --git a/Utilities/cm3p/zlib.h b/Utilities/cm3p/zlib.h
new file mode 100644
index 0000000..fe7baee
--- /dev/null
+++ b/Utilities/cm3p/zlib.h
@@ -0,0 +1,14 @@
+/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
+   file Copyright.txt or https://cmake.org/licensing for details.  */
+#ifndef cm3p_zlib_h
+#define cm3p_zlib_h
+
+/* Use the zlib library configured for CMake.  */
+#include "cmThirdParty.h"
+#ifdef CMAKE_USE_SYSTEM_ZLIB
+#  include <zlib.h> // IWYU pragma: export
+#else
+#  include <cmzlib/zlib.h> // IWYU pragma: export
+#endif
+
+#endif
diff --git a/Utilities/cm3p/zstd.h b/Utilities/cm3p/zstd.h
new file mode 100644
index 0000000..07cc3e4
--- /dev/null
+++ b/Utilities/cm3p/zstd.h
@@ -0,0 +1,14 @@
+/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
+   file Copyright.txt or https://cmake.org/licensing for details.  */
+#ifndef cm3p_zstd_h
+#define cm3p_zstd_h
+
+/* Use the libzstd configured for CMake.  */
+#include "cmThirdParty.h"
+#ifdef CMAKE_USE_SYSTEM_ZSTD
+#  include <zstd.h> // IWYU pragma: export
+#else
+#  include <cmzstd/lib/zstd.h> // IWYU pragma: export
+#endif
+
+#endif
diff --git a/Utilities/cmThirdPartyChecks.cmake b/Utilities/cmThirdPartyChecks.cmake
new file mode 100644
index 0000000..4ccfdfc
--- /dev/null
+++ b/Utilities/cmThirdPartyChecks.cmake
@@ -0,0 +1,296 @@
+# Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
+# file Copyright.txt or https://cmake.org/licensing for details.
+
+# Hard-code third-party try_compile checks where we know the answer.
+
+# Results for builds targeting all supported platforms.
+set(HAVE_ASSERT_H 1)
+set(HAVE__CrtSetReportMode 0) # unused anyway
+set(HAVE_CTYPE_H 1)
+set(HAVE_LOCALE_H 1)
+set(HAVE_MEMMOVE 1)
+set(HAVE_SETLOCALE 1)
+set(HAVE_STDDEF_H 1)
+set(HAVE_STDIO_H 1)
+set(HAVE_STDLIB_H 1)
+set(HAVE_STRCHR 1)
+set(HAVE_STRDUP 1)
+set(HAVE_STRFTIME 1)
+set(HAVE_STRING_H 1)
+set(HAVE_STRRCHR 1)
+set(HAVE_WCHAR_H 1)
+
+# Used by TEST_BIG_ENDIAN.
+set(CMAKE_SIZEOF_UNSIGNED_SHORT 2)
+set(HAVE_CMAKE_SIZEOF_UNSIGNED_SHORT 1)
+
+if(WIN32)
+  # Results for builds targeting Windows platforms.
+  # This covers both MSVC-ABI and GNU-ABI toolchains.
+
+  set(HAVE_ALARM 0)
+  set(HAVE_ARC4RANDOM 0)
+  set(HAVE_ARC4RANDOM_BUF 0)
+  set(HAVE_ARPA_TFTP_H 0)
+  set(HAVE_BSWAP_16 0)
+  set(HAVE_BSWAP_32 0)
+  set(HAVE_BSWAP_64 0)
+  set(HAVE_BUILTIN_AVAILABLE 0)
+  set(HAVE_BYTESWAP_H 0)
+  set(HAVE_CHFLAGS 0)
+  set(HAVE_CHOWN 0)
+  set(HAVE_CHROOT 0)
+  set(HAVE_COPYFILE_H 0)
+  set(HAVE_CRYPTO_H 0)
+  set(HAVE__CTIME64_S 1)
+  set(HAVE_CTIME_R 0)
+  set(HAVE_CYGWIN_CONV_PATH 0)
+  set(HAVE_DES_H 0)
+  set(HAVE_DIRECT_H 1)
+  set(HAVE_DIRFD 0)
+  set(HAVE_DLFCN_H 0)
+  set(HAVE_D_MD_ORDER 0)
+  set(HAVE_EFTYPE 0)
+  set(HAVE_EILSEQ 1)
+  set(HAVE_ERR_H 0)
+  set(HAVE_ERRNO_H 1)
+  set(HAVE_EXT2FS_EXT2_FS_H 0)
+  set(HAVE_FCHDIR 0)
+  set(HAVE_FCHFLAGS 0)
+  set(HAVE_FCHMOD 0)
+  set(HAVE_FCHOWN 0)
+  set(HAVE_FCNTL 0)
+  set(HAVE_FCNTL_H 1)
+  set(HAVE_FCNTL_O_NONBLOCK 0)
+  set(HAVE_FDOPENDIR 0)
+  set(HAVE_FORK 0)
+  set(HAVE_FREEADDRINFO 1)
+  set(HAVE_FREEIFADDRS 0)
+  set(HAVE__FSEEKI64 1)
+  set(HAVE_FSETXATTR 0)
+  set(HAVE_FSTAT 1)
+  set(HAVE_FSTATAT 0)
+  set(HAVE_FSTATFS 0)
+  set(HAVE_FSTATVFS 0)
+  set(HAVE_FTRUNCATE 0)
+  set(HAVE_FUTIMENS 0)
+  set(HAVE_FUTIMES 0)
+  set(HAVE_FUTIMESAT 0)
+  set(HAVE_GETEUID 0)
+  set(HAVE_GETGRGID_R 0)
+  set(HAVE_GETGRNAM_R 0)
+  set(HAVE_GETHOSTBYNAME 1)
+  set(HAVE_GETPAGESIZE 0)
+  set(HAVE_GETPEERNAME 1)
+  set(HAVE_GETPID 1)
+  set(HAVE_GETPROTOBYNAME 1)
+  set(HAVE_GETPWNAM_R 0)
+  set(HAVE_GETPWUID_R 0)
+  set(HAVE_GETRANDOM 0)
+  set(HAVE_GETRLIMIT 0)
+  set(HAVE_GETSOCKNAME 1)
+  set(HAVE_GETVFSBYNAME 0)
+  set(HAVE_GLIBC_STRERROR_R 0)
+  set(HAVE__GMTIME64_S 1)
+  set(HAVE_GMTIME_R 0)
+  set(HAVE_GRP_H 0)
+  set(HAVE_IDN2_H 0)
+  set(HAVE_IFADDRS_H 0)
+  set(HAVE_IF_NAMETOINDEX 0)
+  set(HAVE_INTTYPES_H 1)
+  set(HAVE_IOCTL 0)
+  set(HAVE_IOCTL_FIONBIO 0)
+  set(HAVE_IOCTL_SIOCGIFADDR 0)
+  set(HAVE_IOCTLSOCKET 1)
+  set(HAVE_IOCTLSOCKET_CAMEL 0)
+  set(HAVE_IOCTLSOCKET_CAMEL_FIONBIO 1)
+  set(HAVE_IOCTLSOCKET_FIONBIO 1)
+  set(HAVE_IO_H 1)
+  set(HAVE_KRB_H 0)
+  set(HAVE_LANGINFO_H 0)
+  set(HAVE_LCHFLAGS 0)
+  set(HAVE_LCHMOD 0)
+  set(HAVE_LCHOWN 0)
+  set(HAVE_LIBIDN2 0)
+  set(HAVE_LIBNETWORK 0)
+  set(HAVE_LIBWINMM 1)
+  set(HAVE_LIBWS2_32 1)
+  set(HAVE_LIMITS_H 1)
+  set(HAVE_LINK 0)
+  set(HAVE_LINUX_FIEMAP_H 0)
+  set(HAVE_LINUX_FS_H 0)
+  set(HAVE_LINUX_MAGIC_H 0)
+  set(HAVE_LINUX_TYPES_H 0)
+  set(HAVE__LOCALTIME64_S 1)
+  set(HAVE_LOCALTIME_R 0)
+  set(HAVE_LSTAT 0)
+  set(HAVE_LUTIMES 0)
+  set(HAVE_MACH_ABSOLUTE_TIME 0)
+  set(HAVE_MBRTOWC 1)
+  set(HAVE_MEMBERSHIP_H 0)
+  set(HAVE_MEMORY_H 1)
+  set(HAVE_MKDIR 1)
+  set(HAVE_MKFIFO 0)
+  set(HAVE__MKGMTIME64 1)
+  set(HAVE_MKNOD 0)
+  set(HAVE_MMAP 0)
+  set(HAVE_MSG_NOSIGNAL 0)
+  set(HAVE_NETINET_TCP_H 0)
+  set(HAVE_NL_LANGINFO 0)
+  set(HAVE_OPENAT 0)
+  set(HAVE_PATHS_H 0)
+  set(HAVE_PEM_H 0)
+  set(HAVE_PIPE 0)
+  set(HAVE_POLL 0)
+  set(HAVE_POLL_FINE 0)
+  set(HAVE_POLL_H 0)
+  set(HAVE_POSIX_SPAWNP 0)
+  set(HAVE_POSIX_STRERROR_R 0)
+  set(HAVE_PROCESS_H 1)
+  set(HAVE_PWD_H 0)
+  set(HAVE_READDIR_R 0)
+  set(HAVE_READLINK 0)
+  set(HAVE_READLINKAT 0)
+  set(HAVE_READPASSPHRASE 0)
+  set(HAVE_READPASSPHRASE_H 0)
+  set(HAVE_REGEX_H 0)
+  set(HAVE_RSA_H 0)
+  set(HAVE_SELECT 0)
+  set(HAVE_SETENV 0)
+  set(HAVE_SETMODE 1)
+  set(HAVE_SETRLIMIT 0)
+  set(HAVE_SETSOCKOPT 1)
+  set(HAVE_SETSOCKOPT_SO_NONBLOCK 0)
+  set(HAVE_SIGACTION 0)
+  set(HAVE_SIG_ATOMIC_T_NOT_VOLATILE 1)
+  set(HAVE_SIGINTERRUPT 0)
+  set(HAVE_SIGNAL_H 1)
+  set(HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID 0)
+  set(HAVE_SPAWN_H 0)
+  set(HAVE_SSL_H 0)
+  set(HAVE_STATFS 0)
+  set(HAVE_STATVFS 0)
+  set(HAVE_STDARG_H 1)
+  set(HAVE_STDBOOL_H 1)
+  set(HAVE_STDINT_H 1)
+  set(HAVE_STRERROR 1)
+  set(HAVE_STRERROR_R 0)
+  set(HAVE_STRNCMPI 0)
+  set(HAVE_STRNCPY_S 1)
+  set(HAVE_STROPTS_H 0)
+  set(HAVE__STRTOI64 1)
+  set(HAVE_STRTOLL 1)
+  set(HAVE_STRUCT_STATFS_F_NAMEMAX 0)
+  set(HAVE_STRUCT_STAT_ST_BIRTHTIME 0)
+  set(HAVE_STRUCT_STAT_ST_BIRTHTIMESPEC_TV_NSEC 0)
+  set(HAVE_STRUCT_STAT_ST_BLKSIZE 0)
+  set(HAVE_STRUCT_STAT_ST_FLAGS 0)
+  set(HAVE_STRUCT_STAT_ST_MTIME_N 0)
+  set(HAVE_STRUCT_STAT_ST_MTIMESPEC_TV_NSEC 0)
+  set(HAVE_STRUCT_STAT_ST_MTIME_USEC 0)
+  set(HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC 0)
+  set(HAVE_STRUCT_STAT_ST_UMTIME 0)
+  set(HAVE_STRUCT_TIMEVAL 1)
+  set(HAVE_STRUCT_TM___TM_GMTOFF 0)
+  set(HAVE_STRUCT_TM_TM_GMTOFF 0)
+  set(HAVE_STRUCT_VFSCONF 0)
+  set(HAVE_STRUCT_XVFSCONF 0)
+  set(HAVE_SYMLINK 0)
+  set(HAVE_SYS_ACL_H 0)
+  set(HAVE_SYSCALL_GETRANDOM 0)
+  set(HAVE_SYS_EXTATTR_H 0)
+  set(HAVE_SYS_FILIO_H 0)
+  set(HAVE_SYS_IOCTL_H 0)
+  set(HAVE_SYS_MKDEV_H 0)
+  set(HAVE_SYS_MOUNT_H 0)
+  set(HAVE_SYS_POLL_H 0)
+  set(HAVE_SYS_RESOURCE_H 0)
+  set(HAVE_SYS_RICHACL_H 0)
+  set(HAVE_SYS_SELECT_H 0)
+  set(HAVE_SYS_STATFS_H 0)
+  set(HAVE_SYS_STAT_H 1)
+  set(HAVE_SYS_STATVFS_H 0)
+  set(HAVE_SYS_SYSCTL_H 0)
+  set(HAVE_SYS_SYSMACROS_H 0)
+  set(HAVE_SYS_UIO_H 0)
+  set(HAVE_SYS_UN_H 0)
+  set(HAVE_SYS_UTSNAME_H 0)
+  set(HAVE_SYS_VFS_H 0)
+  set(HAVE_SYS_WAIT_H 0)
+  set(HAVE_SYS_XATTR_H 0)
+  set(HAVE_TIMEGM 0)
+  set(HAVE_TZSET 1)
+  set(HAVE_UNLINKAT 0)
+  set(HAVE_USLEEP 0)
+  set(HAVE_UTIMENSAT 0)
+  set(HAVE_UTIMES 0)
+  set(HAVE_VFORK 0)
+  set(HAVE_WORKING_EXT2_IOC_GETFLAGS 0)
+  set(HAVE_WORKING_FS_IOC_GETFLAGS 0)
+
+  # Some POSIX headers are available on Windows.
+  set(HAVE_SYS_TYPES_H 1)
+  set(HAVE_SYS_UTIME_H 1)
+  set(HAVE_TIME_H 1)
+  set(HAVE_UTIME 1)
+
+  # Wide character APIs are available on Windows.
+  set(HAVE_WCRTOMB 1)
+  set(HAVE_WCSCMP 1)
+  set(HAVE_WCSCPY 1)
+  set(HAVE_WCSLEN 1)
+  set(HAVE_WCTOMB 1)
+  set(HAVE_WCTYPE_H 1)
+
+  # Windows APIs are available on Windows.
+  set(HAVE_WINCRYPT_H 1)
+  set(HAVE_WINDOWS_H 1)
+  set(HAVE_WINIOCTL_H 1)
+  set(HAVE_WINSOCK2_H 1)
+  set(HAVE_WINSOCK_H 1)
+  set(HAVE_WS2TCPIP_H 1)
+
+  # UNIX integer id types do not exist on Windows.
+  set(HAVE_ID_T 0)
+  set(HAVE_GID_T 0)
+  set(HAVE_UID_T 0)
+  set(ID_T "")
+  set(GID_T "")
+  set(UID_T "")
+
+  # curl and expat: stdlib.h, stdarg.h, string.h, float.h
+  set(STDC_HEADERS 1)
+
+  # UNIX device APIs do not exist on Windows.
+  set(MAJOR_IN_MKDEV 0)
+  set(MAJOR_IN_SYSMACROS 0)
+
+  # FreeBSD libmd does not exist on Windows.
+  set(LIBMD_FOUND 0)
+
+  # libarchive looks for external hash implementations.
+  set(ARCHIVE_CRYPTO_MD5_LIBC 0)
+  set(ARCHIVE_CRYPTO_MD5_LIBMD 0)
+  set(ARCHIVE_CRYPTO_MD5_LIBSYSTEM 0)
+  set(ARCHIVE_CRYPTO_MD5_WIN 1)
+  set(ARCHIVE_CRYPTO_RMD160_LIBC 0)
+  set(ARCHIVE_CRYPTO_RMD160_LIBMD 0)
+  set(ARCHIVE_CRYPTO_SHA1_LIBC 0)
+  set(ARCHIVE_CRYPTO_SHA1_LIBMD 0)
+  set(ARCHIVE_CRYPTO_SHA1_LIBSYSTEM 0)
+  set(ARCHIVE_CRYPTO_SHA1_WIN 1)
+  set(ARCHIVE_CRYPTO_SHA256_LIBC 0)
+  set(ARCHIVE_CRYPTO_SHA256_LIBC2 0)
+  set(ARCHIVE_CRYPTO_SHA256_LIBC3 0)
+  set(ARCHIVE_CRYPTO_SHA256_LIBMD 0)
+  set(ARCHIVE_CRYPTO_SHA256_LIBSYSTEM 0)
+  set(ARCHIVE_CRYPTO_SHA384_LIBC 0)
+  set(ARCHIVE_CRYPTO_SHA384_LIBC2 0)
+  set(ARCHIVE_CRYPTO_SHA384_LIBC3 0)
+  set(ARCHIVE_CRYPTO_SHA384_LIBSYSTEM 0)
+  set(ARCHIVE_CRYPTO_SHA512_LIBC 0)
+  set(ARCHIVE_CRYPTO_SHA512_LIBC2 0)
+  set(ARCHIVE_CRYPTO_SHA512_LIBC3 0)
+  set(ARCHIVE_CRYPTO_SHA512_LIBMD 0)
+  set(ARCHIVE_CRYPTO_SHA512_LIBSYSTEM 0)
+endif()
diff --git a/Utilities/cm_bzlib.h b/Utilities/cm_bzlib.h
deleted file mode 100644
index 8669e9e..0000000
--- a/Utilities/cm_bzlib.h
+++ /dev/null
@@ -1,14 +0,0 @@
-/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
-   file Copyright.txt or https://cmake.org/licensing for details.  */
-#ifndef cm_bzlib_h
-#define cm_bzlib_h
-
-/* Use the bzip2 library configured for CMake.  */
-#include "cmThirdParty.h"
-#ifdef CMAKE_USE_SYSTEM_BZIP2
-#  include <bzlib.h>
-#else
-#  include <cmbzip2/bzlib.h>
-#endif
-
-#endif
diff --git a/Utilities/cm_curl.h b/Utilities/cm_curl.h
deleted file mode 100644
index 673f8ad..0000000
--- a/Utilities/cm_curl.h
+++ /dev/null
@@ -1,14 +0,0 @@
-/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
-   file Copyright.txt or https://cmake.org/licensing for details.  */
-#ifndef cm_curl_h
-#define cm_curl_h
-
-/* Use the curl library configured for CMake.  */
-#include "cmThirdParty.h"
-#ifdef CMAKE_USE_SYSTEM_CURL
-#  include <curl/curl.h>
-#else
-#  include <cmcurl/include/curl/curl.h>
-#endif
-
-#endif
diff --git a/Utilities/cm_expat.h b/Utilities/cm_expat.h
deleted file mode 100644
index fc5b39a..0000000
--- a/Utilities/cm_expat.h
+++ /dev/null
@@ -1,14 +0,0 @@
-/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
-   file Copyright.txt or https://cmake.org/licensing for details.  */
-#ifndef cm_expat_h
-#define cm_expat_h
-
-/* Use the expat library configured for CMake.  */
-#include "cmThirdParty.h"
-#ifdef CMAKE_USE_SYSTEM_EXPAT
-#  include <expat.h>
-#else
-#  include <cmexpat/lib/expat.h>
-#endif
-
-#endif
diff --git a/Utilities/cm_jsoncpp_reader.h b/Utilities/cm_jsoncpp_reader.h
deleted file mode 100644
index 23af65c..0000000
--- a/Utilities/cm_jsoncpp_reader.h
+++ /dev/null
@@ -1,14 +0,0 @@
-/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
-   file Copyright.txt or https://cmake.org/licensing for details.  */
-#ifndef cm_jsoncpp_reader_h
-#define cm_jsoncpp_reader_h
-
-/* Use the jsoncpp library configured for CMake.  */
-#include "cmThirdParty.h"
-#ifdef CMAKE_USE_SYSTEM_JSONCPP
-#  include <json/reader.h>
-#else
-#  include <cmjsoncpp/include/json/reader.h>
-#endif
-
-#endif
diff --git a/Utilities/cm_jsoncpp_value.h b/Utilities/cm_jsoncpp_value.h
deleted file mode 100644
index 742d99a..0000000
--- a/Utilities/cm_jsoncpp_value.h
+++ /dev/null
@@ -1,14 +0,0 @@
-/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
-   file Copyright.txt or https://cmake.org/licensing for details.  */
-#ifndef cm_jsoncpp_value_h
-#define cm_jsoncpp_value_h
-
-/* Use the jsoncpp library configured for CMake.  */
-#include "cmThirdParty.h"
-#ifdef CMAKE_USE_SYSTEM_JSONCPP
-#  include <json/value.h>
-#else
-#  include <cmjsoncpp/include/json/value.h>
-#endif
-
-#endif
diff --git a/Utilities/cm_jsoncpp_writer.h b/Utilities/cm_jsoncpp_writer.h
deleted file mode 100644
index d9e5d82..0000000
--- a/Utilities/cm_jsoncpp_writer.h
+++ /dev/null
@@ -1,14 +0,0 @@
-/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
-   file Copyright.txt or https://cmake.org/licensing for details.  */
-#ifndef cm_jsoncpp_writer_h
-#define cm_jsoncpp_writer_h
-
-/* Use the jsoncpp library configured for CMake.  */
-#include "cmThirdParty.h"
-#ifdef CMAKE_USE_SYSTEM_JSONCPP
-#  include <json/writer.h>
-#else
-#  include <cmjsoncpp/include/json/writer.h>
-#endif
-
-#endif
diff --git a/Utilities/cm_kwiml.h b/Utilities/cm_kwiml.h
deleted file mode 100644
index 566f67e..0000000
--- a/Utilities/cm_kwiml.h
+++ /dev/null
@@ -1,16 +0,0 @@
-/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
-   file Copyright.txt or https://cmake.org/licensing for details.  */
-#ifndef cm_kwiml_h
-#define cm_kwiml_h
-
-/* Use the KWIML library configured for CMake.  */
-#include "cmThirdParty.h"
-#ifdef CMAKE_USE_SYSTEM_KWIML
-#  include <kwiml/abi.h>
-#  include <kwiml/int.h>
-#else
-#  include "KWIML/include/kwiml/abi.h"
-#  include "KWIML/include/kwiml/int.h"
-#endif
-
-#endif
diff --git a/Utilities/cm_libarchive.h b/Utilities/cm_libarchive.h
deleted file mode 100644
index ea8e9db..0000000
--- a/Utilities/cm_libarchive.h
+++ /dev/null
@@ -1,16 +0,0 @@
-/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
-   file Copyright.txt or https://cmake.org/licensing for details.  */
-#ifndef cm_libarchive_h
-#define cm_libarchive_h
-
-/* Use the libarchive configured for CMake.  */
-#include "cmThirdParty.h"
-#ifdef CMAKE_USE_SYSTEM_LIBARCHIVE
-#  include <archive.h>
-#  include <archive_entry.h>
-#else
-#  include <cmlibarchive/libarchive/archive.h>
-#  include <cmlibarchive/libarchive/archive_entry.h>
-#endif
-
-#endif
diff --git a/Utilities/cm_lzma.h b/Utilities/cm_lzma.h
deleted file mode 100644
index 0526036..0000000
--- a/Utilities/cm_lzma.h
+++ /dev/null
@@ -1,14 +0,0 @@
-/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
-   file Copyright.txt or https://cmake.org/licensing for details.  */
-#ifndef cm_lzma_h
-#define cm_lzma_h
-
-/* Use the liblzma configured for CMake.  */
-#include "cmThirdParty.h"
-#ifdef CMAKE_USE_SYSTEM_LIBLZMA
-#  include <lzma.h>
-#else
-#  include <cmliblzma/liblzma/api/lzma.h>
-#endif
-
-#endif
diff --git a/Utilities/cm_rhash.h b/Utilities/cm_rhash.h
deleted file mode 100644
index 03d9871..0000000
--- a/Utilities/cm_rhash.h
+++ /dev/null
@@ -1,14 +0,0 @@
-/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
-   file Copyright.txt or https://cmake.org/licensing for details.  */
-#ifndef cm_rhash_h
-#define cm_rhash_h
-
-/* Use the LibRHash library configured for CMake.  */
-#include "cmThirdParty.h"
-#ifdef CMAKE_USE_SYSTEM_LIBRHASH
-#  include <rhash.h>
-#else
-#  include <cmlibrhash/librhash/rhash.h>
-#endif
-
-#endif
diff --git a/Utilities/cm_uv.h b/Utilities/cm_uv.h
deleted file mode 100644
index 448f30d..0000000
--- a/Utilities/cm_uv.h
+++ /dev/null
@@ -1,14 +0,0 @@
-/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
-   file Copyright.txt or https://cmake.org/licensing for details.  */
-#ifndef cm_uv_h
-#define cm_uv_h
-
-/* Use the libuv library configured for CMake.  */
-#include "cmThirdParty.h"
-#ifdef CMAKE_USE_SYSTEM_LIBUV
-#  include <uv.h>
-#else
-#  include <cmlibuv/include/uv.h>
-#endif
-
-#endif
diff --git a/Utilities/cm_zlib.h b/Utilities/cm_zlib.h
deleted file mode 100644
index 2314183..0000000
--- a/Utilities/cm_zlib.h
+++ /dev/null
@@ -1,14 +0,0 @@
-/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
-   file Copyright.txt or https://cmake.org/licensing for details.  */
-#ifndef cm_zlib_h
-#define cm_zlib_h
-
-/* Use the zlib library configured for CMake.  */
-#include "cmThirdParty.h"
-#ifdef CMAKE_USE_SYSTEM_ZLIB
-#  include <zlib.h>
-#else
-#  include <cmzlib/zlib.h>
-#endif
-
-#endif
diff --git a/Utilities/cm_zstd.h b/Utilities/cm_zstd.h
deleted file mode 100644
index 4bda996..0000000
--- a/Utilities/cm_zstd.h
+++ /dev/null
@@ -1,14 +0,0 @@
-/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
-   file Copyright.txt or https://cmake.org/licensing for details.  */
-#ifndef cm_zstd_h
-#define cm_zstd_h
-
-/* Use the libzstd configured for CMake.  */
-#include "cmThirdParty.h"
-#ifdef CMAKE_USE_SYSTEM_ZSTD
-#  include <zstd.h>
-#else
-#  include <cmzstd/lib/zstd.h>
-#endif
-
-#endif
diff --git a/Utilities/cmbzip2/.gitattributes b/Utilities/cmbzip2/.gitattributes
new file mode 100644
index 0000000..562b12e
--- /dev/null
+++ b/Utilities/cmbzip2/.gitattributes
@@ -0,0 +1 @@
+* -whitespace
diff --git a/Utilities/cmbzip2/CHANGES b/Utilities/cmbzip2/CHANGES
deleted file mode 100644
index 6e4f65e..0000000
--- a/Utilities/cmbzip2/CHANGES
+++ /dev/null
@@ -1,319 +0,0 @@
- ------------------------------------------------------------------
- This file is part of bzip2/libbzip2, a program and library for
- lossless, block-sorting data compression.
-
- bzip2/libbzip2 version 1.0.5 of 10 December 2007
- Copyright (C) 1996-2007 Julian Seward <jseward@bzip.org>
-
- Please read the WARNING, DISCLAIMER and PATENTS sections in the 
- README file.
-
- This program is released under the terms of the license contained
- in the file LICENSE.
- ------------------------------------------------------------------
-
-
-0.9.0
-~~~~~
-First version.
-
-
-0.9.0a
-~~~~~~
-Removed 'ranlib' from Makefile, since most modern Unix-es 
-don't need it, or even know about it.
-
-
-0.9.0b
-~~~~~~
-Fixed a problem with error reporting in bzip2.c.  This does not effect
-the library in any way.  Problem is: versions 0.9.0 and 0.9.0a (of the
-program proper) compress and decompress correctly, but give misleading
-error messages (internal panics) when an I/O error occurs, instead of
-reporting the problem correctly.  This shouldn't give any data loss
-(as far as I can see), but is confusing.
-
-Made the inline declarations disappear for non-GCC compilers.
-
-
-0.9.0c
-~~~~~~
-Fixed some problems in the library pertaining to some boundary cases.
-This makes the library behave more correctly in those situations.  The
-fixes apply only to features (calls and parameters) not used by
-bzip2.c, so the non-fixedness of them in previous versions has no
-effect on reliability of bzip2.c.
-
-In bzlib.c:
-   * made zero-length BZ_FLUSH work correctly in bzCompress().
-   * fixed bzWrite/bzRead to ignore zero-length requests.
-   * fixed bzread to correctly handle read requests after EOF.
-   * wrong parameter order in call to bzDecompressInit in
-     bzBuffToBuffDecompress.  Fixed.
-
-In compress.c:
-   * changed setting of nGroups in sendMTFValues() so as to 
-     do a bit better on small files.  This _does_ effect
-     bzip2.c.
-
-
-0.9.5a
-~~~~~~
-Major change: add a fallback sorting algorithm (blocksort.c)
-to give reasonable behaviour even for very repetitive inputs.
-Nuked --repetitive-best and --repetitive-fast since they are
-no longer useful.
-
-Minor changes: mostly a whole bunch of small changes/
-bugfixes in the driver (bzip2.c).  Changes pertaining to the
-user interface are:
-
-   allow decompression of symlink'd files to stdout
-   decompress/test files even without .bz2 extension
-   give more accurate error messages for I/O errors
-   when compressing/decompressing to stdout, don't catch control-C
-   read flags from BZIP2 and BZIP environment variables
-   decline to break hard links to a file unless forced with -f
-   allow -c flag even with no filenames
-   preserve file ownerships as far as possible
-   make -s -1 give the expected block size (100k)
-   add a flag -q --quiet to suppress nonessential warnings
-   stop decoding flags after --, so files beginning in - can be handled
-   resolved inconsistent naming: bzcat or bz2cat ?
-   bzip2 --help now returns 0
-
-Programming-level changes are:
-
-   fixed syntax error in GET_LL4 for Borland C++ 5.02
-   let bzBuffToBuffDecompress return BZ_DATA_ERROR{_MAGIC}
-   fix overshoot of mode-string end in bzopen_or_bzdopen
-   wrapped bzlib.h in #ifdef __cplusplus ... extern "C" { ... }
-   close file handles under all error conditions
-   added minor mods so it compiles with DJGPP out of the box
-   fixed Makefile so it doesn't give problems with BSD make
-   fix uninitialised memory reads in dlltest.c
-
-0.9.5b
-~~~~~~
-Open stdin/stdout in binary mode for DJGPP.
-
-0.9.5c
-~~~~~~
-Changed BZ_N_OVERSHOOT to be ... + 2 instead of ... + 1.  The + 1
-version could cause the sorted order to be wrong in some extremely
-obscure cases.  Also changed setting of quadrant in blocksort.c.
-
-0.9.5d
-~~~~~~
-The only functional change is to make bzlibVersion() in the library
-return the correct string.  This has no effect whatsoever on the
-functioning of the bzip2 program or library.  Added a couple of casts
-so the library compiles without warnings at level 3 in MS Visual
-Studio 6.0.  Included a Y2K statement in the file Y2K_INFO.  All other
-changes are minor documentation changes.
-
-1.0
-~~~
-Several minor bugfixes and enhancements:
-
-* Large file support.  The library uses 64-bit counters to
-  count the volume of data passing through it.  bzip2.c 
-  is now compiled with -D_FILE_OFFSET_BITS=64 to get large
-  file support from the C library.  -v correctly prints out
-  file sizes greater than 4 gigabytes.  All these changes have
-  been made without assuming a 64-bit platform or a C compiler
-  which supports 64-bit ints, so, except for the C library
-  aspect, they are fully portable.
-
-* Decompression robustness.  The library/program should be
-  robust to any corruption of compressed data, detecting and
-  handling _all_ corruption, instead of merely relying on
-  the CRCs.  What this means is that the program should 
-  never crash, given corrupted data, and the library should
-  always return BZ_DATA_ERROR.
-
-* Fixed an obscure race-condition bug only ever observed on
-  Solaris, in which, if you were very unlucky and issued
-  control-C at exactly the wrong time, both input and output
-  files would be deleted.
-
-* Don't run out of file handles on test/decompression when
-  large numbers of files have invalid magic numbers.
-
-* Avoid library namespace pollution.  Prefix all exported 
-  symbols with BZ2_.
-
-* Minor sorting enhancements from my DCC2000 paper.
-
-* Advance the version number to 1.0, so as to counteract the
-  (false-in-this-case) impression some people have that programs 
-  with version numbers less than 1.0 are in some way, experimental,
-  pre-release versions.
-
-* Create an initial Makefile-libbz2_so to build a shared library.
-  Yes, I know I should really use libtool et al ...
-
-* Make the program exit with 2 instead of 0 when decompression
-  fails due to a bad magic number (ie, an invalid bzip2 header).
-  Also exit with 1 (as the manual claims :-) whenever a diagnostic
-  message would have been printed AND the corresponding operation 
-  is aborted, for example
-     bzip2: Output file xx already exists.
-  When a diagnostic message is printed but the operation is not 
-  aborted, for example
-     bzip2: Can't guess original name for wurble -- using wurble.out
-  then the exit value 0 is returned, unless some other problem is
-  also detected.
-
-  I think it corresponds more closely to what the manual claims now.
-
-
-1.0.1
-~~~~~
-* Modified dlltest.c so it uses the new BZ2_ naming scheme.
-* Modified makefile-msc to fix minor build probs on Win2k.
-* Updated README.COMPILATION.PROBLEMS.
-
-There are no functionality changes or bug fixes relative to version
-1.0.0.  This is just a documentation update + a fix for minor Win32
-build problems.  For almost everyone, upgrading from 1.0.0 to 1.0.1 is
-utterly pointless.  Don't bother.
-
-
-1.0.2
-~~~~~
-A bug fix release, addressing various minor issues which have appeared
-in the 18 or so months since 1.0.1 was released.  Most of the fixes
-are to do with file-handling or documentation bugs.  To the best of my
-knowledge, there have been no data-loss-causing bugs reported in the
-compression/decompression engine of 1.0.0 or 1.0.1.
-
-Note that this release does not improve the rather crude build system
-for Unix platforms.  The general plan here is to autoconfiscate/
-libtoolise 1.0.2 soon after release, and release the result as 1.1.0
-or perhaps 1.2.0.  That, however, is still just a plan at this point.
-
-Here are the changes in 1.0.2.  Bug-reporters and/or patch-senders in
-parentheses.
-
-* Fix an infinite segfault loop in 1.0.1 when a directory is
-  encountered in -f (force) mode.
-     (Trond Eivind Glomsrod, Nicholas Nethercote, Volker Schmidt)
-
-* Avoid double fclose() of output file on certain I/O error paths.
-     (Solar Designer)
-
-* Don't fail with internal error 1007 when fed a long stream (> 48MB)
-  of byte 251.  Also print useful message suggesting that 1007s may be
-  caused by bad memory.
-     (noticed by Juan Pedro Vallejo, fixed by me)
-
-* Fix uninitialised variable silly bug in demo prog dlltest.c.
-     (Jorj Bauer)
-
-* Remove 512-MB limitation on recovered file size for bzip2recover
-  on selected platforms which support 64-bit ints.  At the moment
-  all GCC supported platforms, and Win32.
-     (me, Alson van der Meulen)
-
-* Hard-code header byte values, to give correct operation on platforms
-  using EBCDIC as their native character set (IBM's OS/390).
-     (Leland Lucius)
-
-* Copy file access times correctly.
-     (Marty Leisner)
-
-* Add distclean and check targets to Makefile.
-     (Michael Carmack)
-
-* Parameterise use of ar and ranlib in Makefile.  Also add $(LDFLAGS).
-     (Rich Ireland, Bo Thorsen)
-
-* Pass -p (create parent dirs as needed) to mkdir during make install.
-     (Jeremy Fusco)
-
-* Dereference symlinks when copying file permissions in -f mode.
-     (Volker Schmidt)
-
-* Majorly simplify implementation of uInt64_qrm10.
-     (Bo Lindbergh)
-
-* Check the input file still exists before deleting the output one,
-  when aborting in cleanUpAndFail().
-     (Joerg Prante, Robert Linden, Matthias Krings)
-
-Also a bunch of patches courtesy of Philippe Troin, the Debian maintainer
-of bzip2:
-
-* Wrapper scripts (with manpages): bzdiff, bzgrep, bzmore.
-
-* Spelling changes and minor enhancements in bzip2.1.
-
-* Avoid race condition between creating the output file and setting its
-  interim permissions safely, by using fopen_output_safely().
-  No changes to bzip2recover since there is no issue with file
-  permissions there.
-
-* do not print senseless report with -v when compressing an empty
-  file.
-
-* bzcat -f works on non-bzip2 files.
-
-* do not try to escape shell meta-characters on unix (the shell takes
-  care of these).
-
-* added --fast and --best aliases for -1 -9 for gzip compatibility.
-
-
-1.0.3 (15 Feb 05)
-~~~~~~~~~~~~~~~~~
-Fixes some minor bugs since the last version, 1.0.2.
-
-* Further robustification against corrupted compressed data.
-  There are currently no known bitstreams which can cause the
-  decompressor to crash, loop or access memory which does not
-  belong to it.  If you are using bzip2 or the library to 
-  decompress bitstreams from untrusted sources, an upgrade
-  to 1.0.3 is recommended.  This fixes CAN-2005-1260.
-
-* The documentation has been converted to XML, from which html
-  and pdf can be derived.
-
-* Various minor bugs in the documentation have been fixed.
-
-* Fixes for various compilation warnings with newer versions of
-  gcc, and on 64-bit platforms.
-
-* The BZ_NO_STDIO cpp symbol was not properly observed in 1.0.2.
-  This has been fixed.
-
-
-1.0.4 (20 Dec 06)
-~~~~~~~~~~~~~~~~~
-Fixes some minor bugs since the last version, 1.0.3.
-
-* Fix file permissions race problem (CAN-2005-0953).
-
-* Avoid possible segfault in BZ2_bzclose.  From Coverity's NetBSD
-  scan.
-
-* 'const'/prototype cleanups in the C code.
-
-* Change default install location to /usr/local, and handle multiple
-  'make install's without error.
-
-* Sanitise file names more carefully in bzgrep.  Fixes CAN-2005-0758
-  to the extent that applies to bzgrep.
-
-* Use 'mktemp' rather than 'tempfile' in bzdiff.
-
-* Tighten up a couple of assertions in blocksort.c following automated
-  analysis.
-
-* Fix minor doc/comment bugs.
-
-
-1.0.5 (10 Dec 07)
-~~~~~~~~~~~~~~~~~
-Security fix only.  Fixes CERT-FI 20469 as it applies to bzip2.
-
diff --git a/Utilities/cmbzip2/CMakeLists.txt b/Utilities/cmbzip2/CMakeLists.txt
index 2aff69c..cb4a038 100644
--- a/Utilities/cmbzip2/CMakeLists.txt
+++ b/Utilities/cmbzip2/CMakeLists.txt
@@ -1,4 +1,13 @@
 project(bzip2)
+
+# Disable warnings to avoid changing 3rd party code.
+if(CMAKE_C_COMPILER_ID MATCHES
+    "^(GNU|Clang|AppleClang|XLClang|XL|VisualAge|SunPro|HP|Intel)$")
+  set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -w")
+elseif(CMAKE_C_COMPILER_ID STREQUAL "PathScale")
+  set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -woffall")
+endif()
+
 add_definitions(-D_FILE_OFFSET_BITS=64)
 add_library(cmbzip2
   blocksort.c huffman.c crctable.c randtable.c compress.c decompress.c bzlib.c)
diff --git a/Utilities/cmbzip2/LICENSE b/Utilities/cmbzip2/LICENSE
index f420cff..81a37ea 100644
--- a/Utilities/cmbzip2/LICENSE
+++ b/Utilities/cmbzip2/LICENSE
@@ -2,7 +2,7 @@
 --------------------------------------------------------------------------
 
 This program, "bzip2", the associated library "libbzip2", and all
-documentation, are copyright (C) 1996-2007 Julian R Seward.  All
+documentation, are copyright (C) 1996-2019 Julian R Seward.  All
 rights reserved.
 
 Redistribution and use in source and binary forms, with or without
@@ -36,7 +36,7 @@
 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-Julian Seward, jseward@bzip.org
-bzip2/libbzip2 version 1.0.5 of 10 December 2007
+Julian Seward, jseward@acm.org
+bzip2/libbzip2 version 1.0.8 of 13 July 2019
 
 --------------------------------------------------------------------------
diff --git a/Utilities/cmbzip2/Makefile-libbz2_so b/Utilities/cmbzip2/Makefile-libbz2_so
deleted file mode 100644
index 8370887..0000000
--- a/Utilities/cmbzip2/Makefile-libbz2_so
+++ /dev/null
@@ -1,59 +0,0 @@
-
-# This Makefile builds a shared version of the library, 
-# libbz2.so.1.0.4, with soname libbz2.so.1.0,
-# at least on x86-Linux (RedHat 7.2), 
-# with gcc-2.96 20000731 (Red Hat Linux 7.1 2.96-98).  
-# Please see the README file for some important info 
-# about building the library like this.
-
-# ------------------------------------------------------------------
-# This file is part of bzip2/libbzip2, a program and library for
-# lossless, block-sorting data compression.
-#
-# bzip2/libbzip2 version 1.0.5 of 10 December 2007
-# Copyright (C) 1996-2007 Julian Seward <jseward@bzip.org>
-#
-# Please read the WARNING, DISCLAIMER and PATENTS sections in the 
-# README file.
-#
-# This program is released under the terms of the license contained
-# in the file LICENSE.
-# ------------------------------------------------------------------
-
-
-SHELL=/bin/sh
-CC=gcc
-BIGFILES=-D_FILE_OFFSET_BITS=64
-CFLAGS=-fpic -fPIC -Wall -Winline -O2 -g $(BIGFILES)
-
-OBJS= blocksort.o  \
-      huffman.o    \
-      crctable.o   \
-      randtable.o  \
-      compress.o   \
-      decompress.o \
-      bzlib.o
-
-all: $(OBJS)
-    $(CC) -shared -Wl,-soname -Wl,libbz2.so.1.0 -o libbz2.so.1.0.4 $(OBJS)
-    $(CC) $(CFLAGS) -o bzip2-shared bzip2.c libbz2.so.1.0.4
-    rm -f libbz2.so.1.0
-    ln -s libbz2.so.1.0.4 libbz2.so.1.0
-
-clean: 
-    rm -f $(OBJS) bzip2.o libbz2.so.1.0.4 libbz2.so.1.0 bzip2-shared
-
-blocksort.o: blocksort.c
-    $(CC) $(CFLAGS) -c blocksort.c
-huffman.o: huffman.c
-    $(CC) $(CFLAGS) -c huffman.c
-crctable.o: crctable.c
-    $(CC) $(CFLAGS) -c crctable.c
-randtable.o: randtable.c
-    $(CC) $(CFLAGS) -c randtable.c
-compress.o: compress.c
-    $(CC) $(CFLAGS) -c compress.c
-decompress.o: decompress.c
-    $(CC) $(CFLAGS) -c decompress.c
-bzlib.o: bzlib.c
-    $(CC) $(CFLAGS) -c bzlib.c
diff --git a/Utilities/cmbzip2/README b/Utilities/cmbzip2/README
index e17a84e..b9c6099 100644
--- a/Utilities/cmbzip2/README
+++ b/Utilities/cmbzip2/README
@@ -6,8 +6,8 @@
 This file is part of bzip2/libbzip2, a program and library for
 lossless, block-sorting data compression.
 
-bzip2/libbzip2 version 1.0.5 of 10 December 2007
-Copyright (C) 1996-2007 Julian Seward <jseward@bzip.org>
+bzip2/libbzip2 version 1.0.8 of 13 July 2019
+Copyright (C) 1996-2019 Julian Seward <jseward@acm.org>
 
 Please read the WARNING, DISCLAIMER and PATENTS sections in this file.
 
@@ -73,7 +73,7 @@
 
 It's difficult for me to support compilation on all these platforms.
 My approach is to collect binaries for these platforms, and put them
-on the master web site (http://www.bzip.org).  Look there.  However
+on the master web site (https://sourceware.org/bzip2/).  Look there.  However
 (FWIW), bzip2-1.0.X is very standard ANSI C and should compile
 unmodified with MS Visual C.  If you have difficulties building, you
 might want to read README.COMPILATION.PROBLEMS.
@@ -161,39 +161,22 @@
    * Many small improvements in file and flag handling.
    * A Y2K statement.
 
-WHAT'S NEW IN 1.0.0 ?
+WHAT'S NEW IN 1.0.x ?
 
    See the CHANGES file.
 
-WHAT'S NEW IN 1.0.2 ?
-
-   See the CHANGES file.
-
-WHAT'S NEW IN 1.0.3 ?
-
-   See the CHANGES file.
-
-WHAT'S NEW IN 1.0.4 ?
-
-   See the CHANGES file.
-
-WHAT'S NEW IN 1.0.5 ?
-
-   See the CHANGES file.
-
-
-I hope you find bzip2 useful.  Feel free to contact me at
-   jseward@bzip.org
+I hope you find bzip2 useful.  Feel free to contact the developers at
+   bzip2-devel@sourceware.org
 if you have any suggestions or queries.  Many people mailed me with
 comments, suggestions and patches after the releases of bzip-0.15,
 bzip-0.21, and bzip2 versions 0.1pl2, 0.9.0, 0.9.5, 1.0.0, 1.0.1,
 1.0.2 and 1.0.3, and the changes in bzip2 are largely a result of this
 feedback.  I thank you for your comments.
 
-bzip2's "home" is http://www.bzip.org/
+bzip2's "home" is https://sourceware.org/bzip2/
 
 Julian Seward
-jseward@bzip.org
+jseward@acm.org
 Cambridge, UK.
 
 18     July 1996 (version 0.15)
@@ -208,3 +191,6 @@
 15 February 2005 (bzip2, version 1.0.3)
 20 December 2006 (bzip2, version 1.0.4)
 10 December 2007 (bzip2, version 1.0.5)
+ 6     Sept 2010 (bzip2, version 1.0.6)
+27     June 2019 (bzip2, version 1.0.7)
+13     July 2019 (bzip2, version 1.0.8)
diff --git a/Utilities/cmbzip2/README.COMPILATION.PROBLEMS b/Utilities/cmbzip2/README.COMPILATION.PROBLEMS
deleted file mode 100644
index 22b95c6..0000000
--- a/Utilities/cmbzip2/README.COMPILATION.PROBLEMS
+++ /dev/null
@@ -1,58 +0,0 @@
-------------------------------------------------------------------
-This file is part of bzip2/libbzip2, a program and library for
-lossless, block-sorting data compression.
-
-bzip2/libbzip2 version 1.0.5 of 10 December 2007
-Copyright (C) 1996-2007 Julian Seward <jseward@bzip.org>
-
-Please read the WARNING, DISCLAIMER and PATENTS sections in the 
-README file.
-
-This program is released under the terms of the license contained
-in the file LICENSE.
-------------------------------------------------------------------
-
-bzip2-1.0.5 should compile without problems on the vast majority of
-platforms.  Using the supplied Makefile, I've built and tested it
-myself for x86-linux and amd64-linux.  With makefile.msc, Visual C++
-6.0 and nmake, you can build a native Win32 version too.  Large file
-support seems to work correctly on at least on amd64-linux.
-
-When I say "large file" I mean a file of size 2,147,483,648 (2^31)
-bytes or above.  Many older OSs can't handle files above this size,
-but many newer ones can.  Large files are pretty huge -- most files
-you'll encounter are not Large Files.
-
-Early versions of bzip2 (0.1, 0.9.0, 0.9.5) compiled on a wide variety
-of platforms without difficulty, and I hope this version will continue
-in that tradition.  However, in order to support large files, I've had
-to include the define -D_FILE_OFFSET_BITS=64 in the Makefile.  This
-can cause problems.
-
-The technique of adding -D_FILE_OFFSET_BITS=64 to get large file
-support is, as far as I know, the Recommended Way to get correct large
-file support.  For more details, see the Large File Support
-Specification, published by the Large File Summit, at
-
-   http://ftp.sas.com/standards/large.file
-
-As a general comment, if you get compilation errors which you think
-are related to large file support, try removing the above define from
-the Makefile, ie, delete the line
-
-   BIGFILES=-D_FILE_OFFSET_BITS=64 
-
-from the Makefile, and do 'make clean ; make'.  This will give you a
-version of bzip2 without large file support, which, for most
-applications, is probably not a problem.  
-
-Alternatively, try some of the platform-specific hints listed below.
-
-You can use the spewG.c program to generate huge files to test bzip2's
-large file support, if you are feeling paranoid.  Be aware though that
-any compilation problems which affect bzip2 will also affect spewG.c,
-alas.
-
-AIX: I have reports that for large file support, you need to specify
--D_LARGE_FILES rather than -D_FILE_OFFSET_BITS=64.  I have not tested
-this myself.
diff --git a/Utilities/cmbzip2/README.XML.STUFF b/Utilities/cmbzip2/README.XML.STUFF
deleted file mode 100644
index 1a5b4c5..0000000
--- a/Utilities/cmbzip2/README.XML.STUFF
+++ /dev/null
@@ -1,45 +0,0 @@
-  ----------------------------------------------------------------
-  This file is part of bzip2/libbzip2, a program and library for
-  lossless, block-sorting data compression.
-
-  bzip2/libbzip2 version 1.0.5 of 10 December 2007
-  Copyright (C) 1996-2007 Julian Seward <jseward@bzip.org>
-
-  Please read the WARNING, DISCLAIMER and PATENTS sections in the 
-  README file.
-
-  This program is released under the terms of the license contained
-  in the file LICENSE.
-  ----------------------------------------------------------------
-
-The script xmlproc.sh takes an xml file as input,
-and processes it to create .pdf, .html or .ps output.
-It uses format.pl, a perl script to format <pre> blocks nicely,
- and add CDATA tags so writers do not have to use eg. &lt; 
-
-The file "entities.xml" must be edited to reflect current
-version, year, etc.
-
-
-Usage:
-
-  ./xmlproc.sh -v manual.xml
-  Validates an xml file to ensure no dtd-compliance errors
-
-  ./xmlproc.sh -html manual.xml
-  Output: manual.html
-
-  ./xmlproc.sh -pdf manual.xml
-  Output: manual.pdf
-
-  ./xmlproc.sh -ps manual.xml
-  Output: manual.ps
-
-
-Notum bene: 
-- pdfxmltex barfs if given a filename with an underscore in it
-
-- xmltex won't work yet - there's a bug in passivetex
-    which we are all waiting for Sebastian to fix.
-  So we are going the xml -> pdf -> ps route for the time being,
-    using pdfxmltex.
diff --git a/Utilities/cmbzip2/blocksort.c b/Utilities/cmbzip2/blocksort.c
index 95adb5e..92d81fe 100644
--- a/Utilities/cmbzip2/blocksort.c
+++ b/Utilities/cmbzip2/blocksort.c
@@ -8,8 +8,8 @@
    This file is part of bzip2/libbzip2, a program and library for
    lossless, block-sorting data compression.
 
-   bzip2/libbzip2 version 1.0.5 of 10 December 2007
-   Copyright (C) 1996-2007 Julian Seward <jseward@bzip.org>
+   bzip2/libbzip2 version 1.0.8 of 13 July 2019
+   Copyright (C) 1996-2019 Julian Seward <jseward@acm.org>
 
    Please read the WARNING, DISCLAIMER and PATENTS sections in the 
    README file.
@@ -202,9 +202,9 @@
       bhtab [ 0 .. 2+(nblock/32) ] destroyed
 */
 
-#define       SET_BH(zz)  bhtab[(zz) >> 5] |= (1 << ((zz) & 31))
-#define     CLEAR_BH(zz)  bhtab[(zz) >> 5] &= ~(1 << ((zz) & 31))
-#define     ISSET_BH(zz)  (bhtab[(zz) >> 5] & (1 << ((zz) & 31)))
+#define       SET_BH(zz)  bhtab[(zz) >> 5] |= ((UInt32)1 << ((zz) & 31))
+#define     CLEAR_BH(zz)  bhtab[(zz) >> 5] &= ~((UInt32)1 << ((zz) & 31))
+#define     ISSET_BH(zz)  (bhtab[(zz) >> 5] & ((UInt32)1 << ((zz) & 31)))
 #define      WORD_BH(zz)  bhtab[(zz) >> 5]
 #define UNALIGNED_BH(zz)  ((zz) & 0x01f)
 
@@ -274,7 +274,7 @@
       r = -1;
       while (1) {
 
-     /*-- find the next non-singleton bucket --*/
+	 /*-- find the next non-singleton bucket --*/
          k = r + 1;
          while (ISSET_BH(k) && UNALIGNED_BH(k)) k++;
          if (ISSET_BH(k)) {
diff --git a/Utilities/cmbzip2/bz-common.xsl b/Utilities/cmbzip2/bz-common.xsl
deleted file mode 100644
index 66fcd6f..0000000
--- a/Utilities/cmbzip2/bz-common.xsl
+++ /dev/null
@@ -1,39 +0,0 @@
-<?xml version="1.0"?> <!-- -*- sgml -*- -->
-<xsl:stylesheet 
-     xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
-
-<!-- we like '1.2 Title' -->
-<xsl:param name="section.autolabel" select="'1'"/> 
-<xsl:param name="section.label.includes.component.label" select="'1'"/>
-
-<!-- Do not put 'Chapter' at the start of eg 'Chapter 1. Doing This' -->
-<xsl:param name="local.l10n.xml" select="document('')"/> 
-<l:i18n xmlns:l="http://docbook.sourceforge.net/xmlns/l10n/1.0"> 
-  <l:l10n language="en"> 
-    <l:context name="title-numbered">
-      <l:template name="chapter" text="%n.&#160;%t"/>
-    </l:context> 
-  </l:l10n>
-</l:i18n>
-
-<!-- don't generate sub-tocs for qanda sets -->
-<xsl:param name="generate.toc">
-set       toc,title
-book      toc,title,figure,table,example,equation
-chapter   toc,title
-section   toc
-sect1     toc
-sect2     toc
-sect3     toc
-sect4     nop
-sect5     nop
-qandaset  toc
-qandadiv  nop
-appendix  toc,title
-article/appendix  nop
-article   toc,title
-preface   toc,title
-reference toc,title
-</xsl:param>
-
-</xsl:stylesheet>
diff --git a/Utilities/cmbzip2/bz-fo.xsl b/Utilities/cmbzip2/bz-fo.xsl
deleted file mode 100644
index ba3e301..0000000
--- a/Utilities/cmbzip2/bz-fo.xsl
+++ /dev/null
@@ -1,276 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?> <!-- -*- sgml -*- -->
-<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
-     xmlns:fo="http://www.w3.org/1999/XSL/Format" version="1.0">
-
-<xsl:import href="http://docbook.sourceforge.net/release/xsl/current/fo/docbook.xsl"/>
-<xsl:import href="bz-common.xsl"/>
-
-<!-- set indent = yes while debugging, then change to NO -->
-<xsl:output method="xml" indent="yes"/>
-
-<!-- ensure only passivetex extensions are on -->
-<xsl:param name="stylesheet.result.type" select="'fo'"/>
-<!-- fo extensions: PDF bookmarks and index terms -->
-<xsl:param name="use.extensions" select="'1'"/>
-<xsl:param name="xep.extensions" select="0"/>      
-<xsl:param name="fop.extensions" select="0"/>     
-<xsl:param name="saxon.extensions" select="0"/>   
-<xsl:param name="passivetex.extensions" select="1"/>
-<xsl:param name="tablecolumns.extension" select="'1'"/>
-
-<!-- ensure we are using single sided -->
-<xsl:param name="double.sided" select="'0'"/> 
-
-<!-- insert cross references to page numbers -->
-<xsl:param name="insert.xref.page.number" select="1"/>
-
-<!-- <?custom-pagebreak?> inserts a page break at this point -->
-<xsl:template match="processing-instruction('custom-pagebreak')">
-  <fo:block break-before='page'/>
-</xsl:template>
-
-<!-- show links in color -->
-<xsl:attribute-set name="xref.properties">
-  <xsl:attribute name="color">blue</xsl:attribute>
-</xsl:attribute-set>
-
-<!-- make pre listings indented a bit + a bg colour -->
-<xsl:template match="programlisting | screen">
-  <fo:block start-indent="0.25in" wrap-option="no-wrap" 
-            white-space-collapse="false" text-align="start" 
-            font-family="monospace" background-color="#f2f2f9"
-            linefeed-treatment="preserve" 
-            xsl:use-attribute-sets="normal.para.spacing">
-    <xsl:apply-templates/>
-  </fo:block>
-</xsl:template>
-<!-- make verbatim output prettier -->
-<xsl:template match="literallayout">
-  <fo:block start-indent="0.25in" wrap-option="no-wrap" 
-            white-space-collapse="false" text-align="start" 
-            font-family="monospace" background-color="#edf7f4"
-            linefeed-treatment="preserve" 
-            space-before="0em" space-after="0em">
-    <xsl:apply-templates/>
-  </fo:block>
-</xsl:template>
-
-<!-- workaround bug in passivetex fo output for itemizedlist -->
-<xsl:template match="itemizedlist/listitem">
-  <xsl:variable name="id">
-  <xsl:call-template name="object.id"/></xsl:variable>
-  <xsl:variable name="itemsymbol">
-    <xsl:call-template name="list.itemsymbol">
-      <xsl:with-param name="node" select="parent::itemizedlist"/>
-    </xsl:call-template>
-  </xsl:variable>
-  <xsl:variable name="item.contents">
-    <fo:list-item-label end-indent="label-end()">
-      <fo:block>
-        <xsl:choose>
-          <xsl:when test="$itemsymbol='disc'">&#x2022;</xsl:when>
-          <xsl:when test="$itemsymbol='bullet'">&#x2022;</xsl:when>
-          <xsl:otherwise>&#x2022;</xsl:otherwise>
-        </xsl:choose>
-      </fo:block>
-    </fo:list-item-label>
-    <fo:list-item-body start-indent="body-start()">
-      <xsl:apply-templates/>    <!-- removed extra block wrapper -->
-    </fo:list-item-body>
-  </xsl:variable>
-  <xsl:choose>
-    <xsl:when test="parent::*/@spacing = 'compact'">
-      <fo:list-item id="{$id}" 
-          xsl:use-attribute-sets="compact.list.item.spacing">
-        <xsl:copy-of select="$item.contents"/>
-      </fo:list-item>
-    </xsl:when>
-    <xsl:otherwise>
-      <fo:list-item id="{$id}" xsl:use-attribute-sets="list.item.spacing">
-        <xsl:copy-of select="$item.contents"/>
-      </fo:list-item>
-    </xsl:otherwise>
-  </xsl:choose>
-</xsl:template>
-
-<!-- workaround bug in passivetex fo output for orderedlist -->
-<xsl:template match="orderedlist/listitem">
-  <xsl:variable name="id">
-  <xsl:call-template name="object.id"/></xsl:variable>
-  <xsl:variable name="item.contents">
-    <fo:list-item-label end-indent="label-end()">
-      <fo:block>
-        <xsl:apply-templates select="." mode="item-number"/>
-      </fo:block>
-    </fo:list-item-label>
-    <fo:list-item-body start-indent="body-start()">
-      <xsl:apply-templates/>    <!-- removed extra block wrapper -->
-    </fo:list-item-body>
-  </xsl:variable>
-  <xsl:choose>
-    <xsl:when test="parent::*/@spacing = 'compact'">
-      <fo:list-item id="{$id}" 
-          xsl:use-attribute-sets="compact.list.item.spacing">
-        <xsl:copy-of select="$item.contents"/>
-      </fo:list-item>
-    </xsl:when>
-    <xsl:otherwise>
-      <fo:list-item id="{$id}" xsl:use-attribute-sets="list.item.spacing">
-        <xsl:copy-of select="$item.contents"/>
-      </fo:list-item>
-    </xsl:otherwise>
-  </xsl:choose>
-</xsl:template>
-
-<!-- workaround bug in passivetex fo output for variablelist -->
-<xsl:param name="variablelist.as.blocks" select="1"/>
-<xsl:template match="varlistentry" mode="vl.as.blocks">
-  <xsl:variable name="id">
-    <xsl:call-template name="object.id"/></xsl:variable>
-  <fo:block id="{$id}" xsl:use-attribute-sets="list.item.spacing"  
-      keep-together.within-column="always" 
-      keep-with-next.within-column="always">
-    <xsl:apply-templates select="term"/>
-  </fo:block>
-  <fo:block start-indent="0.5in" end-indent="0in" 
-            space-after.minimum="0.2em" 
-            space-after.optimum="0.4em" 
-            space-after.maximum="0.6em">
-    <fo:block>
-      <xsl:apply-templates select="listitem"/>
-    </fo:block>
-  </fo:block>
-</xsl:template>
-
-
-<!-- workaround bug in footers: force right-align w/two 80|30 cols -->
-<xsl:template name="footer.table">
-  <xsl:param name="pageclass" select="''"/>
-  <xsl:param name="sequence" select="''"/>
-  <xsl:param name="gentext-key" select="''"/>
-  <xsl:choose>
-    <xsl:when test="$pageclass = 'index'">
-      <xsl:attribute name="margin-left">0pt</xsl:attribute>
-    </xsl:when>
-  </xsl:choose>
-  <xsl:variable name="candidate">
-    <fo:table table-layout="fixed" width="100%">
-      <fo:table-column column-number="1" column-width="80%"/>
-      <fo:table-column column-number="2" column-width="20%"/>
-      <fo:table-body>
-        <fo:table-row height="14pt">
-          <fo:table-cell text-align="left" display-align="after">
-            <xsl:attribute name="relative-align">baseline</xsl:attribute>
-            <fo:block> 
-              <fo:block> </fo:block><!-- empty cell -->
-            </fo:block>
-          </fo:table-cell>
-          <fo:table-cell text-align="center" display-align="after">
-            <xsl:attribute name="relative-align">baseline</xsl:attribute>
-            <fo:block>
-              <xsl:call-template name="footer.content">
-                <xsl:with-param name="pageclass" select="$pageclass"/>
-                <xsl:with-param name="sequence" select="$sequence"/>
-                <xsl:with-param name="position" select="'center'"/>
-                <xsl:with-param name="gentext-key" select="$gentext-key"/>
-              </xsl:call-template>
-            </fo:block>
-          </fo:table-cell>
-        </fo:table-row>
-      </fo:table-body>
-    </fo:table>
-  </xsl:variable>
-  <!-- Really output a footer? -->
-  <xsl:choose>
-    <xsl:when test="$pageclass='titlepage' and $gentext-key='book'
-                    and $sequence='first'">
-      <!-- no, book titlepages have no footers at all -->
-    </xsl:when>
-    <xsl:when test="$sequence = 'blank' and $footers.on.blank.pages = 0">
-      <!-- no output -->
-    </xsl:when>
-    <xsl:otherwise>
-      <xsl:copy-of select="$candidate"/>
-    </xsl:otherwise>
-  </xsl:choose>
-</xsl:template>
-
-
-<!-- fix bug in headers: force right-align w/two 40|60 cols -->
-<xsl:template name="header.table">
-  <xsl:param name="pageclass" select="''"/>
-  <xsl:param name="sequence" select="''"/>
-  <xsl:param name="gentext-key" select="''"/>
-  <xsl:choose>
-    <xsl:when test="$pageclass = 'index'">
-      <xsl:attribute name="margin-left">0pt</xsl:attribute>
-    </xsl:when>
-  </xsl:choose>
-  <xsl:variable name="candidate">
-    <fo:table table-layout="fixed" width="100%">
-      <xsl:call-template name="head.sep.rule">
-        <xsl:with-param name="pageclass" select="$pageclass"/>
-        <xsl:with-param name="sequence" select="$sequence"/>
-        <xsl:with-param name="gentext-key" select="$gentext-key"/>
-      </xsl:call-template>
-      <fo:table-column column-number="1" column-width="40%"/>
-      <fo:table-column column-number="2" column-width="60%"/>
-      <fo:table-body>
-        <fo:table-row height="14pt">
-          <fo:table-cell text-align="left" display-align="before">
-            <xsl:attribute name="relative-align">baseline</xsl:attribute>
-            <fo:block>
-              <fo:block> </fo:block><!-- empty cell -->
-            </fo:block>
-          </fo:table-cell>
-          <fo:table-cell text-align="center" display-align="before">
-            <xsl:attribute name="relative-align">baseline</xsl:attribute>
-            <fo:block>
-              <xsl:call-template name="header.content">
-                <xsl:with-param name="pageclass" select="$pageclass"/>
-                <xsl:with-param name="sequence" select="$sequence"/>
-                <xsl:with-param name="position" select="'center'"/>
-                <xsl:with-param name="gentext-key" select="$gentext-key"/>
-              </xsl:call-template>
-            </fo:block>
-          </fo:table-cell>
-        </fo:table-row>
-      </fo:table-body>
-    </fo:table>
-  </xsl:variable>
-  <!-- Really output a header? -->
-  <xsl:choose>
-    <xsl:when test="$pageclass = 'titlepage' and $gentext-key = 'book'
-                    and $sequence='first'">
-      <!-- no, book titlepages have no headers at all -->
-    </xsl:when>
-    <xsl:when test="$sequence = 'blank' and $headers.on.blank.pages = 0">
-      <!-- no output -->
-    </xsl:when>
-    <xsl:otherwise>
-      <xsl:copy-of select="$candidate"/>
-    </xsl:otherwise>
-  </xsl:choose>
-</xsl:template>
-
-
-<!-- Bug-fix for Suse 10 PassiveTex version -->
-<!-- Precompute attribute values 'cos PassiveTex is too stupid: -->
-<xsl:attribute-set name="component.title.properties">
-  <xsl:attribute name="keep-with-next.within-column">always</xsl:attribute>
-  <xsl:attribute name="space-before.optimum">
-    <xsl:value-of select="concat($body.font.master, 'pt')"/>
-  </xsl:attribute>
-  <xsl:attribute name="space-before.minimum">
-    <xsl:value-of select="$body.font.master * 0.8"/>
-    <xsl:text>pt</xsl:text>
-  </xsl:attribute>
-  <xsl:attribute name="space-before.maximum">
-    <xsl:value-of select="$body.font.master * 1.2"/>
-    <xsl:text>pt</xsl:text>
-  </xsl:attribute>
-  <xsl:attribute name="hyphenate">false</xsl:attribute>
-</xsl:attribute-set>
-
-
-</xsl:stylesheet>
diff --git a/Utilities/cmbzip2/bz-html.xsl b/Utilities/cmbzip2/bz-html.xsl
deleted file mode 100644
index 1785fff..0000000
--- a/Utilities/cmbzip2/bz-html.xsl
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0"?> <!-- -*- sgml -*- -->
-<!DOCTYPE xsl:stylesheet [ <!ENTITY bz-css SYSTEM "./bzip.css"> ]>
-
-<xsl:stylesheet 
-   xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
-
-<xsl:import href="http://docbook.sourceforge.net/release/xsl/current/html/docbook.xsl"/>
-<xsl:import href="bz-common.xsl"/>
-
-<!-- use 8859-1 encoding -->
-<xsl:output method="html" encoding="ISO-8859-1" indent="yes"/>
-
-<!-- we include the css directly when generating one large file -->
-<xsl:template name="user.head.content">  
-  <style type="text/css" media="screen">
-    <xsl:text>&bz-css;</xsl:text>
-  </style>
-</xsl:template>
-
-</xsl:stylesheet>
diff --git a/Utilities/cmbzip2/bzdiff b/Utilities/cmbzip2/bzdiff
deleted file mode 100644
index c4c9964..0000000
--- a/Utilities/cmbzip2/bzdiff
+++ /dev/null
@@ -1,76 +0,0 @@
-#!/bin/sh
-# sh is buggy on RS/6000 AIX 3.2. Replace above line with #!/bin/ksh
-
-# Bzcmp/diff wrapped for bzip2, 
-# adapted from zdiff by Philippe Troin <phil@fifi.org> for Debian GNU/Linux.
-
-# Bzcmp and bzdiff are used to invoke the cmp or the  diff  pro-
-# gram  on compressed files.  All options specified are passed
-# directly to cmp or diff.  If only 1 file is specified,  then
-# the  files  compared  are file1 and an uncompressed file1.gz.
-# If two files are specified, then they are  uncompressed  (if
-# necessary) and fed to cmp or diff.  The exit status from cmp
-# or diff is preserved.
-
-PATH="/usr/bin:/bin:$PATH"; export PATH
-prog=`echo $0 | sed 's|.*/||'`
-case "$prog" in
-  *cmp) comp=${CMP-cmp}   ;;
-  *)    comp=${DIFF-diff} ;;
-esac
-
-OPTIONS=
-FILES=
-for ARG
-do
-    case "$ARG" in
-    -*) OPTIONS="$OPTIONS $ARG";;
-     *) if test -f "$ARG"; then
-            FILES="$FILES $ARG"
-        else
-            echo "${prog}: $ARG not found or not a regular file"
-        exit 1
-        fi ;;
-    esac
-done
-if test -z "$FILES"; then
-    echo "Usage: $prog [${comp}_options] file [file]"
-    exit 1
-fi
-tmp=`mktemp ${TMPDIR:-/tmp}/bzdiff.XXXXXXXXXX` || {
-      echo 'cannot create a temporary file' >&2
-      exit 1
-}
-set $FILES
-if test $# -eq 1; then
-    FILE=`echo "$1" | sed 's/.bz2$//'`
-    bzip2 -cd "$FILE.bz2" | $comp $OPTIONS - "$FILE"
-    STAT="$?"
-
-elif test $# -eq 2; then
-    case "$1" in
-        *.bz2)
-                case "$2" in
-            *.bz2)
-            F=`echo "$2" | sed 's|.*/||;s|.bz2$||'`
-                        bzip2 -cdfq "$2" > $tmp
-                        bzip2 -cdfq "$1" | $comp $OPTIONS - $tmp
-                        STAT="$?"
-            /bin/rm -f $tmp;;
-
-                *)      bzip2 -cdfq "$1" | $comp $OPTIONS - "$2"
-                        STAT="$?";;
-                esac;;
-        *)      case "$2" in
-            *.bz2)
-                        bzip2 -cdfq "$2" | $comp $OPTIONS "$1" -
-                        STAT="$?";;
-                *)      $comp $OPTIONS "$1" "$2"
-                        STAT="$?";;
-                esac;;
-    esac
-        exit "$STAT"
-else
-    echo "Usage: $prog [${comp}_options] file [file]"
-    exit 1
-fi
diff --git a/Utilities/cmbzip2/bzdiff.1 b/Utilities/cmbzip2/bzdiff.1
deleted file mode 100644
index adb7a8e..0000000
--- a/Utilities/cmbzip2/bzdiff.1
+++ /dev/null
@@ -1,47 +0,0 @@
-\"Shamelessly copied from zmore.1 by Philippe Troin <phil@fifi.org>
-\"for Debian GNU/Linux
-.TH BZDIFF 1
-.SH NAME
-bzcmp, bzdiff \- compare bzip2 compressed files
-.SH SYNOPSIS
-.B bzcmp
-[ cmp_options ] file1
-[ file2 ]
-.br
-.B bzdiff
-[ diff_options ] file1
-[ file2 ]
-.SH DESCRIPTION
-.I  Bzcmp
-and 
-.I bzdiff
-are used to invoke the
-.I cmp
-or the
-.I diff
-program on bzip2 compressed files.  All options specified are passed
-directly to
-.I cmp
-or
-.IR diff "."
-If only 1 file is specified, then the files compared are
-.I file1
-and an uncompressed
-.IR file1 ".bz2."
-If two files are specified, then they are uncompressed if necessary and fed to
-.I cmp
-or
-.IR diff "."
-The exit status from 
-.I cmp
-or
-.I diff
-is preserved.
-.SH "SEE ALSO"
-cmp(1), diff(1), bzmore(1), bzless(1), bzgrep(1), bzip2(1)
-.SH BUGS
-Messages from the
-.I cmp
-or
-.I diff
-programs refer to temporary filenames instead of those specified.
diff --git a/Utilities/cmbzip2/bzgrep b/Utilities/cmbzip2/bzgrep
deleted file mode 100644
index 8ccf919..0000000
--- a/Utilities/cmbzip2/bzgrep
+++ /dev/null
@@ -1,75 +0,0 @@
-#!/bin/sh
-
-# Bzgrep wrapped for bzip2, 
-# adapted from zgrep by Philippe Troin <phil@fifi.org> for Debian GNU/Linux.
-## zgrep notice:
-## zgrep -- a wrapper around a grep program that decompresses files as needed
-## Adapted from a version sent by Charles Levert <charles@comm.polymtl.ca>
-
-PATH="/usr/bin:$PATH"; export PATH
-
-prog=`echo $0 | sed 's|.*/||'`
-case "$prog" in
-    *egrep) grep=${EGREP-egrep} ;;
-    *fgrep) grep=${FGREP-fgrep} ;;
-    *)  grep=${GREP-grep}   ;;
-esac
-pat=""
-while test $# -ne 0; do
-  case "$1" in
-  -e | -f) opt="$opt $1"; shift; pat="$1"
-           if test "$grep" = grep; then  # grep is buggy with -e on SVR4
-             grep=egrep
-           fi;;
-  -A | -B) opt="$opt $1 $2"; shift;;
-  -*)      opt="$opt $1";;
-   *)      if test -z "$pat"; then
-         pat="$1"
-       else
-         break;
-           fi;;
-  esac
-  shift
-done
-
-if test -z "$pat"; then
-  echo "grep through bzip2 files"
-  echo "usage: $prog [grep_options] pattern [files]"
-  exit 1
-fi
-
-list=0
-silent=0
-op=`echo "$opt" | sed -e 's/ //g' -e 's/-//g'`
-case "$op" in
-  *l*) list=1
-esac
-case "$op" in
-  *h*) silent=1
-esac
-
-if test $# -eq 0; then
-  bzip2 -cdfq | $grep $opt "$pat"
-  exit $?
-fi
-
-res=0
-for i do
-  if test -f "$i"; then :; else if test -f "$i.bz2"; then i="$i.bz2"; fi; fi
-  if test $list -eq 1; then
-    bzip2 -cdfq "$i" | $grep $opt "$pat" 2>&1 > /dev/null && echo $i
-    r=$?
-  elif test $# -eq 1 -o $silent -eq 1; then
-    bzip2 -cdfq "$i" | $grep $opt "$pat"
-    r=$?
-  else
-    j=${i//\\/\\\\}
-    j=${j//|/\\|}
-    j=${j//&/\\&}
-    j=`printf "%s" "$j" | tr '\n' ' '`
-    bzip2 -cdfq "$i" | $grep $opt "$pat" | sed "s|^|${j}:|"
-    r=$?
-  fi
-  test "$r" -ne 0 && res="$r"
-done
-exit $res
diff --git a/Utilities/cmbzip2/bzgrep.1 b/Utilities/cmbzip2/bzgrep.1
deleted file mode 100644
index 930af8c..0000000
--- a/Utilities/cmbzip2/bzgrep.1
+++ /dev/null
@@ -1,56 +0,0 @@
-\"Shamelessly copied from zmore.1 by Philippe Troin <phil@fifi.org>
-\"for Debian GNU/Linux
-.TH BZGREP 1
-.SH NAME
-bzgrep, bzfgrep, bzegrep \- search possibly bzip2 compressed files for a regular expression
-.SH SYNOPSIS
-.B bzgrep
-[ grep_options ]
-.BI  [\ -e\ ] " pattern"
-.IR filename ".\|.\|."
-.br
-.B bzegrep
-[ egrep_options ]
-.BI  [\ -e\ ] " pattern"
-.IR filename ".\|.\|."
-.br
-.B bzfgrep
-[ fgrep_options ]
-.BI  [\ -e\ ] " pattern"
-.IR filename ".\|.\|."
-.SH DESCRIPTION
-.IR  Bzgrep
-is used to invoke the
-.I grep
-on bzip2-compressed files. All options specified are passed directly to
-.I grep.
-If no file is specified, then the standard input is decompressed
-if necessary and fed to grep.
-Otherwise the given files are uncompressed if necessary and fed to
-.I grep.
-.PP
-If
-.I bzgrep
-is invoked as
-.I bzegrep
-or
-.I bzfgrep
-then
-.I egrep
-or
-.I fgrep
-is used instead of
-.I grep.
-If the GREP environment variable is set,
-.I bzgrep
-uses it as the
-.I grep
-program to be invoked. For example:
-
-    for sh:  GREP=fgrep  bzgrep string files
-    for csh: (setenv GREP fgrep; bzgrep string files)
-.SH AUTHOR
-Charles Levert (charles@comm.polymtl.ca). Adapted to bzip2 by Philippe
-Troin <phil@fifi.org> for Debian GNU/Linux.
-.SH "SEE ALSO"
-grep(1), egrep(1), fgrep(1), bzdiff(1), bzmore(1), bzless(1), bzip2(1)
diff --git a/Utilities/cmbzip2/bzip.css b/Utilities/cmbzip2/bzip.css
deleted file mode 100644
index 4feb401..0000000
--- a/Utilities/cmbzip2/bzip.css
+++ /dev/null
@@ -1,74 +0,0 @@
-/* Colours:
-#74240f  dark brown      h1, h2, h3, h4
-#336699  medium blue     links
-#339999  turquoise       link hover colour
-#202020  almost black    general text
-#761596  purple          md5sum text
-#626262  dark gray       pre border
-#eeeeee  very light gray pre background
-#f2f2f9  very light blue nav table background
-#3366cc  medium blue     nav table border
-*/
-
-a, a:link, a:visited, a:active { color: #336699; }
-a:hover { color: #339999; }
-
-body { font: 80%/126% sans-serif; }
-h1, h2, h3, h4 { color: #74240f; }
-
-dt { color: #336699; font-weight: bold }
-dd { 
- margin-left: 1.5em; 
- padding-bottom: 0.8em;
-}
-
-/* -- ruler -- */
-div.hr_blue { 
-  height:  3px; 
-  background:#ffffff url("/images/hr_blue.png") repeat-x; }
-div.hr_blue hr { display:none; }
-
-/* release styles */
-#release p { margin-top: 0.4em; }
-#release .md5sum { color: #761596; }
-
-
-/* ------ styles for docs|manuals|howto ------ */
-/* -- lists -- */
-ul  { 
- margin:     0px 4px 16px 16px;
- padding:    0px;
- list-style: url("/images/li-blue.png"); 
-}
-ul li { 
- margin-bottom: 10px;
-}
-ul ul   { 
- list-style-type:  none; 
- list-style-image: none; 
- margin-left:      0px; 
-}
-
-/* header / footer nav tables */
-table.nav {
- border:     solid 1px #3366cc;
- background: #f2f2f9;
- background-color: #f2f2f9;
- margin-bottom: 0.5em;
-}
-/* don't have underlined links in chunked nav menus */
-table.nav a { text-decoration: none; }
-table.nav a:hover { text-decoration: underline; }
-table.nav td { font-size: 85%; }
-
-code, tt, pre { font-size: 120%; }
-code, tt { color: #761596; }
-
-div.literallayout, pre.programlisting, pre.screen {
- color:      #000000;
- padding:    0.5em;
- background: #eeeeee;
- border:     1px solid #626262;
- background-color: #eeeeee;
- margin: 4px 0px 4px 0px; 
-}
diff --git a/Utilities/cmbzip2/bzip2.1 b/Utilities/cmbzip2/bzip2.1
deleted file mode 100644
index a313f2d..0000000
--- a/Utilities/cmbzip2/bzip2.1
+++ /dev/null
@@ -1,454 +0,0 @@
-.PU
-.TH bzip2 1
-.SH NAME
-bzip2, bunzip2 \- a block-sorting file compressor, v1.0.4
-.br
-bzcat \- decompresses files to stdout
-.br
-bzip2recover \- recovers data from damaged bzip2 files
-
-.SH SYNOPSIS
-.ll +8
-.B bzip2
-.RB [ " \-cdfkqstvzVL123456789 " ]
-[
-.I "filenames \&..."
-]
-.ll -8
-.br
-.B bunzip2
-.RB [ " \-fkvsVL " ]
-[ 
-.I "filenames \&..."
-]
-.br
-.B bzcat
-.RB [ " \-s " ]
-[ 
-.I "filenames \&..."
-]
-.br
-.B bzip2recover
-.I "filename"
-
-.SH DESCRIPTION
-.I bzip2
-compresses files using the Burrows-Wheeler block sorting
-text compression algorithm, and Huffman coding.  Compression is
-generally considerably better than that achieved by more conventional
-LZ77/LZ78-based compressors, and approaches the performance of the PPM
-family of statistical compressors.
-
-The command-line options are deliberately very similar to 
-those of 
-.I GNU gzip, 
-but they are not identical.
-
-.I bzip2
-expects a list of file names to accompany the
-command-line flags.  Each file is replaced by a compressed version of
-itself, with the name "original_name.bz2".  
-Each compressed file
-has the same modification date, permissions, and, when possible,
-ownership as the corresponding original, so that these properties can
-be correctly restored at decompression time.  File name handling is
-naive in the sense that there is no mechanism for preserving original
-file names, permissions, ownerships or dates in filesystems which lack
-these concepts, or have serious file name length restrictions, such as
-MS-DOS.
-
-.I bzip2
-and
-.I bunzip2
-will by default not overwrite existing
-files.  If you want this to happen, specify the \-f flag.
-
-If no file names are specified,
-.I bzip2
-compresses from standard
-input to standard output.  In this case,
-.I bzip2
-will decline to
-write compressed output to a terminal, as this would be entirely
-incomprehensible and therefore pointless.
-
-.I bunzip2
-(or
-.I bzip2 \-d) 
-decompresses all
-specified files.  Files which were not created by 
-.I bzip2
-will be detected and ignored, and a warning issued.  
-.I bzip2
-attempts to guess the filename for the decompressed file 
-from that of the compressed file as follows:
-
-       filename.bz2    becomes   filename
-       filename.bz     becomes   filename
-       filename.tbz2   becomes   filename.tar
-       filename.tbz    becomes   filename.tar
-       anyothername    becomes   anyothername.out
-
-If the file does not end in one of the recognised endings, 
-.I .bz2, 
-.I .bz, 
-.I .tbz2
-or
-.I .tbz, 
-.I bzip2 
-complains that it cannot
-guess the name of the original file, and uses the original name
-with
-.I .out
-appended.
-
-As with compression, supplying no
-filenames causes decompression from 
-standard input to standard output.
-
-.I bunzip2 
-will correctly decompress a file which is the
-concatenation of two or more compressed files.  The result is the
-concatenation of the corresponding uncompressed files.  Integrity
-testing (\-t) 
-of concatenated 
-compressed files is also supported.
-
-You can also compress or decompress files to the standard output by
-giving the \-c flag.  Multiple files may be compressed and
-decompressed like this.  The resulting outputs are fed sequentially to
-stdout.  Compression of multiple files 
-in this manner generates a stream
-containing multiple compressed file representations.  Such a stream
-can be decompressed correctly only by
-.I bzip2 
-version 0.9.0 or
-later.  Earlier versions of
-.I bzip2
-will stop after decompressing
-the first file in the stream.
-
-.I bzcat
-(or
-.I bzip2 -dc) 
-decompresses all specified files to
-the standard output.
-
-.I bzip2
-will read arguments from the environment variables
-.I BZIP2
-and
-.I BZIP,
-in that order, and will process them
-before any arguments read from the command line.  This gives a 
-convenient way to supply default arguments.
-
-Compression is always performed, even if the compressed 
-file is slightly
-larger than the original.  Files of less than about one hundred bytes
-tend to get larger, since the compression mechanism has a constant
-overhead in the region of 50 bytes.  Random data (including the output
-of most file compressors) is coded at about 8.05 bits per byte, giving
-an expansion of around 0.5%.
-
-As a self-check for your protection, 
-.I 
-bzip2
-uses 32-bit CRCs to
-make sure that the decompressed version of a file is identical to the
-original.  This guards against corruption of the compressed data, and
-against undetected bugs in
-.I bzip2
-(hopefully very unlikely).  The
-chances of data corruption going undetected is microscopic, about one
-chance in four billion for each file processed.  Be aware, though, that
-the check occurs upon decompression, so it can only tell you that
-something is wrong.  It can't help you 
-recover the original uncompressed
-data.  You can use 
-.I bzip2recover
-to try to recover data from
-damaged files.
-
-Return values: 0 for a normal exit, 1 for environmental problems (file
-not found, invalid flags, I/O errors, &c), 2 to indicate a corrupt
-compressed file, 3 for an internal consistency error (eg, bug) which
-caused
-.I bzip2
-to panic.
-
-.SH OPTIONS
-.TP
-.B \-c --stdout
-Compress or decompress to standard output.
-.TP
-.B \-d --decompress
-Force decompression.  
-.I bzip2, 
-.I bunzip2 
-and
-.I bzcat 
-are
-really the same program, and the decision about what actions to take is
-done on the basis of which name is used.  This flag overrides that
-mechanism, and forces 
-.I bzip2
-to decompress.
-.TP
-.B \-z --compress
-The complement to \-d: forces compression, regardless of the
-invocation name.
-.TP
-.B \-t --test
-Check integrity of the specified file(s), but don't decompress them.
-This really performs a trial decompression and throws away the result.
-.TP
-.B \-f --force
-Force overwrite of output files.  Normally,
-.I bzip2 
-will not overwrite
-existing output files.  Also forces 
-.I bzip2 
-to break hard links
-to files, which it otherwise wouldn't do.
-
-bzip2 normally declines to decompress files which don't have the
-correct magic header bytes.  If forced (-f), however, it will pass
-such files through unmodified.  This is how GNU gzip behaves.
-.TP
-.B \-k --keep
-Keep (don't delete) input files during compression
-or decompression.
-.TP
-.B \-s --small
-Reduce memory usage, for compression, decompression and testing.  Files
-are decompressed and tested using a modified algorithm which only
-requires 2.5 bytes per block byte.  This means any file can be
-decompressed in 2300k of memory, albeit at about half the normal speed.
-
-During compression, \-s selects a block size of 200k, which limits
-memory use to around the same figure, at the expense of your compression
-ratio.  In short, if your machine is low on memory (8 megabytes or
-less), use \-s for everything.  See MEMORY MANAGEMENT below.
-.TP
-.B \-q --quiet
-Suppress non-essential warning messages.  Messages pertaining to
-I/O errors and other critical events will not be suppressed.
-.TP
-.B \-v --verbose
-Verbose mode -- show the compression ratio for each file processed.
-Further \-v's increase the verbosity level, spewing out lots of
-information which is primarily of interest for diagnostic purposes.
-.TP
-.B \-L --license -V --version
-Display the software version, license terms and conditions.
-.TP
-.B \-1 (or \-\-fast) to \-9 (or \-\-best)
-Set the block size to 100 k, 200 k ..  900 k when compressing.  Has no
-effect when decompressing.  See MEMORY MANAGEMENT below.
-The \-\-fast and \-\-best aliases are primarily for GNU gzip 
-compatibility.  In particular, \-\-fast doesn't make things
-significantly faster.  
-And \-\-best merely selects the default behaviour.
-.TP
-.B \--
-Treats all subsequent arguments as file names, even if they start
-with a dash.  This is so you can handle files with names beginning
-with a dash, for example: bzip2 \-- \-myfilename.
-.TP
-.B \--repetitive-fast --repetitive-best
-These flags are redundant in versions 0.9.5 and above.  They provided
-some coarse control over the behaviour of the sorting algorithm in
-earlier versions, which was sometimes useful.  0.9.5 and above have an
-improved algorithm which renders these flags irrelevant.
-
-.SH MEMORY MANAGEMENT
-.I bzip2 
-compresses large files in blocks.  The block size affects
-both the compression ratio achieved, and the amount of memory needed for
-compression and decompression.  The flags \-1 through \-9
-specify the block size to be 100,000 bytes through 900,000 bytes (the
-default) respectively.  At decompression time, the block size used for
-compression is read from the header of the compressed file, and
-.I bunzip2
-then allocates itself just enough memory to decompress
-the file.  Since block sizes are stored in compressed files, it follows
-that the flags \-1 to \-9 are irrelevant to and so ignored
-during decompression.
-
-Compression and decompression requirements, 
-in bytes, can be estimated as:
-
-       Compression:   400k + ( 8 x block size )
-
-       Decompression: 100k + ( 4 x block size ), or
-                      100k + ( 2.5 x block size )
-
-Larger block sizes give rapidly diminishing marginal returns.  Most of
-the compression comes from the first two or three hundred k of block
-size, a fact worth bearing in mind when using
-.I bzip2
-on small machines.
-It is also important to appreciate that the decompression memory
-requirement is set at compression time by the choice of block size.
-
-For files compressed with the default 900k block size,
-.I bunzip2
-will require about 3700 kbytes to decompress.  To support decompression
-of any file on a 4 megabyte machine, 
-.I bunzip2
-has an option to
-decompress using approximately half this amount of memory, about 2300
-kbytes.  Decompression speed is also halved, so you should use this
-option only where necessary.  The relevant flag is -s.
-
-In general, try and use the largest block size memory constraints allow,
-since that maximises the compression achieved.  Compression and
-decompression speed are virtually unaffected by block size.
-
-Another significant point applies to files which fit in a single block
--- that means most files you'd encounter using a large block size.  The
-amount of real memory touched is proportional to the size of the file,
-since the file is smaller than a block.  For example, compressing a file
-20,000 bytes long with the flag -9 will cause the compressor to
-allocate around 7600k of memory, but only touch 400k + 20000 * 8 = 560
-kbytes of it.  Similarly, the decompressor will allocate 3700k but only
-touch 100k + 20000 * 4 = 180 kbytes.
-
-Here is a table which summarises the maximum memory usage for different
-block sizes.  Also recorded is the total compressed size for 14 files of
-the Calgary Text Compression Corpus totalling 3,141,622 bytes.  This
-column gives some feel for how compression varies with block size.
-These figures tend to understate the advantage of larger block sizes for
-larger files, since the Corpus is dominated by smaller files.
-
-           Compress   Decompress   Decompress   Corpus
-    Flag     usage      usage       -s usage     Size
-
-     -1      1200k       500k         350k      914704
-     -2      2000k       900k         600k      877703
-     -3      2800k      1300k         850k      860338
-     -4      3600k      1700k        1100k      846899
-     -5      4400k      2100k        1350k      845160
-     -6      5200k      2500k        1600k      838626
-     -7      6100k      2900k        1850k      834096
-     -8      6800k      3300k        2100k      828642
-     -9      7600k      3700k        2350k      828642
-
-.SH RECOVERING DATA FROM DAMAGED FILES
-.I bzip2
-compresses files in blocks, usually 900kbytes long.  Each
-block is handled independently.  If a media or transmission error causes
-a multi-block .bz2
-file to become damaged, it may be possible to
-recover data from the undamaged blocks in the file.
-
-The compressed representation of each block is delimited by a 48-bit
-pattern, which makes it possible to find the block boundaries with
-reasonable certainty.  Each block also carries its own 32-bit CRC, so
-damaged blocks can be distinguished from undamaged ones.
-
-.I bzip2recover
-is a simple program whose purpose is to search for
-blocks in .bz2 files, and write each block out into its own .bz2 
-file.  You can then use
-.I bzip2 
-\-t
-to test the
-integrity of the resulting files, and decompress those which are
-undamaged.
-
-.I bzip2recover
-takes a single argument, the name of the damaged file, 
-and writes a number of files "rec00001file.bz2",
-"rec00002file.bz2", etc, containing the  extracted  blocks.
-The  output  filenames  are  designed  so  that the use of
-wildcards in subsequent processing -- for example,  
-"bzip2 -dc  rec*file.bz2 > recovered_data" -- processes the files in
-the correct order.
-
-.I bzip2recover
-should be of most use dealing with large .bz2
-files,  as  these will contain many blocks.  It is clearly
-futile to use it on damaged single-block  files,  since  a
-damaged  block  cannot  be recovered.  If you wish to minimise 
-any potential data loss through media  or  transmission errors, 
-you might consider compressing with a smaller
-block size.
-
-.SH PERFORMANCE NOTES
-The sorting phase of compression gathers together similar strings in the
-file.  Because of this, files containing very long runs of repeated
-symbols, like "aabaabaabaab ..."  (repeated several hundred times) may
-compress more slowly than normal.  Versions 0.9.5 and above fare much
-better than previous versions in this respect.  The ratio between
-worst-case and average-case compression time is in the region of 10:1.
-For previous versions, this figure was more like 100:1.  You can use the
-\-vvvv option to monitor progress in great detail, if you want.
-
-Decompression speed is unaffected by these phenomena.
-
-.I bzip2
-usually allocates several megabytes of memory to operate
-in, and then charges all over it in a fairly random fashion.  This means
-that performance, both for compressing and decompressing, is largely
-determined by the speed at which your machine can service cache misses.
-Because of this, small changes to the code to reduce the miss rate have
-been observed to give disproportionately large performance improvements.
-I imagine 
-.I bzip2
-will perform best on machines with very large caches.
-
-.SH CAVEATS
-I/O error messages are not as helpful as they could be.
-.I bzip2
-tries hard to detect I/O errors and exit cleanly, but the details of
-what the problem is sometimes seem rather misleading.
-
-This manual page pertains to version 1.0.4 of
-.I bzip2.  
-Compressed data created by this version is entirely forwards and
-backwards compatible with the previous public releases, versions
-0.1pl2, 0.9.0, 0.9.5, 1.0.0, 1.0.1, 1.0.2 and 1.0.3, but with the following
-exception: 0.9.0 and above can correctly decompress multiple
-concatenated compressed files.  0.1pl2 cannot do this; it will stop
-after decompressing just the first file in the stream.
-
-.I bzip2recover
-versions prior to 1.0.2 used 32-bit integers to represent
-bit positions in compressed files, so they could not handle compressed
-files more than 512 megabytes long.  Versions 1.0.2 and above use
-64-bit ints on some platforms which support them (GNU supported
-targets, and Windows).  To establish whether or not bzip2recover was
-built with such a limitation, run it without arguments.  In any event
-you can build yourself an unlimited version if you can recompile it
-with MaybeUInt64 set to be an unsigned 64-bit integer.
-
-
-
-.SH AUTHOR
-Julian Seward, jsewardbzip.org.
-
-http://www.bzip.org
-
-The ideas embodied in
-.I bzip2
-are due to (at least) the following
-people: Michael Burrows and David Wheeler (for the block sorting
-transformation), David Wheeler (again, for the Huffman coder), Peter
-Fenwick (for the structured coding model in the original
-.I bzip,
-and many refinements), and Alistair Moffat, Radford Neal and Ian Witten
-(for the arithmetic coder in the original
-.I bzip).  
-I am much
-indebted for their help, support and advice.  See the manual in the
-source distribution for pointers to sources of documentation.  Christian
-von Roques encouraged me to look for faster sorting algorithms, so as to
-speed up compression.  Bela Lubkin encouraged me to improve the
-worst-case compression performance.  
-Donna Robinson XMLised the documentation.
-The bz* scripts are derived from those of GNU gzip.
-Many people sent patches, helped
-with portability problems, lent machines, gave advice and were generally
-helpful.
diff --git a/Utilities/cmbzip2/bzip2.1.preformatted b/Utilities/cmbzip2/bzip2.1.preformatted
deleted file mode 100644
index 15e16e5..0000000
--- a/Utilities/cmbzip2/bzip2.1.preformatted
+++ /dev/null
@@ -1,399 +0,0 @@
-bzip2(1)                                                 bzip2(1)
-
-
-
-NNAAMMEE
-       bzip2, bunzip2 − a block‐sorting file compressor, v1.0.4
-       bzcat − decompresses files to stdout
-       bzip2recover − recovers data from damaged bzip2 files
-
-
-SSYYNNOOPPSSIISS
-       bbzziipp22 [ −−ccddffkkqqssttvvzzVVLL112233445566778899 ] [ _f_i_l_e_n_a_m_e_s _._._.  ]
-       bbuunnzziipp22 [ −−ffkkvvssVVLL ] [ _f_i_l_e_n_a_m_e_s _._._.  ]
-       bbzzccaatt [ −−ss ] [ _f_i_l_e_n_a_m_e_s _._._.  ]
-       bbzziipp22rreeccoovveerr _f_i_l_e_n_a_m_e
-
-
-DDEESSCCRRIIPPTTIIOONN
-       _b_z_i_p_2  compresses  files  using  the Burrows‐Wheeler block
-       sorting text compression algorithm,  and  Huffman  coding.
-       Compression  is  generally  considerably  better than that
-       achieved by more conventional LZ77/LZ78‐based compressors,
-       and  approaches  the performance of the PPM family of sta­
-       tistical compressors.
-
-       The command‐line options are deliberately very similar  to
-       those of _G_N_U _g_z_i_p_, but they are not identical.
-
-       _b_z_i_p_2  expects  a list of file names to accompany the com­
-       mand‐line flags.  Each file is replaced  by  a  compressed
-       version  of  itself,  with  the  name "original_name.bz2".
-       Each compressed file has the same modification date,  per­
-       missions, and, when possible, ownership as the correspond­
-       ing original, so that these properties  can  be  correctly
-       restored  at  decompression  time.   File name handling is
-       naive in the sense that there is no mechanism for preserv­
-       ing  original file names, permissions, ownerships or dates
-       in filesystems which lack these concepts, or have  serious
-       file name length restrictions, such as MS‐DOS.
-
-       _b_z_i_p_2  and  _b_u_n_z_i_p_2 will by default not overwrite existing
-       files.  If you want this to happen, specify the −f flag.
-
-       If no file names  are  specified,  _b_z_i_p_2  compresses  from
-       standard  input  to  standard output.  In this case, _b_z_i_p_2
-       will decline to write compressed output to a terminal,  as
-       this  would  be  entirely  incomprehensible  and therefore
-       pointless.
-
-       _b_u_n_z_i_p_2 (or _b_z_i_p_2 _−_d_) decompresses  all  specified  files.
-       Files which were not created by _b_z_i_p_2 will be detected and
-       ignored, and a warning issued.  _b_z_i_p_2  attempts  to  guess
-       the  filename  for  the decompressed file from that of the
-       compressed file as follows:
-
-              filename.bz2    becomes   filename
-              filename.bz     becomes   filename
-              filename.tbz2   becomes   filename.tar
-              filename.tbz    becomes   filename.tar
-              anyothername    becomes   anyothername.out
-
-       If the file does not end in one of the recognised endings,
-       _._b_z_2_,  _._b_z_,  _._t_b_z_2 or _._t_b_z_, _b_z_i_p_2 complains that it cannot
-       guess the name of the original file, and uses the original
-       name with _._o_u_t appended.
-
-       As  with compression, supplying no filenames causes decom­
-       pression from standard input to standard output.
-
-       _b_u_n_z_i_p_2 will correctly decompress a file which is the con­
-       catenation of two or more compressed files.  The result is
-       the concatenation of the corresponding uncompressed files.
-       Integrity testing (−t) of concatenated compressed files is
-       also supported.
-
-       You can also compress or decompress files to the  standard
-       output  by giving the −c flag.  Multiple files may be com­
-       pressed and decompressed like this.  The resulting outputs
-       are  fed  sequentially to stdout.  Compression of multiple
-       files in this manner generates a stream containing  multi­
-       ple compressed file representations.  Such a stream can be
-       decompressed correctly only  by  _b_z_i_p_2  version  0.9.0  or
-       later.   Earlier  versions of _b_z_i_p_2 will stop after decom­
-       pressing the first file in the stream.
-
-       _b_z_c_a_t (or _b_z_i_p_2 _‐_d_c_) decompresses all specified  files  to
-       the standard output.
-
-       _b_z_i_p_2  will  read arguments from the environment variables
-       _B_Z_I_P_2 and _B_Z_I_P_, in  that  order,  and  will  process  them
-       before  any  arguments  read  from the command line.  This
-       gives a convenient way to supply default arguments.
-
-       Compression is always performed, even  if  the  compressed
-       file  is slightly larger than the original.  Files of less
-       than about one hundred bytes tend to get larger, since the
-       compression  mechanism  has  a  constant  overhead  in the
-       region of 50 bytes.  Random data (including the output  of
-       most  file  compressors)  is  coded at about 8.05 bits per
-       byte, giving an expansion of around 0.5%.
-
-       As a self‐check for your  protection,  _b_z_i_p_2  uses  32‐bit
-       CRCs  to make sure that the decompressed version of a file
-       is identical to the original.  This guards against corrup­
-       tion  of  the compressed data, and against undetected bugs
-       in _b_z_i_p_2 (hopefully very unlikely).  The chances  of  data
-       corruption  going  undetected  is  microscopic,  about one
-       chance in four billion for each file processed.  Be aware,
-       though,  that  the  check occurs upon decompression, so it
-       can only tell you that something is wrong.  It can’t  help
-       you  recover  the original uncompressed data.  You can use
-       _b_z_i_p_2_r_e_c_o_v_e_r to try to recover data from damaged files.
-
-       Return values: 0 for a normal exit,  1  for  environmental
-       problems  (file not found, invalid flags, I/O errors, &c),
-       2 to indicate a corrupt compressed file, 3 for an internal
-       consistency error (eg, bug) which caused _b_z_i_p_2 to panic.
-
-
-OOPPTTIIOONNSS
-       −−cc ‐‐‐‐ssttddoouutt
-              Compress or decompress to standard output.
-
-       −−dd ‐‐‐‐ddeeccoommpprreessss
-              Force  decompression.  _b_z_i_p_2_, _b_u_n_z_i_p_2 and _b_z_c_a_t are
-              really the same program,  and  the  decision  about
-              what  actions to take is done on the basis of which
-              name is used.  This flag overrides that  mechanism,
-              and forces _b_z_i_p_2 to decompress.
-
-       −−zz ‐‐‐‐ccoommpprreessss
-              The   complement   to   −d:   forces   compression,
-              regardless of the invocation name.
-
-       −−tt ‐‐‐‐tteesstt
-              Check integrity of the specified file(s), but don’t
-              decompress  them.   This  really  performs  a trial
-              decompression and throws away the result.
-
-       −−ff ‐‐‐‐ffoorrccee
-              Force overwrite of output files.   Normally,  _b_z_i_p_2
-              will  not  overwrite  existing  output files.  Also
-              forces _b_z_i_p_2 to break hard links to files, which it
-              otherwise wouldn’t do.
-
-              bzip2  normally  declines to decompress files which
-              don’t have the  correct  magic  header  bytes.   If
-              forced  (‐f),  however,  it  will  pass  such files
-              through unmodified.  This is how GNU gzip  behaves.
-
-       −−kk ‐‐‐‐kkeeeepp
-              Keep  (don’t delete) input files during compression
-              or decompression.
-
-       −−ss ‐‐‐‐ssmmaallll
-              Reduce memory usage, for compression, decompression
-              and  testing.   Files  are  decompressed and tested
-              using a modified algorithm which only requires  2.5
-              bytes  per  block byte.  This means any file can be
-              decompressed in 2300k of memory,  albeit  at  about
-              half the normal speed.
-
-              During  compression,  −s  selects  a  block size of
-              200k, which limits memory use to  around  the  same
-              figure,  at  the expense of your compression ratio.
-              In short, if your  machine  is  low  on  memory  (8
-              megabytes  or  less),  use  −s for everything.  See
-              MEMORY MANAGEMENT below.
-
-       −−qq ‐‐‐‐qquuiieett
-              Suppress non‐essential warning messages.   Messages
-              pertaining  to I/O errors and other critical events
-              will not be suppressed.
-
-       −−vv ‐‐‐‐vveerrbboossee
-              Verbose mode ‐‐ show the compression ratio for each
-              file  processed.   Further  −v’s  increase the ver­
-              bosity level, spewing out lots of information which
-              is primarily of interest for diagnostic purposes.
-
-       −−LL ‐‐‐‐lliicceennssee ‐‐VV ‐‐‐‐vveerrssiioonn
-              Display  the  software  version,  license terms and
-              conditions.
-
-       −−11 ((oorr −−−−ffaasstt)) ttoo −−99 ((oorr −−−−bbeesstt))
-              Set the block size to 100 k, 200 k ..  900  k  when
-              compressing.   Has  no  effect  when decompressing.
-              See MEMORY MANAGEMENT below.  The −−fast and −−best
-              aliases  are  primarily for GNU gzip compatibility.
-              In particular, −−fast doesn’t make things  signifi­
-              cantly  faster.   And  −−best  merely  selects  the
-              default behaviour.
-
-       −−‐‐     Treats all subsequent arguments as file names, even
-              if they start with a dash.  This is so you can han­
-              dle files with names beginning  with  a  dash,  for
-              example: bzip2 −‐ −myfilename.
-
-       −−‐‐rreeppeettiittiivvee‐‐ffaasstt ‐‐‐‐rreeppeettiittiivvee‐‐bbeesstt
-              These  flags  are  redundant  in versions 0.9.5 and
-              above.  They provided some coarse control over  the
-              behaviour  of the sorting algorithm in earlier ver­
-              sions, which was sometimes useful.  0.9.5 and above
-              have  an  improved  algorithm  which  renders these
-              flags irrelevant.
-
-
-MMEEMMOORRYY MMAANNAAGGEEMMEENNTT
-       _b_z_i_p_2 compresses large files in blocks.   The  block  size
-       affects  both  the  compression  ratio  achieved,  and the
-       amount of memory needed for compression and decompression.
-       The  flags  −1  through  −9  specify  the block size to be
-       100,000 bytes through 900,000 bytes (the default)  respec­
-       tively.   At  decompression  time, the block size used for
-       compression is read from  the  header  of  the  compressed
-       file, and _b_u_n_z_i_p_2 then allocates itself just enough memory
-       to decompress the file.  Since block sizes are  stored  in
-       compressed  files,  it follows that the flags −1 to −9 are
-       irrelevant to and so ignored during decompression.
-
-       Compression and decompression requirements, in bytes,  can
-       be estimated as:
-
-              Compression:   400k + ( 8 x block size )
-
-              Decompression: 100k + ( 4 x block size ), or
-                             100k + ( 2.5 x block size )
-
-       Larger  block  sizes  give  rapidly  diminishing  marginal
-       returns.  Most of the compression comes from the first two
-       or  three hundred k of block size, a fact worth bearing in
-       mind when using _b_z_i_p_2  on  small  machines.   It  is  also
-       important  to  appreciate  that  the  decompression memory
-       requirement is set at compression time by  the  choice  of
-       block size.
-
-       For  files  compressed  with  the default 900k block size,
-       _b_u_n_z_i_p_2 will require about 3700 kbytes to decompress.   To
-       support decompression of any file on a 4 megabyte machine,
-       _b_u_n_z_i_p_2 has an option to  decompress  using  approximately
-       half this amount of memory, about 2300 kbytes.  Decompres­
-       sion speed is also halved, so you should use  this  option
-       only where necessary.  The relevant flag is ‐s.
-
-       In general, try and use the largest block size memory con­
-       straints  allow,  since  that  maximises  the  compression
-       achieved.   Compression and decompression speed are virtu­
-       ally unaffected by block size.
-
-       Another significant point applies to files which fit in  a
-       single  block  ‐‐  that  means  most files you’d encounter
-       using a large block  size.   The  amount  of  real  memory
-       touched is proportional to the size of the file, since the
-       file is smaller than a block.  For example, compressing  a
-       file  20,000  bytes  long  with the flag ‐9 will cause the
-       compressor to allocate around 7600k of  memory,  but  only
-       touch 400k + 20000 * 8 = 560 kbytes of it.  Similarly, the
-       decompressor will allocate 3700k but  only  touch  100k  +
-       20000 * 4 = 180 kbytes.
-
-       Here  is a table which summarises the maximum memory usage
-       for different block sizes.  Also  recorded  is  the  total
-       compressed  size for 14 files of the Calgary Text Compres­
-       sion Corpus totalling 3,141,622 bytes.  This column  gives
-       some  feel  for  how  compression  varies with block size.
-       These figures tend to understate the advantage  of  larger
-       block  sizes  for  larger files, since the Corpus is domi­
-       nated by smaller files.
-
-                  Compress   Decompress   Decompress   Corpus
-           Flag     usage      usage       ‐s usage     Size
-
-            ‐1      1200k       500k         350k      914704
-            ‐2      2000k       900k         600k      877703
-            ‐3      2800k      1300k         850k      860338
-            ‐4      3600k      1700k        1100k      846899
-            ‐5      4400k      2100k        1350k      845160
-            ‐6      5200k      2500k        1600k      838626
-            ‐7      6100k      2900k        1850k      834096
-            ‐8      6800k      3300k        2100k      828642
-            ‐9      7600k      3700k        2350k      828642
-
-
-RREECCOOVVEERRIINNGG DDAATTAA FFRROOMM DDAAMMAAGGEEDD FFIILLEESS
-       _b_z_i_p_2 compresses files in blocks, usually 900kbytes  long.
-       Each block is handled independently.  If a media or trans­
-       mission error causes a multi‐block  .bz2  file  to  become
-       damaged,  it  may  be  possible  to  recover data from the
-       undamaged blocks in the file.
-
-       The compressed representation of each block  is  delimited
-       by  a  48‐bit pattern, which makes it possible to find the
-       block boundaries with reasonable  certainty.   Each  block
-       also  carries its own 32‐bit CRC, so damaged blocks can be
-       distinguished from undamaged ones.
-
-       _b_z_i_p_2_r_e_c_o_v_e_r is a  simple  program  whose  purpose  is  to
-       search  for blocks in .bz2 files, and write each block out
-       into its own .bz2 file.  You can then use _b_z_i_p_2 −t to test
-       the integrity of the resulting files, and decompress those
-       which are undamaged.
-
-       _b_z_i_p_2_r_e_c_o_v_e_r takes a single argument, the name of the dam­
-       aged    file,    and    writes    a    number   of   files
-       "rec00001file.bz2",  "rec00002file.bz2",  etc,  containing
-       the   extracted   blocks.   The   output   filenames   are
-       designed  so  that the use of wildcards in subsequent pro­
-       cessing  ‐‐ for example, "bzip2 ‐dc  rec*file.bz2 > recov­
-       ered_data" ‐‐ processes the files in the correct order.
-
-       _b_z_i_p_2_r_e_c_o_v_e_r should be of most use dealing with large .bz2
-       files,  as  these will contain many blocks.  It is clearly
-       futile to use it on damaged single‐block  files,  since  a
-       damaged  block  cannot  be recovered.  If you wish to min­
-       imise any potential data loss through media  or  transmis­
-       sion errors, you might consider compressing with a smaller
-       block size.
-
-
-PPEERRFFOORRMMAANNCCEE NNOOTTEESS
-       The sorting phase of compression gathers together  similar
-       strings  in  the  file.  Because of this, files containing
-       very long runs of  repeated  symbols,  like  "aabaabaabaab
-       ..."   (repeated  several hundred times) may compress more
-       slowly than normal.  Versions 0.9.5 and  above  fare  much
-       better  than previous versions in this respect.  The ratio
-       between worst‐case and average‐case compression time is in
-       the  region  of  10:1.  For previous versions, this figure
-       was more like 100:1.  You can use the −vvvv option to mon­
-       itor progress in great detail, if you want.
-
-       Decompression speed is unaffected by these phenomena.
-
-       _b_z_i_p_2  usually  allocates  several  megabytes of memory to
-       operate in, and then charges all over it in a fairly  ran­
-       dom  fashion.   This means that performance, both for com­
-       pressing and decompressing, is largely determined  by  the
-       speed  at  which  your  machine  can service cache misses.
-       Because of this, small changes to the code to  reduce  the
-       miss  rate  have  been observed to give disproportionately
-       large performance improvements.  I imagine _b_z_i_p_2 will per­
-       form best on machines with very large caches.
-
-
-CCAAVVEEAATTSS
-       I/O  error  messages  are not as helpful as they could be.
-       _b_z_i_p_2 tries hard to detect I/O errors  and  exit  cleanly,
-       but  the  details  of  what  the problem is sometimes seem
-       rather misleading.
-
-       This manual page pertains to version 1.0.4 of _b_z_i_p_2_.  Com­
-       pressed  data created by this version is entirely forwards
-       and  backwards  compatible  with   the   previous   public
-       releases,  versions  0.1pl2,  0.9.0,  0.9.5, 1.0.0, 1.0.1, 
-       1.0.2 and 1.0.3, but with the  following  exception: 0.9.0
-       and above can  correctly decompress  multiple concatenated
-       compressed files.  0.1pl2  cannot do this;  it  will  stop 
-       after  decompressing just the first file in the stream.
-
-       _b_z_i_p_2_r_e_c_o_v_e_r  versions prior to 1.0.2 used 32‐bit integers
-       to represent bit positions in compressed  files,  so  they
-       could  not handle compressed files more than 512 megabytes
-       long.  Versions 1.0.2 and above use 64‐bit  ints  on  some
-       platforms  which  support them (GNU supported targets, and
-       Windows).  To establish whether or  not  bzip2recover  was
-       built  with  such  a limitation, run it without arguments.
-       In any event you can build yourself an  unlimited  version
-       if  you  can  recompile  it  with MaybeUInt64 set to be an
-       unsigned 64‐bit integer.
-
-
-
-
-AAUUTTHHOORR
-       Julian Seward, jsewardbzip.org.
-
-       http://www.bzip.org
-
-       The ideas embodied in _b_z_i_p_2 are due to (at least) the fol­
-       lowing  people: Michael Burrows and David Wheeler (for the
-       block sorting transformation), David Wheeler  (again,  for
-       the Huffman coder), Peter Fenwick (for the structured cod­
-       ing model in the original _b_z_i_p_, and many refinements), and
-       Alistair  Moffat,  Radford  Neal  and  Ian Witten (for the
-       arithmetic  coder  in  the  original  _b_z_i_p_)_.   I  am  much
-       indebted for their help, support and advice.  See the man­
-       ual in the source distribution for pointers to sources  of
-       documentation.  Christian von Roques encouraged me to look
-       for faster sorting algorithms, so as to speed up  compres­
-       sion.  Bela Lubkin encouraged me to improve the worst‐case
-       compression performance.  Donna Robinson XMLised the docu­
-       mentation.   The bz* scripts are derived from those of GNU
-       gzip.  Many people sent patches, helped  with  portability
-       problems,  lent  machines,  gave advice and were generally
-       helpful.
-
-
-
-                                                         bzip2(1)
diff --git a/Utilities/cmbzip2/bzip2.c b/Utilities/cmbzip2/bzip2.c
index 88e5f09..d95d280 100644
--- a/Utilities/cmbzip2/bzip2.c
+++ b/Utilities/cmbzip2/bzip2.c
@@ -7,8 +7,8 @@
    This file is part of bzip2/libbzip2, a program and library for
    lossless, block-sorting data compression.
 
-   bzip2/libbzip2 version 1.0.5 of 10 December 2007
-   Copyright (C) 1996-2007 Julian Seward <jseward@bzip.org>
+   bzip2/libbzip2 version 1.0.8 of 13 July 2019
+   Copyright (C) 1996-2019 Julian Seward <jseward@acm.org>
 
    Please read the WARNING, DISCLAIMER and PATENTS sections in the 
    README file.
@@ -128,12 +128,12 @@
 #if BZ_LCCWIN32
 #   include <io.h>
 #   include <fcntl.h>
-#   include <sys\stat.h>
+#   include <sys/stat.h>
 
 #   define NORETURN       /**/
 #   define PATH_SEP       '\\'
-#   define MY_LSTAT       _stat
-#   define MY_STAT        _stat
+#   define MY_LSTAT       _stati64
+#   define MY_STAT        _stati64
 #   define MY_S_ISREG(x)  ((x) & _S_IFREG)
 #   define MY_S_ISDIR(x)  ((x) & _S_IFDIR)
 
@@ -380,27 +380,27 @@
 
    if (verbosity >= 1) {
       if (nbytes_in_lo32 == 0 && nbytes_in_hi32 == 0) {
-     fprintf ( stderr, " no data compressed.\n");
+	 fprintf ( stderr, " no data compressed.\n");
       } else {
-     Char   buf_nin[32], buf_nout[32];
-     UInt64 nbytes_in,   nbytes_out;
-     double nbytes_in_d, nbytes_out_d;
-     uInt64_from_UInt32s ( &nbytes_in, 
-                   nbytes_in_lo32, nbytes_in_hi32 );
-     uInt64_from_UInt32s ( &nbytes_out, 
-                   nbytes_out_lo32, nbytes_out_hi32 );
-     nbytes_in_d  = uInt64_to_double ( &nbytes_in );
-     nbytes_out_d = uInt64_to_double ( &nbytes_out );
-     uInt64_toAscii ( buf_nin, &nbytes_in );
-     uInt64_toAscii ( buf_nout, &nbytes_out );
-     fprintf ( stderr, "%6.3f:1, %6.3f bits/byte, "
-           "%5.2f%% saved, %s in, %s out.\n",
-           nbytes_in_d / nbytes_out_d,
-           (8.0 * nbytes_out_d) / nbytes_in_d,
-           100.0 * (1.0 - nbytes_out_d / nbytes_in_d),
-           buf_nin,
-           buf_nout
-         );
+	 Char   buf_nin[32], buf_nout[32];
+	 UInt64 nbytes_in,   nbytes_out;
+	 double nbytes_in_d, nbytes_out_d;
+	 uInt64_from_UInt32s ( &nbytes_in, 
+			       nbytes_in_lo32, nbytes_in_hi32 );
+	 uInt64_from_UInt32s ( &nbytes_out, 
+			       nbytes_out_lo32, nbytes_out_hi32 );
+	 nbytes_in_d  = uInt64_to_double ( &nbytes_in );
+	 nbytes_out_d = uInt64_to_double ( &nbytes_out );
+	 uInt64_toAscii ( buf_nin, &nbytes_in );
+	 uInt64_toAscii ( buf_nout, &nbytes_out );
+	 fprintf ( stderr, "%6.3f:1, %6.3f bits/byte, "
+		   "%5.2f%% saved, %s in, %s out.\n",
+		   nbytes_in_d / nbytes_out_d,
+		   (8.0 * nbytes_out_d) / nbytes_in_d,
+		   100.0 * (1.0 - nbytes_out_d / nbytes_in_d),
+		   buf_nin,
+		   buf_nout
+		 );
       }
    }
 
@@ -505,11 +505,11 @@
    if (forceOverwrite) {
       rewind(zStream);
       while (True) {
-         if (myfeof(zStream)) break;
-         nread = fread ( obuf, sizeof(UChar), 5000, zStream );
-         if (ferror(zStream)) goto errhandler_io;
-         if (nread > 0) fwrite ( obuf, sizeof(UChar), nread, stream );
-         if (ferror(stream)) goto errhandler_io;
+      	 if (myfeof(zStream)) break;
+      	 nread = fread ( obuf, sizeof(UChar), 5000, zStream );
+      	 if (ferror(zStream)) goto errhandler_io;
+      	 if (nread > 0) fwrite ( obuf, sizeof(UChar), nread, stream );
+      	 if (ferror(stream)) goto errhandler_io;
       }
       goto closeok;
    }
@@ -554,7 +554,7 @@
 Bool testStream ( FILE *zStream )
 {
    BZFILE* bzf = NULL;
-   Int32   bzerr, bzerr_dummy, ret, nread, streamNo, i;
+   Int32   bzerr, bzerr_dummy, ret, streamNo, i;
    UChar   obuf[5000];
    UChar   unused[BZ_MAX_UNUSED];
    Int32   nUnused;
@@ -577,7 +577,7 @@
       streamNo++;
 
       while (bzerr == BZ_OK) {
-         nread = BZ2_bzRead ( &bzerr, bzf, obuf, 5000 );
+         BZ2_bzRead ( &bzerr, bzf, obuf, 5000 );
          if (bzerr == BZ_DATA_ERROR_MAGIC) goto errhandler;
       }
       if (bzerr != BZ_STREAM_END) goto errhandler;
@@ -748,8 +748,8 @@
    fprintf ( stderr,
              "\n%s: PANIC -- internal consistency error:\n"
              "\t%s\n"
-             "\tThis is a BUG.  Please report it to me at:\n"
-             "\tjseward@bzip.org\n",
+             "\tThis is a BUG.  Please report it to:\n"
+             "\tbzip2-devel@sourceware.org\n",
              progName, s );
    showFileNames();
    cleanUpAndFail( 3 );
@@ -775,9 +775,9 @@
 {
   if (noisy) {
     fprintf ( stderr,
-          "\n%s: Compressed file ends unexpectedly;\n\t"
-          "perhaps it is corrupted?  *Possible* reason follows.\n",
-          progName );
+	      "\n%s: Compressed file ends unexpectedly;\n\t"
+	      "perhaps it is corrupted?  *Possible* reason follows.\n",
+	      progName );
     perror ( progName );
     showFileNames();
     cadvise();
@@ -829,7 +829,7 @@
       "   The user's manual, Section 4.3, has more info on (1) and (2).\n"
       "   \n"
       "   If you suspect this is a bug in bzip2, or are unsure about (1)\n"
-      "   or (2), feel free to report it to me at: jseward@bzip.org.\n"
+      "   or (2), feel free to report it to: bzip2-devel@sourceware.org.\n"
       "   Section 4.3 of the user's manual describes the info a useful\n"
       "   bug report should have.  If the manual is available on your\n"
       "   system, please try and read it before mailing me.  If you don't\n"
@@ -852,7 +852,7 @@
       "   The user's manual, Section 4.3, has more info on (2) and (3).\n"
       "   \n"
       "   If you suspect this is a bug in bzip2, or are unsure about (2)\n"
-      "   or (3), feel free to report it to me at: jseward@bzip.org.\n"
+      "   or (3), feel free to report it to: bzip2-devel@sourceware.org.\n"
       "   Section 4.3 of the user's manual describes the info a useful\n"
       "   bug report should have.  If the manual is available on your\n"
       "   system, please try and read it before mailing me.  If you don't\n"
@@ -1200,12 +1200,12 @@
    }
    if ( srcMode == SM_F2F && fileExists ( outName ) ) {
       if (forceOverwrite) {
-     remove(outName);
+	 remove(outName);
       } else {
-     fprintf ( stderr, "%s: Output file %s already exists.\n",
-           progName, outName );
-     setExit(1);
-     return;
+	 fprintf ( stderr, "%s: Output file %s already exists.\n",
+		   progName, outName );
+	 setExit(1);
+	 return;
       }
    }
    if ( srcMode == SM_F2F && !forceOverwrite &&
@@ -1386,7 +1386,7 @@
    }   
    if ( srcMode == SM_F2F && fileExists ( outName ) ) {
       if (forceOverwrite) {
-    remove(outName);
+	remove(outName);
       } else {
         fprintf ( stderr, "%s: Output file %s already exists.\n",
                   progName, outName );
@@ -1605,11 +1605,11 @@
     "bzip2, a block-sorting file compressor.  "
     "Version %s.\n"
     "   \n"
-    "   Copyright (C) 1996-2007 by Julian Seward.\n"
+    "   Copyright (C) 1996-2019 by Julian Seward.\n"
     "   \n"
     "   This program is free software; you can redistribute it and/or modify\n"
     "   it under the terms set out in the LICENSE file, which is included\n"
-    "   in the bzip2-1.0.5 source distribution.\n"
+    "   in the bzip2 source distribution.\n"
     "   \n"
     "   This program is distributed in the hope that it will be useful,\n"
     "   but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
@@ -1997,18 +1997,20 @@
       } else {
          decode = True;
          for (aa = argList; aa != NULL; aa = aa->link) {
-        if (ISFLAG("--")) { decode = False; continue; }
+	    if (ISFLAG("--")) { decode = False; continue; }
             if (aa->name[0] == '-' && decode) continue;
             numFilesProcessed++;
             testf ( aa->name );
-     }
+	 }
       }
-      if (testFailsExist && noisy) {
-         fprintf ( stderr,
-           "\n"
-           "You can use the `bzip2recover' program to attempt to recover\n"
-           "data from undamaged sections of corrupted files.\n\n"
-         );
+      if (testFailsExist) {
+	 if (noisy) {
+            fprintf ( stderr,
+               "\n"
+               "You can use the `bzip2recover' program to attempt to recover\n"
+               "data from undamaged sections of corrupted files.\n\n"
+            );
+	 }
          setExit(2);
          exit(exitValue);
       }
diff --git a/Utilities/cmbzip2/bzip2.txt b/Utilities/cmbzip2/bzip2.txt
deleted file mode 100644
index 4fb9c74..0000000
--- a/Utilities/cmbzip2/bzip2.txt
+++ /dev/null
@@ -1,391 +0,0 @@
-
-NAME
-       bzip2, bunzip2 - a block-sorting file compressor, v1.0.4
-       bzcat - decompresses files to stdout
-       bzip2recover - recovers data from damaged bzip2 files
-
-
-SYNOPSIS
-       bzip2 [ -cdfkqstvzVL123456789 ] [ filenames ...  ]
-       bunzip2 [ -fkvsVL ] [ filenames ...  ]
-       bzcat [ -s ] [ filenames ...  ]
-       bzip2recover filename
-
-
-DESCRIPTION
-       bzip2  compresses  files  using  the Burrows-Wheeler block
-       sorting text compression algorithm,  and  Huffman  coding.
-       Compression  is  generally  considerably  better than that
-       achieved by more conventional LZ77/LZ78-based compressors,
-       and  approaches  the performance of the PPM family of sta-
-       tistical compressors.
-
-       The command-line options are deliberately very similar  to
-       those of GNU gzip, but they are not identical.
-
-       bzip2  expects  a list of file names to accompany the com-
-       mand-line flags.  Each file is replaced  by  a  compressed
-       version  of  itself,  with  the  name "original_name.bz2".
-       Each compressed file has the same modification date,  per-
-       missions, and, when possible, ownership as the correspond-
-       ing original, so that these properties  can  be  correctly
-       restored  at  decompression  time.   File name handling is
-       naive in the sense that there is no mechanism for preserv-
-       ing  original file names, permissions, ownerships or dates
-       in filesystems which lack these concepts, or have  serious
-       file name length restrictions, such as MS-DOS.
-
-       bzip2  and  bunzip2 will by default not overwrite existing
-       files.  If you want this to happen, specify the -f flag.
-
-       If no file names  are  specified,  bzip2  compresses  from
-       standard  input  to  standard output.  In this case, bzip2
-       will decline to write compressed output to a terminal,  as
-       this  would  be  entirely  incomprehensible  and therefore
-       pointless.
-
-       bunzip2 (or bzip2 -d) decompresses  all  specified  files.
-       Files which were not created by bzip2 will be detected and
-       ignored, and a warning issued.  bzip2  attempts  to  guess
-       the  filename  for  the decompressed file from that of the
-       compressed file as follows:
-
-              filename.bz2    becomes   filename
-              filename.bz     becomes   filename
-              filename.tbz2   becomes   filename.tar
-              filename.tbz    becomes   filename.tar
-              anyothername    becomes   anyothername.out
-
-       If the file does not end in one of the recognised endings,
-       .bz2,  .bz,  .tbz2 or .tbz, bzip2 complains that it cannot
-       guess the name of the original file, and uses the original
-       name with .out appended.
-
-       As  with compression, supplying no filenames causes decom-
-       pression from standard input to standard output.
-
-       bunzip2 will correctly decompress a file which is the con-
-       catenation of two or more compressed files.  The result is
-       the concatenation of the corresponding uncompressed files.
-       Integrity testing (-t) of concatenated compressed files is
-       also supported.
-
-       You can also compress or decompress files to the  standard
-       output  by giving the -c flag.  Multiple files may be com-
-       pressed and decompressed like this.  The resulting outputs
-       are  fed  sequentially to stdout.  Compression of multiple
-       files in this manner generates a stream containing  multi-
-       ple compressed file representations.  Such a stream can be
-       decompressed correctly only  by  bzip2  version  0.9.0  or
-       later.   Earlier  versions of bzip2 will stop after decom-
-       pressing the first file in the stream.
-
-       bzcat (or bzip2 -dc) decompresses all specified  files  to
-       the standard output.
-
-       bzip2  will  read arguments from the environment variables
-       BZIP2 and BZIP, in  that  order,  and  will  process  them
-       before  any  arguments  read  from the command line.  This
-       gives a convenient way to supply default arguments.
-
-       Compression is always performed, even  if  the  compressed
-       file  is slightly larger than the original.  Files of less
-       than about one hundred bytes tend to get larger, since the
-       compression  mechanism  has  a  constant  overhead  in the
-       region of 50 bytes.  Random data (including the output  of
-       most  file  compressors)  is  coded at about 8.05 bits per
-       byte, giving an expansion of around 0.5%.
-
-       As a self-check for your  protection,  bzip2  uses  32-bit
-       CRCs  to make sure that the decompressed version of a file
-       is identical to the original.  This guards against corrup-
-       tion  of  the compressed data, and against undetected bugs
-       in bzip2 (hopefully very unlikely).  The chances  of  data
-       corruption  going  undetected  is  microscopic,  about one
-       chance in four billion for each file processed.  Be aware,
-       though,  that  the  check occurs upon decompression, so it
-       can only tell you that something is wrong.  It can't  help
-       you  recover  the original uncompressed data.  You can use
-       bzip2recover to try to recover data from damaged files.
-
-       Return values: 0 for a normal exit,  1  for  environmental
-       problems  (file not found, invalid flags, I/O errors, &c),
-       2 to indicate a corrupt compressed file, 3 for an internal
-       consistency error (eg, bug) which caused bzip2 to panic.
-
-
-OPTIONS
-       -c --stdout
-              Compress or decompress to standard output.
-
-       -d --decompress
-              Force  decompression.  bzip2, bunzip2 and bzcat are
-              really the same program,  and  the  decision  about
-              what  actions to take is done on the basis of which
-              name is used.  This flag overrides that  mechanism,
-              and forces bzip2 to decompress.
-
-       -z --compress
-              The   complement   to   -d:   forces   compression,
-              regardless of the invocation name.
-
-       -t --test
-              Check integrity of the specified file(s), but don't
-              decompress  them.   This  really  performs  a trial
-              decompression and throws away the result.
-
-       -f --force
-              Force overwrite of output files.   Normally,  bzip2
-              will  not  overwrite  existing  output files.  Also
-              forces bzip2 to break hard links to files, which it
-              otherwise wouldn't do.
-
-              bzip2  normally  declines to decompress files which
-              don't have the  correct  magic  header  bytes.   If
-              forced  (-f),  however,  it  will  pass  such files
-              through unmodified.  This is how GNU gzip  behaves.
-
-       -k --keep
-              Keep  (don't delete) input files during compression
-              or decompression.
-
-       -s --small
-              Reduce memory usage, for compression, decompression
-              and  testing.   Files  are  decompressed and tested
-              using a modified algorithm which only requires  2.5
-              bytes  per  block byte.  This means any file can be
-              decompressed in 2300k of memory,  albeit  at  about
-              half the normal speed.
-
-              During  compression,  -s  selects  a  block size of
-              200k, which limits memory use to  around  the  same
-              figure,  at  the expense of your compression ratio.
-              In short, if your  machine  is  low  on  memory  (8
-              megabytes  or  less),  use  -s for everything.  See
-              MEMORY MANAGEMENT below.
-
-       -q --quiet
-              Suppress non-essential warning messages.   Messages
-              pertaining  to I/O errors and other critical events
-              will not be suppressed.
-
-       -v --verbose
-              Verbose mode -- show the compression ratio for each
-              file  processed.   Further  -v's  increase the ver-
-              bosity level, spewing out lots of information which
-              is primarily of interest for diagnostic purposes.
-
-       -L --license -V --version
-              Display  the  software  version,  license terms and
-              conditions.
-
-       -1 (or --fast) to -9 (or --best)
-              Set the block size to 100 k, 200 k ..  900  k  when
-              compressing.   Has  no  effect  when decompressing.
-              See MEMORY MANAGEMENT below.  The --fast and --best
-              aliases  are  primarily for GNU gzip compatibility.
-              In particular, --fast doesn't make things  signifi-
-              cantly  faster.   And  --best  merely  selects  the
-              default behaviour.
-
-       --     Treats all subsequent arguments as file names, even
-              if they start with a dash.  This is so you can han-
-              dle files with names beginning  with  a  dash,  for
-              example: bzip2 -- -myfilename.
-
-       --repetitive-fast --repetitive-best
-              These  flags  are  redundant  in versions 0.9.5 and
-              above.  They provided some coarse control over  the
-              behaviour  of the sorting algorithm in earlier ver-
-              sions, which was sometimes useful.  0.9.5 and above
-              have  an  improved  algorithm  which  renders these
-              flags irrelevant.
-
-
-MEMORY MANAGEMENT
-       bzip2 compresses large files in blocks.   The  block  size
-       affects  both  the  compression  ratio  achieved,  and the
-       amount of memory needed for compression and decompression.
-       The  flags  -1  through  -9  specify  the block size to be
-       100,000 bytes through 900,000 bytes (the default)  respec-
-       tively.   At  decompression  time, the block size used for
-       compression is read from  the  header  of  the  compressed
-       file, and bunzip2 then allocates itself just enough memory
-       to decompress the file.  Since block sizes are  stored  in
-       compressed  files,  it follows that the flags -1 to -9 are
-       irrelevant to and so ignored during decompression.
-
-       Compression and decompression requirements, in bytes,  can
-       be estimated as:
-
-              Compression:   400k + ( 8 x block size )
-
-              Decompression: 100k + ( 4 x block size ), or
-                             100k + ( 2.5 x block size )
-
-       Larger  block  sizes  give  rapidly  diminishing  marginal
-       returns.  Most of the compression comes from the first two
-       or  three hundred k of block size, a fact worth bearing in
-       mind when using bzip2  on  small  machines.   It  is  also
-       important  to  appreciate  that  the  decompression memory
-       requirement is set at compression time by  the  choice  of
-       block size.
-
-       For  files  compressed  with  the default 900k block size,
-       bunzip2 will require about 3700 kbytes to decompress.   To
-       support decompression of any file on a 4 megabyte machine,
-       bunzip2 has an option to  decompress  using  approximately
-       half this amount of memory, about 2300 kbytes.  Decompres-
-       sion speed is also halved, so you should use  this  option
-       only where necessary.  The relevant flag is -s.
-
-       In general, try and use the largest block size memory con-
-       straints  allow,  since  that  maximises  the  compression
-       achieved.   Compression and decompression speed are virtu-
-       ally unaffected by block size.
-
-       Another significant point applies to files which fit in  a
-       single  block  --  that  means  most files you'd encounter
-       using a large block  size.   The  amount  of  real  memory
-       touched is proportional to the size of the file, since the
-       file is smaller than a block.  For example, compressing  a
-       file  20,000  bytes  long  with the flag -9 will cause the
-       compressor to allocate around 7600k of  memory,  but  only
-       touch 400k + 20000 * 8 = 560 kbytes of it.  Similarly, the
-       decompressor will allocate 3700k but  only  touch  100k  +
-       20000 * 4 = 180 kbytes.
-
-       Here  is a table which summarises the maximum memory usage
-       for different block sizes.  Also  recorded  is  the  total
-       compressed  size for 14 files of the Calgary Text Compres-
-       sion Corpus totalling 3,141,622 bytes.  This column  gives
-       some  feel  for  how  compression  varies with block size.
-       These figures tend to understate the advantage  of  larger
-       block  sizes  for  larger files, since the Corpus is domi-
-       nated by smaller files.
-
-                  Compress   Decompress   Decompress   Corpus
-           Flag     usage      usage       -s usage     Size
-
-            -1      1200k       500k         350k      914704
-            -2      2000k       900k         600k      877703
-            -3      2800k      1300k         850k      860338
-            -4      3600k      1700k        1100k      846899
-            -5      4400k      2100k        1350k      845160
-            -6      5200k      2500k        1600k      838626
-            -7      6100k      2900k        1850k      834096
-            -8      6800k      3300k        2100k      828642
-            -9      7600k      3700k        2350k      828642
-
-
-RECOVERING DATA FROM DAMAGED FILES
-       bzip2 compresses files in blocks, usually 900kbytes  long.
-       Each block is handled independently.  If a media or trans-
-       mission error causes a multi-block  .bz2  file  to  become
-       damaged,  it  may  be  possible  to  recover data from the
-       undamaged blocks in the file.
-
-       The compressed representation of each block  is  delimited
-       by  a  48-bit pattern, which makes it possible to find the
-       block boundaries with reasonable  certainty.   Each  block
-       also  carries its own 32-bit CRC, so damaged blocks can be
-       distinguished from undamaged ones.
-
-       bzip2recover is a  simple  program  whose  purpose  is  to
-       search  for blocks in .bz2 files, and write each block out
-       into its own .bz2 file.  You can then use bzip2 -t to test
-       the integrity of the resulting files, and decompress those
-       which are undamaged.
-
-       bzip2recover takes a single argument, the name of the dam-
-       aged    file,    and    writes    a    number   of   files
-       "rec00001file.bz2",  "rec00002file.bz2",  etc,  containing
-       the   extracted   blocks.   The   output   filenames   are
-       designed  so  that the use of wildcards in subsequent pro-
-       cessing  -- for example, "bzip2 -dc  rec*file.bz2 > recov-
-       ered_data" -- processes the files in the correct order.
-
-       bzip2recover should be of most use dealing with large .bz2
-       files,  as  these will contain many blocks.  It is clearly
-       futile to use it on damaged single-block  files,  since  a
-       damaged  block  cannot  be recovered.  If you wish to min-
-       imise any potential data loss through media  or  transmis-
-       sion errors, you might consider compressing with a smaller
-       block size.
-
-
-PERFORMANCE NOTES
-       The sorting phase of compression gathers together  similar
-       strings  in  the  file.  Because of this, files containing
-       very long runs of  repeated  symbols,  like  "aabaabaabaab
-       ..."   (repeated  several hundred times) may compress more
-       slowly than normal.  Versions 0.9.5 and  above  fare  much
-       better  than previous versions in this respect.  The ratio
-       between worst-case and average-case compression time is in
-       the  region  of  10:1.  For previous versions, this figure
-       was more like 100:1.  You can use the -vvvv option to mon-
-       itor progress in great detail, if you want.
-
-       Decompression speed is unaffected by these phenomena.
-
-       bzip2  usually  allocates  several  megabytes of memory to
-       operate in, and then charges all over it in a fairly  ran-
-       dom  fashion.   This means that performance, both for com-
-       pressing and decompressing, is largely determined  by  the
-       speed  at  which  your  machine  can service cache misses.
-       Because of this, small changes to the code to  reduce  the
-       miss  rate  have  been observed to give disproportionately
-       large performance improvements.  I imagine bzip2 will per-
-       form best on machines with very large caches.
-
-
-CAVEATS
-       I/O  error  messages  are not as helpful as they could be.
-       bzip2 tries hard to detect I/O errors  and  exit  cleanly,
-       but  the  details  of  what  the problem is sometimes seem
-       rather misleading.
-
-       This manual page pertains to version 1.0.4 of bzip2.  Com-
-       pressed  data created by this version is entirely forwards
-       and  backwards  compatible  with   the   previous   public
-       releases,  versions  0.1pl2,  0.9.0,  0.9.5, 1.0.0, 1.0.1,
-       1.0.2 and 1.0.3, but with the  following  exception: 0.9.0
-       and above can  correctly decompress  multiple concatenated
-       compressed files.  0.1pl2  cannot do this;  it  will  stop
-       after  decompressing just the first file in the stream.
-
-       bzip2recover  versions prior to 1.0.2 used 32-bit integers
-       to represent bit positions in compressed  files,  so  they
-       could  not handle compressed files more than 512 megabytes
-       long.  Versions 1.0.2 and above use 64-bit  ints  on  some
-       platforms  which  support them (GNU supported targets, and
-       Windows).  To establish whether or  not  bzip2recover  was
-       built  with  such  a limitation, run it without arguments.
-       In any event you can build yourself an  unlimited  version
-       if  you  can  recompile  it  with MaybeUInt64 set to be an
-       unsigned 64-bit integer.
-
-
-AUTHOR
-       Julian Seward, jsewardbzip.org.
-
-       http://www.bzip.org
-
-       The ideas embodied in bzip2 are due to (at least) the fol-
-       lowing  people: Michael Burrows and David Wheeler (for the
-       block sorting transformation), David Wheeler  (again,  for
-       the Huffman coder), Peter Fenwick (for the structured cod-
-       ing model in the original bzip, and many refinements), and
-       Alistair  Moffat,  Radford  Neal  and  Ian Witten (for the
-       arithmetic  coder  in  the  original  bzip).   I  am  much
-       indebted for their help, support and advice.  See the man-
-       ual in the source distribution for pointers to sources  of
-       documentation.  Christian von Roques encouraged me to look
-       for faster sorting algorithms, so as to speed up  compres-
-       sion.  Bela Lubkin encouraged me to improve the worst-case
-       compression performance.  Donna Robinson XMLised the docu-
-       mentation.   The bz* scripts are derived from those of GNU
-       gzip.  Many people sent patches, helped  with  portability
-       problems,  lent  machines,  gave advice and were generally
-       helpful.
-
diff --git a/Utilities/cmbzip2/bzip2recover.c b/Utilities/cmbzip2/bzip2recover.c
index 6e47b60..a8131e0 100644
--- a/Utilities/cmbzip2/bzip2recover.c
+++ b/Utilities/cmbzip2/bzip2recover.c
@@ -7,8 +7,8 @@
    This file is part of bzip2/libbzip2, a program and library for
    lossless, block-sorting data compression.
 
-   bzip2/libbzip2 version 1.0.5 of 10 December 2007
-   Copyright (C) 1996-2007 Julian Seward <jseward@bzip.org>
+   bzip2/libbzip2 version 1.0.8 of 13 July 2019
+   Copyright (C) 1996-2019 Julian Seward <jseward@acm.org>
 
    Please read the WARNING, DISCLAIMER and PATENTS sections in the 
    README file.
@@ -18,7 +18,7 @@
    ------------------------------------------------------------------ */
 
 /* This program is a complete hack and should be rewritten properly.
-     It isn't very complicated. */
+	 It isn't very complicated. */
 
 #include <stdio.h>
 #include <errno.h>
@@ -309,11 +309,12 @@
    UInt32      buffHi, buffLo, blockCRC;
    Char*       p;
 
-   strcpy ( progName, argv[0] );
+   strncpy ( progName, argv[0], BZ_MAX_FILENAME-1);
+   progName[BZ_MAX_FILENAME-1]='\0';
    inFileName[0] = outFileName[0] = 0;
 
    fprintf ( stderr, 
-             "bzip2recover 1.0.5: extracts blocks from damaged .bz2 files.\n" );
+             "bzip2recover 1.0.8: extracts blocks from damaged .bz2 files.\n" );
 
    if (argc != 2) {
       fprintf ( stderr, "%s: usage is `%s damaged_file_name'.\n",
@@ -393,7 +394,7 @@
             bEnd[currBlock] = 0;
          }
          if (currBlock > 0 &&
-         (bEnd[currBlock] - bStart[currBlock]) >= 130) {
+	     (bEnd[currBlock] - bStart[currBlock]) >= 130) {
             fprintf ( stderr, "   block %d runs from " MaybeUInt64_FMT 
                               " to " MaybeUInt64_FMT "\n",
                       rbCtr+1,  bStart[currBlock], bEnd[currBlock] );
@@ -457,6 +458,7 @@
             bsPutUChar ( bsWr, 0x50 ); bsPutUChar ( bsWr, 0x90 );
             bsPutUInt32 ( bsWr, blockCRC );
             bsClose ( bsWr );
+            outFile = NULL;
          }
          if (wrBlock >= rbCtr) break;
          wrBlock++;
@@ -474,8 +476,8 @@
             split = outFileName;
          } else {
             ++split;
-     }
-     /* Now split points to the start of the basename. */
+	 }
+	 /* Now split points to the start of the basename. */
          ofs  = split - outFileName;
          sprintf (split, "rec%5d", wrBlock+1);
          for (p = split; *p != 0; p++) if (*p == ' ') *p = '0';
diff --git a/Utilities/cmbzip2/bzlib.c b/Utilities/cmbzip2/bzlib.c
index aeecef1..2178655 100644
--- a/Utilities/cmbzip2/bzlib.c
+++ b/Utilities/cmbzip2/bzlib.c
@@ -8,8 +8,8 @@
    This file is part of bzip2/libbzip2, a program and library for
    lossless, block-sorting data compression.
 
-   bzip2/libbzip2 version 1.0.5 of 10 December 2007
-   Copyright (C) 1996-2007 Julian Seward <jseward@bzip.org>
+   bzip2/libbzip2 version 1.0.8 of 13 July 2019
+   Copyright (C) 1996-2019 Julian Seward <jseward@acm.org>
 
    Please read the WARNING, DISCLAIMER and PATENTS sections in the 
    README file.
@@ -43,12 +43,12 @@
    fprintf(stderr, 
       "\n\nbzip2/libbzip2: internal error number %d.\n"
       "This is a bug in bzip2/libbzip2, %s.\n"
-      "Please report it to me at: jseward@bzip.org.  If this happened\n"
+      "Please report it to: bzip2-devel@sourceware.org.  If this happened\n"
       "when you were using some program which uses libbzip2 as a\n"
       "component, you should also report this bug to the author(s)\n"
       "of that program.  Please make an effort to report this bug;\n"
       "timely and accurate bug reports eventually lead to higher\n"
-      "quality software.  Thanks.  Julian Seward, 10 December 2007.\n\n",
+      "quality software.  Thanks.\n\n",
       errcode,
       BZ2_bzlibVersion()
    );
@@ -102,7 +102,6 @@
 void* default_bzalloc ( void* opaque, Int32 items, Int32 size )
 {
    void* v = malloc ( items * size );
-  (void)opaque;
    return v;
 }
 
@@ -110,7 +109,6 @@
 void default_bzfree ( void* opaque, void* addr )
 {
    if (addr != NULL) free ( addr );
-  (void)opaque;
 }
 
 
@@ -427,7 +425,7 @@
             return progress ? BZ_RUN_OK : BZ_PARAM_ERROR;
          } 
          else
-     if (action == BZ_FLUSH) {
+	 if (action == BZ_FLUSH) {
             s->avail_in_expect = strm->avail_in;
             s->mode = BZ_M_FLUSHING;
             goto preswitch;
@@ -1507,7 +1505,6 @@
 /*---------------------------------------------------*/
 int BZ_API(BZ2_bzflush) (BZFILE *b)
 {
-  (void) b;
    /* do nothing now... */
    return 0;
 }
diff --git a/Utilities/cmbzip2/bzlib.h b/Utilities/cmbzip2/bzlib.h
index c5b75d6..8966a6c 100644
--- a/Utilities/cmbzip2/bzlib.h
+++ b/Utilities/cmbzip2/bzlib.h
@@ -8,8 +8,8 @@
    This file is part of bzip2/libbzip2, a program and library for
    lossless, block-sorting data compression.
 
-   bzip2/libbzip2 version 1.0.5 of 10 December 2007
-   Copyright (C) 1996-2007 Julian Seward <jseward@bzip.org>
+   bzip2/libbzip2 version 1.0.8 of 13 July 2019
+   Copyright (C) 1996-2019 Julian Seward <jseward@acm.org>
 
    Please read the WARNING, DISCLAIMER and PATENTS sections in the 
    README file.
diff --git a/Utilities/cmbzip2/bzlib_private.h b/Utilities/cmbzip2/bzlib_private.h
index 02a667f..ba0f589 100644
--- a/Utilities/cmbzip2/bzlib_private.h
+++ b/Utilities/cmbzip2/bzlib_private.h
@@ -8,8 +8,8 @@
    This file is part of bzip2/libbzip2, a program and library for
    lossless, block-sorting data compression.
 
-   bzip2/libbzip2 version 1.0.5 of 10 December 2007
-   Copyright (C) 1996-2007 Julian Seward <jseward@bzip.org>
+   bzip2/libbzip2 version 1.0.8 of 13 July 2019
+   Copyright (C) 1996-2019 Julian Seward <jseward@acm.org>
 
    Please read the WARNING, DISCLAIMER and PATENTS sections in the 
    README file.
@@ -32,28 +32,13 @@
 
 #include "bzlib.h"
 
-
-#if defined(__BORLANDC__)
-# pragma warn -8004 /* Assigned value never used.  */
-# pragma warn -8008 /* Condition is always true/false.  */
-# pragma warn -8066 /* Unreachable code.  */
-# pragma warn -8057 /* Unused parameter.  */
-#endif
 #if defined(_MSC_VER)
-/* 'integral size mismatch in argument; conversion supplied */
-# pragma warning(disable:4244)
-/* conversion from 'size_t' to 'off_t', possible loss of data */
-# pragma warning(disable:4267)
-/* warning C4127: conditional expression is constant*/
-# pragma warning(disable:4127)
-#endif
-#if defined(__clang__)
-# pragma clang diagnostic ignored "-Wcast-align"
+# pragma warning(push,1)
 #endif
 
 /*-- General stuff. --*/
 
-#define BZ_VERSION  "1.0.5, 10-Dec-2007"
+#define BZ_VERSION  "1.0.8, 13-Jul-2019"
 
 typedef char            Char;
 typedef unsigned char   Bool;
diff --git a/Utilities/cmbzip2/bzmore b/Utilities/cmbzip2/bzmore
deleted file mode 100644
index 21b1de6..0000000
--- a/Utilities/cmbzip2/bzmore
+++ /dev/null
@@ -1,61 +0,0 @@
-#!/bin/sh
-
-# Bzmore wrapped for bzip2, 
-# adapted from zmore by Philippe Troin <phil@fifi.org> for Debian GNU/Linux.
-
-PATH="/usr/bin:$PATH"; export PATH
-
-prog=`echo $0 | sed 's|.*/||'`
-case "$prog" in
-    *less)  more=less   ;;
-    *)  more=more       ;;
-esac
-
-if test "`echo -n a`" = "-n a"; then
-  # looks like a SysV system:
-  n1=''; n2='\c'
-else
-  n1='-n'; n2=''
-fi
-oldtty=`stty -g 2>/dev/null`
-if stty -cbreak 2>/dev/null; then
-  cb='cbreak'; ncb='-cbreak'
-else
-  # 'stty min 1' resets eof to ^a on both SunOS and SysV!
-  cb='min 1 -icanon'; ncb='icanon eof ^d'
-fi
-if test $? -eq 0 -a -n "$oldtty"; then
-   trap 'stty $oldtty 2>/dev/null; exit' 0 2 3 5 10 13 15
-else
-   trap 'stty $ncb echo 2>/dev/null; exit' 0 2 3 5 10 13 15
-fi
-
-if test $# = 0; then
-    if test -t 0; then
-    echo usage: $prog files...
-    else
-    bzip2 -cdfq | eval $more
-    fi
-else
-    FIRST=1
-    for FILE
-    do
-    if test $FIRST -eq 0; then
-        echo $n1 "--More--(Next file: $FILE)$n2"
-        stty $cb -echo 2>/dev/null
-        ANS=`dd bs=1 count=1 2>/dev/null` 
-        stty $ncb echo 2>/dev/null
-        echo " "
-        if test "$ANS" = 'e' -o "$ANS" = 'q'; then
-            exit
-        fi
-    fi
-    if test "$ANS" != 's'; then
-        echo "------> $FILE <------"
-        bzip2 -cdfq "$FILE" | eval $more
-    fi
-    if test -t; then
-        FIRST=0
-    fi
-    done
-fi
diff --git a/Utilities/cmbzip2/bzmore.1 b/Utilities/cmbzip2/bzmore.1
deleted file mode 100644
index c6868ed..0000000
--- a/Utilities/cmbzip2/bzmore.1
+++ /dev/null
@@ -1,152 +0,0 @@
-.\"Shamelessly copied from zmore.1 by Philippe Troin <phil@fifi.org>
-.\"for Debian GNU/Linux
-.TH BZMORE 1
-.SH NAME
-bzmore, bzless \- file perusal filter for crt viewing of bzip2 compressed text
-.SH SYNOPSIS
-.B bzmore
-[ name ...  ]
-.br
-.B bzless
-[ name ...  ]
-.SH NOTE
-In the following description,
-.I bzless
-and
-.I less
-can be used interchangeably with
-.I bzmore
-and
-.I more.
-.SH DESCRIPTION
-.I  Bzmore
-is a filter which allows examination of compressed or plain text files
-one screenful at a time on a soft-copy terminal.
-.I bzmore
-works on files compressed with
-.I bzip2
-and also on uncompressed files.
-If a file does not exist,
-.I bzmore
-looks for a file of the same name with the addition of a .bz2 suffix.
-.PP
-.I Bzmore
-normally pauses after each screenful, printing --More--
-at the bottom of the screen.
-If the user then types a carriage return, one more line is displayed.
-If the user hits a space,
-another screenful is displayed.  Other possibilities are enumerated later.
-.PP
-.I Bzmore
-looks in the file
-.I /etc/termcap
-to determine terminal characteristics,
-and to determine the default window size.
-On a terminal capable of displaying 24 lines,
-the default window size is 22 lines.
-Other sequences which may be typed when
-.I bzmore
-pauses, and their effects, are as follows (\fIi\fP is an optional integer
-argument, defaulting to 1) :
-.PP
-.IP \fIi\|\fP<space>
-display
-.I i
-more lines, (or another screenful if no argument is given)
-.PP
-.IP ^D
-display 11 more lines (a ``scroll'').
-If
-.I i
-is given, then the scroll size is set to \fIi\|\fP.
-.PP
-.IP d
-same as ^D (control-D)
-.PP
-.IP \fIi\|\fPz
-same as typing a space except that \fIi\|\fP, if present, becomes the new
-window size.  Note that the window size reverts back to the default at the
-end of the current file.
-.PP
-.IP \fIi\|\fPs
-skip \fIi\|\fP lines and print a screenful of lines
-.PP
-.IP \fIi\|\fPf
-skip \fIi\fP screenfuls and print a screenful of lines
-.PP
-.IP "q or Q"
-quit reading the current file; go on to the next (if any)
-.PP
-.IP "e or q"
-When the prompt --More--(Next file: 
-.IR file )
-is printed, this command causes bzmore to exit.
-.PP
-.IP s
-When the prompt --More--(Next file: 
-.IR file )
-is printed, this command causes bzmore to skip the next file and continue.
-.PP 
-.IP =
-Display the current line number.
-.PP
-.IP \fIi\|\fP/expr
-search for the \fIi\|\fP-th occurrence of the regular expression \fIexpr.\fP
-If the pattern is not found,
-.I bzmore
-goes on to the next file (if any).
-Otherwise, a screenful is displayed, starting two lines before the place
-where the expression was found.
-The user's erase and kill characters may be used to edit the regular
-expression.
-Erasing back past the first column cancels the search command.
-.PP
-.IP \fIi\|\fPn
-search for the \fIi\|\fP-th occurrence of the last regular expression entered.
-.PP
-.IP !command
-invoke a shell with \fIcommand\|\fP. 
-The character `!' in "command" are replaced with the
-previous shell command.  The sequence "\\!" is replaced by "!".
-.PP
-.IP ":q or :Q"
-quit reading the current file; go on to the next (if any)
-(same as q or Q).
-.PP
-.IP .
-(dot) repeat the previous command.
-.PP
-The commands take effect immediately, i.e., it is not necessary to
-type a carriage return.
-Up to the time when the command character itself is given,
-the user may hit the line kill character to cancel the numerical
-argument being formed.
-In addition, the user may hit the erase character to redisplay the
---More-- message.
-.PP
-At any time when output is being sent to the terminal, the user can
-hit the quit key (normally control\-\\).
-.I Bzmore
-will stop sending output, and will display the usual --More--
-prompt.
-The user may then enter one of the above commands in the normal manner.
-Unfortunately, some output is lost when this is done, due to the
-fact that any characters waiting in the terminal's output queue
-are flushed when the quit signal occurs.
-.PP
-The terminal is set to
-.I noecho
-mode by this program so that the output can be continuous.
-What you type will thus not show on your terminal, except for the / and !
-commands.
-.PP
-If the standard output is not a teletype, then
-.I bzmore
-acts just like
-.I bzcat,
-except that a header is printed before each file.
-.SH FILES
-.DT
-/etc/termcap        Terminal data base
-.SH "SEE ALSO"
-more(1), less(1), bzip2(1), bzdiff(1), bzgrep(1)
diff --git a/Utilities/cmbzip2/compress.c b/Utilities/cmbzip2/compress.c
index feea233..5dfa002 100644
--- a/Utilities/cmbzip2/compress.c
+++ b/Utilities/cmbzip2/compress.c
@@ -8,8 +8,8 @@
    This file is part of bzip2/libbzip2, a program and library for
    lossless, block-sorting data compression.
 
-   bzip2/libbzip2 version 1.0.5 of 10 December 2007
-   Copyright (C) 1996-2007 Julian Seward <jseward@bzip.org>
+   bzip2/libbzip2 version 1.0.8 of 13 July 2019
+   Copyright (C) 1996-2019 Julian Seward <jseward@acm.org>
 
    Please read the WARNING, DISCLAIMER and PATENTS sections in the 
    README file.
@@ -239,7 +239,7 @@
 void sendMTFValues ( EState* s )
 {
    Int32 v, t, i, j, gs, ge, totc, bt, bc, iter;
-   Int32 nSelectors = 0, alphaSize, minLen, maxLen, selCtr;
+   Int32 nSelectors, alphaSize, minLen, maxLen, selCtr;
    Int32 nGroups, nBytes;
 
    /*--
@@ -329,14 +329,14 @@
 
       /*---
         Set up an auxiliary length table which is used to fast-track
-    the common case (nGroups == 6). 
+	the common case (nGroups == 6). 
       ---*/
       if (nGroups == 6) {
          for (v = 0; v < alphaSize; v++) {
             s->len_pack[v][0] = (s->len[1][v] << 16) | s->len[0][v];
             s->len_pack[v][1] = (s->len[3][v] << 16) | s->len[2][v];
             s->len_pack[v][2] = (s->len[5][v] << 16) | s->len[4][v];
-     }
+	 }
       }
 
       nSelectors = 0;
@@ -385,7 +385,7 @@
             cost[4] = cost45 & 0xffff; cost[5] = cost45 >> 16;
 
          } else {
-        /*--- slow version which correctly handles all situations ---*/
+	    /*--- slow version which correctly handles all situations ---*/
             for (i = gs; i <= ge; i++) { 
                UInt16 icv = mtfv[i];
                for (t = 0; t < nGroups; t++) cost[t] += s->len[t][icv];
@@ -426,7 +426,7 @@
 #           undef BZ_ITUR
 
          } else {
-        /*--- slow version which correctly handles all situations ---*/
+	    /*--- slow version which correctly handles all situations ---*/
             for (i = gs; i <= ge; i++)
                s->rfreq[bt][ mtfv[i] ]++;
          }
@@ -454,7 +454,7 @@
 
    AssertH( nGroups < 8, 3002 );
    AssertH( nSelectors < 32768 &&
-            nSelectors <= (2 + (900000 / BZ_G_SIZE)),
+            nSelectors <= BZ_MAX_SELECTORS,
             3003 );
 
 
@@ -579,7 +579,7 @@
 #           undef BZ_ITAH
 
       } else {
-     /*--- slow version which correctly handles all situations ---*/
+	 /*--- slow version which correctly handles all situations ---*/
          for (i = gs; i <= ge; i++) {
             bsW ( s, 
                   s->len  [s->selector[selCtr]] [mtfv[i]],
diff --git a/Utilities/cmbzip2/crctable.c b/Utilities/cmbzip2/crctable.c
index 215687b..2b33c25 100644
--- a/Utilities/cmbzip2/crctable.c
+++ b/Utilities/cmbzip2/crctable.c
@@ -8,8 +8,8 @@
    This file is part of bzip2/libbzip2, a program and library for
    lossless, block-sorting data compression.
 
-   bzip2/libbzip2 version 1.0.5 of 10 December 2007
-   Copyright (C) 1996-2007 Julian Seward <jseward@bzip.org>
+   bzip2/libbzip2 version 1.0.8 of 13 July 2019
+   Copyright (C) 1996-2019 Julian Seward <jseward@acm.org>
 
    Please read the WARNING, DISCLAIMER and PATENTS sections in the 
    README file.
diff --git a/Utilities/cmbzip2/decompress.c b/Utilities/cmbzip2/decompress.c
index bba5e0f..a1a0bac 100644
--- a/Utilities/cmbzip2/decompress.c
+++ b/Utilities/cmbzip2/decompress.c
@@ -8,8 +8,8 @@
    This file is part of bzip2/libbzip2, a program and library for
    lossless, block-sorting data compression.
 
-   bzip2/libbzip2 version 1.0.5 of 10 December 2007
-   Copyright (C) 1996-2007 Julian Seward <jseward@bzip.org>
+   bzip2/libbzip2 version 1.0.8 of 13 July 2019
+   Copyright (C) 1996-2019 Julian Seward <jseward@acm.org>
 
    Please read the WARNING, DISCLAIMER and PATENTS sections in the 
    README file.
@@ -285,7 +285,7 @@
 
       /*--- Now the selectors ---*/
       GET_BITS(BZ_X_SELECTOR_1, nGroups, 3);
-      if (nGroups < 2 || nGroups > 6) RETURN(BZ_DATA_ERROR);
+      if (nGroups < 2 || nGroups > BZ_N_GROUPS) RETURN(BZ_DATA_ERROR);
       GET_BITS(BZ_X_SELECTOR_2, nSelectors, 15);
       if (nSelectors < 1) RETURN(BZ_DATA_ERROR);
       for (i = 0; i < nSelectors; i++) {
@@ -296,8 +296,14 @@
             j++;
             if (j >= nGroups) RETURN(BZ_DATA_ERROR);
          }
-         s->selectorMtf[i] = j;
+         /* Having more than BZ_MAX_SELECTORS doesn't make much sense
+            since they will never be used, but some implementations might
+            "round up" the number of selectors, so just ignore those. */
+         if (i < BZ_MAX_SELECTORS)
+           s->selectorMtf[i] = j;
       }
+      if (nSelectors > BZ_MAX_SELECTORS)
+        nSelectors = BZ_MAX_SELECTORS;
 
       /*--- Undo the MTF values for the selectors. ---*/
       {
@@ -381,6 +387,13 @@
             es = -1;
             N = 1;
             do {
+               /* Check that N doesn't get too big, so that es doesn't
+                  go negative.  The maximum value that can be
+                  RUNA/RUNB encoded is equal to the block size (post
+                  the initial RLE), viz, 900k, so bounding N at 2
+                  million should guard against overflow without
+                  rejecting any legitimate inputs. */
+               if (N >= 2*1024*1024) RETURN(BZ_DATA_ERROR);
                if (nextSym == BZ_RUNA) es = es + (0+1) * N; else
                if (nextSym == BZ_RUNB) es = es + (1+1) * N;
                N = N * 2;
@@ -485,15 +498,28 @@
          RETURN(BZ_DATA_ERROR);
 
       /*-- Set up cftab to facilitate generation of T^(-1) --*/
+      /* Check: unzftab entries in range. */
+      for (i = 0; i <= 255; i++) {
+         if (s->unzftab[i] < 0 || s->unzftab[i] > nblock)
+            RETURN(BZ_DATA_ERROR);
+      }
+      /* Actually generate cftab. */
       s->cftab[0] = 0;
       for (i = 1; i <= 256; i++) s->cftab[i] = s->unzftab[i-1];
       for (i = 1; i <= 256; i++) s->cftab[i] += s->cftab[i-1];
+      /* Check: cftab entries in range. */
       for (i = 0; i <= 256; i++) {
          if (s->cftab[i] < 0 || s->cftab[i] > nblock) {
             /* s->cftab[i] can legitimately be == nblock */
             RETURN(BZ_DATA_ERROR);
          }
       }
+      /* Check: cftab entries non-descending. */
+      for (i = 1; i <= 256; i++) {
+         if (s->cftab[i-1] > s->cftab[i]) {
+            RETURN(BZ_DATA_ERROR);
+         }
+      }
 
       s->state_out_len = 0;
       s->state_out_ch  = 0;
diff --git a/Utilities/cmbzip2/dlltest.c b/Utilities/cmbzip2/dlltest.c
index 4e27da2..03fa146 100644
--- a/Utilities/cmbzip2/dlltest.c
+++ b/Utilities/cmbzip2/dlltest.c
@@ -1,175 +1,175 @@
-/*
-   minibz2
-      libbz2.dll test program.
-      by Yoshioka Tsuneo (tsuneo@rr.iij4u.or.jp)
-      This file is Public Domain.  Welcome any email to me.
-
-   usage: minibz2 [-d] [-{1,2,..9}] [[srcfilename] destfilename]
-*/
-
-#define BZ_IMPORT
-#include <stdio.h>
-#include <stdlib.h>
-#include "bzlib.h"
-#ifdef _WIN32
-#include <io.h>
-#endif
-
-
-#ifdef _WIN32
-
-#define BZ2_LIBNAME "libbz2-1.0.2.DLL" 
-
-#include <windows.h>
-static int BZ2DLLLoaded = 0;
-static HINSTANCE BZ2DLLhLib;
-int BZ2DLLLoadLibrary(void)
-{
-   HINSTANCE hLib;
-
-   if(BZ2DLLLoaded==1){return 0;}
-   hLib=LoadLibrary(BZ2_LIBNAME);
-   if(hLib == NULL){
-      fprintf(stderr,"Can't load %s\n",BZ2_LIBNAME);
-      return -1;
-   }
-   BZ2_bzlibVersion=GetProcAddress(hLib,"BZ2_bzlibVersion");
-   BZ2_bzopen=GetProcAddress(hLib,"BZ2_bzopen");
-   BZ2_bzdopen=GetProcAddress(hLib,"BZ2_bzdopen");
-   BZ2_bzread=GetProcAddress(hLib,"BZ2_bzread");
-   BZ2_bzwrite=GetProcAddress(hLib,"BZ2_bzwrite");
-   BZ2_bzflush=GetProcAddress(hLib,"BZ2_bzflush");
-   BZ2_bzclose=GetProcAddress(hLib,"BZ2_bzclose");
-   BZ2_bzerror=GetProcAddress(hLib,"BZ2_bzerror");
-
-   if (!BZ2_bzlibVersion || !BZ2_bzopen || !BZ2_bzdopen
-       || !BZ2_bzread || !BZ2_bzwrite || !BZ2_bzflush
-       || !BZ2_bzclose || !BZ2_bzerror) {
-      fprintf(stderr,"GetProcAddress failed.\n");
-      return -1;
-   }
-   BZ2DLLLoaded=1;
-   BZ2DLLhLib=hLib;
-   return 0;
-
-}
-int BZ2DLLFreeLibrary(void)
-{
-   if(BZ2DLLLoaded==0){return 0;}
-   FreeLibrary(BZ2DLLhLib);
-   BZ2DLLLoaded=0;
-}
-#endif /* WIN32 */
-
-void usage(void)
-{
-   puts("usage: minibz2 [-d] [-{1,2,..9}] [[srcfilename] destfilename]");
-}
-
-int main(int argc,char *argv[])
-{
-   int decompress = 0;
-   int level = 9;
-   char *fn_r = NULL;
-   char *fn_w = NULL;
-
-#ifdef _WIN32
-   if(BZ2DLLLoadLibrary()<0){
-      fprintf(stderr,"Loading of %s failed.  Giving up.\n", BZ2_LIBNAME);
-      exit(1);
-   }
-   printf("Loading of %s succeeded.  Library version is %s.\n",
-          BZ2_LIBNAME, BZ2_bzlibVersion() );
-#endif
-   while(++argv,--argc){
-      if(**argv =='-' || **argv=='/'){
-         char *p;
-
-         for(p=*argv+1;*p;p++){
-            if(*p=='d'){
-               decompress = 1;
-            }else if('1'<=*p && *p<='9'){
-               level = *p - '0';
-            }else{
-               usage();
-               exit(1);
-            }
-         }
-      }else{
-         break;
-      }
-   }
-   if(argc>=1){
-      fn_r = *argv;
-      argc--;argv++;
-   }else{
-      fn_r = NULL;
-   }
-   if(argc>=1){
-      fn_w = *argv;
-      argc--;argv++;
-   }else{
-      fn_w = NULL;
-   }
-   {
-      int len;
-      char buff[0x1000];
-      char mode[10];
-
-      if(decompress){
-         BZFILE *BZ2fp_r = NULL;
-         FILE *fp_w = NULL;
-
-         if(fn_w){
-            if((fp_w = fopen(fn_w,"wb"))==NULL){
-               printf("can't open [%s]\n",fn_w);
-               perror("reason:");
-               exit(1);
-            }
-         }else{
-            fp_w = stdout;
-         }
-         if((fn_r == NULL && (BZ2fp_r = BZ2_bzdopen(fileno(stdin),"rb"))==NULL)
-            || (fn_r != NULL && (BZ2fp_r = BZ2_bzopen(fn_r,"rb"))==NULL)){
-            printf("can't bz2openstream\n");
-            exit(1);
-         }
-         while((len=BZ2_bzread(BZ2fp_r,buff,0x1000))>0){
-            fwrite(buff,1,len,fp_w);
-         }
-         BZ2_bzclose(BZ2fp_r);
-         if(fp_w != stdout) fclose(fp_w);
-      }else{
-         BZFILE *BZ2fp_w = NULL;
-         FILE *fp_r = NULL;
-
-         if(fn_r){
-            if((fp_r = fopen(fn_r,"rb"))==NULL){
-               printf("can't open [%s]\n",fn_r);
-               perror("reason:");
-               exit(1);
-            }
-         }else{
-            fp_r = stdin;
-         }
-         mode[0]='w';
-         mode[1] = '0' + level;
-         mode[2] = '\0';
-
-         if((fn_w == NULL && (BZ2fp_w = BZ2_bzdopen(fileno(stdout),mode))==NULL)
-            || (fn_w !=NULL && (BZ2fp_w = BZ2_bzopen(fn_w,mode))==NULL)){
-            printf("can't bz2openstream\n");
-            exit(1);
-         }
-         while((len=fread(buff,1,0x1000,fp_r))>0){
-            BZ2_bzwrite(BZ2fp_w,buff,len);
-         }
-         BZ2_bzclose(BZ2fp_w);
-         if(fp_r!=stdin)fclose(fp_r);
-      }
-   }
-#ifdef _WIN32
-   BZ2DLLFreeLibrary();
-#endif
-   return 0;
-}
+/*

+   minibz2

+      libbz2.dll test program.

+      by Yoshioka Tsuneo (tsuneo@rr.iij4u.or.jp)

+      This file is Public Domain.  Welcome any email to me.

+

+   usage: minibz2 [-d] [-{1,2,..9}] [[srcfilename] destfilename]

+*/

+

+#define BZ_IMPORT

+#include <stdio.h>

+#include <stdlib.h>

+#include "bzlib.h"

+#ifdef _WIN32

+#include <io.h>

+#endif

+

+

+#ifdef _WIN32

+

+#define BZ2_LIBNAME "libbz2-1.0.2.DLL" 

+

+#include <windows.h>

+static int BZ2DLLLoaded = 0;

+static HINSTANCE BZ2DLLhLib;

+int BZ2DLLLoadLibrary(void)

+{

+   HINSTANCE hLib;

+

+   if(BZ2DLLLoaded==1){return 0;}

+   hLib=LoadLibrary(BZ2_LIBNAME);

+   if(hLib == NULL){

+      fprintf(stderr,"Can't load %s\n",BZ2_LIBNAME);

+      return -1;

+   }

+   BZ2_bzlibVersion=GetProcAddress(hLib,"BZ2_bzlibVersion");

+   BZ2_bzopen=GetProcAddress(hLib,"BZ2_bzopen");

+   BZ2_bzdopen=GetProcAddress(hLib,"BZ2_bzdopen");

+   BZ2_bzread=GetProcAddress(hLib,"BZ2_bzread");

+   BZ2_bzwrite=GetProcAddress(hLib,"BZ2_bzwrite");

+   BZ2_bzflush=GetProcAddress(hLib,"BZ2_bzflush");

+   BZ2_bzclose=GetProcAddress(hLib,"BZ2_bzclose");

+   BZ2_bzerror=GetProcAddress(hLib,"BZ2_bzerror");

+

+   if (!BZ2_bzlibVersion || !BZ2_bzopen || !BZ2_bzdopen

+       || !BZ2_bzread || !BZ2_bzwrite || !BZ2_bzflush

+       || !BZ2_bzclose || !BZ2_bzerror) {

+      fprintf(stderr,"GetProcAddress failed.\n");

+      return -1;

+   }

+   BZ2DLLLoaded=1;

+   BZ2DLLhLib=hLib;

+   return 0;

+

+}

+int BZ2DLLFreeLibrary(void)

+{

+   if(BZ2DLLLoaded==0){return 0;}

+   FreeLibrary(BZ2DLLhLib);

+   BZ2DLLLoaded=0;

+}

+#endif /* WIN32 */

+

+void usage(void)

+{

+   puts("usage: minibz2 [-d] [-{1,2,..9}] [[srcfilename] destfilename]");

+}

+

+int main(int argc,char *argv[])

+{

+   int decompress = 0;

+   int level = 9;

+   char *fn_r = NULL;

+   char *fn_w = NULL;

+

+#ifdef _WIN32

+   if(BZ2DLLLoadLibrary()<0){

+      fprintf(stderr,"Loading of %s failed.  Giving up.\n", BZ2_LIBNAME);

+      exit(1);

+   }

+   printf("Loading of %s succeeded.  Library version is %s.\n",

+          BZ2_LIBNAME, BZ2_bzlibVersion() );

+#endif

+   while(++argv,--argc){

+      if(**argv =='-' || **argv=='/'){

+         char *p;

+

+         for(p=*argv+1;*p;p++){

+            if(*p=='d'){

+               decompress = 1;

+            }else if('1'<=*p && *p<='9'){

+               level = *p - '0';

+            }else{

+               usage();

+               exit(1);

+            }

+         }

+      }else{

+         break;

+      }

+   }

+   if(argc>=1){

+      fn_r = *argv;

+      argc--;argv++;

+   }else{

+      fn_r = NULL;

+   }

+   if(argc>=1){

+      fn_w = *argv;

+      argc--;argv++;

+   }else{

+      fn_w = NULL;

+   }

+   {

+      int len;

+      char buff[0x1000];

+      char mode[10];

+

+      if(decompress){

+         BZFILE *BZ2fp_r = NULL;

+         FILE *fp_w = NULL;

+

+         if(fn_w){

+            if((fp_w = fopen(fn_w,"wb"))==NULL){

+               printf("can't open [%s]\n",fn_w);

+               perror("reason:");

+               exit(1);

+            }

+         }else{

+            fp_w = stdout;

+         }

+         if((fn_r == NULL && (BZ2fp_r = BZ2_bzdopen(fileno(stdin),"rb"))==NULL)

+            || (fn_r != NULL && (BZ2fp_r = BZ2_bzopen(fn_r,"rb"))==NULL)){

+            printf("can't bz2openstream\n");

+            exit(1);

+         }

+         while((len=BZ2_bzread(BZ2fp_r,buff,0x1000))>0){

+            fwrite(buff,1,len,fp_w);

+         }

+         BZ2_bzclose(BZ2fp_r);

+         if(fp_w != stdout) fclose(fp_w);

+      }else{

+         BZFILE *BZ2fp_w = NULL;

+         FILE *fp_r = NULL;

+

+         if(fn_r){

+            if((fp_r = fopen(fn_r,"rb"))==NULL){

+               printf("can't open [%s]\n",fn_r);

+               perror("reason:");

+               exit(1);

+            }

+         }else{

+            fp_r = stdin;

+         }

+         mode[0]='w';

+         mode[1] = '0' + level;

+         mode[2] = '\0';

+

+         if((fn_w == NULL && (BZ2fp_w = BZ2_bzdopen(fileno(stdout),mode))==NULL)

+            || (fn_w !=NULL && (BZ2fp_w = BZ2_bzopen(fn_w,mode))==NULL)){

+            printf("can't bz2openstream\n");

+            exit(1);

+         }

+         while((len=fread(buff,1,0x1000,fp_r))>0){

+            BZ2_bzwrite(BZ2fp_w,buff,len);

+         }

+         BZ2_bzclose(BZ2fp_w);

+         if(fp_r!=stdin)fclose(fp_r);

+      }

+   }

+#ifdef _WIN32

+   BZ2DLLFreeLibrary();

+#endif

+   return 0;

+}

diff --git a/Utilities/cmbzip2/entities.xml b/Utilities/cmbzip2/entities.xml
deleted file mode 100644
index e9e0553..0000000
--- a/Utilities/cmbzip2/entities.xml
+++ /dev/null
@@ -1,9 +0,0 @@
-<!-- misc. strings -->
-<!ENTITY bz-url "http://www.bzip.org">
-<!ENTITY bz-email "jseward@bzip.org">
-<!ENTITY bz-lifespan "1996-2007">
-
-<!ENTITY bz-version "1.0.5">
-<!ENTITY bz-date "10 December 2007">
-
-<!ENTITY manual-title "bzip2 Manual">
diff --git a/Utilities/cmbzip2/format.pl b/Utilities/cmbzip2/format.pl
deleted file mode 100755
index 2b391da..0000000
--- a/Utilities/cmbzip2/format.pl
+++ /dev/null
@@ -1,68 +0,0 @@
-#!/usr/bin/perl -w
-#
-# ------------------------------------------------------------------
-# This file is part of bzip2/libbzip2, a program and library for
-# lossless, block-sorting data compression.
-#
-# bzip2/libbzip2 version 1.0.5 of 10 December 2007
-# Copyright (C) 1996-2007 Julian Seward <jseward@bzip.org>
-#
-# Please read the WARNING, DISCLAIMER and PATENTS sections in the 
-# README file.
-#
-# This program is released under the terms of the license contained
-# in the file LICENSE.
-# ------------------------------------------------------------------
-#
-use strict;
-
-# get command line values:
-if ( $#ARGV !=1 ) {
-    die "Usage:  $0 xml_infile xml_outfile\n";
-}
-
-my $infile = shift;
-# check infile exists
-die "Can't find file \"$infile\""
-  unless -f $infile;
-# check we can read infile
-if (! -r $infile) {
-    die "Can't read input $infile\n";
-}
-# check we can open infile
-open( INFILE,"<$infile" ) or 
-    die "Can't input $infile $!";
-
-#my $outfile = 'fmt-manual.xml';
-my $outfile = shift;
-#print "Infile: $infile, Outfile: $outfile\n";
-# check we can write to outfile
-open( OUTFILE,">$outfile" ) or 
-    die "Can't output $outfile $! for writing";
-
-my ($prev, $curr, $str);
-$prev = ''; $curr = '';
-while ( <INFILE> ) {
-
-        print OUTFILE $prev;
-    $prev = $curr;
-    $curr = $_;
-    $str = '';
-
-    if ( $prev =~ /<programlisting>$|<screen>$/ ) {
-        chomp $prev;
-        $curr = join( '', $prev, "<![CDATA[", $curr );
-                $prev = '';
-        next;
-    }
-    elsif ( $curr =~ /<\/programlisting>|<\/screen>/ ) {
-        chomp $prev;
-        $curr = join( '', $prev, "]]>", $curr );
-                $prev = '';
-        next;
-    }
-}
-print OUTFILE $curr;
-close INFILE;
-close OUTFILE;
-exit;
diff --git a/Utilities/cmbzip2/huffman.c b/Utilities/cmbzip2/huffman.c
index 87e79e3..43a1899 100644
--- a/Utilities/cmbzip2/huffman.c
+++ b/Utilities/cmbzip2/huffman.c
@@ -8,8 +8,8 @@
    This file is part of bzip2/libbzip2, a program and library for
    lossless, block-sorting data compression.
 
-   bzip2/libbzip2 version 1.0.5 of 10 December 2007
-   Copyright (C) 1996-2007 Julian Seward <jseward@bzip.org>
+   bzip2/libbzip2 version 1.0.8 of 13 July 2019
+   Copyright (C) 1996-2019 Julian Seward <jseward@acm.org>
 
    Please read the WARNING, DISCLAIMER and PATENTS sections in the 
    README file.
diff --git a/Utilities/cmbzip2/libbz2.def b/Utilities/cmbzip2/libbz2.def
deleted file mode 100644
index 69fef54..0000000
--- a/Utilities/cmbzip2/libbz2.def
+++ /dev/null
@@ -1,27 +0,0 @@
-LIBRARY         LIBBZ2
-DESCRIPTION     "libbzip2: library for data compression"
-EXPORTS
-    BZ2_bzCompressInit
-    BZ2_bzCompress
-    BZ2_bzCompressEnd
-    BZ2_bzDecompressInit
-    BZ2_bzDecompress
-    BZ2_bzDecompressEnd
-    BZ2_bzReadOpen
-    BZ2_bzReadClose
-    BZ2_bzReadGetUnused
-    BZ2_bzRead
-    BZ2_bzWriteOpen
-    BZ2_bzWrite
-    BZ2_bzWriteClose
-    BZ2_bzWriteClose64
-    BZ2_bzBuffToBuffCompress
-    BZ2_bzBuffToBuffDecompress
-    BZ2_bzlibVersion
-    BZ2_bzopen
-    BZ2_bzdopen
-    BZ2_bzread
-    BZ2_bzwrite
-    BZ2_bzflush
-    BZ2_bzclose
-    BZ2_bzerror
diff --git a/Utilities/cmbzip2/libbz2.lib b/Utilities/cmbzip2/libbz2.lib
deleted file mode 100644
index 9a97a75..0000000
--- a/Utilities/cmbzip2/libbz2.lib
+++ /dev/null
Binary files differ
diff --git a/Utilities/cmbzip2/makefile.msc b/Utilities/cmbzip2/makefile.msc
deleted file mode 100644
index d5f2e59..0000000
--- a/Utilities/cmbzip2/makefile.msc
+++ /dev/null
@@ -1,63 +0,0 @@
-# Makefile for Microsoft Visual C++ 6.0
-# usage: nmake -f makefile.msc
-# K.M. Syring (syring@gsf.de)
-# Fixed up by JRS for bzip2-0.9.5d release.
-
-CC=cl
-CFLAGS= -DWIN32 -MD -Ox -D_FILE_OFFSET_BITS=64 -nologo
-
-OBJS= blocksort.obj  \
-      huffman.obj    \
-      crctable.obj   \
-      randtable.obj  \
-      compress.obj   \
-      decompress.obj \
-      bzlib.obj
-
-all: lib bzip2 test
-
-bzip2: lib
-    $(CC) $(CFLAGS) -o bzip2 bzip2.c libbz2.lib setargv.obj
-    $(CC) $(CFLAGS) -o bzip2recover bzip2recover.c
-
-lib: $(OBJS)
-    lib /out:libbz2.lib $(OBJS)
-
-test: bzip2
-    type words1
-    .\\bzip2 -1  < sample1.ref > sample1.rb2
-    .\\bzip2 -2  < sample2.ref > sample2.rb2
-    .\\bzip2 -3  < sample3.ref > sample3.rb2
-    .\\bzip2 -d  < sample1.bz2 > sample1.tst
-    .\\bzip2 -d  < sample2.bz2 > sample2.tst
-    .\\bzip2 -ds < sample3.bz2 > sample3.tst
-    @echo All six of the fc's should find no differences.
-    @echo If fc finds an error on sample3.bz2, this could be
-    @echo because WinZip's 'TAR file smart CR/LF conversion'
-    @echo is too clever for its own good.  Disable this option.
-    @echo The correct size for sample3.ref is 120,244.  If it
-    @echo is 150,251, WinZip has messed it up.
-    fc sample1.bz2 sample1.rb2 
-    fc sample2.bz2 sample2.rb2
-    fc sample3.bz2 sample3.rb2
-    fc sample1.tst sample1.ref
-    fc sample2.tst sample2.ref
-    fc sample3.tst sample3.ref
-
-
-
-clean: 
-    del *.obj
-    del libbz2.lib 
-    del bzip2.exe
-    del bzip2recover.exe
-    del sample1.rb2 
-    del sample2.rb2 
-    del sample3.rb2
-    del sample1.tst 
-    del sample2.tst
-    del sample3.tst
-
-.c.obj: 
-    $(CC) $(CFLAGS) -c $*.c -o $*.obj
-
diff --git a/Utilities/cmbzip2/manual.html b/Utilities/cmbzip2/manual.html
deleted file mode 100644
index bb44953..0000000
--- a/Utilities/cmbzip2/manual.html
+++ /dev/null
@@ -1,2540 +0,0 @@
-<html>
-<head>
-<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
-<title>bzip2 and libbzip2, version 1.0.5</title>
-<meta name="generator" content="DocBook XSL Stylesheets V1.69.1">
-<style type="text/css" media="screen">/* Colours:
-#74240f  dark brown      h1, h2, h3, h4
-#336699  medium blue     links
-#339999  turquoise       link hover colour
-#202020  almost black    general text
-#761596  purple          md5sum text
-#626262  dark gray       pre border
-#eeeeee  very light gray pre background
-#f2f2f9  very light blue nav table background
-#3366cc  medium blue     nav table border
-*/
-
-a, a:link, a:visited, a:active { color: #336699; }
-a:hover { color: #339999; }
-
-body { font: 80%/126% sans-serif; }
-h1, h2, h3, h4 { color: #74240f; }
-
-dt { color: #336699; font-weight: bold }
-dd { 
- margin-left: 1.5em; 
- padding-bottom: 0.8em;
-}
-
-/* -- ruler -- */
-div.hr_blue { 
-  height:  3px; 
-  background:#ffffff url("/images/hr_blue.png") repeat-x; }
-div.hr_blue hr { display:none; }
-
-/* release styles */
-#release p { margin-top: 0.4em; }
-#release .md5sum { color: #761596; }
-
-
-/* ------ styles for docs|manuals|howto ------ */
-/* -- lists -- */
-ul  { 
- margin:     0px 4px 16px 16px;
- padding:    0px;
- list-style: url("/images/li-blue.png"); 
-}
-ul li { 
- margin-bottom: 10px;
-}
-ul ul   { 
- list-style-type:  none; 
- list-style-image: none; 
- margin-left:      0px; 
-}
-
-/* header / footer nav tables */
-table.nav {
- border:     solid 1px #3366cc;
- background: #f2f2f9;
- background-color: #f2f2f9;
- margin-bottom: 0.5em;
-}
-/* don't have underlined links in chunked nav menus */
-table.nav a { text-decoration: none; }
-table.nav a:hover { text-decoration: underline; }
-table.nav td { font-size: 85%; }
-
-code, tt, pre { font-size: 120%; }
-code, tt { color: #761596; }
-
-div.literallayout, pre.programlisting, pre.screen {
- color:      #000000;
- padding:    0.5em;
- background: #eeeeee;
- border:     1px solid #626262;
- background-color: #eeeeee;
- margin: 4px 0px 4px 0px; 
-}
-</style>
-</head>
-<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="book" lang="en">
-<div class="titlepage">
-<div>
-<div><h1 class="title">
-<a name="userman"></a>bzip2 and libbzip2, version 1.0.5</h1></div>
-<div><h2 class="subtitle">A program and library for data compression</h2></div>
-<div><div class="authorgroup"><div class="author">
-<h3 class="author">
-<span class="firstname">Julian</span> <span class="surname">Seward</span>
-</h3>
-<div class="affiliation"><span class="orgname">http://www.bzip.org<br></span></div>
-</div></div></div>
-<div><p class="releaseinfo">Version 1.0.5 of 10 December 2007</p></div>
-<div><p class="copyright">Copyright © 1996-2007 Julian Seward</p></div>
-<div><div class="legalnotice">
-<a name="id2499833"></a><p>This program, <code class="computeroutput">bzip2</code>, the
-  associated library <code class="computeroutput">libbzip2</code>, and
-  all documentation, are copyright © 1996-2007 Julian Seward.
-  All rights reserved.</p>
-<p>Redistribution and use in source and binary forms, with
-  or without modification, are permitted provided that the
-  following conditions are met:</p>
-<div class="itemizedlist"><ul type="bullet">
-<li style="list-style-type: disc"><p>Redistributions of source code must retain the
-   above copyright notice, this list of conditions and the
-   following disclaimer.</p></li>
-<li style="list-style-type: disc"><p>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.</p></li>
-<li style="list-style-type: disc"><p>Altered source versions must be plainly marked
-   as such, and must not be misrepresented as being the original
-   software.</p></li>
-<li style="list-style-type: disc"><p>The name of the author may not be used to
-   endorse or promote products derived from this software without
-   specific prior written permission.</p></li>
-</ul></div>
-<p>THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY
-  EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
-  THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
-  PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
-  AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
-  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
-  TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
-  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
-  IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
-  THE POSSIBILITY OF SUCH DAMAGE.</p>
-<p>PATENTS: To the best of my knowledge,
- <code class="computeroutput">bzip2</code> and
- <code class="computeroutput">libbzip2</code> do not use any patented
- algorithms.  However, I do not have the resources to carry
- out a patent search.  Therefore I cannot give any guarantee of
- the above statement.
- </p>
-</div></div>
-</div>
-<hr>
-</div>
-<div class="toc">
-<p><b>Table of Contents</b></p>
-<dl>
-<dt><span class="chapter"><a href="#intro">1. Introduction</a></span></dt>
-<dt><span class="chapter"><a href="#using">2. How to use bzip2</a></span></dt>
-<dd><dl>
-<dt><span class="sect1"><a href="#name">2.1. NAME</a></span></dt>
-<dt><span class="sect1"><a href="#synopsis">2.2. SYNOPSIS</a></span></dt>
-<dt><span class="sect1"><a href="#description">2.3. DESCRIPTION</a></span></dt>
-<dt><span class="sect1"><a href="#options">2.4. OPTIONS</a></span></dt>
-<dt><span class="sect1"><a href="#memory-management">2.5. MEMORY MANAGEMENT</a></span></dt>
-<dt><span class="sect1"><a href="#recovering">2.6. RECOVERING DATA FROM DAMAGED FILES</a></span></dt>
-<dt><span class="sect1"><a href="#performance">2.7. PERFORMANCE NOTES</a></span></dt>
-<dt><span class="sect1"><a href="#caveats">2.8. CAVEATS</a></span></dt>
-<dt><span class="sect1"><a href="#author">2.9. AUTHOR</a></span></dt>
-</dl></dd>
-<dt><span class="chapter"><a href="#libprog">3. 
-Programming with <code class="computeroutput">libbzip2</code>
-</a></span></dt>
-<dd><dl>
-<dt><span class="sect1"><a href="#top-level">3.1. Top-level structure</a></span></dt>
-<dd><dl>
-<dt><span class="sect2"><a href="#ll-summary">3.1.1. Low-level summary</a></span></dt>
-<dt><span class="sect2"><a href="#hl-summary">3.1.2. High-level summary</a></span></dt>
-<dt><span class="sect2"><a href="#util-fns-summary">3.1.3. Utility functions summary</a></span></dt>
-</dl></dd>
-<dt><span class="sect1"><a href="#err-handling">3.2. Error handling</a></span></dt>
-<dt><span class="sect1"><a href="#low-level">3.3. Low-level interface</a></span></dt>
-<dd><dl>
-<dt><span class="sect2"><a href="#bzcompress-init">3.3.1. <code class="computeroutput">BZ2_bzCompressInit</code></a></span></dt>
-<dt><span class="sect2"><a href="#bzCompress">3.3.2. <code class="computeroutput">BZ2_bzCompress</code></a></span></dt>
-<dt><span class="sect2"><a href="#bzCompress-end">3.3.3. <code class="computeroutput">BZ2_bzCompressEnd</code></a></span></dt>
-<dt><span class="sect2"><a href="#bzDecompress-init">3.3.4. <code class="computeroutput">BZ2_bzDecompressInit</code></a></span></dt>
-<dt><span class="sect2"><a href="#bzDecompress">3.3.5. <code class="computeroutput">BZ2_bzDecompress</code></a></span></dt>
-<dt><span class="sect2"><a href="#bzDecompress-end">3.3.6. <code class="computeroutput">BZ2_bzDecompressEnd</code></a></span></dt>
-</dl></dd>
-<dt><span class="sect1"><a href="#hl-interface">3.4. High-level interface</a></span></dt>
-<dd><dl>
-<dt><span class="sect2"><a href="#bzreadopen">3.4.1. <code class="computeroutput">BZ2_bzReadOpen</code></a></span></dt>
-<dt><span class="sect2"><a href="#bzread">3.4.2. <code class="computeroutput">BZ2_bzRead</code></a></span></dt>
-<dt><span class="sect2"><a href="#bzreadgetunused">3.4.3. <code class="computeroutput">BZ2_bzReadGetUnused</code></a></span></dt>
-<dt><span class="sect2"><a href="#bzreadclose">3.4.4. <code class="computeroutput">BZ2_bzReadClose</code></a></span></dt>
-<dt><span class="sect2"><a href="#bzwriteopen">3.4.5. <code class="computeroutput">BZ2_bzWriteOpen</code></a></span></dt>
-<dt><span class="sect2"><a href="#bzwrite">3.4.6. <code class="computeroutput">BZ2_bzWrite</code></a></span></dt>
-<dt><span class="sect2"><a href="#bzwriteclose">3.4.7. <code class="computeroutput">BZ2_bzWriteClose</code></a></span></dt>
-<dt><span class="sect2"><a href="#embed">3.4.8. Handling embedded compressed data streams</a></span></dt>
-<dt><span class="sect2"><a href="#std-rdwr">3.4.9. Standard file-reading/writing code</a></span></dt>
-</dl></dd>
-<dt><span class="sect1"><a href="#util-fns">3.5. Utility functions</a></span></dt>
-<dd><dl>
-<dt><span class="sect2"><a href="#bzbufftobuffcompress">3.5.1. <code class="computeroutput">BZ2_bzBuffToBuffCompress</code></a></span></dt>
-<dt><span class="sect2"><a href="#bzbufftobuffdecompress">3.5.2. <code class="computeroutput">BZ2_bzBuffToBuffDecompress</code></a></span></dt>
-</dl></dd>
-<dt><span class="sect1"><a href="#zlib-compat">3.6. <code class="computeroutput">zlib</code> compatibility functions</a></span></dt>
-<dt><span class="sect1"><a href="#stdio-free">3.7. Using the library in a <code class="computeroutput">stdio</code>-free environment</a></span></dt>
-<dd><dl>
-<dt><span class="sect2"><a href="#stdio-bye">3.7.1. Getting rid of <code class="computeroutput">stdio</code></a></span></dt>
-<dt><span class="sect2"><a href="#critical-error">3.7.2. Critical error handling</a></span></dt>
-</dl></dd>
-<dt><span class="sect1"><a href="#win-dll">3.8. Making a Windows DLL</a></span></dt>
-</dl></dd>
-<dt><span class="chapter"><a href="#misc">4. Miscellanea</a></span></dt>
-<dd><dl>
-<dt><span class="sect1"><a href="#limits">4.1. Limitations of the compressed file format</a></span></dt>
-<dt><span class="sect1"><a href="#port-issues">4.2. Portability issues</a></span></dt>
-<dt><span class="sect1"><a href="#bugs">4.3. Reporting bugs</a></span></dt>
-<dt><span class="sect1"><a href="#package">4.4. Did you get the right package?</a></span></dt>
-<dt><span class="sect1"><a href="#reading">4.5. Further Reading</a></span></dt>
-</dl></dd>
-</dl>
-</div>
-<div class="chapter" lang="en">
-<div class="titlepage"><div><div><h2 class="title">
-<a name="intro"></a>1. Introduction</h2></div></div></div>
-<p><code class="computeroutput">bzip2</code> compresses files
-using the Burrows-Wheeler block-sorting text compression
-algorithm, and Huffman coding.  Compression is generally
-considerably better than that achieved by more conventional
-LZ77/LZ78-based compressors, and approaches the performance of
-the PPM family of statistical compressors.</p>
-<p><code class="computeroutput">bzip2</code> is built on top of
-<code class="computeroutput">libbzip2</code>, a flexible library for
-handling compressed data in the
-<code class="computeroutput">bzip2</code> format.  This manual
-describes both how to use the program and how to work with the
-library interface.  Most of the manual is devoted to this
-library, not the program, which is good news if your interest is
-only in the program.</p>
-<div class="itemizedlist"><ul type="bullet">
-<li style="list-style-type: disc"><p><a href="#using">How to use bzip2</a> describes how to use
- <code class="computeroutput">bzip2</code>; this is the only part
- you need to read if you just want to know how to operate the
- program.</p></li>
-<li style="list-style-type: disc"><p><a href="#libprog">Programming with libbzip2</a> describes the
- programming interfaces in detail, and</p></li>
-<li style="list-style-type: disc"><p><a href="#misc">Miscellanea</a> records some
- miscellaneous notes which I thought ought to be recorded
- somewhere.</p></li>
-</ul></div>
-</div>
-<div class="chapter" lang="en">
-<div class="titlepage"><div><div><h2 class="title">
-<a name="using"></a>2. How to use bzip2</h2></div></div></div>
-<div class="toc">
-<p><b>Table of Contents</b></p>
-<dl>
-<dt><span class="sect1"><a href="#name">2.1. NAME</a></span></dt>
-<dt><span class="sect1"><a href="#synopsis">2.2. SYNOPSIS</a></span></dt>
-<dt><span class="sect1"><a href="#description">2.3. DESCRIPTION</a></span></dt>
-<dt><span class="sect1"><a href="#options">2.4. OPTIONS</a></span></dt>
-<dt><span class="sect1"><a href="#memory-management">2.5. MEMORY MANAGEMENT</a></span></dt>
-<dt><span class="sect1"><a href="#recovering">2.6. RECOVERING DATA FROM DAMAGED FILES</a></span></dt>
-<dt><span class="sect1"><a href="#performance">2.7. PERFORMANCE NOTES</a></span></dt>
-<dt><span class="sect1"><a href="#caveats">2.8. CAVEATS</a></span></dt>
-<dt><span class="sect1"><a href="#author">2.9. AUTHOR</a></span></dt>
-</dl>
-</div>
-<p>This chapter contains a copy of the
-<code class="computeroutput">bzip2</code> man page, and nothing
-else.</p>
-<div class="sect1" lang="en">
-<div class="titlepage"><div><div><h2 class="title" style="clear: both">
-<a name="name"></a>2.1. NAME</h2></div></div></div>
-<div class="itemizedlist"><ul type="bullet">
-<li style="list-style-type: disc"><p><code class="computeroutput">bzip2</code>,
-  <code class="computeroutput">bunzip2</code> - a block-sorting file
-  compressor, v1.0.4</p></li>
-<li style="list-style-type: disc"><p><code class="computeroutput">bzcat</code> -
-   decompresses files to stdout</p></li>
-<li style="list-style-type: disc"><p><code class="computeroutput">bzip2recover</code> -
-   recovers data from damaged bzip2 files</p></li>
-</ul></div>
-</div>
-<div class="sect1" lang="en">
-<div class="titlepage"><div><div><h2 class="title" style="clear: both">
-<a name="synopsis"></a>2.2. SYNOPSIS</h2></div></div></div>
-<div class="itemizedlist"><ul type="bullet">
-<li style="list-style-type: disc"><p><code class="computeroutput">bzip2</code> [
-  -cdfkqstvzVL123456789 ] [ filenames ...  ]</p></li>
-<li style="list-style-type: disc"><p><code class="computeroutput">bunzip2</code> [
-  -fkvsVL ] [ filenames ...  ]</p></li>
-<li style="list-style-type: disc"><p><code class="computeroutput">bzcat</code> [ -s ] [
-  filenames ...  ]</p></li>
-<li style="list-style-type: disc"><p><code class="computeroutput">bzip2recover</code>
-  filename</p></li>
-</ul></div>
-</div>
-<div class="sect1" lang="en">
-<div class="titlepage"><div><div><h2 class="title" style="clear: both">
-<a name="description"></a>2.3. DESCRIPTION</h2></div></div></div>
-<p><code class="computeroutput">bzip2</code> compresses files
-using the Burrows-Wheeler block sorting text compression
-algorithm, and Huffman coding.  Compression is generally
-considerably better than that achieved by more conventional
-LZ77/LZ78-based compressors, and approaches the performance of
-the PPM family of statistical compressors.</p>
-<p>The command-line options are deliberately very similar to
-those of GNU <code class="computeroutput">gzip</code>, but they are
-not identical.</p>
-<p><code class="computeroutput">bzip2</code> expects a list of
-file names to accompany the command-line flags.  Each file is
-replaced by a compressed version of itself, with the name
-<code class="computeroutput">original_name.bz2</code>.  Each
-compressed file has the same modification date, permissions, and,
-when possible, ownership as the corresponding original, so that
-these properties can be correctly restored at decompression time.
-File name handling is naive in the sense that there is no
-mechanism for preserving original file names, permissions,
-ownerships or dates in filesystems which lack these concepts, or
-have serious file name length restrictions, such as
-MS-DOS.</p>
-<p><code class="computeroutput">bzip2</code> and
-<code class="computeroutput">bunzip2</code> will by default not
-overwrite existing files.  If you want this to happen, specify
-the <code class="computeroutput">-f</code> flag.</p>
-<p>If no file names are specified,
-<code class="computeroutput">bzip2</code> compresses from standard
-input to standard output.  In this case,
-<code class="computeroutput">bzip2</code> will decline to write
-compressed output to a terminal, as this would be entirely
-incomprehensible and therefore pointless.</p>
-<p><code class="computeroutput">bunzip2</code> (or
-<code class="computeroutput">bzip2 -d</code>) decompresses all
-specified files.  Files which were not created by
-<code class="computeroutput">bzip2</code> will be detected and
-ignored, and a warning issued.
-<code class="computeroutput">bzip2</code> attempts to guess the
-filename for the decompressed file from that of the compressed
-file as follows:</p>
-<div class="itemizedlist"><ul type="bullet">
-<li style="list-style-type: disc"><p><code class="computeroutput">filename.bz2 </code>
-  becomes
-  <code class="computeroutput">filename</code></p></li>
-<li style="list-style-type: disc"><p><code class="computeroutput">filename.bz </code>
-  becomes
-  <code class="computeroutput">filename</code></p></li>
-<li style="list-style-type: disc"><p><code class="computeroutput">filename.tbz2</code>
-  becomes
-  <code class="computeroutput">filename.tar</code></p></li>
-<li style="list-style-type: disc"><p><code class="computeroutput">filename.tbz </code>
-  becomes
-  <code class="computeroutput">filename.tar</code></p></li>
-<li style="list-style-type: disc"><p><code class="computeroutput">anyothername </code>
-  becomes
-  <code class="computeroutput">anyothername.out</code></p></li>
-</ul></div>
-<p>If the file does not end in one of the recognised endings,
-<code class="computeroutput">.bz2</code>,
-<code class="computeroutput">.bz</code>,
-<code class="computeroutput">.tbz2</code> or
-<code class="computeroutput">.tbz</code>,
-<code class="computeroutput">bzip2</code> complains that it cannot
-guess the name of the original file, and uses the original name
-with <code class="computeroutput">.out</code> appended.</p>
-<p>As with compression, supplying no filenames causes
-decompression from standard input to standard output.</p>
-<p><code class="computeroutput">bunzip2</code> will correctly
-decompress a file which is the concatenation of two or more
-compressed files.  The result is the concatenation of the
-corresponding uncompressed files.  Integrity testing
-(<code class="computeroutput">-t</code>) of concatenated compressed
-files is also supported.</p>
-<p>You can also compress or decompress files to the standard
-output by giving the <code class="computeroutput">-c</code> flag.
-Multiple files may be compressed and decompressed like this.  The
-resulting outputs are fed sequentially to stdout.  Compression of
-multiple files in this manner generates a stream containing
-multiple compressed file representations.  Such a stream can be
-decompressed correctly only by
-<code class="computeroutput">bzip2</code> version 0.9.0 or later.
-Earlier versions of <code class="computeroutput">bzip2</code> will
-stop after decompressing the first file in the stream.</p>
-<p><code class="computeroutput">bzcat</code> (or
-<code class="computeroutput">bzip2 -dc</code>) decompresses all
-specified files to the standard output.</p>
-<p><code class="computeroutput">bzip2</code> will read arguments
-from the environment variables
-<code class="computeroutput">BZIP2</code> and
-<code class="computeroutput">BZIP</code>, in that order, and will
-process them before any arguments read from the command line.
-This gives a convenient way to supply default arguments.</p>
-<p>Compression is always performed, even if the compressed
-file is slightly larger than the original.  Files of less than
-about one hundred bytes tend to get larger, since the compression
-mechanism has a constant overhead in the region of 50 bytes.
-Random data (including the output of most file compressors) is
-coded at about 8.05 bits per byte, giving an expansion of around
-0.5%.</p>
-<p>As a self-check for your protection,
-<code class="computeroutput">bzip2</code> uses 32-bit CRCs to make
-sure that the decompressed version of a file is identical to the
-original.  This guards against corruption of the compressed data,
-and against undetected bugs in
-<code class="computeroutput">bzip2</code> (hopefully very unlikely).
-The chances of data corruption going undetected is microscopic,
-about one chance in four billion for each file processed.  Be
-aware, though, that the check occurs upon decompression, so it
-can only tell you that something is wrong.  It can't help you
-recover the original uncompressed data.  You can use
-<code class="computeroutput">bzip2recover</code> to try to recover
-data from damaged files.</p>
-<p>Return values: 0 for a normal exit, 1 for environmental
-problems (file not found, invalid flags, I/O errors, etc.), 2
-to indicate a corrupt compressed file, 3 for an internal
-consistency error (eg, bug) which caused
-<code class="computeroutput">bzip2</code> to panic.</p>
-</div>
-<div class="sect1" lang="en">
-<div class="titlepage"><div><div><h2 class="title" style="clear: both">
-<a name="options"></a>2.4. OPTIONS</h2></div></div></div>
-<div class="variablelist"><dl>
-<dt><span class="term"><code class="computeroutput">-c --stdout</code></span></dt>
-<dd><p>Compress or decompress to standard
-  output.</p></dd>
-<dt><span class="term"><code class="computeroutput">-d --decompress</code></span></dt>
-<dd><p>Force decompression.
-  <code class="computeroutput">bzip2</code>,
-  <code class="computeroutput">bunzip2</code> and
-  <code class="computeroutput">bzcat</code> are really the same
-  program, and the decision about what actions to take is done on
-  the basis of which name is used.  This flag overrides that
-  mechanism, and forces bzip2 to decompress.</p></dd>
-<dt><span class="term"><code class="computeroutput">-z --compress</code></span></dt>
-<dd><p>The complement to
-  <code class="computeroutput">-d</code>: forces compression,
-  regardless of the invokation name.</p></dd>
-<dt><span class="term"><code class="computeroutput">-t --test</code></span></dt>
-<dd><p>Check integrity of the specified file(s), but
-  don't decompress them.  This really performs a trial
-  decompression and throws away the result.</p></dd>
-<dt><span class="term"><code class="computeroutput">-f --force</code></span></dt>
-<dd>
-<p>Force overwrite of output files.  Normally,
-  <code class="computeroutput">bzip2</code> will not overwrite
-  existing output files.  Also forces
-  <code class="computeroutput">bzip2</code> to break hard links to
-  files, which it otherwise wouldn't do.</p>
-<p><code class="computeroutput">bzip2</code> normally declines
-  to decompress files which don't have the correct magic header
-  bytes. If forced (<code class="computeroutput">-f</code>),
-  however, it will pass such files through unmodified. This is
-  how GNU <code class="computeroutput">gzip</code> behaves.</p>
-</dd>
-<dt><span class="term"><code class="computeroutput">-k --keep</code></span></dt>
-<dd><p>Keep (don't delete) input files during
-  compression or decompression.</p></dd>
-<dt><span class="term"><code class="computeroutput">-s --small</code></span></dt>
-<dd>
-<p>Reduce memory usage, for compression,
-  decompression and testing.  Files are decompressed and tested
-  using a modified algorithm which only requires 2.5 bytes per
-  block byte.  This means any file can be decompressed in 2300k
-  of memory, albeit at about half the normal speed.</p>
-<p>During compression, <code class="computeroutput">-s</code>
-  selects a block size of 200k, which limits memory use to around
-  the same figure, at the expense of your compression ratio.  In
-  short, if your machine is low on memory (8 megabytes or less),
-  use <code class="computeroutput">-s</code> for everything.  See
-  <a href="#memory-management">MEMORY MANAGEMENT</a> below.</p>
-</dd>
-<dt><span class="term"><code class="computeroutput">-q --quiet</code></span></dt>
-<dd><p>Suppress non-essential warning messages.
-  Messages pertaining to I/O errors and other critical events
-  will not be suppressed.</p></dd>
-<dt><span class="term"><code class="computeroutput">-v --verbose</code></span></dt>
-<dd><p>Verbose mode -- show the compression ratio for
-  each file processed.  Further
-  <code class="computeroutput">-v</code>'s increase the verbosity
-  level, spewing out lots of information which is primarily of
-  interest for diagnostic purposes.</p></dd>
-<dt><span class="term"><code class="computeroutput">-L --license -V --version</code></span></dt>
-<dd><p>Display the software version, license terms and
-  conditions.</p></dd>
-<dt><span class="term"><code class="computeroutput">-1</code> (or
- <code class="computeroutput">--fast</code>) to
- <code class="computeroutput">-9</code> (or
- <code class="computeroutput">-best</code>)</span></dt>
-<dd><p>Set the block size to 100 k, 200 k ...  900 k
-  when compressing.  Has no effect when decompressing.  See <a href="#memory-management">MEMORY MANAGEMENT</a> below.  The
-  <code class="computeroutput">--fast</code> and
-  <code class="computeroutput">--best</code> aliases are primarily
-  for GNU <code class="computeroutput">gzip</code> compatibility.
-  In particular, <code class="computeroutput">--fast</code> doesn't
-  make things significantly faster.  And
-  <code class="computeroutput">--best</code> merely selects the
-  default behaviour.</p></dd>
-<dt><span class="term"><code class="computeroutput">--</code></span></dt>
-<dd><p>Treats all subsequent arguments as file names,
-  even if they start with a dash.  This is so you can handle
-  files with names beginning with a dash, for example:
-  <code class="computeroutput">bzip2 --
-  -myfilename</code>.</p></dd>
-<dt>
-<span class="term"><code class="computeroutput">--repetitive-fast</code>, </span><span class="term"><code class="computeroutput">--repetitive-best</code></span>
-</dt>
-<dd><p>These flags are redundant in versions 0.9.5 and
-  above.  They provided some coarse control over the behaviour of
-  the sorting algorithm in earlier versions, which was sometimes
-  useful.  0.9.5 and above have an improved algorithm which
-  renders these flags irrelevant.</p></dd>
-</dl></div>
-</div>
-<div class="sect1" lang="en">
-<div class="titlepage"><div><div><h2 class="title" style="clear: both">
-<a name="memory-management"></a>2.5. MEMORY MANAGEMENT</h2></div></div></div>
-<p><code class="computeroutput">bzip2</code> compresses large
-files in blocks.  The block size affects both the compression
-ratio achieved, and the amount of memory needed for compression
-and decompression.  The flags <code class="computeroutput">-1</code>
-through <code class="computeroutput">-9</code> specify the block
-size to be 100,000 bytes through 900,000 bytes (the default)
-respectively.  At decompression time, the block size used for
-compression is read from the header of the compressed file, and
-<code class="computeroutput">bunzip2</code> then allocates itself
-just enough memory to decompress the file.  Since block sizes are
-stored in compressed files, it follows that the flags
-<code class="computeroutput">-1</code> to
-<code class="computeroutput">-9</code> are irrelevant to and so
-ignored during decompression.</p>
-<p>Compression and decompression requirements, in bytes, can be
-estimated as:</p>
-<pre class="programlisting">Compression:   400k + ( 8 x block size )
-
-Decompression: 100k + ( 4 x block size ), or
-               100k + ( 2.5 x block size )</pre>
-<p>Larger block sizes give rapidly diminishing marginal
-returns.  Most of the compression comes from the first two or
-three hundred k of block size, a fact worth bearing in mind when
-using <code class="computeroutput">bzip2</code> on small machines.
-It is also important to appreciate that the decompression memory
-requirement is set at compression time by the choice of block
-size.</p>
-<p>For files compressed with the default 900k block size,
-<code class="computeroutput">bunzip2</code> will require about 3700
-kbytes to decompress.  To support decompression of any file on a
-4 megabyte machine, <code class="computeroutput">bunzip2</code> has
-an option to decompress using approximately half this amount of
-memory, about 2300 kbytes.  Decompression speed is also halved,
-so you should use this option only where necessary.  The relevant
-flag is <code class="computeroutput">-s</code>.</p>
-<p>In general, try and use the largest block size memory
-constraints allow, since that maximises the compression achieved.
-Compression and decompression speed are virtually unaffected by
-block size.</p>
-<p>Another significant point applies to files which fit in a
-single block -- that means most files you'd encounter using a
-large block size.  The amount of real memory touched is
-proportional to the size of the file, since the file is smaller
-than a block.  For example, compressing a file 20,000 bytes long
-with the flag <code class="computeroutput">-9</code> will cause the
-compressor to allocate around 7600k of memory, but only touch
-400k + 20000 * 8 = 560 kbytes of it.  Similarly, the decompressor
-will allocate 3700k but only touch 100k + 20000 * 4 = 180
-kbytes.</p>
-<p>Here is a table which summarises the maximum memory usage
-for different block sizes.  Also recorded is the total compressed
-size for 14 files of the Calgary Text Compression Corpus
-totalling 3,141,622 bytes.  This column gives some feel for how
-compression varies with block size.  These figures tend to
-understate the advantage of larger block sizes for larger files,
-since the Corpus is dominated by smaller files.</p>
-<pre class="programlisting">        Compress   Decompress   Decompress   Corpus
-Flag     usage      usage       -s usage     Size
-
- -1      1200k       500k         350k      914704
- -2      2000k       900k         600k      877703
- -3      2800k      1300k         850k      860338
- -4      3600k      1700k        1100k      846899
- -5      4400k      2100k        1350k      845160
- -6      5200k      2500k        1600k      838626
- -7      6100k      2900k        1850k      834096
- -8      6800k      3300k        2100k      828642
- -9      7600k      3700k        2350k      828642</pre>
-</div>
-<div class="sect1" lang="en">
-<div class="titlepage"><div><div><h2 class="title" style="clear: both">
-<a name="recovering"></a>2.6. RECOVERING DATA FROM DAMAGED FILES</h2></div></div></div>
-<p><code class="computeroutput">bzip2</code> compresses files in
-blocks, usually 900kbytes long.  Each block is handled
-independently.  If a media or transmission error causes a
-multi-block <code class="computeroutput">.bz2</code> file to become
-damaged, it may be possible to recover data from the undamaged
-blocks in the file.</p>
-<p>The compressed representation of each block is delimited by
-a 48-bit pattern, which makes it possible to find the block
-boundaries with reasonable certainty.  Each block also carries
-its own 32-bit CRC, so damaged blocks can be distinguished from
-undamaged ones.</p>
-<p><code class="computeroutput">bzip2recover</code> is a simple
-program whose purpose is to search for blocks in
-<code class="computeroutput">.bz2</code> files, and write each block
-out into its own <code class="computeroutput">.bz2</code> file.  You
-can then use <code class="computeroutput">bzip2 -t</code> to test
-the integrity of the resulting files, and decompress those which
-are undamaged.</p>
-<p><code class="computeroutput">bzip2recover</code> takes a
-single argument, the name of the damaged file, and writes a
-number of files <code class="computeroutput">rec0001file.bz2</code>,
-<code class="computeroutput">rec0002file.bz2</code>, etc, containing
-the extracted blocks.  The output filenames are designed so that
-the use of wildcards in subsequent processing -- for example,
-<code class="computeroutput">bzip2 -dc rec*file.bz2 &gt;
-recovered_data</code> -- lists the files in the correct
-order.</p>
-<p><code class="computeroutput">bzip2recover</code> should be of
-most use dealing with large <code class="computeroutput">.bz2</code>
-files, as these will contain many blocks.  It is clearly futile
-to use it on damaged single-block files, since a damaged block
-cannot be recovered.  If you wish to minimise any potential data
-loss through media or transmission errors, you might consider
-compressing with a smaller block size.</p>
-</div>
-<div class="sect1" lang="en">
-<div class="titlepage"><div><div><h2 class="title" style="clear: both">
-<a name="performance"></a>2.7. PERFORMANCE NOTES</h2></div></div></div>
-<p>The sorting phase of compression gathers together similar
-strings in the file.  Because of this, files containing very long
-runs of repeated symbols, like "aabaabaabaab ..."  (repeated
-several hundred times) may compress more slowly than normal.
-Versions 0.9.5 and above fare much better than previous versions
-in this respect.  The ratio between worst-case and average-case
-compression time is in the region of 10:1.  For previous
-versions, this figure was more like 100:1.  You can use the
-<code class="computeroutput">-vvvv</code> option to monitor progress
-in great detail, if you want.</p>
-<p>Decompression speed is unaffected by these
-phenomena.</p>
-<p><code class="computeroutput">bzip2</code> usually allocates
-several megabytes of memory to operate in, and then charges all
-over it in a fairly random fashion.  This means that performance,
-both for compressing and decompressing, is largely determined by
-the speed at which your machine can service cache misses.
-Because of this, small changes to the code to reduce the miss
-rate have been observed to give disproportionately large
-performance improvements.  I imagine
-<code class="computeroutput">bzip2</code> will perform best on
-machines with very large caches.</p>
-</div>
-<div class="sect1" lang="en">
-<div class="titlepage"><div><div><h2 class="title" style="clear: both">
-<a name="caveats"></a>2.8. CAVEATS</h2></div></div></div>
-<p>I/O error messages are not as helpful as they could be.
-<code class="computeroutput">bzip2</code> tries hard to detect I/O
-errors and exit cleanly, but the details of what the problem is
-sometimes seem rather misleading.</p>
-<p>This manual page pertains to version 1.0.5 of
-<code class="computeroutput">bzip2</code>.  Compressed data created by
-this version is entirely forwards and backwards compatible with the
-previous public releases, versions 0.1pl2, 0.9.0 and 0.9.5, 1.0.0,
-1.0.1, 1.0.2 and 1.0.3, but with the following exception: 0.9.0 and
-above can correctly decompress multiple concatenated compressed files.
-0.1pl2 cannot do this; it will stop after decompressing just the first
-file in the stream.</p>
-<p><code class="computeroutput">bzip2recover</code> versions
-prior to 1.0.2 used 32-bit integers to represent bit positions in
-compressed files, so it could not handle compressed files more
-than 512 megabytes long.  Versions 1.0.2 and above use 64-bit ints
-on some platforms which support them (GNU supported targets, and
-Windows). To establish whether or not
-<code class="computeroutput">bzip2recover</code> was built with such
-a limitation, run it without arguments. In any event you can
-build yourself an unlimited version if you can recompile it with
-<code class="computeroutput">MaybeUInt64</code> set to be an
-unsigned 64-bit integer.</p>
-</div>
-<div class="sect1" lang="en">
-<div class="titlepage"><div><div><h2 class="title" style="clear: both">
-<a name="author"></a>2.9. AUTHOR</h2></div></div></div>
-<p>Julian Seward,
-<code class="computeroutput">jseward@bzip.org</code></p>
-<p>The ideas embodied in
-<code class="computeroutput">bzip2</code> are due to (at least) the
-following people: Michael Burrows and David Wheeler (for the
-block sorting transformation), David Wheeler (again, for the
-Huffman coder), Peter Fenwick (for the structured coding model in
-the original <code class="computeroutput">bzip</code>, and many
-refinements), and Alistair Moffat, Radford Neal and Ian Witten
-(for the arithmetic coder in the original
-<code class="computeroutput">bzip</code>).  I am much indebted for
-their help, support and advice.  See the manual in the source
-distribution for pointers to sources of documentation.  Christian
-von Roques encouraged me to look for faster sorting algorithms,
-so as to speed up compression.  Bela Lubkin encouraged me to
-improve the worst-case compression performance.  
-Donna Robinson XMLised the documentation.
-Many people sent
-patches, helped with portability problems, lent machines, gave
-advice and were generally helpful.</p>
-</div>
-</div>
-<div class="chapter" lang="en">
-<div class="titlepage"><div><div><h2 class="title">
-<a name="libprog"></a>3. 
-Programming with <code class="computeroutput">libbzip2</code>
-</h2></div></div></div>
-<div class="toc">
-<p><b>Table of Contents</b></p>
-<dl>
-<dt><span class="sect1"><a href="#top-level">3.1. Top-level structure</a></span></dt>
-<dd><dl>
-<dt><span class="sect2"><a href="#ll-summary">3.1.1. Low-level summary</a></span></dt>
-<dt><span class="sect2"><a href="#hl-summary">3.1.2. High-level summary</a></span></dt>
-<dt><span class="sect2"><a href="#util-fns-summary">3.1.3. Utility functions summary</a></span></dt>
-</dl></dd>
-<dt><span class="sect1"><a href="#err-handling">3.2. Error handling</a></span></dt>
-<dt><span class="sect1"><a href="#low-level">3.3. Low-level interface</a></span></dt>
-<dd><dl>
-<dt><span class="sect2"><a href="#bzcompress-init">3.3.1. <code class="computeroutput">BZ2_bzCompressInit</code></a></span></dt>
-<dt><span class="sect2"><a href="#bzCompress">3.3.2. <code class="computeroutput">BZ2_bzCompress</code></a></span></dt>
-<dt><span class="sect2"><a href="#bzCompress-end">3.3.3. <code class="computeroutput">BZ2_bzCompressEnd</code></a></span></dt>
-<dt><span class="sect2"><a href="#bzDecompress-init">3.3.4. <code class="computeroutput">BZ2_bzDecompressInit</code></a></span></dt>
-<dt><span class="sect2"><a href="#bzDecompress">3.3.5. <code class="computeroutput">BZ2_bzDecompress</code></a></span></dt>
-<dt><span class="sect2"><a href="#bzDecompress-end">3.3.6. <code class="computeroutput">BZ2_bzDecompressEnd</code></a></span></dt>
-</dl></dd>
-<dt><span class="sect1"><a href="#hl-interface">3.4. High-level interface</a></span></dt>
-<dd><dl>
-<dt><span class="sect2"><a href="#bzreadopen">3.4.1. <code class="computeroutput">BZ2_bzReadOpen</code></a></span></dt>
-<dt><span class="sect2"><a href="#bzread">3.4.2. <code class="computeroutput">BZ2_bzRead</code></a></span></dt>
-<dt><span class="sect2"><a href="#bzreadgetunused">3.4.3. <code class="computeroutput">BZ2_bzReadGetUnused</code></a></span></dt>
-<dt><span class="sect2"><a href="#bzreadclose">3.4.4. <code class="computeroutput">BZ2_bzReadClose</code></a></span></dt>
-<dt><span class="sect2"><a href="#bzwriteopen">3.4.5. <code class="computeroutput">BZ2_bzWriteOpen</code></a></span></dt>
-<dt><span class="sect2"><a href="#bzwrite">3.4.6. <code class="computeroutput">BZ2_bzWrite</code></a></span></dt>
-<dt><span class="sect2"><a href="#bzwriteclose">3.4.7. <code class="computeroutput">BZ2_bzWriteClose</code></a></span></dt>
-<dt><span class="sect2"><a href="#embed">3.4.8. Handling embedded compressed data streams</a></span></dt>
-<dt><span class="sect2"><a href="#std-rdwr">3.4.9. Standard file-reading/writing code</a></span></dt>
-</dl></dd>
-<dt><span class="sect1"><a href="#util-fns">3.5. Utility functions</a></span></dt>
-<dd><dl>
-<dt><span class="sect2"><a href="#bzbufftobuffcompress">3.5.1. <code class="computeroutput">BZ2_bzBuffToBuffCompress</code></a></span></dt>
-<dt><span class="sect2"><a href="#bzbufftobuffdecompress">3.5.2. <code class="computeroutput">BZ2_bzBuffToBuffDecompress</code></a></span></dt>
-</dl></dd>
-<dt><span class="sect1"><a href="#zlib-compat">3.6. <code class="computeroutput">zlib</code> compatibility functions</a></span></dt>
-<dt><span class="sect1"><a href="#stdio-free">3.7. Using the library in a <code class="computeroutput">stdio</code>-free environment</a></span></dt>
-<dd><dl>
-<dt><span class="sect2"><a href="#stdio-bye">3.7.1. Getting rid of <code class="computeroutput">stdio</code></a></span></dt>
-<dt><span class="sect2"><a href="#critical-error">3.7.2. Critical error handling</a></span></dt>
-</dl></dd>
-<dt><span class="sect1"><a href="#win-dll">3.8. Making a Windows DLL</a></span></dt>
-</dl>
-</div>
-<p>This chapter describes the programming interface to
-<code class="computeroutput">libbzip2</code>.</p>
-<p>For general background information, particularly about
-memory use and performance aspects, you'd be well advised to read
-<a href="#using">How to use bzip2</a> as well.</p>
-<div class="sect1" lang="en">
-<div class="titlepage"><div><div><h2 class="title" style="clear: both">
-<a name="top-level"></a>3.1. Top-level structure</h2></div></div></div>
-<p><code class="computeroutput">libbzip2</code> is a flexible
-library for compressing and decompressing data in the
-<code class="computeroutput">bzip2</code> data format.  Although
-packaged as a single entity, it helps to regard the library as
-three separate parts: the low level interface, and the high level
-interface, and some utility functions.</p>
-<p>The structure of
-<code class="computeroutput">libbzip2</code>'s interfaces is similar
-to that of Jean-loup Gailly's and Mark Adler's excellent
-<code class="computeroutput">zlib</code> library.</p>
-<p>All externally visible symbols have names beginning
-<code class="computeroutput">BZ2_</code>.  This is new in version
-1.0.  The intention is to minimise pollution of the namespaces of
-library clients.</p>
-<p>To use any part of the library, you need to
-<code class="computeroutput">#include &lt;bzlib.h&gt;</code>
-into your sources.</p>
-<div class="sect2" lang="en">
-<div class="titlepage"><div><div><h3 class="title">
-<a name="ll-summary"></a>3.1.1. Low-level summary</h3></div></div></div>
-<p>This interface provides services for compressing and
-decompressing data in memory.  There's no provision for dealing
-with files, streams or any other I/O mechanisms, just straight
-memory-to-memory work.  In fact, this part of the library can be
-compiled without inclusion of
-<code class="computeroutput">stdio.h</code>, which may be helpful
-for embedded applications.</p>
-<p>The low-level part of the library has no global variables
-and is therefore thread-safe.</p>
-<p>Six routines make up the low level interface:
-<code class="computeroutput">BZ2_bzCompressInit</code>,
-<code class="computeroutput">BZ2_bzCompress</code>, and
-<code class="computeroutput">BZ2_bzCompressEnd</code> for
-compression, and a corresponding trio
-<code class="computeroutput">BZ2_bzDecompressInit</code>,
-<code class="computeroutput">BZ2_bzDecompress</code> and
-<code class="computeroutput">BZ2_bzDecompressEnd</code> for
-decompression.  The <code class="computeroutput">*Init</code>
-functions allocate memory for compression/decompression and do
-other initialisations, whilst the
-<code class="computeroutput">*End</code> functions close down
-operations and release memory.</p>
-<p>The real work is done by
-<code class="computeroutput">BZ2_bzCompress</code> and
-<code class="computeroutput">BZ2_bzDecompress</code>.  These
-compress and decompress data from a user-supplied input buffer to
-a user-supplied output buffer.  These buffers can be any size;
-arbitrary quantities of data are handled by making repeated calls
-to these functions.  This is a flexible mechanism allowing a
-consumer-pull style of activity, or producer-push, or a mixture
-of both.</p>
-</div>
-<div class="sect2" lang="en">
-<div class="titlepage"><div><div><h3 class="title">
-<a name="hl-summary"></a>3.1.2. High-level summary</h3></div></div></div>
-<p>This interface provides some handy wrappers around the
-low-level interface to facilitate reading and writing
-<code class="computeroutput">bzip2</code> format files
-(<code class="computeroutput">.bz2</code> files).  The routines
-provide hooks to facilitate reading files in which the
-<code class="computeroutput">bzip2</code> data stream is embedded
-within some larger-scale file structure, or where there are
-multiple <code class="computeroutput">bzip2</code> data streams
-concatenated end-to-end.</p>
-<p>For reading files,
-<code class="computeroutput">BZ2_bzReadOpen</code>,
-<code class="computeroutput">BZ2_bzRead</code>,
-<code class="computeroutput">BZ2_bzReadClose</code> and 
-<code class="computeroutput">BZ2_bzReadGetUnused</code> are
-supplied.  For writing files,
-<code class="computeroutput">BZ2_bzWriteOpen</code>,
-<code class="computeroutput">BZ2_bzWrite</code> and
-<code class="computeroutput">BZ2_bzWriteFinish</code> are
-available.</p>
-<p>As with the low-level library, no global variables are used
-so the library is per se thread-safe.  However, if I/O errors
-occur whilst reading or writing the underlying compressed files,
-you may have to consult <code class="computeroutput">errno</code> to
-determine the cause of the error.  In that case, you'd need a C
-library which correctly supports
-<code class="computeroutput">errno</code> in a multithreaded
-environment.</p>
-<p>To make the library a little simpler and more portable,
-<code class="computeroutput">BZ2_bzReadOpen</code> and
-<code class="computeroutput">BZ2_bzWriteOpen</code> require you to
-pass them file handles (<code class="computeroutput">FILE*</code>s)
-which have previously been opened for reading or writing
-respectively.  That avoids portability problems associated with
-file operations and file attributes, whilst not being much of an
-imposition on the programmer.</p>
-</div>
-<div class="sect2" lang="en">
-<div class="titlepage"><div><div><h3 class="title">
-<a name="util-fns-summary"></a>3.1.3. Utility functions summary</h3></div></div></div>
-<p>For very simple needs,
-<code class="computeroutput">BZ2_bzBuffToBuffCompress</code> and
-<code class="computeroutput">BZ2_bzBuffToBuffDecompress</code> are
-provided.  These compress data in memory from one buffer to
-another buffer in a single function call.  You should assess
-whether these functions fulfill your memory-to-memory
-compression/decompression requirements before investing effort in
-understanding the more general but more complex low-level
-interface.</p>
-<p>Yoshioka Tsuneo
-(<code class="computeroutput">tsuneo@rr.iij4u.or.jp</code>) has
-contributed some functions to give better
-<code class="computeroutput">zlib</code> compatibility.  These
-functions are <code class="computeroutput">BZ2_bzopen</code>,
-<code class="computeroutput">BZ2_bzread</code>,
-<code class="computeroutput">BZ2_bzwrite</code>,
-<code class="computeroutput">BZ2_bzflush</code>,
-<code class="computeroutput">BZ2_bzclose</code>,
-<code class="computeroutput">BZ2_bzerror</code> and
-<code class="computeroutput">BZ2_bzlibVersion</code>.  You may find
-these functions more convenient for simple file reading and
-writing, than those in the high-level interface.  These functions
-are not (yet) officially part of the library, and are minimally
-documented here.  If they break, you get to keep all the pieces.
-I hope to document them properly when time permits.</p>
-<p>Yoshioka also contributed modifications to allow the
-library to be built as a Windows DLL.</p>
-</div>
-</div>
-<div class="sect1" lang="en">
-<div class="titlepage"><div><div><h2 class="title" style="clear: both">
-<a name="err-handling"></a>3.2. Error handling</h2></div></div></div>
-<p>The library is designed to recover cleanly in all
-situations, including the worst-case situation of decompressing
-random data.  I'm not 100% sure that it can always do this, so
-you might want to add a signal handler to catch segmentation
-violations during decompression if you are feeling especially
-paranoid.  I would be interested in hearing more about the
-robustness of the library to corrupted compressed data.</p>
-<p>Version 1.0.3 more robust in this respect than any
-previous version.  Investigations with Valgrind (a tool for detecting
-problems with memory management) indicate
-that, at least for the few files I tested, all single-bit errors
-in the decompressed data are caught properly, with no
-segmentation faults, no uses of uninitialised data, no out of
-range reads or writes, and no infinite looping in the decompressor.
-So it's certainly pretty robust, although
-I wouldn't claim it to be totally bombproof.</p>
-<p>The file <code class="computeroutput">bzlib.h</code> contains
-all definitions needed to use the library.  In particular, you
-should definitely not include
-<code class="computeroutput">bzlib_private.h</code>.</p>
-<p>In <code class="computeroutput">bzlib.h</code>, the various
-return values are defined.  The following list is not intended as
-an exhaustive description of the circumstances in which a given
-value may be returned -- those descriptions are given later.
-Rather, it is intended to convey the rough meaning of each return
-value.  The first five actions are normal and not intended to
-denote an error situation.</p>
-<div class="variablelist"><dl>
-<dt><span class="term"><code class="computeroutput">BZ_OK</code></span></dt>
-<dd><p>The requested action was completed
-   successfully.</p></dd>
-<dt><span class="term"><code class="computeroutput">BZ_RUN_OK, BZ_FLUSH_OK,
-    BZ_FINISH_OK</code></span></dt>
-<dd><p>In 
-   <code class="computeroutput">BZ2_bzCompress</code>, the requested
-   flush/finish/nothing-special action was completed
-   successfully.</p></dd>
-<dt><span class="term"><code class="computeroutput">BZ_STREAM_END</code></span></dt>
-<dd><p>Compression of data was completed, or the
-   logical stream end was detected during
-   decompression.</p></dd>
-</dl></div>
-<p>The following return values indicate an error of some
-kind.</p>
-<div class="variablelist"><dl>
-<dt><span class="term"><code class="computeroutput">BZ_CONFIG_ERROR</code></span></dt>
-<dd><p>Indicates that the library has been improperly
-   compiled on your platform -- a major configuration error.
-   Specifically, it means that
-   <code class="computeroutput">sizeof(char)</code>,
-   <code class="computeroutput">sizeof(short)</code> and
-   <code class="computeroutput">sizeof(int)</code> are not 1, 2 and
-   4 respectively, as they should be.  Note that the library
-   should still work properly on 64-bit platforms which follow
-   the LP64 programming model -- that is, where
-   <code class="computeroutput">sizeof(long)</code> and
-   <code class="computeroutput">sizeof(void*)</code> are 8.  Under
-   LP64, <code class="computeroutput">sizeof(int)</code> is still 4,
-   so <code class="computeroutput">libbzip2</code>, which doesn't
-   use the <code class="computeroutput">long</code> type, is
-   OK.</p></dd>
-<dt><span class="term"><code class="computeroutput">BZ_SEQUENCE_ERROR</code></span></dt>
-<dd><p>When using the library, it is important to call
-   the functions in the correct sequence and with data structures
-   (buffers etc) in the correct states.
-   <code class="computeroutput">libbzip2</code> checks as much as it
-   can to ensure this is happening, and returns
-   <code class="computeroutput">BZ_SEQUENCE_ERROR</code> if not.
-   Code which complies precisely with the function semantics, as
-   detailed below, should never receive this value; such an event
-   denotes buggy code which you should
-   investigate.</p></dd>
-<dt><span class="term"><code class="computeroutput">BZ_PARAM_ERROR</code></span></dt>
-<dd><p>Returned when a parameter to a function call is
-   out of range or otherwise manifestly incorrect.  As with
-   <code class="computeroutput">BZ_SEQUENCE_ERROR</code>, this
-   denotes a bug in the client code.  The distinction between
-   <code class="computeroutput">BZ_PARAM_ERROR</code> and
-   <code class="computeroutput">BZ_SEQUENCE_ERROR</code> is a bit
-   hazy, but still worth making.</p></dd>
-<dt><span class="term"><code class="computeroutput">BZ_MEM_ERROR</code></span></dt>
-<dd><p>Returned when a request to allocate memory
-   failed.  Note that the quantity of memory needed to decompress
-   a stream cannot be determined until the stream's header has
-   been read.  So
-   <code class="computeroutput">BZ2_bzDecompress</code> and
-   <code class="computeroutput">BZ2_bzRead</code> may return
-   <code class="computeroutput">BZ_MEM_ERROR</code> even though some
-   of the compressed data has been read.  The same is not true
-   for compression; once
-   <code class="computeroutput">BZ2_bzCompressInit</code> or
-   <code class="computeroutput">BZ2_bzWriteOpen</code> have
-   successfully completed,
-   <code class="computeroutput">BZ_MEM_ERROR</code> cannot
-   occur.</p></dd>
-<dt><span class="term"><code class="computeroutput">BZ_DATA_ERROR</code></span></dt>
-<dd><p>Returned when a data integrity error is
-   detected during decompression.  Most importantly, this means
-   when stored and computed CRCs for the data do not match.  This
-   value is also returned upon detection of any other anomaly in
-   the compressed data.</p></dd>
-<dt><span class="term"><code class="computeroutput">BZ_DATA_ERROR_MAGIC</code></span></dt>
-<dd><p>As a special case of
-   <code class="computeroutput">BZ_DATA_ERROR</code>, it is
-   sometimes useful to know when the compressed stream does not
-   start with the correct magic bytes (<code class="computeroutput">'B' 'Z'
-   'h'</code>).</p></dd>
-<dt><span class="term"><code class="computeroutput">BZ_IO_ERROR</code></span></dt>
-<dd><p>Returned by
-   <code class="computeroutput">BZ2_bzRead</code> and
-   <code class="computeroutput">BZ2_bzWrite</code> when there is an
-   error reading or writing in the compressed file, and by
-   <code class="computeroutput">BZ2_bzReadOpen</code> and
-   <code class="computeroutput">BZ2_bzWriteOpen</code> for attempts
-   to use a file for which the error indicator (viz,
-   <code class="computeroutput">ferror(f)</code>) is set.  On
-   receipt of <code class="computeroutput">BZ_IO_ERROR</code>, the
-   caller should consult <code class="computeroutput">errno</code>
-   and/or <code class="computeroutput">perror</code> to acquire
-   operating-system specific information about the
-   problem.</p></dd>
-<dt><span class="term"><code class="computeroutput">BZ_UNEXPECTED_EOF</code></span></dt>
-<dd><p>Returned by
-   <code class="computeroutput">BZ2_bzRead</code> when the
-   compressed file finishes before the logical end of stream is
-   detected.</p></dd>
-<dt><span class="term"><code class="computeroutput">BZ_OUTBUFF_FULL</code></span></dt>
-<dd><p>Returned by
-   <code class="computeroutput">BZ2_bzBuffToBuffCompress</code> and
-   <code class="computeroutput">BZ2_bzBuffToBuffDecompress</code> to
-   indicate that the output data will not fit into the output
-   buffer provided.</p></dd>
-</dl></div>
-</div>
-<div class="sect1" lang="en">
-<div class="titlepage"><div><div><h2 class="title" style="clear: both">
-<a name="low-level"></a>3.3. Low-level interface</h2></div></div></div>
-<div class="sect2" lang="en">
-<div class="titlepage"><div><div><h3 class="title">
-<a name="bzcompress-init"></a>3.3.1. <code class="computeroutput">BZ2_bzCompressInit</code></h3></div></div></div>
-<pre class="programlisting">typedef struct {
-  char *next_in;
-  unsigned int avail_in;
-  unsigned int total_in_lo32;
-  unsigned int total_in_hi32;
-
-  char *next_out;
-  unsigned int avail_out;
-  unsigned int total_out_lo32;
-  unsigned int total_out_hi32;
-
-  void *state;
-
-  void *(*bzalloc)(void *,int,int);
-  void (*bzfree)(void *,void *);
-  void *opaque;
-} bz_stream;
-
-int BZ2_bzCompressInit ( bz_stream *strm, 
-                         int blockSize100k, 
-                         int verbosity,
-                         int workFactor );</pre>
-<p>Prepares for compression.  The
-<code class="computeroutput">bz_stream</code> structure holds all
-data pertaining to the compression activity.  A
-<code class="computeroutput">bz_stream</code> structure should be
-allocated and initialised prior to the call.  The fields of
-<code class="computeroutput">bz_stream</code> comprise the entirety
-of the user-visible data.  <code class="computeroutput">state</code>
-is a pointer to the private data structures required for
-compression.</p>
-<p>Custom memory allocators are supported, via fields
-<code class="computeroutput">bzalloc</code>,
-<code class="computeroutput">bzfree</code>, and
-<code class="computeroutput">opaque</code>.  The value
-<code class="computeroutput">opaque</code> is passed to as the first
-argument to all calls to <code class="computeroutput">bzalloc</code>
-and <code class="computeroutput">bzfree</code>, but is otherwise
-ignored by the library.  The call <code class="computeroutput">bzalloc (
-opaque, n, m )</code> is expected to return a pointer
-<code class="computeroutput">p</code> to <code class="computeroutput">n *
-m</code> bytes of memory, and <code class="computeroutput">bzfree (
-opaque, p )</code> should free that memory.</p>
-<p>If you don't want to use a custom memory allocator, set
-<code class="computeroutput">bzalloc</code>,
-<code class="computeroutput">bzfree</code> and
-<code class="computeroutput">opaque</code> to
-<code class="computeroutput">NULL</code>, and the library will then
-use the standard <code class="computeroutput">malloc</code> /
-<code class="computeroutput">free</code> routines.</p>
-<p>Before calling
-<code class="computeroutput">BZ2_bzCompressInit</code>, fields
-<code class="computeroutput">bzalloc</code>,
-<code class="computeroutput">bzfree</code> and
-<code class="computeroutput">opaque</code> should be filled
-appropriately, as just described.  Upon return, the internal
-state will have been allocated and initialised, and
-<code class="computeroutput">total_in_lo32</code>,
-<code class="computeroutput">total_in_hi32</code>,
-<code class="computeroutput">total_out_lo32</code> and
-<code class="computeroutput">total_out_hi32</code> will have been
-set to zero.  These four fields are used by the library to inform
-the caller of the total amount of data passed into and out of the
-library, respectively.  You should not try to change them.  As of
-version 1.0, 64-bit counts are maintained, even on 32-bit
-platforms, using the <code class="computeroutput">_hi32</code>
-fields to store the upper 32 bits of the count.  So, for example,
-the total amount of data in is <code class="computeroutput">(total_in_hi32
-&lt;&lt; 32) + total_in_lo32</code>.</p>
-<p>Parameter <code class="computeroutput">blockSize100k</code>
-specifies the block size to be used for compression.  It should
-be a value between 1 and 9 inclusive, and the actual block size
-used is 100000 x this figure.  9 gives the best compression but
-takes most memory.</p>
-<p>Parameter <code class="computeroutput">verbosity</code> should
-be set to a number between 0 and 4 inclusive.  0 is silent, and
-greater numbers give increasingly verbose monitoring/debugging
-output.  If the library has been compiled with
-<code class="computeroutput">-DBZ_NO_STDIO</code>, no such output
-will appear for any verbosity setting.</p>
-<p>Parameter <code class="computeroutput">workFactor</code>
-controls how the compression phase behaves when presented with
-worst case, highly repetitive, input data.  If compression runs
-into difficulties caused by repetitive data, the library switches
-from the standard sorting algorithm to a fallback algorithm.  The
-fallback is slower than the standard algorithm by perhaps a
-factor of three, but always behaves reasonably, no matter how bad
-the input.</p>
-<p>Lower values of <code class="computeroutput">workFactor</code>
-reduce the amount of effort the standard algorithm will expend
-before resorting to the fallback.  You should set this parameter
-carefully; too low, and many inputs will be handled by the
-fallback algorithm and so compress rather slowly, too high, and
-your average-to-worst case compression times can become very
-large.  The default value of 30 gives reasonable behaviour over a
-wide range of circumstances.</p>
-<p>Allowable values range from 0 to 250 inclusive.  0 is a
-special case, equivalent to using the default value of 30.</p>
-<p>Note that the compressed output generated is the same
-regardless of whether or not the fallback algorithm is
-used.</p>
-<p>Be aware also that this parameter may disappear entirely in
-future versions of the library.  In principle it should be
-possible to devise a good way to automatically choose which
-algorithm to use.  Such a mechanism would render the parameter
-obsolete.</p>
-<p>Possible return values:</p>
-<pre class="programlisting">BZ_CONFIG_ERROR
-  if the library has been mis-compiled
-BZ_PARAM_ERROR
-  if strm is NULL 
-  or blockSize &lt; 1 or blockSize &gt; 9
-  or verbosity &lt; 0 or verbosity &gt; 4
-  or workFactor &lt; 0 or workFactor &gt; 250
-BZ_MEM_ERROR 
-  if not enough memory is available
-BZ_OK 
-  otherwise</pre>
-<p>Allowable next actions:</p>
-<pre class="programlisting">BZ2_bzCompress
-  if BZ_OK is returned
-  no specific action needed in case of error</pre>
-</div>
-<div class="sect2" lang="en">
-<div class="titlepage"><div><div><h3 class="title">
-<a name="bzCompress"></a>3.3.2. <code class="computeroutput">BZ2_bzCompress</code></h3></div></div></div>
-<pre class="programlisting">int BZ2_bzCompress ( bz_stream *strm, int action );</pre>
-<p>Provides more input and/or output buffer space for the
-library.  The caller maintains input and output buffers, and
-calls <code class="computeroutput">BZ2_bzCompress</code> to transfer
-data between them.</p>
-<p>Before each call to
-<code class="computeroutput">BZ2_bzCompress</code>,
-<code class="computeroutput">next_in</code> should point at the data
-to be compressed, and <code class="computeroutput">avail_in</code>
-should indicate how many bytes the library may read.
-<code class="computeroutput">BZ2_bzCompress</code> updates
-<code class="computeroutput">next_in</code>,
-<code class="computeroutput">avail_in</code> and
-<code class="computeroutput">total_in</code> to reflect the number
-of bytes it has read.</p>
-<p>Similarly, <code class="computeroutput">next_out</code> should
-point to a buffer in which the compressed data is to be placed,
-with <code class="computeroutput">avail_out</code> indicating how
-much output space is available.
-<code class="computeroutput">BZ2_bzCompress</code> updates
-<code class="computeroutput">next_out</code>,
-<code class="computeroutput">avail_out</code> and
-<code class="computeroutput">total_out</code> to reflect the number
-of bytes output.</p>
-<p>You may provide and remove as little or as much data as you
-like on each call of
-<code class="computeroutput">BZ2_bzCompress</code>.  In the limit,
-it is acceptable to supply and remove data one byte at a time,
-although this would be terribly inefficient.  You should always
-ensure that at least one byte of output space is available at
-each call.</p>
-<p>A second purpose of
-<code class="computeroutput">BZ2_bzCompress</code> is to request a
-change of mode of the compressed stream.</p>
-<p>Conceptually, a compressed stream can be in one of four
-states: IDLE, RUNNING, FLUSHING and FINISHING.  Before
-initialisation
-(<code class="computeroutput">BZ2_bzCompressInit</code>) and after
-termination (<code class="computeroutput">BZ2_bzCompressEnd</code>),
-a stream is regarded as IDLE.</p>
-<p>Upon initialisation
-(<code class="computeroutput">BZ2_bzCompressInit</code>), the stream
-is placed in the RUNNING state.  Subsequent calls to
-<code class="computeroutput">BZ2_bzCompress</code> should pass
-<code class="computeroutput">BZ_RUN</code> as the requested action;
-other actions are illegal and will result in
-<code class="computeroutput">BZ_SEQUENCE_ERROR</code>.</p>
-<p>At some point, the calling program will have provided all
-the input data it wants to.  It will then want to finish up -- in
-effect, asking the library to process any data it might have
-buffered internally.  In this state,
-<code class="computeroutput">BZ2_bzCompress</code> will no longer
-attempt to read data from
-<code class="computeroutput">next_in</code>, but it will want to
-write data to <code class="computeroutput">next_out</code>.  Because
-the output buffer supplied by the user can be arbitrarily small,
-the finishing-up operation cannot necessarily be done with a
-single call of
-<code class="computeroutput">BZ2_bzCompress</code>.</p>
-<p>Instead, the calling program passes
-<code class="computeroutput">BZ_FINISH</code> as an action to
-<code class="computeroutput">BZ2_bzCompress</code>.  This changes
-the stream's state to FINISHING.  Any remaining input (ie,
-<code class="computeroutput">next_in[0 .. avail_in-1]</code>) is
-compressed and transferred to the output buffer.  To do this,
-<code class="computeroutput">BZ2_bzCompress</code> must be called
-repeatedly until all the output has been consumed.  At that
-point, <code class="computeroutput">BZ2_bzCompress</code> returns
-<code class="computeroutput">BZ_STREAM_END</code>, and the stream's
-state is set back to IDLE.
-<code class="computeroutput">BZ2_bzCompressEnd</code> should then be
-called.</p>
-<p>Just to make sure the calling program does not cheat, the
-library makes a note of <code class="computeroutput">avail_in</code>
-at the time of the first call to
-<code class="computeroutput">BZ2_bzCompress</code> which has
-<code class="computeroutput">BZ_FINISH</code> as an action (ie, at
-the time the program has announced its intention to not supply
-any more input).  By comparing this value with that of
-<code class="computeroutput">avail_in</code> over subsequent calls
-to <code class="computeroutput">BZ2_bzCompress</code>, the library
-can detect any attempts to slip in more data to compress.  Any
-calls for which this is detected will return
-<code class="computeroutput">BZ_SEQUENCE_ERROR</code>.  This
-indicates a programming mistake which should be corrected.</p>
-<p>Instead of asking to finish, the calling program may ask
-<code class="computeroutput">BZ2_bzCompress</code> to take all the
-remaining input, compress it and terminate the current
-(Burrows-Wheeler) compression block.  This could be useful for
-error control purposes.  The mechanism is analogous to that for
-finishing: call <code class="computeroutput">BZ2_bzCompress</code>
-with an action of <code class="computeroutput">BZ_FLUSH</code>,
-remove output data, and persist with the
-<code class="computeroutput">BZ_FLUSH</code> action until the value
-<code class="computeroutput">BZ_RUN</code> is returned.  As with
-finishing, <code class="computeroutput">BZ2_bzCompress</code>
-detects any attempt to provide more input data once the flush has
-begun.</p>
-<p>Once the flush is complete, the stream returns to the
-normal RUNNING state.</p>
-<p>This all sounds pretty complex, but isn't really.  Here's a
-table which shows which actions are allowable in each state, what
-action will be taken, what the next state is, and what the
-non-error return values are.  Note that you can't explicitly ask
-what state the stream is in, but nor do you need to -- it can be
-inferred from the values returned by
-<code class="computeroutput">BZ2_bzCompress</code>.</p>
-<pre class="programlisting">IDLE/any
-  Illegal.  IDLE state only exists after BZ2_bzCompressEnd or
-  before BZ2_bzCompressInit.
-  Return value = BZ_SEQUENCE_ERROR
-
-RUNNING/BZ_RUN
-  Compress from next_in to next_out as much as possible.
-  Next state = RUNNING
-  Return value = BZ_RUN_OK
-
-RUNNING/BZ_FLUSH
-  Remember current value of next_in. Compress from next_in
-  to next_out as much as possible, but do not accept any more input.
-  Next state = FLUSHING
-  Return value = BZ_FLUSH_OK
-
-RUNNING/BZ_FINISH
-  Remember current value of next_in. Compress from next_in
-  to next_out as much as possible, but do not accept any more input.
-  Next state = FINISHING
-  Return value = BZ_FINISH_OK
-
-FLUSHING/BZ_FLUSH
-  Compress from next_in to next_out as much as possible, 
-  but do not accept any more input.
-  If all the existing input has been used up and all compressed
-  output has been removed
-    Next state = RUNNING; Return value = BZ_RUN_OK
-  else
-    Next state = FLUSHING; Return value = BZ_FLUSH_OK
-
-FLUSHING/other     
-  Illegal.
-  Return value = BZ_SEQUENCE_ERROR
-
-FINISHING/BZ_FINISH
-  Compress from next_in to next_out as much as possible,
-  but to not accept any more input.  
-  If all the existing input has been used up and all compressed
-  output has been removed
-    Next state = IDLE; Return value = BZ_STREAM_END
-  else
-    Next state = FINISHING; Return value = BZ_FINISH_OK
-
-FINISHING/other
-  Illegal.
-  Return value = BZ_SEQUENCE_ERROR</pre>
-<p>That still looks complicated?  Well, fair enough.  The
-usual sequence of calls for compressing a load of data is:</p>
-<div class="orderedlist"><ol type="1">
-<li><p>Get started with
-  <code class="computeroutput">BZ2_bzCompressInit</code>.</p></li>
-<li><p>Shovel data in and shlurp out its compressed form
-  using zero or more calls of
-  <code class="computeroutput">BZ2_bzCompress</code> with action =
-  <code class="computeroutput">BZ_RUN</code>.</p></li>
-<li><p>Finish up. Repeatedly call
-  <code class="computeroutput">BZ2_bzCompress</code> with action =
-  <code class="computeroutput">BZ_FINISH</code>, copying out the
-  compressed output, until
-  <code class="computeroutput">BZ_STREAM_END</code> is
-  returned.</p></li>
-<li><p>Close up and go home.  Call
-  <code class="computeroutput">BZ2_bzCompressEnd</code>.</p></li>
-</ol></div>
-<p>If the data you want to compress fits into your input
-buffer all at once, you can skip the calls of
-<code class="computeroutput">BZ2_bzCompress ( ..., BZ_RUN )</code>
-and just do the <code class="computeroutput">BZ2_bzCompress ( ..., BZ_FINISH
-)</code> calls.</p>
-<p>All required memory is allocated by
-<code class="computeroutput">BZ2_bzCompressInit</code>.  The
-compression library can accept any data at all (obviously).  So
-you shouldn't get any error return values from the
-<code class="computeroutput">BZ2_bzCompress</code> calls.  If you
-do, they will be
-<code class="computeroutput">BZ_SEQUENCE_ERROR</code>, and indicate
-a bug in your programming.</p>
-<p>Trivial other possible return values:</p>
-<pre class="programlisting">BZ_PARAM_ERROR
-  if strm is NULL, or strm-&gt;s is NULL</pre>
-</div>
-<div class="sect2" lang="en">
-<div class="titlepage"><div><div><h3 class="title">
-<a name="bzCompress-end"></a>3.3.3. <code class="computeroutput">BZ2_bzCompressEnd</code></h3></div></div></div>
-<pre class="programlisting">int BZ2_bzCompressEnd ( bz_stream *strm );</pre>
-<p>Releases all memory associated with a compression
-stream.</p>
-<p>Possible return values:</p>
-<pre class="programlisting">BZ_PARAM_ERROR  if strm is NULL or strm-&gt;s is NULL
-BZ_OK           otherwise</pre>
-</div>
-<div class="sect2" lang="en">
-<div class="titlepage"><div><div><h3 class="title">
-<a name="bzDecompress-init"></a>3.3.4. <code class="computeroutput">BZ2_bzDecompressInit</code></h3></div></div></div>
-<pre class="programlisting">int BZ2_bzDecompressInit ( bz_stream *strm, int verbosity, int small );</pre>
-<p>Prepares for decompression.  As with
-<code class="computeroutput">BZ2_bzCompressInit</code>, a
-<code class="computeroutput">bz_stream</code> record should be
-allocated and initialised before the call.  Fields
-<code class="computeroutput">bzalloc</code>,
-<code class="computeroutput">bzfree</code> and
-<code class="computeroutput">opaque</code> should be set if a custom
-memory allocator is required, or made
-<code class="computeroutput">NULL</code> for the normal
-<code class="computeroutput">malloc</code> /
-<code class="computeroutput">free</code> routines.  Upon return, the
-internal state will have been initialised, and
-<code class="computeroutput">total_in</code> and
-<code class="computeroutput">total_out</code> will be zero.</p>
-<p>For the meaning of parameter
-<code class="computeroutput">verbosity</code>, see
-<code class="computeroutput">BZ2_bzCompressInit</code>.</p>
-<p>If <code class="computeroutput">small</code> is nonzero, the
-library will use an alternative decompression algorithm which
-uses less memory but at the cost of decompressing more slowly
-(roughly speaking, half the speed, but the maximum memory
-requirement drops to around 2300k).  See <a href="#using">How to use bzip2</a>
-for more information on memory management.</p>
-<p>Note that the amount of memory needed to decompress a
-stream cannot be determined until the stream's header has been
-read, so even if
-<code class="computeroutput">BZ2_bzDecompressInit</code> succeeds, a
-subsequent <code class="computeroutput">BZ2_bzDecompress</code>
-could fail with
-<code class="computeroutput">BZ_MEM_ERROR</code>.</p>
-<p>Possible return values:</p>
-<pre class="programlisting">BZ_CONFIG_ERROR
-  if the library has been mis-compiled
-BZ_PARAM_ERROR
-  if ( small != 0 &amp;&amp; small != 1 )
-  or (verbosity &lt;; 0 || verbosity &gt; 4)
-BZ_MEM_ERROR
-  if insufficient memory is available</pre>
-<p>Allowable next actions:</p>
-<pre class="programlisting">BZ2_bzDecompress
-  if BZ_OK was returned
-  no specific action required in case of error</pre>
-</div>
-<div class="sect2" lang="en">
-<div class="titlepage"><div><div><h3 class="title">
-<a name="bzDecompress"></a>3.3.5. <code class="computeroutput">BZ2_bzDecompress</code></h3></div></div></div>
-<pre class="programlisting">int BZ2_bzDecompress ( bz_stream *strm );</pre>
-<p>Provides more input and/out output buffer space for the
-library.  The caller maintains input and output buffers, and uses
-<code class="computeroutput">BZ2_bzDecompress</code> to transfer
-data between them.</p>
-<p>Before each call to
-<code class="computeroutput">BZ2_bzDecompress</code>,
-<code class="computeroutput">next_in</code> should point at the
-compressed data, and <code class="computeroutput">avail_in</code>
-should indicate how many bytes the library may read.
-<code class="computeroutput">BZ2_bzDecompress</code> updates
-<code class="computeroutput">next_in</code>,
-<code class="computeroutput">avail_in</code> and
-<code class="computeroutput">total_in</code> to reflect the number
-of bytes it has read.</p>
-<p>Similarly, <code class="computeroutput">next_out</code> should
-point to a buffer in which the uncompressed output is to be
-placed, with <code class="computeroutput">avail_out</code>
-indicating how much output space is available.
-<code class="computeroutput">BZ2_bzCompress</code> updates
-<code class="computeroutput">next_out</code>,
-<code class="computeroutput">avail_out</code> and
-<code class="computeroutput">total_out</code> to reflect the number
-of bytes output.</p>
-<p>You may provide and remove as little or as much data as you
-like on each call of
-<code class="computeroutput">BZ2_bzDecompress</code>.  In the limit,
-it is acceptable to supply and remove data one byte at a time,
-although this would be terribly inefficient.  You should always
-ensure that at least one byte of output space is available at
-each call.</p>
-<p>Use of <code class="computeroutput">BZ2_bzDecompress</code> is
-simpler than
-<code class="computeroutput">BZ2_bzCompress</code>.</p>
-<p>You should provide input and remove output as described
-above, and repeatedly call
-<code class="computeroutput">BZ2_bzDecompress</code> until
-<code class="computeroutput">BZ_STREAM_END</code> is returned.
-Appearance of <code class="computeroutput">BZ_STREAM_END</code>
-denotes that <code class="computeroutput">BZ2_bzDecompress</code>
-has detected the logical end of the compressed stream.
-<code class="computeroutput">BZ2_bzDecompress</code> will not
-produce <code class="computeroutput">BZ_STREAM_END</code> until all
-output data has been placed into the output buffer, so once
-<code class="computeroutput">BZ_STREAM_END</code> appears, you are
-guaranteed to have available all the decompressed output, and
-<code class="computeroutput">BZ2_bzDecompressEnd</code> can safely
-be called.</p>
-<p>If case of an error return value, you should call
-<code class="computeroutput">BZ2_bzDecompressEnd</code> to clean up
-and release memory.</p>
-<p>Possible return values:</p>
-<pre class="programlisting">BZ_PARAM_ERROR
-  if strm is NULL or strm-&gt;s is NULL
-  or strm-&gt;avail_out &lt; 1
-BZ_DATA_ERROR
-  if a data integrity error is detected in the compressed stream
-BZ_DATA_ERROR_MAGIC
-  if the compressed stream doesn't begin with the right magic bytes
-BZ_MEM_ERROR
-  if there wasn't enough memory available
-BZ_STREAM_END
-  if the logical end of the data stream was detected and all
-  output in has been consumed, eg s--&gt;avail_out &gt; 0
-BZ_OK
-  otherwise</pre>
-<p>Allowable next actions:</p>
-<pre class="programlisting">BZ2_bzDecompress
-  if BZ_OK was returned
-BZ2_bzDecompressEnd
-  otherwise</pre>
-</div>
-<div class="sect2" lang="en">
-<div class="titlepage"><div><div><h3 class="title">
-<a name="bzDecompress-end"></a>3.3.6. <code class="computeroutput">BZ2_bzDecompressEnd</code></h3></div></div></div>
-<pre class="programlisting">int BZ2_bzDecompressEnd ( bz_stream *strm );</pre>
-<p>Releases all memory associated with a decompression
-stream.</p>
-<p>Possible return values:</p>
-<pre class="programlisting">BZ_PARAM_ERROR
-  if strm is NULL or strm-&gt;s is NULL
-BZ_OK
-  otherwise</pre>
-<p>Allowable next actions:</p>
-<pre class="programlisting">  None.</pre>
-</div>
-</div>
-<div class="sect1" lang="en">
-<div class="titlepage"><div><div><h2 class="title" style="clear: both">
-<a name="hl-interface"></a>3.4. High-level interface</h2></div></div></div>
-<p>This interface provides functions for reading and writing
-<code class="computeroutput">bzip2</code> format files.  First, some
-general points.</p>
-<div class="itemizedlist"><ul type="bullet">
-<li style="list-style-type: disc"><p>All of the functions take an
-  <code class="computeroutput">int*</code> first argument,
-  <code class="computeroutput">bzerror</code>.  After each call,
-  <code class="computeroutput">bzerror</code> should be consulted
-  first to determine the outcome of the call.  If
-  <code class="computeroutput">bzerror</code> is
-  <code class="computeroutput">BZ_OK</code>, the call completed
-  successfully, and only then should the return value of the
-  function (if any) be consulted.  If
-  <code class="computeroutput">bzerror</code> is
-  <code class="computeroutput">BZ_IO_ERROR</code>, there was an
-  error reading/writing the underlying compressed file, and you
-  should then consult <code class="computeroutput">errno</code> /
-  <code class="computeroutput">perror</code> to determine the cause
-  of the difficulty.  <code class="computeroutput">bzerror</code>
-  may also be set to various other values; precise details are
-  given on a per-function basis below.</p></li>
-<li style="list-style-type: disc"><p>If <code class="computeroutput">bzerror</code> indicates
-  an error (ie, anything except
-  <code class="computeroutput">BZ_OK</code> and
-  <code class="computeroutput">BZ_STREAM_END</code>), you should
-  immediately call
-  <code class="computeroutput">BZ2_bzReadClose</code> (or
-  <code class="computeroutput">BZ2_bzWriteClose</code>, depending on
-  whether you are attempting to read or to write) to free up all
-  resources associated with the stream.  Once an error has been
-  indicated, behaviour of all calls except
-  <code class="computeroutput">BZ2_bzReadClose</code>
-  (<code class="computeroutput">BZ2_bzWriteClose</code>) is
-  undefined.  The implication is that (1)
-  <code class="computeroutput">bzerror</code> should be checked
-  after each call, and (2) if
-  <code class="computeroutput">bzerror</code> indicates an error,
-  <code class="computeroutput">BZ2_bzReadClose</code>
-  (<code class="computeroutput">BZ2_bzWriteClose</code>) should then
-  be called to clean up.</p></li>
-<li style="list-style-type: disc"><p>The <code class="computeroutput">FILE*</code> arguments
-  passed to <code class="computeroutput">BZ2_bzReadOpen</code> /
-  <code class="computeroutput">BZ2_bzWriteOpen</code> should be set
-  to binary mode.  Most Unix systems will do this by default, but
-  other platforms, including Windows and Mac, will not.  If you
-  omit this, you may encounter problems when moving code to new
-  platforms.</p></li>
-<li style="list-style-type: disc"><p>Memory allocation requests are handled by
-  <code class="computeroutput">malloc</code> /
-  <code class="computeroutput">free</code>.  At present there is no
-  facility for user-defined memory allocators in the file I/O
-  functions (could easily be added, though).</p></li>
-</ul></div>
-<div class="sect2" lang="en">
-<div class="titlepage"><div><div><h3 class="title">
-<a name="bzreadopen"></a>3.4.1. <code class="computeroutput">BZ2_bzReadOpen</code></h3></div></div></div>
-<pre class="programlisting">typedef void BZFILE;
-
-BZFILE *BZ2_bzReadOpen( int *bzerror, FILE *f, 
-                        int verbosity, int small,
-                        void *unused, int nUnused );</pre>
-<p>Prepare to read compressed data from file handle
-<code class="computeroutput">f</code>.
-<code class="computeroutput">f</code> should refer to a file which
-has been opened for reading, and for which the error indicator
-(<code class="computeroutput">ferror(f)</code>)is not set.  If
-<code class="computeroutput">small</code> is 1, the library will try
-to decompress using less memory, at the expense of speed.</p>
-<p>For reasons explained below,
-<code class="computeroutput">BZ2_bzRead</code> will decompress the
-<code class="computeroutput">nUnused</code> bytes starting at
-<code class="computeroutput">unused</code>, before starting to read
-from the file <code class="computeroutput">f</code>.  At most
-<code class="computeroutput">BZ_MAX_UNUSED</code> bytes may be
-supplied like this.  If this facility is not required, you should
-pass <code class="computeroutput">NULL</code> and
-<code class="computeroutput">0</code> for
-<code class="computeroutput">unused</code> and
-n<code class="computeroutput">Unused</code> respectively.</p>
-<p>For the meaning of parameters
-<code class="computeroutput">small</code> and
-<code class="computeroutput">verbosity</code>, see
-<code class="computeroutput">BZ2_bzDecompressInit</code>.</p>
-<p>The amount of memory needed to decompress a file cannot be
-determined until the file's header has been read.  So it is
-possible that <code class="computeroutput">BZ2_bzReadOpen</code>
-returns <code class="computeroutput">BZ_OK</code> but a subsequent
-call of <code class="computeroutput">BZ2_bzRead</code> will return
-<code class="computeroutput">BZ_MEM_ERROR</code>.</p>
-<p>Possible assignments to
-<code class="computeroutput">bzerror</code>:</p>
-<pre class="programlisting">BZ_CONFIG_ERROR
-  if the library has been mis-compiled
-BZ_PARAM_ERROR
-  if f is NULL
-  or small is neither 0 nor 1
-  or ( unused == NULL &amp;&amp; nUnused != 0 )
-  or ( unused != NULL &amp;&amp; !(0 &lt;= nUnused &lt;= BZ_MAX_UNUSED) )
-BZ_IO_ERROR
-  if ferror(f) is nonzero
-BZ_MEM_ERROR
-  if insufficient memory is available
-BZ_OK
-  otherwise.</pre>
-<p>Possible return values:</p>
-<pre class="programlisting">Pointer to an abstract BZFILE
-  if bzerror is BZ_OK
-NULL
-  otherwise</pre>
-<p>Allowable next actions:</p>
-<pre class="programlisting">BZ2_bzRead
-  if bzerror is BZ_OK
-BZ2_bzClose
-  otherwise</pre>
-</div>
-<div class="sect2" lang="en">
-<div class="titlepage"><div><div><h3 class="title">
-<a name="bzread"></a>3.4.2. <code class="computeroutput">BZ2_bzRead</code></h3></div></div></div>
-<pre class="programlisting">int BZ2_bzRead ( int *bzerror, BZFILE *b, void *buf, int len );</pre>
-<p>Reads up to <code class="computeroutput">len</code>
-(uncompressed) bytes from the compressed file
-<code class="computeroutput">b</code> into the buffer
-<code class="computeroutput">buf</code>.  If the read was
-successful, <code class="computeroutput">bzerror</code> is set to
-<code class="computeroutput">BZ_OK</code> and the number of bytes
-read is returned.  If the logical end-of-stream was detected,
-<code class="computeroutput">bzerror</code> will be set to
-<code class="computeroutput">BZ_STREAM_END</code>, and the number of
-bytes read is returned.  All other
-<code class="computeroutput">bzerror</code> values denote an
-error.</p>
-<p><code class="computeroutput">BZ2_bzRead</code> will supply
-<code class="computeroutput">len</code> bytes, unless the logical
-stream end is detected or an error occurs.  Because of this, it
-is possible to detect the stream end by observing when the number
-of bytes returned is less than the number requested.
-Nevertheless, this is regarded as inadvisable; you should instead
-check <code class="computeroutput">bzerror</code> after every call
-and watch out for
-<code class="computeroutput">BZ_STREAM_END</code>.</p>
-<p>Internally, <code class="computeroutput">BZ2_bzRead</code>
-copies data from the compressed file in chunks of size
-<code class="computeroutput">BZ_MAX_UNUSED</code> bytes before
-decompressing it.  If the file contains more bytes than strictly
-needed to reach the logical end-of-stream,
-<code class="computeroutput">BZ2_bzRead</code> will almost certainly
-read some of the trailing data before signalling
-<code class="computeroutput">BZ_SEQUENCE_END</code>.  To collect the
-read but unused data once
-<code class="computeroutput">BZ_SEQUENCE_END</code> has appeared,
-call <code class="computeroutput">BZ2_bzReadGetUnused</code>
-immediately before
-<code class="computeroutput">BZ2_bzReadClose</code>.</p>
-<p>Possible assignments to
-<code class="computeroutput">bzerror</code>:</p>
-<pre class="programlisting">BZ_PARAM_ERROR
-  if b is NULL or buf is NULL or len &lt; 0
-BZ_SEQUENCE_ERROR
-  if b was opened with BZ2_bzWriteOpen
-BZ_IO_ERROR
-  if there is an error reading from the compressed file
-BZ_UNEXPECTED_EOF
-  if the compressed file ended before 
-  the logical end-of-stream was detected
-BZ_DATA_ERROR
-  if a data integrity error was detected in the compressed stream
-BZ_DATA_ERROR_MAGIC
-  if the stream does not begin with the requisite header bytes 
-  (ie, is not a bzip2 data file).  This is really 
-  a special case of BZ_DATA_ERROR.
-BZ_MEM_ERROR
-  if insufficient memory was available
-BZ_STREAM_END
-  if the logical end of stream was detected.
-BZ_OK
-  otherwise.</pre>
-<p>Possible return values:</p>
-<pre class="programlisting">number of bytes read
-  if bzerror is BZ_OK or BZ_STREAM_END
-undefined
-  otherwise</pre>
-<p>Allowable next actions:</p>
-<pre class="programlisting">collect data from buf, then BZ2_bzRead or BZ2_bzReadClose
-  if bzerror is BZ_OK
-collect data from buf, then BZ2_bzReadClose or BZ2_bzReadGetUnused
-  if bzerror is BZ_SEQUENCE_END
-BZ2_bzReadClose
-  otherwise</pre>
-</div>
-<div class="sect2" lang="en">
-<div class="titlepage"><div><div><h3 class="title">
-<a name="bzreadgetunused"></a>3.4.3. <code class="computeroutput">BZ2_bzReadGetUnused</code></h3></div></div></div>
-<pre class="programlisting">void BZ2_bzReadGetUnused( int* bzerror, BZFILE *b, 
-                          void** unused, int* nUnused );</pre>
-<p>Returns data which was read from the compressed file but
-was not needed to get to the logical end-of-stream.
-<code class="computeroutput">*unused</code> is set to the address of
-the data, and <code class="computeroutput">*nUnused</code> to the
-number of bytes.  <code class="computeroutput">*nUnused</code> will
-be set to a value between <code class="computeroutput">0</code> and
-<code class="computeroutput">BZ_MAX_UNUSED</code> inclusive.</p>
-<p>This function may only be called once
-<code class="computeroutput">BZ2_bzRead</code> has signalled
-<code class="computeroutput">BZ_STREAM_END</code> but before
-<code class="computeroutput">BZ2_bzReadClose</code>.</p>
-<p>Possible assignments to
-<code class="computeroutput">bzerror</code>:</p>
-<pre class="programlisting">BZ_PARAM_ERROR
-  if b is NULL
-  or unused is NULL or nUnused is NULL
-BZ_SEQUENCE_ERROR
-  if BZ_STREAM_END has not been signalled
-  or if b was opened with BZ2_bzWriteOpen
-BZ_OK
-  otherwise</pre>
-<p>Allowable next actions:</p>
-<pre class="programlisting">BZ2_bzReadClose</pre>
-</div>
-<div class="sect2" lang="en">
-<div class="titlepage"><div><div><h3 class="title">
-<a name="bzreadclose"></a>3.4.4. <code class="computeroutput">BZ2_bzReadClose</code></h3></div></div></div>
-<pre class="programlisting">void BZ2_bzReadClose ( int *bzerror, BZFILE *b );</pre>
-<p>Releases all memory pertaining to the compressed file
-<code class="computeroutput">b</code>.
-<code class="computeroutput">BZ2_bzReadClose</code> does not call
-<code class="computeroutput">fclose</code> on the underlying file
-handle, so you should do that yourself if appropriate.
-<code class="computeroutput">BZ2_bzReadClose</code> should be called
-to clean up after all error situations.</p>
-<p>Possible assignments to
-<code class="computeroutput">bzerror</code>:</p>
-<pre class="programlisting">BZ_SEQUENCE_ERROR
-  if b was opened with BZ2_bzOpenWrite
-BZ_OK
-  otherwise</pre>
-<p>Allowable next actions:</p>
-<pre class="programlisting">none</pre>
-</div>
-<div class="sect2" lang="en">
-<div class="titlepage"><div><div><h3 class="title">
-<a name="bzwriteopen"></a>3.4.5. <code class="computeroutput">BZ2_bzWriteOpen</code></h3></div></div></div>
-<pre class="programlisting">BZFILE *BZ2_bzWriteOpen( int *bzerror, FILE *f, 
-                         int blockSize100k, int verbosity,
-                         int workFactor );</pre>
-<p>Prepare to write compressed data to file handle
-<code class="computeroutput">f</code>.
-<code class="computeroutput">f</code> should refer to a file which
-has been opened for writing, and for which the error indicator
-(<code class="computeroutput">ferror(f)</code>)is not set.</p>
-<p>For the meaning of parameters
-<code class="computeroutput">blockSize100k</code>,
-<code class="computeroutput">verbosity</code> and
-<code class="computeroutput">workFactor</code>, see
-<code class="computeroutput">BZ2_bzCompressInit</code>.</p>
-<p>All required memory is allocated at this stage, so if the
-call completes successfully,
-<code class="computeroutput">BZ_MEM_ERROR</code> cannot be signalled
-by a subsequent call to
-<code class="computeroutput">BZ2_bzWrite</code>.</p>
-<p>Possible assignments to
-<code class="computeroutput">bzerror</code>:</p>
-<pre class="programlisting">BZ_CONFIG_ERROR
-  if the library has been mis-compiled
-BZ_PARAM_ERROR
-  if f is NULL
-  or blockSize100k &lt; 1 or blockSize100k &gt; 9
-BZ_IO_ERROR
-  if ferror(f) is nonzero
-BZ_MEM_ERROR
-  if insufficient memory is available
-BZ_OK
-  otherwise</pre>
-<p>Possible return values:</p>
-<pre class="programlisting">Pointer to an abstract BZFILE
-  if bzerror is BZ_OK
-NULL
-  otherwise</pre>
-<p>Allowable next actions:</p>
-<pre class="programlisting">BZ2_bzWrite
-  if bzerror is BZ_OK
-  (you could go directly to BZ2_bzWriteClose, but this would be pretty pointless)
-BZ2_bzWriteClose
-  otherwise</pre>
-</div>
-<div class="sect2" lang="en">
-<div class="titlepage"><div><div><h3 class="title">
-<a name="bzwrite"></a>3.4.6. <code class="computeroutput">BZ2_bzWrite</code></h3></div></div></div>
-<pre class="programlisting">void BZ2_bzWrite ( int *bzerror, BZFILE *b, void *buf, int len );</pre>
-<p>Absorbs <code class="computeroutput">len</code> bytes from the
-buffer <code class="computeroutput">buf</code>, eventually to be
-compressed and written to the file.</p>
-<p>Possible assignments to
-<code class="computeroutput">bzerror</code>:</p>
-<pre class="programlisting">BZ_PARAM_ERROR
-  if b is NULL or buf is NULL or len &lt; 0
-BZ_SEQUENCE_ERROR
-  if b was opened with BZ2_bzReadOpen
-BZ_IO_ERROR
-  if there is an error writing the compressed file.
-BZ_OK
-  otherwise</pre>
-</div>
-<div class="sect2" lang="en">
-<div class="titlepage"><div><div><h3 class="title">
-<a name="bzwriteclose"></a>3.4.7. <code class="computeroutput">BZ2_bzWriteClose</code></h3></div></div></div>
-<pre class="programlisting">void BZ2_bzWriteClose( int *bzerror, BZFILE* f,
-                       int abandon,
-                       unsigned int* nbytes_in,
-                       unsigned int* nbytes_out );
-
-void BZ2_bzWriteClose64( int *bzerror, BZFILE* f,
-                         int abandon,
-                         unsigned int* nbytes_in_lo32,
-                         unsigned int* nbytes_in_hi32,
-                         unsigned int* nbytes_out_lo32,
-                         unsigned int* nbytes_out_hi32 );</pre>
-<p>Compresses and flushes to the compressed file all data so
-far supplied by <code class="computeroutput">BZ2_bzWrite</code>.
-The logical end-of-stream markers are also written, so subsequent
-calls to <code class="computeroutput">BZ2_bzWrite</code> are
-illegal.  All memory associated with the compressed file
-<code class="computeroutput">b</code> is released.
-<code class="computeroutput">fflush</code> is called on the
-compressed file, but it is not
-<code class="computeroutput">fclose</code>'d.</p>
-<p>If <code class="computeroutput">BZ2_bzWriteClose</code> is
-called to clean up after an error, the only action is to release
-the memory.  The library records the error codes issued by
-previous calls, so this situation will be detected automatically.
-There is no attempt to complete the compression operation, nor to
-<code class="computeroutput">fflush</code> the compressed file.  You
-can force this behaviour to happen even in the case of no error,
-by passing a nonzero value to
-<code class="computeroutput">abandon</code>.</p>
-<p>If <code class="computeroutput">nbytes_in</code> is non-null,
-<code class="computeroutput">*nbytes_in</code> will be set to be the
-total volume of uncompressed data handled.  Similarly,
-<code class="computeroutput">nbytes_out</code> will be set to the
-total volume of compressed data written.  For compatibility with
-older versions of the library,
-<code class="computeroutput">BZ2_bzWriteClose</code> only yields the
-lower 32 bits of these counts.  Use
-<code class="computeroutput">BZ2_bzWriteClose64</code> if you want
-the full 64 bit counts.  These two functions are otherwise
-absolutely identical.</p>
-<p>Possible assignments to
-<code class="computeroutput">bzerror</code>:</p>
-<pre class="programlisting">BZ_SEQUENCE_ERROR
-  if b was opened with BZ2_bzReadOpen
-BZ_IO_ERROR
-  if there is an error writing the compressed file
-BZ_OK
-  otherwise</pre>
-</div>
-<div class="sect2" lang="en">
-<div class="titlepage"><div><div><h3 class="title">
-<a name="embed"></a>3.4.8. Handling embedded compressed data streams</h3></div></div></div>
-<p>The high-level library facilitates use of
-<code class="computeroutput">bzip2</code> data streams which form
-some part of a surrounding, larger data stream.</p>
-<div class="itemizedlist"><ul type="bullet">
-<li style="list-style-type: disc"><p>For writing, the library takes an open file handle,
-  writes compressed data to it,
-  <code class="computeroutput">fflush</code>es it but does not
-  <code class="computeroutput">fclose</code> it.  The calling
-  application can write its own data before and after the
-  compressed data stream, using that same file handle.</p></li>
-<li style="list-style-type: disc"><p>Reading is more complex, and the facilities are not as
-  general as they could be since generality is hard to reconcile
-  with efficiency.  <code class="computeroutput">BZ2_bzRead</code>
-  reads from the compressed file in blocks of size
-  <code class="computeroutput">BZ_MAX_UNUSED</code> bytes, and in
-  doing so probably will overshoot the logical end of compressed
-  stream.  To recover this data once decompression has ended,
-  call <code class="computeroutput">BZ2_bzReadGetUnused</code> after
-  the last call of <code class="computeroutput">BZ2_bzRead</code>
-  (the one returning
-  <code class="computeroutput">BZ_STREAM_END</code>) but before
-  calling
-  <code class="computeroutput">BZ2_bzReadClose</code>.</p></li>
-</ul></div>
-<p>This mechanism makes it easy to decompress multiple
-<code class="computeroutput">bzip2</code> streams placed end-to-end.
-As the end of one stream, when
-<code class="computeroutput">BZ2_bzRead</code> returns
-<code class="computeroutput">BZ_STREAM_END</code>, call
-<code class="computeroutput">BZ2_bzReadGetUnused</code> to collect
-the unused data (copy it into your own buffer somewhere).  That
-data forms the start of the next compressed stream.  To start
-uncompressing that next stream, call
-<code class="computeroutput">BZ2_bzReadOpen</code> again, feeding in
-the unused data via the <code class="computeroutput">unused</code> /
-<code class="computeroutput">nUnused</code> parameters.  Keep doing
-this until <code class="computeroutput">BZ_STREAM_END</code> return
-coincides with the physical end of file
-(<code class="computeroutput">feof(f)</code>).  In this situation
-<code class="computeroutput">BZ2_bzReadGetUnused</code> will of
-course return no data.</p>
-<p>This should give some feel for how the high-level interface
-can be used.  If you require extra flexibility, you'll have to
-bite the bullet and get to grips with the low-level
-interface.</p>
-</div>
-<div class="sect2" lang="en">
-<div class="titlepage"><div><div><h3 class="title">
-<a name="std-rdwr"></a>3.4.9. Standard file-reading/writing code</h3></div></div></div>
-<p>Here's how you'd write data to a compressed file:</p>
-<pre class="programlisting">FILE*   f;
-BZFILE* b;
-int     nBuf;
-char    buf[ /* whatever size you like */ ];
-int     bzerror;
-int     nWritten;
-
-f = fopen ( "myfile.bz2", "w" );
-if ( !f ) {
- /* handle error */
-}
-b = BZ2_bzWriteOpen( &amp;bzerror, f, 9 );
-if (bzerror != BZ_OK) {
- BZ2_bzWriteClose ( b );
- /* handle error */
-}
-
-while ( /* condition */ ) {
- /* get data to write into buf, and set nBuf appropriately */
- nWritten = BZ2_bzWrite ( &amp;bzerror, b, buf, nBuf );
- if (bzerror == BZ_IO_ERROR) { 
-   BZ2_bzWriteClose ( &amp;bzerror, b );
-   /* handle error */
- }
-}
-
-BZ2_bzWriteClose( &amp;bzerror, b );
-if (bzerror == BZ_IO_ERROR) {
- /* handle error */
-}</pre>
-<p>And to read from a compressed file:</p>
-<pre class="programlisting">FILE*   f;
-BZFILE* b;
-int     nBuf;
-char    buf[ /* whatever size you like */ ];
-int     bzerror;
-int     nWritten;
-
-f = fopen ( "myfile.bz2", "r" );
-if ( !f ) {
-  /* handle error */
-}
-b = BZ2_bzReadOpen ( &amp;bzerror, f, 0, NULL, 0 );
-if ( bzerror != BZ_OK ) {
-  BZ2_bzReadClose ( &amp;bzerror, b );
-  /* handle error */
-}
-
-bzerror = BZ_OK;
-while ( bzerror == BZ_OK &amp;&amp; /* arbitrary other conditions */) {
-  nBuf = BZ2_bzRead ( &amp;bzerror, b, buf, /* size of buf */ );
-  if ( bzerror == BZ_OK ) {
-    /* do something with buf[0 .. nBuf-1] */
-  }
-}
-if ( bzerror != BZ_STREAM_END ) {
-   BZ2_bzReadClose ( &amp;bzerror, b );
-   /* handle error */
-} else {
-   BZ2_bzReadClose ( &amp;bzerror, b );
-}</pre>
-</div>
-</div>
-<div class="sect1" lang="en">
-<div class="titlepage"><div><div><h2 class="title" style="clear: both">
-<a name="util-fns"></a>3.5. Utility functions</h2></div></div></div>
-<div class="sect2" lang="en">
-<div class="titlepage"><div><div><h3 class="title">
-<a name="bzbufftobuffcompress"></a>3.5.1. <code class="computeroutput">BZ2_bzBuffToBuffCompress</code></h3></div></div></div>
-<pre class="programlisting">int BZ2_bzBuffToBuffCompress( char*         dest,
-                              unsigned int* destLen,
-                              char*         source,
-                              unsigned int  sourceLen,
-                              int           blockSize100k,
-                              int           verbosity,
-                              int           workFactor );</pre>
-<p>Attempts to compress the data in <code class="computeroutput">source[0
-.. sourceLen-1]</code> into the destination buffer,
-<code class="computeroutput">dest[0 .. *destLen-1]</code>.  If the
-destination buffer is big enough,
-<code class="computeroutput">*destLen</code> is set to the size of
-the compressed data, and <code class="computeroutput">BZ_OK</code>
-is returned.  If the compressed data won't fit,
-<code class="computeroutput">*destLen</code> is unchanged, and
-<code class="computeroutput">BZ_OUTBUFF_FULL</code> is
-returned.</p>
-<p>Compression in this manner is a one-shot event, done with a
-single call to this function.  The resulting compressed data is a
-complete <code class="computeroutput">bzip2</code> format data
-stream.  There is no mechanism for making additional calls to
-provide extra input data.  If you want that kind of mechanism,
-use the low-level interface.</p>
-<p>For the meaning of parameters
-<code class="computeroutput">blockSize100k</code>,
-<code class="computeroutput">verbosity</code> and
-<code class="computeroutput">workFactor</code>, see
-<code class="computeroutput">BZ2_bzCompressInit</code>.</p>
-<p>To guarantee that the compressed data will fit in its
-buffer, allocate an output buffer of size 1% larger than the
-uncompressed data, plus six hundred extra bytes.</p>
-<p><code class="computeroutput">BZ2_bzBuffToBuffDecompress</code>
-will not write data at or beyond
-<code class="computeroutput">dest[*destLen]</code>, even in case of
-buffer overflow.</p>
-<p>Possible return values:</p>
-<pre class="programlisting">BZ_CONFIG_ERROR
-  if the library has been mis-compiled
-BZ_PARAM_ERROR
-  if dest is NULL or destLen is NULL
-  or blockSize100k &lt; 1 or blockSize100k &gt; 9
-  or verbosity &lt; 0 or verbosity &gt; 4
-  or workFactor &lt; 0 or workFactor &gt; 250
-BZ_MEM_ERROR
-  if insufficient memory is available 
-BZ_OUTBUFF_FULL
-  if the size of the compressed data exceeds *destLen
-BZ_OK
-  otherwise</pre>
-</div>
-<div class="sect2" lang="en">
-<div class="titlepage"><div><div><h3 class="title">
-<a name="bzbufftobuffdecompress"></a>3.5.2. <code class="computeroutput">BZ2_bzBuffToBuffDecompress</code></h3></div></div></div>
-<pre class="programlisting">int BZ2_bzBuffToBuffDecompress( char*         dest,
-                                unsigned int* destLen,
-                                char*         source,
-                                unsigned int  sourceLen,
-                                int           small,
-                                int           verbosity );</pre>
-<p>Attempts to decompress the data in <code class="computeroutput">source[0
-.. sourceLen-1]</code> into the destination buffer,
-<code class="computeroutput">dest[0 .. *destLen-1]</code>.  If the
-destination buffer is big enough,
-<code class="computeroutput">*destLen</code> is set to the size of
-the uncompressed data, and <code class="computeroutput">BZ_OK</code>
-is returned.  If the compressed data won't fit,
-<code class="computeroutput">*destLen</code> is unchanged, and
-<code class="computeroutput">BZ_OUTBUFF_FULL</code> is
-returned.</p>
-<p><code class="computeroutput">source</code> is assumed to hold
-a complete <code class="computeroutput">bzip2</code> format data
-stream.
-<code class="computeroutput">BZ2_bzBuffToBuffDecompress</code> tries
-to decompress the entirety of the stream into the output
-buffer.</p>
-<p>For the meaning of parameters
-<code class="computeroutput">small</code> and
-<code class="computeroutput">verbosity</code>, see
-<code class="computeroutput">BZ2_bzDecompressInit</code>.</p>
-<p>Because the compression ratio of the compressed data cannot
-be known in advance, there is no easy way to guarantee that the
-output buffer will be big enough.  You may of course make
-arrangements in your code to record the size of the uncompressed
-data, but such a mechanism is beyond the scope of this
-library.</p>
-<p><code class="computeroutput">BZ2_bzBuffToBuffDecompress</code>
-will not write data at or beyond
-<code class="computeroutput">dest[*destLen]</code>, even in case of
-buffer overflow.</p>
-<p>Possible return values:</p>
-<pre class="programlisting">BZ_CONFIG_ERROR
-  if the library has been mis-compiled
-BZ_PARAM_ERROR
-  if dest is NULL or destLen is NULL
-  or small != 0 &amp;&amp; small != 1
-  or verbosity &lt; 0 or verbosity &gt; 4
-BZ_MEM_ERROR
-  if insufficient memory is available 
-BZ_OUTBUFF_FULL
-  if the size of the compressed data exceeds *destLen
-BZ_DATA_ERROR
-  if a data integrity error was detected in the compressed data
-BZ_DATA_ERROR_MAGIC
-  if the compressed data doesn't begin with the right magic bytes
-BZ_UNEXPECTED_EOF
-  if the compressed data ends unexpectedly
-BZ_OK
-  otherwise</pre>
-</div>
-</div>
-<div class="sect1" lang="en">
-<div class="titlepage"><div><div><h2 class="title" style="clear: both">
-<a name="zlib-compat"></a>3.6. <code class="computeroutput">zlib</code> compatibility functions</h2></div></div></div>
-<p>Yoshioka Tsuneo has contributed some functions to give
-better <code class="computeroutput">zlib</code> compatibility.
-These functions are <code class="computeroutput">BZ2_bzopen</code>,
-<code class="computeroutput">BZ2_bzread</code>,
-<code class="computeroutput">BZ2_bzwrite</code>,
-<code class="computeroutput">BZ2_bzflush</code>,
-<code class="computeroutput">BZ2_bzclose</code>,
-<code class="computeroutput">BZ2_bzerror</code> and
-<code class="computeroutput">BZ2_bzlibVersion</code>.  These
-functions are not (yet) officially part of the library.  If they
-break, you get to keep all the pieces.  Nevertheless, I think
-they work ok.</p>
-<pre class="programlisting">typedef void BZFILE;
-
-const char * BZ2_bzlibVersion ( void );</pre>
-<p>Returns a string indicating the library version.</p>
-<pre class="programlisting">BZFILE * BZ2_bzopen  ( const char *path, const char *mode );
-BZFILE * BZ2_bzdopen ( int        fd,    const char *mode );</pre>
-<p>Opens a <code class="computeroutput">.bz2</code> file for
-reading or writing, using either its name or a pre-existing file
-descriptor.  Analogous to <code class="computeroutput">fopen</code>
-and <code class="computeroutput">fdopen</code>.</p>
-<pre class="programlisting">int BZ2_bzread  ( BZFILE* b, void* buf, int len );
-int BZ2_bzwrite ( BZFILE* b, void* buf, int len );</pre>
-<p>Reads/writes data from/to a previously opened
-<code class="computeroutput">BZFILE</code>.  Analogous to
-<code class="computeroutput">fread</code> and
-<code class="computeroutput">fwrite</code>.</p>
-<pre class="programlisting">int  BZ2_bzflush ( BZFILE* b );
-void BZ2_bzclose ( BZFILE* b );</pre>
-<p>Flushes/closes a <code class="computeroutput">BZFILE</code>.
-<code class="computeroutput">BZ2_bzflush</code> doesn't actually do
-anything.  Analogous to <code class="computeroutput">fflush</code>
-and <code class="computeroutput">fclose</code>.</p>
-<pre class="programlisting">const char * BZ2_bzerror ( BZFILE *b, int *errnum )</pre>
-<p>Returns a string describing the more recent error status of
-<code class="computeroutput">b</code>, and also sets
-<code class="computeroutput">*errnum</code> to its numerical
-value.</p>
-</div>
-<div class="sect1" lang="en">
-<div class="titlepage"><div><div><h2 class="title" style="clear: both">
-<a name="stdio-free"></a>3.7. Using the library in a <code class="computeroutput">stdio</code>-free environment</h2></div></div></div>
-<div class="sect2" lang="en">
-<div class="titlepage"><div><div><h3 class="title">
-<a name="stdio-bye"></a>3.7.1. Getting rid of <code class="computeroutput">stdio</code></h3></div></div></div>
-<p>In a deeply embedded application, you might want to use
-just the memory-to-memory functions.  You can do this
-conveniently by compiling the library with preprocessor symbol
-<code class="computeroutput">BZ_NO_STDIO</code> defined.  Doing this
-gives you a library containing only the following eight
-functions:</p>
-<p><code class="computeroutput">BZ2_bzCompressInit</code>,
-<code class="computeroutput">BZ2_bzCompress</code>,
-<code class="computeroutput">BZ2_bzCompressEnd</code>
-<code class="computeroutput">BZ2_bzDecompressInit</code>,
-<code class="computeroutput">BZ2_bzDecompress</code>,
-<code class="computeroutput">BZ2_bzDecompressEnd</code>
-<code class="computeroutput">BZ2_bzBuffToBuffCompress</code>,
-<code class="computeroutput">BZ2_bzBuffToBuffDecompress</code></p>
-<p>When compiled like this, all functions will ignore
-<code class="computeroutput">verbosity</code> settings.</p>
-</div>
-<div class="sect2" lang="en">
-<div class="titlepage"><div><div><h3 class="title">
-<a name="critical-error"></a>3.7.2. Critical error handling</h3></div></div></div>
-<p><code class="computeroutput">libbzip2</code> contains a number
-of internal assertion checks which should, needless to say, never
-be activated.  Nevertheless, if an assertion should fail,
-behaviour depends on whether or not the library was compiled with
-<code class="computeroutput">BZ_NO_STDIO</code> set.</p>
-<p>For a normal compile, an assertion failure yields the
-message:</p>
-<div class="blockquote"><blockquote class="blockquote">
-<p>bzip2/libbzip2: internal error number N.</p>
-<p>This is a bug in bzip2/libbzip2, 1.0.5 of 10 December 2007.
-Please report it to me at: jseward@bzip.org.  If this happened
-when you were using some program which uses libbzip2 as a
-component, you should also report this bug to the author(s)
-of that program.  Please make an effort to report this bug;
-timely and accurate bug reports eventually lead to higher
-quality software.  Thanks.  Julian Seward, 10 December 2007.
-</p>
-</blockquote></div>
-<p>where <code class="computeroutput">N</code> is some error code
-number.  If <code class="computeroutput">N == 1007</code>, it also
-prints some extra text advising the reader that unreliable memory
-is often associated with internal error 1007. (This is a
-frequently-observed-phenomenon with versions 1.0.0/1.0.1).</p>
-<p><code class="computeroutput">exit(3)</code> is then
-called.</p>
-<p>For a <code class="computeroutput">stdio</code>-free library,
-assertion failures result in a call to a function declared
-as:</p>
-<pre class="programlisting">extern void bz_internal_error ( int errcode );</pre>
-<p>The relevant code is passed as a parameter.  You should
-supply such a function.</p>
-<p>In either case, once an assertion failure has occurred, any
-<code class="computeroutput">bz_stream</code> records involved can
-be regarded as invalid.  You should not attempt to resume normal
-operation with them.</p>
-<p>You may, of course, change critical error handling to suit
-your needs.  As I said above, critical errors indicate bugs in
-the library and should not occur.  All "normal" error situations
-are indicated via error return codes from functions, and can be
-recovered from.</p>
-</div>
-</div>
-<div class="sect1" lang="en">
-<div class="titlepage"><div><div><h2 class="title" style="clear: both">
-<a name="win-dll"></a>3.8. Making a Windows DLL</h2></div></div></div>
-<p>Everything related to Windows has been contributed by
-Yoshioka Tsuneo
-(<code class="computeroutput">tsuneo@rr.iij4u.or.jp</code>), so
-you should send your queries to him (but perhaps Cc: me,
-<code class="computeroutput">jseward@bzip.org</code>).</p>
-<p>My vague understanding of what to do is: using Visual C++
-5.0, open the project file
-<code class="computeroutput">libbz2.dsp</code>, and build.  That's
-all.</p>
-<p>If you can't open the project file for some reason, make a
-new one, naming these files:
-<code class="computeroutput">blocksort.c</code>,
-<code class="computeroutput">bzlib.c</code>,
-<code class="computeroutput">compress.c</code>,
-<code class="computeroutput">crctable.c</code>,
-<code class="computeroutput">decompress.c</code>,
-<code class="computeroutput">huffman.c</code>,
-<code class="computeroutput">randtable.c</code> and
-<code class="computeroutput">libbz2.def</code>.  You will also need
-to name the header files <code class="computeroutput">bzlib.h</code>
-and <code class="computeroutput">bzlib_private.h</code>.</p>
-<p>If you don't use VC++, you may need to define the
-proprocessor symbol
-<code class="computeroutput">_WIN32</code>.</p>
-<p>Finally, <code class="computeroutput">dlltest.c</code> is a
-sample program using the DLL.  It has a project file,
-<code class="computeroutput">dlltest.dsp</code>.</p>
-<p>If you just want a makefile for Visual C, have a look at
-<code class="computeroutput">makefile.msc</code>.</p>
-<p>Be aware that if you compile
-<code class="computeroutput">bzip2</code> itself on Win32, you must
-set <code class="computeroutput">BZ_UNIX</code> to 0 and
-<code class="computeroutput">BZ_LCCWIN32</code> to 1, in the file
-<code class="computeroutput">bzip2.c</code>, before compiling.
-Otherwise the resulting binary won't work correctly.</p>
-<p>I haven't tried any of this stuff myself, but it all looks
-plausible.</p>
-</div>
-</div>
-<div class="chapter" lang="en">
-<div class="titlepage"><div><div><h2 class="title">
-<a name="misc"></a>4. Miscellanea</h2></div></div></div>
-<div class="toc">
-<p><b>Table of Contents</b></p>
-<dl>
-<dt><span class="sect1"><a href="#limits">4.1. Limitations of the compressed file format</a></span></dt>
-<dt><span class="sect1"><a href="#port-issues">4.2. Portability issues</a></span></dt>
-<dt><span class="sect1"><a href="#bugs">4.3. Reporting bugs</a></span></dt>
-<dt><span class="sect1"><a href="#package">4.4. Did you get the right package?</a></span></dt>
-<dt><span class="sect1"><a href="#reading">4.5. Further Reading</a></span></dt>
-</dl>
-</div>
-<p>These are just some random thoughts of mine.  Your mileage
-may vary.</p>
-<div class="sect1" lang="en">
-<div class="titlepage"><div><div><h2 class="title" style="clear: both">
-<a name="limits"></a>4.1. Limitations of the compressed file format</h2></div></div></div>
-<p><code class="computeroutput">bzip2-1.0.X</code>,
-<code class="computeroutput">0.9.5</code> and
-<code class="computeroutput">0.9.0</code> use exactly the same file
-format as the original version,
-<code class="computeroutput">bzip2-0.1</code>.  This decision was
-made in the interests of stability.  Creating yet another
-incompatible compressed file format would create further
-confusion and disruption for users.</p>
-<p>Nevertheless, this is not a painless decision.  Development
-work since the release of
-<code class="computeroutput">bzip2-0.1</code> in August 1997 has
-shown complexities in the file format which slow down
-decompression and, in retrospect, are unnecessary.  These
-are:</p>
-<div class="itemizedlist"><ul type="bullet">
-<li style="list-style-type: disc"><p>The run-length encoder, which is the first of the
-   compression transformations, is entirely irrelevant.  The
-   original purpose was to protect the sorting algorithm from the
-   very worst case input: a string of repeated symbols.  But
-   algorithm steps Q6a and Q6b in the original Burrows-Wheeler
-   technical report (SRC-124) show how repeats can be handled
-   without difficulty in block sorting.</p></li>
-<li style="list-style-type: disc">
-<p>The randomisation mechanism doesn't really need to be
-   there.  Udi Manber and Gene Myers published a suffix array
-   construction algorithm a few years back, which can be employed
-   to sort any block, no matter how repetitive, in O(N log N)
-   time.  Subsequent work by Kunihiko Sadakane has produced a
-   derivative O(N (log N)^2) algorithm which usually outperforms
-   the Manber-Myers algorithm.</p>
-<p>I could have changed to Sadakane's algorithm, but I find
-   it to be slower than <code class="computeroutput">bzip2</code>'s
-   existing algorithm for most inputs, and the randomisation
-   mechanism protects adequately against bad cases.  I didn't
-   think it was a good tradeoff to make.  Partly this is due to
-   the fact that I was not flooded with email complaints about
-   <code class="computeroutput">bzip2-0.1</code>'s performance on
-   repetitive data, so perhaps it isn't a problem for real
-   inputs.</p>
-<p>Probably the best long-term solution, and the one I have
-   incorporated into 0.9.5 and above, is to use the existing
-   sorting algorithm initially, and fall back to a O(N (log N)^2)
-   algorithm if the standard algorithm gets into
-   difficulties.</p>
-</li>
-<li style="list-style-type: disc"><p>The compressed file format was never designed to be
-   handled by a library, and I have had to jump though some hoops
-   to produce an efficient implementation of decompression.  It's
-   a bit hairy.  Try passing
-   <code class="computeroutput">decompress.c</code> through the C
-   preprocessor and you'll see what I mean.  Much of this
-   complexity could have been avoided if the compressed size of
-   each block of data was recorded in the data stream.</p></li>
-<li style="list-style-type: disc"><p>An Adler-32 checksum, rather than a CRC32 checksum,
-   would be faster to compute.</p></li>
-</ul></div>
-<p>It would be fair to say that the
-<code class="computeroutput">bzip2</code> format was frozen before I
-properly and fully understood the performance consequences of
-doing so.</p>
-<p>Improvements which I was able to incorporate into 0.9.0,
-despite using the same file format, are:</p>
-<div class="itemizedlist"><ul type="bullet">
-<li style="list-style-type: disc"><p>Single array implementation of the inverse BWT.  This
-  significantly speeds up decompression, presumably because it
-  reduces the number of cache misses.</p></li>
-<li style="list-style-type: disc"><p>Faster inverse MTF transform for large MTF values.
-  The new implementation is based on the notion of sliding blocks
-  of values.</p></li>
-<li style="list-style-type: disc"><p><code class="computeroutput">bzip2-0.9.0</code> now reads
-  and writes files with <code class="computeroutput">fread</code>
-  and <code class="computeroutput">fwrite</code>; version 0.1 used
-  <code class="computeroutput">putc</code> and
-  <code class="computeroutput">getc</code>.  Duh!  Well, you live
-  and learn.</p></li>
-</ul></div>
-<p>Further ahead, it would be nice to be able to do random
-access into files.  This will require some careful design of
-compressed file formats.</p>
-</div>
-<div class="sect1" lang="en">
-<div class="titlepage"><div><div><h2 class="title" style="clear: both">
-<a name="port-issues"></a>4.2. Portability issues</h2></div></div></div>
-<p>After some consideration, I have decided not to use GNU
-<code class="computeroutput">autoconf</code> to configure 0.9.5 or
-1.0.</p>
-<p><code class="computeroutput">autoconf</code>, admirable and
-wonderful though it is, mainly assists with portability problems
-between Unix-like platforms.  But
-<code class="computeroutput">bzip2</code> doesn't have much in the
-way of portability problems on Unix; most of the difficulties
-appear when porting to the Mac, or to Microsoft's operating
-systems.  <code class="computeroutput">autoconf</code> doesn't help
-in those cases, and brings in a whole load of new
-complexity.</p>
-<p>Most people should be able to compile the library and
-program under Unix straight out-of-the-box, so to speak,
-especially if you have a version of GNU C available.</p>
-<p>There are a couple of
-<code class="computeroutput">__inline__</code> directives in the
-code.  GNU C (<code class="computeroutput">gcc</code>) should be
-able to handle them.  If you're not using GNU C, your C compiler
-shouldn't see them at all.  If your compiler does, for some
-reason, see them and doesn't like them, just
-<code class="computeroutput">#define</code>
-<code class="computeroutput">__inline__</code> to be
-<code class="computeroutput">/* */</code>.  One easy way to do this
-is to compile with the flag
-<code class="computeroutput">-D__inline__=</code>, which should be
-understood by most Unix compilers.</p>
-<p>If you still have difficulties, try compiling with the
-macro <code class="computeroutput">BZ_STRICT_ANSI</code> defined.
-This should enable you to build the library in a strictly ANSI
-compliant environment.  Building the program itself like this is
-dangerous and not supported, since you remove
-<code class="computeroutput">bzip2</code>'s checks against
-compressing directories, symbolic links, devices, and other
-not-really-a-file entities.  This could cause filesystem
-corruption!</p>
-<p>One other thing: if you create a
-<code class="computeroutput">bzip2</code> binary for public distribution,
-please consider linking it statically (<code class="computeroutput">gcc
--static</code>).  This avoids all sorts of library-version
-issues that others may encounter later on.</p>
-<p>If you build <code class="computeroutput">bzip2</code> on
-Win32, you must set <code class="computeroutput">BZ_UNIX</code> to 0
-and <code class="computeroutput">BZ_LCCWIN32</code> to 1, in the
-file <code class="computeroutput">bzip2.c</code>, before compiling.
-Otherwise the resulting binary won't work correctly.</p>
-</div>
-<div class="sect1" lang="en">
-<div class="titlepage"><div><div><h2 class="title" style="clear: both">
-<a name="bugs"></a>4.3. Reporting bugs</h2></div></div></div>
-<p>I tried pretty hard to make sure
-<code class="computeroutput">bzip2</code> is bug free, both by
-design and by testing.  Hopefully you'll never need to read this
-section for real.</p>
-<p>Nevertheless, if <code class="computeroutput">bzip2</code> dies
-with a segmentation fault, a bus error or an internal assertion
-failure, it will ask you to email me a bug report.  Experience from
-years of feedback of bzip2 users indicates that almost all these
-problems can be traced to either compiler bugs or hardware
-problems.</p>
-<div class="itemizedlist"><ul type="bullet">
-<li style="list-style-type: disc">
-<p>Recompile the program with no optimisation, and
-  see if it works.  And/or try a different compiler.  I heard all
-  sorts of stories about various flavours of GNU C (and other
-  compilers) generating bad code for
-  <code class="computeroutput">bzip2</code>, and I've run across two
-  such examples myself.</p>
-<p>2.7.X versions of GNU C are known to generate bad code
-  from time to time, at high optimisation levels.  If you get
-  problems, try using the flags
-  <code class="computeroutput">-O2</code>
-  <code class="computeroutput">-fomit-frame-pointer</code>
-  <code class="computeroutput">-fno-strength-reduce</code>.  You
-  should specifically <span class="emphasis"><em>not</em></span> use
-  <code class="computeroutput">-funroll-loops</code>.</p>
-<p>You may notice that the Makefile runs six tests as part
-  of the build process.  If the program passes all of these, it's
-  a pretty good (but not 100%) indication that the compiler has
-  done its job correctly.</p>
-</li>
-<li style="list-style-type: disc">
-<p>If <code class="computeroutput">bzip2</code>
-  crashes randomly, and the crashes are not repeatable, you may
-  have a flaky memory subsystem.
-  <code class="computeroutput">bzip2</code> really hammers your
-  memory hierarchy, and if it's a bit marginal, you may get these
-  problems.  Ditto if your disk or I/O subsystem is slowly
-  failing.  Yup, this really does happen.</p>
-<p>Try using a different machine of the same type, and see
-  if you can repeat the problem.</p>
-</li>
-<li style="list-style-type: disc"><p>This isn't really a bug, but ... If
-  <code class="computeroutput">bzip2</code> tells you your file is
-  corrupted on decompression, and you obtained the file via FTP,
-  there is a possibility that you forgot to tell FTP to do a
-  binary mode transfer.  That absolutely will cause the file to
-  be non-decompressible.  You'll have to transfer it
-  again.</p></li>
-</ul></div>
-<p>If you've incorporated
-<code class="computeroutput">libbzip2</code> into your own program
-and are getting problems, please, please, please, check that the
-parameters you are passing in calls to the library, are correct,
-and in accordance with what the documentation says is allowable.
-I have tried to make the library robust against such problems,
-but I'm sure I haven't succeeded.</p>
-<p>Finally, if the above comments don't help, you'll have to
-send me a bug report.  Now, it's just amazing how many people
-will send me a bug report saying something like:</p>
-<pre class="programlisting">bzip2 crashed with segmentation fault on my machine</pre>
-<p>and absolutely nothing else.  Needless to say, a such a
-report is <span class="emphasis"><em>totally, utterly, completely and
-comprehensively 100% useless; a waste of your time, my time, and
-net bandwidth</em></span>.  With no details at all, there's no way
-I can possibly begin to figure out what the problem is.</p>
-<p>The rules of the game are: facts, facts, facts.  Don't omit
-them because "oh, they won't be relevant".  At the bare
-minimum:</p>
-<pre class="programlisting">Machine type.  Operating system version.  
-Exact version of bzip2 (do bzip2 -V).  
-Exact version of the compiler used.  
-Flags passed to the compiler.</pre>
-<p>However, the most important single thing that will help me
-is the file that you were trying to compress or decompress at the
-time the problem happened.  Without that, my ability to do
-anything more than speculate about the cause, is limited.</p>
-</div>
-<div class="sect1" lang="en">
-<div class="titlepage"><div><div><h2 class="title" style="clear: both">
-<a name="package"></a>4.4. Did you get the right package?</h2></div></div></div>
-<p><code class="computeroutput">bzip2</code> is a resource hog.
-It soaks up large amounts of CPU cycles and memory.  Also, it
-gives very large latencies.  In the worst case, you can feed many
-megabytes of uncompressed data into the library before getting
-any compressed output, so this probably rules out applications
-requiring interactive behaviour.</p>
-<p>These aren't faults of my implementation, I hope, but more
-an intrinsic property of the Burrows-Wheeler transform
-(unfortunately).  Maybe this isn't what you want.</p>
-<p>If you want a compressor and/or library which is faster,
-uses less memory but gets pretty good compression, and has
-minimal latency, consider Jean-loup Gailly's and Mark Adler's
-work, <code class="computeroutput">zlib-1.2.1</code> and
-<code class="computeroutput">gzip-1.2.4</code>.  Look for them at 
-<a href="http://www.zlib.org" target="_top">http://www.zlib.org</a> and 
-<a href="http://www.gzip.org" target="_top">http://www.gzip.org</a>
-respectively.</p>
-<p>For something faster and lighter still, you might try Markus F
-X J Oberhumer's <code class="computeroutput">LZO</code> real-time
-compression/decompression library, at 
-<a href="http://www.oberhumer.com/opensource" target="_top">http://www.oberhumer.com/opensource</a>.</p>
-</div>
-<div class="sect1" lang="en">
-<div class="titlepage"><div><div><h2 class="title" style="clear: both">
-<a name="reading"></a>4.5. Further Reading</h2></div></div></div>
-<p><code class="computeroutput">bzip2</code> is not research
-work, in the sense that it doesn't present any new ideas.
-Rather, it's an engineering exercise based on existing
-ideas.</p>
-<p>Four documents describe essentially all the ideas behind
-<code class="computeroutput">bzip2</code>:</p>
-<div class="literallayout"><p>Michael Burrows and D. J. Wheeler:<br>
-  "A block-sorting lossless data compression algorithm"<br>
-   10th May 1994. <br>
-   Digital SRC Research Report 124.<br>
-   ftp://ftp.digital.com/pub/DEC/SRC/research-reports/SRC-124.ps.gz<br>
-   If you have trouble finding it, try searching at the<br>
-   New Zealand Digital Library, http://www.nzdl.org.<br>
-<br>
-Daniel S. Hirschberg and Debra A. LeLewer<br>
-  "Efficient Decoding of Prefix Codes"<br>
-   Communications of the ACM, April 1990, Vol 33, Number 4.<br>
-   You might be able to get an electronic copy of this<br>
-   from the ACM Digital Library.<br>
-<br>
-David J. Wheeler<br>
-   Program bred3.c and accompanying document bred3.ps.<br>
-   This contains the idea behind the multi-table Huffman coding scheme.<br>
-   ftp://ftp.cl.cam.ac.uk/users/djw3/<br>
-<br>
-Jon L. Bentley and Robert Sedgewick<br>
-  "Fast Algorithms for Sorting and Searching Strings"<br>
-   Available from Sedgewick's web page,<br>
-   www.cs.princeton.edu/~rs<br>
-</p></div>
-<p>The following paper gives valuable additional insights into
-the algorithm, but is not immediately the basis of any code used
-in bzip2.</p>
-<div class="literallayout"><p>Peter Fenwick:<br>
-   Block Sorting Text Compression<br>
-   Proceedings of the 19th Australasian Computer Science Conference,<br>
-     Melbourne, Australia.  Jan 31 - Feb 2, 1996.<br>
-   ftp://ftp.cs.auckland.ac.nz/pub/peter-f/ACSC96paper.ps</p></div>
-<p>Kunihiko Sadakane's sorting algorithm, mentioned above, is
-available from:</p>
-<div class="literallayout"><p>http://naomi.is.s.u-tokyo.ac.jp/~sada/papers/Sada98b.ps.gz<br>
-</p></div>
-<p>The Manber-Myers suffix array construction algorithm is
-described in a paper available from:</p>
-<div class="literallayout"><p>http://www.cs.arizona.edu/people/gene/PAPERS/suffix.ps<br>
-</p></div>
-<p>Finally, the following papers document some
-investigations I made into the performance of sorting
-and decompression algorithms:</p>
-<div class="literallayout"><p>Julian Seward<br>
-   On the Performance of BWT Sorting Algorithms<br>
-   Proceedings of the IEEE Data Compression Conference 2000<br>
-     Snowbird, Utah.  28-30 March 2000.<br>
-<br>
-Julian Seward<br>
-   Space-time Tradeoffs in the Inverse B-W Transform<br>
-   Proceedings of the IEEE Data Compression Conference 2001<br>
-     Snowbird, Utah.  27-29 March 2001.<br>
-</p></div>
-</div>
-</div>
-</div></body>
-</html>
diff --git a/Utilities/cmbzip2/manual.pdf b/Utilities/cmbzip2/manual.pdf
deleted file mode 100644
index 10c10de..0000000
--- a/Utilities/cmbzip2/manual.pdf
+++ /dev/null
Binary files differ
diff --git a/Utilities/cmbzip2/manual.ps b/Utilities/cmbzip2/manual.ps
deleted file mode 100644
index b8b610c..0000000
--- a/Utilities/cmbzip2/manual.ps
+++ /dev/null
@@ -1,82900 +0,0 @@
-%!PS-Adobe-3.0
-%%Creator: xpdf/pdftops 3.01
-%%LanguageLevel: 2
-%%DocumentSuppliedResources: (atend)
-%%DocumentMedia: plain 612 792 0 () ()
-%%BoundingBox: 0 0 612 792
-%%Pages: 38
-%%EndComments
-%%BeginDefaults
-%%PageMedia: plain
-%%EndDefaults
-%%BeginProlog
-%%BeginResource: procset xpdf 3.01 0
-/xpdf 75 dict def xpdf begin
-% PDF special state
-/pdfDictSize 15 def
-/pdfSetup {
-  3 1 roll 2 array astore
-  /setpagedevice where {
-    pop 3 dict begin
-      /PageSize exch def
-      /ImagingBBox null def
-      /Policies 1 dict dup begin /PageSize 3 def end def
-      { /Duplex true def } if
-    currentdict end setpagedevice
-  } {
-    pop pop
-  } ifelse
-} def
-/pdfStartPage {
-  pdfDictSize dict begin
-  /pdfFillCS [] def
-  /pdfFillXform {} def
-  /pdfStrokeCS [] def
-  /pdfStrokeXform {} def
-  /pdfFill [0] def
-  /pdfStroke [0] def
-  /pdfFillOP false def
-  /pdfStrokeOP false def
-  /pdfLastFill false def
-  /pdfLastStroke false def
-  /pdfTextMat [1 0 0 1 0 0] def
-  /pdfFontSize 0 def
-  /pdfCharSpacing 0 def
-  /pdfTextRender 0 def
-  /pdfTextRise 0 def
-  /pdfWordSpacing 0 def
-  /pdfHorizScaling 1 def
-  /pdfTextClipPath [] def
-} def
-/pdfEndPage { end } def
-% PDF color state
-/cs { /pdfFillXform exch def dup /pdfFillCS exch def
-      setcolorspace } def
-/CS { /pdfStrokeXform exch def dup /pdfStrokeCS exch def
-      setcolorspace } def
-/sc { pdfLastFill not { pdfFillCS setcolorspace } if
-      dup /pdfFill exch def aload pop pdfFillXform setcolor
-     /pdfLastFill true def /pdfLastStroke false def } def
-/SC { pdfLastStroke not { pdfStrokeCS setcolorspace } if
-      dup /pdfStroke exch def aload pop pdfStrokeXform setcolor
-     /pdfLastStroke true def /pdfLastFill false def } def
-/op { /pdfFillOP exch def
-      pdfLastFill { pdfFillOP setoverprint } if } def
-/OP { /pdfStrokeOP exch def
-      pdfLastStroke { pdfStrokeOP setoverprint } if } def
-/fCol {
-  pdfLastFill not {
-    pdfFillCS setcolorspace
-    pdfFill aload pop pdfFillXform setcolor
-    pdfFillOP setoverprint
-    /pdfLastFill true def /pdfLastStroke false def
-  } if
-} def
-/sCol {
-  pdfLastStroke not {
-    pdfStrokeCS setcolorspace
-    pdfStroke aload pop pdfStrokeXform setcolor
-    pdfStrokeOP setoverprint
-    /pdfLastStroke true def /pdfLastFill false def
-  } if
-} def
-% build a font
-/pdfMakeFont {
-  4 3 roll findfont
-  4 2 roll matrix scale makefont
-  dup length dict begin
-    { 1 index /FID ne { def } { pop pop } ifelse } forall
-    /Encoding exch def
-    currentdict
-  end
-  definefont pop
-} def
-/pdfMakeFont16 {
-  exch findfont
-  dup length dict begin
-    { 1 index /FID ne { def } { pop pop } ifelse } forall
-    /WMode exch def
-    currentdict
-  end
-  definefont pop
-} def
-% graphics state operators
-/q { gsave pdfDictSize dict begin } def
-/Q {
-  end grestore
-  /pdfLastFill where {
-    pop
-    pdfLastFill {
-      pdfFillOP setoverprint
-    } {
-      pdfStrokeOP setoverprint
-    } ifelse
-  } if
-} def
-/cm { concat } def
-/d { setdash } def
-/i { setflat } def
-/j { setlinejoin } def
-/J { setlinecap } def
-/M { setmiterlimit } def
-/w { setlinewidth } def
-% path segment operators
-/m { moveto } def
-/l { lineto } def
-/c { curveto } def
-/re { 4 2 roll moveto 1 index 0 rlineto 0 exch rlineto
-      neg 0 rlineto closepath } def
-/h { closepath } def
-% path painting operators
-/S { sCol stroke } def
-/Sf { fCol stroke } def
-/f { fCol fill } def
-/f* { fCol eofill } def
-% clipping operators
-/W { clip newpath } def
-/W* { eoclip newpath } def
-% text state operators
-/Tc { /pdfCharSpacing exch def } def
-/Tf { dup /pdfFontSize exch def
-      dup pdfHorizScaling mul exch matrix scale
-      pdfTextMat matrix concatmatrix dup 4 0 put dup 5 0 put
-      exch findfont exch makefont setfont } def
-/Tr { /pdfTextRender exch def } def
-/Ts { /pdfTextRise exch def } def
-/Tw { /pdfWordSpacing exch def } def
-/Tz { /pdfHorizScaling exch def } def
-% text positioning operators
-/Td { pdfTextMat transform moveto } def
-/Tm { /pdfTextMat exch def } def
-% text string operators
-/cshow where {
-  pop
-  /cshow2 {
-    dup {
-      pop pop
-      1 string dup 0 3 index put 3 index exec
-    } exch cshow
-    pop pop
-  } def
-}{
-  /cshow2 {
-    currentfont /FontType get 0 eq {
-      0 2 2 index length 1 sub {
-        2 copy get exch 1 add 2 index exch get
-        2 copy exch 256 mul add
-        2 string dup 0 6 5 roll put dup 1 5 4 roll put
-        3 index exec
-      } for
-    } {
-      dup {
-        1 string dup 0 3 index put 3 index exec
-      } forall
-    } ifelse
-    pop pop
-  } def
-} ifelse
-/awcp {
-  exch {
-    false charpath
-    5 index 5 index rmoveto
-    6 index eq { 7 index 7 index rmoveto } if
-  } exch cshow2
-  6 {pop} repeat
-} def
-/Tj {
-  fCol
-  1 index stringwidth pdfTextMat idtransform pop
-  sub 1 index length dup 0 ne { div } { pop pop 0 } ifelse
-  pdfWordSpacing pdfHorizScaling mul 0 pdfTextMat dtransform 32
-  4 3 roll pdfCharSpacing pdfHorizScaling mul add 0
-  pdfTextMat dtransform
-  6 5 roll Tj1
-} def
-/Tj16 {
-  fCol
-  2 index stringwidth pdfTextMat idtransform pop
-  sub exch div
-  pdfWordSpacing pdfHorizScaling mul 0 pdfTextMat dtransform 32
-  4 3 roll pdfCharSpacing pdfHorizScaling mul add 0
-  pdfTextMat dtransform
-  6 5 roll Tj1
-} def
-/Tj16V {
-  fCol
-  2 index stringwidth pdfTextMat idtransform exch pop
-  sub exch div
-  0 pdfWordSpacing pdfTextMat dtransform 32
-  4 3 roll pdfCharSpacing add 0 exch
-  pdfTextMat dtransform
-  6 5 roll Tj1
-} def
-/Tj1 {
-  0 pdfTextRise pdfTextMat dtransform rmoveto
-  currentpoint 8 2 roll
-  pdfTextRender 1 and 0 eq {
-    6 copy awidthshow
-  } if
-  pdfTextRender 3 and dup 1 eq exch 2 eq or {
-    7 index 7 index moveto
-    6 copy
-    currentfont /FontType get 3 eq { fCol } { sCol } ifelse
-    false awcp currentpoint stroke moveto
-  } if
-  pdfTextRender 4 and 0 ne {
-    8 6 roll moveto
-    false awcp
-    /pdfTextClipPath [ pdfTextClipPath aload pop
-      {/moveto cvx}
-      {/lineto cvx}
-      {/curveto cvx}
-      {/closepath cvx}
-    pathforall ] def
-    currentpoint newpath moveto
-  } {
-    8 {pop} repeat
-  } ifelse
-  0 pdfTextRise neg pdfTextMat dtransform rmoveto
-} def
-/TJm { pdfFontSize 0.001 mul mul neg 0
-       pdfTextMat dtransform rmoveto } def
-/TJmV { pdfFontSize 0.001 mul mul neg 0 exch
-        pdfTextMat dtransform rmoveto } def
-/Tclip { pdfTextClipPath cvx exec clip newpath
-         /pdfTextClipPath [] def } def
-% Level 2 image operators
-/pdfImBuf 100 string def
-/pdfIm {
-  image
-  { currentfile pdfImBuf readline
-    not { pop exit } if
-    (%-EOD-) eq { exit } if } loop
-} def
-/pdfImM {
-  fCol imagemask
-  { currentfile pdfImBuf readline
-    not { pop exit } if
-    (%-EOD-) eq { exit } if } loop
-} def
-/pdfImClip {
-  gsave
-  0 2 4 index length 1 sub {
-    dup 4 index exch 2 copy
-    get 5 index div put
-    1 add 3 index exch 2 copy
-    get 3 index div put
-  } for
-  pop pop rectclip
-} def
-/pdfImClipEnd { grestore } def
-% shading operators
-/colordelta {
-  false 0 1 3 index length 1 sub {
-    dup 4 index exch get 3 index 3 2 roll get sub abs 0.004 gt {
-      pop true
-    } if
-  } for
-  exch pop exch pop
-} def
-/funcCol { func n array astore } def
-/funcSH {
-  dup 0 eq {
-    true
-  } {
-    dup 6 eq {
-      false
-    } {
-      4 index 4 index funcCol dup
-      6 index 4 index funcCol dup
-      3 1 roll colordelta 3 1 roll
-      5 index 5 index funcCol dup
-      3 1 roll colordelta 3 1 roll
-      6 index 8 index funcCol dup
-      3 1 roll colordelta 3 1 roll
-      colordelta or or or
-    } ifelse
-  } ifelse
-  {
-    1 add
-    4 index 3 index add 0.5 mul exch 4 index 3 index add 0.5 mul exch
-    6 index 6 index 4 index 4 index 4 index funcSH
-    2 index 6 index 6 index 4 index 4 index funcSH
-    6 index 2 index 4 index 6 index 4 index funcSH
-    5 3 roll 3 2 roll funcSH pop pop
-  } {
-    pop 3 index 2 index add 0.5 mul 3 index  2 index add 0.5 mul
-    funcCol sc
-    dup 4 index exch mat transform m
-    3 index 3 index mat transform l
-    1 index 3 index mat transform l
-    mat transform l pop pop h f*
-  } ifelse
-} def
-/axialCol {
-  dup 0 lt {
-    pop t0
-  } {
-    dup 1 gt {
-      pop t1
-    } {
-      dt mul t0 add
-    } ifelse
-  } ifelse
-  func n array astore
-} def
-/axialSH {
-  dup 0 eq {
-    true
-  } {
-    dup 8 eq {
-      false
-    } {
-      2 index axialCol 2 index axialCol colordelta
-    } ifelse
-  } ifelse
-  {
-    1 add 3 1 roll 2 copy add 0.5 mul
-    dup 4 3 roll exch 4 index axialSH
-    exch 3 2 roll axialSH
-  } {
-    pop 2 copy add 0.5 mul axialCol sc
-    exch dup dx mul x0 add exch dy mul y0 add
-    3 2 roll dup dx mul x0 add exch dy mul y0 add
-    dx abs dy abs ge {
-      2 copy yMin sub dy mul dx div add yMin m
-      yMax sub dy mul dx div add yMax l
-      2 copy yMax sub dy mul dx div add yMax l
-      yMin sub dy mul dx div add yMin l
-      h f*
-    } {
-      exch 2 copy xMin sub dx mul dy div add xMin exch m
-      xMax sub dx mul dy div add xMax exch l
-      exch 2 copy xMax sub dx mul dy div add xMax exch l
-      xMin sub dx mul dy div add xMin exch l
-      h f*
-    } ifelse
-  } ifelse
-} def
-/radialCol {
-  dup t0 lt {
-    pop t0
-  } {
-    dup t1 gt {
-      pop t1
-    } if
-  } ifelse
-  func n array astore
-} def
-/radialSH {
-  dup 0 eq {
-    true
-  } {
-    dup 8 eq {
-      false
-    } {
-      2 index dt mul t0 add radialCol
-      2 index dt mul t0 add radialCol colordelta
-    } ifelse
-  } ifelse
-  {
-    1 add 3 1 roll 2 copy add 0.5 mul
-    dup 4 3 roll exch 4 index radialSH
-    exch 3 2 roll radialSH
-  } {
-    pop 2 copy add 0.5 mul dt mul t0 add axialCol sc
-    exch dup dx mul x0 add exch dup dy mul y0 add exch dr mul r0 add
-    0 360 arc h
-    dup dx mul x0 add exch dup dy mul y0 add exch dr mul r0 add
-    0 360 arc h f*
-  } ifelse
-} def
-end
-%%EndResource
-%%EndProlog
-%%BeginSetup
-xpdf begin
-%%BeginResource: font DTUUHP+NimbusSanL-Bold
-%!PS-AdobeFont-1.0: NimbusSanL-Bold 1.05
-%%CreationDate: Wed Dec 22 1999
-% Copyright (URW)++,Copyright 1999 by (URW)++ Design & Development
-% (URW)++,Copyright 1999 by (URW)++ Design & Development
-% See the file COPYING (GNU General Public License) for license conditions.
-% As a special exception, permission is granted to include this font
-% program in a Postscript or PDF file that consists of a document that
-% contains text to be displayed or printed using this font, regardless
-% of the conditions or license applying to the document itself.
-12 dict begin
-/FontInfo 10 dict dup begin
-/version (1.05) readonly def
-/Notice ((URW)++,Copyright 1999 by (URW)++ Design & Development. See the file COPYING (GNU General Public License) for license conditions. As a special exception, permission is granted to include this font program in a Postscript or PDF file that consists of a document that contains text to be displayed or printed using this font, regardless of the conditions or license applying to the document itself.) readonly def
-/Copyright (Copyright (URW)++,Copyright 1999 by (URW)++ Design & Development) readonly def
-/FullName (Nimbus Sans L Bold) readonly def
-/FamilyName (Nimbus Sans L) readonly def
-/Weight (Bold) readonly def
-/ItalicAngle 0.0 def
-/isFixedPitch false def
-/UnderlinePosition -155 def
-/UnderlineThickness 69 def
-end readonly def
-/FontName /DTUUHP+NimbusSanL-Bold def
-/PaintType 0 def
-/WMode 0 def
-/FontBBox {-173 -307 1003 949} readonly def
-/FontType 1 def
-/FontMatrix [0.001 0.0 0.0 0.001 0.0 0.0] readonly def
-/Encoding StandardEncoding def
-currentdict end
-currentfile eexec
-d9d66f633b846a989b9974b0179fc6cc445bc2c03103c68570a7b354a4a280ae
-6fbf7f9888e039ab60fcaf852eb4ce3afeb979d5ea70fde44a2ae5c8c0166c27
-bf9665eea11c7d2329c1a211dd26bb372be5822f5ea70d99eb578c7befd44cdf
-045a363056e5e1cc51525ea6fc061dcebb337208eff729802376a2801424f670
-0e7e6397b28f15bc10b40012b0a3eaeb2693e8f7f627c4c9c7c6c5bff105c1e4
-1b2b9e8f09253b76040d268b80719e1b3f5a55ab7b8d62a63193c4ae94c086c1
-552833ddd8f116b5df33205ae709b3aa63da7bebb165b67281827b48fb5edbed
-02a1a5c0784fc57d3487daa59520bada1be3fb9795669924321ce4f466cd8e3f
-7e8ec2494aee80e2dd7a48a6861af5b9f0ccaa4a2fe2b03498eacacd6b9c39c6
-a8f2e39e06bbb061cf2ec380a32efad0b790974bb5cc3daf0992471456967362
-77de34813f27abe99302f86bb4d293a37f84667e7f3dfee4cfe9d1a676a5728c
-aeb5222ff50da97e74b2cdebf725fbca7015a188891c8a376b9dd8a642c4b184
-b1bbf3f376a6d6e31ef1c8354ddf8039cb20faabcb34d4749b3c8c8d6972ceb1
-06b8a5aae3ae40a91f1f2b1155681a9cc933f87528c99a2b0268b43a3e829e7f
-3bd863cb52950773bd9b0731dc4992541d7de7a055ca65ddd2317f1705c20d1f
-93291bcc254cbaba425c032b3b15050d41da14ffe1b3d684eea428095a01e931
-98d4f849b239ad9d79f4502f0271affb0c297f2f347bfb9c137782646f648f77
-0076b85f5a929fcdea2703333f6918b8f125627f8b505c688e30f258ded1aecf
-2c86edcd88c29249a8081731737195fab7adbb54743bd66511194dee2516959b
-a20701e2d97342248297425491f6c9471ec9a98e630d734dac19721f0b324432
-c8d7a0b751453f89f7008ba37bc48e0831ee3ecbd8a0a292d63cfc890b28f695
-9e29ac3b4ddb78a6883b9272ce34a012a82adec0b6b641e3940a438a098ccfbf
-c50544b94facfd9d7ae09ad0632015f81d2f77fc6d80a42ec11d67d8a91c376c
-13c8e3444cdfde4d2a1ed021410f4d6a4e97804ae949bd913094d23108c9d384
-56f11025e2d24939114b6bcf579a0315c52f3ca1bcc2860fc1a0b9fb8a37ae2f
-c20c0fd44d215fc2af737fd0339b070d54e664021240071c665de4170dfa182d
-4e385685fb41a2d85888b1149e9a766cb4f309b4e2baa28cf1f8cc12c4b19e33
-f046ce97b53deb549fea96cf6ce66357c4904b7932f5b1ce03cfe3a10c976b9c
-c9ad11d7a02816f8e11666ca8b3ee1411df2ca94172659bad929e3e3e5248f48
-0690cec6d8f7061608cf2672f65abdc96b4fca84d5c847440cf9523d3bf23f6b
-d4365582e4b187b6a1a0282ed323bf221edd0a4ce11ce7eda738d1af48b2e19f
-eb3da1664de99c447c35dfd45069fded1fcd70b4a6855e91ffbd7146efe88012
-0bff1d6d1acb53d5e07fb5795f561a4a3e953bba7c03a9762adae18e58dce6b3
-b1a703122ef3b16963ac7cb9682ce60e17947e7e675d19901c7e8272ce4c9fdf
-536abdffa429b820a82aee9a73d7dcf77dde4d8e251cb3b3a5b0a91c0fcd7fbb
-ead7a812ff194fd049f28b82f4c2d73e41cc73c1c9f668931a2c7eba5400a1b9
-0902efe6792f207136e1e16b41794e6cbf7316889a602d35c37ef36dec95af26
-e9bb0900456f2ebf2705ecce7b2ed90343d23e006ecb282d4b3629bb0c3892f3
-ff9c17fe6c5fab68358e1cd44aff021948ac9fb8410a3de22e0a01e367c52470
-2a8cfd284cf9e8f505d5dbd7bbe242fe071fea0094a55ed1cd7c9be6b7c56c98
-16ad1985fb7624f5e48cf6c0c2ed85b466f64c52f017b20cdabb85d24452e086
-3942362e764a2bda0f6c1b24426e302ddc4403a087efb2850cf3275c7b24275a
-ae270f212831f4c4a5d95deab61923ca126e587e8f5ed4f2d5738f06e8c4f911
-b346b8ecdac481dedd2f546305a7cd63cb67d40093c618fbbdf498c8d7ead8c7
-1f5f022d0bbcfaa8670e3b3b999a1697c947af38d7e1a360e3f0825a9aa77840
-d7a9dfd575ce2f04d308f7c553ebf569ac84f2c12aa0869ce107c713a3cce624
-5059bfb3f5aa27d10e337086144ab09286be3825a3482c5422454c6a9cbbf205
-833316780eb88302796fc427a0fb9e53a7bf24577feb3fa5d85cb6344f908007
-183522d3c760c11fc7da8d14bb5dd800576a6b4d1b991c1bf3db0f9ca2ac5d22
-91079a199f2f6e6dc68213d33ea893b74f6aff30ed1b51f8b53a015ffd4d2076
-b71f73225b151cfcf11e2a2917cf1b3f60e2b4d442307c394e1625f7e60eb12a
-f2eb9ca7b17b082f1664d09cb7a3f38aea99a13f659089426126f47fad5b6dc7
-64101cd437da3c22bc43e7a8de07253eb371470ee1e4e42a5d1fa2c4db5565ad
-79d6271ae28e8fde5d4cb24064c145de44ed486a1e7df2df921f2b1be5fdb120
-d8b781c3655ea72dc22a2a2d37579f0af60b42320ab25c8d769124352448a154
-7a381b388a4d9a54e82f199ba35f1a3981823ab698e3f87d38d32addd4f13832
-77fcc9acee7fbd3285f689a85b76d0feb9e70f09bad0ce144770a6cc203ce40e
-15912de0e3465dbc7918e3ea49ade57ee8c48c75937f5d25498c45170693067e
-6902937c9b43ab6080111663d5dc6d88f72a39c5e7bad677229498323a3e7a22
-2fe2552b00cb91ce2848a1a53538b7af2503a3671903e10df0e9641dbb70577a
-e828dd3cae98fa9e1a74f4377f908d3cd79461408ed29832bc4c9865550ccb00
-45359282255057a4bd4859915cf1e45ecdb7329f90bbf63e0a22a54b05c5acd1
-9c7c4dfc25482a27a20c7ab908546c3577e87ade93ea46436314a0a7c524b892
-4b012239e77cd65ae2949bbf7e46a5a2269b7ffb1cf8a5bc7eea1944d2b0bf37
-bfc36adad9a599fa133f77935f24ef518819d054345df144731dd2332b0f7f5e
-84c46af486941cf1293e86ee719c9bab6263470c7009c3933f1857b0a863e36c
-288d37e6ac85e6a1b4e6e91c0a9fe367bec427ea3713e8d1f0523ecff6067717
-244ca21c177968583815f023420a660f7aa4cdc8bf25ac3b3e429942b9f5123d
-84234c186d9226487c76dfef5d26165771c0e75f0ace7e3882e49de831b46c12
-e30dc37395241d7619c05abc40f5a36f8042b461fb6c3a5181f77b14e9e6d978
-37356b4b31fac3850df1869063724316104c799b6a2f42c361a375e4d29eba7f
-850fe29efbc2cef627a25db549a4d4c48f9fc9a2f32fa50c1ce6b5a545a95f7e
-bf2e9ed710ae91ace1281a44e49aee4133ccc04926a6dba24b721c21188c89a5
-2a49745501cfaa4364cf49e3ec2a59d9ee46f33362634f9758827b199fd07dba
-939bd7387124656831862f70a97c5a05959572c74865f5902e95093fecdbea3b
-bba9b47dace807262de0c7ef04843259f58a323471237cd573298c5d0a0650ad
-2acabd71cb44c63675192845e3d01b3b28af871f347d4a460cc28d9e94409443
-30e893d27b06132063ab727a38f447a2a4633d29adac01bdccc7634e64dfdc55
-9141f69e1202c4a0fd48479b0ed95a7605c94901373e1100a6cbfc113fcce445
-e0317cc94a8507dd637c37676954b9d34c6727aacf17285876db16dd0e11384c
-2b996e85e82fd8fd2b8f9b83bccb398b997364f0ddb71e60ccc50cdd5d122eec
-c36b86a89fbbb5bfb227fba3a7b7de7c907e58780fc276c24ff066982691a97a
-50d14362d27d790375a47162decc53c5c11e8a7499788dfd86aefffe7e674aed
-26706e2d079e9a571c6a32accc8c0dcf23508f58477d05f9a1fc679c0da64254
-27ae33293d02c9eca01daf2d0a1b07e5515d36e18caa3ab1b6c5736dfdefe384
-dbcd244f0c11087a873c4501c6de2a5a57e346fd3f92a0451e63fff6b99c6dfc
-64ed8673dc54ef6509d0d043925bce39072fc64ddf2c49b8602d1a51ee822f19
-d7b2135aa84626bfe3ff321a6bec3a003ad97e7699cfa34bf41f9c2b38df4794
-cb5ae36c95f42b44212de67a96ca9d047587998636673a031c4eb03cf1a55326
-f5d94dde75086b44f095ede0068fb6b9d256759041cda04ecacbd8d7784159af
-ae31a9c637d9a5c0c6840dd9e30eacc66d4d6fd6f12a603aa2db3e9866693070
-0d69cddc416d4b76cf6b835c7bebf914816b87edcd5a24e346eba2dded30f5a0
-dc033e93b040a6ee7f8ab3c44c61017c758c11c2e2fe3c4f18996287a48fa9f8
-fd068c42d0d3384ff27c5a88ef630125562663ee95a66b7b588b417b20d3ae84
-6ecf2693940d4733f9e70b0455b6097e73553eed34df8da712c29d76326670b7
-13f19d4b5ada1833d46fd6cfb92b85eb946cc74252718cc5e605cd6c3c5a46e8
-51536cddcc3cb244c78e629fab784fd76372ca9417fa67f292a7e780b78186d7
-f391cd91b6222e88c0bcff66208814965511967b2ed0d075c77b57701608b647
-b4e462d3e56e06c0403f858582a754dcbf8841fe81d39359d8c5a77c8ae6b795
-c11b84f702de09f22498a189a4c69d726a63260784066562a50544e5d07aebb5
-8265c1c6607bfc6008f2edfc9d0de71646548e59bb374996a4412ac22ab47dc8
-357153c7c9061e95952a729a80fb45f3650fb0c84a07c1956dcc0856d7b0fa71
-3f09c1b995b0c48c57c9367c0601a46cdaefd0460735682d5aafe8545cba587b
-ca6e8144ff14a25b2fce9b23d8ebf715c5a544bd646d5460d2f8cbd44b6d8203
-54e4b7377db351ff26b7b9336a7dca3a610d3a92541054c544064447ac6d1a15
-cf1d1a3797cfe85fb55b56ac01fbb6f47e9c8e5c2929bdc7ee14f6d868464493
-df4759cc80405ef270a816607f248c5c1d5c56035a8ffc1fc1b5f69aabe2f964
-cba4c0ed5416a20f102c82bdfe59ddb4a16140c85d55af2aa52c92ee85c37881
-9c95865704b3cc39da6270dfaca8c3611edbb6da767bb50a03d6a06ed9890104
-da2a575ea45e16da2e1fdcd603c91af6beb934ea33023152c25c27c3c771b553
-1a9aa1ae684e1539e549972c97321fa0710759b6d4b9e55ef1b41bda01d77786
-87c22cb79310a9000bade74a8ac97b3eb2ff024bfd60c0ad7fdedb23c805f64e
-fd139e015e0d1d3591be5930c356e6b8c1a4f0ad9af94eded4ee9aaa436d4cf9
-58c5897d06b7c97cdec22745c46e7b37695a8c66140f7f8421138892f4851c3f
-d355b1de1d32145d39243d0590a90f1c4ec2c246d3f3779b319c38d4221576be
-fd17d8bc8819cf8ec30075305f8637d1ddf0f7255ad456cc290f10ec39ddc2f5
-290092718e7d268531aaeb377701dafa933b94ce763c1954ef0cce19d77c9208
-157c38b279c578c56b7e523afccc91fe6819483de18ceebbe74b81844ddb84c6
-22d4f29661e89e5417ce43c28028e9e1c54063afd716088b6e8fe0cd1702c2c3
-31273573f5c3d760c8a2c7cbb362ed650ea8ff54f19e097f14af9739885af15b
-46ed31cdef73db671b22efd41ff3f6bbd29625fae7571f9542fc06c77e28d2f6
-3ba2c9cf89da564de3a6fb3f0ff981c5c482a1e1de730041b7f1c890c4528bf1
-8e79f2fa4ed8a738f09a68a5b53edf6cbcf8861003917a89989146af7ab2e5a2
-836279643900c27a90463679a22f0ca5077728f6ae8a28324f9adcc19fa493b5
-e2465c6d98cb608f8dc52cdd6c52bad1a1502779b638df9336e12f035b3c310c
-b92b3add047365f2d25b0ec7e05cc46f31c0575eaf4ebea0b660aa20d9e7edf9
-0aa077e3000e25176038ccc92d4f9fdbae6b05aa2e17ad004e13308464a20cdd
-0271ed0f964e73cb11f18c2b795dba31c3ffd5648c63dab395238ba7c0cc7db6
-b206e6179c6ad7c2534c46a2b9c1d7fe6bc693df35118b708933677ab3a76cee
-9ac0303c2c0967d718a1691f6a922abb6b37625fc01908c10242731b79a1a82c
-fce9efbd1c6bd483fd867bc2938609ee52c0271a7ed1fde1b8667b98e22fd450
-86f515fd2ac2c11c50fce95f3e506ac6518dd4e532ddb100d87a9240bdcdafc2
-0c8bec467d76261165e9d8bdac9197ec798c81cfe80e3619f432674cadf44ff4
-3f61089abeb13d665e7901f4a1ba84115333210009d55e051b692aebee9d9bf3
-d0219c290191c17f7317aaf402b88ba353c25f126e2d32bef73d528c65af0840
-3ed4086daff574762531794fdbf637b765273911297b75338691e9ef4d2ad452
-22454c6a9cbbf205039d6d35c09a0ce284e9a776773a98e09e6a816dd71d80c3
-d80abcb006353b4b7c48c76bd9c1ed9db78bf62e9ad2222e5bee9fde0281f0e6
-11fd6f899938cee729a184be7cbdb0b84fc9c380d6c69cdd6e0f3f6780af684b
-cec6361673853b400f47e00177ff1ee7f9eb8c285a49e137e08d5d7663df71ab
-71ca71adc0857055686a04777a2e1408ce629e018c97524af5588991be92e4fa
-4a27745aa950a72d479c48d6f8c30d4258a882f199b4359f92a963fc650230c5
-79edf743f2cfe86a197296dd675bf05f25ed969de77bfdd0b518cbb5c30b4e42
-27c5117f235b34f7fc32413a980a38968ff9b8151280a0259214790e421d0f39
-eeebe98adba820401c2d47d4132cc68cae0f59b049d7489f62259bfc55091c81
-89e2480dcb77f689965151b7f6706af675a871370d2195b07457af8809f7abfe
-7d3672d76a74f55ec749ef40f755a3eed96cce000644ca0c497afaab7294afdc
-13c3239f54f3eeee809bcd936ff447277d2f3613936e7b39e683f25b60505f2b
-f4343ed0902badeb62495cef53789b9e74baf866be33efe66c1c5faa95f60ac9
-156a26bb9f72cb73e891ee4b905f72845b3ae05e025879f07a7b91fd06204148
-60832d64b6bd5abe0472aa7aff07fa05d23a01238b6f624ae8db25bb71ddd893
-1fc6003f23292a428a5a99df5861e0ae858c398d66d027a32a71d6e62d62b6a1
-a1db86b1ea3005a201618f22899cb1e7d70f65fdcfbf7962ee0d0d15412d006c
-cfebd0e0892888f26238bd1f7f090de03c41ee4ba53548f469fda2d94f6b3da8
-a606fcc3554e3f261b8490a3b8cde3ee846542668ce3b371318f9864c45a4223
-fa2a86e12034bba867c4abeb461c609c8d47e184703bd6c891f39076ee06bfd3
-bffa679de07d8c8eed9b4b24ff74c6db2cf84108f28e4f0fdb78e0e726a9bd3f
-2a1b94daee18fd20f2c902cbeba13c1b281d0a11a96b20800e4cf939dd32bda8
-25aa63d9f86f380af4dd379d80441dc4fbc0719a69ebc16e1617940a19eb0b44
-96581982d45b08e512000e3915490a1a79b908e1e63ae129750fa45dd33c0e9e
-2e767a89c6f11e33f193da18dc6c820dbed8d370492c19ad9d6407e50cb62446
-d3ab009d9e8f3c51eac2139ab64ffa19b70405813652fbbe33fbe5bc95d40b5f
-9ef833a4b1b51e56065abfef1036eeab8e04f096aac0d2813c2e721e0db97368
-c17f0cc971c9ca18a2db11745f67d42ce5148e2e8b2c0e13e4bb16a2789f0c4c
-e7b65be454ea623212bb2ce5afc6b5b3ad5bfed65063354becbc1531389977e4
-6599896d9ddbdf3ad6fdd8a44b14ec8cc9f131d73cba91e28cb54b37655e4b44
-db0457ae7bfd3c6b73bacf09861a7fe4b664928230fa03cb99ebb763703ff8d2
-68877c3a3b1cf915891578aec60c1f7d1e447fc777d8eb3573ba2a9ce47c99ca
-a9d52f2f12b101fe48658edc7543ef85dfe01b72dc4dda597951ea4298fd444a
-ee33b14ff2f91b7297922daa7e346493080868f56aaa2176c9f2c1284e4b2672
-a3b75face39df1c8b7a825a3a5c25871d190e48574e1d03a5fb094d418c47ac1
-687e8347036cc44fed3d84fe5d4b84a61fac9968b8d004c28539a3681476ac45
-56538901ff2764c1c46f5ffe048cd3a7eafc6a9fe98ff9b3cfdf3ac035a9d3f6
-8d75440d43a1842cc1e8b6b9b6d49a9bd093620735c9c7c11c21652a5262a86f
-c10413a373a9e02a488bd9a16a51fb51b027b2c5cde35cb1aed91ce58703e1e9
-ebdc1a161d754ee437412182f7d532426841e2455add22c031a2171426881bbe
-4090d1cbfc498ef46749308b73ebf4dc5a06adde6f83bfb368388bf7c2d900cf
-57932ba4c9db0f15faff7cbd701050a1db98bdc9a5f9f428980ecfb1e999f460
-231e59b5c62c7879278f10f6a61f79cc9da24d35a2d26996d8a4a106e081b8c8
-3fcc015b775acb00f78953a834018c146c65cd715bfb5f90c03feac01839c6ba
-156e327c97350d2851dd77e8263b967742472dc1e3b8f0e980de9f1815007cea
-51619d84375b777d5cf32a144affd8ef0f4fee2df1f839b2a5d900ec8e76363d
-c829f1d03d211175ab982226616b19c51800e4b5d4b28aba82980eaac6131940
-026e3c2297e197fb8f130fb15d2c4098b97c84074d4e50b5c6606bb0f3230931
-52b39a58964b4ca44caf45f63af49b330ab3dd863f5ebfa8ab0db6cc37838a64
-72c601c215037e94ac89420fea13d52174ed5c933e8c8525f88e6ce482661861
-58b904ba7fdb864cfe04bd7ce6070fc5ef576b1de985a8c4eeca7fe32b90d320
-9091d8931bc21c6f969288b1cab44bc53755d8d8f257466803dfd5725dbb5830
-4be6c784fb6f8c5e66802028759c0597246fc103eb63b58f361b144668713570
-8c6be071b51fde425a0aa5724986ca67e87eacb8f517fb3103e52595ba002e02
-82e54cb82b04c993d991d70b5eaac7a639213ec0f82a1d7750f3f6e94d8ac7a0
-8a586b816a9fbe78ff96bf1e3cd52798089f279a0a0d93e0314883988bba0f78
-7ce5745f8b07eb3b750c1d0a13fa4b0338346220ff9ff10cfe04f29e2c24aef0
-f77f6748b63b0c6d53461536034450820c73116cc66feb9c7f7d08e0a47d4c92
-ec61c5342099c27d93a79d9c9f278142ba03b51d6e1e03944abe063baac32629
-1b5dc30de8512f0cb3a973cc43afc2be532ed012c3eb58266cbeebf611f91aa1
-489d0174e713b976f3a0b36c575df597a3d8b12d4c5441e3a478f0933eb129ea
-e44484e084bdde7d2d9ba23a6bf1bbdd51d96ba4a5207af1044e917186b7e66d
-accde1295b615f37f1395827e29e3a1711fb2b6c50374df468be421cc531eae4
-b3cd2473c979d11c11beaf14aa9b6cce4acc8208f22f9fbb6713bb8306e5b5a4
-d46d11e604114d9a5a4be0615a843d10de54ad62d582302fffcfab7f785b11c4
-83081286cfa04302f7b92f64dbb42f3f97cde0c047662be6a3e58986c54b7c3e
-2ac1b0d19bc1490311150931aed3497abaa74303d3f0a3f3af8667c4b0b91385
-cdc9bd2ae98ac32a2d943e0583a0f3c74fcb803559fea211098b48385d3d8d32
-9e2cda61d7589e5383fa32abfcac50355549f1e819eb31531dadc47f5e759790
-d355444f1efa6b1dfc7713d446008225808fffbdc81a3b1b374c7f2901e27e2c
-41c477de0e52e9005288b7175117b32c326b3ad2b9f9342865d0bdd0ba6044ac
-395c2c69bf82a7aa9b77842a3bc7b4a675b0c32a4e4504d2a9fe8762170f54c3
-4dc3620cdea9d1877f274559ac6d37aa83f90346130472775858c18746db4558
-4f2fa7698926c4fb2eef0951579dae63c2d3c7b9e1fc811ee5dda4dc5b5e61fd
-c0ed21724902532087dbef11b1fd0d71eca9f271a3d1bf8ded5df19db6761547
-97d0a12f94147d64bade52704f880d0fcb89f4958547c6839c9e111892797f29
-4e65f7a54e14ea3d3f50712979f84852e57b9c1d70474a3593d53f21603e00e0
-e79ff355914f9a3d4ab1e14410eac9926928e714248535b178d6fe9e0e84ce99
-59f66fb52f37a4e3dfa5488b76d9ae2f62d4495bca11cc148dc20e29a694fabd
-e65c7629ebc40ff0c0fa109631655d3ef9848e16aa7c73cfd4aed02f8f125ab5
-0d628ce52fcae577c7ef0ab688a2f4fa9a0e2a9b10b93130f0b357f4679c1f7c
-9bd270f34f0bfd86459b402c74224a621dfad6ed316d05e15d31707fae7a9b62
-f8f75537326742f1e9d0c7483489f4f4fa38e0f327f24fbfb26307ead2720bd9
-678f45875eb05036341ba38660630b7d005304d4388ff7eb3be9c2635c21af0a
-02d12fd19a4e52181a9c7f2356b2a16eae4e8ed5b1ea0c01565c26856787fdfc
-2aaaf11958ff3414ab62ca19e947db6b78030e2c528f3d1c0215cadbb0c34f72
-6751da03c604bae7b97f379864bb54be9799bd387e88d6c7053f83dbae1cfb04
-f2ac87d12dcbe17a5183780fab4589e8b0d70934e856f11629a91e6d13da7704
-73cc80e0b80bdd42a71eee5f43a4dab994ee7cfeff83d08169aa298c98a85477
-dfc729ed6db098b4ae47a25b8ae7587b8cb2d59cc0989c06129fc201e7c9b763
-f8b3f651a5c735edc975cec4ce461e81ac9d5e3b08a708fc536b46b9566a58c3
-0402aafd2b6018dd063877b880f85e09895dd4c9d89b5f264ad72cbea438c153
-054e1a5ece2091e1d4105f46b047b75ff3be86491e694c1e2e03bff36812d148
-d9923f5d89a28fbc4f45fbc3db74cc37bf3cf41b070d72a4cd571524fa6df788
-3153e77818641287ae22b1c72331fbff019ccecbc1709615ad749dc77cb6b331
-30ca3d0fa05cc47447c17d96cf6ded782ff6b505193915aebe31f1f7b95dc9fd
-91a124f9551224117174ae1e05754dedcec813a8aa4934b73de1b20d7c10a20d
-83a8b085cc2d431b87397e5f8286c0a80704101475ec9845b2bf7ecb9ae457fd
-abad09e4e8ee411d4a20518597b08d5dd66afebba03f632ff2ed520270893f00
-35cf0716f4a092faf8a0c2a3f73ca46afd2a825eee041bbc2b649330fe821807
-707a06ed91847b434d34742844947d54e80422f5b5b56f6dbda934089c32ad12
-375b31af9aa91329c253fafd3cff4858c39ae5efbed4d590819d2f5963b7e08a
-99e157ca1c18b20c62a8f7bd278f560e871b6126d9cdcec52c6839417bc70dd2
-49fa373ca6dd557540906729f2fc5476c38595d958ab2b6c14629f9e16a2a9ce
-9f6e2dd760e55a38a3432e74126135364cec00a7b6dbf0cd48555df9f31e71aa
-9d573bb077085030aa3146d0693fe683884ab380f052c38b31b0e3483d122c4d
-d15a6a93eafec3523f4b2744935de9d1660fb4d8a76d82045862b59ea2183961
-f9868bf03e4a71db61e03fae93bea1092ac5ec83d71dad123d5663149d4bd0be
-e643435aabc919942bbc60d4ab56ecdecad30d270589775a3ff718cef0e2ea46
-b8c75fa911752ef13410185e5cea25aee6fae74489355d3328e0cbe8d4c55d46
-4114b4a4c85309dff4f2a5c2b14fc4f4779f4e3a8bd29076baec35cd59ecadca
-09e93d8dd4786052d970484ea3cb45b37c4a6f74249e9f5eb7583b018dcdabfe
-67259769ae1a904f20b3ef352cd191bbed998f4b2c06465d7355e82ffa718e08
-9dfa5c8fdaac95d8e05cf8b5a899b8484c5ea104eef3e5b21436ed396662222c
-8cfd00b5a854ba9338da205f16e5c0f451bc1c6cf34f0da069af5ccfb460cccb
-b6f393a99f6138e0ece299e0c0f7f1d0c83e0b936cac2dc38f08292245e7afdc
-6538c4fecc7d712ef83997088f73ae6ff0ab83d0ae76a7811cc07b41a57d1d34
-04681526d327b489094dd961f2f60a0c6c275f09f0a171e88056f58735d2f502
-65a167d12ff3395df58c3b901a68f0d96f8ef54ac5548086229adac495fbc256
-afe832991f1839aeddf1a87abc217835e58af4199823165fb9899fc831b47bfe
-4c3c1f5a2696e9a5f310afb8138eea06fda0688e0d0d7cd1ceff93a72c57289d
-332525c3bc60e51ab25526a4876affb2c64657caf14b34fca46a78e41b0c1955
-01fa1a0c0d77d5f7026234af489b316872e64b4d449efc540fb0da553063a71b
-d8ee44b0f9a20adb9f60b99803f1760c0cde357784e87042133aa085e9a37a5b
-b5685e73354ca0e9a48d886fd12841674bc0713d43301883f1c2f6190b47a4b9
-996c0e528b6572c96232ecbc57c57073463ae36b5b2974163cff75828a20c47f
-926e99faab51f19fdbe0f89bb71ffba9eb95a82b3a712b54578f665a89edf193
-d575ed95bb883f9d6797029ff0cc8a75459fac0cca4530e17d93c9834a8d9c9b
-376d3e40f3e44e6e895f25c90a803cf8b0f3056037809e3ed618475c199f43cb
-a7eeff84d38f49aafa4e469aa78cddb87ea76a87da1b888c38e225499d1bb089
-32d599918227c97b1e4de521460f1a175ff2fc500bb95574d9eac64cd00896f6
-27589fe5351f46a46d1fe8ae16fdc945decb08c0b7d841c5516535ab65b84724
-04796bd7b7083a606977316dffaeec0e8681c10df4deef6335403e5b08889558
-48bfb1b8708a5c41c5147fbed3942ac26ce66357c4904b79147dca55f039b648
-ae18d0d6d330a621301e3c1d6e478fc6fcee4c3382d463491a167596ff51f17d
-1afdd4ee7ab8f1b27b4ef2b665cb6818637b5e982447f6d7ab2806f769d254f9
-f5981812a9458a39f51366773a8980c7c6dced448d878af3bc088237815d2727
-40093cb7c3a4e6e86ec6cd61fa8ad13b20e270f97ee5be1799f2966a0ca2a7c9
-32de08bb021adf9466f1b88ffef315b818954057877d3d59f173c1b1874fffdd
-e3749a0dba7d62d70483b1a7c7720c1e95c59faeed0c8be1913177c6dbaa6905
-a6bd1a153906aa1b6919ebd1befb9a54d9b84cd9d548b1abe83933670ea719b8
-6337d01283b95306db92fe059da52d107ec47819bd163b3830c989df4052614a
-9866b057aeaed455fc9864df1960e97806cf95011394e2052861152024969836
-77be8008c246f14aea1c26e620fb331f96cd32a23b1c87d534d678181a198758
-4bffe069fb5a0c6b63ca8a9cfb6c3fd6ecf07c5bc59712ec7d02a5b988c3fbbf
-695fc7068a644d8885ccd88987532539e5cefc64fb97ec1376ef0a97970db510
-4c19b7a64a1b4f7eedfec2515996238dadbbfa8afd8004f12867de20912c2774
-1ceca6f2956b340ccb5e30f2b1f5f6376e6d3a272be05c29125f6d74bbee7879
-8836ee673971ab724dc89867d5a939da0cb41678fbb8d8ed35efa28de86728f7
-953c9c5896b867e4b7df3322563aff8a31cca8901b5542af2c7254547c7c09d0
-15baa7cbdc7352960ac650a543f05e290341d245ddd331a556ac7fc0ee7eb246
-718b71073b9a32776f6215fd8fa2297a2e9be23728cbb24c53ea10a4544ddfb5
-7d6292640840c77bf03728c3e5d2665ed7db7410c9ecb32c249a45664f72f8f4
-2e81a2e086b535f6473b1a3319d134317edbd1864cba7b79f89ef99d16c8871a
-28fbc4cb45f982bac6de81ef637a7e1022a5579f73867e40e31ec8903632e33f
-b24abe53b1f3a3097779b977bbeb41c21857909d3e25f7bc88e6d3fe6f183da0
-0133a99ae39080012df8498b9ce322ea9b76343c2e8be3676f08602470da2761
-ed9de407fba38be82de624e1552be40a0e10b55ad74367b91c80b8bc5cf59f64
-b79072369d9e492ee6b9f9df0b91ae608a44020ed6874038974ccc9afa88d6b7
-8114af4de09e77e4b0a1a1fb27e226a62385b969bbebb657ea927fd86e050ff1
-3ebd001a022333f8caca13c54f9b345cd5b6553c90b4f7fb949d7d65d9bf9fd9
-46a3c7c531f6a6479aab0d5a7015b56959777892feea7990edbd2b423f6e9ce4
-583caac124c268628a9cb703dd96aacd35b1031e08a741d02adfd579267df790
-5ef26af14b2bbdc22a1eb33b58719a1e8463f28784f4c15cb3c25cfb2e20a508
-7854a53f4ab398b02177de500a049d6c9faa13fd40c19178e878f1cc26221c59
-b40545f5f4442abba06656ead5afd938adeb3ea50c699862d48e767c223c1f22
-246e58c5694d1e23511710817a9fd18a1620cc651345e6d3302d85139f7a5734
-7e423be145e165baf46019fe831f97602ec87b3cdfb8fea12869c98f115d1b66
-5aa588fa82484acded7ca2c13a17bda305f63ee226ee1f37cf247f1aea9ff92e
-2fa4c1e0448a5dde45294699a9490a5ea94cf81c53491fc19e2ade5af005c300
-a5fc99b893ed1d469788e94de823006f8848dc9d021f19b934278d44e8c73da9
-3728f389563e10ae6017c5caf3b4b340be1d7d2b7f24a8cfcc1ed1eb920cd366
-6fa12f35e45673fb12b45a6ed7e84937576e5327c82d7f27f6c0255f75ef4b02
-cd492b23ec1f346bdf8e007042a82ab730ab2805569d7b978a4b114577514548
-0d426dc4a8ad86de85b23ab5aa8a50a30bbdd8ef5e9ff8e7954a69987fb5401e
-a9d039d5e05ef245e3c70a85236969f32bd1e5d29d71a2013493945e803838dc
-7241a73c4c1f14548eaadcba64aebc29fd2253fa59b6b039bb2edc9e4a7c8e83
-317ec39a07b8c8297e4b08d4e6f01a53e3d690f1d1db49f19640c16441be6ae8
-d1cbdf853394cf665f741938733fbc700e8d82c4cf1d72456008a0fe55c8b677
-a4f3e197aac9b976343923dd4c5a181454319fc509d499bf14740ef1387f354d
-d71c3bc5b9d4d2d9e0e7a3bc60c79c8e6d344bebeb3b2dc2c3605fdf1002f061
-d52f718b57d1f6c1406b1fdf2ce37ee45693ba72284c5652b2d88b29ad55d9bd
-78032a76ae6427c19749ca1503fdfa6eda4861f0b0c72684589efe6c01d9c964
-1201b79c5ce03520510e13bc5461fa3d2897e2b7c65ebb571e2d0ce319248d4a
-fcde6d70c38d25f6bbf0c09b64553c3fdadc64c293deda6e2ed8c191d7f432ac
-5bcc1ac3183c92d545abbd4da7e768140b9f5a5077b08dc8eae64727eade3e5c
-05e07036b08c31ba5ae366c642f816b5fa60e148795d3d4ce050f09c443d6fe0
-d44f8859d43da39643d4fb8c5e2e34f1b32142ddef07b1c02c09f4cc9509eabe
-99350ccd3a9d2d6fb809016dbe0c1a29fd1d25cc83125ba7d0143e09203f9e34
-99c6d07cc78bfdb82f72c577aff1045cd2ce2e3de0300283ae5ac540d498e467
-0e3718e3dac6dcdf1c7ab2d5f75c5b6e56bc32d8ddace4ce7f9272aae188f3b7
-d6d31b380592cfc0de45eabdd87cfaa15143cce738ede40bd9a06db0b3d5f570
-be5b21b328b3ac4ff46abb190ec17e73d31af389dc8e887280f84caf7b317c27
-38593005aa586b3c4918fa95a9435e45db40bb52d2f6034686463c87280b8085
-877297a871dd11fa1d782568fe813cbdab6daba828c1c264c3db809cb9da6635
-640c3e991dc41cb1841ea1556b7560d47526bdc012a8f1dacb30f38ed0f4721b
-b98b107526258d66804fb0dd4c52d827850d8f0a764a53cd81f66269a8cc114c
-06482a5b2b752416707d28e88291bca02b7746161794437f61e7e3353ecc92c4
-151af9a2f0b0e0e7b8be3106fa8b455e60d1b8e7a30a45922fe00f7ac9031be3
-b9e1dcae83017ffa27f196e1b8da6cff1bc25c0d776dbf675838c24c57a3078c
-d2f6dad8722aa8997078f22bfab7e8f995538174d577c28d1660e5484270e63b
-90ff29111a71bcfdda204034ad6df026ba9fe61c02bc99e0553cae82fc1f84a6
-f8c744cf34a92b3fa239b23fa2aa469c5765c02abeea272fc928d24714c14ea1
-2dc6871a82973f1b57a2063379dc471f0dd0684ab5ce9ab8088512b548c0e96c
-59f314ee81f9ba0a793072325d5b2a478eca04739746
-0000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000
-cleartomark
-%%EndResource
-/F122_0 /DTUUHP+NimbusSanL-Bold 1 1
-[ /.notdef/dotaccent/fi/fl/fraction/hungarumlaut/Lslash/lslash
-  /ogonek/ring/.notdef/breve/minus/.notdef/Zcaron/zcaron
-  /caron/dotlessi/dotlessj/ff/ffi/ffl/notequal/infinity
-  /lessequal/greaterequal/partialdiff/summation/product/pi/grave/quotesingle
-  /space/exclam/quotedbl/numbersign/dollar/percent/ampersand/quoteright
-  /parenleft/parenright/asterisk/plus/comma/hyphen/period/slash
-  /zero/one/two/three/four/five/six/seven
-  /eight/nine/colon/semicolon/less/equal/greater/question
-  /at/A/B/C/D/E/F/G
-  /H/I/J/K/L/M/N/O
-  /P/Q/R/S/T/U/V/W
-  /X/Y/Z/bracketleft/backslash/bracketright/asciicircum/underscore
-  /quoteleft/a/b/c/d/e/f/g
-  /h/i/j/k/l/m/n/o
-  /p/q/r/s/t/u/v/w
-  /x/y/z/braceleft/bar/braceright/asciitilde/.notdef
-  /Euro/integral/quotesinglbase/florin/quotedblbase/ellipsis/dagger/daggerdbl
-  /circumflex/perthousand/Scaron/guilsinglleft/OE/Omega/radical/approxequal
-  /.notdef/.notdef/.notdef/quotedblleft/quotedblright/bullet/endash/emdash
-  /tilde/trademark/scaron/guilsinglright/oe/Delta/lozenge/Ydieresis
-  /.notdef/exclamdown/cent/sterling/currency/yen/brokenbar/section
-  /dieresis/copyright/ordfeminine/guillemotleft/logicalnot/hyphen/registered/macron
-  /degree/plusminus/twosuperior/threesuperior/acute/mu/paragraph/periodcentered
-  /cedilla/onesuperior/ordmasculine/guillemotright/onequarter/onehalf/threequarters/questiondown
-  /Agrave/Aacute/Acircumflex/Atilde/Adieresis/Aring/AE/Ccedilla
-  /Egrave/Eacute/Ecircumflex/Edieresis/Igrave/Iacute/Icircumflex/Idieresis
-  /Eth/Ntilde/Ograve/Oacute/Ocircumflex/Otilde/Odieresis/multiply
-  /Oslash/Ugrave/Uacute/Ucircumflex/Udieresis/Yacute/Thorn/germandbls
-  /agrave/aacute/acircumflex/atilde/adieresis/aring/ae/ccedilla
-  /egrave/eacute/ecircumflex/edieresis/igrave/iacute/icircumflex/idieresis
-  /eth/ntilde/ograve/oacute/ocircumflex/otilde/odieresis/divide
-  /oslash/ugrave/uacute/ucircumflex/udieresis/yacute/thorn/ydieresis]
-pdfMakeFont
-%%BeginResource: font VXAMRV+NimbusRomNo9L-Regu
-%!PS-AdobeFont-1.0: NimbusRomNo9L-Regu 1.05
-%%CreationDate: Wed Dec 22 1999
-% Copyright (URW)++,Copyright 1999 by (URW)++ Design & Development
-% (URW)++,Copyright 1999 by (URW)++ Design & Development
-% See the file COPYING (GNU General Public License) for license conditions.
-% As a special exception, permission is granted to include this font
-% program in a Postscript or PDF file that consists of a document that
-% contains text to be displayed or printed using this font, regardless
-% of the conditions or license applying to the document itself.
-12 dict begin
-/FontInfo 10 dict dup begin
-/version (1.05) readonly def
-/Notice ((URW)++,Copyright 1999 by (URW)++ Design & Development. See the file COPYING (GNU General Public License) for license conditions. As a special exception, permission is granted to include this font program in a Postscript or PDF file that consists of a document that contains text to be displayed or printed using this font, regardless of the conditions or license applying to the document itself.) readonly def
-/Copyright (Copyright (URW)++,Copyright 1999 by (URW)++ Design & Development) readonly def
-/FullName (Nimbus Roman No9 L Regular) readonly def
-/FamilyName (Nimbus Roman No9 L) readonly def
-/Weight (Regular) readonly def
-/ItalicAngle 0.0 def
-/isFixedPitch false def
-/UnderlinePosition -100 def
-/UnderlineThickness 50 def
-end readonly def
-/FontName /VXAMRV+NimbusRomNo9L-Regu def
-/PaintType 0 def
-/WMode 0 def
-/FontBBox {-168 -281 1000 924} readonly def
-/FontType 1 def
-/FontMatrix [0.001 0.0 0.0 0.001 0.0 0.0] readonly def
-/Encoding StandardEncoding def
-currentdict end
-currentfile eexec
-d9d66f633b846a989b9974b0179fc6cc445bc2c03103c68570a7b354a4a280ae
-6fbf7f9888e039ab60fcaf852eb4ce3afeb979d5ea70fde44a2ae5c8c0166c27
-bf9665eea11c7d2329c1a211dd26bb372be5822f5ea70d99eb578c7befd44cdf
-045a363056e5e1cc51525ea6fc061dcebb337208eff729802376a2801424f670
-0e7e6397b28f15bc10b40012b0a3eaeb2693e8f7f627c4c9c7c6c5bff105c1e4
-1b2b9e8f09253b76040d268b80719e1b3f5a55ab7b8e152a40e590419249f2e4
-c36159f8e54b532468e36965a38646781ab0b7f6a3e851fd10caa49adfc1e546
-2fd2ec6150dc6e19523050f6148348a561ad8d2e2721eff8a570cb33460a745b
-926c889304c09753c2d78fb0ca95dc6de5b8c524752c83601e7e9f73df660674
-f05ad83a166da9be89f22feabd4b2665960f6fb5bc32928e1230c212e5d69cee
-0b3311a1738a11747ae263106916d8e95f25b25b4bc6afb03b79abb95dda518b
-41a49458111d2a1433c043627ef9460d324ffe22935f4f6da88b8b91ae95b34e
-08408a34ec8eac3f65b6ae3e3e2524867ee9d29068f81e4372f4470beeb4d6be
-ee4df956becc0cb77f8490117b22b2fb75c938ed0a5e208d88bc38b2ab8b9cfb
-f1d53084b6f43df336481eca0aa2d5317bc83fc0e1d4db01d0b7707eef217e94
-a7f985102ded27d8e8b009f7ef6db91b91e78bfae7bd688e10b3dc9ac77cdee8
-47aa4dc8ec78241e593d26ec7a60696151a2ae5325d736e99e01bdcbde69579f
-92eeec224b6757eedc64a75455bb665df42a0e4ce7b99bf3e7d66f8ffc8c13f9
-d7a1ff7a9d5ff7ac43396779f11c9b008c33a2043d48b61b88b03104b1425f09
-675b559ca4302c001ee80d2b739cc0fd1023bf4f1ff9c01e892e59cca7c26011
-b8e0b6d29cc29fc72792fda5e7d5d88ef98f9dba960c96534c399c54865eab86
-0fa2e0d6c7c44b553eac1574d55e7970744d4792fffbdce6fb4365bdbc2965bb
-2e9edad9e0ebf0b620db415ad98297f5ae83d9c710436657e74d26e83957c745
-89834337035a7501803947f6880b70e56a3a404c62d57b849d28804cbe0f5884
-435a0e12dcc9ba414abb732bfbae237001f557dea5e972ba0838a3c7c9eb75aa
-4a050da0a529bdffbf9011c360564fd17a02c18860af6b86efd4e2c125686c9a
-5e114e95c71fc89a5de9c589bfe5ac0480cff716345265d2435edae67cfc4801
-5bc08e7a48d683acdb91e05f469c0c8919d73a5d07a1ccb173e30e76680acb09
-02a40a3e11916198bd69f1a26e88330f50692d0d5917e99e7a01b327413e24aa
-e98ea484e45897e6ae4d6997b6e8bbf61c9406e916d56985cb2bd297e8acfc6e
-cf2d2281ad84696b7c6cb584bd85cc20ba14add3bc3e25db91124c0acf22e902
-3cfbf04cc40de331991e9075d22ab5ee0e849b340050e6c417c664a782d05549
-db2ef572f193b1c12b4635c2b358747046de5858ec32b3b2e79d42750657977f
-acdd2ee5a7c9320d907438dba63aa05ed410fc7000f53549091be71be45da4ab
-a315f95b724a60f17c70833e889cfe7ea206a7abc4393cb6ef47be3700ba5638
-6831391809ef8384aea8c22735e8062a9f9101add125a321fb65399cbcd9c9e6
-0f46fbf271b2b1ec80832cc054bab5ca80d4561da0a380d56d5cb3d90ae89a19
-48cd824eb1e7ac6127a6dba3e8ea40f00add89749d77ec0eebe26fd6ea5d8cce
-f7239681b3d94898236ae92ff3912e0afe84b6c7e08134c158b640b4aecab5f2
-a90028e67d33df31b461a2846f83d90979bb22618e2a17c5d159fb59d5177e12
-edf1320f596e7a4c379329adb367f92bf2869a9a97398e0c20f5f017ca9db7ba
-b3bab72b87a7b6bf4febd03132f9075c271f2054078396df8403dc91461325f6
-12cf1421f3099ccd799c2c099492c4f071336d985c0c360b2f5a5877fd00b6f9
-2e5911dddfb31d17a60124ee8da6cbda94196d7ed42804610e4f730daf2f2d5a
-b767c320c62543e26534314facae006ba2064623902c8ac479eeebb609e8c3e4
-1516ce412cb410bd026231e22a9cd0f664d769e4e45cbb75b7341f06d8e37285
-beaa9ab71aabe3cbfe5a348681aa246047ca29ca6b442feade254c7582d32d3c
-71b5e645c82e92f057eb5f859bee23daa95c575edaaf9896d6c10980a09db34e
-084c8a754e31b618c6991baa856cb86877044e10c2f189b284e3195a2db6b910
-2574e2461d2fae65b7321c0093a2a34996c0b77123503e9edc623dd02c44fb76
-3c550840bdf969582d226510ebf89944e59684eb2e2c463e69702266fbcf8d1d
-4c0be400495e227b9cb21c8086f328782ca7294dcf3ecdc1a62714143a4c1b98
-e5de1dd554fba60571188a58f0354a6b9ef580689b78a0c8515ca05a35832616
-7e0a90f68f3c306ab60aab20872fb167673f41e8e87ff0111f579cbd0da68b56
-3e35d2ebf9f28b104082e36187373efc7a33f62d3fe4a390b63a76e9b2531871
-6bd59861f51b561dcc115192a6fc22d15a5af03ba09cdfa66b660cf4288e9d79
-26e797256659b0ff64bb5d900990c3cb588e1e18810bcb009a91e5f4f8d9db1a
-f2a063bdabd9c3332f4bdb701bb94b4fd24570b440ae74b8d924e48e7c2defb0
-53a19e5b4df39abf4f6fc6160b5fcca00608422a3091cd03e726b1ea1d203b3f
-c44173460b490498eda3121881ebd21cb5b571d21a6228cc0a1b035ebe97f26b
-0b58179bd22ac950ec3a98458051a874297cd6bfe731c5b413819503111f1f6e
-ebfb5628c955f5fcaed76f2402ce351f77e471d1c9821dad627ff25131590577
-5ff9335dd28d85a11bf155765632b34a3aa1df9c01134bd8fe927e0064319951
-e2c1d374c9acfc30932712a5c3e0fe3c7e355e3356e9135a143f1b4e2738e208
-8f44633dd9300bafc770625a64b2bd20d4f672701310e5d1d5b2dd502802539a
-65344601924c473b7618f9b87bf6eb49474fe62891097b9b381dfc9dd22f6ceb
-340efd950b74e614a2908eea7b0d395e15943d0a9072e2c0e6c91d9141c84281
-6a59f02111333723db78c2c287675d73152ee3c63397f5ea6203c707568137e0
-12438b86ead16d71a0a56d00e6ace9d80aff646b05d829dcf08dce2fed1a17d3
-83a7c9e7c2a5caeb38bda802e6696bab17a5d1e5d6c51b6371c642d5588a2945
-1f3c8b0cd56806531579f7c0d10a9fbe254ea910522d955c86ddd693b8660bbd
-17b2b23fea57af15b1720e42c6de537074c071c50c114ac54c45ba2fee00d13a
-2573bb9243648a1be2569cf68ff78e4cacacdb34dad918a30005c31f17781633
-6b74af8b9931bec0c1892780020c1a92470e3ad7f1bb6ef26c835f13a9c56ded
-51df4a7847c993b88b9fda9a8955d8bdbf6ba773d06645e292ce26d9df4bbd4f
-3d20f52161853827837c837f33425990818b958adcc3ae79b5791ff04daa32fe
-54050aa9d34606f16c7763de770cc33c9acb60e5354d5a27a687ca6e0fd74a4b
-5cffeadf6ad0ba87b906c09201ff65ce6c3f620bbfaaccbe54da884b87e906b5
-f5285d3841ecf78f0a1ee4a80724da3a4fd49ffbaa66be3402a2480a6f8fc164
-343a369e2b8947fd5f58a4697234c742685421ce3d57398c5ed6f6b049fdf39f
-6870236751d9ef2210e680b4d8a6daab758bd7fa7da9680604e5bf85d1826611
-2ca08e8922a1d46ac853f4bdca37f7fe80d2d27854012e4a8f70bd854ea4c189
-ea6939096b56168aeb971aaafe1bca667137a76761cba2fbffceafe3e98d5590
-db3dbc44b3f9d4ef0419cae23086898bb25a222eea19c1a760389672933ea7c2
-8b31025619bd108b79d51d54e23f401f42165f0d513bb2409ce66ba3e83fc000
-4372873eb8b4405a8f5bd88cc2f21d2d60fa4024707869c5fd40d94028ed13b2
-5762cc7924d100d3ce0dd32cfca124ec1fce4cce8c137070a18f05cd73809449
-bcdeb0ac24dcf63679d46aa8b3a4a5d0dbfa9342716619cd3683dfa7a9d6683e
-5a7a03ddb47833fdff8935f2f004f58ede6447adce4fda1b734c75c52d16c406
-9428cdf68855946014584f7fe49b03f896e0054cffff5da4728bf4ce1d892052
-701b48b81f58f5ea344e8ebfe13baa70cb43ce4a979d8225ed78417648672e61
-07eb7b31f81cf52b4136288200e640654e83534eadf05301faf2f3a859772c3a
-545fc20429119ff00c259aa582af4e3cde1c99769f4e433d9b178edcecf142ad
-ffaa6da004a90f53e70048aa8d15a26bfcf7b02ed70bc262d165e99f87ca7424
-0eb98f3d7fc0d4926ae43c8d322bb9eca24a4c45f7dbb0feaa9a900e3521d6b3
-87b52a30acb29c914b06793f19a1efbe3be7d0b8e20cad99d292c315b12376d5
-655121189a833132715762ca7118685814f71aaa08b89e466c7468bca01bd98b
-63ec7cc3ac41dd06c5bbda86227afcc1f7796b5f878946c135bfa75a98db1b57
-0f38c49770ae23986ffaedbf6644df58a252c29ac821f4584b96b5ddafa9b3a1
-aa0ef6d17fc1e75916753bc8c799497e1279ec783ea86df307cd54b58c2b3ebb
-fd722006d127834b089670e5f1e7ba8bc4a0f6181bb4efbb8f99e4475181449f
-2fcb255da4233f7ab097ef0108ba3fc12cda0618870eacb9fe4195dfab182242
-bae0956d09e388d10da2f940186e25c9926886e9806c70105dc75259fb1e5da2
-675e4e114f84862e6b822a10a9d364b1cd13dca3d385b83499c715ecd7598766
-b215910f002358d592fc36d0bd482ee9cc338378ea1566839526a5783f250818
-078b97d73b1d62a1aad3d5a9753bfef23f7b3e6d5bd318c463aa04490b9063a0
-e83e3e68109b182720d2b1c13b498f8f495661c0f4e6455b96a6a92ff806f1cb
-3b1c6eac82d9a687b83c572c42df22beae31d1239719186f14ef637fe4e7c7b1
-fe8f4f1bd8367d76d467be95c394a818198d922bcaeeee371fe17e396b27cec5
-f0554778587fc7d78acdf317a8efdfc82c2f57b6411b3ab68f96e3e7cd321a6d
-4783435056ab5a0095726435be6885bf2784fb2cbeffc0f8248dcd594d34b21c
-98e67de50b6876c3d6d4d4ca7ce0b9013ebe754b104dcfc0719a10cdd9985e19
-2cdf4e88876c2dd4e79e23afa70ab5b4758af32ee87b8415b881ac15c5c3e1bc
-d17a5b961efb3a8dc987deded6f28a240d66f004ad05ce1c551e29b45668db2b
-305c9b1af5cd5388a0802d80f18e0f4bc8065baf393ffab9a4d674312c2033d2
-7c78b5e9461fb09b9b2caaab70ceb3afa574c89bc620328211c85656f63a8ddd
-97c827297327b7980c2fe0acb1c34866aa3c5d7408e257eba3c53de8338bdf96
-cb7ba55fe31bddbf7807148c0a132bdbbe8a2c21a23e11889da13e429914f7f5
-7132936359a0cc65e5993caf52902f76f75d6cb46dd20a3c0be80d45f2c746bf
-236733462080fbdc8c5c1dbe9781f45aba74af8033a6ef2bdb16f7b0930d6b6e
-7ca7fac8cfb2dfab8c063d961077585d24e8fbb5e0b0bee9c4509b23361dd06a
-dd25767833b9a770780b311f608cae7adde000297a2672211f0de8cf7f5fbc62
-78faba25d035fe3a7cc3a4743c0efe1c4a5e9cadf1e05bc7982648d5c9fb2992
-4a9ee1570ba2ab068cce168552299361d62a2bc2c0da48ee94d1cedf1e2d29bb
-43864ab5b770a14c98a432ab76c17998904f052a50ef845100533ba5cfb24c84
-da53581ec4f2201ca9fdae76ef365515188ace4cfc939ad6d193413ca7ee225b
-0137f4637f09952213be725cc7aec579b2fe85f7c6af18d70c4fda0557567e64
-d430f09aca7bf28984977ba0f5849a5a86729d5640bbe4c30b17ab03262a02bd
-8ee077ead7fdaefd37af16007d83714aca07fcf882adc4792583aabb279579df
-6741f637cdf8598fb5827528771444b0aa82dd5e00e70edefa7405a1d8a7797b
-ef021a53ba68c7ff6780c94f1393d1745ab1fd7c728c6112766a3c2e21dff002
-9e45a5c5668f8b084f22cd6a6cfb056cf0f402a73b2c02118259352eff6d680b
-877ce3024c37d532c186f3d4a97603704cc0ddb25cac00aeb4cf601f6fb45655
-8939ab962cb9e16a2400938d226056535ebe5707cf0a8678b54e6e3a103b2eff
-0bb7306d7c7c3f523b2aec267a5f1e3f99208d8ec9ab27d658c26f635c2984ab
-5a4d214768c6dc775bcc616838159aa10d5bd93cfc8b2d836eae5ed480fb6ddb
-24253a62a1b798bfa51b068b6888b76d2233b6fb11794f166254cb3ac8cfb650
-429866dbeb8d09e6d03889899a4e8bfc9a855ea4660f928d0aae8247eec1668c
-8e798398d53e52a5684caa59c47cb38c8f1009a8aa12a269a587593874c2dc78
-0ba989078910f3d70211147751e9f7264d6e64f1b05410ed3427bb7d0704443e
-f2baeb0fb9e3f1c1c14b178e716feb4644240447a3f02211350e36e1a586a042
-9ab336c6b44c0d2977294e704e8695b6daf079bca033b6bd3485eb7a78582fb9
-373716136c63eadbab3a2577738f553f81135829f9118f4bfe20cd51190bd7c5
-17035ebe97f26b0b58973ea9b5e0d111d9eacf2fa54b223c4f40c139ab891a41
-c7d5ba5338bfd58090ea727c3fd9d0c0217c05798787881d07cefe019518ccdd
-a7ad72305f06a98717cda80c5daaafc50e3c6d78d2b5d851beec46731a6c29ed
-ddcb9089de5cc2ddb696d3b7de3b67f066527ae22cc1ae6285dd1ad42e0809ee
-65812268d28e7105859262e9368a3aa7fd0207d47de5ea5591927f5e568386d3
-a61fcbe872945a272c75384be1e85b26aa094704715f1957de37a2fde2577ba3
-85000d0708fc918d52360cda828cedd17cb7d625155ceb6931a29025b44ec8fc
-3678fa08027b20fb9649d07f01484f2fd2e1746f290e32434fcd4d15acf0708b
-ee3fe9948d3ae141749b47810558d71d592735c1c86ee375be7413b2cf462660
-0b115cd043ede5612ab895cee0909da8d165408cd5c4c34114ee4d7fab4c37b6
-a31cb829c4bab2dd04b1a7097dec24c6429c13482667116522f94edc99de551c
-a693362be4d277e12829bc466e13d09841b5d9af504be4ea59e9c2459eea5ac2
-c678e3fa30cdfc5ab855d56c1ad8374f9769a6b575a1dee5aaaab4f716dcebe0
-0fab8b0b5522294ce3164f8446679fcc7aff5bf49062cea58f5c661a895ae753
-8891536066f8416ff5e357fc34cc34d6b68abe2fb2c540a7123bbf90d2671f65
-90515b96cdd1bd2c1396bc15503caa4ccd3ce28e0361801bdc5da98887b2c39d
-b84a0a4de7859c7da394acc497641ece12ad8a7d62ac5f8e6bda0577fe64d581
-35390a37a1570cb25b23b747b236f3f2606a3ff6e487a78069a068e7af13a8e9
-315016ebb2552f644065408a69f1bb6fed50486b2a05d403cd56ec5d3671c9ce
-091995d384491b65eeaf33078529238342c32a4b81788c31e62ba0614bafcf9c
-3c1cd422c605740a8939487e26bb9233d4cde68afe7a0cadc3aecd739c9c425d
-09cb50b4b4be28115ba7fc59b541513cd6fd08039cf40a1f5b90a8bd1263806f
-ec35aaa4100ecc05416ece2f061cfdbc321cf3324f1eda91976cabb8d2d9acc9
-b93c575c363fa691e18215311431841de8187a20d6664348c7a8adb06e867d02
-07bd48fe8067168c4412fc80cdba62f8b9209f5407670a26db1f7f5d67c4d227
-90bcd0f1e8640e5f9288c410487290808b88f9421d506386ac95cd959fd1ed07
-778de2f62958ff409d37332aa4ba88c735f2a56e4e746ee98b9667072874b21a
-5f98225aeecabf5cc818f3fa54edde178b40a1b1d6e2f900365e2b503346b213
-ddb43a269c5a973d303dbf615ac3caabfc39fe2144681e7cd633056bc77d95a9
-16f54291575aff7a3a4c13eca61a8d261b3a74307aac38b50c0e55222626e717
-db6e122547b3b8a766fb877deeea52ece2e74ba02ca7676f0e037cffaf287340
-c19bbfd9378d8e898225eda3fbf814ad51f976241a7285dbcc62610fe998ebc9
-7dc5961af9d70a6786e8922e7932a539f1606101440c6855f2284eb34a895cae
-44637b6a0b1c6386c21f11f2e7ee2adf012ea6ff35314981226505bd4b0ea25d
-371be9fb6fc0425d8f374cc51fcb15600ff7a49a4104bc29a369c8336438bd4a
-45b7c8fd52577a49acdb394cbbc16c844ad99f85b5af1e8018900d50862d7c7b
-045ee4bf7972eb05aa5696a004f3ec9be95c4c14180c7c8098a3a0443c0dfaad
-91e9c3a37509b29066af112db77107b9daf2e45e72dcd78660d5d56018cdf1e4
-ca787593c31a2d6ef925e37e4ee77e687e149bf506664975ccbf5fdc20b5c306
-984208ffb9ec2f79e76a7a029cf5981fd2d07176083d7fa0d9fa7b1e6c6da9fe
-423bf29011478ba39fbdc7e77ba230ee7b89728c9312602dda359f1ee65ba362
-d1f36657943255d62f0c84fe8a630204a8e64d8f940e9ddaf3c2ddc16fd131c7
-f302a2f9fb65ecccad4616977b2ec724fc6a4c39417962e0de1dcfa69aec8a02
-07179266935b655d20af3d45228ac3796fd2b7b6e0580904a27fe0c8023f4fa0
-fd70e469e5f309690c6ab737e9e0dd1db57fb312362b64ff1955401395b42086
-07e7f9449a8953149f324b4d5785c2a0a4c28eb487fd0bfd65462a1a4a741be1
-b1876330912edefcace1dfacea7628d16a4716d3989e1b31830cbc2bf9fce144
-9f0e80bdcbcfcf477a2c30a72ec227b20a0af16fcb8356bc205f18c6088c1d6d
-c579f1dcd23ffa147d72821b7a63fc011d5718fed41b16ea1d83ecd8d2ade289
-54eaa105f82f777b6635c160d0e3d67fbff2080db2a99d489a070d865c39ac9d
-2a88ab5fbce010919edc0ab213a09038fac6d3c81a4972e3c5683f49480fa5fe
-b8cd3279398028dab63ef7e8e1df85a63f93273f187f8f8619c14ab824c97c3c
-70d06fbc0a1b4be1b2b7f11ef469adef71617b304b51c462ab3c6c0e831c9ad3
-cb80c5e0d0fafd079d7f4f245d542ea892c6fe3c3d6d1ac2c92371b7a33aab5a
-ab8375b4cae9661c9d314999093b2a04ea1cb671c9f07ecefba615e023cb0f72
-b6eed231ad31b1f4d03e807e56c1e1663986eed65e3ee47a2dd11c1211236973
-4b4607a6570f534debc72ac06dbb2149f9efb793a917b3b604271fb764fab871
-f7aa5a5fcc54533951454fe7afa29cddef96e951aaa9b8eeb3f9b418bd132974
-c601b6fa29471dc34814fc81a1e1a5155951c12022aadce5826302220b18dfc3
-d30b2277d08e7cc7a87bf1b8ec4507b43cefb117119d86de3be51bf870390ea3
-d8daa3f74ccd3712d1c00261e853dc3078dd411189872a50d85d58cee8fffb1f
-0288029490412f3e58f83dada08fa695b18efd0a4f289705385a411fcb2d7a47
-ffe38977fce18188c0043c448d27e160ee752be0d44d0f83b6bf642c694aa530
-e223aefa3fdb17ee7aeaba75b9a86d7cb0f50ad4d5ce68d4ed48cb0c188f9dc4
-34548b48403078f63079bce8529f910ab280ebcae7df9f824dca756f9d647dc4
-d42da412230a6231307e7495424f98c9f129cc4a326a3dd8e476e18d666f94fe
-53edc87e47f6d84abb643ff3b4084437da26b4a298f819f4b6823eddac11bc85
-b9f5c5d0aa1e7b0ddca82c8e01944b3ea48978c1b8f4ff47779a5523f600d33b
-896b659c31f4f6f7decbae0fe1f83dde18f77f53db140a36b0f6f4b883ebcbb2
-b6d353bf2ca6102173b6dfba0f452d011f6cf7d661a470c3c5dd189c1e83fc4b
-9372ed67ef4ed9a5b98f85c8d73d490133b7362ab976a385cec705a2eb89d7f3
-2fbd60c08b86a30219aa2988f79e6386062be839c1f9d30affde82cade3494ee
-13041755e76cc07ccb3a4a701461290b5b79728eddfc63b2ed5cd4bbe0c4c365
-75488d590258ce2084f898d7c58b3f65b09dea2f8d4f71e80b2a2f8f31d5fcef
-7a7744b64d7baa701e473b85c65814b0a93e3ffbd7b2af85e00ffbfab9bb7766
-f444709a47902c919bd2a4becdce07b64053aea1058e26024b46153d6bb92c0b
-59861b2ddaf3d38dbea5bfedcc49938eb98188a3c4dceefa1f308559f7712ccf
-288219c6a3d4eefb81a2c5f154990fd8f09713a0531017d74b47e1f97aa6f0f3
-92ce5bb7475c676247d57bb14ff676f11a4b5b564ac26bfa9d85c9cb0414fafb
-c35b46eacf74dd964fbddab28fd7bb304b9bf4e12cd15b3bbb163dd66e89f24e
-6485c6ea63365d29907f6ba96d313f9b2ab7d175d549f4235653ef979a5c63cb
-6ee50cc333387a0ed88d30d9fd2197d31a0894ed0a47b15d92dca463a8c84b3a
-986d396e6530b2e9ba127bb5662ca948a8f0c563b9c868644b8d01064db6aa72
-090dda0521e6d778192a8c6d4d4639e80e309194cb76fc5d4615f396dd85b06f
-71dfc7f39a259e322c5e7d28646310eac92e5f6afdd6071b21e6664e1cdd3848
-c864ce0e380fdc48b251d52b5094ead64d380b6818e2c8b1a4eb8f9c18adde6d
-6e4ce1def2ae8f2649f1e5aaa05720a358a74e181568a10b536f68b7a0292787
-12c34acfa5bbafc4aa3eaa4d8ebb26e20bb00d228b4eac4a163e0b72899874a3
-f85e82c396d9e2891d8e0d6e5571d4ef116879cd2f5485dde4b9d40f638a3a95
-de5ddd14adbe72f5bbadf0d9950a195f64fd3209c6d47b46b7708f855da96cb5
-e9e1260f6699d945a611a7ea348db3c86be4b32fc2687f15c4c86957018d428d
-f6244a1fb6a99122bf89d7add01c80f2b2bb2c7168b02c400bfc98d65394948d
-c736741f9e0244fe096571f087c5d6d7d022c726a4cecf37cf2ddeb1e9d77098
-60c5d43121bc2e4b72a2d895a5ad2f449196aefe8c01784323de3804363b88c9
-1c86124f431e6dd0744c3d073fff4bbc2b98bdef713bdefc2da4e0e22eda76d0
-34424ce13529bc04c078dfbf8b3efd96cf662c4e151f15d4f8ea52641689d4a0
-5f7c9ec4efa5119db9e3a61e4a669c29348a1e71382c093499cd35d7d1227a5f
-5bc3db96823c167100074c70040a55142148196567c20c7eecbb25ed6e31f563
-9add24d52aceea4b88114eb6dba9461c2e5262fb9529e9f6f0bde20d3e209a8f
-0c9fd81b99b00d268f764593baa894f7ae50634766c922f751ed183aacaec03d
-b7d96d012cd0d111904245be9537edb0f8769ad1a8abbd8d1cbbe5e79c53c00d
-983c69d8865e93b6495a2f15ad9ab1da7503bd5b85ebe27aba01f71e56482be9
-d4342ac2562d8e6d1e4146447561ef5068d17306d66a52fa41644897a9b161c8
-5dd4161aa3d956e7961aa8020467e76a833e01c974e32aa2b8cf27d62fc81ee4
-d74649bf9530306481f430a539a95dcc2502f712947f6a68dda00589ef404132
-1dbc8b94afd827bbd5f77820353fddec5d98fdd256e858581054789781ab090a
-816e65ad3dc4a68b4ef2356e7cd2f906a859dad680d649457bae159f91805d52
-fb6dcfa5d0ac6373fa8325a817563bc9ed89a17d8cdee9b7516f38908e426f05
-1517eec7941cbadb22390e3e2e17d62ca67f37d01377c5a1e09bef5b795b4446
-54b383193351e05ed8bbd8b0b138cf62a428c78744582eec90a41c3bd44a4e73
-c9b32ea4936c211269ba5f883d45b16681f8afa0646a4031ef69cf4936305336
-5758f50534e6974342f4d232b5024dba0eb297e3aa3e9ef0935bd47998370420
-ead844c7e336288356715ceb8cb8492ecdc8fd8f1183360fa32850051442f4d7
-c0250d658c633de21048f4676a1875df6a8a61f0fc7c25dd5acd0220798ca70e
-f09a72b19595172afb9085b9a5971ad1b9a3a2508884a3bce88c984f58389620
-95584866c59f89120c7f491cde35b9d179f11db0d3c30370138852050cf14b18
-c06dadc218335bb465dd88304f1c1cd11062ca72649491fdc62d571c082cc816
-261444906d399760159f6b1e6df4b42a7a84750aa61c034b11a6e7eddcdeb54d
-e1f5151042a8e9f6a23a81a235fbc3908a85a6b05d8162bbdf3a672715b6fcce
-554e98df1f4583e03e456469890f07f83bc0a8954fc5edc7898f21f6917d30fa
-36faee98f622ef313cc8431931d83d271cef880dba07b832a01384994e964233
-f2e29de305c3863191f877dfba44214da68bdbfbde1e3b8b9659d7800df5bd19
-28bb1425a51abc317efdda09d29e04ec8b17bd3b78085595120b58fb421916c6
-af4b92776ef8a8211cc376a37566422bf2e2a840be57a357ab9b9adaa20600d5
-c49f228d2f7bb606fcfa867342884fcd426a72ca4c5d09612bbe26a2d9d3c8fe
-15a55e095b6705f2a2f2a00c9f1cbae16b91e13798b96d5ae66b5a8d1cd751cc
-9747bd951a55ec3fcc11f58f8afb40913166ab60a01b697507fe0753d085e5a8
-8153cfcbb70e29b7073ab33f7be2b6bd070ed974d0cfe4d41f7f57f05cef38c4
-251aa826e4a1d37459212c1b411b6b51faa564da0ff48ee6402b3c9fb77d502f
-61feeb32602da2b5fa880c537f60e1394571392c3fba4d110ff47a42d923c153
-f7a83bc1ffe67cd11ff1a763950f2d7b6d9575f45562c3a9de6d4ebf59482d7a
-716f39eca97fd68be71aa73987d570ce2ddf953c6ec97cbb76b147ceb8973564
-7ee159434e3af6588f47ff9722b7e90f4d9fd0c5b9e9f3a14f9bfba60ca6556b
-0473dc073a961731d322161500e15ada373d503552c0b76fc6576088e630cf29
-b9b0c82cb348259edd482520a84965a53cd673138aa57c32e41fcf50fe24a447
-4ed23401f43f5206de7fb3b6d1750223115919d85b54eae8298a19212e5c66e0
-c05c6dd7d7f8dd877123205b7e391a189e11fc30fdc6532fca87770985b357a4
-fbf9c5d261a4c998e2fe8eb96e27dac9daf1d3f0ec7422a85d9c7b241857209c
-f372c03c1100d8ebf3ce4ab3c0efc1f979c5999bac6d4abb6abab1d059c53f7e
-34f972f56df329bdb8485e39cc98cbf20ccb70a2a3cfdad4deb3267578b02f0b
-0340f42bac749465951198d2ea2bf7995852a50b5876597e55e1a1977b9e2f0b
-8a8fb0f03839dcf6bd5542827208d443ed4b9c0145e4522274a02e4420f738e7
-962c6d9fee17520ecf6d6772e5e77d6ed395304699dd65d7a610d793e38ce3dc
-e461843d5af1e27bed5652bb84d5e85622b48bec72e1622ab11506ade702cb2e
-8ca3ffb8add5c2470207bed74f2b34faf8cb61dd5e0bf54f2b8e1c7ea1fee81e
-0e0a16747443630b04990ee1be9db5764a580222b27332072e74a60ab7b789da
-aee741eb538e3ac7e38b333c7f6dadcad5b9383ab433359862dcb30ba53a413b
-5e9947eb637e78eedc4b8b17cec6b82f4cb8d2d71a37921e69d428723823ec95
-0f683a6bfb55d22dfb161e1d6b6db49dacece6e43ad2c51a70e6342a85169fde
-f8060d7da7e20b4db176bb862c29749077d7104bcb313e5c886a01cb16f11f62
-984c5f853516c1419df929d29eaf4490a3aebd24358eac006a594afcb839778f
-d0925e2daabe74c7ddcce9a4f454633b52b445fea99105fb0699485956fc737f
-25625d53dcf0b9e2386bbf0900e0e011e8adfe162d5876a850a6507512690d2d
-d1f00992f4dbbca2c63cd70b16dce15d1c128b9d6881f3f7ffeb68d7174ae769
-3b6f5e02523c7f046de294e18255b689d2ef529e6dfe489956afc909284a4d43
-b0ca1d9f8b9be4e4da535522cd9b6e64841c81138ee358ef6768e7f78af8033a
-6885457da6ba42cb4bdd4f35233b8e5ac02b7d8fbf2092bb8ce890decb6e99ca
-152d2aa56c5ab4179ba7936c74dd6c342a392131fb96c14c3b24d9f0e4d8b1cb
-862ea5e7b13e204c914bf95f55ff32e4308fe5b2949fa454560e8dec474ef52b
-65bbbed017d5eaed0d89a3c86fc63bf01d3a6a10a5fe389b1af013ebcbff2a17
-7f6e854dfec5dbf19d4e977a07a42287a2dbd42a78e589a002cca47eb865bd5e
-601a98bb3a8572f20ef1c0a2b3500f615b1b8f9b04215f91acec454312ec1dce
-08f413b9e2ddddcfd2bd85125dc5a043a45c0b9d3c86ac30b21f34cae2d347a1
-e93586eb95fdd3d1db7157b21b7ed1702d31876a1cfce58d619a66df8ccc3116
-319854a57965fe23d2d2d7e02f4d95d810e8a13d29872274fa6f48b7333b743c
-7af418c1fdaf467acd5483a47c5e99a7bd81e18ef98763ecc08820176a109145
-af183870faf171a3c24f603654896e2d1b0ac6224cfc765bf747e194cd18c740
-6c61fd10b6b7dce9c0a6577a87ae840e88f99cbf1c1d6cc83623d2fe80bd710c
-ec79256f89f26b45f75281d3de9636a134f63e244df4a623c63a895fe66e1464
-1959655f235bd056d65e3a50f55a041447594422eeffacce6af7cc9768f72158
-18ed408e47358ad45fce20e4848cc38f70943755e9233ac711e663f2c7d77b46
-c878e70669ad30ed18b6f832e4d7f54a23c837ed440ae97883348a0b5fe95232
-779187e429b6f855ed7cffccc8d6784d8bcd92548e3257ac87231c36f119ddfb
-f28ab8dc8b253a1fa09f016887fc29b6659b40bf3dd9db6ead8c8c3e504b10f8
-37dac82a816e06722397867df32fa25da0713e92ede9e4d41577ef58ac70b402
-a4427a7c86f7c1d7f378b62db43ca4bc3a8669f6e924d719f18799d1a9e5969d
-76bde4fc976074f2d623721d38e3f5c73428d6824049dea9416a450be02dcb55
-908e37faf4a56a36519311ddb3d1cb66837c2964a2dd0d34a23dde43eb30c88d
-b6ea541956b904db911d009f0b209bfdc139f48878c811ec38a21692f9b866c0
-a59d9d736d429de0db4b0526463d0348157019a262b2c3e0bf54095d06110593
-3646fcd24134d6b3a2a906a891187692967e93f69a54ff3ab8050418585ed1f5
-9822b134f8841589fe146d05ab00c8e22651c43723216c053851a5d1f9bdfaf8
-59c55523acf1e394d27500a1cdd551c773c9a6d7b3882f31f29c281fb6c6250d
-8a1c3c8dd110c1910014da6fd1d57b8ae102b261fb65a3019bd75e81ccebde3f
-3e23764e9a5dbe640ca98585da2a4af9de5a5045598a905ee7b82bbaabdd0d92
-bb5351d3a0b3071e8666fce45202af6000790c1c1d0a5bf0c4623b9815b8d3b7
-7c39970a509db6a4a0fface38a60e2dccab7f5b7ad1c0f42a74da16147589a2d
-3dadde9bb1a63a4047ea20dde1109f8856bb81184f4256994b5005d654e49086
-7bb8396fc8d807ebdefbb74e9894bf0ec793699f0e68263885581a17c87d7082
-371d3d4884b50e1295c517fc56b91ebb6b4c23b150d542cd0768924232a5ac00
-8a98f5ce9adc8dd3e65f085b35640919767237d0f9703cbd691a987a0aa0444a
-5ea0d887837482a7248865cd78b6f665301cb67cceb1f689198821227c1acd81
-3d0a50674832bd33b2672756d5186c89528180e190d1525c3e806caddc1e4157
-46055910cee4f60f40b1065f435be8a39eb454d88f5bc45ba818e5b006e5a38d
-29974f68ee1962448f7a9fd83c7f107c7788eb8975dedee759a2bbca40c811b9
-d857cf8e510376d48abd60567f307d6ec471f99b03cc7b5e8140dc0450af3832
-242a353515b5b347774f32b8b6c033adc43b2bf7185480e47c868308f3906bee
-e44131b11b2b14e77f33686307842337cd1f9695491bbbdf271b5345c44d6a75
-58c59d6d5bf8b24af38248368644e331a88cf73d0eba9dfa6f80f11af0293bb8
-40d9755540afd18fb03e0b26b6432277434166123d80044808f6f1115ca55b87
-60f82520eb81166f8363b150bac7f45983d1f4ea0b503fa8d041261e2fd14caa
-c7db8e5b1bdb04a65cbb660526d8b21eeff68105486474803acc96e7b882bc9f
-5a1d5f1e333b2b2aacf4272a05a41aea04b2c18a82b1c66a40753a3690aef089
-b9fe83dd0d86fb7b7045f041b690928b7b2b67162a1f5564117652fa7899a444
-bccc231189c60ceb72abb4038d7d0ab5a027bea7ee75542416b12a16ee00900c
-db94b2c89b2345d209cd68307e101cd06dbb79e76c725dc7180becca0eab9f8c
-ae1714c57bee7e7f54c84e7a2ab9a2b1ddd4d160cb4825b69c1bf5ee26b18391
-acd6fab3f890d8cbff5ba3666b8d7853652da2bd5db79ad8de358e55a5e02270
-e1a2d09adfed75088a71593ff0f54d5c527518cc767584e4380b8fce58b04ca2
-05a69ee280da655169029a16a3df3b86fc4ab635300397767c7d9ec3b3fbd60a
-bbf51ad4a3cb348539fb9b7eb072ece9afb2b3c00e2b91bb40a82d2ddfa58e9d
-f40699038c9a7bf930a83996afe9580c5338405108ac04fd713bb22ca2024475
-f540fe14290ab1818d9bb19483aba2f39a958ea417ec73792233ab538cb70e0a
-455c6b7e0bc86eab1df73eec1e16a6f95cd23b8f695fd2b919dd282bd1129baa
-93fb68080d90c29776bf27fa42dc0721e380ecf88286484417664e41c5b257ca
-bd4835c1d64318507de5dc2f1060644b2b125f17aff1b95a37b9b667906d48c0
-9fa7d875d59cb6f7fef2e37ec418540f8f13c2d70cbe9566299dfb80c06df99e
-b045dd3baefd87b24316700fa1c9f72157b927052cda3fd2b480df750298d645
-7c412ca39f6325d66c77be38bd8e491d8f710c5f91f432e13f89056940029532
-db065329782579b79d9f6ba60552dbd6a302e628f75e0d3582d25eb03e7deb33
-54790b02521553eb0c286cb415cde225b5d65cb79db060d13afe862d5885b567
-2430481620475f50546ac782370e3ea1c95600a524d288b5d4028be7cfbea855
-528953e607721b7488f7d7f9dd5ad14332b32bbef72240036a3e1646fe5418a7
-1fd206ad3fc75b7dcd9813caf5d29ddbb12d7ff94e37bccd72ba1086dc431b5b
-713ed14ab7e9f1bff7dddfa9bf22624e4caf3cc0d4194f0b6a36b1c67e43f117
-4bb23054ed01209d28bc55224028648a4a3073d56835afa9e004fb999372f29a
-d76db663c2a29b5638567058904a4933be88e75ca1f365739a65c27bdc195e7e
-09cfb2426fa829ca3859306b556d1bfadb5d9493c66e34dd7f63583e4532a075
-532cee2d8976f785d7909093787e8aa5fc7912ca8fa89d346634ef71f98c9fa3
-cdfd931ccc699caa314c402ebcd6bbcfcd3ef7ede19e6c8b5ea9bbe73ae35b72
-e214974b2bbb26a115750327d20732b6f6795c25e4c0b1a63b5054383d428d2b
-85ac1f719ce35a18de6f4753cb615aec6212a272d89b3750863536fcf5f791db
-3b7b39a66ebbe9fb1876bb089ec2cba092d291aac88f09c720aac4dd8fdc22d6
-4367c4c5330d4e0ed7d454728af2b4801618edada4fa3e5357fb91458dc13288
-7650401bbca16d73bea8cd5127797f92c8b5314663e02cefabd1edd89e4486ba
-4d371138ea6a07ce358d31bc9ecae64f409546e9101fff7ec710b45f910510aa
-b51eb2374992009a28262a370d42109a0aa5ebbc16d2ec5d58e0a5e7e6f80a02
-5cf8a581f3bbf98752edf64feba585fbeb56b27a79384a22c868693c05084423
-f7cd396cb48e68f76bab6512f76da2772f3d137881ebaf1d3ca6e1c98d54732a
-fc24bfe29efcd703c489dd8dcc69da4b86b5650788bfeab8bf66c5c1df7697af
-ab33d0c14caf16b9810ea74c32ccb5bbac2613c6a3d946436ccf934a20b81cfe
-5e712765d1983bd77cc45612a31c893a5583238c944f91f2d6d1069386621108
-108b0e65b4f6d76bfd0e1158005e8ba53ab48e865e9f6d07835d4e9e124b01b6
-41baaa6cff413e7ef8eed73f1cccaef55a87d71afb309ba162d3e15dda6f04da
-2de8db583beabac1e5680df43bc063095de043b2ad4c8600ef63a8090b64785e
-5288892b63a87d8c805d1000b6524109a41e05e517e07f0a76466125650b3d97
-008057de3d3380b0c352e70ac04fcc21108e619a707fbf7f59869cc9a2d571c9
-f77114250c1c41dcd527323edb2fb883dabf371dccf42389a260fbf53464bd24
-d5ae5be48163f142733b205e110d77de5cc07117d7d6d347cc8b035fa387b249
-fde3beeeac843c89bbb871114f5313437a784c051e021da4f80adb2d5e392f0e
-46068df67f46afeca052378d97597f21c39db6a2ca7c10c57421499da8d5bdec
-128109432f86a0ce63ca2be7fd64e29e8392bdd0013d4990884f7cf49e7b88ad
-846af39a3aa1ec3c85f21db07952d1b45cfc20d6848536b63d2572f44ff718ad
-c2cfacaf395cc64b34290bf19a19d756b38142c6a7471ab436c6b81abed86fbf
-8553dd8d5a052f4d53d6124ea4ddf235f4a792f8aa485fb068d39c682eda37c3
-2fcc58da51f74c24bac8db5cf825407f88daba78f41d8ba078fceb0236c2deff
-e61cc0abbdbec3bfa099b49cd1218dbff85cc705730ea545cdff4421ee5a5355
-9ccea2cf6257b757e4c6b853a476f0c97ece80a41fee4994b05eec575f87bba6
-9066eceb28ac92e1f4483f8744ede06a05ea038565096458785453b2462d103f
-300aff3783f7a2ee1a27cb223e7145b6b74fb5a95a5445b5800d0b7e4451be83
-8a7679e3a29c9bd79be0ce900f8cede4f5fbfcf46b6354268087bb020914f246
-fe06d18cc7e9cb1003bc96fb5961043d919c9298e61dc5c7cb39886e65939fc9
-037e0484b62d1ee35842b3ddb879a7fe175f07451c4456361bb646e5dd87ad6d
-ded8388fa78806f8c993bf16f539a4526503d8baf83d1f0a594db7fb1a11e7da
-d2f9db98c5d8206ea4a44ed134d784b05ac0ca245b2a5adbd93efa4a566e93c4
-84fac7ef0ad46254101b308dc4e39c549942af85c96a5dd31e5d9a99149f49ff
-99cfc5783d2cf9c320640a5029bbd61c86d4a6ae9fee690c5ac5e92d6b07aea0
-31c6110df41e63bd7039d6ba8ea9ef33beb3cdb415f4497245606963da60194a
-8383663ba3f3be2d6e0b4865ddddb484f625beb57eadfc694125ee35480efadd
-70248037bf40187f54cb53a51fd0a916d0b1a54311f43cb39856b5e4e17ddf0e
-54466ad34cdbed8fee17c87f00bfe4832eea2acaf9e93aa5091b62febfba9b01
-5960618d7135ad546cf4d00c8c725c6da697406891b75361c81cfc2d13a03836
-8f2bc045495a1d24628606990f351b6f6f197ec7b52169495bc0047335c4a3d6
-1a7aaa63fba1aca730ba1fa90ca04a0fab27b145b2dd0b4c03f01c79bb77758b
-fa630d02a5200c48499964fdac705d1f6b0aaddc58b47a35077f5ee2fbcab957
-919e5bf614a1468207592bfc36bdd62ea9389142350d0835243f485c99a49ee0
-b6fce33e9f1ca586f704d27c59621206abe70ac31608ca67a512dd60f07510cc
-e0ab7715f3a662f824a011ec47e60f84664e474a255712aad0bbb1c7c1488a49
-0a75447e9feaba451fcd1106d7da535ad82757494620a195b2f0b1622c62351d
-89b62f4f9bb812fed256952928d864147176ff0e03bdd2ba75977cbd0b5ec371
-4478c47d97601280566d937243a0c8b0b33450773897ed5535bea6d7eafd5413
-5c4a4976ee0153f4eb913aed8a1497b743e5e1ace625936b3da74119b49bb536
-1a6fefc0eb959394bd745cea919b1e62c8cac77754c59b725a26c606a7c5b3c1
-45fa3e24e5fd96e230497a0178f21cdd53c733a6bf29605879f61cd4b7ad1117
-1412b03ef42e4f8261df1544138958b3e96ac45e3a45c1bbd0a6d3f1fc4df057
-d0013bd3dea861453e54eb4721124ee277fa0eed1bdb6ca37e30dff04e91b88f
-308edd43cb7dd7e9722e57dcc7f3633209505409a1f98a133874895e00b32c01
-85baefdb0b4e97f75488ea0f76424d9196a2437fc9f67fe2933ff34232768eac
-722a84a7fc52fdf3ad248c69fd7d4c45fc33ffc6a04b562ce367d96b03c0ff8d
-75174dbdc09bdb35a9f4840a6adc555f42d20bf5e2d3da34a991f63648ebe86f
-3e155514afb82c1b3e37fcdcf8c594acf65fdfcf5965f42cb35543ffb1a1e40f
-622e6ed20b4979a37835cf08e40b8bcb015db8eb1a044dced8f6bf6360d0fa20
-e656d90efbf461da451852f58439db9281f60edf5de4af016f8715eee83eb666
-d48784d39764e33008e5d9195ef62439f3af1b989bd952fe0a0d30a85708bb1b
-a353efd6594a3ca201115b3659dc1a80619f155c6649f944dfa3e543971f8dd2
-b0a30afe77658ab82e630bcd4fcc33af8810da1360730055255aacc77fbe09dd
-9b13d44a41e0a1d3789d94bd78494a33ae60b9ad7290e4d1ed6924820140e2a8
-ae5137fe7c2570af124263b99d11ece45cf80a6e11f56dc6d77e50fab50608fa
-09eb1520f22ec16571e92a193f1699f81e352bcd9e0c838a8c1d5bfe80d76957
-7129c9c46fda7235dcc34f604171a75f069f9e00adf56e84ab1f74f093bb6995
-743f9e027fc4d9e6bcd647b2ec7f0d7af2e2efd2dbbb68c83ceb1c760fa71ed5
-0394d38963fdcbf3891934a4cbdab80107778a63f1101017becd233ba0c2e602
-e9075c5e509f2ace7b7d5c346dfb58d0ba3e005e38ea7428dfd0100b7e1fddb2
-7fe8cca96b04f9b349693acba904d44e143e03e82d16158beb36dfa21f57a039
-d6bb9bdd1a787fb9df968004388f8655e9d8b6f435117836bc910697aa1737d0
-55c73fcf23f8b56b58b09195b7cbff574a2418b1ab9f74dc607066fcb798b880
-5fb0d761cd5cca51f9ff0d2e67cabdb026f2a9b292fa472b97ab89af60cba974
-71fdef1417b14e6ff5440867aced2ff9837c1cd1e1aea23bc3cf3444e35f7cb5
-97c2f8d5576ffeaa83e06a9e6383e9225ffe0db4b1575e1f87f28b373716b668
-4f3e9e694d6d56495d21673d165cfae5c6ca112d16a40247216da4debabb7e8d
-34fcb858707d82cb8868dcd8e956d1ddf8bbf6cd57c293f8e3427f14c99e910d
-a7bef26c09e31ca66550496574c0c8f70e7efc9f74bb45fb1ff13b31d8982b44
-038c1218b874ac95ab907d01bca78f00fdec53773064be453a82efa3ce336c46
-69345e172763413f021d75570ddb0a16c806e444d8b9895af997ee7425d2ae29
-1d57d9aa91a5d9e992a7275381ac332a2396900e4d821f69a349d48a5197f98f
-3534ab2a47926edacfc5281c09ea8ddff7ccbdec5b95857c9b2d82829376bec9
-79a6ed53c42f6be0c80a9fe6b90c06624a29adc0e268241e145b18dea609cf8e
-e79720d031691f5912c7b4c1fd4358a6ed07abe23973f5b296ea3e36d8081d64
-50835e84fe95a56764117785baf8b08ac40dcf7453f4c67100445ea6a77ab755
-e3b4882dd0a9d74332f72322d36ab9dbf2199028eb6c6d0f43e79065e0fa47a7
-68bfe8609fe6ad82e7a1fadbe827d86ab6f3db8d0650c31e80c7b5ae24c703da
-104ebb4cbf0d63b0248ac1c47a8ef14a095d902bb390c48760ba7da6fe56fb44
-df02ee166b522a550efab2006e814f4053d0f21f3ee790ca6d17e8ea5ae31083
-5889c2ca6b3fcd267131d33f3f71bbaa5d414479fd6c9e84ae481defa4eacf99
-93a6fe4ff57f5e09fb99b8fce71b958080971e61bf0ccbdd2a86448782aa9871
-0cb686013548fb3f691436501545d2ddb46a3424b643590da9b3069d76eefeda
-946b6ae4a531f7d8b3bf98ab35d37ca5b36729548c06d230b597ab2cfd12dd01
-7fd2398830db4b4f2dd298e945659a564470b22656e28a2defb63714b5dcec1a
-5cca4f9f3a07077c87c06bcc145edea8424d9f44ef8e73fa98fd216cf3fd8408
-52ec5988a7749f0d6923f6c0ef50e9b2a7a61c006316b49c51a0127004566d81
-066e7f1ed02f5f570cef07df070ee98d836ad6048fa77c8888dadea64b72d4ef
-1404634b59cb590e5113d384e43ddcea459dec60c3f1cbec10e33100bc7eb8bc
-7e339177105ad6a478ed9e096477601347e97c3916a3981920b16bf4d64d8fb8
-694341db499b9ca3cf34e140d7db4d6c5c291f100c2d419752e89ba7fac3e8f7
-5b4a63616197bcacae3e0170b7467670f67acd1acab2e0502f02f416b851a5cf
-6f83c3cd9992dc925b388cf75b423edf1d5d234a341adf12cff88bec1da95ad5
-dcff92b3cca7418cc86ab1f1969ea85824d243bc5cf4fafd8f426556dd9017ee
-0242046f909acaed3ff2a91564303d13c8df20ff52e25e60cb7168902daac679
-b794ef58e0ec9a5b5a97a1143b09157c97f9946d98077de28e8908b84f73a018
-e0c3bc6f4a6ee088edde6f1e0f568799d86765d843965381467a99c8b91632e5
-eed53fdeb8673bd6c9b3757773febbf86ee428d4b386985e810db8124f5bf974
-df99afad632f03e338642c9312787ac47a9d2f4a10fc5399b6ae9029a0336d89
-2aabb090e581b749473ff20815277881f985146a028f6dfb0acd19954a0bdbb8
-b4ed1a65d3b9866dac29c6aa8aed39d956433ba649f283aaea848f6cf8f96268
-cc669613981e4705d9220970608e67028de79d0b3668b4a3db70f61c9fc01078
-37ec51eab70d92a017d96cd8893eccbe23081dafeaf81ca2c9d45d38cf554c84
-99a6b479ebfbd96be8f7f4599b10dd45b4ac860ea6aa410f161df2b33c08586d
-87218a790509800164b41e3cd0a7d30d9584813c42fe3935ee56c6f22cde9fd4
-05615ab2abac9dfcac550140c4540d6dff9ed67f530570744d0be3e56041e1d8
-ceb5a6925b3bc52c206f6dd87f2c4de70ec19487d2ddaf20ef6b26fcd60631ba
-b1677d0ab695dd68b2a3b27a70b0b48fcc872991bd0b9688a966e72239b58d3b
-2e58862eb4db390e169100e539c238299449bda356a0968c866ba0e0bf3b88f7
-6cfd39fe10ae30eb6ca7149b41e412cf556969b4c816a1945c0878e2a79e7ece
-7e52754c8dfa755d79fb15e5576a8846307527460b6d9182154e23b84ea9d443
-7fcbb470e9833d2f3f90aa88d0e44b175a9358ad0d846ae6744c4b69a5e24692
-eb37b5b9678729be88cb9f84d2773ba99b29ad2056420328116840ccb475ab76
-27bc7efd2dbe6dcdf596e94c09aa959f2d43d48a80ce2faa7c30be324d18b8f8
-70f77be72199e931d5d5f3acf48ff8060e168b48d066b2354fea58713c1a5367
-330c9491fdb6fe9654a8fd66803fdb1990bcf5bf2d8665980d162f1be17663f6
-857563371b1056144cf54ad30f1fae5707f7bbe87fae41d2c683e8a02931de24
-29e66f35188ff3594f37f7ec5021e8ccf00248be459f80ef9a46d0344e153789
-69729194731a49135ae771aac663c0037db67200c9677bf1f39abbbc54802741
-23d36a35f128c1c35dfac1a29a9c1a488f6d7df23933488c858667bfe24948db
-86bd0087f94b0c6325a403de4a434bf767c137f248c85257a72e39b51351d401
-8b530913ea8be8bfbeb039233bc3432db0b61aa281a0ce2f01b0399b066fde7e
-abcafdd46c4d6bcf2924de2ed3972c01ae0213dc1553928895c2b541b1b254e7
-a1ae46069a110c55de12f66358815cfb07cf0de59865be85f1a8f2b61d0ebae2
-7d341bdc37eab342af148a05d0fa415b86cda706746c75e0fb71a610e455a64a
-d8515705ec8d265f3e4ed9c0203744c86a1fe55ff52b6c8f4ba71e0a26651cd5
-fc38d93b2370b1e38c29343c96dd9b3d4a39b78f7bc7f2eed735f46bb46f96b1
-becbcaa7cd99ef23d16bcb3f38a605dbb908b28b1039d2ea1fc5d7afc11f1aa3
-798b407ec236421ccca18fc1f27a12d7e0b253039827104461c51ccb2283c9e2
-6fcb819b656a1aaf1b29821bcecc50b911d1a05330c43a0c6025ec90dc134042
-77ad9424c2d2e642a1223dc74ff16f70b54c0ff578157f0c701279facaeb2563
-cb3855872d3933c0a7be7b633e7e3ef053e1213e4cd7e1c57804eccd8026e581
-beb4c2fc59cacb4c1e7696d165316d7f3391ede443873c7ac48277e47eebc64e
-3023d06ffccb05a1a71b64b7da4ce1b6256c4970b179c91e1b5d6ade81c151d4
-dc3cccff1d6ebd118285d56ff7631f2c7e2b89cd70b2ef7a3894366fd177c06a
-39e3971747f671898a0109008e3190b0aef909597ffe91d7c7c2069b5680298e
-eee7c04e58cd328c1bafac2a8bcb63f6d9a6a56f29f3551ce1d2512b5885d1b7
-8397e464b5f81f4803eebfc0cc632fb653f52fc7ebe2f64ab5ce16e840bd0577
-cdfa24a928e2888ef6171e43aedaf88616344cd64b3a2c0873dbbf8eb1fdc08c
-cd86f324775672bc550241d139bdeca9e6ee36d49fbb117eb5eb456d99258067
-94ba27cc50585d2544b2f1f16c19ba41b0cb308c4f50039a843e66b20e04db1e
-b0e99faa3556d8e95f4526f0a105d4b761df415148051c604077ce2025732152
-e6db72d810bb8d81c733ba78c0deb8799abaa20d3d77152b2dd109d70efb2bdd
-7f17c1b79bcecf6b30cf0f852ac61197e0f601d2602205bc37708fb4306a782b
-1f2a39bb03554a1d10100221f99ccb45b538bf2a94ddf8c4e0b10c62f4af712c
-a44387b0038bf2474dbd2242c735db0d79246d73a43137d535eee525502ee440
-9021ae2414e9f443740cdacdaabcfaa0084a60ac34303dd559269eb088e2925c
-632bdaae44dae0ae57f3080be448c56aa549b620d1729b6cc2974e571a5697b0
-4ff3e6f6542c4fcb2abc9261d97d6e6e60538d69b36c8189491a978a7d00b9b6
-3e62a1f51d6002e12d0604d53af0188e565ceec8ba572bfde122249dacc9d9d7
-75047c69ef0485adf9f0dcec0f0c926ab91b551ebd9b8f4aa03817c25ca92395
-518304be94b5d56bbdb833cee92c32b792c6a31f37448b319880e4cac35d2edf
-dff530d0f7773e5148d41ae56e02633781cb2abb15ec2d94ae52d3c8fcfd3097
-45d95f67b560165f57393a42fc7474b5284c7cc0b893f84f8733768264ffa8dd
-0bed83d99c035bd1a83597f0d614797c583ec8c5b96b9739f304edfe1e00ab42
-38f353a82e7c71d74877d8519add9b8c78f611174599512f11c22c10cb360307
-b262f1f78c7f9a85f1fd21e94d72abd413650ea6a69b057e021ada9787d06185
-c57c0947f9a2a81822054e855f802160649e25ddc82969d94c052c289f35bb57
-c77de5dfc63716c5b0a87bc7ed859663c457f080089e3d729b9bb1299050788a
-79ada19db21011b01a47b278615be5359e71ecec7c06a67c4943e6106e152824
-ccb1fd39c485e90efebb1b2192d93c8bc52e356e51e5fc805cd7e43543e9c500
-d0ac85b7230350f9f403340a16bbdbbc3bdf0f7a571aaec4d6fdbecb288c210f
-b7c244f1908305a0b1632a8123001175e36124b543ff92c16576d373b9bdece7
-67889128ffa3497ff846f8befaf5de3b7c339f049adc9116c9a7bb8bae435798
-08dca2d9c151d9329c345919930e8437054501bba38c2bd5102a20e4291203f6
-eece2f70bff3df08aeb8ddf1806e9657ee4a5e3fd5a8fd979d90d45734f14f71
-5d339ac91b7fa18a17be81583c08544a8a32729c17975014d629b139c0b3c236
-bc9a99231ffb339b7761a2586eac564be734ef37992cec6c06c2c93de2b340fb
-3a27a52dabe69d9178d9a544430cff229335edd6f817bc52c690917fbf322852
-d4a7a709a593704568cf142b45eff164d817880cc93782c223247c65fa99aca3
-5c66a26093f9ffbc25ca9b3cf6b8ba478695c68212e80e3868a0db1a1c84bcdc
-df05fe054733a1b794ed1cc483a57b97ca2e97fcb1ceb9cc2ae7d5e0e064cc8e
-01cc628180359749622ac1cfbb57d51b25974ecb15dc83f99dbfba2d779adaf9
-6a9307bf3faef5d2ba5135a15d13c4215570e772376a4a4a3a5ec4028ef11004
-b93acaf38128de94531c23f114fec41cb2e2027e8ee138aef6ad017f5d97a600
-1063be706b65da0eda2234e7e9a9c27c084c4564b362ffa93ec9127cbc9366ce
-7b74805943c9961be5a5b5ec87675b02f756af1b70074d03374ae931cff31757
-4145af416a9098bba84ed2d3ed44019257c0f34e7f94dbd10fd04fd15ffd1b64
-f65b2c02e581175436150a074de43f8e11fbc56e806486665cedbcf387504d6f
-0687a13d668c69dddbc37adf91ad0091a770ee23850ae2fcbd6b9de9d8a8c8b8
-eccde66b7122c7b9602dbd0f6b7f7e4890933451c7a3904382d7801bcd992f76
-4cd41d74bc8723eba2647db7f813b465d11052e0f4ef593049942915c614ede3
-4f8f2b77bedec635eb3461d66cbfd4be1689a839b1feaa41c0f0fa23669806bb
-52fea1fa5ab524a447ef3cfea4583a7790baa418ff8917388daadc5a3d1a9fcc
-7f4a826c912eba5d4b82d4c29b639d56532b37ee9aed6bf06137a3af899c70a1
-ce4c9940e6ea87b6e274696c4a15d6aa3c17f9334aa84fcf1edb48e306640e57
-892b25e67c6f87e4e4cdf1a9cf12f69c0028b5fb768e839e1b8f75f3ab2d9763
-6e1be8c5a73bfa8675853695ee32887dd6df5f03f88e637d45f752d22f6c76b3
-71b9a514078c3200ddd2e998f33f1ae5c0a5fdc932f7c4727512caec232a681f
-bbdec1a919bddaebf5efbd06869bcfe0637b72cefaac13f915f25cd3a926c0a5
-4875435ee6a413e2554fe4ecfcb96c1b5d8719e84dd34939dfd7795eedecbceb
-786df32b6360bffed553a74b444a35e0ab0517cf7aa9c4e420e5bea4a5aac950
-54cfb55d1a1e57b58b8fb382e8ea2acbfb9b43d1ab67e0c1450ed3091758c1b3
-8155fd6996500a55fa5d134f17e55978d930425e0c03748364c46d3bef68a390
-649e09e48c2fab92108eef8603c70a977a388d4d24971296aaabcb932bc96033
-f648a6ada265aca938a6512f456fdc194f7186808deb3c16769d3faa850f78fb
-58610c776c2ef3f208404def2940e484a801cdc45aeac88fa9852d1319159340
-3478b1b7f204ff297b67bddf1d38e256f864d3a83d6919ca7db1bbb1f5b8f6e7
-8ba272d1fb28d760618dac6f5633b9481645c9b8eb3a3384518103cc68aceb05
-5a91dd8def04b49d363b0c6daf63aef5d85b1e79504c23b3bb50a4b7194838d6
-b417b0ccbcd95a46834f9bbb2ac30fb2d9b9c31cf4b608e1379399a95f8dfa94
-53998a743c5a5bf33ed1e10177dc4a2a347f5fa4d09470cb5d71b07bf459c800
-0119a2164b143f03fce36c19384a01cec5b9080491b82b9ff115f795d969f480
-b7232d0375a9d46faff31fecc9351b42923e9ab6207d2723915d7843db279505
-280d70d9c80a1821a257aec764b7e85a1e8da7c40d42a0f77385ea66a7643435
-e20af708470f645046bbeac12d840fe3260ce75e20563014d9e2ebdaa57ef06c
-0ddb55fdf6ec3e064312d13e25299b153169788e8a4decc095eb37eaf8e8ce2c
-cd7174f44ee8f3875c5a3de3c7ce22296e99c44628f52cd3d18eb9215c34e563
-0ba85b5fcf3a211021a19945510c7e39ab56d977f74fd50ba8a70def82fa6777
-6930390700b4636330a998b535126d610e8a1cb63f618d69896fb47576857f5f
-8926ddb4833966695a26402aecc48bbcadc04c2833afcedeee14254a9e77603a
-5bb7b9de3c97007901143a7901c00b77a13e72940a6507a76164989e71d91eb2
-3080c585be2f8734909fa1efa7fc6a2464d95e4c5051fb8d6065a7d9a453cbdd
-033626544b72108e4c4c087b4e4dd972893371ba7b8e8291ea4f98d03c61ce6d
-d56734f17a66697f2260af9b3f8b9a36717b490e1ce649d839a66133da7742d2
-dbcaa22ff915fcadffa0383cf34c2290fa42fe23128e29e7bb1c59e55b7ac347
-fe66481f485d7bd09f55cb51d208d0765a510d5f6958fcd3ff5a5ed27d06a02a
-f7ecadce4b4ac5f1d0210c5637f07382193d77945e249d2c4973aa43dea41dc0
-51cd72643bda4f749dd5846a9d3a7346d39f78eaad738d2d255df0f0cab5fb10
-96a0ac86bb013980dedfc84ddfef081700fc3c66b6d5a125c9e83df17d92658c
-10d79a8aaa222004c20aaae6128132c64f96a7a7c869489a63860c15d53f958b
-d6fb81cd165bf253d996c15295f7c2fc52c13b51aded1c774cb35a0ab258bca3
-ab438786ff7e648f42ab568fdd9cd598c52b5748b0c44458d4e0b8080ad19cbc
-55d8aa1a78cafed7bd41a864488d8ab0bc12f6689027c65c70a2b26bd2590026
-3e80ba6189672adfe377e9fb516cc6bbb0f2e341dc9e2f34a8bb00b4079ea28f
-7c8138c415306e00bdd8e71176faf06fac92e38e8e15dc6ec6cdb389d1a15310
-ca67408a9686f21bf6fbbfa7ce032974e2b860a3a72561508bcf22ede4122185
-b83532444134af2bac5ced1932c9cc06b70160d0cefc8f76ed1108b629e81060
-ce6c30e0bc9ac232fef7ab1c99e21792921bddc20f2afd3b083dba29641458a1
-1ba80613610b01543d336ebc45ae15c276c9ff18fecdc0cde3be18e044497217
-b9a812d926538fc42871f439282c1717833170bdbffbd7e2034d794eee9177ed
-28045b2dc45959426e35d30fde
-0000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000
-cleartomark
-%%EndResource
-/F130_0 /VXAMRV+NimbusRomNo9L-Regu 1 1
-[ /.notdef/dotaccent/fi/fl/fraction/hungarumlaut/Lslash/lslash
-  /ogonek/ring/.notdef/breve/minus/.notdef/Zcaron/zcaron
-  /caron/dotlessi/dotlessj/ff/ffi/ffl/notequal/infinity
-  /lessequal/greaterequal/partialdiff/summation/product/pi/grave/quotesingle
-  /space/exclam/quotedbl/numbersign/dollar/percent/ampersand/quoteright
-  /parenleft/parenright/asterisk/plus/comma/hyphen/period/slash
-  /zero/one/two/three/four/five/six/seven
-  /eight/nine/colon/semicolon/less/equal/greater/question
-  /at/A/B/C/D/E/F/G
-  /H/I/J/K/L/M/N/O
-  /P/Q/R/S/T/U/V/W
-  /X/Y/Z/bracketleft/backslash/bracketright/asciicircum/underscore
-  /quoteleft/a/b/c/d/e/f/g
-  /h/i/j/k/l/m/n/o
-  /p/q/r/s/t/u/v/w
-  /x/y/z/braceleft/bar/braceright/asciitilde/.notdef
-  /Euro/integral/quotesinglbase/florin/quotedblbase/ellipsis/dagger/daggerdbl
-  /circumflex/perthousand/Scaron/guilsinglleft/OE/Omega/radical/approxequal
-  /.notdef/.notdef/.notdef/quotedblleft/quotedblright/bullet/endash/emdash
-  /tilde/trademark/scaron/guilsinglright/oe/Delta/lozenge/Ydieresis
-  /.notdef/exclamdown/cent/sterling/currency/yen/brokenbar/section
-  /dieresis/copyright/ordfeminine/guillemotleft/logicalnot/hyphen/registered/macron
-  /degree/plusminus/twosuperior/threesuperior/acute/mu/paragraph/periodcentered
-  /cedilla/onesuperior/ordmasculine/guillemotright/onequarter/onehalf/threequarters/questiondown
-  /Agrave/Aacute/Acircumflex/Atilde/Adieresis/Aring/AE/Ccedilla
-  /Egrave/Eacute/Ecircumflex/Edieresis/Igrave/Iacute/Icircumflex/Idieresis
-  /Eth/Ntilde/Ograve/Oacute/Ocircumflex/Otilde/Odieresis/multiply
-  /Oslash/Ugrave/Uacute/Ucircumflex/Udieresis/Yacute/Thorn/germandbls
-  /agrave/aacute/acircumflex/atilde/adieresis/aring/ae/ccedilla
-  /egrave/eacute/ecircumflex/edieresis/igrave/iacute/icircumflex/idieresis
-  /eth/ntilde/ograve/oacute/ocircumflex/otilde/odieresis/divide
-  /oslash/ugrave/uacute/ucircumflex/udieresis/yacute/thorn/ydieresis]
-pdfMakeFont
-%%BeginResource: font MFECUR+NimbusMonL-Regu
-%!PS-AdobeFont-1.0: NimbusMonL-Regu 1.05
-%%CreationDate: Wed Dec 22 1999
-% Copyright (URW)++,Copyright 1999 by (URW)++ Design & Development
-% (URW)++,Copyright 1999 by (URW)++ Design & Development
-% See the file COPYING (GNU General Public License) for license conditions.
-% As a special exception, permission is granted to include this font
-% program in a Postscript or PDF file that consists of a document that
-% contains text to be displayed or printed using this font, regardless
-% of the conditions or license applying to the document itself.
-12 dict begin
-/FontInfo 10 dict dup begin
-/version (1.05) readonly def
-/Notice ((URW)++,Copyright 1999 by (URW)++ Design & Development. See the file COPYING (GNU General Public License) for license conditions. As a special exception, permission is granted to include this font program in a Postscript or PDF file that consists of a document that contains text to be displayed or printed using this font, regardless of the conditions or license applying to the document itself.) readonly def
-/Copyright (Copyright (URW)++,Copyright 1999 by (URW)++ Design & Development) readonly def
-/FullName (Nimbus Mono L Regular) readonly def
-/FamilyName (Nimbus Mono L) readonly def
-/Weight (Regular) readonly def
-/ItalicAngle 0.0 def
-/isFixedPitch false def
-/UnderlinePosition -100 def
-/UnderlineThickness 50 def
-end readonly def
-/FontName /MFECUR+NimbusMonL-Regu def
-/PaintType 0 def
-/WMode 0 def
-/FontBBox {-12 -237 650 811} readonly def
-/FontType 1 def
-/FontMatrix [0.001 0.0 0.0 0.001 0.0 0.0] readonly def
-/Encoding StandardEncoding def
-currentdict end
-currentfile eexec
-d9d66f633b846a989b9974b0179fc6cc445bc2c03103c68570a7b354a4a280ae
-6fbf7f9888e039ab60fcaf852eb4ce3afeb979d5ea70fde44a2ae5c8c0166c27
-bf9665eea11c7d2329c1a211dd26bb372be5822f5ea70d99eb578c7befd44cdf
-045a363056e5e1cc51525ea6fc061dcebb337208eff729802376a2801424f670
-0e7e6397b28f15bc10b40012b0a3eaeb2693e8f7f627c4c9c7c6c5bff105c1e4
-1b2b9e8f09253b76040d268b80719e1b3f5a55ab7b89290699b50c1bf1baeffe
-1f57be7b5ea025241a248a6d4cfa5067a1da6eba4cfc940599ba3f3c934d7248
-b8e4ac5816f0d2ce8b3c4193ce39d19fffdb75254573173cb51ccd83c2f2d06b
-2483cf9b07b21ec6f502f028c273887bb06dae2afac10e9fd3c7cf51bca7b277
-b706e425302dc78975ac0e43b87073257a5cd7424b6865fca89d886e8f95c4f6
-d457623dbbc0d16bafeb4c649f5d72b09b18502eeab687e915e9b536a361b4f1
-44c3cd4cc683b5f05a4ecb4823a5eb5179bb7eee8b76c21b2491a97808f6318b
-585b0bad98f42fb4a755bcb74cd354f794c8bea5b90fb9681bd5849d45247e39
-930c882490230e1662d39cca875bffeac3e79a78de6e1298abe9817ae98675c4
-16220ad0d3a36580ee2f2a17aaa1246c416d58a4c52fbb26aaf3b6f75833af8e
-3aa996218dafa571fbc7cad90ece9c883c813d8f168c5e86bbfa0f0a5cb36e35
-2de4caa0f8d3227f72c5056bfb5bca6bf9c60e037a0e44670a8d3cbc9a19f379
-ca8db30b711f518a8c7569211ac70c46eed2af62a37f238bd0bd12d60332e673
-c6e784b3eba3f2e71e9993b97e8a38f85048937e958f1cd8fc6e661048546135
-56b810fa1ff611b96495081c04542df7fef085dec619dc8c84cc57683d212813
-9d14728aa32723e1d15f2af8f03422cfafd8ea4c92dabfe00e6110bca39fc555
-bc066ef848e437b50688daf26d001aed7e74605ddf9c0ed36be45455aef92689
-8cf32baf2418e02118593f54fe1857807bfa0b93b5cdccd81d28bede22cda6ee
-2e32422c1e8da8866e526300f9059e85ca54122ecbffdc011460913e0d28f7f5
-fbc9d7f9f6934b3d8efc1a91cba4128f6bbc5eb55e5e7b73647bff70662bafbb
-145cfa65df3db858bc3fc577b1bd8bc74fb8a61bfa71b8304aeeb36d8efe12fa
-6f5eee0eae0830e5177dc745250fc362f78231fc3ac9864559dba92dda2feb96
-2629293435bf4a89f913fd15702cf325981ca3a08b327f7ee35794a9e88326e0
-24559b547fc6da61b7a3b9357f72c767baa9c79c4e7b77f70ec01ac0b8596425
-5f7346dc8cedc702d3d57b09ef89cdd33756619af59acb9d17a3abeaa6c65218
-6d6855348a1095746b34af15df313091c59e5bf9e79b156cd7903c1c42e115e9
-c5203037c808bd295195e074fc4a46fbb1ff01c814878f0c177f552bdc9bb698
-349d73aec17997374ec90b69293a064442141a44c6fe8e3c283c02a4655c579b
-f21b53d1fd37996c682745600785c7b52c4eeb47fa5fd640739e1f09d5c5dd2b
-b7515a4cce0a21281d315563895972bee88bbc7401be9e20cb160b6bc81ed469
-6d66169bdc648aaae8a9495b072911cc814c19d53b95de0071e3a439d3c09c3c
-1cd422c605740a8939487e26bb9233d4cdefcca49bbeb1b913570a51b2f96d30
-2ef8913c6bb60b54f7ea4b8ca16ad3b4194dcba28439eb31a9443caf061c4d88
-c22cec8d9d8d85d7aa225fd64bfae7376abd40f822ba1ecc9339e09403195752
-fc03a5c4742ad93064d975906ed63acb495aae324403d3bca118179e10256543
-1bc84d47e0c016234eec0c52255ae783417941cc884efadb63f8269876f00a8e
-1e1f19eafffa00453203a0752750f8c876aaf87826baf77b81d336ffc29249c9
-a6a44f40381294447840632ee59a3c4530391f35da45c16a001f793782be488b
-5e01d7f75dbd53fb31f956f16202d3d94a300866814ba44c79764cc25acb57f2
-333dfcf3d97a98fca949b1da71ab27885183d8baafc9bc743143f2f1002ad752
-1e55d207de23e97d1760cd918a55148e37e05f6347e8cc299eed28d7319abcdf
-a4a279d5f64cc2151f91a0be9e8382a35b535a6b5f41f3708169881c243391c6
-67d9121ba21f6bb22be1ec9933d9af1dde9693d7704c1141ce2b977ff5181299
-6a57f7806814440a28b1dfb62c4dedb82f0ebaabef3367bebcd43246d54d8eb6
-7af07b164374998f06a0b7e271ad6ea974698a806002374d270c6dd5c9dfd5db
-e056fe1b3d58482a0cc98d4d5603c59ec2e13b446023692b9ac2dd7cf767d2dc
-a7c62bb3578847085cab79f139bd312cb07ce13e38c3fb8f695bcf4021c282b0
-9b20ba67f378cbb8832751b8f3eed370a572139431b9187893b592529fb1b6c5
-19f51798bce9e56ca50185d42fbd85819c3a1153d65997511b19acf87e69c07d
-2ca1a7401c2b23f99c19f95da0df136472f9fb574b21aebbf0c2f892b9260001
-9a9173f108e72c3eb4a93719293e8be026b833cd709c7c05c1a2e7250cad2586
-ca70fb7d927e36a2e4a6f34e754c8dd8ea2571cd82054700d386cdf3420f37bc
-b6a70b9a92e46cebee13f6641c67bc40979f9b86e052164612d3dce7be67fa71
-b26ee9f425b54b3577cb4acf3dad02f2e55d2986dea88a5a1955b78c0cd5decd
-213c55c9c57183a7dd5832d49ee81724a19abb7da0779f1aa6a77d5d31434a09
-c6f53b7e27123dac042f58dc27653d940358bb8100b416b920aee20672559f62
-8b20c687d77ff83cca449e94fcf4f06614fc539802340619e3a791a18581ffb6
-9bb5961d1e70e55615cce5c9e1466d77435e486f15175cf87fff65e58127b5c3
-024b93c1c296aab24f29483aeba00736ed30be5bb5284d7afc43294b927bec1b
-86814a5ac25a3b9cd1f25c813cae791f937375e013159624a360955a58e8fa94
-e49593a97150702c71dd8dbfc3774094df930414ffc68cbd4b4a25041cb3b657
-a54c9bf780142d2586eb5dd9ecc1eb5ea69245d5d9c2af868974ae5d46e3a544
-74e96780ae66023778659d9a45853c24da18dd5ca0489ccceff253b009c06cf5
-826adbd0e8fcf23edd75c3d3de8a4c789a895e06d20606e4f8e3c1bd77976e71
-de409203ef1342bdbf2c11bbab4af5a709f0462aa8fa3a02cbed6f23fb4d5e3d
-1751acbd41eecd8571518a9e13889c221ba5568cadf730f9da026fb38e30a25e
-87ef6a13484d6ee31c174bfa4b80cc38134d7b18c85c83b4f14d3c7b0a0b7069
-7baa1a397252ac47b67306e45d64061535d05540c86b9599df909e105bb55100
-3a0271c25bc5d596da2a446e35c019b5dead7b289614bd5085d49ecd0464b494
-cd1ab564a93ac9cbf438fa558bbef71c2fe003573a03979a10fe8bd54a053724
-a529f46ffe55cec8d6bbaf1f57d16185595c82a1ef42e3c81cbc55bf50587630
-404b2090df6d9d25468c1eb7a4b2b3da7f5b718157ef8b5f23af088301e46411
-b51e6e0d464096ce22bbc2028488d9af49792b4a17cbbba8ace8fc51e1de01b0
-97e6db05466bf66978305642b6790c08e59a7055f9442cc2cfc23095df2c27ea
-decc1ba54d6b81ecc873a9c71796a1ece75765b878d12e4da9e19d026ac44dfa
-2dc7e540506546aac70e7b82ae7fa98bf36549f4d540fffd53abaf7ed9044ca5
-6b4e9044a2b23c3e7c70152e96f4e64f6b1918946789d4f703675f3dd6e8e5a8
-f0add5f7e442c35cc782c92db2007596ec1a76d2d22ca5b00f7f9aa9819327a4
-db8d0b03369a05de96b8c4eaec254cba0f39ef6ca005c53afd0ec32f1c092367
-efd9f773bd00b95a60523bc0392b050b15ad70f7cb42f6d36587144cae2447ab
-aa4b4d9377a7e86ac489685833e1c14c3e17638b00884a46c1efa2b158f6239b
-1bbed6fc68ff606278fd4216c2a6d7888f0f0e5dfc9950962d4964901a47d6cc
-2e3243e1dde9ce7f435a7dfb19349a3017ce44b87dc6baec18354a2042c87ed6
-c1e3a1a505cc679e32789f75780f84082cc653a010d14dba84da0191a510359c
-1d24d700c58e54718f1d85396e7c5d3a365637085b6f79c061df17bfcd260ea0
-6b8416c9042c2831eb041346a22bc54f9d7ba43f8c4487fc240baec20ad4aaa8
-c03f180b614c59db6e5ec1531aefc908c46b93419b9f5b2d4eba0a67ba43d685
-1ad44d4b43b7796de5c9a11f726a90fb1a389a342143f98f49237fb451c43eb5
-981562d923d684923dcaee71b52ab4ce6269169a35f545e74584fa440c41eb82
-41ab194c78a5b980d021b3eb7994846d963b78eb6e149cca7713c12f77023002
-b8a797c9ccd0c2bd70dbe44f81f9d274a5ff3824ee34cb4317fa4971d67d90a2
-f3d1b1b84960f0fbee40e6341c5271b5b945b9098f3095986ab7db2e0714cca0
-301f6b8378559d86f0b0d95c2dfe94ac8e10df0c8c16dba12505a0d467dccb84
-16bfeb18784bdc10624f15da1a880ffbcbafbed0e1c7360962478006db59c78b
-ddcee524b6f9b15a8849ee19aa00fa3f71a3c2c96e68dd0248a94ecc43a60ac3
-88e49e005250706880485df109ce1506c0a4edc40f5ae5fe347d52ff63b26c7c
-185a698e171244aa1095620494949d526276175a7e120340d3247cbca4e3df53
-641d6d392abc61c85a22e06cdbc89cf37bffdf8a79361c6dd69e6774772f699b
-92f7a7184a00fdd7f36fb8a08ccde5bbcab3731366c3b74072044d3ef2ebc1cb
-33118b8c09c04174baef8df1bb4a1e1f848c1a5178ec58ea621f6f8a63d0fcf3
-13db79f885ac659c881ab7e40798a4339e6a78ba27cd9e6803c3d4df196c462b
-d08555bed51d7cf5821204728356cf813f554517ac5e28e6c4047c0100610635
-7d25c33330758f71bd1043365bda5d1d9214c8b159d0f8fb69e40e6fb4ef4668
-a228938436dd209dda5925597151f8633297862799152b0317bf21f9572f503b
-b10826aa7f8d15f5d780ea27f1b8ca0ba3dd732d3e3effcfad6e6ad8769db6c1
-df22ace8467481d16e8af6f56032c90c8f2500ce66afb94d378d893e84208048
-ec0cf900507f02e40da3e99386f939e05d9737b0b11b7dfae473496d056be5e0
-7f1cd25454f4b290cc43d936450c3d675ceef5da533db25ec07addc7e8355d8b
-8abb095ddd61c91da2dbeac0574e9ec9d316ed13df03c997d7a4a9c7a6a3a165
-ec1ce316e820e13291132ae91660d5d1812146abfa137726e8700395b4274502
-7d53b1e5cba817beb577bddcb956e89aa2d1ab24128b9ae8e06d9f0a6dab93bd
-f7ee8e2ff918255c3722a8b0e8520dd02ba7c92aba13ebad9ce0ad0f16f728d0
-ad49bcb12b429811d8ca1b5ae29b7d5393401eb5802db4d4497cad43ead218ec
-c674f42143bc174c525bd736b77dc28bfc7e107366eb9091eeda60664a771782
-cb41506406dfd29c974c5a18da88b473ae58a2f1fbe5680a40138a9d2fb7955b
-3fdda23b2cbe7e27c1dc4aea3069b1e7e25068c9051672b8c9a3a37d6e6fdb24
-3bc20d303198f9b8ad8154b3f4a4f2acb17c31a0489c1366eb8a13012c6b8cca
-4d416b911de781563e26c08538e038dd8ef92435a054348add815687ddb99dda
-88f1e2c5887707cd4be47f71ab81a3d6cc3e039bd09697734840f8bd0b88aac6
-191c6db089943f99ee4174e5fab3baf3a8429e273c4d1a5140e0073f86105402
-3f60df69e65809b7a1a5a8aee4d25bdde9fd6d05a3fcf4be5f253e41fc49e121
-df89f259ba981d2617209b53ebd92e430a69668995961177b159933501771905
-08f625b26b5085c04b325e7fb6bb45eebe3bc9f5c5114eb37f19937635d71a72
-39a0039003764d10cb403b58c61bf411aa8f5d717bcff23fb338da58d13ca81f
-acb3316d2b5b675e86a95cfb525199a21af248a1245c92ee37688c6e76a95187
-3b411697a1ea6694e6ccaddef3d57114cfde70609de67972edd1db95d923e077
-4bce7cc77605f9ba5226fb792829b1b8eaa15361ff78f190a0563fd61aac4452
-ee1b0d293e695416c667735dd886d10e4467b613dd9bb899f2bd75f2f13193f0
-481fcd3b4e2aaec6cf2829b1521dd4b6471ba31aa0aa4d63a6456203896a111b
-89c106f1ea85bfe0c0104b1292a1f8d49334578375b55deae2d7381f5cfcc023
-5ddfb3d8546054a0e6d5d81e4254383385ba593a7d3a8e0beb34285dd95d97ca
-3eb598b643834644b611e6db4b8b4360c847120038768e218031e097ba0bdea7
-732f7e460155a496b91b3241c74f9ee0c99ec7adf6a87b701a0ceb07fef5fa44
-44e127de3e777c23a8d938f9879df1dabb7adb31247a53174f919a2a5a4f920c
-9415f3976a8f4b739e114b2c49d67bcedc1852686cb041e3ee94ef94d9f2096e
-76f1c558f40812444c6f0f4dac3a4bd22b82e32d8bbf1504f8232ef00dd2f3ff
-5c4b8349a9d1becb8c59a9f4763f2566a7a513a6c11f54d1fdc1867ab741f3c6
-e2b44aa95479e4e9813350473bc7897b9ec592f01f97697a17967d344a4bc9a5
-62786f28f87e3639d091922f4994671b22efd41ff3f6b8a651117d0a2a97ccfc
-80a69c974fb2ccb36dd6a4897bf88ebc67bfd892e35e6940e94893e1cdfd2799
-8cfcf2b3737a6232e4783eb4a8ae56b83ed7661377b30225a75a1b90b73079e2
-6aa33fd37b81f7d60de62931b6be9d16367a5fab1d14d281d3e8d09dc525f549
-ed03a449df4655802bc3265010f286df86602740d8a86aaa228b9c47e3e78c0b
-22d2600d5cd55a3116058daa7e34174144f78a8f72e0dcb8cc64addcc52df0df
-3f8c21d9cc04e187be53f8fed4f33633ba03afa178fa5ce769a7eb0e1b9bf5bd
-de0ea74dc99598a66696bf6d5071da995a30b8144acdea116cfc447255a99cce
-4ec01bc8a0b355c0881f6e9eb48725d61ee0b245e0f7cc35b9e76fe11f681017
-f794ed8d4c4c7a02e17bd16a02347f28318ccaafe0575734058121e3ad8064ec
-a0086a58f216020a2dca29376981a2595bfac2a0394d448949b52ffb47e5c5e0
-d6371cb4a417ac834d6c9fa0018c5efb16e39e32c85088b266d74af5630b2544
-d4cf403482c490f86d35f81cc44b34200400c10c6dff035423e725d41d2b5ee0
-c3f03a603a161713216af97036ed38ff8d9b09f189ad191a0d03369c3fcd5a3a
-f88a57338971d7bcb5f3fbf8735ad8459524d93a92eac1c2bf5f0e6e1cf675f1
-6d72b35ceaf34d8fac178a1dd823ca0448ee1fa2f616b803c38b89238aaa1ae7
-cb057ecdbad28147da46a34b8a1f1d389e082cc3e8eb1a7e5c0c932341824c21
-570e003d8c11c87d7082371d3d4804da32fde118c6c5b5b08828e5783200c6ea
-0a7ab73343f5fd681a3116fd818c7054a5199212eb0f3a9a0d87bc364670ee2f
-7a5081a1e48a58748d297e014dd5db7faaf7a27459f115741bf4facfa1b395e3
-e97452bdaff906af9c52c5908748f1e13cc85d165bc893c1eba728458b708f8a
-9e8990a6f258bda0989aad0959e7326d1d6bccb50c4fab15a6ea3cbe94724fc2
-8f174df93fbff41adbb9d4fac0124d33151d06753d4d879ac4f15aec5d1cc0b7
-a9e861f790a16eb0821b2a7b7b42d6f3e389c51a1d7c652859ffbe66646d4199
-a62ed28a30c8932dc4d2855e7e6311d79cedba8beefe2cd529f4b45382f3e6e6
-a7659da9b786fe7bc2e431ee3f11873ab2709200b715343cc25c5365d06be9ac
-829458ff77f4d509d9c3917237d759da6775e09c2eaf4ce966a14157ea2780bc
-e3249446573c82b33ec5ca150022a83301f00f41eea3694059b14b2a9abcea30
-65cfd06b9dce3823477bf80938d355427666a8287a65e231a2357aed80d27a61
-58140c2cdb1f44caefd6b629fa661440c361dde7817154052436a36bbc1bf382
-e30285979c4568b180417740a17150952e3eb4091f583083d75a05a2d91009de
-46da396794dbb5288e2a2e6191d3f22e335f0275f33e9af2154cddbcc99b149c
-6d7aad7fdedb23c805f09725b60b5ec77e8ac9953a3578b23c6023a196f35333
-a36fab2ca195e397fc82318434e9f2844d17bbdc177989fd8af61ddb46512d2c
-f5d7821941b18b7c1f1be16df6e6bed4a1655edcaf6300fa8765e903b03a95a7
-0a7e6d55457f451a8177e0e9c9f3aec8d174843e3a99ed698689019e96cb4683
-bb24c71e22f4895656acc67ecd671963abeffef53724a645b98e5d2680297fe5
-2d43ddfdfd5536f7c239a5092076512a2a9821f12338e388bd5115ff4f4d2c01
-d741f821874380838988c17bd975fc388a253c8c006c67963ce3c4404baa0750
-c56760e367b566ed129911eb056bee42f12bec9980177f1b3713068073cf34c3
-70d6ee202c49b42809afd1f8786e14a6c63794eb2ddf49d5a06f34de23356260
-96ea26d57b94a928e5312147ecc40bbc6a204c4b3ee9d4f4361f8df9e1c1ae68
-ef60fbeb99339842e652479362b19d33de080f9625b5c167bf2b11775929b12c
-fa9e9a89cf84f249a1078f5584425e2ad8ac82adc298867ebea1ec6c0428fdc5
-01dccde39e5fc147959ea254217153c0b550ef96c229664c22286a7827ebbf15
-c7fcdc57dbb5914bb0460b6e0c0f58c98b264925d9996d9e0d31fb70e66eb9e4
-d928015f2c12acdb7d77a66408f2767c05f93292fae45492e5dcea337cbab346
-da82c905ddb016bba5d31e740b813c3d709d78d7ac50326f90d2e4af4c1dd893
-e26f9767db437b52a758d6237e52c4a2a71624d2b1f79dbe83b6b7839deb413b
-f34b91b3dfbc88b7b0b78ab579594ac3d57471074f78e59a64d75b4e6ed3cf22
-33f6ebc86e289402dea3907b0a2406188246e8e44054f81854dae0fedaef8952
-c05c8f5c4591673102a0f24f7deea7e19e27863a27c00b510690b331413df839
-5ae5a37f8c6b25082073bcede7c8ecdbbba2c09467afcebb48f4a4e25cb069c2
-b7acc265f988955a79ba95b3f4d8c6cf94164941723601923409e9d81ba8aeea
-64e8f1f09794779a1262020bc301b1966a789fa2f37d7521db536c0c8da36b7d
-906398a8a41230cda975088fa5a6070d88882dd8dee7af696ef5ba2c5a525d61
-d35a6834907c4846cfc69b17edf77c58e501a0600a04ab4b36d9007ac54ccfb5
-14a47193ed01d4fd5e3c8cf04b3e38c4895de3eee14dfbe6351bbbea6530046f
-89e913d022c0cafe528a33c4e84d465fe6fb031b48d904c5120d452a6c1fdfb9
-08e242a05d015a9ab2536dbadf0ffd0190d355edcd3174cfdda0974e2a33cbfb
-2a3d557ed2f6f284cb3c990c3071b7efc678a5d27518ec1912cbaa890dd6bbc8
-824eb1e7ac6127a67e68428ffd67e650fd44c9ec448a309056ce45e4a4a2b769
-8183ac418981f617dc469a566e713aedce2bbc7cdddf1f7affc6d11e94757130
-c4ec7b55dba7356b21e5267c5ed99f427a19daf476e48993e856c852d35ca1bb
-b32d59ce688ed184fa9ea1622c306cd788d6372c5b4a94b001f198e33209bb59
-46af1ef7b066d049825bb78318a38ca23ec9a93bc4b4b12806c1a0e5be179e3d
-0c0e5bda654e506e74e0ef1a8b12c18bc3f041d5e61a8f03436f146e4daae3b9
-6b8c7ae139f42e8dcf772cb5742104aaf776f3dd19bad920df77b42aac654d32
-2de3779c42639b50059d13b81c3904df76a0ab47046a0132378f9201359f71c8
-12eb4837bcbf3f1498bf8c7b2298e6b2e528f9898ddfaf75b5358a73a67e6307
-707fb13b2360ffdc5659ed8e70ecbab711d89f8c6558622d67737b1108ad5139
-b126a6c7be8b25709fa7cc2a625a0796b7d08b11f098edb80f8aa08a5668ae91
-4ff1c470dbcc7775a73fbd857cdb9a5d0c122d4765caa8d9d35514390c9b339a
-c04a78342e186e5c49dba4cd9ab165b4c139e76b88c807cc4b5db7b5063c2f81
-16721670497a0183c643c5a70ab2405d5d8b6773a4a2d39b3cd0d763c12ec296
-9b3c3ab916656fcca5d715e7dac796937b2b6d4adb251fb79b183e6eab23796a
-0bd0bf5bcab03529467a265781716b0186573b862b2a2057c427d85d7b547c7a
-9e7fdf7a674587df709ffd0a63d0852ea0d02c13e8038762de82362739de9ede
-0db4296421d462d8286e2152aa67298c9ff511e8de1a26089d383bdbbf27066b
-f322738cd2cf198bdefe566ced1808dafc015c8ae972117776594e9c506a3223
-d4ced495d6229c9bec17c47071415f80482f9ecaaeba6a135d2173254dde6be3
-f0ce9a7a81ec2e9af4add855b08309d34e780adf0f7c9029d2ce0d5f807ef0ee
-531217450c82b7f3643456772549acc2ba6a5938c517fd775114ed44ec69a45f
-d9110c969edd9e6f8b4bfb953aed79a1daf47c7238871e4d537100c4d8981d82
-a2344eb7df5baebad28e34870d52d97a66dfc75740cda6b403c1964c0feb034d
-d3e5c8b4a37acb9f5718f7b6a3d267694df8baaabd38154d16c162ebe43b473f
-ec1f060846ee8402d67942ee080dac9b18eb8b09d384ac24f85d287ea3e2c59a
-0f2c1d6bad36e262e031acd399a2b9a7940908d65f142fb209416e891a6abeeb
-389e2df002436d43fa1161b71382d1842788af1a9e6f39ed56e8bf63991fa790
-a52ce312aaede90df1be57e3c1151dd0350ffe7e476cac5f34cf8505bcbd25f3
-29aeed3a52bfe1f10366dfc4a15fe212b1cc9da76c8272d7ce85c2930d797b82
-4a67de55c50d45cb3640db2a79ecb647a2fd2d948114eea9bad6312319f8db5a
-a29d60b22439d45760751904f5de5d8c5c9d0211ac9d30b9459dd05eeea240f0
-97f0c239068c514b8213609014e6bc50633d0ecf774c210aee7c75a5bac24e62
-813181e4d040ad1bd4bd4ec7b99b8a37abd694cb67483d1c5dd5c17f54ea7f20
-50d0ea8ce1cbfa5395e62e10c5d17a423ac76bfba25a38fd474b5b4117ccfccd
-30a2ffa484af429168b1b5679b67542755e989b39387fcd9b1d8f8ba313a758c
-58641f34ccbc8f2556ad1b17c33f601ea76ac75ee6b681aef12c0712a14e7b8e
-a8a5bd316223d5142e8b53a6f81a8a608a3dc32f20c5e417a6aff0f725dd7867
-429fdcdc16a22ef6112fdfc5282c61a1aa9b134c1b420de7b359be8373cf3716
-d7b3ae832ec15e305ff6c8e9d4197f8b0150b30e1b9e7f15275b4b7a65dfc611
-97c0e5f91561f3e6203950edfd6cea20d0649071442b2916ebce5f4d3da73914
-5a2bfe6d055580af134b7dddbb9baf9477454eee8abc7b33eea500102e395212
-78d08c08ae455bc0fc5bf5a0a577e5f5fc71490add5a623ccca134b62c19d3a6
-4019415ecee0168621be2b4856ef3b3944c0db9aef7d3e933a034184934bfd4e
-3fe21d4d2625e6464e9ff9cc25e793eb7b8701d3fa07ff9a3020f76d668d083f
-59c6f6751179d60eb17b9c4e35f3815aa5ed3793a2030d317f1610215fa920a5
-5ff29a67e8e6f186f00b5ce164677eb1961eeee35b5a7891d4296967a9d096bc
-76b0d072eabab7ea758da89fbdc25b8261d9fa08099b6e84494fe034c3edd5f0
-c45e67ffe588b2532efb3dd1c34be9ce299712eac0e4c4cbee6f30e958c9dea0
-15c5c4fef7cd440ea982f91c07928463807fe07f27ef61a5deefa47879847835
-d4e50aa1dd0ad2b3d01069cc7b4741b3f680131f7d5cafc6b3978c3c1d608ac9
-d24342092746628cb71fa01e3c675f14463f9edd4c339ada41ba4b6a0faa5117
-204463bc7b94d01edc1b3d5781898c85516617f29b4dce2d32c2686ddbfdb838
-f67b097be600f6aeefb6eca5f729b45be307232f92731c10c3330672c9584141
-7192e62a0ebae828fadd77bfc2ecdc1e562daf5660354e0edd5b7177bd8e9d24
-f77e526e649044cfd49633d48cea64de714e59438ad980e0b1ffd51ee19692ed
-665e2ff332bb54bdbf75316c4b1a39c538312fd649e8c462994dc8f14bf056ff
-0804de76474d0ee084e363c8b7081b1c08e252e05e49679e6c7ac81f42e9372d
-e5af64f59c4fb62f3e2e7b16ff53bbbc006e3d9b0f29434db5a63210944053da
-ab56b1075a0c3832220752d104fa1770d3acfbc31704a1b7852c077058f616e0
-a4373c1c92c7b60566691573502e9a92d583a3163bf31fc100c92e6405ee4d54
-09d23a83225bf6d1de2c7bead011ad64547d6835ac9a7378033c85592a0c3497
-a03c16190ebdabb792ca0bf803dcbc3bdf0f7a571aae00f596ee01eb476bad97
-3a27a219aafcc0fa245c6731a2e8e561c63b7bc3147b9433a8203fddb7138b0c
-1611c7e62375f2a114f7bfab36cb1a94b9e10ca63833ab245af595217779bc7f
-d12e68a65919eca4fae72f755669580ab0009452bf086ea835f91a0d5b384b40
-82bd515f006865bbee2c50db43b4457a793693806b86f68a2b2419fc3e937a72
-c6f414de148d2a62a71ee9fcab710d6dc08ad6c4ac443365e7a78843f80cd769
-c56efecc2d63487b5fcead1aaaf9481a7361723388f5b51c2d9cea90486cb9f9
-79f6f5ee718d4a49ed91cb091adcbd0e7b3ad963368c9cde877666a742cf5073
-aaf79428b3095f989fc1fa6f5ab1d724d92c33c1325c05a39423b8a83bba9359
-97793fda280740aeb6be3193be5f4feeca2a8f28efa9c8e016f0fc87c8f3392d
-5715b9b9a7aa3c61ac84461e2c3220372568aaed851f1cc40481e326197ecab1
-f3cd792fbeb27a58a5f889a5f6321473148c6d311ca89be96039ac9423700d87
-ab0d7e8b89717d1a62ca14e01f51bd77832bb6dbf76b201a04d222852050cc5c
-c6a4996789a0bfd6ce364592300282f102e66f4ae9e50d60d886cacb099df960
-c42e2213017c567f27326e677bbd04a239631950b566eb39e4f675d2e989f56f
-74da3a0469d988ea0122ecc3670d458ad82bcf7ad04bf3ca9b00d76ee569f98b
-a375285a1abbff253b8f179f71f496286330e364049c72ecad4d82a933af0189
-03de5e4abcfc637803167e56911f826735a7c41e7936f4bea148397bcfb18cda
-fb03182ed7c511aa9de0c6e6c80b24cb535f03ee16bbcb514d65ca9ac2ef15c1
-aa1825759fc4ecafc7c0d9401f139b3f20ee915955268578a933b184a86f2017
-03cbf4db79be18c09c8cb07d85739b8653ad37b8c0b647161e5cac746b3c0b94
-2ae2a0540f38dbee122cad0cf739ef1b49b6dbbd5d08c97c04dca33030f18718
-583337a015395e1fa932df0328c7ddd9546b7812ba06d82a35f8110d55fa377d
-fa6880f52645890d58478e4ee3b72f08b2d7113b2453729b37e4fffad13c5f62
-06b3c767a45c80bd479d1e24df660e46c83c48166fccec13b9cc4e62a6aaa813
-7c424885f83d7647b80849c0a77bed562f134034cda9fd6e8d7dec9e43f0c018
-9287de759676f20005556cedc67c31509a8bf56a5c972b5d247f21d8b6a58953
-7d92101841166d7781d4d80cdc35ca382d8c2dac3ea3a34f93dce0ff8c76ef12
-390d5d57d88f3bc00d46513f0358c43a22c413d9a6ba6b3e13913474b9e53bf5
-31136a5edf9192965aca98e06316c05fd3d6e88fe09cc08e327ed027b81eb146
-63e3073ea5d1d59b74149c5f5242d3cb253c36a84cc837d76b2ba36104aef0d8
-f9f4404d63c42f3d635dc9195ea582b589cb5b54ab01af9ae53f3ec95992c09f
-a5bfe86e6ef6948bc387730a9cff0cdd365650aeaa5e1d52d8f88dd49d36e6f0
-786c7f4ef8c2a5a242e84cfd4dc50adfea0c2ac27839699b92fa8feb6436f2aa
-d02710777083723ca7e481f83b637f19ffb7511de223a0a261324189edb38d88
-6ff5cb1356e8d567afe76f96cb72f88016e39e99af6aad499ac60c8a3205f253
-82c0312e1f2b6ee7b37d178bd4e67550276a7421b4f514fd293ad32bb1121234
-bff93d2297dd32dfdd7e7ba91c0544f79dfea965f4f67494f3ddd97d7881fcfb
-20ed71f6b5cd27b12d04098a9293e273148590fbb65f6fba63e7bcf14dfe6f0b
-51f870be20174f991329a5ef3d3c9fce206799a01ca102ee7999c2a97a19e796
-bb5f88922b76f922d302dd833ec532022b13ec573b375cf75e49718b2278f2b2
-4ce9865f20902d6358440efc9eab6e0e069ac7c193c88a044cf33f6a39388f6a
-296f42c637533cc503adfc71c5f898c408a7e5479868ebd29c9ed02939ffd49a
-2812baa355be429858e0c6aac60817d684778b71fb9a73e7ac4fcb078bb1a75a
-b425ea09ad8585ab3fad79429321a8f96e2e1f02ad70e2fdbeee625bb434b0be
-f8eb957f817c5699c7293e47daa4ead6d47f00fbb6c8674ef1f7729cdb19749a
-ca9cd399a4abcf28ff71edececb2a955ffbe9ebf4bdab56256e7cd66304ed4ab
-1b3fddf6431296aa641a8795a4006a049fd3b35074a865c901636b70619ec26d
-aaaa8c8c9060938337144209f3e3de01e92293ca89583cbb4c2edec074bb4c05
-15130c3ebfd78dc687f0ad0981c0d27fcaeb28f470193ca13d98277dbfcfbf38
-f8353dbd04380abef7176b0b4199d7319ebfd88ece219ba6edec59fd158987e8
-9adc035b8fb2141be0e0f25d56e077e5992e4f95640abca7aeac3d929be02d40
-9a86dbcc043637c5e0f1a5a12579e57b042b386be96c9a8b3c4e79c8dd28a52b
-a1159728785a75f2e579b8669a36a9f9e7807ff9d5aa0d8652609a47264a2003
-fd202bc8fe9cf80e2ef05ea5e5fbae676a77bbdc4308ab92eb0dd9a960f4865b
-8305eef47abc2353287f52c766ea1c1b86fdacf0986e56a87462ac820e61051e
-7f22cd8ea7dcc7838a45a08ea3fec105d80fe5ee5e87732bfc2e9d664a7ab43b
-05321557d69ceed6b679797a67a0c38b9d101bbe870d746568325c52d4ca255b
-b23f9672ce2b4e3fe944f5dbc388e575abd897d969ac2a81915e3fec3d7409ed
-14de1e4cf7737b6e46f6c71142db06a799a7208539c649244ce73a58f2247e81
-4f241aba74d6ae593d47c227137ccddcf1f523a730a234c91ac3ae8a456cad1e
-91a9480c438b047be40bb2e4038f8ebc34ecc3a8037454b7342c317871fc1d97
-42f26e3d956da7679a072cab96b27fb2ddf480d2f40ed88b2e5b0b82892c8314
-cec9bdc12433159714891b8591a051cf2cce7580af74d5096f53a65347488bcb
-948fb028f310575d3429123ebecd9b09d83f30ab8c8ab65d49d691fac27e3612
-66ea08634f4c7d3a648ec068c2cf31f116951934864dca2755daacb6d22803f0
-9488117ef66e9b12663da9d00a3eb0280ba412e4b6f6397ee7800f250fbfa023
-3162addcca4dc23190a52397cda3285291842a2b269c4e07f17a0035fcbe785b
-6a570e4b75692658ed47b6dbf297adf1b3b164740d1e851f08deca9c05a263a8
-3364c544cece706e77a32f6d5d10f8d4170d5246d92c2c9fae457e0f5e4ecd4d
-08b4edfd42a1791cca41078d5e520807817206193d8a649eb39b64c80e126feb
-240e1784da3c66378196828104c49e5fb86475a80c21de71e0aa36ac5e529ade
-427c03c2236db0deca99c7c486ff463a72723efb519263916e73c25da625d0fb
-e45258ad2abf3445b72cbf3e7e64d507198f666edec002e233cc0af6a8c1095c
-3cd232e2ec50b2ede3e09b61e25996b4a64c0eec9d55025b1f47e53e0b128bef
-a34646b4e2c13699d112c958590058e6b606cbd978cbb0ef69eee350bbf71ff1
-8213a42d135e77e2c53a8121aa3dd1e903dc0e961810d103bd70a2b448f29ec5
-c3d907d7243d76c6ae04c22a8fbc6c1a05f9b9ec97cbb0e76928f4aa26c913e0
-3f8c371efb61f370751eea6af25a3df4ab3da3e4aa263c2477343e4b19915219
-c4c52cf43dbf373c316b80619f479d9b531e62f26ef9fc6da13e9cf0bce74d13
-c2832f1c9d9432437d253dccf73cd699342521a3cfe8f85ccdcd23e9b240c961
-fce15ef77fad8438674b55da638df2492b29fc1a003859f382a776260ae5067f
-93dd176181c10c4a45e8f237c5c9781e01d2e1e0890e1a6e75e2bbfda4d29613
-efdcdfb21317d770fa6c1ac3800f328bdb82b48b7320ddcf64add23374971af1
-50470fd002c01ef412c5bb4984737840da5c9e0e4d4b2b7747056a3865af6db4
-f4b9cd84d27dd2e45aa0d9f32d0cf58a5f1baa374359223cfdd07c18017660a2
-9227404eef0abbd0e29bd8698752e85448a5c3cf596dc805a87ff903ff890e48
-b7971764fcd8f921eefcc55b2d20cd5908a6fa35d56bea96a39ab521d985c50c
-4e0213b30325d295a00d32d97e95646867122dbef37a3c866fd72e2f29ed8758
-a362a4f17875cba8be23d04a35714d4c27c4417039fc8bcd25365c8a4bb41815
-ce1f74949d6b6aa58fef0c4cbb8d54ce92d65d0a65f13ac6063de4a55ba5561d
-509f2fec155b2181a169ecf14f1fab587569f260c0cacded8021ed8d7cae5ad1
-332f1061e166686b41277495597c16e728d6a8ff49f824df503a63322b442182
-665a12900dd48d1361342575fdd5c9d9ddd7bc73a937b2ac6257255414029a65
-9001199e9e1f16cf3cf876bee000302935493ae997e3f112420d7d3f06739b79
-eddc1bf7ecfc5316549d2ff228a4e28b522d6cfaae3148bea2755a45bc27dfc5
-128a9a38777cd3b07f91edacedba2565b55218d7891da863243cf68e7800b82f
-0341740a1f5dc6dcf0125cda844867fe4945326f13a954430753a28ea8491bdd
-c545e71e4d52cabc3f05dce434101d36a62328c5fe6b5df3864f9f5aec22f399
-43f72fed081d3724306477a06eb9b6fcc9faeb77e62ee4e20cc51600b1bb081a
-1c5a00e064d5755838b251807ae57c85675cf04b69a66bef0c19c364969d3547
-55efcf31f8ae346582462e986e3a1d653c205e5d58d21de4553832c885e543bd
-11eea2d3c08f883000966c99281251fbc2920917700037278d4934f3441dd535
-bdd3c52111ed0b282ca23cfa97ab25c8726acb13d50599245e532432572c35ac
-b9391685d9e1deed1f95fcb151594cd63e79691b5972ba2c3a0c0a2ffaf3c9fa
-5ac47d9177a691742e4634db6631c8696d0a30bce1d86a4fb737ab85296ea479
-fe90c51cce54d64087bfc80ae56abb5d04f5516bffb681e6b39f480767f2120e
-97d1e8488f1f540e2ebf63eb74596670f5892f4c327971f697c7530778c3676f
-2792289cb12486935c447d4eaf4afec65fe6c6962306449e33fb19fb9806f87a
-8b91874ddf3e3138481fdc711f0954d73f11fba39efdeb55ed13b16b932525e9
-9f3c86ae60f9096efd4968759def8d629ff2838decbe4c68833ba0d64d1d3330
-b84cfe8ceb23f4b5d55aa5a9b51ee595aee0cd668b20c687d77ff83c803ab994
-c743b43d9882837c42a58cf704490fddcb5646d48cfd2e30464d710c1440513f
-4417dfd66d39e0fa6c596e17d07964ebf2caecd0a9fd78e003541ba53468e719
-b7dac2685ccb9b7d857aff1d4432a72f61829010924781f5d15ffcf8d504e361
-6f86c6638469db4ad281d8ec365848b6f7ae1047114a2cd3cf3d1e46e0b4f40e
-1a8d3e1df1c1b677702d7fbd5a5924f91c726de2e37b436250eb71610dd82cd5
-5c049fd044b4407784fd83387eb6a788103430fab4f682294b287dac43f3061e
-d99c74309ae973bb998bbb2a691402843a1a28ee62ae8e8baf4d645d156b94ab
-34680095425ad8b4dc27289e3c6818d6032f91535459d7595b2b9bfc2f44e782
-30f0af49c0a2223e1cee9e1289f682ed5e8ea7db99663a234719667bcffa8077
-e0118b0b9702538421dfada01d97d7a8f232464b9fc209cf278bd5fef80c14be
-011a9f6fc78dd20ab012a30780db2507f4d5e1e493f30814ab1c70cda75ce959
-b5d515b2ee8640dd4bcda6710703a9e5670abadae856b86ef8e4143a5f03fc16
-a6c57ac7c3a96c50e45191b0b1c4f6acd622c400cd0f2ae9e9d51236f1b945d3
-71adc5feab8aa8422a28755b63978aaff787158a68c26fd29ab6e849b076b852
-2190caef1a86663f4e12cdf25ba7bf882ef2e0e21c77c14fdf940792d7bb28f8
-892a9ca0bbabe1c70c152f30f366bc86b5bb1eb3b54425617682a5463238c999
-aba3a7bf788a297d2a555dbb218b19ce501aac43d94a0bb6ae290628821efb0c
-84ceecb30c140917a458db6fd011f3cbfb4a1cb5ea019db628c106e2a55f1c13
-448edd4a9a159ebb369d509da296da724f729fc7560c00c41f4309e32ea6fb71
-16f62325a5af317f106a8d8c2c01ecce6775d45fdbefdf6925e9a44604dda13b
-27cc9a960a21eea2af9bdf6b3cd357d6097ad40df7403005746a30833e814eac
-8db72c383fa42ba9fd007a263ce3b74c1356bd522d2611e4e960c9ff5204d46f
-ee332f9f134e75c791a6d20923ece8d4dfedcf96ab45dfd751739dbd47b4863a
-f0fda172848cd279afd9fac3cc5744c1fa8a5fb4955c6c1c952f56da06430aee
-084507664f93c71d881b63041cdec58306100a0e8c77421d75679ce33e2a0a63
-ac2f813006cea69e00352ffd5f5914b63dbad5905a590ce0903ed9b9679779e2
-d9da62f478768776a173832a8f3cd66b6b62484d190baf2d834241000b0eec79
-f1e53b42a74b159bf781ee4415ab6acff86c5b0593cf463bf95d8fa82293a548
-84bb226f40f24591e5ad463ae4b672905e7a4222edf976e8ad889e71986b3818
-bd3eeb6a0c96787c6fdf3a4faed94f0ba0269fd082ac451531e3b0c01f996090
-3f821dcd64642868f07aa0feada34088a85e6644ef07f4402b4b293073e9d308
-bb298b0e44be36bdda218259b4f48f1b638f5007d3aa8ece802b485e7e9075d2
-6ec881fbdecb3cf58c8a3afe0d9835e7b468c648e52b2eddb81dcba4e9678bf4
-b173541dbec382423e80877ba2df94a605bbc2cdca2b76f74d2eb425d8191958
-804617f21172f397bb762aa7dfd0485cd020397a5d3e9fc9405ec7edccbcbdf4
-295a0057b7684a701bb7ea01e8978fb3367ecd089be19aab2828f6825d275d3f
-60662c1e2ec5e98ecb99a96d6fe379e2fd158a7106b2190902f0ed71969b6daf
-3f9e460f16f1b40cc2aa08330b9fc2e24802bed034b71de445a14bb33f642989
-4f76319eddee328319ee9577740fc803b81714a99bf0a5722981427ba0858546
-c0f77f3919070060704c3bd991d94909d2012146b88c0d35fba7c2de864e35b7
-caf0099c4630443625be3769b01526f3f0c8c821da9d546bc258c004a4d2b46b
-886f1ef916f50d3f5fd139e0570b4151dd41f1f1b5dab0db7787105c77b86901
-73c562d3eef6ef741078659467f333450d7d80c67c91a26ba8c77adcee6f4c56
-c7f248dd92520db35768e703f7bd171f9e663b9daebeb9611cf48425b6b35c1e
-8bc7a0b45441ad3854ac9b37061839f578256a8e41766d1a6b29a99a0195620f
-a090d0ef4120667902b0587946206f294b78775d60ebec668f6e4fb9ca897e85
-76151b245aff8232a90f97a5a93e935c88579dc0f2e9da7cbd02426b3b15ed50
-30acf50107f7b4d4e2c32dd75d6d8c4539176a2244e761ebf1ffbf97d336fdd6
-ef9cf138326e10bdb57638235348eef8ffd33c84b426ec1c81fd8d4a3907d52d
-1ba7e9b64dd56b8fbc2362e30f2451b69b0d7cbea1f3101afcd44242d3ff5b66
-89a7c05449b281035e983c6b8c68859734b232a73996a19d116ac4a94f7b482e
-1f984371e7e9919c312250c35f6f7fee25ec23e562dcc25cb29ea79dff0e7c8c
-fa19280288c26dd5c32f4aeb98c85afda533191809267f0555498da5688b7c20
-219a058efaa597125535871922ff9b20cfbf4c4b35bdfa4bde73ca8ce6abf14c
-510ed2072a01c8adfada0064777509d4f97bd2baf66e7151ade76e407066efdd
-2e08a15790c81d545b340019bd350c7b90b36adc8658c1848020a77f918e1527
-b3974710af503a79d7947dce93bd81161cd7e0b1125d2fe0edaeb91baf1279e7
-312fbed646472b352310fdfbefdcc4c20ccfed0d6626083b0261d7c47d966984
-8dca4298b9ddb58fe21bb391c7d45d9b562d38c4dc23acb5aa87e3ddf59ee238
-c91318db2491a24110af90539a16940141d1efdf4a13d202f9b9401bc89d7297
-5269cd5515f9a6186a6ef866cfa03730f726d7a4075e0bc6f094e9584a84cf1e
-78489bb68dc09ee3f1356f4e45b8621e06078a6727eb72c36fca805213c1675d
-4365255d90164f33ce6b2231113f64fdcf5a789cd61002b2a38d2ca5bf1f5361
-c9ae0f4efb51337e344fb7ce15f8edbdc9ec82a9435175f59b6c19ae2dd0b10a
-944565e4b14bd1dcda02d42be27fb9f0330636091228e3b89709c8148932a5f8
-c5ba5bfecfef6de83eb414adc613d8534c4e4528d934c37e768d08e103b8ed2a
-e1e49bb1b3e6cbcdc3ff63dac7994b8c09203d82a99710449277c20a34e01538
-67c5d5e6abebba650c441d3fe56de997e928193682e5f1faa93a5bc800862132
-ed3b6c005cc0e604231e3e61d17214ca38148c875c268a861a14b54e659dd932
-cbe6ea7109b273975d6ceed351f0b0876a0b647946d29097dd98b5f6bda7b43a
-e6481f17743fda503b34a120c8c06f4798c1fcd4e521a30d76f2340df562b63d
-dd4b27da8b583547d285f3848bb9fddb60d0ed22a4cb27a2784e8d7662e84ffa
-eea50afc03b0815b72bbe9558c8959d0ccc00a8c8c9f740f95b671a66dfdfc68
-77fac12c1995d977495c9ccacd924e45a66f8739de156ee6962c7930f8aac374
-894f8bc396ff69f2249392c7c4248f9cf9ffff9eaf635e66a34511f39a066b88
-4866e776b8d6eca0319f23ca604ead742bb6f6f3b046454a1c0fc242551112b5
-c745e9b8f12723867b2b895c0f93c99df1d542b86c1c9db47390f2d6c3b57ecc
-66b1a6ab514a47fd9aa6240b46c54a92fdf80fc44eeed4b8a136fb88b1fa5b9c
-a2fe682cca4d0c5a3e994cfebdc270f48e3af91ae6bc9172bd9c73053a761364
-6ef9e68ef58c718a478e7d81e57f34a791c26269819c78574d7cc12632684219
-a1f8e1c5ce8b358d6fbf23984e59d9533ad310d158ab5baa9feda08717a7f5e0
-57684c455a7e3d833f82b4e13e9a92b0b8fba5cdd72a7e46709074ddc82e449a
-c906474441066fdd9cb7f341f3a2ee9f2fbf5e4e1a350a45fcad6b2e05825b6c
-89077d742619cf1f8434a3b5cc44998176667cfd5c5f4ee51326d1ee3e449915
-00bdaf57c88a107ac49c14cebf18d010c5b3206ec88fd06e3c5114581ee5a5e8
-c4ee5a5c3d48653fb23d28f26862c433ed083af01ed3df8e147548f9cdd882f8
-ca3088106b9c73b9e28786ffa643c343a940bf850f312666e635b8db95c6f70b
-83d645fd947f6df322d26f8f9081cae71ba8b9d0de67d535b61146c956801d6b
-ff9a69365bda9bc97d8d93142d4c367d5255587ada25e4fb061f8e430f73d2a9
-7142d9e4c17435b78805946e4fde624ea5d9b5c511c9afe2cfaf447cf08235b8
-575ddab8af93588e0c8206f08f883170ed4463da31a53cef67f01aab8f645acc
-c2c764f24bf831dcf005833ccd1296025368b3d51a04efd095fd1355e93de563
-e71dd047ef49f5bf8c17b01b2884872257d743ac6fdd8f54e27a241d7c75b387
-a8841d8cede676e35d4f01acba2acebd8b22113bfbef80d5eab1e8cf56f649a4
-516ec097872a597e83519fc1397c7d4a4f6db7daf044835b17d085578f5a3776
-fd5ed9235c018354e801fac338aa7ee581e97d91df0196ea4bcb09f0e6f2e2bf
-b5470827f1b6bb0b7133c19bf43bbe824ebdaf9526ab15ff8ae8848bf0decb3f
-cfa7d3f5ed71191894c705a27cd9aa30fd384ce6a5f0bc51c5651dd2510a3481
-d086aa87595f885c4c0afcb02b1837cedf85c5e64d440e36581874a117043b75
-78da94a069cf2bd57ae70c230e8d1a0d4637223d14a9868835d8923feb404323
-43c22d0f0e8201c20247c78abf9267915069d6471862c2a0c51ee3ce3153e305
-4a4ec6ea52dcb55df358d1a0d8aafa79fe08ebe4d22e9ecb9d2e50a7f367cded
-7169f84285c482fc1effbde6feea424ecdda2494127c7b896dd05f5e62f5fd1c
-031de960d6ec59954e8405081601df741edd97f227fd426e0998ca7b9b498beb
-4cda9a16715cb699c46d1386469958079ddf5ff174d70338206208f0b9ade386
-03e8dcf31e09f44976c1ad762896a615d9bfe54978b7c3914458c8af4d33dc62
-9f9af5171df3b9e548b24011ec5f02e31dc379582e16f3c999f047b82e7f27f0
-4bfdd827c9a1d19e4230695d4ec499afdb6147146cb6f5a8a26efbd6d0c5f205
-34cb9c37fa4c4b6122f55bacb756173282abd6a2e5219c25b86a5181021f0bac
-6f17f89f3b8f74c281aeea7c1d4ffac602c2364c9e1ec8b0a623bd3541765cf7
-aa5febbb6e857810a564850259ac4ce6d641f7b765dd46584c43c8113c8583f9
-e7763d3f4f83649e12e15557f48dcb0a637140b2f7479f78f1f64bcf8a07acc0
-43b9d9ac1f8b2c3b00c36b46d8e514c998fcd47354b364e8c2434e774ac7098b
-24c3bfadbaab5bdb8ab0a6b9773aea4175615241249a2a58222df8c53c32d01d
-6adc5fb4a933605fff98c7d011266380b305403a79867936156240a5c555105b
-95cec3873530fa6d37e8cfc286118a9618c60d6282412d0ccc5a8e3af47a42ec
-29cee0176d1c4802144619a5bf1cdf9ec5b8d6f87c379c476ab941da24420a86
-04a0b1ad7884b5e05136139afccf0b7101cae4b8f0bfdbe276aad1b95e2c0d57
-3902bfdee651a202b99189cada176a22facd053bbc73af1c90cbda10635798e9
-8de05c338e90b3dc4afb8d29010590b641db4a9ab707294e55e44c97e275b52f
-b88f52a6c7e545cdc73de46da699c8c3d895880368aa035a137fa8686ef4f64e
-09167b9e523312b175a166de5e1297c60db361d9505c12b48c1780a00be2a9a1
-43bc6362c731eb26a61097c62c28d2cc8d75ba3c63e31a49b9cb5b8b7fe1fbbb
-6153bc87b4538ef5cd4919811329ae933d86ef556883323ed5a6db5c98c11b2c
-cc04c4f937289590e5f7ee8d57940f21373a81b8b92eb7ca978c1a07af7b1065
-3e6498a6e2fa734269d61cf0dedd647eddbbe395e1e8190552f9a4332082bee0
-87f28fd6bb19e48de8ad662f41b4a5de657511f2329fe6b541f50ec43be24d5e
-e7336712535ece6a590426e10422d130f4fd8b0fe314c9fe068c6a45835994ae
-7bfda8ae49fab23905e4d8b374fc654f336b36b2080df61abc288b26b9ca7b42
-68e46f120b82cdcb74715e6d09aac096fd117ace3383beaca52aa248cfe307ca
-8930a34b7062fb153d968c93169dd223449ca68765480cfdc5df39be45055d37
-8ba14daa5a4745a9f7b76ab664ef3d5b2fba29c60a06d1a088c05eec6d95c080
-1974ec344b24dfd892db7874e3e9df0fd61ef8f59b525f92f2b374999f923f34
-668e55cc90ff2890107a7528853f44177fa52a071f0ce997ae94b590289411e4
-c0669c936d4b885de8427b60b2f8820bc9d6781bf275a95921d8cf4f55cc8cc7
-73ff7d001f4fc5c41ea1c755ee48c5550677755aee061a3ac85bc0d9c1e5b410
-f38ddb877fef4ad4142c87c42b6fead87f1daa99ee0fbe7e7eee948672373a3f
-7ace2444607921c61cefa7360f3194685acf836165e19395c2b2c9cb5778d9a2
-6f35f91d61e5e4838aa23909b46a899a1e02e27ebfb5368f1080272f6ae9adc5
-44f512191bf17dba3eb22d98b9b934f359fc86c9e451d2d4194632a7db5b1270
-6a58cea47392fa8cc24f6b4ec5d172e9e5601617d8e22e837c0b35b4281364e5
-81757e2fccb98fa88879d7ccc568fa9b183504b491329320c968b5611eb1f337
-a6e50d6faac591da994aa47761865ab84651c328bf259be59bd752f110f89081
-7553823cc67e36721e95f1c4e2e372e020f2b2ffb045aa70ca4dd6d55d88e32d
-c8a17492ef28a44d4a536fca8bd75b3dc392fc296377b2c4743897c32eb65283
-e776e8f8fd97c661c67c3f0d97343af141bf6b77499a13af4605e36d3f4c3fab
-12bc5daa5db1d12dfe5915acf14409e9302b1bbc8c5861948eae329ea31132df
-8494560e564bc16073c7a777fefb30cac6f4b8943c70195289946a60f06d4306
-4536c2740995b7247451c9e1619f7e277af4bcbfff6b68553ae23eef7b179c16
-cab6aae7b6f5fc72e0d7cac34611d1353716580948ba69dc534a3fa592984244
-c1bbd0a6d3f1fc4d9c8ff48e770f5c65be3b5a961e2ab8931e73c8222e6eb481
-86e92906bf2b44fef5a59b460bc88ad1837730515d82c337c349cd087329ffff
-0718e22bd3f09fede7042992a191575008890c5966f1230ab186f019f1794671
-8e619ce8706fd94bf0fb1d6ec22513150c1b9496742a94e048df079bde5d7bf3
-9db82668e5f5453962990f4e3e0245cd2e767c5cf3754c1371bb37bb7e14db75
-a90fcd5de1a7d75748289177ebe65a397762b5b1dbd468e7cbb3fec66a6b3f2e
-8e9a1802bb2cc4506b3ad1632d674f1d54a0c1c08787f274b48d60e9111d8035
-be3af44a3a12e16175ebbafdee5cfce2a9a26cb9826c86207f8ea895e5c2fd66
-216be83f81fa47f39dbaff3789865b1bef63bae463b7d166dfba5e3e9967697d
-f6c91c7dbb765bdb91f4ee5920567a94199416484e75cb6b1c0d1bdd62e831f2
-4b6d7b1009bea14c78ca6b8f1020cb05c9bfd13076d5f335d0b8ae417fa26c75
-d04a28a778d8858e64736fa0a5ba789b58b4d05540ecdf28ee044ea18704076f
-c3c92090d119bc67594021aaa4e89a063ac0e64f2198c5cdb3951c7681ababbf
-6e96666f467a0fdc729efcd2f1d94e193d8fd56802063840696f3eca394c2841
-6b7e6bd4759aaceebdf82bb473d49256e653943469db71794ae96b3d130bf97d
-752a9b3bc4449bb756039609a4f9fcc63c637d8672f2f24dbd49a5f9f5139c54
-23c4a1cba345784f28b7933dd3d2c9938b35e63678b045ec314fd9e9188f1b18
-ca034a26f5d7e2e779cfe4d16560ed2e4f3ac2bf1b5324c6b342e29b5ba3c9e0
-7bf1bff519f91bd9cbd4c198f0b98431d83d7309d0a4b62bcd450d62649e5b41
-335d87c297d288942a637999c2dbdaaaeda4f68d166265a37df001b1a4a5f561
-64a9a7af810851d98af3e01b0e4bbcdf33d3035b98118b48c6452da0caecca10
-228a308a0a3844d57628b2dfd7189f1fd252ea1ce3cbbab7e71329b886cc36ef
-b40f642aa54698e87f4ce8b310f0ee29968ae04de003fbaff84d866e4220b607
-3b3c5fdfef88354a54d4318dd852ffeb9be81630c673e425fd3bb6ddec9f298f
-a9982f8a5859b983bcc09b989f4a71ee4a54d38a220c3ce7491e7d996d8b0e11
-b085acb8f217be35f3eb7fa08bd8ea8c66df8ad00e329ae732ce12801aa8b1a9
-40db1a7b303967c185b90229a1188eeda3a1565dad1c08181fb35ba03667d513
-9f2b6a71dd27e11c7db9a7eced6404cb09250fa0ae2f0fe7fa61147039cb8685
-e7a1566e25b40b1f23ffda5515c107e3487ede0a148f2d8500f102b4f517c956
-87b2e0399387f4a9067ecc725bcb327ba5e98d5c68fb54ac99834146bbd7e91c
-b04d9576bb16e39608c14c25aae446d250b388610b2714757631c18feb700057
-c0022456c9ea28140a150dc6fea0333ecf9c291d95505de3c053c1f957f76a06
-a5e96f792200eb5f1811e86d70c9bf1e0d28da28b8c6042555a27ddd0aa168b0
-0f3c113217d990f6ead0a6ecc4ff4c92c577121d2b1dcbff547c03184360a6b6
-3788919d20302f0c35541b48cb6e926be087b1f7308041dc8cb8f161d8a8bd32
-ecc861efd6ebe16568dd47b82fd1a02200733fef4176a7477185d79e44c128fd
-c54f4f28cee76dcded7399bcfebbfa620a6f5e4df5350fe6005f84541a6e77cd
-97ddcf704455f96435edb3666d9cb57521f35e258eeb2163944c90cbdb3d4a70
-c94b9d3905fff429f16560c6bc44aa27bb481e24d03f29f135eef38d973d12e9
-c251de1d9b976d4d7bb7b4f62dc7a6093d186d240db797432dfb5e71f8fa09d1
-b9b6cbde7b4674bb3f38967091b8b375c0e7dfddc0a206b0d8908707521254a3
-35be48528674c8597822a0a9e9ca84f0b3d2a44ec9deca0db51fa2ef3db16851
-7939ebef52b5af799ff6fe86b0cc459be94187af479e95651233f2515e01ccc9
-57130b01e6e97df375396f8499535a1fcc0dae920db25db41477263a847b578e
-8ac94e59fcb69b97a1ebf8d84e2fab6925bd16077d5a58403539acb40adbb89a
-55623d7e09a8481e71b47416751f01881ece4d94ea9cff6dabb3546ff2cde4cf
-1ba77ecadcd4499637e26c5064a342d71cf50d725c40286ad352bf97e0da521d
-58055ff97c68768b4435db372f0b3d23845d7709ac47b2a965327f62573a8fe9
-e9c5c435ddf12478bcdfde41c0e4303b03949446ec9291c553eebd9add6bfb9a
-45165ce3820af4264dd3b54ac41e4b2df6ede1286973660e37281c7540beb69d
-16a86ae03b8c5ce7ac142585f72a0cba8cfa3c71a54db60d1305790ffbaeee1f
-f31774926a1da96a37574c9a5b66daad0a68adf9f104123941ac4d3342c13bac
-b9b124ec9db917032e3f495107f3cab93d57751e88a5369e27358ecf4f9348ea
-543fb55c0492862ce28cfb1f28e0e5ffaa32df8fdca241db555619583fad76d5
-04ef599f233c424359768f6e8f0cea95774901577277dfd8f90418598e
-0000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000
-cleartomark
-%%EndResource
-/F134_0 /MFECUR+NimbusMonL-Regu 1 1
-[ /.notdef/dotaccent/fi/fl/fraction/hungarumlaut/Lslash/lslash
-  /ogonek/ring/.notdef/breve/minus/.notdef/Zcaron/zcaron
-  /caron/dotlessi/dotlessj/ff/ffi/ffl/notequal/infinity
-  /lessequal/greaterequal/partialdiff/summation/product/pi/grave/quotesingle
-  /space/exclam/quotedbl/numbersign/dollar/percent/ampersand/quoteright
-  /parenleft/parenright/asterisk/plus/comma/hyphen/period/slash
-  /zero/one/two/three/four/five/six/seven
-  /eight/nine/colon/semicolon/less/equal/greater/question
-  /at/A/B/C/D/E/F/G
-  /H/I/J/K/L/M/N/O
-  /P/Q/R/S/T/U/V/W
-  /X/Y/Z/bracketleft/backslash/bracketright/asciicircum/underscore
-  /quoteleft/a/b/c/d/e/f/g
-  /h/i/j/k/l/m/n/o
-  /p/q/r/s/t/u/v/w
-  /x/y/z/braceleft/bar/braceright/asciitilde/.notdef
-  /Euro/integral/quotesinglbase/florin/quotedblbase/ellipsis/dagger/daggerdbl
-  /circumflex/perthousand/Scaron/guilsinglleft/OE/Omega/radical/approxequal
-  /.notdef/.notdef/.notdef/quotedblleft/quotedblright/bullet/endash/emdash
-  /tilde/trademark/scaron/guilsinglright/oe/Delta/lozenge/Ydieresis
-  /.notdef/exclamdown/cent/sterling/currency/yen/brokenbar/section
-  /dieresis/copyright/ordfeminine/guillemotleft/logicalnot/hyphen/registered/macron
-  /degree/plusminus/twosuperior/threesuperior/acute/mu/paragraph/periodcentered
-  /cedilla/onesuperior/ordmasculine/guillemotright/onequarter/onehalf/threequarters/questiondown
-  /Agrave/Aacute/Acircumflex/Atilde/Adieresis/Aring/AE/Ccedilla
-  /Egrave/Eacute/Ecircumflex/Edieresis/Igrave/Iacute/Icircumflex/Idieresis
-  /Eth/Ntilde/Ograve/Oacute/Ocircumflex/Otilde/Odieresis/multiply
-  /Oslash/Ugrave/Uacute/Ucircumflex/Udieresis/Yacute/Thorn/germandbls
-  /agrave/aacute/acircumflex/atilde/adieresis/aring/ae/ccedilla
-  /egrave/eacute/ecircumflex/edieresis/igrave/iacute/icircumflex/idieresis
-  /eth/ntilde/ograve/oacute/ocircumflex/otilde/odieresis/divide
-  /oslash/ugrave/uacute/ucircumflex/udieresis/yacute/thorn/ydieresis]
-pdfMakeFont
-%%BeginResource: font ZOVMRD+CMMI10
-%!PS-AdobeFont-1.1: CMMI10 1.100
-%%CreationDate: 1996 Jul 23 07:53:57
-% Copyright (C) 1997 American Mathematical Society. All Rights Reserved.
-11 dict begin
-/FontInfo 7 dict dup begin
-/version (1.100) readonly def
-/Notice (Copyright (C) 1997 American Mathematical Society. All Rights Reserved) readonly def
-/FullName (CMMI10) readonly def
-/FamilyName (Computer Modern) readonly def
-/Weight (Medium) readonly def
-/ItalicAngle -14.04 def
-/isFixedPitch false def
-end readonly def
-/FontName /ZOVMRD+CMMI10 def
-/PaintType 0 def
-/FontType 1 def
-/FontMatrix [0.001 0 0 0.001 0 0] readonly def
-/Encoding 256 array
-0 1 255 {1 index exch /.notdef put} for
-dup 45 /arrowhookright put
-dup 58 /period put
-readonly def
-/FontBBox{-32 -250 1048 750}readonly def
-currentdict end
-currentfile eexec
-d9d66f633b846a97b686a97e45a3d0aa0529731c99a784ccbe85b4993b2eebde
-3b12d472b7cf54651ef21185116a69ab1096ed4bad2f646635e019b6417cc77b
-532f85d811c70d1429a19a5307ef63eb5c5e02c89fc6c20f6d9d89e7d91fe470
-b72befda23f5df76be05af4ce93137a219ed8a04a9d7d6fdf37e6b7fcde0d90b
-986423e5960a5d9fbb4c956556e8df90cbfaec476fa36fd9a5c8175c9af513fe
-d919c2ddd26bdc0d99398b9f4d03d5993dfc0930297866e1cd0a319b6b1fd958
-9e394a533a081c36d456a09920001a3d2199583eb9b84b4dee08e3d12939e321
-990cd249827d9648574955f61baaa11263a91b6c3d47a5190165b0c25abf6d3e
-6ec187e4b05182126bb0d0323d943170b795255260f9fd25f2248d04f45dfbfb
-def7ff8b19bfef637b210018ae02572b389b3f76282beb29cc301905d388c721
-59616893e774413f48de0b408bc66dce3fe17cb9f84d205839d58014d6a88823
-d9320ae93af96d97a02c4d5a2bb2b8c7925c4578003959c46e3ce1a2f0eac4bf
-8b9b325e46435bde60bc54d72bc8acb5c0a34413ac87045dc7b84646a324b808
-6fd8e34217213e131c3b1510415ce45420688ed9c1d27890ec68bd7c1235faf9
-1dab3a369dd2fc3be5cf9655c7b7eda7361d7e05e5831b6b8e2eec542a7b38ee
-03be4bac6079d038acb3c7c916279764547c2d51976baba94ba9866d79f13909
-95aa39b0f03103a07cbdf441b8c5669f729020af284b7ff52a29c6255fcaacf1
-74109050fba2602e72593fbcbfc26e726ee4aef97b7632bc4f5f353b5c67fed2
-3ea752a4a57b8f7feff1d7341d895f0a3a0be1d8e3391970457a967eff84f6d8
-47750b1145b8cc5bd96ee7aa99ddc9e06939e383bda41175233d58ad263ebf19
-afc0e2f840512d321166547b306c592b8a01e1fa2564b9a26dac14256414e4c8
-42616728d918c74d13c349f4186ec7b9708b86467425a6fdb3a396562f7ee4d8
-40b43621744cf8a23a6e532649b66c2a0002dd04f8f39618e4f572819dd34837
-b5a08e643fdca1505af6a1fa3ddfd1fa758013caed8acddbbb334d664dff5b53
-95601766777978d01677b8d19e1b10a078432d2884bb42d1f224976325883657
-05acb022d1e9cb556e37af91917c78e98229e3a4dbf03ae741998542977ad6df
-1760fc1f1a479464922afda2cba7961e9da696b71205e19c542c97f25419c43c
-fa1a042ba0cf5622ffbd3e775d0d564135d99b9ffba011eebc4066b003ce2f88
-825936d7393d05d3804601cee9d123120fdf73624a9d4e361a28e998acec53f8
-7a62a0aee33be2e96542534a8af24497d1c377cd7f723767b44857d94c6cda7a
-c3d6f0087fa36655dd2b81eaecb31fe4f4a2fb1ea9fbe8b83d35826ac93fbb4f
-2bee014f41f8f276510cf5ce35c3954e8cafc521d0c3ab80ea8c7fc29427a1d4
-42d6f6c1800919e58de9ae12304d718ad80febbb412da54153469cd51a288628
-ad109baa77981525b3d9b0efe593537fcbb8520d38cccbd5db171a0385a432c1
-0000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000
-cleartomark
-%%EndResource
-/F147_0 /ZOVMRD+CMMI10 1 1
-[ /.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
-  /.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
-  /.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
-  /.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
-  /.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
-  /.notdef/.notdef/.notdef/.notdef/.notdef/arrowhookright/.notdef/.notdef
-  /.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
-  /.notdef/.notdef/period/.notdef/.notdef/.notdef/.notdef/.notdef
-  /.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
-  /.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
-  /.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
-  /.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
-  /.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
-  /.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
-  /.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
-  /.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
-  /.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
-  /.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
-  /.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
-  /.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
-  /.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
-  /.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
-  /.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
-  /.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
-  /.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
-  /.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
-  /.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
-  /.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
-  /.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
-  /.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
-  /.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
-  /.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef]
-pdfMakeFont
-%%BeginResource: font ERVBFT+NimbusMonL-Bold
-%!PS-AdobeFont-1.0: NimbusMonL-Bold 1.05
-%%CreationDate: Wed Dec 22 1999
-% Copyright (URW)++,Copyright 1999 by (URW)++ Design & Development
-% (URW)++,Copyright 1999 by (URW)++ Design & Development
-% See the file COPYING (GNU General Public License) for license conditions.
-% As a special exception, permission is granted to include this font
-% program in a Postscript or PDF file that consists of a document that
-% contains text to be displayed or printed using this font, regardless
-% of the conditions or license applying to the document itself.
-12 dict begin
-/FontInfo 10 dict dup begin
-/version (1.05) readonly def
-/Notice ((URW)++,Copyright 1999 by (URW)++ Design & Development. See the file COPYING (GNU General Public License) for license conditions. As a special exception, permission is granted to include this font program in a Postscript or PDF file that consists of a document that contains text to be displayed or printed using this font, regardless of the conditions or license applying to the document itself.) readonly def
-/Copyright (Copyright (URW)++,Copyright 1999 by (URW)++ Design & Development) readonly def
-/FullName (Nimbus Mono L Bold) readonly def
-/FamilyName (Nimbus Mono L) readonly def
-/Weight (Bold) readonly def
-/ItalicAngle 0.0 def
-/isFixedPitch false def
-/UnderlinePosition -100 def
-/UnderlineThickness 50 def
-end readonly def
-/FontName /ERVBFT+NimbusMonL-Bold def
-/PaintType 0 def
-/WMode 0 def
-/FontBBox {-43 -278 681 871} readonly def
-/FontType 1 def
-/FontMatrix [0.001 0.0 0.0 0.001 0.0 0.0] readonly def
-/Encoding StandardEncoding def
-currentdict end
-currentfile eexec
-d9d66f633b846a989b9974b0179fc6cc445bc2c03103c68570a7b354a4a280ae
-6fbf7f9888e039ab60fcaf852eb4ce3afeb979d5ea70fde44a2ae5c8c0166c27
-bf9665eea11c7d2329c1a211dd26bb372be5822f5ea70d99eb578c7befd44cdf
-045a363056e5e1cc51525ea6fc061dcebb337208eff729802376a2801424f670
-0e7e6397b28f15bc10b40012b0a3eaeb2693e8f7f627c4c9c7c6c5bff105c1e4
-1b2b9e8f09253b76040d268b80719e1b3f5a55ab7b892ad5e69acacc6c1640eb
-3067bfc64938f41636db8831883bddabc6777dee17f2e84f1d530bc76f51c621
-75ec6b727a82c193d1c0801ac492bbe281b46626bd21f2adbbfd144793ef754a
-ea5f1cda3310e83d78a098160c66d6b0c68d4976898d9dc1a08d01740ac3e7f6
-8d3ce0a7e109104248cb86318400bd82ef894efd9c9456e97055286c144d3efc
-d2625110f1ae76241079bec19939ac962e0ba813359c15b07c74d5e9868e2167
-ea1199d21ca8827cddf1be8357261bd32e79fea6bc475577c5f6848345bce58d
-f5435281572ae6b33b53607ebee6f862d4c752aee43c00cdbfd258c7765b1358
-5d6165ee034e5815de79cc26c4a720607bafa6049710ee3782bc2cd84fe2473f
-1335d20a3b6e9e8355af36673cdbe63c27d4f0e183fedab10031b1ee33b9573a
-2e1961b7c6baa41f7c3ee707fe86071ede5756a00d7b3bf0a21b7c3cf41093cd
-66eccccc22f4534912cb900b08e69574b07f246305dcbc238780278aeb8c9e55
-3d096a944ec7aa9f697f354aa137df90a9547efec1cbd568cb999979f5aec6af
-a84edaee1564d178541cf4631081781608fd38964257cf89b1c8e0120b3f6af0
-793597ad553cee5cccd5c4f09cb0b4e998e6e76243191af7e93833d067833f0e
-53670d7e996ed67cfe6699a6e3815932ad272af4829c2ee08a30d3938c928d1c
-e89af71192ec1247ca233093aafa54ffa58f4aaf3fe9c62302e598f4ff8cc32c
-4d318391f7a36d0d8b416dd36d776b301425cbaf82d520141238781111a14cce
-7927e2af21ef837558002539aaeb170fa7e7e37efd447c37db455d2f08533155
-53f3c5c3be4817680efd0ba3a114db6aaba6c4d0d57b09ef8baad463996718c1
-9d155a62d7ae82eae4c82760c594a6ba3c7ee4290f0d898bb3e404ccaa91fea4
-eaa2146ac6a23f6c5a8aae834a0587d990024bbe8de485c71b916ad96dd66792
-a732a188e6a57c459ebbd7756cfd54770e2a8d81bd4618d916a30ec7084b2492
-5f77ab14169547eedfefb6f03c7d5365cef512df194628d5fbea6cf56d0f5346
-b6b6c1da1dd8d8321b88807b579bb6a0c8f69cd919e311b6ade903b470f4e0a3
-dd5015c6432452ecec048dcd14814e47def4a53c5ca6fa9e91d8a28c719f9348
-509c0e17d632f8cb3f7468bb0e7f7f6525c086dc7efb997a60e059d3d4938489
-23e60f7c67fa6aa8062594f122a48c54aa7c049859928a3dfc72752acad074aa
-416c667fcd176da4d7d31a9f6be6f146d4a9dc78f419fab7c9e6c74d40ea659c
-24098088bea26bf5a725fe56025d1fcf8465ed7103702aef74973f6fb697e645
-e902d65354a44bb3489007c555a6a08bb057eca27c93bfcee9de42e2782fed4d
-664ad7f2d238b7eda1ca4ad473bb9559e11a9f214e258ce1a2a60512975b112b
-336864238a36732c3adacbfd52c85a0dc809ff955f9c81401f72107f3d263999
-a69836d76d228ab4f954b00da07bc4a4e165f2dc5ecd8138cc408ac22217b15d
-8baf04408d4b47e55129b0e596c93d10cd42372292e1ff483868e8510076f7f1
-ed8ead1bdee2b49533f87ddbef2abdcbca432307f7ad0b3c3d4721f3e67e609b
-b06f8b7e66af7c843aa1f71bdadf0f4fb6baac84815c8154a0023cfb68282b4c
-8e24e478f81f8d26ef82d6d0e1da4a65478f4a1f65a7dfb4d1700207850c33f8
-148158a784b452ac6874080039e2259431c05c4522f1d67522e273b443ae9820
-adb5303cd0d839ffd17eb1fc6957159a569f64873b4b3bf99349c486a3af2b20
-b6b9c41263300ab0844d24daf780b4f324eda854d4e210daedc0e34f4b67fca2
-1265ea3764f8f755007b62e9e18e80bd30f3b96124065198c0a5985ba2172550
-8c8eabe77b26df4451f5068956fce111041a7d23f681ff2c1b93344fe688708b
-61a47674c318d078fc4bf79217659987dcd1bda1e1b74068960036c472906152
-cafe4a8a702d271a02c790ea3e440e4f415556ec703a23b7aaf7bc50c5a32f7f
-fee6426433e945c28be038cbe5ee0e7933945f052757d480c58d4d7dc4ab924f
-985e054fd553d1c037beaba29b14e823a4091b08ed602a69d1c3eb0fd63faa93
-36db22e6588d3d2fa727916163030958cc89b3ce99ddeda6190f97e039f9821d
-ab4e4d9a15cb5094041790b995d8950412bbf049bd1d8afeb8bddafc6aef748a
-f2523b8313e13f90f966c134e39d52e10b63e30aadca42bbac5962e4e3f71337
-bc2fd40679beb44e111250352f04cb0404158bad9f74416c94003bd12c88d9e9
-5cac3a3eb575733eb44a3c32946dacdb3405f5b4a2513fdf9e6bb2e6e21c5385
-6c527ccc120eaf95d400847dfc9e6a40806330442e1895b53a6188e57c65b466
-da203785fc322efd64f2e6f66f996bf7ca035bb2117648a8857f1b10469aee10
-dd22d785de27f01f1d725b56b380917004a06afc0046335f97a2ff20ea44f794
-c1dfd6b107549e39247a5cb3f9c37af849e9c5f06214a570113d91ad4e14d9cb
-aadf8ef93a933795c0cbfb7204dc605b4b3b95b9fed0372d8df634f7293298a3
-6aa4abd1f212ecd5d4ac49d467567385f80e163b9464f6554e48ff78d45aa402
-b5ee093a8f96da45504e41bfb1a72f579031efa801690a32f4e248a5f773027d
-da3f3721d4fb481fd1b8e81054aa4a700e9964a87871e01f03fe80ac4215cdf2
-7a4944cf89a893638730631261114f8aab967fe29e280124fa8d51fc94b1c552
-db58e038097172d5f634ceafb877d7caca03436cf6bf40afe4dc99ce08d3605a
-78e2c90ffe766fd3ac0e8b2ab247c3f689a55e350cbe80a9a452bf8666d5710a
-6fbbc45e4690afc625bb7a8a29bc17aa582b6e200bd5123e26b2d445992a3a5f
-7aa128c3f6230588c41c6c456655961b823e65d7471ad16f9aea07c2b3d39c45
-726f023ea4780719a3656ae18670daa3bc084e60fdf2ba1ff0204f285d72d9a8
-269430e406cd36741bb227a1aa28cedf9484689a78dd5495337bde66b5a790fe
-4af761c0b505ff974e4c7f67348eb1887b5b9315a7b3455d3677bc77b61d48ec
-f5ebdc73b25eeaf12a6c896a54b499ba5f2897b7da9465c34561b23e0e740eec
-fc7adf944329e003f5266b94a425f3864b167a34d0b9d259fcd8d741c9dc0fb5
-bffb8c8cef470f923d7962cb5806c67763358a9f6ccf78220f28e45a84b0ff35
-c585c18b19c61b51cbe58007fb852e0a92ed6d704f15ff0f863528db72ea3dd4
-3ea0af466fa5b60ac4490aa5db18a649c442a60b4f824e914915376a127dbe30
-85a3c56ef4233579b756eb62e04fea0a55503f88bfdf011436d9d5088e027c26
-daa8165842a4ddd43fc3ab8dadbb4d53c5ba9a5b51f33d505fe3ed168109f1f3
-9ac5c3357e48cd9e3adccf2daaad831000e27307d6cb2aa6ecf5f92cff39b266
-73b1d3587e029313101a9075ab35de260f23f3d3bab5f7a6134fd07c076dcd99
-7bf2e7c40ff0c0fa1096312b791d638b0038138ed5c578e51309444691c1b182
-8b346fe0286e13e3907beda13044177c788b4948a4dd398aa9fc317665b250a1
-3570a783821db58159b825b14c2a639f62995a049eeeb8904226a8f8e14a7959
-731a74dc4b215d7ec095ebe86a3bf07080cdb0dce6d06fcc2e3a57bb04944f90
-8f395bd65117984c1596303c2781e3997bbfb6ab9f354ebcea7404785d8dfb04
-b19a3a6792807fe5debd6eeec1ba9ba9a37473d6c435bdefd5b2ea9c21d9ec79
-0043b5ad1b0a50f9a24594d00f8fd155681c33df8f0c0b3cd5a4fc275da65dfc
-6c65ed8713956bb94b6281a4f39c8ef72b932adf3f6ecfa697ff7d84f93e7a29
-8fab7b48172e32ba7b3135f4a2501961f4a1c50403fc38c715743b55095ecc1a
-38f11f1475521fa00f950776279e8a377fb4ca4870c8daa4fc67efe4db8e37c0
-d56ad93cd334ebe18dd6d92a3ea48b29e7e76eec5e8aa0db20ad690869053422
-8567c4b72be2093426677988f8ac9f7fcde0dac8bae175066a485f3b1d0c2129
-9e38a93996a0eb7a3357ee43bcdf8749bcfd7e7e0a23c7d9e118c4da7fff5661
-07454fc1ab28a875af7e512b2432256c401ea462d9aeb0a2f97270cf2aa8ec53
-1e5248ad52b1b74a376faaf7772e948f433cea2f0ed4dabec00855a394fedb83
-1daff1d977e9b816ebd27801505dcaa51f9ab531e6c1358b275d3a6ba38f4f4c
-528f2dceea3a404a6362e3cfef9d904b573571a4e634d4852f3b922495af19c3
-c63c736d1e8a5b15cfc4da58f26f22be233b4579377227110f8fe5b0df57b495
-2c14d2011b6215b855c36d901f001e24261089f5edd39f7e5bbb2bf90c6f5c5e
-7ba8928434f52689365ed48123414ead2e00f8860e60afb5f59d2715c4ee2b3b
-2b10399ca1c3f70259c63762f64a5a1cb6b1995030a7d775a04cd77a95436e4b
-c3b1f3d1959ded9f35fdd7fcde9b051245446dcac11fb3d0228ce4c012a2f201
-81ec3dd2aa1bd66ec02c93e4784268f754c9f0eba42d27b755bc58ad00e09e04
-e05fd21ed0c160353d2f5467b5903b4e1d1b8666acce06ada99c063c684d8738
-3d338c579595d1e2ab301c4236183cf2c3be0320ee83cde4ea050160b58787f2
-bad8154825c9b29cc14682e15db5f53aba109799c10f25fa2e54560fdafe6c91
-c246ae56edebe0aa30e152b61fa64e517f6cc41ac7b3c25ecada33e3f6d6ee5f
-562542e0e66d9c07aa9889505d51452cc2ee73e3683e3fabe26f003b87d9fbdc
-a376e85ad9547c23e463fa073429d32ca0e58326385a89106d5b72cde3c00c11
-c5f40d1e8b61e6cb1cc6416e28afa6caa469682ec8365081a21d77a8b1df7167
-6344226bb9a7533c0fdfe153878a3af3088e520b94933d0099c2ff89974bf795
-d871b9e5d40cd7aac72a99f351d824f86d33cc89bd70dd41f1a866657bac3a58
-a4eedf997eb49f8d967e148f381e753d5e67080d2843d44a3585e078615bea47
-6c882773d995f4154fdb773a7d9e29fe46e464e602cd206063c96fc51c30ffed
-cecdfa28a951dd5211acd684ed3efd9feaa5aa98b091aece8681999d7c8ce708
-1c64f09e18e64198b841d7824e03de11101493975ecb1b7d556714725a14bdb4
-5d9237ecf693202198964c1554a04ab3485bbf9ff863441da3511d8fe6363e32
-a38a11f4dc6a1ee18bfa3a1c2c93a90675b0c21959054b17b1af4d533c87ac69
-08d0c344fe817d6817a74fdb46f35d3b48b9128784f43a68d809425c6570c600
-9a76199111e88a1c9802de558332000dbb9d1211929d509af5915b7ae8ea1c3d
-d2598f5007de8e7383f7453fc6a9c0b91c80e9b1742bf6418dca69450785fb73
-12dd228889cfbc3f6711a26022b29f9295ee1ca8459305fbf2b93cb3fff5b6e7
-2b5c1d2c4d453f0b9a53b6f361136b1048b30e7c90e0de8edda423e55ccb2e2e
-ee7b502af2baf30a92af542869b8f26ee28509dc01492095e0c27ccaa30e0db6
-3f02f11dc0ce8a94b8a8a7ef735e4fab04830ef077a8d788b224c184339274fd
-5f7b547b77f81bad985c73b05a79d3c8661a9c2b71c7313d8b9cb50ae03aee95
-2dbf1afc9ddfc00d59e6f99021dffbb66acddaedf48df5462fc528dfdafa5e5b
-a039d6bb9bdd1a78e47684a3c53ca307abd566093c2a4f6b9f0be52d4f1f2758
-ec48370eab4e1e6ab393a23358bae52fed3b270124639dd0a56ca6afce77494b
-34f46433cac90eb63e7e0d25de6c8a0670b14e83d08a531cf2148002f9a6df19
-7f87c989b831c509df23057b3ec569eb5f5f530edd047a53b5b59f483703bdcf
-b578fdc44ca7487e3d39479ca4760457e7018af01116b29bbdf7c3e0f5c07a8f
-7f502c15059d9635b7ce630194962e4183c3838d9401260a743d8ebae1665ce8
-73bcfe5d090a8984e98030fe6b21dbcb49398b6905ec04ed310e37cd069a85d3
-7cd9e3a02dd8e036b2a79192ec036cf7e10653e08928cb8bf4911122d27e195f
-48d3dfaa34122ef2df8e023c9ea1f246af2879f5df632719bf7a91f266d823aa
-caefce067bf74ee0d625cf128c3930ab83521380e0ceb5daa2384da4ab23c34d
-0db8a4acce1a33b6deea3581efe521279147ac1b36e4f6b2c08df2b2dbab051d
-264a250a06ed06aa906c2682ad2ecdccbfd880941bd824d021f086560bfbb359
-e2519a2708a4976f42913465e18872a93cda809a85730a4930ef1e3e733292c8
-06c80c8865645c6a69b128b1333c3ac8c616d3e3a0163aba54c7a51a063fbce1
-4018cabe1b1ebdafaefc27d2b22afc96449cd515cced671baa88d51c5c778bfe
-00208127f1fc35db9c6afe4fc91dd0bb1277181508d7b9868a055025c65394e9
-ab7a95494118d20fbdd7ce0b5f11492df5e8c54c1ce1ecd2e7279e07fe6a62d5
-63d7ffd38f04ba75057cf190319634f57aa246f03f5f904ff952d7b1006d43bc
-ce88d89ade52e861aefad538b644942b6b97e778000de2f2ac2b2280d85a823a
-176d8387ca420a441980d3e866604325917f78572ec9ba14a0944e37480ad3ff
-9c10590c0705840d09c8bb076a5aae81b5e315ca901e262b773143a554360fda
-3dc799fd07482666f47c17d8a5bad6efa53f20707869c5fd40d940a885310cd6
-d5ca9c351731fa69fdf0bfb148e17ac26ff43bfbb38c101867ed95d789ed2b0f
-61820249b398fac0c5eee32032984302eb1804b82bad515d721213732ad43b95
-d4a02e17b22159ca29e300042804b75807782b9bda49255cccf4e35c461ff59b
-65e36f6c6345dbb2e8c2f5445031999c2d8f0444cf4198ac17db48199c3b3fec
-02a130d230aba456406e1070178bdaafc422343ed9edbf471c965d2b891586db
-a34bb2d66f98f716e605799f3800c68000941a52d691640583cce11b94cb5599
-29fd0d5e8a9307831fe15fcd232eb361721d0da9e7ce111ff1ebc256a407372a
-253180e51f1800ffb0313c2c3f3c4fcddd59f824dcd0eaa1e59837487288b558
-7f8e6d27954208fb815ed1d54a36476a95c660751a2ce7d475c72ff1784c363f
-a641595eb92e65d9e7bfe18eeffeddfe82d9f6f0cee37e6a9e60b44939263272
-4816df40ed24551f0d07d813aba49a80bd3560188e5d0170385fd15c34b45465
-3d5d59bf7624ab116452ac28dc9217b11c75a08d68e55b10e9567a9d3d8d5da8
-89116318aff25efab611da69e132ba2ff888d68c84c056544c0fe9137faa8344
-4008487c34ff2c2376558ce20108f76582965fb06c2129e607a0e60889d97fac
-2c71a026299b071ea7f9995a542b7e31efede8a4d341210a37f7b4bb96aa7c31
-c873cc0c3edff7b23d8a22e7e601ffbbab0f671b02ba487cf6b588ebecd26f9b
-b7e8de0cbda870662bcca90716c0ff768a9c7c69c1dcb4086f1e881c6dd5b3f5
-0ac517ca096f28b1c7ac9195f99e44d444017a3bd54a68f4588f0a7562553053
-8bfaf7788a7243c30446213bc987e3383913f24b36b33e4b082e507cae63358c
-9675599f6d746305a417fe8848f37bf85f4535e28ddbc5868dd6dbd3148cdc1f
-2c2d224f00c3af4c1ddbfd88bf79eec76e45ef546cae548825a0bca6bf93b0b1
-373af60a7b24a75079d6645d0908a9f55ed0fe7397100a730a6f4e55678714bd
-90c887e46a2c7703b13b1dda74a819b97abfe6275a24e73901540168737a8b32
-ca1902b7577b8761b3c4a6b60dfad490e35d71c5f35d8ef382fe66433336951d
-e4ee981f980168853438755f135c333b8723d5778e2e3067dc73b7fd99aafbe1
-d5a2d1cf443905fb45730ce8fff14674abded9f94b45756a646b4cb1f789c7e8
-0748f3641a22c01b10adbdc77760c0e2a0b9055c4f9107d935f5c2fb2fdd2845
-6d6d2d2096e4baf14bcc8d716adf053bfe40845f02c0d18fccc453f3f8e45458
-69f802f506ca21d0fab24d7f3d6d6c219637a2dcbc58614c1456a9c6b0b0f57d
-09cce675fff4f626b1b68c0a63fb9a16145d58176cf27ff5d3513dbec6014f3a
-2b5de7ce69c8ac2fc184bad23950b28cf0414801764967ff97022cd4865d994e
-585ff2c992d480de31f549f26a18e4721133f3d88316976bdae41431d44ec8d7
-4eacb29aeb132ff49e3c646ef025eb541dcc54f38b8aeb562887ed6cdd07ffa6
-cf3b2f89e4b0fbb5226702068b8043b6e2f284e4350c97a7498e6440bc3c8d2d
-27d8aa1eac980e960613180ae4224624b2c6f92ed4666e391ae5e159c0ce207a
-7433e462cd92aeb67eb89fdcd20e46f17f3d15ee679c064176a2db0ad5c38eed
-7595cf6ab9750fca76e8e5ea2443b9d13da375ca2a2dc87fbd3d81ed58e366ef
-94952cbd918134ea08f90516854207a2fd92799c410ed1fb6a9c36877d0b777e
-ef59b03f19bc6b8fda91ab8ae21c89d117825a1595466da10f20b86d6d223cdb
-6976312c7fb7bffb58feadfcd019bacedce96ec239b5a799005e94bdefb9ec40
-e717a597326b5330f38fbf708d002c9eb8d8ea0834241a35e3a07a58a030e678
-5812bb5de1cb511426cf49ff39647db65d8a7f2f87ca5e903eb1478984abcc17
-c7ee0b1f7d1e9e3b81c663abcce77a90f1cff1b01f116d2995e65cba0b3f1a3e
-80079ece2fc25e0f5cf24507c99e5b6e87a417cdf29a1a8c58aa747afa962c25
-14671fbe467e22931a723a236aedff5676acde6ee71dc9eec11301af96927274
-a732813a49a473edb7e9886b6c45605681a563f32745d60cb4a26a7064406756
-c9add724e9b400097377258e81cfe085b1abdb3a00354353b50c9bd11a6e655a
-d264a203708f739a46e4322a1a8204e32ae385d4f7694d6ad63f975986ffd869
-355b7ea9c0feef8f6d7bcce3128a0e45853de0a5f442bb805166c7906c9f1023
-df70bca683907a0bbc11249670f81c522441aa6fc4e7889a38d15ead8cad4ccf
-e95ff5438d0edc450e6399f0228ea318dc2979e7e5a36eb76f9d81061ec8c615
-217d9dc7a1d0924dd953ad2b741e48357953d43186da75f340c58b7d2a6c7eaa
-3038fa4b66b0ccea51af9610e5558d82bf79a301d73d57b6feaef32d6f19e801
-e37a3c1ea341bee088e322faf9ab5ab1934b70f894853984abd5f34c4d3fea05
-5ab4fc70179cc9f1379f98b3d1f529f3c2aa4ae63b8d2bfd46afdbcda8ea11be
-f32c93eb4d435fc37486a1cbaadc3c98de581ebad18f35175d7b3e67c9194d5b
-bb3cd1918e86daacb86055a548fab07ce7c933bd984eb713405d2b3f48124432
-a88e10b97f7be3a270405594d3e06c17b47719e2678f0f069ff1abfe7d3672d7
-6a748a9e277ffdd25f5477d0c9d60d7e8da9e0ef30e5fd6c70d47d31637bc0cd
-4d67f5ed2b103889a61fd11075aabce9f2517ec9b53d7db5b27790d9bb1e19c3
-d7c3a7e1b95516ee38062d4ea759151e4de0449e6aae79500c42b4efe4936d0d
-000fb3391330c035d9d6b9e25671f9ac599a40c37b2439c06fdfd988abcbaf77
-0e42d324e8ca78613f35ea64aa88c3c43e51cebe8ed1067cad94ea0387783e03
-e76af474f739b9249d1e95eef85ab528e8cd2da99e33c7ef0ee9df694db43f3d
-fe467e6fd1b5291ecbf6b1ac7a25c002dee8be0727ec5439715bfd8f854843ea
-1d080677f64889d70165f1bad110a8baf3885629f8ddbc3d3b09c57dea28b4f6
-7a3c042ce64d636d0bdef920ab5ef9544f52ad533837867c4930fd4dd3213e18
-ae2ca622e0e218b1bd54bd60e01d4cddfc2e9b64c6c99e79ab2c3e52cbefa598
-434213d475b6292190b89be95b3c6660133e1b498bd7ff2fd14aab2aca0dffaf
-62d9df30c19ca0e949007dcf8453e70e60a519674d305523d33bfc3119037236
-19cc4ab1707db2c4984c6d4fb4310932e9ede7808cfc7d343a7fda08068966d4
-7877d7de7c0f5ffbfaae5666be3bdb48de31c5ab6bcfa7d35816e5862bc4a13c
-ecf2355935040fac37141f7bef7e58f7b025e187df3950edfd6cea20d0649071
-442b2916ebce5f4d3ce055efdabf1c2dc348ac0ae6777f679e2f62a0a3ee9124
-7fc855bfc6f0c337a74c44ea1f5dd32ce6183a4c80a6b967861f6101c28b72da
-d6aa1128f196627e24179c18f384e27cf7f81f43138381d177f93f8082cc9d56
-1b3c99f1bea073a1a81f8bcea131e3587b397937c4029d486fe6842a709558f7
-43cd16c8f0a5e4fbb3e522663b82e2544a6fecefd3d8a2b222301fd4988c0136
-859e86087fad63292bc4187412731a966710ca9ccb86329560d64be31ca4b526
-82245c1a487046ad21dd9a270e3fae72fecdcf9608784f649a25474034ac744d
-44e14e72d02ff17b2252aa5273de3ba3cd71a95070a9fed0dff80653b3d346c7
-56119529e5bcb6011d341e368827cddf22d4f99f1781829df808507e2b4ceb13
-211b08f55444e75a005639a20c33706f8985f3308c08f77e72dbfbe049ae8177
-c2da2e62eb58f0fbb369f5bab0fff49f9d4765f931fe66f8aa107d8116becdfb
-466d282527bab6fa29721678837cb46d60148a7fd9cae63d6aa634d23ee21161
-ef9e834520f367903a65bef7996ab77d37ba97aeb2a7a8c3502aac988e7a0430
-9d67a06db4a90714fd1a933402df0830026920bf1f71cb0379bda8714415c9bc
-e7795fa4ebc37e819b3d8ee65375bfdd6b36bda41b7791864389e9b589919ee6
-2872bac2e221b28150d3024a984033899e5372ab474b9b4494f7bb4331b6213e
-7953565f35d2ea6da212956dab01571cbeeef86293c58a259860e294f69730e6
-f141680cf75d40e829f9679e98341fd1e0817cb8e40cd6c4fa691ac691fb59df
-b78e87add951eac41ad1b4f4fa45d2e346e0fa73157a7d2b2df89ea56a80e885
-9e0d0331d216db4f1b95d662bad40e472f21bbe05576ce4a2d27af01880f438a
-30c17bc65fb460ac1b3e01aa43aa3677ba05a437fcca3ce4c2864d99c701d79e
-3a199dbc7e2f00be8d4347f96b61ba0f88e90b49d412d0ed162e82715ea04c27
-af3feb0a7b3e4dd17c875a51e9bbed3c9e10eaabeec0f029d94fa90d60605b52
-2dcff539fbc323e7f0e1cbfc1a192a44345efc070bd5d5939d9f4383897704f0
-e785126abd9f582f1afe88a727784afdac3dca49892c6beb52cb1adee18034e8
-e88a441890175575951fd87594b63751e69165496d566bd23c8db4b9239bbaa9
-ef5058f5b51c74cf70632f88f1a05e1b40078c183ea8433427f63a5f68a1b81c
-bd46625b8ba2cf713c001cca4c74a186f93aaa3869a517dd64f1e81c71823239
-1934faea604cf4d9ddf974fb09c5786bde05978bb25209b5c7648602dd62c32c
-61ec4b5ce1177185354dd5cdf15540121b6d82457ff3111db1aab1889fb0e3c8
-38cbc7a671ba16a4bc567d9cdd427205e8f4de7edc64c00bb6080071130b43d3
-6e7919a5b7c29c68ac505ff107d1e2ab66a3417612ba2f461548f1e72c702a19
-7a6311dae649e46768d85d759281429b97a35379b84c763d35cfd434a4e3bbb8
-4c6e5ee8dff3a7449bec14c785bce1d4c617217ee6315fda000f0c54d1054e80
-c8f9f452daaa465f633ffc3eeda9c76e7a77024eaf39bd5bc9562fa44f3da9ae
-7e665a33bd22aae6dbc1d9efab63741e30775eeffb819ff933342c8e6b978f8a
-2aa20c2f2810072c4f2437e7cc13861002ab6d5ee84a6f80549683a34da3cec9
-e3471d112332ea260153836fa24e22eec0cdb0a5b3b0773cfd237daa67c55aa4
-cbf1cc30f43183a93bf7d7068ead32ac8064bb1f0a8bb61cf5472bcab360cf71
-b61c3443eae4f1ec7fc0d883559f8a2ff2522dcd7dad5f395e9ab2454cca6dad
-07bb58bdeb1e54f75816dabea8d170974909b2fad53f9a69d97eb11ff20c6aef
-eb6d76e9fa93c317115602db90359be638da383d9e01f6bdacb5ac5bd7c77d42
-d80646ace9f2384774610f63f97d70c4e81a2871be0a5b028c88afd82a3b6376
-5d5064a6786a829a6e6320120395b1541bfd6e3ec182d50982d7bec4140f146a
-06890a79b85a6f20f9bf616f5f56e02752c5d177a48aa2f8ecb67e42e2314850
-d2109c0965a55d1e0f470371443991f9b8859ac70bd6f049dbf57ccc8e2e3c67
-eb8d1b4f36c660746008460ebc0f7284c802925206b968477a503dfa6879794e
-7ed82fcc58443fa1d95fd561bc9d3a2ccb2bfa19916d8a88e6f7eff0ce0a7d4d
-90c77f63bc75f3368f7a97dea9d9392e3f499ae4b8e53602636cd53ebdb42213
-c2668a3c618a76f6f5a96fc33c0e41ef620a63e3c52512c66b59f810c6b85923
-d81ff8618f42ee19b10d4d088bd6b784e4f9bd6bffe083161181b2f79b374fd4
-b846650d4b95b6c3e58449d8f0a201aec72d87588c54fbb3112045040109a3d2
-d98c778ed3fe07f54010773b628baf29ad3b91072fbdef7cde0b969d0b695bf2
-5d386c6b8647bfd55c169374c57d5bd8fb29af5c5a6718d7cee318a06ad35d96
-fbf879929e28bd43b583aff2769688e087b00ea95b28629a71c6ea847f988357
-da9e23422fe2ebc4c33f183679233e0d1d8150ec58ca6ca0bda2a529e6f6d146
-92010b1eda6360aac940ed23410455209383b68c3a1fd68a0ef92d16cd4deda9
-9dbedb1ce18a79817fb3d043f919f1b98c62ecc70dc27886b258428ae2d1075e
-ef8c1225f96be5ee3c1b4e127d26bc2abc6d457333a0d5cce99dff00f3f41e0b
-a9fd7bac9e96691cd316abe913a6edf95c6c5d37086cf3cb960b82684ce473ed
-574fd8c6ca059bd679441c22e6c39376d3a33c8011361c834bbd7b87c345a9f0
-c6cc1328b5af926f763bebc13be92238da171124de119a097d65e5d623cbf157
-a4e93e250a6bc34bc54feb2889da3f5993eff0bf38ef6e440d0bdb405746aa70
-4e5de570b0347d52b25ae9e0ffd758b8d6da1a57e47289a26d0ed30e31474273
-c2315c74a39e6b26f558dec140d384cd3bbd7246bf46a0f7becce45fe0c343ce
-78016204e814dccc58061d48ffc808423452985b12d28c94eaba89eda793f7b2
-8d9fde11f30434bdf73c48484a814ebe541f4e6eb817de43146ae4e04fa7129a
-ec0e4b92ae22a1d2344375f68314d839aade59c4ac1d556538fd7a9f7ee9a139
-f3620952c6c45f7181a6448a807a1bf62cb59f440199297cbc8a360d0168c153
-7c6b3ba56dd0f7f104271138846a6f305f2c8a7536512c54a1c46232606a6649
-81a8083d59a4b5e8ca2cd0b70dd0b44bef1c2ae9ebcbaeecbc7c4bfb2ce309f7
-830ba06f3c8e79fddf737451a67d8c4425c51e11f832d99198c16dee864b4c9a
-e48863f5a3cd0e6f3c5b31a6bff527bce260aefbc40b1d8065d2f88f97dd9ff4
-8b21d069ae8cebaa511f0d00c1da76207821859bb191d5f9261adff3e6417788
-5b493db49420f472496a8207d3f2d64fa3304de0e78d6259a626d8fdf81c51d0
-f81ef8c619507f0544ebd3aa8d1f200a5ce240a1171441438d6bbb19c0850bdf
-4a0147baf4787513752e4e052a09d6b94bec96107e64f6b2692bedf2a38863e1
-15ac2564c0eb10fb923ef3d505f750bfb6407856406cc92e9b2a3a810fb49ef8
-e8f445c2e32b30d352fba6fe345c8af241307e76c13ed376554b857b23f2b10e
-9f4f1d6b25ee850d744332fb73349790426bc3adf811998f84f4721247ed9dc2
-cb33d343ed9fcbdd001d97708408a4885ef05908333546167859788124f50eaf
-7f9cd5b7a9f4a77b2337f51569fe3fb45e41dc50394ec963851fef76ed67592c
-bac68e378043d77137974cb61772228d63d46d92821662203dcc0dd1db375bd6
-95c9153c7226202ee545aa36b0bfba49bba59e918e3bcad377cb461d52442b9c
-d159764090efaa0a887a12b0c9884d4eb0cbae8b2b5fe1d68b8b13abcde73223
-234063907a8012134dc42337f131ce012a98e582fcc50c9507c1f87b83d62dfc
-bb951dd48c3fb078aaebfa25ae1908f87d97915d86bea53e23c2c4fd426210cb
-a517ee3681183d327a5ab42c02977c3221213e76ed5f986ad6bcc14f50651367
-f142a4dc6379213974fb90a7be
-0000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000
-cleartomark
-%%EndResource
-/F392_0 /ERVBFT+NimbusMonL-Bold 1 1
-[ /.notdef/dotaccent/fi/fl/fraction/hungarumlaut/Lslash/lslash
-  /ogonek/ring/.notdef/breve/minus/.notdef/Zcaron/zcaron
-  /caron/dotlessi/dotlessj/ff/ffi/ffl/notequal/infinity
-  /lessequal/greaterequal/partialdiff/summation/product/pi/grave/quotesingle
-  /space/exclam/quotedbl/numbersign/dollar/percent/ampersand/quoteright
-  /parenleft/parenright/asterisk/plus/comma/hyphen/period/slash
-  /zero/one/two/three/four/five/six/seven
-  /eight/nine/colon/semicolon/less/equal/greater/question
-  /at/A/B/C/D/E/F/G
-  /H/I/J/K/L/M/N/O
-  /P/Q/R/S/T/U/V/W
-  /X/Y/Z/bracketleft/backslash/bracketright/asciicircum/underscore
-  /quoteleft/a/b/c/d/e/f/g
-  /h/i/j/k/l/m/n/o
-  /p/q/r/s/t/u/v/w
-  /x/y/z/braceleft/bar/braceright/asciitilde/.notdef
-  /Euro/integral/quotesinglbase/florin/quotedblbase/ellipsis/dagger/daggerdbl
-  /circumflex/perthousand/Scaron/guilsinglleft/OE/Omega/radical/approxequal
-  /.notdef/.notdef/.notdef/quotedblleft/quotedblright/bullet/endash/emdash
-  /tilde/trademark/scaron/guilsinglright/oe/Delta/lozenge/Ydieresis
-  /.notdef/exclamdown/cent/sterling/currency/yen/brokenbar/section
-  /dieresis/copyright/ordfeminine/guillemotleft/logicalnot/hyphen/registered/macron
-  /degree/plusminus/twosuperior/threesuperior/acute/mu/paragraph/periodcentered
-  /cedilla/onesuperior/ordmasculine/guillemotright/onequarter/onehalf/threequarters/questiondown
-  /Agrave/Aacute/Acircumflex/Atilde/Adieresis/Aring/AE/Ccedilla
-  /Egrave/Eacute/Ecircumflex/Edieresis/Igrave/Iacute/Icircumflex/Idieresis
-  /Eth/Ntilde/Ograve/Oacute/Ocircumflex/Otilde/Odieresis/multiply
-  /Oslash/Ugrave/Uacute/Ucircumflex/Udieresis/Yacute/Thorn/germandbls
-  /agrave/aacute/acircumflex/atilde/adieresis/aring/ae/ccedilla
-  /egrave/eacute/ecircumflex/edieresis/igrave/iacute/icircumflex/idieresis
-  /eth/ntilde/ograve/oacute/ocircumflex/otilde/odieresis/divide
-  /oslash/ugrave/uacute/ucircumflex/udieresis/yacute/thorn/ydieresis]
-pdfMakeFont
-%%BeginResource: font BZXIEB+CMSY10
-%!PS-AdobeFont-1.1: CMSY10 1.0
-%%CreationDate: 1991 Aug 15 07:20:57
-% Copyright (C) 1997 American Mathematical Society. All Rights Reserved.
-11 dict begin
-/FontInfo 7 dict dup begin
-/version (1.0) readonly def
-/Notice (Copyright (C) 1997 American Mathematical Society. All Rights Reserved) readonly def
-/FullName (CMSY10) readonly def
-/FamilyName (Computer Modern) readonly def
-/Weight (Medium) readonly def
-/ItalicAngle -14.035 def
-/isFixedPitch false def
-end readonly def
-/FontName /BZXIEB+CMSY10 def
-/PaintType 0 def
-/FontType 1 def
-/FontMatrix [0.001 0 0 0.001 0 0] readonly def
-/Encoding 256 array
-0 1 255 {1 index exch /.notdef put} for
-dup 32 /arrowleft put
-readonly def
-/FontBBox{-29 -960 1116 775}readonly def
-currentdict end
-currentfile eexec
-d9d66f633b846a97b686a97e45a3d0aa052f09f9c8ade9d907c058b87e9b6964
-7d53359e51216774a4eaa1e2b58ec3176bd1184a633b951372b4198d4e8c5ef4
-a213acb58aa0a658908035bf2ed8531779838a960dfe2b27ea49c37156989c85
-e21b3abf72e39a89232cd9f4237fc80c9e64e8425aa3bef7ded60b122a52922a
-221a37d9a807dd01161779dde7d31ff2b87f97c73d63eecdda4c49501773468a
-27d1663e0b62f461f6e40a5d6676d1d12b51e641c1d4e8e2771864fc104f8cbf
-5b78ec1d88228725f1c453a678f58a7e1b7bd7ca700717d288eb8da1f57c4f09
-0abf1d42c5ddd0c384c7e22f8f8047be1d4c1cc8e33368fb1ac82b4e96146730
-de3302b2e6b819cb6ae455b1af3187ffe8071aa57ef8a6616b9cb7941d44ec7a
-71a7bb3df755178d7d2e4bb69859efa4bbc30bd6bb1531133fd4d9438ff99f09
-4ecc068a324d75b5f696b8688eeb2f17e5ed34ccd6d047a4e3806d000c199d7c
-515db70a8d4f6146fe068dc1e5de8bc5703711da090312ba3fc00a08c453c609
-c627a8bd98d9e826f964721e92bbdc978e88eea0a9c14802ebcc41f810428fa8
-b9972032a01769a7c72d1a65276f414deedaf1d22be23f4705bf5ef31b6a3b69
-0c896320f09e9875b50220a5bdbbd57c041b5ea97f421685a7256b0d9755edbe
-d05190dabf1c3dbf558258163c8231d89167a816bba55fb1f14ad04320ae381d
-f783a9eacee8ae5c1838775fe2380bdd1f3afcccc96d2a2dfc999b52a6689c51
-af82b8d63205b339103134dac7e3c45e6693940276041bb07ebdb9b729e8ef0d
-ee8bf450fa42551be65217fea902e28decc09580b504f0f52f1e8fc5ce7ac28d
-c4e47f908fdaeba23827a97a0aa741aa7708f7bbfec6fa69cc4f7c3bd4
-0000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000
-cleartomark
-%%EndResource
-/F564_0 /BZXIEB+CMSY10 1 1
-[ /.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
-  /.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
-  /.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
-  /.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
-  /arrowleft/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
-  /.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
-  /.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
-  /.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
-  /.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
-  /.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
-  /.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
-  /.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
-  /.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
-  /.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
-  /.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
-  /.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
-  /.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
-  /.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
-  /.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
-  /.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
-  /.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
-  /.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
-  /.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
-  /.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
-  /.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
-  /.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
-  /.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
-  /.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
-  /.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
-  /.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
-  /.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
-  /.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef]
-pdfMakeFont
-%%BeginResource: font WWWUTU+NimbusRomNo9L-ReguItal
-%!PS-AdobeFont-1.0: NimbusRomNo9L-ReguItal 1.05
-%%CreationDate: Wed Dec 22 1999
-% Copyright (URW)++,Copyright 1999 by (URW)++ Design & Development
-% (URW)++,Copyright 1999 by (URW)++ Design & Development
-% See the file COPYING (GNU General Public License) for license conditions.
-% As a special exception, permission is granted to include this font
-% program in a Postscript or PDF file that consists of a document that
-% contains text to be displayed or printed using this font, regardless
-% of the conditions or license applying to the document itself.
-12 dict begin
-/FontInfo 10 dict dup begin
-/version (1.05) readonly def
-/Notice ((URW)++,Copyright 1999 by (URW)++ Design & Development. See the file COPYING (GNU General Public License) for license conditions. As a special exception, permission is granted to include this font program in a Postscript or PDF file that consists of a document that contains text to be displayed or printed using this font, regardless of the conditions or license applying to the document itself.) readonly def
-/Copyright (Copyright (URW)++,Copyright 1999 by (URW)++ Design & Development) readonly def
-/FullName (Nimbus Roman No9 L Regular Italic) readonly def
-/FamilyName (Nimbus Roman No9 L) readonly def
-/Weight (Regular) readonly def
-/ItalicAngle -15.5 def
-/isFixedPitch false def
-/UnderlinePosition -100 def
-/UnderlineThickness 50 def
-end readonly def
-/FontName /WWWUTU+NimbusRomNo9L-ReguItal def
-/PaintType 0 def
-/WMode 0 def
-/FontBBox {-169 -270 1010 924} readonly def
-/FontType 1 def
-/FontMatrix [0.001 0.0 0.0 0.001 0.0 0.0] readonly def
-/Encoding StandardEncoding def
-currentdict end
-currentfile eexec
-d9d66f633b846a989b9974b0179fc6cc445bc2c03103c68570a7b354a4a280ae
-6fbf7f9888e039ab60fcaf852eb4ce3afeb979d5ea70fde44a2ae5c8c0166c27
-bf9665eea11c7d2329c1a211dd26bb372be5822f5ea70d99eb578c7befd44cdf
-045a363056e5e1cc51525ea6fc061dcebb337208eff729802376a2801424f670
-0e7e6397b28f15bc10b40012b0a3eaeb2693e8f7f627c4c9c7c6c5bff105c1e4
-1b2b9e8f09253b76040d268b80719e1b3f5a55ab7b8e134d4cb5abced39ac635
-da001e9934c198a7f9b9ed0028a85e9ae00421dfd8eaa3bb3b4b4ce45d209303
-237bd51809fe4d880900b1eeb236aca87b9ff6ebe6b994a60af5d67ccc42bd56
-77295c346eb4c62bdc1ef22ee07daad928dfb73455f091f32408ed6430b97417
-683af27a03718a156e3f6e7b6e4f2e8177503cd82ddbf4557a3ccff4c858ae7a
-f7efed6cc521a28342436b953e4650b5792be85ea2f989eb6d986905a61fa38b
-96e1bbc830b74469150fb0b598a794fd80d10870084a877273a9502c3456e5ef
-74350e6e3be5863e8ba185eb59fb87b36566af71200b6ed389d1287d4e925e33
-b2383ed05d87d48586e698fbc5d562ed9d8a09ec3eaa1b1f300224af20c23f26
-a2eadc74562571da84b3914d1d80b127c6ff4706c7046bbb372a0013e0ab94f0
-c27946583871d272bf4f20fa84e89d745de7bba885cc09ba72e0f530ed4ef7d1
-864b3c67007ed98800284235372f0a70c912e21e851afbf812165b8df912cd1a
-013e271f0b347967876c68ae4c4107ef8ad1f170916210034c66394a9d971b68
-fbfc1131e37fc178eb97c1b2a0f573add9d7c0bf944e6529734df8a7ef54485b
-a3375cc30e9e328943733cbd352bc15b06c85bfb4a96994291c72a0eae84fb01
-0f1b24d0125fb8c16d60561df8bb7aa7ddfe9549afb70c1e89424214609fde41
-9a142892e30f02754fd234ceb3c59a2a04c06bab7ae40e8fdec50559b8347684
-391c750987802d5452c47c1e0b5f222de9a0eeafee19d796ff375a1e1ef0aeed
-1bcac4f485fcaee18aec585d1a9d80f41871dda45fef1eae82c5893118987beb
-4d9e345c27c7419fe65e4853b40537d822e34ff1e0bd2819d21ef607981259e8
-9f1040a2d708d7463858aa5381759ac49df4dddeb209a278fe60bd2508aca0f4
-6a249a05b652e4c7bf1b676943cdc4602910fa3ea7636985a10f637832a5abab
-9c7a580d605929d6d7154506217252a755beb8462d30a798ffa9b26e500eab24
-7e9fd612c776ae60423995dc1852686cb041e66357a9acd4b6a4e9846b1dc803
-23dab6b7765205d82b50cc6394e725c19df00f7db427341d514047e4bc594efb
-a262eb2c414e43d8acc9cb195d12f3b2a9748f38edb3ac3447d27d20d1e62bbe
-22f6378e508f0cd6f17ef1c500407f6d442e92ef2e00b8de78660d87fd1c7209
-ea67cdb37076e1eaaed128814a948e27e1f2fa81fe54be6c57ef8c2b2e460f08
-6ff1bb529c9100b1d878dc9a077d21805e89d8b0fbc2a074e4b55a869c96fca7
-8117347b9cfa480ff4a37b34b040a99fba99942bd86ce4b46ff5c69babca7a3a
-f5018da05556bff71ecc844b2b718598f0825cda3d19d714fb66472621113ad7
-bb240de7dfbd1f17ffd8f2ef4b85a8eb6e1bfdf26c7f98168197c02c4aa535c2
-0f9ef9b7cb7f1d174b2e94953f541c3b84d43366e0e00a028b98f990b4d01515
-3ccc2e1853473bb9b25857e4b8f9d6695ef332bd3baa9ee551a4b142defb7f03
-97cd075ef9cd41082ccbf63e849c48835e105923e725d41d2b5ee0c3f03a603a
-161713216af97bd21aa87e3a80d75383603152011530b8abd2294d041e90a040
-f61baf86be97f8daa8326eb1a2b4511425785f35f75835683515af6cd0e73194
-2b25d5fa8c7e12ccde33aa193d61a35eba7f7e101843e35dfdf3e07a1442b0eb
-f2a9084634736a21128843df49c84b1061d0826777a754076c4c3d0a68b32dba
-ed4b5c0746ddecdd79fbcc7a4425eddaa7f49257148f05ff52ff6bac71cb65ca
-8ad5869cc9fd7c4c194ae8d5d20a730a035234d8f9a6363e7a49fc22bbd34d08
-eb7fd43a678be52b95eccf029a6b18a512d30ceb0b6adf80ff1232dfda1a5752
-b5222edd9012b45cf0df0644b2e713afef21255a08232efbd5d5f7506bfd050a
-f0daf55b5db595d29361f8253c26c37e09b4f87056edd8c90e0df4fc74072541
-8ad8ccea562e4ce72acc8e9f39284fca274c572ffec24ba30ef9db07054965bd
-2205d717c9b3b0723061cd74ec688b915ab6689904d5762629c891f2fc0cdfb1
-8d8a4d2260dc93d7ac1107b197d7e8418bbacfc660d888697296b7cc6581024c
-e583b0114ffe3b3a960d601ff23c0f633e2b85300042f717c4718c0547fd9b19
-e74d0e18f6908e4528065888c136dc8767b74025ef5faf470a272f57f548d738
-c5d2ff6def4366c1c08e0b09855e04ec3bbd8cb6b770f638ac7d852b7b2250f6
-cfbb5669c9112fbf73546a9c1e968a1e1a06128efee6422e41df1519c7346635
-31fea419bba8067c6d0e964143a0906762197b8de95502ae9bb54ced17de5ce8
-9d628716bf1e306aad09bd7f8cb2b7dae5bfa9ef53e716d5aa2ca014eae837c6
-c0f2d5f535ae93682e855b1bdd6ce955627284a4712f67c1d6de9f80d4dda43a
-9fe34fe4fab544459a1dfa0d1383c50bb3e6c3df078acb88db37ecb38aaabbb3
-cc59d3fbe6a84f1f9521b6e05d0a0b2e0fceae8eeea4f41976945501f32bb383
-455467d21777796688e57ae9b7b392d167b63bfdc1102565649b53694f1eb3e8
-5ec2f094ab06d427b5e1e7412b3369336c766a7fc778190dd5aeebef9b6a034e
-133314cb512667f1a4eef90a1251ca9e8aaf7966ec96004c09c4dfacbb0d4c45
-60d8df4183d3598fb9584a4433c9131f8602474f27e4916b43de80ed1d02f6e4
-d208b014c0a44d94ef709930eca646b2f07d8358d48d0a768b6f13492e3cb877
-fe38c58a7f5468af52ffc11b8c02bd91484cdc022abe678a7f2e298a7fad967a
-2ea7dc427e6ac154766ca4ae15fd414a76064823f3145724184e30ec4f1494c8
-78f7f63edea60daf2448de8a79801ecfd86a06ef122451dd2380bb1a4256a7ea
-806d131e66d5a6e3079f7c2d7c143e2879f5316ffebb1bfa166a088b8fa9cb7f
-4a5f0875a8ff5d378e9e8205c6155ea85756475ca5149eb72643b4ae1f907c0c
-fc8f63150cdc6209b1951af23ff68188360939501770eac39ed55dadc4dfb1c5
-b2ef39c93d0326a804f62e8f187a224444098835ff670ad55b49f3cd0aba2901
-293ae04427916ee14c81f4044a05d9c8ad14ad4b5567e8e0147780a0bd294c5a
-10a50a5cc7656f901588419108d2570e804a5e590004008776c8cf20b56d5ef1
-fa32538c480bcc1955321f954008871ba180177dea952fefec536f6522582647
-bc205dd139a18d2a41956baa4b002169cf042ab2ebf91ff203dc2e2559171910
-2119e94673a275d73f3909d0834b170e2b62beedcca27afb44a35ac51dcb5719
-82706f101b216b4af3523974378a05c327702b132335ff288adf62578f30cdcc
-cf826898361bd49238f368ae2182fbb631e375e903ed9efb911a047119b40830
-a39909494e86aee21694223df1a57ac8e5b4f0465d0868939ac77ccb448d3f58
-36631cebdc06bf2865c58437568cd734efbfa870214853232ccb48cc57c8c32e
-97cdeb89cf5e0c032e81de377b368f7d57187f0828675a52382d41de6cd9fb52
-2a1ccfde3192c650fcd7d1f86db03c401e6eebd0d40bf23c10e021ed66bc5b7c
-ae57d0905bd24925c8573f069139883bbde13df3ae05bec1771eddb9b003555f
-9d69657ac718c065a32ef7ca8a1ff5880fc66196e8123050a47ebe4dd5c1a4a7
-40ce1cf340bf08021fceef8172d9cdeb063f4e4c2205ae4503c71aec1836f9bf
-96ccd0a712e33407446ceab96221d7b3f4342fc74aafa802481acecee7243807
-390b2d12c844193560738e576d27b0f5a90b25e1b5a27de8a2c74b3303526191
-5ee0251065475f26bf0bbca5549f13e1357797a5728b46ba9570c095d938112c
-b3ba212c26cd6bb569ea276e1d8397569f8d4c78528490187a172d2e30dd0228
-d69fdaa25fbdb477c88d52f0ba137280d68656036c17b8852b03c21621d0b21c
-6c016f18cacfa9a998e972f40eda07278da54fe5119babf0145d6824f051cd63
-91bc93472f780f00e261dc74d6673da37d8d9291e25af279829f8d47bb524c19
-8b598ce1c576ac8542b5ead99b039ac2996a6d791a22a5d5bb0fa3eb65d1fa01
-401d5c7d44a9cfe082e9314ada6f4ac8ecea5be8e5a1cb6a1dba1c615e69ec9b
-0f231b64ac31c545859f0195bb9b403121df7be1ea1488b413825d8e1d7afbfc
-e5a8e1e52d9c3ea6de3ce75d013cb7396e825bac3a50d0bffd2d30c6f1c5dc0d
-83c1b68dd8b6042382285812093db4c5d7f6eaa8a4acbeba794f63610456a641
-42fdfd0c4c5f0c4486a6170b7701ca64cd1408f686fbd2afb56ba307722b2bba
-c542123f766171b43aae5ac053094a04ac4faa3cbdadcec81ab5aaac58d3a7b7
-1dbedcfe63d062b11dbcacefea89c6f8916389d3f7d93da89ebd8c37414c7db6
-d6512a4e8c76145ac170faf136a023b3c31cbae9775e436d6cb2835b77b56458
-6905d558a3cfab0f1f3426557a66bf775292df056cfaaca8c087b4c0bcc2aae1
-fa49f346602384f743be6b1aa26134ba2872366c17f1dd356221838a40be3a4d
-0b8502a964d360ea9bc58e4ffbf283c8294679197faf5d23aad1c89c3da84902
-c95619fa0ab76ca0c7ae725a1c5d9c40e84cc84eba8fc95361f3a738ddbcb593
-b3110db2f69ecf9da21d788d36a1bf986e2dd78c9e62f643e6677f80991f90a0
-8bd35484fc4aef3243bc3b460f57bf6f0a503b57f84723738e1b94c3029520c1
-f8d787f99305ef87fe64293b5fbf0a378306459c022f4127f2e2207ba818aac4
-1c860b70833b92cb7228ab2c8f68d03b6ecb67d4f83cb160c170298e1bff339f
-306505ea4fe86929f115b3c55c7fbdb7f09eb38f7c8ca86c9c89d9b92dae37a9
-5839a181e6e55835da3e81c8846980ec5c16646a31bbffe54a8505e005c9200c
-cb2b476083d7e55e63648146e8e615d349ed779b787232605beb38346e3578bf
-d043797edc00f6df91c9a02958ea01f55f00d576c8a8d236e81b59eaf96bdfe3
-4de4125a3893acea97aa8d6373b736d4cc0166095bbb75b7341f06d8e3fb732a
-5539fa8a27abc1d82f1a86a76870450fdebbe889dd048cbf2f184dcca5377649
-9ca0053aa9a88ab4d6f279f8a3ba704ed057dc2a361d07e5af6c9c8ce4b08c05
-d06635afce1cd7fb1288df9ca1f9a556d1a120691297d8134214da14db45cdbf
-5545abb75134d45257b1e373eaf23fb600370cf8e7de02e7211639b11f8fa0d5
-6627c5718f554ca3351ac95c04dbe894e20692065af2c7a9e239449df4a65917
-2e0fa2bd3ebffbffd9093569851a31db46c8c30c1fb8339a7f742a2c89212831
-15459844298972b8b06e2c699d6acaaf331a023047e5b2041fc39d830b0851a5
-8ef1e329b688034f9c91927cbaae2ec2c84f8502127055ade448d6dd7eea3aae
-392dce03347141b3b85f3018b3396b9fb1e4a59c50d9e8b82610088575eec663
-5686e7234e72e4690ce386fcf9d16b54c9c692e9324427dee7e096b6d4c45501
-da2d0eda66a1f29e90c00fd2c62ae43a97f611794c4704d179ce0bd63ffc4f50
-ab3ca7086bf942283fb0d175888a13e5278aaaa25a26e3df4fbf13e64519ad94
-44af171207f3f89b369ccd6162c0ba1320d30d3a596d9f58976f94434c1fb773
-e70be87528a9bd5fb7e494e6cdba0a3cabab8dc2073ea7f5b956bf5d5ca1b258
-25a73e0824ce8d00f4c945c0afdc4b57f7c0162a14b30154b61ab030a73679af
-d43e322a04fc7b3c814f3b2d07585eae6a5254b43bc836c6000bf23a56fbfbfe
-8478f1cd00150ee39f0aad2c7ae3313b8d619b84ddd8cd3878a4b306950873da
-9a592f520b7d7e0cf9b9c97d35139eef9c329763869e64d89a52fed016e1cd40
-4497359d9d4d6bb70222418282cd9ed7f12c16cc1aa6b3eea9c812b7c3910209
-2831b0f05e644f58e878c1eaa3d587c89b26db8b9952e0bead12c7db6aa5a042
-9e33012db0551fe6a589baa800905a7cb35d220efbb675a96444edd18ad89dbc
-ebc4087162e977b4cc680a0e3490bfaf28a556c3bb9299935097e3e048679849
-a85ce906f55bdf564f3cca2b0a70b404d02520b77614e577231cb2310dde1ba5
-cea1ef926ad191c98a21ed76ebb8f407ea2ae2ff56014216abb118c0218590f5
-f3284f9a187a85b3f5091f05b21d747f6fe7384a27ae6a8ddb923df4f61900e9
-adb8be5d338613e1486d710e892b5b733061951d164ae233023a69e02457e90d
-dfb6d8a53ea0a57f3c9e27614633ace3c6cf57dc8c81d0c079642c4a0745d281
-2bc6ac4587a56e65d6955e50f4380d94f9628c130102e2a3325d694865a0dd90
-01ab118f393fd86d01aedb5612fcb49e8b81fa6fadf7b69650fcef45a0a724d9
-ecf8ced5cf56913fb68a39c71350acd855433cc25b25ade198cda46bfccf1fac
-f1c841a1e6058a73e26e580cb46384885c417799d92822689c2f58bc1e0a040a
-9d7d3d73de3c18688d62581d54a0eadf9deffb3db34a9f052bce33d5fe8e8ae9
-78e4b0bdcc2a8ffdcaa5b4c0f4a0256d94364e70e1749dbc2b147d69ec539b47
-ef868ac4807f7ac1f01c93b3361942915581efc754453f221f4a70bb903ec310
-62cca7ac392f6f70b61f49822cfd65c668070babc1102322e4cf224902f0cc6e
-26bb2c119c3c66434f4a85164c49ed51084a1f0795eb631f6d38123619cc5ced
-c8c6908f380a4a3f7939d0b03187e448fa44333ed8d8c2504c3fce0235795d86
-f7a7bb423d1a7ca81b27b4f81c93ac95ba336a0d8e6bb90c96ae775ee34c07da
-5cd019a73b7944424d242dd7d96ea0349307ed426fe0c7fb8b5cbe3d295a3069
-b975fafbe78109cab35ac2fa5154f66af9b9ea522cd4847408d1ce24cf7fc770
-4f222fedc962ff21d09aa2ae6cc1b14cfbcab5d0016607362d3c8f6347f7a54e
-821327ddd475396b465b1bf5894703c6de1e9947e64867e68efb2620c7f46367
-c0c345f294b781943f0c96500688a08347b0272c60e5d6a7810a44c4e5654d09
-05931a57e1fe6ff7edd1e77a1e1c39070b49e4d72a62f06340f9a76d0553905b
-35e5711434d25cc3b14557bbaf66a82a6ef543bbfd14c314ddee0ee99090482f
-c1dd06eecf203ec9511a3ad6ccecdd1139ccf31dc72e407853d159c1622131df
-f560bd84c30c58439b06aef79bf53ffaa90ab3727e59f164271a69c5bf36f0d8
-3f9c0099933b6bdfc2f613d4f3565dfbd0c85e8723491ead13697f8945f63a6a
-612990613b54bb7a19c1d3a13c14f19694e3b1293293a51c64ebe436738eb61e
-2ccef09ca77eeb35c7bf10db2a9b1eabbe4fb88ccefeae6359bf5e136ee974ea
-a1a5c7152d54de8dfab89422943ad50e5884f330ad4078763ea071c6265e555d
-a610d246133435db11c37e786302e3e8889ece1d9ec3670d82babfed7be2fb7e
-fdb78e1b6e1c682b930f48bf0a28301b463a5ca77c368f7d57187f0828675a52
-382d41de6cd9fb522cf52d8792796fccac48d9528d6ba65cca775eea0d9e272c
-084f8017bb4ff779b615a46518b256b2c43b27e28b988bf6b60d783d56905a5d
-7794904c0cb95e2aa83512f47d2c393b778b7611053d31bbc4670c6ffe45ff25
-2b7064e4740e8895169607d57c89956b526a664b28a2a9f7c42d6a40c4a95aa6
-6be98967f52a855db02c498f141fd6afffc0a69b14bbd009a0c0f023d4d6706c
-cc05401aa96d550b6ce0190281ba4cebf16acfa4fd94730cd977d6c120c124ba
-ef8489e22a13c30552196e99046201ccff11cb3aff92a63e47a10a3a6433bfc0
-e77047453b71527f209c939d8516182ca5f0966ccbf971fede25e3fefd92cf8b
-fd11ac59dff36c25aaa8c771a83d9cbb7dccb37f4f7572f11f702bc27ea9510b
-a2d4baa94f5953beb927aaf2426421f0093c603bd63827e28f17d57cef476577
-c1f13eb8beeada42a1eb221cac3dccd5d84a6f74fa2b289c3cab6e2fc94dd92b
-d96a015b218ca7facbe18f9c7a580610905847a649e4477773b87686f7f28b33
-24148f4213ccaac483b43be2a9763fdbbdbbd50a0f9d59fc31f5b7b2ac0f915a
-89abd64d84faa62a4c3167fbbf651a6236ead6ad931c11435921cbdc4ed66f67
-fe83bc059fa0c625001ad5b3bf638293646d33076f3afafa8b8fd7307da5c53b
-5845999c1624e9ed30cd48483403f9afdabbcbe80fa5025bea2cbc081e2b32c7
-42685421ce3d574a414b340075cb02e80d7427d4cc503ee02f5b33e509d76e0b
-21b5d5a252757c4b7893dd9870f9371eca57ae78ac688ee28c31d597bc018496
-3fa54a8e160a77dc8b0627d7319885fb2ae0e2e2c9fbcde4b5a7acb04bf1e611
-b73b0dee3ac8f44c4ca15dbeca20c35a7a8805f3c22e6fba8e9b22722dd25ae3
-ba2dec2a0c9a13509f4c9fd3dba03ef6e49a632bf7de5ec45b64a1f4e3a36976
-1b7a9c7b95bd29b09b930b0d82f2c39f9bc3c24d99c58a664d4adedf7b74e13e
-6d85e03e615a60a2aee9f790c6d0a2e6e82e6840e51b38c4579fb95337423fba
-437d97ab42bafb1097b2e2952e86c88e94ba7020e83163b5d810de8f57625819
-d86d7ae834d7135e30f2e21dd061ff15f22de6c9243d2caaa5abf67abee3a6f5
-306273037adcd10e8f00818ee88ad2ea98d6b7f1ee7e3d1db49a57fa350664d6
-021078ee1ebfbdbe5aee9efab2acd9809ccfb180f8017a84ba6bfc1ba5940eca
-3076c863f8d9df3e4afb32361acab13bacd3e465d094b64bece987be66fa501d
-5deba893368ea3fdd3b3a4201d3bd68b3464ead10c6f0ddf513a630e0133fec8
-08630e4b3c8b0aad1bbeed508e7e03d41b3d060a92b1958407843e4cabd78d79
-ff72fc0e92f4903cfd05856f457dd15b1aab99c1d29804d2f3134c9817f45fd2
-efebb92545f056f4ca76ea74ad464cd041b7cbb8892f2dba833118b83e20c039
-99939ffc6cc50503bb871565797ec537e26eb622fd30303273748af2afd97e07
-a9c2a96f4ef8754dc3ea8f3348cb30d76bdaa84d2e933c94c99d13e74f19970f
-5d2bd19712926e230dd02aeae6461edd83ac935ec2f420649f82d4160a072700
-10141602c3a6572740d8e97fd08e56b987062bb57237bbb3056a36e97e399a7a
-cf9653743a9984ef36254d60772a0eedca800923461a3e4443a5ef469aefceec
-aa1831e56b0d8ea6ccb76bb9dbb6ab7584ee268bdd0f5f0d57eddba9b97d74a2
-910f178f388a50fa32aad7b87b3235efcabd4b5009190d12e8c770f6e70dbe10
-e747e1984a1c41d701e6220b001fe25b9a677c996f8fd91bd40fa7e07f57e8bd
-5d2381442b337924e56de4d18cdc352314caebf065f610b00b50302bae3ad612
-dad9059a3d7f3bd63827e28f17d57cef4a8cb8af1f080a993c3c74871e4b7bdb
-2602d07587aed02aa783d80234b6eecc77d163847e63d3c9aa412d10acea7a5c
-5ece5b893bb3031facee72701acd225d6b6a752cb2f84de3ceab2b97b606a0bf
-c6874869a86e3a55a4e1d7abd94719f604ea68b1108ebb5bebc3ef465bdd2cdb
-864ecfe0d6959d5114eaaf1612c970caa2c94729178e6af130a1df211a3795a9
-b5fb934e47f6c48155a19acce788036b4867f90d40c1e4ff7460399f1f08f98a
-0aa3e0d8e354195a2563759dfe0183c8d67b449516ed8f5cf3288f7298d62092
-922f07027352bc7c9612cfca46f1cf2ed1417ab863c2615f2d26ee13d7a04a18
-8336ec9961e76af2f506e3db3d67a2a4fb2dbbb0ca34be6db9789a1cda607d9b
-35f0eac47f488bbe74f8f04b49dc492ec8f096e6710ad59d248a0c98497541d8
-5f9134d5215b0a05fc29db1aa71e432a2c0b00106bf3124df0b72c144375a280
-9cc5ed8335b3e970eaad9178f43011b55d7f3e11d89be1058361893016254440
-353b88162a4e7913721092e05573497ed693f3120176dc08253d2356559041d8
-741a6b9c41f8eb695369633632ffc35a1e2e4ed6258f0a8eef0bf6bb028efed8
-a679be4bc197cc868255f748ca953312eef556d8fdae4e9706c3116e76140587
-db18492730a14e96c211fcd0aeb0d4324b1b4abd0150637c6c135fcca1823fde
-20482dbbab536f87e1d3f0ac4b5154e33bfaade3ac4af8b8d2082658d35a251e
-a0d718f702ed8d957555331c9593abbf64b2194dac9f098773ef4313cd8a48e7
-4d60513d6ee1c132e59ebf5dce2359b61efd16fb4cce810172abb3939e874792
-a862462c72895461ed4dd265abbf52c11c50e607fd3bebeff0397398f656066c
-5f64fc4e67cf5f984fe818c9500cb10beadc1ac513c0c8e60701144b949ce67d
-08cec1adeb70fb01f48abfea22412f4b07b710a8d774228ae156bfdd556c0f49
-bda072c0926a08150f77ee338b3b4303bd2186da21b89df804cd531c499ef953
-9b1ed325e5ef952af05cf67a9fe64b1af975c18348809161ad382debfde45495
-5b32472edf5098b6d1f8fc8807f81ee5be3659bd0f47542ee81e20cbaef168dd
-4b991069cda2f850b1faa40e74fad79ed5f74a0fde1c060996a2280e9c9d21f5
-d23174d3ef4d9eb6e337d443cfccaeab8b0015e6427f9439c8473a1364faf782
-f58bd8bd775899092844ba570c427dff47b8cc4859fd9042ce78aa27ffea8b5a
-c52be0d97cd01c7250a6eda489b5a17e23167239e0d7fd8f3429529ef02548e9
-b7bc1dcfc729600ff98d9f9b33ecdd10ff78baa313b7e35c51dfe8c6a17568fd
-bfbd434860a8ef3821b336783fa328279c05b05aba37f8d26da43391c9cfbd71
-6b240148995a005448afbe45ef2c2853aa3c1cf3ba6434ec79e8dbacef443569
-8e6ef17bdf960e9a37f0b34f4aa39641492bcce95afe55d168e510f934288da7
-c61eb3e1a42f18abc608995cd8c9afcc591751bcd9759387d3924751b1a2c79a
-0cf18b53d3ed8096e2c559dd001e8bf6824b3eedafedd8b89fa23f4aeed14435
-a7d05da7b0607edf2aab0816e866f6791e834bff5f5c6699edb97df199549d54
-3d039671a481d094352ec76d2f7e5119887ee3ad1117f749a85b3b6f37e3d25f
-25397d1d019da9c5c6fbbfbaeb4fdf0a423f6394968f2eabc560f76e75b07b54
-a6d87328604fc86be37a1e8e5790eb845cca88bbc2e01eab28a6d6615229658b
-7554a85064aacf698949e4f56f2bd61bd5af31bd6012ef0c1bb627cbeec71b52
-e99af95f699617a8462e14e144424a64e4c1cda80a13cf7b20929041b2df6686
-15c2f77a73f9cdbca33cd11188a9a608b240b27e7cfc5234fdad6db5d6565787
-d99f45709674690ee704de4ce6accc37343eaac02dd8ca368221d607c4ea24dc
-05aaa5162120301a8fb4c3166ef0e813aab536200a8d54d3e0679cbad59cae0d
-d9c251016336c63243b42f4a439af0f1b4d4cc3ee9c24dae5ec87c10b4b046eb
-3877eae636101c3231319957690cf7cd562fb48e44abd46bfd8640de5348a01d
-8389dbe26165729c3ea1023b354cc6b6928922cffb2df9ea60d853a74067b442
-a7d4938296e2ffdeee8b33dae2ecf5be2451fbe3829f9c1d45820c9849176a43
-22694f059367670d68ad12080a84603821f867ca37dc727c3c5254103af21cd9
-034f679aea5d4bc81366245725fa46cd671ac9251817e8abbe9f06f182b738e9
-05769b0d6a504170334d09bb7b809c249ca9678658b36fef98a0f8936cc9167f
-31837fb2e92319b8e4df5168494fe90a12a88b93bae098fac2f3af2c087759cf
-0fdc3d901e921222a19e53c654d13e52a6f272bd65e3deee14e3e59c6dd9b794
-dbd476ccd4deb50e94d207123a5bb6276e40177c13adee9227e283b51bdc8e50
-2af8d9f3d4cdf61a9bffdb5047aa305f7c61fbb49440b70993c9620020fadf15
-4b5248e8e2a6fd5638a447a593b320039eb53a709e992a481c0de5f19640c17f
-cdcfacfbf7b5252c0274c53f6de78a11db640076e01a11be6a63c3a8be0e3fb0
-f0c1f40b379b80399771b0b23aa0fb934ee3184f0c18d5cb40285510a4eb92f1
-6f089ce3cf32b52add23b0f6a436637a17a71f90e8c91adeaff7eb97220a17b7
-354ea80c678e158c1ecd586f0e2e6d7ab5a179500d404e19a65db6c9568b0799
-330d69b254d29e704196964553817ab428be257c5d51aac61ee9cffcd3ec4615
-1d6e9992ad91a791d1c2465df24757dcbc64f3788b15868b905e53ccd04625c7
-f04fa267d68a6aeb59443ead9bc171f845b2b0d7ac7e788c21411a1d4b3935d6
-ef2093333ce092da5d06fcf6c1f1afc68db00cc1d0090f21046b54694f5162cc
-cb07ac6e81a3b657871db0692cd70edcfb645c335167e08eb15caa6cbf6419b0
-1cb28d3beb8c5ab6c8f77663a2c258177a1feb9abb560e903b45a1d14644a08d
-778a0db918b36ed5a2d6d409adf41a21b13211679094cf290c4652633d861e1e
-2cf20b69ccdcf17ac7d4bc15febe037998b98c176369d225995e578f62f6e548
-049da929686caf8b58bf1baf99bfd7196c8084419d381078ad0bc6bffbe163de
-15a4d0e6fb53208aff06f08967882b17c0696f060218ae037682036cb39365b7
-33d8c2b0f2414f3c919473a6abc8d419f70b541a62082602990c3c35a55217d5
-96fea82048181950779a3fc5f67bdad8df84e5433fa67bccd05ec886d857b789
-18ffbf083fa0b9f98cf5cfc9ae29d607d2ed11fa02131fd7c258431b20f7b113
-c316b7163644fdef029d33366200e9c4b5727940490a81aa139dddf9493f6b32
-0ee84950a6a549460032d0ba7fb3b2ded2e4028bd3ef456005bfc1456c681f25
-82dad6da15127a1ef14550d9557b86c2bc37440d538ee5146f320c9db07aed68
-70f6fa748a5b87fde0e3ef4cf1567e743eea26076ba668b46f3f7ad99f4df367
-fd40d87cca35267a09a3a33f8212655b747323e9d5f184cde766906f6f85ef2b
-3ad0dc0edcd150e589dae9c0e19d464ad618c32e14a5dbcaa6ecbcd990cc49ad
-c6de19129debd2de99b506adf4dbdea4ff1364e300447c9c0deda2cdf1d3648b
-1a83bd4be46e1797fb5b6216077a54f12c7ace9c28320026a19492e58193d082
-c0b5473a5a603ce22ea377511b725ad9c23b1a1b906b465fa02d0fb620e23074
-66c9d077730916850cd2abcc2412a364f4a0efde3fb741dea91fbba138e74dcb
-809627282be317d8f1dbb22220c9696bf39a27fc38aff90eaf458151a00a8a88
-9d4f5d933b1eee63054c65798ad32079ce573d53c620b6a0f81fd931b5a24707
-ebb30cf01b0c63b55ee8c08b805a9a45aea8aacf49982ce6d3e8726c6a122437
-1b9b116a56de605482449dabbb83d353ebdf355fcb8cde5658c699b8a55718a8
-6e051b42221dda48257e9f56d09f31a77630930abb0fce0d49ec9cb27c6ce480
-4c3b36d45ec195e7f78dc930370ed66cd4b6763085ec4c626693e69b39e993b1
-70b2289f29dcf94d5d2763a8211a92c40442371aa2f4297c9958c833421ee693
-a74b256e425979afe86b286bbda0983e14194250d9fecd03a8ba1fe615e93ae1
-d60d43f6858ea9cd47ddf88a1bfb5e90b60a28cdb269d9e1e43b0cf470a95b48
-aa5299e7159e7ccb18200914b93c3b0df79f181789fdfd6693613d0d42778883
-88847927f59d40f0cb5334f62eafe4f380076cfb7720174eceab1eb5050ea12c
-e4293db115c4f9bd4d21910a69d566a706f5c0e1bcb344203503855e6643b125
-17b6db03c41f13a347ad39e47a46d626f8a31a163bda6d23264657b412bdec99
-c87a103d26
-0000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000
-0000000000000000000000000000000000000000000000000000000000000000
-cleartomark
-%%EndResource
-/F637_0 /WWWUTU+NimbusRomNo9L-ReguItal 1 1
-[ /.notdef/dotaccent/fi/fl/fraction/hungarumlaut/Lslash/lslash
-  /ogonek/ring/.notdef/breve/minus/.notdef/Zcaron/zcaron
-  /caron/dotlessi/dotlessj/ff/ffi/ffl/notequal/infinity
-  /lessequal/greaterequal/partialdiff/summation/product/pi/grave/quotesingle
-  /space/exclam/quotedbl/numbersign/dollar/percent/ampersand/quoteright
-  /parenleft/parenright/asterisk/plus/comma/hyphen/period/slash
-  /zero/one/two/three/four/five/six/seven
-  /eight/nine/colon/semicolon/less/equal/greater/question
-  /at/A/B/C/D/E/F/G
-  /H/I/J/K/L/M/N/O
-  /P/Q/R/S/T/U/V/W
-  /X/Y/Z/bracketleft/backslash/bracketright/asciicircum/underscore
-  /quoteleft/a/b/c/d/e/f/g
-  /h/i/j/k/l/m/n/o
-  /p/q/r/s/t/u/v/w
-  /x/y/z/braceleft/bar/braceright/asciitilde/.notdef
-  /Euro/integral/quotesinglbase/florin/quotedblbase/ellipsis/dagger/daggerdbl
-  /circumflex/perthousand/Scaron/guilsinglleft/OE/Omega/radical/approxequal
-  /.notdef/.notdef/.notdef/quotedblleft/quotedblright/bullet/endash/emdash
-  /tilde/trademark/scaron/guilsinglright/oe/Delta/lozenge/Ydieresis
-  /.notdef/exclamdown/cent/sterling/currency/yen/brokenbar/section
-  /dieresis/copyright/ordfeminine/guillemotleft/logicalnot/hyphen/registered/macron
-  /degree/plusminus/twosuperior/threesuperior/acute/mu/paragraph/periodcentered
-  /cedilla/onesuperior/ordmasculine/guillemotright/onequarter/onehalf/threequarters/questiondown
-  /Agrave/Aacute/Acircumflex/Atilde/Adieresis/Aring/AE/Ccedilla
-  /Egrave/Eacute/Ecircumflex/Edieresis/Igrave/Iacute/Icircumflex/Idieresis
-  /Eth/Ntilde/Ograve/Oacute/Ocircumflex/Otilde/Odieresis/multiply
-  /Oslash/Ugrave/Uacute/Ucircumflex/Udieresis/Yacute/Thorn/germandbls
-  /agrave/aacute/acircumflex/atilde/adieresis/aring/ae/ccedilla
-  /egrave/eacute/ecircumflex/edieresis/igrave/iacute/icircumflex/idieresis
-  /eth/ntilde/ograve/oacute/ocircumflex/otilde/odieresis/divide
-  /oslash/ugrave/uacute/ucircumflex/udieresis/yacute/thorn/ydieresis]
-pdfMakeFont
-612 792 false pdfSetup
-%%EndSetup
-%%Page: 1 1
-%%BeginPageSetup
-%%PageOrientation: Portrait
-pdfStartPage
-0 0 612 792 re W
-%%EndPageSetup
-[] 0 d
-1 i
-0 j
-0 J
-10 M
-1 w
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-false op
-false OP
-0 0 612 792 re
-W
-q
-[1 0 0 1 72 756] cm
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 463.019 0] cm
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-[1 0 0 1 2.4906 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -468 -36] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -720] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-117.436 701.916 Td
-/F122_0 24.7902 Tf
-(bzip2) 63.3638 Tj
--278 TJm
-(and) 44.077 Tj
--278 TJm
-(libbzip2,) 99.1856 Tj
--278 TJm
-(ver) 37.2101 Tj
-15 TJm
-(sion) 50.9687 Tj
--278 TJm
-(1.0.5) 55.1334 Tj
-[1 0 0 1 72 696.784] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -15.4939] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -681.29] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-90.4929 661.631 Td
-/F122_0 20.6585 Tf
-(A) 14.9154 Tj
--278 TJm
-(pr) 20.6585 Tj
-20 TJm
-(ogram) 63.1324 Tj
--278 TJm
-(and) 36.7308 Tj
--278 TJm
-(librar) 51.6669 Tj
--10 TJm
-(y) 11.4861 Tj
--278 TJm
-(f) 6.87928 Tj
-20 TJm
-(or) 20.6585 Tj
--278 TJm
-(data) 42.4739 Tj
--278 TJm
-(compression) 128.579 Tj
-[1 0 0 1 72 657.035] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -144] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -513.035] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-207.676 503.285 Td
-/F122_0 11.9552 Tf
-(J) 6.64709 Tj
-20 TJm
-(ulian) 27.9034 Tj
--278 TJm
-(Se) 14.6212 Tj
-15 TJm
-(war) 20.5988 Tj
-20 TJm
-(d,) 10.6282 Tj
--278 TJm
-(http://www) 61.103 Tj
-40 TJm
-(.bzip.or) 42.5127 Tj
-15 TJm
-(g) 7.30463 Tj
-[1 0 0 1 72 500.625] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -435.826] cm
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 463.019 0] cm
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-[1 0 0 1 2.4906 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-Q
-showpage
-%%PageTrailer
-pdfEndPage
-%%Page: 2 2
-%%BeginPageSetup
-%%PageOrientation: Portrait
-pdfStartPage
-0 0 612 792 re W
-%%EndPageSetup
-[] 0 d
-1 i
-0 j
-0 J
-10 M
-1 w
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-false op
-false OP
-0 0 612 792 re
-W
-q
-[1 0 0 1 72 741.554] cm
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-[1 0 0 1 1.8929 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 14.4459] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 187.197 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 140.398 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -140.398 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 280.796 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -472.974 -13.9477] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -0.4981] cm
-q
-[] 0 d
-0 J
-0.4981 w
-0 0.2491 m
-475.465 0.2491 l
-S
-Q
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 479.251 0] cm
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-[1 0 0 1 -13.1436 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -468 -21.5542] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -720] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 709.534 Td
-/F122_0 14.3462 Tf
-(bzip2) 36.6689 Tj
--489 TJm
-(and) 25.5075 Tj
--488 TJm
-(libbzip2,) 57.3991 Tj
--542 TJm
-(ver) 21.5336 Tj
-15 TJm
-(sion) 29.4958 Tj
--488 TJm
-(1.0.5:) 36.6832 Tj
--766 TJm
-(A) 10.358 Tj
--488 TJm
-(pr) 14.3462 Tj
-20 TJm
-(ogram) 43.842 Tj
--489 TJm
-(and) 25.5075 Tj
--489 TJm
-(librar) 35.8798 Tj
--10 TJm
-(y) 7.97649 Tj
--488 TJm
-(f) 4.77728 Tj
-20 TJm
-(or) 14.3462 Tj
--489 TJm
-(data) 29.4958 Tj
-72 692.319 Td
-(compression) 89.2907 Tj
-[1 0 0 1 72 689.349] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -689.349] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 680.364 Td
-/F130_0 9.9626 Tf
-(by) 9.9626 Tj
--250 TJm
-(Julian) 23.8007 Tj
--250 TJm
-(Se) 9.9626 Tj
-25 TJm
-(w) 7.193 Tj
-10 TJm
-(ard) 12.7222 Tj
-[1 0 0 1 72 678.207] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -678.207] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 668.409 Td
-/F130_0 9.9626 Tf
-(Cop) 16.6077 Tj
-10 TJm
-(yright) 23.8007 Tj
-[1 0 0 1 114.799 668.409] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -114.799 -668.409] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-114.799 668.409 Td
-/F130_0 9.9626 Tf
-(\251) 7.57158 Tj
-[1 0 0 1 122.371 668.409] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -122.371 -668.409] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-124.861 668.409 Td
-/F130_0 9.9626 Tf
-(1996-2007) 43.1679 Tj
--250 TJm
-(Julian) 23.8007 Tj
--250 TJm
-(Se) 9.9626 Tj
-25 TJm
-(w) 7.193 Tj
-10 TJm
-(ard) 12.7222 Tj
-[1 0 0 1 72 666.252] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -7.9701] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -658.282] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 650.875 Td
-/F130_0 7.9701 Tf
-(This) 14.1708 Tj
--250 TJm
-(program,) 28.9952 Tj
-[1 0 0 1 119.151 650.875] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -119.151 -650.875] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-119.151 650.875 Td
-/F134_0 7.9701 Tf
-(bzip2) 23.9103 Tj
-[1 0 0 1 143.061 650.875] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -143.061 -650.875] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-143.061 650.875 Td
-/F130_0 7.9701 Tf
-(,) 1.99253 Tj
--250 TJm
-(the) 9.73946 Tj
--250 TJm
-(associated) 32.7571 Tj
--250 TJm
-(library) 21.2483 Tj
-[1 0 0 1 216.768 650.875] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -216.768 -650.875] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-216.768 650.875 Td
-/F134_0 7.9701 Tf
-(libbzip2) 38.2565 Tj
-[1 0 0 1 255.024 650.875] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -255.024 -650.875] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-255.024 650.875 Td
-/F130_0 7.9701 Tf
-(,) 1.99253 Tj
--250 TJm
-(and) 11.5088 Tj
--250 TJm
-(all) 7.9701 Tj
--250 TJm
-(documentation,) 49.3668 Tj
--250 TJm
-(are) 9.73149 Tj
--250 TJm
-(cop) 11.5088 Tj
-10 TJm
-(yright) 19.0406 Tj
--250 TJm
-(\251) 6.05728 Tj
--250 TJm
-(1996-2007) 34.5344 Tj
--250 TJm
-(Julian) 19.0406 Tj
--250 TJm
-(Se) 7.9701 Tj
-25 TJm
-(w) 5.75441 Tj
-10 TJm
-(ard.) 12.1703 Tj
--310 TJm
-(All) 10.1858 Tj
--250 TJm
-(rights) 18.1559 Tj
--250 TJm
-(reserv) 19.471 Tj
-15 TJm
-(ed.) 9.5163 Tj
-[1 0 0 1 72 649.149] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -7.9701] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -641.179] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 633.34 Td
-/F130_0 7.9701 Tf
-(Redistrib) 29.2264 Tj
-20 TJm
-(ution) 16.3865 Tj
--250 TJm
-(and) 11.5088 Tj
--250 TJm
-(use) 10.6241 Tj
--250 TJm
-(in) 6.20074 Tj
--250 TJm
-(source) 20.802 Tj
--250 TJm
-(and) 11.5088 Tj
--250 TJm
-(binary) 20.3636 Tj
--250 TJm
-(forms,) 20.5868 Tj
--250 TJm
-(with) 14.1708 Tj
--250 TJm
-(or) 6.63909 Tj
--250 TJm
-(without) 24.3566 Tj
--250 TJm
-(modi\002cation,) 42.2894 Tj
--250 TJm
-(are) 9.73149 Tj
--250 TJm
-(permitted) 30.5494 Tj
--250 TJm
-(pro) 10.6241 Tj
-15 TJm
-(vided) 17.7096 Tj
--250 TJm
-(that) 11.9551 Tj
--250 TJm
-(the) 9.73946 Tj
--250 TJm
-(follo) 15.0555 Tj
-25 TJm
-(wing) 15.9402 Tj
--250 TJm
-(conditions) 33.2114 Tj
--250 TJm
-(are) 9.73149 Tj
--250 TJm
-(met:) 14.1708 Tj
-[1 0 0 1 72 631.615] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -23.7789] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 5.5791 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -77.5791 -607.836] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-77.5791 607.836 Td
-/F130_0 7.9701 Tf
-(\225) 2.78954 Tj
-[1 0 0 1 80.3686 607.836] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 1.9926 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 1.594 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -83.9552 -607.836] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-83.9552 607.836 Td
-/F130_0 7.9701 Tf
-(Redistrib) 29.2264 Tj
-20 TJm
-(utions) 19.4869 Tj
--250 TJm
-(of) 6.63909 Tj
--250 TJm
-(source) 20.802 Tj
--250 TJm
-(code) 15.0475 Tj
--250 TJm
-(must) 15.5018 Tj
--250 TJm
-(retain) 18.1479 Tj
--250 TJm
-(the) 9.73946 Tj
--250 TJm
-(abo) 11.5088 Tj
-15 TJm
-(v) 3.98505 Tj
-15 TJm
-(e) 3.53872 Tj
--250 TJm
-(cop) 11.5088 Tj
-10 TJm
-(yright) 19.0406 Tj
--250 TJm
-(notice,) 21.4714 Tj
--250 TJm
-(this) 11.5168 Tj
--250 TJm
-(list) 9.74743 Tj
--250 TJm
-(of) 6.63909 Tj
--250 TJm
-(conditions) 33.2114 Tj
--250 TJm
-(and) 11.5088 Tj
--250 TJm
-(the) 9.73946 Tj
--250 TJm
-(follo) 15.0555 Tj
-25 TJm
-(wing) 15.9402 Tj
--250 TJm
-(disclaimer) 33.2034 Tj
-55 TJm
-(.) 1.99253 Tj
-[1 0 0 1 470.908 607.836] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -398.908 -17.5343] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 5.5791 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -77.5791 -590.302] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-77.5791 590.302 Td
-/F130_0 7.9701 Tf
-(\225) 2.78954 Tj
-[1 0 0 1 80.3686 590.302] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 1.9926 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 1.594 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -83.9552 -590.302] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-83.9552 590.302 Td
-/F130_0 7.9701 Tf
-(The) 12.3935 Tj
--270 TJm
-(origin) 19.0406 Tj
--270 TJm
-(of) 6.63909 Tj
--270 TJm
-(this) 11.5168 Tj
--270 TJm
-(softw) 17.7096 Tj
-10 TJm
-(are) 9.73149 Tj
--270 TJm
-(must) 15.5018 Tj
--270 TJm
-(not) 10.1858 Tj
--270 TJm
-(be) 7.52377 Tj
--270 TJm
-(misrepresented;) 50.4667 Tj
--279 TJm
-(you) 11.9551 Tj
--270 TJm
-(must) 15.5018 Tj
--270 TJm
-(not) 10.1858 Tj
--270 TJm
-(claim) 17.7096 Tj
--270 TJm
-(that) 11.9551 Tj
--270 TJm
-(you) 11.9551 Tj
--270 TJm
-(wrote) 18.1479 Tj
--270 TJm
-(the) 9.73946 Tj
--270 TJm
-(original) 24.795 Tj
--270 TJm
-(softw) 17.7096 Tj
-10 TJm
-(are.) 11.724 Tj
--740 TJm
-(If) 5.30809 Tj
--270 TJm
-(you) 11.9551 Tj
--270 TJm
-(use) 10.6241 Tj
--270 TJm
-(this) 11.5168 Tj
--270 TJm
-(softw) 17.7096 Tj
-10 TJm
-(are) 9.73149 Tj
--270 TJm
-(in) 6.20074 Tj
--269 TJm
-(a) 3.53872 Tj
-83.9552 580.737 Td
-(product,) 26.3412 Tj
--250 TJm
-(an) 7.52377 Tj
--250 TJm
-(ackno) 19.0326 Tj
-25 TJm
-(wledgment) 35.4191 Tj
--250 TJm
-(in) 6.20074 Tj
--250 TJm
-(the) 9.73946 Tj
--250 TJm
-(product) 24.3487 Tj
--250 TJm
-(documentation) 47.3743 Tj
--250 TJm
-(w) 5.75441 Tj
-10 TJm
-(ould) 14.1708 Tj
--250 TJm
-(be) 7.52377 Tj
--250 TJm
-(appreciated) 36.7342 Tj
--250 TJm
-(b) 3.98505 Tj
-20 TJm
-(ut) 6.20074 Tj
--250 TJm
-(is) 5.31606 Tj
--250 TJm
-(not) 10.1858 Tj
--250 TJm
-(required.) 28.5489 Tj
-[1 0 0 1 403.817 580.737] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -331.817 -17.5342] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 5.5791 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -77.5791 -563.203] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-77.5791 563.203 Td
-/F130_0 7.9701 Tf
-(\225) 2.78954 Tj
-[1 0 0 1 80.3686 563.203] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 1.9926 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 1.594 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -83.9552 -563.203] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-83.9552 563.203 Td
-/F130_0 7.9701 Tf
-(Altered) 23.9023 Tj
--250 TJm
-(source) 20.802 Tj
--250 TJm
-(v) 3.98505 Tj
-15 TJm
-(ersions) 22.5793 Tj
--250 TJm
-(must) 15.5018 Tj
--250 TJm
-(be) 7.52377 Tj
--250 TJm
-(plainly) 22.1409 Tj
--250 TJm
-(mark) 16.3786 Tj
-10 TJm
-(ed) 7.52377 Tj
--250 TJm
-(as) 6.63909 Tj
--250 TJm
-(such,) 16.6017 Tj
--250 TJm
-(and) 11.5088 Tj
--250 TJm
-(must) 15.5018 Tj
--250 TJm
-(not) 10.1858 Tj
--250 TJm
-(be) 7.52377 Tj
--250 TJm
-(misrepresented) 48.251 Tj
--250 TJm
-(as) 6.63909 Tj
--250 TJm
-(being) 17.7096 Tj
--250 TJm
-(the) 9.73946 Tj
--250 TJm
-(original) 24.795 Tj
--250 TJm
-(softw) 17.7096 Tj
-10 TJm
-(are.) 11.724 Tj
-[1 0 0 1 464.405 563.203] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -392.405 -17.5343] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 5.5791 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -77.5791 -545.669] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-77.5791 545.669 Td
-/F130_0 7.9701 Tf
-(\225) 2.78954 Tj
-[1 0 0 1 80.3686 545.669] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 1.9926 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 1.594 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -83.9552 -545.669] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-83.9552 545.669 Td
-/F130_0 7.9701 Tf
-(The) 12.3935 Tj
--250 TJm
-(name) 17.2632 Tj
--250 TJm
-(of) 6.63909 Tj
--250 TJm
-(the) 9.73946 Tj
--250 TJm
-(author) 20.3636 Tj
--250 TJm
-(may) 13.7245 Tj
--250 TJm
-(not) 10.1858 Tj
--250 TJm
-(be) 7.52377 Tj
--250 TJm
-(used) 14.6092 Tj
--250 TJm
-(to) 6.20074 Tj
--250 TJm
-(endorse) 24.787 Tj
--250 TJm
-(or) 6.63909 Tj
--250 TJm
-(promote) 26.5643 Tj
--250 TJm
-(products) 27.449 Tj
--250 TJm
-(deri) 12.3935 Tj
-25 TJm
-(v) 3.98505 Tj
-15 TJm
-(ed) 7.52377 Tj
--250 TJm
-(from) 15.4939 Tj
--250 TJm
-(this) 11.5168 Tj
--250 TJm
-(softw) 17.7096 Tj
-10 TJm
-(are) 9.73149 Tj
--250 TJm
-(without) 24.3566 Tj
--250 TJm
-(speci\002c) 24.3487 Tj
--250 TJm
-(prior) 15.4939 Tj
--250 TJm
-(written) 22.5793 Tj
--250 TJm
-(permission.) 36.9733 Tj
-[1 0 0 1 533.577 545.669] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -461.577 -9.6956] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -535.973] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 528.135 Td
-/F130_0 7.9701 Tf
-(THIS) 17.7096 Tj
--401 TJm
-(SOFTW) 27.0107 Tj
-120 TJm
-(ARE) 15.9402 Tj
--401 TJm
-(IS) 7.08542 Tj
--400 TJm
-(PR) 9.74743 Tj
-40 TJm
-(O) 5.75441 Tj
-50 TJm
-(VIDED) 24.787 Tj
--401 TJm
-(BY) 11.0705 Tj
--401 TJm
-(THE) 15.4939 Tj
--401 TJm
-(A) 5.75441 Tj
-55 TJm
-(UTHOR) 27.449 Tj
--401 TJm
-("AS) 13.4376 Tj
--401 TJm
-(IS") 10.3372 Tj
--401 TJm
-(AND) 17.2632 Tj
--400 TJm
-(ANY) 17.2632 Tj
--401 TJm
-(EXPRESS) 34.1041 Tj
--401 TJm
-(OR) 11.0705 Tj
--401 TJm
-(IMPLIED) 32.3188 Tj
--401 TJm
-(W) 7.52377 Tj
-120 TJm
-(ARRANTIES,) 46.7128 Tj
--401 TJm
-(INCLUDING,) 46.2585 Tj
--400 TJm
-(B) 5.31606 Tj
-10 TJm
-(UT) 10.6241 Tj
-72 518.571 Td
-(NO) 11.5088 Tj
-40 TJm
-(T) 4.86973 Tj
--304 TJm
-(LIMITED) 32.7571 Tj
--304 TJm
-(T) 4.86973 Tj
-18 TJm
-(O,) 7.74694 Tj
--305 TJm
-(THE) 15.4939 Tj
--304 TJm
-(IMPLIED) 32.3188 Tj
--304 TJm
-(W) 7.52377 Tj
-120 TJm
-(ARRANTIES) 44.7202 Tj
--304 TJm
-(OF) 10.1858 Tj
--304 TJm
-(MERCHANT) 44.7202 Tj
-93 TJm
-(ABILITY) 31.8724 Tj
--304 TJm
-(AND) 17.2632 Tj
--305 TJm
-(FITNESS) 31.442 Tj
--304 TJm
-(FOR) 15.5018 Tj
--304 TJm
-(A) 5.75441 Tj
--304 TJm
-(P) 4.43138 Tj
-92 TJm
-(AR) 11.0705 Tj
-60 TJm
-(TICULAR) 34.5344 Tj
--304 TJm
-(PURPOSE) 34.9887 Tj
--304 TJm
-(ARE) 15.9402 Tj
--305 TJm
-(DI) 8.40846 Tj
-1 TJm
-(S-) 7.08542 Tj
-72 509.006 Td
-(CLAIMED.) 38.2963 Tj
--576 TJm
-(IN) 8.40846 Tj
--287 TJm
-(NO) 11.5088 Tj
--288 TJm
-(EVENT) 26.118 Tj
--288 TJm
-(SHALL) 25.6797 Tj
--288 TJm
-(THE) 15.4939 Tj
--287 TJm
-(A) 5.75441 Tj
-55 TJm
-(UTHOR) 27.449 Tj
--288 TJm
-(BE) 10.1858 Tj
--288 TJm
-(LIABLE) 28.3337 Tj
--288 TJm
-(FOR) 15.5018 Tj
--288 TJm
-(ANY) 17.2632 Tj
--287 TJm
-(DIRECT) 28.78 Tj
-74 TJm
-(,) 1.99253 Tj
--288 TJm
-(INDIRECT) 37.1885 Tj
-74 TJm
-(,) 1.99253 Tj
--288 TJm
-(INCIDENT) 37.6268 Tj
-93 TJm
-(AL,) 12.6167 Tj
--288 TJm
-(SPECIAL,) 34.3193 Tj
--288 TJm
-(EXEMPLAR) 42.9509 Tj
-65 TJm
-(Y) 5.75441 Tj
-129 TJm
-(,) 1.99253 Tj
-72 499.442 Td
-(OR) 11.0705 Tj
--299 TJm
-(CONSEQ) 31.8804 Tj
-10 TJm
-(UENTIAL) 34.5265 Tj
--300 TJm
-(D) 5.75441 Tj
-40 TJm
-(AMA) 18.5942 Tj
-40 TJm
-(GES) 15.0555 Tj
--299 TJm
-(\(INCLUDING,) 48.9125 Tj
--299 TJm
-(B) 5.31606 Tj
-10 TJm
-(UT) 10.6241 Tj
--299 TJm
-(NO) 11.5088 Tj
-40 TJm
-(T) 4.86973 Tj
--300 TJm
-(LIMITED) 32.7571 Tj
--299 TJm
-(T) 4.86973 Tj
-18 TJm
-(O,) 7.74694 Tj
--299 TJm
-(PR) 9.74743 Tj
-40 TJm
-(OCUREMENT) 49.59 Tj
--299 TJm
-(OF) 10.1858 Tj
--300 TJm
-(SUBSTITUTE) 47.8206 Tj
--299 TJm
-(GOODS) 27.449 Tj
--299 TJm
-(OR) 11.0705 Tj
--300 TJm
-(SER) 14.6172 Tj
-80 TJm
-(VICES) 23.0256 Tj
-1 TJm
-(;) 2.21569 Tj
-72 489.878 Td
-(LOSS) 19.4869 Tj
--360 TJm
-(OF) 10.1858 Tj
--360 TJm
-(USE,) 17.048 Tj
--360 TJm
-(D) 5.75441 Tj
-40 TJm
-(A) 5.75441 Tj
-111 TJm
-(T) 4.86973 Tj
-93 TJm
-(A,) 7.74694 Tj
--360 TJm
-(OR) 11.0705 Tj
--359 TJm
-(PR) 9.74743 Tj
-40 TJm
-(OFITS;) 24.3566 Tj
--360 TJm
-(OR) 11.0705 Tj
--360 TJm
-(B) 5.31606 Tj
-10 TJm
-(USINESS) 32.3267 Tj
--360 TJm
-(INTERR) 28.78 Tj
-40 TJm
-(UPTION\)) 31.8724 Tj
--360 TJm
-(HO) 11.5088 Tj
-35 TJm
-(WEVER) 28.3337 Tj
--360 TJm
-(CA) 11.0705 Tj
-55 TJm
-(USED) 20.8099 Tj
--359 TJm
-(AND) 17.2632 Tj
--360 TJm
-(ON) 11.5088 Tj
--360 TJm
-(ANY) 17.2632 Tj
--360 TJm
-(THEOR) 26.5643 Tj
-65 TJm
-(Y) 5.75441 Tj
--360 TJm
-(OF) 10.1858 Tj
--360 TJm
-(LIAB) 18.5942 Tj
-1 TJm
-(ILITY) 20.802 Tj
-128 TJm
-(,) 1.99253 Tj
-72 480.314 Td
-(WHETHER) 38.9578 Tj
--247 TJm
-(IN) 8.40846 Tj
--247 TJm
-(CONTRA) 32.7651 Tj
-40 TJm
-(CT) 10.1858 Tj
-74 TJm
-(,) 1.99253 Tj
--247 TJm
-(STRICT) 27.457 Tj
--247 TJm
-(LIABILITY) 39.3962 Tj
-129 TJm
-(,) 1.99253 Tj
--246 TJm
-(OR) 11.0705 Tj
--247 TJm
-(T) 4.86973 Tj
-18 TJm
-(OR) 11.0705 Tj
-60 TJm
-(T) 4.86973 Tj
--247 TJm
-(\(INCLUDING) 46.92 Tj
--247 TJm
-(NEGLIGENCE) 50.4667 Tj
--247 TJm
-(OR) 11.0705 Tj
--247 TJm
-(O) 5.75441 Tj
-40 TJm
-(THER) 20.8099 Tj
-55 TJm
-(WISE\)) 22.133 Tj
--247 TJm
-(ARISING) 32.3188 Tj
--247 TJm
-(IN) 8.40846 Tj
--247 TJm
-(ANY) 17.2632 Tj
--247 TJm
-(W) 7.52377 Tj
-120 TJm
-(A) 5.75441 Tj
-105 TJm
-(Y) 5.75441 Tj
--247 TJm
-(OUT) 16.3786 Tj
-72 470.75 Td
-(OF) 10.1858 Tj
--250 TJm
-(THE) 15.4939 Tj
--250 TJm
-(USE) 15.0555 Tj
--250 TJm
-(OF) 10.1858 Tj
--250 TJm
-(THIS) 17.7096 Tj
--250 TJm
-(SOFTW) 27.0107 Tj
-120 TJm
-(ARE,) 17.9327 Tj
--250 TJm
-(EVEN) 21.2483 Tj
--250 TJm
-(IF) 7.08542 Tj
--250 TJm
-(AD) 11.5088 Tj
-40 TJm
-(VISED) 23.464 Tj
--250 TJm
-(OF) 10.1858 Tj
--250 TJm
-(THE) 15.4939 Tj
--250 TJm
-(POSSIBILITY) 47.8206 Tj
--250 TJm
-(OF) 10.1858 Tj
--250 TJm
-(SUCH) 21.2563 Tj
--250 TJm
-(D) 5.75441 Tj
-40 TJm
-(AMA) 18.5942 Tj
-40 TJm
-(GE.) 12.6167 Tj
-[1 0 0 1 72 469.598] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -7.9701] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -461.628] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 453.216 Td
-/F130_0 7.9701 Tf
-(P) 4.43138 Tj
-92 TJm
-(A) 5.75441 Tj
-111 TJm
-(TENTS:) 27.0107 Tj
--296 TJm
-(T) 4.86973 Tj
-80 TJm
-(o) 3.98505 Tj
--295 TJm
-(the) 9.73946 Tj
--296 TJm
-(best) 12.8398 Tj
--295 TJm
-(of) 6.63909 Tj
--296 TJm
-(my) 10.1858 Tj
--295 TJm
-(kno) 11.9551 Tj
-25 TJm
-(wledge,) 25.0102 Tj
-[1 0 0 1 208.544 453.216] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -208.544 -453.216] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-208.544 453.216 Td
-/F134_0 7.9701 Tf
-(bzip2) 23.9103 Tj
-[1 0 0 1 232.454 453.216] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -232.454 -453.216] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-234.81 453.216 Td
-/F130_0 7.9701 Tf
-(and) 11.5088 Tj
-[1 0 0 1 248.674 453.216] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -248.674 -453.216] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-248.674 453.216 Td
-/F134_0 7.9701 Tf
-(libbzip2) 38.2565 Tj
-[1 0 0 1 286.931 453.216] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -286.931 -453.216] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-289.286 453.216 Td
-/F130_0 7.9701 Tf
-(do) 7.9701 Tj
--296 TJm
-(not) 10.1858 Tj
--295 TJm
-(use) 10.6241 Tj
--296 TJm
-(an) 7.52377 Tj
-15 TJm
-(y) 3.98505 Tj
--295 TJm
-(patented) 27.0027 Tj
--296 TJm
-(algorithms.) 36.0886 Tj
--893 TJm
-(Ho) 9.73946 Tj
-25 TJm
-(we) 9.29314 Tj
-25 TJm
-(v) 3.98505 Tj
-15 TJm
-(er) 6.19277 Tj
-40 TJm
-(,) 1.99253 Tj
--307 TJm
-(I) 2.65404 Tj
--295 TJm
-(do) 7.9701 Tj
--296 TJm
-(not) 10.1858 Tj
--295 TJm
-(ha) 7.52377 Tj
-20 TJm
-(v) 3.98505 Tj
-15 TJm
-(e) 3.53872 Tj
--296 TJm
-(the) 9.73946 Tj
--295 TJm
-(resources) 30.0951 Tj
--296 TJm
-(to) 6.20074 Tj
-72 443.652 Td
-(carry) 16.3706 Tj
--250 TJm
-(out) 10.1858 Tj
--250 TJm
-(a) 3.53872 Tj
--250 TJm
-(patent) 19.4789 Tj
--250 TJm
-(search.) 22.3482 Tj
--620 TJm
-(Therefore) 31.4181 Tj
--250 TJm
-(I) 2.65404 Tj
--250 TJm
-(cannot) 21.2483 Tj
--250 TJm
-(gi) 6.20074 Tj
-25 TJm
-(v) 3.98505 Tj
-15 TJm
-(e) 3.53872 Tj
--250 TJm
-(an) 7.52377 Tj
-15 TJm
-(y) 3.98505 Tj
--250 TJm
-(guarantee) 30.9798 Tj
--250 TJm
-(of) 6.63909 Tj
--250 TJm
-(the) 9.73946 Tj
--250 TJm
-(abo) 11.5088 Tj
-15 TJm
-(v) 3.98505 Tj
-15 TJm
-(e) 3.53872 Tj
--250 TJm
-(statement.) 32.5419 Tj
-[1 0 0 1 72 441.926] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -391.074] cm
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-[1 0 0 1 1.8929 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 374.394 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 46.7993 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -46.7993 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 93.5986 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 6.2765 0] cm
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-[1 0 0 1 -13.1436 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-Q
-showpage
-%%PageTrailer
-pdfEndPage
-%%Page: 3 3
-%%BeginPageSetup
-%%PageOrientation: Portrait
-pdfStartPage
-0 0 612 792 re W
-%%EndPageSetup
-[] 0 d
-1 i
-0 j
-0 J
-10 M
-1 w
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-false op
-false OP
-0 0 612 792 re
-W
-q
-[1 0 0 1 72 741.554] cm
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-[1 0 0 1 1.8929 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 14.4459] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 187.197 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 140.398 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -140.398 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 280.796 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -472.974 -13.9477] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -0.4981] cm
-q
-[] 0 d
-0 J
-0.4981 w
-0 0.2491 m
-475.465 0.2491 l
-S
-Q
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 479.251 0] cm
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-[1 0 0 1 -13.1436 0] cm
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-[1 0 0 1 -468 -21.5542] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -720] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 707.441 Td
-/F122_0 17.2154 Tf
-(T) 10.5186 Tj
-80 TJm
-(ab) 20.0904 Tj
-10 TJm
-(le) 14.3576 Tj
--278 TJm
-(of) 16.2513 Tj
--278 TJm
-(Contents) 74.5943 Tj
-[1 0 0 1 72 698.619] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -11.7401] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -686.879] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 686.879 Td
-/F130_0 9.9626 Tf
-(1.) 7.47195 Tj
--310 TJm
-(Introduction) 49.2551 Tj
-[1 0 0 1 131.815 686.879] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4906 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -136.796 -686.879] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-145.733 686.879 Td
-/F147_0 9.9626 Tf
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
-[1 0 0 1 511.108 686.879] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -511.108 -686.879] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-511.108 686.879 Td
-/F130_0 9.9626 Tf
-(1) 4.9813 Tj
-[1 0 0 1 516.09 686.879] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -444.09 -0.0996] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -11.8556] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -674.923] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 674.923 Td
-/F130_0 9.9626 Tf
-(2.) 7.47195 Tj
--310 TJm
-(Ho) 12.1743 Tj
-25 TJm
-(w) 7.193 Tj
--250 TJm
-(to) 7.7509 Tj
--250 TJm
-(use) 13.2801 Tj
--250 TJm
-(bzip2) 22.1369 Tj
-[1 0 0 1 152.318 674.923] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4906 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -157.3 -674.923] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-167.054 674.923 Td
-/F147_0 9.9626 Tf
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
-[1 0 0 1 511.108 674.923] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -511.108 -674.923] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-511.108 674.923 Td
-/F130_0 9.9626 Tf
-(2) 4.9813 Tj
-[1 0 0 1 516.09 674.923] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -444.09 -2.1568] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.7984] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -662.968] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 662.968 Td
-/F130_0 9.9626 Tf
-(2.1.) 14.9439 Tj
--310 TJm
-(N) 7.193 Tj
-35 TJm
-(AME) 22.1369 Tj
-[1 0 0 1 119.014 662.968] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4906 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -123.995 -662.968] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-132.691 662.968 Td
-/F147_0 9.9626 Tf
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
-[1 0 0 1 511.108 662.968] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -511.108 -662.968] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-511.108 662.968 Td
-/F130_0 9.9626 Tf
-(2) 4.9813 Tj
-[1 0 0 1 516.09 662.968] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -444.09 -0.0995] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -11.8556] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -651.013] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 651.013 Td
-/F130_0 9.9626 Tf
-(2.2.) 14.9439 Tj
--310 TJm
-(SYNOPSIS) 47.0534 Tj
-[1 0 0 1 137.085 651.013] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4906 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -142.067 -651.013] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-150.582 651.013 Td
-/F147_0 9.9626 Tf
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
-[1 0 0 1 511.108 651.013] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -511.108 -651.013] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-511.108 651.013 Td
-/F130_0 9.9626 Tf
-(2) 4.9813 Tj
-[1 0 0 1 516.09 651.013] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -444.09 -0.0996] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -11.8556] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -639.058] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 639.058 Td
-/F130_0 9.9626 Tf
-(2.3.) 14.9439 Tj
--310 TJm
-(DESCRIPTION) 64.7569 Tj
-[1 0 0 1 154.789 639.058] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -159.77 -639.058] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-168.29 639.058 Td
-/F147_0 9.9626 Tf
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
-[1 0 0 1 511.108 639.058] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -511.108 -639.058] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-511.108 639.058 Td
-/F130_0 9.9626 Tf
-(3) 4.9813 Tj
-[1 0 0 1 516.09 639.058] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -444.09 -0.0995] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -11.8557] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -627.103] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 627.103 Td
-/F130_0 9.9626 Tf
-(2.4.) 14.9439 Tj
--310 TJm
-(OPTIONS) 42.0621 Tj
-[1 0 0 1 132.094 627.103] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4906 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -137.076 -627.103] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-145.873 627.103 Td
-/F147_0 9.9626 Tf
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
-[1 0 0 1 511.108 627.103] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -511.108 -627.103] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-511.108 627.103 Td
-/F130_0 9.9626 Tf
-(4) 4.9813 Tj
-[1 0 0 1 516.09 627.103] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -444.09 -0.0995] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -11.8556] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -615.147] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 615.147 Td
-/F130_0 9.9626 Tf
-(2.5.) 14.9439 Tj
--310 TJm
-(MEMOR) 37.6387 Tj
-65 TJm
-(Y) 7.193 Tj
--250 TJm
-(MAN) 23.2427 Tj
-35 TJm
-(A) 7.193 Tj
-40 TJm
-(GEMENT) 41.5042 Tj
-[1 0 0 1 207.9 615.147] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4906 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -212.881 -615.147] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-221.412 615.147 Td
-/F147_0 9.9626 Tf
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
-[1 0 0 1 511.108 615.147] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -511.108 -615.147] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-511.108 615.147 Td
-/F130_0 9.9626 Tf
-(5) 4.9813 Tj
-[1 0 0 1 516.09 615.147] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -444.09 -0.0996] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -11.8556] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -603.192] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 603.192 Td
-/F130_0 9.9626 Tf
-(2.6.) 14.9439 Tj
--310 TJm
-(RECO) 26.5703 Tj
-50 TJm
-(VERING) 37.6287 Tj
--250 TJm
-(D) 7.193 Tj
-40 TJm
-(A) 7.193 Tj
-111 TJm
-(T) 6.08715 Tj
-93 TJm
-(A) 7.193 Tj
--250 TJm
-(FR) 12.1843 Tj
-40 TJm
-(OM) 16.0497 Tj
--250 TJm
-(D) 7.193 Tj
-40 TJm
-(AMA) 23.2427 Tj
-40 TJm
-(GED) 20.4731 Tj
--250 TJm
-(FILES) 26.5703 Tj
-[1 0 0 1 293.449 603.192] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4906 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -298.43 -603.192] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-308.464 603.192 Td
-/F147_0 9.9626 Tf
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
-[1 0 0 1 511.108 603.192] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -511.108 -603.192] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-511.108 603.192 Td
-/F130_0 9.9626 Tf
-(6) 4.9813 Tj
-[1 0 0 1 516.09 603.192] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -444.09 -0.0995] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -11.8557] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -591.237] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 591.237 Td
-/F130_0 9.9626 Tf
-(2.7.) 14.9439 Tj
--310 TJm
-(PERFORMANCE) 73.6236 Tj
--250 TJm
-(NO) 14.386 Tj
-40 TJm
-(TES) 17.7135 Tj
-[1 0 0 1 197.847 591.237] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4906 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -202.829 -591.237] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-211.958 591.237 Td
-/F147_0 9.9626 Tf
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
-[1 0 0 1 511.108 591.237] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -511.108 -591.237] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-511.108 591.237 Td
-/F130_0 9.9626 Tf
-(6) 4.9813 Tj
-[1 0 0 1 516.09 591.237] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -444.09 -0.0995] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -11.8557] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -579.282] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 579.282 Td
-/F130_0 9.9626 Tf
-(2.8.) 14.9439 Tj
--310 TJm
-(CA) 13.8381 Tj
-135 TJm
-(VEA) 20.4731 Tj
-111 TJm
-(TS) 11.6264 Tj
-[1 0 0 1 133.519 579.282] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -138.5 -579.282] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-148.799 579.282 Td
-/F147_0 9.9626 Tf
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
-[1 0 0 1 511.108 579.282] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -511.108 -579.282] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-511.108 579.282 Td
-/F130_0 9.9626 Tf
-(7) 4.9813 Tj
-[1 0 0 1 516.09 579.282] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -444.09 -0.0995] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -11.8556] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -567.327] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 567.327 Td
-/F130_0 9.9626 Tf
-(2.9.) 14.9439 Tj
--310 TJm
-(A) 7.193 Tj
-55 TJm
-(UTHOR) 34.3112 Tj
-[1 0 0 1 130.989 567.327] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -135.97 -567.327] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-145.32 567.327 Td
-/F147_0 9.9626 Tf
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
-[1 0 0 1 511.108 567.327] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -511.108 -567.327] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-511.108 567.327 Td
-/F130_0 9.9626 Tf
-(7) 4.9813 Tj
-[1 0 0 1 516.09 567.327] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -444.09 -0.2192] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -11.736] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -555.372] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 555.372 Td
-/F130_0 9.9626 Tf
-(3.) 7.47195 Tj
--310 TJm
-(Programming) 54.7943 Tj
--250 TJm
-(with) 17.7135 Tj
-[1 0 0 1 160.049 555.372] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -160.049 -555.372] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-160.049 555.372 Td
-/F134_0 9.9626 Tf
-(libbzip2) 47.8205 Tj
-[1 0 0 1 207.87 555.372] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4906 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -215.342 -555.372] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-224.856 555.372 Td
-/F147_0 9.9626 Tf
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
-[1 0 0 1 511.108 555.372] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -511.108 -555.372] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-511.108 555.372 Td
-/F130_0 9.9626 Tf
-(8) 4.9813 Tj
-[1 0 0 1 516.09 555.372] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -444.09 -2.1568] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.7984] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -543.416] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 543.416 Td
-/F130_0 9.9626 Tf
-(3.1.) 14.9439 Tj
--310 TJm
-(T) 6.08715 Tj
-80 TJm
-(op-le) 20.4731 Tj
-25 TJm
-(v) 4.9813 Tj
-15 TJm
-(el) 7.193 Tj
--250 TJm
-(structure) 34.8591 Tj
-[1 0 0 1 164.921 543.416] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4906 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -169.902 -543.416] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-179.997 543.416 Td
-/F147_0 9.9626 Tf
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
-[1 0 0 1 511.108 543.416] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -511.108 -543.416] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-511.108 543.416 Td
-/F130_0 9.9626 Tf
-(8) 4.9813 Tj
-[1 0 0 1 516.09 543.416] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -444.09 -2.1568] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.7983] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -531.461] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 531.461 Td
-/F130_0 9.9626 Tf
-(3.1.1.) 22.4159 Tj
--310 TJm
-(Lo) 11.0684 Tj
-25 TJm
-(w-le) 17.7035 Tj
-25 TJm
-(v) 4.9813 Tj
-15 TJm
-(el) 7.193 Tj
--250 TJm
-(summary) 37.0808 Tj
-[1 0 0 1 177.374 531.461] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4906 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -182.355 -531.461] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-192.866 531.461 Td
-/F147_0 9.9626 Tf
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
-[1 0 0 1 511.108 531.461] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -511.108 -531.461] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-511.108 531.461 Td
-/F130_0 9.9626 Tf
-(9) 4.9813 Tj
-[1 0 0 1 516.09 531.461] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -444.09 -2.1568] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.7984] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -519.506] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 519.506 Td
-/F130_0 9.9626 Tf
-(3.1.2.) 22.4159 Tj
--310 TJm
-(High-le) 30.4357 Tj
-25 TJm
-(v) 4.9813 Tj
-15 TJm
-(el) 7.193 Tj
--250 TJm
-(summary) 37.0808 Tj
-[1 0 0 1 179.287 519.506] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4906 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -184.268 -519.506] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-193.822 519.506 Td
-/F147_0 9.9626 Tf
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
-[1 0 0 1 511.108 519.506] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -511.108 -519.506] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-511.108 519.506 Td
-/F130_0 9.9626 Tf
-(9) 4.9813 Tj
-[1 0 0 1 516.09 519.506] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -444.09 -2.1568] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.7984] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -507.551] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 507.551 Td
-/F130_0 9.9626 Tf
-(3.1.3.) 22.4159 Tj
--310 TJm
-(Utility) 26.0223 Tj
--250 TJm
-(functions) 37.0808 Tj
--250 TJm
-(summary) 37.0808 Tj
-[1 0 0 1 202.669 507.551] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4906 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -207.65 -507.551] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-216.582 507.551 Td
-/F147_0 9.9626 Tf
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
-[1 0 0 1 511.108 507.551] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -511.108 -507.551] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-511.108 507.551 Td
-/F130_0 9.9626 Tf
-(9) 4.9813 Tj
-[1 0 0 1 516.09 507.551] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -444.09 -2.1568] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.7983] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -495.596] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 495.596 Td
-/F130_0 9.9626 Tf
-(3.2.) 14.9439 Tj
--310 TJm
-(Error) 21.0211 Tj
--250 TJm
-(handling) 34.8691 Tj
-[1 0 0 1 148.413 495.596] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4906 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -153.394 -495.596] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-162.611 495.596 Td
-/F147_0 9.9626 Tf
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
-[1 0 0 1 506.127 495.596] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -506.127 -495.596] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-506.127 495.596 Td
-/F130_0 9.9626 Tf
-(10) 9.9626 Tj
-[1 0 0 1 516.09 495.596] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -444.09 -2.1568] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.7984] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -483.641] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 483.641 Td
-/F130_0 9.9626 Tf
-(3.3.) 14.9439 Tj
--310 TJm
-(Lo) 11.0684 Tj
-25 TJm
-(w-le) 17.7035 Tj
-25 TJm
-(v) 4.9813 Tj
-15 TJm
-(el) 7.193 Tj
--250 TJm
-(interf) 21.579 Tj
-10 TJm
-(ace) 13.2702 Tj
-[1 0 0 1 167.571 483.641] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -172.552 -483.641] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-181.045 483.641 Td
-/F147_0 9.9626 Tf
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
-[1 0 0 1 506.127 483.641] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -506.127 -483.641] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-506.127 483.641 Td
-/F130_0 9.9626 Tf
-(11) 9.9626 Tj
-[1 0 0 1 516.09 483.641] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -444.09 -0.0995] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -11.8557] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -471.685] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 471.685 Td
-/F130_0 9.9626 Tf
-(3.3.1.) 22.4159 Tj
-[1 0 0 1 97.5043 471.685] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -97.5043 -471.685] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-97.5043 471.685 Td
-/F134_0 9.9626 Tf
-(BZ2_bzCompressInit) 107.596 Tj
-[1 0 0 1 205.101 471.685] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4906 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -210.082 -471.685] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-219.736 471.685 Td
-/F147_0 9.9626 Tf
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
-[1 0 0 1 506.127 471.685] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -506.127 -471.685] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-506.127 471.685 Td
-/F130_0 9.9626 Tf
-(11) 9.9626 Tj
-[1 0 0 1 516.09 471.685] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -444.09 -1.5341] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -10.421] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -459.73] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 459.73 Td
-/F130_0 9.9626 Tf
-(3.3.2.) 22.4159 Tj
-[1 0 0 1 97.5043 459.73] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -97.5043 -459.73] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-97.5043 459.73 Td
-/F134_0 9.9626 Tf
-(BZ2_bzCompress) 83.6858 Tj
-[1 0 0 1 181.19 459.73] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4906 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -186.172 -459.73] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-194.497 459.73 Td
-/F147_0 9.9626 Tf
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
-[1 0 0 1 506.127 459.73] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -506.127 -459.73] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-506.127 459.73 Td
-/F130_0 9.9626 Tf
-(13) 9.9626 Tj
-[1 0 0 1 516.09 459.73] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -444.09 -1.5342] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -10.421] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -447.775] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 447.775 Td
-/F130_0 9.9626 Tf
-(3.3.3.) 22.4159 Tj
-[1 0 0 1 97.5043 447.775] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -97.5043 -447.775] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-97.5043 447.775 Td
-/F134_0 9.9626 Tf
-(BZ2_bzCompressEnd) 101.619 Tj
-[1 0 0 1 199.123 447.775] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4906 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -204.105 -447.775] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-214.533 447.775 Td
-/F147_0 9.9626 Tf
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
-[1 0 0 1 506.127 447.775] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -506.127 -447.775] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-506.127 447.775 Td
-/F130_0 9.9626 Tf
-(16) 9.9626 Tj
-[1 0 0 1 516.09 447.775] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -444.09 -1.5342] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -10.421] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -435.82] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 435.82 Td
-/F130_0 9.9626 Tf
-(3.3.4.) 22.4159 Tj
-[1 0 0 1 97.5043 435.82] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -97.5043 -435.82] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-97.5043 435.82 Td
-/F134_0 9.9626 Tf
-(BZ2_bzDecompressInit) 119.551 Tj
-[1 0 0 1 217.056 435.82] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4906 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -222.037 -435.82] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-232.355 435.82 Td
-/F147_0 9.9626 Tf
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
-[1 0 0 1 506.127 435.82] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -506.127 -435.82] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-506.127 435.82 Td
-/F130_0 9.9626 Tf
-(16) 9.9626 Tj
-[1 0 0 1 516.09 435.82] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -444.09 -1.5341] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -10.421] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -423.865] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 423.865 Td
-/F130_0 9.9626 Tf
-(3.3.5.) 22.4159 Tj
-[1 0 0 1 97.5043 423.865] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -97.5043 -423.865] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-97.5043 423.865 Td
-/F134_0 9.9626 Tf
-(BZ2_bzDecompress) 95.641 Tj
-[1 0 0 1 193.146 423.865] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4906 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -198.127 -423.865] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-207.116 423.865 Td
-/F147_0 9.9626 Tf
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
-[1 0 0 1 506.127 423.865] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -506.127 -423.865] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-506.127 423.865 Td
-/F130_0 9.9626 Tf
-(17) 9.9626 Tj
-[1 0 0 1 516.09 423.865] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -444.09 -1.5342] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -10.421] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -411.91] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 411.91 Td
-/F130_0 9.9626 Tf
-(3.3.6.) 22.4159 Tj
-[1 0 0 1 97.5043 411.91] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -97.5043 -411.91] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-97.5043 411.91 Td
-/F134_0 9.9626 Tf
-(BZ2_bzDecompressEnd) 113.574 Tj
-[1 0 0 1 211.078 411.91] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -216.06 -411.91] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-224.938 411.91 Td
-/F147_0 9.9626 Tf
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
-[1 0 0 1 506.127 411.91] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -506.127 -411.91] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-506.127 411.91 Td
-/F130_0 9.9626 Tf
-(18) 9.9626 Tj
-[1 0 0 1 516.09 411.91] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -444.09 -1.5342] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -10.421] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -399.954] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 399.954 Td
-/F130_0 9.9626 Tf
-(3.4.) 14.9439 Tj
--310 TJm
-(High-le) 30.4357 Tj
-25 TJm
-(v) 4.9813 Tj
-15 TJm
-(el) 7.193 Tj
--250 TJm
-(interf) 21.579 Tj
-10 TJm
-(ace) 13.2702 Tj
-[1 0 0 1 169.483 399.954] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4906 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -174.465 -399.954] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-184.216 399.954 Td
-/F147_0 9.9626 Tf
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
-[1 0 0 1 506.127 399.954] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -506.127 -399.954] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-506.127 399.954 Td
-/F130_0 9.9626 Tf
-(18) 9.9626 Tj
-[1 0 0 1 516.09 399.954] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -444.09 -2.1568] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.7983] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -387.999] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 387.999 Td
-/F130_0 9.9626 Tf
-(3.4.1.) 22.4159 Tj
-[1 0 0 1 97.5043 387.999] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -97.5043 -387.999] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-97.5043 387.999 Td
-/F134_0 9.9626 Tf
-(BZ2_bzReadOpen) 83.6858 Tj
-[1 0 0 1 181.19 387.999] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4906 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -186.172 -387.999] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-194.497 387.999 Td
-/F147_0 9.9626 Tf
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
-[1 0 0 1 506.127 387.999] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -506.127 -387.999] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-506.127 387.999 Td
-/F130_0 9.9626 Tf
-(19) 9.9626 Tj
-[1 0 0 1 516.09 387.999] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -444.09 -1.5342] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -10.421] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -376.044] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 376.044 Td
-/F130_0 9.9626 Tf
-(3.4.2.) 22.4159 Tj
-[1 0 0 1 97.5043 376.044] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -97.5043 -376.044] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-97.5043 376.044 Td
-/F134_0 9.9626 Tf
-(BZ2_bzRead) 59.7756 Tj
-[1 0 0 1 157.28 376.044] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4906 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -162.261 -376.044] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-171.472 376.044 Td
-/F147_0 9.9626 Tf
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
-[1 0 0 1 506.127 376.044] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -506.127 -376.044] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-506.127 376.044 Td
-/F130_0 9.9626 Tf
-(20) 9.9626 Tj
-[1 0 0 1 516.09 376.044] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -444.09 -1.31] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -10.6452] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -364.089] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 364.089 Td
-/F130_0 9.9626 Tf
-(3.4.3.) 22.4159 Tj
-[1 0 0 1 97.5043 364.089] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -97.5043 -364.089] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-97.5043 364.089 Td
-/F134_0 9.9626 Tf
-(BZ2_bzReadGetUnused) 113.574 Tj
-[1 0 0 1 211.078 364.089] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -216.06 -364.089] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-224.938 364.089 Td
-/F147_0 9.9626 Tf
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
-[1 0 0 1 506.127 364.089] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -506.127 -364.089] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-506.127 364.089 Td
-/F130_0 9.9626 Tf
-(21) 9.9626 Tj
-[1 0 0 1 516.09 364.089] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -444.09 -1.31] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -10.6452] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -352.134] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 352.134 Td
-/F130_0 9.9626 Tf
-(3.4.4.) 22.4159 Tj
-[1 0 0 1 97.5043 352.134] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -97.5043 -352.134] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-97.5043 352.134 Td
-/F134_0 9.9626 Tf
-(BZ2_bzReadClose) 89.6634 Tj
-[1 0 0 1 187.168 352.134] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4906 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -192.149 -352.134] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-201.914 352.134 Td
-/F147_0 9.9626 Tf
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
-[1 0 0 1 506.127 352.134] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -506.127 -352.134] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-506.127 352.134 Td
-/F130_0 9.9626 Tf
-(22) 9.9626 Tj
-[1 0 0 1 516.09 352.134] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -444.09 -1.31] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -10.6451] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -340.179] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 340.179 Td
-/F130_0 9.9626 Tf
-(3.4.5.) 22.4159 Tj
-[1 0 0 1 97.5043 340.179] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -97.5043 -340.179] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-97.5043 340.179 Td
-/F134_0 9.9626 Tf
-(BZ2_bzWriteOpen) 89.6634 Tj
-[1 0 0 1 187.168 340.179] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4906 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -192.149 -340.179] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-201.914 340.179 Td
-/F147_0 9.9626 Tf
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
-[1 0 0 1 506.127 340.179] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -506.127 -340.179] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-506.127 340.179 Td
-/F130_0 9.9626 Tf
-(22) 9.9626 Tj
-[1 0 0 1 516.09 340.179] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -444.09 -1.5342] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -10.421] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -328.223] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 328.223 Td
-/F130_0 9.9626 Tf
-(3.4.6.) 22.4159 Tj
-[1 0 0 1 97.5043 328.223] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -97.5043 -328.223] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-97.5043 328.223 Td
-/F134_0 9.9626 Tf
-(BZ2_bzWrite) 65.7532 Tj
-[1 0 0 1 163.258 328.223] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4906 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -168.239 -328.223] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-176.675 328.223 Td
-/F147_0 9.9626 Tf
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
-[1 0 0 1 506.127 328.223] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -506.127 -328.223] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-506.127 328.223 Td
-/F130_0 9.9626 Tf
-(23) 9.9626 Tj
-[1 0 0 1 516.09 328.223] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -444.09 -1.31] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -10.6452] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -316.268] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 316.268 Td
-/F130_0 9.9626 Tf
-(3.4.7.) 22.4159 Tj
-[1 0 0 1 97.5043 316.268] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -97.5043 -316.268] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-97.5043 316.268 Td
-/F134_0 9.9626 Tf
-(BZ2_bzWriteClose) 95.641 Tj
-[1 0 0 1 193.146 316.268] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4906 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -198.127 -316.268] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-207.116 316.268 Td
-/F147_0 9.9626 Tf
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
-[1 0 0 1 506.127 316.268] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -506.127 -316.268] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-506.127 316.268 Td
-/F130_0 9.9626 Tf
-(23) 9.9626 Tj
-[1 0 0 1 516.09 316.268] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -444.09 -1.31] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -10.6451] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -304.313] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 304.313 Td
-/F130_0 9.9626 Tf
-(3.4.8.) 22.4159 Tj
--310 TJm
-(Handling) 37.0808 Tj
--250 TJm
-(embedded) 40.9463 Tj
--250 TJm
-(compressed) 47.0334 Tj
--250 TJm
-(data) 16.5977 Tj
--250 TJm
-(streams) 30.4357 Tj
-[1 0 0 1 279.56 304.313] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4906 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -284.541 -304.313] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-294.601 304.313 Td
-/F147_0 9.9626 Tf
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
-[1 0 0 1 506.127 304.313] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -506.127 -304.313] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-506.127 304.313 Td
-/F130_0 9.9626 Tf
-(24) 9.9626 Tj
-[1 0 0 1 516.09 304.313] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -444.09 -2.1568] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.7984] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -292.358] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 292.358 Td
-/F130_0 9.9626 Tf
-(3.4.9.) 22.4159 Tj
--310 TJm
-(Standard) 35.417 Tj
--250 TJm
-(\002le-reading/writing) 77.4791 Tj
--250 TJm
-(code) 18.8094 Tj
-[1 0 0 1 234.19 292.358] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4906 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -239.172 -292.358] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-247.564 292.358 Td
-/F147_0 9.9626 Tf
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
-[1 0 0 1 506.127 292.358] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -506.127 -292.358] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-506.127 292.358 Td
-/F130_0 9.9626 Tf
-(25) 9.9626 Tj
-[1 0 0 1 516.09 292.358] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -444.09 -2.1568] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.7984] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -280.403] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 280.403 Td
-/F130_0 9.9626 Tf
-(3.5.) 14.9439 Tj
--310 TJm
-(Utility) 26.0223 Tj
--250 TJm
-(functions) 37.0808 Tj
-[1 0 0 1 155.625 280.403] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4906 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -160.607 -280.403] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-170.645 280.403 Td
-/F147_0 9.9626 Tf
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
-[1 0 0 1 506.127 280.403] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -506.127 -280.403] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-506.127 280.403 Td
-/F130_0 9.9626 Tf
-(26) 9.9626 Tj
-[1 0 0 1 516.09 280.403] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -444.09 -2.1568] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.7983] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -268.448] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 268.448 Td
-/F130_0 9.9626 Tf
-(3.5.1.) 22.4159 Tj
-[1 0 0 1 97.5043 268.448] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -97.5043 -268.448] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-97.5043 268.448 Td
-/F134_0 9.9626 Tf
-(BZ2_bzBuffToBuffCompress) 143.461 Tj
-[1 0 0 1 240.966 268.448] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4906 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -245.948 -268.448] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-255.38 268.448 Td
-/F147_0 9.9626 Tf
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
-[1 0 0 1 506.127 268.448] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -506.127 -268.448] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-506.127 268.448 Td
-/F130_0 9.9626 Tf
-(26) 9.9626 Tj
-[1 0 0 1 516.09 268.448] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -444.09 -1.5342] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -10.421] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -256.492] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 256.492 Td
-/F130_0 9.9626 Tf
-(3.5.2.) 22.4159 Tj
-[1 0 0 1 97.5043 256.492] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -97.5043 -256.492] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-97.5043 256.492 Td
-/F134_0 9.9626 Tf
-(BZ2_bzBuffToBuffDecompress) 155.417 Tj
-[1 0 0 1 252.922 256.492] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4906 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -257.903 -256.492] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-267.999 256.492 Td
-/F147_0 9.9626 Tf
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
-[1 0 0 1 506.127 256.492] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -506.127 -256.492] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-506.127 256.492 Td
-/F130_0 9.9626 Tf
-(27) 9.9626 Tj
-[1 0 0 1 516.09 256.492] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -444.09 -1.5342] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -10.421] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -244.537] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 244.537 Td
-/F130_0 9.9626 Tf
-(3.6.) 14.9439 Tj
-[1 0 0 1 90.0324 244.537] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -90.0324 -244.537] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-90.0324 244.537 Td
-/F134_0 9.9626 Tf
-(zlib) 23.9102 Tj
-[1 0 0 1 113.943 244.537] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -113.943 -244.537] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-116.433 244.537 Td
-/F130_0 9.9626 Tf
-(compatibility) 53.1405 Tj
--250 TJm
-(functions) 37.0808 Tj
-[1 0 0 1 209.144 244.537] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4906 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -214.126 -244.537] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-223.971 244.537 Td
-/F147_0 9.9626 Tf
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
-[1 0 0 1 506.127 244.537] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -506.127 -244.537] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-506.127 244.537 Td
-/F130_0 9.9626 Tf
-(28) 9.9626 Tj
-[1 0 0 1 516.09 244.537] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -444.09 -2.1568] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.7983] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -232.582] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 232.582 Td
-/F130_0 9.9626 Tf
-(3.7.) 14.9439 Tj
--310 TJm
-(Using) 23.8007 Tj
--250 TJm
-(the) 12.1743 Tj
--250 TJm
-(library) 26.5603 Tj
--250 TJm
-(in) 7.7509 Tj
--250 TJm
-(a) 4.42339 Tj
-[1 0 0 1 177.195 232.582] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -177.195 -232.582] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-177.195 232.582 Td
-/F134_0 9.9626 Tf
-(stdio) 29.8878 Tj
-[1 0 0 1 207.083 232.582] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -207.083 -232.582] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-207.083 232.582 Td
-/F130_0 9.9626 Tf
-(-free) 18.7994 Tj
--250 TJm
-(en) 9.40469 Tj
-40 TJm
-(vironment) 40.9562 Tj
-[1 0 0 1 278.335 232.582] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -283.316 -232.582] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-291.775 232.582 Td
-/F147_0 9.9626 Tf
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
-[1 0 0 1 506.127 232.582] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -506.127 -232.582] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-506.127 232.582 Td
-/F130_0 9.9626 Tf
-(28) 9.9626 Tj
-[1 0 0 1 516.09 232.582] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -444.09 -2.1568] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.7984] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -220.627] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 220.627 Td
-/F130_0 9.9626 Tf
-(3.7.1.) 22.4159 Tj
--310 TJm
-(Getting) 29.8878 Tj
--250 TJm
-(rid) 11.0684 Tj
--250 TJm
-(of) 8.29885 Tj
-[1 0 0 1 154.231 220.627] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -154.231 -220.627] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-154.231 220.627 Td
-/F134_0 9.9626 Tf
-(stdio) 29.8878 Tj
-[1 0 0 1 184.119 220.627] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4906 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -189.1 -220.627] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-198.175 220.627 Td
-/F147_0 9.9626 Tf
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
-[1 0 0 1 506.127 220.627] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -506.127 -220.627] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-506.127 220.627 Td
-/F130_0 9.9626 Tf
-(29) 9.9626 Tj
-[1 0 0 1 516.09 220.627] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -444.09 -2.1568] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.7984] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -208.672] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 208.672 Td
-/F130_0 9.9626 Tf
-(3.7.2.) 22.4159 Tj
--310 TJm
-(Critical) 29.8878 Tj
--250 TJm
-(error) 19.3573 Tj
--250 TJm
-(handling) 34.8691 Tj
-[1 0 0 1 186.599 208.672] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4906 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -191.58 -208.672] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-201.629 208.672 Td
-/F147_0 9.9626 Tf
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
-[1 0 0 1 506.127 208.672] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -506.127 -208.672] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-506.127 208.672 Td
-/F130_0 9.9626 Tf
-(29) 9.9626 Tj
-[1 0 0 1 516.09 208.672] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -444.09 -2.1568] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.7983] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -196.717] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 196.717 Td
-/F130_0 9.9626 Tf
-(3.8.) 14.9439 Tj
--310 TJm
-(Making) 30.9936 Tj
--250 TJm
-(a) 4.42339 Tj
--250 TJm
-(W) 9.40469 Tj
-40 TJm
-(indo) 17.7135 Tj
-25 TJm
-(ws) 11.0684 Tj
--250 TJm
-(DLL) 19.3673 Tj
-[1 0 0 1 189.828 196.717] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4906 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -194.809 -196.717] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-203.243 196.717 Td
-/F147_0 9.9626 Tf
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
-[1 0 0 1 506.127 196.717] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -506.127 -196.717] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-506.127 196.717 Td
-/F130_0 9.9626 Tf
-(29) 9.9626 Tj
-[1 0 0 1 516.09 196.717] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -444.09 -2.1569] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.7983] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -184.761] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 184.761 Td
-/F130_0 9.9626 Tf
-(4.) 7.47195 Tj
--310 TJm
-(Miscellanea) 48.1393 Tj
-[1 0 0 1 130.699 184.761] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4906 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -135.68 -184.761] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-144.898 184.761 Td
-/F147_0 9.9626 Tf
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
-[1 0 0 1 506.127 184.761] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -506.127 -184.761] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-506.127 184.761 Td
-/F130_0 9.9626 Tf
-(31) 9.9626 Tj
-[1 0 0 1 516.09 184.761] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -444.09 -0.0995] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -11.8557] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -172.806] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 172.806 Td
-/F130_0 9.9626 Tf
-(4.1.) 14.9439 Tj
--310 TJm
-(Limitations) 45.9475 Tj
--250 TJm
-(of) 8.29885 Tj
--250 TJm
-(the) 12.1743 Tj
--250 TJm
-(compressed) 47.0334 Tj
--250 TJm
-(\002le) 12.7322 Tj
--250 TJm
-(format) 26.5603 Tj
-[1 0 0 1 255.231 172.806] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4906 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -260.212 -172.806] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-269.154 172.806 Td
-/F147_0 9.9626 Tf
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
-[1 0 0 1 506.127 172.806] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -506.127 -172.806] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-506.127 172.806 Td
-/F130_0 9.9626 Tf
-(31) 9.9626 Tj
-[1 0 0 1 516.09 172.806] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -444.09 -2.1568] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.7983] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -160.851] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 160.851 Td
-/F130_0 9.9626 Tf
-(4.2.) 14.9439 Tj
--310 TJm
-(Portability) 42.0721 Tj
--250 TJm
-(issues) 23.8007 Tj
-[1 0 0 1 158.395 160.851] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4906 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -163.376 -160.851] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-172.03 160.851 Td
-/F147_0 9.9626 Tf
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
-[1 0 0 1 506.127 160.851] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -506.127 -160.851] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-506.127 160.851 Td
-/F130_0 9.9626 Tf
-(32) 9.9626 Tj
-[1 0 0 1 516.09 160.851] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -444.09 -2.1569] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.7983] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -148.896] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 148.896 Td
-/F130_0 9.9626 Tf
-(4.3.) 14.9439 Tj
--310 TJm
-(Reporting) 39.8504 Tj
--250 TJm
-(b) 4.9813 Tj
-20 TJm
-(ugs) 13.8381 Tj
-[1 0 0 1 150.993 148.896] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4906 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -155.975 -148.896] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-166.115 148.896 Td
-/F147_0 9.9626 Tf
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
-[1 0 0 1 506.127 148.896] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -506.127 -148.896] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-506.127 148.896 Td
-/F130_0 9.9626 Tf
-(32) 9.9626 Tj
-[1 0 0 1 516.09 148.896] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -444.09 -2.1568] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.7984] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -136.941] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 136.941 Td
-/F130_0 9.9626 Tf
-(4.4.) 14.9439 Tj
--310 TJm
-(Did) 14.9439 Tj
--250 TJm
-(you) 14.9439 Tj
--250 TJm
-(get) 12.1743 Tj
--250 TJm
-(the) 12.1743 Tj
--250 TJm
-(right) 18.8194 Tj
--250 TJm
-(package?) 37.0609 Tj
-[1 0 0 1 212.602 136.941] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 3.0884 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 3.0884 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -218.778 -136.941] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-229.109 136.941 Td
-/F147_0 9.9626 Tf
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
-[1 0 0 1 506.127 136.941] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -506.127 -136.941] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-506.127 136.941 Td
-/F130_0 9.9626 Tf
-(33) 9.9626 Tj
-[1 0 0 1 516.09 136.941] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -444.09 -2.1568] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.7983] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -124.986] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 124.986 Td
-/F130_0 9.9626 Tf
-(4.5.) 14.9439 Tj
--310 TJm
-(Further) 29.3299 Tj
--250 TJm
-(Reading) 33.2053 Tj
-[1 0 0 1 155.058 124.986] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4906 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -160.039 -124.986] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-170.361 124.986 Td
-/F147_0 9.9626 Tf
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
-[1 0 0 1 506.127 124.986] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -506.127 -124.986] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-506.127 124.986 Td
-/F130_0 9.9626 Tf
-(34) 9.9626 Tj
-[1 0 0 1 516.09 124.986] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -444.09 -2.1569] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.9626] cm
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-[1 0 0 1 0 -62.0143] cm
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-[1 0 0 1 1.8929 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 374.394 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 6.7546] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 41.3997 -6.7546] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -494.668 -50.8518] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-536.068 50.8518 Td
-/F130_0 9.9626 Tf
-(iii) 8.30881 Tj
-[1 0 0 1 453.269 50.8518] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 93.5985 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 6.2765 0] cm
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-[1 0 0 1 -13.1436 0] cm
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-Q
-showpage
-%%PageTrailer
-pdfEndPage
-%%Page: 4 4
-%%BeginPageSetup
-%%PageOrientation: Portrait
-pdfStartPage
-0 0 612 792 re W
-%%EndPageSetup
-[] 0 d
-1 i
-0 j
-0 J
-10 M
-1 w
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-false op
-false OP
-0 0 612 792 re
-W
-q
-[1 0 0 1 72 741.554] cm
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-[1 0 0 1 1.8929 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 14.4459] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 187.197 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 140.398 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -140.398 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 280.796 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -472.974 -13.9477] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -0.4981] cm
-q
-[] 0 d
-0 J
-0.4981 w
-0 0.2491 m
-475.465 0.2491 l
-S
-Q
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 479.251 0] cm
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-[1 0 0 1 -13.1436 0] cm
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-[1 0 0 1 -468 -21.5542] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -720] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 701.916 Td
-/F122_0 24.7902 Tf
-(1.) 20.675 Tj
--278 TJm
-(Intr) 39.937 Tj
-20 TJm
-(oduction) 104.664 Tj
-[1 0 0 1 72 701.606] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-[1 0 0 1 0 -9.9626] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -691.643] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 679.998 Td
-/F134_0 9.9626 Tf
-(bzip2) 29.8878 Tj
-[1 0 0 1 101.888 679.998] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -101.888 -679.998] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-104.507 679.998 Td
-/F130_0 9.9626 Tf
-(compresses) 45.9276 Tj
--263 TJm
-(\002les) 16.6077 Tj
--263 TJm
-(using) 21.589 Tj
--263 TJm
-(the) 12.1743 Tj
--262 TJm
-(Burro) 23.2427 Tj
-25 TJm
-(ws-Wheeler) 48.1293 Tj
--263 TJm
-(block-sorting) 53.1305 Tj
--263 TJm
-(te) 7.193 Tj
-15 TJm
-(xt) 7.7509 Tj
--263 TJm
-(compression) 50.3609 Tj
--263 TJm
-(algorithm,) 41.2352 Tj
--266 TJm
-(and) 14.386 Tj
--263 TJm
-(Huf) 15.4918 Tj
-25 TJm
-(fman) 20.4731 Tj
--263 TJm
-(coding.) 29.6088 Tj
-72 668.043 Td
-(Compression) 52.5826 Tj
--203 TJm
-(is) 6.64505 Tj
--204 TJm
-(generally) 37.0708 Tj
--203 TJm
-(considerably) 50.9089 Tj
--203 TJm
-(better) 22.6848 Tj
--204 TJm
-(t) 2.7696 Tj
-1 TJm
-(han) 14.386 Tj
--204 TJm
-(that) 14.9439 Tj
--203 TJm
-(achie) 21.0211 Tj
-25 TJm
-(v) 4.9813 Tj
-15 TJm
-(ed) 9.40469 Tj
--203 TJm
-(by) 9.9626 Tj
--204 TJm
-(more) 20.4731 Tj
--203 TJm
-(con) 14.386 Tj
-40 TJm
-(v) 4.9813 Tj
-15 TJm
-(entional) 32.0995 Tj
--203 TJm
-(LZ77/LZ78-based) 73.0458 Tj
--204 TJm
-(compressors,) 52.2937 Tj
-72 656.087 Td
-(and) 14.386 Tj
--250 TJm
-(approaches) 44.8118 Tj
--250 TJm
-(the) 12.1743 Tj
--250 TJm
-(performance) 50.341 Tj
--250 TJm
-(of) 8.29885 Tj
--250 TJm
-(the) 12.1743 Tj
--250 TJm
-(PPM) 19.9352 Tj
--250 TJm
-(f) 3.31755 Tj
-10 TJm
-(amily) 22.6948 Tj
--250 TJm
-(of) 8.29885 Tj
--250 TJm
-(statistical) 37.6387 Tj
--250 TJm
-(compressors.) 52.2937 Tj
-[1 0 0 1 72 653.931] cm
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-[1 0 0 1 0 -9.9627] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -643.968] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 634.17 Td
-/F134_0 9.9626 Tf
-(bzip2) 29.8878 Tj
-[1 0 0 1 101.888 634.17] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -101.888 -634.17] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-105.073 634.17 Td
-/F130_0 9.9626 Tf
-(is) 6.64505 Tj
--320 TJm
-(b) 4.9813 Tj
-20 TJm
-(uilt) 13.2901 Tj
--319 TJm
-(on) 9.9626 Tj
--320 TJm
-(top) 12.7322 Tj
--320 TJm
-(of) 8.29885 Tj
-[1 0 0 1 176.712 634.17] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -176.712 -634.17] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-176.712 634.17 Td
-/F134_0 9.9626 Tf
-(libbzip2) 47.8205 Tj
-[1 0 0 1 224.533 634.17] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -224.533 -634.17] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-224.533 634.17 Td
-/F130_0 9.9626 Tf
-(,) 2.49065 Tj
--337 TJm
-(a) 4.42339 Tj
--320 TJm
-(\003e) 9.9626 Tj
-15 TJm
-(xible) 19.9252 Tj
--320 TJm
-(library) 26.5603 Tj
--319 TJm
-(for) 11.6164 Tj
--320 TJm
-(handling) 34.8691 Tj
--320 TJm
-(compressed) 47.0334 Tj
--320 TJm
-(data) 16.5977 Tj
--319 TJm
-(in) 7.7509 Tj
--320 TJm
-(the) 12.1743 Tj
-[1 0 0 1 449.816 634.17] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -449.816 -634.17] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-449.816 634.17 Td
-/F134_0 9.9626 Tf
-(bzip2) 29.8878 Tj
-[1 0 0 1 479.704 634.17] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -479.704 -634.17] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-482.889 634.17 Td
-/F130_0 9.9626 Tf
-(format.) 29.0509 Tj
--1039 TJm
-(This) 17.7135 Tj
-72 622.214 Td
-(manual) 29.3299 Tj
--316 TJm
-(describes) 37.0708 Tj
--316 TJm
-(both) 17.7135 Tj
--317 TJm
-(ho) 9.9626 Tj
-25 TJm
-(w) 7.193 Tj
--316 TJm
-(to) 7.7509 Tj
--316 TJm
-(use) 13.2801 Tj
--316 TJm
-(the) 12.1743 Tj
--316 TJm
-(program) 33.7533 Tj
--316 TJm
-(and) 14.386 Tj
--317 TJm
-(ho) 9.9626 Tj
-25 TJm
-(w) 7.193 Tj
--316 TJm
-(to) 7.7509 Tj
--316 TJm
-(w) 7.193 Tj
-10 TJm
-(ork) 13.2801 Tj
--316 TJm
-(with) 17.7135 Tj
--316 TJm
-(the) 12.1743 Tj
--317 TJm
-(library) 26.5603 Tj
--316 TJm
-(interf) 21.579 Tj
-10 TJm
-(ace.) 15.7608 Tj
--1017 TJm
-(Most) 20.4831 Tj
--316 TJm
-(of) 8.29885 Tj
--316 TJm
-(the) 12.1743 Tj
--317 TJm
-(manual) 29.3299 Tj
--316 TJm
-(is) 6.64505 Tj
-72 610.259 Td
-(de) 9.40469 Tj
-25 TJm
-(v) 4.9813 Tj
-20 TJm
-(oted) 17.1556 Tj
--250 TJm
-(to) 7.7509 Tj
--250 TJm
-(this) 14.396 Tj
--250 TJm
-(library) 26.5603 Tj
-65 TJm
-(,) 2.49065 Tj
--250 TJm
-(not) 12.7322 Tj
--250 TJm
-(the) 12.1743 Tj
--250 TJm
-(program,) 36.2439 Tj
--250 TJm
-(which) 24.3486 Tj
--250 TJm
-(is) 6.64505 Tj
--250 TJm
-(good) 19.9252 Tj
--250 TJm
-(ne) 9.40469 Tj
-25 TJm
-(ws) 11.0684 Tj
--250 TJm
-(if) 6.08715 Tj
--250 TJm
-(your) 18.2614 Tj
--250 TJm
-(interest) 29.3299 Tj
--250 TJm
-(is) 6.64505 Tj
--250 TJm
-(only) 17.7135 Tj
--250 TJm
-(in) 7.7509 Tj
--250 TJm
-(the) 12.1743 Tj
--250 TJm
-(program.) 36.2439 Tj
-[1 0 0 1 72 608.102] cm
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-[1 0 0 1 0 -29.7236] cm
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-[1 0 0 1 6.9739 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -78.9739 -578.379] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-78.9739 578.379 Td
-/F130_0 9.9626 Tf
-(\225) 3.48691 Tj
-[1 0 0 1 82.4608 578.379] cm
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-[1 0 0 1 1.9925 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 1] sc
-/DeviceRGB {} CS
-[0 0 1] SC
-[1 0 0 1 -86.944 -578.379] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-86.944 578.379 Td
-/F130_0 9.9626 Tf
-(Ho) 12.1743 Tj
-25 TJm
-(w) 7.193 Tj
--259 TJm
-(to) 7.7509 Tj
--260 TJm
-(use) 13.2801 Tj
--259 TJm
-(bzip2) 22.1369 Tj
-[1 0 0 1 156.985 578.379] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 1] sc
-/DeviceRGB {} CS
-[0 0 1] SC
-/DeviceRGB {} cs
-[0 0 1] sc
-/DeviceRGB {} CS
-[0 0 1] SC
-[1 0 0 1 -156.985 -578.379] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-159.57 578.379 Td
-/F130_0 9.9626 Tf
-([2]) 11.6164 Tj
-[1 0 0 1 171.186 578.379] cm
-/DeviceRGB {} cs
-[0 0 1] sc
-/DeviceRGB {} CS
-[0 0 1] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -171.186 -578.379] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-173.771 578.379 Td
-/F130_0 9.9626 Tf
-(describes) 37.0708 Tj
--259 TJm
-(ho) 9.9626 Tj
-25 TJm
-(w) 7.193 Tj
--260 TJm
-(to) 7.7509 Tj
--259 TJm
-(use) 13.2801 Tj
-[1 0 0 1 259.119 578.379] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -259.119 -578.379] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-259.119 578.379 Td
-/F134_0 9.9626 Tf
-(bzip2) 29.8878 Tj
-[1 0 0 1 289.007 578.379] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -289.007 -578.379] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-289.007 578.379 Td
-/F130_0 9.9626 Tf
-(;) 2.7696 Tj
--264 TJm
-(this) 14.396 Tj
--260 TJm
-(is) 6.64505 Tj
--259 TJm
-(the) 12.1743 Tj
--260 TJm
-(only) 17.7135 Tj
--259 TJm
-(part) 15.4918 Tj
--259 TJm
-(you) 14.9439 Tj
--260 TJm
-(need) 18.8094 Tj
--259 TJm
-(to) 7.7509 Tj
--260 TJm
-(read) 17.1456 Tj
--259 TJm
-(if) 6.08715 Tj
--260 TJm
-(you) 14.9439 Tj
--259 TJm
-(just) 14.396 Tj
--260 TJm
-(w) 7.193 Tj
-10 TJm
-(ant) 12.1743 Tj
--259 TJm
-(to) 7.7509 Tj
--260 TJm
-(kno) 14.9439 Tj
-25 TJm
-(w) 7.193 Tj
-86.944 566.424 Td
-(ho) 9.9626 Tj
-25 TJm
-(w) 7.193 Tj
--250 TJm
-(to) 7.7509 Tj
--250 TJm
-(operate) 29.3199 Tj
--250 TJm
-(the) 12.1743 Tj
--250 TJm
-(program.) 36.2439 Tj
-[1 0 0 1 199.302 566.424] cm
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-[1 0 0 1 -127.302 -21.9178] cm
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-[1 0 0 1 6.9739 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -78.9739 -544.506] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-78.9739 544.506 Td
-/F130_0 9.9626 Tf
-(\225) 3.48691 Tj
-[1 0 0 1 82.4608 544.506] cm
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-[1 0 0 1 1.9925 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 1] sc
-/DeviceRGB {} CS
-[0 0 1] SC
-[1 0 0 1 -86.944 -544.506] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-86.944 544.506 Td
-/F130_0 9.9626 Tf
-(Programming) 54.7943 Tj
--250 TJm
-(with) 17.7135 Tj
--250 TJm
-(libbzip2) 32.6574 Tj
-[1 0 0 1 197.09 544.506] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 1] sc
-/DeviceRGB {} CS
-[0 0 1] SC
-/DeviceRGB {} cs
-[0 0 1] sc
-/DeviceRGB {} CS
-[0 0 1] SC
-[1 0 0 1 -197.09 -544.506] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-199.58 544.506 Td
-/F130_0 9.9626 Tf
-([8]) 11.6164 Tj
-[1 0 0 1 211.197 544.506] cm
-/DeviceRGB {} cs
-[0 0 1] sc
-/DeviceRGB {} CS
-[0 0 1] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -211.197 -544.506] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-213.687 544.506 Td
-/F130_0 9.9626 Tf
-(describes) 37.0708 Tj
--250 TJm
-(the) 12.1743 Tj
--250 TJm
-(programming) 54.2364 Tj
--250 TJm
-(interf) 21.579 Tj
-10 TJm
-(aces) 17.1456 Tj
--250 TJm
-(in) 7.7509 Tj
--250 TJm
-(detail,) 24.6275 Tj
--250 TJm
-(and) 14.386 Tj
-[1 0 0 1 417.501 544.506] cm
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-[1 0 0 1 -345.501 -21.9178] cm
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-[1 0 0 1 6.9739 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -78.9739 -522.588] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-78.9739 522.588 Td
-/F130_0 9.9626 Tf
-(\225) 3.48691 Tj
-[1 0 0 1 82.4608 522.588] cm
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-[1 0 0 1 1.9925 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 1] sc
-/DeviceRGB {} CS
-[0 0 1] SC
-[1 0 0 1 -86.944 -522.588] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-86.944 522.588 Td
-/F130_0 9.9626 Tf
-(Miscellanea) 48.1393 Tj
-[1 0 0 1 135.083 522.588] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 1] sc
-/DeviceRGB {} CS
-[0 0 1] SC
-/DeviceRGB {} cs
-[0 0 1] sc
-/DeviceRGB {} CS
-[0 0 1] SC
-[1 0 0 1 -135.083 -522.588] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-137.573 522.588 Td
-/F130_0 9.9626 Tf
-([31]) 16.5977 Tj
-[1 0 0 1 154.171 522.588] cm
-/DeviceRGB {} cs
-[0 0 1] sc
-/DeviceRGB {} CS
-[0 0 1] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -154.171 -522.588] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-156.662 522.588 Td
-/F130_0 9.9626 Tf
-(records) 29.3199 Tj
--250 TJm
-(some) 21.031 Tj
--250 TJm
-(miscellaneous) 56.4481 Tj
--250 TJm
-(notes) 21.031 Tj
--250 TJm
-(which) 24.3486 Tj
--250 TJm
-(I) 3.31755 Tj
--250 TJm
-(thought) 30.4457 Tj
--250 TJm
-(ought) 22.6948 Tj
--250 TJm
-(to) 7.7509 Tj
--250 TJm
-(be) 9.40469 Tj
--250 TJm
-(recorded) 34.8492 Tj
--250 TJm
-(some) 21.031 Tj
-25 TJm
-(where.) 26.8293 Tj
-[1 0 0 1 492.31 522.588] cm
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-[1 0 0 1 -420.31 -471.736] cm
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-[1 0 0 1 1.8929 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 374.394 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 6.7546] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 43.0633 -6.7546] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -496.332 -50.8518] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-539.395 50.8518 Td
-/F130_0 9.9626 Tf
-(1) 4.9813 Tj
-[1 0 0 1 453.269 50.8518] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 93.5985 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 6.2765 0] cm
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-[1 0 0 1 -13.1436 0] cm
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-Q
-showpage
-%%PageTrailer
-pdfEndPage
-%%Page: 5 5
-%%BeginPageSetup
-%%PageOrientation: Portrait
-pdfStartPage
-0 0 612 792 re W
-%%EndPageSetup
-[] 0 d
-1 i
-0 j
-0 J
-10 M
-1 w
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-false op
-false OP
-0 0 612 792 re
-W
-q
-[1 0 0 1 72 741.554] cm
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-[1 0 0 1 1.8929 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 14.4459] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 187.197 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 140.398 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -140.398 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 280.796 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -472.974 -13.9477] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -0.4981] cm
-q
-[] 0 d
-0 J
-0.4981 w
-0 0.2491 m
-475.465 0.2491 l
-S
-Q
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 479.251 0] cm
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-[1 0 0 1 -13.1436 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -468 -21.5542] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -720] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 701.916 Td
-/F122_0 24.7902 Tf
-(2.) 20.675 Tj
--278 TJm
-(Ho) 33.0453 Tj
-15 TJm
-(w) 19.2868 Tj
--278 TJm
-(to) 23.4019 Tj
--278 TJm
-(use) 42.7135 Tj
--278 TJm
-(bzip2) 63.3638 Tj
-[1 0 0 1 72 696.784] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-[1 0 0 1 0 -9.9626] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -14.944] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -671.877] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 656.35 Td
-/F122_0 17.2154 Tf
-(T) 10.5186 Tj
-80 TJm
-(ab) 20.0904 Tj
-10 TJm
-(le) 14.3576 Tj
--278 TJm
-(of) 16.2513 Tj
--278 TJm
-(Contents) 74.5943 Tj
-[1 0 0 1 72 647.528] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -11.7401] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -635.788] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 635.788 Td
-/F130_0 9.9626 Tf
-(2.1.) 14.9439 Tj
--310 TJm
-(N) 7.193 Tj
-35 TJm
-(AME) 22.1369 Tj
-[1 0 0 1 119.014 635.788] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4906 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -123.995 -635.788] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-132.691 635.788 Td
-/F147_0 9.9626 Tf
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
-[1 0 0 1 511.108 635.788] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -511.108 -635.788] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-511.108 635.788 Td
-/F130_0 9.9626 Tf
-(2) 4.9813 Tj
-[1 0 0 1 516.09 635.788] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -444.09 -0.0995] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -11.8556] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -623.832] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 623.832 Td
-/F130_0 9.9626 Tf
-(2.2.) 14.9439 Tj
--310 TJm
-(SYNOPSIS) 47.0534 Tj
-[1 0 0 1 137.085 623.832] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4906 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -142.067 -623.832] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-150.582 623.832 Td
-/F147_0 9.9626 Tf
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
-[1 0 0 1 511.108 623.832] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -511.108 -623.832] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-511.108 623.832 Td
-/F130_0 9.9626 Tf
-(2) 4.9813 Tj
-[1 0 0 1 516.09 623.832] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -444.09 -0.0996] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -11.8556] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -611.877] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 611.877 Td
-/F130_0 9.9626 Tf
-(2.3.) 14.9439 Tj
--310 TJm
-(DESCRIPTION) 64.7569 Tj
-[1 0 0 1 154.789 611.877] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -159.77 -611.877] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-168.29 611.877 Td
-/F147_0 9.9626 Tf
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
-[1 0 0 1 511.108 611.877] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -511.108 -611.877] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-511.108 611.877 Td
-/F130_0 9.9626 Tf
-(3) 4.9813 Tj
-[1 0 0 1 516.09 611.877] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -444.09 -0.0995] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -11.8557] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -599.922] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 599.922 Td
-/F130_0 9.9626 Tf
-(2.4.) 14.9439 Tj
--310 TJm
-(OPTIONS) 42.0621 Tj
-[1 0 0 1 132.094 599.922] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4906 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -137.076 -599.922] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-145.873 599.922 Td
-/F147_0 9.9626 Tf
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
-[1 0 0 1 511.108 599.922] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -511.108 -599.922] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-511.108 599.922 Td
-/F130_0 9.9626 Tf
-(4) 4.9813 Tj
-[1 0 0 1 516.09 599.922] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -444.09 -0.0995] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -11.8556] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -587.967] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 587.967 Td
-/F130_0 9.9626 Tf
-(2.5.) 14.9439 Tj
--310 TJm
-(MEMOR) 37.6387 Tj
-65 TJm
-(Y) 7.193 Tj
--250 TJm
-(MAN) 23.2427 Tj
-35 TJm
-(A) 7.193 Tj
-40 TJm
-(GEMENT) 41.5042 Tj
-[1 0 0 1 207.9 587.967] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4906 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -212.881 -587.967] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-221.412 587.967 Td
-/F147_0 9.9626 Tf
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
-[1 0 0 1 511.108 587.967] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -511.108 -587.967] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-511.108 587.967 Td
-/F130_0 9.9626 Tf
-(5) 4.9813 Tj
-[1 0 0 1 516.09 587.967] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -444.09 -0.0996] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -11.8556] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -576.012] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 576.012 Td
-/F130_0 9.9626 Tf
-(2.6.) 14.9439 Tj
--310 TJm
-(RECO) 26.5703 Tj
-50 TJm
-(VERING) 37.6287 Tj
--250 TJm
-(D) 7.193 Tj
-40 TJm
-(A) 7.193 Tj
-111 TJm
-(T) 6.08715 Tj
-93 TJm
-(A) 7.193 Tj
--250 TJm
-(FR) 12.1843 Tj
-40 TJm
-(OM) 16.0497 Tj
--250 TJm
-(D) 7.193 Tj
-40 TJm
-(AMA) 23.2427 Tj
-40 TJm
-(GED) 20.4731 Tj
--250 TJm
-(FILES) 26.5703 Tj
-[1 0 0 1 293.449 576.012] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4906 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -298.43 -576.012] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-308.464 576.012 Td
-/F147_0 9.9626 Tf
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
-[1 0 0 1 511.108 576.012] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -511.108 -576.012] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-511.108 576.012 Td
-/F130_0 9.9626 Tf
-(6) 4.9813 Tj
-[1 0 0 1 516.09 576.012] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -444.09 -0.0995] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -11.8557] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -564.056] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 564.056 Td
-/F130_0 9.9626 Tf
-(2.7.) 14.9439 Tj
--310 TJm
-(PERFORMANCE) 73.6236 Tj
--250 TJm
-(NO) 14.386 Tj
-40 TJm
-(TES) 17.7135 Tj
-[1 0 0 1 197.847 564.056] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4906 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -202.829 -564.056] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-211.958 564.056 Td
-/F147_0 9.9626 Tf
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
-[1 0 0 1 511.108 564.056] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -511.108 -564.056] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-511.108 564.056 Td
-/F130_0 9.9626 Tf
-(6) 4.9813 Tj
-[1 0 0 1 516.09 564.056] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -444.09 -0.0995] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -11.8556] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -552.101] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 552.101 Td
-/F130_0 9.9626 Tf
-(2.8.) 14.9439 Tj
--310 TJm
-(CA) 13.8381 Tj
-135 TJm
-(VEA) 20.4731 Tj
-111 TJm
-(TS) 11.6264 Tj
-[1 0 0 1 133.519 552.101] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -138.5 -552.101] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-148.799 552.101 Td
-/F147_0 9.9626 Tf
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
-[1 0 0 1 511.108 552.101] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -511.108 -552.101] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-511.108 552.101 Td
-/F130_0 9.9626 Tf
-(7) 4.9813 Tj
-[1 0 0 1 516.09 552.101] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -444.09 -0.0996] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -11.8556] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -540.146] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 540.146 Td
-/F130_0 9.9626 Tf
-(2.9.) 14.9439 Tj
--310 TJm
-(A) 7.193 Tj
-55 TJm
-(UTHOR) 34.3112 Tj
-[1 0 0 1 130.989 540.146] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -135.97 -540.146] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-145.32 540.146 Td
-/F147_0 9.9626 Tf
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
-[1 0 0 1 511.108 540.146] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -511.108 -540.146] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-511.108 540.146 Td
-/F130_0 9.9626 Tf
-(7) 4.9813 Tj
-[1 0 0 1 516.09 540.146] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -444.09 -0.2191] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.9627] cm
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-[1 0 0 1 0 -9.9626] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -520.002] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 508.266 Td
-/F130_0 9.9626 Tf
-(This) 17.7135 Tj
--250 TJm
-(chapter) 29.3199 Tj
--250 TJm
-(contains) 33.2053 Tj
--250 TJm
-(a) 4.42339 Tj
--250 TJm
-(cop) 14.386 Tj
-10 TJm
-(y) 4.9813 Tj
--250 TJm
-(of) 8.29885 Tj
--250 TJm
-(the) 12.1743 Tj
-[1 0 0 1 213.837 508.266] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -213.837 -508.266] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-213.837 508.266 Td
-/F134_0 9.9626 Tf
-(bzip2) 29.8878 Tj
-[1 0 0 1 243.725 508.266] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -243.725 -508.266] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-246.215 508.266 Td
-/F130_0 9.9626 Tf
-(man) 17.1556 Tj
--250 TJm
-(page,) 21.3 Tj
--250 TJm
-(and) 14.386 Tj
--250 TJm
-(nothing) 30.4457 Tj
--250 TJm
-(else.) 17.9825 Tj
-[1 0 0 1 72 506.109] cm
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.9626] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -496.146] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 473.513 Td
-/F122_0 20.6585 Tf
-(2.1.) 34.4584 Tj
--278 TJm
-(NAME) 60.8186 Tj
-[1 0 0 1 72 473.513] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -31.8804] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 6.9739 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -78.9739 -441.632] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-78.9739 441.632 Td
-/F130_0 9.9626 Tf
-(\225) 3.48691 Tj
-[1 0 0 1 82.4608 441.632] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 1.9925 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -86.944 -441.632] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-86.944 441.632 Td
-/F134_0 9.9626 Tf
-(bzip2) 29.8878 Tj
-[1 0 0 1 116.832 441.632] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -116.832 -441.632] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-116.832 441.632 Td
-/F130_0 9.9626 Tf
-(,) 2.49065 Tj
-[1 0 0 1 121.813 441.632] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -121.813 -441.632] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-121.813 441.632 Td
-/F134_0 9.9626 Tf
-(bunzip2) 41.8429 Tj
-[1 0 0 1 163.656 441.632] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -163.656 -441.632] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-166.147 441.632 Td
-/F130_0 9.9626 Tf
-(-) 3.31755 Tj
--250 TJm
-(a) 4.42339 Tj
--250 TJm
-(block-sorting) 53.1305 Tj
--250 TJm
-(\002le) 12.7322 Tj
--250 TJm
-(compressor) 45.9276 Tj
-40 TJm
-(,) 2.49065 Tj
--250 TJm
-(v1.0.4) 24.9065 Tj
-[1 0 0 1 325.129 441.632] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -253.129 -21.9179] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 6.9739 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -78.9739 -419.715] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-78.9739 419.715 Td
-/F130_0 9.9626 Tf
-(\225) 3.48691 Tj
-[1 0 0 1 82.4608 419.715] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 1.9925 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -86.944 -419.715] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-86.944 419.715 Td
-/F134_0 9.9626 Tf
-(bzcat) 29.8878 Tj
-[1 0 0 1 116.832 419.715] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -116.832 -419.715] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-119.322 419.715 Td
-/F130_0 9.9626 Tf
-(-) 3.31755 Tj
--250 TJm
-(decompresses) 55.3323 Tj
--250 TJm
-(\002les) 16.6077 Tj
--250 TJm
-(to) 7.7509 Tj
--250 TJm
-(stdout) 24.3586 Tj
-[1 0 0 1 236.651 419.715] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -164.651 -21.9178] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 6.9739 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -78.9739 -397.797] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-78.9739 397.797 Td
-/F130_0 9.9626 Tf
-(\225) 3.48691 Tj
-[1 0 0 1 82.4608 397.797] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 1.9925 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -86.944 -397.797] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-86.944 397.797 Td
-/F134_0 9.9626 Tf
-(bzip2recover) 71.7307 Tj
-[1 0 0 1 158.675 397.797] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -158.675 -397.797] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-161.166 397.797 Td
-/F130_0 9.9626 Tf
-(-) 3.31755 Tj
--250 TJm
-(reco) 17.1456 Tj
-15 TJm
-(v) 4.9813 Tj
-15 TJm
-(ers) 11.6164 Tj
--250 TJm
-(data) 16.5977 Tj
--250 TJm
-(from) 19.3673 Tj
--250 TJm
-(damaged) 35.965 Tj
--250 TJm
-(bzip2) 22.1369 Tj
--250 TJm
-(\002les) 16.6077 Tj
-[1 0 0 1 323.545 397.797] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -251.545 -12.1195] cm
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.9626] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -375.715] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 353.081 Td
-/F122_0 20.6585 Tf
-(2.2.) 34.4584 Tj
--278 TJm
-(SYNOPSIS) 105.627 Tj
-[1 0 0 1 72 352.823] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -31.6223] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 6.9739 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -78.9739 -321.201] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-78.9739 321.201 Td
-/F130_0 9.9626 Tf
-(\225) 3.48691 Tj
-[1 0 0 1 82.4608 321.201] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 1.9925 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -86.944 -321.201] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-86.944 321.201 Td
-/F134_0 9.9626 Tf
-(bzip2) 29.8878 Tj
-[1 0 0 1 116.832 321.201] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -116.832 -321.201] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-119.322 321.201 Td
-/F130_0 9.9626 Tf
-([) 3.31755 Tj
--250 TJm
-(-cdfkqstvzVL123456789) 100.164 Tj
--250 TJm
-(]) 3.31755 Tj
--250 TJm
-([) 3.31755 Tj
--250 TJm
-(\002lenames) 38.1866 Tj
--250 TJm
-(...) 7.47195 Tj
--620 TJm
-(]) 3.31755 Tj
-[1 0 0 1 297.045 321.201] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -225.045 -21.9178] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 6.9739 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -78.9739 -299.283] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-78.9739 299.283 Td
-/F130_0 9.9626 Tf
-(\225) 3.48691 Tj
-[1 0 0 1 82.4608 299.283] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 1.9925 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -86.944 -299.283] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-86.944 299.283 Td
-/F134_0 9.9626 Tf
-(bunzip2) 41.8429 Tj
-[1 0 0 1 128.787 299.283] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -128.787 -299.283] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-131.278 299.283 Td
-/F130_0 9.9626 Tf
-([) 3.31755 Tj
--250 TJm
-(-fkvsVL) 33.7533 Tj
--250 TJm
-(]) 3.31755 Tj
--250 TJm
-([) 3.31755 Tj
--250 TJm
-(\002lenames) 38.1866 Tj
--250 TJm
-(...) 7.47195 Tj
--620 TJm
-(]) 3.31755 Tj
-[1 0 0 1 242.589 299.283] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -170.589 -21.9178] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 6.9739 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -78.9739 -277.365] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-78.9739 277.365 Td
-/F130_0 9.9626 Tf
-(\225) 3.48691 Tj
-[1 0 0 1 82.4608 277.365] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 1.9925 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -86.944 -277.365] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-86.944 277.365 Td
-/F134_0 9.9626 Tf
-(bzcat) 29.8878 Tj
-[1 0 0 1 116.832 277.365] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -116.832 -277.365] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-119.322 277.365 Td
-/F130_0 9.9626 Tf
-([) 3.31755 Tj
--250 TJm
-(-s) 7.193 Tj
--250 TJm
-(]) 3.31755 Tj
--250 TJm
-([) 3.31755 Tj
--250 TJm
-(\002lenames) 38.1866 Tj
--250 TJm
-(...) 7.47195 Tj
--620 TJm
-(]) 3.31755 Tj
-[1 0 0 1 204.074 277.365] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -132.074 -21.9178] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 6.9739 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -78.9739 -255.447] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-78.9739 255.447 Td
-/F130_0 9.9626 Tf
-(\225) 3.48691 Tj
-[1 0 0 1 82.4608 255.447] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 1.9925 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -86.944 -255.447] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-86.944 255.447 Td
-/F134_0 9.9626 Tf
-(bzip2recover) 71.7307 Tj
-[1 0 0 1 158.675 255.447] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -158.675 -255.447] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-161.166 255.447 Td
-/F130_0 9.9626 Tf
-(\002lename) 34.3112 Tj
-[1 0 0 1 195.476 255.447] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -123.477 -204.596] cm
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-[1 0 0 1 1.8929 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 374.394 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 6.7545] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 43.0633 -6.7545] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -496.332 -50.8519] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-539.395 50.8519 Td
-/F130_0 9.9626 Tf
-(2) 4.9813 Tj
-[1 0 0 1 453.269 50.8519] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 93.5985 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 6.2765 0] cm
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-[1 0 0 1 -13.1436 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-Q
-showpage
-%%PageTrailer
-pdfEndPage
-%%Page: 6 6
-%%BeginPageSetup
-%%PageOrientation: Portrait
-pdfStartPage
-0 0 612 792 re W
-%%EndPageSetup
-[] 0 d
-1 i
-0 j
-0 J
-10 M
-1 w
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-false op
-false OP
-0 0 612 792 re
-W
-q
-[1 0 0 1 72 741.554] cm
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-[1 0 0 1 1.8929 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 14.4459] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 187.197 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 -8.9114] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 8.9114] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 105.519 -6.7546] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -371.59 -749.245] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-477.109 749.245 Td
-/F130_0 9.9626 Tf
-(Ho) 12.1743 Tj
-25 TJm
-(w) 7.193 Tj
--250 TJm
-(to) 7.7509 Tj
--250 TJm
-(use) 13.2801 Tj
--250 TJm
-(bzip2) 22.1369 Tj
-[1 0 0 1 266.071 747.089] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 280.796 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -472.974 -5.0363] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -0.4981] cm
-q
-[] 0 d
-0 J
-0.4981 w
-0 0.2491 m
-475.465 0.2491 l
-S
-Q
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 479.251 0] cm
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-[1 0 0 1 -13.1436 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -468 -21.5542] cm
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -720] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 704.93 Td
-/F122_0 20.6585 Tf
-(2.3.) 34.4584 Tj
--278 TJm
-(DESCRIPTION) 141.18 Tj
-[1 0 0 1 72 704.672] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.9626] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -694.709] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 683.012 Td
-/F134_0 9.9626 Tf
-(bzip2) 29.8878 Tj
-[1 0 0 1 101.888 683.012] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -101.888 -683.012] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-104.56 683.012 Td
-/F130_0 9.9626 Tf
-(compresses) 45.9276 Tj
--268 TJm
-(\002les) 16.6077 Tj
--268 TJm
-(using) 21.589 Tj
--268 TJm
-(the) 12.1743 Tj
--269 TJm
-(Burro) 23.2427 Tj
-25 TJm
-(ws-Wheeler) 48.1293 Tj
--268 TJm
-(block) 22.1369 Tj
--268 TJm
-(sorting) 27.6761 Tj
--268 TJm
-(te) 7.193 Tj
-15 TJm
-(xt) 7.7509 Tj
--268 TJm
-(compression) 50.3609 Tj
--268 TJm
-(algorithm,) 41.2352 Tj
--273 TJm
-(and) 14.386 Tj
--268 TJm
-(Huf) 15.4918 Tj
-25 TJm
-(fman) 20.4731 Tj
--269 TJm
-(c) 4.42339 Tj
-1 TJm
-(od) 9.9626 Tj
--1 TJm
-(i) 2.7696 Tj
-1 TJm
-(ng.) 12.4533 Tj
-72 671.057 Td
-(Compression) 52.5826 Tj
--203 TJm
-(is) 6.64505 Tj
--204 TJm
-(generally) 37.0708 Tj
--203 TJm
-(considerably) 50.9089 Tj
--203 TJm
-(better) 22.6848 Tj
--204 TJm
-(t) 2.7696 Tj
-1 TJm
-(han) 14.386 Tj
--204 TJm
-(that) 14.9439 Tj
--203 TJm
-(achie) 21.0211 Tj
-25 TJm
-(v) 4.9813 Tj
-15 TJm
-(ed) 9.40469 Tj
--203 TJm
-(by) 9.9626 Tj
--204 TJm
-(more) 20.4731 Tj
--203 TJm
-(con) 14.386 Tj
-40 TJm
-(v) 4.9813 Tj
-15 TJm
-(entional) 32.0995 Tj
--203 TJm
-(LZ77/LZ78-based) 73.0458 Tj
--204 TJm
-(compressors,) 52.2937 Tj
-72 659.101 Td
-(and) 14.386 Tj
--250 TJm
-(approaches) 44.8118 Tj
--250 TJm
-(the) 12.1743 Tj
--250 TJm
-(performance) 50.341 Tj
--250 TJm
-(of) 8.29885 Tj
--250 TJm
-(the) 12.1743 Tj
--250 TJm
-(PPM) 19.9352 Tj
--250 TJm
-(f) 3.31755 Tj
-10 TJm
-(amily) 22.6948 Tj
--250 TJm
-(of) 8.29885 Tj
--250 TJm
-(statistical) 37.6387 Tj
--250 TJm
-(compressors.) 52.2937 Tj
-[1 0 0 1 72 656.945] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.9626] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -646.982] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 637.184 Td
-/F130_0 9.9626 Tf
-(The) 15.4918 Tj
--250 TJm
-(command-line) 57.5539 Tj
--250 TJm
-(options) 29.3399 Tj
--250 TJm
-(are) 12.1643 Tj
--250 TJm
-(deliberately) 47.0334 Tj
--250 TJm
-(v) 4.9813 Tj
-15 TJm
-(ery) 12.7222 Tj
--250 TJm
-(similar) 27.6761 Tj
--250 TJm
-(to) 7.7509 Tj
--250 TJm
-(those) 21.031 Tj
--250 TJm
-(of) 8.29885 Tj
--250 TJm
-(GNU) 21.579 Tj
-[1 0 0 1 364.869 637.184] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -364.869 -637.184] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-364.869 637.184 Td
-/F134_0 9.9626 Tf
-(gzip) 23.9102 Tj
-[1 0 0 1 388.779 637.184] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -388.779 -637.184] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-388.779 637.184 Td
-/F130_0 9.9626 Tf
-(,) 2.49065 Tj
--250 TJm
-(b) 4.9813 Tj
-20 TJm
-(ut) 7.7509 Tj
--250 TJm
-(the) 12.1743 Tj
-15 TJm
-(y) 4.9813 Tj
--250 TJm
-(are) 12.1643 Tj
--250 TJm
-(not) 12.7322 Tj
--250 TJm
-(identical.) 36.8018 Tj
-[1 0 0 1 72 635.027] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.9626] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -625.064] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 615.266 Td
-/F134_0 9.9626 Tf
-(bzip2) 29.8878 Tj
-[1 0 0 1 101.888 615.266] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -101.888 -615.266] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-105.175 615.266 Td
-/F130_0 9.9626 Tf
-(e) 4.42339 Tj
-15 TJm
-(xpects) 25.4544 Tj
--330 TJm
-(a) 4.42339 Tj
--330 TJm
-(list) 12.1843 Tj
--330 TJm
-(of) 8.29885 Tj
--330 TJm
-(\002le) 12.7322 Tj
--329 TJm
-(names) 25.4544 Tj
--330 TJm
-(to) 7.7509 Tj
--330 TJm
-(accompan) 40.3884 Tj
-15 TJm
-(y) 4.9813 Tj
--330 TJm
-(the) 12.1743 Tj
--330 TJm
-(command-line) 57.5539 Tj
--330 TJm
-(\003ags.) 21.31 Tj
--1099 TJm
-(Each) 19.9152 Tj
--330 TJm
-(\002le) 12.7322 Tj
--330 TJm
-(is) 6.64505 Tj
--330 TJm
-(replaced) 33.7433 Tj
--330 TJm
-(by) 9.9626 Tj
--330 TJm
-(a) 4.42339 Tj
--330 TJm
-(compressed) 47.0334 Tj
-72 603.311 Td
-(v) 4.9813 Tj
-15 TJm
-(ersion) 24.3486 Tj
--349 TJm
-(of) 8.29885 Tj
--348 TJm
-(itself,) 22.4159 Tj
--373 TJm
-(with) 17.7135 Tj
--349 TJm
-(the) 12.1743 Tj
--349 TJm
-(name) 21.579 Tj
-[1 0 0 1 204.444 603.311] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -204.444 -603.311] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-204.444 603.311 Td
-/F134_0 9.9626 Tf
-(original_name.bz2) 101.619 Tj
-[1 0 0 1 306.063 603.311] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -306.063 -603.311] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-306.063 603.311 Td
-/F130_0 9.9626 Tf
-(.) 2.49065 Tj
--1212 TJm
-(Each) 19.9152 Tj
--348 TJm
-(compressed) 47.0334 Tj
--349 TJm
-(\002le) 12.7322 Tj
--348 TJm
-(has) 13.2801 Tj
--349 TJm
-(the) 12.1743 Tj
--348 TJm
-(same) 20.4731 Tj
--349 TJm
-(modi\002cation) 50.3709 Tj
--349 TJm
-(date,) 19.0883 Tj
-72 591.356 Td
-(permissions,) 50.092 Tj
--344 TJm
-(and,) 16.8766 Tj
--344 TJm
-(when) 21.579 Tj
--325 TJm
-(possible,) 35.1481 Tj
--344 TJm
-(o) 4.9813 Tj
-25 TJm
-(wnership) 36.5229 Tj
--325 TJm
-(as) 8.29885 Tj
--325 TJm
-(the) 12.1743 Tj
--326 TJm
-(corresponding) 56.996 Tj
--325 TJm
-(original,) 33.4843 Tj
--344 TJm
-(so) 8.85675 Tj
--325 TJm
-(that) 14.9439 Tj
--325 TJm
-(these) 20.4731 Tj
--325 TJm
-(properties) 39.8404 Tj
--325 TJm
-(can) 13.8281 Tj
--326 TJm
-(be) 9.40469 Tj
--325 TJm
-(correctly) 35.4071 Tj
-72 579.4 Td
-(restored) 32.0895 Tj
--308 TJm
-(at) 7.193 Tj
--308 TJm
-(decompression) 59.7656 Tj
--307 TJm
-(time.) 20.2042 Tj
--484 TJm
-(File) 15.5018 Tj
--308 TJm
-(name) 21.579 Tj
--308 TJm
-(handling) 34.8691 Tj
--308 TJm
-(is) 6.64505 Tj
--307 TJm
-(nai) 12.1743 Tj
-25 TJm
-(v) 4.9813 Tj
-15 TJm
-(e) 4.42339 Tj
--308 TJm
-(in) 7.7509 Tj
--308 TJm
-(the) 12.1743 Tj
--308 TJm
-(sense) 21.579 Tj
--308 TJm
-(that) 14.9439 Tj
--308 TJm
-(there) 19.9152 Tj
--307 TJm
-(is) 6.64505 Tj
--308 TJm
-(no) 9.9626 Tj
--308 TJm
-(mechanism) 45.3796 Tj
--308 TJm
-(for) 11.6164 Tj
--308 TJm
-(preserving) 42.0521 Tj
-72 567.445 Td
-(original) 30.9936 Tj
--334 TJm
-(\002le) 12.7322 Tj
--333 TJm
-(names,) 27.9451 Tj
--355 TJm
-(permissions,) 50.092 Tj
--355 TJm
-(o) 4.9813 Tj
-25 TJm
-(wnerships) 40.3983 Tj
--333 TJm
-(or) 8.29885 Tj
--334 TJm
-(dates) 20.4731 Tj
--334 TJm
-(in) 7.7509 Tj
--333 TJm
-(\002lesystems) 44.2838 Tj
--334 TJm
-(which) 24.3486 Tj
--334 TJm
-(lack) 16.5977 Tj
--333 TJm
-(these) 20.4731 Tj
--334 TJm
-(concepts,) 37.3498 Tj
--355 TJm
-(or) 8.29885 Tj
--333 TJm
-(ha) 9.40469 Tj
-20 TJm
-(v) 4.9813 Tj
-15 TJm
-(e) 4.42339 Tj
--334 TJm
-(serious) 28.224 Tj
--334 TJm
-(\002le) 12.7322 Tj
-72 555.49 Td
-(name) 21.579 Tj
--250 TJm
-(length) 24.9065 Tj
--250 TJm
-(restrictions,) 46.7644 Tj
--250 TJm
-(such) 18.2614 Tj
--250 TJm
-(as) 8.29885 Tj
--250 TJm
-(MS-DOS.) 40.1294 Tj
-[1 0 0 1 72 553.333] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.9626] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -543.371] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 533.572 Td
-/F134_0 9.9626 Tf
-(bzip2) 29.8878 Tj
-[1 0 0 1 101.888 533.572] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -101.888 -533.572] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-104.379 533.572 Td
-/F130_0 9.9626 Tf
-(and) 14.386 Tj
-[1 0 0 1 121.255 533.572] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -121.255 -533.572] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-121.255 533.572 Td
-/F134_0 9.9626 Tf
-(bunzip2) 41.8429 Tj
-[1 0 0 1 163.098 533.572] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -163.098 -533.572] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-165.589 533.572 Td
-/F130_0 9.9626 Tf
-(will) 15.5018 Tj
--250 TJm
-(by) 9.9626 Tj
--250 TJm
-(def) 12.7222 Tj
-10 TJm
-(ault) 14.9439 Tj
--250 TJm
-(not) 12.7322 Tj
--250 TJm
-(o) 4.9813 Tj
-15 TJm
-(v) 4.9813 Tj
-15 TJm
-(erwrite) 28.2141 Tj
--250 TJm
-(e) 4.42339 Tj
-15 TJm
-(xisting) 27.1282 Tj
--250 TJm
-(\002les.) 19.0983 Tj
--620 TJm
-(If) 6.63509 Tj
--250 TJm
-(you) 14.9439 Tj
--250 TJm
-(w) 7.193 Tj
-10 TJm
-(ant) 12.1743 Tj
--250 TJm
-(this) 14.396 Tj
--250 TJm
-(to) 7.7509 Tj
--250 TJm
-(happen,) 31.2626 Tj
--250 TJm
-(specify) 28.772 Tj
--250 TJm
-(the) 12.1743 Tj
-[1 0 0 1 495.977 533.572] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -495.977 -533.572] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-495.977 533.572 Td
-/F134_0 9.9626 Tf
-(-f) 11.9551 Tj
-[1 0 0 1 507.932 533.572] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -507.932 -533.572] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-510.423 533.572 Td
-/F130_0 9.9626 Tf
-(\003ag.) 17.4346 Tj
-[1 0 0 1 72 531.415] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.9627] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -521.453] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 511.654 Td
-/F130_0 9.9626 Tf
-(If) 6.63509 Tj
--284 TJm
-(no) 9.9626 Tj
--285 TJm
-(\002le) 12.7322 Tj
--284 TJm
-(names) 25.4544 Tj
--284 TJm
-(are) 12.1643 Tj
--284 TJm
-(speci\002ed,) 37.9077 Tj
-[1 0 0 1 193.935 511.654] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -193.935 -511.654] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-193.935 511.654 Td
-/F134_0 9.9626 Tf
-(bzip2) 29.8878 Tj
-[1 0 0 1 223.823 511.654] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -223.823 -511.654] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-226.655 511.654 Td
-/F130_0 9.9626 Tf
-(compresses) 45.9276 Tj
--284 TJm
-(from) 19.3673 Tj
--285 TJm
-(standard) 33.7533 Tj
--284 TJm
-(input) 20.4831 Tj
--284 TJm
-(to) 7.7509 Tj
--284 TJm
-(standard) 33.7533 Tj
--285 TJm
-(output.) 27.9551 Tj
--825 TJm
-(In) 8.29885 Tj
--285 TJm
-(this) 14.396 Tj
--284 TJm
-(case,) 19.6363 Tj
-[1 0 0 1 491.778 511.654] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -491.778 -511.654] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-491.778 511.654 Td
-/F134_0 9.9626 Tf
-(bzip2) 29.8878 Tj
-[1 0 0 1 521.666 511.654] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -521.666 -511.654] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-524.499 511.654 Td
-/F130_0 9.9626 Tf
-(will) 15.5018 Tj
-72 499.699 Td
-(decline) 28.772 Tj
--250 TJm
-(to) 7.7509 Tj
--250 TJm
-(write) 20.4731 Tj
--250 TJm
-(compressed) 47.0334 Tj
--250 TJm
-(output) 25.4644 Tj
--250 TJm
-(to) 7.7509 Tj
--250 TJm
-(a) 4.42339 Tj
--250 TJm
-(terminal,) 35.696 Tj
--250 TJm
-(as) 8.29885 Tj
--250 TJm
-(this) 14.396 Tj
--250 TJm
-(w) 7.193 Tj
-10 TJm
-(ould) 17.7135 Tj
--250 TJm
-(be) 9.40469 Tj
--250 TJm
-(entirely) 30.4357 Tj
--250 TJm
-(incomprehensible) 70.8341 Tj
--250 TJm
-(and) 14.386 Tj
--250 TJm
-(therefore) 35.955 Tj
--250 TJm
-(pointless.) 37.9177 Tj
-[1 0 0 1 72 497.542] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.9626] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -487.58] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 477.781 Td
-/F134_0 9.9626 Tf
-(bunzip2) 41.8429 Tj
-[1 0 0 1 113.843 477.781] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -113.843 -477.781] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-116.176 477.781 Td
-/F130_0 9.9626 Tf
-(\(or) 11.6164 Tj
-[1 0 0 1 130.125 477.781] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -130.125 -477.781] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-130.125 477.781 Td
-/F134_0 9.9626 Tf
-(bzip2) 29.8878 Tj
--600 TJm
-(-d) 11.9551 Tj
-[1 0 0 1 177.946 477.781] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -177.946 -477.781] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-177.946 477.781 Td
-/F130_0 9.9626 Tf
-(\)) 3.31755 Tj
--234 TJm
-(decompresses) 55.3323 Tj
--234 TJm
-(all) 9.9626 Tj
--234 TJm
-(speci\002ed) 35.417 Tj
--235 TJm
-(\002les.) 19.0983 Tj
--609 TJm
-(Files) 19.3773 Tj
--234 TJm
-(which) 24.3486 Tj
--234 TJm
-(were) 19.3573 Tj
--234 TJm
-(not) 12.7322 Tj
--235 TJm
-(created) 28.762 Tj
--234 TJm
-(by) 9.9626 Tj
-[1 0 0 1 445.012 477.781] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -445.012 -477.781] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-445.012 477.781 Td
-/F134_0 9.9626 Tf
-(bzip2) 29.8878 Tj
-[1 0 0 1 474.9 477.781] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -474.9 -477.781] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-477.233 477.781 Td
-/F130_0 9.9626 Tf
-(will) 15.5018 Tj
--234 TJm
-(be) 9.40469 Tj
--234 TJm
-(detected) 33.1954 Tj
-72 465.826 Td
-(and) 14.386 Tj
--280 TJm
-(i) 2.7696 Tj
-1 TJm
-(gnored,) 30.1568 Tj
--287 TJm
-(and) 14.386 Tj
--280 TJm
-(a) 4.42339 Tj
--279 TJm
-(w) 7.193 Tj
-10 TJm
-(arning) 25.4544 Tj
--280 TJm
-(issued.) 27.3972 Tj
-[1 0 0 1 216.033 465.826] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -216.033 -465.826] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-216.033 465.826 Td
-/F134_0 9.9626 Tf
-(bzip2) 29.8878 Tj
-[1 0 0 1 245.921 465.826] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -245.921 -465.826] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-248.705 465.826 Td
-/F130_0 9.9626 Tf
-(attempts) 33.7633 Tj
--279 TJm
-(to) 7.7509 Tj
--280 TJm
-(guess) 22.1369 Tj
--279 TJm
-(the) 12.1743 Tj
--280 TJm
-(\002lename) 34.3112 Tj
--279 TJm
-(for) 11.6164 Tj
--280 TJm
-(the) 12.1743 Tj
--279 TJm
-(decompressed) 56.4381 Tj
--280 TJm
-(\002le) 12.7322 Tj
--279 TJm
-(from) 19.3673 Tj
--280 TJm
-(that) 14.9439 Tj
--279 TJm
-(of) 8.29885 Tj
--280 TJm
-(the) 12.1743 Tj
-72 453.871 Td
-(compressed) 47.0334 Tj
--250 TJm
-(\002le) 12.7322 Tj
--250 TJm
-(as) 8.29885 Tj
--250 TJm
-(follo) 18.8194 Tj
-25 TJm
-(ws:) 13.8381 Tj
-[1 0 0 1 72 451.714] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -29.7236] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 6.9739 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -78.9739 -421.991] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-78.9739 421.991 Td
-/F130_0 9.9626 Tf
-(\225) 3.48691 Tj
-[1 0 0 1 82.4608 421.991] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 1.9925 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -86.944 -421.991] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-86.944 421.991 Td
-/F134_0 9.9626 Tf
-(filename.bz2) 71.7307 Tj
-[1 0 0 1 164.653 421.991] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -164.653 -421.991] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-167.143 421.991 Td
-/F130_0 9.9626 Tf
-(becomes) 34.8591 Tj
-[1 0 0 1 204.493 421.991] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -204.493 -421.991] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-204.493 421.991 Td
-/F134_0 9.9626 Tf
-(filename) 47.8205 Tj
-[1 0 0 1 252.313 421.991] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -180.313 -21.9178] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 6.9739 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -78.9739 -400.073] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-78.9739 400.073 Td
-/F130_0 9.9626 Tf
-(\225) 3.48691 Tj
-[1 0 0 1 82.4608 400.073] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 1.9925 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -86.944 -400.073] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-86.944 400.073 Td
-/F134_0 9.9626 Tf
-(filename.bz) 65.7532 Tj
-[1 0 0 1 158.675 400.073] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -158.675 -400.073] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-161.166 400.073 Td
-/F130_0 9.9626 Tf
-(becomes) 34.8591 Tj
-[1 0 0 1 198.515 400.073] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -198.515 -400.073] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-198.515 400.073 Td
-/F134_0 9.9626 Tf
-(filename) 47.8205 Tj
-[1 0 0 1 246.336 400.073] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -174.336 -21.9178] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 6.9739 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -78.9739 -378.155] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-78.9739 378.155 Td
-/F130_0 9.9626 Tf
-(\225) 3.48691 Tj
-[1 0 0 1 82.4608 378.155] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 1.9925 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -86.944 -378.155] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-86.944 378.155 Td
-/F134_0 9.9626 Tf
-(filename.tbz2) 77.7083 Tj
-[1 0 0 1 164.653 378.155] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -164.653 -378.155] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-167.143 378.155 Td
-/F130_0 9.9626 Tf
-(becomes) 34.8591 Tj
-[1 0 0 1 204.493 378.155] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -204.493 -378.155] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-204.493 378.155 Td
-/F134_0 9.9626 Tf
-(filename.tar) 71.7307 Tj
-[1 0 0 1 276.224 378.155] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -204.224 -21.9178] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 6.9739 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -78.9739 -356.237] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-78.9739 356.237 Td
-/F130_0 9.9626 Tf
-(\225) 3.48691 Tj
-[1 0 0 1 82.4608 356.237] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 1.9925 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -86.944 -356.237] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-86.944 356.237 Td
-/F134_0 9.9626 Tf
-(filename.tbz) 71.7307 Tj
-[1 0 0 1 164.653 356.237] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -164.653 -356.237] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-167.143 356.237 Td
-/F130_0 9.9626 Tf
-(becomes) 34.8591 Tj
-[1 0 0 1 204.493 356.237] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -204.493 -356.237] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-204.493 356.237 Td
-/F134_0 9.9626 Tf
-(filename.tar) 71.7307 Tj
-[1 0 0 1 276.224 356.237] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -204.224 -21.9178] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 6.9739 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -78.9739 -334.319] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-78.9739 334.319 Td
-/F130_0 9.9626 Tf
-(\225) 3.48691 Tj
-[1 0 0 1 82.4608 334.319] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 1.9925 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -86.944 -334.319] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-86.944 334.319 Td
-/F134_0 9.9626 Tf
-(anyothername) 71.7307 Tj
-[1 0 0 1 164.653 334.319] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -164.653 -334.319] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-167.143 334.319 Td
-/F130_0 9.9626 Tf
-(becomes) 34.8591 Tj
-[1 0 0 1 204.493 334.319] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -204.493 -334.319] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-204.493 334.319 Td
-/F134_0 9.9626 Tf
-(anyothername.out) 95.641 Tj
-[1 0 0 1 300.134 334.319] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -228.134 -11.4968] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -322.823] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 312.402 Td
-/F130_0 9.9626 Tf
-(If) 6.63509 Tj
--342 TJm
-(the) 12.1743 Tj
--342 TJm
-(\002le) 12.7322 Tj
--342 TJm
-(does) 18.2614 Tj
--342 TJm
-(not) 12.7322 Tj
--343 TJm
-(end) 14.386 Tj
--342 TJm
-(in) 7.7509 Tj
--342 TJm
-(one) 14.386 Tj
--342 TJm
-(of) 8.29885 Tj
--342 TJm
-(the) 12.1743 Tj
--342 TJm
-(recognised) 43.158 Tj
--342 TJm
-(endings,) 33.4843 Tj
-[1 0 0 1 309.305 312.402] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -309.305 -312.402] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-309.305 312.402 Td
-/F134_0 9.9626 Tf
-(.bz2) 23.9102 Tj
-[1 0 0 1 333.215 312.402] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -333.215 -312.402] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-333.215 312.402 Td
-/F130_0 9.9626 Tf
-(,) 2.49065 Tj
-[1 0 0 1 339.344 312.402] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -339.344 -312.402] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-339.344 312.402 Td
-/F134_0 9.9626 Tf
-(.bz) 17.9327 Tj
-[1 0 0 1 357.276 312.402] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -357.276 -312.402] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-357.276 312.402 Td
-/F130_0 9.9626 Tf
-(,) 2.49065 Tj
-[1 0 0 1 363.405 312.402] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -363.405 -312.402] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-363.405 312.402 Td
-/F134_0 9.9626 Tf
-(.tbz2) 29.8878 Tj
-[1 0 0 1 393.293 312.402] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -393.293 -312.402] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-396.701 312.402 Td
-/F130_0 9.9626 Tf
-(or) 8.29885 Tj
-[1 0 0 1 408.409 312.402] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -408.409 -312.402] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-408.409 312.402 Td
-/F134_0 9.9626 Tf
-(.tbz) 23.9102 Tj
-[1 0 0 1 432.319 312.402] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -432.319 -312.402] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-432.319 312.402 Td
-/F130_0 9.9626 Tf
-(,) 2.49065 Tj
-[1 0 0 1 438.448 312.402] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -438.448 -312.402] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-438.448 312.402 Td
-/F134_0 9.9626 Tf
-(bzip2) 29.8878 Tj
-[1 0 0 1 468.336 312.402] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -468.336 -312.402] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-471.744 312.402 Td
-/F130_0 9.9626 Tf
-(complains) 40.9562 Tj
--342 TJm
-(that) 14.9439 Tj
--342 TJm
-(it) 5.53921 Tj
-72 300.446 Td
-(cannot) 26.5603 Tj
--250 TJm
-(guess) 22.1369 Tj
--250 TJm
-(the) 12.1743 Tj
--250 TJm
-(name) 21.579 Tj
--250 TJm
-(of) 8.29885 Tj
--250 TJm
-(the) 12.1743 Tj
--250 TJm
-(original) 30.9936 Tj
--250 TJm
-(\002le,) 15.2229 Tj
--250 TJm
-(and) 14.386 Tj
--250 TJm
-(uses) 17.1556 Tj
--250 TJm
-(the) 12.1743 Tj
--250 TJm
-(original) 30.9936 Tj
--250 TJm
-(name) 21.579 Tj
--250 TJm
-(with) 17.7135 Tj
-[1 0 0 1 370.009 300.446] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -370.009 -300.446] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-370.009 300.446 Td
-/F134_0 9.9626 Tf
-(.out) 23.9102 Tj
-[1 0 0 1 393.92 300.446] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -393.92 -300.446] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-396.41 300.446 Td
-/F130_0 9.9626 Tf
-(appended.) 40.6673 Tj
-[1 0 0 1 72 298.29] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.9626] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -288.327] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 278.529 Td
-/F130_0 9.9626 Tf
-(As) 11.0684 Tj
--250 TJm
-(with) 17.7135 Tj
--250 TJm
-(compression,) 52.8516 Tj
--250 TJm
-(supplying) 39.3025 Tj
--250 TJm
-(no) 9.9626 Tj
--250 TJm
-(\002lenames) 38.1866 Tj
--250 TJm
-(causes) 26.0024 Tj
--250 TJm
-(decompression) 59.7656 Tj
--250 TJm
-(from) 19.3673 Tj
--250 TJm
-(standard) 33.7533 Tj
--250 TJm
-(input) 20.4831 Tj
--250 TJm
-(to) 7.7509 Tj
--250 TJm
-(standard) 33.7533 Tj
--250 TJm
-(output.) 27.9551 Tj
-[1 0 0 1 72 276.372] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.9626] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -266.409] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 256.611 Td
-/F134_0 9.9626 Tf
-(bunzip2) 41.8429 Tj
-[1 0 0 1 113.843 256.611] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -113.843 -256.611] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-116.409 256.611 Td
-/F130_0 9.9626 Tf
-(will) 15.5018 Tj
--257 TJm
-(correctly) 35.4071 Tj
--258 TJm
-(decompress) 47.0334 Tj
--257 TJm
-(a) 4.42339 Tj
--258 TJm
-(\002le) 12.7322 Tj
--257 TJm
-(which) 24.3486 Tj
--258 TJm
-(is) 6.64505 Tj
--258 TJm
-(the) 12.1743 Tj
--257 TJm
-(concatenation) 55.3323 Tj
--258 TJm
-(of) 8.29885 Tj
--257 TJm
-(tw) 9.9626 Tj
-10 TJm
-(o) 4.9813 Tj
--258 TJm
-(or) 8.29885 Tj
--257 TJm
-(more) 20.4731 Tj
--258 TJm
-(compressed) 47.0334 Tj
--257 TJm
-(\002les.) 19.0983 Tj
--665 TJm
-(The) 15.4918 Tj
--258 TJm
-(result) 22.1369 Tj
--257 TJm
-(is) 6.64505 Tj
-72 244.656 Td
-(the) 12.1743 Tj
--239 TJm
-(concatenation) 55.3323 Tj
--238 TJm
-(of) 8.29885 Tj
--239 TJm
-(the) 12.1743 Tj
--239 TJm
-(corresponding) 56.996 Tj
--239 TJm
-(uncompressed) 56.996 Tj
--238 TJm
-(\002les.) 19.0983 Tj
--613 TJm
-(Inte) 15.4918 Tj
-15 TJm
-(grity) 18.8194 Tj
--238 TJm
-(testing) 26.5703 Tj
--239 TJm
-(\() 3.31755 Tj
-[1 0 0 1 382.247 244.656] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -382.247 -244.656] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-382.247 244.656 Td
-/F134_0 9.9626 Tf
-(-t) 11.9551 Tj
-[1 0 0 1 394.202 244.656] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -394.202 -244.656] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-394.202 244.656 Td
-/F130_0 9.9626 Tf
-(\)) 3.31755 Tj
--239 TJm
-(of) 8.29885 Tj
--238 TJm
-(concatenated) 52.0048 Tj
--239 TJm
-(compressed) 47.0334 Tj
--239 TJm
-(\002les) 16.6077 Tj
--239 TJm
-(is) 6.64505 Tj
-72 232.7 Td
-(also) 16.0497 Tj
--250 TJm
-(supported.) 41.7831 Tj
-[1 0 0 1 72 230.544] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.9626] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -220.581] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 210.783 Td
-/F130_0 9.9626 Tf
-(Y) 7.193 Tj
-110 TJm
-(ou) 9.9626 Tj
--399 TJm
-(can) 13.8281 Tj
--399 TJm
-(also) 16.0497 Tj
--399 TJm
-(compress) 37.6287 Tj
--400 TJm
-(or) 8.29885 Tj
--399 TJm
-(decompress) 47.0334 Tj
--399 TJm
-(\002les) 16.6077 Tj
--399 TJm
-(to) 7.7509 Tj
--399 TJm
-(the) 12.1743 Tj
--399 TJm
-(standard) 33.7533 Tj
--399 TJm
-(output) 25.4644 Tj
--399 TJm
-(by) 9.9626 Tj
--400 TJm
-(gi) 7.7509 Tj
-25 TJm
-(ving) 17.7135 Tj
--399 TJm
-(the) 12.1743 Tj
-[1 0 0 1 409.67 210.783] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -409.67 -210.783] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-409.67 210.783 Td
-/F134_0 9.9626 Tf
-(-c) 11.9551 Tj
-[1 0 0 1 421.625 210.783] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -421.625 -210.783] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-425.602 210.783 Td
-/F130_0 9.9626 Tf
-(\003ag.) 17.4346 Tj
--757 TJm
-(Multiple) 34.3212 Tj
--400 TJm
-(\002l) 8.30881 Tj
-1 TJm
-(es) 8.29885 Tj
--400 TJm
-(may) 17.1556 Tj
--399 TJm
-(be) 9.40469 Tj
-72 198.828 Td
-(compressed) 47.0334 Tj
--367 TJm
-(and) 14.386 Tj
--367 TJm
-(decompressed) 56.4381 Tj
--367 TJm
-(lik) 10.5205 Tj
-10 TJm
-(e) 4.42339 Tj
--367 TJm
-(this.) 16.8866 Tj
--1321 TJm
-(The) 15.4918 Tj
--367 TJm
-(resulting) 34.8691 Tj
--367 TJm
-(outputs) 29.3399 Tj
--367 TJm
-(are) 12.1643 Tj
--367 TJm
-(fed) 12.7222 Tj
--367 TJm
-(sequentially) 48.1492 Tj
--366 TJm
-(to) 7.7509 Tj
--367 TJm
-(stdout.) 26.8492 Tj
--1322 TJm
-(Compression) 52.5826 Tj
--367 TJm
-(of) 8.29885 Tj
-72 186.872 Td
-(multiple) 33.2153 Tj
--289 TJm
-(\002les) 16.6077 Tj
--289 TJm
-(in) 7.7509 Tj
--289 TJm
-(this) 14.396 Tj
--289 TJm
-(manner) 29.8778 Tj
--288 TJm
-(generates) 37.6188 Tj
--289 TJm
-(a) 4.42339 Tj
--289 TJm
-(stream) 26.5603 Tj
--289 TJm
-(containing) 42.0621 Tj
--289 TJm
-(multiple) 33.2153 Tj
--289 TJm
-(compressed) 47.0334 Tj
--289 TJm
-(\002le) 12.7322 Tj
--289 TJm
-(representations.) 62.8042 Tj
--853 TJm
-(Such) 19.9252 Tj
--289 TJm
-(a) 4.42339 Tj
--289 TJm
-(stream) 26.5603 Tj
-72 174.917 Td
-(can) 13.8281 Tj
--391 TJm
-(be) 9.40469 Tj
--391 TJm
-(decompressed) 56.4381 Tj
--390 TJm
-(correctly) 35.4071 Tj
--391 TJm
-(only) 17.7135 Tj
--391 TJm
-(by) 9.9626 Tj
-[1 0 0 1 238.116 174.917] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -238.116 -174.917] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-238.116 174.917 Td
-/F134_0 9.9626 Tf
-(bzip2) 29.8878 Tj
-[1 0 0 1 268.004 174.917] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -268.004 -174.917] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-271.897 174.917 Td
-/F130_0 9.9626 Tf
-(v) 4.9813 Tj
-15 TJm
-(ersion) 24.3486 Tj
--391 TJm
-(0.9.0) 19.9252 Tj
--391 TJm
-(or) 8.29885 Tj
--391 TJm
-(l) 2.7696 Tj
-1 TJm
-(ater) 14.9339 Tj
-55 TJm
-(.) 2.49065 Tj
--733 TJm
-(Earlier) 27.1082 Tj
--391 TJm
-(v) 4.9813 Tj
-15 TJm
-(ersions) 28.224 Tj
--391 TJm
-(of) 8.29885 Tj
-[1 0 0 1 448.071 174.917] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -448.071 -174.917] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-448.071 174.917 Td
-/F134_0 9.9626 Tf
-(bzip2) 29.8878 Tj
-[1 0 0 1 477.958 174.917] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -477.958 -174.917] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-481.852 174.917 Td
-/F130_0 9.9626 Tf
-(will) 15.5018 Tj
--391 TJm
-(stop) 16.6077 Tj
--391 TJm
-(after) 18.2515 Tj
-72 162.962 Td
-(decompressing) 59.7656 Tj
--250 TJm
-(the) 12.1743 Tj
--250 TJm
-(\002rst) 15.5018 Tj
--250 TJm
-(\002le) 12.7322 Tj
--250 TJm
-(in) 7.7509 Tj
--250 TJm
-(the) 12.1743 Tj
--250 TJm
-(stream.) 29.0509 Tj
-[1 0 0 1 72 160.805] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.9627] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -150.843] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 141.044 Td
-/F134_0 9.9626 Tf
-(bzcat) 29.8878 Tj
-[1 0 0 1 101.888 141.044] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -101.888 -141.044] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-104.379 141.044 Td
-/F130_0 9.9626 Tf
-(\(or) 11.6164 Tj
-[1 0 0 1 118.486 141.044] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -118.486 -141.044] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-118.486 141.044 Td
-/F134_0 9.9626 Tf
-(bzip2) 29.8878 Tj
--600 TJm
-(-dc) 17.9327 Tj
-[1 0 0 1 172.284 141.044] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -172.284 -141.044] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-172.284 141.044 Td
-/F130_0 9.9626 Tf
-(\)) 3.31755 Tj
--250 TJm
-(decompresses) 55.3323 Tj
--250 TJm
-(all) 9.9626 Tj
--250 TJm
-(speci\002ed) 35.417 Tj
--250 TJm
-(\002les) 16.6077 Tj
--250 TJm
-(to) 7.7509 Tj
--250 TJm
-(the) 12.1743 Tj
--250 TJm
-(standard) 33.7533 Tj
--250 TJm
-(output.) 27.9551 Tj
-[1 0 0 1 72 138.887] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.9627] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -128.925] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 119.126 Td
-/F134_0 9.9626 Tf
-(bzip2) 29.8878 Tj
-[1 0 0 1 101.888 119.126] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -101.888 -119.126] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-104.866 119.126 Td
-/F130_0 9.9626 Tf
-(will) 15.5018 Tj
--299 TJm
-(read) 17.1456 Tj
--299 TJm
-(ar) 7.74094 Tj
-18 TJm
-(guments) 33.7633 Tj
--299 TJm
-(from) 19.3673 Tj
--299 TJm
-(the) 12.1743 Tj
--299 TJm
-(en) 9.40469 Tj
-40 TJm
-(vironment) 40.9562 Tj
--298 TJm
-(v) 4.9813 Tj
-25 TJm
-(ariables) 30.9837 Tj
-[1 0 0 1 316.903 119.126] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -316.903 -119.126] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-316.903 119.126 Td
-/F134_0 9.9626 Tf
-(BZIP2) 29.8878 Tj
-[1 0 0 1 346.791 119.126] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -346.791 -119.126] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-349.769 119.126 Td
-/F130_0 9.9626 Tf
-(and) 14.386 Tj
-[1 0 0 1 367.133 119.126] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -367.133 -119.126] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-367.133 119.126 Td
-/F134_0 9.9626 Tf
-(BZIP) 23.9102 Tj
-[1 0 0 1 391.043 119.126] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -391.043 -119.126] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-391.043 119.126 Td
-/F130_0 9.9626 Tf
-(,) 2.49065 Tj
--299 TJm
-(in) 7.7509 Tj
--299 TJm
-(that) 14.9439 Tj
--299 TJm
-(order) 21.0211 Tj
-40 TJm
-(,) 2.49065 Tj
--311 TJm
-(and) 14.386 Tj
--299 TJm
-(will) 15.5018 Tj
--299 TJm
-(process) 29.8778 Tj
--299 TJm
-(them) 19.9252 Tj
-72 107.171 Td
-(before) 25.4445 Tj
--250 TJm
-(an) 9.40469 Tj
-15 TJm
-(y) 4.9813 Tj
--250 TJm
-(ar) 7.74094 Tj
-18 TJm
-(guments) 33.7633 Tj
--250 TJm
-(read) 17.1456 Tj
--250 TJm
-(from) 19.3673 Tj
--250 TJm
-(the) 12.1743 Tj
--250 TJm
-(command) 39.2925 Tj
--250 TJm
-(line.) 17.4346 Tj
--310 TJm
-(This) 17.7135 Tj
--250 TJm
-(gi) 7.7509 Tj
-25 TJm
-(v) 4.9813 Tj
-15 TJm
-(es) 8.29885 Tj
--250 TJm
-(a) 4.42339 Tj
--250 TJm
-(con) 14.386 Tj
-40 TJm
-(v) 4.9813 Tj
-15 TJm
-(enient) 24.3486 Tj
--250 TJm
-(w) 7.193 Tj
-10 TJm
-(ay) 9.40469 Tj
--250 TJm
-(to) 7.7509 Tj
--250 TJm
-(supply) 26.5703 Tj
--250 TJm
-(def) 12.7222 Tj
-10 TJm
-(ault) 14.9439 Tj
--250 TJm
-(ar) 7.74094 Tj
-18 TJm
-(guments.) 36.2539 Tj
-[1 0 0 1 72 105.014] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.9627] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -95.0517] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 85.2534 Td
-/F130_0 9.9626 Tf
-(Compression) 52.5826 Tj
--294 TJm
-(is) 6.64505 Tj
--294 TJm
-(al) 7.193 Tj
-10 TJm
-(w) 7.193 Tj
-10 TJm
-(ays) 13.2801 Tj
--294 TJm
-(performed,) 43.9849 Tj
--305 TJm
-(e) 4.42339 Tj
-25 TJm
-(v) 4.9813 Tj
-15 TJm
-(en) 9.40469 Tj
--294 TJm
-(if) 6.08715 Tj
--294 TJm
-(the) 12.1743 Tj
--294 TJm
-(compressed) 47.0334 Tj
--294 TJm
-(\002le) 12.7322 Tj
--293 TJm
-(is) 6.64505 Tj
--294 TJm
-(slightly) 29.8978 Tj
--294 TJm
-(lar) 10.5105 Tj
-18 TJm
-(ger) 12.7222 Tj
--294 TJm
-(than) 17.1556 Tj
--294 TJm
-(the) 12.1743 Tj
--294 TJm
-(original.) 33.4843 Tj
--884 TJm
-(Files) 19.3773 Tj
--294 TJm
-(of) 8.29885 Tj
--294 TJm
-(less) 14.9439 Tj
--294 TJm
-(than) 17.1556 Tj
-72 73.2982 Td
-(about) 22.1369 Tj
--246 TJm
-(one) 14.386 Tj
--246 TJm
-(hundred) 32.6474 Tj
--245 TJm
-(bytes) 21.031 Tj
--246 TJm
-(tend) 17.1556 Tj
--246 TJm
-(to) 7.7509 Tj
--246 TJm
-(get) 12.1743 Tj
--246 TJm
-(l) 2.7696 Tj
-1 TJm
-(ar) 7.74094 Tj
-18 TJm
-(ger) 12.7222 Tj
-40 TJm
-(,) 2.49065 Tj
--247 TJm
-(since) 20.4731 Tj
--246 TJm
-(the) 12.1743 Tj
--246 TJm
-(compression) 50.3609 Tj
--245 TJm
-(mechanism) 45.3796 Tj
--246 TJm
-(has) 13.2801 Tj
--246 TJm
-(a) 4.42339 Tj
--246 TJm
-(constant) 33.2053 Tj
--246 TJm
-(o) 4.9813 Tj
-15 TJm
-(v) 4.9813 Tj
-15 TJm
-(erhead) 26.5503 Tj
--245 TJm
-(in) 7.7509 Tj
--246 TJm
-(the) 12.1743 Tj
--246 TJm
-(re) 7.74094 Tj
-15 TJm
-(gion) 17.7135 Tj
--246 TJm
-(of) 8.29885 Tj
-[1 0 0 1 72 50.8518] cm
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-[1 0 0 1 1.8929 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 374.394 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 6.8541] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 43.0633 -6.7545] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -496.332 -50.9514] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-539.395 50.9514 Td
-/F130_0 9.9626 Tf
-(3) 4.9813 Tj
-[1 0 0 1 453.269 50.8518] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 93.5985 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 6.2765 0] cm
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-[1 0 0 1 -13.1436 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-Q
-showpage
-%%PageTrailer
-pdfEndPage
-%%Page: 7 7
-%%BeginPageSetup
-%%PageOrientation: Portrait
-pdfStartPage
-0 0 612 792 re W
-%%EndPageSetup
-[] 0 d
-1 i
-0 j
-0 J
-10 M
-1 w
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-false op
-false OP
-0 0 612 792 re
-W
-q
-[1 0 0 1 72 741.554] cm
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-[1 0 0 1 1.8929 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 14.4459] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 187.197 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 -8.9114] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 8.9114] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 105.519 -6.7546] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -371.59 -749.245] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-477.109 749.245 Td
-/F130_0 9.9626 Tf
-(Ho) 12.1743 Tj
-25 TJm
-(w) 7.193 Tj
--250 TJm
-(to) 7.7509 Tj
--250 TJm
-(use) 13.2801 Tj
--250 TJm
-(bzip2) 22.1369 Tj
-[1 0 0 1 266.071 747.089] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 280.796 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -472.974 -5.0363] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -0.4981] cm
-q
-[] 0 d
-0 J
-0.4981 w
-0 0.2491 m
-475.465 0.2491 l
-S
-Q
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 479.251 0] cm
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-[1 0 0 1 -13.1436 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -540 -741.554] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 710.037 Td
-/F130_0 9.9626 Tf
-(50) 9.9626 Tj
--264 TJm
-(bytes.) 23.5217 Tj
--351 TJm
-(Random) 33.7633 Tj
--264 TJm
-(dat) 12.1743 Tj
-1 TJm
-(a) 4.42339 Tj
--264 TJm
-(\(including) 40.9562 Tj
--264 TJm
-(the) 12.1743 Tj
--264 TJm
-(output) 25.4644 Tj
--263 TJm
-(of) 8.29885 Tj
--264 TJm
-(most) 19.3773 Tj
--264 TJm
-(\002le) 12.7322 Tj
--263 TJm
-(compressors\)) 53.1206 Tj
--264 TJm
-(is) 6.64505 Tj
--264 TJm
-(coded) 23.7907 Tj
--263 TJm
-(at) 7.193 Tj
--264 TJm
-(about) 22.1369 Tj
--264 TJm
-(8.05) 17.4346 Tj
--263 TJm
-(bits) 14.396 Tj
--264 TJm
-(per) 12.7222 Tj
--264 TJm
-(byte,) 19.6462 Tj
--267 TJm
-(gi) 7.7509 Tj
-25 TJm
-(ving) 17.7135 Tj
--264 TJm
-(an) 9.40469 Tj
-72 698.082 Td
-(e) 4.42339 Tj
-15 TJm
-(xpansion) 35.9749 Tj
--250 TJm
-(of) 8.29885 Tj
--250 TJm
-(around) 27.6661 Tj
--250 TJm
-(0.5%.) 23.2427 Tj
-[1 0 0 1 72 695.925] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.8441] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -686.081] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 676.283 Td
-/F130_0 9.9626 Tf
-(As) 11.0684 Tj
--268 TJm
-(a) 4.42339 Tj
--268 TJm
-(self-check) 40.9363 Tj
--269 TJm
-(for) 11.6164 Tj
--268 TJm
-(your) 18.2614 Tj
--268 TJm
-(protection,) 42.889 Tj
-[1 0 0 1 217.273 676.283] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -217.273 -676.283] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-217.273 676.283 Td
-/F134_0 9.9626 Tf
-(bzip2) 29.8878 Tj
-[1 0 0 1 247.161 676.283] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -247.161 -676.283] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-249.833 676.283 Td
-/F130_0 9.9626 Tf
-(uses) 17.1556 Tj
--268 TJm
-(32-bit) 23.8007 Tj
--268 TJm
-(CRCs) 23.8106 Tj
--269 TJm
-(to) 7.7509 Tj
--268 TJm
-(mak) 17.1556 Tj
-10 TJm
-(e) 4.42339 Tj
--268 TJm
-(sure) 16.5977 Tj
--268 TJm
-(that) 14.9439 Tj
--268 TJm
-(the) 12.1743 Tj
--269 TJm
-(decompressed) 56.4381 Tj
--268 TJm
-(v) 4.9813 Tj
-15 TJm
-(ersion) 24.3486 Tj
--268 TJm
-(of) 8.29885 Tj
--268 TJm
-(a) 4.42339 Tj
--268 TJm
-(\002le) 12.7322 Tj
--269 TJm
-(is) 6.64505 Tj
-72 664.328 Td
-(identical) 34.3112 Tj
--200 TJm
-(to) 7.7509 Tj
--199 TJm
-(the) 12.1743 Tj
--200 TJm
-(original.) 33.4843 Tj
--586 TJm
-(This) 17.7135 Tj
--200 TJm
-(guards) 26.5603 Tj
--199 TJm
-(ag) 9.40469 Tj
-5 TJm
-(ainst) 18.8194 Tj
--200 TJm
-(corruption) 41.5042 Tj
--199 TJm
-(of) 8.29885 Tj
--200 TJm
-(the) 12.1743 Tj
--200 TJm
-(compressed) 47.0334 Tj
--199 TJm
-(data,) 19.0883 Tj
--210 TJm
-(and) 14.386 Tj
--199 TJm
-(ag) 9.40469 Tj
-5 TJm
-(ainst) 18.8194 Tj
--200 TJm
-(undetected) 43.158 Tj
--200 TJm
-(b) 4.9813 Tj
-20 TJm
-(ugs) 13.8381 Tj
--199 TJm
-(in) 7.7509 Tj
-[1 0 0 1 510.112 664.328] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -510.112 -664.328] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-510.112 664.328 Td
-/F134_0 9.9626 Tf
-(bzip2) 29.8878 Tj
-[1 0 0 1 540 664.328] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -540 -664.328] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 652.373 Td
-/F130_0 9.9626 Tf
-(\(hopefully) 41.5042 Tj
--275 TJm
-(v) 4.9813 Tj
-15 TJm
-(ery) 12.7222 Tj
--274 TJm
-(unlik) 20.4831 Tj
-10 TJm
-(ely\).) 17.9825 Tj
--384 TJm
-(The) 15.4918 Tj
--275 TJm
-(chances) 31.5316 Tj
--275 TJm
-(of) 8.29885 Tj
--275 TJm
-(data) 16.5977 Tj
--274 TJm
-(corruption) 41.5042 Tj
--275 TJm
-(going) 22.6948 Tj
--275 TJm
-(undetected) 43.158 Tj
--274 TJm
-(is) 6.64505 Tj
--275 TJm
-(microscopic,) 51.1878 Tj
--281 TJm
-(about) 22.1369 Tj
--275 TJm
-(one) 14.386 Tj
--274 TJm
-(chance) 27.6562 Tj
--275 TJm
-(in) 7.7509 Tj
--275 TJm
-(four) 16.5977 Tj
-72 640.417 Td
-(billion) 26.0223 Tj
--279 TJm
-(for) 11.6164 Tj
--279 TJm
-(each) 18.2515 Tj
--279 TJm
-(\002le) 12.7322 Tj
--280 TJm
-(processed.) 41.7732 Tj
--795 TJm
-(Be) 11.0684 Tj
--279 TJm
-(a) 4.42339 Tj
-15 TJm
-(w) 7.193 Tj
-10 TJm
-(are,) 14.655 Tj
--286 TJm
-(though,) 30.1668 Tj
--287 TJm
-(that) 14.9439 Tj
--279 TJm
-(the) 12.1743 Tj
--279 TJm
-(check) 23.2328 Tj
--279 TJm
-(occurs) 26.0024 Tj
--279 TJm
-(upon) 19.9252 Tj
--279 TJm
-(decompression,) 62.2563 Tj
--287 TJm
-(so) 8.85675 Tj
--279 TJm
-(it) 5.53921 Tj
--279 TJm
-(can) 13.8281 Tj
--279 TJm
-(only) 17.7135 Tj
--280 TJm
-(tell) 12.7322 Tj
--279 TJm
-(you) 14.9439 Tj
-72 628.462 Td
-(that) 14.9439 Tj
--237 TJm
-(something) 41.5142 Tj
--236 TJm
-(is) 6.64505 Tj
--237 TJm
-(wrong.) 27.9451 Tj
--611 TJm
-(It) 6.08715 Tj
--237 TJm
-(can') 17.1456 Tj
-18 TJm
-(t) 2.7696 Tj
--237 TJm
-(help) 17.1556 Tj
--237 TJm
-(you) 14.9439 Tj
--236 TJm
-(reco) 17.1456 Tj
-15 TJm
-(v) 4.9813 Tj
-15 TJm
-(er) 7.74094 Tj
--237 TJm
-(the) 12.1743 Tj
--237 TJm
-(original) 30.9936 Tj
--237 TJm
-(uncompressed) 56.996 Tj
--236 TJm
-(data.) 19.0883 Tj
--612 TJm
-(Y) 7.193 Tj
-110 TJm
-(ou) 9.9626 Tj
--236 TJm
-(can) 13.8281 Tj
--237 TJm
-(use) 13.2801 Tj
-[1 0 0 1 458.159 628.462] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -458.159 -628.462] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-458.159 628.462 Td
-/F134_0 9.9626 Tf
-(bzip2recover) 71.7307 Tj
-[1 0 0 1 529.89 628.462] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -529.89 -628.462] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-532.249 628.462 Td
-/F130_0 9.9626 Tf
-(to) 7.7509 Tj
-72 616.507 Td
-(try) 11.0684 Tj
--250 TJm
-(to) 7.7509 Tj
--250 TJm
-(reco) 17.1456 Tj
-15 TJm
-(v) 4.9813 Tj
-15 TJm
-(er) 7.74094 Tj
--250 TJm
-(data) 16.5977 Tj
--250 TJm
-(from) 19.3673 Tj
--250 TJm
-(damaged) 35.965 Tj
--250 TJm
-(\002les.) 19.0983 Tj
-[1 0 0 1 72 614.35] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.8441] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -604.506] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 594.708 Td
-/F130_0 9.9626 Tf
-(Return) 27.1182 Tj
--298 TJm
-(v) 4.9813 Tj
-25 TJm
-(alues:) 23.2427 Tj
--406 TJm
-(0) 4.9813 Tj
--298 TJm
-(for) 11.6164 Tj
--298 TJm
-(a) 4.42339 Tj
--298 TJm
-(normal) 28.224 Tj
--298 TJm
-(e) 4.42339 Tj
-15 TJm
-(xit,) 13.0112 Tj
--310 TJm
-(1) 4.9813 Tj
--298 TJm
-(for) 11.6164 Tj
--297 TJm
-(en) 9.40469 Tj
-40 TJm
-(vironmental) 48.1492 Tj
--298 TJm
-(problems) 37.0808 Tj
--298 TJm
-(\(\002le) 16.0497 Tj
--298 TJm
-(not) 12.7322 Tj
--298 TJm
-(found,) 25.7334 Tj
--310 TJm
-(in) 7.7509 Tj
-40 TJm
-(v) 4.9813 Tj
-25 TJm
-(alid) 14.9439 Tj
--298 TJm
-(\003ags,) 21.31 Tj
--310 TJm
-(I/O) 13.2801 Tj
--298 TJm
-(errors,) 25.7234 Tj
--310 TJm
-(etc.\),) 19.9152 Tj
--310 TJm
-(2) 4.9813 Tj
--298 TJm
-(to) 7.7509 Tj
-72 582.753 Td
-(indicate) 31.5416 Tj
--250 TJm
-(a) 4.42339 Tj
--250 TJm
-(corrupt) 28.772 Tj
--250 TJm
-(compressed) 47.0334 Tj
--250 TJm
-(\002le,) 15.2229 Tj
--250 TJm
-(3) 4.9813 Tj
--250 TJm
-(for) 11.6164 Tj
--250 TJm
-(an) 9.40469 Tj
--250 TJm
-(internal) 30.4357 Tj
--250 TJm
-(consistenc) 41.5042 Tj
-15 TJm
-(y) 4.9813 Tj
--250 TJm
-(error) 19.3573 Tj
--250 TJm
-(\(e) 7.74094 Tj
-15 TJm
-(g,) 7.47195 Tj
--250 TJm
-(b) 4.9813 Tj
-20 TJm
-(ug\)) 13.2801 Tj
--250 TJm
-(which) 24.3486 Tj
--250 TJm
-(caused) 27.1082 Tj
-[1 0 0 1 443.065 582.753] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -443.065 -582.753] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-443.065 582.753 Td
-/F134_0 9.9626 Tf
-(bzip2) 29.8878 Tj
-[1 0 0 1 472.953 582.753] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -472.953 -582.753] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-475.444 582.753 Td
-/F130_0 9.9626 Tf
-(to) 7.7509 Tj
--250 TJm
-(panic.) 24.0696 Tj
-[1 0 0 1 72 580.596] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.8441] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -570.752] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 548.118 Td
-/F122_0 20.6585 Tf
-(2.4.) 34.4584 Tj
--278 TJm
-(OPTIONS) 92.9839 Tj
-[1 0 0 1 72 547.86] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.8441] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.8441] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -528.172] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 516.475 Td
-/F134_0 9.9626 Tf
-(-c) 11.9551 Tj
--600 TJm
-(--stdout) 47.8205 Tj
-[1 0 0 1 137.753 516.475] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -68.2441 -0.1544] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -516.32] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-108 504.52 Td
-/F130_0 9.9626 Tf
-(Compress) 39.8504 Tj
--250 TJm
-(or) 8.29885 Tj
--250 TJm
-(decompress) 47.0334 Tj
--250 TJm
-(to) 7.7509 Tj
--250 TJm
-(standard) 33.7533 Tj
--250 TJm
-(output.) 27.9551 Tj
-[1 0 0 1 72 502.363] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -3.8664] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.8441] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -488.652] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 478.854 Td
-/F134_0 9.9626 Tf
-(-d) 11.9551 Tj
--600 TJm
-(--decompress) 71.7307 Tj
-[1 0 0 1 161.664 478.854] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4906 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -92.1544 -1.5341] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -477.32] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-108 466.899 Td
-/F130_0 9.9626 Tf
-(F) 5.53921 Tj
-15 TJm
-(orce) 17.1456 Tj
--296 TJm
-(decompression.) 62.2563 Tj
-[1 0 0 1 200.214 466.899] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -200.214 -466.899] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-200.214 466.899 Td
-/F134_0 9.9626 Tf
-(bzip2) 29.8878 Tj
-[1 0 0 1 230.102 466.899] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -230.102 -466.899] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-230.102 466.899 Td
-/F130_0 9.9626 Tf
-(,) 2.49065 Tj
-[1 0 0 1 235.659 466.899] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -235.659 -466.899] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-235.659 466.899 Td
-/F134_0 9.9626 Tf
-(bunzip2) 41.8429 Tj
-[1 0 0 1 277.502 466.899] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -277.502 -466.899] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-280.454 466.899 Td
-/F130_0 9.9626 Tf
-(and) 14.386 Tj
-[1 0 0 1 297.791 466.899] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -297.791 -466.899] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-297.791 466.899 Td
-/F134_0 9.9626 Tf
-(bzcat) 29.8878 Tj
-[1 0 0 1 327.679 466.899] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -327.679 -466.899] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-330.631 466.899 Td
-/F130_0 9.9626 Tf
-(are) 12.1643 Tj
--296 TJm
-(really) 22.6848 Tj
--296 TJm
-(the) 12.1743 Tj
--297 TJm
-(same) 20.4731 Tj
--296 TJm
-(program,) 36.2439 Tj
--308 TJm
-(and) 14.386 Tj
--296 TJm
-(the) 12.1743 Tj
--296 TJm
-(decision) 33.2053 Tj
--297 TJm
-(about) 22.1369 Tj
-108 454.944 Td
-(what) 19.3673 Tj
--303 TJm
-(actions) 28.224 Tj
--303 TJm
-(to) 7.7509 Tj
--303 TJm
-(tak) 12.1743 Tj
-10 TJm
-(e) 4.42339 Tj
--303 TJm
-(is) 6.64505 Tj
--303 TJm
-(done) 19.3673 Tj
--303 TJm
-(on) 9.9626 Tj
--304 TJm
-(the) 12.1743 Tj
--303 TJm
-(basis) 19.9252 Tj
--303 TJm
-(of) 8.29885 Tj
--303 TJm
-(which) 24.3486 Tj
--303 TJm
-(name) 21.579 Tj
--303 TJm
-(is) 6.64505 Tj
--303 TJm
-(used.) 20.7521 Tj
--939 TJm
-(This) 17.7135 Tj
--303 TJm
-(\003ag) 14.9439 Tj
--303 TJm
-(o) 4.9813 Tj
-15 TJm
-(v) 4.9813 Tj
-15 TJm
-(errides) 27.1082 Tj
--303 TJm
-(that) 14.9439 Tj
--303 TJm
-(mechanism,) 47.8703 Tj
--316 TJm
-(and) 14.386 Tj
-108 442.988 Td
-(forces) 24.3386 Tj
--250 TJm
-(bzip2) 22.1369 Tj
--250 TJm
-(to) 7.7509 Tj
--250 TJm
-(decompress.) 49.5241 Tj
-[1 0 0 1 72 440.832] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -3.8665] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.8441] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -427.121] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 417.323 Td
-/F134_0 9.9626 Tf
-(-z) 11.9551 Tj
--600 TJm
-(--compress) 59.7756 Tj
-[1 0 0 1 149.709 417.323] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -80.1993 -1.5342] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -415.789] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-108 405.368 Td
-/F130_0 9.9626 Tf
-(The) 15.4918 Tj
--250 TJm
-(complement) 49.2551 Tj
--250 TJm
-(to) 7.7509 Tj
-[1 0 0 1 187.969 405.368] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -187.969 -405.368] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-187.969 405.368 Td
-/F134_0 9.9626 Tf
-(-d) 11.9551 Tj
-[1 0 0 1 199.924 405.368] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -199.924 -405.368] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-199.924 405.368 Td
-/F130_0 9.9626 Tf
-(:) 2.7696 Tj
--310 TJm
-(forces) 24.3386 Tj
--250 TJm
-(compression,) 52.8516 Tj
--250 TJm
-(re) 7.74094 Tj
-15 TJm
-(g) 4.9813 Tj
-5 TJm
-(ardless) 27.6661 Tj
--250 TJm
-(of) 8.29885 Tj
--250 TJm
-(the) 12.1743 Tj
--250 TJm
-(in) 7.7509 Tj
-40 TJm
-(v) 4.9813 Tj
-20 TJm
-(okation) 29.8878 Tj
--250 TJm
-(name.) 24.0696 Tj
-[1 0 0 1 72 403.211] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -3.8665] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.8441] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -389.5] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 379.702 Td
-/F134_0 9.9626 Tf
-(-t) 11.9551 Tj
--600 TJm
-(--test) 35.8654 Tj
-[1 0 0 1 125.798 379.702] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4906 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -56.2889 -0.1544] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -379.548] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-108 367.747 Td
-/F130_0 9.9626 Tf
-(Check) 25.4544 Tj
--270 TJm
-(inte) 14.9439 Tj
-15 TJm
-(grity) 18.8194 Tj
--271 TJm
-(of) 8.29885 Tj
--270 TJm
-(the) 12.1743 Tj
--271 TJm
-(speci\002ed) 35.417 Tj
--270 TJm
-(\002le\(s\),) 25.7334 Tj
--276 TJm
-(b) 4.9813 Tj
-20 TJm
-(ut) 7.7509 Tj
--270 TJm
-(don') 18.2614 Tj
-18 TJm
-(t) 2.7696 Tj
--270 TJm
-(decompress) 47.0334 Tj
--271 TJm
-(them.) 22.4159 Tj
--742 TJm
-(This) 17.7135 Tj
--271 TJm
-(really) 22.6848 Tj
--270 TJm
-(performs) 35.965 Tj
--270 TJm
-(a) 4.42339 Tj
--271 TJm
-(trial) 16.0497 Tj
--270 TJm
-(decompres-) 46.4755 Tj
-108 355.791 Td
-(sion) 16.6077 Tj
--250 TJm
-(and) 14.386 Tj
--250 TJm
-(thro) 16.0497 Tj
-25 TJm
-(ws) 11.0684 Tj
--250 TJm
-(a) 4.42339 Tj
-15 TJm
-(w) 7.193 Tj
-10 TJm
-(ay) 9.40469 Tj
--250 TJm
-(the) 12.1743 Tj
--250 TJm
-(result.) 24.6275 Tj
-[1 0 0 1 72 353.635] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -3.8664] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.8441] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -339.924] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 330.126 Td
-/F134_0 9.9626 Tf
-(-f) 11.9551 Tj
--600 TJm
-(--force) 41.8429 Tj
-[1 0 0 1 131.776 330.126] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -62.2665 -0.1544] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -329.971] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-108 318.171 Td
-/F130_0 9.9626 Tf
-(F) 5.53921 Tj
-15 TJm
-(orce) 17.1456 Tj
--338 TJm
-(o) 4.9813 Tj
-15 TJm
-(v) 4.9813 Tj
-15 TJm
-(erwrite) 28.2141 Tj
--339 TJm
-(of) 8.29885 Tj
--338 TJm
-(output) 25.4644 Tj
--338 TJm
-(\002les.) 19.0983 Tj
--1150 TJm
-(Normally) 38.1866 Tj
-65 TJm
-(,) 2.49065 Tj
-[1 0 0 1 289.831 318.171] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -289.831 -318.171] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-289.831 318.171 Td
-/F134_0 9.9626 Tf
-(bzip2) 29.8878 Tj
-[1 0 0 1 319.719 318.171] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -319.719 -318.171] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-323.089 318.171 Td
-/F130_0 9.9626 Tf
-(will) 15.5018 Tj
--338 TJm
-(not) 12.7322 Tj
--339 TJm
-(o) 4.9813 Tj
-15 TJm
-(v) 4.9813 Tj
-15 TJm
-(erwrite) 28.2141 Tj
--338 TJm
-(e) 4.42339 Tj
-15 TJm
-(xisting) 27.1282 Tj
--338 TJm
-(output) 25.4644 Tj
--338 TJm
-(\002les.) 19.0983 Tj
--1150 TJm
-(Also) 18.8194 Tj
--339 TJm
-(forces) 24.3386 Tj
-[1 0 0 1 108 306.215] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -108 -306.215] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-108 306.215 Td
-/F134_0 9.9626 Tf
-(bzip2) 29.8878 Tj
-[1 0 0 1 137.888 306.215] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -137.888 -306.215] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-140.379 306.215 Td
-/F130_0 9.9626 Tf
-(to) 7.7509 Tj
--250 TJm
-(break) 22.1269 Tj
--250 TJm
-(hard) 17.7035 Tj
--250 TJm
-(links) 19.3773 Tj
--250 TJm
-(to) 7.7509 Tj
--250 TJm
-(\002les,) 19.0983 Tj
--250 TJm
-(which) 24.3486 Tj
--250 TJm
-(it) 5.53921 Tj
--250 TJm
-(otherwise) 38.7346 Tj
--250 TJm
-(w) 7.193 Tj
-10 TJm
-(ouldn') 26.0123 Tj
-18 TJm
-(t) 2.7696 Tj
--250 TJm
-(do.) 12.4533 Tj
-[1 0 0 1 72 304.681] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.8441] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -294.837] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-108 284.416 Td
-/F134_0 9.9626 Tf
-(bzip2) 29.8878 Tj
-[1 0 0 1 137.888 284.416] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -137.888 -284.416] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-141.211 284.416 Td
-/F130_0 9.9626 Tf
-(normally) 35.9749 Tj
--334 TJm
-(declines) 32.6474 Tj
--333 TJm
-(to) 7.7509 Tj
--334 TJm
-(decompress) 47.0334 Tj
--333 TJm
-(\002les) 16.6077 Tj
--334 TJm
-(which) 24.3486 Tj
--333 TJm
-(don') 18.2614 Tj
-18 TJm
-(t) 2.7696 Tj
--334 TJm
-(ha) 9.40469 Tj
-20 TJm
-(v) 4.9813 Tj
-15 TJm
-(e) 4.42339 Tj
--333 TJm
-(the) 12.1743 Tj
--334 TJm
-(correct) 27.6562 Tj
--333 TJm
-(magic) 24.3486 Tj
--334 TJm
-(header) 26.5503 Tj
--333 TJm
-(bytes.) 23.5217 Tj
--561 TJm
-(If) 6.63509 Tj
--334 TJm
-(forced) 25.4445 Tj
-108 272.461 Td
-(\() 3.31755 Tj
-[1 0 0 1 111.318 272.461] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -111.318 -272.461] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-111.318 272.461 Td
-/F134_0 9.9626 Tf
-(-f) 11.9551 Tj
-[1 0 0 1 123.273 272.461] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -123.273 -272.461] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-123.273 272.461 Td
-/F130_0 9.9626 Tf
-(\),) 5.8082 Tj
--250 TJm
-(ho) 9.9626 Tj
-25 TJm
-(we) 11.6164 Tj
-25 TJm
-(v) 4.9813 Tj
-15 TJm
-(er) 7.74094 Tj
-40 TJm
-(,) 2.49065 Tj
--250 TJm
-(it) 5.53921 Tj
--250 TJm
-(will) 15.5018 Tj
--250 TJm
-(pass) 17.1556 Tj
--250 TJm
-(such) 18.2614 Tj
--250 TJm
-(\002les) 16.6077 Tj
--250 TJm
-(through) 30.9936 Tj
--250 TJm
-(unmodi\002ed.) 47.8803 Tj
--310 TJm
-(This) 17.7135 Tj
--250 TJm
-(is) 6.64505 Tj
--250 TJm
-(ho) 9.9626 Tj
-25 TJm
-(w) 7.193 Tj
--250 TJm
-(GNU) 21.579 Tj
-[1 0 0 1 412.585 272.461] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -412.585 -272.461] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-412.585 272.461 Td
-/F134_0 9.9626 Tf
-(gzip) 23.9102 Tj
-[1 0 0 1 436.496 272.461] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -436.496 -272.461] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-438.986 272.461 Td
-/F130_0 9.9626 Tf
-(beha) 18.8094 Tj
-20 TJm
-(v) 4.9813 Tj
-15 TJm
-(es.) 10.7895 Tj
-[1 0 0 1 72 270.304] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -3.8665] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.8441] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -256.594] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 246.795 Td
-/F134_0 9.9626 Tf
-(-k) 11.9551 Tj
--600 TJm
-(--keep) 35.8654 Tj
-[1 0 0 1 125.798 246.795] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4906 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -56.2889 -1.5342] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -245.261] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-108 234.84 Td
-/F130_0 9.9626 Tf
-(K) 7.193 Tj
-25 TJm
-(eep) 13.8281 Tj
--250 TJm
-(\(don') 21.579 Tj
-18 TJm
-(t) 2.7696 Tj
--250 TJm
-(delete\)) 27.1082 Tj
--250 TJm
-(input) 20.4831 Tj
--250 TJm
-(\002les) 16.6077 Tj
--250 TJm
-(during) 26.0123 Tj
--250 TJm
-(compression) 50.3609 Tj
--250 TJm
-(or) 8.29885 Tj
--250 TJm
-(decompression.) 62.2563 Tj
-[1 0 0 1 72 232.683] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -3.8665] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.8441] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -218.973] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 209.174 Td
-/F134_0 9.9626 Tf
-(-s) 11.9551 Tj
--600 TJm
-(--small) 41.8429 Tj
-[1 0 0 1 131.776 209.174] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -62.2665 -0.1544] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -209.02] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-108 197.219 Td
-/F130_0 9.9626 Tf
-(Reduce) 29.8778 Tj
--347 TJm
-(memory) 33.2053 Tj
--347 TJm
-(usage,) 25.1755 Tj
--371 TJm
-(for) 11.6164 Tj
--346 TJm
-(compression,) 52.8516 Tj
--371 TJm
-(decompression) 59.7656 Tj
--347 TJm
-(and) 14.386 Tj
--347 TJm
-(testing.) 29.0609 Tj
--1201 TJm
-(Files) 19.3773 Tj
--347 TJm
-(are) 12.1643 Tj
--347 TJm
-(decompressed) 56.4381 Tj
--346 TJm
-(and) 14.386 Tj
--347 TJm
-(tested) 23.2427 Tj
-108 185.264 Td
-(using) 21.589 Tj
--388 TJm
-(a) 4.42339 Tj
--388 TJm
-(modi\002ed) 35.427 Tj
--388 TJm
-(algorithm) 38.7446 Tj
--389 TJm
-(which) 24.3486 Tj
--388 TJm
-(only) 17.7135 Tj
--388 TJm
-(requires) 32.0895 Tj
--388 TJm
-(2.5) 12.4533 Tj
--388 TJm
-(bytes) 21.031 Tj
--388 TJm
-(per) 12.7222 Tj
--388 TJm
-(block) 22.1369 Tj
--389 TJm
-(byte.) 19.6462 Tj
--1448 TJm
-(This) 17.7135 Tj
--389 TJm
-(means) 25.4544 Tj
--388 TJm
-(an) 9.40469 Tj
-15 TJm
-(y) 4.9813 Tj
--388 TJm
-(\002le) 12.7322 Tj
--388 TJm
-(can) 13.8281 Tj
--388 TJm
-(be) 9.40469 Tj
-108 173.309 Td
-(decompressed) 56.4381 Tj
--250 TJm
-(in) 7.7509 Tj
--250 TJm
-(2300k) 24.9065 Tj
--250 TJm
-(of) 8.29885 Tj
--250 TJm
-(memory) 33.2053 Tj
-65 TJm
-(,) 2.49065 Tj
--250 TJm
-(albeit) 22.1369 Tj
--250 TJm
-(at) 7.193 Tj
--250 TJm
-(about) 22.1369 Tj
--250 TJm
-(half) 15.4918 Tj
--250 TJm
-(the) 12.1743 Tj
--250 TJm
-(normal) 28.224 Tj
--250 TJm
-(speed.) 25.1755 Tj
-[1 0 0 1 72 171.152] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.8441] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -161.308] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-108 151.51 Td
-/F130_0 9.9626 Tf
-(During) 28.224 Tj
--252 TJm
-(compr) 25.4544 Tj
-1 TJm
-(ession,) 27.3972 Tj
-[1 0 0 1 194.09 151.51] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -194.09 -151.51] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-194.09 151.51 Td
-/F134_0 9.9626 Tf
-(-s) 11.9551 Tj
-[1 0 0 1 206.046 151.51] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -206.046 -151.51] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-208.551 151.51 Td
-/F130_0 9.9626 Tf
-(selects) 26.5603 Tj
--251 TJm
-(a) 4.42339 Tj
--252 TJm
-(block) 22.1369 Tj
--251 TJm
-(size) 15.4918 Tj
--252 TJm
-(of) 8.29885 Tj
--252 TJm
-(200k,) 22.4159 Tj
--251 TJm
-(which) 24.3486 Tj
--252 TJm
-(limits) 22.7048 Tj
--251 TJm
-(memory) 33.2053 Tj
--252 TJm
-(use) 13.2801 Tj
--251 TJm
-(to) 7.7509 Tj
--252 TJm
-(around) 27.6661 Tj
--251 TJm
-(the) 12.1743 Tj
--252 TJm
-(same) 20.4731 Tj
--251 TJm
-(\002gure,) 25.7334 Tj
--252 TJm
-(at) 7.193 Tj
-108 139.554 Td
-(the) 12.1743 Tj
--287 TJm
-(e) 4.42339 Tj
-15 TJm
-(xpense) 27.6661 Tj
--287 TJm
-(of) 8.29885 Tj
--288 TJm
-(your) 18.2614 Tj
--287 TJm
-(compression) 50.3609 Tj
--287 TJm
-(ratio.) 20.7521 Tj
--843 TJm
-(In) 8.29885 Tj
--287 TJm
-(short,) 22.4159 Tj
--297 TJm
-(if) 6.08715 Tj
--287 TJm
-(your) 18.2614 Tj
--287 TJm
-(machine) 33.7533 Tj
--287 TJm
-(is) 6.64505 Tj
--287 TJm
-(lo) 7.7509 Tj
-25 TJm
-(w) 7.193 Tj
--287 TJm
-(on) 9.9626 Tj
--288 TJm
-(memory) 33.2053 Tj
--287 TJm
-(\(8) 8.29885 Tj
--287 TJm
-(me) 12.1743 Tj
-15 TJm
-(g) 4.9813 Tj
-5 TJm
-(abytes) 25.4544 Tj
--287 TJm
-(or) 8.29885 Tj
--287 TJm
-(less\),) 20.7521 Tj
-108 127.599 Td
-(use) 13.2801 Tj
-[1 0 0 1 123.771 127.599] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -123.771 -127.599] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-123.771 127.599 Td
-/F134_0 9.9626 Tf
-(-s) 11.9551 Tj
-[1 0 0 1 135.726 127.599] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -135.726 -127.599] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-138.216 127.599 Td
-/F130_0 9.9626 Tf
-(for) 11.6164 Tj
--250 TJm
-(e) 4.42339 Tj
-25 TJm
-(v) 4.9813 Tj
-15 TJm
-(erything.) 35.696 Tj
--620 TJm
-(See) 14.386 Tj
-[1 0 0 1 220.079 127.599] cm
-/DeviceRGB {} cs
-[0 0 1] sc
-/DeviceRGB {} CS
-[0 0 1] SC
-[1 0 0 1 -220.079 -127.599] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-220.079 127.599 Td
-/F130_0 9.9626 Tf
-(MEMOR) 37.6387 Tj
-65 TJm
-(Y) 7.193 Tj
--250 TJm
-(MAN) 23.2427 Tj
-35 TJm
-(A) 7.193 Tj
-40 TJm
-(GEMENT) 41.5042 Tj
-[1 0 0 1 337.946 127.599] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 1] sc
-/DeviceRGB {} CS
-[0 0 1] SC
-/DeviceRGB {} cs
-[0 0 1] sc
-/DeviceRGB {} CS
-[0 0 1] SC
-[1 0 0 1 -337.946 -127.599] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-340.437 127.599 Td
-/F130_0 9.9626 Tf
-([5]) 11.6164 Tj
-[1 0 0 1 352.053 127.599] cm
-/DeviceRGB {} cs
-[0 0 1] sc
-/DeviceRGB {} CS
-[0 0 1] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -352.053 -127.599] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-354.544 127.599 Td
-/F130_0 9.9626 Tf
-(belo) 17.1556 Tj
-25 TJm
-(w) 7.193 Tj
-65 TJm
-(.) 2.49065 Tj
-[1 0 0 1 72 125.443] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -3.8665] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.8441] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -111.732] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 101.934 Td
-/F134_0 9.9626 Tf
-(-q) 11.9551 Tj
--600 TJm
-(--quiet) 41.8429 Tj
-[1 0 0 1 131.776 101.934] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -62.2665 -1.5342] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -100.399] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-108 89.9784 Td
-/F130_0 9.9626 Tf
-(Suppress) 35.9749 Tj
--221 TJm
-(non-essential) 52.5726 Tj
--220 TJm
-(w) 7.193 Tj
-10 TJm
-(arning) 25.4544 Tj
--221 TJm
-(messages.) 40.1194 Tj
--300 TJm
-(Messages) 38.7346 Tj
--221 TJm
-(pertaining) 40.3983 Tj
--221 TJm
-(to) 7.7509 Tj
--220 TJm
-(I/O) 13.2801 Tj
--221 TJm
-(errors) 23.2328 Tj
--221 TJm
-(and) 14.386 Tj
--220 TJm
-(other) 20.4731 Tj
--221 TJm
-(critical) 27.6661 Tj
--221 TJm
-(e) 4.42339 Tj
-25 TJm
-(v) 4.9813 Tj
-15 TJm
-(ents) 16.0497 Tj
--221 TJm
-(wi) 9.9626 Tj
-1 TJm
-(ll) 5.53921 Tj
--221 TJm
-(not) 12.7322 Tj
-108 78.0232 Td
-(be) 9.40469 Tj
--250 TJm
-(suppressed.) 46.2065 Tj
-[1 0 0 1 72 75.8664] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -3.8664] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -21.1482] cm
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-[1 0 0 1 1.8929 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 374.394 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 6.7546] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 43.0633 -6.7546] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -496.332 -50.8518] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-539.395 50.8518 Td
-/F130_0 9.9626 Tf
-(4) 4.9813 Tj
-[1 0 0 1 453.269 50.8518] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 93.5985 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 6.2765 0] cm
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-[1 0 0 1 -13.1436 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-Q
-showpage
-%%PageTrailer
-pdfEndPage
-%%Page: 8 8
-%%BeginPageSetup
-%%PageOrientation: Portrait
-pdfStartPage
-0 0 612 792 re W
-%%EndPageSetup
-[] 0 d
-1 i
-0 j
-0 J
-10 M
-1 w
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-false op
-false OP
-0 0 612 792 re
-W
-q
-[1 0 0 1 72 741.554] cm
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-[1 0 0 1 1.8929 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 14.4459] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 187.197 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 -8.9114] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 8.9114] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 105.519 -6.7546] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -371.59 -749.245] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-477.109 749.245 Td
-/F130_0 9.9626 Tf
-(Ho) 12.1743 Tj
-25 TJm
-(w) 7.193 Tj
--250 TJm
-(to) 7.7509 Tj
--250 TJm
-(use) 13.2801 Tj
--250 TJm
-(bzip2) 22.1369 Tj
-[1 0 0 1 266.071 747.089] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 280.796 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -472.974 -5.0363] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -0.4981] cm
-q
-[] 0 d
-0 J
-0.4981 w
-0 0.2491 m
-475.465 0.2491 l
-S
-Q
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 479.251 0] cm
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-[1 0 0 1 -13.1436 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -468 -21.5542] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -720] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 710.037 Td
-/F134_0 9.9626 Tf
-(-v) 11.9551 Tj
--600 TJm
-(--verbose) 53.798 Tj
-[1 0 0 1 143.731 710.037] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -74.2217 -0.1544] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -709.883] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-108 698.082 Td
-/F130_0 9.9626 Tf
-(V) 7.193 Tj
-111 TJm
-(erbose) 26.0024 Tj
--323 TJm
-(mode) 22.1369 Tj
--322 TJm
-(--) 6.63509 Tj
--323 TJm
-(sho) 13.8381 Tj
-25 TJm
-(w) 7.193 Tj
--322 TJm
-(the) 12.1743 Tj
--323 TJm
-(compression) 50.3609 Tj
--323 TJm
-(ratio) 18.2614 Tj
--322 TJm
-(for) 11.6164 Tj
--323 TJm
-(each) 18.2515 Tj
--322 TJm
-(\002le) 12.7322 Tj
--323 TJm
-(processed.) 41.7732 Tj
--1056 TJm
-(Further) 29.3299 Tj
-[1 0 0 1 430.015 698.082] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -430.015 -698.082] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-430.015 698.082 Td
-/F134_0 9.9626 Tf
-(-v) 11.9551 Tj
-[1 0 0 1 441.97 698.082] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -441.97 -698.082] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-441.97 698.082 Td
-/F130_0 9.9626 Tf
-(') 3.31755 Tj
-55 TJm
-(s) 3.87545 Tj
--323 TJm
-(increase) 32.6375 Tj
--322 TJm
-(the) 12.1743 Tj
--323 TJm
-(v) 4.9813 Tj
-15 TJm
-(erbosity) 32.0995 Tj
-108 686.127 Td
-(le) 7.193 Tj
-25 TJm
-(v) 4.9813 Tj
-15 TJm
-(el,) 9.68365 Tj
--250 TJm
-(spe) 13.2801 Tj
-25 TJm
-(wing) 19.9252 Tj
--250 TJm
-(out) 12.7322 Tj
--250 TJm
-(lots) 14.396 Tj
--250 TJm
-(of) 8.29885 Tj
--250 TJm
-(information) 47.0434 Tj
--250 TJm
-(which) 24.3486 Tj
--250 TJm
-(is) 6.64505 Tj
--250 TJm
-(primarily) 37.0808 Tj
--250 TJm
-(of) 8.29885 Tj
--250 TJm
-(interest) 29.3299 Tj
--250 TJm
-(for) 11.6164 Tj
--250 TJm
-(diagnostic) 40.9562 Tj
--250 TJm
-(purposes.) 37.9077 Tj
-[1 0 0 1 72 683.97] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -3.985] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.9626] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -670.023] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 660.224 Td
-/F134_0 9.9626 Tf
-(-L) 11.9551 Tj
--600 TJm
-(--license) 53.798 Tj
--600 TJm
-(-V) 11.9551 Tj
--600 TJm
-(--version) 53.798 Tj
-[1 0 0 1 221.44 660.224] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -151.93 -0.1544] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -660.07] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-108 648.269 Td
-/F130_0 9.9626 Tf
-(Display) 30.9936 Tj
--250 TJm
-(the) 12.1743 Tj
--250 TJm
-(softw) 22.1369 Tj
-10 TJm
-(are) 12.1643 Tj
--250 TJm
-(v) 4.9813 Tj
-15 TJm
-(ersion,) 26.8392 Tj
--250 TJm
-(license) 27.6661 Tj
--250 TJm
-(terms) 22.1369 Tj
--250 TJm
-(and) 14.386 Tj
--250 TJm
-(conditions.) 44.0048 Tj
-[1 0 0 1 72 646.112] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -3.985] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.9626] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -632.165] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 622.366 Td
-/F134_0 9.9626 Tf
-(-1) 11.9551 Tj
-[1 0 0 1 83.9552 622.366] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -83.9552 -622.366] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-86.4458 622.366 Td
-/F130_0 9.9626 Tf
-(\(or) 11.6164 Tj
-[1 0 0 1 100.553 622.366] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -100.553 -622.366] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-100.553 622.366 Td
-/F134_0 9.9626 Tf
-(--fast) 35.8654 Tj
-[1 0 0 1 136.418 622.366] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -136.418 -622.366] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-136.418 622.366 Td
-/F130_0 9.9626 Tf
-(\)) 3.31755 Tj
--250 TJm
-(to) 7.7509 Tj
-[1 0 0 1 152.468 622.366] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -152.468 -622.366] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-152.468 622.366 Td
-/F134_0 9.9626 Tf
-(-9) 11.9551 Tj
-[1 0 0 1 164.423 622.366] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -164.423 -622.366] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-166.914 622.366 Td
-/F130_0 9.9626 Tf
-(\(or) 11.6164 Tj
-[1 0 0 1 181.021 622.366] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -181.021 -622.366] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-181.021 622.366 Td
-/F134_0 9.9626 Tf
-(-best) 29.8878 Tj
-[1 0 0 1 210.909 622.366] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -210.909 -622.366] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-210.909 622.366 Td
-/F130_0 9.9626 Tf
-(\)) 3.31755 Tj
-[1 0 0 1 214.226 622.366] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -142.226 -1.7832] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -620.583] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-108 610.411 Td
-/F130_0 9.9626 Tf
-(Set) 12.7322 Tj
--288 TJm
-(the) 12.1743 Tj
--289 TJm
-(block) 22.1369 Tj
--288 TJm
-(size) 15.4918 Tj
--288 TJm
-(to) 7.7509 Tj
--288 TJm
-(100) 14.9439 Tj
--289 TJm
-(k,) 7.47195 Tj
--298 TJm
-(200) 14.9439 Tj
--288 TJm
-(k) 4.9813 Tj
--288 TJm
-(...) 7.47195 Tj
--850 TJm
-(900) 14.9439 Tj
--288 TJm
-(k) 4.9813 Tj
--288 TJm
-(when) 21.579 Tj
--289 TJm
-(compressing.) 52.8516 Tj
--849 TJm
-(Has) 15.4918 Tj
--289 TJm
-(no) 9.9626 Tj
--288 TJm
-(ef) 7.74094 Tj
-25 TJm
-(fect) 14.9339 Tj
--288 TJm
-(when) 21.579 Tj
--288 TJm
-(decompressing.) 62.2563 Tj
--850 TJm
-(See) 14.386 Tj
-[1 0 0 1 108 598.456] cm
-/DeviceRGB {} cs
-[0 0 1] sc
-/DeviceRGB {} CS
-[0 0 1] SC
-[1 0 0 1 -108 -598.456] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-108 598.456 Td
-/F130_0 9.9626 Tf
-(MEMOR) 37.6387 Tj
-65 TJm
-(Y) 7.193 Tj
--297 TJm
-(MAN) 23.2427 Tj
-35 TJm
-(A) 7.193 Tj
-40 TJm
-(GEMENT) 41.5042 Tj
-[1 0 0 1 226.338 598.456] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 1] sc
-/DeviceRGB {} CS
-[0 0 1] SC
-/DeviceRGB {} cs
-[0 0 1] sc
-/DeviceRGB {} CS
-[0 0 1] SC
-[1 0 0 1 -226.338 -598.456] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-229.3 598.456 Td
-/F130_0 9.9626 Tf
-([5]) 11.6164 Tj
-[1 0 0 1 240.916 598.456] cm
-/DeviceRGB {} cs
-[0 0 1] sc
-/DeviceRGB {} CS
-[0 0 1] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -240.916 -598.456] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-243.878 598.456 Td
-/F130_0 9.9626 Tf
-(belo) 17.1556 Tj
-25 TJm
-(w) 7.193 Tj
-65 TJm
-(.) 2.49065 Tj
--904 TJm
-(The) 15.4918 Tj
-[1 0 0 1 297.278 598.456] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -297.278 -598.456] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-297.278 598.456 Td
-/F134_0 9.9626 Tf
-(--fast) 35.8654 Tj
-[1 0 0 1 333.144 598.456] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -333.144 -598.456] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-336.106 598.456 Td
-/F130_0 9.9626 Tf
-(and) 14.386 Tj
-[1 0 0 1 353.454 598.456] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -353.454 -598.456] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-353.454 598.456 Td
-/F134_0 9.9626 Tf
-(--best) 35.8654 Tj
-[1 0 0 1 389.319 598.456] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -389.319 -598.456] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-392.281 598.456 Td
-/F130_0 9.9626 Tf
-(aliases) 26.5603 Tj
--297 TJm
-(are) 12.1643 Tj
--298 TJm
-(primarily) 37.0808 Tj
--297 TJm
-(for) 11.6164 Tj
--297 TJm
-(GNU) 21.579 Tj
-[1 0 0 1 516.09 598.456] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -516.09 -598.456] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-516.09 598.456 Td
-/F134_0 9.9626 Tf
-(gzip) 23.9102 Tj
-[1 0 0 1 540 598.456] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -540 -598.456] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-108 586.501 Td
-/F130_0 9.9626 Tf
-(compatibility) 53.1405 Tj
-65 TJm
-(.) 2.49065 Tj
--356 TJm
-(In) 8.29885 Tj
--265 TJm
-(particular) 38.1767 Tj
-40 TJm
-(,) 2.49065 Tj
-[1 0 0 1 220.423 586.501] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -220.423 -586.501] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-220.423 586.501 Td
-/F134_0 9.9626 Tf
-(--fast) 35.8654 Tj
-[1 0 0 1 256.288 586.501] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -256.288 -586.501] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-258.932 586.501 Td
-/F130_0 9.9626 Tf
-(doesn') 26.5603 Tj
-18 TJm
-(t) 2.7696 Tj
--265 TJm
-(mak) 17.1556 Tj
-10 TJm
-(e) 4.42339 Tj
--266 TJm
-(things) 24.3586 Tj
--265 TJm
-(signi\002cantly) 49.2651 Tj
--265 TJm
-(f) 3.31755 Tj
-10 TJm
-(aster) 18.8094 Tj
-55 TJm
-(.) 2.49065 Tj
--712 TJm
-(And) 17.1556 Tj
-[1 0 0 1 444.622 586.501] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -444.622 -586.501] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-444.622 586.501 Td
-/F134_0 9.9626 Tf
-(--best) 35.8654 Tj
-[1 0 0 1 480.487 586.501] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -480.487 -586.501] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-483.131 586.501 Td
-/F130_0 9.9626 Tf
-(merely) 27.6661 Tj
--265 TJm
-(selects) 26.5603 Tj
-108 574.546 Td
-(the) 12.1743 Tj
--250 TJm
-(def) 12.7222 Tj
-10 TJm
-(ault) 14.9439 Tj
--250 TJm
-(beha) 18.8094 Tj
-20 TJm
-(viour) 21.031 Tj
-55 TJm
-(.) 2.49065 Tj
-[1 0 0 1 72 574.446] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -3.985] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.9626] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -560.498] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 548.643 Td
-/F134_0 9.9626 Tf
-(--) 11.9551 Tj
-[1 0 0 1 83.9552 548.643] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4906 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -14.4458 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -548.643] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-108 536.688 Td
-/F130_0 9.9626 Tf
-(T) 6.08715 Tj
-35 TJm
-(reats) 18.8094 Tj
--261 TJm
-(all) 9.9626 Tj
--261 TJm
-(subsequent) 44.2738 Tj
--260 TJm
-(ar) 7.74094 Tj
-18 TJm
-(guments) 33.7633 Tj
--261 TJm
-(as) 8.29885 Tj
--261 TJm
-(\002le) 12.7322 Tj
--261 TJm
-(names,) 27.9451 Tj
--263 TJm
-(e) 4.42339 Tj
-25 TJm
-(v) 4.9813 Tj
-15 TJm
-(en) 9.40469 Tj
--261 TJm
-(if) 6.08715 Tj
--261 TJm
-(the) 12.1743 Tj
-15 TJm
-(y) 4.9813 Tj
--260 TJm
-(start) 17.1556 Tj
--261 TJm
-(with) 17.7135 Tj
--261 TJm
-(a) 4.42339 Tj
--261 TJm
-(dash.) 20.7521 Tj
--685 TJm
-(This) 17.7135 Tj
--260 TJm
-(is) 6.64505 Tj
--261 TJm
-(so) 8.85675 Tj
--261 TJm
-(you) 14.9439 Tj
--261 TJm
-(can) 13.8281 Tj
--260 TJm
-(handle) 26.5603 Tj
--261 TJm
-(\002les) 16.6077 Tj
-108 524.732 Td
-(with) 17.7135 Tj
--250 TJm
-(names) 25.4544 Tj
--250 TJm
-(be) 9.40469 Tj
-15 TJm
-(ginning) 30.4457 Tj
--250 TJm
-(with) 17.7135 Tj
--250 TJm
-(a) 4.42339 Tj
--250 TJm
-(dash,) 20.7521 Tj
--250 TJm
-(for) 11.6164 Tj
--250 TJm
-(e) 4.42339 Tj
-15 TJm
-(xample:) 32.0995 Tj
-[1 0 0 1 302.27 524.732] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -302.27 -524.732] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-302.27 524.732 Td
-/F134_0 9.9626 Tf
-(bzip2) 29.8878 Tj
--600 TJm
-(--) 11.9551 Tj
--600 TJm
-(-myfilename) 65.7532 Tj
-[1 0 0 1 421.821 524.732] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -421.821 -524.732] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-421.821 524.732 Td
-/F130_0 9.9626 Tf
-(.) 2.49065 Tj
-[1 0 0 1 72 522.576] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -3.985] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.9626] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -508.628] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 498.83 Td
-/F134_0 9.9626 Tf
-(--repetitive-fast) 101.619 Tj
-[1 0 0 1 173.619 498.83] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -173.619 -498.83] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-173.619 498.83 Td
-/F130_0 9.9626 Tf
-(,) 2.49065 Tj
-[1 0 0 1 178.6 498.83] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4906 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -183.582 -498.83] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-183.582 498.83 Td
-/F134_0 9.9626 Tf
-(--repetitive-best) 101.619 Tj
-[1 0 0 1 285.2 498.83] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -215.691 -1.5342] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -497.295] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-108 486.874 Td
-/F130_0 9.9626 Tf
-(These) 23.7907 Tj
--207 TJm
-(\003ags) 18.8194 Tj
--206 TJm
-(are) 12.1643 Tj
--207 TJm
-(redundant) 39.8404 Tj
--207 TJm
-(in) 7.7509 Tj
--206 TJm
-(v) 4.9813 Tj
-15 TJm
-(ersions) 28.224 Tj
--207 TJm
-(0.9.5) 19.9252 Tj
--207 TJm
-(and) 14.386 Tj
--206 TJm
-(abo) 14.386 Tj
-15 TJm
-(v) 4.9813 Tj
-15 TJm
-(e.) 6.91404 Tj
--591 TJm
-(The) 15.4918 Tj
-15 TJm
-(y) 4.9813 Tj
--207 TJm
-(pro) 13.2801 Tj
-15 TJm
-(vided) 22.1369 Tj
--207 TJm
-(some) 21.031 Tj
--207 TJm
-(c) 4.42339 Tj
-1 TJm
-(o) 4.9813 Tj
--1 TJm
-(a) 4.42339 Tj
-1 TJm
-(rse) 11.6164 Tj
--207 TJm
-(control) 28.224 Tj
--207 TJm
-(o) 4.9813 Tj
-15 TJm
-(v) 4.9813 Tj
-15 TJm
-(er) 7.74094 Tj
--207 TJm
-(the) 12.1743 Tj
--206 TJm
-(beha) 18.8094 Tj
-20 TJm
-(viour) 21.031 Tj
-108 474.919 Td
-(of) 8.29885 Tj
--250 TJm
-(the) 12.1743 Tj
--251 TJm
-(sorting) 27.6761 Tj
--250 TJm
-(algorithm) 38.7446 Tj
--250 TJm
-(in) 7.7509 Tj
--251 TJm
-(earlier) 25.4445 Tj
--250 TJm
-(v) 4.9813 Tj
-15 TJm
-(ersions,) 30.7147 Tj
--250 TJm
-(which) 24.3486 Tj
--251 TJm
-(w) 7.193 Tj
-10 TJm
-(as) 8.29885 Tj
--250 TJm
-(sometimes) 42.62 Tj
--250 TJm
-(useful.) 26.8392 Tj
--622 TJm
-(0.9.5) 19.9252 Tj
--251 TJm
-(and) 14.386 Tj
--250 TJm
-(abo) 14.386 Tj
-15 TJm
-(v) 4.9813 Tj
-15 TJm
-(e) 4.42339 Tj
--250 TJm
-(ha) 9.40469 Tj
-20 TJm
-(v) 4.9813 Tj
-15 TJm
-(e) 4.42339 Tj
--251 TJm
-(an) 9.40469 Tj
--250 TJm
-(impro) 23.8007 Tj
-15 TJm
-(v) 4.9813 Tj
-15 TJm
-(ed) 9.40469 Tj
-108 462.964 Td
-(algorithm) 38.7446 Tj
--250 TJm
-(which) 24.3486 Tj
--250 TJm
-(renders) 29.3199 Tj
--250 TJm
-(these) 20.4731 Tj
--250 TJm
-(\003ags) 18.8194 Tj
--250 TJm
-(irrele) 21.0211 Tj
-25 TJm
-(v) 4.9813 Tj
-25 TJm
-(ant.) 14.6649 Tj
-[1 0 0 1 72 460.807] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -3.985] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.9627] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.9626] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -436.897] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 414.264 Td
-/F122_0 20.6585 Tf
-(2.5.) 34.4584 Tj
--278 TJm
-(MEMOR) 79.184 Tj
-50 TJm
-(Y) 13.7792 Tj
--278 TJm
-(MANA) 61.9548 Tj
-50 TJm
-(GEMENT) 88.3771 Tj
-[1 0 0 1 72 414.005] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.9626] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -404.043] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 392.346 Td
-/F134_0 9.9626 Tf
-(bzip2) 29.8878 Tj
-[1 0 0 1 101.888 392.346] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -101.888 -392.346] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-104.454 392.346 Td
-/F130_0 9.9626 Tf
-(compresses) 45.9276 Tj
--258 TJm
-(lar) 10.5105 Tj
-18 TJm
-(ge) 9.40469 Tj
--257 TJm
-(\002les) 16.6077 Tj
--258 TJm
-(in) 7.7509 Tj
--257 TJm
-(blocks.) 28.503 Tj
--666 TJm
-(The) 15.4918 Tj
--257 TJm
-(block) 22.1369 Tj
--258 TJm
-(size) 15.4918 Tj
--258 TJm
-(af) 7.74094 Tj
-25 TJm
-(fects) 18.8094 Tj
--257 TJm
-(both) 17.7135 Tj
--258 TJm
-(the) 12.1743 Tj
--257 TJm
-(compression) 50.3609 Tj
--258 TJm
-(ratio) 18.2614 Tj
--257 TJm
-(achie) 21.0211 Tj
-25 TJm
-(v) 4.9813 Tj
-15 TJm
-(ed,) 11.8953 Tj
--260 TJm
-(and) 14.386 Tj
--258 TJm
-(the) 12.1743 Tj
--257 TJm
-(amount) 29.8878 Tj
-72 380.391 Td
-(of) 8.29885 Tj
--215 TJm
-(memory) 33.2053 Tj
--215 TJm
-(needed) 28.2141 Tj
--215 TJm
-(for) 11.6164 Tj
--215 TJm
-(compression) 50.3609 Tj
--214 TJm
-(and) 14.386 Tj
--215 TJm
-(decompression.) 62.2563 Tj
--597 TJm
-(The) 15.4918 Tj
--215 TJm
-(\003ags) 18.8194 Tj
-[1 0 0 1 337.719 380.391] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -337.719 -380.391] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-337.719 380.391 Td
-/F134_0 9.9626 Tf
-(-1) 11.9551 Tj
-[1 0 0 1 349.674 380.391] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -349.674 -380.391] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-351.815 380.391 Td
-/F130_0 9.9626 Tf
-(through) 30.9936 Tj
-[1 0 0 1 384.95 380.391] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -384.95 -380.391] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-384.95 380.391 Td
-/F134_0 9.9626 Tf
-(-9) 11.9551 Tj
-[1 0 0 1 396.905 380.391] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -396.905 -380.391] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-399.046 380.391 Td
-/F130_0 9.9626 Tf
-(specify) 28.772 Tj
--215 TJm
-(the) 12.1743 Tj
--215 TJm
-(block) 22.1369 Tj
--215 TJm
-(size) 15.4918 Tj
--215 TJm
-(to) 7.7509 Tj
--214 TJm
-(be) 9.40469 Tj
--215 TJm
-(100,000) 32.3785 Tj
-72 368.435 Td
-(bytes) 21.031 Tj
--278 TJm
-(through) 30.9936 Tj
--277 TJm
-(900,000) 32.3785 Tj
--278 TJm
-(bytes) 21.031 Tj
--278 TJm
-(\(the) 15.4918 Tj
--277 TJm
-(def) 12.7222 Tj
-10 TJm
-(ault\)) 18.2614 Tj
--278 TJm
-(respecti) 30.9837 Tj
-25 TJm
-(v) 4.9813 Tj
-15 TJm
-(ely) 12.1743 Tj
-65 TJm
-(.) 2.49065 Tj
--786 TJm
-(At) 9.9626 Tj
--278 TJm
-(decompression) 59.7656 Tj
--278 TJm
-(time,) 20.2042 Tj
--284 TJm
-(the) 12.1743 Tj
--278 TJm
-(block) 22.1369 Tj
--278 TJm
-(size) 15.4918 Tj
--277 TJm
-(used) 18.2614 Tj
--278 TJm
-(for) 11.6164 Tj
--278 TJm
-(compression) 50.3609 Tj
-72 356.48 Td
-(is) 6.64505 Tj
--243 TJm
-(read) 17.1456 Tj
--242 TJm
-(from) 19.3673 Tj
--243 TJm
-(the) 12.1743 Tj
--242 TJm
-(header) 26.5503 Tj
--243 TJm
-(of) 8.29885 Tj
--242 TJm
-(the) 12.1743 Tj
--243 TJm
-(compressed) 47.0334 Tj
--242 TJm
-(\002le,) 15.2229 Tj
--244 TJm
-(and) 14.386 Tj
-[1 0 0 1 275.174 356.48] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -275.174 -356.48] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-275.174 356.48 Td
-/F134_0 9.9626 Tf
-(bunzip2) 41.8429 Tj
-[1 0 0 1 317.017 356.48] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -317.017 -356.48] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-319.433 356.48 Td
-/F130_0 9.9626 Tf
-(then) 17.1556 Tj
--243 TJm
-(all) 9.9626 Tj
-1 TJm
-(o) 4.9813 Tj
--1 TJm
-(c) 4.42339 Tj
-1 TJm
-(ates) 15.4918 Tj
--243 TJm
-(itself) 19.9252 Tj
--242 TJm
-(just) 14.396 Tj
--243 TJm
-(enough) 29.3299 Tj
--243 TJm
-(memory) 33.2053 Tj
--242 TJm
-(to) 7.7509 Tj
--243 TJm
-(decompress) 47.0334 Tj
-72 344.525 Td
-(the) 12.1743 Tj
--303 TJm
-(\002le.) 15.2229 Tj
--940 TJm
-(Since) 22.1369 Tj
--304 TJm
-(block) 22.1369 Tj
--303 TJm
-(sizes) 19.3673 Tj
--303 TJm
-(are) 12.1643 Tj
--303 TJm
-(stored) 24.3486 Tj
--304 TJm
-(in) 7.7509 Tj
--303 TJm
-(compressed) 47.0334 Tj
--303 TJm
-(\002les,) 19.0983 Tj
--317 TJm
-(it) 5.53921 Tj
--303 TJm
-(follo) 18.8194 Tj
-25 TJm
-(ws) 11.0684 Tj
--304 TJm
-(that) 14.9439 Tj
--303 TJm
-(the) 12.1743 Tj
--303 TJm
-(\003ags) 18.8194 Tj
-[1 0 0 1 406.35 344.525] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -406.35 -344.525] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-406.35 344.525 Td
-/F134_0 9.9626 Tf
-(-1) 11.9551 Tj
-[1 0 0 1 418.305 344.525] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -418.305 -344.525] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-421.327 344.525 Td
-/F130_0 9.9626 Tf
-(to) 7.7509 Tj
-[1 0 0 1 432.1 344.525] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -432.1 -344.525] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-432.1 344.525 Td
-/F134_0 9.9626 Tf
-(-9) 11.9551 Tj
-[1 0 0 1 444.055 344.525] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -444.055 -344.525] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-447.077 344.525 Td
-/F130_0 9.9626 Tf
-(are) 12.1643 Tj
--303 TJm
-(irrele) 21.0211 Tj
-25 TJm
-(v) 4.9813 Tj
-25 TJm
-(ant) 12.1743 Tj
--304 TJm
-(to) 7.7509 Tj
--303 TJm
-(and) 14.386 Tj
--303 TJm
-(so) 8.85675 Tj
-72 332.57 Td
-(ignored) 30.4357 Tj
--250 TJm
-(during) 26.0123 Tj
--250 TJm
-(decompression.) 62.2563 Tj
-[1 0 0 1 72 330.413] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.9626] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -320.45] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 310.652 Td
-/F130_0 9.9626 Tf
-(Compression) 52.5826 Tj
--250 TJm
-(and) 14.386 Tj
--250 TJm
-(decompression) 59.7656 Tj
--250 TJm
-(requirements,) 54.5054 Tj
--250 TJm
-(in) 7.7509 Tj
--250 TJm
-(bytes,) 23.5217 Tj
--250 TJm
-(can) 13.8281 Tj
--250 TJm
-(be) 9.40469 Tj
--250 TJm
-(estimated) 38.1866 Tj
--250 TJm
-(as:) 11.0684 Tj
-[1 0 0 1 72 308.495] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -60.7721] cm
-/DeviceRGB {} cs
-[0.94899 0.94899 0.976456] sc
-/DeviceRGB {} CS
-[0.94899 0.94899 0.976456] SC
-0 0 468 59.7758 re
-f
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 3.5866] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 56.1893] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 18 -8.3686] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -90 -299.13] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-90 299.13 Td
-/F134_0 9.9626 Tf
-(Compression:) 71.7307 Tj
--1278 TJm
-(400k) 23.9102 Tj
--426 TJm
-(+) 5.97756 Tj
--426 TJm
-(\() 5.97756 Tj
--426 TJm
-(8) 5.97756 Tj
--426 TJm
-(x) 5.97756 Tj
--426 TJm
-(block) 29.8878 Tj
--426 TJm
-(size) 23.9102 Tj
--426 TJm
-(\)) 5.97756 Tj
-90 275.22 Td
-(Decompression:) 83.6858 Tj
--426 TJm
-(100k) 23.9102 Tj
--426 TJm
-(+) 5.97756 Tj
--426 TJm
-(\() 5.97756 Tj
--426 TJm
-(4) 5.97756 Tj
--426 TJm
-(x) 5.97756 Tj
--426 TJm
-(block) 29.8878 Tj
--426 TJm
-(size) 23.9102 Tj
--426 TJm
-(\),) 11.9551 Tj
--426 TJm
-(or) 11.9551 Tj
-153.66 263.265 Td
-(100k) 23.9102 Tj
--426 TJm
-(+) 5.97756 Tj
--426 TJm
-(\() 5.97756 Tj
--426 TJm
-(2.5) 17.9327 Tj
--426 TJm
-(x) 5.97756 Tj
--426 TJm
-(block) 29.8878 Tj
--426 TJm
-(size) 23.9102 Tj
--426 TJm
-(\)) 5.97756 Tj
-[1 0 0 1 72 247.723] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 468 3.5866] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -468 -13.5492] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -237.761] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 225.805 Td
-/F130_0 9.9626 Tf
-(Lar) 13.8281 Tj
-18 TJm
-(ger) 12.7222 Tj
--292 TJm
-(block) 22.1369 Tj
--292 TJm
-(sizes) 19.3673 Tj
--291 TJm
-(gi) 7.7509 Tj
-25 TJm
-(v) 4.9813 Tj
-15 TJm
-(e) 4.42339 Tj
--292 TJm
-(rapidly) 28.224 Tj
--292 TJm
-(diminishing) 47.6113 Tj
--292 TJm
-(mar) 15.4918 Tj
-18 TJm
-(ginal) 19.9252 Tj
--291 TJm
-(returns.) 30.1568 Tj
--871 TJm
-(Most) 20.4831 Tj
--292 TJm
-(of) 8.29885 Tj
--291 TJm
-(the) 12.1743 Tj
--292 TJm
-(compression) 50.3609 Tj
--292 TJm
-(comes) 25.4544 Tj
--292 TJm
-(from) 19.3673 Tj
--291 TJm
-(the) 12.1743 Tj
--292 TJm
-(\002rst) 15.5018 Tj
--292 TJm
-(tw) 9.9626 Tj
-10 TJm
-(o) 4.9813 Tj
--292 TJm
-(or) 8.29885 Tj
-72 213.85 Td
-(three) 19.9152 Tj
--232 TJm
-(hundred) 32.6474 Tj
--232 TJm
-(k) 4.9813 Tj
--232 TJm
-(of) 8.29885 Tj
--232 TJm
-(block) 22.1369 Tj
--232 TJm
-(size,) 17.9825 Tj
--235 TJm
-(a) 4.42339 Tj
--232 TJm
-(f) 3.31755 Tj
-10 TJm
-(act) 11.6164 Tj
--232 TJm
-(w) 7.193 Tj
-10 TJm
-(orth) 16.0497 Tj
--232 TJm
-(bearing) 29.8778 Tj
--232 TJm
-(in) 7.7509 Tj
--232 TJm
-(mind) 20.4831 Tj
--232 TJm
-(when) 21.579 Tj
--231 TJm
-(using) 21.589 Tj
-[1 0 0 1 354.025 213.85] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -354.025 -213.85] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-354.025 213.85 Td
-/F134_0 9.9626 Tf
-(bzip2) 29.8878 Tj
-[1 0 0 1 383.913 213.85] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -383.913 -213.85] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-386.223 213.85 Td
-/F130_0 9.9626 Tf
-(on) 9.9626 Tj
--232 TJm
-(small) 21.589 Tj
--232 TJm
-(machines.) 40.1194 Tj
--304 TJm
-(It) 6.08715 Tj
--232 TJm
-(is) 6.64505 Tj
--232 TJm
-(also) 16.0497 Tj
--231 TJm
-(important) 38.7446 Tj
-72 201.895 Td
-(to) 7.7509 Tj
--250 TJm
-(appreciate) 40.9363 Tj
--250 TJm
-(that) 14.9439 Tj
--250 TJm
-(the) 12.1743 Tj
--250 TJm
-(decompression) 59.7656 Tj
--250 TJm
-(memory) 33.2053 Tj
--250 TJm
-(requirement) 48.1393 Tj
--250 TJm
-(is) 6.64505 Tj
--250 TJm
-(set) 11.0684 Tj
--250 TJm
-(at) 7.193 Tj
--250 TJm
-(compression) 50.3609 Tj
--250 TJm
-(time) 17.7135 Tj
--250 TJm
-(by) 9.9626 Tj
--250 TJm
-(the) 12.1743 Tj
--250 TJm
-(choice) 26.0024 Tj
--250 TJm
-(of) 8.29885 Tj
--250 TJm
-(block) 22.1369 Tj
--250 TJm
-(size.) 17.9825 Tj
-[1 0 0 1 72 199.738] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.9627] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -189.776] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 179.977 Td
-/F130_0 9.9626 Tf
-(F) 5.53921 Tj
-15 TJm
-(or) 8.29885 Tj
--388 TJm
-(\002les) 16.6077 Tj
--389 TJm
-(compressed) 47.0334 Tj
--388 TJm
-(with) 17.7135 Tj
--389 TJm
-(the) 12.1743 Tj
--388 TJm
-(def) 12.7222 Tj
-10 TJm
-(ault) 14.9439 Tj
--389 TJm
-(900k) 19.9252 Tj
--388 TJm
-(block) 22.1369 Tj
--389 TJm
-(size,) 17.9825 Tj
-[1 0 0 1 302.002 179.977] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -302.002 -179.977] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-302.002 179.977 Td
-/F134_0 9.9626 Tf
-(bunzip2) 41.8429 Tj
-[1 0 0 1 343.846 179.977] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -343.846 -179.977] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-347.715 179.977 Td
-/F130_0 9.9626 Tf
-(will) 15.5018 Tj
--388 TJm
-(require) 28.2141 Tj
--389 TJm
-(about) 22.1369 Tj
--388 TJm
-(3700) 19.9252 Tj
--389 TJm
-(kbytes) 26.0123 Tj
--388 TJm
-(to) 7.7509 Tj
--389 TJm
-(decompress.) 49.5241 Tj
-72 168.022 Td
-(T) 6.08715 Tj
-80 TJm
-(o) 4.9813 Tj
--424 TJm
-(support) 29.8878 Tj
--425 TJm
-(decompression) 59.7656 Tj
--424 TJm
-(of) 8.29885 Tj
--424 TJm
-(an) 9.40469 Tj
-15 TJm
-(y) 4.9813 Tj
--425 TJm
-(\002l) 8.30881 Tj
-1 TJm
-(e) 4.42339 Tj
--425 TJm
-(on) 9.9626 Tj
--424 TJm
-(a) 4.42339 Tj
--424 TJm
-(4) 4.9813 Tj
--425 TJm
-(me) 12.1743 Tj
-15 TJm
-(g) 4.9813 Tj
-5 TJm
-(abyte) 21.579 Tj
--424 TJm
-(machine,) 36.2439 Tj
-[1 0 0 1 348.272 168.022] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -348.272 -168.022] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-348.272 168.022 Td
-/F134_0 9.9626 Tf
-(bunzip2) 41.8429 Tj
-[1 0 0 1 390.115 168.022] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -390.115 -168.022] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-394.342 168.022 Td
-/F130_0 9.9626 Tf
-(has) 13.2801 Tj
--424 TJm
-(an) 9.40469 Tj
--425 TJm
-(option) 25.4644 Tj
--424 TJm
-(to) 7.7509 Tj
--424 TJm
-(decompress) 47.0334 Tj
--424 TJm
-(using) 21.589 Tj
-72 156.067 Td
-(approximately) 57.5539 Tj
--281 TJm
-(half) 15.4918 Tj
--281 TJm
-(this) 14.396 Tj
--280 TJm
-(amount) 29.8878 Tj
--281 TJm
-(of) 8.29885 Tj
--281 TJm
-(memory) 33.2053 Tj
-65 TJm
-(,) 2.49065 Tj
--288 TJm
-(about) 22.1369 Tj
--281 TJm
-(2300) 19.9252 Tj
--281 TJm
-(kbytes.) 28.503 Tj
--805 TJm
-(Decompression) 61.9773 Tj
--280 TJm
-(speed) 22.6848 Tj
--281 TJm
-(is) 6.64505 Tj
--281 TJm
-(also) 16.0497 Tj
--281 TJm
-(halv) 17.1556 Tj
-15 TJm
-(ed,) 11.8953 Tj
--288 TJm
-(so) 8.85675 Tj
--281 TJm
-(you) 14.9439 Tj
--281 TJm
-(should) 26.5703 Tj
-72 144.112 Td
-(use) 13.2801 Tj
--250 TJm
-(this) 14.396 Tj
--250 TJm
-(option) 25.4644 Tj
--250 TJm
-(only) 17.7135 Tj
--250 TJm
-(where) 24.3386 Tj
--250 TJm
-(necessary) 38.7246 Tj
-65 TJm
-(.) 2.49065 Tj
--620 TJm
-(The) 15.4918 Tj
--250 TJm
-(rele) 14.9339 Tj
-25 TJm
-(v) 4.9813 Tj
-25 TJm
-(ant) 12.1743 Tj
--250 TJm
-(\003ag) 14.9439 Tj
--250 TJm
-(is) 6.64505 Tj
-[1 0 0 1 305.024 144.112] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -305.024 -144.112] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-305.024 144.112 Td
-/F134_0 9.9626 Tf
-(-s) 11.9551 Tj
-[1 0 0 1 316.979 144.112] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -316.979 -144.112] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-316.979 144.112 Td
-/F130_0 9.9626 Tf
-(.) 2.49065 Tj
-[1 0 0 1 72 141.955] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.9626] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -131.992] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 122.194 Td
-/F130_0 9.9626 Tf
-(In) 8.29885 Tj
--204 TJm
-(general,) 31.8106 Tj
--214 TJm
-(try) 11.0684 Tj
--204 TJm
-(and) 14.386 Tj
--205 TJm
-(use) 13.2801 Tj
--204 TJm
-(the) 12.1743 Tj
--204 TJm
-(lar) 10.5105 Tj
-18 TJm
-(gest) 16.0497 Tj
--205 TJm
-(block) 22.1369 Tj
--204 TJm
-(size) 15.4918 Tj
--205 TJm
-(memory) 33.2053 Tj
--204 TJm
-(constraints) 43.1679 Tj
--204 TJm
-(allo) 14.9439 Tj
-25 TJm
-(w) 7.193 Tj
-65 TJm
-(,) 2.49065 Tj
--214 TJm
-(since) 20.4731 Tj
--204 TJm
-(that) 14.9439 Tj
--205 TJm
-(maximises) 42.62 Tj
--204 TJm
-(the) 12.1743 Tj
--204 TJm
-(compression) 50.3609 Tj
--205 TJm
-(achie) 21.0211 Tj
-25 TJm
-(v) 4.9813 Tj
-15 TJm
-(ed.) 11.8953 Tj
-72 110.239 Td
-(Compression) 52.5826 Tj
--250 TJm
-(and) 14.386 Tj
--250 TJm
-(decompression) 59.7656 Tj
--250 TJm
-(speed) 22.6848 Tj
--250 TJm
-(are) 12.1643 Tj
--250 TJm
-(virtually) 33.7633 Tj
--250 TJm
-(unaf) 17.7035 Tj
-25 TJm
-(fected) 24.3386 Tj
--250 TJm
-(by) 9.9626 Tj
--250 TJm
-(block) 22.1369 Tj
--250 TJm
-(size.) 17.9825 Tj
-[1 0 0 1 72 108.082] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.9627] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -98.1193] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 88.321 Td
-/F130_0 9.9626 Tf
-(Another) 32.6474 Tj
--296 TJm
-(signi\002cant) 41.5142 Tj
--296 TJm
-(point) 20.4831 Tj
--295 TJm
-(applies) 28.224 Tj
--296 TJm
-(to) 7.7509 Tj
--296 TJm
-(\002les) 16.6077 Tj
--296 TJm
-(which) 24.3486 Tj
--296 TJm
-(\002t) 8.30881 Tj
--296 TJm
-(in) 7.7509 Tj
--296 TJm
-(a) 4.42339 Tj
--295 TJm
-(single) 23.8007 Tj
--296 TJm
-(block) 22.1369 Tj
--296 TJm
-(--) 6.63509 Tj
--296 TJm
-(that) 14.9439 Tj
--296 TJm
-(means) 25.4544 Tj
--296 TJm
-(most) 19.3773 Tj
--295 TJm
-(\002les) 16.6077 Tj
--296 TJm
-(you') 18.2614 Tj
-50 TJm
-(d) 4.9813 Tj
--296 TJm
-(encounter) 39.2825 Tj
--296 TJm
-(using) 21.589 Tj
--296 TJm
-(a) 4.42339 Tj
-72 76.3658 Td
-(lar) 10.5105 Tj
-18 TJm
-(ge) 9.40469 Tj
--290 TJm
-(block) 22.1369 Tj
--290 TJm
-(size.) 17.9825 Tj
--859 TJm
-(The) 15.4918 Tj
--290 TJm
-(amount) 29.8878 Tj
--290 TJm
-(of) 8.29885 Tj
--290 TJm
-(real) 14.9339 Tj
--290 TJm
-(memory) 33.2053 Tj
--289 TJm
-(touched) 31.5416 Tj
--290 TJm
-(is) 6.64505 Tj
--290 TJm
-(proportional) 49.2551 Tj
--290 TJm
-(to) 7.7509 Tj
--290 TJm
-(the) 12.1743 Tj
--290 TJm
-(size) 15.4918 Tj
--290 TJm
-(of) 8.29885 Tj
--290 TJm
-(the) 12.1743 Tj
--289 TJm
-(\002le,) 15.2229 Tj
--300 TJm
-(since) 20.4731 Tj
--290 TJm
-(the) 12.1743 Tj
--290 TJm
-(\002le) 12.7322 Tj
--290 TJm
-(is) 6.64505 Tj
--290 TJm
-(smaller) 29.3299 Tj
-[1 0 0 1 72 50.8518] cm
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-[1 0 0 1 1.8929 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 374.394 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 6.8541] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 43.0633 -6.7545] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -496.332 -50.9514] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-539.395 50.9514 Td
-/F130_0 9.9626 Tf
-(5) 4.9813 Tj
-[1 0 0 1 453.269 50.8518] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 93.5985 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 6.2765 0] cm
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-[1 0 0 1 -13.1436 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-Q
-showpage
-%%PageTrailer
-pdfEndPage
-%%Page: 9 9
-%%BeginPageSetup
-%%PageOrientation: Portrait
-pdfStartPage
-0 0 612 792 re W
-%%EndPageSetup
-[] 0 d
-1 i
-0 j
-0 J
-10 M
-1 w
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-false op
-false OP
-0 0 612 792 re
-W
-q
-[1 0 0 1 72 741.554] cm
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-[1 0 0 1 1.8929 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 14.4459] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 187.197 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 -8.9114] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 8.9114] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 105.519 -6.7546] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -371.59 -749.245] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-477.109 749.245 Td
-/F130_0 9.9626 Tf
-(Ho) 12.1743 Tj
-25 TJm
-(w) 7.193 Tj
--250 TJm
-(to) 7.7509 Tj
--250 TJm
-(use) 13.2801 Tj
--250 TJm
-(bzip2) 22.1369 Tj
-[1 0 0 1 266.071 747.089] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 280.796 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -472.974 -5.0363] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -0.4981] cm
-q
-[] 0 d
-0 J
-0.4981 w
-0 0.2491 m
-475.465 0.2491 l
-S
-Q
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 479.251 0] cm
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-[1 0 0 1 -13.1436 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -540 -741.554] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 710.037 Td
-/F130_0 9.9626 Tf
-(than) 17.1556 Tj
--362 TJm
-(a) 4.42339 Tj
--362 TJm
-(block.) 24.6275 Tj
--1293 TJm
-(F) 5.53921 Tj
-15 TJm
-(or) 8.29885 Tj
--362 TJm
-(e) 4.42339 Tj
-15 TJm
-(xample,) 31.8205 Tj
--390 TJm
-(compressing) 50.3609 Tj
--362 TJm
-(a) 4.42339 Tj
--362 TJm
-(\002le) 12.7322 Tj
--362 TJm
-(20,000) 27.3972 Tj
--362 TJm
-(bytes) 21.031 Tj
--362 TJm
-(long) 17.7135 Tj
--362 TJm
-(with) 17.7135 Tj
--362 TJm
-(the) 12.1743 Tj
--362 TJm
-(\003ag) 14.9439 Tj
-[1 0 0 1 406.528 710.037] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -406.528 -710.037] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-406.528 710.037 Td
-/F134_0 9.9626 Tf
-(-9) 11.9551 Tj
-[1 0 0 1 418.483 710.037] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -418.483 -710.037] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-422.09 710.037 Td
-/F130_0 9.9626 Tf
-(will) 15.5018 Tj
--362 TJm
-(cause) 22.1269 Tj
--362 TJm
-(the) 12.1743 Tj
--362 TJm
-(compressor) 45.9276 Tj
--362 TJm
-(to) 7.7509 Tj
-72 698.082 Td
-(allocate) 30.9837 Tj
--271 TJm
-(around) 27.6661 Tj
--272 TJm
-(7600k) 24.9065 Tj
--271 TJm
-(of) 8.29885 Tj
--272 TJm
-(memory) 33.2053 Tj
-65 TJm
-(,) 2.49065 Tj
--277 TJm
-(b) 4.9813 Tj
-20 TJm
-(ut) 7.7509 Tj
--271 TJm
-(only) 17.7135 Tj
--272 TJm
-(touch) 22.1369 Tj
--271 TJm
-(400k) 19.9252 Tj
--272 TJm
-(+) 5.61891 Tj
--271 TJm
-(20000) 24.9065 Tj
--272 TJm
-(*) 4.9813 Tj
--271 TJm
-(8) 4.9813 Tj
--272 TJm
-(=) 5.61891 Tj
--271 TJm
-(560) 14.9439 Tj
--272 TJm
-(kbytes) 26.0123 Tj
--271 TJm
-(of) 8.29885 Tj
--272 TJm
-(it.) 8.02986 Tj
--748 TJm
-(Similarly) 37.0908 Tj
-65 TJm
-(,) 2.49065 Tj
--277 TJm
-(the) 12.1743 Tj
--272 TJm
-(decompressor) 55.3323 Tj
-72 686.127 Td
-(will) 15.5018 Tj
--250 TJm
-(allocate) 30.9837 Tj
--250 TJm
-(3700k) 24.9065 Tj
--250 TJm
-(b) 4.9813 Tj
-20 TJm
-(ut) 7.7509 Tj
--250 TJm
-(only) 17.7135 Tj
--250 TJm
-(touch) 22.1369 Tj
--250 TJm
-(100k) 19.9252 Tj
--250 TJm
-(+) 5.61891 Tj
--250 TJm
-(20000) 24.9065 Tj
--250 TJm
-(*) 4.9813 Tj
--250 TJm
-(4) 4.9813 Tj
--250 TJm
-(=) 5.61891 Tj
--250 TJm
-(180) 14.9439 Tj
--250 TJm
-(kbytes.) 28.503 Tj
-[1 0 0 1 72 683.97] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.9626] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -674.008] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 664.209 Td
-/F130_0 9.9626 Tf
-(Here) 19.3573 Tj
--293 TJm
-(is) 6.64505 Tj
--294 TJm
-(a) 4.42339 Tj
--293 TJm
-(table) 19.3673 Tj
--294 TJm
-(which) 24.3486 Tj
--293 TJm
-(summarises) 47.0434 Tj
--294 TJm
-(the) 12.1743 Tj
--293 TJm
-(maximum) 40.4083 Tj
--294 TJm
-(memory) 33.2053 Tj
--293 TJm
-(usage) 22.6848 Tj
--294 TJm
-(for) 11.6164 Tj
--293 TJm
-(dif) 11.0684 Tj
-25 TJm
-(ferent) 23.2328 Tj
--294 TJm
-(block) 22.1369 Tj
--293 TJm
-(sizes.) 21.8579 Tj
--881 TJm
-(Also) 18.8194 Tj
--293 TJm
-(recorded) 34.8492 Tj
--294 TJm
-(is) 6.64505 Tj
--293 TJm
-(the) 12.1743 Tj
--294 TJm
-(total) 17.7135 Tj
-72 652.254 Td
-(compressed) 47.0334 Tj
--289 TJm
-(size) 15.4918 Tj
--289 TJm
-(for) 11.6164 Tj
--289 TJm
-(14) 9.9626 Tj
--289 TJm
-(\002les) 16.6077 Tj
--290 TJm
-(of) 8.29885 Tj
--289 TJm
-(the) 12.1743 Tj
--289 TJm
-(Calg) 18.8194 Tj
-5 TJm
-(ary) 12.7222 Tj
--289 TJm
-(T) 6.08715 Tj
-70 TJm
-(e) 4.42339 Tj
-15 TJm
-(xt) 7.7509 Tj
--289 TJm
-(Compression) 52.5826 Tj
--289 TJm
-(Corpus) 28.782 Tj
--289 TJm
-(totalling) 33.2153 Tj
--289 TJm
-(3,141,622) 39.8504 Tj
--290 TJm
-(bytes.) 23.5217 Tj
--854 TJm
-(This) 17.7135 Tj
--290 TJm
-(column) 29.8878 Tj
--289 TJm
-(gi) 7.7509 Tj
-25 TJm
-(v) 4.9813 Tj
-15 TJm
-(es) 8.29885 Tj
-72 640.299 Td
-(some) 21.031 Tj
--253 TJm
-(feel) 14.9339 Tj
--253 TJm
-(for) 11.6164 Tj
--253 TJm
-(ho) 9.9626 Tj
-25 TJm
-(w) 7.193 Tj
--253 TJm
-(compression) 50.3609 Tj
--253 TJm
-(v) 4.9813 Tj
-25 TJm
-(aries) 18.8094 Tj
--253 TJm
-(with) 17.7135 Tj
--253 TJm
-(block) 22.1369 Tj
--253 TJm
-(size.) 17.9825 Tj
--638 TJm
-(These) 23.7907 Tj
--253 TJm
-(\002gures) 27.1182 Tj
--253 TJm
-(tend) 17.1556 Tj
--254 TJm
-(to) 7.7509 Tj
--253 TJm
-(understate) 40.9463 Tj
--253 TJm
-(the) 12.1743 Tj
--253 TJm
-(adv) 14.386 Tj
-25 TJm
-(antage) 26.0024 Tj
--253 TJm
-(of) 8.29885 Tj
--253 TJm
-(lar) 10.5105 Tj
-18 TJm
-(ger) 12.7222 Tj
--253 TJm
-(block) 22.1369 Tj
-72 628.344 Td
-(sizes) 19.3673 Tj
--250 TJm
-(for) 11.6164 Tj
--250 TJm
-(lar) 10.5105 Tj
-18 TJm
-(ger) 12.7222 Tj
--250 TJm
-(\002les,) 19.0983 Tj
--250 TJm
-(since) 20.4731 Tj
--250 TJm
-(the) 12.1743 Tj
--250 TJm
-(Corpus) 28.782 Tj
--250 TJm
-(is) 6.64505 Tj
--250 TJm
-(dominated) 42.0621 Tj
--250 TJm
-(by) 9.9626 Tj
--250 TJm
-(smaller) 29.3299 Tj
--250 TJm
-(\002les.) 19.0983 Tj
-[1 0 0 1 72 626.187] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -156.413] cm
-/DeviceRGB {} cs
-[0.94899 0.94899 0.976456] sc
-/DeviceRGB {} CS
-[0.94899 0.94899 0.976456] SC
-0 0 468 155.417 re
-f
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 3.5865] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 151.831] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 18 -8.3686] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -90 -616.822] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-123.952 616.822 Td
-/F134_0 9.9626 Tf
-(Compress) 47.8205 Tj
--1278 TJm
-(Decompress) 59.7756 Tj
--1278 TJm
-(Decompress) 59.7756 Tj
--1278 TJm
-(Corpus) 35.8654 Tj
-90 604.867 Td
-(Flag) 23.9102 Tj
--2130 TJm
-(usage) 29.8878 Tj
--2556 TJm
-(usage) 29.8878 Tj
--2982 TJm
-(-s) 11.9551 Tj
--426 TJm
-(usage) 29.8878 Tj
--2130 TJm
-(Size) 23.9102 Tj
-94.244 580.956 Td
-(-1) 11.9551 Tj
--2556 TJm
-(1200k) 29.8878 Tj
--2982 TJm
-(500k) 23.9102 Tj
--3834 TJm
-(350k) 23.9102 Tj
--2556 TJm
-(914704) 35.8654 Tj
-94.244 569.001 Td
-(-2) 11.9551 Tj
--2556 TJm
-(2000k) 29.8878 Tj
--2982 TJm
-(900k) 23.9102 Tj
--3834 TJm
-(600k) 23.9102 Tj
--2556 TJm
-(877703) 35.8654 Tj
-94.244 557.046 Td
-(-3) 11.9551 Tj
--2556 TJm
-(2800k) 29.8878 Tj
--2556 TJm
-(1300k) 29.8878 Tj
--3834 TJm
-(850k) 23.9102 Tj
--2556 TJm
-(860338) 35.8654 Tj
-94.244 545.091 Td
-(-4) 11.9551 Tj
--2556 TJm
-(3600k) 29.8878 Tj
--2556 TJm
-(1700k) 29.8878 Tj
--3408 TJm
-(1100k) 29.8878 Tj
--2556 TJm
-(846899) 35.8654 Tj
-94.244 533.136 Td
-(-5) 11.9551 Tj
--2556 TJm
-(4400k) 29.8878 Tj
--2556 TJm
-(2100k) 29.8878 Tj
--3408 TJm
-(1350k) 29.8878 Tj
--2556 TJm
-(845160) 35.8654 Tj
-94.244 521.181 Td
-(-6) 11.9551 Tj
--2556 TJm
-(5200k) 29.8878 Tj
--2556 TJm
-(2500k) 29.8878 Tj
--3408 TJm
-(1600k) 29.8878 Tj
--2556 TJm
-(838626) 35.8654 Tj
-94.244 509.225 Td
-(-7) 11.9551 Tj
--2556 TJm
-(6100k) 29.8878 Tj
--2556 TJm
-(2900k) 29.8878 Tj
--3408 TJm
-(1850k) 29.8878 Tj
--2556 TJm
-(834096) 35.8654 Tj
-94.244 497.27 Td
-(-8) 11.9551 Tj
--2556 TJm
-(6800k) 29.8878 Tj
--2556 TJm
-(3300k) 29.8878 Tj
--3408 TJm
-(2100k) 29.8878 Tj
--2556 TJm
-(828642) 35.8654 Tj
-94.244 485.315 Td
-(-9) 11.9551 Tj
--2556 TJm
-(7600k) 29.8878 Tj
--2556 TJm
-(3700k) 29.8878 Tj
--3408 TJm
-(2350k) 29.8878 Tj
--2556 TJm
-(828642) 35.8654 Tj
-[1 0 0 1 72 469.773] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 468 3.5866] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -468 -3.5866] cm
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.9626] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -459.811] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 435.021 Td
-/F122_0 20.6585 Tf
-(2.6.) 34.4584 Tj
--278 TJm
-(RECO) 59.6824 Tj
-50 TJm
-(VERING) 79.2047 Tj
--278 TJm
-(D) 14.9154 Tj
-40 TJm
-(A) 14.9154 Tj
-90 TJm
-(T) 12.6223 Tj
-90 TJm
-(A) 14.9154 Tj
--278 TJm
-(FR) 27.5378 Tj
-20 TJm
-(OM) 33.2808 Tj
--278 TJm
-(D) 14.9154 Tj
-40 TJm
-(AMA) 47.0394 Tj
-50 TJm
-(GED) 44.767 Tj
-72 410.23 Td
-(FILES) 58.5462 Tj
-[1 0 0 1 72 409.972] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.9626] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -400.01] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 388.312 Td
-/F134_0 9.9626 Tf
-(bzip2) 29.8878 Tj
-[1 0 0 1 101.888 388.312] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -101.888 -388.312] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-105.138 388.312 Td
-/F130_0 9.9626 Tf
-(compresses) 45.9276 Tj
--326 TJm
-(\002les) 16.6077 Tj
--326 TJm
-(in) 7.7509 Tj
--326 TJm
-(blocks,) 28.503 Tj
--346 TJm
-(usually) 28.782 Tj
--326 TJm
-(900kbytes) 40.9562 Tj
--326 TJm
-(long.) 20.2042 Tj
--1077 TJm
-(Each) 19.9152 Tj
--326 TJm
-(block) 22.1369 Tj
--327 TJm
-(is) 6.64505 Tj
--326 TJm
-(handled) 31.5416 Tj
--326 TJm
-(independently) 56.4481 Tj
-65 TJm
-(.) 2.49065 Tj
--1077 TJm
-(If) 6.63509 Tj
--326 TJm
-(a) 4.42339 Tj
--326 TJm
-(media) 24.3486 Tj
--326 TJm
-(or) 8.29885 Tj
-72 376.357 Td
-(transmission) 50.3709 Tj
--319 TJm
-(error) 19.3573 Tj
--318 TJm
-(causes) 26.0024 Tj
--319 TJm
-(a) 4.42339 Tj
--318 TJm
-(multi-block) 46.4955 Tj
-[1 0 0 1 234.518 376.357] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -234.518 -376.357] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-234.518 376.357 Td
-/F134_0 9.9626 Tf
-(.bz2) 23.9102 Tj
-[1 0 0 1 258.429 376.357] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -258.429 -376.357] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-261.603 376.357 Td
-/F130_0 9.9626 Tf
-(\002le) 12.7322 Tj
--319 TJm
-(to) 7.7509 Tj
--318 TJm
-(become) 30.9837 Tj
--319 TJm
-(damaged,) 38.4556 Tj
--336 TJm
-(it) 5.53921 Tj
--318 TJm
-(may) 17.1556 Tj
--319 TJm
-(be) 9.40469 Tj
--318 TJm
-(possible) 32.6574 Tj
--319 TJm
-(to) 7.7509 Tj
--318 TJm
-(reco) 17.1456 Tj
-15 TJm
-(v) 4.9813 Tj
-15 TJm
-(er) 7.74094 Tj
--319 TJm
-(data) 16.5977 Tj
--319 TJm
-(from) 19.3673 Tj
--318 TJm
-(the) 12.1743 Tj
-72 364.402 Td
-(undamaged) 45.9276 Tj
--250 TJm
-(blocks) 26.0123 Tj
--250 TJm
-(in) 7.7509 Tj
--250 TJm
-(the) 12.1743 Tj
--250 TJm
-(\002le.) 15.2229 Tj
-[1 0 0 1 72 362.245] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.9627] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -352.283] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 342.484 Td
-/F130_0 9.9626 Tf
-(The) 15.4918 Tj
--358 TJm
-(compressed) 47.0334 Tj
--357 TJm
-(representation) 56.4381 Tj
--358 TJm
-(of) 8.29885 Tj
--357 TJm
-(each) 18.2515 Tj
--358 TJm
-(block) 22.1369 Tj
--358 TJm
-(is) 6.64505 Tj
--357 TJm
-(delimited) 37.6387 Tj
--358 TJm
-(by) 9.9626 Tj
--357 TJm
-(a) 4.42339 Tj
--358 TJm
-(48-bit) 23.8007 Tj
--358 TJm
-(pattern,) 30.1568 Tj
--384 TJm
-(which) 24.3486 Tj
--358 TJm
-(mak) 17.1556 Tj
-10 TJm
-(es) 8.29885 Tj
--357 TJm
-(it) 5.53921 Tj
--358 TJm
-(possible) 32.6574 Tj
--357 TJm
-(to) 7.7509 Tj
--358 TJm
-(\002nd) 15.5018 Tj
--358 TJm
-(the) 12.1743 Tj
-72 330.529 Td
-(block) 22.1369 Tj
--286 TJm
-(boundaries) 43.7159 Tj
--286 TJm
-(wit) 12.7322 Tj
-1 TJm
-(h) 4.9813 Tj
--286 TJm
-(reasonable) 42.6001 Tj
--286 TJm
-(certainty) 34.8591 Tj
-65 TJm
-(.) 2.49065 Tj
--835 TJm
-(Each) 19.9152 Tj
--285 TJm
-(block) 22.1369 Tj
--286 TJm
-(also) 16.0497 Tj
--286 TJm
-(carries) 26.5503 Tj
--286 TJm
-(its) 9.41466 Tj
--285 TJm
-(o) 4.9813 Tj
-25 TJm
-(wn) 12.1743 Tj
--286 TJm
-(32-bit) 23.8007 Tj
--286 TJm
-(CRC,) 22.4258 Tj
--286 TJm
-(so) 8.85675 Tj
--285 TJm
-(damaged) 35.965 Tj
--286 TJm
-(blocks) 26.0123 Tj
--286 TJm
-(can) 13.8281 Tj
--286 TJm
-(be) 9.40469 Tj
-72 318.574 Td
-(distinguished) 53.1405 Tj
--250 TJm
-(from) 19.3673 Tj
--250 TJm
-(undamaged) 45.9276 Tj
--250 TJm
-(ones.) 20.7521 Tj
-[1 0 0 1 72 316.417] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.9626] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -306.455] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 296.656 Td
-/F134_0 9.9626 Tf
-(bzip2recover) 71.7307 Tj
-[1 0 0 1 143.731 296.656] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -143.731 -296.656] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-146.448 296.656 Td
-/F130_0 9.9626 Tf
-(is) 6.64505 Tj
--273 TJm
-(a) 4.42339 Tj
--272 TJm
-(simple) 26.5703 Tj
--273 TJm
-(program) 33.7533 Tj
--273 TJm
-(whose) 25.4544 Tj
--272 TJm
-(purpose) 31.5416 Tj
--273 TJm
-(is) 6.64505 Tj
--273 TJm
-(to) 7.7509 Tj
--272 TJm
-(search) 25.4445 Tj
--273 TJm
-(for) 11.6164 Tj
--273 TJm
-(blocks) 26.0123 Tj
--272 TJm
-(in) 7.7509 Tj
-[1 0 0 1 392.655 296.656] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -392.655 -296.656] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-392.655 296.656 Td
-/F134_0 9.9626 Tf
-(.bz2) 23.9102 Tj
-[1 0 0 1 416.566 296.656] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -416.566 -296.656] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-419.282 296.656 Td
-/F130_0 9.9626 Tf
-(\002les,) 19.0983 Tj
--278 TJm
-(and) 14.386 Tj
--273 TJm
-(write) 20.4731 Tj
--273 TJm
-(each) 18.2515 Tj
--272 TJm
-(block) 22.1369 Tj
--273 TJm
-(out) 12.7322 Tj
-72 284.701 Td
-(into) 15.5018 Tj
--254 TJm
-(its) 9.41466 Tj
--255 TJm
-(o) 4.9813 Tj
-25 TJm
-(wn) 12.1743 Tj
-[1 0 0 1 121.43 284.701] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -121.43 -284.701] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-121.43 284.701 Td
-/F134_0 9.9626 Tf
-(.bz2) 23.9102 Tj
-[1 0 0 1 145.34 284.701] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -145.34 -284.701] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-147.875 284.701 Td
-/F130_0 9.9626 Tf
-(\002le.) 15.2229 Tj
--647 TJm
-(Y) 7.193 Tj
-110 TJm
-(ou) 9.9626 Tj
--255 TJm
-(can) 13.8281 Tj
--254 TJm
-(then) 17.1556 Tj
--255 TJm
-(use) 13.2801 Tj
-[1 0 0 1 240.01 284.701] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -240.01 -284.701] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-240.01 284.701 Td
-/F134_0 9.9626 Tf
-(bzip2) 29.8878 Tj
--600 TJm
-(-t) 11.9551 Tj
-[1 0 0 1 287.831 284.701] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -287.831 -284.701] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-290.367 284.701 Td
-/F130_0 9.9626 Tf
-(to) 7.7509 Tj
--255 TJm
-(t) 2.7696 Tj
-1 TJm
-(est) 11.0684 Tj
--255 TJm
-(the) 12.1743 Tj
--254 TJm
-(inte) 14.9439 Tj
-15 TJm
-(grity) 18.8194 Tj
--255 TJm
-(of) 8.29885 Tj
--254 TJm
-(the) 12.1743 Tj
--255 TJm
-(resulting) 34.8691 Tj
--254 TJm
-(\002les,) 19.0983 Tj
--256 TJm
-(and) 14.386 Tj
--255 TJm
-(decompress) 47.0334 Tj
--254 TJm
-(those) 21.031 Tj
-72 272.746 Td
-(which) 24.3486 Tj
--250 TJm
-(are) 12.1643 Tj
--250 TJm
-(undamaged.) 48.4182 Tj
-[1 0 0 1 72 270.589] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.9627] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -260.626] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 250.828 Td
-/F134_0 9.9626 Tf
-(bzip2recover) 71.7307 Tj
-[1 0 0 1 143.731 250.828] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -143.731 -250.828] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-150.099 250.828 Td
-/F130_0 9.9626 Tf
-(tak) 12.1743 Tj
-10 TJm
-(es) 8.29885 Tj
--639 TJm
-(a) 4.42339 Tj
--639 TJm
-(single) 23.8007 Tj
--639 TJm
-(ar) 7.74094 Tj
-18 TJm
-(gument,) 32.3785 Tj
--737 TJm
-(the) 12.1743 Tj
--639 TJm
-(name) 21.579 Tj
--639 TJm
-(of) 8.29885 Tj
--639 TJm
-(the) 12.1743 Tj
--639 TJm
-(damaged) 35.965 Tj
--639 TJm
-(\002le,) 15.2229 Tj
--737 TJm
-(and) 14.386 Tj
--639 TJm
-(writes) 24.3486 Tj
--639 TJm
-(a) 4.42339 Tj
--639 TJm
-(number) 30.4357 Tj
--639 TJm
-(of) 8.29885 Tj
--640 TJm
-(\002les) 16.6077 Tj
-[1 0 0 1 72 238.873] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -238.873] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 238.873 Td
-/F134_0 9.9626 Tf
-(rec0001file.bz2) 89.6634 Tj
-[1 0 0 1 161.664 238.873] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -161.664 -238.873] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-161.664 238.873 Td
-/F130_0 9.9626 Tf
-(,) 2.49065 Tj
-[1 0 0 1 169.072 238.873] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -169.072 -238.873] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-169.072 238.873 Td
-/F134_0 9.9626 Tf
-(rec0002file.bz2) 89.6634 Tj
-[1 0 0 1 258.736 238.873] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -258.736 -238.873] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-258.736 238.873 Td
-/F130_0 9.9626 Tf
-(,) 2.49065 Tj
--494 TJm
-(etc,) 14.107 Tj
--493 TJm
-(containing) 42.0621 Tj
--445 TJm
-(the) 12.1743 Tj
--445 TJm
-(e) 4.42339 Tj
-15 TJm
-(xtracted) 32.0895 Tj
--445 TJm
-(blocks.) 28.503 Tj
--1789 TJm
-(The) 15.4918 Tj
--445 TJm
-(output) 25.4644 Tj
--445 TJm
-(\002lenames) 38.1866 Tj
--445 TJm
-(are) 12.1643 Tj
-72 226.918 Td
-(designed) 35.417 Tj
--337 TJm
-(so) 8.85675 Tj
--337 TJm
-(that) 14.9439 Tj
--337 TJm
-(the) 12.1743 Tj
--337 TJm
-(use) 13.2801 Tj
--337 TJm
-(of) 8.29885 Tj
--337 TJm
-(wildc) 22.1369 Tj
-1 TJm
-(ards) 16.5977 Tj
--337 TJm
-(in) 7.7509 Tj
--337 TJm
-(subsequent) 44.2738 Tj
--337 TJm
-(processing) 42.61 Tj
--337 TJm
-(--) 6.63509 Tj
--337 TJm
-(for) 11.6164 Tj
--337 TJm
-(e) 4.42339 Tj
-15 TJm
-(xample,) 31.8205 Tj
-[1 0 0 1 396.538 226.918] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -396.538 -226.918] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-396.538 226.918 Td
-/F134_0 9.9626 Tf
-(bzip2) 29.8878 Tj
--600 TJm
-(-dc) 17.9327 Tj
--600 TJm
-(rec) 17.9327 Tj
-474.247 225.174 Td
-(*) 5.97756 Tj
-480.224 226.918 Td
-(file.bz2) 47.8205 Tj
--600 TJm
-(>) 5.97756 Tj
-72 214.963 Td
-(recovered_data) 83.6858 Tj
-[1 0 0 1 155.686 214.963] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -155.686 -214.963] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-158.177 214.963 Td
-/F130_0 9.9626 Tf
-(--) 6.63509 Tj
--250 TJm
-(lists) 16.0597 Tj
--250 TJm
-(the) 12.1743 Tj
--250 TJm
-(\002les) 16.6077 Tj
--250 TJm
-(in) 7.7509 Tj
--250 TJm
-(the) 12.1743 Tj
--250 TJm
-(correct) 27.6562 Tj
--250 TJm
-(order) 21.0211 Tj
-55 TJm
-(.) 2.49065 Tj
-[1 0 0 1 72 213.653] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.9627] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -203.69] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 193.045 Td
-/F134_0 9.9626 Tf
-(bzip2recover) 71.7307 Tj
-[1 0 0 1 143.731 193.045] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -143.731 -193.045] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-145.93 193.045 Td
-/F130_0 9.9626 Tf
-(should) 26.5703 Tj
--221 TJm
-(be) 9.40469 Tj
--220 TJm
-(of) 8.29885 Tj
--221 TJm
-(most) 19.3773 Tj
--221 TJm
-(use) 13.2801 Tj
--220 TJm
-(dealing) 29.3299 Tj
--221 TJm
-(with) 17.7135 Tj
--221 TJm
-(lar) 10.5105 Tj
-18 TJm
-(ge) 9.40469 Tj
-[1 0 0 1 307.229 193.045] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -307.229 -193.045] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-307.229 193.045 Td
-/F134_0 9.9626 Tf
-(.bz2) 23.9102 Tj
-[1 0 0 1 331.14 193.045] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -331.14 -193.045] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-333.338 193.045 Td
-/F130_0 9.9626 Tf
-(\002les,) 19.0983 Tj
--227 TJm
-(as) 8.29885 Tj
--220 TJm
-(these) 20.4731 Tj
--221 TJm
-(will) 15.5018 Tj
--221 TJm
-(contain) 29.3299 Tj
--220 TJm
-(man) 17.1556 Tj
-15 TJm
-(y) 4.9813 Tj
--221 TJm
-(blocks.) 28.503 Tj
--600 TJm
-(It) 6.08715 Tj
--221 TJm
-(is) 6.64505 Tj
--221 TJm
-(clearly) 27.1082 Tj
-72 181.09 Td
-(futile) 21.031 Tj
--289 TJm
-(to) 7.7509 Tj
--289 TJm
-(use) 13.2801 Tj
--289 TJm
-(it) 5.53921 Tj
--289 TJm
-(on) 9.9626 Tj
--289 TJm
-(damaged) 35.965 Tj
--289 TJm
-(single-block) 49.2551 Tj
--290 TJm
-(\002les) 16.6077 Tj
-1 TJm
-(,) 2.49065 Tj
--299 TJm
-(since) 20.4731 Tj
--289 TJm
-(a) 4.42339 Tj
--290 TJm
-(damaged) 35.965 Tj
--289 TJm
-(block) 22.1369 Tj
--289 TJm
-(cannot) 26.5603 Tj
--289 TJm
-(be) 9.40469 Tj
--289 TJm
-(reco) 17.1456 Tj
-15 TJm
-(v) 4.9813 Tj
-15 TJm
-(ered.) 19.6363 Tj
--854 TJm
-(If) 6.63509 Tj
--289 TJm
-(you) 14.9439 Tj
--290 TJm
-(wish) 18.8194 Tj
--289 TJm
-(to) 7.7509 Tj
--289 TJm
-(minimise) 37.0908 Tj
-72 169.135 Td
-(an) 9.40469 Tj
-15 TJm
-(y) 4.9813 Tj
--320 TJm
-(potential) 34.8691 Tj
--320 TJm
-(data) 16.5977 Tj
--319 TJm
-(loss) 15.5018 Tj
--320 TJm
-(through) 30.9936 Tj
--320 TJm
-(media) 24.3486 Tj
--320 TJm
-(or) 8.29885 Tj
--319 TJm
-(transmission) 50.3709 Tj
--320 TJm
-(errors,) 25.7234 Tj
--337 TJm
-(you) 14.9439 Tj
--320 TJm
-(might) 23.2527 Tj
--320 TJm
-(consider) 33.7533 Tj
--320 TJm
-(compressing) 50.3609 Tj
--319 TJm
-(with) 17.7135 Tj
--320 TJm
-(a) 4.42339 Tj
--320 TJm
-(smaller) 29.3299 Tj
--320 TJm
-(block) 22.1369 Tj
-72 157.179 Td
-(size.) 17.9825 Tj
-[1 0 0 1 72 157.08] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.9626] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -147.117] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 122.426 Td
-/F122_0 20.6585 Tf
-(2.7.) 34.4584 Tj
--278 TJm
-(PERFORMANCE) 161.818 Tj
--278 TJm
-(NO) 30.9877 Tj
-40 TJm
-(TES) 40.1808 Tj
-[1 0 0 1 72 122.168] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.9626] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -112.206] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 100.509 Td
-/F130_0 9.9626 Tf
-(The) 15.4918 Tj
--305 TJm
-(sorting) 27.6761 Tj
--304 TJm
-(phase) 22.6848 Tj
--305 TJm
-(of) 8.29885 Tj
--304 TJm
-(compression) 50.3609 Tj
--305 TJm
-(g) 4.9813 Tj
-5 TJm
-(athers) 23.7907 Tj
--304 TJm
-(together) 32.6474 Tj
--305 TJm
-(similar) 27.6761 Tj
--304 TJm
-(strings) 26.5703 Tj
--305 TJm
-(in) 7.7509 Tj
--304 TJm
-(the) 12.1743 Tj
--305 TJm
-(\002le.) 15.2229 Tj
--947 TJm
-(Because) 33.1954 Tj
--305 TJm
-(of) 8.29885 Tj
--304 TJm
-(this,) 16.8866 Tj
--319 TJm
-(\002les) 16.6077 Tj
--304 TJm
-(containing) 42.0621 Tj
--305 TJm
-(v) 4.9813 Tj
-15 TJm
-(ery) 12.7222 Tj
-72 88.5534 Td
-(long) 17.7135 Tj
--286 TJm
-(runs) 17.1556 Tj
--285 TJm
-(of) 8.29885 Tj
--286 TJm
-(repeated) 33.7433 Tj
--285 TJm
-(symbols,) 35.706 Tj
--295 TJm
-(lik) 10.5205 Tj
-10 TJm
-(e) 4.42339 Tj
--286 TJm
-("aabaabaabaab) 59.3771 Tj
--285 TJm
-(...") 11.5367 Tj
--571 TJm
-(\(repeated) 37.0609 Tj
--286 TJm
-(se) 8.29885 Tj
-25 TJm
-(v) 4.9813 Tj
-15 TJm
-(eral) 14.9339 Tj
--286 TJm
-(hundred) 32.6474 Tj
--285 TJm
-(times\)) 24.9065 Tj
--286 TJm
-(may) 17.1556 Tj
--286 TJm
-(com) 17.1556 Tj
-1 TJm
-(press) 20.4731 Tj
--286 TJm
-(more) 20.4731 Tj
--286 TJm
-(slo) 11.6264 Tj
-25 TJm
-(wly) 14.9439 Tj
-72 76.5983 Td
-(than) 17.1556 Tj
--322 TJm
-(normal.) 30.7147 Tj
--524 TJm
-(V) 7.193 Tj
-111 TJm
-(ersions) 28.224 Tj
--322 TJm
-(0.9.5) 19.9252 Tj
--321 TJm
-(and) 14.386 Tj
--322 TJm
-(abo) 14.386 Tj
-15 TJm
-(v) 4.9813 Tj
-15 TJm
-(e) 4.42339 Tj
--322 TJm
-(f) 3.31755 Tj
-10 TJm
-(are) 12.1643 Tj
--321 TJm
-(much) 22.1369 Tj
--322 TJm
-(better) 22.6848 Tj
--321 TJm
-(than) 17.1556 Tj
--322 TJm
-(pre) 12.7222 Tj
-25 TJm
-(vious) 21.589 Tj
--321 TJm
-(v) 4.9813 Tj
-15 TJm
-(ersions) 28.224 Tj
--322 TJm
-(in) 7.7509 Tj
--322 TJm
-(this) 14.396 Tj
--321 TJm
-(respect.) 30.7047 Tj
--1050 TJm
-(The) 15.4918 Tj
--321 TJm
-(ratio) 18.2614 Tj
--322 TJm
-(between) 33.1954 Tj
-[1 0 0 1 72 50.8518] cm
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-[1 0 0 1 1.8929 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 374.394 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 6.8541] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 43.0633 -6.7545] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -496.332 -50.9514] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-539.395 50.9514 Td
-/F130_0 9.9626 Tf
-(6) 4.9813 Tj
-[1 0 0 1 453.269 50.8518] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 93.5985 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 6.2765 0] cm
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-[1 0 0 1 -13.1436 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-Q
-showpage
-%%PageTrailer
-pdfEndPage
-%%Page: 10 10
-%%BeginPageSetup
-%%PageOrientation: Portrait
-pdfStartPage
-0 0 612 792 re W
-%%EndPageSetup
-[] 0 d
-1 i
-0 j
-0 J
-10 M
-1 w
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-false op
-false OP
-0 0 612 792 re
-W
-q
-[1 0 0 1 72 741.554] cm
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-[1 0 0 1 1.8929 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 14.4459] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 187.197 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 -8.9114] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 8.9114] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 105.519 -6.7546] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -371.59 -749.245] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-477.109 749.245 Td
-/F130_0 9.9626 Tf
-(Ho) 12.1743 Tj
-25 TJm
-(w) 7.193 Tj
--250 TJm
-(to) 7.7509 Tj
--250 TJm
-(use) 13.2801 Tj
--250 TJm
-(bzip2) 22.1369 Tj
-[1 0 0 1 266.071 747.089] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 280.796 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -472.974 -5.0363] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -0.4981] cm
-q
-[] 0 d
-0 J
-0.4981 w
-0 0.2491 m
-475.465 0.2491 l
-S
-Q
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 479.251 0] cm
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-[1 0 0 1 -13.1436 0] cm
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-[1 0 0 1 -540 -741.554] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 710.037 Td
-/F130_0 9.9626 Tf
-(w) 7.193 Tj
-10 TJm
-(orst-case) 35.4071 Tj
--289 TJm
-(and) 14.386 Tj
--290 TJm
-(a) 4.42339 Tj
-20 TJm
-(v) 4.9813 Tj
-15 TJm
-(erage-case) 42.0322 Tj
--289 TJm
-(compression) 50.3609 Tj
--290 TJm
-(time) 17.7135 Tj
--289 TJm
-(is) 6.64505 Tj
--290 TJm
-(in) 7.7509 Tj
--289 TJm
-(the) 12.1743 Tj
--290 TJm
-(re) 7.74094 Tj
-15 TJm
-(gion) 17.7135 Tj
--289 TJm
-(of) 8.29885 Tj
--289 TJm
-(10:1.) 20.2042 Tj
--857 TJm
-(F) 5.53921 Tj
-15 TJm
-(or) 8.29885 Tj
--290 TJm
-(pre) 12.7222 Tj
-25 TJm
-(vious) 21.589 Tj
--289 TJm
-(v) 4.9813 Tj
-15 TJm
-(ersions,) 30.7147 Tj
--299 TJm
-(this) 14.396 Tj
--290 TJm
-(\002gure) 23.2427 Tj
--289 TJm
-(w) 7.193 Tj
-10 TJm
-(as) 8.29885 Tj
--290 TJm
-(more) 20.4731 Tj
-72 698.082 Td
-(lik) 10.5205 Tj
-10 TJm
-(e) 4.42339 Tj
--250 TJm
-(100:1.) 25.1855 Tj
--620 TJm
-(Y) 7.193 Tj
-110 TJm
-(ou) 9.9626 Tj
--250 TJm
-(can) 13.8281 Tj
--250 TJm
-(use) 13.2801 Tj
--250 TJm
-(the) 12.1743 Tj
-[1 0 0 1 186.002 698.082] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -186.002 -698.082] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-186.002 698.082 Td
-/F134_0 9.9626 Tf
-(-vvvv) 29.8878 Tj
-[1 0 0 1 215.889 698.082] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -215.889 -698.082] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-218.38 698.082 Td
-/F130_0 9.9626 Tf
-(option) 25.4644 Tj
--250 TJm
-(to) 7.7509 Tj
--250 TJm
-(monitor) 31.5516 Tj
--250 TJm
-(progress) 33.7533 Tj
--250 TJm
-(in) 7.7509 Tj
--250 TJm
-(great) 19.9152 Tj
--250 TJm
-(detail,) 24.6275 Tj
--250 TJm
-(if) 6.08715 Tj
--250 TJm
-(you) 14.9439 Tj
--250 TJm
-(w) 7.193 Tj
-10 TJm
-(ant.) 14.6649 Tj
-[1 0 0 1 72 695.925] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.9627] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -685.963] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 676.164 Td
-/F130_0 9.9626 Tf
-(Decompression) 61.9773 Tj
--250 TJm
-(speed) 22.6848 Tj
--250 TJm
-(is) 6.64505 Tj
--250 TJm
-(unaf) 17.7035 Tj
-25 TJm
-(fected) 24.3386 Tj
--250 TJm
-(by) 9.9626 Tj
--250 TJm
-(these) 20.4731 Tj
--250 TJm
-(phenomena.) 48.4182 Tj
-[1 0 0 1 72 674.007] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.9626] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -664.045] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 654.247 Td
-/F134_0 9.9626 Tf
-(bzip2) 29.8878 Tj
-[1 0 0 1 101.888 654.247] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -101.888 -654.247] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-104.863 654.247 Td
-/F130_0 9.9626 Tf
-(usually) 28.782 Tj
--299 TJm
-(allocates) 34.8591 Tj
--298 TJm
-(se) 8.29885 Tj
-25 TJm
-(v) 4.9813 Tj
-15 TJm
-(eral) 14.9339 Tj
--299 TJm
-(me) 12.1743 Tj
-15 TJm
-(g) 4.9813 Tj
-5 TJm
-(abytes) 25.4544 Tj
--298 TJm
-(of) 8.29885 Tj
--299 TJm
-(memory) 33.2053 Tj
--299 TJm
-(to) 7.7509 Tj
--298 TJm
-(operate) 29.3199 Tj
--299 TJm
-(in,) 10.2416 Tj
--311 TJm
-(and) 14.386 Tj
--298 TJm
-(then) 17.1556 Tj
--299 TJm
-(char) 17.1456 Tj
-18 TJm
-(ges) 13.2801 Tj
--298 TJm
-(all) 9.9626 Tj
--299 TJm
-(o) 4.9813 Tj
-15 TJm
-(v) 4.9813 Tj
-15 TJm
-(er) 7.74094 Tj
--299 TJm
-(it) 5.53921 Tj
--298 TJm
-(in) 7.7509 Tj
--299 TJm
-(a) 4.42339 Tj
--298 TJm
-(f) 3.31755 Tj
-10 TJm
-(airly) 18.2614 Tj
--299 TJm
-(random) 30.4357 Tj
-72 642.291 Td
-(f) 3.31755 Tj
-10 TJm
-(ashion.) 28.503 Tj
--743 TJm
-(This) 17.7135 Tj
--270 TJm
-(means) 25.4544 Tj
--271 TJm
-(that) 14.9439 Tj
--270 TJm
-(performance,) 52.8317 Tj
--276 TJm
-(both) 17.7135 Tj
--270 TJm
-(for) 11.6164 Tj
--271 TJm
-(compressing) 50.3609 Tj
--270 TJm
-(and) 14.386 Tj
--271 TJm
-(decompressing,) 62.2563 Tj
--275 TJm
-(is) 6.64505 Tj
--271 TJm
-(lar) 10.5105 Tj
-18 TJm
-(gely) 17.1556 Tj
--270 TJm
-(determined) 44.8217 Tj
--271 TJm
-(by) 9.9626 Tj
--270 TJm
-(the) 12.1743 Tj
--271 TJm
-(speed) 22.6848 Tj
-72 630.336 Td
-(at) 7.193 Tj
--294 TJm
-(which) 24.3486 Tj
--294 TJm
-(your) 18.2614 Tj
--294 TJm
-(machine) 33.7533 Tj
--295 TJm
-(ca) 8.84679 Tj
-1 TJm
-(n) 4.9813 Tj
--295 TJm
-(service) 28.2141 Tj
--294 TJm
-(cache) 22.6749 Tj
--294 TJm
-(misses.) 29.0609 Tj
--442 TJm
-(Because) 33.1954 Tj
--294 TJm
-(of) 8.29885 Tj
--294 TJm
-(this,) 16.8866 Tj
--306 TJm
-(small) 21.589 Tj
--294 TJm
-(changes) 32.0895 Tj
--294 TJm
-(to) 7.7509 Tj
--294 TJm
-(the) 12.1743 Tj
--294 TJm
-(code) 18.8094 Tj
--294 TJm
-(to) 7.7509 Tj
--294 TJm
-(reduce) 26.5503 Tj
--294 TJm
-(the) 12.1743 Tj
--295 TJm
-(miss) 18.2714 Tj
--294 TJm
-(rate) 14.9339 Tj
-72 618.381 Td
-(ha) 9.40469 Tj
-20 TJm
-(v) 4.9813 Tj
-15 TJm
-(e) 4.42339 Tj
--253 TJm
-(been) 18.8094 Tj
--253 TJm
-(observ) 26.5603 Tj
-15 TJm
-(ed) 9.40469 Tj
--253 TJm
-(to) 7.7509 Tj
--253 TJm
-(gi) 7.7509 Tj
-25 TJm
-(v) 4.9813 Tj
-15 TJm
-(e) 4.42339 Tj
--253 TJm
-(disproportionately) 73.0557 Tj
--253 TJm
-(lar) 10.5105 Tj
-18 TJm
-(ge) 9.40469 Tj
--253 TJm
-(performance) 50.341 Tj
--253 TJm
-(impro) 23.8007 Tj
-15 TJm
-(v) 4.9813 Tj
-15 TJm
-(ements.) 30.7147 Tj
--639 TJm
-(I) 3.31755 Tj
--253 TJm
-(imagine) 32.0995 Tj
-[1 0 0 1 438.909 618.381] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -438.909 -618.381] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-438.909 618.381 Td
-/F134_0 9.9626 Tf
-(bzip2) 29.8878 Tj
-[1 0 0 1 468.796 618.381] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -468.796 -618.381] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-471.318 618.381 Td
-/F130_0 9.9626 Tf
-(will) 15.5018 Tj
--253 TJm
-(perform) 32.0895 Tj
--253 TJm
-(best) 16.0497 Tj
-72 606.426 Td
-(on) 9.9626 Tj
--250 TJm
-(machines) 37.6287 Tj
--250 TJm
-(with) 17.7135 Tj
--250 TJm
-(v) 4.9813 Tj
-15 TJm
-(ery) 12.7222 Tj
--250 TJm
-(lar) 10.5105 Tj
-18 TJm
-(ge) 9.40469 Tj
--250 TJm
-(caches.) 29.041 Tj
-[1 0 0 1 72 604.269] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.9627] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -594.306] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 571.673 Td
-/F122_0 20.6585 Tf
-(2.8.) 34.4584 Tj
--278 TJm
-(CA) 29.8309 Tj
-80 TJm
-(VEA) 42.4739 Tj
-90 TJm
-(TS) 26.4016 Tj
-[1 0 0 1 72 571.415] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.9626] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -561.452] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 549.755 Td
-/F130_0 9.9626 Tf
-(I/O) 13.2801 Tj
--268 TJm
-(error) 19.3573 Tj
--267 TJm
-(messages) 37.6287 Tj
--268 TJm
-(are) 12.1643 Tj
--268 TJm
-(not) 12.7322 Tj
--268 TJm
-(as) 8.29885 Tj
--267 TJm
-(helpful) 28.224 Tj
--268 TJm
-(as) 8.29885 Tj
--268 TJm
-(the) 12.1743 Tj
-15 TJm
-(y) 4.9813 Tj
--267 TJm
-(could) 22.1369 Tj
--268 TJm
-(be.) 11.8953 Tj
-[1 0 0 1 293.313 549.755] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -293.313 -549.755] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-293.313 549.755 Td
-/F134_0 9.9626 Tf
-(bzip2) 29.8878 Tj
-[1 0 0 1 323.201 549.755] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -323.201 -549.755] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-325.868 549.755 Td
-/F130_0 9.9626 Tf
-(tries) 17.1556 Tj
--268 TJm
-(hard) 17.7035 Tj
--267 TJm
-(to) 7.7509 Tj
--268 TJm
-(detect) 23.7907 Tj
--268 TJm
-(I/O) 13.2801 Tj
--268 TJm
-(errors) 23.2328 Tj
--267 TJm
-(and) 14.386 Tj
--268 TJm
-(e) 4.42339 Tj
-15 TJm
-(xit) 10.5205 Tj
--268 TJm
-(cleanly) 28.772 Tj
-65 TJm
-(,) 2.49065 Tj
--272 TJm
-(b) 4.9813 Tj
-20 TJm
-(ut) 7.7509 Tj
--268 TJm
-(the) 12.1743 Tj
-72 537.8 Td
-(details) 26.0123 Tj
--250 TJm
-(of) 8.29885 Tj
--250 TJm
-(what) 19.3673 Tj
--250 TJm
-(the) 12.1743 Tj
--250 TJm
-(problem) 33.2053 Tj
--250 TJm
-(is) 6.64505 Tj
--250 TJm
-(sometimes) 42.62 Tj
--250 TJm
-(seem) 20.4731 Tj
--250 TJm
-(rather) 23.2328 Tj
--250 TJm
-(misleading.) 46.2165 Tj
-[1 0 0 1 72 535.643] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.9626] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -525.681] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 515.882 Td
-/F130_0 9.9626 Tf
-(This) 17.7135 Tj
--280 TJm
-(manual) 29.3299 Tj
--279 TJm
-(page) 18.8094 Tj
--280 TJm
-(pertains) 31.5416 Tj
--280 TJm
-(to) 7.7509 Tj
--279 TJm
-(v) 4.9813 Tj
-15 TJm
-(ersion) 24.3486 Tj
--280 TJm
-(1.0.5) 19.9252 Tj
--280 TJm
-(of) 8.29885 Tj
-[1 0 0 1 256.84 515.882] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -256.84 -515.882] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-256.84 515.882 Td
-/F134_0 9.9626 Tf
-(bzip2) 29.8878 Tj
-[1 0 0 1 286.728 515.882] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -286.728 -515.882] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-286.728 515.882 Td
-/F130_0 9.9626 Tf
-(.) 2.49065 Tj
--798 TJm
-(Compressed) 49.2551 Tj
--280 TJm
-(data) 16.5977 Tj
--279 TJm
-(created) 28.762 Tj
--280 TJm
-(by) 9.9626 Tj
--280 TJm
-(this) 14.396 Tj
--279 TJm
-(v) 4.9813 Tj
-15 TJm
-(ersion) 24.3486 Tj
--280 TJm
-(is) 6.64505 Tj
--280 TJm
-(entirely) 30.4357 Tj
--279 TJm
-(forw) 18.8094 Tj
-10 TJm
-(ards) 16.5977 Tj
-72 503.927 Td
-(and) 14.386 Tj
--294 TJm
-(backw) 26.0024 Tj
-10 TJm
-(ards) 16.5977 Tj
--293 TJm
-(compatible) 44.2738 Tj
--294 TJm
-(with) 17.7135 Tj
--294 TJm
-(the) 12.1743 Tj
--293 TJm
-(pre) 12.7222 Tj
-25 TJm
-(vious) 21.589 Tj
--294 TJm
-(public) 24.9065 Tj
--294 TJm
-(releases,) 34.0223 Tj
--304 TJm
-(v) 4.9813 Tj
-15 TJm
-(ersions) 28.224 Tj
--294 TJm
-(0.1pl2,) 27.6761 Tj
--305 TJm
-(0.9.0) 19.9252 Tj
--293 TJm
-(and) 14.386 Tj
--294 TJm
-(0.9.5,) 22.4159 Tj
--305 TJm
-(1.0.0,) 22.4159 Tj
--304 TJm
-(1.0.1,) 22.4159 Tj
--305 TJm
-(1.0.2) 19.9252 Tj
--294 TJm
-(and) 14.386 Tj
-72 491.972 Td
-(1.0.3,) 22.4159 Tj
--263 TJm
-(b) 4.9813 Tj
-20 TJm
-(ut) 7.7509 Tj
--260 TJm
-(with) 17.7135 Tj
--260 TJm
-(the) 12.1743 Tj
--260 TJm
-(follo) 18.8194 Tj
-25 TJm
-(wing) 19.9252 Tj
--260 TJm
-(e) 4.42339 Tj
-15 TJm
-(xception:) 37.0808 Tj
--330 TJm
-(0.9.0) 19.9252 Tj
--260 TJm
-(and) 14.386 Tj
--260 TJm
-(abo) 14.386 Tj
-15 TJm
-(v) 4.9813 Tj
-15 TJm
-(e) 4.42339 Tj
--260 TJm
-(can) 13.8281 Tj
--260 TJm
-(correctly) 35.4071 Tj
--260 TJm
-(decompress) 47.0334 Tj
--260 TJm
-(multiple) 33.2153 Tj
--260 TJm
-(concatenated) 52.0048 Tj
--260 TJm
-(compressed) 47.0334 Tj
-72 480.017 Td
-(\002les.) 19.0983 Tj
--310 TJm
-(0.1pl2) 25.1855 Tj
--250 TJm
-(cannot) 26.5603 Tj
--250 TJm
-(do) 9.9626 Tj
--250 TJm
-(this;) 17.1656 Tj
--250 TJm
-(it) 5.53921 Tj
--250 TJm
-(will) 15.5018 Tj
--250 TJm
-(stop) 16.6077 Tj
--250 TJm
-(after) 18.2515 Tj
--250 TJm
-(decompressing) 59.7656 Tj
--250 TJm
-(just) 14.396 Tj
--250 TJm
-(the) 12.1743 Tj
--250 TJm
-(\002rst) 15.5018 Tj
--250 TJm
-(\002le) 12.7322 Tj
--250 TJm
-(in) 7.7509 Tj
--250 TJm
-(the) 12.1743 Tj
--250 TJm
-(stream.) 29.0509 Tj
-[1 0 0 1 72 477.86] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.9626] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -467.897] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 458.099 Td
-/F134_0 9.9626 Tf
-(bzip2recover) 71.7307 Tj
-[1 0 0 1 143.731 458.099] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -143.731 -458.099] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-146.174 458.099 Td
-/F130_0 9.9626 Tf
-(v) 4.9813 Tj
-15 TJm
-(ersions) 28.224 Tj
--245 TJm
-(prior) 19.3673 Tj
--245 TJm
-(to) 7.7509 Tj
--245 TJm
-(1.0.2) 19.9252 Tj
--246 TJm
-(used) 18.2614 Tj
--245 TJm
-(32-bit) 23.8007 Tj
--245 TJm
-(inte) 14.9439 Tj
-15 TJm
-(gers) 16.5977 Tj
--245 TJm
-(to) 7.7509 Tj
--245 TJm
-(represent) 36.5129 Tj
--245 TJm
-(bit) 10.5205 Tj
--246 TJm
-(positions) 35.9849 Tj
--245 TJm
-(in) 7.7509 Tj
--245 TJm
-(compressed) 47.0334 Tj
--245 TJm
-(\002les,) 19.0983 Tj
--246 TJm
-(so) 8.85675 Tj
--245 TJm
-(it) 5.53921 Tj
--245 TJm
-(could) 22.1369 Tj
-72 446.144 Td
-(not) 12.7322 Tj
--384 TJm
-(handle) 26.5603 Tj
--383 TJm
-(compressed) 47.0334 Tj
--384 TJm
-(\002les) 16.6077 Tj
--383 TJm
-(more) 20.4731 Tj
--384 TJm
-(than) 17.1556 Tj
--383 TJm
-(512) 14.9439 Tj
--384 TJm
-(me) 12.1743 Tj
-15 TJm
-(g) 4.9813 Tj
-5 TJm
-(abytes) 25.4544 Tj
--383 TJm
-(long.) 20.2042 Tj
--1421 TJm
-(V) 7.193 Tj
-111 TJm
-(ersions) 28.224 Tj
--384 TJm
-(1.0.2) 19.9252 Tj
--383 TJm
-(and) 14.386 Tj
--384 TJm
-(abo) 14.386 Tj
-15 TJm
-(v) 4.9813 Tj
-15 TJm
-(e) 4.42339 Tj
--384 TJm
-(use) 13.2801 Tj
--383 TJm
-(64-bit) 23.8007 Tj
--384 TJm
-(ints) 14.396 Tj
--383 TJm
-(on) 9.9626 Tj
--384 TJm
-(some) 21.031 Tj
-72 434.189 Td
-(platforms) 38.1866 Tj
--245 TJm
-(which) 24.3486 Tj
--246 TJm
-(support) 29.8878 Tj
--245 TJm
-(them) 19.9252 Tj
--246 TJm
-(\(GNU) 24.8965 Tj
--245 TJm
-(supported) 39.2925 Tj
--245 TJm
-(tar) 10.5105 Tj
-18 TJm
-(gets,) 18.5404 Tj
--247 TJm
-(and) 14.386 Tj
--245 TJm
-(W) 9.40469 Tj
-40 TJm
-(indo) 17.7135 Tj
-25 TJm
-(ws\).) 16.8766 Tj
--309 TJm
-(T) 6.08715 Tj
-80 TJm
-(o) 4.9813 Tj
--245 TJm
-(establish) 34.8691 Tj
--245 TJm
-(whether) 32.0895 Tj
--246 TJm
-(or) 8.29885 Tj
--245 TJm
-(not) 12.7322 Tj
-[1 0 0 1 468.269 434.189] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -468.269 -434.189] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-468.269 434.189 Td
-/F134_0 9.9626 Tf
-(bzip2recover) 71.7307 Tj
-[1 0 0 1 540 434.189] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -540 -434.189] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 422.233 Td
-/F130_0 9.9626 Tf
-(w) 7.193 Tj
-10 TJm
-(as) 8.29885 Tj
--255 TJm
-(b) 4.9813 Tj
-20 TJm
-(uilt) 13.2901 Tj
--255 TJm
-(with) 17.7135 Tj
--255 TJm
-(such) 18.2614 Tj
--255 TJm
-(a) 4.42339 Tj
--255 TJm
-(limitation,) 41.2452 Tj
--256 TJm
-(run) 13.2801 Tj
--255 TJm
-(it) 5.53921 Tj
--255 TJm
-(without) 30.4457 Tj
--255 TJm
-(ar) 7.74094 Tj
-18 TJm
-(guments.) 36.2539 Tj
--325 TJm
-(In) 8.29885 Tj
--255 TJm
-(an) 9.40469 Tj
-15 TJm
-(y) 4.9813 Tj
--256 TJm
-(e) 4.42339 Tj
-25 TJm
-(v) 4.9813 Tj
-15 TJm
-(ent) 12.1743 Tj
--255 TJm
-(you) 14.9439 Tj
--255 TJm
-(can) 13.8281 Tj
--255 TJm
-(b) 4.9813 Tj
-20 TJm
-(uild) 15.5018 Tj
--255 TJm
-(yourself) 32.6474 Tj
--255 TJm
-(an) 9.40469 Tj
--255 TJm
-(unlimited) 38.1966 Tj
--255 TJm
-(v) 4.9813 Tj
-15 TJm
-(ersion) 24.3486 Tj
--255 TJm
-(if) 6.08715 Tj
-72 410.278 Td
-(you) 14.9439 Tj
--250 TJm
-(can) 13.8281 Tj
--250 TJm
-(recompile) 39.8404 Tj
--250 TJm
-(it) 5.53921 Tj
--250 TJm
-(with) 17.7135 Tj
-[1 0 0 1 176.318 410.278] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -176.318 -410.278] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-176.318 410.278 Td
-/F134_0 9.9626 Tf
-(MaybeUInt64) 65.7532 Tj
-[1 0 0 1 242.071 410.278] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -242.071 -410.278] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-244.562 410.278 Td
-/F130_0 9.9626 Tf
-(set) 11.0684 Tj
--250 TJm
-(to) 7.7509 Tj
--250 TJm
-(be) 9.40469 Tj
--250 TJm
-(an) 9.40469 Tj
--250 TJm
-(unsigned) 35.9749 Tj
--250 TJm
-(64-bit) 23.8007 Tj
--250 TJm
-(inte) 14.9439 Tj
-15 TJm
-(ger) 12.7222 Tj
-55 TJm
-(.) 2.49065 Tj
-[1 0 0 1 72 408.121] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.9626] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -398.159] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 375.525 Td
-/F122_0 20.6585 Tf
-(2.9.) 34.4584 Tj
--278 TJm
-(A) 14.9154 Tj
-50 TJm
-(UTHOR) 73.441 Tj
-[1 0 0 1 72 375.267] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.9626] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -365.305] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 353.608 Td
-/F130_0 9.9626 Tf
-(Julian) 23.8007 Tj
--250 TJm
-(Se) 9.9626 Tj
-25 TJm
-(w) 7.193 Tj
-10 TJm
-(ard,) 15.2129 Tj
-[1 0 0 1 132.801 353.608] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -132.801 -353.608] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-132.801 353.608 Td
-/F134_0 9.9626 Tf
-(jseward@bzip.org) 95.641 Tj
-[1 0 0 1 228.443 353.608] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -156.443 -1.5342] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.9626] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -342.111] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 331.69 Td
-/F130_0 9.9626 Tf
-(The) 15.4918 Tj
--299 TJm
-(ideas) 20.4731 Tj
--300 TJm
-(embodied) 39.2925 Tj
--299 TJm
-(in) 7.7509 Tj
-[1 0 0 1 166.942 331.69] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -166.942 -331.69] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-166.942 331.69 Td
-/F134_0 9.9626 Tf
-(bzip2) 29.8878 Tj
-[1 0 0 1 196.83 331.69] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -196.83 -331.69] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-199.813 331.69 Td
-/F130_0 9.9626 Tf
-(are) 12.1643 Tj
--299 TJm
-(due) 14.386 Tj
--300 TJm
-(to) 7.7509 Tj
--299 TJm
-(\(at) 10.5105 Tj
--300 TJm
-(least\)) 21.579 Tj
--299 TJm
-(the) 12.1743 Tj
--300 TJm
-(follo) 18.8194 Tj
-25 TJm
-(wing) 19.9252 Tj
--299 TJm
-(people:) 29.3299 Tj
--409 TJm
-(Michael) 32.6474 Tj
--300 TJm
-(Burro) 23.2427 Tj
-25 TJm
-(ws) 11.0684 Tj
--299 TJm
-(and) 14.386 Tj
--299 TJm
-(Da) 11.6164 Tj
-20 TJm
-(vid) 12.7322 Tj
--300 TJm
-(Wheeler) 33.7433 Tj
--299 TJm
-(\(for) 14.9339 Tj
-72 319.735 Td
-(the) 12.1743 Tj
--312 TJm
-(block) 22.1369 Tj
--313 TJm
-(sorting) 27.6761 Tj
--312 TJm
-(transformation\),) 64.468 Tj
--328 TJm
-(Da) 11.6164 Tj
-20 TJm
-(vid) 12.7322 Tj
--312 TJm
-(Wheeler) 33.7433 Tj
--313 TJm
-(\(ag) 12.7222 Tj
-5 TJm
-(ain,) 14.6649 Tj
--327 TJm
-(for) 11.6164 Tj
--313 TJm
-(the) 12.1743 Tj
--312 TJm
-(Huf) 15.4918 Tj
-25 TJm
-(fman) 20.4731 Tj
--312 TJm
-(coder\),) 27.9351 Tj
--328 TJm
-(Peter) 20.4731 Tj
--313 TJm
-(Fenwick) 34.3112 Tj
--312 TJm
-(\(for) 14.9339 Tj
--312 TJm
-(the) 12.1743 Tj
--313 TJm
-(structured) 39.8404 Tj
-72 307.78 Td
-(coding) 27.1182 Tj
--325 TJm
-(model) 24.9065 Tj
--326 TJm
-(in) 7.7509 Tj
--325 TJm
-(the) 12.1743 Tj
--326 TJm
-(original) 30.9936 Tj
-[1 0 0 1 191.156 307.779] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -191.156 -307.779] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-191.156 307.779 Td
-/F134_0 9.9626 Tf
-(bzip) 23.9102 Tj
-[1 0 0 1 215.067 307.779] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -215.067 -307.779] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-215.067 307.779 Td
-/F130_0 9.9626 Tf
-(,) 2.49065 Tj
--344 TJm
-(and) 14.386 Tj
--326 TJm
-(man) 17.1556 Tj
-15 TJm
-(y) 4.9813 Tj
--325 TJm
-(re\002nements\),) 52.2937 Tj
--345 TJm
-(and) 14.386 Tj
--325 TJm
-(Alistair) 29.8878 Tj
--326 TJm
-(Mof) 17.1556 Tj
-25 TJm
-(f) 3.31755 Tj
-10 TJm
-(at,) 9.68365 Tj
--344 TJm
-(Radford) 32.6474 Tj
--325 TJm
-(Neal) 18.8094 Tj
--326 TJm
-(and) 14.386 Tj
--325 TJm
-(Ian) 12.7222 Tj
--326 TJm
-(W) 9.40469 Tj
-40 TJm
-(itten) 17.7135 Tj
--325 TJm
-(\(for) 14.9339 Tj
-72 295.824 Td
-(the) 12.1743 Tj
--277 TJm
-(arithmetic) 40.3983 Tj
--277 TJm
-(coder) 22.1269 Tj
--277 TJm
-(in) 7.7509 Tj
--277 TJm
-(the) 12.1743 Tj
--277 TJm
-(original) 30.9936 Tj
-[1 0 0 1 214.171 295.824] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -214.171 -295.824] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-214.171 295.824 Td
-/F134_0 9.9626 Tf
-(bzip) 23.9102 Tj
-[1 0 0 1 238.082 295.824] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -238.082 -295.824] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-238.082 295.824 Td
-/F130_0 9.9626 Tf
-(\).) 5.8082 Tj
--782 TJm
-(I) 3.31755 Tj
--277 TJm
-(am) 12.1743 Tj
--276 TJm
-(much) 22.1369 Tj
--277 TJm
-(indebted) 34.3112 Tj
--277 TJm
-(for) 11.6164 Tj
--277 TJm
-(their) 18.2614 Tj
--277 TJm
-(help,) 19.6462 Tj
--284 TJm
-(support) 29.8878 Tj
--277 TJm
-(and) 14.386 Tj
--277 TJm
-(advice.) 28.493 Tj
--781 TJm
-(See) 14.386 Tj
--277 TJm
-(the) 12.1743 Tj
--277 TJm
-(manual) 29.3299 Tj
-72 283.869 Td
-(in) 7.7509 Tj
--330 TJm
-(the) 12.1743 Tj
--330 TJm
-(source) 26.0024 Tj
--330 TJm
-(distrib) 25.4644 Tj
-20 TJm
-(ution) 20.4831 Tj
--330 TJm
-(for) 11.6164 Tj
--329 TJm
-(pointers) 32.0995 Tj
--330 TJm
-(to) 7.7509 Tj
--330 TJm
-(sources) 29.8778 Tj
--330 TJm
-(of) 8.29885 Tj
--330 TJm
-(documentation.) 61.7083 Tj
--1099 TJm
-(Christian) 36.5329 Tj
--330 TJm
-(v) 4.9813 Tj
-20 TJm
-(on) 9.9626 Tj
--330 TJm
-(Roques) 29.8878 Tj
--330 TJm
-(encouraged) 45.9176 Tj
--330 TJm
-(me) 12.1743 Tj
--330 TJm
-(to) 7.7509 Tj
--330 TJm
-(look) 17.7135 Tj
-72 271.914 Td
-(for) 11.6164 Tj
--271 TJm
-(f) 3.31755 Tj
-10 TJm
-(aster) 18.8094 Tj
--271 TJm
-(sorting) 27.6761 Tj
--271 TJm
-(algorithms,) 45.1107 Tj
--276 TJm
-(so) 8.85675 Tj
--272 TJm
-(as) 8.29885 Tj
--271 TJm
-(to) 7.7509 Tj
--271 TJm
-(speed) 22.6848 Tj
--271 TJm
-(up) 9.9626 Tj
--271 TJm
-(compression.) 52.8516 Tj
--746 TJm
-(Bela) 18.2614 Tj
--271 TJm
-(Lubkin) 28.782 Tj
--271 TJm
-(encouraged) 45.9176 Tj
--271 TJm
-(me) 12.1743 Tj
--272 TJm
-(to) 7.7509 Tj
--271 TJm
-(impro) 23.8007 Tj
-15 TJm
-(v) 4.9813 Tj
-15 TJm
-(e) 4.42339 Tj
--271 TJm
-(the) 12.1743 Tj
--271 TJm
-(w) 7.193 Tj
-10 TJm
-(orst-case) 35.4071 Tj
-72 259.959 Td
-(compression) 50.3609 Tj
--340 TJm
-(performance.) 52.8317 Tj
--580 TJm
-(Donna) 26.5603 Tj
--339 TJm
-(Robinson) 38.1966 Tj
--340 TJm
-(XMLised) 38.1866 Tj
--340 TJm
-(the) 12.1743 Tj
--340 TJm
-(documentation.) 61.7083 Tj
--580 TJm
-(Man) 18.2614 Tj
-15 TJm
-(y) 4.9813 Tj
--340 TJm
-(people) 26.5603 Tj
--340 TJm
-(sent) 16.0497 Tj
--339 TJm
-(patches,) 32.3685 Tj
--363 TJm
-(helped) 26.5603 Tj
--340 TJm
-(with) 17.7135 Tj
-72 248.004 Td
-(portability) 41.5142 Tj
--250 TJm
-(problems,) 39.5714 Tj
--250 TJm
-(lent) 14.9439 Tj
--250 TJm
-(machines,) 40.1194 Tj
--250 TJm
-(g) 4.9813 Tj
-5 TJm
-(a) 4.42339 Tj
-20 TJm
-(v) 4.9813 Tj
-15 TJm
-(e) 4.42339 Tj
--250 TJm
-(advice) 26.0024 Tj
--250 TJm
-(and) 14.386 Tj
--250 TJm
-(were) 19.3573 Tj
--250 TJm
-(generally) 37.0708 Tj
--250 TJm
-(helpful.) 30.7147 Tj
-[1 0 0 1 72 245.847] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-[1 0 0 1 0 -194.995] cm
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-[1 0 0 1 1.8929 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 374.394 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 6.5851] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 43.0633 -6.4855] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -496.332 -50.9514] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-539.395 50.9514 Td
-/F130_0 9.9626 Tf
-(7) 4.9813 Tj
-[1 0 0 1 453.269 50.8518] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 93.5985 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 6.2765 0] cm
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-[1 0 0 1 -13.1436 0] cm
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-Q
-showpage
-%%PageTrailer
-pdfEndPage
-%%Page: 11 11
-%%BeginPageSetup
-%%PageOrientation: Portrait
-pdfStartPage
-0 0 612 792 re W
-%%EndPageSetup
-[] 0 d
-1 i
-0 j
-0 J
-10 M
-1 w
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-false op
-false OP
-0 0 612 792 re
-W
-q
-[1 0 0 1 72 741.554] cm
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-[1 0 0 1 1.8929 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 4.3836 14.4459] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 187.197 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4906 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 141.643 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -141.643 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 280.796 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -472.974 -13.9477] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -0.4981] cm
-q
-[] 0 d
-0 J
-0.4981 w
-0 0.2491 m
-475.465 0.2491 l
-S
-Q
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 479.251 0] cm
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-[1 0 0 1 -15.0365 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -468 -21.5542] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -720] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 701.916 Td
-/F122_0 24.7902 Tf
-(3.) 20.675 Tj
--556 TJm
-(Pr) 26.1785 Tj
-20 TJm
-(ogramming) 134.983 Tj
--278 TJm
-(with) 49.5804 Tj
-[1 0 0 1 330.484 701.916] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -330.484 -701.916] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-330.484 701.916 Td
-/F392_0 24.7902 Tf
-(libbzip2) 118.993 Tj
-[1 0 0 1 449.477 701.916] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -377.477 -5.5156] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-[1 0 0 1 0 -9.9627] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -14.9439] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -671.493] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 656.35 Td
-/F122_0 17.2154 Tf
-(T) 10.5186 Tj
-80 TJm
-(ab) 20.0904 Tj
-10 TJm
-(le) 14.3576 Tj
--278 TJm
-(of) 16.2513 Tj
--278 TJm
-(Contents) 74.5943 Tj
-[1 0 0 1 72 647.528] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -11.7401] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -635.788] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 635.788 Td
-/F130_0 9.9626 Tf
-(3.1.) 14.9439 Tj
--310 TJm
-(T) 6.08715 Tj
-80 TJm
-(op-le) 20.4731 Tj
-25 TJm
-(v) 4.9813 Tj
-15 TJm
-(el) 7.193 Tj
--250 TJm
-(structure) 34.8591 Tj
-[1 0 0 1 164.921 635.788] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -169.902 -635.788] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-179.997 635.788 Td
-/F147_0 9.9626 Tf
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
-[1 0 0 1 511.108 635.788] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -511.108 -635.788] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-511.108 635.788 Td
-/F130_0 9.9626 Tf
-(8) 4.9813 Tj
-[1 0 0 1 516.09 635.788] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -444.09 -2.1568] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.7983] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -623.832] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 623.832 Td
-/F130_0 9.9626 Tf
-(3.1.1.) 22.4159 Tj
--310 TJm
-(Lo) 11.0684 Tj
-25 TJm
-(w-le) 17.7035 Tj
-25 TJm
-(v) 4.9813 Tj
-15 TJm
-(el) 7.193 Tj
--250 TJm
-(summary) 37.0808 Tj
-[1 0 0 1 177.374 623.832] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4906 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -182.355 -623.832] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-192.866 623.832 Td
-/F147_0 9.9626 Tf
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
-[1 0 0 1 511.108 623.832] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -511.108 -623.832] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-511.108 623.832 Td
-/F130_0 9.9626 Tf
-(9) 4.9813 Tj
-[1 0 0 1 516.09 623.832] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -444.09 -2.1569] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.7983] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -611.877] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 611.877 Td
-/F130_0 9.9626 Tf
-(3.1.2.) 22.4159 Tj
--310 TJm
-(High-le) 30.4357 Tj
-25 TJm
-(v) 4.9813 Tj
-15 TJm
-(el) 7.193 Tj
--250 TJm
-(summary) 37.0808 Tj
-[1 0 0 1 179.287 611.877] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4906 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -184.268 -611.877] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-193.822 611.877 Td
-/F147_0 9.9626 Tf
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
-[1 0 0 1 511.108 611.877] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -511.108 -611.877] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-511.108 611.877 Td
-/F130_0 9.9626 Tf
-(9) 4.9813 Tj
-[1 0 0 1 516.09 611.877] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -444.09 -2.1568] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.7984] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -599.922] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 599.922 Td
-/F130_0 9.9626 Tf
-(3.1.3.) 22.4159 Tj
--310 TJm
-(Utility) 26.0223 Tj
--250 TJm
-(functions) 37.0808 Tj
--250 TJm
-(summary) 37.0808 Tj
-[1 0 0 1 202.669 599.922] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4906 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -207.65 -599.922] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-216.582 599.922 Td
-/F147_0 9.9626 Tf
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
-[1 0 0 1 511.108 599.922] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -511.108 -599.922] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-511.108 599.922 Td
-/F130_0 9.9626 Tf
-(9) 4.9813 Tj
-[1 0 0 1 516.09 599.922] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -444.09 -2.1568] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.7983] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -587.967] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 587.967 Td
-/F130_0 9.9626 Tf
-(3.2.) 14.9439 Tj
--310 TJm
-(Error) 21.0211 Tj
--250 TJm
-(handling) 34.8691 Tj
-[1 0 0 1 148.413 587.967] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4906 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -153.394 -587.967] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-162.611 587.967 Td
-/F147_0 9.9626 Tf
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
-[1 0 0 1 506.127 587.967] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -506.127 -587.967] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-506.127 587.967 Td
-/F130_0 9.9626 Tf
-(10) 9.9626 Tj
-[1 0 0 1 516.09 587.967] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -444.09 -2.1569] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.7983] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -576.012] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 576.012 Td
-/F130_0 9.9626 Tf
-(3.3.) 14.9439 Tj
--310 TJm
-(Lo) 11.0684 Tj
-25 TJm
-(w-le) 17.7035 Tj
-25 TJm
-(v) 4.9813 Tj
-15 TJm
-(el) 7.193 Tj
--250 TJm
-(interf) 21.579 Tj
-10 TJm
-(ace) 13.2702 Tj
-[1 0 0 1 167.571 576.012] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -172.552 -576.012] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-181.045 576.012 Td
-/F147_0 9.9626 Tf
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
-[1 0 0 1 506.127 576.012] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -506.127 -576.012] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-506.127 576.012 Td
-/F130_0 9.9626 Tf
-(11) 9.9626 Tj
-[1 0 0 1 516.09 576.012] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -444.09 -0.0995] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -11.8557] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -564.056] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 564.056 Td
-/F130_0 9.9626 Tf
-(3.3.1.) 22.4159 Tj
-[1 0 0 1 97.5043 564.056] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -97.5043 -564.056] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-97.5043 564.056 Td
-/F134_0 9.9626 Tf
-(BZ2_bzCompressInit) 107.596 Tj
-[1 0 0 1 205.101 564.056] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4906 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -210.082 -564.056] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-219.736 564.056 Td
-/F147_0 9.9626 Tf
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
-[1 0 0 1 506.127 564.056] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -506.127 -564.056] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-506.127 564.056 Td
-/F130_0 9.9626 Tf
-(11) 9.9626 Tj
-[1 0 0 1 516.09 564.056] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -444.09 -1.5341] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -10.421] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -552.101] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 552.101 Td
-/F130_0 9.9626 Tf
-(3.3.2.) 22.4159 Tj
-[1 0 0 1 97.5043 552.101] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -97.5043 -552.101] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-97.5043 552.101 Td
-/F134_0 9.9626 Tf
-(BZ2_bzCompress) 83.6858 Tj
-[1 0 0 1 181.19 552.101] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4906 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -186.172 -552.101] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-194.497 552.101 Td
-/F147_0 9.9626 Tf
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
-[1 0 0 1 506.127 552.101] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -506.127 -552.101] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-506.127 552.101 Td
-/F130_0 9.9626 Tf
-(13) 9.9626 Tj
-[1 0 0 1 516.09 552.101] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -444.09 -1.5342] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -10.421] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -540.146] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 540.146 Td
-/F130_0 9.9626 Tf
-(3.3.3.) 22.4159 Tj
-[1 0 0 1 97.5043 540.146] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -97.5043 -540.146] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-97.5043 540.146 Td
-/F134_0 9.9626 Tf
-(BZ2_bzCompressEnd) 101.619 Tj
-[1 0 0 1 199.123 540.146] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4906 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -204.105 -540.146] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-214.533 540.146 Td
-/F147_0 9.9626 Tf
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
-[1 0 0 1 506.127 540.146] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -506.127 -540.146] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-506.127 540.146 Td
-/F130_0 9.9626 Tf
-(16) 9.9626 Tj
-[1 0 0 1 516.09 540.146] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -444.09 -1.5342] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -10.421] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -528.191] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 528.191 Td
-/F130_0 9.9626 Tf
-(3.3.4.) 22.4159 Tj
-[1 0 0 1 97.5043 528.191] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -97.5043 -528.191] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-97.5043 528.191 Td
-/F134_0 9.9626 Tf
-(BZ2_bzDecompressInit) 119.551 Tj
-[1 0 0 1 217.056 528.191] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4906 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -222.037 -528.191] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-232.355 528.191 Td
-/F147_0 9.9626 Tf
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
-[1 0 0 1 506.127 528.191] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -506.127 -528.191] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-506.127 528.191 Td
-/F130_0 9.9626 Tf
-(16) 9.9626 Tj
-[1 0 0 1 516.09 528.191] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -444.09 -1.5341] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -10.421] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -516.236] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 516.236 Td
-/F130_0 9.9626 Tf
-(3.3.5.) 22.4159 Tj
-[1 0 0 1 97.5043 516.236] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -97.5043 -516.236] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-97.5043 516.236 Td
-/F134_0 9.9626 Tf
-(BZ2_bzDecompress) 95.641 Tj
-[1 0 0 1 193.146 516.236] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4906 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -198.127 -516.236] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-207.116 516.236 Td
-/F147_0 9.9626 Tf
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
-[1 0 0 1 506.127 516.236] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -506.127 -516.236] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-506.127 516.236 Td
-/F130_0 9.9626 Tf
-(17) 9.9626 Tj
-[1 0 0 1 516.09 516.236] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -444.09 -1.5342] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -10.421] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -504.281] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 504.281 Td
-/F130_0 9.9626 Tf
-(3.3.6.) 22.4159 Tj
-[1 0 0 1 97.5043 504.281] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -97.5043 -504.281] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-97.5043 504.281 Td
-/F134_0 9.9626 Tf
-(BZ2_bzDecompressEnd) 113.574 Tj
-[1 0 0 1 211.078 504.281] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -216.06 -504.281] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-224.938 504.281 Td
-/F147_0 9.9626 Tf
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
-[1 0 0 1 506.127 504.281] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -506.127 -504.281] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-506.127 504.281 Td
-/F130_0 9.9626 Tf
-(18) 9.9626 Tj
-[1 0 0 1 516.09 504.281] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -444.09 -1.5342] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -10.421] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -492.325] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 492.325 Td
-/F130_0 9.9626 Tf
-(3.4.) 14.9439 Tj
--310 TJm
-(High-le) 30.4357 Tj
-25 TJm
-(v) 4.9813 Tj
-15 TJm
-(el) 7.193 Tj
--250 TJm
-(interf) 21.579 Tj
-10 TJm
-(ace) 13.2702 Tj
-[1 0 0 1 169.483 492.325] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4906 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -174.465 -492.325] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-184.216 492.325 Td
-/F147_0 9.9626 Tf
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
-[1 0 0 1 506.127 492.325] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -506.127 -492.325] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-506.127 492.325 Td
-/F130_0 9.9626 Tf
-(18) 9.9626 Tj
-[1 0 0 1 516.09 492.325] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -444.09 -2.1568] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.7983] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -480.37] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 480.37 Td
-/F130_0 9.9626 Tf
-(3.4.1.) 22.4159 Tj
-[1 0 0 1 97.5043 480.37] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -97.5043 -480.37] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-97.5043 480.37 Td
-/F134_0 9.9626 Tf
-(BZ2_bzReadOpen) 83.6858 Tj
-[1 0 0 1 181.19 480.37] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4906 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -186.172 -480.37] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-194.497 480.37 Td
-/F147_0 9.9626 Tf
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
-[1 0 0 1 506.127 480.37] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -506.127 -480.37] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-506.127 480.37 Td
-/F130_0 9.9626 Tf
-(19) 9.9626 Tj
-[1 0 0 1 516.09 480.37] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -444.09 -1.5342] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -10.421] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -468.415] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 468.415 Td
-/F130_0 9.9626 Tf
-(3.4.2.) 22.4159 Tj
-[1 0 0 1 97.5043 468.415] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -97.5043 -468.415] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-97.5043 468.415 Td
-/F134_0 9.9626 Tf
-(BZ2_bzRead) 59.7756 Tj
-[1 0 0 1 157.28 468.415] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4906 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -162.261 -468.415] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-171.472 468.415 Td
-/F147_0 9.9626 Tf
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
-[1 0 0 1 506.127 468.415] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -506.127 -468.415] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-506.127 468.415 Td
-/F130_0 9.9626 Tf
-(20) 9.9626 Tj
-[1 0 0 1 516.09 468.415] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -444.09 -1.31] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -10.6452] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -456.46] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 456.46 Td
-/F130_0 9.9626 Tf
-(3.4.3.) 22.4159 Tj
-[1 0 0 1 97.5043 456.46] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -97.5043 -456.46] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-97.5043 456.46 Td
-/F134_0 9.9626 Tf
-(BZ2_bzReadGetUnused) 113.574 Tj
-[1 0 0 1 211.078 456.46] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -216.06 -456.46] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-224.938 456.46 Td
-/F147_0 9.9626 Tf
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
-[1 0 0 1 506.127 456.46] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -506.127 -456.46] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-506.127 456.46 Td
-/F130_0 9.9626 Tf
-(21) 9.9626 Tj
-[1 0 0 1 516.09 456.46] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -444.09 -1.31] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -10.6452] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -444.505] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 444.505 Td
-/F130_0 9.9626 Tf
-(3.4.4.) 22.4159 Tj
-[1 0 0 1 97.5043 444.505] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -97.5043 -444.505] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-97.5043 444.505 Td
-/F134_0 9.9626 Tf
-(BZ2_bzReadClose) 89.6634 Tj
-[1 0 0 1 187.168 444.505] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4906 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -192.149 -444.505] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-201.914 444.505 Td
-/F147_0 9.9626 Tf
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
-[1 0 0 1 506.127 444.505] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -506.127 -444.505] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-506.127 444.505 Td
-/F130_0 9.9626 Tf
-(22) 9.9626 Tj
-[1 0 0 1 516.09 444.505] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -444.09 -1.31] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -10.6451] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -432.55] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 432.55 Td
-/F130_0 9.9626 Tf
-(3.4.5.) 22.4159 Tj
-[1 0 0 1 97.5043 432.55] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -97.5043 -432.55] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-97.5043 432.55 Td
-/F134_0 9.9626 Tf
-(BZ2_bzWriteOpen) 89.6634 Tj
-[1 0 0 1 187.168 432.55] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4906 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -192.149 -432.55] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-201.914 432.55 Td
-/F147_0 9.9626 Tf
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
-[1 0 0 1 506.127 432.55] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -506.127 -432.55] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-506.127 432.55 Td
-/F130_0 9.9626 Tf
-(22) 9.9626 Tj
-[1 0 0 1 516.09 432.55] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -444.09 -1.5342] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -10.421] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -420.594] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 420.594 Td
-/F130_0 9.9626 Tf
-(3.4.6.) 22.4159 Tj
-[1 0 0 1 97.5043 420.594] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -97.5043 -420.594] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-97.5043 420.594 Td
-/F134_0 9.9626 Tf
-(BZ2_bzWrite) 65.7532 Tj
-[1 0 0 1 163.258 420.594] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4906 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -168.239 -420.594] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-176.675 420.594 Td
-/F147_0 9.9626 Tf
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
-[1 0 0 1 506.127 420.594] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -506.127 -420.594] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-506.127 420.594 Td
-/F130_0 9.9626 Tf
-(23) 9.9626 Tj
-[1 0 0 1 516.09 420.594] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -444.09 -1.31] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -10.6452] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -408.639] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 408.639 Td
-/F130_0 9.9626 Tf
-(3.4.7.) 22.4159 Tj
-[1 0 0 1 97.5043 408.639] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -97.5043 -408.639] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-97.5043 408.639 Td
-/F134_0 9.9626 Tf
-(BZ2_bzWriteClose) 95.641 Tj
-[1 0 0 1 193.146 408.639] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4906 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -198.127 -408.639] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-207.116 408.639 Td
-/F147_0 9.9626 Tf
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
-[1 0 0 1 506.127 408.639] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -506.127 -408.639] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-506.127 408.639 Td
-/F130_0 9.9626 Tf
-(23) 9.9626 Tj
-[1 0 0 1 516.09 408.639] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -444.09 -1.31] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -10.6451] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -396.684] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 396.684 Td
-/F130_0 9.9626 Tf
-(3.4.8.) 22.4159 Tj
--310 TJm
-(Handling) 37.0808 Tj
--250 TJm
-(embedded) 40.9463 Tj
--250 TJm
-(compressed) 47.0334 Tj
--250 TJm
-(data) 16.5977 Tj
--250 TJm
-(streams) 30.4357 Tj
-[1 0 0 1 279.56 396.684] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4906 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -284.541 -396.684] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-294.601 396.684 Td
-/F147_0 9.9626 Tf
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
-[1 0 0 1 506.127 396.684] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -506.127 -396.684] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-506.127 396.684 Td
-/F130_0 9.9626 Tf
-(24) 9.9626 Tj
-[1 0 0 1 516.09 396.684] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -444.09 -2.1568] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.7984] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -384.729] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 384.729 Td
-/F130_0 9.9626 Tf
-(3.4.9.) 22.4159 Tj
--310 TJm
-(Standard) 35.417 Tj
--250 TJm
-(\002le-reading/writing) 77.4791 Tj
--250 TJm
-(code) 18.8094 Tj
-[1 0 0 1 234.19 384.729] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4906 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -239.172 -384.729] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-247.564 384.729 Td
-/F147_0 9.9626 Tf
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
-[1 0 0 1 506.127 384.729] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -506.127 -384.729] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-506.127 384.729 Td
-/F130_0 9.9626 Tf
-(25) 9.9626 Tj
-[1 0 0 1 516.09 384.729] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -444.09 -2.1568] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.7984] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -372.774] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 372.774 Td
-/F130_0 9.9626 Tf
-(3.5.) 14.9439 Tj
--310 TJm
-(Utility) 26.0223 Tj
--250 TJm
-(functions) 37.0808 Tj
-[1 0 0 1 155.625 372.774] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4906 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -160.607 -372.774] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-170.645 372.774 Td
-/F147_0 9.9626 Tf
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
-[1 0 0 1 506.127 372.774] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -506.127 -372.774] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-506.127 372.774 Td
-/F130_0 9.9626 Tf
-(26) 9.9626 Tj
-[1 0 0 1 516.09 372.774] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -444.09 -2.1568] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.7983] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -360.819] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 360.819 Td
-/F130_0 9.9626 Tf
-(3.5.1.) 22.4159 Tj
-[1 0 0 1 97.5043 360.819] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -97.5043 -360.819] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-97.5043 360.819 Td
-/F134_0 9.9626 Tf
-(BZ2_bzBuffToBuffCompress) 143.461 Tj
-[1 0 0 1 240.966 360.819] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4906 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -245.948 -360.819] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-255.38 360.819 Td
-/F147_0 9.9626 Tf
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
-[1 0 0 1 506.127 360.819] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -506.127 -360.819] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-506.127 360.819 Td
-/F130_0 9.9626 Tf
-(26) 9.9626 Tj
-[1 0 0 1 516.09 360.819] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -444.09 -1.5342] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -10.421] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -348.863] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 348.863 Td
-/F130_0 9.9626 Tf
-(3.5.2.) 22.4159 Tj
-[1 0 0 1 97.5043 348.863] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -97.5043 -348.863] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-97.5043 348.863 Td
-/F134_0 9.9626 Tf
-(BZ2_bzBuffToBuffDecompress) 155.417 Tj
-[1 0 0 1 252.922 348.863] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4906 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -257.903 -348.863] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-267.999 348.863 Td
-/F147_0 9.9626 Tf
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
-[1 0 0 1 506.127 348.863] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -506.127 -348.863] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-506.127 348.863 Td
-/F130_0 9.9626 Tf
-(27) 9.9626 Tj
-[1 0 0 1 516.09 348.863] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -444.09 -1.5342] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -10.421] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -336.908] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 336.908 Td
-/F130_0 9.9626 Tf
-(3.6.) 14.9439 Tj
-[1 0 0 1 90.0324 336.908] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -90.0324 -336.908] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-90.0324 336.908 Td
-/F134_0 9.9626 Tf
-(zlib) 23.9102 Tj
-[1 0 0 1 113.943 336.908] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -113.943 -336.908] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-116.433 336.908 Td
-/F130_0 9.9626 Tf
-(compatibility) 53.1405 Tj
--250 TJm
-(functions) 37.0808 Tj
-[1 0 0 1 209.144 336.908] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4906 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -214.126 -336.908] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-223.971 336.908 Td
-/F147_0 9.9626 Tf
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
-[1 0 0 1 506.127 336.908] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -506.127 -336.908] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-506.127 336.908 Td
-/F130_0 9.9626 Tf
-(28) 9.9626 Tj
-[1 0 0 1 516.09 336.908] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -444.09 -2.1568] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.7983] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -324.953] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 324.953 Td
-/F130_0 9.9626 Tf
-(3.7.) 14.9439 Tj
--310 TJm
-(Using) 23.8007 Tj
--250 TJm
-(the) 12.1743 Tj
--250 TJm
-(library) 26.5603 Tj
--250 TJm
-(in) 7.7509 Tj
--250 TJm
-(a) 4.42339 Tj
-[1 0 0 1 177.195 324.953] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -177.195 -324.953] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-177.195 324.953 Td
-/F134_0 9.9626 Tf
-(stdio) 29.8878 Tj
-[1 0 0 1 207.083 324.953] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -207.083 -324.953] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-207.083 324.953 Td
-/F130_0 9.9626 Tf
-(-free) 18.7994 Tj
--250 TJm
-(en) 9.40469 Tj
-40 TJm
-(vironment) 40.9562 Tj
-[1 0 0 1 278.335 324.953] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -283.316 -324.953] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-291.775 324.953 Td
-/F147_0 9.9626 Tf
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
-[1 0 0 1 506.127 324.953] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -506.127 -324.953] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-506.127 324.953 Td
-/F130_0 9.9626 Tf
-(28) 9.9626 Tj
-[1 0 0 1 516.09 324.953] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -444.09 -2.1569] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.7983] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -312.998] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 312.998 Td
-/F130_0 9.9626 Tf
-(3.7.1.) 22.4159 Tj
--310 TJm
-(Getting) 29.8878 Tj
--250 TJm
-(rid) 11.0684 Tj
--250 TJm
-(of) 8.29885 Tj
-[1 0 0 1 154.231 312.998] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -154.231 -312.998] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-154.231 312.998 Td
-/F134_0 9.9626 Tf
-(stdio) 29.8878 Tj
-[1 0 0 1 184.119 312.998] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4906 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -189.1 -312.998] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-198.175 312.998 Td
-/F147_0 9.9626 Tf
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
-[1 0 0 1 506.127 312.998] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -506.127 -312.998] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-506.127 312.998 Td
-/F130_0 9.9626 Tf
-(29) 9.9626 Tj
-[1 0 0 1 516.09 312.998] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -444.09 -2.1568] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.7984] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -301.043] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 301.043 Td
-/F130_0 9.9626 Tf
-(3.7.2.) 22.4159 Tj
--310 TJm
-(Critical) 29.8878 Tj
--250 TJm
-(error) 19.3573 Tj
--250 TJm
-(handling) 34.8691 Tj
-[1 0 0 1 186.599 301.043] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4906 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -191.58 -301.043] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-201.629 301.043 Td
-/F147_0 9.9626 Tf
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
-[1 0 0 1 506.127 301.043] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -506.127 -301.043] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-506.127 301.043 Td
-/F130_0 9.9626 Tf
-(29) 9.9626 Tj
-[1 0 0 1 516.09 301.043] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -444.09 -2.1568] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.7983] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -289.088] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 289.088 Td
-/F130_0 9.9626 Tf
-(3.8.) 14.9439 Tj
--310 TJm
-(Making) 30.9936 Tj
--250 TJm
-(a) 4.42339 Tj
--250 TJm
-(W) 9.40469 Tj
-40 TJm
-(indo) 17.7135 Tj
-25 TJm
-(ws) 11.0684 Tj
--250 TJm
-(DLL) 19.3673 Tj
-[1 0 0 1 189.828 289.088] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4906 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -194.809 -289.088] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-203.243 289.088 Td
-/F147_0 9.9626 Tf
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
-[1 0 0 1 506.127 289.088] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -506.127 -289.088] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-506.127 289.088 Td
-/F130_0 9.9626 Tf
-(29) 9.9626 Tj
-[1 0 0 1 516.09 289.088] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -444.09 -2.1569] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.9626] cm
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-[1 0 0 1 0 -9.9626] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -267.006] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 257.207 Td
-/F130_0 9.9626 Tf
-(This) 17.7135 Tj
--250 TJm
-(chapter) 29.3199 Tj
--250 TJm
-(describes) 37.0708 Tj
--250 TJm
-(the) 12.1743 Tj
--250 TJm
-(programming) 54.2364 Tj
--250 TJm
-(interf) 21.579 Tj
-10 TJm
-(ace) 13.2702 Tj
--250 TJm
-(to) 7.7509 Tj
-[1 0 0 1 282.448 257.207] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -282.448 -257.207] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-282.448 257.207 Td
-/F134_0 9.9626 Tf
-(libbzip2) 47.8205 Tj
-[1 0 0 1 330.269 257.207] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -330.269 -257.207] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-330.269 257.207 Td
-/F130_0 9.9626 Tf
-(.) 2.49065 Tj
-[1 0 0 1 72 255.05] cm
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-[1 0 0 1 0 -9.9627] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -245.088] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 235.289 Td
-/F130_0 9.9626 Tf
-(F) 5.53921 Tj
-15 TJm
-(or) 8.29885 Tj
--273 TJm
-(general) 29.3199 Tj
--272 TJm
-(background) 47.0334 Tj
--273 TJm
-(information,) 49.534 Tj
--278 TJm
-(particularly) 45.9276 Tj
--273 TJm
-(about) 22.1369 Tj
--273 TJm
-(memory) 33.2053 Tj
--272 TJm
-(use) 13.2801 Tj
--273 TJm
-(and) 14.386 Tj
--273 TJm
-(performance) 50.341 Tj
--272 TJm
-(aspects,) 31.2626 Tj
--279 TJm
-(you') 18.2614 Tj
-50 TJm
-(d) 4.9813 Tj
--272 TJm
-(be) 9.40469 Tj
--273 TJm
-(well) 17.1556 Tj
--273 TJm
-(advised) 30.4357 Tj
-72 223.334 Td
-(to) 7.7509 Tj
--250 TJm
-(read) 17.1456 Tj
-[1 0 0 1 101.878 223.334] cm
-/DeviceRGB {} cs
-[0 0 1] sc
-/DeviceRGB {} CS
-[0 0 1] SC
-[1 0 0 1 -101.878 -223.334] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-101.878 223.334 Td
-/F130_0 9.9626 Tf
-(Ho) 12.1743 Tj
-25 TJm
-(w) 7.193 Tj
--250 TJm
-(to) 7.7509 Tj
--250 TJm
-(use) 13.2801 Tj
--250 TJm
-(bzip2) 22.1369 Tj
-[1 0 0 1 171.636 223.334] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 1] sc
-/DeviceRGB {} CS
-[0 0 1] SC
-/DeviceRGB {} cs
-[0 0 1] sc
-/DeviceRGB {} CS
-[0 0 1] SC
-[1 0 0 1 -171.636 -223.334] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-174.126 223.334 Td
-/F130_0 9.9626 Tf
-([2]) 11.6164 Tj
-[1 0 0 1 185.743 223.334] cm
-/DeviceRGB {} cs
-[0 0 1] sc
-/DeviceRGB {} CS
-[0 0 1] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -185.743 -223.334] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-188.233 223.334 Td
-/F130_0 9.9626 Tf
-(as) 8.29885 Tj
--250 TJm
-(well.) 19.6462 Tj
-[1 0 0 1 72 221.177] cm
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.9626] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -211.215] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 188.581 Td
-/F122_0 20.6585 Tf
-(3.1.) 34.4584 Tj
--278 TJm
-(T) 12.6223 Tj
-80 TJm
-(op-le) 49.3532 Tj
-15 TJm
-(vel) 28.7153 Tj
--278 TJm
-(structure) 89.5339 Tj
-[1 0 0 1 72 184.305] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.9627] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -174.343] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 166.664 Td
-/F134_0 9.9626 Tf
-(libbzip2) 47.8205 Tj
-[1 0 0 1 119.821 166.664] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -119.821 -166.664] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-123.608 166.664 Td
-/F130_0 9.9626 Tf
-(is) 6.64505 Tj
--380 TJm
-(a) 4.42339 Tj
--380 TJm
-(\003e) 9.9626 Tj
-15 TJm
-(xible) 19.9252 Tj
--381 TJm
-(library) 26.5603 Tj
--380 TJm
-(for) 11.6164 Tj
--380 TJm
-(compressing) 50.3609 Tj
--380 TJm
-(and) 14.386 Tj
--380 TJm
-(decompressing) 59.7656 Tj
--380 TJm
-(data) 16.5977 Tj
--381 TJm
-(in) 7.7509 Tj
--380 TJm
-(the) 12.1743 Tj
-[1 0 0 1 405.291 166.664] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -405.291 -166.664] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-405.291 166.664 Td
-/F134_0 9.9626 Tf
-(bzip2) 29.8878 Tj
-[1 0 0 1 435.178 166.664] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -435.178 -166.664] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-438.966 166.664 Td
-/F130_0 9.9626 Tf
-(data) 16.5977 Tj
--380 TJm
-(format.) 29.0509 Tj
--1401 TJm
-(Although) 37.6387 Tj
-72 154.708 Td
-(packaged) 37.6188 Tj
--285 TJm
-(as) 8.29885 Tj
--284 TJm
-(a) 4.42339 Tj
--285 TJm
-(single) 23.8007 Tj
--285 TJm
-(entity) 22.6948 Tj
-65 TJm
-(,) 2.49065 Tj
--293 TJm
-(it) 5.53921 Tj
--285 TJm
-(helps) 21.031 Tj
--285 TJm
-(to) 7.7509 Tj
--284 TJm
-(re) 7.74094 Tj
-15 TJm
-(g) 4.9813 Tj
-5 TJm
-(ard) 12.7222 Tj
--285 TJm
-(the) 12.1743 Tj
--285 TJm
-(library) 26.5603 Tj
--284 TJm
-(as) 8.29885 Tj
--285 TJm
-(three) 19.9152 Tj
--285 TJm
-(separate) 32.6375 Tj
--284 TJm
-(parts:) 22.1369 Tj
--380 TJm
-(the) 12.1743 Tj
--285 TJm
-(lo) 7.7509 Tj
-25 TJm
-(w) 7.193 Tj
--284 TJm
-(le) 7.193 Tj
-25 TJm
-(v) 4.9813 Tj
-15 TJm
-(el) 7.193 Tj
--285 TJm
-(interf) 21.579 Tj
-10 TJm
-(ace,) 15.7608 Tj
--293 TJm
-(and) 14.386 Tj
--285 TJm
-(the) 12.1743 Tj
--285 TJm
-(high) 17.7135 Tj
-72 142.753 Td
-(le) 7.193 Tj
-25 TJm
-(v) 4.9813 Tj
-15 TJm
-(el) 7.193 Tj
--250 TJm
-(interf) 21.579 Tj
-10 TJm
-(ace,) 15.7608 Tj
--250 TJm
-(and) 14.386 Tj
--250 TJm
-(some) 21.031 Tj
--250 TJm
-(utility) 23.8106 Tj
--250 TJm
-(functions.) 39.5714 Tj
-[1 0 0 1 72 140.596] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.9626] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -130.634] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 120.835 Td
-/F130_0 9.9626 Tf
-(The) 15.4918 Tj
--349 TJm
-(structure) 34.8591 Tj
--349 TJm
-(of) 8.29885 Tj
-[1 0 0 1 141.082 120.835] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -141.082 -120.835] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-141.082 120.835 Td
-/F134_0 9.9626 Tf
-(libbzip2) 47.8205 Tj
-[1 0 0 1 188.903 120.835] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -188.903 -120.835] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-188.903 120.835 Td
-/F130_0 9.9626 Tf
-(') 3.31755 Tj
-55 TJm
-(s) 3.87545 Tj
--349 TJm
-(interf) 21.579 Tj
-10 TJm
-(aces) 17.1456 Tj
--349 TJm
-(is) 6.64505 Tj
--349 TJm
-(similar) 27.6761 Tj
--349 TJm
-(to) 7.7509 Tj
--349 TJm
-(that) 14.9439 Tj
--349 TJm
-(of) 8.29885 Tj
--349 TJm
-(Jean-loup) 38.7346 Tj
--349 TJm
-(Gailly') 28.224 Tj
-55 TJm
-(s) 3.87545 Tj
--349 TJm
-(and) 14.386 Tj
--349 TJm
-(Mark) 21.579 Tj
--349 TJm
-(Adler') 26.0024 Tj
-55 TJm
-(s) 3.87545 Tj
--349 TJm
-(e) 4.42339 Tj
-15 TJm
-(xcellent) 31.5416 Tj
-[1 0 0 1 516.09 120.835] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -516.09 -120.835] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-516.09 120.835 Td
-/F134_0 9.9626 Tf
-(zlib) 23.9102 Tj
-[1 0 0 1 540 120.835] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -540 -120.835] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 108.88 Td
-/F130_0 9.9626 Tf
-(library) 26.5603 Tj
-65 TJm
-(.) 2.49065 Tj
-[1 0 0 1 72 106.723] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.9626] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -96.7608] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 86.9624 Td
-/F130_0 9.9626 Tf
-(All) 12.7322 Tj
--242 TJm
-(e) 4.42339 Tj
-15 TJm
-(xternally) 35.417 Tj
--242 TJm
-(visible) 26.5703 Tj
--241 TJm
-(symbols) 33.2153 Tj
--242 TJm
-(ha) 9.40469 Tj
-20 TJm
-(v) 4.9813 Tj
-15 TJm
-(e) 4.42339 Tj
--242 TJm
-(names) 25.4544 Tj
--242 TJm
-(be) 9.40469 Tj
-15 TJm
-(ginning) 30.4457 Tj
-[1 0 0 1 284.687 86.9624] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -284.687 -86.9624] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-284.687 86.9624 Td
-/F134_0 9.9626 Tf
-(BZ2_) 23.9102 Tj
-[1 0 0 1 308.597 86.9624] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -308.597 -86.9624] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-308.597 86.9624 Td
-/F130_0 9.9626 Tf
-(.) 2.49065 Tj
--615 TJm
-(This) 17.7135 Tj
--241 TJm
-(is) 6.64505 Tj
--242 TJm
-(ne) 9.40469 Tj
-25 TJm
-(w) 7.193 Tj
--242 TJm
-(in) 7.7509 Tj
--242 TJm
-(v) 4.9813 Tj
-15 TJm
-(ersion) 24.3486 Tj
--242 TJm
-(1.0.) 14.9439 Tj
--614 TJm
-(The) 15.4918 Tj
--242 TJm
-(intention) 35.427 Tj
--242 TJm
-(is) 6.64505 Tj
--241 TJm
-(to) 7.7509 Tj
--242 TJm
-(minimise) 37.0908 Tj
-72 75.0073 Td
-(pollution) 35.9849 Tj
--250 TJm
-(of) 8.29885 Tj
--250 TJm
-(the) 12.1743 Tj
--250 TJm
-(namespaces) 47.5814 Tj
--250 TJm
-(of) 8.29885 Tj
--250 TJm
-(library) 26.5603 Tj
--250 TJm
-(clients.) 28.503 Tj
-[1 0 0 1 72 72.8505] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -21.9987] cm
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-[1 0 0 1 1.8929 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 4.3836 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 374.394 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 6.8541] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 43.0633 -6.7545] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -498.225 -50.9514] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-541.288 50.9514 Td
-/F130_0 9.9626 Tf
-(8) 4.9813 Tj
-[1 0 0 1 455.161 50.8518] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 93.5986 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 6.2765 0] cm
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-[1 0 0 1 -15.0366 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-Q
-showpage
-%%PageTrailer
-pdfEndPage
-%%Page: 12 12
-%%BeginPageSetup
-%%PageOrientation: Portrait
-pdfStartPage
-0 0 612 792 re W
-%%EndPageSetup
-[] 0 d
-1 i
-0 j
-0 J
-10 M
-1 w
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-false op
-false OP
-0 0 612 792 re
-W
-q
-[1 0 0 1 72 741.554] cm
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-[1 0 0 1 1.8929 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 4.3836 14.4459] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 187.197 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4906 -8.9114] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 8.9114] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 76.4979 -6.7546] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -344.462 -749.245] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-420.96 749.245 Td
-/F130_0 9.9626 Tf
-(Programming) 54.7943 Tj
--250 TJm
-(with) 17.7135 Tj
-[1 0 0 1 498.449 749.245] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -498.449 -749.245] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-498.449 749.245 Td
-/F134_0 9.9626 Tf
-(libbzip2) 47.8205 Tj
-[1 0 0 1 546.269 749.245] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -278.305 -2.1568] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 280.796 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -472.974 -5.0363] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -0.4981] cm
-q
-[] 0 d
-0 J
-0.4981 w
-0 0.2491 m
-475.465 0.2491 l
-S
-Q
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 479.251 0] cm
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-[1 0 0 1 -15.0365 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -468 -21.5542] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -720] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 710.037 Td
-/F130_0 9.9626 Tf
-(T) 6.08715 Tj
-80 TJm
-(o) 4.9813 Tj
--250 TJm
-(use) 13.2801 Tj
--250 TJm
-(an) 9.40469 Tj
-15 TJm
-(y) 4.9813 Tj
--250 TJm
-(part) 15.4918 Tj
--250 TJm
-(of) 8.29885 Tj
--250 TJm
-(the) 12.1743 Tj
--250 TJm
-(library) 26.5603 Tj
-65 TJm
-(,) 2.49065 Tj
--250 TJm
-(you) 14.9439 Tj
--250 TJm
-(need) 18.8094 Tj
--250 TJm
-(to) 7.7509 Tj
-[1 0 0 1 240.567 710.037] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -240.567 -710.037] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-240.567 710.037 Td
-/F134_0 9.9626 Tf
-(#include) 47.8205 Tj
--600 TJm
-(<bzlib.h>) 53.798 Tj
-[1 0 0 1 348.163 710.037] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -348.163 -710.037] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-350.654 710.037 Td
-/F130_0 9.9626 Tf
-(into) 15.5018 Tj
--250 TJm
-(your) 18.2614 Tj
--250 TJm
-(sources.) 32.3685 Tj
-[1 0 0 1 72 707.88] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.9626] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -697.918] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 679.416 Td
-/F122_0 17.2154 Tf
-(3.1.1.) 43.0729 Tj
--278 TJm
-(Lo) 21.0372 Tj
-15 TJm
-(w-le) 33.484 Tj
-15 TJm
-(vel) 23.9294 Tj
--278 TJm
-(summar) 66.9679 Tj
--10 TJm
-(y) 9.57176 Tj
-[1 0 0 1 72 675.853] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.9627] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -665.89] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 657.498 Td
-/F130_0 9.9626 Tf
-(This) 17.7135 Tj
--212 TJm
-(interf) 21.579 Tj
-10 TJm
-(ace) 13.2702 Tj
--212 TJm
-(pro) 13.2801 Tj
-15 TJm
-(vides) 21.031 Tj
--212 TJm
-(services) 32.0895 Tj
--212 TJm
-(for) 11.6164 Tj
--212 TJm
-(compressing) 50.3609 Tj
--212 TJm
-(and) 14.386 Tj
--212 TJm
-(decompress) 47.0334 Tj
-1 TJm
-(ing) 12.7322 Tj
--212 TJm
-(data) 16.5977 Tj
--212 TJm
-(in) 7.7509 Tj
--212 TJm
-(memory) 33.2053 Tj
-65 TJm
-(.) 2.49065 Tj
--595 TJm
-(There') 26.5503 Tj
-55 TJm
-(s) 3.87545 Tj
--212 TJm
-(no) 9.9626 Tj
--212 TJm
-(pro) 13.2801 Tj
-15 TJm
-(vision) 24.3586 Tj
--212 TJm
-(for) 11.6164 Tj
--212 TJm
-(dealing) 29.3299 Tj
-72 645.543 Td
-(with) 17.7135 Tj
--213 TJm
-(\002les,) 19.0983 Tj
--220 TJm
-(streams) 30.4357 Tj
--213 TJm
-(or) 8.29885 Tj
--213 TJm
-(an) 9.40469 Tj
-15 TJm
-(y) 4.9813 Tj
--213 TJm
-(other) 20.4731 Tj
--213 TJm
-(I/O) 13.2801 Tj
--213 TJm
-(mechanisms,) 51.7457 Tj
--221 TJm
-(just) 14.396 Tj
--213 TJm
-(straight) 29.8878 Tj
--213 TJm
-(memory-to-memory) 80.7967 Tj
--213 TJm
-(w) 7.193 Tj
-10 TJm
-(ork.) 15.7708 Tj
--595 TJm
-(In) 8.29885 Tj
--213 TJm
-(f) 3.31755 Tj
-10 TJm
-(act,) 14.107 Tj
--221 TJm
-(this) 14.396 Tj
--213 TJm
-(part) 15.4918 Tj
--213 TJm
-(of) 8.29885 Tj
--213 TJm
-(the) 12.1743 Tj
--213 TJm
-(library) 26.5603 Tj
-72 633.588 Td
-(can) 13.8281 Tj
--250 TJm
-(be) 9.40469 Tj
--250 TJm
-(compiled) 37.0808 Tj
--250 TJm
-(without) 30.4457 Tj
--250 TJm
-(inclusion) 36.5329 Tj
--250 TJm
-(of) 8.29885 Tj
-[1 0 0 1 222.534 633.588] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -222.534 -633.588] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-222.534 633.588 Td
-/F134_0 9.9626 Tf
-(stdio.h) 41.8429 Tj
-[1 0 0 1 264.377 633.588] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -264.377 -633.588] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-264.377 633.588 Td
-/F130_0 9.9626 Tf
-(,) 2.49065 Tj
--250 TJm
-(which) 24.3486 Tj
--250 TJm
-(may) 17.1556 Tj
--250 TJm
-(be) 9.40469 Tj
--250 TJm
-(helpful) 28.224 Tj
--250 TJm
-(for) 11.6164 Tj
--250 TJm
-(embedded) 40.9463 Tj
--250 TJm
-(applications.) 50.6399 Tj
-[1 0 0 1 72 631.431] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.9626] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -621.469] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 611.67 Td
-/F130_0 9.9626 Tf
-(The) 15.4918 Tj
--250 TJm
-(lo) 7.7509 Tj
-25 TJm
-(w-le) 17.7035 Tj
-25 TJm
-(v) 4.9813 Tj
-15 TJm
-(el) 7.193 Tj
--250 TJm
-(part) 15.4918 Tj
--250 TJm
-(of) 8.29885 Tj
--250 TJm
-(the) 12.1743 Tj
--250 TJm
-(library) 26.5603 Tj
--250 TJm
-(has) 13.2801 Tj
--250 TJm
-(no) 9.9626 Tj
--250 TJm
-(global) 24.9065 Tj
--250 TJm
-(v) 4.9813 Tj
-25 TJm
-(ariables) 30.9837 Tj
--250 TJm
-(and) 14.386 Tj
--250 TJm
-(is) 6.64505 Tj
--250 TJm
-(therefore) 35.955 Tj
--250 TJm
-(thread-safe.) 46.7445 Tj
-[1 0 0 1 72 609.513] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.9626] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -599.551] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 589.752 Td
-/F130_0 9.9626 Tf
-(Six) 13.2901 Tj
--875 TJm
-(routines) 32.0995 Tj
--876 TJm
-(mak) 17.1556 Tj
-10 TJm
-(e) 4.42339 Tj
--875 TJm
-(up) 9.9626 Tj
--876 TJm
-(the) 12.1743 Tj
--875 TJm
-(lo) 7.7509 Tj
-25 TJm
-(w) 7.193 Tj
--876 TJm
-(le) 7.193 Tj
-25 TJm
-(v) 4.9813 Tj
-15 TJm
-(el) 7.193 Tj
--875 TJm
-(interf) 21.579 Tj
-10 TJm
-(ace:) 16.0398 Tj
-[1 0 0 1 308.791 589.752] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -308.791 -589.752] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-308.791 589.752 Td
-/F134_0 9.9626 Tf
-(BZ2_bzCompressInit) 107.596 Tj
-[1 0 0 1 416.387 589.752] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -416.387 -589.752] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-416.387 589.752 Td
-/F130_0 9.9626 Tf
-(,) 2.49065 Tj
-[1 0 0 1 429.158 589.752] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -429.158 -589.752] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-429.158 589.752 Td
-/F134_0 9.9626 Tf
-(BZ2_bzCompress) 83.6858 Tj
-[1 0 0 1 512.844 589.752] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -512.844 -589.752] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-512.844 589.752 Td
-/F130_0 9.9626 Tf
-(,) 2.49065 Tj
--1032 TJm
-(and) 14.386 Tj
-[1 0 0 1 72 577.797] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -577.797] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 577.797 Td
-/F134_0 9.9626 Tf
-(BZ2_bzCompressEnd) 101.619 Tj
-[1 0 0 1 173.619 577.797] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -173.619 -577.797] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-186.15 577.797 Td
-/F130_0 9.9626 Tf
-(for) 11.6164 Tj
--1258 TJm
-(compression,) 52.8516 Tj
--1510 TJm
-(and) 14.386 Tj
--1257 TJm
-(a) 4.42339 Tj
--1258 TJm
-(corresponding) 56.996 Tj
--1258 TJm
-(trio) 13.8381 Tj
-[1 0 0 1 417.958 577.797] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -417.958 -577.797] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-417.958 577.797 Td
-/F134_0 9.9626 Tf
-(BZ2_bzDecompressInit) 119.551 Tj
-[1 0 0 1 537.509 577.797] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -537.509 -577.797] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-537.509 577.797 Td
-/F130_0 9.9626 Tf
-(,) 2.49065 Tj
-[1 0 0 1 72 565.842] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -565.842] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 565.842 Td
-/F134_0 9.9626 Tf
-(BZ2_bzDecompress) 95.641 Tj
-[1 0 0 1 167.641 565.842] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -167.641 -565.842] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-172.707 565.842 Td
-/F130_0 9.9626 Tf
-(and) 14.386 Tj
-[1 0 0 1 192.158 565.842] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -192.158 -565.842] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-192.158 565.842 Td
-/F134_0 9.9626 Tf
-(BZ2_bzDecompressEnd) 113.574 Tj
-[1 0 0 1 305.732 565.842] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -305.732 -565.842] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-310.798 565.842 Td
-/F130_0 9.9626 Tf
-(for) 11.6164 Tj
--508 TJm
-(decompression.) 62.2563 Tj
--2171 TJm
-(The) 15.4918 Tj
-[1 0 0 1 431.918 565.842] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -431.918 -565.842] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-431.918 564.099 Td
-/F134_0 9.9626 Tf
-(*) 5.97756 Tj
-437.895 565.842 Td
-(Init) 23.9102 Tj
-[1 0 0 1 461.805 565.842] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -461.805 -565.842] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-466.871 565.842 Td
-/F130_0 9.9626 Tf
-(functions) 37.0808 Tj
--508 TJm
-(allocate) 30.9837 Tj
-72 553.887 Td
-(memory) 33.2053 Tj
--574 TJm
-(for) 11.6164 Tj
--573 TJm
-(compression/decompression) 112.896 Tj
--574 TJm
-(and) 14.386 Tj
--574 TJm
-(do) 9.9626 Tj
--573 TJm
-(other) 20.4731 Tj
--574 TJm
-(initialisations,) 56.1891 Tj
--654 TJm
-(whilst) 24.3586 Tj
--574 TJm
-(the) 12.1743 Tj
-[1 0 0 1 419.502 553.887] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -419.502 -553.887] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-419.502 552.144 Td
-/F134_0 9.9626 Tf
-(*) 5.97756 Tj
-425.48 553.887 Td
-(End) 17.9327 Tj
-[1 0 0 1 443.413 553.887] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -443.413 -553.887] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-449.128 553.887 Td
-/F130_0 9.9626 Tf
-(functions) 37.0808 Tj
--574 TJm
-(close) 20.4731 Tj
--573 TJm
-(do) 9.9626 Tj
-25 TJm
-(wn) 12.1743 Tj
-72 541.932 Td
-(operations) 41.5042 Tj
--250 TJm
-(and) 14.386 Tj
--250 TJm
-(release) 27.6562 Tj
--250 TJm
-(memory) 33.2053 Tj
-65 TJm
-(.) 2.49065 Tj
-[1 0 0 1 72 539.775] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.9626] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -529.812] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 520.014 Td
-/F130_0 9.9626 Tf
-(The) 15.4918 Tj
--303 TJm
-(real) 14.9339 Tj
--303 TJm
-(w) 7.193 Tj
-10 TJm
-(ork) 13.2801 Tj
--303 TJm
-(is) 6.64505 Tj
--303 TJm
-(done) 19.3673 Tj
--303 TJm
-(by) 9.9626 Tj
-[1 0 0 1 176.892 520.014] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -176.892 -520.014] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-176.892 520.014 Td
-/F134_0 9.9626 Tf
-(BZ2_bzCompress) 83.6858 Tj
-[1 0 0 1 260.578 520.014] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -260.578 -520.014] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-263.598 520.014 Td
-/F130_0 9.9626 Tf
-(and) 14.386 Tj
-[1 0 0 1 281.003 520.014] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -281.003 -520.014] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-281.003 520.014 Td
-/F134_0 9.9626 Tf
-(BZ2_bzDecompress) 95.641 Tj
-[1 0 0 1 376.645 520.014] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -376.645 -520.014] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-376.645 520.014 Td
-/F130_0 9.9626 Tf
-(.) 2.49065 Tj
--939 TJm
-(These) 23.7907 Tj
--303 TJm
-(compress) 37.6287 Tj
--303 TJm
-(and) 14.386 Tj
--303 TJm
-(decompress) 47.0334 Tj
--303 TJm
-(data) 16.5977 Tj
-72 508.059 Td
-(from) 19.3673 Tj
--205 TJm
-(a) 4.42339 Tj
--205 TJm
-(user) 16.5977 Tj
-20 TJm
-(-supplied) 37.0808 Tj
--205 TJm
-(input) 20.4831 Tj
--206 TJm
-(b) 4.9813 Tj
-20 TJm
-(uf) 8.29885 Tj
-25 TJm
-(fer) 11.0585 Tj
--205 TJm
-(to) 7.7509 Tj
--205 TJm
-(a) 4.42339 Tj
--205 TJm
-(user) 16.5977 Tj
-20 TJm
-(-supplied) 37.0808 Tj
--205 TJm
-(output) 25.4644 Tj
--205 TJm
-(b) 4.9813 Tj
-20 TJm
-(uf) 8.29885 Tj
-25 TJm
-(fer) 11.0585 Tj
-55 TJm
-(.) 2.49065 Tj
--591 TJm
-(These) 23.7907 Tj
--205 TJm
-(b) 4.9813 Tj
-20 TJm
-(uf) 8.29885 Tj
-25 TJm
-(fers) 14.9339 Tj
--205 TJm
-(can) 13.8281 Tj
--205 TJm
-(be) 9.40469 Tj
--205 TJm
-(an) 9.40469 Tj
-15 TJm
-(y) 4.9813 Tj
--205 TJm
-(size;) 18.2614 Tj
--220 TJm
-(arbitrary) 34.3012 Tj
--206 TJm
-(quantities) 38.7446 Tj
--205 TJm
-(of) 8.29885 Tj
-72 496.104 Td
-(data) 16.5977 Tj
--258 TJm
-(are) 12.1643 Tj
--258 TJm
-(handled) 31.5416 Tj
--258 TJm
-(by) 9.9626 Tj
--257 TJm
-(making) 29.8878 Tj
--258 TJm
-(repeated) 33.7433 Tj
--258 TJm
-(calls) 18.2614 Tj
--258 TJm
-(to) 7.7509 Tj
--258 TJm
-(these) 20.4731 Tj
--258 TJm
-(functions.) 39.5714 Tj
--667 TJm
-(This) 17.7135 Tj
--258 TJm
-(is) 6.64505 Tj
--258 TJm
-(a) 4.42339 Tj
--257 TJm
-(\003e) 9.9626 Tj
-15 TJm
-(xible) 19.9252 Tj
--258 TJm
-(mechanism) 45.3796 Tj
--258 TJm
-(allo) 14.9439 Tj
-25 TJm
-(wing) 19.9252 Tj
--258 TJm
-(a) 4.42339 Tj
--258 TJm
-(consumer) 38.7346 Tj
-20 TJm
-(-pull) 18.8194 Tj
-72 484.148 Td
-(style) 18.8194 Tj
--250 TJm
-(of) 8.29885 Tj
--250 TJm
-(acti) 14.386 Tj
-25 TJm
-(vity) 15.5018 Tj
-65 TJm
-(,) 2.49065 Tj
--250 TJm
-(or) 8.29885 Tj
--250 TJm
-(producer) 35.4071 Tj
-20 TJm
-(-push,) 24.6275 Tj
--250 TJm
-(or) 8.29885 Tj
--250 TJm
-(a) 4.42339 Tj
--250 TJm
-(mixture) 30.9936 Tj
--250 TJm
-(of) 8.29885 Tj
--250 TJm
-(both.) 20.2042 Tj
-[1 0 0 1 72 481.992] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.9626] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -472.029] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 453.527 Td
-/F122_0 17.2154 Tf
-(3.1.2.) 43.0729 Tj
--278 TJm
-(High-le) 58.343 Tj
-15 TJm
-(vel) 23.9294 Tj
--278 TJm
-(summar) 66.9679 Tj
--10 TJm
-(y) 9.57176 Tj
-[1 0 0 1 72 449.697] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.9626] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -439.734] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 431.61 Td
-/F130_0 9.9626 Tf
-(This) 17.7135 Tj
--284 TJm
-(interf) 21.579 Tj
-10 TJm
-(ace) 13.2702 Tj
--284 TJm
-(pro) 13.2801 Tj
-15 TJm
-(vides) 21.031 Tj
--285 TJm
-(some) 21.031 Tj
--284 TJm
-(handy) 24.3486 Tj
--284 TJm
-(wrappers) 36.5129 Tj
--284 TJm
-(around) 27.6661 Tj
--284 TJm
-(the) 12.1743 Tj
--284 TJm
-(lo) 7.7509 Tj
-25 TJm
-(w-le) 17.7035 Tj
-25 TJm
-(v) 4.9813 Tj
-15 TJm
-(el) 7.193 Tj
--285 TJm
-(interf) 21.579 Tj
-10 TJm
-(ace) 13.2702 Tj
--284 TJm
-(to) 7.7509 Tj
--284 TJm
-(f) 3.31755 Tj
-10 TJm
-(acilitate) 31.5416 Tj
--284 TJm
-(reading) 29.8778 Tj
--284 TJm
-(and) 14.386 Tj
--285 TJm
-(writ) 16.0497 Tj
-1 TJm
-(ing) 12.7322 Tj
-[1 0 0 1 510.112 431.61] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -510.112 -431.61] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-510.112 431.61 Td
-/F134_0 9.9626 Tf
-(bzip2) 29.8878 Tj
-[1 0 0 1 540 431.61] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -540 -431.61] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 419.654 Td
-/F130_0 9.9626 Tf
-(format) 26.5603 Tj
--347 TJm
-(\002les) 16.6077 Tj
--346 TJm
-(\() 3.31755 Tj
-[1 0 0 1 125.391 419.654] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -125.391 -419.654] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-125.391 419.654 Td
-/F134_0 9.9626 Tf
-(.bz2) 23.9102 Tj
-[1 0 0 1 149.301 419.654] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -149.301 -419.654] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-152.754 419.654 Td
-/F130_0 9.9626 Tf
-(\002les\).) 22.4159 Tj
--1200 TJm
-(The) 15.4918 Tj
--346 TJm
-(routines) 32.0995 Tj
--347 TJm
-(pro) 13.2801 Tj
-15 TJm
-(vide) 17.1556 Tj
--346 TJm
-(hooks) 23.8007 Tj
--347 TJm
-(to) 7.7509 Tj
--346 TJm
-(f) 3.31755 Tj
-10 TJm
-(acilitate) 31.5416 Tj
--347 TJm
-(reading) 29.8778 Tj
--347 TJm
-(\002les) 16.6077 Tj
--346 TJm
-(in) 7.7509 Tj
--347 TJm
-(which) 24.3486 Tj
--346 TJm
-(the) 12.1743 Tj
-[1 0 0 1 460.049 419.654] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -460.049 -419.654] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-460.049 419.654 Td
-/F134_0 9.9626 Tf
-(bzip2) 29.8878 Tj
-[1 0 0 1 489.937 419.654] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -489.937 -419.654] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-493.39 419.654 Td
-/F130_0 9.9626 Tf
-(data) 16.5977 Tj
--347 TJm
-(stream) 26.5603 Tj
-72 407.699 Td
-(is) 6.64505 Tj
--339 TJm
-(embedded) 40.9463 Tj
--339 TJm
-(within) 25.4644 Tj
--339 TJm
-(some) 21.031 Tj
--339 TJm
-(lar) 10.5105 Tj
-18 TJm
-(ger) 12.7222 Tj
-20 TJm
-(-scale) 23.2328 Tj
--339 TJm
-(\002le) 12.7322 Tj
--339 TJm
-(structure,) 37.3498 Tj
--361 TJm
-(or) 8.29885 Tj
--339 TJm
-(wh) 12.1743 Tj
--1 TJm
-(e) 4.42339 Tj
-1 TJm
-(re) 7.74094 Tj
--340 TJm
-(there) 19.9152 Tj
--339 TJm
-(are) 12.1643 Tj
--339 TJm
-(multiple) 33.2153 Tj
-[1 0 0 1 400.941 407.699] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -400.941 -407.699] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-400.941 407.699 Td
-/F134_0 9.9626 Tf
-(bzip2) 29.8878 Tj
-[1 0 0 1 430.829 407.699] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -430.829 -407.699] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-434.207 407.699 Td
-/F130_0 9.9626 Tf
-(data) 16.5977 Tj
--339 TJm
-(streams) 30.4357 Tj
--339 TJm
-(concatenated) 52.0048 Tj
-72 395.744 Td
-(end-to-end.) 45.6486 Tj
-[1 0 0 1 72 395.644] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.9626] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -385.682] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 373.826 Td
-/F130_0 9.9626 Tf
-(F) 5.53921 Tj
-15 TJm
-(or) 8.29885 Tj
--332 TJm
-(reading) 29.8778 Tj
--333 TJm
-(\002les,) 19.0983 Tj
-[1 0 0 1 144.803 373.826] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -144.803 -373.826] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-144.803 373.826 Td
-/F134_0 9.9626 Tf
-(BZ2_bzReadOpen) 83.6858 Tj
-[1 0 0 1 228.489 373.826] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -228.489 -373.826] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-228.489 373.826 Td
-/F130_0 9.9626 Tf
-(,) 2.49065 Tj
-[1 0 0 1 234.496 373.826] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -234.496 -373.826] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-234.496 373.826 Td
-/F134_0 9.9626 Tf
-(BZ2_bzRead) 59.7756 Tj
-[1 0 0 1 294.272 373.826] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -294.272 -373.826] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-294.272 373.826 Td
-/F130_0 9.9626 Tf
-(,) 2.49065 Tj
-[1 0 0 1 300.279 373.826] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -300.279 -373.826] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-300.279 373.826 Td
-/F134_0 9.9626 Tf
-(BZ2_bzReadClose) 89.6634 Tj
-[1 0 0 1 389.942 373.826] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -389.942 -373.826] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-393.253 373.826 Td
-/F130_0 9.9626 Tf
-(and) 14.386 Tj
-[1 0 0 1 410.951 373.826] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -410.951 -373.826] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-410.951 373.826 Td
-/F134_0 9.9626 Tf
-(BZ2_bzReadGetUnused) 113.574 Tj
-[1 0 0 1 524.525 373.826] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -524.525 -373.826] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-527.836 373.826 Td
-/F130_0 9.9626 Tf
-(are) 12.1643 Tj
-72 361.871 Td
-(supplied.) 36.2539 Tj
--620 TJm
-(F) 5.53921 Tj
-15 TJm
-(or) 8.29885 Tj
--250 TJm
-(writing) 28.782 Tj
--250 TJm
-(\002les,) 19.0983 Tj
-[1 0 0 1 183.471 361.871] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -183.471 -361.871] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-183.471 361.871 Td
-/F134_0 9.9626 Tf
-(BZ2_bzWriteOpen) 89.6634 Tj
-[1 0 0 1 273.135 361.871] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -273.135 -361.871] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-273.135 361.871 Td
-/F130_0 9.9626 Tf
-(,) 2.49065 Tj
-[1 0 0 1 278.116 361.871] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -278.116 -361.871] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-278.116 361.871 Td
-/F134_0 9.9626 Tf
-(BZ2_bzWrite) 65.7532 Tj
-[1 0 0 1 343.869 361.871] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -343.869 -361.871] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-346.36 361.871 Td
-/F130_0 9.9626 Tf
-(and) 14.386 Tj
-[1 0 0 1 363.237 361.871] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -363.237 -361.871] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-363.237 361.871 Td
-/F134_0 9.9626 Tf
-(BZ2_bzWriteFinish) 101.619 Tj
-[1 0 0 1 464.856 361.871] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -464.856 -361.871] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-467.346 361.871 Td
-/F130_0 9.9626 Tf
-(are) 12.1643 Tj
--250 TJm
-(a) 4.42339 Tj
-20 TJm
-(v) 4.9813 Tj
-25 TJm
-(ailable.) 29.0509 Tj
-[1 0 0 1 72 359.714] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.9627] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -349.751] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 339.953 Td
-/F130_0 9.9626 Tf
-(As) 11.0684 Tj
--374 TJm
-(with) 17.7135 Tj
--374 TJm
-(the) 12.1743 Tj
--375 TJm
-(lo) 7.7509 Tj
-25 TJm
-(w-le) 17.7035 Tj
-25 TJm
-(v) 4.9813 Tj
-15 TJm
-(el) 7.193 Tj
--374 TJm
-(library) 26.5603 Tj
-65 TJm
-(,) 2.49065 Tj
--405 TJm
-(no) 9.9626 Tj
--374 TJm
-(global) 24.9065 Tj
--374 TJm
-(v) 4.9813 Tj
-25 TJm
-(ariables) 30.9837 Tj
--375 TJm
-(are) 12.1643 Tj
--374 TJm
-(used) 18.2614 Tj
--374 TJm
-(so) 8.85675 Tj
--374 TJm
-(the) 12.1743 Tj
--374 TJm
-(library) 26.5603 Tj
--375 TJm
-(is) 6.64505 Tj
--374 TJm
-(per) 12.7222 Tj
--374 TJm
-(se) 8.29885 Tj
--374 TJm
-(thread-safe.) 46.7445 Tj
--1365 TJm
-(Ho) 12.1743 Tj
-25 TJm
-(we) 11.6164 Tj
-25 TJm
-(v) 4.9813 Tj
-15 TJm
-(er) 7.74094 Tj
-40 TJm
-(,) 2.49065 Tj
--406 TJm
-(if) 6.08715 Tj
--374 TJm
-(I/O) 13.2801 Tj
-72 327.998 Td
-(errors) 23.2328 Tj
--267 TJm
-(occur) 22.1269 Tj
--267 TJm
-(whilst) 24.3586 Tj
--267 TJm
-(reading) 29.8778 Tj
--267 TJm
-(or) 8.29885 Tj
--267 TJm
-(writing) 28.782 Tj
--267 TJm
-(the) 12.1743 Tj
--268 TJm
-(underlying) 43.1679 Tj
--267 TJm
-(compressed) 47.0334 Tj
--267 TJm
-(\002les,) 19.0983 Tj
--271 TJm
-(you) 14.9439 Tj
--267 TJm
-(may) 17.1556 Tj
--267 TJm
-(ha) 9.40469 Tj
-20 TJm
-(v) 4.9813 Tj
-15 TJm
-(e) 4.42339 Tj
--267 TJm
-(to) 7.7509 Tj
--267 TJm
-(consult) 28.782 Tj
-[1 0 0 1 457.199 327.998] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -457.199 -327.998] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-457.199 327.998 Td
-/F134_0 9.9626 Tf
-(errno) 29.8878 Tj
-[1 0 0 1 487.087 327.998] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -487.087 -327.998] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-489.748 327.998 Td
-/F130_0 9.9626 Tf
-(to) 7.7509 Tj
--267 TJm
-(determine) 39.8404 Tj
-72 316.043 Td
-(the) 12.1743 Tj
--366 TJm
-(cause) 22.1269 Tj
--365 TJm
-(of) 8.29885 Tj
--366 TJm
-(the) 12.1743 Tj
--365 TJm
-(error) 19.3573 Tj
-55 TJm
-(.) 2.49065 Tj
--1314 TJm
-(In) 8.29885 Tj
--366 TJm
-(that) 14.9439 Tj
--365 TJm
-(case,) 19.6363 Tj
--395 TJm
-(you') 18.2614 Tj
-50 TJm
-(d) 4.9813 Tj
--366 TJm
-(need) 18.8094 Tj
--365 TJm
-(a) 4.42339 Tj
--366 TJm
-(C) 6.64505 Tj
--365 TJm
-(library) 26.5603 Tj
--366 TJm
-(which) 24.3486 Tj
--366 TJm
-(correctly) 35.4071 Tj
--365 TJm
-(supports) 33.7633 Tj
-[1 0 0 1 431.668 316.043] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -431.668 -316.043] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-431.668 316.043 Td
-/F134_0 9.9626 Tf
-(errno) 29.8878 Tj
-[1 0 0 1 461.556 316.043] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -461.556 -316.043] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-465.199 316.043 Td
-/F130_0 9.9626 Tf
-(in) 7.7509 Tj
--366 TJm
-(a) 4.42339 Tj
--365 TJm
-(multithreaded) 55.3422 Tj
-72 304.088 Td
-(en) 9.40469 Tj
-40 TJm
-(vironment.) 43.4469 Tj
-[1 0 0 1 72 303.988] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.9626] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -294.025] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 282.17 Td
-/F130_0 9.9626 Tf
-(T) 6.08715 Tj
-80 TJm
-(o) 4.9813 Tj
--243 TJm
-(mak) 17.1556 Tj
-10 TJm
-(e) 4.42339 Tj
--243 TJm
-(the) 12.1743 Tj
--242 TJm
-(library) 26.5603 Tj
--243 TJm
-(a) 4.42339 Tj
--243 TJm
-(little) 18.2714 Tj
--242 TJm
-(simpler) 29.8878 Tj
--243 TJm
-(and) 14.386 Tj
--243 TJm
-(more) 20.4731 Tj
--243 TJm
-(portable,) 35.1381 Tj
-[1 0 0 1 289.263 282.17] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -289.263 -282.17] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-289.263 282.17 Td
-/F134_0 9.9626 Tf
-(BZ2_bzReadOpen) 83.6858 Tj
-[1 0 0 1 372.949 282.17] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -372.949 -282.17] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-375.368 282.17 Td
-/F130_0 9.9626 Tf
-(and) 14.386 Tj
-[1 0 0 1 392.172 282.17] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -392.172 -282.17] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-392.172 282.17 Td
-/F134_0 9.9626 Tf
-(BZ2_bzWriteOpen) 89.6634 Tj
-[1 0 0 1 481.836 282.17] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -481.836 -282.17] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-484.254 282.17 Td
-/F130_0 9.9626 Tf
-(require) 28.2141 Tj
--243 TJm
-(you) 14.9439 Tj
--242 TJm
-(to) 7.7509 Tj
-72 270.215 Td
-(pass) 17.1556 Tj
--247 TJm
-(them) 19.9252 Tj
--248 TJm
-(\002le) 12.7322 Tj
--247 TJm
-(handles) 30.4357 Tj
--247 TJm
-(\() 3.31755 Tj
-[1 0 0 1 165.421 270.215] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -165.421 -270.215] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-165.421 270.215 Td
-/F134_0 9.9626 Tf
-(FILE) 23.9102 Tj
-189.331 268.471 Td
-(*) 5.97756 Tj
-[1 0 0 1 195.309 270.215] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -195.309 -270.215] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-195.309 270.215 Td
-/F130_0 9.9626 Tf
-(s\)) 7.193 Tj
--247 TJm
-(which) 24.3486 Tj
--248 TJm
-(ha) 9.40469 Tj
-20 TJm
-(v) 4.9813 Tj
-15 TJm
-(e) 4.42339 Tj
--247 TJm
-(pre) 12.7222 Tj
-25 TJm
-(viously) 29.3399 Tj
--247 TJm
-(been) 18.8094 Tj
--248 TJm
-(opened) 28.772 Tj
--247 TJm
-(for) 11.6164 Tj
--247 TJm
-(reading) 29.8778 Tj
--247 TJm
-(or) 8.29885 Tj
--248 TJm
-(writing) 28.782 Tj
--247 TJm
-(respecti) 30.9837 Tj
-25 TJm
-(v) 4.9813 Tj
-15 TJm
-(ely) 12.1743 Tj
-65 TJm
-(.) 2.49065 Tj
--618 TJm
-(That) 18.2614 Tj
--248 TJm
-(a) 4.42339 Tj
-20 TJm
-(v) 4.9813 Tj
-20 TJm
-(oids) 16.6077 Tj
-72 258.26 Td
-(portability) 41.5142 Tj
--272 TJm
-(problems) 37.0808 Tj
--273 TJm
-(associated) 40.9463 Tj
--272 TJm
-(with) 17.7135 Tj
--272 TJm
-(\002le) 12.7322 Tj
--273 TJm
-(operations) 41.5042 Tj
--272 TJm
-(and) 14.386 Tj
--272 TJm
-(\002le) 12.7322 Tj
--273 TJm
-(attrib) 21.031 Tj
-20 TJm
-(utes,) 18.5404 Tj
--278 TJm
-(whilst) 24.3586 Tj
--272 TJm
-(not) 12.7322 Tj
--272 TJm
-(being) 22.1369 Tj
--273 TJm
-(much) 22.1369 Tj
--272 TJm
-(of) 8.29885 Tj
--273 TJm
-(an) 9.40469 Tj
--272 TJm
-(imposition) 42.63 Tj
--272 TJm
-(on) 9.9626 Tj
--273 TJm
-(the) 12.1743 Tj
-72 246.304 Td
-(programmer) 49.2451 Tj
-55 TJm
-(.) 2.49065 Tj
-[1 0 0 1 72 244.147] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.9626] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -234.185] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 215.683 Td
-/F122_0 17.2154 Tf
-(3.1.3.) 43.0729 Tj
--278 TJm
-(Utility) 47.8244 Tj
--278 TJm
-(functions) 77.4693 Tj
--278 TJm
-(summar) 66.9679 Tj
--10 TJm
-(y) 9.57176 Tj
-[1 0 0 1 72 212.12] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.9626] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -202.157] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 193.765 Td
-/F130_0 9.9626 Tf
-(F) 5.53921 Tj
-15 TJm
-(or) 8.29885 Tj
--273 TJm
-(v) 4.9813 Tj
-15 TJm
-(ery) 12.7222 Tj
--273 TJm
-(simple) 26.5703 Tj
--273 TJm
-(needs,) 25.1755 Tj
-[1 0 0 1 165.929 193.765] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -165.929 -193.765] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-165.929 193.765 Td
-/F134_0 9.9626 Tf
-(BZ2_bzBuffToBuffCompress) 143.461 Tj
-[1 0 0 1 309.391 193.765] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -309.391 -193.765] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-312.112 193.765 Td
-/F130_0 9.9626 Tf
-(and) 14.386 Tj
-[1 0 0 1 329.219 193.765] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -329.219 -193.765] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-329.219 193.765 Td
-/F134_0 9.9626 Tf
-(BZ2_bzBuffToBuffDecompress) 155.417 Tj
-[1 0 0 1 484.636 193.765] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -484.636 -193.765] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-487.357 193.765 Td
-/F130_0 9.9626 Tf
-(are) 12.1643 Tj
--273 TJm
-(pro) 13.2801 Tj
-15 TJm
-(vided.) 24.6275 Tj
-72 181.81 Td
-(These) 23.7907 Tj
--374 TJm
-(compress) 37.6287 Tj
--373 TJm
-(data) 16.5977 Tj
--374 TJm
-(in) 7.7509 Tj
--373 TJm
-(memory) 33.2053 Tj
--374 TJm
-(from) 19.3673 Tj
--373 TJm
-(one) 14.386 Tj
--374 TJm
-(b) 4.9813 Tj
-20 TJm
-(uf) 8.29885 Tj
-25 TJm
-(fer) 11.0585 Tj
--373 TJm
-(to) 7.7509 Tj
--374 TJm
-(another) 29.8778 Tj
--374 TJm
-(b) 4.9813 Tj
-20 TJm
-(uf) 8.29885 Tj
-25 TJm
-(fer) 11.0585 Tj
--373 TJm
-(in) 7.7509 Tj
--374 TJm
-(a) 4.42339 Tj
--373 TJm
-(single) 23.8007 Tj
--374 TJm
-(function) 33.2053 Tj
--373 TJm
-(call.) 16.8766 Tj
--1362 TJm
-(Y) 7.193 Tj
-110 TJm
-(ou) 9.9626 Tj
--373 TJm
-(should) 26.5703 Tj
--374 TJm
-(assess) 24.3486 Tj
-72 169.855 Td
-(whether) 32.0895 Tj
--344 TJm
-(these) 20.4731 Tj
--343 TJm
-(functions) 37.0808 Tj
--344 TJm
-(ful\002ll) 22.1469 Tj
--344 TJm
-(your) 18.2614 Tj
--343 TJm
-(memory-to-memory) 80.7967 Tj
--344 TJm
-(compression/decompression) 112.896 Tj
--343 TJm
-(requirements) 52.0147 Tj
--344 TJm
-(before) 25.4445 Tj
--344 TJm
-(in) 7.7509 Tj
-40 TJm
-(v) 4.9813 Tj
-15 TJm
-(esting) 23.8007 Tj
-72 157.9 Td
-(ef) 7.74094 Tj
-25 TJm
-(fort) 14.386 Tj
--250 TJm
-(in) 7.7509 Tj
--250 TJm
-(understanding) 56.4481 Tj
--250 TJm
-(the) 12.1743 Tj
--250 TJm
-(more) 20.4731 Tj
--250 TJm
-(general) 29.3199 Tj
--250 TJm
-(b) 4.9813 Tj
-20 TJm
-(ut) 7.7509 Tj
--250 TJm
-(more) 20.4731 Tj
--250 TJm
-(comple) 29.3299 Tj
-15 TJm
-(x) 4.9813 Tj
--250 TJm
-(lo) 7.7509 Tj
-25 TJm
-(w-le) 17.7035 Tj
-25 TJm
-(v) 4.9813 Tj
-15 TJm
-(el) 7.193 Tj
--250 TJm
-(interf) 21.579 Tj
-10 TJm
-(ace.) 15.7608 Tj
-[1 0 0 1 72 155.743] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.9627] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -145.78] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 135.982 Td
-/F130_0 9.9626 Tf
-(Y) 7.193 Tj
-110 TJm
-(oshioka) 30.9936 Tj
--423 TJm
-(Tsuneo) 29.3299 Tj
--422 TJm
-(\() 3.31755 Tj
-[1 0 0 1 150.16 135.982] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -150.16 -135.982] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-150.16 135.982 Td
-/F134_0 9.9626 Tf
-(tsuneo@rr.iij4u.or.jp) 125.529 Tj
-[1 0 0 1 275.69 135.982] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -275.69 -135.982] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-275.69 135.982 Td
-/F130_0 9.9626 Tf
-(\)) 3.31755 Tj
--423 TJm
-(has) 13.2801 Tj
--422 TJm
-(contrib) 28.224 Tj
-20 TJm
-(uted) 17.1556 Tj
--423 TJm
-(some) 21.031 Tj
--423 TJm
-(functions) 37.0808 Tj
--422 TJm
-(to) 7.7509 Tj
--423 TJm
-(gi) 7.7509 Tj
-25 TJm
-(v) 4.9813 Tj
-15 TJm
-(e) 4.42339 Tj
--423 TJm
-(better) 22.6848 Tj
-[1 0 0 1 476.462 135.982] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -476.462 -135.982] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-476.462 135.982 Td
-/F134_0 9.9626 Tf
-(zlib) 23.9102 Tj
-[1 0 0 1 500.372 135.982] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -500.372 -135.982] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-504.583 135.982 Td
-/F130_0 9.9626 Tf
-(compati-) 35.417 Tj
-72 124.027 Td
-(bility) 21.041 Tj
-65 TJm
-(.) 2.49065 Tj
--1446 TJm
-(These) 23.7907 Tj
--388 TJm
-(functions) 37.0808 Tj
--387 TJm
-(are) 12.1643 Tj
-[1 0 0 1 193.913 124.027] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -193.913 -124.027] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-193.913 124.027 Td
-/F134_0 9.9626 Tf
-(BZ2_bzopen) 59.7756 Tj
-[1 0 0 1 253.689 124.027] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -253.689 -124.027] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-253.689 124.027 Td
-/F130_0 9.9626 Tf
-(,) 2.49065 Tj
-[1 0 0 1 260.385 124.027] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -260.385 -124.027] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-260.385 124.027 Td
-/F134_0 9.9626 Tf
-(BZ2_bzread) 59.7756 Tj
-[1 0 0 1 320.161 124.027] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -320.161 -124.027] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-320.161 124.027 Td
-/F130_0 9.9626 Tf
-(,) 2.49065 Tj
-[1 0 0 1 326.857 124.027] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -326.857 -124.027] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-326.857 124.027 Td
-/F134_0 9.9626 Tf
-(BZ2_bzwrite) 65.7532 Tj
-[1 0 0 1 392.611 124.027] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -392.611 -124.027] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-392.611 124.027 Td
-/F130_0 9.9626 Tf
-(,) 2.49065 Tj
-[1 0 0 1 399.306 124.027] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -399.306 -124.027] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-399.306 124.027 Td
-/F134_0 9.9626 Tf
-(BZ2_bzflush) 65.7532 Tj
-[1 0 0 1 465.06 124.027] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -465.06 -124.027] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-465.06 124.027 Td
-/F130_0 9.9626 Tf
-(,) 2.49065 Tj
-[1 0 0 1 471.756 124.027] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -471.756 -124.027] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-471.756 124.027 Td
-/F134_0 9.9626 Tf
-(BZ2_bzclose) 65.7532 Tj
-[1 0 0 1 537.509 124.027] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -537.509 -124.027] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-537.509 124.027 Td
-/F130_0 9.9626 Tf
-(,) 2.49065 Tj
-[1 0 0 1 72 112.072] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -112.072] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 112.072 Td
-/F134_0 9.9626 Tf
-(BZ2_bzerror) 65.7532 Tj
-[1 0 0 1 137.753 112.072] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -137.753 -112.072] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-140.408 112.072 Td
-/F130_0 9.9626 Tf
-(and) 14.386 Tj
-[1 0 0 1 157.449 112.072] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -157.449 -112.072] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-157.449 112.072 Td
-/F134_0 9.9626 Tf
-(BZ2_bzlibVersion) 95.641 Tj
-[1 0 0 1 253.091 112.072] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -253.091 -112.072] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-253.091 112.072 Td
-/F130_0 9.9626 Tf
-(.) 2.49065 Tj
--719 TJm
-(Y) 7.193 Tj
-110 TJm
-(ou) 9.9626 Tj
--266 TJm
-(may) 17.1556 Tj
--267 TJm
-(\002nd) 15.5018 Tj
--266 TJm
-(these) 20.4731 Tj
--267 TJm
-(functions) 37.0808 Tj
--266 TJm
-(more) 20.4731 Tj
--267 TJm
-(con) 14.386 Tj
-40 TJm
-(v) 4.9813 Tj
-15 TJm
-(enient) 24.3486 Tj
--266 TJm
-(for) 11.6164 Tj
--267 TJm
-(simple) 26.5703 Tj
--266 TJm
-(\002le) 12.7322 Tj
--267 TJm
-(reading) 29.8778 Tj
-72 100.117 Td
-(and) 14.386 Tj
--270 TJm
-(wri) 13.2801 Tj
-1 TJm
-(ting,) 17.9925 Tj
--275 TJm
-(than) 17.1556 Tj
--269 TJm
-(those) 21.031 Tj
--270 TJm
-(in) 7.7509 Tj
--269 TJm
-(the) 12.1743 Tj
--270 TJm
-(high-le) 28.224 Tj
-25 TJm
-(v) 4.9813 Tj
-15 TJm
-(el) 7.193 Tj
--269 TJm
-(interf) 21.579 Tj
-10 TJm
-(ace.) 15.7608 Tj
--737 TJm
-(These) 23.7907 Tj
--270 TJm
-(functions) 37.0808 Tj
--269 TJm
-(are) 12.1643 Tj
--270 TJm
-(not) 12.7322 Tj
--269 TJm
-(\(yet\)) 18.8094 Tj
--270 TJm
-(of) 8.29885 Tj
-25 TJm
-(\002cially) 27.6761 Tj
--269 TJm
-(part) 15.4918 Tj
--270 TJm
-(of) 8.29885 Tj
--269 TJm
-(the) 12.1743 Tj
--270 TJm
-(library) 26.5603 Tj
-65 TJm
-(,) 2.49065 Tj
--274 TJm
-(and) 14.386 Tj
--270 TJm
-(are) 12.1643 Tj
-72 88.1614 Td
-(minimally) 40.9662 Tj
--291 TJm
-(documented) 48.6972 Tj
--291 TJm
-(here.) 19.6363 Tj
--867 TJm
-(If) 6.63509 Tj
--291 TJm
-(the) 12.1743 Tj
-15 TJm
-(y) 4.9813 Tj
--291 TJm
-(break,) 24.6176 Tj
--301 TJm
-(you) 14.9439 Tj
--291 TJm
-(get) 12.1743 Tj
--292 TJm
-(to) 7.7509 Tj
--291 TJm
-(k) 4.9813 Tj
-10 TJm
-(eep) 13.8281 Tj
--291 TJm
-(all) 9.9626 Tj
--291 TJm
-(the) 12.1743 Tj
--291 TJm
-(pieces.) 27.3872 Tj
--433 TJm
-(I) 3.31755 Tj
--291 TJm
-(hope) 19.3673 Tj
--291 TJm
-(to) 7.7509 Tj
--291 TJm
-(document) 39.2925 Tj
--292 TJm
-(them) 19.9252 Tj
--291 TJm
-(properly) 33.7533 Tj
--291 TJm
-(when) 21.579 Tj
-72 76.2062 Td
-(time) 17.7135 Tj
--250 TJm
-(permits.) 32.3785 Tj
-[1 0 0 1 72 74.0494] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -23.1976] cm
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-[1 0 0 1 1.8929 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 4.3836 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 374.394 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 6.9737] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 43.0633 -6.7545] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -498.225 -51.071] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-541.288 51.071 Td
-/F130_0 9.9626 Tf
-(9) 4.9813 Tj
-[1 0 0 1 455.161 50.8518] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 93.5986 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 6.2765 0] cm
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-[1 0 0 1 -15.0366 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-Q
-showpage
-%%PageTrailer
-pdfEndPage
-%%Page: 13 13
-%%BeginPageSetup
-%%PageOrientation: Portrait
-pdfStartPage
-0 0 612 792 re W
-%%EndPageSetup
-[] 0 d
-1 i
-0 j
-0 J
-10 M
-1 w
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-false op
-false OP
-0 0 612 792 re
-W
-q
-[1 0 0 1 72 741.554] cm
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-[1 0 0 1 1.8929 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 14.4459] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 187.197 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 -8.9114] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 8.9114] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 76.4979 -6.7546] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -342.569 -749.245] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-419.067 749.245 Td
-/F130_0 9.9626 Tf
-(Programming) 54.7943 Tj
--250 TJm
-(with) 17.7135 Tj
-[1 0 0 1 496.556 749.245] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -496.556 -749.245] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-496.556 749.245 Td
-/F134_0 9.9626 Tf
-(libbzip2) 47.8205 Tj
-[1 0 0 1 544.376 749.245] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -278.305 -2.1568] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 280.796 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -472.974 -5.0363] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -0.4981] cm
-q
-[] 0 d
-0 J
-0.4981 w
-0 0.2491 m
-475.465 0.2491 l
-S
-Q
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 479.251 0] cm
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-[1 0 0 1 -13.1436 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -468 -21.5542] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -720] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 710.037 Td
-/F130_0 9.9626 Tf
-(Y) 7.193 Tj
-110 TJm
-(oshioka) 30.9936 Tj
--250 TJm
-(also) 16.0497 Tj
--250 TJm
-(contrib) 28.224 Tj
-20 TJm
-(uted) 17.1556 Tj
--250 TJm
-(modi\002cations) 54.2464 Tj
--250 TJm
-(to) 7.7509 Tj
--250 TJm
-(allo) 14.9439 Tj
-25 TJm
-(w) 7.193 Tj
--250 TJm
-(the) 12.1743 Tj
--250 TJm
-(library) 26.5603 Tj
--250 TJm
-(to) 7.7509 Tj
--250 TJm
-(be) 9.40469 Tj
--250 TJm
-(b) 4.9813 Tj
-20 TJm
-(uilt) 13.2901 Tj
--250 TJm
-(as) 8.29885 Tj
--250 TJm
-(a) 4.42339 Tj
--250 TJm
-(W) 9.40469 Tj
-40 TJm
-(indo) 17.7135 Tj
-25 TJm
-(ws) 11.0684 Tj
--250 TJm
-(DLL.) 21.8579 Tj
-[1 0 0 1 72 707.88] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.7436] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -698.137] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 675.504 Td
-/F122_0 20.6585 Tf
-(3.2.) 34.4584 Tj
--278 TJm
-(Err) 29.8515 Tj
-20 TJm
-(or) 20.6585 Tj
--278 TJm
-(handling) 86.084 Tj
-[1 0 0 1 72 670.907] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.7436] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -661.164] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 653.805 Td
-/F130_0 9.9626 Tf
-(The) 15.4918 Tj
--214 TJm
-(library) 26.5603 Tj
--215 TJm
-(is) 6.64505 Tj
--214 TJm
-(designed) 35.417 Tj
--215 TJm
-(to) 7.7509 Tj
--214 TJm
-(reco) 17.1456 Tj
-15 TJm
-(v) 4.9813 Tj
-15 TJm
-(er) 7.74094 Tj
--215 TJm
-(cleanly) 28.772 Tj
--214 TJm
-(in) 7.7509 Tj
--215 TJm
-(all) 9.9626 Tj
--214 TJm
-(situations,) 40.6873 Tj
--222 TJm
-(including) 37.6387 Tj
--214 TJm
-(the) 12.1743 Tj
--215 TJm
-(w) 7.193 Tj
-10 TJm
-(orst-case) 35.4071 Tj
--214 TJm
-(situation) 34.3212 Tj
--215 TJm
-(of) 8.29885 Tj
--214 TJm
-(decompressing) 59.7656 Tj
--215 TJm
-(random) 30.4357 Tj
-72 641.85 Td
-(data.) 19.0883 Tj
--764 TJm
-(I'm) 14.386 Tj
--274 TJm
-(not) 12.7322 Tj
--275 TJm
-(100%) 23.2427 Tj
--274 TJm
-(sure) 16.5977 Tj
--274 TJm
-(that) 14.9439 Tj
--274 TJm
-(it) 5.53921 Tj
--274 TJm
-(can) 13.8281 Tj
--274 TJm
-(al) 7.193 Tj
-10 TJm
-(w) 7.193 Tj
-10 TJm
-(ays) 13.2801 Tj
--274 TJm
-(do) 9.9626 Tj
--274 TJm
-(this,) 16.8866 Tj
--280 TJm
-(so) 8.85675 Tj
--274 TJm
-(you) 14.9439 Tj
--274 TJm
-(might) 23.2527 Tj
--274 TJm
-(w) 7.193 Tj
-10 TJm
-(ant) 12.1743 Tj
--274 TJm
-(to) 7.7509 Tj
--274 TJm
-(add) 14.386 Tj
--274 TJm
-(a) 4.42339 Tj
--275 TJm
-(s) 3.87545 Tj
-1 TJm
-(ignal) 19.9252 Tj
--275 TJm
-(handler) 29.8778 Tj
--274 TJm
-(to) 7.7509 Tj
--274 TJm
-(catch) 21.0211 Tj
--274 TJm
-(se) 8.29885 Tj
-15 TJm
-(gmentation) 44.8317 Tj
-72 629.894 Td
-(violations) 39.3025 Tj
--273 TJm
-(during) 26.0123 Tj
--273 TJm
-(decompression) 59.7656 Tj
--273 TJm
-(if) 6.08715 Tj
--273 TJm
-(you) 14.9439 Tj
--273 TJm
-(are) 12.1643 Tj
--273 TJm
-(feeling) 27.6661 Tj
--274 TJm
-(especiall) 34.8591 Tj
-1 TJm
-(y) 4.9813 Tj
--274 TJm
-(paranoid.) 37.3498 Tj
--758 TJm
-(I) 3.31755 Tj
--273 TJm
-(w) 7.193 Tj
-10 TJm
-(ould) 17.7135 Tj
--273 TJm
-(be) 9.40469 Tj
--273 TJm
-(interested) 38.7346 Tj
--273 TJm
-(in) 7.7509 Tj
--274 TJm
-(hearing) 29.8778 Tj
--273 TJm
-(more) 20.4731 Tj
--273 TJm
-(about) 22.1369 Tj
-72 617.939 Td
-(the) 12.1743 Tj
--250 TJm
-(rob) 13.2801 Tj
-20 TJm
-(ustness) 28.782 Tj
--250 TJm
-(of) 8.29885 Tj
--250 TJm
-(the) 12.1743 Tj
--250 TJm
-(library) 26.5603 Tj
--250 TJm
-(to) 7.7509 Tj
--250 TJm
-(corrupted) 38.1767 Tj
--250 TJm
-(compressed) 47.0334 Tj
--250 TJm
-(data.) 19.0883 Tj
-[1 0 0 1 72 615.783] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.7436] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -606.039] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 596.241 Td
-/F130_0 9.9626 Tf
-(V) 7.193 Tj
-111 TJm
-(ersion) 24.3486 Tj
--251 TJm
-(1.0.3) 19.9252 Tj
--251 TJm
-(more) 20.4731 Tj
--251 TJm
-(rob) 13.2801 Tj
-20 TJm
-(ust) 11.6264 Tj
--251 TJm
-(in) 7.7509 Tj
--251 TJm
-(this) 14.396 Tj
--251 TJm
-(respect) 28.2141 Tj
--252 TJm
-(than) 17.1556 Tj
--251 TJm
-(an) 9.40469 Tj
-15 TJm
-(y) 4.9813 Tj
--251 TJm
-(pre) 12.7222 Tj
-25 TJm
-(vious) 21.589 Tj
--251 TJm
-(v) 4.9813 Tj
-15 TJm
-(ersion.) 26.8392 Tj
--626 TJm
-(In) 8.29885 Tj
-40 TJm
-(v) 4.9813 Tj
-15 TJm
-(estig) 18.8194 Tj
-5 TJm
-(ations) 23.8007 Tj
--251 TJm
-(with) 17.7135 Tj
--251 TJm
-(V) 7.193 Tj
-111 TJm
-(algrind) 28.224 Tj
--251 TJm
-(\(a) 7.74094 Tj
--252 TJm
-(tool) 15.5018 Tj
--251 TJm
-(for) 11.6164 Tj
--251 TJm
-(detecting) 36.5229 Tj
-72 584.285 Td
-(problems) 37.0808 Tj
--422 TJm
-(with) 17.7135 Tj
--421 TJm
-(memory) 33.2053 Tj
--422 TJm
-(management\)) 54.2264 Tj
--421 TJm
-(indicate) 31.5416 Tj
--422 TJm
-(that,) 17.4346 Tj
--464 TJm
-(at) 7.193 Tj
--422 TJm
-(least) 18.2614 Tj
--421 TJm
-(for) 11.6164 Tj
--422 TJm
-(the) 12.1743 Tj
--422 TJm
-(f) 3.31755 Tj
-1 TJm
-(e) 4.42339 Tj
-25 TJm
-(w) 7.193 Tj
--422 TJm
-(\002les) 16.6077 Tj
--422 TJm
-(I) 3.31755 Tj
--421 TJm
-(tested,) 25.7334 Tj
--464 TJm
-(all) 9.9626 Tj
--422 TJm
-(single-bit) 37.6387 Tj
--422 TJm
-(errors) 23.2328 Tj
--421 TJm
-(in) 7.7509 Tj
--422 TJm
-(the) 12.1743 Tj
-72 572.33 Td
-(decompressed) 56.4381 Tj
--342 TJm
-(data) 16.5977 Tj
--341 TJm
-(are) 12.1643 Tj
--342 TJm
-(caught) 26.5603 Tj
--342 TJm
-(properly) 33.7533 Tj
-65 TJm
-(,) 2.49065 Tj
--365 TJm
-(with) 17.7135 Tj
--341 TJm
-(no) 9.9626 Tj
--342 TJm
-(se) 8.29885 Tj
-15 TJm
-(gmentation) 44.8317 Tj
--342 TJm
-(f) 3.31755 Tj
-10 TJm
-(aults,) 21.31 Tj
--365 TJm
-(no) 9.9626 Tj
--341 TJm
-(uses) 17.1556 Tj
--342 TJm
-(of) 8.29885 Tj
--342 TJm
-(uninitialised) 49.2651 Tj
--342 TJm
-(data,) 19.0883 Tj
--364 TJm
-(no) 9.9626 Tj
--342 TJm
-(out) 12.7322 Tj
--342 TJm
-(of) 8.29885 Tj
--342 TJm
-(range) 22.1269 Tj
-72 560.375 Td
-(reads) 21.0211 Tj
--261 TJm
-(or) 8.29885 Tj
--260 TJm
-(writes,) 26.8392 Tj
--263 TJm
-(and) 14.386 Tj
--261 TJm
-(no) 9.9626 Tj
--261 TJm
-(in\002nit) 23.8106 Tj
-1 TJm
-(e) 4.42339 Tj
--261 TJm
-(looping) 30.4457 Tj
--261 TJm
-(in) 7.7509 Tj
--260 TJm
-(the) 12.1743 Tj
--261 TJm
-(decompressor) 55.3323 Tj
-55 TJm
-(.) 2.49065 Tj
--342 TJm
-(So) 10.5205 Tj
--260 TJm
-(it') 8.85675 Tj
-55 TJm
-(s) 3.87545 Tj
--261 TJm
-(certainly) 34.8591 Tj
--260 TJm
-(pretty) 23.2427 Tj
--261 TJm
-(rob) 13.2801 Tj
-20 TJm
-(ust,) 14.117 Tj
--263 TJm
-(although) 34.8691 Tj
--261 TJm
-(I) 3.31755 Tj
--260 TJm
-(w) 7.193 Tj
-10 TJm
-(ouldn') 26.0123 Tj
-18 TJm
-(t) 2.7696 Tj
--261 TJm
-(claim) 22.1369 Tj
-72 548.42 Td
-(it) 5.53921 Tj
--250 TJm
-(to) 7.7509 Tj
--250 TJm
-(be) 9.40469 Tj
--250 TJm
-(totally) 25.4644 Tj
--250 TJm
-(bombproof.) 46.7644 Tj
-[1 0 0 1 72 546.263] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.7436] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -536.519] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 526.721 Td
-/F130_0 9.9626 Tf
-(The) 15.4918 Tj
--282 TJm
-(\002le) 12.7322 Tj
-[1 0 0 1 105.84 526.721] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -105.84 -526.721] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-105.84 526.721 Td
-/F134_0 9.9626 Tf
-(bzlib.h) 41.8429 Tj
-[1 0 0 1 147.683 526.721] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -147.683 -526.721] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-150.491 526.721 Td
-/F130_0 9.9626 Tf
-(contains) 33.2053 Tj
--282 TJm
-(all) 9.9626 Tj
--282 TJm
-(de\002nitions) 42.0721 Tj
--282 TJm
-(nee) 13.8281 Tj
-1 TJm
-(ded) 14.386 Tj
--282 TJm
-(to) 7.7509 Tj
--282 TJm
-(use) 13.2801 Tj
--282 TJm
-(the) 12.1743 Tj
--282 TJm
-(library) 26.5603 Tj
-65 TJm
-(.) 2.49065 Tj
--811 TJm
-(In) 8.29885 Tj
--282 TJm
-(particular) 38.1767 Tj
-40 TJm
-(,) 2.49065 Tj
--290 TJm
-(you) 14.9439 Tj
--282 TJm
-(should) 26.5703 Tj
--281 TJm
-(de\002nitely) 37.6387 Tj
--282 TJm
-(not) 12.7322 Tj
--282 TJm
-(include) 29.3299 Tj
-[1 0 0 1 72 514.766] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -514.766] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 514.766 Td
-/F134_0 9.9626 Tf
-(bzlib_private.h) 89.6634 Tj
-[1 0 0 1 161.664 514.766] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -161.664 -514.766] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-161.664 514.766 Td
-/F130_0 9.9626 Tf
-(.) 2.49065 Tj
-[1 0 0 1 72 513.232] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.7436] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -503.488] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 493.067 Td
-/F130_0 9.9626 Tf
-(In) 8.29885 Tj
-[1 0 0 1 82.8075 493.067] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -82.8075 -493.067] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-82.8075 493.067 Td
-/F134_0 9.9626 Tf
-(bzlib.h) 41.8429 Tj
-[1 0 0 1 124.651 493.067] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -124.651 -493.067] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-124.651 493.067 Td
-/F130_0 9.9626 Tf
-(,) 2.49065 Tj
--252 TJm
-(the) 12.1743 Tj
--252 TJm
-(v) 4.9813 Tj
-25 TJm
-(arious) 24.3486 Tj
--252 TJm
-(return) 23.7907 Tj
--252 TJm
-(v) 4.9813 Tj
-25 TJm
-(alues) 20.4731 Tj
--251 TJm
-(are) 12.1643 Tj
--252 TJm
-(de\002ned.) 31.8205 Tj
--631 TJm
-(The) 15.4918 Tj
--252 TJm
-(follo) 18.8194 Tj
-25 TJm
-(wing) 19.9252 Tj
--252 TJm
-(list) 12.1843 Tj
--251 TJm
-(is) 6.64505 Tj
--252 TJm
-(not) 12.7322 Tj
--252 TJm
-(intended) 34.3112 Tj
--252 TJm
-(as) 8.29885 Tj
--252 TJm
-(an) 9.40469 Tj
--251 TJm
-(e) 4.42339 Tj
-15 TJm
-(xhausti) 28.782 Tj
-25 TJm
-(v) 4.9813 Tj
-15 TJm
-(e) 4.42339 Tj
--252 TJm
-(description) 44.2738 Tj
--252 TJm
-(of) 8.29885 Tj
-72 481.112 Td
-(the) 12.1743 Tj
--236 TJm
-(circumstances) 56.4381 Tj
--236 TJm
-(in) 7.7509 Tj
--237 TJm
-(which) 24.3486 Tj
--236 TJm
-(a) 4.42339 Tj
--236 TJm
-(gi) 7.7509 Tj
-25 TJm
-(v) 4.9813 Tj
-15 TJm
-(en) 9.40469 Tj
--236 TJm
-(v) 4.9813 Tj
-25 TJm
-(alue) 16.5977 Tj
--236 TJm
-(may) 17.1556 Tj
--237 TJm
-(be) 9.40469 Tj
--236 TJm
-(returned) 33.1954 Tj
--236 TJm
-(--) 6.63509 Tj
--236 TJm
-(those) 21.031 Tj
--236 TJm
-(descriptions) 48.1492 Tj
--236 TJm
-(are) 12.1643 Tj
--237 TJm
-(gi) 7.7509 Tj
-25 TJm
-(v) 4.9813 Tj
-15 TJm
-(en) 9.40469 Tj
--236 TJm
-(later) 17.7035 Tj
-55 TJm
-(.) 2.49065 Tj
--305 TJm
-(Rather) 26.5603 Tj
-40 TJm
-(,) 2.49065 Tj
--239 TJm
-(it) 5.53921 Tj
--236 TJm
-(is) 6.64505 Tj
--237 TJm
-(intended) 34.3112 Tj
--236 TJm
-(to) 7.7509 Tj
-72 469.157 Td
-(con) 14.386 Tj
-40 TJm
-(v) 4.9813 Tj
-15 TJm
-(e) 4.42339 Tj
-15 TJm
-(y) 4.9813 Tj
--266 TJm
-(the) 12.1743 Tj
--265 TJm
-(rough) 23.2427 Tj
--266 TJm
-(meaning) 34.3112 Tj
--265 TJm
-(of) 8.29885 Tj
--266 TJm
-(each) 18.2515 Tj
--266 TJm
-(return) 23.7907 Tj
--265 TJm
-(v) 4.9813 Tj
-25 TJm
-(alue.) 19.0883 Tj
--714 TJm
-(The) 15.4918 Tj
--265 TJm
-(\002rst) 15.5018 Tj
--266 TJm
-(\002) 5.53921 Tj
-25 TJm
-(v) 4.9813 Tj
-15 TJm
-(e) 4.42339 Tj
--265 TJm
-(actions) 28.224 Tj
--266 TJm
-(are) 12.1643 Tj
--266 TJm
-(normal) 28.224 Tj
--265 TJm
-(and) 14.386 Tj
--266 TJm
-(not) 12.7322 Tj
--265 TJm
-(intended) 34.3112 Tj
--266 TJm
-(to) 7.7509 Tj
--266 TJm
-(denote) 26.5603 Tj
--265 TJm
-(an) 9.40469 Tj
--266 TJm
-(error) 19.3573 Tj
-72 457.202 Td
-(situation.) 36.8118 Tj
-[1 0 0 1 72 457.102] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.7436] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.7435] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -437.615] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 425.76 Td
-/F134_0 9.9626 Tf
-(BZ_OK) 29.8878 Tj
-[1 0 0 1 101.888 425.76] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -32.3786 -1.3101] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -424.449] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-108 413.804 Td
-/F130_0 9.9626 Tf
-(The) 15.4918 Tj
--250 TJm
-(requested) 38.1767 Tj
--250 TJm
-(action) 24.3486 Tj
--250 TJm
-(w) 7.193 Tj
-10 TJm
-(as) 8.29885 Tj
--250 TJm
-(completed) 41.5042 Tj
--250 TJm
-(successfully) 48.6972 Tj
-65 TJm
-(.) 2.49065 Tj
-[1 0 0 1 72 411.648] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -3.766] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.7436] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -398.138] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 388.34 Td
-/F134_0 9.9626 Tf
-(BZ_RUN_OK,) 59.7756 Tj
--600 TJm
-(BZ_FLUSH_OK,) 71.7307 Tj
--600 TJm
-(BZ_FINISH_OK) 71.7307 Tj
-[1 0 0 1 287.193 388.34] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -217.684 -1.31] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -387.03] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-108 376.384 Td
-/F130_0 9.9626 Tf
-(In) 8.29885 Tj
-[1 0 0 1 118.79 376.384] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -118.79 -376.384] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-118.79 376.384 Td
-/F134_0 9.9626 Tf
-(BZ2_bzCompress) 83.6858 Tj
-[1 0 0 1 202.476 376.384] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -202.476 -376.384] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-202.476 376.384 Td
-/F130_0 9.9626 Tf
-(,) 2.49065 Tj
--250 TJm
-(the) 12.1743 Tj
--250 TJm
-(requested) 38.1767 Tj
--250 TJm
-(\003ush/\002nish/nothing-special) 108.493 Tj
--250 TJm
-(action) 24.3486 Tj
--250 TJm
-(w) 7.193 Tj
-10 TJm
-(as) 8.29885 Tj
--250 TJm
-(completed) 41.5042 Tj
--250 TJm
-(successfully) 48.6972 Tj
-65 TJm
-(.) 2.49065 Tj
-[1 0 0 1 72 374.228] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -3.7659] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.7436] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -360.718] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 350.92 Td
-/F134_0 9.9626 Tf
-(BZ_STREAM_END) 77.7083 Tj
-[1 0 0 1 149.709 350.92] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -80.1993 -1.31] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -349.61] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-108 338.965 Td
-/F130_0 9.9626 Tf
-(Compression) 52.5826 Tj
--250 TJm
-(of) 8.29885 Tj
--250 TJm
-(data) 16.5977 Tj
--250 TJm
-(w) 7.193 Tj
-10 TJm
-(as) 8.29885 Tj
--250 TJm
-(completed,) 43.9948 Tj
--250 TJm
-(or) 8.29885 Tj
--250 TJm
-(the) 12.1743 Tj
--250 TJm
-(logical) 27.1182 Tj
--250 TJm
-(stream) 26.5603 Tj
--250 TJm
-(end) 14.386 Tj
--250 TJm
-(w) 7.193 Tj
-10 TJm
-(as) 8.29885 Tj
--250 TJm
-(detected) 33.1954 Tj
--250 TJm
-(during) 26.0123 Tj
--250 TJm
-(decompression.) 62.2563 Tj
-[1 0 0 1 72 336.808] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -3.7659] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.7436] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.7436] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -313.555] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 303.756 Td
-/F130_0 9.9626 Tf
-(The) 15.4918 Tj
--250 TJm
-(follo) 18.8194 Tj
-25 TJm
-(wing) 19.9252 Tj
--250 TJm
-(return) 23.7907 Tj
--250 TJm
-(v) 4.9813 Tj
-25 TJm
-(alues) 20.4731 Tj
--250 TJm
-(indicate) 31.5416 Tj
--250 TJm
-(an) 9.40469 Tj
--250 TJm
-(error) 19.3573 Tj
--250 TJm
-(of) 8.29885 Tj
--250 TJm
-(some) 21.031 Tj
--250 TJm
-(kind.) 20.2042 Tj
-[1 0 0 1 72 301.6] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.7436] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.7436] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -282.112] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 272.314 Td
-/F134_0 9.9626 Tf
-(BZ_CONFIG_ERROR) 89.6634 Tj
-[1 0 0 1 161.664 272.314] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4906 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -92.1544 -1.31] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -271.004] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-108 260.359 Td
-/F130_0 9.9626 Tf
-(Indicates) 35.965 Tj
--386 TJm
-(that) 14.9439 Tj
--385 TJm
-(the) 12.1743 Tj
--386 TJm
-(library) 26.5603 Tj
--386 TJm
-(has) 13.2801 Tj
--386 TJm
-(been) 18.8094 Tj
--385 TJm
-(improperly) 44.2738 Tj
--386 TJm
-(compiled) 37.0808 Tj
--386 TJm
-(on) 9.9626 Tj
--386 TJm
-(your) 18.2614 Tj
--385 TJm
-(platform) 34.3112 Tj
--386 TJm
-(--) 6.63509 Tj
--386 TJm
-(a) 4.42339 Tj
--386 TJm
-(major) 23.2427 Tj
--385 TJm
-(con\002guration) 53.1305 Tj
--386 TJm
-(error) 19.3573 Tj
-55 TJm
-(.) 2.49065 Tj
-108 248.404 Td
-(Speci\002cally) 47.0434 Tj
-65 TJm
-(,) 2.49065 Tj
--481 TJm
-(it) 5.53921 Tj
--435 TJm
-(means) 25.4544 Tj
--435 TJm
-(that) 14.9439 Tj
-[1 0 0 1 220.614 248.404] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -220.614 -248.404] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-220.614 248.404 Td
-/F134_0 9.9626 Tf
-(sizeof\(char\)) 71.7307 Tj
-[1 0 0 1 292.345 248.404] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -292.345 -248.404] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-292.345 248.404 Td
-/F130_0 9.9626 Tf
-(,) 2.49065 Tj
-[1 0 0 1 299.628 248.404] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -299.628 -248.404] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-299.628 248.404 Td
-/F134_0 9.9626 Tf
-(sizeof\(short\)) 77.7083 Tj
-[1 0 0 1 377.337 248.404] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -377.337 -248.404] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-381.669 248.404 Td
-/F130_0 9.9626 Tf
-(and) 14.386 Tj
-[1 0 0 1 400.388 248.404] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -400.388 -248.404] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-400.388 248.404 Td
-/F134_0 9.9626 Tf
-(sizeof\(int\)) 65.7532 Tj
-[1 0 0 1 466.141 248.404] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -466.141 -248.404] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-470.474 248.404 Td
-/F130_0 9.9626 Tf
-(are) 12.1643 Tj
--435 TJm
-(not) 12.7322 Tj
--435 TJm
-(1,) 7.47195 Tj
--481 TJm
-(2) 4.9813 Tj
--435 TJm
-(and) 14.386 Tj
-108 236.449 Td
-(4) 4.9813 Tj
--389 TJm
-(respecti) 30.9837 Tj
-25 TJm
-(v) 4.9813 Tj
-15 TJm
-(ely) 12.1743 Tj
-65 TJm
-(,) 2.49065 Tj
--424 TJm
-(as) 8.29885 Tj
--390 TJm
-(the) 12.1743 Tj
-15 TJm
-(y) 4.9813 Tj
--389 TJm
-(should) 26.5703 Tj
--389 TJm
-(be.) 11.8953 Tj
--1456 TJm
-(Note) 19.3673 Tj
--389 TJm
-(that) 14.9439 Tj
--389 TJm
-(the) 12.1743 Tj
--389 TJm
-(library) 26.5603 Tj
--390 TJm
-(should) 26.5703 Tj
--389 TJm
-(still) 14.9539 Tj
--389 TJm
-(w) 7.193 Tj
-10 TJm
-(ork) 13.2801 Tj
--389 TJm
-(properly) 33.7533 Tj
--390 TJm
-(on) 9.9626 Tj
--389 TJm
-(64-bit) 23.8007 Tj
--389 TJm
-(platforms) 38.1866 Tj
-108 224.493 Td
-(which) 24.3486 Tj
--292 TJm
-(follo) 18.8194 Tj
-25 TJm
-(w) 7.193 Tj
--292 TJm
-(the) 12.1743 Tj
--292 TJm
-(LP64) 21.589 Tj
--292 TJm
-(programming) 54.2364 Tj
--293 TJm
-(model) 24.9065 Tj
--292 TJm
-(--) 6.63509 Tj
--292 TJm
-(that) 14.9439 Tj
--292 TJm
-(is,) 9.1357 Tj
--303 TJm
-(where) 24.3386 Tj
-[1 0 0 1 355.279 224.493] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -355.279 -224.493] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-355.279 224.493 Td
-/F134_0 9.9626 Tf
-(sizeof\(long\)) 71.7307 Tj
-[1 0 0 1 427.01 224.493] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -427.01 -224.493] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-429.92 224.493 Td
-/F130_0 9.9626 Tf
-(and) 14.386 Tj
-[1 0 0 1 447.217 224.493] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -447.217 -224.493] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-447.217 224.493 Td
-/F134_0 9.9626 Tf
-(sizeof\(void) 65.7532 Tj
-512.97 222.75 Td
-(*) 5.97756 Tj
-518.948 224.493 Td
-(\)) 5.97756 Tj
-[1 0 0 1 524.925 224.493] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -524.925 -224.493] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-527.836 224.493 Td
-/F130_0 9.9626 Tf
-(are) 12.1643 Tj
-108 212.538 Td
-(8.) 7.47195 Tj
--620 TJm
-(Under) 24.8965 Tj
--250 TJm
-(LP64,) 24.0796 Tj
-[1 0 0 1 175.606 212.538] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -175.606 -212.538] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-175.606 212.538 Td
-/F134_0 9.9626 Tf
-(sizeof\(int\)) 65.7532 Tj
-[1 0 0 1 241.36 212.538] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -241.36 -212.538] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-243.85 212.538 Td
-/F130_0 9.9626 Tf
-(is) 6.64505 Tj
--250 TJm
-(still) 14.9539 Tj
--250 TJm
-(4,) 7.47195 Tj
--250 TJm
-(so) 8.85675 Tj
-[1 0 0 1 291.74 212.538] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -291.74 -212.538] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-291.74 212.538 Td
-/F134_0 9.9626 Tf
-(libbzip2) 47.8205 Tj
-[1 0 0 1 339.56 212.538] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -339.56 -212.538] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-339.56 212.538 Td
-/F130_0 9.9626 Tf
-(,) 2.49065 Tj
--250 TJm
-(which) 24.3486 Tj
--250 TJm
-(doesn') 26.5603 Tj
-18 TJm
-(t) 2.7696 Tj
--250 TJm
-(use) 13.2801 Tj
--250 TJm
-(the) 12.1743 Tj
-[1 0 0 1 433.458 212.538] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -433.458 -212.538] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-433.458 212.538 Td
-/F134_0 9.9626 Tf
-(long) 23.9102 Tj
-[1 0 0 1 457.368 212.538] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -457.368 -212.538] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-459.859 212.538 Td
-/F130_0 9.9626 Tf
-(type,) 19.6462 Tj
--250 TJm
-(is) 6.64505 Tj
--250 TJm
-(OK.) 16.8766 Tj
-[1 0 0 1 72 210.381] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -3.7659] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.7436] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -196.872] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 187.074 Td
-/F134_0 9.9626 Tf
-(BZ_SEQUENCE_ERROR) 101.619 Tj
-[1 0 0 1 173.619 187.074] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -104.11 -1.31] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -185.764] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-108 175.118 Td
-/F130_0 9.9626 Tf
-(When) 23.7907 Tj
--291 TJm
-(using) 21.589 Tj
--290 TJm
-(the) 12.1743 Tj
--291 TJm
-(library) 26.5603 Tj
-65 TJm
-(,) 2.49065 Tj
--300 TJm
-(it) 5.53921 Tj
--291 TJm
-(is) 6.64505 Tj
--290 TJm
-(important) 38.7446 Tj
--291 TJm
-(to) 7.7509 Tj
--290 TJm
-(call) 14.386 Tj
--291 TJm
-(the) 12.1743 Tj
--290 TJm
-(functions) 37.0808 Tj
--291 TJm
-(in) 7.7509 Tj
--290 TJm
-(the) 12.1743 Tj
--291 TJm
-(correct) 27.6562 Tj
--290 TJm
-(sequence) 36.5129 Tj
--291 TJm
-(and) 14.386 Tj
--290 TJm
-(with) 17.7135 Tj
--291 TJm
-(data) 16.5977 Tj
--290 TJm
-(structures) 38.7346 Tj
-108 163.163 Td
-(\(b) 8.29885 Tj
-20 TJm
-(uf) 8.29885 Tj
-25 TJm
-(fers) 14.9339 Tj
--206 TJm
-(etc\)) 14.9339 Tj
--205 TJm
-(in) 7.7509 Tj
--206 TJm
-(the) 12.1743 Tj
--205 TJm
-(correct) 27.6562 Tj
--206 TJm
-(states.) 24.6275 Tj
-[1 0 0 1 239.409 163.163] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -239.409 -163.163] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-239.409 163.163 Td
-/F134_0 9.9626 Tf
-(libbzip2) 47.8205 Tj
-[1 0 0 1 287.23 163.163] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -287.23 -163.163] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-289.278 163.163 Td
-/F130_0 9.9626 Tf
-(checks) 27.1082 Tj
--206 TJm
-(as) 8.29885 Tj
--205 TJm
-(much) 22.1369 Tj
--206 TJm
-(as) 8.29885 Tj
--205 TJm
-(it) 5.53921 Tj
--206 TJm
-(can) 13.8281 Tj
--206 TJm
-(to) 7.7509 Tj
--205 TJm
-(ensure) 26.0024 Tj
--206 TJm
-(this) 14.396 Tj
--206 TJm
-(is) 6.64505 Tj
--205 TJm
-(happening,) 43.9948 Tj
--215 TJm
-(and) 14.386 Tj
--205 TJm
-(returns) 27.6661 Tj
-[1 0 0 1 108 151.208] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -108 -151.208] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-108 151.208 Td
-/F134_0 9.9626 Tf
-(BZ_SEQUENCE_ERROR) 101.619 Tj
-[1 0 0 1 209.619 151.208] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -209.619 -151.208] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-213.27 151.208 Td
-/F130_0 9.9626 Tf
-(if) 6.08715 Tj
--367 TJm
-(not.) 15.2229 Tj
--659 TJm
-(Code) 21.031 Tj
--367 TJm
-(which) 24.3486 Tj
--367 TJm
-(complies) 35.9749 Tj
--366 TJm
-(precisely) 35.965 Tj
--367 TJm
-(with) 17.7135 Tj
--366 TJm
-(the) 12.1743 Tj
--367 TJm
-(function) 33.2053 Tj
--366 TJm
-(semantics,) 41.7831 Tj
--396 TJm
-(as) 8.29885 Tj
--367 TJm
-(detailed) 31.5416 Tj
-108 139.253 Td
-(belo) 17.1556 Tj
-25 TJm
-(w) 7.193 Tj
-65 TJm
-(,) 2.49065 Tj
--250 TJm
-(should) 26.5703 Tj
--250 TJm
-(ne) 9.40469 Tj
-25 TJm
-(v) 4.9813 Tj
-15 TJm
-(er) 7.74094 Tj
--250 TJm
-(recei) 19.3573 Tj
-25 TJm
-(v) 4.9813 Tj
-15 TJm
-(e) 4.42339 Tj
--250 TJm
-(this) 14.396 Tj
--250 TJm
-(v) 4.9813 Tj
-25 TJm
-(alue;) 19.3673 Tj
--250 TJm
-(such) 18.2614 Tj
--250 TJm
-(an) 9.40469 Tj
--250 TJm
-(e) 4.42339 Tj
-25 TJm
-(v) 4.9813 Tj
-15 TJm
-(ent) 12.1743 Tj
--250 TJm
-(denotes) 30.4357 Tj
--250 TJm
-(b) 4.9813 Tj
-20 TJm
-(uggy) 19.9252 Tj
--250 TJm
-(code) 18.8094 Tj
--250 TJm
-(which) 24.3486 Tj
--250 TJm
-(you) 14.9439 Tj
--250 TJm
-(should) 26.5703 Tj
--250 TJm
-(in) 7.7509 Tj
-40 TJm
-(v) 4.9813 Tj
-15 TJm
-(estig) 18.8194 Tj
-5 TJm
-(ate.) 14.107 Tj
-[1 0 0 1 72 137.096] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -3.7659] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.7436] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -123.587] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 113.788 Td
-/F134_0 9.9626 Tf
-(BZ_PARAM_ERROR) 83.6858 Tj
-[1 0 0 1 155.686 113.788] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4906 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -86.1768 -1.31] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -112.478] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-108 101.833 Td
-/F130_0 9.9626 Tf
-(Returned) 36.5229 Tj
--434 TJm
-(when) 21.579 Tj
--434 TJm
-(a) 4.42339 Tj
--434 TJm
-(parameter) 39.8305 Tj
--434 TJm
-(to) 7.7509 Tj
--434 TJm
-(a) 4.42339 Tj
--433 TJm
-(function) 33.2053 Tj
--434 TJm
-(call) 14.386 Tj
--434 TJm
-(is) 6.64505 Tj
--434 TJm
-(out) 12.7322 Tj
--434 TJm
-(of) 8.29885 Tj
--434 TJm
-(range) 22.1269 Tj
--434 TJm
-(or) 8.29885 Tj
--434 TJm
-(otherwise) 38.7346 Tj
--434 TJm
-(manifestly) 42.0621 Tj
--434 TJm
-(incorrect.) 37.8977 Tj
--1723 TJm
-(As) 11.0684 Tj
-108 89.8778 Td
-(with) 17.7135 Tj
-[1 0 0 1 131.644 89.8778] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -131.644 -89.8778] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-131.644 89.8778 Td
-/F134_0 9.9626 Tf
-(BZ_SEQUENCE_ERROR) 101.619 Tj
-[1 0 0 1 233.263 89.8778] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -233.263 -89.8778] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-233.263 89.8778 Td
-/F130_0 9.9626 Tf
-(,) 2.49065 Tj
--595 TJm
-(this) 14.396 Tj
--596 TJm
-(denotes) 30.4357 Tj
--595 TJm
-(a) 4.42339 Tj
--595 TJm
-(b) 4.9813 Tj
-20 TJm
-(ug) 9.9626 Tj
--596 TJm
-(in) 7.7509 Tj
--595 TJm
-(the) 12.1743 Tj
--595 TJm
-(client) 22.1369 Tj
--595 TJm
-(code.) 21.3 Tj
--2692 TJm
-(The) 15.4918 Tj
--596 TJm
-(distinction) 42.0721 Tj
--595 TJm
-(between) 33.1954 Tj
-[1 0 0 1 108 77.9227] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -108 -77.9227] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-108 77.9227 Td
-/F134_0 9.9626 Tf
-(BZ_PARAM_ERROR) 83.6858 Tj
-[1 0 0 1 191.686 77.9227] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -191.686 -77.9227] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-194.177 77.9227 Td
-/F130_0 9.9626 Tf
-(and) 14.386 Tj
-[1 0 0 1 211.053 77.9227] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -211.053 -77.9227] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-211.053 77.9227 Td
-/F134_0 9.9626 Tf
-(BZ_SEQUENCE_ERROR) 101.619 Tj
-[1 0 0 1 312.672 77.9227] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -312.672 -77.9227] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-315.163 77.9227 Td
-/F130_0 9.9626 Tf
-(is) 6.64505 Tj
--250 TJm
-(a) 4.42339 Tj
--250 TJm
-(bit) 10.5205 Tj
--250 TJm
-(hazy) 18.8094 Tj
-65 TJm
-(,) 2.49065 Tj
--250 TJm
-(b) 4.9813 Tj
-20 TJm
-(ut) 7.7509 Tj
--250 TJm
-(still) 14.9539 Tj
--250 TJm
-(w) 7.193 Tj
-10 TJm
-(orth) 16.0497 Tj
--250 TJm
-(making.) 32.3785 Tj
-[1 0 0 1 72 75.7659] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -3.7659] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -21.1482] cm
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-[1 0 0 1 1.8929 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 374.394 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 6.8541] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 40.5726 -6.7545] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -493.841 -50.9514] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-534.414 50.9514 Td
-/F130_0 9.9626 Tf
-(10) 9.9626 Tj
-[1 0 0 1 453.269 50.8518] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 93.5985 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 6.2765 0] cm
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-[1 0 0 1 -13.1436 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-Q
-showpage
-%%PageTrailer
-pdfEndPage
-%%Page: 14 14
-%%BeginPageSetup
-%%PageOrientation: Portrait
-pdfStartPage
-0 0 612 792 re W
-%%EndPageSetup
-[] 0 d
-1 i
-0 j
-0 J
-10 M
-1 w
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-false op
-false OP
-0 0 612 792 re
-W
-q
-[1 0 0 1 72 741.554] cm
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-[1 0 0 1 1.8929 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 14.4459] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 187.197 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 -8.9114] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 8.9114] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 76.4979 -6.7546] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -342.569 -749.245] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-419.067 749.245 Td
-/F130_0 9.9626 Tf
-(Programming) 54.7943 Tj
--250 TJm
-(with) 17.7135 Tj
-[1 0 0 1 496.556 749.245] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -496.556 -749.245] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-496.556 749.245 Td
-/F134_0 9.9626 Tf
-(libbzip2) 47.8205 Tj
-[1 0 0 1 544.376 749.245] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -278.305 -2.1568] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 280.796 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -472.974 -5.0363] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -0.4981] cm
-q
-[] 0 d
-0 J
-0.4981 w
-0 0.2491 m
-475.465 0.2491 l
-S
-Q
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 479.251 0] cm
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-[1 0 0 1 -13.1436 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -468 -21.5542] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -720] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 710.037 Td
-/F134_0 9.9626 Tf
-(BZ_MEM_ERROR) 71.7307 Tj
-[1 0 0 1 143.731 710.037] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -74.2217 -1.31] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -708.727] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-108 698.082 Td
-/F130_0 9.9626 Tf
-(Returned) 36.5229 Tj
--228 TJm
-(when) 21.579 Tj
--227 TJm
-(a) 4.42339 Tj
--228 TJm
-(request) 28.772 Tj
--227 TJm
-(to) 7.7509 Tj
--228 TJm
-(allocate) 30.9837 Tj
--228 TJm
-(memory) 33.2053 Tj
--227 TJm
-(f) 3.31755 Tj
-10 TJm
-(ailed.) 21.8579 Tj
--605 TJm
-(Note) 19.3673 Tj
--228 TJm
-(that) 14.9439 Tj
--228 TJm
-(the) 12.1743 Tj
--227 TJm
-(quantity) 32.6574 Tj
--228 TJm
-(of) 8.29885 Tj
--227 TJm
-(memory) 33.2053 Tj
--228 TJm
-(needed) 28.2141 Tj
--228 TJm
-(to) 7.7509 Tj
--227 TJm
-(decompress) 47.0334 Tj
-108 686.127 Td
-(a) 4.42339 Tj
--351 TJm
-(stream) 26.5603 Tj
--352 TJm
-(cannot) 26.5603 Tj
--351 TJm
-(be) 9.40469 Tj
--352 TJm
-(determined) 44.8217 Tj
--351 TJm
-(until) 18.2714 Tj
--352 TJm
-(the) 12.1743 Tj
--351 TJm
-(stream') 29.8778 Tj
-55 TJm
-(s) 3.87545 Tj
--351 TJm
-(header) 26.5503 Tj
--352 TJm
-(has) 13.2801 Tj
--351 TJm
-(been) 18.8094 Tj
--352 TJm
-(read.) 19.6363 Tj
--1228 TJm
-(So) 10.5205 Tj
-[1 0 0 1 426.471 686.127] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -426.471 -686.127] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-426.471 686.127 Td
-/F134_0 9.9626 Tf
-(BZ2_bzDecompress) 95.641 Tj
-[1 0 0 1 522.113 686.127] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -522.113 -686.127] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-525.614 686.127 Td
-/F130_0 9.9626 Tf
-(and) 14.386 Tj
-[1 0 0 1 108 674.172] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -108 -674.172] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-108 674.172 Td
-/F134_0 9.9626 Tf
-(BZ2_bzRead) 59.7756 Tj
-[1 0 0 1 167.776 674.172] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -167.776 -674.172] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-172.13 674.172 Td
-/F130_0 9.9626 Tf
-(may) 17.1556 Tj
--437 TJm
-(return) 23.7907 Tj
-[1 0 0 1 221.784 674.172] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -221.784 -674.172] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-221.784 674.172 Td
-/F134_0 9.9626 Tf
-(BZ_MEM_ERROR) 71.7307 Tj
-[1 0 0 1 293.515 674.172] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -293.515 -674.172] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-297.867 674.172 Td
-/F130_0 9.9626 Tf
-(e) 4.42339 Tj
-25 TJm
-(v) 4.9813 Tj
-15 TJm
-(en) 9.40469 Tj
--437 TJm
-(though) 27.6761 Tj
--437 TJm
-(some) 21.031 Tj
--437 TJm
-(of) 8.29885 Tj
--437 TJm
-(the) 12.1743 Tj
--437 TJm
-(compressed) 47.0334 Tj
--437 TJm
-(data) 16.5977 Tj
--437 TJm
-(has) 13.2801 Tj
--437 TJm
-(been) 18.8094 Tj
--437 TJm
-(read.) 19.6363 Tj
-108 662.217 Td
-(The) 15.4918 Tj
--479 TJm
-(same) 20.4731 Tj
--478 TJm
-(is) 6.64505 Tj
--479 TJm
-(not) 12.7322 Tj
--478 TJm
-(true) 15.4918 Tj
--479 TJm
-(for) 11.6164 Tj
--479 TJm
-(compression;) 53.1305 Tj
--593 TJm
-(once) 18.8094 Tj
-[1 0 0 1 301.675 662.217] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -301.675 -662.217] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-301.675 662.217 Td
-/F134_0 9.9626 Tf
-(BZ2_bzCompressInit) 107.596 Tj
-[1 0 0 1 409.271 662.217] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -409.271 -662.217] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-414.04 662.217 Td
-/F130_0 9.9626 Tf
-(or) 8.29885 Tj
-[1 0 0 1 427.107 662.217] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -427.107 -662.217] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-427.107 662.217 Td
-/F134_0 9.9626 Tf
-(BZ2_bzWriteOpen) 89.6634 Tj
-[1 0 0 1 516.771 662.217] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -516.771 -662.217] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-521.539 662.217 Td
-/F130_0 9.9626 Tf
-(ha) 9.40469 Tj
-20 TJm
-(v) 4.9813 Tj
-15 TJm
-(e) 4.42339 Tj
-108 650.262 Td
-(successfully) 48.6972 Tj
--250 TJm
-(completed,) 43.9948 Tj
-[1 0 0 1 205.672 650.261] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -205.672 -650.261] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-205.672 650.261 Td
-/F134_0 9.9626 Tf
-(BZ_MEM_ERROR) 71.7307 Tj
-[1 0 0 1 277.403 650.261] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -277.403 -650.261] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-279.894 650.261 Td
-/F130_0 9.9626 Tf
-(cannot) 26.5603 Tj
--250 TJm
-(occur) 22.1269 Tj
-55 TJm
-(.) 2.49065 Tj
-[1 0 0 1 72 648.105] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -3.985] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.9626] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -634.157] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 624.359 Td
-/F134_0 9.9626 Tf
-(BZ_DATA_ERROR) 77.7083 Tj
-[1 0 0 1 149.709 624.359] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -80.1993 -1.31] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -623.049] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-108 612.404 Td
-/F130_0 9.9626 Tf
-(Returned) 36.5229 Tj
--266 TJm
-(when) 21.579 Tj
--265 TJm
-(a) 4.42339 Tj
--266 TJm
-(data) 16.5977 Tj
--265 TJm
-(inte) 14.9439 Tj
-15 TJm
-(grity) 18.8194 Tj
--266 TJm
-(error) 19.3573 Tj
--266 TJm
-(is) 6.64505 Tj
--265 TJm
-(detected) 33.1954 Tj
--266 TJm
-(during) 26.0123 Tj
--265 TJm
-(decompression.) 62.2563 Tj
--714 TJm
-(Most) 20.4831 Tj
--266 TJm
-(importantl) 41.5142 Tj
-1 TJm
-(y) 4.9813 Tj
-64 TJm
-(,) 2.49065 Tj
--269 TJm
-(this) 14.396 Tj
--266 TJm
-(means) 25.4544 Tj
--265 TJm
-(when) 21.579 Tj
-108 600.448 Td
-(stored) 24.3486 Tj
--222 TJm
-(and) 14.386 Tj
--223 TJm
-(computed) 39.2925 Tj
--222 TJm
-(CRCs) 23.8106 Tj
--222 TJm
-(for) 11.6164 Tj
--222 TJm
-(the) 12.1743 Tj
--223 TJm
-(data) 16.5977 Tj
--222 TJm
-(do) 9.9626 Tj
--222 TJm
-(not) 12.7322 Tj
--222 TJm
-(match.) 26.8392 Tj
--602 TJm
-(This) 17.7135 Tj
--222 TJm
-(v) 4.9813 Tj
-25 TJm
-(alue) 16.5977 Tj
--222 TJm
-(is) 6.64505 Tj
--223 TJm
-(also) 16.0497 Tj
--222 TJm
-(returned) 33.1954 Tj
--222 TJm
-(upon) 19.9252 Tj
--222 TJm
-(detection) 36.5229 Tj
--223 TJm
-(of) 8.29885 Tj
--222 TJm
-(an) 9.40469 Tj
-15 TJm
-(y) 4.9813 Tj
--222 TJm
-(other) 20.4731 Tj
-108 588.493 Td
-(anomaly) 34.3112 Tj
--250 TJm
-(in) 7.7509 Tj
--250 TJm
-(the) 12.1743 Tj
--250 TJm
-(compressed) 47.0334 Tj
--250 TJm
-(data.) 19.0883 Tj
-[1 0 0 1 72 586.336] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -3.985] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.9626] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -572.389] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 562.59 Td
-/F134_0 9.9626 Tf
-(BZ_DATA_ERROR_MAGIC) 113.574 Tj
-[1 0 0 1 185.574 562.59] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -116.065 -1.31] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -561.28] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-108 550.635 Td
-/F130_0 9.9626 Tf
-(As) 11.0684 Tj
--306 TJm
-(a) 4.42339 Tj
--306 TJm
-(special) 27.6661 Tj
--306 TJm
-(case) 17.1456 Tj
--307 TJm
-(of) 8.29885 Tj
-[1 0 0 1 191.852 550.635] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -191.852 -550.635] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-191.852 550.635 Td
-/F134_0 9.9626 Tf
-(BZ_DATA_ERROR) 77.7083 Tj
-[1 0 0 1 269.561 550.635] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -269.561 -550.635] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-269.561 550.635 Td
-/F130_0 9.9626 Tf
-(,) 2.49065 Tj
--306 TJm
-(it) 5.53921 Tj
--306 TJm
-(is) 6.64505 Tj
--306 TJm
-(sometimes) 42.62 Tj
--307 TJm
-(usef) 16.5977 Tj
-1 TJm
-(ul) 7.7509 Tj
--307 TJm
-(to) 7.7509 Tj
--306 TJm
-(kno) 14.9439 Tj
-25 TJm
-(w) 7.193 Tj
--306 TJm
-(when) 21.579 Tj
--306 TJm
-(the) 12.1743 Tj
--306 TJm
-(compressed) 47.0334 Tj
--306 TJm
-(stream) 26.5603 Tj
--306 TJm
-(does) 18.2614 Tj
-108 538.68 Td
-(not) 12.7322 Tj
--250 TJm
-(start) 17.1556 Tj
--250 TJm
-(with) 17.7135 Tj
--250 TJm
-(the) 12.1743 Tj
--250 TJm
-(correct) 27.6562 Tj
--250 TJm
-(magic) 24.3486 Tj
--250 TJm
-(bytes) 21.031 Tj
--250 TJm
-(\() 3.31755 Tj
-[1 0 0 1 261.562 538.68] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -261.562 -538.68] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-261.562 538.68 Td
-/F134_0 9.9626 Tf
-('B') 17.9327 Tj
--600 TJm
-('Z') 17.9327 Tj
--600 TJm
-('h') 17.9327 Tj
-[1 0 0 1 327.316 538.68] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -327.316 -538.68] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-327.316 538.68 Td
-/F130_0 9.9626 Tf
-(\).) 5.8082 Tj
-[1 0 0 1 72 536.523] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -3.985] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.9626] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -522.576] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 512.777 Td
-/F134_0 9.9626 Tf
-(BZ_IO_ERROR) 65.7532 Tj
-[1 0 0 1 137.753 512.777] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -68.2441 -1.3101] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -511.467] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-108 500.822 Td
-/F130_0 9.9626 Tf
-(Returned) 36.5229 Tj
--233 TJm
-(by) 9.9626 Tj
-[1 0 0 1 159.123 500.822] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -159.123 -500.822] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-159.123 500.822 Td
-/F134_0 9.9626 Tf
-(BZ2_bzRead) 59.7756 Tj
-[1 0 0 1 218.899 500.822] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -218.899 -500.822] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-221.218 500.822 Td
-/F130_0 9.9626 Tf
-(and) 14.386 Tj
-[1 0 0 1 237.923 500.822] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -237.923 -500.822] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-237.923 500.822 Td
-/F134_0 9.9626 Tf
-(BZ2_bzWrite) 65.7532 Tj
-[1 0 0 1 303.676 500.822] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -303.676 -500.822] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-305.995 500.822 Td
-/F130_0 9.9626 Tf
-(when) 21.579 Tj
--233 TJm
-(there) 19.9152 Tj
--232 TJm
-(is) 6.64505 Tj
--233 TJm
-(an) 9.40469 Tj
--233 TJm
-(error) 19.3573 Tj
--233 TJm
-(reading) 29.8778 Tj
--232 TJm
-(or) 8.29885 Tj
--233 TJm
-(writing) 28.782 Tj
--233 TJm
-(in) 7.7509 Tj
--233 TJm
-(the) 12.1743 Tj
--232 TJm
-(compressed) 47.0334 Tj
-108 488.867 Td
-(\002le,) 15.2229 Tj
--384 TJm
-(and) 14.386 Tj
--357 TJm
-(by) 9.9626 Tj
-[1 0 0 1 158.511 488.867] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -158.511 -488.867] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-158.511 488.867 Td
-/F134_0 9.9626 Tf
-(BZ2_bzReadOpen) 83.6858 Tj
-[1 0 0 1 242.197 488.867] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -242.197 -488.867] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-245.755 488.867 Td
-/F130_0 9.9626 Tf
-(and) 14.386 Tj
-[1 0 0 1 263.698 488.867] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -263.698 -488.867] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-263.698 488.867 Td
-/F134_0 9.9626 Tf
-(BZ2_bzWriteOpen) 89.6634 Tj
-[1 0 0 1 353.362 488.867] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -353.362 -488.867] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-356.92 488.867 Td
-/F130_0 9.9626 Tf
-(for) 11.6164 Tj
--357 TJm
-(attempts) 33.7633 Tj
--357 TJm
-(to) 7.7509 Tj
--357 TJm
-(use) 13.2801 Tj
--357 TJm
-(a) 4.42339 Tj
--357 TJm
-(\002le) 12.7322 Tj
--357 TJm
-(for) 11.6164 Tj
--358 TJm
-(which) 24.3486 Tj
--357 TJm
-(the) 12.1743 Tj
--357 TJm
-(error) 19.3573 Tj
-108 476.912 Td
-(indicator) 35.417 Tj
--260 TJm
-(\(viz,) 17.9825 Tj
-[1 0 0 1 166.603 476.912] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -166.603 -476.912] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-166.603 476.912 Td
-/F134_0 9.9626 Tf
-(ferror\(f\)) 53.798 Tj
-[1 0 0 1 220.401 476.912] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -220.401 -476.912] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-220.401 476.912 Td
-/F130_0 9.9626 Tf
-(\)) 3.31755 Tj
--260 TJm
-(is) 6.64505 Tj
--260 TJm
-(set.) 13.5591 Tj
--679 TJm
-(On) 12.1743 Tj
--260 TJm
-(receipt) 27.1082 Tj
--260 TJm
-(of) 8.29885 Tj
-[1 0 0 1 311.223 476.912] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -311.223 -476.912] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-311.223 476.912 Td
-/F134_0 9.9626 Tf
-(BZ_IO_ERROR) 65.7532 Tj
-[1 0 0 1 376.976 476.912] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -376.976 -476.912] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-376.976 476.912 Td
-/F130_0 9.9626 Tf
-(,) 2.49065 Tj
--260 TJm
-(the) 12.1743 Tj
--260 TJm
-(caller) 22.1269 Tj
--260 TJm
-(should) 26.5703 Tj
--260 TJm
-(consult) 28.782 Tj
-[1 0 0 1 482.068 476.912] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -482.068 -476.912] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-482.068 476.912 Td
-/F134_0 9.9626 Tf
-(errno) 29.8878 Tj
-[1 0 0 1 511.956 476.912] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -511.956 -476.912] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-514.546 476.912 Td
-/F130_0 9.9626 Tf
-(and/or) 25.4544 Tj
-[1 0 0 1 108 464.957] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -108 -464.957] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-108 464.957 Td
-/F134_0 9.9626 Tf
-(perror) 35.8654 Tj
-[1 0 0 1 143.865 464.957] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -143.865 -464.957] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-146.356 464.957 Td
-/F130_0 9.9626 Tf
-(to) 7.7509 Tj
--250 TJm
-(acquire) 29.3199 Tj
--250 TJm
-(operating-system) 68.6224 Tj
--250 TJm
-(speci\002c) 30.4357 Tj
--250 TJm
-(information) 47.0434 Tj
--250 TJm
-(about) 22.1369 Tj
--250 TJm
-(the) 12.1743 Tj
--250 TJm
-(problem.) 35.696 Tj
-[1 0 0 1 72 462.8] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -3.9849] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.9627] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -448.852] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 439.054 Td
-/F134_0 9.9626 Tf
-(BZ_UNEXPECTED_EOF) 101.619 Tj
-[1 0 0 1 173.619 439.054] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -104.11 -1.31] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -437.744] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-108 427.099 Td
-/F130_0 9.9626 Tf
-(Returned) 36.5229 Tj
--250 TJm
-(by) 9.9626 Tj
-[1 0 0 1 159.467 427.099] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -159.467 -427.099] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-159.467 427.099 Td
-/F134_0 9.9626 Tf
-(BZ2_bzRead) 59.7756 Tj
-[1 0 0 1 219.242 427.099] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -219.242 -427.099] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-221.733 427.099 Td
-/F130_0 9.9626 Tf
-(when) 21.579 Tj
--250 TJm
-(the) 12.1743 Tj
--250 TJm
-(compressed) 47.0334 Tj
--250 TJm
-(\002le) 12.7322 Tj
--250 TJm
-(\002nishes) 30.4457 Tj
--250 TJm
-(before) 25.4445 Tj
--250 TJm
-(the) 12.1743 Tj
--250 TJm
-(logical) 27.1182 Tj
--250 TJm
-(end) 14.386 Tj
--250 TJm
-(of) 8.29885 Tj
--250 TJm
-(stream) 26.5603 Tj
--250 TJm
-(is) 6.64505 Tj
--250 TJm
-(detected.) 35.686 Tj
-[1 0 0 1 72 424.942] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -3.985] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.9626] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -410.994] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 401.196 Td
-/F134_0 9.9626 Tf
-(BZ_OUTBUFF_FULL) 89.6634 Tj
-[1 0 0 1 161.664 401.196] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4906 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -92.1544 -1.31] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -399.886] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-108 389.241 Td
-/F130_0 9.9626 Tf
-(Returned) 36.5229 Tj
--258 TJm
-(by) 9.9626 Tj
-[1 0 0 1 159.632 389.241] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -159.632 -389.241] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-159.632 389.241 Td
-/F134_0 9.9626 Tf
-(BZ2_bzBuffToBuffCompress) 143.461 Tj
-[1 0 0 1 303.094 389.241] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -303.094 -389.241] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-305.668 389.241 Td
-/F130_0 9.9626 Tf
-(and) 14.386 Tj
-[1 0 0 1 322.627 389.241] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -322.627 -389.241] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-322.627 389.241 Td
-/F134_0 9.9626 Tf
-(BZ2_bzBuffToBuffDecompress) 155.417 Tj
-[1 0 0 1 478.044 389.241] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -478.044 -389.241] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-480.618 389.241 Td
-/F130_0 9.9626 Tf
-(to) 7.7509 Tj
--258 TJm
-(indicate) 31.5416 Tj
--259 TJm
-(that) 14.9439 Tj
-108 377.286 Td
-(the) 12.1743 Tj
--250 TJm
-(output) 25.4644 Tj
--250 TJm
-(data) 16.5977 Tj
--250 TJm
-(will) 15.5018 Tj
--250 TJm
-(not) 12.7322 Tj
--250 TJm
-(\002t) 8.30881 Tj
--250 TJm
-(into) 15.5018 Tj
--250 TJm
-(the) 12.1743 Tj
--250 TJm
-(output) 25.4644 Tj
--250 TJm
-(b) 4.9813 Tj
-20 TJm
-(uf) 8.29885 Tj
-25 TJm
-(fer) 11.0585 Tj
--250 TJm
-(pro) 13.2801 Tj
-15 TJm
-(vided.) 24.6275 Tj
-[1 0 0 1 72 375.129] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -3.985] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.9626] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.9626] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -351.218] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 328.585 Td
-/F122_0 20.6585 Tf
-(3.3.) 34.4584 Tj
--278 TJm
-(Lo) 25.2447 Tj
-15 TJm
-(w-le) 40.1808 Tj
-15 TJm
-(vel) 28.7153 Tj
--278 TJm
-(interface) 86.1046 Tj
-[1 0 0 1 72 328.327] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.9627] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -318.364] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 297.964 Td
-/F122_0 17.2154 Tf
-(3.3.1.) 43.0729 Tj
-[1 0 0 1 119.858 297.964] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -119.858 -297.964] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-119.858 297.964 Td
-/F392_0 17.2154 Tf
-(BZ2_bzCompressInit) 185.926 Tj
-[1 0 0 1 305.785 297.964] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -233.785 -2.3327] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -244.779] cm
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-[1 0 0 1 1.8929 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 374.394 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 6.7546] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 40.5726 -6.7546] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -493.841 -50.8518] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-534.414 50.8518 Td
-/F130_0 9.9626 Tf
-(11) 9.9626 Tj
-[1 0 0 1 453.269 50.8518] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 93.5985 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 6.2765 0] cm
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-[1 0 0 1 -13.1436 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-Q
-showpage
-%%PageTrailer
-pdfEndPage
-%%Page: 15 15
-%%BeginPageSetup
-%%PageOrientation: Portrait
-pdfStartPage
-0 0 612 792 re W
-%%EndPageSetup
-[] 0 d
-1 i
-0 j
-0 J
-10 M
-1 w
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-false op
-false OP
-0 0 612 792 re
-W
-q
-[1 0 0 1 72 741.554] cm
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-[1 0 0 1 1.8929 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 14.4459] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 187.197 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 -8.9114] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 8.9114] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 76.4979 -6.7546] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -342.569 -749.245] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-419.067 749.245 Td
-/F130_0 9.9626 Tf
-(Programming) 54.7943 Tj
--250 TJm
-(with) 17.7135 Tj
-[1 0 0 1 496.556 749.245] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -496.556 -749.245] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-496.556 749.245 Td
-/F134_0 9.9626 Tf
-(libbzip2) 47.8205 Tj
-[1 0 0 1 544.376 749.245] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -278.305 -2.1568] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 280.796 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -472.974 -5.0363] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -0.4981] cm
-q
-[] 0 d
-0 J
-0.4981 w
-0 0.2491 m
-475.465 0.2491 l
-S
-Q
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 479.251 0] cm
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-[1 0 0 1 -13.1436 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -468 -296.523] cm
-/DeviceRGB {} cs
-[0.94899 0.94899 0.976456] sc
-/DeviceRGB {} CS
-[0.94899 0.94899 0.976456] SC
-0 0 468 274.969 re
-f
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 3.5866] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 271.382] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 18 -8.3686] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -90 -711.631] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-90 711.631 Td
-/F134_0 9.9626 Tf
-(typedef) 41.8429 Tj
--426 TJm
-(struct) 35.8654 Tj
--426 TJm
-({) 5.97756 Tj
-98.4879 699.676 Td
-(char) 23.9102 Tj
-126.642 697.933 Td
-(*) 5.97756 Tj
-132.62 699.676 Td
-(next_in;) 47.8205 Tj
-98.4879 687.721 Td
-(unsigned) 47.8205 Tj
--426 TJm
-(int) 17.9327 Tj
--426 TJm
-(avail_in;) 53.798 Tj
-98.4879 675.766 Td
-(unsigned) 47.8205 Tj
--426 TJm
-(int) 17.9327 Tj
--426 TJm
-(total_in_lo32;) 83.6858 Tj
-98.4879 663.811 Td
-(unsigned) 47.8205 Tj
--426 TJm
-(int) 17.9327 Tj
--426 TJm
-(total_in_hi32;) 83.6858 Tj
-98.4879 639.9 Td
-(char) 23.9102 Tj
-126.642 638.157 Td
-(*) 5.97756 Tj
-132.62 639.9 Td
-(next_out;) 53.798 Tj
-98.4879 627.945 Td
-(unsigned) 47.8205 Tj
--426 TJm
-(int) 17.9327 Tj
--426 TJm
-(avail_out;) 59.7756 Tj
-98.4879 615.99 Td
-(unsigned) 47.8205 Tj
--426 TJm
-(int) 17.9327 Tj
--426 TJm
-(total_out_lo32;) 89.6634 Tj
-98.4879 604.035 Td
-(unsigned) 47.8205 Tj
--426 TJm
-(int) 17.9327 Tj
--426 TJm
-(total_out_hi32;) 89.6634 Tj
-98.4879 580.125 Td
-(void) 23.9102 Tj
-126.642 578.381 Td
-(*) 5.97756 Tj
-132.62 580.125 Td
-(state;) 35.8654 Tj
-98.4879 556.214 Td
-(void) 23.9102 Tj
-126.642 554.471 Td
-(*) 5.97756 Tj
-132.62 556.214 Td
-(\() 5.97756 Tj
-138.597 554.471 Td
-(*) 5.97756 Tj
-144.575 556.214 Td
-(bzalloc\)\(void) 77.7083 Tj
-226.527 554.471 Td
-(*) 5.97756 Tj
-232.505 556.214 Td
-(,int,int\);) 59.7756 Tj
-98.4879 544.259 Td
-(void) 23.9102 Tj
--426 TJm
-(\() 5.97756 Tj
-132.62 542.516 Td
-(*) 5.97756 Tj
-138.597 544.259 Td
-(bzfree\)\(void) 71.7307 Tj
-214.572 542.516 Td
-(*) 5.97756 Tj
-220.55 544.259 Td
-(,void) 29.8878 Tj
-254.682 542.516 Td
-(*) 5.97756 Tj
-260.659 544.259 Td
-(\);) 11.9551 Tj
-98.4879 532.304 Td
-(void) 23.9102 Tj
-126.642 530.56 Td
-(*) 5.97756 Tj
-132.62 532.304 Td
-(opaque;) 41.8429 Tj
-89.9999 520.349 Td
-(}) 5.97756 Tj
--426 TJm
-(bz_stream;) 59.7756 Tj
-89.9999 496.438 Td
-(int) 17.9327 Tj
--426 TJm
-(BZ2_bzCompressInit) 107.596 Tj
--426 TJm
-(\() 5.97756 Tj
--426 TJm
-(bz_stream) 53.798 Tj
-292.281 494.695 Td
-(*) 5.97756 Tj
-298.258 496.438 Td
-(strm,) 29.8878 Tj
-196.099 484.483 Td
-(int) 17.9327 Tj
--426 TJm
-(blockSize100k,) 83.6858 Tj
-196.099 472.528 Td
-(int) 17.9327 Tj
--426 TJm
-(verbosity,) 59.7756 Tj
-196.099 460.573 Td
-(int) 17.9327 Tj
--426 TJm
-(workFactor) 59.7756 Tj
--426 TJm
-(\);) 11.9551 Tj
-[1 0 0 1 72 445.031] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 468 3.5866] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -468 -13.5492] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -435.068] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 423.113 Td
-/F130_0 9.9626 Tf
-(Prepares) 34.3012 Tj
--356 TJm
-(for) 11.6164 Tj
--356 TJm
-(compression.) 52.8516 Tj
--1256 TJm
-(The) 15.4918 Tj
-[1 0 0 1 209.409 423.113] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -209.409 -423.113] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-209.409 423.113 Td
-/F134_0 9.9626 Tf
-(bz_stream) 53.798 Tj
-[1 0 0 1 263.208 423.113] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -263.208 -423.113] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-266.754 423.113 Td
-/F130_0 9.9626 Tf
-(structure) 34.8591 Tj
--356 TJm
-(holds) 21.589 Tj
--356 TJm
-(all) 9.9626 Tj
--356 TJm
-(data) 16.5977 Tj
--356 TJm
-(pertaining) 40.3983 Tj
--356 TJm
-(to) 7.7509 Tj
--356 TJm
-(the) 12.1743 Tj
--356 TJm
-(compression) 50.3609 Tj
--355 TJm
-(acti) 14.386 Tj
-25 TJm
-(vity) 15.5018 Tj
-65 TJm
-(.) 2.49065 Tj
--1256 TJm
-(A) 7.193 Tj
-[1 0 0 1 72 411.158] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -411.158] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 411.158 Td
-/F134_0 9.9626 Tf
-(bz_stream) 53.798 Tj
-[1 0 0 1 125.798 411.158] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -125.798 -411.158] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-128.581 411.158 Td
-/F130_0 9.9626 Tf
-(structure) 34.8591 Tj
--279 TJm
-(should) 26.5703 Tj
--280 TJm
-(be) 9.40469 Tj
--279 TJm
-(allocated) 35.965 Tj
--279 TJm
-(and) 14.386 Tj
--280 TJm
-(initialised) 39.3025 Tj
--279 TJm
-(prior) 19.3673 Tj
--279 TJm
-(to) 7.7509 Tj
--279 TJm
-(the) 12.1743 Tj
--280 TJm
-(call.) 16.8766 Tj
--796 TJm
-(The) 15.4918 Tj
--279 TJm
-(\002elds) 21.589 Tj
--279 TJm
-(of) 8.29885 Tj
-[1 0 0 1 431.939 411.158] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -431.939 -411.158] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-431.939 411.158 Td
-/F134_0 9.9626 Tf
-(bz_stream) 53.798 Tj
-[1 0 0 1 485.738 411.158] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -485.738 -411.158] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-488.52 411.158 Td
-/F130_0 9.9626 Tf
-(comprise) 36.5229 Tj
--279 TJm
-(the) 12.1743 Tj
-72 399.203 Td
-(entirety) 30.4357 Tj
--250 TJm
-(of) 8.29885 Tj
--250 TJm
-(the) 12.1743 Tj
--250 TJm
-(user) 16.5977 Tj
-20 TJm
-(-visible) 29.8878 Tj
--250 TJm
-(data.) 19.0883 Tj
-[1 0 0 1 204.422 399.203] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -204.422 -399.203] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-204.422 399.203 Td
-/F134_0 9.9626 Tf
-(state) 29.8878 Tj
-[1 0 0 1 234.31 399.203] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -234.31 -399.203] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-236.8 399.203 Td
-/F130_0 9.9626 Tf
-(is) 6.64505 Tj
--250 TJm
-(a) 4.42339 Tj
--250 TJm
-(pointer) 28.224 Tj
--250 TJm
-(to) 7.7509 Tj
--250 TJm
-(the) 12.1743 Tj
--250 TJm
-(pri) 11.0684 Tj
-25 TJm
-(v) 4.9813 Tj
-25 TJm
-(ate) 11.6164 Tj
--250 TJm
-(data) 16.5977 Tj
--250 TJm
-(structures) 38.7346 Tj
--250 TJm
-(required) 33.1954 Tj
--250 TJm
-(for) 11.6164 Tj
--250 TJm
-(compression.) 52.8516 Tj
-[1 0 0 1 72 397.046] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.9626] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -387.083] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 377.285 Td
-/F130_0 9.9626 Tf
-(Custom) 31.0036 Tj
--372 TJm
-(memory) 33.2053 Tj
--372 TJm
-(allocators) 38.7346 Tj
--372 TJm
-(are) 12.1643 Tj
--372 TJm
-(supported,) 41.7831 Tj
--403 TJm
-(via) 12.1743 Tj
--372 TJm
-(\002elds) 21.589 Tj
-[1 0 0 1 288.908 377.285] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -288.908 -377.285] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-288.908 377.285 Td
-/F134_0 9.9626 Tf
-(bzalloc) 41.8429 Tj
-[1 0 0 1 330.751 377.285] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -330.751 -377.285] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-330.751 377.285 Td
-/F130_0 9.9626 Tf
-(,) 2.49065 Tj
-[1 0 0 1 337.253 377.285] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -337.253 -377.285] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-337.253 377.285 Td
-/F134_0 9.9626 Tf
-(bzfree) 35.8654 Tj
-[1 0 0 1 373.118 377.285] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -373.118 -377.285] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-373.118 377.285 Td
-/F130_0 9.9626 Tf
-(,) 2.49065 Tj
--403 TJm
-(and) 14.386 Tj
-[1 0 0 1 397.714 377.285] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -397.714 -377.285] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-397.714 377.285 Td
-/F134_0 9.9626 Tf
-(opaque) 35.8654 Tj
-[1 0 0 1 433.579 377.285] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -433.579 -377.285] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-433.579 377.285 Td
-/F130_0 9.9626 Tf
-(.) 2.49065 Tj
--1353 TJm
-(The) 15.4918 Tj
--372 TJm
-(v) 4.9813 Tj
-25 TJm
-(alue) 16.5977 Tj
-[1 0 0 1 493.782 377.285] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -493.782 -377.285] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-493.782 377.285 Td
-/F134_0 9.9626 Tf
-(opaque) 35.8654 Tj
-[1 0 0 1 529.648 377.285] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -529.648 -377.285] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-533.355 377.285 Td
-/F130_0 9.9626 Tf
-(is) 6.64505 Tj
-72 365.33 Td
-(passed) 26.5603 Tj
--306 TJm
-(to) 7.7509 Tj
--306 TJm
-(as) 8.29885 Tj
--306 TJm
-(the) 12.1743 Tj
--306 TJm
-(\002rst) 15.5018 Tj
--306 TJm
-(ar) 7.74094 Tj
-18 TJm
-(gument) 29.8878 Tj
--306 TJm
-(to) 7.7509 Tj
--306 TJm
-(all) 9.9626 Tj
--306 TJm
-(calls) 18.2614 Tj
--305 TJm
-(to) 7.7509 Tj
-[1 0 0 1 253.941 365.33] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -253.941 -365.33] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-253.941 365.33 Td
-/F134_0 9.9626 Tf
-(bzalloc) 41.8429 Tj
-[1 0 0 1 295.784 365.33] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -295.784 -365.33] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-298.832 365.33 Td
-/F130_0 9.9626 Tf
-(and) 14.386 Tj
-[1 0 0 1 316.266 365.33] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -316.266 -365.33] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-316.266 365.33 Td
-/F134_0 9.9626 Tf
-(bzfree) 35.8654 Tj
-[1 0 0 1 352.132 365.33] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -352.132 -365.33] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-352.132 365.33 Td
-/F130_0 9.9626 Tf
-(,) 2.49065 Tj
--320 TJm
-(b) 4.9813 Tj
-20 TJm
-(ut) 7.7509 Tj
--306 TJm
-(is) 6.64505 Tj
--306 TJm
-(otherwise) 38.7346 Tj
--306 TJm
-(ignored) 30.4357 Tj
--306 TJm
-(by) 9.9626 Tj
--306 TJm
-(the) 12.1743 Tj
--306 TJm
-(library) 26.5603 Tj
-65 TJm
-(.) 2.49065 Tj
--955 TJm
-(The) 15.4918 Tj
-72 353.375 Td
-(call) 14.386 Tj
-[1 0 0 1 89.4309 353.375] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -89.4309 -353.375] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-89.4309 353.375 Td
-/F134_0 9.9626 Tf
-(bzalloc) 41.8429 Tj
--600 TJm
-(\() 5.97756 Tj
--600 TJm
-(opaque,) 41.8429 Tj
--600 TJm
-(n,) 11.9551 Tj
--600 TJm
-(m) 5.97756 Tj
--600 TJm
-(\)) 5.97756 Tj
-[1 0 0 1 232.893 353.375] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -232.893 -353.375] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-235.938 353.375 Td
-/F130_0 9.9626 Tf
-(is) 6.64505 Tj
--306 TJm
-(e) 4.42339 Tj
-15 TJm
-(xpected) 30.9837 Tj
--305 TJm
-(to) 7.7509 Tj
--306 TJm
-(return) 23.7907 Tj
--306 TJm
-(a) 4.42339 Tj
--305 TJm
-(pointer) 28.224 Tj
-[1 0 0 1 360.3 353.375] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -360.3 -353.375] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-360.3 353.375 Td
-/F134_0 9.9626 Tf
-(p) 5.97756 Tj
-[1 0 0 1 366.277 353.375] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -366.277 -353.375] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-369.322 353.375 Td
-/F130_0 9.9626 Tf
-(to) 7.7509 Tj
-[1 0 0 1 380.118 353.375] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -380.118 -353.375] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-380.118 353.375 Td
-/F134_0 9.9626 Tf
-(n) 5.97756 Tj
-392.073 351.631 Td
-(*) 5.97756 Tj
-404.029 353.375 Td
-(m) 5.97756 Tj
-[1 0 0 1 410.006 353.375] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -410.006 -353.375] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-413.051 353.375 Td
-/F130_0 9.9626 Tf
-(bytes) 21.031 Tj
--306 TJm
-(of) 8.29885 Tj
--305 TJm
-(memory) 33.2053 Tj
-65 TJm
-(,) 2.49065 Tj
--320 TJm
-(and) 14.386 Tj
-[1 0 0 1 504.135 353.375] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -504.135 -353.375] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-504.135 353.375 Td
-/F134_0 9.9626 Tf
-(bzfree) 35.8654 Tj
-72 341.42 Td
-(\() 5.97756 Tj
--600 TJm
-(opaque,) 41.8429 Tj
--600 TJm
-(p) 5.97756 Tj
--600 TJm
-(\)) 5.97756 Tj
-[1 0 0 1 149.709 341.42] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -149.709 -341.42] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-152.199 341.42 Td
-/F130_0 9.9626 Tf
-(should) 26.5703 Tj
--250 TJm
-(free) 15.4819 Tj
--250 TJm
-(that) 14.9439 Tj
--250 TJm
-(memory) 33.2053 Tj
-65 TJm
-(.) 2.49065 Tj
-[1 0 0 1 72 339.263] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.9626] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -329.3] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 319.502 Td
-/F130_0 9.9626 Tf
-(If) 6.63509 Tj
--280 TJm
-(you) 14.9439 Tj
--280 TJm
-(don') 18.2614 Tj
-18 TJm
-(t) 2.7696 Tj
--280 TJm
-(w) 7.193 Tj
-10 TJm
-(ant) 12.1743 Tj
--279 TJm
-(to) 7.7509 Tj
--280 TJm
-(use) 13.2801 Tj
--280 TJm
-(a) 4.42339 Tj
--280 TJm
-(custom) 28.782 Tj
--280 TJm
-(memory) 33.2053 Tj
--279 TJm
-(allocator) 34.8591 Tj
-40 TJm
-(,) 2.49065 Tj
--288 TJm
-(set) 11.0684 Tj
-[1 0 0 1 299.9 319.502] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -299.9 -319.502] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-299.9 319.502 Td
-/F134_0 9.9626 Tf
-(bzalloc) 41.8429 Tj
-[1 0 0 1 341.743 319.502] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -341.743 -319.502] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-341.743 319.502 Td
-/F130_0 9.9626 Tf
-(,) 2.49065 Tj
-[1 0 0 1 347.096 319.502] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -347.096 -319.502] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-347.096 319.502 Td
-/F134_0 9.9626 Tf
-(bzfree) 35.8654 Tj
-[1 0 0 1 382.961 319.502] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -382.961 -319.502] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-385.749 319.502 Td
-/F130_0 9.9626 Tf
-(and) 14.386 Tj
-[1 0 0 1 402.923 319.502] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -402.923 -319.502] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-402.923 319.502 Td
-/F134_0 9.9626 Tf
-(opaque) 35.8654 Tj
-[1 0 0 1 438.788 319.502] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -438.788 -319.502] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-441.576 319.502 Td
-/F130_0 9.9626 Tf
-(to) 7.7509 Tj
-[1 0 0 1 452.115 319.502] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -452.115 -319.502] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-452.115 319.502 Td
-/F134_0 9.9626 Tf
-(NULL) 23.9102 Tj
-[1 0 0 1 476.025 319.502] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -476.025 -319.502] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-476.025 319.502 Td
-/F130_0 9.9626 Tf
-(,) 2.49065 Tj
--280 TJm
-(and) 14.386 Tj
--280 TJm
-(the) 12.1743 Tj
--279 TJm
-(library) 26.5603 Tj
-72 307.547 Td
-(will) 15.5018 Tj
--250 TJm
-(then) 17.1556 Tj
--250 TJm
-(use) 13.2801 Tj
--250 TJm
-(the) 12.1743 Tj
--250 TJm
-(standard) 33.7533 Tj
-[1 0 0 1 176.318 307.547] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -176.318 -307.547] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-176.318 307.547 Td
-/F134_0 9.9626 Tf
-(malloc) 35.8654 Tj
-[1 0 0 1 212.183 307.547] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -212.183 -307.547] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-214.674 307.547 Td
-/F130_0 9.9626 Tf
-(/) 2.7696 Tj
-[1 0 0 1 219.934 307.547] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -219.934 -307.547] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-219.934 307.547 Td
-/F134_0 9.9626 Tf
-(free) 23.9102 Tj
-[1 0 0 1 243.844 307.547] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -243.844 -307.547] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-246.335 307.547 Td
-/F130_0 9.9626 Tf
-(routines.) 34.5901 Tj
-[1 0 0 1 72 307.392] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.9626] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -297.43] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 285.629 Td
-/F130_0 9.9626 Tf
-(Before) 27.1082 Tj
--362 TJm
-(calling) 27.1182 Tj
-[1 0 0 1 133.438 285.629] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -133.438 -285.629] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-133.438 285.629 Td
-/F134_0 9.9626 Tf
-(BZ2_bzCompressInit) 107.596 Tj
-[1 0 0 1 241.035 285.629] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -241.035 -285.629] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-241.035 285.629 Td
-/F130_0 9.9626 Tf
-(,) 2.49065 Tj
--390 TJm
-(\002elds) 21.589 Tj
-[1 0 0 1 272.606 285.629] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -272.606 -285.629] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-272.606 285.629 Td
-/F134_0 9.9626 Tf
-(bzalloc) 41.8429 Tj
-[1 0 0 1 314.449 285.629] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -314.449 -285.629] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-314.449 285.629 Td
-/F130_0 9.9626 Tf
-(,) 2.49065 Tj
-[1 0 0 1 320.825 285.629] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -320.825 -285.629] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-320.825 285.629 Td
-/F134_0 9.9626 Tf
-(bzfree) 35.8654 Tj
-[1 0 0 1 356.69 285.629] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -356.69 -285.629] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-360.296 285.629 Td
-/F130_0 9.9626 Tf
-(and) 14.386 Tj
-[1 0 0 1 378.288 285.629] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -378.288 -285.629] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-378.288 285.629 Td
-/F134_0 9.9626 Tf
-(opaque) 35.8654 Tj
-[1 0 0 1 414.154 285.629] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -414.154 -285.629] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-417.76 285.629 Td
-/F130_0 9.9626 Tf
-(should) 26.5703 Tj
--362 TJm
-(be) 9.40469 Tj
--362 TJm
-(\002lled) 20.4831 Tj
--362 TJm
-(appropriately) 53.1206 Tj
-65 TJm
-(,) 2.49065 Tj
-72 273.674 Td
-(as) 8.29885 Tj
--322 TJm
-(just) 14.396 Tj
--323 TJm
-(described.) 40.6673 Tj
--1055 TJm
-(Upon) 22.1369 Tj
--322 TJm
-(return,) 26.2813 Tj
--341 TJm
-(the) 12.1743 Tj
--322 TJm
-(internal) 30.4357 Tj
--323 TJm
-(state) 18.2614 Tj
--322 TJm
-(will) 15.5018 Tj
--323 TJm
-(ha) 9.40469 Tj
-20 TJm
-(v) 4.9813 Tj
-15 TJm
-(e) 4.42339 Tj
--322 TJm
-(been) 18.8094 Tj
--323 TJm
-(allocated) 35.965 Tj
--322 TJm
-(and) 14.386 Tj
--323 TJm
-(initialised,) 41.7931 Tj
--340 TJm
-(and) 14.386 Tj
-[1 0 0 1 459.801 273.674] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -459.801 -273.674] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-459.801 273.674 Td
-/F134_0 9.9626 Tf
-(total_in_lo32) 77.7083 Tj
-[1 0 0 1 537.509 273.674] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -537.509 -273.674] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-537.509 273.674 Td
-/F130_0 9.9626 Tf
-(,) 2.49065 Tj
-[1 0 0 1 72 261.718] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -261.718] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 261.718 Td
-/F134_0 9.9626 Tf
-(total_in_hi32) 77.7083 Tj
-[1 0 0 1 149.709 261.718] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -149.709 -261.718] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-149.709 261.718 Td
-/F130_0 9.9626 Tf
-(,) 2.49065 Tj
-[1 0 0 1 155.006 261.718] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -155.006 -261.718] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-155.006 261.718 Td
-/F134_0 9.9626 Tf
-(total_out_lo32) 83.6858 Tj
-[1 0 0 1 238.692 261.718] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -238.692 -261.718] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-241.435 261.718 Td
-/F130_0 9.9626 Tf
-(and) 14.386 Tj
-[1 0 0 1 258.564 261.718] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -258.564 -261.718] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-258.564 261.718 Td
-/F134_0 9.9626 Tf
-(total_out_hi32) 83.6858 Tj
-[1 0 0 1 342.25 261.718] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -342.25 -261.718] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-344.994 261.718 Td
-/F130_0 9.9626 Tf
-(will) 15.5018 Tj
--275 TJm
-(ha) 9.40469 Tj
-20 TJm
-(v) 4.9813 Tj
-15 TJm
-(e) 4.42339 Tj
--276 TJm
-(been) 18.8094 Tj
--275 TJm
-(set) 11.0684 Tj
--275 TJm
-(to) 7.7509 Tj
--276 TJm
-(zero.) 19.6363 Tj
--772 TJm
-(These) 23.7907 Tj
--275 TJm
-(four) 16.5977 Tj
--276 TJm
-(\002elds) 21.589 Tj
--275 TJm
-(are) 12.1643 Tj
-72 249.763 Td
-(used) 18.2614 Tj
--340 TJm
-(by) 9.9626 Tj
--339 TJm
-(the) 12.1743 Tj
--340 TJm
-(library) 26.5603 Tj
--339 TJm
-(to) 7.7509 Tj
--340 TJm
-(inform) 27.1182 Tj
--339 TJm
-(the) 12.1743 Tj
--340 TJm
-(caller) 22.1269 Tj
--339 TJm
-(of) 8.29885 Tj
--340 TJm
-(the) 12.1743 Tj
--339 TJm
-(total) 17.7135 Tj
--340 TJm
-(amount) 29.8878 Tj
--339 TJm
-(of) 8.29885 Tj
--340 TJm
-(data) 16.5977 Tj
--340 TJm
-(passed) 26.5603 Tj
--339 TJm
-(into) 15.5018 Tj
--340 TJm
-(and) 14.386 Tj
--339 TJm
-(out) 12.7322 Tj
--340 TJm
-(of) 8.29885 Tj
--339 TJm
-(the) 12.1743 Tj
--340 TJm
-(library) 26.5603 Tj
-65 TJm
-(,) 2.49065 Tj
--362 TJm
-(respecti) 30.9837 Tj
-25 TJm
-(v) 4.9813 Tj
-15 TJm
-(ely) 12.1743 Tj
-65 TJm
-(.) 2.49065 Tj
-72 237.808 Td
-(Y) 7.193 Tj
-110 TJm
-(ou) 9.9626 Tj
--376 TJm
-(should) 26.5703 Tj
--377 TJm
-(not) 12.7322 Tj
--376 TJm
-(try) 11.0684 Tj
--376 TJm
-(to) 7.7509 Tj
--377 TJm
-(change) 28.2141 Tj
--376 TJm
-(them.) 22.4159 Tj
--1378 TJm
-(As) 11.0684 Tj
--377 TJm
-(of) 8.29885 Tj
--376 TJm
-(v) 4.9813 Tj
-15 TJm
-(ersion) 24.3486 Tj
--377 TJm
-(1.0,) 14.9439 Tj
--408 TJm
-(64-bit) 23.8007 Tj
--376 TJm
-(counts) 26.0123 Tj
--376 TJm
-(are) 12.1643 Tj
--377 TJm
-(maintained,) 46.7644 Tj
--408 TJm
-(e) 4.42339 Tj
-25 TJm
-(v) 4.9813 Tj
-15 TJm
-(en) 9.40469 Tj
--376 TJm
-(on) 9.9626 Tj
--376 TJm
-(32-bit) 23.8007 Tj
--377 TJm
-(platforms,) 40.6773 Tj
-72 225.853 Td
-(using) 21.589 Tj
--371 TJm
-(the) 12.1743 Tj
-[1 0 0 1 113.148 225.853] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -113.148 -225.853] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-113.148 225.853 Td
-/F134_0 9.9626 Tf
-(_hi32) 29.8878 Tj
-[1 0 0 1 143.036 225.853] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -143.036 -225.853] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-146.729 225.853 Td
-/F130_0 9.9626 Tf
-(\002elds) 21.589 Tj
--371 TJm
-(to) 7.7509 Tj
--370 TJm
-(store) 19.3673 Tj
--371 TJm
-(the) 12.1743 Tj
--371 TJm
-(upper) 22.6848 Tj
--370 TJm
-(32) 9.9626 Tj
--371 TJm
-(bits) 14.396 Tj
--370 TJm
-(of) 8.29885 Tj
--371 TJm
-(the) 12.1743 Tj
--371 TJm
-(count.) 24.6275 Tj
--1344 TJm
-(So,) 13.0112 Tj
--400 TJm
-(for) 11.6164 Tj
--371 TJm
-(e) 4.42339 Tj
-15 TJm
-(xample,) 31.8205 Tj
--401 TJm
-(the) 12.1743 Tj
--371 TJm
-(total) 17.7135 Tj
--370 TJm
-(amount) 29.8878 Tj
--371 TJm
-(of) 8.29885 Tj
--370 TJm
-(data) 16.5977 Tj
--371 TJm
-(in) 7.7509 Tj
--371 TJm
-(is) 6.64505 Tj
-[1 0 0 1 72 213.898] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -213.898] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 213.898 Td
-/F134_0 9.9626 Tf
-(\(total_in_hi32) 83.6858 Tj
--600 TJm
-(<<) 11.9551 Tj
--600 TJm
-(32\)) 17.9327 Tj
--600 TJm
-(+) 5.97756 Tj
--600 TJm
-(total_in_lo32) 77.7083 Tj
-[1 0 0 1 293.171 213.898] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -293.171 -213.898] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-293.171 213.898 Td
-/F130_0 9.9626 Tf
-(.) 2.49065 Tj
-[1 0 0 1 72 212.588] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.9627] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -202.625] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 191.98 Td
-/F130_0 9.9626 Tf
-(P) 5.53921 Tj
-15 TJm
-(arameter) 34.8492 Tj
-[1 0 0 1 115.367 191.98] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -115.367 -191.98] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-115.367 191.98 Td
-/F134_0 9.9626 Tf
-(blockSize100k) 77.7083 Tj
-[1 0 0 1 193.076 191.98] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -193.076 -191.98] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-196.204 191.98 Td
-/F130_0 9.9626 Tf
-(speci\002es) 34.3112 Tj
--314 TJm
-(the) 12.1743 Tj
--314 TJm
-(block) 22.1369 Tj
--314 TJm
-(size) 15.4918 Tj
--314 TJm
-(to) 7.7509 Tj
--314 TJm
-(be) 9.40469 Tj
--314 TJm
-(used) 18.2614 Tj
--314 TJm
-(for) 11.6164 Tj
--314 TJm
-(compression.) 52.8516 Tj
--1004 TJm
-(It) 6.08715 Tj
--314 TJm
-(should) 26.5703 Tj
--314 TJm
-(be) 9.40469 Tj
--315 TJm
-(a) 4.42339 Tj
--314 TJm
-(v) 4.9813 Tj
-25 TJm
-(alue) 16.5977 Tj
--314 TJm
-(between) 33.1954 Tj
--314 TJm
-(1) 4.9813 Tj
-72 180.025 Td
-(and) 14.386 Tj
--289 TJm
-(9) 4.9813 Tj
--289 TJm
-(inclusi) 26.5703 Tj
-25 TJm
-(v) 4.9813 Tj
-15 TJm
-(e,) 6.91404 Tj
--299 TJm
-(and) 14.386 Tj
--289 TJm
-(the) 12.1743 Tj
--289 TJm
-(actual) 23.7907 Tj
--289 TJm
-(block) 22.1369 Tj
--289 TJm
-(size) 15.4918 Tj
--289 TJm
-(used) 18.2614 Tj
--289 TJm
-(is) 6.64505 Tj
--289 TJm
-(100000) 29.8878 Tj
--289 TJm
-(x) 4.9813 Tj
--289 TJm
-(this) 14.396 Tj
--289 TJm
-(\002gure.) 25.7334 Tj
--854 TJm
-(9) 4.9813 Tj
--290 TJm
-(gi) 7.7509 Tj
-25 TJm
-(v) 4.9813 Tj
-15 TJm
-(es) 8.29885 Tj
--289 TJm
-(the) 12.1743 Tj
--289 TJm
-(best) 16.0497 Tj
--289 TJm
-(compression) 50.3609 Tj
--289 TJm
-(b) 4.9813 Tj
-20 TJm
-(ut) 7.7509 Tj
--289 TJm
-(tak) 12.1743 Tj
-10 TJm
-(es) 8.29885 Tj
--289 TJm
-(most) 19.3773 Tj
-72 168.07 Td
-(memory) 33.2053 Tj
-65 TJm
-(.) 2.49065 Tj
-[1 0 0 1 72 165.913] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.9626] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -155.95] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 146.152 Td
-/F130_0 9.9626 Tf
-(P) 5.53921 Tj
-15 TJm
-(arameter) 34.8492 Tj
-[1 0 0 1 115.095 146.152] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -115.095 -146.152] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-115.095 146.152 Td
-/F134_0 9.9626 Tf
-(verbosity) 53.798 Tj
-[1 0 0 1 168.893 146.152] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -168.893 -146.152] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-171.75 146.152 Td
-/F130_0 9.9626 Tf
-(should) 26.5703 Tj
--287 TJm
-(be) 9.40469 Tj
--286 TJm
-(set) 11.0684 Tj
--287 TJm
-(to) 7.7509 Tj
--287 TJm
-(a) 4.42339 Tj
--287 TJm
-(number) 30.4357 Tj
--286 TJm
-(between) 33.1954 Tj
--287 TJm
-(0) 4.9813 Tj
--287 TJm
-(and) 14.386 Tj
--287 TJm
-(4) 4.9813 Tj
--286 TJm
-(inclusi) 26.5703 Tj
-25 TJm
-(v) 4.9813 Tj
-15 TJm
-(e.) 6.91404 Tj
--841 TJm
-(0) 4.9813 Tj
--286 TJm
-(is) 6.64505 Tj
--287 TJm
-(silent,) 24.0796 Tj
--296 TJm
-(and) 14.386 Tj
--287 TJm
-(greater) 27.6562 Tj
--287 TJm
-(numbers) 34.3112 Tj
--286 TJm
-(gi) 7.7509 Tj
-25 TJm
-(v) 4.9813 Tj
-15 TJm
-(e) 4.42339 Tj
-72 134.197 Td
-(increasingly) 48.6972 Tj
--342 TJm
-(v) 4.9813 Tj
-15 TJm
-(erbose) 26.0024 Tj
--342 TJm
-(monitoring/deb) 61.4394 Tj
-20 TJm
-(ugging) 27.6761 Tj
--342 TJm
-(output.) 27.9551 Tj
--1173 TJm
-(If) 6.63509 Tj
--343 TJm
-(the) 12.1743 Tj
--342 TJm
-(library) 26.5603 Tj
--342 TJm
-(has) 13.2801 Tj
--342 TJm
-(been) 18.8094 Tj
--342 TJm
-(compiled) 37.0808 Tj
--342 TJm
-(with) 17.7135 Tj
-[1 0 0 1 446.429 134.197] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -446.429 -134.197] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-446.429 134.197 Td
-/F134_0 9.9626 Tf
-(-DBZ_NO_STDIO) 77.7083 Tj
-[1 0 0 1 524.138 134.197] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -524.138 -134.197] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-524.138 134.197 Td
-/F130_0 9.9626 Tf
-(,) 2.49065 Tj
--342 TJm
-(no) 9.9626 Tj
-72 122.242 Td
-(such) 18.2614 Tj
--250 TJm
-(output) 25.4644 Tj
--250 TJm
-(will) 15.5018 Tj
--250 TJm
-(appear) 26.5503 Tj
--250 TJm
-(for) 11.6164 Tj
--250 TJm
-(an) 9.40469 Tj
-15 TJm
-(y) 4.9813 Tj
--250 TJm
-(v) 4.9813 Tj
-15 TJm
-(erbosity) 32.0995 Tj
--250 TJm
-(setting.) 29.0609 Tj
-[1 0 0 1 72 120.085] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.9626] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -110.122] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 100.324 Td
-/F130_0 9.9626 Tf
-(P) 5.53921 Tj
-15 TJm
-(arameter) 34.8492 Tj
-[1 0 0 1 116.619 100.324] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -116.619 -100.324] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-116.619 100.324 Td
-/F134_0 9.9626 Tf
-(workFactor) 59.7756 Tj
-[1 0 0 1 176.394 100.324] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -176.394 -100.324] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-180.775 100.324 Td
-/F130_0 9.9626 Tf
-(controls) 32.0995 Tj
--440 TJm
-(ho) 9.9626 Tj
-25 TJm
-(w) 7.193 Tj
--439 TJm
-(the) 12.1743 Tj
--440 TJm
-(compression) 50.3609 Tj
--440 TJm
-(phase) 22.6848 Tj
--439 TJm
-(beha) 18.8094 Tj
-20 TJm
-(v) 4.9813 Tj
-15 TJm
-(es) 8.29885 Tj
--440 TJm
-(when) 21.579 Tj
--439 TJm
-(presented) 38.1767 Tj
--440 TJm
-(with) 17.7135 Tj
--440 TJm
-(w) 7.193 Tj
-10 TJm
-(orst) 14.9439 Tj
--439 TJm
-(case,) 19.6363 Tj
--487 TJm
-(highly) 25.4644 Tj
-72 88.3686 Td
-(repetiti) 28.224 Tj
-25 TJm
-(v) 4.9813 Tj
-15 TJm
-(e,) 6.91404 Tj
--433 TJm
-(input) 20.4831 Tj
--396 TJm
-(data.) 19.0883 Tj
--1496 TJm
-(If) 6.63509 Tj
--396 TJm
-(compression) 50.3609 Tj
--396 TJm
-(runs) 17.1556 Tj
--397 TJm
-(i) 2.7696 Tj
-1 TJm
-(nto) 12.7322 Tj
--397 TJm
-(dif) 11.0684 Tj
-25 TJm
-(\002culties) 31.5516 Tj
--396 TJm
-(caused) 27.1082 Tj
--396 TJm
-(by) 9.9626 Tj
--396 TJm
-(repetiti) 28.224 Tj
-25 TJm
-(v) 4.9813 Tj
-15 TJm
-(e) 4.42339 Tj
--396 TJm
-(data,) 19.0883 Tj
--432 TJm
-(the) 12.1743 Tj
--397 TJm
-(library) 26.5603 Tj
--396 TJm
-(switches) 34.3112 Tj
--396 TJm
-(from) 19.3673 Tj
-[1 0 0 1 72 50.8518] cm
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-[1 0 0 1 1.8929 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 374.394 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 6.7546] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 40.5726 -6.7546] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -493.841 -50.8518] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-534.414 50.8518 Td
-/F130_0 9.9626 Tf
-(12) 9.9626 Tj
-[1 0 0 1 453.269 50.8518] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 93.5985 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 6.2765 0] cm
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-[1 0 0 1 -13.1436 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-Q
-showpage
-%%PageTrailer
-pdfEndPage
-%%Page: 16 16
-%%BeginPageSetup
-%%PageOrientation: Portrait
-pdfStartPage
-0 0 612 792 re W
-%%EndPageSetup
-[] 0 d
-1 i
-0 j
-0 J
-10 M
-1 w
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-false op
-false OP
-0 0 612 792 re
-W
-q
-[1 0 0 1 72 741.554] cm
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-[1 0 0 1 1.8929 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 14.4459] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 187.197 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 -8.9114] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 8.9114] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 76.4979 -6.7546] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -342.569 -749.245] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-419.067 749.245 Td
-/F130_0 9.9626 Tf
-(Programming) 54.7943 Tj
--250 TJm
-(with) 17.7135 Tj
-[1 0 0 1 496.556 749.245] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -496.556 -749.245] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-496.556 749.245 Td
-/F134_0 9.9626 Tf
-(libbzip2) 47.8205 Tj
-[1 0 0 1 544.376 749.245] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -278.305 -2.1568] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 280.796 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -472.974 -5.0363] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -0.4981] cm
-q
-[] 0 d
-0 J
-0.4981 w
-0 0.2491 m
-475.465 0.2491 l
-S
-Q
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 479.251 0] cm
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-[1 0 0 1 -13.1436 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -540 -741.554] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 710.037 Td
-/F130_0 9.9626 Tf
-(the) 12.1743 Tj
--255 TJm
-(standard) 33.7533 Tj
--254 TJm
-(sorting) 27.6761 Tj
--255 TJm
-(algorithm) 38.7446 Tj
--254 TJm
-(to) 7.7509 Tj
--255 TJm
-(a) 4.42339 Tj
--255 TJm
-(f) 3.31755 Tj
-10 TJm
-(allback) 28.772 Tj
--254 TJm
-(algorithm.) 41.2352 Tj
--648 TJm
-(The) 15.4918 Tj
--255 TJm
-(f) 3.31755 Tj
-10 TJm
-(allback) 28.772 Tj
--254 TJm
-(is) 6.64505 Tj
--255 TJm
-(slo) 11.6264 Tj
-25 TJm
-(wer) 14.9339 Tj
--255 TJm
-(than) 17.1556 Tj
--254 TJm
-(the) 12.1743 Tj
--255 TJm
-(standard) 33.7533 Tj
--254 TJm
-(algorithm) 38.7446 Tj
--255 TJm
-(by) 9.9626 Tj
--255 TJm
-(perhaps) 30.9837 Tj
-72 698.082 Td
-(a) 4.42339 Tj
--250 TJm
-(f) 3.31755 Tj
-10 TJm
-(actor) 19.9152 Tj
--250 TJm
-(of) 8.29885 Tj
--250 TJm
-(three,) 22.4059 Tj
--250 TJm
-(b) 4.9813 Tj
-20 TJm
-(ut) 7.7509 Tj
--250 TJm
-(al) 7.193 Tj
-10 TJm
-(w) 7.193 Tj
-10 TJm
-(ays) 13.2801 Tj
--250 TJm
-(beha) 18.8094 Tj
-20 TJm
-(v) 4.9813 Tj
-15 TJm
-(es) 8.29885 Tj
--250 TJm
-(reasonably) 43.158 Tj
-65 TJm
-(,) 2.49065 Tj
--250 TJm
-(no) 9.9626 Tj
--250 TJm
-(matter) 25.4544 Tj
--250 TJm
-(ho) 9.9626 Tj
-25 TJm
-(w) 7.193 Tj
--250 TJm
-(bad) 14.386 Tj
--250 TJm
-(the) 12.1743 Tj
--250 TJm
-(input.) 22.9738 Tj
-[1 0 0 1 72 695.925] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.9617] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -685.964] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 676.165 Td
-/F130_0 9.9626 Tf
-(Lo) 11.0684 Tj
-25 TJm
-(wer) 14.9339 Tj
--240 TJm
-(v) 4.9813 Tj
-25 TJm
-(alues) 20.4731 Tj
--239 TJm
-(of) 8.29885 Tj
-[1 0 0 1 138.421 676.165] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -138.421 -676.165] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-138.421 676.165 Td
-/F134_0 9.9626 Tf
-(workFactor) 59.7756 Tj
-[1 0 0 1 198.197 676.165] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -198.197 -676.165] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-200.585 676.165 Td
-/F130_0 9.9626 Tf
-(reduce) 26.5503 Tj
--240 TJm
-(the) 12.1743 Tj
--239 TJm
-(amount) 29.8878 Tj
--240 TJm
-(of) 8.29885 Tj
--240 TJm
-(ef) 7.74094 Tj
-25 TJm
-(fort) 14.386 Tj
--239 TJm
-(the) 12.1743 Tj
--240 TJm
-(standard) 33.7533 Tj
--240 TJm
-(algorithm) 38.7446 Tj
--239 TJm
-(will) 15.5018 Tj
--240 TJm
-(e) 4.42339 Tj
-15 TJm
-(xpend) 24.3486 Tj
--240 TJm
-(before) 25.4445 Tj
--240 TJm
-(resorting) 35.417 Tj
--239 TJm
-(to) 7.7509 Tj
--240 TJm
-(the) 12.1743 Tj
-72 664.21 Td
-(f) 3.31755 Tj
-10 TJm
-(allback.) 31.2626 Tj
--618 TJm
-(Y) 7.193 Tj
-110 TJm
-(ou) 9.9626 Tj
--248 TJm
-(should) 26.5703 Tj
--247 TJm
-(set) 11.0684 Tj
--248 TJm
-(this) 14.396 Tj
--247 TJm
-(parameter) 39.8305 Tj
--248 TJm
-(carefully;) 38.1767 Tj
--248 TJm
-(too) 12.7322 Tj
--248 TJm
-(lo) 7.7509 Tj
-25 TJm
-(w) 7.193 Tj
-65 TJm
-(,) 2.49065 Tj
--248 TJm
-(and) 14.386 Tj
--247 TJm
-(man) 17.1556 Tj
-15 TJm
-(y) 4.9813 Tj
--248 TJm
-(inputs) 24.3586 Tj
--248 TJm
-(will) 15.5018 Tj
--247 TJm
-(be) 9.40469 Tj
--248 TJm
-(handled) 31.5416 Tj
--247 TJm
-(by) 9.9626 Tj
--248 TJm
-(the) 12.1743 Tj
--247 TJm
-(f) 3.31755 Tj
-10 TJm
-(allback) 28.772 Tj
--248 TJm
-(algorithm) 38.7446 Tj
-72 652.255 Td
-(and) 14.386 Tj
--308 TJm
-(so) 8.85675 Tj
--308 TJm
-(compress) 37.6287 Tj
--308 TJm
-(rather) 23.2328 Tj
--309 TJm
-(slo) 11.6264 Tj
-25 TJm
-(wly) 14.9439 Tj
-65 TJm
-(,) 2.49065 Tj
--322 TJm
-(too) 12.7322 Tj
--309 TJm
-(high,) 20.2042 Tj
--322 TJm
-(and) 14.386 Tj
--308 TJm
-(your) 18.2614 Tj
--309 TJm
-(a) 4.42339 Tj
-20 TJm
-(v) 4.9813 Tj
-15 TJm
-(erage-to-w) 43.148 Tj
-10 TJm
-(orst) 14.9439 Tj
--308 TJm
-(case) 17.1456 Tj
--308 TJm
-(compression) 50.3609 Tj
--308 TJm
-(times) 21.589 Tj
--308 TJm
-(can) 13.8281 Tj
--308 TJm
-(become) 30.9837 Tj
--309 TJm
-(v) 4.9813 Tj
-15 TJm
-(ery) 12.7222 Tj
--308 TJm
-(lar) 10.5105 Tj
-18 TJm
-(ge.) 11.8953 Tj
-72 640.3 Td
-(The) 15.4918 Tj
--250 TJm
-(def) 12.7222 Tj
-10 TJm
-(ault) 14.9439 Tj
--250 TJm
-(v) 4.9813 Tj
-25 TJm
-(alue) 16.5977 Tj
--250 TJm
-(of) 8.29885 Tj
--250 TJm
-(30) 9.9626 Tj
--250 TJm
-(gi) 7.7509 Tj
-25 TJm
-(v) 4.9813 Tj
-15 TJm
-(es) 8.29885 Tj
--250 TJm
-(reasonable) 42.6001 Tj
--250 TJm
-(beha) 18.8094 Tj
-20 TJm
-(viour) 21.031 Tj
--250 TJm
-(o) 4.9813 Tj
-15 TJm
-(v) 4.9813 Tj
-15 TJm
-(er) 7.74094 Tj
--250 TJm
-(a) 4.42339 Tj
--250 TJm
-(wide) 19.3673 Tj
--250 TJm
-(range) 22.1269 Tj
--250 TJm
-(of) 8.29885 Tj
--250 TJm
-(circumstances.) 58.9288 Tj
-[1 0 0 1 72 638.143] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.9617] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -628.181] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 618.383 Td
-/F130_0 9.9626 Tf
-(Allo) 17.7135 Tj
-25 TJm
-(w) 7.193 Tj
-10 TJm
-(able) 16.5977 Tj
--250 TJm
-(v) 4.9813 Tj
-25 TJm
-(alues) 20.4731 Tj
--250 TJm
-(range) 22.1269 Tj
--250 TJm
-(from) 19.3673 Tj
--250 TJm
-(0) 4.9813 Tj
--250 TJm
-(to) 7.7509 Tj
--250 TJm
-(250) 14.9439 Tj
--250 TJm
-(inclusi) 26.5703 Tj
-25 TJm
-(v) 4.9813 Tj
-15 TJm
-(e.) 6.91404 Tj
--620 TJm
-(0) 4.9813 Tj
--250 TJm
-(is) 6.64505 Tj
--250 TJm
-(a) 4.42339 Tj
--250 TJm
-(special) 27.6661 Tj
--250 TJm
-(case,) 19.6363 Tj
--250 TJm
-(equi) 17.1556 Tj
-25 TJm
-(v) 4.9813 Tj
-25 TJm
-(alent) 19.3673 Tj
--250 TJm
-(to) 7.7509 Tj
--250 TJm
-(using) 21.589 Tj
--250 TJm
-(the) 12.1743 Tj
--250 TJm
-(def) 12.7222 Tj
-10 TJm
-(ault) 14.9439 Tj
--250 TJm
-(v) 4.9813 Tj
-25 TJm
-(alue) 16.5977 Tj
--250 TJm
-(of) 8.29885 Tj
--250 TJm
-(30.) 12.4533 Tj
-[1 0 0 1 72 616.226] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.9617] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -606.265] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 596.466 Td
-/F130_0 9.9626 Tf
-(Note) 19.3673 Tj
--250 TJm
-(that) 14.9439 Tj
--250 TJm
-(the) 12.1743 Tj
--250 TJm
-(compressed) 47.0334 Tj
--250 TJm
-(output) 25.4644 Tj
--250 TJm
-(generated) 38.7246 Tj
--250 TJm
-(is) 6.64505 Tj
--250 TJm
-(the) 12.1743 Tj
--250 TJm
-(same) 20.4731 Tj
--250 TJm
-(re) 7.74094 Tj
-15 TJm
-(g) 4.9813 Tj
-5 TJm
-(ardless) 27.6661 Tj
--250 TJm
-(of) 8.29885 Tj
--250 TJm
-(whether) 32.0895 Tj
--250 TJm
-(or) 8.29885 Tj
--250 TJm
-(not) 12.7322 Tj
--250 TJm
-(the) 12.1743 Tj
--250 TJm
-(f) 3.31755 Tj
-10 TJm
-(allback) 28.772 Tj
--250 TJm
-(algorithm) 38.7446 Tj
--250 TJm
-(is) 6.64505 Tj
--250 TJm
-(used.) 20.7521 Tj
-[1 0 0 1 72 594.309] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.9617] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -584.348] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 574.549 Td
-/F130_0 9.9626 Tf
-(Be) 11.0684 Tj
--303 TJm
-(a) 4.42339 Tj
-15 TJm
-(w) 7.193 Tj
-10 TJm
-(are) 12.1643 Tj
--303 TJm
-(also) 16.0497 Tj
--303 TJm
-(that) 14.9439 Tj
--303 TJm
-(this) 14.396 Tj
--304 TJm
-(parameter) 39.8305 Tj
--303 TJm
-(may) 17.1556 Tj
--303 TJm
-(disappear) 38.1767 Tj
--303 TJm
-(entirely) 30.4357 Tj
--303 TJm
-(in) 7.7509 Tj
--303 TJm
-(future) 23.7907 Tj
--303 TJm
-(v) 4.9813 Tj
-15 TJm
-(ersions) 28.224 Tj
--303 TJm
-(of) 8.29885 Tj
--303 TJm
-(the) 12.1743 Tj
--304 TJm
-(library) 26.5603 Tj
-65 TJm
-(.) 2.49065 Tj
--938 TJm
-(In) 8.29885 Tj
--303 TJm
-(principle) 35.417 Tj
--303 TJm
-(it) 5.53921 Tj
--304 TJm
-(should) 26.5703 Tj
--303 TJm
-(be) 9.40469 Tj
-72 562.594 Td
-(possible) 32.6574 Tj
--270 TJm
-(to) 7.7509 Tj
--270 TJm
-(de) 9.40469 Tj
-25 TJm
-(vise) 16.0497 Tj
--270 TJm
-(a) 4.42339 Tj
--270 TJm
-(good) 19.9252 Tj
--270 TJm
-(w) 7.193 Tj
-10 TJm
-(ay) 9.40469 Tj
--270 TJm
-(to) 7.7509 Tj
--271 TJm
-(automat) 32.0995 Tj
-1 TJm
-(ically) 22.1369 Tj
--271 TJm
-(choose) 27.6661 Tj
--270 TJm
-(which) 24.3486 Tj
--270 TJm
-(algorithm) 38.7446 Tj
--270 TJm
-(to) 7.7509 Tj
--270 TJm
-(use.) 15.7708 Tj
--740 TJm
-(Such) 19.9252 Tj
--270 TJm
-(a) 4.42339 Tj
--271 TJm
-(m) 7.7509 Tj
-1 TJm
-(echanism) 37.6287 Tj
--271 TJm
-(w) 7.193 Tj
-10 TJm
-(ould) 17.7135 Tj
--270 TJm
-(render) 25.4445 Tj
--270 TJm
-(the) 12.1743 Tj
-72 550.639 Td
-(parameter) 39.8305 Tj
--250 TJm
-(obsolete.) 35.696 Tj
-[1 0 0 1 72 548.482] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.9616] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -538.521] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 528.722 Td
-/F130_0 9.9626 Tf
-(Possible) 33.2153 Tj
--250 TJm
-(return) 23.7907 Tj
--250 TJm
-(v) 4.9813 Tj
-25 TJm
-(alues:) 23.2427 Tj
-[1 0 0 1 72 528.623] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -144.458] cm
-/DeviceRGB {} cs
-[0.94899 0.94899 0.976456] sc
-/DeviceRGB {} CS
-[0.94899 0.94899 0.976456] SC
-0 0 468 143.462 re
-f
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 3.5866] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 139.875] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 18 -8.3686] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -90 -519.258] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-90 519.258 Td
-/F134_0 9.9626 Tf
-(BZ_CONFIG_ERROR) 89.6634 Tj
-98.4879 507.303 Td
-(if) 11.9551 Tj
--426 TJm
-(the) 17.9327 Tj
--426 TJm
-(library) 41.8429 Tj
--426 TJm
-(has) 17.9327 Tj
--426 TJm
-(been) 23.9102 Tj
--426 TJm
-(mis-compiled) 71.7307 Tj
-90 495.348 Td
-(BZ_PARAM_ERROR) 83.6858 Tj
-98.4879 483.392 Td
-(if) 11.9551 Tj
--426 TJm
-(strm) 23.9102 Tj
--426 TJm
-(is) 11.9551 Tj
--426 TJm
-(NULL) 23.9102 Tj
-98.4879 471.437 Td
-(or) 11.9551 Tj
--426 TJm
-(blockSize) 53.798 Tj
--426 TJm
-(<) 5.97756 Tj
--426 TJm
-(1) 5.97756 Tj
--426 TJm
-(or) 11.9551 Tj
--426 TJm
-(blockSize) 53.798 Tj
--426 TJm
-(>) 5.97756 Tj
--426 TJm
-(9) 5.97756 Tj
-98.4879 459.482 Td
-(or) 11.9551 Tj
--426 TJm
-(verbosity) 53.798 Tj
--426 TJm
-(<) 5.97756 Tj
--426 TJm
-(0) 5.97756 Tj
--426 TJm
-(or) 11.9551 Tj
--426 TJm
-(verbosity) 53.798 Tj
--426 TJm
-(>) 5.97756 Tj
--426 TJm
-(4) 5.97756 Tj
-98.4879 447.527 Td
-(or) 11.9551 Tj
--426 TJm
-(workFactor) 59.7756 Tj
--426 TJm
-(<) 5.97756 Tj
--426 TJm
-(0) 5.97756 Tj
--426 TJm
-(or) 11.9551 Tj
--426 TJm
-(workFactor) 59.7756 Tj
--426 TJm
-(>) 5.97756 Tj
--426 TJm
-(250) 17.9327 Tj
-90 435.572 Td
-(BZ_MEM_ERROR) 71.7307 Tj
-98.4879 423.617 Td
-(if) 11.9551 Tj
--426 TJm
-(not) 17.9327 Tj
--426 TJm
-(enough) 35.8654 Tj
--426 TJm
-(memory) 35.8654 Tj
--426 TJm
-(is) 11.9551 Tj
--426 TJm
-(available) 53.798 Tj
-90 411.661 Td
-(BZ_OK) 29.8878 Tj
-98.4879 399.706 Td
-(otherwise) 53.798 Tj
-[1 0 0 1 72 384.165] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 468 3.5866] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -468 -13.5482] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -374.203] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 362.248 Td
-/F130_0 9.9626 Tf
-(Allo) 17.7135 Tj
-25 TJm
-(w) 7.193 Tj
-10 TJm
-(able) 16.5977 Tj
--250 TJm
-(ne) 9.40469 Tj
-15 TJm
-(xt) 7.7509 Tj
--250 TJm
-(actions:) 30.9936 Tj
-[1 0 0 1 72 362.148] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -48.8169] cm
-/DeviceRGB {} cs
-[0.94899 0.94899 0.976456] sc
-/DeviceRGB {} CS
-[0.94899 0.94899 0.976456] SC
-0 0 468 47.8207 re
-f
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 3.5866] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 44.2341] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 18 -8.3686] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -90 -352.783] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-90 352.783 Td
-/F134_0 9.9626 Tf
-(BZ2_bzCompress) 83.6858 Tj
-98.4879 340.828 Td
-(if) 11.9551 Tj
--426 TJm
-(BZ_OK) 29.8878 Tj
--426 TJm
-(is) 11.9551 Tj
--426 TJm
-(returned) 47.8205 Tj
-98.4879 328.873 Td
-(no) 11.9551 Tj
--426 TJm
-(specific) 47.8205 Tj
--426 TJm
-(action) 35.8654 Tj
--426 TJm
-(needed) 35.8654 Tj
--426 TJm
-(in) 11.9551 Tj
--426 TJm
-(case) 23.9102 Tj
--426 TJm
-(of) 11.9551 Tj
--426 TJm
-(error) 29.8878 Tj
-[1 0 0 1 72 313.331] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 468 3.5866] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -468 -3.5866] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.9616] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -303.37] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 282.711 Td
-/F122_0 17.2154 Tf
-(3.3.2.) 43.0729 Tj
-[1 0 0 1 119.858 282.711] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -119.858 -282.711] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-119.858 282.711 Td
-/F392_0 17.2154 Tf
-(BZ2_bzCompress) 144.609 Tj
-[1 0 0 1 264.468 282.711] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -192.468 -2.3327] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -24.9066] cm
-/DeviceRGB {} cs
-[0.94899 0.94899 0.976456] sc
-/DeviceRGB {} CS
-[0.94899 0.94899 0.976456] SC
-0 0 468 23.9103 re
-f
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 3.5866] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 20.3237] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 18 -8.3685] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -90 -271.014] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-90 271.014 Td
-/F134_0 9.9626 Tf
-(int) 17.9327 Tj
--426 TJm
-(BZ2_bzCompress) 83.6858 Tj
--426 TJm
-(\() 5.97756 Tj
--426 TJm
-(bz_stream) 53.798 Tj
-268.371 269.27 Td
-(*) 5.97756 Tj
-274.348 271.014 Td
-(strm,) 29.8878 Tj
--426 TJm
-(int) 17.9327 Tj
--426 TJm
-(action) 35.8654 Tj
--426 TJm
-(\);) 11.9551 Tj
-[1 0 0 1 72 255.472] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 468 3.5866] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -468 -13.5482] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -245.51] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 233.555 Td
-/F130_0 9.9626 Tf
-(Pro) 13.8381 Tj
-15 TJm
-(vides) 21.031 Tj
--222 TJm
-(more) 20.4731 Tj
--221 TJm
-(input) 20.4831 Tj
--222 TJm
-(and/or) 25.4544 Tj
--222 TJm
-(output) 25.4644 Tj
--222 TJm
-(b) 4.9813 Tj
-20 TJm
-(uf) 8.29885 Tj
-25 TJm
-(fer) 11.0585 Tj
--221 TJm
-(space) 22.1269 Tj
--222 TJm
-(for) 11.6164 Tj
--222 TJm
-(the) 12.1743 Tj
--221 TJm
-(library) 26.5603 Tj
-65 TJm
-(.) 2.49065 Tj
--601 TJm
-(The) 15.4918 Tj
--222 TJm
-(caller) 22.1269 Tj
--222 TJm
-(maintains) 38.7446 Tj
--222 TJm
-(input) 20.4831 Tj
--221 TJm
-(and) 14.386 Tj
--222 TJm
-(output) 25.4644 Tj
--222 TJm
-(b) 4.9813 Tj
-20 TJm
-(uf) 8.29885 Tj
-25 TJm
-(fers,) 17.4246 Tj
--227 TJm
-(and) 14.386 Tj
--222 TJm
-(calls) 18.2614 Tj
-[1 0 0 1 72 221.6] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -221.6] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 221.6 Td
-/F134_0 9.9626 Tf
-(BZ2_bzCompress) 83.6858 Tj
-[1 0 0 1 155.686 221.6] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -155.686 -221.6] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-158.177 221.6 Td
-/F130_0 9.9626 Tf
-(to) 7.7509 Tj
--250 TJm
-(transfer) 30.4258 Tj
--250 TJm
-(data) 16.5977 Tj
--250 TJm
-(between) 33.1954 Tj
--250 TJm
-(them.) 22.4159 Tj
-[1 0 0 1 72 220.066] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.9617] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -210.104] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 199.683 Td
-/F130_0 9.9626 Tf
-(Before) 27.1082 Tj
--212 TJm
-(each) 18.2515 Tj
--213 TJm
-(call) 14.386 Tj
--212 TJm
-(to) 7.7509 Tj
-[1 0 0 1 147.961 199.683] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -147.961 -199.683] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-147.961 199.683 Td
-/F134_0 9.9626 Tf
-(BZ2_bzCompress) 83.6858 Tj
-[1 0 0 1 231.647 199.683] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -231.647 -199.683] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-231.647 199.683 Td
-/F130_0 9.9626 Tf
-(,) 2.49065 Tj
-[1 0 0 1 236.329 199.683] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -236.329 -199.683] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-236.329 199.683 Td
-/F134_0 9.9626 Tf
-(next_in) 41.8429 Tj
-[1 0 0 1 278.172 199.683] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -278.172 -199.683] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-280.288 199.683 Td
-/F130_0 9.9626 Tf
-(should) 26.5703 Tj
--212 TJm
-(point) 20.4831 Tj
--213 TJm
-(at) 7.193 Tj
--212 TJm
-(the) 12.1743 Tj
--213 TJm
-(data) 16.5977 Tj
--212 TJm
-(to) 7.7509 Tj
--212 TJm
-(be) 9.40469 Tj
--213 TJm
-(compressed,) 49.5241 Tj
--220 TJm
-(and) 14.386 Tj
-[1 0 0 1 463.493 199.683] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -463.493 -199.683] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-463.493 199.683 Td
-/F134_0 9.9626 Tf
-(avail_in) 47.8205 Tj
-[1 0 0 1 511.314 199.683] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -511.314 -199.683] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-513.43 199.683 Td
-/F130_0 9.9626 Tf
-(should) 26.5703 Tj
-72 187.728 Td
-(indicate) 31.5416 Tj
--246 TJm
-(ho) 9.9626 Tj
-25 TJm
-(w) 7.193 Tj
--247 TJm
-(m) 7.7509 Tj
-1 TJm
-(an) 9.40469 Tj
-14 TJm
-(y) 4.9813 Tj
--246 TJm
-(bytes) 21.031 Tj
--246 TJm
-(the) 12.1743 Tj
--246 TJm
-(library) 26.5603 Tj
--247 TJm
-(may) 17.1556 Tj
--246 TJm
-(read.) 19.6363 Tj
-[1 0 0 1 259.242 187.728] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -259.242 -187.728] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-259.242 187.728 Td
-/F134_0 9.9626 Tf
-(BZ2_bzCompress) 83.6858 Tj
-[1 0 0 1 342.929 187.728] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -342.929 -187.728] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-345.382 187.728 Td
-/F130_0 9.9626 Tf
-(updates) 30.4357 Tj
-[1 0 0 1 378.271 187.728] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -378.271 -187.728] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-378.271 187.728 Td
-/F134_0 9.9626 Tf
-(next_in) 41.8429 Tj
-[1 0 0 1 420.114 187.728] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -420.114 -187.728] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-420.114 187.728 Td
-/F130_0 9.9626 Tf
-(,) 2.49065 Tj
-[1 0 0 1 425.066 187.728] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -425.066 -187.728] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-425.066 187.728 Td
-/F134_0 9.9626 Tf
-(avail_in) 47.8205 Tj
-[1 0 0 1 472.886 187.728] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -472.886 -187.728] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-475.34 187.728 Td
-/F130_0 9.9626 Tf
-(and) 14.386 Tj
-[1 0 0 1 492.179 187.728] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -492.179 -187.728] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-492.179 187.728 Td
-/F134_0 9.9626 Tf
-(total_in) 47.8205 Tj
-[1 0 0 1 540 187.728] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -540 -187.728] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 175.773 Td
-/F130_0 9.9626 Tf
-(to) 7.7509 Tj
--250 TJm
-(re\003ect) 24.8965 Tj
--250 TJm
-(the) 12.1743 Tj
--250 TJm
-(number) 30.4357 Tj
--250 TJm
-(of) 8.29885 Tj
--250 TJm
-(bytes) 21.031 Tj
--250 TJm
-(it) 5.53921 Tj
--250 TJm
-(has) 13.2801 Tj
--250 TJm
-(read.) 19.6363 Tj
-[1 0 0 1 72 173.616] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.9616] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -163.654] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 153.856 Td
-/F130_0 9.9626 Tf
-(Similarly) 37.0908 Tj
-65 TJm
-(,) 2.49065 Tj
-[1 0 0 1 113.611 153.856] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -113.611 -153.856] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-113.611 153.856 Td
-/F134_0 9.9626 Tf
-(next_out) 47.8205 Tj
-[1 0 0 1 161.432 153.856] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -161.432 -153.856] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-164.072 153.856 Td
-/F130_0 9.9626 Tf
-(should) 26.5703 Tj
--265 TJm
-(point) 20.4831 Tj
--265 TJm
-(to) 7.7509 Tj
--265 TJm
-(a) 4.42339 Tj
--265 TJm
-(b) 4.9813 Tj
-20 TJm
-(uf) 8.29885 Tj
-25 TJm
-(fer) 11.0585 Tj
--265 TJm
-(in) 7.7509 Tj
--265 TJm
-(which) 24.3486 Tj
--265 TJm
-(the) 12.1743 Tj
--265 TJm
-(compressed) 47.0334 Tj
--265 TJm
-(data) 16.5977 Tj
--265 TJm
-(is) 6.64505 Tj
--265 TJm
-(to) 7.7509 Tj
--265 TJm
-(be) 9.40469 Tj
--265 TJm
-(placed,) 28.493 Tj
--269 TJm
-(with) 17.7135 Tj
-[1 0 0 1 464.742 153.856] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -464.742 -153.856] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-464.742 153.856 Td
-/F134_0 9.9626 Tf
-(avail_out) 53.798 Tj
-[1 0 0 1 518.54 153.856] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -518.54 -153.856] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-521.181 153.856 Td
-/F130_0 9.9626 Tf
-(indi-) 18.8194 Tj
-72 141.901 Td
-(cating) 24.3486 Tj
--209 TJm
-(ho) 9.9626 Tj
-25 TJm
-(w) 7.193 Tj
--209 TJm
-(much) 22.1369 Tj
--209 TJm
-(output) 25.4644 Tj
--209 TJm
-(space) 22.1269 Tj
--209 TJm
-(is) 6.64505 Tj
--210 TJm
-(a) 4.42339 Tj
-20 TJm
-(v) 4.9813 Tj
-25 TJm
-(ailable.) 29.0509 Tj
-[1 0 0 1 243.087 141.901] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -243.087 -141.901] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-243.087 141.901 Td
-/F134_0 9.9626 Tf
-(BZ2_bzCompress) 83.6858 Tj
-[1 0 0 1 326.773 141.901] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -326.773 -141.901] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-328.856 141.901 Td
-/F130_0 9.9626 Tf
-(updates) 30.4357 Tj
-[1 0 0 1 361.375 141.901] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -361.375 -141.901] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-361.375 141.901 Td
-/F134_0 9.9626 Tf
-(next_out) 47.8205 Tj
-[1 0 0 1 409.196 141.901] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -409.196 -141.901] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-409.196 141.901 Td
-/F130_0 9.9626 Tf
-(,) 2.49065 Tj
-[1 0 0 1 413.851 141.901] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -413.851 -141.901] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-413.851 141.901 Td
-/F134_0 9.9626 Tf
-(avail_out) 53.798 Tj
-[1 0 0 1 467.649 141.901] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -467.649 -141.901] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-469.732 141.901 Td
-/F130_0 9.9626 Tf
-(and) 14.386 Tj
-[1 0 0 1 486.202 141.901] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -486.202 -141.901] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-486.202 141.901 Td
-/F134_0 9.9626 Tf
-(total_out) 53.798 Tj
-[1 0 0 1 540 141.901] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -540 -141.901] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 129.946 Td
-/F130_0 9.9626 Tf
-(to) 7.7509 Tj
--250 TJm
-(re\003ect) 24.8965 Tj
--250 TJm
-(the) 12.1743 Tj
--250 TJm
-(number) 30.4357 Tj
--250 TJm
-(of) 8.29885 Tj
--250 TJm
-(bytes) 21.031 Tj
--250 TJm
-(output.) 27.9551 Tj
-[1 0 0 1 72 127.789] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.9617] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -117.827] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 108.029 Td
-/F130_0 9.9626 Tf
-(Y) 7.193 Tj
-110 TJm
-(ou) 9.9626 Tj
--272 TJm
-(may) 17.1556 Tj
--272 TJm
-(pro) 13.2801 Tj
-15 TJm
-(vide) 17.1556 Tj
--272 TJm
-(and) 14.386 Tj
--272 TJm
-(remo) 20.4731 Tj
-15 TJm
-(v) 4.9813 Tj
-15 TJm
-(e) 4.42339 Tj
--272 TJm
-(as) 8.29885 Tj
--272 TJm
-(little) 18.2714 Tj
--272 TJm
-(or) 8.29885 Tj
--272 TJm
-(as) 8.29885 Tj
--272 TJm
-(much) 22.1369 Tj
--271 TJm
-(data) 16.5977 Tj
--272 TJm
-(as) 8.29885 Tj
--272 TJm
-(you) 14.9439 Tj
--272 TJm
-(lik) 10.5205 Tj
-10 TJm
-(e) 4.42339 Tj
--272 TJm
-(on) 9.9626 Tj
--272 TJm
-(each) 18.2515 Tj
--272 TJm
-(call) 14.386 Tj
--272 TJm
-(of) 8.29885 Tj
-[1 0 0 1 399.123 108.029] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -399.123 -108.029] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-399.123 108.029 Td
-/F134_0 9.9626 Tf
-(BZ2_bzCompress) 83.6858 Tj
-[1 0 0 1 482.809 108.029] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -482.809 -108.029] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-482.809 108.029 Td
-/F130_0 9.9626 Tf
-(.) 2.49065 Tj
--752 TJm
-(In) 8.29885 Tj
--272 TJm
-(the) 12.1743 Tj
--272 TJm
-(limit,) 21.32 Tj
-72 96.0736 Td
-(it) 5.53921 Tj
--266 TJm
-(is) 6.64505 Tj
--265 TJm
-(acceptable) 42.0422 Tj
--266 TJm
-(to) 7.7509 Tj
--266 TJm
-(supply) 26.5703 Tj
--266 TJm
-(and) 14.386 Tj
--265 TJm
-(remo) 20.4731 Tj
-15 TJm
-(v) 4.9813 Tj
-15 TJm
-(e) 4.42339 Tj
--266 TJm
-(data) 16.5977 Tj
--266 TJm
-(one) 14.386 Tj
--265 TJm
-(byte) 17.1556 Tj
--266 TJm
-(at) 7.193 Tj
--266 TJm
-(a) 4.42339 Tj
--266 TJm
-(time,) 20.2042 Tj
--269 TJm
-(although) 34.8691 Tj
--266 TJm
-(this) 14.396 Tj
--266 TJm
-(w) 7.193 Tj
-10 TJm
-(ould) 17.7135 Tj
--265 TJm
-(be) 9.40469 Tj
--266 TJm
-(terribly) 29.3299 Tj
--266 TJm
-(inef) 15.4918 Tj
-25 TJm
-(\002cient.) 27.3972 Tj
--714 TJm
-(Y) 7.193 Tj
-110 TJm
-(ou) 9.9626 Tj
--266 TJm
-(should) 26.5703 Tj
-72 84.1184 Td
-(al) 7.193 Tj
-10 TJm
-(w) 7.193 Tj
-10 TJm
-(ays) 13.2801 Tj
--250 TJm
-(ensure) 26.0024 Tj
--250 TJm
-(that) 14.9439 Tj
--250 TJm
-(at) 7.193 Tj
--250 TJm
-(least) 18.2614 Tj
--250 TJm
-(one) 14.386 Tj
--250 TJm
-(byte) 17.1556 Tj
--250 TJm
-(of) 8.29885 Tj
--250 TJm
-(output) 25.4644 Tj
--250 TJm
-(space) 22.1269 Tj
--250 TJm
-(is) 6.64505 Tj
--250 TJm
-(a) 4.42339 Tj
-20 TJm
-(v) 4.9813 Tj
-25 TJm
-(ailable) 26.5603 Tj
--250 TJm
-(at) 7.193 Tj
--250 TJm
-(each) 18.2515 Tj
--250 TJm
-(call.) 16.8766 Tj
-[1 0 0 1 72 81.9616] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.9616] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -21.1482] cm
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-[1 0 0 1 1.8929 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 374.394 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 6.8541] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 40.5726 -6.7545] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -493.841 -50.9514] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-534.414 50.9514 Td
-/F130_0 9.9626 Tf
-(13) 9.9626 Tj
-[1 0 0 1 453.269 50.8518] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 93.5985 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 6.2765 0] cm
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-[1 0 0 1 -13.1436 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-Q
-showpage
-%%PageTrailer
-pdfEndPage
-%%Page: 17 17
-%%BeginPageSetup
-%%PageOrientation: Portrait
-pdfStartPage
-0 0 612 792 re W
-%%EndPageSetup
-[] 0 d
-1 i
-0 j
-0 J
-10 M
-1 w
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-false op
-false OP
-0 0 612 792 re
-W
-q
-[1 0 0 1 72 741.554] cm
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-[1 0 0 1 1.8929 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 14.4459] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 187.197 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 -8.9114] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 8.9114] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 76.4979 -6.7546] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -342.569 -749.245] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-419.067 749.245 Td
-/F130_0 9.9626 Tf
-(Programming) 54.7943 Tj
--250 TJm
-(with) 17.7135 Tj
-[1 0 0 1 496.556 749.245] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -496.556 -749.245] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-496.556 749.245 Td
-/F134_0 9.9626 Tf
-(libbzip2) 47.8205 Tj
-[1 0 0 1 544.376 749.245] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -278.305 -2.1568] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 280.796 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -472.974 -5.0363] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -0.4981] cm
-q
-[] 0 d
-0 J
-0.4981 w
-0 0.2491 m
-475.465 0.2491 l
-S
-Q
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 479.251 0] cm
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-[1 0 0 1 -13.1436 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -540 -741.554] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 710.037 Td
-/F130_0 9.9626 Tf
-(A) 7.193 Tj
--250 TJm
-(second) 27.6661 Tj
--250 TJm
-(purpose) 31.5416 Tj
--250 TJm
-(of) 8.29885 Tj
-[1 0 0 1 156.662 710.037] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -156.662 -710.037] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-156.662 710.037 Td
-/F134_0 9.9626 Tf
-(BZ2_bzCompress) 83.6858 Tj
-[1 0 0 1 240.348 710.037] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -240.348 -710.037] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-242.839 710.037 Td
-/F130_0 9.9626 Tf
-(is) 6.64505 Tj
--250 TJm
-(to) 7.7509 Tj
--250 TJm
-(request) 28.772 Tj
--250 TJm
-(a) 4.42339 Tj
--250 TJm
-(change) 28.2141 Tj
--250 TJm
-(of) 8.29885 Tj
--250 TJm
-(mode) 22.1369 Tj
--250 TJm
-(of) 8.29885 Tj
--250 TJm
-(the) 12.1743 Tj
--250 TJm
-(compressed) 47.0334 Tj
--250 TJm
-(stream.) 29.0509 Tj
-[1 0 0 1 72 707.88] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.9626] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -697.918] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 688.12 Td
-/F130_0 9.9626 Tf
-(Conceptually) 53.1305 Tj
-65 TJm
-(,) 2.49065 Tj
--217 TJm
-(a) 4.42339 Tj
--210 TJm
-(compressed) 47.0334 Tj
--209 TJm
-(stream) 26.5603 Tj
--209 TJm
-(can) 13.8281 Tj
--209 TJm
-(be) 9.40469 Tj
--210 TJm
-(in) 7.7509 Tj
--209 TJm
-(one) 14.386 Tj
--209 TJm
-(of) 8.29885 Tj
--209 TJm
-(four) 16.5977 Tj
--210 TJm
-(states:) 24.9065 Tj
--289 TJm
-(IDLE,) 25.1755 Tj
--209 TJm
-(R) 6.64505 Tj
-40 TJm
-(UNNING,) 41.7732 Tj
--210 TJm
-(FLUSHING) 49.2551 Tj
--209 TJm
-(and) 14.386 Tj
--209 TJm
-(FINISHING.) 52.2937 Tj
--419 TJm
-(Be-) 14.386 Tj
-72 676.164 Td
-(fore) 16.0398 Tj
--264 TJm
-(initialisation) 49.823 Tj
--263 TJm
-(\() 3.31755 Tj
-[1 0 0 1 146.434 676.164] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -146.434 -676.164] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-146.434 676.164 Td
-/F134_0 9.9626 Tf
-(BZ2_bzCompressInit) 107.596 Tj
-[1 0 0 1 254.031 676.164] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -254.031 -676.164] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-254.031 676.164 Td
-/F130_0 9.9626 Tf
-(\)) 3.31755 Tj
--264 TJm
-(and) 14.386 Tj
--263 TJm
-(after) 18.2515 Tj
--264 TJm
-(termination) 45.9375 Tj
--264 TJm
-(\() 3.31755 Tj
-[1 0 0 1 349.75 676.164] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -349.75 -676.164] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-349.75 676.164 Td
-/F134_0 9.9626 Tf
-(BZ2_bzCompressEnd) 101.619 Tj
-[1 0 0 1 451.369 676.164] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -451.369 -676.164] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-451.369 676.164 Td
-/F130_0 9.9626 Tf
-(\),) 5.8082 Tj
--267 TJm
-(a) 4.42339 Tj
--264 TJm
-(stream) 26.5603 Tj
--264 TJm
-(is) 6.64505 Tj
--263 TJm
-(re) 7.74094 Tj
-15 TJm
-(g) 4.9813 Tj
-5 TJm
-(arded) 22.1269 Tj
-72 664.209 Td
-(as) 8.29885 Tj
--250 TJm
-(IDLE.) 25.1755 Tj
-[1 0 0 1 72 664.11] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.9627] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -654.147] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 642.291 Td
-/F130_0 9.9626 Tf
-(Upon) 22.1369 Tj
--389 TJm
-(initialisation) 49.823 Tj
--390 TJm
-(\() 3.31755 Tj
-[1 0 0 1 155.036 642.291] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -155.036 -642.291] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-155.036 642.291 Td
-/F134_0 9.9626 Tf
-(BZ2_bzCompressInit) 107.596 Tj
-[1 0 0 1 262.632 642.291] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -262.632 -642.291] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-262.632 642.291 Td
-/F130_0 9.9626 Tf
-(\),) 5.8082 Tj
--424 TJm
-(the) 12.1743 Tj
--390 TJm
-(stream) 26.5603 Tj
--389 TJm
-(is) 6.64505 Tj
--389 TJm
-(placed) 26.0024 Tj
--390 TJm
-(in) 7.7509 Tj
--389 TJm
-(the) 12.1743 Tj
--390 TJm
-(R) 6.64505 Tj
-40 TJm
-(UNNING) 39.2825 Tj
--389 TJm
-(state.) 20.7521 Tj
--1457 TJm
-(Subsequent) 45.9375 Tj
--389 TJm
-(calls) 18.2614 Tj
-72 630.336 Td
-(to) 7.7509 Tj
-[1 0 0 1 83.818 630.336] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -83.818 -630.336] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-83.818 630.336 Td
-/F134_0 9.9626 Tf
-(BZ2_bzCompress) 83.6858 Tj
-[1 0 0 1 167.504 630.336] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -167.504 -630.336] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-171.571 630.336 Td
-/F130_0 9.9626 Tf
-(should) 26.5703 Tj
--408 TJm
-(pass) 17.1556 Tj
-[1 0 0 1 223.431 630.336] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -223.431 -630.336] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-223.431 630.336 Td
-/F134_0 9.9626 Tf
-(BZ_RUN) 35.8654 Tj
-[1 0 0 1 259.297 630.336] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -259.297 -630.336] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-263.363 630.336 Td
-/F130_0 9.9626 Tf
-(as) 8.29885 Tj
--408 TJm
-(the) 12.1743 Tj
--408 TJm
-(requested) 38.1767 Tj
--409 TJm
-(action;) 27.1182 Tj
--487 TJm
-(other) 20.4731 Tj
--408 TJm
-(actions) 28.224 Tj
--408 TJm
-(are) 12.1643 Tj
--409 TJm
-(ille) 12.7322 Tj
-15 TJm
-(g) 4.9813 Tj
-5 TJm
-(al) 7.193 Tj
--408 TJm
-(and) 14.386 Tj
--408 TJm
-(will) 15.5018 Tj
--408 TJm
-(result) 22.1369 Tj
--409 TJm
-(in) 7.7509 Tj
-[1 0 0 1 72 618.381] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -618.381] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 618.381 Td
-/F134_0 9.9626 Tf
-(BZ_SEQUENCE_ERROR) 101.619 Tj
-[1 0 0 1 173.619 618.381] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -173.619 -618.381] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-173.619 618.381 Td
-/F130_0 9.9626 Tf
-(.) 2.49065 Tj
-[1 0 0 1 72 617.071] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.9626] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -607.108] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 596.463 Td
-/F130_0 9.9626 Tf
-(At) 9.9626 Tj
--279 TJm
-(some) 21.031 Tj
--279 TJm
-(point,) 22.9738 Tj
--286 TJm
-(the) 12.1743 Tj
--279 TJm
-(calling) 27.1182 Tj
--279 TJm
-(program) 33.7533 Tj
--279 TJm
-(will) 15.5018 Tj
--279 TJm
-(ha) 9.40469 Tj
-20 TJm
-(v) 4.9813 Tj
-15 TJm
-(e) 4.42339 Tj
--278 TJm
-(pro) 13.2801 Tj
-14 TJm
-(vi) 7.7509 Tj
-1 TJm
-(ded) 14.386 Tj
--279 TJm
-(all) 9.9626 Tj
--279 TJm
-(the) 12.1743 Tj
--279 TJm
-(input) 20.4831 Tj
--279 TJm
-(data) 16.5977 Tj
--279 TJm
-(it) 5.53921 Tj
--279 TJm
-(w) 7.193 Tj
-10 TJm
-(ants) 16.0497 Tj
--279 TJm
-(to.) 10.2416 Tj
--793 TJm
-(It) 6.08715 Tj
--279 TJm
-(will) 15.5018 Tj
--279 TJm
-(then) 17.1556 Tj
--279 TJm
-(w) 7.193 Tj
-10 TJm
-(ant) 12.1743 Tj
--279 TJm
-(to) 7.7509 Tj
--279 TJm
-(\002nish) 22.1469 Tj
--279 TJm
-(up) 9.9626 Tj
--279 TJm
-(--) 6.63509 Tj
-72 584.508 Td
-(in) 7.7509 Tj
--287 TJm
-(ef) 7.74094 Tj
-25 TJm
-(fect,) 17.4246 Tj
--297 TJm
-(asking) 26.0123 Tj
--288 TJm
-(the) 12.1743 Tj
--287 TJm
-(library) 26.5603 Tj
--287 TJm
-(to) 7.7509 Tj
--288 TJm
-(process) 29.8778 Tj
--287 TJm
-(an) 9.40469 Tj
-15 TJm
-(y) 4.9813 Tj
--288 TJm
-(data) 16.5977 Tj
--287 TJm
-(it) 5.53921 Tj
--287 TJm
-(might) 23.2527 Tj
--288 TJm
-(ha) 9.40469 Tj
-20 TJm
-(v) 4.9813 Tj
-15 TJm
-(e) 4.42339 Tj
--287 TJm
-(b) 4.9813 Tj
-20 TJm
-(uf) 8.29885 Tj
-25 TJm
-(fered) 20.4632 Tj
--288 TJm
-(internally) 38.1866 Tj
-65 TJm
-(.) 2.49065 Tj
--844 TJm
-(In) 8.29885 Tj
--288 TJm
-(this) 14.396 Tj
--287 TJm
-(state,) 20.7521 Tj
-[1 0 0 1 456.314 584.508] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -456.314 -584.508] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-456.314 584.508 Td
-/F134_0 9.9626 Tf
-(BZ2_bzCompress) 83.6858 Tj
-[1 0 0 1 540 584.508] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -540 -584.508] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 572.553 Td
-/F130_0 9.9626 Tf
-(will) 15.5018 Tj
--258 TJm
-(no) 9.9626 Tj
--257 TJm
-(longer) 25.4544 Tj
--258 TJm
-(attempt) 29.8878 Tj
--258 TJm
-(to) 7.7509 Tj
--258 TJm
-(read) 17.1456 Tj
--257 TJm
-(data) 16.5977 Tj
--258 TJm
-(from) 19.3673 Tj
-[1 0 0 1 234.207 572.553] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -234.207 -572.553] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-234.207 572.553 Td
-/F134_0 9.9626 Tf
-(next_in) 41.8429 Tj
-[1 0 0 1 276.051 572.553] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -276.051 -572.553] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-276.051 572.553 Td
-/F130_0 9.9626 Tf
-(,) 2.49065 Tj
--260 TJm
-(b) 4.9813 Tj
-20 TJm
-(ut) 7.7509 Tj
--257 TJm
-(it) 5.53921 Tj
--258 TJm
-(will) 15.5018 Tj
--258 TJm
-(w) 7.193 Tj
-10 TJm
-(ant) 12.1743 Tj
--257 TJm
-(to) 7.7509 Tj
--258 TJm
-(write) 20.4731 Tj
--258 TJm
-(data) 16.5977 Tj
--258 TJm
-(to) 7.7509 Tj
-[1 0 0 1 407.082 572.553] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -407.082 -572.553] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-407.082 572.553 Td
-/F134_0 9.9626 Tf
-(next_out) 47.8205 Tj
-[1 0 0 1 454.902 572.553] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -454.902 -572.553] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-454.902 572.553 Td
-/F130_0 9.9626 Tf
-(.) 2.49065 Tj
--666 TJm
-(Because) 33.1954 Tj
--258 TJm
-(the) 12.1743 Tj
--258 TJm
-(output) 25.4644 Tj
-72 560.598 Td
-(b) 4.9813 Tj
-20 TJm
-(uf) 8.29885 Tj
-25 TJm
-(fer) 11.0585 Tj
--228 TJm
-(supplied) 33.7633 Tj
--228 TJm
-(by) 9.9626 Tj
--229 TJm
-(the) 12.1743 Tj
--228 TJm
-(user) 16.5977 Tj
--228 TJm
-(can) 13.8281 Tj
--228 TJm
-(be) 9.40469 Tj
--228 TJm
-(arbitrarily) 39.8404 Tj
--229 TJm
-(sma) 16.0497 Tj
-1 TJm
-(ll,) 8.02986 Tj
--233 TJm
-(the) 12.1743 Tj
--228 TJm
-(\002nishing-up) 48.1592 Tj
--228 TJm
-(operation) 37.6287 Tj
--229 TJm
-(cannot) 26.5603 Tj
--228 TJm
-(necessarily) 44.2638 Tj
--228 TJm
-(be) 9.40469 Tj
--228 TJm
-(done) 19.3673 Tj
--228 TJm
-(with) 17.7135 Tj
--229 TJm
-(a) 4.42339 Tj
--228 TJm
-(single) 23.8007 Tj
-72 548.643 Td
-(call) 14.386 Tj
--250 TJm
-(of) 8.29885 Tj
-[1 0 0 1 99.6659 548.643] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -99.6659 -548.643] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-99.6659 548.643 Td
-/F134_0 9.9626 Tf
-(BZ2_bzCompress) 83.6858 Tj
-[1 0 0 1 183.352 548.643] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -183.352 -548.643] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-183.352 548.643 Td
-/F130_0 9.9626 Tf
-(.) 2.49065 Tj
-[1 0 0 1 72 547.108] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.9626] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -537.146] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 526.725 Td
-/F130_0 9.9626 Tf
-(Instead,) 31.2626 Tj
--346 TJm
-(the) 12.1743 Tj
--327 TJm
-(calling) 27.1182 Tj
--326 TJm
-(program) 33.7533 Tj
--327 TJm
-(passes) 25.4544 Tj
-[1 0 0 1 218.231 526.725] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -218.231 -526.725] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-218.231 526.725 Td
-/F134_0 9.9626 Tf
-(BZ_FINISH) 53.798 Tj
-[1 0 0 1 272.029 526.725] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -272.029 -526.725] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-275.284 526.725 Td
-/F130_0 9.9626 Tf
-(as) 8.29885 Tj
--327 TJm
-(an) 9.40469 Tj
--327 TJm
-(action) 24.3486 Tj
--326 TJm
-(to) 7.7509 Tj
-[1 0 0 1 338.108 526.725] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -338.108 -526.725] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-338.108 526.725 Td
-/F134_0 9.9626 Tf
-(BZ2_bzCompress) 83.6858 Tj
-[1 0 0 1 421.795 526.725] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -421.795 -526.725] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-421.795 526.725 Td
-/F130_0 9.9626 Tf
-(.) 2.49065 Tj
--1081 TJm
-(This) 17.7135 Tj
--326 TJm
-(changes) 32.0895 Tj
--327 TJm
-(the) 12.1743 Tj
--327 TJm
-(stream') 29.8778 Tj
-55 TJm
-(s) 3.87545 Tj
-72 514.77 Td
-(state) 18.2614 Tj
--291 TJm
-(to) 7.7509 Tj
--290 TJm
-(FINISHING.) 52.2937 Tj
--581 TJm
-(An) 12.1743 Tj
-15 TJm
-(y) 4.9813 Tj
--291 TJm
-(remaining) 40.3983 Tj
--290 TJm
-(input) 20.4831 Tj
--291 TJm
-(\(ie,) 13.0012 Tj
-[1 0 0 1 264.452 514.77] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -264.452 -514.77] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-264.452 514.77 Td
-/F134_0 9.9626 Tf
-(next_in[0) 53.798 Tj
--600 TJm
-(..) 11.9551 Tj
--1200 TJm
-(avail_in-1]) 65.7532 Tj
-[1 0 0 1 413.892 514.77] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -413.892 -514.77] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-413.892 514.77 Td
-/F130_0 9.9626 Tf
-(\)) 3.31755 Tj
--291 TJm
-(is) 6.64505 Tj
--290 TJm
-(compressed) 47.0334 Tj
--291 TJm
-(and) 14.386 Tj
--290 TJm
-(transferred) 43.148 Tj
-72 502.814 Td
-(to) 7.7509 Tj
--421 TJm
-(the) 12.1743 Tj
--421 TJm
-(output) 25.4644 Tj
--421 TJm
-(b) 4.9813 Tj
-20 TJm
-(uf) 8.29885 Tj
-25 TJm
-(fer) 11.0585 Tj
-55 TJm
-(.) 2.49065 Tj
--1646 TJm
-(T) 6.08715 Tj
-80 TJm
-(o) 4.9813 Tj
--421 TJm
-(do) 9.9626 Tj
--422 TJm
-(this) 14.396 Tj
-1 TJm
-(,) 2.49065 Tj
-[1 0 0 1 222.339 502.814] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -222.339 -502.814] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-222.339 502.814 Td
-/F134_0 9.9626 Tf
-(BZ2_bzCompress) 83.6858 Tj
-[1 0 0 1 306.025 502.814] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -306.025 -502.814] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-310.22 502.814 Td
-/F130_0 9.9626 Tf
-(must) 19.3773 Tj
--421 TJm
-(be) 9.40469 Tj
--421 TJm
-(called) 23.7907 Tj
--421 TJm
-(repeatedly) 41.4942 Tj
--421 TJm
-(until) 18.2714 Tj
--421 TJm
-(all) 9.9626 Tj
--421 TJm
-(the) 12.1743 Tj
--421 TJm
-(output) 25.4644 Tj
--421 TJm
-(has) 13.2801 Tj
--421 TJm
-(been) 18.8094 Tj
-72 490.859 Td
-(consumed.) 42.889 Tj
--1397 TJm
-(At) 9.9626 Tj
--379 TJm
-(that) 14.9439 Tj
--380 TJm
-(point,) 22.9738 Tj
-[1 0 0 1 188.346 490.859] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -188.346 -490.859] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-188.346 490.859 Td
-/F134_0 9.9626 Tf
-(BZ2_bzCompress) 83.6858 Tj
-[1 0 0 1 272.033 490.859] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -272.033 -490.859] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-275.813 490.859 Td
-/F130_0 9.9626 Tf
-(returns) 27.6661 Tj
-[1 0 0 1 307.259 490.859] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -307.259 -490.859] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-307.259 490.859 Td
-/F134_0 9.9626 Tf
-(BZ_STREAM_END) 77.7083 Tj
-[1 0 0 1 384.968 490.859] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -384.968 -490.859] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-384.968 490.859 Td
-/F130_0 9.9626 Tf
-(,) 2.49065 Tj
--379 TJm
-(and) 14.386 Tj
--380 TJm
-(the) 12.1743 Tj
--379 TJm
-(stream') 29.8778 Tj
-55 TJm
-(s) 3.87545 Tj
--380 TJm
-(state) 18.2614 Tj
--379 TJm
-(is) 6.64505 Tj
--380 TJm
-(set) 11.0684 Tj
--379 TJm
-(back) 18.8094 Tj
--379 TJm
-(to) 7.7509 Tj
-72 478.904 Td
-(IDLE.) 25.1755 Tj
-[1 0 0 1 99.6662 478.904] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -99.6662 -478.904] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-99.6662 478.904 Td
-/F134_0 9.9626 Tf
-(BZ2_bzCompressEnd) 101.619 Tj
-[1 0 0 1 201.285 478.904] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -201.285 -478.904] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-203.776 478.904 Td
-/F130_0 9.9626 Tf
-(should) 26.5703 Tj
--250 TJm
-(then) 17.1556 Tj
--250 TJm
-(be) 9.40469 Tj
--250 TJm
-(called.) 26.2813 Tj
-[1 0 0 1 72 477.37] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.9626] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -467.407] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 456.986 Td
-/F130_0 9.9626 Tf
-(Just) 15.5018 Tj
--380 TJm
-(to) 7.7509 Tj
--380 TJm
-(mak) 17.1556 Tj
-10 TJm
-(e) 4.42339 Tj
--379 TJm
-(sure) 16.5977 Tj
--380 TJm
-(the) 12.1743 Tj
--380 TJm
-(calling) 27.1182 Tj
--380 TJm
-(program) 33.7533 Tj
--379 TJm
-(does) 18.2614 Tj
--380 TJm
-(not) 12.7322 Tj
--380 TJm
-(cheat,) 23.5117 Tj
--412 TJm
-(the) 12.1743 Tj
--380 TJm
-(library) 26.5603 Tj
--380 TJm
-(mak) 17.1556 Tj
-10 TJm
-(es) 8.29885 Tj
--379 TJm
-(a) 4.42339 Tj
--380 TJm
-(note) 17.1556 Tj
--380 TJm
-(of) 8.29885 Tj
-[1 0 0 1 415.708 456.986] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -415.708 -456.986] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-415.708 456.986 Td
-/F134_0 9.9626 Tf
-(avail_in) 47.8205 Tj
-[1 0 0 1 463.528 456.986] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -463.528 -456.986] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-467.312 456.986 Td
-/F130_0 9.9626 Tf
-(at) 7.193 Tj
--380 TJm
-(the) 12.1743 Tj
--380 TJm
-(time) 17.7135 Tj
--379 TJm
-(of) 8.29885 Tj
--380 TJm
-(the) 12.1743 Tj
-72 445.031 Td
-(\002rst) 15.5018 Tj
--286 TJm
-(call) 14.386 Tj
--286 TJm
-(t) 2.7696 Tj
-1 TJm
-(o) 4.9813 Tj
-[1 0 0 1 118.179 445.031] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -118.179 -445.031] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-118.179 445.031 Td
-/F134_0 9.9626 Tf
-(BZ2_bzCompress) 83.6858 Tj
-[1 0 0 1 201.865 445.031] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -201.865 -445.031] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-204.713 445.031 Td
-/F130_0 9.9626 Tf
-(which) 24.3486 Tj
--286 TJm
-(has) 13.2801 Tj
-[1 0 0 1 248.035 445.031] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -248.035 -445.031] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-248.035 445.031 Td
-/F134_0 9.9626 Tf
-(BZ_FINISH) 53.798 Tj
-[1 0 0 1 301.833 445.031] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -301.833 -445.031] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-304.68 445.031 Td
-/F130_0 9.9626 Tf
-(as) 8.29885 Tj
--286 TJm
-(an) 9.40469 Tj
--286 TJm
-(action) 24.3486 Tj
--285 TJm
-(\(ie,) 13.0012 Tj
--295 TJm
-(at) 7.193 Tj
--286 TJm
-(the) 12.1743 Tj
--286 TJm
-(time) 17.7135 Tj
--285 TJm
-(the) 12.1743 Tj
--286 TJm
-(program) 33.7533 Tj
--286 TJm
-(has) 13.2801 Tj
--286 TJm
-(announced) 43.158 Tj
--285 TJm
-(its) 9.41466 Tj
-72 433.076 Td
-(intention) 35.427 Tj
--292 TJm
-(to) 7.7509 Tj
--292 TJm
-(not) 12.7322 Tj
--291 TJm
-(supply) 26.5703 Tj
--292 TJm
-(an) 9.40469 Tj
-15 TJm
-(y) 4.9813 Tj
--292 TJm
-(more) 20.4731 Tj
--292 TJm
-(input\).) 26.2913 Tj
--870 TJm
-(By) 11.6264 Tj
--292 TJm
-(comparing) 42.61 Tj
--292 TJm
-(this) 14.396 Tj
--292 TJm
-(v) 4.9813 Tj
-25 TJm
-(alue) 16.5977 Tj
--291 TJm
-(with) 17.7135 Tj
--292 TJm
-(that) 14.9439 Tj
--292 TJm
-(of) 8.29885 Tj
-[1 0 0 1 392.862 433.076] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -392.862 -433.076] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-392.862 433.076 Td
-/F134_0 9.9626 Tf
-(avail_in) 47.8205 Tj
-[1 0 0 1 440.682 433.076] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -440.682 -433.076] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-443.589 433.076 Td
-/F130_0 9.9626 Tf
-(o) 4.9813 Tj
-15 TJm
-(v) 4.9813 Tj
-15 TJm
-(er) 7.74094 Tj
--292 TJm
-(subsequent) 44.2738 Tj
--292 TJm
-(calls) 18.2614 Tj
--291 TJm
-(to) 7.7509 Tj
-[1 0 0 1 72 421.121] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -421.121] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 421.121 Td
-/F134_0 9.9626 Tf
-(BZ2_bzCompress) 83.6858 Tj
-[1 0 0 1 155.686 421.121] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -155.686 -421.121] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-155.686 421.121 Td
-/F130_0 9.9626 Tf
-(,) 2.49065 Tj
--247 TJm
-(the) 12.1743 Tj
--247 TJm
-(library) 26.5603 Tj
--246 TJm
-(can) 13.8281 Tj
--247 TJm
-(detect) 23.7907 Tj
--246 TJm
-(an) 9.40469 Tj
-15 TJm
-(y) 4.9813 Tj
--247 TJm
-(att) 9.9626 Tj
-1 TJm
-(empts) 23.8007 Tj
--247 TJm
-(to) 7.7509 Tj
--246 TJm
-(slip) 14.396 Tj
--247 TJm
-(in) 7.7509 Tj
--246 TJm
-(more) 20.4731 Tj
--247 TJm
-(data) 16.5977 Tj
--246 TJm
-(to) 7.7509 Tj
--247 TJm
-(compress.) 40.1194 Tj
--617 TJm
-(An) 12.1743 Tj
-15 TJm
-(y) 4.9813 Tj
--247 TJm
-(calls) 18.2614 Tj
--246 TJm
-(for) 11.6164 Tj
--247 TJm
-(which) 24.3486 Tj
--246 TJm
-(this) 14.396 Tj
--247 TJm
-(is) 6.64505 Tj
-72 409.166 Td
-(detected) 33.1954 Tj
--250 TJm
-(will) 15.5018 Tj
--250 TJm
-(return) 23.7907 Tj
-[1 0 0 1 151.959 409.166] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -151.959 -409.166] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-151.959 409.166 Td
-/F134_0 9.9626 Tf
-(BZ_SEQUENCE_ERROR) 101.619 Tj
-[1 0 0 1 253.578 409.166] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -253.578 -409.166] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-253.578 409.166 Td
-/F130_0 9.9626 Tf
-(.) 2.49065 Tj
--500 TJm
-(This) 17.7135 Tj
--250 TJm
-(indicates) 35.417 Tj
--250 TJm
-(a) 4.42339 Tj
--250 TJm
-(programming) 54.2364 Tj
--250 TJm
-(mistak) 26.5703 Tj
-10 TJm
-(e) 4.42339 Tj
--250 TJm
-(which) 24.3486 Tj
--250 TJm
-(should) 26.5703 Tj
--250 TJm
-(be) 9.40469 Tj
--250 TJm
-(corrected.) 39.5515 Tj
-[1 0 0 1 72 407.009] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.9627] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -397.046] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 387.248 Td
-/F130_0 9.9626 Tf
-(Instead) 28.772 Tj
--224 TJm
-(of) 8.29885 Tj
--223 TJm
-(asking) 26.0123 Tj
--224 TJm
-(to) 7.7509 Tj
--223 TJm
-(\002nish,) 24.6375 Tj
--229 TJm
-(the) 12.1743 Tj
--224 TJm
-(calling) 27.1182 Tj
--223 TJm
-(program) 33.7533 Tj
--224 TJm
-(may) 17.1556 Tj
--224 TJm
-(ask) 13.2801 Tj
-[1 0 0 1 293.282 387.248] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -293.282 -387.248] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-293.282 387.248 Td
-/F134_0 9.9626 Tf
-(BZ2_bzCompress) 83.6858 Tj
-[1 0 0 1 376.968 387.248] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -376.968 -387.248] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-379.196 387.248 Td
-/F130_0 9.9626 Tf
-(to) 7.7509 Tj
--224 TJm
-(tak) 12.1743 Tj
-10 TJm
-(e) 4.42339 Tj
--223 TJm
-(all) 9.9626 Tj
--224 TJm
-(the) 12.1743 Tj
--223 TJm
-(remaining) 40.3983 Tj
--224 TJm
-(input,) 22.9738 Tj
--229 TJm
-(compress) 37.6287 Tj
-72 375.293 Td
-(it) 5.53921 Tj
--278 TJm
-(and) 14.386 Tj
--278 TJm
-(terminate) 37.6287 Tj
--278 TJm
-(the) 12.1743 Tj
--278 TJm
-(current) 28.2141 Tj
--277 TJm
-(\(Burro) 26.5603 Tj
-25 TJm
-(ws-Wheeler\)) 51.4469 Tj
--278 TJm
-(compression) 50.3609 Tj
--278 TJm
-(block.) 24.6275 Tj
--787 TJm
-(Th) 11.0684 Tj
--1 TJm
-(i) 2.7696 Tj
-1 TJm
-(s) 3.87545 Tj
--278 TJm
-(could) 22.1369 Tj
--278 TJm
-(be) 9.40469 Tj
--278 TJm
-(useful) 24.3486 Tj
--278 TJm
-(for) 11.6164 Tj
--278 TJm
-(error) 19.3573 Tj
--278 TJm
-(control) 28.224 Tj
--278 TJm
-(purposes.) 37.9077 Tj
-72 363.338 Td
-(The) 15.4918 Tj
--328 TJm
-(mechanism) 45.3796 Tj
--328 TJm
-(is) 6.64505 Tj
--328 TJm
-(analogous) 40.3983 Tj
--328 TJm
-(to) 7.7509 Tj
--328 TJm
-(that) 14.9439 Tj
--328 TJm
-(for) 11.6164 Tj
--328 TJm
-(\002nishing:) 37.6487 Tj
--466 TJm
-(call) 14.386 Tj
-[1 0 0 1 297.049 363.337] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -297.049 -363.337] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-297.049 363.337 Td
-/F134_0 9.9626 Tf
-(BZ2_bzCompress) 83.6858 Tj
-[1 0 0 1 380.735 363.337] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -380.735 -363.337] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-384.003 363.337 Td
-/F130_0 9.9626 Tf
-(with) 17.7135 Tj
--328 TJm
-(an) 9.40469 Tj
--328 TJm
-(action) 24.3486 Tj
--328 TJm
-(of) 8.29885 Tj
-[1 0 0 1 456.841 363.337] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -456.841 -363.337] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-456.841 363.337 Td
-/F134_0 9.9626 Tf
-(BZ_FLUSH) 47.8205 Tj
-[1 0 0 1 504.662 363.337] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -504.662 -363.337] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-504.662 363.337 Td
-/F130_0 9.9626 Tf
-(,) 2.49065 Tj
--328 TJm
-(remo) 20.4731 Tj
-15 TJm
-(v) 4.9813 Tj
-15 TJm
-(e) 4.42339 Tj
-72 351.382 Td
-(output) 25.4644 Tj
--445 TJm
-(data,) 19.0883 Tj
--494 TJm
-(and) 14.386 Tj
--446 TJm
-(persist) 26.0123 Tj
--445 TJm
-(with) 17.7135 Tj
--445 TJm
-(the) 12.1743 Tj
-[1 0 0 1 213.94 351.382] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -213.94 -351.382] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-213.94 351.382 Td
-/F134_0 9.9626 Tf
-(BZ_FLUSH) 47.8205 Tj
-[1 0 0 1 261.761 351.382] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -261.761 -351.382] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-266.195 351.382 Td
-/F130_0 9.9626 Tf
-(action) 24.3486 Tj
--445 TJm
-(until) 18.2714 Tj
--445 TJm
-(the) 12.1743 Tj
--446 TJm
-(v) 4.9813 Tj
-25 TJm
-(alue) 16.5977 Tj
-[1 0 0 1 360.062 351.382] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -360.062 -351.382] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-360.062 351.382 Td
-/F134_0 9.9626 Tf
-(BZ_RUN) 35.8654 Tj
-[1 0 0 1 395.928 351.382] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -395.928 -351.382] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-400.362 351.382 Td
-/F130_0 9.9626 Tf
-(is) 6.64505 Tj
--445 TJm
-(returned.) 35.686 Tj
--1792 TJm
-(As) 11.0684 Tj
--445 TJm
-(with) 17.7135 Tj
--445 TJm
-(\002nishing,) 37.3697 Tj
-[1 0 0 1 72 339.427] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -339.427] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 339.427 Td
-/F134_0 9.9626 Tf
-(BZ2_bzCompress) 83.6858 Tj
-[1 0 0 1 155.686 339.427] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -155.686 -339.427] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-158.177 339.427 Td
-/F130_0 9.9626 Tf
-(detects) 27.6661 Tj
--250 TJm
-(an) 9.40469 Tj
-15 TJm
-(y) 4.9813 Tj
--250 TJm
-(attempt) 29.8878 Tj
--250 TJm
-(to) 7.7509 Tj
--250 TJm
-(pro) 13.2801 Tj
-15 TJm
-(vide) 17.1556 Tj
--250 TJm
-(more) 20.4731 Tj
--250 TJm
-(input) 20.4831 Tj
--250 TJm
-(data) 16.5977 Tj
--250 TJm
-(once) 18.8094 Tj
--250 TJm
-(the) 12.1743 Tj
--250 TJm
-(\003ush) 19.3773 Tj
--250 TJm
-(has) 13.2801 Tj
--250 TJm
-(be) 9.40469 Tj
-15 TJm
-(gun.) 17.4346 Tj
-[1 0 0 1 72 337.27] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.9626] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -327.308] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 317.509 Td
-/F130_0 9.9626 Tf
-(Once) 21.0211 Tj
--250 TJm
-(the) 12.1743 Tj
--250 TJm
-(\003ush) 19.3773 Tj
--250 TJm
-(is) 6.64505 Tj
--250 TJm
-(complete,) 39.0135 Tj
--250 TJm
-(the) 12.1743 Tj
--250 TJm
-(stream) 26.5603 Tj
--250 TJm
-(returns) 27.6661 Tj
--250 TJm
-(to) 7.7509 Tj
--250 TJm
-(the) 12.1743 Tj
--250 TJm
-(normal) 28.224 Tj
--250 TJm
-(R) 6.64505 Tj
-40 TJm
-(UNNING) 39.2825 Tj
--250 TJm
-(state.) 20.7521 Tj
-[1 0 0 1 72 315.353] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.9626] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -305.39] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 295.591 Td
-/F130_0 9.9626 Tf
-(This) 17.7135 Tj
--344 TJm
-(all) 9.9626 Tj
--343 TJm
-(sounds) 27.6761 Tj
--344 TJm
-(pretty) 23.2427 Tj
--344 TJm
-(comple) 29.3299 Tj
-15 TJm
-(x,) 7.47195 Tj
--367 TJm
-(b) 4.9813 Tj
-20 TJm
-(ut) 7.7509 Tj
--344 TJm
-(isn') 14.9439 Tj
-18 TJm
-(t) 2.7696 Tj
--344 TJm
-(really) 22.6848 Tj
-65 TJm
-(.) 2.49065 Tj
--1182 TJm
-(Here') 22.6749 Tj
-55 TJm
-(s) 3.87545 Tj
--344 TJm
-(a) 4.42339 Tj
--344 TJm
-(table) 19.3673 Tj
--343 TJm
-(which) 24.3486 Tj
--344 TJm
-(sho) 13.8381 Tj
-25 TJm
-(ws) 11.0684 Tj
--344 TJm
-(which) 24.3486 Tj
--344 TJm
-(actions) 28.224 Tj
--343 TJm
-(are) 12.1643 Tj
--344 TJm
-(allo) 14.9439 Tj
-25 TJm
-(w) 7.193 Tj
-10 TJm
-(able) 16.5977 Tj
--344 TJm
-(in) 7.7509 Tj
--344 TJm
-(each) 18.2515 Tj
-72 283.636 Td
-(state,) 20.7521 Tj
--281 TJm
-(what) 19.3673 Tj
--274 TJm
-(action) 24.3486 Tj
--275 TJm
-(will) 15.5018 Tj
--274 TJm
-(be) 9.40469 Tj
--275 TJm
-(tak) 12.1743 Tj
-10 TJm
-(en,) 11.8953 Tj
--280 TJm
-(what) 19.3673 Tj
--275 TJm
-(the) 12.1743 Tj
--274 TJm
-(ne) 9.40469 Tj
-15 TJm
-(xt) 7.7509 Tj
--275 TJm
-(state) 18.2614 Tj
--274 TJm
-(is,) 9.1357 Tj
--281 TJm
-(and) 14.386 Tj
--274 TJm
-(what) 19.3673 Tj
--275 TJm
-(the) 12.1743 Tj
--275 TJm
-(non-error) 37.6188 Tj
--274 TJm
-(return) 23.7907 Tj
--275 TJm
-(v) 4.9813 Tj
-25 TJm
-(alues) 20.4731 Tj
--274 TJm
-(are.) 14.655 Tj
--767 TJm
-(Note) 19.3673 Tj
--275 TJm
-(that) 14.9439 Tj
--274 TJm
-(you) 14.9439 Tj
--275 TJm
-(can') 17.1456 Tj
-18 TJm
-(t) 2.7696 Tj
-72 271.681 Td
-(e) 4.42339 Tj
-15 TJm
-(xplicitly) 33.2153 Tj
--347 TJm
-(ask) 13.2801 Tj
--348 TJm
-(what) 19.3673 Tj
--347 TJm
-(state) 18.2614 Tj
--348 TJm
-(the) 12.1743 Tj
--347 TJm
-(stream) 26.5603 Tj
--348 TJm
-(is) 6.64505 Tj
--347 TJm
-(in,) 10.2416 Tj
--372 TJm
-(b) 4.9813 Tj
-20 TJm
-(ut) 7.7509 Tj
--347 TJm
-(nor) 13.2801 Tj
--348 TJm
-(do) 9.9626 Tj
--347 TJm
-(you) 14.9439 Tj
--348 TJm
-(need) 18.8094 Tj
--347 TJm
-(to) 7.7509 Tj
--348 TJm
-(--) 6.63509 Tj
--347 TJm
-(it) 5.53921 Tj
--348 TJm
-(can) 13.8281 Tj
--347 TJm
-(be) 9.40469 Tj
--347 TJm
-(inferred) 31.5316 Tj
--348 TJm
-(from) 19.3673 Tj
--347 TJm
-(the) 12.1743 Tj
--348 TJm
-(v) 4.9813 Tj
-25 TJm
-(alues) 20.4731 Tj
--347 TJm
-(returned) 33.1954 Tj
--348 TJm
-(by) 9.9626 Tj
-[1 0 0 1 72 259.726] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -259.726] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 259.726 Td
-/F134_0 9.9626 Tf
-(BZ2_bzCompress) 83.6858 Tj
-[1 0 0 1 155.686 259.726] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -155.686 -259.726] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-155.686 259.726 Td
-/F130_0 9.9626 Tf
-(.) 2.49065 Tj
-[1 0 0 1 72 258.192] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -207.34] cm
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-[1 0 0 1 1.8929 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 374.394 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 6.7546] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 40.5726 -6.7546] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -493.841 -50.8518] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-534.414 50.8518 Td
-/F130_0 9.9626 Tf
-(14) 9.9626 Tj
-[1 0 0 1 453.269 50.8518] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 93.5985 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 6.2765 0] cm
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-[1 0 0 1 -13.1436 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-Q
-showpage
-%%PageTrailer
-pdfEndPage
-%%Page: 18 18
-%%BeginPageSetup
-%%PageOrientation: Portrait
-pdfStartPage
-0 0 612 792 re W
-%%EndPageSetup
-[] 0 d
-1 i
-0 j
-0 J
-10 M
-1 w
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-false op
-false OP
-0 0 612 792 re
-W
-q
-[1 0 0 1 72 741.554] cm
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-[1 0 0 1 1.8929 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 14.4459] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 187.197 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 -8.9114] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 8.9114] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 76.4979 -6.7546] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -342.569 -749.245] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-419.067 749.245 Td
-/F130_0 9.9626 Tf
-(Programming) 54.7943 Tj
--250 TJm
-(with) 17.7135 Tj
-[1 0 0 1 496.556 749.245] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -496.556 -749.245] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-496.556 749.245 Td
-/F134_0 9.9626 Tf
-(libbzip2) 47.8205 Tj
-[1 0 0 1 544.376 749.245] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -278.305 -2.1568] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 280.796 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -472.974 -5.0363] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -0.4981] cm
-q
-[] 0 d
-0 J
-0.4981 w
-0 0.2491 m
-475.465 0.2491 l
-S
-Q
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 479.251 0] cm
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-[1 0 0 1 -13.1436 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -468 -595.402] cm
-/DeviceRGB {} cs
-[0.94899 0.94899 0.976456] sc
-/DeviceRGB {} CS
-[0.94899 0.94899 0.976456] SC
-0 0 468 573.848 re
-f
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 3.5866] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 570.261] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 18 -8.3686] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -90 -711.631] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-90 711.631 Td
-/F134_0 9.9626 Tf
-(IDLE/any) 47.8205 Tj
-98.4879 699.676 Td
-(Illegal.) 47.8205 Tj
--852 TJm
-(IDLE) 23.9102 Tj
--426 TJm
-(state) 29.8878 Tj
--426 TJm
-(only) 23.9102 Tj
--426 TJm
-(exists) 35.8654 Tj
--426 TJm
-(after) 29.8878 Tj
--426 TJm
-(BZ2_bzCompressEnd) 101.619 Tj
--426 TJm
-(or) 11.9551 Tj
-98.4879 687.721 Td
-(before) 35.8654 Tj
--426 TJm
-(BZ2_bzCompressInit.) 113.574 Tj
-98.4879 675.766 Td
-(Return) 35.8654 Tj
--426 TJm
-(value) 29.8878 Tj
--426 TJm
-(=) 5.97756 Tj
--426 TJm
-(BZ_SEQUENCE_ERROR) 101.619 Tj
-90 651.856 Td
-(RUNNING/BZ_RUN) 83.6858 Tj
-98.4879 639.9 Td
-(Compress) 47.8205 Tj
--426 TJm
-(from) 23.9102 Tj
--426 TJm
-(next_in) 41.8429 Tj
--426 TJm
-(to) 11.9551 Tj
--426 TJm
-(next_out) 47.8205 Tj
--426 TJm
-(as) 11.9551 Tj
--426 TJm
-(much) 23.9102 Tj
--426 TJm
-(as) 11.9551 Tj
--426 TJm
-(possible.) 53.798 Tj
-98.4879 627.945 Td
-(Next) 23.9102 Tj
--426 TJm
-(state) 29.8878 Tj
--426 TJm
-(=) 5.97756 Tj
--426 TJm
-(RUNNING) 41.8429 Tj
-98.4879 615.99 Td
-(Return) 35.8654 Tj
--426 TJm
-(value) 29.8878 Tj
--426 TJm
-(=) 5.97756 Tj
--426 TJm
-(BZ_RUN_OK) 53.798 Tj
-90 592.08 Td
-(RUNNING/BZ_FLUSH) 95.641 Tj
-98.4879 580.125 Td
-(Remember) 47.8205 Tj
--426 TJm
-(current) 41.8429 Tj
--426 TJm
-(value) 29.8878 Tj
--426 TJm
-(of) 11.9551 Tj
--426 TJm
-(next_in.) 47.8205 Tj
--426 TJm
-(Compress) 47.8205 Tj
--426 TJm
-(from) 23.9102 Tj
--426 TJm
-(next_in) 41.8429 Tj
-98.4879 568.169 Td
-(to) 11.9551 Tj
--426 TJm
-(next_out) 47.8205 Tj
--426 TJm
-(as) 11.9551 Tj
--426 TJm
-(much) 23.9102 Tj
--426 TJm
-(as) 11.9551 Tj
--426 TJm
-(possible,) 53.798 Tj
--426 TJm
-(but) 17.9327 Tj
--426 TJm
-(do) 11.9551 Tj
--426 TJm
-(not) 17.9327 Tj
--426 TJm
-(accept) 35.8654 Tj
--426 TJm
-(any) 17.9327 Tj
--426 TJm
-(more) 23.9102 Tj
--426 TJm
-(input.) 35.8654 Tj
-98.4879 556.214 Td
-(Next) 23.9102 Tj
--426 TJm
-(state) 29.8878 Tj
--426 TJm
-(=) 5.97756 Tj
--426 TJm
-(FLUSHING) 47.8205 Tj
-98.4879 544.259 Td
-(Return) 35.8654 Tj
--426 TJm
-(value) 29.8878 Tj
--426 TJm
-(=) 5.97756 Tj
--426 TJm
-(BZ_FLUSH_OK) 65.7532 Tj
-90 520.349 Td
-(RUNNING/BZ_FINISH) 101.619 Tj
-98.4879 508.394 Td
-(Remember) 47.8205 Tj
--426 TJm
-(current) 41.8429 Tj
--426 TJm
-(value) 29.8878 Tj
--426 TJm
-(of) 11.9551 Tj
--426 TJm
-(next_in.) 47.8205 Tj
--426 TJm
-(Compress) 47.8205 Tj
--426 TJm
-(from) 23.9102 Tj
--426 TJm
-(next_in) 41.8429 Tj
-98.4879 496.438 Td
-(to) 11.9551 Tj
--426 TJm
-(next_out) 47.8205 Tj
--426 TJm
-(as) 11.9551 Tj
--426 TJm
-(much) 23.9102 Tj
--426 TJm
-(as) 11.9551 Tj
--426 TJm
-(possible,) 53.798 Tj
--426 TJm
-(but) 17.9327 Tj
--426 TJm
-(do) 11.9551 Tj
--426 TJm
-(not) 17.9327 Tj
--426 TJm
-(accept) 35.8654 Tj
--426 TJm
-(any) 17.9327 Tj
--426 TJm
-(more) 23.9102 Tj
--426 TJm
-(input.) 35.8654 Tj
-98.4879 484.483 Td
-(Next) 23.9102 Tj
--426 TJm
-(state) 29.8878 Tj
--426 TJm
-(=) 5.97756 Tj
--426 TJm
-(FINISHING) 53.798 Tj
-98.4879 472.528 Td
-(Return) 35.8654 Tj
--426 TJm
-(value) 29.8878 Tj
--426 TJm
-(=) 5.97756 Tj
--426 TJm
-(BZ_FINISH_OK) 71.7307 Tj
-90 448.618 Td
-(FLUSHING/BZ_FLUSH) 101.619 Tj
-98.4879 436.663 Td
-(Compress) 47.8205 Tj
--426 TJm
-(from) 23.9102 Tj
--426 TJm
-(next_in) 41.8429 Tj
--426 TJm
-(to) 11.9551 Tj
--426 TJm
-(next_out) 47.8205 Tj
--426 TJm
-(as) 11.9551 Tj
--426 TJm
-(much) 23.9102 Tj
--426 TJm
-(as) 11.9551 Tj
--426 TJm
-(possible,) 53.798 Tj
-98.4879 424.707 Td
-(but) 17.9327 Tj
--426 TJm
-(do) 11.9551 Tj
--426 TJm
-(not) 17.9327 Tj
--426 TJm
-(accept) 35.8654 Tj
--426 TJm
-(any) 17.9327 Tj
--426 TJm
-(more) 23.9102 Tj
--426 TJm
-(input.) 35.8654 Tj
-98.4879 412.752 Td
-(If) 11.9551 Tj
--426 TJm
-(all) 17.9327 Tj
--426 TJm
-(the) 17.9327 Tj
--426 TJm
-(existing) 47.8205 Tj
--426 TJm
-(input) 29.8878 Tj
--426 TJm
-(has) 17.9327 Tj
--426 TJm
-(been) 23.9102 Tj
--426 TJm
-(used) 23.9102 Tj
--426 TJm
-(up) 11.9551 Tj
--426 TJm
-(and) 17.9327 Tj
--426 TJm
-(all) 17.9327 Tj
--426 TJm
-(compressed) 59.7756 Tj
-98.4879 400.797 Td
-(output) 35.8654 Tj
--426 TJm
-(has) 17.9327 Tj
--426 TJm
-(been) 23.9102 Tj
--426 TJm
-(removed) 41.8429 Tj
-106.976 388.842 Td
-(Next) 23.9102 Tj
--426 TJm
-(state) 29.8878 Tj
--426 TJm
-(=) 5.97756 Tj
--426 TJm
-(RUNNING;) 47.8205 Tj
--426 TJm
-(Return) 35.8654 Tj
--426 TJm
-(value) 29.8878 Tj
--426 TJm
-(=) 5.97756 Tj
--426 TJm
-(BZ_RUN_OK) 53.798 Tj
-98.4879 376.887 Td
-(else) 23.9102 Tj
-106.976 364.932 Td
-(Next) 23.9102 Tj
--426 TJm
-(state) 29.8878 Tj
--426 TJm
-(=) 5.97756 Tj
--426 TJm
-(FLUSHING;) 53.798 Tj
--426 TJm
-(Return) 35.8654 Tj
--426 TJm
-(value) 29.8878 Tj
--426 TJm
-(=) 5.97756 Tj
--426 TJm
-(BZ_FLUSH_OK) 65.7532 Tj
-90 341.021 Td
-(FLUSHING/other) 83.6858 Tj
-98.4879 329.066 Td
-(Illegal.) 47.8205 Tj
-98.4879 317.111 Td
-(Return) 35.8654 Tj
--426 TJm
-(value) 29.8878 Tj
--426 TJm
-(=) 5.97756 Tj
--426 TJm
-(BZ_SEQUENCE_ERROR) 101.619 Tj
-90 293.201 Td
-(FINISHING/BZ_FINISH) 113.574 Tj
-98.4879 281.245 Td
-(Compress) 47.8205 Tj
--426 TJm
-(from) 23.9102 Tj
--426 TJm
-(next_in) 41.8429 Tj
--426 TJm
-(to) 11.9551 Tj
--426 TJm
-(next_out) 47.8205 Tj
--426 TJm
-(as) 11.9551 Tj
--426 TJm
-(much) 23.9102 Tj
--426 TJm
-(as) 11.9551 Tj
--426 TJm
-(possible,) 53.798 Tj
-98.4879 269.29 Td
-(but) 17.9327 Tj
--426 TJm
-(to) 11.9551 Tj
--426 TJm
-(not) 17.9327 Tj
--426 TJm
-(accept) 35.8654 Tj
--426 TJm
-(any) 17.9327 Tj
--426 TJm
-(more) 23.9102 Tj
--426 TJm
-(input.) 35.8654 Tj
-98.4879 257.335 Td
-(If) 11.9551 Tj
--426 TJm
-(all) 17.9327 Tj
--426 TJm
-(the) 17.9327 Tj
--426 TJm
-(existing) 47.8205 Tj
--426 TJm
-(input) 29.8878 Tj
--426 TJm
-(has) 17.9327 Tj
--426 TJm
-(been) 23.9102 Tj
--426 TJm
-(used) 23.9102 Tj
--426 TJm
-(up) 11.9551 Tj
--426 TJm
-(and) 17.9327 Tj
--426 TJm
-(all) 17.9327 Tj
--426 TJm
-(compressed) 59.7756 Tj
-98.4879 245.38 Td
-(output) 35.8654 Tj
--426 TJm
-(has) 17.9327 Tj
--426 TJm
-(been) 23.9102 Tj
--426 TJm
-(removed) 41.8429 Tj
-106.976 233.425 Td
-(Next) 23.9102 Tj
--426 TJm
-(state) 29.8878 Tj
--426 TJm
-(=) 5.97756 Tj
--426 TJm
-(IDLE;) 29.8878 Tj
--426 TJm
-(Return) 35.8654 Tj
--426 TJm
-(value) 29.8878 Tj
--426 TJm
-(=) 5.97756 Tj
--426 TJm
-(BZ_STREAM_END) 77.7083 Tj
-98.4879 221.47 Td
-(else) 23.9102 Tj
-106.976 209.514 Td
-(Next) 23.9102 Tj
--426 TJm
-(state) 29.8878 Tj
--426 TJm
-(=) 5.97756 Tj
--426 TJm
-(FINISHING;) 59.7756 Tj
--426 TJm
-(Return) 35.8654 Tj
--426 TJm
-(value) 29.8878 Tj
--426 TJm
-(=) 5.97756 Tj
--426 TJm
-(BZ_FINISH_OK) 71.7307 Tj
-90 185.604 Td
-(FINISHING/other) 89.6634 Tj
-98.4879 173.649 Td
-(Illegal.) 47.8205 Tj
-98.4879 161.694 Td
-(Return) 35.8654 Tj
--426 TJm
-(value) 29.8878 Tj
--426 TJm
-(=) 5.97756 Tj
--426 TJm
-(BZ_SEQUENCE_ERROR) 101.619 Tj
-[1 0 0 1 72 146.152] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 468 3.5866] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -468 -13.5492] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -136.189] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 124.234 Td
-/F130_0 9.9626 Tf
-(That) 18.2614 Tj
--250 TJm
-(still) 14.9539 Tj
--250 TJm
-(looks) 21.589 Tj
--250 TJm
-(complicated?) 53.1206 Tj
--620 TJm
-(W) 9.40469 Tj
-80 TJm
-(ell,) 12.4533 Tj
--250 TJm
-(f) 3.31755 Tj
-10 TJm
-(air) 10.5105 Tj
--250 TJm
-(enough.) 31.8205 Tj
--620 TJm
-(The) 15.4918 Tj
--250 TJm
-(usual) 21.031 Tj
--250 TJm
-(sequence) 36.5129 Tj
--250 TJm
-(of) 8.29885 Tj
--250 TJm
-(calls) 18.2614 Tj
--250 TJm
-(for) 11.6164 Tj
--250 TJm
-(compressing) 50.3609 Tj
--250 TJm
-(a) 4.42339 Tj
--250 TJm
-(load) 17.1556 Tj
--250 TJm
-(of) 8.29885 Tj
--250 TJm
-(data) 16.5977 Tj
--250 TJm
-(is:) 9.41466 Tj
-[1 0 0 1 72 122.077] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -29.7236] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 7.3724 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -79.3724 -92.3537] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-79.3724 92.3537 Td
-/F130_0 9.9626 Tf
-(1.) 7.47195 Tj
-[1 0 0 1 86.8444 92.3537] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 3.0884 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 1.9925 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -91.9253 -92.3537] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-91.9253 92.3537 Td
-/F130_0 9.9626 Tf
-(Get) 14.386 Tj
--250 TJm
-(started) 26.5603 Tj
--250 TJm
-(with) 17.7135 Tj
-[1 0 0 1 158.056 92.3537] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -158.056 -92.3537] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-158.056 92.3537 Td
-/F134_0 9.9626 Tf
-(BZ2_bzCompressInit) 107.596 Tj
-[1 0 0 1 265.653 92.3537] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -265.653 -92.3537] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-265.653 92.3537 Td
-/F130_0 9.9626 Tf
-(.) 2.49065 Tj
-[1 0 0 1 268.144 92.3537] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -196.144 -41.5019] cm
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-[1 0 0 1 1.893 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4906 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 374.394 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 6.8542] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 40.5726 -6.7546] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -493.841 -50.9514] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-534.414 50.9514 Td
-/F130_0 9.9626 Tf
-(15) 9.9626 Tj
-[1 0 0 1 453.269 50.8518] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 93.5985 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 6.2765 0] cm
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-[1 0 0 1 -13.1436 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-Q
-showpage
-%%PageTrailer
-pdfEndPage
-%%Page: 19 19
-%%BeginPageSetup
-%%PageOrientation: Portrait
-pdfStartPage
-0 0 612 792 re W
-%%EndPageSetup
-[] 0 d
-1 i
-0 j
-0 J
-10 M
-1 w
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-false op
-false OP
-0 0 612 792 re
-W
-q
-[1 0 0 1 72 741.554] cm
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-[1 0 0 1 1.8929 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 14.4459] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 187.197 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 -8.9114] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 8.9114] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 76.4979 -6.7546] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -342.569 -749.245] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-419.067 749.245 Td
-/F130_0 9.9626 Tf
-(Programming) 54.7943 Tj
--250 TJm
-(with) 17.7135 Tj
-[1 0 0 1 496.556 749.245] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -496.556 -749.245] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-496.556 749.245 Td
-/F134_0 9.9626 Tf
-(libbzip2) 47.8205 Tj
-[1 0 0 1 544.376 749.245] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -278.305 -2.1568] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 280.796 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -472.974 -5.0363] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -0.4981] cm
-q
-[] 0 d
-0 J
-0.4981 w
-0 0.2491 m
-475.465 0.2491 l
-S
-Q
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 479.251 0] cm
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-[1 0 0 1 -13.1436 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -468 -31.5168] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 7.3724 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -79.3724 -710.037] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-79.3724 710.037 Td
-/F130_0 9.9626 Tf
-(2.) 7.47195 Tj
-[1 0 0 1 86.8444 710.037] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 3.0884 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 1.9925 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -91.9253 -710.037] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-91.9253 710.037 Td
-/F130_0 9.9626 Tf
-(Sho) 15.5018 Tj
-15 TJm
-(v) 4.9813 Tj
-15 TJm
-(el) 7.193 Tj
--240 TJm
-(data) 16.5977 Tj
--240 TJm
-(in) 7.7509 Tj
--241 TJm
-(and) 14.386 Tj
--240 TJm
-(shlurp) 24.9065 Tj
--240 TJm
-(out) 12.7322 Tj
--240 TJm
-(its) 9.41466 Tj
--240 TJm
-(compressed) 47.0334 Tj
--241 TJm
-(form) 19.3673 Tj
--240 TJm
-(using) 21.589 Tj
--240 TJm
-(zero) 17.1456 Tj
--240 TJm
-(or) 8.29885 Tj
--240 TJm
-(more) 20.4731 Tj
--241 TJm
-(calls) 18.2614 Tj
--240 TJm
-(of) 8.29885 Tj
-[1 0 0 1 401.454 710.037] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -401.454 -710.037] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-401.454 710.037 Td
-/F134_0 9.9626 Tf
-(BZ2_bzCompress) 83.6858 Tj
-[1 0 0 1 485.14 710.037] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -485.14 -710.037] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-487.533 710.037 Td
-/F130_0 9.9626 Tf
-(with) 17.7135 Tj
--240 TJm
-(action) 24.3486 Tj
--240 TJm
-(=) 5.61891 Tj
-[1 0 0 1 91.9253 698.082] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -91.9253 -698.082] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-91.9253 698.082 Td
-/F134_0 9.9626 Tf
-(BZ_RUN) 35.8654 Tj
-[1 0 0 1 127.791 698.082] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -127.791 -698.082] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-127.791 698.082 Td
-/F130_0 9.9626 Tf
-(.) 2.49065 Tj
-[1 0 0 1 130.281 698.082] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -58.2814 -21.9178] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 7.3724 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -79.3724 -676.164] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-79.3724 676.164 Td
-/F130_0 9.9626 Tf
-(3.) 7.47195 Tj
-[1 0 0 1 86.8444 676.164] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 3.0884 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 1.9925 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -91.9253 -676.164] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-91.9253 676.164 Td
-/F130_0 9.9626 Tf
-(Finish) 24.9165 Tj
--242 TJm
-(up.) 12.4533 Tj
--307 TJm
-(Repeatedly) 44.8217 Tj
--241 TJm
-(call) 14.386 Tj
-[1 0 0 1 198.784 676.164] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -198.784 -676.164] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-198.784 676.164 Td
-/F134_0 9.9626 Tf
-(BZ2_bzCompress) 83.6858 Tj
-[1 0 0 1 282.471 676.164] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -282.471 -676.164] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-284.878 676.164 Td
-/F130_0 9.9626 Tf
-(with) 17.7135 Tj
--242 TJm
-(action) 24.3486 Tj
--241 TJm
-(=) 5.61891 Tj
-[1 0 0 1 339.78 676.164] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -339.78 -676.164] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-339.78 676.164 Td
-/F134_0 9.9626 Tf
-(BZ_FINISH) 53.798 Tj
-[1 0 0 1 393.579 676.164] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -393.579 -676.164] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-393.579 676.164 Td
-/F130_0 9.9626 Tf
-(,) 2.49065 Tj
--242 TJm
-(cop) 14.386 Tj
-10 TJm
-(ying) 17.7135 Tj
--241 TJm
-(out) 12.7322 Tj
--242 TJm
-(the) 12.1743 Tj
--242 TJm
-(compres) 33.7533 Tj
-1 TJm
-(sed) 13.2801 Tj
--242 TJm
-(output,) 27.9551 Tj
-91.9253 664.209 Td
-(until) 18.2714 Tj
-[1 0 0 1 112.687 664.209] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -112.687 -664.209] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-112.687 664.209 Td
-/F134_0 9.9626 Tf
-(BZ_STREAM_END) 77.7083 Tj
-[1 0 0 1 190.396 664.209] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -190.396 -664.209] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-192.886 664.209 Td
-/F130_0 9.9626 Tf
-(is) 6.64505 Tj
--250 TJm
-(returned.) 35.686 Tj
-[1 0 0 1 237.708 664.209] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -165.708 -21.9178] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 7.3724 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -79.3724 -642.291] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-79.3724 642.291 Td
-/F130_0 9.9626 Tf
-(4.) 7.47195 Tj
-[1 0 0 1 86.8444 642.291] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 3.0884 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 1.9925 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -91.9253 -642.291] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-91.9253 642.291 Td
-/F130_0 9.9626 Tf
-(Close) 22.6948 Tj
--250 TJm
-(up) 9.9626 Tj
--250 TJm
-(and) 14.386 Tj
--250 TJm
-(go) 9.9626 Tj
--250 TJm
-(home.) 24.6275 Tj
--620 TJm
-(Call) 16.6077 Tj
-[1 0 0 1 208.796 642.291] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -208.796 -642.291] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-208.796 642.291 Td
-/F134_0 9.9626 Tf
-(BZ2_bzCompressEnd) 101.619 Tj
-[1 0 0 1 310.415 642.291] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -310.415 -642.291] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-310.415 642.291 Td
-/F130_0 9.9626 Tf
-(.) 2.49065 Tj
-[1 0 0 1 312.906 642.291] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -240.906 -12.1195] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -630.172] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 620.374 Td
-/F130_0 9.9626 Tf
-(If) 6.63509 Tj
--269 TJm
-(the) 12.1743 Tj
--270 TJm
-(data) 16.5977 Tj
--269 TJm
-(you) 14.9439 Tj
--270 TJm
-(w) 7.193 Tj
-10 TJm
-(ant) 12.1743 Tj
--269 TJm
-(to) 7.7509 Tj
--270 TJm
-(compress) 37.6287 Tj
--269 TJm
-(\002ts) 12.1843 Tj
--270 TJm
-(into) 15.5018 Tj
--269 TJm
-(your) 18.2614 Tj
--270 TJm
-(input) 20.4831 Tj
--269 TJm
-(b) 4.9813 Tj
-20 TJm
-(uf) 8.29885 Tj
-25 TJm
-(fer) 11.0585 Tj
--270 TJm
-(all) 9.9626 Tj
--269 TJm
-(at) 7.193 Tj
--270 TJm
-(once,) 21.3 Tj
--274 TJm
-(you) 14.9439 Tj
--269 TJm
-(can) 13.8281 Tj
--270 TJm
-(skip) 16.6077 Tj
--269 TJm
-(the) 12.1743 Tj
--270 TJm
-(calls) 18.2614 Tj
--269 TJm
-(of) 8.29885 Tj
-[1 0 0 1 456.314 620.374] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -456.314 -620.374] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-456.314 620.374 Td
-/F134_0 9.9626 Tf
-(BZ2_bzCompress) 83.6858 Tj
-72 608.418 Td
-(\() 5.97756 Tj
--600 TJm
-(...,) 23.9102 Tj
--600 TJm
-(BZ_RUN) 35.8654 Tj
--600 TJm
-(\)) 5.97756 Tj
-[1 0 0 1 161.664 608.418] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -161.664 -608.418] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-164.154 608.418 Td
-/F130_0 9.9626 Tf
-(and) 14.386 Tj
--250 TJm
-(just) 14.396 Tj
--250 TJm
-(do) 9.9626 Tj
--250 TJm
-(the) 12.1743 Tj
-[1 0 0 1 225.036 608.418] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -225.036 -608.418] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-225.036 608.418 Td
-/F134_0 9.9626 Tf
-(BZ2_bzCompress) 83.6858 Tj
--600 TJm
-(\() 5.97756 Tj
--600 TJm
-(...,) 23.9102 Tj
--600 TJm
-(BZ_FINISH) 53.798 Tj
--600 TJm
-(\)) 5.97756 Tj
-[1 0 0 1 422.296 608.418] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -422.296 -608.418] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-424.786 608.418 Td
-/F130_0 9.9626 Tf
-(calls.) 20.7521 Tj
-[1 0 0 1 72 606.262] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.9627] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -596.299] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 586.501 Td
-/F130_0 9.9626 Tf
-(All) 12.7322 Tj
--278 TJm
-(required) 33.1954 Tj
--277 TJm
-(memory) 33.2053 Tj
--278 TJm
-(is) 6.64505 Tj
--277 TJm
-(allocated) 35.965 Tj
--278 TJm
-(by) 9.9626 Tj
-[1 0 0 1 220.295 586.501] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -220.295 -586.501] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-220.295 586.501 Td
-/F134_0 9.9626 Tf
-(BZ2_bzCompressInit) 107.596 Tj
-[1 0 0 1 327.891 586.501] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -327.891 -586.501] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-327.891 586.501 Td
-/F130_0 9.9626 Tf
-(.) 2.49065 Tj
--785 TJm
-(The) 15.4918 Tj
--278 TJm
-(compression) 50.3609 Tj
--277 TJm
-(library) 26.5603 Tj
--278 TJm
-(can) 13.8281 Tj
--277 TJm
-(accept) 25.4445 Tj
--278 TJm
-(an) 9.40469 Tj
-15 TJm
-(y) 4.9813 Tj
--277 TJm
-(data) 16.5977 Tj
--278 TJm
-(at) 7.193 Tj
--278 TJm
-(all) 9.9626 Tj
-72 574.545 Td
-(\(ob) 13.2801 Tj
-15 TJm
-(viously\).) 35.1481 Tj
--612 TJm
-(So) 10.5205 Tj
--238 TJm
-(you) 14.9439 Tj
--237 TJm
-(shouldn') 34.8691 Tj
-18 TJm
-(t) 2.7696 Tj
--238 TJm
-(get) 12.1743 Tj
--238 TJm
-(an) 9.40469 Tj
-15 TJm
-(y) 4.9813 Tj
--237 TJm
-(error) 19.3573 Tj
--238 TJm
-(return) 23.7907 Tj
--238 TJm
-(v) 4.9813 Tj
-25 TJm
-(alues) 20.4731 Tj
--238 TJm
-(from) 19.3673 Tj
--237 TJm
-(the) 12.1743 Tj
-[1 0 0 1 339.287 574.545] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -339.287 -574.545] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-339.287 574.545 Td
-/F134_0 9.9626 Tf
-(BZ2_bzCompress) 83.6858 Tj
-[1 0 0 1 422.973 574.545] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -422.973 -574.545] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-425.342 574.545 Td
-/F130_0 9.9626 Tf
-(calls.) 20.7521 Tj
--612 TJm
-(If) 6.63509 Tj
--238 TJm
-(you) 14.9439 Tj
--237 TJm
-(do,) 12.4533 Tj
--240 TJm
-(the) 12.1743 Tj
-15 TJm
-(y) 4.9813 Tj
--238 TJm
-(will) 15.5018 Tj
--238 TJm
-(be) 9.40469 Tj
-[1 0 0 1 72 562.59] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -562.59] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 562.59 Td
-/F134_0 9.9626 Tf
-(BZ_SEQUENCE_ERROR) 101.619 Tj
-[1 0 0 1 173.619 562.59] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -173.619 -562.59] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-173.619 562.59 Td
-/F130_0 9.9626 Tf
-(,) 2.49065 Tj
--250 TJm
-(and) 14.386 Tj
--250 TJm
-(indicate) 31.5416 Tj
--250 TJm
-(a) 4.42339 Tj
--250 TJm
-(b) 4.9813 Tj
-20 TJm
-(ug) 9.9626 Tj
--250 TJm
-(in) 7.7509 Tj
--250 TJm
-(your) 18.2614 Tj
--250 TJm
-(programming.) 56.727 Tj
-[1 0 0 1 72 560.433] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.9626] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -550.471] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 540.673 Td
-/F130_0 9.9626 Tf
-(T) 6.08715 Tj
-35 TJm
-(ri) 6.08715 Tj
-25 TJm
-(vial) 14.9439 Tj
--250 TJm
-(other) 20.4731 Tj
--250 TJm
-(possible) 32.6574 Tj
--250 TJm
-(return) 23.7907 Tj
--250 TJm
-(v) 4.9813 Tj
-25 TJm
-(alues:) 23.2427 Tj
-[1 0 0 1 72 538.516] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -36.8617] cm
-/DeviceRGB {} cs
-[0.94899 0.94899 0.976456] sc
-/DeviceRGB {} CS
-[0.94899 0.94899 0.976456] SC
-0 0 468 35.8655 re
-f
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 3.5866] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 32.2789] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 18 -8.3686] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -90 -529.151] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-90 529.151 Td
-/F134_0 9.9626 Tf
-(BZ_PARAM_ERROR) 83.6858 Tj
-98.4879 517.196 Td
-(if) 11.9551 Tj
--426 TJm
-(strm) 23.9102 Tj
--426 TJm
-(is) 11.9551 Tj
--426 TJm
-(NULL,) 29.8878 Tj
--426 TJm
-(or) 11.9551 Tj
--426 TJm
-(strm->s) 41.8429 Tj
--426 TJm
-(is) 11.9551 Tj
--426 TJm
-(NULL) 23.9102 Tj
-[1 0 0 1 72 501.654] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 468 3.5866] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -468 -3.5866] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.9626] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -491.691] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 471.033 Td
-/F122_0 17.2154 Tf
-(3.3.3.) 43.0729 Tj
-[1 0 0 1 119.858 471.033] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -119.858 -471.033] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-119.858 471.033 Td
-/F392_0 17.2154 Tf
-(BZ2_bzCompressEnd) 175.597 Tj
-[1 0 0 1 295.455 471.033] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -223.455 -2.3326] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -24.9066] cm
-/DeviceRGB {} cs
-[0.94899 0.94899 0.976456] sc
-/DeviceRGB {} CS
-[0.94899 0.94899 0.976456] SC
-0 0 468 23.9103 re
-f
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 3.5866] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 20.3237] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 18 -8.3686] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -90 -459.335] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-90 459.335 Td
-/F134_0 9.9626 Tf
-(int) 17.9327 Tj
--426 TJm
-(BZ2_bzCompressEnd) 101.619 Tj
--426 TJm
-(\() 5.97756 Tj
--426 TJm
-(bz_stream) 53.798 Tj
-286.303 457.592 Td
-(*) 5.97756 Tj
-292.281 459.335 Td
-(strm) 23.9102 Tj
--426 TJm
-(\);) 11.9551 Tj
-[1 0 0 1 72 443.793] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 468 3.5866] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -468 -13.5493] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -433.831] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 421.876 Td
-/F130_0 9.9626 Tf
-(Releases) 34.8591 Tj
--250 TJm
-(all) 9.9626 Tj
--250 TJm
-(memory) 33.2053 Tj
--250 TJm
-(associated) 40.9463 Tj
--250 TJm
-(with) 17.7135 Tj
--250 TJm
-(a) 4.42339 Tj
--250 TJm
-(compression) 50.3609 Tj
--250 TJm
-(stream.) 29.0509 Tj
-[1 0 0 1 72 419.719] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.9626] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -409.756] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 399.958 Td
-/F130_0 9.9626 Tf
-(Possible) 33.2153 Tj
--250 TJm
-(return) 23.7907 Tj
--250 TJm
-(v) 4.9813 Tj
-25 TJm
-(alues:) 23.2427 Tj
-[1 0 0 1 72 399.858] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -36.8618] cm
-/DeviceRGB {} cs
-[0.94899 0.94899 0.976456] sc
-/DeviceRGB {} CS
-[0.94899 0.94899 0.976456] SC
-0 0 468 35.8655 re
-f
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 3.5866] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 32.2789] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 18 -8.3686] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -90 -390.493] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-90 390.493 Td
-/F134_0 9.9626 Tf
-(BZ_PARAM_ERROR) 83.6858 Tj
--852 TJm
-(if) 11.9551 Tj
--426 TJm
-(strm) 23.9102 Tj
--426 TJm
-(is) 11.9551 Tj
--426 TJm
-(NULL) 23.9102 Tj
--426 TJm
-(or) 11.9551 Tj
--426 TJm
-(strm->s) 41.8429 Tj
--426 TJm
-(is) 11.9551 Tj
--426 TJm
-(NULL) 23.9102 Tj
-90 378.538 Td
-(BZ_OK) 29.8878 Tj
--4686 TJm
-(otherwise) 53.798 Tj
-[1 0 0 1 72 362.996] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 468 3.5866] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -468 -3.5866] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.9626] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -353.034] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 332.375 Td
-/F122_0 17.2154 Tf
-(3.3.4.) 43.0729 Tj
-[1 0 0 1 119.858 332.375] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -119.858 -332.375] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-119.858 332.375 Td
-/F392_0 17.2154 Tf
-(BZ2_bzDecompressInit) 206.585 Tj
-[1 0 0 1 326.443 332.375] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -254.443 -2.3327] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -24.9066] cm
-/DeviceRGB {} cs
-[0.94899 0.94899 0.976456] sc
-/DeviceRGB {} CS
-[0.94899 0.94899 0.976456] SC
-0 0 468 23.9103 re
-f
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 3.5866] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 20.3237] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 18 -8.3685] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -90 -320.678] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-90 320.678 Td
-/F134_0 9.9626 Tf
-(int) 17.9327 Tj
--426 TJm
-(BZ2_bzDecompressInit) 119.551 Tj
--426 TJm
-(\() 5.97756 Tj
--426 TJm
-(bz_stream) 53.798 Tj
-304.236 318.934 Td
-(*) 5.97756 Tj
-310.214 320.678 Td
-(strm,) 29.8878 Tj
--426 TJm
-(int) 17.9327 Tj
--426 TJm
-(verbosity,) 59.7756 Tj
--426 TJm
-(int) 17.9327 Tj
--426 TJm
-(small) 29.8878 Tj
--426 TJm
-(\);) 11.9551 Tj
-[1 0 0 1 72 305.136] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 468 3.5866] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -468 -13.5492] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -295.173] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 283.218 Td
-/F130_0 9.9626 Tf
-(Prepares) 34.3012 Tj
--351 TJm
-(for) 11.6164 Tj
--351 TJm
-(decompression.) 62.2563 Tj
--1228 TJm
-(As) 11.0684 Tj
--351 TJm
-(with) 17.7135 Tj
-[1 0 0 1 235.177 283.218] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -235.177 -283.218] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-235.177 283.218 Td
-/F134_0 9.9626 Tf
-(BZ2_bzCompressInit) 107.596 Tj
-[1 0 0 1 342.773 283.218] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -342.773 -283.218] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-342.773 283.218 Td
-/F130_0 9.9626 Tf
-(,) 2.49065 Tj
--377 TJm
-(a) 4.42339 Tj
-[1 0 0 1 356.937 283.218] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -356.937 -283.218] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-356.937 283.218 Td
-/F134_0 9.9626 Tf
-(bz_stream) 53.798 Tj
-[1 0 0 1 410.736 283.218] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -410.736 -283.218] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-414.235 283.218 Td
-/F130_0 9.9626 Tf
-(record) 25.4445 Tj
--351 TJm
-(should) 26.5703 Tj
--351 TJm
-(be) 9.40469 Tj
--352 TJm
-(allocated) 35.965 Tj
--351 TJm
-(and) 14.386 Tj
-72 271.263 Td
-(initialised) 39.3025 Tj
--306 TJm
-(before) 25.4445 Tj
--305 TJm
-(the) 12.1743 Tj
--306 TJm
-(call.) 16.8766 Tj
--953 TJm
-(Fields) 24.3586 Tj
-[1 0 0 1 211.833 271.263] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -211.833 -271.263] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-211.833 271.263 Td
-/F134_0 9.9626 Tf
-(bzalloc) 41.8429 Tj
-[1 0 0 1 253.676 271.263] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -253.676 -271.263] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-253.676 271.263 Td
-/F130_0 9.9626 Tf
-(,) 2.49065 Tj
-[1 0 0 1 259.35 271.263] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -259.35 -271.263] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-259.35 271.263 Td
-/F134_0 9.9626 Tf
-(bzfree) 35.8654 Tj
-[1 0 0 1 295.215 271.263] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -295.215 -271.263] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-298.26 271.263 Td
-/F130_0 9.9626 Tf
-(and) 14.386 Tj
-[1 0 0 1 315.69 271.263] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -315.69 -271.263] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-315.69 271.263 Td
-/F134_0 9.9626 Tf
-(opaque) 35.8654 Tj
-[1 0 0 1 351.556 271.263] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -351.556 -271.263] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-354.6 271.263 Td
-/F130_0 9.9626 Tf
-(should) 26.5703 Tj
--306 TJm
-(be) 9.40469 Tj
--305 TJm
-(set) 11.0684 Tj
--306 TJm
-(if) 6.08715 Tj
--305 TJm
-(a) 4.42339 Tj
--306 TJm
-(custom) 28.782 Tj
--305 TJm
-(memory) 33.2053 Tj
--306 TJm
-(allocator) 34.8591 Tj
--306 TJm
-(is) 6.64505 Tj
-72 259.308 Td
-(required,) 35.686 Tj
--350 TJm
-(or) 8.29885 Tj
--331 TJm
-(made) 21.579 Tj
-[1 0 0 1 147.635 259.308] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -147.635 -259.308] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-147.635 259.308 Td
-/F134_0 9.9626 Tf
-(NULL) 23.9102 Tj
-[1 0 0 1 171.546 259.308] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -171.546 -259.308] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-174.835 259.308 Td
-/F130_0 9.9626 Tf
-(for) 11.6164 Tj
--330 TJm
-(the) 12.1743 Tj
--331 TJm
-(normal) 28.224 Tj
-[1 0 0 1 236.722 259.308] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -236.722 -259.308] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-236.722 259.308 Td
-/F134_0 9.9626 Tf
-(malloc) 35.8654 Tj
-[1 0 0 1 272.587 259.308] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -272.587 -259.308] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-275.878 259.308 Td
-/F130_0 9.9626 Tf
-(/) 2.7696 Tj
-[1 0 0 1 281.938 259.308] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -281.938 -259.308] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-281.938 259.308 Td
-/F134_0 9.9626 Tf
-(free) 23.9102 Tj
-[1 0 0 1 305.848 259.308] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -305.848 -259.308] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-309.139 259.308 Td
-/F130_0 9.9626 Tf
-(routines.) 34.5901 Tj
--1102 TJm
-(Upon) 22.1369 Tj
--330 TJm
-(return,) 26.2813 Tj
--350 TJm
-(the) 12.1743 Tj
--331 TJm
-(internal) 30.4357 Tj
--330 TJm
-(state) 18.2614 Tj
--330 TJm
-(will) 15.5018 Tj
--330 TJm
-(ha) 9.40469 Tj
-20 TJm
-(v) 4.9813 Tj
-15 TJm
-(e) 4.42339 Tj
--331 TJm
-(been) 18.8094 Tj
-72 247.353 Td
-(initialised,) 41.7931 Tj
--250 TJm
-(and) 14.386 Tj
-[1 0 0 1 133.16 247.353] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -133.16 -247.353] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-133.16 247.353 Td
-/F134_0 9.9626 Tf
-(total_in) 47.8205 Tj
-[1 0 0 1 180.98 247.353] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -180.98 -247.353] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-183.471 247.353 Td
-/F130_0 9.9626 Tf
-(and) 14.386 Tj
-[1 0 0 1 200.348 247.353] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -200.348 -247.353] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-200.348 247.353 Td
-/F134_0 9.9626 Tf
-(total_out) 53.798 Tj
-[1 0 0 1 254.146 247.353] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -254.146 -247.353] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-256.637 247.353 Td
-/F130_0 9.9626 Tf
-(will) 15.5018 Tj
--250 TJm
-(be) 9.40469 Tj
--250 TJm
-(zero.) 19.6363 Tj
-[1 0 0 1 72 245.913] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.9626] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -235.951] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 225.435 Td
-/F130_0 9.9626 Tf
-(F) 5.53921 Tj
-15 TJm
-(or) 8.29885 Tj
--250 TJm
-(the) 12.1743 Tj
--250 TJm
-(meaning) 34.3112 Tj
--250 TJm
-(of) 8.29885 Tj
--250 TJm
-(parameter) 39.8305 Tj
-[1 0 0 1 192.756 225.435] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -192.756 -225.435] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-192.756 225.435 Td
-/F134_0 9.9626 Tf
-(verbosity) 53.798 Tj
-[1 0 0 1 246.554 225.435] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -246.554 -225.435] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-246.554 225.435 Td
-/F130_0 9.9626 Tf
-(,) 2.49065 Tj
--250 TJm
-(see) 12.7222 Tj
-[1 0 0 1 266.748 225.435] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -266.748 -225.435] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-266.748 225.435 Td
-/F134_0 9.9626 Tf
-(BZ2_bzCompressInit) 107.596 Tj
-[1 0 0 1 374.345 225.435] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -374.345 -225.435] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-374.345 225.435 Td
-/F130_0 9.9626 Tf
-(.) 2.49065 Tj
-[1 0 0 1 72 223.278] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.9627] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -213.315] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 203.517 Td
-/F130_0 9.9626 Tf
-(If) 6.63509 Tj
-[1 0 0 1 81.4975 203.517] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -81.4975 -203.517] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-81.4975 203.517 Td
-/F134_0 9.9626 Tf
-(small) 29.8878 Tj
-[1 0 0 1 111.385 203.517] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -111.385 -203.517] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-114.248 203.517 Td
-/F130_0 9.9626 Tf
-(is) 6.64505 Tj
--287 TJm
-(nonzero,) 34.5802 Tj
--297 TJm
-(the) 12.1743 Tj
--287 TJm
-(library) 26.5603 Tj
--288 TJm
-(will) 15.5018 Tj
--287 TJm
-(use) 13.2801 Tj
--287 TJm
-(an) 9.40469 Tj
--287 TJm
-(alternati) 32.6474 Tj
-25 TJm
-(v) 4.9813 Tj
-15 TJm
-(e) 4.42339 Tj
--288 TJm
-(decompression) 59.7656 Tj
--287 TJm
-(algorithm) 38.7446 Tj
--287 TJm
-(which) 24.3486 Tj
--288 TJm
-(uses) 17.1556 Tj
--287 TJm
-(less) 14.9439 Tj
--287 TJm
-(memory) 33.2053 Tj
--287 TJm
-(b) 4.9813 Tj
-20 TJm
-(ut) 7.7509 Tj
--288 TJm
-(at) 7.193 Tj
--287 TJm
-(the) 12.1743 Tj
-72 191.562 Td
-(cost) 16.0497 Tj
--289 TJm
-(of) 8.29885 Tj
--290 TJm
-(decompressing) 59.7656 Tj
--289 TJm
-(more) 20.4731 Tj
--289 TJm
-(slo) 11.6264 Tj
-25 TJm
-(wly) 14.9439 Tj
--290 TJm
-(\(roughly) 34.3112 Tj
--289 TJm
-(speaking,) 37.9077 Tj
--299 TJm
-(half) 15.4918 Tj
--290 TJm
-(the) 12.1743 Tj
--289 TJm
-(speed,) 25.1755 Tj
--299 TJm
-(b) 4.9813 Tj
-20 TJm
-(ut) 7.7509 Tj
--289 TJm
-(the) 12.1743 Tj
--290 TJm
-(maximum) 40.4083 Tj
--289 TJm
-(memory) 33.2053 Tj
--289 TJm
-(requirement) 48.1393 Tj
--290 TJm
-(drops) 22.1369 Tj
-72 179.607 Td
-(to) 7.7509 Tj
--250 TJm
-(around) 27.6661 Tj
--250 TJm
-(2300k\).) 30.7147 Tj
--620 TJm
-(See) 14.386 Tj
-[1 0 0 1 166.166 179.607] cm
-/DeviceRGB {} cs
-[0 0 1] sc
-/DeviceRGB {} CS
-[0 0 1] SC
-[1 0 0 1 -166.166 -179.607] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-166.166 179.607 Td
-/F130_0 9.9626 Tf
-(Ho) 12.1743 Tj
-25 TJm
-(w) 7.193 Tj
--250 TJm
-(to) 7.7509 Tj
--250 TJm
-(use) 13.2801 Tj
--250 TJm
-(bzip2) 22.1369 Tj
-[1 0 0 1 235.924 179.607] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 1] sc
-/DeviceRGB {} CS
-[0 0 1] SC
-/DeviceRGB {} cs
-[0 0 1] sc
-/DeviceRGB {} CS
-[0 0 1] SC
-[1 0 0 1 -235.924 -179.607] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-238.415 179.607 Td
-/F130_0 9.9626 Tf
-([2]) 11.6164 Tj
-[1 0 0 1 250.031 179.607] cm
-/DeviceRGB {} cs
-[0 0 1] sc
-/DeviceRGB {} CS
-[0 0 1] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -250.031 -179.607] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-252.522 179.607 Td
-/F130_0 9.9626 Tf
-(for) 11.6164 Tj
--250 TJm
-(more) 20.4731 Tj
--250 TJm
-(information) 47.0434 Tj
--250 TJm
-(on) 9.9626 Tj
--250 TJm
-(memory) 33.2053 Tj
--250 TJm
-(management.) 53.3995 Tj
-[1 0 0 1 72 177.45] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.9626] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -167.487] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 157.689 Td
-/F130_0 9.9626 Tf
-(Note) 19.3673 Tj
--289 TJm
-(that) 14.9439 Tj
--290 TJm
-(the) 12.1743 Tj
--289 TJm
-(amount) 29.8878 Tj
--289 TJm
-(of) 8.29885 Tj
--289 TJm
-(memory) 33.2053 Tj
--290 TJm
-(needed) 28.2141 Tj
--289 TJm
-(to) 7.7509 Tj
--289 TJm
-(decompress) 47.0334 Tj
--289 TJm
-(a) 4.42339 Tj
--290 TJm
-(stream) 26.5603 Tj
--289 TJm
-(cannot) 26.5603 Tj
--289 TJm
-(be) 9.40469 Tj
--289 TJm
-(determined) 44.8217 Tj
--290 TJm
-(until) 18.2714 Tj
--289 TJm
-(the) 12.1743 Tj
--289 TJm
-(stream') 29.8778 Tj
-55 TJm
-(s) 3.87545 Tj
--289 TJm
-(header) 26.5503 Tj
--290 TJm
-(has) 13.2801 Tj
-72 145.734 Td
-(been) 18.8094 Tj
--342 TJm
-(read,) 19.6363 Tj
--366 TJm
-(so) 8.85675 Tj
--342 TJm
-(e) 4.42339 Tj
-25 TJm
-(v) 4.9813 Tj
-15 TJm
-(en) 9.40469 Tj
--342 TJm
-(if) 6.08715 Tj
-[1 0 0 1 161.081 145.734] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -161.081 -145.734] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-161.081 145.734 Td
-/F134_0 9.9626 Tf
-(BZ2_bzDecompressInit) 119.551 Tj
-[1 0 0 1 280.633 145.734] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -280.633 -145.734] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-284.043 145.734 Td
-/F130_0 9.9626 Tf
-(succeeds,) 37.8977 Tj
--365 TJm
-(a) 4.42339 Tj
--343 TJm
-(subsequent) 44.2738 Tj
-[1 0 0 1 381.098 145.734] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -381.098 -145.734] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-381.098 145.734 Td
-/F134_0 9.9626 Tf
-(BZ2_bzDecompress) 95.641 Tj
-[1 0 0 1 476.739 145.734] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -476.739 -145.734] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-480.149 145.734 Td
-/F130_0 9.9626 Tf
-(could) 22.1369 Tj
--342 TJm
-(f) 3.31755 Tj
-10 TJm
-(ail) 9.9626 Tj
--343 TJm
-(with) 17.7135 Tj
-[1 0 0 1 72 133.779] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -133.779] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 133.779 Td
-/F134_0 9.9626 Tf
-(BZ_MEM_ERROR) 71.7307 Tj
-[1 0 0 1 143.731 133.779] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -143.731 -133.779] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-143.731 133.779 Td
-/F130_0 9.9626 Tf
-(.) 2.49065 Tj
-[1 0 0 1 72 132.469] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.9627] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -122.506] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 111.861 Td
-/F130_0 9.9626 Tf
-(Possible) 33.2153 Tj
--250 TJm
-(return) 23.7907 Tj
--250 TJm
-(v) 4.9813 Tj
-25 TJm
-(alues:) 23.2427 Tj
-[1 0 0 1 72 111.761] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -60.9095] cm
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-[1 0 0 1 1.8929 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 374.394 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 6.8541] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 40.5726 -6.7545] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -493.841 -50.9514] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-534.414 50.9514 Td
-/F130_0 9.9626 Tf
-(16) 9.9626 Tj
-[1 0 0 1 453.269 50.8518] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 93.5985 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 6.2765 0] cm
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-[1 0 0 1 -13.1436 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-Q
-showpage
-%%PageTrailer
-pdfEndPage
-%%Page: 20 20
-%%BeginPageSetup
-%%PageOrientation: Portrait
-pdfStartPage
-0 0 612 792 re W
-%%EndPageSetup
-[] 0 d
-1 i
-0 j
-0 J
-10 M
-1 w
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-false op
-false OP
-0 0 612 792 re
-W
-q
-[1 0 0 1 72 741.554] cm
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-[1 0 0 1 1.8929 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 14.4459] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 187.197 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 -8.9114] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 8.9114] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 76.4979 -6.7546] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -342.569 -749.245] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-419.067 749.245 Td
-/F130_0 9.9626 Tf
-(Programming) 54.7943 Tj
--250 TJm
-(with) 17.7135 Tj
-[1 0 0 1 496.556 749.245] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -496.556 -749.245] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-496.556 749.245 Td
-/F134_0 9.9626 Tf
-(libbzip2) 47.8205 Tj
-[1 0 0 1 544.376 749.245] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -278.305 -2.1568] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 280.796 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -472.974 -5.0363] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -0.4981] cm
-q
-[] 0 d
-0 J
-0.4981 w
-0 0.2491 m
-475.465 0.2491 l
-S
-Q
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 479.251 0] cm
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-[1 0 0 1 -13.1436 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -468 -117.195] cm
-/DeviceRGB {} cs
-[0.94899 0.94899 0.976456] sc
-/DeviceRGB {} CS
-[0.94899 0.94899 0.976456] SC
-0 0 468 95.6413 re
-f
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 3.5866] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 92.0547] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 18 -8.3686] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -90 -711.631] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-90 711.631 Td
-/F134_0 9.9626 Tf
-(BZ_CONFIG_ERROR) 89.6634 Tj
-98.4879 699.676 Td
-(if) 11.9551 Tj
--426 TJm
-(the) 17.9327 Tj
--426 TJm
-(library) 41.8429 Tj
--426 TJm
-(has) 17.9327 Tj
--426 TJm
-(been) 23.9102 Tj
--426 TJm
-(mis-compiled) 71.7307 Tj
-90 687.721 Td
-(BZ_PARAM_ERROR) 83.6858 Tj
-98.4879 675.766 Td
-(if) 11.9551 Tj
--426 TJm
-(\() 5.97756 Tj
--426 TJm
-(small) 29.8878 Tj
--426 TJm
-(!=) 11.9551 Tj
--426 TJm
-(0) 5.97756 Tj
--426 TJm
-(&&) 11.9551 Tj
--426 TJm
-(small) 29.8878 Tj
--426 TJm
-(!=) 11.9551 Tj
--426 TJm
-(1) 5.97756 Tj
--426 TJm
-(\)) 5.97756 Tj
-98.4879 663.811 Td
-(or) 11.9551 Tj
--426 TJm
-(\(verbosity) 59.7756 Tj
--426 TJm
-(<;) 11.9551 Tj
--426 TJm
-(0) 5.97756 Tj
--426 TJm
-(||) 11.9551 Tj
--426 TJm
-(verbosity) 53.798 Tj
--426 TJm
-(>) 5.97756 Tj
--426 TJm
-(4\)) 11.9551 Tj
-90 651.856 Td
-(BZ_MEM_ERROR) 71.7307 Tj
-98.4879 639.9 Td
-(if) 11.9551 Tj
--426 TJm
-(insufficient) 71.7307 Tj
--426 TJm
-(memory) 35.8654 Tj
--426 TJm
-(is) 11.9551 Tj
--426 TJm
-(available) 53.798 Tj
-[1 0 0 1 72 624.359] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 468 3.5865] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -468 -13.5492] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -614.396] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 602.441 Td
-/F130_0 9.9626 Tf
-(Allo) 17.7135 Tj
-25 TJm
-(w) 7.193 Tj
-10 TJm
-(able) 16.5977 Tj
--250 TJm
-(ne) 9.40469 Tj
-15 TJm
-(xt) 7.7509 Tj
--250 TJm
-(actions:) 30.9936 Tj
-[1 0 0 1 72 602.341] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -48.8169] cm
-/DeviceRGB {} cs
-[0.94899 0.94899 0.976456] sc
-/DeviceRGB {} CS
-[0.94899 0.94899 0.976456] SC
-0 0 468 47.8207 re
-f
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 3.5866] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 44.2341] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 18 -8.3686] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -90 -592.976] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-90 592.976 Td
-/F134_0 9.9626 Tf
-(BZ2_bzDecompress) 95.641 Tj
-98.4879 581.021 Td
-(if) 11.9551 Tj
--426 TJm
-(BZ_OK) 29.8878 Tj
--426 TJm
-(was) 17.9327 Tj
--426 TJm
-(returned) 47.8205 Tj
-98.4879 569.066 Td
-(no) 11.9551 Tj
--426 TJm
-(specific) 47.8205 Tj
--426 TJm
-(action) 35.8654 Tj
--426 TJm
-(required) 47.8205 Tj
--426 TJm
-(in) 11.9551 Tj
--426 TJm
-(case) 23.9102 Tj
--426 TJm
-(of) 11.9551 Tj
--426 TJm
-(error) 29.8878 Tj
-[1 0 0 1 72 553.524] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 468 3.5866] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -468 -3.5866] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.9626] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -543.562] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 522.903 Td
-/F122_0 17.2154 Tf
-(3.3.5.) 43.0729 Tj
-[1 0 0 1 119.858 522.903] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -119.858 -522.903] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-119.858 522.903 Td
-/F392_0 17.2154 Tf
-(BZ2_bzDecompress) 165.268 Tj
-[1 0 0 1 285.126 522.903] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -213.126 -2.3327] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -24.9066] cm
-/DeviceRGB {} cs
-[0.94899 0.94899 0.976456] sc
-/DeviceRGB {} CS
-[0.94899 0.94899 0.976456] SC
-0 0 468 23.9103 re
-f
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 3.5866] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 20.3237] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 18 -8.3685] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -90 -511.206] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-90 511.206 Td
-/F134_0 9.9626 Tf
-(int) 17.9327 Tj
--426 TJm
-(BZ2_bzDecompress) 95.641 Tj
--426 TJm
-(\() 5.97756 Tj
--426 TJm
-(bz_stream) 53.798 Tj
-280.326 509.462 Td
-(*) 5.97756 Tj
-286.303 511.206 Td
-(strm) 23.9102 Tj
--426 TJm
-(\);) 11.9551 Tj
-[1 0 0 1 72 495.664] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 468 3.5866] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -468 -13.5492] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -485.701] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 473.746 Td
-/F130_0 9.9626 Tf
-(Pro) 13.8381 Tj
-15 TJm
-(vides) 21.031 Tj
--301 TJm
-(more) 20.4731 Tj
--302 TJm
-(input) 20.4831 Tj
--301 TJm
-(and/out) 29.8878 Tj
--302 TJm
-(output) 25.4644 Tj
--301 TJm
-(b) 4.9813 Tj
-20 TJm
-(uf) 8.29885 Tj
-25 TJm
-(fer) 11.0585 Tj
--301 TJm
-(space) 22.1269 Tj
--302 TJm
-(for) 11.6164 Tj
--301 TJm
-(the) 12.1743 Tj
--302 TJm
-(library) 26.5603 Tj
-65 TJm
-(.) 2.49065 Tj
--928 TJm
-(The) 15.4918 Tj
--301 TJm
-(caller) 22.1269 Tj
--302 TJm
-(maintains) 38.7446 Tj
--301 TJm
-(input) 20.4831 Tj
--302 TJm
-(and) 14.386 Tj
--301 TJm
-(output) 25.4644 Tj
--301 TJm
-(b) 4.9813 Tj
-20 TJm
-(uf) 8.29885 Tj
-25 TJm
-(fers,) 17.4246 Tj
--315 TJm
-(and) 14.386 Tj
-72 461.791 Td
-(uses) 17.1556 Tj
-[1 0 0 1 91.6461 461.791] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -91.6461 -461.791] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-91.6461 461.791 Td
-/F134_0 9.9626 Tf
-(BZ2_bzDecompress) 95.641 Tj
-[1 0 0 1 187.287 461.791] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -187.287 -461.791] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-189.778 461.791 Td
-/F130_0 9.9626 Tf
-(to) 7.7509 Tj
--250 TJm
-(transfer) 30.4258 Tj
--250 TJm
-(data) 16.5977 Tj
--250 TJm
-(between) 33.1954 Tj
--250 TJm
-(them.) 22.4159 Tj
-[1 0 0 1 72 460.257] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.9626] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -450.294] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 439.873 Td
-/F130_0 9.9626 Tf
-(Before) 27.1082 Tj
--498 TJm
-(each) 18.2515 Tj
--499 TJm
-(call) 14.386 Tj
--498 TJm
-(to) 7.7509 Tj
-[1 0 0 1 159.356 439.873] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -159.356 -439.873] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-159.356 439.873 Td
-/F134_0 9.9626 Tf
-(BZ2_bzDecompress) 95.641 Tj
-[1 0 0 1 254.997 439.873] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -254.997 -439.873] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-254.997 439.873 Td
-/F130_0 9.9626 Tf
-(,) 2.49065 Tj
-[1 0 0 1 263.071 439.873] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -263.071 -439.873] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-263.071 439.873 Td
-/F134_0 9.9626 Tf
-(next_in) 41.8429 Tj
-[1 0 0 1 304.914 439.873] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -304.914 -439.873] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-309.879 439.873 Td
-/F130_0 9.9626 Tf
-(should) 26.5703 Tj
--498 TJm
-(point) 20.4831 Tj
--499 TJm
-(at) 7.193 Tj
--498 TJm
-(the) 12.1743 Tj
--498 TJm
-(compressed) 47.0334 Tj
--499 TJm
-(data,) 19.0883 Tj
--560 TJm
-(and) 14.386 Tj
-[1 0 0 1 492.179 439.873] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -492.179 -439.873] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-492.179 439.873 Td
-/F134_0 9.9626 Tf
-(avail_in) 47.8205 Tj
-[1 0 0 1 540 439.873] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -540 -439.873] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 427.918 Td
-/F130_0 9.9626 Tf
-(should) 26.5703 Tj
--308 TJm
-(indicate) 31.5416 Tj
--308 TJm
-(ho) 9.9626 Tj
-25 TJm
-(w) 7.193 Tj
--309 TJm
-(man) 17.1556 Tj
-15 TJm
-(y) 4.9813 Tj
--308 TJm
-(bytes) 21.031 Tj
--308 TJm
-(the) 12.1743 Tj
--308 TJm
-(library) 26.5603 Tj
--308 TJm
-(may) 17.1556 Tj
--309 TJm
-(read.) 19.6363 Tj
-[1 0 0 1 294.955 427.918] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -294.955 -427.918] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-294.955 427.918 Td
-/F134_0 9.9626 Tf
-(BZ2_bzDecompress) 95.641 Tj
-[1 0 0 1 390.597 427.918] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -390.597 -427.918] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-393.667 427.918 Td
-/F130_0 9.9626 Tf
-(updates) 30.4357 Tj
-[1 0 0 1 427.173 427.918] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -427.173 -427.918] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-427.173 427.918 Td
-/F134_0 9.9626 Tf
-(next_in) 41.8429 Tj
-[1 0 0 1 469.016 427.918] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -469.016 -427.918] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-469.016 427.918 Td
-/F130_0 9.9626 Tf
-(,) 2.49065 Tj
-[1 0 0 1 474.723 427.918] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -474.723 -427.918] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-474.723 427.918 Td
-/F134_0 9.9626 Tf
-(avail_in) 47.8205 Tj
-[1 0 0 1 522.543 427.918] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -522.543 -427.918] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-525.614 427.918 Td
-/F130_0 9.9626 Tf
-(and) 14.386 Tj
-[1 0 0 1 72 415.963] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -415.963] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 415.963 Td
-/F134_0 9.9626 Tf
-(total_in) 47.8205 Tj
-[1 0 0 1 119.821 415.963] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -119.821 -415.963] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-122.311 415.963 Td
-/F130_0 9.9626 Tf
-(to) 7.7509 Tj
--250 TJm
-(re\003ect) 24.8965 Tj
--250 TJm
-(the) 12.1743 Tj
--250 TJm
-(number) 30.4357 Tj
--250 TJm
-(of) 8.29885 Tj
--250 TJm
-(bytes) 21.031 Tj
--250 TJm
-(it) 5.53921 Tj
--250 TJm
-(has) 13.2801 Tj
--250 TJm
-(read.) 19.6363 Tj
-[1 0 0 1 72 413.806] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.9626] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -403.843] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 394.045 Td
-/F130_0 9.9626 Tf
-(Similarly) 37.0908 Tj
-65 TJm
-(,) 2.49065 Tj
-[1 0 0 1 113.799 394.045] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -113.799 -394.045] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-113.799 394.045 Td
-/F134_0 9.9626 Tf
-(next_out) 47.8205 Tj
-[1 0 0 1 161.62 394.045] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -161.62 -394.045] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-164.41 394.045 Td
-/F130_0 9.9626 Tf
-(should) 26.5703 Tj
--280 TJm
-(point) 20.4831 Tj
--280 TJm
-(to) 7.7509 Tj
--280 TJm
-(a) 4.42339 Tj
--280 TJm
-(b) 4.9813 Tj
-20 TJm
-(uf) 8.29885 Tj
-25 TJm
-(fer) 11.0585 Tj
--280 TJm
-(in) 7.7509 Tj
--281 TJm
-(which) 24.3486 Tj
--280 TJm
-(the) 12.1743 Tj
--280 TJm
-(uncompressed) 56.996 Tj
--280 TJm
-(output) 25.4644 Tj
--280 TJm
-(is) 6.64505 Tj
--280 TJm
-(to) 7.7509 Tj
--280 TJm
-(be) 9.40469 Tj
--280 TJm
-(placed,) 28.493 Tj
--288 TJm
-(with) 17.7135 Tj
-[1 0 0 1 486.202 394.045] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -486.202 -394.045] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-486.202 394.045 Td
-/F134_0 9.9626 Tf
-(avail_out) 53.798 Tj
-[1 0 0 1 540 394.045] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -540 -394.045] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 382.09 Td
-/F130_0 9.9626 Tf
-(indicating) 39.8504 Tj
--525 TJm
-(ho) 9.9626 Tj
-25 TJm
-(w) 7.193 Tj
--524 TJm
-(much) 22.1369 Tj
--525 TJm
-(output) 25.4644 Tj
--524 TJm
-(space) 22.1269 Tj
--525 TJm
-(is) 6.64505 Tj
--525 TJm
-(a) 4.42339 Tj
-20 TJm
-(v) 4.9813 Tj
-25 TJm
-(ailable.) 29.0509 Tj
-[1 0 0 1 285.792 382.09] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -285.792 -382.09] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-285.792 382.09 Td
-/F134_0 9.9626 Tf
-(BZ2_bzCompress) 83.6858 Tj
-[1 0 0 1 369.478 382.09] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -369.478 -382.09] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-374.705 382.09 Td
-/F130_0 9.9626 Tf
-(updates) 30.4357 Tj
-[1 0 0 1 410.367 382.09] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -410.367 -382.09] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-410.367 382.09 Td
-/F134_0 9.9626 Tf
-(next_out) 47.8205 Tj
-[1 0 0 1 458.188 382.09] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -458.188 -382.09] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-458.188 382.09 Td
-/F130_0 9.9626 Tf
-(,) 2.49065 Tj
-[1 0 0 1 466.589 382.09] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -466.589 -382.09] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-466.589 382.09 Td
-/F134_0 9.9626 Tf
-(avail_out) 53.798 Tj
-[1 0 0 1 520.387 382.09] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -520.387 -382.09] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-525.614 382.09 Td
-/F130_0 9.9626 Tf
-(and) 14.386 Tj
-[1 0 0 1 72 370.135] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -370.135] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 370.135 Td
-/F134_0 9.9626 Tf
-(total_out) 53.798 Tj
-[1 0 0 1 125.798 370.135] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -125.798 -370.135] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-128.289 370.135 Td
-/F130_0 9.9626 Tf
-(to) 7.7509 Tj
--250 TJm
-(re\003ect) 24.8965 Tj
--250 TJm
-(the) 12.1743 Tj
--250 TJm
-(number) 30.4357 Tj
--250 TJm
-(of) 8.29885 Tj
--250 TJm
-(bytes) 21.031 Tj
--250 TJm
-(output.) 27.9551 Tj
-[1 0 0 1 72 367.978] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.9626] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -358.015] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 348.217 Td
-/F130_0 9.9626 Tf
-(Y) 7.193 Tj
-110 TJm
-(ou) 9.9626 Tj
--320 TJm
-(may) 17.1556 Tj
--321 TJm
-(pro) 13.2801 Tj
-15 TJm
-(vide) 17.1556 Tj
--320 TJm
-(and) 14.386 Tj
--321 TJm
-(remo) 20.4731 Tj
-15 TJm
-(v) 4.9813 Tj
-15 TJm
-(e) 4.42339 Tj
--320 TJm
-(as) 8.29885 Tj
--321 TJm
-(little) 18.2714 Tj
--320 TJm
-(or) 8.29885 Tj
--320 TJm
-(as) 8.29885 Tj
--321 TJm
-(much) 22.1369 Tj
--320 TJm
-(data) 16.5977 Tj
--321 TJm
-(as) 8.29885 Tj
--320 TJm
-(you) 14.9439 Tj
--321 TJm
-(lik) 10.5205 Tj
-10 TJm
-(e) 4.42339 Tj
--320 TJm
-(on) 9.9626 Tj
--320 TJm
-(each) 18.2515 Tj
--321 TJm
-(call) 14.386 Tj
--320 TJm
-(of) 8.29885 Tj
-[1 0 0 1 407.816 348.217] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -407.816 -348.217] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-407.816 348.217 Td
-/F134_0 9.9626 Tf
-(BZ2_bzDecompress) 95.641 Tj
-[1 0 0 1 503.457 348.217] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -503.457 -348.217] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-503.457 348.217 Td
-/F130_0 9.9626 Tf
-(.) 2.49065 Tj
--1043 TJm
-(In) 8.29885 Tj
--320 TJm
-(the) 12.1743 Tj
-72 336.262 Td
-(limit,) 21.32 Tj
--295 TJm
-(it) 5.53921 Tj
--286 TJm
-(is) 6.64505 Tj
--287 TJm
-(acceptable) 42.0422 Tj
--286 TJm
-(to) 7.7509 Tj
--286 TJm
-(supply) 26.5703 Tj
--286 TJm
-(and) 14.386 Tj
--287 TJm
-(remo) 20.4731 Tj
-15 TJm
-(v) 4.9813 Tj
-15 TJm
-(e) 4.42339 Tj
--286 TJm
-(data) 16.5977 Tj
--286 TJm
-(one) 14.386 Tj
--286 TJm
-(byte) 17.1556 Tj
--287 TJm
-(at) 7.193 Tj
--286 TJm
-(a) 4.42339 Tj
--286 TJm
-(time,) 20.2042 Tj
--295 TJm
-(although) 34.8691 Tj
--286 TJm
-(this) 14.396 Tj
--287 TJm
-(w) 7.193 Tj
-10 TJm
-(ould) 17.7135 Tj
--286 TJm
-(be) 9.40469 Tj
--286 TJm
-(terribly) 29.3299 Tj
--286 TJm
-(inef) 15.4918 Tj
-25 TJm
-(\002cient.) 27.3972 Tj
--838 TJm
-(Y) 7.193 Tj
-110 TJm
-(ou) 9.9626 Tj
-72 324.306 Td
-(should) 26.5703 Tj
--250 TJm
-(al) 7.193 Tj
-10 TJm
-(w) 7.193 Tj
-10 TJm
-(ays) 13.2801 Tj
--250 TJm
-(ensure) 26.0024 Tj
--250 TJm
-(that) 14.9439 Tj
--250 TJm
-(at) 7.193 Tj
--250 TJm
-(least) 18.2614 Tj
--250 TJm
-(one) 14.386 Tj
--250 TJm
-(byte) 17.1556 Tj
--250 TJm
-(of) 8.29885 Tj
--250 TJm
-(output) 25.4644 Tj
--250 TJm
-(space) 22.1269 Tj
--250 TJm
-(is) 6.64505 Tj
--250 TJm
-(a) 4.42339 Tj
-20 TJm
-(v) 4.9813 Tj
-25 TJm
-(ailable) 26.5603 Tj
--250 TJm
-(at) 7.193 Tj
--250 TJm
-(each) 18.2515 Tj
--250 TJm
-(call.) 16.8766 Tj
-[1 0 0 1 72 322.15] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.9626] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -312.187] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 302.389 Td
-/F130_0 9.9626 Tf
-(Use) 15.4918 Tj
--250 TJm
-(of) 8.29885 Tj
-[1 0 0 1 100.772 302.389] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -100.772 -302.389] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-100.772 302.389 Td
-/F134_0 9.9626 Tf
-(BZ2_bzDecompress) 95.641 Tj
-[1 0 0 1 196.413 302.389] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -196.413 -302.389] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-198.904 302.389 Td
-/F130_0 9.9626 Tf
-(is) 6.64505 Tj
--250 TJm
-(simpler) 29.8878 Tj
--250 TJm
-(than) 17.1556 Tj
-[1 0 0 1 260.064 302.389] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -260.064 -302.389] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-260.064 302.389 Td
-/F134_0 9.9626 Tf
-(BZ2_bzCompress) 83.6858 Tj
-[1 0 0 1 343.75 302.389] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -343.75 -302.389] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-343.75 302.389 Td
-/F130_0 9.9626 Tf
-(.) 2.49065 Tj
-[1 0 0 1 72 300.232] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.9626] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -290.269] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 280.471 Td
-/F130_0 9.9626 Tf
-(Y) 7.193 Tj
-110 TJm
-(ou) 9.9626 Tj
--346 TJm
-(should) 26.5703 Tj
--347 TJm
-(pro) 13.2801 Tj
-15 TJm
-(vide) 17.1556 Tj
--346 TJm
-(input) 20.4831 Tj
--346 TJm
-(and) 14.386 Tj
--346 TJm
-(remo) 20.4731 Tj
-15 TJm
-(v) 4.9813 Tj
-15 TJm
-(e) 4.42339 Tj
--347 TJm
-(output) 25.4644 Tj
--346 TJm
-(as) 8.29885 Tj
--346 TJm
-(described) 38.1767 Tj
--346 TJm
-(abo) 14.386 Tj
-15 TJm
-(v) 4.9813 Tj
-15 TJm
-(e,) 6.91404 Tj
--371 TJm
-(and) 14.386 Tj
--346 TJm
-(repeatedly) 41.4942 Tj
--346 TJm
-(call) 14.386 Tj
-[1 0 0 1 422.638 280.471] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -422.638 -280.471] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-422.638 280.471 Td
-/F134_0 9.9626 Tf
-(BZ2_bzDecompress) 95.641 Tj
-[1 0 0 1 518.279 280.471] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -518.279 -280.471] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-521.729 280.471 Td
-/F130_0 9.9626 Tf
-(until) 18.2714 Tj
-[1 0 0 1 72 268.516] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -268.516] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 268.516 Td
-/F134_0 9.9626 Tf
-(BZ_STREAM_END) 77.7083 Tj
-[1 0 0 1 149.709 268.516] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -149.709 -268.516] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-152.314 268.516 Td
-/F130_0 9.9626 Tf
-(is) 6.64505 Tj
--262 TJm
-(returned.) 35.686 Tj
--344 TJm
-(Appearance) 47.5714 Tj
--262 TJm
-(of) 8.29885 Tj
-[1 0 0 1 261.767 268.516] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -261.767 -268.516] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-261.767 268.516 Td
-/F134_0 9.9626 Tf
-(BZ_STREAM_END) 77.7083 Tj
-[1 0 0 1 339.475 268.516] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -339.475 -268.516] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-342.081 268.516 Td
-/F130_0 9.9626 Tf
-(denotes) 30.4357 Tj
--262 TJm
-(that) 14.9439 Tj
-[1 0 0 1 392.672 268.516] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -392.672 -268.516] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-392.672 268.516 Td
-/F134_0 9.9626 Tf
-(BZ2_bzDecompress) 95.641 Tj
-[1 0 0 1 488.313 268.516] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -488.313 -268.516] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-490.919 268.516 Td
-/F130_0 9.9626 Tf
-(has) 13.2801 Tj
--262 TJm
-(detected) 33.1954 Tj
-72 256.561 Td
-(the) 12.1743 Tj
--212 TJm
-(logical) 27.1182 Tj
--212 TJm
-(end) 14.386 Tj
--211 TJm
-(of) 8.29885 Tj
--212 TJm
-(the) 12.1743 Tj
--212 TJm
-(compressed) 47.0334 Tj
--212 TJm
-(stream.) 29.0509 Tj
-[1 0 0 1 237.858 256.561] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -237.858 -256.561] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-237.858 256.561 Td
-/F134_0 9.9626 Tf
-(BZ2_bzDecompress) 95.641 Tj
-[1 0 0 1 333.499 256.561] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -333.499 -256.561] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-335.609 256.561 Td
-/F130_0 9.9626 Tf
-(will) 15.5018 Tj
--212 TJm
-(not) 12.7322 Tj
--212 TJm
-(produce) 32.0895 Tj
-[1 0 0 1 402.263 256.561] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -402.263 -256.561] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-402.263 256.561 Td
-/F134_0 9.9626 Tf
-(BZ_STREAM_END) 77.7083 Tj
-[1 0 0 1 479.972 256.561] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -479.972 -256.561] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-482.082 256.561 Td
-/F130_0 9.9626 Tf
-(until) 18.2714 Tj
--212 TJm
-(all) 9.9626 Tj
--212 TJm
-(output) 25.4644 Tj
-72 244.605 Td
-(data) 16.5977 Tj
--256 TJm
-(has) 13.2801 Tj
--256 TJm
-(been) 18.8094 Tj
--255 TJm
-(placed) 26.0024 Tj
--256 TJm
-(into) 15.5018 Tj
--256 TJm
-(the) 12.1743 Tj
--256 TJm
-(output) 25.4644 Tj
--256 TJm
-(b) 4.9813 Tj
-20 TJm
-(uf) 8.29885 Tj
-25 TJm
-(fer) 11.0585 Tj
-40 TJm
-(,) 2.49065 Tj
--257 TJm
-(so) 8.85675 Tj
--256 TJm
-(once) 18.8094 Tj
-[1 0 0 1 278.978 244.605] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -278.978 -244.605] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-278.978 244.605 Td
-/F134_0 9.9626 Tf
-(BZ_STREAM_END) 77.7083 Tj
-[1 0 0 1 356.687 244.605] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -356.687 -244.605] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-359.236 244.605 Td
-/F130_0 9.9626 Tf
-(appears,) 32.9164 Tj
--257 TJm
-(you) 14.9439 Tj
--256 TJm
-(are) 12.1643 Tj
--256 TJm
-(guaranteed) 43.7059 Tj
--256 TJm
-(to) 7.7509 Tj
--256 TJm
-(ha) 9.40469 Tj
-20 TJm
-(v) 4.9813 Tj
-15 TJm
-(e) 4.42339 Tj
--255 TJm
-(a) 4.42339 Tj
-20 TJm
-(v) 4.9813 Tj
-25 TJm
-(ailable) 26.5603 Tj
-72 232.65 Td
-(all) 9.9626 Tj
--250 TJm
-(the) 12.1743 Tj
--250 TJm
-(decompressed) 56.4381 Tj
--250 TJm
-(output,) 27.9551 Tj
--250 TJm
-(and) 14.386 Tj
-[1 0 0 1 205.369 232.65] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -205.369 -232.65] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-205.369 232.65 Td
-/F134_0 9.9626 Tf
-(BZ2_bzDecompressEnd) 113.574 Tj
-[1 0 0 1 318.943 232.65] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -318.943 -232.65] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-321.433 232.65 Td
-/F130_0 9.9626 Tf
-(can) 13.8281 Tj
--250 TJm
-(safely) 23.7907 Tj
--250 TJm
-(be) 9.40469 Tj
--250 TJm
-(called.) 26.2813 Tj
-[1 0 0 1 72 230.493] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.9626] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -220.531] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 210.732 Td
-/F130_0 9.9626 Tf
-(If) 6.63509 Tj
--250 TJm
-(case) 17.1456 Tj
--250 TJm
-(of) 8.29885 Tj
--250 TJm
-(an) 9.40469 Tj
--250 TJm
-(error) 19.3573 Tj
--250 TJm
-(return) 23.7907 Tj
--250 TJm
-(v) 4.9813 Tj
-25 TJm
-(alue,) 19.0883 Tj
--250 TJm
-(you) 14.9439 Tj
--250 TJm
-(should) 26.5703 Tj
--250 TJm
-(call) 14.386 Tj
-[1 0 0 1 261.259 210.732] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -261.259 -210.732] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-261.259 210.732 Td
-/F134_0 9.9626 Tf
-(BZ2_bzDecompressEnd) 113.574 Tj
-[1 0 0 1 374.833 210.732] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -374.833 -210.732] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-377.323 210.732 Td
-/F130_0 9.9626 Tf
-(to) 7.7509 Tj
--250 TJm
-(clean) 21.0211 Tj
--250 TJm
-(up) 9.9626 Tj
--250 TJm
-(and) 14.386 Tj
--250 TJm
-(release) 27.6562 Tj
--250 TJm
-(memory) 33.2053 Tj
-65 TJm
-(.) 2.49065 Tj
-[1 0 0 1 72 208.576] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.9626] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -198.613] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 188.815 Td
-/F130_0 9.9626 Tf
-(Possible) 33.2153 Tj
--250 TJm
-(return) 23.7907 Tj
--250 TJm
-(v) 4.9813 Tj
-25 TJm
-(alues:) 23.2427 Tj
-[1 0 0 1 72 188.715] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -137.863] cm
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-[1 0 0 1 1.8929 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 374.394 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 6.8541] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 40.5726 -6.7545] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -493.841 -50.9514] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-534.414 50.9514 Td
-/F130_0 9.9626 Tf
-(17) 9.9626 Tj
-[1 0 0 1 453.269 50.8518] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 93.5985 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 6.2765 0] cm
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-[1 0 0 1 -13.1436 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-Q
-showpage
-%%PageTrailer
-pdfEndPage
-%%Page: 21 21
-%%BeginPageSetup
-%%PageOrientation: Portrait
-pdfStartPage
-0 0 612 792 re W
-%%EndPageSetup
-[] 0 d
-1 i
-0 j
-0 J
-10 M
-1 w
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-false op
-false OP
-0 0 612 792 re
-W
-q
-[1 0 0 1 72 741.554] cm
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-[1 0 0 1 1.8929 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 14.4459] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 187.197 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 -8.9114] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 8.9114] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 76.4979 -6.7546] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -342.569 -749.245] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-419.067 749.245 Td
-/F130_0 9.9626 Tf
-(Programming) 54.7943 Tj
--250 TJm
-(with) 17.7135 Tj
-[1 0 0 1 496.556 749.245] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -496.556 -749.245] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-496.556 749.245 Td
-/F134_0 9.9626 Tf
-(libbzip2) 47.8205 Tj
-[1 0 0 1 544.376 749.245] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -278.305 -2.1568] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 280.796 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -472.974 -5.0363] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -0.4981] cm
-q
-[] 0 d
-0 J
-0.4981 w
-0 0.2491 m
-475.465 0.2491 l
-S
-Q
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 479.251 0] cm
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-[1 0 0 1 -13.1436 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -468 -200.882] cm
-/DeviceRGB {} cs
-[0.94899 0.94899 0.976456] sc
-/DeviceRGB {} CS
-[0.94899 0.94899 0.976456] SC
-0 0 468 179.328 re
-f
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 3.5866] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 175.741] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 18 -8.3686] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -90 -711.631] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-90 711.631 Td
-/F134_0 9.9626 Tf
-(BZ_PARAM_ERROR) 83.6858 Tj
-98.4879 699.676 Td
-(if) 11.9551 Tj
--426 TJm
-(strm) 23.9102 Tj
--426 TJm
-(is) 11.9551 Tj
--426 TJm
-(NULL) 23.9102 Tj
--426 TJm
-(or) 11.9551 Tj
--426 TJm
-(strm->s) 41.8429 Tj
--426 TJm
-(is) 11.9551 Tj
--426 TJm
-(NULL) 23.9102 Tj
-98.4879 687.721 Td
-(or) 11.9551 Tj
--426 TJm
-(strm->avail_out) 89.6634 Tj
--426 TJm
-(<) 5.97756 Tj
--426 TJm
-(1) 5.97756 Tj
-90 675.766 Td
-(BZ_DATA_ERROR) 77.7083 Tj
-98.4879 663.811 Td
-(if) 11.9551 Tj
--426 TJm
-(a) 5.97756 Tj
--426 TJm
-(data) 23.9102 Tj
--426 TJm
-(integrity) 53.798 Tj
--426 TJm
-(error) 29.8878 Tj
--426 TJm
-(is) 11.9551 Tj
--426 TJm
-(detected) 47.8205 Tj
--426 TJm
-(in) 11.9551 Tj
--426 TJm
-(the) 17.9327 Tj
--426 TJm
-(compressed) 59.7756 Tj
--426 TJm
-(stream) 35.8654 Tj
-90 651.856 Td
-(BZ_DATA_ERROR_MAGIC) 113.574 Tj
-98.4879 639.9 Td
-(if) 11.9551 Tj
--426 TJm
-(the) 17.9327 Tj
--426 TJm
-(compressed) 59.7756 Tj
--426 TJm
-(stream) 35.8654 Tj
--426 TJm
-(doesn't) 41.8429 Tj
--426 TJm
-(begin) 29.8878 Tj
--426 TJm
-(with) 23.9102 Tj
--426 TJm
-(the) 17.9327 Tj
--426 TJm
-(right) 29.8878 Tj
--426 TJm
-(magic) 29.8878 Tj
--426 TJm
-(bytes) 29.8878 Tj
-90 627.945 Td
-(BZ_MEM_ERROR) 71.7307 Tj
-98.4879 615.99 Td
-(if) 11.9551 Tj
--426 TJm
-(there) 29.8878 Tj
--426 TJm
-(wasn't) 35.8654 Tj
--426 TJm
-(enough) 35.8654 Tj
--426 TJm
-(memory) 35.8654 Tj
--426 TJm
-(available) 53.798 Tj
-90 604.035 Td
-(BZ_STREAM_END) 77.7083 Tj
-98.4879 592.08 Td
-(if) 11.9551 Tj
--426 TJm
-(the) 17.9327 Tj
--426 TJm
-(logical) 41.8429 Tj
--426 TJm
-(end) 17.9327 Tj
--426 TJm
-(of) 11.9551 Tj
--426 TJm
-(the) 17.9327 Tj
--426 TJm
-(data) 23.9102 Tj
--426 TJm
-(stream) 35.8654 Tj
--426 TJm
-(was) 17.9327 Tj
--426 TJm
-(detected) 47.8205 Tj
--426 TJm
-(and) 17.9327 Tj
--426 TJm
-(all) 17.9327 Tj
-98.4879 580.125 Td
-(output) 35.8654 Tj
--426 TJm
-(in) 11.9551 Tj
--426 TJm
-(has) 17.9327 Tj
--426 TJm
-(been) 23.9102 Tj
--426 TJm
-(consumed,) 53.798 Tj
--426 TJm
-(eg) 11.9551 Tj
--426 TJm
-(s-->avail_out) 77.7083 Tj
--426 TJm
-(>) 5.97756 Tj
--426 TJm
-(0) 5.97756 Tj
-90 568.169 Td
-(BZ_OK) 29.8878 Tj
-98.4879 556.214 Td
-(otherwise) 53.798 Tj
-[1 0 0 1 72 540.673] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 468 3.5866] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -468 -13.5492] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -530.71] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 518.755 Td
-/F130_0 9.9626 Tf
-(Allo) 17.7135 Tj
-25 TJm
-(w) 7.193 Tj
-10 TJm
-(able) 16.5977 Tj
--250 TJm
-(ne) 9.40469 Tj
-15 TJm
-(xt) 7.7509 Tj
--250 TJm
-(actions:) 30.9936 Tj
-[1 0 0 1 72 518.655] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -60.7721] cm
-/DeviceRGB {} cs
-[0.94899 0.94899 0.976456] sc
-/DeviceRGB {} CS
-[0.94899 0.94899 0.976456] SC
-0 0 468 59.7758 re
-f
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 3.5866] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 56.1892] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 18 -8.3686] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -90 -509.29] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-90 509.29 Td
-/F134_0 9.9626 Tf
-(BZ2_bzDecompress) 95.641 Tj
-98.4879 497.335 Td
-(if) 11.9551 Tj
--426 TJm
-(BZ_OK) 29.8878 Tj
--426 TJm
-(was) 17.9327 Tj
--426 TJm
-(returned) 47.8205 Tj
-90 485.38 Td
-(BZ2_bzDecompressEnd) 113.574 Tj
-98.4879 473.425 Td
-(otherwise) 53.798 Tj
-[1 0 0 1 72 457.883] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 468 3.5866] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -468 -3.5866] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.9626] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -447.92] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 427.262 Td
-/F122_0 17.2154 Tf
-(3.3.6.) 43.0729 Tj
-[1 0 0 1 119.858 427.262] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -119.858 -427.262] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-119.858 427.262 Td
-/F392_0 17.2154 Tf
-(BZ2_bzDecompressEnd) 196.256 Tj
-[1 0 0 1 316.114 427.262] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -244.114 -2.3326] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -24.9066] cm
-/DeviceRGB {} cs
-[0.94899 0.94899 0.976456] sc
-/DeviceRGB {} CS
-[0.94899 0.94899 0.976456] SC
-0 0 468 23.9103 re
-f
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 3.5866] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 20.3237] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 18 -8.3686] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -90 -415.564] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-90 415.564 Td
-/F134_0 9.9626 Tf
-(int) 17.9327 Tj
--426 TJm
-(BZ2_bzDecompressEnd) 113.574 Tj
--426 TJm
-(\() 5.97756 Tj
--426 TJm
-(bz_stream) 53.798 Tj
-298.259 413.821 Td
-(*) 5.97756 Tj
-304.236 415.564 Td
-(strm) 23.9102 Tj
--426 TJm
-(\);) 11.9551 Tj
-[1 0 0 1 72 400.023] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 468 3.5866] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -468 -13.5492] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -390.06] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 378.105 Td
-/F130_0 9.9626 Tf
-(Releases) 34.8591 Tj
--250 TJm
-(all) 9.9626 Tj
--250 TJm
-(memory) 33.2053 Tj
--250 TJm
-(associated) 40.9463 Tj
--250 TJm
-(with) 17.7135 Tj
--250 TJm
-(a) 4.42339 Tj
--250 TJm
-(decompression) 59.7656 Tj
--250 TJm
-(stream.) 29.0509 Tj
-[1 0 0 1 72 375.948] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.9627] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -365.985] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 356.187 Td
-/F130_0 9.9626 Tf
-(Possible) 33.2153 Tj
--250 TJm
-(return) 23.7907 Tj
--250 TJm
-(v) 4.9813 Tj
-25 TJm
-(alues:) 23.2427 Tj
-[1 0 0 1 72 356.087] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -60.7721] cm
-/DeviceRGB {} cs
-[0.94899 0.94899 0.976456] sc
-/DeviceRGB {} CS
-[0.94899 0.94899 0.976456] SC
-0 0 468 59.7758 re
-f
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 3.5866] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 56.1893] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 18 -8.3686] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -90 -346.723] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-90 346.723 Td
-/F134_0 9.9626 Tf
-(BZ_PARAM_ERROR) 83.6858 Tj
-98.4879 334.767 Td
-(if) 11.9551 Tj
--426 TJm
-(strm) 23.9102 Tj
--426 TJm
-(is) 11.9551 Tj
--426 TJm
-(NULL) 23.9102 Tj
--426 TJm
-(or) 11.9551 Tj
--426 TJm
-(strm->s) 41.8429 Tj
--426 TJm
-(is) 11.9551 Tj
--426 TJm
-(NULL) 23.9102 Tj
-90 322.812 Td
-(BZ_OK) 29.8878 Tj
-98.4879 310.857 Td
-(otherwise) 53.798 Tj
-[1 0 0 1 72 295.315] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 468 3.5866] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -468 -13.5492] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -285.353] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 273.397 Td
-/F130_0 9.9626 Tf
-(Allo) 17.7135 Tj
-25 TJm
-(w) 7.193 Tj
-10 TJm
-(able) 16.5977 Tj
--250 TJm
-(ne) 9.40469 Tj
-15 TJm
-(xt) 7.7509 Tj
--250 TJm
-(actions:) 30.9936 Tj
-[1 0 0 1 72 273.298] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -24.9066] cm
-/DeviceRGB {} cs
-[0.94899 0.94899 0.976456] sc
-/DeviceRGB {} CS
-[0.94899 0.94899 0.976456] SC
-0 0 468 23.9103 re
-f
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 3.5866] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 20.3237] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 18 -8.3686] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -90 -263.933] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-98.4879 263.933 Td
-/F134_0 9.9626 Tf
-(None.) 29.8878 Tj
-[1 0 0 1 72 248.391] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 468 3.5866] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -468 -3.5866] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.9626] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -238.429] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 213.639 Td
-/F122_0 20.6585 Tf
-(3.4.) 34.4584 Tj
--278 TJm
-(High-le) 70.0117 Tj
-15 TJm
-(vel) 28.7153 Tj
--278 TJm
-(interface) 86.1046 Tj
-[1 0 0 1 72 209.042] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.9626] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -199.08] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 191.721 Td
-/F130_0 9.9626 Tf
-(This) 17.7135 Tj
--250 TJm
-(interf) 21.579 Tj
-10 TJm
-(ace) 13.2702 Tj
--250 TJm
-(pro) 13.2801 Tj
-15 TJm
-(vides) 21.031 Tj
--250 TJm
-(functions) 37.0808 Tj
--250 TJm
-(for) 11.6164 Tj
--250 TJm
-(reading) 29.8778 Tj
--250 TJm
-(and) 14.386 Tj
--250 TJm
-(writing) 28.782 Tj
-[1 0 0 1 300.292 191.721] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -300.292 -191.721] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-300.292 191.721 Td
-/F134_0 9.9626 Tf
-(bzip2) 29.8878 Tj
-[1 0 0 1 330.18 191.721] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -330.18 -191.721] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-332.67 191.721 Td
-/F130_0 9.9626 Tf
-(format) 26.5603 Tj
--250 TJm
-(\002les.) 19.0983 Tj
--620 TJm
-(First,) 20.7621 Tj
--250 TJm
-(some) 21.031 Tj
--250 TJm
-(general) 29.3199 Tj
--250 TJm
-(points.) 26.8492 Tj
-[1 0 0 1 72 189.564] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -29.7236] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 6.9739 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -78.9739 -159.84] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-78.9739 159.84 Td
-/F130_0 9.9626 Tf
-(\225) 3.48691 Tj
-[1 0 0 1 82.4608 159.84] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 1.9925 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -86.944 -159.84] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-86.944 159.84 Td
-/F130_0 9.9626 Tf
-(All) 12.7322 Tj
--332 TJm
-(of) 8.29885 Tj
--331 TJm
-(the) 12.1743 Tj
--332 TJm
-(functions) 37.0808 Tj
--332 TJm
-(tak) 12.1743 Tj
-10 TJm
-(e) 4.42339 Tj
--331 TJm
-(an) 9.40469 Tj
-[1 0 0 1 202.958 159.84] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -202.958 -159.84] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-202.958 159.84 Td
-/F134_0 9.9626 Tf
-(int) 17.9327 Tj
-220.891 158.097 Td
-(*) 5.97756 Tj
-[1 0 0 1 226.868 159.84] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -226.868 -159.84] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-230.172 159.84 Td
-/F130_0 9.9626 Tf
-(\002rst) 15.5018 Tj
--332 TJm
-(ar) 7.74094 Tj
-18 TJm
-(gument,) 32.3785 Tj
-[1 0 0 1 292.426 159.84] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -292.426 -159.84] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-292.426 159.84 Td
-/F134_0 9.9626 Tf
-(bzerror) 41.8429 Tj
-[1 0 0 1 334.269 159.84] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -334.269 -159.84] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-334.269 159.84 Td
-/F130_0 9.9626 Tf
-(.) 2.49065 Tj
--1110 TJm
-(After) 21.0211 Tj
--332 TJm
-(each) 18.2515 Tj
--331 TJm
-(call,) 16.8766 Tj
-[1 0 0 1 414.083 159.84] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -414.083 -159.84] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-414.083 159.84 Td
-/F134_0 9.9626 Tf
-(bzerror) 41.8429 Tj
-[1 0 0 1 455.926 159.84] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -455.926 -159.84] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-459.23 159.84 Td
-/F130_0 9.9626 Tf
-(should) 26.5703 Tj
--332 TJm
-(be) 9.40469 Tj
--331 TJm
-(consulted) 38.1866 Tj
-86.944 147.885 Td
-(\002rst) 15.5018 Tj
--349 TJm
-(to) 7.7509 Tj
--349 TJm
-(determine) 39.8404 Tj
--348 TJm
-(the) 12.1743 Tj
--349 TJm
-(outcome) 34.3112 Tj
--349 TJm
-(of) 8.29885 Tj
--349 TJm
-(the) 12.1743 Tj
--348 TJm
-(call.) 16.8766 Tj
--1213 TJm
-(If) 6.63509 Tj
-[1 0 0 1 280.386 147.885] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -280.386 -147.885] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-280.386 147.885 Td
-/F134_0 9.9626 Tf
-(bzerror) 41.8429 Tj
-[1 0 0 1 322.229 147.885] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -322.229 -147.885] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-325.704 147.885 Td
-/F130_0 9.9626 Tf
-(is) 6.64505 Tj
-[1 0 0 1 335.824 147.885] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -335.824 -147.885] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-335.824 147.885 Td
-/F134_0 9.9626 Tf
-(BZ_OK) 29.8878 Tj
-[1 0 0 1 365.711 147.885] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -365.711 -147.885] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-365.711 147.885 Td
-/F130_0 9.9626 Tf
-(,) 2.49065 Tj
--349 TJm
-(the) 12.1743 Tj
--349 TJm
-(call) 14.386 Tj
--348 TJm
-(completed) 41.5042 Tj
--349 TJm
-(successfully) 48.6972 Tj
-65 TJm
-(,) 2.49065 Tj
--374 TJm
-(and) 14.386 Tj
--348 TJm
-(only) 17.7135 Tj
-86.944 135.93 Td
-(then) 17.1556 Tj
--271 TJm
-(should) 26.5703 Tj
--270 TJm
-(the) 12.1743 Tj
--271 TJm
-(return) 23.7907 Tj
--270 TJm
-(v) 4.9813 Tj
-25 TJm
-(alue) 16.5977 Tj
--271 TJm
-(of) 8.29885 Tj
--271 TJm
-(the) 12.1743 Tj
--270 TJm
-(function) 33.2053 Tj
--271 TJm
-(\(if) 9.40469 Tj
--270 TJm
-(an) 9.40469 Tj
-15 TJm
-(y\)) 8.29885 Tj
--271 TJm
-(be) 9.40469 Tj
--271 TJm
-(cons) 18.2614 Tj
-1 TJm
-(u) 4.9813 Tj
--1 TJm
-(l) 2.7696 Tj
-1 TJm
-(ted.) 14.6649 Tj
--744 TJm
-(If) 6.63509 Tj
-[1 0 0 1 365.077 135.93] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -365.077 -135.93] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-365.077 135.93 Td
-/F134_0 9.9626 Tf
-(bzerror) 41.8429 Tj
-[1 0 0 1 406.92 135.93] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -406.92 -135.93] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-409.616 135.93 Td
-/F130_0 9.9626 Tf
-(is) 6.64505 Tj
-[1 0 0 1 418.956 135.93] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -418.956 -135.93] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-418.956 135.93 Td
-/F134_0 9.9626 Tf
-(BZ_IO_ERROR) 65.7532 Tj
-[1 0 0 1 484.71 135.93] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -484.71 -135.93] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-484.71 135.93 Td
-/F130_0 9.9626 Tf
-(,) 2.49065 Tj
--271 TJm
-(there) 19.9152 Tj
--270 TJm
-(w) 7.193 Tj
-10 TJm
-(as) 8.29885 Tj
--271 TJm
-(an) 9.40469 Tj
-86.944 123.975 Td
-(error) 19.3573 Tj
--246 TJm
-(reading/writing) 61.4294 Tj
--245 TJm
-(the) 12.1743 Tj
--246 TJm
-(underlying) 43.1679 Tj
--246 TJm
-(compressed) 47.0334 Tj
--245 TJm
-(\002le,) 15.2229 Tj
--247 TJm
-(and) 14.386 Tj
--245 TJm
-(you) 14.9439 Tj
--246 TJm
-(should) 26.5703 Tj
--246 TJm
-(then) 17.1556 Tj
--245 TJm
-(consult) 28.782 Tj
-[1 0 0 1 414.096 123.975] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -414.096 -123.975] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-414.096 123.975 Td
-/F134_0 9.9626 Tf
-(errno) 29.8878 Tj
-[1 0 0 1 443.984 123.975] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -443.984 -123.975] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-446.432 123.975 Td
-/F130_0 9.9626 Tf
-(/) 2.7696 Tj
-[1 0 0 1 451.649 123.975] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -451.649 -123.975] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-451.649 123.975 Td
-/F134_0 9.9626 Tf
-(perror) 35.8654 Tj
-[1 0 0 1 487.514 123.975] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -487.514 -123.975] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-489.962 123.975 Td
-/F130_0 9.9626 Tf
-(to) 7.7509 Tj
--246 TJm
-(determine) 39.8404 Tj
-86.944 112.02 Td
-(the) 12.1743 Tj
--356 TJm
-(cause) 22.1269 Tj
--356 TJm
-(of) 8.29885 Tj
--355 TJm
-(the) 12.1743 Tj
--356 TJm
-(dif) 11.0684 Tj
-25 TJm
-(\002culty) 25.4644 Tj
-65 TJm
-(.) 2.49065 Tj
-[1 0 0 1 206.528 112.02] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -206.528 -112.02] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-206.528 112.02 Td
-/F134_0 9.9626 Tf
-(bzerror) 41.8429 Tj
-[1 0 0 1 248.371 112.02] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -248.371 -112.02] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-251.916 112.02 Td
-/F130_0 9.9626 Tf
-(may) 17.1556 Tj
--356 TJm
-(also) 16.0497 Tj
--356 TJm
-(be) 9.40469 Tj
--355 TJm
-(set) 11.0684 Tj
--356 TJm
-(to) 7.7509 Tj
--356 TJm
-(v) 4.9813 Tj
-25 TJm
-(arious) 24.3486 Tj
--356 TJm
-(other) 20.4731 Tj
--356 TJm
-(v) 4.9813 Tj
-25 TJm
-(alues;) 23.2427 Tj
--408 TJm
-(precise) 28.2141 Tj
--356 TJm
-(details) 26.0123 Tj
--356 TJm
-(are) 12.1643 Tj
--356 TJm
-(gi) 7.7509 Tj
-25 TJm
-(v) 4.9813 Tj
-15 TJm
-(en) 9.40469 Tj
--356 TJm
-(on) 9.9626 Tj
--356 TJm
-(a) 4.42339 Tj
-86.944 100.064 Td
-(per) 12.7222 Tj
-20 TJm
-(-function) 36.5229 Tj
--250 TJm
-(basis) 19.9252 Tj
--250 TJm
-(belo) 17.1556 Tj
-25 TJm
-(w) 7.193 Tj
-65 TJm
-(.) 2.49065 Tj
-[1 0 0 1 186.839 100.064] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -114.838 -49.2126] cm
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-[1 0 0 1 1.8929 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 374.394 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 6.8541] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 40.5726 -6.7545] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -493.841 -50.9514] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-534.414 50.9514 Td
-/F130_0 9.9626 Tf
-(18) 9.9626 Tj
-[1 0 0 1 453.269 50.8518] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 93.5985 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 6.2765 0] cm
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-[1 0 0 1 -13.1436 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-Q
-showpage
-%%PageTrailer
-pdfEndPage
-%%Page: 22 22
-%%BeginPageSetup
-%%PageOrientation: Portrait
-pdfStartPage
-0 0 612 792 re W
-%%EndPageSetup
-[] 0 d
-1 i
-0 j
-0 J
-10 M
-1 w
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-false op
-false OP
-0 0 612 792 re
-W
-q
-[1 0 0 1 72 741.554] cm
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-[1 0 0 1 1.8929 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 14.4459] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 187.197 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 -8.9114] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 8.9114] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 76.4979 -6.7546] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -342.569 -749.245] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-419.067 749.245 Td
-/F130_0 9.9626 Tf
-(Programming) 54.7943 Tj
--250 TJm
-(with) 17.7135 Tj
-[1 0 0 1 496.556 749.245] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -496.556 -749.245] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-496.556 749.245 Td
-/F134_0 9.9626 Tf
-(libbzip2) 47.8205 Tj
-[1 0 0 1 544.376 749.245] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -278.305 -2.1568] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 280.796 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -472.974 -5.0363] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -0.4981] cm
-q
-[] 0 d
-0 J
-0.4981 w
-0 0.2491 m
-475.465 0.2491 l
-S
-Q
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 479.251 0] cm
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-[1 0 0 1 -13.1436 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -468 -31.5168] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 6.9739 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -78.9739 -710.037] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-78.9739 710.037 Td
-/F130_0 9.9626 Tf
-(\225) 3.48691 Tj
-[1 0 0 1 82.4608 710.037] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 1.9925 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -86.944 -710.037] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-86.944 710.037 Td
-/F130_0 9.9626 Tf
-(If) 6.63509 Tj
-[1 0 0 1 95.9576 710.037] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -95.9576 -710.037] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-95.9576 710.037 Td
-/F134_0 9.9626 Tf
-(bzerror) 41.8429 Tj
-[1 0 0 1 137.801 710.037] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -137.801 -710.037] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-140.179 710.037 Td
-/F130_0 9.9626 Tf
-(indicates) 35.417 Tj
--239 TJm
-(an) 9.40469 Tj
--238 TJm
-(error) 19.3573 Tj
--239 TJm
-(\(ie,) 13.0012 Tj
--241 TJm
-(an) 9.40469 Tj
-15 TJm
-(ything) 25.4644 Tj
--239 TJm
-(e) 4.42339 Tj
-15 TJm
-(xcept) 21.579 Tj
-[1 0 0 1 292.225 710.037] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -292.225 -710.037] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-292.225 710.037 Td
-/F134_0 9.9626 Tf
-(BZ_OK) 29.8878 Tj
-[1 0 0 1 322.113 710.037] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -322.113 -710.037] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-324.492 710.037 Td
-/F130_0 9.9626 Tf
-(and) 14.386 Tj
-[1 0 0 1 341.256 710.037] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -341.256 -710.037] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-341.256 710.037 Td
-/F134_0 9.9626 Tf
-(BZ_STREAM_END) 77.7083 Tj
-[1 0 0 1 418.965 710.037] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -418.965 -710.037] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-418.965 710.037 Td
-/F130_0 9.9626 Tf
-(\),) 5.8082 Tj
--239 TJm
-(you) 14.9439 Tj
--239 TJm
-(should) 26.5703 Tj
--238 TJm
-(immediately) 49.813 Tj
--239 TJm
-(call) 14.386 Tj
-[1 0 0 1 86.944 698.082] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -86.944 -698.082] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-86.944 698.082 Td
-/F134_0 9.9626 Tf
-(BZ2_bzReadClose) 89.6634 Tj
-[1 0 0 1 176.608 698.082] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -176.608 -698.082] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-179.343 698.082 Td
-/F130_0 9.9626 Tf
-(\(or) 11.6164 Tj
-[1 0 0 1 193.695 698.082] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -193.695 -698.082] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-193.695 698.082 Td
-/F134_0 9.9626 Tf
-(BZ2_bzWriteClose) 95.641 Tj
-[1 0 0 1 289.337 698.082] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -289.337 -698.082] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-289.337 698.082 Td
-/F130_0 9.9626 Tf
-(,) 2.49065 Tj
--281 TJm
-(depending) 41.5042 Tj
--274 TJm
-(on) 9.9626 Tj
--275 TJm
-(whether) 32.0895 Tj
--274 TJm
-(you) 14.9439 Tj
--275 TJm
-(are) 12.1643 Tj
--275 TJm
-(attempting) 42.62 Tj
--274 TJm
-(to) 7.7509 Tj
--275 TJm
-(read) 17.1456 Tj
--274 TJm
-(or) 8.29885 Tj
--275 TJm
-(to) 7.7509 Tj
--274 TJm
-(write\)) 23.7907 Tj
-86.944 686.127 Td
-(to) 7.7509 Tj
--242 TJm
-(free) 15.4819 Tj
--242 TJm
-(up) 9.9626 Tj
--241 TJm
-(all) 9.9626 Tj
--242 TJm
-(resources) 37.6188 Tj
--242 TJm
-(associated) 40.9463 Tj
--242 TJm
-(wi) 9.9626 Tj
-1 TJm
-(th) 7.7509 Tj
--242 TJm
-(the) 12.1743 Tj
--242 TJm
-(stream.) 29.0509 Tj
--614 TJm
-(Once) 21.0211 Tj
--242 TJm
-(an) 9.40469 Tj
--242 TJm
-(error) 19.3573 Tj
--242 TJm
-(has) 13.2801 Tj
--242 TJm
-(been) 18.8094 Tj
--241 TJm
-(indicated,) 39.0135 Tj
--244 TJm
-(beha) 18.8094 Tj
-20 TJm
-(viour) 21.031 Tj
--241 TJm
-(of) 8.29885 Tj
--242 TJm
-(all) 9.9626 Tj
--242 TJm
-(calls) 18.2614 Tj
--242 TJm
-(e) 4.42339 Tj
-15 TJm
-(xcept) 21.579 Tj
-[1 0 0 1 86.944 674.172] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -86.944 -674.172] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-86.944 674.172 Td
-/F134_0 9.9626 Tf
-(BZ2_bzReadClose) 89.6634 Tj
-[1 0 0 1 176.608 674.172] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -176.608 -674.172] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-179.705 674.172 Td
-/F130_0 9.9626 Tf
-(\() 3.31755 Tj
-[1 0 0 1 183.022 674.172] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -183.022 -674.172] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-183.022 674.172 Td
-/F134_0 9.9626 Tf
-(BZ2_bzWriteClose) 95.641 Tj
-[1 0 0 1 278.664 674.172] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -278.664 -674.172] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-278.664 674.172 Td
-/F130_0 9.9626 Tf
-(\)) 3.31755 Tj
--311 TJm
-(is) 6.64505 Tj
--311 TJm
-(unde\002ned.) 41.7831 Tj
--985 TJm
-(The) 15.4918 Tj
--311 TJm
-(implication) 45.3896 Tj
--310 TJm
-(is) 6.64505 Tj
--311 TJm
-(that) 14.9439 Tj
--311 TJm
-(\(1\)) 11.6164 Tj
-[1 0 0 1 455.988 674.172] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -455.988 -674.172] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-455.988 674.172 Td
-/F134_0 9.9626 Tf
-(bzerror) 41.8429 Tj
-[1 0 0 1 497.831 674.172] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -497.831 -674.172] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-500.928 674.172 Td
-/F130_0 9.9626 Tf
-(should) 26.5703 Tj
--311 TJm
-(be) 9.40469 Tj
-86.944 662.217 Td
-(check) 23.2328 Tj
-10 TJm
-(ed) 9.40469 Tj
--291 TJm
-(after) 18.2515 Tj
--291 TJm
-(each) 18.2515 Tj
--291 TJm
-(call,) 16.8766 Tj
--301 TJm
-(and) 14.386 Tj
--291 TJm
-(\(2\)) 11.6164 Tj
--291 TJm
-(if) 6.08715 Tj
-[1 0 0 1 225.347 662.217] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -225.347 -662.217] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-225.347 662.217 Td
-/F134_0 9.9626 Tf
-(bzerror) 41.8429 Tj
-[1 0 0 1 267.19 662.217] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -267.19 -662.217] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-270.09 662.217 Td
-/F130_0 9.9626 Tf
-(indicates) 35.417 Tj
--291 TJm
-(an) 9.40469 Tj
--291 TJm
-(error) 19.3573 Tj
-40 TJm
-(,) 2.49065 Tj
-[1 0 0 1 345.161 662.217] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -345.161 -662.217] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-345.161 662.217 Td
-/F134_0 9.9626 Tf
-(BZ2_bzReadClose) 89.6634 Tj
-[1 0 0 1 434.824 662.217] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -434.824 -662.217] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-437.724 662.217 Td
-/F130_0 9.9626 Tf
-(\() 3.31755 Tj
-[1 0 0 1 441.041 662.217] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -441.041 -662.217] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-441.041 662.217 Td
-/F134_0 9.9626 Tf
-(BZ2_bzWriteClose) 95.641 Tj
-[1 0 0 1 536.683 662.217] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -536.683 -662.217] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-536.683 662.217 Td
-/F130_0 9.9626 Tf
-(\)) 3.31755 Tj
-86.944 650.262 Td
-(should) 26.5703 Tj
--250 TJm
-(then) 17.1556 Tj
--250 TJm
-(be) 9.40469 Tj
--250 TJm
-(called) 23.7907 Tj
--250 TJm
-(to) 7.7509 Tj
--250 TJm
-(clean) 21.0211 Tj
--250 TJm
-(up.) 12.4533 Tj
-[1 0 0 1 220.034 650.261] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -148.034 -21.9178] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 6.9739 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -78.9739 -628.344] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-78.9739 628.344 Td
-/F130_0 9.9626 Tf
-(\225) 3.48691 Tj
-[1 0 0 1 82.4608 628.344] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 1.9925 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -86.944 -628.344] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-86.944 628.344 Td
-/F130_0 9.9626 Tf
-(The) 15.4918 Tj
-[1 0 0 1 106.362 628.344] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -106.362 -628.344] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-106.362 628.344 Td
-/F134_0 9.9626 Tf
-(FILE) 23.9102 Tj
-130.273 626.6 Td
-(*) 5.97756 Tj
-[1 0 0 1 136.25 628.344] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -136.25 -628.344] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-140.177 628.344 Td
-/F130_0 9.9626 Tf
-(ar) 7.74094 Tj
-18 TJm
-(guments) 33.7633 Tj
--394 TJm
-(passed) 26.5603 Tj
--394 TJm
-(to) 7.7509 Tj
-[1 0 0 1 227.592 628.344] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -227.592 -628.344] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-227.592 628.344 Td
-/F134_0 9.9626 Tf
-(BZ2_bzReadOpen) 83.6858 Tj
-[1 0 0 1 311.278 628.344] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -311.278 -628.344] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-315.205 628.344 Td
-/F130_0 9.9626 Tf
-(/) 2.7696 Tj
-[1 0 0 1 321.901 628.344] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -321.901 -628.344] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-321.901 628.344 Td
-/F134_0 9.9626 Tf
-(BZ2_bzWriteOpen) 89.6634 Tj
-[1 0 0 1 411.565 628.344] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -411.565 -628.344] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-415.491 628.344 Td
-/F130_0 9.9626 Tf
-(should) 26.5703 Tj
--394 TJm
-(be) 9.40469 Tj
--394 TJm
-(set) 11.0684 Tj
--394 TJm
-(to) 7.7509 Tj
--394 TJm
-(binary) 25.4544 Tj
--395 TJm
-(mode.) 24.6275 Tj
-86.944 616.389 Td
-(Most) 20.4831 Tj
--229 TJm
-(Unix) 19.9252 Tj
--229 TJm
-(systems) 31.5516 Tj
--228 TJm
-(will) 15.5018 Tj
--229 TJm
-(do) 9.9626 Tj
--229 TJm
-(this) 14.396 Tj
--229 TJm
-(by) 9.9626 Tj
--229 TJm
-(def) 12.7222 Tj
-10 TJm
-(ault,) 17.4346 Tj
--233 TJm
-(b) 4.9813 Tj
-20 TJm
-(ut) 7.7509 Tj
--229 TJm
-(other) 20.4731 Tj
--229 TJm
-(platforms,) 40.6773 Tj
--233 TJm
-(including) 37.6387 Tj
--229 TJm
-(W) 9.40469 Tj
-40 TJm
-(indo) 17.7135 Tj
-25 TJm
-(ws) 11.0684 Tj
--228 TJm
-(and) 14.386 Tj
--229 TJm
-(Mac,) 20.1942 Tj
--233 TJm
-(will) 15.5018 Tj
--229 TJm
-(not.) 15.2229 Tj
--606 TJm
-(If) 6.63509 Tj
--229 TJm
-(you) 14.9439 Tj
--229 TJm
-(omit) 18.2714 Tj
-86.944 604.433 Td
-(this,) 16.8866 Tj
--250 TJm
-(you) 14.9439 Tj
--250 TJm
-(may) 17.1556 Tj
--250 TJm
-(encounter) 39.2825 Tj
--250 TJm
-(problems) 37.0808 Tj
--250 TJm
-(when) 21.579 Tj
--250 TJm
-(mo) 12.7322 Tj
-15 TJm
-(ving) 17.7135 Tj
--250 TJm
-(code) 18.8094 Tj
--250 TJm
-(to) 7.7509 Tj
--250 TJm
-(ne) 9.40469 Tj
-25 TJm
-(w) 7.193 Tj
--250 TJm
-(platforms.) 40.6773 Tj
-[1 0 0 1 372.66 604.433] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -300.66 -21.9178] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 6.9739 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -78.9739 -582.516] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-78.9739 582.516 Td
-/F130_0 9.9626 Tf
-(\225) 3.48691 Tj
-[1 0 0 1 82.4608 582.516] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 1.9925 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -86.944 -582.516] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-86.944 582.516 Td
-/F130_0 9.9626 Tf
-(Memory) 34.3112 Tj
--348 TJm
-(allocation) 39.2925 Tj
--348 TJm
-(requests) 32.6474 Tj
--348 TJm
-(are) 12.1643 Tj
--348 TJm
-(handled) 31.5416 Tj
--348 TJm
-(by) 9.9626 Tj
-[1 0 0 1 267.67 582.516] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -267.67 -582.516] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-267.67 582.516 Td
-/F134_0 9.9626 Tf
-(malloc) 35.8654 Tj
-[1 0 0 1 303.535 582.516] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -303.535 -582.516] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-307.003 582.516 Td
-/F130_0 9.9626 Tf
-(/) 2.7696 Tj
-[1 0 0 1 313.241 582.516] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -313.241 -582.516] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-313.241 582.516 Td
-/F134_0 9.9626 Tf
-(free) 23.9102 Tj
-[1 0 0 1 337.151 582.516] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -337.151 -582.516] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-337.151 582.516 Td
-/F130_0 9.9626 Tf
-(.) 2.49065 Tj
--1209 TJm
-(At) 9.9626 Tj
--348 TJm
-(present) 28.772 Tj
--348 TJm
-(there) 19.9152 Tj
--348 TJm
-(is) 6.64505 Tj
--348 TJm
-(no) 9.9626 Tj
--348 TJm
-(f) 3.31755 Tj
-10 TJm
-(acility) 24.9065 Tj
--348 TJm
-(for) 11.6164 Tj
--348 TJm
-(user) 16.5977 Tj
-20 TJm
-(-de\002ned) 32.6474 Tj
-86.944 570.56 Td
-(memory) 33.2053 Tj
--250 TJm
-(allocators) 38.7346 Tj
--250 TJm
-(in) 7.7509 Tj
--250 TJm
-(the) 12.1743 Tj
--250 TJm
-(\002le) 12.7322 Tj
--250 TJm
-(I/O) 13.2801 Tj
--250 TJm
-(functions) 37.0808 Tj
--250 TJm
-(\(could) 25.4544 Tj
--250 TJm
-(easily) 23.2427 Tj
--250 TJm
-(be) 9.40469 Tj
--250 TJm
-(added,) 26.2813 Tj
--250 TJm
-(though\).) 33.4843 Tj
-[1 0 0 1 387.165 570.56] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -315.165 -12.1195] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.9626] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -548.478] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 529.977 Td
-/F122_0 17.2154 Tf
-(3.4.1.) 43.0729 Tj
-[1 0 0 1 119.858 529.977] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -119.858 -529.977] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-119.858 529.977 Td
-/F392_0 17.2154 Tf
-(BZ2_bzReadOpen) 144.609 Tj
-[1 0 0 1 264.468 529.977] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -192.468 -2.3327] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -72.7272] cm
-/DeviceRGB {} cs
-[0.94899 0.94899 0.976456] sc
-/DeviceRGB {} CS
-[0.94899 0.94899 0.976456] SC
-0 0 468 71.731 re
-f
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 3.5866] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 68.1444] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 18 -8.3686] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -90 -518.279] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-90 518.279 Td
-/F134_0 9.9626 Tf
-(typedef) 41.8429 Tj
--426 TJm
-(void) 23.9102 Tj
--426 TJm
-(BZFILE;) 41.8429 Tj
-90 494.369 Td
-(BZFILE) 35.8654 Tj
-130.109 492.625 Td
-(*) 5.97756 Tj
-136.087 494.369 Td
-(BZ2_bzReadOpen\() 89.6634 Tj
--426 TJm
-(int) 17.9327 Tj
-252.171 492.625 Td
-(*) 5.97756 Tj
-258.149 494.369 Td
-(bzerror,) 47.8205 Tj
--426 TJm
-(FILE) 23.9102 Tj
-338.368 492.625 Td
-(*) 5.97756 Tj
-344.346 494.369 Td
-(f,) 11.9551 Tj
-191.855 482.414 Td
-(int) 17.9327 Tj
--426 TJm
-(verbosity,) 59.7756 Tj
--426 TJm
-(int) 17.9327 Tj
--426 TJm
-(small,) 35.8654 Tj
-191.855 470.458 Td
-(void) 23.9102 Tj
-220.01 468.715 Td
-(*) 5.97756 Tj
-225.987 470.458 Td
-(unused,) 41.8429 Tj
--426 TJm
-(int) 17.9327 Tj
--426 TJm
-(nUnused) 41.8429 Tj
--426 TJm
-(\);) 11.9551 Tj
-[1 0 0 1 72 454.917] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 468 3.5866] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -468 -13.5492] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -444.954] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 432.999 Td
-/F130_0 9.9626 Tf
-(Prepare) 30.4258 Tj
--290 TJm
-(to) 7.7509 Tj
--289 TJm
-(read) 17.1456 Tj
--290 TJm
-(compressed) 47.0334 Tj
--290 TJm
-(data) 16.5977 Tj
--289 TJm
-(from) 19.3673 Tj
--290 TJm
-(\002le) 12.7322 Tj
--289 TJm
-(handle) 26.5603 Tj
-[1 0 0 1 272.697 432.999] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -272.697 -432.999] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-272.697 432.999 Td
-/F134_0 9.9626 Tf
-(f) 5.97756 Tj
-[1 0 0 1 278.675 432.999] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -278.675 -432.999] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-278.675 432.999 Td
-/F130_0 9.9626 Tf
-(.) 2.49065 Tj
-[1 0 0 1 285.439 432.999] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -285.439 -432.999] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-285.439 432.999 Td
-/F134_0 9.9626 Tf
-(f) 5.97756 Tj
-[1 0 0 1 291.417 432.999] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -291.417 -432.999] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-294.303 432.999 Td
-/F130_0 9.9626 Tf
-(should) 26.5703 Tj
--290 TJm
-(refer) 18.7994 Tj
--289 TJm
-(to) 7.7509 Tj
--290 TJm
-(a) 4.42339 Tj
--290 TJm
-(\002le) 12.7322 Tj
--289 TJm
-(which) 24.3486 Tj
--290 TJm
-(has) 13.2801 Tj
--289 TJm
-(been) 18.8094 Tj
--290 TJm
-(opened) 28.772 Tj
--290 TJm
-(for) 11.6164 Tj
--289 TJm
-(reading,) 32.3685 Tj
--300 TJm
-(and) 14.386 Tj
-72 421.044 Td
-(for) 11.6164 Tj
--306 TJm
-(which) 24.3486 Tj
--305 TJm
-(the) 12.1743 Tj
--306 TJm
-(error) 19.3573 Tj
--306 TJm
-(indicator) 35.417 Tj
--305 TJm
-(\() 3.31755 Tj
-[1 0 0 1 193.457 421.044] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -193.457 -421.044] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-193.457 421.044 Td
-/F134_0 9.9626 Tf
-(ferror\(f\)) 53.798 Tj
-[1 0 0 1 247.255 421.044] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -247.255 -421.044] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-247.255 421.044 Td
-/F130_0 9.9626 Tf
-(\)is) 9.9626 Tj
--306 TJm
-(not) 12.7322 Tj
--305 TJm
-(set.) 13.5591 Tj
--954 TJm
-(If) 6.63509 Tj
-[1 0 0 1 308.784 421.044] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -308.784 -421.044] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-308.784 421.044 Td
-/F134_0 9.9626 Tf
-(small) 29.8878 Tj
-[1 0 0 1 338.671 421.044] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -338.671 -421.044] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-341.717 421.044 Td
-/F130_0 9.9626 Tf
-(is) 6.64505 Tj
--306 TJm
-(1,) 7.47195 Tj
--319 TJm
-(the) 12.1743 Tj
--306 TJm
-(library) 26.5603 Tj
--306 TJm
-(will) 15.5018 Tj
--305 TJm
-(try) 11.0684 Tj
--306 TJm
-(to) 7.7509 Tj
--306 TJm
-(dec) 13.8281 Tj
-1 TJm
-(ompress) 33.2053 Tj
--306 TJm
-(using) 21.589 Tj
--306 TJm
-(less) 14.9439 Tj
-72 409.089 Td
-(memory) 33.2053 Tj
-65 TJm
-(,) 2.49065 Tj
--250 TJm
-(at) 7.193 Tj
--250 TJm
-(the) 12.1743 Tj
--250 TJm
-(e) 4.42339 Tj
-15 TJm
-(xpense) 27.6661 Tj
--250 TJm
-(of) 8.29885 Tj
--250 TJm
-(speed.) 25.1755 Tj
-[1 0 0 1 72 406.932] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.9626] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -396.969] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 387.171 Td
-/F130_0 9.9626 Tf
-(F) 5.53921 Tj
-15 TJm
-(or) 8.29885 Tj
--227 TJm
-(reasons) 29.8778 Tj
--227 TJm
-(e) 4.42339 Tj
-15 TJm
-(xplained) 34.3112 Tj
--228 TJm
-(belo) 17.1556 Tj
-25 TJm
-(w) 7.193 Tj
-65 TJm
-(,) 2.49065 Tj
-[1 0 0 1 189.193 387.171] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -189.193 -387.171] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-189.193 387.171 Td
-/F134_0 9.9626 Tf
-(BZ2_bzRead) 59.7756 Tj
-[1 0 0 1 248.969 387.171] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -248.969 -387.171] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-251.232 387.171 Td
-/F130_0 9.9626 Tf
-(will) 15.5018 Tj
--227 TJm
-(decompress) 47.0334 Tj
--227 TJm
-(the) 12.1743 Tj
-[1 0 0 1 332.732 387.171] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -332.732 -387.171] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-332.732 387.171 Td
-/F134_0 9.9626 Tf
-(nUnused) 41.8429 Tj
-[1 0 0 1 374.575 387.171] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -374.575 -387.171] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-376.838 387.171 Td
-/F130_0 9.9626 Tf
-(bytes) 21.031 Tj
--227 TJm
-(starting) 29.8878 Tj
--227 TJm
-(at) 7.193 Tj
-[1 0 0 1 441.74 387.171] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -441.74 -387.171] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-441.74 387.171 Td
-/F134_0 9.9626 Tf
-(unused) 35.8654 Tj
-[1 0 0 1 477.605 387.171] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -477.605 -387.171] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-477.605 387.171 Td
-/F130_0 9.9626 Tf
-(,) 2.49065 Tj
--232 TJm
-(before) 25.4445 Tj
--227 TJm
-(starting) 29.8878 Tj
-72 375.216 Td
-(to) 7.7509 Tj
--280 TJm
-(read) 17.1456 Tj
--279 TJm
-(from) 19.3673 Tj
--280 TJm
-(the) 12.1743 Tj
--279 TJm
-(\002le) 12.7322 Tj
-[1 0 0 1 155.094 375.215] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -155.094 -375.215] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-155.094 375.215 Td
-/F134_0 9.9626 Tf
-(f) 5.97756 Tj
-[1 0 0 1 161.072 375.215] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -161.072 -375.215] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-161.072 375.215 Td
-/F130_0 9.9626 Tf
-(.) 2.49065 Tj
--797 TJm
-(At) 9.9626 Tj
--280 TJm
-(most) 19.3773 Tj
-[1 0 0 1 206.414 375.215] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -206.414 -375.215] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-206.414 375.215 Td
-/F134_0 9.9626 Tf
-(BZ_MAX_UNUSED) 77.7083 Tj
-[1 0 0 1 284.122 375.215] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -284.122 -375.215] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-286.907 375.215 Td
-/F130_0 9.9626 Tf
-(bytes) 21.031 Tj
--280 TJm
-(may) 17.1556 Tj
--279 TJm
-(be) 9.40469 Tj
--280 TJm
-(supplied) 33.7633 Tj
--279 TJm
-(lik) 10.5205 Tj
-10 TJm
-(e) 4.42339 Tj
--280 TJm
-(this.) 16.8866 Tj
--797 TJm
-(If) 6.63509 Tj
--279 TJm
-(this) 14.396 Tj
--280 TJm
-(f) 3.31755 Tj
-10 TJm
-(acility) 24.9065 Tj
--279 TJm
-(is) 6.64505 Tj
--280 TJm
-(not) 12.7322 Tj
--279 TJm
-(required,) 35.686 Tj
-72 363.26 Td
-(you) 14.9439 Tj
--250 TJm
-(should) 26.5703 Tj
--250 TJm
-(pass) 17.1556 Tj
-[1 0 0 1 138.141 363.26] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -138.141 -363.26] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-138.141 363.26 Td
-/F134_0 9.9626 Tf
-(NULL) 23.9102 Tj
-[1 0 0 1 162.052 363.26] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -162.052 -363.26] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-164.542 363.26 Td
-/F130_0 9.9626 Tf
-(and) 14.386 Tj
-[1 0 0 1 181.419 363.26] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -181.419 -363.26] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-181.419 363.26 Td
-/F134_0 9.9626 Tf
-(0) 5.97756 Tj
-[1 0 0 1 187.397 363.26] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -187.397 -363.26] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-189.887 363.26 Td
-/F130_0 9.9626 Tf
-(for) 11.6164 Tj
-[1 0 0 1 203.994 363.26] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -203.994 -363.26] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-203.994 363.26 Td
-/F134_0 9.9626 Tf
-(unused) 35.8654 Tj
-[1 0 0 1 239.86 363.26] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -239.86 -363.26] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-242.351 363.26 Td
-/F130_0 9.9626 Tf
-(and) 14.386 Tj
--250 TJm
-(n) 4.9813 Tj
-[1 0 0 1 264.208 363.26] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -264.208 -363.26] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-264.208 363.26 Td
-/F134_0 9.9626 Tf
-(Unused) 35.8654 Tj
-[1 0 0 1 300.074 363.26] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -300.074 -363.26] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-302.565 363.26 Td
-/F130_0 9.9626 Tf
-(respecti) 30.9837 Tj
-25 TJm
-(v) 4.9813 Tj
-15 TJm
-(ely) 12.1743 Tj
-65 TJm
-(.) 2.49065 Tj
-[1 0 0 1 72 361.103] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.9626] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -351.141] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 341.343 Td
-/F130_0 9.9626 Tf
-(F) 5.53921 Tj
-15 TJm
-(or) 8.29885 Tj
--250 TJm
-(the) 12.1743 Tj
--250 TJm
-(meaning) 34.3112 Tj
--250 TJm
-(of) 8.29885 Tj
--250 TJm
-(parameters) 43.7059 Tj
-[1 0 0 1 196.631 341.343] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -196.631 -341.343] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-196.631 341.343 Td
-/F134_0 9.9626 Tf
-(small) 29.8878 Tj
-[1 0 0 1 226.519 341.343] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -226.519 -341.343] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-229.01 341.343 Td
-/F130_0 9.9626 Tf
-(and) 14.386 Tj
-[1 0 0 1 245.887 341.343] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -245.887 -341.343] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-245.887 341.343 Td
-/F134_0 9.9626 Tf
-(verbosity) 53.798 Tj
-[1 0 0 1 299.685 341.343] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -299.685 -341.343] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-299.685 341.343 Td
-/F130_0 9.9626 Tf
-(,) 2.49065 Tj
--250 TJm
-(see) 12.7222 Tj
-[1 0 0 1 319.879 341.343] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -319.879 -341.343] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-319.879 341.343 Td
-/F134_0 9.9626 Tf
-(BZ2_bzDecompressInit) 119.551 Tj
-[1 0 0 1 439.431 341.343] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -439.431 -341.343] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-439.431 341.343 Td
-/F130_0 9.9626 Tf
-(.) 2.49065 Tj
-[1 0 0 1 72 339.186] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.9626] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -329.223] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 319.425 Td
-/F130_0 9.9626 Tf
-(The) 15.4918 Tj
--402 TJm
-(amount) 29.8878 Tj
--402 TJm
-(of) 8.29885 Tj
--402 TJm
-(memory) 33.2053 Tj
--402 TJm
-(needed) 28.2141 Tj
--402 TJm
-(to) 7.7509 Tj
--402 TJm
-(decompress) 47.0334 Tj
--402 TJm
-(a) 4.42339 Tj
--401 TJm
-(\002le) 12.7322 Tj
--402 TJm
-(cannot) 26.5603 Tj
--402 TJm
-(be) 9.40469 Tj
--402 TJm
-(determined) 44.8217 Tj
--402 TJm
-(until) 18.2714 Tj
--402 TJm
-(the) 12.1743 Tj
--402 TJm
-(\002le') 16.0497 Tj
-55 TJm
-(s) 3.87545 Tj
--402 TJm
-(header) 26.5503 Tj
--402 TJm
-(has) 13.2801 Tj
--402 TJm
-(been) 18.8094 Tj
--402 TJm
-(read.) 19.6363 Tj
-72 307.47 Td
-(So) 10.5205 Tj
--492 TJm
-(it) 5.53921 Tj
--491 TJm
-(is) 6.64505 Tj
--492 TJm
-(possible) 32.6574 Tj
--492 TJm
-(that) 14.9439 Tj
-[1 0 0 1 166.797 307.47] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -166.797 -307.47] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-166.797 307.47 Td
-/F134_0 9.9626 Tf
-(BZ2_bzReadOpen) 83.6858 Tj
-[1 0 0 1 250.483 307.47] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -250.483 -307.47] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-255.381 307.47 Td
-/F130_0 9.9626 Tf
-(returns) 27.6661 Tj
-[1 0 0 1 287.945 307.47] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -287.945 -307.47] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-287.945 307.47 Td
-/F134_0 9.9626 Tf
-(BZ_OK) 29.8878 Tj
-[1 0 0 1 317.833 307.47] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -317.833 -307.47] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-322.729 307.47 Td
-/F130_0 9.9626 Tf
-(b) 4.9813 Tj
-20 TJm
-(ut) 7.7509 Tj
--492 TJm
-(a) 4.42339 Tj
--491 TJm
-(subsequent) 44.2738 Tj
--492 TJm
-(call) 14.386 Tj
--492 TJm
-(of) 8.29885 Tj
-[1 0 0 1 431.135 307.47] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -431.135 -307.47] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-431.135 307.47 Td
-/F134_0 9.9626 Tf
-(BZ2_bzRead) 59.7756 Tj
-[1 0 0 1 490.911 307.47] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -490.911 -307.47] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-495.81 307.47 Td
-/F130_0 9.9626 Tf
-(will) 15.5018 Tj
--492 TJm
-(return) 23.7907 Tj
-[1 0 0 1 72 295.514] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -295.514] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 295.514 Td
-/F134_0 9.9626 Tf
-(BZ_MEM_ERROR) 71.7307 Tj
-[1 0 0 1 143.731 295.514] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -143.731 -295.514] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-143.731 295.514 Td
-/F130_0 9.9626 Tf
-(.) 2.49065 Tj
-[1 0 0 1 72 294.204] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.9626] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -284.242] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 273.597 Td
-/F130_0 9.9626 Tf
-(Possible) 33.2153 Tj
--250 TJm
-(assignments) 48.7072 Tj
--250 TJm
-(to) 7.7509 Tj
-[1 0 0 1 169.144 273.597] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -169.144 -273.597] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-169.144 273.597 Td
-/F134_0 9.9626 Tf
-(bzerror) 41.8429 Tj
-[1 0 0 1 210.987 273.597] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -210.987 -273.597] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-210.987 273.597 Td
-/F130_0 9.9626 Tf
-(:) 2.7696 Tj
-[1 0 0 1 72 271.44] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -168.369] cm
-/DeviceRGB {} cs
-[0.94899 0.94899 0.976456] sc
-/DeviceRGB {} CS
-[0.94899 0.94899 0.976456] SC
-0 0 468 167.372 re
-f
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 3.5866] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 163.786] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 18 -8.3686] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -90 -262.075] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-90 262.075 Td
-/F134_0 9.9626 Tf
-(BZ_CONFIG_ERROR) 89.6634 Tj
-98.4879 250.12 Td
-(if) 11.9551 Tj
--426 TJm
-(the) 17.9327 Tj
--426 TJm
-(library) 41.8429 Tj
--426 TJm
-(has) 17.9327 Tj
--426 TJm
-(been) 23.9102 Tj
--426 TJm
-(mis-compiled) 71.7307 Tj
-90 238.165 Td
-(BZ_PARAM_ERROR) 83.6858 Tj
-98.4879 226.209 Td
-(if) 11.9551 Tj
--426 TJm
-(f) 5.97756 Tj
--426 TJm
-(is) 11.9551 Tj
--426 TJm
-(NULL) 23.9102 Tj
-98.4879 214.254 Td
-(or) 11.9551 Tj
--426 TJm
-(small) 29.8878 Tj
--426 TJm
-(is) 11.9551 Tj
--426 TJm
-(neither) 41.8429 Tj
--426 TJm
-(0) 5.97756 Tj
--426 TJm
-(nor) 17.9327 Tj
--426 TJm
-(1) 5.97756 Tj
-98.4879 202.299 Td
-(or) 11.9551 Tj
--426 TJm
-(\() 5.97756 Tj
--426 TJm
-(unused) 35.8654 Tj
--426 TJm
-(==) 11.9551 Tj
--426 TJm
-(NULL) 23.9102 Tj
--426 TJm
-(&&) 11.9551 Tj
--426 TJm
-(nUnused) 41.8429 Tj
--426 TJm
-(!=) 11.9551 Tj
--426 TJm
-(0) 5.97756 Tj
--426 TJm
-(\)) 5.97756 Tj
-98.4879 190.344 Td
-(or) 11.9551 Tj
--426 TJm
-(\() 5.97756 Tj
--426 TJm
-(unused) 35.8654 Tj
--426 TJm
-(!=) 11.9551 Tj
--426 TJm
-(NULL) 23.9102 Tj
--426 TJm
-(&&) 11.9551 Tj
--426 TJm
-(!\(0) 17.9327 Tj
--426 TJm
-(<=) 11.9551 Tj
--426 TJm
-(nUnused) 41.8429 Tj
--426 TJm
-(<=) 11.9551 Tj
--426 TJm
-(BZ_MAX_UNUSED\)) 83.6858 Tj
--426 TJm
-(\)) 5.97756 Tj
-90 178.389 Td
-(BZ_IO_ERROR) 65.7532 Tj
-98.4879 166.434 Td
-(if) 11.9551 Tj
--426 TJm
-(ferror\(f\)) 53.798 Tj
--426 TJm
-(is) 11.9551 Tj
--426 TJm
-(nonzero) 41.8429 Tj
-90 154.478 Td
-(BZ_MEM_ERROR) 71.7307 Tj
-98.4879 142.523 Td
-(if) 11.9551 Tj
--426 TJm
-(insufficient) 71.7307 Tj
--426 TJm
-(memory) 35.8654 Tj
--426 TJm
-(is) 11.9551 Tj
--426 TJm
-(available) 53.798 Tj
-90 130.568 Td
-(BZ_OK) 29.8878 Tj
-98.4879 118.613 Td
-(otherwise.) 59.7756 Tj
-[1 0 0 1 72 103.071] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 468 3.5866] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -468 -13.5492] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -93.1085] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 81.1533 Td
-/F130_0 9.9626 Tf
-(Possible) 33.2153 Tj
--250 TJm
-(return) 23.7907 Tj
--250 TJm
-(v) 4.9813 Tj
-25 TJm
-(alues:) 23.2427 Tj
-[1 0 0 1 72 81.0538] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -30.202] cm
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-[1 0 0 1 1.8929 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 374.394 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 6.9737] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 40.5726 -6.7546] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -493.841 -51.071] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-534.414 51.071 Td
-/F130_0 9.9626 Tf
-(19) 9.9626 Tj
-[1 0 0 1 453.269 50.8519] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 93.5985 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 6.2765 0] cm
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-[1 0 0 1 -13.1436 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-Q
-showpage
-%%PageTrailer
-pdfEndPage
-%%Page: 23 23
-%%BeginPageSetup
-%%PageOrientation: Portrait
-pdfStartPage
-0 0 612 792 re W
-%%EndPageSetup
-[] 0 d
-1 i
-0 j
-0 J
-10 M
-1 w
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-false op
-false OP
-0 0 612 792 re
-W
-q
-[1 0 0 1 72 741.554] cm
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-[1 0 0 1 1.8929 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 14.4459] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 187.197 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 -8.9114] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 8.9114] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 76.4979 -6.7546] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -342.569 -749.245] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-419.067 749.245 Td
-/F130_0 9.9626 Tf
-(Programming) 54.7943 Tj
--250 TJm
-(with) 17.7135 Tj
-[1 0 0 1 496.556 749.245] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -496.556 -749.245] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-496.556 749.245 Td
-/F134_0 9.9626 Tf
-(libbzip2) 47.8205 Tj
-[1 0 0 1 544.376 749.245] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -278.305 -2.1568] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 280.796 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -472.974 -5.0363] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -0.4981] cm
-q
-[] 0 d
-0 J
-0.4981 w
-0 0.2491 m
-475.465 0.2491 l
-S
-Q
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 479.251 0] cm
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-[1 0 0 1 -13.1436 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -468 -81.33] cm
-/DeviceRGB {} cs
-[0.94899 0.94899 0.976456] sc
-/DeviceRGB {} CS
-[0.94899 0.94899 0.976456] SC
-0 0 468 59.7758 re
-f
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 3.5866] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 56.1892] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 18 -8.3686] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -90 -711.631] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-90 711.631 Td
-/F134_0 9.9626 Tf
-(Pointer) 41.8429 Tj
--426 TJm
-(to) 11.9551 Tj
--426 TJm
-(an) 11.9551 Tj
--426 TJm
-(abstract) 47.8205 Tj
--426 TJm
-(BZFILE) 35.8654 Tj
-98.4879 699.676 Td
-(if) 11.9551 Tj
--426 TJm
-(bzerror) 41.8429 Tj
--426 TJm
-(is) 11.9551 Tj
--426 TJm
-(BZ_OK) 29.8878 Tj
-90 687.721 Td
-(NULL) 23.9102 Tj
-98.4879 675.766 Td
-(otherwise) 53.798 Tj
-[1 0 0 1 72 660.224] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 468 3.5866] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -468 -13.5493] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -650.261] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 638.306 Td
-/F130_0 9.9626 Tf
-(Allo) 17.7135 Tj
-25 TJm
-(w) 7.193 Tj
-10 TJm
-(able) 16.5977 Tj
--250 TJm
-(ne) 9.40469 Tj
-15 TJm
-(xt) 7.7509 Tj
--250 TJm
-(actions:) 30.9936 Tj
-[1 0 0 1 72 638.207] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -60.7721] cm
-/DeviceRGB {} cs
-[0.94899 0.94899 0.976456] sc
-/DeviceRGB {} CS
-[0.94899 0.94899 0.976456] SC
-0 0 468 59.7758 re
-f
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 3.5866] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 56.1893] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 18 -8.3686] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -90 -628.842] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-90 628.842 Td
-/F134_0 9.9626 Tf
-(BZ2_bzRead) 59.7756 Tj
-98.4879 616.887 Td
-(if) 11.9551 Tj
--426 TJm
-(bzerror) 41.8429 Tj
--426 TJm
-(is) 11.9551 Tj
--426 TJm
-(BZ_OK) 29.8878 Tj
-90 604.932 Td
-(BZ2_bzClose) 65.7532 Tj
-98.4879 592.976 Td
-(otherwise) 53.798 Tj
-[1 0 0 1 72 577.435] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 468 3.5866] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -468 -3.5866] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.9626] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -567.472] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 546.813 Td
-/F122_0 17.2154 Tf
-(3.4.2.) 43.0729 Tj
-[1 0 0 1 119.858 546.813] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -119.858 -546.813] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-119.858 546.813 Td
-/F392_0 17.2154 Tf
-(BZ2_bzRead) 103.292 Tj
-[1 0 0 1 223.15 546.813] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -151.15 -2.3326] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -24.9066] cm
-/DeviceRGB {} cs
-[0.94899 0.94899 0.976456] sc
-/DeviceRGB {} CS
-[0.94899 0.94899 0.976456] SC
-0 0 468 23.9103 re
-f
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 3.5866] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 20.3237] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 18 -8.3686] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -90 -535.116] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-90 535.116 Td
-/F134_0 9.9626 Tf
-(int) 17.9327 Tj
--426 TJm
-(BZ2_bzRead) 59.7756 Tj
--426 TJm
-(\() 5.97756 Tj
--426 TJm
-(int) 17.9327 Tj
-208.595 533.373 Td
-(*) 5.97756 Tj
-214.572 535.116 Td
-(bzerror,) 47.8205 Tj
--426 TJm
-(BZFILE) 35.8654 Tj
-306.747 533.373 Td
-(*) 5.97756 Tj
-312.724 535.116 Td
-(b,) 11.9551 Tj
--426 TJm
-(void) 23.9102 Tj
-357.077 533.373 Td
-(*) 5.97756 Tj
-363.055 535.116 Td
-(buf,) 23.9102 Tj
--426 TJm
-(int) 17.9327 Tj
--426 TJm
-(len) 17.9327 Tj
--426 TJm
-(\);) 11.9551 Tj
-[1 0 0 1 72 519.574] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 468 3.5866] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -468 -13.5492] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -509.612] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 497.656 Td
-/F130_0 9.9626 Tf
-(Reads) 24.3486 Tj
--285 TJm
-(up) 9.9626 Tj
--284 TJm
-(to) 7.7509 Tj
-[1 0 0 1 122.569 497.656] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -122.569 -497.656] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-122.569 497.656 Td
-/F134_0 9.9626 Tf
-(len) 17.9327 Tj
-[1 0 0 1 140.501 497.656] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -140.501 -497.656] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-143.337 497.656 Td
-/F130_0 9.9626 Tf
-(\(uncompressed\)) 63.6311 Tj
--285 TJm
-(bytes) 21.031 Tj
--284 TJm
-(from) 19.3673 Tj
--285 TJm
-(the) 12.1743 Tj
--284 TJm
-(compressed) 47.0334 Tj
--285 TJm
-(\002le) 12.7322 Tj
-[1 0 0 1 336.319 497.656] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -336.319 -497.656] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-336.319 497.656 Td
-/F134_0 9.9626 Tf
-(b) 5.97756 Tj
-[1 0 0 1 342.296 497.656] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -342.296 -497.656] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-345.132 497.656 Td
-/F130_0 9.9626 Tf
-(into) 15.5018 Tj
--285 TJm
-(the) 12.1743 Tj
--284 TJm
-(b) 4.9813 Tj
-20 TJm
-(uf) 8.29885 Tj
-25 TJm
-(fer) 11.0585 Tj
-[1 0 0 1 405.205 497.656] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -405.205 -497.656] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-405.205 497.656 Td
-/F134_0 9.9626 Tf
-(buf) 17.9327 Tj
-[1 0 0 1 423.137 497.656] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -423.137 -497.656] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-423.137 497.656 Td
-/F130_0 9.9626 Tf
-(.) 2.49065 Tj
--828 TJm
-(If) 6.63509 Tj
--284 TJm
-(the) 12.1743 Tj
--285 TJm
-(read) 17.1456 Tj
--285 TJm
-(w) 7.193 Tj
-10 TJm
-(as) 8.29885 Tj
--284 TJm
-(successful,) 43.4369 Tj
-[1 0 0 1 72 485.701] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -485.701] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 485.701 Td
-/F134_0 9.9626 Tf
-(bzerror) 41.8429 Tj
-[1 0 0 1 113.843 485.701] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -113.843 -485.701] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-117.36 485.701 Td
-/F130_0 9.9626 Tf
-(is) 6.64505 Tj
--353 TJm
-(set) 11.0684 Tj
--353 TJm
-(to) 7.7509 Tj
-[1 0 0 1 153.374 485.701] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -153.374 -485.701] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-153.374 485.701 Td
-/F134_0 9.9626 Tf
-(BZ_OK) 29.8878 Tj
-[1 0 0 1 183.262 485.701] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -183.262 -485.701] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-186.778 485.701 Td
-/F130_0 9.9626 Tf
-(and) 14.386 Tj
--353 TJm
-(the) 12.1743 Tj
--353 TJm
-(number) 30.4357 Tj
--353 TJm
-(of) 8.29885 Tj
--353 TJm
-(bytes) 21.031 Tj
--353 TJm
-(read) 17.1456 Tj
--353 TJm
-(is) 6.64505 Tj
--353 TJm
-(returned.) 35.686 Tj
--1238 TJm
-(If) 6.63509 Tj
--353 TJm
-(the) 12.1743 Tj
--353 TJm
-(logical) 27.1182 Tj
--353 TJm
-(end-of-stream) 55.8802 Tj
--353 TJm
-(w) 7.193 Tj
-10 TJm
-(as) 8.29885 Tj
--353 TJm
-(detected,) 35.686 Tj
-[1 0 0 1 72 473.746] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -473.746] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 473.746 Td
-/F134_0 9.9626 Tf
-(bzerror) 41.8429 Tj
-[1 0 0 1 113.843 473.746] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -113.843 -473.746] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-116.795 473.746 Td
-/F130_0 9.9626 Tf
-(will) 15.5018 Tj
--296 TJm
-(be) 9.40469 Tj
--297 TJm
-(set) 11.0684 Tj
--296 TJm
-(to) 7.7509 Tj
-[1 0 0 1 172.329 473.746] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -172.329 -473.746] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-172.329 473.746 Td
-/F134_0 9.9626 Tf
-(BZ_STREAM_END) 77.7083 Tj
-[1 0 0 1 250.037 473.746] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -250.037 -473.746] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-250.037 473.746 Td
-/F130_0 9.9626 Tf
-(,) 2.49065 Tj
--296 TJm
-(and) 14.386 Tj
--297 TJm
-(the) 12.1743 Tj
--296 TJm
-(number) 30.4357 Tj
--296 TJm
-(of) 8.29885 Tj
--297 TJm
-(bytes) 21.031 Tj
--296 TJm
-(read) 17.1456 Tj
--296 TJm
-(is) 6.64505 Tj
--296 TJm
-(returned.) 35.686 Tj
--898 TJm
-(All) 12.7322 Tj
--297 TJm
-(other) 20.4731 Tj
-[1 0 0 1 470 473.746] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -470 -473.746] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-470 473.746 Td
-/F134_0 9.9626 Tf
-(bzerror) 41.8429 Tj
-[1 0 0 1 511.843 473.746] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -511.843 -473.746] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-514.795 473.746 Td
-/F130_0 9.9626 Tf
-(v) 4.9813 Tj
-25 TJm
-(alues) 20.4731 Tj
-72 461.791 Td
-(denote) 26.5603 Tj
--250 TJm
-(an) 9.40469 Tj
--250 TJm
-(error) 19.3573 Tj
-55 TJm
-(.) 2.49065 Tj
-[1 0 0 1 72 461.691] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.9626] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -451.729] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 439.873 Td
-/F134_0 9.9626 Tf
-(BZ2_bzRead) 59.7756 Tj
-[1 0 0 1 131.776 439.873] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -131.776 -439.873] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-134.224 439.873 Td
-/F130_0 9.9626 Tf
-(will) 15.5018 Tj
--246 TJm
-(supply) 26.5703 Tj
-[1 0 0 1 181.193 439.873] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -181.193 -439.873] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-181.193 439.873 Td
-/F134_0 9.9626 Tf
-(len) 17.9327 Tj
-[1 0 0 1 199.126 439.873] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -199.126 -439.873] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-201.575 439.873 Td
-/F130_0 9.9626 Tf
-(bytes,) 23.5217 Tj
--247 TJm
-(unless) 24.9065 Tj
--245 TJm
-(the) 12.1743 Tj
--246 TJm
-(logical) 27.1182 Tj
--246 TJm
-(stream) 26.5603 Tj
--246 TJm
-(end) 14.386 Tj
--245 TJm
-(is) 6.64505 Tj
--246 TJm
-(detected) 33.1954 Tj
--246 TJm
-(or) 8.29885 Tj
--246 TJm
-(an) 9.40469 Tj
--246 TJm
-(error) 19.3573 Tj
--245 TJm
-(occurs.) 28.493 Tj
--617 TJm
-(Because) 33.1954 Tj
--246 TJm
-(of) 8.29885 Tj
--246 TJm
-(this,) 16.8866 Tj
--247 TJm
-(it) 5.53921 Tj
-72 427.918 Td
-(is) 6.64505 Tj
--231 TJm
-(possible) 32.6574 Tj
--231 TJm
-(to) 7.7509 Tj
--231 TJm
-(detect) 23.7907 Tj
--231 TJm
-(the) 12.1743 Tj
--231 TJm
-(stream) 26.5603 Tj
--231 TJm
-(end) 14.386 Tj
--232 TJm
-(by) 9.9626 Tj
--231 TJm
-(observing) 39.2925 Tj
--231 TJm
-(when) 21.579 Tj
--231 TJm
-(the) 12.1743 Tj
--231 TJm
-(number) 30.4357 Tj
--231 TJm
-(of) 8.29885 Tj
--231 TJm
-(bytes) 21.031 Tj
--231 TJm
-(returned) 33.1954 Tj
--231 TJm
-(is) 6.64505 Tj
--231 TJm
-(less) 14.9439 Tj
--231 TJm
-(than) 17.1556 Tj
--232 TJm
-(the) 12.1743 Tj
--231 TJm
-(number) 30.4357 Tj
--231 TJm
-(requested.) 40.6673 Tj
-72 415.963 Td
-(Ne) 11.6164 Tj
-25 TJm
-(v) 4.9813 Tj
-15 TJm
-(ertheless,) 37.3498 Tj
--309 TJm
-(this) 14.396 Tj
--297 TJm
-(is) 6.64505 Tj
--298 TJm
-(re) 7.74094 Tj
-15 TJm
-(g) 4.9813 Tj
-5 TJm
-(arded) 22.1269 Tj
--297 TJm
-(as) 8.29885 Tj
--297 TJm
-(inadvisable;) 48.1492 Tj
--321 TJm
-(you) 14.9439 Tj
--298 TJm
-(should) 26.5703 Tj
--297 TJm
-(instead) 28.224 Tj
--297 TJm
-(check) 23.2328 Tj
-[1 0 0 1 360.631 415.963] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -360.631 -415.963] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-360.631 415.963 Td
-/F134_0 9.9626 Tf
-(bzerror) 41.8429 Tj
-[1 0 0 1 402.475 415.963] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -402.475 -415.963] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-405.437 415.963 Td
-/F130_0 9.9626 Tf
-(after) 18.2515 Tj
--297 TJm
-(e) 4.42339 Tj
-25 TJm
-(v) 4.9813 Tj
-15 TJm
-(ery) 12.7222 Tj
--298 TJm
-(call) 14.386 Tj
--297 TJm
-(and) 14.386 Tj
--297 TJm
-(w) 7.193 Tj
-10 TJm
-(atch) 16.5977 Tj
--298 TJm
-(out) 12.7322 Tj
--297 TJm
-(for) 11.6164 Tj
-[1 0 0 1 72 404.008] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -404.008] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 404.008 Td
-/F134_0 9.9626 Tf
-(BZ_STREAM_END) 77.7083 Tj
-[1 0 0 1 149.709 404.008] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -149.709 -404.008] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-149.709 404.008 Td
-/F130_0 9.9626 Tf
-(.) 2.49065 Tj
-[1 0 0 1 72 402.698] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.9626] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -392.735] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 382.09 Td
-/F130_0 9.9626 Tf
-(Internally) 38.7346 Tj
-65 TJm
-(,) 2.49065 Tj
-[1 0 0 1 117.541 382.09] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -117.541 -382.09] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-117.541 382.09 Td
-/F134_0 9.9626 Tf
-(BZ2_bzRead) 59.7756 Tj
-[1 0 0 1 177.317 382.09] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -177.317 -382.09] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-181.786 382.09 Td
-/F130_0 9.9626 Tf
-(copies) 25.4544 Tj
--449 TJm
-(data) 16.5977 Tj
--448 TJm
-(from) 19.3673 Tj
--449 TJm
-(the) 12.1743 Tj
--448 TJm
-(compressed) 47.0334 Tj
--449 TJm
-(\002le) 12.7322 Tj
--448 TJm
-(in) 7.7509 Tj
--449 TJm
-(chunks) 28.224 Tj
--449 TJm
-(of) 8.29885 Tj
--448 TJm
-(size) 15.4918 Tj
-[1 0 0 1 419.602 382.09] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -419.602 -382.09] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-419.602 382.09 Td
-/F134_0 9.9626 Tf
-(BZ_MAX_UNUSED) 77.7083 Tj
-[1 0 0 1 497.31 382.09] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -497.31 -382.09] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-501.778 382.09 Td
-/F130_0 9.9626 Tf
-(bytes) 21.031 Tj
--449 TJm
-(be-) 12.7222 Tj
-72 370.135 Td
-(fore) 16.0398 Tj
--414 TJm
-(decompressing) 59.7656 Tj
--414 TJm
-(it.) 8.02986 Tj
--1605 TJm
-(If) 6.63509 Tj
--415 TJm
-(the) 12.1743 Tj
--414 TJm
-(\002le) 12.7322 Tj
--414 TJm
-(contains) 33.2053 Tj
--414 TJm
-(more) 20.4731 Tj
--414 TJm
-(bytes) 21.031 Tj
--415 TJm
-(than) 17.1556 Tj
--414 TJm
-(strictly) 27.6761 Tj
--414 TJm
-(needed) 28.2141 Tj
--414 TJm
-(to) 7.7509 Tj
--414 TJm
-(reach) 21.569 Tj
--414 TJm
-(the) 12.1743 Tj
--415 TJm
-(logical) 27.1182 Tj
--414 TJm
-(end-of-stream,) 58.3709 Tj
-[1 0 0 1 72 358.18] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -358.18] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 358.18 Td
-/F134_0 9.9626 Tf
-(BZ2_bzRead) 59.7756 Tj
-[1 0 0 1 131.776 358.18] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -131.776 -358.18] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-134.749 358.18 Td
-/F130_0 9.9626 Tf
-(will) 15.5018 Tj
--298 TJm
-(almost) 26.5703 Tj
--299 TJm
-(certainly) 34.8591 Tj
--298 TJm
-(read) 17.1456 Tj
--299 TJm
-(some) 21.031 Tj
--298 TJm
-(of) 8.29885 Tj
--299 TJm
-(the) 12.1743 Tj
--298 TJm
-(trailing) 28.782 Tj
--298 TJm
-(data) 16.5977 Tj
--299 TJm
-(before) 25.4445 Tj
--298 TJm
-(signalling) 39.3025 Tj
-[1 0 0 1 413.162 358.18] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -413.162 -358.18] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-413.162 358.18 Td
-/F134_0 9.9626 Tf
-(BZ_SEQUENCE_END) 89.6634 Tj
-[1 0 0 1 502.826 358.18] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -502.826 -358.18] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-502.826 358.18 Td
-/F130_0 9.9626 Tf
-(.) 2.49065 Tj
--597 TJm
-(T) 6.08715 Tj
-80 TJm
-(o) 4.9813 Tj
--298 TJm
-(col-) 15.4918 Tj
-72 346.224 Td
-(lect) 14.386 Tj
--242 TJm
-(the) 12.1743 Tj
--242 TJm
-(read) 17.1456 Tj
--243 TJm
-(b) 4.9813 Tj
-20 TJm
-(ut) 7.7509 Tj
--242 TJm
-(unused) 28.224 Tj
--242 TJm
-(data) 16.5977 Tj
--242 TJm
-(once) 18.8094 Tj
-[1 0 0 1 208.759 346.224] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -208.759 -346.224] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-208.759 346.224 Td
-/F134_0 9.9626 Tf
-(BZ_SEQUENCE_END) 89.6634 Tj
-[1 0 0 1 298.423 346.224] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -298.423 -346.224] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-300.835 346.224 Td
-/F130_0 9.9626 Tf
-(has) 13.2801 Tj
--242 TJm
-(appeared,) 38.4457 Tj
--244 TJm
-(call) 14.386 Tj
-[1 0 0 1 374.201 346.224] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -374.201 -346.224] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-374.201 346.224 Td
-/F134_0 9.9626 Tf
-(BZ2_bzReadGetUnused) 113.574 Tj
-[1 0 0 1 487.775 346.224] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -487.775 -346.224] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-490.188 346.224 Td
-/F130_0 9.9626 Tf
-(immediately) 49.813 Tj
-72 334.269 Td
-(before) 25.4445 Tj
-[1 0 0 1 99.935 334.269] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -99.935 -334.269] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-99.935 334.269 Td
-/F134_0 9.9626 Tf
-(BZ2_bzReadClose) 89.6634 Tj
-[1 0 0 1 189.599 334.269] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -189.599 -334.269] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-189.599 334.269 Td
-/F130_0 9.9626 Tf
-(.) 2.49065 Tj
-[1 0 0 1 72 332.959] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.9627] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -322.996] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 312.351 Td
-/F130_0 9.9626 Tf
-(Possible) 33.2153 Tj
--250 TJm
-(assignments) 48.7072 Tj
--250 TJm
-(to) 7.7509 Tj
-[1 0 0 1 169.144 312.351] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -169.144 -312.351] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-169.144 312.351 Td
-/F134_0 9.9626 Tf
-(bzerror) 41.8429 Tj
-[1 0 0 1 210.987 312.351] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -210.987 -312.351] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-210.987 312.351 Td
-/F130_0 9.9626 Tf
-(:) 2.7696 Tj
-[1 0 0 1 72 310.195] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -259.343] cm
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-[1 0 0 1 1.8929 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 374.394 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 6.8541] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 40.5726 -6.7545] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -493.841 -50.9514] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-534.414 50.9514 Td
-/F130_0 9.9626 Tf
-(20) 9.9626 Tj
-[1 0 0 1 453.269 50.8518] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 93.5985 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 6.2765 0] cm
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-[1 0 0 1 -13.1436 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-Q
-showpage
-%%PageTrailer
-pdfEndPage
-%%Page: 24 24
-%%BeginPageSetup
-%%PageOrientation: Portrait
-pdfStartPage
-0 0 612 792 re W
-%%EndPageSetup
-[] 0 d
-1 i
-0 j
-0 J
-10 M
-1 w
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-false op
-false OP
-0 0 612 792 re
-W
-q
-[1 0 0 1 72 741.554] cm
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-[1 0 0 1 1.8929 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 14.4459] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 187.197 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 -8.9114] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 8.9114] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 76.4979 -6.7546] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -342.569 -749.245] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-419.067 749.245 Td
-/F130_0 9.9626 Tf
-(Programming) 54.7943 Tj
--250 TJm
-(with) 17.7135 Tj
-[1 0 0 1 496.556 749.245] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -496.556 -749.245] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-496.556 749.245 Td
-/F134_0 9.9626 Tf
-(libbzip2) 47.8205 Tj
-[1 0 0 1 544.376 749.245] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -278.305 -2.1568] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 280.796 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -472.974 -5.0363] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -0.4981] cm
-q
-[] 0 d
-0 J
-0.4981 w
-0 0.2491 m
-475.465 0.2491 l
-S
-Q
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 479.251 0] cm
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-[1 0 0 1 -13.1436 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -468 -284.568] cm
-/DeviceRGB {} cs
-[0.94899 0.94899 0.976456] sc
-/DeviceRGB {} CS
-[0.94899 0.94899 0.976456] SC
-0 0 468 263.014 re
-f
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 3.5866] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 259.427] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 18 -8.3686] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -90 -711.631] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-90 711.631 Td
-/F134_0 9.9626 Tf
-(BZ_PARAM_ERROR) 83.6858 Tj
-98.4879 699.676 Td
-(if) 11.9551 Tj
--426 TJm
-(b) 5.97756 Tj
--426 TJm
-(is) 11.9551 Tj
--426 TJm
-(NULL) 23.9102 Tj
--426 TJm
-(or) 11.9551 Tj
--426 TJm
-(buf) 17.9327 Tj
--426 TJm
-(is) 11.9551 Tj
--426 TJm
-(NULL) 23.9102 Tj
--426 TJm
-(or) 11.9551 Tj
--426 TJm
-(len) 17.9327 Tj
--426 TJm
-(<) 5.97756 Tj
--426 TJm
-(0) 5.97756 Tj
-90 687.721 Td
-(BZ_SEQUENCE_ERROR) 101.619 Tj
-98.4879 675.766 Td
-(if) 11.9551 Tj
--426 TJm
-(b) 5.97756 Tj
--426 TJm
-(was) 17.9327 Tj
--426 TJm
-(opened) 35.8654 Tj
--426 TJm
-(with) 23.9102 Tj
--426 TJm
-(BZ2_bzWriteOpen) 89.6634 Tj
-90 663.811 Td
-(BZ_IO_ERROR) 65.7532 Tj
-98.4879 651.856 Td
-(if) 11.9551 Tj
--426 TJm
-(there) 29.8878 Tj
--426 TJm
-(is) 11.9551 Tj
--426 TJm
-(an) 11.9551 Tj
--426 TJm
-(error) 29.8878 Tj
--426 TJm
-(reading) 41.8429 Tj
--426 TJm
-(from) 23.9102 Tj
--426 TJm
-(the) 17.9327 Tj
--426 TJm
-(compressed) 59.7756 Tj
--426 TJm
-(file) 23.9102 Tj
-90 639.9 Td
-(BZ_UNEXPECTED_EOF) 101.619 Tj
-98.4879 627.945 Td
-(if) 11.9551 Tj
--426 TJm
-(the) 17.9327 Tj
--426 TJm
-(compressed) 59.7756 Tj
--426 TJm
-(file) 23.9102 Tj
--426 TJm
-(ended) 29.8878 Tj
--426 TJm
-(before) 35.8654 Tj
-98.4879 615.99 Td
-(the) 17.9327 Tj
--426 TJm
-(logical) 41.8429 Tj
--426 TJm
-(end-of-stream) 77.7083 Tj
--426 TJm
-(was) 17.9327 Tj
--426 TJm
-(detected) 47.8205 Tj
-90 604.035 Td
-(BZ_DATA_ERROR) 77.7083 Tj
-98.4879 592.08 Td
-(if) 11.9551 Tj
--426 TJm
-(a) 5.97756 Tj
--426 TJm
-(data) 23.9102 Tj
--426 TJm
-(integrity) 53.798 Tj
--426 TJm
-(error) 29.8878 Tj
--426 TJm
-(was) 17.9327 Tj
--426 TJm
-(detected) 47.8205 Tj
--426 TJm
-(in) 11.9551 Tj
--426 TJm
-(the) 17.9327 Tj
--426 TJm
-(compressed) 59.7756 Tj
--426 TJm
-(stream) 35.8654 Tj
-90 580.125 Td
-(BZ_DATA_ERROR_MAGIC) 113.574 Tj
-98.4879 568.169 Td
-(if) 11.9551 Tj
--426 TJm
-(the) 17.9327 Tj
--426 TJm
-(stream) 35.8654 Tj
--426 TJm
-(does) 23.9102 Tj
--426 TJm
-(not) 17.9327 Tj
--426 TJm
-(begin) 29.8878 Tj
--426 TJm
-(with) 23.9102 Tj
--426 TJm
-(the) 17.9327 Tj
--426 TJm
-(requisite) 53.798 Tj
--426 TJm
-(header) 35.8654 Tj
--426 TJm
-(bytes) 29.8878 Tj
-98.4879 556.214 Td
-(\(ie,) 23.9102 Tj
--426 TJm
-(is) 11.9551 Tj
--426 TJm
-(not) 17.9327 Tj
--426 TJm
-(a) 5.97756 Tj
--426 TJm
-(bzip2) 29.8878 Tj
--426 TJm
-(data) 23.9102 Tj
--426 TJm
-(file\).) 35.8654 Tj
--852 TJm
-(This) 23.9102 Tj
--426 TJm
-(is) 11.9551 Tj
--426 TJm
-(really) 35.8654 Tj
-98.4879 544.259 Td
-(a) 5.97756 Tj
--426 TJm
-(special) 41.8429 Tj
--426 TJm
-(case) 23.9102 Tj
--426 TJm
-(of) 11.9551 Tj
--426 TJm
-(BZ_DATA_ERROR.) 83.6858 Tj
-90 532.304 Td
-(BZ_MEM_ERROR) 71.7307 Tj
-98.4879 520.349 Td
-(if) 11.9551 Tj
--426 TJm
-(insufficient) 71.7307 Tj
--426 TJm
-(memory) 35.8654 Tj
--426 TJm
-(was) 17.9327 Tj
--426 TJm
-(available) 53.798 Tj
-90 508.394 Td
-(BZ_STREAM_END) 77.7083 Tj
-98.4879 496.438 Td
-(if) 11.9551 Tj
--426 TJm
-(the) 17.9327 Tj
--426 TJm
-(logical) 41.8429 Tj
--426 TJm
-(end) 17.9327 Tj
--426 TJm
-(of) 11.9551 Tj
--426 TJm
-(stream) 35.8654 Tj
--426 TJm
-(was) 17.9327 Tj
--426 TJm
-(detected.) 53.798 Tj
-90 484.483 Td
-(BZ_OK) 29.8878 Tj
-98.4879 472.528 Td
-(otherwise.) 59.7756 Tj
-[1 0 0 1 72 456.986] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 468 3.5866] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -468 -13.5492] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -447.024] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 435.068 Td
-/F130_0 9.9626 Tf
-(Possible) 33.2153 Tj
--250 TJm
-(return) 23.7907 Tj
--250 TJm
-(v) 4.9813 Tj
-25 TJm
-(alues:) 23.2427 Tj
-[1 0 0 1 72 434.969] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -60.7721] cm
-/DeviceRGB {} cs
-[0.94899 0.94899 0.976456] sc
-/DeviceRGB {} CS
-[0.94899 0.94899 0.976456] SC
-0 0 468 59.7758 re
-f
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 3.5866] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 56.1893] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 18 -8.3686] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -90 -425.604] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-90 425.604 Td
-/F134_0 9.9626 Tf
-(number) 35.8654 Tj
--426 TJm
-(of) 11.9551 Tj
--426 TJm
-(bytes) 29.8878 Tj
--426 TJm
-(read) 23.9102 Tj
-98.4879 413.649 Td
-(if) 11.9551 Tj
--426 TJm
-(bzerror) 41.8429 Tj
--426 TJm
-(is) 11.9551 Tj
--426 TJm
-(BZ_OK) 29.8878 Tj
--426 TJm
-(or) 11.9551 Tj
--426 TJm
-(BZ_STREAM_END) 77.7083 Tj
-90 401.694 Td
-(undefined) 53.798 Tj
-98.4879 389.739 Td
-(otherwise) 53.798 Tj
-[1 0 0 1 72 374.197] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 468 3.5866] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -468 -13.5492] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -364.234] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 352.279 Td
-/F130_0 9.9626 Tf
-(Allo) 17.7135 Tj
-25 TJm
-(w) 7.193 Tj
-10 TJm
-(able) 16.5977 Tj
--250 TJm
-(ne) 9.40469 Tj
-15 TJm
-(xt) 7.7509 Tj
--250 TJm
-(actions:) 30.9936 Tj
-[1 0 0 1 72 352.18] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -84.6825] cm
-/DeviceRGB {} cs
-[0.94899 0.94899 0.976456] sc
-/DeviceRGB {} CS
-[0.94899 0.94899 0.976456] SC
-0 0 468 83.6862 re
-f
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 3.5866] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 80.0996] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 18 -8.3686] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -90 -342.815] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-90 342.815 Td
-/F134_0 9.9626 Tf
-(collect) 41.8429 Tj
--426 TJm
-(data) 23.9102 Tj
--426 TJm
-(from) 23.9102 Tj
--426 TJm
-(buf,) 23.9102 Tj
--426 TJm
-(then) 23.9102 Tj
--426 TJm
-(BZ2_bzRead) 59.7756 Tj
--426 TJm
-(or) 11.9551 Tj
--426 TJm
-(BZ2_bzReadClose) 89.6634 Tj
-98.4879 330.859 Td
-(if) 11.9551 Tj
--426 TJm
-(bzerror) 41.8429 Tj
--426 TJm
-(is) 11.9551 Tj
--426 TJm
-(BZ_OK) 29.8878 Tj
-90 318.904 Td
-(collect) 41.8429 Tj
--426 TJm
-(data) 23.9102 Tj
--426 TJm
-(from) 23.9102 Tj
--426 TJm
-(buf,) 23.9102 Tj
--426 TJm
-(then) 23.9102 Tj
--426 TJm
-(BZ2_bzReadClose) 89.6634 Tj
--426 TJm
-(or) 11.9551 Tj
--426 TJm
-(BZ2_bzReadGetUnused) 113.574 Tj
-98.4879 306.949 Td
-(if) 11.9551 Tj
--426 TJm
-(bzerror) 41.8429 Tj
--426 TJm
-(is) 11.9551 Tj
--426 TJm
-(BZ_SEQUENCE_END) 89.6634 Tj
-90 294.994 Td
-(BZ2_bzReadClose) 89.6634 Tj
-98.4879 283.039 Td
-(otherwise) 53.798 Tj
-[1 0 0 1 72 267.497] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 468 3.5866] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -468 -3.5866] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.9626] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -257.534] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 236.876 Td
-/F122_0 17.2154 Tf
-(3.4.3.) 43.0729 Tj
-[1 0 0 1 119.858 236.876] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -119.858 -236.876] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-119.858 236.876 Td
-/F392_0 17.2154 Tf
-(BZ2_bzReadGetUnused) 196.256 Tj
-[1 0 0 1 316.114 236.876] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -244.114 -2.3327] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -36.8617] cm
-/DeviceRGB {} cs
-[0.94899 0.94899 0.976456] sc
-/DeviceRGB {} CS
-[0.94899 0.94899 0.976456] SC
-0 0 468 35.8655 re
-f
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 3.5866] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 32.2789] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 18 -8.3686] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -90 -225.178] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-90 225.178 Td
-/F134_0 9.9626 Tf
-(void) 23.9102 Tj
--426 TJm
-(BZ2_bzReadGetUnused\() 119.551 Tj
--426 TJm
-(int) 17.9327 Tj
-259.883 223.435 Td
-(*) 5.97756 Tj
-270.104 225.178 Td
-(bzerror,) 47.8205 Tj
--426 TJm
-(BZFILE) 35.8654 Tj
-362.278 223.435 Td
-(*) 5.97756 Tj
-368.256 225.178 Td
-(b,) 11.9551 Tj
-200.343 213.223 Td
-(void) 23.9102 Tj
-224.254 211.48 Td
-(**) 11.9551 Tj
-240.453 213.223 Td
-(unused,) 41.8429 Tj
--426 TJm
-(int) 17.9327 Tj
-304.473 211.48 Td
-(*) 5.97756 Tj
-314.694 213.223 Td
-(nUnused) 41.8429 Tj
--426 TJm
-(\);) 11.9551 Tj
-[1 0 0 1 72 197.681] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 468 3.5866] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -468 -13.5492] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -187.719] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 175.764 Td
-/F130_0 9.9626 Tf
-(Returns) 30.9936 Tj
--435 TJm
-(data) 16.5977 Tj
--435 TJm
-(which) 24.3486 Tj
--435 TJm
-(w) 7.193 Tj
-10 TJm
-(as) 8.29885 Tj
--435 TJm
-(read) 17.1456 Tj
--435 TJm
-(from) 19.3673 Tj
--435 TJm
-(the) 12.1743 Tj
--435 TJm
-(compressed) 47.0334 Tj
--435 TJm
-(\002le) 12.7322 Tj
--435 TJm
-(b) 4.9813 Tj
-20 TJm
-(ut) 7.7509 Tj
--435 TJm
-(w) 7.193 Tj
-10 TJm
-(as) 8.29885 Tj
--435 TJm
-(not) 12.7322 Tj
--435 TJm
-(needed) 28.2141 Tj
--435 TJm
-(to) 7.7509 Tj
--435 TJm
-(get) 12.1743 Tj
--435 TJm
-(to) 7.7509 Tj
--435 TJm
-(the) 12.1743 Tj
--435 TJm
-(logical) 27.1182 Tj
--435 TJm
-(end-of-stream.) 58.3709 Tj
-[1 0 0 1 72 163.809] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -163.809] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 162.065 Td
-/F134_0 9.9626 Tf
-(*) 5.97756 Tj
-77.9776 163.809 Td
-(unused) 35.8654 Tj
-[1 0 0 1 113.843 163.809] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -113.843 -163.809] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-117.2 163.809 Td
-/F130_0 9.9626 Tf
-(is) 6.64505 Tj
--337 TJm
-(set) 11.0684 Tj
--337 TJm
-(to) 7.7509 Tj
--337 TJm
-(the) 12.1743 Tj
--337 TJm
-(address) 29.8778 Tj
--337 TJm
-(of) 8.29885 Tj
--336 TJm
-(the) 12.1743 Tj
--337 TJm
-(data,) 19.0883 Tj
--359 TJm
-(and) 14.386 Tj
-[1 0 0 1 269.089 163.809] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -269.089 -163.809] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-269.089 162.065 Td
-/F134_0 9.9626 Tf
-(*) 5.97756 Tj
-275.067 163.809 Td
-(nUnused) 41.8429 Tj
-[1 0 0 1 316.91 163.809] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -316.91 -163.809] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-320.267 163.809 Td
-/F130_0 9.9626 Tf
-(to) 7.7509 Tj
--337 TJm
-(the) 12.1743 Tj
--337 TJm
-(number) 30.4357 Tj
--337 TJm
-(of) 8.29885 Tj
--337 TJm
-(bytes.) 23.5217 Tj
-[1 0 0 1 427.247 163.809] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -427.247 -163.809] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-427.247 162.065 Td
-/F134_0 9.9626 Tf
-(*) 5.97756 Tj
-433.225 163.809 Td
-(nUnused) 41.8429 Tj
-[1 0 0 1 475.068 163.809] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -475.068 -163.809] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-478.425 163.809 Td
-/F130_0 9.9626 Tf
-(will) 15.5018 Tj
--337 TJm
-(be) 9.40469 Tj
--337 TJm
-(set) 11.0684 Tj
--337 TJm
-(to) 7.7509 Tj
--337 TJm
-(a) 4.42339 Tj
-72 151.853 Td
-(v) 4.9813 Tj
-25 TJm
-(alue) 16.5977 Tj
--250 TJm
-(between) 33.1954 Tj
-[1 0 0 1 131.506 151.853] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -131.506 -151.853] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-131.506 151.853 Td
-/F134_0 9.9626 Tf
-(0) 5.97756 Tj
-[1 0 0 1 137.484 151.853] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -137.484 -151.853] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-139.975 151.853 Td
-/F130_0 9.9626 Tf
-(and) 14.386 Tj
-[1 0 0 1 156.851 151.853] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -156.851 -151.853] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-156.851 151.853 Td
-/F134_0 9.9626 Tf
-(BZ_MAX_UNUSED) 77.7083 Tj
-[1 0 0 1 234.56 151.853] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -234.56 -151.853] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-237.05 151.853 Td
-/F130_0 9.9626 Tf
-(inclusi) 26.5703 Tj
-25 TJm
-(v) 4.9813 Tj
-15 TJm
-(e.) 6.91404 Tj
-[1 0 0 1 72 150.543] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.9626] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -140.581] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 129.935 Td
-/F130_0 9.9626 Tf
-(This) 17.7135 Tj
--882 TJm
-(function) 33.2053 Tj
--883 TJm
-(may) 17.1556 Tj
--882 TJm
-(only) 17.7135 Tj
--883 TJm
-(be) 9.40469 Tj
--882 TJm
-(called) 23.7907 Tj
--883 TJm
-(once) 18.8094 Tj
-[1 0 0 1 271.332 129.935] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -271.332 -129.935] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-271.332 129.935 Td
-/F134_0 9.9626 Tf
-(BZ2_bzRead) 59.7756 Tj
-[1 0 0 1 331.108 129.935] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -331.108 -129.935] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-339.9 129.935 Td
-/F130_0 9.9626 Tf
-(has) 13.2801 Tj
--882 TJm
-(signalled) 35.9749 Tj
-[1 0 0 1 406.737 129.935] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -406.737 -129.935] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-406.737 129.935 Td
-/F134_0 9.9626 Tf
-(BZ_STREAM_END) 77.7083 Tj
-[1 0 0 1 484.446 129.935] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -484.446 -129.935] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-493.231 129.935 Td
-/F130_0 9.9626 Tf
-(b) 4.9813 Tj
-20 TJm
-(ut) 7.7509 Tj
--882 TJm
-(before) 25.4445 Tj
-[1 0 0 1 72 117.98] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -117.98] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 117.98 Td
-/F134_0 9.9626 Tf
-(BZ2_bzReadClose) 89.6634 Tj
-[1 0 0 1 161.664 117.98] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -161.664 -117.98] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-161.664 117.98 Td
-/F130_0 9.9626 Tf
-(.) 2.49065 Tj
-[1 0 0 1 72 116.67] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.9626] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -106.708] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 96.0625 Td
-/F130_0 9.9626 Tf
-(Possible) 33.2153 Tj
--250 TJm
-(assignments) 48.7072 Tj
--250 TJm
-(to) 7.7509 Tj
-[1 0 0 1 169.144 96.0625] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -169.144 -96.0625] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-169.144 96.0625 Td
-/F134_0 9.9626 Tf
-(bzerror) 41.8429 Tj
-[1 0 0 1 210.987 96.0625] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -210.987 -96.0625] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-210.987 96.0625 Td
-/F130_0 9.9626 Tf
-(:) 2.7696 Tj
-[1 0 0 1 72 93.9057] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -43.0539] cm
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-[1 0 0 1 1.8929 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 374.394 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 6.7546] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 40.5726 -6.7546] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -493.841 -50.8518] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-534.414 50.8518 Td
-/F130_0 9.9626 Tf
-(21) 9.9626 Tj
-[1 0 0 1 453.269 50.8518] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 93.5985 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 6.2765 0] cm
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-[1 0 0 1 -13.1436 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-Q
-showpage
-%%PageTrailer
-pdfEndPage
-%%Page: 25 25
-%%BeginPageSetup
-%%PageOrientation: Portrait
-pdfStartPage
-0 0 612 792 re W
-%%EndPageSetup
-[] 0 d
-1 i
-0 j
-0 J
-10 M
-1 w
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-false op
-false OP
-0 0 612 792 re
-W
-q
-[1 0 0 1 72 741.554] cm
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-[1 0 0 1 1.8929 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 14.4459] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 187.197 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 -8.9114] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 8.9114] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 76.4979 -6.7546] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -342.569 -749.245] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-419.067 749.245 Td
-/F130_0 9.9626 Tf
-(Programming) 54.7943 Tj
--250 TJm
-(with) 17.7135 Tj
-[1 0 0 1 496.556 749.245] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -496.556 -749.245] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-496.556 749.245 Td
-/F134_0 9.9626 Tf
-(libbzip2) 47.8205 Tj
-[1 0 0 1 544.376 749.245] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -278.305 -2.1568] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 280.796 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -472.974 -5.0363] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -0.4981] cm
-q
-[] 0 d
-0 J
-0.4981 w
-0 0.2491 m
-475.465 0.2491 l
-S
-Q
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 479.251 0] cm
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-[1 0 0 1 -13.1436 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -468 -129.151] cm
-/DeviceRGB {} cs
-[0.94899 0.94899 0.976456] sc
-/DeviceRGB {} CS
-[0.94899 0.94899 0.976456] SC
-0 0 468 107.597 re
-f
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 3.5866] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 104.01] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 18 -8.3686] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -90 -711.631] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-90 711.631 Td
-/F134_0 9.9626 Tf
-(BZ_PARAM_ERROR) 83.6858 Tj
-98.4879 699.676 Td
-(if) 11.9551 Tj
--426 TJm
-(b) 5.97756 Tj
--426 TJm
-(is) 11.9551 Tj
--426 TJm
-(NULL) 23.9102 Tj
-98.4879 687.721 Td
-(or) 11.9551 Tj
--426 TJm
-(unused) 35.8654 Tj
--426 TJm
-(is) 11.9551 Tj
--426 TJm
-(NULL) 23.9102 Tj
--426 TJm
-(or) 11.9551 Tj
--426 TJm
-(nUnused) 41.8429 Tj
--426 TJm
-(is) 11.9551 Tj
--426 TJm
-(NULL) 23.9102 Tj
-90 675.766 Td
-(BZ_SEQUENCE_ERROR) 101.619 Tj
-98.4879 663.811 Td
-(if) 11.9551 Tj
--426 TJm
-(BZ_STREAM_END) 77.7083 Tj
--426 TJm
-(has) 17.9327 Tj
--426 TJm
-(not) 17.9327 Tj
--426 TJm
-(been) 23.9102 Tj
--426 TJm
-(signalled) 53.798 Tj
-98.4879 651.856 Td
-(or) 11.9551 Tj
--426 TJm
-(if) 11.9551 Tj
--426 TJm
-(b) 5.97756 Tj
--426 TJm
-(was) 17.9327 Tj
--426 TJm
-(opened) 35.8654 Tj
--426 TJm
-(with) 23.9102 Tj
--426 TJm
-(BZ2_bzWriteOpen) 89.6634 Tj
-90 639.9 Td
-(BZ_OK) 29.8878 Tj
-98.4879 627.945 Td
-(otherwise) 53.798 Tj
-[1 0 0 1 72 612.404] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 468 3.5866] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -468 -13.5492] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -602.441] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 590.486 Td
-/F130_0 9.9626 Tf
-(Allo) 17.7135 Tj
-25 TJm
-(w) 7.193 Tj
-10 TJm
-(able) 16.5977 Tj
--250 TJm
-(ne) 9.40469 Tj
-15 TJm
-(xt) 7.7509 Tj
--250 TJm
-(actions:) 30.9936 Tj
-[1 0 0 1 72 590.386] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -24.9066] cm
-/DeviceRGB {} cs
-[0.94899 0.94899 0.976456] sc
-/DeviceRGB {} CS
-[0.94899 0.94899 0.976456] SC
-0 0 468 23.9103 re
-f
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 3.5866] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 20.3238] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 18 -8.3686] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -90 -581.021] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-90 581.021 Td
-/F134_0 9.9626 Tf
-(BZ2_bzReadClose) 89.6634 Tj
-[1 0 0 1 72 565.48] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 468 3.5866] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -468 -3.5866] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.9626] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -555.517] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 534.858 Td
-/F122_0 17.2154 Tf
-(3.4.4.) 43.0729 Tj
-[1 0 0 1 119.858 534.858] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -119.858 -534.858] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-119.858 534.858 Td
-/F392_0 17.2154 Tf
-(BZ2_bzReadClose) 154.939 Tj
-[1 0 0 1 274.797 534.858] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -202.797 -2.3327] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -24.9066] cm
-/DeviceRGB {} cs
-[0.94899 0.94899 0.976456] sc
-/DeviceRGB {} CS
-[0.94899 0.94899 0.976456] SC
-0 0 468 23.9103 re
-f
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 3.5866] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 20.3237] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 18 -8.3685] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -90 -523.161] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-90 523.161 Td
-/F134_0 9.9626 Tf
-(void) 23.9102 Tj
--426 TJm
-(BZ2_bzReadClose) 89.6634 Tj
--426 TJm
-(\() 5.97756 Tj
--426 TJm
-(int) 17.9327 Tj
-244.46 521.417 Td
-(*) 5.97756 Tj
-250.438 523.161 Td
-(bzerror,) 47.8205 Tj
--426 TJm
-(BZFILE) 35.8654 Tj
-342.612 521.417 Td
-(*) 5.97756 Tj
-348.59 523.161 Td
-(b) 5.97756 Tj
--426 TJm
-(\);) 11.9551 Tj
-[1 0 0 1 72 507.619] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 468 3.5866] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -468 -13.5492] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -497.656] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 485.701 Td
-/F130_0 9.9626 Tf
-(Releases) 34.8591 Tj
--430 TJm
-(all) 9.9626 Tj
--429 TJm
-(memory) 33.2053 Tj
--430 TJm
-(pertaining) 40.3983 Tj
--429 TJm
-(to) 7.7509 Tj
--430 TJm
-(the) 12.1743 Tj
--429 TJm
-(compressed) 47.0334 Tj
--430 TJm
-(\002le) 12.7322 Tj
-[1 0 0 1 304.352 485.701] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -304.352 -485.701] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-304.352 485.701 Td
-/F134_0 9.9626 Tf
-(b) 5.97756 Tj
-[1 0 0 1 310.33 485.701] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -310.33 -485.701] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-310.33 485.701 Td
-/F130_0 9.9626 Tf
-(.) 2.49065 Tj
-[1 0 0 1 321.276 485.701] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -321.276 -485.701] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-321.276 485.701 Td
-/F134_0 9.9626 Tf
-(BZ2_bzReadClose) 89.6634 Tj
-[1 0 0 1 410.94 485.701] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -410.94 -485.701] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-415.22 485.701 Td
-/F130_0 9.9626 Tf
-(does) 18.2614 Tj
--430 TJm
-(not) 12.7322 Tj
--429 TJm
-(call) 14.386 Tj
-[1 0 0 1 473.438 485.701] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -473.438 -485.701] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-473.438 485.701 Td
-/F134_0 9.9626 Tf
-(fclose) 35.8654 Tj
-[1 0 0 1 509.304 485.701] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -509.304 -485.701] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-513.584 485.701 Td
-/F130_0 9.9626 Tf
-(on) 9.9626 Tj
--430 TJm
-(the) 12.1743 Tj
-72 473.746 Td
-(underlying) 43.1679 Tj
--264 TJm
-(\002le) 12.7322 Tj
--264 TJm
-(handle,) 29.0509 Tj
--267 TJm
-(so) 8.85675 Tj
--264 TJm
-(you) 14.9439 Tj
--264 TJm
-(should) 26.5703 Tj
--264 TJm
-(do) 9.9626 Tj
--264 TJm
-(that) 14.9439 Tj
--264 TJm
-(yourself) 32.6474 Tj
--264 TJm
-(if) 6.08715 Tj
--263 TJm
-(appropriate.) 47.8603 Tj
-[1 0 0 1 348.653 473.746] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -348.653 -473.746] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-348.653 473.746 Td
-/F134_0 9.9626 Tf
-(BZ2_bzReadClose) 89.6634 Tj
-[1 0 0 1 438.317 473.746] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -438.317 -473.746] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-440.946 473.746 Td
-/F130_0 9.9626 Tf
-(should) 26.5703 Tj
--264 TJm
-(be) 9.40469 Tj
--264 TJm
-(called) 23.7907 Tj
--264 TJm
-(to) 7.7509 Tj
--264 TJm
-(clean) 21.0211 Tj
-72 461.791 Td
-(up) 9.9626 Tj
--250 TJm
-(after) 18.2515 Tj
--250 TJm
-(all) 9.9626 Tj
--250 TJm
-(error) 19.3573 Tj
--250 TJm
-(situations.) 40.6873 Tj
-[1 0 0 1 72 459.634] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.9626] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -449.671] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 439.873 Td
-/F130_0 9.9626 Tf
-(Possible) 33.2153 Tj
--250 TJm
-(assignments) 48.7072 Tj
--250 TJm
-(to) 7.7509 Tj
-[1 0 0 1 169.144 439.873] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -169.144 -439.873] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-169.144 439.873 Td
-/F134_0 9.9626 Tf
-(bzerror) 41.8429 Tj
-[1 0 0 1 210.987 439.873] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -210.987 -439.873] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-210.987 439.873 Td
-/F130_0 9.9626 Tf
-(:) 2.7696 Tj
-[1 0 0 1 72 437.716] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -60.7721] cm
-/DeviceRGB {} cs
-[0.94899 0.94899 0.976456] sc
-/DeviceRGB {} CS
-[0.94899 0.94899 0.976456] SC
-0 0 468 59.7758 re
-f
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 3.5866] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 56.1893] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 18 -8.3686] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -90 -428.351] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-90 428.351 Td
-/F134_0 9.9626 Tf
-(BZ_SEQUENCE_ERROR) 101.619 Tj
-98.4879 416.396 Td
-(if) 11.9551 Tj
--426 TJm
-(b) 5.97756 Tj
--426 TJm
-(was) 17.9327 Tj
--426 TJm
-(opened) 35.8654 Tj
--426 TJm
-(with) 23.9102 Tj
--426 TJm
-(BZ2_bzOpenWrite) 89.6634 Tj
-90 404.441 Td
-(BZ_OK) 29.8878 Tj
-98.4879 392.486 Td
-(otherwise) 53.798 Tj
-[1 0 0 1 72 376.944] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 468 3.5866] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -468 -13.5492] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -366.982] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 355.026 Td
-/F130_0 9.9626 Tf
-(Allo) 17.7135 Tj
-25 TJm
-(w) 7.193 Tj
-10 TJm
-(able) 16.5977 Tj
--250 TJm
-(ne) 9.40469 Tj
-15 TJm
-(xt) 7.7509 Tj
--250 TJm
-(actions:) 30.9936 Tj
-[1 0 0 1 72 354.927] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -24.9066] cm
-/DeviceRGB {} cs
-[0.94899 0.94899 0.976456] sc
-/DeviceRGB {} CS
-[0.94899 0.94899 0.976456] SC
-0 0 468 23.9103 re
-f
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 3.5866] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 20.3237] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 18 -8.3686] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -90 -345.562] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-90 345.562 Td
-/F134_0 9.9626 Tf
-(none) 23.9102 Tj
-[1 0 0 1 72 330.02] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 468 3.5866] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -468 -3.5866] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.9627] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -320.058] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 299.399 Td
-/F122_0 17.2154 Tf
-(3.4.5.) 43.0729 Tj
-[1 0 0 1 119.858 299.399] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -119.858 -299.399] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-119.858 299.399 Td
-/F392_0 17.2154 Tf
-(BZ2_bzWriteOpen) 154.939 Tj
-[1 0 0 1 274.797 299.399] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -202.797 -2.3327] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -48.8169] cm
-/DeviceRGB {} cs
-[0.94899 0.94899 0.976456] sc
-/DeviceRGB {} CS
-[0.94899 0.94899 0.976456] SC
-0 0 468 47.8207 re
-f
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 3.5866] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 44.2341] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 18 -8.3686] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -90 -287.702] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-90 287.702 Td
-/F134_0 9.9626 Tf
-(BZFILE) 35.8654 Tj
-130.109 285.958 Td
-(*) 5.97756 Tj
-136.087 287.702 Td
-(BZ2_bzWriteOpen\() 95.641 Tj
--426 TJm
-(int) 17.9327 Tj
-258.149 285.958 Td
-(*) 5.97756 Tj
-264.127 287.702 Td
-(bzerror,) 47.8205 Tj
--426 TJm
-(FILE) 23.9102 Tj
-344.346 285.958 Td
-(*) 5.97756 Tj
-350.323 287.702 Td
-(f,) 11.9551 Tj
-196.099 275.746 Td
-(int) 17.9327 Tj
--426 TJm
-(blockSize100k,) 83.6858 Tj
--426 TJm
-(int) 17.9327 Tj
--426 TJm
-(verbosity,) 59.7756 Tj
-196.099 263.791 Td
-(int) 17.9327 Tj
--426 TJm
-(workFactor) 59.7756 Tj
--426 TJm
-(\);) 11.9551 Tj
-[1 0 0 1 72 248.249] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 468 3.5866] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -468 -13.5492] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -238.287] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 226.332 Td
-/F130_0 9.9626 Tf
-(Prepare) 30.4258 Tj
--268 TJm
-(to) 7.7509 Tj
--269 TJm
-(write) 20.4731 Tj
--268 TJm
-(compressed) 47.0334 Tj
--269 TJm
-(data) 16.5977 Tj
--268 TJm
-(to) 7.7509 Tj
--269 TJm
-(\002le) 12.7322 Tj
--268 TJm
-(handle) 26.5603 Tj
-[1 0 0 1 262.72 226.332] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -262.72 -226.332] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-262.72 226.332 Td
-/F134_0 9.9626 Tf
-(f) 5.97756 Tj
-[1 0 0 1 268.698 226.332] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -268.698 -226.332] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-268.698 226.332 Td
-/F130_0 9.9626 Tf
-(.) 2.49065 Tj
-[1 0 0 1 274.829 226.332] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -274.829 -226.332] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-274.829 226.332 Td
-/F134_0 9.9626 Tf
-(f) 5.97756 Tj
-[1 0 0 1 280.807 226.332] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -280.807 -226.332] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-283.481 226.332 Td
-/F130_0 9.9626 Tf
-(should) 26.5703 Tj
--268 TJm
-(refer) 18.7994 Tj
--269 TJm
-(to) 7.7509 Tj
--268 TJm
-(a) 4.42339 Tj
--269 TJm
-(\002le) 12.7322 Tj
--268 TJm
-(which) 24.3486 Tj
--269 TJm
-(has) 13.2801 Tj
--268 TJm
-(been) 18.8094 Tj
--269 TJm
-(opened) 28.772 Tj
--268 TJm
-(for) 11.6164 Tj
--269 TJm
-(writing,) 31.2726 Tj
--273 TJm
-(and) 14.386 Tj
--268 TJm
-(for) 11.6164 Tj
-72 214.377 Td
-(which) 24.3486 Tj
--250 TJm
-(the) 12.1743 Tj
--250 TJm
-(error) 19.3573 Tj
--250 TJm
-(indicator) 35.417 Tj
--250 TJm
-(\() 3.31755 Tj
-[1 0 0 1 176.577 214.376] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -176.577 -214.376] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-176.577 214.376 Td
-/F134_0 9.9626 Tf
-(ferror\(f\)) 53.798 Tj
-[1 0 0 1 230.375 214.376] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -230.375 -214.376] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-230.375 214.376 Td
-/F130_0 9.9626 Tf
-(\)is) 9.9626 Tj
--250 TJm
-(not) 12.7322 Tj
--250 TJm
-(set.) 13.5591 Tj
-[1 0 0 1 72 212.593] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.9626] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -202.631] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 192.459 Td
-/F130_0 9.9626 Tf
-(F) 5.53921 Tj
-15 TJm
-(or) 8.29885 Tj
--223 TJm
-(the) 12.1743 Tj
--224 TJm
-(meaning) 34.3112 Tj
--223 TJm
-(of) 8.29885 Tj
--224 TJm
-(parameters) 43.7059 Tj
-[1 0 0 1 195.306 192.459] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -195.306 -192.459] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-195.306 192.459 Td
-/F134_0 9.9626 Tf
-(blockSize100k) 77.7083 Tj
-[1 0 0 1 273.015 192.459] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -273.015 -192.459] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-273.015 192.459 Td
-/F130_0 9.9626 Tf
-(,) 2.49065 Tj
-[1 0 0 1 277.784 192.459] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -277.784 -192.459] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-277.784 192.459 Td
-/F134_0 9.9626 Tf
-(verbosity) 53.798 Tj
-[1 0 0 1 331.583 192.459] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -331.583 -192.459] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-333.808 192.459 Td
-/F130_0 9.9626 Tf
-(and) 14.386 Tj
-[1 0 0 1 350.42 192.459] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -350.42 -192.459] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-350.42 192.459 Td
-/F134_0 9.9626 Tf
-(workFactor) 59.7756 Tj
-[1 0 0 1 410.196 192.459] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -410.196 -192.459] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-410.196 192.459 Td
-/F130_0 9.9626 Tf
-(,) 2.49065 Tj
--229 TJm
-(see) 12.7222 Tj
-[1 0 0 1 429.913 192.459] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -429.913 -192.459] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-429.913 192.459 Td
-/F134_0 9.9626 Tf
-(BZ2_bzCompressInit) 107.596 Tj
-[1 0 0 1 537.509 192.459] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -537.509 -192.459] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-537.509 192.459 Td
-/F130_0 9.9626 Tf
-(.) 2.49065 Tj
-[1 0 0 1 72 190.302] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.9626] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -180.339] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 170.541 Td
-/F130_0 9.9626 Tf
-(All) 12.7322 Tj
--382 TJm
-(required) 33.1954 Tj
--382 TJm
-(memory) 33.2053 Tj
--382 TJm
-(is) 6.64505 Tj
--382 TJm
-(allocated) 35.965 Tj
--383 TJm
-(at) 7.193 Tj
--382 TJm
-(this) 14.396 Tj
--382 TJm
-(stage,) 22.9638 Tj
--415 TJm
-(so) 8.85675 Tj
--382 TJm
-(if) 6.08715 Tj
--382 TJm
-(the) 12.1743 Tj
--382 TJm
-(call) 14.386 Tj
--382 TJm
-(completes) 40.3983 Tj
--382 TJm
-(successfully) 48.6972 Tj
-65 TJm
-(,) 2.49065 Tj
-[1 0 0 1 424.691 170.541] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -424.691 -170.541] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-424.691 170.541 Td
-/F134_0 9.9626 Tf
-(BZ_MEM_ERROR) 71.7307 Tj
-[1 0 0 1 496.422 170.541] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -496.422 -170.541] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-500.228 170.541 Td
-/F130_0 9.9626 Tf
-(cannot) 26.5603 Tj
--382 TJm
-(be) 9.40469 Tj
-72 158.586 Td
-(signalled) 35.9749 Tj
--250 TJm
-(by) 9.9626 Tj
--250 TJm
-(a) 4.42339 Tj
--250 TJm
-(subsequent) 44.2738 Tj
--250 TJm
-(call) 14.386 Tj
--250 TJm
-(to) 7.7509 Tj
-[1 0 0 1 203.715 158.586] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -203.715 -158.586] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-203.715 158.586 Td
-/F134_0 9.9626 Tf
-(BZ2_bzWrite) 65.7532 Tj
-[1 0 0 1 269.468 158.586] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -269.468 -158.586] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-269.468 158.586 Td
-/F130_0 9.9626 Tf
-(.) 2.49065 Tj
-[1 0 0 1 72 156.429] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.9626] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -146.466] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 136.668 Td
-/F130_0 9.9626 Tf
-(Possible) 33.2153 Tj
--250 TJm
-(assignments) 48.7072 Tj
--250 TJm
-(to) 7.7509 Tj
-[1 0 0 1 169.144 136.668] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -169.144 -136.668] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-169.144 136.668 Td
-/F134_0 9.9626 Tf
-(bzerror) 41.8429 Tj
-[1 0 0 1 210.987 136.668] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -210.987 -136.668] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-210.987 136.668 Td
-/F130_0 9.9626 Tf
-(:) 2.7696 Tj
-[1 0 0 1 72 134.511] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -83.6593] cm
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-[1 0 0 1 1.8929 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 374.394 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 6.7546] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 40.5726 -6.7546] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -493.841 -50.8518] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-534.414 50.8518 Td
-/F130_0 9.9626 Tf
-(22) 9.9626 Tj
-[1 0 0 1 453.269 50.8518] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 93.5985 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 6.2765 0] cm
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-[1 0 0 1 -13.1436 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-Q
-showpage
-%%PageTrailer
-pdfEndPage
-%%Page: 26 26
-%%BeginPageSetup
-%%PageOrientation: Portrait
-pdfStartPage
-0 0 612 792 re W
-%%EndPageSetup
-[] 0 d
-1 i
-0 j
-0 J
-10 M
-1 w
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-false op
-false OP
-0 0 612 792 re
-W
-q
-[1 0 0 1 72 741.554] cm
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-[1 0 0 1 1.8929 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 14.4459] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 187.197 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 -8.9114] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 8.9114] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 76.4979 -6.7546] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -342.569 -749.245] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-419.067 749.245 Td
-/F130_0 9.9626 Tf
-(Programming) 54.7943 Tj
--250 TJm
-(with) 17.7135 Tj
-[1 0 0 1 496.556 749.245] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -496.556 -749.245] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-496.556 749.245 Td
-/F134_0 9.9626 Tf
-(libbzip2) 47.8205 Tj
-[1 0 0 1 544.376 749.245] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -278.305 -2.1568] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 280.796 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -472.974 -5.0363] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -0.4981] cm
-q
-[] 0 d
-0 J
-0.4981 w
-0 0.2491 m
-475.465 0.2491 l
-S
-Q
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 479.251 0] cm
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-[1 0 0 1 -13.1436 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -468 -165.016] cm
-/DeviceRGB {} cs
-[0.94899 0.94899 0.976456] sc
-/DeviceRGB {} CS
-[0.94899 0.94899 0.976456] SC
-0 0 468 143.462 re
-f
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 3.5866] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 139.875] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 18 -8.3686] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -90 -711.631] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-90 711.631 Td
-/F134_0 9.9626 Tf
-(BZ_CONFIG_ERROR) 89.6634 Tj
-98.4879 699.676 Td
-(if) 11.9551 Tj
--426 TJm
-(the) 17.9327 Tj
--426 TJm
-(library) 41.8429 Tj
--426 TJm
-(has) 17.9327 Tj
--426 TJm
-(been) 23.9102 Tj
--426 TJm
-(mis-compiled) 71.7307 Tj
-90 687.721 Td
-(BZ_PARAM_ERROR) 83.6858 Tj
-98.4879 675.766 Td
-(if) 11.9551 Tj
--426 TJm
-(f) 5.97756 Tj
--426 TJm
-(is) 11.9551 Tj
--426 TJm
-(NULL) 23.9102 Tj
-98.4879 663.811 Td
-(or) 11.9551 Tj
--426 TJm
-(blockSize100k) 77.7083 Tj
--426 TJm
-(<) 5.97756 Tj
--426 TJm
-(1) 5.97756 Tj
--426 TJm
-(or) 11.9551 Tj
--426 TJm
-(blockSize100k) 77.7083 Tj
--426 TJm
-(>) 5.97756 Tj
--426 TJm
-(9) 5.97756 Tj
-90 651.856 Td
-(BZ_IO_ERROR) 65.7532 Tj
-98.4879 639.9 Td
-(if) 11.9551 Tj
--426 TJm
-(ferror\(f\)) 53.798 Tj
--426 TJm
-(is) 11.9551 Tj
--426 TJm
-(nonzero) 41.8429 Tj
-90 627.945 Td
-(BZ_MEM_ERROR) 71.7307 Tj
-98.4879 615.99 Td
-(if) 11.9551 Tj
--426 TJm
-(insufficient) 71.7307 Tj
--426 TJm
-(memory) 35.8654 Tj
--426 TJm
-(is) 11.9551 Tj
--426 TJm
-(available) 53.798 Tj
-90 604.035 Td
-(BZ_OK) 29.8878 Tj
-98.4879 592.08 Td
-(otherwise) 53.798 Tj
-[1 0 0 1 72 576.538] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 468 3.5866] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -468 -13.5492] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -566.575] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 554.62 Td
-/F130_0 9.9626 Tf
-(Possible) 33.2153 Tj
--250 TJm
-(return) 23.7907 Tj
--250 TJm
-(v) 4.9813 Tj
-25 TJm
-(alues:) 23.2427 Tj
-[1 0 0 1 72 554.521] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -60.7721] cm
-/DeviceRGB {} cs
-[0.94899 0.94899 0.976456] sc
-/DeviceRGB {} CS
-[0.94899 0.94899 0.976456] SC
-0 0 468 59.7758 re
-f
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 3.5866] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 56.1892] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 18 -8.3686] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -90 -545.156] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-90 545.156 Td
-/F134_0 9.9626 Tf
-(Pointer) 41.8429 Tj
--426 TJm
-(to) 11.9551 Tj
--426 TJm
-(an) 11.9551 Tj
--426 TJm
-(abstract) 47.8205 Tj
--426 TJm
-(BZFILE) 35.8654 Tj
-98.4879 533.201 Td
-(if) 11.9551 Tj
--426 TJm
-(bzerror) 41.8429 Tj
--426 TJm
-(is) 11.9551 Tj
--426 TJm
-(BZ_OK) 29.8878 Tj
-90 521.245 Td
-(NULL) 23.9102 Tj
-98.4879 509.29 Td
-(otherwise) 53.798 Tj
-[1 0 0 1 72 493.748] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 468 3.5866] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -468 -13.5492] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -483.786] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 471.831 Td
-/F130_0 9.9626 Tf
-(Allo) 17.7135 Tj
-25 TJm
-(w) 7.193 Tj
-10 TJm
-(able) 16.5977 Tj
--250 TJm
-(ne) 9.40469 Tj
-15 TJm
-(xt) 7.7509 Tj
--250 TJm
-(actions:) 30.9936 Tj
-[1 0 0 1 72 471.731] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -84.6825] cm
-/DeviceRGB {} cs
-[0.94899 0.94899 0.976456] sc
-/DeviceRGB {} CS
-[0.94899 0.94899 0.976456] SC
-0 0 468 83.6862 re
-f
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 3.5866] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 80.0996] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 18 -8.3686] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -90 -462.366] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-90 462.366 Td
-/F134_0 9.9626 Tf
-(BZ2_bzWrite) 65.7532 Tj
-98.4879 450.411 Td
-(if) 11.9551 Tj
--426 TJm
-(bzerror) 41.8429 Tj
--426 TJm
-(is) 11.9551 Tj
--426 TJm
-(BZ_OK) 29.8878 Tj
-98.4879 438.456 Td
-(\(you) 23.9102 Tj
--426 TJm
-(could) 29.8878 Tj
--426 TJm
-(go) 11.9551 Tj
--426 TJm
-(directly) 47.8205 Tj
--426 TJm
-(to) 11.9551 Tj
--426 TJm
-(BZ2_bzWriteClose,) 101.619 Tj
--426 TJm
-(but) 17.9327 Tj
--426 TJm
-(this) 23.9102 Tj
--426 TJm
-(would) 29.8878 Tj
--426 TJm
-(be) 11.9551 Tj
--426 TJm
-(pretty) 35.8654 Tj
-485.505 434.212 Td
-/F564_0 9.9626 Tf
-( ) 9.9626 Tj
-493.808 434.212 Td
-/F147_0 9.9626 Tf
-(-) 2.7696 Tj
-90 426.501 Td
-/F134_0 9.9626 Tf
-(pointless\)) 59.7756 Tj
-90 414.546 Td
-(BZ2_bzWriteClose) 95.641 Tj
-98.4879 402.59 Td
-(otherwise) 53.798 Tj
-[1 0 0 1 72 387.049] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 468 3.5866] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -468 -3.5866] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.9626] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -377.086] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 356.428 Td
-/F122_0 17.2154 Tf
-(3.4.6.) 43.0729 Tj
-[1 0 0 1 119.858 356.428] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -119.858 -356.428] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-119.858 356.428 Td
-/F392_0 17.2154 Tf
-(BZ2_bzWrite) 113.622 Tj
-[1 0 0 1 233.48 356.428] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -161.48 -2.3327] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -24.9066] cm
-/DeviceRGB {} cs
-[0.94899 0.94899 0.976456] sc
-/DeviceRGB {} CS
-[0.94899 0.94899 0.976456] SC
-0 0 468 23.9103 re
-f
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 3.5866] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 20.3237] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 18 -8.3685] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -90 -344.73] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-90 344.73 Td
-/F134_0 9.9626 Tf
-(void) 23.9102 Tj
--426 TJm
-(BZ2_bzWrite) 65.7532 Tj
--426 TJm
-(\() 5.97756 Tj
--426 TJm
-(int) 17.9327 Tj
-220.55 342.987 Td
-(*) 5.97756 Tj
-226.528 344.73 Td
-(bzerror,) 47.8205 Tj
--426 TJm
-(BZFILE) 35.8654 Tj
-318.702 342.987 Td
-(*) 5.97756 Tj
-324.679 344.73 Td
-(b,) 11.9551 Tj
--426 TJm
-(void) 23.9102 Tj
-369.033 342.987 Td
-(*) 5.97756 Tj
-375.01 344.73 Td
-(buf,) 23.9102 Tj
--426 TJm
-(int) 17.9327 Tj
--426 TJm
-(len) 17.9327 Tj
--426 TJm
-(\);) 11.9551 Tj
-[1 0 0 1 72 329.188] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 468 3.5866] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -468 -13.5492] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -319.226] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 307.27 Td
-/F130_0 9.9626 Tf
-(Absorbs) 33.2053 Tj
-[1 0 0 1 107.696 307.27] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -107.696 -307.27] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-107.696 307.27 Td
-/F134_0 9.9626 Tf
-(len) 17.9327 Tj
-[1 0 0 1 125.629 307.27] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -125.629 -307.27] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-128.119 307.27 Td
-/F130_0 9.9626 Tf
-(bytes) 21.031 Tj
--250 TJm
-(from) 19.3673 Tj
--250 TJm
-(the) 12.1743 Tj
--250 TJm
-(b) 4.9813 Tj
-20 TJm
-(uf) 8.29885 Tj
-25 TJm
-(fer) 11.0585 Tj
-[1 0 0 1 214.544 307.27] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -214.544 -307.27] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-214.544 307.27 Td
-/F134_0 9.9626 Tf
-(buf) 17.9327 Tj
-[1 0 0 1 232.477 307.27] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -232.477 -307.27] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-232.477 307.27 Td
-/F130_0 9.9626 Tf
-(,) 2.49065 Tj
--250 TJm
-(e) 4.42339 Tj
-25 TJm
-(v) 4.9813 Tj
-15 TJm
-(entually) 32.0995 Tj
--250 TJm
-(to) 7.7509 Tj
--250 TJm
-(be) 9.40469 Tj
--250 TJm
-(compressed) 47.0334 Tj
--250 TJm
-(and) 14.386 Tj
--250 TJm
-(written) 28.224 Tj
--250 TJm
-(to) 7.7509 Tj
--250 TJm
-(the) 12.1743 Tj
--250 TJm
-(\002le.) 15.2229 Tj
-[1 0 0 1 72 305.114] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.9627] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -295.151] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 285.353 Td
-/F130_0 9.9626 Tf
-(Possible) 33.2153 Tj
--250 TJm
-(assignments) 48.7072 Tj
--250 TJm
-(to) 7.7509 Tj
-[1 0 0 1 169.144 285.353] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -169.144 -285.353] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-169.144 285.353 Td
-/F134_0 9.9626 Tf
-(bzerror) 41.8429 Tj
-[1 0 0 1 210.987 285.353] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -210.987 -285.353] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-210.987 285.353 Td
-/F130_0 9.9626 Tf
-(:) 2.7696 Tj
-[1 0 0 1 72 283.196] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -108.593] cm
-/DeviceRGB {} cs
-[0.94899 0.94899 0.976456] sc
-/DeviceRGB {} CS
-[0.94899 0.94899 0.976456] SC
-0 0 468 107.597 re
-f
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 3.5866] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 104.01] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 18 -8.3686] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -90 -273.831] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-90 273.831 Td
-/F134_0 9.9626 Tf
-(BZ_PARAM_ERROR) 83.6858 Tj
-98.4879 261.876 Td
-(if) 11.9551 Tj
--426 TJm
-(b) 5.97756 Tj
--426 TJm
-(is) 11.9551 Tj
--426 TJm
-(NULL) 23.9102 Tj
--426 TJm
-(or) 11.9551 Tj
--426 TJm
-(buf) 17.9327 Tj
--426 TJm
-(is) 11.9551 Tj
--426 TJm
-(NULL) 23.9102 Tj
--426 TJm
-(or) 11.9551 Tj
--426 TJm
-(len) 17.9327 Tj
--426 TJm
-(<) 5.97756 Tj
--426 TJm
-(0) 5.97756 Tj
-90 249.921 Td
-(BZ_SEQUENCE_ERROR) 101.619 Tj
-98.4879 237.965 Td
-(if) 11.9551 Tj
--426 TJm
-(b) 5.97756 Tj
--426 TJm
-(was) 17.9327 Tj
--426 TJm
-(opened) 35.8654 Tj
--426 TJm
-(with) 23.9102 Tj
--426 TJm
-(BZ2_bzReadOpen) 83.6858 Tj
-90 226.01 Td
-(BZ_IO_ERROR) 65.7532 Tj
-98.4879 214.055 Td
-(if) 11.9551 Tj
--426 TJm
-(there) 29.8878 Tj
--426 TJm
-(is) 11.9551 Tj
--426 TJm
-(an) 11.9551 Tj
--426 TJm
-(error) 29.8878 Tj
--426 TJm
-(writing) 41.8429 Tj
--426 TJm
-(the) 17.9327 Tj
--426 TJm
-(compressed) 59.7756 Tj
--426 TJm
-(file.) 29.8878 Tj
-90 202.1 Td
-(BZ_OK) 29.8878 Tj
-98.4879 190.145 Td
-(otherwise) 53.798 Tj
-[1 0 0 1 72 174.603] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 468 3.5866] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -468 -3.5866] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.9626] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -164.64] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 143.982 Td
-/F122_0 17.2154 Tf
-(3.4.7.) 43.0729 Tj
-[1 0 0 1 119.858 143.982] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -119.858 -143.982] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-119.858 143.982 Td
-/F392_0 17.2154 Tf
-(BZ2_bzWriteClose) 165.268 Tj
-[1 0 0 1 285.126 143.982] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -213.126 -2.3326] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -90.7975] cm
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-[1 0 0 1 1.8929 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 374.394 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 6.8541] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 40.5726 -6.7545] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -493.841 -50.9514] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-534.414 50.9514 Td
-/F130_0 9.9626 Tf
-(23) 9.9626 Tj
-[1 0 0 1 453.269 50.8518] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 93.5985 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 6.2765 0] cm
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-[1 0 0 1 -13.1436 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-Q
-showpage
-%%PageTrailer
-pdfEndPage
-%%Page: 27 27
-%%BeginPageSetup
-%%PageOrientation: Portrait
-pdfStartPage
-0 0 612 792 re W
-%%EndPageSetup
-[] 0 d
-1 i
-0 j
-0 J
-10 M
-1 w
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-false op
-false OP
-0 0 612 792 re
-W
-q
-[1 0 0 1 72 741.554] cm
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-[1 0 0 1 1.8929 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 14.4459] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 187.197 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 -8.9114] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 8.9114] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 76.4979 -6.7546] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -342.569 -749.245] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-419.067 749.245 Td
-/F130_0 9.9626 Tf
-(Programming) 54.7943 Tj
--250 TJm
-(with) 17.7135 Tj
-[1 0 0 1 496.556 749.245] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -496.556 -749.245] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-496.556 749.245 Td
-/F134_0 9.9626 Tf
-(libbzip2) 47.8205 Tj
-[1 0 0 1 544.376 749.245] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -278.305 -2.1568] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 280.796 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -472.974 -5.0363] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -0.4981] cm
-q
-[] 0 d
-0 J
-0.4981 w
-0 0.2491 m
-475.465 0.2491 l
-S
-Q
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 479.251 0] cm
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-[1 0 0 1 -13.1436 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -468 -165.016] cm
-/DeviceRGB {} cs
-[0.94899 0.94899 0.976456] sc
-/DeviceRGB {} CS
-[0.94899 0.94899 0.976456] SC
-0 0 468 143.462 re
-f
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 3.5866] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 139.875] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 18 -8.3686] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -90 -711.631] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-90 711.631 Td
-/F134_0 9.9626 Tf
-(void) 23.9102 Tj
--426 TJm
-(BZ2_bzWriteClose\() 101.619 Tj
--426 TJm
-(int) 17.9327 Tj
-246.194 709.888 Td
-(*) 5.97756 Tj
-252.171 711.631 Td
-(bzerror,) 47.8205 Tj
--426 TJm
-(BZFILE) 35.8654 Tj
-340.102 709.888 Td
-(*) 5.97756 Tj
-350.323 711.631 Td
-(f,) 11.9551 Tj
-187.611 699.676 Td
-(int) 17.9327 Tj
--426 TJm
-(abandon,) 47.8205 Tj
-187.611 687.721 Td
-(unsigned) 47.8205 Tj
--426 TJm
-(int) 17.9327 Tj
-257.609 685.978 Td
-(*) 5.97756 Tj
-267.83 687.721 Td
-(nbytes_in,) 59.7756 Tj
-187.611 675.766 Td
-(unsigned) 47.8205 Tj
--426 TJm
-(int) 17.9327 Tj
-257.609 674.023 Td
-(*) 5.97756 Tj
-267.83 675.766 Td
-(nbytes_out) 59.7756 Tj
--426 TJm
-(\);) 11.9551 Tj
-90 651.856 Td
-(void) 23.9102 Tj
--426 TJm
-(BZ2_bzWriteClose64\() 113.574 Tj
--426 TJm
-(int) 17.9327 Tj
-258.149 650.112 Td
-(*) 5.97756 Tj
-264.127 651.856 Td
-(bzerror,) 47.8205 Tj
--426 TJm
-(BZFILE) 35.8654 Tj
-352.057 650.112 Td
-(*) 5.97756 Tj
-362.278 651.856 Td
-(f,) 11.9551 Tj
-196.099 639.9 Td
-(int) 17.9327 Tj
--426 TJm
-(abandon,) 47.8205 Tj
-196.099 627.945 Td
-(unsigned) 47.8205 Tj
--426 TJm
-(int) 17.9327 Tj
-266.097 626.202 Td
-(*) 5.97756 Tj
-276.318 627.945 Td
-(nbytes_in_lo32,) 89.6634 Tj
-196.099 615.99 Td
-(unsigned) 47.8205 Tj
--426 TJm
-(int) 17.9327 Tj
-266.097 614.247 Td
-(*) 5.97756 Tj
-276.318 615.99 Td
-(nbytes_in_hi32,) 89.6634 Tj
-196.099 604.035 Td
-(unsigned) 47.8205 Tj
--426 TJm
-(int) 17.9327 Tj
-266.097 602.292 Td
-(*) 5.97756 Tj
-276.318 604.035 Td
-(nbytes_out_lo32,) 95.641 Tj
-196.099 592.08 Td
-(unsigned) 47.8205 Tj
--426 TJm
-(int) 17.9327 Tj
-266.097 590.336 Td
-(*) 5.97756 Tj
-276.318 592.08 Td
-(nbytes_out_hi32) 89.6634 Tj
--426 TJm
-(\);) 11.9551 Tj
-[1 0 0 1 72 576.538] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 468 3.5866] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -468 -13.5492] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -566.575] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 554.62 Td
-/F130_0 9.9626 Tf
-(Compresses) 48.1492 Tj
--403 TJm
-(and) 14.386 Tj
--402 TJm
-(\003ushes) 27.6761 Tj
--403 TJm
-(to) 7.7509 Tj
--403 TJm
-(the) 12.1743 Tj
--402 TJm
-(compressed) 47.0334 Tj
--403 TJm
-(\002le) 12.7322 Tj
--403 TJm
-(a) 4.42339 Tj
-1 TJm
-(ll) 5.53921 Tj
--403 TJm
-(data) 16.5977 Tj
--403 TJm
-(so) 8.85675 Tj
--402 TJm
-(f) 3.31755 Tj
-10 TJm
-(ar) 7.74094 Tj
--403 TJm
-(supplied) 33.7633 Tj
--403 TJm
-(by) 9.9626 Tj
-[1 0 0 1 384.152 554.62] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -384.152 -554.62] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-384.152 554.62 Td
-/F134_0 9.9626 Tf
-(BZ2_bzWrite) 65.7532 Tj
-[1 0 0 1 449.906 554.62] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -449.906 -554.62] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-449.906 554.62 Td
-/F130_0 9.9626 Tf
-(.) 2.49065 Tj
--768 TJm
-(The) 15.4918 Tj
--403 TJm
-(logical) 27.1182 Tj
--402 TJm
-(end-of-) 29.3199 Tj
-72 542.665 Td
-(stream) 26.5603 Tj
--352 TJm
-(mark) 20.4731 Tj
-10 TJm
-(ers) 11.6164 Tj
--352 TJm
-(are) 12.1643 Tj
--353 TJm
-(also) 16.0497 Tj
--352 TJm
-(written,) 30.7147 Tj
--378 TJm
-(so) 8.85675 Tj
--352 TJm
-(subsequent) 44.2738 Tj
--352 TJm
-(calls) 18.2614 Tj
--352 TJm
-(to) 7.7509 Tj
-[1 0 0 1 300.456 542.665] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -300.456 -542.665] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-300.456 542.665 Td
-/F134_0 9.9626 Tf
-(BZ2_bzWrite) 65.7532 Tj
-[1 0 0 1 366.209 542.665] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -366.209 -542.665] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-369.718 542.665 Td
-/F130_0 9.9626 Tf
-(are) 12.1643 Tj
--352 TJm
-(ille) 12.7322 Tj
-15 TJm
-(g) 4.9813 Tj
-5 TJm
-(al.) 9.68365 Tj
--1234 TJm
-(All) 12.7322 Tj
--352 TJm
-(memory) 33.2053 Tj
--352 TJm
-(associated) 40.9463 Tj
--352 TJm
-(with) 17.7135 Tj
-72 530.71 Td
-(the) 12.1743 Tj
--250 TJm
-(compressed) 47.0334 Tj
--250 TJm
-(\002le) 12.7322 Tj
-[1 0 0 1 151.411 530.71] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -151.411 -530.71] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-151.411 530.71 Td
-/F134_0 9.9626 Tf
-(b) 5.97756 Tj
-[1 0 0 1 157.389 530.71] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -157.389 -530.71] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-159.879 530.71 Td
-/F130_0 9.9626 Tf
-(is) 6.64505 Tj
--250 TJm
-(released.) 35.1281 Tj
-[1 0 0 1 207.231 530.71] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -207.231 -530.71] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-207.231 530.71 Td
-/F134_0 9.9626 Tf
-(fflush) 35.8654 Tj
-[1 0 0 1 243.097 530.71] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -243.097 -530.71] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-245.587 530.71 Td
-/F130_0 9.9626 Tf
-(is) 6.64505 Tj
--250 TJm
-(called) 23.7907 Tj
--250 TJm
-(on) 9.9626 Tj
--250 TJm
-(the) 12.1743 Tj
--250 TJm
-(compressed) 47.0334 Tj
--250 TJm
-(\002le,) 15.2229 Tj
--250 TJm
-(b) 4.9813 Tj
-20 TJm
-(ut) 7.7509 Tj
--250 TJm
-(it) 5.53921 Tj
--250 TJm
-(is) 6.64505 Tj
--250 TJm
-(not) 12.7322 Tj
-[1 0 0 1 422.771 530.71] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -422.771 -530.71] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-422.771 530.71 Td
-/F134_0 9.9626 Tf
-(fclose) 35.8654 Tj
-[1 0 0 1 458.636 530.71] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -458.636 -530.71] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-458.636 530.71 Td
-/F130_0 9.9626 Tf
-(') 3.31755 Tj
-50 TJm
-(d.) 7.47195 Tj
-[1 0 0 1 72 528.553] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.9626] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -518.59] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 508.792 Td
-/F130_0 9.9626 Tf
-(If) 6.63509 Tj
-[1 0 0 1 81.5743 508.792] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -81.5743 -508.792] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-81.5743 508.792 Td
-/F134_0 9.9626 Tf
-(BZ2_bzWriteClose) 95.641 Tj
-[1 0 0 1 177.216 508.792] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -177.216 -508.792] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-180.155 508.792 Td
-/F130_0 9.9626 Tf
-(is) 6.64505 Tj
--295 TJm
-(called) 23.7907 Tj
--295 TJm
-(to) 7.7509 Tj
--295 TJm
-(clean) 21.0211 Tj
--295 TJm
-(up) 9.9626 Tj
--295 TJm
-(after) 18.2515 Tj
--295 TJm
-(an) 9.40469 Tj
--295 TJm
-(error) 19.3573 Tj
-40 TJm
-(,) 2.49065 Tj
--306 TJm
-(the) 12.1743 Tj
--295 TJm
-(only) 17.7135 Tj
--295 TJm
-(action) 24.3486 Tj
--295 TJm
-(is) 6.64505 Tj
--295 TJm
-(to) 7.7509 Tj
--295 TJm
-(release) 27.6562 Tj
--295 TJm
-(the) 12.1743 Tj
--295 TJm
-(memory) 33.2053 Tj
-65 TJm
-(.) 2.49065 Tj
--891 TJm
-(The) 15.4918 Tj
--295 TJm
-(library) 26.5603 Tj
-72 496.837 Td
-(records) 29.3199 Tj
--289 TJm
-(the) 12.1743 Tj
--289 TJm
-(error) 19.3573 Tj
--289 TJm
-(codes) 22.6848 Tj
--289 TJm
-(issued) 24.9065 Tj
--289 TJm
-(by) 9.9626 Tj
--289 TJm
-(pre) 12.7222 Tj
-25 TJm
-(vious) 21.589 Tj
--289 TJm
-(calls,) 20.7521 Tj
--299 TJm
-(so) 8.85675 Tj
--289 TJm
-(this) 14.396 Tj
--289 TJm
-(situation) 34.3212 Tj
--289 TJm
-(will) 15.5018 Tj
--289 TJm
-(be) 9.40469 Tj
--289 TJm
-(detected) 33.1954 Tj
--289 TJm
-(automatically) 54.2364 Tj
-65 TJm
-(.) 2.49065 Tj
--427 TJm
-(There) 23.2328 Tj
--289 TJm
-(is) 6.64505 Tj
--289 TJm
-(no) 9.9626 Tj
--289 TJm
-(attempt) 29.8878 Tj
-72 484.882 Td
-(to) 7.7509 Tj
--263 TJm
-(complete) 36.5229 Tj
--262 TJm
-(the) 12.1743 Tj
--263 TJm
-(compression) 50.3609 Tj
--263 TJm
-(operation,) 40.1194 Tj
--265 TJm
-(nor) 13.2801 Tj
--263 TJm
-(to) 7.7509 Tj
-[1 0 0 1 258.308 484.882] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -258.308 -484.882] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-258.308 484.882 Td
-/F134_0 9.9626 Tf
-(fflush) 35.8654 Tj
-[1 0 0 1 294.173 484.882] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -294.173 -484.882] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-296.79 484.882 Td
-/F130_0 9.9626 Tf
-(the) 12.1743 Tj
--263 TJm
-(compressed) 47.0334 Tj
--262 TJm
-(\002le.) 15.2229 Tj
--696 TJm
-(Y) 7.193 Tj
-110 TJm
-(ou) 9.9626 Tj
--263 TJm
-(can) 13.8281 Tj
--263 TJm
-(force) 20.4632 Tj
--262 TJm
-(this) 14.396 Tj
--263 TJm
-(beha) 18.8094 Tj
-20 TJm
-(viour) 21.031 Tj
--263 TJm
-(to) 7.7509 Tj
--262 TJm
-(happen) 28.772 Tj
-72 472.926 Td
-(e) 4.42339 Tj
-25 TJm
-(v) 4.9813 Tj
-15 TJm
-(en) 9.40469 Tj
--250 TJm
-(in) 7.7509 Tj
--250 TJm
-(the) 12.1743 Tj
--250 TJm
-(case) 17.1456 Tj
--250 TJm
-(of) 8.29885 Tj
--250 TJm
-(no) 9.9626 Tj
--250 TJm
-(error) 19.3573 Tj
-40 TJm
-(,) 2.49065 Tj
--250 TJm
-(by) 9.9626 Tj
--250 TJm
-(passing) 29.8878 Tj
--250 TJm
-(a) 4.42339 Tj
--250 TJm
-(nonzero) 32.0895 Tj
--250 TJm
-(v) 4.9813 Tj
-25 TJm
-(alue) 16.5977 Tj
--250 TJm
-(to) 7.7509 Tj
-[1 0 0 1 305.014 472.926] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -305.014 -472.926] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-305.014 472.926 Td
-/F134_0 9.9626 Tf
-(abandon) 41.8429 Tj
-[1 0 0 1 346.858 472.926] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -346.858 -472.926] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-346.858 472.926 Td
-/F130_0 9.9626 Tf
-(.) 2.49065 Tj
-[1 0 0 1 72 470.77] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.9627] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -460.807] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 451.009 Td
-/F130_0 9.9626 Tf
-(If) 6.63509 Tj
-[1 0 0 1 80.5974 451.009] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -80.5974 -451.009] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-80.5974 451.009 Td
-/F134_0 9.9626 Tf
-(nbytes_in) 53.798 Tj
-[1 0 0 1 134.396 451.009] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -134.396 -451.009] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-136.358 451.009 Td
-/F130_0 9.9626 Tf
-(is) 6.64505 Tj
--197 TJm
-(non-null,) 36.2539 Tj
-[1 0 0 1 183.287 451.009] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -183.287 -451.009] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-183.287 449.265 Td
-/F134_0 9.9626 Tf
-(*) 5.97756 Tj
-189.265 451.009 Td
-(nbytes_in) 53.798 Tj
-[1 0 0 1 243.063 451.009] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -243.063 -451.009] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-245.025 451.009 Td
-/F130_0 9.9626 Tf
-(will) 15.5018 Tj
--197 TJm
-(be) 9.40469 Tj
--197 TJm
-(set) 11.0684 Tj
--197 TJm
-(to) 7.7509 Tj
--197 TJm
-(be) 9.40469 Tj
--197 TJm
-(the) 12.1743 Tj
--197 TJm
-(total) 17.7135 Tj
--197 TJm
-(v) 4.9813 Tj
-20 TJm
-(olume) 24.9065 Tj
--197 TJm
-(of) 8.29885 Tj
--197 TJm
-(uncompressed) 56.996 Tj
--197 TJm
-(data) 16.5977 Tj
--197 TJm
-(handled.) 34.0322 Tj
--584 TJm
-(Similarly) 37.0908 Tj
-65 TJm
-(,) 2.49065 Tj
-[1 0 0 1 72 439.053] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -439.053] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 439.053 Td
-/F134_0 9.9626 Tf
-(nbytes_out) 59.7756 Tj
-[1 0 0 1 131.776 439.053] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -131.776 -439.053] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-134.716 439.053 Td
-/F130_0 9.9626 Tf
-(will) 15.5018 Tj
--295 TJm
-(be) 9.40469 Tj
--295 TJm
-(set) 11.0684 Tj
--295 TJm
-(to) 7.7509 Tj
--295 TJm
-(the) 12.1743 Tj
--295 TJm
-(total) 17.7135 Tj
--295 TJm
-(v) 4.9813 Tj
-20 TJm
-(olume) 24.9065 Tj
--296 TJm
-(of) 8.29885 Tj
--295 TJm
-(compressed) 47.0334 Tj
--295 TJm
-(data) 16.5977 Tj
--295 TJm
-(written.) 30.7147 Tj
--890 TJm
-(F) 5.53921 Tj
-15 TJm
-(or) 8.29885 Tj
--295 TJm
-(compatibility) 53.1405 Tj
--295 TJm
-(with) 17.7135 Tj
--295 TJm
-(older) 20.4731 Tj
--296 TJm
-(v) 4.9813 Tj
-15 TJm
-(ersions) 28.224 Tj
--295 TJm
-(of) 8.29885 Tj
-72 427.098 Td
-(the) 12.1743 Tj
--283 TJm
-(library) 26.5603 Tj
-65 TJm
-(,) 2.49065 Tj
-[1 0 0 1 118.294 427.098] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -118.294 -427.098] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-118.294 427.098 Td
-/F134_0 9.9626 Tf
-(BZ2_bzWriteClose) 95.641 Tj
-[1 0 0 1 213.936 427.098] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -213.936 -427.098] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-216.753 427.098 Td
-/F130_0 9.9626 Tf
-(only) 17.7135 Tj
--283 TJm
-(yields) 23.8007 Tj
--283 TJm
-(the) 12.1743 Tj
--282 TJm
-(lo) 7.7509 Tj
-25 TJm
-(wer) 14.9339 Tj
--283 TJm
-(32) 9.9626 Tj
--283 TJm
-(bits) 14.396 Tj
--283 TJm
-(of) 8.29885 Tj
--283 TJm
-(these) 20.4731 Tj
--282 TJm
-(counts.) 28.503 Tj
--817 TJm
-(Use) 15.4918 Tj
-[1 0 0 1 423.499 427.098] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -423.499 -427.098] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-423.499 427.098 Td
-/F134_0 9.9626 Tf
-(BZ2_bzWriteClose64) 107.596 Tj
-[1 0 0 1 531.095 427.098] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -531.095 -427.098] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-533.913 427.098 Td
-/F130_0 9.9626 Tf
-(if) 6.08715 Tj
-72 415.143 Td
-(you) 14.9439 Tj
--250 TJm
-(w) 7.193 Tj
-10 TJm
-(ant) 12.1743 Tj
--250 TJm
-(the) 12.1743 Tj
--250 TJm
-(full) 13.8381 Tj
--250 TJm
-(64) 9.9626 Tj
--250 TJm
-(bit) 10.5205 Tj
--250 TJm
-(counts.) 28.503 Tj
--620 TJm
-(These) 23.7907 Tj
--250 TJm
-(tw) 9.9626 Tj
-10 TJm
-(o) 4.9813 Tj
--250 TJm
-(functions) 37.0808 Tj
--250 TJm
-(are) 12.1643 Tj
--250 TJm
-(otherwise) 38.7346 Tj
--250 TJm
-(absolutely) 40.9562 Tj
--250 TJm
-(identical.) 36.8018 Tj
-[1 0 0 1 72 412.986] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.9627] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -403.024] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 393.225 Td
-/F130_0 9.9626 Tf
-(Possible) 33.2153 Tj
--250 TJm
-(assignments) 48.7072 Tj
--250 TJm
-(to) 7.7509 Tj
-[1 0 0 1 169.144 393.225] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -169.144 -393.225] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-169.144 393.225 Td
-/F134_0 9.9626 Tf
-(bzerror) 41.8429 Tj
-[1 0 0 1 210.987 393.225] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -210.987 -393.225] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-210.987 393.225 Td
-/F130_0 9.9626 Tf
-(:) 2.7696 Tj
-[1 0 0 1 72 391.069] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -84.6825] cm
-/DeviceRGB {} cs
-[0.94899 0.94899 0.976456] sc
-/DeviceRGB {} CS
-[0.94899 0.94899 0.976456] SC
-0 0 468 83.6862 re
-f
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 3.5866] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 80.0996] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 18 -8.3686] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -90 -381.704] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-90 381.704 Td
-/F134_0 9.9626 Tf
-(BZ_SEQUENCE_ERROR) 101.619 Tj
-98.4879 369.748 Td
-(if) 11.9551 Tj
--426 TJm
-(b) 5.97756 Tj
--426 TJm
-(was) 17.9327 Tj
--426 TJm
-(opened) 35.8654 Tj
--426 TJm
-(with) 23.9102 Tj
--426 TJm
-(BZ2_bzReadOpen) 83.6858 Tj
-90 357.793 Td
-(BZ_IO_ERROR) 65.7532 Tj
-98.4879 345.838 Td
-(if) 11.9551 Tj
--426 TJm
-(there) 29.8878 Tj
--426 TJm
-(is) 11.9551 Tj
--426 TJm
-(an) 11.9551 Tj
--426 TJm
-(error) 29.8878 Tj
--426 TJm
-(writing) 41.8429 Tj
--426 TJm
-(the) 17.9327 Tj
--426 TJm
-(compressed) 59.7756 Tj
--426 TJm
-(file) 23.9102 Tj
-90 333.883 Td
-(BZ_OK) 29.8878 Tj
-98.4879 321.928 Td
-(otherwise) 53.798 Tj
-[1 0 0 1 72 306.386] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 468 3.5866] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -468 -3.5866] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.9626] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -296.423] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 275.765 Td
-/F122_0 17.2154 Tf
-(3.4.8.) 43.0729 Tj
--278 TJm
-(Handling) 73.6475 Tj
--278 TJm
-(embed) 55.4852 Tj
-10 TJm
-(ded) 30.609 Tj
--278 TJm
-(compressed) 101.416 Tj
--278 TJm
-(data) 35.3949 Tj
--278 TJm
-(streams) 66.0211 Tj
-[1 0 0 1 72 271.935] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.9627] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -261.972] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 253.847 Td
-/F130_0 9.9626 Tf
-(The) 15.4918 Tj
--203 TJm
-(high-le) 28.224 Tj
-25 TJm
-(v) 4.9813 Tj
-15 TJm
-(el) 7.193 Tj
--203 TJm
-(library) 26.5603 Tj
--203 TJm
-(f) 3.31755 Tj
-10 TJm
-(acilitates) 35.417 Tj
--203 TJm
-(use) 13.2801 Tj
--203 TJm
-(of) 8.29885 Tj
-[1 0 0 1 226.404 253.847] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -226.404 -253.847] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-226.404 253.847 Td
-/F134_0 9.9626 Tf
-(bzip2) 29.8878 Tj
-[1 0 0 1 256.292 253.847] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -256.292 -253.847] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-258.316 253.847 Td
-/F130_0 9.9626 Tf
-(data) 16.5977 Tj
--203 TJm
-(streams) 30.4357 Tj
--203 TJm
-(which) 24.3486 Tj
--203 TJm
-(form) 19.3673 Tj
--203 TJm
-(some) 21.031 Tj
--203 TJm
-(part) 15.4918 Tj
--203 TJm
-(of) 8.29885 Tj
--204 TJm
-(a) 4.42339 Tj
--203 TJm
-(surrounding,) 50.6399 Tj
--212 TJm
-(lar) 10.5105 Tj
-18 TJm
-(ger) 12.7222 Tj
--203 TJm
-(data) 16.5977 Tj
--203 TJm
-(stream.) 29.0509 Tj
-[1 0 0 1 72 251.69] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -29.7236] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 6.9739 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -78.9739 -221.967] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-78.9739 221.967 Td
-/F130_0 9.9626 Tf
-(\225) 3.48691 Tj
-[1 0 0 1 82.4608 221.967] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 1.9925 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -86.944 -221.967] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-86.944 221.967 Td
-/F130_0 9.9626 Tf
-(F) 5.53921 Tj
-15 TJm
-(or) 8.29885 Tj
--240 TJm
-(writing,) 31.2726 Tj
--243 TJm
-(the) 12.1743 Tj
--240 TJm
-(library) 26.5603 Tj
--241 TJm
-(tak) 12.1743 Tj
-10 TJm
-(es) 8.29885 Tj
--240 TJm
-(an) 9.40469 Tj
--241 TJm
-(open) 19.3673 Tj
--240 TJm
-(\002le) 12.7322 Tj
--241 TJm
-(handle,) 29.0509 Tj
--242 TJm
-(writes) 24.3486 Tj
--241 TJm
-(compres) 33.7533 Tj
-1 TJm
-(sed) 13.2801 Tj
--241 TJm
-(data) 16.5977 Tj
--240 TJm
-(to) 7.7509 Tj
--241 TJm
-(it,) 8.02986 Tj
-[1 0 0 1 398.926 221.967] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -398.926 -221.967] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-398.926 221.967 Td
-/F134_0 9.9626 Tf
-(fflush) 35.8654 Tj
-[1 0 0 1 434.791 221.967] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -434.791 -221.967] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-434.791 221.967 Td
-/F130_0 9.9626 Tf
-(es) 8.29885 Tj
--240 TJm
-(it) 5.53921 Tj
--241 TJm
-(b) 4.9813 Tj
-20 TJm
-(ut) 7.7509 Tj
--240 TJm
-(does) 18.2614 Tj
--241 TJm
-(not) 12.7322 Tj
-[1 0 0 1 504.135 221.967] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -504.135 -221.967] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-504.135 221.967 Td
-/F134_0 9.9626 Tf
-(fclose) 35.8654 Tj
-[1 0 0 1 540 221.967] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -540 -221.967] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-86.944 210.011 Td
-/F130_0 9.9626 Tf
-(it.) 8.02986 Tj
--610 TJm
-(The) 15.4918 Tj
--235 TJm
-(calling) 27.1182 Tj
--235 TJm
-(application) 44.2738 Tj
--235 TJm
-(can) 13.8281 Tj
--235 TJm
-(write) 20.4731 Tj
--235 TJm
-(its) 9.41466 Tj
--235 TJm
-(o) 4.9813 Tj
-25 TJm
-(wn) 12.1743 Tj
--235 TJm
-(data) 16.5977 Tj
--235 TJm
-(before) 25.4445 Tj
--235 TJm
-(and) 14.386 Tj
--235 TJm
-(after) 18.2515 Tj
--235 TJm
-(the) 12.1743 Tj
--235 TJm
-(compressed) 47.0334 Tj
--235 TJm
-(data) 16.5977 Tj
--235 TJm
-(stream,) 29.0509 Tj
--238 TJm
-(using) 21.589 Tj
--235 TJm
-(that) 14.9439 Tj
--235 TJm
-(same) 20.4731 Tj
--235 TJm
-(\002le) 12.7322 Tj
-86.944 198.056 Td
-(handle.) 29.0509 Tj
-[1 0 0 1 115.995 198.056] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -43.9948 -21.9178] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 6.9739 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -78.9739 -176.139] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-78.9739 176.139 Td
-/F130_0 9.9626 Tf
-(\225) 3.48691 Tj
-[1 0 0 1 82.4608 176.139] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 1.9925 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -86.944 -176.139] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-86.944 176.139 Td
-/F130_0 9.9626 Tf
-(Reading) 33.2053 Tj
--236 TJm
-(is) 6.64505 Tj
--236 TJm
-(more) 20.4731 Tj
--236 TJm
-(comple) 29.3299 Tj
-15 TJm
-(x,) 7.47195 Tj
--238 TJm
-(and) 14.386 Tj
--236 TJm
-(the) 12.1743 Tj
--236 TJm
-(f) 3.31755 Tj
-10 TJm
-(acilities) 30.9936 Tj
--236 TJm
-(are) 12.1643 Tj
--236 TJm
-(not) 12.7322 Tj
--235 TJm
-(as) 8.29885 Tj
--236 TJm
-(general) 29.3199 Tj
--236 TJm
-(as) 8.29885 Tj
--236 TJm
-(the) 12.1743 Tj
-15 TJm
-(y) 4.9813 Tj
--236 TJm
-(could) 22.1369 Tj
--236 TJm
-(be) 9.40469 Tj
--236 TJm
-(since) 20.4731 Tj
--235 TJm
-(generality) 39.8404 Tj
--236 TJm
-(is) 6.64505 Tj
--236 TJm
-(hard) 17.7035 Tj
--236 TJm
-(to) 7.7509 Tj
--236 TJm
-(reconcile) 36.5129 Tj
-86.944 164.183 Td
-(with) 17.7135 Tj
--404 TJm
-(ef) 7.74094 Tj
-25 TJm
-(\002cienc) 26.5603 Tj
-15 TJm
-(y) 4.9813 Tj
-65 TJm
-(.) 2.49065 Tj
-[1 0 0 1 164.811 164.183] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -164.811 -164.183] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-164.811 164.183 Td
-/F134_0 9.9626 Tf
-(BZ2_bzRead) 59.7756 Tj
-[1 0 0 1 224.587 164.183] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -224.587 -164.183] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-228.614 164.183 Td
-/F130_0 9.9626 Tf
-(reads) 21.0211 Tj
--404 TJm
-(from) 19.3673 Tj
--405 TJm
-(the) 12.1743 Tj
--404 TJm
-(compressed) 47.0334 Tj
--404 TJm
-(\002le) 12.7322 Tj
--404 TJm
-(in) 7.7509 Tj
--405 TJm
-(blocks) 26.0123 Tj
--404 TJm
-(of) 8.29885 Tj
--404 TJm
-(size) 15.4918 Tj
-[1 0 0 1 434.744 164.183] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -434.744 -164.183] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-434.744 164.183 Td
-/F134_0 9.9626 Tf
-(BZ_MAX_UNUSED) 77.7083 Tj
-[1 0 0 1 512.452 164.183] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -512.452 -164.183] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-516.479 164.183 Td
-/F130_0 9.9626 Tf
-(bytes,) 23.5217 Tj
-86.944 152.228 Td
-(and) 14.386 Tj
--413 TJm
-(in) 7.7509 Tj
--413 TJm
-(doing) 22.6948 Tj
--413 TJm
-(so) 8.85675 Tj
--413 TJm
-(probably) 35.417 Tj
--413 TJm
-(will) 15.5018 Tj
--413 TJm
-(o) 4.9813 Tj
-15 TJm
-(v) 4.9813 Tj
-15 TJm
-(ershoot) 29.3299 Tj
--413 TJm
-(the) 12.1743 Tj
--413 TJm
-(logical) 27.1182 Tj
--413 TJm
-(end) 14.386 Tj
--413 TJm
-(of) 8.29885 Tj
--413 TJm
-(compressed) 47.0334 Tj
--413 TJm
-(stream.) 29.0509 Tj
--1598 TJm
-(T) 6.08715 Tj
-80 TJm
-(o) 4.9813 Tj
--413 TJm
-(reco) 17.1456 Tj
-15 TJm
-(v) 4.9813 Tj
-15 TJm
-(er) 7.74094 Tj
--413 TJm
-(this) 14.396 Tj
--413 TJm
-(data) 16.5977 Tj
--413 TJm
-(once) 18.8094 Tj
-86.944 140.273 Td
-(decompression) 59.7656 Tj
--252 TJm
-(has) 13.2801 Tj
--252 TJm
-(ended,) 26.2813 Tj
--253 TJm
-(call) 14.386 Tj
-[1 0 0 1 210.705 140.273] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -210.705 -140.273] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-210.705 140.273 Td
-/F134_0 9.9626 Tf
-(BZ2_bzReadGetUnused) 113.574 Tj
-[1 0 0 1 324.279 140.273] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -324.279 -140.273] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-326.789 140.273 Td
-/F130_0 9.9626 Tf
-(after) 18.2515 Tj
--252 TJm
-(the) 12.1743 Tj
--252 TJm
-(last) 13.8381 Tj
--252 TJm
-(call) 14.386 Tj
--252 TJm
-(of) 8.29885 Tj
-[1 0 0 1 406.291 140.273] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -406.291 -140.273] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-406.291 140.273 Td
-/F134_0 9.9626 Tf
-(BZ2_bzRead) 59.7756 Tj
-[1 0 0 1 466.067 140.273] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -466.067 -140.273] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-468.578 140.273 Td
-/F130_0 9.9626 Tf
-(\(the) 15.4918 Tj
--252 TJm
-(one) 14.386 Tj
--252 TJm
-(returning) 36.5229 Tj
-[1 0 0 1 86.944 128.318] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -86.944 -128.318] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-86.944 128.318 Td
-/F134_0 9.9626 Tf
-(BZ_STREAM_END) 77.7083 Tj
-[1 0 0 1 164.653 128.318] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -164.653 -128.318] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-164.653 128.318 Td
-/F130_0 9.9626 Tf
-(\)) 3.31755 Tj
--250 TJm
-(b) 4.9813 Tj
-20 TJm
-(ut) 7.7509 Tj
--250 TJm
-(before) 25.4445 Tj
--250 TJm
-(calling) 27.1182 Tj
-[1 0 0 1 243.028 128.318] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -243.028 -128.318] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-243.028 128.318 Td
-/F134_0 9.9626 Tf
-(BZ2_bzReadClose) 89.6634 Tj
-[1 0 0 1 332.692 128.318] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -332.692 -128.318] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-332.692 128.318 Td
-/F130_0 9.9626 Tf
-(.) 2.49065 Tj
-[1 0 0 1 335.182 128.318] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -263.182 -77.466] cm
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-[1 0 0 1 1.8929 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 374.394 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 6.7545] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 40.5726 -6.7545] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -493.841 -50.8519] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-534.414 50.8518 Td
-/F130_0 9.9626 Tf
-(24) 9.9626 Tj
-[1 0 0 1 453.269 50.8518] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 93.5985 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 6.2765 0] cm
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-[1 0 0 1 -13.1436 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-Q
-showpage
-%%PageTrailer
-pdfEndPage
-%%Page: 28 28
-%%BeginPageSetup
-%%PageOrientation: Portrait
-pdfStartPage
-0 0 612 792 re W
-%%EndPageSetup
-[] 0 d
-1 i
-0 j
-0 J
-10 M
-1 w
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-false op
-false OP
-0 0 612 792 re
-W
-q
-[1 0 0 1 72 741.554] cm
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-[1 0 0 1 1.8929 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 14.4459] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 187.197 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 -8.9114] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 8.9114] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 76.4979 -6.7546] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -342.569 -749.245] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-419.067 749.245 Td
-/F130_0 9.9626 Tf
-(Programming) 54.7943 Tj
--250 TJm
-(with) 17.7135 Tj
-[1 0 0 1 496.556 749.245] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -496.556 -749.245] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-496.556 749.245 Td
-/F134_0 9.9626 Tf
-(libbzip2) 47.8205 Tj
-[1 0 0 1 544.376 749.245] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -278.305 -2.1568] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 280.796 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -472.974 -5.0363] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -0.4981] cm
-q
-[] 0 d
-0 J
-0.4981 w
-0 0.2491 m
-475.465 0.2491 l
-S
-Q
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 479.251 0] cm
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-[1 0 0 1 -13.1436 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -468 -21.5542] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -720] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 710.037 Td
-/F130_0 9.9626 Tf
-(This) 17.7135 Tj
--271 TJm
-(mechanism) 45.3796 Tj
--272 TJm
-(mak) 17.1556 Tj
-10 TJm
-(es) 8.29885 Tj
--271 TJm
-(it) 5.53921 Tj
--271 TJm
-(easy) 17.7035 Tj
--271 TJm
-(to) 7.7509 Tj
--272 TJm
-(decompress) 47.0334 Tj
--271 TJm
-(multiple) 33.2153 Tj
-[1 0 0 1 293.312 710.037] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -293.312 -710.037] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-293.312 710.037 Td
-/F134_0 9.9626 Tf
-(bzip2) 29.8878 Tj
-[1 0 0 1 323.2 710.037] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -323.2 -710.037] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-325.903 710.037 Td
-/F130_0 9.9626 Tf
-(streams) 30.4357 Tj
--271 TJm
-(placed) 26.0024 Tj
--272 TJm
-(end-to-end.) 45.6486 Tj
--374 TJm
-(As) 11.0684 Tj
--271 TJm
-(the) 12.1743 Tj
--271 TJm
-(end) 14.386 Tj
--271 TJm
-(of) 8.29885 Tj
--272 TJm
-(one) 14.386 Tj
--271 TJm
-(stream,) 29.0509 Tj
-72 698.082 Td
-(when) 21.579 Tj
-[1 0 0 1 96.1948 698.082] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -96.1948 -698.082] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-96.1948 698.082 Td
-/F134_0 9.9626 Tf
-(BZ2_bzRead) 59.7756 Tj
-[1 0 0 1 155.971 698.082] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -155.971 -698.082] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-158.586 698.082 Td
-/F130_0 9.9626 Tf
-(returns) 27.6661 Tj
-[1 0 0 1 188.868 698.082] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -188.868 -698.082] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-188.868 698.082 Td
-/F134_0 9.9626 Tf
-(BZ_STREAM_END) 77.7083 Tj
-[1 0 0 1 266.577 698.082] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -266.577 -698.082] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-266.577 698.082 Td
-/F130_0 9.9626 Tf
-(,) 2.49065 Tj
--263 TJm
-(call) 14.386 Tj
-[1 0 0 1 288.685 698.082] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -288.685 -698.082] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-288.685 698.082 Td
-/F134_0 9.9626 Tf
-(BZ2_bzReadGetUnused) 113.574 Tj
-[1 0 0 1 402.259 698.082] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -402.259 -698.082] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-404.875 698.082 Td
-/F130_0 9.9626 Tf
-(to) 7.7509 Tj
--263 TJm
-(collect) 26.5603 Tj
--262 TJm
-(the) 12.1743 Tj
--263 TJm
-(unused) 28.224 Tj
--262 TJm
-(data) 16.5977 Tj
--263 TJm
-(\(cop) 17.7035 Tj
-10 TJm
-(y) 4.9813 Tj
--262 TJm
-(it) 5.53921 Tj
-72 686.127 Td
-(into) 15.5018 Tj
--265 TJm
-(your) 18.2614 Tj
--265 TJm
-(o) 4.9813 Tj
-25 TJm
-(wn) 12.1743 Tj
--265 TJm
-(b) 4.9813 Tj
-20 TJm
-(uf) 8.29885 Tj
-25 TJm
-(fer) 11.0585 Tj
--265 TJm
-(some) 21.031 Tj
-25 TJm
-(where\).) 30.1468 Tj
--711 TJm
-(That) 18.2614 Tj
--265 TJm
-(data) 16.5977 Tj
--265 TJm
-(forms) 23.2427 Tj
--265 TJm
-(the) 12.1743 Tj
--265 TJm
-(start) 17.1556 Tj
--265 TJm
-(of) 8.29885 Tj
--265 TJm
-(the) 12.1743 Tj
--265 TJm
-(ne) 9.40469 Tj
-15 TJm
-(xt) 7.7509 Tj
--265 TJm
-(compressed) 47.0334 Tj
--265 TJm
-(stream.) 29.0509 Tj
--711 TJm
-(T) 6.08715 Tj
-80 TJm
-(o) 4.9813 Tj
--265 TJm
-(start) 17.1556 Tj
--265 TJm
-(uncompressing) 60.3235 Tj
-72 674.172 Td
-(that) 14.9439 Tj
--246 TJm
-(ne) 9.40469 Tj
-15 TJm
-(xt) 7.7509 Tj
--246 TJm
-(stream,) 29.0509 Tj
--247 TJm
-(call) 14.386 Tj
-[1 0 0 1 157.205 674.172] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -157.205 -674.172] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-157.205 674.172 Td
-/F134_0 9.9626 Tf
-(BZ2_bzReadOpen) 83.6858 Tj
-[1 0 0 1 240.891 674.172] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -240.891 -674.172] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-243.344 674.172 Td
-/F130_0 9.9626 Tf
-(ag) 9.40469 Tj
-5 TJm
-(ain,) 14.6649 Tj
--247 TJm
-(feeding) 29.8778 Tj
--246 TJm
-(in) 7.7509 Tj
--246 TJm
-(the) 12.1743 Tj
--247 TJm
-(unused) 28.224 Tj
--246 TJm
-(data) 16.5977 Tj
--246 TJm
-(via) 12.1743 Tj
--246 TJm
-(the) 12.1743 Tj
-[1 0 0 1 405.967 674.172] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -405.967 -674.172] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-405.967 674.172 Td
-/F134_0 9.9626 Tf
-(unused) 35.8654 Tj
-[1 0 0 1 441.833 674.172] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -441.833 -674.172] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-444.286 674.172 Td
-/F130_0 9.9626 Tf
-(/) 2.7696 Tj
-[1 0 0 1 449.508 674.172] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -449.508 -674.172] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-449.508 674.172 Td
-/F134_0 9.9626 Tf
-(nUnused) 41.8429 Tj
-[1 0 0 1 491.351 674.172] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -491.351 -674.172] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-493.804 674.172 Td
-/F130_0 9.9626 Tf
-(parameters.) 46.1966 Tj
-72 662.217 Td
-(K) 7.193 Tj
-25 TJm
-(eep) 13.8281 Tj
--263 TJm
-(doing) 22.6948 Tj
--263 TJm
-(this) 14.396 Tj
--264 TJm
-(until) 18.2714 Tj
-[1 0 0 1 158.622 662.217] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -158.622 -662.217] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-158.622 662.217 Td
-/F134_0 9.9626 Tf
-(BZ_STREAM_END) 77.7083 Tj
-[1 0 0 1 236.33 662.217] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -236.33 -662.217] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-238.952 662.217 Td
-/F130_0 9.9626 Tf
-(return) 23.7907 Tj
--263 TJm
-(coincides) 37.6287 Tj
--263 TJm
-(with) 17.7135 Tj
--263 TJm
-(the) 12.1743 Tj
--264 TJm
-(ph) 9.9626 Tj
-5 TJm
-(ysical) 23.2427 Tj
--263 TJm
-(end) 14.386 Tj
--263 TJm
-(of) 8.29885 Tj
--263 TJm
-(\002le) 12.7322 Tj
--263 TJm
-(\() 3.31755 Tj
-[1 0 0 1 423.125 662.217] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -423.125 -662.217] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-423.125 662.217 Td
-/F134_0 9.9626 Tf
-(feof\(f\)) 41.8429 Tj
-[1 0 0 1 464.968 662.217] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -464.968 -662.217] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-464.968 662.217 Td
-/F130_0 9.9626 Tf
-(\).) 5.8082 Tj
--699 TJm
-(In) 8.29885 Tj
--263 TJm
-(this) 14.396 Tj
--263 TJm
-(situation) 34.3212 Tj
-[1 0 0 1 72 650.261] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -650.261] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 650.261 Td
-/F134_0 9.9626 Tf
-(BZ2_bzReadGetUnused) 113.574 Tj
-[1 0 0 1 185.574 650.261] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -185.574 -650.261] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-188.065 650.261 Td
-/F130_0 9.9626 Tf
-(will) 15.5018 Tj
--250 TJm
-(of) 8.29885 Tj
--250 TJm
-(course) 26.0024 Tj
--250 TJm
-(return) 23.7907 Tj
--250 TJm
-(no) 9.9626 Tj
--250 TJm
-(data.) 19.0883 Tj
-[1 0 0 1 72 648.951] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.9626] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -638.989] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 628.344 Td
-/F130_0 9.9626 Tf
-(This) 17.7135 Tj
--240 TJm
-(should) 26.5703 Tj
--241 TJm
-(gi) 7.7509 Tj
-25 TJm
-(v) 4.9813 Tj
-15 TJm
-(e) 4.42339 Tj
--240 TJm
-(some) 21.031 Tj
--241 TJm
-(feel) 14.9339 Tj
--240 TJm
-(for) 11.6164 Tj
--241 TJm
-(ho) 9.9626 Tj
-25 TJm
-(w) 7.193 Tj
--240 TJm
-(the) 12.1743 Tj
--240 TJm
-(high-le) 28.224 Tj
-25 TJm
-(v) 4.9813 Tj
-15 TJm
-(el) 7.193 Tj
--241 TJm
-(interf) 21.579 Tj
-10 TJm
-(ace) 13.2702 Tj
--240 TJm
-(can) 13.8281 Tj
--241 TJm
-(be) 9.40469 Tj
--240 TJm
-(used.) 20.7521 Tj
--614 TJm
-(If) 6.63509 Tj
--240 TJm
-(you) 14.9439 Tj
--241 TJm
-(require) 28.2141 Tj
--240 TJm
-(e) 4.42339 Tj
-15 TJm
-(xtra) 15.4918 Tj
--241 TJm
-(\003e) 9.9626 Tj
-15 TJm
-(xibi) 15.5018 Tj
-1 TJm
-(lity) 13.2901 Tj
-65 TJm
-(,) 2.49065 Tj
--243 TJm
-(you') 18.2614 Tj
-10 TJm
-(ll) 5.53921 Tj
--240 TJm
-(ha) 9.40469 Tj
-20 TJm
-(v) 4.9813 Tj
-15 TJm
-(e) 4.42339 Tj
--241 TJm
-(to) 7.7509 Tj
-72 616.389 Td
-(bite) 14.9439 Tj
--250 TJm
-(the) 12.1743 Tj
--250 TJm
-(b) 4.9813 Tj
-20 TJm
-(ullet) 17.7135 Tj
--250 TJm
-(and) 14.386 Tj
--250 TJm
-(get) 12.1743 Tj
--250 TJm
-(to) 7.7509 Tj
--250 TJm
-(grips) 19.9252 Tj
--250 TJm
-(with) 17.7135 Tj
--250 TJm
-(the) 12.1743 Tj
--250 TJm
-(lo) 7.7509 Tj
-25 TJm
-(w-le) 17.7035 Tj
-25 TJm
-(v) 4.9813 Tj
-15 TJm
-(el) 7.193 Tj
--250 TJm
-(interf) 21.579 Tj
-10 TJm
-(ace.) 15.7608 Tj
-[1 0 0 1 72 614.232] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.9626] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -604.269] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 585.767 Td
-/F122_0 17.2154 Tf
-(3.4.9.) 43.0729 Tj
--278 TJm
-(Standar) 64.0929 Tj
-20 TJm
-(d) 10.5186 Tj
--278 TJm
-(\002le-reading/writing) 154.009 Tj
--278 TJm
-(code) 40.1807 Tj
-[1 0 0 1 72 581.937] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.9626] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -571.975] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 563.85 Td
-/F130_0 9.9626 Tf
-(Here') 22.6749 Tj
-55 TJm
-(s) 3.87545 Tj
--250 TJm
-(ho) 9.9626 Tj
-25 TJm
-(w) 7.193 Tj
--250 TJm
-(you') 18.2614 Tj
-50 TJm
-(d) 4.9813 Tj
--250 TJm
-(write) 20.4731 Tj
--250 TJm
-(data) 16.5977 Tj
--250 TJm
-(to) 7.7509 Tj
--250 TJm
-(a) 4.42339 Tj
--250 TJm
-(compressed) 47.0334 Tj
--250 TJm
-(\002le:) 15.5018 Tj
-[1 0 0 1 72 561.693] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -371.606] cm
-/DeviceRGB {} cs
-[0.94899 0.94899 0.976456] sc
-/DeviceRGB {} CS
-[0.94899 0.94899 0.976456] SC
-0 0 468 370.61 re
-f
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 3.5866] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 367.024] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 18 -8.3686] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -90 -552.328] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-90 552.328 Td
-/F134_0 9.9626 Tf
-(FILE) 23.9102 Tj
-113.91 550.584 Td
-(*) 5.97756 Tj
-132.62 552.328 Td
-(f;) 11.9551 Tj
-90 540.373 Td
-(BZFILE) 35.8654 Tj
-125.865 538.629 Td
-(*) 5.97756 Tj
-136.087 540.373 Td
-(b;) 11.9551 Tj
-90 528.418 Td
-(int) 17.9327 Tj
--2130 TJm
-(nBuf;) 29.8878 Tj
-90 516.462 Td
-(char) 23.9102 Tj
--1704 TJm
-(buf[) 23.9102 Tj
--426 TJm
-(/) 5.97756 Tj
-165.018 514.719 Td
-(*) 5.97756 Tj
-175.24 516.462 Td
-(whatever) 47.8205 Tj
--426 TJm
-(size) 23.9102 Tj
--426 TJm
-(you) 17.9327 Tj
--426 TJm
-(like) 23.9102 Tj
-305.79 514.719 Td
-(*) 5.97756 Tj
-311.767 516.462 Td
-(/) 5.97756 Tj
--426 TJm
-(];) 11.9551 Tj
-90 504.507 Td
-(int) 17.9327 Tj
--2130 TJm
-(bzerror;) 47.8205 Tj
-90 492.552 Td
-(int) 17.9327 Tj
--2130 TJm
-(nWritten;) 53.798 Tj
-90 468.642 Td
-(f) 5.97756 Tj
--426 TJm
-(=) 5.97756 Tj
--426 TJm
-(fopen) 29.8878 Tj
--426 TJm
-(\() 5.97756 Tj
--426 TJm
-("myfile.bz2",) 77.7083 Tj
--426 TJm
-("w") 17.9327 Tj
--426 TJm
-(\);) 11.9551 Tj
-90 456.687 Td
-(if) 11.9551 Tj
--426 TJm
-(\() 5.97756 Tj
--426 TJm
-(!f) 11.9551 Tj
--426 TJm
-(\)) 5.97756 Tj
--426 TJm
-({) 5.97756 Tj
-94.244 444.731 Td
-(/) 5.97756 Tj
-100.222 442.988 Td
-(*) 5.97756 Tj
-110.443 444.731 Td
-(handle) 35.8654 Tj
--426 TJm
-(error) 29.8878 Tj
-184.685 442.988 Td
-(*) 5.97756 Tj
-190.662 444.731 Td
-(/) 5.97756 Tj
-90 432.776 Td
-(}) 5.97756 Tj
-90 420.821 Td
-(b) 5.97756 Tj
--426 TJm
-(=) 5.97756 Tj
--426 TJm
-(BZ2_bzWriteOpen\() 95.641 Tj
--426 TJm
-(&bzerror,) 53.798 Tj
--426 TJm
-(f,) 11.9551 Tj
--426 TJm
-(9) 5.97756 Tj
--426 TJm
-(\);) 11.9551 Tj
-90 408.866 Td
-(if) 11.9551 Tj
--426 TJm
-(\(bzerror) 47.8205 Tj
--426 TJm
-(!=) 11.9551 Tj
--426 TJm
-(BZ_OK\)) 35.8654 Tj
--426 TJm
-({) 5.97756 Tj
-94.244 396.911 Td
-(BZ2_bzWriteClose) 95.641 Tj
--426 TJm
-(\() 5.97756 Tj
--426 TJm
-(b) 5.97756 Tj
--426 TJm
-(\);) 11.9551 Tj
-94.244 384.956 Td
-(/) 5.97756 Tj
-100.222 383.212 Td
-(*) 5.97756 Tj
-110.443 384.956 Td
-(handle) 35.8654 Tj
--426 TJm
-(error) 29.8878 Tj
-184.685 383.212 Td
-(*) 5.97756 Tj
-190.662 384.956 Td
-(/) 5.97756 Tj
-90 373 Td
-(}) 5.97756 Tj
-90 349.09 Td
-(while) 29.8878 Tj
--426 TJm
-(\() 5.97756 Tj
--426 TJm
-(/) 5.97756 Tj
-140.331 347.347 Td
-(*) 5.97756 Tj
-150.553 349.09 Td
-(condition) 53.798 Tj
-208.595 347.347 Td
-(*) 5.97756 Tj
-214.572 349.09 Td
-(/) 5.97756 Tj
--426 TJm
-(\)) 5.97756 Tj
--426 TJm
-({) 5.97756 Tj
-94.244 337.135 Td
-(/) 5.97756 Tj
-100.222 335.391 Td
-(*) 5.97756 Tj
-110.443 337.135 Td
-(get) 17.9327 Tj
--426 TJm
-(data) 23.9102 Tj
--426 TJm
-(to) 11.9551 Tj
--426 TJm
-(write) 29.8878 Tj
--426 TJm
-(into) 23.9102 Tj
--426 TJm
-(buf,) 23.9102 Tj
--426 TJm
-(and) 17.9327 Tj
--426 TJm
-(set) 17.9327 Tj
--426 TJm
-(nBuf) 23.9102 Tj
--426 TJm
-(appropriately) 77.7083 Tj
-421.874 335.391 Td
-(*) 5.97756 Tj
-427.852 337.135 Td
-(/) 5.97756 Tj
-94.2439 325.18 Td
-(nWritten) 47.8205 Tj
--426 TJm
-(=) 5.97756 Tj
--426 TJm
-(BZ2_bzWrite) 65.7532 Tj
--426 TJm
-(\() 5.97756 Tj
--426 TJm
-(&bzerror,) 53.798 Tj
--426 TJm
-(b,) 11.9551 Tj
--426 TJm
-(buf,) 23.9102 Tj
--426 TJm
-(nBuf) 23.9102 Tj
--426 TJm
-(\);) 11.9551 Tj
-94.2439 313.225 Td
-(if) 11.9551 Tj
--426 TJm
-(\(bzerror) 47.8205 Tj
--426 TJm
-(==) 11.9551 Tj
--426 TJm
-(BZ_IO_ERROR\)) 71.7307 Tj
--426 TJm
-({) 5.97756 Tj
-102.732 301.269 Td
-(BZ2_bzWriteClose) 95.641 Tj
--426 TJm
-(\() 5.97756 Tj
--426 TJm
-(&bzerror,) 53.798 Tj
--426 TJm
-(b) 5.97756 Tj
--426 TJm
-(\);) 11.9551 Tj
-102.732 289.314 Td
-(/) 5.97756 Tj
-108.709 287.571 Td
-(*) 5.97756 Tj
-118.931 289.314 Td
-(handle) 35.8654 Tj
--426 TJm
-(error) 29.8878 Tj
-193.172 287.571 Td
-(*) 5.97756 Tj
-199.15 289.314 Td
-(/) 5.97756 Tj
-94.2439 277.359 Td
-(}) 5.97756 Tj
-90 265.404 Td
-(}) 5.97756 Tj
-90 241.494 Td
-(BZ2_bzWriteClose\() 101.619 Tj
--426 TJm
-(&bzerror,) 53.798 Tj
--426 TJm
-(b) 5.97756 Tj
--426 TJm
-(\);) 11.9551 Tj
-90 229.538 Td
-(if) 11.9551 Tj
--426 TJm
-(\(bzerror) 47.8205 Tj
--426 TJm
-(==) 11.9551 Tj
--426 TJm
-(BZ_IO_ERROR\)) 71.7307 Tj
--426 TJm
-({) 5.97756 Tj
-94.2439 217.583 Td
-(/) 5.97756 Tj
-100.221 215.84 Td
-(*) 5.97756 Tj
-110.443 217.583 Td
-(handle) 35.8654 Tj
--426 TJm
-(error) 29.8878 Tj
-184.684 215.84 Td
-(*) 5.97756 Tj
-190.662 217.583 Td
-(/) 5.97756 Tj
-89.9999 205.628 Td
-(}) 5.97756 Tj
-[1 0 0 1 72 190.086] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 468 3.5866] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -468 -13.5492] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -180.124] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 168.168 Td
-/F130_0 9.9626 Tf
-(And) 17.1556 Tj
--250 TJm
-(to) 7.7509 Tj
--250 TJm
-(read) 17.1456 Tj
--250 TJm
-(from) 19.3673 Tj
--250 TJm
-(a) 4.42339 Tj
--250 TJm
-(compressed) 47.0334 Tj
--250 TJm
-(\002le:) 15.5018 Tj
-[1 0 0 1 72 166.012] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -115.16] cm
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-[1 0 0 1 1.8929 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 374.394 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 6.8541] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 40.5726 -6.7546] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -493.841 -50.9513] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-534.414 50.9513 Td
-/F130_0 9.9626 Tf
-(25) 9.9626 Tj
-[1 0 0 1 453.269 50.8518] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 93.5985 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 6.2765 0] cm
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-[1 0 0 1 -13.1436 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-Q
-showpage
-%%PageTrailer
-pdfEndPage
-%%Page: 29 29
-%%BeginPageSetup
-%%PageOrientation: Portrait
-pdfStartPage
-0 0 612 792 re W
-%%EndPageSetup
-[] 0 d
-1 i
-0 j
-0 J
-10 M
-1 w
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-false op
-false OP
-0 0 612 792 re
-W
-q
-[1 0 0 1 72 741.554] cm
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-[1 0 0 1 1.8929 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 14.4459] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 187.197 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 -8.9114] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 8.9114] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 76.4979 -6.7546] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -342.569 -749.245] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-419.067 749.245 Td
-/F130_0 9.9626 Tf
-(Programming) 54.7943 Tj
--250 TJm
-(with) 17.7135 Tj
-[1 0 0 1 496.556 749.245] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -496.556 -749.245] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-496.556 749.245 Td
-/F134_0 9.9626 Tf
-(libbzip2) 47.8205 Tj
-[1 0 0 1 544.376 749.245] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -278.305 -2.1568] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 280.796 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -472.974 -5.0363] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -0.4981] cm
-q
-[] 0 d
-0 J
-0.4981 w
-0 0.2491 m
-475.465 0.2491 l
-S
-Q
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 479.251 0] cm
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-[1 0 0 1 -13.1436 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -468 -392.164] cm
-/DeviceRGB {} cs
-[0.94899 0.94899 0.976456] sc
-/DeviceRGB {} CS
-[0.94899 0.94899 0.976456] SC
-0 0 468 370.61 re
-f
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 3.5866] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 367.024] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 18 -8.3686] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -90 -711.631] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-90 711.631 Td
-/F134_0 9.9626 Tf
-(FILE) 23.9102 Tj
-113.91 709.888 Td
-(*) 5.97756 Tj
-132.62 711.631 Td
-(f;) 11.9551 Tj
-90 699.676 Td
-(BZFILE) 35.8654 Tj
-125.865 697.933 Td
-(*) 5.97756 Tj
-136.087 699.676 Td
-(b;) 11.9551 Tj
-90 687.721 Td
-(int) 17.9327 Tj
--2130 TJm
-(nBuf;) 29.8878 Tj
-90 675.766 Td
-(char) 23.9102 Tj
--1704 TJm
-(buf[) 23.9102 Tj
--426 TJm
-(/) 5.97756 Tj
-165.018 674.023 Td
-(*) 5.97756 Tj
-175.24 675.766 Td
-(whatever) 47.8205 Tj
--426 TJm
-(size) 23.9102 Tj
--426 TJm
-(you) 17.9327 Tj
--426 TJm
-(like) 23.9102 Tj
-305.79 674.023 Td
-(*) 5.97756 Tj
-311.767 675.766 Td
-(/) 5.97756 Tj
--426 TJm
-(];) 11.9551 Tj
-90 663.811 Td
-(int) 17.9327 Tj
--2130 TJm
-(bzerror;) 47.8205 Tj
-90 651.856 Td
-(int) 17.9327 Tj
--2130 TJm
-(nWritten;) 53.798 Tj
-90 627.945 Td
-(f) 5.97756 Tj
--426 TJm
-(=) 5.97756 Tj
--426 TJm
-(fopen) 29.8878 Tj
--426 TJm
-(\() 5.97756 Tj
--426 TJm
-("myfile.bz2",) 77.7083 Tj
--426 TJm
-("r") 17.9327 Tj
--426 TJm
-(\);) 11.9551 Tj
-90 615.99 Td
-(if) 11.9551 Tj
--426 TJm
-(\() 5.97756 Tj
--426 TJm
-(!f) 11.9551 Tj
--426 TJm
-(\)) 5.97756 Tj
--426 TJm
-({) 5.97756 Tj
-98.488 604.035 Td
-(/) 5.97756 Tj
-104.466 602.292 Td
-(*) 5.97756 Tj
-114.687 604.035 Td
-(handle) 35.8654 Tj
--426 TJm
-(error) 29.8878 Tj
-188.929 602.292 Td
-(*) 5.97756 Tj
-194.906 604.035 Td
-(/) 5.97756 Tj
-90 592.08 Td
-(}) 5.97756 Tj
-90 580.125 Td
-(b) 5.97756 Tj
--426 TJm
-(=) 5.97756 Tj
--426 TJm
-(BZ2_bzReadOpen) 83.6858 Tj
--426 TJm
-(\() 5.97756 Tj
--426 TJm
-(&bzerror,) 53.798 Tj
--426 TJm
-(f,) 11.9551 Tj
--426 TJm
-(0,) 11.9551 Tj
--426 TJm
-(NULL,) 29.8878 Tj
--426 TJm
-(0) 5.97756 Tj
--426 TJm
-(\);) 11.9551 Tj
-90 568.169 Td
-(if) 11.9551 Tj
--426 TJm
-(\() 5.97756 Tj
--426 TJm
-(bzerror) 41.8429 Tj
--426 TJm
-(!=) 11.9551 Tj
--426 TJm
-(BZ_OK) 29.8878 Tj
--426 TJm
-(\)) 5.97756 Tj
--426 TJm
-({) 5.97756 Tj
-98.488 556.214 Td
-(BZ2_bzReadClose) 89.6634 Tj
--426 TJm
-(\() 5.97756 Tj
--426 TJm
-(&bzerror,) 53.798 Tj
--426 TJm
-(b) 5.97756 Tj
--426 TJm
-(\);) 11.9551 Tj
-98.488 544.259 Td
-(/) 5.97756 Tj
-104.466 542.516 Td
-(*) 5.97756 Tj
-114.687 544.259 Td
-(handle) 35.8654 Tj
--426 TJm
-(error) 29.8878 Tj
-188.929 542.516 Td
-(*) 5.97756 Tj
-194.906 544.259 Td
-(/) 5.97756 Tj
-90 532.304 Td
-(}) 5.97756 Tj
-90 508.394 Td
-(bzerror) 41.8429 Tj
--426 TJm
-(=) 5.97756 Tj
--426 TJm
-(BZ_OK;) 35.8654 Tj
-90 496.438 Td
-(while) 29.8878 Tj
--426 TJm
-(\() 5.97756 Tj
--426 TJm
-(bzerror) 41.8429 Tj
--426 TJm
-(==) 11.9551 Tj
--426 TJm
-(BZ_OK) 29.8878 Tj
--426 TJm
-(&&) 11.9551 Tj
--426 TJm
-(/) 5.97756 Tj
-252.948 494.695 Td
-(*) 5.97756 Tj
-263.17 496.438 Td
-(arbitrary) 53.798 Tj
--426 TJm
-(other) 29.8878 Tj
--426 TJm
-(conditions) 59.7756 Tj
-419.364 494.695 Td
-(*) 5.97756 Tj
-425.341 496.438 Td
-(/\)) 11.9551 Tj
--426 TJm
-({) 5.97756 Tj
-98.488 484.483 Td
-(nBuf) 23.9102 Tj
--426 TJm
-(=) 5.97756 Tj
--426 TJm
-(BZ2_bzRead) 59.7756 Tj
--426 TJm
-(\() 5.97756 Tj
--426 TJm
-(&bzerror,) 53.798 Tj
--426 TJm
-(b,) 11.9551 Tj
--426 TJm
-(buf,) 23.9102 Tj
--426 TJm
-(/) 5.97756 Tj
-319.478 482.74 Td
-(*) 5.97756 Tj
-329.7 484.483 Td
-(size) 23.9102 Tj
--426 TJm
-(of) 11.9551 Tj
--426 TJm
-(buf) 17.9327 Tj
-396.23 482.74 Td
-(*) 5.97756 Tj
-402.208 484.483 Td
-(/) 5.97756 Tj
--426 TJm
-(\);) 11.9551 Tj
-98.488 472.528 Td
-(if) 11.9551 Tj
--426 TJm
-(\() 5.97756 Tj
--426 TJm
-(bzerror) 41.8429 Tj
--426 TJm
-(==) 11.9551 Tj
--426 TJm
-(BZ_OK) 29.8878 Tj
--426 TJm
-(\)) 5.97756 Tj
--426 TJm
-({) 5.97756 Tj
-106.976 460.573 Td
-(/) 5.97756 Tj
-112.953 458.829 Td
-(*) 5.97756 Tj
-123.175 460.573 Td
-(do) 11.9551 Tj
--426 TJm
-(something) 53.798 Tj
--426 TJm
-(with) 23.9102 Tj
--426 TJm
-(buf[0) 29.8878 Tj
--426 TJm
-(..) 11.9551 Tj
--426 TJm
-(nBuf-1]) 41.8429 Tj
-321.989 458.829 Td
-(*) 5.97756 Tj
-327.966 460.573 Td
-(/) 5.97756 Tj
-98.4879 448.618 Td
-(}) 5.97756 Tj
-90 436.663 Td
-(}) 5.97756 Tj
-90 424.707 Td
-(if) 11.9551 Tj
--426 TJm
-(\() 5.97756 Tj
--426 TJm
-(bzerror) 41.8429 Tj
--426 TJm
-(!=) 11.9551 Tj
--426 TJm
-(BZ_STREAM_END) 77.7083 Tj
--426 TJm
-(\)) 5.97756 Tj
--426 TJm
-({) 5.97756 Tj
-102.732 412.752 Td
-(BZ2_bzReadClose) 89.6634 Tj
--426 TJm
-(\() 5.97756 Tj
--426 TJm
-(&bzerror,) 53.798 Tj
--426 TJm
-(b) 5.97756 Tj
--426 TJm
-(\);) 11.9551 Tj
-102.732 400.797 Td
-(/) 5.97756 Tj
-108.709 399.054 Td
-(*) 5.97756 Tj
-118.931 400.797 Td
-(handle) 35.8654 Tj
--426 TJm
-(error) 29.8878 Tj
-193.172 399.054 Td
-(*) 5.97756 Tj
-199.15 400.797 Td
-(/) 5.97756 Tj
-90 388.842 Td
-(}) 5.97756 Tj
--426 TJm
-(else) 23.9102 Tj
--426 TJm
-({) 5.97756 Tj
-102.732 376.887 Td
-(BZ2_bzReadClose) 89.6634 Tj
--426 TJm
-(\() 5.97756 Tj
--426 TJm
-(&bzerror,) 53.798 Tj
--426 TJm
-(b) 5.97756 Tj
--426 TJm
-(\);) 11.9551 Tj
-90 364.932 Td
-(}) 5.97756 Tj
-[1 0 0 1 72 349.39] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 468 3.5866] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -468 -3.5866] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.9626] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -339.427] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 314.637 Td
-/F122_0 20.6585 Tf
-(3.5.) 34.4584 Tj
--278 TJm
-(Utility) 57.3893 Tj
--278 TJm
-(functions) 92.9633 Tj
-[1 0 0 1 72 310.361] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.9626] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -300.398] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 284.016 Td
-/F122_0 17.2154 Tf
-(3.5.1.) 43.0729 Tj
-[1 0 0 1 119.858 284.016] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -119.858 -284.016] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-119.858 284.016 Td
-/F392_0 17.2154 Tf
-(BZ2_bzBuffToBuffCompress) 247.902 Tj
-[1 0 0 1 367.76 284.016] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -295.76 -2.3327] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -96.6376] cm
-/DeviceRGB {} cs
-[0.94899 0.94899 0.976456] sc
-/DeviceRGB {} CS
-[0.94899 0.94899 0.976456] SC
-0 0 468 95.6413 re
-f
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 3.5866] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 92.0548] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 18 -8.3686] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -90 -272.318] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-90 272.318 Td
-/F134_0 9.9626 Tf
-(int) 17.9327 Tj
--426 TJm
-(BZ2_bzBuffToBuffCompress\() 149.439 Tj
--426 TJm
-(char) 23.9102 Tj
-289.771 270.575 Td
-(*) 5.97756 Tj
-333.944 272.318 Td
-(dest,) 29.8878 Tj
-217.319 260.363 Td
-(unsigned) 47.8205 Tj
--426 TJm
-(int) 17.9327 Tj
-287.317 258.62 Td
-(*) 5.97756 Tj
-297.538 260.363 Td
-(destLen,) 47.8205 Tj
-217.319 248.408 Td
-(char) 23.9102 Tj
-241.23 246.664 Td
-(*) 5.97756 Tj
-285.403 248.408 Td
-(source,) 41.8429 Tj
-217.319 236.453 Td
-(unsigned) 47.8205 Tj
--426 TJm
-(int) 17.9327 Tj
--852 TJm
-(sourceLen,) 59.7756 Tj
-217.319 224.498 Td
-(int) 17.9327 Tj
--4686 TJm
-(blockSize100k,) 83.6858 Tj
-217.319 212.542 Td
-(int) 17.9327 Tj
--4686 TJm
-(verbosity,) 59.7756 Tj
-217.319 200.587 Td
-(int) 17.9327 Tj
--4686 TJm
-(workFactor) 59.7756 Tj
--426 TJm
-(\);) 11.9551 Tj
-[1 0 0 1 72 185.045] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 468 3.5866] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -468 -13.5492] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -175.083] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 163.128 Td
-/F130_0 9.9626 Tf
-(Attempts) 36.5329 Tj
--442 TJm
-(to) 7.7509 Tj
--442 TJm
-(compress) 37.6287 Tj
--443 TJm
-(the) 12.1743 Tj
--442 TJm
-(data) 16.5977 Tj
--442 TJm
-(in) 7.7509 Tj
-[1 0 0 1 216.87 163.128] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -216.87 -163.128] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-216.87 163.128 Td
-/F134_0 9.9626 Tf
-(source[0) 47.8205 Tj
--600 TJm
-(..) 11.9551 Tj
--1200 TJm
-(sourceLen-1]) 71.7307 Tj
-[1 0 0 1 366.31 163.128] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -366.31 -163.128] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-370.715 163.128 Td
-/F130_0 9.9626 Tf
-(into) 15.5018 Tj
--442 TJm
-(the) 12.1743 Tj
--442 TJm
-(destination) 43.7259 Tj
--443 TJm
-(b) 4.9813 Tj
-20 TJm
-(uf) 8.29885 Tj
-25 TJm
-(fer) 11.0585 Tj
-40 TJm
-(,) 2.49065 Tj
-[1 0 0 1 486.202 163.128] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -486.202 -163.128] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-486.202 163.128 Td
-/F134_0 9.9626 Tf
-(dest[0) 35.8654 Tj
--600 TJm
-(..) 11.9551 Tj
-72 149.429 Td
-(*) 5.97756 Tj
-77.9776 151.173 Td
-(destLen-1]) 59.7756 Tj
-[1 0 0 1 137.753 151.172] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -137.753 -151.172] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-137.753 151.172 Td
-/F130_0 9.9626 Tf
-(.) 2.49065 Tj
--1393 TJm
-(If) 6.63509 Tj
--379 TJm
-(the) 12.1743 Tj
--379 TJm
-(destination) 43.7259 Tj
--379 TJm
-(b) 4.9813 Tj
-20 TJm
-(uf) 8.29885 Tj
-25 TJm
-(fer) 11.0585 Tj
--378 TJm
-(is) 6.64505 Tj
--379 TJm
-(big) 12.7322 Tj
--379 TJm
-(enough,) 31.8205 Tj
-[1 0 0 1 318.486 151.172] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -318.486 -151.172] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-318.486 149.429 Td
-/F134_0 9.9626 Tf
-(*) 5.97756 Tj
-324.464 151.173 Td
-(destLen) 41.8429 Tj
-[1 0 0 1 366.307 151.172] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -366.307 -151.172] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-370.081 151.172 Td
-/F130_0 9.9626 Tf
-(is) 6.64505 Tj
--379 TJm
-(set) 11.0684 Tj
--379 TJm
-(to) 7.7509 Tj
--378 TJm
-(the) 12.1743 Tj
--379 TJm
-(size) 15.4918 Tj
--379 TJm
-(of) 8.29885 Tj
--379 TJm
-(the) 12.1743 Tj
--379 TJm
-(compressed) 47.0334 Tj
--379 TJm
-(data,) 19.0883 Tj
-72 139.217 Td
-(and) 14.386 Tj
-[1 0 0 1 89.5273 139.217] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -89.5273 -139.217] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-89.5273 139.217 Td
-/F134_0 9.9626 Tf
-(BZ_OK) 29.8878 Tj
-[1 0 0 1 119.415 139.217] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -119.415 -139.217] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-122.556 139.217 Td
-/F130_0 9.9626 Tf
-(is) 6.64505 Tj
--315 TJm
-(returned.) 35.686 Tj
--1012 TJm
-(If) 6.63509 Tj
--315 TJm
-(the) 12.1743 Tj
--316 TJm
-(compressed) 47.0334 Tj
--315 TJm
-(data) 16.5977 Tj
--315 TJm
-(w) 7.193 Tj
-10 TJm
-(on') 13.2801 Tj
-18 TJm
-(t) 2.7696 Tj
--316 TJm
-(\002t,) 10.7995 Tj
-[1 0 0 1 313.322 139.217] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -313.322 -139.217] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-313.322 137.474 Td
-/F134_0 9.9626 Tf
-(*) 5.97756 Tj
-319.3 139.217 Td
-(destLen) 41.8429 Tj
-[1 0 0 1 361.143 139.217] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -361.143 -139.217] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-364.284 139.217 Td
-/F130_0 9.9626 Tf
-(is) 6.64505 Tj
--315 TJm
-(unchanged,) 45.6486 Tj
--332 TJm
-(and) 14.386 Tj
-[1 0 0 1 440.551 139.217] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -440.551 -139.217] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-440.551 139.217 Td
-/F134_0 9.9626 Tf
-(BZ_OUTBUFF_FULL) 89.6634 Tj
-[1 0 0 1 530.215 139.217] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -530.215 -139.217] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-533.355 139.217 Td
-/F130_0 9.9626 Tf
-(is) 6.64505 Tj
-72 127.262 Td
-(returned.) 35.686 Tj
-[1 0 0 1 72 127.163] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.9626] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -117.2] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 105.344 Td
-/F130_0 9.9626 Tf
-(Compression) 52.5826 Tj
--297 TJm
-(in) 7.7509 Tj
--297 TJm
-(this) 14.396 Tj
--297 TJm
-(manner) 29.8778 Tj
--297 TJm
-(is) 6.64505 Tj
--297 TJm
-(a) 4.42339 Tj
--297 TJm
-(one-shot) 34.3112 Tj
--297 TJm
-(e) 4.42339 Tj
-25 TJm
-(v) 4.9813 Tj
-15 TJm
-(ent,) 14.6649 Tj
--309 TJm
-(done) 19.3673 Tj
--297 TJm
-(with) 17.7135 Tj
--297 TJm
-(a) 4.42339 Tj
--297 TJm
-(single) 23.8007 Tj
--297 TJm
-(call) 14.386 Tj
--297 TJm
-(to) 7.7509 Tj
--297 TJm
-(this) 14.396 Tj
--297 TJm
-(function.) 35.696 Tj
--903 TJm
-(The) 15.4918 Tj
--297 TJm
-(resulting) 34.8691 Tj
--297 TJm
-(compressed) 47.0334 Tj
-72 93.3892 Td
-(data) 16.5977 Tj
--296 TJm
-(is) 6.64505 Tj
--296 TJm
-(a) 4.42339 Tj
--296 TJm
-(complete) 36.5229 Tj
-[1 0 0 1 147.988 93.3892] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -147.988 -93.3892] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-147.988 93.3892 Td
-/F134_0 9.9626 Tf
-(bzip2) 29.8878 Tj
-[1 0 0 1 177.875 93.3892] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -177.875 -93.3892] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-180.825 93.3892 Td
-/F130_0 9.9626 Tf
-(format) 26.5603 Tj
--296 TJm
-(data) 16.5977 Tj
--296 TJm
-(stream.) 29.0509 Tj
--897 TJm
-(There) 23.2328 Tj
--296 TJm
-(is) 6.64505 Tj
--296 TJm
-(no) 9.9626 Tj
--296 TJm
-(mechanism) 45.3796 Tj
--296 TJm
-(for) 11.6164 Tj
--296 TJm
-(making) 29.8878 Tj
--296 TJm
-(additional) 39.8504 Tj
--296 TJm
-(calls) 18.2614 Tj
--296 TJm
-(to) 7.7509 Tj
--296 TJm
-(pro) 13.2801 Tj
-15 TJm
-(vide) 17.1556 Tj
--296 TJm
-(e) 4.42339 Tj
-15 TJm
-(xtra) 15.4918 Tj
-72 81.434 Td
-(input) 20.4831 Tj
--250 TJm
-(data.) 19.0883 Tj
--620 TJm
-(If) 6.63509 Tj
--250 TJm
-(you) 14.9439 Tj
--250 TJm
-(w) 7.193 Tj
-10 TJm
-(ant) 12.1743 Tj
--250 TJm
-(that) 14.9439 Tj
--250 TJm
-(kind) 17.7135 Tj
--250 TJm
-(of) 8.29885 Tj
--250 TJm
-(mechanism,) 47.8703 Tj
--250 TJm
-(use) 13.2801 Tj
--250 TJm
-(the) 12.1743 Tj
--250 TJm
-(lo) 7.7509 Tj
-25 TJm
-(w-le) 17.7035 Tj
-25 TJm
-(v) 4.9813 Tj
-15 TJm
-(el) 7.193 Tj
--250 TJm
-(interf) 21.579 Tj
-10 TJm
-(ace.) 15.7608 Tj
-[1 0 0 1 72 79.2772] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -28.4254] cm
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-[1 0 0 1 1.8929 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 374.394 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 6.8541] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 40.5726 -6.7545] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -493.841 -50.9514] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-534.414 50.9514 Td
-/F130_0 9.9626 Tf
-(26) 9.9626 Tj
-[1 0 0 1 453.269 50.8518] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 93.5985 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 6.2765 0] cm
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-[1 0 0 1 -13.1436 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-Q
-showpage
-%%PageTrailer
-pdfEndPage
-%%Page: 30 30
-%%BeginPageSetup
-%%PageOrientation: Portrait
-pdfStartPage
-0 0 612 792 re W
-%%EndPageSetup
-[] 0 d
-1 i
-0 j
-0 J
-10 M
-1 w
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-false op
-false OP
-0 0 612 792 re
-W
-q
-[1 0 0 1 72 741.554] cm
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-[1 0 0 1 1.8929 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 14.4459] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 187.197 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 -8.9114] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 8.9114] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 76.4979 -6.7546] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -342.569 -749.245] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-419.067 749.245 Td
-/F130_0 9.9626 Tf
-(Programming) 54.7943 Tj
--250 TJm
-(with) 17.7135 Tj
-[1 0 0 1 496.556 749.245] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -496.556 -749.245] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-496.556 749.245 Td
-/F134_0 9.9626 Tf
-(libbzip2) 47.8205 Tj
-[1 0 0 1 544.376 749.245] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -278.305 -2.1568] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 280.796 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -472.974 -5.0363] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -0.4981] cm
-q
-[] 0 d
-0 J
-0.4981 w
-0 0.2491 m
-475.465 0.2491 l
-S
-Q
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 479.251 0] cm
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-[1 0 0 1 -13.1436 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -468 -21.5542] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -720] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 710.037 Td
-/F130_0 9.9626 Tf
-(F) 5.53921 Tj
-15 TJm
-(or) 8.29885 Tj
--223 TJm
-(the) 12.1743 Tj
--224 TJm
-(meaning) 34.3112 Tj
--223 TJm
-(of) 8.29885 Tj
--224 TJm
-(parameters) 43.7059 Tj
-[1 0 0 1 195.306 710.037] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -195.306 -710.037] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-195.306 710.037 Td
-/F134_0 9.9626 Tf
-(blockSize100k) 77.7083 Tj
-[1 0 0 1 273.015 710.037] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -273.015 -710.037] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-273.015 710.037 Td
-/F130_0 9.9626 Tf
-(,) 2.49065 Tj
-[1 0 0 1 277.784 710.037] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -277.784 -710.037] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-277.784 710.037 Td
-/F134_0 9.9626 Tf
-(verbosity) 53.798 Tj
-[1 0 0 1 331.583 710.037] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -331.583 -710.037] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-333.808 710.037 Td
-/F130_0 9.9626 Tf
-(and) 14.386 Tj
-[1 0 0 1 350.42 710.037] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -350.42 -710.037] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-350.42 710.037 Td
-/F134_0 9.9626 Tf
-(workFactor) 59.7756 Tj
-[1 0 0 1 410.196 710.037] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -410.196 -710.037] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-410.196 710.037 Td
-/F130_0 9.9626 Tf
-(,) 2.49065 Tj
--229 TJm
-(see) 12.7222 Tj
-[1 0 0 1 429.913 710.037] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -429.913 -710.037] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-429.913 710.037 Td
-/F134_0 9.9626 Tf
-(BZ2_bzCompressInit) 107.596 Tj
-[1 0 0 1 537.509 710.037] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -537.509 -710.037] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-537.509 710.037 Td
-/F130_0 9.9626 Tf
-(.) 2.49065 Tj
-[1 0 0 1 72 707.88] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.9626] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -697.918] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 688.12 Td
-/F130_0 9.9626 Tf
-(T) 6.08715 Tj
-80 TJm
-(o) 4.9813 Tj
--410 TJm
-(guarantee) 38.7246 Tj
--410 TJm
-(that) 14.9439 Tj
--410 TJm
-(the) 12.1743 Tj
--410 TJm
-(compressed) 47.0334 Tj
--410 TJm
-(data) 16.5977 Tj
--410 TJm
-(will) 15.5018 Tj
--410 TJm
-(\002t) 8.30881 Tj
--410 TJm
-(in) 7.7509 Tj
--410 TJm
-(its) 9.41466 Tj
--410 TJm
-(b) 4.9813 Tj
-20 TJm
-(uf) 8.29885 Tj
-25 TJm
-(fer) 11.0585 Tj
-40 TJm
-(,) 2.49065 Tj
--450 TJm
-(allocate) 30.9837 Tj
--410 TJm
-(an) 9.40469 Tj
--410 TJm
-(output) 25.4644 Tj
--410 TJm
-(b) 4.9813 Tj
-20 TJm
-(uf) 8.29885 Tj
-25 TJm
-(fer) 11.0585 Tj
--411 TJm
-(of) 8.29885 Tj
--410 TJm
-(size) 15.4918 Tj
--410 TJm
-(1%) 13.2801 Tj
--410 TJm
-(lar) 10.5105 Tj
-18 TJm
-(ger) 12.7222 Tj
--410 TJm
-(than) 17.1556 Tj
--410 TJm
-(the) 12.1743 Tj
-72 676.164 Td
-(uncompressed) 56.996 Tj
--250 TJm
-(data,) 19.0883 Tj
--250 TJm
-(plus) 16.6077 Tj
--250 TJm
-(six) 11.6264 Tj
--250 TJm
-(hundred) 32.6474 Tj
--250 TJm
-(e) 4.42339 Tj
-15 TJm
-(xtra) 15.4918 Tj
--250 TJm
-(bytes.) 23.5217 Tj
-[1 0 0 1 72 674.007] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.9626] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -664.045] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 654.247 Td
-/F134_0 9.9626 Tf
-(BZ2_bzBuffToBuffDecompress) 155.417 Tj
-[1 0 0 1 227.417 654.247] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -227.417 -654.247] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-230.553 654.247 Td
-/F130_0 9.9626 Tf
-(will) 15.5018 Tj
--315 TJm
-(not) 12.7322 Tj
--315 TJm
-(write) 20.4731 Tj
--314 TJm
-(data) 16.5977 Tj
--315 TJm
-(at) 7.193 Tj
--315 TJm
-(or) 8.29885 Tj
--315 TJm
-(be) 9.40469 Tj
-15 TJm
-(yond) 19.9252 Tj
-[1 0 0 1 362.484 654.247] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -362.484 -654.247] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-362.484 654.247 Td
-/F134_0 9.9626 Tf
-(dest[) 29.8878 Tj
-392.372 652.503 Td
-(*) 5.97756 Tj
-398.349 654.247 Td
-(destLen]) 47.8205 Tj
-[1 0 0 1 446.17 654.247] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -446.17 -654.247] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-446.17 654.247 Td
-/F130_0 9.9626 Tf
-(,) 2.49065 Tj
--331 TJm
-(e) 4.42339 Tj
-25 TJm
-(v) 4.9813 Tj
-15 TJm
-(en) 9.40469 Tj
--315 TJm
-(in) 7.7509 Tj
--315 TJm
-(case) 17.1456 Tj
--314 TJm
-(of) 8.29885 Tj
--315 TJm
-(b) 4.9813 Tj
-20 TJm
-(uf) 8.29885 Tj
-25 TJm
-(fer) 11.0585 Tj
-72 642.291 Td
-(o) 4.9813 Tj
-15 TJm
-(v) 4.9813 Tj
-15 TJm
-(er\003o) 18.2614 Tj
-25 TJm
-(w) 7.193 Tj
-65 TJm
-(.) 2.49065 Tj
-[1 0 0 1 72 642.192] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.9626] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -632.229] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 620.374 Td
-/F130_0 9.9626 Tf
-(Possible) 33.2153 Tj
--250 TJm
-(return) 23.7907 Tj
--250 TJm
-(v) 4.9813 Tj
-25 TJm
-(alues:) 23.2427 Tj
-[1 0 0 1 72 620.274] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -168.369] cm
-/DeviceRGB {} cs
-[0.94899 0.94899 0.976456] sc
-/DeviceRGB {} CS
-[0.94899 0.94899 0.976456] SC
-0 0 468 167.372 re
-f
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 3.5866] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 163.786] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 18 -8.3686] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -90 -610.909] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-90 610.909 Td
-/F134_0 9.9626 Tf
-(BZ_CONFIG_ERROR) 89.6634 Tj
-98.4879 598.954 Td
-(if) 11.9551 Tj
--426 TJm
-(the) 17.9327 Tj
--426 TJm
-(library) 41.8429 Tj
--426 TJm
-(has) 17.9327 Tj
--426 TJm
-(been) 23.9102 Tj
--426 TJm
-(mis-compiled) 71.7307 Tj
-90 586.999 Td
-(BZ_PARAM_ERROR) 83.6858 Tj
-98.4879 575.044 Td
-(if) 11.9551 Tj
--426 TJm
-(dest) 23.9102 Tj
--426 TJm
-(is) 11.9551 Tj
--426 TJm
-(NULL) 23.9102 Tj
--426 TJm
-(or) 11.9551 Tj
--426 TJm
-(destLen) 41.8429 Tj
--426 TJm
-(is) 11.9551 Tj
--426 TJm
-(NULL) 23.9102 Tj
-98.4879 563.088 Td
-(or) 11.9551 Tj
--426 TJm
-(blockSize100k) 77.7083 Tj
--426 TJm
-(<) 5.97756 Tj
--426 TJm
-(1) 5.97756 Tj
--426 TJm
-(or) 11.9551 Tj
--426 TJm
-(blockSize100k) 77.7083 Tj
--426 TJm
-(>) 5.97756 Tj
--426 TJm
-(9) 5.97756 Tj
-98.4879 551.133 Td
-(or) 11.9551 Tj
--426 TJm
-(verbosity) 53.798 Tj
--426 TJm
-(<) 5.97756 Tj
--426 TJm
-(0) 5.97756 Tj
--426 TJm
-(or) 11.9551 Tj
--426 TJm
-(verbosity) 53.798 Tj
--426 TJm
-(>) 5.97756 Tj
--426 TJm
-(4) 5.97756 Tj
-98.4879 539.178 Td
-(or) 11.9551 Tj
--426 TJm
-(workFactor) 59.7756 Tj
--426 TJm
-(<) 5.97756 Tj
--426 TJm
-(0) 5.97756 Tj
--426 TJm
-(or) 11.9551 Tj
--426 TJm
-(workFactor) 59.7756 Tj
--426 TJm
-(>) 5.97756 Tj
--426 TJm
-(250) 17.9327 Tj
-90 527.223 Td
-(BZ_MEM_ERROR) 71.7307 Tj
-98.4879 515.268 Td
-(if) 11.9551 Tj
--426 TJm
-(insufficient) 71.7307 Tj
--426 TJm
-(memory) 35.8654 Tj
--426 TJm
-(is) 11.9551 Tj
--426 TJm
-(available) 53.798 Tj
-90 503.313 Td
-(BZ_OUTBUFF_FULL) 89.6634 Tj
-98.4879 491.357 Td
-(if) 11.9551 Tj
--426 TJm
-(the) 17.9327 Tj
--426 TJm
-(size) 23.9102 Tj
--426 TJm
-(of) 11.9551 Tj
--426 TJm
-(the) 17.9327 Tj
--426 TJm
-(compressed) 59.7756 Tj
--426 TJm
-(data) 23.9102 Tj
--426 TJm
-(exceeds) 41.8429 Tj
-341.655 489.614 Td
-(*) 5.97756 Tj
-347.633 491.357 Td
-(destLen) 41.8429 Tj
-90 479.402 Td
-(BZ_OK) 29.8878 Tj
-98.4879 467.447 Td
-(otherwise) 53.798 Tj
-[1 0 0 1 72 451.905] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 468 3.5866] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -468 -3.5866] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.9626] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -441.943] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 421.284 Td
-/F122_0 17.2154 Tf
-(3.5.2.) 43.0729 Tj
-[1 0 0 1 119.858 421.284] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -119.858 -421.284] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-119.858 421.284 Td
-/F392_0 17.2154 Tf
-(BZ2_bzBuffToBuffDecompress) 268.56 Tj
-[1 0 0 1 388.419 421.284] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -316.419 -2.3327] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -84.6824] cm
-/DeviceRGB {} cs
-[0.94899 0.94899 0.976456] sc
-/DeviceRGB {} CS
-[0.94899 0.94899 0.976456] SC
-0 0 468 83.6862 re
-f
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 3.5866] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 80.0996] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 18 -8.3686] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -90 -409.587] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-90 409.587 Td
-/F134_0 9.9626 Tf
-(int) 17.9327 Tj
--426 TJm
-(BZ2_bzBuffToBuffDecompress\() 161.394 Tj
--426 TJm
-(char) 23.9102 Tj
-301.726 407.843 Td
-(*) 5.97756 Tj
-345.899 409.587 Td
-(dest,) 29.8878 Tj
-225.807 397.632 Td
-(unsigned) 47.8205 Tj
--426 TJm
-(int) 17.9327 Tj
-295.805 395.888 Td
-(*) 5.97756 Tj
-306.026 397.632 Td
-(destLen,) 47.8205 Tj
-225.807 385.676 Td
-(char) 23.9102 Tj
-249.718 383.933 Td
-(*) 5.97756 Tj
-293.891 385.676 Td
-(source,) 41.8429 Tj
-225.807 373.721 Td
-(unsigned) 47.8205 Tj
--426 TJm
-(int) 17.9327 Tj
--852 TJm
-(sourceLen,) 59.7756 Tj
-225.807 361.766 Td
-(int) 17.9327 Tj
--4686 TJm
-(small,) 35.8654 Tj
-225.807 349.811 Td
-(int) 17.9327 Tj
--4686 TJm
-(verbosity) 53.798 Tj
--426 TJm
-(\);) 11.9551 Tj
-[1 0 0 1 72 334.269] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 468 3.5866] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -468 -13.5492] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -324.306] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 312.351 Td
-/F130_0 9.9626 Tf
-(Attempts) 36.5329 Tj
--358 TJm
-(to) 7.7509 Tj
--359 TJm
-(decompress) 47.0334 Tj
--358 TJm
-(the) 12.1743 Tj
--358 TJm
-(data) 16.5977 Tj
--359 TJm
-(in) 7.7509 Tj
-[1 0 0 1 221.259 312.351] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -221.259 -312.351] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-221.259 312.351 Td
-/F134_0 9.9626 Tf
-(source[0) 47.8205 Tj
--600 TJm
-(..) 11.9551 Tj
--1200 TJm
-(sourceLen-1]) 71.7307 Tj
-[1 0 0 1 370.698 312.351] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -370.698 -312.351] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-374.268 312.351 Td
-/F130_0 9.9626 Tf
-(into) 15.5018 Tj
--358 TJm
-(the) 12.1743 Tj
--359 TJm
-(destination) 43.7259 Tj
--358 TJm
-(b) 4.9813 Tj
-20 TJm
-(uf) 8.29885 Tj
-25 TJm
-(fer) 11.0585 Tj
-40 TJm
-(,) 2.49065 Tj
-[1 0 0 1 486.202 312.351] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -486.202 -312.351] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-486.202 312.351 Td
-/F134_0 9.9626 Tf
-(dest[0) 35.8654 Tj
--600 TJm
-(..) 11.9551 Tj
-72 298.653 Td
-(*) 5.97756 Tj
-77.9776 300.396 Td
-(destLen-1]) 59.7756 Tj
-[1 0 0 1 137.753 300.396] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -137.753 -300.396] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-137.753 300.396 Td
-/F130_0 9.9626 Tf
-(.) 2.49065 Tj
--1123 TJm
-(If) 6.63509 Tj
--334 TJm
-(the) 12.1743 Tj
--334 TJm
-(destination) 43.7259 Tj
--334 TJm
-(b) 4.9813 Tj
-20 TJm
-(uf) 8.29885 Tj
-25 TJm
-(fer) 11.0585 Tj
--334 TJm
-(is) 6.64505 Tj
--334 TJm
-(big) 12.7322 Tj
--334 TJm
-(enough,) 31.8205 Tj
-[1 0 0 1 312.554 300.396] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -312.554 -300.396] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-312.554 298.653 Td
-/F134_0 9.9626 Tf
-(*) 5.97756 Tj
-318.531 300.396 Td
-(destLen) 41.8429 Tj
-[1 0 0 1 360.374 300.396] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -360.374 -300.396] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-363.701 300.396 Td
-/F130_0 9.9626 Tf
-(is) 6.64505 Tj
--334 TJm
-(set) 11.0684 Tj
--334 TJm
-(to) 7.7509 Tj
--334 TJm
-(the) 12.1743 Tj
--334 TJm
-(size) 15.4918 Tj
--333 TJm
-(of) 8.29885 Tj
--334 TJm
-(the) 12.1743 Tj
--334 TJm
-(uncompressed) 56.996 Tj
--334 TJm
-(data,) 19.0883 Tj
-72 288.441 Td
-(and) 14.386 Tj
-[1 0 0 1 89.5273 288.441] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -89.5273 -288.441] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-89.5273 288.441 Td
-/F134_0 9.9626 Tf
-(BZ_OK) 29.8878 Tj
-[1 0 0 1 119.415 288.441] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -119.415 -288.441] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-122.556 288.441 Td
-/F130_0 9.9626 Tf
-(is) 6.64505 Tj
--315 TJm
-(returned.) 35.686 Tj
--1012 TJm
-(If) 6.63509 Tj
--315 TJm
-(the) 12.1743 Tj
--316 TJm
-(compressed) 47.0334 Tj
--315 TJm
-(data) 16.5977 Tj
--315 TJm
-(w) 7.193 Tj
-10 TJm
-(on') 13.2801 Tj
-18 TJm
-(t) 2.7696 Tj
--316 TJm
-(\002t,) 10.7995 Tj
-[1 0 0 1 313.322 288.441] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -313.322 -288.441] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-313.322 286.698 Td
-/F134_0 9.9626 Tf
-(*) 5.97756 Tj
-319.3 288.441 Td
-(destLen) 41.8429 Tj
-[1 0 0 1 361.143 288.441] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -361.143 -288.441] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-364.284 288.441 Td
-/F130_0 9.9626 Tf
-(is) 6.64505 Tj
--315 TJm
-(unchanged,) 45.6486 Tj
--332 TJm
-(and) 14.386 Tj
-[1 0 0 1 440.551 288.441] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -440.551 -288.441] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-440.551 288.441 Td
-/F134_0 9.9626 Tf
-(BZ_OUTBUFF_FULL) 89.6634 Tj
-[1 0 0 1 530.215 288.441] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -530.215 -288.441] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-533.355 288.441 Td
-/F130_0 9.9626 Tf
-(is) 6.64505 Tj
-72 276.486 Td
-(returned.) 35.686 Tj
-[1 0 0 1 72 276.386] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.9626] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -266.424] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 254.568 Td
-/F134_0 9.9626 Tf
-(source) 35.8654 Tj
-[1 0 0 1 107.865 254.568] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -107.865 -254.568] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-110.981 254.568 Td
-/F130_0 9.9626 Tf
-(is) 6.64505 Tj
--313 TJm
-(assumed) 34.3112 Tj
--312 TJm
-(to) 7.7509 Tj
--313 TJm
-(hold) 17.7135 Tj
--313 TJm
-(a) 4.42339 Tj
--313 TJm
-(complete) 36.5229 Tj
-[1 0 0 1 237.04 254.568] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -237.04 -254.568] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-237.04 254.568 Td
-/F134_0 9.9626 Tf
-(bzip2) 29.8878 Tj
-[1 0 0 1 266.928 254.568] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -266.928 -254.568] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-270.044 254.568 Td
-/F130_0 9.9626 Tf
-(format) 26.5603 Tj
--313 TJm
-(data) 16.5977 Tj
--312 TJm
-(stream.) 29.0509 Tj
-[1 0 0 1 353.446 254.568] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -353.446 -254.568] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-353.446 254.568 Td
-/F134_0 9.9626 Tf
-(BZ2_bzBuffToBuffDecompress) 155.417 Tj
-[1 0 0 1 508.863 254.568] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -508.863 -254.568] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-511.978 254.568 Td
-/F130_0 9.9626 Tf
-(tries) 17.1556 Tj
--313 TJm
-(to) 7.7509 Tj
-72 242.613 Td
-(decompress) 47.0334 Tj
--250 TJm
-(the) 12.1743 Tj
--250 TJm
-(entirety) 30.4357 Tj
--250 TJm
-(of) 8.29885 Tj
--250 TJm
-(the) 12.1743 Tj
--250 TJm
-(stream) 26.5603 Tj
--250 TJm
-(into) 15.5018 Tj
--250 TJm
-(the) 12.1743 Tj
--250 TJm
-(output) 25.4644 Tj
--250 TJm
-(b) 4.9813 Tj
-20 TJm
-(uf) 8.29885 Tj
-25 TJm
-(fer) 11.0585 Tj
-55 TJm
-(.) 2.49065 Tj
-[1 0 0 1 72 240.456] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.9626] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -230.493] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 220.695 Td
-/F130_0 9.9626 Tf
-(F) 5.53921 Tj
-15 TJm
-(or) 8.29885 Tj
--250 TJm
-(the) 12.1743 Tj
--250 TJm
-(meaning) 34.3112 Tj
--250 TJm
-(of) 8.29885 Tj
--250 TJm
-(parameters) 43.7059 Tj
-[1 0 0 1 196.631 220.695] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -196.631 -220.695] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-196.631 220.695 Td
-/F134_0 9.9626 Tf
-(small) 29.8878 Tj
-[1 0 0 1 226.519 220.695] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -226.519 -220.695] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-229.01 220.695 Td
-/F130_0 9.9626 Tf
-(and) 14.386 Tj
-[1 0 0 1 245.887 220.695] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -245.887 -220.695] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-245.887 220.695 Td
-/F134_0 9.9626 Tf
-(verbosity) 53.798 Tj
-[1 0 0 1 299.685 220.695] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -299.685 -220.695] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-299.685 220.695 Td
-/F130_0 9.9626 Tf
-(,) 2.49065 Tj
--250 TJm
-(see) 12.7222 Tj
-[1 0 0 1 319.879 220.695] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -319.879 -220.695] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-319.879 220.695 Td
-/F134_0 9.9626 Tf
-(BZ2_bzDecompressInit) 119.551 Tj
-[1 0 0 1 439.431 220.695] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -439.431 -220.695] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-439.431 220.695 Td
-/F130_0 9.9626 Tf
-(.) 2.49065 Tj
-[1 0 0 1 72 218.538] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.9626] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -208.576] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 198.777 Td
-/F130_0 9.9626 Tf
-(Because) 33.1954 Tj
--250 TJm
-(the) 12.1743 Tj
--249 TJm
-(compression) 50.3609 Tj
--250 TJm
-(ratio) 18.2614 Tj
--249 TJm
-(of) 8.29885 Tj
--250 TJm
-(the) 12.1743 Tj
--249 TJm
-(compressed) 47.0334 Tj
--250 TJm
-(data) 16.5977 Tj
--249 TJm
-(cannot) 26.5603 Tj
--250 TJm
-(be) 9.40469 Tj
--250 TJm
-(kno) 14.9439 Tj
-25 TJm
-(wn) 12.1743 Tj
--249 TJm
-(in) 7.7509 Tj
--250 TJm
-(adv) 14.386 Tj
-25 TJm
-(ance,) 20.7421 Tj
--249 TJm
-(there) 19.9152 Tj
--250 TJm
-(is) 6.64505 Tj
--249 TJm
-(no) 9.9626 Tj
--250 TJm
-(easy) 17.7035 Tj
--250 TJm
-(w) 7.193 Tj
-10 TJm
-(ay) 9.40469 Tj
--249 TJm
-(to) 7.7509 Tj
--250 TJm
-(guarantee) 38.7246 Tj
-72 186.822 Td
-(that) 14.9439 Tj
--286 TJm
-(the) 12.1743 Tj
--287 TJm
-(output) 25.4644 Tj
--286 TJm
-(b) 4.9813 Tj
-20 TJm
-(uf) 8.29885 Tj
-25 TJm
-(fer) 11.0585 Tj
--287 TJm
-(will) 15.5018 Tj
--286 TJm
-(be) 9.40469 Tj
--286 TJm
-(big) 12.7322 Tj
--287 TJm
-(enough.) 31.8205 Tj
--838 TJm
-(Y) 7.193 Tj
-110 TJm
-(ou) 9.9626 Tj
--287 TJm
-(may) 17.1556 Tj
--286 TJm
-(of) 8.29885 Tj
--287 TJm
-(course) 26.0024 Tj
--286 TJm
-(mak) 17.1556 Tj
-10 TJm
-(e) 4.42339 Tj
--286 TJm
-(arrangements) 53.6685 Tj
--287 TJm
-(in) 7.7509 Tj
--286 TJm
-(your) 18.2614 Tj
--287 TJm
-(code) 18.8094 Tj
--286 TJm
-(to) 7.7509 Tj
--286 TJm
-(record) 25.4445 Tj
--287 TJm
-(the) 12.1743 Tj
--286 TJm
-(size) 15.4918 Tj
--287 TJm
-(of) 8.29885 Tj
-72 174.867 Td
-(the) 12.1743 Tj
--250 TJm
-(uncompressed) 56.996 Tj
--250 TJm
-(data,) 19.0883 Tj
--250 TJm
-(b) 4.9813 Tj
-20 TJm
-(ut) 7.7509 Tj
--250 TJm
-(such) 18.2614 Tj
--250 TJm
-(a) 4.42339 Tj
--250 TJm
-(mechanism) 45.3796 Tj
--250 TJm
-(is) 6.64505 Tj
--250 TJm
-(be) 9.40469 Tj
-15 TJm
-(yond) 19.9252 Tj
--250 TJm
-(the) 12.1743 Tj
--250 TJm
-(scope) 22.6848 Tj
--250 TJm
-(of) 8.29885 Tj
--250 TJm
-(this) 14.396 Tj
--250 TJm
-(library) 26.5603 Tj
-65 TJm
-(.) 2.49065 Tj
-[1 0 0 1 72 172.71] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.9626] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -162.747] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 152.949 Td
-/F134_0 9.9626 Tf
-(BZ2_bzBuffToBuffDecompress) 155.417 Tj
-[1 0 0 1 227.417 152.949] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -227.417 -152.949] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-230.553 152.949 Td
-/F130_0 9.9626 Tf
-(will) 15.5018 Tj
--315 TJm
-(not) 12.7322 Tj
--315 TJm
-(write) 20.4731 Tj
--314 TJm
-(data) 16.5977 Tj
--315 TJm
-(at) 7.193 Tj
--315 TJm
-(or) 8.29885 Tj
--315 TJm
-(be) 9.40469 Tj
-15 TJm
-(yond) 19.9252 Tj
-[1 0 0 1 362.484 152.949] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -362.484 -152.949] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-362.484 152.949 Td
-/F134_0 9.9626 Tf
-(dest[) 29.8878 Tj
-392.372 151.206 Td
-(*) 5.97756 Tj
-398.349 152.949 Td
-(destLen]) 47.8205 Tj
-[1 0 0 1 446.17 152.949] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -446.17 -152.949] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-446.17 152.949 Td
-/F130_0 9.9626 Tf
-(,) 2.49065 Tj
--331 TJm
-(e) 4.42339 Tj
-25 TJm
-(v) 4.9813 Tj
-15 TJm
-(en) 9.40469 Tj
--315 TJm
-(in) 7.7509 Tj
--315 TJm
-(case) 17.1456 Tj
--314 TJm
-(of) 8.29885 Tj
--315 TJm
-(b) 4.9813 Tj
-20 TJm
-(uf) 8.29885 Tj
-25 TJm
-(fer) 11.0585 Tj
-72 140.994 Td
-(o) 4.9813 Tj
-15 TJm
-(v) 4.9813 Tj
-15 TJm
-(er\003o) 18.2614 Tj
-25 TJm
-(w) 7.193 Tj
-65 TJm
-(.) 2.49065 Tj
-[1 0 0 1 72 140.894] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.9626] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -130.932] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 119.076 Td
-/F130_0 9.9626 Tf
-(Possible) 33.2153 Tj
--250 TJm
-(return) 23.7907 Tj
--250 TJm
-(v) 4.9813 Tj
-25 TJm
-(alues:) 23.2427 Tj
-[1 0 0 1 72 118.977] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -68.1248] cm
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-[1 0 0 1 1.8929 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 374.394 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 6.8541] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 40.5726 -6.7545] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -493.841 -50.9514] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-534.414 50.9514 Td
-/F130_0 9.9626 Tf
-(27) 9.9626 Tj
-[1 0 0 1 453.269 50.8518] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 93.5985 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 6.2765 0] cm
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-[1 0 0 1 -13.1436 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-Q
-showpage
-%%PageTrailer
-pdfEndPage
-%%Page: 31 31
-%%BeginPageSetup
-%%PageOrientation: Portrait
-pdfStartPage
-0 0 612 792 re W
-%%EndPageSetup
-[] 0 d
-1 i
-0 j
-0 J
-10 M
-1 w
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-false op
-false OP
-0 0 612 792 re
-W
-q
-[1 0 0 1 72 741.554] cm
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-[1 0 0 1 1.8929 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 4.3836 14.4459] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 187.197 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4906 -8.9114] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 8.9114] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 76.4979 -6.7546] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -344.462 -749.245] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-420.96 749.245 Td
-/F130_0 9.9626 Tf
-(Programming) 54.7943 Tj
--250 TJm
-(with) 17.7135 Tj
-[1 0 0 1 498.449 749.245] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -498.449 -749.245] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-498.449 749.245 Td
-/F134_0 9.9626 Tf
-(libbzip2) 47.8205 Tj
-[1 0 0 1 546.269 749.245] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -278.305 -2.1568] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 280.796 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -472.974 -5.0363] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -0.4981] cm
-q
-[] 0 d
-0 J
-0.4981 w
-0 0.2491 m
-475.465 0.2491 l
-S
-Q
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 479.251 0] cm
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-[1 0 0 1 -15.0365 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -468 -248.702] cm
-/DeviceRGB {} cs
-[0.94899 0.94899 0.976456] sc
-/DeviceRGB {} CS
-[0.94899 0.94899 0.976456] SC
-0 0 468 227.148 re
-f
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 3.5866] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 223.562] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 18 -8.3686] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -90 -711.631] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-90 711.631 Td
-/F134_0 9.9626 Tf
-(BZ_CONFIG_ERROR) 89.6634 Tj
-98.4879 699.676 Td
-(if) 11.9551 Tj
--426 TJm
-(the) 17.9327 Tj
--426 TJm
-(library) 41.8429 Tj
--426 TJm
-(has) 17.9327 Tj
--426 TJm
-(been) 23.9102 Tj
--426 TJm
-(mis-compiled) 71.7307 Tj
-90 687.721 Td
-(BZ_PARAM_ERROR) 83.6858 Tj
-98.4879 675.766 Td
-(if) 11.9551 Tj
--426 TJm
-(dest) 23.9102 Tj
--426 TJm
-(is) 11.9551 Tj
--426 TJm
-(NULL) 23.9102 Tj
--426 TJm
-(or) 11.9551 Tj
--426 TJm
-(destLen) 41.8429 Tj
--426 TJm
-(is) 11.9551 Tj
--426 TJm
-(NULL) 23.9102 Tj
-98.4879 663.811 Td
-(or) 11.9551 Tj
--426 TJm
-(small) 29.8878 Tj
--426 TJm
-(!=) 11.9551 Tj
--426 TJm
-(0) 5.97756 Tj
--426 TJm
-(&&) 11.9551 Tj
--426 TJm
-(small) 29.8878 Tj
--426 TJm
-(!=) 11.9551 Tj
--426 TJm
-(1) 5.97756 Tj
-98.4879 651.856 Td
-(or) 11.9551 Tj
--426 TJm
-(verbosity) 53.798 Tj
--426 TJm
-(<) 5.97756 Tj
--426 TJm
-(0) 5.97756 Tj
--426 TJm
-(or) 11.9551 Tj
--426 TJm
-(verbosity) 53.798 Tj
--426 TJm
-(>) 5.97756 Tj
--426 TJm
-(4) 5.97756 Tj
-90 639.9 Td
-(BZ_MEM_ERROR) 71.7307 Tj
-98.4879 627.945 Td
-(if) 11.9551 Tj
--426 TJm
-(insufficient) 71.7307 Tj
--426 TJm
-(memory) 35.8654 Tj
--426 TJm
-(is) 11.9551 Tj
--426 TJm
-(available) 53.798 Tj
-90 615.99 Td
-(BZ_OUTBUFF_FULL) 89.6634 Tj
-98.4879 604.035 Td
-(if) 11.9551 Tj
--426 TJm
-(the) 17.9327 Tj
--426 TJm
-(size) 23.9102 Tj
--426 TJm
-(of) 11.9551 Tj
--426 TJm
-(the) 17.9327 Tj
--426 TJm
-(compressed) 59.7756 Tj
--426 TJm
-(data) 23.9102 Tj
--426 TJm
-(exceeds) 41.8429 Tj
-341.655 602.291 Td
-(*) 5.97756 Tj
-347.633 604.035 Td
-(destLen) 41.8429 Tj
-90 592.08 Td
-(BZ_DATA_ERROR) 77.7083 Tj
-98.4879 580.125 Td
-(if) 11.9551 Tj
--426 TJm
-(a) 5.97756 Tj
--426 TJm
-(data) 23.9102 Tj
--426 TJm
-(integrity) 53.798 Tj
--426 TJm
-(error) 29.8878 Tj
--426 TJm
-(was) 17.9327 Tj
--426 TJm
-(detected) 47.8205 Tj
--426 TJm
-(in) 11.9551 Tj
--426 TJm
-(the) 17.9327 Tj
--426 TJm
-(compressed) 59.7756 Tj
--426 TJm
-(data) 23.9102 Tj
-90 568.169 Td
-(BZ_DATA_ERROR_MAGIC) 113.574 Tj
-98.4879 556.214 Td
-(if) 11.9551 Tj
--426 TJm
-(the) 17.9327 Tj
--426 TJm
-(compressed) 59.7756 Tj
--426 TJm
-(data) 23.9102 Tj
--426 TJm
-(doesn't) 41.8429 Tj
--426 TJm
-(begin) 29.8878 Tj
--426 TJm
-(with) 23.9102 Tj
--426 TJm
-(the) 17.9327 Tj
--426 TJm
-(right) 29.8878 Tj
--426 TJm
-(magic) 29.8878 Tj
--426 TJm
-(bytes) 29.8878 Tj
-90 544.259 Td
-(BZ_UNEXPECTED_EOF) 101.619 Tj
-98.4879 532.304 Td
-(if) 11.9551 Tj
--426 TJm
-(the) 17.9327 Tj
--426 TJm
-(compressed) 59.7756 Tj
--426 TJm
-(data) 23.9102 Tj
--426 TJm
-(ends) 23.9102 Tj
--426 TJm
-(unexpectedly) 71.7307 Tj
-90 520.349 Td
-(BZ_OK) 29.8878 Tj
-98.4879 508.394 Td
-(otherwise) 53.798 Tj
-[1 0 0 1 72 492.852] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 468 3.5866] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -468 -3.5866] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.9626] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -482.889] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 458.099 Td
-/F122_0 20.6585 Tf
-(3.6.) 34.4584 Tj
-[1 0 0 1 112.201 458.099] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -112.201 -458.099] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-112.201 458.099 Td
-/F392_0 20.6585 Tf
-(zlib) 49.5804 Tj
-[1 0 0 1 161.781 458.099] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -161.781 -458.099] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-167.524 458.099 Td
-/F122_0 20.6585 Tf
-(compatibility) 127.422 Tj
--278 TJm
-(functions) 92.9633 Tj
-[1 0 0 1 72 453.823] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.9626] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -443.86] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 436.181 Td
-/F130_0 9.9626 Tf
-(Y) 7.193 Tj
-110 TJm
-(oshioka) 30.9936 Tj
--604 TJm
-(Tsuneo) 29.3299 Tj
--604 TJm
-(has) 13.2801 Tj
--604 TJm
-(contrib) 28.224 Tj
-20 TJm
-(uted) 17.1556 Tj
--604 TJm
-(some) 21.031 Tj
--604 TJm
-(functions) 37.0808 Tj
--604 TJm
-(to) 7.7509 Tj
--604 TJm
-(gi) 7.7509 Tj
-25 TJm
-(v) 4.9813 Tj
-15 TJm
-(e) 4.42339 Tj
--604 TJm
-(better) 22.6848 Tj
-[1 0 0 1 356.347 436.181] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -356.347 -436.181] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-356.347 436.181 Td
-/F134_0 9.9626 Tf
-(zlib) 23.9102 Tj
-[1 0 0 1 380.257 436.181] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -380.257 -436.181] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-386.275 436.181 Td
-/F130_0 9.9626 Tf
-(compatibility) 53.1405 Tj
-65 TJm
-(.) 2.49065 Tj
--1372 TJm
-(These) 23.7907 Tj
--604 TJm
-(functions) 37.0808 Tj
--604 TJm
-(are) 12.1643 Tj
-[1 0 0 1 72 424.226] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -424.226] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 424.226 Td
-/F134_0 9.9626 Tf
-(BZ2_bzopen) 59.7756 Tj
-[1 0 0 1 131.776 424.226] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -131.776 -424.226] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-131.776 424.226 Td
-/F130_0 9.9626 Tf
-(,) 2.49065 Tj
-[1 0 0 1 144.283 424.226] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -144.283 -424.226] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-144.283 424.226 Td
-/F134_0 9.9626 Tf
-(BZ2_bzread) 59.7756 Tj
-[1 0 0 1 204.059 424.226] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -204.059 -424.226] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-204.059 424.226 Td
-/F130_0 9.9626 Tf
-(,) 2.49065 Tj
-[1 0 0 1 216.566 424.226] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -216.566 -424.226] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-216.566 424.226 Td
-/F134_0 9.9626 Tf
-(BZ2_bzwrite) 65.7532 Tj
-[1 0 0 1 282.32 424.226] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -282.32 -424.226] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-282.32 424.226 Td
-/F130_0 9.9626 Tf
-(,) 2.49065 Tj
-[1 0 0 1 294.827 424.226] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -294.827 -424.226] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-294.827 424.226 Td
-/F134_0 9.9626 Tf
-(BZ2_bzflush) 65.7532 Tj
-[1 0 0 1 360.581 424.226] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -360.581 -424.226] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-360.581 424.226 Td
-/F130_0 9.9626 Tf
-(,) 2.49065 Tj
-[1 0 0 1 373.088 424.226] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -373.088 -424.226] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-373.088 424.226 Td
-/F134_0 9.9626 Tf
-(BZ2_bzclose) 65.7532 Tj
-[1 0 0 1 438.842 424.226] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -438.842 -424.226] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-438.842 424.226 Td
-/F130_0 9.9626 Tf
-(,) 2.49065 Tj
-[1 0 0 1 451.349 424.226] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -451.349 -424.226] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-451.349 424.226 Td
-/F134_0 9.9626 Tf
-(BZ2_bzerror) 65.7532 Tj
-[1 0 0 1 517.102 424.226] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -517.102 -424.226] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-525.614 424.226 Td
-/F130_0 9.9626 Tf
-(and) 14.386 Tj
-[1 0 0 1 72 412.271] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -412.271] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 412.271 Td
-/F134_0 9.9626 Tf
-(BZ2_bzlibVersion) 95.641 Tj
-[1 0 0 1 167.641 412.271] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -167.641 -412.271] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-167.641 412.271 Td
-/F130_0 9.9626 Tf
-(.) 2.49065 Tj
--1420 TJm
-(Thes) 19.3673 Tj
-1 TJm
-(e) 4.42339 Tj
--384 TJm
-(functions) 37.0808 Tj
--383 TJm
-(are) 12.1643 Tj
--383 TJm
-(not) 12.7322 Tj
--383 TJm
-(\(yet\)) 18.8094 Tj
--384 TJm
-(of) 8.29885 Tj
-25 TJm
-(\002cially) 27.6761 Tj
--383 TJm
-(part) 15.4918 Tj
--383 TJm
-(of) 8.29885 Tj
--383 TJm
-(the) 12.1743 Tj
--384 TJm
-(library) 26.5603 Tj
-65 TJm
-(.) 2.49065 Tj
--1419 TJm
-(If) 6.63509 Tj
--383 TJm
-(the) 12.1743 Tj
-15 TJm
-(y) 4.9813 Tj
--384 TJm
-(break,) 24.6176 Tj
--416 TJm
-(you) 14.9439 Tj
--383 TJm
-(get) 12.1743 Tj
--384 TJm
-(to) 7.7509 Tj
-72 400.316 Td
-(k) 4.9813 Tj
-10 TJm
-(eep) 13.8281 Tj
--250 TJm
-(all) 9.9626 Tj
--250 TJm
-(the) 12.1743 Tj
--250 TJm
-(pieces.) 27.3872 Tj
--620 TJm
-(Ne) 11.6164 Tj
-25 TJm
-(v) 4.9813 Tj
-15 TJm
-(ertheless,) 37.3498 Tj
--250 TJm
-(I) 3.31755 Tj
--250 TJm
-(think) 20.4831 Tj
--250 TJm
-(the) 12.1743 Tj
-15 TJm
-(y) 4.9813 Tj
--250 TJm
-(w) 7.193 Tj
-10 TJm
-(ork) 13.2801 Tj
--250 TJm
-(ok.) 12.4533 Tj
-[1 0 0 1 72 398.159] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -48.8169] cm
-/DeviceRGB {} cs
-[0.94899 0.94899 0.976456] sc
-/DeviceRGB {} CS
-[0.94899 0.94899 0.976456] SC
-0 0 468 47.8207 re
-f
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 3.5866] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 44.2341] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 18 -8.3686] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -90 -388.794] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-90 388.794 Td
-/F134_0 9.9626 Tf
-(typedef) 41.8429 Tj
--426 TJm
-(void) 23.9102 Tj
--426 TJm
-(BZFILE;) 41.8429 Tj
-90 364.884 Td
-(const) 29.8878 Tj
--426 TJm
-(char) 23.9102 Tj
-152.286 363.14 Td
-(*) 5.97756 Tj
-162.508 364.884 Td
-(BZ2_bzlibVersion) 95.641 Tj
--426 TJm
-(\() 5.97756 Tj
--426 TJm
-(void) 23.9102 Tj
--426 TJm
-(\);) 11.9551 Tj
-[1 0 0 1 72 349.342] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 468 3.5866] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -468 -13.5492] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -339.379] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 327.424 Td
-/F130_0 9.9626 Tf
-(Returns) 30.9936 Tj
--250 TJm
-(a) 4.42339 Tj
--250 TJm
-(string) 22.6948 Tj
--250 TJm
-(indicating) 39.8504 Tj
--250 TJm
-(the) 12.1743 Tj
--250 TJm
-(library) 26.5603 Tj
--250 TJm
-(v) 4.9813 Tj
-15 TJm
-(ersion.) 26.8392 Tj
-[1 0 0 1 72 325.267] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -36.8618] cm
-/DeviceRGB {} cs
-[0.94899 0.94899 0.976456] sc
-/DeviceRGB {} CS
-[0.94899 0.94899 0.976456] SC
-0 0 468 35.8655 re
-f
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 3.5866] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 32.2789] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 18 -8.3686] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -90 -315.902] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-90 315.902 Td
-/F134_0 9.9626 Tf
-(BZFILE) 35.8654 Tj
-130.109 314.159 Td
-(*) 5.97756 Tj
-140.331 315.902 Td
-(BZ2_bzopen) 59.7756 Tj
--852 TJm
-(\() 5.97756 Tj
--426 TJm
-(const) 29.8878 Tj
--426 TJm
-(char) 23.9102 Tj
-281.103 314.159 Td
-(*) 5.97756 Tj
-287.08 315.902 Td
-(path,) 29.8878 Tj
--426 TJm
-(const) 29.8878 Tj
--426 TJm
-(char) 23.9102 Tj
-383.498 314.159 Td
-(*) 5.97756 Tj
-389.476 315.902 Td
-(mode) 23.9102 Tj
--426 TJm
-(\);) 11.9551 Tj
-90 303.947 Td
-(BZFILE) 35.8654 Tj
-130.109 302.204 Td
-(*) 5.97756 Tj
-140.331 303.947 Td
-(BZ2_bzdopen) 65.7532 Tj
--426 TJm
-(\() 5.97756 Tj
--426 TJm
-(int) 17.9327 Tj
--3408 TJm
-(fd,) 17.9327 Tj
--1704 TJm
-(const) 29.8878 Tj
--426 TJm
-(char) 23.9102 Tj
-369.629 302.204 Td
-(*) 5.97756 Tj
-375.607 303.947 Td
-(mode) 23.9102 Tj
--426 TJm
-(\);) 11.9551 Tj
-[1 0 0 1 72 288.405] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 468 3.5866] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -468 -13.5492] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -278.443] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 266.488 Td
-/F130_0 9.9626 Tf
-(Opens) 25.4544 Tj
--243 TJm
-(a) 4.42339 Tj
-[1 0 0 1 106.713 266.488] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -106.713 -266.488] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-106.713 266.488 Td
-/F134_0 9.9626 Tf
-(.bz2) 23.9102 Tj
-[1 0 0 1 130.624 266.488] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -130.624 -266.488] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-133.041 266.488 Td
-/F130_0 9.9626 Tf
-(\002le) 12.7322 Tj
--243 TJm
-(for) 11.6164 Tj
--242 TJm
-(reading) 29.8778 Tj
--243 TJm
-(or) 8.29885 Tj
--243 TJm
-(writing,) 31.2726 Tj
--244 TJm
-(using) 21.589 Tj
--243 TJm
-(ei) 7.193 Tj
-1 TJm
-(ther) 15.4918 Tj
--243 TJm
-(its) 9.41466 Tj
--243 TJm
-(name) 21.579 Tj
--242 TJm
-(o) 4.9813 Tj
--1 TJm
-(r) 3.31755 Tj
--242 TJm
-(a) 4.42339 Tj
--243 TJm
-(pre-e) 20.4632 Tj
-15 TJm
-(xisting) 27.1282 Tj
--243 TJm
-(\002le) 12.7322 Tj
--242 TJm
-(descriptor) 39.8404 Tj
-55 TJm
-(.) 2.49065 Tj
--615 TJm
-(Analogous) 43.1679 Tj
--243 TJm
-(to) 7.7509 Tj
-[1 0 0 1 510.112 266.488] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -510.112 -266.488] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-510.112 266.488 Td
-/F134_0 9.9626 Tf
-(fopen) 29.8878 Tj
-[1 0 0 1 540 266.488] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -540 -266.488] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 254.532 Td
-/F130_0 9.9626 Tf
-(and) 14.386 Tj
-[1 0 0 1 88.8767 254.532] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -88.8767 -254.532] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-88.8767 254.532 Td
-/F134_0 9.9626 Tf
-(fdopen) 35.8654 Tj
-[1 0 0 1 124.742 254.532] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -124.742 -254.532] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-124.742 254.532 Td
-/F130_0 9.9626 Tf
-(.) 2.49065 Tj
-[1 0 0 1 72 252.998] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -36.8618] cm
-/DeviceRGB {} cs
-[0.94899 0.94899 0.976456] sc
-/DeviceRGB {} CS
-[0.94899 0.94899 0.976456] SC
-0 0 468 35.8655 re
-f
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 3.5866] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 32.2789] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 18 -8.3686] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -90 -243.633] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-90 243.633 Td
-/F134_0 9.9626 Tf
-(int) 17.9327 Tj
--426 TJm
-(BZ2_bzread) 59.7756 Tj
--852 TJm
-(\() 5.97756 Tj
--426 TJm
-(BZFILE) 35.8654 Tj
-226.528 241.89 Td
-(*) 5.97756 Tj
-236.749 243.633 Td
-(b,) 11.9551 Tj
--426 TJm
-(void) 23.9102 Tj
-276.859 241.89 Td
-(*) 5.97756 Tj
-287.08 243.633 Td
-(buf,) 23.9102 Tj
--426 TJm
-(int) 17.9327 Tj
--426 TJm
-(len) 17.9327 Tj
--426 TJm
-(\);) 11.9551 Tj
-90 231.678 Td
-(int) 17.9327 Tj
--426 TJm
-(BZ2_bzwrite) 65.7532 Tj
--426 TJm
-(\() 5.97756 Tj
--426 TJm
-(BZFILE) 35.8654 Tj
-228.261 229.935 Td
-(*) 5.97756 Tj
-238.483 231.678 Td
-(b,) 11.9551 Tj
--426 TJm
-(void) 23.9102 Tj
-278.592 229.935 Td
-(*) 5.97756 Tj
-288.814 231.678 Td
-(buf,) 23.9102 Tj
--426 TJm
-(int) 17.9327 Tj
--426 TJm
-(len) 17.9327 Tj
--426 TJm
-(\);) 11.9551 Tj
-[1 0 0 1 72 216.136] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 468 3.5866] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -468 -13.5492] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -206.174] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 194.219 Td
-/F130_0 9.9626 Tf
-(Reads/writes) 51.4668 Tj
--250 TJm
-(data) 16.5977 Tj
--250 TJm
-(from/to) 29.8878 Tj
--250 TJm
-(a) 4.42339 Tj
--250 TJm
-(pre) 12.7222 Tj
-25 TJm
-(viously) 29.3399 Tj
--250 TJm
-(opened) 28.772 Tj
-[1 0 0 1 259.903 194.219] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -259.903 -194.219] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-259.903 194.219 Td
-/F134_0 9.9626 Tf
-(BZFILE) 35.8654 Tj
-[1 0 0 1 295.769 194.219] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -295.769 -194.219] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-295.769 194.219 Td
-/F130_0 9.9626 Tf
-(.) 2.49065 Tj
--500 TJm
-(Analogous) 43.1679 Tj
--250 TJm
-(to) 7.7509 Tj
-[1 0 0 1 359.141 194.219] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -359.141 -194.219] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-359.141 194.219 Td
-/F134_0 9.9626 Tf
-(fread) 29.8878 Tj
-[1 0 0 1 389.029 194.219] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -389.029 -194.219] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-391.519 194.219 Td
-/F130_0 9.9626 Tf
-(and) 14.386 Tj
-[1 0 0 1 408.396 194.219] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -408.396 -194.219] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-408.396 194.219 Td
-/F134_0 9.9626 Tf
-(fwrite) 35.8654 Tj
-[1 0 0 1 444.261 194.219] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -444.261 -194.219] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-444.261 194.219 Td
-/F130_0 9.9626 Tf
-(.) 2.49065 Tj
-[1 0 0 1 72 192.062] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -36.8618] cm
-/DeviceRGB {} cs
-[0.94899 0.94899 0.976456] sc
-/DeviceRGB {} CS
-[0.94899 0.94899 0.976456] SC
-0 0 468 35.8655 re
-f
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 3.5866] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 32.2789] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 18 -8.3686] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -90 -182.697] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-90 182.697 Td
-/F134_0 9.9626 Tf
-(int) 17.9327 Tj
--852 TJm
-(BZ2_bzflush) 65.7532 Tj
--426 TJm
-(\() 5.97756 Tj
--426 TJm
-(BZFILE) 35.8654 Tj
-232.505 180.954 Td
-(*) 5.97756 Tj
-242.727 182.697 Td
-(b) 5.97756 Tj
--426 TJm
-(\);) 11.9551 Tj
-90 170.742 Td
-(void) 23.9102 Tj
--426 TJm
-(BZ2_bzclose) 65.7532 Tj
--426 TJm
-(\() 5.97756 Tj
--426 TJm
-(BZFILE) 35.8654 Tj
-234.239 168.998 Td
-(*) 5.97756 Tj
-244.46 170.742 Td
-(b) 5.97756 Tj
--426 TJm
-(\);) 11.9551 Tj
-[1 0 0 1 72 155.2] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 468 3.5866] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -468 -13.5492] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -145.237] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 133.282 Td
-/F130_0 9.9626 Tf
-(Flushes/closes) 57.5639 Tj
--250 TJm
-(a) 4.42339 Tj
-[1 0 0 1 138.968 133.282] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -138.968 -133.282] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-138.968 133.282 Td
-/F134_0 9.9626 Tf
-(BZFILE) 35.8654 Tj
-[1 0 0 1 174.833 133.282] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -174.833 -133.282] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-174.833 133.282 Td
-/F130_0 9.9626 Tf
-(.) 2.49065 Tj
-[1 0 0 1 179.815 133.282] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -179.815 -133.282] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-179.815 133.282 Td
-/F134_0 9.9626 Tf
-(BZ2_bzflush) 65.7532 Tj
-[1 0 0 1 245.568 133.282] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -245.568 -133.282] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-248.059 133.282 Td
-/F130_0 9.9626 Tf
-(doesn') 26.5603 Tj
-18 TJm
-(t) 2.7696 Tj
--250 TJm
-(actually) 31.5416 Tj
--250 TJm
-(do) 9.9626 Tj
--250 TJm
-(an) 9.40469 Tj
-15 TJm
-(ything.) 27.9551 Tj
--620 TJm
-(Analogous) 43.1679 Tj
--250 TJm
-(to) 7.7509 Tj
-[1 0 0 1 425.472 133.282] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -425.472 -133.282] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-425.472 133.282 Td
-/F134_0 9.9626 Tf
-(fflush) 35.8654 Tj
-[1 0 0 1 461.338 133.282] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -461.338 -133.282] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-463.828 133.282 Td
-/F130_0 9.9626 Tf
-(and) 14.386 Tj
-[1 0 0 1 480.705 133.282] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -480.705 -133.282] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-480.705 133.282 Td
-/F134_0 9.9626 Tf
-(fclose) 35.8654 Tj
-[1 0 0 1 516.57 133.282] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -516.57 -133.282] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-516.57 133.282 Td
-/F130_0 9.9626 Tf
-(.) 2.49065 Tj
-[1 0 0 1 72 131.125] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -24.9066] cm
-/DeviceRGB {} cs
-[0.94899 0.94899 0.976456] sc
-/DeviceRGB {} CS
-[0.94899 0.94899 0.976456] SC
-0 0 468 23.9103 re
-f
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 3.5866] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 20.3237] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 18 -8.3685] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -90 -121.761] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-90 121.761 Td
-/F134_0 9.9626 Tf
-(const) 29.8878 Tj
--426 TJm
-(char) 23.9102 Tj
-152.286 120.017 Td
-(*) 5.97756 Tj
-162.508 121.761 Td
-(BZ2_bzerror) 65.7532 Tj
--426 TJm
-(\() 5.97756 Tj
--426 TJm
-(BZFILE) 35.8654 Tj
-282.836 120.017 Td
-(*) 5.97756 Tj
-288.814 121.761 Td
-(b,) 11.9551 Tj
--426 TJm
-(int) 17.9327 Tj
-327.19 120.017 Td
-(*) 5.97756 Tj
-333.167 121.761 Td
-(errnum) 35.8654 Tj
--426 TJm
-(\)) 5.97756 Tj
-[1 0 0 1 72 106.219] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 468 3.5866] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -468 -13.5492] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -96.2563] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 84.3011 Td
-/F130_0 9.9626 Tf
-(Returns) 30.9936 Tj
--250 TJm
-(a) 4.42339 Tj
--250 TJm
-(string) 22.6948 Tj
--250 TJm
-(describing) 41.5042 Tj
--250 TJm
-(the) 12.1743 Tj
--250 TJm
-(more) 20.4731 Tj
--250 TJm
-(recent) 24.3386 Tj
--250 TJm
-(error) 19.3573 Tj
--250 TJm
-(status) 22.6948 Tj
--250 TJm
-(of) 8.29885 Tj
-[1 0 0 1 303.858 84.3011] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -303.858 -84.3011] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-303.858 84.3011 Td
-/F134_0 9.9626 Tf
-(b) 5.97756 Tj
-[1 0 0 1 309.835 84.3011] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -309.835 -84.3011] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-309.835 84.3011 Td
-/F130_0 9.9626 Tf
-(,) 2.49065 Tj
--250 TJm
-(and) 14.386 Tj
--250 TJm
-(also) 16.0497 Tj
--250 TJm
-(sets) 14.9439 Tj
-[1 0 0 1 367.668 84.3011] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -367.668 -84.3011] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-367.668 82.5576 Td
-/F134_0 9.9626 Tf
-(*) 5.97756 Tj
-373.645 84.3011 Td
-(errnum) 35.8654 Tj
-[1 0 0 1 409.511 84.3011] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -409.511 -84.3011] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-412.001 84.3011 Td
-/F130_0 9.9626 Tf
-(to) 7.7509 Tj
--250 TJm
-(its) 9.41466 Tj
--250 TJm
-(numerical) 39.8404 Tj
--250 TJm
-(v) 4.9813 Tj
-25 TJm
-(alue.) 19.0883 Tj
-[1 0 0 1 72 82.1443] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.9627] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -21.3298] cm
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-[1 0 0 1 1.8929 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 4.3836 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 374.394 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 6.8541] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 40.5726 -6.7545] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -495.734 -50.9514] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-536.307 50.9514 Td
-/F130_0 9.9626 Tf
-(28) 9.9626 Tj
-[1 0 0 1 455.161 50.8518] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 93.5985 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 6.2765 0] cm
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-[1 0 0 1 -15.0365 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-Q
-showpage
-%%PageTrailer
-pdfEndPage
-%%Page: 32 32
-%%BeginPageSetup
-%%PageOrientation: Portrait
-pdfStartPage
-0 0 612 792 re W
-%%EndPageSetup
-[] 0 d
-1 i
-0 j
-0 J
-10 M
-1 w
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-false op
-false OP
-0 0 612 792 re
-W
-q
-[1 0 0 1 72 741.554] cm
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-[1 0 0 1 1.8929 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 14.4459] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 187.197 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 -8.9114] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 8.9114] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 76.4979 -6.7546] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -342.569 -749.245] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-419.067 749.245 Td
-/F130_0 9.9626 Tf
-(Programming) 54.7943 Tj
--250 TJm
-(with) 17.7135 Tj
-[1 0 0 1 496.556 749.245] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -496.556 -749.245] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-496.556 749.245 Td
-/F134_0 9.9626 Tf
-(libbzip2) 47.8205 Tj
-[1 0 0 1 544.376 749.245] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -278.305 -2.1568] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 280.796 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -472.974 -5.0363] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -0.4981] cm
-q
-[] 0 d
-0 J
-0.4981 w
-0 0.2491 m
-475.465 0.2491 l
-S
-Q
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 479.251 0] cm
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-[1 0 0 1 -13.1436 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -540 -741.554] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 704.93 Td
-/F122_0 20.6585 Tf
-(3.7.) 34.4584 Tj
--278 TJm
-(Using) 57.3893 Tj
--278 TJm
-(the) 30.9877 Tj
--278 TJm
-(librar) 51.6669 Tj
--10 TJm
-(y) 11.4861 Tj
--278 TJm
-(in) 18.3654 Tj
--278 TJm
-(a) 11.4861 Tj
-[1 0 0 1 322.501 704.93] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -322.501 -704.93] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-322.501 704.93 Td
-/F392_0 20.6585 Tf
-(stdio) 61.9755 Tj
-[1 0 0 1 384.477 704.93] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -384.477 -704.93] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-384.477 704.93 Td
-/F122_0 20.6585 Tf
-(-free) 44.767 Tj
-72 680.139 Td
-(en) 24.1085 Tj
-40 TJm
-(vir) 25.2653 Tj
-20 TJm
-(onment) 74.5978 Tj
-[1 0 0 1 72 679.881] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.898] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -669.983] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 649.583 Td
-/F122_0 17.2154 Tf
-(3.7.1.) 43.0729 Tj
--278 TJm
-(Getting) 60.2539 Tj
--278 TJm
-(rid) 22.0013 Tj
--278 TJm
-(of) 16.2513 Tj
-[1 0 0 1 232.721 649.583] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -232.721 -649.583] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-232.721 649.583 Td
-/F392_0 17.2154 Tf
-(stdio) 51.6462 Tj
-[1 0 0 1 284.367 649.583] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -212.367 -3.8303] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.898] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -635.855] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 627.73 Td
-/F130_0 9.9626 Tf
-(In) 8.29885 Tj
--319 TJm
-(a) 4.42339 Tj
--319 TJm
-(deeply) 26.5603 Tj
--319 TJm
-(embedded) 40.9463 Tj
--319 TJm
-(application,) 46.7644 Tj
--336 TJm
-(you) 14.9439 Tj
--319 TJm
-(might) 23.2527 Tj
--319 TJm
-(w) 7.193 Tj
-10 TJm
-(ant) 12.1743 Tj
--319 TJm
-(to) 7.7509 Tj
--319 TJm
-(use) 13.2801 Tj
--319 TJm
-(just) 14.396 Tj
--319 TJm
-(the) 12.1743 Tj
--319 TJm
-(memory-to-memory) 80.7967 Tj
--319 TJm
-(functions.) 39.5714 Tj
--1035 TJm
-(Y) 7.193 Tj
-110 TJm
-(ou) 9.9626 Tj
--319 TJm
-(can) 13.8281 Tj
--319 TJm
-(do) 9.9626 Tj
--319 TJm
-(this) 14.396 Tj
-72 615.775 Td
-(con) 14.386 Tj
-40 TJm
-(v) 4.9813 Tj
-15 TJm
-(eniently) 32.0995 Tj
--327 TJm
-(by) 9.9626 Tj
--327 TJm
-(compiling) 40.4083 Tj
--327 TJm
-(the) 12.1743 Tj
--327 TJm
-(library) 26.5603 Tj
--327 TJm
-(with) 17.7135 Tj
--328 TJm
-(preproces) 38.7246 Tj
-1 TJm
-(sor) 12.1743 Tj
--328 TJm
-(symbol) 29.3399 Tj
-[1 0 0 1 336.046 615.775] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -336.046 -615.775] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-336.046 615.775 Td
-/F134_0 9.9626 Tf
-(BZ_NO_STDIO) 65.7532 Tj
-[1 0 0 1 401.799 615.775] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -401.799 -615.775] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-405.057 615.775 Td
-/F130_0 9.9626 Tf
-(de\002ned.) 31.8205 Tj
--1083 TJm
-(Doing) 24.9065 Tj
--327 TJm
-(this) 14.396 Tj
--327 TJm
-(gi) 7.7509 Tj
-25 TJm
-(v) 4.9813 Tj
-15 TJm
-(es) 8.29885 Tj
--327 TJm
-(you) 14.9439 Tj
--327 TJm
-(a) 4.42339 Tj
-72 603.819 Td
-(library) 26.5603 Tj
--250 TJm
-(containing) 42.0621 Tj
--250 TJm
-(only) 17.7135 Tj
--250 TJm
-(the) 12.1743 Tj
--250 TJm
-(follo) 18.8194 Tj
-25 TJm
-(wing) 19.9252 Tj
--250 TJm
-(eight) 19.9252 Tj
--250 TJm
-(functions:) 39.8504 Tj
-[1 0 0 1 72 601.662] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.898] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -591.764] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 581.966 Td
-/F134_0 9.9626 Tf
-(BZ2_bzCompressInit) 107.596 Tj
-[1 0 0 1 179.596 581.966] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -179.596 -581.966] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-179.596 581.966 Td
-/F130_0 9.9626 Tf
-(,) 2.49065 Tj
-[1 0 0 1 199.079 581.966] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -199.079 -581.966] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-199.079 581.966 Td
-/F134_0 9.9626 Tf
-(BZ2_bzCompress) 83.6858 Tj
-[1 0 0 1 282.765 581.966] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -282.765 -581.966] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-282.765 581.966 Td
-/F130_0 9.9626 Tf
-(,) 2.49065 Tj
-[1 0 0 1 302.247 581.966] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -302.247 -581.966] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-302.247 581.966 Td
-/F134_0 9.9626 Tf
-(BZ2_bzCompressEnd) 101.619 Tj
-[1 0 0 1 403.866 581.966] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 14.0915 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -417.958 -581.966] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-417.958 581.966 Td
-/F134_0 9.9626 Tf
-(BZ2_bzDecompressInit) 119.551 Tj
-[1 0 0 1 537.509 581.966] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -537.509 -581.966] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-537.509 581.966 Td
-/F130_0 9.9626 Tf
-(,) 2.49065 Tj
-[1 0 0 1 72 570.011] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -570.011] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 570.011 Td
-/F134_0 9.9626 Tf
-(BZ2_bzDecompress) 95.641 Tj
-[1 0 0 1 167.641 570.011] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -167.641 -570.011] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-167.641 570.011 Td
-/F130_0 9.9626 Tf
-(,) 2.49065 Tj
-[1 0 0 1 172.144 570.011] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -172.144 -570.011] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-172.144 570.011 Td
-/F134_0 9.9626 Tf
-(BZ2_bzDecompressEnd) 113.574 Tj
-[1 0 0 1 285.719 570.011] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 1.8929 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -287.611 -570.011] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-287.611 570.011 Td
-/F134_0 9.9626 Tf
-(BZ2_bzBuffToBuffCompress) 143.461 Tj
-[1 0 0 1 431.073 570.011] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -431.073 -570.011] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-431.073 570.011 Td
-/F130_0 9.9626 Tf
-(,) 2.49065 Tj
-[1 0 0 1 435.577 570.011] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -435.577 -570.011] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-435.577 570.011 Td
-/F134_0 9.9626 Tf
-(BZ2_bzBuffToBuffDecompress) 155.417 Tj
-[1 0 0 1 590.994 570.011] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -518.994 -1.5341] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.8981] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -558.579] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 548.158 Td
-/F130_0 9.9626 Tf
-(When) 23.7907 Tj
--250 TJm
-(compiled) 37.0808 Tj
--250 TJm
-(lik) 10.5205 Tj
-10 TJm
-(e) 4.42339 Tj
--250 TJm
-(this,) 16.8866 Tj
--250 TJm
-(all) 9.9626 Tj
--250 TJm
-(functions) 37.0808 Tj
--250 TJm
-(will) 15.5018 Tj
--250 TJm
-(ignore) 25.4544 Tj
-[1 0 0 1 272.526 548.158] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -272.526 -548.158] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-272.526 548.158 Td
-/F134_0 9.9626 Tf
-(verbosity) 53.798 Tj
-[1 0 0 1 326.324 548.158] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -326.324 -548.158] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-328.815 548.158 Td
-/F130_0 9.9626 Tf
-(settings.) 32.9364 Tj
-[1 0 0 1 72 546.001] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.898] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -536.103] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 517.601 Td
-/F122_0 17.2154 Tf
-(3.7.2.) 43.0729 Tj
--278 TJm
-(Critical) 58.3602 Tj
--278 TJm
-(err) 22.9653 Tj
-20 TJm
-(or) 17.2154 Tj
--278 TJm
-(handling) 71.7366 Tj
-[1 0 0 1 72 513.771] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.898] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -503.873] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 495.748 Td
-/F134_0 9.9626 Tf
-(libbzip2) 47.8205 Tj
-[1 0 0 1 119.821 495.748] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -119.821 -495.748] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-124.529 495.748 Td
-/F130_0 9.9626 Tf
-(contains) 33.2053 Tj
--473 TJm
-(a) 4.42339 Tj
--472 TJm
-(number) 30.4357 Tj
--473 TJm
-(of) 8.29885 Tj
--472 TJm
-(internal) 30.4357 Tj
--473 TJm
-(assertion) 35.417 Tj
--472 TJm
-(checks) 27.1082 Tj
--473 TJm
-(which) 24.3486 Tj
--472 TJm
-(should,) 29.0609 Tj
--529 TJm
-(needless) 33.7533 Tj
--472 TJm
-(to) 7.7509 Tj
--473 TJm
-(say) 13.2801 Tj
-65 TJm
-(,) 2.49065 Tj
--528 TJm
-(ne) 9.40469 Tj
-25 TJm
-(v) 4.9813 Tj
-15 TJm
-(er) 7.74094 Tj
--473 TJm
-(be) 9.40469 Tj
--472 TJm
-(acti) 14.386 Tj
-25 TJm
-(v) 4.9813 Tj
-25 TJm
-(ated.) 19.0883 Tj
-72 483.793 Td
-(Ne) 11.6164 Tj
-25 TJm
-(v) 4.9813 Tj
-15 TJm
-(ertheless,) 37.3498 Tj
--533 TJm
-(if) 6.08715 Tj
--476 TJm
-(an) 9.40469 Tj
--476 TJm
-(assertion) 35.417 Tj
--476 TJm
-(should) 26.5703 Tj
--476 TJm
-(f) 3.31755 Tj
-10 TJm
-(ail,) 12.4533 Tj
--532 TJm
-(beha) 18.8094 Tj
-20 TJm
-(viour) 21.031 Tj
--476 TJm
-(depends) 32.6474 Tj
--476 TJm
-(on) 9.9626 Tj
--476 TJm
-(whether) 32.0895 Tj
--476 TJm
-(or) 8.29885 Tj
--477 TJm
-(not) 12.7322 Tj
--476 TJm
-(the) 12.1743 Tj
--476 TJm
-(library) 26.5603 Tj
--476 TJm
-(w) 7.193 Tj
-10 TJm
-(as) 8.29885 Tj
--476 TJm
-(compiled) 37.0808 Tj
--476 TJm
-(with) 17.7135 Tj
-[1 0 0 1 72 471.838] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -471.838] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 471.838 Td
-/F134_0 9.9626 Tf
-(BZ_NO_STDIO) 65.7532 Tj
-[1 0 0 1 137.753 471.838] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -137.753 -471.838] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-140.244 471.838 Td
-/F130_0 9.9626 Tf
-(set.) 13.5591 Tj
-[1 0 0 1 72 470.528] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.898] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -460.63] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 449.985 Td
-/F130_0 9.9626 Tf
-(F) 5.53921 Tj
-15 TJm
-(or) 8.29885 Tj
--250 TJm
-(a) 4.42339 Tj
--250 TJm
-(normal) 28.224 Tj
--250 TJm
-(compile,) 34.5901 Tj
--250 TJm
-(an) 9.40469 Tj
--250 TJm
-(assertion) 35.417 Tj
--250 TJm
-(f) 3.31755 Tj
-10 TJm
-(ailure) 22.6848 Tj
--250 TJm
-(yields) 23.8007 Tj
--250 TJm
-(the) 12.1743 Tj
--250 TJm
-(message:) 36.5229 Tj
-[1 0 0 1 72 447.828] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.898] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -437.93] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 428.131 Td
-/F130_0 9.9626 Tf
-(bzip2/libbzip2:) 60.3335 Tj
--310 TJm
-(internal) 30.4357 Tj
--250 TJm
-(error) 19.3573 Tj
--250 TJm
-(number) 30.4357 Tj
--250 TJm
-(N.) 9.68365 Tj
-[1 0 0 1 72 425.975] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.898] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -416.077] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 406.278 Td
-/F130_0 9.9626 Tf
-(This) 17.7135 Tj
--332 TJm
-(is) 6.64505 Tj
--331 TJm
-(a) 4.42339 Tj
--332 TJm
-(b) 4.9813 Tj
-20 TJm
-(ug) 9.9626 Tj
--332 TJm
-(in) 7.7509 Tj
--331 TJm
-(bzip2/libbzip2,) 60.0546 Tj
--352 TJm
-(1.0.5) 19.9252 Tj
--332 TJm
-(of) 8.29885 Tj
--332 TJm
-(10) 9.9626 Tj
--332 TJm
-(December) 40.9363 Tj
--331 TJm
-(2007.) 22.4159 Tj
--555 TJm
-(Please) 25.4544 Tj
--332 TJm
-(report) 23.7907 Tj
--332 TJm
-(it) 5.53921 Tj
--331 TJm
-(to) 7.7509 Tj
--332 TJm
-(me) 12.1743 Tj
--332 TJm
-(at:) 9.9626 Tj
--473 TJm
-(jse) 11.0684 Tj
-25 TJm
-(w) 7.193 Tj
-10 TJm
-(ard@bzip.or) 49.8429 Tj
-18 TJm
-(g.) 7.47195 Tj
--1110 TJm
-(If) 6.63509 Tj
--332 TJm
-(this) 14.396 Tj
-72 394.323 Td
-(happened) 38.1767 Tj
--297 TJm
-(when) 21.579 Tj
--298 TJm
-(you) 14.9439 Tj
--297 TJm
-(were) 19.3573 Tj
--297 TJm
-(using) 21.589 Tj
--297 TJm
-(some) 21.031 Tj
--298 TJm
-(program) 33.7533 Tj
--297 TJm
-(which) 24.3486 Tj
--297 TJm
-(uses) 17.1556 Tj
--297 TJm
-(libbzip2) 32.6574 Tj
--298 TJm
-(as) 8.29885 Tj
--297 TJm
-(a) 4.42339 Tj
--297 TJm
-(component,) 46.7644 Tj
--309 TJm
-(you) 14.9439 Tj
--298 TJm
-(should) 26.5703 Tj
--297 TJm
-(also) 16.0497 Tj
--297 TJm
-(report) 23.7907 Tj
--297 TJm
-(this) 14.396 Tj
--298 TJm
-(b) 4.9813 Tj
-20 TJm
-(ug) 9.9626 Tj
-72 382.368 Td
-(to) 7.7509 Tj
--264 TJm
-(the) 12.1743 Tj
--264 TJm
-(author\(s\)) 35.965 Tj
--264 TJm
-(of) 8.29885 Tj
--264 TJm
-(that) 14.9439 Tj
--264 TJm
-(program.) 36.2439 Tj
--703 TJm
-(Please) 25.4544 Tj
--264 TJm
-(mak) 17.1556 Tj
-10 TJm
-(e) 4.42339 Tj
--264 TJm
-(an) 9.40469 Tj
--264 TJm
-(ef) 7.74094 Tj
-25 TJm
-(fort) 14.386 Tj
--264 TJm
-(to) 7.7509 Tj
--264 TJm
-(report) 23.7907 Tj
--263 TJm
-(this) 14.396 Tj
--264 TJm
-(b) 4.9813 Tj
-20 TJm
-(ug;) 12.7322 Tj
--271 TJm
-(timely) 25.4644 Tj
--264 TJm
-(and) 14.386 Tj
--264 TJm
-(accurate) 33.1854 Tj
--264 TJm
-(b) 4.9813 Tj
-20 TJm
-(ug) 9.9626 Tj
--264 TJm
-(reports) 27.6661 Tj
--264 TJm
-(e) 4.42339 Tj
-25 TJm
-(v) 4.9813 Tj
-15 TJm
-(entually) 32.0995 Tj
-72 370.413 Td
-(lead) 16.5977 Tj
--250 TJm
-(to) 7.7509 Tj
--250 TJm
-(higher) 25.4544 Tj
--250 TJm
-(quality) 27.6761 Tj
--250 TJm
-(softw) 22.1369 Tj
-10 TJm
-(are.) 14.655 Tj
--620 TJm
-(Thanks.) 31.8205 Tj
--620 TJm
-(Julian) 23.8007 Tj
--250 TJm
-(Se) 9.9626 Tj
-25 TJm
-(w) 7.193 Tj
-10 TJm
-(ard,) 15.2129 Tj
--250 TJm
-(10) 9.9626 Tj
--250 TJm
-(December) 40.9363 Tj
--250 TJm
-(2007.) 22.4159 Tj
-[1 0 0 1 72 368.256] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.801] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.898] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -348.557] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 338.758 Td
-/F130_0 9.9626 Tf
-(where) 24.3386 Tj
-[1 0 0 1 98.8312 338.758] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -98.8312 -338.758] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-98.8312 338.758 Td
-/F134_0 9.9626 Tf
-(N) 5.97756 Tj
-[1 0 0 1 104.809 338.758] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -104.809 -338.758] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-107.302 338.758 Td
-/F130_0 9.9626 Tf
-(is) 6.64505 Tj
--250 TJm
-(some) 21.031 Tj
--250 TJm
-(error) 19.3573 Tj
--251 TJm
-(code) 18.8094 Tj
--250 TJm
-(number) 30.4357 Tj
-55 TJm
-(.) 2.49065 Tj
--621 TJm
-(If) 6.63509 Tj
-[1 0 0 1 230.81 338.758] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -230.81 -338.758] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-230.81 338.758 Td
-/F134_0 9.9626 Tf
-(N) 5.97756 Tj
--600 TJm
-(==) 11.9551 Tj
--600 TJm
-(1007) 23.9102 Tj
-[1 0 0 1 284.608 338.758] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -284.608 -338.758] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-284.608 338.758 Td
-/F130_0 9.9626 Tf
-(,) 2.49065 Tj
--250 TJm
-(it) 5.53921 Tj
--250 TJm
-(also) 16.0497 Tj
--251 TJm
-(prints) 22.6948 Tj
--250 TJm
-(some) 21.031 Tj
--250 TJm
-(e) 4.42339 Tj
-15 TJm
-(xtra) 15.4918 Tj
--250 TJm
-(te) 7.193 Tj
-15 TJm
-(xt) 7.7509 Tj
--250 TJm
-(advising) 33.7633 Tj
--251 TJm
-(the) 12.1743 Tj
--250 TJm
-(reader) 24.8866 Tj
--250 TJm
-(that) 14.9439 Tj
--250 TJm
-(unreliable) 39.8404 Tj
-72 326.803 Td
-(memory) 33.2053 Tj
--425 TJm
-(is) 6.64505 Tj
--424 TJm
-(often) 20.4731 Tj
--425 TJm
-(associated) 40.9463 Tj
--425 TJm
-(with) 17.7135 Tj
--424 TJm
-(internal) 30.4357 Tj
--425 TJm
-(error) 19.3573 Tj
--424 TJm
-(1007.) 22.4159 Tj
--834 TJm
-(\(This) 21.031 Tj
--425 TJm
-(is) 6.64505 Tj
--425 TJm
-(a) 4.42339 Tj
--424 TJm
-(frequently-observ) 70.8241 Tj
-15 TJm
-(ed-phenomenon) 64.189 Tj
--425 TJm
-(with) 17.7135 Tj
--425 TJm
-(v) 4.9813 Tj
-15 TJm
-(ersions) 28.224 Tj
-72 314.848 Td
-(1.0.0/1.0.1\).) 48.4282 Tj
-[1 0 0 1 72 313.065] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.898] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -303.167] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 292.995 Td
-/F134_0 9.9626 Tf
-(exit\(3\)) 41.8429 Tj
-[1 0 0 1 113.843 292.995] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -113.843 -292.995] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-116.334 292.995 Td
-/F130_0 9.9626 Tf
-(is) 6.64505 Tj
--250 TJm
-(then) 17.1556 Tj
--250 TJm
-(called.) 26.2813 Tj
-[1 0 0 1 72 291.899] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.8981] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -282.001] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 271.142 Td
-/F130_0 9.9626 Tf
-(F) 5.53921 Tj
-15 TJm
-(or) 8.29885 Tj
--250 TJm
-(a) 4.42339 Tj
-[1 0 0 1 95.0933 271.142] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -95.0933 -271.142] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-95.0933 271.142 Td
-/F134_0 9.9626 Tf
-(stdio) 29.8878 Tj
-[1 0 0 1 124.981 271.142] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -124.981 -271.142] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-124.981 271.142 Td
-/F130_0 9.9626 Tf
-(-free) 18.7994 Tj
--250 TJm
-(library) 26.5603 Tj
-65 TJm
-(,) 2.49065 Tj
--250 TJm
-(assertion) 35.417 Tj
--250 TJm
-(f) 3.31755 Tj
-10 TJm
-(ailures) 26.5603 Tj
--250 TJm
-(result) 22.1369 Tj
--250 TJm
-(in) 7.7509 Tj
--250 TJm
-(a) 4.42339 Tj
--250 TJm
-(call) 14.386 Tj
--250 TJm
-(to) 7.7509 Tj
--250 TJm
-(a) 4.42339 Tj
--250 TJm
-(function) 33.2053 Tj
--250 TJm
-(declared) 33.7433 Tj
--250 TJm
-(as:) 11.0684 Tj
-[1 0 0 1 72 268.985] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -24.9066] cm
-/DeviceRGB {} cs
-[0.94899 0.94899 0.976456] sc
-/DeviceRGB {} CS
-[0.94899 0.94899 0.976456] SC
-0 0 468 23.9103 re
-f
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 3.5866] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 20.3237] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 18 -8.3685] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -90 -259.62] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-90 259.62 Td
-/F134_0 9.9626 Tf
-(extern) 35.8654 Tj
--426 TJm
-(void) 23.9102 Tj
--426 TJm
-(bz_internal_error) 101.619 Tj
--426 TJm
-(\() 5.97756 Tj
--426 TJm
-(int) 17.9327 Tj
--426 TJm
-(errcode) 41.8429 Tj
--426 TJm
-(\);) 11.9551 Tj
-[1 0 0 1 72 244.078] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 468 3.5866] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -468 -13.4846] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -234.18] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 222.225 Td
-/F130_0 9.9626 Tf
-(The) 15.4918 Tj
--250 TJm
-(rele) 14.9339 Tj
-25 TJm
-(v) 4.9813 Tj
-25 TJm
-(ant) 12.1743 Tj
--250 TJm
-(code) 18.8094 Tj
--250 TJm
-(is) 6.64505 Tj
--250 TJm
-(passed) 26.5603 Tj
--250 TJm
-(as) 8.29885 Tj
--250 TJm
-(a) 4.42339 Tj
--250 TJm
-(parameter) 39.8305 Tj
-55 TJm
-(.) 2.49065 Tj
--620 TJm
-(Y) 7.193 Tj
-110 TJm
-(ou) 9.9626 Tj
--250 TJm
-(should) 26.5703 Tj
--250 TJm
-(supply) 26.5703 Tj
--250 TJm
-(such) 18.2614 Tj
--250 TJm
-(a) 4.42339 Tj
--250 TJm
-(function.) 35.696 Tj
-[1 0 0 1 72 220.068] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.898] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -210.17] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 200.372 Td
-/F130_0 9.9626 Tf
-(In) 8.29885 Tj
--294 TJm
-(either) 22.6848 Tj
--294 TJm
-(case,) 19.6363 Tj
--306 TJm
-(once) 18.8094 Tj
--294 TJm
-(an) 9.40469 Tj
--294 TJm
-(assertion) 35.417 Tj
--294 TJm
-(f) 3.31755 Tj
-10 TJm
-(ailure) 22.6848 Tj
--294 TJm
-(has) 13.2801 Tj
--295 TJm
-(occurred,) 37.3398 Tj
--305 TJm
-(an) 9.40469 Tj
-15 TJm
-(y) 4.9813 Tj
-[1 0 0 1 306.541 200.372] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -306.541 -200.372] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-306.541 200.372 Td
-/F134_0 9.9626 Tf
-(bz_stream) 53.798 Tj
-[1 0 0 1 360.339 200.372] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -360.339 -200.372] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-363.271 200.372 Td
-/F130_0 9.9626 Tf
-(records) 29.3199 Tj
--294 TJm
-(in) 7.7509 Tj
-40 TJm
-(v) 4.9813 Tj
-20 TJm
-(olv) 12.7322 Tj
-15 TJm
-(ed) 9.40469 Tj
--294 TJm
-(can) 13.8281 Tj
--295 TJm
-(be) 9.40469 Tj
--294 TJm
-(re) 7.74094 Tj
-15 TJm
-(g) 4.9813 Tj
-5 TJm
-(arded) 22.1269 Tj
--294 TJm
-(as) 8.29885 Tj
--294 TJm
-(in) 7.7509 Tj
-40 TJm
-(v) 4.9813 Tj
-25 TJm
-(alid.) 17.4346 Tj
-72 188.417 Td
-(Y) 7.193 Tj
-110 TJm
-(ou) 9.9626 Tj
--250 TJm
-(should) 26.5703 Tj
--250 TJm
-(not) 12.7322 Tj
--250 TJm
-(attempt) 29.8878 Tj
--250 TJm
-(to) 7.7509 Tj
--250 TJm
-(resume) 28.772 Tj
--250 TJm
-(normal) 28.224 Tj
--250 TJm
-(operation) 37.6287 Tj
--250 TJm
-(with) 17.7135 Tj
--250 TJm
-(them.) 22.4159 Tj
-[1 0 0 1 72 186.26] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.898] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -176.362] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 166.564 Td
-/F130_0 9.9626 Tf
-(Y) 7.193 Tj
-110 TJm
-(ou) 9.9626 Tj
--299 TJm
-(may) 17.1556 Tj
-65 TJm
-(,) 2.49065 Tj
--310 TJm
-(of) 8.29885 Tj
--299 TJm
-(course,) 28.493 Tj
--311 TJm
-(change) 28.2141 Tj
--298 TJm
-(critical) 27.6661 Tj
--299 TJm
-(error) 19.3573 Tj
--298 TJm
-(handling) 34.8691 Tj
--299 TJm
-(to) 7.7509 Tj
--298 TJm
-(suit) 14.396 Tj
--299 TJm
-(your) 18.2614 Tj
--298 TJm
-(needs.) 25.1755 Tj
--912 TJm
-(As) 11.0684 Tj
--298 TJm
-(I) 3.31755 Tj
--299 TJm
-(said) 16.0497 Tj
--298 TJm
-(abo) 14.386 Tj
-15 TJm
-(v) 4.9813 Tj
-15 TJm
-(e,) 6.91404 Tj
--311 TJm
-(critical) 27.6661 Tj
--299 TJm
-(errors) 23.2328 Tj
--298 TJm
-(indicate) 31.5416 Tj
--299 TJm
-(b) 4.9813 Tj
-20 TJm
-(ugs) 13.8381 Tj
-72 154.608 Td
-(in) 7.7509 Tj
--263 TJm
-(the) 12.1743 Tj
--263 TJm
-(library) 26.5603 Tj
--263 TJm
-(and) 14.386 Tj
--263 TJm
-(should) 26.5703 Tj
--263 TJm
-(not) 12.7322 Tj
--263 TJm
-(occur) 22.1269 Tj
-55 TJm
-(.) 2.49065 Tj
--697 TJm
-(All) 12.7322 Tj
--263 TJm
-("normal") 36.3535 Tj
--263 TJm
-(error) 19.3573 Tj
--263 TJm
-(situations) 38.1966 Tj
--263 TJm
-(are) 12.1643 Tj
--263 TJm
-(indicated) 36.5229 Tj
--263 TJm
-(via) 12.1743 Tj
--263 TJm
-(error) 19.3573 Tj
--263 TJm
-(return) 23.7907 Tj
--263 TJm
-(codes) 22.6848 Tj
--263 TJm
-(from) 19.3673 Tj
--263 TJm
-(functions,) 39.5714 Tj
-72 142.653 Td
-(and) 14.386 Tj
--250 TJm
-(can) 13.8281 Tj
--250 TJm
-(be) 9.40469 Tj
--250 TJm
-(reco) 17.1456 Tj
-15 TJm
-(v) 4.9813 Tj
-15 TJm
-(ered) 17.1456 Tj
--250 TJm
-(from.) 21.8579 Tj
-[1 0 0 1 72 142.554] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.898] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -132.656] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 107.965 Td
-/F122_0 20.6585 Tf
-(3.8.) 34.4584 Tj
--278 TJm
-(Making) 71.1685 Tj
--278 TJm
-(a) 11.4861 Tj
--278 TJm
-(Windo) 63.1117 Tj
-15 TJm
-(ws) 27.5584 Tj
--278 TJm
-(DLL) 40.1601 Tj
-[1 0 0 1 72 103.369] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.898] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -93.4708] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 86.112 Td
-/F130_0 9.9626 Tf
-(Ev) 11.0684 Tj
-15 TJm
-(erything) 33.2053 Tj
--328 TJm
-(related) 27.1082 Tj
--327 TJm
-(to) 7.7509 Tj
--328 TJm
-(W) 9.40469 Tj
-40 TJm
-(indo) 17.7135 Tj
-25 TJm
-(ws) 11.0684 Tj
--328 TJm
-(has) 13.2801 Tj
--327 TJm
-(been) 18.8094 Tj
--328 TJm
-(contrib) 28.224 Tj
-20 TJm
-(uted) 17.1556 Tj
--328 TJm
-(by) 9.9626 Tj
--327 TJm
-(Y) 7.193 Tj
-110 TJm
-(oshioka) 30.9936 Tj
--328 TJm
-(Tsuneo) 29.3299 Tj
--328 TJm
-(\() 3.31755 Tj
-[1 0 0 1 378.139 86.112] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -378.139 -86.112] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-378.139 86.112 Td
-/F134_0 9.9626 Tf
-(tsuneo@rr.iij4u.or.jp) 125.529 Tj
-[1 0 0 1 503.668 86.112] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -503.668 -86.112] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-503.668 86.112 Td
-/F130_0 9.9626 Tf
-(\),) 5.8082 Tj
--347 TJm
-(so) 8.85675 Tj
--328 TJm
-(you) 14.9439 Tj
-72 74.1568 Td
-(should) 26.5703 Tj
--250 TJm
-(send) 18.2614 Tj
--250 TJm
-(your) 18.2614 Tj
--250 TJm
-(queries) 28.772 Tj
--250 TJm
-(to) 7.7509 Tj
--250 TJm
-(him) 15.5018 Tj
--250 TJm
-(\(b) 8.29885 Tj
-20 TJm
-(ut) 7.7509 Tj
--250 TJm
-(perhaps) 30.9837 Tj
--250 TJm
-(Cc:) 13.8381 Tj
--310 TJm
-(me,) 14.6649 Tj
-[1 0 0 1 287.958 74.1568] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -287.958 -74.1568] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-287.958 74.1568 Td
-/F134_0 9.9626 Tf
-(jseward@bzip.org) 95.641 Tj
-[1 0 0 1 383.6 74.1568] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -383.6 -74.1568] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-383.6 74.1568 Td
-/F130_0 9.9626 Tf
-(\).) 5.8082 Tj
-[1 0 0 1 72 72] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -21.1482] cm
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-[1 0 0 1 1.8929 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 374.394 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 6.9738] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 40.5726 -6.7546] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -493.841 -51.071] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-534.414 51.071 Td
-/F130_0 9.9626 Tf
-(29) 9.9626 Tj
-[1 0 0 1 453.269 50.8518] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 93.5985 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 6.2765 0] cm
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-[1 0 0 1 -13.1436 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-Q
-showpage
-%%PageTrailer
-pdfEndPage
-%%Page: 33 33
-%%BeginPageSetup
-%%PageOrientation: Portrait
-pdfStartPage
-0 0 612 792 re W
-%%EndPageSetup
-[] 0 d
-1 i
-0 j
-0 J
-10 M
-1 w
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-false op
-false OP
-0 0 612 792 re
-W
-q
-[1 0 0 1 72 741.554] cm
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-[1 0 0 1 1.8929 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 14.4459] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 187.197 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 -8.9114] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 8.9114] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 76.4979 -6.7546] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -342.569 -749.245] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-419.067 749.245 Td
-/F130_0 9.9626 Tf
-(Programming) 54.7943 Tj
--250 TJm
-(with) 17.7135 Tj
-[1 0 0 1 496.556 749.245] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -496.556 -749.245] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-496.556 749.245 Td
-/F134_0 9.9626 Tf
-(libbzip2) 47.8205 Tj
-[1 0 0 1 544.376 749.245] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -278.305 -2.1568] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 280.796 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -472.974 -5.0363] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -0.4981] cm
-q
-[] 0 d
-0 J
-0.4981 w
-0 0.2491 m
-475.465 0.2491 l
-S
-Q
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 479.251 0] cm
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-[1 0 0 1 -13.1436 0] cm
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-[1 0 0 1 -468 -21.5542] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -720] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 710.037 Td
-/F130_0 9.9626 Tf
-(My) 13.8381 Tj
--367 TJm
-(v) 4.9813 Tj
-25 TJm
-(ague) 18.8094 Tj
--367 TJm
-(understanding) 56.4481 Tj
--367 TJm
-(of) 8.29885 Tj
--367 TJm
-(what) 19.3673 Tj
--368 TJm
-(to) 7.7509 Tj
--367 TJm
-(do) 9.9626 Tj
--367 TJm
-(is:) 9.41466 Tj
--544 TJm
-(using) 21.589 Tj
--367 TJm
-(V) 7.193 Tj
-60 TJm
-(isual) 18.8194 Tj
--367 TJm
-(C++) 17.8829 Tj
--367 TJm
-(5.0,) 14.9439 Tj
--397 TJm
-(open) 19.3673 Tj
--367 TJm
-(the) 12.1743 Tj
--367 TJm
-(project) 27.6661 Tj
--367 TJm
-(\002le) 12.7322 Tj
-[1 0 0 1 432.966 710.037] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -432.966 -710.037] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-432.966 710.037 Td
-/F134_0 9.9626 Tf
-(libbz2.dsp) 59.7756 Tj
-[1 0 0 1 492.742 710.037] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -492.742 -710.037] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-492.742 710.037 Td
-/F130_0 9.9626 Tf
-(,) 2.49065 Tj
--396 TJm
-(and) 14.386 Tj
--368 TJm
-(b) 4.9813 Tj
-20 TJm
-(uild.) 17.9925 Tj
-72 698.082 Td
-(That') 21.579 Tj
-55 TJm
-(s) 3.87545 Tj
--250 TJm
-(all.) 12.4533 Tj
-[1 0 0 1 72 697.983] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.9626] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -688.02] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 676.164 Td
-/F130_0 9.9626 Tf
-(If) 6.63509 Tj
--284 TJm
-(you) 14.9439 Tj
--284 TJm
-(can') 17.1456 Tj
-18 TJm
-(t) 2.7696 Tj
--285 TJm
-(open) 19.3673 Tj
--284 TJm
-(the) 12.1743 Tj
--284 TJm
-(project) 27.6661 Tj
--284 TJm
-(\002le) 12.7322 Tj
--284 TJm
-(for) 11.6164 Tj
--285 TJm
-(some) 21.031 Tj
--284 TJm
-(reason,) 28.493 Tj
--293 TJm
-(mak) 17.1556 Tj
-10 TJm
-(e) 4.42339 Tj
--284 TJm
-(a) 4.42339 Tj
--284 TJm
-(ne) 9.40469 Tj
-25 TJm
-(w) 7.193 Tj
--284 TJm
-(one,) 16.8766 Tj
--293 TJm
-(naming) 29.8878 Tj
--284 TJm
-(these) 20.4731 Tj
--284 TJm
-(\002les:) 19.3773 Tj
-[1 0 0 1 424.505 676.164] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -424.505 -676.164] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-424.505 676.164 Td
-/F134_0 9.9626 Tf
-(blocksort.c) 65.7532 Tj
-[1 0 0 1 490.259 676.164] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -490.259 -676.164] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-490.259 676.164 Td
-/F130_0 9.9626 Tf
-(,) 2.49065 Tj
-[1 0 0 1 495.666 676.164] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -495.666 -676.164] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-495.666 676.164 Td
-/F134_0 9.9626 Tf
-(bzlib.c) 41.8429 Tj
-[1 0 0 1 537.509 676.164] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -537.509 -676.164] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-537.509 676.164 Td
-/F130_0 9.9626 Tf
-(,) 2.49065 Tj
-[1 0 0 1 72 664.209] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -664.209] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 664.209 Td
-/F134_0 9.9626 Tf
-(compress.c) 59.7756 Tj
-[1 0 0 1 131.776 664.209] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -131.776 -664.209] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-131.776 664.209 Td
-/F130_0 9.9626 Tf
-(,) 2.49065 Tj
-[1 0 0 1 136.436 664.209] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -136.436 -664.209] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-136.436 664.209 Td
-/F134_0 9.9626 Tf
-(crctable.c) 59.7756 Tj
-[1 0 0 1 196.211 664.209] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -196.211 -664.209] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-196.211 664.209 Td
-/F130_0 9.9626 Tf
-(,) 2.49065 Tj
-[1 0 0 1 200.871 664.209] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -200.871 -664.209] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-200.871 664.209 Td
-/F134_0 9.9626 Tf
-(decompress.c) 71.7307 Tj
-[1 0 0 1 272.602 664.209] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -272.602 -664.209] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-272.602 664.209 Td
-/F130_0 9.9626 Tf
-(,) 2.49065 Tj
-[1 0 0 1 277.262 664.209] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -277.262 -664.209] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-277.262 664.209 Td
-/F134_0 9.9626 Tf
-(huffman.c) 53.798 Tj
-[1 0 0 1 331.06 664.209] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -331.06 -664.209] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-331.06 664.209 Td
-/F130_0 9.9626 Tf
-(,) 2.49065 Tj
-[1 0 0 1 335.72 664.209] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -335.72 -664.209] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-335.72 664.209 Td
-/F134_0 9.9626 Tf
-(randtable.c) 65.7532 Tj
-[1 0 0 1 401.473 664.209] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -401.473 -664.209] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-403.562 664.209 Td
-/F130_0 9.9626 Tf
-(and) 14.386 Tj
-[1 0 0 1 420.037 664.209] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -420.037 -664.209] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-420.037 664.209 Td
-/F134_0 9.9626 Tf
-(libbz2.def) 59.7756 Tj
-[1 0 0 1 479.812 664.209] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -479.812 -664.209] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-479.812 664.209 Td
-/F130_0 9.9626 Tf
-(.) 2.49065 Tj
--593 TJm
-(Y) 7.193 Tj
-110 TJm
-(ou) 9.9626 Tj
--210 TJm
-(will) 15.5018 Tj
--209 TJm
-(also) 16.0497 Tj
-72 652.254 Td
-(need) 18.8094 Tj
--250 TJm
-(to) 7.7509 Tj
--250 TJm
-(name) 21.579 Tj
--250 TJm
-(the) 12.1743 Tj
--250 TJm
-(header) 26.5503 Tj
--250 TJm
-(\002les) 16.6077 Tj
-[1 0 0 1 190.415 652.254] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -190.415 -652.254] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-190.415 652.254 Td
-/F134_0 9.9626 Tf
-(bzlib.h) 41.8429 Tj
-[1 0 0 1 232.258 652.254] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -232.258 -652.254] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-234.748 652.254 Td
-/F130_0 9.9626 Tf
-(and) 14.386 Tj
-[1 0 0 1 251.625 652.254] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -251.625 -652.254] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-251.625 652.254 Td
-/F134_0 9.9626 Tf
-(bzlib_private.h) 89.6634 Tj
-[1 0 0 1 341.289 652.254] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -341.289 -652.254] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-341.289 652.254 Td
-/F130_0 9.9626 Tf
-(.) 2.49065 Tj
-[1 0 0 1 72 650.72] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.9627] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -640.757] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 630.336 Td
-/F130_0 9.9626 Tf
-(If) 6.63509 Tj
--250 TJm
-(you) 14.9439 Tj
--250 TJm
-(don') 18.2614 Tj
-18 TJm
-(t) 2.7696 Tj
--250 TJm
-(use) 13.2801 Tj
--250 TJm
-(VC++,) 27.5665 Tj
--250 TJm
-(you) 14.9439 Tj
--250 TJm
-(may) 17.1556 Tj
--250 TJm
-(need) 18.8094 Tj
--250 TJm
-(to) 7.7509 Tj
--250 TJm
-(de\002ne) 24.3486 Tj
--250 TJm
-(the) 12.1743 Tj
--250 TJm
-(proprocessor) 51.4568 Tj
--250 TJm
-(symbol) 29.3399 Tj
-[1 0 0 1 363.634 630.336] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -363.634 -630.336] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-363.634 630.336 Td
-/F134_0 9.9626 Tf
-(_WIN32) 35.8654 Tj
-[1 0 0 1 399.5 630.336] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -399.5 -630.336] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-399.5 630.336 Td
-/F130_0 9.9626 Tf
-(.) 2.49065 Tj
-[1 0 0 1 72 628.179] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.9626] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -618.217] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 608.418 Td
-/F130_0 9.9626 Tf
-(Finally) 28.234 Tj
-65 TJm
-(,) 2.49065 Tj
-[1 0 0 1 104.568 608.418] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -104.568 -608.418] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-104.568 608.418 Td
-/F134_0 9.9626 Tf
-(dlltest.c) 53.798 Tj
-[1 0 0 1 158.366 608.418] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -158.366 -608.418] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-160.856 608.418 Td
-/F130_0 9.9626 Tf
-(is) 6.64505 Tj
--250 TJm
-(a) 4.42339 Tj
--250 TJm
-(sample) 28.224 Tj
--250 TJm
-(program) 33.7533 Tj
--250 TJm
-(using) 21.589 Tj
--250 TJm
-(the) 12.1743 Tj
--250 TJm
-(DLL.) 21.8579 Tj
--500 TJm
-(It) 6.08715 Tj
--250 TJm
-(has) 13.2801 Tj
--250 TJm
-(a) 4.42339 Tj
--250 TJm
-(project) 27.6661 Tj
--250 TJm
-(\002le,) 15.2229 Tj
-[1 0 0 1 388.58 608.418] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -388.58 -608.418] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-388.58 608.418 Td
-/F134_0 9.9626 Tf
-(dlltest.dsp) 65.7532 Tj
-[1 0 0 1 454.333 608.418] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -454.333 -608.418] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-454.333 608.418 Td
-/F130_0 9.9626 Tf
-(.) 2.49065 Tj
-[1 0 0 1 72 606.262] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.9627] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -596.299] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 586.501 Td
-/F130_0 9.9626 Tf
-(If) 6.63509 Tj
--250 TJm
-(you) 14.9439 Tj
--250 TJm
-(just) 14.396 Tj
--250 TJm
-(w) 7.193 Tj
-10 TJm
-(ant) 12.1743 Tj
--250 TJm
-(a) 4.42339 Tj
--250 TJm
-(mak) 17.1556 Tj
-10 TJm
-(e\002le) 17.1556 Tj
--250 TJm
-(for) 11.6164 Tj
--250 TJm
-(V) 7.193 Tj
-60 TJm
-(isual) 18.8194 Tj
--250 TJm
-(C,) 9.1357 Tj
--250 TJm
-(ha) 9.40469 Tj
-20 TJm
-(v) 4.9813 Tj
-15 TJm
-(e) 4.42339 Tj
--250 TJm
-(a) 4.42339 Tj
--250 TJm
-(look) 17.7135 Tj
--250 TJm
-(at) 7.193 Tj
-[1 0 0 1 292.212 586.501] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -292.212 -586.501] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-292.212 586.501 Td
-/F134_0 9.9626 Tf
-(makefile.msc) 71.7307 Tj
-[1 0 0 1 363.943 586.501] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -363.943 -586.501] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-363.943 586.501 Td
-/F130_0 9.9626 Tf
-(.) 2.49065 Tj
-[1 0 0 1 72 584.344] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.9627] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -574.381] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 564.583 Td
-/F130_0 9.9626 Tf
-(Be) 11.0684 Tj
--291 TJm
-(a) 4.42339 Tj
-15 TJm
-(w) 7.193 Tj
-10 TJm
-(are) 12.1643 Tj
--291 TJm
-(that) 14.9439 Tj
--291 TJm
-(if) 6.08715 Tj
--291 TJm
-(you) 14.9439 Tj
--291 TJm
-(compile) 32.0995 Tj
-[1 0 0 1 192.069 564.583] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -192.069 -564.583] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-192.069 564.583 Td
-/F134_0 9.9626 Tf
-(bzip2) 29.8878 Tj
-[1 0 0 1 221.958 564.583] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -221.958 -564.583] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-224.857 564.583 Td
-/F130_0 9.9626 Tf
-(itself) 19.9252 Tj
--291 TJm
-(on) 9.9626 Tj
--291 TJm
-(W) 9.40469 Tj
-40 TJm
-(in32,) 20.2042 Tj
--301 TJm
-(you) 14.9439 Tj
--291 TJm
-(must) 19.3773 Tj
--291 TJm
-(set) 11.0684 Tj
-[1 0 0 1 346.841 564.583] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -346.841 -564.583] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-346.841 564.583 Td
-/F134_0 9.9626 Tf
-(BZ_UNIX) 41.8429 Tj
-[1 0 0 1 388.685 564.583] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -388.685 -564.583] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-391.583 564.583 Td
-/F130_0 9.9626 Tf
-(to) 7.7509 Tj
--291 TJm
-(0) 4.9813 Tj
--291 TJm
-(and) 14.386 Tj
-[1 0 0 1 427.399 564.583] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -427.399 -564.583] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-427.399 564.583 Td
-/F134_0 9.9626 Tf
-(BZ_LCCWIN32) 65.7532 Tj
-[1 0 0 1 493.153 564.583] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -493.153 -564.583] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-496.052 564.583 Td
-/F130_0 9.9626 Tf
-(to) 7.7509 Tj
--291 TJm
-(1,) 7.47195 Tj
--301 TJm
-(in) 7.7509 Tj
--291 TJm
-(the) 12.1743 Tj
-72 552.628 Td
-(\002le) 12.7322 Tj
-[1 0 0 1 87.2227 552.628] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -87.2227 -552.628] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-87.2227 552.628 Td
-/F134_0 9.9626 Tf
-(bzip2.c) 41.8429 Tj
-[1 0 0 1 129.066 552.628] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -129.066 -552.628] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-129.066 552.628 Td
-/F130_0 9.9626 Tf
-(,) 2.49065 Tj
--250 TJm
-(before) 25.4445 Tj
--250 TJm
-(compiling.) 42.899 Tj
--310 TJm
-(Otherwise) 40.9463 Tj
--250 TJm
-(the) 12.1743 Tj
--250 TJm
-(resulting) 34.8691 Tj
--250 TJm
-(binary) 25.4544 Tj
--250 TJm
-(w) 7.193 Tj
-10 TJm
-(on') 13.2801 Tj
-18 TJm
-(t) 2.7696 Tj
--250 TJm
-(w) 7.193 Tj
-10 TJm
-(ork) 13.2801 Tj
--250 TJm
-(correctly) 35.4071 Tj
-65 TJm
-(.) 2.49065 Tj
-[1 0 0 1 72 550.471] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.9626] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -540.508] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 530.71 Td
-/F130_0 9.9626 Tf
-(I) 3.31755 Tj
--250 TJm
-(ha) 9.40469 Tj
-20 TJm
-(v) 4.9813 Tj
-15 TJm
-(en') 12.7222 Tj
-18 TJm
-(t) 2.7696 Tj
--250 TJm
-(tried) 18.2614 Tj
--250 TJm
-(an) 9.40469 Tj
-15 TJm
-(y) 4.9813 Tj
--250 TJm
-(of) 8.29885 Tj
--250 TJm
-(this) 14.396 Tj
--250 TJm
-(stuf) 14.9439 Tj
-25 TJm
-(f) 3.31755 Tj
--250 TJm
-(myself,) 29.6088 Tj
--250 TJm
-(b) 4.9813 Tj
-20 TJm
-(ut) 7.7509 Tj
--250 TJm
-(it) 5.53921 Tj
--250 TJm
-(all) 9.9626 Tj
--250 TJm
-(looks) 21.589 Tj
--250 TJm
-(plausible.) 38.4656 Tj
-[1 0 0 1 72 528.553] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-[1 0 0 1 0 -477.701] cm
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-[1 0 0 1 1.8929 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 374.394 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 6.8541] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 40.5726 -6.7545] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -493.841 -50.9514] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-534.414 50.9514 Td
-/F130_0 9.9626 Tf
-(30) 9.9626 Tj
-[1 0 0 1 453.269 50.8518] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 93.5985 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 6.2765 0] cm
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-[1 0 0 1 -13.1436 0] cm
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-Q
-showpage
-%%PageTrailer
-pdfEndPage
-%%Page: 34 34
-%%BeginPageSetup
-%%PageOrientation: Portrait
-pdfStartPage
-0 0 612 792 re W
-%%EndPageSetup
-[] 0 d
-1 i
-0 j
-0 J
-10 M
-1 w
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-false op
-false OP
-0 0 612 792 re
-W
-q
-[1 0 0 1 72 741.554] cm
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-[1 0 0 1 1.8929 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 14.4459] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 187.197 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 140.398 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -140.398 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 280.796 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -472.974 -13.9477] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -0.4981] cm
-q
-[] 0 d
-0 J
-0.4981 w
-0 0.2491 m
-475.465 0.2491 l
-S
-Q
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 479.251 0] cm
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-[1 0 0 1 -13.1436 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -468 -21.5542] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -720] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 701.916 Td
-/F122_0 24.7902 Tf
-(4.) 20.675 Tj
--278 TJm
-(Miscellanea) 139.172 Tj
-[1 0 0 1 72 701.606] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-[1 0 0 1 0 -9.1347] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -14.1161] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -678.355] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 658.006 Td
-/F122_0 17.2154 Tf
-(T) 10.5186 Tj
-80 TJm
-(ab) 20.0904 Tj
-10 TJm
-(le) 14.3576 Tj
--278 TJm
-(of) 16.2513 Tj
--278 TJm
-(Contents) 74.5943 Tj
-[1 0 0 1 72 649.183] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -11.7401] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -637.443] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 637.443 Td
-/F130_0 9.9626 Tf
-(4.1.) 14.9439 Tj
--310 TJm
-(Limitations) 45.9475 Tj
--250 TJm
-(of) 8.29885 Tj
--250 TJm
-(the) 12.1743 Tj
--250 TJm
-(compressed) 47.0334 Tj
--250 TJm
-(\002le) 12.7322 Tj
--250 TJm
-(format) 26.5603 Tj
-[1 0 0 1 255.231 637.443] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4906 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -260.212 -637.443] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-269.154 637.443 Td
-/F147_0 9.9626 Tf
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
-[1 0 0 1 506.127 637.443] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -506.127 -637.443] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-506.127 637.443 Td
-/F130_0 9.9626 Tf
-(31) 9.9626 Tj
-[1 0 0 1 516.09 637.443] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -444.09 -2.1568] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.7984] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -625.488] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 625.488 Td
-/F130_0 9.9626 Tf
-(4.2.) 14.9439 Tj
--310 TJm
-(Portability) 42.0721 Tj
--250 TJm
-(issues) 23.8007 Tj
-[1 0 0 1 158.395 625.488] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4906 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -163.376 -625.488] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-172.03 625.488 Td
-/F147_0 9.9626 Tf
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
-[1 0 0 1 506.127 625.488] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -506.127 -625.488] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-506.127 625.488 Td
-/F130_0 9.9626 Tf
-(32) 9.9626 Tj
-[1 0 0 1 516.09 625.488] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -444.09 -2.1568] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.7984] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -613.533] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 613.533 Td
-/F130_0 9.9626 Tf
-(4.3.) 14.9439 Tj
--310 TJm
-(Reporting) 39.8504 Tj
--250 TJm
-(b) 4.9813 Tj
-20 TJm
-(ugs) 13.8381 Tj
-[1 0 0 1 150.993 613.533] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4906 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -155.975 -613.533] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-166.115 613.533 Td
-/F147_0 9.9626 Tf
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
-[1 0 0 1 506.127 613.533] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -506.127 -613.533] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-506.127 613.533 Td
-/F130_0 9.9626 Tf
-(32) 9.9626 Tj
-[1 0 0 1 516.09 613.533] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -444.09 -2.1568] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.7983] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -601.578] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 601.578 Td
-/F130_0 9.9626 Tf
-(4.4.) 14.9439 Tj
--310 TJm
-(Did) 14.9439 Tj
--250 TJm
-(you) 14.9439 Tj
--250 TJm
-(get) 12.1743 Tj
--250 TJm
-(the) 12.1743 Tj
--250 TJm
-(right) 18.8194 Tj
--250 TJm
-(package?) 37.0609 Tj
-[1 0 0 1 212.602 601.578] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 3.0884 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 3.0884 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -218.778 -601.578] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-229.109 601.578 Td
-/F147_0 9.9626 Tf
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
-[1 0 0 1 506.127 601.578] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -506.127 -601.578] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-506.127 601.578 Td
-/F130_0 9.9626 Tf
-(33) 9.9626 Tj
-[1 0 0 1 516.09 601.578] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -444.09 -2.1568] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.7984] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -589.623] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 589.623 Td
-/F130_0 9.9626 Tf
-(4.5.) 14.9439 Tj
--310 TJm
-(Further) 29.3299 Tj
--250 TJm
-(Reading) 33.2053 Tj
-[1 0 0 1 155.058 589.623] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4906 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -160.039 -589.623] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-170.361 589.623 Td
-/F147_0 9.9626 Tf
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
--166 TJm
-(:) 2.7696 Tj
--167 TJm
-(:) 2.7696 Tj
-[1 0 0 1 506.127 589.623] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -506.127 -589.623] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-506.127 589.623 Td
-/F130_0 9.9626 Tf
-(34) 9.9626 Tj
-[1 0 0 1 516.09 589.623] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -444.09 -2.1568] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.1348] cm
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-[1 0 0 1 0 -9.6315] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -568.7] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 558.901 Td
-/F130_0 9.9626 Tf
-(These) 23.7907 Tj
--250 TJm
-(are) 12.1643 Tj
--250 TJm
-(just) 14.396 Tj
--250 TJm
-(some) 21.031 Tj
--250 TJm
-(random) 30.4357 Tj
--250 TJm
-(thoughts) 34.3212 Tj
--250 TJm
-(of) 8.29885 Tj
--250 TJm
-(mine.) 22.4159 Tj
--620 TJm
-(Y) 7.193 Tj
-110 TJm
-(our) 13.2801 Tj
--250 TJm
-(mileage) 31.5416 Tj
--250 TJm
-(may) 17.1556 Tj
--250 TJm
-(v) 4.9813 Tj
-25 TJm
-(ary) 12.7222 Tj
-65 TJm
-(.) 2.49065 Tj
-[1 0 0 1 72 556.744] cm
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.6315] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -547.113] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 524.48 Td
-/F122_0 20.6585 Tf
-(4.1.) 34.4584 Tj
--278 TJm
-(Limitations) 110.192 Tj
--278 TJm
-(of) 19.5016 Tj
--278 TJm
-(the) 30.9877 Tj
--278 TJm
-(compressed) 121.699 Tj
--278 TJm
-(\002le) 29.8515 Tj
--278 TJm
-(f) 6.87928 Tj
-20 TJm
-(ormat) 57.3893 Tj
-[1 0 0 1 72 520.203] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.6315] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -510.572] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 502.893 Td
-/F134_0 9.9626 Tf
-(bzip2-1.0.X) 65.7532 Tj
-[1 0 0 1 137.753 502.893] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -137.753 -502.893] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-137.753 502.893 Td
-/F130_0 9.9626 Tf
-(,) 2.49065 Tj
-[1 0 0 1 143.405 502.893] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -143.405 -502.893] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-143.405 502.893 Td
-/F134_0 9.9626 Tf
-(0.9.5) 29.8878 Tj
-[1 0 0 1 173.293 502.893] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -173.293 -502.893] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-176.453 502.893 Td
-/F130_0 9.9626 Tf
-(and) 14.386 Tj
-[1 0 0 1 194 502.893] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -194 -502.893] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-194 502.893 Td
-/F134_0 9.9626 Tf
-(0.9.0) 29.8878 Tj
-[1 0 0 1 223.888 502.893] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -223.888 -502.893] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-227.048 502.893 Td
-/F130_0 9.9626 Tf
-(use) 13.2801 Tj
--317 TJm
-(e) 4.42339 Tj
-15 TJm
-(xactly) 24.3486 Tj
--317 TJm
-(the) 12.1743 Tj
--318 TJm
-(same) 20.4731 Tj
--317 TJm
-(\002le) 12.7322 Tj
--317 TJm
-(format) 26.5603 Tj
--317 TJm
-(as) 8.29885 Tj
--318 TJm
-(the) 12.1743 Tj
--317 TJm
-(original) 30.9936 Tj
--317 TJm
-(v) 4.9813 Tj
-15 TJm
-(ersion,) 26.8392 Tj
-[1 0 0 1 455.801 502.893] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -455.801 -502.893] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-455.801 502.893 Td
-/F134_0 9.9626 Tf
-(bzip2-0.1) 53.798 Tj
-[1 0 0 1 509.599 502.893] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -509.599 -502.893] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-509.599 502.893 Td
-/F130_0 9.9626 Tf
-(.) 2.49065 Tj
--1023 TJm
-(This) 17.7135 Tj
-72 490.938 Td
-(decision) 33.2053 Tj
--222 TJm
-(w) 7.193 Tj
-10 TJm
-(as) 8.29885 Tj
--222 TJm
-(made) 21.579 Tj
--222 TJm
-(in) 7.7509 Tj
--221 TJm
-(the) 12.1743 Tj
--222 TJm
-(interests) 33.2053 Tj
--222 TJm
-(of) 8.29885 Tj
--222 TJm
-(stability) 32.1095 Tj
-65 TJm
-(.) 2.49065 Tj
--601 TJm
-(Creating) 34.3112 Tj
--222 TJm
-(yet) 12.1743 Tj
--222 TJm
-(another) 29.8778 Tj
--222 TJm
-(incompatible) 52.0247 Tj
--221 TJm
-(compressed) 47.0334 Tj
--222 TJm
-(\002le) 12.7322 Tj
--222 TJm
-(format) 26.5603 Tj
--222 TJm
-(w) 7.193 Tj
-10 TJm
-(ould) 17.7135 Tj
--222 TJm
-(create) 23.7807 Tj
-72 478.983 Td
-(further) 27.1082 Tj
--250 TJm
-(confusion) 39.2925 Tj
--250 TJm
-(and) 14.386 Tj
--250 TJm
-(disruption) 40.4083 Tj
--250 TJm
-(for) 11.6164 Tj
--250 TJm
-(users.) 22.9638 Tj
-[1 0 0 1 72 476.826] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.6315] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -467.194] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 457.396 Td
-/F130_0 9.9626 Tf
-(Ne) 11.6164 Tj
-25 TJm
-(v) 4.9813 Tj
-15 TJm
-(ertheless,) 37.3498 Tj
--234 TJm
-(this) 14.396 Tj
--229 TJm
-(is) 6.64505 Tj
--230 TJm
-(not) 12.7322 Tj
--229 TJm
-(a) 4.42339 Tj
--230 TJm
-(painless) 32.0995 Tj
--229 TJm
-(decision.) 35.696 Tj
--606 TJm
-(De) 11.6164 Tj
-25 TJm
-(v) 4.9813 Tj
-15 TJm
-(elopment) 37.0808 Tj
--230 TJm
-(w) 7.193 Tj
-10 TJm
-(ork) 13.2801 Tj
--230 TJm
-(since) 20.4731 Tj
--229 TJm
-(the) 12.1743 Tj
--230 TJm
-(release) 27.6562 Tj
--229 TJm
-(of) 8.29885 Tj
-[1 0 0 1 407.317 457.396] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -407.317 -457.396] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-407.317 457.396 Td
-/F134_0 9.9626 Tf
-(bzip2-0.1) 53.798 Tj
-[1 0 0 1 461.115 457.396] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -461.115 -457.396] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-463.402 457.396 Td
-/F130_0 9.9626 Tf
-(in) 7.7509 Tj
--230 TJm
-(August) 28.782 Tj
--229 TJm
-(1997) 19.9252 Tj
--230 TJm
-(has) 13.2801 Tj
-72 445.441 Td
-(sho) 13.8381 Tj
-25 TJm
-(wn) 12.1743 Tj
--226 TJm
-(comple) 29.3299 Tj
-15 TJm
-(xities) 21.589 Tj
--226 TJm
-(in) 7.7509 Tj
--225 TJm
-(the) 12.1743 Tj
--226 TJm
-(\002le) 12.7322 Tj
--226 TJm
-(format) 26.5603 Tj
--226 TJm
-(which) 24.3486 Tj
--226 TJm
-(slo) 11.6264 Tj
-25 TJm
-(w) 7.193 Tj
--225 TJm
-(do) 9.9626 Tj
-25 TJm
-(wn) 12.1743 Tj
--226 TJm
-(decompression) 59.7656 Tj
--226 TJm
-(and,) 16.8766 Tj
--231 TJm
-(in) 7.7509 Tj
--226 TJm
-(retrospect,) 41.7732 Tj
--230 TJm
-(are) 12.1643 Tj
--226 TJm
-(unnecessary) 48.6872 Tj
-65 TJm
-(.) 2.49065 Tj
--604 TJm
-(These) 23.7907 Tj
--226 TJm
-(are:) 14.9339 Tj
-[1 0 0 1 72 443.284] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -29.0613] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 6.9739 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -78.9739 -414.222] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-78.9739 414.222 Td
-/F130_0 9.9626 Tf
-(\225) 3.48691 Tj
-[1 0 0 1 82.4608 414.222] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 1.9925 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -86.944 -414.222] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-86.944 414.222 Td
-/F130_0 9.9626 Tf
-(The) 15.4918 Tj
--265 TJm
-(run-length) 41.5042 Tj
--266 TJm
-(encoder) 31.5316 Tj
-40 TJm
-(,) 2.49065 Tj
--269 TJm
-(which) 24.3486 Tj
--265 TJm
-(is) 6.64505 Tj
--265 TJm
-(the) 12.1743 Tj
--266 TJm
-(\002rst) 15.5018 Tj
--265 TJm
-(of) 8.29885 Tj
--265 TJm
-(the) 12.1743 Tj
--266 TJm
-(compression) 50.3609 Tj
--265 TJm
-(transformations,) 65.0259 Tj
--269 TJm
-(is) 6.64505 Tj
--265 TJm
-(entirely) 30.4357 Tj
--266 TJm
-(irrele) 21.0211 Tj
-25 TJm
-(v) 4.9813 Tj
-25 TJm
-(ant.) 14.6649 Tj
--711 TJm
-(The) 15.4918 Tj
--266 TJm
-(original) 30.9936 Tj
-86.944 402.267 Td
-(purpose) 31.5416 Tj
--301 TJm
-(w) 7.193 Tj
-10 TJm
-(as) 8.29885 Tj
--301 TJm
-(to) 7.7509 Tj
--301 TJm
-(protect) 27.6661 Tj
--301 TJm
-(the) 12.1743 Tj
--301 TJm
-(sorting) 27.6761 Tj
--301 TJm
-(algorithm) 38.7446 Tj
--301 TJm
-(from) 19.3673 Tj
--301 TJm
-(the) 12.1743 Tj
--301 TJm
-(v) 4.9813 Tj
-15 TJm
-(ery) 12.7222 Tj
--301 TJm
-(w) 7.193 Tj
-10 TJm
-(orst) 14.9439 Tj
--301 TJm
-(case) 17.1456 Tj
--301 TJm
-(input:) 23.2527 Tj
--412 TJm
-(a) 4.42339 Tj
--301 TJm
-(string) 22.6948 Tj
--301 TJm
-(of) 8.29885 Tj
--301 TJm
-(repeated) 33.7433 Tj
--301 TJm
-(symbols.) 35.706 Tj
--927 TJm
-(But) 14.396 Tj
-86.944 390.312 Td
-(algorithm) 38.7446 Tj
--274 TJm
-(steps) 19.9252 Tj
--275 TJm
-(Q6a) 16.5977 Tj
--274 TJm
-(and) 14.386 Tj
--274 TJm
-(Q6b) 17.1556 Tj
--275 TJm
-(in) 7.7509 Tj
--274 TJm
-(the) 12.1743 Tj
--274 TJm
-(original) 30.9936 Tj
--275 TJm
-(Burro) 23.2427 Tj
-25 TJm
-(ws-Wheel) 40.3884 Tj
-1 TJm
-(er) 7.74094 Tj
--275 TJm
-(technical) 35.965 Tj
--274 TJm
-(report) 23.7907 Tj
--274 TJm
-(\(SRC-124\)) 43.7259 Tj
--275 TJm
-(sho) 13.8381 Tj
-25 TJm
-(w) 7.193 Tj
--274 TJm
-(ho) 9.9626 Tj
-25 TJm
-(w) 7.193 Tj
--274 TJm
-(repeats) 28.2141 Tj
--275 TJm
-(can) 13.8281 Tj
-86.944 378.357 Td
-(be) 9.40469 Tj
--250 TJm
-(handled) 31.5416 Tj
--250 TJm
-(without) 30.4457 Tj
--250 TJm
-(dif) 11.0684 Tj
-25 TJm
-(\002culty) 25.4644 Tj
--250 TJm
-(in) 7.7509 Tj
--250 TJm
-(block) 22.1369 Tj
--250 TJm
-(sorting.) 30.1668 Tj
-[1 0 0 1 269.617 378.357] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -197.617 -21.5867] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 6.9739 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -78.9739 -356.77] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-78.9739 356.77 Td
-/F130_0 9.9626 Tf
-(\225) 3.48691 Tj
-[1 0 0 1 82.4608 356.77] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 1.9925 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -86.944 -356.77] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-86.944 356.77 Td
-/F130_0 9.9626 Tf
-(The) 15.4918 Tj
--293 TJm
-(randomisation) 57.006 Tj
--293 TJm
-(mechanism) 45.3796 Tj
--293 TJm
-(doesn') 26.5603 Tj
-18 TJm
-(t) 2.7696 Tj
--294 TJm
-(really) 22.6848 Tj
--293 TJm
-(need) 18.8094 Tj
--293 TJm
-(to) 7.7509 Tj
--293 TJm
-(be) 9.40469 Tj
--293 TJm
-(there.) 22.4059 Tj
--879 TJm
-(Udi) 14.9439 Tj
--294 TJm
-(Manber) 30.9837 Tj
--293 TJm
-(and) 14.386 Tj
--293 TJm
-(Gene) 21.0211 Tj
--293 TJm
-(Myers) 25.4544 Tj
--293 TJm
-(published) 38.7446 Tj
--294 TJm
-(a) 4.42339 Tj
--293 TJm
-(suf) 12.1743 Tj
-25 TJm
-(\002x) 10.5205 Tj
-86.944 344.815 Td
-(array) 20.4632 Tj
--238 TJm
-(construction) 49.2551 Tj
--239 TJm
-(algorithm) 38.7446 Tj
--238 TJm
-(a) 4.42339 Tj
--238 TJm
-(fe) 7.74094 Tj
-25 TJm
-(w) 7.193 Tj
--239 TJm
-(years) 21.0211 Tj
--238 TJm
-(back,) 21.3 Tj
--241 TJm
-(which) 24.3486 Tj
--238 TJm
-(can) 13.8281 Tj
--238 TJm
-(be) 9.40469 Tj
--239 TJm
-(emplo) 24.9065 Tj
-10 TJm
-(yed) 14.386 Tj
--238 TJm
-(to) 7.7509 Tj
--238 TJm
-(sort) 14.9439 Tj
--239 TJm
-(an) 9.40469 Tj
-15 TJm
-(y) 4.9813 Tj
--238 TJm
-(block,) 24.6275 Tj
--241 TJm
-(no) 9.9626 Tj
--238 TJm
-(matter) 25.4544 Tj
--238 TJm
-(ho) 9.9626 Tj
-25 TJm
-(w) 7.193 Tj
--239 TJm
-(repetiti) 28.224 Tj
-25 TJm
-(v) 4.9813 Tj
-15 TJm
-(e,) 6.91404 Tj
-86.944 332.86 Td
-(in) 7.7509 Tj
--229 TJm
-(O\(N) 17.7035 Tj
--230 TJm
-(log) 12.7322 Tj
--229 TJm
-(N\)) 10.5105 Tj
--230 TJm
-(time.) 20.2042 Tj
--606 TJm
-(Subsequent) 45.9375 Tj
--230 TJm
-(w) 7.193 Tj
-10 TJm
-(ork) 13.2801 Tj
--229 TJm
-(by) 9.9626 Tj
--230 TJm
-(K) 7.193 Tj
-15 TJm
-(unihik) 25.4644 Tj
-10 TJm
-(o) 4.9813 Tj
--229 TJm
-(Sadakane) 38.1767 Tj
--229 TJm
-(has) 13.2801 Tj
--230 TJm
-(produced) 37.0708 Tj
--229 TJm
-(a) 4.42339 Tj
--230 TJm
-(deri) 15.4918 Tj
-25 TJm
-(v) 4.9813 Tj
-25 TJm
-(ati) 9.9626 Tj
-25 TJm
-(v) 4.9813 Tj
-15 TJm
-(e) 4.42339 Tj
--229 TJm
-(O\(N) 17.7035 Tj
--230 TJm
-(\(log) 16.0497 Tj
--229 TJm
-(N\)^2\)) 23.4818 Tj
--230 TJm
-(algorithm) 38.7446 Tj
-86.944 320.905 Td
-(which) 24.3486 Tj
--250 TJm
-(usually) 28.782 Tj
--250 TJm
-(outperforms) 48.6972 Tj
--250 TJm
-(the) 12.1743 Tj
--250 TJm
-(Manber) 30.9837 Tj
-20 TJm
-(-Myers) 28.772 Tj
--250 TJm
-(algorithm.) 41.2352 Tj
-[1 0 0 1 314.189 320.905] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -242.189 -11.7883] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -309.116] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-86.944 299.318 Td
-/F130_0 9.9626 Tf
-(I) 3.31755 Tj
--248 TJm
-(could) 22.1369 Tj
--248 TJm
-(ha) 9.40469 Tj
-20 TJm
-(v) 4.9813 Tj
-15 TJm
-(e) 4.42339 Tj
--248 TJm
-(changed) 33.1954 Tj
--248 TJm
-(to) 7.7509 Tj
--248 TJm
-(Sadakane') 41.4942 Tj
-55 TJm
-(s) 3.87545 Tj
--248 TJm
-(algorithm,) 41.2352 Tj
--249 TJm
-(b) 4.9813 Tj
-20 TJm
-(ut) 7.7509 Tj
--248 TJm
-(I) 3.31755 Tj
--248 TJm
-(\002nd) 15.5018 Tj
--248 TJm
-(it) 5.53921 Tj
--248 TJm
-(to) 7.7509 Tj
--248 TJm
-(be) 9.40469 Tj
--248 TJm
-(slo) 11.6264 Tj
-25 TJm
-(wer) 14.9339 Tj
--248 TJm
-(than) 17.1556 Tj
-[1 0 0 1 392.444 299.318] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -392.444 -299.318] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-392.444 299.318 Td
-/F134_0 9.9626 Tf
-(bzip2) 29.8878 Tj
-[1 0 0 1 422.332 299.318] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -422.332 -299.318] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-422.332 299.318 Td
-/F130_0 9.9626 Tf
-(') 3.31755 Tj
-55 TJm
-(s) 3.87545 Tj
--248 TJm
-(e) 4.42339 Tj
-15 TJm
-(xisting) 27.1282 Tj
--248 TJm
-(algorithm) 38.7446 Tj
--248 TJm
-(for) 11.6164 Tj
--248 TJm
-(most) 19.3773 Tj
-86.944 287.363 Td
-(inputs,) 26.8492 Tj
--370 TJm
-(and) 14.386 Tj
--345 TJm
-(the) 12.1743 Tj
--346 TJm
-(randomisation) 57.006 Tj
--346 TJm
-(mechanism) 45.3796 Tj
--345 TJm
-(protects) 31.5416 Tj
--346 TJm
-(adequately) 43.158 Tj
--345 TJm
-(ag) 9.40469 Tj
-5 TJm
-(ainst) 18.8194 Tj
--346 TJm
-(bad) 14.386 Tj
--346 TJm
-(cases.) 23.5117 Tj
--1194 TJm
-(I) 3.31755 Tj
--345 TJm
-(didn') 21.031 Tj
-18 TJm
-(t) 2.7696 Tj
--346 TJm
-(think) 20.4831 Tj
--346 TJm
-(it) 5.53921 Tj
--345 TJm
-(w) 7.193 Tj
-10 TJm
-(as) 8.29885 Tj
--346 TJm
-(a) 4.42339 Tj
--346 TJm
-(good) 19.9252 Tj
-86.944 275.408 Td
-(tradeof) 28.2141 Tj
-25 TJm
-(f) 3.31755 Tj
--262 TJm
-(to) 7.7509 Tj
--261 TJm
-(mak) 17.1556 Tj
-10 TJm
-(e.) 6.91404 Tj
--690 TJm
-(P) 5.53921 Tj
-15 TJm
-(artly) 18.2614 Tj
--262 TJm
-(this) 14.396 Tj
--261 TJm
-(is) 6.64505 Tj
--262 TJm
-(due) 14.386 Tj
--261 TJm
-(to) 7.7509 Tj
--262 TJm
-(the) 12.1743 Tj
--262 TJm
-(f) 3.31755 Tj
-10 TJm
-(act) 11.6164 Tj
--261 TJm
-(that) 14.9439 Tj
--262 TJm
-(I) 3.31755 Tj
--261 TJm
-(w) 7.193 Tj
-10 TJm
-(as) 8.29885 Tj
--262 TJm
-(not) 12.7322 Tj
--262 TJm
-(\003ooded) 29.8878 Tj
--261 TJm
-(with) 17.7135 Tj
--262 TJm
-(email) 22.1369 Tj
--261 TJm
-(complaints) 43.7259 Tj
--262 TJm
-(about) 22.1369 Tj
-[1 0 0 1 479.557 275.408] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -479.557 -275.408] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-479.557 275.408 Td
-/F134_0 9.9626 Tf
-(bzip2-0.1) 53.798 Tj
-[1 0 0 1 533.355 275.408] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -533.355 -275.408] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-533.355 275.408 Td
-/F130_0 9.9626 Tf
-(') 3.31755 Tj
-55 TJm
-(s) 3.87545 Tj
-86.944 263.453 Td
-(performance) 50.341 Tj
--250 TJm
-(on) 9.9626 Tj
--250 TJm
-(repetiti) 28.224 Tj
-25 TJm
-(v) 4.9813 Tj
-15 TJm
-(e) 4.42339 Tj
--250 TJm
-(data,) 19.0883 Tj
--250 TJm
-(so) 8.85675 Tj
--250 TJm
-(perhaps) 30.9837 Tj
--250 TJm
-(it) 5.53921 Tj
--250 TJm
-(isn') 14.9439 Tj
-18 TJm
-(t) 2.7696 Tj
--250 TJm
-(a) 4.42339 Tj
--250 TJm
-(problem) 33.2053 Tj
--250 TJm
-(for) 11.6164 Tj
--250 TJm
-(real) 14.9339 Tj
--250 TJm
-(inputs.) 26.8492 Tj
-[1 0 0 1 72 261.296] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.6315] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -251.664] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-86.944 241.866 Td
-/F130_0 9.9626 Tf
-(Probably) 35.9749 Tj
--289 TJm
-(the) 12.1743 Tj
--288 TJm
-(best) 16.0497 Tj
--289 TJm
-(long-term) 39.2925 Tj
--289 TJm
-(solution,) 34.6001 Tj
--298 TJm
-(and) 14.386 Tj
--289 TJm
-(the) 12.1743 Tj
--289 TJm
-(one) 14.386 Tj
--288 TJm
-(I) 3.31755 Tj
--289 TJm
-(ha) 9.40469 Tj
-20 TJm
-(v) 4.9813 Tj
-15 TJm
-(e) 4.42339 Tj
--289 TJm
-(incorporated) 50.351 Tj
--288 TJm
-(into) 15.5018 Tj
--289 TJm
-(0.9.5) 19.9252 Tj
--289 TJm
-(and) 14.386 Tj
--288 TJm
-(abo) 14.386 Tj
-15 TJm
-(v) 4.9813 Tj
-14 TJm
-(e,) 6.91404 Tj
--298 TJm
-(is) 6.64505 Tj
--289 TJm
-(to) 7.7509 Tj
--288 TJm
-(use) 13.2801 Tj
--289 TJm
-(the) 12.1743 Tj
--289 TJm
-(e) 4.42339 Tj
-15 TJm
-(xisting) 27.1282 Tj
-86.944 229.911 Td
-(sorting) 27.6761 Tj
--451 TJm
-(algorithm) 38.7446 Tj
--452 TJm
-(initially) 31.0036 Tj
-65 TJm
-(,) 2.49065 Tj
--501 TJm
-(and) 14.386 Tj
--452 TJm
-(f) 3.31755 Tj
-10 TJm
-(all) 9.9626 Tj
--451 TJm
-(back) 18.8094 Tj
--452 TJm
-(to) 7.7509 Tj
--451 TJm
-(a) 4.42339 Tj
--451 TJm
-(O\(N) 17.7035 Tj
--452 TJm
-(\(log) 16.0497 Tj
--451 TJm
-(N\)^2\)) 23.4818 Tj
--451 TJm
-(algorithm) 38.7446 Tj
--452 TJm
-(if) 6.08715 Tj
--451 TJm
-(the) 12.1743 Tj
--452 TJm
-(standard) 33.7533 Tj
--451 TJm
-(algorithm) 38.7446 Tj
--451 TJm
-(gets) 16.0497 Tj
--452 TJm
-(into) 15.5018 Tj
-86.944 217.956 Td
-(dif) 11.0684 Tj
-25 TJm
-(\002culties.) 34.0422 Tj
-[1 0 0 1 72 217.856] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -21.4871] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 6.9739 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -78.9739 -196.369] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-78.9739 196.369 Td
-/F130_0 9.9626 Tf
-(\225) 3.48691 Tj
-[1 0 0 1 82.4608 196.369] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 1.9925 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -86.944 -196.369] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-86.944 196.369 Td
-/F130_0 9.9626 Tf
-(The) 15.4918 Tj
--299 TJm
-(compressed) 47.0334 Tj
--299 TJm
-(\002le) 12.7322 Tj
--299 TJm
-(format) 26.5603 Tj
--299 TJm
-(w) 7.193 Tj
-10 TJm
-(as) 8.29885 Tj
--300 TJm
-(ne) 9.40469 Tj
-25 TJm
-(v) 4.9813 Tj
-15 TJm
-(er) 7.74094 Tj
--299 TJm
-(designed) 35.417 Tj
--299 TJm
-(to) 7.7509 Tj
--299 TJm
-(be) 9.40469 Tj
--299 TJm
-(handled) 31.5416 Tj
--299 TJm
-(by) 9.9626 Tj
--299 TJm
-(a) 4.42339 Tj
--299 TJm
-(library) 26.5603 Tj
-65 TJm
-(,) 2.49065 Tj
--312 TJm
-(and) 14.386 Tj
--299 TJm
-(I) 3.31755 Tj
--299 TJm
-(ha) 9.40469 Tj
-20 TJm
-(v) 4.9813 Tj
-15 TJm
-(e) 4.42339 Tj
--299 TJm
-(had) 14.386 Tj
--299 TJm
-(to) 7.7509 Tj
--299 TJm
-(jump) 20.4831 Tj
--300 TJm
-(though) 27.6761 Tj
--299 TJm
-(some) 21.031 Tj
-86.944 184.414 Td
-(hoops) 23.8007 Tj
--278 TJm
-(to) 7.7509 Tj
--277 TJm
-(produce) 32.0895 Tj
--278 TJm
-(an) 9.40469 Tj
--278 TJm
-(ef) 7.74094 Tj
-25 TJm
-(\002cient) 24.9065 Tj
--277 TJm
-(implementation) 62.5452 Tj
--278 TJm
-(of) 8.29885 Tj
--278 TJm
-(decompression.) 62.2563 Tj
--786 TJm
-(It') 9.40469 Tj
-55 TJm
-(s) 3.87545 Tj
--278 TJm
-(a) 4.42339 Tj
--277 TJm
-(bit) 10.5205 Tj
--278 TJm
-(hairy) 20.4731 Tj
-65 TJm
-(.) 2.49065 Tj
--786 TJm
-(T) 6.08715 Tj
-35 TJm
-(ry) 8.29885 Tj
--278 TJm
-(passing) 29.8878 Tj
-[1 0 0 1 468.269 184.414] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -468.269 -184.414] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-468.269 184.414 Td
-/F134_0 9.9626 Tf
-(decompress.c) 71.7307 Tj
-[1 0 0 1 540 184.414] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -540 -184.414] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-86.944 172.459 Td
-/F130_0 9.9626 Tf
-(through) 30.9936 Tj
--268 TJm
-(the) 12.1743 Tj
--268 TJm
-(C) 6.64505 Tj
--268 TJm
-(preprocessor) 50.8989 Tj
--269 TJm
-(and) 14.386 Tj
--268 TJm
-(you') 18.2614 Tj
-10 TJm
-(ll) 5.53921 Tj
--268 TJm
-(see) 12.7222 Tj
--268 TJm
-(what) 19.3673 Tj
--268 TJm
-(I) 3.31755 Tj
--268 TJm
-(mean.) 24.0696 Tj
--729 TJm
-(Much) 23.2427 Tj
--268 TJm
-(of) 8.29885 Tj
--269 TJm
-(this) 14.396 Tj
--268 TJm
-(comple) 29.3299 Tj
-15 TJm
-(xity) 15.5018 Tj
--268 TJm
-(could) 22.1369 Tj
--268 TJm
-(ha) 9.40469 Tj
-20 TJm
-(v) 4.9813 Tj
-15 TJm
-(e) 4.42339 Tj
--268 TJm
-(been) 18.8094 Tj
--268 TJm
-(a) 4.42339 Tj
-20 TJm
-(v) 4.9813 Tj
-20 TJm
-(oided) 22.1369 Tj
--269 TJm
-(if) 6.08715 Tj
--268 TJm
-(the) 12.1743 Tj
-86.944 160.503 Td
-(compressed) 47.0334 Tj
--250 TJm
-(size) 15.4918 Tj
--250 TJm
-(of) 8.29885 Tj
--250 TJm
-(each) 18.2515 Tj
--250 TJm
-(block) 22.1369 Tj
--250 TJm
-(of) 8.29885 Tj
--250 TJm
-(data) 16.5977 Tj
--250 TJm
-(w) 7.193 Tj
-10 TJm
-(as) 8.29885 Tj
--250 TJm
-(recorded) 34.8492 Tj
--250 TJm
-(in) 7.7509 Tj
--250 TJm
-(the) 12.1743 Tj
--250 TJm
-(data) 16.5977 Tj
--250 TJm
-(stream.) 29.0509 Tj
-[1 0 0 1 368.754 160.503] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -296.754 -21.5867] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 6.9739 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -78.9739 -138.917] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-78.9739 138.917 Td
-/F130_0 9.9626 Tf
-(\225) 3.48691 Tj
-[1 0 0 1 82.4608 138.917] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 1.9925 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -86.944 -138.917] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-86.944 138.917 Td
-/F130_0 9.9626 Tf
-(An) 12.1743 Tj
--250 TJm
-(Adler) 22.6848 Tj
-20 TJm
-(-32) 13.2801 Tj
--250 TJm
-(checksum,) 42.3311 Tj
--250 TJm
-(rather) 23.2328 Tj
--250 TJm
-(than) 17.1556 Tj
--250 TJm
-(a) 4.42339 Tj
--250 TJm
-(CRC32) 29.8978 Tj
--250 TJm
-(checksum,) 42.3311 Tj
--250 TJm
-(w) 7.193 Tj
-10 TJm
-(ould) 17.7135 Tj
--250 TJm
-(be) 9.40469 Tj
--250 TJm
-(f) 3.31755 Tj
-10 TJm
-(aster) 18.8094 Tj
--250 TJm
-(to) 7.7509 Tj
--250 TJm
-(compute.) 36.8018 Tj
-[1 0 0 1 424.934 138.917] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -352.934 -11.7883] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -127.128] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 117.33 Td
-/F130_0 9.9626 Tf
-(It) 6.08715 Tj
--349 TJm
-(w) 7.193 Tj
-10 TJm
-(ould) 17.7135 Tj
--349 TJm
-(be) 9.40469 Tj
--349 TJm
-(f) 3.31755 Tj
-10 TJm
-(air) 10.5105 Tj
--348 TJm
-(to) 7.7509 Tj
--349 TJm
-(say) 13.2801 Tj
--349 TJm
-(that) 14.9439 Tj
--349 TJm
-(the) 12.1743 Tj
-[1 0 0 1 201.979 117.33] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -201.979 -117.33] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-201.979 117.33 Td
-/F134_0 9.9626 Tf
-(bzip2) 29.8878 Tj
-[1 0 0 1 231.867 117.33] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -231.867 -117.33] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-235.342 117.33 Td
-/F130_0 9.9626 Tf
-(format) 26.5603 Tj
--349 TJm
-(w) 7.193 Tj
-10 TJm
-(as) 8.29885 Tj
--349 TJm
-(frozen) 25.4445 Tj
--348 TJm
-(before) 25.4445 Tj
--349 TJm
-(I) 3.31755 Tj
--349 TJm
-(properly) 33.7533 Tj
--349 TJm
-(and) 14.386 Tj
--349 TJm
-(fully) 18.8194 Tj
--349 TJm
-(understood) 44.2738 Tj
--348 TJm
-(the) 12.1743 Tj
--349 TJm
-(performance) 50.341 Tj
-72 105.375 Td
-(consequences) 54.7744 Tj
--250 TJm
-(of) 8.29885 Tj
--250 TJm
-(doing) 22.6948 Tj
--250 TJm
-(so.) 11.3474 Tj
-[1 0 0 1 72 103.218] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.6315] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -93.5867] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 83.7883 Td
-/F130_0 9.9626 Tf
-(Impro) 24.3486 Tj
-15 TJm
-(v) 4.9813 Tj
-15 TJm
-(ements) 28.224 Tj
--250 TJm
-(which) 24.3486 Tj
--250 TJm
-(I) 3.31755 Tj
--250 TJm
-(w) 7.193 Tj
-10 TJm
-(as) 8.29885 Tj
--250 TJm
-(able) 16.5977 Tj
--250 TJm
-(to) 7.7509 Tj
--250 TJm
-(incorporate) 45.3697 Tj
--250 TJm
-(into) 15.5018 Tj
--250 TJm
-(0.9.0,) 22.4159 Tj
--250 TJm
-(despite) 28.224 Tj
--250 TJm
-(using) 21.589 Tj
--250 TJm
-(the) 12.1743 Tj
--250 TJm
-(same) 20.4731 Tj
--250 TJm
-(\002le) 12.7322 Tj
--250 TJm
-(format,) 29.0509 Tj
--250 TJm
-(are:) 14.9339 Tj
-[1 0 0 1 72 81.6315] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -30.7796] cm
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-[1 0 0 1 1.8929 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 374.394 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 6.8541] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 40.5726 -6.7546] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -493.841 -50.9514] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-534.414 50.9514 Td
-/F130_0 9.9626 Tf
-(31) 9.9626 Tj
-[1 0 0 1 453.269 50.8519] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 93.5985 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 6.2765 0] cm
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-[1 0 0 1 -13.1436 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-Q
-showpage
-%%PageTrailer
-pdfEndPage
-%%Page: 35 35
-%%BeginPageSetup
-%%PageOrientation: Portrait
-pdfStartPage
-0 0 612 792 re W
-%%EndPageSetup
-[] 0 d
-1 i
-0 j
-0 J
-10 M
-1 w
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-false op
-false OP
-0 0 612 792 re
-W
-q
-[1 0 0 1 72 741.554] cm
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-[1 0 0 1 1.8929 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 14.4459] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 187.197 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 -6.8541] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 6.8541] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 116.328 -6.7546] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -382.4 -749.245] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-498.728 749.245 Td
-/F130_0 9.9626 Tf
-(Miscellanea) 48.1393 Tj
-[1 0 0 1 266.071 749.146] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 280.796 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -472.974 -7.0936] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -0.4981] cm
-q
-[] 0 d
-0 J
-0.4981 w
-0 0.2491 m
-475.465 0.2491 l
-S
-Q
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 479.251 0] cm
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-[1 0 0 1 -13.1436 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -468 -31.5168] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 6.9739 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -78.9739 -710.037] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-78.9739 710.037 Td
-/F130_0 9.9626 Tf
-(\225) 3.48691 Tj
-[1 0 0 1 82.4608 710.037] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 1.9925 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -86.944 -710.037] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-86.944 710.037 Td
-/F130_0 9.9626 Tf
-(Single) 25.4644 Tj
--202 TJm
-(array) 20.4632 Tj
--201 TJm
-(implementation) 62.5452 Tj
--202 TJm
-(of) 8.29885 Tj
--202 TJm
-(the) 12.1743 Tj
--201 TJm
-(in) 7.7509 Tj
-40 TJm
-(v) 4.9813 Tj
-15 TJm
-(erse) 16.0398 Tj
--202 TJm
-(BWT) 22.1369 Tj
-74 TJm
-(.) 2.49065 Tj
--403 TJm
-(This) 17.7135 Tj
--202 TJm
-(signi\002cantly) 49.2651 Tj
--201 TJm
-(speeds) 26.5603 Tj
--202 TJm
-(up) 9.9626 Tj
--202 TJm
-(decompression,) 62.2563 Tj
--211 TJm
-(presumably) 46.4855 Tj
--202 TJm
-(because) 31.5316 Tj
-86.944 698.082 Td
-(it) 5.53921 Tj
--250 TJm
-(reduces) 30.4258 Tj
--250 TJm
-(the) 12.1743 Tj
--250 TJm
-(number) 30.4357 Tj
--250 TJm
-(of) 8.29885 Tj
--250 TJm
-(cache) 22.6749 Tj
--250 TJm
-(misses.) 29.0609 Tj
-[1 0 0 1 240.496 698.082] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -168.496 -21.9178] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 6.9739 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -78.9739 -676.164] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-78.9739 676.164 Td
-/F130_0 9.9626 Tf
-(\225) 3.48691 Tj
-[1 0 0 1 82.4608 676.164] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 1.9925 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -86.944 -676.164] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-86.944 676.164 Td
-/F130_0 9.9626 Tf
-(F) 5.53921 Tj
-15 TJm
-(aster) 18.8094 Tj
--314 TJm
-(in) 7.7509 Tj
-40 TJm
-(v) 4.9813 Tj
-15 TJm
-(erse) 16.0398 Tj
--315 TJm
-(MTF) 20.4831 Tj
--314 TJm
-(transform) 38.7346 Tj
--315 TJm
-(for) 11.6164 Tj
--314 TJm
-(lar) 10.5105 Tj
-18 TJm
-(ge) 9.40469 Tj
--315 TJm
-(MTF) 20.4831 Tj
--314 TJm
-(v) 4.9813 Tj
-25 TJm
-(alues.) 22.9638 Tj
--504 TJm
-(The) 15.4918 Tj
--314 TJm
-(ne) 9.40469 Tj
-25 TJm
-(w) 7.193 Tj
--314 TJm
-(implementation) 62.5452 Tj
--315 TJm
-(is) 6.64505 Tj
--314 TJm
-(based) 22.6848 Tj
--315 TJm
-(on) 9.9626 Tj
--314 TJm
-(the) 12.1743 Tj
--315 TJm
-(notion) 25.4644 Tj
--314 TJm
-(of) 8.29885 Tj
--315 TJm
-(sliding) 27.1282 Tj
-86.944 664.209 Td
-(blocks) 26.0123 Tj
--250 TJm
-(of) 8.29885 Tj
--250 TJm
-(v) 4.9813 Tj
-25 TJm
-(alues.) 22.9638 Tj
-[1 0 0 1 153.932 664.209] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -81.9321 -21.9178] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 6.9739 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -78.9739 -642.291] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-78.9739 642.291 Td
-/F130_0 9.9626 Tf
-(\225) 3.48691 Tj
-[1 0 0 1 82.4608 642.291] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 1.9925 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -86.944 -642.291] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-86.944 642.291 Td
-/F134_0 9.9626 Tf
-(bzip2-0.9.0) 65.7532 Tj
-[1 0 0 1 152.697 642.291] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -152.697 -642.291] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-155.412 642.291 Td
-/F130_0 9.9626 Tf
-(no) 9.9626 Tj
-25 TJm
-(w) 7.193 Tj
--272 TJm
-(reads) 21.0211 Tj
--273 TJm
-(and) 14.386 Tj
--272 TJm
-(writes) 24.3486 Tj
--273 TJm
-(\002les) 16.6077 Tj
--272 TJm
-(with) 17.7135 Tj
-[1 0 0 1 282.68 642.291] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -282.68 -642.291] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-282.68 642.291 Td
-/F134_0 9.9626 Tf
-(fread) 29.8878 Tj
-[1 0 0 1 312.568 642.291] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -312.568 -642.291] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-315.282 642.291 Td
-/F130_0 9.9626 Tf
-(and) 14.386 Tj
-[1 0 0 1 332.383 642.291] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -332.383 -642.291] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-332.383 642.291 Td
-/F134_0 9.9626 Tf
-(fwrite) 35.8654 Tj
-[1 0 0 1 368.248 642.291] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -368.248 -642.291] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-368.248 642.291 Td
-/F130_0 9.9626 Tf
-(;) 2.7696 Tj
--284 TJm
-(v) 4.9813 Tj
-15 TJm
-(ersion) 24.3486 Tj
--272 TJm
-(0.1) 12.4533 Tj
--273 TJm
-(used) 18.2614 Tj
-[1 0 0 1 441.882 642.291] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -441.882 -642.291] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-441.882 642.291 Td
-/F134_0 9.9626 Tf
-(putc) 23.9102 Tj
-[1 0 0 1 465.792 642.291] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -465.792 -642.291] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-468.507 642.291 Td
-/F130_0 9.9626 Tf
-(and) 14.386 Tj
-[1 0 0 1 485.607 642.291] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -485.607 -642.291] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-485.607 642.291 Td
-/F134_0 9.9626 Tf
-(getc) 23.9102 Tj
-[1 0 0 1 509.517 642.291] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -509.517 -642.291] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-509.517 642.291 Td
-/F130_0 9.9626 Tf
-(.) 2.49065 Tj
--755 TJm
-(Duh!) 20.4731 Tj
-86.944 630.336 Td
-(W) 9.40469 Tj
-80 TJm
-(ell,) 12.4533 Tj
--250 TJm
-(you) 14.9439 Tj
--250 TJm
-(li) 5.53921 Tj
-25 TJm
-(v) 4.9813 Tj
-15 TJm
-(e) 4.42339 Tj
--250 TJm
-(and) 14.386 Tj
--250 TJm
-(learn.) 22.4059 Tj
-[1 0 0 1 184.248 630.336] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -112.248 -12.1195] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -618.217] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 608.418 Td
-/F130_0 9.9626 Tf
-(Further) 29.3299 Tj
--304 TJm
-(ahead,) 25.7234 Tj
--318 TJm
-(it) 5.53921 Tj
--305 TJm
-(w) 7.193 Tj
-10 TJm
-(ould) 17.7135 Tj
--304 TJm
-(be) 9.40469 Tj
--305 TJm
-(nice) 16.5977 Tj
--304 TJm
-(to) 7.7509 Tj
--305 TJm
-(be) 9.40469 Tj
--304 TJm
-(able) 16.5977 Tj
--304 TJm
-(to) 7.7509 Tj
--305 TJm
-(do) 9.9626 Tj
--304 TJm
-(random) 30.4357 Tj
--305 TJm
-(access) 25.4445 Tj
--304 TJm
-(into) 15.5018 Tj
--305 TJm
-(\002les.) 19.0983 Tj
--946 TJm
-(This) 17.7135 Tj
--305 TJm
-(will) 15.5018 Tj
--304 TJm
-(require) 28.2141 Tj
--304 TJm
-(some) 21.031 Tj
--305 TJm
-(careful) 27.6562 Tj
--304 TJm
-(design) 26.0123 Tj
--305 TJm
-(of) 8.29885 Tj
-72 596.463 Td
-(compressed) 47.0334 Tj
--250 TJm
-(\002le) 12.7322 Tj
--250 TJm
-(formats.) 32.9264 Tj
-[1 0 0 1 72 594.306] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.9626] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -584.344] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 561.71 Td
-/F122_0 20.6585 Tf
-(4.2.) 34.4584 Tj
--278 TJm
-(P) 13.7792 Tj
-40 TJm
-(or) 20.6585 Tj
--20 TJm
-(tability) 66.5823 Tj
--278 TJm
-(issues) 64.3099 Tj
-[1 0 0 1 72 557.434] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.9626] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -547.472] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 539.793 Td
-/F130_0 9.9626 Tf
-(After) 21.0211 Tj
--250 TJm
-(some) 21.031 Tj
--250 TJm
-(consideration,) 56.1691 Tj
--250 TJm
-(I) 3.31755 Tj
--250 TJm
-(ha) 9.40469 Tj
-20 TJm
-(v) 4.9813 Tj
-15 TJm
-(e) 4.42339 Tj
--250 TJm
-(decided) 30.9837 Tj
--250 TJm
-(not) 12.7322 Tj
--250 TJm
-(to) 7.7509 Tj
--250 TJm
-(use) 13.2801 Tj
--250 TJm
-(GNU) 21.579 Tj
-[1 0 0 1 303.231 539.793] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -303.231 -539.793] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-303.231 539.793 Td
-/F134_0 9.9626 Tf
-(autoconf) 47.8205 Tj
-[1 0 0 1 351.052 539.793] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -351.052 -539.793] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-353.542 539.793 Td
-/F130_0 9.9626 Tf
-(to) 7.7509 Tj
--250 TJm
-(con\002gure) 37.6287 Tj
--250 TJm
-(0.9.5) 19.9252 Tj
--250 TJm
-(or) 8.29885 Tj
--250 TJm
-(1.0.) 14.9439 Tj
-[1 0 0 1 72 537.636] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.9627] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -527.673] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 517.875 Td
-/F134_0 9.9626 Tf
-(autoconf) 47.8205 Tj
-[1 0 0 1 119.821 517.875] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -119.821 -517.875] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-119.821 517.875 Td
-/F130_0 9.9626 Tf
-(,) 2.49065 Tj
--502 TJm
-(admirable) 39.8404 Tj
--452 TJm
-(and) 14.386 Tj
--452 TJm
-(w) 7.193 Tj
-10 TJm
-(onderful) 33.7533 Tj
--452 TJm
-(though) 27.6761 Tj
--452 TJm
-(it) 5.53921 Tj
--452 TJm
-(is,) 9.1357 Tj
--502 TJm
-(mainly) 27.6761 Tj
--452 TJm
-(assists) 25.4644 Tj
--452 TJm
-(with) 17.7135 Tj
--452 TJm
-(portability) 41.5142 Tj
--452 TJm
-(problems) 37.0808 Tj
--452 TJm
-(between) 33.1954 Tj
--452 TJm
-(Unix-lik) 33.7633 Tj
-10 TJm
-(e) 4.42339 Tj
-72 505.92 Td
-(platforms.) 40.6773 Tj
--1398 TJm
-(But) 14.396 Tj
-[1 0 0 1 144.784 505.92] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -144.784 -505.92] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-144.784 505.92 Td
-/F134_0 9.9626 Tf
-(bzip2) 29.8878 Tj
-[1 0 0 1 174.672 505.92] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -174.672 -505.92] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-178.455 505.92 Td
-/F130_0 9.9626 Tf
-(doesn') 26.5603 Tj
-18 TJm
-(t) 2.7696 Tj
--380 TJm
-(ha) 9.40469 Tj
-20 TJm
-(v) 4.9813 Tj
-15 TJm
-(e) 4.42339 Tj
--379 TJm
-(much) 22.1369 Tj
--380 TJm
-(in) 7.7509 Tj
--380 TJm
-(the) 12.1743 Tj
--379 TJm
-(w) 7.193 Tj
-10 TJm
-(ay) 9.40469 Tj
--380 TJm
-(of) 8.29885 Tj
--380 TJm
-(portability) 41.5142 Tj
--379 TJm
-(problems) 37.0808 Tj
--380 TJm
-(on) 9.9626 Tj
--380 TJm
-(Unix;) 22.6948 Tj
--444 TJm
-(most) 19.3773 Tj
--380 TJm
-(of) 8.29885 Tj
--380 TJm
-(the) 12.1743 Tj
--379 TJm
-(dif) 11.0684 Tj
-25 TJm
-(\002culties) 31.5516 Tj
-72 493.964 Td
-(appear) 26.5503 Tj
--297 TJm
-(when) 21.579 Tj
--296 TJm
-(po) 9.9626 Tj
--1 TJm
-(r) 3.31755 Tj
-1 TJm
-(ting) 15.5018 Tj
--297 TJm
-(to) 7.7509 Tj
--297 TJm
-(the) 12.1743 Tj
--297 TJm
-(Mac,) 20.1942 Tj
--308 TJm
-(or) 8.29885 Tj
--297 TJm
-(to) 7.7509 Tj
--297 TJm
-(Microsoft') 42.61 Tj
-55 TJm
-(s) 3.87545 Tj
--296 TJm
-(operating) 37.6287 Tj
--297 TJm
-(systems.) 34.0422 Tj
-[1 0 0 1 361.339 493.964] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -361.339 -493.964] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-361.339 493.964 Td
-/F134_0 9.9626 Tf
-(autoconf) 47.8205 Tj
-[1 0 0 1 409.16 493.964] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -409.16 -493.964] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-412.116 493.964 Td
-/F130_0 9.9626 Tf
-(doesn') 26.5603 Tj
-18 TJm
-(t) 2.7696 Tj
--297 TJm
-(help) 17.1556 Tj
--296 TJm
-(in) 7.7509 Tj
--297 TJm
-(those) 21.031 Tj
--297 TJm
-(cases,) 23.5117 Tj
--308 TJm
-(and) 14.386 Tj
-72 482.009 Td
-(brings) 24.9065 Tj
--250 TJm
-(in) 7.7509 Tj
--250 TJm
-(a) 4.42339 Tj
--250 TJm
-(whole) 24.3486 Tj
--250 TJm
-(load) 17.1556 Tj
--250 TJm
-(of) 8.29885 Tj
--250 TJm
-(ne) 9.40469 Tj
-25 TJm
-(w) 7.193 Tj
--250 TJm
-(comple) 29.3299 Tj
-15 TJm
-(xity) 15.5018 Tj
-65 TJm
-(.) 2.49065 Tj
-[1 0 0 1 72 479.852] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.9626] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -469.89] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 460.091 Td
-/F130_0 9.9626 Tf
-(Most) 20.4831 Tj
--392 TJm
-(people) 26.5603 Tj
--392 TJm
-(should) 26.5703 Tj
--393 TJm
-(be) 9.40469 Tj
--392 TJm
-(able) 16.5977 Tj
--392 TJm
-(to) 7.7509 Tj
--392 TJm
-(compile) 32.0995 Tj
--393 TJm
-(the) 12.1743 Tj
--392 TJm
-(library) 26.5603 Tj
--392 TJm
-(and) 14.386 Tj
--392 TJm
-(program) 33.7533 Tj
--393 TJm
-(under) 22.6848 Tj
--392 TJm
-(Unix) 19.9252 Tj
--392 TJm
-(straight) 29.8878 Tj
--392 TJm
-(out-of-the-box,) 60.5925 Tj
--428 TJm
-(so) 8.85675 Tj
--392 TJm
-(to) 7.7509 Tj
--393 TJm
-(speak,) 25.1755 Tj
-72 448.136 Td
-(especially) 39.8404 Tj
--250 TJm
-(if) 6.08715 Tj
--250 TJm
-(you) 14.9439 Tj
--250 TJm
-(ha) 9.40469 Tj
-20 TJm
-(v) 4.9813 Tj
-15 TJm
-(e) 4.42339 Tj
--250 TJm
-(a) 4.42339 Tj
--250 TJm
-(v) 4.9813 Tj
-15 TJm
-(ersion) 24.3486 Tj
--250 TJm
-(of) 8.29885 Tj
--250 TJm
-(GNU) 21.579 Tj
--250 TJm
-(C) 6.64505 Tj
--250 TJm
-(a) 4.42339 Tj
-20 TJm
-(v) 4.9813 Tj
-25 TJm
-(ailable.) 29.0509 Tj
-[1 0 0 1 72 445.979] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.9627] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -436.017] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 426.218 Td
-/F130_0 9.9626 Tf
-(There) 23.2328 Tj
--259 TJm
-(are) 12.1643 Tj
--258 TJm
-(a) 4.42339 Tj
--259 TJm
-(couple) 26.5603 Tj
--258 TJm
-(of) 8.29885 Tj
-[1 0 0 1 159.561 426.218] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -159.561 -426.218] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-159.561 426.218 Td
-/F134_0 9.9626 Tf
-(__inline__) 59.7756 Tj
-[1 0 0 1 219.337 426.218] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -219.337 -426.218] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-221.913 426.218 Td
-/F130_0 9.9626 Tf
-(directi) 25.4544 Tj
-25 TJm
-(v) 4.9813 Tj
-15 TJm
-(es) 8.29885 Tj
--259 TJm
-(in) 7.7509 Tj
--258 TJm
-(the) 12.1743 Tj
--259 TJm
-(code.) 21.3 Tj
--671 TJm
-(GNU) 21.579 Tj
--259 TJm
-(C) 6.64505 Tj
--258 TJm
-(\() 3.31755 Tj
-[1 0 0 1 352.587 426.218] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -352.587 -426.218] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-352.587 426.218 Td
-/F134_0 9.9626 Tf
-(gcc) 17.9327 Tj
-[1 0 0 1 370.52 426.218] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -370.52 -426.218] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-370.52 426.218 Td
-/F130_0 9.9626 Tf
-(\)) 3.31755 Tj
--259 TJm
-(should) 26.5703 Tj
--258 TJm
-(be) 9.40469 Tj
--259 TJm
-(able) 16.5977 Tj
--258 TJm
-(to) 7.7509 Tj
--259 TJm
-(handle) 26.5603 Tj
--259 TJm
-(them.) 22.4159 Tj
--671 TJm
-(If) 6.63509 Tj
--259 TJm
-(you') 18.2614 Tj
-50 TJm
-(re) 7.74094 Tj
-72 414.263 Td
-(not) 12.7322 Tj
--279 TJm
-(using) 21.589 Tj
--279 TJm
-(GNU) 21.579 Tj
--279 TJm
-(C,) 9.1357 Tj
--279 TJm
-(your) 18.2614 Tj
--279 TJm
-(C) 6.64505 Tj
--279 TJm
-(compiler) 35.417 Tj
--279 TJm
-(shouldn') 34.8691 Tj
-18 TJm
-(t) 2.7696 Tj
--279 TJm
-(see) 12.7222 Tj
--279 TJm
-(them) 19.9252 Tj
--279 TJm
-(at) 7.193 Tj
--279 TJm
-(all.) 12.4533 Tj
--794 TJm
-(If) 6.63509 Tj
--279 TJm
-(your) 18.2614 Tj
--279 TJm
-(compiler) 35.417 Tj
--279 TJm
-(does,) 20.7521 Tj
--286 TJm
-(for) 11.6164 Tj
--279 TJm
-(some) 21.031 Tj
--279 TJm
-(reason,) 28.493 Tj
--287 TJm
-(see) 12.7222 Tj
--279 TJm
-(them) 19.9252 Tj
--279 TJm
-(and) 14.386 Tj
-72 402.308 Td
-(doesn') 26.5603 Tj
-18 TJm
-(t) 2.7696 Tj
--283 TJm
-(lik) 10.5205 Tj
-10 TJm
-(e) 4.42339 Tj
--283 TJm
-(them,) 22.4159 Tj
--291 TJm
-(just) 14.396 Tj
-[1 0 0 1 164.167 402.308] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -164.167 -402.308] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-164.167 402.308 Td
-/F134_0 9.9626 Tf
-(#define) 41.8429 Tj
-[1 0 0 1 206.01 402.308] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.8196 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -208.829 -402.308] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-208.829 402.308 Td
-/F134_0 9.9626 Tf
-(__inline__) 59.7756 Tj
-[1 0 0 1 268.605 402.308] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -268.605 -402.308] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-271.425 402.308 Td
-/F130_0 9.9626 Tf
-(to) 7.7509 Tj
--283 TJm
-(be) 9.40469 Tj
-[1 0 0 1 294.22 402.308] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -294.22 -402.308] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-294.22 402.308 Td
-/F134_0 9.9626 Tf
-(/) 5.97756 Tj
-300.197 400.565 Td
-(*) 5.97756 Tj
--600 TJm
-(*) 5.97756 Tj
-318.13 402.308 Td
-(/) 5.97756 Tj
-[1 0 0 1 324.108 402.308] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -324.108 -402.308] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-324.108 402.308 Td
-/F130_0 9.9626 Tf
-(.) 2.49065 Tj
--818 TJm
-(One) 16.5977 Tj
--283 TJm
-(easy) 17.7035 Tj
--283 TJm
-(w) 7.193 Tj
-10 TJm
-(ay) 9.40469 Tj
--283 TJm
-(to) 7.7509 Tj
--283 TJm
-(do) 9.9626 Tj
--283 TJm
-(this) 14.396 Tj
--283 TJm
-(is) 6.64505 Tj
--283 TJm
-(to) 7.7509 Tj
--283 TJm
-(compile) 32.0995 Tj
--283 TJm
-(with) 17.7135 Tj
--283 TJm
-(the) 12.1743 Tj
--283 TJm
-(\003ag) 14.9439 Tj
-[1 0 0 1 72 390.353] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -390.353] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 390.353 Td
-/F134_0 9.9626 Tf
-(-D__inline__=) 77.7083 Tj
-[1 0 0 1 149.709 390.353] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -149.709 -390.353] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-149.709 390.353 Td
-/F130_0 9.9626 Tf
-(,) 2.49065 Tj
--250 TJm
-(which) 24.3486 Tj
--250 TJm
-(should) 26.5703 Tj
--250 TJm
-(be) 9.40469 Tj
--250 TJm
-(understood) 44.2738 Tj
--250 TJm
-(by) 9.9626 Tj
--250 TJm
-(most) 19.3773 Tj
--250 TJm
-(Unix) 19.9252 Tj
--250 TJm
-(compilers.) 41.7831 Tj
-[1 0 0 1 72 388.196] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.9627] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -378.233] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 368.435 Td
-/F130_0 9.9626 Tf
-(If) 6.63509 Tj
--321 TJm
-(you) 14.9439 Tj
--321 TJm
-(still) 14.9539 Tj
--322 TJm
-(ha) 9.40469 Tj
-20 TJm
-(v) 4.9813 Tj
-15 TJm
-(e) 4.42339 Tj
--321 TJm
-(dif) 11.0684 Tj
-25 TJm
-(\002culties,) 34.0422 Tj
--339 TJm
-(try) 11.0684 Tj
--321 TJm
-(compiling) 40.4083 Tj
--321 TJm
-(with) 17.7135 Tj
--322 TJm
-(t) 2.7696 Tj
-1 TJm
-(he) 9.40469 Tj
--322 TJm
-(macro) 24.8965 Tj
-[1 0 0 1 310.295 368.435] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -310.295 -368.435] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-310.295 368.435 Td
-/F134_0 9.9626 Tf
-(BZ_STRICT_ANSI) 83.6858 Tj
-[1 0 0 1 393.981 368.435] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -393.981 -368.435] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-397.18 368.435 Td
-/F130_0 9.9626 Tf
-(de\002ned.) 31.8205 Tj
--524 TJm
-(This) 17.7135 Tj
--321 TJm
-(should) 26.5703 Tj
--321 TJm
-(enable) 26.0024 Tj
--321 TJm
-(you) 14.9439 Tj
--322 TJm
-(to) 7.7509 Tj
-72 356.48 Td
-(b) 4.9813 Tj
-20 TJm
-(uild) 15.5018 Tj
--321 TJm
-(the) 12.1743 Tj
--321 TJm
-(library) 26.5603 Tj
--322 TJm
-(in) 7.7509 Tj
--321 TJm
-(a) 4.42339 Tj
--321 TJm
-(strictly) 27.6761 Tj
--321 TJm
-(ANSI) 23.2427 Tj
--321 TJm
-(compliant) 39.8504 Tj
--322 TJm
-(en) 9.40469 Tj
-40 TJm
-(vironment.) 43.4469 Tj
--1047 TJm
-(Building) 34.8791 Tj
--321 TJm
-(the) 12.1743 Tj
--321 TJm
-(program) 33.7533 Tj
--322 TJm
-(itself) 19.9252 Tj
--321 TJm
-(lik) 10.5205 Tj
-10 TJm
-(e) 4.42339 Tj
--321 TJm
-(this) 14.396 Tj
--321 TJm
-(is) 6.64505 Tj
--321 TJm
-(dangerous) 40.9463 Tj
--322 TJm
-(and) 14.386 Tj
-72 344.525 Td
-(not) 12.7322 Tj
--260 TJm
-(supported,) 41.7831 Tj
--263 TJm
-(since) 20.4731 Tj
--260 TJm
-(you) 14.9439 Tj
--260 TJm
-(remo) 20.4731 Tj
-15 TJm
-(v) 4.9813 Tj
-15 TJm
-(e) 4.42339 Tj
-[1 0 0 1 204.498 344.525] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -204.498 -344.525] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-204.498 344.525 Td
-/F134_0 9.9626 Tf
-(bzip2) 29.8878 Tj
-[1 0 0 1 234.386 344.525] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -234.386 -344.525] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-234.386 344.525 Td
-/F130_0 9.9626 Tf
-(') 3.31755 Tj
-55 TJm
-(s) 3.87545 Tj
--260 TJm
-(checks) 27.1082 Tj
--260 TJm
-(ag) 9.40469 Tj
-5 TJm
-(ainst) 18.8194 Tj
--261 TJm
-(compressi) 40.3983 Tj
-1 TJm
-(ng) 9.9626 Tj
--261 TJm
-(directories,) 44.5428 Tj
--262 TJm
-(symbolic) 36.5329 Tj
--261 TJm
-(links,) 21.8679 Tj
--262 TJm
-(de) 9.40469 Tj
-25 TJm
-(vices,) 22.9638 Tj
--263 TJm
-(and) 14.386 Tj
--260 TJm
-(other) 20.4731 Tj
-72 332.57 Td
-(not-really-a-\002le) 62.5253 Tj
--250 TJm
-(entities.) 31.2726 Tj
--620 TJm
-(This) 17.7135 Tj
--250 TJm
-(could) 22.1369 Tj
--250 TJm
-(cause) 22.1269 Tj
--250 TJm
-(\002lesystem) 40.4083 Tj
--250 TJm
-(corruption!) 44.8217 Tj
-[1 0 0 1 72 330.413] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.9626] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -320.45] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 310.652 Td
-/F130_0 9.9626 Tf
-(One) 16.5977 Tj
--392 TJm
-(other) 20.4731 Tj
--391 TJm
-(thing:) 23.2527 Tj
--594 TJm
-(if) 6.08715 Tj
--391 TJm
-(you) 14.9439 Tj
--392 TJm
-(create) 23.7807 Tj
--391 TJm
-(a) 4.42339 Tj
-[1 0 0 1 210.879 310.652] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -210.879 -310.652] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-210.879 310.652 Td
-/F134_0 9.9626 Tf
-(bzip2) 29.8878 Tj
-[1 0 0 1 240.767 310.652] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -240.767 -310.652] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-244.669 310.652 Td
-/F130_0 9.9626 Tf
-(binary) 25.4544 Tj
--392 TJm
-(for) 11.6164 Tj
--391 TJm
-(public) 24.9065 Tj
--392 TJm
-(distrib) 25.4644 Tj
-20 TJm
-(ution,) 22.9738 Tj
--427 TJm
-(please) 24.8965 Tj
--392 TJm
-(consider) 33.7533 Tj
--391 TJm
-(linking) 28.234 Tj
--392 TJm
-(it) 5.53921 Tj
--391 TJm
-(statically) 35.9749 Tj
--392 TJm
-(\() 3.31755 Tj
-[1 0 0 1 522.067 310.652] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -522.067 -310.652] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-522.067 310.652 Td
-/F134_0 9.9626 Tf
-(gcc) 17.9327 Tj
-72 298.697 Td
-(-static) 41.8429 Tj
-[1 0 0 1 113.843 298.697] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -113.843 -298.697] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-113.843 298.697 Td
-/F130_0 9.9626 Tf
-(\).) 5.8082 Tj
--620 TJm
-(This) 17.7135 Tj
--250 TJm
-(a) 4.42339 Tj
-20 TJm
-(v) 4.9813 Tj
-20 TJm
-(oids) 16.6077 Tj
--250 TJm
-(all) 9.9626 Tj
--250 TJm
-(sorts) 18.8194 Tj
--250 TJm
-(of) 8.29885 Tj
--250 TJm
-(library-v) 34.8591 Tj
-15 TJm
-(ersion) 24.3486 Tj
--250 TJm
-(issues) 23.8007 Tj
--250 TJm
-(that) 14.9439 Tj
--250 TJm
-(others) 24.3486 Tj
--250 TJm
-(may) 17.1556 Tj
--250 TJm
-(encounter) 39.2825 Tj
--250 TJm
-(later) 17.7035 Tj
--250 TJm
-(on.) 12.4533 Tj
-[1 0 0 1 72 296.54] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.9627] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -286.577] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 276.779 Td
-/F130_0 9.9626 Tf
-(If) 6.63509 Tj
--296 TJm
-(you) 14.9439 Tj
--296 TJm
-(b) 4.9813 Tj
-20 TJm
-(uild) 15.5018 Tj
-[1 0 0 1 122.709 276.779] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -122.709 -276.779] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-122.709 276.779 Td
-/F134_0 9.9626 Tf
-(bzip2) 29.8878 Tj
-[1 0 0 1 152.596 276.779] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -152.596 -276.779] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-155.545 276.779 Td
-/F130_0 9.9626 Tf
-(on) 9.9626 Tj
--296 TJm
-(W) 9.40469 Tj
-40 TJm
-(in32,) 20.2042 Tj
--307 TJm
-(you) 14.9439 Tj
--296 TJm
-(must) 19.3773 Tj
--296 TJm
-(set) 11.0684 Tj
-[1 0 0 1 254.965 276.779] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -254.965 -276.779] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-254.965 276.779 Td
-/F134_0 9.9626 Tf
-(BZ_UNIX) 41.8429 Tj
-[1 0 0 1 296.808 276.779] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -296.808 -276.779] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-299.756 276.779 Td
-/F130_0 9.9626 Tf
-(to) 7.7509 Tj
--296 TJm
-(0) 4.9813 Tj
--296 TJm
-(and) 14.386 Tj
-[1 0 0 1 335.72 276.779] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -335.72 -276.779] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-335.72 276.779 Td
-/F134_0 9.9626 Tf
-(BZ_LCCWIN32) 65.7532 Tj
-[1 0 0 1 401.473 276.779] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -401.473 -276.779] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-404.422 276.779 Td
-/F130_0 9.9626 Tf
-(to) 7.7509 Tj
--296 TJm
-(1,) 7.47195 Tj
--307 TJm
-(in) 7.7509 Tj
--296 TJm
-(the) 12.1743 Tj
--296 TJm
-(\002le) 12.7322 Tj
-[1 0 0 1 467.159 276.779] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -467.159 -276.779] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-467.159 276.779 Td
-/F134_0 9.9626 Tf
-(bzip2.c) 41.8429 Tj
-[1 0 0 1 509.002 276.779] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -509.002 -276.779] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-509.002 276.779 Td
-/F130_0 9.9626 Tf
-(,) 2.49065 Tj
--307 TJm
-(before) 25.4445 Tj
-72 264.824 Td
-(compiling.) 42.899 Tj
--310 TJm
-(Otherwise) 40.9463 Tj
--250 TJm
-(the) 12.1743 Tj
--250 TJm
-(resulting) 34.8691 Tj
--250 TJm
-(binary) 25.4544 Tj
--250 TJm
-(w) 7.193 Tj
-10 TJm
-(on') 13.2801 Tj
-18 TJm
-(t) 2.7696 Tj
--250 TJm
-(w) 7.193 Tj
-10 TJm
-(ork) 13.2801 Tj
--250 TJm
-(correctly) 35.4071 Tj
-65 TJm
-(.) 2.49065 Tj
-[1 0 0 1 72 262.667] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.9626] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -252.704] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 230.071 Td
-/F122_0 20.6585 Tf
-(4.3.) 34.4584 Tj
--278 TJm
-(Repor) 59.6824 Tj
--20 TJm
-(ting) 37.867 Tj
--278 TJm
-(b) 12.6223 Tj
-20 TJm
-(ugs) 36.7308 Tj
-[1 0 0 1 72 225.474] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.9626] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -215.512] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 208.153 Td
-/F130_0 9.9626 Tf
-(I) 3.31755 Tj
--228 TJm
-(tried) 18.2614 Tj
--228 TJm
-(pretty) 23.2427 Tj
--228 TJm
-(hard) 17.7035 Tj
--228 TJm
-(to) 7.7509 Tj
--228 TJm
-(mak) 17.1556 Tj
-10 TJm
-(e) 4.42339 Tj
--228 TJm
-(sure) 16.5977 Tj
-[1 0 0 1 196.25 208.153] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -196.25 -208.153] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-196.25 208.153 Td
-/F134_0 9.9626 Tf
-(bzip2) 29.8878 Tj
-[1 0 0 1 226.138 208.153] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -226.138 -208.153] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-228.409 208.153 Td
-/F130_0 9.9626 Tf
-(is) 6.64505 Tj
--228 TJm
-(b) 4.9813 Tj
-20 TJm
-(ug) 9.9626 Tj
--228 TJm
-(free,) 17.9725 Tj
--232 TJm
-(both) 17.7135 Tj
--228 TJm
-(by) 9.9626 Tj
--228 TJm
-(design) 26.0123 Tj
--228 TJm
-(and) 14.386 Tj
--228 TJm
-(by) 9.9626 Tj
--228 TJm
-(testing.) 29.0609 Tj
--605 TJm
-(Hopefully) 40.3983 Tj
--228 TJm
-(you') 18.2614 Tj
-10 TJm
-(ll) 5.53921 Tj
--228 TJm
-(ne) 9.40469 Tj
-25 TJm
-(v) 4.9813 Tj
-15 TJm
-(er) 7.74094 Tj
--228 TJm
-(need) 18.8094 Tj
--228 TJm
-(to) 7.7509 Tj
--228 TJm
-(read) 17.1456 Tj
-72 196.198 Td
-(this) 14.396 Tj
--250 TJm
-(section) 28.224 Tj
--250 TJm
-(for) 11.6164 Tj
--250 TJm
-(real.) 17.4246 Tj
-[1 0 0 1 72 196.098] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.9627] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -186.136] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 174.28 Td
-/F130_0 9.9626 Tf
-(Ne) 11.6164 Tj
-25 TJm
-(v) 4.9813 Tj
-15 TJm
-(ertheless,) 37.3498 Tj
--313 TJm
-(if) 6.08715 Tj
-[1 0 0 1 137.751 174.28] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -137.751 -174.28] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-137.751 174.28 Td
-/F134_0 9.9626 Tf
-(bzip2) 29.8878 Tj
-[1 0 0 1 167.639 174.28] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -167.639 -174.28] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-170.634 174.28 Td
-/F130_0 9.9626 Tf
-(dies) 16.0497 Tj
--301 TJm
-(with) 17.7135 Tj
--300 TJm
-(a) 4.42339 Tj
--301 TJm
-(se) 8.29885 Tj
-15 TJm
-(gmentation) 44.8317 Tj
--300 TJm
-(f) 3.31755 Tj
-10 TJm
-(ault,) 17.4346 Tj
--314 TJm
-(a) 4.42339 Tj
--300 TJm
-(b) 4.9813 Tj
-20 TJm
-(us) 8.85675 Tj
--301 TJm
-(error) 19.3573 Tj
--300 TJm
-(or) 8.29885 Tj
--301 TJm
-(an) 9.40469 Tj
--301 TJm
-(internal) 30.4357 Tj
--300 TJm
-(assertion) 35.417 Tj
--301 TJm
-(f) 3.31755 Tj
-10 TJm
-(ailure,) 25.1755 Tj
--313 TJm
-(it) 5.53921 Tj
--301 TJm
-(wil) 12.7322 Tj
-1 TJm
-(l) 2.7696 Tj
--301 TJm
-(ask) 13.2801 Tj
--301 TJm
-(you) 14.9439 Tj
--300 TJm
-(to) 7.7509 Tj
-72 162.325 Td
-(email) 22.1369 Tj
--242 TJm
-(me) 12.1743 Tj
--243 TJm
-(a) 4.42339 Tj
--242 TJm
-(b) 4.9813 Tj
-20 TJm
-(ug) 9.9626 Tj
--243 TJm
-(report.) 26.2813 Tj
--615 TJm
-(Experience) 44.8118 Tj
--242 TJm
-(from) 19.3673 Tj
--243 TJm
-(years) 21.0211 Tj
--242 TJm
-(of) 8.29885 Tj
--242 TJm
-(feedback) 35.955 Tj
--243 TJm
-(of) 8.29885 Tj
--242 TJm
-(bzip2) 22.1369 Tj
--243 TJm
-(users) 20.4731 Tj
--242 TJm
-(indicates) 35.417 Tj
--243 TJm
-(that) 14.9439 Tj
--242 TJm
-(almost) 26.5703 Tj
--242 TJm
-(all) 9.9626 Tj
--243 TJm
-(these) 20.4731 Tj
--242 TJm
-(problems) 37.0808 Tj
--243 TJm
-(can) 13.8281 Tj
-72 150.37 Td
-(be) 9.40469 Tj
--250 TJm
-(traced) 24.3386 Tj
--250 TJm
-(to) 7.7509 Tj
--250 TJm
-(either) 22.6848 Tj
--250 TJm
-(compiler) 35.417 Tj
--250 TJm
-(b) 4.9813 Tj
-20 TJm
-(ugs) 13.8381 Tj
--250 TJm
-(or) 8.29885 Tj
--250 TJm
-(hardw) 24.8965 Tj
-10 TJm
-(are) 12.1643 Tj
--250 TJm
-(problems.) 39.5714 Tj
-[1 0 0 1 72 148.213] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -97.3611] cm
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-[1 0 0 1 1.8929 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 374.394 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 6.8541] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 40.5726 -6.7545] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -493.841 -50.9514] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-534.414 50.9514 Td
-/F130_0 9.9626 Tf
-(32) 9.9626 Tj
-[1 0 0 1 453.269 50.8518] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 93.5985 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 6.2765 0] cm
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-[1 0 0 1 -13.1436 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-Q
-showpage
-%%PageTrailer
-pdfEndPage
-%%Page: 36 36
-%%BeginPageSetup
-%%PageOrientation: Portrait
-pdfStartPage
-0 0 612 792 re W
-%%EndPageSetup
-[] 0 d
-1 i
-0 j
-0 J
-10 M
-1 w
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-false op
-false OP
-0 0 612 792 re
-W
-q
-[1 0 0 1 72 741.554] cm
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-[1 0 0 1 1.8929 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 14.4459] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 187.197 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 -6.8541] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 6.8541] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 116.328 -6.7546] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -382.4 -749.245] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-498.728 749.245 Td
-/F130_0 9.9626 Tf
-(Miscellanea) 48.1393 Tj
-[1 0 0 1 266.071 749.146] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 280.796 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -472.974 -7.0936] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -0.4981] cm
-q
-[] 0 d
-0 J
-0.4981 w
-0 0.2491 m
-475.465 0.2491 l
-S
-Q
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 479.251 0] cm
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-[1 0 0 1 -13.1436 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -468 -31.5168] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 6.9739 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -78.9739 -710.037] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-78.9739 710.037 Td
-/F130_0 9.9626 Tf
-(\225) 3.48691 Tj
-[1 0 0 1 82.4608 710.037] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 1.9925 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -86.944 -710.037] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-86.944 710.037 Td
-/F130_0 9.9626 Tf
-(Recompile) 43.1679 Tj
--306 TJm
-(the) 12.1743 Tj
--306 TJm
-(program) 33.7533 Tj
--306 TJm
-(with) 17.7135 Tj
--306 TJm
-(no) 9.9626 Tj
--306 TJm
-(optimisation,) 52.3136 Tj
--320 TJm
-(and) 14.386 Tj
--306 TJm
-(see) 12.7222 Tj
--306 TJm
-(if) 6.08715 Tj
--306 TJm
-(it) 5.53921 Tj
--306 TJm
-(w) 7.193 Tj
-10 TJm
-(orks.) 19.6462 Tj
--956 TJm
-(And/or) 28.224 Tj
--306 TJm
-(try) 11.0684 Tj
--306 TJm
-(a) 4.42339 Tj
--306 TJm
-(dif) 11.0684 Tj
-25 TJm
-(ferent) 23.2328 Tj
--306 TJm
-(compiler) 35.417 Tj
-55 TJm
-(.) 2.49065 Tj
--956 TJm
-(I) 3.31755 Tj
--306 TJm
-(heard) 22.1269 Tj
--306 TJm
-(all) 9.9626 Tj
-86.944 698.082 Td
-(sorts) 18.8194 Tj
--282 TJm
-(of) 8.29885 Tj
--282 TJm
-(stories) 26.0123 Tj
--282 TJm
-(about) 22.1369 Tj
--283 TJm
-(v) 4.9813 Tj
-25 TJm
-(arious) 24.3486 Tj
--282 TJm
-(\003a) 9.9626 Tj
-20 TJm
-(v) 4.9813 Tj
-20 TJm
-(ours) 17.1556 Tj
--282 TJm
-(of) 8.29885 Tj
--282 TJm
-(GNU) 21.579 Tj
--282 TJm
-(C) 6.64505 Tj
--282 TJm
-(\(and) 17.7035 Tj
--282 TJm
-(other) 20.4731 Tj
--283 TJm
-(compilers\)) 42.61 Tj
--282 TJm
-(generating) 42.0521 Tj
--282 TJm
-(bad) 14.386 Tj
--282 TJm
-(code) 18.8094 Tj
--282 TJm
-(for) 11.6164 Tj
-[1 0 0 1 472.141 698.082] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -472.141 -698.082] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-472.141 698.082 Td
-/F134_0 9.9626 Tf
-(bzip2) 29.8878 Tj
-[1 0 0 1 502.029 698.082] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -502.029 -698.082] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-502.029 698.082 Td
-/F130_0 9.9626 Tf
-(,) 2.49065 Tj
--290 TJm
-(and) 14.386 Tj
--282 TJm
-(I') 6.63509 Tj
-50 TJm
-(v) 4.9813 Tj
-15 TJm
-(e) 4.42339 Tj
-86.944 686.127 Td
-(run) 13.2801 Tj
--250 TJm
-(across) 24.8965 Tj
--250 TJm
-(tw) 9.9626 Tj
-10 TJm
-(o) 4.9813 Tj
--250 TJm
-(such) 18.2614 Tj
--250 TJm
-(e) 4.42339 Tj
-15 TJm
-(xamples) 33.2053 Tj
--250 TJm
-(myself.) 29.6088 Tj
-[1 0 0 1 237.767 686.127] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -165.767 -12.1195] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -674.007] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-86.944 664.209 Td
-/F130_0 9.9626 Tf
-(2.7.X) 22.1369 Tj
--280 TJm
-(v) 4.9813 Tj
-15 TJm
-(ersions) 28.224 Tj
--279 TJm
-(of) 8.29885 Tj
--280 TJm
-(GNU) 21.579 Tj
--279 TJm
-(C) 6.64505 Tj
--280 TJm
-(are) 12.1643 Tj
--279 TJm
-(kno) 14.9439 Tj
-25 TJm
-(wn) 12.1743 Tj
--280 TJm
-(to) 7.7509 Tj
--280 TJm
-(generate) 33.7433 Tj
--279 TJm
-(bad) 14.386 Tj
--280 TJm
-(code) 18.8094 Tj
--279 TJm
-(from) 19.3673 Tj
--280 TJm
-(time) 17.7135 Tj
--279 TJm
-(to) 7.7509 Tj
--280 TJm
-(time,) 20.2042 Tj
--287 TJm
-(at) 7.193 Tj
--280 TJm
-(high) 17.7135 Tj
--279 TJm
-(optimisation) 49.823 Tj
--280 TJm
-(le) 7.193 Tj
-25 TJm
-(v) 4.9813 Tj
-15 TJm
-(els.) 13.5591 Tj
--797 TJm
-(If) 6.63509 Tj
--280 TJm
-(you) 14.9439 Tj
-86.944 652.254 Td
-(get) 12.1743 Tj
--295 TJm
-(problems,) 39.5714 Tj
--307 TJm
-(try) 11.0684 Tj
--296 TJm
-(using) 21.589 Tj
--295 TJm
-(the) 12.1743 Tj
--296 TJm
-(\003ags) 18.8194 Tj
-[1 0 0 1 220.116 652.254] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -220.116 -652.254] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-220.116 652.254 Td
-/F134_0 9.9626 Tf
-(-O2) 17.9327 Tj
-[1 0 0 1 238.049 652.254] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.9438 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -240.993 -652.254] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-240.993 652.254 Td
-/F134_0 9.9626 Tf
-(-fomit-frame-pointer) 119.551 Tj
-[1 0 0 1 360.544 652.254] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.9438 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -363.488 -652.254] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-363.488 652.254 Td
-/F134_0 9.9626 Tf
-(-fno-strength-reduce) 119.551 Tj
-[1 0 0 1 483.04 652.254] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -483.04 -652.254] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-483.04 652.254 Td
-/F130_0 9.9626 Tf
-(.) 2.49065 Tj
--893 TJm
-(Y) 7.193 Tj
-110 TJm
-(ou) 9.9626 Tj
--295 TJm
-(should) 26.5703 Tj
-86.944 640.299 Td
-(speci\002cally) 45.3796 Tj
-[1 0 0 1 134.814 640.299] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -134.814 -640.299] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-134.814 640.299 Td
-/F637_0 9.9626 Tf
-(not) 12.7322 Tj
-[1 0 0 1 147.546 640.299] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -147.546 -640.299] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-150.036 640.299 Td
-/F130_0 9.9626 Tf
-(use) 13.2801 Tj
-[1 0 0 1 165.807 640.299] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -165.807 -640.299] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-165.807 640.299 Td
-/F134_0 9.9626 Tf
-(-funroll-loops) 83.6858 Tj
-[1 0 0 1 249.493 640.299] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -249.493 -640.299] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-249.493 640.299 Td
-/F130_0 9.9626 Tf
-(.) 2.49065 Tj
-[1 0 0 1 72 638.142] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.9626] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -628.179] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-86.944 618.381 Td
-/F130_0 9.9626 Tf
-(Y) 7.193 Tj
-110 TJm
-(ou) 9.9626 Tj
--249 TJm
-(may) 17.1556 Tj
--249 TJm
-(notice) 24.3486 Tj
--248 TJm
-(that) 14.9439 Tj
--249 TJm
-(the) 12.1743 Tj
--249 TJm
-(Mak) 18.2614 Tj
-10 TJm
-(e\002le) 17.1556 Tj
--249 TJm
-(runs) 17.1556 Tj
--248 TJm
-(six) 11.6264 Tj
--249 TJm
-(tests) 17.7135 Tj
--249 TJm
-(as) 8.29885 Tj
--249 TJm
-(part) 15.4918 Tj
--249 TJm
-(of) 8.29885 Tj
--248 TJm
-(the) 12.1743 Tj
--249 TJm
-(b) 4.9813 Tj
-20 TJm
-(uild) 15.5018 Tj
--249 TJm
-(process.) 32.3685 Tj
--619 TJm
-(If) 6.63509 Tj
--249 TJm
-(the) 12.1743 Tj
--249 TJm
-(program) 33.7533 Tj
--248 TJm
-(passes) 25.4544 Tj
--249 TJm
-(all) 9.9626 Tj
--249 TJm
-(of) 8.29885 Tj
--249 TJm
-(these,) 22.9638 Tj
--249 TJm
-(it') 8.85675 Tj
-55 TJm
-(s) 3.87545 Tj
-86.944 606.426 Td
-(a) 4.42339 Tj
--250 TJm
-(pretty) 23.2427 Tj
--250 TJm
-(good) 19.9252 Tj
--250 TJm
-(\(b) 8.29885 Tj
-20 TJm
-(ut) 7.7509 Tj
--250 TJm
-(not) 12.7322 Tj
--250 TJm
-(100%\)) 26.5603 Tj
--250 TJm
-(indication) 39.8504 Tj
--250 TJm
-(that) 14.9439 Tj
--250 TJm
-(the) 12.1743 Tj
--250 TJm
-(compiler) 35.417 Tj
--250 TJm
-(has) 13.2801 Tj
--250 TJm
-(done) 19.3673 Tj
--250 TJm
-(its) 9.41466 Tj
--250 TJm
-(job) 12.7322 Tj
--250 TJm
-(correctly) 35.4071 Tj
-65 TJm
-(.) 2.49065 Tj
-[1 0 0 1 72 604.269] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -19.761] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 6.9739 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -78.9739 -584.508] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-78.9739 584.508 Td
-/F130_0 9.9626 Tf
-(\225) 3.48691 Tj
-[1 0 0 1 82.4608 584.508] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 1.9925 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -86.944 -584.508] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-86.944 584.508 Td
-/F130_0 9.9626 Tf
-(If) 6.63509 Tj
-[1 0 0 1 95.9558 584.508] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -95.9558 -584.508] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-95.9558 584.508 Td
-/F134_0 9.9626 Tf
-(bzip2) 29.8878 Tj
-[1 0 0 1 125.844 584.508] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -125.844 -584.508] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-128.22 584.508 Td
-/F130_0 9.9626 Tf
-(crashes) 29.3199 Tj
--239 TJm
-(randomly) 38.1866 Tj
-65 TJm
-(,) 2.49065 Tj
--240 TJm
-(and) 14.386 Tj
--239 TJm
-(the) 12.1743 Tj
--239 TJm
-(crashe) 25.4445 Tj
-1 TJm
-(s) 3.87545 Tj
--239 TJm
-(are) 12.1643 Tj
--239 TJm
-(not) 12.7322 Tj
--238 TJm
-(repeatable,) 43.427 Tj
--241 TJm
-(you) 14.9439 Tj
--239 TJm
-(may) 17.1556 Tj
--238 TJm
-(ha) 9.40469 Tj
-20 TJm
-(v) 4.9813 Tj
-15 TJm
-(e) 4.42339 Tj
--239 TJm
-(a) 4.42339 Tj
--238 TJm
-(\003ak) 14.9439 Tj
-15 TJm
-(y) 4.9813 Tj
--239 TJm
-(memory) 33.2053 Tj
--238 TJm
-(subsystem.) 44.0048 Tj
-[1 0 0 1 510.112 584.508] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -510.112 -584.508] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-510.112 584.508 Td
-/F134_0 9.9626 Tf
-(bzip2) 29.8878 Tj
-[1 0 0 1 540 584.508] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -540 -584.508] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-86.944 572.553 Td
-/F130_0 9.9626 Tf
-(really) 22.6848 Tj
--254 TJm
-(hammers) 36.5229 Tj
--253 TJm
-(your) 18.2614 Tj
--254 TJm
-(memory) 33.2053 Tj
--253 TJm
-(hierarch) 32.6375 Tj
-5 TJm
-(y) 4.9813 Tj
-65 TJm
-(,) 2.49065 Tj
--255 TJm
-(and) 14.386 Tj
--253 TJm
-(if) 6.08715 Tj
--254 TJm
-(it') 8.85675 Tj
-55 TJm
-(s) 3.87545 Tj
--254 TJm
-(a) 4.42339 Tj
--253 TJm
-(bit) 10.5205 Tj
--254 TJm
-(mar) 15.4918 Tj
-18 TJm
-(ginal,) 22.4159 Tj
--254 TJm
-(you) 14.9439 Tj
--254 TJm
-(may) 17.1556 Tj
--253 TJm
-(get) 12.1743 Tj
--254 TJm
-(these) 20.4731 Tj
--253 TJm
-(problems.) 39.5714 Tj
--642 TJm
-(Ditto) 20.4831 Tj
--254 TJm
-(if) 6.08715 Tj
--253 TJm
-(your) 18.2614 Tj
--254 TJm
-(disk) 16.6077 Tj
-86.944 560.598 Td
-(or) 8.29885 Tj
--250 TJm
-(I/O) 13.2801 Tj
--250 TJm
-(subsystem) 41.5142 Tj
--250 TJm
-(is) 6.64505 Tj
--250 TJm
-(slo) 11.6264 Tj
-25 TJm
-(wly) 14.9439 Tj
--250 TJm
-(f) 3.31755 Tj
-10 TJm
-(ailing.) 25.1855 Tj
--620 TJm
-(Y) 7.193 Tj
-111 TJm
-(up,) 12.4533 Tj
--250 TJm
-(this) 14.396 Tj
--250 TJm
-(really) 22.6848 Tj
--250 TJm
-(does) 18.2614 Tj
--250 TJm
-(happen.) 31.2626 Tj
-[1 0 0 1 345.143 560.598] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -273.143 -12.1195] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -548.478] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-86.944 538.68 Td
-/F130_0 9.9626 Tf
-(T) 6.08715 Tj
-35 TJm
-(ry) 8.29885 Tj
--250 TJm
-(using) 21.589 Tj
--250 TJm
-(a) 4.42339 Tj
--250 TJm
-(dif) 11.0684 Tj
-25 TJm
-(ferent) 23.2328 Tj
--250 TJm
-(machine) 33.7533 Tj
--250 TJm
-(of) 8.29885 Tj
--250 TJm
-(the) 12.1743 Tj
--250 TJm
-(same) 20.4731 Tj
--250 TJm
-(type,) 19.6462 Tj
--250 TJm
-(and) 14.386 Tj
--250 TJm
-(see) 12.7222 Tj
--250 TJm
-(if) 6.08715 Tj
--250 TJm
-(you) 14.9439 Tj
--250 TJm
-(can) 13.8281 Tj
--250 TJm
-(repeat) 24.3386 Tj
--250 TJm
-(the) 12.1743 Tj
--250 TJm
-(problem.) 35.696 Tj
-[1 0 0 1 72 536.523] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -19.761] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 6.9739 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -78.9739 -516.762] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-78.9739 516.762 Td
-/F130_0 9.9626 Tf
-(\225) 3.48691 Tj
-[1 0 0 1 82.4608 516.762] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 1.9925 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -86.944 -516.762] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-86.944 516.762 Td
-/F130_0 9.9626 Tf
-(This) 17.7135 Tj
--229 TJm
-(isn') 14.9439 Tj
-18 TJm
-(t) 2.7696 Tj
--230 TJm
-(really) 22.6848 Tj
--229 TJm
-(a) 4.42339 Tj
--229 TJm
-(b) 4.9813 Tj
-20 TJm
-(ug,) 12.4533 Tj
--234 TJm
-(b) 4.9813 Tj
-20 TJm
-(ut) 7.7509 Tj
--229 TJm
-(...) 7.47195 Tj
--303 TJm
-(If) 6.63509 Tj
-[1 0 0 1 212.232 516.762] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -212.232 -516.762] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-212.232 516.762 Td
-/F134_0 9.9626 Tf
-(bzip2) 29.8878 Tj
-[1 0 0 1 242.12 516.762] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -242.12 -516.762] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-244.405 516.762 Td
-/F130_0 9.9626 Tf
-(tells) 16.6077 Tj
--229 TJm
-(you) 14.9439 Tj
--230 TJm
-(your) 18.2614 Tj
--229 TJm
-(\002le) 12.7322 Tj
--229 TJm
-(is) 6.64505 Tj
--230 TJm
-(corrupted) 38.1767 Tj
--229 TJm
-(on) 9.9626 Tj
--230 TJm
-(decompression,) 62.2563 Tj
--233 TJm
-(and) 14.386 Tj
--229 TJm
-(you) 14.9439 Tj
--230 TJm
-(obtained) 34.3112 Tj
--229 TJm
-(the) 12.1743 Tj
--229 TJm
-(\002le) 12.7322 Tj
-86.944 504.807 Td
-(via) 12.1743 Tj
--262 TJm
-(FTP) 17.1656 Tj
-111 TJm
-(,) 2.49065 Tj
--263 TJm
-(there) 19.9152 Tj
--262 TJm
-(is) 6.64505 Tj
--262 TJm
-(a) 4.42339 Tj
--262 TJm
-(possibility) 41.5241 Tj
--263 TJm
-(that) 14.9439 Tj
--262 TJm
-(you) 14.9439 Tj
--262 TJm
-(for) 11.6164 Tj
-18 TJm
-(got) 12.7322 Tj
--263 TJm
-(to) 7.7509 Tj
--262 TJm
-(tell) 12.7322 Tj
--262 TJm
-(FTP) 17.1656 Tj
--263 TJm
-(to) 7.7509 Tj
--262 TJm
-(do) 9.9626 Tj
--262 TJm
-(a) 4.42339 Tj
--262 TJm
-(binary) 25.4544 Tj
--263 TJm
-(mode) 22.1369 Tj
--262 TJm
-(transfer) 30.4258 Tj
-55 TJm
-(.) 2.49065 Tj
--694 TJm
-(That) 18.2614 Tj
--262 TJm
-(absolutely) 40.9562 Tj
--262 TJm
-(will) 15.5018 Tj
--263 TJm
-(cause) 22.1269 Tj
-86.944 492.852 Td
-(the) 12.1743 Tj
--250 TJm
-(\002le) 12.7322 Tj
--250 TJm
-(to) 7.7509 Tj
--250 TJm
-(be) 9.40469 Tj
--250 TJm
-(non-decompressible.) 82.7294 Tj
--620 TJm
-(Y) 7.193 Tj
-110 TJm
-(ou') 13.2801 Tj
-10 TJm
-(ll) 5.53921 Tj
--250 TJm
-(ha) 9.40469 Tj
-20 TJm
-(v) 4.9813 Tj
-15 TJm
-(e) 4.42339 Tj
--250 TJm
-(to) 7.7509 Tj
--250 TJm
-(transfer) 30.4258 Tj
--250 TJm
-(it) 5.53921 Tj
--250 TJm
-(ag) 9.40469 Tj
-5 TJm
-(ain.) 14.6649 Tj
-[1 0 0 1 351.34 492.852] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -279.34 -12.1195] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -480.732] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 470.934 Td
-/F130_0 9.9626 Tf
-(If) 6.63509 Tj
--235 TJm
-(you') 18.2614 Tj
-50 TJm
-(v) 4.9813 Tj
-15 TJm
-(e) 4.42339 Tj
--236 TJm
-(incor) 20.4731 Tj
-1 TJm
-(p) 4.9813 Tj
--1 TJm
-(or) 8.29885 Tj
-1 TJm
-(ated) 16.5977 Tj
-[1 0 0 1 163.036 470.934] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -163.036 -470.934] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-163.036 470.934 Td
-/F134_0 9.9626 Tf
-(libbzip2) 47.8205 Tj
-[1 0 0 1 210.856 470.934] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -210.856 -470.934] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-213.2 470.934 Td
-/F130_0 9.9626 Tf
-(into) 15.5018 Tj
--235 TJm
-(your) 18.2614 Tj
--235 TJm
-(o) 4.9813 Tj
-25 TJm
-(wn) 12.1743 Tj
--236 TJm
-(program) 33.7533 Tj
--235 TJm
-(and) 14.386 Tj
--235 TJm
-(are) 12.1643 Tj
--236 TJm
-(get) 12.1743 Tj
-1 TJm
-(ting) 15.5018 Tj
--236 TJm
-(problems,) 39.5714 Tj
--238 TJm
-(please,) 27.3872 Tj
--238 TJm
-(please,) 27.3872 Tj
--238 TJm
-(please,) 27.3872 Tj
--238 TJm
-(check) 23.2328 Tj
--236 TJm
-(that) 14.9439 Tj
-72 458.979 Td
-(the) 12.1743 Tj
--242 TJm
-(parameters) 43.7059 Tj
--243 TJm
-(you) 14.9439 Tj
--242 TJm
-(are) 12.1643 Tj
--242 TJm
-(passing) 29.8878 Tj
--243 TJm
-(in) 7.7509 Tj
--242 TJm
-(calls) 18.2614 Tj
--242 TJm
-(to) 7.7509 Tj
--243 TJm
-(the) 12.1743 Tj
--242 TJm
-(library) 26.5603 Tj
-65 TJm
-(,) 2.49065 Tj
--244 TJm
-(are) 12.1643 Tj
--242 TJm
-(correct,) 30.1468 Tj
--244 TJm
-(and) 14.386 Tj
--243 TJm
-(in) 7.7509 Tj
--242 TJm
-(accordance) 44.8018 Tj
--242 TJm
-(with) 17.7135 Tj
--243 TJm
-(what) 19.3673 Tj
--242 TJm
-(the) 12.1743 Tj
--242 TJm
-(documentation) 59.2177 Tj
--243 TJm
-(says) 17.1556 Tj
-72 447.024 Td
-(is) 6.64505 Tj
--250 TJm
-(allo) 14.9439 Tj
-25 TJm
-(w) 7.193 Tj
-10 TJm
-(able.) 19.0883 Tj
--310 TJm
-(I) 3.31755 Tj
--250 TJm
-(ha) 9.40469 Tj
-20 TJm
-(v) 4.9813 Tj
-15 TJm
-(e) 4.42339 Tj
--250 TJm
-(tried) 18.2614 Tj
--250 TJm
-(to) 7.7509 Tj
--250 TJm
-(mak) 17.1556 Tj
-10 TJm
-(e) 4.42339 Tj
--250 TJm
-(the) 12.1743 Tj
--250 TJm
-(library) 26.5603 Tj
--250 TJm
-(rob) 13.2801 Tj
-20 TJm
-(ust) 11.6264 Tj
--250 TJm
-(ag) 9.40469 Tj
-5 TJm
-(ainst) 18.8194 Tj
--250 TJm
-(such) 18.2614 Tj
--250 TJm
-(problems,) 39.5714 Tj
--250 TJm
-(b) 4.9813 Tj
-20 TJm
-(ut) 7.7509 Tj
--250 TJm
-(I'm) 14.386 Tj
--250 TJm
-(sure) 16.5977 Tj
--250 TJm
-(I) 3.31755 Tj
--250 TJm
-(ha) 9.40469 Tj
-20 TJm
-(v) 4.9813 Tj
-15 TJm
-(en') 12.7222 Tj
-18 TJm
-(t) 2.7696 Tj
--250 TJm
-(succeeded.) 43.427 Tj
-[1 0 0 1 72 444.867] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.9626] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -434.904] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 425.106 Td
-/F130_0 9.9626 Tf
-(Finally) 28.234 Tj
-65 TJm
-(,) 2.49065 Tj
--324 TJm
-(if) 6.08715 Tj
--310 TJm
-(the) 12.1743 Tj
--309 TJm
-(abo) 14.386 Tj
-15 TJm
-(v) 4.9813 Tj
-15 TJm
-(e) 4.42339 Tj
--309 TJm
-(comments) 40.9562 Tj
--310 TJm
-(don') 18.2614 Tj
-18 TJm
-(t) 2.7696 Tj
--309 TJm
-(help,) 19.6462 Tj
--324 TJm
-(you') 18.2614 Tj
-10 TJm
-(ll) 5.53921 Tj
--310 TJm
-(ha) 9.40469 Tj
-20 TJm
-(v) 4.9813 Tj
-15 TJm
-(e) 4.42339 Tj
--309 TJm
-(to) 7.7509 Tj
--309 TJm
-(send) 18.2614 Tj
--310 TJm
-(me) 12.1743 Tj
--309 TJm
-(a) 4.42339 Tj
--309 TJm
-(b) 4.9813 Tj
-20 TJm
-(ug) 9.9626 Tj
--310 TJm
-(report.) 26.2813 Tj
--976 TJm
-(No) 12.1743 Tj
-25 TJm
-(w) 7.193 Tj
-65 TJm
-(,) 2.49065 Tj
--324 TJm
-(it') 8.85675 Tj
-55 TJm
-(s) 3.87545 Tj
--310 TJm
-(just) 14.396 Tj
--309 TJm
-(amazing) 33.7533 Tj
--309 TJm
-(ho) 9.9626 Tj
-25 TJm
-(w) 7.193 Tj
--310 TJm
-(man) 17.1556 Tj
-15 TJm
-(y) 4.9813 Tj
-72 413.151 Td
-(people) 26.5603 Tj
--250 TJm
-(will) 15.5018 Tj
--250 TJm
-(send) 18.2614 Tj
--250 TJm
-(me) 12.1743 Tj
--250 TJm
-(a) 4.42339 Tj
--250 TJm
-(b) 4.9813 Tj
-20 TJm
-(ug) 9.9626 Tj
--250 TJm
-(report) 23.7907 Tj
--250 TJm
-(saying) 26.0123 Tj
--250 TJm
-(something) 41.5142 Tj
--250 TJm
-(lik) 10.5205 Tj
-10 TJm
-(e:) 7.193 Tj
-[1 0 0 1 72 410.994] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -24.9066] cm
-/DeviceRGB {} cs
-[0.94899 0.94899 0.976456] sc
-/DeviceRGB {} CS
-[0.94899 0.94899 0.976456] SC
-0 0 468 23.9103 re
-f
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 3.5866] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 20.3237] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 18 -8.3685] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -90 -401.629] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-90 401.629 Td
-/F134_0 9.9626 Tf
-(bzip2) 29.8878 Tj
--426 TJm
-(crashed) 41.8429 Tj
--426 TJm
-(with) 23.9102 Tj
--426 TJm
-(segmentation) 71.7307 Tj
--426 TJm
-(fault) 29.8878 Tj
--426 TJm
-(on) 11.9551 Tj
--426 TJm
-(my) 11.9551 Tj
--426 TJm
-(machine) 41.8429 Tj
-[1 0 0 1 72 386.087] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 468 3.5866] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -468 -13.5492] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -376.125] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 364.169 Td
-/F130_0 9.9626 Tf
-(and) 14.386 Tj
--241 TJm
-(absolutely) 40.9562 Tj
--241 TJm
-(nothing) 30.4457 Tj
--241 TJm
-(el) 7.193 Tj
-1 TJm
-(se.) 10.7895 Tj
--614 TJm
-(Needless) 35.965 Tj
--241 TJm
-(to) 7.7509 Tj
--241 TJm
-(say) 13.2801 Tj
-65 TJm
-(,) 2.49065 Tj
--243 TJm
-(a) 4.42339 Tj
--241 TJm
-(such) 18.2614 Tj
--240 TJm
-(a) 4.42339 Tj
--241 TJm
-(report) 23.7907 Tj
--241 TJm
-(is) 6.64505 Tj
-[1 0 0 1 324.681 364.169] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -324.681 -364.169] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-324.681 364.169 Td
-/F637_0 9.9626 Tf
-(totally) 25.4644 Tj
-55 TJm
-(,) 2.49065 Tj
--243 TJm
-(utterly) 26.0123 Tj
-55 TJm
-(,) 2.49065 Tj
--242 TJm
-(completely) 43.158 Tj
--241 TJm
-(and) 14.9439 Tj
--241 TJm
-(compr) 25.4544 Tj
-37 TJm
-(ehensively) 41.4942 Tj
--241 TJm
-(100%) 23.2427 Tj
-72 352.214 Td
-(useless;) 31.5416 Tj
--257 TJm
-(a) 4.9813 Tj
--255 TJm
-(waste) 22.6948 Tj
--255 TJm
-(of) 7.7509 Tj
--255 TJm
-(your) 18.2614 Tj
--255 TJm
-(time) 17.1556 Tj
-10 TJm
-(,) 2.49065 Tj
--256 TJm
-(my) 11.6164 Tj
--255 TJm
-(time) 17.1556 Tj
-10 TJm
-(,) 2.49065 Tj
--256 TJm
-(and) 14.9439 Tj
--255 TJm
-(net) 12.1743 Tj
--255 TJm
-(bandwidth) 42.0721 Tj
-[1 0 0 1 302.574 352.214] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -302.574 -352.214] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-302.574 352.214 Td
-/F130_0 9.9626 Tf
-(.) 2.49065 Tj
--650 TJm
-(W) 9.40469 Tj
-40 TJm
-(ith) 10.5205 Tj
--254 TJm
-(no) 9.9626 Tj
--255 TJm
-(details) 26.0123 Tj
--255 TJm
-(at) 7.193 Tj
--255 TJm
-(all,) 12.4533 Tj
--256 TJm
-(there') 23.2328 Tj
-55 TJm
-(s) 3.87545 Tj
--255 TJm
-(no) 9.9626 Tj
--255 TJm
-(w) 7.193 Tj
-10 TJm
-(ay) 9.40469 Tj
--255 TJm
-(I) 3.31755 Tj
--255 TJm
-(can) 13.8281 Tj
--255 TJm
-(possibly) 33.2153 Tj
--255 TJm
-(be) 9.40469 Tj
-15 TJm
-(gin) 12.7322 Tj
-72 340.259 Td
-(to) 7.7509 Tj
--250 TJm
-(\002gure) 23.2427 Tj
--250 TJm
-(out) 12.7322 Tj
--250 TJm
-(what) 19.3673 Tj
--250 TJm
-(the) 12.1743 Tj
--250 TJm
-(problem) 33.2053 Tj
--250 TJm
-(is.) 9.1357 Tj
-[1 0 0 1 72 338.102] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.9627] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -328.14] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 318.341 Td
-/F130_0 9.9626 Tf
-(The) 15.4918 Tj
--309 TJm
-(rules) 19.3673 Tj
--309 TJm
-(of) 8.29885 Tj
--309 TJm
-(the) 12.1743 Tj
--310 TJm
-(g) 4.9813 Tj
-5 TJm
-(ame) 16.5977 Tj
--309 TJm
-(are:) 14.9339 Tj
--428 TJm
-(f) 3.31755 Tj
-10 TJm
-(acts,) 17.9825 Tj
--324 TJm
-(f) 3.31755 Tj
-10 TJm
-(acts,) 17.9825 Tj
--324 TJm
-(f) 3.31755 Tj
-10 TJm
-(acts.) 17.9825 Tj
--975 TJm
-(Don') 20.4731 Tj
-18 TJm
-(t) 2.7696 Tj
--309 TJm
-(omit) 18.2714 Tj
--309 TJm
-(them) 19.9252 Tj
--309 TJm
-(because) 31.5316 Tj
--309 TJm
-("oh,) 16.518 Tj
--324 TJm
-(the) 12.1743 Tj
-15 TJm
-(y) 4.9813 Tj
--309 TJm
-(w) 7.193 Tj
-10 TJm
-(on') 13.2801 Tj
-18 TJm
-(t) 2.7696 Tj
--309 TJm
-(be) 9.40469 Tj
--310 TJm
-(rele) 14.9339 Tj
-25 TJm
-(v) 4.9813 Tj
-25 TJm
-(ant".) 18.7297 Tj
--974 TJm
-(At) 9.9626 Tj
--310 TJm
-(the) 12.1743 Tj
--309 TJm
-(bare) 17.1456 Tj
-72 306.386 Td
-(minimum:) 41.5241 Tj
-[1 0 0 1 72 306.287] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -60.7721] cm
-/DeviceRGB {} cs
-[0.94899 0.94899 0.976456] sc
-/DeviceRGB {} CS
-[0.94899 0.94899 0.976456] SC
-0 0 468 59.7758 re
-f
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 3.5866] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 56.1892] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 18 -8.3686] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -90 -296.922] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-90 296.922 Td
-/F134_0 9.9626 Tf
-(Machine) 41.8429 Tj
--426 TJm
-(type.) 29.8878 Tj
--852 TJm
-(Operating) 53.798 Tj
--426 TJm
-(system) 35.8654 Tj
--426 TJm
-(version.) 47.8205 Tj
-90 284.967 Td
-(Exact) 29.8878 Tj
--426 TJm
-(version) 41.8429 Tj
--426 TJm
-(of) 11.9551 Tj
--426 TJm
-(bzip2) 29.8878 Tj
--426 TJm
-(\(do) 17.9327 Tj
--426 TJm
-(bzip2) 29.8878 Tj
--426 TJm
-(-V\).) 23.9102 Tj
-90 273.011 Td
-(Exact) 29.8878 Tj
--426 TJm
-(version) 41.8429 Tj
--426 TJm
-(of) 11.9551 Tj
--426 TJm
-(the) 17.9327 Tj
--426 TJm
-(compiler) 47.8205 Tj
--426 TJm
-(used.) 29.8878 Tj
-90 261.056 Td
-(Flags) 29.8878 Tj
--426 TJm
-(passed) 35.8654 Tj
--426 TJm
-(to) 11.9551 Tj
--426 TJm
-(the) 17.9327 Tj
--426 TJm
-(compiler.) 53.798 Tj
-[1 0 0 1 72 245.514] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 468 3.5866] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -468 -13.5492] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -235.552] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 223.597 Td
-/F130_0 9.9626 Tf
-(Ho) 12.1743 Tj
-25 TJm
-(we) 11.6164 Tj
-25 TJm
-(v) 4.9813 Tj
-15 TJm
-(er) 7.74094 Tj
-40 TJm
-(,) 2.49065 Tj
--254 TJm
-(the) 12.1743 Tj
--252 TJm
-(most) 19.3773 Tj
--253 TJm
-(important) 38.7446 Tj
--253 TJm
-(single) 23.8007 Tj
--253 TJm
-(thing) 20.4831 Tj
--253 TJm
-(t) 2.7696 Tj
-1 TJm
-(hat) 12.1743 Tj
--253 TJm
-(will) 15.5018 Tj
--253 TJm
-(help) 17.1556 Tj
--253 TJm
-(me) 12.1743 Tj
--253 TJm
-(is) 6.64505 Tj
--252 TJm
-(the) 12.1743 Tj
--253 TJm
-(\002le) 12.7322 Tj
--253 TJm
-(that) 14.9439 Tj
--253 TJm
-(you) 14.9439 Tj
--253 TJm
-(were) 19.3573 Tj
--253 TJm
-(trying) 23.8007 Tj
--252 TJm
-(to) 7.7509 Tj
--253 TJm
-(compress) 37.6287 Tj
--253 TJm
-(or) 8.29885 Tj
--253 TJm
-(decompress) 47.0334 Tj
-72 211.641 Td
-(at) 7.193 Tj
--304 TJm
-(the) 12.1743 Tj
--305 TJm
-(time) 17.7135 Tj
--304 TJm
-(the) 12.1743 Tj
--304 TJm
-(problem) 33.2053 Tj
--305 TJm
-(happened.) 40.6673 Tj
--946 TJm
-(W) 9.40469 Tj
-40 TJm
-(ithout) 23.2527 Tj
--304 TJm
-(that,) 17.4346 Tj
--318 TJm
-(my) 12.7322 Tj
--305 TJm
-(ability) 25.4644 Tj
--304 TJm
-(to) 7.7509 Tj
--304 TJm
-(do) 9.9626 Tj
--305 TJm
-(an) 9.40469 Tj
-15 TJm
-(ything) 25.4644 Tj
--304 TJm
-(more) 20.4731 Tj
--304 TJm
-(than) 17.1556 Tj
--305 TJm
-(speculate) 37.0708 Tj
--304 TJm
-(about) 22.1369 Tj
--304 TJm
-(the) 12.1743 Tj
--305 TJm
-(cause,) 24.6176 Tj
--318 TJm
-(is) 6.64505 Tj
-72 199.686 Td
-(limited.) 30.7247 Tj
-[1 0 0 1 72 199.587] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.9626] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -189.624] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 164.933 Td
-/F122_0 20.6585 Tf
-(4.4.) 34.4584 Tj
--278 TJm
-(Did) 33.2808 Tj
--278 TJm
-(y) 11.4861 Tj
-25 TJm
-(ou) 25.2447 Tj
--278 TJm
-(g) 12.6223 Tj
--10 TJm
-(et) 18.3654 Tj
--278 TJm
-(the) 30.9877 Tj
--278 TJm
-(right) 45.9032 Tj
--278 TJm
-(pac) 35.5946 Tj
-20 TJm
-(ka) 22.9723 Tj
-10 TJm
-(g) 12.6223 Tj
--10 TJm
-(e?) 24.1085 Tj
-[1 0 0 1 72 160.337] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.9626] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -150.374] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 143.016 Td
-/F134_0 9.9626 Tf
-(bzip2) 29.8878 Tj
-[1 0 0 1 101.888 143.016] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -101.888 -143.016] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-104.603 143.016 Td
-/F130_0 9.9626 Tf
-(is) 6.64505 Tj
--272 TJm
-(a) 4.42339 Tj
--273 TJm
-(resource) 33.7433 Tj
--272 TJm
-(hog.) 17.4346 Tj
--378 TJm
-(It) 6.08715 Tj
--272 TJm
-(soaks) 22.1369 Tj
--273 TJm
-(up) 9.9626 Tj
--272 TJm
-(lar) 10.5105 Tj
-18 TJm
-(ge) 9.40469 Tj
--273 TJm
-(amounts) 33.7633 Tj
--272 TJm
-(of) 8.29885 Tj
--273 TJm
-(CPU) 19.3773 Tj
--272 TJm
-(c) 4.42339 Tj
-15 TJm
-(ycles) 20.4731 Tj
--273 TJm
-(and) 14.386 Tj
--272 TJm
-(memory) 33.2053 Tj
-65 TJm
-(.) 2.49065 Tj
--755 TJm
-(Also,) 21.31 Tj
--278 TJm
-(it) 5.53921 Tj
--273 TJm
-(gi) 7.7509 Tj
-25 TJm
-(v) 4.9813 Tj
-15 TJm
-(es) 8.29885 Tj
--272 TJm
-(v) 4.9813 Tj
-15 TJm
-(ery) 12.7222 Tj
--273 TJm
-(lar) 10.5105 Tj
-18 TJm
-(ge) 9.40469 Tj
--272 TJm
-(latencies.) 37.3498 Tj
-72 131.06 Td
-(In) 8.29885 Tj
--251 TJm
-(the) 12.1743 Tj
--251 TJm
-(w) 7.193 Tj
-10 TJm
-(orst) 14.9439 Tj
--251 TJm
-(case,) 19.6363 Tj
--251 TJm
-(you) 14.9439 Tj
--251 TJm
-(can) 13.8281 Tj
--251 TJm
-(feed) 17.1456 Tj
--251 TJm
-(man) 17.1556 Tj
-15 TJm
-(y) 4.9813 Tj
--251 TJm
-(me) 12.1743 Tj
-15 TJm
-(g) 4.9813 Tj
-4 TJm
-(abyt) 17.1556 Tj
-1 TJm
-(es) 8.29885 Tj
--252 TJm
-(of) 8.29885 Tj
--251 TJm
-(uncompressed) 56.996 Tj
--251 TJm
-(data) 16.5977 Tj
--251 TJm
-(into) 15.5018 Tj
--251 TJm
-(the) 12.1743 Tj
--251 TJm
-(library) 26.5603 Tj
--251 TJm
-(before) 25.4445 Tj
--251 TJm
-(getting) 27.6761 Tj
--251 TJm
-(an) 9.40469 Tj
-15 TJm
-(y) 4.9813 Tj
--251 TJm
-(compressed) 47.0334 Tj
-72 119.105 Td
-(output,) 27.9551 Tj
--250 TJm
-(so) 8.85675 Tj
--250 TJm
-(this) 14.396 Tj
--250 TJm
-(probably) 35.417 Tj
--250 TJm
-(rules) 19.3673 Tj
--250 TJm
-(out) 12.7322 Tj
--250 TJm
-(applications) 48.1492 Tj
--250 TJm
-(requiring) 36.5229 Tj
--250 TJm
-(interacti) 32.6474 Tj
-25 TJm
-(v) 4.9813 Tj
-15 TJm
-(e) 4.42339 Tj
--250 TJm
-(beha) 18.8094 Tj
-20 TJm
-(viour) 21.031 Tj
-55 TJm
-(.) 2.49065 Tj
-[1 0 0 1 72 116.949] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.9627] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -106.986] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 97.1875 Td
-/F130_0 9.9626 Tf
-(These) 23.7907 Tj
--304 TJm
-(aren') 20.4632 Tj
-18 TJm
-(t) 2.7696 Tj
--304 TJm
-(f) 3.31755 Tj
-10 TJm
-(aults) 18.8194 Tj
--304 TJm
-(of) 8.29885 Tj
--304 TJm
-(my) 12.7322 Tj
--304 TJm
-(implementation,) 65.0359 Tj
--317 TJm
-(I) 3.31755 Tj
--304 TJm
-(hope,) 21.8579 Tj
--318 TJm
-(b) 4.9813 Tj
-20 TJm
-(ut) 7.7509 Tj
--304 TJm
-(more) 20.4731 Tj
--304 TJm
-(an) 9.40469 Tj
--304 TJm
-(intrinsic) 32.6574 Tj
--304 TJm
-(property) 33.7533 Tj
--304 TJm
-(of) 8.29885 Tj
--304 TJm
-(the) 12.1743 Tj
--304 TJm
-(Burro) 23.2427 Tj
-25 TJm
-(ws-Wheeler) 48.1293 Tj
--304 TJm
-(transform) 38.7346 Tj
-72 85.2323 Td
-(\(unfortunately\).) 62.8042 Tj
--620 TJm
-(Maybe) 27.6661 Tj
--250 TJm
-(this) 14.396 Tj
--250 TJm
-(isn') 14.9439 Tj
-18 TJm
-(t) 2.7696 Tj
--250 TJm
-(what) 19.3673 Tj
--250 TJm
-(you) 14.9439 Tj
--250 TJm
-(w) 7.193 Tj
-10 TJm
-(ant.) 14.6649 Tj
-[1 0 0 1 72 83.0755] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.9626] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -22.2611] cm
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-[1 0 0 1 1.8929 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 374.394 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 6.8541] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 40.5726 -6.7545] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -493.841 -50.9514] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-534.414 50.9514 Td
-/F130_0 9.9626 Tf
-(33) 9.9626 Tj
-[1 0 0 1 453.269 50.8518] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 93.5985 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 6.2765 0] cm
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-[1 0 0 1 -13.1436 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-Q
-showpage
-%%PageTrailer
-pdfEndPage
-%%Page: 37 37
-%%BeginPageSetup
-%%PageOrientation: Portrait
-pdfStartPage
-0 0 612 792 re W
-%%EndPageSetup
-[] 0 d
-1 i
-0 j
-0 J
-10 M
-1 w
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-false op
-false OP
-0 0 612 792 re
-W
-q
-[1 0 0 1 72 741.554] cm
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-[1 0 0 1 1.8929 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 14.4459] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 187.197 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 -6.8541] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 6.8541] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 116.328 -6.7546] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -382.4 -749.245] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-498.728 749.245 Td
-/F130_0 9.9626 Tf
-(Miscellanea) 48.1393 Tj
-[1 0 0 1 266.071 749.146] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 280.796 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -472.974 -7.0936] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -0.4981] cm
-q
-[] 0 d
-0 J
-0.4981 w
-0 0.2491 m
-475.465 0.2491 l
-S
-Q
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 479.251 0] cm
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-[1 0 0 1 -13.1436 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -540 -741.554] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 710.037 Td
-/F130_0 9.9626 Tf
-(If) 6.63509 Tj
--275 TJm
-(you) 14.9439 Tj
--274 TJm
-(w) 7.193 Tj
-10 TJm
-(ant) 12.1743 Tj
--275 TJm
-(a) 4.42339 Tj
--274 TJm
-(compressor) 45.9276 Tj
--275 TJm
-(and/or) 25.4544 Tj
--275 TJm
-(library) 26.5603 Tj
--274 TJm
-(which) 24.3486 Tj
--275 TJm
-(is) 6.64505 Tj
--274 TJm
-(f) 3.31755 Tj
-10 TJm
-(aster) 18.8094 Tj
-40 TJm
-(,) 2.49065 Tj
--281 TJm
-(uses) 17.1556 Tj
--275 TJm
-(less) 14.9439 Tj
--274 TJm
-(memory) 33.2053 Tj
--275 TJm
-(b) 4.9813 Tj
-20 TJm
-(ut) 7.7509 Tj
--275 TJm
-(gets) 16.0497 Tj
--274 TJm
-(pretty) 23.2427 Tj
--275 TJm
-(good) 19.9252 Tj
--274 TJm
-(compression,) 52.8516 Tj
--281 TJm
-(and) 14.386 Tj
--275 TJm
-(has) 13.2801 Tj
-72 698.082 Td
-(minimal) 33.2153 Tj
--288 TJm
-(latenc) 23.7907 Tj
-15 TJm
-(y) 4.9813 Tj
-65 TJm
-(,) 2.49065 Tj
--297 TJm
-(consider) 33.7533 Tj
--288 TJm
-(Jean-loup) 38.7346 Tj
--288 TJm
-(Gailly') 28.224 Tj
-55 TJm
-(s) 3.87545 Tj
--288 TJm
-(and) 14.386 Tj
--288 TJm
-(Mark) 21.579 Tj
--288 TJm
-(Adl) 14.9439 Tj
-1 TJm
-(er') 11.0585 Tj
-55 TJm
-(s) 3.87545 Tj
--288 TJm
-(w) 7.193 Tj
-10 TJm
-(ork,) 15.7708 Tj
-[1 0 0 1 353.879 698.082] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -353.879 -698.082] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-353.879 698.082 Td
-/F134_0 9.9626 Tf
-(zlib-1.2.1) 59.7756 Tj
-[1 0 0 1 413.655 698.082] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -413.655 -698.082] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-416.523 698.082 Td
-/F130_0 9.9626 Tf
-(and) 14.386 Tj
-[1 0 0 1 433.777 698.082] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -433.777 -698.082] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-433.777 698.082 Td
-/F134_0 9.9626 Tf
-(gzip-1.2.4) 59.7756 Tj
-[1 0 0 1 493.553 698.082] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -493.553 -698.082] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-493.553 698.082 Td
-/F130_0 9.9626 Tf
-(.) 2.49065 Tj
--847 TJm
-(Look) 21.031 Tj
--288 TJm
-(for) 11.6164 Tj
-72 686.127 Td
-(them) 19.9252 Tj
--250 TJm
-(at) 7.193 Tj
--250 TJm
-(http://www) 45.3896 Tj
-65 TJm
-(.zlib) 17.4346 Tj
-40 TJm
-(.or) 10.7895 Tj
-18 TJm
-(g) 4.9813 Tj
--250 TJm
-(and) 14.386 Tj
--250 TJm
-(http://www) 45.3896 Tj
-65 TJm
-(.gzip.or) 30.4357 Tj
-18 TJm
-(g) 4.9813 Tj
--250 TJm
-(respecti) 30.9837 Tj
-25 TJm
-(v) 4.9813 Tj
-15 TJm
-(ely) 12.1743 Tj
-65 TJm
-(.) 2.49065 Tj
-[1 0 0 1 72 683.97] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.9626] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -674.008] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 664.209 Td
-/F130_0 9.9626 Tf
-(F) 5.53921 Tj
-15 TJm
-(or) 8.29885 Tj
--582 TJm
-(something) 41.5142 Tj
--583 TJm
-(f) 3.31755 Tj
-10 TJm
-(aster) 18.8094 Tj
--582 TJm
-(and) 14.386 Tj
--582 TJm
-(lighter) 26.0123 Tj
--583 TJm
-(still,) 17.4445 Tj
--665 TJm
-(you) 14.9439 Tj
--582 TJm
-(might) 23.2527 Tj
--583 TJm
-(try) 11.0684 Tj
--582 TJm
-(Markus) 30.4357 Tj
--582 TJm
-(F) 5.53921 Tj
--582 TJm
-(X) 7.193 Tj
--582 TJm
-(J) 3.87545 Tj
--582 TJm
-(Oberhumer') 48.6872 Tj
-55 TJm
-(s) 3.87545 Tj
-[1 0 0 1 437.433 664.209] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -437.433 -664.209] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-437.433 664.209 Td
-/F134_0 9.9626 Tf
-(LZO) 17.9327 Tj
-[1 0 0 1 455.365 664.209] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -455.365 -664.209] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-461.163 664.209 Td
-/F130_0 9.9626 Tf
-(real-time) 35.965 Tj
--582 TJm
-(compres-) 37.0708 Tj
-72 652.254 Td
-(sion/decompression) 79.1429 Tj
--250 TJm
-(library) 26.5603 Tj
-65 TJm
-(,) 2.49065 Tj
--250 TJm
-(at) 7.193 Tj
--250 TJm
-(http://www) 45.3896 Tj
-65 TJm
-(.oberhumer) 45.6486 Tj
-55 TJm
-(.com/opensource.) 70.2762 Tj
-[1 0 0 1 72 650.097] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.9626] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -640.135] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 617.501 Td
-/F122_0 20.6585 Tf
-(4.5.) 34.4584 Tj
--278 TJm
-(Fur) 33.2808 Tj
--20 TJm
-(ther) 39.0239 Tj
--278 TJm
-(Reading) 81.4978 Tj
-[1 0 0 1 72 612.905] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.9626] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -602.942] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 595.583 Td
-/F134_0 9.9626 Tf
-(bzip2) 29.8878 Tj
-[1 0 0 1 101.888 595.583] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -101.888 -595.583] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-104.923 595.583 Td
-/F130_0 9.9626 Tf
-(is) 6.64505 Tj
--305 TJm
-(not) 12.7322 Tj
--304 TJm
-(research) 33.1854 Tj
--305 TJm
-(w) 7.193 Tj
-10 TJm
-(ork,) 15.7708 Tj
--318 TJm
-(in) 7.7509 Tj
--305 TJm
-(the) 12.1743 Tj
--304 TJm
-(sense) 21.579 Tj
--305 TJm
-(that) 14.9439 Tj
--304 TJm
-(it) 5.53921 Tj
--305 TJm
-(doesn') 26.5603 Tj
-18 TJm
-(t) 2.7696 Tj
--305 TJm
-(present) 28.772 Tj
--304 TJm
-(an) 9.40469 Tj
-15 TJm
-(y) 4.9813 Tj
--305 TJm
-(ne) 9.40469 Tj
-25 TJm
-(w) 7.193 Tj
--304 TJm
-(ideas.) 22.9638 Tj
--474 TJm
-(Rather) 26.5603 Tj
-40 TJm
-(,) 2.49065 Tj
--318 TJm
-(it') 8.85675 Tj
-55 TJm
-(s) 3.87545 Tj
--305 TJm
-(an) 9.40469 Tj
--305 TJm
-(engineeri) 37.0708 Tj
-1 TJm
-(ng) 9.9626 Tj
--305 TJm
-(e) 4.42339 Tj
-15 TJm
-(x) 4.9813 Tj
-15 TJm
-(ercise) 23.2328 Tj
-72 583.628 Td
-(based) 22.6848 Tj
--250 TJm
-(on) 9.9626 Tj
--250 TJm
-(e) 4.42339 Tj
-15 TJm
-(xisting) 27.1282 Tj
--250 TJm
-(ideas.) 22.9638 Tj
-[1 0 0 1 72 581.471] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -9.9627] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -571.509] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 561.71 Td
-/F130_0 9.9626 Tf
-(F) 5.53921 Tj
-15 TJm
-(our) 13.2801 Tj
--250 TJm
-(documents) 43.1679 Tj
--250 TJm
-(describe) 33.1954 Tj
--250 TJm
-(essentially) 42.0621 Tj
--250 TJm
-(all) 9.9626 Tj
--250 TJm
-(the) 12.1743 Tj
--250 TJm
-(ideas) 20.4731 Tj
--250 TJm
-(behind) 27.1182 Tj
-[1 0 0 1 298.747 561.71] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -298.747 -561.71] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-298.747 561.71 Td
-/F134_0 9.9626 Tf
-(bzip2) 29.8878 Tj
-[1 0 0 1 328.635 561.71] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -328.635 -561.71] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-328.635 561.71 Td
-/F130_0 9.9626 Tf
-(:) 2.7696 Tj
-[1 0 0 1 72 559.554] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -299.875] cm
-/DeviceRGB {} cs
-[0.929398 0.968597 0.956848] sc
-/DeviceRGB {} CS
-[0.929398 0.968597 0.956848] SC
-0 0 468 298.879 re
-f
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 3.5866] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 295.293] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 18 -8.3686] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -90 -550.189] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-90 550.189 Td
-/F134_0 9.9626 Tf
-(Michael) 41.8429 Tj
--426 TJm
-(Burrows) 41.8429 Tj
--426 TJm
-(and) 17.9327 Tj
--426 TJm
-(D.) 11.9551 Tj
--426 TJm
-(J.) 11.9551 Tj
--426 TJm
-(Wheeler:) 47.8205 Tj
-98.4879 538.234 Td
-("A) 11.9551 Tj
--426 TJm
-(block-sorting) 77.7083 Tj
--426 TJm
-(lossless) 47.8205 Tj
--426 TJm
-(data) 23.9102 Tj
--426 TJm
-(compression) 65.7532 Tj
--426 TJm
-(algorithm") 59.7756 Tj
-102.732 526.278 Td
-(10th) 23.9102 Tj
--426 TJm
-(May) 17.9327 Tj
--426 TJm
-(1994.) 29.8878 Tj
-102.732 514.323 Td
-(Digital) 41.8429 Tj
--426 TJm
-(SRC) 17.9327 Tj
--426 TJm
-(Research) 47.8205 Tj
--426 TJm
-(Report) 35.8654 Tj
--426 TJm
-(124.) 23.9102 Tj
-102.732 502.368 Td
-(ftp://ftp.digital.com/pub/DEC/SRC/research-reports/SRC-124.ps.g\
-z) 382.564 Tj
-102.732 490.413 Td
-(If) 11.9551 Tj
--426 TJm
-(you) 17.9327 Tj
--426 TJm
-(have) 23.9102 Tj
--426 TJm
-(trouble) 41.8429 Tj
--426 TJm
-(finding) 41.8429 Tj
--426 TJm
-(it,) 17.9327 Tj
--426 TJm
-(try) 17.9327 Tj
--426 TJm
-(searching) 53.798 Tj
--426 TJm
-(at) 11.9551 Tj
--426 TJm
-(the) 17.9327 Tj
-102.732 478.458 Td
-(New) 17.9327 Tj
--426 TJm
-(Zealand) 41.8429 Tj
--426 TJm
-(Digital) 41.8429 Tj
--426 TJm
-(Library,) 47.8205 Tj
--426 TJm
-(http://www.nzdl.org.) 119.551 Tj
-90 454.547 Td
-(Daniel) 35.8654 Tj
--426 TJm
-(S.) 11.9551 Tj
--426 TJm
-(Hirschberg) 59.7756 Tj
--426 TJm
-(and) 17.9327 Tj
--426 TJm
-(Debra) 29.8878 Tj
--426 TJm
-(A.) 11.9551 Tj
--426 TJm
-(LeLewer) 41.8429 Tj
-98.4879 442.592 Td
-("Efficient) 59.7756 Tj
--426 TJm
-(Decoding) 47.8205 Tj
--426 TJm
-(of) 11.9551 Tj
--426 TJm
-(Prefix) 35.8654 Tj
--426 TJm
-(Codes") 35.8654 Tj
-102.732 430.637 Td
-(Communications) 83.6858 Tj
--426 TJm
-(of) 11.9551 Tj
--426 TJm
-(the) 17.9327 Tj
--426 TJm
-(ACM,) 23.9102 Tj
--426 TJm
-(April) 29.8878 Tj
--426 TJm
-(1990,) 29.8878 Tj
--426 TJm
-(Vol) 17.9327 Tj
--426 TJm
-(33,) 17.9327 Tj
--426 TJm
-(Number) 35.8654 Tj
--426 TJm
-(4.) 11.9551 Tj
-102.732 418.682 Td
-(You) 17.9327 Tj
--426 TJm
-(might) 29.8878 Tj
--426 TJm
-(be) 11.9551 Tj
--426 TJm
-(able) 23.9102 Tj
--426 TJm
-(to) 11.9551 Tj
--426 TJm
-(get) 17.9327 Tj
--426 TJm
-(an) 11.9551 Tj
--426 TJm
-(electronic) 59.7756 Tj
--426 TJm
-(copy) 23.9102 Tj
--426 TJm
-(of) 11.9551 Tj
--426 TJm
-(this) 23.9102 Tj
-102.732 406.727 Td
-(from) 23.9102 Tj
--426 TJm
-(the) 17.9327 Tj
--426 TJm
-(ACM) 17.9327 Tj
--426 TJm
-(Digital) 41.8429 Tj
--426 TJm
-(Library.) 47.8205 Tj
-90 382.816 Td
-(David) 29.8878 Tj
--426 TJm
-(J.) 11.9551 Tj
--426 TJm
-(Wheeler) 41.8429 Tj
-102.732 370.861 Td
-(Program) 41.8429 Tj
--426 TJm
-(bred3.c) 41.8429 Tj
--426 TJm
-(and) 17.9327 Tj
--426 TJm
-(accompanying) 71.7307 Tj
--426 TJm
-(document) 47.8205 Tj
--426 TJm
-(bred3.ps.) 53.798 Tj
-102.732 358.906 Td
-(This) 23.9102 Tj
--426 TJm
-(contains) 47.8205 Tj
--426 TJm
-(the) 17.9327 Tj
--426 TJm
-(idea) 23.9102 Tj
--426 TJm
-(behind) 35.8654 Tj
--426 TJm
-(the) 17.9327 Tj
--426 TJm
-(multi-table) 65.7532 Tj
--426 TJm
-(Huffman) 41.8429 Tj
--426 TJm
-(coding) 35.8654 Tj
--426 TJm
-(scheme.) 41.8429 Tj
-102.732 346.951 Td
-(ftp://ftp.cl.cam.ac.uk/users/djw3/) 203.237 Tj
-90 323.041 Td
-(Jon) 17.9327 Tj
--426 TJm
-(L.) 11.9551 Tj
--426 TJm
-(Bentley) 41.8429 Tj
--426 TJm
-(and) 17.9327 Tj
--426 TJm
-(Robert) 35.8654 Tj
--426 TJm
-(Sedgewick) 53.798 Tj
-98.4879 311.085 Td
-("Fast) 29.8878 Tj
--426 TJm
-(Algorithms) 59.7756 Tj
--426 TJm
-(for) 17.9327 Tj
--426 TJm
-(Sorting) 41.8429 Tj
--426 TJm
-(and) 17.9327 Tj
--426 TJm
-(Searching) 53.798 Tj
--426 TJm
-(Strings") 47.8205 Tj
-102.732 299.13 Td
-(Available) 53.798 Tj
--426 TJm
-(from) 23.9102 Tj
--426 TJm
-(Sedgewick's) 65.7532 Tj
--426 TJm
-(web) 17.9327 Tj
--426 TJm
-(page,) 29.8878 Tj
-102.732 287.175 Td
-(www.cs.princeton.edu/~rs) 143.461 Tj
-[1 0 0 1 72 259.678] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 468 3.5866] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -468 -13.5492] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -249.715] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 237.76 Td
-/F130_0 9.9626 Tf
-(The) 15.4918 Tj
--239 TJm
-(follo) 18.8194 Tj
-25 TJm
-(wing) 19.9252 Tj
--238 TJm
-(paper) 22.1269 Tj
--239 TJm
-(gi) 7.7509 Tj
-25 TJm
-(v) 4.9813 Tj
-15 TJm
-(es) 8.29885 Tj
--239 TJm
-(v) 4.9813 Tj
-25 TJm
-(aluable) 28.772 Tj
--238 TJm
-(additional) 39.8504 Tj
--239 TJm
-(insights) 31.0036 Tj
--238 TJm
-(into) 15.5018 Tj
--239 TJm
-(the) 12.1743 Tj
--239 TJm
-(algorithm,) 41.2352 Tj
--241 TJm
-(b) 4.9813 Tj
-20 TJm
-(ut) 7.7509 Tj
--238 TJm
-(is) 6.64505 Tj
--239 TJm
-(not) 12.7322 Tj
--239 TJm
-(immedi) 30.4457 Tj
-1 TJm
-(ately) 19.3673 Tj
--239 TJm
-(the) 12.1743 Tj
--239 TJm
-(basis) 19.9252 Tj
--238 TJm
-(of) 8.29885 Tj
--239 TJm
-(an) 9.40469 Tj
-15 TJm
-(y) 4.9813 Tj
--239 TJm
-(code) 18.8094 Tj
-72 225.805 Td
-(used) 18.2614 Tj
--250 TJm
-(in) 7.7509 Tj
--250 TJm
-(bzip2.) 24.6275 Tj
-[1 0 0 1 72 223.648] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -72.7273] cm
-/DeviceRGB {} cs
-[0.929398 0.968597 0.956848] sc
-/DeviceRGB {} CS
-[0.929398 0.968597 0.956848] SC
-0 0 468 71.731 re
-f
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 3.5866] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 68.1444] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 18 -8.3686] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -90 -214.283] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-90 214.283 Td
-/F134_0 9.9626 Tf
-(Peter) 29.8878 Tj
--426 TJm
-(Fenwick:) 47.8205 Tj
-102.732 202.328 Td
-(Block) 29.8878 Tj
--426 TJm
-(Sorting) 41.8429 Tj
--426 TJm
-(Text) 23.9102 Tj
--426 TJm
-(Compression) 65.7532 Tj
-102.732 190.373 Td
-(Proceedings) 65.7532 Tj
--426 TJm
-(of) 11.9551 Tj
--426 TJm
-(the) 17.9327 Tj
--426 TJm
-(19th) 23.9102 Tj
--426 TJm
-(Australasian) 71.7307 Tj
--426 TJm
-(Computer) 47.8205 Tj
--426 TJm
-(Science) 41.8429 Tj
--426 TJm
-(Conference,) 65.7532 Tj
-111.22 178.418 Td
-(Melbourne,) 59.7756 Tj
--426 TJm
-(Australia.) 59.7756 Tj
--852 TJm
-(Jan) 17.9327 Tj
--426 TJm
-(31) 11.9551 Tj
--426 TJm
-(-) 5.97756 Tj
--426 TJm
-(Feb) 17.9327 Tj
--426 TJm
-(2,) 11.9551 Tj
--426 TJm
-(1996.) 29.8878 Tj
-102.732 166.463 Td
-(ftp://ftp.cs.auckland.ac.nz/pub/peter-f/ACSC96paper.ps) 322.788 Tj
-[1 0 0 1 72 150.921] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 468 3.5866] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -468 -13.5492] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -140.958] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 129.003 Td
-/F130_0 9.9626 Tf
-(K) 7.193 Tj
-15 TJm
-(unihik) 25.4644 Tj
-10 TJm
-(o) 4.9813 Tj
--250 TJm
-(Sadakane') 41.4942 Tj
-55 TJm
-(s) 3.87545 Tj
--250 TJm
-(sorting) 27.6761 Tj
--250 TJm
-(algorithm,) 41.2352 Tj
--250 TJm
-(mentioned) 42.0621 Tj
--250 TJm
-(abo) 14.386 Tj
-15 TJm
-(v) 4.9813 Tj
-15 TJm
-(e,) 6.91404 Tj
--250 TJm
-(is) 6.64505 Tj
--250 TJm
-(a) 4.42339 Tj
-20 TJm
-(v) 4.9813 Tj
-25 TJm
-(ailable) 26.5603 Tj
--250 TJm
-(from:) 22.1369 Tj
-[1 0 0 1 72 126.846] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -36.8618] cm
-/DeviceRGB {} cs
-[0.929398 0.968597 0.956848] sc
-/DeviceRGB {} CS
-[0.929398 0.968597 0.956848] SC
-0 0 468 35.8655 re
-f
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 3.5866] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 32.2789] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 18 -8.3686] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -90 -117.482] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-90 117.482 Td
-/F134_0 9.9626 Tf
-(http://naomi.is.s.u-tokyo.ac.jp/~sada/papers/Sada98b.ps.gz) 346.698 Tj
-[1 0 0 1 72 89.9846] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 468 3.5866] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -468 -13.5492] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -29.1702] cm
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-[1 0 0 1 1.8929 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 374.394 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 6.8542] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 40.5726 -6.7546] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -493.841 -50.9514] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-534.414 50.9514 Td
-/F130_0 9.9626 Tf
-(34) 9.9626 Tj
-[1 0 0 1 453.269 50.8518] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 93.5985 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 6.2765 0] cm
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-[1 0 0 1 -13.1436 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-Q
-showpage
-%%PageTrailer
-pdfEndPage
-%%Page: 38 38
-%%BeginPageSetup
-%%PageOrientation: Portrait
-pdfStartPage
-0 0 612 792 re W
-%%EndPageSetup
-[] 0 d
-1 i
-0 j
-0 J
-10 M
-1 w
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-false op
-false OP
-0 0 612 792 re
-W
-q
-[1 0 0 1 72 741.554] cm
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-[1 0 0 1 1.8929 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 14.4459] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 187.197 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 -6.8541] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 6.8541] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 116.328 -6.7546] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -382.4 -749.245] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-498.728 749.245 Td
-/F130_0 9.9626 Tf
-(Miscellanea) 48.1393 Tj
-[1 0 0 1 266.071 749.146] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 280.796 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -472.974 -7.0936] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -0.4981] cm
-q
-[] 0 d
-0 J
-0.4981 w
-0 0.2491 m
-475.465 0.2491 l
-S
-Q
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 479.251 0] cm
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-[1 0 0 1 -13.1436 0] cm
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-[1 0 0 1 -540 -741.554] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 710.037 Td
-/F130_0 9.9626 Tf
-(The) 15.4918 Tj
--250 TJm
-(Manber) 30.9837 Tj
-20 TJm
-(-Myers) 28.772 Tj
--250 TJm
-(suf) 12.1743 Tj
-25 TJm
-(\002x) 10.5205 Tj
--250 TJm
-(array) 20.4632 Tj
--250 TJm
-(construction) 49.2551 Tj
--250 TJm
-(algorithm) 38.7446 Tj
--250 TJm
-(is) 6.64505 Tj
--250 TJm
-(described) 38.1767 Tj
--250 TJm
-(in) 7.7509 Tj
--250 TJm
-(a) 4.42339 Tj
--250 TJm
-(paper) 22.1269 Tj
--250 TJm
-(a) 4.42339 Tj
-20 TJm
-(v) 4.9813 Tj
-25 TJm
-(ailable) 26.5603 Tj
--250 TJm
-(from:) 22.1369 Tj
-[1 0 0 1 72 707.88] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -36.8618] cm
-/DeviceRGB {} cs
-[0.929398 0.968597 0.956848] sc
-/DeviceRGB {} CS
-[0.929398 0.968597 0.956848] SC
-0 0 468 35.8655 re
-f
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 3.5866] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 32.2789] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 18 -8.3685] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -90 -698.516] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-90 698.516 Td
-/F134_0 9.9626 Tf
-(http://www.cs.arizona.edu/people/gene/PAPERS/suffix.ps) 322.788 Tj
-[1 0 0 1 72 671.019] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 468 3.5866] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -468 -13.5492] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -72 -661.056] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-72 649.101 Td
-/F130_0 9.9626 Tf
-(Finally) 28.234 Tj
-65 TJm
-(,) 2.49065 Tj
--227 TJm
-(the) 12.1743 Tj
--221 TJm
-(follo) 18.8194 Tj
-25 TJm
-(wing) 19.9252 Tj
--222 TJm
-(papers) 26.0024 Tj
--221 TJm
-(document) 39.2925 Tj
--221 TJm
-(some) 21.031 Tj
--222 TJm
-(in) 7.7509 Tj
-40 TJm
-(v) 4.9813 Tj
-15 TJm
-(estig) 18.8194 Tj
-5 TJm
-(ations) 23.8007 Tj
--221 TJm
-(I) 3.31755 Tj
--221 TJm
-(made) 21.579 Tj
--222 TJm
-(into) 15.5018 Tj
--221 TJm
-(the) 12.1743 Tj
--221 TJm
-(performance) 50.341 Tj
--222 TJm
-(of) 8.29885 Tj
--221 TJm
-(sorting) 27.6761 Tj
--221 TJm
-(and) 14.386 Tj
--222 TJm
-(decompression) 59.7656 Tj
-72 637.146 Td
-(algorithms:) 45.3896 Tj
-[1 0 0 1 72 634.989] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 -132.503] cm
-/DeviceRGB {} cs
-[0.929398 0.968597 0.956848] sc
-/DeviceRGB {} CS
-[0.929398 0.968597 0.956848] SC
-0 0 468 131.507 re
-f
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 3.5866] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 127.92] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 18 -8.3686] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -90 -625.624] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-90 625.624 Td
-/F134_0 9.9626 Tf
-(Julian) 35.8654 Tj
--426 TJm
-(Seward) 35.8654 Tj
-102.732 613.669 Td
-(On) 11.9551 Tj
--426 TJm
-(the) 17.9327 Tj
--426 TJm
-(Performance) 65.7532 Tj
--426 TJm
-(of) 11.9551 Tj
--426 TJm
-(BWT) 17.9327 Tj
--426 TJm
-(Sorting) 41.8429 Tj
--426 TJm
-(Algorithms) 59.7756 Tj
-102.732 601.714 Td
-(Proceedings) 65.7532 Tj
--426 TJm
-(of) 11.9551 Tj
--426 TJm
-(the) 17.9327 Tj
--426 TJm
-(IEEE) 23.9102 Tj
--426 TJm
-(Data) 23.9102 Tj
--426 TJm
-(Compression) 65.7532 Tj
--426 TJm
-(Conference) 59.7756 Tj
--426 TJm
-(2000) 23.9102 Tj
-111.22 589.759 Td
-(Snowbird,) 53.798 Tj
--426 TJm
-(Utah.) 29.8878 Tj
--852 TJm
-(28-30) 29.8878 Tj
--426 TJm
-(March) 29.8878 Tj
--426 TJm
-(2000.) 29.8878 Tj
-90 565.848 Td
-(Julian) 35.8654 Tj
--426 TJm
-(Seward) 35.8654 Tj
-102.732 553.893 Td
-(Space-time) 59.7756 Tj
--426 TJm
-(Tradeoffs) 53.798 Tj
--426 TJm
-(in) 11.9551 Tj
--426 TJm
-(the) 17.9327 Tj
--426 TJm
-(Inverse) 41.8429 Tj
--426 TJm
-(B-W) 17.9327 Tj
--426 TJm
-(Transform) 53.798 Tj
-102.732 541.938 Td
-(Proceedings) 65.7532 Tj
--426 TJm
-(of) 11.9551 Tj
--426 TJm
-(the) 17.9327 Tj
--426 TJm
-(IEEE) 23.9102 Tj
--426 TJm
-(Data) 23.9102 Tj
--426 TJm
-(Compression) 65.7532 Tj
--426 TJm
-(Conference) 59.7756 Tj
--426 TJm
-(2001) 23.9102 Tj
-111.22 529.983 Td
-(Snowbird,) 53.798 Tj
--426 TJm
-(Utah.) 29.8878 Tj
--852 TJm
-(27-29) 29.8878 Tj
--426 TJm
-(March) 29.8878 Tj
--426 TJm
-(2001.) 29.8878 Tj
-[1 0 0 1 72 502.486] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 468 3.5866] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -468 -3.5866] cm
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-[1 0 0 1 0 -451.634] cm
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-[1 0 0 1 1.8929 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 374.394 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 2.4907 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 0 6.8541] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 40.5726 -6.7546] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 -493.841 -50.9513] cm
-[1 0 0 1 0 0] Tm
-0 0 Td
-534.414 50.9513 Td
-/F130_0 9.9626 Tf
-(35) 9.9626 Tj
-[1 0 0 1 453.269 50.8518] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 93.5985 0] cm
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-/DeviceRGB {} cs
-[0 0 0] sc
-/DeviceRGB {} CS
-[0 0 0] SC
-[1 0 0 1 6.2765 0] cm
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-[1 0 0 1 -13.1436 0] cm
-/DeviceGray {} cs
-[0] sc
-/DeviceGray {} CS
-[0] SC
-Q
-showpage
-%%PageTrailer
-pdfEndPage
-%%Trailer
-end
-%%DocumentSuppliedResources:
-%%+ font DTUUHP+NimbusSanL-Bold
-%%+ font VXAMRV+NimbusRomNo9L-Regu
-%%+ font MFECUR+NimbusMonL-Regu
-%%+ font ZOVMRD+CMMI10
-%%+ font ERVBFT+NimbusMonL-Bold
-%%+ font BZXIEB+CMSY10
-%%+ font WWWUTU+NimbusRomNo9L-ReguItal
-%%EOF
diff --git a/Utilities/cmbzip2/manual.xml b/Utilities/cmbzip2/manual.xml
deleted file mode 100644
index f224136..0000000
--- a/Utilities/cmbzip2/manual.xml
+++ /dev/null
@@ -1,2964 +0,0 @@
-<?xml version="1.0"?> <!-- -*- sgml -*- -->
-<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
-  "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd"[
-
-<!-- various strings, dates etc. common to all docs -->
-<!ENTITY % common-ents SYSTEM "entities.xml"> %common-ents;
-]>
-
-<book lang="en" id="userman" xreflabel="bzip2 Manual">
-
- <bookinfo>
-  <title>bzip2 and libbzip2, version 1.0.5</title>
-  <subtitle>A program and library for data compression</subtitle>
-  <copyright>
-   <year>&bz-lifespan;</year>
-   <holder>Julian Seward</holder>
-  </copyright>
-  <releaseinfo>Version &bz-version; of &bz-date;</releaseinfo>
-
-  <authorgroup>
-   <author>
-    <firstname>Julian</firstname>
-    <surname>Seward</surname>
-    <affiliation>
-     <orgname>&bz-url;</orgname>
-    </affiliation>
-   </author>
-  </authorgroup>
-
-  <legalnotice>
-
-  <para>This program, <computeroutput>bzip2</computeroutput>, the
-  associated library <computeroutput>libbzip2</computeroutput>, and
-  all documentation, are copyright &copy; &bz-lifespan; Julian Seward.
-  All rights reserved.</para>
-
-  <para>Redistribution and use in source and binary forms, with
-  or without modification, are permitted provided that the
-  following conditions are met:</para>
-
-  <itemizedlist mark='bullet'>
-
-   <listitem><para>Redistributions of source code must retain the
-   above copyright notice, this list of conditions and the
-   following disclaimer.</para></listitem>
-
-   <listitem><para>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.</para></listitem>
-
-   <listitem><para>Altered source versions must be plainly marked
-   as such, and must not be misrepresented as being the original
-   software.</para></listitem>
-
-   <listitem><para>The name of the author may not be used to
-   endorse or promote products derived from this software without
-   specific prior written permission.</para></listitem>
-
-  </itemizedlist>
-
-  <para>THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY
-  EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
-  THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
-  PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
-  AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
-  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
-  TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
-  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
-  IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
-  THE POSSIBILITY OF SUCH DAMAGE.</para>
-
- <para>PATENTS: To the best of my knowledge,
- <computeroutput>bzip2</computeroutput> and
- <computeroutput>libbzip2</computeroutput> do not use any patented
- algorithms.  However, I do not have the resources to carry
- out a patent search.  Therefore I cannot give any guarantee of
- the above statement.
- </para>
-
-</legalnotice>
-
-</bookinfo>
-
-
-
-<chapter id="intro" xreflabel="Introduction">
-<title>Introduction</title>
-
-<para><computeroutput>bzip2</computeroutput> compresses files
-using the Burrows-Wheeler block-sorting text compression
-algorithm, and Huffman coding.  Compression is generally
-considerably better than that achieved by more conventional
-LZ77/LZ78-based compressors, and approaches the performance of
-the PPM family of statistical compressors.</para>
-
-<para><computeroutput>bzip2</computeroutput> is built on top of
-<computeroutput>libbzip2</computeroutput>, a flexible library for
-handling compressed data in the
-<computeroutput>bzip2</computeroutput> format.  This manual
-describes both how to use the program and how to work with the
-library interface.  Most of the manual is devoted to this
-library, not the program, which is good news if your interest is
-only in the program.</para>
-
-<itemizedlist mark='bullet'>
-
- <listitem><para><xref linkend="using"/> describes how to use
- <computeroutput>bzip2</computeroutput>; this is the only part
- you need to read if you just want to know how to operate the
- program.</para></listitem>
-
- <listitem><para><xref linkend="libprog"/> describes the
- programming interfaces in detail, and</para></listitem>
-
- <listitem><para><xref linkend="misc"/> records some
- miscellaneous notes which I thought ought to be recorded
- somewhere.</para></listitem>
-
-</itemizedlist>
-
-</chapter>
-
-
-<chapter id="using" xreflabel="How to use bzip2">
-<title>How to use bzip2</title>
-
-<para>This chapter contains a copy of the
-<computeroutput>bzip2</computeroutput> man page, and nothing
-else.</para>
-
-<sect1 id="name" xreflabel="NAME">
-<title>NAME</title>
-
-<itemizedlist mark='bullet'>
-
- <listitem><para><computeroutput>bzip2</computeroutput>,
-  <computeroutput>bunzip2</computeroutput> - a block-sorting file
-  compressor, v1.0.4</para></listitem>
-
- <listitem><para><computeroutput>bzcat</computeroutput> -
-   decompresses files to stdout</para></listitem>
-
- <listitem><para><computeroutput>bzip2recover</computeroutput> -
-   recovers data from damaged bzip2 files</para></listitem>
-
-</itemizedlist>
-
-</sect1>
-
-
-<sect1 id="synopsis" xreflabel="SYNOPSIS">
-<title>SYNOPSIS</title>
-
-<itemizedlist mark='bullet'>
-
- <listitem><para><computeroutput>bzip2</computeroutput> [
-  -cdfkqstvzVL123456789 ] [ filenames ...  ]</para></listitem>
-
- <listitem><para><computeroutput>bunzip2</computeroutput> [
-  -fkvsVL ] [ filenames ...  ]</para></listitem>
-
- <listitem><para><computeroutput>bzcat</computeroutput> [ -s ] [
-  filenames ...  ]</para></listitem>
-
- <listitem><para><computeroutput>bzip2recover</computeroutput>
-  filename</para></listitem>
-
-</itemizedlist>
-
-</sect1>
-
-
-<sect1 id="description" xreflabel="DESCRIPTION">
-<title>DESCRIPTION</title>
-
-<para><computeroutput>bzip2</computeroutput> compresses files
-using the Burrows-Wheeler block sorting text compression
-algorithm, and Huffman coding.  Compression is generally
-considerably better than that achieved by more conventional
-LZ77/LZ78-based compressors, and approaches the performance of
-the PPM family of statistical compressors.</para>
-
-<para>The command-line options are deliberately very similar to
-those of GNU <computeroutput>gzip</computeroutput>, but they are
-not identical.</para>
-
-<para><computeroutput>bzip2</computeroutput> expects a list of
-file names to accompany the command-line flags.  Each file is
-replaced by a compressed version of itself, with the name
-<computeroutput>original_name.bz2</computeroutput>.  Each
-compressed file has the same modification date, permissions, and,
-when possible, ownership as the corresponding original, so that
-these properties can be correctly restored at decompression time.
-File name handling is naive in the sense that there is no
-mechanism for preserving original file names, permissions,
-ownerships or dates in filesystems which lack these concepts, or
-have serious file name length restrictions, such as
-MS-DOS.</para>
-
-<para><computeroutput>bzip2</computeroutput> and
-<computeroutput>bunzip2</computeroutput> will by default not
-overwrite existing files.  If you want this to happen, specify
-the <computeroutput>-f</computeroutput> flag.</para>
-
-<para>If no file names are specified,
-<computeroutput>bzip2</computeroutput> compresses from standard
-input to standard output.  In this case,
-<computeroutput>bzip2</computeroutput> will decline to write
-compressed output to a terminal, as this would be entirely
-incomprehensible and therefore pointless.</para>
-
-<para><computeroutput>bunzip2</computeroutput> (or
-<computeroutput>bzip2 -d</computeroutput>) decompresses all
-specified files.  Files which were not created by
-<computeroutput>bzip2</computeroutput> will be detected and
-ignored, and a warning issued.
-<computeroutput>bzip2</computeroutput> attempts to guess the
-filename for the decompressed file from that of the compressed
-file as follows:</para>
-
-<itemizedlist mark='bullet'>
-
- <listitem><para><computeroutput>filename.bz2 </computeroutput>
-  becomes
-  <computeroutput>filename</computeroutput></para></listitem>
-
- <listitem><para><computeroutput>filename.bz </computeroutput>
-  becomes
-  <computeroutput>filename</computeroutput></para></listitem>
-
- <listitem><para><computeroutput>filename.tbz2</computeroutput>
-  becomes
-  <computeroutput>filename.tar</computeroutput></para></listitem>
-
- <listitem><para><computeroutput>filename.tbz </computeroutput>
-  becomes
-  <computeroutput>filename.tar</computeroutput></para></listitem>
-
- <listitem><para><computeroutput>anyothername </computeroutput>
-  becomes
-  <computeroutput>anyothername.out</computeroutput></para></listitem>
-
-</itemizedlist>
-
-<para>If the file does not end in one of the recognised endings,
-<computeroutput>.bz2</computeroutput>,
-<computeroutput>.bz</computeroutput>,
-<computeroutput>.tbz2</computeroutput> or
-<computeroutput>.tbz</computeroutput>,
-<computeroutput>bzip2</computeroutput> complains that it cannot
-guess the name of the original file, and uses the original name
-with <computeroutput>.out</computeroutput> appended.</para>
-
-<para>As with compression, supplying no filenames causes
-decompression from standard input to standard output.</para>
-
-<para><computeroutput>bunzip2</computeroutput> will correctly
-decompress a file which is the concatenation of two or more
-compressed files.  The result is the concatenation of the
-corresponding uncompressed files.  Integrity testing
-(<computeroutput>-t</computeroutput>) of concatenated compressed
-files is also supported.</para>
-
-<para>You can also compress or decompress files to the standard
-output by giving the <computeroutput>-c</computeroutput> flag.
-Multiple files may be compressed and decompressed like this.  The
-resulting outputs are fed sequentially to stdout.  Compression of
-multiple files in this manner generates a stream containing
-multiple compressed file representations.  Such a stream can be
-decompressed correctly only by
-<computeroutput>bzip2</computeroutput> version 0.9.0 or later.
-Earlier versions of <computeroutput>bzip2</computeroutput> will
-stop after decompressing the first file in the stream.</para>
-
-<para><computeroutput>bzcat</computeroutput> (or
-<computeroutput>bzip2 -dc</computeroutput>) decompresses all
-specified files to the standard output.</para>
-
-<para><computeroutput>bzip2</computeroutput> will read arguments
-from the environment variables
-<computeroutput>BZIP2</computeroutput> and
-<computeroutput>BZIP</computeroutput>, in that order, and will
-process them before any arguments read from the command line.
-This gives a convenient way to supply default arguments.</para>
-
-<para>Compression is always performed, even if the compressed
-file is slightly larger than the original.  Files of less than
-about one hundred bytes tend to get larger, since the compression
-mechanism has a constant overhead in the region of 50 bytes.
-Random data (including the output of most file compressors) is
-coded at about 8.05 bits per byte, giving an expansion of around
-0.5%.</para>
-
-<para>As a self-check for your protection,
-<computeroutput>bzip2</computeroutput> uses 32-bit CRCs to make
-sure that the decompressed version of a file is identical to the
-original.  This guards against corruption of the compressed data,
-and against undetected bugs in
-<computeroutput>bzip2</computeroutput> (hopefully very unlikely).
-The chances of data corruption going undetected is microscopic,
-about one chance in four billion for each file processed.  Be
-aware, though, that the check occurs upon decompression, so it
-can only tell you that something is wrong.  It can't help you
-recover the original uncompressed data.  You can use
-<computeroutput>bzip2recover</computeroutput> to try to recover
-data from damaged files.</para>
-
-<para>Return values: 0 for a normal exit, 1 for environmental
-problems (file not found, invalid flags, I/O errors, etc.), 2
-to indicate a corrupt compressed file, 3 for an internal
-consistency error (eg, bug) which caused
-<computeroutput>bzip2</computeroutput> to panic.</para>
-
-</sect1>
-
-
-<sect1 id="options" xreflabel="OPTIONS">
-<title>OPTIONS</title>
-
-<variablelist>
-
- <varlistentry>
- <term><computeroutput>-c --stdout</computeroutput></term>
- <listitem><para>Compress or decompress to standard
-  output.</para></listitem>
- </varlistentry>
-
- <varlistentry>
- <term><computeroutput>-d --decompress</computeroutput></term>
- <listitem><para>Force decompression.
-  <computeroutput>bzip2</computeroutput>,
-  <computeroutput>bunzip2</computeroutput> and
-  <computeroutput>bzcat</computeroutput> are really the same
-  program, and the decision about what actions to take is done on
-  the basis of which name is used.  This flag overrides that
-  mechanism, and forces bzip2 to decompress.</para></listitem>
- </varlistentry>
-
- <varlistentry>
- <term><computeroutput>-z --compress</computeroutput></term>
- <listitem><para>The complement to
-  <computeroutput>-d</computeroutput>: forces compression,
-  regardless of the invokation name.</para></listitem>
- </varlistentry>
-
- <varlistentry>
- <term><computeroutput>-t --test</computeroutput></term>
- <listitem><para>Check integrity of the specified file(s), but
-  don't decompress them.  This really performs a trial
-  decompression and throws away the result.</para></listitem>
- </varlistentry>
-
- <varlistentry>
- <term><computeroutput>-f --force</computeroutput></term>
- <listitem><para>Force overwrite of output files.  Normally,
-  <computeroutput>bzip2</computeroutput> will not overwrite
-  existing output files.  Also forces
-  <computeroutput>bzip2</computeroutput> to break hard links to
-  files, which it otherwise wouldn't do.</para>
-  <para><computeroutput>bzip2</computeroutput> normally declines
-  to decompress files which don't have the correct magic header
-  bytes. If forced (<computeroutput>-f</computeroutput>),
-  however, it will pass such files through unmodified. This is
-  how GNU <computeroutput>gzip</computeroutput> behaves.</para>
- </listitem>
- </varlistentry>
-
- <varlistentry>
- <term><computeroutput>-k --keep</computeroutput></term>
- <listitem><para>Keep (don't delete) input files during
-  compression or decompression.</para></listitem>
- </varlistentry>
-
- <varlistentry>
- <term><computeroutput>-s --small</computeroutput></term>
- <listitem><para>Reduce memory usage, for compression,
-  decompression and testing.  Files are decompressed and tested
-  using a modified algorithm which only requires 2.5 bytes per
-  block byte.  This means any file can be decompressed in 2300k
-  of memory, albeit at about half the normal speed.</para>
-  <para>During compression, <computeroutput>-s</computeroutput>
-  selects a block size of 200k, which limits memory use to around
-  the same figure, at the expense of your compression ratio.  In
-  short, if your machine is low on memory (8 megabytes or less),
-  use <computeroutput>-s</computeroutput> for everything.  See
-  <xref linkend="memory-management"/> below.</para></listitem>
- </varlistentry>
-
- <varlistentry>
- <term><computeroutput>-q --quiet</computeroutput></term>
- <listitem><para>Suppress non-essential warning messages.
-  Messages pertaining to I/O errors and other critical events
-  will not be suppressed.</para></listitem>
- </varlistentry>
-
- <varlistentry>
- <term><computeroutput>-v --verbose</computeroutput></term>
- <listitem><para>Verbose mode -- show the compression ratio for
-  each file processed.  Further
-  <computeroutput>-v</computeroutput>'s increase the verbosity
-  level, spewing out lots of information which is primarily of
-  interest for diagnostic purposes.</para></listitem>
- </varlistentry>
-
- <varlistentry>
- <term><computeroutput>-L --license -V --version</computeroutput></term>
- <listitem><para>Display the software version, license terms and
-  conditions.</para></listitem>
- </varlistentry>
-
- <varlistentry>
- <term><computeroutput>-1</computeroutput> (or
- <computeroutput>--fast</computeroutput>) to
- <computeroutput>-9</computeroutput> (or
- <computeroutput>-best</computeroutput>)</term>
- <listitem><para>Set the block size to 100 k, 200 k ...  900 k
-  when compressing.  Has no effect when decompressing.  See <xref
-  linkend="memory-management" /> below.  The
-  <computeroutput>--fast</computeroutput> and
-  <computeroutput>--best</computeroutput> aliases are primarily
-  for GNU <computeroutput>gzip</computeroutput> compatibility.
-  In particular, <computeroutput>--fast</computeroutput> doesn't
-  make things significantly faster.  And
-  <computeroutput>--best</computeroutput> merely selects the
-  default behaviour.</para></listitem>
- </varlistentry>
-
- <varlistentry>
- <term><computeroutput>--</computeroutput></term>
- <listitem><para>Treats all subsequent arguments as file names,
-  even if they start with a dash.  This is so you can handle
-  files with names beginning with a dash, for example:
-  <computeroutput>bzip2 --
-  -myfilename</computeroutput>.</para></listitem>
- </varlistentry>
-
- <varlistentry>
- <term><computeroutput>--repetitive-fast</computeroutput></term>
- <term><computeroutput>--repetitive-best</computeroutput></term>
- <listitem><para>These flags are redundant in versions 0.9.5 and
-  above.  They provided some coarse control over the behaviour of
-  the sorting algorithm in earlier versions, which was sometimes
-  useful.  0.9.5 and above have an improved algorithm which
-  renders these flags irrelevant.</para></listitem>
- </varlistentry>
-
-</variablelist>
-
-</sect1>
-
-
-<sect1 id="memory-management" xreflabel="MEMORY MANAGEMENT">
-<title>MEMORY MANAGEMENT</title>
-
-<para><computeroutput>bzip2</computeroutput> compresses large
-files in blocks.  The block size affects both the compression
-ratio achieved, and the amount of memory needed for compression
-and decompression.  The flags <computeroutput>-1</computeroutput>
-through <computeroutput>-9</computeroutput> specify the block
-size to be 100,000 bytes through 900,000 bytes (the default)
-respectively.  At decompression time, the block size used for
-compression is read from the header of the compressed file, and
-<computeroutput>bunzip2</computeroutput> then allocates itself
-just enough memory to decompress the file.  Since block sizes are
-stored in compressed files, it follows that the flags
-<computeroutput>-1</computeroutput> to
-<computeroutput>-9</computeroutput> are irrelevant to and so
-ignored during decompression.</para>
-
-<para>Compression and decompression requirements, in bytes, can be
-estimated as:</para>
-<programlisting>
-Compression:   400k + ( 8 x block size )
-
-Decompression: 100k + ( 4 x block size ), or
-               100k + ( 2.5 x block size )
-</programlisting>
-
-<para>Larger block sizes give rapidly diminishing marginal
-returns.  Most of the compression comes from the first two or
-three hundred k of block size, a fact worth bearing in mind when
-using <computeroutput>bzip2</computeroutput> on small machines.
-It is also important to appreciate that the decompression memory
-requirement is set at compression time by the choice of block
-size.</para>
-
-<para>For files compressed with the default 900k block size,
-<computeroutput>bunzip2</computeroutput> will require about 3700
-kbytes to decompress.  To support decompression of any file on a
-4 megabyte machine, <computeroutput>bunzip2</computeroutput> has
-an option to decompress using approximately half this amount of
-memory, about 2300 kbytes.  Decompression speed is also halved,
-so you should use this option only where necessary.  The relevant
-flag is <computeroutput>-s</computeroutput>.</para>
-
-<para>In general, try and use the largest block size memory
-constraints allow, since that maximises the compression achieved.
-Compression and decompression speed are virtually unaffected by
-block size.</para>
-
-<para>Another significant point applies to files which fit in a
-single block -- that means most files you'd encounter using a
-large block size.  The amount of real memory touched is
-proportional to the size of the file, since the file is smaller
-than a block.  For example, compressing a file 20,000 bytes long
-with the flag <computeroutput>-9</computeroutput> will cause the
-compressor to allocate around 7600k of memory, but only touch
-400k + 20000 * 8 = 560 kbytes of it.  Similarly, the decompressor
-will allocate 3700k but only touch 100k + 20000 * 4 = 180
-kbytes.</para>
-
-<para>Here is a table which summarises the maximum memory usage
-for different block sizes.  Also recorded is the total compressed
-size for 14 files of the Calgary Text Compression Corpus
-totalling 3,141,622 bytes.  This column gives some feel for how
-compression varies with block size.  These figures tend to
-understate the advantage of larger block sizes for larger files,
-since the Corpus is dominated by smaller files.</para>
-
-<programlisting>
-        Compress   Decompress   Decompress   Corpus
-Flag     usage      usage       -s usage     Size
-
- -1      1200k       500k         350k      914704
- -2      2000k       900k         600k      877703
- -3      2800k      1300k         850k      860338
- -4      3600k      1700k        1100k      846899
- -5      4400k      2100k        1350k      845160
- -6      5200k      2500k        1600k      838626
- -7      6100k      2900k        1850k      834096
- -8      6800k      3300k        2100k      828642
- -9      7600k      3700k        2350k      828642
-</programlisting>
-
-</sect1>
-
-
-<sect1 id="recovering" xreflabel="RECOVERING DATA FROM DAMAGED FILES">
-<title>RECOVERING DATA FROM DAMAGED FILES</title>
-
-<para><computeroutput>bzip2</computeroutput> compresses files in
-blocks, usually 900kbytes long.  Each block is handled
-independently.  If a media or transmission error causes a
-multi-block <computeroutput>.bz2</computeroutput> file to become
-damaged, it may be possible to recover data from the undamaged
-blocks in the file.</para>
-
-<para>The compressed representation of each block is delimited by
-a 48-bit pattern, which makes it possible to find the block
-boundaries with reasonable certainty.  Each block also carries
-its own 32-bit CRC, so damaged blocks can be distinguished from
-undamaged ones.</para>
-
-<para><computeroutput>bzip2recover</computeroutput> is a simple
-program whose purpose is to search for blocks in
-<computeroutput>.bz2</computeroutput> files, and write each block
-out into its own <computeroutput>.bz2</computeroutput> file.  You
-can then use <computeroutput>bzip2 -t</computeroutput> to test
-the integrity of the resulting files, and decompress those which
-are undamaged.</para>
-
-<para><computeroutput>bzip2recover</computeroutput> takes a
-single argument, the name of the damaged file, and writes a
-number of files <computeroutput>rec0001file.bz2</computeroutput>,
-<computeroutput>rec0002file.bz2</computeroutput>, etc, containing
-the extracted blocks.  The output filenames are designed so that
-the use of wildcards in subsequent processing -- for example,
-<computeroutput>bzip2 -dc rec*file.bz2 &#62;
-recovered_data</computeroutput> -- lists the files in the correct
-order.</para>
-
-<para><computeroutput>bzip2recover</computeroutput> should be of
-most use dealing with large <computeroutput>.bz2</computeroutput>
-files, as these will contain many blocks.  It is clearly futile
-to use it on damaged single-block files, since a damaged block
-cannot be recovered.  If you wish to minimise any potential data
-loss through media or transmission errors, you might consider
-compressing with a smaller block size.</para>
-
-</sect1>
-
-
-<sect1 id="performance" xreflabel="PERFORMANCE NOTES">
-<title>PERFORMANCE NOTES</title>
-
-<para>The sorting phase of compression gathers together similar
-strings in the file.  Because of this, files containing very long
-runs of repeated symbols, like "aabaabaabaab ..."  (repeated
-several hundred times) may compress more slowly than normal.
-Versions 0.9.5 and above fare much better than previous versions
-in this respect.  The ratio between worst-case and average-case
-compression time is in the region of 10:1.  For previous
-versions, this figure was more like 100:1.  You can use the
-<computeroutput>-vvvv</computeroutput> option to monitor progress
-in great detail, if you want.</para>
-
-<para>Decompression speed is unaffected by these
-phenomena.</para>
-
-<para><computeroutput>bzip2</computeroutput> usually allocates
-several megabytes of memory to operate in, and then charges all
-over it in a fairly random fashion.  This means that performance,
-both for compressing and decompressing, is largely determined by
-the speed at which your machine can service cache misses.
-Because of this, small changes to the code to reduce the miss
-rate have been observed to give disproportionately large
-performance improvements.  I imagine
-<computeroutput>bzip2</computeroutput> will perform best on
-machines with very large caches.</para>
-
-</sect1>
-
-
-
-<sect1 id="caveats" xreflabel="CAVEATS">
-<title>CAVEATS</title>
-
-<para>I/O error messages are not as helpful as they could be.
-<computeroutput>bzip2</computeroutput> tries hard to detect I/O
-errors and exit cleanly, but the details of what the problem is
-sometimes seem rather misleading.</para>
-
-<para>This manual page pertains to version &bz-version; of
-<computeroutput>bzip2</computeroutput>.  Compressed data created by
-this version is entirely forwards and backwards compatible with the
-previous public releases, versions 0.1pl2, 0.9.0 and 0.9.5, 1.0.0,
-1.0.1, 1.0.2 and 1.0.3, but with the following exception: 0.9.0 and
-above can correctly decompress multiple concatenated compressed files.
-0.1pl2 cannot do this; it will stop after decompressing just the first
-file in the stream.</para>
-
-<para><computeroutput>bzip2recover</computeroutput> versions
-prior to 1.0.2 used 32-bit integers to represent bit positions in
-compressed files, so it could not handle compressed files more
-than 512 megabytes long.  Versions 1.0.2 and above use 64-bit ints
-on some platforms which support them (GNU supported targets, and
-Windows). To establish whether or not
-<computeroutput>bzip2recover</computeroutput> was built with such
-a limitation, run it without arguments. In any event you can
-build yourself an unlimited version if you can recompile it with
-<computeroutput>MaybeUInt64</computeroutput> set to be an
-unsigned 64-bit integer.</para>
-
-</sect1>
-
-
-
-<sect1 id="author" xreflabel="AUTHOR">
-<title>AUTHOR</title>
-
-<para>Julian Seward,
-<computeroutput>&bz-email;</computeroutput></para>
-
-<para>The ideas embodied in
-<computeroutput>bzip2</computeroutput> are due to (at least) the
-following people: Michael Burrows and David Wheeler (for the
-block sorting transformation), David Wheeler (again, for the
-Huffman coder), Peter Fenwick (for the structured coding model in
-the original <computeroutput>bzip</computeroutput>, and many
-refinements), and Alistair Moffat, Radford Neal and Ian Witten
-(for the arithmetic coder in the original
-<computeroutput>bzip</computeroutput>).  I am much indebted for
-their help, support and advice.  See the manual in the source
-distribution for pointers to sources of documentation.  Christian
-von Roques encouraged me to look for faster sorting algorithms,
-so as to speed up compression.  Bela Lubkin encouraged me to
-improve the worst-case compression performance.  
-Donna Robinson XMLised the documentation.
-Many people sent
-patches, helped with portability problems, lent machines, gave
-advice and were generally helpful.</para>
-
-</sect1>
-
-</chapter>
-
-
-
-<chapter id="libprog" xreflabel="Programming with libbzip2">
-<title>
-Programming with <computeroutput>libbzip2</computeroutput>
-</title>
-
-<para>This chapter describes the programming interface to
-<computeroutput>libbzip2</computeroutput>.</para>
-
-<para>For general background information, particularly about
-memory use and performance aspects, you'd be well advised to read
-<xref linkend="using"/> as well.</para>
-
-
-<sect1 id="top-level" xreflabel="Top-level structure">
-<title>Top-level structure</title>
-
-<para><computeroutput>libbzip2</computeroutput> is a flexible
-library for compressing and decompressing data in the
-<computeroutput>bzip2</computeroutput> data format.  Although
-packaged as a single entity, it helps to regard the library as
-three separate parts: the low level interface, and the high level
-interface, and some utility functions.</para>
-
-<para>The structure of
-<computeroutput>libbzip2</computeroutput>'s interfaces is similar
-to that of Jean-loup Gailly's and Mark Adler's excellent
-<computeroutput>zlib</computeroutput> library.</para>
-
-<para>All externally visible symbols have names beginning
-<computeroutput>BZ2_</computeroutput>.  This is new in version
-1.0.  The intention is to minimise pollution of the namespaces of
-library clients.</para>
-
-<para>To use any part of the library, you need to
-<computeroutput>#include &lt;bzlib.h&gt;</computeroutput>
-into your sources.</para>
-
-
-
-<sect2 id="ll-summary" xreflabel="Low-level summary">
-<title>Low-level summary</title>
-
-<para>This interface provides services for compressing and
-decompressing data in memory.  There's no provision for dealing
-with files, streams or any other I/O mechanisms, just straight
-memory-to-memory work.  In fact, this part of the library can be
-compiled without inclusion of
-<computeroutput>stdio.h</computeroutput>, which may be helpful
-for embedded applications.</para>
-
-<para>The low-level part of the library has no global variables
-and is therefore thread-safe.</para>
-
-<para>Six routines make up the low level interface:
-<computeroutput>BZ2_bzCompressInit</computeroutput>,
-<computeroutput>BZ2_bzCompress</computeroutput>, and
-<computeroutput>BZ2_bzCompressEnd</computeroutput> for
-compression, and a corresponding trio
-<computeroutput>BZ2_bzDecompressInit</computeroutput>,
-<computeroutput>BZ2_bzDecompress</computeroutput> and
-<computeroutput>BZ2_bzDecompressEnd</computeroutput> for
-decompression.  The <computeroutput>*Init</computeroutput>
-functions allocate memory for compression/decompression and do
-other initialisations, whilst the
-<computeroutput>*End</computeroutput> functions close down
-operations and release memory.</para>
-
-<para>The real work is done by
-<computeroutput>BZ2_bzCompress</computeroutput> and
-<computeroutput>BZ2_bzDecompress</computeroutput>.  These
-compress and decompress data from a user-supplied input buffer to
-a user-supplied output buffer.  These buffers can be any size;
-arbitrary quantities of data are handled by making repeated calls
-to these functions.  This is a flexible mechanism allowing a
-consumer-pull style of activity, or producer-push, or a mixture
-of both.</para>
-
-</sect2>
-
-
-<sect2 id="hl-summary" xreflabel="High-level summary">
-<title>High-level summary</title>
-
-<para>This interface provides some handy wrappers around the
-low-level interface to facilitate reading and writing
-<computeroutput>bzip2</computeroutput> format files
-(<computeroutput>.bz2</computeroutput> files).  The routines
-provide hooks to facilitate reading files in which the
-<computeroutput>bzip2</computeroutput> data stream is embedded
-within some larger-scale file structure, or where there are
-multiple <computeroutput>bzip2</computeroutput> data streams
-concatenated end-to-end.</para>
-
-<para>For reading files,
-<computeroutput>BZ2_bzReadOpen</computeroutput>,
-<computeroutput>BZ2_bzRead</computeroutput>,
-<computeroutput>BZ2_bzReadClose</computeroutput> and 
-<computeroutput>BZ2_bzReadGetUnused</computeroutput> are
-supplied.  For writing files,
-<computeroutput>BZ2_bzWriteOpen</computeroutput>,
-<computeroutput>BZ2_bzWrite</computeroutput> and
-<computeroutput>BZ2_bzWriteFinish</computeroutput> are
-available.</para>
-
-<para>As with the low-level library, no global variables are used
-so the library is per se thread-safe.  However, if I/O errors
-occur whilst reading or writing the underlying compressed files,
-you may have to consult <computeroutput>errno</computeroutput> to
-determine the cause of the error.  In that case, you'd need a C
-library which correctly supports
-<computeroutput>errno</computeroutput> in a multithreaded
-environment.</para>
-
-<para>To make the library a little simpler and more portable,
-<computeroutput>BZ2_bzReadOpen</computeroutput> and
-<computeroutput>BZ2_bzWriteOpen</computeroutput> require you to
-pass them file handles (<computeroutput>FILE*</computeroutput>s)
-which have previously been opened for reading or writing
-respectively.  That avoids portability problems associated with
-file operations and file attributes, whilst not being much of an
-imposition on the programmer.</para>
-
-</sect2>
-
-
-<sect2 id="util-fns-summary" xreflabel="Utility functions summary">
-<title>Utility functions summary</title>
-
-<para>For very simple needs,
-<computeroutput>BZ2_bzBuffToBuffCompress</computeroutput> and
-<computeroutput>BZ2_bzBuffToBuffDecompress</computeroutput> are
-provided.  These compress data in memory from one buffer to
-another buffer in a single function call.  You should assess
-whether these functions fulfill your memory-to-memory
-compression/decompression requirements before investing effort in
-understanding the more general but more complex low-level
-interface.</para>
-
-<para>Yoshioka Tsuneo
-(<computeroutput>tsuneo@rr.iij4u.or.jp</computeroutput>) has
-contributed some functions to give better
-<computeroutput>zlib</computeroutput> compatibility.  These
-functions are <computeroutput>BZ2_bzopen</computeroutput>,
-<computeroutput>BZ2_bzread</computeroutput>,
-<computeroutput>BZ2_bzwrite</computeroutput>,
-<computeroutput>BZ2_bzflush</computeroutput>,
-<computeroutput>BZ2_bzclose</computeroutput>,
-<computeroutput>BZ2_bzerror</computeroutput> and
-<computeroutput>BZ2_bzlibVersion</computeroutput>.  You may find
-these functions more convenient for simple file reading and
-writing, than those in the high-level interface.  These functions
-are not (yet) officially part of the library, and are minimally
-documented here.  If they break, you get to keep all the pieces.
-I hope to document them properly when time permits.</para>
-
-<para>Yoshioka also contributed modifications to allow the
-library to be built as a Windows DLL.</para>
-
-</sect2>
-
-</sect1>
-
-
-<sect1 id="err-handling" xreflabel="Error handling">
-<title>Error handling</title>
-
-<para>The library is designed to recover cleanly in all
-situations, including the worst-case situation of decompressing
-random data.  I'm not 100% sure that it can always do this, so
-you might want to add a signal handler to catch segmentation
-violations during decompression if you are feeling especially
-paranoid.  I would be interested in hearing more about the
-robustness of the library to corrupted compressed data.</para>
-
-<para>Version 1.0.3 more robust in this respect than any
-previous version.  Investigations with Valgrind (a tool for detecting
-problems with memory management) indicate
-that, at least for the few files I tested, all single-bit errors
-in the decompressed data are caught properly, with no
-segmentation faults, no uses of uninitialised data, no out of
-range reads or writes, and no infinite looping in the decompressor.
-So it's certainly pretty robust, although
-I wouldn't claim it to be totally bombproof.</para>
-
-<para>The file <computeroutput>bzlib.h</computeroutput> contains
-all definitions needed to use the library.  In particular, you
-should definitely not include
-<computeroutput>bzlib_private.h</computeroutput>.</para>
-
-<para>In <computeroutput>bzlib.h</computeroutput>, the various
-return values are defined.  The following list is not intended as
-an exhaustive description of the circumstances in which a given
-value may be returned -- those descriptions are given later.
-Rather, it is intended to convey the rough meaning of each return
-value.  The first five actions are normal and not intended to
-denote an error situation.</para>
-
-<variablelist>
-
- <varlistentry>
-  <term><computeroutput>BZ_OK</computeroutput></term>
-  <listitem><para>The requested action was completed
-   successfully.</para></listitem>
- </varlistentry>
-
- <varlistentry>
-  <term><computeroutput>BZ_RUN_OK, BZ_FLUSH_OK,
-    BZ_FINISH_OK</computeroutput></term>
-  <listitem><para>In 
-   <computeroutput>BZ2_bzCompress</computeroutput>, the requested
-   flush/finish/nothing-special action was completed
-   successfully.</para></listitem>
- </varlistentry>
-
- <varlistentry>
-  <term><computeroutput>BZ_STREAM_END</computeroutput></term>
-  <listitem><para>Compression of data was completed, or the
-   logical stream end was detected during
-   decompression.</para></listitem>
- </varlistentry>
-
-</variablelist>
-
-<para>The following return values indicate an error of some
-kind.</para>
-
-<variablelist>
-
- <varlistentry>
-  <term><computeroutput>BZ_CONFIG_ERROR</computeroutput></term>
-  <listitem><para>Indicates that the library has been improperly
-   compiled on your platform -- a major configuration error.
-   Specifically, it means that
-   <computeroutput>sizeof(char)</computeroutput>,
-   <computeroutput>sizeof(short)</computeroutput> and
-   <computeroutput>sizeof(int)</computeroutput> are not 1, 2 and
-   4 respectively, as they should be.  Note that the library
-   should still work properly on 64-bit platforms which follow
-   the LP64 programming model -- that is, where
-   <computeroutput>sizeof(long)</computeroutput> and
-   <computeroutput>sizeof(void*)</computeroutput> are 8.  Under
-   LP64, <computeroutput>sizeof(int)</computeroutput> is still 4,
-   so <computeroutput>libbzip2</computeroutput>, which doesn't
-   use the <computeroutput>long</computeroutput> type, is
-   OK.</para></listitem>
- </varlistentry>
-
- <varlistentry>
-  <term><computeroutput>BZ_SEQUENCE_ERROR</computeroutput></term>
-  <listitem><para>When using the library, it is important to call
-   the functions in the correct sequence and with data structures
-   (buffers etc) in the correct states.
-   <computeroutput>libbzip2</computeroutput> checks as much as it
-   can to ensure this is happening, and returns
-   <computeroutput>BZ_SEQUENCE_ERROR</computeroutput> if not.
-   Code which complies precisely with the function semantics, as
-   detailed below, should never receive this value; such an event
-   denotes buggy code which you should
-   investigate.</para></listitem>
- </varlistentry>
-
- <varlistentry>
-  <term><computeroutput>BZ_PARAM_ERROR</computeroutput></term>
-  <listitem><para>Returned when a parameter to a function call is
-   out of range or otherwise manifestly incorrect.  As with
-   <computeroutput>BZ_SEQUENCE_ERROR</computeroutput>, this
-   denotes a bug in the client code.  The distinction between
-   <computeroutput>BZ_PARAM_ERROR</computeroutput> and
-   <computeroutput>BZ_SEQUENCE_ERROR</computeroutput> is a bit
-   hazy, but still worth making.</para></listitem>
- </varlistentry>
-
- <varlistentry>
-  <term><computeroutput>BZ_MEM_ERROR</computeroutput></term>
-  <listitem><para>Returned when a request to allocate memory
-   failed.  Note that the quantity of memory needed to decompress
-   a stream cannot be determined until the stream's header has
-   been read.  So
-   <computeroutput>BZ2_bzDecompress</computeroutput> and
-   <computeroutput>BZ2_bzRead</computeroutput> may return
-   <computeroutput>BZ_MEM_ERROR</computeroutput> even though some
-   of the compressed data has been read.  The same is not true
-   for compression; once
-   <computeroutput>BZ2_bzCompressInit</computeroutput> or
-   <computeroutput>BZ2_bzWriteOpen</computeroutput> have
-   successfully completed,
-   <computeroutput>BZ_MEM_ERROR</computeroutput> cannot
-   occur.</para></listitem>
- </varlistentry>
-
- <varlistentry>
-  <term><computeroutput>BZ_DATA_ERROR</computeroutput></term>
-  <listitem><para>Returned when a data integrity error is
-   detected during decompression.  Most importantly, this means
-   when stored and computed CRCs for the data do not match.  This
-   value is also returned upon detection of any other anomaly in
-   the compressed data.</para></listitem>
- </varlistentry>
-
- <varlistentry>
-  <term><computeroutput>BZ_DATA_ERROR_MAGIC</computeroutput></term>
-  <listitem><para>As a special case of
-   <computeroutput>BZ_DATA_ERROR</computeroutput>, it is
-   sometimes useful to know when the compressed stream does not
-   start with the correct magic bytes (<computeroutput>'B' 'Z'
-   'h'</computeroutput>).</para></listitem>
- </varlistentry>
-
- <varlistentry>
-  <term><computeroutput>BZ_IO_ERROR</computeroutput></term>
-  <listitem><para>Returned by
-   <computeroutput>BZ2_bzRead</computeroutput> and
-   <computeroutput>BZ2_bzWrite</computeroutput> when there is an
-   error reading or writing in the compressed file, and by
-   <computeroutput>BZ2_bzReadOpen</computeroutput> and
-   <computeroutput>BZ2_bzWriteOpen</computeroutput> for attempts
-   to use a file for which the error indicator (viz,
-   <computeroutput>ferror(f)</computeroutput>) is set.  On
-   receipt of <computeroutput>BZ_IO_ERROR</computeroutput>, the
-   caller should consult <computeroutput>errno</computeroutput>
-   and/or <computeroutput>perror</computeroutput> to acquire
-   operating-system specific information about the
-   problem.</para></listitem>
- </varlistentry>
-
- <varlistentry>
-  <term><computeroutput>BZ_UNEXPECTED_EOF</computeroutput></term>
-  <listitem><para>Returned by
-   <computeroutput>BZ2_bzRead</computeroutput> when the
-   compressed file finishes before the logical end of stream is
-   detected.</para></listitem>
- </varlistentry>
-
- <varlistentry>
-  <term><computeroutput>BZ_OUTBUFF_FULL</computeroutput></term>
-  <listitem><para>Returned by
-   <computeroutput>BZ2_bzBuffToBuffCompress</computeroutput> and
-   <computeroutput>BZ2_bzBuffToBuffDecompress</computeroutput> to
-   indicate that the output data will not fit into the output
-   buffer provided.</para></listitem>
- </varlistentry>
-
-</variablelist>
-
-</sect1>
-
-
-
-<sect1 id="low-level" xreflabel=">Low-level interface">
-<title>Low-level interface</title>
-
-
-<sect2 id="bzcompress-init" xreflabel="BZ2_bzCompressInit">
-<title><computeroutput>BZ2_bzCompressInit</computeroutput></title>
-
-<programlisting>
-typedef struct {
-  char *next_in;
-  unsigned int avail_in;
-  unsigned int total_in_lo32;
-  unsigned int total_in_hi32;
-
-  char *next_out;
-  unsigned int avail_out;
-  unsigned int total_out_lo32;
-  unsigned int total_out_hi32;
-
-  void *state;
-
-  void *(*bzalloc)(void *,int,int);
-  void (*bzfree)(void *,void *);
-  void *opaque;
-} bz_stream;
-
-int BZ2_bzCompressInit ( bz_stream *strm, 
-                         int blockSize100k, 
-                         int verbosity,
-                         int workFactor );
-</programlisting>
-
-<para>Prepares for compression.  The
-<computeroutput>bz_stream</computeroutput> structure holds all
-data pertaining to the compression activity.  A
-<computeroutput>bz_stream</computeroutput> structure should be
-allocated and initialised prior to the call.  The fields of
-<computeroutput>bz_stream</computeroutput> comprise the entirety
-of the user-visible data.  <computeroutput>state</computeroutput>
-is a pointer to the private data structures required for
-compression.</para>
-
-<para>Custom memory allocators are supported, via fields
-<computeroutput>bzalloc</computeroutput>,
-<computeroutput>bzfree</computeroutput>, and
-<computeroutput>opaque</computeroutput>.  The value
-<computeroutput>opaque</computeroutput> is passed to as the first
-argument to all calls to <computeroutput>bzalloc</computeroutput>
-and <computeroutput>bzfree</computeroutput>, but is otherwise
-ignored by the library.  The call <computeroutput>bzalloc (
-opaque, n, m )</computeroutput> is expected to return a pointer
-<computeroutput>p</computeroutput> to <computeroutput>n *
-m</computeroutput> bytes of memory, and <computeroutput>bzfree (
-opaque, p )</computeroutput> should free that memory.</para>
-
-<para>If you don't want to use a custom memory allocator, set
-<computeroutput>bzalloc</computeroutput>,
-<computeroutput>bzfree</computeroutput> and
-<computeroutput>opaque</computeroutput> to
-<computeroutput>NULL</computeroutput>, and the library will then
-use the standard <computeroutput>malloc</computeroutput> /
-<computeroutput>free</computeroutput> routines.</para>
-
-<para>Before calling
-<computeroutput>BZ2_bzCompressInit</computeroutput>, fields
-<computeroutput>bzalloc</computeroutput>,
-<computeroutput>bzfree</computeroutput> and
-<computeroutput>opaque</computeroutput> should be filled
-appropriately, as just described.  Upon return, the internal
-state will have been allocated and initialised, and
-<computeroutput>total_in_lo32</computeroutput>,
-<computeroutput>total_in_hi32</computeroutput>,
-<computeroutput>total_out_lo32</computeroutput> and
-<computeroutput>total_out_hi32</computeroutput> will have been
-set to zero.  These four fields are used by the library to inform
-the caller of the total amount of data passed into and out of the
-library, respectively.  You should not try to change them.  As of
-version 1.0, 64-bit counts are maintained, even on 32-bit
-platforms, using the <computeroutput>_hi32</computeroutput>
-fields to store the upper 32 bits of the count.  So, for example,
-the total amount of data in is <computeroutput>(total_in_hi32
-&#60;&#60; 32) + total_in_lo32</computeroutput>.</para>
-
-<para>Parameter <computeroutput>blockSize100k</computeroutput>
-specifies the block size to be used for compression.  It should
-be a value between 1 and 9 inclusive, and the actual block size
-used is 100000 x this figure.  9 gives the best compression but
-takes most memory.</para>
-
-<para>Parameter <computeroutput>verbosity</computeroutput> should
-be set to a number between 0 and 4 inclusive.  0 is silent, and
-greater numbers give increasingly verbose monitoring/debugging
-output.  If the library has been compiled with
-<computeroutput>-DBZ_NO_STDIO</computeroutput>, no such output
-will appear for any verbosity setting.</para>
-
-<para>Parameter <computeroutput>workFactor</computeroutput>
-controls how the compression phase behaves when presented with
-worst case, highly repetitive, input data.  If compression runs
-into difficulties caused by repetitive data, the library switches
-from the standard sorting algorithm to a fallback algorithm.  The
-fallback is slower than the standard algorithm by perhaps a
-factor of three, but always behaves reasonably, no matter how bad
-the input.</para>
-
-<para>Lower values of <computeroutput>workFactor</computeroutput>
-reduce the amount of effort the standard algorithm will expend
-before resorting to the fallback.  You should set this parameter
-carefully; too low, and many inputs will be handled by the
-fallback algorithm and so compress rather slowly, too high, and
-your average-to-worst case compression times can become very
-large.  The default value of 30 gives reasonable behaviour over a
-wide range of circumstances.</para>
-
-<para>Allowable values range from 0 to 250 inclusive.  0 is a
-special case, equivalent to using the default value of 30.</para>
-
-<para>Note that the compressed output generated is the same
-regardless of whether or not the fallback algorithm is
-used.</para>
-
-<para>Be aware also that this parameter may disappear entirely in
-future versions of the library.  In principle it should be
-possible to devise a good way to automatically choose which
-algorithm to use.  Such a mechanism would render the parameter
-obsolete.</para>
-
-<para>Possible return values:</para>
-
-<programlisting>
-BZ_CONFIG_ERROR
-  if the library has been mis-compiled
-BZ_PARAM_ERROR
-  if strm is NULL 
-  or blockSize < 1 or blockSize > 9
-  or verbosity < 0 or verbosity > 4
-  or workFactor < 0 or workFactor > 250
-BZ_MEM_ERROR 
-  if not enough memory is available
-BZ_OK 
-  otherwise
-</programlisting>
-
-<para>Allowable next actions:</para>
-
-<programlisting>
-BZ2_bzCompress
-  if BZ_OK is returned
-  no specific action needed in case of error
-</programlisting>
-
-</sect2>
-
-
-<sect2 id="bzCompress" xreflabel="BZ2_bzCompress">
-<title><computeroutput>BZ2_bzCompress</computeroutput></title>
-
-<programlisting>
-int BZ2_bzCompress ( bz_stream *strm, int action );
-</programlisting>
-
-<para>Provides more input and/or output buffer space for the
-library.  The caller maintains input and output buffers, and
-calls <computeroutput>BZ2_bzCompress</computeroutput> to transfer
-data between them.</para>
-
-<para>Before each call to
-<computeroutput>BZ2_bzCompress</computeroutput>,
-<computeroutput>next_in</computeroutput> should point at the data
-to be compressed, and <computeroutput>avail_in</computeroutput>
-should indicate how many bytes the library may read.
-<computeroutput>BZ2_bzCompress</computeroutput> updates
-<computeroutput>next_in</computeroutput>,
-<computeroutput>avail_in</computeroutput> and
-<computeroutput>total_in</computeroutput> to reflect the number
-of bytes it has read.</para>
-
-<para>Similarly, <computeroutput>next_out</computeroutput> should
-point to a buffer in which the compressed data is to be placed,
-with <computeroutput>avail_out</computeroutput> indicating how
-much output space is available.
-<computeroutput>BZ2_bzCompress</computeroutput> updates
-<computeroutput>next_out</computeroutput>,
-<computeroutput>avail_out</computeroutput> and
-<computeroutput>total_out</computeroutput> to reflect the number
-of bytes output.</para>
-
-<para>You may provide and remove as little or as much data as you
-like on each call of
-<computeroutput>BZ2_bzCompress</computeroutput>.  In the limit,
-it is acceptable to supply and remove data one byte at a time,
-although this would be terribly inefficient.  You should always
-ensure that at least one byte of output space is available at
-each call.</para>
-
-<para>A second purpose of
-<computeroutput>BZ2_bzCompress</computeroutput> is to request a
-change of mode of the compressed stream.</para>
-
-<para>Conceptually, a compressed stream can be in one of four
-states: IDLE, RUNNING, FLUSHING and FINISHING.  Before
-initialisation
-(<computeroutput>BZ2_bzCompressInit</computeroutput>) and after
-termination (<computeroutput>BZ2_bzCompressEnd</computeroutput>),
-a stream is regarded as IDLE.</para>
-
-<para>Upon initialisation
-(<computeroutput>BZ2_bzCompressInit</computeroutput>), the stream
-is placed in the RUNNING state.  Subsequent calls to
-<computeroutput>BZ2_bzCompress</computeroutput> should pass
-<computeroutput>BZ_RUN</computeroutput> as the requested action;
-other actions are illegal and will result in
-<computeroutput>BZ_SEQUENCE_ERROR</computeroutput>.</para>
-
-<para>At some point, the calling program will have provided all
-the input data it wants to.  It will then want to finish up -- in
-effect, asking the library to process any data it might have
-buffered internally.  In this state,
-<computeroutput>BZ2_bzCompress</computeroutput> will no longer
-attempt to read data from
-<computeroutput>next_in</computeroutput>, but it will want to
-write data to <computeroutput>next_out</computeroutput>.  Because
-the output buffer supplied by the user can be arbitrarily small,
-the finishing-up operation cannot necessarily be done with a
-single call of
-<computeroutput>BZ2_bzCompress</computeroutput>.</para>
-
-<para>Instead, the calling program passes
-<computeroutput>BZ_FINISH</computeroutput> as an action to
-<computeroutput>BZ2_bzCompress</computeroutput>.  This changes
-the stream's state to FINISHING.  Any remaining input (ie,
-<computeroutput>next_in[0 .. avail_in-1]</computeroutput>) is
-compressed and transferred to the output buffer.  To do this,
-<computeroutput>BZ2_bzCompress</computeroutput> must be called
-repeatedly until all the output has been consumed.  At that
-point, <computeroutput>BZ2_bzCompress</computeroutput> returns
-<computeroutput>BZ_STREAM_END</computeroutput>, and the stream's
-state is set back to IDLE.
-<computeroutput>BZ2_bzCompressEnd</computeroutput> should then be
-called.</para>
-
-<para>Just to make sure the calling program does not cheat, the
-library makes a note of <computeroutput>avail_in</computeroutput>
-at the time of the first call to
-<computeroutput>BZ2_bzCompress</computeroutput> which has
-<computeroutput>BZ_FINISH</computeroutput> as an action (ie, at
-the time the program has announced its intention to not supply
-any more input).  By comparing this value with that of
-<computeroutput>avail_in</computeroutput> over subsequent calls
-to <computeroutput>BZ2_bzCompress</computeroutput>, the library
-can detect any attempts to slip in more data to compress.  Any
-calls for which this is detected will return
-<computeroutput>BZ_SEQUENCE_ERROR</computeroutput>.  This
-indicates a programming mistake which should be corrected.</para>
-
-<para>Instead of asking to finish, the calling program may ask
-<computeroutput>BZ2_bzCompress</computeroutput> to take all the
-remaining input, compress it and terminate the current
-(Burrows-Wheeler) compression block.  This could be useful for
-error control purposes.  The mechanism is analogous to that for
-finishing: call <computeroutput>BZ2_bzCompress</computeroutput>
-with an action of <computeroutput>BZ_FLUSH</computeroutput>,
-remove output data, and persist with the
-<computeroutput>BZ_FLUSH</computeroutput> action until the value
-<computeroutput>BZ_RUN</computeroutput> is returned.  As with
-finishing, <computeroutput>BZ2_bzCompress</computeroutput>
-detects any attempt to provide more input data once the flush has
-begun.</para>
-
-<para>Once the flush is complete, the stream returns to the
-normal RUNNING state.</para>
-
-<para>This all sounds pretty complex, but isn't really.  Here's a
-table which shows which actions are allowable in each state, what
-action will be taken, what the next state is, and what the
-non-error return values are.  Note that you can't explicitly ask
-what state the stream is in, but nor do you need to -- it can be
-inferred from the values returned by
-<computeroutput>BZ2_bzCompress</computeroutput>.</para>
-
-<programlisting>
-IDLE/any
-  Illegal.  IDLE state only exists after BZ2_bzCompressEnd or
-  before BZ2_bzCompressInit.
-  Return value = BZ_SEQUENCE_ERROR
-
-RUNNING/BZ_RUN
-  Compress from next_in to next_out as much as possible.
-  Next state = RUNNING
-  Return value = BZ_RUN_OK
-
-RUNNING/BZ_FLUSH
-  Remember current value of next_in. Compress from next_in
-  to next_out as much as possible, but do not accept any more input.
-  Next state = FLUSHING
-  Return value = BZ_FLUSH_OK
-
-RUNNING/BZ_FINISH
-  Remember current value of next_in. Compress from next_in
-  to next_out as much as possible, but do not accept any more input.
-  Next state = FINISHING
-  Return value = BZ_FINISH_OK
-
-FLUSHING/BZ_FLUSH
-  Compress from next_in to next_out as much as possible, 
-  but do not accept any more input.
-  If all the existing input has been used up and all compressed
-  output has been removed
-    Next state = RUNNING; Return value = BZ_RUN_OK
-  else
-    Next state = FLUSHING; Return value = BZ_FLUSH_OK
-
-FLUSHING/other     
-  Illegal.
-  Return value = BZ_SEQUENCE_ERROR
-
-FINISHING/BZ_FINISH
-  Compress from next_in to next_out as much as possible,
-  but to not accept any more input.  
-  If all the existing input has been used up and all compressed
-  output has been removed
-    Next state = IDLE; Return value = BZ_STREAM_END
-  else
-    Next state = FINISHING; Return value = BZ_FINISH_OK
-
-FINISHING/other
-  Illegal.
-  Return value = BZ_SEQUENCE_ERROR
-</programlisting>
-
-
-<para>That still looks complicated?  Well, fair enough.  The
-usual sequence of calls for compressing a load of data is:</para>
-
-<orderedlist>
-
- <listitem><para>Get started with
-  <computeroutput>BZ2_bzCompressInit</computeroutput>.</para></listitem>
-
- <listitem><para>Shovel data in and shlurp out its compressed form
-  using zero or more calls of
-  <computeroutput>BZ2_bzCompress</computeroutput> with action =
-  <computeroutput>BZ_RUN</computeroutput>.</para></listitem>
-
- <listitem><para>Finish up. Repeatedly call
-  <computeroutput>BZ2_bzCompress</computeroutput> with action =
-  <computeroutput>BZ_FINISH</computeroutput>, copying out the
-  compressed output, until
-  <computeroutput>BZ_STREAM_END</computeroutput> is
-  returned.</para></listitem> <listitem><para>Close up and go home.  Call
-  <computeroutput>BZ2_bzCompressEnd</computeroutput>.</para></listitem>
-
-</orderedlist>
-
-<para>If the data you want to compress fits into your input
-buffer all at once, you can skip the calls of
-<computeroutput>BZ2_bzCompress ( ..., BZ_RUN )</computeroutput>
-and just do the <computeroutput>BZ2_bzCompress ( ..., BZ_FINISH
-)</computeroutput> calls.</para>
-
-<para>All required memory is allocated by
-<computeroutput>BZ2_bzCompressInit</computeroutput>.  The
-compression library can accept any data at all (obviously).  So
-you shouldn't get any error return values from the
-<computeroutput>BZ2_bzCompress</computeroutput> calls.  If you
-do, they will be
-<computeroutput>BZ_SEQUENCE_ERROR</computeroutput>, and indicate
-a bug in your programming.</para>
-
-<para>Trivial other possible return values:</para>
-
-<programlisting>
-BZ_PARAM_ERROR
-  if strm is NULL, or strm->s is NULL
-</programlisting>
-
-</sect2>
-
-
-<sect2 id="bzCompress-end" xreflabel="BZ2_bzCompressEnd">
-<title><computeroutput>BZ2_bzCompressEnd</computeroutput></title>
-
-<programlisting>
-int BZ2_bzCompressEnd ( bz_stream *strm );
-</programlisting>
-
-<para>Releases all memory associated with a compression
-stream.</para>
-
-<para>Possible return values:</para>
-
-<programlisting>
-BZ_PARAM_ERROR  if strm is NULL or strm->s is NULL
-BZ_OK           otherwise
-</programlisting>
-
-</sect2>
-
-
-<sect2 id="bzDecompress-init" xreflabel="BZ2_bzDecompressInit">
-<title><computeroutput>BZ2_bzDecompressInit</computeroutput></title>
-
-<programlisting>
-int BZ2_bzDecompressInit ( bz_stream *strm, int verbosity, int small );
-</programlisting>
-
-<para>Prepares for decompression.  As with
-<computeroutput>BZ2_bzCompressInit</computeroutput>, a
-<computeroutput>bz_stream</computeroutput> record should be
-allocated and initialised before the call.  Fields
-<computeroutput>bzalloc</computeroutput>,
-<computeroutput>bzfree</computeroutput> and
-<computeroutput>opaque</computeroutput> should be set if a custom
-memory allocator is required, or made
-<computeroutput>NULL</computeroutput> for the normal
-<computeroutput>malloc</computeroutput> /
-<computeroutput>free</computeroutput> routines.  Upon return, the
-internal state will have been initialised, and
-<computeroutput>total_in</computeroutput> and
-<computeroutput>total_out</computeroutput> will be zero.</para>
-
-<para>For the meaning of parameter
-<computeroutput>verbosity</computeroutput>, see
-<computeroutput>BZ2_bzCompressInit</computeroutput>.</para>
-
-<para>If <computeroutput>small</computeroutput> is nonzero, the
-library will use an alternative decompression algorithm which
-uses less memory but at the cost of decompressing more slowly
-(roughly speaking, half the speed, but the maximum memory
-requirement drops to around 2300k).  See <xref linkend="using"/>
-for more information on memory management.</para>
-
-<para>Note that the amount of memory needed to decompress a
-stream cannot be determined until the stream's header has been
-read, so even if
-<computeroutput>BZ2_bzDecompressInit</computeroutput> succeeds, a
-subsequent <computeroutput>BZ2_bzDecompress</computeroutput>
-could fail with
-<computeroutput>BZ_MEM_ERROR</computeroutput>.</para>
-
-<para>Possible return values:</para>
-
-<programlisting>
-BZ_CONFIG_ERROR
-  if the library has been mis-compiled
-BZ_PARAM_ERROR
-  if ( small != 0 && small != 1 )
-  or (verbosity <; 0 || verbosity > 4)
-BZ_MEM_ERROR
-  if insufficient memory is available
-</programlisting>
-
-<para>Allowable next actions:</para>
-
-<programlisting>
-BZ2_bzDecompress
-  if BZ_OK was returned
-  no specific action required in case of error
-</programlisting>
-
-</sect2>
-
-
-<sect2 id="bzDecompress" xreflabel="BZ2_bzDecompress">
-<title><computeroutput>BZ2_bzDecompress</computeroutput></title>
-
-<programlisting>
-int BZ2_bzDecompress ( bz_stream *strm );
-</programlisting>
-
-<para>Provides more input and/out output buffer space for the
-library.  The caller maintains input and output buffers, and uses
-<computeroutput>BZ2_bzDecompress</computeroutput> to transfer
-data between them.</para>
-
-<para>Before each call to
-<computeroutput>BZ2_bzDecompress</computeroutput>,
-<computeroutput>next_in</computeroutput> should point at the
-compressed data, and <computeroutput>avail_in</computeroutput>
-should indicate how many bytes the library may read.
-<computeroutput>BZ2_bzDecompress</computeroutput> updates
-<computeroutput>next_in</computeroutput>,
-<computeroutput>avail_in</computeroutput> and
-<computeroutput>total_in</computeroutput> to reflect the number
-of bytes it has read.</para>
-
-<para>Similarly, <computeroutput>next_out</computeroutput> should
-point to a buffer in which the uncompressed output is to be
-placed, with <computeroutput>avail_out</computeroutput>
-indicating how much output space is available.
-<computeroutput>BZ2_bzCompress</computeroutput> updates
-<computeroutput>next_out</computeroutput>,
-<computeroutput>avail_out</computeroutput> and
-<computeroutput>total_out</computeroutput> to reflect the number
-of bytes output.</para>
-
-<para>You may provide and remove as little or as much data as you
-like on each call of
-<computeroutput>BZ2_bzDecompress</computeroutput>.  In the limit,
-it is acceptable to supply and remove data one byte at a time,
-although this would be terribly inefficient.  You should always
-ensure that at least one byte of output space is available at
-each call.</para>
-
-<para>Use of <computeroutput>BZ2_bzDecompress</computeroutput> is
-simpler than
-<computeroutput>BZ2_bzCompress</computeroutput>.</para>
-
-<para>You should provide input and remove output as described
-above, and repeatedly call
-<computeroutput>BZ2_bzDecompress</computeroutput> until
-<computeroutput>BZ_STREAM_END</computeroutput> is returned.
-Appearance of <computeroutput>BZ_STREAM_END</computeroutput>
-denotes that <computeroutput>BZ2_bzDecompress</computeroutput>
-has detected the logical end of the compressed stream.
-<computeroutput>BZ2_bzDecompress</computeroutput> will not
-produce <computeroutput>BZ_STREAM_END</computeroutput> until all
-output data has been placed into the output buffer, so once
-<computeroutput>BZ_STREAM_END</computeroutput> appears, you are
-guaranteed to have available all the decompressed output, and
-<computeroutput>BZ2_bzDecompressEnd</computeroutput> can safely
-be called.</para>
-
-<para>If case of an error return value, you should call
-<computeroutput>BZ2_bzDecompressEnd</computeroutput> to clean up
-and release memory.</para>
-
-<para>Possible return values:</para>
-
-<programlisting>
-BZ_PARAM_ERROR
-  if strm is NULL or strm->s is NULL
-  or strm->avail_out < 1
-BZ_DATA_ERROR
-  if a data integrity error is detected in the compressed stream
-BZ_DATA_ERROR_MAGIC
-  if the compressed stream doesn't begin with the right magic bytes
-BZ_MEM_ERROR
-  if there wasn't enough memory available
-BZ_STREAM_END
-  if the logical end of the data stream was detected and all
-  output in has been consumed, eg s-->avail_out > 0
-BZ_OK
-  otherwise
-</programlisting>
-
-<para>Allowable next actions:</para>
-
-<programlisting>
-BZ2_bzDecompress
-  if BZ_OK was returned
-BZ2_bzDecompressEnd
-  otherwise
-</programlisting>
-
-</sect2>
-
-
-<sect2 id="bzDecompress-end" xreflabel="BZ2_bzDecompressEnd">
-<title><computeroutput>BZ2_bzDecompressEnd</computeroutput></title>
-
-<programlisting>
-int BZ2_bzDecompressEnd ( bz_stream *strm );
-</programlisting>
-
-<para>Releases all memory associated with a decompression
-stream.</para>
-
-<para>Possible return values:</para>
-
-<programlisting>
-BZ_PARAM_ERROR
-  if strm is NULL or strm->s is NULL
-BZ_OK
-  otherwise
-</programlisting>
-
-<para>Allowable next actions:</para>
-
-<programlisting>
-  None.
-</programlisting>
-
-</sect2>
-
-</sect1>
-
-
-<sect1 id="hl-interface" xreflabel="High-level interface">
-<title>High-level interface</title>
-
-<para>This interface provides functions for reading and writing
-<computeroutput>bzip2</computeroutput> format files.  First, some
-general points.</para>
-
-<itemizedlist mark='bullet'>
-
- <listitem><para>All of the functions take an
-  <computeroutput>int*</computeroutput> first argument,
-  <computeroutput>bzerror</computeroutput>.  After each call,
-  <computeroutput>bzerror</computeroutput> should be consulted
-  first to determine the outcome of the call.  If
-  <computeroutput>bzerror</computeroutput> is
-  <computeroutput>BZ_OK</computeroutput>, the call completed
-  successfully, and only then should the return value of the
-  function (if any) be consulted.  If
-  <computeroutput>bzerror</computeroutput> is
-  <computeroutput>BZ_IO_ERROR</computeroutput>, there was an
-  error reading/writing the underlying compressed file, and you
-  should then consult <computeroutput>errno</computeroutput> /
-  <computeroutput>perror</computeroutput> to determine the cause
-  of the difficulty.  <computeroutput>bzerror</computeroutput>
-  may also be set to various other values; precise details are
-  given on a per-function basis below.</para></listitem>
-
- <listitem><para>If <computeroutput>bzerror</computeroutput> indicates
-  an error (ie, anything except
-  <computeroutput>BZ_OK</computeroutput> and
-  <computeroutput>BZ_STREAM_END</computeroutput>), you should
-  immediately call
-  <computeroutput>BZ2_bzReadClose</computeroutput> (or
-  <computeroutput>BZ2_bzWriteClose</computeroutput>, depending on
-  whether you are attempting to read or to write) to free up all
-  resources associated with the stream.  Once an error has been
-  indicated, behaviour of all calls except
-  <computeroutput>BZ2_bzReadClose</computeroutput>
-  (<computeroutput>BZ2_bzWriteClose</computeroutput>) is
-  undefined.  The implication is that (1)
-  <computeroutput>bzerror</computeroutput> should be checked
-  after each call, and (2) if
-  <computeroutput>bzerror</computeroutput> indicates an error,
-  <computeroutput>BZ2_bzReadClose</computeroutput>
-  (<computeroutput>BZ2_bzWriteClose</computeroutput>) should then
-  be called to clean up.</para></listitem>
-
- <listitem><para>The <computeroutput>FILE*</computeroutput> arguments
-  passed to <computeroutput>BZ2_bzReadOpen</computeroutput> /
-  <computeroutput>BZ2_bzWriteOpen</computeroutput> should be set
-  to binary mode.  Most Unix systems will do this by default, but
-  other platforms, including Windows and Mac, will not.  If you
-  omit this, you may encounter problems when moving code to new
-  platforms.</para></listitem>
-
- <listitem><para>Memory allocation requests are handled by
-  <computeroutput>malloc</computeroutput> /
-  <computeroutput>free</computeroutput>.  At present there is no
-  facility for user-defined memory allocators in the file I/O
-  functions (could easily be added, though).</para></listitem>
-
-</itemizedlist>
-
-
-
-<sect2 id="bzreadopen" xreflabel="BZ2_bzReadOpen">
-<title><computeroutput>BZ2_bzReadOpen</computeroutput></title>
-
-<programlisting>
-typedef void BZFILE;
-
-BZFILE *BZ2_bzReadOpen( int *bzerror, FILE *f, 
-                        int verbosity, int small,
-                        void *unused, int nUnused );
-</programlisting>
-
-<para>Prepare to read compressed data from file handle
-<computeroutput>f</computeroutput>.
-<computeroutput>f</computeroutput> should refer to a file which
-has been opened for reading, and for which the error indicator
-(<computeroutput>ferror(f)</computeroutput>)is not set.  If
-<computeroutput>small</computeroutput> is 1, the library will try
-to decompress using less memory, at the expense of speed.</para>
-
-<para>For reasons explained below,
-<computeroutput>BZ2_bzRead</computeroutput> will decompress the
-<computeroutput>nUnused</computeroutput> bytes starting at
-<computeroutput>unused</computeroutput>, before starting to read
-from the file <computeroutput>f</computeroutput>.  At most
-<computeroutput>BZ_MAX_UNUSED</computeroutput> bytes may be
-supplied like this.  If this facility is not required, you should
-pass <computeroutput>NULL</computeroutput> and
-<computeroutput>0</computeroutput> for
-<computeroutput>unused</computeroutput> and
-n<computeroutput>Unused</computeroutput> respectively.</para>
-
-<para>For the meaning of parameters
-<computeroutput>small</computeroutput> and
-<computeroutput>verbosity</computeroutput>, see
-<computeroutput>BZ2_bzDecompressInit</computeroutput>.</para>
-
-<para>The amount of memory needed to decompress a file cannot be
-determined until the file's header has been read.  So it is
-possible that <computeroutput>BZ2_bzReadOpen</computeroutput>
-returns <computeroutput>BZ_OK</computeroutput> but a subsequent
-call of <computeroutput>BZ2_bzRead</computeroutput> will return
-<computeroutput>BZ_MEM_ERROR</computeroutput>.</para>
-
-<para>Possible assignments to
-<computeroutput>bzerror</computeroutput>:</para>
-
-<programlisting>
-BZ_CONFIG_ERROR
-  if the library has been mis-compiled
-BZ_PARAM_ERROR
-  if f is NULL
-  or small is neither 0 nor 1
-  or ( unused == NULL && nUnused != 0 )
-  or ( unused != NULL && !(0 <= nUnused <= BZ_MAX_UNUSED) )
-BZ_IO_ERROR
-  if ferror(f) is nonzero
-BZ_MEM_ERROR
-  if insufficient memory is available
-BZ_OK
-  otherwise.
-</programlisting>
-
-<para>Possible return values:</para>
-
-<programlisting>
-Pointer to an abstract BZFILE
-  if bzerror is BZ_OK
-NULL
-  otherwise
-</programlisting>
-
-<para>Allowable next actions:</para>
-
-<programlisting>
-BZ2_bzRead
-  if bzerror is BZ_OK
-BZ2_bzClose
-  otherwise
-</programlisting>
-
-</sect2>
-
-
-<sect2 id="bzread" xreflabel="BZ2_bzRead">
-<title><computeroutput>BZ2_bzRead</computeroutput></title>
-
-<programlisting>
-int BZ2_bzRead ( int *bzerror, BZFILE *b, void *buf, int len );
-</programlisting>
-
-<para>Reads up to <computeroutput>len</computeroutput>
-(uncompressed) bytes from the compressed file
-<computeroutput>b</computeroutput> into the buffer
-<computeroutput>buf</computeroutput>.  If the read was
-successful, <computeroutput>bzerror</computeroutput> is set to
-<computeroutput>BZ_OK</computeroutput> and the number of bytes
-read is returned.  If the logical end-of-stream was detected,
-<computeroutput>bzerror</computeroutput> will be set to
-<computeroutput>BZ_STREAM_END</computeroutput>, and the number of
-bytes read is returned.  All other
-<computeroutput>bzerror</computeroutput> values denote an
-error.</para>
-
-<para><computeroutput>BZ2_bzRead</computeroutput> will supply
-<computeroutput>len</computeroutput> bytes, unless the logical
-stream end is detected or an error occurs.  Because of this, it
-is possible to detect the stream end by observing when the number
-of bytes returned is less than the number requested.
-Nevertheless, this is regarded as inadvisable; you should instead
-check <computeroutput>bzerror</computeroutput> after every call
-and watch out for
-<computeroutput>BZ_STREAM_END</computeroutput>.</para>
-
-<para>Internally, <computeroutput>BZ2_bzRead</computeroutput>
-copies data from the compressed file in chunks of size
-<computeroutput>BZ_MAX_UNUSED</computeroutput> bytes before
-decompressing it.  If the file contains more bytes than strictly
-needed to reach the logical end-of-stream,
-<computeroutput>BZ2_bzRead</computeroutput> will almost certainly
-read some of the trailing data before signalling
-<computeroutput>BZ_SEQUENCE_END</computeroutput>.  To collect the
-read but unused data once
-<computeroutput>BZ_SEQUENCE_END</computeroutput> has appeared,
-call <computeroutput>BZ2_bzReadGetUnused</computeroutput>
-immediately before
-<computeroutput>BZ2_bzReadClose</computeroutput>.</para>
-
-<para>Possible assignments to
-<computeroutput>bzerror</computeroutput>:</para>
-
-<programlisting>
-BZ_PARAM_ERROR
-  if b is NULL or buf is NULL or len < 0
-BZ_SEQUENCE_ERROR
-  if b was opened with BZ2_bzWriteOpen
-BZ_IO_ERROR
-  if there is an error reading from the compressed file
-BZ_UNEXPECTED_EOF
-  if the compressed file ended before 
-  the logical end-of-stream was detected
-BZ_DATA_ERROR
-  if a data integrity error was detected in the compressed stream
-BZ_DATA_ERROR_MAGIC
-  if the stream does not begin with the requisite header bytes 
-  (ie, is not a bzip2 data file).  This is really 
-  a special case of BZ_DATA_ERROR.
-BZ_MEM_ERROR
-  if insufficient memory was available
-BZ_STREAM_END
-  if the logical end of stream was detected.
-BZ_OK
-  otherwise.
-</programlisting>
-
-<para>Possible return values:</para>
-
-<programlisting>
-number of bytes read
-  if bzerror is BZ_OK or BZ_STREAM_END
-undefined
-  otherwise
-</programlisting>
-
-<para>Allowable next actions:</para>
-
-<programlisting>
-collect data from buf, then BZ2_bzRead or BZ2_bzReadClose
-  if bzerror is BZ_OK
-collect data from buf, then BZ2_bzReadClose or BZ2_bzReadGetUnused
-  if bzerror is BZ_SEQUENCE_END
-BZ2_bzReadClose
-  otherwise
-</programlisting>
-
-</sect2>
-
-
-<sect2 id="bzreadgetunused" xreflabel="BZ2_bzReadGetUnused">
-<title><computeroutput>BZ2_bzReadGetUnused</computeroutput></title>
-
-<programlisting>
-void BZ2_bzReadGetUnused( int* bzerror, BZFILE *b, 
-                          void** unused, int* nUnused );
-</programlisting>
-
-<para>Returns data which was read from the compressed file but
-was not needed to get to the logical end-of-stream.
-<computeroutput>*unused</computeroutput> is set to the address of
-the data, and <computeroutput>*nUnused</computeroutput> to the
-number of bytes.  <computeroutput>*nUnused</computeroutput> will
-be set to a value between <computeroutput>0</computeroutput> and
-<computeroutput>BZ_MAX_UNUSED</computeroutput> inclusive.</para>
-
-<para>This function may only be called once
-<computeroutput>BZ2_bzRead</computeroutput> has signalled
-<computeroutput>BZ_STREAM_END</computeroutput> but before
-<computeroutput>BZ2_bzReadClose</computeroutput>.</para>
-
-<para>Possible assignments to
-<computeroutput>bzerror</computeroutput>:</para>
-
-<programlisting>
-BZ_PARAM_ERROR
-  if b is NULL
-  or unused is NULL or nUnused is NULL
-BZ_SEQUENCE_ERROR
-  if BZ_STREAM_END has not been signalled
-  or if b was opened with BZ2_bzWriteOpen
-BZ_OK
-  otherwise
-</programlisting>
-
-<para>Allowable next actions:</para>
-
-<programlisting>
-BZ2_bzReadClose
-</programlisting>
-
-</sect2>
-
-
-<sect2 id="bzreadclose" xreflabel="BZ2_bzReadClose">
-<title><computeroutput>BZ2_bzReadClose</computeroutput></title>
-
-<programlisting>
-void BZ2_bzReadClose ( int *bzerror, BZFILE *b );
-</programlisting>
-
-<para>Releases all memory pertaining to the compressed file
-<computeroutput>b</computeroutput>.
-<computeroutput>BZ2_bzReadClose</computeroutput> does not call
-<computeroutput>fclose</computeroutput> on the underlying file
-handle, so you should do that yourself if appropriate.
-<computeroutput>BZ2_bzReadClose</computeroutput> should be called
-to clean up after all error situations.</para>
-
-<para>Possible assignments to
-<computeroutput>bzerror</computeroutput>:</para>
-
-<programlisting>
-BZ_SEQUENCE_ERROR
-  if b was opened with BZ2_bzOpenWrite
-BZ_OK
-  otherwise
-</programlisting>
-
-<para>Allowable next actions:</para>
-
-<programlisting>
-none
-</programlisting>
-
-</sect2>
-
-
-<sect2 id="bzwriteopen" xreflabel="BZ2_bzWriteOpen">
-<title><computeroutput>BZ2_bzWriteOpen</computeroutput></title>
-
-<programlisting>
-BZFILE *BZ2_bzWriteOpen( int *bzerror, FILE *f, 
-                         int blockSize100k, int verbosity,
-                         int workFactor );
-</programlisting>
-
-<para>Prepare to write compressed data to file handle
-<computeroutput>f</computeroutput>.
-<computeroutput>f</computeroutput> should refer to a file which
-has been opened for writing, and for which the error indicator
-(<computeroutput>ferror(f)</computeroutput>)is not set.</para>
-
-<para>For the meaning of parameters
-<computeroutput>blockSize100k</computeroutput>,
-<computeroutput>verbosity</computeroutput> and
-<computeroutput>workFactor</computeroutput>, see
-<computeroutput>BZ2_bzCompressInit</computeroutput>.</para>
-
-<para>All required memory is allocated at this stage, so if the
-call completes successfully,
-<computeroutput>BZ_MEM_ERROR</computeroutput> cannot be signalled
-by a subsequent call to
-<computeroutput>BZ2_bzWrite</computeroutput>.</para>
-
-<para>Possible assignments to
-<computeroutput>bzerror</computeroutput>:</para>
-
-<programlisting>
-BZ_CONFIG_ERROR
-  if the library has been mis-compiled
-BZ_PARAM_ERROR
-  if f is NULL
-  or blockSize100k < 1 or blockSize100k > 9
-BZ_IO_ERROR
-  if ferror(f) is nonzero
-BZ_MEM_ERROR
-  if insufficient memory is available
-BZ_OK
-  otherwise
-</programlisting>
-
-<para>Possible return values:</para>
-
-<programlisting>
-Pointer to an abstract BZFILE
-  if bzerror is BZ_OK
-NULL
-  otherwise
-</programlisting>
-
-<para>Allowable next actions:</para>
-
-<programlisting>
-BZ2_bzWrite
-  if bzerror is BZ_OK
-  (you could go directly to BZ2_bzWriteClose, but this would be pretty pointless)
-BZ2_bzWriteClose
-  otherwise
-</programlisting>
-
-</sect2>
-
-
-<sect2 id="bzwrite" xreflabel="BZ2_bzWrite">
-<title><computeroutput>BZ2_bzWrite</computeroutput></title>
-
-<programlisting>
-void BZ2_bzWrite ( int *bzerror, BZFILE *b, void *buf, int len );
-</programlisting>
-
-<para>Absorbs <computeroutput>len</computeroutput> bytes from the
-buffer <computeroutput>buf</computeroutput>, eventually to be
-compressed and written to the file.</para>
-
-<para>Possible assignments to
-<computeroutput>bzerror</computeroutput>:</para>
-
-<programlisting>
-BZ_PARAM_ERROR
-  if b is NULL or buf is NULL or len < 0
-BZ_SEQUENCE_ERROR
-  if b was opened with BZ2_bzReadOpen
-BZ_IO_ERROR
-  if there is an error writing the compressed file.
-BZ_OK
-  otherwise
-</programlisting>
-
-</sect2>
-
-
-<sect2 id="bzwriteclose" xreflabel="BZ2_bzWriteClose">
-<title><computeroutput>BZ2_bzWriteClose</computeroutput></title>
-
-<programlisting>
-void BZ2_bzWriteClose( int *bzerror, BZFILE* f,
-                       int abandon,
-                       unsigned int* nbytes_in,
-                       unsigned int* nbytes_out );
-
-void BZ2_bzWriteClose64( int *bzerror, BZFILE* f,
-                         int abandon,
-                         unsigned int* nbytes_in_lo32,
-                         unsigned int* nbytes_in_hi32,
-                         unsigned int* nbytes_out_lo32,
-                         unsigned int* nbytes_out_hi32 );
-</programlisting>
-
-<para>Compresses and flushes to the compressed file all data so
-far supplied by <computeroutput>BZ2_bzWrite</computeroutput>.
-The logical end-of-stream markers are also written, so subsequent
-calls to <computeroutput>BZ2_bzWrite</computeroutput> are
-illegal.  All memory associated with the compressed file
-<computeroutput>b</computeroutput> is released.
-<computeroutput>fflush</computeroutput> is called on the
-compressed file, but it is not
-<computeroutput>fclose</computeroutput>'d.</para>
-
-<para>If <computeroutput>BZ2_bzWriteClose</computeroutput> is
-called to clean up after an error, the only action is to release
-the memory.  The library records the error codes issued by
-previous calls, so this situation will be detected automatically.
-There is no attempt to complete the compression operation, nor to
-<computeroutput>fflush</computeroutput> the compressed file.  You
-can force this behaviour to happen even in the case of no error,
-by passing a nonzero value to
-<computeroutput>abandon</computeroutput>.</para>
-
-<para>If <computeroutput>nbytes_in</computeroutput> is non-null,
-<computeroutput>*nbytes_in</computeroutput> will be set to be the
-total volume of uncompressed data handled.  Similarly,
-<computeroutput>nbytes_out</computeroutput> will be set to the
-total volume of compressed data written.  For compatibility with
-older versions of the library,
-<computeroutput>BZ2_bzWriteClose</computeroutput> only yields the
-lower 32 bits of these counts.  Use
-<computeroutput>BZ2_bzWriteClose64</computeroutput> if you want
-the full 64 bit counts.  These two functions are otherwise
-absolutely identical.</para>
-
-<para>Possible assignments to
-<computeroutput>bzerror</computeroutput>:</para>
-
-<programlisting>
-BZ_SEQUENCE_ERROR
-  if b was opened with BZ2_bzReadOpen
-BZ_IO_ERROR
-  if there is an error writing the compressed file
-BZ_OK
-  otherwise
-</programlisting>
-
-</sect2>
-
-
-<sect2 id="embed" xreflabel="Handling embedded compressed data streams">
-<title>Handling embedded compressed data streams</title>
-
-<para>The high-level library facilitates use of
-<computeroutput>bzip2</computeroutput> data streams which form
-some part of a surrounding, larger data stream.</para>
-
-<itemizedlist mark='bullet'>
-
- <listitem><para>For writing, the library takes an open file handle,
-  writes compressed data to it,
-  <computeroutput>fflush</computeroutput>es it but does not
-  <computeroutput>fclose</computeroutput> it.  The calling
-  application can write its own data before and after the
-  compressed data stream, using that same file handle.</para></listitem>
-
- <listitem><para>Reading is more complex, and the facilities are not as
-  general as they could be since generality is hard to reconcile
-  with efficiency.  <computeroutput>BZ2_bzRead</computeroutput>
-  reads from the compressed file in blocks of size
-  <computeroutput>BZ_MAX_UNUSED</computeroutput> bytes, and in
-  doing so probably will overshoot the logical end of compressed
-  stream.  To recover this data once decompression has ended,
-  call <computeroutput>BZ2_bzReadGetUnused</computeroutput> after
-  the last call of <computeroutput>BZ2_bzRead</computeroutput>
-  (the one returning
-  <computeroutput>BZ_STREAM_END</computeroutput>) but before
-  calling
-  <computeroutput>BZ2_bzReadClose</computeroutput>.</para></listitem>
-
-</itemizedlist>
-
-<para>This mechanism makes it easy to decompress multiple
-<computeroutput>bzip2</computeroutput> streams placed end-to-end.
-As the end of one stream, when
-<computeroutput>BZ2_bzRead</computeroutput> returns
-<computeroutput>BZ_STREAM_END</computeroutput>, call
-<computeroutput>BZ2_bzReadGetUnused</computeroutput> to collect
-the unused data (copy it into your own buffer somewhere).  That
-data forms the start of the next compressed stream.  To start
-uncompressing that next stream, call
-<computeroutput>BZ2_bzReadOpen</computeroutput> again, feeding in
-the unused data via the <computeroutput>unused</computeroutput> /
-<computeroutput>nUnused</computeroutput> parameters.  Keep doing
-this until <computeroutput>BZ_STREAM_END</computeroutput> return
-coincides with the physical end of file
-(<computeroutput>feof(f)</computeroutput>).  In this situation
-<computeroutput>BZ2_bzReadGetUnused</computeroutput> will of
-course return no data.</para>
-
-<para>This should give some feel for how the high-level interface
-can be used.  If you require extra flexibility, you'll have to
-bite the bullet and get to grips with the low-level
-interface.</para>
-
-</sect2>
-
-
-<sect2 id="std-rdwr" xreflabel="Standard file-reading/writing code">
-<title>Standard file-reading/writing code</title>
-
-<para>Here's how you'd write data to a compressed file:</para>
-
-<programlisting>
-FILE*   f;
-BZFILE* b;
-int     nBuf;
-char    buf[ /* whatever size you like */ ];
-int     bzerror;
-int     nWritten;
-
-f = fopen ( "myfile.bz2", "w" );
-if ( !f ) {
- /* handle error */
-}
-b = BZ2_bzWriteOpen( &bzerror, f, 9 );
-if (bzerror != BZ_OK) {
- BZ2_bzWriteClose ( b );
- /* handle error */
-}
-
-while ( /* condition */ ) {
- /* get data to write into buf, and set nBuf appropriately */
- nWritten = BZ2_bzWrite ( &bzerror, b, buf, nBuf );
- if (bzerror == BZ_IO_ERROR) { 
-   BZ2_bzWriteClose ( &bzerror, b );
-   /* handle error */
- }
-}
-
-BZ2_bzWriteClose( &bzerror, b );
-if (bzerror == BZ_IO_ERROR) {
- /* handle error */
-}
-</programlisting>
-
-<para>And to read from a compressed file:</para>
-
-<programlisting>
-FILE*   f;
-BZFILE* b;
-int     nBuf;
-char    buf[ /* whatever size you like */ ];
-int     bzerror;
-int     nWritten;
-
-f = fopen ( "myfile.bz2", "r" );
-if ( !f ) {
-  /* handle error */
-}
-b = BZ2_bzReadOpen ( &bzerror, f, 0, NULL, 0 );
-if ( bzerror != BZ_OK ) {
-  BZ2_bzReadClose ( &bzerror, b );
-  /* handle error */
-}
-
-bzerror = BZ_OK;
-while ( bzerror == BZ_OK && /* arbitrary other conditions */) {
-  nBuf = BZ2_bzRead ( &bzerror, b, buf, /* size of buf */ );
-  if ( bzerror == BZ_OK ) {
-    /* do something with buf[0 .. nBuf-1] */
-  }
-}
-if ( bzerror != BZ_STREAM_END ) {
-   BZ2_bzReadClose ( &bzerror, b );
-   /* handle error */
-} else {
-   BZ2_bzReadClose ( &bzerror, b );
-}
-</programlisting>
-
-</sect2>
-
-</sect1>
-
-
-<sect1 id="util-fns" xreflabel="Utility functions">
-<title>Utility functions</title>
-
-
-<sect2 id="bzbufftobuffcompress" xreflabel="BZ2_bzBuffToBuffCompress">
-<title><computeroutput>BZ2_bzBuffToBuffCompress</computeroutput></title>
-
-<programlisting>
-int BZ2_bzBuffToBuffCompress( char*         dest,
-                              unsigned int* destLen,
-                              char*         source,
-                              unsigned int  sourceLen,
-                              int           blockSize100k,
-                              int           verbosity,
-                              int           workFactor );
-</programlisting>
-
-<para>Attempts to compress the data in <computeroutput>source[0
-.. sourceLen-1]</computeroutput> into the destination buffer,
-<computeroutput>dest[0 .. *destLen-1]</computeroutput>.  If the
-destination buffer is big enough,
-<computeroutput>*destLen</computeroutput> is set to the size of
-the compressed data, and <computeroutput>BZ_OK</computeroutput>
-is returned.  If the compressed data won't fit,
-<computeroutput>*destLen</computeroutput> is unchanged, and
-<computeroutput>BZ_OUTBUFF_FULL</computeroutput> is
-returned.</para>
-
-<para>Compression in this manner is a one-shot event, done with a
-single call to this function.  The resulting compressed data is a
-complete <computeroutput>bzip2</computeroutput> format data
-stream.  There is no mechanism for making additional calls to
-provide extra input data.  If you want that kind of mechanism,
-use the low-level interface.</para>
-
-<para>For the meaning of parameters
-<computeroutput>blockSize100k</computeroutput>,
-<computeroutput>verbosity</computeroutput> and
-<computeroutput>workFactor</computeroutput>, see
-<computeroutput>BZ2_bzCompressInit</computeroutput>.</para>
-
-<para>To guarantee that the compressed data will fit in its
-buffer, allocate an output buffer of size 1% larger than the
-uncompressed data, plus six hundred extra bytes.</para>
-
-<para><computeroutput>BZ2_bzBuffToBuffDecompress</computeroutput>
-will not write data at or beyond
-<computeroutput>dest[*destLen]</computeroutput>, even in case of
-buffer overflow.</para>
-
-<para>Possible return values:</para>
-
-<programlisting>
-BZ_CONFIG_ERROR
-  if the library has been mis-compiled
-BZ_PARAM_ERROR
-  if dest is NULL or destLen is NULL
-  or blockSize100k < 1 or blockSize100k > 9
-  or verbosity < 0 or verbosity > 4
-  or workFactor < 0 or workFactor > 250
-BZ_MEM_ERROR
-  if insufficient memory is available 
-BZ_OUTBUFF_FULL
-  if the size of the compressed data exceeds *destLen
-BZ_OK
-  otherwise
-</programlisting>
-
-</sect2>
-
-
-<sect2 id="bzbufftobuffdecompress" xreflabel="BZ2_bzBuffToBuffDecompress">
-<title><computeroutput>BZ2_bzBuffToBuffDecompress</computeroutput></title>
-
-<programlisting>
-int BZ2_bzBuffToBuffDecompress( char*         dest,
-                                unsigned int* destLen,
-                                char*         source,
-                                unsigned int  sourceLen,
-                                int           small,
-                                int           verbosity );
-</programlisting>
-
-<para>Attempts to decompress the data in <computeroutput>source[0
-.. sourceLen-1]</computeroutput> into the destination buffer,
-<computeroutput>dest[0 .. *destLen-1]</computeroutput>.  If the
-destination buffer is big enough,
-<computeroutput>*destLen</computeroutput> is set to the size of
-the uncompressed data, and <computeroutput>BZ_OK</computeroutput>
-is returned.  If the compressed data won't fit,
-<computeroutput>*destLen</computeroutput> is unchanged, and
-<computeroutput>BZ_OUTBUFF_FULL</computeroutput> is
-returned.</para>
-
-<para><computeroutput>source</computeroutput> is assumed to hold
-a complete <computeroutput>bzip2</computeroutput> format data
-stream.
-<computeroutput>BZ2_bzBuffToBuffDecompress</computeroutput> tries
-to decompress the entirety of the stream into the output
-buffer.</para>
-
-<para>For the meaning of parameters
-<computeroutput>small</computeroutput> and
-<computeroutput>verbosity</computeroutput>, see
-<computeroutput>BZ2_bzDecompressInit</computeroutput>.</para>
-
-<para>Because the compression ratio of the compressed data cannot
-be known in advance, there is no easy way to guarantee that the
-output buffer will be big enough.  You may of course make
-arrangements in your code to record the size of the uncompressed
-data, but such a mechanism is beyond the scope of this
-library.</para>
-
-<para><computeroutput>BZ2_bzBuffToBuffDecompress</computeroutput>
-will not write data at or beyond
-<computeroutput>dest[*destLen]</computeroutput>, even in case of
-buffer overflow.</para>
-
-<para>Possible return values:</para>
-
-<programlisting>
-BZ_CONFIG_ERROR
-  if the library has been mis-compiled
-BZ_PARAM_ERROR
-  if dest is NULL or destLen is NULL
-  or small != 0 && small != 1
-  or verbosity < 0 or verbosity > 4
-BZ_MEM_ERROR
-  if insufficient memory is available 
-BZ_OUTBUFF_FULL
-  if the size of the compressed data exceeds *destLen
-BZ_DATA_ERROR
-  if a data integrity error was detected in the compressed data
-BZ_DATA_ERROR_MAGIC
-  if the compressed data doesn't begin with the right magic bytes
-BZ_UNEXPECTED_EOF
-  if the compressed data ends unexpectedly
-BZ_OK
-  otherwise
-</programlisting>
-
-</sect2>
-
-</sect1>
-
-
-<sect1 id="zlib-compat" xreflabel="zlib compatibility functions">
-<title><computeroutput>zlib</computeroutput> compatibility functions</title>
-
-<para>Yoshioka Tsuneo has contributed some functions to give
-better <computeroutput>zlib</computeroutput> compatibility.
-These functions are <computeroutput>BZ2_bzopen</computeroutput>,
-<computeroutput>BZ2_bzread</computeroutput>,
-<computeroutput>BZ2_bzwrite</computeroutput>,
-<computeroutput>BZ2_bzflush</computeroutput>,
-<computeroutput>BZ2_bzclose</computeroutput>,
-<computeroutput>BZ2_bzerror</computeroutput> and
-<computeroutput>BZ2_bzlibVersion</computeroutput>.  These
-functions are not (yet) officially part of the library.  If they
-break, you get to keep all the pieces.  Nevertheless, I think
-they work ok.</para>
-
-<programlisting>
-typedef void BZFILE;
-
-const char * BZ2_bzlibVersion ( void );
-</programlisting>
-
-<para>Returns a string indicating the library version.</para>
-
-<programlisting>
-BZFILE * BZ2_bzopen  ( const char *path, const char *mode );
-BZFILE * BZ2_bzdopen ( int        fd,    const char *mode );
-</programlisting>
-
-<para>Opens a <computeroutput>.bz2</computeroutput> file for
-reading or writing, using either its name or a pre-existing file
-descriptor.  Analogous to <computeroutput>fopen</computeroutput>
-and <computeroutput>fdopen</computeroutput>.</para>
-
-<programlisting>
-int BZ2_bzread  ( BZFILE* b, void* buf, int len );
-int BZ2_bzwrite ( BZFILE* b, void* buf, int len );
-</programlisting>
-
-<para>Reads/writes data from/to a previously opened
-<computeroutput>BZFILE</computeroutput>.  Analogous to
-<computeroutput>fread</computeroutput> and
-<computeroutput>fwrite</computeroutput>.</para>
-
-<programlisting>
-int  BZ2_bzflush ( BZFILE* b );
-void BZ2_bzclose ( BZFILE* b );
-</programlisting>
-
-<para>Flushes/closes a <computeroutput>BZFILE</computeroutput>.
-<computeroutput>BZ2_bzflush</computeroutput> doesn't actually do
-anything.  Analogous to <computeroutput>fflush</computeroutput>
-and <computeroutput>fclose</computeroutput>.</para>
-
-<programlisting>
-const char * BZ2_bzerror ( BZFILE *b, int *errnum )
-</programlisting>
-
-<para>Returns a string describing the more recent error status of
-<computeroutput>b</computeroutput>, and also sets
-<computeroutput>*errnum</computeroutput> to its numerical
-value.</para>
-
-</sect1>
-
-
-<sect1 id="stdio-free" 
-       xreflabel="Using the library in a stdio-free environment">
-<title>Using the library in a <computeroutput>stdio</computeroutput>-free environment</title>
-
-
-<sect2 id="stdio-bye" xreflabel="Getting rid of stdio">
-<title>Getting rid of <computeroutput>stdio</computeroutput></title>
-
-<para>In a deeply embedded application, you might want to use
-just the memory-to-memory functions.  You can do this
-conveniently by compiling the library with preprocessor symbol
-<computeroutput>BZ_NO_STDIO</computeroutput> defined.  Doing this
-gives you a library containing only the following eight
-functions:</para>
-
-<para><computeroutput>BZ2_bzCompressInit</computeroutput>,
-<computeroutput>BZ2_bzCompress</computeroutput>,
-<computeroutput>BZ2_bzCompressEnd</computeroutput>
-<computeroutput>BZ2_bzDecompressInit</computeroutput>,
-<computeroutput>BZ2_bzDecompress</computeroutput>,
-<computeroutput>BZ2_bzDecompressEnd</computeroutput>
-<computeroutput>BZ2_bzBuffToBuffCompress</computeroutput>,
-<computeroutput>BZ2_bzBuffToBuffDecompress</computeroutput></para>
-
-<para>When compiled like this, all functions will ignore
-<computeroutput>verbosity</computeroutput> settings.</para>
-
-</sect2>
-
-
-<sect2 id="critical-error" xreflabel="Critical error handling">
-<title>Critical error handling</title>
-
-<para><computeroutput>libbzip2</computeroutput> contains a number
-of internal assertion checks which should, needless to say, never
-be activated.  Nevertheless, if an assertion should fail,
-behaviour depends on whether or not the library was compiled with
-<computeroutput>BZ_NO_STDIO</computeroutput> set.</para>
-
-<para>For a normal compile, an assertion failure yields the
-message:</para>
-
-<blockquote>
-<para>bzip2/libbzip2: internal error number N.</para>
-<para>This is a bug in bzip2/libbzip2, &bz-version; of &bz-date;.
-Please report it to me at: &bz-email;.  If this happened
-when you were using some program which uses libbzip2 as a
-component, you should also report this bug to the author(s)
-of that program.  Please make an effort to report this bug;
-timely and accurate bug reports eventually lead to higher
-quality software.  Thanks.  Julian Seward, &bz-date;.
-</para></blockquote>
-
-<para>where <computeroutput>N</computeroutput> is some error code
-number.  If <computeroutput>N == 1007</computeroutput>, it also
-prints some extra text advising the reader that unreliable memory
-is often associated with internal error 1007. (This is a
-frequently-observed-phenomenon with versions 1.0.0/1.0.1).</para>
-
-<para><computeroutput>exit(3)</computeroutput> is then
-called.</para>
-
-<para>For a <computeroutput>stdio</computeroutput>-free library,
-assertion failures result in a call to a function declared
-as:</para>
-
-<programlisting>
-extern void bz_internal_error ( int errcode );
-</programlisting>
-
-<para>The relevant code is passed as a parameter.  You should
-supply such a function.</para>
-
-<para>In either case, once an assertion failure has occurred, any
-<computeroutput>bz_stream</computeroutput> records involved can
-be regarded as invalid.  You should not attempt to resume normal
-operation with them.</para>
-
-<para>You may, of course, change critical error handling to suit
-your needs.  As I said above, critical errors indicate bugs in
-the library and should not occur.  All "normal" error situations
-are indicated via error return codes from functions, and can be
-recovered from.</para>
-
-</sect2>
-
-</sect1>
-
-
-<sect1 id="win-dll" xreflabel="Making a Windows DLL">
-<title>Making a Windows DLL</title>
-
-<para>Everything related to Windows has been contributed by
-Yoshioka Tsuneo
-(<computeroutput>tsuneo@rr.iij4u.or.jp</computeroutput>), so
-you should send your queries to him (but perhaps Cc: me,
-<computeroutput>&bz-email;</computeroutput>).</para>
-
-<para>My vague understanding of what to do is: using Visual C++
-5.0, open the project file
-<computeroutput>libbz2.dsp</computeroutput>, and build.  That's
-all.</para>
-
-<para>If you can't open the project file for some reason, make a
-new one, naming these files:
-<computeroutput>blocksort.c</computeroutput>,
-<computeroutput>bzlib.c</computeroutput>,
-<computeroutput>compress.c</computeroutput>,
-<computeroutput>crctable.c</computeroutput>,
-<computeroutput>decompress.c</computeroutput>,
-<computeroutput>huffman.c</computeroutput>,
-<computeroutput>randtable.c</computeroutput> and
-<computeroutput>libbz2.def</computeroutput>.  You will also need
-to name the header files <computeroutput>bzlib.h</computeroutput>
-and <computeroutput>bzlib_private.h</computeroutput>.</para>
-
-<para>If you don't use VC++, you may need to define the
-proprocessor symbol
-<computeroutput>_WIN32</computeroutput>.</para>
-
-<para>Finally, <computeroutput>dlltest.c</computeroutput> is a
-sample program using the DLL.  It has a project file,
-<computeroutput>dlltest.dsp</computeroutput>.</para>
-
-<para>If you just want a makefile for Visual C, have a look at
-<computeroutput>makefile.msc</computeroutput>.</para>
-
-<para>Be aware that if you compile
-<computeroutput>bzip2</computeroutput> itself on Win32, you must
-set <computeroutput>BZ_UNIX</computeroutput> to 0 and
-<computeroutput>BZ_LCCWIN32</computeroutput> to 1, in the file
-<computeroutput>bzip2.c</computeroutput>, before compiling.
-Otherwise the resulting binary won't work correctly.</para>
-
-<para>I haven't tried any of this stuff myself, but it all looks
-plausible.</para>
-
-</sect1>
-
-</chapter>
-
-
-
-<chapter id="misc" xreflabel="Miscellanea">
-<title>Miscellanea</title>
-
-<para>These are just some random thoughts of mine.  Your mileage
-may vary.</para>
-
-
-<sect1 id="limits" xreflabel="Limitations of the compressed file format">
-<title>Limitations of the compressed file format</title>
-
-<para><computeroutput>bzip2-1.0.X</computeroutput>,
-<computeroutput>0.9.5</computeroutput> and
-<computeroutput>0.9.0</computeroutput> use exactly the same file
-format as the original version,
-<computeroutput>bzip2-0.1</computeroutput>.  This decision was
-made in the interests of stability.  Creating yet another
-incompatible compressed file format would create further
-confusion and disruption for users.</para>
-
-<para>Nevertheless, this is not a painless decision.  Development
-work since the release of
-<computeroutput>bzip2-0.1</computeroutput> in August 1997 has
-shown complexities in the file format which slow down
-decompression and, in retrospect, are unnecessary.  These
-are:</para>
-
-<itemizedlist mark='bullet'>
-
- <listitem><para>The run-length encoder, which is the first of the
-   compression transformations, is entirely irrelevant.  The
-   original purpose was to protect the sorting algorithm from the
-   very worst case input: a string of repeated symbols.  But
-   algorithm steps Q6a and Q6b in the original Burrows-Wheeler
-   technical report (SRC-124) show how repeats can be handled
-   without difficulty in block sorting.</para></listitem>
-
- <listitem><para>The randomisation mechanism doesn't really need to be
-   there.  Udi Manber and Gene Myers published a suffix array
-   construction algorithm a few years back, which can be employed
-   to sort any block, no matter how repetitive, in O(N log N)
-   time.  Subsequent work by Kunihiko Sadakane has produced a
-   derivative O(N (log N)^2) algorithm which usually outperforms
-   the Manber-Myers algorithm.</para>
-
-   <para>I could have changed to Sadakane's algorithm, but I find
-   it to be slower than <computeroutput>bzip2</computeroutput>'s
-   existing algorithm for most inputs, and the randomisation
-   mechanism protects adequately against bad cases.  I didn't
-   think it was a good tradeoff to make.  Partly this is due to
-   the fact that I was not flooded with email complaints about
-   <computeroutput>bzip2-0.1</computeroutput>'s performance on
-   repetitive data, so perhaps it isn't a problem for real
-   inputs.</para>
-
-   <para>Probably the best long-term solution, and the one I have
-   incorporated into 0.9.5 and above, is to use the existing
-   sorting algorithm initially, and fall back to a O(N (log N)^2)
-   algorithm if the standard algorithm gets into
-   difficulties.</para></listitem>
-
-  <listitem><para>The compressed file format was never designed to be
-   handled by a library, and I have had to jump though some hoops
-   to produce an efficient implementation of decompression.  It's
-   a bit hairy.  Try passing
-   <computeroutput>decompress.c</computeroutput> through the C
-   preprocessor and you'll see what I mean.  Much of this
-   complexity could have been avoided if the compressed size of
-   each block of data was recorded in the data stream.</para></listitem>
-
- <listitem><para>An Adler-32 checksum, rather than a CRC32 checksum,
-   would be faster to compute.</para></listitem>
-
-</itemizedlist>
-
-<para>It would be fair to say that the
-<computeroutput>bzip2</computeroutput> format was frozen before I
-properly and fully understood the performance consequences of
-doing so.</para>
-
-<para>Improvements which I was able to incorporate into 0.9.0,
-despite using the same file format, are:</para>
-
-<itemizedlist mark='bullet'>
-
- <listitem><para>Single array implementation of the inverse BWT.  This
-  significantly speeds up decompression, presumably because it
-  reduces the number of cache misses.</para></listitem>
-
- <listitem><para>Faster inverse MTF transform for large MTF values.
-  The new implementation is based on the notion of sliding blocks
-  of values.</para></listitem>
-
- <listitem><para><computeroutput>bzip2-0.9.0</computeroutput> now reads
-  and writes files with <computeroutput>fread</computeroutput>
-  and <computeroutput>fwrite</computeroutput>; version 0.1 used
-  <computeroutput>putc</computeroutput> and
-  <computeroutput>getc</computeroutput>.  Duh!  Well, you live
-  and learn.</para></listitem>
-
-</itemizedlist>
-
-<para>Further ahead, it would be nice to be able to do random
-access into files.  This will require some careful design of
-compressed file formats.</para>
-
-</sect1>
-
-
-<sect1 id="port-issues" xreflabel="Portability issues">
-<title>Portability issues</title>
-
-<para>After some consideration, I have decided not to use GNU
-<computeroutput>autoconf</computeroutput> to configure 0.9.5 or
-1.0.</para>
-
-<para><computeroutput>autoconf</computeroutput>, admirable and
-wonderful though it is, mainly assists with portability problems
-between Unix-like platforms.  But
-<computeroutput>bzip2</computeroutput> doesn't have much in the
-way of portability problems on Unix; most of the difficulties
-appear when porting to the Mac, or to Microsoft's operating
-systems.  <computeroutput>autoconf</computeroutput> doesn't help
-in those cases, and brings in a whole load of new
-complexity.</para>
-
-<para>Most people should be able to compile the library and
-program under Unix straight out-of-the-box, so to speak,
-especially if you have a version of GNU C available.</para>
-
-<para>There are a couple of
-<computeroutput>__inline__</computeroutput> directives in the
-code.  GNU C (<computeroutput>gcc</computeroutput>) should be
-able to handle them.  If you're not using GNU C, your C compiler
-shouldn't see them at all.  If your compiler does, for some
-reason, see them and doesn't like them, just
-<computeroutput>#define</computeroutput>
-<computeroutput>__inline__</computeroutput> to be
-<computeroutput>/* */</computeroutput>.  One easy way to do this
-is to compile with the flag
-<computeroutput>-D__inline__=</computeroutput>, which should be
-understood by most Unix compilers.</para>
-
-<para>If you still have difficulties, try compiling with the
-macro <computeroutput>BZ_STRICT_ANSI</computeroutput> defined.
-This should enable you to build the library in a strictly ANSI
-compliant environment.  Building the program itself like this is
-dangerous and not supported, since you remove
-<computeroutput>bzip2</computeroutput>'s checks against
-compressing directories, symbolic links, devices, and other
-not-really-a-file entities.  This could cause filesystem
-corruption!</para>
-
-<para>One other thing: if you create a
-<computeroutput>bzip2</computeroutput> binary for public distribution,
-please consider linking it statically (<computeroutput>gcc
--static</computeroutput>).  This avoids all sorts of library-version
-issues that others may encounter later on.</para>
-
-<para>If you build <computeroutput>bzip2</computeroutput> on
-Win32, you must set <computeroutput>BZ_UNIX</computeroutput> to 0
-and <computeroutput>BZ_LCCWIN32</computeroutput> to 1, in the
-file <computeroutput>bzip2.c</computeroutput>, before compiling.
-Otherwise the resulting binary won't work correctly.</para>
-
-</sect1>
-
-
-<sect1 id="bugs" xreflabel="Reporting bugs">
-<title>Reporting bugs</title>
-
-<para>I tried pretty hard to make sure
-<computeroutput>bzip2</computeroutput> is bug free, both by
-design and by testing.  Hopefully you'll never need to read this
-section for real.</para>
-
-<para>Nevertheless, if <computeroutput>bzip2</computeroutput> dies
-with a segmentation fault, a bus error or an internal assertion
-failure, it will ask you to email me a bug report.  Experience from
-years of feedback of bzip2 users indicates that almost all these
-problems can be traced to either compiler bugs or hardware
-problems.</para>
-
-<itemizedlist mark='bullet'>
-
- <listitem><para>Recompile the program with no optimisation, and
-  see if it works.  And/or try a different compiler.  I heard all
-  sorts of stories about various flavours of GNU C (and other
-  compilers) generating bad code for
-  <computeroutput>bzip2</computeroutput>, and I've run across two
-  such examples myself.</para>
-
-  <para>2.7.X versions of GNU C are known to generate bad code
-  from time to time, at high optimisation levels.  If you get
-  problems, try using the flags
-  <computeroutput>-O2</computeroutput>
-  <computeroutput>-fomit-frame-pointer</computeroutput>
-  <computeroutput>-fno-strength-reduce</computeroutput>.  You
-  should specifically <emphasis>not</emphasis> use
-  <computeroutput>-funroll-loops</computeroutput>.</para>
-
-  <para>You may notice that the Makefile runs six tests as part
-  of the build process.  If the program passes all of these, it's
-  a pretty good (but not 100%) indication that the compiler has
-  done its job correctly.</para></listitem>
-
- <listitem><para>If <computeroutput>bzip2</computeroutput>
-  crashes randomly, and the crashes are not repeatable, you may
-  have a flaky memory subsystem.
-  <computeroutput>bzip2</computeroutput> really hammers your
-  memory hierarchy, and if it's a bit marginal, you may get these
-  problems.  Ditto if your disk or I/O subsystem is slowly
-  failing.  Yup, this really does happen.</para>
-
-  <para>Try using a different machine of the same type, and see
-  if you can repeat the problem.</para></listitem>
-
-  <listitem><para>This isn't really a bug, but ... If
-  <computeroutput>bzip2</computeroutput> tells you your file is
-  corrupted on decompression, and you obtained the file via FTP,
-  there is a possibility that you forgot to tell FTP to do a
-  binary mode transfer.  That absolutely will cause the file to
-  be non-decompressible.  You'll have to transfer it
-  again.</para></listitem>
-
-</itemizedlist>
-
-<para>If you've incorporated
-<computeroutput>libbzip2</computeroutput> into your own program
-and are getting problems, please, please, please, check that the
-parameters you are passing in calls to the library, are correct,
-and in accordance with what the documentation says is allowable.
-I have tried to make the library robust against such problems,
-but I'm sure I haven't succeeded.</para>
-
-<para>Finally, if the above comments don't help, you'll have to
-send me a bug report.  Now, it's just amazing how many people
-will send me a bug report saying something like:</para>
-
-<programlisting>
-bzip2 crashed with segmentation fault on my machine
-</programlisting>
-
-<para>and absolutely nothing else.  Needless to say, a such a
-report is <emphasis>totally, utterly, completely and
-comprehensively 100% useless; a waste of your time, my time, and
-net bandwidth</emphasis>.  With no details at all, there's no way
-I can possibly begin to figure out what the problem is.</para>
-
-<para>The rules of the game are: facts, facts, facts.  Don't omit
-them because "oh, they won't be relevant".  At the bare
-minimum:</para>
-
-<programlisting>
-Machine type.  Operating system version.  
-Exact version of bzip2 (do bzip2 -V).  
-Exact version of the compiler used.  
-Flags passed to the compiler.
-</programlisting>
-
-<para>However, the most important single thing that will help me
-is the file that you were trying to compress or decompress at the
-time the problem happened.  Without that, my ability to do
-anything more than speculate about the cause, is limited.</para>
-
-</sect1>
-
-
-<sect1 id="package" xreflabel="Did you get the right package?">
-<title>Did you get the right package?</title>
-
-<para><computeroutput>bzip2</computeroutput> is a resource hog.
-It soaks up large amounts of CPU cycles and memory.  Also, it
-gives very large latencies.  In the worst case, you can feed many
-megabytes of uncompressed data into the library before getting
-any compressed output, so this probably rules out applications
-requiring interactive behaviour.</para>
-
-<para>These aren't faults of my implementation, I hope, but more
-an intrinsic property of the Burrows-Wheeler transform
-(unfortunately).  Maybe this isn't what you want.</para>
-
-<para>If you want a compressor and/or library which is faster,
-uses less memory but gets pretty good compression, and has
-minimal latency, consider Jean-loup Gailly's and Mark Adler's
-work, <computeroutput>zlib-1.2.1</computeroutput> and
-<computeroutput>gzip-1.2.4</computeroutput>.  Look for them at 
-<ulink url="http://www.zlib.org">http://www.zlib.org</ulink> and 
-<ulink url="http://www.gzip.org">http://www.gzip.org</ulink>
-respectively.</para>
-
-<para>For something faster and lighter still, you might try Markus F
-X J Oberhumer's <computeroutput>LZO</computeroutput> real-time
-compression/decompression library, at 
-<ulink url="http://www.oberhumer.com/opensource">http://www.oberhumer.com/opensource</ulink>.</para>
-
-</sect1>
-
-
-
-<sect1 id="reading" xreflabel="Further Reading">
-<title>Further Reading</title>
-
-<para><computeroutput>bzip2</computeroutput> is not research
-work, in the sense that it doesn't present any new ideas.
-Rather, it's an engineering exercise based on existing
-ideas.</para>
-
-<para>Four documents describe essentially all the ideas behind
-<computeroutput>bzip2</computeroutput>:</para>
-
-<literallayout>Michael Burrows and D. J. Wheeler:
-  "A block-sorting lossless data compression algorithm"
-   10th May 1994. 
-   Digital SRC Research Report 124.
-   ftp://ftp.digital.com/pub/DEC/SRC/research-reports/SRC-124.ps.gz
-   If you have trouble finding it, try searching at the
-   New Zealand Digital Library, http://www.nzdl.org.
-
-Daniel S. Hirschberg and Debra A. LeLewer
-  "Efficient Decoding of Prefix Codes"
-   Communications of the ACM, April 1990, Vol 33, Number 4.
-   You might be able to get an electronic copy of this
-   from the ACM Digital Library.
-
-David J. Wheeler
-   Program bred3.c and accompanying document bred3.ps.
-   This contains the idea behind the multi-table Huffman coding scheme.
-   ftp://ftp.cl.cam.ac.uk/users/djw3/
-
-Jon L. Bentley and Robert Sedgewick
-  "Fast Algorithms for Sorting and Searching Strings"
-   Available from Sedgewick's web page,
-   www.cs.princeton.edu/~rs
-</literallayout>
-
-<para>The following paper gives valuable additional insights into
-the algorithm, but is not immediately the basis of any code used
-in bzip2.</para>
-
-<literallayout>Peter Fenwick:
-   Block Sorting Text Compression
-   Proceedings of the 19th Australasian Computer Science Conference,
-     Melbourne, Australia.  Jan 31 - Feb 2, 1996.
-   ftp://ftp.cs.auckland.ac.nz/pub/peter-f/ACSC96paper.ps</literallayout>
-
-<para>Kunihiko Sadakane's sorting algorithm, mentioned above, is
-available from:</para>
-
-<literallayout>http://naomi.is.s.u-tokyo.ac.jp/~sada/papers/Sada98b.ps.gz
-</literallayout>
-
-<para>The Manber-Myers suffix array construction algorithm is
-described in a paper available from:</para>
-
-<literallayout>http://www.cs.arizona.edu/people/gene/PAPERS/suffix.ps
-</literallayout>
-
-<para>Finally, the following papers document some
-investigations I made into the performance of sorting
-and decompression algorithms:</para>
-
-<literallayout>Julian Seward
-   On the Performance of BWT Sorting Algorithms
-   Proceedings of the IEEE Data Compression Conference 2000
-     Snowbird, Utah.  28-30 March 2000.
-
-Julian Seward
-   Space-time Tradeoffs in the Inverse B-W Transform
-   Proceedings of the IEEE Data Compression Conference 2001
-     Snowbird, Utah.  27-29 March 2001.
-</literallayout>
-
-</sect1>
-
-</chapter>
-
-</book>
diff --git a/Utilities/cmbzip2/mk251.c b/Utilities/cmbzip2/mk251.c
index 39e94c0..6c5bbf9 100644
--- a/Utilities/cmbzip2/mk251.c
+++ b/Utilities/cmbzip2/mk251.c
@@ -9,8 +9,8 @@
    This file is part of bzip2/libbzip2, a program and library for
    lossless, block-sorting data compression.
 
-   bzip2/libbzip2 version 1.0.5 of 10 December 2007
-   Copyright (C) 1996-2007 Julian Seward <jseward@bzip.org>
+   bzip2/libbzip2 version 1.0.8 of 13 July 2019
+   Copyright (C) 1996-2019 Julian Seward <jseward@acm.org>
 
    Please read the WARNING, DISCLAIMER and PATENTS sections in the 
    README file.
diff --git a/Utilities/cmbzip2/randtable.c b/Utilities/cmbzip2/randtable.c
index 068b763..bdc6d4a 100644
--- a/Utilities/cmbzip2/randtable.c
+++ b/Utilities/cmbzip2/randtable.c
@@ -8,8 +8,8 @@
    This file is part of bzip2/libbzip2, a program and library for
    lossless, block-sorting data compression.
 
-   bzip2/libbzip2 version 1.0.5 of 10 December 2007
-   Copyright (C) 1996-2007 Julian Seward <jseward@bzip.org>
+   bzip2/libbzip2 version 1.0.8 of 13 July 2019
+   Copyright (C) 1996-2019 Julian Seward <jseward@acm.org>
 
    Please read the WARNING, DISCLAIMER and PATENTS sections in the 
    README file.
diff --git a/Utilities/cmbzip2/sample1.rb2 b/Utilities/cmbzip2/sample1.rb2
deleted file mode 100644
index 4edda36..0000000
--- a/Utilities/cmbzip2/sample1.rb2
+++ /dev/null
Binary files differ
diff --git a/Utilities/cmbzip2/sample1.ref b/Utilities/cmbzip2/sample1.ref
deleted file mode 100644
index dc869ee..0000000
--- a/Utilities/cmbzip2/sample1.ref
+++ /dev/null
Binary files differ
diff --git a/Utilities/cmbzip2/sample1.tst b/Utilities/cmbzip2/sample1.tst
deleted file mode 100644
index dc869ee..0000000
--- a/Utilities/cmbzip2/sample1.tst
+++ /dev/null
Binary files differ
diff --git a/Utilities/cmbzip2/sample2.rb2 b/Utilities/cmbzip2/sample2.rb2
deleted file mode 100644
index 8e54297..0000000
--- a/Utilities/cmbzip2/sample2.rb2
+++ /dev/null
Binary files differ
diff --git a/Utilities/cmbzip2/sample2.ref b/Utilities/cmbzip2/sample2.ref
deleted file mode 100644
index 40e5b58..0000000
--- a/Utilities/cmbzip2/sample2.ref
+++ /dev/null
Binary files differ
diff --git a/Utilities/cmbzip2/sample2.tst b/Utilities/cmbzip2/sample2.tst
deleted file mode 100644
index 40e5b58..0000000
--- a/Utilities/cmbzip2/sample2.tst
+++ /dev/null
Binary files differ
diff --git a/Utilities/cmbzip2/sample3.rb2 b/Utilities/cmbzip2/sample3.rb2
deleted file mode 100644
index 1c9b08c..0000000
--- a/Utilities/cmbzip2/sample3.rb2
+++ /dev/null
Binary files differ
diff --git a/Utilities/cmbzip2/sample3.ref b/Utilities/cmbzip2/sample3.ref
deleted file mode 100644
index 775a2f6..0000000
--- a/Utilities/cmbzip2/sample3.ref
+++ /dev/null
@@ -1,30007 +0,0 @@
-This file is exceedingly boring.  If you find yourself
-reading it, please (1) take it from me that you can safely
-guess what the rest of the file says, and (2) seek professional
-help.
-
-ps.  there are no further sarcastic remarks in this file.
-
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
diff --git a/Utilities/cmbzip2/sample3.tst b/Utilities/cmbzip2/sample3.tst
deleted file mode 100644
index 775a2f6..0000000
--- a/Utilities/cmbzip2/sample3.tst
+++ /dev/null
@@ -1,30007 +0,0 @@
-This file is exceedingly boring.  If you find yourself
-reading it, please (1) take it from me that you can safely
-guess what the rest of the file says, and (2) seek professional
-help.
-
-ps.  there are no further sarcastic remarks in this file.
-
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
-ugh
diff --git a/Utilities/cmbzip2/spewG.c b/Utilities/cmbzip2/spewG.c
index 7bd1284..65d24c8 100644
--- a/Utilities/cmbzip2/spewG.c
+++ b/Utilities/cmbzip2/spewG.c
@@ -13,15 +13,15 @@
    This file is part of bzip2/libbzip2, a program and library for
    lossless, block-sorting data compression.
 
-   bzip2/libbzip2 version 1.0.5 of 10 December 2007
-   Copyright (C) 1996-2007 Julian Seward <jseward@bzip.org>
+   bzip2/libbzip2 version 1.0.8 of 13 July 2019
+   Copyright (C) 1996-2019 Julian Seward <jseward@acm.org>
 
    Please read the WARNING, DISCLAIMER and PATENTS sections in the 
    README file.
 
    This program is released under the terms of the license contained
    in the file LICENSE.
-     ------------------------------------------------------------------ */
+	 ------------------------------------------------------------------ */
 
 
 #define _FILE_OFFSET_BITS 64
diff --git a/Utilities/cmbzip2/unzcrash.c b/Utilities/cmbzip2/unzcrash.c
index a1b7546..c68f93c 100644
--- a/Utilities/cmbzip2/unzcrash.c
+++ b/Utilities/cmbzip2/unzcrash.c
@@ -17,8 +17,8 @@
    This file is part of bzip2/libbzip2, a program and library for
    lossless, block-sorting data compression.
 
-   bzip2/libbzip2 version 1.0.5 of 10 December 2007
-   Copyright (C) 1996-2007 Julian Seward <jseward@bzip.org>
+   bzip2/libbzip2 version 1.0.8 of 13 July 2019
+   Copyright (C) 1996-2019 Julian Seward <jseward@acm.org>
 
    Please read the WARNING, DISCLAIMER and PATENTS sections in the 
    README file.
diff --git a/Utilities/cmbzip2/words0 b/Utilities/cmbzip2/words0
deleted file mode 100644
index fbf442a..0000000
--- a/Utilities/cmbzip2/words0
+++ /dev/null
@@ -1,9 +0,0 @@
-
-If compilation produces errors, or a large number of warnings,
-please read README.COMPILATION.PROBLEMS -- you might be able to
-adjust the flags in this Makefile to improve matters.
-
-Also in README.COMPILATION.PROBLEMS are some hints that may help
-if your build produces an executable which is unable to correctly
-handle so-called 'large files' -- files of size 2GB or more.
-
diff --git a/Utilities/cmbzip2/words1 b/Utilities/cmbzip2/words1
deleted file mode 100644
index 2e83de9..0000000
--- a/Utilities/cmbzip2/words1
+++ /dev/null
@@ -1,4 +0,0 @@
-
-Doing 6 tests (3 compress, 3 uncompress) ...
-If there's a problem, things might stop at this point.
- 
diff --git a/Utilities/cmbzip2/words2 b/Utilities/cmbzip2/words2
deleted file mode 100644
index caddcf4..0000000
--- a/Utilities/cmbzip2/words2
+++ /dev/null
@@ -1,5 +0,0 @@
-
-Checking test results.  If any of the four "cmp"s which follow
-report any differences, something is wrong.  If you can't easily
-figure out what, please let me know (jseward@bzip.org).
-
diff --git a/Utilities/cmbzip2/words3 b/Utilities/cmbzip2/words3
deleted file mode 100644
index 6972669..0000000
--- a/Utilities/cmbzip2/words3
+++ /dev/null
@@ -1,30 +0,0 @@
-
-If you got this far and the 'cmp's didn't complain, it looks
-like you're in business.  
-
-To install in /usr/local/bin, /usr/local/lib, /usr/local/man and 
-/usr/local/include, type
-
-   make install
-
-To install somewhere else, eg, /xxx/yyy/{bin,lib,man,include}, type 
-
-   make install PREFIX=/xxx/yyy
-
-If you are (justifiably) paranoid and want to see what 'make install'
-is going to do, you can first do
-
-   make -n install                      or
-   make -n install PREFIX=/xxx/yyy      respectively.
-
-The -n instructs make to show the commands it would execute, but
-not actually execute them.
-
-Instructions for use are in the preformatted manual page, in the file
-bzip2.txt.  For more detailed documentation, read the full manual.  
-It is available in Postscript form (manual.ps), PDF form (manual.pdf),
-and HTML form (manual.html).
-
-You can also do "bzip2 --help" to see some helpful information. 
-"bzip2 -L" displays the software license.
-
diff --git a/Utilities/cmbzip2/xmlproc.sh b/Utilities/cmbzip2/xmlproc.sh
deleted file mode 100755
index 5384177..0000000
--- a/Utilities/cmbzip2/xmlproc.sh
+++ /dev/null
@@ -1,114 +0,0 @@
-#!/bin/bash
-# see the README file for usage etc.
-#
-# ------------------------------------------------------------------
-#  This file is part of bzip2/libbzip2, a program and library for
-#  lossless, block-sorting data compression.
-#
-#  bzip2/libbzip2 version 1.0.5 of 10 December 2007
-#  Copyright (C) 1996-2007 Julian Seward <jseward@bzip.org>
-#
-#  Please read the WARNING, DISCLAIMER and PATENTS sections in the 
-#  README file.
-#
-#  This program is released under the terms of the license contained
-#  in the file LICENSE.
-# ----------------------------------------------------------------
-
-
-usage() {
-  echo '';
-  echo 'Usage: xmlproc.sh -[option] <filename.xml>';
-  echo 'Specify a target from:';
-  echo '-v      verify xml file conforms to dtd';
-  echo '-html   output in html format (single file)';
-  echo '-ps     output in postscript format';
-  echo '-pdf    output in pdf format';
-  exit;
-}
-
-if test $# -ne 2; then
-  usage
-fi
-# assign the variable for the output type
-action=$1; shift
-# assign the output filename
-xmlfile=$1; shift
-# and check user input it correct
-if !(test -f $xmlfile); then
-  echo "No such file: $xmlfile";
-  exit;
-fi
-# some other stuff we will use
-OUT=output
-xsl_fo=bz-fo.xsl
-xsl_html=bz-html.xsl
-
-basename=$xmlfile
-basename=${basename//'.xml'/''}
-
-fofile="${basename}.fo"
-htmlfile="${basename}.html"
-pdffile="${basename}.pdf"
-psfile="${basename}.ps"
-xmlfmtfile="${basename}.fmt"
-
-# first process the xmlfile with CDATA tags
-./format.pl $xmlfile $xmlfmtfile
-# so the shell knows where the catalogs live
-export XML_CATALOG_FILES=/etc/xml/catalog
-
-# post-processing tidy up
-cleanup() {
-  echo "Cleaning up: $@" 
-  while [ $# != 0 ]
-  do
-    arg=$1; shift;
-    echo "  deleting $arg";
-    rm $arg
-  done
-}
-
-case $action in
-  -v)
-   flags='--noout --xinclude --noblanks --postvalid'
-   dtd='--dtdvalid http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd'
-   xmllint $flags $dtd $xmlfmtfile 2> $OUT 
-   egrep 'error' $OUT 
-   rm $OUT
-  ;;
-
-  -html)
-   echo "Creating $htmlfile ..."
-   xsltproc --nonet --xinclude  -o $htmlfile $xsl_html $xmlfmtfile
-   cleanup $xmlfmtfile
-  ;;
-
-  -pdf)
-   echo "Creating $pdffile ..."
-   xsltproc --nonet --xinclude -o $fofile $xsl_fo $xmlfmtfile
-   pdfxmltex $fofile >$OUT </dev/null
-   pdfxmltex $fofile >$OUT </dev/null
-   pdfxmltex $fofile >$OUT </dev/null
-   cleanup $OUT $xmlfmtfile *.aux *.fo *.log *.out
-  ;;
-
-  -ps)
-   echo "Creating $psfile ..."
-   xsltproc --nonet --xinclude -o $fofile $xsl_fo $xmlfmtfile
-   pdfxmltex $fofile >$OUT </dev/null
-   pdfxmltex $fofile >$OUT </dev/null
-   pdfxmltex $fofile >$OUT </dev/null
-   pdftops $pdffile $psfile
-   cleanup $OUT $xmlfmtfile $pdffile *.aux *.fo *.log *.out
-#  passivetex is broken, so we can't go this route yet.
-#   xmltex $fofile >$OUT </dev/null
-#   xmltex $fofile >$OUT </dev/null
-#   xmltex $fofile >$OUT </dev/null
-#   dvips -R -q -o bzip-manual.ps *.dvi
-  ;;
-
-  *)
-  usage
-  ;;
-esac
diff --git a/Utilities/cmcurl/CMake/CMakeConfigurableFile.in b/Utilities/cmcurl/CMake/CMakeConfigurableFile.in
index df2c382..2bafe2c 100644
--- a/Utilities/cmcurl/CMake/CMakeConfigurableFile.in
+++ b/Utilities/cmcurl/CMake/CMakeConfigurableFile.in
@@ -1 +1,22 @@
+#***************************************************************************
+#                                  _   _ ____  _
+#  Project                     ___| | | |  _ \| |
+#                             / __| | | | |_) | |
+#                            | (__| |_| |  _ <| |___
+#                             \___|\___/|_| \_\_____|
+#
+# Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+#
+# This software is licensed as described in the file COPYING, which
+# you should have received as part of this distribution. The terms
+# are also available at https://curl.haxx.se/docs/copyright.html.
+#
+# You may opt to use, copy, modify, merge, publish, distribute and/or sell
+# copies of the Software, and permit persons to whom the Software is
+# furnished to do so, under the terms of the COPYING file.
+#
+# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+# KIND, either express or implied.
+#
+###########################################################################
 @CMAKE_CONFIGURABLE_FILE_CONTENT@
diff --git a/Utilities/cmcurl/CMake/CurlSymbolHiding.cmake b/Utilities/cmcurl/CMake/CurlSymbolHiding.cmake
index 60ee8e6..aaac9fe 100644
--- a/Utilities/cmcurl/CMake/CurlSymbolHiding.cmake
+++ b/Utilities/cmcurl/CMake/CurlSymbolHiding.cmake
@@ -1,3 +1,24 @@
+#***************************************************************************
+#                                  _   _ ____  _
+#  Project                     ___| | | |  _ \| |
+#                             / __| | | | |_) | |
+#                            | (__| |_| |  _ <| |___
+#                             \___|\___/|_| \_\_____|
+#
+# Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+#
+# This software is licensed as described in the file COPYING, which
+# you should have received as part of this distribution. The terms
+# are also available at https://curl.haxx.se/docs/copyright.html.
+#
+# You may opt to use, copy, modify, merge, publish, distribute and/or sell
+# copies of the Software, and permit persons to whom the Software is
+# furnished to do so, under the terms of the COPYING file.
+#
+# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+# KIND, either express or implied.
+#
+###########################################################################
 include(CheckCSourceCompiles)
 
 option(CURL_HIDDEN_SYMBOLS "Set to ON to hide libcurl internal symbols (=hide all symbols that aren't officially external)." ON)
@@ -11,13 +32,7 @@
     set(_SYMBOL_EXTERN "__attribute__ ((__visibility__ (\"default\")))")
     set(_CFLAG_SYMBOLS_HIDE "-fvisibility=hidden")
   elseif(CMAKE_COMPILER_IS_GNUCC)
-    if(NOT CMAKE_VERSION VERSION_LESS 2.8.10)
-      set(GCC_VERSION ${CMAKE_C_COMPILER_VERSION})
-    else()
-      execute_process(COMMAND ${CMAKE_C_COMPILER} -dumpversion
-                      OUTPUT_VARIABLE GCC_VERSION)
-    endif()
-    if(NOT GCC_VERSION VERSION_LESS 3.4)
+    if(NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 3.4)
       # note: this is considered buggy prior to 4.0 but the autotools don't care, so let's ignore that fact
       set(SUPPORTS_SYMBOL_HIDING TRUE)
       set(_SYMBOL_EXTERN "__attribute__ ((__visibility__ (\"default\")))")
@@ -29,7 +44,7 @@
     set(_CFLAG_SYMBOLS_HIDE "-xldscope=hidden")
   elseif(CMAKE_C_COMPILER_ID MATCHES "Intel" AND NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 9.0)
     # note: this should probably just check for version 9.1.045 but I'm not 100% sure
-    #       so let's to it the same way autotools do.
+    #       so let's do it the same way autotools do.
     set(SUPPORTS_SYMBOL_HIDING TRUE)
     set(_SYMBOL_EXTERN "__attribute__ ((__visibility__ (\"default\")))")
     set(_CFLAG_SYMBOLS_HIDE "-fvisibility=hidden")
diff --git a/Utilities/cmcurl/CMake/CurlTests.c b/Utilities/cmcurl/CMake/CurlTests.c
index 07b516b..3ef35f0 100644
--- a/Utilities/cmcurl/CMake/CurlTests.c
+++ b/Utilities/cmcurl/CMake/CurlTests.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -125,6 +125,7 @@
 #if   defined(HAVE_GETHOSTBYADDR_R_5) || \
       defined(HAVE_GETHOSTBYADDR_R_5_REENTRANT)
   rc = gethostbyaddr_r(address, length, type, &h, &hdata);
+  (void)rc;
 #elif defined(HAVE_GETHOSTBYADDR_R_7) || \
       defined(HAVE_GETHOSTBYADDR_R_7_REENTRANT)
   hp = gethostbyaddr_r(address, length, type, &h, buffer, 8192, &h_errnop);
@@ -132,6 +133,7 @@
 #elif defined(HAVE_GETHOSTBYADDR_R_8) || \
       defined(HAVE_GETHOSTBYADDR_R_8_REENTRANT)
   rc = gethostbyaddr_r(address, length, type, &h, buffer, 8192, &hp, &h_errnop);
+  (void)rc;
 #endif
 
 #if   defined(HAVE_GETHOSTBYNAME_R_3) || \
diff --git a/Utilities/cmcurl/CMake/FindBearSSL.cmake b/Utilities/cmcurl/CMake/FindBearSSL.cmake
new file mode 100644
index 0000000..a8f72c9
--- /dev/null
+++ b/Utilities/cmcurl/CMake/FindBearSSL.cmake
@@ -0,0 +1,30 @@
+#***************************************************************************
+#                                  _   _ ____  _
+#  Project                     ___| | | |  _ \| |
+#                             / __| | | | |_) | |
+#                            | (__| |_| |  _ <| |___
+#                             \___|\___/|_| \_\_____|
+#
+# Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+#
+# This software is licensed as described in the file COPYING, which
+# you should have received as part of this distribution. The terms
+# are also available at https://curl.haxx.se/docs/copyright.html.
+#
+# You may opt to use, copy, modify, merge, publish, distribute and/or sell
+# copies of the Software, and permit persons to whom the Software is
+# furnished to do so, under the terms of the COPYING file.
+#
+# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+# KIND, either express or implied.
+#
+###########################################################################
+find_path(BEARSSL_INCLUDE_DIRS bearssl.h)
+
+find_library(BEARSSL_LIBRARY bearssl)
+
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(BEARSSL DEFAULT_MSG
+    BEARSSL_INCLUDE_DIRS BEARSSL_LIBRARY)
+
+mark_as_advanced(BEARSSL_INCLUDE_DIRS BEARSSL_LIBRARY)
diff --git a/Utilities/cmcurl/CMake/FindBrotli.cmake b/Utilities/cmcurl/CMake/FindBrotli.cmake
index 351b8f7..c43172b 100644
--- a/Utilities/cmcurl/CMake/FindBrotli.cmake
+++ b/Utilities/cmcurl/CMake/FindBrotli.cmake
@@ -1,3 +1,24 @@
+#***************************************************************************
+#                                  _   _ ____  _
+#  Project                     ___| | | |  _ \| |
+#                             / __| | | | |_) | |
+#                            | (__| |_| |  _ <| |___
+#                             \___|\___/|_| \_\_____|
+#
+# Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+#
+# This software is licensed as described in the file COPYING, which
+# you should have received as part of this distribution. The terms
+# are also available at https://curl.haxx.se/docs/copyright.html.
+#
+# You may opt to use, copy, modify, merge, publish, distribute and/or sell
+# copies of the Software, and permit persons to whom the Software is
+# furnished to do so, under the terms of the COPYING file.
+#
+# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+# KIND, either express or implied.
+#
+###########################################################################
 include(FindPackageHandleStandardArgs)
 
 find_path(BROTLI_INCLUDE_DIR "brotli/decode.h")
diff --git a/Utilities/cmcurl/CMake/FindCARES.cmake b/Utilities/cmcurl/CMake/FindCARES.cmake
index 723044a..9160ae5 100644
--- a/Utilities/cmcurl/CMake/FindCARES.cmake
+++ b/Utilities/cmcurl/CMake/FindCARES.cmake
@@ -1,3 +1,24 @@
+#***************************************************************************
+#                                  _   _ ____  _
+#  Project                     ___| | | |  _ \| |
+#                             / __| | | | |_) | |
+#                            | (__| |_| |  _ <| |___
+#                             \___|\___/|_| \_\_____|
+#
+# Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+#
+# This software is licensed as described in the file COPYING, which
+# you should have received as part of this distribution. The terms
+# are also available at https://curl.haxx.se/docs/copyright.html.
+#
+# You may opt to use, copy, modify, merge, publish, distribute and/or sell
+# copies of the Software, and permit persons to whom the Software is
+# furnished to do so, under the terms of the COPYING file.
+#
+# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+# KIND, either express or implied.
+#
+###########################################################################
 # - Find c-ares
 # Find the c-ares includes and library
 # This module defines
@@ -7,34 +28,16 @@
 # also defined, but not for general use are
 # CARES_LIBRARY, where to find the c-ares library.
 
-find_path(CARES_INCLUDE_DIR ares.h
-  /usr/local/include
-  /usr/include
-  )
+find_path(CARES_INCLUDE_DIR ares.h)
 
 set(CARES_NAMES ${CARES_NAMES} cares)
 find_library(CARES_LIBRARY
   NAMES ${CARES_NAMES}
-  PATHS /usr/lib /usr/local/lib
   )
 
-if(CARES_LIBRARY AND CARES_INCLUDE_DIR)
-  set(CARES_LIBRARIES ${CARES_LIBRARY})
-  set(CARES_FOUND "YES")
-else()
-  set(CARES_FOUND "NO")
-endif()
-
-
-if(CARES_FOUND)
-  if(NOT CARES_FIND_QUIETLY)
-    message(STATUS "Found c-ares: ${CARES_LIBRARIES}")
-  endif()
-else()
-  if(CARES_FIND_REQUIRED)
-    message(FATAL_ERROR "Could not find c-ares library")
-  endif()
-endif()
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(CARES
+    REQUIRED_VARS CARES_LIBRARY CARES_INCLUDE_DIR)
 
 mark_as_advanced(
   CARES_LIBRARY
diff --git a/Utilities/cmcurl/CMake/FindGSS.cmake b/Utilities/cmcurl/CMake/FindGSS.cmake
index 8a28f2f..02111a2 100644
--- a/Utilities/cmcurl/CMake/FindGSS.cmake
+++ b/Utilities/cmcurl/CMake/FindGSS.cmake
@@ -1,3 +1,24 @@
+#***************************************************************************
+#                                  _   _ ____  _
+#  Project                     ___| | | |  _ \| |
+#                             / __| | | | |_) | |
+#                            | (__| |_| |  _ <| |___
+#                             \___|\___/|_| \_\_____|
+#
+# Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+#
+# This software is licensed as described in the file COPYING, which
+# you should have received as part of this distribution. The terms
+# are also available at https://curl.haxx.se/docs/copyright.html.
+#
+# You may opt to use, copy, modify, merge, publish, distribute and/or sell
+# copies of the Software, and permit persons to whom the Software is
+# furnished to do so, under the terms of the COPYING file.
+#
+# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+# KIND, either express or implied.
+#
+###########################################################################
 # - Try to find the GSS Kerberos library
 # Once done this will define
 #
@@ -62,6 +83,7 @@
           COMMAND ${_GSS_CONFIGURE_SCRIPT} "--cflags" "gssapi"
           OUTPUT_VARIABLE _GSS_CFLAGS
           RESULT_VARIABLE _GSS_CONFIGURE_FAILED
+          OUTPUT_STRIP_TRAILING_WHITESPACE
       )
     message(STATUS "CFLAGS: ${_GSS_CFLAGS}")
     if(NOT _GSS_CONFIGURE_FAILED) # 0 means success
@@ -84,6 +106,7 @@
         COMMAND ${_GSS_CONFIGURE_SCRIPT} "--libs" "gssapi"
         OUTPUT_VARIABLE _GSS_LIB_FLAGS
         RESULT_VARIABLE _GSS_CONFIGURE_FAILED
+        OUTPUT_STRIP_TRAILING_WHITESPACE
     )
     message(STATUS "LDFLAGS: ${_GSS_LIB_FLAGS}")
 
@@ -110,6 +133,7 @@
         COMMAND ${_GSS_CONFIGURE_SCRIPT} "--version"
         OUTPUT_VARIABLE _GSS_VERSION
         RESULT_VARIABLE _GSS_CONFIGURE_FAILED
+        OUTPUT_STRIP_TRAILING_WHITESPACE
     )
 
     # older versions may not have the "--version" parameter. In this case we just don't care.
@@ -121,6 +145,7 @@
         COMMAND ${_GSS_CONFIGURE_SCRIPT} "--vendor"
         OUTPUT_VARIABLE _GSS_VENDOR
         RESULT_VARIABLE _GSS_CONFIGURE_FAILED
+        OUTPUT_STRIP_TRAILING_WHITESPACE
     )
 
     # older versions may not have the "--vendor" parameter. In this case we just don't care.
@@ -134,7 +159,7 @@
       endif()
     endif()
 
-  else() # either there is no config script or we are on platform that doesn't provide one (Windows?)
+  else() # either there is no config script or we are on a platform that doesn't provide one (Windows?)
 
     find_path(_GSS_INCLUDE_DIR
         NAMES
@@ -164,7 +189,7 @@
         set(CMAKE_REQUIRED_DEFINITIONS "")
       endif()
     else()
-      # I'm not convienced if this is the right way but this is what autotools do at the moment
+      # I'm not convinced if this is the right way but this is what autotools do at the moment
       find_path(_GSS_INCLUDE_DIR
           NAMES
               "gssapi.h"
diff --git a/Utilities/cmcurl/CMake/FindLibSSH2.cmake b/Utilities/cmcurl/CMake/FindLibSSH2.cmake
index 84822db..4cdf3e3 100644
--- a/Utilities/cmcurl/CMake/FindLibSSH2.cmake
+++ b/Utilities/cmcurl/CMake/FindLibSSH2.cmake
@@ -1,3 +1,24 @@
+#***************************************************************************
+#                                  _   _ ____  _
+#  Project                     ___| | | |  _ \| |
+#                             / __| | | | |_) | |
+#                            | (__| |_| |  _ <| |___
+#                             \___|\___/|_| \_\_____|
+#
+# Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+#
+# This software is licensed as described in the file COPYING, which
+# you should have received as part of this distribution. The terms
+# are also available at https://curl.haxx.se/docs/copyright.html.
+#
+# You may opt to use, copy, modify, merge, publish, distribute and/or sell
+# copies of the Software, and permit persons to whom the Software is
+# furnished to do so, under the terms of the COPYING file.
+#
+# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+# KIND, either express or implied.
+#
+###########################################################################
 # - Try to find the libssh2 library
 # Once done this will define
 #
@@ -5,31 +26,18 @@
 # LIBSSH2_INCLUDE_DIR - the libssh2 include directory
 # LIBSSH2_LIBRARY - the libssh2 library name
 
-if(LIBSSH2_INCLUDE_DIR AND LIBSSH2_LIBRARY)
-  set(LibSSH2_FIND_QUIETLY TRUE)
-endif()
+find_path(LIBSSH2_INCLUDE_DIR libssh2.h)
 
-find_path(LIBSSH2_INCLUDE_DIR libssh2.h
-)
-
-find_library(LIBSSH2_LIBRARY NAMES ssh2
-)
+find_library(LIBSSH2_LIBRARY NAMES ssh2 libssh2)
 
 if(LIBSSH2_INCLUDE_DIR)
-  file(STRINGS "${LIBSSH2_INCLUDE_DIR}/libssh2.h" libssh2_version_str REGEX "^#define[\t ]+LIBSSH2_VERSION_NUM[\t ]+0x[0-9][0-9][0-9][0-9][0-9][0-9].*")
-
-  string(REGEX REPLACE "^.*LIBSSH2_VERSION_NUM[\t ]+0x([0-9][0-9]).*$" "\\1" LIBSSH2_VERSION_MAJOR "${libssh2_version_str}")
-  string(REGEX REPLACE "^.*LIBSSH2_VERSION_NUM[\t ]+0x[0-9][0-9]([0-9][0-9]).*$" "\\1" LIBSSH2_VERSION_MINOR  "${libssh2_version_str}")
-  string(REGEX REPLACE "^.*LIBSSH2_VERSION_NUM[\t ]+0x[0-9][0-9][0-9][0-9]([0-9][0-9]).*$" "\\1" LIBSSH2_VERSION_PATCH "${libssh2_version_str}")
-
-  string(REGEX REPLACE "^0(.+)" "\\1" LIBSSH2_VERSION_MAJOR "${LIBSSH2_VERSION_MAJOR}")
-  string(REGEX REPLACE "^0(.+)" "\\1" LIBSSH2_VERSION_MINOR "${LIBSSH2_VERSION_MINOR}")
-  string(REGEX REPLACE "^0(.+)" "\\1" LIBSSH2_VERSION_PATCH "${LIBSSH2_VERSION_PATCH}")
-
-  set(LIBSSH2_VERSION "${LIBSSH2_VERSION_MAJOR}.${LIBSSH2_VERSION_MINOR}.${LIBSSH2_VERSION_PATCH}")
+  file(STRINGS "${LIBSSH2_INCLUDE_DIR}/libssh2.h" libssh2_version_str REGEX "^#define[\t ]+LIBSSH2_VERSION[\t ]+\"(.*)\"")
+  string(REGEX REPLACE "^.*\"([^\"]+)\"" "\\1"  LIBSSH2_VERSION "${libssh2_version_str}")
 endif()
 
 include(FindPackageHandleStandardArgs)
-find_package_handle_standard_args(LibSSH2 DEFAULT_MSG LIBSSH2_INCLUDE_DIR LIBSSH2_LIBRARY )
+find_package_handle_standard_args(LibSSH2
+    REQUIRED_VARS LIBSSH2_LIBRARY LIBSSH2_INCLUDE_DIR
+    VERSION_VAR LIBSSH2_VERSION)
 
-mark_as_advanced(LIBSSH2_INCLUDE_DIR LIBSSH2_LIBRARY LIBSSH2_VERSION_MAJOR LIBSSH2_VERSION_MINOR LIBSSH2_VERSION_PATCH LIBSSH2_VERSION)
+mark_as_advanced(LIBSSH2_INCLUDE_DIR LIBSSH2_LIBRARY)
diff --git a/Utilities/cmcurl/CMake/FindMbedTLS.cmake b/Utilities/cmcurl/CMake/FindMbedTLS.cmake
index a916395..2ebe721 100644
--- a/Utilities/cmcurl/CMake/FindMbedTLS.cmake
+++ b/Utilities/cmcurl/CMake/FindMbedTLS.cmake
@@ -1,3 +1,24 @@
+#***************************************************************************
+#                                  _   _ ____  _
+#  Project                     ___| | | |  _ \| |
+#                             / __| | | | |_) | |
+#                            | (__| |_| |  _ <| |___
+#                             \___|\___/|_| \_\_____|
+#
+# Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+#
+# This software is licensed as described in the file COPYING, which
+# you should have received as part of this distribution. The terms
+# are also available at https://curl.haxx.se/docs/copyright.html.
+#
+# You may opt to use, copy, modify, merge, publish, distribute and/or sell
+# copies of the Software, and permit persons to whom the Software is
+# furnished to do so, under the terms of the COPYING file.
+#
+# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+# KIND, either express or implied.
+#
+###########################################################################
 find_path(MBEDTLS_INCLUDE_DIRS mbedtls/ssl.h)
 
 find_library(MBEDTLS_LIBRARY mbedtls)
diff --git a/Utilities/cmcurl/CMake/FindNGHTTP2.cmake b/Utilities/cmcurl/CMake/FindNGHTTP2.cmake
index 348b961..e1eba05 100644
--- a/Utilities/cmcurl/CMake/FindNGHTTP2.cmake
+++ b/Utilities/cmcurl/CMake/FindNGHTTP2.cmake
@@ -1,3 +1,24 @@
+#***************************************************************************
+#                                  _   _ ____  _
+#  Project                     ___| | | |  _ \| |
+#                             / __| | | | |_) | |
+#                            | (__| |_| |  _ <| |___
+#                             \___|\___/|_| \_\_____|
+#
+# Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+#
+# This software is licensed as described in the file COPYING, which
+# you should have received as part of this distribution. The terms
+# are also available at https://curl.haxx.se/docs/copyright.html.
+#
+# You may opt to use, copy, modify, merge, publish, distribute and/or sell
+# copies of the Software, and permit persons to whom the Software is
+# furnished to do so, under the terms of the COPYING file.
+#
+# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+# KIND, either express or implied.
+#
+###########################################################################
 include(FindPackageHandleStandardArgs)
 
 find_path(NGHTTP2_INCLUDE_DIR "nghttp2/nghttp2.h")
@@ -10,9 +31,9 @@
     REQUIRED_VARS
       NGHTTP2_LIBRARY
       NGHTTP2_INCLUDE_DIR
-    FAIL_MESSAGE
-      "Could NOT find NGHTTP2"
 )
 
 set(NGHTTP2_INCLUDE_DIRS ${NGHTTP2_INCLUDE_DIR})
 set(NGHTTP2_LIBRARIES ${NGHTTP2_LIBRARY})
+
+mark_as_advanced(NGHTTP2_INCLUDE_DIRS NGHTTP2_LIBRARIES)
diff --git a/Utilities/cmcurl/CMake/FindNGHTTP3.cmake b/Utilities/cmcurl/CMake/FindNGHTTP3.cmake
new file mode 100644
index 0000000..73ce9e1
--- /dev/null
+++ b/Utilities/cmcurl/CMake/FindNGHTTP3.cmake
@@ -0,0 +1,76 @@
+#***************************************************************************
+#                                  _   _ ____  _
+#  Project                     ___| | | |  _ \| |
+#                             / __| | | | |_) | |
+#                            | (__| |_| |  _ <| |___
+#                             \___|\___/|_| \_\_____|
+#
+# Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+#
+# This software is licensed as described in the file COPYING, which
+# you should have received as part of this distribution. The terms
+# are also available at https://curl.haxx.se/docs/copyright.html.
+#
+# You may opt to use, copy, modify, merge, publish, distribute and/or sell
+# copies of the Software, and permit persons to whom the Software is
+# furnished to do so, under the terms of the COPYING file.
+#
+# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+# KIND, either express or implied.
+#
+###########################################################################
+
+#[=======================================================================[.rst:
+FindNGHTTP3
+----------
+
+Find the nghttp3 library
+
+Result Variables
+^^^^^^^^^^^^^^^^
+
+``NGHTTP3_FOUND``
+  System has nghttp3
+``NGHTTP3_INCLUDE_DIRS``
+  The nghttp3 include directories.
+``NGHTTP3_LIBRARIES``
+  The libraries needed to use nghttp3
+``NGHTTP3_VERSION``
+  version of nghttp3.
+#]=======================================================================]
+
+if(UNIX)
+  find_package(PkgConfig QUIET)
+  pkg_search_module(PC_NGHTTP3 libnghttp3)
+endif()
+
+find_path(NGHTTP3_INCLUDE_DIR nghttp3/nghttp3.h
+  HINTS
+    ${PC_NGHTTP3_INCLUDEDIR}
+    ${PC_NGHTTP3_INCLUDE_DIRS}
+)
+
+find_library(NGHTTP3_LIBRARY NAMES nghttp3
+  HINTS
+    ${PC_NGHTTP3_LIBDIR}
+    ${PC_NGHTTP3_LIBRARY_DIRS}
+)
+
+if(PC_NGHTTP3_VERSION)
+  set(NGHTTP3_VERSION ${PC_NGHTTP3_VERSION})
+endif()
+
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(NGHTTP3
+  REQUIRED_VARS
+    NGHTTP3_LIBRARY
+    NGHTTP3_INCLUDE_DIR
+  VERSION_VAR NGHTTP3_VERSION
+)
+
+if(NGHTTP3_FOUND)
+  set(NGHTTP3_LIBRARIES    ${NGHTTP3_LIBRARY})
+  set(NGHTTP3_INCLUDE_DIRS ${NGHTTP3_INCLUDE_DIR})
+endif()
+
+mark_as_advanced(NGHTTP3_INCLUDE_DIRS NGHTTP3_LIBRARIES)
diff --git a/Utilities/cmcurl/CMake/FindNGTCP2.cmake b/Utilities/cmcurl/CMake/FindNGTCP2.cmake
new file mode 100644
index 0000000..a1ed8cd
--- /dev/null
+++ b/Utilities/cmcurl/CMake/FindNGTCP2.cmake
@@ -0,0 +1,113 @@
+#***************************************************************************
+#                                  _   _ ____  _
+#  Project                     ___| | | |  _ \| |
+#                             / __| | | | |_) | |
+#                            | (__| |_| |  _ <| |___
+#                             \___|\___/|_| \_\_____|
+#
+# Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+#
+# This software is licensed as described in the file COPYING, which
+# you should have received as part of this distribution. The terms
+# are also available at https://curl.haxx.se/docs/copyright.html.
+#
+# You may opt to use, copy, modify, merge, publish, distribute and/or sell
+# copies of the Software, and permit persons to whom the Software is
+# furnished to do so, under the terms of the COPYING file.
+#
+# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+# KIND, either express or implied.
+#
+###########################################################################
+
+#[=======================================================================[.rst:
+FindNGTCP2
+----------
+
+Find the ngtcp2 library
+
+This module accepts optional COMPONENTS to control the crypto library (these are
+mutually exclusive)::
+
+  OpenSSL:  Use libngtcp2_crypto_openssl
+  GnuTLS:   Use libngtcp2_crypto_gnutls
+
+Result Variables
+^^^^^^^^^^^^^^^^
+
+``NGTCP2_FOUND``
+  System has ngtcp2
+``NGTCP2_INCLUDE_DIRS``
+  The ngtcp2 include directories.
+``NGTCP2_LIBRARIES``
+  The libraries needed to use ngtcp2
+``NGTCP2_VERSION``
+  version of ngtcp2.
+#]=======================================================================]
+
+if(UNIX)
+  find_package(PkgConfig QUIET)
+  pkg_search_module(PC_NGTCP2 libngtcp2)
+endif()
+
+find_path(NGTCP2_INCLUDE_DIR ngtcp2/ngtcp2.h
+  HINTS
+    ${PC_NGTCP2_INCLUDEDIR}
+    ${PC_NGTCP2_INCLUDE_DIRS}
+)
+
+find_library(NGTCP2_LIBRARY NAMES ngtcp2
+  HINTS
+    ${PC_NGTCP2_LIBDIR}
+    ${PC_NGTCP2_LIBRARY_DIRS}
+)
+
+if(PC_NGTCP2_VERSION)
+  set(NGTCP2_VERSION ${PC_NGTCP2_VERSION})
+endif()
+
+if(NGTCP2_FIND_COMPONENTS)
+  set(NGTCP2_CRYPTO_BACKEND "")
+  foreach(component IN LISTS NGTCP2_FIND_COMPONENTS)
+    if(component MATCHES "^(OpenSSL|GnuTLS)")
+      if(NGTCP2_CRYPTO_BACKEND)
+        message(FATAL_ERROR "NGTCP2: Only one crypto library can be selected")
+      endif()
+      set(NGTCP2_CRYPTO_BACKEND ${component})
+    endif()
+  endforeach()
+
+  if(NGTCP2_CRYPTO_BACKEND)
+    string(TOLOWER "ngtcp2_crypto_${NGTCP2_CRYPTO_BACKEND}" _crypto_library)
+    if(UNIX)
+      pkg_search_module(PC_${_crypto_library} lib${_crypto_library})
+    endif()
+    find_library(${_crypto_library}_LIBRARY
+      NAMES
+        ${_crypto_library}
+      HINTS
+        ${PC_${_crypto_library}_LIBDIR}
+        ${PC_${_crypto_library}_LIBRARY_DIRS}
+    )
+    if(${_crypto_library}_LIBRARY)
+      set(NGTCP2_${NGTCP2_CRYPTO_BACKEND}_FOUND TRUE)
+      set(NGTCP2_CRYPTO_LIBRARY ${${_crypto_library}_LIBRARY})
+    endif()
+  endif()
+endif()
+
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(NGTCP2
+  REQUIRED_VARS
+    NGTCP2_LIBRARY
+    NGTCP2_INCLUDE_DIR
+  VERSION_VAR NGTCP2_VERSION
+  HANDLE_COMPONENTS
+)
+
+if(NGTCP2_FOUND)
+  set(NGTCP2_LIBRARIES    ${NGTCP2_LIBRARY} ${NGTCP2_CRYPTO_LIBRARY})
+  set(NGTCP2_INCLUDE_DIRS ${NGTCP2_INCLUDE_DIR})
+endif()
+
+mark_as_advanced(NGTCP2_INCLUDE_DIRS NGTCP2_LIBRARIES)
diff --git a/Utilities/cmcurl/CMake/FindNSS.cmake b/Utilities/cmcurl/CMake/FindNSS.cmake
new file mode 100644
index 0000000..5fdb2b7
--- /dev/null
+++ b/Utilities/cmcurl/CMake/FindNSS.cmake
@@ -0,0 +1,38 @@
+#***************************************************************************
+#                                  _   _ ____  _
+#  Project                     ___| | | |  _ \| |
+#                             / __| | | | |_) | |
+#                            | (__| |_| |  _ <| |___
+#                             \___|\___/|_| \_\_____|
+#
+# Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+#
+# This software is licensed as described in the file COPYING, which
+# you should have received as part of this distribution. The terms
+# are also available at https://curl.haxx.se/docs/copyright.html.
+#
+# You may opt to use, copy, modify, merge, publish, distribute and/or sell
+# copies of the Software, and permit persons to whom the Software is
+# furnished to do so, under the terms of the COPYING file.
+#
+# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+# KIND, either express or implied.
+#
+###########################################################################
+if(UNIX)
+  find_package(PkgConfig QUIET)
+  pkg_search_module(PC_NSS nss)
+endif()
+if(NOT PC_NSS_FOUND)
+  return()
+endif()
+
+set(NSS_LIBRARIES ${PC_NSS_LINK_LIBRARIES})
+set(NSS_INCLUDE_DIRS ${PC_NSS_INCLUDE_DIRS})
+
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(NSS
+    REQUIRED_VARS NSS_LIBRARIES NSS_INCLUDE_DIRS
+    VERSION_VAR PC_NSS_VERSION)
+
+mark_as_advanced(NSS_INCLUDE_DIRS NSS_LIBRARIES)
diff --git a/Utilities/cmcurl/CMake/FindQUICHE.cmake b/Utilities/cmcurl/CMake/FindQUICHE.cmake
new file mode 100644
index 0000000..01d1758
--- /dev/null
+++ b/Utilities/cmcurl/CMake/FindQUICHE.cmake
@@ -0,0 +1,68 @@
+#***************************************************************************
+#                                  _   _ ____  _
+#  Project                     ___| | | |  _ \| |
+#                             / __| | | | |_) | |
+#                            | (__| |_| |  _ <| |___
+#                             \___|\___/|_| \_\_____|
+#
+# Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+#
+# This software is licensed as described in the file COPYING, which
+# you should have received as part of this distribution. The terms
+# are also available at https://curl.haxx.se/docs/copyright.html.
+#
+# You may opt to use, copy, modify, merge, publish, distribute and/or sell
+# copies of the Software, and permit persons to whom the Software is
+# furnished to do so, under the terms of the COPYING file.
+#
+# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+# KIND, either express or implied.
+#
+###########################################################################
+
+#[=======================================================================[.rst:
+FindQUICHE
+----------
+
+Find the quiche library
+
+Result Variables
+^^^^^^^^^^^^^^^^
+
+``QUICHE_FOUND``
+  System has quiche
+``QUICHE_INCLUDE_DIRS``
+  The quiche include directories.
+``QUICHE_LIBRARIES``
+  The libraries needed to use quiche
+#]=======================================================================]
+if(UNIX)
+  find_package(PkgConfig QUIET)
+  pkg_search_module(PC_QUICHE quiche)
+endif()
+
+find_path(QUICHE_INCLUDE_DIR quiche.h
+  HINTS
+    ${PC_QUICHE_INCLUDEDIR}
+    ${PC_QUICHE_INCLUDE_DIRS}
+)
+
+find_library(QUICHE_LIBRARY NAMES quiche
+  HINTS
+    ${PC_QUICHE_LIBDIR}
+    ${PC_QUICHE_LIBRARY_DIRS}
+)
+
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(QUICHE
+  REQUIRED_VARS
+    QUICHE_LIBRARY
+    QUICHE_INCLUDE_DIR
+)
+
+if(QUICHE_FOUND)
+  set(QUICHE_LIBRARIES    ${QUICHE_LIBRARY})
+  set(QUICHE_INCLUDE_DIRS ${QUICHE_INCLUDE_DIR})
+endif()
+
+mark_as_advanced(QUICHE_INCLUDE_DIRS QUICHE_LIBRARIES)
diff --git a/Utilities/cmcurl/CMake/FindWolfSSL.cmake b/Utilities/cmcurl/CMake/FindWolfSSL.cmake
new file mode 100644
index 0000000..54df1a8
--- /dev/null
+++ b/Utilities/cmcurl/CMake/FindWolfSSL.cmake
@@ -0,0 +1,34 @@
+#***************************************************************************
+#                                  _   _ ____  _
+#  Project                     ___| | | |  _ \| |
+#                             / __| | | | |_) | |
+#                            | (__| |_| |  _ <| |___
+#                             \___|\___/|_| \_\_____|
+#
+# Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+#
+# This software is licensed as described in the file COPYING, which
+# you should have received as part of this distribution. The terms
+# are also available at https://curl.haxx.se/docs/copyright.html.
+#
+# You may opt to use, copy, modify, merge, publish, distribute and/or sell
+# copies of the Software, and permit persons to whom the Software is
+# furnished to do so, under the terms of the COPYING file.
+#
+# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+# KIND, either express or implied.
+#
+###########################################################################
+find_path(WolfSSL_INCLUDE_DIR NAMES wolfssl/ssl.h)
+find_library(WolfSSL_LIBRARY NAMES wolfssl)
+mark_as_advanced(WolfSSL_INCLUDE_DIR WolfSSL_LIBRARY)
+
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(WolfSSL
+  REQUIRED_VARS WolfSSL_INCLUDE_DIR WolfSSL_LIBRARY
+  )
+
+if(WolfSSL_FOUND)
+  set(WolfSSL_INCLUDE_DIRS ${WolfSSL_INCLUDE_DIR})
+  set(WolfSSL_LIBRARIES ${WolfSSL_LIBRARY})
+endif()
diff --git a/Utilities/cmcurl/CMake/Macros.cmake b/Utilities/cmcurl/CMake/Macros.cmake
index 7f71345..65a41e4 100644
--- a/Utilities/cmcurl/CMake/Macros.cmake
+++ b/Utilities/cmcurl/CMake/Macros.cmake
@@ -1,3 +1,24 @@
+#***************************************************************************
+#                                  _   _ ____  _
+#  Project                     ___| | | |  _ \| |
+#                             / __| | | | |_) | |
+#                            | (__| |_| |  _ <| |___
+#                             \___|\___/|_| \_\_____|
+#
+# Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+#
+# This software is licensed as described in the file COPYING, which
+# you should have received as part of this distribution. The terms
+# are also available at https://curl.haxx.se/docs/copyright.html.
+#
+# You may opt to use, copy, modify, merge, publish, distribute and/or sell
+# copies of the Software, and permit persons to whom the Software is
+# furnished to do so, under the terms of the COPYING file.
+#
+# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+# KIND, either express or implied.
+#
+###########################################################################
 #File defines convenience macros for available feature testing
 
 # This macro checks if the symbol exists in the library and if it
diff --git a/Utilities/cmcurl/CMake/OtherTests.cmake b/Utilities/cmcurl/CMake/OtherTests.cmake
index c1c9aa3..8c9a491 100644
--- a/Utilities/cmcurl/CMake/OtherTests.cmake
+++ b/Utilities/cmcurl/CMake/OtherTests.cmake
@@ -1,3 +1,24 @@
+#***************************************************************************
+#                                  _   _ ____  _
+#  Project                     ___| | | |  _ \| |
+#                             / __| | | | |_) | |
+#                            | (__| |_| |  _ <| |___
+#                             \___|\___/|_| \_\_____|
+#
+# Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+#
+# This software is licensed as described in the file COPYING, which
+# you should have received as part of this distribution. The terms
+# are also available at https://curl.haxx.se/docs/copyright.html.
+#
+# You may opt to use, copy, modify, merge, publish, distribute and/or sell
+# copies of the Software, and permit persons to whom the Software is
+# furnished to do so, under the terms of the COPYING file.
+#
+# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+# KIND, either express or implied.
+#
+###########################################################################
 include(CheckCSourceCompiles)
 # The begin of the sources (macros and includes)
 set(_source_epilogue "#undef inline")
@@ -26,13 +47,20 @@
 
 set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY)
 
+if(1) # CMake hard-codes these
+  set(RECV_TYPE_ARG1 "curl_socket_t")
+  set(RECV_TYPE_ARG2 "char *")
+  set(RECV_TYPE_ARG3 "size_t")
+  set(RECV_TYPE_ARG4 "int")
+  set(RECV_TYPE_RETV "ssize_t")
+else()
 check_c_source_compiles("${_source_epilogue}
 int main(void) {
     recv(0, 0, 0, 0);
     return 0;
 }" curl_cv_recv)
 if(curl_cv_recv)
-  if(NOT DEFINED curl_cv_func_recv_args OR "${curl_cv_func_recv_args}" STREQUAL "unknown")
+  if(NOT DEFINED curl_cv_func_recv_args OR curl_cv_func_recv_args STREQUAL "unknown")
     foreach(recv_retv "int" "ssize_t" )
       foreach(recv_arg1 "SOCKET" "int" )
         foreach(recv_arg2 "char *" "void *" )
@@ -42,6 +70,9 @@
                 unset(curl_cv_func_recv_test CACHE)
                 check_c_source_compiles("
                   ${_source_epilogue}
+                  #ifdef WINSOCK_API_LINKAGE
+                  WINSOCK_API_LINKAGE
+                  #endif
                   extern ${recv_retv} ${signature_call_conv}
                   recv(${recv_arg1}, ${recv_arg2}, ${recv_arg3}, ${recv_arg4});
                   int main(void) {
@@ -81,15 +112,24 @@
     string(REGEX REPLACE "^[^,]*,[^,]*,[^,]*,[^,]*,([^,]*)$" "\\1" RECV_TYPE_RETV "${curl_cv_func_recv_args}")
   endif()
 
-  if("${curl_cv_func_recv_args}" STREQUAL "unknown")
+  if(curl_cv_func_recv_args STREQUAL "unknown")
     message(FATAL_ERROR "Cannot find proper types to use for recv args")
   endif()
 else()
   message(FATAL_ERROR "Unable to link function recv")
 endif()
 set(curl_cv_func_recv_args "${curl_cv_func_recv_args}" CACHE INTERNAL "Arguments for recv")
+endif()
 set(HAVE_RECV 1)
 
+if(1) # CMake hard-codes these
+  set(SEND_QUAL_ARG2 " ")
+  set(SEND_TYPE_ARG1 "curl_socket_t")
+  set(SEND_TYPE_ARG2 "char *")
+  set(SEND_TYPE_ARG3 "size_t")
+  set(SEND_TYPE_ARG4 "int")
+  set(SEND_TYPE_RETV "ssize_t")
+else()
 check_c_source_compiles("${_source_epilogue}
 int main(void) {
     send(0, 0, 0, 0);
@@ -106,6 +146,9 @@
                 unset(curl_cv_func_send_test CACHE)
                 check_c_source_compiles("
                   ${_source_epilogue}
+                  #ifdef WINSOCK_API_LINKAGE
+                  WINSOCK_API_LINKAGE
+                  #endif
                   extern ${send_retv} ${signature_call_conv}
                   send(${send_arg1}, ${send_arg2}, ${send_arg3}, ${send_arg4});
                   int main(void) {
@@ -156,6 +199,7 @@
   message(FATAL_ERROR "Unable to link function send")
 endif()
 set(curl_cv_func_send_args "${curl_cv_func_send_args}" CACHE INTERNAL "Arguments for send")
+endif()
 set(HAVE_SEND 1)
 
 check_c_source_compiles("${_source_epilogue}
diff --git a/Utilities/cmcurl/CMake/Platforms/WindowsCache.cmake b/Utilities/cmcurl/CMake/Platforms/WindowsCache.cmake
index 2dbe1bb..7c020bd 100644
--- a/Utilities/cmcurl/CMake/Platforms/WindowsCache.cmake
+++ b/Utilities/cmcurl/CMake/Platforms/WindowsCache.cmake
@@ -1,3 +1,24 @@
+#***************************************************************************
+#                                  _   _ ____  _
+#  Project                     ___| | | |  _ \| |
+#                             / __| | | | |_) | |
+#                            | (__| |_| |  _ <| |___
+#                             \___|\___/|_| \_\_____|
+#
+# Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+#
+# This software is licensed as described in the file COPYING, which
+# you should have received as part of this distribution. The terms
+# are also available at https://curl.haxx.se/docs/copyright.html.
+#
+# You may opt to use, copy, modify, merge, publish, distribute and/or sell
+# copies of the Software, and permit persons to whom the Software is
+# furnished to do so, under the terms of the COPYING file.
+#
+# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+# KIND, either express or implied.
+#
+###########################################################################
 if(NOT UNIX)
   if(WIN32)
     set(HAVE_LIBDL 0)
@@ -7,7 +28,6 @@
     set(HAVE_LIBNSL 0)
     set(HAVE_GETHOSTNAME 1)
     set(HAVE_LIBZ 0)
-    set(HAVE_LIBCRYPTO 0)
 
     set(HAVE_DLOPEN 0)
 
diff --git a/Utilities/cmcurl/CMake/Utilities.cmake b/Utilities/cmcurl/CMake/Utilities.cmake
index 5cb1d44..59b17d0 100644
--- a/Utilities/cmcurl/CMake/Utilities.cmake
+++ b/Utilities/cmcurl/CMake/Utilities.cmake
@@ -1,13 +1,33 @@
+#***************************************************************************
+#                                  _   _ ____  _
+#  Project                     ___| | | |  _ \| |
+#                             / __| | | | |_) | |
+#                            | (__| |_| |  _ <| |___
+#                             \___|\___/|_| \_\_____|
+#
+# Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+#
+# This software is licensed as described in the file COPYING, which
+# you should have received as part of this distribution. The terms
+# are also available at https://curl.haxx.se/docs/copyright.html.
+#
+# You may opt to use, copy, modify, merge, publish, distribute and/or sell
+# copies of the Software, and permit persons to whom the Software is
+# furnished to do so, under the terms of the COPYING file.
+#
+# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+# KIND, either express or implied.
+#
+###########################################################################
 # File containing various utilities
 
 # Returns a list of arguments that evaluate to true
 function(count_true output_count_var)
-  set(lst)
+  set(lst_len 0)
   foreach(option_var IN LISTS ARGN)
     if(${option_var})
-      list(APPEND lst ${option_var})
+      math(EXPR lst_len "${lst_len} + 1")
     endif()
   endforeach()
-  list(LENGTH lst lst_len)
   set(${output_count_var} ${lst_len} PARENT_SCOPE)
 endfunction()
diff --git a/Utilities/cmcurl/CMake/cmake_uninstall.cmake.in b/Utilities/cmcurl/CMake/cmake_uninstall.cmake.in
index 5178fd8..74e56a2 100644
--- a/Utilities/cmcurl/CMake/cmake_uninstall.cmake.in
+++ b/Utilities/cmcurl/CMake/cmake_uninstall.cmake.in
@@ -1,3 +1,24 @@
+#***************************************************************************
+#                                  _   _ ____  _
+#  Project                     ___| | | |  _ \| |
+#                             / __| | | | |_) | |
+#                            | (__| |_| |  _ <| |___
+#                             \___|\___/|_| \_\_____|
+#
+# Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+#
+# This software is licensed as described in the file COPYING, which
+# you should have received as part of this distribution. The terms
+# are also available at https://curl.haxx.se/docs/copyright.html.
+#
+# You may opt to use, copy, modify, merge, publish, distribute and/or sell
+# copies of the Software, and permit persons to whom the Software is
+# furnished to do so, under the terms of the COPYING file.
+#
+# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+# KIND, either express or implied.
+#
+###########################################################################
 if(NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt")
   message(FATAL_ERROR "Cannot find install manifest: @CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt")
 endif()
diff --git a/Utilities/cmcurl/CMake/curl-config.cmake.in b/Utilities/cmcurl/CMake/curl-config.cmake.in
index 1294e17..ae8cc30 100644
--- a/Utilities/cmcurl/CMake/curl-config.cmake.in
+++ b/Utilities/cmcurl/CMake/curl-config.cmake.in
@@ -1,3 +1,24 @@
+#***************************************************************************
+#                                  _   _ ____  _
+#  Project                     ___| | | |  _ \| |
+#                             / __| | | | |_) | |
+#                            | (__| |_| |  _ <| |___
+#                             \___|\___/|_| \_\_____|
+#
+# Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+#
+# This software is licensed as described in the file COPYING, which
+# you should have received as part of this distribution. The terms
+# are also available at https://curl.haxx.se/docs/copyright.html.
+#
+# You may opt to use, copy, modify, merge, publish, distribute and/or sell
+# copies of the Software, and permit persons to whom the Software is
+# furnished to do so, under the terms of the COPYING file.
+#
+# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+# KIND, either express or implied.
+#
+###########################################################################
 @PACKAGE_INIT@
 
 include(CMakeFindDependencyMacro)
diff --git a/Utilities/cmcurl/CMakeLists.txt b/Utilities/cmcurl/CMakeLists.txt
index bc8a7dc..d327f55 100644
--- a/Utilities/cmcurl/CMakeLists.txt
+++ b/Utilities/cmcurl/CMakeLists.txt
@@ -5,6 +5,7 @@
 set(BUILD_SHARED_LIBS OFF CACHE INTERNAL "Build shared libraries")
 set(CMAKE_USE_GSSAPI OFF CACHE INTERNAL "Disable curl gssapi")
 set(CMAKE_USE_LIBSSH2 OFF CACHE INTERNAL "Disable curl libssh2")
+set(CMAKE_USE_LIBSSH OFF)
 set(CMAKE_USE_OPENLDAP OFF CACHE INTERNAL "No curl OpenLDAP")
 set(CURL_DISABLE_COOKIES OFF CACHE INTERNAL "Do not disable curl cookie support")
 set(CURL_DISABLE_CRYPTO_AUTH OFF CACHE INTERNAL "Do not disable curl crypto auth")
@@ -23,18 +24,26 @@
 set(CURL_DISABLE_TELNET ON CACHE INTERNAL "Disable curl telnet protocol?")
 set(CURL_DISABLE_TFTP ON CACHE INTERNAL "Disable curl tftp protocol?")
 set(CURL_DISABLE_VERBOSE_STRINGS OFF CACHE INTERNAL "Do not disable curl verbosity")
+set(CURL_ENABLE_MQTT OFF)
 set(CURL_HIDDEN_SYMBOLS OFF CACHE INTERNAL "No curl hidden symbols")
+set(CURL_LTO OFF CACHE INTERNAL "Turn on compiler Link Time Optimizations")
+set(CURL_STATIC_CRT OFF CACHE INTERNAL "Set to ON to build libcurl with static CRT on Windows (/MT).")
 set(CURL_WERROR OFF CACHE INTERNAL "Turn compiler warnings into errors")
 set(DISABLED_THREADSAFE OFF CACHE INTERNAL "Curl can use thread-safe functions")
 set(ENABLE_ARES OFF CACHE INTERNAL "No curl c-ares support")
+set(ENABLE_ALT_SVC OFF)
 set(ENABLE_CURLDEBUG OFF CACHE INTERNAL "No curl TrackMemory features")
 set(ENABLE_DEBUG OFF CACHE INTERNAL "No curl debug features")
+set(ENABLE_INET_PTON OFF CACHE INTERNAL "Set to OFF to prevent usage of inet_pton when building against modern SDKs while still requiring compatibility with older Windows versions, such as Windows XP, Windows Server 2003 etc.")
 set(ENABLE_IPV6 ON CACHE INTERNAL "Enable curl IPv6 support detection")
 set(ENABLE_MANUAL OFF CACHE INTERNAL "No curl built-in manual")
 set(ENABLE_THREADED_RESOLVER OFF CACHE INTERNAL "No curl POSIX threaded DNS lookup")
 set(ENABLE_UNIX_SOCKETS OFF CACHE INTERNAL "No curl Unix domain sockets support")
 set(HTTP_ONLY OFF CACHE INTERNAL "Curl is not http-only")
 set(PICKY_COMPILER OFF CACHE INTERNAL "Enable picky compiler options")
+set(USE_NGHTTP2 ON)
+set(USE_NGTCP2 OFF)
+set(USE_QUICHE OFF)
 set(USE_WIN32_LDAP OFF CACHE INTERNAL "No curl Windows LDAP")
 if(CMAKE_USE_OPENSSL)
 elseif(WIN32)
@@ -60,6 +69,9 @@
   unset(CMAKE_USE_DARWINSSL CACHE)
 endif()
 set(CMAKE_USE_MBEDTLS OFF CACHE INTERNAL "Enable mbedTLS for SSL/TLS")
+set(CMAKE_USE_BEARSSL OFF CACHE INTERNAL "Enable BearSSL for SSL/TLS")
+set(CMAKE_USE_NSS OFF CACHE INTERNAL "Enable NSS for SSL/TLS")
+set(CMAKE_USE_WOLFSSL OFF)
 
 # Windows Vista and above have inet_pton, but this will link on
 # older versions and then the executable will fail to launch at
@@ -91,7 +103,7 @@
 #                            | (__| |_| |  _ <| |___
 #                             \___|\___/|_| \_\_____|
 #
-# Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+# Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
 #
 # This software is licensed as described in the file COPYING, which
 # you should have received as part of this distribution. The terms
@@ -112,7 +124,6 @@
 # The output .so file lacks the soname number which we currently have within the lib/Makefile.am file
 # Add full (4 or 5 libs) SSL support
 # Add INSTALL target (EXTRA_DIST variables in Makefile.am may be moved to Makefile.inc so that CMake/CPack is aware of what's to include).
-# Add CTests(?)
 # Check on all possible platforms
 # Test with as many configurations possible (With or without any option)
 # Create scripts that help keeping the CMake build system up to date (to reduce maintenance). According to Tetetest:
@@ -136,7 +147,7 @@
 message(WARNING "the curl cmake build system is poorly maintained. Be aware")
 endif()
 
-file(READ ${CURL_SOURCE_DIR}/include/curl/curlver.h CURL_VERSION_H_CONTENTS)
+file(STRINGS ${CURL_SOURCE_DIR}/include/curl/curlver.h CURL_VERSION_H_CONTENTS REGEX "#define LIBCURL_VERSION( |_NUM )")
 string(REGEX MATCH "#define LIBCURL_VERSION \"[^\"]*"
   CURL_VERSION ${CURL_VERSION_H_CONTENTS})
 string(REGEX REPLACE "[^\"]+\"" "" CURL_VERSION ${CURL_VERSION})
@@ -168,7 +179,20 @@
 if(WIN32)
   option(CURL_STATIC_CRT "Set to ON to build libcurl with static CRT on Windows (/MT)." OFF)
   option(ENABLE_INET_PTON "Set to OFF to prevent usage of inet_pton when building against modern SDKs while still requiring compatibility with older Windows versions, such as Windows XP, Windows Server 2003 etc." ON)
+  if(0) # This code not needed for building within CMake.
+  set(CURL_TARGET_WINDOWS_VERSION "" CACHE STRING "Minimum target Windows version as hex string")
+  if(CURL_TARGET_WINDOWS_VERSION)
+    add_definitions(-D_WIN32_WINNT=${CURL_TARGET_WINDOWS_VERSION})
+  elseif(ENABLE_INET_PTON)
+    # _WIN32_WINNT_VISTA (0x0600)
+    add_definitions(-D_WIN32_WINNT=0x0600)
+  else()
+    # _WIN32_WINNT_WINXP (0x0501)
+    add_definitions(-D_WIN32_WINNT=0x0501)
+  endif()
+  endif()
 endif()
+option(CURL_LTO "Turn on compiler Link Time Optimizations" OFF)
 
 if(0) # This code not needed for building within CMake.
 cmake_dependent_option(ENABLE_THREADED_RESOLVER "Set to ON to enable threaded DNS lookup"
@@ -184,8 +208,9 @@
     foreach(_CCOPT -pedantic -Wall -W -Wpointer-arith -Wwrite-strings -Wunused -Wshadow -Winline -Wnested-externs -Wmissing-declarations -Wmissing-prototypes -Wno-long-long -Wfloat-equal -Wno-multichar -Wsign-compare -Wundef -Wno-format-nonliteral -Wendif-labels -Wstrict-prototypes -Wdeclaration-after-statement -Wstrict-aliasing=3 -Wcast-align -Wtype-limits -Wold-style-declaration -Wmissing-parameter-type -Wempty-body -Wclobbered -Wignored-qualifiers -Wconversion -Wno-sign-conversion -Wvla -Wdouble-promotion -Wno-system-headers -Wno-pedantic-ms-format)
       # surprisingly, CHECK_C_COMPILER_FLAG needs a new variable to store each new
       # test result in.
-      check_c_compiler_flag(${_CCOPT} OPT${_CCOPT})
-      if(OPT${_CCOPT})
+      string(MAKE_C_IDENTIFIER "OPT${_CCOPT}" _optvarname)
+      check_c_compiler_flag(${_CCOPT} ${_optvarname})
+      if(${_optvarname})
         set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${_CCOPT}")
       endif()
     endforeach()
@@ -216,7 +241,6 @@
   set(USE_ARES 1)
   find_package(CARES REQUIRED)
   list(APPEND CURL_LIBS ${CARES_LIBRARY})
-  set(CURL_LIBS ${CURL_LIBS} ${CARES_LIBRARY})
 endif()
 
 if(0) # This code not needed for building within CMake.
@@ -255,6 +279,8 @@
 mark_as_advanced(CURL_DISABLE_SMTP)
 option(CURL_DISABLE_GOPHER "to disable Gopher" OFF)
 mark_as_advanced(CURL_DISABLE_GOPHER)
+option(CURL_ENABLE_MQTT "to enable MQTT" OFF)
+mark_as_advanced(CURL_ENABLE_MQTT)
 
 if(HTTP_ONLY)
   set(CURL_DISABLE_FTP ON)
@@ -267,6 +293,7 @@
   set(CURL_DISABLE_RTSP ON)
   set(CURL_DISABLE_POP3 ON)
   set(CURL_DISABLE_IMAP ON)
+  set(CURL_DISABLE_SMB ON)
   set(CURL_DISABLE_SMTP ON)
   set(CURL_DISABLE_GOPHER ON)
 endif()
@@ -303,10 +330,6 @@
     ON "NROFF_USEFUL;PERL_FOUND"
     OFF)
 
-if(NOT PERL_FOUND)
-  message(STATUS "Perl not found, testing disabled.")
-  set(BUILD_TESTING OFF)
-endif()
 if(ENABLE_MANUAL)
   set(USE_MANUAL ON)
 endif()
@@ -317,6 +340,7 @@
 set(CMAKE_REQUIRED_FLAGS ${CMAKE_ANSI_CFLAGS})
 
 if(CURL_STATIC_CRT)
+  set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
   set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} /MT")
   set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} /MTd")
 endif()
@@ -332,6 +356,7 @@
 endif()
 
 # Include all the necessary files for macros
+include(CMakePushCheckState)
 include(CheckFunctionExists)
 include(CheckIncludeFile)
 include(CheckIncludeFiles)
@@ -359,7 +384,7 @@
 
 # Check for all needed libraries
 if(0) # This code not needed for building within CMake.
-check_library_exists_concat("dl"     dlopen       HAVE_LIBDL)
+check_library_exists_concat("${CMAKE_DL_LIBS}" dlopen HAVE_LIBDL)
 else()
   # Use the cmake-defined dl libs as dl is should not be used
   # on HPUX, but rather dld this avoids a warning
@@ -390,7 +415,7 @@
 endif()
 
 # check SSL libraries
-# TODO support GNUTLS, NSS, POLARSSL, CYASSL
+# TODO support GnuTLS
 
 if(APPLE)
   option(CMAKE_USE_SECTRANSP "enable Apple OS native SSL/TLS" OFF)
@@ -401,9 +426,12 @@
     CMAKE_USE_WINSSL OFF)
 endif()
 option(CMAKE_USE_MBEDTLS "Enable mbedTLS for SSL/TLS" OFF)
+option(CMAKE_USE_BEARSSL "Enable BearSSL for SSL/TLS" OFF)
+option(CMAKE_USE_NSS "Enable NSS for SSL/TLS" OFF)
+option(CMAKE_USE_WOLFSSL "enable wolfSSL for SSL/TLS" OFF)
 
 set(openssl_default ON)
-if(WIN32 OR CMAKE_USE_SECTRANSP OR CMAKE_USE_WINSSL OR CMAKE_USE_MBEDTLS)
+if(WIN32 OR CMAKE_USE_SECTRANSP OR CMAKE_USE_WINSSL OR CMAKE_USE_MBEDTLS OR CMAKE_USE_NSS OR CMAKE_USE_WOLFSSL)
   set(openssl_default OFF)
 endif()
 
@@ -412,6 +440,9 @@
   CMAKE_USE_SECTRANSP
   CMAKE_USE_OPENSSL
   CMAKE_USE_MBEDTLS
+  CMAKE_USE_BEARSSL
+  CMAKE_USE_NSS
+  CMAKE_USE_WOLFSSL
 )
 if(enabled_ssl_options_count GREATER "1")
   set(CURL_WITH_MULTI_SSL ON)
@@ -457,8 +488,6 @@
   endif()
   set(SSL_ENABLED ON)
   set(USE_OPENSSL ON)
-  set(HAVE_LIBCRYPTO ON)
-  set(HAVE_LIBSSL ON)
   list(APPEND CURL_LIBS ${OPENSSL_LIBRARIES})
   include_directories(${OPENSSL_INCLUDE_DIR})
 
@@ -492,6 +521,35 @@
   include_directories(${MBEDTLS_INCLUDE_DIRS})
 endif()
 
+if(CMAKE_USE_BEARSSL)
+  find_package(BearSSL REQUIRED)
+  set(SSL_ENABLED ON)
+  set(USE_BEARSSL ON)
+  list(APPEND CURL_LIBS ${BEARSSL_LIBRARY})
+  include_directories(${BEARSSL_INCLUDE_DIRS})
+endif()
+
+if(CMAKE_USE_WOLFSSL)
+  find_package(WolfSSL REQUIRED)
+  set(SSL_ENABLED ON)
+  set(USE_WOLFSSL ON)
+  list(APPEND CURL_LIBS ${WolfSSL_LIBRARIES})
+  include_directories(${WolfSSL_INCLUDE_DIRS})
+endif()
+
+if(CMAKE_USE_NSS)
+  find_package(NSS REQUIRED)
+  include_directories(${NSS_INCLUDE_DIRS})
+  list(APPEND CURL_LIBS ${NSS_LIBRARIES})
+  set(SSL_ENABLED ON)
+  set(USE_NSS ON)
+  cmake_push_check_state()
+  set(CMAKE_REQUIRED_INCLUDES ${NSS_INCLUDE_DIRS})
+  set(CMAKE_REQUIRED_LIBRARIES ${NSS_LIBRARIES})
+  check_symbol_exists(PK11_CreateManagedGenericObject "pk11pub.h" HAVE_PK11_CREATEMANAGEDGENERICOBJECT)
+  cmake_pop_check_state()
+endif()
+
 option(USE_NGHTTP2 "Use Nghttp2 library" OFF)
 if(USE_NGHTTP2)
   find_package(NGHTTP2 REQUIRED)
@@ -499,6 +557,60 @@
   list(APPEND CURL_LIBS ${NGHTTP2_LIBRARIES})
 endif()
 
+function(CheckQuicSupportInOpenSSL)
+  # Be sure that the OpenSSL library actually supports QUIC.
+  cmake_push_check_state()
+  set(CMAKE_REQUIRED_INCLUDES   "${OPENSSL_INCLUDE_DIR}")
+  set(CMAKE_REQUIRED_LIBRARIES  "${OPENSSL_LIBRARIES}")
+  check_symbol_exists(SSL_CTX_set_quic_method "openssl/ssl.h" HAVE_SSL_CTX_SET_QUIC_METHOD)
+  if(NOT HAVE_SSL_CTX_SET_QUIC_METHOD)
+    message(FATAL_ERROR "QUIC support is missing in OpenSSL/boringssl. Try setting -DOPENSSL_ROOT_DIR")
+  endif()
+  cmake_pop_check_state()
+endfunction()
+
+option(USE_NGTCP2 "Use ngtcp2 and nghttp3 libraries for HTTP/3 support" OFF)
+if(USE_NGTCP2)
+  if(USE_OPENSSL)
+    find_package(NGTCP2 REQUIRED OpenSSL)
+    CheckQuicSupportInOpenSSL()
+  elseif(USE_GNUTLS)
+    # TODO add GnuTLS support as vtls library.
+    find_package(NGTCP2 REQUIRED GnuTLS)
+  else()
+    message(FATAL_ERROR "ngtcp2 requires OpenSSL or GnuTLS")
+  endif()
+  set(USE_NGTCP2 ON)
+  include_directories(${NGTCP2_INCLUDE_DIRS})
+  list(APPEND CURL_LIBS ${NGTCP2_LIBRARIES})
+
+  find_package(NGHTTP3 REQUIRED)
+  set(USE_NGHTTP3 ON)
+  include_directories(${NGHTTP3_INCLUDE_DIRS})
+  list(APPEND CURL_LIBS ${NGHTTP3_LIBRARIES})
+endif()
+
+option(USE_QUICHE "Use quiche library for HTTP/3 support" OFF)
+if(USE_QUICHE)
+  if(USE_NGTCP2)
+    message(FATAL_ERROR "Only one HTTP/3 backend can be selected!")
+  endif()
+  find_package(QUICHE REQUIRED)
+  CheckQuicSupportInOpenSSL()
+  set(USE_QUICHE ON)
+  include_directories(${QUICHE_INCLUDE_DIRS})
+  list(APPEND CURL_LIBS ${QUICHE_LIBRARIES})
+  cmake_push_check_state()
+  set(CMAKE_REQUIRED_INCLUDES   "${QUICHE_INCLUDE_DIRS}")
+  set(CMAKE_REQUIRED_LIBRARIES  "${QUICHE_LIBRARIES}")
+  check_symbol_exists(quiche_conn_set_qlog_fd "quiche.h" HAVE_QUICHE_CONN_SET_QLOG_FD)
+  cmake_pop_check_state()
+endif()
+
+if(WIN32)
+  set(USE_WIN32_CRYPTO ON)
+endif()
+
 if(NOT CURL_DISABLE_LDAP)
   if(WIN32)
     option(USE_WIN32_LDAP "Use Windows LDAP implementation" ON)
@@ -653,7 +765,7 @@
 option(CURL_BROTLI "Set to ON to enable building curl with brotli support." OFF)
 set(HAVE_BROTLI OFF)
 if(CURL_BROTLI)
-  find_package(BROTLI QUIET)
+  find_package(Brotli QUIET)
   if(BROTLI_FOUND)
     set(HAVE_BROTLI ON)
     list(APPEND CURL_LIBS ${BROTLI_LIBRARIES})
@@ -696,6 +808,20 @@
   endif()
 endif()
 
+# libssh
+option(CMAKE_USE_LIBSSH "Use libSSH" OFF)
+mark_as_advanced(CMAKE_USE_LIBSSH)
+if(NOT HAVE_LIBSSH2 AND CMAKE_USE_LIBSSH)
+  find_package(libssh CONFIG)
+  if(libssh_FOUND)
+    message(STATUS "Found libssh ${libssh_VERSION}")
+    # Use imported target for include and library paths.
+    list(APPEND CURL_LIBS ssh)
+    set(USE_LIBSSH ON)
+    set(HAVE_LIBSSH_LIBSSH_H 1)
+  endif()
+endif()
+
 option(CMAKE_USE_GSSAPI "Use GSSAPI implementation (right now only Heimdal is supported with CMake build)" OFF)
 mark_as_advanced(CMAKE_USE_GSSAPI)
 
@@ -764,6 +890,8 @@
   unset(USE_UNIX_SOCKETS CACHE)
 endif()
 
+option(ENABLE_ALT_SVC "Enable alt-svc support" OFF)
+set(USE_ALTSVC ${ENABLE_ALT_SVC})
 
 if(0) # This code not needed for building within CMake.
 #
@@ -793,7 +921,9 @@
   unset(CURL_CA_PATH CACHE)
 elseif("${CURL_CA_PATH}" STREQUAL "auto")
   unset(CURL_CA_PATH CACHE)
-  set(CURL_CA_PATH_AUTODETECT TRUE)
+  if(NOT USE_NSS)
+    set(CURL_CA_PATH_AUTODETECT TRUE)
+  endif()
 else()
   set(CURL_CA_PATH_SET TRUE)
 endif()
@@ -832,7 +962,7 @@
 endif()
 
 if(CURL_CA_PATH_SET AND NOT USE_OPENSSL AND NOT USE_MBEDTLS)
-  message(FATAL_ERROR
+  message(STATUS
           "CA path only supported by OpenSSL, GnuTLS or mbed TLS. "
           "Set CURL_CA_PATH=none or enable one of those TLS backends.")
 endif()
@@ -876,7 +1006,6 @@
 check_include_file_concat("arpa/tftp.h"      HAVE_ARPA_TFTP_H)
 check_include_file_concat("assert.h"         HAVE_ASSERT_H)
 check_include_file_concat("crypto.h"         HAVE_CRYPTO_H)
-check_include_file_concat("des.h"            HAVE_DES_H)
 check_include_file_concat("err.h"            HAVE_ERR_H)
 check_include_file_concat("errno.h"          HAVE_ERRNO_H)
 check_include_file_concat("fcntl.h"          HAVE_FCNTL_H)
@@ -925,18 +1054,8 @@
 
 check_type_size(size_t  SIZEOF_SIZE_T)
 check_type_size(ssize_t  SIZEOF_SSIZE_T)
-check_type_size("long long"  SIZEOF_LONG_LONG)
-check_type_size("long"  SIZEOF_LONG)
-check_type_size("short"  SIZEOF_SHORT)
-check_type_size("int"  SIZEOF_INT)
-check_type_size("__int64"  SIZEOF___INT64)
 check_type_size("time_t"  SIZEOF_TIME_T)
 
-if(HAVE_SIZEOF_LONG_LONG)
-  set(HAVE_LONGLONG 1)
-  set(HAVE_LL 1)
-endif()
-
 find_file(RANDOM_FILE urandom /dev)
 mark_as_advanced(RANDOM_FILE)
 
@@ -983,6 +1102,7 @@
 check_symbol_exists(getpwuid      "${CURL_INCLUDES}" HAVE_GETPWUID)
 check_symbol_exists(getpwuid_r    "${CURL_INCLUDES}" HAVE_GETPWUID_R)
 check_symbol_exists(geteuid       "${CURL_INCLUDES}" HAVE_GETEUID)
+check_symbol_exists(usleep        "${CURL_INCLUDES}" HAVE_USLEEP)
 check_symbol_exists(utime         "${CURL_INCLUDES}" HAVE_UTIME)
 check_symbol_exists(gmtime_r      "${CURL_INCLUDES}" HAVE_GMTIME_R)
 check_symbol_exists(localtime_r   "${CURL_INCLUDES}" HAVE_LOCALTIME_R)
@@ -1010,6 +1130,7 @@
 check_symbol_exists(getprotobyname "${CURL_INCLUDES}" HAVE_GETPROTOBYNAME)
 check_symbol_exists(getpeername    "${CURL_INCLUDES}" HAVE_GETPEERNAME)
 check_symbol_exists(getsockname    "${CURL_INCLUDES}" HAVE_GETSOCKNAME)
+check_symbol_exists(if_nametoindex "${CURL_INCLUDES}" HAVE_IF_NAMETOINDEX)
 check_symbol_exists(getrlimit      "${CURL_INCLUDES}" HAVE_GETRLIMIT)
 check_symbol_exists(setlocale      "${CURL_INCLUDES}" HAVE_SETLOCALE)
 check_symbol_exists(setmode        "${CURL_INCLUDES}" HAVE_SETMODE)
@@ -1018,20 +1139,7 @@
 check_symbol_exists(ioctl          "${CURL_INCLUDES}" HAVE_IOCTL)
 check_symbol_exists(setsockopt     "${CURL_INCLUDES}" HAVE_SETSOCKOPT)
 check_function_exists(mach_absolute_time HAVE_MACH_ABSOLUTE_TIME)
-
-# symbol exists in win32, but function does not.
-if(WIN32)
-  if(ENABLE_INET_PTON)
-    check_function_exists(inet_pton HAVE_INET_PTON)
-    # _WIN32_WINNT_VISTA (0x0600)
-    add_definitions(-D_WIN32_WINNT=0x0600)
-  else()
-    # _WIN32_WINNT_WINXP (0x0501)
-    add_definitions(-D_WIN32_WINNT=0x0501)
-  endif()
-else()
-  check_function_exists(inet_pton HAVE_INET_PTON)
-endif()
+check_symbol_exists(inet_pton      "${CURL_INCLUDES}" HAVE_INET_PTON)
 
 check_symbol_exists(fsetxattr "${CURL_INCLUDES}" HAVE_FSETXATTR)
 if(HAVE_FSETXATTR)
@@ -1255,6 +1363,23 @@
   endif()
 endif()
 
+if(CURL_LTO)
+  if(CMAKE_VERSION VERSION_LESS 3.9)
+    message(FATAL_ERROR "Requested LTO but your cmake version ${CMAKE_VERSION} is to old. You need at least 3.9")
+  endif()
+
+  cmake_policy(SET CMP0069 NEW)
+
+  include(CheckIPOSupported)
+  check_ipo_supported(RESULT CURL_HAS_LTO OUTPUT CURL_LTO_ERROR LANGUAGES C)
+  if(CURL_HAS_LTO)
+    message(STATUS "LTO supported and enabled")
+  else()
+    message(FATAL_ERROR "LTO was requested - but compiler doesn't support it\n${CURL_LTO_ERROR}")
+  endif()
+endif()
+
+
 # Ugly (but functional) way to include "Makefile.inc" by transforming it (= regenerate it).
 function(transform_makefile_inc INPUT_FILE OUTPUT_FILE)
   file(READ ${INPUT_FILE} MAKEFILE_INC_TEXT)
@@ -1268,7 +1393,7 @@
   string(REGEX REPLACE "\\$\\(([a-zA-Z_][a-zA-Z0-9_]*)\\)" "\${\\1}" MAKEFILE_INC_TEXT ${MAKEFILE_INC_TEXT})    # Replace $() with ${}
   string(REGEX REPLACE "@([a-zA-Z_][a-zA-Z0-9_]*)@" "\${\\1}" MAKEFILE_INC_TEXT ${MAKEFILE_INC_TEXT})    # Replace @@ with ${}, even if that may not be read by CMake scripts.
   file(WRITE ${OUTPUT_FILE} ${MAKEFILE_INC_TEXT})
-
+  set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS "${INPUT_FILE}")
 endfunction()
 
 if(0) # This code not needed for building within CMake.
@@ -1304,19 +1429,29 @@
 #-----------------------------------------------------------------------------
 
 if(0) # This code not needed for building within CMake.
-include(CTest)
-if(BUILD_TESTING)
+option(BUILD_TESTING "Build tests" "${PERL_FOUND}")
+if(NOT PERL_FOUND)
+  message(STATUS "Perl not found, testing disabled.")
+elseif(BUILD_TESTING)
   add_subdirectory(tests)
 endif()
 
+# NTLM support requires crypto function adaptions from various SSL libs
+# TODO alternative SSL libs tests for SSP1, GNUTLS, NSS
+if(NOT CURL_DISABLE_CRYPTO_AUTH AND (USE_OPENSSL OR USE_WINDOWS_SSPI OR USE_DARWINSSL OR USE_MBEDTLS OR USE_WIN32_CRYPTO))
+  set(use_ntlm ON)
+else()
+  set(use_ntlm OFF)
+endif()
+
 # Helper to populate a list (_items) with a label when conditions (the remaining
 # args) are satisfied
-function(_add_if label)
-  # TODO need to disable policy CMP0054 (CMake 3.1) to allow this indirection
+macro(_add_if label)
+  # needs to be a macro to allow this indirection
   if(${ARGN})
-    set(_items ${_items} "${label}" PARENT_SCOPE)
+    set(_items ${_items} "${label}")
   endif()
-endfunction()
+endmacro()
 
 # Clear list and try to detect available features
 set(_items)
@@ -1331,6 +1466,7 @@
 # TODO SSP1 (WinSSL) check is missing
 _add_if("SSPI"          USE_WINDOWS_SSPI)
 _add_if("GSS-API"       HAVE_GSSAPI)
+_add_if("alt-svc"       ENABLE_ALT_SVC)
 # TODO SSP1 missing for SPNEGO
 _add_if("SPNEGO"        NOT CURL_DISABLE_CRYPTO_AUTH AND
                         (HAVE_GSSAPI OR USE_WINDOWS_SSPI))
@@ -1338,15 +1474,16 @@
                         (HAVE_GSSAPI OR USE_WINDOWS_SSPI))
 # NTLM support requires crypto function adaptions from various SSL libs
 # TODO alternative SSL libs tests for SSP1, GNUTLS, NSS
-if(NOT CURL_DISABLE_CRYPTO_AUTH AND (USE_OPENSSL OR USE_WINDOWS_SSPI OR USE_SECTRANSP OR USE_MBEDTLS))
-  _add_if("NTLM"        1)
-  # TODO missing option (autoconf: --enable-ntlm-wb)
-  _add_if("NTLM_WB"     NOT CURL_DISABLE_HTTP AND NTLM_WB_ENABLED)
-endif()
+_add_if("NTLM"        use_ntlm)
+# TODO missing option (autoconf: --enable-ntlm-wb)
+_add_if("NTLM_WB"     use_ntlm AND NOT CURL_DISABLE_HTTP AND NTLM_WB_ENABLED)
 # TODO missing option (--enable-tls-srp), depends on GNUTLS_SRP/OPENSSL_SRP
 _add_if("TLS-SRP"       USE_TLS_SRP)
 # TODO option --with-nghttp2 tests for nghttp2 lib and nghttp2/nghttp2.h header
 _add_if("HTTP2"         USE_NGHTTP2)
+_add_if("HTTP3"         USE_NGTCP2 OR USE_QUICHE)
+_add_if("MultiSSL"      CURL_WITH_MULTI_SSL)
+_add_if("HTTPS-proxy"   SSL_ENABLED AND (USE_OPENSSL OR USE_GNUTLS OR USE_NSS))
 string(REPLACE ";" " " SUPPORT_FEATURES "${_items}")
 message(STATUS "Enabled features: ${SUPPORT_FEATURES}")
 
@@ -1371,12 +1508,15 @@
 _add_if("POP3S"         NOT CURL_DISABLE_POP3 AND SSL_ENABLED)
 _add_if("IMAP"          NOT CURL_DISABLE_IMAP)
 _add_if("IMAPS"         NOT CURL_DISABLE_IMAP AND SSL_ENABLED)
+_add_if("SMB"           NOT CURL_DISABLE_SMB AND use_ntlm)
+_add_if("SMBS"          NOT CURL_DISABLE_SMB AND SSL_ENABLED AND use_ntlm)
 _add_if("SMTP"          NOT CURL_DISABLE_SMTP)
 _add_if("SMTPS"         NOT CURL_DISABLE_SMTP AND SSL_ENABLED)
-_add_if("SCP"           USE_LIBSSH2)
-_add_if("SFTP"          USE_LIBSSH2)
+_add_if("SCP"           USE_LIBSSH2 OR USE_LIBSSH)
+_add_if("SFTP"          USE_LIBSSH2 OR USE_LIBSSH)
 _add_if("RTSP"          NOT CURL_DISABLE_RTSP)
 _add_if("RTMP"          USE_LIBRTMP)
+_add_if("MQTT"          CURL_ENABLE_MQTT)
 if(_items)
   list(SORT _items)
 endif()
@@ -1389,6 +1529,9 @@
 _add_if("OpenSSL"          SSL_ENABLED AND USE_OPENSSL)
 _add_if("Secure Transport" SSL_ENABLED AND USE_SECTRANSP)
 _add_if("mbedTLS"          SSL_ENABLED AND USE_MBEDTLS)
+_add_if("BearSSL"          SSL_ENABLED AND USE_BEARSSL)
+_add_if("NSS"              SSL_ENABLED AND USE_NSS)
+_add_if("wolfSSL"          SSL_ENABLED AND USE_WOLFSSL)
 if(_items)
   list(SORT _items)
 endif()
@@ -1402,25 +1545,43 @@
 # TODO when to set "-DCURL_STATICLIB" for CPPFLAG_CURL_STATICLIB?
 set(CPPFLAG_CURL_STATICLIB  "")
 set(CURLVERSION             "${CURL_VERSION}")
-if(BUILD_SHARED_LIBS)
-  set(ENABLE_SHARED         "yes")
-  set(ENABLE_STATIC         "no")
-else()
-  set(ENABLE_SHARED         "no")
-  set(ENABLE_STATIC         "yes")
-endif()
 set(exec_prefix             "\${prefix}")
 set(includedir              "\${prefix}/include")
 set(LDFLAGS                 "${CMAKE_SHARED_LINKER_FLAGS}")
 set(LIBCURL_LIBS            "")
 set(libdir                  "${CMAKE_INSTALL_PREFIX}/lib")
 foreach(_lib ${CMAKE_C_IMPLICIT_LINK_LIBRARIES} ${CURL_LIBS})
+  if(TARGET "${_lib}")
+    set(_libname "${_lib}")
+    get_target_property(_libtype "${_libname}" TYPE)
+    if(_libtype STREQUAL INTERFACE_LIBRARY)
+      # Interface libraries can occur when an external project embeds curl and
+      # defined targets such as ZLIB::ZLIB by themselves. Ignore these as
+      # reading the LOCATION property will error out. Assume the user won't need
+      # this information in the .pc file.
+      continue()
+    endif()
+    get_target_property(_lib "${_libname}" LOCATION)
+    if(NOT _lib)
+      message(WARNING "Bad lib in library list: ${_libname}")
+      continue()
+    endif()
+  endif()
   if(_lib MATCHES ".*/.*" OR _lib MATCHES "^-")
     set(LIBCURL_LIBS          "${LIBCURL_LIBS} ${_lib}")
   else()
     set(LIBCURL_LIBS          "${LIBCURL_LIBS} -l${_lib}")
   endif()
 endforeach()
+if(BUILD_SHARED_LIBS)
+  set(ENABLE_SHARED         "yes")
+  set(ENABLE_STATIC         "no")
+  set(LIBCURL_NO_SHARED     "")
+else()
+  set(ENABLE_SHARED         "no")
+  set(ENABLE_STATIC         "yes")
+  set(LIBCURL_NO_SHARED     "${LIBCURL_LIBS}")
+endif()
 # "a" (Linux) or "lib" (Windows)
 string(REPLACE "." "" libext "${CMAKE_STATIC_LIBRARY_SUFFIX}")
 set(prefix                  "${CMAKE_INSTALL_PREFIX}")
diff --git a/Utilities/cmcurl/COPYING b/Utilities/cmcurl/COPYING
index 3528bd7..9d9e4af 100644
--- a/Utilities/cmcurl/COPYING
+++ b/Utilities/cmcurl/COPYING
@@ -1,6 +1,6 @@
 COPYRIGHT AND PERMISSION NOTICE
 
-Copyright (c) 1996 - 2019, Daniel Stenberg, <daniel@haxx.se>, and many
+Copyright (c) 1996 - 2020, Daniel Stenberg, <daniel@haxx.se>, and many
 contributors, see the THANKS file.
 
 All rights reserved.
diff --git a/Utilities/cmcurl/include/curl/curl.h b/Utilities/cmcurl/include/curl/curl.h
index 089c427..194b578 100644
--- a/Utilities/cmcurl/include/curl/curl.h
+++ b/Utilities/cmcurl/include/curl/curl.h
@@ -1,5 +1,5 @@
-#ifndef __CURL_CURL_H
-#define __CURL_CURL_H
+#ifndef CURLINC_CURL_H
+#define CURLINC_CURL_H
 /***************************************************************************
  *                                  _   _ ____  _
  *  Project                     ___| | | |  _ \| |
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -38,12 +38,12 @@
 #include "system.h"          /* determine things run-time */
 
 /*
- * Define WIN32 when build target is Win32 API
+ * Define CURL_WIN32 when build target is Win32 API
  */
 
-#if (defined(_WIN32) || defined(__WIN32__)) && \
-     !defined(WIN32) && !defined(__SYMBIAN32__)
-#define WIN32
+#if (defined(_WIN32) || defined(__WIN32__) || defined(WIN32)) &&        \
+  !defined(__SYMBIAN32__)
+#define CURL_WIN32
 #endif
 
 #include <stdio.h>
@@ -58,7 +58,7 @@
 #include <sys/types.h>
 #include <time.h>
 
-#if defined(WIN32) && !defined(_WIN32_WCE) && !defined(__CYGWIN__)
+#if defined(CURL_WIN32) && !defined(_WIN32_WCE) && !defined(__CYGWIN__)
 #if !(defined(_WINSOCKAPI_) || defined(_WINSOCK_H) || \
       defined(__LWIP_OPT_H__) || defined(LWIP_HDR_OPT_H))
 /* The check above prevents the winsock2 inclusion if winsock.h already was
@@ -79,11 +79,11 @@
 #include <sys/select.h>
 #endif
 
-#if !defined(WIN32) && !defined(_WIN32_WCE)
+#if !defined(CURL_WIN32) && !defined(_WIN32_WCE)
 #include <sys/socket.h>
 #endif
 
-#if !defined(WIN32) && !defined(__WATCOMC__) && !defined(__VXWORKS__)
+#if !defined(CURL_WIN32) && !defined(__WATCOMC__) && !defined(__VXWORKS__)
 #include <sys/time.h>
 #endif
 
@@ -114,7 +114,7 @@
 
 #ifdef CURL_STATICLIB
 #  define CURL_EXTERN
-#elif defined(WIN32) || defined(__SYMBIAN32__) || \
+#elif defined(CURL_WIN32) || defined(__SYMBIAN32__) || \
      (__has_declspec_attribute(dllexport) && \
       __has_declspec_attribute(dllimport))
 #  if defined(BUILDING_LIBCURL)
@@ -130,7 +130,7 @@
 
 #ifndef curl_socket_typedef
 /* socket typedef */
-#if defined(WIN32) && !defined(__LWIP_OPT_H__) && !defined(LWIP_HDR_OPT_H)
+#if defined(CURL_WIN32) && !defined(__LWIP_OPT_H__) && !defined(LWIP_HDR_OPT_H)
 typedef SOCKET curl_socket_t;
 #define CURL_SOCKET_BAD INVALID_SOCKET
 #else
@@ -154,7 +154,8 @@
   CURLSSLBACKEND_SECURETRANSPORT = 9,
   CURLSSLBACKEND_AXTLS = 10, /* never used since 7.63.0 */
   CURLSSLBACKEND_MBEDTLS = 11,
-  CURLSSLBACKEND_MESALINK = 12
+  CURLSSLBACKEND_MESALINK = 12,
+  CURLSSLBACKEND_BEARSSL = 13
 } curl_sslbackend;
 
 /* aliases for library clones and renames */
@@ -209,16 +210,22 @@
                                        set. Added in 7.46.0 */
 };
 
-/* This is the CURLOPT_PROGRESSFUNCTION callback proto. It is now considered
-   deprecated but was the only choice up until 7.31.0 */
+
+/* This is a return code for the progress callback that, when returned, will
+   signal libcurl to continue executing the default progress function */
+#define CURL_PROGRESSFUNC_CONTINUE 0x10000001
+
+/* This is the CURLOPT_PROGRESSFUNCTION callback prototype. It is now
+   considered deprecated but was the only choice up until 7.31.0 */
 typedef int (*curl_progress_callback)(void *clientp,
                                       double dltotal,
                                       double dlnow,
                                       double ultotal,
                                       double ulnow);
 
-/* This is the CURLOPT_XFERINFOFUNCTION callback proto. It was introduced in
-   7.32.0, it avoids floating point and provides more detailed information. */
+/* This is the CURLOPT_XFERINFOFUNCTION callback prototype. It was introduced
+   in 7.32.0, avoids the use of floating point numbers and provides more
+   detailed information. */
 typedef int (*curl_xferinfo_callback)(void *clientp,
                                       curl_off_t dltotal,
                                       curl_off_t dlnow,
@@ -283,10 +290,7 @@
 #define CURLFINFOFLAG_KNOWN_SIZE        (1<<6)
 #define CURLFINFOFLAG_KNOWN_HLINKCOUNT  (1<<7)
 
-/* Content of this structure depends on information which is known and is
-   achievable (e.g. by FTP LIST parsing). Please see the url_easy_setopt(3) man
-   page for callbacks returning this structure -- some fields are mandatory,
-   some others are optional. The FLAG field has special meaning. */
+/* Information about a single file, used when doing FTP wildcard matching */
 struct curl_fileinfo {
   char *filename;
   curlfiletype filetype;
@@ -602,6 +606,10 @@
                                     */
   CURLE_RECURSIVE_API_CALL,      /* 93 - an api function was called from
                                     inside a callback */
+  CURLE_AUTH_ERROR,              /* 94 - an authentication function returned an
+                                    error */
+  CURLE_HTTP3,                   /* 95 - An HTTP/3 layer problem */
+  CURLE_QUIC_CONNECT_ERROR,      /* 96 - QUIC connection error */
   CURL_LAST /* never use! */
 } CURLcode;
 
@@ -685,8 +693,10 @@
 typedef CURLcode (*curl_conv_callback)(char *buffer, size_t length);
 
 typedef CURLcode (*curl_ssl_ctx_callback)(CURL *curl,    /* easy handle */
-                                          void *ssl_ctx, /* actually an
-                                                            OpenSSL SSL_CTX */
+                                          void *ssl_ctx, /* actually an OpenSSL
+                                                            or WolfSSL SSL_CTX,
+                                                            or an mbedTLS
+                                                          mbedtls_ssl_config */
                                           void *userptr);
 
 typedef enum {
@@ -764,7 +774,7 @@
 };
 
 struct curl_khkey {
-  const char *key; /* points to a zero-terminated string encoded with base64
+  const char *key; /* points to a null-terminated string encoded with base64
                       if len is zero, otherwise to the "raw" data */
   size_t len;
   enum curl_khtype keytype;
@@ -819,6 +829,19 @@
    SSL backends where such behavior is present. */
 #define CURLSSLOPT_NO_REVOKE (1<<1)
 
+/* - NO_PARTIALCHAIN tells libcurl to *NOT* accept a partial certificate chain
+   if possible. The OpenSSL backend has this ability. */
+#define CURLSSLOPT_NO_PARTIALCHAIN (1<<2)
+
+/* - REVOKE_BEST_EFFORT tells libcurl to ignore certificate revocation offline
+   checks and ignore missing revocation list for those SSL backends where such
+   behavior is present. */
+#define CURLSSLOPT_REVOKE_BEST_EFFORT (1<<3)
+
+/* - CURLSSLOPT_NATIVE_CA tells libcurl to use standard certificate store of
+   operating system. Currently implemented under MS-Windows. */
+#define CURLSSLOPT_NATIVE_CA (1<<4)
+
 /* The default connection attempt delay in milliseconds for happy eyeballs.
    CURLOPT_HAPPY_EYEBALLS_TIMEOUT_MS.3 and happy-eyeballs-timeout-ms.d document
    this value, keep them in sync. */
@@ -883,7 +906,7 @@
 
 /* CURLALTSVC_* are bits for the CURLOPT_ALTSVC_CTRL option */
 #define CURLALTSVC_IMMEDIATELY  (1<<0)
-#define CURLALTSVC_ALTUSED      (1<<1)
+
 #define CURLALTSVC_READONLYFILE (1<<2)
 #define CURLALTSVC_H1           (1<<3)
 #define CURLALTSVC_H2           (1<<4)
@@ -918,85 +941,72 @@
 #define CURLPROTO_GOPHER (1<<25)
 #define CURLPROTO_SMB    (1<<26)
 #define CURLPROTO_SMBS   (1<<27)
+#define CURLPROTO_MQTT   (1<<28)
 #define CURLPROTO_ALL    (~0) /* enable everything */
 
 /* long may be 32 or 64 bits, but we should never depend on anything else
    but 32 */
 #define CURLOPTTYPE_LONG          0
 #define CURLOPTTYPE_OBJECTPOINT   10000
-#define CURLOPTTYPE_STRINGPOINT   10000
 #define CURLOPTTYPE_FUNCTIONPOINT 20000
 #define CURLOPTTYPE_OFF_T         30000
+#define CURLOPTTYPE_BLOB          40000
 
 /* *STRINGPOINT is an alias for OBJECTPOINT to allow tools to extract the
    string options from the header file */
 
-/* name is uppercase CURLOPT_<name>,
-   type is one of the defined CURLOPTTYPE_<type>
-   number is unique identifier */
-#ifdef CINIT
-#undef CINIT
-#endif
 
-#ifdef CURL_ISOCPP
-#define CINIT(na,t,nu) CURLOPT_ ## na = CURLOPTTYPE_ ## t + nu
-#else
-/* The macro "##" is ISO C, we assume pre-ISO C doesn't support it. */
-#define LONG          CURLOPTTYPE_LONG
-#define OBJECTPOINT   CURLOPTTYPE_OBJECTPOINT
-#define STRINGPOINT   CURLOPTTYPE_OBJECTPOINT
-#define FUNCTIONPOINT CURLOPTTYPE_FUNCTIONPOINT
-#define OFF_T         CURLOPTTYPE_OFF_T
-#define CINIT(name,type,number) CURLOPT_/**/name = type + number
-#endif
+#define CURLOPT(na,t,nu) na = t + nu
+
+/* handy aliases that make no run-time difference */
+#define CURLOPTTYPE_STRINGPOINT  CURLOPTTYPE_OBJECTPOINT
+#define CURLOPTTYPE_SLISTPOINT  CURLOPTTYPE_OBJECTPOINT
 
 /*
- * This macro-mania below setups the CURLOPT_[what] enum, to be used with
- * curl_easy_setopt(). The first argument in the CINIT() macro is the [what]
- * word.
+ * All CURLOPT_* values.
  */
 
 typedef enum {
   /* This is the FILE * or void * the regular output should be written to. */
-  CINIT(WRITEDATA, OBJECTPOINT, 1),
+  CURLOPT(CURLOPT_WRITEDATA, CURLOPTTYPE_OBJECTPOINT, 1),
 
   /* The full URL to get/put */
-  CINIT(URL, STRINGPOINT, 2),
+  CURLOPT(CURLOPT_URL, CURLOPTTYPE_STRINGPOINT, 2),
 
   /* Port number to connect to, if other than default. */
-  CINIT(PORT, LONG, 3),
+  CURLOPT(CURLOPT_PORT, CURLOPTTYPE_LONG, 3),
 
   /* Name of proxy to use. */
-  CINIT(PROXY, STRINGPOINT, 4),
+  CURLOPT(CURLOPT_PROXY, CURLOPTTYPE_STRINGPOINT, 4),
 
   /* "user:password;options" to use when fetching. */
-  CINIT(USERPWD, STRINGPOINT, 5),
+  CURLOPT(CURLOPT_USERPWD, CURLOPTTYPE_STRINGPOINT, 5),
 
   /* "user:password" to use with proxy. */
-  CINIT(PROXYUSERPWD, STRINGPOINT, 6),
+  CURLOPT(CURLOPT_PROXYUSERPWD, CURLOPTTYPE_STRINGPOINT, 6),
 
   /* Range to get, specified as an ASCII string. */
-  CINIT(RANGE, STRINGPOINT, 7),
+  CURLOPT(CURLOPT_RANGE, CURLOPTTYPE_STRINGPOINT, 7),
 
   /* not used */
 
   /* Specified file stream to upload from (use as input): */
-  CINIT(READDATA, OBJECTPOINT, 9),
+  CURLOPT(CURLOPT_READDATA, CURLOPTTYPE_OBJECTPOINT, 9),
 
   /* Buffer to receive error messages in, must be at least CURL_ERROR_SIZE
    * bytes big. */
-  CINIT(ERRORBUFFER, OBJECTPOINT, 10),
+  CURLOPT(CURLOPT_ERRORBUFFER, CURLOPTTYPE_OBJECTPOINT, 10),
 
   /* Function that will be called to store the output (instead of fwrite). The
    * parameters will use fwrite() syntax, make sure to follow them. */
-  CINIT(WRITEFUNCTION, FUNCTIONPOINT, 11),
+  CURLOPT(CURLOPT_WRITEFUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 11),
 
   /* Function that will be called to read the input (instead of fread). The
    * parameters will use fread() syntax, make sure to follow them. */
-  CINIT(READFUNCTION, FUNCTIONPOINT, 12),
+  CURLOPT(CURLOPT_READFUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 12),
 
   /* Time-out the read operation after this amount of seconds */
-  CINIT(TIMEOUT, LONG, 13),
+  CURLOPT(CURLOPT_TIMEOUT, CURLOPTTYPE_LONG, 13),
 
   /* If the CURLOPT_INFILE is used, this can be used to inform libcurl about
    * how large the file being sent really is. That allows better error
@@ -1007,20 +1017,20 @@
    * which takes an off_t type, allowing platforms with larger off_t
    * sizes to handle larger files.  See below for INFILESIZE_LARGE.
    */
-  CINIT(INFILESIZE, LONG, 14),
+  CURLOPT(CURLOPT_INFILESIZE, CURLOPTTYPE_LONG, 14),
 
   /* POST static input fields. */
-  CINIT(POSTFIELDS, OBJECTPOINT, 15),
+  CURLOPT(CURLOPT_POSTFIELDS, CURLOPTTYPE_OBJECTPOINT, 15),
 
   /* Set the referrer page (needed by some CGIs) */
-  CINIT(REFERER, STRINGPOINT, 16),
+  CURLOPT(CURLOPT_REFERER, CURLOPTTYPE_STRINGPOINT, 16),
 
   /* Set the FTP PORT string (interface name, named or numerical IP address)
      Use i.e '-' to use default address. */
-  CINIT(FTPPORT, STRINGPOINT, 17),
+  CURLOPT(CURLOPT_FTPPORT, CURLOPTTYPE_STRINGPOINT, 17),
 
   /* Set the User-Agent string (examined by some CGIs) */
-  CINIT(USERAGENT, STRINGPOINT, 18),
+  CURLOPT(CURLOPT_USERAGENT, CURLOPTTYPE_STRINGPOINT, 18),
 
   /* If the download receives less than "low speed limit" bytes/second
    * during "low speed time" seconds, the operations is aborted.
@@ -1029,10 +1039,10 @@
    */
 
   /* Set the "low speed limit" */
-  CINIT(LOW_SPEED_LIMIT, LONG, 19),
+  CURLOPT(CURLOPT_LOW_SPEED_LIMIT, CURLOPTTYPE_LONG, 19),
 
   /* Set the "low speed time" */
-  CINIT(LOW_SPEED_TIME, LONG, 20),
+  CURLOPT(CURLOPT_LOW_SPEED_TIME, CURLOPTTYPE_LONG, 20),
 
   /* Set the continuation offset.
    *
@@ -1040,48 +1050,48 @@
    * off_t types, allowing for large file offsets on platforms which
    * use larger-than-32-bit off_t's.  Look below for RESUME_FROM_LARGE.
    */
-  CINIT(RESUME_FROM, LONG, 21),
+  CURLOPT(CURLOPT_RESUME_FROM, CURLOPTTYPE_LONG, 21),
 
   /* Set cookie in request: */
-  CINIT(COOKIE, STRINGPOINT, 22),
+  CURLOPT(CURLOPT_COOKIE, CURLOPTTYPE_STRINGPOINT, 22),
 
   /* This points to a linked list of headers, struct curl_slist kind. This
      list is also used for RTSP (in spite of its name) */
-  CINIT(HTTPHEADER, OBJECTPOINT, 23),
+  CURLOPT(CURLOPT_HTTPHEADER, CURLOPTTYPE_SLISTPOINT, 23),
 
   /* This points to a linked list of post entries, struct curl_httppost */
-  CINIT(HTTPPOST, OBJECTPOINT, 24),
+  CURLOPT(CURLOPT_HTTPPOST, CURLOPTTYPE_OBJECTPOINT, 24),
 
   /* name of the file keeping your private SSL-certificate */
-  CINIT(SSLCERT, STRINGPOINT, 25),
+  CURLOPT(CURLOPT_SSLCERT, CURLOPTTYPE_STRINGPOINT, 25),
 
   /* password for the SSL or SSH private key */
-  CINIT(KEYPASSWD, STRINGPOINT, 26),
+  CURLOPT(CURLOPT_KEYPASSWD, CURLOPTTYPE_STRINGPOINT, 26),
 
   /* send TYPE parameter? */
-  CINIT(CRLF, LONG, 27),
+  CURLOPT(CURLOPT_CRLF, CURLOPTTYPE_LONG, 27),
 
   /* send linked-list of QUOTE commands */
-  CINIT(QUOTE, OBJECTPOINT, 28),
+  CURLOPT(CURLOPT_QUOTE, CURLOPTTYPE_SLISTPOINT, 28),
 
   /* send FILE * or void * to store headers to, if you use a callback it
      is simply passed to the callback unmodified */
-  CINIT(HEADERDATA, OBJECTPOINT, 29),
+  CURLOPT(CURLOPT_HEADERDATA, CURLOPTTYPE_OBJECTPOINT, 29),
 
   /* point to a file to read the initial cookies from, also enables
      "cookie awareness" */
-  CINIT(COOKIEFILE, STRINGPOINT, 31),
+  CURLOPT(CURLOPT_COOKIEFILE, CURLOPTTYPE_STRINGPOINT, 31),
 
   /* What version to specifically try to use.
      See CURL_SSLVERSION defines below. */
-  CINIT(SSLVERSION, LONG, 32),
+  CURLOPT(CURLOPT_SSLVERSION, CURLOPTTYPE_LONG, 32),
 
   /* What kind of HTTP time condition to use, see defines */
-  CINIT(TIMECONDITION, LONG, 33),
+  CURLOPT(CURLOPT_TIMECONDITION, CURLOPTTYPE_LONG, 33),
 
   /* Time to use with the above condition. Specified in number of seconds
      since 1 Jan 1970 */
-  CINIT(TIMEVALUE, LONG, 34),
+  CURLOPT(CURLOPT_TIMEVALUE, CURLOPTTYPE_LONG, 34),
 
   /* 35 = OBSOLETE */
 
@@ -1089,37 +1099,58 @@
      HTTP: DELETE, TRACE and others
      FTP: to use a different list command
      */
-  CINIT(CUSTOMREQUEST, STRINGPOINT, 36),
+  CURLOPT(CURLOPT_CUSTOMREQUEST, CURLOPTTYPE_STRINGPOINT, 36),
 
   /* FILE handle to use instead of stderr */
-  CINIT(STDERR, OBJECTPOINT, 37),
+  CURLOPT(CURLOPT_STDERR, CURLOPTTYPE_OBJECTPOINT, 37),
 
   /* 38 is not used */
 
   /* send linked-list of post-transfer QUOTE commands */
-  CINIT(POSTQUOTE, OBJECTPOINT, 39),
+  CURLOPT(CURLOPT_POSTQUOTE, CURLOPTTYPE_SLISTPOINT, 39),
 
-  CINIT(OBSOLETE40, OBJECTPOINT, 40), /* OBSOLETE, do not use! */
+   /* OBSOLETE, do not use! */
+  CURLOPT(CURLOPT_OBSOLETE40, CURLOPTTYPE_OBJECTPOINT, 40),
 
-  CINIT(VERBOSE, LONG, 41),      /* talk a lot */
-  CINIT(HEADER, LONG, 42),       /* throw the header out too */
-  CINIT(NOPROGRESS, LONG, 43),   /* shut off the progress meter */
-  CINIT(NOBODY, LONG, 44),       /* use HEAD to get http document */
-  CINIT(FAILONERROR, LONG, 45),  /* no output on http error codes >= 400 */
-  CINIT(UPLOAD, LONG, 46),       /* this is an upload */
-  CINIT(POST, LONG, 47),         /* HTTP POST method */
-  CINIT(DIRLISTONLY, LONG, 48),  /* bare names when listing directories */
+  /* talk a lot */
+  CURLOPT(CURLOPT_VERBOSE, CURLOPTTYPE_LONG, 41),
 
-  CINIT(APPEND, LONG, 50),       /* Append instead of overwrite on upload! */
+  /* throw the header out too */
+  CURLOPT(CURLOPT_HEADER, CURLOPTTYPE_LONG, 42),
+
+  /* shut off the progress meter */
+  CURLOPT(CURLOPT_NOPROGRESS, CURLOPTTYPE_LONG, 43),
+
+  /* use HEAD to get http document */
+  CURLOPT(CURLOPT_NOBODY, CURLOPTTYPE_LONG, 44),
+
+  /* no output on http error codes >= 400 */
+  CURLOPT(CURLOPT_FAILONERROR, CURLOPTTYPE_LONG, 45),
+
+  /* this is an upload */
+  CURLOPT(CURLOPT_UPLOAD, CURLOPTTYPE_LONG, 46),
+
+  /* HTTP POST method */
+  CURLOPT(CURLOPT_POST, CURLOPTTYPE_LONG, 47),
+
+  /* bare names when listing directories */
+  CURLOPT(CURLOPT_DIRLISTONLY, CURLOPTTYPE_LONG, 48),
+
+  /* Append instead of overwrite on upload! */
+  CURLOPT(CURLOPT_APPEND, CURLOPTTYPE_LONG, 50),
 
   /* Specify whether to read the user+password from the .netrc or the URL.
    * This must be one of the CURL_NETRC_* enums below. */
-  CINIT(NETRC, LONG, 51),
+  CURLOPT(CURLOPT_NETRC, CURLOPTTYPE_LONG, 51),
 
-  CINIT(FOLLOWLOCATION, LONG, 52),  /* use Location: Luke! */
+  /* use Location: Luke! */
+  CURLOPT(CURLOPT_FOLLOWLOCATION, CURLOPTTYPE_LONG, 52),
 
-  CINIT(TRANSFERTEXT, LONG, 53), /* transfer data in text/ASCII format */
-  CINIT(PUT, LONG, 54),          /* HTTP PUT */
+   /* transfer data in text/ASCII format */
+  CURLOPT(CURLOPT_TRANSFERTEXT, CURLOPTTYPE_LONG, 53),
+
+  /* HTTP PUT */
+  CURLOPT(CURLOPT_PUT, CURLOPTTYPE_LONG, 54),
 
   /* 55 = OBSOLETE */
 
@@ -1127,265 +1158,267 @@
    * Function that will be called instead of the internal progress display
    * function. This function should be defined as the curl_progress_callback
    * prototype defines. */
-  CINIT(PROGRESSFUNCTION, FUNCTIONPOINT, 56),
+  CURLOPT(CURLOPT_PROGRESSFUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 56),
 
   /* Data passed to the CURLOPT_PROGRESSFUNCTION and CURLOPT_XFERINFOFUNCTION
      callbacks */
-  CINIT(PROGRESSDATA, OBJECTPOINT, 57),
+  CURLOPT(CURLOPT_PROGRESSDATA, CURLOPTTYPE_OBJECTPOINT, 57),
 #define CURLOPT_XFERINFODATA CURLOPT_PROGRESSDATA
 
   /* We want the referrer field set automatically when following locations */
-  CINIT(AUTOREFERER, LONG, 58),
+  CURLOPT(CURLOPT_AUTOREFERER, CURLOPTTYPE_LONG, 58),
 
   /* Port of the proxy, can be set in the proxy string as well with:
      "[host]:[port]" */
-  CINIT(PROXYPORT, LONG, 59),
+  CURLOPT(CURLOPT_PROXYPORT, CURLOPTTYPE_LONG, 59),
 
   /* size of the POST input data, if strlen() is not good to use */
-  CINIT(POSTFIELDSIZE, LONG, 60),
+  CURLOPT(CURLOPT_POSTFIELDSIZE, CURLOPTTYPE_LONG, 60),
 
   /* tunnel non-http operations through a HTTP proxy */
-  CINIT(HTTPPROXYTUNNEL, LONG, 61),
+  CURLOPT(CURLOPT_HTTPPROXYTUNNEL, CURLOPTTYPE_LONG, 61),
 
   /* Set the interface string to use as outgoing network interface */
-  CINIT(INTERFACE, STRINGPOINT, 62),
+  CURLOPT(CURLOPT_INTERFACE, CURLOPTTYPE_STRINGPOINT, 62),
 
   /* Set the krb4/5 security level, this also enables krb4/5 awareness.  This
    * is a string, 'clear', 'safe', 'confidential' or 'private'.  If the string
    * is set but doesn't match one of these, 'private' will be used.  */
-  CINIT(KRBLEVEL, STRINGPOINT, 63),
+  CURLOPT(CURLOPT_KRBLEVEL, CURLOPTTYPE_STRINGPOINT, 63),
 
   /* Set if we should verify the peer in ssl handshake, set 1 to verify. */
-  CINIT(SSL_VERIFYPEER, LONG, 64),
+  CURLOPT(CURLOPT_SSL_VERIFYPEER, CURLOPTTYPE_LONG, 64),
 
   /* The CApath or CAfile used to validate the peer certificate
      this option is used only if SSL_VERIFYPEER is true */
-  CINIT(CAINFO, STRINGPOINT, 65),
+  CURLOPT(CURLOPT_CAINFO, CURLOPTTYPE_STRINGPOINT, 65),
 
   /* 66 = OBSOLETE */
   /* 67 = OBSOLETE */
 
   /* Maximum number of http redirects to follow */
-  CINIT(MAXREDIRS, LONG, 68),
+  CURLOPT(CURLOPT_MAXREDIRS, CURLOPTTYPE_LONG, 68),
 
   /* Pass a long set to 1 to get the date of the requested document (if
      possible)! Pass a zero to shut it off. */
-  CINIT(FILETIME, LONG, 69),
+  CURLOPT(CURLOPT_FILETIME, CURLOPTTYPE_LONG, 69),
 
   /* This points to a linked list of telnet options */
-  CINIT(TELNETOPTIONS, OBJECTPOINT, 70),
+  CURLOPT(CURLOPT_TELNETOPTIONS, CURLOPTTYPE_SLISTPOINT, 70),
 
   /* Max amount of cached alive connections */
-  CINIT(MAXCONNECTS, LONG, 71),
+  CURLOPT(CURLOPT_MAXCONNECTS, CURLOPTTYPE_LONG, 71),
 
-  CINIT(OBSOLETE72, LONG, 72), /* OBSOLETE, do not use! */
+  /* OBSOLETE, do not use! */
+  CURLOPT(CURLOPT_OBSOLETE72, CURLOPTTYPE_LONG, 72),
 
   /* 73 = OBSOLETE */
 
   /* Set to explicitly use a new connection for the upcoming transfer.
      Do not use this unless you're absolutely sure of this, as it makes the
      operation slower and is less friendly for the network. */
-  CINIT(FRESH_CONNECT, LONG, 74),
+  CURLOPT(CURLOPT_FRESH_CONNECT, CURLOPTTYPE_LONG, 74),
 
   /* Set to explicitly forbid the upcoming transfer's connection to be re-used
      when done. Do not use this unless you're absolutely sure of this, as it
      makes the operation slower and is less friendly for the network. */
-  CINIT(FORBID_REUSE, LONG, 75),
+  CURLOPT(CURLOPT_FORBID_REUSE, CURLOPTTYPE_LONG, 75),
 
   /* Set to a file name that contains random data for libcurl to use to
      seed the random engine when doing SSL connects. */
-  CINIT(RANDOM_FILE, STRINGPOINT, 76),
+  CURLOPT(CURLOPT_RANDOM_FILE, CURLOPTTYPE_STRINGPOINT, 76),
 
   /* Set to the Entropy Gathering Daemon socket pathname */
-  CINIT(EGDSOCKET, STRINGPOINT, 77),
+  CURLOPT(CURLOPT_EGDSOCKET, CURLOPTTYPE_STRINGPOINT, 77),
 
   /* Time-out connect operations after this amount of seconds, if connects are
      OK within this time, then fine... This only aborts the connect phase. */
-  CINIT(CONNECTTIMEOUT, LONG, 78),
+  CURLOPT(CURLOPT_CONNECTTIMEOUT, CURLOPTTYPE_LONG, 78),
 
   /* Function that will be called to store headers (instead of fwrite). The
    * parameters will use fwrite() syntax, make sure to follow them. */
-  CINIT(HEADERFUNCTION, FUNCTIONPOINT, 79),
+  CURLOPT(CURLOPT_HEADERFUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 79),
 
   /* Set this to force the HTTP request to get back to GET. Only really usable
      if POST, PUT or a custom request have been used first.
    */
-  CINIT(HTTPGET, LONG, 80),
+  CURLOPT(CURLOPT_HTTPGET, CURLOPTTYPE_LONG, 80),
 
   /* Set if we should verify the Common name from the peer certificate in ssl
    * handshake, set 1 to check existence, 2 to ensure that it matches the
    * provided hostname. */
-  CINIT(SSL_VERIFYHOST, LONG, 81),
+  CURLOPT(CURLOPT_SSL_VERIFYHOST, CURLOPTTYPE_LONG, 81),
 
   /* Specify which file name to write all known cookies in after completed
      operation. Set file name to "-" (dash) to make it go to stdout. */
-  CINIT(COOKIEJAR, STRINGPOINT, 82),
+  CURLOPT(CURLOPT_COOKIEJAR, CURLOPTTYPE_STRINGPOINT, 82),
 
   /* Specify which SSL ciphers to use */
-  CINIT(SSL_CIPHER_LIST, STRINGPOINT, 83),
+  CURLOPT(CURLOPT_SSL_CIPHER_LIST, CURLOPTTYPE_STRINGPOINT, 83),
 
   /* Specify which HTTP version to use! This must be set to one of the
      CURL_HTTP_VERSION* enums set below. */
-  CINIT(HTTP_VERSION, LONG, 84),
+  CURLOPT(CURLOPT_HTTP_VERSION, CURLOPTTYPE_LONG, 84),
 
   /* Specifically switch on or off the FTP engine's use of the EPSV command. By
      default, that one will always be attempted before the more traditional
      PASV command. */
-  CINIT(FTP_USE_EPSV, LONG, 85),
+  CURLOPT(CURLOPT_FTP_USE_EPSV, CURLOPTTYPE_LONG, 85),
 
   /* type of the file keeping your SSL-certificate ("DER", "PEM", "ENG") */
-  CINIT(SSLCERTTYPE, STRINGPOINT, 86),
+  CURLOPT(CURLOPT_SSLCERTTYPE, CURLOPTTYPE_STRINGPOINT, 86),
 
   /* name of the file keeping your private SSL-key */
-  CINIT(SSLKEY, STRINGPOINT, 87),
+  CURLOPT(CURLOPT_SSLKEY, CURLOPTTYPE_STRINGPOINT, 87),
 
   /* type of the file keeping your private SSL-key ("DER", "PEM", "ENG") */
-  CINIT(SSLKEYTYPE, STRINGPOINT, 88),
+  CURLOPT(CURLOPT_SSLKEYTYPE, CURLOPTTYPE_STRINGPOINT, 88),
 
   /* crypto engine for the SSL-sub system */
-  CINIT(SSLENGINE, STRINGPOINT, 89),
+  CURLOPT(CURLOPT_SSLENGINE, CURLOPTTYPE_STRINGPOINT, 89),
 
   /* set the crypto engine for the SSL-sub system as default
      the param has no meaning...
    */
-  CINIT(SSLENGINE_DEFAULT, LONG, 90),
+  CURLOPT(CURLOPT_SSLENGINE_DEFAULT, CURLOPTTYPE_LONG, 90),
 
   /* Non-zero value means to use the global dns cache */
-  CINIT(DNS_USE_GLOBAL_CACHE, LONG, 91), /* DEPRECATED, do not use! */
+  /* DEPRECATED, do not use! */
+  CURLOPT(CURLOPT_DNS_USE_GLOBAL_CACHE, CURLOPTTYPE_LONG, 91),
 
   /* DNS cache timeout */
-  CINIT(DNS_CACHE_TIMEOUT, LONG, 92),
+  CURLOPT(CURLOPT_DNS_CACHE_TIMEOUT, CURLOPTTYPE_LONG, 92),
 
   /* send linked-list of pre-transfer QUOTE commands */
-  CINIT(PREQUOTE, OBJECTPOINT, 93),
+  CURLOPT(CURLOPT_PREQUOTE, CURLOPTTYPE_SLISTPOINT, 93),
 
   /* set the debug function */
-  CINIT(DEBUGFUNCTION, FUNCTIONPOINT, 94),
+  CURLOPT(CURLOPT_DEBUGFUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 94),
 
   /* set the data for the debug function */
-  CINIT(DEBUGDATA, OBJECTPOINT, 95),
+  CURLOPT(CURLOPT_DEBUGDATA, CURLOPTTYPE_OBJECTPOINT, 95),
 
   /* mark this as start of a cookie session */
-  CINIT(COOKIESESSION, LONG, 96),
+  CURLOPT(CURLOPT_COOKIESESSION, CURLOPTTYPE_LONG, 96),
 
   /* The CApath directory used to validate the peer certificate
      this option is used only if SSL_VERIFYPEER is true */
-  CINIT(CAPATH, STRINGPOINT, 97),
+  CURLOPT(CURLOPT_CAPATH, CURLOPTTYPE_STRINGPOINT, 97),
 
   /* Instruct libcurl to use a smaller receive buffer */
-  CINIT(BUFFERSIZE, LONG, 98),
+  CURLOPT(CURLOPT_BUFFERSIZE, CURLOPTTYPE_LONG, 98),
 
   /* Instruct libcurl to not use any signal/alarm handlers, even when using
      timeouts. This option is useful for multi-threaded applications.
      See libcurl-the-guide for more background information. */
-  CINIT(NOSIGNAL, LONG, 99),
+  CURLOPT(CURLOPT_NOSIGNAL, CURLOPTTYPE_LONG, 99),
 
   /* Provide a CURLShare for mutexing non-ts data */
-  CINIT(SHARE, OBJECTPOINT, 100),
+  CURLOPT(CURLOPT_SHARE, CURLOPTTYPE_OBJECTPOINT, 100),
 
   /* indicates type of proxy. accepted values are CURLPROXY_HTTP (default),
      CURLPROXY_HTTPS, CURLPROXY_SOCKS4, CURLPROXY_SOCKS4A and
      CURLPROXY_SOCKS5. */
-  CINIT(PROXYTYPE, LONG, 101),
+  CURLOPT(CURLOPT_PROXYTYPE, CURLOPTTYPE_LONG, 101),
 
   /* Set the Accept-Encoding string. Use this to tell a server you would like
      the response to be compressed. Before 7.21.6, this was known as
      CURLOPT_ENCODING */
-  CINIT(ACCEPT_ENCODING, STRINGPOINT, 102),
+  CURLOPT(CURLOPT_ACCEPT_ENCODING, CURLOPTTYPE_STRINGPOINT, 102),
 
   /* Set pointer to private data */
-  CINIT(PRIVATE, OBJECTPOINT, 103),
+  CURLOPT(CURLOPT_PRIVATE, CURLOPTTYPE_OBJECTPOINT, 103),
 
   /* Set aliases for HTTP 200 in the HTTP Response header */
-  CINIT(HTTP200ALIASES, OBJECTPOINT, 104),
+  CURLOPT(CURLOPT_HTTP200ALIASES, CURLOPTTYPE_SLISTPOINT, 104),
 
   /* Continue to send authentication (user+password) when following locations,
      even when hostname changed. This can potentially send off the name
      and password to whatever host the server decides. */
-  CINIT(UNRESTRICTED_AUTH, LONG, 105),
+  CURLOPT(CURLOPT_UNRESTRICTED_AUTH, CURLOPTTYPE_LONG, 105),
 
   /* Specifically switch on or off the FTP engine's use of the EPRT command (
      it also disables the LPRT attempt). By default, those ones will always be
      attempted before the good old traditional PORT command. */
-  CINIT(FTP_USE_EPRT, LONG, 106),
+  CURLOPT(CURLOPT_FTP_USE_EPRT, CURLOPTTYPE_LONG, 106),
 
   /* Set this to a bitmask value to enable the particular authentications
      methods you like. Use this in combination with CURLOPT_USERPWD.
      Note that setting multiple bits may cause extra network round-trips. */
-  CINIT(HTTPAUTH, LONG, 107),
+  CURLOPT(CURLOPT_HTTPAUTH, CURLOPTTYPE_LONG, 107),
 
-  /* Set the ssl context callback function, currently only for OpenSSL ssl_ctx
-     in second argument. The function must be matching the
-     curl_ssl_ctx_callback proto. */
-  CINIT(SSL_CTX_FUNCTION, FUNCTIONPOINT, 108),
+  /* Set the ssl context callback function, currently only for OpenSSL or
+     WolfSSL ssl_ctx, or mbedTLS mbedtls_ssl_config in the second argument.
+     The function must match the curl_ssl_ctx_callback prototype. */
+  CURLOPT(CURLOPT_SSL_CTX_FUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 108),
 
   /* Set the userdata for the ssl context callback function's third
      argument */
-  CINIT(SSL_CTX_DATA, OBJECTPOINT, 109),
+  CURLOPT(CURLOPT_SSL_CTX_DATA, CURLOPTTYPE_OBJECTPOINT, 109),
 
   /* FTP Option that causes missing dirs to be created on the remote server.
      In 7.19.4 we introduced the convenience enums for this option using the
      CURLFTP_CREATE_DIR prefix.
   */
-  CINIT(FTP_CREATE_MISSING_DIRS, LONG, 110),
+  CURLOPT(CURLOPT_FTP_CREATE_MISSING_DIRS, CURLOPTTYPE_LONG, 110),
 
   /* Set this to a bitmask value to enable the particular authentications
      methods you like. Use this in combination with CURLOPT_PROXYUSERPWD.
      Note that setting multiple bits may cause extra network round-trips. */
-  CINIT(PROXYAUTH, LONG, 111),
+  CURLOPT(CURLOPT_PROXYAUTH, CURLOPTTYPE_LONG, 111),
 
   /* FTP option that changes the timeout, in seconds, associated with
      getting a response.  This is different from transfer timeout time and
      essentially places a demand on the FTP server to acknowledge commands
      in a timely manner. */
-  CINIT(FTP_RESPONSE_TIMEOUT, LONG, 112),
+  CURLOPT(CURLOPT_FTP_RESPONSE_TIMEOUT, CURLOPTTYPE_LONG, 112),
 #define CURLOPT_SERVER_RESPONSE_TIMEOUT CURLOPT_FTP_RESPONSE_TIMEOUT
 
   /* Set this option to one of the CURL_IPRESOLVE_* defines (see below) to
      tell libcurl to resolve names to those IP versions only. This only has
      affect on systems with support for more than one, i.e IPv4 _and_ IPv6. */
-  CINIT(IPRESOLVE, LONG, 113),
+  CURLOPT(CURLOPT_IPRESOLVE, CURLOPTTYPE_LONG, 113),
 
   /* Set this option to limit the size of a file that will be downloaded from
      an HTTP or FTP server.
 
      Note there is also _LARGE version which adds large file support for
      platforms which have larger off_t sizes.  See MAXFILESIZE_LARGE below. */
-  CINIT(MAXFILESIZE, LONG, 114),
+  CURLOPT(CURLOPT_MAXFILESIZE, CURLOPTTYPE_LONG, 114),
 
   /* See the comment for INFILESIZE above, but in short, specifies
    * the size of the file being uploaded.  -1 means unknown.
    */
-  CINIT(INFILESIZE_LARGE, OFF_T, 115),
+  CURLOPT(CURLOPT_INFILESIZE_LARGE, CURLOPTTYPE_OFF_T, 115),
 
-  /* Sets the continuation offset.  There is also a LONG version of this;
-   * look above for RESUME_FROM.
+  /* Sets the continuation offset.  There is also a CURLOPTTYPE_LONG version
+   * of this; look above for RESUME_FROM.
    */
-  CINIT(RESUME_FROM_LARGE, OFF_T, 116),
+  CURLOPT(CURLOPT_RESUME_FROM_LARGE, CURLOPTTYPE_OFF_T, 116),
 
   /* Sets the maximum size of data that will be downloaded from
    * an HTTP or FTP server.  See MAXFILESIZE above for the LONG version.
    */
-  CINIT(MAXFILESIZE_LARGE, OFF_T, 117),
+  CURLOPT(CURLOPT_MAXFILESIZE_LARGE, CURLOPTTYPE_OFF_T, 117),
 
   /* Set this option to the file name of your .netrc file you want libcurl
      to parse (using the CURLOPT_NETRC option). If not set, libcurl will do
      a poor attempt to find the user's home directory and check for a .netrc
      file in there. */
-  CINIT(NETRC_FILE, STRINGPOINT, 118),
+  CURLOPT(CURLOPT_NETRC_FILE, CURLOPTTYPE_STRINGPOINT, 118),
 
   /* Enable SSL/TLS for FTP, pick one of:
      CURLUSESSL_TRY     - try using SSL, proceed anyway otherwise
      CURLUSESSL_CONTROL - SSL for the control connection or fail
      CURLUSESSL_ALL     - SSL for all communication or fail
   */
-  CINIT(USE_SSL, LONG, 119),
+  CURLOPT(CURLOPT_USE_SSL, CURLOPTTYPE_LONG, 119),
 
   /* The _LARGE version of the standard POSTFIELDSIZE option */
-  CINIT(POSTFIELDSIZE_LARGE, OFF_T, 120),
+  CURLOPT(CURLOPT_POSTFIELDSIZE_LARGE, CURLOPTTYPE_OFF_T, 120),
 
   /* Enable/disable the TCP Nagle algorithm */
-  CINIT(TCP_NODELAY, LONG, 121),
+  CURLOPT(CURLOPT_TCP_NODELAY, CURLOPTTYPE_LONG, 121),
 
   /* 122 OBSOLETE, used in 7.12.3. Gone in 7.13.0 */
   /* 123 OBSOLETE. Gone in 7.16.0 */
@@ -1405,143 +1438,143 @@
      CURLFTPAUTH_SSL     - try "AUTH SSL" first, then TLS
      CURLFTPAUTH_TLS     - try "AUTH TLS" first, then SSL
   */
-  CINIT(FTPSSLAUTH, LONG, 129),
+  CURLOPT(CURLOPT_FTPSSLAUTH, CURLOPTTYPE_LONG, 129),
 
-  CINIT(IOCTLFUNCTION, FUNCTIONPOINT, 130),
-  CINIT(IOCTLDATA, OBJECTPOINT, 131),
+  CURLOPT(CURLOPT_IOCTLFUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 130),
+  CURLOPT(CURLOPT_IOCTLDATA, CURLOPTTYPE_OBJECTPOINT, 131),
 
   /* 132 OBSOLETE. Gone in 7.16.0 */
   /* 133 OBSOLETE. Gone in 7.16.0 */
 
-  /* zero terminated string for pass on to the FTP server when asked for
+  /* null-terminated string for pass on to the FTP server when asked for
      "account" info */
-  CINIT(FTP_ACCOUNT, STRINGPOINT, 134),
+  CURLOPT(CURLOPT_FTP_ACCOUNT, CURLOPTTYPE_STRINGPOINT, 134),
 
   /* feed cookie into cookie engine */
-  CINIT(COOKIELIST, STRINGPOINT, 135),
+  CURLOPT(CURLOPT_COOKIELIST, CURLOPTTYPE_STRINGPOINT, 135),
 
   /* ignore Content-Length */
-  CINIT(IGNORE_CONTENT_LENGTH, LONG, 136),
+  CURLOPT(CURLOPT_IGNORE_CONTENT_LENGTH, CURLOPTTYPE_LONG, 136),
 
   /* Set to non-zero to skip the IP address received in a 227 PASV FTP server
      response. Typically used for FTP-SSL purposes but is not restricted to
      that. libcurl will then instead use the same IP address it used for the
      control connection. */
-  CINIT(FTP_SKIP_PASV_IP, LONG, 137),
+  CURLOPT(CURLOPT_FTP_SKIP_PASV_IP, CURLOPTTYPE_LONG, 137),
 
   /* Select "file method" to use when doing FTP, see the curl_ftpmethod
      above. */
-  CINIT(FTP_FILEMETHOD, LONG, 138),
+  CURLOPT(CURLOPT_FTP_FILEMETHOD, CURLOPTTYPE_LONG, 138),
 
   /* Local port number to bind the socket to */
-  CINIT(LOCALPORT, LONG, 139),
+  CURLOPT(CURLOPT_LOCALPORT, CURLOPTTYPE_LONG, 139),
 
   /* Number of ports to try, including the first one set with LOCALPORT.
      Thus, setting it to 1 will make no additional attempts but the first.
   */
-  CINIT(LOCALPORTRANGE, LONG, 140),
+  CURLOPT(CURLOPT_LOCALPORTRANGE, CURLOPTTYPE_LONG, 140),
 
   /* no transfer, set up connection and let application use the socket by
      extracting it with CURLINFO_LASTSOCKET */
-  CINIT(CONNECT_ONLY, LONG, 141),
+  CURLOPT(CURLOPT_CONNECT_ONLY, CURLOPTTYPE_LONG, 141),
 
   /* Function that will be called to convert from the
      network encoding (instead of using the iconv calls in libcurl) */
-  CINIT(CONV_FROM_NETWORK_FUNCTION, FUNCTIONPOINT, 142),
+  CURLOPT(CURLOPT_CONV_FROM_NETWORK_FUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 142),
 
   /* Function that will be called to convert to the
      network encoding (instead of using the iconv calls in libcurl) */
-  CINIT(CONV_TO_NETWORK_FUNCTION, FUNCTIONPOINT, 143),
+  CURLOPT(CURLOPT_CONV_TO_NETWORK_FUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 143),
 
   /* Function that will be called to convert from UTF8
      (instead of using the iconv calls in libcurl)
      Note that this is used only for SSL certificate processing */
-  CINIT(CONV_FROM_UTF8_FUNCTION, FUNCTIONPOINT, 144),
+  CURLOPT(CURLOPT_CONV_FROM_UTF8_FUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 144),
 
   /* if the connection proceeds too quickly then need to slow it down */
   /* limit-rate: maximum number of bytes per second to send or receive */
-  CINIT(MAX_SEND_SPEED_LARGE, OFF_T, 145),
-  CINIT(MAX_RECV_SPEED_LARGE, OFF_T, 146),
+  CURLOPT(CURLOPT_MAX_SEND_SPEED_LARGE, CURLOPTTYPE_OFF_T, 145),
+  CURLOPT(CURLOPT_MAX_RECV_SPEED_LARGE, CURLOPTTYPE_OFF_T, 146),
 
   /* Pointer to command string to send if USER/PASS fails. */
-  CINIT(FTP_ALTERNATIVE_TO_USER, STRINGPOINT, 147),
+  CURLOPT(CURLOPT_FTP_ALTERNATIVE_TO_USER, CURLOPTTYPE_STRINGPOINT, 147),
 
   /* callback function for setting socket options */
-  CINIT(SOCKOPTFUNCTION, FUNCTIONPOINT, 148),
-  CINIT(SOCKOPTDATA, OBJECTPOINT, 149),
+  CURLOPT(CURLOPT_SOCKOPTFUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 148),
+  CURLOPT(CURLOPT_SOCKOPTDATA, CURLOPTTYPE_OBJECTPOINT, 149),
 
   /* set to 0 to disable session ID re-use for this transfer, default is
      enabled (== 1) */
-  CINIT(SSL_SESSIONID_CACHE, LONG, 150),
+  CURLOPT(CURLOPT_SSL_SESSIONID_CACHE, CURLOPTTYPE_LONG, 150),
 
   /* allowed SSH authentication methods */
-  CINIT(SSH_AUTH_TYPES, LONG, 151),
+  CURLOPT(CURLOPT_SSH_AUTH_TYPES, CURLOPTTYPE_LONG, 151),
 
   /* Used by scp/sftp to do public/private key authentication */
-  CINIT(SSH_PUBLIC_KEYFILE, STRINGPOINT, 152),
-  CINIT(SSH_PRIVATE_KEYFILE, STRINGPOINT, 153),
+  CURLOPT(CURLOPT_SSH_PUBLIC_KEYFILE, CURLOPTTYPE_STRINGPOINT, 152),
+  CURLOPT(CURLOPT_SSH_PRIVATE_KEYFILE, CURLOPTTYPE_STRINGPOINT, 153),
 
   /* Send CCC (Clear Command Channel) after authentication */
-  CINIT(FTP_SSL_CCC, LONG, 154),
+  CURLOPT(CURLOPT_FTP_SSL_CCC, CURLOPTTYPE_LONG, 154),
 
   /* Same as TIMEOUT and CONNECTTIMEOUT, but with ms resolution */
-  CINIT(TIMEOUT_MS, LONG, 155),
-  CINIT(CONNECTTIMEOUT_MS, LONG, 156),
+  CURLOPT(CURLOPT_TIMEOUT_MS, CURLOPTTYPE_LONG, 155),
+  CURLOPT(CURLOPT_CONNECTTIMEOUT_MS, CURLOPTTYPE_LONG, 156),
 
   /* set to zero to disable the libcurl's decoding and thus pass the raw body
      data to the application even when it is encoded/compressed */
-  CINIT(HTTP_TRANSFER_DECODING, LONG, 157),
-  CINIT(HTTP_CONTENT_DECODING, LONG, 158),
+  CURLOPT(CURLOPT_HTTP_TRANSFER_DECODING, CURLOPTTYPE_LONG, 157),
+  CURLOPT(CURLOPT_HTTP_CONTENT_DECODING, CURLOPTTYPE_LONG, 158),
 
   /* Permission used when creating new files and directories on the remote
      server for protocols that support it, SFTP/SCP/FILE */
-  CINIT(NEW_FILE_PERMS, LONG, 159),
-  CINIT(NEW_DIRECTORY_PERMS, LONG, 160),
+  CURLOPT(CURLOPT_NEW_FILE_PERMS, CURLOPTTYPE_LONG, 159),
+  CURLOPT(CURLOPT_NEW_DIRECTORY_PERMS, CURLOPTTYPE_LONG, 160),
 
   /* Set the behaviour of POST when redirecting. Values must be set to one
      of CURL_REDIR* defines below. This used to be called CURLOPT_POST301 */
-  CINIT(POSTREDIR, LONG, 161),
+  CURLOPT(CURLOPT_POSTREDIR, CURLOPTTYPE_LONG, 161),
 
   /* used by scp/sftp to verify the host's public key */
-  CINIT(SSH_HOST_PUBLIC_KEY_MD5, STRINGPOINT, 162),
+  CURLOPT(CURLOPT_SSH_HOST_PUBLIC_KEY_MD5, CURLOPTTYPE_STRINGPOINT, 162),
 
   /* Callback function for opening socket (instead of socket(2)). Optionally,
      callback is able change the address or refuse to connect returning
      CURL_SOCKET_BAD.  The callback should have type
      curl_opensocket_callback */
-  CINIT(OPENSOCKETFUNCTION, FUNCTIONPOINT, 163),
-  CINIT(OPENSOCKETDATA, OBJECTPOINT, 164),
+  CURLOPT(CURLOPT_OPENSOCKETFUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 163),
+  CURLOPT(CURLOPT_OPENSOCKETDATA, CURLOPTTYPE_OBJECTPOINT, 164),
 
   /* POST volatile input fields. */
-  CINIT(COPYPOSTFIELDS, OBJECTPOINT, 165),
+  CURLOPT(CURLOPT_COPYPOSTFIELDS, CURLOPTTYPE_OBJECTPOINT, 165),
 
   /* set transfer mode (;type=<a|i>) when doing FTP via an HTTP proxy */
-  CINIT(PROXY_TRANSFER_MODE, LONG, 166),
+  CURLOPT(CURLOPT_PROXY_TRANSFER_MODE, CURLOPTTYPE_LONG, 166),
 
   /* Callback function for seeking in the input stream */
-  CINIT(SEEKFUNCTION, FUNCTIONPOINT, 167),
-  CINIT(SEEKDATA, OBJECTPOINT, 168),
+  CURLOPT(CURLOPT_SEEKFUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 167),
+  CURLOPT(CURLOPT_SEEKDATA, CURLOPTTYPE_OBJECTPOINT, 168),
 
   /* CRL file */
-  CINIT(CRLFILE, STRINGPOINT, 169),
+  CURLOPT(CURLOPT_CRLFILE, CURLOPTTYPE_STRINGPOINT, 169),
 
   /* Issuer certificate */
-  CINIT(ISSUERCERT, STRINGPOINT, 170),
+  CURLOPT(CURLOPT_ISSUERCERT, CURLOPTTYPE_STRINGPOINT, 170),
 
   /* (IPv6) Address scope */
-  CINIT(ADDRESS_SCOPE, LONG, 171),
+  CURLOPT(CURLOPT_ADDRESS_SCOPE, CURLOPTTYPE_LONG, 171),
 
   /* Collect certificate chain info and allow it to get retrievable with
      CURLINFO_CERTINFO after the transfer is complete. */
-  CINIT(CERTINFO, LONG, 172),
+  CURLOPT(CURLOPT_CERTINFO, CURLOPTTYPE_LONG, 172),
 
   /* "name" and "pwd" to use when fetching. */
-  CINIT(USERNAME, STRINGPOINT, 173),
-  CINIT(PASSWORD, STRINGPOINT, 174),
+  CURLOPT(CURLOPT_USERNAME, CURLOPTTYPE_STRINGPOINT, 173),
+  CURLOPT(CURLOPT_PASSWORD, CURLOPTTYPE_STRINGPOINT, 174),
 
     /* "name" and "pwd" to use with Proxy when fetching. */
-  CINIT(PROXYUSERNAME, STRINGPOINT, 175),
-  CINIT(PROXYPASSWORD, STRINGPOINT, 176),
+  CURLOPT(CURLOPT_PROXYUSERNAME, CURLOPTTYPE_STRINGPOINT, 175),
+  CURLOPT(CURLOPT_PROXYPASSWORD, CURLOPTTYPE_STRINGPOINT, 176),
 
   /* Comma separated list of hostnames defining no-proxy zones. These should
      match both hostnames directly, and hostnames within a domain. For
@@ -1550,103 +1583,103 @@
      implementations of this, .local.com will be considered to be the same as
      local.com. A single * is the only valid wildcard, and effectively
      disables the use of proxy. */
-  CINIT(NOPROXY, STRINGPOINT, 177),
+  CURLOPT(CURLOPT_NOPROXY, CURLOPTTYPE_STRINGPOINT, 177),
 
   /* block size for TFTP transfers */
-  CINIT(TFTP_BLKSIZE, LONG, 178),
+  CURLOPT(CURLOPT_TFTP_BLKSIZE, CURLOPTTYPE_LONG, 178),
 
   /* Socks Service */
-  CINIT(SOCKS5_GSSAPI_SERVICE, STRINGPOINT, 179), /* DEPRECATED, do not use! */
+  /* DEPRECATED, do not use! */
+  CURLOPT(CURLOPT_SOCKS5_GSSAPI_SERVICE, CURLOPTTYPE_STRINGPOINT, 179),
 
   /* Socks Service */
-  CINIT(SOCKS5_GSSAPI_NEC, LONG, 180),
+  CURLOPT(CURLOPT_SOCKS5_GSSAPI_NEC, CURLOPTTYPE_LONG, 180),
 
   /* set the bitmask for the protocols that are allowed to be used for the
      transfer, which thus helps the app which takes URLs from users or other
      external inputs and want to restrict what protocol(s) to deal
      with. Defaults to CURLPROTO_ALL. */
-  CINIT(PROTOCOLS, LONG, 181),
+  CURLOPT(CURLOPT_PROTOCOLS, CURLOPTTYPE_LONG, 181),
 
   /* set the bitmask for the protocols that libcurl is allowed to follow to,
      as a subset of the CURLOPT_PROTOCOLS ones. That means the protocol needs
-     to be set in both bitmasks to be allowed to get redirected to. Defaults
-     to all protocols except FILE and SCP. */
-  CINIT(REDIR_PROTOCOLS, LONG, 182),
+     to be set in both bitmasks to be allowed to get redirected to. */
+  CURLOPT(CURLOPT_REDIR_PROTOCOLS, CURLOPTTYPE_LONG, 182),
 
   /* set the SSH knownhost file name to use */
-  CINIT(SSH_KNOWNHOSTS, STRINGPOINT, 183),
+  CURLOPT(CURLOPT_SSH_KNOWNHOSTS, CURLOPTTYPE_STRINGPOINT, 183),
 
   /* set the SSH host key callback, must point to a curl_sshkeycallback
      function */
-  CINIT(SSH_KEYFUNCTION, FUNCTIONPOINT, 184),
+  CURLOPT(CURLOPT_SSH_KEYFUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 184),
 
   /* set the SSH host key callback custom pointer */
-  CINIT(SSH_KEYDATA, OBJECTPOINT, 185),
+  CURLOPT(CURLOPT_SSH_KEYDATA, CURLOPTTYPE_OBJECTPOINT, 185),
 
   /* set the SMTP mail originator */
-  CINIT(MAIL_FROM, STRINGPOINT, 186),
+  CURLOPT(CURLOPT_MAIL_FROM, CURLOPTTYPE_STRINGPOINT, 186),
 
   /* set the list of SMTP mail receiver(s) */
-  CINIT(MAIL_RCPT, OBJECTPOINT, 187),
+  CURLOPT(CURLOPT_MAIL_RCPT, CURLOPTTYPE_SLISTPOINT, 187),
 
   /* FTP: send PRET before PASV */
-  CINIT(FTP_USE_PRET, LONG, 188),
+  CURLOPT(CURLOPT_FTP_USE_PRET, CURLOPTTYPE_LONG, 188),
 
   /* RTSP request method (OPTIONS, SETUP, PLAY, etc...) */
-  CINIT(RTSP_REQUEST, LONG, 189),
+  CURLOPT(CURLOPT_RTSP_REQUEST, CURLOPTTYPE_LONG, 189),
 
   /* The RTSP session identifier */
-  CINIT(RTSP_SESSION_ID, STRINGPOINT, 190),
+  CURLOPT(CURLOPT_RTSP_SESSION_ID, CURLOPTTYPE_STRINGPOINT, 190),
 
   /* The RTSP stream URI */
-  CINIT(RTSP_STREAM_URI, STRINGPOINT, 191),
+  CURLOPT(CURLOPT_RTSP_STREAM_URI, CURLOPTTYPE_STRINGPOINT, 191),
 
   /* The Transport: header to use in RTSP requests */
-  CINIT(RTSP_TRANSPORT, STRINGPOINT, 192),
+  CURLOPT(CURLOPT_RTSP_TRANSPORT, CURLOPTTYPE_STRINGPOINT, 192),
 
   /* Manually initialize the client RTSP CSeq for this handle */
-  CINIT(RTSP_CLIENT_CSEQ, LONG, 193),
+  CURLOPT(CURLOPT_RTSP_CLIENT_CSEQ, CURLOPTTYPE_LONG, 193),
 
   /* Manually initialize the server RTSP CSeq for this handle */
-  CINIT(RTSP_SERVER_CSEQ, LONG, 194),
+  CURLOPT(CURLOPT_RTSP_SERVER_CSEQ, CURLOPTTYPE_LONG, 194),
 
   /* The stream to pass to INTERLEAVEFUNCTION. */
-  CINIT(INTERLEAVEDATA, OBJECTPOINT, 195),
+  CURLOPT(CURLOPT_INTERLEAVEDATA, CURLOPTTYPE_OBJECTPOINT, 195),
 
   /* Let the application define a custom write method for RTP data */
-  CINIT(INTERLEAVEFUNCTION, FUNCTIONPOINT, 196),
+  CURLOPT(CURLOPT_INTERLEAVEFUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 196),
 
   /* Turn on wildcard matching */
-  CINIT(WILDCARDMATCH, LONG, 197),
+  CURLOPT(CURLOPT_WILDCARDMATCH, CURLOPTTYPE_LONG, 197),
 
   /* Directory matching callback called before downloading of an
      individual file (chunk) started */
-  CINIT(CHUNK_BGN_FUNCTION, FUNCTIONPOINT, 198),
+  CURLOPT(CURLOPT_CHUNK_BGN_FUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 198),
 
   /* Directory matching callback called after the file (chunk)
      was downloaded, or skipped */
-  CINIT(CHUNK_END_FUNCTION, FUNCTIONPOINT, 199),
+  CURLOPT(CURLOPT_CHUNK_END_FUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 199),
 
   /* Change match (fnmatch-like) callback for wildcard matching */
-  CINIT(FNMATCH_FUNCTION, FUNCTIONPOINT, 200),
+  CURLOPT(CURLOPT_FNMATCH_FUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 200),
 
   /* Let the application define custom chunk data pointer */
-  CINIT(CHUNK_DATA, OBJECTPOINT, 201),
+  CURLOPT(CURLOPT_CHUNK_DATA, CURLOPTTYPE_OBJECTPOINT, 201),
 
   /* FNMATCH_FUNCTION user pointer */
-  CINIT(FNMATCH_DATA, OBJECTPOINT, 202),
+  CURLOPT(CURLOPT_FNMATCH_DATA, CURLOPTTYPE_OBJECTPOINT, 202),
 
   /* send linked-list of name:port:address sets */
-  CINIT(RESOLVE, OBJECTPOINT, 203),
+  CURLOPT(CURLOPT_RESOLVE, CURLOPTTYPE_SLISTPOINT, 203),
 
   /* Set a username for authenticated TLS */
-  CINIT(TLSAUTH_USERNAME, STRINGPOINT, 204),
+  CURLOPT(CURLOPT_TLSAUTH_USERNAME, CURLOPTTYPE_STRINGPOINT, 204),
 
   /* Set a password for authenticated TLS */
-  CINIT(TLSAUTH_PASSWORD, STRINGPOINT, 205),
+  CURLOPT(CURLOPT_TLSAUTH_PASSWORD, CURLOPTTYPE_STRINGPOINT, 205),
 
   /* Set authentication type for authenticated TLS */
-  CINIT(TLSAUTH_TYPE, STRINGPOINT, 206),
+  CURLOPT(CURLOPT_TLSAUTH_TYPE, CURLOPTTYPE_STRINGPOINT, 206),
 
   /* Set to 1 to enable the "TE:" header in HTTP requests to ask for
      compressed transfer-encoded responses. Set to 0 to disable the use of TE:
@@ -1658,268 +1691,285 @@
      option is set to 1.
 
   */
-  CINIT(TRANSFER_ENCODING, LONG, 207),
+  CURLOPT(CURLOPT_TRANSFER_ENCODING, CURLOPTTYPE_LONG, 207),
 
   /* Callback function for closing socket (instead of close(2)). The callback
      should have type curl_closesocket_callback */
-  CINIT(CLOSESOCKETFUNCTION, FUNCTIONPOINT, 208),
-  CINIT(CLOSESOCKETDATA, OBJECTPOINT, 209),
+  CURLOPT(CURLOPT_CLOSESOCKETFUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 208),
+  CURLOPT(CURLOPT_CLOSESOCKETDATA, CURLOPTTYPE_OBJECTPOINT, 209),
 
   /* allow GSSAPI credential delegation */
-  CINIT(GSSAPI_DELEGATION, LONG, 210),
+  CURLOPT(CURLOPT_GSSAPI_DELEGATION, CURLOPTTYPE_LONG, 210),
 
   /* Set the name servers to use for DNS resolution */
-  CINIT(DNS_SERVERS, STRINGPOINT, 211),
+  CURLOPT(CURLOPT_DNS_SERVERS, CURLOPTTYPE_STRINGPOINT, 211),
 
   /* Time-out accept operations (currently for FTP only) after this amount
      of milliseconds. */
-  CINIT(ACCEPTTIMEOUT_MS, LONG, 212),
+  CURLOPT(CURLOPT_ACCEPTTIMEOUT_MS, CURLOPTTYPE_LONG, 212),
 
   /* Set TCP keepalive */
-  CINIT(TCP_KEEPALIVE, LONG, 213),
+  CURLOPT(CURLOPT_TCP_KEEPALIVE, CURLOPTTYPE_LONG, 213),
 
   /* non-universal keepalive knobs (Linux, AIX, HP-UX, more) */
-  CINIT(TCP_KEEPIDLE, LONG, 214),
-  CINIT(TCP_KEEPINTVL, LONG, 215),
+  CURLOPT(CURLOPT_TCP_KEEPIDLE, CURLOPTTYPE_LONG, 214),
+  CURLOPT(CURLOPT_TCP_KEEPINTVL, CURLOPTTYPE_LONG, 215),
 
   /* Enable/disable specific SSL features with a bitmask, see CURLSSLOPT_* */
-  CINIT(SSL_OPTIONS, LONG, 216),
+  CURLOPT(CURLOPT_SSL_OPTIONS, CURLOPTTYPE_LONG, 216),
 
   /* Set the SMTP auth originator */
-  CINIT(MAIL_AUTH, STRINGPOINT, 217),
+  CURLOPT(CURLOPT_MAIL_AUTH, CURLOPTTYPE_STRINGPOINT, 217),
 
   /* Enable/disable SASL initial response */
-  CINIT(SASL_IR, LONG, 218),
+  CURLOPT(CURLOPT_SASL_IR, CURLOPTTYPE_LONG, 218),
 
   /* Function that will be called instead of the internal progress display
    * function. This function should be defined as the curl_xferinfo_callback
    * prototype defines. (Deprecates CURLOPT_PROGRESSFUNCTION) */
-  CINIT(XFERINFOFUNCTION, FUNCTIONPOINT, 219),
+  CURLOPT(CURLOPT_XFERINFOFUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 219),
 
   /* The XOAUTH2 bearer token */
-  CINIT(XOAUTH2_BEARER, STRINGPOINT, 220),
+  CURLOPT(CURLOPT_XOAUTH2_BEARER, CURLOPTTYPE_STRINGPOINT, 220),
 
   /* Set the interface string to use as outgoing network
    * interface for DNS requests.
    * Only supported by the c-ares DNS backend */
-  CINIT(DNS_INTERFACE, STRINGPOINT, 221),
+  CURLOPT(CURLOPT_DNS_INTERFACE, CURLOPTTYPE_STRINGPOINT, 221),
 
   /* Set the local IPv4 address to use for outgoing DNS requests.
    * Only supported by the c-ares DNS backend */
-  CINIT(DNS_LOCAL_IP4, STRINGPOINT, 222),
+  CURLOPT(CURLOPT_DNS_LOCAL_IP4, CURLOPTTYPE_STRINGPOINT, 222),
 
   /* Set the local IPv6 address to use for outgoing DNS requests.
    * Only supported by the c-ares DNS backend */
-  CINIT(DNS_LOCAL_IP6, STRINGPOINT, 223),
+  CURLOPT(CURLOPT_DNS_LOCAL_IP6, CURLOPTTYPE_STRINGPOINT, 223),
 
   /* Set authentication options directly */
-  CINIT(LOGIN_OPTIONS, STRINGPOINT, 224),
+  CURLOPT(CURLOPT_LOGIN_OPTIONS, CURLOPTTYPE_STRINGPOINT, 224),
 
   /* Enable/disable TLS NPN extension (http2 over ssl might fail without) */
-  CINIT(SSL_ENABLE_NPN, LONG, 225),
+  CURLOPT(CURLOPT_SSL_ENABLE_NPN, CURLOPTTYPE_LONG, 225),
 
   /* Enable/disable TLS ALPN extension (http2 over ssl might fail without) */
-  CINIT(SSL_ENABLE_ALPN, LONG, 226),
+  CURLOPT(CURLOPT_SSL_ENABLE_ALPN, CURLOPTTYPE_LONG, 226),
 
   /* Time to wait for a response to a HTTP request containing an
    * Expect: 100-continue header before sending the data anyway. */
-  CINIT(EXPECT_100_TIMEOUT_MS, LONG, 227),
+  CURLOPT(CURLOPT_EXPECT_100_TIMEOUT_MS, CURLOPTTYPE_LONG, 227),
 
   /* This points to a linked list of headers used for proxy requests only,
      struct curl_slist kind */
-  CINIT(PROXYHEADER, OBJECTPOINT, 228),
+  CURLOPT(CURLOPT_PROXYHEADER, CURLOPTTYPE_SLISTPOINT, 228),
 
   /* Pass in a bitmask of "header options" */
-  CINIT(HEADEROPT, LONG, 229),
+  CURLOPT(CURLOPT_HEADEROPT, CURLOPTTYPE_LONG, 229),
 
   /* The public key in DER form used to validate the peer public key
      this option is used only if SSL_VERIFYPEER is true */
-  CINIT(PINNEDPUBLICKEY, STRINGPOINT, 230),
+  CURLOPT(CURLOPT_PINNEDPUBLICKEY, CURLOPTTYPE_STRINGPOINT, 230),
 
   /* Path to Unix domain socket */
-  CINIT(UNIX_SOCKET_PATH, STRINGPOINT, 231),
+  CURLOPT(CURLOPT_UNIX_SOCKET_PATH, CURLOPTTYPE_STRINGPOINT, 231),
 
   /* Set if we should verify the certificate status. */
-  CINIT(SSL_VERIFYSTATUS, LONG, 232),
+  CURLOPT(CURLOPT_SSL_VERIFYSTATUS, CURLOPTTYPE_LONG, 232),
 
   /* Set if we should enable TLS false start. */
-  CINIT(SSL_FALSESTART, LONG, 233),
+  CURLOPT(CURLOPT_SSL_FALSESTART, CURLOPTTYPE_LONG, 233),
 
   /* Do not squash dot-dot sequences */
-  CINIT(PATH_AS_IS, LONG, 234),
+  CURLOPT(CURLOPT_PATH_AS_IS, CURLOPTTYPE_LONG, 234),
 
   /* Proxy Service Name */
-  CINIT(PROXY_SERVICE_NAME, STRINGPOINT, 235),
+  CURLOPT(CURLOPT_PROXY_SERVICE_NAME, CURLOPTTYPE_STRINGPOINT, 235),
 
   /* Service Name */
-  CINIT(SERVICE_NAME, STRINGPOINT, 236),
+  CURLOPT(CURLOPT_SERVICE_NAME, CURLOPTTYPE_STRINGPOINT, 236),
 
   /* Wait/don't wait for pipe/mutex to clarify */
-  CINIT(PIPEWAIT, LONG, 237),
+  CURLOPT(CURLOPT_PIPEWAIT, CURLOPTTYPE_LONG, 237),
 
   /* Set the protocol used when curl is given a URL without a protocol */
-  CINIT(DEFAULT_PROTOCOL, STRINGPOINT, 238),
+  CURLOPT(CURLOPT_DEFAULT_PROTOCOL, CURLOPTTYPE_STRINGPOINT, 238),
 
   /* Set stream weight, 1 - 256 (default is 16) */
-  CINIT(STREAM_WEIGHT, LONG, 239),
+  CURLOPT(CURLOPT_STREAM_WEIGHT, CURLOPTTYPE_LONG, 239),
 
   /* Set stream dependency on another CURL handle */
-  CINIT(STREAM_DEPENDS, OBJECTPOINT, 240),
+  CURLOPT(CURLOPT_STREAM_DEPENDS, CURLOPTTYPE_OBJECTPOINT, 240),
 
   /* Set E-xclusive stream dependency on another CURL handle */
-  CINIT(STREAM_DEPENDS_E, OBJECTPOINT, 241),
+  CURLOPT(CURLOPT_STREAM_DEPENDS_E, CURLOPTTYPE_OBJECTPOINT, 241),
 
   /* Do not send any tftp option requests to the server */
-  CINIT(TFTP_NO_OPTIONS, LONG, 242),
+  CURLOPT(CURLOPT_TFTP_NO_OPTIONS, CURLOPTTYPE_LONG, 242),
 
   /* Linked-list of host:port:connect-to-host:connect-to-port,
      overrides the URL's host:port (only for the network layer) */
-  CINIT(CONNECT_TO, OBJECTPOINT, 243),
+  CURLOPT(CURLOPT_CONNECT_TO, CURLOPTTYPE_SLISTPOINT, 243),
 
   /* Set TCP Fast Open */
-  CINIT(TCP_FASTOPEN, LONG, 244),
+  CURLOPT(CURLOPT_TCP_FASTOPEN, CURLOPTTYPE_LONG, 244),
 
   /* Continue to send data if the server responds early with an
    * HTTP status code >= 300 */
-  CINIT(KEEP_SENDING_ON_ERROR, LONG, 245),
+  CURLOPT(CURLOPT_KEEP_SENDING_ON_ERROR, CURLOPTTYPE_LONG, 245),
 
   /* The CApath or CAfile used to validate the proxy certificate
      this option is used only if PROXY_SSL_VERIFYPEER is true */
-  CINIT(PROXY_CAINFO, STRINGPOINT, 246),
+  CURLOPT(CURLOPT_PROXY_CAINFO, CURLOPTTYPE_STRINGPOINT, 246),
 
   /* The CApath directory used to validate the proxy certificate
      this option is used only if PROXY_SSL_VERIFYPEER is true */
-  CINIT(PROXY_CAPATH, STRINGPOINT, 247),
+  CURLOPT(CURLOPT_PROXY_CAPATH, CURLOPTTYPE_STRINGPOINT, 247),
 
   /* Set if we should verify the proxy in ssl handshake,
      set 1 to verify. */
-  CINIT(PROXY_SSL_VERIFYPEER, LONG, 248),
+  CURLOPT(CURLOPT_PROXY_SSL_VERIFYPEER, CURLOPTTYPE_LONG, 248),
 
   /* Set if we should verify the Common name from the proxy certificate in ssl
    * handshake, set 1 to check existence, 2 to ensure that it matches
    * the provided hostname. */
-  CINIT(PROXY_SSL_VERIFYHOST, LONG, 249),
+  CURLOPT(CURLOPT_PROXY_SSL_VERIFYHOST, CURLOPTTYPE_LONG, 249),
 
   /* What version to specifically try to use for proxy.
      See CURL_SSLVERSION defines below. */
-  CINIT(PROXY_SSLVERSION, LONG, 250),
+  CURLOPT(CURLOPT_PROXY_SSLVERSION, CURLOPTTYPE_LONG, 250),
 
   /* Set a username for authenticated TLS for proxy */
-  CINIT(PROXY_TLSAUTH_USERNAME, STRINGPOINT, 251),
+  CURLOPT(CURLOPT_PROXY_TLSAUTH_USERNAME, CURLOPTTYPE_STRINGPOINT, 251),
 
   /* Set a password for authenticated TLS for proxy */
-  CINIT(PROXY_TLSAUTH_PASSWORD, STRINGPOINT, 252),
+  CURLOPT(CURLOPT_PROXY_TLSAUTH_PASSWORD, CURLOPTTYPE_STRINGPOINT, 252),
 
   /* Set authentication type for authenticated TLS for proxy */
-  CINIT(PROXY_TLSAUTH_TYPE, STRINGPOINT, 253),
+  CURLOPT(CURLOPT_PROXY_TLSAUTH_TYPE, CURLOPTTYPE_STRINGPOINT, 253),
 
   /* name of the file keeping your private SSL-certificate for proxy */
-  CINIT(PROXY_SSLCERT, STRINGPOINT, 254),
+  CURLOPT(CURLOPT_PROXY_SSLCERT, CURLOPTTYPE_STRINGPOINT, 254),
 
   /* type of the file keeping your SSL-certificate ("DER", "PEM", "ENG") for
      proxy */
-  CINIT(PROXY_SSLCERTTYPE, STRINGPOINT, 255),
+  CURLOPT(CURLOPT_PROXY_SSLCERTTYPE, CURLOPTTYPE_STRINGPOINT, 255),
 
   /* name of the file keeping your private SSL-key for proxy */
-  CINIT(PROXY_SSLKEY, STRINGPOINT, 256),
+  CURLOPT(CURLOPT_PROXY_SSLKEY, CURLOPTTYPE_STRINGPOINT, 256),
 
   /* type of the file keeping your private SSL-key ("DER", "PEM", "ENG") for
      proxy */
-  CINIT(PROXY_SSLKEYTYPE, STRINGPOINT, 257),
+  CURLOPT(CURLOPT_PROXY_SSLKEYTYPE, CURLOPTTYPE_STRINGPOINT, 257),
 
   /* password for the SSL private key for proxy */
-  CINIT(PROXY_KEYPASSWD, STRINGPOINT, 258),
+  CURLOPT(CURLOPT_PROXY_KEYPASSWD, CURLOPTTYPE_STRINGPOINT, 258),
 
   /* Specify which SSL ciphers to use for proxy */
-  CINIT(PROXY_SSL_CIPHER_LIST, STRINGPOINT, 259),
+  CURLOPT(CURLOPT_PROXY_SSL_CIPHER_LIST, CURLOPTTYPE_STRINGPOINT, 259),
 
   /* CRL file for proxy */
-  CINIT(PROXY_CRLFILE, STRINGPOINT, 260),
+  CURLOPT(CURLOPT_PROXY_CRLFILE, CURLOPTTYPE_STRINGPOINT, 260),
 
   /* Enable/disable specific SSL features with a bitmask for proxy, see
      CURLSSLOPT_* */
-  CINIT(PROXY_SSL_OPTIONS, LONG, 261),
+  CURLOPT(CURLOPT_PROXY_SSL_OPTIONS, CURLOPTTYPE_LONG, 261),
 
   /* Name of pre proxy to use. */
-  CINIT(PRE_PROXY, STRINGPOINT, 262),
+  CURLOPT(CURLOPT_PRE_PROXY, CURLOPTTYPE_STRINGPOINT, 262),
 
   /* The public key in DER form used to validate the proxy public key
      this option is used only if PROXY_SSL_VERIFYPEER is true */
-  CINIT(PROXY_PINNEDPUBLICKEY, STRINGPOINT, 263),
+  CURLOPT(CURLOPT_PROXY_PINNEDPUBLICKEY, CURLOPTTYPE_STRINGPOINT, 263),
 
   /* Path to an abstract Unix domain socket */
-  CINIT(ABSTRACT_UNIX_SOCKET, STRINGPOINT, 264),
+  CURLOPT(CURLOPT_ABSTRACT_UNIX_SOCKET, CURLOPTTYPE_STRINGPOINT, 264),
 
   /* Suppress proxy CONNECT response headers from user callbacks */
-  CINIT(SUPPRESS_CONNECT_HEADERS, LONG, 265),
+  CURLOPT(CURLOPT_SUPPRESS_CONNECT_HEADERS, CURLOPTTYPE_LONG, 265),
 
   /* The request target, instead of extracted from the URL */
-  CINIT(REQUEST_TARGET, STRINGPOINT, 266),
+  CURLOPT(CURLOPT_REQUEST_TARGET, CURLOPTTYPE_STRINGPOINT, 266),
 
   /* bitmask of allowed auth methods for connections to SOCKS5 proxies */
-  CINIT(SOCKS5_AUTH, LONG, 267),
+  CURLOPT(CURLOPT_SOCKS5_AUTH, CURLOPTTYPE_LONG, 267),
 
   /* Enable/disable SSH compression */
-  CINIT(SSH_COMPRESSION, LONG, 268),
+  CURLOPT(CURLOPT_SSH_COMPRESSION, CURLOPTTYPE_LONG, 268),
 
   /* Post MIME data. */
-  CINIT(MIMEPOST, OBJECTPOINT, 269),
+  CURLOPT(CURLOPT_MIMEPOST, CURLOPTTYPE_OBJECTPOINT, 269),
 
   /* Time to use with the CURLOPT_TIMECONDITION. Specified in number of
      seconds since 1 Jan 1970. */
-  CINIT(TIMEVALUE_LARGE, OFF_T, 270),
+  CURLOPT(CURLOPT_TIMEVALUE_LARGE, CURLOPTTYPE_OFF_T, 270),
 
   /* Head start in milliseconds to give happy eyeballs. */
-  CINIT(HAPPY_EYEBALLS_TIMEOUT_MS, LONG, 271),
+  CURLOPT(CURLOPT_HAPPY_EYEBALLS_TIMEOUT_MS, CURLOPTTYPE_LONG, 271),
 
   /* Function that will be called before a resolver request is made */
-  CINIT(RESOLVER_START_FUNCTION, FUNCTIONPOINT, 272),
+  CURLOPT(CURLOPT_RESOLVER_START_FUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 272),
 
   /* User data to pass to the resolver start callback. */
-  CINIT(RESOLVER_START_DATA, OBJECTPOINT, 273),
+  CURLOPT(CURLOPT_RESOLVER_START_DATA, CURLOPTTYPE_OBJECTPOINT, 273),
 
   /* send HAProxy PROXY protocol header? */
-  CINIT(HAPROXYPROTOCOL, LONG, 274),
+  CURLOPT(CURLOPT_HAPROXYPROTOCOL, CURLOPTTYPE_LONG, 274),
 
   /* shuffle addresses before use when DNS returns multiple */
-  CINIT(DNS_SHUFFLE_ADDRESSES, LONG, 275),
+  CURLOPT(CURLOPT_DNS_SHUFFLE_ADDRESSES, CURLOPTTYPE_LONG, 275),
 
   /* Specify which TLS 1.3 ciphers suites to use */
-  CINIT(TLS13_CIPHERS, STRINGPOINT, 276),
-  CINIT(PROXY_TLS13_CIPHERS, STRINGPOINT, 277),
+  CURLOPT(CURLOPT_TLS13_CIPHERS, CURLOPTTYPE_STRINGPOINT, 276),
+  CURLOPT(CURLOPT_PROXY_TLS13_CIPHERS, CURLOPTTYPE_STRINGPOINT, 277),
 
   /* Disallow specifying username/login in URL. */
-  CINIT(DISALLOW_USERNAME_IN_URL, LONG, 278),
+  CURLOPT(CURLOPT_DISALLOW_USERNAME_IN_URL, CURLOPTTYPE_LONG, 278),
 
   /* DNS-over-HTTPS URL */
-  CINIT(DOH_URL, STRINGPOINT, 279),
+  CURLOPT(CURLOPT_DOH_URL, CURLOPTTYPE_STRINGPOINT, 279),
 
   /* Preferred buffer size to use for uploads */
-  CINIT(UPLOAD_BUFFERSIZE, LONG, 280),
+  CURLOPT(CURLOPT_UPLOAD_BUFFERSIZE, CURLOPTTYPE_LONG, 280),
 
   /* Time in ms between connection upkeep calls for long-lived connections. */
-  CINIT(UPKEEP_INTERVAL_MS, LONG, 281),
+  CURLOPT(CURLOPT_UPKEEP_INTERVAL_MS, CURLOPTTYPE_LONG, 281),
 
   /* Specify URL using CURL URL API. */
-  CINIT(CURLU, OBJECTPOINT, 282),
+  CURLOPT(CURLOPT_CURLU, CURLOPTTYPE_OBJECTPOINT, 282),
 
   /* add trailing data just after no more data is available */
-  CINIT(TRAILERFUNCTION, FUNCTIONPOINT, 283),
+  CURLOPT(CURLOPT_TRAILERFUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 283),
 
   /* pointer to be passed to HTTP_TRAILER_FUNCTION */
-  CINIT(TRAILERDATA, OBJECTPOINT, 284),
+  CURLOPT(CURLOPT_TRAILERDATA, CURLOPTTYPE_OBJECTPOINT, 284),
 
   /* set this to 1L to allow HTTP/0.9 responses or 0L to disallow */
-  CINIT(HTTP09_ALLOWED, LONG, 285),
+  CURLOPT(CURLOPT_HTTP09_ALLOWED, CURLOPTTYPE_LONG, 285),
 
   /* alt-svc control bitmask */
-  CINIT(ALTSVC_CTRL, LONG, 286),
+  CURLOPT(CURLOPT_ALTSVC_CTRL, CURLOPTTYPE_LONG, 286),
 
   /* alt-svc cache file name to possibly read from/write to */
-  CINIT(ALTSVC, STRINGPOINT, 287),
+  CURLOPT(CURLOPT_ALTSVC, CURLOPTTYPE_STRINGPOINT, 287),
 
   /* maximum age of a connection to consider it for reuse (in seconds) */
-  CINIT(MAXAGE_CONN, LONG, 288),
+  CURLOPT(CURLOPT_MAXAGE_CONN, CURLOPTTYPE_LONG, 288),
+
+  /* SASL authorisation identity */
+  CURLOPT(CURLOPT_SASL_AUTHZID, CURLOPTTYPE_STRINGPOINT, 289),
+
+  /* allow RCPT TO command to fail for some recipients */
+  CURLOPT(CURLOPT_MAIL_RCPT_ALLLOWFAILS, CURLOPTTYPE_LONG, 290),
+
+  /* the private SSL-certificate as a "blob" */
+  CURLOPT(CURLOPT_SSLCERT_BLOB, CURLOPTTYPE_BLOB, 291),
+  CURLOPT(CURLOPT_SSLKEY_BLOB, CURLOPTTYPE_BLOB, 292),
+  CURLOPT(CURLOPT_PROXY_SSLCERT_BLOB, CURLOPTTYPE_BLOB, 293),
+  CURLOPT(CURLOPT_PROXY_SSLKEY_BLOB, CURLOPTTYPE_BLOB, 294),
+  CURLOPT(CURLOPT_ISSUERCERT_BLOB, CURLOPTTYPE_BLOB, 295),
+
+  /* Issuer certificate for proxy */
+  CURLOPT(CURLOPT_PROXY_ISSUERCERT, CURLOPTTYPE_STRINGPOINT, 296),
+  CURLOPT(CURLOPT_PROXY_ISSUERCERT_BLOB, CURLOPTTYPE_BLOB, 297),
 
   CURLOPT_LASTENTRY /* the last unused */
 } CURLoption;
@@ -1974,7 +2024,8 @@
   CURL_HTTP_VERSION_2TLS, /* use version 2 for HTTPS, version 1.1 for HTTP */
   CURL_HTTP_VERSION_2_PRIOR_KNOWLEDGE,  /* please use HTTP 2 without HTTP/1.1
                                            Upgrade */
-
+  CURL_HTTP_VERSION_3 = 30, /* Makes use of explicit HTTP/3 without fallback.
+                               Use CURLOPT_ALTSVC to enable HTTP/3 upgrade */
   CURL_HTTP_VERSION_LAST /* *ILLEGAL* http version */
 };
 
@@ -2067,7 +2118,7 @@
   CURL_TIMECOND_LAST
 } curl_TimeCond;
 
-/* Special size_t value signaling a zero-terminated string. */
+/* Special size_t value signaling a null-terminated string. */
 #define CURL_ZERO_TERMINATED ((size_t) -1)
 
 /* curl_strequal() and curl_strnequal() are subject for removal in a future
@@ -2076,8 +2127,8 @@
 CURL_EXTERN int curl_strnequal(const char *s1, const char *s2, size_t n);
 
 /* Mime/form handling support. */
-typedef struct curl_mime_s      curl_mime;      /* Mime context. */
-typedef struct curl_mimepart_s  curl_mimepart;  /* Mime part context. */
+typedef struct curl_mime      curl_mime;      /* Mime context. */
+typedef struct curl_mimepart  curl_mimepart;  /* Mime part context. */
 
 /*
  * NAME curl_mime_init()
@@ -2200,52 +2251,35 @@
                                        struct curl_slist *headers,
                                        int take_ownership);
 
-/* Old form API. */
-/* name is uppercase CURLFORM_<name> */
-#ifdef CFINIT
-#undef CFINIT
-#endif
-
-#ifdef CURL_ISOCPP
-#define CFINIT(name) CURLFORM_ ## name
-#else
-/* The macro "##" is ISO C, we assume pre-ISO C doesn't support it. */
-#define CFINIT(name) CURLFORM_/**/name
-#endif
-
 typedef enum {
-  CFINIT(NOTHING),        /********* the first one is unused ************/
+  CURLFORM_NOTHING,        /********* the first one is unused ************/
+  CURLFORM_COPYNAME,
+  CURLFORM_PTRNAME,
+  CURLFORM_NAMELENGTH,
+  CURLFORM_COPYCONTENTS,
+  CURLFORM_PTRCONTENTS,
+  CURLFORM_CONTENTSLENGTH,
+  CURLFORM_FILECONTENT,
+  CURLFORM_ARRAY,
+  CURLFORM_OBSOLETE,
+  CURLFORM_FILE,
 
-  /*  */
-  CFINIT(COPYNAME),
-  CFINIT(PTRNAME),
-  CFINIT(NAMELENGTH),
-  CFINIT(COPYCONTENTS),
-  CFINIT(PTRCONTENTS),
-  CFINIT(CONTENTSLENGTH),
-  CFINIT(FILECONTENT),
-  CFINIT(ARRAY),
-  CFINIT(OBSOLETE),
-  CFINIT(FILE),
+  CURLFORM_BUFFER,
+  CURLFORM_BUFFERPTR,
+  CURLFORM_BUFFERLENGTH,
 
-  CFINIT(BUFFER),
-  CFINIT(BUFFERPTR),
-  CFINIT(BUFFERLENGTH),
+  CURLFORM_CONTENTTYPE,
+  CURLFORM_CONTENTHEADER,
+  CURLFORM_FILENAME,
+  CURLFORM_END,
+  CURLFORM_OBSOLETE2,
 
-  CFINIT(CONTENTTYPE),
-  CFINIT(CONTENTHEADER),
-  CFINIT(FILENAME),
-  CFINIT(END),
-  CFINIT(OBSOLETE2),
-
-  CFINIT(STREAM),
-  CFINIT(CONTENTLEN), /* added in 7.46.0, provide a curl_off_t length */
+  CURLFORM_STREAM,
+  CURLFORM_CONTENTLEN, /* added in 7.46.0, provide a curl_off_t length */
 
   CURLFORM_LASTENTRY /* the last unused */
 } CURLformoption;
 
-#undef CFINIT /* done */
-
 /* structure to be used as parameter for CURLFORM_ARRAY */
 struct curl_forms {
   CURLformoption option;
@@ -2416,7 +2450,7 @@
  * initialize libcurl and set user defined memory management callback
  * functions.  Users can implement memory management routines to check for
  * memory leaks, check for mis-use of the curl library etc.  User registered
- * callback routines with be invoked by this library instead of the system
+ * callback routines will be invoked by this library instead of the system
  * memory management routines like malloc, free etc.
  */
 CURL_EXTERN CURLcode curl_global_init_mem(long flags,
@@ -2468,10 +2502,11 @@
  * subsequent attempt to change it will result in a CURLSSLSET_TOO_LATE.
  */
 
-typedef struct {
+struct curl_ssl_backend {
   curl_sslbackend id;
   const char *name;
-} curl_ssl_backend;
+};
+typedef struct curl_ssl_backend curl_ssl_backend;
 
 typedef enum {
   CURLSSLSET_OK = 0,
@@ -2514,8 +2549,8 @@
  */
 CURL_EXTERN time_t curl_getdate(const char *p, const time_t *unused);
 
-/* info about the certificate chain, only for OpenSSL builds. Asked
-   for with CURLOPT_CERTINFO / CURLINFO_CERTINFO */
+/* info about the certificate chain, only for OpenSSL, GnuTLS, Schannel, NSS
+   and GSKit builds. Asked for with CURLOPT_CERTINFO / CURLINFO_CERTINFO */
 struct curl_certinfo {
   int num_of_certs;             /* number of certificates with information */
   struct curl_slist **certinfo; /* for each index in this array, there's a
@@ -2610,8 +2645,9 @@
   CURLINFO_STARTTRANSFER_TIME_T = CURLINFO_OFF_T + 54,
   CURLINFO_REDIRECT_TIME_T  = CURLINFO_OFF_T + 55,
   CURLINFO_APPCONNECT_TIME_T = CURLINFO_OFF_T + 56,
+  CURLINFO_RETRY_AFTER      = CURLINFO_OFF_T + 57,
 
-  CURLINFO_LASTONE          = 56
+  CURLINFO_LASTONE          = 57
 } CURLINFO;
 
 /* CURLINFO_RESPONSE_CODE is the new name for the option previously known as
@@ -2710,6 +2746,8 @@
   CURLVERSION_THIRD,
   CURLVERSION_FOURTH,
   CURLVERSION_FIFTH,
+  CURLVERSION_SIXTH,
+  CURLVERSION_SEVENTH,
   CURLVERSION_LAST /* never actually use this */
 } CURLversion;
 
@@ -2718,9 +2756,9 @@
    meant to be a built-in version number for what kind of struct the caller
    expects. If the struct ever changes, we redefine the NOW to another enum
    from above. */
-#define CURLVERSION_NOW CURLVERSION_FIFTH
+#define CURLVERSION_NOW CURLVERSION_SEVENTH
 
-typedef struct {
+struct curl_version_info_data {
   CURLversion age;          /* age of the returned struct */
   const char *version;      /* LIBCURL_VERSION */
   unsigned int version_num; /* LIBCURL_VERSION_NUM */
@@ -2747,12 +2785,25 @@
   const char *libssh_version; /* human readable string */
 
   /* These fields were added in CURLVERSION_FIFTH */
-
   unsigned int brotli_ver_num; /* Numeric Brotli version
                                   (MAJOR << 24) | (MINOR << 12) | PATCH */
   const char *brotli_version; /* human readable string. */
 
-} curl_version_info_data;
+  /* These fields were added in CURLVERSION_SIXTH */
+  unsigned int nghttp2_ver_num; /* Numeric nghttp2 version
+                                   (MAJOR << 16) | (MINOR << 8) | PATCH */
+  const char *nghttp2_version; /* human readable string. */
+  const char *quic_version;    /* human readable quic (+ HTTP/3) library +
+                                  version or NULL */
+
+  /* These fields were added in CURLVERSION_SEVENTH */
+  const char *cainfo;          /* the built-in default CURLOPT_CAINFO, might
+                                  be NULL */
+  const char *capath;          /* the built-in default CURLOPT_CAPATH, might
+                                  be NULL */
+
+};
+typedef struct curl_version_info_data curl_version_info_data;
 
 #define CURL_VERSION_IPV6         (1<<0)  /* IPv6-enabled */
 #define CURL_VERSION_KERBEROS4    (1<<1)  /* Kerberos V4 auth is supported
@@ -2784,6 +2835,7 @@
 #define CURL_VERSION_MULTI_SSL    (1<<22) /* Multiple SSL backends available */
 #define CURL_VERSION_BROTLI       (1<<23) /* Brotli features are present. */
 #define CURL_VERSION_ALTSVC       (1<<24) /* Alt-Svc handling built-in */
+#define CURL_VERSION_HTTP3        (1<<25) /* HTTP3 support built-in */
 
  /*
  * NAME curl_version_info()
@@ -2866,4 +2918,4 @@
 #endif /* __STDC__ >= 1 */
 #endif /* gcc >= 4.3 && !__cplusplus */
 
-#endif /* __CURL_CURL_H */
+#endif /* CURLINC_CURL_H */
diff --git a/Utilities/cmcurl/include/curl/curlver.h b/Utilities/cmcurl/include/curl/curlver.h
index 04efb93..97a8bd8 100644
--- a/Utilities/cmcurl/include/curl/curlver.h
+++ b/Utilities/cmcurl/include/curl/curlver.h
@@ -1,5 +1,5 @@
-#ifndef __CURL_CURLVER_H
-#define __CURL_CURLVER_H
+#ifndef CURLINC_CURLVER_H
+#define CURLINC_CURLVER_H
 /***************************************************************************
  *                                  _   _ ____  _
  *  Project                     ___| | | |  _ \| |
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -26,20 +26,20 @@
    a script at release-time. This was made its own header file in 7.11.2 */
 
 /* This is the global package copyright */
-#define LIBCURL_COPYRIGHT "1996 - 2019 Daniel Stenberg, <daniel@haxx.se>."
+#define LIBCURL_COPYRIGHT "1996 - 2020 Daniel Stenberg, <daniel@haxx.se>."
 
 /* This is the version number of the libcurl package from which this header
    file origins: */
-#define LIBCURL_VERSION "7.65.0"
+#define LIBCURL_VERSION "7.71.1"
 
 /* The numeric version number is also available "in parts" by using these
    defines: */
 #define LIBCURL_VERSION_MAJOR 7
-#define LIBCURL_VERSION_MINOR 65
-#define LIBCURL_VERSION_PATCH 0
+#define LIBCURL_VERSION_MINOR 71
+#define LIBCURL_VERSION_PATCH 1
 
 /* This is the numeric version of the libcurl version number, meant for easier
-   parsing and comparions by programs. The LIBCURL_VERSION_NUM define will
+   parsing and comparisons by programs. The LIBCURL_VERSION_NUM define will
    always follow this syntax:
 
          0xXXYYZZ
@@ -57,7 +57,7 @@
    CURL_VERSION_BITS() macro since curl's own configure script greps for it
    and needs it to contain the full number.
 */
-#define LIBCURL_VERSION_NUM 0x074100
+#define LIBCURL_VERSION_NUM 0x074701
 
 /*
  * This is the date and time when the full source package was created. The
@@ -74,4 +74,4 @@
 #define CURL_AT_LEAST_VERSION(x,y,z) \
   (LIBCURL_VERSION_NUM >= CURL_VERSION_BITS(x, y, z))
 
-#endif /* __CURL_CURLVER_H */
+#endif /* CURLINC_CURLVER_H */
diff --git a/Utilities/cmcurl/include/curl/easy.h b/Utilities/cmcurl/include/curl/easy.h
index f42a8a9..9aef133 100644
--- a/Utilities/cmcurl/include/curl/easy.h
+++ b/Utilities/cmcurl/include/curl/easy.h
@@ -1,5 +1,5 @@
-#ifndef __CURL_EASY_H
-#define __CURL_EASY_H
+#ifndef CURLINC_EASY_H
+#define CURLINC_EASY_H
 /***************************************************************************
  *                                  _   _ ____  _
  *  Project                     ___| | | |  _ \| |
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -25,6 +25,17 @@
 extern "C" {
 #endif
 
+/* Flag bits in the curl_blob struct: */
+#define CURL_BLOB_COPY   1 /* tell libcurl to copy the data */
+#define CURL_BLOB_NOCOPY 0 /* tell libcurl to NOT copy the data */
+
+struct curl_blob {
+  void *data;
+  size_t len;
+  unsigned int flags; /* bit 0 is defined, the rest are reserved and should be
+                         left zeroes */
+};
+
 CURL_EXTERN CURL *curl_easy_init(void);
 CURL_EXTERN CURLcode curl_easy_setopt(CURL *curl, CURLoption option, ...);
 CURL_EXTERN CURLcode curl_easy_perform(CURL *curl);
diff --git a/Utilities/cmcurl/include/curl/mprintf.h b/Utilities/cmcurl/include/curl/mprintf.h
index e20f546..f615ed7 100644
--- a/Utilities/cmcurl/include/curl/mprintf.h
+++ b/Utilities/cmcurl/include/curl/mprintf.h
@@ -1,5 +1,5 @@
-#ifndef __CURL_MPRINTF_H
-#define __CURL_MPRINTF_H
+#ifndef CURLINC_MPRINTF_H
+#define CURLINC_MPRINTF_H
 /***************************************************************************
  *                                  _   _ ____  _
  *  Project                     ___| | | |  _ \| |
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -47,4 +47,4 @@
 }
 #endif
 
-#endif /* __CURL_MPRINTF_H */
+#endif /* CURLINC_MPRINTF_H */
diff --git a/Utilities/cmcurl/include/curl/multi.h b/Utilities/cmcurl/include/curl/multi.h
index b19dbaf..2e6bb72 100644
--- a/Utilities/cmcurl/include/curl/multi.h
+++ b/Utilities/cmcurl/include/curl/multi.h
@@ -1,5 +1,5 @@
-#ifndef __CURL_MULTI_H
-#define __CURL_MULTI_H
+#ifndef CURLINC_MULTI_H
+#define CURLINC_MULTI_H
 /***************************************************************************
  *                                  _   _ ____  _
  *  Project                     ___| | | |  _ \| |
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -72,6 +72,8 @@
                             attempted to get added - again */
   CURLM_RECURSIVE_API_CALL, /* an api function was called from inside a
                                callback */
+  CURLM_WAKEUP_FAILURE,  /* wakeup is unavailable or failed */
+  CURLM_BAD_FUNCTION_ARGUMENT,  /* function called with a bad parameter */
   CURLM_LAST
 } CURLMcode;
 
@@ -173,6 +175,29 @@
                                       int timeout_ms,
                                       int *ret);
 
+/*
+ * Name:     curl_multi_poll()
+ *
+ * Desc:     Poll on all fds within a CURLM set as well as any
+ *           additional fds passed to the function.
+ *
+ * Returns:  CURLMcode type, general multi error code.
+ */
+CURL_EXTERN CURLMcode curl_multi_poll(CURLM *multi_handle,
+                                      struct curl_waitfd extra_fds[],
+                                      unsigned int extra_nfds,
+                                      int timeout_ms,
+                                      int *ret);
+
+/*
+ * Name:     curl_multi_wakeup()
+ *
+ * Desc:     wakes up a sleeping curl_multi_poll call.
+ *
+ * Returns:  CURLMcode type, general multi error code.
+ */
+CURL_EXTERN CURLMcode curl_multi_wakeup(CURLM *multi_handle);
+
  /*
   * Name:    curl_multi_perform()
   *
@@ -242,7 +267,7 @@
  *          value into the equivalent human readable error string.  This is
  *          useful for printing meaningful error messages.
  *
- * Returns: A pointer to a zero-terminated error message.
+ * Returns: A pointer to a null-terminated error message.
  */
 CURL_EXTERN const char *curl_multi_strerror(CURLMcode);
 
@@ -319,68 +344,56 @@
 CURL_EXTERN CURLMcode curl_multi_timeout(CURLM *multi_handle,
                                          long *milliseconds);
 
-#undef CINIT /* re-using the same name as in curl.h */
-
-#ifdef CURL_ISOCPP
-#define CINIT(name,type,num) CURLMOPT_ ## name = CURLOPTTYPE_ ## type + num
-#else
-/* The macro "##" is ISO C, we assume pre-ISO C doesn't support it. */
-#define LONG          CURLOPTTYPE_LONG
-#define OBJECTPOINT   CURLOPTTYPE_OBJECTPOINT
-#define FUNCTIONPOINT CURLOPTTYPE_FUNCTIONPOINT
-#define OFF_T         CURLOPTTYPE_OFF_T
-#define CINIT(name,type,number) CURLMOPT_/**/name = type + number
-#endif
-
 typedef enum {
   /* This is the socket callback function pointer */
-  CINIT(SOCKETFUNCTION, FUNCTIONPOINT, 1),
+  CURLOPT(CURLMOPT_SOCKETFUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 1),
 
   /* This is the argument passed to the socket callback */
-  CINIT(SOCKETDATA, OBJECTPOINT, 2),
+  CURLOPT(CURLMOPT_SOCKETDATA, CURLOPTTYPE_OBJECTPOINT, 2),
 
     /* set to 1 to enable pipelining for this multi handle */
-  CINIT(PIPELINING, LONG, 3),
+  CURLOPT(CURLMOPT_PIPELINING, CURLOPTTYPE_LONG, 3),
 
    /* This is the timer callback function pointer */
-  CINIT(TIMERFUNCTION, FUNCTIONPOINT, 4),
+  CURLOPT(CURLMOPT_TIMERFUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 4),
 
   /* This is the argument passed to the timer callback */
-  CINIT(TIMERDATA, OBJECTPOINT, 5),
+  CURLOPT(CURLMOPT_TIMERDATA, CURLOPTTYPE_OBJECTPOINT, 5),
 
   /* maximum number of entries in the connection cache */
-  CINIT(MAXCONNECTS, LONG, 6),
+  CURLOPT(CURLMOPT_MAXCONNECTS, CURLOPTTYPE_LONG, 6),
 
   /* maximum number of (pipelining) connections to one host */
-  CINIT(MAX_HOST_CONNECTIONS, LONG, 7),
+  CURLOPT(CURLMOPT_MAX_HOST_CONNECTIONS, CURLOPTTYPE_LONG, 7),
 
   /* maximum number of requests in a pipeline */
-  CINIT(MAX_PIPELINE_LENGTH, LONG, 8),
+  CURLOPT(CURLMOPT_MAX_PIPELINE_LENGTH, CURLOPTTYPE_LONG, 8),
 
   /* a connection with a content-length longer than this
      will not be considered for pipelining */
-  CINIT(CONTENT_LENGTH_PENALTY_SIZE, OFF_T, 9),
+  CURLOPT(CURLMOPT_CONTENT_LENGTH_PENALTY_SIZE, CURLOPTTYPE_OFF_T, 9),
 
   /* a connection with a chunk length longer than this
      will not be considered for pipelining */
-  CINIT(CHUNK_LENGTH_PENALTY_SIZE, OFF_T, 10),
+  CURLOPT(CURLMOPT_CHUNK_LENGTH_PENALTY_SIZE, CURLOPTTYPE_OFF_T, 10),
 
-  /* a list of site names(+port) that are blacklisted from
-     pipelining */
-  CINIT(PIPELINING_SITE_BL, OBJECTPOINT, 11),
+  /* a list of site names(+port) that are blocked from pipelining */
+  CURLOPT(CURLMOPT_PIPELINING_SITE_BL, CURLOPTTYPE_OBJECTPOINT, 11),
 
-  /* a list of server types that are blacklisted from
-     pipelining */
-  CINIT(PIPELINING_SERVER_BL, OBJECTPOINT, 12),
+  /* a list of server types that are blocked from pipelining */
+  CURLOPT(CURLMOPT_PIPELINING_SERVER_BL, CURLOPTTYPE_OBJECTPOINT, 12),
 
   /* maximum number of open connections in total */
-  CINIT(MAX_TOTAL_CONNECTIONS, LONG, 13),
+  CURLOPT(CURLMOPT_MAX_TOTAL_CONNECTIONS, CURLOPTTYPE_LONG, 13),
 
    /* This is the server push callback function pointer */
-  CINIT(PUSHFUNCTION, FUNCTIONPOINT, 14),
+  CURLOPT(CURLMOPT_PUSHFUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 14),
 
   /* This is the argument passed to the server push callback */
-  CINIT(PUSHDATA, OBJECTPOINT, 15),
+  CURLOPT(CURLMOPT_PUSHDATA, CURLOPTTYPE_OBJECTPOINT, 15),
+
+  /* maximum number of concurrent streams to support on a connection */
+  CURLOPT(CURLMOPT_MAX_CONCURRENT_STREAMS, CURLOPTTYPE_LONG, 16),
 
   CURLMOPT_LASTENTRY /* the last unused */
 } CURLMoption;
diff --git a/Utilities/cmcurl/include/curl/stdcheaders.h b/Utilities/cmcurl/include/curl/stdcheaders.h
index 027b6f4..a6bdc1a 100644
--- a/Utilities/cmcurl/include/curl/stdcheaders.h
+++ b/Utilities/cmcurl/include/curl/stdcheaders.h
@@ -1,5 +1,5 @@
-#ifndef __STDC_HEADERS_H
-#define __STDC_HEADERS_H
+#ifndef CURLINC_STDCHEADERS_H
+#define CURLINC_STDCHEADERS_H
 /***************************************************************************
  *                                  _   _ ____  _
  *  Project                     ___| | | |  _ \| |
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -30,4 +30,4 @@
 int strcasecmp(const char *, const char *);
 int strncasecmp(const char *, const char *, size_t);
 
-#endif /* __STDC_HEADERS_H */
+#endif /* CURLINC_STDCHEADERS_H */
diff --git a/Utilities/cmcurl/include/curl/system.h b/Utilities/cmcurl/include/curl/system.h
index 1e555ec..867af61 100644
--- a/Utilities/cmcurl/include/curl/system.h
+++ b/Utilities/cmcurl/include/curl/system.h
@@ -1,5 +1,5 @@
-#ifndef __CURL_SYSTEM_H
-#define __CURL_SYSTEM_H
+#ifndef CURLINC_SYSTEM_H
+#define CURLINC_SYSTEM_H
 /***************************************************************************
  *                                  _   _ ____  _
  *  Project                     ___| | | |  _ \| |
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -137,15 +137,26 @@
 #  define CURL_TYPEOF_CURL_SOCKLEN_T int
 
 #elif defined(__LCC__)
-#  define CURL_TYPEOF_CURL_OFF_T     long
-#  define CURL_FORMAT_CURL_OFF_T     "ld"
-#  define CURL_FORMAT_CURL_OFF_TU    "lu"
-#  define CURL_SUFFIX_CURL_OFF_T     L
-#  define CURL_SUFFIX_CURL_OFF_TU    UL
-#  define CURL_TYPEOF_CURL_SOCKLEN_T int
+#  if defined(__e2k__) /* MCST eLbrus C Compiler */
+#    define CURL_TYPEOF_CURL_OFF_T     long
+#    define CURL_FORMAT_CURL_OFF_T     "ld"
+#    define CURL_FORMAT_CURL_OFF_TU    "lu"
+#    define CURL_SUFFIX_CURL_OFF_T     L
+#    define CURL_SUFFIX_CURL_OFF_TU    UL
+#    define CURL_TYPEOF_CURL_SOCKLEN_T socklen_t
+#    define CURL_PULL_SYS_TYPES_H      1
+#    define CURL_PULL_SYS_SOCKET_H     1
+#  else                /* Local (or Little) C Compiler */
+#    define CURL_TYPEOF_CURL_OFF_T     long
+#    define CURL_FORMAT_CURL_OFF_T     "ld"
+#    define CURL_FORMAT_CURL_OFF_TU    "lu"
+#    define CURL_SUFFIX_CURL_OFF_T     L
+#    define CURL_SUFFIX_CURL_OFF_TU    UL
+#    define CURL_TYPEOF_CURL_SOCKLEN_T int
+#  endif
 
 #elif defined(__SYMBIAN32__)
-#  if defined(__EABI__)  /* Treat all ARM compilers equally */
+#  if defined(__EABI__) /* Treat all ARM compilers equally */
 #    define CURL_TYPEOF_CURL_OFF_T     long long
 #    define CURL_FORMAT_CURL_OFF_T     "lld"
 #    define CURL_FORMAT_CURL_OFF_TU    "llu"
@@ -288,7 +299,6 @@
 #  define CURL_TYPEOF_CURL_SOCKLEN_T int
 
 #elif defined(__TINYC__) /* also known as tcc */
-
 #  define CURL_TYPEOF_CURL_OFF_T     long long
 #  define CURL_FORMAT_CURL_OFF_T     "lld"
 #  define CURL_FORMAT_CURL_OFF_TU    "llu"
@@ -377,6 +387,7 @@
 #    define CURL_SUFFIX_CURL_OFF_TU    ULL
 #  elif defined(__LP64__) || \
         defined(__x86_64__) || defined(__ppc64__) || defined(__sparc64__) || \
+        defined(__e2k__) || \
         (defined(__SIZEOF_LONG__) && __SIZEOF_LONG__ == 8) || \
         (defined(__LONG_MAX__) && __LONG_MAX__ == 9223372036854775807L)
 #    define CURL_TYPEOF_CURL_OFF_T     long
@@ -473,21 +484,21 @@
  */
 
 #if defined(__BORLANDC__) && (__BORLANDC__ == 0x0551)
-#  define __CURL_OFF_T_C_HLPR2(x) x
-#  define __CURL_OFF_T_C_HLPR1(x) __CURL_OFF_T_C_HLPR2(x)
-#  define CURL_OFF_T_C(Val)  __CURL_OFF_T_C_HLPR1(Val) ## \
-                             __CURL_OFF_T_C_HLPR1(CURL_SUFFIX_CURL_OFF_T)
-#  define CURL_OFF_TU_C(Val) __CURL_OFF_T_C_HLPR1(Val) ## \
-                             __CURL_OFF_T_C_HLPR1(CURL_SUFFIX_CURL_OFF_TU)
+#  define CURLINC_OFF_T_C_HLPR2(x) x
+#  define CURLINC_OFF_T_C_HLPR1(x) CURLINC_OFF_T_C_HLPR2(x)
+#  define CURL_OFF_T_C(Val)  CURLINC_OFF_T_C_HLPR1(Val) ## \
+                             CURLINC_OFF_T_C_HLPR1(CURL_SUFFIX_CURL_OFF_T)
+#  define CURL_OFF_TU_C(Val) CURLINC_OFF_T_C_HLPR1(Val) ## \
+                             CURLINC_OFF_T_C_HLPR1(CURL_SUFFIX_CURL_OFF_TU)
 #else
 #  ifdef CURL_ISOCPP
-#    define __CURL_OFF_T_C_HLPR2(Val,Suffix) Val ## Suffix
+#    define CURLINC_OFF_T_C_HLPR2(Val,Suffix) Val ## Suffix
 #  else
-#    define __CURL_OFF_T_C_HLPR2(Val,Suffix) Val/**/Suffix
+#    define CURLINC_OFF_T_C_HLPR2(Val,Suffix) Val/**/Suffix
 #  endif
-#  define __CURL_OFF_T_C_HLPR1(Val,Suffix) __CURL_OFF_T_C_HLPR2(Val,Suffix)
-#  define CURL_OFF_T_C(Val)  __CURL_OFF_T_C_HLPR1(Val,CURL_SUFFIX_CURL_OFF_T)
-#  define CURL_OFF_TU_C(Val) __CURL_OFF_T_C_HLPR1(Val,CURL_SUFFIX_CURL_OFF_TU)
+#  define CURLINC_OFF_T_C_HLPR1(Val,Suffix) CURLINC_OFF_T_C_HLPR2(Val,Suffix)
+#  define CURL_OFF_T_C(Val)  CURLINC_OFF_T_C_HLPR1(Val,CURL_SUFFIX_CURL_OFF_T)
+#  define CURL_OFF_TU_C(Val) CURLINC_OFF_T_C_HLPR1(Val,CURL_SUFFIX_CURL_OFF_TU)
 #endif
 
-#endif /* __CURL_SYSTEM_H */
+#endif /* CURLINC_SYSTEM_H */
diff --git a/Utilities/cmcurl/include/curl/typecheck-gcc.h b/Utilities/cmcurl/include/curl/typecheck-gcc.h
index 2d1de4d..f8cb921 100644
--- a/Utilities/cmcurl/include/curl/typecheck-gcc.h
+++ b/Utilities/cmcurl/include/curl/typecheck-gcc.h
@@ -1,5 +1,5 @@
-#ifndef __CURL_TYPECHECK_GCC_H
-#define __CURL_TYPECHECK_GCC_H
+#ifndef CURLINC_TYPECHECK_GCC_H
+#define CURLINC_TYPECHECK_GCC_H
 /***************************************************************************
  *                                  _   _ ____  _
  *  Project                     ___| | | |  _ \| |
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -25,10 +25,10 @@
 /* wraps curl_easy_setopt() with typechecking */
 
 /* To add a new kind of warning, add an
- *   if(_curl_is_sometype_option(_curl_opt))
- *     if(!_curl_is_sometype(value))
+ *   if(curlcheck_sometype_option(_curl_opt))
+ *     if(!curlcheck_sometype(value))
  *       _curl_easy_setopt_err_sometype();
- * block and define _curl_is_sometype_option, _curl_is_sometype and
+ * block and define curlcheck_sometype_option, curlcheck_sometype and
  * _curl_easy_setopt_err_sometype below
  *
  * NOTE: We use two nested 'if' statements here instead of the && operator, in
@@ -38,112 +38,112 @@
  * To add an option that uses the same type as an existing option, you'll just
  * need to extend the appropriate _curl_*_option macro
  */
-#define curl_easy_setopt(handle, option, value)                               \
-__extension__ ({                                                              \
-  __typeof__(option) _curl_opt = option;                                     \
-  if(__builtin_constant_p(_curl_opt)) {                                       \
-    if(_curl_is_long_option(_curl_opt))                                       \
-      if(!_curl_is_long(value))                                               \
-        _curl_easy_setopt_err_long();                                         \
-    if(_curl_is_off_t_option(_curl_opt))                                      \
-      if(!_curl_is_off_t(value))                                              \
-        _curl_easy_setopt_err_curl_off_t();                                   \
-    if(_curl_is_string_option(_curl_opt))                                     \
-      if(!_curl_is_string(value))                                             \
-        _curl_easy_setopt_err_string();                                       \
-    if(_curl_is_write_cb_option(_curl_opt))                                   \
-      if(!_curl_is_write_cb(value))                                           \
-        _curl_easy_setopt_err_write_callback();                               \
-    if((_curl_opt) == CURLOPT_RESOLVER_START_FUNCTION)                        \
-      if(!_curl_is_resolver_start_callback(value))                            \
-        _curl_easy_setopt_err_resolver_start_callback();                      \
-    if((_curl_opt) == CURLOPT_READFUNCTION)                                   \
-      if(!_curl_is_read_cb(value))                                            \
-        _curl_easy_setopt_err_read_cb();                                      \
-    if((_curl_opt) == CURLOPT_IOCTLFUNCTION)                                  \
-      if(!_curl_is_ioctl_cb(value))                                           \
-        _curl_easy_setopt_err_ioctl_cb();                                     \
-    if((_curl_opt) == CURLOPT_SOCKOPTFUNCTION)                                \
-      if(!_curl_is_sockopt_cb(value))                                         \
-        _curl_easy_setopt_err_sockopt_cb();                                   \
-    if((_curl_opt) == CURLOPT_OPENSOCKETFUNCTION)                             \
-      if(!_curl_is_opensocket_cb(value))                                      \
-        _curl_easy_setopt_err_opensocket_cb();                                \
-    if((_curl_opt) == CURLOPT_PROGRESSFUNCTION)                               \
-      if(!_curl_is_progress_cb(value))                                        \
-        _curl_easy_setopt_err_progress_cb();                                  \
-    if((_curl_opt) == CURLOPT_DEBUGFUNCTION)                                  \
-      if(!_curl_is_debug_cb(value))                                           \
-        _curl_easy_setopt_err_debug_cb();                                     \
-    if((_curl_opt) == CURLOPT_SSL_CTX_FUNCTION)                               \
-      if(!_curl_is_ssl_ctx_cb(value))                                         \
-        _curl_easy_setopt_err_ssl_ctx_cb();                                   \
-    if(_curl_is_conv_cb_option(_curl_opt))                                    \
-      if(!_curl_is_conv_cb(value))                                            \
-        _curl_easy_setopt_err_conv_cb();                                      \
-    if((_curl_opt) == CURLOPT_SEEKFUNCTION)                                   \
-      if(!_curl_is_seek_cb(value))                                            \
-        _curl_easy_setopt_err_seek_cb();                                      \
-    if(_curl_is_cb_data_option(_curl_opt))                                    \
-      if(!_curl_is_cb_data(value))                                            \
-        _curl_easy_setopt_err_cb_data();                                      \
-    if((_curl_opt) == CURLOPT_ERRORBUFFER)                                    \
-      if(!_curl_is_error_buffer(value))                                       \
-        _curl_easy_setopt_err_error_buffer();                                 \
-    if((_curl_opt) == CURLOPT_STDERR)                                         \
-      if(!_curl_is_FILE(value))                                               \
-        _curl_easy_setopt_err_FILE();                                         \
-    if(_curl_is_postfields_option(_curl_opt))                                 \
-      if(!_curl_is_postfields(value))                                         \
-        _curl_easy_setopt_err_postfields();                                   \
-    if((_curl_opt) == CURLOPT_HTTPPOST)                                       \
-      if(!_curl_is_arr((value), struct curl_httppost))                        \
-        _curl_easy_setopt_err_curl_httpost();                                 \
-    if((_curl_opt) == CURLOPT_MIMEPOST)                                       \
-      if(!_curl_is_ptr((value), curl_mime))                                   \
-        _curl_easy_setopt_err_curl_mimepost();                                \
-    if(_curl_is_slist_option(_curl_opt))                                      \
-      if(!_curl_is_arr((value), struct curl_slist))                           \
-        _curl_easy_setopt_err_curl_slist();                                   \
-    if((_curl_opt) == CURLOPT_SHARE)                                          \
-      if(!_curl_is_ptr((value), CURLSH))                                      \
-        _curl_easy_setopt_err_CURLSH();                                       \
-  }                                                                           \
-  curl_easy_setopt(handle, _curl_opt, value);                                 \
-})
+#define curl_easy_setopt(handle, option, value)                         \
+  __extension__({                                                       \
+      __typeof__(option) _curl_opt = option;                            \
+      if(__builtin_constant_p(_curl_opt)) {                             \
+        if(curlcheck_long_option(_curl_opt))                            \
+          if(!curlcheck_long(value))                                    \
+            _curl_easy_setopt_err_long();                               \
+        if(curlcheck_off_t_option(_curl_opt))                           \
+          if(!curlcheck_off_t(value))                                   \
+            _curl_easy_setopt_err_curl_off_t();                         \
+        if(curlcheck_string_option(_curl_opt))                          \
+          if(!curlcheck_string(value))                                  \
+            _curl_easy_setopt_err_string();                             \
+        if(curlcheck_write_cb_option(_curl_opt))                        \
+          if(!curlcheck_write_cb(value))                                \
+            _curl_easy_setopt_err_write_callback();                     \
+        if((_curl_opt) == CURLOPT_RESOLVER_START_FUNCTION)              \
+          if(!curlcheck_resolver_start_callback(value))                 \
+            _curl_easy_setopt_err_resolver_start_callback();            \
+        if((_curl_opt) == CURLOPT_READFUNCTION)                         \
+          if(!curlcheck_read_cb(value))                                 \
+            _curl_easy_setopt_err_read_cb();                            \
+        if((_curl_opt) == CURLOPT_IOCTLFUNCTION)                        \
+          if(!curlcheck_ioctl_cb(value))                                \
+            _curl_easy_setopt_err_ioctl_cb();                           \
+        if((_curl_opt) == CURLOPT_SOCKOPTFUNCTION)                      \
+          if(!curlcheck_sockopt_cb(value))                              \
+            _curl_easy_setopt_err_sockopt_cb();                         \
+        if((_curl_opt) == CURLOPT_OPENSOCKETFUNCTION)                   \
+          if(!curlcheck_opensocket_cb(value))                           \
+            _curl_easy_setopt_err_opensocket_cb();                      \
+        if((_curl_opt) == CURLOPT_PROGRESSFUNCTION)                     \
+          if(!curlcheck_progress_cb(value))                             \
+            _curl_easy_setopt_err_progress_cb();                        \
+        if((_curl_opt) == CURLOPT_DEBUGFUNCTION)                        \
+          if(!curlcheck_debug_cb(value))                                \
+            _curl_easy_setopt_err_debug_cb();                           \
+        if((_curl_opt) == CURLOPT_SSL_CTX_FUNCTION)                     \
+          if(!curlcheck_ssl_ctx_cb(value))                              \
+            _curl_easy_setopt_err_ssl_ctx_cb();                         \
+        if(curlcheck_conv_cb_option(_curl_opt))                         \
+          if(!curlcheck_conv_cb(value))                                 \
+            _curl_easy_setopt_err_conv_cb();                            \
+        if((_curl_opt) == CURLOPT_SEEKFUNCTION)                         \
+          if(!curlcheck_seek_cb(value))                                 \
+            _curl_easy_setopt_err_seek_cb();                            \
+        if(curlcheck_cb_data_option(_curl_opt))                         \
+          if(!curlcheck_cb_data(value))                                 \
+            _curl_easy_setopt_err_cb_data();                            \
+        if((_curl_opt) == CURLOPT_ERRORBUFFER)                          \
+          if(!curlcheck_error_buffer(value))                            \
+            _curl_easy_setopt_err_error_buffer();                       \
+        if((_curl_opt) == CURLOPT_STDERR)                               \
+          if(!curlcheck_FILE(value))                                    \
+            _curl_easy_setopt_err_FILE();                               \
+        if(curlcheck_postfields_option(_curl_opt))                      \
+          if(!curlcheck_postfields(value))                              \
+            _curl_easy_setopt_err_postfields();                         \
+        if((_curl_opt) == CURLOPT_HTTPPOST)                             \
+          if(!curlcheck_arr((value), struct curl_httppost))             \
+            _curl_easy_setopt_err_curl_httpost();                       \
+        if((_curl_opt) == CURLOPT_MIMEPOST)                             \
+          if(!curlcheck_ptr((value), curl_mime))                        \
+            _curl_easy_setopt_err_curl_mimepost();                      \
+        if(curlcheck_slist_option(_curl_opt))                           \
+          if(!curlcheck_arr((value), struct curl_slist))                \
+            _curl_easy_setopt_err_curl_slist();                         \
+        if((_curl_opt) == CURLOPT_SHARE)                                \
+          if(!curlcheck_ptr((value), CURLSH))                           \
+            _curl_easy_setopt_err_CURLSH();                             \
+      }                                                                 \
+      curl_easy_setopt(handle, _curl_opt, value);                       \
+    })
 
 /* wraps curl_easy_getinfo() with typechecking */
-#define curl_easy_getinfo(handle, info, arg)                                  \
-__extension__ ({                                                              \
-  __typeof__(info) _curl_info = info;                                         \
-  if(__builtin_constant_p(_curl_info)) {                                      \
-    if(_curl_is_string_info(_curl_info))                                      \
-      if(!_curl_is_arr((arg), char *))                                        \
-        _curl_easy_getinfo_err_string();                                      \
-    if(_curl_is_long_info(_curl_info))                                        \
-      if(!_curl_is_arr((arg), long))                                          \
-        _curl_easy_getinfo_err_long();                                        \
-    if(_curl_is_double_info(_curl_info))                                      \
-      if(!_curl_is_arr((arg), double))                                        \
-        _curl_easy_getinfo_err_double();                                      \
-    if(_curl_is_slist_info(_curl_info))                                       \
-      if(!_curl_is_arr((arg), struct curl_slist *))                           \
-        _curl_easy_getinfo_err_curl_slist();                                  \
-    if(_curl_is_tlssessioninfo_info(_curl_info))                              \
-      if(!_curl_is_arr((arg), struct curl_tlssessioninfo *))                  \
-        _curl_easy_getinfo_err_curl_tlssesssioninfo();                        \
-    if(_curl_is_certinfo_info(_curl_info))                                    \
-      if(!_curl_is_arr((arg), struct curl_certinfo *))                        \
-        _curl_easy_getinfo_err_curl_certinfo();                               \
-    if(_curl_is_socket_info(_curl_info))                                      \
-      if(!_curl_is_arr((arg), curl_socket_t))                                 \
-        _curl_easy_getinfo_err_curl_socket();                                 \
-    if(_curl_is_off_t_info(_curl_info))                                       \
-      if(!_curl_is_arr((arg), curl_off_t))                                    \
-        _curl_easy_getinfo_err_curl_off_t();                                  \
-  }                                                                           \
-  curl_easy_getinfo(handle, _curl_info, arg);                                 \
-})
+#define curl_easy_getinfo(handle, info, arg)                            \
+  __extension__({                                                      \
+      __typeof__(info) _curl_info = info;                               \
+      if(__builtin_constant_p(_curl_info)) {                            \
+        if(curlcheck_string_info(_curl_info))                           \
+          if(!curlcheck_arr((arg), char *))                             \
+            _curl_easy_getinfo_err_string();                            \
+        if(curlcheck_long_info(_curl_info))                             \
+          if(!curlcheck_arr((arg), long))                               \
+            _curl_easy_getinfo_err_long();                              \
+        if(curlcheck_double_info(_curl_info))                           \
+          if(!curlcheck_arr((arg), double))                             \
+            _curl_easy_getinfo_err_double();                            \
+        if(curlcheck_slist_info(_curl_info))                            \
+          if(!curlcheck_arr((arg), struct curl_slist *))                \
+            _curl_easy_getinfo_err_curl_slist();                        \
+        if(curlcheck_tlssessioninfo_info(_curl_info))                   \
+          if(!curlcheck_arr((arg), struct curl_tlssessioninfo *))       \
+            _curl_easy_getinfo_err_curl_tlssesssioninfo();              \
+        if(curlcheck_certinfo_info(_curl_info))                         \
+          if(!curlcheck_arr((arg), struct curl_certinfo *))             \
+            _curl_easy_getinfo_err_curl_certinfo();                     \
+        if(curlcheck_socket_info(_curl_info))                           \
+          if(!curlcheck_arr((arg), curl_socket_t))                      \
+            _curl_easy_getinfo_err_curl_socket();                       \
+        if(curlcheck_off_t_info(_curl_info))                            \
+          if(!curlcheck_arr((arg), curl_off_t))                         \
+            _curl_easy_getinfo_err_curl_off_t();                        \
+      }                                                                 \
+      curl_easy_getinfo(handle, _curl_info, arg);                       \
+    })
 
 /*
  * For now, just make sure that the functions are called with three arguments
@@ -156,83 +156,83 @@
  * functions */
 
 /* To define a new warning, use _CURL_WARNING(identifier, "message") */
-#define _CURL_WARNING(id, message)                                            \
-  static void __attribute__((__warning__(message)))                           \
-  __attribute__((__unused__)) __attribute__((__noinline__))                   \
+#define CURLWARNING(id, message)                                        \
+  static void __attribute__((__warning__(message)))                     \
+  __attribute__((__unused__)) __attribute__((__noinline__))             \
   id(void) { __asm__(""); }
 
-_CURL_WARNING(_curl_easy_setopt_err_long,
+CURLWARNING(_curl_easy_setopt_err_long,
   "curl_easy_setopt expects a long argument for this option")
-_CURL_WARNING(_curl_easy_setopt_err_curl_off_t,
+CURLWARNING(_curl_easy_setopt_err_curl_off_t,
   "curl_easy_setopt expects a curl_off_t argument for this option")
-_CURL_WARNING(_curl_easy_setopt_err_string,
+CURLWARNING(_curl_easy_setopt_err_string,
               "curl_easy_setopt expects a "
               "string ('char *' or char[]) argument for this option"
   )
-_CURL_WARNING(_curl_easy_setopt_err_write_callback,
+CURLWARNING(_curl_easy_setopt_err_write_callback,
   "curl_easy_setopt expects a curl_write_callback argument for this option")
-_CURL_WARNING(_curl_easy_setopt_err_resolver_start_callback,
+CURLWARNING(_curl_easy_setopt_err_resolver_start_callback,
               "curl_easy_setopt expects a "
               "curl_resolver_start_callback argument for this option"
   )
-_CURL_WARNING(_curl_easy_setopt_err_read_cb,
+CURLWARNING(_curl_easy_setopt_err_read_cb,
   "curl_easy_setopt expects a curl_read_callback argument for this option")
-_CURL_WARNING(_curl_easy_setopt_err_ioctl_cb,
+CURLWARNING(_curl_easy_setopt_err_ioctl_cb,
   "curl_easy_setopt expects a curl_ioctl_callback argument for this option")
-_CURL_WARNING(_curl_easy_setopt_err_sockopt_cb,
+CURLWARNING(_curl_easy_setopt_err_sockopt_cb,
   "curl_easy_setopt expects a curl_sockopt_callback argument for this option")
-_CURL_WARNING(_curl_easy_setopt_err_opensocket_cb,
+CURLWARNING(_curl_easy_setopt_err_opensocket_cb,
               "curl_easy_setopt expects a "
               "curl_opensocket_callback argument for this option"
   )
-_CURL_WARNING(_curl_easy_setopt_err_progress_cb,
+CURLWARNING(_curl_easy_setopt_err_progress_cb,
   "curl_easy_setopt expects a curl_progress_callback argument for this option")
-_CURL_WARNING(_curl_easy_setopt_err_debug_cb,
+CURLWARNING(_curl_easy_setopt_err_debug_cb,
   "curl_easy_setopt expects a curl_debug_callback argument for this option")
-_CURL_WARNING(_curl_easy_setopt_err_ssl_ctx_cb,
+CURLWARNING(_curl_easy_setopt_err_ssl_ctx_cb,
   "curl_easy_setopt expects a curl_ssl_ctx_callback argument for this option")
-_CURL_WARNING(_curl_easy_setopt_err_conv_cb,
+CURLWARNING(_curl_easy_setopt_err_conv_cb,
   "curl_easy_setopt expects a curl_conv_callback argument for this option")
-_CURL_WARNING(_curl_easy_setopt_err_seek_cb,
+CURLWARNING(_curl_easy_setopt_err_seek_cb,
   "curl_easy_setopt expects a curl_seek_callback argument for this option")
-_CURL_WARNING(_curl_easy_setopt_err_cb_data,
+CURLWARNING(_curl_easy_setopt_err_cb_data,
               "curl_easy_setopt expects a "
               "private data pointer as argument for this option")
-_CURL_WARNING(_curl_easy_setopt_err_error_buffer,
+CURLWARNING(_curl_easy_setopt_err_error_buffer,
               "curl_easy_setopt expects a "
               "char buffer of CURL_ERROR_SIZE as argument for this option")
-_CURL_WARNING(_curl_easy_setopt_err_FILE,
+CURLWARNING(_curl_easy_setopt_err_FILE,
   "curl_easy_setopt expects a 'FILE *' argument for this option")
-_CURL_WARNING(_curl_easy_setopt_err_postfields,
+CURLWARNING(_curl_easy_setopt_err_postfields,
   "curl_easy_setopt expects a 'void *' or 'char *' argument for this option")
-_CURL_WARNING(_curl_easy_setopt_err_curl_httpost,
+CURLWARNING(_curl_easy_setopt_err_curl_httpost,
               "curl_easy_setopt expects a 'struct curl_httppost *' "
               "argument for this option")
-_CURL_WARNING(_curl_easy_setopt_err_curl_mimepost,
+CURLWARNING(_curl_easy_setopt_err_curl_mimepost,
               "curl_easy_setopt expects a 'curl_mime *' "
               "argument for this option")
-_CURL_WARNING(_curl_easy_setopt_err_curl_slist,
+CURLWARNING(_curl_easy_setopt_err_curl_slist,
   "curl_easy_setopt expects a 'struct curl_slist *' argument for this option")
-_CURL_WARNING(_curl_easy_setopt_err_CURLSH,
+CURLWARNING(_curl_easy_setopt_err_CURLSH,
   "curl_easy_setopt expects a CURLSH* argument for this option")
 
-_CURL_WARNING(_curl_easy_getinfo_err_string,
+CURLWARNING(_curl_easy_getinfo_err_string,
   "curl_easy_getinfo expects a pointer to 'char *' for this info")
-_CURL_WARNING(_curl_easy_getinfo_err_long,
+CURLWARNING(_curl_easy_getinfo_err_long,
   "curl_easy_getinfo expects a pointer to long for this info")
-_CURL_WARNING(_curl_easy_getinfo_err_double,
+CURLWARNING(_curl_easy_getinfo_err_double,
   "curl_easy_getinfo expects a pointer to double for this info")
-_CURL_WARNING(_curl_easy_getinfo_err_curl_slist,
+CURLWARNING(_curl_easy_getinfo_err_curl_slist,
   "curl_easy_getinfo expects a pointer to 'struct curl_slist *' for this info")
-_CURL_WARNING(_curl_easy_getinfo_err_curl_tlssesssioninfo,
+CURLWARNING(_curl_easy_getinfo_err_curl_tlssesssioninfo,
               "curl_easy_getinfo expects a pointer to "
               "'struct curl_tlssessioninfo *' for this info")
-_CURL_WARNING(_curl_easy_getinfo_err_curl_certinfo,
+CURLWARNING(_curl_easy_getinfo_err_curl_certinfo,
               "curl_easy_getinfo expects a pointer to "
               "'struct curl_certinfo *' for this info")
-_CURL_WARNING(_curl_easy_getinfo_err_curl_socket,
+CURLWARNING(_curl_easy_getinfo_err_curl_socket,
   "curl_easy_getinfo expects a pointer to curl_socket_t for this info")
-_CURL_WARNING(_curl_easy_getinfo_err_curl_off_t,
+CURLWARNING(_curl_easy_getinfo_err_curl_off_t,
   "curl_easy_getinfo expects a pointer to curl_off_t for this info")
 
 /* groups of curl_easy_setops options that take the same type of argument */
@@ -244,14 +244,14 @@
  */
 
 /* evaluates to true if option takes a long argument */
-#define _curl_is_long_option(option)                                          \
+#define curlcheck_long_option(option)                   \
   (0 < (option) && (option) < CURLOPTTYPE_OBJECTPOINT)
 
-#define _curl_is_off_t_option(option)                                         \
-  ((option) > CURLOPTTYPE_OFF_T)
+#define curlcheck_off_t_option(option)          \
+  (((option) > CURLOPTTYPE_OFF_T) && ((option) < CURLOPTTYPE_BLOB))
 
 /* evaluates to true if option takes a char* argument */
-#define _curl_is_string_option(option)                                        \
+#define curlcheck_string_option(option)                                       \
   ((option) == CURLOPT_ABSTRACT_UNIX_SOCKET ||                                \
    (option) == CURLOPT_ACCEPT_ENCODING ||                                     \
    (option) == CURLOPT_ALTSVC ||                                              \
@@ -300,15 +300,18 @@
    (option) == CURLOPT_PROXY_SSLKEY ||                                        \
    (option) == CURLOPT_PROXY_SSLKEYTYPE ||                                    \
    (option) == CURLOPT_PROXY_SSL_CIPHER_LIST ||                               \
+   (option) == CURLOPT_PROXY_TLS13_CIPHERS ||                                 \
    (option) == CURLOPT_PROXY_TLSAUTH_PASSWORD ||                              \
-   (option) == CURLOPT_PROXY_TLSAUTH_USERNAME ||                              \
    (option) == CURLOPT_PROXY_TLSAUTH_TYPE ||                                  \
+   (option) == CURLOPT_PROXY_TLSAUTH_USERNAME ||                              \
    (option) == CURLOPT_RANDOM_FILE ||                                         \
    (option) == CURLOPT_RANGE ||                                               \
    (option) == CURLOPT_REFERER ||                                             \
+   (option) == CURLOPT_REQUEST_TARGET ||                                      \
    (option) == CURLOPT_RTSP_SESSION_ID ||                                     \
    (option) == CURLOPT_RTSP_STREAM_URI ||                                     \
    (option) == CURLOPT_RTSP_TRANSPORT ||                                      \
+   (option) == CURLOPT_SASL_AUTHZID ||                                        \
    (option) == CURLOPT_SERVICE_NAME ||                                        \
    (option) == CURLOPT_SOCKS5_GSSAPI_SERVICE ||                               \
    (option) == CURLOPT_SSH_HOST_PUBLIC_KEY_MD5 ||                             \
@@ -321,6 +324,7 @@
    (option) == CURLOPT_SSLKEY ||                                              \
    (option) == CURLOPT_SSLKEYTYPE ||                                          \
    (option) == CURLOPT_SSL_CIPHER_LIST ||                                     \
+   (option) == CURLOPT_TLS13_CIPHERS ||                                       \
    (option) == CURLOPT_TLSAUTH_PASSWORD ||                                    \
    (option) == CURLOPT_TLSAUTH_TYPE ||                                        \
    (option) == CURLOPT_TLSAUTH_USERNAME ||                                    \
@@ -333,18 +337,18 @@
    0)
 
 /* evaluates to true if option takes a curl_write_callback argument */
-#define _curl_is_write_cb_option(option)                                      \
-  ((option) == CURLOPT_HEADERFUNCTION ||                                      \
+#define curlcheck_write_cb_option(option)                               \
+  ((option) == CURLOPT_HEADERFUNCTION ||                                \
    (option) == CURLOPT_WRITEFUNCTION)
 
 /* evaluates to true if option takes a curl_conv_callback argument */
-#define _curl_is_conv_cb_option(option)                                       \
-  ((option) == CURLOPT_CONV_TO_NETWORK_FUNCTION ||                            \
-   (option) == CURLOPT_CONV_FROM_NETWORK_FUNCTION ||                          \
+#define curlcheck_conv_cb_option(option)                                \
+  ((option) == CURLOPT_CONV_TO_NETWORK_FUNCTION ||                      \
+   (option) == CURLOPT_CONV_FROM_NETWORK_FUNCTION ||                    \
    (option) == CURLOPT_CONV_FROM_UTF8_FUNCTION)
 
 /* evaluates to true if option takes a data argument to pass to a callback */
-#define _curl_is_cb_data_option(option)                                       \
+#define curlcheck_cb_data_option(option)                                      \
   ((option) == CURLOPT_CHUNK_DATA ||                                          \
    (option) == CURLOPT_CLOSESOCKETDATA ||                                     \
    (option) == CURLOPT_DEBUGDATA ||                                           \
@@ -362,17 +366,17 @@
    (option) == CURLOPT_SSL_CTX_DATA ||                                        \
    (option) == CURLOPT_WRITEDATA ||                                           \
    (option) == CURLOPT_RESOLVER_START_DATA ||                                 \
-   (option) == CURLOPT_CURLU ||                                               \
+   (option) == CURLOPT_TRAILERDATA ||                                         \
    0)
 
 /* evaluates to true if option takes a POST data argument (void* or char*) */
-#define _curl_is_postfields_option(option)                                    \
+#define curlcheck_postfields_option(option)                                   \
   ((option) == CURLOPT_POSTFIELDS ||                                          \
    (option) == CURLOPT_COPYPOSTFIELDS ||                                      \
    0)
 
 /* evaluates to true if option takes a struct curl_slist * argument */
-#define _curl_is_slist_option(option)                                         \
+#define curlcheck_slist_option(option)                                        \
   ((option) == CURLOPT_HTTP200ALIASES ||                                      \
    (option) == CURLOPT_HTTPHEADER ||                                          \
    (option) == CURLOPT_MAIL_RCPT ||                                           \
@@ -382,45 +386,47 @@
    (option) == CURLOPT_QUOTE ||                                               \
    (option) == CURLOPT_RESOLVE ||                                             \
    (option) == CURLOPT_TELNETOPTIONS ||                                       \
+   (option) == CURLOPT_CONNECT_TO ||                                          \
    0)
 
 /* groups of curl_easy_getinfo infos that take the same type of argument */
 
 /* evaluates to true if info expects a pointer to char * argument */
-#define _curl_is_string_info(info)                                            \
-  (CURLINFO_STRING < (info) && (info) < CURLINFO_LONG)
+#define curlcheck_string_info(info)                             \
+  (CURLINFO_STRING < (info) && (info) < CURLINFO_LONG &&        \
+   (info) != CURLINFO_PRIVATE)
 
 /* evaluates to true if info expects a pointer to long argument */
-#define _curl_is_long_info(info)                                              \
+#define curlcheck_long_info(info)                       \
   (CURLINFO_LONG < (info) && (info) < CURLINFO_DOUBLE)
 
 /* evaluates to true if info expects a pointer to double argument */
-#define _curl_is_double_info(info)                                            \
+#define curlcheck_double_info(info)                     \
   (CURLINFO_DOUBLE < (info) && (info) < CURLINFO_SLIST)
 
 /* true if info expects a pointer to struct curl_slist * argument */
-#define _curl_is_slist_info(info)                                       \
+#define curlcheck_slist_info(info)                                      \
   (((info) == CURLINFO_SSL_ENGINES) || ((info) == CURLINFO_COOKIELIST))
 
 /* true if info expects a pointer to struct curl_tlssessioninfo * argument */
-#define _curl_is_tlssessioninfo_info(info)                              \
+#define curlcheck_tlssessioninfo_info(info)                              \
   (((info) == CURLINFO_TLS_SSL_PTR) || ((info) == CURLINFO_TLS_SESSION))
 
 /* true if info expects a pointer to struct curl_certinfo * argument */
-#define _curl_is_certinfo_info(info) ((info) == CURLINFO_CERTINFO)
+#define curlcheck_certinfo_info(info) ((info) == CURLINFO_CERTINFO)
 
 /* true if info expects a pointer to struct curl_socket_t argument */
-#define _curl_is_socket_info(info)                                            \
+#define curlcheck_socket_info(info)                     \
   (CURLINFO_SOCKET < (info) && (info) < CURLINFO_OFF_T)
 
 /* true if info expects a pointer to curl_off_t argument */
-#define _curl_is_off_t_info(info)                                             \
+#define curlcheck_off_t_info(info)              \
   (CURLINFO_OFF_T < (info))
 
 
 /* typecheck helpers -- check whether given expression has requested type*/
 
-/* For pointers, you can use the _curl_is_ptr/_curl_is_arr macros,
+/* For pointers, you can use the curlcheck_ptr/curlcheck_arr macros,
  * otherwise define a new macro. Search for __builtin_types_compatible_p
  * in the GCC manual.
  * NOTE: these macros MUST NOT EVALUATE their arguments! The argument is
@@ -430,35 +436,35 @@
  */
 
 /* XXX: should evaluate to true if expr is a pointer */
-#define _curl_is_any_ptr(expr)                                                \
+#define curlcheck_any_ptr(expr)                 \
   (sizeof(expr) == sizeof(void *))
 
 /* evaluates to true if expr is NULL */
 /* XXX: must not evaluate expr, so this check is not accurate */
-#define _curl_is_NULL(expr)                                                   \
+#define curlcheck_NULL(expr)                                            \
   (__builtin_types_compatible_p(__typeof__(expr), __typeof__(NULL)))
 
 /* evaluates to true if expr is type*, const type* or NULL */
-#define _curl_is_ptr(expr, type)                                              \
-  (_curl_is_NULL(expr) ||                                                     \
-   __builtin_types_compatible_p(__typeof__(expr), type *) ||                  \
+#define curlcheck_ptr(expr, type)                                       \
+  (curlcheck_NULL(expr) ||                                              \
+   __builtin_types_compatible_p(__typeof__(expr), type *) ||            \
    __builtin_types_compatible_p(__typeof__(expr), const type *))
 
 /* evaluates to true if expr is one of type[], type*, NULL or const type* */
-#define _curl_is_arr(expr, type)                                              \
-  (_curl_is_ptr((expr), type) ||                                              \
+#define curlcheck_arr(expr, type)                                       \
+  (curlcheck_ptr((expr), type) ||                                       \
    __builtin_types_compatible_p(__typeof__(expr), type []))
 
 /* evaluates to true if expr is a string */
-#define _curl_is_string(expr)                                                 \
-  (_curl_is_arr((expr), char) ||                                              \
-   _curl_is_arr((expr), signed char) ||                                       \
-   _curl_is_arr((expr), unsigned char))
+#define curlcheck_string(expr)                                          \
+  (curlcheck_arr((expr), char) ||                                       \
+   curlcheck_arr((expr), signed char) ||                                \
+   curlcheck_arr((expr), unsigned char))
 
 /* evaluates to true if expr is a long (no matter the signedness)
  * XXX: for now, int is also accepted (and therefore short and char, which
  * are promoted to int when passed to a variadic function) */
-#define _curl_is_long(expr)                                                   \
+#define curlcheck_long(expr)                                                  \
   (__builtin_types_compatible_p(__typeof__(expr), long) ||                    \
    __builtin_types_compatible_p(__typeof__(expr), signed long) ||             \
    __builtin_types_compatible_p(__typeof__(expr), unsigned long) ||           \
@@ -473,59 +479,59 @@
    __builtin_types_compatible_p(__typeof__(expr), unsigned char))
 
 /* evaluates to true if expr is of type curl_off_t */
-#define _curl_is_off_t(expr)                                                  \
+#define curlcheck_off_t(expr)                                   \
   (__builtin_types_compatible_p(__typeof__(expr), curl_off_t))
 
 /* evaluates to true if expr is abuffer suitable for CURLOPT_ERRORBUFFER */
 /* XXX: also check size of an char[] array? */
-#define _curl_is_error_buffer(expr)                                           \
-  (_curl_is_NULL(expr) ||                                                     \
-   __builtin_types_compatible_p(__typeof__(expr), char *) ||                  \
+#define curlcheck_error_buffer(expr)                                    \
+  (curlcheck_NULL(expr) ||                                              \
+   __builtin_types_compatible_p(__typeof__(expr), char *) ||            \
    __builtin_types_compatible_p(__typeof__(expr), char[]))
 
 /* evaluates to true if expr is of type (const) void* or (const) FILE* */
 #if 0
-#define _curl_is_cb_data(expr)                                                \
-  (_curl_is_ptr((expr), void) ||                                              \
-   _curl_is_ptr((expr), FILE))
+#define curlcheck_cb_data(expr)                                         \
+  (curlcheck_ptr((expr), void) ||                                       \
+   curlcheck_ptr((expr), FILE))
 #else /* be less strict */
-#define _curl_is_cb_data(expr)                                                \
-  _curl_is_any_ptr(expr)
+#define curlcheck_cb_data(expr)                 \
+  curlcheck_any_ptr(expr)
 #endif
 
 /* evaluates to true if expr is of type FILE* */
-#define _curl_is_FILE(expr)                                             \
-  (_curl_is_NULL(expr) ||                                              \
+#define curlcheck_FILE(expr)                                            \
+  (curlcheck_NULL(expr) ||                                              \
    (__builtin_types_compatible_p(__typeof__(expr), FILE *)))
 
 /* evaluates to true if expr can be passed as POST data (void* or char*) */
-#define _curl_is_postfields(expr)                                             \
-  (_curl_is_ptr((expr), void) ||                                              \
-   _curl_is_arr((expr), char) ||                                              \
-   _curl_is_arr((expr), unsigned char))
+#define curlcheck_postfields(expr)                                      \
+  (curlcheck_ptr((expr), void) ||                                       \
+   curlcheck_arr((expr), char) ||                                       \
+   curlcheck_arr((expr), unsigned char))
 
 /* helper: __builtin_types_compatible_p distinguishes between functions and
  * function pointers, hide it */
-#define _curl_callback_compatible(func, type)                                 \
-  (__builtin_types_compatible_p(__typeof__(func), type) ||                    \
+#define curlcheck_cb_compatible(func, type)                             \
+  (__builtin_types_compatible_p(__typeof__(func), type) ||              \
    __builtin_types_compatible_p(__typeof__(func) *, type))
 
 /* evaluates to true if expr is of type curl_resolver_start_callback */
-#define _curl_is_resolver_start_callback(expr)       \
-  (_curl_is_NULL(expr) || \
-   _curl_callback_compatible((expr), curl_resolver_start_callback))
+#define curlcheck_resolver_start_callback(expr)       \
+  (curlcheck_NULL(expr) || \
+   curlcheck_cb_compatible((expr), curl_resolver_start_callback))
 
 /* evaluates to true if expr is of type curl_read_callback or "similar" */
-#define _curl_is_read_cb(expr)                                          \
-  (_curl_is_NULL(expr) ||                                                     \
-   _curl_callback_compatible((expr), __typeof__(fread) *) ||                  \
-   _curl_callback_compatible((expr), curl_read_callback) ||                   \
-   _curl_callback_compatible((expr), _curl_read_callback1) ||                 \
-   _curl_callback_compatible((expr), _curl_read_callback2) ||                 \
-   _curl_callback_compatible((expr), _curl_read_callback3) ||                 \
-   _curl_callback_compatible((expr), _curl_read_callback4) ||                 \
-   _curl_callback_compatible((expr), _curl_read_callback5) ||                 \
-   _curl_callback_compatible((expr), _curl_read_callback6))
+#define curlcheck_read_cb(expr)                                         \
+  (curlcheck_NULL(expr) ||                                              \
+   curlcheck_cb_compatible((expr), __typeof__(fread) *) ||              \
+   curlcheck_cb_compatible((expr), curl_read_callback) ||               \
+   curlcheck_cb_compatible((expr), _curl_read_callback1) ||             \
+   curlcheck_cb_compatible((expr), _curl_read_callback2) ||             \
+   curlcheck_cb_compatible((expr), _curl_read_callback3) ||             \
+   curlcheck_cb_compatible((expr), _curl_read_callback4) ||             \
+   curlcheck_cb_compatible((expr), _curl_read_callback5) ||             \
+   curlcheck_cb_compatible((expr), _curl_read_callback6))
 typedef size_t (*_curl_read_callback1)(char *, size_t, size_t, void *);
 typedef size_t (*_curl_read_callback2)(char *, size_t, size_t, const void *);
 typedef size_t (*_curl_read_callback3)(char *, size_t, size_t, FILE *);
@@ -534,16 +540,16 @@
 typedef size_t (*_curl_read_callback6)(void *, size_t, size_t, FILE *);
 
 /* evaluates to true if expr is of type curl_write_callback or "similar" */
-#define _curl_is_write_cb(expr)                                               \
-  (_curl_is_read_cb(expr) ||                                            \
-   _curl_callback_compatible((expr), __typeof__(fwrite) *) ||                 \
-   _curl_callback_compatible((expr), curl_write_callback) ||                  \
-   _curl_callback_compatible((expr), _curl_write_callback1) ||                \
-   _curl_callback_compatible((expr), _curl_write_callback2) ||                \
-   _curl_callback_compatible((expr), _curl_write_callback3) ||                \
-   _curl_callback_compatible((expr), _curl_write_callback4) ||                \
-   _curl_callback_compatible((expr), _curl_write_callback5) ||                \
-   _curl_callback_compatible((expr), _curl_write_callback6))
+#define curlcheck_write_cb(expr)                                        \
+  (curlcheck_read_cb(expr) ||                                           \
+   curlcheck_cb_compatible((expr), __typeof__(fwrite) *) ||             \
+   curlcheck_cb_compatible((expr), curl_write_callback) ||              \
+   curlcheck_cb_compatible((expr), _curl_write_callback1) ||            \
+   curlcheck_cb_compatible((expr), _curl_write_callback2) ||            \
+   curlcheck_cb_compatible((expr), _curl_write_callback3) ||            \
+   curlcheck_cb_compatible((expr), _curl_write_callback4) ||            \
+   curlcheck_cb_compatible((expr), _curl_write_callback5) ||            \
+   curlcheck_cb_compatible((expr), _curl_write_callback6))
 typedef size_t (*_curl_write_callback1)(const char *, size_t, size_t, void *);
 typedef size_t (*_curl_write_callback2)(const char *, size_t, size_t,
                                        const void *);
@@ -554,37 +560,37 @@
 typedef size_t (*_curl_write_callback6)(const void *, size_t, size_t, FILE *);
 
 /* evaluates to true if expr is of type curl_ioctl_callback or "similar" */
-#define _curl_is_ioctl_cb(expr)                                         \
-  (_curl_is_NULL(expr) ||                                                     \
-   _curl_callback_compatible((expr), curl_ioctl_callback) ||                  \
-   _curl_callback_compatible((expr), _curl_ioctl_callback1) ||                \
-   _curl_callback_compatible((expr), _curl_ioctl_callback2) ||                \
-   _curl_callback_compatible((expr), _curl_ioctl_callback3) ||                \
-   _curl_callback_compatible((expr), _curl_ioctl_callback4))
+#define curlcheck_ioctl_cb(expr)                                        \
+  (curlcheck_NULL(expr) ||                                              \
+   curlcheck_cb_compatible((expr), curl_ioctl_callback) ||              \
+   curlcheck_cb_compatible((expr), _curl_ioctl_callback1) ||            \
+   curlcheck_cb_compatible((expr), _curl_ioctl_callback2) ||            \
+   curlcheck_cb_compatible((expr), _curl_ioctl_callback3) ||            \
+   curlcheck_cb_compatible((expr), _curl_ioctl_callback4))
 typedef curlioerr (*_curl_ioctl_callback1)(CURL *, int, void *);
 typedef curlioerr (*_curl_ioctl_callback2)(CURL *, int, const void *);
 typedef curlioerr (*_curl_ioctl_callback3)(CURL *, curliocmd, void *);
 typedef curlioerr (*_curl_ioctl_callback4)(CURL *, curliocmd, const void *);
 
 /* evaluates to true if expr is of type curl_sockopt_callback or "similar" */
-#define _curl_is_sockopt_cb(expr)                                       \
-  (_curl_is_NULL(expr) ||                                                     \
-   _curl_callback_compatible((expr), curl_sockopt_callback) ||                \
-   _curl_callback_compatible((expr), _curl_sockopt_callback1) ||              \
-   _curl_callback_compatible((expr), _curl_sockopt_callback2))
+#define curlcheck_sockopt_cb(expr)                                      \
+  (curlcheck_NULL(expr) ||                                              \
+   curlcheck_cb_compatible((expr), curl_sockopt_callback) ||            \
+   curlcheck_cb_compatible((expr), _curl_sockopt_callback1) ||          \
+   curlcheck_cb_compatible((expr), _curl_sockopt_callback2))
 typedef int (*_curl_sockopt_callback1)(void *, curl_socket_t, curlsocktype);
 typedef int (*_curl_sockopt_callback2)(const void *, curl_socket_t,
                                       curlsocktype);
 
 /* evaluates to true if expr is of type curl_opensocket_callback or
    "similar" */
-#define _curl_is_opensocket_cb(expr)                                    \
-  (_curl_is_NULL(expr) ||                                                     \
-   _curl_callback_compatible((expr), curl_opensocket_callback) ||             \
-   _curl_callback_compatible((expr), _curl_opensocket_callback1) ||           \
-   _curl_callback_compatible((expr), _curl_opensocket_callback2) ||           \
-   _curl_callback_compatible((expr), _curl_opensocket_callback3) ||           \
-   _curl_callback_compatible((expr), _curl_opensocket_callback4))
+#define curlcheck_opensocket_cb(expr)                                   \
+  (curlcheck_NULL(expr) ||                                              \
+   curlcheck_cb_compatible((expr), curl_opensocket_callback) ||         \
+   curlcheck_cb_compatible((expr), _curl_opensocket_callback1) ||       \
+   curlcheck_cb_compatible((expr), _curl_opensocket_callback2) ||       \
+   curlcheck_cb_compatible((expr), _curl_opensocket_callback3) ||       \
+   curlcheck_cb_compatible((expr), _curl_opensocket_callback4))
 typedef curl_socket_t (*_curl_opensocket_callback1)
   (void *, curlsocktype, struct curl_sockaddr *);
 typedef curl_socket_t (*_curl_opensocket_callback2)
@@ -595,28 +601,28 @@
   (const void *, curlsocktype, const struct curl_sockaddr *);
 
 /* evaluates to true if expr is of type curl_progress_callback or "similar" */
-#define _curl_is_progress_cb(expr)                                      \
-  (_curl_is_NULL(expr) ||                                                     \
-   _curl_callback_compatible((expr), curl_progress_callback) ||               \
-   _curl_callback_compatible((expr), _curl_progress_callback1) ||             \
-   _curl_callback_compatible((expr), _curl_progress_callback2))
+#define curlcheck_progress_cb(expr)                                     \
+  (curlcheck_NULL(expr) ||                                              \
+   curlcheck_cb_compatible((expr), curl_progress_callback) ||           \
+   curlcheck_cb_compatible((expr), _curl_progress_callback1) ||         \
+   curlcheck_cb_compatible((expr), _curl_progress_callback2))
 typedef int (*_curl_progress_callback1)(void *,
     double, double, double, double);
 typedef int (*_curl_progress_callback2)(const void *,
     double, double, double, double);
 
 /* evaluates to true if expr is of type curl_debug_callback or "similar" */
-#define _curl_is_debug_cb(expr)                                         \
-  (_curl_is_NULL(expr) ||                                                     \
-   _curl_callback_compatible((expr), curl_debug_callback) ||                  \
-   _curl_callback_compatible((expr), _curl_debug_callback1) ||                \
-   _curl_callback_compatible((expr), _curl_debug_callback2) ||                \
-   _curl_callback_compatible((expr), _curl_debug_callback3) ||                \
-   _curl_callback_compatible((expr), _curl_debug_callback4) ||                \
-   _curl_callback_compatible((expr), _curl_debug_callback5) ||                \
-   _curl_callback_compatible((expr), _curl_debug_callback6) ||                \
-   _curl_callback_compatible((expr), _curl_debug_callback7) ||                \
-   _curl_callback_compatible((expr), _curl_debug_callback8))
+#define curlcheck_debug_cb(expr)                                        \
+  (curlcheck_NULL(expr) ||                                              \
+   curlcheck_cb_compatible((expr), curl_debug_callback) ||              \
+   curlcheck_cb_compatible((expr), _curl_debug_callback1) ||            \
+   curlcheck_cb_compatible((expr), _curl_debug_callback2) ||            \
+   curlcheck_cb_compatible((expr), _curl_debug_callback3) ||            \
+   curlcheck_cb_compatible((expr), _curl_debug_callback4) ||            \
+   curlcheck_cb_compatible((expr), _curl_debug_callback5) ||            \
+   curlcheck_cb_compatible((expr), _curl_debug_callback6) ||            \
+   curlcheck_cb_compatible((expr), _curl_debug_callback7) ||            \
+   curlcheck_cb_compatible((expr), _curl_debug_callback8))
 typedef int (*_curl_debug_callback1) (CURL *,
     curl_infotype, char *, size_t, void *);
 typedef int (*_curl_debug_callback2) (CURL *,
@@ -636,17 +642,17 @@
 
 /* evaluates to true if expr is of type curl_ssl_ctx_callback or "similar" */
 /* this is getting even messier... */
-#define _curl_is_ssl_ctx_cb(expr)                                       \
-  (_curl_is_NULL(expr) ||                                                     \
-   _curl_callback_compatible((expr), curl_ssl_ctx_callback) ||                \
-   _curl_callback_compatible((expr), _curl_ssl_ctx_callback1) ||              \
-   _curl_callback_compatible((expr), _curl_ssl_ctx_callback2) ||              \
-   _curl_callback_compatible((expr), _curl_ssl_ctx_callback3) ||              \
-   _curl_callback_compatible((expr), _curl_ssl_ctx_callback4) ||              \
-   _curl_callback_compatible((expr), _curl_ssl_ctx_callback5) ||              \
-   _curl_callback_compatible((expr), _curl_ssl_ctx_callback6) ||              \
-   _curl_callback_compatible((expr), _curl_ssl_ctx_callback7) ||              \
-   _curl_callback_compatible((expr), _curl_ssl_ctx_callback8))
+#define curlcheck_ssl_ctx_cb(expr)                                      \
+  (curlcheck_NULL(expr) ||                                              \
+   curlcheck_cb_compatible((expr), curl_ssl_ctx_callback) ||            \
+   curlcheck_cb_compatible((expr), _curl_ssl_ctx_callback1) ||          \
+   curlcheck_cb_compatible((expr), _curl_ssl_ctx_callback2) ||          \
+   curlcheck_cb_compatible((expr), _curl_ssl_ctx_callback3) ||          \
+   curlcheck_cb_compatible((expr), _curl_ssl_ctx_callback4) ||          \
+   curlcheck_cb_compatible((expr), _curl_ssl_ctx_callback5) ||          \
+   curlcheck_cb_compatible((expr), _curl_ssl_ctx_callback6) ||          \
+   curlcheck_cb_compatible((expr), _curl_ssl_ctx_callback7) ||          \
+   curlcheck_cb_compatible((expr), _curl_ssl_ctx_callback8))
 typedef CURLcode (*_curl_ssl_ctx_callback1)(CURL *, void *, void *);
 typedef CURLcode (*_curl_ssl_ctx_callback2)(CURL *, void *, const void *);
 typedef CURLcode (*_curl_ssl_ctx_callback3)(CURL *, const void *, void *);
@@ -669,26 +675,26 @@
 #endif
 
 /* evaluates to true if expr is of type curl_conv_callback or "similar" */
-#define _curl_is_conv_cb(expr)                                          \
-  (_curl_is_NULL(expr) ||                                                     \
-   _curl_callback_compatible((expr), curl_conv_callback) ||                   \
-   _curl_callback_compatible((expr), _curl_conv_callback1) ||                 \
-   _curl_callback_compatible((expr), _curl_conv_callback2) ||                 \
-   _curl_callback_compatible((expr), _curl_conv_callback3) ||                 \
-   _curl_callback_compatible((expr), _curl_conv_callback4))
+#define curlcheck_conv_cb(expr)                                         \
+  (curlcheck_NULL(expr) ||                                              \
+   curlcheck_cb_compatible((expr), curl_conv_callback) ||               \
+   curlcheck_cb_compatible((expr), _curl_conv_callback1) ||             \
+   curlcheck_cb_compatible((expr), _curl_conv_callback2) ||             \
+   curlcheck_cb_compatible((expr), _curl_conv_callback3) ||             \
+   curlcheck_cb_compatible((expr), _curl_conv_callback4))
 typedef CURLcode (*_curl_conv_callback1)(char *, size_t length);
 typedef CURLcode (*_curl_conv_callback2)(const char *, size_t length);
 typedef CURLcode (*_curl_conv_callback3)(void *, size_t length);
 typedef CURLcode (*_curl_conv_callback4)(const void *, size_t length);
 
 /* evaluates to true if expr is of type curl_seek_callback or "similar" */
-#define _curl_is_seek_cb(expr)                                          \
-  (_curl_is_NULL(expr) ||                                                     \
-   _curl_callback_compatible((expr), curl_seek_callback) ||                   \
-   _curl_callback_compatible((expr), _curl_seek_callback1) ||                 \
-   _curl_callback_compatible((expr), _curl_seek_callback2))
+#define curlcheck_seek_cb(expr)                                         \
+  (curlcheck_NULL(expr) ||                                              \
+   curlcheck_cb_compatible((expr), curl_seek_callback) ||               \
+   curlcheck_cb_compatible((expr), _curl_seek_callback1) ||             \
+   curlcheck_cb_compatible((expr), _curl_seek_callback2))
 typedef CURLcode (*_curl_seek_callback1)(void *, curl_off_t, int);
 typedef CURLcode (*_curl_seek_callback2)(const void *, curl_off_t, int);
 
 
-#endif /* __CURL_TYPECHECK_GCC_H */
+#endif /* CURLINC_TYPECHECK_GCC_H */
diff --git a/Utilities/cmcurl/include/curl/urlapi.h b/Utilities/cmcurl/include/curl/urlapi.h
index 58e89d8..f2d0677 100644
--- a/Utilities/cmcurl/include/curl/urlapi.h
+++ b/Utilities/cmcurl/include/curl/urlapi.h
@@ -1,5 +1,5 @@
-#ifndef __CURL_URLAPI_H
-#define __CURL_URLAPI_H
+#ifndef CURLINC_URLAPI_H
+#define CURLINC_URLAPI_H
 /***************************************************************************
  *                                  _   _ ____  _
  *  Project                     ___| | | |  _ \| |
@@ -77,6 +77,8 @@
 #define CURLU_URLENCODE (1<<7)          /* URL encode on set */
 #define CURLU_APPENDQUERY (1<<8)        /* append a form style part */
 #define CURLU_GUESS_SCHEME (1<<9)       /* legacy curl-style guessing */
+#define CURLU_NO_AUTHORITY (1<<10)      /* Allow empty authority when the
+                                           scheme is unknown. */
 
 typedef struct Curl_URL CURLU;
 
@@ -120,4 +122,4 @@
 } /* end of extern "C" */
 #endif
 
-#endif
+#endif /* CURLINC_URLAPI_H */
diff --git a/Utilities/cmcurl/lib/CMakeLists.txt b/Utilities/cmcurl/lib/CMakeLists.txt
index 2a6279c..32bea68 100644
--- a/Utilities/cmcurl/lib/CMakeLists.txt
+++ b/Utilities/cmcurl/lib/CMakeLists.txt
@@ -1,3 +1,24 @@
+#***************************************************************************
+#                                  _   _ ____  _
+#  Project                     ___| | | |  _ \| |
+#                             / __| | | | |_) | |
+#                            | (__| |_| |  _ <| |___
+#                             \___|\___/|_| \_\_____|
+#
+# Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+#
+# This software is licensed as described in the file COPYING, which
+# you should have received as part of this distribution. The terms
+# are also available at https://curl.haxx.se/docs/copyright.html.
+#
+# You may opt to use, copy, modify, merge, publish, distribute and/or sell
+# copies of the Software, and permit persons to whom the Software is
+# furnished to do so, under the terms of the COPYING file.
+#
+# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+# KIND, either express or implied.
+#
+###########################################################################
 set(LIB_NAME cmcurl)
 
 if(BUILD_SHARED_LIBS)
@@ -20,7 +41,6 @@
 
 if(MSVC AND NOT CURL_STATICLIB)
   list(APPEND CSOURCES libcurl.rc)
-  set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /wd4127")
 endif()
 
 # SET(CSOURCES
@@ -97,11 +117,16 @@
   ${CMAKE_CURL_SSL_DLLS}
   )
 
+add_library(
+  ${PROJECT_NAME}::${LIB_NAME}
+  ALIAS ${LIB_NAME}
+  )
+
 if(NOT BUILD_SHARED_LIBS)
     set_target_properties(${LIB_NAME} PROPERTIES INTERFACE_COMPILE_DEFINITIONS CURL_STATICLIB)
 endif()
 
-target_link_libraries(${LIB_NAME} ${CURL_LIBS})
+target_link_libraries(${LIB_NAME} PRIVATE ${CURL_LIBS})
 
 if(0) # This code not needed for building within CMake.
 if(WIN32)
@@ -121,6 +146,12 @@
 set_target_properties(${LIB_NAME} PROPERTIES PREFIX "")
 set_target_properties(${LIB_NAME} PROPERTIES IMPORT_PREFIX "")
 
+if(CURL_HAS_LTO)
+  set_target_properties(${LIB_NAME} PROPERTIES
+    INTERPROCEDURAL_OPTIMIZATION_RELEASE TRUE
+    INTERPROCEDURAL_OPTIMIZATION_RELWITHDEBINFO TRUE)
+endif()
+
 if(WIN32)
   if(BUILD_SHARED_LIBS)
     # Add "_imp" as a suffix before the extension to avoid conflicting with the statically linked "libcurl.lib"
@@ -141,7 +172,7 @@
 
 export(TARGETS ${LIB_NAME}
        APPEND FILE ${PROJECT_BINARY_DIR}/libcurl-target.cmake
-       NAMESPACE CURL::
+       NAMESPACE ${PROJECT_NAME}::
 )
 
 endif()
diff --git a/Utilities/cmcurl/lib/Makefile.inc b/Utilities/cmcurl/lib/Makefile.inc
index 235b82b..723b826 100644
--- a/Utilities/cmcurl/lib/Makefile.inc
+++ b/Utilities/cmcurl/lib/Makefile.inc
@@ -5,7 +5,7 @@
 #                            | (__| |_| |  _ <| |___
 #                             \___|\___/|_| \_\_____|
 #
-# Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+# Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
 #
 # This software is licensed as described in the file COPYING, which
 # you should have received as part of this distribution. The terms
@@ -20,65 +20,70 @@
 #
 ###########################################################################
 
-LIB_VAUTH_CFILES = vauth/vauth.c vauth/cleartext.c vauth/cram.c         \
-  vauth/digest.c vauth/digest_sspi.c vauth/krb5_gssapi.c                \
-  vauth/krb5_sspi.c vauth/ntlm.c vauth/ntlm_sspi.c vauth/oauth2.c       \
-  vauth/spnego_gssapi.c vauth/spnego_sspi.c
+LIB_VAUTH_CFILES = vauth/cleartext.c vauth/cram.c vauth/digest.c             \
+  vauth/digest_sspi.c vauth/krb5_gssapi.c vauth/krb5_sspi.c vauth/ntlm.c     \
+  vauth/ntlm_sspi.c vauth/oauth2.c vauth/spnego_gssapi.c vauth/spnego_sspi.c \
+  vauth/vauth.c
 
-LIB_VAUTH_HFILES = vauth/vauth.h vauth/digest.h vauth/ntlm.h
+LIB_VAUTH_HFILES = vauth/digest.h vauth/ntlm.h vauth/vauth.h
 
-LIB_VTLS_CFILES = vtls/openssl.c vtls/gtls.c vtls/vtls.c vtls/nss.c     \
-  vtls/polarssl.c vtls/polarssl_threadlock.c                            \
-  vtls/cyassl.c vtls/schannel.c vtls/schannel_verify.c                  \
-  vtls/sectransp.c vtls/gskit.c vtls/mbedtls.c vtls/mesalink.c
+LIB_VTLS_CFILES = vtls/bearssl.c vtls/gskit.c vtls/gtls.c vtls/keylog.c  \
+  vtls/mbedtls.c vtls/mbedtls_threadlock.c vtls/mesalink.c vtls/nss.c    \
+  vtls/openssl.c vtls/schannel.c vtls/schannel_verify.c vtls/sectransp.c \
+  vtls/vtls.c vtls/wolfssl.c
 
-LIB_VTLS_HFILES = vtls/openssl.h vtls/vtls.h vtls/gtls.h                \
-  vtls/nssg.h vtls/polarssl.h vtls/polarssl_threadlock.h                \
-  vtls/cyassl.h vtls/schannel.h vtls/sectransp.h vtls/gskit.h           \
-  vtls/mbedtls.h vtls/mesalink.h
+LIB_VTLS_HFILES = vtls/bearssl.h vtls/gskit.h vtls/gtls.h vtls/keylog.h      \
+  vtls/mbedtls.h vtls/mbedtls_threadlock.h vtls/mesalink.h vtls/nssg.h       \
+  vtls/openssl.h vtls/schannel.h vtls/sectransp.h vtls/vtls.h vtls/wolfssl.h
 
-LIB_CFILES = file.c timeval.c base64.c hostip.c progress.c formdata.c   \
-  cookie.c http.c sendf.c ftp.c url.c dict.c if2ip.c speedcheck.c       \
-  ldap.c version.c getenv.c escape.c mprintf.c telnet.c netrc.c         \
-  getinfo.c transfer.c strcase.c easy.c security.c curl_fnmatch.c       \
-  fileinfo.c ftplistparser.c wildcard.c krb5.c memdebug.c http_chunks.c \
-  strtok.c connect.c llist.c hash.c multi.c content_encoding.c share.c  \
-  http_digest.c md4.c md5.c http_negotiate.c inet_pton.c strtoofft.c    \
-  strerror.c amigaos.c hostasyn.c hostip4.c hostip6.c hostsyn.c         \
-  inet_ntop.c parsedate.c select.c tftp.c splay.c strdup.c socks.c      \
-  ssh.c ssh-libssh.c curl_addrinfo.c socks_gssapi.c socks_sspi.c        \
-  curl_sspi.c slist.c nonblock.c curl_memrchr.c imap.c pop3.c smtp.c    \
-  pingpong.c rtsp.c curl_threads.c warnless.c hmac.c curl_rtmp.c        \
-  openldap.c curl_gethostname.c gopher.c idn_win32.c                    \
-  http_proxy.c non-ascii.c asyn-ares.c asyn-thread.c curl_gssapi.c      \
-  http_ntlm.c curl_ntlm_wb.c curl_ntlm_core.c curl_sasl.c rand.c        \
-  curl_multibyte.c hostcheck.c conncache.c dotdot.c                     \
-  x509asn1.c http2.c smb.c curl_endian.c curl_des.c system_win32.c      \
-  mime.c sha256.c setopt.c curl_path.c curl_ctype.c curl_range.c psl.c  \
-  doh.c urlapi.c curl_get_line.c altsvc.c
+LIB_VQUIC_CFILES = vquic/ngtcp2.c vquic/quiche.c vquic/vquic.c
 
-LIB_HFILES = arpa_telnet.h netrc.h file.h timeval.h hostip.h progress.h \
-  formdata.h cookie.h http.h sendf.h ftp.h url.h dict.h if2ip.h         \
-  speedcheck.h urldata.h curl_ldap.h escape.h telnet.h getinfo.h        \
-  strcase.h curl_sec.h memdebug.h http_chunks.h curl_fnmatch.h          \
-  wildcard.h fileinfo.h ftplistparser.h strtok.h connect.h llist.h      \
-  hash.h content_encoding.h share.h curl_md4.h curl_md5.h http_digest.h \
-  http_negotiate.h inet_pton.h amigaos.h strtoofft.h strerror.h         \
-  inet_ntop.h curlx.h curl_memory.h curl_setup.h transfer.h select.h    \
-  easyif.h multiif.h parsedate.h tftp.h sockaddr.h splay.h strdup.h     \
-  socks.h ssh.h curl_base64.h curl_addrinfo.h curl_sspi.h      \
-  slist.h nonblock.h curl_memrchr.h imap.h pop3.h smtp.h pingpong.h     \
-  rtsp.h curl_threads.h warnless.h curl_hmac.h curl_rtmp.h              \
-  curl_gethostname.h gopher.h http_proxy.h non-ascii.h asyn.h           \
-  http_ntlm.h curl_gssapi.h curl_ntlm_wb.h curl_ntlm_core.h             \
-  curl_sasl.h curl_multibyte.h hostcheck.h conncache.h                  \
-  curl_setup_once.h multihandle.h setup-vms.h dotdot.h                  \
-  x509asn1.h http2.h sigpipe.h smb.h curl_endian.h curl_des.h           \
-  curl_printf.h system_win32.h rand.h mime.h curl_sha256.h setopt.h     \
-  curl_path.h curl_ctype.h curl_range.h psl.h doh.h urlapi-int.h        \
-  curl_get_line.h altsvc.h
+LIB_VQUIC_HFILES = vquic/ngtcp2.h vquic/quiche.h vquic/vquic.h
+
+LIB_VSSH_CFILES = vssh/libssh.c vssh/libssh2.c vssh/wolfssh.c
+
+LIB_VSSH_HFILES = vssh/ssh.h
+
+LIB_CFILES = altsvc.c amigaos.c asyn-ares.c asyn-thread.c base64.c            \
+  conncache.c connect.c content_encoding.c cookie.c curl_addrinfo.c           \
+  curl_ctype.c curl_des.c curl_endian.c curl_fnmatch.c curl_get_line.c        \
+  curl_gethostname.c curl_gssapi.c curl_memrchr.c curl_multibyte.c            \
+  curl_ntlm_core.c curl_ntlm_wb.c curl_path.c curl_range.c curl_rtmp.c        \
+  curl_sasl.c curl_sspi.c curl_threads.c dict.c dotdot.c easy.c escape.c      \
+  file.c fileinfo.c formdata.c ftp.c url.c ftplistparser.c getenv.c getinfo.c \
+  gopher.c hash.c hmac.c hostasyn.c hostcheck.c hostip.c hostip4.c hostip6.c  \
+  hostsyn.c http.c http2.c http_chunks.c http_digest.c http_negotiate.c       \
+  http_ntlm.c http_proxy.c idn_win32.c if2ip.c imap.c inet_ntop.c inet_pton.c \
+  krb5.c ldap.c llist.c md4.c md5.c memdebug.c mime.c mprintf.c mqtt.c        \
+  multi.c netrc.c non-ascii.c nonblock.c openldap.c parsedate.c pingpong.c    \
+  pop3.c progress.c psl.c doh.c rand.c rename.c rtsp.c security.c select.c    \
+  sendf.c setopt.c sha256.c share.c slist.c smb.c smtp.c socketpair.c socks.c \
+  socks_gssapi.c socks_sspi.c speedcheck.c splay.c strcase.c strdup.c         \
+  strerror.c strtok.c strtoofft.c system_win32.c telnet.c tftp.c timeval.c    \
+  transfer.c urlapi.c version.c warnless.c wildcard.c x509asn1.c dynbuf.c
+
+LIB_HFILES = altsvc.h amigaos.h arpa_telnet.h asyn.h conncache.h connect.h    \
+  content_encoding.h cookie.h curl_addrinfo.h curl_base64.h curl_ctype.h      \
+  curl_des.h curl_endian.h curl_fnmatch.h curl_get_line.h curl_gethostname.h  \
+  curl_gssapi.h curl_hmac.h curl_ldap.h curl_md4.h curl_md5.h curl_memory.h   \
+  curl_memrchr.h curl_multibyte.h curl_ntlm_core.h curl_ntlm_wb.h curl_path.h \
+  curl_printf.h curl_range.h curl_rtmp.h curl_sasl.h curl_sec.h curl_setup.h  \
+  curl_setup_once.h curl_sha256.h curl_sspi.h curl_threads.h curlx.h dict.h   \
+  dotdot.h easyif.h escape.h file.h fileinfo.h formdata.h ftp.h url.h         \
+  ftplistparser.h getinfo.h gopher.h hash.h hostcheck.h hostip.h http.h       \
+  http2.h http_chunks.h http_digest.h http_negotiate.h http_ntlm.h            \
+  http_proxy.h if2ip.h imap.h inet_ntop.h inet_pton.h llist.h memdebug.h      \
+  mime.h mqtt.h multihandle.h multiif.h netrc.h non-ascii.h nonblock.h        \
+  parsedate.h pingpong.h pop3.h progress.h psl.h doh.h quic.h rand.h rename.h \
+  rtsp.h select.h sendf.h setopt.h setup-vms.h share.h sigpipe.h slist.h      \
+  smb.h smtp.h sockaddr.h socketpair.h socks.h speedcheck.h splay.h strcase.h \
+  strdup.h strerror.h strtok.h strtoofft.h system_win32.h telnet.h tftp.h     \
+  timeval.h transfer.h urlapi-int.h urldata.h warnless.h wildcard.h           \
+  x509asn1.h dynbuf.h
 
 LIB_RCFILES = libcurl.rc
 
-CSOURCES = $(LIB_CFILES) $(LIB_VAUTH_CFILES) $(LIB_VTLS_CFILES)
-HHEADERS = $(LIB_HFILES) $(LIB_VAUTH_HFILES) $(LIB_VTLS_HFILES)
+CSOURCES = $(LIB_CFILES) $(LIB_VAUTH_CFILES) $(LIB_VTLS_CFILES) \
+  $(LIB_VQUIC_CFILES) $(LIB_VSSH_CFILES)
+HHEADERS = $(LIB_HFILES) $(LIB_VAUTH_HFILES) $(LIB_VTLS_HFILES) \
+  $(LIB_VQUIC_HFILES) $(LIB_VSSH_HFILES)
diff --git a/Utilities/cmcurl/lib/altsvc.c b/Utilities/cmcurl/lib/altsvc.c
index 85a4e01..c2ec489 100644
--- a/Utilities/cmcurl/lib/altsvc.c
+++ b/Utilities/cmcurl/lib/altsvc.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 2019 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -34,6 +34,8 @@
 #include "parsedate.h"
 #include "sendf.h"
 #include "warnless.h"
+#include "rand.h"
+#include "rename.h"
 
 /* The last 3 #include files should be in this order */
 #include "curl_printf.h"
@@ -48,15 +50,21 @@
 #define MAX_ALTSVC_ALPNLENSTR "10"
 #define MAX_ALTSVC_ALPNLEN 10
 
+#if defined(USE_QUICHE) && !defined(UNITTESTS)
+#define H3VERSION "h3-29"
+#elif defined(USE_NGTCP2) && !defined(UNITTESTS)
+#define H3VERSION "h3-29"
+#else
+#define H3VERSION "h3"
+#endif
+
 static enum alpnid alpn2alpnid(char *name)
 {
   if(strcasecompare(name, "h1"))
     return ALPN_h1;
   if(strcasecompare(name, "h2"))
     return ALPN_h2;
-  if(strcasecompare(name, "h2c"))
-    return ALPN_h2c;
-  if(strcasecompare(name, "h3"))
+  if(strcasecompare(name, H3VERSION))
     return ALPN_h3;
   return ALPN_none; /* unknown, probably rubbish input */
 }
@@ -69,10 +77,8 @@
     return "h1";
   case ALPN_h2:
     return "h2";
-  case ALPN_h2c:
-    return "h2c";
   case ALPN_h3:
-    return "h3";
+    return H3VERSION;
   default:
     return ""; /* bad */
   }
@@ -81,8 +87,8 @@
 
 static void altsvc_free(struct altsvc *as)
 {
-  free(as->srchost);
-  free(as->dsthost);
+  free(as->src.host);
+  free(as->dst.host);
   free(as);
 }
 
@@ -97,17 +103,17 @@
   if(!as)
     return NULL;
 
-  as->srchost = strdup(srchost);
-  if(!as->srchost)
+  as->src.host = strdup(srchost);
+  if(!as->src.host)
     goto error;
-  as->dsthost = strdup(dsthost);
-  if(!as->dsthost)
+  as->dst.host = strdup(dsthost);
+  if(!as->dst.host)
     goto error;
 
-  as->srcalpnid = srcalpnid;
-  as->dstalpnid = dstalpnid;
-  as->srcport = curlx_ultous(srcport);
-  as->dstport = curlx_ultous(dstport);
+  as->src.alpnid = srcalpnid;
+  as->dst.alpnid = dstalpnid;
+  as->src.port = curlx_ultous(srcport);
+  as->dst.port = curlx_ultous(dstport);
 
   return as;
   error:
@@ -156,14 +162,13 @@
               date, &persist, &prio);
   if(9 == rc) {
     struct altsvc *as;
-    time_t expires = curl_getdate(date, NULL);
+    time_t expires = Curl_getdate_capped(date);
     as = altsvc_create(srchost, dsthost, srcalpn, dstalpn, srcport, dstport);
     if(as) {
       as->expires = expires;
       as->prio = prio;
       as->persist = persist ? 1 : 0;
       Curl_llist_insert_next(&asi->list, asi->list.tail, as, &as->node);
-      asi->num++; /* one more entry */
     }
   }
 
@@ -183,7 +188,16 @@
 {
   CURLcode result = CURLE_OK;
   char *line = NULL;
-  FILE *fp = fopen(file, FOPEN_READTEXT);
+  FILE *fp;
+
+  /* we need a private copy of the file name so that the altsvc cache file
+     name survives an easy handle reset */
+  free(asi->filename);
+  asi->filename = strdup(file);
+  if(!asi->filename)
+    return CURLE_OUT_OF_MEMORY;
+
+  fp = fopen(file, FOPEN_READTEXT);
   if(fp) {
     line = malloc(MAX_ALTSVC_LINE);
     if(!line)
@@ -204,6 +218,7 @@
   return result;
 
   fail:
+  Curl_safefree(asi->filename);
   free(line);
   fclose(fp);
   return CURLE_OUT_OF_MEMORY;
@@ -226,8 +241,8 @@
           "\"%d%02d%02d "
           "%02d:%02d:%02d\" "
           "%u %d\n",
-          Curl_alpnid2str(as->srcalpnid), as->srchost, as->srcport,
-          Curl_alpnid2str(as->dstalpnid), as->dsthost, as->dstport,
+          Curl_alpnid2str(as->src.alpnid), as->src.host, as->src.port,
+          Curl_alpnid2str(as->dst.alpnid), as->dst.host, as->dst.port,
           stamp.tm_year + 1900, stamp.tm_mon + 1, stamp.tm_mday,
           stamp.tm_hour, stamp.tm_min, stamp.tm_sec,
           as->persist, as->prio);
@@ -252,7 +267,7 @@
 #ifdef USE_NGHTTP2
     | CURLALTSVC_H2
 #endif
-#ifdef USE_HTTP3
+#ifdef ENABLE_QUIC
     | CURLALTSVC_H3
 #endif
     ;
@@ -297,6 +312,7 @@
       n = e->next;
       altsvc_free(as);
     }
+    free(altsvc->filename);
     free(altsvc);
   }
 }
@@ -304,34 +320,57 @@
 /*
  * Curl_altsvc_save() writes the altsvc cache to a file.
  */
-CURLcode Curl_altsvc_save(struct altsvcinfo *altsvc, const char *file)
+CURLcode Curl_altsvc_save(struct Curl_easy *data,
+                          struct altsvcinfo *altsvc, const char *file)
 {
   struct curl_llist_element *e;
   struct curl_llist_element *n;
   CURLcode result = CURLE_OK;
   FILE *out;
+  char *tempstore;
+  unsigned char randsuffix[9];
 
   if(!altsvc)
     /* no cache activated */
     return CURLE_OK;
 
-  if((altsvc->flags & CURLALTSVC_READONLYFILE) || !file[0])
-    /* marked as read-only or zero length file name */
+  /* if not new name is given, use the one we stored from the load */
+  if(!file && altsvc->filename)
+    file = altsvc->filename;
+
+  if((altsvc->flags & CURLALTSVC_READONLYFILE) || !file || !file[0])
+    /* marked as read-only, no file or zero length file name */
     return CURLE_OK;
-  out = fopen(file, FOPEN_WRITETEXT);
+
+  if(Curl_rand_hex(data, randsuffix, sizeof(randsuffix)))
+    return CURLE_FAILED_INIT;
+
+  tempstore = aprintf("%s.%s.tmp", file, randsuffix);
+  if(!tempstore)
+    return CURLE_OUT_OF_MEMORY;
+
+  out = fopen(tempstore, FOPEN_WRITETEXT);
   if(!out)
-    return CURLE_WRITE_ERROR;
-  fputs("# Your alt-svc cache. https://curl.haxx.se/docs/alt-svc.html\n"
-        "# This file was generated by libcurl! Edit at your own risk.\n",
-        out);
-  for(e = altsvc->list.head; e; e = n) {
-    struct altsvc *as = e->ptr;
-    n = e->next;
-    result = altsvc_out(as, out);
+    result = CURLE_WRITE_ERROR;
+  else {
+    fputs("# Your alt-svc cache. https://curl.haxx.se/docs/alt-svc.html\n"
+          "# This file was generated by libcurl! Edit at your own risk.\n",
+          out);
+    for(e = altsvc->list.head; e; e = n) {
+      struct altsvc *as = e->ptr;
+      n = e->next;
+      result = altsvc_out(as, out);
+      if(result)
+        break;
+    }
+    fclose(out);
+    if(!result && Curl_rename(tempstore, file))
+      result = CURLE_WRITE_ERROR;
+
     if(result)
-      break;
+      unlink(tempstore);
   }
-  fclose(out);
+  free(tempstore);
   return result;
 }
 
@@ -343,15 +382,15 @@
   while(*p && ISBLANK(*p))
     p++;
   protop = p;
-  while(*p && ISALNUM(*p))
+  while(*p && !ISBLANK(*p) && (*p != ';') && (*p != '='))
     p++;
   len = p - protop;
+  *ptr = p;
 
   if(!len || (len >= buflen))
     return CURLE_BAD_FUNCTION_ARGUMENT;
   memcpy(alpnbuf, protop, len);
   alpnbuf[len] = 0;
-  *ptr = p;
   return CURLE_OK;
 }
 
@@ -365,12 +404,11 @@
   for(e = asi->list.head; e; e = n) {
     struct altsvc *as = e->ptr;
     n = e->next;
-    if((srcalpnid == as->srcalpnid) &&
-       (srcport == as->srcport) &&
-       strcasecompare(srchost, as->srchost)) {
+    if((srcalpnid == as->src.alpnid) &&
+       (srcport == as->src.port) &&
+       strcasecompare(srchost, as->src.host)) {
       Curl_llist_remove(&asi->list, e, NULL);
       altsvc_free(as);
-      asi->num--;
     }
   }
 }
@@ -391,12 +429,18 @@
 #define time(x) debugtime(x)
 #endif
 
+#define ISNEWLINE(x) (((x) == '\n') || (x) == '\r')
+
 /*
  * Curl_altsvc_parse() takes an incoming alt-svc response header and stores
  * the data correctly in the cache.
  *
  * 'value' points to the header *value*. That's contents to the right of the
  * header name.
+ *
+ * Currently this function rejects invalid data without returning an error.
+ * Invalid host name, port number will result in the specific alternative
+ * being rejected. Unknown protocols are skipped.
  */
 CURLcode Curl_altsvc_parse(struct Curl_easy *data,
                            struct altsvcinfo *asi, const char *value,
@@ -410,12 +454,11 @@
   char alpnbuf[MAX_ALTSVC_ALPNLEN] = "";
   struct altsvc *as;
   unsigned short dstport = srcport; /* the same by default */
-  const char *semip;
-  time_t maxage = 24 * 3600; /* default is 24 hours */
-  bool persist = FALSE;
   CURLcode result = getalnum(&p, alpnbuf, sizeof(alpnbuf));
-  if(result)
-    return result;
+  if(result) {
+    infof(data, "Excessive alt-svc header, ignoring...\n");
+    return CURLE_OK;
+  }
 
   DEBUGASSERT(asi);
 
@@ -427,47 +470,20 @@
     return CURLE_OK;
   }
 
-  /* The 'ma' and 'persist' flags are annoyingly meant for all alternatives
-     but are set after the list on the line. Scan for the semicolons and get
-     those fields first! */
-  semip = p;
-  do {
-    semip = strchr(semip, ';');
-    if(semip) {
-      char option[32];
-      unsigned long num;
-      char *end_ptr;
-      semip++; /* pass the semicolon */
-      result = getalnum(&semip, option, sizeof(option));
-      if(result)
-        break;
-      while(*semip && ISBLANK(*semip))
-        semip++;
-      if(*semip != '=')
-        continue;
-      semip++;
-      num = strtoul(semip, &end_ptr, 10);
-      if(num < ULONG_MAX) {
-        if(strcasecompare("ma", option))
-          maxage = num;
-        else if(strcasecompare("persist", option) && (num == 1))
-          persist = TRUE;
-      }
-      semip = end_ptr;
-    }
-  } while(semip);
-
   do {
     if(*p == '=') {
       /* [protocol]="[host][:port]" */
       dstalpnid = alpn2alpnid(alpnbuf);
-      if(!dstalpnid) {
-        infof(data, "Unknown alt-svc protocol \"%s\", ignoring...\n", alpnbuf);
-        return CURLE_OK;
-      }
       p++;
       if(*p == '\"') {
-        const char *dsthost;
+        const char *dsthost = "";
+        const char *value_ptr;
+        char option[32];
+        unsigned long num;
+        char *end_ptr;
+        bool quoted = FALSE;
+        time_t maxage = 24 * 3600; /* default is 24 hours */
+        bool persist = FALSE;
         p++;
         if(*p != ':') {
           /* host name starts here */
@@ -475,11 +491,15 @@
           while(*p && (ISALNUM(*p) || (*p == '.') || (*p == '-')))
             p++;
           len = p - hostp;
-          if(!len || (len >= MAX_ALTSVC_HOSTLEN))
-            return CURLE_BAD_FUNCTION_ARGUMENT;
-          memcpy(namebuf, hostp, len);
-          namebuf[len] = 0;
-          dsthost = namebuf;
+          if(!len || (len >= MAX_ALTSVC_HOSTLEN)) {
+            infof(data, "Excessive alt-svc host name, ignoring...\n");
+            dstalpnid = ALPN_none;
+          }
+          else {
+            memcpy(namebuf, hostp, len);
+            namebuf[len] = 0;
+            dsthost = namebuf;
+          }
         }
         else {
           /* no destination name, use source host */
@@ -487,31 +507,85 @@
         }
         if(*p == ':') {
           /* a port number */
-          char *end_ptr;
           unsigned long port = strtoul(++p, &end_ptr, 10);
           if(port > USHRT_MAX || end_ptr == p || *end_ptr != '\"') {
             infof(data, "Unknown alt-svc port number, ignoring...\n");
-            return CURLE_OK;
+            dstalpnid = ALPN_none;
           }
           p = end_ptr;
           dstport = curlx_ultous(port);
         }
         if(*p++ != '\"')
-          return CURLE_BAD_FUNCTION_ARGUMENT;
-        as = altsvc_createid(srchost, dsthost,
-                             srcalpnid, dstalpnid,
-                             srcport, dstport);
-        if(as) {
-          /* The expires time also needs to take the Age: value (if any) into
-             account. [See RFC 7838 section 3.1] */
-          as->expires = maxage + time(NULL);
-          as->persist = persist;
-          Curl_llist_insert_next(&asi->list, asi->list.tail, as, &as->node);
-          asi->num++; /* one more entry */
-          infof(data, "Added alt-svc: %s:%d over %s\n", dsthost, dstport,
-                Curl_alpnid2str(dstalpnid));
+          break;
+        /* Handle the optional 'ma' and 'persist' flags. Unknown flags
+           are skipped. */
+        for(;;) {
+          while(ISBLANK(*p))
+            p++;
+          if(*p != ';')
+            break;
+          p++; /* pass the semicolon */
+          if(!*p || ISNEWLINE(*p))
+            break;
+          result = getalnum(&p, option, sizeof(option));
+          if(result) {
+            /* skip option if name is too long */
+            option[0] = '\0';
+          }
+          while(*p && ISBLANK(*p))
+            p++;
+          if(*p != '=')
+            return CURLE_OK;
+          p++;
+          while(*p && ISBLANK(*p))
+            p++;
+          if(!*p)
+            return CURLE_OK;
+          if(*p == '\"') {
+            /* quoted value */
+            p++;
+            quoted = TRUE;
+          }
+          value_ptr = p;
+          if(quoted) {
+            while(*p && *p != '\"')
+              p++;
+            if(!*p++)
+              return CURLE_OK;
+          }
+          else {
+            while(*p && !ISBLANK(*p) && *p!= ';' && *p != ',')
+              p++;
+          }
+          num = strtoul(value_ptr, &end_ptr, 10);
+          if((end_ptr != value_ptr) && (num < ULONG_MAX)) {
+            if(strcasecompare("ma", option))
+              maxage = num;
+            else if(strcasecompare("persist", option) && (num == 1))
+              persist = TRUE;
+          }
+        }
+        if(dstalpnid) {
+          as = altsvc_createid(srchost, dsthost,
+                               srcalpnid, dstalpnid,
+                               srcport, dstport);
+          if(as) {
+            /* The expires time also needs to take the Age: value (if any) into
+               account. [See RFC 7838 section 3.1] */
+            as->expires = maxage + time(NULL);
+            as->persist = persist;
+            Curl_llist_insert_next(&asi->list, asi->list.tail, as, &as->node);
+            infof(data, "Added alt-svc: %s:%d over %s\n", dsthost, dstport,
+                  Curl_alpnid2str(dstalpnid));
+          }
+        }
+        else {
+          infof(data, "Unknown alt-svc protocol \"%s\", skipping...\n",
+                alpnbuf);
         }
       }
+      else
+        break;
       /* after the double quote there can be a comma if there's another
          string or a semicolon if no more */
       if(*p == ',') {
@@ -519,11 +593,11 @@
         p++;
         result = getalnum(&p, alpnbuf, sizeof(alpnbuf));
         if(result)
-          /* failed to parse, but since we already did at least one host we
-             return OK */
-          return CURLE_OK;
+          break;
       }
     }
+    else
+      break;
   } while(*p && (*p != ';') && (*p != '\n') && (*p != '\r'));
 
   return CURLE_OK;
@@ -535,31 +609,31 @@
 bool Curl_altsvc_lookup(struct altsvcinfo *asi,
                         enum alpnid srcalpnid, const char *srchost,
                         int srcport,
-                        enum alpnid *dstalpnid, const char **dsthost,
-                        int *dstport)
+                        struct altsvc **dstentry,
+                        const int versions) /* one or more bits */
 {
   struct curl_llist_element *e;
   struct curl_llist_element *n;
   time_t now = time(NULL);
   DEBUGASSERT(asi);
   DEBUGASSERT(srchost);
-  DEBUGASSERT(dsthost);
+  DEBUGASSERT(dstentry);
 
   for(e = asi->list.head; e; e = n) {
     struct altsvc *as = e->ptr;
     n = e->next;
     if(as->expires < now) {
       /* an expired entry, remove */
+      Curl_llist_remove(&asi->list, e, NULL);
       altsvc_free(as);
       continue;
     }
-    if((as->srcalpnid == srcalpnid) &&
-       strcasecompare(as->srchost, srchost) &&
-       as->srcport == srcport) {
+    if((as->src.alpnid == srcalpnid) &&
+       strcasecompare(as->src.host, srchost) &&
+       (as->src.port == srcport) &&
+       (versions & as->dst.alpnid)) {
       /* match */
-      *dstalpnid = as->dstalpnid;
-      *dsthost = as->dsthost;
-      *dstport = as->dstport;
+      *dstentry = as;
       return TRUE;
     }
   }
diff --git a/Utilities/cmcurl/lib/altsvc.h b/Utilities/cmcurl/lib/altsvc.h
index eefb45b..578a4fb 100644
--- a/Utilities/cmcurl/lib/altsvc.h
+++ b/Utilities/cmcurl/lib/altsvc.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 2019 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -28,20 +28,21 @@
 #include "llist.h"
 
 enum alpnid {
-  ALPN_none,
-  ALPN_h1,
-  ALPN_h2,
-  ALPN_h2c,
-  ALPN_h3
+  ALPN_none = 0,
+  ALPN_h1 = CURLALTSVC_H1,
+  ALPN_h2 = CURLALTSVC_H2,
+  ALPN_h3 = CURLALTSVC_H3
+};
+
+struct althost {
+  char *host;
+  unsigned short port;
+  enum alpnid alpnid;
 };
 
 struct altsvc {
-  char *srchost;
-  char *dsthost;
-  unsigned short srcport;
-  unsigned short dstport;
-  enum alpnid srcalpnid;
-  enum alpnid dstalpnid;
+  struct althost src;
+  struct althost dst;
   time_t expires;
   bool persist;
   int prio;
@@ -51,14 +52,14 @@
 struct altsvcinfo {
   char *filename;
   struct curl_llist list; /* list of entries */
-  size_t num; /* number of alt-svc entries */
   long flags; /* the publicly set bitmask */
 };
 
 const char *Curl_alpnid2str(enum alpnid id);
 struct altsvcinfo *Curl_altsvc_init(void);
 CURLcode Curl_altsvc_load(struct altsvcinfo *asi, const char *file);
-CURLcode Curl_altsvc_save(struct altsvcinfo *asi, const char *file);
+CURLcode Curl_altsvc_save(struct Curl_easy *data,
+                          struct altsvcinfo *asi, const char *file);
 CURLcode Curl_altsvc_ctrl(struct altsvcinfo *asi, const long ctrl);
 void Curl_altsvc_cleanup(struct altsvcinfo *altsvc);
 CURLcode Curl_altsvc_parse(struct Curl_easy *data,
@@ -68,10 +69,10 @@
 bool Curl_altsvc_lookup(struct altsvcinfo *asi,
                         enum alpnid srcalpnid, const char *srchost,
                         int srcport,
-                        enum alpnid *dstalpnid, const char **dsthost,
-                        int *dstport);
+                        struct altsvc **dstentry,
+                        const int versions); /* CURLALTSVC_H* bits */
 #else
 /* disabled */
-#define Curl_altsvc_save(a,b)
+#define Curl_altsvc_save(a,b,c)
 #endif /* CURL_DISABLE_HTTP || USE_ALTSVC */
 #endif /* HEADER_CURL_ALTSVC_H */
diff --git a/Utilities/cmcurl/lib/asyn-ares.c b/Utilities/cmcurl/lib/asyn-ares.c
index 8561a47..ba5160b 100644
--- a/Utilities/cmcurl/lib/asyn-ares.c
+++ b/Utilities/cmcurl/lib/asyn-ares.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -87,7 +87,8 @@
 
 struct ResolverResults {
   int num_pending; /* number of ares_gethostbyname() requests */
-  Curl_addrinfo *temp_ai; /* intermediary result while fetching c-ares parts */
+  struct Curl_addrinfo *temp_ai; /* intermediary result while fetching c-ares
+                                    parts */
   int last_status;
   struct curltime happy_eyeballs_dns_time; /* when this timer started, or 0 */
 };
@@ -253,16 +254,14 @@
  */
 
 int Curl_resolver_getsock(struct connectdata *conn,
-                          curl_socket_t *socks,
-                          int numsocks)
-
+                          curl_socket_t *socks)
 {
   struct timeval maxtime;
   struct timeval timebuf;
   struct timeval *timeout;
   long milli;
   int max = ares_getsock((ares_channel)conn->data->state.resolver,
-                         (ares_socket_t *)socks, numsocks);
+                         (ares_socket_t *)socks, MAX_SOCKSPEREASYHANDLE);
 
   maxtime.tv_sec = CURL_TIMEOUT_RESOLVE;
   maxtime.tv_usec = 0;
@@ -287,7 +286,7 @@
  * return number of sockets it worked on
  */
 
-static int waitperform(struct connectdata *conn, int timeout_ms)
+static int waitperform(struct connectdata *conn, timediff_t timeout_ms)
 {
   struct Curl_easy *data = conn->data;
   int nfds;
@@ -354,8 +353,8 @@
     conn->async.os_specific;
   CURLcode result = CURLE_OK;
 
-  if(dns)
-    *dns = NULL;
+  DEBUGASSERT(dns);
+  *dns = NULL;
 
   waitperform(conn, 0);
 
@@ -383,19 +382,18 @@
   }
 
   if(res && !res->num_pending) {
-    if(dns) {
-      (void)Curl_addrinfo_callback(conn, res->last_status, res->temp_ai);
-      /* temp_ai ownership is moved to the connection, so we need not free-up
-         them */
-      res->temp_ai = NULL;
-    }
+    (void)Curl_addrinfo_callback(conn, res->last_status, res->temp_ai);
+    /* temp_ai ownership is moved to the connection, so we need not free-up
+       them */
+    res->temp_ai = NULL;
+
     if(!conn->async.dns) {
       failf(data, "Could not resolve: %s (%s)",
             conn->async.hostname, ares_strerror(conn->async.status));
       result = conn->bits.proxy?CURLE_COULDNT_RESOLVE_PROXY:
         CURLE_COULDNT_RESOLVE_HOST;
     }
-    else if(dns)
+    else
       *dns = conn->async.dns;
 
     destroy_async_data(&conn->async);
@@ -410,7 +408,7 @@
  * Waits for a resolve to finish. This function should be avoided since using
  * this risk getting the multi interface to "hang".
  *
- * If 'entry' is non-NULL, make it point to the resolved dns entry
+ * 'entry' MUST be non-NULL.
  *
  * Returns CURLE_COULDNT_RESOLVE_HOST if the host was not resolved,
  * CURLE_OPERATION_TIMEDOUT if a time-out occurred, or other errors.
@@ -422,10 +420,9 @@
   struct Curl_easy *data = conn->data;
   timediff_t timeout;
   struct curltime now = Curl_now();
-  struct Curl_dns_entry *temp_entry;
 
-  if(entry)
-    *entry = NULL; /* clear on entry */
+  DEBUGASSERT(entry);
+  *entry = NULL; /* clear on entry */
 
   timeout = Curl_timeleft(data, &now, TRUE);
   if(timeout < 0) {
@@ -440,9 +437,13 @@
   while(!result) {
     struct timeval *tvp, tv, store;
     int itimeout;
-    int timeout_ms;
+    timediff_t timeout_ms;
 
-    itimeout = (timeout > (long)INT_MAX) ? INT_MAX : (int)timeout;
+#if TIMEDIFF_T_MAX > INT_MAX
+    itimeout = (timeout > INT_MAX) ? INT_MAX : (int)timeout;
+#else
+    itimeout = (int)timeout;
+#endif
 
     store.tv_sec = itimeout/1000;
     store.tv_usec = (itimeout%1000)*1000;
@@ -453,12 +454,12 @@
        second is left, otherwise just use 1000ms to make sure the progress
        callback gets called frequent enough */
     if(!tvp->tv_sec)
-      timeout_ms = (int)(tvp->tv_usec/1000);
+      timeout_ms = (timediff_t)(tvp->tv_usec/1000);
     else
       timeout_ms = 1000;
 
     waitperform(conn, timeout_ms);
-    result = Curl_resolver_is_resolved(conn, entry?&temp_entry:NULL);
+    result = Curl_resolver_is_resolved(conn, entry);
 
     if(result || conn->async.done)
       break;
@@ -473,7 +474,7 @@
       else if(timediff > timeout)
         timeout = -1;
       else
-        timeout -= (long)timediff;
+        timeout -= timediff;
       now = now2; /* for next loop */
     }
     if(timeout < 0)
@@ -498,9 +499,9 @@
 
 /* Connects results to the list */
 static void compound_results(struct ResolverResults *res,
-                             Curl_addrinfo *ai)
+                             struct Curl_addrinfo *ai)
 {
-  Curl_addrinfo *ai_tail;
+  struct Curl_addrinfo *ai_tail;
   if(!ai)
     return;
   ai_tail = ai;
@@ -542,7 +543,7 @@
     res->num_pending--;
 
     if(CURL_ASYNC_SUCCESS == status) {
-      Curl_addrinfo *ai = Curl_he2ai(hostent, conn->async.port);
+      struct Curl_addrinfo *ai = Curl_he2ai(hostent, conn->async.port);
       if(ai) {
         compound_results(res, ai);
       }
@@ -621,33 +622,18 @@
  * memory we need to free after use. That memory *MUST* be freed with
  * Curl_freeaddrinfo(), nothing else.
  */
-Curl_addrinfo *Curl_resolver_getaddrinfo(struct connectdata *conn,
-                                         const char *hostname,
-                                         int port,
-                                         int *waitp)
+struct Curl_addrinfo *Curl_resolver_getaddrinfo(struct connectdata *conn,
+                                                const char *hostname,
+                                                int port,
+                                                int *waitp)
 {
   char *bufp;
   struct Curl_easy *data = conn->data;
-  struct in_addr in;
   int family = PF_INET;
-#ifdef ENABLE_IPV6 /* CURLRES_IPV6 */
-  struct in6_addr in6;
-#endif /* CURLRES_IPV6 */
 
   *waitp = 0; /* default to synchronous response */
 
-  /* First check if this is an IPv4 address string */
-  if(Curl_inet_pton(AF_INET, hostname, &in) > 0) {
-    /* This is a dotted IP address 123.123.123.123-style */
-    return Curl_ip2addr(AF_INET, &in, hostname, port);
-  }
-
 #ifdef ENABLE_IPV6 /* CURLRES_IPV6 */
-  /* Otherwise, check if this is an IPv6 address string */
-  if(Curl_inet_pton (AF_INET6, hostname, &in6) > 0)
-    /* This must be an IPv6 address literal.  */
-    return Curl_ip2addr(AF_INET6, &in6, hostname, port);
-
   switch(conn->ip_version) {
   default:
 #if ARES_VERSION >= 0x010601
@@ -686,7 +672,7 @@
     res->last_status = ARES_ENOTFOUND;
 #ifdef ENABLE_IPV6 /* CURLRES_IPV6 */
     if(family == PF_UNSPEC) {
-      if(Curl_ipv6works()) {
+      if(Curl_ipv6works(conn)) {
         res->num_pending = 2;
 
         /* areschannel is already setup in the Curl_open() function */
@@ -734,7 +720,11 @@
     return CURLE_OK;
 
 #if (ARES_VERSION >= 0x010704)
+#if (ARES_VERSION >= 0x010b00)
+  ares_result = ares_set_servers_ports_csv(data->state.resolver, servers);
+#else
   ares_result = ares_set_servers_csv(data->state.resolver, servers);
+#endif
   switch(ares_result) {
   case ARES_SUCCESS:
     result = CURLE_OK;
diff --git a/Utilities/cmcurl/lib/asyn-thread.c b/Utilities/cmcurl/lib/asyn-thread.c
index 55e0811..a60f4f0 100644
--- a/Utilities/cmcurl/lib/asyn-thread.c
+++ b/Utilities/cmcurl/lib/asyn-thread.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -21,6 +21,7 @@
  ***************************************************************************/
 
 #include "curl_setup.h"
+#include "socketpair.h"
 
 /***********************************************************************
  * Only for threaded name resolves builds
@@ -70,10 +71,10 @@
 #include "strerror.h"
 #include "url.h"
 #include "multiif.h"
-#include "inet_pton.h"
 #include "inet_ntop.h"
 #include "curl_threads.h"
 #include "connect.h"
+#include "socketpair.h"
 /* The last 3 #include files should be in this order */
 #include "curl_printf.h"
 #include "curl_memory.h"
@@ -157,14 +158,18 @@
 
 /* Data for synchronization between resolver thread and its parent */
 struct thread_sync_data {
-  curl_mutex_t * mtx;
+  curl_mutex_t *mtx;
   int done;
 
   char *hostname;        /* hostname to resolve, Curl_async.hostname
                             duplicate */
   int port;
+#ifdef USE_SOCKETPAIR
+  struct connectdata *conn;
+  curl_socket_t sock_pair[2]; /* socket pair */
+#endif
   int sock_error;
-  Curl_addrinfo *res;
+  struct Curl_addrinfo *res;
 #ifdef HAVE_GETADDRINFO
   struct addrinfo hints;
 #endif
@@ -174,7 +179,7 @@
 struct thread_data {
   curl_thread_t thread_hnd;
   unsigned int poll_interval;
-  time_t interval_end;
+  timediff_t interval_end;
   struct thread_sync_data tsd;
 };
 
@@ -185,7 +190,7 @@
 
 /* Destroy resolver thread synchronization data */
 static
-void destroy_thread_sync_data(struct thread_sync_data * tsd)
+void destroy_thread_sync_data(struct thread_sync_data *tsd)
 {
   if(tsd->mtx) {
     Curl_mutex_destroy(tsd->mtx);
@@ -197,12 +202,21 @@
   if(tsd->res)
     Curl_freeaddrinfo(tsd->res);
 
+#ifdef USE_SOCKETPAIR
+  /*
+   * close one end of the socket pair (may be done in resolver thread);
+   * the other end (for reading) is always closed in the parent thread.
+   */
+  if(tsd->sock_pair[1] != CURL_SOCKET_BAD) {
+    sclose(tsd->sock_pair[1]);
+  }
+#endif
   memset(tsd, 0, sizeof(*tsd));
 }
 
 /* Initialize resolver thread synchronization data */
 static
-int init_thread_sync_data(struct thread_data * td,
+int init_thread_sync_data(struct thread_data *td,
                            const char *hostname,
                            int port,
                            const struct addrinfo *hints)
@@ -230,6 +244,14 @@
 
   Curl_mutex_init(tsd->mtx);
 
+#ifdef USE_SOCKETPAIR
+  /* create socket pair, avoid AF_LOCAL since it doesn't build on Solaris */
+  if(Curl_socketpair(AF_UNIX, SOCK_STREAM, 0, &tsd->sock_pair[0]) < 0) {
+    tsd->sock_pair[0] = CURL_SOCKET_BAD;
+    tsd->sock_pair[1] = CURL_SOCKET_BAD;
+    goto err_exit;
+  }
+#endif
   tsd->sock_error = CURL_ASYNC_SUCCESS;
 
   /* Copying hostname string because original can be destroyed by parent
@@ -276,6 +298,9 @@
   struct thread_data *td = tsd->td;
   char service[12];
   int rc;
+#ifdef USE_SOCKETPAIR
+  char buf[1];
+#endif
 
   msnprintf(service, sizeof(service), "%d", tsd->port);
 
@@ -298,6 +323,16 @@
     free(td);
   }
   else {
+#ifdef USE_SOCKETPAIR
+    if(tsd->sock_pair[1] != CURL_SOCKET_BAD) {
+      /* DNS has been resolved, signal client task */
+      buf[0] = 1;
+      if(swrite(tsd->sock_pair[1],  buf, sizeof(buf)) < 0) {
+        /* update sock_erro to errno */
+        tsd->sock_error = SOCKERRNO;
+      }
+    }
+#endif
     tsd->done = 1;
     Curl_mutex_release(tsd->mtx);
   }
@@ -348,6 +383,10 @@
   if(async->os_specific) {
     struct thread_data *td = (struct thread_data*) async->os_specific;
     int done;
+#ifdef USE_SOCKETPAIR
+    curl_socket_t sock_rd = td->tsd.sock_pair[0];
+    struct connectdata *conn = td->tsd.conn;
+#endif
 
     /*
      * if the thread is still blocking in the resolve syscall, detach it and
@@ -369,6 +408,15 @@
 
       free(async->os_specific);
     }
+#ifdef USE_SOCKETPAIR
+    /*
+     * ensure CURLMOPT_SOCKETFUNCTION fires CURL_POLL_REMOVE
+     * before the FD is invalidated to avoid EBADF on EPOLL_CTL_DEL
+     */
+    if(conn)
+      Curl_multi_closed(conn->data, sock_rd);
+    sclose(sock_rd);
+#endif
   }
   async->os_specific = NULL;
 
@@ -446,11 +494,14 @@
   const char *host_or_proxy;
   CURLcode result;
 
+#ifndef CURL_DISABLE_PROXY
   if(conn->bits.httpproxy) {
     host_or_proxy = "proxy";
     result = CURLE_COULDNT_RESOLVE_PROXY;
   }
-  else {
+  else
+#endif
+  {
     host_or_proxy = "host";
     result = CURLE_COULDNT_RESOLVE_HOST;
   }
@@ -461,6 +512,9 @@
   return result;
 }
 
+/*
+ * 'entry' may be NULL and then no data is returned
+ */
 static CURLcode thread_wait_resolv(struct connectdata *conn,
                                    struct Curl_dns_entry **entry,
                                    bool report)
@@ -545,6 +599,7 @@
   struct thread_data   *td = (struct thread_data*) conn->async.os_specific;
   int done = 0;
 
+  DEBUGASSERT(entry);
   *entry = NULL;
 
   if(!td) {
@@ -569,6 +624,7 @@
   }
   else {
     /* poll for name lookup done with exponential backoff up to 250ms */
+    /* should be fine even if this converts to 32 bit */
     timediff_t elapsed = Curl_timediff(Curl_now(),
                                        data->progress.t_startsingle);
     if(elapsed < 0)
@@ -592,47 +648,61 @@
 }
 
 int Curl_resolver_getsock(struct connectdata *conn,
-                          curl_socket_t *socks,
-                          int numsocks)
+                          curl_socket_t *socks)
 {
-  time_t milli;
+  int ret_val = 0;
+  timediff_t milli;
   timediff_t ms;
   struct Curl_easy *data = conn->data;
   struct resdata *reslv = (struct resdata *)data->state.resolver;
+#ifdef USE_SOCKETPAIR
+  struct thread_data *td = (struct thread_data*)conn->async.os_specific;
+#else
   (void)socks;
-  (void)numsocks;
-  ms = Curl_timediff(Curl_now(), reslv->start);
-  if(ms < 3)
-    milli = 0;
-  else if(ms <= 50)
-    milli = ms/3;
-  else if(ms <= 250)
-    milli = 50;
-  else
-    milli = 200;
-  Curl_expire(data, milli, EXPIRE_ASYNC_NAME);
-  return 0;
+#endif
+
+#ifdef USE_SOCKETPAIR
+  if(td) {
+    /* return read fd to client for polling the DNS resolution status */
+    socks[0] = td->tsd.sock_pair[0];
+    DEBUGASSERT(td->tsd.conn == conn || !td->tsd.conn);
+    td->tsd.conn = conn;
+    ret_val = GETSOCK_READSOCK(0);
+  }
+  else {
+#endif
+    ms = Curl_timediff(Curl_now(), reslv->start);
+    if(ms < 3)
+      milli = 0;
+    else if(ms <= 50)
+      milli = ms/3;
+    else if(ms <= 250)
+      milli = 50;
+    else
+      milli = 200;
+    Curl_expire(data, milli, EXPIRE_ASYNC_NAME);
+#ifdef USE_SOCKETPAIR
+  }
+#endif
+
+
+  return ret_val;
 }
 
 #ifndef HAVE_GETADDRINFO
 /*
  * Curl_getaddrinfo() - for platforms without getaddrinfo
  */
-Curl_addrinfo *Curl_resolver_getaddrinfo(struct connectdata *conn,
-                                         const char *hostname,
-                                         int port,
-                                         int *waitp)
+struct Curl_addrinfo *Curl_resolver_getaddrinfo(struct connectdata *conn,
+                                                const char *hostname,
+                                                int port,
+                                                int *waitp)
 {
-  struct in_addr in;
   struct Curl_easy *data = conn->data;
   struct resdata *reslv = (struct resdata *)data->state.resolver;
 
   *waitp = 0; /* default to synchronous response */
 
-  if(Curl_inet_pton(AF_INET, hostname, &in) > 0)
-    /* This is a dotted IP address 123.123.123.123-style */
-    return Curl_ip2addr(AF_INET, &in, hostname, port);
-
   reslv->start = Curl_now();
 
   /* fire up a new resolver thread! */
@@ -651,38 +721,18 @@
 /*
  * Curl_resolver_getaddrinfo() - for getaddrinfo
  */
-Curl_addrinfo *Curl_resolver_getaddrinfo(struct connectdata *conn,
-                                         const char *hostname,
-                                         int port,
-                                         int *waitp)
+struct Curl_addrinfo *Curl_resolver_getaddrinfo(struct connectdata *conn,
+                                                const char *hostname,
+                                                int port,
+                                                int *waitp)
 {
   struct addrinfo hints;
-  char sbuf[12];
   int pf = PF_INET;
   struct Curl_easy *data = conn->data;
   struct resdata *reslv = (struct resdata *)data->state.resolver;
 
   *waitp = 0; /* default to synchronous response */
 
-#ifndef USE_RESOLVE_ON_IPS
-  {
-    struct in_addr in;
-    /* First check if this is an IPv4 address string */
-    if(Curl_inet_pton(AF_INET, hostname, &in) > 0)
-      /* This is a dotted IP address 123.123.123.123-style */
-      return Curl_ip2addr(AF_INET, &in, hostname, port);
-  }
-#ifdef CURLRES_IPV6
-  {
-    struct in6_addr in6;
-    /* check if this is an IPv6 address string */
-    if(Curl_inet_pton(AF_INET6, hostname, &in6) > 0)
-      /* This is an IPv6 address literal */
-      return Curl_ip2addr(AF_INET6, &in6, hostname, port);
-  }
-#endif /* CURLRES_IPV6 */
-#endif /* !USE_RESOLVE_ON_IPS */
-
 #ifdef CURLRES_IPV6
   /*
    * Check if a limited name resolve has been requested.
@@ -699,16 +749,15 @@
     break;
   }
 
-  if((pf != PF_INET) && !Curl_ipv6works())
+  if((pf != PF_INET) && !Curl_ipv6works(conn))
     /* The stack seems to be a non-IPv6 one */
     pf = PF_INET;
 #endif /* CURLRES_IPV6 */
 
   memset(&hints, 0, sizeof(hints));
   hints.ai_family = pf;
-  hints.ai_socktype = conn->socktype;
-
-  msnprintf(sbuf, sizeof(sbuf), "%d", port);
+  hints.ai_socktype = (conn->transport == TRNSPRT_TCP)?
+    SOCK_STREAM : SOCK_DGRAM;
 
   reslv->start = Curl_now();
   /* fire up a new resolver thread! */
diff --git a/Utilities/cmcurl/lib/asyn.h b/Utilities/cmcurl/lib/asyn.h
index ccd4b1f..be2796c 100644
--- a/Utilities/cmcurl/lib/asyn.h
+++ b/Utilities/cmcurl/lib/asyn.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -114,8 +114,7 @@
  * return bitmask indicating what file descriptors (referring to array indexes
  * in the 'sock' array) to wait for, read/write.
  */
-int Curl_resolver_getsock(struct connectdata *conn, curl_socket_t *sock,
-                          int numsocks);
+int Curl_resolver_getsock(struct connectdata *conn, curl_socket_t *sock);
 
 /*
  * Curl_resolver_is_resolved()
@@ -154,10 +153,10 @@
  * Each resolver backend must of course make sure to return data in the
  * correct format to comply with this.
  */
-Curl_addrinfo *Curl_resolver_getaddrinfo(struct connectdata *conn,
-                                         const char *hostname,
-                                         int port,
-                                         int *waitp);
+struct Curl_addrinfo *Curl_resolver_getaddrinfo(struct connectdata *conn,
+                                                const char *hostname,
+                                                int port,
+                                                int *waitp);
 
 #ifndef CURLRES_ASYNCH
 /* convert these functions if an asynch resolver isn't used */
diff --git a/Utilities/cmcurl/lib/base64.c b/Utilities/cmcurl/lib/base64.c
index fb081a6..643cef6 100644
--- a/Utilities/cmcurl/lib/base64.c
+++ b/Utilities/cmcurl/lib/base64.c
@@ -24,8 +24,8 @@
 
 #include "curl_setup.h"
 
-#if !defined(CURL_DISABLE_HTTP_AUTH) || defined(USE_LIBSSH2) || \
-  defined(USE_LIBSSH) || !defined(CURL_DISABLE_LDAP) || \
+#if !defined(CURL_DISABLE_HTTP_AUTH) || defined(USE_SSH) || \
+  !defined(CURL_DISABLE_LDAP) || \
   !defined(CURL_DISABLE_DOH) || defined(USE_SSL)
 
 #include "urldata.h" /* for the Curl_easy definition */
diff --git a/Utilities/cmcurl/lib/conncache.c b/Utilities/cmcurl/lib/conncache.c
index 5350919..d21a00c 100644
--- a/Utilities/cmcurl/lib/conncache.c
+++ b/Utilities/cmcurl/lib/conncache.c
@@ -6,7 +6,7 @@
  *                             \___|\___/|_| \_\_____|
  *
  * Copyright (C) 2012 - 2016, Linus Nielsen Feltzing, <linus@haxx.se>
- * Copyright (C) 2012 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 2012 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -40,26 +40,7 @@
 #include "curl_memory.h"
 #include "memdebug.h"
 
-#ifdef CURLDEBUG
-/* the debug versions of these macros make extra certain that the lock is
-   never doubly locked or unlocked */
-#define CONN_LOCK(x) if((x)->share) {                                   \
-    Curl_share_lock((x), CURL_LOCK_DATA_CONNECT, CURL_LOCK_ACCESS_SINGLE); \
-    DEBUGASSERT(!(x)->state.conncache_lock);                            \
-    (x)->state.conncache_lock = TRUE;                                   \
-  }
-
-#define CONN_UNLOCK(x) if((x)->share) {                                 \
-    DEBUGASSERT((x)->state.conncache_lock);                             \
-    (x)->state.conncache_lock = FALSE;                                  \
-    Curl_share_unlock((x), CURL_LOCK_DATA_CONNECT);                     \
-  }
-#else
-#define CONN_LOCK(x) if((x)->share)                                     \
-    Curl_share_lock((x), CURL_LOCK_DATA_CONNECT, CURL_LOCK_ACCESS_SINGLE)
-#define CONN_UNLOCK(x) if((x)->share)                   \
-    Curl_share_unlock((x), CURL_LOCK_DATA_CONNECT)
-#endif
+#define HASHKEY_SIZE 128
 
 static void conn_llist_dtor(void *user, void *element)
 {
@@ -68,58 +49,57 @@
   conn->bundle = NULL;
 }
 
-static CURLcode bundle_create(struct Curl_easy *data,
-                              struct connectbundle **cb_ptr)
+static CURLcode bundle_create(struct connectbundle **bundlep)
 {
-  (void)data;
-  DEBUGASSERT(*cb_ptr == NULL);
-  *cb_ptr = malloc(sizeof(struct connectbundle));
-  if(!*cb_ptr)
+  DEBUGASSERT(*bundlep == NULL);
+  *bundlep = malloc(sizeof(struct connectbundle));
+  if(!*bundlep)
     return CURLE_OUT_OF_MEMORY;
 
-  (*cb_ptr)->num_connections = 0;
-  (*cb_ptr)->multiuse = BUNDLE_UNKNOWN;
+  (*bundlep)->num_connections = 0;
+  (*bundlep)->multiuse = BUNDLE_UNKNOWN;
 
-  Curl_llist_init(&(*cb_ptr)->conn_list, (curl_llist_dtor) conn_llist_dtor);
+  Curl_llist_init(&(*bundlep)->conn_list, (curl_llist_dtor) conn_llist_dtor);
   return CURLE_OK;
 }
 
-static void bundle_destroy(struct connectbundle *cb_ptr)
+static void bundle_destroy(struct connectbundle *bundle)
 {
-  if(!cb_ptr)
+  if(!bundle)
     return;
 
-  Curl_llist_destroy(&cb_ptr->conn_list, NULL);
+  Curl_llist_destroy(&bundle->conn_list, NULL);
 
-  free(cb_ptr);
+  free(bundle);
 }
 
 /* Add a connection to a bundle */
-static void bundle_add_conn(struct connectbundle *cb_ptr,
+static void bundle_add_conn(struct connectbundle *bundle,
                             struct connectdata *conn)
 {
-  Curl_llist_insert_next(&cb_ptr->conn_list, cb_ptr->conn_list.tail, conn,
+  Curl_llist_insert_next(&bundle->conn_list, bundle->conn_list.tail, conn,
                          &conn->bundle_node);
-  conn->bundle = cb_ptr;
-  cb_ptr->num_connections++;
+  conn->bundle = bundle;
+  bundle->num_connections++;
 }
 
 /* Remove a connection from a bundle */
-static int bundle_remove_conn(struct connectbundle *cb_ptr,
+static int bundle_remove_conn(struct connectbundle *bundle,
                               struct connectdata *conn)
 {
   struct curl_llist_element *curr;
 
-  curr = cb_ptr->conn_list.head;
+  curr = bundle->conn_list.head;
   while(curr) {
     if(curr->ptr == conn) {
-      Curl_llist_remove(&cb_ptr->conn_list, curr, NULL);
-      cb_ptr->num_connections--;
+      Curl_llist_remove(&bundle->conn_list, curr, NULL);
+      bundle->num_connections--;
       conn->bundle = NULL;
       return 1; /* we removed a handle */
     }
     curr = curr->next;
   }
+  DEBUGASSERT(0);
   return 0;
 }
 
@@ -141,10 +121,8 @@
 
   rc = Curl_hash_init(&connc->hash, size, Curl_hash_str,
                       Curl_str_key_compare, free_bundle_hash_entry);
-  if(rc) {
-    Curl_close(connc->closure_handle);
-    connc->closure_handle = NULL;
-  }
+  if(rc)
+    Curl_close(&connc->closure_handle);
   else
     connc->closure_handle->state.conn_cache = connc;
 
@@ -159,28 +137,30 @@
 
 /* creates a key to find a bundle for this connection */
 static void hashkey(struct connectdata *conn, char *buf,
-                    size_t len) /* something like 128 is fine */
+                    size_t len,  /* something like 128 is fine */
+                    const char **hostp)
 {
   const char *hostname;
+  long port = conn->remote_port;
 
-  if(conn->bits.socksproxy)
-    hostname = conn->socks_proxy.host.name;
-  else if(conn->bits.httpproxy)
+#ifndef CURL_DISABLE_PROXY
+  if(conn->bits.httpproxy && !conn->bits.tunnel_proxy) {
     hostname = conn->http_proxy.host.name;
-  else if(conn->bits.conn_to_host)
-    hostname = conn->conn_to_host.name;
+    port = conn->port;
+  }
+  else
+#endif
+    if(conn->bits.conn_to_host)
+      hostname = conn->conn_to_host.name;
   else
     hostname = conn->host.name;
 
-  DEBUGASSERT(len > 32);
+  if(hostp)
+    /* report back which name we used */
+    *hostp = hostname;
 
   /* put the number first so that the hostname gets cut off if too long */
-  msnprintf(buf, len, "%ld%s", conn->port, hostname);
-}
-
-void Curl_conncache_unlock(struct Curl_easy *data)
-{
-  CONN_UNLOCK(data);
+  msnprintf(buf, len, "%ld%s", port, hostname);
 }
 
 /* Returns number of connections currently held in the connection cache.
@@ -189,21 +169,9 @@
 size_t Curl_conncache_size(struct Curl_easy *data)
 {
   size_t num;
-  CONN_LOCK(data);
+  CONNCACHE_LOCK(data);
   num = data->state.conn_cache->num_conn;
-  CONN_UNLOCK(data);
-  return num;
-}
-
-/* Returns number of connections currently held in the connections's bundle
-   Locks/unlocks the cache itself!
-*/
-size_t Curl_conncache_bundle_size(struct connectdata *conn)
-{
-  size_t num;
-  CONN_LOCK(conn->data);
-  num = conn->bundle->num_connections;
-  CONN_UNLOCK(conn->data);
+  CONNCACHE_UNLOCK(data);
   return num;
 }
 
@@ -212,13 +180,14 @@
 
    **NOTE**: When it returns, it holds the connection cache lock! */
 struct connectbundle *Curl_conncache_find_bundle(struct connectdata *conn,
-                                                 struct conncache *connc)
+                                                 struct conncache *connc,
+                                                 const char **hostp)
 {
   struct connectbundle *bundle = NULL;
-  CONN_LOCK(conn->data);
+  CONNCACHE_LOCK(conn->data);
   if(connc) {
-    char key[128];
-    hashkey(conn, key, sizeof(key));
+    char key[HASHKEY_SIZE];
+    hashkey(conn, key, sizeof(key), hostp);
     bundle = Curl_hash_pick(&connc->hash, key, strlen(key));
   }
 
@@ -262,30 +231,28 @@
                                  struct connectdata *conn)
 {
   CURLcode result = CURLE_OK;
-  struct connectbundle *bundle;
-  struct connectbundle *new_bundle = NULL;
+  struct connectbundle *bundle = NULL;
   struct Curl_easy *data = conn->data;
 
   /* *find_bundle() locks the connection cache */
-  bundle = Curl_conncache_find_bundle(conn, data->state.conn_cache);
+  bundle = Curl_conncache_find_bundle(conn, data->state.conn_cache, NULL);
   if(!bundle) {
     int rc;
-    char key[128];
+    char key[HASHKEY_SIZE];
 
-    result = bundle_create(data, &new_bundle);
+    result = bundle_create(&bundle);
     if(result) {
       goto unlock;
     }
 
-    hashkey(conn, key, sizeof(key));
-    rc = conncache_add_bundle(data->state.conn_cache, key, new_bundle);
+    hashkey(conn, key, sizeof(key), NULL);
+    rc = conncache_add_bundle(data->state.conn_cache, key, bundle);
 
     if(!rc) {
-      bundle_destroy(new_bundle);
+      bundle_destroy(bundle);
       result = CURLE_OUT_OF_MEMORY;
       goto unlock;
     }
-    bundle = new_bundle;
   }
 
   bundle_add_conn(bundle, conn);
@@ -297,15 +264,17 @@
                conn->connection_id, connc->num_conn));
 
   unlock:
-  CONN_UNLOCK(data);
+  CONNCACHE_UNLOCK(data);
 
   return result;
 }
 
 /*
- * Removes the connectdata object from the connection cache *and* clears the
- * ->data pointer association. Pass TRUE/FALSE in the 'lock' argument
- * depending on if the parent function already holds the lock or not.
+ * Removes the connectdata object from the connection cache, but does *not*
+ * clear the conn->data association. The transfer still owns this connection.
+ *
+ * Pass TRUE/FALSE in the 'lock' argument depending on if the parent function
+ * already holds the lock or not.
  */
 void Curl_conncache_remove_conn(struct Curl_easy *data,
                                 struct connectdata *conn, bool lock)
@@ -317,7 +286,7 @@
      due to a failed connection attempt, before being added to a bundle */
   if(bundle) {
     if(lock) {
-      CONN_LOCK(data);
+      CONNCACHE_LOCK(data);
     }
     bundle_remove_conn(bundle, conn);
     if(bundle->num_connections == 0)
@@ -328,9 +297,8 @@
       DEBUGF(infof(data, "The cache now contains %zu members\n",
                    connc->num_conn));
     }
-    conn->data = NULL; /* clear the association */
     if(lock) {
-      CONN_UNLOCK(data);
+      CONNCACHE_UNLOCK(data);
     }
   }
 }
@@ -359,7 +327,7 @@
   if(!connc)
     return FALSE;
 
-  CONN_LOCK(data);
+  CONNCACHE_LOCK(data);
   Curl_hash_start_iterate(&connc->hash, &iter);
 
   he = Curl_hash_next_element(&iter);
@@ -377,12 +345,12 @@
       curr = curr->next;
 
       if(1 == func(conn, param)) {
-        CONN_UNLOCK(data);
+        CONNCACHE_UNLOCK(data);
         return TRUE;
       }
     }
   }
-  CONN_UNLOCK(data);
+  CONNCACHE_UNLOCK(data);
   return FALSE;
 }
 
@@ -423,17 +391,15 @@
  *
  * Return TRUE if stored, FALSE if closed.
  */
-bool Curl_conncache_return_conn(struct connectdata *conn)
+bool Curl_conncache_return_conn(struct Curl_easy *data,
+                                struct connectdata *conn)
 {
-  struct Curl_easy *data = conn->data;
-
   /* data->multi->maxconnects can be negative, deal with it. */
   size_t maxconnects =
     (data->multi->maxconnects < 0) ? data->multi->num_easy * 4:
     data->multi->maxconnects;
   struct connectdata *conn_candidate = NULL;
 
-  conn->data = NULL; /* no owner anymore */
   conn->lastused = Curl_now(); /* it was used up until now */
   if(maxconnects > 0 &&
      Curl_conncache_size(data) > maxconnects) {
@@ -523,7 +489,7 @@
 
   now = Curl_now();
 
-  CONN_LOCK(data);
+  CONNCACHE_LOCK(data);
   Curl_hash_start_iterate(&connc->hash, &iter);
 
   he = Curl_hash_next_element(&iter);
@@ -536,7 +502,8 @@
     while(curr) {
       conn = curr->ptr;
 
-      if(!CONN_INUSE(conn) && !conn->data) {
+      if(!CONN_INUSE(conn) && !conn->data && !conn->bits.close &&
+         !conn->bits.connect_only) {
         /* Set higher score for the age passed since the connection was used */
         score = Curl_timediff(now, conn->lastused);
 
@@ -559,7 +526,7 @@
                  connc->num_conn));
     conn_candidate->data = data; /* associate! */
   }
-  CONN_UNLOCK(data);
+  CONNCACHE_UNLOCK(data);
 
   return conn_candidate;
 }
@@ -567,6 +534,11 @@
 void Curl_conncache_close_all_connections(struct conncache *connc)
 {
   struct connectdata *conn;
+  char buffer[READBUFFER_MIN + 1];
+  if(!connc->closure_handle)
+    return;
+  connc->closure_handle->state.buffer = buffer;
+  connc->closure_handle->set.buffer_size = READBUFFER_MIN;
 
   conn = conncache_find_first_connection(connc);
   while(conn) {
@@ -576,19 +548,21 @@
     sigpipe_ignore(conn->data, &pipe_st);
     /* This will remove the connection from the cache */
     connclose(conn, "kill all");
+    Curl_conncache_remove_conn(conn->data, conn, TRUE);
     (void)Curl_disconnect(connc->closure_handle, conn, FALSE);
     sigpipe_restore(&pipe_st);
 
     conn = conncache_find_first_connection(connc);
   }
 
+  connc->closure_handle->state.buffer = NULL;
   if(connc->closure_handle) {
     SIGPIPE_VARIABLE(pipe_st);
     sigpipe_ignore(connc->closure_handle, &pipe_st);
 
     Curl_hostcache_clean(connc->closure_handle,
                          connc->closure_handle->dns.hostcache);
-    Curl_close(connc->closure_handle);
+    Curl_close(&connc->closure_handle);
     sigpipe_restore(&pipe_st);
   }
 }
diff --git a/Utilities/cmcurl/lib/conncache.h b/Utilities/cmcurl/lib/conncache.h
index 35be9e0..3dda21c 100644
--- a/Utilities/cmcurl/lib/conncache.h
+++ b/Utilities/cmcurl/lib/conncache.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 2015 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 2015 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  * Copyright (C) 2012 - 2014, Linus Nielsen Feltzing, <linus@haxx.se>
  *
  * This software is licensed as described in the file COPYING, which
@@ -42,6 +42,27 @@
 #define BUNDLE_UNKNOWN     0  /* initial value */
 #define BUNDLE_MULTIPLEX   2
 
+#ifdef CURLDEBUG
+/* the debug versions of these macros make extra certain that the lock is
+   never doubly locked or unlocked */
+#define CONNCACHE_LOCK(x) if((x)->share) {                              \
+    Curl_share_lock((x), CURL_LOCK_DATA_CONNECT, CURL_LOCK_ACCESS_SINGLE); \
+    DEBUGASSERT(!(x)->state.conncache_lock);                            \
+    (x)->state.conncache_lock = TRUE;                                   \
+  }
+
+#define CONNCACHE_UNLOCK(x) if((x)->share) {                            \
+    DEBUGASSERT((x)->state.conncache_lock);                             \
+    (x)->state.conncache_lock = FALSE;                                  \
+    Curl_share_unlock((x), CURL_LOCK_DATA_CONNECT);                     \
+  }
+#else
+#define CONNCACHE_LOCK(x) if((x)->share)                                \
+    Curl_share_lock((x), CURL_LOCK_DATA_CONNECT, CURL_LOCK_ACCESS_SINGLE)
+#define CONNCACHE_UNLOCK(x) if((x)->share)              \
+    Curl_share_unlock((x), CURL_LOCK_DATA_CONNECT)
+#endif
+
 struct connectbundle {
   int multiuse;                 /* supports multi-use */
   size_t num_connections;       /* Number of connections in the bundle */
@@ -54,13 +75,13 @@
 
 /* return the correct bundle, to a host or a proxy */
 struct connectbundle *Curl_conncache_find_bundle(struct connectdata *conn,
-                                                 struct conncache *connc);
-void Curl_conncache_unlock(struct Curl_easy *data);
+                                                 struct conncache *connc,
+                                                 const char **hostp);
 /* returns number of connections currently held in the connection cache */
 size_t Curl_conncache_size(struct Curl_easy *data);
-size_t Curl_conncache_bundle_size(struct connectdata *conn);
 
-bool Curl_conncache_return_conn(struct connectdata *conn);
+bool Curl_conncache_return_conn(struct Curl_easy *data,
+                                struct connectdata *conn);
 CURLcode Curl_conncache_add_conn(struct conncache *connc,
                                  struct connectdata *conn) WARN_UNUSED_RESULT;
 void Curl_conncache_remove_conn(struct Curl_easy *data,
diff --git a/Utilities/cmcurl/lib/connect.c b/Utilities/cmcurl/lib/connect.c
index 002535b..29293f0 100644
--- a/Utilities/cmcurl/lib/connect.c
+++ b/Utilities/cmcurl/lib/connect.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -75,6 +75,8 @@
 #include "conncache.h"
 #include "multihandle.h"
 #include "system_win32.h"
+#include "quic.h"
+#include "socks.h"
 
 /* The last 3 #include files should be in this order */
 #include "curl_printf.h"
@@ -164,12 +166,13 @@
 
 static CURLcode
 singleipconnect(struct connectdata *conn,
-                const Curl_addrinfo *ai, /* start connecting to this */
-                curl_socket_t *sock);
+                const struct Curl_addrinfo *ai, /* start connecting to this */
+                int tempindex);          /* 0 or 1 among the temp ones */
 
 /*
  * Curl_timeleft() returns the amount of milliseconds left allowed for the
- * transfer/connection. If the value is negative, the timeout time has already
+ * transfer/connection. If the value is 0, there's no timeout (ie there's
+ * infinite time left). If the value is negative, the timeout time has already
  * elapsed.
  *
  * The start time is stored in progress.t_startsingle - as set with
@@ -368,6 +371,11 @@
         infof(data, "Name '%s' family %i resolved to '%s' family %i\n",
               dev, af, myhost, h->addr->ai_family);
         Curl_resolv_unlock(data, h);
+        if(af != h->addr->ai_family) {
+          /* bad IP version combo, signal the caller to try another address
+             family if available */
+          return CURLE_UNSUPPORTED_PROTOCOL;
+        }
         done = 1;
       }
       else {
@@ -548,13 +556,27 @@
   return rc;
 }
 
-/* Used within the multi interface. Try next IP address, return TRUE if no
+/* update tempaddr[tempindex] (to the next entry), makes sure to stick
+   to the correct family */
+static struct Curl_addrinfo *ainext(struct connectdata *conn,
+                                    int tempindex,
+                                    bool next) /* use next entry? */
+{
+  struct Curl_addrinfo *ai = conn->tempaddr[tempindex];
+  if(ai && next)
+    ai = ai->ai_next;
+  while(ai && (ai->ai_family != conn->tempfamily[tempindex]))
+    ai = ai->ai_next;
+  conn->tempaddr[tempindex] = ai;
+  return ai;
+}
+
+/* Used within the multi interface. Try next IP address, returns error if no
    more address exists or error */
 static CURLcode trynextip(struct connectdata *conn,
                           int sockindex,
                           int tempindex)
 {
-  const int other = tempindex ^ 1;
   CURLcode result = CURLE_COULDNT_CONNECT;
 
   /* First clean up after the failed socket.
@@ -565,38 +587,15 @@
   conn->tempsock[tempindex] = CURL_SOCKET_BAD;
 
   if(sockindex == FIRSTSOCKET) {
-    Curl_addrinfo *ai = NULL;
-    int family = AF_UNSPEC;
-
-    if(conn->tempaddr[tempindex]) {
-      /* find next address in the same protocol family */
-      family = conn->tempaddr[tempindex]->ai_family;
-      ai = conn->tempaddr[tempindex]->ai_next;
-    }
-#ifdef ENABLE_IPV6
-    else if(conn->tempaddr[0]) {
-      /* happy eyeballs - try the other protocol family */
-      int firstfamily = conn->tempaddr[0]->ai_family;
-      family = (firstfamily == AF_INET) ? AF_INET6 : AF_INET;
-      ai = conn->tempaddr[0]->ai_next;
-    }
-#endif
+    struct Curl_addrinfo *ai = conn->tempaddr[tempindex];
 
     while(ai) {
-      if(conn->tempaddr[other]) {
-        /* we can safely skip addresses of the other protocol family */
-        while(ai && ai->ai_family != family)
-          ai = ai->ai_next;
-      }
-
       if(ai) {
-        result = singleipconnect(conn, ai, &conn->tempsock[tempindex]);
+        result = singleipconnect(conn, ai, tempindex);
         if(result == CURLE_COULDNT_CONNECT) {
-          ai = ai->ai_next;
+          ai = ainext(conn, tempindex, TRUE);
           continue;
         }
-
-        conn->tempaddr[tempindex] = ai;
       }
       break;
     }
@@ -620,13 +619,10 @@
   conn->data->info.conn_local_port = conn->local_port;
 }
 
-UNITTEST bool getaddressinfo(struct sockaddr *sa, char *addr,
-                             long *port);
-
 /* retrieves ip address and port from a sockaddr structure.
    note it calls Curl_inet_ntop which sets errno on fail, not SOCKERRNO. */
-UNITTEST bool getaddressinfo(struct sockaddr *sa, char *addr,
-                             long *port)
+bool Curl_addr2string(struct sockaddr *sa, curl_socklen_t salen,
+                      char *addr, long *port)
 {
   struct sockaddr_in *si = NULL;
 #ifdef ENABLE_IPV6
@@ -634,6 +630,8 @@
 #endif
 #if defined(HAVE_SYS_UN_H) && defined(AF_UNIX)
   struct sockaddr_un *su = NULL;
+#else
+  (void)salen;
 #endif
 
   switch(sa->sa_family) {
@@ -659,8 +657,12 @@
 #endif
 #if defined(HAVE_SYS_UN_H) && defined(AF_UNIX)
     case AF_UNIX:
-      su = (struct sockaddr_un*)sa;
-      msnprintf(addr, MAX_IPADR_LEN, "%s", su->sun_path);
+      if(salen > (curl_socklen_t)sizeof(sa_family_t)) {
+        su = (struct sockaddr_un*)sa;
+        msnprintf(addr, MAX_IPADR_LEN, "%s", su->sun_path);
+      }
+      else
+        addr[0] = 0; /* socket with no name */
       *port = 0;
       return TRUE;
 #endif
@@ -678,62 +680,136 @@
    connection */
 void Curl_updateconninfo(struct connectdata *conn, curl_socket_t sockfd)
 {
-  if(conn->socktype == SOCK_DGRAM)
-    /* there's no connection! */
-    return;
-
+  if(conn->transport == TRNSPRT_TCP) {
 #if defined(HAVE_GETPEERNAME) || defined(HAVE_GETSOCKNAME)
-  if(!conn->bits.reuse && !conn->bits.tcp_fastopen) {
-    struct Curl_easy *data = conn->data;
-    char buffer[STRERROR_LEN];
-    struct Curl_sockaddr_storage ssrem;
-    struct Curl_sockaddr_storage ssloc;
-    curl_socklen_t len;
+    if(!conn->bits.reuse && !conn->bits.tcp_fastopen) {
+      struct Curl_easy *data = conn->data;
+      char buffer[STRERROR_LEN];
+      struct Curl_sockaddr_storage ssrem;
+      struct Curl_sockaddr_storage ssloc;
+      curl_socklen_t plen;
+      curl_socklen_t slen;
 #ifdef HAVE_GETPEERNAME
-    len = sizeof(struct Curl_sockaddr_storage);
-    if(getpeername(sockfd, (struct sockaddr*) &ssrem, &len)) {
-      int error = SOCKERRNO;
-      failf(data, "getpeername() failed with errno %d: %s",
-            error, Curl_strerror(error, buffer, sizeof(buffer)));
-      return;
-    }
+      plen = sizeof(struct Curl_sockaddr_storage);
+      if(getpeername(sockfd, (struct sockaddr*) &ssrem, &plen)) {
+        int error = SOCKERRNO;
+        failf(data, "getpeername() failed with errno %d: %s",
+              error, Curl_strerror(error, buffer, sizeof(buffer)));
+        return;
+      }
 #endif
 #ifdef HAVE_GETSOCKNAME
-    len = sizeof(struct Curl_sockaddr_storage);
-    memset(&ssloc, 0, sizeof(ssloc));
-    if(getsockname(sockfd, (struct sockaddr*) &ssloc, &len)) {
-      int error = SOCKERRNO;
-      failf(data, "getsockname() failed with errno %d: %s",
-            error, Curl_strerror(error, buffer, sizeof(buffer)));
-      return;
-    }
+      slen = sizeof(struct Curl_sockaddr_storage);
+      memset(&ssloc, 0, sizeof(ssloc));
+      if(getsockname(sockfd, (struct sockaddr*) &ssloc, &slen)) {
+        int error = SOCKERRNO;
+        failf(data, "getsockname() failed with errno %d: %s",
+              error, Curl_strerror(error, buffer, sizeof(buffer)));
+        return;
+      }
 #endif
 #ifdef HAVE_GETPEERNAME
-    if(!getaddressinfo((struct sockaddr*)&ssrem,
-                       conn->primary_ip, &conn->primary_port)) {
-      failf(data, "ssrem inet_ntop() failed with errno %d: %s",
-            errno, Curl_strerror(errno, buffer, sizeof(buffer)));
-      return;
-    }
-    memcpy(conn->ip_addr_str, conn->primary_ip, MAX_IPADR_LEN);
+      if(!Curl_addr2string((struct sockaddr*)&ssrem, plen,
+                           conn->primary_ip, &conn->primary_port)) {
+        failf(data, "ssrem inet_ntop() failed with errno %d: %s",
+              errno, Curl_strerror(errno, buffer, sizeof(buffer)));
+        return;
+      }
+      memcpy(conn->ip_addr_str, conn->primary_ip, MAX_IPADR_LEN);
 #endif
 #ifdef HAVE_GETSOCKNAME
-    if(!getaddressinfo((struct sockaddr*)&ssloc,
-                       conn->local_ip, &conn->local_port)) {
-      failf(data, "ssloc inet_ntop() failed with errno %d: %s",
-            errno, Curl_strerror(errno, buffer, sizeof(buffer)));
-      return;
-    }
+      if(!Curl_addr2string((struct sockaddr*)&ssloc, slen,
+                           conn->local_ip, &conn->local_port)) {
+        failf(data, "ssloc inet_ntop() failed with errno %d: %s",
+              errno, Curl_strerror(errno, buffer, sizeof(buffer)));
+        return;
+      }
 #endif
-  }
+    }
 #else /* !HAVE_GETSOCKNAME && !HAVE_GETPEERNAME */
-  (void)sockfd; /* unused */
+    (void)sockfd; /* unused */
 #endif
+  } /* end of TCP-only section */
 
   /* persist connection info in session handle */
   Curl_persistconninfo(conn);
 }
 
+/* After a TCP connection to the proxy has been verified, this function does
+   the next magic steps. If 'done' isn't set TRUE, it is not done yet and
+   must be called again.
+
+   Note: this function's sub-functions call failf()
+
+*/
+static CURLcode connect_SOCKS(struct connectdata *conn, int sockindex,
+                              bool *done)
+{
+  CURLcode result = CURLE_OK;
+
+#ifndef CURL_DISABLE_PROXY
+  if(conn->bits.socksproxy) {
+    /* for the secondary socket (FTP), use the "connect to host"
+     * but ignore the "connect to port" (use the secondary port)
+     */
+    const char * const host =
+      conn->bits.httpproxy ?
+      conn->http_proxy.host.name :
+      conn->bits.conn_to_host ?
+      conn->conn_to_host.name :
+      sockindex == SECONDARYSOCKET ?
+      conn->secondaryhostname : conn->host.name;
+    const int port =
+      conn->bits.httpproxy ? (int)conn->http_proxy.port :
+      sockindex == SECONDARYSOCKET ? conn->secondary_port :
+      conn->bits.conn_to_port ? conn->conn_to_port :
+      conn->remote_port;
+    switch(conn->socks_proxy.proxytype) {
+    case CURLPROXY_SOCKS5:
+    case CURLPROXY_SOCKS5_HOSTNAME:
+      result = Curl_SOCKS5(conn->socks_proxy.user, conn->socks_proxy.passwd,
+                           host, port, sockindex, conn, done);
+      break;
+
+    case CURLPROXY_SOCKS4:
+    case CURLPROXY_SOCKS4A:
+      result = Curl_SOCKS4(conn->socks_proxy.user, host, port, sockindex,
+                           conn, done);
+      break;
+
+    default:
+      failf(conn->data, "unknown proxytype option given");
+      result = CURLE_COULDNT_CONNECT;
+    } /* switch proxytype */
+  }
+  else
+#else
+    (void)conn;
+    (void)sockindex;
+#endif /* CURL_DISABLE_PROXY */
+    *done = TRUE; /* no SOCKS proxy, so consider us connected */
+
+  return result;
+}
+
+/*
+ * post_SOCKS() is called after a successful connect to the peer, which
+ * *could* be a SOCKS proxy
+ */
+static void post_SOCKS(struct connectdata *conn,
+                       int sockindex,
+                       bool *connected)
+{
+  conn->bits.tcpconnect[sockindex] = TRUE;
+
+  *connected = TRUE;
+  if(sockindex == FIRSTSOCKET)
+    Curl_pgrsTime(conn->data, TIMER_CONNECT); /* connect done */
+  Curl_updateconninfo(conn, conn->sock[sockindex]);
+  Curl_verboseconnect(conn);
+  conn->data->info.numconnects++; /* to track the number of connections made */
+}
+
 /*
  * Curl_is_connected() checks if the socket has connected.
  */
@@ -747,8 +823,8 @@
   timediff_t allow;
   int error = 0;
   struct curltime now;
-  int rc;
-  int i;
+  int rc = 0;
+  unsigned int i;
 
   DEBUGASSERT(sockindex >= FIRSTSOCKET && sockindex <= SECONDARYSOCKET);
 
@@ -771,33 +847,62 @@
     return CURLE_OPERATION_TIMEDOUT;
   }
 
+  if(SOCKS_STATE(conn->cnnct.state)) {
+    /* still doing SOCKS */
+    result = connect_SOCKS(conn, sockindex, connected);
+    if(!result && *connected)
+      post_SOCKS(conn, sockindex, connected);
+    return result;
+  }
+
   for(i = 0; i<2; i++) {
     const int other = i ^ 1;
     if(conn->tempsock[i] == CURL_SOCKET_BAD)
       continue;
-
+    error = 0;
+#ifdef ENABLE_QUIC
+    if(conn->transport == TRNSPRT_QUIC) {
+      result = Curl_quic_is_connected(conn, i, connected);
+      if(!result && *connected) {
+        /* use this socket from now on */
+        conn->sock[sockindex] = conn->tempsock[i];
+        conn->ip_addr = conn->tempaddr[i];
+        conn->tempsock[i] = CURL_SOCKET_BAD;
+        post_SOCKS(conn, sockindex, connected);
+        connkeep(conn, "HTTP/3 default");
+        return CURLE_OK;
+      }
+      if(result)
+        error = SOCKERRNO;
+    }
+    else
+#endif
+    {
 #ifdef mpeix
-    /* Call this function once now, and ignore the results. We do this to
-       "clear" the error state on the socket so that we can later read it
-       reliably. This is reported necessary on the MPE/iX operating system. */
-    (void)verifyconnect(conn->tempsock[i], NULL);
+      /* Call this function once now, and ignore the results. We do this to
+         "clear" the error state on the socket so that we can later read it
+         reliably. This is reported necessary on the MPE/iX operating
+         system. */
+      (void)verifyconnect(conn->tempsock[i], NULL);
 #endif
 
-    /* check socket for connect */
-    rc = SOCKET_WRITABLE(conn->tempsock[i], 0);
+      /* check socket for connect */
+      rc = SOCKET_WRITABLE(conn->tempsock[i], 0);
+    }
 
     if(rc == 0) { /* no connection yet */
-      error = 0;
-      if(Curl_timediff(now, conn->connecttime) >= conn->timeoutms_per_addr) {
-        infof(data, "After %ldms connect time, move on!\n",
-              conn->timeoutms_per_addr);
+      if(Curl_timediff(now, conn->connecttime) >=
+         conn->timeoutms_per_addr[i]) {
+        infof(data, "After %" CURL_FORMAT_TIMEDIFF_T
+              "ms connect time, move on!\n", conn->timeoutms_per_addr[i]);
         error = ETIMEDOUT;
       }
 
       /* should we try another protocol family? */
-      if(i == 0 && conn->tempaddr[1] == NULL &&
+      if(i == 0 && !conn->bits.parallel_connect &&
          (Curl_timediff(now, conn->connecttime) >=
           data->set.happy_eyeballs_timeout)) {
+        conn->bits.parallel_connect = TRUE; /* starting now */
         trynextip(conn, sockindex, 1);
       }
     }
@@ -819,18 +924,13 @@
           conn->tempsock[other] = CURL_SOCKET_BAD;
         }
 
-        /* see if we need to do any proxy magic first once we connected */
-        result = Curl_connected_proxy(conn, sockindex);
-        if(result)
+        /* see if we need to kick off any SOCKS proxy magic once we
+           connected */
+        result = connect_SOCKS(conn, sockindex, connected);
+        if(result || !*connected)
           return result;
 
-        conn->bits.tcpconnect[sockindex] = TRUE;
-
-        *connected = TRUE;
-        if(sockindex == FIRSTSOCKET)
-          Curl_pgrsTime(data, TIMER_CONNECT); /* connect done */
-        Curl_updateconninfo(conn, conn->sock[sockindex]);
-        Curl_verboseconnect(conn);
+        post_SOCKS(conn, sockindex, connected);
 
         return CURLE_OK;
       }
@@ -848,51 +948,70 @@
       SET_SOCKERRNO(error);
       if(conn->tempaddr[i]) {
         CURLcode status;
+#ifndef CURL_DISABLE_VERBOSE_STRINGS
         char ipaddress[MAX_IPADR_LEN];
         char buffer[STRERROR_LEN];
-        Curl_printable_address(conn->tempaddr[i], ipaddress, MAX_IPADR_LEN);
+        Curl_printable_address(conn->tempaddr[i], ipaddress,
+                               sizeof(ipaddress));
         infof(data, "connect to %s port %ld failed: %s\n",
               ipaddress, conn->port,
               Curl_strerror(error, buffer, sizeof(buffer)));
+#endif
 
-        conn->timeoutms_per_addr = conn->tempaddr[i]->ai_next == NULL ?
-                                   allow : allow / 2;
-
+        conn->timeoutms_per_addr[i] = conn->tempaddr[i]->ai_next == NULL ?
+          allow : allow / 2;
+        ainext(conn, i, TRUE);
         status = trynextip(conn, sockindex, i);
-        if(status != CURLE_COULDNT_CONNECT
-            || conn->tempsock[other] == CURL_SOCKET_BAD)
+        if((status != CURLE_COULDNT_CONNECT) ||
+           conn->tempsock[other] == CURL_SOCKET_BAD)
           /* the last attempt failed and no other sockets remain open */
           result = status;
       }
     }
   }
 
-  if(result) {
+  if(result &&
+     (conn->tempsock[0] == CURL_SOCKET_BAD) &&
+     (conn->tempsock[1] == CURL_SOCKET_BAD)) {
     /* no more addresses to try */
     const char *hostname;
     char buffer[STRERROR_LEN];
 
-    /* if the first address family runs out of addresses to try before
-       the happy eyeball timeout, go ahead and try the next family now */
-    if(conn->tempaddr[1] == NULL) {
-      result = trynextip(conn, sockindex, 1);
-      if(!result)
-        return result;
-    }
+    /* if the first address family runs out of addresses to try before the
+       happy eyeball timeout, go ahead and try the next family now */
+    result = trynextip(conn, sockindex, 1);
+    if(!result)
+      return result;
 
+#ifndef CURL_DISABLE_PROXY
     if(conn->bits.socksproxy)
       hostname = conn->socks_proxy.host.name;
     else if(conn->bits.httpproxy)
       hostname = conn->http_proxy.host.name;
-    else if(conn->bits.conn_to_host)
-      hostname = conn->conn_to_host.name;
+    else
+#endif
+      if(conn->bits.conn_to_host)
+        hostname = conn->conn_to_host.name;
     else
       hostname = conn->host.name;
 
     failf(data, "Failed to connect to %s port %ld: %s",
           hostname, conn->port,
           Curl_strerror(error, buffer, sizeof(buffer)));
+
+    Curl_quic_disconnect(conn, 0);
+    Curl_quic_disconnect(conn, 1);
+
+#ifdef WSAETIMEDOUT
+    if(WSAETIMEDOUT == data->state.os_errno)
+      result = CURLE_OPERATION_TIMEDOUT;
+#elif defined(ETIMEDOUT)
+    if(ETIMEDOUT == data->state.os_errno)
+      result = CURLE_OPERATION_TIMEDOUT;
+#endif
   }
+  else
+    result = CURLE_OK; /* still trying */
 
   return result;
 }
@@ -900,14 +1019,12 @@
 static void tcpnodelay(struct connectdata *conn, curl_socket_t sockfd)
 {
 #if defined(TCP_NODELAY)
-#if !defined(CURL_DISABLE_VERBOSE_STRINGS)
-  struct Curl_easy *data = conn->data;
-#endif
   curl_socklen_t onoff = (curl_socklen_t) 1;
   int level = IPPROTO_TCP;
+#if !defined(CURL_DISABLE_VERBOSE_STRINGS)
+  struct Curl_easy *data = conn->data;
   char buffer[STRERROR_LEN];
-
-#if defined(CURL_DISABLE_VERBOSE_STRINGS)
+#else
   (void) conn;
 #endif
 
@@ -915,8 +1032,6 @@
                 sizeof(onoff)) < 0)
     infof(data, "Could not set TCP_NODELAY: %s\n",
           Curl_strerror(SOCKERRNO, buffer, sizeof(buffer)));
-  else
-    infof(data, "TCP_NODELAY set\n");
 #else
   (void)conn;
   (void)sockfd;
@@ -998,8 +1113,8 @@
  * having connected.
  */
 static CURLcode singleipconnect(struct connectdata *conn,
-                                const Curl_addrinfo *ai,
-                                curl_socket_t *sockp)
+                                const struct Curl_addrinfo *ai,
+                                int tempindex)
 {
   struct Curl_sockaddr_ex addr;
   int rc = -1;
@@ -1015,19 +1130,16 @@
   int optval = 1;
 #endif
   char buffer[STRERROR_LEN];
-
+  curl_socket_t *sockp = &conn->tempsock[tempindex];
   *sockp = CURL_SOCKET_BAD;
 
   result = Curl_socket(conn, ai, &addr, &sockfd);
   if(result)
-    /* Failed to create the socket, but still return OK since we signal the
-       lack of socket as well. This allows the parent function to keep looping
-       over alternative addresses/socket families etc. */
-    return CURLE_OK;
+    return result;
 
   /* store remote address and port used in this connection attempt */
-  if(!getaddressinfo((struct sockaddr*)&addr.sa_addr,
-                     ipaddress, &port)) {
+  if(!Curl_addr2string((struct sockaddr*)&addr.sa_addr, addr.addrlen,
+                       ipaddress, &port)) {
     /* malformed address or bug in inet_ntop, try next address */
     failf(data, "sa_addr inet_ntop() failed with errno %d: %s",
           errno, Curl_strerror(errno, buffer, sizeof(buffer)));
@@ -1091,11 +1203,13 @@
   (void)curlx_nonblock(sockfd, TRUE);
 
   conn->connecttime = Curl_now();
-  if(conn->num_addr > 1)
-    Curl_expire(data, conn->timeoutms_per_addr, EXPIRE_DNS_PER_NAME);
+  if(conn->num_addr > 1) {
+    Curl_expire(data, conn->timeoutms_per_addr[0], EXPIRE_DNS_PER_NAME);
+    Curl_expire(data, conn->timeoutms_per_addr[1], EXPIRE_DNS_PER_NAME2);
+  }
 
-  /* Connect TCP sockets, bind UDP */
-  if(!isconnected && (conn->socktype == SOCK_STREAM)) {
+  /* Connect TCP and QUIC sockets */
+  if(!isconnected && (conn->transport != TRNSPRT_UDP)) {
     if(conn->bits.tcp_fastopen) {
 #if defined(CONNECT_DATA_IDEMPOTENT) /* Darwin */
 #  if defined(HAVE_BUILTIN_AVAILABLE)
@@ -1124,8 +1238,6 @@
       if(setsockopt(sockfd, IPPROTO_TCP, TCP_FASTOPEN_CONNECT,
                     (void *)&optval, sizeof(optval)) < 0)
         infof(data, "Failed to enable TCP Fast Open on fd %d\n", sockfd);
-      else
-        infof(data, "TCP_FASTOPEN_CONNECT set\n");
 
       rc = connect(sockfd, &addr.sa_addr, addr.addrlen);
 #elif defined(MSG_FASTOPEN) /* old Linux */
@@ -1141,6 +1253,16 @@
 
     if(-1 == rc)
       error = SOCKERRNO;
+#ifdef ENABLE_QUIC
+    else if(conn->transport == TRNSPRT_QUIC) {
+      /* pass in 'sockfd' separately since it hasn't been put into the
+         tempsock array at this point */
+      result = Curl_quic_connect(conn, sockfd, tempindex,
+                                 &addr.sa_addr, addr.addrlen);
+      if(result)
+        error = SOCKERRNO;
+    }
+#endif
   }
   else {
     *sockp = sockfd;
@@ -1193,7 +1315,7 @@
   struct Curl_easy *data = conn->data;
   struct curltime before = Curl_now();
   CURLcode result = CURLE_COULDNT_CONNECT;
-
+  int i;
   timediff_t timeout_ms = Curl_timeleft(data, &before, TRUE);
 
   if(timeout_ms < 0) {
@@ -1203,30 +1325,37 @@
   }
 
   conn->num_addr = Curl_num_addresses(remotehost->addr);
-  conn->tempaddr[0] = remotehost->addr;
-  conn->tempaddr[1] = NULL;
-  conn->tempsock[0] = CURL_SOCKET_BAD;
-  conn->tempsock[1] = CURL_SOCKET_BAD;
+  conn->tempaddr[0] = conn->tempaddr[1] = remotehost->addr;
+  conn->tempsock[0] = conn->tempsock[1] = CURL_SOCKET_BAD;
 
   /* Max time for the next connection attempt */
-  conn->timeoutms_per_addr =
+  conn->timeoutms_per_addr[0] =
     conn->tempaddr[0]->ai_next == NULL ? timeout_ms : timeout_ms / 2;
+  conn->timeoutms_per_addr[1] =
+    conn->tempaddr[1]->ai_next == NULL ? timeout_ms : timeout_ms / 2;
 
-  /* start connecting to first IP */
-  while(conn->tempaddr[0]) {
-    result = singleipconnect(conn, conn->tempaddr[0], &(conn->tempsock[0]));
-    if(!result)
-      break;
-    conn->tempaddr[0] = conn->tempaddr[0]->ai_next;
+  conn->tempfamily[0] = conn->tempaddr[0]?
+    conn->tempaddr[0]->ai_family:0;
+  conn->tempfamily[1] = conn->tempfamily[0] == AF_INET6 ?
+    AF_INET : AF_INET6;
+  ainext(conn, 1, FALSE); /* assigns conn->tempaddr[1] accordingly */
+
+  DEBUGF(infof(data, "family0 == %s, family1 == %s\n",
+               conn->tempfamily[0] == AF_INET ? "v4" : "v6",
+               conn->tempfamily[1] == AF_INET ? "v4" : "v6"));
+
+  /* get through the list in family order in case of quick failures */
+  for(i = 0; (i < 2) && result; i++) {
+    while(conn->tempaddr[i]) {
+      result = singleipconnect(conn, conn->tempaddr[i], i);
+      if(!result)
+        break;
+      ainext(conn, i, TRUE);
+    }
   }
-
-  if(conn->tempsock[0] == CURL_SOCKET_BAD) {
-    if(!result)
-      result = CURLE_COULDNT_CONNECT;
+  if(result)
     return result;
-  }
 
-  data->info.numconnects++; /* to track the number of connections made */
   Curl_expire(conn->data, data->set.happy_eyeballs_timeout,
               EXPIRE_HAPPY_EYEBALLS);
 
@@ -1326,12 +1455,11 @@
                       curl_socket_t sock)
 {
   if(conn && conn->fclosesocket) {
-    if((sock == conn->sock[SECONDARYSOCKET]) &&
-       conn->sock_accepted[SECONDARYSOCKET])
+    if((sock == conn->sock[SECONDARYSOCKET]) && conn->bits.sock_accepted)
       /* if this socket matches the second socket, and that was created with
          accept, then we MUST NOT call the callback but clear the accepted
          status */
-      conn->sock_accepted[SECONDARYSOCKET] = FALSE;
+      conn->bits.sock_accepted = FALSE;
     else {
       int rc;
       Curl_multi_closed(conn->data, sock);
@@ -1361,7 +1489,7 @@
  *
  */
 CURLcode Curl_socket(struct connectdata *conn,
-                     const Curl_addrinfo *ai,
+                     const struct Curl_addrinfo *ai,
                      struct Curl_sockaddr_ex *addr,
                      curl_socket_t *sockfd)
 {
@@ -1381,8 +1509,9 @@
    */
 
   addr->family = ai->ai_family;
-  addr->socktype = conn->socktype;
-  addr->protocol = conn->socktype == SOCK_DGRAM?IPPROTO_UDP:ai->ai_protocol;
+  addr->socktype = (conn->transport == TRNSPRT_TCP) ? SOCK_STREAM : SOCK_DGRAM;
+  addr->protocol = conn->transport != TRNSPRT_TCP ? IPPROTO_UDP :
+    ai->ai_protocol;
   addr->addrlen = ai->ai_addrlen;
 
   if(addr->addrlen > sizeof(struct Curl_sockaddr_storage))
@@ -1413,6 +1542,11 @@
     /* no socket, no connection */
     return CURLE_COULDNT_CONNECT;
 
+  if(conn->transport == TRNSPRT_QUIC) {
+    /* QUIC sockets need to be nonblocking */
+    (void)curlx_nonblock(*sockfd, TRUE);
+  }
+
 #if defined(ENABLE_IPV6) && defined(HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID)
   if(conn->scope_id && (addr->family == AF_INET6)) {
     struct sockaddr_in6 * const sa6 = (void *)&addr->sa_addr;
@@ -1437,6 +1571,7 @@
   /* close if a connection, or a stream that isn't multiplexed */
   bool closeit = (ctrl == CONNCTRL_CONNECTION) ||
     ((ctrl == CONNCTRL_STREAM) && !(conn->handler->flags & PROTOPT_STREAM));
+  DEBUGASSERT(conn);
   if((ctrl == CONNCTRL_STREAM) &&
      (conn->handler->flags & PROTOPT_STREAM))
     DEBUGF(infof(conn->data, "Kill stream: %s\n", reason));
@@ -1452,6 +1587,7 @@
 bool Curl_conn_data_pending(struct connectdata *conn, int sockindex)
 {
   int readable;
+  DEBUGASSERT(conn);
 
   if(Curl_ssl_data_pending(conn, sockindex) ||
      Curl_recv_has_postponed_data(conn, sockindex))
diff --git a/Utilities/cmcurl/lib/connect.h b/Utilities/cmcurl/lib/connect.h
index 6a5c755..6fd9ea8 100644
--- a/Utilities/cmcurl/lib/connect.h
+++ b/Utilities/cmcurl/lib/connect.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -51,6 +51,9 @@
 curl_socket_t Curl_getconnectinfo(struct Curl_easy *data,
                                   struct connectdata **connp);
 
+bool Curl_addr2string(struct sockaddr *sa, curl_socklen_t salen,
+                      char *addr, long *port);
+
 /*
  * Check if a connection seems to be alive.
  */
@@ -102,7 +105,7 @@
  *
  */
 CURLcode Curl_socket(struct connectdata *conn,
-                     const Curl_addrinfo *ai,
+                     const struct Curl_addrinfo *ai,
                      struct Curl_sockaddr_ex *addr,
                      curl_socket_t *sockfd);
 
diff --git a/Utilities/cmcurl/lib/content_encoding.c b/Utilities/cmcurl/lib/content_encoding.c
index 6d47537..e2e68a1 100644
--- a/Utilities/cmcurl/lib/content_encoding.c
+++ b/Utilities/cmcurl/lib/content_encoding.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -81,11 +81,11 @@
 } zlibInitState;
 
 /* Writer parameters. */
-typedef struct {
+struct zlib_params {
   zlibInitState zlib_init;   /* zlib init state */
   uInt trailerlen;           /* Remaining trailer byte count. */
   z_stream z;                /* State structure for zlib. */
-}  zlib_params;
+};
 
 
 static voidpf
@@ -133,7 +133,8 @@
   return result;
 }
 
-static CURLcode process_trailer(struct connectdata *conn, zlib_params *zp)
+static CURLcode process_trailer(struct connectdata *conn,
+                                struct zlib_params *zp)
 {
   z_stream *z = &zp->z;
   CURLcode result = CURLE_OK;
@@ -157,9 +158,10 @@
 }
 
 static CURLcode inflate_stream(struct connectdata *conn,
-                               contenc_writer *writer, zlibInitState started)
+                               struct contenc_writer *writer,
+                               zlibInitState started)
 {
-  zlib_params *zp = (zlib_params *) &writer->params;
+  struct zlib_params *zp = (struct zlib_params *) &writer->params;
   z_stream *z = &zp->z;         /* zlib state structure */
   uInt nread = z->avail_in;
   Bytef *orig_in = z->next_in;
@@ -259,9 +261,9 @@
 
 /* Deflate handler. */
 static CURLcode deflate_init_writer(struct connectdata *conn,
-                                    contenc_writer *writer)
+                                    struct contenc_writer *writer)
 {
-  zlib_params *zp = (zlib_params *) &writer->params;
+  struct zlib_params *zp = (struct zlib_params *) &writer->params;
   z_stream *z = &zp->z;     /* zlib state structure */
 
   if(!writer->downstream)
@@ -278,10 +280,10 @@
 }
 
 static CURLcode deflate_unencode_write(struct connectdata *conn,
-                                       contenc_writer *writer,
+                                       struct contenc_writer *writer,
                                        const char *buf, size_t nbytes)
 {
-  zlib_params *zp = (zlib_params *) &writer->params;
+  struct zlib_params *zp = (struct zlib_params *) &writer->params;
   z_stream *z = &zp->z;     /* zlib state structure */
 
   /* Set the compressed input when this function is called */
@@ -296,29 +298,29 @@
 }
 
 static void deflate_close_writer(struct connectdata *conn,
-                                 contenc_writer *writer)
+                                 struct contenc_writer *writer)
 {
-  zlib_params *zp = (zlib_params *) &writer->params;
+  struct zlib_params *zp = (struct zlib_params *) &writer->params;
   z_stream *z = &zp->z;     /* zlib state structure */
 
   exit_zlib(conn, z, &zp->zlib_init, CURLE_OK);
 }
 
-static const content_encoding deflate_encoding = {
+static const struct content_encoding deflate_encoding = {
   "deflate",
   NULL,
   deflate_init_writer,
   deflate_unencode_write,
   deflate_close_writer,
-  sizeof(zlib_params)
+  sizeof(struct zlib_params)
 };
 
 
 /* Gzip handler. */
 static CURLcode gzip_init_writer(struct connectdata *conn,
-                                 contenc_writer *writer)
+                                 struct contenc_writer *writer)
 {
-  zlib_params *zp = (zlib_params *) &writer->params;
+  struct zlib_params *zp = (struct zlib_params *) &writer->params;
   z_stream *z = &zp->z;     /* zlib state structure */
 
   if(!writer->downstream)
@@ -432,10 +434,10 @@
 #endif
 
 static CURLcode gzip_unencode_write(struct connectdata *conn,
-                                    contenc_writer *writer,
+                                    struct contenc_writer *writer,
                                     const char *buf, size_t nbytes)
 {
-  zlib_params *zp = (zlib_params *) &writer->params;
+  struct zlib_params *zp = (struct zlib_params *) &writer->params;
   z_stream *z = &zp->z;     /* zlib state structure */
 
   if(zp->zlib_init == ZLIB_INIT_GZIP) {
@@ -560,33 +562,31 @@
 }
 
 static void gzip_close_writer(struct connectdata *conn,
-                              contenc_writer *writer)
+                              struct contenc_writer *writer)
 {
-  zlib_params *zp = (zlib_params *) &writer->params;
+  struct zlib_params *zp = (struct zlib_params *) &writer->params;
   z_stream *z = &zp->z;     /* zlib state structure */
 
   exit_zlib(conn, z, &zp->zlib_init, CURLE_OK);
 }
 
-static const content_encoding gzip_encoding = {
+static const struct content_encoding gzip_encoding = {
   "gzip",
   "x-gzip",
   gzip_init_writer,
   gzip_unencode_write,
   gzip_close_writer,
-  sizeof(zlib_params)
+  sizeof(struct zlib_params)
 };
 
 #endif /* HAVE_LIBZ */
 
 
 #ifdef HAVE_BROTLI
-
 /* Writer parameters. */
-typedef struct {
+struct brotli_params {
   BrotliDecoderState *br;    /* State structure for brotli. */
-}  brotli_params;
-
+};
 
 static CURLcode brotli_map_error(BrotliDecoderErrorCode be)
 {
@@ -627,10 +627,9 @@
 }
 
 static CURLcode brotli_init_writer(struct connectdata *conn,
-                                   contenc_writer *writer)
+                                   struct contenc_writer *writer)
 {
-  brotli_params *bp = (brotli_params *) &writer->params;
-
+  struct brotli_params *bp = (struct brotli_params *) &writer->params;
   (void) conn;
 
   if(!writer->downstream)
@@ -641,10 +640,10 @@
 }
 
 static CURLcode brotli_unencode_write(struct connectdata *conn,
-                                      contenc_writer *writer,
+                                      struct contenc_writer *writer,
                                       const char *buf, size_t nbytes)
 {
-  brotli_params *bp = (brotli_params *) &writer->params;
+  struct brotli_params *bp = (struct brotli_params *) &writer->params;
   const uint8_t *src = (const uint8_t *) buf;
   char *decomp;
   uint8_t *dst;
@@ -689,10 +688,9 @@
 }
 
 static void brotli_close_writer(struct connectdata *conn,
-                                contenc_writer *writer)
+                                struct contenc_writer *writer)
 {
-  brotli_params *bp = (brotli_params *) &writer->params;
-
+  struct brotli_params *bp = (struct brotli_params *) &writer->params;
   (void) conn;
 
   if(bp->br) {
@@ -701,40 +699,40 @@
   }
 }
 
-static const content_encoding brotli_encoding = {
+static const struct content_encoding brotli_encoding = {
   "br",
   NULL,
   brotli_init_writer,
   brotli_unencode_write,
   brotli_close_writer,
-  sizeof(brotli_params)
+  sizeof(struct brotli_params)
 };
 #endif
 
 
 /* Identity handler. */
 static CURLcode identity_init_writer(struct connectdata *conn,
-                                     contenc_writer *writer)
+                                     struct contenc_writer *writer)
 {
   (void) conn;
   return writer->downstream? CURLE_OK: CURLE_WRITE_ERROR;
 }
 
 static CURLcode identity_unencode_write(struct connectdata *conn,
-                                        contenc_writer *writer,
+                                        struct contenc_writer *writer,
                                         const char *buf, size_t nbytes)
 {
   return Curl_unencode_write(conn, writer->downstream, buf, nbytes);
 }
 
 static void identity_close_writer(struct connectdata *conn,
-                                  contenc_writer *writer)
+                                  struct contenc_writer *writer)
 {
   (void) conn;
   (void) writer;
 }
 
-static const content_encoding identity_encoding = {
+static const struct content_encoding identity_encoding = {
   "identity",
   "none",
   identity_init_writer,
@@ -745,7 +743,7 @@
 
 
 /* supported content encodings table. */
-static const content_encoding * const encodings[] = {
+static const struct content_encoding * const encodings[] = {
   &identity_encoding,
 #ifdef HAVE_LIBZ
   &deflate_encoding,
@@ -762,8 +760,8 @@
 char *Curl_all_content_encodings(void)
 {
   size_t len = 0;
-  const content_encoding * const *cep;
-  const content_encoding *ce;
+  const struct content_encoding * const *cep;
+  const struct content_encoding *ce;
   char *ace;
 
   for(cep = encodings; *cep; cep++) {
@@ -796,14 +794,14 @@
 
 /* Real client writer: no downstream. */
 static CURLcode client_init_writer(struct connectdata *conn,
-                                   contenc_writer *writer)
+                                   struct contenc_writer *writer)
 {
   (void) conn;
   return writer->downstream? CURLE_WRITE_ERROR: CURLE_OK;
 }
 
 static CURLcode client_unencode_write(struct connectdata *conn,
-                                      contenc_writer *writer,
+                                      struct contenc_writer *writer,
                                       const char *buf, size_t nbytes)
 {
   struct Curl_easy *data = conn->data;
@@ -818,13 +816,13 @@
 }
 
 static void client_close_writer(struct connectdata *conn,
-                                contenc_writer *writer)
+                                struct contenc_writer *writer)
 {
   (void) conn;
   (void) writer;
 }
 
-static const content_encoding client_encoding = {
+static const struct content_encoding client_encoding = {
   NULL,
   NULL,
   client_init_writer,
@@ -836,14 +834,14 @@
 
 /* Deferred error dummy writer. */
 static CURLcode error_init_writer(struct connectdata *conn,
-                                  contenc_writer *writer)
+                                  struct contenc_writer *writer)
 {
   (void) conn;
   return writer->downstream? CURLE_OK: CURLE_WRITE_ERROR;
 }
 
 static CURLcode error_unencode_write(struct connectdata *conn,
-                                     contenc_writer *writer,
+                                     struct contenc_writer *writer,
                                      const char *buf, size_t nbytes)
 {
   char *all = Curl_all_content_encodings();
@@ -861,13 +859,13 @@
 }
 
 static void error_close_writer(struct connectdata *conn,
-                               contenc_writer *writer)
+                               struct contenc_writer *writer)
 {
   (void) conn;
   (void) writer;
 }
 
-static const content_encoding error_encoding = {
+static const struct content_encoding error_encoding = {
   NULL,
   NULL,
   error_init_writer,
@@ -877,12 +875,13 @@
 };
 
 /* Create an unencoding writer stage using the given handler. */
-static contenc_writer *new_unencoding_writer(struct connectdata *conn,
-                                             const content_encoding *handler,
-                                             contenc_writer *downstream)
+static struct contenc_writer *
+new_unencoding_writer(struct connectdata *conn,
+                      const struct content_encoding *handler,
+                      struct contenc_writer *downstream)
 {
-  size_t sz = offsetof(contenc_writer, params) + handler->paramsize;
-  contenc_writer *writer = (contenc_writer *) calloc(1, sz);
+  size_t sz = offsetof(struct contenc_writer, params) + handler->paramsize;
+  struct contenc_writer *writer = (struct contenc_writer *)calloc(1, sz);
 
   if(writer) {
     writer->handler = handler;
@@ -897,7 +896,8 @@
 }
 
 /* Write data using an unencoding writer stack. */
-CURLcode Curl_unencode_write(struct connectdata *conn, contenc_writer *writer,
+CURLcode Curl_unencode_write(struct connectdata *conn,
+                             struct contenc_writer *writer,
                              const char *buf, size_t nbytes)
 {
   if(!nbytes)
@@ -910,7 +910,7 @@
 {
   struct Curl_easy *data = conn->data;
   struct SingleRequest *k = &data->req;
-  contenc_writer *writer = k->writer_stack;
+  struct contenc_writer *writer = k->writer_stack;
 
   while(writer) {
     k->writer_stack = writer->downstream;
@@ -921,12 +921,13 @@
 }
 
 /* Find the content encoding by name. */
-static const content_encoding *find_encoding(const char *name, size_t len)
+static const struct content_encoding *find_encoding(const char *name,
+                                                    size_t len)
 {
-  const content_encoding * const *cep;
+  const struct content_encoding * const *cep;
 
   for(cep = encodings; *cep; cep++) {
-    const content_encoding *ce = *cep;
+    const struct content_encoding *ce = *cep;
     if((strncasecompare(name, ce->name, len) && !ce->name[len]) ||
        (ce->alias && strncasecompare(name, ce->alias, len) && !ce->alias[len]))
       return ce;
@@ -962,8 +963,8 @@
       Curl_httpchunk_init(conn);   /* init our chunky engine. */
     }
     else if(namelen) {
-      const content_encoding *encoding = find_encoding(name, namelen);
-      contenc_writer *writer;
+      const struct content_encoding *encoding = find_encoding(name, namelen);
+      struct contenc_writer *writer;
 
       if(!k->writer_stack) {
         k->writer_stack = new_unencoding_writer(conn, &client_encoding, NULL);
@@ -997,7 +998,8 @@
   return CURLE_NOT_BUILT_IN;
 }
 
-CURLcode Curl_unencode_write(struct connectdata *conn, contenc_writer *writer,
+CURLcode Curl_unencode_write(struct connectdata *conn,
+                             struct contenc_writer *writer,
                              const char *buf, size_t nbytes)
 {
   (void) conn;
diff --git a/Utilities/cmcurl/lib/content_encoding.h b/Utilities/cmcurl/lib/content_encoding.h
index 4cd52be..bdd3f1c 100644
--- a/Utilities/cmcurl/lib/content_encoding.h
+++ b/Utilities/cmcurl/lib/content_encoding.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -23,31 +23,31 @@
  ***************************************************************************/
 #include "curl_setup.h"
 
-/* Decoding writer. */
-typedef struct contenc_writer_s contenc_writer;
-typedef struct content_encoding_s content_encoding;
-
-struct contenc_writer_s {
-  const content_encoding *handler;  /* Encoding handler. */
-  contenc_writer *downstream;  /* Downstream writer. */
+struct contenc_writer {
+  const struct content_encoding *handler;  /* Encoding handler. */
+  struct contenc_writer *downstream;  /* Downstream writer. */
   void *params;  /* Encoding-specific storage (variable length). */
 };
 
 /* Content encoding writer. */
-struct content_encoding_s {
+struct content_encoding {
   const char *name;        /* Encoding name. */
   const char *alias;       /* Encoding name alias. */
-  CURLcode (*init_writer)(struct connectdata *conn, contenc_writer *writer);
-  CURLcode (*unencode_write)(struct connectdata *conn, contenc_writer *writer,
+  CURLcode (*init_writer)(struct connectdata *conn,
+                          struct contenc_writer *writer);
+  CURLcode (*unencode_write)(struct connectdata *conn,
+                             struct contenc_writer *writer,
                              const char *buf, size_t nbytes);
-  void (*close_writer)(struct connectdata *conn, contenc_writer *writer);
+  void (*close_writer)(struct connectdata *conn,
+                       struct contenc_writer *writer);
   size_t paramsize;
 };
 
 
 CURLcode Curl_build_unencoding_stack(struct connectdata *conn,
                                      const char *enclist, int maybechunked);
-CURLcode Curl_unencode_write(struct connectdata *conn, contenc_writer *writer,
+CURLcode Curl_unencode_write(struct connectdata *conn,
+                             struct contenc_writer *writer,
                              const char *buf, size_t nbytes);
 void Curl_unencode_cleanup(struct connectdata *conn);
 char *Curl_all_content_encodings(void);
diff --git a/Utilities/cmcurl/lib/cookie.c b/Utilities/cmcurl/lib/cookie.c
index 9a9e14d..cb7d94b 100644
--- a/Utilities/cmcurl/lib/cookie.c
+++ b/Utilities/cmcurl/lib/cookie.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -96,6 +96,9 @@
 #include "curl_get_line.h"
 #include "curl_memrchr.h"
 #include "inet_pton.h"
+#include "parsedate.h"
+#include "rand.h"
+#include "rename.h"
 
 /* The last 3 #include files should be in this order */
 #include "curl_printf.h"
@@ -242,18 +245,17 @@
  */
 static const char *get_top_domain(const char * const domain, size_t *outlen)
 {
-  size_t len;
+  size_t len = 0;
   const char *first = NULL, *last;
 
-  if(!domain)
-    return NULL;
-
-  len = strlen(domain);
-  last = memrchr(domain, '.', len);
-  if(last) {
-    first = memrchr(domain, '.', (last - domain));
-    if(first)
-      len -= (++first - domain);
+  if(domain) {
+    len = strlen(domain);
+    last = memrchr(domain, '.', len);
+    if(last) {
+      first = memrchr(domain, '.', (last - domain));
+      if(first)
+        len -= (++first - domain);
+    }
   }
 
   if(outlen)
@@ -536,9 +538,9 @@
          * only test for names where that can possibly be true.
          */
         if(nlen > 3 && name[0] == '_' && name[1] == '_') {
-          if(strncasecompare("__Secure-", name, 9))
+          if(!strncmp("__Secure-", name, 9))
             co->prefix |= COOKIE_PREFIX__SECURE;
-          else if(strncasecompare("__Host-", name, 7))
+          else if(!strncmp("__Host-", name, 7))
             co->prefix |= COOKIE_PREFIX__HOST;
         }
 
@@ -715,7 +717,7 @@
     else if(co->expirestr) {
       /* Note that if the date couldn't get parsed for whatever reason,
          the cookie will be treated as a session cookie */
-      co->expires = curl_getdate(co->expirestr, NULL);
+      co->expires = Curl_getdate_capped(co->expirestr);
 
       /* Session cookies have expires set to 0 so if we get that back
          from the date parser let's add a second to make it a
@@ -753,7 +755,7 @@
         co->path = malloc(pathlen + 1); /* one extra for the zero byte */
         if(co->path) {
           memcpy(co->path, path, pathlen);
-          co->path[pathlen] = 0; /* zero terminate */
+          co->path[pathlen] = 0; /* null-terminate */
           co->spath = sanitize_cookie_path(co->path);
           if(!co->spath)
             badcookie = TRUE; /* out of memory bad */
@@ -819,22 +821,14 @@
           badcookie = TRUE;
         break;
       case 1:
-        /* This field got its explanation on the 23rd of May 2001 by
-           Andrés García:
-
-           flag: A TRUE/FALSE value indicating if all machines within a given
-           domain can access the variable. This value is set automatically by
-           the browser, depending on the value you set for the domain.
-
-           As far as I can see, it is set to true when the cookie says
+        /* flag: A TRUE/FALSE value indicating if all machines within a given
+           domain can access the variable. Set TRUE when the cookie says
            .domain.com and to false when the domain is complete www.domain.com
         */
         co->tailmatch = strcasecompare(ptr, "TRUE")?TRUE:FALSE;
         break;
       case 2:
-        /* It turns out, that sometimes the file format allows the path
-           field to remain not filled in, we try to detect this and work
-           around it! Andrés García made us aware of this... */
+        /* The file format allows the path field to remain not filled in */
         if(strcmp("TRUE", ptr) && strcmp("FALSE", ptr)) {
           /* only if the path doesn't look like a boolean option! */
           co->path = strdup(ptr);
@@ -1053,7 +1047,7 @@
 
         *clist = *co;  /* then store all the new data */
 
-        free(co);   /* free the newly alloced memory */
+        free(co);   /* free the newly allocated memory */
         co = clist; /* point to the previous struct instead */
 
         /* We have replaced a cookie, now skip the rest of the list but
@@ -1098,6 +1092,8 @@
  *
  * If 'newsession' is TRUE, discard all "session cookies" on read from file.
  *
+ * Note that 'data' might be called as NULL pointer.
+ *
  * Returns NULL on out of memory. Invalid cookies are ignored.
  ****************************************************************************/
 struct CookieInfo *Curl_cookie_init(struct Curl_easy *data,
@@ -1168,6 +1164,8 @@
   }
 
   c->running = TRUE;          /* now, we're running */
+  if(data)
+    data->state.cookie_engine = TRUE;
 
   return c;
 
@@ -1504,11 +1502,14 @@
  *
  * The function returns non-zero on write failure.
  */
-static int cookie_output(struct CookieInfo *c, const char *dumphere)
+static int cookie_output(struct Curl_easy *data,
+                         struct CookieInfo *c, const char *filename)
 {
   struct Cookie *co;
-  FILE *out;
+  FILE *out = NULL;
   bool use_stdout = FALSE;
+  char *tempstore = NULL;
+  bool error = false;
 
   if(!c)
     /* no cookie engine alive */
@@ -1517,16 +1518,24 @@
   /* at first, remove expired cookies */
   remove_expired(c);
 
-  if(!strcmp("-", dumphere)) {
+  if(!strcmp("-", filename)) {
     /* use stdout */
     out = stdout;
     use_stdout = TRUE;
   }
   else {
-    out = fopen(dumphere, FOPEN_WRITETEXT);
-    if(!out) {
-      return 1; /* failure */
-    }
+    unsigned char randsuffix[9];
+
+    if(Curl_rand_hex(data, randsuffix, sizeof(randsuffix)))
+      return 2;
+
+    tempstore = aprintf("%s.%s.tmp", filename, randsuffix);
+    if(!tempstore)
+      return 1;
+
+    out = fopen(tempstore, FOPEN_WRITETEXT);
+    if(!out)
+      goto error;
   }
 
   fputs("# Netscape HTTP Cookie File\n"
@@ -1536,35 +1545,31 @@
 
   if(c->numcookies) {
     unsigned int i;
-    unsigned int j;
+    size_t nvalid = 0;
     struct Cookie **array;
 
-    array = malloc(sizeof(struct Cookie *) * c->numcookies);
+    array = calloc(1, sizeof(struct Cookie *) * c->numcookies);
     if(!array) {
-      if(!use_stdout)
-        fclose(out);
-      return 1;
+      goto error;
     }
 
-    j = 0;
+    /* only sort the cookies with a domain property */
     for(i = 0; i < COOKIE_HASH_SIZE; i++) {
       for(co = c->cookies[i]; co; co = co->next) {
         if(!co->domain)
           continue;
-        array[j++] = co;
+        array[nvalid++] = co;
       }
     }
 
-    qsort(array, c->numcookies, sizeof(struct Cookie *), cookie_sort_ct);
+    qsort(array, nvalid, sizeof(struct Cookie *), cookie_sort_ct);
 
-    for(i = 0; i < j; i++) {
+    for(i = 0; i < nvalid; i++) {
       char *format_ptr = get_netscape_format(array[i]);
       if(format_ptr == NULL) {
         fprintf(out, "#\n# Fatal libcurl error\n");
         free(array);
-        if(!use_stdout)
-          fclose(out);
-        return 1;
+        goto error;
       }
       fprintf(out, "%s\n", format_ptr);
       free(format_ptr);
@@ -1572,10 +1577,24 @@
 
     free(array);
   }
-  if(!use_stdout)
-    fclose(out);
 
-  return 0;
+  if(!use_stdout) {
+    fclose(out);
+    out = NULL;
+    if(Curl_rename(tempstore, filename)) {
+      unlink(tempstore);
+      goto error;
+    }
+  }
+
+  goto cleanup;
+error:
+  error = true;
+cleanup:
+  if(out && !use_stdout)
+    fclose(out);
+  free(tempstore);
+  return error ? 1 : 0;
 }
 
 static struct curl_slist *cookie_list(struct Curl_easy *data)
@@ -1621,7 +1640,7 @@
   return list;
 }
 
-void Curl_flush_cookies(struct Curl_easy *data, int cleanup)
+void Curl_flush_cookies(struct Curl_easy *data, bool cleanup)
 {
   if(data->set.str[STRING_COOKIEJAR]) {
     if(data->change.cookielist) {
@@ -1634,7 +1653,7 @@
     Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, CURL_LOCK_ACCESS_SINGLE);
 
     /* if we have a destination file for all the cookies to get dumped to */
-    if(cookie_output(data->cookies, data->set.str[STRING_COOKIEJAR]))
+    if(cookie_output(data, data->cookies, data->set.str[STRING_COOKIEJAR]))
       infof(data, "WARNING: failed to save cookies in %s\n",
             data->set.str[STRING_COOKIEJAR]);
   }
@@ -1650,6 +1669,7 @@
 
   if(cleanup && (!data->share || (data->cookies != data->share->cookies))) {
     Curl_cookie_cleanup(data->cookies);
+    data->cookies = NULL;
   }
   Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE);
 }
diff --git a/Utilities/cmcurl/lib/cookie.h b/Utilities/cmcurl/lib/cookie.h
index b2730cf..b3865e6 100644
--- a/Utilities/cmcurl/lib/cookie.h
+++ b/Utilities/cmcurl/lib/cookie.h
@@ -109,7 +109,7 @@
 #define Curl_cookie_cleanup(x) Curl_nop_stmt
 #define Curl_flush_cookies(x,y) Curl_nop_stmt
 #else
-void Curl_flush_cookies(struct Curl_easy *data, int cleanup);
+void Curl_flush_cookies(struct Curl_easy *data, bool cleanup);
 void Curl_cookie_cleanup(struct CookieInfo *);
 struct CookieInfo *Curl_cookie_init(struct Curl_easy *data,
                                     const char *, struct CookieInfo *, bool);
diff --git a/Utilities/cmcurl/lib/curl_addrinfo.c b/Utilities/cmcurl/lib/curl_addrinfo.c
index 16c4779..947d0d3 100644
--- a/Utilities/cmcurl/lib/curl_addrinfo.c
+++ b/Utilities/cmcurl/lib/curl_addrinfo.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -50,10 +50,6 @@
 #  define in_addr_t unsigned long
 #endif
 
-#if defined(WIN32) && defined(USE_UNIX_SOCKETS)
-#include <afunix.h>
-#endif
-
 #include <stddef.h>
 
 #include "curl_addrinfo.h"
@@ -82,16 +78,13 @@
 #endif
 
 void
-Curl_freeaddrinfo(Curl_addrinfo *cahead)
+Curl_freeaddrinfo(struct Curl_addrinfo *cahead)
 {
-  Curl_addrinfo *vqualifier canext;
-  Curl_addrinfo *ca;
+  struct Curl_addrinfo *vqualifier canext;
+  struct Curl_addrinfo *ca;
 
-  for(ca = cahead; ca != NULL; ca = canext) {
-    free(ca->ai_addr);
-    free(ca->ai_canonname);
+  for(ca = cahead; ca; ca = canext) {
     canext = ca->ai_next;
-
     free(ca);
   }
 }
@@ -116,13 +109,13 @@
 Curl_getaddrinfo_ex(const char *nodename,
                     const char *servname,
                     const struct addrinfo *hints,
-                    Curl_addrinfo **result)
+                    struct Curl_addrinfo **result)
 {
   const struct addrinfo *ai;
   struct addrinfo *aihead;
-  Curl_addrinfo *cafirst = NULL;
-  Curl_addrinfo *calast = NULL;
-  Curl_addrinfo *ca;
+  struct Curl_addrinfo *cafirst = NULL;
+  struct Curl_addrinfo *calast = NULL;
+  struct Curl_addrinfo *ca;
   size_t ss_size;
   int error;
 
@@ -135,7 +128,7 @@
   /* traverse the addrinfo list */
 
   for(ai = aihead; ai != NULL; ai = ai->ai_next) {
-
+    size_t namelen = ai->ai_canonname ? strlen(ai->ai_canonname) + 1 : 0;
     /* ignore elements with unsupported address family, */
     /* settle family-specific sockaddr structure size.  */
     if(ai->ai_family == AF_INET)
@@ -155,7 +148,7 @@
     if((size_t)ai->ai_addrlen < ss_size)
       continue;
 
-    ca = malloc(sizeof(Curl_addrinfo));
+    ca = malloc(sizeof(struct Curl_addrinfo) + ss_size + namelen);
     if(!ca) {
       error = EAI_MEMORY;
       break;
@@ -173,22 +166,12 @@
     ca->ai_canonname = NULL;
     ca->ai_next      = NULL;
 
-    ca->ai_addr = malloc(ss_size);
-    if(!ca->ai_addr) {
-      error = EAI_MEMORY;
-      free(ca);
-      break;
-    }
+    ca->ai_addr = (void *)((char *)ca + sizeof(struct Curl_addrinfo));
     memcpy(ca->ai_addr, ai->ai_addr, ss_size);
 
-    if(ai->ai_canonname != NULL) {
-      ca->ai_canonname = strdup(ai->ai_canonname);
-      if(!ca->ai_canonname) {
-        error = EAI_MEMORY;
-        free(ca->ai_addr);
-        free(ca);
-        break;
-      }
+    if(namelen) {
+      ca->ai_canonname = (void *)((char *)ca->ai_addr + ss_size);
+      memcpy(ca->ai_canonname, ai->ai_canonname, namelen);
     }
 
     /* if the return list is empty, this becomes the first element */
@@ -256,7 +239,6 @@
  *       struct sockaddr      *ai_addr;
  *       struct Curl_addrinfo *ai_next;
  *     };
- *     typedef struct Curl_addrinfo Curl_addrinfo;
  *
  *   hostent defined in <netdb.h>
  *
@@ -273,12 +255,12 @@
  *     #define h_addr  h_addr_list[0]
  */
 
-Curl_addrinfo *
+struct Curl_addrinfo *
 Curl_he2ai(const struct hostent *he, int port)
 {
-  Curl_addrinfo *ai;
-  Curl_addrinfo *prevai = NULL;
-  Curl_addrinfo *firstai = NULL;
+  struct Curl_addrinfo *ai;
+  struct Curl_addrinfo *prevai = NULL;
+  struct Curl_addrinfo *firstai = NULL;
   struct sockaddr_in *addr;
 #ifdef ENABLE_IPV6
   struct sockaddr_in6 *addr6;
@@ -294,8 +276,8 @@
   DEBUGASSERT((he->h_name != NULL) && (he->h_addr_list != NULL));
 
   for(i = 0; (curr = he->h_addr_list[i]) != NULL; i++) {
-
     size_t ss_size;
+    size_t namelen = strlen(he->h_name) + 1; /* include zero termination */
 #ifdef ENABLE_IPV6
     if(he->h_addrtype == AF_INET6)
       ss_size = sizeof(struct sockaddr_in6);
@@ -303,24 +285,17 @@
 #endif
       ss_size = sizeof(struct sockaddr_in);
 
-    ai = calloc(1, sizeof(Curl_addrinfo));
+    /* allocate memory to told the struct, the address and the name */
+    ai = calloc(1, sizeof(struct Curl_addrinfo) + ss_size + namelen);
     if(!ai) {
       result = CURLE_OUT_OF_MEMORY;
       break;
     }
-    ai->ai_canonname = strdup(he->h_name);
-    if(!ai->ai_canonname) {
-      result = CURLE_OUT_OF_MEMORY;
-      free(ai);
-      break;
-    }
-    ai->ai_addr = calloc(1, ss_size);
-    if(!ai->ai_addr) {
-      result = CURLE_OUT_OF_MEMORY;
-      free(ai->ai_canonname);
-      free(ai);
-      break;
-    }
+    /* put the address after the struct */
+    ai->ai_addr = (void *)((char *)ai + sizeof(struct Curl_addrinfo));
+    /* then put the name after the address */
+    ai->ai_canonname = (char *)ai->ai_addr + ss_size;
+    memcpy(ai->ai_canonname, he->h_name, namelen);
 
     if(!firstai)
       /* store the pointer we want to return from this function */
@@ -393,10 +368,10 @@
  * given address/host
  */
 
-Curl_addrinfo *
+struct Curl_addrinfo *
 Curl_ip2addr(int af, const void *inaddr, const char *hostname, int port)
 {
-  Curl_addrinfo *ai;
+  struct Curl_addrinfo *ai;
 
 #if defined(__VMS) && \
     defined(__INITIAL_POINTER_SIZE) && (__INITIAL_POINTER_SIZE == 64)
@@ -469,7 +444,7 @@
  * Given an IPv4 or IPv6 dotted string address, this converts it to a proper
  * allocated Curl_addrinfo struct and returns it.
  */
-Curl_addrinfo *Curl_str2addr(char *address, int port)
+struct Curl_addrinfo *Curl_str2addr(char *address, int port)
 {
   struct in_addr in;
   if(Curl_inet_pton(AF_INET, address, &in) > 0)
@@ -492,22 +467,19 @@
  * struct initialized with this path.
  * Set '*longpath' to TRUE if the error is a too long path.
  */
-Curl_addrinfo *Curl_unix2addr(const char *path, bool *longpath, bool abstract)
+struct Curl_addrinfo *Curl_unix2addr(const char *path, bool *longpath,
+                                     bool abstract)
 {
-  Curl_addrinfo *ai;
+  struct Curl_addrinfo *ai;
   struct sockaddr_un *sa_un;
   size_t path_len;
 
   *longpath = FALSE;
 
-  ai = calloc(1, sizeof(Curl_addrinfo));
+  ai = calloc(1, sizeof(struct Curl_addrinfo) + sizeof(struct sockaddr_un));
   if(!ai)
     return NULL;
-  ai->ai_addr = calloc(1, sizeof(struct sockaddr_un));
-  if(!ai->ai_addr) {
-    free(ai);
-    return NULL;
-  }
+  ai->ai_addr = (void *)((char *)ai + sizeof(struct Curl_addrinfo));
 
   sa_un = (void *) ai->ai_addr;
   sa_un->sun_family = AF_UNIX;
@@ -515,7 +487,6 @@
   /* sun_path must be able to store the NUL-terminated path */
   path_len = strlen(path) + 1;
   if(path_len > sizeof(sa_un->sun_path)) {
-    free(ai->ai_addr);
     free(ai);
     *longpath = TRUE;
     return NULL;
@@ -598,9 +569,9 @@
  * Work-arounds the sin6_port is always zero bug on iOS 9.3.2 and Mac OS X
  * 10.11.5.
  */
-void Curl_addrinfo_set_port(Curl_addrinfo *addrinfo, int port)
+void Curl_addrinfo_set_port(struct Curl_addrinfo *addrinfo, int port)
 {
-  Curl_addrinfo *ca;
+  struct Curl_addrinfo *ca;
   struct sockaddr_in *addr;
 #ifdef ENABLE_IPV6
   struct sockaddr_in6 *addr6;
diff --git a/Utilities/cmcurl/lib/curl_addrinfo.h b/Utilities/cmcurl/lib/curl_addrinfo.h
index 205e121..a0cade6 100644
--- a/Utilities/cmcurl/lib/curl_addrinfo.h
+++ b/Utilities/cmcurl/lib/curl_addrinfo.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -40,7 +40,6 @@
 #  include <stdlib.h>
 #endif
 
-
 /*
  * Curl_addrinfo is our internal struct definition that we use to allow
  * consistent internal handling of this data. We use this even when the
@@ -58,29 +57,29 @@
   struct sockaddr      *ai_addr;
   struct Curl_addrinfo *ai_next;
 };
-typedef struct Curl_addrinfo Curl_addrinfo;
 
 void
-Curl_freeaddrinfo(Curl_addrinfo *cahead);
+Curl_freeaddrinfo(struct Curl_addrinfo *cahead);
 
 #ifdef HAVE_GETADDRINFO
 int
 Curl_getaddrinfo_ex(const char *nodename,
                     const char *servname,
                     const struct addrinfo *hints,
-                    Curl_addrinfo **result);
+                    struct Curl_addrinfo **result);
 #endif
 
-Curl_addrinfo *
+struct Curl_addrinfo *
 Curl_he2ai(const struct hostent *he, int port);
 
-Curl_addrinfo *
+struct Curl_addrinfo *
 Curl_ip2addr(int af, const void *inaddr, const char *hostname, int port);
 
-Curl_addrinfo *Curl_str2addr(char *dotted, int port);
+struct Curl_addrinfo *Curl_str2addr(char *dotted, int port);
 
 #ifdef USE_UNIX_SOCKETS
-Curl_addrinfo *Curl_unix2addr(const char *path, bool *longpath, bool abstract);
+struct Curl_addrinfo *Curl_unix2addr(const char *path, bool *longpath,
+                                     bool abstract);
 #endif
 
 #if defined(CURLDEBUG) && defined(HAVE_GETADDRINFO) && \
@@ -98,7 +97,7 @@
 
 #ifdef HAVE_GETADDRINFO
 #ifdef USE_RESOLVE_ON_IPS
-void Curl_addrinfo_set_port(Curl_addrinfo *addrinfo, int port);
+void Curl_addrinfo_set_port(struct Curl_addrinfo *addrinfo, int port);
 #else
 #define Curl_addrinfo_set_port(x,y)
 #endif
diff --git a/Utilities/cmcurl/lib/curl_base64.h b/Utilities/cmcurl/lib/curl_base64.h
index 7e9fc26..cfb6ee7 100644
--- a/Utilities/cmcurl/lib/curl_base64.h
+++ b/Utilities/cmcurl/lib/curl_base64.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
diff --git a/Utilities/cmcurl/lib/curl_config.h.cmake b/Utilities/cmcurl/lib/curl_config.h.cmake
index b285c3f..00ae658 100644
--- a/Utilities/cmcurl/lib/curl_config.h.cmake
+++ b/Utilities/cmcurl/lib/curl_config.h.cmake
@@ -1,5 +1,28 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
 /* lib/curl_config.h.in.  Generated somehow by cmake.  */
 
+#include <cm3p/kwiml/abi.h>
+
 /* when building libcurl itself */
 #cmakedefine BUILDING_LIBCURL 1
 
@@ -33,6 +56,9 @@
 /* to disable LDAPS */
 #cmakedefine CURL_DISABLE_LDAPS 1
 
+/* to enable MQTT */
+#undef CURL_ENABLE_MQTT
+
 /* to disable POP3 */
 #cmakedefine CURL_DISABLE_POP3 1
 
@@ -64,6 +90,9 @@
 #define CURL_EXTERN_SYMBOL
 #endif
 
+/* Allow SMB to work on Windows */
+#cmakedefine USE_WIN32_CRYPTO
+
 /* Use Windows LDAP implementation */
 #cmakedefine USE_WIN32_LDAP 1
 
@@ -133,15 +162,9 @@
 /* Define to 1 if you have the <crypto.h> header file. */
 #cmakedefine HAVE_CRYPTO_H 1
 
-/* Define to 1 if you have the <des.h> header file. */
-#cmakedefine HAVE_DES_H 1
-
 /* Define to 1 if you have the <dlfcn.h> header file. */
 #cmakedefine HAVE_DLFCN_H 1
 
-/* Define to 1 if you have the `ENGINE_load_builtin_engines' function. */
-#cmakedefine HAVE_ENGINE_LOAD_BUILTIN_ENGINES 1
-
 /* Define to 1 if you have the <errno.h> header file. */
 #cmakedefine HAVE_ERRNO_H 1
 
@@ -232,6 +255,9 @@
 /* Define to 1 if you have the `getsockname' function. */
 #cmakedefine HAVE_GETSOCKNAME 1
 
+/* Define to 1 if you have the `if_nametoindex' function. */
+#cmakedefine HAVE_IF_NAMETOINDEX 1
+
 /* Define to 1 if you have the `getpwuid' function. */
 #cmakedefine HAVE_GETPWUID 1
 
@@ -395,8 +421,8 @@
 /* Define to 1 if you have the <libssh2.h> header file. */
 #cmakedefine HAVE_LIBSSH2_H 1
 
-/* Define to 1 if you have the `ssl' library (-lssl). */
-#cmakedefine HAVE_LIBSSL 1
+/* Define to 1 if you have the <libssh/libssh.h> header file. */
+#cmakedefine HAVE_LIBSSH_LIBSSH_H 1
 
 /* if zlib is available */
 #cmakedefine HAVE_LIBZ 1
@@ -404,9 +430,6 @@
 /* if brotli is available */
 #cmakedefine HAVE_BROTLI 1
 
-/* if your compiler supports LL */
-#cmakedefine HAVE_LL 1
-
 /* Define to 1 if you have the <locale.h> header file. */
 #cmakedefine HAVE_LOCALE_H 1
 
@@ -414,7 +437,9 @@
 #cmakedefine HAVE_LOCALTIME_R 1
 
 /* Define to 1 if the compiler supports the 'long long' data type. */
-#cmakedefine HAVE_LONGLONG 1
+#if KWIML_ABI_SIZEOF_LONG_LONG
+#  define HAVE_LONGLONG 1
+#endif
 
 /* Define to 1 if you have the malloc.h header file. */
 #cmakedefine HAVE_MALLOC_H 1
@@ -446,9 +471,6 @@
 /* Define to 1 if you have the <openssl/crypto.h> header file. */
 #cmakedefine HAVE_OPENSSL_CRYPTO_H 1
 
-/* Define to 1 if you have the <openssl/engine.h> header file. */
-#cmakedefine HAVE_OPENSSL_ENGINE_H 1
-
 /* Define to 1 if you have the <openssl/err.h> header file. */
 #cmakedefine HAVE_OPENSSL_ERR_H 1
 
@@ -575,9 +597,6 @@
 /* Define to 1 if you have the `socket' function. */
 #cmakedefine HAVE_SOCKET 1
 
-/* Define to 1 if you have the `SSL_get_shutdown' function. */
-#cmakedefine HAVE_SSL_GET_SHUTDOWN 1
-
 /* Define to 1 if you have the <ssl.h> header file. */
 #cmakedefine HAVE_SSL_H 1
 
@@ -879,35 +898,46 @@
 /* Define to the function return type for send. */
 #cmakedefine SEND_TYPE_RETV ${SEND_TYPE_RETV}
 
+/*
+ Note: SIZEOF_* variables are fetched with CMake through check_type_size().
+ As per CMake documentation on CheckTypeSize, C preprocessor code is
+ generated by CMake into SIZEOF_*_CODE. This is what we use in the
+ following statements.
+
+ Reference: https://cmake.org/cmake/help/latest/module/CheckTypeSize.html
+*/
+
 /* The size of `int', as computed by sizeof. */
-@SIZEOF_INT_CODE@
+#define SIZEOF_INT KWIML_ABI_SIZEOF_INT
 
 /* The size of `short', as computed by sizeof. */
-@SIZEOF_SHORT_CODE@
+#define SIZEOF_SHORT KWIML_ABI_SIZEOF_SHORT
 
 /* The size of `long', as computed by sizeof. */
-@SIZEOF_LONG_CODE@
+#define SIZEOF_LONG KWIML_ABI_SIZEOF_LONG
 
 /* The size of `long long', as computed by sizeof. */
-@SIZEOF_LONG_LONG_CODE@
+#define SIZEOF_LONG_LONG KWIML_ABI_SIZEOF_LONG_LONG
 
 /* The size of `__int64', as computed by sizeof. */
-@SIZEOF___INT64_CODE@
+#if KWIML_ABI_SIZEOF___INT64
+#  define SIZEOF___INT64 KWIML_ABI_SIZEOF___INT64
+#endif
 
 /* The size of `off_t', as computed by sizeof. */
-@SIZEOF_OFF_T_CODE@
+${SIZEOF_OFF_T_CODE}
 
 /* The size of `curl_off_t', as computed by sizeof. */
-@SIZEOF_CURL_OFF_T_CODE@
+${SIZEOF_CURL_OFF_T_CODE}
 
 /* The size of `size_t', as computed by sizeof. */
-@SIZEOF_SIZE_T_CODE@
+${SIZEOF_SIZE_T_CODE}
 
 /* The size of `ssize_t', as computed by sizeof. */
-@SIZEOF_SSIZE_T_CODE@
+${SIZEOF_SSIZE_T_CODE}
 
 /* The size of `time_t', as computed by sizeof. */
-@SIZEOF_TIME_T_CODE@
+${SIZEOF_TIME_T_CODE}
 
 /* Define to 1 if you have the ANSI C header files. */
 #cmakedefine STDC_HEADERS 1
@@ -933,15 +963,21 @@
 /* if GnuTLS is enabled */
 #cmakedefine USE_GNUTLS 1
 
-/* if PolarSSL is enabled */
-#cmakedefine USE_POLARSSL 1
-
 /* if Secure Transport is enabled */
 #cmakedefine USE_SECTRANSP 1
 
 /* if mbedTLS is enabled */
 #cmakedefine USE_MBEDTLS 1
 
+/* if BearSSL is enabled */
+#cmakedefine USE_BEARSSL 1
+
+/* if WolfSSL is enabled */
+#cmakedefine USE_WOLFSSL 1
+
+/* if libSSH is in use */
+#cmakedefine USE_LIBSSH 1
+
 /* if libSSH2 is in use */
 #cmakedefine USE_LIBSSH2 1
 
@@ -951,6 +987,9 @@
 /* if NSS is enabled */
 #cmakedefine USE_NSS 1
 
+/* if you have the PK11_CreateManagedGenericObject function */
+#cmakedefine HAVE_PK11_CREATEMANAGEDGENERICOBJECT 1
+
 /* if you want to use OpenLDAP code instead of legacy ldap implementation */
 #cmakedefine USE_OPENLDAP 1
 
@@ -960,9 +999,24 @@
 /* to enable NGHTTP2  */
 #cmakedefine USE_NGHTTP2 1
 
+/* to enable NGTCP2 */
+#cmakedefine USE_NGTCP2 1
+
+/* to enable NGHTTP3  */
+#cmakedefine USE_NGHTTP3 1
+
+/* to enable quiche */
+#cmakedefine USE_QUICHE 1
+
+/* Define to 1 if you have the quiche_conn_set_qlog_fd function. */
+#cmakedefine HAVE_QUICHE_CONN_SET_QLOG_FD 1
+
 /* if Unix domain sockets are enabled  */
 #cmakedefine USE_UNIX_SOCKETS
 
+/* to enable alt-svc */
+#cmakedefine USE_ALTSVC 1
+
 /* to enable SSPI support */
 #cmakedefine USE_WINDOWS_SSPI 1
 
diff --git a/Utilities/cmcurl/lib/curl_des.c b/Utilities/cmcurl/lib/curl_des.c
index b123a00..39c0f35 100644
--- a/Utilities/cmcurl/lib/curl_des.c
+++ b/Utilities/cmcurl/lib/curl_des.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 2015, Steve Holme, <steve_holme@hotmail.com>.
+ * Copyright (C) 2015 - 2019, Steve Holme, <steve_holme@hotmail.com>.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
diff --git a/Utilities/cmcurl/lib/curl_des.h b/Utilities/cmcurl/lib/curl_des.h
index 129060f..a42eeb5 100644
--- a/Utilities/cmcurl/lib/curl_des.h
+++ b/Utilities/cmcurl/lib/curl_des.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 2015, Steve Holme, <steve_holme@hotmail.com>.
+ * Copyright (C) 2015 - 2019, Steve Holme, <steve_holme@hotmail.com>.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
diff --git a/Utilities/cmcurl/lib/curl_endian.c b/Utilities/cmcurl/lib/curl_endian.c
index b7563b3..a774d13 100644
--- a/Utilities/cmcurl/lib/curl_endian.c
+++ b/Utilities/cmcurl/lib/curl_endian.c
@@ -81,6 +81,7 @@
                           ((unsigned short)buf[1]));
 }
 
+#if (CURL_SIZEOF_CURL_OFF_T > 4)
 /*
  * write32_le()
  *
@@ -100,7 +101,6 @@
   buffer[3] = (char)((value & 0xFF000000) >> 24);
 }
 
-#if (CURL_SIZEOF_CURL_OFF_T > 4)
 /*
  * Curl_write64_le()
  *
diff --git a/Utilities/cmcurl/lib/curl_endian.h b/Utilities/cmcurl/lib/curl_endian.h
index 4f345a6..9830e58 100644
--- a/Utilities/cmcurl/lib/curl_endian.h
+++ b/Utilities/cmcurl/lib/curl_endian.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -31,9 +31,6 @@
 /* Converts a 16-bit integer from big endian */
 unsigned short Curl_read16_be(const unsigned char *buf);
 
-/* Converts a 32-bit integer to little endian */
-void Curl_write32_le(const int value, unsigned char *buffer);
-
 #if (CURL_SIZEOF_CURL_OFF_T > 4)
 /* Converts a 64-bit integer to little endian */
 #if defined(HAVE_LONGLONG)
diff --git a/Utilities/cmcurl/lib/curl_fnmatch.h b/Utilities/cmcurl/lib/curl_fnmatch.h
index 69ffe39..34fccae 100644
--- a/Utilities/cmcurl/lib/curl_fnmatch.h
+++ b/Utilities/cmcurl/lib/curl_fnmatch.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2009, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
diff --git a/Utilities/cmcurl/lib/curl_gethostname.h b/Utilities/cmcurl/lib/curl_gethostname.h
index 07517c5..8ae15e6 100644
--- a/Utilities/cmcurl/lib/curl_gethostname.h
+++ b/Utilities/cmcurl/lib/curl_gethostname.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2010, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
diff --git a/Utilities/cmcurl/lib/curl_hmac.h b/Utilities/cmcurl/lib/curl_hmac.h
index 756dc9e..9b70c84 100644
--- a/Utilities/cmcurl/lib/curl_hmac.h
+++ b/Utilities/cmcurl/lib/curl_hmac.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -24,6 +24,8 @@
 
 #ifndef CURL_DISABLE_CRYPTO_AUTH
 
+#define HMAC_MD5_LENGTH 16
+
 typedef void    (* HMAC_hinit_func)(void *context);
 typedef void    (* HMAC_hupdate_func)(void *context,
                                       const unsigned char *data,
@@ -32,35 +34,38 @@
 
 
 /* Per-hash function HMAC parameters. */
-
-typedef struct {
-  HMAC_hinit_func       hmac_hinit;     /* Initialize context procedure. */
+struct HMAC_params {
+  HMAC_hinit_func
+  hmac_hinit;     /* Initialize context procedure. */
   HMAC_hupdate_func     hmac_hupdate;   /* Update context with data. */
   HMAC_hfinal_func      hmac_hfinal;    /* Get final result procedure. */
   unsigned int          hmac_ctxtsize;  /* Context structure size. */
   unsigned int          hmac_maxkeylen; /* Maximum key length (bytes). */
   unsigned int          hmac_resultlen; /* Result length (bytes). */
-} HMAC_params;
+};
 
 
 /* HMAC computation context. */
-
-typedef struct {
-  const HMAC_params *hmac_hash; /* Hash function definition. */
+struct HMAC_context {
+  const struct HMAC_params *hmac_hash; /* Hash function definition. */
   void *hmac_hashctxt1;         /* Hash function context 1. */
   void *hmac_hashctxt2;         /* Hash function context 2. */
-} HMAC_context;
+};
 
 
 /* Prototypes. */
-
-HMAC_context * Curl_HMAC_init(const HMAC_params *hashparams,
-                              const unsigned char *key,
-                              unsigned int keylen);
-int Curl_HMAC_update(HMAC_context *context,
+struct HMAC_context *Curl_HMAC_init(const struct HMAC_params *hashparams,
+                                    const unsigned char *key,
+                                    unsigned int keylen);
+int Curl_HMAC_update(struct HMAC_context *context,
                      const unsigned char *data,
                      unsigned int len);
-int Curl_HMAC_final(HMAC_context *context, unsigned char *result);
+int Curl_HMAC_final(struct HMAC_context *context, unsigned char *result);
+
+CURLcode Curl_hmacit(const struct HMAC_params *hashparams,
+                     const unsigned char *key, const size_t keylen,
+                     const unsigned char *data, const size_t datalen,
+                     unsigned char *output);
 
 #endif
 
diff --git a/Utilities/cmcurl/lib/curl_ldap.h b/Utilities/cmcurl/lib/curl_ldap.h
index 94c0029..912e131 100644
--- a/Utilities/cmcurl/lib/curl_ldap.h
+++ b/Utilities/cmcurl/lib/curl_ldap.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2010, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
diff --git a/Utilities/cmcurl/lib/curl_md4.h b/Utilities/cmcurl/lib/curl_md4.h
index 392203f..c7bb209 100644
--- a/Utilities/cmcurl/lib/curl_md4.h
+++ b/Utilities/cmcurl/lib/curl_md4.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -24,14 +24,13 @@
 
 #include "curl_setup.h"
 
-#if defined(USE_NSS) || defined(USE_OS400CRYPTO) || \
-    (defined(USE_OPENSSL) && defined(OPENSSL_NO_MD4)) || \
-    (defined(USE_MBEDTLS) && !defined(MBEDTLS_MD4_C))
+#if !defined(CURL_DISABLE_CRYPTO_AUTH)
 
-void Curl_md4it(unsigned char *output, const unsigned char *input, size_t len);
+#define MD4_DIGEST_LENGTH 16
 
-#endif /* defined(USE_NSS) || defined(USE_OS400CRYPTO) ||
-    (defined(USE_OPENSSL) && defined(OPENSSL_NO_MD4)) ||
-    (defined(USE_MBEDTLS) && !defined(MBEDTLS_MD4_C)) */
+void Curl_md4it(unsigned char *output, const unsigned char *input,
+                const size_t len);
+
+#endif /* !defined(CURL_DISABLE_CRYPTO_AUTH) */
 
 #endif /* HEADER_CURL_MD4_H */
diff --git a/Utilities/cmcurl/lib/curl_md5.h b/Utilities/cmcurl/lib/curl_md5.h
index aaf25f6..e06c68e 100644
--- a/Utilities/cmcurl/lib/curl_md5.h
+++ b/Utilities/cmcurl/lib/curl_md5.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -33,30 +33,30 @@
                                       unsigned int len);
 typedef void (* Curl_MD5_final_func)(unsigned char *result, void *context);
 
-typedef struct {
+struct MD5_params {
   Curl_MD5_init_func     md5_init_func;   /* Initialize context procedure */
   Curl_MD5_update_func   md5_update_func; /* Update context with data */
   Curl_MD5_final_func    md5_final_func;  /* Get final result procedure */
   unsigned int           md5_ctxtsize;  /* Context structure size */
   unsigned int           md5_resultlen; /* Result length (bytes) */
-} MD5_params;
+};
 
-typedef struct {
-  const MD5_params      *md5_hash;      /* Hash function definition */
+struct MD5_context {
+  const struct MD5_params *md5_hash;    /* Hash function definition */
   void                  *md5_hashctx;   /* Hash function context */
-} MD5_context;
+};
 
-extern const MD5_params Curl_DIGEST_MD5[1];
-extern const HMAC_params Curl_HMAC_MD5[1];
+extern const struct MD5_params Curl_DIGEST_MD5[1];
+extern const struct HMAC_params Curl_HMAC_MD5[1];
 
-void Curl_md5it(unsigned char *output,
-                const unsigned char *input);
+void Curl_md5it(unsigned char *output, const unsigned char *input,
+                const size_t len);
 
-MD5_context * Curl_MD5_init(const MD5_params *md5params);
-CURLcode Curl_MD5_update(MD5_context *context,
+struct MD5_context *Curl_MD5_init(const struct MD5_params *md5params);
+CURLcode Curl_MD5_update(struct MD5_context *context,
                          const unsigned char *data,
                          unsigned int len);
-CURLcode Curl_MD5_final(MD5_context *context, unsigned char *result);
+CURLcode Curl_MD5_final(struct MD5_context *context, unsigned char *result);
 
 #endif
 
diff --git a/Utilities/cmcurl/lib/curl_memrchr.h b/Utilities/cmcurl/lib/curl_memrchr.h
index 747509c..90a8a07 100644
--- a/Utilities/cmcurl/lib/curl_memrchr.h
+++ b/Utilities/cmcurl/lib/curl_memrchr.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2009, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
diff --git a/Utilities/cmcurl/lib/curl_multibyte.c b/Utilities/cmcurl/lib/curl_multibyte.c
index e48334f..2c8925b5 100644
--- a/Utilities/cmcurl/lib/curl_multibyte.c
+++ b/Utilities/cmcurl/lib/curl_multibyte.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -20,24 +20,21 @@
  *
  ***************************************************************************/
 
+/*
+ * This file is 'mem-include-scan' clean. See test 1132.
+ */
+
 #include "curl_setup.h"
 
-#include <curl/curl.h>
-
-#if defined(USE_WIN32_IDN) || ((defined(USE_WINDOWS_SSPI) || \
-                                defined(USE_WIN32_LDAP)) && defined(UNICODE))
-
- /*
-  * MultiByte conversions using Windows kernel32 library.
-  */
+#if defined(WIN32)
 
 #include "curl_multibyte.h"
-#include "curl_memory.h"
 
-/* The last #include file should be: */
-#include "memdebug.h"
+/*
+ * MultiByte conversions using Windows kernel32 library.
+ */
 
-wchar_t *Curl_convert_UTF8_to_wchar(const char *str_utf8)
+wchar_t *curlx_convert_UTF8_to_wchar(const char *str_utf8)
 {
   wchar_t *str_w = NULL;
 
@@ -59,7 +56,7 @@
   return str_w;
 }
 
-char *Curl_convert_wchar_to_UTF8(const wchar_t *str_w)
+char *curlx_convert_wchar_to_UTF8(const wchar_t *str_w)
 {
   char *str_utf8 = NULL;
 
@@ -81,4 +78,76 @@
   return str_utf8;
 }
 
-#endif /* USE_WIN32_IDN || ((USE_WINDOWS_SSPI || USE_WIN32_LDAP) && UNICODE) */
+#endif /* WIN32 */
+
+#if defined(USE_WIN32_LARGE_FILES) || defined(USE_WIN32_SMALL_FILES)
+
+FILE *curlx_win32_fopen(const char *filename, const char *mode)
+{
+#ifdef _UNICODE
+  FILE *result = NULL;
+  wchar_t *filename_w = curlx_convert_UTF8_to_wchar(filename);
+  wchar_t *mode_w = curlx_convert_UTF8_to_wchar(mode);
+  if(filename_w && mode_w)
+    result = _wfopen(filename_w, mode_w);
+  free(filename_w);
+  free(mode_w);
+  if(result)
+    return result;
+#endif
+
+  return (fopen)(filename, mode);
+}
+
+int curlx_win32_stat(const char *path, struct_stat *buffer)
+{
+  int result = -1;
+#ifdef _UNICODE
+  wchar_t *path_w = curlx_convert_UTF8_to_wchar(path);
+#endif /* _UNICODE */
+
+#if defined(USE_WIN32_SMALL_FILES)
+#if defined(_UNICODE)
+  if(path_w)
+    result = _wstat(path_w, buffer);
+  else
+#endif /* _UNICODE */
+    result = _stat(path, buffer);
+#else /* USE_WIN32_SMALL_FILES */
+#if defined(_UNICODE)
+  if(path_w)
+    result = _wstati64(path_w, buffer);
+  else
+#endif /* _UNICODE */
+    result = _stati64(path, buffer);
+#endif /* USE_WIN32_SMALL_FILES */
+
+#ifdef _UNICODE
+  free(path_w);
+#endif
+
+  return result;
+}
+
+int curlx_win32_access(const char *path, int mode)
+{
+    int result = -1;
+#ifdef _UNICODE
+    wchar_t *path_w = curlx_convert_UTF8_to_wchar(path);
+#endif /* _UNICODE */
+
+#if defined(_UNICODE)
+    if(path_w)
+        result = _waccess(path_w, mode);
+    else
+#endif /* _UNICODE */
+        result = _access(path, mode);
+
+#ifdef _UNICODE
+    free(path_w);
+#endif
+
+    return result;
+}
+
+#endif /* USE_WIN32_LARGE_FILES || USE_WIN32_SMALL_FILES */
diff --git a/Utilities/cmcurl/lib/curl_multibyte.h b/Utilities/cmcurl/lib/curl_multibyte.h
index 615f5c0..5f8c05a 100644
--- a/Utilities/cmcurl/lib/curl_multibyte.h
+++ b/Utilities/cmcurl/lib/curl_multibyte.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -23,46 +23,46 @@
  ***************************************************************************/
 #include "curl_setup.h"
 
-#if defined(USE_WIN32_IDN) || ((defined(USE_WINDOWS_SSPI) || \
-                                defined(USE_WIN32_LDAP)) && defined(UNICODE))
+#if defined(WIN32)
 
  /*
   * MultiByte conversions using Windows kernel32 library.
   */
 
-wchar_t *Curl_convert_UTF8_to_wchar(const char *str_utf8);
-char *Curl_convert_wchar_to_UTF8(const wchar_t *str_w);
+wchar_t *curlx_convert_UTF8_to_wchar(const char *str_utf8);
+char *curlx_convert_wchar_to_UTF8(const wchar_t *str_w);
 
-#endif /* USE_WIN32_IDN || ((USE_WINDOWS_SSPI || USE_WIN32_LDAP) && UNICODE) */
-
-
-#if defined(USE_WIN32_IDN) || defined(USE_WINDOWS_SSPI) || \
-    defined(USE_WIN32_LDAP)
+#endif /* WIN32 */
 
 /*
- * Macros Curl_convert_UTF8_to_tchar(), Curl_convert_tchar_to_UTF8()
- * and Curl_unicodefree() main purpose is to minimize the number of
+ * Macros curlx_convert_UTF8_to_tchar(), curlx_convert_tchar_to_UTF8()
+ * and curlx_unicodefree() main purpose is to minimize the number of
  * preprocessor conditional directives needed by code using these
  * to differentiate UNICODE from non-UNICODE builds.
  *
- * When building with UNICODE defined, this two macros
- * Curl_convert_UTF8_to_tchar() and Curl_convert_tchar_to_UTF8()
+ * When building with UNICODE defined, these two macros
+ * curlx_convert_UTF8_to_tchar() and curlx_convert_tchar_to_UTF8()
  * return a pointer to a newly allocated memory area holding result.
  * When the result is no longer needed, allocated memory is intended
- * to be free'ed with Curl_unicodefree().
+ * to be free'ed with curlx_unicodefree().
  *
  * When building without UNICODE defined, this macros
- * Curl_convert_UTF8_to_tchar() and Curl_convert_tchar_to_UTF8()
- * return the pointer received as argument. Curl_unicodefree() does
+ * curlx_convert_UTF8_to_tchar() and curlx_convert_tchar_to_UTF8()
+ * return the pointer received as argument. curlx_unicodefree() does
  * no actual free'ing of this pointer it is simply set to NULL.
  */
 
-#ifdef UNICODE
+#if defined(UNICODE) && defined(WIN32)
 
-#define Curl_convert_UTF8_to_tchar(ptr) Curl_convert_UTF8_to_wchar((ptr))
-#define Curl_convert_tchar_to_UTF8(ptr) Curl_convert_wchar_to_UTF8((ptr))
-#define Curl_unicodefree(ptr) \
-  do {if((ptr)) {free((ptr)); (ptr) = NULL;}} WHILE_FALSE
+#define curlx_convert_UTF8_to_tchar(ptr) curlx_convert_UTF8_to_wchar((ptr))
+#define curlx_convert_tchar_to_UTF8(ptr) curlx_convert_wchar_to_UTF8((ptr))
+#define curlx_unicodefree(ptr)                          \
+  do {                                                  \
+    if(ptr) {                                           \
+      (free)(ptr);                                        \
+      (ptr) = NULL;                                     \
+    }                                                   \
+  } while(0)
 
 typedef union {
   unsigned short       *tchar_ptr;
@@ -73,10 +73,10 @@
 
 #else
 
-#define Curl_convert_UTF8_to_tchar(ptr) (ptr)
-#define Curl_convert_tchar_to_UTF8(ptr) (ptr)
-#define Curl_unicodefree(ptr) \
-  do {(ptr) = NULL;} WHILE_FALSE
+#define curlx_convert_UTF8_to_tchar(ptr) (ptr)
+#define curlx_convert_tchar_to_UTF8(ptr) (ptr)
+#define curlx_unicodefree(ptr) \
+  do {(ptr) = NULL;} while(0)
 
 typedef union {
   char                *tchar_ptr;
@@ -85,8 +85,6 @@
   const unsigned char *const_tbyte_ptr;
 } xcharp_u;
 
-#endif /* UNICODE */
-
-#endif /* USE_WIN32_IDN || USE_WINDOWS_SSPI || USE_WIN32_LDAP */
+#endif /* UNICODE && WIN32 */
 
 #endif /* HEADER_CURL_MULTIBYTE_H */
diff --git a/Utilities/cmcurl/lib/curl_ntlm_core.c b/Utilities/cmcurl/lib/curl_ntlm_core.c
index b6df38f..0eefb15 100644
--- a/Utilities/cmcurl/lib/curl_ntlm_core.c
+++ b/Utilities/cmcurl/lib/curl_ntlm_core.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -52,18 +52,18 @@
 
 #if !defined(USE_WINDOWS_SSPI) || defined(USE_WIN32_CRYPTO)
 
-#ifdef USE_OPENSSL
+#if defined(USE_OPENSSL) || defined(USE_WOLFSSL)
+
+#ifdef USE_WOLFSSL
+#include <wolfssl/options.h>
+#endif
 
 #  include <openssl/des.h>
-#  ifndef OPENSSL_NO_MD4
-#    include <openssl/md4.h>
-#  else
-#    include "curl_md4.h"
-#  endif
 #  include <openssl/md5.h>
 #  include <openssl/ssl.h>
 #  include <openssl/rand.h>
-#  if (OPENSSL_VERSION_NUMBER < 0x00907001L)
+#  if (defined(OPENSSL_VERSION_NUMBER) && \
+       (OPENSSL_VERSION_NUMBER < 0x00907001L)) && !defined(USE_WOLFSSL)
 #    define DES_key_schedule des_key_schedule
 #    define DES_cblock des_cblock
 #    define DES_set_odd_parity des_set_odd_parity
@@ -79,29 +79,21 @@
 #elif defined(USE_GNUTLS_NETTLE)
 
 #  include <nettle/des.h>
-#  include <nettle/md4.h>
 
 #elif defined(USE_GNUTLS)
 
 #  include <gcrypt.h>
-#  define MD5_DIGEST_LENGTH 16
-#  define MD4_DIGEST_LENGTH 16
 
 #elif defined(USE_NSS)
 
 #  include <nss.h>
 #  include <pk11pub.h>
 #  include <hasht.h>
-#  include "curl_md4.h"
-#  define MD5_DIGEST_LENGTH MD5_LENGTH
 
 #elif defined(USE_MBEDTLS)
 
 #  include <mbedtls/des.h>
-#  include <mbedtls/md4.h>
-#  if !defined(MBEDTLS_MD4_C)
-#    include "curl_md4.h"
-#  endif
+#  include "curl_md4.h"
 
 #elif defined(USE_SECTRANSP)
 
@@ -110,7 +102,6 @@
 
 #elif defined(USE_OS400CRYPTO)
 #  include "cipher.mih"  /* mih/cipher */
-#  include "curl_md4.h"
 #elif defined(USE_WIN32_CRYPTO)
 #  include <wincrypt.h>
 #else
@@ -126,12 +117,12 @@
 #include "warnless.h"
 #include "curl_endian.h"
 #include "curl_des.h"
+#include "curl_md4.h"
 /* The last 3 #include files should be in this order */
 #include "curl_printf.h"
 #include "curl_memory.h"
 #include "memdebug.h"
 
-#define NTLM_HMAC_MD5_LEN     (16)
 #define NTLMv2_BLOB_SIGNATURE "\x01\x01\x00\x00"
 #define NTLMv2_BLOB_LEN       (44 -16 + ntlm->target_info_len + 4)
 
@@ -150,7 +141,7 @@
   key[7] = (unsigned char) ((key_56[6] << 1) & 0xFF);
 }
 
-#ifdef USE_OPENSSL
+#if defined(USE_OPENSSL) || defined(USE_WOLFSSL)
 /*
  * Turns a 56 bit key into the 64 bit, odd parity key and sets the key.  The
  * key schedule ks is also set.
@@ -218,7 +209,6 @@
                         const unsigned char *key_56)
 {
   const CK_MECHANISM_TYPE mech = CKM_DES_ECB; /* DES cipher in ECB mode */
-  PK11SlotInfo *slot = NULL;
   char key[8];                                /* expanded 64 bit key */
   SECItem key_item;
   PK11SymKey *symkey = NULL;
@@ -228,7 +218,7 @@
   bool rv = FALSE;
 
   /* use internal slot for DES encryption (requires NSS to be initialized) */
-  slot = PK11_GetInternalKeySlot();
+  PK11SlotInfo *slot = PK11_GetInternalKeySlot();
   if(!slot)
     return FALSE;
 
@@ -355,7 +345,7 @@
 
   /* Acquire the crypto provider */
   if(!CryptAcquireContext(&hprov, NULL, NULL, PROV_RSA_FULL,
-                          CRYPT_VERIFYCONTEXT))
+                          CRYPT_VERIFYCONTEXT | CRYPT_SILENT))
     return FALSE;
 
   /* Setup the key blob structure */
@@ -400,7 +390,7 @@
                             const unsigned char *plaintext,
                             unsigned char *results)
 {
-#ifdef USE_OPENSSL
+#if defined(USE_OPENSSL) || defined(USE_WOLFSSL)
   DES_key_schedule ks;
 
   setup_des_key(keys, DESKEY(ks));
@@ -475,7 +465,7 @@
   {
     /* Create LanManager hashed password. */
 
-#ifdef USE_OPENSSL
+#if defined(USE_OPENSSL) || defined(USE_WOLFSSL)
     DES_key_schedule ks;
 
     setup_des_key(pw, DESKEY(ks));
@@ -553,7 +543,7 @@
   CURLcode result;
   if(len > SIZE_T_MAX/2) /* avoid integer overflow */
     return CURLE_OUT_OF_MEMORY;
-  pw = len ? malloc(len * 2) : strdup("");
+  pw = len ? malloc(len * 2) : (unsigned char *)strdup("");
   if(!pw)
     return CURLE_OUT_OF_MEMORY;
 
@@ -567,57 +557,10 @@
   if(result)
     return result;
 
-  {
-    /* Create NT hashed password. */
-#ifdef USE_OPENSSL
-#if !defined(OPENSSL_NO_MD4)
-    MD4_CTX MD4pw;
-    MD4_Init(&MD4pw);
-    MD4_Update(&MD4pw, pw, 2 * len);
-    MD4_Final(ntbuffer, &MD4pw);
-#else
-    Curl_md4it(ntbuffer, pw, 2 * len);
-#endif
-#elif defined(USE_GNUTLS_NETTLE)
-    struct md4_ctx MD4pw;
-    md4_init(&MD4pw);
-    md4_update(&MD4pw, (unsigned int)(2 * len), pw);
-    md4_digest(&MD4pw, MD4_DIGEST_SIZE, ntbuffer);
-#elif defined(USE_GNUTLS)
-    gcry_md_hd_t MD4pw;
-    gcry_md_open(&MD4pw, GCRY_MD_MD4, 0);
-    gcry_md_write(MD4pw, pw, 2 * len);
-    memcpy(ntbuffer, gcry_md_read(MD4pw, 0), MD4_DIGEST_LENGTH);
-    gcry_md_close(MD4pw);
-#elif defined(USE_NSS)
-    Curl_md4it(ntbuffer, pw, 2 * len);
-#elif defined(USE_MBEDTLS)
-#if defined(MBEDTLS_MD4_C)
-    mbedtls_md4(pw, 2 * len, ntbuffer);
-#else
-    Curl_md4it(ntbuffer, pw, 2 * len);
-#endif
-#elif defined(USE_SECTRANSP)
-    (void)CC_MD4(pw, (CC_LONG)(2 * len), ntbuffer);
-#elif defined(USE_OS400CRYPTO)
-    Curl_md4it(ntbuffer, pw, 2 * len);
-#elif defined(USE_WIN32_CRYPTO)
-    HCRYPTPROV hprov;
-    if(CryptAcquireContext(&hprov, NULL, NULL, PROV_RSA_FULL,
-                           CRYPT_VERIFYCONTEXT)) {
-      HCRYPTHASH hhash;
-      if(CryptCreateHash(hprov, CALG_MD4, 0, 0, &hhash)) {
-        DWORD length = 16;
-        CryptHashData(hhash, pw, (unsigned int)len * 2, 0);
-        CryptGetHashParam(hhash, HP_HASHVAL, ntbuffer, &length, 0);
-        CryptDestroyHash(hhash);
-      }
-      CryptReleaseContext(hprov, 0);
-    }
-#endif
+  /* Create NT hashed password. */
+  Curl_md4it(ntbuffer, pw, 2 * len);
 
-    memset(ntbuffer + 16, 0, 21 - 16);
-  }
+  memset(ntbuffer + 16, 0, 21 - 16);
 
   free(pw);
 
@@ -626,25 +569,6 @@
 
 #if defined(USE_NTLM_V2) && !defined(USE_WINDOWS_SSPI)
 
-/* This returns the HMAC MD5 digest */
-static CURLcode hmac_md5(const unsigned char *key, unsigned int keylen,
-                         const unsigned char *data, unsigned int datalen,
-                         unsigned char *output)
-{
-  HMAC_context *ctxt = Curl_HMAC_init(Curl_HMAC_MD5, key, keylen);
-
-  if(!ctxt)
-    return CURLE_OUT_OF_MEMORY;
-
-  /* Update the digest with the given challenge */
-  Curl_HMAC_update(ctxt, data, datalen);
-
-  /* Finalise the digest */
-  Curl_HMAC_final(ctxt, output);
-
-  return CURLE_OK;
-}
-
 /* This creates the NTLMv2 hash by using NTLM hash as the key and Unicode
  * (uppercase UserName + Domain) as the data
  */
@@ -674,8 +598,8 @@
   ascii_uppercase_to_unicode_le(identity, user, userlen);
   ascii_to_unicode_le(identity + (userlen << 1), domain, domlen);
 
-  result = hmac_md5(ntlmhash, 16, identity, curlx_uztoui(identity_len),
-                    ntlmv2hash);
+  result = Curl_hmacit(Curl_HMAC_MD5, ntlmhash, 16, identity, identity_len,
+                       ntlmv2hash);
   free(identity);
 
   return result;
@@ -721,7 +645,7 @@
 
   unsigned int len = 0;
   unsigned char *ptr = NULL;
-  unsigned char hmac_output[NTLM_HMAC_MD5_LEN];
+  unsigned char hmac_output[HMAC_MD5_LENGTH];
   curl_off_t tw;
 
   CURLcode result = CURLE_OK;
@@ -740,7 +664,7 @@
     tw = ((curl_off_t)time(NULL) + CURL_OFF_T_C(11644473600)) * 10000000;
 
   /* Calculate the response len */
-  len = NTLM_HMAC_MD5_LEN + NTLMv2_BLOB_LEN;
+  len = HMAC_MD5_LENGTH + NTLMv2_BLOB_LEN;
 
   /* Allocate the response */
   ptr = calloc(1, len);
@@ -748,7 +672,7 @@
     return CURLE_OUT_OF_MEMORY;
 
   /* Create the BLOB structure */
-  msnprintf((char *)ptr + NTLM_HMAC_MD5_LEN, NTLMv2_BLOB_LEN,
+  msnprintf((char *)ptr + HMAC_MD5_LENGTH, NTLMv2_BLOB_LEN,
             "%c%c%c%c"   /* NTLMv2_BLOB_SIGNATURE */
             "%c%c%c%c",  /* Reserved = 0 */
             NTLMv2_BLOB_SIGNATURE[0], NTLMv2_BLOB_SIGNATURE[1],
@@ -761,7 +685,7 @@
 
   /* Concatenate the Type 2 challenge with the BLOB and do HMAC MD5 */
   memcpy(ptr + 8, &ntlm->nonce[0], 8);
-  result = hmac_md5(ntlmv2hash, NTLM_HMAC_MD5_LEN, ptr + 8,
+  result = Curl_hmacit(Curl_HMAC_MD5, ntlmv2hash, HMAC_MD5_LENGTH, ptr + 8,
                     NTLMv2_BLOB_LEN + 8, hmac_output);
   if(result) {
     free(ptr);
@@ -769,7 +693,7 @@
   }
 
   /* Concatenate the HMAC MD5 output  with the BLOB */
-  memcpy(ptr, hmac_output, NTLM_HMAC_MD5_LEN);
+  memcpy(ptr, hmac_output, HMAC_MD5_LENGTH);
 
   /* Return the response */
   *ntresp = ptr;
@@ -804,7 +728,8 @@
   memcpy(&data[0], challenge_server, 8);
   memcpy(&data[8], challenge_client, 8);
 
-  result = hmac_md5(ntlmv2hash, 16, &data[0], 16, hmac_output);
+  result = Curl_hmacit(Curl_HMAC_MD5, ntlmv2hash, 16, &data[0], 16,
+                       hmac_output);
   if(result)
     return result;
 
diff --git a/Utilities/cmcurl/lib/curl_ntlm_core.h b/Utilities/cmcurl/lib/curl_ntlm_core.h
index 3b4b805..7895b64 100644
--- a/Utilities/cmcurl/lib/curl_ntlm_core.h
+++ b/Utilities/cmcurl/lib/curl_ntlm_core.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -29,6 +29,7 @@
 /* If NSS is the first available SSL backend (see order in curl_ntlm_core.c)
    then it must be initialized to be used by NTLM. */
 #if !defined(USE_OPENSSL) && \
+    !defined(USE_WOLFSSL) && \
     !defined(USE_GNUTLS_NETTLE) && \
     !defined(USE_GNUTLS) && \
     defined(USE_NSS)
@@ -37,7 +38,10 @@
 
 #if !defined(USE_WINDOWS_SSPI) || defined(USE_WIN32_CRYPTO)
 
-#ifdef USE_OPENSSL
+#if defined(USE_OPENSSL) || defined(USE_WOLFSSL)
+#ifdef USE_WOLFSSL
+#  include <wolfssl/options.h>
+#endif
 #  include <openssl/ssl.h>
 #endif
 
@@ -46,9 +50,9 @@
 #define USE_NTRESPONSES
 
 /* Define USE_NTLM2SESSION in order to make the type-3 message include the
-   NTLM2Session response message, requires USE_NTRESPONSES defined to 1 and a
-   Crypto engine that we have curl_ssl_md5sum() for. */
-#if defined(USE_NTRESPONSES) && !defined(USE_WIN32_CRYPTO)
+   NTLM2Session response message, requires USE_NTRESPONSES defined to 1 and
+   MD5 support */
+#if defined(USE_NTRESPONSES) && !defined(CURL_DISABLE_CRYPTO_AUTH)
 #define USE_NTLM2SESSION
 #endif
 
diff --git a/Utilities/cmcurl/lib/curl_ntlm_wb.c b/Utilities/cmcurl/lib/curl_ntlm_wb.c
index 80266e2..17a92f8 100644
--- a/Utilities/cmcurl/lib/curl_ntlm_wb.c
+++ b/Utilities/cmcurl/lib/curl_ntlm_wb.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -76,22 +76,22 @@
 #  define sclose_nolog(x)  close((x))
 #endif
 
-void Curl_http_auth_cleanup_ntlm_wb(struct connectdata *conn)
+static void ntlm_wb_cleanup(struct ntlmdata *ntlm)
 {
-  if(conn->ntlm_auth_hlpr_socket != CURL_SOCKET_BAD) {
-    sclose(conn->ntlm_auth_hlpr_socket);
-    conn->ntlm_auth_hlpr_socket = CURL_SOCKET_BAD;
+  if(ntlm->ntlm_auth_hlpr_socket != CURL_SOCKET_BAD) {
+    sclose(ntlm->ntlm_auth_hlpr_socket);
+    ntlm->ntlm_auth_hlpr_socket = CURL_SOCKET_BAD;
   }
 
-  if(conn->ntlm_auth_hlpr_pid) {
+  if(ntlm->ntlm_auth_hlpr_pid) {
     int i;
     for(i = 0; i < 4; i++) {
-      pid_t ret = waitpid(conn->ntlm_auth_hlpr_pid, NULL, WNOHANG);
-      if(ret == conn->ntlm_auth_hlpr_pid || errno == ECHILD)
+      pid_t ret = waitpid(ntlm->ntlm_auth_hlpr_pid, NULL, WNOHANG);
+      if(ret == ntlm->ntlm_auth_hlpr_pid || errno == ECHILD)
         break;
       switch(i) {
       case 0:
-        kill(conn->ntlm_auth_hlpr_pid, SIGTERM);
+        kill(ntlm->ntlm_auth_hlpr_pid, SIGTERM);
         break;
       case 1:
         /* Give the process another moment to shut down cleanly before
@@ -99,22 +99,21 @@
         Curl_wait_ms(1);
         break;
       case 2:
-        kill(conn->ntlm_auth_hlpr_pid, SIGKILL);
+        kill(ntlm->ntlm_auth_hlpr_pid, SIGKILL);
         break;
       case 3:
         break;
       }
     }
-    conn->ntlm_auth_hlpr_pid = 0;
+    ntlm->ntlm_auth_hlpr_pid = 0;
   }
 
-  free(conn->challenge_header);
-  conn->challenge_header = NULL;
-  free(conn->response_header);
-  conn->response_header = NULL;
+  Curl_safefree(ntlm->challenge);
+  Curl_safefree(ntlm->response);
 }
 
-static CURLcode ntlm_wb_init(struct connectdata *conn, const char *userp)
+static CURLcode ntlm_wb_init(struct Curl_easy *data, struct ntlmdata *ntlm,
+                             const char *userp)
 {
   curl_socket_t sockfds[2];
   pid_t child_pid;
@@ -128,9 +127,13 @@
 #endif
   char buffer[STRERROR_LEN];
 
+#if defined(CURL_DISABLE_VERBOSE_STRINGS)
+  (void) data;
+#endif
+
   /* Return if communication with ntlm_auth already set up */
-  if(conn->ntlm_auth_hlpr_socket != CURL_SOCKET_BAD ||
-     conn->ntlm_auth_hlpr_pid)
+  if(ntlm->ntlm_auth_hlpr_socket != CURL_SOCKET_BAD ||
+     ntlm->ntlm_auth_hlpr_pid)
     return CURLE_OK;
 
   username = userp;
@@ -181,13 +184,13 @@
     ntlm_auth = NTLM_WB_FILE;
 
   if(access(ntlm_auth, X_OK) != 0) {
-    failf(conn->data, "Could not access ntlm_auth: %s errno %d: %s",
+    failf(data, "Could not access ntlm_auth: %s errno %d: %s",
           ntlm_auth, errno, Curl_strerror(errno, buffer, sizeof(buffer)));
     goto done;
   }
 
-  if(socketpair(AF_UNIX, SOCK_STREAM, 0, sockfds)) {
-    failf(conn->data, "Could not open socket pair. errno %d: %s",
+  if(Curl_socketpair(AF_UNIX, SOCK_STREAM, 0, sockfds)) {
+    failf(data, "Could not open socket pair. errno %d: %s",
           errno, Curl_strerror(errno, buffer, sizeof(buffer)));
     goto done;
   }
@@ -196,7 +199,7 @@
   if(child_pid == -1) {
     sclose(sockfds[0]);
     sclose(sockfds[1]);
-    failf(conn->data, "Could not fork. errno %d: %s",
+    failf(data, "Could not fork. errno %d: %s",
           errno, Curl_strerror(errno, buffer, sizeof(buffer)));
     goto done;
   }
@@ -208,13 +211,13 @@
     /* Don't use sclose in the child since it fools the socket leak detector */
     sclose_nolog(sockfds[0]);
     if(dup2(sockfds[1], STDIN_FILENO) == -1) {
-      failf(conn->data, "Could not redirect child stdin. errno %d: %s",
+      failf(data, "Could not redirect child stdin. errno %d: %s",
             errno, Curl_strerror(errno, buffer, sizeof(buffer)));
       exit(1);
     }
 
     if(dup2(sockfds[1], STDOUT_FILENO) == -1) {
-      failf(conn->data, "Could not redirect child stdout. errno %d: %s",
+      failf(data, "Could not redirect child stdout. errno %d: %s",
             errno, Curl_strerror(errno, buffer, sizeof(buffer)));
       exit(1);
     }
@@ -234,14 +237,14 @@
             NULL);
 
     sclose_nolog(sockfds[1]);
-    failf(conn->data, "Could not execl(). errno %d: %s",
+    failf(data, "Could not execl(). errno %d: %s",
           errno, Curl_strerror(errno, buffer, sizeof(buffer)));
     exit(1);
   }
 
   sclose(sockfds[1]);
-  conn->ntlm_auth_hlpr_socket = sockfds[0];
-  conn->ntlm_auth_hlpr_pid = child_pid;
+  ntlm->ntlm_auth_hlpr_socket = sockfds[0];
+  ntlm->ntlm_auth_hlpr_pid = child_pid;
   free(domain);
   free(ntlm_auth_alloc);
   return CURLE_OK;
@@ -255,17 +258,17 @@
 /* if larger than this, something is seriously wrong */
 #define MAX_NTLM_WB_RESPONSE 100000
 
-static CURLcode ntlm_wb_response(struct connectdata *conn,
+static CURLcode ntlm_wb_response(struct Curl_easy *data, struct ntlmdata *ntlm,
                                  const char *input, curlntlm state)
 {
-  char *buf = malloc(NTLM_BUFSIZE);
   size_t len_in = strlen(input), len_out = 0;
-
-  if(!buf)
-    return CURLE_OUT_OF_MEMORY;
+  struct dynbuf b;
+  char *ptr = NULL;
+  unsigned char *buf = (unsigned char *)data->state.buffer;
+  Curl_dyn_init(&b, MAX_NTLM_WB_RESPONSE);
 
   while(len_in > 0) {
-    ssize_t written = swrite(conn->ntlm_auth_hlpr_socket, input, len_in);
+    ssize_t written = swrite(ntlm->ntlm_auth_hlpr_socket, input, len_in);
     if(written == -1) {
       /* Interrupted by a signal, retry it */
       if(errno == EINTR)
@@ -278,10 +281,8 @@
   }
   /* Read one line */
   while(1) {
-    ssize_t size;
-    char *newbuf;
-
-    size = sread(conn->ntlm_auth_hlpr_socket, buf + len_out, NTLM_BUFSIZE);
+    ssize_t size =
+      sread(ntlm->ntlm_auth_hlpr_socket, buf, data->set.buffer_size);
     if(size == -1) {
       if(errno == EINTR)
         continue;
@@ -290,48 +291,41 @@
     else if(size == 0)
       goto done;
 
-    len_out += size;
-    if(buf[len_out - 1] == '\n') {
-      buf[len_out - 1] = '\0';
-      break;
+    if(Curl_dyn_addn(&b, buf, size))
+      goto done;
+
+    len_out = Curl_dyn_len(&b);
+    ptr = Curl_dyn_ptr(&b);
+    if(len_out && ptr[len_out - 1] == '\n') {
+      ptr[len_out - 1] = '\0';
+      break; /* done! */
     }
-
-    if(len_out > MAX_NTLM_WB_RESPONSE) {
-      failf(conn->data, "too large ntlm_wb response!");
-      free(buf);
-      return CURLE_OUT_OF_MEMORY;
-    }
-
-    newbuf = Curl_saferealloc(buf, len_out + NTLM_BUFSIZE);
-    if(!newbuf)
-      return CURLE_OUT_OF_MEMORY;
-
-    buf = newbuf;
+    /* loop */
   }
 
   /* Samba/winbind installed but not configured */
   if(state == NTLMSTATE_TYPE1 &&
      len_out == 3 &&
-     buf[0] == 'P' && buf[1] == 'W')
+     ptr[0] == 'P' && ptr[1] == 'W')
     goto done;
   /* invalid response */
   if(len_out < 4)
     goto done;
   if(state == NTLMSTATE_TYPE1 &&
-     (buf[0]!='Y' || buf[1]!='R' || buf[2]!=' '))
+     (ptr[0]!='Y' || ptr[1]!='R' || ptr[2]!=' '))
     goto done;
   if(state == NTLMSTATE_TYPE2 &&
-     (buf[0]!='K' || buf[1]!='K' || buf[2]!=' ') &&
-     (buf[0]!='A' || buf[1]!='F' || buf[2]!=' '))
+     (ptr[0]!='K' || ptr[1]!='K' || ptr[2]!=' ') &&
+     (ptr[0]!='A' || ptr[1]!='F' || ptr[2]!=' '))
     goto done;
 
-  conn->response_header = aprintf("NTLM %.*s", len_out - 4, buf + 3);
-  free(buf);
-  if(!conn->response_header)
+  ntlm->response = strdup(ptr + 3);
+  Curl_dyn_free(&b);
+  if(!ntlm->response)
     return CURLE_OUT_OF_MEMORY;
   return CURLE_OK;
 done:
-  free(buf);
+  Curl_dyn_free(&b);
   return CURLE_REMOTE_ACCESS_DENIED;
 }
 
@@ -339,6 +333,7 @@
                             bool proxy,
                             const char *header)
 {
+  struct ntlmdata *ntlm = proxy ? &conn->proxyntlm : &conn->ntlm;
   curlntlm *state = proxy ? &conn->proxy_ntlm_state : &conn->http_ntlm_state;
 
   if(!checkprefix("NTLM", header))
@@ -349,8 +344,8 @@
     header++;
 
   if(*header) {
-    conn->challenge_header = strdup(header);
-    if(!conn->challenge_header)
+    ntlm->challenge = strdup(header);
+    if(!ntlm->challenge)
       return CURLE_OUT_OF_MEMORY;
 
     *state = NTLMSTATE_TYPE2; /* We got a type-2 message */
@@ -381,32 +376,38 @@
  * This is for creating ntlm header output by delegating challenge/response
  * to Samba's winbind daemon helper ntlm_auth.
  */
-CURLcode Curl_output_ntlm_wb(struct connectdata *conn,
-                              bool proxy)
+CURLcode Curl_output_ntlm_wb(struct connectdata *conn, bool proxy)
 {
   /* point to the address of the pointer that holds the string to send to the
      server, which is for a plain host or for a HTTP proxy */
   char **allocuserpwd;
   /* point to the name and password for this */
   const char *userp;
+  struct ntlmdata *ntlm;
   curlntlm *state;
   struct auth *authp;
+  struct Curl_easy *data = conn->data;
 
   CURLcode res = CURLE_OK;
-  char *input;
 
   DEBUGASSERT(conn);
   DEBUGASSERT(conn->data);
 
   if(proxy) {
-    allocuserpwd = &conn->allocptr.proxyuserpwd;
+#ifndef CURL_DISABLE_PROXY
+    allocuserpwd = &data->state.aptr.proxyuserpwd;
     userp = conn->http_proxy.user;
+    ntlm = &conn->proxyntlm;
     state = &conn->proxy_ntlm_state;
     authp = &conn->data->state.authproxy;
+#else
+    return CURLE_NOT_BUILT_IN;
+#endif
   }
   else {
-    allocuserpwd = &conn->allocptr.userpwd;
+    allocuserpwd = &data->state.aptr.userpwd;
     userp = conn->user;
+    ntlm = &conn->ntlm;
     state = &conn->http_ntlm_state;
     authp = &conn->data->state.authhost;
   }
@@ -432,38 +433,36 @@
      * request handling process.
      */
     /* Create communication with ntlm_auth */
-    res = ntlm_wb_init(conn, userp);
+    res = ntlm_wb_init(conn->data, ntlm, userp);
     if(res)
       return res;
-    res = ntlm_wb_response(conn, "YR\n", *state);
+    res = ntlm_wb_response(conn->data, ntlm, "YR\n", *state);
     if(res)
       return res;
 
     free(*allocuserpwd);
-    *allocuserpwd = aprintf("%sAuthorization: %s\r\n",
+    *allocuserpwd = aprintf("%sAuthorization: NTLM %s\r\n",
                             proxy ? "Proxy-" : "",
-                            conn->response_header);
+                            ntlm->response);
     DEBUG_OUT(fprintf(stderr, "**** Header %s\n ", *allocuserpwd));
-    free(conn->response_header);
+    Curl_safefree(ntlm->response);
     if(!*allocuserpwd)
       return CURLE_OUT_OF_MEMORY;
-    conn->response_header = NULL;
     break;
 
-  case NTLMSTATE_TYPE2:
-    input = aprintf("TT %s\n", conn->challenge_header);
+  case NTLMSTATE_TYPE2: {
+    char *input = aprintf("TT %s\n", ntlm->challenge);
     if(!input)
       return CURLE_OUT_OF_MEMORY;
-    res = ntlm_wb_response(conn, input, *state);
+    res = ntlm_wb_response(conn->data, ntlm, input, *state);
     free(input);
-    input = NULL;
     if(res)
       return res;
 
     free(*allocuserpwd);
-    *allocuserpwd = aprintf("%sAuthorization: %s\r\n",
+    *allocuserpwd = aprintf("%sAuthorization: NTLM %s\r\n",
                             proxy ? "Proxy-" : "",
-                            conn->response_header);
+                            ntlm->response);
     DEBUG_OUT(fprintf(stderr, "**** %s\n ", *allocuserpwd));
     *state = NTLMSTATE_TYPE3; /* we sent a type-3 */
     authp->done = TRUE;
@@ -471,7 +470,7 @@
     if(!*allocuserpwd)
       return CURLE_OUT_OF_MEMORY;
     break;
-
+  }
   case NTLMSTATE_TYPE3:
     /* connection is already authenticated,
      * don't send a header in future requests */
@@ -486,4 +485,10 @@
   return CURLE_OK;
 }
 
+void Curl_http_auth_cleanup_ntlm_wb(struct connectdata *conn)
+{
+  ntlm_wb_cleanup(&conn->ntlm);
+  ntlm_wb_cleanup(&conn->proxyntlm);
+}
+
 #endif /* !CURL_DISABLE_HTTP && USE_NTLM && NTLM_WB_ENABLED */
diff --git a/Utilities/cmcurl/lib/curl_path.c b/Utilities/cmcurl/lib/curl_path.c
index 85dddce..fbd98cb 100644
--- a/Utilities/cmcurl/lib/curl_path.c
+++ b/Utilities/cmcurl/lib/curl_path.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -42,7 +42,7 @@
   size_t working_path_len;
   CURLcode result =
     Curl_urldecode(data, data->state.up.path, 0, &working_path,
-                   &working_path_len, FALSE);
+                   &working_path_len, REJECT_ZERO);
   if(result)
     return result;
 
@@ -55,7 +55,7 @@
     }
     if((working_path_len > 3) && (!memcmp(working_path, "/~/", 3)))
       /* It is referenced to the home directory, so strip the leading '/~/' */
-      memcpy(real_path, working_path + 3, 4 + working_path_len-3);
+      memcpy(real_path, working_path + 3, working_path_len - 2);
     else
       memcpy(real_path, working_path, 1 + working_path_len);
   }
diff --git a/Utilities/cmcurl/lib/curl_rtmp.c b/Utilities/cmcurl/lib/curl_rtmp.c
index 16b1de1..df8f2b1 100644
--- a/Utilities/cmcurl/lib/curl_rtmp.c
+++ b/Utilities/cmcurl/lib/curl_rtmp.c
@@ -199,13 +199,13 @@
     RTMP_Free(r);
     return CURLE_URL_MALFORMAT;
   }
-  conn->proto.generic = r;
+  conn->proto.rtmp = r;
   return CURLE_OK;
 }
 
 static CURLcode rtmp_connect(struct connectdata *conn, bool *done)
 {
-  RTMP *r = conn->proto.generic;
+  RTMP *r = conn->proto.rtmp;
   SET_RCVTIMEO(tv, 10);
 
   r->m_sb.sb_socket = (int)conn->sock[FIRSTSOCKET];
@@ -240,7 +240,7 @@
 static CURLcode rtmp_do(struct connectdata *conn, bool *done)
 {
   struct Curl_easy *data = conn->data;
-  RTMP *r = conn->proto.generic;
+  RTMP *r = conn->proto.rtmp;
 
   if(!RTMP_ConnectStream(r, 0))
     return CURLE_FAILED_INIT;
@@ -268,10 +268,10 @@
 static CURLcode rtmp_disconnect(struct connectdata *conn,
                                 bool dead_connection)
 {
-  RTMP *r = conn->proto.generic;
+  RTMP *r = conn->proto.rtmp;
   (void)dead_connection;
   if(r) {
-    conn->proto.generic = NULL;
+    conn->proto.rtmp = NULL;
     RTMP_Close(r);
     RTMP_Free(r);
   }
@@ -281,7 +281,7 @@
 static ssize_t rtmp_recv(struct connectdata *conn, int sockindex, char *buf,
                          size_t len, CURLcode *err)
 {
-  RTMP *r = conn->proto.generic;
+  RTMP *r = conn->proto.rtmp;
   ssize_t nread;
 
   (void)sockindex; /* unused */
@@ -302,7 +302,7 @@
 static ssize_t rtmp_send(struct connectdata *conn, int sockindex,
                          const void *buf, size_t len, CURLcode *err)
 {
-  RTMP *r = conn->proto.generic;
+  RTMP *r = conn->proto.rtmp;
   ssize_t num;
 
   (void)sockindex; /* unused */
diff --git a/Utilities/cmcurl/lib/curl_rtmp.h b/Utilities/cmcurl/lib/curl_rtmp.h
index 3306e22..86a0138 100644
--- a/Utilities/cmcurl/lib/curl_rtmp.h
+++ b/Utilities/cmcurl/lib/curl_rtmp.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 2010, Howard Chu, <hyc@highlandsun.com>
+ * Copyright (C) 2010 - 2019, Howard Chu, <hyc@highlandsun.com>
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
diff --git a/Utilities/cmcurl/lib/curl_sasl.c b/Utilities/cmcurl/lib/curl_sasl.c
index 018e422..83fe896 100644
--- a/Utilities/cmcurl/lib/curl_sasl.c
+++ b/Utilities/cmcurl/lib/curl_sasl.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 2012 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 2012 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -264,14 +264,20 @@
   size_t len = 0;
   saslstate state1 = SASL_STOP;
   saslstate state2 = SASL_FINAL;
+#ifndef CURL_DISABLE_PROXY
   const char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name :
     conn->host.name;
   const long int port = SSL_IS_PROXY() ? conn->port : conn->remote_port;
+#else
+  const char * const hostname = conn->host.name;
+  const long int port = conn->remote_port;
+#endif
 #if defined(USE_KERBEROS5) || defined(USE_NTLM)
   const char *service = data->set.str[STRING_SERVICE_NAME] ?
     data->set.str[STRING_SERVICE_NAME] :
     sasl->params->service;
 #endif
+  const char *oauth_bearer = data->set.str[STRING_BEARER];
 
   sasl->force_ir = force_ir;    /* Latch for future use */
   sasl->authused = 0;           /* No mechanism used yet */
@@ -341,7 +347,7 @@
       }
     else
 #endif
-    if((enabledmechs & SASL_MECH_OAUTHBEARER) && conn->oauth_bearer) {
+    if((enabledmechs & SASL_MECH_OAUTHBEARER) && oauth_bearer) {
       mech = SASL_MECH_STRING_OAUTHBEARER;
       state1 = SASL_OAUTH2;
       state2 = SASL_OAUTH2_RESP;
@@ -351,17 +357,17 @@
         result = Curl_auth_create_oauth_bearer_message(data, conn->user,
                                                        hostname,
                                                        port,
-                                                       conn->oauth_bearer,
+                                                       oauth_bearer,
                                                        &resp, &len);
     }
-    else if((enabledmechs & SASL_MECH_XOAUTH2) && conn->oauth_bearer) {
+    else if((enabledmechs & SASL_MECH_XOAUTH2) && oauth_bearer) {
       mech = SASL_MECH_STRING_XOAUTH2;
       state1 = SASL_OAUTH2;
       sasl->authused = SASL_MECH_XOAUTH2;
 
       if(force_ir || data->set.sasl_ir)
         result = Curl_auth_create_xoauth_bearer_message(data, conn->user,
-                                                        conn->oauth_bearer,
+                                                        oauth_bearer,
                                                         &resp, &len);
     }
     else if(enabledmechs & SASL_MECH_PLAIN) {
@@ -370,8 +376,9 @@
       sasl->authused = SASL_MECH_PLAIN;
 
       if(force_ir || data->set.sasl_ir)
-        result = Curl_auth_create_plain_message(data, NULL, conn->user,
-                                                conn->passwd, &resp, &len);
+        result = Curl_auth_create_plain_message(data, conn->sasl_authzid,
+                                                conn->user, conn->passwd,
+                                                &resp, &len);
     }
     else if(enabledmechs & SASL_MECH_LOGIN) {
       mech = SASL_MECH_STRING_LOGIN;
@@ -415,21 +422,27 @@
   struct Curl_easy *data = conn->data;
   saslstate newstate = SASL_FINAL;
   char *resp = NULL;
+#ifndef CURL_DISABLE_PROXY
   const char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name :
     conn->host.name;
   const long int port = SSL_IS_PROXY() ? conn->port : conn->remote_port;
+#else
+  const char * const hostname = conn->host.name;
+  const long int port = conn->remote_port;
+#endif
 #if !defined(CURL_DISABLE_CRYPTO_AUTH)
   char *chlg = NULL;
   size_t chlglen = 0;
 #endif
-#if !defined(CURL_DISABLE_CRYPTO_AUTH) || defined(USE_KERBEROS5) || \
-    defined(USE_NTLM)
+#if !defined(CURL_DISABLE_CRYPTO_AUTH) || defined(USE_KERBEROS5) ||     \
+  defined(USE_NTLM)
   const char *service = data->set.str[STRING_SERVICE_NAME] ?
-                        data->set.str[STRING_SERVICE_NAME] :
-                        sasl->params->service;
+    data->set.str[STRING_SERVICE_NAME] :
+    sasl->params->service;
   char *serverdata;
 #endif
   size_t len = 0;
+  const char *oauth_bearer = data->set.str[STRING_BEARER];
 
   *progress = SASL_INPROGRESS;
 
@@ -453,8 +466,9 @@
     *progress = SASL_DONE;
     return result;
   case SASL_PLAIN:
-    result = Curl_auth_create_plain_message(data, NULL, conn->user,
-                                            conn->passwd, &resp, &len);
+    result = Curl_auth_create_plain_message(data, conn->sasl_authzid,
+                                            conn->user, conn->passwd,
+                                            &resp, &len);
     break;
   case SASL_LOGIN:
     result = Curl_auth_create_login_message(data, conn->user, &resp, &len);
@@ -556,7 +570,7 @@
       result = Curl_auth_create_oauth_bearer_message(data, conn->user,
                                                      hostname,
                                                      port,
-                                                     conn->oauth_bearer,
+                                                     oauth_bearer,
                                                      &resp, &len);
 
       /* Failures maybe sent by the server as continuations for OAUTHBEARER */
@@ -564,7 +578,7 @@
     }
     else
       result = Curl_auth_create_xoauth_bearer_message(data, conn->user,
-                                                      conn->oauth_bearer,
+                                                      oauth_bearer,
                                                       &resp, &len);
     break;
 
diff --git a/Utilities/cmcurl/lib/curl_setup.h b/Utilities/cmcurl/lib/curl_setup.h
index efba5dd..dadfff9 100644
--- a/Utilities/cmcurl/lib/curl_setup.h
+++ b/Utilities/cmcurl/lib/curl_setup.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -27,6 +27,14 @@
 #endif
 
 /*
+ * Disable Visual Studio warnings:
+ * 4127 "conditional expression is constant"
+ */
+#ifdef _MSC_VER
+#pragma warning(disable:4127)
+#endif
+
+/*
  * Define WIN32 when build target is Win32 API
  */
 
@@ -96,6 +104,10 @@
 #  include "config-vxworks.h"
 #endif
 
+#ifdef __PLAN9__
+#  include "config-plan9.h"
+#endif
+
 #endif /* HAVE_CONFIG_H */
 
 #if defined(_MSC_VER)
@@ -223,6 +235,14 @@
 #endif
 
 /*
+ * Windows setup file includes some system headers.
+ */
+
+#ifdef HAVE_WINDOWS_H
+#  include "setup-win32.h"
+#endif
+
+/*
  * Use getaddrinfo to resolve the IPv4 address literal. If the current network
  * interface doesn't support IPv4, but supports IPv6, NAT64, and DNS64,
  * performing this task will result in a synthesized IPv6 address.
@@ -231,58 +251,6 @@
 #define USE_RESOLVE_ON_IPS 1
 #endif
 
-/*
- * Include header files for windows builds before redefining anything.
- * Use this preprocessor block only to include or exclude windows.h,
- * winsock2.h, ws2tcpip.h or winsock.h. Any other windows thing belongs
- * to any other further and independent block.  Under Cygwin things work
- * just as under linux (e.g. <sys/socket.h>) and the winsock headers should
- * never be included when __CYGWIN__ is defined.  configure script takes
- * care of this, not defining HAVE_WINDOWS_H, HAVE_WINSOCK_H, HAVE_WINSOCK2_H,
- * neither HAVE_WS2TCPIP_H when __CYGWIN__ is defined.
- */
-
-#ifdef HAVE_WINDOWS_H
-#  if defined(UNICODE) && !defined(_UNICODE)
-#    define _UNICODE
-#  endif
-#  if defined(_UNICODE) && !defined(UNICODE)
-#    define UNICODE
-#  endif
-#  include <winerror.h>
-#  include <windows.h>
-#  ifdef HAVE_WINSOCK2_H
-#    include <winsock2.h>
-#    ifdef HAVE_WS2TCPIP_H
-#      include <ws2tcpip.h>
-#    endif
-#  else
-#    ifdef HAVE_WINSOCK_H
-#      include <winsock.h>
-#    endif
-#  endif
-#  include <tchar.h>
-#  ifdef UNICODE
-     typedef wchar_t *(*curl_wcsdup_callback)(const wchar_t *str);
-#  endif
-#endif
-
-/*
- * Define USE_WINSOCK to 2 if we have and use WINSOCK2 API, else
- * define USE_WINSOCK to 1 if we have and use WINSOCK  API, else
- * undefine USE_WINSOCK.
- */
-
-#undef USE_WINSOCK
-
-#ifdef HAVE_WINSOCK2_H
-#  define USE_WINSOCK 2
-#else
-#  ifdef HAVE_WINSOCK_H
-#    define USE_WINSOCK 1
-#  endif
-#endif
-
 #ifdef USE_LWIPSOCK
 #  include <lwip/init.h>
 #  include <lwip/sockets.h>
@@ -378,9 +346,14 @@
 #  undef  fstat
 #  define fstat(fdes,stp)            _fstati64(fdes, stp)
 #  undef  stat
-#  define stat(fname,stp)            _stati64(fname, stp)
+#  define stat(fname,stp)            curlx_win32_stat(fname, stp)
 #  define struct_stat                struct _stati64
 #  define LSEEK_ERROR                (__int64)-1
+#  define fopen(fname,mode)          curlx_win32_fopen(fname, mode)
+#  define access(fname,mode)         curlx_win32_access(fname, mode)
+   int curlx_win32_stat(const char *path, struct_stat *buffer);
+   FILE *curlx_win32_fopen(const char *filename, const char *mode);
+   int curlx_win32_access(const char *path, int mode);
 #endif
 
 /*
@@ -395,8 +368,13 @@
 #    undef  lseek
 #    define lseek(fdes,offset,whence)  _lseek(fdes, (long)offset, whence)
 #    define fstat(fdes,stp)            _fstat(fdes, stp)
-#    define stat(fname,stp)            _stat(fname, stp)
+#    define stat(fname,stp)            curlx_win32_stat(fname, stp)
 #    define struct_stat                struct _stat
+#    define fopen(fname,mode)          curlx_win32_fopen(fname, mode)
+#    define access(fname,mode)         curlx_win32_access(fname, mode)
+     int curlx_win32_stat(const char *path, struct_stat *buffer);
+     FILE *curlx_win32_fopen(const char *filename, const char *mode);
+     int curlx_win32_access(const char *path, int mode);
 #  endif
 #  define LSEEK_ERROR                (long)-1
 #endif
@@ -497,7 +475,6 @@
 #ifdef WIN32
 
 #  define DIR_CHAR      "\\"
-#  define DOT_CHAR      "_"
 
 #else /* WIN32 */
 
@@ -523,14 +500,6 @@
 #  endif
 
 #  define DIR_CHAR      "/"
-#  ifndef DOT_CHAR
-#    define DOT_CHAR      "."
-#  endif
-
-#  ifdef MSDOS
-#    undef DOT_CHAR
-#    define DOT_CHAR      "_"
-#  endif
 
 #  ifndef fileno /* sunos 4 have this as a macro! */
      int fileno(FILE *stream);
@@ -583,6 +552,12 @@
  * Mutually exclusive CURLRES_* definitions.
  */
 
+#if defined(ENABLE_IPV6) && defined(HAVE_GETADDRINFO)
+#  define CURLRES_IPV6
+#else
+#  define CURLRES_IPV4
+#endif
+
 #ifdef USE_ARES
 #  define CURLRES_ASYNCH
 #  define CURLRES_ARES
@@ -597,12 +572,6 @@
 #  define CURLRES_SYNCH
 #endif
 
-#ifdef ENABLE_IPV6
-#  define CURLRES_IPV6
-#else
-#  define CURLRES_IPV4
-#endif
-
 /* ---------------------------------------------------------------- */
 
 /*
@@ -662,9 +631,10 @@
 #define LIBIDN_REQUIRED_VERSION "0.4.1"
 
 #if defined(USE_GNUTLS) || defined(USE_OPENSSL) || defined(USE_NSS) || \
-    defined(USE_POLARSSL) || defined(USE_MBEDTLS) || \
-    defined(USE_CYASSL) || defined(USE_SCHANNEL) || \
-    defined(USE_SECTRANSP) || defined(USE_GSKIT) || defined(USE_MESALINK)
+    defined(USE_MBEDTLS) || \
+    defined(USE_WOLFSSL) || defined(USE_SCHANNEL) || \
+    defined(USE_SECTRANSP) || defined(USE_GSKIT) || defined(USE_MESALINK) || \
+    defined(USE_BEARSSL)
 #define USE_SSL    /* SSL support has been enabled */
 #endif
 
@@ -682,10 +652,11 @@
 
 /* Single point where USE_NTLM definition might be defined */
 #if !defined(CURL_DISABLE_NTLM) && !defined(CURL_DISABLE_CRYPTO_AUTH)
-#if defined(USE_OPENSSL) || defined(USE_WINDOWS_SSPI) || \
-    defined(USE_GNUTLS) || defined(USE_NSS) || defined(USE_SECTRANSP) || \
-    defined(USE_OS400CRYPTO) || defined(USE_WIN32_CRYPTO) || \
-    defined(USE_MBEDTLS)
+#if defined(USE_OPENSSL) || defined(USE_WINDOWS_SSPI) ||                \
+  defined(USE_GNUTLS) || defined(USE_NSS) || defined(USE_SECTRANSP) ||  \
+  defined(USE_OS400CRYPTO) || defined(USE_WIN32_CRYPTO) ||              \
+  defined(USE_MBEDTLS) ||                                               \
+  (defined(USE_WOLFSSL) && defined(HAVE_WOLFSSL_DES_SET_ODD_PARITY))
 
 #define USE_NTLM
 
@@ -733,7 +704,7 @@
  */
 
 #ifndef Curl_nop_stmt
-#  define Curl_nop_stmt do { } WHILE_FALSE
+#  define Curl_nop_stmt do { } while(0)
 #endif
 
 /*
@@ -842,4 +813,8 @@
 #define UNITTEST static
 #endif
 
+#if defined(USE_NGTCP2) || defined(USE_QUICHE)
+#define ENABLE_QUIC
+#endif
+
 #endif /* HEADER_CURL_SETUP_H */
diff --git a/Utilities/cmcurl/lib/curl_setup_once.h b/Utilities/cmcurl/lib/curl_setup_once.h
index 413ccea..e7c00de 100644
--- a/Utilities/cmcurl/lib/curl_setup_once.h
+++ b/Utilities/cmcurl/lib/curl_setup_once.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -330,27 +330,6 @@
 #include "curl_ctype.h"
 
 /*
- * Macro WHILE_FALSE may be used to build single-iteration do-while loops,
- * avoiding compiler warnings. Mostly intended for other macro definitions.
- */
-
-#define WHILE_FALSE  while(0)
-
-#if defined(_MSC_VER) && !defined(__POCC__)
-#  undef WHILE_FALSE
-#  if (_MSC_VER < 1500)
-#    define WHILE_FALSE  while(1, 0)
-#  else
-#    define WHILE_FALSE \
-__pragma(warning(push)) \
-__pragma(warning(disable:4127)) \
-while(0) \
-__pragma(warning(pop))
-#  endif
-#endif
-
-
-/*
  * Typedef to 'int' if sig_atomic_t is not an available 'typedefed' type.
  */
 
@@ -387,7 +366,7 @@
 #ifdef DEBUGBUILD
 #define DEBUGF(x) x
 #else
-#define DEBUGF(x) do { } WHILE_FALSE
+#define DEBUGF(x) do { } while(0)
 #endif
 
 
@@ -395,10 +374,11 @@
  * Macro used to include assertion code only in debug builds.
  */
 
+#undef DEBUGASSERT
 #if defined(DEBUGBUILD) && defined(HAVE_ASSERT_H)
 #define DEBUGASSERT(x) assert(x)
 #else
-#define DEBUGASSERT(x) do { } WHILE_FALSE
+#define DEBUGASSERT(x) do { } while(0)
 #endif
 
 
@@ -501,6 +481,8 @@
 
 #ifdef __VMS
 #define argv_item_t  __char_ptr32
+#elif defined(_UNICODE)
+#define argv_item_t wchar_t *
 #else
 #define argv_item_t  char *
 #endif
diff --git a/Utilities/cmcurl/lib/curl_sha256.h b/Utilities/cmcurl/lib/curl_sha256.h
index 6db4b04..35d286c 100644
--- a/Utilities/cmcurl/lib/curl_sha256.h
+++ b/Utilities/cmcurl/lib/curl_sha256.h
@@ -7,7 +7,8 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2010, Florin Petriuc, <petriuc.florin@gmail.com>
+ * Copyright (C) 2017, Florin Petriuc, <petriuc.florin@gmail.com>
+ * Copyright (C) 2018 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -24,8 +25,10 @@
 
 #ifndef CURL_DISABLE_CRYPTO_AUTH
 
-void Curl_sha256it(unsigned char *outbuffer,
-                const unsigned char *input);
+#define SHA256_DIGEST_LENGTH 32
+
+void Curl_sha256it(unsigned char *outbuffer, const unsigned char *input,
+                   const size_t len);
 
 #endif
 
diff --git a/Utilities/cmcurl/lib/curl_sspi.c b/Utilities/cmcurl/lib/curl_sspi.c
index 1d0de4e..83ece9a 100644
--- a/Utilities/cmcurl/lib/curl_sspi.c
+++ b/Utilities/cmcurl/lib/curl_sspi.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -151,7 +151,7 @@
   /* Initialize the identity */
   memset(identity, 0, sizeof(*identity));
 
-  useranddomain.tchar_ptr = Curl_convert_UTF8_to_tchar((char *)userp);
+  useranddomain.tchar_ptr = curlx_convert_UTF8_to_tchar((char *)userp);
   if(!useranddomain.tchar_ptr)
     return CURLE_OUT_OF_MEMORY;
 
@@ -173,7 +173,7 @@
   /* Setup the identity's user and length */
   dup_user.tchar_ptr = _tcsdup(user.tchar_ptr);
   if(!dup_user.tchar_ptr) {
-    Curl_unicodefree(useranddomain.tchar_ptr);
+    curlx_unicodefree(useranddomain.tchar_ptr);
     return CURLE_OUT_OF_MEMORY;
   }
   identity->User = dup_user.tbyte_ptr;
@@ -183,7 +183,7 @@
   /* Setup the identity's domain and length */
   dup_domain.tchar_ptr = malloc(sizeof(TCHAR) * (domlen + 1));
   if(!dup_domain.tchar_ptr) {
-    Curl_unicodefree(useranddomain.tchar_ptr);
+    curlx_unicodefree(useranddomain.tchar_ptr);
     return CURLE_OUT_OF_MEMORY;
   }
   _tcsncpy(dup_domain.tchar_ptr, domain.tchar_ptr, domlen);
@@ -192,22 +192,22 @@
   identity->DomainLength = curlx_uztoul(domlen);
   dup_domain.tchar_ptr = NULL;
 
-  Curl_unicodefree(useranddomain.tchar_ptr);
+  curlx_unicodefree(useranddomain.tchar_ptr);
 
   /* Setup the identity's password and length */
-  passwd.tchar_ptr = Curl_convert_UTF8_to_tchar((char *)passwdp);
+  passwd.tchar_ptr = curlx_convert_UTF8_to_tchar((char *)passwdp);
   if(!passwd.tchar_ptr)
     return CURLE_OUT_OF_MEMORY;
   dup_passwd.tchar_ptr = _tcsdup(passwd.tchar_ptr);
   if(!dup_passwd.tchar_ptr) {
-    Curl_unicodefree(passwd.tchar_ptr);
+    curlx_unicodefree(passwd.tchar_ptr);
     return CURLE_OUT_OF_MEMORY;
   }
   identity->Password = dup_passwd.tbyte_ptr;
   identity->PasswordLength = curlx_uztoul(_tcslen(dup_passwd.tchar_ptr));
   dup_passwd.tchar_ptr = NULL;
 
-  Curl_unicodefree(passwd.tchar_ptr);
+  curlx_unicodefree(passwd.tchar_ptr);
 
   /* Setup the identity's flags */
   identity->Flags = SECFLAG_WINNT_AUTH_IDENTITY;
diff --git a/Utilities/cmcurl/lib/curl_sspi.h b/Utilities/cmcurl/lib/curl_sspi.h
index 2bbf947..c09026e 100644
--- a/Utilities/cmcurl/lib/curl_sspi.h
+++ b/Utilities/cmcurl/lib/curl_sspi.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
diff --git a/Utilities/cmcurl/lib/curl_threads.c b/Utilities/cmcurl/lib/curl_threads.c
index 8e5937a..b5f10a2 100644
--- a/Utilities/cmcurl/lib/curl_threads.c
+++ b/Utilities/cmcurl/lib/curl_threads.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -48,7 +48,7 @@
 
 static void *curl_thread_create_thunk(void *arg)
 {
-  struct curl_actual_call * ac = arg;
+  struct curl_actual_call *ac = arg;
   unsigned int (*func)(void *) = ac->func;
   void *real_arg = ac->arg;
 
diff --git a/Utilities/cmcurl/lib/curl_threads.h b/Utilities/cmcurl/lib/curl_threads.h
index 2a93644..65d1a79 100644
--- a/Utilities/cmcurl/lib/curl_threads.h
+++ b/Utilities/cmcurl/lib/curl_threads.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
diff --git a/Utilities/cmcurl/lib/curlx.h b/Utilities/cmcurl/lib/curlx.h
index 3e9b516..a8bae14 100644
--- a/Utilities/cmcurl/lib/curlx.h
+++ b/Utilities/cmcurl/lib/curlx.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -53,6 +53,16 @@
   curlx_uztosi()
 */
 
+#include "curl_multibyte.h"
+/* "curl_multibyte.h" provides these functions and macros:
+
+  curlx_convert_UTF8_to_wchar()
+  curlx_convert_wchar_to_UTF8()
+  curlx_convert_UTF8_to_tchar()
+  curlx_convert_tchar_to_UTF8()
+  curlx_unicodefree()
+*/
+
 /* Now setup curlx_ * names for the functions that are to become curlx_ and
    be removed from a future libcurl official API:
    curlx_getenv
diff --git a/Utilities/cmcurl/lib/dict.c b/Utilities/cmcurl/lib/dict.c
index 208a233..f529b48 100644
--- a/Utilities/cmcurl/lib/dict.c
+++ b/Utilities/cmcurl/lib/dict.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -46,6 +46,8 @@
 
 #ifdef HAVE_SYS_SELECT_H
 #include <sys/select.h>
+#elif defined(HAVE_UNISTD_H)
+#include <unistd.h>
 #endif
 
 #include "urldata.h"
@@ -97,7 +99,8 @@
   char *dictp;
   size_t len;
 
-  CURLcode result = Curl_urldecode(data, inputbuff, 0, &newp, &len, FALSE);
+  CURLcode result = Curl_urldecode(data, inputbuff, 0, &newp, &len,
+                                   REJECT_NADA);
   if(!newp || result)
     return NULL;
 
diff --git a/Utilities/cmcurl/lib/dict.h b/Utilities/cmcurl/lib/dict.h
index 12c0f33..38a55ac 100644
--- a/Utilities/cmcurl/lib/dict.h
+++ b/Utilities/cmcurl/lib/dict.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2009, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
diff --git a/Utilities/cmcurl/lib/doh.c b/Utilities/cmcurl/lib/doh.c
index 6d1f330..ebb2c24 100644
--- a/Utilities/cmcurl/lib/doh.c
+++ b/Utilities/cmcurl/lib/doh.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 2018 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 2018 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -35,13 +35,13 @@
 #include "curl_base64.h"
 #include "connect.h"
 #include "strdup.h"
+#include "dynbuf.h"
 /* The last 3 #include files should be in this order */
 #include "curl_printf.h"
 #include "curl_memory.h"
 #include "memdebug.h"
 
 #define DNS_CLASS_IN 0x01
-#define DOH_MAX_RESPONSE_SIZE 3000 /* bytes */
 
 #ifndef CURL_DISABLE_VERBOSE_STRINGS
 static const char * const errors[]={
@@ -74,17 +74,50 @@
 #define UNITTEST static
 #endif
 
+/* @unittest 1655
+ */
 UNITTEST DOHcode doh_encode(const char *host,
                             DNStype dnstype,
                             unsigned char *dnsp, /* buffer */
                             size_t len,  /* buffer size */
                             size_t *olen) /* output length */
 {
-  size_t hostlen = strlen(host);
+  const size_t hostlen = strlen(host);
   unsigned char *orig = dnsp;
   const char *hostp = host;
 
-  if(len < (12 + hostlen + 4))
+  /* The expected output length is 16 bytes more than the length of
+   * the QNAME-encoding of the host name.
+   *
+   * A valid DNS name may not contain a zero-length label, except at
+   * the end.  For this reason, a name beginning with a dot, or
+   * containing a sequence of two or more consecutive dots, is invalid
+   * and cannot be encoded as a QNAME.
+   *
+   * If the host name ends with a trailing dot, the corresponding
+   * QNAME-encoding is one byte longer than the host name. If (as is
+   * also valid) the hostname is shortened by the omission of the
+   * trailing dot, then its QNAME-encoding will be two bytes longer
+   * than the host name.
+   *
+   * Each [ label, dot ] pair is encoded as [ length, label ],
+   * preserving overall length.  A final [ label ] without a dot is
+   * also encoded as [ length, label ], increasing overall length
+   * by one. The encoding is completed by appending a zero byte,
+   * representing the zero-length root label, again increasing
+   * the overall length by one.
+   */
+
+  size_t expected_len;
+  DEBUGASSERT(hostlen);
+  expected_len = 12 + 1 + hostlen + 4;
+  if(host[hostlen-1]!='.')
+    expected_len++;
+
+  if(expected_len > (256 + 16)) /* RFCs 1034, 1035 */
+    return DOH_DNS_NAME_TOO_LONG;
+
+  if(len < expected_len)
     return DOH_TOO_SMALL_BUFFER;
 
   *dnsp++ = 0; /* 16 bit id */
@@ -100,59 +133,55 @@
   *dnsp++ = '\0';
   *dnsp++ = '\0'; /* ARCOUNT */
 
-  /* store a QNAME */
-  do {
-    char *dot = strchr(hostp, '.');
+  /* encode each label and store it in the QNAME */
+  while(*hostp) {
     size_t labellen;
-    bool found = false;
-    if(dot) {
-      found = true;
+    char *dot = strchr(hostp, '.');
+    if(dot)
       labellen = dot - hostp;
-    }
     else
       labellen = strlen(hostp);
-    if(labellen > 63) {
-      /* too long label, error out */
+    if((labellen > 63) || (!labellen)) {
+      /* label is too long or too short, error out */
       *olen = 0;
       return DOH_DNS_BAD_LABEL;
     }
+    /* label is non-empty, process it */
     *dnsp++ = (unsigned char)labellen;
     memcpy(dnsp, hostp, labellen);
     dnsp += labellen;
-    hostp += labellen + 1;
-    if(!found) {
-      *dnsp++ = 0; /* terminating zero */
-      break;
-    }
-  } while(1);
+    hostp += labellen;
+    /* advance past dot, but only if there is one */
+    if(dot)
+      hostp++;
+  } /* next label */
 
-  *dnsp++ = '\0'; /* upper 8 bit TYPE */
-  *dnsp++ = (unsigned char)dnstype;
+  *dnsp++ = 0; /* append zero-length label for root */
+
+  /* There are assigned TYPE codes beyond 255: use range [1..65535]  */
+  *dnsp++ = (unsigned char)(255 & (dnstype>>8)); /* upper 8 bit TYPE */
+  *dnsp++ = (unsigned char)(255 & dnstype);      /* lower 8 bit TYPE */
+
   *dnsp++ = '\0'; /* upper 8 bit CLASS */
   *dnsp++ = DNS_CLASS_IN; /* IN - "the Internet" */
 
   *olen = dnsp - orig;
+
+  /* verify that our estimation of length is valid, since
+   * this has led to buffer overflows in this function */
+  DEBUGASSERT(*olen == expected_len);
   return DOH_OK;
 }
 
 static size_t
-doh_write_cb(void *contents, size_t size, size_t nmemb, void *userp)
+doh_write_cb(const void *contents, size_t size, size_t nmemb, void *userp)
 {
   size_t realsize = size * nmemb;
-  struct dohresponse *mem = (struct dohresponse *)userp;
+  struct dynbuf *mem = (struct dynbuf *)userp;
 
-  if((mem->size + realsize) > DOH_MAX_RESPONSE_SIZE)
-    /* suspiciously much for us */
+  if(Curl_dyn_addn(mem, contents, realsize))
     return 0;
 
-  mem->memory = Curl_saferealloc(mem->memory, mem->size + realsize);
-  if(!mem->memory)
-    /* out of memory! */
-    return 0;
-
-  memcpy(&(mem->memory[mem->size]), contents, realsize);
-  mem->size += realsize;
-
   return realsize;
 }
 
@@ -180,7 +209,7 @@
   result = curl_easy_setopt(doh, x, y);   \
   if(result)                              \
     goto error;                           \
-} WHILE_FALSE
+} while(0)
 
 static CURLcode dohprobe(struct Curl_easy *data,
                          struct dnsprobe *p, DNStype dnstype,
@@ -200,10 +229,7 @@
   }
 
   p->dnstype = dnstype;
-  p->serverdoh.memory = NULL;
-  /* the memory will be grown as needed by realloc in the doh_write_cb
-     function */
-  p->serverdoh.size = 0;
+  Curl_dyn_init(&p->serverdoh, DYN_DOH_RESPONSE);
 
   /* Note: this is code for sending the DoH request with GET but there's still
      no logic that actually enables this. We should either add that ability or
@@ -225,13 +251,16 @@
   }
 
   timeout_ms = Curl_timeleft(data, NULL, TRUE);
-
+  if(timeout_ms <= 0) {
+    result = CURLE_OPERATION_TIMEDOUT;
+    goto error;
+  }
   /* Curl_open() is the internal version of curl_easy_init() */
   result = Curl_open(&doh);
   if(!result) {
     /* pass in the struct pointer via a local variable to please coverity and
        the gcc typecheck helpers */
-    struct dohresponse *resp = &p->serverdoh;
+    struct dynbuf *resp = &p->serverdoh;
     ERROR_CHECK_SETOPT(CURLOPT_URL, url);
     ERROR_CHECK_SETOPT(CURLOPT_WRITEFUNCTION, doh_write_cb);
     ERROR_CHECK_SETOPT(CURLOPT_WRITEDATA, resp);
@@ -246,6 +275,9 @@
 #ifndef CURLDEBUG
     /* enforce HTTPS if not debug */
     ERROR_CHECK_SETOPT(CURLOPT_PROTOCOLS, CURLPROTO_HTTPS);
+#else
+    /* in debug mode, also allow http */
+    ERROR_CHECK_SETOPT(CURLOPT_PROTOCOLS, CURLPROTO_HTTP|CURLPROTO_HTTPS);
 #endif
     ERROR_CHECK_SETOPT(CURLOPT_TIMEOUT_MS, (long)timeout_ms);
     if(data->set.verbose)
@@ -259,38 +291,45 @@
       ERROR_CHECK_SETOPT(CURLOPT_SSL_FALSESTART, 1L);
     if(data->set.ssl.primary.verifyhost)
       ERROR_CHECK_SETOPT(CURLOPT_SSL_VERIFYHOST, 2L);
+#ifndef CURL_DISABLE_PROXY
     if(data->set.proxy_ssl.primary.verifyhost)
       ERROR_CHECK_SETOPT(CURLOPT_PROXY_SSL_VERIFYHOST, 2L);
-    if(data->set.ssl.primary.verifypeer)
-      ERROR_CHECK_SETOPT(CURLOPT_SSL_VERIFYPEER, 1L);
     if(data->set.proxy_ssl.primary.verifypeer)
       ERROR_CHECK_SETOPT(CURLOPT_PROXY_SSL_VERIFYPEER, 1L);
+    if(data->set.str[STRING_SSL_CAFILE_PROXY]) {
+      ERROR_CHECK_SETOPT(CURLOPT_PROXY_CAINFO,
+        data->set.str[STRING_SSL_CAFILE_PROXY]);
+    }
+    if(data->set.str[STRING_SSL_CRLFILE_PROXY]) {
+      ERROR_CHECK_SETOPT(CURLOPT_PROXY_CRLFILE,
+        data->set.str[STRING_SSL_CRLFILE_PROXY]);
+    }
+    if(data->set.proxy_ssl.no_revoke)
+      ERROR_CHECK_SETOPT(CURLOPT_PROXY_SSL_OPTIONS, CURLSSLOPT_NO_REVOKE);
+    else if(data->set.proxy_ssl.revoke_best_effort)
+      ERROR_CHECK_SETOPT(CURLOPT_PROXY_SSL_OPTIONS,
+                         CURLSSLOPT_REVOKE_BEST_EFFORT);
+    if(data->set.str[STRING_SSL_CAPATH_PROXY]) {
+      ERROR_CHECK_SETOPT(CURLOPT_PROXY_CAPATH,
+        data->set.str[STRING_SSL_CAPATH_PROXY]);
+    }
+#endif
+    if(data->set.ssl.primary.verifypeer)
+      ERROR_CHECK_SETOPT(CURLOPT_SSL_VERIFYPEER, 1L);
     if(data->set.ssl.primary.verifystatus)
       ERROR_CHECK_SETOPT(CURLOPT_SSL_VERIFYSTATUS, 1L);
     if(data->set.str[STRING_SSL_CAFILE_ORIG]) {
       ERROR_CHECK_SETOPT(CURLOPT_CAINFO,
         data->set.str[STRING_SSL_CAFILE_ORIG]);
     }
-    if(data->set.str[STRING_SSL_CAFILE_PROXY]) {
-      ERROR_CHECK_SETOPT(CURLOPT_PROXY_CAINFO,
-        data->set.str[STRING_SSL_CAFILE_PROXY]);
-    }
     if(data->set.str[STRING_SSL_CAPATH_ORIG]) {
       ERROR_CHECK_SETOPT(CURLOPT_CAPATH,
         data->set.str[STRING_SSL_CAPATH_ORIG]);
     }
-    if(data->set.str[STRING_SSL_CAPATH_PROXY]) {
-      ERROR_CHECK_SETOPT(CURLOPT_PROXY_CAPATH,
-        data->set.str[STRING_SSL_CAPATH_PROXY]);
-    }
     if(data->set.str[STRING_SSL_CRLFILE_ORIG]) {
       ERROR_CHECK_SETOPT(CURLOPT_CRLFILE,
         data->set.str[STRING_SSL_CRLFILE_ORIG]);
     }
-    if(data->set.str[STRING_SSL_CRLFILE_PROXY]) {
-      ERROR_CHECK_SETOPT(CURLOPT_PROXY_CRLFILE,
-        data->set.str[STRING_SSL_CRLFILE_PROXY]);
-    }
     if(data->set.ssl.certinfo)
       ERROR_CHECK_SETOPT(CURLOPT_CERTINFO, 1L);
     if(data->set.str[STRING_SSL_RANDOM_FILE]) {
@@ -303,8 +342,8 @@
     }
     if(data->set.ssl.no_revoke)
       ERROR_CHECK_SETOPT(CURLOPT_SSL_OPTIONS, CURLSSLOPT_NO_REVOKE);
-    if(data->set.proxy_ssl.no_revoke)
-      ERROR_CHECK_SETOPT(CURLOPT_PROXY_SSL_OPTIONS, CURLSSLOPT_NO_REVOKE);
+    else if(data->set.ssl.revoke_best_effort)
+      ERROR_CHECK_SETOPT(CURLOPT_SSL_OPTIONS, CURLSSLOPT_REVOKE_BEST_EFFORT);
     if(data->set.ssl.fsslctx)
       ERROR_CHECK_SETOPT(CURLOPT_SSL_CTX_FUNCTION, data->set.ssl.fsslctx);
     if(data->set.ssl.fsslctxp)
@@ -325,7 +364,7 @@
 
   error:
   free(nurl);
-  Curl_close(doh);
+  Curl_close(&doh);
   return result;
 }
 
@@ -334,13 +373,14 @@
  * 'Curl_addrinfo *' with the address information.
  */
 
-Curl_addrinfo *Curl_doh(struct connectdata *conn,
-                        const char *hostname,
-                        int port,
-                        int *waitp)
+struct Curl_addrinfo *Curl_doh(struct connectdata *conn,
+                               const char *hostname,
+                               int port,
+                               int *waitp)
 {
   struct Curl_easy *data = conn->data;
   CURLcode result = CURLE_OK;
+  int slot;
   *waitp = TRUE; /* this never returns synchronously */
   (void)conn;
   (void)hostname;
@@ -349,6 +389,7 @@
   /* start clean, consider allocating this struct on demand */
   memset(&data->req.doh, 0, sizeof(struct dohdata));
 
+  conn->bits.doh = TRUE;
   data->req.doh.host = hostname;
   data->req.doh.port = port;
   data->req.doh.headers =
@@ -359,8 +400,8 @@
 
   if(conn->ip_version != CURL_IPRESOLVE_V6) {
     /* create IPv4 DOH request */
-    result = dohprobe(data, &data->req.doh.probe[0], DNS_TYPE_A,
-                      hostname, data->set.str[STRING_DOH],
+    result = dohprobe(data, &data->req.doh.probe[DOH_PROBE_SLOT_IPADDR_V4],
+                      DNS_TYPE_A, hostname, data->set.str[STRING_DOH],
                       data->multi, data->req.doh.headers);
     if(result)
       goto error;
@@ -369,8 +410,8 @@
 
   if(conn->ip_version != CURL_IPRESOLVE_V4) {
     /* create IPv6 DOH request */
-    result = dohprobe(data, &data->req.doh.probe[1], DNS_TYPE_AAAA,
-                      hostname, data->set.str[STRING_DOH],
+    result = dohprobe(data, &data->req.doh.probe[DOH_PROBE_SLOT_IPADDR_V6],
+                      DNS_TYPE_AAAA, hostname, data->set.str[STRING_DOH],
                       data->multi, data->req.doh.headers);
     if(result)
       goto error;
@@ -381,14 +422,13 @@
   error:
   curl_slist_free_all(data->req.doh.headers);
   data->req.doh.headers = NULL;
-  curl_easy_cleanup(data->req.doh.probe[0].easy);
-  data->req.doh.probe[0].easy = NULL;
-  curl_easy_cleanup(data->req.doh.probe[1].easy);
-  data->req.doh.probe[1].easy = NULL;
+  for(slot = 0; slot < DOH_PROBE_SLOTS; slot++) {
+    Curl_close(&data->req.doh.probe[slot].easy);
+  }
   return NULL;
 }
 
-static DOHcode skipqname(unsigned char *doh, size_t dohlen,
+static DOHcode skipqname(const unsigned char *doh, size_t dohlen,
                          unsigned int *indexp)
 {
   unsigned char length;
@@ -412,18 +452,24 @@
   return DOH_OK;
 }
 
-static unsigned short get16bit(unsigned char *doh, int index)
+static unsigned short get16bit(const unsigned char *doh, int index)
 {
   return (unsigned short)((doh[index] << 8) | doh[index + 1]);
 }
 
-static unsigned int get32bit(unsigned char *doh, int index)
+static unsigned int get32bit(const unsigned char *doh, int index)
 {
-  return (doh[index] << 24) | (doh[index + 1] << 16) |
-    (doh[index + 2] << 8) | doh[index + 3];
+   /* make clang and gcc optimize this to bswap by incrementing
+      the pointer first. */
+   doh += index;
+
+   /* avoid undefined behaviour by casting to unsigned before shifting
+      24 bits, possibly into the sign bit. codegen is same, but
+      ub sanitizer won't be upset */
+  return ( (unsigned)doh[0] << 24) | (doh[1] << 16) |(doh[2] << 8) | doh[3];
 }
 
-static DOHcode store_a(unsigned char *doh, int index, struct dohentry *d)
+static DOHcode store_a(const unsigned char *doh, int index, struct dohentry *d)
 {
   /* silently ignore addresses over the limit */
   if(d->numaddr < DOH_MAX_ADDR) {
@@ -435,7 +481,9 @@
   return DOH_OK;
 }
 
-static DOHcode store_aaaa(unsigned char *doh, int index, struct dohentry *d)
+static DOHcode store_aaaa(const unsigned char *doh,
+                          int index,
+                          struct dohentry *d)
 {
   /* silently ignore addresses over the limit */
   if(d->numaddr < DOH_MAX_ADDR) {
@@ -447,38 +495,12 @@
   return DOH_OK;
 }
 
-static DOHcode cnameappend(struct cnamestore *c,
-                           unsigned char *src,
-                           size_t len)
-{
-  if(!c->alloc) {
-    c->allocsize = len + 1;
-    c->alloc = malloc(c->allocsize);
-    if(!c->alloc)
-      return DOH_OUT_OF_MEM;
-  }
-  else if(c->allocsize < (c->allocsize + len + 1)) {
-    char *ptr;
-    c->allocsize += len + 1;
-    ptr = realloc(c->alloc, c->allocsize);
-    if(!ptr) {
-      free(c->alloc);
-      return DOH_OUT_OF_MEM;
-    }
-    c->alloc = ptr;
-  }
-  memcpy(&c->alloc[c->len], src, len);
-  c->len += len;
-  c->alloc[c->len] = 0; /* keep it zero terminated */
-  return DOH_OK;
-}
-
-static DOHcode store_cname(unsigned char *doh,
+static DOHcode store_cname(const unsigned char *doh,
                            size_t dohlen,
                            unsigned int index,
                            struct dohentry *d)
 {
-  struct cnamestore *c;
+  struct dynbuf *c;
   unsigned int loop = 128; /* a valid DNS name can never loop this much */
   unsigned char length;
 
@@ -496,7 +518,7 @@
       if((index + 1) >= dohlen)
         return DOH_DNS_OUT_OF_RANGE;
 
-      /* move to the the new index */
+      /* move to the new index */
       newpos = (length & 0x3f) << 8 | doh[index + 1];
       index = newpos;
       continue;
@@ -507,18 +529,15 @@
       index++;
 
     if(length) {
-      DOHcode rc;
-      if(c->len) {
-        rc = cnameappend(c, (unsigned char *)".", 1);
-        if(rc)
-          return rc;
+      if(Curl_dyn_len(c)) {
+        if(Curl_dyn_add(c, "."))
+          return DOH_OUT_OF_MEM;
       }
       if((index + length) > dohlen)
         return DOH_DNS_BAD_LABEL;
 
-      rc = cnameappend(c, &doh[index], length);
-      if(rc)
-        return rc;
+      if(Curl_dyn_addn(c, &doh[index], length))
+        return DOH_OUT_OF_MEM;
       index += length;
     }
   } while(length && --loop);
@@ -528,7 +547,7 @@
   return DOH_OK;
 }
 
-static DOHcode rdata(unsigned char *doh,
+static DOHcode rdata(const unsigned char *doh,
                      size_t dohlen,
                      unsigned short rdlength,
                      unsigned short type,
@@ -561,6 +580,9 @@
     if(rc)
       return rc;
     break;
+  case DNS_TYPE_DNAME:
+    /* explicit for clarity; just skip; rely on synthesized CNAME  */
+    break;
   default:
     /* unsupported type, just skip it */
     break;
@@ -568,14 +590,17 @@
   return DOH_OK;
 }
 
-static void init_dohentry(struct dohentry *de)
+UNITTEST void de_init(struct dohentry *de)
 {
+  int i;
   memset(de, 0, sizeof(*de));
   de->ttl = INT_MAX;
+  for(i = 0; i < DOH_MAX_CNAME; i++)
+    Curl_dyn_init(&de->cname[i], DYN_DOH_CNAME);
 }
 
 
-UNITTEST DOHcode doh_decode(unsigned char *doh,
+UNITTEST DOHcode doh_decode(const unsigned char *doh,
                             size_t dohlen,
                             DNStype dnstype,
                             struct dohentry *d)
@@ -622,8 +647,10 @@
       return DOH_DNS_OUT_OF_RANGE;
 
     type = get16bit(doh, index);
-    if((type != DNS_TYPE_CNAME) && (type != dnstype))
-      /* Not the same type as was asked for nor CNAME */
+    if((type != DNS_TYPE_CNAME)    /* may be synthesized from DNAME */
+       && (type != DNS_TYPE_DNAME) /* if present, accept and ignore */
+       && (type != dnstype))
+      /* Not the same type as was asked for nor CNAME nor DNAME */
       return DOH_DNS_UNEXPECTED_TYPE;
     index += 2;
 
@@ -713,12 +740,12 @@
 
 #ifndef CURL_DISABLE_VERBOSE_STRINGS
 static void showdoh(struct Curl_easy *data,
-                    struct dohentry *d)
+                    const struct dohentry *d)
 {
   int i;
   infof(data, "TTL: %u seconds\n", d->ttl);
   for(i = 0; i < d->numaddr; i++) {
-    struct dohaddr *a = &d->addr[i];
+    const struct dohaddr *a = &d->addr[i];
     if(a->type == DNS_TYPE_A) {
       infof(data, "DOH A: %u.%u.%u.%u\n",
             a->ip.v4[0], a->ip.v4[1],
@@ -744,7 +771,7 @@
     }
   }
   for(i = 0; i < d->numcname; i++) {
-    infof(data, "CNAME: %s\n", d->cname[i].alloc);
+    infof(data, "CNAME: %s\n", Curl_dyn_ptr(&d->cname[i]));
   }
 }
 #else
@@ -764,18 +791,19 @@
  * must be an associated call later to Curl_freeaddrinfo().
  */
 
-static Curl_addrinfo *
+static struct Curl_addrinfo *
 doh2ai(const struct dohentry *de, const char *hostname, int port)
 {
-  Curl_addrinfo *ai;
-  Curl_addrinfo *prevai = NULL;
-  Curl_addrinfo *firstai = NULL;
+  struct Curl_addrinfo *ai;
+  struct Curl_addrinfo *prevai = NULL;
+  struct Curl_addrinfo *firstai = NULL;
   struct sockaddr_in *addr;
 #ifdef ENABLE_IPV6
   struct sockaddr_in6 *addr6;
 #endif
   CURLcode result = CURLE_OK;
   int i;
+  size_t hostlen = strlen(hostname) + 1; /* include zero terminator */
 
   if(!de)
     /* no input == no output! */
@@ -798,24 +826,14 @@
       addrtype = AF_INET;
     }
 
-    ai = calloc(1, sizeof(Curl_addrinfo));
+    ai = calloc(1, sizeof(struct Curl_addrinfo) + ss_size + hostlen);
     if(!ai) {
       result = CURLE_OUT_OF_MEMORY;
       break;
     }
-    ai->ai_canonname = strdup(hostname);
-    if(!ai->ai_canonname) {
-      result = CURLE_OUT_OF_MEMORY;
-      free(ai);
-      break;
-    }
-    ai->ai_addr = calloc(1, ss_size);
-    if(!ai->ai_addr) {
-      result = CURLE_OUT_OF_MEMORY;
-      free(ai->ai_canonname);
-      free(ai);
-      break;
-    }
+    ai->ai_addr = (void *)((char *)ai + sizeof(struct Curl_addrinfo));
+    ai->ai_canonname = (void *)((char *)ai->ai_addr + ss_size);
+    memcpy(ai->ai_canonname, hostname, hostlen);
 
     if(!firstai)
       /* store the pointer we want to return from this function */
@@ -877,54 +895,54 @@
 {
   int i = 0;
   for(i = 0; i < d->numcname; i++) {
-    free(d->cname[i].alloc);
+    Curl_dyn_free(&d->cname[i]);
   }
 }
 
 CURLcode Curl_doh_is_resolved(struct connectdata *conn,
                               struct Curl_dns_entry **dnsp)
 {
+  CURLcode result;
   struct Curl_easy *data = conn->data;
   *dnsp = NULL; /* defaults to no response */
 
-  if(!data->req.doh.probe[0].easy && !data->req.doh.probe[1].easy) {
+  if(!data->req.doh.probe[DOH_PROBE_SLOT_IPADDR_V4].easy &&
+     !data->req.doh.probe[DOH_PROBE_SLOT_IPADDR_V6].easy) {
     failf(data, "Could not DOH-resolve: %s", conn->async.hostname);
     return conn->bits.proxy?CURLE_COULDNT_RESOLVE_PROXY:
       CURLE_COULDNT_RESOLVE_HOST;
   }
   else if(!data->req.doh.pending) {
-    DOHcode rc;
-    DOHcode rc2;
+    DOHcode rc[DOH_PROBE_SLOTS] = {
+      DOH_OK, DOH_OK
+    };
     struct dohentry de;
+    int slot;
     /* remove DOH handles from multi handle and close them */
-    curl_multi_remove_handle(data->multi, data->req.doh.probe[0].easy);
-    Curl_close(data->req.doh.probe[0].easy);
-    curl_multi_remove_handle(data->multi, data->req.doh.probe[1].easy);
-    Curl_close(data->req.doh.probe[1].easy);
-
+    for(slot = 0; slot < DOH_PROBE_SLOTS; slot++) {
+      curl_multi_remove_handle(data->multi, data->req.doh.probe[slot].easy);
+      Curl_close(&data->req.doh.probe[slot].easy);
+    }
     /* parse the responses, create the struct and return it! */
-    init_dohentry(&de);
-    rc = doh_decode(data->req.doh.probe[0].serverdoh.memory,
-                    data->req.doh.probe[0].serverdoh.size,
-                    data->req.doh.probe[0].dnstype,
-                    &de);
-    free(data->req.doh.probe[0].serverdoh.memory);
-    if(rc) {
-      infof(data, "DOH: %s type %s for %s\n", doh_strerror(rc),
-            type2name(data->req.doh.probe[0].dnstype),
-            data->req.doh.host);
-    }
-    rc2 = doh_decode(data->req.doh.probe[1].serverdoh.memory,
-                     data->req.doh.probe[1].serverdoh.size,
-                     data->req.doh.probe[1].dnstype,
-                     &de);
-    free(data->req.doh.probe[1].serverdoh.memory);
-    if(rc2) {
-      infof(data, "DOH: %s type %s for %s\n", doh_strerror(rc2),
-            type2name(data->req.doh.probe[1].dnstype),
-            data->req.doh.host);
-    }
-    if(!rc || !rc2) {
+    de_init(&de);
+    for(slot = 0; slot < DOH_PROBE_SLOTS; slot++) {
+      struct dnsprobe *p = &data->req.doh.probe[slot];
+      if(!p->dnstype)
+        continue;
+      rc[slot] = doh_decode(Curl_dyn_uptr(&p->serverdoh),
+                            Curl_dyn_len(&p->serverdoh),
+                            p->dnstype,
+                            &de);
+      Curl_dyn_free(&p->serverdoh);
+      if(rc[slot]) {
+        infof(data, "DOH: %s type %s for %s\n", doh_strerror(rc[slot]),
+              type2name(p->dnstype), data->req.doh.host);
+      }
+    } /* next slot */
+
+    result = CURLE_COULDNT_RESOLVE_HOST; /* until we know better */
+    if(!rc[DOH_PROBE_SLOT_IPADDR_V4] || !rc[DOH_PROBE_SLOT_IPADDR_V6]) {
+      /* we have an address, of one kind or other */
       struct Curl_dns_entry *dns;
       struct Curl_addrinfo *ai;
 
@@ -946,21 +964,26 @@
       if(data->share)
         Curl_share_unlock(data, CURL_LOCK_DATA_DNS);
 
-      de_cleanup(&de);
-      if(!dns)
+      if(!dns) {
         /* returned failure, bail out nicely */
         Curl_freeaddrinfo(ai);
+      }
       else {
         conn->async.dns = dns;
         *dnsp = dns;
-        return CURLE_OK;
+        result = CURLE_OK;      /* address resolution OK */
       }
-    }
+    } /* address processing done */
+
+    /* Now process any build-specific attributes retrieved from DNS */
+
+    /* All done */
     de_cleanup(&de);
+    return result;
 
-    return CURLE_COULDNT_RESOLVE_HOST;
-  }
+  } /* !data->req.doh.pending */
 
+  /* else wait for pending DOH transactions to complete */
   return CURLE_OK;
 }
 
diff --git a/Utilities/cmcurl/lib/doh.h b/Utilities/cmcurl/lib/doh.h
index 34bfa6f..bbd4c1a 100644
--- a/Utilities/cmcurl/lib/doh.h
+++ b/Utilities/cmcurl/lib/doh.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 2018 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 2018 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -32,16 +32,15 @@
  * and returns a 'Curl_addrinfo *' with the address information.
  */
 
-Curl_addrinfo *Curl_doh(struct connectdata *conn,
-                        const char *hostname,
-                        int port,
-                        int *waitp);
+struct Curl_addrinfo *Curl_doh(struct connectdata *conn,
+                               const char *hostname,
+                               int port,
+                               int *waitp);
 
 CURLcode Curl_doh_is_resolved(struct connectdata *conn,
                               struct Curl_dns_entry **dns);
 
-int Curl_doh_getsock(struct connectdata *conn, curl_socket_t *socks,
-                     int numsocks);
+int Curl_doh_getsock(struct connectdata *conn, curl_socket_t *socks);
 
 typedef enum {
   DOH_OK,
@@ -56,25 +55,21 @@
   DOH_DNS_UNEXPECTED_TYPE,  /* 9 */
   DOH_DNS_UNEXPECTED_CLASS, /* 10 */
   DOH_NO_CONTENT,           /* 11 */
-  DOH_DNS_BAD_ID            /* 12 */
+  DOH_DNS_BAD_ID,           /* 12 */
+  DOH_DNS_NAME_TOO_LONG     /* 13 */
 } DOHcode;
 
 typedef enum {
   DNS_TYPE_A = 1,
   DNS_TYPE_NS = 2,
   DNS_TYPE_CNAME = 5,
-  DNS_TYPE_AAAA = 28
+  DNS_TYPE_AAAA = 28,
+  DNS_TYPE_DNAME = 39           /* RFC6672 */
 } DNStype;
 
 #define DOH_MAX_ADDR 24
 #define DOH_MAX_CNAME 4
 
-struct cnamestore {
-  size_t len;       /* length of cname */
-  char *alloc;      /* allocated pointer */
-  size_t allocsize; /* allocated size */
-};
-
 struct dohaddr {
   int type;
   union {
@@ -84,11 +79,11 @@
 };
 
 struct dohentry {
-  unsigned int ttl;
-  int numaddr;
+  struct dynbuf cname[DOH_MAX_CNAME];
   struct dohaddr addr[DOH_MAX_ADDR];
+  int numaddr;
+  unsigned int ttl;
   int numcname;
-  struct cnamestore cname[DOH_MAX_CNAME];
 };
 
 
@@ -98,10 +93,11 @@
                    unsigned char *dnsp, /* buffer */
                    size_t len,  /* buffer size */
                    size_t *olen); /* output length */
-DOHcode doh_decode(unsigned char *doh,
+DOHcode doh_decode(const unsigned char *doh,
                    size_t dohlen,
                    DNStype dnstype,
                    struct dohentry *d);
+void de_init(struct dohentry *d);
 void de_cleanup(struct dohentry *d);
 #endif
 
diff --git a/Utilities/cmcurl/lib/dotdot.c b/Utilities/cmcurl/lib/dotdot.c
index 2c6177a..ce9a052 100644
--- a/Utilities/cmcurl/lib/dotdot.c
+++ b/Utilities/cmcurl/lib/dotdot.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -39,7 +39,7 @@
  * Curl_dedotdotify()
  * @unittest: 1395
  *
- * This function gets a zero-terminated path with dot and dotdot sequences
+ * This function gets a null-terminated path with dot and dotdot sequences
  * passed in and strips them off according to the rules in RFC 3986 section
  * 5.2.4.
  *
@@ -62,7 +62,7 @@
   if(!out)
     return NULL; /* out of memory */
 
-  *out = 0; /* zero terminates, for inputs like "./" */
+  *out = 0; /* null-terminates, for inputs like "./" */
 
   /* get a cloned copy of the input */
   clone = strdup(input);
@@ -129,7 +129,7 @@
         if(*outptr == '/')
           break;
       }
-      *outptr = 0; /* zero-terminate where it stops */
+      *outptr = 0; /* null-terminate where it stops */
     }
     else if(!strcmp("/..", clone)) {
       clone[2]='/';
@@ -141,7 +141,7 @@
         if(*outptr == '/')
           break;
       }
-      *outptr = 0; /* zero-terminate where it stops */
+      *outptr = 0; /* null-terminate where it stops */
     }
 
     /*  D.  if the input buffer consists only of "." or "..", then remove
diff --git a/Utilities/cmcurl/lib/dotdot.h b/Utilities/cmcurl/lib/dotdot.h
index 125af43..f70b1db 100644
--- a/Utilities/cmcurl/lib/dotdot.h
+++ b/Utilities/cmcurl/lib/dotdot.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
diff --git a/Utilities/cmcurl/lib/dynbuf.c b/Utilities/cmcurl/lib/dynbuf.c
new file mode 100644
index 0000000..38d370b
--- /dev/null
+++ b/Utilities/cmcurl/lib/dynbuf.c
@@ -0,0 +1,227 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+#include "strdup.h"
+#include "dynbuf.h"
+
+/* The last 3 #include files should be in this order */
+#include "curl_printf.h"
+#include "curl_memory.h"
+#include "memdebug.h"
+
+#define MIN_FIRST_ALLOC 32
+
+#define DYNINIT 0xbee51da /* random pattern */
+
+/*
+ * Init a dynbuf struct.
+ */
+void Curl_dyn_init(struct dynbuf *s, size_t toobig)
+{
+  DEBUGASSERT(s);
+  DEBUGASSERT(toobig);
+  s->bufr = NULL;
+  s->leng = 0;
+  s->allc = 0;
+  s->toobig = toobig;
+#ifdef DEBUGBUILD
+  s->init = DYNINIT;
+#endif
+}
+
+/*
+ * free the buffer and re-init the necessary fields. It doesn't touch the
+ * 'init' field and thus this buffer can be reused to add data to again.
+ */
+void Curl_dyn_free(struct dynbuf *s)
+{
+  DEBUGASSERT(s);
+  Curl_safefree(s->bufr);
+  s->leng = s->allc = 0;
+}
+
+/*
+ * Store/append an chunk of memory to the dynbuf.
+ */
+static CURLcode dyn_nappend(struct dynbuf *s,
+                            const unsigned char *mem, size_t len)
+{
+  size_t indx = s->leng;
+  size_t a = s->allc;
+  size_t fit = len + indx + 1; /* new string + old string + zero byte */
+
+  /* try to detect if there's rubbish in the struct */
+  DEBUGASSERT(s->init == DYNINIT);
+  DEBUGASSERT(s->toobig);
+  DEBUGASSERT(indx < s->toobig);
+  DEBUGASSERT(!s->leng || s->bufr);
+
+  if(fit > s->toobig) {
+    Curl_dyn_free(s);
+    return CURLE_OUT_OF_MEMORY;
+  }
+  else if(!a) {
+    DEBUGASSERT(!indx);
+    /* first invoke */
+    if(fit < MIN_FIRST_ALLOC)
+      a = MIN_FIRST_ALLOC;
+    else
+      a = fit;
+  }
+  else {
+    while(a < fit)
+      a *= 2;
+  }
+
+  if(a != s->allc) {
+    s->bufr = Curl_saferealloc(s->bufr, a);
+    if(!s->bufr) {
+      s->leng = s->allc = 0;
+      return CURLE_OUT_OF_MEMORY;
+    }
+    s->allc = a;
+  }
+
+  if(len)
+    memcpy(&s->bufr[indx], mem, len);
+  s->leng = indx + len;
+  s->bufr[s->leng] = 0;
+  return CURLE_OK;
+}
+
+/*
+ * Clears the string, keeps the allocation. This can also be called on a
+ * buffer that already was freed.
+ */
+void Curl_dyn_reset(struct dynbuf *s)
+{
+  DEBUGASSERT(s);
+  DEBUGASSERT(s->init == DYNINIT);
+  DEBUGASSERT(!s->leng || s->bufr);
+  if(s->leng)
+    s->bufr[0] = 0;
+  s->leng = 0;
+}
+
+#ifdef USE_NGTCP2
+/*
+ * Specify the size of the tail to keep (number of bytes from the end of the
+ * buffer). The rest will be dropped.
+ */
+CURLcode Curl_dyn_tail(struct dynbuf *s, size_t trail)
+{
+  DEBUGASSERT(s);
+  DEBUGASSERT(s->init == DYNINIT);
+  DEBUGASSERT(!s->leng || s->bufr);
+  if(trail > s->leng)
+    return CURLE_BAD_FUNCTION_ARGUMENT;
+  else if(trail == s->leng)
+    return CURLE_OK;
+  else if(!trail) {
+    Curl_dyn_reset(s);
+  }
+  else {
+    memmove(&s->bufr[0], &s->bufr[s->leng - trail], trail);
+    s->leng = trail;
+  }
+  return CURLE_OK;
+
+}
+#endif
+
+/*
+ * Appends a buffer with length.
+ */
+CURLcode Curl_dyn_addn(struct dynbuf *s, const void *mem, size_t len)
+{
+  DEBUGASSERT(s);
+  DEBUGASSERT(s->init == DYNINIT);
+  DEBUGASSERT(!s->leng || s->bufr);
+  return dyn_nappend(s, mem, len);
+}
+
+/*
+ * Append a null-terminated string at the end.
+ */
+CURLcode Curl_dyn_add(struct dynbuf *s, const char *str)
+{
+  size_t n = strlen(str);
+  DEBUGASSERT(s);
+  DEBUGASSERT(s->init == DYNINIT);
+  DEBUGASSERT(!s->leng || s->bufr);
+  return dyn_nappend(s, (unsigned char *)str, n);
+}
+
+/*
+ * Append a string printf()-style
+ */
+CURLcode Curl_dyn_addf(struct dynbuf *s, const char *fmt, ...)
+{
+  char *str;
+  va_list ap;
+  va_start(ap, fmt);
+  str = vaprintf(fmt, ap); /* this allocs a new string to append */
+  va_end(ap);
+
+  if(str) {
+    CURLcode result = dyn_nappend(s, (unsigned char *)str, strlen(str));
+    free(str);
+    return result;
+  }
+  /* If we failed, we cleanup the whole buffer and return error */
+  Curl_dyn_free(s);
+  return CURLE_OUT_OF_MEMORY;
+}
+
+/*
+ * Returns a pointer to the buffer.
+ */
+char *Curl_dyn_ptr(const struct dynbuf *s)
+{
+  DEBUGASSERT(s);
+  DEBUGASSERT(s->init == DYNINIT);
+  DEBUGASSERT(!s->leng || s->bufr);
+  return s->bufr;
+}
+
+/*
+ * Returns an unsigned pointer to the buffer.
+ */
+unsigned char *Curl_dyn_uptr(const struct dynbuf *s)
+{
+  DEBUGASSERT(s);
+  DEBUGASSERT(s->init == DYNINIT);
+  DEBUGASSERT(!s->leng || s->bufr);
+  return (unsigned char *)s->bufr;
+}
+
+/*
+ * Returns the length of the buffer.
+ */
+size_t Curl_dyn_len(const struct dynbuf *s)
+{
+  DEBUGASSERT(s);
+  DEBUGASSERT(s->init == DYNINIT);
+  DEBUGASSERT(!s->leng || s->bufr);
+  return s->leng;
+}
diff --git a/Utilities/cmcurl/lib/dynbuf.h b/Utilities/cmcurl/lib/dynbuf.h
new file mode 100644
index 0000000..c80239e
--- /dev/null
+++ b/Utilities/cmcurl/lib/dynbuf.h
@@ -0,0 +1,63 @@
+#ifndef HEADER_CURL_DYNBUF_H
+#define HEADER_CURL_DYNBUF_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+struct dynbuf {
+  char *bufr;    /* point to a null-terminated allocated buffer */
+  size_t leng;   /* number of bytes *EXCLUDING* the zero terminator */
+  size_t allc;   /* size of the current allocation */
+  size_t toobig; /* size limit for the buffer */
+#ifdef DEBUGBUILD
+  int init;     /* detect API usage mistakes */
+#endif
+};
+
+void Curl_dyn_init(struct dynbuf *s, size_t toobig);
+void Curl_dyn_free(struct dynbuf *s);
+CURLcode Curl_dyn_addn(struct dynbuf *s, const void *mem, size_t len)
+  WARN_UNUSED_RESULT;
+CURLcode Curl_dyn_add(struct dynbuf *s, const char *str)
+  WARN_UNUSED_RESULT;
+CURLcode Curl_dyn_addf(struct dynbuf *s, const char *fmt, ...)
+  WARN_UNUSED_RESULT;
+void Curl_dyn_reset(struct dynbuf *s);
+CURLcode Curl_dyn_tail(struct dynbuf *s, size_t trail);
+char *Curl_dyn_ptr(const struct dynbuf *s);
+unsigned char *Curl_dyn_uptr(const struct dynbuf *s);
+size_t Curl_dyn_len(const struct dynbuf *s);
+
+/* Dynamic buffer max sizes */
+#define DYN_DOH_RESPONSE    3000
+#define DYN_DOH_CNAME       256
+#define DYN_PAUSE_BUFFER    (64 * 1024 * 1024)
+#define DYN_HAXPROXY        2048
+#define DYN_HTTP_REQUEST    (128*1024)
+#define DYN_H2_HEADERS      (128*1024)
+#define DYN_H2_TRAILER      4096
+#define DYN_APRINTF         8000000
+#define DYN_RTSP_REQ_HEADER (64*1024)
+#define DYN_TRAILERS        (64*1024)
+#define DYN_PROXY_CONNECT_HEADERS 16384
+#define DYN_QLOG_NAME       1024
+#define DYN_H1_TRAILER      DYN_H2_TRAILER
+#endif
diff --git a/Utilities/cmcurl/lib/easy.c b/Utilities/cmcurl/lib/easy.c
index 4a6f965..292cca7 100644
--- a/Utilities/cmcurl/lib/easy.c
+++ b/Utilities/cmcurl/lib/easy.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -72,18 +72,18 @@
 #include "warnless.h"
 #include "multiif.h"
 #include "sigpipe.h"
-#include "ssh.h"
+#include "vssh/ssh.h"
 #include "setopt.h"
 #include "http_digest.h"
 #include "system_win32.h"
+#include "http2.h"
+#include "dynbuf.h"
 
 /* The last 3 #include files should be in this order */
 #include "curl_printf.h"
 #include "curl_memory.h"
 #include "memdebug.h"
 
-void Curl_version_init(void);
-
 /* true globals -- for curl_global_init() and curl_global_cleanup() */
 static unsigned int  initialized;
 static long          init_flags;
@@ -157,20 +157,20 @@
 
   if(!Curl_ssl_init()) {
     DEBUGF(fprintf(stderr, "Error: Curl_ssl_init failed\n"));
-    return CURLE_FAILED_INIT;
+    goto fail;
   }
 
 #ifdef WIN32
   if(Curl_win32_init(flags)) {
     DEBUGF(fprintf(stderr, "Error: win32_init failed\n"));
-    return CURLE_FAILED_INIT;
+    goto fail;
   }
 #endif
 
 #ifdef __AMIGA__
   if(!Curl_amiga_init()) {
     DEBUGF(fprintf(stderr, "Error: Curl_amiga_init failed\n"));
-    return CURLE_FAILED_INIT;
+    goto fail;
   }
 #endif
 
@@ -182,33 +182,29 @@
 
   if(Curl_resolver_global_init()) {
     DEBUGF(fprintf(stderr, "Error: resolver_global_init failed\n"));
-    return CURLE_FAILED_INIT;
+    goto fail;
   }
 
-  (void)Curl_ipv6works();
-
-#if defined(USE_LIBSSH2) && defined(HAVE_LIBSSH2_INIT)
-  if(libssh2_init(0)) {
-    DEBUGF(fprintf(stderr, "Error: libssh2_init failed\n"));
-    return CURLE_FAILED_INIT;
+#if defined(USE_SSH)
+  if(Curl_ssh_init()) {
+    goto fail;
   }
 #endif
 
-#if defined(USE_LIBSSH)
-  if(ssh_init()) {
-    DEBUGF(fprintf(stderr, "Error: libssh_init failed\n"));
+#ifdef USE_WOLFSSH
+  if(WS_SUCCESS != wolfSSH_Init()) {
+    DEBUGF(fprintf(stderr, "Error: wolfSSH_Init failed\n"));
     return CURLE_FAILED_INIT;
   }
 #endif
 
-  if(flags & CURL_GLOBAL_ACK_EINTR)
-    Curl_ack_eintr = 1;
-
   init_flags = flags;
 
-  Curl_version_init();
-
   return CURLE_OK;
+
+  fail:
+  initialized--; /* undo the increase */
+  return CURLE_FAILED_INIT;
 }
 
 
@@ -274,12 +270,10 @@
 
   Curl_amiga_cleanup();
 
-#if defined(USE_LIBSSH2) && defined(HAVE_LIBSSH2_EXIT)
-  (void)libssh2_exit();
-#endif
+  Curl_ssh_cleanup();
 
-#if defined(USE_LIBSSH)
-  (void)ssh_finalize();
+#ifdef USE_WOLFSSH
+  (void)wolfSSH_Cleanup();
 #endif
 
   init_flags  = 0;
@@ -516,7 +510,7 @@
     before = Curl_now();
 
     /* wait for activity or timeout */
-    pollrc = Curl_poll(fds, numfds, (int)ev->ms);
+    pollrc = Curl_poll(fds, numfds, ev->ms);
 
     after = Curl_now();
 
@@ -602,27 +596,11 @@
 
   while(!done && !mcode) {
     int still_running = 0;
-    bool gotsocket = FALSE;
 
-    mcode = Curl_multi_wait(multi, NULL, 0, 1000, NULL, &gotsocket);
+    mcode = curl_multi_poll(multi, NULL, 0, 1000, NULL);
 
-    if(!mcode) {
-      if(!gotsocket) {
-        long sleep_ms;
-
-        /* If it returns without any filedescriptor instantly, we need to
-           avoid busy-looping during periods where it has nothing particular
-           to wait for */
-        curl_multi_timeout(multi, &sleep_ms);
-        if(sleep_ms) {
-          if(sleep_ms > 1000)
-            sleep_ms = 1000;
-          Curl_wait_ms((int)sleep_ms);
-        }
-      }
-
+    if(!mcode)
       mcode = curl_multi_perform(multi, &still_running);
-    }
 
     /* only read 'still_running' if curl_multi_perform() return OK */
     if(!mcode && !still_running) {
@@ -703,6 +681,7 @@
   mcode = curl_multi_add_handle(multi, data);
   if(mcode) {
     curl_multi_cleanup(multi);
+    data->multi_easy = NULL;
     if(mcode == CURLM_OUT_OF_MEMORY)
       return CURLE_OUT_OF_MEMORY;
     return CURLE_FAILED_INIT;
@@ -710,10 +689,6 @@
 
   sigpipe_ignore(data, &pipe_st);
 
-  /* assign this after curl_multi_add_handle() since that function checks for
-     it and rejects this handle otherwise */
-  data->multi = multi;
-
   /* run the transfer */
   result = events ? easy_events(multi) : easy_transfer(multi);
 
@@ -761,7 +736,7 @@
     return;
 
   sigpipe_ignore(data, &pipe_st);
-  Curl_close(data);
+  Curl_close(&data);
   sigpipe_restore(&pipe_st);
 }
 
@@ -789,6 +764,7 @@
 {
   CURLcode result = CURLE_OK;
   enum dupstring i;
+  enum dupblob j;
 
   /* Copy src->set into dst->set first, then deal with the strings
      afterwards */
@@ -805,6 +781,16 @@
       return result;
   }
 
+  /* clear all blob pointers first */
+  memset(dst->set.blobs, 0, BLOB_LAST * sizeof(struct curl_blob *));
+  /* duplicate all blobs */
+  for(j = (enum dupblob)0; j < BLOB_LAST; j++) {
+    result = Curl_setblobopt(&dst->set.blobs[j], src->set.blobs[j]);
+    /* Curl_setstropt return CURLE_BAD_FUNCTION_ARGUMENT with blob */
+    if(result)
+      return result;
+  }
+
   /* duplicate memory areas pointed to */
   i = STRING_COPYPOSTFIELDS;
   if(src->set.postfieldsize && src->set.str[i]) {
@@ -843,19 +829,13 @@
    * the likeliness of us forgetting to init a buffer here in the future.
    */
   outcurl->set.buffer_size = data->set.buffer_size;
-  outcurl->state.buffer = malloc(outcurl->set.buffer_size + 1);
-  if(!outcurl->state.buffer)
-    goto fail;
-
-  outcurl->state.headerbuff = malloc(HEADERSIZE);
-  if(!outcurl->state.headerbuff)
-    goto fail;
-  outcurl->state.headersize = HEADERSIZE;
 
   /* copy all userdefined values */
   if(dupset(outcurl, data))
     goto fail;
 
+  Curl_dyn_init(&outcurl->state.headerb, CURL_MAX_HTTP_HEADER);
+
   /* the connection cache is setup on demand */
   outcurl->state.conn_cache = NULL;
 
@@ -910,6 +890,28 @@
                              data->state.resolver))
     goto fail;
 
+#ifdef USE_ARES
+  {
+    CURLcode rc;
+
+    rc = Curl_set_dns_servers(outcurl, data->set.str[STRING_DNS_SERVERS]);
+    if(rc && rc != CURLE_NOT_BUILT_IN)
+      goto fail;
+
+    rc = Curl_set_dns_interface(outcurl, data->set.str[STRING_DNS_INTERFACE]);
+    if(rc && rc != CURLE_NOT_BUILT_IN)
+      goto fail;
+
+    rc = Curl_set_dns_local_ip4(outcurl, data->set.str[STRING_DNS_LOCAL_IP4]);
+    if(rc && rc != CURLE_NOT_BUILT_IN)
+      goto fail;
+
+    rc = Curl_set_dns_local_ip6(outcurl, data->set.str[STRING_DNS_LOCAL_IP6]);
+    if(rc && rc != CURLE_NOT_BUILT_IN)
+      goto fail;
+  }
+#endif /* USE_ARES */
+
   Curl_convert_setup(outcurl);
 
   Curl_initinfo(outcurl);
@@ -926,7 +928,7 @@
     curl_slist_free_all(outcurl->change.cookielist);
     outcurl->change.cookielist = NULL;
     Curl_safefree(outcurl->state.buffer);
-    Curl_safefree(outcurl->state.headerbuff);
+    Curl_dyn_free(&outcurl->state.headerb);
     Curl_safefree(outcurl->change.url);
     Curl_safefree(outcurl->change.referer);
     Curl_freeset(outcurl);
@@ -982,68 +984,101 @@
  */
 CURLcode curl_easy_pause(struct Curl_easy *data, int action)
 {
-  struct SingleRequest *k = &data->req;
+  struct SingleRequest *k;
   CURLcode result = CURLE_OK;
+  int oldstate;
+  int newstate;
 
-  /* first switch off both pause bits */
-  int newstate = k->keepon &~ (KEEP_RECV_PAUSE| KEEP_SEND_PAUSE);
+  if(!GOOD_EASY_HANDLE(data) || !data->conn)
+    /* crazy input, don't continue */
+    return CURLE_BAD_FUNCTION_ARGUMENT;
 
-  /* set the new desired pause bits */
-  newstate |= ((action & CURLPAUSE_RECV)?KEEP_RECV_PAUSE:0) |
+  k = &data->req;
+  oldstate = k->keepon & (KEEP_RECV_PAUSE| KEEP_SEND_PAUSE);
+
+  /* first switch off both pause bits then set the new pause bits */
+  newstate = (k->keepon &~ (KEEP_RECV_PAUSE| KEEP_SEND_PAUSE)) |
+    ((action & CURLPAUSE_RECV)?KEEP_RECV_PAUSE:0) |
     ((action & CURLPAUSE_SEND)?KEEP_SEND_PAUSE:0);
 
+  if((newstate & (KEEP_RECV_PAUSE| KEEP_SEND_PAUSE)) == oldstate) {
+    /* Not changing any pause state, return */
+    DEBUGF(infof(data, "pause: no change, early return\n"));
+    return CURLE_OK;
+  }
+
+  /* Unpause parts in active mime tree. */
+  if((k->keepon & ~newstate & KEEP_SEND_PAUSE) &&
+     (data->mstate == CURLM_STATE_PERFORM ||
+      data->mstate == CURLM_STATE_TOOFAST) &&
+     data->state.fread_func == (curl_read_callback) Curl_mime_read) {
+    Curl_mime_unpause(data->state.in);
+  }
+
   /* put it back in the keepon */
   k->keepon = newstate;
 
-  if(!(newstate & KEEP_RECV_PAUSE) && data->state.tempcount) {
-    /* there are buffers for sending that can be delivered as the receive
-       pausing is lifted! */
-    unsigned int i;
-    unsigned int count = data->state.tempcount;
-    struct tempbuf writebuf[3]; /* there can only be three */
-    struct connectdata *conn = data->conn;
-    struct Curl_easy *saved_data = NULL;
+  if(!(newstate & KEEP_RECV_PAUSE)) {
+    Curl_http2_stream_pause(data, FALSE);
 
-    /* copy the structs to allow for immediate re-pausing */
-    for(i = 0; i < data->state.tempcount; i++) {
-      writebuf[i] = data->state.tempwrite[i];
-      data->state.tempwrite[i].buf = NULL;
+    if(data->state.tempcount) {
+      /* there are buffers for sending that can be delivered as the receive
+         pausing is lifted! */
+      unsigned int i;
+      unsigned int count = data->state.tempcount;
+      struct tempbuf writebuf[3]; /* there can only be three */
+      struct connectdata *conn = data->conn;
+      struct Curl_easy *saved_data = NULL;
+
+      /* copy the structs to allow for immediate re-pausing */
+      for(i = 0; i < data->state.tempcount; i++) {
+        writebuf[i] = data->state.tempwrite[i];
+        Curl_dyn_init(&data->state.tempwrite[i].b, DYN_PAUSE_BUFFER);
+      }
+      data->state.tempcount = 0;
+
+      /* set the connection's current owner */
+      if(conn->data != data) {
+        saved_data = conn->data;
+        conn->data = data;
+      }
+
+      for(i = 0; i < count; i++) {
+        /* even if one function returns error, this loops through and frees
+           all buffers */
+        if(!result)
+          result = Curl_client_write(conn, writebuf[i].type,
+                                     Curl_dyn_ptr(&writebuf[i].b),
+                                     Curl_dyn_len(&writebuf[i].b));
+        Curl_dyn_free(&writebuf[i].b);
+      }
+
+      /* recover previous owner of the connection */
+      if(saved_data)
+        conn->data = saved_data;
+
+      if(result)
+        return result;
     }
-    data->state.tempcount = 0;
-
-    /* set the connection's current owner */
-    if(conn->data != data) {
-      saved_data = conn->data;
-      conn->data = data;
-    }
-
-    for(i = 0; i < count; i++) {
-      /* even if one function returns error, this loops through and frees all
-         buffers */
-      if(!result)
-        result = Curl_client_write(conn, writebuf[i].type, writebuf[i].buf,
-                                   writebuf[i].len);
-      free(writebuf[i].buf);
-    }
-
-    /* recover previous owner of the connection */
-    if(saved_data)
-      conn->data = saved_data;
-
-    if(result)
-      return result;
   }
 
   /* if there's no error and we're not pausing both directions, we want
      to have this handle checked soon */
-  if(!result &&
-     ((newstate&(KEEP_RECV_PAUSE|KEEP_SEND_PAUSE)) !=
-      (KEEP_RECV_PAUSE|KEEP_SEND_PAUSE)) )
+  if((newstate & (KEEP_RECV_PAUSE|KEEP_SEND_PAUSE)) !=
+     (KEEP_RECV_PAUSE|KEEP_SEND_PAUSE)) {
     Curl_expire(data, 0, EXPIRE_RUN_NOW); /* get this handle going again */
 
-  /* This transfer may have been moved in or out of the bundle, update
-     the corresponding socket callback, if used */
-  Curl_updatesocket(data);
+    /* force a recv/send check of this connection, as the data might've been
+       read off the socket already */
+    data->conn->cselect_bits = CURL_CSELECT_IN | CURL_CSELECT_OUT;
+    if(data->multi)
+      Curl_update_timer(data->multi);
+  }
+
+  if(!data->state.done)
+    /* This transfer may have been moved in or out of the bundle, update the
+       corresponding socket callback, if used */
+    Curl_updatesocket(data);
 
   return result;
 }
@@ -1138,6 +1173,35 @@
 }
 
 /*
+ * Wrapper to call functions in Curl_conncache_foreach()
+ *
+ * Returns always 0.
+ */
+static int conn_upkeep(struct connectdata *conn,
+                       void *param)
+{
+  /* Param is unused. */
+  (void)param;
+
+  if(conn->handler->connection_check) {
+    /* Do a protocol-specific keepalive check on the connection. */
+    conn->handler->connection_check(conn, CONNCHECK_KEEPALIVE);
+  }
+
+  return 0; /* continue iteration */
+}
+
+static CURLcode upkeep(struct conncache *conn_cache, void *data)
+{
+  /* Loop over every connection and make connection alive. */
+  Curl_conncache_foreach(data,
+                         conn_cache,
+                         data,
+                         conn_upkeep);
+  return CURLE_OK;
+}
+
+/*
  * Performs connection upkeep for the given session handle.
  */
 CURLcode curl_easy_upkeep(struct Curl_easy *data)
@@ -1148,7 +1212,7 @@
 
   if(data->multi_easy) {
     /* Use the common function to keep connections alive. */
-    return Curl_upkeep(&data->multi_easy->conn_cache, data);
+    return upkeep(&data->multi_easy->conn_cache, data);
   }
   else {
     /* No connections, so just return success */
diff --git a/Utilities/cmcurl/lib/easyif.h b/Utilities/cmcurl/lib/easyif.h
index 6ba7e54..eda0d62 100644
--- a/Utilities/cmcurl/lib/easyif.h
+++ b/Utilities/cmcurl/lib/easyif.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
diff --git a/Utilities/cmcurl/lib/escape.c b/Utilities/cmcurl/lib/escape.c
index 7121db3..2bea145 100644
--- a/Utilities/cmcurl/lib/escape.c
+++ b/Utilities/cmcurl/lib/escape.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -79,82 +79,83 @@
 char *curl_easy_escape(struct Curl_easy *data, const char *string,
                        int inlength)
 {
-  size_t alloc;
-  char *ns;
-  char *testing_ptr = NULL;
-  size_t newlen;
-  size_t strindex = 0;
   size_t length;
   CURLcode result;
+  struct dynbuf d;
 
   if(inlength < 0)
     return NULL;
 
-  alloc = (inlength?(size_t)inlength:strlen(string)) + 1;
-  newlen = alloc;
+  Curl_dyn_init(&d, CURL_MAX_INPUT_LENGTH);
 
-  ns = malloc(alloc);
-  if(!ns)
-    return NULL;
+  length = (inlength?(size_t)inlength:strlen(string));
+  if(!length)
+    return strdup("");
 
-  length = alloc-1;
   while(length--) {
     unsigned char in = *string; /* we need to treat the characters unsigned */
 
-    if(Curl_isunreserved(in))
-      /* just copy this */
-      ns[strindex++] = in;
+    if(Curl_isunreserved(in)) {
+      /* append this */
+      if(Curl_dyn_addn(&d, &in, 1))
+        return NULL;
+    }
     else {
       /* encode it */
-      newlen += 2; /* the size grows with two, since this'll become a %XX */
-      if(newlen > alloc) {
-        alloc *= 2;
-        testing_ptr = Curl_saferealloc(ns, alloc);
-        if(!testing_ptr)
-          return NULL;
-        ns = testing_ptr;
-      }
-
+      char encoded[4];
       result = Curl_convert_to_network(data, (char *)&in, 1);
       if(result) {
         /* Curl_convert_to_network calls failf if unsuccessful */
-        free(ns);
+        Curl_dyn_free(&d);
         return NULL;
       }
 
-      msnprintf(&ns[strindex], 4, "%%%02X", in);
-
-      strindex += 3;
+      msnprintf(encoded, sizeof(encoded), "%%%02X", in);
+      if(Curl_dyn_add(&d, encoded))
+        return NULL;
     }
     string++;
   }
-  ns[strindex] = 0; /* terminate it */
-  return ns;
+
+  return Curl_dyn_ptr(&d);
 }
 
 /*
  * Curl_urldecode() URL decodes the given string.
  *
- * Optionally detects control characters (byte codes lower than 32) in the
- * data and rejects such data.
- *
  * Returns a pointer to a malloced string in *ostring with length given in
  * *olen. If length == 0, the length is assumed to be strlen(string).
  *
  * 'data' can be set to NULL but then this function can't convert network
  * data to host for non-ascii.
+ *
+ * ctrl options:
+ * - REJECT_NADA: accept everything
+ * - REJECT_CTRL: rejects control characters (byte codes lower than 32) in
+ *                the data
+ * - REJECT_ZERO: rejects decoded zero bytes
+ *
+ * The values for the enum starts at 2, to make the assert detect legacy
+ * invokes that used TRUE/FALSE (0 and 1).
  */
+
 CURLcode Curl_urldecode(struct Curl_easy *data,
                         const char *string, size_t length,
                         char **ostring, size_t *olen,
-                        bool reject_ctrl)
+                        enum urlreject ctrl)
 {
-  size_t alloc = (length?length:strlen(string)) + 1;
-  char *ns = malloc(alloc);
+  size_t alloc;
+  char *ns;
   size_t strindex = 0;
   unsigned long hex;
   CURLcode result = CURLE_OK;
 
+  DEBUGASSERT(string);
+  DEBUGASSERT(ctrl >= REJECT_NADA); /* crash on TRUE/FALSE */
+
+  alloc = (length?length:strlen(string)) + 1;
+  ns = malloc(alloc);
+
   if(!ns)
     return CURLE_OUT_OF_MEMORY;
 
@@ -186,7 +187,8 @@
       alloc -= 2;
     }
 
-    if(reject_ctrl && (in < 0x20)) {
+    if(((ctrl == REJECT_CTRL) && (in < 0x20)) ||
+       ((ctrl == REJECT_ZERO) && (in == 0))) {
       free(ns);
       return CURLE_URL_MALFORMAT;
     }
@@ -220,7 +222,7 @@
     size_t inputlen = length;
     size_t outputlen;
     CURLcode res = Curl_urldecode(data, string, inputlen, &str, &outputlen,
-                                  FALSE);
+                                  REJECT_NADA);
     if(res)
       return NULL;
 
diff --git a/Utilities/cmcurl/lib/escape.h b/Utilities/cmcurl/lib/escape.h
index d8bbe5c..586db7e 100644
--- a/Utilities/cmcurl/lib/escape.h
+++ b/Utilities/cmcurl/lib/escape.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -25,9 +25,16 @@
  * allocated string or NULL if an error occurred.  */
 
 bool Curl_isunreserved(unsigned char in);
+
+enum urlreject {
+  REJECT_NADA = 2,
+  REJECT_CTRL,
+  REJECT_ZERO
+};
+
 CURLcode Curl_urldecode(struct Curl_easy *data,
                         const char *string, size_t length,
                         char **ostring, size_t *olen,
-                        bool reject_crlf);
+                        enum urlreject ctrl);
 
 #endif /* HEADER_CURL_ESCAPE_H */
diff --git a/Utilities/cmcurl/lib/file.c b/Utilities/cmcurl/lib/file.c
index d349cd9..cd3e49c 100644
--- a/Utilities/cmcurl/lib/file.c
+++ b/Utilities/cmcurl/lib/file.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -144,7 +144,7 @@
   size_t real_path_len;
 
   CURLcode result = Curl_urldecode(data, data->state.up.path, 0, &real_path,
-                                   &real_path_len, FALSE);
+                                   &real_path_len, REJECT_ZERO);
   if(result)
     return result;
 
diff --git a/Utilities/cmcurl/lib/file.h b/Utilities/cmcurl/lib/file.h
index 20828ad..f6b74a7 100644
--- a/Utilities/cmcurl/lib/file.h
+++ b/Utilities/cmcurl/lib/file.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2009, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
diff --git a/Utilities/cmcurl/lib/formdata.c b/Utilities/cmcurl/lib/formdata.c
index 429d479..1cab2c5 100644
--- a/Utilities/cmcurl/lib/formdata.c
+++ b/Utilities/cmcurl/lib/formdata.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -123,11 +123,11 @@
  * parent_form_info is NULL.
  *
  ***************************************************************************/
-static FormInfo * AddFormInfo(char *value,
-                              char *contenttype,
-                              FormInfo *parent_form_info)
+static struct FormInfo *AddFormInfo(char *value,
+                                    char *contenttype,
+                                    struct FormInfo *parent_form_info)
 {
-  FormInfo *form_info;
+  struct FormInfo *form_info;
   form_info = calloc(1, sizeof(struct FormInfo));
   if(form_info) {
     if(value)
@@ -204,7 +204,7 @@
                      struct curl_httppost **last_post,
                      va_list params)
 {
-  FormInfo *first_form, *current_form, *form = NULL;
+  struct FormInfo *first_form, *current_form, *form = NULL;
   CURLFORMcode return_value = CURL_FORMADD_OK;
   const char *prevtype = NULL;
   struct curl_httppost *post = NULL;
@@ -521,7 +521,7 @@
   if(CURL_FORMADD_OK != return_value) {
     /* On error, free allocated fields for all nodes of the FormInfo linked
        list without deallocating nodes. List nodes are deallocated later on */
-    FormInfo *ptr;
+    struct FormInfo *ptr;
     for(ptr = first_form; ptr != NULL; ptr = ptr->more) {
       if(ptr->name_alloc) {
         Curl_safefree(ptr->name);
@@ -602,7 +602,7 @@
         /* Note that there's small risk that form->name is NULL here if the
            app passed in a bad combo, so we better check for that first. */
         if(form->name) {
-          /* copy name (without strdup; possibly not nul-terminated) */
+          /* copy name (without strdup; possibly not null-terminated) */
           form->name = Curl_memdup(form->name, form->namelength?
                                    form->namelength:
                                    strlen(form->name) + 1);
@@ -650,7 +650,7 @@
       /* On error, free allocated fields for nodes of the FormInfo linked
          list which are not already owned by the httppost linked list
          without deallocating nodes. List nodes are deallocated later on */
-      FormInfo *ptr;
+      struct FormInfo *ptr;
       for(ptr = form; ptr != NULL; ptr = ptr->more) {
         if(ptr->name_alloc) {
           Curl_safefree(ptr->name);
@@ -676,7 +676,7 @@
      fields given that these have either been deallocated or are owned
      now by the httppost linked list */
   while(first_form) {
-    FormInfo *ptr = first_form->more;
+    struct FormInfo *ptr = first_form->more;
     free(first_form);
     first_form = ptr;
   }
@@ -728,14 +728,10 @@
     if(!nread)
       break;
 
-    switch(nread) {
-    default:
-      if(append(arg, buffer, nread) != nread)
-        result = CURLE_READ_ERROR;
-      break;
-    case CURL_READFUNC_ABORT:
-    case CURL_READFUNC_PAUSE:
-      break;
+    if(nread > sizeof(buffer) || append(arg, buffer, nread) != nread) {
+      result = CURLE_READ_ERROR;
+      if(nread == CURL_READFUNC_ABORT)
+        result = CURLE_ABORTED_BY_CALLBACK;
     }
   }
 
@@ -775,7 +771,7 @@
 }
 
 
-/* Set mime part name, taking care of non nul-terminated name string. */
+/* Set mime part name, taking care of non null-terminated name string. */
 static CURLcode setname(curl_mimepart *part, const char *name, size_t len)
 {
   char *zname;
diff --git a/Utilities/cmcurl/lib/formdata.h b/Utilities/cmcurl/lib/formdata.h
index cb20805..3766d38 100644
--- a/Utilities/cmcurl/lib/formdata.h
+++ b/Utilities/cmcurl/lib/formdata.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -27,7 +27,7 @@
 #ifndef CURL_DISABLE_MIME
 
 /* used by FormAdd for temporary storage */
-typedef struct FormInfo {
+struct FormInfo {
   char *name;
   bool name_alloc;
   size_t namelength;
@@ -45,7 +45,7 @@
   char *userp;        /* pointer for the read callback */
   struct curl_slist *contentheader;
   struct FormInfo *more;
-} FormInfo;
+};
 
 CURLcode Curl_getformdata(struct Curl_easy *data,
                           curl_mimepart *,
diff --git a/Utilities/cmcurl/lib/ftp.c b/Utilities/cmcurl/lib/ftp.c
index 53510f8..cfd70a6 100644
--- a/Utilities/cmcurl/lib/ftp.c
+++ b/Utilities/cmcurl/lib/ftp.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -55,7 +55,6 @@
 #include "transfer.h"
 #include "escape.h"
 #include "http.h" /* for HTTP proxy tunnel stuff */
-#include "socks.h"
 #include "ftp.h"
 #include "fileinfo.h"
 #include "ftplistparser.h"
@@ -78,6 +77,7 @@
 #include "warnless.h"
 #include "http_proxy.h"
 #include "non-ascii.h"
+#include "socks.h"
 /* The last 3 #include files should be in this order */
 #include "curl_printf.h"
 #include "curl_memory.h"
@@ -113,7 +113,7 @@
 static CURLcode ftp_regular_transfer(struct connectdata *conn, bool *done);
 #ifndef CURL_DISABLE_VERBOSE_STRINGS
 static void ftp_pasv_verbose(struct connectdata *conn,
-                             Curl_addrinfo *ai,
+                             struct Curl_addrinfo *ai,
                              char *newhost, /* ascii version */
                              int port);
 #endif
@@ -132,13 +132,11 @@
 static CURLcode ftp_disconnect(struct connectdata *conn, bool dead_connection);
 static CURLcode ftp_do_more(struct connectdata *conn, int *completed);
 static CURLcode ftp_multi_statemach(struct connectdata *conn, bool *done);
-static int ftp_getsock(struct connectdata *conn, curl_socket_t *socks,
-                       int numsocks);
-static int ftp_domore_getsock(struct connectdata *conn, curl_socket_t *socks,
-                              int numsocks);
+static int ftp_getsock(struct connectdata *conn, curl_socket_t *socks);
+static int ftp_domore_getsock(struct connectdata *conn, curl_socket_t *socks);
 static CURLcode ftp_doing(struct connectdata *conn,
                           bool *dophase_done);
-static CURLcode ftp_setup_connection(struct connectdata * conn);
+static CURLcode ftp_setup_connection(struct connectdata *conn);
 
 static CURLcode init_wc_data(struct connectdata *conn);
 static CURLcode wc_statemach(struct connectdata *conn);
@@ -223,6 +221,9 @@
     conn->sock[SECONDARYSOCKET] = CURL_SOCKET_BAD;
   }
   conn->bits.tcpconnect[SECONDARYSOCKET] = FALSE;
+#ifndef CURL_DISABLE_PROXY
+  conn->bits.proxy_ssl_connected[SECONDARYSOCKET] = FALSE;
+#endif
 }
 
 /*
@@ -255,18 +256,6 @@
   Curl_safefree(ftpc->newhost);
 }
 
-/* Returns non-zero if the given string contains CR (\r) or LF (\n),
-   which are not allowed within RFC 959 <string>.
-   Note: The input string is in the client's encoding which might
-   not be ASCII, so escape sequences \r & \n must be used instead
-   of hex values 0x0d & 0x0a.
-*/
-static bool isBadFtpString(const char *string)
-{
-  return ((NULL != strchr(string, '\r')) ||
-          (NULL != strchr(string, '\n'))) ? TRUE : FALSE;
-}
-
 /***********************************************************************
  *
  * AcceptServerConnect()
@@ -305,7 +294,7 @@
 
   conn->sock[SECONDARYSOCKET] = s;
   (void)curlx_nonblock(s, TRUE); /* enable non-blocking */
-  conn->sock_accepted[SECONDARYSOCKET] = TRUE;
+  conn->bits.sock_accepted = TRUE;
 
   if(data->set.fsockopt) {
     int error = 0;
@@ -348,7 +337,7 @@
   now = Curl_now();
 
   /* check if the generic timeout possibly is set shorter */
-  other =  Curl_timeleft(data, &now, FALSE);
+  other = Curl_timeleft(data, &now, FALSE);
   if(other && (other < timeout_ms))
     /* note that this also works fine for when other happens to be negative
        due to it already having elapsed */
@@ -382,7 +371,7 @@
   struct ftp_conn *ftpc = &conn->proto.ftpc;
   struct pingpong *pp = &ftpc->pp;
   int result;
-  time_t timeout_ms;
+  timediff_t timeout_ms;
   ssize_t nread;
   int ftpcode;
 
@@ -400,7 +389,7 @@
   if(pp->cache_size && pp->cache && pp->cache[0] > '3') {
     /* Data connection could not be established, let's return */
     infof(data, "There is negative response in cache while serv connect\n");
-    Curl_GetFTPResponse(&nread, conn, &ftpcode);
+    (void)Curl_GetFTPResponse(&nread, conn, &ftpcode);
     return CURLE_FTP_ACCEPT_FAILED;
   }
 
@@ -422,7 +411,7 @@
     }
     else if(result & CURL_CSELECT_IN) {
       infof(data, "Ctrl conn has data while waiting for data conn\n");
-      Curl_GetFTPResponse(&nread, conn, &ftpcode);
+      (void)Curl_GetFTPResponse(&nread, conn, &ftpcode);
 
       if(ftpcode/100 > 3)
         return CURLE_FTP_ACCEPT_FAILED;
@@ -493,7 +482,7 @@
 static CURLcode AllowServerConnect(struct connectdata *conn, bool *connected)
 {
   struct Curl_easy *data = conn->data;
-  time_t timeout_ms;
+  timediff_t timeout_ms;
   CURLcode result = CURLE_OK;
 
   *connected = FALSE;
@@ -525,7 +514,7 @@
   }
   else {
     /* Add timeout to multi handle and break out of the loop */
-    if(!result && *connected == FALSE) {
+    if(*connected == FALSE) {
       Curl_expire(data, data->set.accepttimeout > 0 ?
                   data->set.accepttimeout: DEFAULT_ACCEPT_TIMEOUT, 0);
     }
@@ -565,10 +554,8 @@
 #ifdef HAVE_GSSAPI
   char * const buf = data->state.buffer;
 #endif
-  CURLcode result = CURLE_OK;
   int code;
-
-  result = Curl_pp_readresp(sockfd, pp, &code, size);
+  CURLcode result = Curl_pp_readresp(sockfd, pp, &code, size);
 
 #if defined(HAVE_GSSAPI)
   /* handle the security-oriented responses 6xx ***/
@@ -648,8 +635,8 @@
 
   while(!*ftpcode && !result) {
     /* check and reset timeout value every lap */
-    time_t timeout = Curl_pp_state_timeout(pp, FALSE);
-    time_t interval_ms;
+    timediff_t timeout = Curl_pp_state_timeout(pp, FALSE);
+    timediff_t interval_ms;
 
     if(timeout <= 0) {
       failf(data, "FTP response timeout");
@@ -789,9 +776,8 @@
 static CURLcode ftp_state_user(struct connectdata *conn)
 {
   CURLcode result;
-  struct FTP *ftp = conn->data->req.protop;
   /* send USER */
-  PPSENDF(&conn->proto.ftpc.pp, "USER %s", ftp->user?ftp->user:"");
+  PPSENDF(&conn->proto.ftpc.pp, "USER %s", conn->user?conn->user:"");
 
   state(conn, FTP_USER);
   conn->data->state.ftp_trying_alternative = FALSE;
@@ -812,28 +798,27 @@
 
 /* For the FTP "protocol connect" and "doing" phases only */
 static int ftp_getsock(struct connectdata *conn,
-                       curl_socket_t *socks,
-                       int numsocks)
+                       curl_socket_t *socks)
 {
-  return Curl_pp_getsock(&conn->proto.ftpc.pp, socks, numsocks);
+  return Curl_pp_getsock(&conn->proto.ftpc.pp, socks);
 }
 
 /* For the FTP "DO_MORE" phase only */
-static int ftp_domore_getsock(struct connectdata *conn, curl_socket_t *socks,
-                              int numsocks)
+static int ftp_domore_getsock(struct connectdata *conn, curl_socket_t *socks)
 {
   struct ftp_conn *ftpc = &conn->proto.ftpc;
 
-  if(!numsocks)
-    return GETSOCK_BLANK;
-
   /* When in DO_MORE state, we could be either waiting for us to connect to a
    * remote site, or we could wait for that site to connect to us. Or just
    * handle ordinary commands.
    */
 
+  if(SOCKS_STATE(conn->cnnct.state))
+    return Curl_SOCKS_getsock(conn, socks, SECONDARYSOCKET);
+
   if(FTP_STOP == ftpc->state) {
     int bits = GETSOCK_READSOCK(0);
+    bool any = FALSE;
 
     /* if stopped and still in this state, then we're also waiting for a
        connect on the secondary connection */
@@ -848,17 +833,18 @@
         if(conn->tempsock[i] != CURL_SOCKET_BAD) {
           socks[s] = conn->tempsock[i];
           bits |= GETSOCK_WRITESOCK(s++);
+          any = TRUE;
         }
       }
     }
-    else {
+    if(!any) {
       socks[1] = conn->sock[SECONDARYSOCKET];
       bits |= GETSOCK_WRITESOCK(1) | GETSOCK_READSOCK(1);
     }
 
     return bits;
   }
-  return Curl_pp_getsock(&conn->proto.ftpc.pp, socks, numsocks);
+  return Curl_pp_getsock(&conn->proto.ftpc.pp, socks);
 }
 
 /* This is called after the FTP_QUOTE state is passed.
@@ -876,6 +862,10 @@
     /* already done and fine */
     result = ftp_state_mdtm(conn);
   else {
+    /* FTPFILE_NOCWD with full path: expect ftpc->cwddone! */
+    DEBUGASSERT((conn->data->set.ftp_filemethod != FTPFILE_NOCWD) ||
+                !(ftpc->dirdepth && ftpc->dirs[0][0] == '/'));
+
     ftpc->count2 = 0; /* count2 counts failed CWDs */
 
     /* count3 is set to allow a MKD to fail once. In the case when first CWD
@@ -883,10 +873,9 @@
        dir) this then allows for a second try to CWD to it */
     ftpc->count3 = (conn->data->set.ftp_create_missing_dirs == 2)?1:0;
 
-    if((conn->data->set.ftp_filemethod == FTPFILE_NOCWD) && !ftpc->cwdcount)
-      /* No CWD necessary */
-      result = ftp_state_mdtm(conn);
-    else if(conn->bits.reuse && ftpc->entrypath) {
+    if(conn->bits.reuse && ftpc->entrypath &&
+       /* no need to go to entrypath when we have an absolute path */
+       !(ftpc->dirdepth && ftpc->dirs[0][0] == '/')) {
       /* This is a re-used connection. Since we change directory to where the
          transfer is taking place, we must first get back to the original dir
          where we ended up after login: */
@@ -926,10 +915,10 @@
   struct ftp_conn *ftpc = &conn->proto.ftpc;
   struct Curl_easy *data = conn->data;
   curl_socket_t portsock = CURL_SOCKET_BAD;
-  char myhost[256] = "";
+  char myhost[MAX_IPADR_LEN + 1] = "";
 
   struct Curl_sockaddr_storage ss;
-  Curl_addrinfo *res, *ai;
+  struct Curl_addrinfo *res, *ai;
   curl_socklen_t sslen;
   char hbuf[NI_MAXHOST];
   struct sockaddr *sa = (struct sockaddr *)&ss;
@@ -937,9 +926,8 @@
 #ifdef ENABLE_IPV6
   struct sockaddr_in6 * const sa6 = (void *)sa;
 #endif
-  char tmp[1024];
   static const char mode[][5] = { "EPRT", "PORT" };
-  int rc;
+  enum resolve_t rc;
   int error;
   char *host = NULL;
   char *string_ftpport = data->set.str[STRING_FTPPORT];
@@ -1055,6 +1043,7 @@
   } /* data->set.ftpport */
 
   if(!host) {
+    const char *r;
     /* not an interface and not a host name, get default by extracting
        the IP from the control connection */
     sslen = sizeof(ss);
@@ -1067,13 +1056,15 @@
     switch(sa->sa_family) {
 #ifdef ENABLE_IPV6
     case AF_INET6:
-      Curl_inet_ntop(sa->sa_family, &sa6->sin6_addr, hbuf, sizeof(hbuf));
+      r = Curl_inet_ntop(sa->sa_family, &sa6->sin6_addr, hbuf, sizeof(hbuf));
       break;
 #endif
     default:
-      Curl_inet_ntop(sa->sa_family, &sa4->sin_addr, hbuf, sizeof(hbuf));
+      r = Curl_inet_ntop(sa->sa_family, &sa4->sin_addr, hbuf, sizeof(hbuf));
       break;
     }
+    if(!r)
+      return CURLE_FTP_PORT_FAILED;
     host = hbuf; /* use this host name */
     possibly_non_local = FALSE; /* we know it is local now */
   }
@@ -1252,8 +1243,10 @@
       break;
     }
     if(PORT == fcmd) {
+      /* large enough for [IP address],[num],[num] */
+      char target[sizeof(myhost) + 20];
       char *source = myhost;
-      char *dest = tmp;
+      char *dest = target;
 
       /* translate x.x.x.x to x,x,x,x */
       while(source && *source) {
@@ -1267,7 +1260,7 @@
       *dest = 0;
       msnprintf(dest, 20, ",%d,%d", (int)(port>>8), (int)(port&0xff));
 
-      result = Curl_pp_sendf(&ftpc->pp, "%s %s", mode[fcmd], tmp);
+      result = Curl_pp_sendf(&ftpc->pp, "%s %s", mode[fcmd], target);
       if(result) {
         failf(data, "Failure sending PORT command: %s",
               curl_easy_strerror(result));
@@ -1308,7 +1301,7 @@
   struct ftp_conn *ftpc = &conn->proto.ftpc;
   CURLcode result = CURLE_OK;
   /*
-    Here's the excecutive summary on what to do:
+    Here's the executive summary on what to do:
 
     PASV is RFC959, expect:
     227 Entering Passive Mode (a1,a2,a3,a4,p1,p2)
@@ -1445,31 +1438,37 @@
      servers either... */
 
   /*
-     if FTPFILE_NOCWD was specified, we are currently in
-     the user's home directory, so we should add the path
+     if FTPFILE_NOCWD was specified, we should add the path
      as argument for the LIST / NLST / or custom command.
      Whether the server will support this, is uncertain.
 
      The other ftp_filemethods will CWD into dir/dir/ first and
      then just do LIST (in that case: nothing to do here)
   */
-  char *cmd, *lstArg, *slashPos;
-  const char *inpath = ftp->path;
+  char *lstArg = NULL;
+  char *cmd;
 
-  lstArg = NULL;
-  if((data->set.ftp_filemethod == FTPFILE_NOCWD) &&
-     inpath && inpath[0] && strchr(inpath, '/')) {
-    size_t n = strlen(inpath);
-
-    /* Check if path does not end with /, as then we cut off the file part */
-    if(inpath[n - 1] != '/') {
-      /* chop off the file part if format is dir/dir/file */
-      slashPos = strrchr(inpath, '/');
-      n = slashPos - inpath;
-    }
-    result = Curl_urldecode(data, inpath, n, &lstArg, NULL, TRUE);
+  if((data->set.ftp_filemethod == FTPFILE_NOCWD) && ftp->path) {
+    /* url-decode before evaluation: e.g. paths starting/ending with %2f */
+    const char *slashPos = NULL;
+    char *rawPath = NULL;
+    result = Curl_urldecode(data, ftp->path, 0, &rawPath, NULL, REJECT_CTRL);
     if(result)
       return result;
+
+    slashPos = strrchr(rawPath, '/');
+    if(slashPos) {
+      /* chop off the file part if format is dir/file otherwise remove
+         the trailing slash for dir/dir/ except for absolute path / */
+      size_t n = slashPos - rawPath;
+      if(n == 0)
+        ++n;
+
+      lstArg = rawPath;
+      lstArg[n] = '\0';
+    }
+    else
+      free(rawPath);
   }
 
   cmd = aprintf("%s%s%s",
@@ -1478,15 +1477,12 @@
                 (data->set.ftp_list_only?"NLST":"LIST"),
                 lstArg? " ": "",
                 lstArg? lstArg: "");
+  free(lstArg);
 
-  if(!cmd) {
-    free(lstArg);
+  if(!cmd)
     return CURLE_OUT_OF_MEMORY;
-  }
 
   result = Curl_pp_sendf(&conn->proto.ftpc.pp, "%s", cmd);
-
-  free(lstArg);
   free(cmd);
 
   if(result)
@@ -1499,24 +1495,14 @@
 
 static CURLcode ftp_state_retr_prequote(struct connectdata *conn)
 {
-  CURLcode result = CURLE_OK;
-
   /* We've sent the TYPE, now we must send the list of prequote strings */
-
-  result = ftp_state_quote(conn, TRUE, FTP_RETR_PREQUOTE);
-
-  return result;
+  return ftp_state_quote(conn, TRUE, FTP_RETR_PREQUOTE);
 }
 
 static CURLcode ftp_state_stor_prequote(struct connectdata *conn)
 {
-  CURLcode result = CURLE_OK;
-
   /* We've sent the TYPE, now we must send the list of prequote strings */
-
-  result = ftp_state_quote(conn, TRUE, FTP_STOR_PREQUOTE);
-
-  return result;
+  return ftp_state_quote(conn, TRUE, FTP_STOR_PREQUOTE);
 }
 
 static CURLcode ftp_state_type(struct connectdata *conn)
@@ -1781,7 +1767,11 @@
 {
   CURLcode result = CURLE_OK;
 
-  if(conn->bits.ipv6 && !(conn->bits.tunnel_proxy || conn->bits.socksproxy)) {
+  if(conn->bits.ipv6
+#ifndef CURL_DISABLE_PROXY
+     && !(conn->bits.tunnel_proxy || conn->bits.socksproxy)
+#endif
+    ) {
     /* We can't disable EPSV when doing IPv6, so this is instead a fail */
     failf(conn->data, "Failed EPSV attempt, exiting\n");
     return CURLE_WEIRD_SERVER_REPLY;
@@ -1806,9 +1796,10 @@
      If a proxy tunnel is used, returns the original host name instead, because
      the effective control connection address is the proxy address,
      not the ftp host. */
+#ifndef CURL_DISABLE_PROXY
   if(conn->bits.tunnel_proxy || conn->bits.socksproxy)
     return conn->host.name;
-
+#endif
   return conn->ip_addr_str;
 }
 
@@ -1819,7 +1810,7 @@
   CURLcode result;
   struct Curl_easy *data = conn->data;
   struct Curl_dns_entry *addr = NULL;
-  int rc;
+  enum resolve_t rc;
   unsigned short connectport; /* the local port connect() should use! */
   char *str = &data->state.buffer[4];  /* start on the first letter */
 
@@ -1925,6 +1916,7 @@
     return CURLE_FTP_WEIRD_PASV_REPLY;
   }
 
+#ifndef CURL_DISABLE_PROXY
   if(conn->bits.proxy) {
     /*
      * This connection uses a proxy and we need to connect to the proxy again
@@ -1947,7 +1939,9 @@
       return CURLE_COULDNT_RESOLVE_PROXY;
     }
   }
-  else {
+  else
+#endif
+  {
     /* normal, direct, ftp connection */
     rc = Curl_resolv(conn, ftpc->newhost, ftpc->newport, FALSE, &addr);
     if(rc == CURLRESOLV_PENDING)
@@ -2052,13 +2046,11 @@
                      &year, &month, &day, &hour, &minute, &second)) {
         /* we have a time, reformat it */
         char timebuf[24];
-        time_t secs = time(NULL);
-
         msnprintf(timebuf, sizeof(timebuf),
                   "%04d%02d%02d %02d:%02d:%02d GMT",
                   year, month, day, hour, minute, second);
         /* now, convert this into a time() value: */
-        data->info.filetime = curl_getdate(timebuf, &secs);
+        data->info.filetime = Curl_getdate_capped(timebuf);
       }
 
 #ifdef CURL_FTP_HTTPSTYLE_HEAD
@@ -2261,9 +2253,25 @@
   char *buf = data->state.buffer;
 
   /* get the size from the ascii string: */
-  if(ftpcode == 213)
+  if(ftpcode == 213) {
+    /* To allow servers to prepend "rubbish" in the response string, we scan
+       for all the digits at the end of the response and parse only those as a
+       number. */
+    char *start = &buf[4];
+    char *fdigit = strchr(start, '\r');
+    if(fdigit) {
+      do
+        fdigit--;
+      while(ISDIGIT(*fdigit) && (fdigit > start));
+      if(!ISDIGIT(*fdigit))
+        fdigit++;
+    }
+    else
+      fdigit = start;
     /* ignores parsing errors, which will make the size remain unknown */
-    (void)curlx_strtoofft(buf + 4, NULL, 0, &filesize);
+    (void)curlx_strtoofft(fdigit, NULL, 0, &filesize);
+
+  }
 
   if(instate == FTP_SIZE) {
 #ifdef CURL_FTP_HTTPSTYLE_HEAD
@@ -2527,7 +2535,6 @@
 {
   CURLcode result = CURLE_OK;
   struct Curl_easy *data = conn->data;
-  struct FTP *ftp = data->req.protop;
   struct ftp_conn *ftpc = &conn->proto.ftpc;
   (void)instate; /* no use for this yet */
 
@@ -2535,7 +2542,7 @@
   if((ftpcode == 331) && (ftpc->state == FTP_USER)) {
     /* 331 Password required for ...
        (the server requires to send the user's password too) */
-    PPSENDF(&ftpc->pp, "PASS %s", ftp->passwd?ftp->passwd:"");
+    PPSENDF(&ftpc->pp, "PASS %s", conn->passwd?conn->passwd:"");
     state(conn, FTP_PASS);
   }
   else if(ftpcode/100 == 2) {
@@ -2643,9 +2650,12 @@
 #endif
 
       if(data->set.use_ssl &&
-         (!conn->ssl[FIRSTSOCKET].use ||
-          (conn->bits.proxy_ssl_connected[FIRSTSOCKET] &&
-           !conn->proxy_ssl[FIRSTSOCKET].use))) {
+         (!conn->ssl[FIRSTSOCKET].use
+#ifndef CURL_DISABLE_PROXY
+          || (conn->bits.proxy_ssl_connected[FIRSTSOCKET] &&
+              !conn->proxy_ssl[FIRSTSOCKET].use)
+#endif
+           )) {
         /* We don't have a SSL/TLS connection yet, but FTPS is
            requested. Try a FTPS connection now */
 
@@ -2817,7 +2827,7 @@
             store++;
             ptr++;
           }
-          *store = '\0'; /* zero terminate */
+          *store = '\0'; /* null-terminate */
         }
         if(entry_extracted) {
           /* If the path name does not look like an absolute path (i.e.: it
@@ -2881,7 +2891,7 @@
           ptr++;
         for(store = os; *ptr && *ptr != ' ';)
           *store++ = *ptr++;
-        *store = '\0'; /* zero terminate */
+        *store = '\0'; /* null-terminate */
 
         /* Check for special servers here. */
 
@@ -3134,7 +3144,8 @@
   ssize_t nread;
   int ftpcode;
   CURLcode result = CURLE_OK;
-  char *path = NULL;
+  char *rawPath = NULL;
+  size_t pathLen = 0;
 
   if(!ftp)
     return CURLE_OK;
@@ -3172,9 +3183,6 @@
     break;
   }
 
-  /* now store a copy of the directory we are in */
-  free(ftpc->prevpath);
-
   if(data->state.wildcardmatch) {
     if(data->set.chunk_end && ftpc->file) {
       Curl_set_in_callback(data, true);
@@ -3185,41 +3193,42 @@
   }
 
   if(!result)
-    /* get the "raw" path */
-    result = Curl_urldecode(data, ftp->path, 0, &path, NULL, TRUE);
+    /* get the url-decoded "raw" path */
+    result = Curl_urldecode(data, ftp->path, 0, &rawPath, &pathLen,
+                            REJECT_CTRL);
   if(result) {
     /* We can limp along anyway (and should try to since we may already be in
      * the error path) */
     ftpc->ctl_valid = FALSE; /* mark control connection as bad */
     connclose(conn, "FTP: out of memory!"); /* mark for connection closure */
+    free(ftpc->prevpath);
     ftpc->prevpath = NULL; /* no path remembering */
   }
-  else {
-    size_t flen = ftpc->file?strlen(ftpc->file):0; /* file is "raw" already */
-    size_t dlen = strlen(path)-flen;
-    if(!ftpc->cwdfail) {
-      ftpc->prevmethod = data->set.ftp_filemethod;
-      if(dlen && (data->set.ftp_filemethod != FTPFILE_NOCWD)) {
-        ftpc->prevpath = path;
-        if(flen)
-          /* if 'path' is not the whole string */
-          ftpc->prevpath[dlen] = 0; /* terminate */
+  else { /* remember working directory for connection reuse */
+    if((data->set.ftp_filemethod == FTPFILE_NOCWD) && (rawPath[0] == '/'))
+      free(rawPath); /* full path => no CWDs happened => keep ftpc->prevpath */
+    else {
+      free(ftpc->prevpath);
+
+      if(!ftpc->cwdfail) {
+        if(data->set.ftp_filemethod == FTPFILE_NOCWD)
+          pathLen = 0; /* relative path => working directory is FTP home */
+        else
+          pathLen -= ftpc->file?strlen(ftpc->file):0; /* file is url-decoded */
+
+        rawPath[pathLen] = '\0';
+        ftpc->prevpath = rawPath;
       }
       else {
-        free(path);
-        /* we never changed dir */
-        ftpc->prevpath = strdup("");
-        if(!ftpc->prevpath)
-          return CURLE_OUT_OF_MEMORY;
+        free(rawPath);
+        ftpc->prevpath = NULL; /* no path */
       }
-      if(ftpc->prevpath)
-        infof(data, "Remembering we are in dir \"%s\"\n", ftpc->prevpath);
     }
-    else {
-      ftpc->prevpath = NULL; /* no path */
-      free(path);
-    }
+
+    if(ftpc->prevpath)
+      infof(data, "Remembering we are in dir \"%s\"\n", ftpc->prevpath);
   }
+
   /* free the dir tree and file parts */
   freedirs(ftpc);
 
@@ -3242,9 +3251,9 @@
     }
 
     if(conn->ssl[SECONDARYSOCKET].use) {
-      /* The secondary socket is using SSL so we must close down that part
-         first before we close the socket for real */
-      Curl_ssl_close(conn, SECONDARYSOCKET);
+      /* The secondary socket used SSL so we must close down that part first
+         before we close the socket for real */
+      result = Curl_ssl_shutdown(conn, SECONDARYSOCKET);
 
       /* Note that we keep "use" set to TRUE since that (next) connection is
          still requested to use SSL */
@@ -3260,7 +3269,7 @@
      * data has been transferred. This happens when doing through NATs etc that
      * abandon old silent connections.
      */
-    long old_time = pp->response_time;
+    timediff_t old_time = pp->response_time;
 
     pp->response_time = 60*1000; /* give it only a minute for now */
     pp->response = Curl_now(); /* timeout relative now */
@@ -3453,7 +3462,7 @@
 #ifndef CURL_DISABLE_VERBOSE_STRINGS
 static void
 ftp_pasv_verbose(struct connectdata *conn,
-                 Curl_addrinfo *ai,
+                 struct Curl_addrinfo *ai,
                  char *newhost, /* ascii version */
                  int port)
 {
@@ -3511,6 +3520,7 @@
     }
   }
 
+#ifndef CURL_DISABLE_PROXY
   result = Curl_proxy_connect(conn, SECONDARYSOCKET);
   if(result)
     return result;
@@ -3521,7 +3531,7 @@
   if(conn->bits.tunnel_proxy && conn->bits.httpproxy &&
      Curl_connect_ongoing(conn))
     return result;
-
+#endif
 
   if(ftpc->state) {
     /* already in a state so skip the initial commands.
@@ -3532,14 +3542,13 @@
 
     /* if we got an error or if we don't wait for a data connection return
        immediately */
-    if(result || (ftpc->wait_data_conn != TRUE))
+    if(result || !ftpc->wait_data_conn)
       return result;
 
-    if(ftpc->wait_data_conn)
-      /* if we reach the end of the FTP state machine here, *complete will be
-         TRUE but so is ftpc->wait_data_conn, which says we need to wait for
-         the data connection and therefore we're not actually complete */
-      *completep = 0;
+    /* if we reach the end of the FTP state machine here, *complete will be
+       TRUE but so is ftpc->wait_data_conn, which says we need to wait for the
+       data connection and therefore we're not actually complete */
+    *completep = 0;
   }
 
   if(ftp->transfer <= FTPTRANSFER_INFO) {
@@ -3573,13 +3582,8 @@
         return result;
 
       result = ftp_multi_statemach(conn, &complete);
-      if(ftpc->wait_data_conn)
-        /* if we reach the end of the FTP state machine here, *complete will be
-           TRUE but so is ftpc->wait_data_conn, which says we need to wait for
-           the data connection and therefore we're not actually complete */
-        *completep = 0;
-      else
-        *completep = (int)complete;
+      /* ftpc->wait_data_conn is always false here */
+      *completep = (int)complete;
     }
     else {
       /* download */
@@ -3619,10 +3623,8 @@
     return result;
   }
 
-  if(!result && (ftp->transfer != FTPTRANSFER_BODY))
-    /* no data to transfer. FIX: it feels like a kludge to have this here
-       too! */
-    Curl_setup_transfer(data, -1, -1, FALSE, -1);
+  /* no data to transfer */
+  Curl_setup_transfer(data, -1, -1, FALSE, -1);
 
   if(!ftpc->wait_data_conn) {
     /* no waiting for the data connection so this is now complete */
@@ -4100,186 +4102,142 @@
   /* the ftp struct is already inited in ftp_connect() */
   struct FTP *ftp = data->req.protop;
   struct ftp_conn *ftpc = &conn->proto.ftpc;
-  const char *slash_pos;  /* position of the first '/' char in curpos */
-  const char *path_to_use = ftp->path;
-  const char *cur_pos;
-  const char *filename = NULL;
-
-  cur_pos = path_to_use; /* current position in path. point at the begin of
-                            next path component */
+  const char *slashPos = NULL;
+  const char *fileName = NULL;
+  CURLcode result = CURLE_OK;
+  char *rawPath = NULL; /* url-decoded "raw" path */
+  size_t pathLen = 0;
 
   ftpc->ctl_valid = FALSE;
   ftpc->cwdfail = FALSE;
 
+  /* url-decode ftp path before further evaluation */
+  result = Curl_urldecode(data, ftp->path, 0, &rawPath, &pathLen, REJECT_CTRL);
+  if(result)
+    return result;
+
   switch(data->set.ftp_filemethod) {
-  case FTPFILE_NOCWD:
-    /* fastest, but less standard-compliant */
+    case FTPFILE_NOCWD: /* fastest, but less standard-compliant */
 
-    /*
-      The best time to check whether the path is a file or directory is right
-      here. so:
-
-      the first condition in the if() right here, is there just in case
-      someone decides to set path to NULL one day
-   */
-    if(path_to_use[0] &&
-       (path_to_use[strlen(path_to_use) - 1] != '/') )
-      filename = path_to_use;  /* this is a full file path */
-    /*
-      else {
-        ftpc->file is not used anywhere other than for operations on a file.
-        In other words, never for directory operations.
-        So we can safely leave filename as NULL here and use it as a
-        argument in dir/file decisions.
-      }
-    */
-    break;
-
-  case FTPFILE_SINGLECWD:
-    /* get the last slash */
-    if(!path_to_use[0]) {
-      /* no dir, no file */
-      ftpc->dirdepth = 0;
+      if((pathLen > 0) && (rawPath[pathLen - 1] != '/'))
+          fileName = rawPath;  /* this is a full file path */
+      /*
+        else: ftpc->file is not used anywhere other than for operations on
+              a file. In other words, never for directory operations.
+              So we can safely leave filename as NULL here and use it as a
+              argument in dir/file decisions.
+      */
       break;
-    }
-    slash_pos = strrchr(cur_pos, '/');
-    if(slash_pos || !*cur_pos) {
-      size_t dirlen = slash_pos-cur_pos;
-      CURLcode result;
 
-      ftpc->dirs = calloc(1, sizeof(ftpc->dirs[0]));
-      if(!ftpc->dirs)
-        return CURLE_OUT_OF_MEMORY;
+    case FTPFILE_SINGLECWD:
+      slashPos = strrchr(rawPath, '/');
+      if(slashPos) {
+        /* get path before last slash, except for / */
+        size_t dirlen = slashPos - rawPath;
+        if(dirlen == 0)
+            dirlen++;
 
-      if(!dirlen)
-        dirlen++;
+        ftpc->dirs = calloc(1, sizeof(ftpc->dirs[0]));
+        if(!ftpc->dirs) {
+          free(rawPath);
+          return CURLE_OUT_OF_MEMORY;
+        }
 
-      result = Curl_urldecode(conn->data, slash_pos ? cur_pos : "/",
-                              slash_pos ? dirlen : 1,
-                              &ftpc->dirs[0], NULL,
-                              TRUE);
-      if(result) {
-        freedirs(ftpc);
-        return result;
+        ftpc->dirs[0] = calloc(1, dirlen + 1);
+        if(!ftpc->dirs[0]) {
+          free(rawPath);
+          return CURLE_OUT_OF_MEMORY;
+        }
+
+        strncpy(ftpc->dirs[0], rawPath, dirlen);
+        ftpc->dirdepth = 1; /* we consider it to be a single dir */
+        fileName = slashPos + 1; /* rest is file name */
       }
-      ftpc->dirdepth = 1; /* we consider it to be a single dir */
-      filename = slash_pos ? slash_pos + 1 : cur_pos; /* rest is file name */
-    }
-    else
-      filename = cur_pos;  /* this is a file name only */
-    break;
+      else
+        fileName = rawPath; /* file name only (or empty) */
+      break;
 
-  default: /* allow pretty much anything */
-  case FTPFILE_MULTICWD:
-    ftpc->dirdepth = 0;
-    ftpc->diralloc = 5; /* default dir depth to allocate */
-    ftpc->dirs = calloc(ftpc->diralloc, sizeof(ftpc->dirs[0]));
-    if(!ftpc->dirs)
-      return CURLE_OUT_OF_MEMORY;
+    default: /* allow pretty much anything */
+    case FTPFILE_MULTICWD: {
+      /* current position: begin of next path component */
+      const char *curPos = rawPath;
 
-    /* we have a special case for listing the root dir only */
-    if(!strcmp(path_to_use, "/")) {
-      cur_pos++; /* make it point to the zero byte */
-      ftpc->dirs[0] = strdup("/");
-      ftpc->dirdepth++;
-    }
-    else {
-      /* parse the URL path into separate path components */
-      while((slash_pos = strchr(cur_pos, '/')) != NULL) {
-        /* 1 or 0 pointer offset to indicate absolute directory */
-        ssize_t absolute_dir = ((cur_pos - ftp->path > 0) &&
-                                (ftpc->dirdepth == 0))?1:0;
+      int dirAlloc = 0; /* number of entries allocated for the 'dirs' array */
+      const char *str = rawPath;
+      for(; *str != 0; ++str)
+        if (*str == '/')
+          ++dirAlloc;
 
-        /* seek out the next path component */
-        if(slash_pos-cur_pos) {
+      if(dirAlloc > 0) {
+        ftpc->dirs = calloc(dirAlloc, sizeof(ftpc->dirs[0]));
+        if(!ftpc->dirs) {
+          free(rawPath);
+          return CURLE_OUT_OF_MEMORY;
+        }
+
+        /* parse the URL path into separate path components */
+        while((slashPos = strchr(curPos, '/')) != NULL) {
+          size_t compLen = slashPos - curPos;
+
+          /* path starts with a slash: add that as a directory */
+          if((compLen == 0) && (ftpc->dirdepth == 0))
+            ++compLen;
+
           /* we skip empty path components, like "x//y" since the FTP command
              CWD requires a parameter and a non-existent parameter a) doesn't
              work on many servers and b) has no effect on the others. */
-          size_t len = slash_pos - cur_pos + absolute_dir;
-          CURLcode result =
-            Curl_urldecode(conn->data, cur_pos - absolute_dir, len,
-                           &ftpc->dirs[ftpc->dirdepth], NULL,
-                           TRUE);
-          if(result) {
-            freedirs(ftpc);
-            return result;
-          }
-        }
-        else {
-          cur_pos = slash_pos + 1; /* jump to the rest of the string */
-          if(!ftpc->dirdepth) {
-            /* path starts with a slash, add that as a directory */
-            ftpc->dirs[ftpc->dirdepth] = strdup("/");
-            if(!ftpc->dirs[ftpc->dirdepth++]) { /* run out of memory ... */
-              failf(data, "no memory");
-              freedirs(ftpc);
+          if(compLen > 0) {
+            char *comp = calloc(1, compLen + 1);
+            if(!comp) {
+              free(rawPath);
               return CURLE_OUT_OF_MEMORY;
             }
+            strncpy(comp, curPos, compLen);
+            ftpc->dirs[ftpc->dirdepth++] = comp;
           }
-          continue;
-        }
-
-        cur_pos = slash_pos + 1; /* jump to the rest of the string */
-        if(++ftpc->dirdepth >= ftpc->diralloc) {
-          /* enlarge array */
-          char **bigger;
-          ftpc->diralloc *= 2; /* double the size each time */
-          bigger = realloc(ftpc->dirs, ftpc->diralloc * sizeof(ftpc->dirs[0]));
-          if(!bigger) {
-            freedirs(ftpc);
-            return CURLE_OUT_OF_MEMORY;
-          }
-          ftpc->dirs = bigger;
+          curPos = slashPos + 1;
         }
       }
+      DEBUGASSERT(ftpc->dirdepth <= dirAlloc);
+      fileName = curPos; /* the rest is the file name (or empty) */
     }
-    filename = cur_pos;  /* the rest is the file name */
     break;
   } /* switch */
 
-  if(filename && *filename) {
-    CURLcode result =
-      Curl_urldecode(conn->data, filename, 0,  &ftpc->file, NULL, TRUE);
-
-    if(result) {
-      freedirs(ftpc);
-      return result;
-    }
-  }
+  if(fileName && *fileName)
+    ftpc->file = strdup(fileName);
   else
-    ftpc->file = NULL; /* instead of point to a zero byte, we make it a NULL
-                          pointer */
+    ftpc->file = NULL; /* instead of point to a zero byte,
+                            we make it a NULL pointer */
 
   if(data->set.upload && !ftpc->file && (ftp->transfer == FTPTRANSFER_BODY)) {
     /* We need a file name when uploading. Return error! */
     failf(data, "Uploading to a URL without a file name!");
+    free(rawPath);
     return CURLE_URL_MALFORMAT;
   }
 
   ftpc->cwddone = FALSE; /* default to not done */
 
-  if(ftpc->prevpath) {
-    /* prevpath is "raw" so we convert the input path before we compare the
-       strings */
-    size_t dlen;
-    char *path;
-    CURLcode result =
-      Curl_urldecode(conn->data, ftp->path, 0, &path, &dlen, TRUE);
-    if(result) {
-      freedirs(ftpc);
-      return result;
-    }
+  if((data->set.ftp_filemethod == FTPFILE_NOCWD) && (rawPath[0] == '/'))
+    ftpc->cwddone = TRUE; /* skip CWD for absolute paths */
+  else { /* newly created FTP connections are already in entry path */
+    const char *oldPath = conn->bits.reuse ? ftpc->prevpath : "";
+    if(oldPath) {
+      size_t n = pathLen;
+      if(data->set.ftp_filemethod == FTPFILE_NOCWD)
+        n = 0; /* CWD to entry for relative paths */
+      else
+        n -= ftpc->file?strlen(ftpc->file):0;
 
-    dlen -= ftpc->file?strlen(ftpc->file):0;
-    if((dlen == strlen(ftpc->prevpath)) &&
-       !strncmp(path, ftpc->prevpath, dlen) &&
-       (ftpc->prevmethod == data->set.ftp_filemethod)) {
-      infof(data, "Request has same path as previous transfer\n");
-      ftpc->cwddone = TRUE;
+      if((strlen(oldPath) == n) && !strncmp(rawPath, oldPath, n)) {
+        infof(data, "Request has same path as previous transfer\n");
+        ftpc->cwddone = TRUE;
+      }
     }
-    free(path);
   }
 
+  free(rawPath);
   return CURLE_OK;
 }
 
@@ -4401,7 +4359,6 @@
     char command;
     *type = 0;                     /* it was in the middle of the hostname */
     command = Curl_raw_toupper(type[6]);
-    conn->bits.type_set = TRUE;
 
     switch(command) {
     case 'A': /* ASCII mode */
@@ -4423,18 +4380,6 @@
   /* get some initial data into the ftp struct */
   ftp->transfer = FTPTRANSFER_BODY;
   ftp->downloadsize = 0;
-
-  /* No need to duplicate user+password, the connectdata struct won't change
-     during a session, but we re-init them here since on subsequent inits
-     since the conn struct may have changed or been replaced.
-  */
-  ftp->user = conn->user;
-  ftp->passwd = conn->passwd;
-  if(isBadFtpString(ftp->user))
-    return CURLE_URL_MALFORMAT;
-  if(isBadFtpString(ftp->passwd))
-    return CURLE_URL_MALFORMAT;
-
   conn->proto.ftpc.known_filesize = -1; /* unknown size for now */
 
   return CURLE_OK;
diff --git a/Utilities/cmcurl/lib/ftp.h b/Utilities/cmcurl/lib/ftp.h
index 828d69a..06421c6 100644
--- a/Utilities/cmcurl/lib/ftp.h
+++ b/Utilities/cmcurl/lib/ftp.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -102,8 +102,6 @@
    perhaps the Curl_easy is changed between the times the connection is
    used. */
 struct FTP {
-  char *user;    /* user name string */
-  char *passwd;  /* password string */
   char *path;    /* points to the urlpieces struct field */
   char *pathalloc; /* if non-NULL a pointer to an allocated path */
 
@@ -121,8 +119,7 @@
   char *entrypath; /* the PWD reply when we logged on */
   char **dirs;   /* realloc()ed array for path components */
   int dirdepth;  /* number of entries used in the 'dirs' array */
-  int diralloc;  /* number of entries allocated for the 'dirs' array */
-  char *file;    /* decoded file */
+  char *file;    /* url-decoded file name (or path) */
   bool dont_check;  /* Set to TRUE to prevent the final (post-transfer)
                        file size and 226/250 status check. It should still
                        read the line, just ignore the result. */
@@ -135,8 +132,7 @@
   bool cwdfail;     /* set TRUE if a CWD command fails, as then we must prevent
                        caching the current directory */
   bool wait_data_conn; /* this is set TRUE if data connection is waited */
-  char *prevpath;   /* conn->path from the previous transfer */
-  curl_ftpfile prevmethod; /* ftp method in previous transfer  */
+  char *prevpath;   /* url-decoded conn->path from the previous transfer */
   char transfertype; /* set by ftp_transfertype for use by Curl_client_write()a
                         and others (A/I or zero) */
   int count1; /* general purpose counter for the state machine */
@@ -154,7 +150,6 @@
      connection to */
   char *newhost;          /* this is the pair to connect the DATA... */
   unsigned short newport; /* connection to */
-
 };
 
 #define DEFAULT_ACCEPT_TIMEOUT   60000 /* milliseconds == one minute */
diff --git a/Utilities/cmcurl/lib/ftplistparser.c b/Utilities/cmcurl/lib/ftplistparser.c
index c4eb437..f399a4c 100644
--- a/Utilities/cmcurl/lib/ftplistparser.c
+++ b/Utilities/cmcurl/lib/ftplistparser.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
diff --git a/Utilities/cmcurl/lib/ftplistparser.h b/Utilities/cmcurl/lib/ftplistparser.h
index 8128887..b34ae9b 100644
--- a/Utilities/cmcurl/lib/ftplistparser.h
+++ b/Utilities/cmcurl/lib/ftplistparser.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
diff --git a/Utilities/cmcurl/lib/getenv.c b/Utilities/cmcurl/lib/getenv.c
index 89d181d..9385b8f 100644
--- a/Utilities/cmcurl/lib/getenv.c
+++ b/Utilities/cmcurl/lib/getenv.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -27,25 +27,48 @@
 
 #include "memdebug.h"
 
-static
-char *GetEnv(const char *variable)
+static char *GetEnv(const char *variable)
 {
 #if defined(_WIN32_WCE) || defined(CURL_WINDOWS_APP)
   (void)variable;
   return NULL;
-#else
-#ifdef WIN32
-  char env[MAX_PATH]; /* MAX_PATH is from windef.h */
-  char *temp = getenv(variable);
-  env[0] = '\0';
-  if(temp != NULL)
-    ExpandEnvironmentStringsA(temp, env, sizeof(env));
-  return (env[0] != '\0')?strdup(env):NULL;
+#elif defined(WIN32)
+  /* This uses Windows API instead of C runtime getenv() to get the environment
+     variable since some changes aren't always visible to the latter. #4774 */
+  char *buf = NULL;
+  char *tmp;
+  DWORD bufsize;
+  DWORD rc = 1;
+  const DWORD max = 32768; /* max env var size from MSCRT source */
+
+  for(;;) {
+    tmp = realloc(buf, rc);
+    if(!tmp) {
+      free(buf);
+      return NULL;
+    }
+
+    buf = tmp;
+    bufsize = rc;
+
+    /* It's possible for rc to be 0 if the variable was found but empty.
+       Since getenv doesn't make that distinction we ignore it as well. */
+    rc = GetEnvironmentVariableA(variable, buf, bufsize);
+    if(!rc || rc == bufsize || rc > max) {
+      free(buf);
+      return NULL;
+    }
+
+    /* if rc < bufsize then rc is bytes written not including null */
+    if(rc < bufsize)
+      return buf;
+
+    /* else rc is bytes needed, try again */
+  }
 #else
   char *env = getenv(variable);
   return (env && env[0])?strdup(env):NULL;
 #endif
-#endif
 }
 
 char *curl_getenv(const char *v)
diff --git a/Utilities/cmcurl/lib/getinfo.c b/Utilities/cmcurl/lib/getinfo.c
index e118da8..6d5bd5f 100644
--- a/Utilities/cmcurl/lib/getinfo.c
+++ b/Utilities/cmcurl/lib/getinfo.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -147,6 +147,33 @@
     long          *to_long;
   } lptr;
 
+#ifdef DEBUGBUILD
+  char *timestr = getenv("CURL_TIME");
+  if(timestr) {
+    unsigned long val = strtol(timestr, NULL, 10);
+    switch(info) {
+    case CURLINFO_LOCAL_PORT:
+      *param_longp = (long)val;
+      return CURLE_OK;
+    default:
+      break;
+    }
+  }
+  /* use another variable for this to allow different values */
+  timestr = getenv("CURL_DEBUG_SIZE");
+  if(timestr) {
+    unsigned long val = strtol(timestr, NULL, 10);
+    switch(info) {
+    case CURLINFO_HEADER_SIZE:
+    case CURLINFO_REQUEST_SIZE:
+      *param_longp = (long)val;
+      return CURLE_OK;
+    default:
+      break;
+    }
+  }
+#endif
+
   switch(info) {
   case CURLINFO_RESPONSE_CODE:
     *param_longp = data->info.httpcode;
@@ -171,9 +198,11 @@
   case CURLINFO_SSL_VERIFYRESULT:
     *param_longp = data->set.ssl.certverifyresult;
     break;
+#ifndef CURL_DISABLE_PROXY
   case CURLINFO_PROXY_SSL_VERIFYRESULT:
     *param_longp = data->set.proxy_ssl.certverifyresult;
     break;
+#endif
   case CURLINFO_REDIRECT_COUNT:
     *param_longp = data->set.followlocation;
     break;
@@ -212,8 +241,11 @@
     *param_longp = data->info.conn_local_port;
     break;
   case CURLINFO_CONDITION_UNMET:
-    /* return if the condition prevented the document to get transferred */
-    *param_longp = data->info.timecond ? 1L : 0L;
+    if(data->info.httpcode == 304)
+      *param_longp = 1L;
+    else
+      /* return if the condition prevented the document to get transferred */
+      *param_longp = data->info.timecond ? 1L : 0L;
     break;
   case CURLINFO_RTSP_CLIENT_CSEQ:
     *param_longp = data->state.rtsp_next_client_CSeq;
@@ -235,6 +267,9 @@
     case 20:
       *param_longp = CURL_HTTP_VERSION_2_0;
       break;
+    case 30:
+      *param_longp = CURL_HTTP_VERSION_3;
+      break;
     default:
       *param_longp = CURL_HTTP_VERSION_NONE;
       break;
@@ -243,7 +278,6 @@
   case CURLINFO_PROTOCOL:
     *param_longp = data->info.conn_protocol;
     break;
-
   default:
     return CURLE_UNKNOWN_OPTION;
   }
@@ -256,6 +290,27 @@
 static CURLcode getinfo_offt(struct Curl_easy *data, CURLINFO info,
                              curl_off_t *param_offt)
 {
+#ifdef DEBUGBUILD
+  char *timestr = getenv("CURL_TIME");
+  if(timestr) {
+    unsigned long val = strtol(timestr, NULL, 10);
+    switch(info) {
+    case CURLINFO_TOTAL_TIME_T:
+    case CURLINFO_NAMELOOKUP_TIME_T:
+    case CURLINFO_CONNECT_TIME_T:
+    case CURLINFO_APPCONNECT_TIME_T:
+    case CURLINFO_PRETRANSFER_TIME_T:
+    case CURLINFO_STARTTRANSFER_TIME_T:
+    case CURLINFO_REDIRECT_TIME_T:
+    case CURLINFO_SPEED_DOWNLOAD_T:
+    case CURLINFO_SPEED_UPLOAD_T:
+      *param_offt = (curl_off_t)val;
+      return CURLE_OK;
+    default:
+      break;
+    }
+  }
+#endif
   switch(info) {
   case CURLINFO_FILETIME_T:
     *param_offt = (curl_off_t)data->info.filetime;
@@ -267,7 +322,7 @@
     *param_offt = data->progress.downloaded;
     break;
   case CURLINFO_SPEED_DOWNLOAD_T:
-    *param_offt =  data->progress.dlspeed;
+    *param_offt = data->progress.dlspeed;
     break;
   case CURLINFO_SPEED_UPLOAD_T:
     *param_offt = data->progress.ulspeed;
@@ -280,7 +335,7 @@
     *param_offt = (data->progress.flags & PGRS_UL_SIZE_KNOWN)?
       data->progress.size_ul:-1;
     break;
-  case CURLINFO_TOTAL_TIME_T:
+   case CURLINFO_TOTAL_TIME_T:
     *param_offt = data->progress.timespent;
     break;
   case CURLINFO_NAMELOOKUP_TIME_T:
@@ -301,7 +356,9 @@
   case CURLINFO_REDIRECT_TIME_T:
     *param_offt = data->progress.t_redirect;
     break;
-
+  case CURLINFO_RETRY_AFTER:
+    *param_offt = data->info.retry_after;
+    break;
   default:
     return CURLE_UNKNOWN_OPTION;
   }
@@ -312,6 +369,27 @@
 static CURLcode getinfo_double(struct Curl_easy *data, CURLINFO info,
                                double *param_doublep)
 {
+#ifdef DEBUGBUILD
+  char *timestr = getenv("CURL_TIME");
+  if(timestr) {
+    unsigned long val = strtol(timestr, NULL, 10);
+    switch(info) {
+    case CURLINFO_TOTAL_TIME:
+    case CURLINFO_NAMELOOKUP_TIME:
+    case CURLINFO_CONNECT_TIME:
+    case CURLINFO_APPCONNECT_TIME:
+    case CURLINFO_PRETRANSFER_TIME:
+    case CURLINFO_STARTTRANSFER_TIME:
+    case CURLINFO_REDIRECT_TIME:
+    case CURLINFO_SPEED_DOWNLOAD:
+    case CURLINFO_SPEED_UPLOAD:
+      *param_doublep = (double)val;
+      return CURLE_OK;
+    default:
+      break;
+    }
+  }
+#endif
   switch(info) {
   case CURLINFO_TOTAL_TIME:
     *param_doublep = DOUBLE_SECS(data->progress.timespent);
@@ -332,13 +410,13 @@
     *param_doublep = DOUBLE_SECS(data->progress.t_starttransfer);
     break;
   case CURLINFO_SIZE_UPLOAD:
-    *param_doublep =  (double)data->progress.uploaded;
+    *param_doublep = (double)data->progress.uploaded;
     break;
   case CURLINFO_SIZE_DOWNLOAD:
     *param_doublep = (double)data->progress.downloaded;
     break;
   case CURLINFO_SPEED_DOWNLOAD:
-    *param_doublep =  (double)data->progress.dlspeed;
+    *param_doublep = (double)data->progress.dlspeed;
     break;
   case CURLINFO_SPEED_UPLOAD:
     *param_doublep = (double)data->progress.ulspeed;
diff --git a/Utilities/cmcurl/lib/getinfo.h b/Utilities/cmcurl/lib/getinfo.h
index aecf717..8d2af42 100644
--- a/Utilities/cmcurl/lib/getinfo.h
+++ b/Utilities/cmcurl/lib/getinfo.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2010, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
diff --git a/Utilities/cmcurl/lib/gopher.c b/Utilities/cmcurl/lib/gopher.c
index b296c62..b4811b2 100644
--- a/Utilities/cmcurl/lib/gopher.c
+++ b/Utilities/cmcurl/lib/gopher.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -28,6 +28,7 @@
 #include <curl/curl.h>
 #include "transfer.h"
 #include "sendf.h"
+#include "connect.h"
 #include "progress.h"
 #include "gopher.h"
 #include "select.h"
@@ -83,8 +84,10 @@
   char *query = data->state.up.query;
   char *sel = NULL;
   char *sel_org = NULL;
+  timediff_t timeout_ms;
   ssize_t amount, k;
   size_t len;
+  int what;
 
   *done = TRUE; /* unconditionally */
 
@@ -113,7 +116,7 @@
     newp += 2;
 
     /* ... and finally unescape */
-    result = Curl_urldecode(data, newp, 0, &sel, &len, FALSE);
+    result = Curl_urldecode(data, newp, 0, &sel, &len, REJECT_ZERO);
     free(gopherpath);
     if(result)
       return result;
@@ -139,19 +142,29 @@
     else
       break;
 
+    timeout_ms = Curl_timeleft(conn->data, NULL, FALSE);
+    if(timeout_ms < 0) {
+      result = CURLE_OPERATION_TIMEDOUT;
+      break;
+    }
+    if(!timeout_ms)
+      timeout_ms = TIMEDIFF_T_MAX;
+
     /* Don't busyloop. The entire loop thing is a work-around as it causes a
        BLOCKING behavior which is a NO-NO. This function should rather be
        split up in a do and a doing piece where the pieces that aren't
        possible to send now will be sent in the doing function repeatedly
        until the entire request is sent.
-
-       Wait a while for the socket to be writable. Note that this doesn't
-       acknowledge the timeout.
     */
-    if(SOCKET_WRITABLE(sockfd, 100) < 0) {
+    what = SOCKET_WRITABLE(sockfd, timeout_ms);
+    if(what < 0) {
       result = CURLE_SEND_ERROR;
       break;
     }
+    else if(!what) {
+      result = CURLE_OPERATION_TIMEDOUT;
+      break;
+    }
   }
 
   free(sel_org);
diff --git a/Utilities/cmcurl/lib/gopher.h b/Utilities/cmcurl/lib/gopher.h
index 501c990..dec2557 100644
--- a/Utilities/cmcurl/lib/gopher.h
+++ b/Utilities/cmcurl/lib/gopher.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2009, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
diff --git a/Utilities/cmcurl/lib/hash.h b/Utilities/cmcurl/lib/hash.h
index 90a25d1..558d0f4 100644
--- a/Utilities/cmcurl/lib/hash.h
+++ b/Utilities/cmcurl/lib/hash.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -80,7 +80,7 @@
 void *Curl_hash_pick(struct curl_hash *, void *key, size_t key_len);
 void Curl_hash_apply(struct curl_hash *h, void *user,
                      void (*cb)(void *user, void *ptr));
-int Curl_hash_count(struct curl_hash *h);
+#define Curl_hash_count(h) ((h)->size)
 void Curl_hash_destroy(struct curl_hash *h);
 void Curl_hash_clean(struct curl_hash *h);
 void Curl_hash_clean_with_criterium(struct curl_hash *h, void *user,
diff --git a/Utilities/cmcurl/lib/hmac.c b/Utilities/cmcurl/lib/hmac.c
index bf49ebe..e4fea8a 100644
--- a/Utilities/cmcurl/lib/hmac.c
+++ b/Utilities/cmcurl/lib/hmac.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -30,6 +30,7 @@
 
 #include "curl_hmac.h"
 #include "curl_memory.h"
+#include "warnless.h"
 
 /* The last #include file should be: */
 #include "memdebug.h"
@@ -47,13 +48,13 @@
 
 
 
-HMAC_context *
-Curl_HMAC_init(const HMAC_params * hashparams,
+struct HMAC_context *
+Curl_HMAC_init(const struct HMAC_params *hashparams,
                const unsigned char *key,
                unsigned int keylen)
 {
   size_t i;
-  HMAC_context *ctxt;
+  struct HMAC_context *ctxt;
   unsigned char *hkey;
   unsigned char b;
 
@@ -100,7 +101,7 @@
   return ctxt;
 }
 
-int Curl_HMAC_update(HMAC_context * ctxt,
+int Curl_HMAC_update(struct HMAC_context *ctxt,
                      const unsigned char *data,
                      unsigned int len)
 {
@@ -110,9 +111,9 @@
 }
 
 
-int Curl_HMAC_final(HMAC_context *ctxt, unsigned char *result)
+int Curl_HMAC_final(struct HMAC_context *ctxt, unsigned char *result)
 {
-  const HMAC_params * hashparams = ctxt->hmac_hash;
+  const struct HMAC_params *hashparams = ctxt->hmac_hash;
 
   /* Do not get result if called with a null parameter: only release
      storage. */
@@ -129,4 +130,41 @@
   return 0;
 }
 
+/*
+ * Curl_hmacit()
+ *
+ * This is used to generate a HMAC hash, for the specified input data, given
+ * the specified hash function and key.
+ *
+ * Parameters:
+ *
+ * hashparams [in]     - The hash function (Curl_HMAC_MD5).
+ * key        [in]     - The key to use.
+ * keylen     [in]     - The length of the key.
+ * data       [in]     - The data to encrypt.
+ * datalen    [in]     - The length of the data.
+ * output     [in/out] - The output buffer.
+ *
+ * Returns CURLE_OK on success.
+ */
+CURLcode Curl_hmacit(const struct HMAC_params *hashparams,
+                     const unsigned char *key, const size_t keylen,
+                     const unsigned char *data, const size_t datalen,
+                     unsigned char *output)
+{
+  struct HMAC_context *ctxt =
+    Curl_HMAC_init(hashparams, key, curlx_uztoui(keylen));
+
+  if(!ctxt)
+    return CURLE_OUT_OF_MEMORY;
+
+  /* Update the digest with the given challenge */
+  Curl_HMAC_update(ctxt, data, curlx_uztoui(datalen));
+
+  /* Finalise the digest */
+  Curl_HMAC_final(ctxt, output);
+
+  return CURLE_OK;
+}
+
 #endif /* CURL_DISABLE_CRYPTO_AUTH */
diff --git a/Utilities/cmcurl/lib/hostasyn.c b/Utilities/cmcurl/lib/hostasyn.c
index 99d872b..ed9190f 100644
--- a/Utilities/cmcurl/lib/hostasyn.c
+++ b/Utilities/cmcurl/lib/hostasyn.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -117,10 +117,10 @@
  * name resolve layers (selected at build-time). They all take this same set
  * of arguments
  */
-Curl_addrinfo *Curl_getaddrinfo(struct connectdata *conn,
-                                const char *hostname,
-                                int port,
-                                int *waitp)
+struct Curl_addrinfo *Curl_getaddrinfo(struct connectdata *conn,
+                                       const char *hostname,
+                                       int port,
+                                       int *waitp)
 {
   return Curl_resolver_getaddrinfo(conn, hostname, port, waitp);
 }
diff --git a/Utilities/cmcurl/lib/hostcheck.c b/Utilities/cmcurl/lib/hostcheck.c
index 115d24b..9e0db05 100644
--- a/Utilities/cmcurl/lib/hostcheck.c
+++ b/Utilities/cmcurl/lib/hostcheck.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
diff --git a/Utilities/cmcurl/lib/hostcheck.h b/Utilities/cmcurl/lib/hostcheck.h
index f562df9..9c18085 100644
--- a/Utilities/cmcurl/lib/hostcheck.h
+++ b/Utilities/cmcurl/lib/hostcheck.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
diff --git a/Utilities/cmcurl/lib/hostip.c b/Utilities/cmcurl/lib/hostip.c
index cf33ed8..dd5916e 100644
--- a/Utilities/cmcurl/lib/hostip.c
+++ b/Utilities/cmcurl/lib/hostip.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -59,6 +59,7 @@
 #include "strerror.h"
 #include "url.h"
 #include "inet_ntop.h"
+#include "inet_pton.h"
 #include "multiif.h"
 #include "doh.h"
 #include "warnless.h"
@@ -119,7 +120,7 @@
 /*
  * Return # of addresses in a Curl_addrinfo struct
  */
-int Curl_num_addresses(const Curl_addrinfo *addr)
+int Curl_num_addresses(const struct Curl_addrinfo *addr)
 {
   int i = 0;
   while(addr) {
@@ -130,39 +131,36 @@
 }
 
 /*
- * Curl_printable_address() returns a printable version of the 1st address
+ * Curl_printable_address() stores a printable version of the 1st address
  * given in the 'ai' argument. The result will be stored in the buf that is
  * bufsize bytes big.
  *
- * If the conversion fails, it returns NULL.
+ * If the conversion fails, the target buffer is empty.
  */
-const char *
-Curl_printable_address(const Curl_addrinfo *ai, char *buf, size_t bufsize)
+void Curl_printable_address(const struct Curl_addrinfo *ai, char *buf,
+                            size_t bufsize)
 {
-  const struct sockaddr_in *sa4;
-  const struct in_addr *ipaddr4;
-#ifdef ENABLE_IPV6
-  const struct sockaddr_in6 *sa6;
-  const struct in6_addr *ipaddr6;
-#endif
+  DEBUGASSERT(bufsize);
+  buf[0] = 0;
 
   switch(ai->ai_family) {
-    case AF_INET:
-      sa4 = (const void *)ai->ai_addr;
-      ipaddr4 = &sa4->sin_addr;
-      return Curl_inet_ntop(ai->ai_family, (const void *)ipaddr4, buf,
-                            bufsize);
-#ifdef ENABLE_IPV6
-    case AF_INET6:
-      sa6 = (const void *)ai->ai_addr;
-      ipaddr6 = &sa6->sin6_addr;
-      return Curl_inet_ntop(ai->ai_family, (const void *)ipaddr6, buf,
-                            bufsize);
-#endif
-    default:
-      break;
+  case AF_INET: {
+    const struct sockaddr_in *sa4 = (const void *)ai->ai_addr;
+    const struct in_addr *ipaddr4 = &sa4->sin_addr;
+    (void)Curl_inet_ntop(ai->ai_family, (const void *)ipaddr4, buf, bufsize);
+    break;
   }
-  return NULL;
+#ifdef ENABLE_IPV6
+  case AF_INET6: {
+    const struct sockaddr_in6 *sa6 = (const void *)ai->ai_addr;
+    const struct in6_addr *ipaddr6 = &sa6->sin6_addr;
+    (void)Curl_inet_ntop(ai->ai_family, (const void *)ipaddr6, buf, bufsize);
+    break;
+  }
+#endif
+  default:
+    break;
+  }
 }
 
 /*
@@ -336,7 +334,7 @@
 
 #ifndef CURL_DISABLE_SHUFFLE_DNS
 UNITTEST CURLcode Curl_shuffle_addr(struct Curl_easy *data,
-                                    Curl_addrinfo **addr);
+                                    struct Curl_addrinfo **addr);
 /*
  * Curl_shuffle_addr() shuffles the order of addresses in a 'Curl_addrinfo'
  * struct by re-linking its linked list.
@@ -350,13 +348,13 @@
  * @unittest: 1608
  */
 UNITTEST CURLcode Curl_shuffle_addr(struct Curl_easy *data,
-                                    Curl_addrinfo **addr)
+                                    struct Curl_addrinfo **addr)
 {
   CURLcode result = CURLE_OK;
   const int num_addrs = Curl_num_addresses(*addr);
 
   if(num_addrs > 1) {
-    Curl_addrinfo **nodes;
+    struct Curl_addrinfo **nodes;
     infof(data, "Shuffling %i addresses", num_addrs);
 
     nodes = malloc(num_addrs*sizeof(*nodes));
@@ -375,7 +373,7 @@
       if(rnd) {
         /* Fisher-Yates shuffle */
         if(Curl_rand(data, (unsigned char *)rnd, rnd_size) == CURLE_OK) {
-          Curl_addrinfo *swap_tmp;
+          struct Curl_addrinfo *swap_tmp;
           for(i = num_addrs - 1; i > 0; i--) {
             swap_tmp = nodes[rnd[i] % (i + 1)];
             nodes[rnd[i] % (i + 1)] = nodes[i];
@@ -414,7 +412,7 @@
  */
 struct Curl_dns_entry *
 Curl_cache_addr(struct Curl_easy *data,
-                Curl_addrinfo *addr,
+                struct Curl_addrinfo *addr,
                 const char *hostname,
                 int port)
 {
@@ -482,18 +480,19 @@
  * CURLRESOLV_PENDING  (1) = waiting for response, no pointer
  */
 
-int Curl_resolv(struct connectdata *conn,
-                const char *hostname,
-                int port,
-                bool allowDOH,
-                struct Curl_dns_entry **entry)
+enum resolve_t Curl_resolv(struct connectdata *conn,
+                           const char *hostname,
+                           int port,
+                           bool allowDOH,
+                           struct Curl_dns_entry **entry)
 {
   struct Curl_dns_entry *dns = NULL;
   struct Curl_easy *data = conn->data;
   CURLcode result;
-  int rc = CURLRESOLV_ERROR; /* default to failure */
+  enum resolve_t rc = CURLRESOLV_ERROR; /* default to failure */
 
   *entry = NULL;
+  conn->bits.doh = FALSE; /* default is not */
 
   if(data->share)
     Curl_share_lock(data, CURL_LOCK_DATA_DNS, CURL_LOCK_ACCESS_SINGLE);
@@ -512,13 +511,13 @@
   if(!dns) {
     /* The entry was not in the cache. Resolve it to IP address */
 
-    Curl_addrinfo *addr;
+    struct Curl_addrinfo *addr = NULL;
     int respwait = 0;
-
-    /* Check what IP specifics the app has requested and if we can provide it.
-     * If not, bail out. */
-    if(!Curl_ipvalid(conn))
-      return CURLRESOLV_ERROR;
+    struct in_addr in;
+#ifndef USE_RESOLVE_ON_IPS
+    const
+#endif
+      bool ipnum = FALSE;
 
     /* notify the resolver start callback */
     if(data->set.resolver_start) {
@@ -531,20 +530,59 @@
         return CURLRESOLV_ERROR;
     }
 
-    if(allowDOH && data->set.doh) {
-      addr = Curl_doh(conn, hostname, port, &respwait);
+#ifndef USE_RESOLVE_ON_IPS
+    /* First check if this is an IPv4 address string */
+    if(Curl_inet_pton(AF_INET, hostname, &in) > 0)
+      /* This is a dotted IP address 123.123.123.123-style */
+      addr = Curl_ip2addr(AF_INET, &in, hostname, port);
+#ifdef ENABLE_IPV6
+    if(!addr) {
+      struct in6_addr in6;
+      /* check if this is an IPv6 address string */
+      if(Curl_inet_pton(AF_INET6, hostname, &in6) > 0)
+        /* This is an IPv6 address literal */
+        addr = Curl_ip2addr(AF_INET6, &in6, hostname, port);
     }
+#endif /* ENABLE_IPV6 */
+
+#else /* if USE_RESOLVE_ON_IPS */
+    /* First check if this is an IPv4 address string */
+    if(Curl_inet_pton(AF_INET, hostname, &in) > 0)
+      /* This is a dotted IP address 123.123.123.123-style */
+      ipnum = TRUE;
+#ifdef ENABLE_IPV6
     else {
-      /* If Curl_getaddrinfo() returns NULL, 'respwait' might be set to a
-         non-zero value indicating that we need to wait for the response to the
-         resolve call */
-      addr = Curl_getaddrinfo(conn,
+      struct in6_addr in6;
+      /* check if this is an IPv6 address string */
+      if(Curl_inet_pton(AF_INET6, hostname, &in6) > 0)
+        /* This is an IPv6 address literal */
+        ipnum = TRUE;
+    }
+#endif /* ENABLE_IPV6 */
+
+#endif /* !USE_RESOLVE_ON_IPS */
+
+    if(!addr) {
+      /* Check what IP specifics the app has requested and if we can provide
+       * it. If not, bail out. */
+      if(!Curl_ipvalid(conn))
+        return CURLRESOLV_ERROR;
+
+      if(allowDOH && data->set.doh && !ipnum) {
+        addr = Curl_doh(conn, hostname, port, &respwait);
+      }
+      else {
+        /* If Curl_getaddrinfo() returns NULL, 'respwait' might be set to a
+           non-zero value indicating that we need to wait for the response to
+           the resolve call */
+        addr = Curl_getaddrinfo(conn,
 #ifdef DEBUGBUILD
-                              (data->set.str[STRING_DEVICE]
-                               && !strcmp(data->set.str[STRING_DEVICE],
-                                          "LocalHost"))?"localhost":
+                                (data->set.str[STRING_DEVICE]
+                                 && !strcmp(data->set.str[STRING_DEVICE],
+                                            "LocalHost"))?"localhost":
 #endif
-                              hostname, port, &respwait);
+                                hostname, port, &respwait);
+      }
     }
     if(!addr) {
       if(respwait) {
@@ -620,11 +658,11 @@
  * CURLRESOLV_PENDING  (1) = waiting for response, no pointer
  */
 
-int Curl_resolv_timeout(struct connectdata *conn,
-                        const char *hostname,
-                        int port,
-                        struct Curl_dns_entry **entry,
-                        time_t timeoutms)
+enum resolve_t Curl_resolv_timeout(struct connectdata *conn,
+                                   const char *hostname,
+                                   int port,
+                                   struct Curl_dns_entry **entry,
+                                   timediff_t timeoutms)
 {
 #ifdef USE_ALARM_TIMEOUT
 #ifdef HAVE_SIGACTION
@@ -640,7 +678,7 @@
   volatile unsigned int prev_alarm = 0;
   struct Curl_easy *data = conn->data;
 #endif /* USE_ALARM_TIMEOUT */
-  int rc;
+  enum resolve_t rc;
 
   *entry = NULL;
 
@@ -749,7 +787,7 @@
                                             conn->created) / 1000;
 
     /* the alarm period is counted in even number of seconds */
-    unsigned long alarm_set = prev_alarm - elapsed_secs;
+    unsigned long alarm_set = (unsigned long)(prev_alarm - elapsed_secs);
 
     if(!alarm_set ||
        ((alarm_set >= 0x80000000) && (prev_alarm < 0x80000000)) ) {
@@ -868,7 +906,7 @@
     }
     else {
       struct Curl_dns_entry *dns;
-      Curl_addrinfo *head = NULL, *tail = NULL;
+      struct Curl_addrinfo *head = NULL, *tail = NULL;
       size_t entry_len;
       char address[64];
 #if !defined(CURL_DISABLE_VERBOSE_STRINGS)
@@ -902,7 +940,7 @@
 
       while(*end_ptr) {
         size_t alen;
-        Curl_addrinfo *ai;
+        struct Curl_addrinfo *ai;
 
         addr_begin = end_ptr + 1;
         addr_end = strchr(addr_begin, ',');
@@ -1021,25 +1059,27 @@
 CURLcode Curl_resolv_check(struct connectdata *conn,
                            struct Curl_dns_entry **dns)
 {
-  if(conn->data->set.doh)
+#if defined(CURL_DISABLE_DOH) && !defined(CURLRES_ASYNCH)
+  (void)dns;
+#endif
+
+  if(conn->bits.doh)
     return Curl_doh_is_resolved(conn, dns);
   return Curl_resolver_is_resolved(conn, dns);
 }
 
 int Curl_resolv_getsock(struct connectdata *conn,
-                        curl_socket_t *socks,
-                        int numsocks)
+                        curl_socket_t *socks)
 {
 #ifdef CURLRES_ASYNCH
-  if(conn->data->set.doh)
+  if(conn->bits.doh)
     /* nothing to wait for during DOH resolve, those handles have their own
        sockets */
     return GETSOCK_BLANK;
-  return Curl_resolver_getsock(conn, socks, numsocks);
+  return Curl_resolver_getsock(conn, socks);
 #else
   (void)conn;
   (void)socks;
-  (void)numsocks;
   return GETSOCK_BLANK;
 #endif
 }
@@ -1061,10 +1101,12 @@
 
   result = Curl_setup_conn(conn, protocol_done);
 
-  if(result)
-    /* We're not allowed to return failure with memory left allocated
-       in the connectdata struct, free those here */
-    Curl_disconnect(conn->data, conn, TRUE); /* close the connection */
-
+  if(result) {
+    struct Curl_easy *data = conn->data;
+    DEBUGASSERT(data);
+    Curl_detach_connnection(data);
+    Curl_conncache_remove_conn(data, conn, TRUE);
+    Curl_disconnect(data, conn, TRUE);
+  }
   return result;
 }
diff --git a/Utilities/cmcurl/lib/hostip.h b/Utilities/cmcurl/lib/hostip.h
index 9dc0d5a..374b06c 100644
--- a/Utilities/cmcurl/lib/hostip.h
+++ b/Utilities/cmcurl/lib/hostip.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -25,6 +25,7 @@
 #include "curl_setup.h"
 #include "hash.h"
 #include "curl_addrinfo.h"
+#include "timeval.h" /* for timediff_t */
 #include "asyn.h"
 
 #ifdef HAVE_SETJMP_H
@@ -61,10 +62,9 @@
  * Returns a struct curl_hash pointer on success, NULL on failure.
  */
 struct curl_hash *Curl_global_host_cache_init(void);
-void Curl_global_host_cache_dtor(void);
 
 struct Curl_dns_entry {
-  Curl_addrinfo *addr;
+  struct Curl_addrinfo *addr;
   /* timestamp == 0 -- CURLOPT_RESOLVE entry, doesn't timeout */
   time_t timestamp;
   /* use-counter, use Curl_resolv_unlock to release reference */
@@ -79,26 +79,29 @@
  * use, or we'll leak memory!
  */
 /* return codes */
-#define CURLRESOLV_TIMEDOUT -2
-#define CURLRESOLV_ERROR    -1
-#define CURLRESOLV_RESOLVED  0
-#define CURLRESOLV_PENDING   1
-int Curl_resolv(struct connectdata *conn,
-                const char *hostname,
-                int port,
-                bool allowDOH,
-                struct Curl_dns_entry **dnsentry);
-int Curl_resolv_timeout(struct connectdata *conn, const char *hostname,
-                        int port, struct Curl_dns_entry **dnsentry,
-                        time_t timeoutms);
+enum resolve_t {
+  CURLRESOLV_TIMEDOUT = -2,
+  CURLRESOLV_ERROR    = -1,
+  CURLRESOLV_RESOLVED =  0,
+  CURLRESOLV_PENDING  =  1
+};
+enum resolve_t Curl_resolv(struct connectdata *conn,
+                           const char *hostname,
+                           int port,
+                           bool allowDOH,
+                           struct Curl_dns_entry **dnsentry);
+enum resolve_t Curl_resolv_timeout(struct connectdata *conn,
+                                   const char *hostname, int port,
+                                   struct Curl_dns_entry **dnsentry,
+                                   timediff_t timeoutms);
 
 #ifdef CURLRES_IPV6
 /*
  * Curl_ipv6works() returns TRUE if IPv6 seems to work.
  */
-bool Curl_ipv6works(void);
+bool Curl_ipv6works(struct connectdata *conn);
 #else
-#define Curl_ipv6works() FALSE
+#define Curl_ipv6works(x) FALSE
 #endif
 
 /*
@@ -114,19 +117,16 @@
  * name resolve layers (selected at build-time). They all take this same set
  * of arguments
  */
-Curl_addrinfo *Curl_getaddrinfo(struct connectdata *conn,
-                                const char *hostname,
-                                int port,
-                                int *waitp);
+struct Curl_addrinfo *Curl_getaddrinfo(struct connectdata *conn,
+                                       const char *hostname,
+                                       int port,
+                                       int *waitp);
 
 
 /* unlock a previously resolved dns entry */
 void Curl_resolv_unlock(struct Curl_easy *data,
                         struct Curl_dns_entry *dns);
 
-/* for debugging purposes only: */
-void Curl_scan_cache_used(void *user, void *ptr);
-
 /* init a new dns cache and return success */
 int Curl_mk_dnscache(struct curl_hash *hash);
 
@@ -134,7 +134,7 @@
 void Curl_hostcache_prune(struct Curl_easy *data);
 
 /* Return # of addresses in a Curl_addrinfo struct */
-int Curl_num_addresses(const Curl_addrinfo *addr);
+int Curl_num_addresses(const struct Curl_addrinfo *addr);
 
 #if defined(CURLDEBUG) && defined(HAVE_GETNAMEINFO)
 int curl_dogetnameinfo(GETNAMEINFO_QUAL_ARG1 GETNAMEINFO_TYPE_ARG1 sa,
@@ -146,7 +146,7 @@
 #endif
 
 /* IPv4 threadsafe resolve function used for synch and asynch builds */
-Curl_addrinfo *Curl_ipv4_resolve_r(const char *hostname, int port);
+struct Curl_addrinfo *Curl_ipv4_resolve_r(const char *hostname, int port);
 
 CURLcode Curl_once_resolved(struct connectdata *conn, bool *protocol_connect);
 
@@ -158,15 +158,15 @@
  */
 CURLcode Curl_addrinfo_callback(struct connectdata *conn,
                                 int status,
-                                Curl_addrinfo *ai);
+                                struct Curl_addrinfo *ai);
 
 /*
  * Curl_printable_address() returns a printable version of the 1st address
  * given in the 'ip' argument. The result will be stored in the buf that is
  * bufsize bytes big.
  */
-const char *Curl_printable_address(const Curl_addrinfo *ip,
-                                   char *buf, size_t bufsize);
+void Curl_printable_address(const struct Curl_addrinfo *ip,
+                            char *buf, size_t bufsize);
 
 /*
  * Curl_fetch_addr() fetches a 'Curl_dns_entry' already in the DNS cache.
@@ -187,7 +187,7 @@
  * Returns the Curl_dns_entry entry pointer or NULL if the storage failed.
  */
 struct Curl_dns_entry *
-Curl_cache_addr(struct Curl_easy *data, Curl_addrinfo *addr,
+Curl_cache_addr(struct Curl_easy *data, struct Curl_addrinfo *addr,
                 const char *hostname, int port);
 
 #ifndef INADDR_NONE
@@ -237,11 +237,6 @@
 void Curl_hostcache_clean(struct Curl_easy *data, struct curl_hash *hash);
 
 /*
- * Destroy the hostcache of this handle.
- */
-void Curl_hostcache_destroy(struct Curl_easy *data);
-
-/*
  * Populate the cache with specified entries from CURLOPT_RESOLVE.
  */
 CURLcode Curl_loadhostpairs(struct Curl_easy *data);
@@ -249,7 +244,6 @@
 CURLcode Curl_resolv_check(struct connectdata *conn,
                            struct Curl_dns_entry **dns);
 int Curl_resolv_getsock(struct connectdata *conn,
-                        curl_socket_t *socks,
-                        int numsocks);
+                        curl_socket_t *socks);
 
 #endif /* HEADER_CURL_HOSTIP_H */
diff --git a/Utilities/cmcurl/lib/hostip4.c b/Utilities/cmcurl/lib/hostip4.c
index e6ba710..eae9416 100644
--- a/Utilities/cmcurl/lib/hostip4.c
+++ b/Utilities/cmcurl/lib/hostip4.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -52,7 +52,6 @@
 #include "share.h"
 #include "strerror.h"
 #include "url.h"
-#include "inet_pton.h"
 /* The last 3 #include files should be in this order */
 #include "curl_printf.h"
 #include "curl_memory.h"
@@ -89,12 +88,12 @@
  * flavours have thread-safe versions of the plain gethostbyname() etc.
  *
  */
-Curl_addrinfo *Curl_getaddrinfo(struct connectdata *conn,
-                                const char *hostname,
-                                int port,
-                                int *waitp)
+struct Curl_addrinfo *Curl_getaddrinfo(struct connectdata *conn,
+                                       const char *hostname,
+                                       int port,
+                                       int *waitp)
 {
-  Curl_addrinfo *ai = NULL;
+  struct Curl_addrinfo *ai = NULL;
 
 #ifdef CURL_DISABLE_VERBOSE_STRINGS
   (void)conn;
@@ -120,36 +119,30 @@
  * implying that only threadsafe code and function calls may be used.
  *
  */
-Curl_addrinfo *Curl_ipv4_resolve_r(const char *hostname,
-                                   int port)
+struct Curl_addrinfo *Curl_ipv4_resolve_r(const char *hostname,
+                                          int port)
 {
 #if !defined(HAVE_GETADDRINFO_THREADSAFE) && defined(HAVE_GETHOSTBYNAME_R_3)
   int res;
 #endif
-  Curl_addrinfo *ai = NULL;
+  struct Curl_addrinfo *ai = NULL;
   struct hostent *h = NULL;
-  struct in_addr in;
   struct hostent *buf = NULL;
 
-  if(Curl_inet_pton(AF_INET, hostname, &in) > 0)
-    /* This is a dotted IP address 123.123.123.123-style */
-    return Curl_ip2addr(AF_INET, &in, hostname, port);
-
 #if defined(HAVE_GETADDRINFO_THREADSAFE)
-  else {
-    struct addrinfo hints;
-    char sbuf[12];
-    char *sbufptr = NULL;
+  struct addrinfo hints;
+  char sbuf[12];
+  char *sbufptr = NULL;
 
-    memset(&hints, 0, sizeof(hints));
-    hints.ai_family = PF_INET;
-    hints.ai_socktype = SOCK_STREAM;
-    if(port) {
-      msnprintf(sbuf, sizeof(sbuf), "%d", port);
-      sbufptr = sbuf;
-    }
+  memset(&hints, 0, sizeof(hints));
+  hints.ai_family = PF_INET;
+  hints.ai_socktype = SOCK_STREAM;
+  if(port) {
+    msnprintf(sbuf, sizeof(sbuf), "%d", port);
+    sbufptr = sbuf;
+  }
 
-    (void)Curl_getaddrinfo_ex(hostname, sbufptr, &hints, &ai);
+  (void)Curl_getaddrinfo_ex(hostname, sbufptr, &hints, &ai);
 
 #elif defined(HAVE_GETHOSTBYNAME_R)
   /*
@@ -157,144 +150,141 @@
    * Since there are three different versions of it, the following code is
    * somewhat #ifdef-ridden.
    */
-  else {
-    int h_errnop;
+  int h_errnop;
 
-    buf = calloc(1, CURL_HOSTENT_SIZE);
-    if(!buf)
-      return NULL; /* major failure */
-    /*
-     * The clearing of the buffer is a workaround for a gethostbyname_r bug in
-     * qnx nto and it is also _required_ for some of these functions on some
-     * platforms.
-     */
+  buf = calloc(1, CURL_HOSTENT_SIZE);
+  if(!buf)
+    return NULL; /* major failure */
+  /*
+   * The clearing of the buffer is a workaround for a gethostbyname_r bug in
+   * qnx nto and it is also _required_ for some of these functions on some
+   * platforms.
+   */
 
 #if defined(HAVE_GETHOSTBYNAME_R_5)
-    /* Solaris, IRIX and more */
-    h = gethostbyname_r(hostname,
-                        (struct hostent *)buf,
-                        (char *)buf + sizeof(struct hostent),
-                        CURL_HOSTENT_SIZE - sizeof(struct hostent),
-                        &h_errnop);
+  /* Solaris, IRIX and more */
+  h = gethostbyname_r(hostname,
+                      (struct hostent *)buf,
+                      (char *)buf + sizeof(struct hostent),
+                      CURL_HOSTENT_SIZE - sizeof(struct hostent),
+                      &h_errnop);
 
-    /* If the buffer is too small, it returns NULL and sets errno to
-     * ERANGE. The errno is thread safe if this is compiled with
-     * -D_REENTRANT as then the 'errno' variable is a macro defined to get
-     * used properly for threads.
-     */
+  /* If the buffer is too small, it returns NULL and sets errno to
+   * ERANGE. The errno is thread safe if this is compiled with
+   * -D_REENTRANT as then the 'errno' variable is a macro defined to get
+   * used properly for threads.
+   */
 
-    if(h) {
-      ;
-    }
-    else
-#elif defined(HAVE_GETHOSTBYNAME_R_6)
-    /* Linux */
-
-    (void)gethostbyname_r(hostname,
-                        (struct hostent *)buf,
-                        (char *)buf + sizeof(struct hostent),
-                        CURL_HOSTENT_SIZE - sizeof(struct hostent),
-                        &h, /* DIFFERENCE */
-                        &h_errnop);
-    /* Redhat 8, using glibc 2.2.93 changed the behavior. Now all of a
-     * sudden this function returns EAGAIN if the given buffer size is too
-     * small. Previous versions are known to return ERANGE for the same
-     * problem.
-     *
-     * This wouldn't be such a big problem if older versions wouldn't
-     * sometimes return EAGAIN on a common failure case. Alas, we can't
-     * assume that EAGAIN *or* ERANGE means ERANGE for any given version of
-     * glibc.
-     *
-     * For now, we do that and thus we may call the function repeatedly and
-     * fail for older glibc versions that return EAGAIN, until we run out of
-     * buffer size (step_size grows beyond CURL_HOSTENT_SIZE).
-     *
-     * If anyone has a better fix, please tell us!
-     *
-     * -------------------------------------------------------------------
-     *
-     * On October 23rd 2003, Dan C dug up more details on the mysteries of
-     * gethostbyname_r() in glibc:
-     *
-     * In glibc 2.2.5 the interface is different (this has also been
-     * discovered in glibc 2.1.1-6 as shipped by Redhat 6). What I can't
-     * explain, is that tests performed on glibc 2.2.4-34 and 2.2.4-32
-     * (shipped/upgraded by Redhat 7.2) don't show this behavior!
-     *
-     * In this "buggy" version, the return code is -1 on error and 'errno'
-     * is set to the ERANGE or EAGAIN code. Note that 'errno' is not a
-     * thread-safe variable.
-     */
-
-    if(!h) /* failure */
-#elif defined(HAVE_GETHOSTBYNAME_R_3)
-    /* AIX, Digital Unix/Tru64, HPUX 10, more? */
-
-    /* For AIX 4.3 or later, we don't use gethostbyname_r() at all, because of
-     * the plain fact that it does not return unique full buffers on each
-     * call, but instead several of the pointers in the hostent structs will
-     * point to the same actual data! This have the unfortunate down-side that
-     * our caching system breaks down horribly. Luckily for us though, AIX 4.3
-     * and more recent versions have a "completely thread-safe"[*] libc where
-     * all the data is stored in thread-specific memory areas making calls to
-     * the plain old gethostbyname() work fine even for multi-threaded
-     * programs.
-     *
-     * This AIX 4.3 or later detection is all made in the configure script.
-     *
-     * Troels Walsted Hansen helped us work this out on March 3rd, 2003.
-     *
-     * [*] = much later we've found out that it isn't at all "completely
-     * thread-safe", but at least the gethostbyname() function is.
-     */
-
-    if(CURL_HOSTENT_SIZE >=
-       (sizeof(struct hostent) + sizeof(struct hostent_data))) {
-
-      /* August 22nd, 2000: Albert Chin-A-Young brought an updated version
-       * that should work! September 20: Richard Prescott worked on the buffer
-       * size dilemma.
-       */
-
-      res = gethostbyname_r(hostname,
-                            (struct hostent *)buf,
-                            (struct hostent_data *)((char *)buf +
-                                                    sizeof(struct hostent)));
-      h_errnop = SOCKERRNO; /* we don't deal with this, but set it anyway */
-    }
-    else
-      res = -1; /* failure, too smallish buffer size */
-
-    if(!res) { /* success */
-
-      h = buf; /* result expected in h */
-
-      /* This is the worst kind of the different gethostbyname_r() interfaces.
-       * Since we don't know how big buffer this particular lookup required,
-       * we can't realloc down the huge alloc without doing closer analysis of
-       * the returned data. Thus, we always use CURL_HOSTENT_SIZE for every
-       * name lookup. Fixing this would require an extra malloc() and then
-       * calling Curl_addrinfo_copy() that subsequent realloc()s down the new
-       * memory area to the actually used amount.
-       */
-    }
-    else
-#endif /* HAVE_...BYNAME_R_5 || HAVE_...BYNAME_R_6 || HAVE_...BYNAME_R_3 */
-    {
-      h = NULL; /* set return code to NULL */
-      free(buf);
-    }
-#else /* HAVE_GETADDRINFO_THREADSAFE || HAVE_GETHOSTBYNAME_R */
-    /*
-     * Here is code for platforms that don't have a thread safe
-     * getaddrinfo() nor gethostbyname_r() function or for which
-     * gethostbyname() is the preferred one.
-     */
-  else {
-    h = gethostbyname((void *)hostname);
-#endif /* HAVE_GETADDRINFO_THREADSAFE || HAVE_GETHOSTBYNAME_R */
+  if(h) {
+    ;
   }
+  else
+#elif defined(HAVE_GETHOSTBYNAME_R_6)
+  /* Linux */
+
+  (void)gethostbyname_r(hostname,
+                      (struct hostent *)buf,
+                      (char *)buf + sizeof(struct hostent),
+                      CURL_HOSTENT_SIZE - sizeof(struct hostent),
+                      &h, /* DIFFERENCE */
+                      &h_errnop);
+  /* Redhat 8, using glibc 2.2.93 changed the behavior. Now all of a
+   * sudden this function returns EAGAIN if the given buffer size is too
+   * small. Previous versions are known to return ERANGE for the same
+   * problem.
+   *
+   * This wouldn't be such a big problem if older versions wouldn't
+   * sometimes return EAGAIN on a common failure case. Alas, we can't
+   * assume that EAGAIN *or* ERANGE means ERANGE for any given version of
+   * glibc.
+   *
+   * For now, we do that and thus we may call the function repeatedly and
+   * fail for older glibc versions that return EAGAIN, until we run out of
+   * buffer size (step_size grows beyond CURL_HOSTENT_SIZE).
+   *
+   * If anyone has a better fix, please tell us!
+   *
+   * -------------------------------------------------------------------
+   *
+   * On October 23rd 2003, Dan C dug up more details on the mysteries of
+   * gethostbyname_r() in glibc:
+   *
+   * In glibc 2.2.5 the interface is different (this has also been
+   * discovered in glibc 2.1.1-6 as shipped by Redhat 6). What I can't
+   * explain, is that tests performed on glibc 2.2.4-34 and 2.2.4-32
+   * (shipped/upgraded by Redhat 7.2) don't show this behavior!
+   *
+   * In this "buggy" version, the return code is -1 on error and 'errno'
+   * is set to the ERANGE or EAGAIN code. Note that 'errno' is not a
+   * thread-safe variable.
+   */
+
+  if(!h) /* failure */
+#elif defined(HAVE_GETHOSTBYNAME_R_3)
+  /* AIX, Digital Unix/Tru64, HPUX 10, more? */
+
+  /* For AIX 4.3 or later, we don't use gethostbyname_r() at all, because of
+   * the plain fact that it does not return unique full buffers on each
+   * call, but instead several of the pointers in the hostent structs will
+   * point to the same actual data! This have the unfortunate down-side that
+   * our caching system breaks down horribly. Luckily for us though, AIX 4.3
+   * and more recent versions have a "completely thread-safe"[*] libc where
+   * all the data is stored in thread-specific memory areas making calls to
+   * the plain old gethostbyname() work fine even for multi-threaded
+   * programs.
+   *
+   * This AIX 4.3 or later detection is all made in the configure script.
+   *
+   * Troels Walsted Hansen helped us work this out on March 3rd, 2003.
+   *
+   * [*] = much later we've found out that it isn't at all "completely
+   * thread-safe", but at least the gethostbyname() function is.
+   */
+
+  if(CURL_HOSTENT_SIZE >=
+     (sizeof(struct hostent) + sizeof(struct hostent_data))) {
+
+    /* August 22nd, 2000: Albert Chin-A-Young brought an updated version
+     * that should work! September 20: Richard Prescott worked on the buffer
+     * size dilemma.
+     */
+
+    res = gethostbyname_r(hostname,
+                          (struct hostent *)buf,
+                          (struct hostent_data *)((char *)buf +
+                                                  sizeof(struct hostent)));
+    h_errnop = SOCKERRNO; /* we don't deal with this, but set it anyway */
+  }
+  else
+    res = -1; /* failure, too smallish buffer size */
+
+  if(!res) { /* success */
+
+    h = buf; /* result expected in h */
+
+    /* This is the worst kind of the different gethostbyname_r() interfaces.
+     * Since we don't know how big buffer this particular lookup required,
+     * we can't realloc down the huge alloc without doing closer analysis of
+     * the returned data. Thus, we always use CURL_HOSTENT_SIZE for every
+     * name lookup. Fixing this would require an extra malloc() and then
+     * calling Curl_addrinfo_copy() that subsequent realloc()s down the new
+     * memory area to the actually used amount.
+     */
+  }
+  else
+#endif /* HAVE_...BYNAME_R_5 || HAVE_...BYNAME_R_6 || HAVE_...BYNAME_R_3 */
+  {
+    h = NULL; /* set return code to NULL */
+    free(buf);
+  }
+#else /* HAVE_GETADDRINFO_THREADSAFE || HAVE_GETHOSTBYNAME_R */
+  /*
+   * Here is code for platforms that don't have a thread safe
+   * getaddrinfo() nor gethostbyname_r() function or for which
+   * gethostbyname() is the preferred one.
+   */
+  h = gethostbyname((void *)hostname);
+#endif /* HAVE_GETADDRINFO_THREADSAFE || HAVE_GETHOSTBYNAME_R */
 
   if(h) {
     ai = Curl_he2ai(h, port);
diff --git a/Utilities/cmcurl/lib/hostip6.c b/Utilities/cmcurl/lib/hostip6.c
index 5511f1a..1121575 100644
--- a/Utilities/cmcurl/lib/hostip6.c
+++ b/Utilities/cmcurl/lib/hostip6.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -62,13 +62,19 @@
 /*
  * Curl_ipv6works() returns TRUE if IPv6 seems to work.
  */
-bool Curl_ipv6works(void)
+bool Curl_ipv6works(struct connectdata *conn)
 {
-  /* the nature of most system is that IPv6 status doesn't come and go
-     during a program's lifetime so we only probe the first time and then we
-     have the info kept for fast re-use */
-  static int ipv6_works = -1;
-  if(-1 == ipv6_works) {
+  if(conn) {
+    /* the nature of most system is that IPv6 status doesn't come and go
+       during a program's lifetime so we only probe the first time and then we
+       have the info kept for fast re-use */
+    DEBUGASSERT(conn);
+    DEBUGASSERT(conn->data);
+    DEBUGASSERT(conn->data->multi);
+    return conn->data->multi->ipv6_works;
+  }
+  else {
+    int ipv6_works = -1;
     /* probe to see if we have a working IPv6 stack */
     curl_socket_t s = socket(PF_INET6, SOCK_DGRAM, 0);
     if(s == CURL_SOCKET_BAD)
@@ -78,8 +84,8 @@
       ipv6_works = 1;
       Curl_closesocket(NULL, s);
     }
+    return (ipv6_works>0)?TRUE:FALSE;
   }
-  return (ipv6_works>0)?TRUE:FALSE;
 }
 
 /*
@@ -89,7 +95,7 @@
 bool Curl_ipvalid(struct connectdata *conn)
 {
   if(conn->ip_version == CURL_IPRESOLVE_V6)
-    return Curl_ipv6works();
+    return Curl_ipv6works(conn);
 
   return TRUE;
 }
@@ -97,20 +103,16 @@
 #if defined(CURLRES_SYNCH)
 
 #ifdef DEBUG_ADDRINFO
-static void dump_addrinfo(struct connectdata *conn, const Curl_addrinfo *ai)
+static void dump_addrinfo(struct connectdata *conn,
+                          const struct Curl_addrinfo *ai)
 {
   printf("dump_addrinfo:\n");
   for(; ai; ai = ai->ai_next) {
     char buf[INET6_ADDRSTRLEN];
     printf("    fam %2d, CNAME %s, ",
            ai->ai_family, ai->ai_canonname ? ai->ai_canonname : "<none>");
-    if(Curl_printable_address(ai, buf, sizeof(buf)))
-      printf("%s\n", buf);
-    else {
-      char buffer[STRERROR_LEN];
-      printf("failed; %s\n",
-             Curl_strerror(SOCKERRNO, buffer, sizeof(buffer)));
-    }
+    Curl_printable_address(ai, buf, sizeof(buf));
+    printf("%s\n", buf);
   }
 }
 #else
@@ -126,13 +128,13 @@
  * memory we need to free after use. That memory *MUST* be freed with
  * Curl_freeaddrinfo(), nothing else.
  */
-Curl_addrinfo *Curl_getaddrinfo(struct connectdata *conn,
-                                const char *hostname,
-                                int port,
-                                int *waitp)
+struct Curl_addrinfo *Curl_getaddrinfo(struct connectdata *conn,
+                                       const char *hostname,
+                                       int port,
+                                       int *waitp)
 {
   struct addrinfo hints;
-  Curl_addrinfo *res;
+  struct Curl_addrinfo *res;
   int error;
   char sbuf[12];
   char *sbufptr = NULL;
@@ -159,13 +161,14 @@
     break;
   }
 
-  if((pf != PF_INET) && !Curl_ipv6works())
+  if((pf != PF_INET) && !Curl_ipv6works(conn))
     /* The stack seems to be a non-IPv6 one */
     pf = PF_INET;
 
   memset(&hints, 0, sizeof(hints));
   hints.ai_family = pf;
-  hints.ai_socktype = conn->socktype;
+  hints.ai_socktype = (conn->transport == TRNSPRT_TCP) ?
+    SOCK_STREAM : SOCK_DGRAM;
 
 #ifndef USE_RESOLVE_ON_IPS
   /*
diff --git a/Utilities/cmcurl/lib/hostsyn.c b/Utilities/cmcurl/lib/hostsyn.c
index 3de6746..9e31008 100644
--- a/Utilities/cmcurl/lib/hostsyn.c
+++ b/Utilities/cmcurl/lib/hostsyn.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
diff --git a/Utilities/cmcurl/lib/http.c b/Utilities/cmcurl/lib/http.c
index 338c59a..28d66c2 100644
--- a/Utilities/cmcurl/lib/http.c
+++ b/Utilities/cmcurl/lib/http.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -88,8 +88,7 @@
  */
 
 static int http_getsock_do(struct connectdata *conn,
-                           curl_socket_t *socks,
-                           int numsocks);
+                           curl_socket_t *socks);
 static int http_should_fail(struct connectdata *conn);
 
 #ifndef CURL_DISABLE_PROXY
@@ -99,8 +98,7 @@
 #ifdef USE_SSL
 static CURLcode https_connecting(struct connectdata *conn, bool *done);
 static int https_getsock(struct connectdata *conn,
-                         curl_socket_t *socks,
-                         int numsocks);
+                         curl_socket_t *socks);
 #else
 #define https_connecting(x,y) CURLE_COULDNT_CONNECT
 #endif
@@ -127,7 +125,8 @@
   ZERO_NULL,                            /* connection_check */
   PORT_HTTP,                            /* defport */
   CURLPROTO_HTTP,                       /* protocol */
-  PROTOPT_CREDSPERREQUEST               /* flags */
+  PROTOPT_CREDSPERREQUEST |             /* flags */
+  PROTOPT_USERPWDCTRL
 };
 
 #ifdef USE_SSL
@@ -152,7 +151,8 @@
   ZERO_NULL,                            /* connection_check */
   PORT_HTTPS,                           /* defport */
   CURLPROTO_HTTPS,                      /* protocol */
-  PROTOPT_SSL | PROTOPT_CREDSPERREQUEST | PROTOPT_ALPN_NPN /* flags */
+  PROTOPT_SSL | PROTOPT_CREDSPERREQUEST | PROTOPT_ALPN_NPN | /* flags */
+  PROTOPT_USERPWDCTRL
 };
 #endif
 
@@ -171,10 +171,22 @@
   Curl_mime_initpart(&http->form, conn->data);
   data->req.protop = http;
 
-  if(!CONN_INUSE(conn))
-    /* if not already multi-using, setup connection details */
-    Curl_http2_setup_conn(conn);
-  Curl_http2_setup_req(data);
+  if(data->set.httpversion == CURL_HTTP_VERSION_3) {
+    if(conn->handler->flags & PROTOPT_SSL)
+      /* Only go HTTP/3 directly on HTTPS URLs. It needs a UDP socket and does
+         the QUIC dance. */
+      conn->transport = TRNSPRT_QUIC;
+    else {
+      failf(data, "HTTP/3 requested for non-HTTPS URL");
+      return CURLE_URL_MALFORMAT;
+    }
+  }
+  else {
+    if(!CONN_INUSE(conn))
+      /* if not already multi-using, setup connection details */
+      Curl_http2_setup_conn(conn);
+    Curl_http2_setup_req(data);
+  }
   return CURLE_OK;
 }
 
@@ -258,7 +270,7 @@
     return NULL;
 
   memcpy(value, start, len);
-  value[len] = 0; /* zero terminate */
+  value[len] = 0; /* null-terminate */
 
   return value;
 }
@@ -282,17 +294,21 @@
   char *out;
 
   if(proxy) {
-    userp = &conn->allocptr.proxyuserpwd;
+#ifndef CURL_DISABLE_PROXY
+    userp = &data->state.aptr.proxyuserpwd;
     user = conn->http_proxy.user;
     pwd = conn->http_proxy.passwd;
+#else
+    return CURLE_NOT_BUILT_IN;
+#endif
   }
   else {
-    userp = &conn->allocptr.userpwd;
+    userp = &data->state.aptr.userpwd;
     user = conn->user;
     pwd = conn->passwd;
   }
 
-  out = aprintf("%s:%s", user, pwd);
+  out = aprintf("%s:%s", user, pwd ? pwd : "");
   if(!out)
     return CURLE_OUT_OF_MEMORY;
 
@@ -330,11 +346,12 @@
 {
   char **userp;
   CURLcode result = CURLE_OK;
+  struct Curl_easy *data = conn->data;
 
-  userp = &conn->allocptr.userpwd;
+  userp = &data->state.aptr.userpwd;
   free(*userp);
   *userp = aprintf("Authorization: Bearer %s\r\n",
-                   conn->oauth_bearer);
+                   conn->data->set.str[STRING_BEARER]);
 
   if(!*userp) {
     result = CURLE_OUT_OF_MEMORY;
@@ -383,7 +400,7 @@
 }
 
 /*
- * Curl_http_perhapsrewind()
+ * http_perhapsrewind()
  *
  * If we are doing POST or PUT {
  *   If we have more data to send {
@@ -417,7 +434,7 @@
        skip this rewinding stuff */
     return CURLE_OK;
 
-  switch(data->set.httpreq) {
+  switch(data->state.httpreq) {
   case HTTPREQ_GET:
   case HTTPREQ_HEAD:
     return CURLE_OK;
@@ -438,11 +455,8 @@
   }
   else {
     /* figure out how much data we are expected to send */
-    switch(data->set.httpreq) {
+    switch(data->state.httpreq) {
     case HTTPREQ_POST:
-      if(data->state.infilesize != -1)
-        expectsend = data->state.infilesize;
-      break;
     case HTTPREQ_PUT:
       if(data->state.infilesize != -1)
         expectsend = data->state.infilesize;
@@ -548,7 +562,7 @@
   CURLcode result = CURLE_OK;
   unsigned long authmask = ~0ul;
 
-  if(!conn->oauth_bearer)
+  if(!data->set.str[STRING_BEARER])
     authmask &= (unsigned long)~CURLAUTH_BEARER;
 
   if(100 <= data->req.httpcode && 199 >= data->req.httpcode)
@@ -558,7 +572,7 @@
   if(data->state.authproblem)
     return data->set.http_fail_on_error?CURLE_HTTP_RETURNED_ERROR:CURLE_OK;
 
-  if((conn->bits.user_passwd || conn->oauth_bearer) &&
+  if((conn->bits.user_passwd || data->set.str[STRING_BEARER]) &&
      ((data->req.httpcode == 401) ||
       (conn->bits.authneg && data->req.httpcode < 300))) {
     pickhost = pickoneauth(&data->state.authhost, authmask);
@@ -571,6 +585,7 @@
       conn->data->set.httpversion = CURL_HTTP_VERSION_1_1;
     }
   }
+#ifndef CURL_DISABLE_PROXY
   if(conn->bits.proxy_user_passwd &&
      ((data->req.httpcode == 407) ||
       (conn->bits.authneg && data->req.httpcode < 300))) {
@@ -579,10 +594,11 @@
     if(!pickproxy)
       data->state.authproblem = TRUE;
   }
+#endif
 
   if(pickhost || pickproxy) {
-    if((data->set.httpreq != HTTPREQ_GET) &&
-       (data->set.httpreq != HTTPREQ_HEAD) &&
+    if((data->state.httpreq != HTTPREQ_GET) &&
+       (data->state.httpreq != HTTPREQ_HEAD) &&
        !conn->bits.rewindaftersend) {
       result = http_perhapsrewind(conn);
       if(result)
@@ -603,8 +619,8 @@
        authentication is not "done" yet and
        no authentication seems to be required and
        we didn't try HEAD or GET */
-    if((data->set.httpreq != HTTPREQ_GET) &&
-       (data->set.httpreq != HTTPREQ_HEAD)) {
+    if((data->state.httpreq != HTTPREQ_GET) &&
+       (data->state.httpreq != HTTPREQ_HEAD)) {
       data->req.newurl = strdup(data->change.url); /* clone URL */
       if(!data->req.newurl)
         return CURLE_OUT_OF_MEMORY;
@@ -634,9 +650,7 @@
 {
   const char *auth = NULL;
   CURLcode result = CURLE_OK;
-#if !defined(CURL_DISABLE_VERBOSE_STRINGS) || defined(USE_SPNEGO)
   struct Curl_easy *data = conn->data;
-#endif
 
 #ifdef CURL_DISABLE_CRYPTO_AUTH
   (void)request;
@@ -644,7 +658,7 @@
 #endif
 
 #ifdef USE_SPNEGO
-  if((authstatus->picked == CURLAUTH_NEGOTIATE)) {
+  if(authstatus->picked == CURLAUTH_NEGOTIATE) {
     auth = "Negotiate";
     result = Curl_output_negotiate(conn, proxy);
     if(result)
@@ -684,10 +698,13 @@
 #endif
   if(authstatus->picked == CURLAUTH_BASIC) {
     /* Basic */
-    if((proxy && conn->bits.proxy_user_passwd &&
-        !Curl_checkProxyheaders(conn, "Proxy-authorization")) ||
-       (!proxy && conn->bits.user_passwd &&
-        !Curl_checkheaders(conn, "Authorization"))) {
+    if(
+#ifndef CURL_DISABLE_PROXY
+      (proxy && conn->bits.proxy_user_passwd &&
+       !Curl_checkProxyheaders(conn, "Proxy-authorization")) ||
+#endif
+      (!proxy && conn->bits.user_passwd &&
+       !Curl_checkheaders(conn, "Authorization"))) {
       auth = "Basic";
       result = http_output_basic(conn, proxy);
       if(result)
@@ -700,7 +717,7 @@
   }
   if(authstatus->picked == CURLAUTH_BEARER) {
     /* Bearer */
-    if((!proxy && conn->oauth_bearer &&
+    if((!proxy && data->set.str[STRING_BEARER] &&
         !Curl_checkheaders(conn, "Authorization:"))) {
       auth = "Bearer";
       result = http_output_bearer(conn);
@@ -714,10 +731,15 @@
   }
 
   if(auth) {
+#ifndef CURL_DISABLE_PROXY
     infof(data, "%s auth using %s with user '%s'\n",
           proxy ? "Proxy" : "Server", auth,
           proxy ? (conn->http_proxy.user ? conn->http_proxy.user : "") :
-                  (conn->user ? conn->user : ""));
+          (conn->user ? conn->user : ""));
+#else
+    infof(data, "Server auth using %s with user '%s'\n",
+          auth, conn->user ? conn->user : "");
+#endif
     authstatus->multipass = (!authstatus->done) ? TRUE : FALSE;
   }
   else
@@ -757,8 +779,11 @@
   authhost = &data->state.authhost;
   authproxy = &data->state.authproxy;
 
-  if((conn->bits.httpproxy && conn->bits.proxy_user_passwd) ||
-     conn->bits.user_passwd || conn->oauth_bearer)
+  if(
+#ifndef CURL_DISABLE_PROXY
+    (conn->bits.httpproxy && conn->bits.proxy_user_passwd) ||
+#endif
+     conn->bits.user_passwd || data->set.str[STRING_BEARER])
     /* continue please */;
   else {
     authhost->done = TRUE;
@@ -1062,8 +1087,10 @@
   */
   if((httpcode == 401) && !conn->bits.user_passwd)
     return TRUE;
+#ifndef CURL_DISABLE_PROXY
   if((httpcode == 407) && !conn->bits.proxy_user_passwd)
     return TRUE;
+#endif
 
   return data->state.authproblem;
 }
@@ -1120,45 +1147,20 @@
   return fullsize;
 }
 
-/* ------------------------------------------------------------------------- */
-/* add_buffer functions */
-
 /*
- * Curl_add_buffer_init() sets up and returns a fine buffer struct
- */
-Curl_send_buffer *Curl_add_buffer_init(void)
-{
-  return calloc(1, sizeof(Curl_send_buffer));
-}
-
-/*
- * Curl_add_buffer_free() frees all associated resources.
- */
-void Curl_add_buffer_free(Curl_send_buffer **inp)
-{
-  Curl_send_buffer *in = *inp;
-  if(in) /* deal with NULL input */
-    free(in->buffer);
-  free(in);
-  *inp = NULL;
-}
-
-/*
- * Curl_add_buffer_send() sends a header buffer and frees all associated
+ * Curl_buffer_send() sends a header buffer and frees all associated
  * memory.  Body data may be appended to the header data if desired.
  *
  * Returns CURLcode
  */
-CURLcode Curl_add_buffer_send(Curl_send_buffer **inp,
-                              struct connectdata *conn,
-
-                              /* add the number of sent bytes to this
-                                 counter */
-                              curl_off_t *bytes_written,
-
-                              /* how much of the buffer contains body data */
-                              size_t included_body_bytes,
-                              int socketindex)
+CURLcode Curl_buffer_send(struct dynbuf *in,
+                          struct connectdata *conn,
+                          /* add the number of sent bytes to this
+                             counter */
+                          curl_off_t *bytes_written,
+                          /* how much of the buffer contains body data */
+                          size_t included_body_bytes,
+                          int socketindex)
 {
   ssize_t amount;
   CURLcode result;
@@ -1169,7 +1171,6 @@
   size_t sendsize;
   curl_socket_t sockfd;
   size_t headersize;
-  Curl_send_buffer *in = *inp;
 
   DEBUGASSERT(socketindex <= SECONDARYSOCKET);
 
@@ -1178,8 +1179,8 @@
   /* The looping below is required since we use non-blocking sockets, but due
      to the circumstances we will just loop and try again and again etc */
 
-  ptr = in->buffer;
-  size = in->size_used;
+  ptr = Curl_dyn_ptr(in);
+  size = Curl_dyn_len(in);
 
   headersize = size - included_body_bytes; /* the initial part that isn't body
                                               is header */
@@ -1190,12 +1191,15 @@
   /* Curl_convert_to_network calls failf if unsuccessful */
   if(result) {
     /* conversion failed, free memory and return to the caller */
-    Curl_add_buffer_free(inp);
+    Curl_dyn_free(in);
     return result;
   }
 
-  if((conn->handler->flags & PROTOPT_SSL ||
-     conn->http_proxy.proxytype == CURLPROXY_HTTPS)
+  if((conn->handler->flags & PROTOPT_SSL
+#ifndef CURL_DISABLE_PROXY
+      || conn->http_proxy.proxytype == CURLPROXY_HTTPS
+#endif
+       )
      && conn->httpversion != 20) {
     /* We never send more than CURL_MAX_WRITE_SIZE bytes in one single chunk
        when we speak HTTPS, as if only a fraction of it is sent now, this data
@@ -1214,14 +1218,27 @@
     result = Curl_get_upload_buffer(data);
     if(result) {
       /* malloc failed, free memory and return to the caller */
-      Curl_add_buffer_free(&in);
+      Curl_dyn_free(in);
       return result;
     }
     memcpy(data->state.ulbuf, ptr, sendsize);
     ptr = data->state.ulbuf;
   }
-  else
+  else {
+#ifdef CURLDEBUG
+    /* Allow debug builds override this logic to force short initial sends */
+    char *p = getenv("CURL_SMALLREQSEND");
+    if(p) {
+      size_t altsize = (size_t)strtoul(p, NULL, 10);
+      if(altsize)
+        sendsize = CURLMIN(size, altsize);
+      else
+        sendsize = size;
+    }
+    else
+#endif
     sendsize = size;
+  }
 
   result = Curl_write(conn, sockfd, ptr, sendsize, &amount);
 
@@ -1264,7 +1281,7 @@
 
         size -= amount;
 
-        ptr = in->buffer + amount;
+        ptr = Curl_dyn_ptr(in) + amount;
 
         /* backup the currently set pointers */
         http->backup.fread_func = data->state.fread_func;
@@ -1278,7 +1295,7 @@
         http->postdata = ptr;
         http->postsize = (curl_off_t)size;
 
-        http->send_buffer = in;
+        http->send_buffer = *in; /* copy the whole struct */
         http->sending = HTTPSEND_REQUEST;
 
         return CURLE_OK;
@@ -1298,92 +1315,11 @@
         return CURLE_SEND_ERROR;
     }
   }
-  Curl_add_buffer_free(&in);
+  Curl_dyn_free(in);
 
   return result;
 }
 
-
-/*
- * add_bufferf() add the formatted input to the buffer.
- */
-CURLcode Curl_add_bufferf(Curl_send_buffer **inp, const char *fmt, ...)
-{
-  char *s;
-  va_list ap;
-  Curl_send_buffer *in = *inp;
-  va_start(ap, fmt);
-  s = vaprintf(fmt, ap); /* this allocs a new string to append */
-  va_end(ap);
-
-  if(s) {
-    CURLcode result = Curl_add_buffer(inp, s, strlen(s));
-    free(s);
-    return result;
-  }
-  /* If we failed, we cleanup the whole buffer and return error */
-  free(in->buffer);
-  free(in);
-  *inp = NULL;
-  return CURLE_OUT_OF_MEMORY;
-}
-
-/*
- * Curl_add_buffer() appends a memory chunk to the existing buffer
- */
-CURLcode Curl_add_buffer(Curl_send_buffer **inp, const void *inptr,
-                         size_t size)
-{
-  char *new_rb;
-  Curl_send_buffer *in = *inp;
-
-  if(~size < in->size_used) {
-    /* If resulting used size of send buffer would wrap size_t, cleanup
-       the whole buffer and return error. Otherwise the required buffer
-       size will fit into a single allocatable memory chunk */
-    Curl_safefree(in->buffer);
-    free(in);
-    *inp = NULL;
-    return CURLE_OUT_OF_MEMORY;
-  }
-
-  if(!in->buffer ||
-     ((in->size_used + size) > (in->size_max - 1))) {
-    /* If current buffer size isn't enough to hold the result, use a
-       buffer size that doubles the required size. If this new size
-       would wrap size_t, then just use the largest possible one */
-    size_t new_size;
-
-    if((size > (size_t)-1 / 2) || (in->size_used > (size_t)-1 / 2) ||
-       (~(size * 2) < (in->size_used * 2)))
-      new_size = (size_t)-1;
-    else
-      new_size = (in->size_used + size) * 2;
-
-    if(in->buffer)
-      /* we have a buffer, enlarge the existing one */
-      new_rb = Curl_saferealloc(in->buffer, new_size);
-    else
-      /* create a new buffer */
-      new_rb = malloc(new_size);
-
-    if(!new_rb) {
-      /* If we failed, we cleanup the whole buffer and return error */
-      free(in);
-      *inp = NULL;
-      return CURLE_OUT_OF_MEMORY;
-    }
-
-    in->buffer = new_rb;
-    in->size_max = new_size;
-  }
-  memcpy(&in->buffer[in->size_used], inptr, size);
-
-  in->size_used += size;
-
-  return CURLE_OK;
-}
-
 /* end of the add_buffer functions */
 /* ------------------------------------------------------------------------- */
 
@@ -1456,6 +1392,7 @@
      function to make the re-use checks properly be able to check this bit. */
   connkeep(conn, "HTTP default");
 
+#ifndef CURL_DISABLE_PROXY
   /* the CONNECT procedure might not have been completed */
   result = Curl_proxy_connect(conn, FIRSTSOCKET);
   if(result)
@@ -1472,7 +1409,6 @@
     /* nothing else to do except wait right now - we're not done here. */
     return CURLE_OK;
 
-#ifndef CURL_DISABLE_PROXY
   if(conn->data->set.haproxyprotocol) {
     /* add HAProxy PROXY protocol header */
     result = add_haproxy_protocol_header(conn);
@@ -1497,11 +1433,9 @@
    interface and then we're always _sending_ a request and thus we wait for
    the single socket to become writable only */
 static int http_getsock_do(struct connectdata *conn,
-                           curl_socket_t *socks,
-                           int numsocks)
+                           curl_socket_t *socks)
 {
   /* write mode */
-  (void)numsocks; /* unused, we trust it to be at least 1 */
   socks[0] = conn->sock[FIRSTSOCKET];
   return GETSOCK_WRITESOCK(0);
 }
@@ -1510,7 +1444,7 @@
 static CURLcode add_haproxy_protocol_header(struct connectdata *conn)
 {
   char proxy_header[128];
-  Curl_send_buffer *req_buffer;
+  struct dynbuf req;
   CURLcode result;
   char tcp_version[5];
 
@@ -1531,19 +1465,14 @@
             conn->data->info.conn_local_port,
             conn->data->info.conn_primary_port);
 
-  req_buffer = Curl_add_buffer_init();
-  if(!req_buffer)
-    return CURLE_OUT_OF_MEMORY;
+  Curl_dyn_init(&req, DYN_HAXPROXY);
 
-  result = Curl_add_bufferf(&req_buffer, proxy_header);
+  result = Curl_dyn_add(&req, proxy_header);
   if(result)
     return result;
 
-  result = Curl_add_buffer_send(&req_buffer,
-                                conn,
-                                &conn->data->info.request_size,
-                                0,
-                                FIRSTSOCKET);
+  result = Curl_buffer_send(&req, conn, &conn->data->info.request_size,
+                            0, FIRSTSOCKET);
 
   return result;
 }
@@ -1555,6 +1484,13 @@
   CURLcode result;
   DEBUGASSERT((conn) && (conn->handler->flags & PROTOPT_SSL));
 
+#ifdef ENABLE_QUIC
+  if(conn->transport == TRNSPRT_QUIC) {
+    *done = TRUE;
+    return CURLE_OK;
+  }
+#endif
+
   /* perform SSL initialization for this socket */
   result = Curl_ssl_connect_nonblocking(conn, FIRSTSOCKET, done);
   if(result)
@@ -1564,11 +1500,10 @@
 }
 
 static int https_getsock(struct connectdata *conn,
-                         curl_socket_t *socks,
-                         int numsocks)
+                         curl_socket_t *socks)
 {
   if(conn->handler->flags & PROTOPT_SSL)
-    return Curl_ssl_getsock(conn, socks, numsocks);
+    return Curl_ssl_getsock(conn, socks);
   return GETSOCK_BLANK;
 }
 #endif /* USE_SSL */
@@ -1598,13 +1533,11 @@
   if(!http)
     return CURLE_OK;
 
-  if(http->send_buffer) {
-    Curl_add_buffer_free(&http->send_buffer);
-  }
-
-  Curl_http2_done(conn, premature);
-
+  Curl_dyn_free(&http->send_buffer);
+  Curl_http2_done(data, premature);
+  Curl_quic_done(data, premature);
   Curl_mime_cleanpart(&http->form);
+  Curl_dyn_reset(&data->state.headerb);
 
   if(status)
     return status;
@@ -1650,6 +1583,12 @@
 static const char *get_http_string(const struct Curl_easy *data,
                                    const struct connectdata *conn)
 {
+#ifdef ENABLE_QUIC
+  if((data->set.httpversion == CURL_HTTP_VERSION_3) ||
+     (conn->httpversion == 30))
+    return "3";
+#endif
+
 #ifdef USE_NGHTTP2
   if(conn->proto.httpc.h2)
     return "2";
@@ -1664,13 +1603,13 @@
 /* check and possibly add an Expect: header */
 static CURLcode expect100(struct Curl_easy *data,
                           struct connectdata *conn,
-                          Curl_send_buffer *req_buffer)
+                          struct dynbuf *req)
 {
   CURLcode result = CURLE_OK;
   data->state.expect100header = FALSE; /* default to false unless it is set
                                           to TRUE below */
-  if(use_http_1_1plus(data, conn) &&
-     (conn->httpversion != 20)) {
+  if(!data->state.disableexpect && use_http_1_1plus(data, conn) &&
+     (conn->httpversion < 20)) {
     /* if not doing HTTP 1.0 or version 2, or disabled explicitly, we add an
        Expect: 100-continue to the headers which actually speeds up post
        operations (as there is one packet coming back from the web server) */
@@ -1680,8 +1619,7 @@
         Curl_compareheader(ptr, "Expect:", "100-continue");
     }
     else {
-      result = Curl_add_bufferf(&req_buffer,
-                                "Expect: 100-continue\r\n");
+      result = Curl_dyn_add(req, "Expect: 100-continue\r\n");
       if(!result)
         data->state.expect100header = TRUE;
     }
@@ -1700,7 +1638,7 @@
    will return an error code if one of the headers is
    not formatted correctly */
 CURLcode Curl_http_compile_trailers(struct curl_slist *trailers,
-                                    Curl_send_buffer *buffer,
+                                    struct dynbuf *b,
                                     struct Curl_easy *handle)
 {
   char *ptr = NULL;
@@ -1726,8 +1664,10 @@
     /* only add correctly formatted trailers */
     ptr = strchr(trailers->data, ':');
     if(ptr && *(ptr + 1) == ' ') {
-      result = Curl_add_bufferf(&buffer, "%s%s", trailers->data,
-                                endofline_native);
+      result = Curl_dyn_add(b, trailers->data);
+      if(result)
+        return result;
+      result = Curl_dyn_add(b, endofline_native);
       if(result)
         return result;
     }
@@ -1735,14 +1675,13 @@
       infof(handle, "Malformatted trailing header ! Skipping trailer.");
     trailers = trailers->next;
   }
-  result = Curl_add_buffer(&buffer, endofline_network,
-                           strlen(endofline_network));
+  result = Curl_dyn_add(b, endofline_network);
   return result;
 }
 
 CURLcode Curl_add_custom_headers(struct connectdata *conn,
                                  bool is_connect,
-                                 Curl_send_buffer *req_buffer)
+                                 struct dynbuf *req)
 {
   char *ptr;
   struct curl_slist *h[2];
@@ -1751,6 +1690,7 @@
   struct Curl_easy *data = conn->data;
   int i;
 
+#ifndef CURL_DISABLE_PROXY
   enum proxy_use proxy;
 
   if(is_connect)
@@ -1777,6 +1717,10 @@
       h[0] = data->set.headers;
     break;
   }
+#else
+  (void)is_connect;
+  h[0] = data->set.headers;
+#endif
 
   /* loop through one or two lists */
   for(i = 0; i < numlists; i++) {
@@ -1804,7 +1748,7 @@
               /* copy the source */
               semicolonp = strdup(headers->data);
               if(!semicolonp) {
-                Curl_add_buffer_free(&req_buffer);
+                Curl_dyn_free(req);
                 return CURLE_OUT_OF_MEMORY;
               }
               /* put a colon where the semicolon is */
@@ -1828,16 +1772,16 @@
           CURLcode result = CURLE_OK;
           char *compare = semicolonp ? semicolonp : headers->data;
 
-          if(conn->allocptr.host &&
+          if(data->state.aptr.host &&
              /* a Host: header was sent already, don't pass on any custom Host:
                 header as that will produce *two* in the same request! */
              checkprefix("Host:", compare))
             ;
-          else if(data->set.httpreq == HTTPREQ_POST_FORM &&
+          else if(data->state.httpreq == HTTPREQ_POST_FORM &&
                   /* this header (extended by formdata.c) is sent later */
                   checkprefix("Content-Type:", compare))
             ;
-          else if(data->set.httpreq == HTTPREQ_POST_MIME &&
+          else if(data->state.httpreq == HTTPREQ_POST_MIME &&
                   /* this header is sent later */
                   checkprefix("Content-Type:", compare))
             ;
@@ -1846,12 +1790,12 @@
                      we will force length zero then */
                   checkprefix("Content-Length:", compare))
             ;
-          else if(conn->allocptr.te &&
+          else if(data->state.aptr.te &&
                   /* when asking for Transfer-Encoding, don't pass on a custom
                      Connection: */
                   checkprefix("Connection:", compare))
             ;
-          else if((conn->httpversion == 20) &&
+          else if((conn->httpversion >= 20) &&
                   checkprefix("Transfer-Encoding:", compare))
             /* HTTP/2 doesn't support chunked requests */
             ;
@@ -1865,7 +1809,7 @@
                    !strcasecompare(data->state.first_host, conn->host.name)))
             ;
           else {
-            result = Curl_add_bufferf(&req_buffer, "%s\r\n", compare);
+            result = Curl_dyn_addf(req, "%s\r\n", compare);
           }
           if(semicolonp)
             free(semicolonp);
@@ -1881,9 +1825,10 @@
 }
 
 #ifndef CURL_DISABLE_PARSEDATE
-CURLcode Curl_add_timecondition(struct Curl_easy *data,
-                                Curl_send_buffer *req_buffer)
+CURLcode Curl_add_timecondition(const struct connectdata *conn,
+                                struct dynbuf *req)
 {
+  struct Curl_easy *data = conn->data;
   const struct tm *tm;
   struct tm keeptime;
   CURLcode result;
@@ -1916,6 +1861,11 @@
     break;
   }
 
+  if(Curl_checkheaders(conn, condp)) {
+    /* A custom header was specified; it will be sent instead. */
+    return CURLE_OK;
+  }
+
   /* The If-Modified-Since header family should have their times set in
    * GMT as RFC2616 defines: "All HTTP date/time stamps MUST be
    * represented in Greenwich Mean Time (GMT), without exception. For the
@@ -1935,17 +1885,17 @@
             tm->tm_min,
             tm->tm_sec);
 
-  result = Curl_add_buffer(&req_buffer, datestr, strlen(datestr));
+  result = Curl_dyn_add(req, datestr);
 
   return result;
 }
 #else
 /* disabled */
-CURLcode Curl_add_timecondition(struct Curl_easy *data,
-                                Curl_send_buffer *req_buffer)
+CURLcode Curl_add_timecondition(const struct connectdata *conn,
+                                struct dynbuf *req)
 {
-  (void)data;
-  (void)req_buffer;
+  (void)conn;
+  (void)req;
   return CURLE_OK;
 }
 #endif
@@ -1968,63 +1918,66 @@
   const char *te = ""; /* transfer-encoding */
   const char *ptr;
   const char *request;
-  Curl_HttpReq httpreq = data->set.httpreq;
+  Curl_HttpReq httpreq = data->state.httpreq;
 #if !defined(CURL_DISABLE_COOKIES)
   char *addcookies = NULL;
 #endif
   curl_off_t included_body = 0;
   const char *httpstring;
-  Curl_send_buffer *req_buffer;
+  struct dynbuf req;
   curl_off_t postsize = 0; /* curl_off_t to handle large file sizes */
+  char *altused = NULL;
 
   /* Always consider the DO phase done after this function call, even if there
      may be parts of the request that is not yet sent, since we can deal with
      the rest of the request in the PERFORM phase. */
   *done = TRUE;
 
-  if(conn->httpversion < 20) { /* unless the connection is re-used and already
-                                  http2 */
-    switch(conn->negnpn) {
-    case CURL_HTTP_VERSION_2:
-      conn->httpversion = 20; /* we know we're on HTTP/2 now */
-
-      result = Curl_http2_switched(conn, NULL, 0);
-      if(result)
-        return result;
-      break;
-    case CURL_HTTP_VERSION_1_1:
-      /* continue with HTTP/1.1 when explicitly requested */
-      break;
-    default:
-      /* Check if user wants to use HTTP/2 with clear TCP*/
-#ifdef USE_NGHTTP2
-      if(conn->data->set.httpversion ==
-         CURL_HTTP_VERSION_2_PRIOR_KNOWLEDGE) {
-        if(conn->bits.httpproxy && !conn->bits.tunnel_proxy) {
-          /* We don't support HTTP/2 proxies yet. Also it's debatable whether
-             or not this setting should apply to HTTP/2 proxies. */
-          infof(data, "Ignoring HTTP/2 prior knowledge due to proxy\n");
-          break;
-        }
-
-        DEBUGF(infof(data, "HTTP/2 over clean TCP\n"));
-        conn->httpversion = 20;
+  if(conn->transport != TRNSPRT_QUIC) {
+    if(conn->httpversion < 20) { /* unless the connection is re-used and
+                                    already http2 */
+      switch(conn->negnpn) {
+      case CURL_HTTP_VERSION_2:
+        conn->httpversion = 20; /* we know we're on HTTP/2 now */
 
         result = Curl_http2_switched(conn, NULL, 0);
         if(result)
           return result;
-      }
+        break;
+      case CURL_HTTP_VERSION_1_1:
+        /* continue with HTTP/1.1 when explicitly requested */
+        break;
+      default:
+        /* Check if user wants to use HTTP/2 with clear TCP*/
+#ifdef USE_NGHTTP2
+        if(conn->data->set.httpversion ==
+           CURL_HTTP_VERSION_2_PRIOR_KNOWLEDGE) {
+#ifndef CURL_DISABLE_PROXY
+          if(conn->bits.httpproxy && !conn->bits.tunnel_proxy) {
+            /* We don't support HTTP/2 proxies yet. Also it's debatable
+               whether or not this setting should apply to HTTP/2 proxies. */
+            infof(data, "Ignoring HTTP/2 prior knowledge due to proxy\n");
+            break;
+          }
 #endif
-      break;
+          DEBUGF(infof(data, "HTTP/2 over clean TCP\n"));
+          conn->httpversion = 20;
+
+          result = Curl_http2_switched(conn, NULL, 0);
+          if(result)
+            return result;
+        }
+#endif
+        break;
+      }
+    }
+    else {
+      /* prepare for a http2 request */
+      result = Curl_http2_setup(conn);
+      if(result)
+        return result;
     }
   }
-  else {
-    /* prepare for a http2 request */
-    result = Curl_http2_setup(conn);
-    if(result)
-      return result;
-  }
-
   http = data->req.protop;
   DEBUGASSERT(http);
 
@@ -2080,8 +2033,8 @@
      with the user-agent string specified, we erase the previously made string
      here. */
   if(Curl_checkheaders(conn, "User-Agent")) {
-    free(conn->allocptr.uagent);
-    conn->allocptr.uagent = NULL;
+    free(data->state.aptr.uagent);
+    data->state.aptr.uagent = NULL;
   }
 
   /* setup the authentication headers */
@@ -2109,14 +2062,14 @@
   else
     conn->bits.authneg = FALSE;
 
-  Curl_safefree(conn->allocptr.ref);
+  Curl_safefree(data->state.aptr.ref);
   if(data->change.referer && !Curl_checkheaders(conn, "Referer")) {
-    conn->allocptr.ref = aprintf("Referer: %s\r\n", data->change.referer);
-    if(!conn->allocptr.ref)
+    data->state.aptr.ref = aprintf("Referer: %s\r\n", data->change.referer);
+    if(!data->state.aptr.ref)
       return CURLE_OUT_OF_MEMORY;
   }
   else
-    conn->allocptr.ref = NULL;
+    data->state.aptr.ref = NULL;
 
 #if !defined(CURL_DISABLE_COOKIES)
   if(data->set.str[STRING_COOKIE] && !Curl_checkheaders(conn, "Cookie"))
@@ -2125,15 +2078,15 @@
 
   if(!Curl_checkheaders(conn, "Accept-Encoding") &&
      data->set.str[STRING_ENCODING]) {
-    Curl_safefree(conn->allocptr.accept_encoding);
-    conn->allocptr.accept_encoding =
+    Curl_safefree(data->state.aptr.accept_encoding);
+    data->state.aptr.accept_encoding =
       aprintf("Accept-Encoding: %s\r\n", data->set.str[STRING_ENCODING]);
-    if(!conn->allocptr.accept_encoding)
+    if(!data->state.aptr.accept_encoding)
       return CURLE_OUT_OF_MEMORY;
   }
   else {
-    Curl_safefree(conn->allocptr.accept_encoding);
-    conn->allocptr.accept_encoding = NULL;
+    Curl_safefree(data->state.aptr.accept_encoding);
+    data->state.aptr.accept_encoding = NULL;
   }
 
 #ifdef HAVE_LIBZ
@@ -2149,7 +2102,7 @@
     char *cptr = Curl_checkheaders(conn, "Connection");
 #define TE_HEADER "TE: gzip\r\n"
 
-    Curl_safefree(conn->allocptr.te);
+    Curl_safefree(data->state.aptr.te);
 
     if(cptr) {
       cptr = Curl_copy_header_value(cptr);
@@ -2158,11 +2111,11 @@
     }
 
     /* Create the (updated) Connection: header */
-    conn->allocptr.te = aprintf("Connection: %s%sTE\r\n" TE_HEADER,
+    data->state.aptr.te = aprintf("Connection: %s%sTE\r\n" TE_HEADER,
                                 cptr ? cptr : "", (cptr && *cptr) ? ", ":"");
 
     free(cptr);
-    if(!conn->allocptr.te)
+    if(!data->state.aptr.te)
       return CURLE_OUT_OF_MEMORY;
   }
 #endif
@@ -2220,14 +2173,16 @@
   else {
     if((conn->handler->protocol & PROTO_FAMILY_HTTP) &&
        (((httpreq == HTTPREQ_POST_MIME || httpreq == HTTPREQ_POST_FORM) &&
-       http->postsize < 0) ||
-       (data->set.upload && data->state.infilesize == -1))) {
+         http->postsize < 0) ||
+        ((data->set.upload || httpreq == HTTPREQ_POST) &&
+         data->state.infilesize == -1))) {
       if(conn->bits.authneg)
         /* don't enable chunked during auth neg */
         ;
       else if(use_http_1_1plus(data, conn)) {
-        /* HTTP, upload, unknown file size and not HTTP 1.0 */
-        data->req.upload_chunky = TRUE;
+        if(conn->httpversion < 20)
+          /* HTTP, upload, unknown file size and not HTTP 1.0 */
+          data->req.upload_chunky = TRUE;
       }
       else {
         failf(data, "Chunky upload is not supported by HTTP 1.0");
@@ -2243,7 +2198,7 @@
       te = "Transfer-Encoding: chunked\r\n";
   }
 
-  Curl_safefree(conn->allocptr.host);
+  Curl_safefree(data->state.aptr.host);
 
   ptr = Curl_checkheaders(conn, "Host");
   if(ptr && (!data->state.this_is_a_follow ||
@@ -2278,19 +2233,19 @@
         if(colon)
           *colon = 0; /* The host must not include an embedded port number */
       }
-      Curl_safefree(conn->allocptr.cookiehost);
-      conn->allocptr.cookiehost = cookiehost;
+      Curl_safefree(data->state.aptr.cookiehost);
+      data->state.aptr.cookiehost = cookiehost;
     }
 #endif
 
     if(strcmp("Host:", ptr)) {
-      conn->allocptr.host = aprintf("Host:%s\r\n", &ptr[5]);
-      if(!conn->allocptr.host)
+      data->state.aptr.host = aprintf("Host:%s\r\n", &ptr[5]);
+      if(!data->state.aptr.host)
         return CURLE_OUT_OF_MEMORY;
     }
     else
       /* when clearing the header */
-      conn->allocptr.host = NULL;
+      data->state.aptr.host = NULL;
   }
   else {
     /* When building Host: headers, we must put the host name within
@@ -2302,18 +2257,18 @@
         (conn->remote_port == PORT_HTTP)) )
       /* if(HTTPS on port 443) OR (HTTP on port 80) then don't include
          the port number in the host string */
-      conn->allocptr.host = aprintf("Host: %s%s%s\r\n",
+      data->state.aptr.host = aprintf("Host: %s%s%s\r\n",
                                     conn->bits.ipv6_ip?"[":"",
                                     host,
                                     conn->bits.ipv6_ip?"]":"");
     else
-      conn->allocptr.host = aprintf("Host: %s%s%s:%d\r\n",
+      data->state.aptr.host = aprintf("Host: %s%s%s:%d\r\n",
                                     conn->bits.ipv6_ip?"[":"",
                                     host,
                                     conn->bits.ipv6_ip?"]":"",
                                     conn->remote_port);
 
-    if(!conn->allocptr.host)
+    if(!data->state.aptr.host)
       /* without Host: we can't make a nice request */
       return CURLE_OUT_OF_MEMORY;
   }
@@ -2328,7 +2283,6 @@
 
     /* and no fragment part */
     CURLUcode uc;
-    char *url;
     CURLU *h = curl_url_dup(data->state.uh);
     if(!h)
       return CURLE_OUT_OF_MEMORY;
@@ -2359,19 +2313,15 @@
         return CURLE_OUT_OF_MEMORY;
       }
     }
-    /* now extract the new version of the URL */
-    uc = curl_url_get(h, CURLUPART_URL, &url, 0);
+    /* Extract the URL to use in the request. Store in STRING_TEMP_URL for
+       clean-up reasons if the function returns before the free() further
+       down. */
+    uc = curl_url_get(h, CURLUPART_URL, &data->set.str[STRING_TEMP_URL], 0);
     if(uc) {
       curl_url_cleanup(h);
       return CURLE_OUT_OF_MEMORY;
     }
 
-    if(data->change.url_alloc)
-      free(data->change.url);
-
-    data->change.url = url;
-    data->change.url_alloc = TRUE;
-
     curl_url_cleanup(h);
 
     if(strcasecompare("ftp", data->state.up.scheme)) {
@@ -2399,7 +2349,7 @@
                     data->set.prefer_ascii ? 'a' : 'i');
         }
       }
-      if(conn->bits.user_passwd && !conn->bits.userpwd_in_url)
+      if(conn->bits.user_passwd)
         paste_ftp_userpwd = TRUE;
     }
   }
@@ -2489,21 +2439,21 @@
     if(((httpreq == HTTPREQ_GET) || (httpreq == HTTPREQ_HEAD)) &&
        !Curl_checkheaders(conn, "Range")) {
       /* if a line like this was already allocated, free the previous one */
-      free(conn->allocptr.rangeline);
-      conn->allocptr.rangeline = aprintf("Range: bytes=%s\r\n",
+      free(data->state.aptr.rangeline);
+      data->state.aptr.rangeline = aprintf("Range: bytes=%s\r\n",
                                          data->state.range);
     }
     else if((httpreq == HTTPREQ_POST || httpreq == HTTPREQ_PUT) &&
             !Curl_checkheaders(conn, "Content-Range")) {
 
       /* if a line like this was already allocated, free the previous one */
-      free(conn->allocptr.rangeline);
+      free(data->state.aptr.rangeline);
 
       if(data->set.set_resume_from < 0) {
         /* Upload resume was asked for, but we don't know the size of the
            remote part so we tell the server (and act accordingly) that we
            upload the whole file (again) */
-        conn->allocptr.rangeline =
+        data->state.aptr.rangeline =
           aprintf("Content-Range: bytes 0-%" CURL_FORMAT_CURL_OFF_T
                   "/%" CURL_FORMAT_CURL_OFF_T "\r\n",
                   data->state.infilesize - 1, data->state.infilesize);
@@ -2513,7 +2463,7 @@
         /* This is because "resume" was selected */
         curl_off_t total_expected_size =
           data->state.resume_from + data->state.infilesize;
-        conn->allocptr.rangeline =
+        data->state.aptr.rangeline =
           aprintf("Content-Range: bytes %s%" CURL_FORMAT_CURL_OFF_T
                   "/%" CURL_FORMAT_CURL_OFF_T "\r\n",
                   data->state.range, total_expected_size-1,
@@ -2522,11 +2472,11 @@
       else {
         /* Range was selected and then we just pass the incoming range and
            append total size */
-        conn->allocptr.rangeline =
+        data->state.aptr.rangeline =
           aprintf("Content-Range: bytes %s/%" CURL_FORMAT_CURL_OFF_T "\r\n",
                   data->state.range, data->state.infilesize);
       }
-      if(!conn->allocptr.rangeline)
+      if(!data->state.aptr.rangeline)
         return CURLE_OUT_OF_MEMORY;
     }
   }
@@ -2534,14 +2484,11 @@
   httpstring = get_http_string(data, conn);
 
   /* initialize a dynamic send-buffer */
-  req_buffer = Curl_add_buffer_init();
-
-  if(!req_buffer)
-    return CURLE_OUT_OF_MEMORY;
+  Curl_dyn_init(&req, DYN_HTTP_REQUEST);
 
   /* add the main request stuff */
   /* GET/HEAD/POST/PUT */
-  result = Curl_add_bufferf(&req_buffer, "%s ", request);
+  result = Curl_dyn_addf(&req, "%s ", request);
   if(result)
     return result;
 
@@ -2550,72 +2497,92 @@
     query = NULL;
   }
 
+#ifndef CURL_DISABLE_PROXY
   /* url */
   if(conn->bits.httpproxy && !conn->bits.tunnel_proxy) {
-    char *url = data->change.url;
-    result = Curl_add_buffer(&req_buffer, url, strlen(url));
+    char *url = data->set.str[STRING_TEMP_URL];
+    result = Curl_dyn_add(&req, url);
+    Curl_safefree(data->set.str[STRING_TEMP_URL]);
   }
-  else if(paste_ftp_userpwd)
-    result = Curl_add_bufferf(&req_buffer, "ftp://%s:%s@%s",
-                              conn->user, conn->passwd,
-                              path + sizeof("ftp://") - 1);
+  else
+#endif
+  if(paste_ftp_userpwd)
+    result = Curl_dyn_addf(&req, "ftp://%s:%s@%s", conn->user, conn->passwd,
+                           path + sizeof("ftp://") - 1);
   else {
-    result = Curl_add_buffer(&req_buffer, path, strlen(path));
+    result = Curl_dyn_add(&req, path);
     if(result)
       return result;
     if(query)
-      result = Curl_add_bufferf(&req_buffer, "?%s", query);
+      result = Curl_dyn_addf(&req, "?%s", query);
   }
   if(result)
     return result;
 
+#ifdef USE_ALTSVC
+  if(conn->bits.altused && !Curl_checkheaders(conn, "Alt-Used")) {
+    altused = aprintf("Alt-Used: %s:%d\r\n",
+                      conn->conn_to_host.name, conn->conn_to_port);
+    if(!altused) {
+      Curl_dyn_free(&req);
+      return CURLE_OUT_OF_MEMORY;
+    }
+  }
+#endif
   result =
-    Curl_add_bufferf(&req_buffer,
-                     "%s" /* ftp typecode (;type=x) */
-                     " HTTP/%s\r\n" /* HTTP version */
-                     "%s" /* host */
-                     "%s" /* proxyuserpwd */
-                     "%s" /* userpwd */
-                     "%s" /* range */
-                     "%s" /* user agent */
-                     "%s" /* accept */
-                     "%s" /* TE: */
-                     "%s" /* accept-encoding */
-                     "%s" /* referer */
-                     "%s" /* Proxy-Connection */
-                     "%s",/* transfer-encoding */
+    Curl_dyn_addf(&req,
+                  "%s" /* ftp typecode (;type=x) */
+                  " HTTP/%s\r\n" /* HTTP version */
+                  "%s" /* host */
+                  "%s" /* proxyuserpwd */
+                  "%s" /* userpwd */
+                  "%s" /* range */
+                  "%s" /* user agent */
+                  "%s" /* accept */
+                  "%s" /* TE: */
+                  "%s" /* accept-encoding */
+                  "%s" /* referer */
+                  "%s" /* Proxy-Connection */
+                  "%s" /* transfer-encoding */
+                  "%s",/* Alt-Used */
 
-                     ftp_typecode,
-                     httpstring,
-                     (conn->allocptr.host?conn->allocptr.host:""),
-                     conn->allocptr.proxyuserpwd?
-                     conn->allocptr.proxyuserpwd:"",
-                     conn->allocptr.userpwd?conn->allocptr.userpwd:"",
-                     (data->state.use_range && conn->allocptr.rangeline)?
-                     conn->allocptr.rangeline:"",
-                     (data->set.str[STRING_USERAGENT] &&
-                      *data->set.str[STRING_USERAGENT] &&
-                      conn->allocptr.uagent)?
-                     conn->allocptr.uagent:"",
-                     http->p_accept?http->p_accept:"",
-                     conn->allocptr.te?conn->allocptr.te:"",
-                     (data->set.str[STRING_ENCODING] &&
-                      *data->set.str[STRING_ENCODING] &&
-                      conn->allocptr.accept_encoding)?
-                     conn->allocptr.accept_encoding:"",
-                     (data->change.referer && conn->allocptr.ref)?
-                     conn->allocptr.ref:"" /* Referer: <data> */,
-                     (conn->bits.httpproxy &&
-                      !conn->bits.tunnel_proxy &&
-                      !Curl_checkProxyheaders(conn, "Proxy-Connection"))?
-                     "Proxy-Connection: Keep-Alive\r\n":"",
-                     te
+                  ftp_typecode,
+                  httpstring,
+                  (data->state.aptr.host?data->state.aptr.host:""),
+                  data->state.aptr.proxyuserpwd?
+                  data->state.aptr.proxyuserpwd:"",
+                  data->state.aptr.userpwd?data->state.aptr.userpwd:"",
+                  (data->state.use_range && data->state.aptr.rangeline)?
+                  data->state.aptr.rangeline:"",
+                  (data->set.str[STRING_USERAGENT] &&
+                   *data->set.str[STRING_USERAGENT] &&
+                   data->state.aptr.uagent)?
+                  data->state.aptr.uagent:"",
+                  http->p_accept?http->p_accept:"",
+                  data->state.aptr.te?data->state.aptr.te:"",
+                  (data->set.str[STRING_ENCODING] &&
+                   *data->set.str[STRING_ENCODING] &&
+                   data->state.aptr.accept_encoding)?
+                  data->state.aptr.accept_encoding:"",
+                  (data->change.referer && data->state.aptr.ref)?
+                  data->state.aptr.ref:"" /* Referer: <data> */,
+#ifndef CURL_DISABLE_PROXY
+                  (conn->bits.httpproxy &&
+                   !conn->bits.tunnel_proxy &&
+                   !Curl_checkProxyheaders(conn, "Proxy-Connection"))?
+                  "Proxy-Connection: Keep-Alive\r\n":"",
+#else
+                  "",
+#endif
+                  te,
+                  altused ? altused : ""
       );
 
   /* clear userpwd and proxyuserpwd to avoid re-using old credentials
    * from re-used connections */
-  Curl_safefree(conn->allocptr.userpwd);
-  Curl_safefree(conn->allocptr.proxyuserpwd);
+  Curl_safefree(data->state.aptr.userpwd);
+  Curl_safefree(data->state.aptr.proxyuserpwd);
+  free(altused);
 
   if(result)
     return result;
@@ -2625,7 +2592,7 @@
      (data->set.httpversion == CURL_HTTP_VERSION_2)) {
     /* append HTTP2 upgrade magic stuff to the HTTP request if it isn't done
        over SSL */
-    result = Curl_http2_request_upgrade(req_buffer, conn);
+    result = Curl_http2_request_upgrade(&req, conn);
     if(result)
       return result;
   }
@@ -2635,11 +2602,11 @@
     struct Cookie *co = NULL; /* no cookies from start */
     int count = 0;
 
-    if(data->cookies) {
+    if(data->cookies && data->state.cookie_engine) {
       Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, CURL_LOCK_ACCESS_SINGLE);
       co = Curl_cookie_getlist(data->cookies,
-                               conn->allocptr.cookiehost?
-                               conn->allocptr.cookiehost:host,
+                               data->state.aptr.cookiehost?
+                               data->state.aptr.cookiehost:host,
                                data->state.up.path,
                                (conn->handler->protocol&CURLPROTO_HTTPS)?
                                TRUE:FALSE);
@@ -2651,13 +2618,12 @@
       while(co) {
         if(co->value) {
           if(0 == count) {
-            result = Curl_add_bufferf(&req_buffer, "Cookie: ");
+            result = Curl_dyn_add(&req, "Cookie: ");
             if(result)
               break;
           }
-          result = Curl_add_bufferf(&req_buffer,
-                                    "%s%s=%s", count?"; ":"",
-                                    co->name, co->value);
+          result = Curl_dyn_addf(&req, "%s%s=%s", count?"; ":"",
+                                 co->name, co->value);
           if(result)
             break;
           count++;
@@ -2668,26 +2634,25 @@
     }
     if(addcookies && !result) {
       if(!count)
-        result = Curl_add_bufferf(&req_buffer, "Cookie: ");
+        result = Curl_dyn_add(&req, "Cookie: ");
       if(!result) {
-        result = Curl_add_bufferf(&req_buffer, "%s%s", count?"; ":"",
-                                  addcookies);
+        result = Curl_dyn_addf(&req, "%s%s", count?"; ":"", addcookies);
         count++;
       }
     }
     if(count && !result)
-      result = Curl_add_buffer(&req_buffer, "\r\n", 2);
+      result = Curl_dyn_add(&req, "\r\n");
 
     if(result)
       return result;
   }
 #endif
 
-  result = Curl_add_timecondition(data, req_buffer);
+  result = Curl_add_timecondition(conn, &req);
   if(result)
     return result;
 
-  result = Curl_add_custom_headers(conn, FALSE, req_buffer);
+  result = Curl_add_custom_headers(conn, FALSE, &req);
   if(result)
     return result;
 
@@ -2710,20 +2675,20 @@
     if((postsize != -1) && !data->req.upload_chunky &&
        (conn->bits.authneg || !Curl_checkheaders(conn, "Content-Length"))) {
       /* only add Content-Length if not uploading chunked */
-      result = Curl_add_bufferf(&req_buffer,
-                                "Content-Length: %" CURL_FORMAT_CURL_OFF_T
-                                "\r\n", postsize);
+      result = Curl_dyn_addf(&req, "Content-Length: %" CURL_FORMAT_CURL_OFF_T
+                             "\r\n", postsize);
       if(result)
         return result;
     }
 
     if(postsize != 0) {
-      result = expect100(data, conn, req_buffer);
+      result = expect100(data, conn, &req);
       if(result)
         return result;
     }
 
-    result = Curl_add_buffer(&req_buffer, "\r\n", 2); /* end of headers */
+    /* end of headers */
+    result = Curl_dyn_add(&req, "\r\n");
     if(result)
       return result;
 
@@ -2731,8 +2696,8 @@
     Curl_pgrsSetUploadSize(data, postsize);
 
     /* this sends the buffer and frees all the buffer resources */
-    result = Curl_add_buffer_send(&req_buffer, conn,
-                                  &data->info.request_size, 0, FIRSTSOCKET);
+    result = Curl_buffer_send(&req, conn, &data->info.request_size, 0,
+                              FIRSTSOCKET);
     if(result)
       failf(data, "Failed sending PUT request");
     else
@@ -2748,12 +2713,12 @@
     /* This is form posting using mime data. */
     if(conn->bits.authneg) {
       /* nothing to post! */
-      result = Curl_add_bufferf(&req_buffer, "Content-Length: 0\r\n\r\n");
+      result = Curl_dyn_add(&req, "Content-Length: 0\r\n\r\n");
       if(result)
         return result;
 
-      result = Curl_add_buffer_send(&req_buffer, conn,
-                                    &data->info.request_size, 0, FIRSTSOCKET);
+      result = Curl_buffer_send(&req, conn, &data->info.request_size, 0,
+                                FIRSTSOCKET);
       if(result)
         failf(data, "Failed sending POST request");
       else
@@ -2771,9 +2736,9 @@
        (conn->bits.authneg || !Curl_checkheaders(conn, "Content-Length"))) {
       /* we allow replacing this header if not during auth negotiation,
          although it isn't very wise to actually set your own */
-      result = Curl_add_bufferf(&req_buffer,
-                                "Content-Length: %" CURL_FORMAT_CURL_OFF_T
-                                "\r\n", postsize);
+      result = Curl_dyn_addf(&req,
+                             "Content-Length: %" CURL_FORMAT_CURL_OFF_T
+                             "\r\n", postsize);
       if(result)
         return result;
     }
@@ -2784,7 +2749,7 @@
       struct curl_slist *hdr;
 
       for(hdr = http->sendit->curlheaders; hdr; hdr = hdr->next) {
-        result = Curl_add_bufferf(&req_buffer, "%s\r\n", hdr->data);
+        result = Curl_dyn_addf(&req, "%s\r\n", hdr->data);
         if(result)
           return result;
       }
@@ -2801,7 +2766,7 @@
         Curl_compareheader(ptr, "Expect:", "100-continue");
     }
     else if(postsize > EXPECT_100_THRESHOLD || postsize < 0) {
-      result = expect100(data, conn, req_buffer);
+      result = expect100(data, conn, &req);
       if(result)
         return result;
     }
@@ -2809,7 +2774,7 @@
       data->state.expect100header = FALSE;
 
     /* make the request end in a true CRLF */
-    result = Curl_add_buffer(&req_buffer, "\r\n", 2);
+    result = Curl_dyn_add(&req, "\r\n");
     if(result)
       return result;
 
@@ -2822,8 +2787,8 @@
     http->sending = HTTPSEND_BODY;
 
     /* this sends the buffer and frees all the buffer resources */
-    result = Curl_add_buffer_send(&req_buffer, conn,
-                                  &data->info.request_size, 0, FIRSTSOCKET);
+    result = Curl_buffer_send(&req, conn, &data->info.request_size, 0,
+                              FIRSTSOCKET);
     if(result)
       failf(data, "Failed sending POST request");
     else
@@ -2851,17 +2816,15 @@
        (conn->bits.authneg || !Curl_checkheaders(conn, "Content-Length"))) {
       /* we allow replacing this header if not during auth negotiation,
          although it isn't very wise to actually set your own */
-      result = Curl_add_bufferf(&req_buffer,
-                                "Content-Length: %" CURL_FORMAT_CURL_OFF_T
-                                "\r\n", postsize);
+      result = Curl_dyn_addf(&req, "Content-Length: %" CURL_FORMAT_CURL_OFF_T
+                             "\r\n", postsize);
       if(result)
         return result;
     }
 
     if(!Curl_checkheaders(conn, "Content-Type")) {
-      result = Curl_add_bufferf(&req_buffer,
-                                "Content-Type: application/"
-                                "x-www-form-urlencoded\r\n");
+      result = Curl_dyn_add(&req, "Content-Type: application/"
+                            "x-www-form-urlencoded\r\n");
       if(result)
         return result;
     }
@@ -2876,7 +2839,7 @@
         Curl_compareheader(ptr, "Expect:", "100-continue");
     }
     else if(postsize > EXPECT_100_THRESHOLD || postsize < 0) {
-      result = expect100(data, conn, req_buffer);
+      result = expect100(data, conn, &req);
       if(result)
         return result;
     }
@@ -2897,31 +2860,32 @@
            is no magic limit but only set to prevent really huge POSTs to
            get the data duplicated with malloc() and family. */
 
-        result = Curl_add_buffer(&req_buffer, "\r\n", 2); /* end of headers! */
+        /* end of headers! */
+        result = Curl_dyn_add(&req, "\r\n");
         if(result)
           return result;
 
         if(!data->req.upload_chunky) {
           /* We're not sending it 'chunked', append it to the request
              already now to reduce the number if send() calls */
-          result = Curl_add_buffer(&req_buffer, data->set.postfields,
-                                   (size_t)postsize);
+          result = Curl_dyn_addn(&req, data->set.postfields,
+                                 (size_t)postsize);
           included_body = postsize;
         }
         else {
           if(postsize) {
             /* Append the POST data chunky-style */
-            result = Curl_add_bufferf(&req_buffer, "%x\r\n", (int)postsize);
+            result = Curl_dyn_addf(&req, "%x\r\n", (int)postsize);
             if(!result) {
-              result = Curl_add_buffer(&req_buffer, data->set.postfields,
-                                       (size_t)postsize);
+              result = Curl_dyn_addn(&req, data->set.postfields,
+                                     (size_t)postsize);
               if(!result)
-                result = Curl_add_buffer(&req_buffer, "\r\n", 2);
+                result = Curl_dyn_add(&req, "\r\n");
               included_body = postsize + 2;
             }
           }
           if(!result)
-            result = Curl_add_buffer(&req_buffer, "\x30\x0d\x0a\x0d\x0a", 5);
+            result = Curl_dyn_add(&req, "\x30\x0d\x0a\x0d\x0a");
           /* 0  CR  LF  CR  LF */
           included_body += 5;
         }
@@ -2943,21 +2907,22 @@
         /* set the upload size to the progress meter */
         Curl_pgrsSetUploadSize(data, http->postsize);
 
-        result = Curl_add_buffer(&req_buffer, "\r\n", 2); /* end of headers! */
+        /* end of headers! */
+        result = Curl_dyn_add(&req, "\r\n");
         if(result)
           return result;
       }
     }
     else {
-      result = Curl_add_buffer(&req_buffer, "\r\n", 2); /* end of headers! */
+       /* end of headers! */
+      result = Curl_dyn_add(&req, "\r\n");
       if(result)
         return result;
 
       if(data->req.upload_chunky && conn->bits.authneg) {
         /* Chunky upload is selected and we're negotiating auth still, send
            end-of-data only */
-        result = Curl_add_buffer(&req_buffer,
-                                 "\x30\x0d\x0a\x0d\x0a", 5);
+        result = Curl_dyn_add(&req, (char *)"\x30\x0d\x0a\x0d\x0a");
         /* 0  CR  LF  CR  LF */
         if(result)
           return result;
@@ -2977,8 +2942,8 @@
       }
     }
     /* issue the request */
-    result = Curl_add_buffer_send(&req_buffer, conn, &data->info.request_size,
-                                  (size_t)included_body, FIRSTSOCKET);
+    result = Curl_buffer_send(&req, conn, &data->info.request_size,
+                              (size_t)included_body, FIRSTSOCKET);
 
     if(result)
       failf(data, "Failed sending HTTP POST request");
@@ -2988,23 +2953,24 @@
     break;
 
   default:
-    result = Curl_add_buffer(&req_buffer, "\r\n", 2);
+    result = Curl_dyn_add(&req, "\r\n");
     if(result)
       return result;
 
     /* issue the request */
-    result = Curl_add_buffer_send(&req_buffer, conn,
-                                  &data->info.request_size, 0, FIRSTSOCKET);
+    result = Curl_buffer_send(&req, conn, &data->info.request_size, 0,
+                              FIRSTSOCKET);
 
     if(result)
       failf(data, "Failed sending HTTP request");
     else
       /* HTTP GET/HEAD download: */
-      Curl_setup_transfer(data, FIRSTSOCKET, -1, TRUE,
-                          http->postdata?FIRSTSOCKET:-1);
+      Curl_setup_transfer(data, FIRSTSOCKET, -1, TRUE, -1);
   }
   if(result)
     return result;
+  if(!postsize && (http->sending != HTTPSEND_REQUEST))
+    data->req.upload_done = TRUE;
 
   if(data->req.writebytecount) {
     /* if a request-body has been sent off, we make sure this progress is noted
@@ -3138,52 +3104,10 @@
   return checkhttpprefix(data, s, len);
 }
 
-/*
- * header_append() copies a chunk of data to the end of the already received
- * header. We make sure that the full string fit in the allocated header
- * buffer, or else we enlarge it.
- */
-static CURLcode header_append(struct Curl_easy *data,
-                              struct SingleRequest *k,
-                              size_t length)
-{
-  size_t newsize = k->hbuflen + length;
-  if(newsize > CURL_MAX_HTTP_HEADER) {
-    /* The reason to have a max limit for this is to avoid the risk of a bad
-       server feeding libcurl with a never-ending header that will cause
-       reallocs infinitely */
-    failf(data, "Rejected %zu bytes header (max is %d)!", newsize,
-          CURL_MAX_HTTP_HEADER);
-    return CURLE_OUT_OF_MEMORY;
-  }
-  if(newsize >= data->state.headersize) {
-    /* We enlarge the header buffer as it is too small */
-    char *newbuff;
-    size_t hbufp_index;
-
-    newsize = CURLMAX((k->hbuflen + length) * 3 / 2, data->state.headersize*2);
-    hbufp_index = k->hbufp - data->state.headerbuff;
-    newbuff = realloc(data->state.headerbuff, newsize);
-    if(!newbuff) {
-      failf(data, "Failed to alloc memory for big header!");
-      return CURLE_OUT_OF_MEMORY;
-    }
-    data->state.headersize = newsize;
-    data->state.headerbuff = newbuff;
-    k->hbufp = data->state.headerbuff + hbufp_index;
-  }
-  memcpy(k->hbufp, k->str_start, length);
-  k->hbufp += length;
-  k->hbuflen += length;
-  *k->hbufp = 0;
-
-  return CURLE_OK;
-}
-
 static void print_http_error(struct Curl_easy *data)
 {
   struct SingleRequest *k = &data->req;
-  char *beg = k->p;
+  char *beg = Curl_dyn_ptr(&data->state.headerb);
 
   /* make sure that data->req.p points to the HTTP status line */
   if(!strncmp(beg, "HTTP", 4)) {
@@ -3221,14 +3145,17 @@
  * Read any HTTP header lines from the server and pass them to the client app.
  */
 CURLcode Curl_http_readwrite_headers(struct Curl_easy *data,
-                                       struct connectdata *conn,
-                                       ssize_t *nread,
-                                       bool *stop_reading)
+                                     struct connectdata *conn,
+                                     ssize_t *nread,
+                                     bool *stop_reading)
 {
   CURLcode result;
   struct SingleRequest *k = &data->req;
   ssize_t onread = *nread;
   char *ostr = k->str;
+  char *headp;
+  char *str_start;
+  char *end_ptr;
 
   /* header line within buffer loop */
   do {
@@ -3237,22 +3164,25 @@
     int writetype;
 
     /* str_start is start of line within buf */
-    k->str_start = k->str;
+    str_start = k->str;
 
     /* data is in network encoding so use 0x0a instead of '\n' */
-    k->end_ptr = memchr(k->str_start, 0x0a, *nread);
+    end_ptr = memchr(str_start, 0x0a, *nread);
 
-    if(!k->end_ptr) {
+    if(!end_ptr) {
       /* Not a complete header line within buffer, append the data to
          the end of the headerbuff. */
-      result = header_append(data, k, *nread);
+      result = Curl_dyn_addn(&data->state.headerb, str_start, *nread);
       if(result)
         return result;
 
       if(!k->headerline) {
         /* check if this looks like a protocol header */
-        statusline st = checkprotoprefix(data, conn, data->state.headerbuff,
-                                         k->hbuflen);
+        statusline st =
+          checkprotoprefix(data, conn,
+                           Curl_dyn_ptr(&data->state.headerb),
+                           Curl_dyn_len(&data->state.headerb));
+
         if(st == STATUS_BAD) {
           /* this is not the beginning of a protocol first header line */
           k->header = FALSE;
@@ -3270,28 +3200,26 @@
     }
 
     /* decrease the size of the remaining (supposed) header line */
-    rest_length = (k->end_ptr - k->str) + 1;
+    rest_length = (end_ptr - k->str) + 1;
     *nread -= (ssize_t)rest_length;
 
-    k->str = k->end_ptr + 1; /* move past new line */
+    k->str = end_ptr + 1; /* move past new line */
 
-    full_length = k->str - k->str_start;
+    full_length = k->str - str_start;
 
-    result = header_append(data, k, full_length);
+    result = Curl_dyn_addn(&data->state.headerb, str_start, full_length);
     if(result)
       return result;
 
-    k->end_ptr = k->hbufp;
-    k->p = data->state.headerbuff;
-
     /****
-     * We now have a FULL header line that p points to
+     * We now have a FULL header line in 'headerb'.
      *****/
 
     if(!k->headerline) {
       /* the first read header */
-      statusline st = checkprotoprefix(data, conn, data->state.headerbuff,
-                                       k->hbuflen);
+      statusline st = checkprotoprefix(data, conn,
+                                       Curl_dyn_ptr(&data->state.headerb),
+                                       Curl_dyn_len(&data->state.headerb));
       if(st == STATUS_BAD) {
         streamclose(conn, "bad HTTP: No end-of-message indicator");
         /* this is not the beginning of a protocol first header line */
@@ -3314,26 +3242,27 @@
       }
     }
 
-    /* headers are in network encoding so
-       use 0x0a and 0x0d instead of '\n' and '\r' */
-    if((0x0a == *k->p) || (0x0d == *k->p)) {
+    /* headers are in network encoding so use 0x0a and 0x0d instead of '\n'
+       and '\r' */
+    headp = Curl_dyn_ptr(&data->state.headerb);
+    if((0x0a == *headp) || (0x0d == *headp)) {
       size_t headerlen;
       /* Zero-length header line means end of headers! */
 
 #ifdef CURL_DOES_CONVERSIONS
-      if(0x0d == *k->p) {
-        *k->p = '\r'; /* replace with CR in host encoding */
-        k->p++;       /* pass the CR byte */
+      if(0x0d == *headp) {
+        *headp = '\r'; /* replace with CR in host encoding */
+        headp++;       /* pass the CR byte */
       }
-      if(0x0a == *k->p) {
-        *k->p = '\n'; /* replace with LF in host encoding */
-        k->p++;       /* pass the LF byte */
+      if(0x0a == *headp) {
+        *headp = '\n'; /* replace with LF in host encoding */
+        headp++;       /* pass the LF byte */
       }
 #else
-      if('\r' == *k->p)
-        k->p++; /* pass the \r byte */
-      if('\n' == *k->p)
-        k->p++; /* pass the \n byte */
+      if('\r' == *headp)
+        headp++; /* pass the \r byte */
+      if('\n' == *headp)
+        headp++; /* pass the \n byte */
 #endif /* CURL_DOES_CONVERSIONS */
 
       if(100 <= k->httpcode && 199 >= k->httpcode) {
@@ -3394,7 +3323,7 @@
         if((k->size == -1) && !k->chunk && !conn->bits.close &&
            (conn->httpversion == 11) &&
            !(conn->handler->protocol & CURLPROTO_RTSP) &&
-           data->set.httpreq != HTTPREQ_HEAD) {
+           data->state.httpreq != HTTPREQ_HEAD) {
           /* On HTTP 1.1, when connection is not to get closed, but no
              Content-Length nor Transfer-Encoding chunked have been
              received, according to RFC2616 section 4.4 point 5, we
@@ -3452,10 +3381,9 @@
       if(data->set.include_header)
         writetype |= CLIENTWRITE_BODY;
 
-      headerlen = k->p - data->state.headerbuff;
-
+      headerlen = Curl_dyn_len(&data->state.headerb);
       result = Curl_client_write(conn, writetype,
-                                 data->state.headerbuff,
+                                 Curl_dyn_ptr(&data->state.headerb),
                                  headerlen);
       if(result)
         return result;
@@ -3490,7 +3418,7 @@
            * continue sending even if it gets discarded
            */
 
-          switch(data->set.httpreq) {
+          switch(data->state.httpreq) {
           case HTTPREQ_PUT:
           case HTTPREQ_POST:
           case HTTPREQ_POST_FORM:
@@ -3501,7 +3429,16 @@
              */
             Curl_expire_done(data, EXPIRE_100_TIMEOUT);
             if(!k->upload_done) {
-              if(data->set.http_keep_sending_on_error) {
+              if((k->httpcode == 417) && data->state.expect100header) {
+                /* 417 Expectation Failed - try again without the Expect
+                   header */
+                infof(data, "Got 417 while waiting for a 100\n");
+                data->state.disableexpect = TRUE;
+                DEBUGASSERT(!data->req.newurl);
+                data->req.newurl = strdup(conn->data->change.url);
+                Curl_done_sending(conn, k);
+              }
+              else if(data->set.http_keep_sending_on_error) {
                 infof(data, "HTTP error before end of send, keep sending\n");
                 if(k->exp100 > EXP100_SEND_DATA) {
                   k->exp100 = EXP100_SEND_DATA;
@@ -3511,8 +3448,10 @@
               else {
                 infof(data, "HTTP error before end of send, stop sending\n");
                 streamclose(conn, "Stop sending data before everything sent");
+                result = Curl_done_sending(conn, k);
+                if(result)
+                  return result;
                 k->upload_done = TRUE;
-                k->keepon &= ~KEEP_SEND; /* don't send */
                 if(data->state.expect100header)
                   k->exp100 = EXP100_FAILED;
               }
@@ -3597,14 +3536,12 @@
 
         if(data->set.verbose)
           Curl_debug(data, CURLINFO_HEADER_IN,
-                     k->str_start, headerlen);
+                     str_start, headerlen);
         break;          /* exit header line loop */
       }
 
-      /* We continue reading headers, so reset the line-based
-         header parsing variables hbufp && hbuflen */
-      k->hbufp = data->state.headerbuff;
-      k->hbuflen = 0;
+      /* We continue reading headers, reset the line-based header */
+      Curl_dyn_reset(&data->state.headerb);
       continue;
     }
 
@@ -3623,12 +3560,11 @@
 #define SCRATCHSIZE 21
       CURLcode res;
       char scratch[SCRATCHSIZE + 1]; /* "HTTP/major.minor 123" */
-      /* We can't really convert this yet because we
-         don't know if it's the 1st header line or the body.
-         So we do a partial conversion into a scratch area,
-         leaving the data at k->p as-is.
+      /* We can't really convert this yet because we don't know if it's the
+         1st header line or the body.  So we do a partial conversion into a
+         scratch area, leaving the data at 'headp' as-is.
       */
-      strncpy(&scratch[0], k->p, SCRATCHSIZE);
+      strncpy(&scratch[0], headp, SCRATCHSIZE);
       scratch[SCRATCHSIZE] = 0; /* null terminate */
       res = Curl_convert_from_network(data,
                                       &scratch[0],
@@ -3637,7 +3573,7 @@
         /* Curl_convert_from_network calls failf if unsuccessful */
         return res;
 #else
-#define HEADER1 k->p /* no conversion needed, just use k->p */
+#define HEADER1 headp /* no conversion needed, just use headp */
 #endif /* CURL_DOES_CONVERSIONS */
 
       if(conn->handler->protocol & PROTO_FAMILY_HTTP) {
@@ -3649,6 +3585,7 @@
          * guarantees on future behaviors since it isn't within the protocol.
          */
         char separator;
+        char twoorthree[2];
         nc = sscanf(HEADER1,
                     " HTTP/%1d.%1d%c%3d",
                     &httpversion_major,
@@ -3656,8 +3593,8 @@
                     &separator,
                     &k->httpcode);
 
-        if(nc == 1 && httpversion_major == 2 &&
-           1 == sscanf(HEADER1, " HTTP/2 %d", &k->httpcode)) {
+        if(nc == 1 && httpversion_major >= 2 &&
+           2 == sscanf(HEADER1, " HTTP/%1[23] %d", twoorthree, &k->httpcode)) {
           conn->httpversion = 0;
           nc = 4;
           separator = ' ';
@@ -3687,7 +3624,11 @@
              compare header line against list of aliases
           */
           if(!nc) {
-            if(checkhttpprefix(data, k->p, k->hbuflen) == STATUS_DONE) {
+            statusline check =
+              checkhttpprefix(data,
+                              Curl_dyn_ptr(&data->state.headerb),
+                              Curl_dyn_len(&data->state.headerb));
+            if(check == STATUS_DONE) {
               nc = 1;
               k->httpcode = 200;
               conn->httpversion = 10;
@@ -3695,7 +3636,7 @@
           }
         }
         else {
-          failf(data, "Unsupported HTTP version in response\n");
+          failf(data, "Unsupported HTTP version in response");
           return CURLE_UNSUPPORTED_PROTOCOL;
         }
       }
@@ -3733,15 +3674,18 @@
          * depending on how authentication is working.  Other codes
          * are definitely errors, so give up here.
          */
-        if(data->state.resume_from && data->set.httpreq == HTTPREQ_GET &&
+        if(data->state.resume_from && data->state.httpreq == HTTPREQ_GET &&
              k->httpcode == 416) {
           /* "Requested Range Not Satisfiable", just proceed and
              pretend this is no error */
           k->ignorebody = TRUE; /* Avoid appending error msg to good data. */
         }
         else if(data->set.http_fail_on_error && (k->httpcode >= 400) &&
-           ((k->httpcode != 401) || !conn->bits.user_passwd) &&
-           ((k->httpcode != 407) || !conn->bits.proxy_user_passwd) ) {
+                ((k->httpcode != 401) || !conn->bits.user_passwd)
+#ifndef CURL_DISABLE_PROXY
+                && ((k->httpcode != 407) || !conn->bits.proxy_user_passwd)
+#endif
+          ) {
           /* serious error, go home! */
           print_http_error(data);
           return CURLE_HTTP_RETURNED_ERROR;
@@ -3757,9 +3701,8 @@
         else if(conn->httpversion == 20 ||
                 (k->upgr101 == UPGR101_REQUESTED && k->httpcode == 101)) {
           DEBUGF(infof(data, "HTTP/2 found, allow multiplexing\n"));
-
-          /* HTTP/2 cannot blacklist multiplexing since it is a core
-             functionality of the protocol */
+          /* HTTP/2 cannot avoid multiplexing since it is a core functionality
+             of the protocol */
           conn->bundle->multiuse = BUNDLE_MULTIPLEX;
         }
         else if(conn->httpversion >= 11 &&
@@ -3769,6 +3712,7 @@
                        "HTTP 1.1 or later with persistent connection\n"));
         }
 
+        k->http_bodyless = k->httpcode >= 100 && k->httpcode < 200;
         switch(k->httpcode) {
         case 304:
           /* (quote from RFC2616, section 10.3.5): The 304 response
@@ -3786,10 +3730,9 @@
            * empty line after the header fields. */
           k->size = 0;
           k->maxdownload = 0;
-          k->ignorecl = TRUE; /* ignore Content-Length headers */
+          k->http_bodyless = TRUE;
           break;
         default:
-          /* nothing */
           break;
         }
       }
@@ -3799,16 +3742,16 @@
       }
     }
 
-    result = Curl_convert_from_network(data, k->p, strlen(k->p));
+    result = Curl_convert_from_network(data, headp, strlen(headp));
     /* Curl_convert_from_network calls failf if unsuccessful */
     if(result)
       return result;
 
     /* Check for Content-Length: header lines to get size */
-    if(!k->ignorecl && !data->set.ignorecl &&
-       checkprefix("Content-Length:", k->p)) {
+    if(!k->http_bodyless &&
+       !data->set.ignorecl && checkprefix("Content-Length:", headp)) {
       curl_off_t contentlength;
-      CURLofft offt = curlx_strtoofft(k->p + 15, NULL, 10, &contentlength);
+      CURLofft offt = curlx_strtoofft(headp + 15, NULL, 10, &contentlength);
 
       if(offt == CURL_OFFT_OK) {
         if(data->set.max_filesize &&
@@ -3839,8 +3782,8 @@
       }
     }
     /* check for Content-Type: header lines to get the MIME-type */
-    else if(checkprefix("Content-Type:", k->p)) {
-      char *contenttype = Curl_copy_header_value(k->p);
+    else if(checkprefix("Content-Type:", headp)) {
+      char *contenttype = Curl_copy_header_value(headp);
       if(!contenttype)
         return CURLE_OUT_OF_MEMORY;
       if(!*contenttype)
@@ -3851,10 +3794,10 @@
         data->info.contenttype = contenttype;
       }
     }
+#ifndef CURL_DISABLE_PROXY
     else if((conn->httpversion == 10) &&
             conn->bits.httpproxy &&
-            Curl_compareheader(k->p,
-                               "Proxy-Connection:", "keep-alive")) {
+            Curl_compareheader(headp, "Proxy-Connection:", "keep-alive")) {
       /*
        * When a HTTP/1.0 reply comes when using a proxy, the
        * 'Proxy-Connection: keep-alive' line tells us the
@@ -3866,8 +3809,7 @@
     }
     else if((conn->httpversion == 11) &&
             conn->bits.httpproxy &&
-            Curl_compareheader(k->p,
-                               "Proxy-Connection:", "close")) {
+            Curl_compareheader(headp, "Proxy-Connection:", "close")) {
       /*
        * We get a HTTP/1.1 response from a proxy and it says it'll
        * close down after this transfer.
@@ -3875,8 +3817,9 @@
       connclose(conn, "Proxy-Connection: asked to close after done");
       infof(data, "HTTP/1.1 proxy connection set close!\n");
     }
+#endif
     else if((conn->httpversion == 10) &&
-            Curl_compareheader(k->p, "Connection:", "keep-alive")) {
+            Curl_compareheader(headp, "Connection:", "keep-alive")) {
       /*
        * A HTTP/1.0 reply with the 'Connection: keep-alive' line
        * tells us the connection will be kept alive for our
@@ -3886,7 +3829,7 @@
       connkeep(conn, "Connection keep-alive");
       infof(data, "HTTP/1.0 connection set to keep alive!\n");
     }
-    else if(Curl_compareheader(k->p, "Connection:", "close")) {
+    else if(Curl_compareheader(headp, "Connection:", "close")) {
       /*
        * [RFC 2616, section 8.1.2.1]
        * "Connection: close" is HTTP/1.1 language and means that
@@ -3895,7 +3838,7 @@
        */
       streamclose(conn, "Connection: close used");
     }
-    else if(checkprefix("Transfer-Encoding:", k->p)) {
+    else if(!k->http_bodyless && checkprefix("Transfer-Encoding:", headp)) {
       /* One or more encodings. We check for chunked and/or a compression
          algorithm. */
       /*
@@ -3907,11 +3850,11 @@
        * of chunks, and a chunk-data set to zero signals the
        * end-of-chunks. */
 
-      result = Curl_build_unencoding_stack(conn, k->p + 18, TRUE);
+      result = Curl_build_unencoding_stack(conn, headp + 18, TRUE);
       if(result)
         return result;
     }
-    else if(checkprefix("Content-Encoding:", k->p) &&
+    else if(!k->http_bodyless && checkprefix("Content-Encoding:", headp) &&
             data->set.str[STRING_ENCODING]) {
       /*
        * Process Content-Encoding. Look for the values: identity,
@@ -3920,11 +3863,24 @@
        * 2616). zlib cannot handle compress.  However, errors are
        * handled further down when the response body is processed
        */
-      result = Curl_build_unencoding_stack(conn, k->p + 17, FALSE);
+      result = Curl_build_unencoding_stack(conn, headp + 17, FALSE);
       if(result)
         return result;
     }
-    else if(checkprefix("Content-Range:", k->p)) {
+    else if(checkprefix("Retry-After:", headp)) {
+      /* Retry-After = HTTP-date / delay-seconds */
+      curl_off_t retry_after = 0; /* zero for unknown or "now" */
+      time_t date = Curl_getdate_capped(&headp[12]);
+      if(-1 == date) {
+        /* not a date, try it as a decimal number */
+        (void)curlx_strtoofft(&headp[12], NULL, 10, &retry_after);
+      }
+      else
+        /* convert date to number of seconds into the future */
+        retry_after = date - time(NULL);
+      data->info.retry_after = retry_after; /* store it */
+    }
+    else if(!k->http_bodyless && checkprefix("Content-Range:", headp)) {
       /* Content-Range: bytes [num]-
          Content-Range: bytes: [num]-
          Content-Range: [num]-
@@ -3936,7 +3892,7 @@
          The forth means the requested range was unsatisfied.
       */
 
-      char *ptr = k->p + 14;
+      char *ptr = headp + 14;
 
       /* Move forward until first digit or asterisk */
       while(*ptr && !ISDIGIT(*ptr) && *ptr != '*')
@@ -3954,37 +3910,35 @@
         data->state.resume_from = 0; /* get everything */
     }
 #if !defined(CURL_DISABLE_COOKIES)
-    else if(data->cookies &&
-            checkprefix("Set-Cookie:", k->p)) {
+    else if(data->cookies && data->state.cookie_engine &&
+            checkprefix("Set-Cookie:", headp)) {
       Curl_share_lock(data, CURL_LOCK_DATA_COOKIE,
                       CURL_LOCK_ACCESS_SINGLE);
       Curl_cookie_add(data,
-                      data->cookies, TRUE, FALSE, k->p + 11,
+                      data->cookies, TRUE, FALSE, headp + 11,
                       /* If there is a custom-set Host: name, use it
                          here, or else use real peer host name. */
-                      conn->allocptr.cookiehost?
-                      conn->allocptr.cookiehost:conn->host.name,
+                      data->state.aptr.cookiehost?
+                      data->state.aptr.cookiehost:conn->host.name,
                       data->state.up.path,
                       (conn->handler->protocol&CURLPROTO_HTTPS)?
                       TRUE:FALSE);
       Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE);
     }
 #endif
-    else if(checkprefix("Last-Modified:", k->p) &&
+    else if(!k->http_bodyless && checkprefix("Last-Modified:", headp) &&
             (data->set.timecondition || data->set.get_filetime) ) {
-      time_t secs = time(NULL);
-      k->timeofdoc = curl_getdate(k->p + strlen("Last-Modified:"),
-                                  &secs);
+      k->timeofdoc = Curl_getdate_capped(headp + strlen("Last-Modified:"));
       if(data->set.get_filetime)
         data->info.filetime = k->timeofdoc;
     }
-    else if((checkprefix("WWW-Authenticate:", k->p) &&
+    else if((checkprefix("WWW-Authenticate:", headp) &&
              (401 == k->httpcode)) ||
-            (checkprefix("Proxy-authenticate:", k->p) &&
+            (checkprefix("Proxy-authenticate:", headp) &&
              (407 == k->httpcode))) {
 
       bool proxy = (k->httpcode == 407) ? TRUE : FALSE;
-      char *auth = Curl_copy_header_value(k->p);
+      char *auth = Curl_copy_header_value(headp);
       if(!auth)
         return CURLE_OUT_OF_MEMORY;
 
@@ -3995,27 +3949,28 @@
       if(result)
         return result;
     }
-  #ifdef USE_SPNEGO
-    else if(checkprefix("Persistent-Auth", k->p)) {
+#ifdef USE_SPNEGO
+    else if(checkprefix("Persistent-Auth", headp)) {
       struct negotiatedata *negdata = &conn->negotiate;
       struct auth *authp = &data->state.authhost;
       if(authp->picked == CURLAUTH_NEGOTIATE) {
-        char *persistentauth = Curl_copy_header_value(k->p);
+        char *persistentauth = Curl_copy_header_value(headp);
         if(!persistentauth)
           return CURLE_OUT_OF_MEMORY;
-        negdata->noauthpersist = checkprefix("false", persistentauth);
+        negdata->noauthpersist = checkprefix("false", persistentauth)?
+          TRUE:FALSE;
         negdata->havenoauthpersist = TRUE;
         infof(data, "Negotiate: noauthpersist -> %d, header part: %s",
           negdata->noauthpersist, persistentauth);
         free(persistentauth);
       }
     }
-  #endif
+#endif
     else if((k->httpcode >= 300 && k->httpcode < 400) &&
-            checkprefix("Location:", k->p) &&
+            checkprefix("Location:", headp) &&
             !data->req.location) {
       /* this is the URL that the server advises us to use instead */
-      char *location = Curl_copy_header_value(k->p);
+      char *location = Curl_copy_header_value(headp);
       if(!location)
         return CURLE_OUT_OF_MEMORY;
       if(!*location)
@@ -4040,7 +3995,7 @@
     }
 #ifdef USE_ALTSVC
     /* If enabled, the header is incoming and this is over HTTPS */
-    else if(data->asi && checkprefix("Alt-Svc:", k->p) &&
+    else if(data->asi && checkprefix("Alt-Svc:", headp) &&
             ((conn->handler->flags & PROTOPT_SSL) ||
 #ifdef CURLDEBUG
              /* allow debug builds to circumvent the HTTPS restriction */
@@ -4052,7 +4007,7 @@
       /* the ALPN of the current request */
       enum alpnid id = (conn->httpversion == 20) ? ALPN_h2 : ALPN_h1;
       result = Curl_altsvc_parse(data, data->asi,
-                                 &k->p[ strlen("Alt-Svc:") ],
+                                 &headp[ strlen("Alt-Svc:") ],
                                  id, conn->host.name,
                                  curlx_uitous(conn->remote_port));
       if(result)
@@ -4060,7 +4015,7 @@
     }
 #endif
     else if(conn->handler->protocol & CURLPROTO_RTSP) {
-      result = Curl_rtsp_parseheader(conn, k->p);
+      result = Curl_rtsp_parseheader(conn, headp);
       if(result)
         return result;
     }
@@ -4074,18 +4029,18 @@
       writetype |= CLIENTWRITE_BODY;
 
     if(data->set.verbose)
-      Curl_debug(data, CURLINFO_HEADER_IN, k->p, (size_t)k->hbuflen);
+      Curl_debug(data, CURLINFO_HEADER_IN, headp,
+                 Curl_dyn_len(&data->state.headerb));
 
-    result = Curl_client_write(conn, writetype, k->p, k->hbuflen);
+    result = Curl_client_write(conn, writetype, headp,
+                               Curl_dyn_len(&data->state.headerb));
     if(result)
       return result;
 
-    data->info.header_size += (long)k->hbuflen;
-    data->req.headerbytecount += (long)k->hbuflen;
+    data->info.header_size += Curl_dyn_len(&data->state.headerb);
+    data->req.headerbytecount += Curl_dyn_len(&data->state.headerb);
 
-    /* reset hbufp pointer && hbuflen */
-    k->hbufp = data->state.headerbuff;
-    k->hbuflen = 0;
+    Curl_dyn_reset(&data->state.headerb);
   }
   while(*k->str); /* header line within buffer */
 
diff --git a/Utilities/cmcurl/lib/http.h b/Utilities/cmcurl/lib/http.h
index a59fe7a..641bc0b 100644
--- a/Utilities/cmcurl/lib/http.h
+++ b/Utilities/cmcurl/lib/http.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -44,57 +44,30 @@
 
 char *Curl_checkProxyheaders(const struct connectdata *conn,
                              const char *thisheader);
-/* ------------------------------------------------------------------------- */
-/*
- * The add_buffer series of functions are used to build one large memory chunk
- * from repeated function invokes. Used so that the entire HTTP request can
- * be sent in one go.
- */
-struct Curl_send_buffer {
-  char *buffer;
-  size_t size_max;
-  size_t size_used;
-};
-typedef struct Curl_send_buffer Curl_send_buffer;
+CURLcode Curl_buffer_send(struct dynbuf *in,
+                          struct connectdata *conn,
+                          curl_off_t *bytes_written,
+                          size_t included_body_bytes,
+                          int socketindex);
 
-Curl_send_buffer *Curl_add_buffer_init(void);
-void Curl_add_buffer_free(Curl_send_buffer **inp);
-CURLcode Curl_add_bufferf(Curl_send_buffer **inp, const char *fmt, ...)
-  WARN_UNUSED_RESULT;
-CURLcode Curl_add_buffer(Curl_send_buffer **inp, const void *inptr,
-                         size_t size) WARN_UNUSED_RESULT;
-CURLcode Curl_add_buffer_send(Curl_send_buffer **inp,
-                              struct connectdata *conn,
-                              curl_off_t *bytes_written,
-                              size_t included_body_bytes,
-                              int socketindex);
-
-CURLcode Curl_add_timecondition(struct Curl_easy *data,
-                                Curl_send_buffer *buf);
+CURLcode Curl_add_timecondition(const struct connectdata *conn,
+                                struct dynbuf *buf);
 CURLcode Curl_add_custom_headers(struct connectdata *conn,
                                  bool is_connect,
-                                 Curl_send_buffer *req_buffer);
+                                 struct dynbuf *req_buffer);
 CURLcode Curl_http_compile_trailers(struct curl_slist *trailers,
-                                    Curl_send_buffer *buffer,
+                                    struct dynbuf *buf,
                                     struct Curl_easy *handle);
 
 /* protocol-specific functions set up to be called by the main engine */
 CURLcode Curl_http(struct connectdata *conn, bool *done);
 CURLcode Curl_http_done(struct connectdata *, CURLcode, bool premature);
 CURLcode Curl_http_connect(struct connectdata *conn, bool *done);
-CURLcode Curl_http_setup_conn(struct connectdata *conn);
-
-/* The following functions are defined in http_chunks.c */
-void Curl_httpchunk_init(struct connectdata *conn);
-CHUNKcode Curl_httpchunk_read(struct connectdata *conn, char *datap,
-                              ssize_t length, ssize_t *wrote);
 
 /* These functions are in http.c */
-void Curl_http_auth_stage(struct Curl_easy *data, int stage);
 CURLcode Curl_http_input_auth(struct connectdata *conn, bool proxy,
                               const char *auth);
 CURLcode Curl_http_auth_act(struct connectdata *conn);
-CURLcode Curl_http_perhapsrewind(struct connectdata *conn);
 
 /* If only the PICKNONE bit is set, there has been a round-trip and we
    selected to use no auth at all. Ie, we actively select no auth, as opposed
@@ -124,11 +97,15 @@
  *
  */
 #ifndef EXPECT_100_THRESHOLD
-#define EXPECT_100_THRESHOLD 1024
+#define EXPECT_100_THRESHOLD (1024*1024)
 #endif
 
 #endif /* CURL_DISABLE_HTTP */
 
+#ifdef USE_NGHTTP3
+struct h3out; /* see ngtcp2 */
+#endif
+
 /****************************************************************************
  * HTTP unique setup
  ***************************************************************************/
@@ -158,9 +135,9 @@
   } sending;
 
 #ifndef CURL_DISABLE_HTTP
-  Curl_send_buffer *send_buffer; /* used if the request couldn't be sent in
-                                    one chunk, points to an allocated
-                                    send_buffer struct */
+  struct dynbuf send_buffer; /* used if the request couldn't be sent in one
+                                chunk, points to an allocated send_buffer
+                                struct */
 #endif
 #ifdef USE_NGHTTP2
   /*********** for HTTP/2 we store stream-local data here *************/
@@ -168,27 +145,44 @@
 
   bool bodystarted;
   /* We store non-final and final response headers here, per-stream */
-  Curl_send_buffer *header_recvbuf;
+  struct dynbuf header_recvbuf;
   size_t nread_header_recvbuf; /* number of bytes in header_recvbuf fed into
                                   upper layer */
-  Curl_send_buffer *trailer_recvbuf;
   int status_code; /* HTTP status code */
   const uint8_t *pausedata; /* pointer to data received in on_data_chunk */
   size_t pauselen; /* the number of bytes left in data */
-  bool closed; /* TRUE on HTTP2 stream close */
   bool close_handled; /* TRUE if stream closure is handled by libcurl */
-  char *mem;     /* points to a buffer in memory to store received data */
-  size_t len;    /* size of the buffer 'mem' points to */
-  size_t memlen; /* size of data copied to mem */
-
-  const uint8_t *upload_mem; /* points to a buffer to read from */
-  size_t upload_len; /* size of the buffer 'upload_mem' points to */
-  curl_off_t upload_left; /* number of bytes left to upload */
 
   char **push_headers;       /* allocated array */
   size_t push_headers_used;  /* number of entries filled in */
   size_t push_headers_alloc; /* number of entries allocated */
 #endif
+#if defined(USE_NGHTTP2) || defined(USE_NGHTTP3)
+  bool closed; /* TRUE on HTTP2 stream close */
+  char *mem;     /* points to a buffer in memory to store received data */
+  size_t len;    /* size of the buffer 'mem' points to */
+  size_t memlen; /* size of data copied to mem */
+#endif
+#if defined(USE_NGHTTP2) || defined(ENABLE_QUIC)
+  /* fields used by both HTTP/2 and HTTP/3 */
+  const uint8_t *upload_mem; /* points to a buffer to read from */
+  size_t upload_len; /* size of the buffer 'upload_mem' points to */
+  curl_off_t upload_left; /* number of bytes left to upload */
+#endif
+
+#ifdef ENABLE_QUIC
+  /*********** for HTTP/3 we store stream-local data here *************/
+  int64_t stream3_id; /* stream we are interested in */
+  bool firstheader;  /* FALSE until headers arrive */
+  bool firstbody;  /* FALSE until body arrives */
+  bool h3req;    /* FALSE until request is issued */
+  bool upload_done;
+#endif
+#ifdef USE_NGHTTP3
+  size_t unacked_window;
+  struct h3out *h3out; /* per-stream buffers for upload */
+  struct dynbuf overflow; /* excess data received during a single Curl_read */
+#endif
 };
 
 #ifdef USE_NGHTTP2
diff --git a/Utilities/cmcurl/lib/http2.c b/Utilities/cmcurl/lib/http2.c
index 8e7bc21..6cf651f 100644
--- a/Utilities/cmcurl/lib/http2.c
+++ b/Utilities/cmcurl/lib/http2.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -36,6 +36,7 @@
 #include "connect.h"
 #include "strtoofft.h"
 #include "strdup.h"
+#include "dynbuf.h"
 /* The last 3 #include files should be in this order */
 #include "curl_printf.h"
 #include "curl_memory.h"
@@ -43,19 +44,11 @@
 
 #define H2_BUFSIZE 32768
 
-#if (NGHTTP2_VERSION_NUM < 0x010000)
+#if (NGHTTP2_VERSION_NUM < 0x010c00)
 #error too old nghttp2 version, upgrade!
 #endif
 
-#if (NGHTTP2_VERSION_NUM > 0x010800)
-#define NGHTTP2_HAS_HTTP2_STRERROR 1
-#endif
-
-#if (NGHTTP2_VERSION_NUM >= 0x010900)
-/* nghttp2_session_callbacks_set_error_callback is present in nghttp2 1.9.0 or
-   later */
-#define NGHTTP2_HAS_ERROR_CALLBACK 1
-#else
+#ifdef CURL_DISABLE_VERBOSE_STRINGS
 #define nghttp2_session_callbacks_set_error_callback(x,y)
 #endif
 
@@ -63,12 +56,12 @@
 #define NGHTTP2_HAS_SET_LOCAL_WINDOW_SIZE 1
 #endif
 
-#define HTTP2_HUGE_WINDOW_SIZE (1 << 30)
+#define HTTP2_HUGE_WINDOW_SIZE (32 * 1024 * 1024) /* 32 MB */
 
 #ifdef DEBUG_HTTP2
 #define H2BUGF(x) x
 #else
-#define H2BUGF(x) do { } WHILE_FALSE
+#define H2BUGF(x) do { } while(0)
 #endif
 
 
@@ -100,16 +93,11 @@
 }
 
 static int http2_perform_getsock(const struct connectdata *conn,
-                                 curl_socket_t *sock, /* points to
-                                                         numsocks
-                                                         number of
-                                                         sockets */
-                                 int numsocks)
+                                 curl_socket_t *sock)
 {
   const struct http_conn *c = &conn->proto.httpc;
   struct SingleRequest *k = &conn->data->req;
   int bitmap = GETSOCK_BLANK;
-  (void)numsocks;
 
   sock[0] = conn->sock[FIRSTSOCKET];
 
@@ -126,11 +114,9 @@
 }
 
 static int http2_getsock(struct connectdata *conn,
-                         curl_socket_t *sock, /* points to numsocks
-                                                 number of sockets */
-                         int numsocks)
+                         curl_socket_t *socks)
 {
-  return http2_perform_getsock(conn, sock, numsocks);
+  return http2_perform_getsock(conn, socks);
 }
 
 /*
@@ -139,8 +125,7 @@
 static void http2_stream_free(struct HTTP *http)
 {
   if(http) {
-    Curl_add_buffer_free(&http->header_recvbuf);
-    Curl_add_buffer_free(&http->trailer_recvbuf);
+    Curl_dyn_free(&http->header_recvbuf);
     for(; http->push_headers_used > 0; --http->push_headers_used) {
       free(http->push_headers[http->push_headers_used - 1]);
     }
@@ -240,7 +225,7 @@
 
   if(checks_to_perform & CONNCHECK_KEEPALIVE) {
     struct curltime now = Curl_now();
-    time_t elapsed = Curl_timediff(now, check->keepalive);
+    timediff_t elapsed = Curl_timediff(now, check->keepalive);
 
     if(elapsed > check->upkeep_interval_ms) {
       /* Perform an HTTP/2 PING */
@@ -269,24 +254,22 @@
   return ret_val;
 }
 
-/* called from Curl_http_setup_conn */
+/* called from http_setup_conn */
 void Curl_http2_setup_req(struct Curl_easy *data)
 {
   struct HTTP *http = data->req.protop;
-
-  http->nread_header_recvbuf = 0;
   http->bodystarted = FALSE;
   http->status_code = -1;
   http->pausedata = NULL;
   http->pauselen = 0;
   http->closed = FALSE;
   http->close_handled = FALSE;
-  http->mem = data->state.buffer;
-  http->len = data->set.buffer_size;
+  http->mem = NULL;
+  http->len = 0;
   http->memlen = 0;
 }
 
-/* called from Curl_http_setup_conn */
+/* called from http_setup_conn */
 void Curl_http2_setup_conn(struct connectdata *conn)
 {
   conn->proto.httpc.settings.max_concurrent_streams =
@@ -348,36 +331,7 @@
 int Curl_http2_ver(char *p, size_t len)
 {
   nghttp2_info *h2 = nghttp2_version(0);
-  return msnprintf(p, len, " nghttp2/%s", h2->version_str);
-}
-
-/* HTTP/2 error code to name based on the Error Code Registry.
-https://tools.ietf.org/html/rfc7540#page-77
-nghttp2_error_code enums are identical.
-*/
-static const char *http2_strerror(uint32_t err)
-{
-#ifndef NGHTTP2_HAS_HTTP2_STRERROR
-  const char *str[] = {
-    "NO_ERROR",             /* 0x0 */
-    "PROTOCOL_ERROR",       /* 0x1 */
-    "INTERNAL_ERROR",       /* 0x2 */
-    "FLOW_CONTROL_ERROR",   /* 0x3 */
-    "SETTINGS_TIMEOUT",     /* 0x4 */
-    "STREAM_CLOSED",        /* 0x5 */
-    "FRAME_SIZE_ERROR",     /* 0x6 */
-    "REFUSED_STREAM",       /* 0x7 */
-    "CANCEL",               /* 0x8 */
-    "COMPRESSION_ERROR",    /* 0x9 */
-    "CONNECT_ERROR",        /* 0xA */
-    "ENHANCE_YOUR_CALM",    /* 0xB */
-    "INADEQUATE_SECURITY",  /* 0xC */
-    "HTTP_1_1_REQUIRED"     /* 0xD */
-  };
-  return (err < sizeof(str) / sizeof(str[0])) ? str[err] : "unknown";
-#else
-  return nghttp2_http2_strerror(err);
-#endif
+  return msnprintf(p, len, "nghttp2/%s", h2->version_str);
 }
 
 /*
@@ -503,26 +457,58 @@
     /* setup the request struct */
     struct HTTP *http = calloc(1, sizeof(struct HTTP));
     if(!http) {
-      (void)Curl_close(second);
-      second = NULL;
+      (void)Curl_close(&second);
     }
     else {
       second->req.protop = http;
-      http->header_recvbuf = Curl_add_buffer_init();
-      if(!http->header_recvbuf) {
-        free(http);
-        (void)Curl_close(second);
-        second = NULL;
-      }
-      else {
-        Curl_http2_setup_req(second);
-        second->state.stream_weight = data->state.stream_weight;
-      }
+      Curl_dyn_init(&http->header_recvbuf, DYN_H2_HEADERS);
+      Curl_http2_setup_req(second);
+      second->state.stream_weight = data->state.stream_weight;
     }
   }
   return second;
 }
 
+static int set_transfer_url(struct Curl_easy *data,
+                            struct curl_pushheaders *hp)
+{
+  const char *v;
+  CURLU *u = curl_url();
+  CURLUcode uc;
+  char *url;
+
+  v = curl_pushheader_byname(hp, ":scheme");
+  if(v) {
+    uc = curl_url_set(u, CURLUPART_SCHEME, v, 0);
+    if(uc)
+      return 1;
+  }
+
+  v = curl_pushheader_byname(hp, ":authority");
+  if(v) {
+    uc = curl_url_set(u, CURLUPART_HOST, v, 0);
+    if(uc)
+      return 2;
+  }
+
+  v = curl_pushheader_byname(hp, ":path");
+  if(v) {
+    uc = curl_url_set(u, CURLUPART_PATH, v, 0);
+    if(uc)
+      return 3;
+  }
+
+  uc = curl_url_get(u, CURLUPART_URL, &url, 0);
+  if(uc)
+    return 4;
+  curl_url_cleanup(u);
+
+  if(data->change.url_alloc)
+    free(data->change.url);
+  data->change.url_alloc = TRUE;
+  data->change.url = url;
+  return 0;
+}
 
 static int push_promise(struct Curl_easy *data,
                         struct connectdata *conn,
@@ -554,11 +540,15 @@
     stream = data->req.protop;
     if(!stream) {
       failf(data, "Internal NULL stream!\n");
-      (void)Curl_close(newhandle);
+      (void)Curl_close(&newhandle);
       rv = 1;
       goto fail;
     }
 
+    rv = set_transfer_url(newhandle, &heads);
+    if(rv)
+      goto fail;
+
     Curl_set_in_callback(data, true);
     rv = data->multi->push_cb(data, newhandle,
                               stream->push_headers_used, &heads,
@@ -576,7 +566,7 @@
       /* denied, kill off the new handle again */
       http2_stream_free(newhandle->req.protop);
       newhandle->req.protop = NULL;
-      (void)Curl_close(newhandle);
+      (void)Curl_close(&newhandle);
       goto fail;
     }
 
@@ -592,7 +582,7 @@
       infof(data, "failed to add handle to multi\n");
       http2_stream_free(newhandle->req.protop);
       newhandle->req.protop = NULL;
-      Curl_close(newhandle);
+      Curl_close(&newhandle);
       rv = 1;
       goto fail;
     }
@@ -714,15 +704,17 @@
       stream->status_code = -1;
     }
 
-    result = Curl_add_buffer(&stream->header_recvbuf, "\r\n", 2);
+    result = Curl_dyn_add(&stream->header_recvbuf, "\r\n");
     if(result)
       return NGHTTP2_ERR_CALLBACK_FAILURE;
 
-    left = stream->header_recvbuf->size_used - stream->nread_header_recvbuf;
+    left = Curl_dyn_len(&stream->header_recvbuf) -
+      stream->nread_header_recvbuf;
     ncopy = CURLMIN(stream->len, left);
 
     memcpy(&stream->mem[stream->memlen],
-           stream->header_recvbuf->buffer + stream->nread_header_recvbuf,
+           Curl_dyn_ptr(&stream->header_recvbuf) +
+           stream->nread_header_recvbuf,
            ncopy);
     stream->nread_header_recvbuf += ncopy;
 
@@ -847,7 +839,7 @@
       return 0;
     }
     H2BUGF(infof(data_s, "on_stream_close(), %s (err %d), stream %u\n",
-                 http2_strerror(error_code), error_code, stream_id));
+                 nghttp2_strerror(error_code), error_code, stream_id));
     stream = data_s->req.protop;
     if(!stream)
       return NGHTTP2_ERR_CALLBACK_FAILURE;
@@ -855,6 +847,7 @@
     stream->closed = TRUE;
     httpc = &conn->proto.httpc;
     drain_this(data_s, httpc);
+    Curl_expire(data_s, 0, EXPIRE_RUN_NOW);
     httpc->error_code = error_code;
 
     /* remove the entry from the hash as the stream is now gone */
@@ -897,12 +890,6 @@
     return 0;
   }
 
-  if(!stream->trailer_recvbuf) {
-    stream->trailer_recvbuf = Curl_add_buffer_init();
-    if(!stream->trailer_recvbuf) {
-      return NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE;
-    }
-  }
   return 0;
 }
 
@@ -974,7 +961,9 @@
       if(!check)
         /* no memory */
         return NGHTTP2_ERR_CALLBACK_FAILURE;
-      if(!Curl_strcasecompare(check, (const char *)value)) {
+      if(!Curl_strcasecompare(check, (const char *)value) &&
+         ((conn->remote_port != conn->given->defport) ||
+          !Curl_strcasecompare(conn->host.name, (const char *)value))) {
         /* This is push is not for the same authority that was asked for in
          * the URL. RFC 7540 section 8.2 says: "A client MUST treat a
          * PUSH_PROMISE for which the server is not authoritative as a stream
@@ -1016,26 +1005,19 @@
   }
 
   if(stream->bodystarted) {
-    /* This is trailer fields. */
-    /* 4 is for ": " and "\r\n". */
-    uint32_t n = (uint32_t)(namelen + valuelen + 4);
-
+    /* This is a trailer */
+    struct dynbuf trail;
     H2BUGF(infof(data_s, "h2 trailer: %.*s: %.*s\n", namelen, name, valuelen,
                  value));
-
-    result = Curl_add_buffer(&stream->trailer_recvbuf, &n, sizeof(n));
-    if(result)
-      return NGHTTP2_ERR_CALLBACK_FAILURE;
-    result = Curl_add_buffer(&stream->trailer_recvbuf, name, namelen);
-    if(result)
-      return NGHTTP2_ERR_CALLBACK_FAILURE;
-    result = Curl_add_buffer(&stream->trailer_recvbuf, ": ", 2);
-    if(result)
-      return NGHTTP2_ERR_CALLBACK_FAILURE;
-    result = Curl_add_buffer(&stream->trailer_recvbuf, value, valuelen);
-    if(result)
-      return NGHTTP2_ERR_CALLBACK_FAILURE;
-    result = Curl_add_buffer(&stream->trailer_recvbuf, "\r\n\0", 3);
+    Curl_dyn_init(&trail, DYN_H2_TRAILER);
+    result = Curl_dyn_addf(&trail,
+                           "%.*s: %.*s\r\n", namelen, name,
+                           valuelen, value);
+    if(!result)
+      result = Curl_client_write(conn, CLIENTWRITE_HEADER,
+                                 Curl_dyn_ptr(&trail),
+                                 Curl_dyn_len(&trail));
+    Curl_dyn_free(&trail);
     if(result)
       return NGHTTP2_ERR_CALLBACK_FAILURE;
 
@@ -1050,14 +1032,14 @@
     stream->status_code = decode_status_code(value, valuelen);
     DEBUGASSERT(stream->status_code != -1);
 
-    result = Curl_add_buffer(&stream->header_recvbuf, "HTTP/2 ", 7);
+    result = Curl_dyn_add(&stream->header_recvbuf, "HTTP/2 ");
     if(result)
       return NGHTTP2_ERR_CALLBACK_FAILURE;
-    result = Curl_add_buffer(&stream->header_recvbuf, value, valuelen);
+    result = Curl_dyn_addn(&stream->header_recvbuf, value, valuelen);
     if(result)
       return NGHTTP2_ERR_CALLBACK_FAILURE;
     /* the space character after the status code is mandatory */
-    result = Curl_add_buffer(&stream->header_recvbuf, " \r\n", 3);
+    result = Curl_dyn_add(&stream->header_recvbuf, " \r\n");
     if(result)
       return NGHTTP2_ERR_CALLBACK_FAILURE;
     /* if we receive data for another handle, wake that up */
@@ -1072,16 +1054,16 @@
   /* nghttp2 guarantees that namelen > 0, and :status was already
      received, and this is not pseudo-header field . */
   /* convert to a HTTP1-style header */
-  result = Curl_add_buffer(&stream->header_recvbuf, name, namelen);
+  result = Curl_dyn_addn(&stream->header_recvbuf, name, namelen);
   if(result)
     return NGHTTP2_ERR_CALLBACK_FAILURE;
-  result = Curl_add_buffer(&stream->header_recvbuf, ": ", 2);
+  result = Curl_dyn_add(&stream->header_recvbuf, ": ");
   if(result)
     return NGHTTP2_ERR_CALLBACK_FAILURE;
-  result = Curl_add_buffer(&stream->header_recvbuf, value, valuelen);
+  result = Curl_dyn_addn(&stream->header_recvbuf, value, valuelen);
   if(result)
     return NGHTTP2_ERR_CALLBACK_FAILURE;
-  result = Curl_add_buffer(&stream->header_recvbuf, "\r\n", 2);
+  result = Curl_dyn_add(&stream->header_recvbuf, "\r\n");
   if(result)
     return NGHTTP2_ERR_CALLBACK_FAILURE;
   /* if we receive data for another handle, wake that up */
@@ -1144,8 +1126,7 @@
   return nread;
 }
 
-#if defined(NGHTTP2_HAS_ERROR_CALLBACK) &&      \
-  !defined(CURL_DISABLE_VERBOSE_STRINGS)
+#if !defined(CURL_DISABLE_VERBOSE_STRINGS)
 static int error_callback(nghttp2_session *session,
                           const char *msg,
                           size_t len,
@@ -1162,9 +1143,10 @@
                               struct http_conn *httpc)
 {
   nghttp2_settings_entry *iv = httpc->local_settings;
+  DEBUGASSERT(conn->data);
 
   iv[0].settings_id = NGHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS;
-  iv[0].value = 100;
+  iv[0].value = Curl_multi_max_concurrent_streams(conn->data->multi);
 
   iv[1].settings_id = NGHTTP2_SETTINGS_INITIAL_WINDOW_SIZE;
   iv[1].value = HTTP2_HUGE_WINDOW_SIZE;
@@ -1175,33 +1157,26 @@
   httpc->local_settings_num = 3;
 }
 
-void Curl_http2_done(struct connectdata *conn, bool premature)
+void Curl_http2_done(struct Curl_easy *data, bool premature)
 {
-  struct Curl_easy *data = conn->data;
   struct HTTP *http = data->req.protop;
-  struct http_conn *httpc = &conn->proto.httpc;
+  struct http_conn *httpc = &data->conn->proto.httpc;
 
   /* there might be allocated resources done before this got the 'h2' pointer
      setup */
-  if(http->header_recvbuf) {
-    Curl_add_buffer_free(&http->header_recvbuf);
-    Curl_add_buffer_free(&http->trailer_recvbuf);
-    if(http->push_headers) {
-      /* if they weren't used and then freed before */
-      for(; http->push_headers_used > 0; --http->push_headers_used) {
-        free(http->push_headers[http->push_headers_used - 1]);
-      }
-      free(http->push_headers);
-      http->push_headers = NULL;
+  Curl_dyn_free(&http->header_recvbuf);
+  if(http->push_headers) {
+    /* if they weren't used and then freed before */
+    for(; http->push_headers_used > 0; --http->push_headers_used) {
+      free(http->push_headers[http->push_headers_used - 1]);
     }
+    free(http->push_headers);
+    http->push_headers = NULL;
   }
 
   if(!httpc->h2) /* not HTTP/2 ? */
     return;
 
-  if(data->state.drain)
-    drained_transfer(data, httpc);
-
   if(premature) {
     /* RST_STREAM */
     if(!nghttp2_submit_rst_stream(httpc->h2, NGHTTP2_FLAG_NONE,
@@ -1213,6 +1188,10 @@
       httpc->pause_stream_id = 0;
     }
   }
+
+  if(data->state.drain)
+    drained_transfer(data, httpc);
+
   /* -1 means unassigned and 0 means cleared */
   if(http->stream_id > 0) {
     int rv = nghttp2_session_set_stream_user_data(httpc->h2,
@@ -1263,9 +1242,7 @@
     /* nghttp2_on_header_callback */
     nghttp2_session_callbacks_set_on_header_callback(callbacks, on_header);
 
-#ifndef CURL_DISABLE_VERBOSE_STRINGS
     nghttp2_session_callbacks_set_error_callback(callbacks, error_callback);
-#endif
 
     /* The nghttp2 session is not yet setup, do it */
     rc = nghttp2_session_client_new(&conn->proto.httpc.h2, callbacks, conn);
@@ -1283,7 +1260,7 @@
 /*
  * Append headers to ask for a HTTP1.1 to HTTP2 upgrade.
  */
-CURLcode Curl_http2_request_upgrade(Curl_send_buffer *req,
+CURLcode Curl_http2_request_upgrade(struct dynbuf *req,
                                     struct connectdata *conn)
 {
   CURLcode result;
@@ -1302,7 +1279,7 @@
                                          httpc->local_settings_num);
   if(!binlen) {
     failf(conn->data, "nghttp2 unexpectedly failed on pack_settings_payload");
-    Curl_add_buffer_free(&req);
+    Curl_dyn_free(req);
     return CURLE_FAILED_INIT;
   }
   conn->proto.httpc.binlen = binlen;
@@ -1310,15 +1287,15 @@
   result = Curl_base64url_encode(conn->data, (const char *)binsettings, binlen,
                                  &base64, &blen);
   if(result) {
-    Curl_add_buffer_free(&req);
+    Curl_dyn_free(req);
     return result;
   }
 
-  result = Curl_add_bufferf(&req,
-                            "Connection: Upgrade, HTTP2-Settings\r\n"
-                            "Upgrade: %s\r\n"
-                            "HTTP2-Settings: %s\r\n",
-                            NGHTTP2_CLEARTEXT_PROTO_VERSION_ID, base64);
+  result = Curl_dyn_addf(req,
+                         "Connection: Upgrade, HTTP2-Settings\r\n"
+                         "Upgrade: %s\r\n"
+                         "HTTP2-Settings: %s\r\n",
+                         NGHTTP2_CLEARTEXT_PROTO_VERSION_ID, base64);
   free(base64);
 
   k->upgr101 = UPGR101_REQUESTED;
@@ -1412,10 +1389,11 @@
 
     struct HTTP *stream = conn->data->req.protop;
 
+    struct http_conn *httpc = &conn->proto.httpc;
+    nghttp2_session *h2 = httpc->h2;
+
     if(stream->upload_left) {
       /* If the stream still thinks there's data left to upload. */
-      struct http_conn *httpc = &conn->proto.httpc;
-      nghttp2_session *h2 = httpc->h2;
 
       stream->upload_left = 0; /* DONE! */
 
@@ -1425,6 +1403,23 @@
 
       (void)h2_process_pending_input(conn, httpc, &result);
     }
+
+    /* If nghttp2 still has pending frames unsent */
+    if(nghttp2_session_want_write(h2)) {
+      struct Curl_easy *data = conn->data;
+      struct SingleRequest *k = &data->req;
+      int rv;
+
+      H2BUGF(infof(data, "HTTP/2 still wants to send data (easy %p)\n", data));
+
+      /* re-set KEEP_SEND to make sure we are called again */
+      k->keepon |= KEEP_SEND;
+
+      /* and attempt to send the pending frames */
+      rv = h2_session_send(data, h2);
+      if(rv != 0)
+        result = CURLE_SEND_ERROR;
+    }
   }
   return result;
 }
@@ -1433,8 +1428,6 @@
                                          struct Curl_easy *data,
                                          struct HTTP *stream, CURLcode *err)
 {
-  char *trailer_pos, *trailer_end;
-  CURLcode result;
   struct http_conn *httpc = &conn->proto.httpc;
 
   if(httpc->pause_stream_id == stream->stream_id) {
@@ -1463,7 +1456,7 @@
   }
   else if(httpc->error_code != NGHTTP2_NO_ERROR) {
     failf(data, "HTTP/2 stream %d was not closed cleanly: %s (err %u)",
-          stream->stream_id, http2_strerror(httpc->error_code),
+          stream->stream_id, nghttp2_strerror(httpc->error_code),
           httpc->error_code);
     *err = CURLE_HTTP2_STREAM;
     return -1;
@@ -1477,25 +1470,6 @@
     return -1;
   }
 
-  if(stream->trailer_recvbuf && stream->trailer_recvbuf->buffer) {
-    trailer_pos = stream->trailer_recvbuf->buffer;
-    trailer_end = trailer_pos + stream->trailer_recvbuf->size_used;
-
-    for(; trailer_pos < trailer_end;) {
-      uint32_t n;
-      memcpy(&n, trailer_pos, sizeof(n));
-      trailer_pos += sizeof(n);
-
-      result = Curl_client_write(conn, CLIENTWRITE_HEADER, trailer_pos, n);
-      if(result) {
-        *err = result;
-        return -1;
-      }
-
-      trailer_pos += n + 1;
-    }
-  }
-
   stream->close_handled = TRUE;
 
   H2BUGF(infof(data, "http2_recv returns 0, http2_handle_stream_close\n"));
@@ -1541,6 +1515,7 @@
 
     H2BUGF(infof(data, "Queuing PRIORITY on stream %u (easy %p)\n",
                  stream->stream_id, data));
+    DEBUGASSERT(stream->stream_id != -1);
     rv = nghttp2_submit_priority(h2, NGHTTP2_FLAG_NONE, stream->stream_id,
                                  &pri_spec);
     if(rv)
@@ -1565,6 +1540,11 @@
   if(should_close_session(httpc)) {
     H2BUGF(infof(data,
                  "http2_recv: nothing to do in this session\n"));
+    if(conn->bits.close) {
+      /* already marked for closure, return OK and we're done */
+      *err = CURLE_OK;
+      return 0;
+    }
     *err = CURLE_HTTP2;
     return -1;
   }
@@ -1580,13 +1560,13 @@
    */
 
   if(stream->bodystarted &&
-     stream->nread_header_recvbuf < stream->header_recvbuf->size_used) {
-    /* If there is body data pending for this stream to return, do that */
+     stream->nread_header_recvbuf < Curl_dyn_len(&stream->header_recvbuf)) {
+    /* If there is header data pending for this stream to return, do that */
     size_t left =
-      stream->header_recvbuf->size_used - stream->nread_header_recvbuf;
+      Curl_dyn_len(&stream->header_recvbuf) - stream->nread_header_recvbuf;
     size_t ncopy = CURLMIN(len, left);
-    memcpy(mem, stream->header_recvbuf->buffer + stream->nread_header_recvbuf,
-           ncopy);
+    memcpy(mem, Curl_dyn_ptr(&stream->header_recvbuf) +
+           stream->nread_header_recvbuf, ncopy);
     stream->nread_header_recvbuf += ncopy;
 
     H2BUGF(infof(data, "http2_recv: Got %d bytes from header_recvbuf\n",
@@ -1594,8 +1574,12 @@
     return ncopy;
   }
 
-  H2BUGF(infof(data, "http2_recv: easy %p (stream %u)\n",
-               data, stream->stream_id));
+  H2BUGF(infof(data, "http2_recv: easy %p (stream %u) win %u/%u\n",
+               data, stream->stream_id,
+               nghttp2_session_get_local_window_size(httpc->h2),
+               nghttp2_session_get_stream_local_window_size(httpc->h2,
+                                                            stream->stream_id)
+           ));
 
   if((data->state.drain) && stream->memlen) {
     H2BUGF(infof(data, "http2_recv: DRAIN %zu bytes stream %u!! (%p => %p)\n",
@@ -1626,7 +1610,6 @@
     stream->pausedata += nread;
     stream->pauselen -= nread;
 
-    infof(data, "%zd data bytes written\n", nread);
     if(stream->pauselen == 0) {
       H2BUGF(infof(data, "Unpaused by stream %u\n", stream->stream_id));
       DEBUGASSERT(httpc->pause_stream_id == stream->stream_id);
@@ -1660,6 +1643,9 @@
        socket is not read.  But it seems that usually streams are
        notified with its drain property, and socket is read again
        quickly. */
+    if(stream->closed)
+      /* closed overrides paused */
+      return 0;
     H2BUGF(infof(data, "stream %x is paused, pause id: %x\n",
                  stream->stream_id, httpc->pause_stream_id));
     *err = CURLE_AGAIN;
@@ -1754,14 +1740,14 @@
     else if(!stream->closed) {
       drained_transfer(data, httpc);
     }
+    else
+      /* this stream is closed, trigger a another read ASAP to detect that */
+      Curl_expire(data, 0, EXPIRE_RUN_NOW);
 
     return retlen;
   }
-  /* If stream is closed, return 0 to signal the http routine to close
-     the connection */
-  if(stream->closed) {
-    return http2_handle_stream_close(conn, data, stream, err);
-  }
+  if(stream->closed)
+    return 0;
   *err = CURLE_AGAIN;
   H2BUGF(infof(data, "http2_recv returns AGAIN for stream %u\n",
                stream->stream_id));
@@ -1772,8 +1758,9 @@
    field list. */
 #define AUTHORITY_DST_IDX 3
 
+/* USHRT_MAX is 65535 == 0xffff */
 #define HEADER_OVERFLOW(x) \
-  (x.namelen > (uint16_t)-1 || x.valuelen > (uint16_t)-1 - x.namelen)
+  (x.namelen > 0xffff || x.valuelen > 0xffff - x.namelen)
 
 /*
  * Check header memory for the token "trailers".
@@ -1880,7 +1867,11 @@
        are going to send or sending request body in DATA frame */
     stream->upload_mem = mem;
     stream->upload_len = len;
-    nghttp2_session_resume_data(h2, stream->stream_id);
+    rv = nghttp2_session_resume_data(h2, stream->stream_id);
+    if(nghttp2_is_fatal(rv)) {
+      *err = CURLE_SEND_ERROR;
+      return -1;
+    }
     rv = h2_session_send(conn->data, h2);
     if(nghttp2_is_fatal(rv)) {
       *err = CURLE_SEND_ERROR;
@@ -2019,8 +2010,10 @@
       nva[i].namelen = strlen((char *)nva[i].name);
     }
     else {
-      nva[i].name = (unsigned char *)hdbuf;
       nva[i].namelen = (size_t)(end - hdbuf);
+      /* Lower case the header name for HTTP/2 */
+      Curl_strntolower((char *)hdbuf, hdbuf, nva[i].namelen);
+      nva[i].name = (unsigned char *)hdbuf;
     }
     hdbuf = end + 1;
     while(*hdbuf == ' ' || *hdbuf == '\t')
@@ -2082,7 +2075,7 @@
 
   h2_pri_spec(conn->data, &pri_spec);
 
-  switch(conn->data->set.httpreq) {
+  switch(conn->data->state.httpreq) {
   case HTTPREQ_POST:
   case HTTPREQ_POST_FORM:
   case HTTPREQ_POST_MIME:
@@ -2130,17 +2123,14 @@
     return -1;
   }
 
-  if(stream->stream_id != -1) {
-    /* If whole HEADERS frame was sent off to the underlying socket,
-       the nghttp2 library calls data_source_read_callback. But only
-       it found that no data available, so it deferred the DATA
-       transmission. Which means that nghttp2_session_want_write()
-       returns 0 on http2_perform_getsock(), which results that no
-       writable socket check is performed. To workaround this, we
-       issue nghttp2_session_resume_data() here to bring back DATA
-       transmission from deferred state. */
-    nghttp2_session_resume_data(h2, stream->stream_id);
-  }
+  /* If whole HEADERS frame was sent off to the underlying socket, the nghttp2
+     library calls data_source_read_callback. But only it found that no data
+     available, so it deferred the DATA transmission. Which means that
+     nghttp2_session_want_write() returns 0 on http2_perform_getsock(), which
+     results that no writable socket check is performed. To workaround this,
+     we issue nghttp2_session_resume_data() here to bring back DATA
+     transmission from deferred state. */
+  nghttp2_session_resume_data(h2, stream->stream_id);
 
   return len;
 
@@ -2156,13 +2146,11 @@
   struct http_conn *httpc = &conn->proto.httpc;
   struct HTTP *stream = conn->data->req.protop;
 
+  DEBUGASSERT(conn->data->state.buffer);
+
   stream->stream_id = -1;
 
-  if(!stream->header_recvbuf) {
-    stream->header_recvbuf = Curl_add_buffer_init();
-    if(!stream->header_recvbuf)
-      return CURLE_OUT_OF_MEMORY;
-  }
+  Curl_dyn_init(&stream->header_recvbuf, DYN_H2_HEADERS);
 
   if((conn->handler == &Curl_handler_http2_ssl) ||
      (conn->handler == &Curl_handler_http2))
@@ -2175,7 +2163,7 @@
 
   result = http2_init(conn);
   if(result) {
-    Curl_add_buffer_free(&stream->header_recvbuf);
+    Curl_dyn_free(&stream->header_recvbuf);
     return result;
   }
 
@@ -2183,6 +2171,8 @@
   stream->upload_left = 0;
   stream->upload_mem = NULL;
   stream->upload_len = 0;
+  stream->mem = conn->data->state.buffer;
+  stream->len = conn->data->set.buffer_size;
 
   httpc->inbuflen = 0;
   httpc->nread_inbuf = 0;
@@ -2255,7 +2245,6 @@
     }
   }
 
-#ifdef NGHTTP2_HAS_SET_LOCAL_WINDOW_SIZE
   rv = nghttp2_session_set_local_window_size(httpc->h2, NGHTTP2_FLAG_NONE, 0,
                                              HTTP2_HUGE_WINDOW_SIZE);
   if(rv != 0) {
@@ -2263,7 +2252,6 @@
           nghttp2_strerror(rv), rv);
     return CURLE_HTTP2;
   }
-#endif
 
   /* we are going to copy mem to httpc->inbuf.  This is required since
      mem is part of buffer pointed by stream->mem, and callbacks
@@ -2321,6 +2309,51 @@
   return CURLE_OK;
 }
 
+CURLcode Curl_http2_stream_pause(struct Curl_easy *data, bool pause)
+{
+  DEBUGASSERT(data);
+  DEBUGASSERT(data->conn);
+  /* if it isn't HTTP/2, we're done */
+  if(!data->conn->proto.httpc.h2)
+    return CURLE_OK;
+#ifdef NGHTTP2_HAS_SET_LOCAL_WINDOW_SIZE
+  else {
+    struct HTTP *stream = data->req.protop;
+    struct http_conn *httpc = &data->conn->proto.httpc;
+    uint32_t window = !pause * HTTP2_HUGE_WINDOW_SIZE;
+    int rv = nghttp2_session_set_local_window_size(httpc->h2,
+                                                   NGHTTP2_FLAG_NONE,
+                                                   stream->stream_id,
+                                                   window);
+    if(rv) {
+      failf(data, "nghttp2_session_set_local_window_size() failed: %s(%d)",
+            nghttp2_strerror(rv), rv);
+      return CURLE_HTTP2;
+    }
+
+    /* make sure the window update gets sent */
+    rv = h2_session_send(data, httpc->h2);
+    if(rv)
+      return CURLE_SEND_ERROR;
+
+    DEBUGF(infof(data, "Set HTTP/2 window size to %u for stream %u\n",
+                 window, stream->stream_id));
+
+#ifdef DEBUGBUILD
+    {
+      /* read out the stream local window again */
+      uint32_t window2 =
+        nghttp2_session_get_stream_local_window_size(httpc->h2,
+                                                     stream->stream_id);
+      DEBUGF(infof(data, "HTTP/2 window size is now %u for stream %u\n",
+                   window2, stream->stream_id));
+    }
+#endif
+  }
+#endif
+  return CURLE_OK;
+}
+
 CURLcode Curl_http2_add_child(struct Curl_easy *parent,
                               struct Curl_easy *child,
                               bool exclusive)
@@ -2414,8 +2447,6 @@
 #else /* !USE_NGHTTP2 */
 
 /* Satisfy external references even if http2 is not compiled in. */
-
-#define CURL_DISABLE_TYPECHECK
 #include <curl/curl.h>
 
 char *curl_pushheader_bynum(struct curl_pushheaders *h, size_t num)
diff --git a/Utilities/cmcurl/lib/http2.h b/Utilities/cmcurl/lib/http2.h
index db6217b..e82b212 100644
--- a/Utilities/cmcurl/lib/http2.h
+++ b/Utilities/cmcurl/lib/http2.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -42,16 +42,15 @@
 CURLcode Curl_http2_init(struct connectdata *conn);
 void Curl_http2_init_state(struct UrlState *state);
 void Curl_http2_init_userset(struct UserDefined *set);
-CURLcode Curl_http2_send_request(struct connectdata *conn);
-CURLcode Curl_http2_request_upgrade(Curl_send_buffer *req,
+CURLcode Curl_http2_request_upgrade(struct dynbuf *req,
                                     struct connectdata *conn);
 CURLcode Curl_http2_setup(struct connectdata *conn);
 CURLcode Curl_http2_switched(struct connectdata *conn,
                              const char *data, size_t nread);
-/* called from Curl_http_setup_conn */
+/* called from http_setup_conn */
 void Curl_http2_setup_conn(struct connectdata *conn);
 void Curl_http2_setup_req(struct Curl_easy *data);
-void Curl_http2_done(struct connectdata *conn, bool premature);
+void Curl_http2_done(struct Curl_easy *data, bool premature);
 CURLcode Curl_http2_done_sending(struct connectdata *conn);
 CURLcode Curl_http2_add_child(struct Curl_easy *parent,
                               struct Curl_easy *child,
@@ -59,11 +58,11 @@
 void Curl_http2_remove_child(struct Curl_easy *parent,
                              struct Curl_easy *child);
 void Curl_http2_cleanup_dependencies(struct Curl_easy *data);
+CURLcode Curl_http2_stream_pause(struct Curl_easy *data, bool pause);
 
 /* returns true if the HTTP/2 stream error was HTTP_1_1_REQUIRED */
 bool Curl_h2_http_1_1_error(struct connectdata *conn);
 #else /* USE_NGHTTP2 */
-#define Curl_http2_send_request(x) CURLE_UNSUPPORTED_PROTOCOL
 #define Curl_http2_request_upgrade(x,y) CURLE_UNSUPPORTED_PROTOCOL
 #define Curl_http2_setup(x) CURLE_UNSUPPORTED_PROTOCOL
 #define Curl_http2_switched(x,y,z) CURLE_UNSUPPORTED_PROTOCOL
@@ -76,6 +75,7 @@
 #define Curl_http2_add_child(x, y, z)
 #define Curl_http2_remove_child(x, y)
 #define Curl_http2_cleanup_dependencies(x)
+#define Curl_http2_stream_pause(x, y)
 #define Curl_h2_http_1_1_error(x) 0
 #endif
 
diff --git a/Utilities/cmcurl/lib/http_chunks.c b/Utilities/cmcurl/lib/http_chunks.c
index 18dfcb2..767f806 100644
--- a/Utilities/cmcurl/lib/http_chunks.c
+++ b/Utilities/cmcurl/lib/http_chunks.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -26,7 +26,7 @@
 
 #include "urldata.h" /* it includes http_chunks.h */
 #include "sendf.h"   /* for the client write stuff */
-
+#include "dynbuf.h"
 #include "content_encoding.h"
 #include "http.h"
 #include "non-ascii.h" /* for Curl_convert_to_network prototype */
@@ -93,6 +93,7 @@
   chunk->hexindex = 0;      /* start at 0 */
   chunk->dataleft = 0;      /* no data left yet! */
   chunk->state = CHUNK_HEX; /* we get hex first! */
+  Curl_dyn_init(&conn->trailer, DYN_H1_TRAILER);
 }
 
 /*
@@ -109,7 +110,8 @@
 CHUNKcode Curl_httpchunk_read(struct connectdata *conn,
                               char *datap,
                               ssize_t datalen,
-                              ssize_t *wrotep)
+                              ssize_t *wrotep,
+                              CURLcode *extrap)
 {
   CURLcode result = CURLE_OK;
   struct Curl_easy *data = conn->data;
@@ -125,8 +127,10 @@
      chunk read process, to properly calculate the content length*/
   if(data->set.http_te_skip && !k->ignorebody) {
     result = Curl_client_write(conn, CLIENTWRITE_BODY, datap, datalen);
-    if(result)
-      return CHUNKE_WRITE_ERROR;
+    if(result) {
+      *extrap = result;
+      return CHUNKE_PASSTHRU_ERROR;
+    }
   }
 
   while(length) {
@@ -174,7 +178,6 @@
         /* we're now expecting data to come, unless size was zero! */
         if(0 == ch->datasize) {
           ch->state = CHUNK_TRAILER; /* now check for trailers */
-          conn->trlPos = 0;
         }
         else
           ch->state = CHUNK_DATA;
@@ -197,8 +200,10 @@
         else
           result = Curl_client_write(conn, CLIENTWRITE_BODY, datap, piece);
 
-        if(result)
-          return CHUNKE_WRITE_ERROR;
+        if(result) {
+          *extrap = result;
+          return CHUNKE_PASSTHRU_ERROR;
+        }
       }
 
       *wrote += piece;
@@ -224,30 +229,33 @@
 
     case CHUNK_TRAILER:
       if((*datap == 0x0d) || (*datap == 0x0a)) {
+        char *tr = Curl_dyn_ptr(&conn->trailer);
         /* this is the end of a trailer, but if the trailer was zero bytes
            there was no trailer and we move on */
 
-        if(conn->trlPos) {
-          /* we allocate trailer with 3 bytes extra room to fit this */
-          conn->trailer[conn->trlPos++] = 0x0d;
-          conn->trailer[conn->trlPos++] = 0x0a;
-          conn->trailer[conn->trlPos] = 0;
+        if(tr) {
+          size_t trlen;
+          result = Curl_dyn_add(&conn->trailer, (char *)"\x0d\x0a");
+          if(result)
+            return CHUNKE_OUT_OF_MEMORY;
 
+          tr = Curl_dyn_ptr(&conn->trailer);
+          trlen = Curl_dyn_len(&conn->trailer);
           /* Convert to host encoding before calling Curl_client_write */
-          result = Curl_convert_from_network(conn->data, conn->trailer,
-                                             conn->trlPos);
+          result = Curl_convert_from_network(conn->data, tr, trlen);
           if(result)
             /* Curl_convert_from_network calls failf if unsuccessful */
             /* Treat it as a bad chunk */
             return CHUNKE_BAD_CHUNK;
 
           if(!data->set.http_te_skip) {
-            result = Curl_client_write(conn, CLIENTWRITE_HEADER,
-                                       conn->trailer, conn->trlPos);
-            if(result)
-              return CHUNKE_WRITE_ERROR;
+            result = Curl_client_write(conn, CLIENTWRITE_HEADER, tr, trlen);
+            if(result) {
+              *extrap = result;
+              return CHUNKE_PASSTHRU_ERROR;
+            }
           }
-          conn->trlPos = 0;
+          Curl_dyn_reset(&conn->trailer);
           ch->state = CHUNK_TRAILER_CR;
           if(*datap == 0x0a)
             /* already on the LF */
@@ -260,25 +268,9 @@
         }
       }
       else {
-        /* conn->trailer is assumed to be freed in url.c on a
-           connection basis */
-        if(conn->trlPos >= conn->trlMax) {
-          /* we always allocate three extra bytes, just because when the full
-             header has been received we append CRLF\0 */
-          char *ptr;
-          if(conn->trlMax) {
-            conn->trlMax *= 2;
-            ptr = realloc(conn->trailer, conn->trlMax + 3);
-          }
-          else {
-            conn->trlMax = 128;
-            ptr = malloc(conn->trlMax + 3);
-          }
-          if(!ptr)
-            return CHUNKE_OUT_OF_MEMORY;
-          conn->trailer = ptr;
-        }
-        conn->trailer[conn->trlPos++]=*datap;
+        result = Curl_dyn_addn(&conn->trailer, datap, 1);
+        if(result)
+          return CHUNKE_OUT_OF_MEMORY;
       }
       datap++;
       length--;
@@ -339,8 +331,9 @@
     return "Illegal or missing hexadecimal sequence";
   case CHUNKE_BAD_CHUNK:
     return "Malformed encoding found";
-  case CHUNKE_WRITE_ERROR:
-    return "Write error";
+  case CHUNKE_PASSTHRU_ERROR:
+    DEBUGASSERT(0); /* never used */
+    return "";
   case CHUNKE_BAD_ENCODING:
     return "Bad content-encoding found";
   case CHUNKE_OUT_OF_MEMORY:
diff --git a/Utilities/cmcurl/lib/http_chunks.h b/Utilities/cmcurl/lib/http_chunks.h
index b969c55..8f4a33c 100644
--- a/Utilities/cmcurl/lib/http_chunks.h
+++ b/Utilities/cmcurl/lib/http_chunks.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -21,6 +21,9 @@
  * KIND, either express or implied.
  *
  ***************************************************************************/
+
+struct connectdata;
+
 /*
  * The longest possible hexadecimal number we support in a chunked transfer.
  * Weird enough, RFC2616 doesn't set a maximum size! Since we use strtoul()
@@ -71,9 +74,9 @@
   CHUNKE_TOO_LONG_HEX = 1,
   CHUNKE_ILLEGAL_HEX,
   CHUNKE_BAD_CHUNK,
-  CHUNKE_WRITE_ERROR,
   CHUNKE_BAD_ENCODING,
   CHUNKE_OUT_OF_MEMORY,
+  CHUNKE_PASSTHRU_ERROR, /* Curl_httpchunk_read() returns a CURLcode to use */
   CHUNKE_LAST
 } CHUNKcode;
 
@@ -87,4 +90,10 @@
   size_t dataleft; /* untouched data amount at the end of the last buffer */
 };
 
+/* The following functions are defined in http_chunks.c */
+void Curl_httpchunk_init(struct connectdata *conn);
+CHUNKcode Curl_httpchunk_read(struct connectdata *conn, char *datap,
+                              ssize_t length, ssize_t *wrote,
+                              CURLcode *passthru);
+
 #endif /* HEADER_CURL_HTTP_CHUNKS_H */
diff --git a/Utilities/cmcurl/lib/http_digest.c b/Utilities/cmcurl/lib/http_digest.c
index 9616c30..b06dc0d 100644
--- a/Utilities/cmcurl/lib/http_digest.c
+++ b/Utilities/cmcurl/lib/http_digest.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -94,15 +94,19 @@
   struct auth *authp;
 
   if(proxy) {
+#ifdef CURL_DISABLE_PROXY
+    return CURLE_NOT_BUILT_IN;
+#else
     digest = &data->state.proxydigest;
-    allocuserpwd = &conn->allocptr.proxyuserpwd;
+    allocuserpwd = &data->state.aptr.proxyuserpwd;
     userp = conn->http_proxy.user;
     passwdp = conn->http_proxy.passwd;
     authp = &data->state.authproxy;
+#endif
   }
   else {
     digest = &data->state.digest;
-    allocuserpwd = &conn->allocptr.userpwd;
+    allocuserpwd = &data->state.aptr.userpwd;
     userp = conn->user;
     passwdp = conn->passwd;
     authp = &data->state.authhost;
diff --git a/Utilities/cmcurl/lib/http_digest.h b/Utilities/cmcurl/lib/http_digest.h
index 73410ae..96e39a7 100644
--- a/Utilities/cmcurl/lib/http_digest.h
+++ b/Utilities/cmcurl/lib/http_digest.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
diff --git a/Utilities/cmcurl/lib/http_negotiate.c b/Utilities/cmcurl/lib/http_negotiate.c
index c8f4064..0a19ec2 100644
--- a/Utilities/cmcurl/lib/http_negotiate.c
+++ b/Utilities/cmcurl/lib/http_negotiate.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -52,6 +52,7 @@
   curlnegotiate state;
 
   if(proxy) {
+#ifndef CURL_DISABLE_PROXY
     userp = conn->http_proxy.user;
     passwdp = conn->http_proxy.passwd;
     service = data->set.str[STRING_PROXY_SERVICE_NAME] ?
@@ -59,6 +60,9 @@
     host = conn->http_proxy.host.name;
     neg_ctx = &conn->proxyneg;
     state = conn->proxy_negotiate_state;
+#else
+    return CURLE_NOT_BUILT_IN;
+#endif
   }
   else {
     userp = conn->user;
@@ -119,7 +123,8 @@
   struct auth *authp = proxy ? &conn->data->state.authproxy :
     &conn->data->state.authhost;
   curlnegotiate *state = proxy ? &conn->proxy_negotiate_state :
-                                 &conn->http_negotiate_state;
+    &conn->http_negotiate_state;
+  struct Curl_easy *data = conn->data;
   char *base64 = NULL;
   size_t len = 0;
   char *userp;
@@ -148,10 +153,10 @@
     }
     if(!neg_ctx->context) {
       result = Curl_input_negotiate(conn, proxy, "Negotiate");
-      if(result == CURLE_LOGIN_DENIED) {
+      if(result == CURLE_AUTH_ERROR) {
         /* negotiate auth failed, let's continue unauthenticated to stay
          * compatible with the behavior before curl-7_64_0-158-g6c6035532 */
-        conn->data->state.authproblem = TRUE;
+        authp->done = TRUE;
         return CURLE_OK;
       }
       else if(result)
@@ -164,15 +169,15 @@
       return result;
 
     userp = aprintf("%sAuthorization: Negotiate %s\r\n", proxy ? "Proxy-" : "",
-      base64);
+                    base64);
 
     if(proxy) {
-      Curl_safefree(conn->allocptr.proxyuserpwd);
-      conn->allocptr.proxyuserpwd = userp;
+      Curl_safefree(data->state.aptr.proxyuserpwd);
+      data->state.aptr.proxyuserpwd = userp;
     }
     else {
-      Curl_safefree(conn->allocptr.userpwd);
-      conn->allocptr.userpwd = userp;
+      Curl_safefree(data->state.aptr.userpwd);
+      data->state.aptr.userpwd = userp;
     }
 
     free(base64);
diff --git a/Utilities/cmcurl/lib/http_negotiate.h b/Utilities/cmcurl/lib/http_negotiate.h
index 4f0ac16..a737f6f 100644
--- a/Utilities/cmcurl/lib/http_negotiate.h
+++ b/Utilities/cmcurl/lib/http_negotiate.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -33,6 +33,8 @@
 
 void Curl_http_auth_cleanup_negotiate(struct connectdata *conn);
 
-#endif /* !CURL_DISABLE_HTTP && USE_SPNEGO */
+#else /* !CURL_DISABLE_HTTP && USE_SPNEGO */
+#define Curl_http_auth_cleanup_negotiate(x)
+#endif
 
 #endif /* HEADER_CURL_HTTP_NEGOTIATE_H */
diff --git a/Utilities/cmcurl/lib/http_ntlm.c b/Utilities/cmcurl/lib/http_ntlm.c
index e4a4fe0..cab543c 100644
--- a/Utilities/cmcurl/lib/http_ntlm.c
+++ b/Utilities/cmcurl/lib/http_ntlm.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -44,9 +44,7 @@
 
 /* SSL backend-specific #if branches in this file must be kept in the order
    documented in curl_ntlm_core. */
-#if defined(NTLM_NEEDS_NSS_INIT)
-#include "vtls/nssg.h"
-#elif defined(USE_WINDOWS_SSPI)
+#if defined(USE_WINDOWS_SSPI)
 #include "curl_sspi.h"
 #endif
 
@@ -133,17 +131,15 @@
   struct ntlmdata *ntlm;
   curlntlm *state;
   struct auth *authp;
+  struct Curl_easy *data = conn->data;
+
 
   DEBUGASSERT(conn);
-  DEBUGASSERT(conn->data);
-
-#if defined(NTLM_NEEDS_NSS_INIT)
-  if(CURLE_OK != Curl_nss_force_init(conn->data))
-    return CURLE_OUT_OF_MEMORY;
-#endif
+  DEBUGASSERT(data);
 
   if(proxy) {
-    allocuserpwd = &conn->allocptr.proxyuserpwd;
+#ifndef CURL_DISABLE_PROXY
+    allocuserpwd = &data->state.aptr.proxyuserpwd;
     userp = conn->http_proxy.user;
     passwdp = conn->http_proxy.passwd;
     service = conn->data->set.str[STRING_PROXY_SERVICE_NAME] ?
@@ -152,9 +148,12 @@
     ntlm = &conn->proxyntlm;
     state = &conn->proxy_ntlm_state;
     authp = &conn->data->state.authproxy;
+#else
+    return CURLE_NOT_BUILT_IN;
+#endif
   }
   else {
-    allocuserpwd = &conn->allocptr.userpwd;
+    allocuserpwd = &data->state.aptr.userpwd;
     userp = conn->user;
     passwdp = conn->passwd;
     service = conn->data->set.str[STRING_SERVICE_NAME] ?
diff --git a/Utilities/cmcurl/lib/http_ntlm.h b/Utilities/cmcurl/lib/http_ntlm.h
index 003714d..3ebdf97 100644
--- a/Utilities/cmcurl/lib/http_ntlm.h
+++ b/Utilities/cmcurl/lib/http_ntlm.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -35,6 +35,8 @@
 
 void Curl_http_auth_cleanup_ntlm(struct connectdata *conn);
 
-#endif /* !CURL_DISABLE_HTTP && USE_NTLM */
+#else /* !CURL_DISABLE_HTTP && USE_NTLM */
+#define Curl_http_auth_cleanup_ntlm(x)
+#endif
 
 #endif /* HEADER_CURL_HTTP_NTLM_H */
diff --git a/Utilities/cmcurl/lib/http_proxy.c b/Utilities/cmcurl/lib/http_proxy.c
index d7ed117..f188cbf 100644
--- a/Utilities/cmcurl/lib/http_proxy.c
+++ b/Utilities/cmcurl/lib/http_proxy.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -58,8 +58,9 @@
       Curl_ssl_connect_nonblocking(conn, sockindex,
                                    &conn->bits.proxy_ssl_connected[sockindex]);
     if(result)
-      conn->bits.close = TRUE; /* a failed connection is marked for closure to
-                                  prevent (bad) re-use or similar */
+      /* a failed connection is marked for closure to prevent (bad) re-use or
+         similar */
+      connclose(conn, "TLS handshake failed");
   }
   return result;
 #else
@@ -71,6 +72,7 @@
 
 CURLcode Curl_proxy_connect(struct connectdata *conn, int sockindex)
 {
+  struct Curl_easy *data = conn->data;
   if(conn->http_proxy.proxytype == CURLPROXY_HTTPS) {
     const CURLcode result = https_proxy_connect(conn, sockindex);
     if(result)
@@ -126,7 +128,7 @@
     conn->data->req.protop = prot_save;
     if(CURLE_OK != result)
       return result;
-    Curl_safefree(conn->allocptr.proxyuserpwd);
+    Curl_safefree(data->state.aptr.proxyuserpwd);
 #else
     return CURLE_NOT_BUILT_IN;
 #endif
@@ -157,15 +159,15 @@
       return CURLE_OUT_OF_MEMORY;
     infof(conn->data, "allocate connect buffer!\n");
     conn->connect_state = s;
+    Curl_dyn_init(&s->rcvbuf, DYN_PROXY_CONNECT_HEADERS);
   }
   else {
     DEBUGASSERT(conn->connect_state);
     s = conn->connect_state;
+    Curl_dyn_reset(&s->rcvbuf);
   }
   s->tunnel_state = TUNNEL_INIT;
   s->keepon = TRUE;
-  s->line_start = s->connect_buffer;
-  s->ptr = s->line_start;
   s->cl = 0;
   s->close_connection = FALSE;
   return CURLE_OK;
@@ -175,6 +177,7 @@
 {
   struct http_connect_state *s = conn->connect_state;
   s->tunnel_state = TUNNEL_COMPLETE;
+  Curl_dyn_free(&s->rcvbuf);
   infof(conn->data, "CONNECT phase completed!\n");
 }
 
@@ -189,6 +192,8 @@
   CURLcode result;
   curl_socket_t tunnelsocket = conn->sock[sockindex];
   struct http_connect_state *s = conn->connect_state;
+  char *linep;
+  size_t perline;
 
 #define SELECT_OK      0
 #define SELECT_ERROR   1
@@ -203,7 +208,7 @@
     if(TUNNEL_INIT == s->tunnel_state) {
       /* BEGIN CONNECT PHASE */
       char *host_port;
-      Curl_send_buffer *req_buffer;
+      struct dynbuf req;
 
       infof(data, "Establish HTTP proxy tunnel to %s:%d\n",
             hostname, remote_port);
@@ -214,17 +219,12 @@
       free(data->req.newurl);
       data->req.newurl = NULL;
 
-      /* initialize a dynamic send-buffer */
-      req_buffer = Curl_add_buffer_init();
-
-      if(!req_buffer)
-        return CURLE_OUT_OF_MEMORY;
-
       host_port = aprintf("%s:%d", hostname, remote_port);
-      if(!host_port) {
-        Curl_add_buffer_free(&req_buffer);
+      if(!host_port)
         return CURLE_OUT_OF_MEMORY;
-      }
+
+      /* initialize a dynamic send-buffer */
+      Curl_dyn_init(&req, DYN_HTTP_REQUEST);
 
       /* Setup the proxy-authorization header, if any */
       result = Curl_http_output_auth(conn, "CONNECT", host_port, TRUE);
@@ -235,8 +235,8 @@
         char *host = NULL;
         const char *proxyconn = "";
         const char *useragent = "";
-        const char *http = (conn->http_proxy.proxytype == CURLPROXY_HTTP_1_0) ?
-          "1.0" : "1.1";
+        const char *httpv =
+          (conn->http_proxy.proxytype == CURLPROXY_HTTP_1_0) ? "1.0" : "1.1";
         bool ipv6_ip = conn->bits.ipv6_ip;
         char *hostheader;
 
@@ -247,7 +247,7 @@
           aprintf("%s%s%s:%d", ipv6_ip?"[":"", hostname, ipv6_ip?"]":"",
                   remote_port);
         if(!hostheader) {
-          Curl_add_buffer_free(&req_buffer);
+          Curl_dyn_free(&req);
           return CURLE_OUT_OF_MEMORY;
         }
 
@@ -255,7 +255,7 @@
           host = aprintf("Host: %s\r\n", hostheader);
           if(!host) {
             free(hostheader);
-            Curl_add_buffer_free(&req_buffer);
+            Curl_dyn_free(&req);
             return CURLE_OUT_OF_MEMORY;
           }
         }
@@ -264,52 +264,49 @@
 
         if(!Curl_checkProxyheaders(conn, "User-Agent") &&
            data->set.str[STRING_USERAGENT])
-          useragent = conn->allocptr.uagent;
+          useragent = data->state.aptr.uagent;
 
         result =
-          Curl_add_bufferf(&req_buffer,
-                           "CONNECT %s HTTP/%s\r\n"
-                           "%s"  /* Host: */
-                           "%s"  /* Proxy-Authorization */
-                           "%s"  /* User-Agent */
-                           "%s", /* Proxy-Connection */
-                           hostheader,
-                           http,
-                           host?host:"",
-                           conn->allocptr.proxyuserpwd?
-                           conn->allocptr.proxyuserpwd:"",
-                           useragent,
-                           proxyconn);
+          Curl_dyn_addf(&req,
+                        "CONNECT %s HTTP/%s\r\n"
+                        "%s"  /* Host: */
+                        "%s"  /* Proxy-Authorization */
+                        "%s"  /* User-Agent */
+                        "%s", /* Proxy-Connection */
+                        hostheader,
+                        httpv,
+                        host?host:"",
+                        data->state.aptr.proxyuserpwd?
+                        data->state.aptr.proxyuserpwd:"",
+                        useragent,
+                        proxyconn);
 
         if(host)
           free(host);
         free(hostheader);
 
         if(!result)
-          result = Curl_add_custom_headers(conn, TRUE, req_buffer);
+          result = Curl_add_custom_headers(conn, TRUE, &req);
 
         if(!result)
           /* CRLF terminate the request */
-          result = Curl_add_bufferf(&req_buffer, "\r\n");
+          result = Curl_dyn_add(&req, "\r\n");
 
         if(!result) {
           /* Send the connect request to the proxy */
           /* BLOCKING */
-          result =
-            Curl_add_buffer_send(&req_buffer, conn,
-                                 &data->info.request_size, 0, sockindex);
+          result = Curl_buffer_send(&req, conn, &data->info.request_size, 0,
+                                    sockindex);
         }
-        req_buffer = NULL;
         if(result)
           failf(data, "Failed sending CONNECT to proxy");
       }
 
-      Curl_add_buffer_free(&req_buffer);
+      Curl_dyn_free(&req);
       if(result)
         return result;
 
       s->tunnel_state = TUNNEL_CONNECT;
-      s->perline = 0;
     } /* END CONNECT PHASE */
 
     check = Curl_timeleft(data, NULL, TRUE);
@@ -327,18 +324,13 @@
     { /* READING RESPONSE PHASE */
       int error = SELECT_OK;
 
-      while(s->keepon && !error) {
+      while(s->keepon) {
         ssize_t gotbytes;
-
-        /* make sure we have space to read more data */
-        if(s->ptr >= &s->connect_buffer[CONNECT_BUFFER_SIZE]) {
-          failf(data, "CONNECT response too large!");
-          return CURLE_RECV_ERROR;
-        }
+        char byte;
 
         /* Read one byte at a time to avoid a race condition. Wait at most one
            second before looping to ensure continuous pgrsUpdates. */
-        result = Curl_read(conn, tunnelsocket, s->ptr, 1, &gotbytes);
+        result = Curl_read(conn, tunnelsocket, &byte, 1, &gotbytes);
         if(result == CURLE_AGAIN)
           /* socket buffer drained, return */
           return CURLE_OK;
@@ -365,11 +357,9 @@
           break;
         }
 
-
         if(s->keepon > TRUE) {
           /* This means we are currently ignoring a response-body */
 
-          s->ptr = s->connect_buffer;
           if(s->cl) {
             /* A Content-Length based body: simply count down the counter
                and make sure to break out of the loop when we're done! */
@@ -384,11 +374,12 @@
             /* chunked-encoded body, so we need to do the chunked dance
                properly to know when the end of the body is reached */
             CHUNKcode r;
+            CURLcode extra;
             ssize_t tookcareof = 0;
 
             /* now parse the chunked piece of data so that we can
                properly tell when the stream ends */
-            r = Curl_httpchunk_read(conn, s->ptr, 1, &tookcareof);
+            r = Curl_httpchunk_read(conn, &byte, 1, &tookcareof, &extra);
             if(r == CHUNKE_STOP) {
               /* we're done reading chunks! */
               infof(data, "chunk reading DONE\n");
@@ -400,25 +391,27 @@
           continue;
         }
 
-        s->perline++; /* amount of bytes in this line so far */
-
-        /* if this is not the end of a header line then continue */
-        if(*s->ptr != 0x0a) {
-          s->ptr++;
-          continue;
+        if(Curl_dyn_addn(&s->rcvbuf, &byte, 1)) {
+          failf(data, "CONNECT response too large!");
+          return CURLE_RECV_ERROR;
         }
 
+        /* if this is not the end of a header line then continue */
+        if(byte != 0x0a)
+          continue;
+
+        linep = Curl_dyn_ptr(&s->rcvbuf);
+        perline = Curl_dyn_len(&s->rcvbuf); /* amount of bytes in this line */
+
         /* convert from the network encoding */
-        result = Curl_convert_from_network(data, s->line_start,
-                                           (size_t)s->perline);
+        result = Curl_convert_from_network(data, linep, perline);
         /* Curl_convert_from_network calls failf if unsuccessful */
         if(result)
           return result;
 
         /* output debug if that is requested */
         if(data->set.verbose)
-          Curl_debug(data, CURLINFO_HEADER_IN,
-                     s->line_start, (size_t)s->perline);
+          Curl_debug(data, CURLINFO_HEADER_IN, linep, perline);
 
         if(!data->set.suppress_connect_headers) {
           /* send the header to the callback */
@@ -426,23 +419,22 @@
           if(data->set.include_header)
             writetype |= CLIENTWRITE_BODY;
 
-          result = Curl_client_write(conn, writetype,
-                                     s->line_start, s->perline);
+          result = Curl_client_write(conn, writetype, linep, perline);
           if(result)
             return result;
         }
 
-        data->info.header_size += (long)s->perline;
-        data->req.headerbytecount += (long)s->perline;
+        data->info.header_size += (long)perline;
+        data->req.headerbytecount += (long)perline;
 
         /* Newlines are CRLF, so the CR is ignored as the line isn't
            really terminated until the LF comes. Treat a following CR
            as end-of-headers as well.*/
 
-        if(('\r' == s->line_start[0]) ||
-           ('\n' == s->line_start[0])) {
+        if(('\r' == linep[0]) ||
+           ('\n' == linep[0])) {
           /* end of response-headers from the proxy */
-          s->ptr = s->connect_buffer;
+
           if((407 == k->httpcode) && !data->state.authproblem) {
             /* If we get a 407 response code with content length
                when we have no auth problem, we must ignore the
@@ -455,24 +447,23 @@
             }
             else if(s->chunked_encoding) {
               CHUNKcode r;
+              CURLcode extra;
 
               infof(data, "Ignore chunked response-body\n");
 
-              /* We set ignorebody true here since the chunked
-                 decoder function will acknowledge that. Pay
-                 attention so that this is cleared again when this
-                 function returns! */
+              /* We set ignorebody true here since the chunked decoder
+                 function will acknowledge that. Pay attention so that this is
+                 cleared again when this function returns! */
               k->ignorebody = TRUE;
 
-              if(s->line_start[1] == '\n') {
-                /* this can only be a LF if the letter at index 0
-                   was a CR */
-                s->line_start++;
-              }
+              if(linep[1] == '\n')
+                /* this can only be a LF if the letter at index 0 was a CR */
+                linep++;
 
-              /* now parse the chunked piece of data so that we can
-                 properly tell when the stream ends */
-              r = Curl_httpchunk_read(conn, s->line_start + 1, 1, &gotbytes);
+              /* now parse the chunked piece of data so that we can properly
+                 tell when the stream ends */
+              r = Curl_httpchunk_read(conn, linep + 1, 1, &gotbytes,
+                                      &extra);
               if(r == CHUNKE_STOP) {
                 /* we're done reading chunks! */
                 infof(data, "chunk reading DONE\n");
@@ -496,14 +487,13 @@
           continue;
         }
 
-        s->line_start[s->perline] = 0; /* zero terminate the buffer */
-        if((checkprefix("WWW-Authenticate:", s->line_start) &&
+        if((checkprefix("WWW-Authenticate:", linep) &&
             (401 == k->httpcode)) ||
-           (checkprefix("Proxy-authenticate:", s->line_start) &&
+           (checkprefix("Proxy-authenticate:", linep) &&
             (407 == k->httpcode))) {
 
           bool proxy = (k->httpcode == 407) ? TRUE : FALSE;
-          char *auth = Curl_copy_header_value(s->line_start);
+          char *auth = Curl_copy_header_value(linep);
           if(!auth)
             return CURLE_OUT_OF_MEMORY;
 
@@ -514,7 +504,7 @@
           if(result)
             return result;
         }
-        else if(checkprefix("Content-Length:", s->line_start)) {
+        else if(checkprefix("Content-Length:", linep)) {
           if(k->httpcode/100 == 2) {
             /* A client MUST ignore any Content-Length or Transfer-Encoding
                header fields received in a successful response to CONNECT.
@@ -523,13 +513,13 @@
                   k->httpcode);
           }
           else {
-            (void)curlx_strtoofft(s->line_start +
+            (void)curlx_strtoofft(linep +
                                   strlen("Content-Length:"), NULL, 10, &s->cl);
           }
         }
-        else if(Curl_compareheader(s->line_start, "Connection:", "close"))
+        else if(Curl_compareheader(linep, "Connection:", "close"))
           s->close_connection = TRUE;
-        else if(checkprefix("Transfer-Encoding:", s->line_start)) {
+        else if(checkprefix("Transfer-Encoding:", linep)) {
           if(k->httpcode/100 == 2) {
             /* A client MUST ignore any Content-Length or Transfer-Encoding
                header fields received in a successful response to CONNECT.
@@ -537,7 +527,7 @@
             infof(data, "Ignoring Transfer-Encoding in "
                   "CONNECT %03d response\n", k->httpcode);
           }
-          else if(Curl_compareheader(s->line_start,
+          else if(Curl_compareheader(linep,
                                      "Transfer-Encoding:", "chunked")) {
             infof(data, "CONNECT responded chunked\n");
             s->chunked_encoding = TRUE;
@@ -545,19 +535,16 @@
             Curl_httpchunk_init(conn);
           }
         }
-        else if(Curl_compareheader(s->line_start,
-                                   "Proxy-Connection:", "close"))
+        else if(Curl_compareheader(linep, "Proxy-Connection:", "close"))
           s->close_connection = TRUE;
-        else if(2 == sscanf(s->line_start, "HTTP/1.%d %d",
+        else if(2 == sscanf(linep, "HTTP/1.%d %d",
                             &subversion,
                             &k->httpcode)) {
           /* store the HTTP code from the proxy */
           data->info.httpproxycode = k->httpcode;
         }
 
-        s->perline = 0; /* line starts over here */
-        s->ptr = s->connect_buffer;
-        s->line_start = s->ptr;
+        Curl_dyn_reset(&s->rcvbuf);
       } /* while there's buffer left and loop is requested */
 
       if(Curl_pgrsUpdate(conn))
@@ -618,6 +605,7 @@
     if(conn->bits.proxy_connect_closed)
       /* this is not an error, just part of the connection negotiation */
       return CURLE_OK;
+    Curl_dyn_free(&s->rcvbuf);
     failf(data, "Received HTTP code %d from proxy after CONNECT",
           data->req.httpcode);
     return CURLE_RECV_ERROR;
@@ -628,16 +616,18 @@
   /* If a proxy-authorization header was used for the proxy, then we should
      make sure that it isn't accidentally used for the document request
      after we've connected. So let's free and clear it here. */
-  Curl_safefree(conn->allocptr.proxyuserpwd);
-  conn->allocptr.proxyuserpwd = NULL;
+  Curl_safefree(data->state.aptr.proxyuserpwd);
+  data->state.aptr.proxyuserpwd = NULL;
 
   data->state.authproxy.done = TRUE;
+  data->state.authproxy.multipass = FALSE;
 
   infof(data, "Proxy replied %d to CONNECT request\n",
         data->info.httpproxycode);
   data->req.ignorebody = FALSE; /* put it (back) to non-ignore state */
   conn->bits.rewindaftersend = FALSE; /* make sure this isn't set for the
                                          document request  */
+  Curl_dyn_free(&s->rcvbuf);
   return CURLE_OK;
 }
 
diff --git a/Utilities/cmcurl/lib/http_proxy.h b/Utilities/cmcurl/lib/http_proxy.h
index e19fa85..29988a6 100644
--- a/Utilities/cmcurl/lib/http_proxy.h
+++ b/Utilities/cmcurl/lib/http_proxy.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -47,5 +47,6 @@
 #endif
 
 void Curl_connect_free(struct Curl_easy *data);
+void Curl_connect_done(struct Curl_easy *data);
 
 #endif /* HEADER_CURL_HTTP_PROXY_H */
diff --git a/Utilities/cmcurl/lib/idn_win32.c b/Utilities/cmcurl/lib/idn_win32.c
index 8dc300b..2f5850d 100644
--- a/Utilities/cmcurl/lib/idn_win32.c
+++ b/Utilities/cmcurl/lib/idn_win32.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -72,13 +72,13 @@
 {
   bool success = FALSE;
 
-  wchar_t *in_w = Curl_convert_UTF8_to_wchar(in);
+  wchar_t *in_w = curlx_convert_UTF8_to_wchar(in);
   if(in_w) {
     wchar_t punycode[IDN_MAX_LENGTH];
     int chars = IdnToAscii(0, in_w, -1, punycode, IDN_MAX_LENGTH);
     free(in_w);
     if(chars) {
-      *out = Curl_convert_wchar_to_UTF8(punycode);
+      *out = curlx_convert_wchar_to_UTF8(punycode);
       if(*out)
         success = TRUE;
     }
@@ -91,7 +91,7 @@
 {
   bool success = FALSE;
 
-  wchar_t *in_w = Curl_convert_UTF8_to_wchar(in);
+  wchar_t *in_w = curlx_convert_UTF8_to_wchar(in);
   if(in_w) {
     size_t in_len = wcslen(in_w) + 1;
     wchar_t unicode[IDN_MAX_LENGTH];
@@ -99,7 +99,7 @@
                              unicode, IDN_MAX_LENGTH);
     free(in_w);
     if(chars) {
-      *out = Curl_convert_wchar_to_UTF8(unicode);
+      *out = curlx_convert_wchar_to_UTF8(unicode);
       if(*out)
         success = TRUE;
     }
diff --git a/Utilities/cmcurl/lib/if2ip.c b/Utilities/cmcurl/lib/if2ip.c
index d003de6..3938869 100644
--- a/Utilities/cmcurl/lib/if2ip.c
+++ b/Utilities/cmcurl/lib/if2ip.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -118,7 +118,7 @@
         if(iface->ifa_addr->sa_family == af) {
           if(strcasecompare(iface->ifa_name, interf)) {
             void *addr;
-            char *ip;
+            const char *ip;
             char scope[12] = "";
             char ipstr[64];
 #ifdef ENABLE_IPV6
@@ -129,11 +129,11 @@
               unsigned int ifscope = Curl_ipv6_scope(iface->ifa_addr);
 
               if(ifscope != remote_scope) {
-                /* We are interested only in interface addresses whose
-                   scope matches the remote address we want to
-                   connect to: global for global, link-local for
-                   link-local, etc... */
-                if(res == IF2IP_NOT_FOUND) res = IF2IP_AF_NOT_SUPPORTED;
+                /* We are interested only in interface addresses whose scope
+                   matches the remote address we want to connect to: global
+                   for global, link-local for link-local, etc... */
+                if(res == IF2IP_NOT_FOUND)
+                  res = IF2IP_AF_NOT_SUPPORTED;
                 continue;
               }
 
@@ -153,15 +153,15 @@
               }
 
               if(scopeid)
-                  msnprintf(scope, sizeof(scope), "%%%u", scopeid);
+                msnprintf(scope, sizeof(scope), "%%%u", scopeid);
 #endif
             }
             else
 #endif
               addr =
-                  &((struct sockaddr_in *)(void *)iface->ifa_addr)->sin_addr;
+                &((struct sockaddr_in *)(void *)iface->ifa_addr)->sin_addr;
             res = IF2IP_FOUND;
-            ip = (char *) Curl_inet_ntop(af, addr, ipstr, sizeof(ipstr));
+            ip = Curl_inet_ntop(af, addr, ipstr, sizeof(ipstr));
             msnprintf(buf, buf_size, "%s%s", ip, scope);
             break;
           }
@@ -190,6 +190,7 @@
   struct sockaddr_in *s;
   curl_socket_t dummy;
   size_t len;
+  const char *r;
 
   (void)remote_scope;
   (void)local_scope_id;
@@ -219,9 +220,11 @@
 
   s = (struct sockaddr_in *)(void *)&req.ifr_addr;
   memcpy(&in, &s->sin_addr, sizeof(in));
-  Curl_inet_ntop(s->sin_family, &in, buf, buf_size);
+  r = Curl_inet_ntop(s->sin_family, &in, buf, buf_size);
 
   sclose(dummy);
+  if(!r)
+    return IF2IP_NOT_FOUND;
   return IF2IP_FOUND;
 }
 
diff --git a/Utilities/cmcurl/lib/imap.c b/Utilities/cmcurl/lib/imap.c
index bdcc69c..cad0e59 100644
--- a/Utilities/cmcurl/lib/imap.c
+++ b/Utilities/cmcurl/lib/imap.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -95,8 +95,7 @@
 static CURLcode imap_connect(struct connectdata *conn, bool *done);
 static CURLcode imap_disconnect(struct connectdata *conn, bool dead);
 static CURLcode imap_multi_statemach(struct connectdata *conn, bool *done);
-static int imap_getsock(struct connectdata *conn, curl_socket_t *socks,
-                        int numsocks);
+static int imap_getsock(struct connectdata *conn, curl_socket_t *socks);
 static CURLcode imap_doing(struct connectdata *conn, bool *dophase_done);
 static CURLcode imap_setup_connection(struct connectdata *conn);
 static char *imap_atom(const char *str, bool escape_only);
@@ -188,7 +187,7 @@
   conn->handler = &Curl_handler_imaps;
 
   /* Set the connection's upgraded to TLS flag */
-  conn->tls_upgraded = TRUE;
+  conn->bits.tls_upgraded = TRUE;
 }
 #else
 #define imap_to_imaps(x) Curl_nop_stmt
@@ -444,10 +443,8 @@
  */
 static CURLcode imap_perform_starttls(struct connectdata *conn)
 {
-  CURLcode result = CURLE_OK;
-
   /* Send the STARTTLS command */
-  result = imap_sendf(conn, "STARTTLS");
+  CURLcode result = imap_sendf(conn, "STARTTLS");
 
   if(!result)
     state(conn, IMAP_STARTTLS);
@@ -463,11 +460,10 @@
  */
 static CURLcode imap_perform_upgrade_tls(struct connectdata *conn)
 {
-  CURLcode result = CURLE_OK;
-  struct imap_conn *imapc = &conn->proto.imapc;
-
   /* Start the SSL connection */
-  result = Curl_ssl_connect_nonblocking(conn, FIRSTSOCKET, &imapc->ssldone);
+  struct imap_conn *imapc = &conn->proto.imapc;
+  CURLcode result = Curl_ssl_connect_nonblocking(conn, FIRSTSOCKET,
+                                                 &imapc->ssldone);
 
   if(!result) {
     if(imapc->state != IMAP_UPGRADETLS)
@@ -826,10 +822,8 @@
  */
 static CURLcode imap_perform_logout(struct connectdata *conn)
 {
-  CURLcode result = CURLE_OK;
-
   /* Send the LOGOUT command */
-  result = imap_sendf(conn, "LOGOUT");
+  CURLcode result = imap_sendf(conn, "LOGOUT");
 
   if(!result)
     state(conn, IMAP_LOGOUT);
@@ -1312,6 +1306,7 @@
       break;
 
     case IMAP_LIST:
+    case IMAP_SEARCH:
       result = imap_state_listsearch_resp(conn, imapcode, imapc->state);
       break;
 
@@ -1335,10 +1330,6 @@
       result = imap_state_append_final_resp(conn, imapcode, imapc->state);
       break;
 
-    case IMAP_SEARCH:
-      result = imap_state_listsearch_resp(conn, imapcode, imapc->state);
-      break;
-
     case IMAP_LOGOUT:
       /* fallthrough, just stop! */
     default:
@@ -1397,10 +1388,9 @@
 }
 
 /* For the IMAP "protocol connect" and "doing" phases only */
-static int imap_getsock(struct connectdata *conn, curl_socket_t *socks,
-                        int numsocks)
+static int imap_getsock(struct connectdata *conn, curl_socket_t *socks)
 {
-  return Curl_pp_getsock(&conn->proto.imapc.pp, socks, numsocks);
+  return Curl_pp_getsock(&conn->proto.imapc.pp, socks);
 }
 
 /***********************************************************************
@@ -1720,7 +1710,7 @@
     return result;
 
   /* Clear the TLS upgraded flag */
-  conn->tls_upgraded = FALSE;
+  conn->bits.tls_upgraded = FALSE;
 
   return CURLE_OK;
 }
@@ -1967,7 +1957,7 @@
       end--;
 
     result = Curl_urldecode(data, begin, end - begin, &imap->mailbox, NULL,
-                            TRUE);
+                            REJECT_CTRL);
     if(result)
       return result;
   }
@@ -1989,7 +1979,8 @@
       return CURLE_URL_MALFORMAT;
 
     /* Decode the name parameter */
-    result = Curl_urldecode(data, begin, ptr - begin, &name, NULL, TRUE);
+    result = Curl_urldecode(data, begin, ptr - begin, &name, NULL,
+                            REJECT_CTRL);
     if(result)
       return result;
 
@@ -1999,7 +1990,8 @@
       ptr++;
 
     /* Decode the value parameter */
-    result = Curl_urldecode(data, begin, ptr - begin, &value, &valuelen, TRUE);
+    result = Curl_urldecode(data, begin, ptr - begin, &value, &valuelen,
+                            REJECT_CTRL);
     if(result) {
       free(name);
       return result;
@@ -2087,7 +2079,7 @@
 
   if(custom) {
     /* URL decode the custom request */
-    result = Curl_urldecode(data, custom, 0, &imap->custom, NULL, TRUE);
+    result = Curl_urldecode(data, custom, 0, &imap->custom, NULL, REJECT_CTRL);
 
     /* Extract the parameters if specified */
     if(!result) {
diff --git a/Utilities/cmcurl/lib/imap.h b/Utilities/cmcurl/lib/imap.h
index 0efcfd2..4786f56 100644
--- a/Utilities/cmcurl/lib/imap.h
+++ b/Utilities/cmcurl/lib/imap.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 2009 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 2009 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
diff --git a/Utilities/cmcurl/lib/inet_ntop.c b/Utilities/cmcurl/lib/inet_ntop.c
index 855981c..9a5af7f 100644
--- a/Utilities/cmcurl/lib/inet_ntop.c
+++ b/Utilities/cmcurl/lib/inet_ntop.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1996-2001  Internet Software Consortium.
+ * Copyright (C) 1996-2019  Internet Software Consortium.
  *
  * Permission to use, copy, modify, and distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
diff --git a/Utilities/cmcurl/lib/inet_ntop.h b/Utilities/cmcurl/lib/inet_ntop.h
index d150bb6..9d3f237 100644
--- a/Utilities/cmcurl/lib/inet_ntop.h
+++ b/Utilities/cmcurl/lib/inet_ntop.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
diff --git a/Utilities/cmcurl/lib/inet_pton.c b/Utilities/cmcurl/lib/inet_pton.c
index 0d65ae0..9c87a05 100644
--- a/Utilities/cmcurl/lib/inet_pton.c
+++ b/Utilities/cmcurl/lib/inet_pton.c
@@ -1,6 +1,6 @@
 /* This is from the BIND 4.9.4 release, modified to compile by itself */
 
-/* Copyright (c) 1996 by Internet Software Consortium.
+/* Copyright (c) 1996 - 2019 by Internet Software Consortium.
  *
  * Permission to use, copy, modify, and distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
diff --git a/Utilities/cmcurl/lib/inet_pton.h b/Utilities/cmcurl/lib/inet_pton.h
index 0209b9b..e695af9 100644
--- a/Utilities/cmcurl/lib/inet_pton.h
+++ b/Utilities/cmcurl/lib/inet_pton.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
diff --git a/Utilities/cmcurl/lib/krb5.c b/Utilities/cmcurl/lib/krb5.c
index 147ab02..5bd8e71 100644
--- a/Utilities/cmcurl/lib/krb5.c
+++ b/Utilities/cmcurl/lib/krb5.c
@@ -1,8 +1,8 @@
 /* GSSAPI/krb5 support for FTP - loosely based on old krb4.c
  *
- * Copyright (c) 1995, 1996, 1997, 1998, 1999 Kungliga Tekniska Högskolan
+ * Copyright (c) 1995, 1996, 1997, 1998, 1999 Kungliga Tekniska Högskolan
  * (Royal Institute of Technology, Stockholm, Sweden).
- * Copyright (c) 2004 - 2017 Daniel Stenberg
+ * Copyright (c) 2004 - 2019 Daniel Stenberg
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -320,10 +320,8 @@
     OM_uint32 min;
     gss_ctx_id_t *context = app_data;
     if(*context != GSS_C_NO_CONTEXT) {
-#ifdef DEBUGBUILD
-      OM_uint32 maj =
-#endif
-      gss_delete_sec_context(&min, context, GSS_C_NO_BUFFER);
+      OM_uint32 maj = gss_delete_sec_context(&min, context, GSS_C_NO_BUFFER);
+      (void)maj;
       DEBUGASSERT(maj == GSS_S_COMPLETE);
     }
 }
diff --git a/Utilities/cmcurl/lib/ldap.c b/Utilities/cmcurl/lib/ldap.c
index fd31faa..512def6 100644
--- a/Utilities/cmcurl/lib/ldap.c
+++ b/Utilities/cmcurl/lib/ldap.c
@@ -5,7 +5,7 @@
  *                | (__| |_| |  _ <| |___
  *                 \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -75,7 +75,7 @@
 
 /* Use our own implementation. */
 
-typedef struct {
+struct ldap_urldesc {
   char   *lud_host;
   int     lud_port;
 #if defined(USE_WIN32_LDAP)
@@ -95,10 +95,10 @@
   size_t    lud_attrs_dups; /* how many were dup'ed, this field is not in the
                                "real" struct so can only be used in code
                                without HAVE_LDAP_URL_PARSE defined */
-} CURL_LDAPURLDesc;
+};
 
 #undef LDAPURLDesc
-#define LDAPURLDesc             CURL_LDAPURLDesc
+#define LDAPURLDesc struct ldap_urldesc
 
 static int  _ldap_url_parse(const struct connectdata *conn,
                             LDAPURLDesc **ludp);
@@ -112,13 +112,19 @@
   #define LDAP_TRACE(x)   do { \
                             _ldap_trace("%u: ", __LINE__); \
                             _ldap_trace x; \
-                          } WHILE_FALSE
+                          } while(0)
 
   static void _ldap_trace(const char *fmt, ...);
 #else
   #define LDAP_TRACE(x)   Curl_nop_stmt
 #endif
 
+#if defined(USE_WIN32_LDAP) && defined(ldap_err2string)
+/* Use ansi error strings in UNICODE builds */
+#undef ldap_err2string
+#define ldap_err2string ldap_err2stringA
+#endif
+
 
 static CURLcode Curl_ldap(struct connectdata *conn, bool *done);
 
@@ -233,13 +239,13 @@
   PTCHAR inpass = NULL;
 
   if(user && passwd && (conn->data->set.httpauth & CURLAUTH_BASIC)) {
-    inuser = Curl_convert_UTF8_to_tchar((char *) user);
-    inpass = Curl_convert_UTF8_to_tchar((char *) passwd);
+    inuser = curlx_convert_UTF8_to_tchar((char *) user);
+    inpass = curlx_convert_UTF8_to_tchar((char *) passwd);
 
     rc = ldap_simple_bind_s(server, inuser, inpass);
 
-    Curl_unicodefree(inuser);
-    Curl_unicodefree(inpass);
+    curlx_unicodefree(inuser);
+    curlx_unicodefree(inpass);
   }
 #if defined(USE_WINDOWS_SSPI)
   else {
@@ -300,7 +306,7 @@
           ldap_ssl ? "encrypted" : "cleartext");
 
 #if defined(USE_WIN32_LDAP)
-  host = Curl_convert_UTF8_to_tchar(conn->host.name);
+  host = curlx_convert_UTF8_to_tchar(conn->host.name);
   if(!host) {
     result = CURLE_OUT_OF_MEMORY;
 
@@ -511,7 +517,7 @@
       size_t name_len;
 #if defined(USE_WIN32_LDAP)
       TCHAR *dn = ldap_get_dn(server, entryIterator);
-      name = Curl_convert_tchar_to_UTF8(dn);
+      name = curlx_convert_tchar_to_UTF8(dn);
       if(!name) {
         ldap_memfree(dn);
 
@@ -527,7 +533,7 @@
       result = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"DN: ", 4);
       if(result) {
 #if defined(USE_WIN32_LDAP)
-        Curl_unicodefree(name);
+        curlx_unicodefree(name);
 #endif
         ldap_memfree(dn);
 
@@ -538,7 +544,7 @@
                                  name_len);
       if(result) {
 #if defined(USE_WIN32_LDAP)
-        Curl_unicodefree(name);
+        curlx_unicodefree(name);
 #endif
         ldap_memfree(dn);
 
@@ -548,7 +554,7 @@
       result = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"\n", 1);
       if(result) {
 #if defined(USE_WIN32_LDAP)
-        Curl_unicodefree(name);
+        curlx_unicodefree(name);
 #endif
         ldap_memfree(dn);
 
@@ -558,7 +564,7 @@
       dlsize += name_len + 5;
 
 #if defined(USE_WIN32_LDAP)
-      Curl_unicodefree(name);
+      curlx_unicodefree(name);
 #endif
       ldap_memfree(dn);
     }
@@ -570,7 +576,7 @@
       BerValue **vals;
       size_t attr_len;
 #if defined(USE_WIN32_LDAP)
-      char *attr = Curl_convert_tchar_to_UTF8(attribute);
+      char *attr = curlx_convert_tchar_to_UTF8(attribute);
       if(!attr) {
         if(ber)
           ber_free(ber, 0);
@@ -591,7 +597,7 @@
           if(result) {
             ldap_value_free_len(vals);
 #if defined(USE_WIN32_LDAP)
-            Curl_unicodefree(attr);
+            curlx_unicodefree(attr);
 #endif
             ldap_memfree(attribute);
             if(ber)
@@ -605,7 +611,7 @@
           if(result) {
             ldap_value_free_len(vals);
 #if defined(USE_WIN32_LDAP)
-            Curl_unicodefree(attr);
+            curlx_unicodefree(attr);
 #endif
             ldap_memfree(attribute);
             if(ber)
@@ -618,7 +624,7 @@
           if(result) {
             ldap_value_free_len(vals);
 #if defined(USE_WIN32_LDAP)
-            Curl_unicodefree(attr);
+            curlx_unicodefree(attr);
 #endif
             ldap_memfree(attribute);
             if(ber)
@@ -640,7 +646,7 @@
             if(result) {
               ldap_value_free_len(vals);
 #if defined(USE_WIN32_LDAP)
-              Curl_unicodefree(attr);
+              curlx_unicodefree(attr);
 #endif
               ldap_memfree(attribute);
               if(ber)
@@ -656,7 +662,7 @@
               if(result) {
                 ldap_value_free_len(vals);
 #if defined(USE_WIN32_LDAP)
-                Curl_unicodefree(attr);
+                curlx_unicodefree(attr);
 #endif
                 ldap_memfree(attribute);
                 if(ber)
@@ -674,7 +680,7 @@
             if(result) {
               ldap_value_free_len(vals);
 #if defined(USE_WIN32_LDAP)
-              Curl_unicodefree(attr);
+              curlx_unicodefree(attr);
 #endif
               ldap_memfree(attribute);
               if(ber)
@@ -690,7 +696,7 @@
           if(result) {
             ldap_value_free_len(vals);
 #if defined(USE_WIN32_LDAP)
-            Curl_unicodefree(attr);
+            curlx_unicodefree(attr);
 #endif
             ldap_memfree(attribute);
             if(ber)
@@ -708,7 +714,7 @@
 
       /* Free the attribute as we are done with it */
 #if defined(USE_WIN32_LDAP)
-      Curl_unicodefree(attr);
+      curlx_unicodefree(attr);
 #endif
       ldap_memfree(attribute);
 
@@ -740,7 +746,7 @@
 #endif /* HAVE_LDAP_SSL && CURL_HAS_NOVELL_LDAPSDK */
 
 #if defined(USE_WIN32_LDAP)
-  Curl_unicodefree(host);
+  curlx_unicodefree(host);
 #endif
 
   /* no data to transfer */
@@ -838,10 +844,10 @@
 static int _ldap_url_parse2(const struct connectdata *conn, LDAPURLDesc *ludp)
 {
   int rc = LDAP_SUCCESS;
-  char *path;
-  char *query;
   char *p;
-  char *q;
+  char *path;
+  char *q = NULL;
+  char *query = NULL;
   size_t i;
 
   if(!conn->data ||
@@ -859,11 +865,13 @@
   if(!path)
     return LDAP_NO_MEMORY;
 
-  /* Duplicate the query */
-  q = query = strdup(conn->data->state.up.query);
-  if(!query) {
-    free(path);
-    return LDAP_NO_MEMORY;
+  /* Duplicate the query if present */
+  if(conn->data->state.up.query) {
+    q = query = strdup(conn->data->state.up.query);
+    if(!query) {
+      free(path);
+      return LDAP_NO_MEMORY;
+    }
   }
 
   /* Parse the DN (Distinguished Name) */
@@ -875,7 +883,7 @@
     LDAP_TRACE(("DN '%s'\n", dn));
 
     /* Unescape the DN */
-    result = Curl_urldecode(conn->data, dn, 0, &unescaped, NULL, FALSE);
+    result = Curl_urldecode(conn->data, dn, 0, &unescaped, NULL, REJECT_ZERO);
     if(result) {
       rc = LDAP_NO_MEMORY;
 
@@ -884,10 +892,10 @@
 
 #if defined(USE_WIN32_LDAP)
     /* Convert the unescaped string to a tchar */
-    ludp->lud_dn = Curl_convert_UTF8_to_tchar(unescaped);
+    ludp->lud_dn = curlx_convert_UTF8_to_tchar(unescaped);
 
     /* Free the unescaped string as we are done with it */
-    Curl_unicodefree(unescaped);
+    curlx_unicodefree(unescaped);
 
     if(!ludp->lud_dn) {
       rc = LDAP_NO_MEMORY;
@@ -941,7 +949,7 @@
 
       /* Unescape the attribute */
       result = Curl_urldecode(conn->data, attributes[i], 0, &unescaped, NULL,
-                              FALSE);
+                              REJECT_ZERO);
       if(result) {
         free(attributes);
 
@@ -952,10 +960,10 @@
 
 #if defined(USE_WIN32_LDAP)
       /* Convert the unescaped string to a tchar */
-      ludp->lud_attrs[i] = Curl_convert_UTF8_to_tchar(unescaped);
+      ludp->lud_attrs[i] = curlx_convert_UTF8_to_tchar(unescaped);
 
       /* Free the unescaped string as we are done with it */
-      Curl_unicodefree(unescaped);
+      curlx_unicodefree(unescaped);
 
       if(!ludp->lud_attrs[i]) {
         free(attributes);
@@ -1010,7 +1018,8 @@
     LDAP_TRACE(("filter '%s'\n", filter));
 
     /* Unescape the filter */
-    result = Curl_urldecode(conn->data, filter, 0, &unescaped, NULL, FALSE);
+    result = Curl_urldecode(conn->data, filter, 0, &unescaped, NULL,
+                            REJECT_ZERO);
     if(result) {
       rc = LDAP_NO_MEMORY;
 
@@ -1019,10 +1028,10 @@
 
 #if defined(USE_WIN32_LDAP)
     /* Convert the unescaped string to a tchar */
-    ludp->lud_filter = Curl_convert_UTF8_to_tchar(unescaped);
+    ludp->lud_filter = curlx_convert_UTF8_to_tchar(unescaped);
 
     /* Free the unescaped string as we are done with it */
-    Curl_unicodefree(unescaped);
+    curlx_unicodefree(unescaped);
 
     if(!ludp->lud_filter) {
       rc = LDAP_NO_MEMORY;
diff --git a/Utilities/cmcurl/lib/llist.c b/Utilities/cmcurl/lib/llist.c
index f8769c2..e7c6f51 100644
--- a/Utilities/cmcurl/lib/llist.c
+++ b/Utilities/cmcurl/lib/llist.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -144,54 +144,3 @@
 {
   return list->size;
 }
-
-/*
- * @unittest: 1300
- */
-void Curl_llist_move(struct curl_llist *list, struct curl_llist_element *e,
-                     struct curl_llist *to_list,
-                     struct curl_llist_element *to_e)
-{
-  /* Remove element from list */
-  if(e == NULL || list->size == 0)
-    return;
-
-  if(e == list->head) {
-    list->head = e->next;
-
-    if(list->head == NULL)
-      list->tail = NULL;
-    else
-      e->next->prev = NULL;
-  }
-  else {
-    e->prev->next = e->next;
-    if(!e->next)
-      list->tail = e->prev;
-    else
-      e->next->prev = e->prev;
-  }
-
-  --list->size;
-
-  /* Add element to to_list after to_e */
-  if(to_list->size == 0) {
-    to_list->head = e;
-    to_list->head->prev = NULL;
-    to_list->head->next = NULL;
-    to_list->tail = e;
-  }
-  else {
-    e->next = to_e->next;
-    e->prev = to_e;
-    if(to_e->next) {
-      to_e->next->prev = e;
-    }
-    else {
-      to_list->tail = e;
-    }
-    to_e->next = e;
-  }
-
-  ++to_list->size;
-}
diff --git a/Utilities/cmcurl/lib/llist.h b/Utilities/cmcurl/lib/llist.h
index b9d4c89..0178c42 100644
--- a/Utilities/cmcurl/lib/llist.h
+++ b/Utilities/cmcurl/lib/llist.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -47,7 +47,4 @@
                        void *);
 size_t Curl_llist_count(struct curl_llist *);
 void Curl_llist_destroy(struct curl_llist *, void *);
-void Curl_llist_move(struct curl_llist *, struct curl_llist_element *,
-                     struct curl_llist *, struct curl_llist_element *);
-
 #endif /* HEADER_CURL_LLIST_H */
diff --git a/Utilities/cmcurl/lib/md4.c b/Utilities/cmcurl/lib/md4.c
index e7c77bc..0fab52d 100644
--- a/Utilities/cmcurl/lib/md4.c
+++ b/Utilities/cmcurl/lib/md4.c
@@ -1,5 +1,231 @@
-/*
- * !checksrc! disable COPYRIGHT
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#if !defined(CURL_DISABLE_CRYPTO_AUTH)
+
+#include "curl_md4.h"
+#include "warnless.h"
+
+#ifdef USE_OPENSSL
+#include <openssl/opensslconf.h>
+#if defined(OPENSSL_VERSION_MAJOR) && (OPENSSL_VERSION_MAJOR >= 3)
+/* OpenSSL 3.0.0 marks the MD4 functions as deprecated */
+#define OPENSSL_NO_MD4
+#endif
+#endif /* USE_OPENSSL */
+
+#ifdef USE_MBEDTLS
+#include <mbedtls/config.h>
+#include <mbedtls/version.h>
+
+#if(MBEDTLS_VERSION_NUMBER >= 0x02070000)
+  #define HAS_MBEDTLS_RESULT_CODE_BASED_FUNCTIONS
+#endif
+#endif /* USE_MBEDTLS */
+
+#if defined(USE_GNUTLS_NETTLE)
+
+#include <nettle/md4.h>
+
+#include "curl_memory.h"
+
+/* The last #include file should be: */
+#include "memdebug.h"
+
+typedef struct md4_ctx MD4_CTX;
+
+static void MD4_Init(MD4_CTX *ctx)
+{
+  md4_init(ctx);
+}
+
+static void MD4_Update(MD4_CTX *ctx, const void *data, unsigned long size)
+{
+  md4_update(ctx, size, data);
+}
+
+static void MD4_Final(unsigned char *result, MD4_CTX *ctx)
+{
+  md4_digest(ctx, MD4_DIGEST_SIZE, result);
+}
+
+#elif defined(USE_GNUTLS)
+
+#include <gcrypt.h>
+
+#include "curl_memory.h"
+
+/* The last #include file should be: */
+#include "memdebug.h"
+
+typedef gcry_md_hd_t MD4_CTX;
+
+static void MD4_Init(MD4_CTX *ctx)
+{
+  gcry_md_open(ctx, GCRY_MD_MD4, 0);
+}
+
+static void MD4_Update(MD4_CTX *ctx, const void *data, unsigned long size)
+{
+  gcry_md_write(*ctx, data, size);
+}
+
+static void MD4_Final(unsigned char *result, MD4_CTX *ctx)
+{
+  memcpy(result, gcry_md_read(*ctx, 0), MD4_DIGEST_LENGTH);
+  gcry_md_close(*ctx);
+}
+
+#elif defined(USE_OPENSSL) && !defined(OPENSSL_NO_MD4)
+/* When OpenSSL is available we use the MD4-functions from OpenSSL */
+#include <openssl/md4.h>
+
+#elif (defined(__MAC_OS_X_VERSION_MAX_ALLOWED) && \
+              (__MAC_OS_X_VERSION_MAX_ALLOWED >= 1040)) || \
+      (defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && \
+              (__IPHONE_OS_VERSION_MAX_ALLOWED >= 20000))
+
+#include <CommonCrypto/CommonDigest.h>
+
+#include "curl_memory.h"
+
+/* The last #include file should be: */
+#include "memdebug.h"
+
+typedef CC_MD4_CTX MD4_CTX;
+
+static void MD4_Init(MD4_CTX *ctx)
+{
+  (void)CC_MD4_Init(ctx);
+}
+
+static void MD4_Update(MD4_CTX *ctx, const void *data, unsigned long size)
+{
+  (void)CC_MD4_Update(ctx, data, (CC_LONG)size);
+}
+
+static void MD4_Final(unsigned char *result, MD4_CTX *ctx)
+{
+  (void)CC_MD4_Final(result, ctx);
+}
+
+#elif defined(USE_WIN32_CRYPTO)
+
+#include <wincrypt.h>
+
+#include "curl_memory.h"
+
+/* The last #include file should be: */
+#include "memdebug.h"
+
+struct md4_ctx {
+  HCRYPTPROV hCryptProv;
+  HCRYPTHASH hHash;
+};
+typedef struct md4_ctx MD4_CTX;
+
+static void MD4_Init(MD4_CTX *ctx)
+{
+  ctx->hCryptProv = 0;
+  ctx->hHash = 0;
+
+  if(CryptAcquireContext(&ctx->hCryptProv, NULL, NULL, PROV_RSA_FULL,
+                         CRYPT_VERIFYCONTEXT | CRYPT_SILENT)) {
+    CryptCreateHash(ctx->hCryptProv, CALG_MD4, 0, 0, &ctx->hHash);
+  }
+}
+
+static void MD4_Update(MD4_CTX *ctx, const void *data, unsigned long size)
+{
+  CryptHashData(ctx->hHash, (BYTE *)data, (unsigned int) size, 0);
+}
+
+static void MD4_Final(unsigned char *result, MD4_CTX *ctx)
+{
+  unsigned long length = 0;
+
+  CryptGetHashParam(ctx->hHash, HP_HASHVAL, NULL, &length, 0);
+  if(length == MD4_DIGEST_LENGTH)
+    CryptGetHashParam(ctx->hHash, HP_HASHVAL, result, &length, 0);
+
+  if(ctx->hHash)
+    CryptDestroyHash(ctx->hHash);
+
+  if(ctx->hCryptProv)
+    CryptReleaseContext(ctx->hCryptProv, 0);
+}
+
+#elif(defined(USE_MBEDTLS) && defined(MBEDTLS_MD4_C))
+
+#include <mbedtls/md4.h>
+
+#include "curl_memory.h"
+
+/* The last #include file should be: */
+#include "memdebug.h"
+
+struct md4_ctx {
+  void *data;
+  unsigned long size;
+};
+typedef struct md4_ctx MD4_CTX;
+
+static void MD4_Init(MD4_CTX *ctx)
+{
+  ctx->data = NULL;
+  ctx->size = 0;
+}
+
+static void MD4_Update(MD4_CTX *ctx, const void *data, unsigned long size)
+{
+  if(ctx->data == NULL) {
+    ctx->data = malloc(size);
+    if(ctx->data != NULL) {
+      memcpy(ctx->data, data, size);
+      ctx->size = size;
+    }
+  }
+}
+
+static void MD4_Final(unsigned char *result, MD4_CTX *ctx)
+{
+  if(ctx->data != NULL) {
+#if !defined(HAS_MBEDTLS_RESULT_CODE_BASED_FUNCTIONS)
+    mbedtls_md4(ctx->data, ctx->size, result);
+#else
+    (void) mbedtls_md4_ret(ctx->data, ctx->size, result);
+#endif
+
+    Curl_safefree(ctx->data);
+    ctx->size = 0;
+  }
+}
+
+#else
+/* When no other crypto library is available, or the crypto library doesn't
+ * support MD4, we use this code segment this implementation of it
+ *
  * This is an OpenSSL-compatible implementation of the RSA Data Security, Inc.
  * MD4 Message-Digest Algorithm (RFC 1320).
  *
@@ -36,31 +262,19 @@
  * compile-time configuration.
  */
 
-#include "curl_setup.h"
-
-/* The NSS, OS/400, and when not included, OpenSSL and mbed TLS crypto
- * libraries do not provide the MD4 hash algorithm, so we use this
- * implementation of it */
-#if defined(USE_NSS) || defined(USE_OS400CRYPTO) || \
-    (defined(USE_OPENSSL) && defined(OPENSSL_NO_MD4)) || \
-    (defined(USE_MBEDTLS) && !defined(MBEDTLS_MD4_C))
-
-#include "curl_md4.h"
-#include "warnless.h"
-
-#ifndef HAVE_OPENSSL
 
 #include <string.h>
 
 /* Any 32-bit or wider unsigned integer data type will do */
 typedef unsigned int MD4_u32plus;
 
-typedef struct {
+struct md4_ctx {
   MD4_u32plus lo, hi;
   MD4_u32plus a, b, c, d;
   unsigned char buffer[64];
   MD4_u32plus block[16];
-} MD4_CTX;
+};
+typedef struct md4_ctx MD4_CTX;
 
 static void MD4_Init(MD4_CTX *ctx);
 static void MD4_Update(MD4_CTX *ctx, const void *data, unsigned long size);
@@ -298,16 +512,16 @@
   memset(ctx, 0, sizeof(*ctx));
 }
 
-#endif
+#endif /* CRYPTO LIBS */
 
-void Curl_md4it(unsigned char *output, const unsigned char *input, size_t len)
+void Curl_md4it(unsigned char *output, const unsigned char *input,
+                const size_t len)
 {
   MD4_CTX ctx;
+
   MD4_Init(&ctx);
   MD4_Update(&ctx, input, curlx_uztoui(len));
   MD4_Final(output, &ctx);
 }
 
-#endif /* defined(USE_NSS) || defined(USE_OS400CRYPTO) ||
-    (defined(USE_OPENSSL) && defined(OPENSSL_NO_MD4)) ||
-    (defined(USE_MBEDTLS) && !defined(MBEDTLS_MD4_C)) */
+#endif /* CURL_DISABLE_CRYPTO_AUTH */
diff --git a/Utilities/cmcurl/lib/md5.c b/Utilities/cmcurl/lib/md5.c
index 2b81ca4..557a51e 100644
--- a/Utilities/cmcurl/lib/md5.c
+++ b/Utilities/cmcurl/lib/md5.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -30,6 +30,14 @@
 #include "curl_hmac.h"
 #include "warnless.h"
 
+#ifdef USE_MBEDTLS
+#include <mbedtls/version.h>
+
+#if(MBEDTLS_VERSION_NUMBER >= 0x02070000)
+  #define HAS_MBEDTLS_RESULT_CODE_BASED_FUNCTIONS
+#endif
+#endif /* USE_MBEDTLS */
+
 #if defined(USE_GNUTLS_NETTLE)
 
 #include <nettle/md5.h>
@@ -51,7 +59,7 @@
   md5_update(ctx, inputLen, input);
 }
 
-static void MD5_Final(unsigned char digest[16], MD5_CTX *ctx)
+static void MD5_Final(unsigned char *digest, MD5_CTX *ctx)
 {
   md5_digest(ctx, 16, digest);
 }
@@ -77,7 +85,7 @@
   gcry_md_write(*ctx, input, inputLen);
 }
 
-static void MD5_Final(unsigned char digest[16], MD5_CTX *ctx)
+static void MD5_Final(unsigned char *digest, MD5_CTX *ctx)
 {
   memcpy(digest, gcry_md_read(*ctx, 0), 16);
   gcry_md_close(*ctx);
@@ -90,6 +98,46 @@
 /* The last #include file should be: */
 #include "memdebug.h"
 
+#elif defined(USE_MBEDTLS)
+
+#include <mbedtls/md5.h>
+
+#include "curl_memory.h"
+
+/* The last #include file should be: */
+#include "memdebug.h"
+
+typedef mbedtls_md5_context MD5_CTX;
+
+static void MD5_Init(MD5_CTX *ctx)
+{
+#if !defined(HAS_MBEDTLS_RESULT_CODE_BASED_FUNCTIONS)
+  mbedtls_md5_starts(ctx);
+#else
+  (void) mbedtls_md5_starts_ret(ctx);
+#endif
+}
+
+static void MD5_Update(MD5_CTX *ctx,
+                       const unsigned char *data,
+                       unsigned int length)
+{
+#if !defined(HAS_MBEDTLS_RESULT_CODE_BASED_FUNCTIONS)
+  mbedtls_md5_update(ctx, data, length);
+#else
+  (void) mbedtls_md5_update_ret(ctx, data, length);
+#endif
+}
+
+static void MD5_Final(unsigned char *digest, MD5_CTX *ctx)
+{
+#if !defined(HAS_MBEDTLS_RESULT_CODE_BASED_FUNCTIONS)
+  mbedtls_md5_finish(ctx, digest);
+#else
+  (void) mbedtls_md5_finish_ret(ctx, digest);
+#endif
+}
+
 #elif (defined(__MAC_OS_X_VERSION_MAX_ALLOWED) && \
               (__MAC_OS_X_VERSION_MAX_ALLOWED >= 1040)) || \
       (defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && \
@@ -119,27 +167,28 @@
   CC_MD5_Update(ctx, input, inputLen);
 }
 
-static void MD5_Final(unsigned char digest[16], MD5_CTX *ctx)
+static void MD5_Final(unsigned char *digest, MD5_CTX *ctx)
 {
   CC_MD5_Final(digest, ctx);
 }
 
-#elif defined(WIN32) && !defined(CURL_WINDOWS_APP)
+#elif defined(USE_WIN32_CRYPTO)
 
 #include <wincrypt.h>
 #include "curl_memory.h"
 /* The last #include file should be: */
 #include "memdebug.h"
 
-typedef struct {
+struct md5_ctx {
   HCRYPTPROV hCryptProv;
   HCRYPTHASH hHash;
-} MD5_CTX;
+};
+typedef struct md5_ctx MD5_CTX;
 
 static void MD5_Init(MD5_CTX *ctx)
 {
-  if(CryptAcquireContext(&ctx->hCryptProv, NULL, NULL,
-                         PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) {
+  if(CryptAcquireContext(&ctx->hCryptProv, NULL, NULL, PROV_RSA_FULL,
+                         CRYPT_VERIFYCONTEXT | CRYPT_SILENT)) {
     CryptCreateHash(ctx->hCryptProv, CALG_MD5, 0, 0, &ctx->hHash);
   }
 }
@@ -151,7 +200,7 @@
   CryptHashData(ctx->hHash, (unsigned char *)input, inputLen, 0);
 }
 
-static void MD5_Final(unsigned char digest[16], MD5_CTX *ctx)
+static void MD5_Final(unsigned char *digest, MD5_CTX *ctx)
 {
   unsigned long length = 0;
   CryptGetHashParam(ctx->hHash, HP_HASHVAL, NULL, &length, 0);
@@ -164,7 +213,9 @@
 }
 
 #else
+
 /* When no other crypto library is available we use this code segment */
+
 /*
  * This is an OpenSSL-compatible implementation of the RSA Data Security, Inc.
  * MD5 Message-Digest Algorithm (RFC 1321).
@@ -211,12 +262,13 @@
 /* Any 32-bit or wider unsigned integer data type will do */
 typedef unsigned int MD5_u32plus;
 
-typedef struct {
+struct md5_ctx {
   MD5_u32plus lo, hi;
   MD5_u32plus a, b, c, d;
   unsigned char buffer[64];
   MD5_u32plus block[16];
-} MD5_CTX;
+};
+typedef struct md5_ctx MD5_CTX;
 
 static void MD5_Init(MD5_CTX *ctx);
 static void MD5_Update(MD5_CTX *ctx, const void *data, unsigned long size);
@@ -478,7 +530,7 @@
 
 #endif /* CRYPTO LIBS */
 
-const HMAC_params Curl_HMAC_MD5[] = {
+const struct HMAC_params Curl_HMAC_MD5[] = {
   {
     /* Hash initialization function. */
     CURLX_FUNCTION_CAST(HMAC_hinit_func, MD5_Init),
@@ -495,7 +547,7 @@
   }
 };
 
-const MD5_params Curl_DIGEST_MD5[] = {
+const struct MD5_params Curl_DIGEST_MD5[] = {
   {
     /* Digest initialization function */
     CURLX_FUNCTION_CAST(Curl_MD5_init_func, MD5_Init),
@@ -513,18 +565,19 @@
 /*
  * @unittest: 1601
  */
-void Curl_md5it(unsigned char *outbuffer, /* 16 bytes */
-                const unsigned char *input)
+void Curl_md5it(unsigned char *outbuffer, const unsigned char *input,
+                const size_t len)
 {
   MD5_CTX ctx;
+
   MD5_Init(&ctx);
-  MD5_Update(&ctx, input, curlx_uztoui(strlen((char *)input)));
+  MD5_Update(&ctx, input, curlx_uztoui(len));
   MD5_Final(outbuffer, &ctx);
 }
 
-MD5_context *Curl_MD5_init(const MD5_params *md5params)
+struct MD5_context *Curl_MD5_init(const struct MD5_params *md5params)
 {
-  MD5_context *ctxt;
+  struct MD5_context *ctxt;
 
   /* Create MD5 context */
   ctxt = malloc(sizeof(*ctxt));
@@ -546,7 +599,7 @@
   return ctxt;
 }
 
-CURLcode Curl_MD5_update(MD5_context *context,
+CURLcode Curl_MD5_update(struct MD5_context *context,
                          const unsigned char *data,
                          unsigned int len)
 {
@@ -555,7 +608,7 @@
   return CURLE_OK;
 }
 
-CURLcode Curl_MD5_final(MD5_context *context, unsigned char *result)
+CURLcode Curl_MD5_final(struct MD5_context *context, unsigned char *result)
 {
   (*context->md5_hash->md5_final_func)(result, context->md5_hashctx);
 
diff --git a/Utilities/cmcurl/lib/memdebug.c b/Utilities/cmcurl/lib/memdebug.c
index ede6009..1c6b151 100644
--- a/Utilities/cmcurl/lib/memdebug.c
+++ b/Utilities/cmcurl/lib/memdebug.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -328,7 +328,7 @@
     (Curl_cfree)(mem);
   }
 
-  if(source)
+  if(source && ptr)
     curl_dbg_log("MEM %s:%d free(%p)\n", source, line, (void *)ptr);
 }
 
diff --git a/Utilities/cmcurl/lib/memdebug.h b/Utilities/cmcurl/lib/memdebug.h
index 5236f60..7ca4426 100644
--- a/Utilities/cmcurl/lib/memdebug.h
+++ b/Utilities/cmcurl/lib/memdebug.h
@@ -169,6 +169,6 @@
  */
 
 #define Curl_safefree(ptr) \
-  do { free((ptr)); (ptr) = NULL;} WHILE_FALSE
+  do { free((ptr)); (ptr) = NULL;} while(0)
 
 #endif /* HEADER_CURL_MEMDEBUG_H */
diff --git a/Utilities/cmcurl/lib/mime.c b/Utilities/cmcurl/lib/mime.c
index 2135f72..6a9b64a 100644
--- a/Utilities/cmcurl/lib/mime.c
+++ b/Utilities/cmcurl/lib/mime.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -26,6 +26,7 @@
 
 #include "mime.h"
 #include "non-ascii.h"
+#include "warnless.h"
 #include "urldata.h"
 #include "sendf.h"
 
@@ -52,6 +53,10 @@
 
 
 #define READ_ERROR                      ((size_t) -1)
+#define STOP_FILLING                    ((size_t) -2)
+
+static size_t mime_subparts_read(char *buffer, size_t size, size_t nitems,
+                                 void *instream, bool *hasread);
 
 /* Encoders. */
 static size_t encoder_nop_read(char *buffer, size_t size, bool ateof,
@@ -66,7 +71,7 @@
                               curl_mimepart *part);
 static curl_off_t encoder_qp_size(curl_mimepart *part);
 
-static const mime_encoder encoders[] = {
+static const struct mime_encoder encoders[] = {
   {"binary", encoder_nop_read, encoder_nop_size},
   {"8bit", encoder_nop_read, encoder_nop_size},
   {"7bit", encoder_7bit_read, encoder_nop_size},
@@ -264,7 +269,8 @@
 
 
 /* Set readback state. */
-static void mimesetstate(mime_state *state, enum mimestate tok, void *ptr)
+static void mimesetstate(struct mime_state *state,
+                         enum mimestate tok, void *ptr)
 {
   state->state = tok;
   state->ptr = ptr;
@@ -337,7 +343,7 @@
 }
 
 /* Initialize data encoder state. */
-static void cleanup_encoder_state(mime_encoder_state *p)
+static void cleanup_encoder_state(struct mime_encoder_state *p)
 {
   p->pos = 0;
   p->bufbeg = 0;
@@ -347,17 +353,22 @@
 
 /* Dummy encoder. This is used for 8bit and binary content encodings. */
 static size_t encoder_nop_read(char *buffer, size_t size, bool ateof,
-                               curl_mimepart *part)
+                               struct curl_mimepart *part)
 {
-  mime_encoder_state *st = &part->encstate;
+  struct mime_encoder_state *st = &part->encstate;
   size_t insize = st->bufend - st->bufbeg;
 
   (void) ateof;
 
+  if(!size)
+    return STOP_FILLING;
+
   if(size > insize)
     size = insize;
+
   if(size)
-    memcpy(buffer, st->buf, size);
+    memcpy(buffer, st->buf + st->bufbeg, size);
+
   st->bufbeg += size;
   return size;
 }
@@ -372,11 +383,14 @@
 static size_t encoder_7bit_read(char *buffer, size_t size, bool ateof,
                                 curl_mimepart *part)
 {
-  mime_encoder_state *st = &part->encstate;
+  struct mime_encoder_state *st = &part->encstate;
   size_t cursize = st->bufend - st->bufbeg;
 
   (void) ateof;
 
+  if(!size)
+    return STOP_FILLING;
+
   if(size > cursize)
     size = cursize;
 
@@ -395,7 +409,7 @@
 static size_t encoder_base64_read(char *buffer, size_t size, bool ateof,
                                 curl_mimepart *part)
 {
-  mime_encoder_state *st = &part->encstate;
+  struct mime_encoder_state *st = &part->encstate;
   size_t cursize = 0;
   int i;
   char *ptr = buffer;
@@ -404,8 +418,11 @@
     /* Line full ? */
     if(st->pos > MAX_ENCODED_LINE_LENGTH - 4) {
       /* Yes, we need 2 characters for CRLF. */
-      if(size < 2)
+      if(size < 2) {
+        if(!cursize)
+          return STOP_FILLING;
         break;
+      }
       *ptr++ = '\r';
       *ptr++ = '\n';
       st->pos = 0;
@@ -414,7 +431,12 @@
     }
 
     /* Be sure there is enough space and input data for a base64 group. */
-    if(size < 4 || st->bufend - st->bufbeg < 3)
+    if(size < 4) {
+      if(!cursize)
+        return STOP_FILLING;
+      break;
+    }
+    if(st->bufend - st->bufbeg < 3)
       break;
 
     /* Encode three bytes as four characters. */
@@ -431,25 +453,31 @@
   }
 
   /* If at eof, we have to flush the buffered data. */
-  if(ateof && size >= 4) {
-    /* Buffered data size can only be 0, 1 or 2. */
-    ptr[2] = ptr[3] = '=';
-    i = 0;
-    switch(st->bufend - st->bufbeg) {
-    case 2:
-      i = (st->buf[st->bufbeg + 1] & 0xFF) << 8;
-      /* FALLTHROUGH */
-    case 1:
-      i |= (st->buf[st->bufbeg] & 0xFF) << 16;
-      ptr[0] = base64[(i >> 18) & 0x3F];
-      ptr[1] = base64[(i >> 12) & 0x3F];
-      if(++st->bufbeg != st->bufend) {
-        ptr[2] = base64[(i >> 6) & 0x3F];
-        st->bufbeg++;
+  if(ateof) {
+    if(size < 4) {
+      if(!cursize)
+        return STOP_FILLING;
+    }
+    else {
+      /* Buffered data size can only be 0, 1 or 2. */
+      ptr[2] = ptr[3] = '=';
+      i = 0;
+      switch(st->bufend - st->bufbeg) {
+      case 2:
+        i = (st->buf[st->bufbeg + 1] & 0xFF) << 8;
+        /* FALLTHROUGH */
+      case 1:
+        i |= (st->buf[st->bufbeg] & 0xFF) << 16;
+        ptr[0] = base64[(i >> 18) & 0x3F];
+        ptr[1] = base64[(i >> 12) & 0x3F];
+        if(++st->bufbeg != st->bufend) {
+          ptr[2] = base64[(i >> 6) & 0x3F];
+          st->bufbeg++;
+        }
+        cursize += 4;
+        st->pos += 4;
+        break;
       }
-      cursize += 4;
-      st->pos += 4;
-      break;
     }
   }
 
@@ -485,7 +513,7 @@
  * Check if a CRLF or end of data is in input buffer at current position + n.
  * Return -1 if more data needed, 1 if CRLF or end of data, else 0.
  */
-static int qp_lookahead_eol(mime_encoder_state *st, int ateof, size_t n)
+static int qp_lookahead_eol(struct mime_encoder_state *st, int ateof, size_t n)
 {
   n += st->bufbeg;
   if(n >= st->bufend && ateof)
@@ -502,7 +530,7 @@
 static size_t encoder_qp_read(char *buffer, size_t size, bool ateof,
                               curl_mimepart *part)
 {
-  mime_encoder_state *st = &part->encstate;
+  struct mime_encoder_state *st = &part->encstate;
   char *ptr = buffer;
   size_t cursize = 0;
   int softlinebreak;
@@ -567,7 +595,6 @@
         switch(qp_lookahead_eol(st, ateof, consumed)) {
         case -1:        /* Need more data. */
           return cursize;
-          break;
         case 0:         /* Not followed by a CRLF. */
           softlinebreak = 1;
           break;
@@ -581,8 +608,11 @@
     }
 
     /* If the output buffer would overflow, do not store. */
-    if(len > size)
+    if(len > size) {
+      if(!cursize)
+        return STOP_FILLING;
       break;
+    }
 
     /* Append to output buffer. */
     memcpy(ptr, buf, len);
@@ -612,16 +642,18 @@
                             void *instream)
 {
   curl_mimepart *part = (curl_mimepart *) instream;
-  size_t sz = (size_t) part->datasize - part->state.offset;
+  size_t sz = curlx_sotouz(part->datasize - part->state.offset);
   (void) size;   /* Always 1.*/
 
+  if(!nitems)
+    return STOP_FILLING;
+
   if(sz > nitems)
     sz = nitems;
 
   if(sz)
-    memcpy(buffer, (char *) &part->data[part->state.offset], sz);
+    memcpy(buffer, part->data + curlx_sotouz(part->state.offset), sz);
 
-  part->state.offset += sz;
   return sz;
 }
 
@@ -641,7 +673,7 @@
   if(offset < 0 || offset > part->datasize)
     return CURL_SEEKFUNC_FAIL;
 
-  part->state.offset = (size_t) offset;
+  part->state.offset = offset;
   return CURL_SEEKFUNC_OK;
 }
 
@@ -653,7 +685,7 @@
 
 /* Named file callbacks. */
 /* Argument is a pointer to the mime part. */
-static int mime_open_file(curl_mimepart * part)
+static int mime_open_file(curl_mimepart *part)
 {
   /* Open a MIMEKIND_FILE part. */
 
@@ -668,6 +700,9 @@
 {
   curl_mimepart *part = (curl_mimepart *) instream;
 
+  if(!nitems)
+    return STOP_FILLING;
+
   if(mime_open_file(part))
     return READ_ERROR;
 
@@ -705,21 +740,22 @@
 /* Argument is a pointer to the mime structure. */
 
 /* Readback a byte string segment. */
-static size_t readback_bytes(mime_state *state,
+static size_t readback_bytes(struct mime_state *state,
                              char *buffer, size_t bufsize,
                              const char *bytes, size_t numbytes,
                              const char *trail)
 {
   size_t sz;
+  size_t offset = curlx_sotouz(state->offset);
 
-  if(numbytes > state->offset) {
-    sz = numbytes - state->offset;
-    bytes += state->offset;
+  if(numbytes > offset) {
+    sz = numbytes - offset;
+    bytes += offset;
   }
   else {
     size_t tsz = strlen(trail);
 
-    sz = state->offset - numbytes;
+    sz = offset - numbytes;
     if(sz >= tsz)
       return 0;
     bytes = trail + sz;
@@ -736,25 +772,79 @@
 
 /* Read a non-encoded part content. */
 static size_t read_part_content(curl_mimepart *part,
-                                char *buffer, size_t bufsize)
+                                char *buffer, size_t bufsize, bool *hasread)
 {
   size_t sz = 0;
 
-  if(part->readfunc)
-    sz = part->readfunc(buffer, 1, bufsize, part->arg);
+  switch(part->lastreadstatus) {
+  case 0:
+  case CURL_READFUNC_ABORT:
+  case CURL_READFUNC_PAUSE:
+  case READ_ERROR:
+    return part->lastreadstatus;
+  default:
+    break;
+  }
+
+  /* If we can determine we are at end of part data, spare a read. */
+  if(part->datasize != (curl_off_t) -1 &&
+     part->state.offset >= part->datasize) {
+    /* sz is already zero. */
+  }
+  else {
+    switch(part->kind) {
+    case MIMEKIND_MULTIPART:
+      /*
+       * Cannot be processed as other kinds since read function requires
+       * an additional parameter and is highly recursive.
+       */
+       sz = mime_subparts_read(buffer, 1, bufsize, part->arg, hasread);
+       break;
+    case MIMEKIND_FILE:
+      if(part->fp && feof(part->fp))
+        break;  /* At EOF. */
+      /* FALLTHROUGH */
+    default:
+      if(part->readfunc) {
+        if(!(part->flags & MIME_FAST_READ)) {
+          if(*hasread)
+            return STOP_FILLING;
+          *hasread = TRUE;
+        }
+        sz = part->readfunc(buffer, 1, bufsize, part->arg);
+      }
+      break;
+    }
+  }
+
+  switch(sz) {
+  case STOP_FILLING:
+    break;
+  case 0:
+  case CURL_READFUNC_ABORT:
+  case CURL_READFUNC_PAUSE:
+  case READ_ERROR:
+    part->lastreadstatus = sz;
+    break;
+  default:
+    part->state.offset += sz;
+    part->lastreadstatus = sz;
+    break;
+  }
+
   return sz;
 }
 
 /* Read and encode part content. */
-static size_t read_encoded_part_content(curl_mimepart *part,
-                                        char *buffer, size_t bufsize)
+static size_t read_encoded_part_content(curl_mimepart *part, char *buffer,
+                                        size_t bufsize, bool *hasread)
 {
-  mime_encoder_state *st = &part->encstate;
+  struct mime_encoder_state *st = &part->encstate;
   size_t cursize = 0;
   size_t sz;
   bool ateof = FALSE;
 
-  while(bufsize) {
+  for(;;) {
     if(st->bufbeg < st->bufend || ateof) {
       /* Encode buffered data. */
       sz = part->encoder->encodefunc(buffer, bufsize, ateof, part);
@@ -763,9 +853,8 @@
         if(ateof)
           return cursize;
         break;
-      case CURL_READFUNC_ABORT:
-      case CURL_READFUNC_PAUSE:
       case READ_ERROR:
+      case STOP_FILLING:
         return cursize? cursize: sz;
       default:
         cursize += sz;
@@ -787,7 +876,7 @@
     if(st->bufend >= sizeof(st->buf))
       return cursize? cursize: READ_ERROR;    /* Buffer full. */
     sz = read_part_content(part, st->buf + st->bufend,
-                           sizeof(st->buf) - st->bufend);
+                           sizeof(st->buf) - st->bufend, hasread);
     switch(sz) {
     case 0:
       ateof = TRUE;
@@ -795,6 +884,7 @@
     case CURL_READFUNC_ABORT:
     case CURL_READFUNC_PAUSE:
     case READ_ERROR:
+    case STOP_FILLING:
       return cursize? cursize: sz;
     default:
       st->bufend += sz;
@@ -802,12 +892,12 @@
     }
   }
 
-  return cursize;
+  /* NOTREACHED */
 }
 
 /* Readback a mime part. */
 static size_t readback_part(curl_mimepart *part,
-                            char *buffer, size_t bufsize)
+                            char *buffer, size_t bufsize, bool *hasread)
 {
   size_t cursize = 0;
 #ifdef CURL_DOES_CONVERSIONS
@@ -866,9 +956,9 @@
       break;
     case MIMESTATE_CONTENT:
       if(part->encoder)
-        sz = read_encoded_part_content(part, buffer, bufsize);
+        sz = read_encoded_part_content(part, buffer, bufsize, hasread);
       else
-        sz = read_part_content(part, buffer, bufsize);
+        sz = read_part_content(part, buffer, bufsize, hasread);
       switch(sz) {
       case 0:
         mimesetstate(&part->state, MIMESTATE_END, NULL);
@@ -881,6 +971,7 @@
       case CURL_READFUNC_ABORT:
       case CURL_READFUNC_PAUSE:
       case READ_ERROR:
+      case STOP_FILLING:
         return cursize? cursize: sz;
       }
       break;
@@ -909,9 +1000,9 @@
   return cursize;
 }
 
-/* Readback from mime. */
+/* Readback from mime. Warning: not a read callback function. */
 static size_t mime_subparts_read(char *buffer, size_t size, size_t nitems,
-                                 void *instream)
+                                 void *instream, bool *hasread)
 {
   curl_mime *mime = (curl_mime *) instream;
   size_t cursize = 0;
@@ -932,7 +1023,7 @@
 #endif
       mimesetstate(&mime->state, MIMESTATE_BOUNDARY1, mime->firstpart);
       /* The first boundary always follows the header termination empty line,
-         so is always preceded by a CRLK. We can then spare 2 characters
+         so is always preceded by a CRLF. We can then spare 2 characters
          by skipping the leading CRLF in boundary. */
       mime->state.offset += 2;
       break;
@@ -962,11 +1053,12 @@
         mimesetstate(&mime->state, MIMESTATE_END, NULL);
         break;
       }
-      sz = readback_part(part, buffer, nitems);
+      sz = readback_part(part, buffer, nitems, hasread);
       switch(sz) {
       case CURL_READFUNC_ABORT:
       case CURL_READFUNC_PAUSE:
       case READ_ERROR:
+      case STOP_FILLING:
         return cursize? cursize: sz;
       case 0:
 #ifdef CURL_DOES_CONVERSIONS
@@ -1031,6 +1123,7 @@
   if(res == CURL_SEEKFUNC_OK)
     mimesetstate(&part->state, targetstate, NULL);
 
+  part->lastreadstatus = 1; /* Successful read status. */
   return res;
 }
 
@@ -1073,6 +1166,8 @@
   part->datasize = (curl_off_t) 0;    /* No size yet. */
   cleanup_encoder_state(&part->encstate);
   part->kind = MIMEKIND_NONE;
+  part->flags &= ~MIME_FAST_READ;
+  part->lastreadstatus = 1; /* Successful read status. */
 }
 
 static void mime_subparts_free(void *ptr)
@@ -1135,6 +1230,8 @@
   const curl_mimepart *s;
   CURLcode res = CURLE_OK;
 
+  DEBUGASSERT(dst);
+
   /* Duplicate content. */
   switch(src->kind) {
   case MIMEKIND_NONE:
@@ -1184,20 +1281,18 @@
     }
   }
 
-  /* Duplicate other fields. */
-  if(dst != NULL)
+  if(!res) {
+    /* Duplicate other fields. */
     dst->encoder = src->encoder;
-  else
-    res = CURLE_WRITE_ERROR;
-  if(!res)
     res = curl_mime_type(dst, src->mimetype);
+  }
   if(!res)
     res = curl_mime_name(dst, src->name);
   if(!res)
     res = curl_mime_filename(dst, src->filename);
 
   /* If an error occurred, rollback. */
-  if(res && dst)
+  if(res)
     Curl_mime_cleanpart(dst);
 
   return res;
@@ -1238,6 +1333,7 @@
 {
   memset((char *) part, 0, sizeof(*part));
   part->easy = easy;
+  part->lastreadstatus = 1; /* Successful read status. */
   mimesetstate(&part->state, MIMESTATE_BEGIN, NULL);
 }
 
@@ -1323,11 +1419,12 @@
 
     if(datasize)
       memcpy(part->data, data, datasize);
-    part->data[datasize] = '\0';    /* Set a nul terminator as sentinel. */
+    part->data[datasize] = '\0';    /* Set a null terminator as sentinel. */
 
     part->readfunc = mime_mem_read;
     part->seekfunc = mime_mem_seek;
     part->freefunc = mime_mem_free;
+    part->flags |= MIME_FAST_READ;
     part->kind = MIMEKIND_DATA;
   }
 
@@ -1405,7 +1502,7 @@
 CURLcode curl_mime_encoder(curl_mimepart *part, const char *encoding)
 {
   CURLcode result = CURLE_BAD_FUNCTION_ARGUMENT;
-  const mime_encoder *mep;
+  const struct mime_encoder *mep;
 
   if(!part)
     return result;
@@ -1502,7 +1599,7 @@
     }
 
     subparts->parent = part;
-    part->readfunc = mime_subparts_read;
+    /* Subparts are processed internally: no read callback. */
     part->seekfunc = mime_subparts_seek;
     part->freefunc = take_ownership? mime_subparts_free: mime_subparts_unbind;
     part->arg = subparts;
@@ -1524,9 +1621,23 @@
 size_t Curl_mime_read(char *buffer, size_t size, size_t nitems, void *instream)
 {
   curl_mimepart *part = (curl_mimepart *) instream;
+  size_t ret;
+  bool hasread;
 
   (void) size;   /* Always 1. */
-  return readback_part(part, buffer, nitems);
+
+  do {
+    hasread = FALSE;
+    ret = readback_part(part, buffer, nitems, &hasread);
+    /*
+     * If this is not possible to get some data without calling more than
+     * one read callback (probably because a content encoder is not able to
+     * deliver a new bunch for the few data accumulated so far), force another
+     * read until we get enough data or a special exit code.
+     */
+  } while(ret == STOP_FILLING);
+
+  return ret;
 }
 
 /* Rewind mime stream. */
@@ -1667,6 +1778,23 @@
   return NULL;
 }
 
+static bool content_type_match(const char *contenttype, const char *target)
+{
+  size_t len = strlen(target);
+
+  if(contenttype && strncasecompare(contenttype, target, len))
+    switch(contenttype[len]) {
+    case '\0':
+    case '\t':
+    case '\r':
+    case '\n':
+    case ' ':
+    case ';':
+      return TRUE;
+    }
+  return FALSE;
+}
+
 CURLcode Curl_mime_prepare_headers(curl_mimepart *part,
                                    const char *contenttype,
                                    const char *disposition,
@@ -1718,7 +1846,7 @@
       boundary = mime->boundary;
   }
   else if(contenttype && !customct &&
-          strcasecompare(contenttype, "text/plain"))
+          content_type_match(contenttype, "text/plain"))
     if(strategy == MIMESTRATEGY_MAIL || !part->filename)
       contenttype = NULL;
 
@@ -1794,7 +1922,7 @@
     curl_mimepart *subpart;
 
     disposition = NULL;
-    if(strcasecompare(contenttype, "multipart/form-data"))
+    if(content_type_match(contenttype, "multipart/form-data"))
       disposition = "form-data";
     for(subpart = mime->firstpart; subpart; subpart = subpart->nextpart) {
       ret = Curl_mime_prepare_headers(subpart, NULL, disposition, strategy);
@@ -1805,6 +1933,26 @@
   return ret;
 }
 
+/* Recursively reset paused status in the given part. */
+void Curl_mime_unpause(curl_mimepart *part)
+{
+  if(part) {
+    if(part->lastreadstatus == CURL_READFUNC_PAUSE)
+      part->lastreadstatus = 1; /* Successful read status. */
+    if(part->kind == MIMEKIND_MULTIPART) {
+      curl_mime *mime = (curl_mime *) part->arg;
+
+      if(mime) {
+        curl_mimepart *subpart;
+
+        for(subpart = mime->firstpart; subpart; subpart = subpart->nextpart)
+          Curl_mime_unpause(subpart);
+      }
+    }
+  }
+}
+
+
 #else /* !CURL_DISABLE_HTTP || !CURL_DISABLE_SMTP || !CURL_DISABLE_IMAP */
 
 /* Mime not compiled in: define stubs for externally-referenced functions. */
@@ -1901,4 +2049,11 @@
   return CURLE_NOT_BUILT_IN;
 }
 
+CURLcode Curl_mime_add_header(struct curl_slist **slp, const char *fmt, ...)
+{
+  (void)slp;
+  (void)fmt;
+  return CURLE_NOT_BUILT_IN;
+}
+
 #endif /* if disabled */
diff --git a/Utilities/cmcurl/lib/mime.h b/Utilities/cmcurl/lib/mime.h
index 4c9a5fb..50b7ea6 100644
--- a/Utilities/cmcurl/lib/mime.h
+++ b/Utilities/cmcurl/lib/mime.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -31,6 +31,7 @@
 /* Part flags. */
 #define MIME_USERHEADERS_OWNER  (1 << 0)
 #define MIME_BODY_ONLY          (1 << 1)
+#define MIME_FAST_READ          (1 << 2)
 
 #define FILE_CONTENTTYPE_DEFAULT        "application/octet-stream"
 #define MULTIPART_CONTENTTYPE_DEFAULT   "multipart/mixed"
@@ -68,43 +69,43 @@
 };
 
 /* Content transfer encoder. */
-typedef struct {
+struct mime_encoder {
   const char *   name;          /* Encoding name. */
   size_t         (*encodefunc)(char *buffer, size_t size, bool ateof,
                                curl_mimepart *part);  /* Encoded read. */
   curl_off_t     (*sizefunc)(curl_mimepart *part);  /* Encoded size. */
-}  mime_encoder;
+};
 
 /* Content transfer encoder state. */
-typedef struct {
+struct mime_encoder_state {
   size_t         pos;           /* Position on output line. */
   size_t         bufbeg;        /* Next data index in input buffer. */
   size_t         bufend;        /* First unused byte index in input buffer. */
   char           buf[ENCODING_BUFFER_SIZE]; /* Input buffer. */
-}  mime_encoder_state;
+};
 
 /* Mime readback state. */
-typedef struct {
+struct mime_state {
   enum mimestate state;       /* Current state token. */
   void *ptr;                  /* State-dependent pointer. */
-  size_t offset;              /* State-dependent offset. */
-}  mime_state;
+  curl_off_t offset;          /* State-dependent offset. */
+};
 
 /* minimum buffer size for the boundary string */
 #define MIME_BOUNDARY_LEN (24 + MIME_RAND_BOUNDARY_CHARS + 1)
 
 /* A mime multipart. */
-struct curl_mime_s {
+struct curl_mime {
   struct Curl_easy *easy;          /* The associated easy handle. */
   curl_mimepart *parent;           /* Parent part. */
   curl_mimepart *firstpart;        /* First part. */
   curl_mimepart *lastpart;         /* Last part. */
   char boundary[MIME_BOUNDARY_LEN]; /* The part boundary. */
-  mime_state state;                /* Current readback state. */
+  struct mime_state state;         /* Current readback state. */
 };
 
 /* A mime part. */
-struct curl_mimepart_s {
+struct curl_mimepart {
   struct Curl_easy *easy;          /* The associated easy handle. */
   curl_mime *parent;               /* Parent mime structure. */
   curl_mimepart *nextpart;         /* Forward linked list. */
@@ -122,30 +123,35 @@
   char *name;                      /* Data name. */
   curl_off_t datasize;             /* Expected data size. */
   unsigned int flags;              /* Flags. */
-  mime_state state;                /* Current readback state. */
-  const mime_encoder *encoder;     /* Content data encoder. */
-  mime_encoder_state encstate;     /* Data encoder state. */
+  struct mime_state state;         /* Current readback state. */
+  const struct mime_encoder *encoder; /* Content data encoder. */
+  struct mime_encoder_state encstate; /* Data encoder state. */
+  size_t lastreadstatus;           /* Last read callback returned status. */
 };
 
-#if (!defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_MIME)) || \
+CURLcode Curl_mime_add_header(struct curl_slist **slp, const char *fmt, ...);
+
+#if (!defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_MIME)) ||     \
   !defined(CURL_DISABLE_SMTP) || !defined(CURL_DISABLE_IMAP)
 
 /* Prototypes. */
-void Curl_mime_initpart(curl_mimepart *part, struct Curl_easy *easy);
-void Curl_mime_cleanpart(curl_mimepart *part);
-CURLcode Curl_mime_duppart(curl_mimepart *dst, const curl_mimepart *src);
-CURLcode Curl_mime_set_subparts(curl_mimepart *part,
-                                curl_mime *subparts, int take_ownership);
-CURLcode Curl_mime_prepare_headers(curl_mimepart *part,
+void Curl_mime_initpart(struct curl_mimepart *part, struct Curl_easy *easy);
+void Curl_mime_cleanpart(struct curl_mimepart *part);
+CURLcode Curl_mime_duppart(struct curl_mimepart *dst,
+                           const curl_mimepart *src);
+CURLcode Curl_mime_set_subparts(struct curl_mimepart *part,
+                                struct curl_mime *subparts,
+                                int take_ownership);
+CURLcode Curl_mime_prepare_headers(struct curl_mimepart *part,
                                    const char *contenttype,
                                    const char *disposition,
                                    enum mimestrategy strategy);
-curl_off_t Curl_mime_size(curl_mimepart *part);
+curl_off_t Curl_mime_size(struct curl_mimepart *part);
 size_t Curl_mime_read(char *buffer, size_t size, size_t nitems,
                       void *instream);
-CURLcode Curl_mime_rewind(curl_mimepart *part);
-CURLcode Curl_mime_add_header(struct curl_slist **slp, const char *fmt, ...);
+CURLcode Curl_mime_rewind(struct curl_mimepart *part);
 const char *Curl_mime_contenttype(const char *filename);
+void Curl_mime_unpause(struct curl_mimepart *part);
 
 #else
 /* if disabled */
@@ -157,7 +163,7 @@
 #define Curl_mime_size(x) (curl_off_t) -1
 #define Curl_mime_read NULL
 #define Curl_mime_rewind(x) ((void)x, CURLE_NOT_BUILT_IN)
-#define Curl_mime_add_header(x,y,...) CURLE_NOT_BUILT_IN
+#define Curl_mime_unpause(x)
 #endif
 
 
diff --git a/Utilities/cmcurl/lib/mprintf.c b/Utilities/cmcurl/lib/mprintf.c
index e190936..63c9d11 100644
--- a/Utilities/cmcurl/lib/mprintf.c
+++ b/Utilities/cmcurl/lib/mprintf.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1999 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1999 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -36,6 +36,7 @@
  */
 
 #include "curl_setup.h"
+#include "dynbuf.h"
 #include <curl/mprintf.h>
 
 #include "curl_memory.h"
@@ -104,7 +105,7 @@
       done++; \
     else \
      return done; /* return immediately on failure */ \
-  } WHILE_FALSE
+  } while(0)
 
 /* Data type to read from the arglist */
 typedef enum {
@@ -145,7 +146,7 @@
   FLAGS_FLOATG     = 1<<19  /* %g or %G */
 };
 
-typedef struct {
+struct va_stack {
   FormatType type;
   int flags;
   long width;     /* width OR width parameter number */
@@ -159,7 +160,7 @@
     } num;
     double dnum;
   } data;
-} va_stack_t;
+};
 
 struct nsprintf {
   char *buffer;
@@ -168,11 +169,9 @@
 };
 
 struct asprintf {
-  char *buffer; /* allocated buffer */
-  size_t len;   /* length of string */
-  size_t alloc; /* length of alloc */
-  int fail;     /* (!= 0) if an alloc has failed and thus
-                   the output is not the complete data */
+  struct dynbuf b;
+  bool fail; /* if an alloc has failed and thus the output is not the complete
+                data */
 };
 
 static long dprintf_DollarString(char *input, char **end)
@@ -224,8 +223,8 @@
  *
  ******************************************************************/
 
-static int dprintf_Pass1(const char *format, va_stack_t *vto, char **endpos,
-                         va_list arglist)
+static int dprintf_Pass1(const char *format, struct va_stack *vto,
+                         char **endpos, va_list arglist)
 {
   char *fmt = (char *)format;
   int param_num = 0;
@@ -571,13 +570,11 @@
   long param; /* current parameter to read */
   long param_num = 0; /* parameter counter */
 
-  va_stack_t vto[MAX_PARAMETERS];
+  struct va_stack vto[MAX_PARAMETERS];
   char *endpos[MAX_PARAMETERS];
   char **end;
-
   char work[BUFFSIZE];
-
-  va_stack_t *p;
+  struct va_stack *p;
 
   /* 'workend' points to the final buffer byte position, but with an extra
      byte as margin to avoid the (false?) warning Coverity gives us
@@ -1031,35 +1028,10 @@
   struct asprintf *infop = (struct asprintf *)data;
   unsigned char outc = (unsigned char)output;
 
-  if(!infop->buffer) {
-    infop->buffer = malloc(32);
-    if(!infop->buffer) {
-      infop->fail = 1;
-      return -1; /* fail */
-    }
-    infop->alloc = 32;
-    infop->len = 0;
+  if(Curl_dyn_addn(&infop->b, &outc, 1)) {
+    infop->fail = 1;
+    return -1; /* fail */
   }
-  else if(infop->len + 1 >= infop->alloc) {
-    char *newptr = NULL;
-    size_t newsize = infop->alloc*2;
-
-    /* detect wrap-around or other overflow problems */
-    if(newsize > infop->alloc)
-      newptr = realloc(infop->buffer, newsize);
-
-    if(!newptr) {
-      infop->fail = 1;
-      return -1; /* fail */
-    }
-    infop->buffer = newptr;
-    infop->alloc = newsize;
-  }
-
-  infop->buffer[ infop->len ] = outc;
-
-  infop->len++;
-
   return outc; /* fputc() returns like this on success */
 }
 
@@ -1068,24 +1040,18 @@
   va_list ap_save; /* argument pointer */
   int retcode;
   struct asprintf info;
-
-  info.buffer = NULL;
-  info.len = 0;
-  info.alloc = 0;
+  Curl_dyn_init(&info.b, DYN_APRINTF);
   info.fail = 0;
 
   va_start(ap_save, format);
   retcode = dprintf_formatf(&info, alloc_addbyter, format, ap_save);
   va_end(ap_save);
   if((-1 == retcode) || info.fail) {
-    if(info.alloc)
-      free(info.buffer);
+    Curl_dyn_free(&info.b);
     return NULL;
   }
-  if(info.alloc) {
-    info.buffer[info.len] = 0; /* we terminate this with a zero byte */
-    return info.buffer;
-  }
+  if(Curl_dyn_len(&info.b))
+    return Curl_dyn_ptr(&info.b);
   return strdup("");
 }
 
@@ -1093,23 +1059,16 @@
 {
   int retcode;
   struct asprintf info;
-
-  info.buffer = NULL;
-  info.len = 0;
-  info.alloc = 0;
+  Curl_dyn_init(&info.b, DYN_APRINTF);
   info.fail = 0;
 
   retcode = dprintf_formatf(&info, alloc_addbyter, format, ap_save);
   if((-1 == retcode) || info.fail) {
-    if(info.alloc)
-      free(info.buffer);
+    Curl_dyn_free(&info.b);
     return NULL;
   }
-
-  if(info.alloc) {
-    info.buffer[info.len] = 0; /* we terminate this with a zero byte */
-    return info.buffer;
-  }
+  if(Curl_dyn_len(&info.b))
+    return Curl_dyn_ptr(&info.b);
   return strdup("");
 }
 
diff --git a/Utilities/cmcurl/lib/mqtt.c b/Utilities/cmcurl/lib/mqtt.c
new file mode 100644
index 0000000..f6f4416
--- /dev/null
+++ b/Utilities/cmcurl/lib/mqtt.c
@@ -0,0 +1,628 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 2019, Björn Stenberg, <bjorn@haxx.se>
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#ifdef CURL_ENABLE_MQTT
+
+#include "urldata.h"
+#include <curl/curl.h>
+#include "transfer.h"
+#include "sendf.h"
+#include "progress.h"
+#include "mqtt.h"
+#include "select.h"
+#include "strdup.h"
+#include "url.h"
+#include "escape.h"
+#include "warnless.h"
+#include "curl_printf.h"
+#include "curl_memory.h"
+#include "multiif.h"
+#include "rand.h"
+
+/* The last #include file should be: */
+#include "memdebug.h"
+
+#define MQTT_MSG_CONNECT   0x10
+#define MQTT_MSG_CONNACK   0x20
+#define MQTT_MSG_PUBLISH   0x30
+#define MQTT_MSG_SUBSCRIBE 0x82
+#define MQTT_MSG_SUBACK    0x90
+#define MQTT_MSG_DISCONNECT 0xe0
+
+#define MQTT_CONNACK_LEN 2
+#define MQTT_SUBACK_LEN 3
+#define MQTT_CLIENTID_LEN 12 /* "curl0123abcd" */
+
+/*
+ * Forward declarations.
+ */
+
+static CURLcode mqtt_do(struct connectdata *conn, bool *done);
+static CURLcode mqtt_doing(struct connectdata *conn, bool *done);
+static int mqtt_getsock(struct connectdata *conn, curl_socket_t *sock);
+static CURLcode mqtt_setup_conn(struct connectdata *conn);
+
+/*
+ * MQTT protocol handler.
+ */
+
+const struct Curl_handler Curl_handler_mqtt = {
+  "MQTT",                             /* scheme */
+  mqtt_setup_conn,                    /* setup_connection */
+  mqtt_do,                            /* do_it */
+  ZERO_NULL,                          /* done */
+  ZERO_NULL,                          /* do_more */
+  ZERO_NULL,                          /* connect_it */
+  ZERO_NULL,                          /* connecting */
+  mqtt_doing,                         /* doing */
+  ZERO_NULL,                          /* proto_getsock */
+  mqtt_getsock,                       /* doing_getsock */
+  ZERO_NULL,                          /* domore_getsock */
+  ZERO_NULL,                          /* perform_getsock */
+  ZERO_NULL,                          /* disconnect */
+  ZERO_NULL,                          /* readwrite */
+  ZERO_NULL,                          /* connection_check */
+  PORT_MQTT,                          /* defport */
+  CURLPROTO_MQTT,                     /* protocol */
+  PROTOPT_NONE                        /* flags */
+};
+
+static CURLcode mqtt_setup_conn(struct connectdata *conn)
+{
+  /* allocate the HTTP-specific struct for the Curl_easy, only to survive
+     during this request */
+  struct MQTT *mq;
+  struct Curl_easy *data = conn->data;
+  DEBUGASSERT(data->req.protop == NULL);
+
+  mq = calloc(1, sizeof(struct MQTT));
+  if(!mq)
+    return CURLE_OUT_OF_MEMORY;
+  data->req.protop = mq;
+  return CURLE_OK;
+}
+
+static CURLcode mqtt_send(struct connectdata *conn,
+                          char *buf, size_t len)
+{
+  CURLcode result = CURLE_OK;
+  curl_socket_t sockfd = conn->sock[FIRSTSOCKET];
+  struct Curl_easy *data = conn->data;
+  struct MQTT *mq = data->req.protop;
+  ssize_t n;
+  result = Curl_write(conn, sockfd, buf, len, &n);
+  if(!result && data->set.verbose)
+    Curl_debug(data, CURLINFO_HEADER_OUT, buf, (size_t)n);
+  if(len != (size_t)n) {
+    size_t nsend = len - n;
+    char *sendleftovers = Curl_memdup(&buf[n], nsend);
+    if(!sendleftovers)
+      return CURLE_OUT_OF_MEMORY;
+    mq->sendleftovers = sendleftovers;
+    mq->nsend = nsend;
+  }
+  return result;
+}
+
+/* Generic function called by the multi interface to figure out what socket(s)
+   to wait for and for what actions during the DOING and PROTOCONNECT
+   states */
+static int mqtt_getsock(struct connectdata *conn,
+                        curl_socket_t *sock)
+{
+  sock[0] = conn->sock[FIRSTSOCKET];
+  return GETSOCK_READSOCK(FIRSTSOCKET);
+}
+
+static CURLcode mqtt_connect(struct connectdata *conn)
+{
+  CURLcode result = CURLE_OK;
+  const size_t client_id_offset = 14;
+  const size_t packetlen = client_id_offset + MQTT_CLIENTID_LEN;
+  char client_id[MQTT_CLIENTID_LEN + 1] = "curl";
+  const size_t curl_len = strlen("curl");
+  char packet[32] = {
+    MQTT_MSG_CONNECT,  /* packet type */
+    0x00,              /* remaining length */
+    0x00, 0x04,        /* protocol length */
+    'M','Q','T','T',   /* protocol name */
+    0x04,              /* protocol level */
+    0x02,              /* CONNECT flag: CleanSession */
+    0x00, 0x3c,        /* keep-alive 0 = disabled */
+    0x00, 0x00         /* payload1 length */
+  };
+  packet[1] = (packetlen - 2) & 0x7f;
+  packet[client_id_offset - 1] = MQTT_CLIENTID_LEN;
+
+  result = Curl_rand_hex(conn->data, (unsigned char *)&client_id[curl_len],
+                         MQTT_CLIENTID_LEN - curl_len + 1);
+  memcpy(&packet[client_id_offset], client_id, MQTT_CLIENTID_LEN);
+  infof(conn->data, "Using client id '%s'\n", client_id);
+  if(!result)
+    result = mqtt_send(conn, packet, packetlen);
+  return result;
+}
+
+static CURLcode mqtt_disconnect(struct connectdata *conn)
+{
+  CURLcode result = CURLE_OK;
+  result = mqtt_send(conn, (char *)"\xe0\x00", 2);
+  return result;
+}
+
+static CURLcode mqtt_verify_connack(struct connectdata *conn)
+{
+  CURLcode result;
+  curl_socket_t sockfd = conn->sock[FIRSTSOCKET];
+  unsigned char readbuf[MQTT_CONNACK_LEN];
+  ssize_t nread;
+  struct Curl_easy *data = conn->data;
+
+  result = Curl_read(conn, sockfd, (char *)readbuf, MQTT_CONNACK_LEN, &nread);
+  if(result)
+    goto fail;
+
+  if(data->set.verbose)
+    Curl_debug(data, CURLINFO_HEADER_IN, (char *)readbuf, (size_t)nread);
+
+  /* fixme */
+  if(nread < MQTT_CONNACK_LEN) {
+    result = CURLE_WEIRD_SERVER_REPLY;
+    goto fail;
+  }
+
+  /* verify CONNACK */
+  if(readbuf[0] != 0x00 || readbuf[1] != 0x00) {
+    failf(data, "Expected %02x%02x but got %02x%02x",
+          0x00, 0x00, readbuf[0], readbuf[1]);
+    result = CURLE_WEIRD_SERVER_REPLY;
+  }
+
+fail:
+  return result;
+}
+
+static CURLcode mqtt_get_topic(struct connectdata *conn,
+                               char **topic, size_t *topiclen)
+{
+  CURLcode result = CURLE_OK;
+  char *path = conn->data->state.up.path;
+
+  if(strlen(path) > 1) {
+    result = Curl_urldecode(conn->data, path + 1, 0, topic, topiclen,
+                            REJECT_NADA);
+  }
+  else {
+    failf(conn->data, "Error: No topic specified.");
+    result = CURLE_URL_MALFORMAT;
+  }
+  return result;
+}
+
+
+static int mqtt_encode_len(char *buf, size_t len)
+{
+  unsigned char encoded;
+  int i;
+
+  for(i = 0; (len > 0) && (i<4); i++) {
+    encoded = len % 0x80;
+    len /= 0x80;
+    if(len)
+      encoded |= 0x80;
+    buf[i] = encoded;
+  }
+
+  return i;
+}
+
+static CURLcode mqtt_subscribe(struct connectdata *conn)
+{
+  CURLcode result = CURLE_OK;
+  char *topic = NULL;
+  size_t topiclen;
+  unsigned char *packet = NULL;
+  size_t packetlen;
+  char encodedsize[4];
+  size_t n;
+
+  result = mqtt_get_topic(conn, &topic, &topiclen);
+  if(result)
+    goto fail;
+
+  conn->proto.mqtt.packetid++;
+
+  packetlen = topiclen + 5; /* packetid + topic (has a two byte length field)
+                               + 2 bytes topic length + QoS byte */
+  n = mqtt_encode_len((char *)encodedsize, packetlen);
+  packetlen += n + 1; /* add one for the control packet type byte */
+
+  packet = malloc(packetlen);
+  if(!packet) {
+    result = CURLE_OUT_OF_MEMORY;
+    goto fail;
+  }
+
+  packet[0] = MQTT_MSG_SUBSCRIBE;
+  memcpy(&packet[1], encodedsize, n);
+  packet[1 + n] = (conn->proto.mqtt.packetid >> 8) & 0xff;
+  packet[2 + n] = conn->proto.mqtt.packetid & 0xff;
+  packet[3 + n] = (topiclen >> 8) & 0xff;
+  packet[4 + n ] = topiclen & 0xff;
+  memcpy(&packet[5 + n], topic, topiclen);
+  packet[5 + n + topiclen] = 0; /* QoS zero */
+
+  result = mqtt_send(conn, (char *)packet, packetlen);
+
+fail:
+  free(topic);
+  free(packet);
+  return result;
+}
+
+/*
+ * Called when the first byte was already read.
+ */
+static CURLcode mqtt_verify_suback(struct connectdata *conn)
+{
+  CURLcode result;
+  curl_socket_t sockfd = conn->sock[FIRSTSOCKET];
+  unsigned char readbuf[MQTT_SUBACK_LEN];
+  ssize_t nread;
+  struct mqtt_conn *mqtt = &conn->proto.mqtt;
+
+  result = Curl_read(conn, sockfd, (char *)readbuf, MQTT_SUBACK_LEN, &nread);
+  if(result)
+    goto fail;
+
+  if(conn->data->set.verbose)
+    Curl_debug(conn->data, CURLINFO_HEADER_IN, (char *)readbuf, (size_t)nread);
+
+  /* fixme */
+  if(nread < MQTT_SUBACK_LEN) {
+    result = CURLE_WEIRD_SERVER_REPLY;
+    goto fail;
+  }
+
+  /* verify SUBACK */
+  if(readbuf[0] != ((mqtt->packetid >> 8) & 0xff) ||
+     readbuf[1] != (mqtt->packetid & 0xff) ||
+     readbuf[2] != 0x00)
+    result = CURLE_WEIRD_SERVER_REPLY;
+
+fail:
+  return result;
+}
+
+static CURLcode mqtt_publish(struct connectdata *conn)
+{
+  CURLcode result;
+  char *payload = conn->data->set.postfields;
+  size_t payloadlen = (size_t)conn->data->set.postfieldsize;
+  char *topic = NULL;
+  size_t topiclen;
+  unsigned char *pkt = NULL;
+  size_t i = 0;
+  size_t remaininglength;
+  size_t encodelen;
+  char encodedbytes[4];
+
+  result = mqtt_get_topic(conn, &topic, &topiclen);
+  if(result)
+    goto fail;
+
+  remaininglength = payloadlen + 2 + topiclen;
+  encodelen = mqtt_encode_len(encodedbytes, remaininglength);
+
+  /* add the control byte and the encoded remaining length */
+  pkt = malloc(remaininglength + 1 + encodelen);
+  if(!pkt) {
+    result = CURLE_OUT_OF_MEMORY;
+    goto fail;
+  }
+
+  /* assemble packet */
+  pkt[i++] = MQTT_MSG_PUBLISH;
+  memcpy(&pkt[i], encodedbytes, encodelen);
+  i += encodelen;
+  pkt[i++] = (topiclen >> 8) & 0xff;
+  pkt[i++] = (topiclen & 0xff);
+  memcpy(&pkt[i], topic, topiclen);
+  i += topiclen;
+  memcpy(&pkt[i], payload, payloadlen);
+  i += payloadlen;
+  result = mqtt_send(conn, (char *)pkt, i);
+
+fail:
+  free(pkt);
+  free(topic);
+  return result;
+}
+
+static size_t mqtt_decode_len(unsigned char *buf,
+                              size_t buflen, size_t *lenbytes)
+{
+  size_t len = 0;
+  size_t mult = 1;
+  size_t i;
+  unsigned char encoded = 128;
+
+  for(i = 0; (i < buflen) && (encoded & 128); i++) {
+    encoded = buf[i];
+    len += (encoded & 127) * mult;
+    mult *= 128;
+  }
+
+  if(lenbytes)
+    *lenbytes = i;
+
+  return len;
+}
+
+#ifdef CURLDEBUG
+static const char *statenames[]={
+  "MQTT_FIRST",
+  "MQTT_REMAINING_LENGTH",
+  "MQTT_CONNACK",
+  "MQTT_SUBACK",
+  "MQTT_SUBACK_COMING",
+  "MQTT_PUBWAIT",
+  "MQTT_PUB_REMAIN",
+
+  "NOT A STATE"
+};
+#endif
+
+/* The only way to change state */
+static void mqstate(struct connectdata *conn,
+                    enum mqttstate state,
+                    enum mqttstate nextstate) /* used if state == FIRST */
+{
+  struct mqtt_conn *mqtt = &conn->proto.mqtt;
+#ifdef CURLDEBUG
+  infof(conn->data, "%s (from %s) (next is %s)\n",
+        statenames[state],
+        statenames[mqtt->state],
+        (state == MQTT_FIRST)? statenames[nextstate] : "");
+#endif
+  mqtt->state = state;
+  if(state == MQTT_FIRST)
+    mqtt->nextstate = nextstate;
+}
+
+
+/* for the publish packet */
+#define MQTT_HEADER_LEN 5    /* max 5 bytes */
+
+static CURLcode mqtt_read_publish(struct connectdata *conn,
+                                  bool *done)
+{
+  CURLcode result = CURLE_OK;
+  curl_socket_t sockfd = conn->sock[FIRSTSOCKET];
+  ssize_t nread;
+  struct Curl_easy *data = conn->data;
+  unsigned char *pkt = (unsigned char *)data->state.buffer;
+  size_t remlen;
+  struct mqtt_conn *mqtt = &conn->proto.mqtt;
+  struct MQTT *mq = data->req.protop;
+  unsigned char packet;
+
+  switch(mqtt->state) {
+  MQTT_SUBACK_COMING:
+  case MQTT_SUBACK_COMING:
+    result = mqtt_verify_suback(conn);
+    if(result)
+      break;
+
+    mqstate(conn, MQTT_FIRST, MQTT_PUBWAIT);
+    break;
+
+  case MQTT_SUBACK:
+  case MQTT_PUBWAIT:
+    /* we are expecting PUBLISH or SUBACK */
+    packet = mq->firstbyte & 0xf0;
+    if(packet == MQTT_MSG_PUBLISH)
+      mqstate(conn, MQTT_PUB_REMAIN, MQTT_NOSTATE);
+    else if(packet == MQTT_MSG_SUBACK) {
+      mqstate(conn, MQTT_SUBACK_COMING, MQTT_NOSTATE);
+      goto MQTT_SUBACK_COMING;
+    }
+    else if(packet == MQTT_MSG_DISCONNECT) {
+      infof(data, "Got DISCONNECT\n");
+      *done = TRUE;
+      goto end;
+    }
+    else {
+      result = CURLE_WEIRD_SERVER_REPLY;
+      goto end;
+    }
+
+    /* -- switched state -- */
+    remlen = mq->remaining_length;
+    infof(data, "Remaining length: %zd bytes\n", remlen);
+    Curl_pgrsSetDownloadSize(data, remlen);
+    data->req.bytecount = 0;
+    data->req.size = remlen;
+    mq->npacket = remlen; /* get this many bytes */
+    /* FALLTHROUGH */
+  case MQTT_PUB_REMAIN: {
+    /* read rest of packet, but no more. Cap to buffer size */
+    struct SingleRequest *k = &data->req;
+    size_t rest = mq->npacket;
+    if(rest > (size_t)data->set.buffer_size)
+      rest = (size_t)data->set.buffer_size;
+    result = Curl_read(conn, sockfd, (char *)pkt, rest, &nread);
+    if(result) {
+      if(CURLE_AGAIN == result) {
+        infof(data, "EEEE AAAAGAIN\n");
+      }
+      goto end;
+    }
+    if(!nread) {
+      infof(data, "server disconnected\n");
+      result = CURLE_PARTIAL_FILE;
+      goto end;
+    }
+    if(data->set.verbose)
+      Curl_debug(data, CURLINFO_DATA_IN, (char *)pkt, (size_t)nread);
+
+    mq->npacket -= nread;
+    k->bytecount += nread;
+    Curl_pgrsSetDownloadCounter(data, k->bytecount);
+
+    /* if QoS is set, message contains packet id */
+
+    result = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)pkt, nread);
+    if(result)
+      goto end;
+
+    if(!mq->npacket)
+      /* no more PUBLISH payload, back to subscribe wait state */
+      mqstate(conn, MQTT_FIRST, MQTT_PUBWAIT);
+    break;
+  }
+  default:
+    DEBUGASSERT(NULL); /* illegal state */
+    result = CURLE_WEIRD_SERVER_REPLY;
+    goto end;
+  }
+  end:
+  return result;
+}
+
+static CURLcode mqtt_do(struct connectdata *conn, bool *done)
+{
+  CURLcode result = CURLE_OK;
+  struct Curl_easy *data = conn->data;
+
+  *done = FALSE; /* unconditionally */
+
+  result = mqtt_connect(conn);
+  if(result) {
+    failf(data, "Error %d sending MQTT CONN request", result);
+    return result;
+  }
+  mqstate(conn, MQTT_FIRST, MQTT_CONNACK);
+  return CURLE_OK;
+}
+
+static CURLcode mqtt_doing(struct connectdata *conn, bool *done)
+{
+  CURLcode result = CURLE_OK;
+  struct mqtt_conn *mqtt = &conn->proto.mqtt;
+  struct Curl_easy *data = conn->data;
+  struct MQTT *mq = data->req.protop;
+  ssize_t nread;
+  curl_socket_t sockfd = conn->sock[FIRSTSOCKET];
+  unsigned char *pkt = (unsigned char *)data->state.buffer;
+  unsigned char byte;
+
+  *done = FALSE;
+
+  if(mq->nsend) {
+    /* send the remainder of an outgoing packet */
+    char *ptr = mq->sendleftovers;
+    result = mqtt_send(conn, mq->sendleftovers, mq->nsend);
+    free(ptr);
+    if(result)
+      return result;
+  }
+
+  infof(data, "mqtt_doing: state [%d]\n", (int) mqtt->state);
+  switch(mqtt->state) {
+  case MQTT_FIRST:
+    /* Read the initial byte only */
+    result = Curl_read(conn, sockfd, (char *)&mq->firstbyte, 1, &nread);
+    if(result)
+      break;
+    if(data->set.verbose)
+      Curl_debug(data, CURLINFO_HEADER_IN, (char *)&mq->firstbyte, 1);
+    /* remember the first byte */
+    mq->npacket = 0;
+    mqstate(conn, MQTT_REMAINING_LENGTH, MQTT_NOSTATE);
+    /* FALLTHROUGH */
+  case MQTT_REMAINING_LENGTH:
+    do {
+      result = Curl_read(conn, sockfd, (char *)&byte, 1, &nread);
+      if(result)
+        break;
+      if(data->set.verbose)
+        Curl_debug(data, CURLINFO_HEADER_IN, (char *)&byte, 1);
+      pkt[mq->npacket++] = byte;
+    } while((byte & 0x80) && (mq->npacket < 4));
+    if(result)
+      break;
+    mq->remaining_length = mqtt_decode_len(&pkt[0], mq->npacket, NULL);
+    mq->npacket = 0;
+    if(mq->remaining_length) {
+      mqstate(conn, mqtt->nextstate, MQTT_NOSTATE);
+      break;
+    }
+    mqstate(conn, MQTT_FIRST, MQTT_FIRST);
+
+    if(mq->firstbyte == MQTT_MSG_DISCONNECT) {
+      infof(data, "Got DISCONNECT\n");
+      *done = TRUE;
+    }
+    break;
+  case MQTT_CONNACK:
+    result = mqtt_verify_connack(conn);
+    if(result)
+      break;
+
+    if(conn->data->state.httpreq == HTTPREQ_POST) {
+      result = mqtt_publish(conn);
+      if(!result) {
+        result = mqtt_disconnect(conn);
+        *done = TRUE;
+      }
+      mqtt->nextstate = MQTT_FIRST;
+    }
+    else {
+      result = mqtt_subscribe(conn);
+      if(!result) {
+        mqstate(conn, MQTT_FIRST, MQTT_SUBACK);
+      }
+    }
+    break;
+
+  case MQTT_SUBACK:
+  case MQTT_PUBWAIT:
+  case MQTT_PUB_REMAIN:
+    result = mqtt_read_publish(conn, done);
+    break;
+
+  default:
+    failf(conn->data, "State not handled yet");
+    *done = TRUE;
+    break;
+  }
+
+  if(result == CURLE_AGAIN)
+    result = CURLE_OK;
+  return result;
+}
+
+#endif /* CURL_ENABLE_MQTT */
diff --git a/Utilities/cmcurl/lib/mqtt.h b/Utilities/cmcurl/lib/mqtt.h
new file mode 100644
index 0000000..37463d5
--- /dev/null
+++ b/Utilities/cmcurl/lib/mqtt.h
@@ -0,0 +1,59 @@
+#ifndef HEADER_CURL_MQTT_H
+#define HEADER_CURL_MQTT_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 2019 - 2020, Björn Stenberg, <bjorn@haxx.se>
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#ifdef CURL_ENABLE_MQTT
+extern const struct Curl_handler Curl_handler_mqtt;
+#endif
+
+enum mqttstate {
+  MQTT_FIRST,             /* 0 */
+  MQTT_REMAINING_LENGTH,  /* 1 */
+  MQTT_CONNACK,           /* 2 */
+  MQTT_SUBACK,            /* 3 */
+  MQTT_SUBACK_COMING,     /* 4 - the SUBACK remainder */
+  MQTT_PUBWAIT,    /* 5 - wait for publish */
+  MQTT_PUB_REMAIN,  /* 6 - wait for the remainder of the publish */
+
+  MQTT_NOSTATE /* 7 - never used an actual state */
+};
+
+struct mqtt_conn {
+  enum mqttstate state;
+  enum mqttstate nextstate; /* switch to this after remaining length is
+                               done */
+  unsigned int packetid;
+};
+
+/* protocol-specific transfer-related data */
+struct MQTT {
+  char *sendleftovers;
+  size_t nsend; /* size of sendleftovers */
+
+  /* when receiving */
+  size_t npacket; /* byte counter */
+  unsigned char firstbyte;
+  size_t remaining_length;
+};
+
+#endif /* HEADER_CURL_MQTT_H */
diff --git a/Utilities/cmcurl/lib/multi.c b/Utilities/cmcurl/lib/multi.c
index c7c46ee..249e360 100644
--- a/Utilities/cmcurl/lib/multi.c
+++ b/Utilities/cmcurl/lib/multi.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -46,6 +46,8 @@
 #include "connect.h"
 #include "http_proxy.h"
 #include "http2.h"
+#include "socketpair.h"
+#include "socks.h"
 /* The last 3 #include files should be in this order */
 #include "curl_printf.h"
 #include "curl_memory.h"
@@ -71,15 +73,12 @@
 
 static CURLMcode singlesocket(struct Curl_multi *multi,
                               struct Curl_easy *data);
-static int update_timer(struct Curl_multi *multi);
-
 static CURLMcode add_next_timeout(struct curltime now,
                                   struct Curl_multi *multi,
                                   struct Curl_easy *d);
 static CURLMcode multi_timeout(struct Curl_multi *multi,
                                long *timeout_ms);
 static void process_pending_handles(struct Curl_multi *multi);
-static void detach_connnection(struct Curl_easy *data);
 
 #ifdef DEBUGBUILD
 static const char * const statename[]={
@@ -112,7 +111,7 @@
 
   /* Important: reset the conn pointer so that we don't point to memory
      that could be freed anytime */
-  detach_connnection(data);
+  Curl_detach_connnection(data);
   Curl_expire_clear(data); /* stop all timers */
 }
 
@@ -169,9 +168,11 @@
   }
 #endif
 
-  if(state == CURLM_STATE_COMPLETED)
+  if(state == CURLM_STATE_COMPLETED) {
     /* changing to COMPLETED means there's one less easy handle 'alive' */
+    DEBUGASSERT(data->multi->num_alive > 0);
     data->multi->num_alive--;
+  }
 
   /* if this state has an init-function, run it */
   if(finit[state])
@@ -189,7 +190,7 @@
  */
 
 struct Curl_sh_entry {
-  struct curl_llist list; /* list of easy handles using this socket */
+  struct curl_hash transfers; /* hash of transfers using this socket */
   unsigned int action;  /* what combined action READ/WRITE this socket waits
                            for */
   void *socketp; /* settable by users with curl_multi_assign() */
@@ -206,12 +207,36 @@
 static struct Curl_sh_entry *sh_getentry(struct curl_hash *sh,
                                          curl_socket_t s)
 {
-  if(s != CURL_SOCKET_BAD)
+  if(s != CURL_SOCKET_BAD) {
     /* only look for proper sockets */
     return Curl_hash_pick(sh, (char *)&s, sizeof(curl_socket_t));
+  }
   return NULL;
 }
 
+#define TRHASH_SIZE 13
+static size_t trhash(void *key, size_t key_length, size_t slots_num)
+{
+  size_t keyval = (size_t)*(struct Curl_easy **)key;
+  (void) key_length;
+
+  return (keyval % slots_num);
+}
+
+static size_t trhash_compare(void *k1, size_t k1_len, void *k2, size_t k2_len)
+{
+  (void)k1_len;
+  (void)k2_len;
+
+  return *(struct Curl_easy **)k1 == *(struct Curl_easy **)k2;
+}
+
+static void trhash_dtor(void *nada)
+{
+  (void)nada;
+}
+
+
 /* make sure this socket is present in the hash for this handle */
 static struct Curl_sh_entry *sh_addentry(struct curl_hash *sh,
                                          curl_socket_t s)
@@ -219,19 +244,25 @@
   struct Curl_sh_entry *there = sh_getentry(sh, s);
   struct Curl_sh_entry *check;
 
-  if(there)
+  if(there) {
     /* it is present, return fine */
     return there;
+  }
 
   /* not present, add it */
   check = calloc(1, sizeof(struct Curl_sh_entry));
   if(!check)
     return NULL; /* major failure */
 
-  Curl_llist_init(&check->list, NULL);
+  if(Curl_hash_init(&check->transfers, TRHASH_SIZE, trhash,
+                    trhash_compare, trhash_dtor)) {
+    free(check);
+    return NULL;
+  }
 
   /* make/add new hash entry */
   if(!Curl_hash_add(sh, (char *)&s, sizeof(curl_socket_t), check)) {
+    Curl_hash_destroy(&check->transfers);
     free(check);
     return NULL; /* major failure */
   }
@@ -241,8 +272,11 @@
 
 
 /* delete the given socket + handle from the hash */
-static void sh_delentry(struct curl_hash *sh, curl_socket_t s)
+static void sh_delentry(struct Curl_sh_entry *entry,
+                        struct curl_hash *sh, curl_socket_t s)
 {
+  Curl_hash_destroy(&entry->transfers);
+
   /* We remove the hash entry. This will end up in a call to
      sh_freeentry(). */
   Curl_hash_delete(sh, (char *)&s, sizeof(curl_socket_t));
@@ -311,17 +345,6 @@
   return CURLM_OK;
 }
 
-/*
- * multi_freeamsg()
- *
- * Callback used by the llist system when a single list entry is destroyed.
- */
-static void multi_freeamsg(void *a, void *b)
-{
-  (void)a;
-  (void)b;
-}
-
 struct Curl_multi *Curl_multi_handle(int hashsize, /* socket hash */
                                      int chashsize) /* connection hash */
 {
@@ -341,11 +364,30 @@
   if(Curl_conncache_init(&multi->conn_cache, chashsize))
     goto error;
 
-  Curl_llist_init(&multi->msglist, multi_freeamsg);
-  Curl_llist_init(&multi->pending, multi_freeamsg);
+  Curl_llist_init(&multi->msglist, NULL);
+  Curl_llist_init(&multi->pending, NULL);
+
+  multi->multiplexing = TRUE;
 
   /* -1 means it not set by user, use the default value */
   multi->maxconnects = -1;
+  multi->max_concurrent_streams = 100;
+  multi->ipv6_works = Curl_ipv6works(NULL);
+
+#ifdef ENABLE_WAKEUP
+  if(Curl_socketpair(AF_UNIX, SOCK_STREAM, 0, multi->wakeup_pair) < 0) {
+    multi->wakeup_pair[0] = CURL_SOCKET_BAD;
+    multi->wakeup_pair[1] = CURL_SOCKET_BAD;
+  }
+  else if(curlx_nonblock(multi->wakeup_pair[0], TRUE) < 0 ||
+          curlx_nonblock(multi->wakeup_pair[1], TRUE) < 0) {
+    sclose(multi->wakeup_pair[0]);
+    sclose(multi->wakeup_pair[1]);
+    multi->wakeup_pair[0] = CURL_SOCKET_BAD;
+    multi->wakeup_pair[1] = CURL_SOCKET_BAD;
+  }
+#endif
+
   return multi;
 
   error:
@@ -453,18 +495,19 @@
   /* increase the alive-counter */
   multi->num_alive++;
 
-  /* A somewhat crude work-around for a little glitch in update_timer() that
-     happens if the lastcall time is set to the same time when the handle is
-     removed as when the next handle is added, as then the check in
-     update_timer() that prevents calling the application multiple times with
-     the same timer info will not trigger and then the new handle's timeout
-     will not be notified to the app.
+  /* A somewhat crude work-around for a little glitch in Curl_update_timer()
+     that happens if the lastcall time is set to the same time when the handle
+     is removed as when the next handle is added, as then the check in
+     Curl_update_timer() that prevents calling the application multiple times
+     with the same timer info will not trigger and then the new handle's
+     timeout will not be notified to the app.
 
      The work-around is thus simply to clear the 'lastcall' variable to force
-     update_timer() to always trigger a callback to the app when a new easy
-     handle is added */
+     Curl_update_timer() to always trigger a callback to the app when a new
+     easy handle is added */
   memset(&multi->timer_lastcall, 0, sizeof(multi->timer_lastcall));
 
+  CONNCACHE_LOCK(data);
   /* The closure handle only ever has default timeouts set. To improve the
      state somewhat we clone the timeouts from each added handle so that the
      closure handle always has the same timeouts as the most recently added
@@ -474,8 +517,9 @@
     data->set.server_response_timeout;
   data->state.conn_cache->closure_handle->set.no_signal =
     data->set.no_signal;
+  CONNCACHE_UNLOCK(data);
 
-  update_timer(multi);
+  Curl_update_timer(multi);
   return CURLM_OK;
 }
 
@@ -510,6 +554,8 @@
     /* Stop if multi_done() has already been called */
     return CURLE_OK;
 
+  conn->data = data; /* ensure the connection uses this transfer now */
+
   /* Stop the resolver and free its own resources (but not dns_entry yet). */
   Curl_resolver_kill(conn);
 
@@ -546,15 +592,20 @@
 
   process_pending_handles(data->multi); /* connection / multiplex */
 
-  detach_connnection(data);
+  CONNCACHE_LOCK(data);
+  Curl_detach_connnection(data);
   if(CONN_INUSE(conn)) {
     /* Stop if still used. */
+    /* conn->data must not remain pointing to this transfer since it is going
+       away! Find another to own it! */
+    conn->data = conn->easyq.head->ptr;
+    CONNCACHE_UNLOCK(data);
     DEBUGF(infof(data, "Connection still in use %zu, "
                  "no more multi_done now!\n",
                  conn->easyq.size));
     return CURLE_OK;
   }
-
+  conn->data = NULL; /* the connection now has no owner */
   data->state.done = TRUE; /* called just now! */
 
   if(conn->dns_entry) {
@@ -567,7 +618,7 @@
   /* if the transfer was completed in a paused state there can be buffered
      data left to free */
   for(i = 0; i < data->state.tempcount; i++) {
-    free(data->state.tempwrite[i].buf);
+    Curl_dyn_free(&data->state.tempwrite[i].b);
   }
   data->state.tempcount = 0;
 
@@ -597,7 +648,11 @@
 #endif
      ) || conn->bits.close
        || (premature && !(conn->handler->flags & PROTOPT_STREAM))) {
-    CURLcode res2 = Curl_disconnect(data, conn, premature);
+    CURLcode res2;
+    connclose(conn, "disconnecting");
+    Curl_conncache_remove_conn(data, conn, FALSE);
+    CONNCACHE_UNLOCK(data);
+    res2 = Curl_disconnect(data, conn, premature);
 
     /* If we had an error already, make sure we return that one. But
        if we got a new error, return that. */
@@ -606,17 +661,21 @@
   }
   else {
     char buffer[256];
+    const char *host =
+#ifndef CURL_DISABLE_PROXY
+      conn->bits.socksproxy ?
+      conn->socks_proxy.host.dispname :
+      conn->bits.httpproxy ? conn->http_proxy.host.dispname :
+#endif
+      conn->bits.conn_to_host ? conn->conn_to_host.dispname :
+      conn->host.dispname;
     /* create string before returning the connection */
     msnprintf(buffer, sizeof(buffer),
               "Connection #%ld to host %s left intact",
-              conn->connection_id,
-              conn->bits.socksproxy ? conn->socks_proxy.host.dispname :
-              conn->bits.httpproxy ? conn->http_proxy.host.dispname :
-              conn->bits.conn_to_host ? conn->conn_to_host.dispname :
-              conn->host.dispname);
-
+              conn->connection_id, host);
     /* the connection is no longer in use by this transfer */
-    if(Curl_conncache_return_conn(conn)) {
+    CONNCACHE_UNLOCK(data);
+    if(Curl_conncache_return_conn(data, conn)) {
       /* remember the most recently used connection */
       data->state.lastconnect = conn;
       infof(data, "%s\n", buffer);
@@ -625,6 +684,7 @@
       data->state.lastconnect = NULL;
   }
 
+  Curl_safefree(data->state.buffer);
   Curl_free_request_state(data);
   return result;
 }
@@ -649,6 +709,10 @@
   if(!data->multi)
     return CURLM_OK; /* it is already removed so let's say it is fine! */
 
+  /* Prevent users from trying to remove an easy handle from the wrong multi */
+  if(data->multi != multi)
+    return CURLM_BAD_EASY_HANDLE;
+
   if(multi->in_callback)
     return CURLM_RECURSIVE_API_CALL;
 
@@ -674,19 +738,14 @@
     easy_owns_conn = TRUE;
   }
 
-  /* The timer must be shut down before data->multi is set to NULL,
-     else the timenode will remain in the splay tree after
-     curl_easy_cleanup is called. */
-  Curl_expire_clear(data);
-
   if(data->conn) {
 
     /* we must call multi_done() here (if we still own the connection) so that
        we don't leave a half-baked one around */
     if(easy_owns_conn) {
 
-      /* multi_done() clears the conn->data field to lose the association
-         between the easy handle and the connection
+      /* multi_done() clears the association between the easy handle and the
+         connection.
 
          Note that this ignores the return code simply because there's
          nothing really useful to do with it anyway! */
@@ -694,6 +753,11 @@
     }
   }
 
+  /* The timer must be shut down before data->multi is set to NULL, else the
+     timenode will remain in the splay tree after curl_easy_cleanup is
+     called. Do it after multi_done() in case that sets another time! */
+  Curl_expire_clear(data);
+
   if(data->connect_queue.ptr)
     /* the handle was in the pending list waiting for an available connection,
        so go ahead and remove it */
@@ -723,10 +787,7 @@
                                 vanish with this handle */
 
   /* Remove the association between the connection and the handle */
-  if(data->conn) {
-    data->conn->data = NULL;
-    detach_connnection(data);
-  }
+  Curl_detach_connnection(data);
 
 #ifdef USE_LIBPSL
   /* Remove the PSL association. */
@@ -765,7 +826,7 @@
      We do not touch the easy handle here! */
   multi->num_easy--; /* one less to care about now */
 
-  update_timer(multi);
+  Curl_update_timer(multi);
   return CURLM_OK;
 }
 
@@ -775,9 +836,13 @@
   return (multi && (multi->multiplexing));
 }
 
-/* This is the only function that should clear data->conn. This will
-   occasionally be called with the pointer already cleared. */
-static void detach_connnection(struct Curl_easy *data)
+/*
+ * Curl_detach_connnection() removes the given transfer from the connection.
+ *
+ * This is the only function that should clear data->conn. This will
+ * occasionally be called with the data->conn pointer already cleared.
+ */
+void Curl_detach_connnection(struct Curl_easy *data)
 {
   struct connectdata *conn = data->conn;
   if(conn)
@@ -785,7 +850,11 @@
   data->conn = NULL;
 }
 
-/* This is the only function that should assign data->conn */
+/*
+ * Curl_attach_connnection() attaches this transfer to this connection.
+ *
+ * This is the only function that should assign data->conn
+ */
 void Curl_attach_connnection(struct Curl_easy *data,
                              struct connectdata *conn)
 {
@@ -797,25 +866,32 @@
 }
 
 static int waitconnect_getsock(struct connectdata *conn,
-                               curl_socket_t *sock,
-                               int numsocks)
+                               curl_socket_t *sock)
 {
   int i;
   int s = 0;
   int rc = 0;
 
-  if(!numsocks)
-    return GETSOCK_BLANK;
-
 #ifdef USE_SSL
+#ifndef CURL_DISABLE_PROXY
   if(CONNECT_FIRSTSOCKET_PROXY_SSL())
-    return Curl_ssl_getsock(conn, sock, numsocks);
+    return Curl_ssl_getsock(conn, sock);
 #endif
+#endif
+
+  if(SOCKS_STATE(conn->cnnct.state))
+    return Curl_SOCKS_getsock(conn, sock, FIRSTSOCKET);
 
   for(i = 0; i<2; i++) {
     if(conn->tempsock[i] != CURL_SOCKET_BAD) {
       sock[s] = conn->tempsock[i];
-      rc |= GETSOCK_WRITESOCK(s++);
+      rc |= GETSOCK_WRITESOCK(s);
+#ifdef ENABLE_QUIC
+      if(conn->transport == TRNSPRT_QUIC)
+        /* when connecting QUIC, we want to read the socket too */
+        rc |= GETSOCK_READSOCK(s);
+#endif
+      s++;
     }
   }
 
@@ -823,12 +899,8 @@
 }
 
 static int waitproxyconnect_getsock(struct connectdata *conn,
-                                    curl_socket_t *sock,
-                                    int numsocks)
+                                    curl_socket_t *sock)
 {
-  if(!numsocks)
-    return GETSOCK_BLANK;
-
   sock[0] = conn->sock[FIRSTSOCKET];
 
   /* when we've sent a CONNECT to a proxy, we should rather wait for the
@@ -840,19 +912,37 @@
 }
 
 static int domore_getsock(struct connectdata *conn,
-                          curl_socket_t *socks,
-                          int numsocks)
+                          curl_socket_t *socks)
 {
   if(conn && conn->handler->domore_getsock)
-    return conn->handler->domore_getsock(conn, socks, numsocks);
+    return conn->handler->domore_getsock(conn, socks);
   return GETSOCK_BLANK;
 }
 
-/* returns bitmapped flags for this handle and its sockets */
+static int doing_getsock(struct connectdata *conn,
+                         curl_socket_t *socks)
+{
+  if(conn && conn->handler->doing_getsock)
+    return conn->handler->doing_getsock(conn, socks);
+  return GETSOCK_BLANK;
+}
+
+static int protocol_getsock(struct connectdata *conn,
+                            curl_socket_t *socks)
+{
+  if(conn->handler->proto_getsock)
+    return conn->handler->proto_getsock(conn, socks);
+  /* Backup getsock logic. Since there is a live socket in use, we must wait
+     for it or it will be removed from watching when the multi_socket API is
+     used. */
+  socks[0] = conn->sock[FIRSTSOCKET];
+  return GETSOCK_READSOCK(0) | GETSOCK_WRITESOCK(0);
+}
+
+/* returns bitmapped flags for this handle and its sockets. The 'socks[]'
+   array contains MAX_SOCKSPEREASYHANDLE entries. */
 static int multi_getsock(struct Curl_easy *data,
-                         curl_socket_t *socks, /* points to numsocks number
-                                                  of sockets */
-                         int numsocks)
+                         curl_socket_t *socks)
 {
   /* The no connection case can happen when this is called from
      curl_multi_remove_handle() => singlesocket() => multi_getsock().
@@ -884,30 +974,30 @@
     return 0;
 
   case CURLM_STATE_WAITRESOLVE:
-    return Curl_resolv_getsock(data->conn, socks, numsocks);
+    return Curl_resolv_getsock(data->conn, socks);
 
   case CURLM_STATE_PROTOCONNECT:
   case CURLM_STATE_SENDPROTOCONNECT:
-    return Curl_protocol_getsock(data->conn, socks, numsocks);
+    return protocol_getsock(data->conn, socks);
 
   case CURLM_STATE_DO:
   case CURLM_STATE_DOING:
-    return Curl_doing_getsock(data->conn, socks, numsocks);
+    return doing_getsock(data->conn, socks);
 
   case CURLM_STATE_WAITPROXYCONNECT:
-    return waitproxyconnect_getsock(data->conn, socks, numsocks);
+    return waitproxyconnect_getsock(data->conn, socks);
 
   case CURLM_STATE_WAITCONNECT:
-    return waitconnect_getsock(data->conn, socks, numsocks);
+    return waitconnect_getsock(data->conn, socks);
 
   case CURLM_STATE_DO_MORE:
-    return domore_getsock(data->conn, socks, numsocks);
+    return domore_getsock(data->conn, socks);
 
   case CURLM_STATE_DO_DONE: /* since is set after DO is completed, we switch
                                to waiting for the same as the *PERFORM
                                states */
   case CURLM_STATE_PERFORM:
-    return Curl_single_getsock(data->conn, socks, numsocks);
+    return Curl_single_getsock(data->conn, socks);
   }
 
 }
@@ -933,7 +1023,7 @@
 
   data = multi->easyp;
   while(data) {
-    int bitmap = multi_getsock(data, sockbunch, MAX_SOCKSPEREASYHANDLE);
+    int bitmap = multi_getsock(data, sockbunch);
 
     for(i = 0; i< MAX_SOCKSPEREASYHANDLE; i++) {
       curl_socket_t s = CURL_SOCKET_BAD;
@@ -963,12 +1053,13 @@
 
 #define NUM_POLLS_ON_STACK 10
 
-CURLMcode Curl_multi_wait(struct Curl_multi *multi,
-                          struct curl_waitfd extra_fds[],
-                          unsigned int extra_nfds,
-                          int timeout_ms,
-                          int *ret,
-                          bool *gotsocket) /* if any socket was checked */
+static CURLMcode Curl_multi_wait(struct Curl_multi *multi,
+                                 struct curl_waitfd extra_fds[],
+                                 unsigned int extra_nfds,
+                                 int timeout_ms,
+                                 int *ret,
+                                 bool extrawait, /* when no socket, wait */
+                                 bool use_wakeup)
 {
   struct Curl_easy *data;
   curl_socket_t sockbunch[MAX_SOCKSPEREASYHANDLE];
@@ -982,19 +1073,19 @@
   struct pollfd a_few_on_stack[NUM_POLLS_ON_STACK];
   struct pollfd *ufds = &a_few_on_stack[0];
 
-  if(gotsocket)
-    *gotsocket = FALSE;
-
   if(!GOOD_MULTI_HANDLE(multi))
     return CURLM_BAD_HANDLE;
 
   if(multi->in_callback)
     return CURLM_RECURSIVE_API_CALL;
 
+  if(timeout_ms < 0)
+    return CURLM_BAD_FUNCTION_ARGUMENT;
+
   /* Count up how many fds we have from the multi handle */
   data = multi->easyp;
   while(data) {
-    bitmap = multi_getsock(data, sockbunch, MAX_SOCKSPEREASYHANDLE);
+    bitmap = multi_getsock(data, sockbunch);
 
     for(i = 0; i< MAX_SOCKSPEREASYHANDLE; i++) {
       curl_socket_t s = CURL_SOCKET_BAD;
@@ -1025,6 +1116,12 @@
   curlfds = nfds; /* number of internal file descriptors */
   nfds += extra_nfds; /* add the externally provided ones */
 
+#ifdef ENABLE_WAKEUP
+  if(use_wakeup && multi->wakeup_pair[0] != CURL_SOCKET_BAD) {
+    ++nfds;
+  }
+#endif
+
   if(nfds > NUM_POLLS_ON_STACK) {
     /* 'nfds' is a 32 bit value and 'struct pollfd' is typically 8 bytes
        big, so at 2^29 sockets this value might wrap. When a process gets
@@ -1044,7 +1141,7 @@
     /* Add the curl handles to our pollfds first */
     data = multi->easyp;
     while(data) {
-      bitmap = multi_getsock(data, sockbunch, MAX_SOCKSPEREASYHANDLE);
+      bitmap = multi_getsock(data, sockbunch);
 
       for(i = 0; i< MAX_SOCKSPEREASYHANDLE; i++) {
         curl_socket_t s = CURL_SOCKET_BAD;
@@ -1083,6 +1180,14 @@
     ++nfds;
   }
 
+#ifdef ENABLE_WAKEUP
+  if(use_wakeup && multi->wakeup_pair[0] != CURL_SOCKET_BAD) {
+    ufds[nfds].fd = multi->wakeup_pair[0];
+    ufds[nfds].events = POLLIN;
+    ++nfds;
+  }
+#endif
+
   if(nfds) {
     int pollrc;
     /* wait... */
@@ -1106,6 +1211,31 @@
 
         extra_fds[i].revents = mask;
       }
+
+#ifdef ENABLE_WAKEUP
+      if(use_wakeup && multi->wakeup_pair[0] != CURL_SOCKET_BAD) {
+        if(ufds[curlfds + extra_nfds].revents & POLLIN) {
+          char buf[64];
+          ssize_t nread;
+          while(1) {
+            /* the reading socket is non-blocking, try to read
+               data from it until it receives an error (except EINTR).
+               In normal cases it will get EAGAIN or EWOULDBLOCK
+               when there is no more data, breaking the loop. */
+            nread = sread(multi->wakeup_pair[0], buf, sizeof(buf));
+            if(nread <= 0) {
+#ifndef USE_WINSOCK
+              if(nread < 0 && EINTR == SOCKERRNO)
+                continue;
+#endif
+              break;
+            }
+          }
+          /* do not count the wakeup socket into the returned value */
+          retcode--;
+        }
+      }
+#endif
     }
   }
 
@@ -1113,9 +1243,23 @@
     free(ufds);
   if(ret)
     *ret = retcode;
-  if(gotsocket && (extra_fds || curlfds))
+  if(!extrawait || nfds)
     /* if any socket was checked */
-    *gotsocket = TRUE;
+    ;
+  else {
+    long sleep_ms = 0;
+
+    /* Avoid busy-looping when there's nothing particular to wait for */
+    if(!curl_multi_timeout(multi, &sleep_ms) && sleep_ms) {
+      if(sleep_ms > timeout_ms)
+        sleep_ms = timeout_ms;
+      /* when there are no easy handles in the multi, this holds a -1
+         timeout */
+      else if((sleep_ms < 0) && extrawait)
+        sleep_ms = timeout_ms;
+      Curl_wait_ms(sleep_ms);
+    }
+  }
 
   return CURLM_OK;
 }
@@ -1126,7 +1270,65 @@
                           int timeout_ms,
                           int *ret)
 {
-  return Curl_multi_wait(multi, extra_fds, extra_nfds, timeout_ms, ret, NULL);
+  return Curl_multi_wait(multi, extra_fds, extra_nfds, timeout_ms, ret, FALSE,
+                         FALSE);
+}
+
+CURLMcode curl_multi_poll(struct Curl_multi *multi,
+                          struct curl_waitfd extra_fds[],
+                          unsigned int extra_nfds,
+                          int timeout_ms,
+                          int *ret)
+{
+  return Curl_multi_wait(multi, extra_fds, extra_nfds, timeout_ms, ret, TRUE,
+                         TRUE);
+}
+
+CURLMcode curl_multi_wakeup(struct Curl_multi *multi)
+{
+  /* this function is usually called from another thread,
+     it has to be careful only to access parts of the
+     Curl_multi struct that are constant */
+
+  /* GOOD_MULTI_HANDLE can be safely called */
+  if(!GOOD_MULTI_HANDLE(multi))
+    return CURLM_BAD_HANDLE;
+
+#ifdef ENABLE_WAKEUP
+  /* the wakeup_pair variable is only written during init and cleanup,
+     making it safe to access from another thread after the init part
+     and before cleanup */
+  if(multi->wakeup_pair[1] != CURL_SOCKET_BAD) {
+    char buf[1];
+    buf[0] = 1;
+    while(1) {
+      /* swrite() is not thread-safe in general, because concurrent calls
+         can have their messages interleaved, but in this case the content
+         of the messages does not matter, which makes it ok to call.
+
+         The write socket is set to non-blocking, this way this function
+         cannot block, making it safe to call even from the same thread
+         that will call Curl_multi_wait(). If swrite() returns that it
+         would block, it's considered successful because it means that
+         previous calls to this function will wake up the poll(). */
+      if(swrite(multi->wakeup_pair[1], buf, sizeof(buf)) < 0) {
+        int err = SOCKERRNO;
+        int return_success;
+#ifdef USE_WINSOCK
+        return_success = WSAEWOULDBLOCK == err;
+#else
+        if(EINTR == err)
+          continue;
+        return_success = EWOULDBLOCK == err || EAGAIN == err;
+#endif
+        if(!return_success)
+          return CURLM_WAKEUP_FAILURE;
+      }
+      return CURLM_OK;
+    }
+  }
+#endif
+  return CURLM_WAKEUP_FAILURE;
 }
 
 /*
@@ -1189,6 +1391,7 @@
 
   DEBUGASSERT(conn);
   DEBUGASSERT(conn->handler);
+  DEBUGASSERT(conn->data == data);
 
   if(conn->handler->do_it) {
     /* generic protocol-specific function pointer set in curl_connect() */
@@ -1226,6 +1429,124 @@
   return result;
 }
 
+/*
+ * We are doing protocol-specific connecting and this is being called over and
+ * over from the multi interface until the connection phase is done on
+ * protocol layer.
+ */
+
+static CURLcode protocol_connecting(struct connectdata *conn,
+                                    bool *done)
+{
+  CURLcode result = CURLE_OK;
+
+  if(conn && conn->handler->connecting) {
+    *done = FALSE;
+    result = conn->handler->connecting(conn, done);
+  }
+  else
+    *done = TRUE;
+
+  return result;
+}
+
+/*
+ * We are DOING this is being called over and over from the multi interface
+ * until the DOING phase is done on protocol layer.
+ */
+
+static CURLcode protocol_doing(struct connectdata *conn, bool *done)
+{
+  CURLcode result = CURLE_OK;
+
+  if(conn && conn->handler->doing) {
+    *done = FALSE;
+    result = conn->handler->doing(conn, done);
+  }
+  else
+    *done = TRUE;
+
+  return result;
+}
+
+/*
+ * We have discovered that the TCP connection has been successful, we can now
+ * proceed with some action.
+ *
+ */
+static CURLcode protocol_connect(struct connectdata *conn,
+                                 bool *protocol_done)
+{
+  CURLcode result = CURLE_OK;
+
+  DEBUGASSERT(conn);
+  DEBUGASSERT(protocol_done);
+
+  *protocol_done = FALSE;
+
+  if(conn->bits.tcpconnect[FIRSTSOCKET] && conn->bits.protoconnstart) {
+    /* We already are connected, get back. This may happen when the connect
+       worked fine in the first call, like when we connect to a local server
+       or proxy. Note that we don't know if the protocol is actually done.
+
+       Unless this protocol doesn't have any protocol-connect callback, as
+       then we know we're done. */
+    if(!conn->handler->connecting)
+      *protocol_done = TRUE;
+
+    return CURLE_OK;
+  }
+
+  if(!conn->bits.protoconnstart) {
+#ifndef CURL_DISABLE_PROXY
+    result = Curl_proxy_connect(conn, FIRSTSOCKET);
+    if(result)
+      return result;
+
+    if(CONNECT_FIRSTSOCKET_PROXY_SSL())
+      /* wait for HTTPS proxy SSL initialization to complete */
+      return CURLE_OK;
+
+    if(conn->bits.tunnel_proxy && conn->bits.httpproxy &&
+       Curl_connect_ongoing(conn))
+      /* when using an HTTP tunnel proxy, await complete tunnel establishment
+         before proceeding further. Return CURLE_OK so we'll be called again */
+      return CURLE_OK;
+#endif
+    if(conn->handler->connect_it) {
+      /* is there a protocol-specific connect() procedure? */
+
+      /* Call the protocol-specific connect function */
+      result = conn->handler->connect_it(conn, protocol_done);
+    }
+    else
+      *protocol_done = TRUE;
+
+    /* it has started, possibly even completed but that knowledge isn't stored
+       in this bit! */
+    if(!result)
+      conn->bits.protoconnstart = TRUE;
+  }
+
+  return result; /* pass back status */
+}
+
+/*
+ * Curl_preconnect() is called immediately before a connect starts. When a
+ * redirect is followed, this is then called multiple times during a single
+ * transfer.
+ */
+CURLcode Curl_preconnect(struct Curl_easy *data)
+{
+  if(!data->state.buffer) {
+    data->state.buffer = malloc(data->set.buffer_size + 1);
+    if(!data->state.buffer)
+      return CURLE_OUT_OF_MEMORY;
+  }
+  return CURLE_OK;
+}
+
+
 static CURLMcode multi_runsingle(struct Curl_multi *multi,
                                  struct curltime now,
                                  struct Curl_easy *data)
@@ -1233,7 +1554,7 @@
   struct Curl_message *msg = NULL;
   bool connected;
   bool async;
-  bool protocol_connect = FALSE;
+  bool protocol_connected = FALSE;
   bool dophase_done = FALSE;
   bool done = FALSE;
   CURLMcode rc;
@@ -1252,16 +1573,6 @@
     bool stream_error = FALSE;
     rc = CURLM_OK;
 
-    if(!data->conn &&
-       data->mstate > CURLM_STATE_CONNECT &&
-       data->mstate < CURLM_STATE_DONE) {
-      /* In all these states, the code will blindly access 'data->conn'
-         so this is precaution that it isn't NULL. And it silences static
-         analyzers. */
-      failf(data, "In state %d with no conn, bail out!\n", data->mstate);
-      return CURLM_INTERNAL_ERROR;
-    }
-
     if(multi_ischanged(multi, TRUE)) {
       DEBUGF(infof(data, "multi changed, check CONNECT_PEND queue!\n"));
       process_pending_handles(multi); /* multiplexed */
@@ -1342,6 +1653,11 @@
 
     case CURLM_STATE_CONNECT:
       /* Connect. We want to get a connection identifier filled in. */
+      /* init this transfer. */
+      result = Curl_preconnect(data);
+      if(result)
+        break;
+
       Curl_pgrsTime(data, TIMER_STARTSINGLE);
       if(data->set.timeout)
         Curl_expire(data, data->set.timeout, EXPIRE_TIMEOUT);
@@ -1349,7 +1665,7 @@
       if(data->set.connecttimeout)
         Curl_expire(data, data->set.connecttimeout, EXPIRE_CONNECTTIMEOUT);
 
-      result = Curl_connect(data, &async, &protocol_connect);
+      result = Curl_connect(data, &async, &protocol_connected);
       if(CURLE_NO_CONNECTION_AVAILABLE == result) {
         /* There was no connection available. We will go to the pending
            state and wait for an available connection. */
@@ -1377,7 +1693,7 @@
              WAITDO or DO! */
           rc = CURLM_CALL_MULTI_PERFORM;
 
-          if(protocol_connect)
+          if(protocol_connected)
             multistate(data, CURLM_STATE_DO);
           else {
 #ifndef CURL_DISABLE_HTTP
@@ -1399,9 +1715,12 @@
       const char *hostname;
 
       DEBUGASSERT(conn);
+#ifndef CURL_DISABLE_PROXY
       if(conn->bits.httpproxy)
         hostname = conn->http_proxy.host.name;
-      else if(conn->bits.conn_to_host)
+      else
+#endif
+        if(conn->bits.conn_to_host)
         hostname = conn->conn_to_host.name;
       else
         hostname = conn->host.name;
@@ -1432,7 +1751,7 @@
       if(dns) {
         /* Perform the next step in the connection phase, and then move on
            to the WAITCONNECT state */
-        result = Curl_once_resolved(data->conn, &protocol_connect);
+        result = Curl_once_resolved(data->conn, &protocol_connected);
 
         if(result)
           /* if Curl_once_resolved() returns failure, the connection struct
@@ -1441,7 +1760,7 @@
         else {
           /* call again please so that we get the next socket setup */
           rc = CURLM_CALL_MULTI_PERFORM;
-          if(protocol_connect)
+          if(protocol_connected)
             multistate(data, CURLM_STATE_DO);
           else {
 #ifndef CURL_DISABLE_HTTP
@@ -1466,8 +1785,8 @@
     case CURLM_STATE_WAITPROXYCONNECT:
       /* this is HTTP-specific, but sending CONNECT to a proxy is HTTP... */
       DEBUGASSERT(data->conn);
-      result = Curl_http_connect(data->conn, &protocol_connect);
-
+      result = Curl_http_connect(data->conn, &protocol_connected);
+#ifndef CURL_DISABLE_PROXY
       if(data->conn->bits.proxy_connect_closed) {
         rc = CURLM_CALL_MULTI_PERFORM;
         /* connect back to proxy again */
@@ -1475,15 +1794,20 @@
         multi_done(data, CURLE_OK, FALSE);
         multistate(data, CURLM_STATE_CONNECT);
       }
-      else if(!result) {
-        if((data->conn->http_proxy.proxytype != CURLPROXY_HTTPS ||
-           data->conn->bits.proxy_ssl_connected[FIRSTSOCKET]) &&
-           Curl_connect_complete(data->conn)) {
-          rc = CURLM_CALL_MULTI_PERFORM;
-          /* initiate protocol connect phase */
-          multistate(data, CURLM_STATE_SENDPROTOCONNECT);
+      else
+#endif
+        if(!result) {
+          if(
+#ifndef CURL_DISABLE_PROXY
+            (data->conn->http_proxy.proxytype != CURLPROXY_HTTPS ||
+             data->conn->bits.proxy_ssl_connected[FIRSTSOCKET]) &&
+#endif
+            Curl_connect_complete(data->conn)) {
+            rc = CURLM_CALL_MULTI_PERFORM;
+            /* initiate protocol connect phase */
+            multistate(data, CURLM_STATE_SENDPROTOCONNECT);
+          }
         }
-      }
       else if(result)
         stream_error = TRUE;
       break;
@@ -1495,17 +1819,25 @@
       result = Curl_is_connected(data->conn, FIRSTSOCKET, &connected);
       if(connected && !result) {
 #ifndef CURL_DISABLE_HTTP
-        if((data->conn->http_proxy.proxytype == CURLPROXY_HTTPS &&
-            !data->conn->bits.proxy_ssl_connected[FIRSTSOCKET]) ||
-           Curl_connect_ongoing(data->conn)) {
+        if(
+#ifndef CURL_DISABLE_PROXY
+          (data->conn->http_proxy.proxytype == CURLPROXY_HTTPS &&
+           !data->conn->bits.proxy_ssl_connected[FIRSTSOCKET]) ||
+#endif
+          Curl_connect_ongoing(data->conn)) {
           multistate(data, CURLM_STATE_WAITPROXYCONNECT);
           break;
         }
 #endif
         rc = CURLM_CALL_MULTI_PERFORM;
-        multistate(data, data->conn->bits.tunnel_proxy?
+#ifndef CURL_DISABLE_PROXY
+        multistate(data,
+                   data->conn->bits.tunnel_proxy?
                    CURLM_STATE_WAITPROXYCONNECT:
                    CURLM_STATE_SENDPROTOCONNECT);
+#else
+        multistate(data, CURLM_STATE_SENDPROTOCONNECT);
+#endif
       }
       else if(result) {
         /* failure detected */
@@ -1517,8 +1849,8 @@
       break;
 
     case CURLM_STATE_SENDPROTOCONNECT:
-      result = Curl_protocol_connect(data->conn, &protocol_connect);
-      if(!result && !protocol_connect)
+      result = protocol_connect(data->conn, &protocol_connected);
+      if(!result && !protocol_connected)
         /* switch to waiting state */
         multistate(data, CURLM_STATE_PROTOCONNECT);
       else if(!result) {
@@ -1536,8 +1868,8 @@
 
     case CURLM_STATE_PROTOCONNECT:
       /* protocol-specific connect phase */
-      result = Curl_protocol_connecting(data->conn, &protocol_connect);
-      if(!result && protocol_connect) {
+      result = protocol_connecting(data->conn, &protocol_connected);
+      if(!result && protocol_connected) {
         /* after the connect has completed, go WAITDO or DO */
         multistate(data, CURLM_STATE_DO);
         rc = CURLM_CALL_MULTI_PERFORM;
@@ -1659,8 +1991,7 @@
     case CURLM_STATE_DOING:
       /* we continue DOING until the DO phase is complete */
       DEBUGASSERT(data->conn);
-      result = Curl_protocol_doing(data->conn,
-                                   &dophase_done);
+      result = protocol_doing(data->conn, &dophase_done);
       if(!result) {
         if(dophase_done) {
           /* after DO, go DO_DONE or DO_MORE */
@@ -1772,7 +2103,7 @@
       char *newurl = NULL;
       bool retry = FALSE;
       bool comeback = FALSE;
-
+      DEBUGASSERT(data->state.buffer);
       /* check if over send speed */
       send_timeout_ms = 0;
       if(data->set.max_send_speed > 0)
@@ -1911,8 +2242,13 @@
           }
         }
       }
-      else if(comeback)
-        rc = CURLM_CALL_MULTI_PERFORM;
+      else if(comeback) {
+        /* This avoids CURLM_CALL_MULTI_PERFORM so that a very fast transfer
+           won't get stuck on this transfer at the expense of other concurrent
+           transfers */
+        Curl_expire(data, 0, EXPIRE_RUN_NOW);
+        rc = CURLM_OK;
+      }
       break;
     }
 
@@ -1940,8 +2276,7 @@
          * access free'd data, if the connection is free'd and the handle
          * removed before we perform the processing in CURLM_STATE_COMPLETED
          */
-        if(data->conn)
-          detach_connnection(data);
+        Curl_detach_connnection(data);
       }
 
 #ifndef CURL_DISABLE_FTP
@@ -1988,13 +2323,18 @@
           if(stream_error) {
             /* Don't attempt to send data over a connection that timed out */
             bool dead_connection = result == CURLE_OPERATION_TIMEDOUT;
-            /* disconnect properly */
-            Curl_disconnect(data, data->conn, dead_connection);
+            struct connectdata *conn = data->conn;
 
             /* This is where we make sure that the conn pointer is reset.
                We don't have to do this in every case block above where a
                failure is detected */
-            detach_connnection(data);
+            Curl_detach_connnection(data);
+
+            /* remove connection from cache */
+            Curl_conncache_remove_conn(data, conn, TRUE);
+
+            /* disconnect properly */
+            Curl_disconnect(data, conn, dead_connection);
           }
         }
         else if(data->mstate == CURLM_STATE_CONNECT) {
@@ -2093,7 +2433,7 @@
   *running_handles = multi->num_alive;
 
   if(CURLM_OK >= returncode)
-    update_timer(multi);
+    Curl_update_timer(multi);
 
   return returncode;
 }
@@ -2145,6 +2485,11 @@
 
     Curl_hash_destroy(&multi->hostcache);
     Curl_psl_destroy(&multi->psl);
+
+#ifdef ENABLE_WAKEUP
+    sclose(multi->wakeup_pair[0]);
+    sclose(multi->wakeup_pair[1]);
+#endif
     free(multi);
 
     return CURLM_OK;
@@ -2210,7 +2555,7 @@
 
   /* Fill in the 'current' struct with the state as it is now: what sockets to
      supervise and for what actions */
-  curraction = multi_getsock(data, socks, MAX_SOCKSPEREASYHANDLE);
+  curraction = multi_getsock(data, socks);
 
   /* We have 0 .. N sockets already and we get to know about the 0 .. M
      sockets we should have from now on. Detect the differences, remove no
@@ -2238,14 +2583,14 @@
     actions[i] = action;
     if(entry) {
       /* check if new for this transfer */
-      for(i = 0; i< data->numsocks; i++) {
-        if(s == data->sockets[i]) {
-          prevaction = data->actions[i];
+      int j;
+      for(j = 0; j< data->numsocks; j++) {
+        if(s == data->sockets[j]) {
+          prevaction = data->actions[j];
           sincebefore = TRUE;
           break;
         }
       }
-
     }
     else {
       /* this is a socket we didn't have before, add it to the hash! */
@@ -2273,29 +2618,22 @@
       if(action & CURL_POLL_OUT)
         entry->writers++;
 
-      /* add 'data' to the list of handles using this socket! */
-      Curl_llist_insert_next(&entry->list, entry->list.tail,
-                             data, &data->sh_queue);
+      /* add 'data' to the transfer hash on this socket! */
+      if(!Curl_hash_add(&entry->transfers, (char *)&data, /* hash key */
+                        sizeof(struct Curl_easy *), data))
+        return CURLM_OUT_OF_MEMORY;
     }
 
     comboaction = (entry->writers? CURL_POLL_OUT : 0) |
       (entry->readers ? CURL_POLL_IN : 0);
 
-#if 0
-    infof(data, "--- Comboaction: %u readers %u writers\n",
-          entry->readers, entry->writers);
-#endif
-    /* check if it has the same action set */
-    if(entry->action == comboaction)
+    /* socket existed before and has the same action set as before */
+    if(sincebefore && (entry->action == comboaction))
       /* same, continue */
       continue;
 
-    /* we know (entry != NULL) at this point, see the logic above */
     if(multi->socket_cb)
-      multi->socket_cb(data,
-                       s,
-                       comboaction,
-                       multi->socket_userp,
+      multi->socket_cb(data, s, comboaction, multi->socket_userp,
                        entry->socketp);
 
     entry->action = comboaction; /* store the current action state */
@@ -2335,11 +2673,14 @@
           multi->socket_cb(data, s, CURL_POLL_REMOVE,
                            multi->socket_userp,
                            entry->socketp);
-        sh_delentry(&multi->sockhash, s);
+        sh_delentry(entry, &multi->sockhash, s);
       }
       else {
-        /* remove this transfer as a user of this socket */
-        Curl_llist_remove(&entry->list, &data->sh_queue, NULL);
+        /* still users, but remove this handle as a user of this socket */
+        if(Curl_hash_delete(&entry->transfers, (char *)&data,
+                            sizeof(struct Curl_easy *))) {
+          DEBUGASSERT(NULL);
+        }
       }
     }
   } /* for loop over numsocks */
@@ -2383,7 +2724,7 @@
                            entry->socketp);
 
         /* now remove it from the socket hash */
-        sh_delentry(&multi->sockhash, s);
+        sh_delentry(entry, &multi->sockhash, s);
       }
     }
   }
@@ -2474,7 +2815,6 @@
     return result;
   }
   if(s != CURL_SOCKET_TIMEOUT) {
-
     struct Curl_sh_entry *entry = sh_getentry(&multi->sockhash, s);
 
     if(!entry)
@@ -2485,37 +2825,22 @@
          and just move on. */
       ;
     else {
-      struct curl_llist *list = &entry->list;
-      struct curl_llist_element *e;
-      SIGPIPE_VARIABLE(pipe_st);
+      struct curl_hash_iterator iter;
+      struct curl_hash_element *he;
 
       /* the socket can be shared by many transfers, iterate */
-      for(e = list->head; e; e = e->next) {
-        data = (struct Curl_easy *)e->ptr;
-
-        if(data->magic != CURLEASY_MAGIC_NUMBER)
-          /* bad bad bad bad bad bad bad */
-          return CURLM_INTERNAL_ERROR;
+      Curl_hash_start_iterate(&entry->transfers, &iter);
+      for(he = Curl_hash_next_element(&iter); he;
+          he = Curl_hash_next_element(&iter)) {
+        data = (struct Curl_easy *)he->ptr;
+        DEBUGASSERT(data);
+        DEBUGASSERT(data->magic == CURLEASY_MAGIC_NUMBER);
 
         if(data->conn && !(data->conn->handler->flags & PROTOPT_DIRLOCK))
           /* set socket event bitmask if they're not locked */
           data->conn->cselect_bits = ev_bitmask;
 
-        sigpipe_ignore(data, &pipe_st);
-        result = multi_runsingle(multi, now, data);
-        sigpipe_restore(&pipe_st);
-
-        if(data->conn && !(data->conn->handler->flags & PROTOPT_DIRLOCK))
-          /* clear the bitmask only if not locked */
-          data->conn->cselect_bits = 0;
-
-        if(CURLM_OK >= result) {
-          /* get the socket(s) and check if the state has been changed since
-             last */
-          result = singlesocket(multi, data);
-          if(result)
-            return result;
-        }
+        Curl_expire(data, 0, EXPIRE_RUN_NOW);
       }
 
       /* Now we fall-through and do the timer-based stuff, since we don't want
@@ -2530,9 +2855,10 @@
   }
   else {
     /* Asked to run due to time-out. Clear the 'lastcall' variable to force
-       update_timer() to trigger a callback to the app again even if the same
-       timeout is still the one to run after this call. That handles the case
-       when the application asks libcurl to run the timeout prematurely. */
+       Curl_update_timer() to trigger a callback to the app again even if the
+       same timeout is still the one to run after this call. That handles the
+       case when the application asks libcurl to run the timeout
+       prematurely. */
     memset(&multi->timer_lastcall, 0, sizeof(multi->timer_lastcall));
   }
 
@@ -2631,6 +2957,16 @@
     break;
   case CURLMOPT_PIPELINING_SERVER_BL:
     break;
+  case CURLMOPT_MAX_CONCURRENT_STREAMS:
+    {
+      long streams = va_arg(param, long);
+      if(streams < 1)
+        streams = 100;
+      multi->max_concurrent_streams =
+        (streams > (long)INITIAL_MAX_CONCURRENT_STREAMS)?
+        INITIAL_MAX_CONCURRENT_STREAMS : (unsigned int)streams;
+    }
+    break;
   default:
     res = CURLM_UNKNOWN_OPTION;
     break;
@@ -2650,7 +2986,7 @@
     return CURLM_RECURSIVE_API_CALL;
   result = multi_socket(multi, FALSE, s, 0, running_handles);
   if(CURLM_OK >= result)
-    update_timer(multi);
+    Curl_update_timer(multi);
   return result;
 }
 
@@ -2662,7 +2998,7 @@
     return CURLM_RECURSIVE_API_CALL;
   result = multi_socket(multi, FALSE, s, ev_bitmask, running_handles);
   if(CURLM_OK >= result)
-    update_timer(multi);
+    Curl_update_timer(multi);
   return result;
 }
 
@@ -2674,7 +3010,7 @@
     return CURLM_RECURSIVE_API_CALL;
   result = multi_socket(multi, TRUE, CURL_SOCKET_BAD, 0, running_handles);
   if(CURLM_OK >= result)
-    update_timer(multi);
+    Curl_update_timer(multi);
   return result;
 }
 
@@ -2734,14 +3070,14 @@
  * Tell the application it should update its timers, if it subscribes to the
  * update timer callback.
  */
-static int update_timer(struct Curl_multi *multi)
+void Curl_update_timer(struct Curl_multi *multi)
 {
   long timeout_ms;
 
   if(!multi->timer_cb)
-    return 0;
+    return;
   if(multi_timeout(multi, &timeout_ms)) {
-    return -1;
+    return;
   }
   if(timeout_ms < 0) {
     static const struct curltime none = {0, 0};
@@ -2749,9 +3085,10 @@
       multi->timer_lastcall = none;
       /* there's no timeout now but there was one previously, tell the app to
          disable it */
-      return multi->timer_cb(multi, -1, multi->timer_userp);
+      multi->timer_cb(multi, -1, multi->timer_userp);
+      return;
     }
-    return 0;
+    return;
   }
 
   /* When multi_timeout() is done, multi->timetree points to the node with the
@@ -2759,11 +3096,11 @@
    * if this is the same (fixed) time as we got in a previous call and then
    * avoid calling the callback again. */
   if(Curl_splaycomparekeys(multi->timetree->key, multi->timer_lastcall) == 0)
-    return 0;
+    return;
 
   multi->timer_lastcall = multi->timetree->key;
 
-  return multi->timer_cb(multi, timeout_ms, multi->timer_userp);
+  multi->timer_cb(multi, timeout_ms, multi->timer_userp);
 }
 
 /*
@@ -2840,7 +3177,7 @@
  *
  * Expire replaces a former timeout using the same id if already set.
  */
-void Curl_expire(struct Curl_easy *data, time_t milli, expire_id id)
+void Curl_expire(struct Curl_easy *data, timediff_t milli, expire_id id)
 {
   struct Curl_multi *multi = data->multi;
   struct curltime *nowp = &data->state.expiretime;
@@ -2854,7 +3191,7 @@
   DEBUGASSERT(id < EXPIRE_LAST);
 
   set = Curl_now();
-  set.tv_sec += milli/1000;
+  set.tv_sec += (time_t)(milli/1000); /* might be a 64 to 32 bit conversion */
   set.tv_usec += (unsigned int)(milli%1000)*1000;
 
   if(set.tv_usec >= 1000000) {
@@ -3068,3 +3405,9 @@
   }
 }
 #endif
+
+unsigned int Curl_multi_max_concurrent_streams(struct Curl_multi *multi)
+{
+  DEBUGASSERT(multi);
+  return multi->max_concurrent_streams;
+}
diff --git a/Utilities/cmcurl/lib/multihandle.h b/Utilities/cmcurl/lib/multihandle.h
index 279379a..91eca16 100644
--- a/Utilities/cmcurl/lib/multihandle.h
+++ b/Utilities/cmcurl/lib/multihandle.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -24,6 +24,7 @@
 
 #include "conncache.h"
 #include "psl.h"
+#include "socketpair.h"
 
 struct Curl_message {
   struct curl_llist_element list;
@@ -66,6 +67,14 @@
 
 #define CURLPIPE_ANY (CURLPIPE_MULTIPLEX)
 
+#if defined(USE_SOCKETPAIR) && !defined(USE_BLOCKING_SOCKETS)
+#define ENABLE_WAKEUP
+#endif
+
+
+/* value for MAXIMUM CONCURRENT STREAMS upper limit */
+#define INITIAL_MAX_CONCURRENT_STREAMS ((1U << 31) - 1)
+
 /* This is the struct known as CURLM on the outside */
 struct Curl_multi {
   /* First a simple identifier to easier detect if a user mix up
@@ -110,11 +119,6 @@
      same actual socket) */
   struct curl_hash sockhash;
 
-  /* multiplexing wanted */
-  bool multiplexing;
-
-  bool recheckstate; /* see Curl_multi_connchanged */
-
   /* Shared connection cache (bundles)*/
   struct conncache conn_cache;
 
@@ -132,7 +136,17 @@
   void *timer_userp;
   struct curltime timer_lastcall; /* the fixed time for the timeout for the
                                     previous callback */
+  unsigned int max_concurrent_streams;
+
+#ifdef ENABLE_WAKEUP
+  curl_socket_t wakeup_pair[2]; /* socketpair() used for wakeup
+                                   0 is used for read, 1 is used for write */
+#endif
+  /* multiplexing wanted */
+  bool multiplexing;
+  bool recheckstate; /* see Curl_multi_connchanged */
   bool in_callback;            /* true while executing a callback */
+  bool ipv6_works;
 };
 
 #endif /* HEADER_CURL_MULTIHANDLE_H */
diff --git a/Utilities/cmcurl/lib/multiif.h b/Utilities/cmcurl/lib/multiif.h
index e8a5e70..7d574df 100644
--- a/Utilities/cmcurl/lib/multiif.h
+++ b/Utilities/cmcurl/lib/multiif.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -27,15 +27,17 @@
  */
 
 void Curl_updatesocket(struct Curl_easy *data);
-void Curl_expire(struct Curl_easy *data, time_t milli, expire_id);
+void Curl_expire(struct Curl_easy *data, timediff_t milli, expire_id);
 void Curl_expire_clear(struct Curl_easy *data);
 void Curl_expire_done(struct Curl_easy *data, expire_id id);
-void Curl_detach_connnection(struct Curl_easy *data);
+void Curl_update_timer(struct Curl_multi *multi);
 void Curl_attach_connnection(struct Curl_easy *data,
                              struct connectdata *conn);
+void Curl_detach_connnection(struct Curl_easy *data);
 bool Curl_multiplex_wanted(const struct Curl_multi *multi);
 void Curl_set_in_callback(struct Curl_easy *data, bool value);
 bool Curl_is_in_callback(struct Curl_easy *easy);
+CURLcode Curl_preconnect(struct Curl_easy *data);
 
 /* Internal version of curl_multi_init() accepts size parameters for the
    socket and connection hashes */
@@ -89,11 +91,8 @@
                                  struct Curl_easy *data,
                                  struct connectdata *conn);
 
-CURLMcode Curl_multi_wait(struct Curl_multi *multi,
-                          struct curl_waitfd extra_fds[],
-                          unsigned int extra_nfds,
-                          int timeout_ms,
-                          int *ret,
-                          bool *gotsocket); /* if any socket was checked */
+
+/* Return the value of the CURLMOPT_MAX_CONCURRENT_STREAMS option */
+unsigned int Curl_multi_max_concurrent_streams(struct Curl_multi *multi);
 
 #endif /* HEADER_CURL_MULTIIF_H */
diff --git a/Utilities/cmcurl/lib/netrc.c b/Utilities/cmcurl/lib/netrc.c
index 1bd998f..1c9da31 100644
--- a/Utilities/cmcurl/lib/netrc.c
+++ b/Utilities/cmcurl/lib/netrc.c
@@ -45,27 +45,27 @@
   HOSTVALID     /* this is "our" machine! */
 };
 
+#define NETRC_FILE_MISSING 1
+#define NETRC_FAILED -1
+#define NETRC_SUCCESS 0
+
 /*
- * @unittest: 1304
- *
- * *loginp and *passwordp MUST be allocated if they aren't NULL when passed
- * in.
+ * Returns zero on success.
  */
-int Curl_parsenetrc(const char *host,
-                    char **loginp,
-                    char **passwordp,
-                    bool *login_changed,
-                    bool *password_changed,
-                    char *netrcfile)
+static int parsenetrc(const char *host,
+                      char **loginp,
+                      char **passwordp,
+                      bool *login_changed,
+                      bool *password_changed,
+                      char *netrcfile)
 {
   FILE *file;
-  int retcode = 1;
+  int retcode = NETRC_FILE_MISSING;
   char *login = *loginp;
   char *password = *passwordp;
   bool specific_login = (login && *login != 0);
   bool login_alloc = FALSE;
   bool password_alloc = FALSE;
-  bool netrc_alloc = FALSE;
   enum host_lookup_state state = NOTHING;
 
   char state_login = 0;      /* Found a login keyword */
@@ -73,51 +73,9 @@
   int state_our_login = FALSE;  /* With specific_login, found *our* login
                                    name */
 
-#define NETRC DOT_CHAR "netrc"
-
-  if(!netrcfile) {
-    bool home_alloc = FALSE;
-    char *home = curl_getenv("HOME"); /* portable environment reader */
-    if(home) {
-      home_alloc = TRUE;
-#if defined(HAVE_GETPWUID_R) && defined(HAVE_GETEUID)
-    }
-    else {
-      struct passwd pw, *pw_res;
-      char pwbuf[1024];
-      if(!getpwuid_r(geteuid(), &pw, pwbuf, sizeof(pwbuf), &pw_res)
-         && pw_res) {
-        home = strdup(pw.pw_dir);
-        if(!home)
-          return CURLE_OUT_OF_MEMORY;
-        home_alloc = TRUE;
-      }
-#elif defined(HAVE_GETPWUID) && defined(HAVE_GETEUID)
-    }
-    else {
-      struct passwd *pw;
-      pw = getpwuid(geteuid());
-      if(pw) {
-        home = pw->pw_dir;
-      }
-#endif
-    }
-
-    if(!home)
-      return retcode; /* no home directory found (or possibly out of memory) */
-
-    netrcfile = curl_maprintf("%s%s%s", home, DIR_CHAR, NETRC);
-    if(home_alloc)
-      free(home);
-    if(!netrcfile) {
-      return -1;
-    }
-    netrc_alloc = TRUE;
-  }
+  DEBUGASSERT(netrcfile);
 
   file = fopen(netrcfile, FOPEN_READTEXT);
-  if(netrc_alloc)
-    free(netrcfile);
   if(file) {
     char *tok;
     char *tok_buf;
@@ -130,7 +88,7 @@
       if(tok && *tok == '#')
         /* treat an initial hash as a comment line */
         continue;
-      while(!done && tok) {
+      while(tok) {
 
         if((login && *login) && (password && *password)) {
           done = TRUE;
@@ -148,14 +106,14 @@
           }
           else if(strcasecompare("default", tok)) {
             state = HOSTVALID;
-            retcode = 0; /* we did find our host */
+            retcode = NETRC_SUCCESS; /* we did find our host */
           }
           break;
         case HOSTFOUND:
           if(strcasecompare(host, tok)) {
             /* and yes, this is our host! */
             state = HOSTVALID;
-            retcode = 0; /* we did find our host */
+            retcode = NETRC_SUCCESS; /* we did find our host */
           }
           else
             /* not our host */
@@ -174,7 +132,7 @@
               }
               login = strdup(tok);
               if(!login) {
-                retcode = -1; /* allocation failed */
+                retcode = NETRC_FAILED; /* allocation failed */
                 goto out;
               }
               login_alloc = TRUE;
@@ -190,7 +148,7 @@
               }
               password = strdup(tok);
               if(!password) {
-                retcode = -1; /* allocation failed */
+                retcode = NETRC_FAILED; /* allocation failed */
                 goto out;
               }
               password_alloc = TRUE;
@@ -215,6 +173,7 @@
 
     out:
     if(!retcode) {
+      /* success */
       *login_changed = FALSE;
       *password_changed = FALSE;
       if(login_alloc) {
@@ -242,4 +201,78 @@
   return retcode;
 }
 
+/*
+ * @unittest: 1304
+ *
+ * *loginp and *passwordp MUST be allocated if they aren't NULL when passed
+ * in.
+ */
+int Curl_parsenetrc(const char *host,
+                    char **loginp,
+                    char **passwordp,
+                    bool *login_changed,
+                    bool *password_changed,
+                    char *netrcfile)
+{
+  int retcode = 1;
+  char *filealloc = NULL;
+
+  if(!netrcfile) {
+    char *home = NULL;
+    char *homea = curl_getenv("HOME"); /* portable environment reader */
+    if(homea) {
+      home = homea;
+#if defined(HAVE_GETPWUID_R) && defined(HAVE_GETEUID)
+    }
+    else {
+      struct passwd pw, *pw_res;
+      char pwbuf[1024];
+      if(!getpwuid_r(geteuid(), &pw, pwbuf, sizeof(pwbuf), &pw_res)
+         && pw_res) {
+        home = pw.pw_dir;
+      }
+#elif defined(HAVE_GETPWUID) && defined(HAVE_GETEUID)
+    }
+    else {
+      struct passwd *pw;
+      pw = getpwuid(geteuid());
+      if(pw) {
+        home = pw->pw_dir;
+      }
+#endif
+    }
+
+    if(!home)
+      return retcode; /* no home directory found (or possibly out of
+                         memory) */
+
+    filealloc = curl_maprintf("%s%s.netrc", home, DIR_CHAR);
+    if(!filealloc) {
+      free(homea);
+      return -1;
+    }
+    retcode = parsenetrc(host, loginp, passwordp, login_changed,
+                         password_changed, filealloc);
+    free(filealloc);
+#ifdef WIN32
+    if(retcode == NETRC_FILE_MISSING) {
+      /* fallback to the old-style "_netrc" file */
+      filealloc = curl_maprintf("%s%s_netrc", home, DIR_CHAR);
+      if(!filealloc) {
+        free(homea);
+        return -1;
+      }
+      retcode = parsenetrc(host, loginp, passwordp, login_changed,
+                           password_changed, filealloc);
+      free(filealloc);
+    }
+#endif
+    free(homea);
+  }
+  else
+    retcode = parsenetrc(host, loginp, passwordp, login_changed,
+                         password_changed, netrcfile);
+  return retcode;
+}
+
 #endif
diff --git a/Utilities/cmcurl/lib/non-ascii.c b/Utilities/cmcurl/lib/non-ascii.c
index 42beaec..a48e67d 100644
--- a/Utilities/cmcurl/lib/non-ascii.c
+++ b/Utilities/cmcurl/lib/non-ascii.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
diff --git a/Utilities/cmcurl/lib/nonblock.c b/Utilities/cmcurl/lib/nonblock.c
index 4d105c1..abeb659 100644
--- a/Utilities/cmcurl/lib/nonblock.c
+++ b/Utilities/cmcurl/lib/nonblock.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
diff --git a/Utilities/cmcurl/lib/nonblock.h b/Utilities/cmcurl/lib/nonblock.h
index eb18ea1..d50d315 100644
--- a/Utilities/cmcurl/lib/nonblock.h
+++ b/Utilities/cmcurl/lib/nonblock.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2009, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
diff --git a/Utilities/cmcurl/lib/nwlib.c b/Utilities/cmcurl/lib/nwlib.c
index 7bf5f51..beec0b3 100644
--- a/Utilities/cmcurl/lib/nwlib.c
+++ b/Utilities/cmcurl/lib/nwlib.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -36,21 +36,19 @@
 /* The last #include file should be: */
 #include "memdebug.h"
 
-typedef struct
-{
+struct libthreaddata {
   int     _errno;
   void    *twentybytes;
-} libthreaddata_t;
+};
 
-typedef struct
-{
+struct libdata {
   int         x;
   int         y;
   int         z;
   void        *tenbytes;
   NXKey_t     perthreadkey;   /* if -1, no key obtained... */
   NXMutex_t   *lock;
-} libdata_t;
+};
 
 int         gLibId      = -1;
 void        *gLibHandle = (void *) NULL;
@@ -60,7 +58,8 @@
 /* internal library function prototypes... */
 int  DisposeLibraryData(void *);
 void DisposeThreadData(void *);
-int  GetOrSetUpData(int id, libdata_t **data, libthreaddata_t **threaddata);
+int  GetOrSetUpData(int id, struct libdata **data,
+                    struct libthreaddata **threaddata);
 
 
 int _NonAppStart(void        *NLMHandle,
@@ -154,24 +153,24 @@
     return 0;
 }
 
-int GetOrSetUpData(int id, libdata_t **appData,
-                   libthreaddata_t **threadData)
+int GetOrSetUpData(int id, struct libdata **appData,
+                   struct libthreaddata **threadData)
 {
   int                 err;
-  libdata_t           *app_data;
-  libthreaddata_t *thread_data;
+  struct libdata      *app_data;
+  struct libthreaddata *thread_data;
   NXKey_t             key;
   NX_LOCK_INFO_ALLOC(liblock, "Application Data Lock", 0);
 
   err         = 0;
-  thread_data = (libthreaddata_t *) NULL;
+  thread_data = (struct libthreaddata_t *) NULL;
 
   /*
    * Attempt to get our data for the application calling us. This is where we
    * store whatever application-specific information we need to carry in
    * support of calling applications.
    */
-  app_data = (libdata_t *) get_app_data(id);
+  app_data = (struct libdata *) get_app_data(id);
 
   if(!app_data) {
     /*
@@ -184,9 +183,9 @@
      */
     NXLock(gLibLock);
 
-    app_data = (libdata_t *) get_app_data(id);
+    app_data = (struct libdata *) get_app_data(id);
     if(!app_data) {
-      app_data = calloc(1, sizeof(libdata_t));
+      app_data = calloc(1, sizeof(struct libdata));
 
       if(app_data) {
         app_data->tenbytes = malloc(10);
@@ -249,7 +248,7 @@
        * a pointer is not very important, this just helps to demonstrate that
        * we can have arbitrarily complex per-thread data.
        */
-      thread_data = malloc(sizeof(libthreaddata_t));
+      thread_data = malloc(sizeof(struct libthreaddata));
 
       if(thread_data) {
         thread_data->_errno      = 0;
@@ -257,7 +256,7 @@
 
         if(!thread_data->twentybytes) {
           free(thread_data);
-          thread_data = (libthreaddata_t *) NULL;
+          thread_data = (struct libthreaddata *) NULL;
           err         = ENOMEM;
         }
 
@@ -265,7 +264,7 @@
         if(err) {
           free(thread_data->twentybytes);
           free(thread_data);
-          thread_data = (libthreaddata_t *) NULL;
+          thread_data = (struct libthreaddata *) NULL;
         }
       }
     }
@@ -295,7 +294,7 @@
 void DisposeThreadData(void *data)
 {
   if(data) {
-    void *twentybytes = ((libthreaddata_t *) data)->twentybytes;
+    void *twentybytes = ((struct libthreaddata *) data)->twentybytes;
 
     free(twentybytes);
     free(data);
diff --git a/Utilities/cmcurl/lib/openldap.c b/Utilities/cmcurl/lib/openldap.c
index eeab2c7..782d6a0 100644
--- a/Utilities/cmcurl/lib/openldap.c
+++ b/Utilities/cmcurl/lib/openldap.c
@@ -6,7 +6,7 @@
  *                 \___|\___/|_| \_\_____|
  *
  * Copyright (C) 2010, Howard Chu, <hyc@openldap.org>
- * Copyright (C) 2011 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 2011 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -151,7 +151,7 @@
   "bad or missing extensions"
 };
 
-typedef struct ldapconninfo {
+struct ldapconninfo {
   LDAP *ld;
   Curl_recv *recv;  /* for stacking SSL handler */
   Curl_send *send;
@@ -160,16 +160,16 @@
   bool ssldone;
   bool sslinst;
   bool didbind;
-} ldapconninfo;
+};
 
-typedef struct ldapreqinfo {
+struct ldapreqinfo {
   int msgid;
   int nument;
-} ldapreqinfo;
+};
 
 static CURLcode ldap_setup_connection(struct connectdata *conn)
 {
-  ldapconninfo *li;
+  struct ldapconninfo *li;
   LDAPURLDesc *lud;
   struct Curl_easy *data = conn->data;
   int rc, proto;
@@ -190,11 +190,11 @@
   proto = ldap_pvt_url_scheme2proto(lud->lud_scheme);
   ldap_free_urldesc(lud);
 
-  li = calloc(1, sizeof(ldapconninfo));
+  li = calloc(1, sizeof(struct ldapconninfo));
   if(!li)
     return CURLE_OUT_OF_MEMORY;
   li->proto = proto;
-  conn->proto.generic = li;
+  conn->proto.ldapc = li;
   connkeep(conn, "OpenLDAP default");
   return CURLE_OK;
 }
@@ -205,7 +205,7 @@
 
 static CURLcode ldap_connect(struct connectdata *conn, bool *done)
 {
-  ldapconninfo *li = conn->proto.generic;
+  struct ldapconninfo *li = conn->proto.ldapc;
   struct Curl_easy *data = conn->data;
   int rc, proto = LDAP_VERSION3;
   char hosturl[1024];
@@ -252,7 +252,7 @@
 
 static CURLcode ldap_connecting(struct connectdata *conn, bool *done)
 {
-  ldapconninfo *li = conn->proto.generic;
+  struct ldapconninfo *li = conn->proto.ldapc;
   struct Curl_easy *data = conn->data;
   LDAPMessage *msg = NULL;
   struct timeval tv = {0, 1}, *tvp;
@@ -357,7 +357,7 @@
 
 static CURLcode ldap_disconnect(struct connectdata *conn, bool dead_connection)
 {
-  ldapconninfo *li = conn->proto.generic;
+  struct ldapconninfo *li = conn->proto.ldapc;
   (void) dead_connection;
 
   if(li) {
@@ -365,7 +365,7 @@
       ldap_unbind_ext(li->ld, NULL, NULL);
       li->ld = NULL;
     }
-    conn->proto.generic = NULL;
+    conn->proto.ldapc = NULL;
     free(li);
   }
   return CURLE_OK;
@@ -373,8 +373,8 @@
 
 static CURLcode ldap_do(struct connectdata *conn, bool *done)
 {
-  ldapconninfo *li = conn->proto.generic;
-  ldapreqinfo *lr;
+  struct ldapconninfo *li = conn->proto.ldapc;
+  struct ldapreqinfo *lr;
   CURLcode status = CURLE_OK;
   int rc = 0;
   LDAPURLDesc *ludp = NULL;
@@ -406,7 +406,7 @@
     failf(data, "LDAP local: ldap_search_ext %s", ldap_err2string(rc));
     return CURLE_LDAP_SEARCH_FAILED;
   }
-  lr = calloc(1, sizeof(ldapreqinfo));
+  lr = calloc(1, sizeof(struct ldapreqinfo));
   if(!lr)
     return CURLE_OUT_OF_MEMORY;
   lr->msgid = msgid;
@@ -419,7 +419,7 @@
 static CURLcode ldap_done(struct connectdata *conn, CURLcode res,
                           bool premature)
 {
-  ldapreqinfo *lr = conn->data->req.protop;
+  struct ldapreqinfo *lr = conn->data->req.protop;
 
   (void)res;
   (void)premature;
@@ -427,7 +427,7 @@
   if(lr) {
     /* if there was a search in progress, abandon it */
     if(lr->msgid) {
-      ldapconninfo *li = conn->proto.generic;
+      struct ldapconninfo *li = conn->proto.ldapc;
       ldap_abandon_ext(li->ld, lr->msgid, NULL, NULL);
       lr->msgid = 0;
     }
@@ -441,9 +441,9 @@
 static ssize_t ldap_recv(struct connectdata *conn, int sockindex, char *buf,
                          size_t len, CURLcode *err)
 {
-  ldapconninfo *li = conn->proto.generic;
+  struct ldapconninfo *li = conn->proto.ldapc;
   struct Curl_easy *data = conn->data;
-  ldapreqinfo *lr = data->req.protop;
+  struct ldapreqinfo *lr = data->req.protop;
   int rc, ret;
   LDAPMessage *msg = NULL;
   LDAPMessage *ent;
@@ -718,7 +718,7 @@
 ldapsb_tls_read(Sockbuf_IO_Desc *sbiod, void *buf, ber_len_t len)
 {
   struct connectdata *conn = sbiod->sbiod_pvt;
-  ldapconninfo *li = conn->proto.generic;
+  struct ldapconninfo *li = conn->proto.ldapc;
   ber_slen_t ret;
   CURLcode err = CURLE_RECV_ERROR;
 
@@ -733,7 +733,7 @@
 ldapsb_tls_write(Sockbuf_IO_Desc *sbiod, void *buf, ber_len_t len)
 {
   struct connectdata *conn = sbiod->sbiod_pvt;
-  ldapconninfo *li = conn->proto.generic;
+  struct ldapconninfo *li = conn->proto.ldapc;
   ber_slen_t ret;
   CURLcode err = CURLE_SEND_ERROR;
 
diff --git a/Utilities/cmcurl/lib/parsedate.c b/Utilities/cmcurl/lib/parsedate.c
index 7ae5eb8..585d7ea 100644
--- a/Utilities/cmcurl/lib/parsedate.c
+++ b/Utilities/cmcurl/lib/parsedate.c
@@ -100,16 +100,20 @@
 #define PARSEDATE_LATER  1
 #define PARSEDATE_SOONER 2
 
-#ifndef CURL_DISABLE_PARSEDATE
-
+#if !defined(CURL_DISABLE_PARSEDATE) || !defined(CURL_DISABLE_FTP) || \
+  !defined(CURL_DISABLE_FILE)
+/* These names are also used by FTP and FILE code */
 const char * const Curl_wkday[] =
 {"Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"};
-static const char * const weekday[] =
-{ "Monday", "Tuesday", "Wednesday", "Thursday",
-  "Friday", "Saturday", "Sunday" };
 const char * const Curl_month[]=
 { "Jan", "Feb", "Mar", "Apr", "May", "Jun",
   "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
+#endif
+
+#ifndef CURL_DISABLE_PARSEDATE
+static const char * const weekday[] =
+{ "Monday", "Tuesday", "Wednesday", "Thursday",
+  "Friday", "Saturday", "Sunday" };
 
 struct tzinfo {
   char name[5];
@@ -583,6 +587,30 @@
   return -1;
 }
 
+/* Curl_getdate_capped() differs from curl_getdate() in that this will return
+   TIME_T_MAX in case the parsed time value was too big, instead of an
+   error. */
+
+time_t Curl_getdate_capped(const char *p)
+{
+  time_t parsed = -1;
+  int rc = parsedate(p, &parsed);
+
+  switch(rc) {
+  case PARSEDATE_OK:
+    if(parsed == -1)
+      /* avoid returning -1 for a working scenario */
+      parsed++;
+    return parsed;
+  case PARSEDATE_LATER:
+    /* this returns the maximum time value */
+    return parsed;
+  default:
+    return -1; /* everything else is fail */
+  }
+  /* UNREACHABLE */
+}
+
 /*
  * Curl_gmtime() is a gmtime() replacement for portability. Do not use the
  * gmtime_r() or gmtime() functions anywhere else but here.
diff --git a/Utilities/cmcurl/lib/parsedate.h b/Utilities/cmcurl/lib/parsedate.h
index 8dc3b90..8c7ae94 100644
--- a/Utilities/cmcurl/lib/parsedate.h
+++ b/Utilities/cmcurl/lib/parsedate.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -27,4 +27,10 @@
 
 CURLcode Curl_gmtime(time_t intime, struct tm *store);
 
+/* Curl_getdate_capped() differs from curl_getdate() in that this will return
+   TIME_T_MAX in case the parsed time value was too big, instead of an
+   error. */
+
+time_t Curl_getdate_capped(const char *p);
+
 #endif /* HEADER_CURL_PARSEDATE_H */
diff --git a/Utilities/cmcurl/lib/pingpong.c b/Utilities/cmcurl/lib/pingpong.c
index e9568ee..3143315 100644
--- a/Utilities/cmcurl/lib/pingpong.c
+++ b/Utilities/cmcurl/lib/pingpong.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -44,12 +44,12 @@
 
 /* Returns timeout in ms. 0 or negative number means the timeout has already
    triggered */
-time_t Curl_pp_state_timeout(struct pingpong *pp, bool disconnecting)
+timediff_t Curl_pp_state_timeout(struct pingpong *pp, bool disconnecting)
 {
   struct connectdata *conn = pp->conn;
   struct Curl_easy *data = conn->data;
-  time_t timeout_ms; /* in milliseconds */
-  long response_time = (data->set.server_response_timeout)?
+  timediff_t timeout_ms; /* in milliseconds */
+  timediff_t response_time = (data->set.server_response_timeout)?
     data->set.server_response_timeout: pp->response_time;
 
   /* if CURLOPT_SERVER_RESPONSE_TIMEOUT is set, use that to determine
@@ -64,7 +64,7 @@
 
   if(data->set.timeout && !disconnecting) {
     /* if timeout is requested, find out how much remaining time we have */
-    time_t timeout2_ms = data->set.timeout - /* timeout time */
+    timediff_t timeout2_ms = data->set.timeout - /* timeout time */
       Curl_timediff(Curl_now(), conn->now); /* spent time */
 
     /* pick the lowest number */
@@ -83,8 +83,8 @@
   struct connectdata *conn = pp->conn;
   curl_socket_t sock = conn->sock[FIRSTSOCKET];
   int rc;
-  time_t interval_ms;
-  time_t timeout_ms = Curl_pp_state_timeout(pp, disconnecting);
+  timediff_t interval_ms;
+  timediff_t timeout_ms = Curl_pp_state_timeout(pp, disconnecting);
   struct Curl_easy *data = conn->data;
   CURLcode result = CURLE_OK;
 
@@ -384,10 +384,10 @@
 
           if(pp->endofresp(conn, pp->linestart_resp, perline, code)) {
             /* This is the end of the last line, copy the last line to the
-               start of the buffer and zero terminate, for old times sake */
+               start of the buffer and null-terminate, for old times sake */
             size_t n = ptr - pp->linestart_resp;
             memmove(buf, pp->linestart_resp, n);
-            buf[n] = 0; /* zero terminate */
+            buf[n] = 0; /* null-terminate */
             keepon = FALSE;
             pp->linestart_resp = ptr + 1; /* advance pointer */
             i++; /* skip this before getting out */
@@ -463,14 +463,9 @@
 }
 
 int Curl_pp_getsock(struct pingpong *pp,
-                    curl_socket_t *socks,
-                    int numsocks)
+                    curl_socket_t *socks)
 {
   struct connectdata *conn = pp->conn;
-
-  if(!numsocks)
-    return GETSOCK_BLANK;
-
   socks[0] = conn->sock[FIRSTSOCKET];
 
   if(pp->sendleft) {
diff --git a/Utilities/cmcurl/lib/pingpong.h b/Utilities/cmcurl/lib/pingpong.h
index dbe1f8d..e874799 100644
--- a/Utilities/cmcurl/lib/pingpong.h
+++ b/Utilities/cmcurl/lib/pingpong.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -60,9 +60,8 @@
   size_t sendsize; /* total size of the sendthis buffer */
   struct curltime response; /* set to Curl_now() when a command has been sent
                                off, used to time-out response reading */
-  long response_time; /* When no timeout is given, this is the amount of
-                         milliseconds we await for a server response. */
-
+  timediff_t response_time; /* When no timeout is given, this is the amount of
+                               milliseconds we await for a server response. */
   struct connectdata *conn; /* points to the connectdata struct that this
                                belongs to */
 
@@ -89,7 +88,7 @@
 
 /* Returns timeout in ms. 0 or negative number means the timeout has already
    triggered */
-time_t Curl_pp_state_timeout(struct pingpong *pp, bool disconnecting);
+timediff_t Curl_pp_state_timeout(struct pingpong *pp, bool disconnecting);
 
 
 /***********************************************************************
@@ -135,8 +134,7 @@
 /* call this when a pingpong connection is disconnected */
 CURLcode Curl_pp_disconnect(struct pingpong *pp);
 
-int Curl_pp_getsock(struct pingpong *pp, curl_socket_t *socks,
-                    int numsocks);
+int Curl_pp_getsock(struct pingpong *pp, curl_socket_t *socks);
 
 
 /***********************************************************************
diff --git a/Utilities/cmcurl/lib/pop3.c b/Utilities/cmcurl/lib/pop3.c
index c8f3965..9ff5c78 100644
--- a/Utilities/cmcurl/lib/pop3.c
+++ b/Utilities/cmcurl/lib/pop3.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -95,8 +95,7 @@
 static CURLcode pop3_connect(struct connectdata *conn, bool *done);
 static CURLcode pop3_disconnect(struct connectdata *conn, bool dead);
 static CURLcode pop3_multi_statemach(struct connectdata *conn, bool *done);
-static int pop3_getsock(struct connectdata *conn, curl_socket_t *socks,
-                        int numsocks);
+static int pop3_getsock(struct connectdata *conn, curl_socket_t *socks);
 static CURLcode pop3_doing(struct connectdata *conn, bool *dophase_done);
 static CURLcode pop3_setup_connection(struct connectdata *conn);
 static CURLcode pop3_parse_url_options(struct connectdata *conn);
@@ -179,7 +178,7 @@
   conn->handler = &Curl_handler_pop3s;
 
   /* Set the connection's upgraded to TLS flag */
-  conn->tls_upgraded = TRUE;
+  conn->bits.tls_upgraded = TRUE;
 }
 #else
 #define pop3_to_pop3s(x) Curl_nop_stmt
@@ -339,10 +338,8 @@
  */
 static CURLcode pop3_perform_starttls(struct connectdata *conn)
 {
-  CURLcode result = CURLE_OK;
-
   /* Send the STLS command */
-  result = Curl_pp_sendf(&conn->proto.pop3c.pp, "%s", "STLS");
+  CURLcode result = Curl_pp_sendf(&conn->proto.pop3c.pp, "%s", "STLS");
 
   if(!result)
     state(conn, POP3_STARTTLS);
@@ -358,11 +355,10 @@
  */
 static CURLcode pop3_perform_upgrade_tls(struct connectdata *conn)
 {
-  CURLcode result = CURLE_OK;
-  struct pop3_conn *pop3c = &conn->proto.pop3c;
-
   /* Start the SSL connection */
-  result = Curl_ssl_connect_nonblocking(conn, FIRSTSOCKET, &pop3c->ssldone);
+  struct pop3_conn *pop3c = &conn->proto.pop3c;
+  CURLcode result = Curl_ssl_connect_nonblocking(conn, FIRSTSOCKET,
+                                                 &pop3c->ssldone);
 
   if(!result) {
     if(pop3c->state != POP3_UPGRADETLS)
@@ -416,7 +412,7 @@
   CURLcode result = CURLE_OK;
   struct pop3_conn *pop3c = &conn->proto.pop3c;
   size_t i;
-  MD5_context *ctxt;
+  struct MD5_context *ctxt;
   unsigned char digest[MD5_DIGEST_LEN];
   char secret[2 * MD5_DIGEST_LEN + 1];
 
@@ -593,10 +589,8 @@
  */
 static CURLcode pop3_perform_quit(struct connectdata *conn)
 {
-  CURLcode result = CURLE_OK;
-
   /* Send the QUIT command */
-  result = Curl_pp_sendf(&conn->proto.pop3c.pp, "%s", "QUIT");
+  CURLcode result = Curl_pp_sendf(&conn->proto.pop3c.pp, "%s", "QUIT");
 
   if(!result)
     state(conn, POP3_QUIT);
@@ -1060,10 +1054,9 @@
 }
 
 /* For the POP3 "protocol connect" and "doing" phases only */
-static int pop3_getsock(struct connectdata *conn, curl_socket_t *socks,
-                        int numsocks)
+static int pop3_getsock(struct connectdata *conn, curl_socket_t *socks)
 {
-  return Curl_pp_getsock(&conn->proto.pop3c.pp, socks, numsocks);
+  return Curl_pp_getsock(&conn->proto.pop3c.pp, socks);
 }
 
 /***********************************************************************
@@ -1319,7 +1312,7 @@
     return result;
 
   /* Clear the TLS upgraded flag */
-  conn->tls_upgraded = FALSE;
+  conn->bits.tls_upgraded = FALSE;
 
   return CURLE_OK;
 }
@@ -1397,7 +1390,7 @@
   const char *path = &data->state.up.path[1]; /* skip leading path */
 
   /* URL decode the path for the message ID */
-  return Curl_urldecode(data, path, 0, &pop3->id, NULL, TRUE);
+  return Curl_urldecode(data, path, 0, &pop3->id, NULL, REJECT_CTRL);
 }
 
 /***********************************************************************
@@ -1415,7 +1408,7 @@
 
   /* URL decode the custom request */
   if(custom)
-    result = Curl_urldecode(data, custom, 0, &pop3->custom, NULL, TRUE);
+    result = Curl_urldecode(data, custom, 0, &pop3->custom, NULL, REJECT_CTRL);
 
   return result;
 }
diff --git a/Utilities/cmcurl/lib/pop3.h b/Utilities/cmcurl/lib/pop3.h
index a8e697c..3ba7999 100644
--- a/Utilities/cmcurl/lib/pop3.h
+++ b/Utilities/cmcurl/lib/pop3.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 2009 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 2009 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
diff --git a/Utilities/cmcurl/lib/progress.c b/Utilities/cmcurl/lib/progress.c
index f586d59..8951384 100644
--- a/Utilities/cmcurl/lib/progress.c
+++ b/Utilities/cmcurl/lib/progress.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -26,6 +26,7 @@
 #include "sendf.h"
 #include "multiif.h"
 #include "progress.h"
+#include "timeval.h"
 #include "curl_printf.h"
 
 /* check rate limits within this many recent milliseconds, at minimum. */
@@ -168,7 +169,7 @@
 void Curl_pgrsTime(struct Curl_easy *data, timerid timer)
 {
   struct curltime now = Curl_now();
-  time_t *delta = NULL;
+  timediff_t *delta = NULL;
 
   switch(timer) {
   default:
@@ -238,6 +239,8 @@
   data->progress.ul_limit_start.tv_usec = 0;
   data->progress.dl_limit_start.tv_sec = 0;
   data->progress.dl_limit_start.tv_usec = 0;
+  data->progress.downloaded = 0;
+  data->progress.uploaded = 0;
   /* clear all bits except HIDE and HEADERS_OUT */
   data->progress.flags &= PGRS_HIDE|PGRS_HEADERS_OUT;
   Curl_ratelimit(data, data->progress.start);
@@ -268,8 +271,8 @@
                                   struct curltime now)
 {
   curl_off_t size = cursize - startsize;
-  time_t minimum;
-  time_t actual;
+  timediff_t minimum;
+  timediff_t actual;
 
   if(!limit || !size)
     return 0;
@@ -279,13 +282,13 @@
    * stay below 'limit'.
    */
   if(size < CURL_OFF_T_MAX/1000)
-    minimum = (time_t) (CURL_OFF_T_C(1000) * size / limit);
+    minimum = (timediff_t) (CURL_OFF_T_C(1000) * size / limit);
   else {
-    minimum = (time_t) (size / limit);
-    if(minimum < TIME_T_MAX/1000)
+    minimum = (timediff_t) (size / limit);
+    if(minimum < TIMEDIFF_T_MAX/1000)
       minimum *= 1000;
     else
-      minimum = TIME_T_MAX;
+      minimum = TIMEDIFF_T_MAX;
   }
 
   /*
@@ -364,18 +367,15 @@
   }
 }
 
-#ifndef CURL_DISABLE_PROGRESS_METER
-static void progress_meter(struct connectdata *conn)
+/* returns TRUE if it's time to show the progress meter */
+static bool progress_calc(struct connectdata *conn, struct curltime now)
 {
-  struct curltime now;
   curl_off_t timespent;
   curl_off_t timespent_ms; /* milliseconds */
   struct Curl_easy *data = conn->data;
-  bool shownow = FALSE;
   curl_off_t dl = data->progress.downloaded;
   curl_off_t ul = data->progress.uploaded;
-
-  now = Curl_now(); /* what time is it */
+  bool timetoshow = FALSE;
 
   /* The time spent so far (from the start) */
   data->progress.timespent = Curl_timediff_us(now, data->progress.start);
@@ -398,10 +398,8 @@
   if(data->progress.lastshow != now.tv_sec) {
     int countindex; /* amount of seconds stored in the speeder array */
     int nowindex = data->progress.speeder_c% CURR_TIME;
-    if(!(data->progress.flags & PGRS_HIDE))
-      shownow = TRUE;
-
     data->progress.lastshow = now.tv_sec;
+    timetoshow = TRUE;
 
     /* Let's do the "current speed" thing, with the dl + ul speeds
        combined. Store the speed at entry 'nowindex'. */
@@ -434,8 +432,7 @@
         data->progress.speeder_c%CURR_TIME:0;
 
       /* Figure out the exact time for the time span */
-      span_ms = Curl_timediff(now,
-                              data->progress.speeder_time[checkindex]);
+      span_ms = Curl_timediff(now, data->progress.speeder_time[checkindex]);
       if(0 == span_ms)
         span_ms = 1; /* at least one millisecond MUST have passed */
 
@@ -461,118 +458,119 @@
         data->progress.ulspeed + data->progress.dlspeed;
 
   } /* Calculations end */
-  if(!shownow)
-    /* only show the internal progress meter once per second */
-    return;
-  else {
-    /* If there's no external callback set, use internal code to show
-       progress */
-    /* progress meter has not been shut off */
-    char max5[6][10];
-    curl_off_t dlpercen = 0;
-    curl_off_t ulpercen = 0;
-    curl_off_t total_percen = 0;
-    curl_off_t total_transfer;
-    curl_off_t total_expected_transfer;
-    char time_left[10];
-    char time_total[10];
-    char time_spent[10];
-    curl_off_t ulestimate = 0;
-    curl_off_t dlestimate = 0;
-    curl_off_t total_estimate;
+  return timetoshow;
+}
 
-    if(!(data->progress.flags & PGRS_HEADERS_OUT)) {
-      if(data->state.resume_from) {
-        fprintf(data->set.err,
-                "** Resuming transfer from byte position %"
-                CURL_FORMAT_CURL_OFF_T "\n", data->state.resume_from);
-      }
+#ifndef CURL_DISABLE_PROGRESS_METER
+static void progress_meter(struct connectdata *conn)
+{
+  struct Curl_easy *data = conn->data;
+  char max5[6][10];
+  curl_off_t dlpercen = 0;
+  curl_off_t ulpercen = 0;
+  curl_off_t total_percen = 0;
+  curl_off_t total_transfer;
+  curl_off_t total_expected_transfer;
+  char time_left[10];
+  char time_total[10];
+  char time_spent[10];
+  curl_off_t ulestimate = 0;
+  curl_off_t dlestimate = 0;
+  curl_off_t total_estimate;
+  curl_off_t timespent =
+    (curl_off_t)data->progress.timespent/1000000; /* seconds */
+
+  if(!(data->progress.flags & PGRS_HEADERS_OUT)) {
+    if(data->state.resume_from) {
       fprintf(data->set.err,
-              "  %% Total    %% Received %% Xferd  Average Speed   "
-              "Time    Time     Time  Current\n"
-              "                                 Dload  Upload   "
-              "Total   Spent    Left  Speed\n");
-      data->progress.flags |= PGRS_HEADERS_OUT; /* headers are shown */
+              "** Resuming transfer from byte position %"
+              CURL_FORMAT_CURL_OFF_T "\n", data->state.resume_from);
     }
-
-    /* Figure out the estimated time of arrival for the upload */
-    if((data->progress.flags & PGRS_UL_SIZE_KNOWN) &&
-       (data->progress.ulspeed > CURL_OFF_T_C(0))) {
-      ulestimate = data->progress.size_ul / data->progress.ulspeed;
-
-      if(data->progress.size_ul > CURL_OFF_T_C(10000))
-        ulpercen = data->progress.uploaded /
-          (data->progress.size_ul/CURL_OFF_T_C(100));
-      else if(data->progress.size_ul > CURL_OFF_T_C(0))
-        ulpercen = (data->progress.uploaded*100) /
-          data->progress.size_ul;
-    }
-
-    /* ... and the download */
-    if((data->progress.flags & PGRS_DL_SIZE_KNOWN) &&
-       (data->progress.dlspeed > CURL_OFF_T_C(0))) {
-      dlestimate = data->progress.size_dl / data->progress.dlspeed;
-
-      if(data->progress.size_dl > CURL_OFF_T_C(10000))
-        dlpercen = data->progress.downloaded /
-          (data->progress.size_dl/CURL_OFF_T_C(100));
-      else if(data->progress.size_dl > CURL_OFF_T_C(0))
-        dlpercen = (data->progress.downloaded*100) /
-          data->progress.size_dl;
-    }
-
-    /* Now figure out which of them is slower and use that one for the
-       total estimate! */
-    total_estimate = ulestimate>dlestimate?ulestimate:dlestimate;
-
-    /* create the three time strings */
-    time2str(time_left, total_estimate > 0?(total_estimate - timespent):0);
-    time2str(time_total, total_estimate);
-    time2str(time_spent, timespent);
-
-    /* Get the total amount of data expected to get transferred */
-    total_expected_transfer =
-      ((data->progress.flags & PGRS_UL_SIZE_KNOWN)?
-       data->progress.size_ul:data->progress.uploaded)+
-      ((data->progress.flags & PGRS_DL_SIZE_KNOWN)?
-       data->progress.size_dl:data->progress.downloaded);
-
-    /* We have transferred this much so far */
-    total_transfer = data->progress.downloaded + data->progress.uploaded;
-
-    /* Get the percentage of data transferred so far */
-    if(total_expected_transfer > CURL_OFF_T_C(10000))
-      total_percen = total_transfer /
-        (total_expected_transfer/CURL_OFF_T_C(100));
-    else if(total_expected_transfer > CURL_OFF_T_C(0))
-      total_percen = (total_transfer*100) / total_expected_transfer;
-
     fprintf(data->set.err,
-            "\r"
-            "%3" CURL_FORMAT_CURL_OFF_T " %s  "
-            "%3" CURL_FORMAT_CURL_OFF_T " %s  "
-            "%3" CURL_FORMAT_CURL_OFF_T " %s  %s  %s %s %s %s %s",
-            total_percen,  /* 3 letters */                /* total % */
-            max5data(total_expected_transfer, max5[2]),   /* total size */
-            dlpercen,      /* 3 letters */                /* rcvd % */
-            max5data(data->progress.downloaded, max5[0]), /* rcvd size */
-            ulpercen,      /* 3 letters */                /* xfer % */
-            max5data(data->progress.uploaded, max5[1]),   /* xfer size */
-            max5data(data->progress.dlspeed, max5[3]),    /* avrg dl speed */
-            max5data(data->progress.ulspeed, max5[4]),    /* avrg ul speed */
-            time_total,    /* 8 letters */                /* total time */
-            time_spent,    /* 8 letters */                /* time spent */
-            time_left,     /* 8 letters */                /* time left */
-            max5data(data->progress.current_speed, max5[5])
-      );
+            "  %% Total    %% Received %% Xferd  Average Speed   "
+            "Time    Time     Time  Current\n"
+            "                                 Dload  Upload   "
+            "Total   Spent    Left  Speed\n");
+    data->progress.flags |= PGRS_HEADERS_OUT; /* headers are shown */
+  }
 
-    /* we flush the output stream to make it appear as soon as possible */
-    fflush(data->set.err);
-  } /* don't show now */
+  /* Figure out the estimated time of arrival for the upload */
+  if((data->progress.flags & PGRS_UL_SIZE_KNOWN) &&
+     (data->progress.ulspeed > CURL_OFF_T_C(0))) {
+    ulestimate = data->progress.size_ul / data->progress.ulspeed;
+
+    if(data->progress.size_ul > CURL_OFF_T_C(10000))
+      ulpercen = data->progress.uploaded /
+        (data->progress.size_ul/CURL_OFF_T_C(100));
+    else if(data->progress.size_ul > CURL_OFF_T_C(0))
+      ulpercen = (data->progress.uploaded*100) /
+        data->progress.size_ul;
+  }
+
+  /* ... and the download */
+  if((data->progress.flags & PGRS_DL_SIZE_KNOWN) &&
+     (data->progress.dlspeed > CURL_OFF_T_C(0))) {
+    dlestimate = data->progress.size_dl / data->progress.dlspeed;
+
+    if(data->progress.size_dl > CURL_OFF_T_C(10000))
+      dlpercen = data->progress.downloaded /
+        (data->progress.size_dl/CURL_OFF_T_C(100));
+    else if(data->progress.size_dl > CURL_OFF_T_C(0))
+      dlpercen = (data->progress.downloaded*100) /
+        data->progress.size_dl;
+  }
+
+  /* Now figure out which of them is slower and use that one for the
+     total estimate! */
+  total_estimate = ulestimate>dlestimate?ulestimate:dlestimate;
+
+  /* create the three time strings */
+  time2str(time_left, total_estimate > 0?(total_estimate - timespent):0);
+  time2str(time_total, total_estimate);
+  time2str(time_spent, timespent);
+
+  /* Get the total amount of data expected to get transferred */
+  total_expected_transfer =
+    ((data->progress.flags & PGRS_UL_SIZE_KNOWN)?
+     data->progress.size_ul:data->progress.uploaded)+
+    ((data->progress.flags & PGRS_DL_SIZE_KNOWN)?
+     data->progress.size_dl:data->progress.downloaded);
+
+  /* We have transferred this much so far */
+  total_transfer = data->progress.downloaded + data->progress.uploaded;
+
+  /* Get the percentage of data transferred so far */
+  if(total_expected_transfer > CURL_OFF_T_C(10000))
+    total_percen = total_transfer /
+      (total_expected_transfer/CURL_OFF_T_C(100));
+  else if(total_expected_transfer > CURL_OFF_T_C(0))
+    total_percen = (total_transfer*100) / total_expected_transfer;
+
+  fprintf(data->set.err,
+          "\r"
+          "%3" CURL_FORMAT_CURL_OFF_T " %s  "
+          "%3" CURL_FORMAT_CURL_OFF_T " %s  "
+          "%3" CURL_FORMAT_CURL_OFF_T " %s  %s  %s %s %s %s %s",
+          total_percen,  /* 3 letters */                /* total % */
+          max5data(total_expected_transfer, max5[2]),   /* total size */
+          dlpercen,      /* 3 letters */                /* rcvd % */
+          max5data(data->progress.downloaded, max5[0]), /* rcvd size */
+          ulpercen,      /* 3 letters */                /* xfer % */
+          max5data(data->progress.uploaded, max5[1]),   /* xfer size */
+          max5data(data->progress.dlspeed, max5[3]),    /* avrg dl speed */
+          max5data(data->progress.ulspeed, max5[4]),    /* avrg ul speed */
+          time_total,    /* 8 letters */                /* total time */
+          time_spent,    /* 8 letters */                /* time spent */
+          time_left,     /* 8 letters */                /* time left */
+          max5data(data->progress.current_speed, max5[5])
+    );
+
+  /* we flush the output stream to make it appear as soon as possible */
+  fflush(data->set.err);
 }
 #else
  /* progress bar disabled */
-#define progress_meter(x)
+#define progress_meter(x) Curl_nop_stmt
 #endif
 
 
@@ -583,6 +581,8 @@
 int Curl_pgrsUpdate(struct connectdata *conn)
 {
   struct Curl_easy *data = conn->data;
+  struct curltime now = Curl_now(); /* what time is it */
+  bool showprogress = progress_calc(conn, now);
   if(!(data->progress.flags & PGRS_HIDE)) {
     if(data->set.fxferinfo) {
       int result;
@@ -594,11 +594,13 @@
                                    data->progress.size_ul,
                                    data->progress.uploaded);
       Curl_set_in_callback(data, false);
-      if(result)
-        failf(data, "Callback aborted");
-      return result;
+      if(result != CURL_PROGRESSFUNC_CONTINUE) {
+        if(result)
+          failf(data, "Callback aborted");
+        return result;
+      }
     }
-    if(data->set.fprogress) {
+    else if(data->set.fprogress) {
       int result;
       /* The older deprecated callback is set, call that */
       Curl_set_in_callback(data, true);
@@ -608,12 +610,16 @@
                                    (double)data->progress.size_ul,
                                    (double)data->progress.uploaded);
       Curl_set_in_callback(data, false);
-      if(result)
-        failf(data, "Callback aborted");
-      return result;
+      if(result != CURL_PROGRESSFUNC_CONTINUE) {
+        if(result)
+          failf(data, "Callback aborted");
+        return result;
+      }
     }
+
+    if(showprogress)
+      progress_meter(conn);
   }
-  progress_meter(conn);
 
   return 0;
 }
diff --git a/Utilities/cmcurl/lib/quic.h b/Utilities/cmcurl/lib/quic.h
new file mode 100644
index 0000000..8e7df90
--- /dev/null
+++ b/Utilities/cmcurl/lib/quic.h
@@ -0,0 +1,59 @@
+#ifndef HEADER_CURL_QUIC_H
+#define HEADER_CURL_QUIC_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#ifdef ENABLE_QUIC
+#ifdef USE_NGTCP2
+#include "vquic/ngtcp2.h"
+#endif
+#ifdef USE_QUICHE
+#include "vquic/quiche.h"
+#endif
+
+#include "urldata.h"
+
+/* functions provided by the specific backends */
+CURLcode Curl_quic_connect(struct connectdata *conn,
+                           curl_socket_t sockfd,
+                           int sockindex,
+                           const struct sockaddr *addr,
+                           socklen_t addrlen);
+CURLcode Curl_quic_is_connected(struct connectdata *conn,
+                                curl_socket_t sockfd,
+                                bool *connected);
+int Curl_quic_ver(char *p, size_t len);
+CURLcode Curl_quic_done_sending(struct connectdata *conn);
+void Curl_quic_done(struct Curl_easy *data, bool premature);
+bool Curl_quic_data_pending(const struct Curl_easy *data);
+void Curl_quic_disconnect(struct connectdata *conn, int tempindex);
+
+#else /* ENABLE_QUIC */
+#define Curl_quic_done_sending(x)
+#define Curl_quic_done(x,y)
+#define Curl_quic_data_pending(x)
+#define Curl_quic_disconnect(x,y)
+#endif /* !ENABLE_QUIC */
+
+#endif /* HEADER_CURL_QUIC_H */
diff --git a/Utilities/cmcurl/lib/rand.c b/Utilities/cmcurl/lib/rand.c
index 6ee45fe..c415048 100644
--- a/Utilities/cmcurl/lib/rand.c
+++ b/Utilities/cmcurl/lib/rand.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -106,8 +106,7 @@
  * 'rndptr' points to.
  *
  * If libcurl is built without TLS support or with a TLS backend that lacks a
- * proper random API (Gskit, PolarSSL or mbedTLS), this function will use
- * "weak" random.
+ * proper random API (Gskit or mbedTLS), this function will use "weak" random.
  *
  * When built *with* TLS support and a backend that offers strong random, it
  * will return error if it cannot provide strong random values.
diff --git a/Utilities/cmcurl/lib/rand.h b/Utilities/cmcurl/lib/rand.h
index 5deb041..3c8e2b8 100644
--- a/Utilities/cmcurl/lib/rand.h
+++ b/Utilities/cmcurl/lib/rand.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -27,8 +27,7 @@
  * 'rnd' points to.
  *
  * If libcurl is built without TLS support or with a TLS backend that lacks a
- * proper random API (Gskit, PolarSSL or mbedTLS), this function will use
- * "weak" random.
+ * proper random API (Gskit or mbedTLS), this function will use "weak" random.
  *
  * When built *with* TLS support and a backend that offers strong random, it
  * will return error if it cannot provide strong random values.
diff --git a/Utilities/cmcurl/lib/rename.c b/Utilities/cmcurl/lib/rename.c
new file mode 100644
index 0000000..bb170d3
--- /dev/null
+++ b/Utilities/cmcurl/lib/rename.c
@@ -0,0 +1,62 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "rename.h"
+
+#include "curl_setup.h"
+
+#if (!defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_COOKIES)) ||  \
+  defined(USE_ALTSVC)
+
+#include "timeval.h"
+
+/* The last 3 #include files should be in this order */
+#include "curl_printf.h"
+#include "curl_memory.h"
+#include "memdebug.h"
+
+/* return 0 on success, 1 on error */
+int Curl_rename(const char *oldpath, const char *newpath)
+{
+#ifdef WIN32
+  /* rename() on Windows doesn't overwrite, so we can't use it here.
+     MoveFileExA() will overwrite and is usually atomic, however it fails
+     when there are open handles to the file. */
+  const int max_wait_ms = 1000;
+  struct curltime start = Curl_now();
+  for(;;) {
+    timediff_t diff;
+    if(MoveFileExA(oldpath, newpath, MOVEFILE_REPLACE_EXISTING))
+      break;
+    diff = Curl_timediff(Curl_now(), start);
+    if(diff < 0 || diff > max_wait_ms)
+      return 1;
+    Sleep(1);
+  }
+#else
+  if(rename(oldpath, newpath))
+    return 1;
+#endif
+  return 0;
+}
+
+#endif
diff --git a/Utilities/cmcurl/lib/rename.h b/Utilities/cmcurl/lib/rename.h
new file mode 100644
index 0000000..d7442c8
--- /dev/null
+++ b/Utilities/cmcurl/lib/rename.h
@@ -0,0 +1,27 @@
+#ifndef HEADER_CURL_RENAME_H
+#define HEADER_CURL_RENAME_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+int Curl_rename(const char *oldpath, const char *newpath);
+
+#endif /* HEADER_CURL_RENAME_H */
diff --git a/Utilities/cmcurl/lib/rtsp.c b/Utilities/cmcurl/lib/rtsp.c
index 74cf232..dbd7dc6 100644
--- a/Utilities/cmcurl/lib/rtsp.c
+++ b/Utilities/cmcurl/lib/rtsp.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -52,10 +52,7 @@
 static CURLcode rtsp_done(struct connectdata *conn, CURLcode, bool premature);
 static CURLcode rtsp_connect(struct connectdata *conn, bool *done);
 static CURLcode rtsp_disconnect(struct connectdata *conn, bool dead);
-
-static int rtsp_getsock_do(struct connectdata *conn,
-                           curl_socket_t *socks,
-                           int numsocks);
+static int rtsp_getsock_do(struct connectdata *conn, curl_socket_t *socks);
 
 /*
  * Parse and write out any available RTP data.
@@ -77,11 +74,9 @@
    interface and then we're always _sending_ a request and thus we wait for
    the single socket to become writable only */
 static int rtsp_getsock_do(struct connectdata *conn,
-                           curl_socket_t *socks,
-                           int numsocks)
+                           curl_socket_t *socks)
 {
   /* write mode */
-  (void)numsocks; /* unused, we trust it to be at least 1 */
   socks[0] = conn->sock[FIRSTSOCKET];
   return GETSOCK_WRITESOCK(0);
 }
@@ -238,7 +233,7 @@
   CURLcode result = CURLE_OK;
   Curl_RtspReq rtspreq = data->set.rtspreq;
   struct RTSP *rtsp = data->req.protop;
-  Curl_send_buffer *req_buffer;
+  struct dynbuf req_buffer;
   curl_off_t postsize = 0; /* for ANNOUNCE and SET_PARAMETER */
   curl_off_t putsize = 0; /* for ANNOUNCE and SET_PARAMETER */
 
@@ -338,12 +333,12 @@
   if(rtspreq == RTSPREQ_SETUP && !p_transport) {
     /* New Transport: setting? */
     if(data->set.str[STRING_RTSP_TRANSPORT]) {
-      Curl_safefree(conn->allocptr.rtsp_transport);
+      Curl_safefree(data->state.aptr.rtsp_transport);
 
-      conn->allocptr.rtsp_transport =
+      data->state.aptr.rtsp_transport =
         aprintf("Transport: %s\r\n",
                 data->set.str[STRING_RTSP_TRANSPORT]);
-      if(!conn->allocptr.rtsp_transport)
+      if(!data->state.aptr.rtsp_transport)
         return CURLE_OUT_OF_MEMORY;
     }
     else {
@@ -352,7 +347,7 @@
       return CURLE_BAD_FUNCTION_ARGUMENT;
     }
 
-    p_transport = conn->allocptr.rtsp_transport;
+    p_transport = data->state.aptr.rtsp_transport;
   }
 
   /* Accept Headers for DESCRIBE requests */
@@ -364,14 +359,14 @@
     /* Accept-Encoding header */
     if(!Curl_checkheaders(conn, "Accept-Encoding") &&
        data->set.str[STRING_ENCODING]) {
-      Curl_safefree(conn->allocptr.accept_encoding);
-      conn->allocptr.accept_encoding =
+      Curl_safefree(data->state.aptr.accept_encoding);
+      data->state.aptr.accept_encoding =
         aprintf("Accept-Encoding: %s\r\n", data->set.str[STRING_ENCODING]);
 
-      if(!conn->allocptr.accept_encoding)
+      if(!data->state.aptr.accept_encoding)
         return CURLE_OUT_OF_MEMORY;
 
-      p_accept_encoding = conn->allocptr.accept_encoding;
+      p_accept_encoding = data->state.aptr.accept_encoding;
     }
   }
 
@@ -379,13 +374,13 @@
      it might have been used in the proxy connect, but if we have got a header
      with the user-agent string specified, we erase the previously made string
      here. */
-  if(Curl_checkheaders(conn, "User-Agent") && conn->allocptr.uagent) {
-    Curl_safefree(conn->allocptr.uagent);
-    conn->allocptr.uagent = NULL;
+  if(Curl_checkheaders(conn, "User-Agent") && data->state.aptr.uagent) {
+    Curl_safefree(data->state.aptr.uagent);
+    data->state.aptr.uagent = NULL;
   }
   else if(!Curl_checkheaders(conn, "User-Agent") &&
           data->set.str[STRING_USERAGENT]) {
-    p_uagent = conn->allocptr.uagent;
+    p_uagent = data->state.aptr.uagent;
   }
 
   /* setup the authentication headers */
@@ -393,17 +388,17 @@
   if(result)
     return result;
 
-  p_proxyuserpwd = conn->allocptr.proxyuserpwd;
-  p_userpwd = conn->allocptr.userpwd;
+  p_proxyuserpwd = data->state.aptr.proxyuserpwd;
+  p_userpwd = data->state.aptr.userpwd;
 
   /* Referrer */
-  Curl_safefree(conn->allocptr.ref);
+  Curl_safefree(data->state.aptr.ref);
   if(data->change.referer && !Curl_checkheaders(conn, "Referer"))
-    conn->allocptr.ref = aprintf("Referer: %s\r\n", data->change.referer);
+    data->state.aptr.ref = aprintf("Referer: %s\r\n", data->change.referer);
   else
-    conn->allocptr.ref = NULL;
+    data->state.aptr.ref = NULL;
 
-  p_referrer = conn->allocptr.ref;
+  p_referrer = data->state.aptr.ref;
 
   /*
    * Range Header
@@ -416,9 +411,9 @@
 
     /* Check to see if there is a range set in the custom headers */
     if(!Curl_checkheaders(conn, "Range") && data->state.range) {
-      Curl_safefree(conn->allocptr.rangeline);
-      conn->allocptr.rangeline = aprintf("Range: %s\r\n", data->state.range);
-      p_range = conn->allocptr.rangeline;
+      Curl_safefree(data->state.aptr.rangeline);
+      data->state.aptr.rangeline = aprintf("Range: %s\r\n", data->state.range);
+      p_range = data->state.aptr.rangeline;
     }
   }
 
@@ -435,16 +430,13 @@
   }
 
   /* Initialize a dynamic send buffer */
-  req_buffer = Curl_add_buffer_init();
-
-  if(!req_buffer)
-    return CURLE_OUT_OF_MEMORY;
+  Curl_dyn_init(&req_buffer, DYN_RTSP_REQ_HEADER);
 
   result =
-    Curl_add_bufferf(&req_buffer,
-                     "%s %s RTSP/1.0\r\n" /* Request Stream-URI RTSP/1.0 */
-                     "CSeq: %ld\r\n", /* CSeq */
-                     p_request, p_stream_uri, rtsp->CSeq_sent);
+    Curl_dyn_addf(&req_buffer,
+                  "%s %s RTSP/1.0\r\n" /* Request Stream-URI RTSP/1.0 */
+                  "CSeq: %ld\r\n", /* CSeq */
+                  p_request, p_stream_uri, rtsp->CSeq_sent);
   if(result)
     return result;
 
@@ -453,7 +445,7 @@
    * to make comparison easier
    */
   if(p_session_id) {
-    result = Curl_add_bufferf(&req_buffer, "Session: %s\r\n", p_session_id);
+    result = Curl_dyn_addf(&req_buffer, "Session: %s\r\n", p_session_id);
     if(result)
       return result;
   }
@@ -461,42 +453,42 @@
   /*
    * Shared HTTP-like options
    */
-  result = Curl_add_bufferf(&req_buffer,
-                            "%s" /* transport */
-                            "%s" /* accept */
-                            "%s" /* accept-encoding */
-                            "%s" /* range */
-                            "%s" /* referrer */
-                            "%s" /* user-agent */
-                            "%s" /* proxyuserpwd */
-                            "%s" /* userpwd */
-                            ,
-                            p_transport ? p_transport : "",
-                            p_accept ? p_accept : "",
-                            p_accept_encoding ? p_accept_encoding : "",
-                            p_range ? p_range : "",
-                            p_referrer ? p_referrer : "",
-                            p_uagent ? p_uagent : "",
-                            p_proxyuserpwd ? p_proxyuserpwd : "",
-                            p_userpwd ? p_userpwd : "");
+  result = Curl_dyn_addf(&req_buffer,
+                         "%s" /* transport */
+                         "%s" /* accept */
+                         "%s" /* accept-encoding */
+                         "%s" /* range */
+                         "%s" /* referrer */
+                         "%s" /* user-agent */
+                         "%s" /* proxyuserpwd */
+                         "%s" /* userpwd */
+                         ,
+                         p_transport ? p_transport : "",
+                         p_accept ? p_accept : "",
+                         p_accept_encoding ? p_accept_encoding : "",
+                         p_range ? p_range : "",
+                         p_referrer ? p_referrer : "",
+                         p_uagent ? p_uagent : "",
+                         p_proxyuserpwd ? p_proxyuserpwd : "",
+                         p_userpwd ? p_userpwd : "");
 
   /*
    * Free userpwd now --- cannot reuse this for Negotiate and possibly NTLM
    * with basic and digest, it will be freed anyway by the next request
    */
-  Curl_safefree(conn->allocptr.userpwd);
-  conn->allocptr.userpwd = NULL;
+  Curl_safefree(data->state.aptr.userpwd);
+  data->state.aptr.userpwd = NULL;
 
   if(result)
     return result;
 
   if((rtspreq == RTSPREQ_SETUP) || (rtspreq == RTSPREQ_DESCRIBE)) {
-    result = Curl_add_timecondition(data, req_buffer);
+    result = Curl_add_timecondition(conn, &req_buffer);
     if(result)
       return result;
   }
 
-  result = Curl_add_custom_headers(conn, FALSE, req_buffer);
+  result = Curl_add_custom_headers(conn, FALSE, &req_buffer);
   if(result)
     return result;
 
@@ -506,14 +498,14 @@
 
     if(data->set.upload) {
       putsize = data->state.infilesize;
-      data->set.httpreq = HTTPREQ_PUT;
+      data->state.httpreq = HTTPREQ_PUT;
 
     }
     else {
       postsize = (data->state.infilesize != -1)?
         data->state.infilesize:
         (data->set.postfields? (curl_off_t)strlen(data->set.postfields):0);
-      data->set.httpreq = HTTPREQ_POST;
+      data->state.httpreq = HTTPREQ_POST;
     }
 
     if(putsize > 0 || postsize > 0) {
@@ -521,9 +513,9 @@
        * actually set a custom Content-Length in the headers */
       if(!Curl_checkheaders(conn, "Content-Length")) {
         result =
-          Curl_add_bufferf(&req_buffer,
-                           "Content-Length: %" CURL_FORMAT_CURL_OFF_T"\r\n",
-                           (data->set.upload ? putsize : postsize));
+          Curl_dyn_addf(&req_buffer,
+                        "Content-Length: %" CURL_FORMAT_CURL_OFF_T"\r\n",
+                        (data->set.upload ? putsize : postsize));
         if(result)
           return result;
       }
@@ -531,8 +523,8 @@
       if(rtspreq == RTSPREQ_SET_PARAMETER ||
          rtspreq == RTSPREQ_GET_PARAMETER) {
         if(!Curl_checkheaders(conn, "Content-Type")) {
-          result = Curl_add_bufferf(&req_buffer,
-                                    "Content-Type: text/parameters\r\n");
+          result = Curl_dyn_addf(&req_buffer,
+                                 "Content-Type: text/parameters\r\n");
           if(result)
             return result;
         }
@@ -540,8 +532,8 @@
 
       if(rtspreq == RTSPREQ_ANNOUNCE) {
         if(!Curl_checkheaders(conn, "Content-Type")) {
-          result = Curl_add_bufferf(&req_buffer,
-                                    "Content-Type: application/sdp\r\n");
+          result = Curl_dyn_addf(&req_buffer,
+                                 "Content-Type: application/sdp\r\n");
           if(result)
             return result;
         }
@@ -551,7 +543,7 @@
     }
     else if(rtspreq == RTSPREQ_GET_PARAMETER) {
       /* Check for an empty GET_PARAMETER (heartbeat) request */
-      data->set.httpreq = HTTPREQ_HEAD;
+      data->state.httpreq = HTTPREQ_HEAD;
       data->set.opt_no_body = TRUE;
     }
   }
@@ -559,20 +551,20 @@
   /* RTSP never allows chunked transfer */
   data->req.forbidchunk = TRUE;
   /* Finish the request buffer */
-  result = Curl_add_buffer(&req_buffer, "\r\n", 2);
+  result = Curl_dyn_add(&req_buffer, "\r\n");
   if(result)
     return result;
 
   if(postsize > 0) {
-    result = Curl_add_buffer(&req_buffer, data->set.postfields,
-                             (size_t)postsize);
+    result = Curl_dyn_addn(&req_buffer, data->set.postfields,
+                           (size_t)postsize);
     if(result)
       return result;
   }
 
   /* issue the request */
-  result = Curl_add_buffer_send(&req_buffer, conn,
-                                &data->info.request_size, 0, FIRSTSOCKET);
+  result = Curl_buffer_send(&req_buffer, conn,
+                            &data->info.request_size, 0, FIRSTSOCKET);
   if(result) {
     failf(data, "Failed sending RTSP request");
     return result;
diff --git a/Utilities/cmcurl/lib/rtsp.h b/Utilities/cmcurl/lib/rtsp.h
index 2f9cc32..1aae864 100644
--- a/Utilities/cmcurl/lib/rtsp.h
+++ b/Utilities/cmcurl/lib/rtsp.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
diff --git a/Utilities/cmcurl/lib/security.c b/Utilities/cmcurl/lib/security.c
index 7695154..3b9c20a 100644
--- a/Utilities/cmcurl/lib/security.c
+++ b/Utilities/cmcurl/lib/security.c
@@ -7,7 +7,7 @@
  * rewrite to work around the paragraph 2 in the BSD licenses as explained
  * below.
  *
- * Copyright (c) 1998, 1999, 2017 Kungliga Tekniska Högskolan
+ * Copyright (c) 1998, 1999, 2017 Kungliga Tekniska Högskolan
  * (Royal Institute of Technology, Stockholm, Sweden).
  *
  * Copyright (C) 2001 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
@@ -191,7 +191,6 @@
                           struct krb5buffer *buf)
 {
   int len;
-  void *tmp = NULL;
   CURLcode result;
 
   result = socket_read(fd, &len, sizeof(len));
@@ -201,12 +200,11 @@
   if(len) {
     /* only realloc if there was a length */
     len = ntohl(len);
-    tmp = Curl_saferealloc(buf->data, len);
+    buf->data = Curl_saferealloc(buf->data, len);
   }
-  if(tmp == NULL)
+  if(!len || !buf->data)
     return CURLE_OUT_OF_MEMORY;
 
-  buf->data = tmp;
   result = socket_read(fd, buf->data, len);
   if(result)
     return result;
@@ -238,7 +236,7 @@
 
   /* Handle clear text response. */
   if(conn->sec_complete == 0 || conn->data_prot == PROT_CLEAR)
-      return read(fd, buffer, len);
+      return sread(fd, buffer, len);
 
   if(conn->in_buffer.eof_flag) {
     conn->in_buffer.eof_flag = 0;
@@ -267,7 +265,7 @@
 }
 
 /* Send |length| bytes from |from| to the |fd| socket taking care of encoding
-   and negociating with the server. |from| can be NULL. */
+   and negotiating with the server. |from| can be NULL. */
 static void do_sec_send(struct connectdata *conn, curl_socket_t fd,
                         const char *from, int length)
 {
diff --git a/Utilities/cmcurl/lib/select.c b/Utilities/cmcurl/lib/select.c
index 6e73890..6832b42 100644
--- a/Utilities/cmcurl/lib/select.c
+++ b/Utilities/cmcurl/lib/select.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -22,8 +22,12 @@
 
 #include "curl_setup.h"
 
+#include <limits.h>
+
 #ifdef HAVE_SYS_SELECT_H
 #include <sys/select.h>
+#elif defined(HAVE_UNISTD_H)
+#include <unistd.h>
 #endif
 
 #if !defined(HAVE_SELECT) && !defined(HAVE_POLL_FINE)
@@ -48,14 +52,9 @@
 #include "urldata.h"
 #include "connect.h"
 #include "select.h"
+#include "timeval.h"
 #include "warnless.h"
 
-/* Convenience local macros */
-#define ELAPSED_MS() (int)Curl_timediff(Curl_now(), initial_tv)
-
-int Curl_ack_eintr = 0;
-#define ERROR_NOT_EINTR(error) (Curl_ack_eintr || error != EINTR)
-
 /*
  * Internal function used for waiting a specific amount of ms
  * in Curl_socket_check() and Curl_poll() when no file descriptor
@@ -72,15 +71,8 @@
  *   -1 = system call error, invalid timeout value, or interrupted
  *    0 = specified timeout has elapsed
  */
-int Curl_wait_ms(int timeout_ms)
+int Curl_wait_ms(timediff_t timeout_ms)
 {
-#if !defined(MSDOS) && !defined(USE_WINSOCK)
-#ifndef HAVE_POLL_FINE
-  struct timeval pending_tv;
-#endif
-  struct curltime initial_tv;
-  int pending_ms;
-#endif
   int r = 0;
 
   if(!timeout_ms)
@@ -91,31 +83,47 @@
   }
 #if defined(MSDOS)
   delay(timeout_ms);
-#elif defined(USE_WINSOCK)
-  Sleep(timeout_ms);
+#elif defined(WIN32)
+  /* prevent overflow, timeout_ms is typecast to ULONG/DWORD. */
+#if TIMEDIFF_T_MAX >= ULONG_MAX
+  if(timeout_ms >= ULONG_MAX)
+    timeout_ms = ULONG_MAX-1;
+    /* don't use ULONG_MAX, because that is equal to INFINITE */
+#endif
+  Sleep((ULONG)timeout_ms);
 #else
-  pending_ms = timeout_ms;
-  initial_tv = Curl_now();
-  do {
-    int error;
 #if defined(HAVE_POLL_FINE)
-    r = poll(NULL, 0, pending_ms);
+  /* prevent overflow, timeout_ms is typecast to int. */
+#if TIMEDIFF_T_MAX > INT_MAX
+  if(timeout_ms > INT_MAX)
+    timeout_ms = INT_MAX;
+#endif
+  r = poll(NULL, 0, (int)timeout_ms);
 #else
-    pending_tv.tv_sec = pending_ms / 1000;
-    pending_tv.tv_usec = (pending_ms % 1000) * 1000;
+  {
+    struct timeval pending_tv;
+    timediff_t tv_sec = timeout_ms / 1000;
+    timediff_t tv_usec = (timeout_ms % 1000) * 1000; /* max=999999 */
+#ifdef HAVE_SUSECONDS_T
+#if TIMEDIFF_T_MAX > TIME_T_MAX
+    /* tv_sec overflow check in case time_t is signed */
+    if(tv_sec > TIME_T_MAX)
+      tv_sec = TIME_T_MAX;
+#endif
+    pending_tv.tv_sec = (time_t)tv_sec;
+    pending_tv.tv_usec = (suseconds_t)tv_usec;
+#else
+#if TIMEDIFF_T_MAX > INT_MAX
+    /* tv_sec overflow check in case time_t is signed */
+    if(tv_sec > INT_MAX)
+      tv_sec = INT_MAX;
+#endif
+    pending_tv.tv_sec = (int)tv_sec;
+    pending_tv.tv_usec = (int)tv_usec;
+#endif
     r = select(0, NULL, NULL, NULL, &pending_tv);
+  }
 #endif /* HAVE_POLL_FINE */
-    if(r != -1)
-      break;
-    error = SOCKERRNO;
-    if(error && ERROR_NOT_EINTR(error))
-      break;
-    pending_ms = timeout_ms - ELAPSED_MS();
-    if(pending_ms <= 0) {
-      r = 0;  /* Simulate a "call timed out" case */
-      break;
-    }
-  } while(r == -1);
 #endif /* USE_WINSOCK */
   if(r)
     r = -1;
@@ -123,6 +131,98 @@
 }
 
 /*
+ * This is a wrapper around select() to aid in Windows compatibility.
+ * A negative timeout value makes this function wait indefinitely,
+ * unless no valid file descriptor is given, when this happens the
+ * negative timeout is ignored and the function times out immediately.
+ *
+ * Return values:
+ *   -1 = system call error or fd >= FD_SETSIZE
+ *    0 = timeout
+ *    N = number of signalled file descriptors
+ */
+int Curl_select(curl_socket_t maxfd,   /* highest socket number */
+                fd_set *fds_read,      /* sockets ready for reading */
+                fd_set *fds_write,     /* sockets ready for writing */
+                fd_set *fds_err,       /* sockets with errors */
+                timediff_t timeout_ms) /* milliseconds to wait */
+{
+  struct timeval pending_tv;
+  struct timeval *ptimeout;
+  int r;
+
+#ifdef USE_WINSOCK
+  /* WinSock select() can't handle zero events.  See the comment below. */
+  if((!fds_read || fds_read->fd_count == 0) &&
+     (!fds_write || fds_write->fd_count == 0) &&
+     (!fds_err || fds_err->fd_count == 0)) {
+    r = Curl_wait_ms(timeout_ms);
+    return r;
+  }
+#endif
+
+  ptimeout = &pending_tv;
+  if(timeout_ms < 0) {
+    ptimeout = NULL;
+  }
+  else if(timeout_ms > 0) {
+    timediff_t tv_sec = timeout_ms / 1000;
+    timediff_t tv_usec = (timeout_ms % 1000) * 1000; /* max=999999 */
+#ifdef HAVE_SUSECONDS_T
+#if TIMEDIFF_T_MAX > TIME_T_MAX
+    /* tv_sec overflow check in case time_t is signed */
+    if(tv_sec > TIME_T_MAX)
+      tv_sec = TIME_T_MAX;
+#endif
+    pending_tv.tv_sec = (time_t)tv_sec;
+    pending_tv.tv_usec = (suseconds_t)tv_usec;
+#elif defined(WIN32) /* maybe also others in the future */
+#if TIMEDIFF_T_MAX > LONG_MAX
+    /* tv_sec overflow check on Windows there we know it is long */
+    if(tv_sec > LONG_MAX)
+      tv_sec = LONG_MAX;
+#endif
+    pending_tv.tv_sec = (long)tv_sec;
+    pending_tv.tv_usec = (long)tv_usec;
+#else
+#if TIMEDIFF_T_MAX > INT_MAX
+    /* tv_sec overflow check in case time_t is signed */
+    if(tv_sec > INT_MAX)
+      tv_sec = INT_MAX;
+#endif
+    pending_tv.tv_sec = (int)tv_sec;
+    pending_tv.tv_usec = (int)tv_usec;
+#endif
+  }
+  else {
+    pending_tv.tv_sec = 0;
+    pending_tv.tv_usec = 0;
+  }
+
+#ifdef USE_WINSOCK
+  /* WinSock select() must not be called with an fd_set that contains zero
+    fd flags, or it will return WSAEINVAL.  But, it also can't be called
+    with no fd_sets at all!  From the documentation:
+
+    Any two of the parameters, readfds, writefds, or exceptfds, can be
+    given as null. At least one must be non-null, and any non-null
+    descriptor set must contain at least one handle to a socket.
+
+    It is unclear why WinSock doesn't just handle this for us instead of
+    calling this an error.
+  */
+  r = select((int)maxfd + 1,
+             fds_read && fds_read->fd_count ? fds_read : NULL,
+             fds_write && fds_write->fd_count ? fds_write : NULL,
+             fds_err && fds_err->fd_count ? fds_err : NULL, ptimeout);
+#else
+  r = select((int)maxfd + 1, fds_read, fds_write, fds_err, ptimeout);
+#endif
+
+  return r;
+}
+
+/*
  * Wait for read or write events on a set of file descriptors. It uses poll()
  * when a fine poll() is available, in order to avoid limits with FD_SETSIZE,
  * otherwise select() is used.  An error is returned if select() is being used
@@ -145,34 +245,24 @@
 int Curl_socket_check(curl_socket_t readfd0, /* two sockets to read from */
                       curl_socket_t readfd1,
                       curl_socket_t writefd, /* socket to write to */
-                      time_t timeout_ms)     /* milliseconds to wait */
+                      timediff_t timeout_ms) /* milliseconds to wait */
 {
 #ifdef HAVE_POLL_FINE
   struct pollfd pfd[3];
   int num;
 #else
-  struct timeval pending_tv;
-  struct timeval *ptimeout;
   fd_set fds_read;
   fd_set fds_write;
   fd_set fds_err;
   curl_socket_t maxfd;
 #endif
-  struct curltime initial_tv = {0, 0};
-  int pending_ms = 0;
   int r;
   int ret;
 
-#if SIZEOF_TIME_T != SIZEOF_INT
-  /* wrap-around precaution */
-  if(timeout_ms >= INT_MAX)
-    timeout_ms = INT_MAX;
-#endif
-
   if((readfd0 == CURL_SOCKET_BAD) && (readfd1 == CURL_SOCKET_BAD) &&
      (writefd == CURL_SOCKET_BAD)) {
     /* no sockets, just wait */
-    r = Curl_wait_ms((int)timeout_ms);
+    r = Curl_wait_ms(timeout_ms);
     return r;
   }
 
@@ -181,11 +271,6 @@
      when function is called with a zero timeout or a negative timeout
      value indicating a blocking call should be performed. */
 
-  if(timeout_ms > 0) {
-    pending_ms = (int)timeout_ms;
-    initial_tv = Curl_now();
-  }
-
 #ifdef HAVE_POLL_FINE
 
   num = 0;
@@ -208,31 +293,9 @@
     num++;
   }
 
-  do {
-    int error;
-    if(timeout_ms < 0)
-      pending_ms = -1;
-    else if(!timeout_ms)
-      pending_ms = 0;
-    r = poll(pfd, num, pending_ms);
-    if(r != -1)
-      break;
-    error = SOCKERRNO;
-    if(error && ERROR_NOT_EINTR(error))
-      break;
-    if(timeout_ms > 0) {
-      pending_ms = (int)(timeout_ms - ELAPSED_MS());
-      if(pending_ms <= 0) {
-        r = 0;  /* Simulate a "call timed out" case */
-        break;
-      }
-    }
-  } while(r == -1);
-
-  if(r < 0)
-    return -1;
-  if(r == 0)
-    return 0;
+  r = Curl_poll(pfd, num, timeout_ms);
+  if(r <= 0)
+    return r;
 
   ret = 0;
   num = 0;
@@ -288,62 +351,17 @@
       maxfd = writefd;
   }
 
-  ptimeout = (timeout_ms < 0) ? NULL : &pending_tv;
+  /* We know that we have at least one bit set in at least two fd_sets in
+     this case, but we may have no bits set in either fds_read or fd_write,
+     so check for that and handle it.  Luckily, with WinSock, we can _also_
+     ask how many bits are set on an fd_set.
 
-  do {
-    int error;
-    if(timeout_ms > 0) {
-      pending_tv.tv_sec = pending_ms / 1000;
-      pending_tv.tv_usec = (pending_ms % 1000) * 1000;
-    }
-    else if(!timeout_ms) {
-      pending_tv.tv_sec = 0;
-      pending_tv.tv_usec = 0;
-    }
-
-    /* WinSock select() must not be called with an fd_set that contains zero
-       fd flags, or it will return WSAEINVAL.  But, it also can't be called
-       with no fd_sets at all!  From the documentation:
-
-         Any two of the parameters, readfds, writefds, or exceptfds, can be
-         given as null. At least one must be non-null, and any non-null
-         descriptor set must contain at least one handle to a socket.
-
-       We know that we have at least one bit set in at least two fd_sets in
-       this case, but we may have no bits set in either fds_read or fd_write,
-       so check for that and handle it.  Luckily, with WinSock, we can _also_
-       ask how many bits are set on an fd_set.
-
-       It is unclear why WinSock doesn't just handle this for us instead of
-       calling this an error.
-
-       Note also that WinSock ignores the first argument, so we don't worry
-       about the fact that maxfd is computed incorrectly with WinSock (since
-       curl_socket_t is unsigned in such cases and thus -1 is the largest
-       value).
-    */
-#ifdef USE_WINSOCK
-    r = select((int)maxfd + 1,
-               fds_read.fd_count ? &fds_read : NULL,
-               fds_write.fd_count ? &fds_write : NULL,
-               &fds_err, ptimeout);
-#else
-    r = select((int)maxfd + 1, &fds_read, &fds_write, &fds_err, ptimeout);
-#endif
-
-    if(r != -1)
-      break;
-    error = SOCKERRNO;
-    if(error && ERROR_NOT_EINTR(error))
-      break;
-    if(timeout_ms > 0) {
-      pending_ms = (int)(timeout_ms - ELAPSED_MS());
-      if(pending_ms <= 0) {
-        r = 0;  /* Simulate a "call timed out" case */
-        break;
-      }
-    }
-  } while(r == -1);
+     Note also that WinSock ignores the first argument, so we don't worry
+     about the fact that maxfd is computed incorrectly with WinSock (since
+     curl_socket_t is unsigned in such cases and thus -1 is the largest
+     value).
+  */
+  r = Curl_select(maxfd, &fds_read, &fds_write, &fds_err, timeout_ms);
 
   if(r < 0)
     return -1;
@@ -389,20 +407,18 @@
  *    0 = timeout
  *    N = number of structures with non zero revent fields
  */
-int Curl_poll(struct pollfd ufds[], unsigned int nfds, int timeout_ms)
+int Curl_poll(struct pollfd ufds[], unsigned int nfds, timediff_t timeout_ms)
 {
-#ifndef HAVE_POLL_FINE
-  struct timeval pending_tv;
-  struct timeval *ptimeout;
+#ifdef HAVE_POLL_FINE
+  int pending_ms;
+#else
   fd_set fds_read;
   fd_set fds_write;
   fd_set fds_err;
   curl_socket_t maxfd;
 #endif
-  struct curltime initial_tv = {0, 0};
   bool fds_none = TRUE;
   unsigned int i;
-  int pending_ms = 0;
   int r;
 
   if(ufds) {
@@ -414,6 +430,7 @@
     }
   }
   if(fds_none) {
+    /* no sockets, just wait */
     r = Curl_wait_ms(timeout_ms);
     return r;
   }
@@ -423,33 +440,20 @@
      when function is called with a zero timeout or a negative timeout
      value indicating a blocking call should be performed. */
 
-  if(timeout_ms > 0) {
-    pending_ms = timeout_ms;
-    initial_tv = Curl_now();
-  }
-
 #ifdef HAVE_POLL_FINE
 
-  do {
-    int error;
-    if(timeout_ms < 0)
-      pending_ms = -1;
-    else if(!timeout_ms)
-      pending_ms = 0;
-    r = poll(ufds, nfds, pending_ms);
-    if(r != -1)
-      break;
-    error = SOCKERRNO;
-    if(error && ERROR_NOT_EINTR(error))
-      break;
-    if(timeout_ms > 0) {
-      pending_ms = (int)(timeout_ms - ELAPSED_MS());
-      if(pending_ms <= 0) {
-        r = 0;  /* Simulate a "call timed out" case */
-        break;
-      }
-    }
-  } while(r == -1);
+  /* prevent overflow, timeout_ms is typecast to int. */
+#if TIMEDIFF_T_MAX > INT_MAX
+  if(timeout_ms > INT_MAX)
+    timeout_ms = INT_MAX;
+#endif
+  if(timeout_ms > 0)
+    pending_ms = (int)timeout_ms;
+  else if(timeout_ms < 0)
+    pending_ms = -1;
+  else
+    pending_ms = 0;
+  r = poll(ufds, nfds, pending_ms);
 
   if(r < 0)
     return -1;
@@ -490,54 +494,7 @@
     }
   }
 
-#ifdef USE_WINSOCK
-  /* WinSock select() can't handle zero events.  See the comment about this in
-     Curl_check_socket(). */
-  if(fds_read.fd_count == 0 && fds_write.fd_count == 0
-     && fds_err.fd_count == 0) {
-    r = Curl_wait_ms(timeout_ms);
-    return r;
-  }
-#endif
-
-  ptimeout = (timeout_ms < 0) ? NULL : &pending_tv;
-
-  do {
-    int error;
-    if(timeout_ms > 0) {
-      pending_tv.tv_sec = pending_ms / 1000;
-      pending_tv.tv_usec = (pending_ms % 1000) * 1000;
-    }
-    else if(!timeout_ms) {
-      pending_tv.tv_sec = 0;
-      pending_tv.tv_usec = 0;
-    }
-
-#ifdef USE_WINSOCK
-    r = select((int)maxfd + 1,
-               /* WinSock select() can't handle fd_sets with zero bits set, so
-                  don't give it such arguments.  See the comment about this in
-                  Curl_check_socket().
-               */
-               fds_read.fd_count ? &fds_read : NULL,
-               fds_write.fd_count ? &fds_write : NULL,
-               fds_err.fd_count ? &fds_err : NULL, ptimeout);
-#else
-    r = select((int)maxfd + 1, &fds_read, &fds_write, &fds_err, ptimeout);
-#endif
-    if(r != -1)
-      break;
-    error = SOCKERRNO;
-    if(error && ERROR_NOT_EINTR(error))
-      break;
-    if(timeout_ms > 0) {
-      pending_ms = timeout_ms - ELAPSED_MS();
-      if(pending_ms <= 0) {
-        r = 0;  /* Simulate a "call timed out" case */
-        break;
-      }
-    }
-  } while(r == -1);
+  r = Curl_select(maxfd, &fds_read, &fds_write, &fds_err, timeout_ms);
 
   if(r < 0)
     return -1;
diff --git a/Utilities/cmcurl/lib/select.h b/Utilities/cmcurl/lib/select.h
index 9a1ba45..95181f4 100644
--- a/Utilities/cmcurl/lib/select.h
+++ b/Utilities/cmcurl/lib/select.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -72,28 +72,26 @@
    therefore defined here */
 #define CURL_CSELECT_IN2 (CURL_CSELECT_ERR << 1)
 
+int Curl_select(curl_socket_t maxfd,
+                fd_set *fds_read,
+                fd_set *fds_write,
+                fd_set *fds_err,
+                timediff_t timeout_ms);
+
 int Curl_socket_check(curl_socket_t readfd, curl_socket_t readfd2,
                       curl_socket_t writefd,
-                      time_t timeout_ms);
-
+                      timediff_t timeout_ms);
 #define SOCKET_READABLE(x,z) \
   Curl_socket_check(x, CURL_SOCKET_BAD, CURL_SOCKET_BAD, z)
 #define SOCKET_WRITABLE(x,z) \
   Curl_socket_check(CURL_SOCKET_BAD, CURL_SOCKET_BAD, x, z)
 
-int Curl_poll(struct pollfd ufds[], unsigned int nfds, int timeout_ms);
-
-/* On non-DOS and non-Winsock platforms, when Curl_ack_eintr is set,
- * EINTR condition is honored and function might exit early without
- * awaiting full timeout.  Otherwise EINTR will be ignored and full
- * timeout will elapse. */
-extern int Curl_ack_eintr;
-
-int Curl_wait_ms(int timeout_ms);
+int Curl_poll(struct pollfd ufds[], unsigned int nfds, timediff_t timeout_ms);
+int Curl_wait_ms(timediff_t timeout_ms);
 
 #ifdef TPF
 int tpf_select_libcurl(int maxfds, fd_set* reads, fd_set* writes,
-                       fd_set* excepts, struct timeval* tv);
+                       fd_set* excepts, struct timeval *tv);
 #endif
 
 /* Winsock and TPF sockets are not in range [0..FD_SETSIZE-1], which
@@ -109,7 +107,7 @@
     SET_SOCKERRNO(EINVAL); \
     return -1; \
   } \
-} WHILE_FALSE
+} while(0)
 #endif
 
 #endif /* HEADER_CURL_SELECT_H */
diff --git a/Utilities/cmcurl/lib/sendf.c b/Utilities/cmcurl/lib/sendf.c
index 5913ea4..6943fa8 100644
--- a/Utilities/cmcurl/lib/sendf.c
+++ b/Utilities/cmcurl/lib/sendf.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -36,13 +36,14 @@
 #include "sendf.h"
 #include "connect.h"
 #include "vtls/vtls.h"
-#include "ssh.h"
+#include "vssh/ssh.h"
 #include "easyif.h"
 #include "multiif.h"
 #include "non-ascii.h"
 #include "strerror.h"
 #include "select.h"
 #include "strdup.h"
+#include "http2.h"
 
 /* The last 3 #include files should be in this order */
 #include "curl_printf.h"
@@ -224,7 +225,7 @@
   (void)sockindex;
   return false;
 }
-#define pre_receive_plain(c,n) do {} WHILE_FALSE
+#define pre_receive_plain(c,n) do {} while(0)
 #define get_pre_recved(c,n,b,l) 0
 #endif /* ! USE_RECV_BEFORE_SEND_WORKAROUND */
 
@@ -266,7 +267,7 @@
     size_t len;
     char error[CURL_ERROR_SIZE + 2];
     va_start(ap, fmt);
-    mvsnprintf(error, CURL_ERROR_SIZE, fmt, ap);
+    (void)mvsnprintf(error, CURL_ERROR_SIZE, fmt, ap);
     len = strlen(error);
 
     if(data->set.errorbuffer && !data->state.errorbuf) {
@@ -497,10 +498,12 @@
      is again enabled */
   struct SingleRequest *k = &data->req;
   struct UrlState *s = &data->state;
-  char *dupl;
   unsigned int i;
   bool newtype = TRUE;
 
+  /* If this transfers over HTTP/2, pause the stream! */
+  Curl_http2_stream_pause(data, TRUE);
+
   if(s->tempcount) {
     for(i = 0; i< s->tempcount; i++) {
       if(s->tempwrite[i].type == type) {
@@ -514,42 +517,21 @@
   else
     i = 0;
 
-  if(!newtype) {
-    /* append new data to old data */
-
-    /* figure out the new size of the data to save */
-    size_t newlen = len + s->tempwrite[i].len;
-    /* allocate the new memory area */
-    char *newptr = realloc(s->tempwrite[i].buf, newlen);
-    if(!newptr)
-      return CURLE_OUT_OF_MEMORY;
-    /* copy the new data to the end of the new area */
-    memcpy(newptr + s->tempwrite[i].len, ptr, len);
-
-    /* update the pointer and the size */
-    s->tempwrite[i].buf = newptr;
-    s->tempwrite[i].len = newlen;
-  }
-  else {
-    dupl = Curl_memdup(ptr, len);
-    if(!dupl)
-      return CURLE_OUT_OF_MEMORY;
-
+  if(newtype) {
     /* store this information in the state struct for later use */
-    s->tempwrite[i].buf = dupl;
-    s->tempwrite[i].len = len;
+    Curl_dyn_init(&s->tempwrite[i].b, DYN_PAUSE_BUFFER);
     s->tempwrite[i].type = type;
 
     if(newtype)
       s->tempcount++;
   }
 
+  if(Curl_dyn_addn(&s->tempwrite[i].b, (unsigned char *)ptr, len))
+    return CURLE_OUT_OF_MEMORY;
+
   /* mark the connection as RECV paused */
   k->keepon |= KEEP_RECV_PAUSE;
 
-  DEBUGF(infof(data, "Paused %zu bytes in buffer for type %02x\n",
-               len, type));
-
   return CURLE_OK;
 }
 
@@ -611,7 +593,7 @@
         return pausewrite(data, type, ptr, len);
       }
       if(wrote != chunklen) {
-        failf(data, "Failed writing body (%zu != %zu)", wrote, chunklen);
+        failf(data, "Failure writing output to destination");
         return CURLE_WRITE_ERROR;
       }
     }
@@ -692,19 +674,20 @@
   ssize_t nread = sread(sockfd, buf, bytesfromsocket);
 
   if(-1 == nread) {
-    int err = SOCKERRNO;
-    int return_error;
+    const int err = SOCKERRNO;
+    const bool return_error =
 #ifdef USE_WINSOCK
-    return_error = WSAEWOULDBLOCK == err;
+      WSAEWOULDBLOCK == err
 #else
-    return_error = EWOULDBLOCK == err || EAGAIN == err || EINTR == err;
+      EWOULDBLOCK == err || EAGAIN == err || EINTR == err
 #endif
+      ;
+    *n = 0; /* no data returned */
     if(return_error)
       return CURLE_AGAIN;
     return CURLE_RECV_ERROR;
   }
 
-  /* we only return number of bytes read when we return OK */
   *n = nread;
   return CURLE_OK;
 }
diff --git a/Utilities/cmcurl/lib/setopt.c b/Utilities/cmcurl/lib/setopt.c
index 92cd5b2..90edf6a 100644
--- a/Utilities/cmcurl/lib/setopt.c
+++ b/Utilities/cmcurl/lib/setopt.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -77,6 +77,37 @@
   return CURLE_OK;
 }
 
+CURLcode Curl_setblobopt(struct curl_blob **blobp,
+                         const struct curl_blob *blob)
+{
+  /* free the previous storage at `blobp' and replace by a dynamic storage
+     copy of blob. If CURL_BLOB_COPY is set, the data is copied. */
+
+  Curl_safefree(*blobp);
+
+  if(blob) {
+    struct curl_blob *nblob;
+    if(blob->len > CURL_MAX_INPUT_LENGTH)
+      return CURLE_BAD_FUNCTION_ARGUMENT;
+    nblob = (struct curl_blob *)
+      malloc(sizeof(struct curl_blob) +
+             ((blob->flags & CURL_BLOB_COPY) ? blob->len : 0));
+    if(!nblob)
+      return CURLE_OUT_OF_MEMORY;
+    *nblob = *blob;
+    if(blob->flags & CURL_BLOB_COPY) {
+      /* put the data after the blob struct in memory */
+      nblob->data = (char *)nblob + sizeof(struct curl_blob);
+      memcpy(nblob->data, blob->data, blob->len);
+    }
+
+    *blobp = nblob;
+    return CURLE_OK;
+  }
+
+  return CURLE_OK;
+}
+
 static CURLcode setstropt_userpwd(char *option, char **userp, char **passwdp)
 {
   CURLcode result = CURLE_OK;
@@ -119,8 +150,11 @@
 #define C_SSLVERSION_VALUE(x) (x & 0xffff)
 #define C_SSLVERSION_MAX_VALUE(x) (x & 0xffff0000)
 
-static CURLcode vsetopt(struct Curl_easy *data, CURLoption option,
-                        va_list param)
+/*
+ * Do not make Curl_vsetopt() static: it is called from
+ * packages/OS400/ccsidcurl.c.
+ */
+CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param)
 {
   char *argptr;
   CURLcode result = CURLE_OK;
@@ -237,6 +271,9 @@
      * Do not include the body part in the output data stream.
      */
     data->set.opt_no_body = (0 != va_arg(param, long)) ? TRUE : FALSE;
+    if(data->set.opt_no_body)
+      /* in HTTP lingo, no body means using the HEAD request... */
+      data->set.method = HTTPREQ_HEAD;
     break;
   case CURLOPT_FAILONERROR:
     /*
@@ -258,13 +295,13 @@
     data->set.upload = (0 != va_arg(param, long)) ? TRUE : FALSE;
     if(data->set.upload) {
       /* If this is HTTP, PUT is what's needed to "upload" */
-      data->set.httpreq = HTTPREQ_PUT;
+      data->set.method = HTTPREQ_PUT;
       data->set.opt_no_body = FALSE; /* this is implied */
     }
     else
       /* In HTTP, the opposite of upload is GET (unless NOBODY is true as
          then this can be changed to HEAD later on) */
-      data->set.httpreq = HTTPREQ_GET;
+      data->set.method = HTTPREQ_GET;
     break;
   case CURLOPT_REQUEST_TARGET:
     result = Curl_setstropt(&data->set.str[STRING_TARGET],
@@ -312,7 +349,7 @@
      * Parse the $HOME/.netrc file
      */
     arg = va_arg(param, long);
-    if((arg < CURL_NETRC_IGNORED) || (arg > CURL_NETRC_REQUIRED))
+    if((arg < CURL_NETRC_IGNORED) || (arg >= CURL_NETRC_LAST))
       return CURLE_BAD_FUNCTION_ARGUMENT;
     data->set.use_netrc = (enum CURL_NETRC_OPTION)arg;
     break;
@@ -339,7 +376,7 @@
      * curl/curl.h header file.
      */
     arg = va_arg(param, long);
-    if((arg < CURL_TIMECOND_NONE) || (arg > CURL_TIMECOND_LASTMOD))
+    if((arg < CURL_TIMECOND_NONE) || (arg >= CURL_TIMECOND_LAST))
       return CURLE_BAD_FUNCTION_ARGUMENT;
     data->set.timecondition = (curl_TimeCond)arg;
     break;
@@ -360,7 +397,9 @@
     break;
 
   case CURLOPT_SSLVERSION:
+#ifndef CURL_DISABLE_PROXY
   case CURLOPT_PROXY_SSLVERSION:
+#endif
     /*
      * Set explicit SSL version to try to connect with, as some SSL
      * implementations are lame.
@@ -368,9 +407,11 @@
 #ifdef USE_SSL
     {
       long version, version_max;
-      struct ssl_primary_config *primary = (option == CURLOPT_SSLVERSION ?
-                                            &data->set.ssl.primary :
-                                            &data->set.proxy_ssl.primary);
+      struct ssl_primary_config *primary = &data->set.ssl.primary;
+#ifndef CURL_DISABLE_PROXY
+      if(option != CURLOPT_SSLVERSION)
+        primary = &data->set.proxy_ssl.primary;
+#endif
 
       arg = va_arg(param, long);
 
@@ -478,11 +519,11 @@
        CURLOPT_POSTFIELDS isn't used and the POST data is read off the
        callback! */
     if(va_arg(param, long)) {
-      data->set.httpreq = HTTPREQ_POST;
+      data->set.method = HTTPREQ_POST;
       data->set.opt_no_body = FALSE; /* this is implied */
     }
     else
-      data->set.httpreq = HTTPREQ_GET;
+      data->set.method = HTTPREQ_GET;
     break;
 
   case CURLOPT_COPYPOSTFIELDS:
@@ -529,7 +570,7 @@
     }
 
     data->set.postfields = data->set.str[STRING_COPYPOSTFIELDS];
-    data->set.httpreq = HTTPREQ_POST;
+    data->set.method = HTTPREQ_POST;
     break;
 
   case CURLOPT_POSTFIELDS:
@@ -539,7 +580,7 @@
     data->set.postfields = va_arg(param, void *);
     /* Release old copied data. */
     (void) Curl_setstropt(&data->set.str[STRING_COPYPOSTFIELDS], NULL);
-    data->set.httpreq = HTTPREQ_POST;
+    data->set.method = HTTPREQ_POST;
     break;
 
   case CURLOPT_POSTFIELDSIZE:
@@ -585,7 +626,7 @@
      * Set to make us do HTTP POST
      */
     data->set.httppost = va_arg(param, struct curl_httppost *);
-    data->set.httpreq = HTTPREQ_POST_FORM;
+    data->set.method = HTTPREQ_POST_FORM;
     data->set.opt_no_body = FALSE; /* this is implied */
     break;
 #endif   /* CURL_DISABLE_HTTP */
@@ -597,7 +638,7 @@
     result = Curl_mime_set_subparts(&data->set.mimepost,
                                     va_arg(param, curl_mime *), FALSE);
     if(!result) {
-      data->set.httpreq = HTTPREQ_POST_MIME;
+      data->set.method = HTTPREQ_POST_MIME;
       data->set.opt_no_body = FALSE; /* this is implied */
     }
     break;
@@ -749,7 +790,7 @@
     }
     else if(strcasecompare(argptr, "FLUSH")) {
       /* flush cookies to file, takes care of the locking */
-      Curl_flush_cookies(data, 0);
+      Curl_flush_cookies(data, FALSE);
     }
     else if(strcasecompare(argptr, "RELOAD")) {
       /* reload cookies from file */
@@ -792,7 +833,7 @@
      * Set to force us do HTTP GET
      */
     if(va_arg(param, long)) {
-      data->set.httpreq = HTTPREQ_GET;
+      data->set.method = HTTPREQ_GET;
       data->set.upload = FALSE; /* switch off upload */
       data->set.opt_no_body = FALSE; /* this is implied */
     }
@@ -806,11 +847,16 @@
     arg = va_arg(param, long);
     if(arg < CURL_HTTP_VERSION_NONE)
       return CURLE_BAD_FUNCTION_ARGUMENT;
+#ifdef ENABLE_QUIC
+    if(arg == CURL_HTTP_VERSION_3)
+      ;
+    else
+#endif
 #ifndef USE_NGHTTP2
     if(arg >= CURL_HTTP_VERSION_2)
       return CURLE_UNSUPPORTED_PROTOCOL;
 #else
-    if(arg > CURL_HTTP_VERSION_2_PRIOR_KNOWLEDGE)
+    if(arg >= CURL_HTTP_VERSION_LAST)
       return CURLE_UNSUPPORTED_PROTOCOL;
     if(arg == CURL_HTTP_VERSION_NONE)
       arg = CURL_HTTP_VERSION_2TLS;
@@ -897,7 +943,7 @@
                             va_arg(param, char *));
 
     /* we don't set
-       data->set.httpreq = HTTPREQ_CUSTOM;
+       data->set.method = HTTPREQ_CUSTOM;
        here, we continue as if we were using the already set type
        and this just changes the actual request keyword */
     break;
@@ -1101,7 +1147,7 @@
      * How do access files over FTP.
      */
     arg = va_arg(param, long);
-    if((arg < CURLFTPMETHOD_DEFAULT) || (arg > CURLFTPMETHOD_SINGLECWD))
+    if((arg < CURLFTPMETHOD_DEFAULT) || (arg >= CURLFTPMETHOD_LAST))
       return CURLE_BAD_FUNCTION_ARGUMENT;
     data->set.ftp_filemethod = (curl_ftpfile)arg;
     break;
@@ -1128,7 +1174,7 @@
 
   case CURLOPT_FTP_SSL_CCC:
     arg = va_arg(param, long);
-    if((arg < CURLFTPSSL_CCC_NONE) || (arg > CURLFTPSSL_CCC_ACTIVE))
+    if((arg < CURLFTPSSL_CCC_NONE) || (arg >= CURLFTPSSL_CCC_LAST))
       return CURLE_BAD_FUNCTION_ARGUMENT;
     data->set.ftp_ccc = (curl_ftpccc)arg;
     break;
@@ -1156,7 +1202,7 @@
      * Set a specific auth for FTP-SSL transfers.
      */
     arg = va_arg(param, long);
-    if((arg < CURLFTPAUTH_DEFAULT) || (arg > CURLFTPAUTH_TLS))
+    if((arg < CURLFTPAUTH_DEFAULT) || (arg >= CURLFTPAUTH_LAST))
       return CURLE_BAD_FUNCTION_ARGUMENT;
     data->set.ftpsslauth = (curl_ftpauth)arg;
     break;
@@ -1598,6 +1644,13 @@
     result = Curl_setstropt(&data->set.str[STRING_CERT_ORIG],
                             va_arg(param, char *));
     break;
+  case CURLOPT_SSLCERT_BLOB:
+    /*
+     * Blob that holds file name of the SSL certificate to use
+     */
+    result = Curl_setblobopt(&data->set.blobs[BLOB_CERT_ORIG],
+                             va_arg(param, struct curl_blob *));
+    break;
 #ifndef CURL_DISABLE_PROXY
   case CURLOPT_PROXY_SSLCERT:
     /*
@@ -1606,6 +1659,13 @@
     result = Curl_setstropt(&data->set.str[STRING_CERT_PROXY],
                             va_arg(param, char *));
     break;
+  case CURLOPT_PROXY_SSLCERT_BLOB:
+    /*
+     * Blob that holds file name of the SSL certificate to use for proxy
+     */
+    result = Curl_setblobopt(&data->set.blobs[BLOB_CERT_PROXY],
+                             va_arg(param, struct curl_blob *));
+    break;
 #endif
   case CURLOPT_SSLCERTTYPE:
     /*
@@ -1630,6 +1690,13 @@
     result = Curl_setstropt(&data->set.str[STRING_KEY_ORIG],
                             va_arg(param, char *));
     break;
+  case CURLOPT_SSLKEY_BLOB:
+    /*
+     * Blob that holds file name of the SSL key to use
+     */
+    result = Curl_setblobopt(&data->set.blobs[BLOB_KEY_ORIG],
+                             va_arg(param, struct curl_blob *));
+    break;
 #ifndef CURL_DISABLE_PROXY
   case CURLOPT_PROXY_SSLKEY:
     /*
@@ -1638,6 +1705,13 @@
     result = Curl_setstropt(&data->set.str[STRING_KEY_PROXY],
                             va_arg(param, char *));
     break;
+  case CURLOPT_PROXY_SSLKEY_BLOB:
+    /*
+     * Blob that holds file name of the SSL key to use for proxy
+     */
+    result = Curl_setblobopt(&data->set.blobs[BLOB_KEY_PROXY],
+                             va_arg(param, struct curl_blob *));
+    break;
 #endif
   case CURLOPT_SSLKEYTYPE:
     /*
@@ -1775,16 +1849,9 @@
     arg = va_arg(param, long);
 
     /* Obviously people are not reading documentation and too many thought
-       this argument took a boolean when it wasn't and misused it. We thus ban
-       1 as a sensible input and we warn about its use. Then we only have the
-       2 action internally stored as TRUE. */
-
-    if(1 == arg) {
-      failf(data, "CURLOPT_SSL_VERIFYHOST no longer supports 1 as value!");
-      return CURLE_BAD_FUNCTION_ARGUMENT;
-    }
-
-    data->set.ssl.primary.verifyhost = (0 != arg) ? TRUE : FALSE;
+       this argument took a boolean when it wasn't and misused it.
+       Treat 1 and 2 the same */
+    data->set.ssl.primary.verifyhost = (bool)((arg & 3) ? TRUE : FALSE);
 
     /* Update the current connection ssl_config. */
     if(data->conn) {
@@ -1799,17 +1866,8 @@
      */
     arg = va_arg(param, long);
 
-    /* Obviously people are not reading documentation and too many thought
-       this argument took a boolean when it wasn't and misused it. We thus ban
-       1 as a sensible input and we warn about its use. Then we only have the
-       2 action internally stored as TRUE. */
-
-    if(1 == arg) {
-      failf(data, "CURLOPT_SSL_VERIFYHOST no longer supports 1 as value!");
-      return CURLE_BAD_FUNCTION_ARGUMENT;
-    }
-
-    data->set.proxy_ssl.primary.verifyhost = (0 != arg)?TRUE:FALSE;
+    /* Treat both 1 and 2 as TRUE */
+    data->set.proxy_ssl.primary.verifyhost = (bool)((arg & 3)?TRUE:FALSE);
 
     /* Update the current connection proxy_ssl_config. */
     if(data->conn) {
@@ -1978,6 +2036,30 @@
     result = Curl_setstropt(&data->set.str[STRING_SSL_ISSUERCERT_ORIG],
                             va_arg(param, char *));
     break;
+  case CURLOPT_ISSUERCERT_BLOB:
+    /*
+     * Blob that holds Issuer certificate to check certificates issuer
+     */
+    result = Curl_setblobopt(&data->set.blobs[BLOB_SSL_ISSUERCERT_ORIG],
+                             va_arg(param, struct curl_blob *));
+    break;
+#ifndef CURL_DISABLE_PROXY
+  case CURLOPT_PROXY_ISSUERCERT:
+    /*
+     * Set Issuer certificate file
+     * to check certificates issuer
+     */
+    result = Curl_setstropt(&data->set.str[STRING_SSL_ISSUERCERT_PROXY],
+                            va_arg(param, char *));
+    break;
+  case CURLOPT_PROXY_ISSUERCERT_BLOB:
+    /*
+     * Blob that holds Issuer certificate to check certificates issuer
+     */
+    result = Curl_setblobopt(&data->set.blobs[BLOB_SSL_ISSUERCERT_PROXY],
+                             va_arg(param, struct curl_blob *));
+    break;
+#endif
 #ifndef CURL_DISABLE_TELNET
   case CURLOPT_TELNETOPTIONS:
     /*
@@ -2001,7 +2083,7 @@
       arg = READBUFFER_MIN;
 
     /* Resize if new size */
-    if(arg != data->set.buffer_size) {
+    if((arg != data->set.buffer_size) && data->state.buffer) {
       char *newbuff = realloc(data->state.buffer, arg + 1);
       if(!newbuff) {
         DEBUGF(fprintf(stderr, "Error: realloc of buffer failed\n"));
@@ -2131,7 +2213,7 @@
      * Make transfers attempt to use SSL/TLS.
      */
     arg = va_arg(param, long);
-    if((arg < CURLUSESSL_NONE) || (arg > CURLUSESSL_ALL))
+    if((arg < CURLUSESSL_NONE) || (arg >= CURLUSESSL_LAST))
       return CURLE_BAD_FUNCTION_ARGUMENT;
     data->set.use_ssl = (curl_usessl)arg;
     break;
@@ -2141,6 +2223,9 @@
     data->set.ssl.enable_beast =
       (bool)((arg&CURLSSLOPT_ALLOW_BEAST) ? TRUE : FALSE);
     data->set.ssl.no_revoke = !!(arg & CURLSSLOPT_NO_REVOKE);
+    data->set.ssl.no_partialchain = !!(arg & CURLSSLOPT_NO_PARTIALCHAIN);
+    data->set.ssl.revoke_best_effort = !!(arg & CURLSSLOPT_REVOKE_BEST_EFFORT);
+    data->set.ssl.native_ca_store = !!(arg & CURLSSLOPT_NATIVE_CA);
     break;
 
 #ifndef CURL_DISABLE_PROXY
@@ -2149,6 +2234,10 @@
     data->set.proxy_ssl.enable_beast =
       (bool)((arg&CURLSSLOPT_ALLOW_BEAST) ? TRUE : FALSE);
     data->set.proxy_ssl.no_revoke = !!(arg & CURLSSLOPT_NO_REVOKE);
+    data->set.proxy_ssl.no_partialchain = !!(arg & CURLSSLOPT_NO_PARTIALCHAIN);
+    data->set.proxy_ssl.native_ca_store = !!(arg & CURLSSLOPT_NATIVE_CA);
+    data->set.proxy_ssl.revoke_best_effort =
+      !!(arg & CURLSSLOPT_REVOKE_BEST_EFFORT);
     break;
 #endif
 
@@ -2251,7 +2340,9 @@
   case CURLOPT_SSL_SESSIONID_CACHE:
     data->set.ssl.primary.sessionid = (0 != va_arg(param, long)) ?
       TRUE : FALSE;
+#ifndef CURL_DISABLE_PROXY
     data->set.proxy_ssl.primary.sessionid = data->set.ssl.primary.sessionid;
+#endif
     break;
 
 #ifdef USE_SSH
@@ -2294,7 +2385,7 @@
 
   case CURLOPT_SSH_KEYFUNCTION:
     /* setting to NULL is fine since the ssh.c functions themselves will
-       then rever to use the internal default */
+       then revert to use the internal default */
     data->set.ssh_keyfunc = va_arg(param, curl_sshkeycallback);
     break;
 
@@ -2371,8 +2462,7 @@
   case CURLOPT_REDIR_PROTOCOLS:
     /* set the bitmask for the protocols that libcurl is allowed to follow to,
        as a subset of the CURLOPT_PROTOCOLS ones. That means the protocol needs
-       to be set in both bitmasks to be allowed to get redirected to. Defaults
-       to all protocols except FILE and SCP. */
+       to be set in both bitmasks to be allowed to get redirected to. */
     data->set.redir_protocols = va_arg(param, long);
     break;
 
@@ -2398,8 +2488,18 @@
     /* Set the list of mail recipients */
     data->set.mail_rcpt = va_arg(param, struct curl_slist *);
     break;
+  case CURLOPT_MAIL_RCPT_ALLLOWFAILS:
+    /* allow RCPT TO command to fail for some recipients */
+    data->set.mail_rcpt_allowfails = (0 != va_arg(param, long)) ? TRUE : FALSE;
+    break;
 #endif
 
+  case CURLOPT_SASL_AUTHZID:
+    /* Authorisation identity (identity to act as) */
+    result = Curl_setstropt(&data->set.str[STRING_SASL_AUTHZID],
+                            va_arg(param, char *));
+    break;
+
   case CURLOPT_SASL_IR:
     /* Enable/disable SASL initial response */
     data->set.sasl_ir = (0 != va_arg(param, long)) ? TRUE : FALSE;
@@ -2503,7 +2603,7 @@
 
   case CURLOPT_RTSP_SERVER_CSEQ:
     /* Same as the above, but for server-initiated requests */
-    data->state.rtsp_next_client_CSeq = va_arg(param, long);
+    data->state.rtsp_next_server_CSeq = va_arg(param, long);
     break;
 
   case CURLOPT_INTERLEAVEDATA:
@@ -2544,9 +2644,11 @@
   case CURLOPT_PROXY_TLSAUTH_USERNAME:
     result = Curl_setstropt(&data->set.str[STRING_TLSAUTH_USERNAME_PROXY],
                             va_arg(param, char *));
+#ifndef CURL_DISABLE_PROXY
     if(data->set.str[STRING_TLSAUTH_USERNAME_PROXY] &&
        !data->set.proxy_ssl.authtype)
       data->set.proxy_ssl.authtype = CURL_TLSAUTH_SRP; /* default to SRP */
+#endif
     break;
   case CURLOPT_TLSAUTH_PASSWORD:
     result = Curl_setstropt(&data->set.str[STRING_TLSAUTH_PASSWORD_ORIG],
@@ -2557,9 +2659,11 @@
   case CURLOPT_PROXY_TLSAUTH_PASSWORD:
     result = Curl_setstropt(&data->set.str[STRING_TLSAUTH_PASSWORD_PROXY],
                             va_arg(param, char *));
+#ifndef CURL_DISABLE_PROXY
     if(data->set.str[STRING_TLSAUTH_USERNAME_PROXY] &&
        !data->set.proxy_ssl.authtype)
       data->set.proxy_ssl.authtype = CURL_TLSAUTH_SRP; /* default to SRP */
+#endif
     break;
   case CURLOPT_TLSAUTH_TYPE:
     argptr = va_arg(param, char *);
@@ -2569,6 +2673,7 @@
     else
       data->set.ssl.authtype = CURL_TLSAUTH_NONE;
     break;
+#ifndef CURL_DISABLE_PROXY
   case CURLOPT_PROXY_TLSAUTH_TYPE:
     argptr = va_arg(param, char *);
     if(!argptr ||
@@ -2578,18 +2683,35 @@
       data->set.proxy_ssl.authtype = CURL_TLSAUTH_NONE;
     break;
 #endif
+#endif
 #ifdef USE_ARES
   case CURLOPT_DNS_SERVERS:
-    result = Curl_set_dns_servers(data, va_arg(param, char *));
+    result = Curl_setstropt(&data->set.str[STRING_DNS_SERVERS],
+                            va_arg(param, char *));
+    if(result)
+      return result;
+    result = Curl_set_dns_servers(data, data->set.str[STRING_DNS_SERVERS]);
     break;
   case CURLOPT_DNS_INTERFACE:
-    result = Curl_set_dns_interface(data, va_arg(param, char *));
+    result = Curl_setstropt(&data->set.str[STRING_DNS_INTERFACE],
+                            va_arg(param, char *));
+    if(result)
+      return result;
+    result = Curl_set_dns_interface(data, data->set.str[STRING_DNS_INTERFACE]);
     break;
   case CURLOPT_DNS_LOCAL_IP4:
-    result = Curl_set_dns_local_ip4(data, va_arg(param, char *));
+    result = Curl_setstropt(&data->set.str[STRING_DNS_LOCAL_IP4],
+                            va_arg(param, char *));
+    if(result)
+      return result;
+    result = Curl_set_dns_local_ip4(data, data->set.str[STRING_DNS_LOCAL_IP4]);
     break;
   case CURLOPT_DNS_LOCAL_IP6:
-    result = Curl_set_dns_local_ip6(data, va_arg(param, char *));
+    result = Curl_setstropt(&data->set.str[STRING_DNS_LOCAL_IP6],
+                            va_arg(param, char *));
+    if(result)
+      return result;
+    result = Curl_set_dns_local_ip6(data, data->set.str[STRING_DNS_LOCAL_IP6]);
     break;
 #endif
   case CURLOPT_TCP_KEEPALIVE:
@@ -2615,14 +2737,12 @@
     result = CURLE_NOT_BUILT_IN;
 #endif
     break;
-#ifdef USE_NGHTTP2
   case CURLOPT_SSL_ENABLE_NPN:
     data->set.ssl_enable_npn = (0 != va_arg(param, long)) ? TRUE : FALSE;
     break;
   case CURLOPT_SSL_ENABLE_ALPN:
     data->set.ssl_enable_alpn = (0 != va_arg(param, long)) ? TRUE : FALSE;
     break;
-#endif
 #ifdef USE_UNIX_SOCKETS
   case CURLOPT_UNIX_SOCKET_PATH:
     data->set.abstract_unix_socket = FALSE;
@@ -2728,7 +2848,8 @@
     result = Curl_setstropt(&data->set.str[STRING_ALTSVC], argptr);
     if(result)
       return result;
-    (void)Curl_altsvc_load(data->asi, argptr);
+    if(argptr)
+      (void)Curl_altsvc_load(data->asi, argptr);
     break;
   case CURLOPT_ALTSVC_CTRL:
     if(!data->asi) {
@@ -2770,7 +2891,7 @@
 
   va_start(arg, tag);
 
-  result = vsetopt(data, tag, arg);
+  result = Curl_vsetopt(data, tag, arg);
 
   va_end(arg);
   return result;
diff --git a/Utilities/cmcurl/lib/setopt.h b/Utilities/cmcurl/lib/setopt.h
index c658e04..5fc4368 100644
--- a/Utilities/cmcurl/lib/setopt.h
+++ b/Utilities/cmcurl/lib/setopt.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -23,7 +23,8 @@
  ***************************************************************************/
 
 CURLcode Curl_setstropt(char **charp, const char *s);
-CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option,
-                      va_list arg);
+CURLcode Curl_setblobopt(struct curl_blob **blobp,
+                         const struct curl_blob *blob);
+CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list arg);
 
 #endif /* HEADER_CURL_SETOPT_H */
diff --git a/Utilities/cmcurl/lib/setup-os400.h b/Utilities/cmcurl/lib/setup-os400.h
index a3c2a7b..b693cb3 100644
--- a/Utilities/cmcurl/lib/setup-os400.h
+++ b/Utilities/cmcurl/lib/setup-os400.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -200,17 +200,21 @@
 /* Some socket functions must be wrapped to process textual addresses
    like AF_UNIX. */
 
-extern int Curl_os400_connect(int sd, struct sockaddr * destaddr, int addrlen);
-extern int Curl_os400_bind(int sd, struct sockaddr * localaddr, int addrlen);
+extern int Curl_os400_connect(int sd, struct sockaddr *destaddr, int addrlen);
+extern int Curl_os400_bind(int sd, struct sockaddr *localaddr, int addrlen);
 extern int Curl_os400_sendto(int sd, char *buffer, int buflen, int flags,
-                             struct sockaddr * dstaddr, int addrlen);
+                             struct sockaddr *dstaddr, int addrlen);
 extern int Curl_os400_recvfrom(int sd, char *buffer, int buflen, int flags,
                                struct sockaddr *fromaddr, int *addrlen);
+extern int Curl_os400_getpeername(int sd, struct sockaddr *addr, int *addrlen);
+extern int Curl_os400_getsockname(int sd, struct sockaddr *addr, int *addrlen);
 
 #define connect                 Curl_os400_connect
 #define bind                    Curl_os400_bind
 #define sendto                  Curl_os400_sendto
 #define recvfrom                Curl_os400_recvfrom
+#define getpeername             Curl_os400_getpeername
+#define getsockname             Curl_os400_getsockname
 
 #ifdef HAVE_LIBZ
 #define zlibVersion             Curl_os400_zlibVersion
diff --git a/Utilities/cmcurl/lib/setup-vms.h b/Utilities/cmcurl/lib/setup-vms.h
index 6c454ae..0e39c9f 100644
--- a/Utilities/cmcurl/lib/setup-vms.h
+++ b/Utilities/cmcurl/lib/setup-vms.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -73,7 +73,7 @@
 #   endif
 #endif
 
-    struct passwd * decc_getpwuid(uid_t uid);
+    struct passwd *decc_getpwuid(uid_t uid);
 
 #ifdef __DECC
 #   if __INITIAL_POINTER_SIZE == 32
@@ -138,9 +138,9 @@
 
 static struct passwd vms_passwd_cache;
 
-static struct passwd * vms_getpwuid(uid_t uid)
+static struct passwd *vms_getpwuid(uid_t uid)
 {
-  struct passwd * my_passwd;
+  struct passwd *my_passwd;
 
 /* Hack needed to support 64 bit builds, decc_getpwnam is 32 bit only */
 #ifdef __DECC
diff --git a/Utilities/cmcurl/lib/setup-win32.h b/Utilities/cmcurl/lib/setup-win32.h
new file mode 100644
index 0000000..45b5847
--- /dev/null
+++ b/Utilities/cmcurl/lib/setup-win32.h
@@ -0,0 +1,123 @@
+#ifndef HEADER_CURL_SETUP_WIN32_H
+#define HEADER_CURL_SETUP_WIN32_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+/*
+ * Include header files for windows builds before redefining anything.
+ * Use this preprocessor block only to include or exclude windows.h,
+ * winsock2.h, ws2tcpip.h or winsock.h. Any other windows thing belongs
+ * to any other further and independent block.  Under Cygwin things work
+ * just as under linux (e.g. <sys/socket.h>) and the winsock headers should
+ * never be included when __CYGWIN__ is defined.  configure script takes
+ * care of this, not defining HAVE_WINDOWS_H, HAVE_WINSOCK_H, HAVE_WINSOCK2_H,
+ * neither HAVE_WS2TCPIP_H when __CYGWIN__ is defined.
+ */
+
+#ifdef HAVE_WINDOWS_H
+#  if defined(UNICODE) && !defined(_UNICODE)
+#    define _UNICODE
+#  endif
+#  if defined(_UNICODE) && !defined(UNICODE)
+#    define UNICODE
+#  endif
+#  include <winerror.h>
+#  include <windows.h>
+#  ifdef HAVE_WINSOCK2_H
+#    include <winsock2.h>
+#    ifdef HAVE_WS2TCPIP_H
+#      include <ws2tcpip.h>
+#    endif
+#  else
+#    ifdef HAVE_WINSOCK_H
+#      include <winsock.h>
+#    endif
+#  endif
+#  include <tchar.h>
+#  ifdef UNICODE
+     typedef wchar_t *(*curl_wcsdup_callback)(const wchar_t *str);
+#  endif
+#endif
+
+/*
+ * Define USE_WINSOCK to 2 if we have and use WINSOCK2 API, else
+ * define USE_WINSOCK to 1 if we have and use WINSOCK  API, else
+ * undefine USE_WINSOCK.
+ */
+
+#undef USE_WINSOCK
+
+#ifdef HAVE_WINSOCK2_H
+#  define USE_WINSOCK 2
+#else
+#  ifdef HAVE_WINSOCK_H
+#    define USE_WINSOCK 1
+#  endif
+#endif
+
+/*
+ * Define _WIN32_WINNT_[OS] symbols because not all Windows build systems have
+ * those symbols to compare against, and even those that do may be missing
+ * newer symbols.
+ */
+
+#ifndef _WIN32_WINNT_NT4
+#define _WIN32_WINNT_NT4            0x0400   /* Windows NT 4.0 */
+#endif
+#ifndef _WIN32_WINNT_WIN2K
+#define _WIN32_WINNT_WIN2K          0x0500   /* Windows 2000 */
+#endif
+#ifndef _WIN32_WINNT_WINXP
+#define _WIN32_WINNT_WINXP          0x0501   /* Windows XP */
+#endif
+#ifndef _WIN32_WINNT_WS03
+#define _WIN32_WINNT_WS03           0x0502   /* Windows Server 2003 */
+#endif
+#ifndef _WIN32_WINNT_WIN6
+#define _WIN32_WINNT_WIN6           0x0600   /* Windows Vista */
+#endif
+#ifndef _WIN32_WINNT_VISTA
+#define _WIN32_WINNT_VISTA          0x0600   /* Windows Vista */
+#endif
+#ifndef _WIN32_WINNT_WS08
+#define _WIN32_WINNT_WS08           0x0600   /* Windows Server 2008 */
+#endif
+#ifndef _WIN32_WINNT_LONGHORN
+#define _WIN32_WINNT_LONGHORN       0x0600   /* Windows Vista */
+#endif
+#ifndef _WIN32_WINNT_WIN7
+#define _WIN32_WINNT_WIN7           0x0601   /* Windows 7 */
+#endif
+#ifndef _WIN32_WINNT_WIN8
+#define _WIN32_WINNT_WIN8           0x0602   /* Windows 8 */
+#endif
+#ifndef _WIN32_WINNT_WINBLUE
+#define _WIN32_WINNT_WINBLUE        0x0603   /* Windows 8.1 */
+#endif
+#ifndef _WIN32_WINNT_WINTHRESHOLD
+#define _WIN32_WINNT_WINTHRESHOLD   0x0A00   /* Windows 10 */
+#endif
+#ifndef _WIN32_WINNT_WIN10
+#define _WIN32_WINNT_WIN10          0x0A00   /* Windows 10 */
+#endif
+
+#endif /* HEADER_CURL_SETUP_WIN32_H */
diff --git a/Utilities/cmcurl/lib/sha256.c b/Utilities/cmcurl/lib/sha256.c
index f9287af..ee5d273 100644
--- a/Utilities/cmcurl/lib/sha256.c
+++ b/Utilities/cmcurl/lib/sha256.c
@@ -5,7 +5,8 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2018, Florin Petriuc, <petriuc.florin@gmail.com>
+ * Copyright (C) 2017, Florin Petriuc, <petriuc.florin@gmail.com>
+ * Copyright (C) 2018 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -35,16 +36,210 @@
 #define USE_OPENSSL_SHA256
 #endif
 
-#endif
+#endif /* USE_OPENSSL */
 
-#ifdef USE_OPENSSL_SHA256
+#ifdef USE_MBEDTLS
+#include <mbedtls/version.h>
+
+#if(MBEDTLS_VERSION_NUMBER >= 0x02070000)
+  #define HAS_RESULT_CODE_BASED_FUNCTIONS
+#endif
+#endif /* USE_MBEDTLS */
+
+/* Please keep the SSL backend-specific #if branches in this order:
+ *
+ * 1. USE_OPENSSL
+ * 2. USE_GNUTLS_NETTLE
+ * 3. USE_GNUTLS
+ * 4. USE_MBEDTLS
+ * 5. USE_COMMON_CRYPTO
+ * 6. USE_WIN32_CRYPTO
+ *
+ * This ensures that the same SSL branch gets activated throughout this source
+ * file even if multiple backends are enabled at the same time.
+ */
+
+#if defined(USE_OPENSSL_SHA256)
+
 /* When OpenSSL is available we use the SHA256-function from OpenSSL */
 #include <openssl/sha.h>
+
+#elif defined(USE_GNUTLS_NETTLE)
+
+#include <nettle/sha.h>
+
+#include "curl_memory.h"
+
+/* The last #include file should be: */
+#include "memdebug.h"
+
+typedef struct sha256_ctx SHA256_CTX;
+
+static void SHA256_Init(SHA256_CTX *ctx)
+{
+  sha256_init(ctx);
+}
+
+static void SHA256_Update(SHA256_CTX *ctx,
+                          const unsigned char *data,
+                          unsigned int length)
+{
+  sha256_update(ctx, length, data);
+}
+
+static void SHA256_Final(unsigned char *digest, SHA256_CTX *ctx)
+{
+  sha256_digest(ctx, SHA256_DIGEST_SIZE, digest);
+}
+
+#elif defined(USE_GNUTLS)
+
+#include <gcrypt.h>
+
+#include "curl_memory.h"
+
+/* The last #include file should be: */
+#include "memdebug.h"
+
+typedef gcry_md_hd_t SHA256_CTX;
+
+static void SHA256_Init(SHA256_CTX *ctx)
+{
+  gcry_md_open(ctx, GCRY_MD_SHA256, 0);
+}
+
+static void SHA256_Update(SHA256_CTX *ctx,
+                          const unsigned char *data,
+                          unsigned int length)
+{
+  gcry_md_write(*ctx, data, length);
+}
+
+static void SHA256_Final(unsigned char *digest, SHA256_CTX *ctx)
+{
+  memcpy(digest, gcry_md_read(*ctx, 0), SHA256_DIGEST_LENGTH);
+  gcry_md_close(*ctx);
+}
+
+#elif defined(USE_MBEDTLS)
+
+#include <mbedtls/sha256.h>
+
+#include "curl_memory.h"
+
+/* The last #include file should be: */
+#include "memdebug.h"
+
+typedef mbedtls_sha256_context SHA256_CTX;
+
+static void SHA256_Init(SHA256_CTX *ctx)
+{
+#if !defined(HAS_RESULT_CODE_BASED_FUNCTIONS)
+  mbedtls_sha256_starts(ctx, 0);
+#else
+  (void) mbedtls_sha256_starts_ret(ctx, 0);
+#endif
+}
+
+static void SHA256_Update(SHA256_CTX *ctx,
+                          const unsigned char *data,
+                          unsigned int length)
+{
+#if !defined(HAS_RESULT_CODE_BASED_FUNCTIONS)
+  mbedtls_sha256_update(ctx, data, length);
+#else
+  (void) mbedtls_sha256_update_ret(ctx, data, length);
+#endif
+}
+
+static void SHA256_Final(unsigned char *digest, SHA256_CTX *ctx)
+{
+#if !defined(HAS_RESULT_CODE_BASED_FUNCTIONS)
+  mbedtls_sha256_finish(ctx, digest);
+#else
+  (void) mbedtls_sha256_finish_ret(ctx, digest);
+#endif
+}
+
+#elif (defined(__MAC_OS_X_VERSION_MAX_ALLOWED) && \
+              (__MAC_OS_X_VERSION_MAX_ALLOWED >= 1040)) || \
+      (defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && \
+              (__IPHONE_OS_VERSION_MAX_ALLOWED >= 20000))
+
+#include <CommonCrypto/CommonDigest.h>
+
+#include "curl_memory.h"
+
+/* The last #include file should be: */
+#include "memdebug.h"
+
+typedef CC_SHA256_CTX SHA256_CTX;
+
+static void SHA256_Init(SHA256_CTX *ctx)
+{
+  (void) CC_SHA256_Init(ctx);
+}
+
+static void SHA256_Update(SHA256_CTX *ctx,
+                          const unsigned char *data,
+                          unsigned int length)
+{
+  (void) CC_SHA256_Update(ctx, data, length);
+}
+
+static void SHA256_Final(unsigned char *digest, SHA256_CTX *ctx)
+{
+  (void) CC_SHA256_Final(digest, ctx);
+}
+
+#elif defined(USE_WIN32_CRYPTO)
+
+#include <wincrypt.h>
+
+struct sha256_ctx {
+  HCRYPTPROV hCryptProv;
+  HCRYPTHASH hHash;
+};
+typedef struct sha256_ctx SHA256_CTX;
+
+#if !defined(CALG_SHA_256)
+#define CALG_SHA_256 0x0000800c
+#endif
+
+static void SHA256_Init(SHA256_CTX *ctx)
+{
+  if(CryptAcquireContext(&ctx->hCryptProv, NULL, NULL, PROV_RSA_AES,
+                         CRYPT_VERIFYCONTEXT | CRYPT_SILENT)) {
+    CryptCreateHash(ctx->hCryptProv, CALG_SHA_256, 0, 0, &ctx->hHash);
+  }
+}
+
+static void SHA256_Update(SHA256_CTX *ctx,
+                          const unsigned char *data,
+                          unsigned int length)
+{
+  CryptHashData(ctx->hHash, (unsigned char *) data, length, 0);
+}
+
+static void SHA256_Final(unsigned char *digest, SHA256_CTX *ctx)
+{
+  unsigned long length = 0;
+
+  CryptGetHashParam(ctx->hHash, HP_HASHVAL, NULL, &length, 0);
+  if(length == SHA256_DIGEST_LENGTH)
+    CryptGetHashParam(ctx->hHash, HP_HASHVAL, digest, &length, 0);
+
+  if(ctx->hHash)
+    CryptDestroyHash(ctx->hHash);
+
+  if(ctx->hCryptProv)
+    CryptReleaseContext(ctx->hCryptProv, 0);
+}
+
 #else
 
 /* When no other crypto library is available we use this code segment */
 
-/* ===== start - public domain SHA256 implementation ===== */
 /* This is based on SHA256 implementation in LibTomCrypt that was released into
  * public domain by Tom St Denis. */
 
@@ -86,7 +281,7 @@
 } while(0)
 #endif
 
-typedef struct sha256_state {
+struct sha256_state {
 #ifdef HAVE_LONGLONG
   unsigned long long length;
 #else
@@ -94,8 +289,10 @@
 #endif
   unsigned long state[8], curlen;
   unsigned char buf[64];
-} SHA256_CTX;
-/* the K array */
+};
+typedef struct sha256_state SHA256_CTX;
+
+/* The K array */
 static const unsigned long K[64] = {
   0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL, 0x3956c25bUL,
   0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL, 0xd807aa98UL, 0x12835b01UL,
@@ -111,6 +308,7 @@
   0x682e6ff3UL, 0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL,
   0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL
 };
+
 /* Various logical functions */
 #define RORc(x, y) \
 (((((unsigned long)(x) & 0xFFFFFFFFUL) >> (unsigned long)((y) & 31)) | \
@@ -123,13 +321,15 @@
 #define Sigma1(x)   (S(x, 6) ^ S(x, 11) ^ S(x, 25))
 #define Gamma0(x)   (S(x, 7) ^ S(x, 18) ^ R(x, 3))
 #define Gamma1(x)   (S(x, 17) ^ S(x, 19) ^ R(x, 10))
-/* compress 512-bits */
+
+/* Compress 512-bits */
 static int sha256_compress(struct sha256_state *md,
                            unsigned char *buf)
 {
   unsigned long S[8], W[64];
   int i;
-  /* copy state into S */
+
+  /* Copy state into S */
   for(i = 0; i < 8; i++) {
     S[i] = md->state[i];
   }
@@ -141,6 +341,7 @@
     W[i] = Gamma1(W[i - 2]) + W[i - 7] + Gamma0(W[i - 15]) +
       W[i - 16];
   }
+
   /* Compress */
 #define RND(a,b,c,d,e,f,g,h,i)                                  \
   unsigned long t0 = h + Sigma1(e) + Ch(e, f, g) + K[i] + W[i]; \
@@ -153,12 +354,15 @@
     t = S[7]; S[7] = S[6]; S[6] = S[5]; S[5] = S[4];
     S[4] = S[3]; S[3] = S[2]; S[2] = S[1]; S[1] = S[0]; S[0] = t;
   }
-  /* feedback */
+
+  /* Feedback */
   for(i = 0; i < 8; i++) {
     md->state[i] = md->state[i] + S[i];
   }
+
   return 0;
 }
+
 /* Initialize the hash state */
 static void SHA256_Init(struct sha256_state *md)
 {
@@ -173,7 +377,8 @@
   md->state[6] = 0x1F83D9ABUL;
   md->state[7] = 0x5BE0CD19UL;
 }
-/**
+
+/*
    Process a block of memory though the hash
    @param md     The hash state
    @param in     The data to hash
@@ -185,6 +390,7 @@
                          unsigned long inlen)
 {
   unsigned long n;
+
 #define block_size 64
   if(md->curlen > sizeof(md->buf))
     return -1;
@@ -210,9 +416,11 @@
       }
     }
   }
+
   return 0;
 }
-/**
+
+/*
    Terminate the hash to get the digest
    @param md  The hash state
    @param out [out] The destination of the hash (32 bytes)
@@ -222,13 +430,17 @@
                         struct sha256_state *md)
 {
   int i;
+
   if(md->curlen >= sizeof(md->buf))
     return -1;
-  /* increase the length of the message */
+
+  /* Increase the length of the message */
   md->length += md->curlen * 8;
-  /* append the '1' bit */
+
+  /* Append the '1' bit */
   md->buf[md->curlen++] = (unsigned char)0x80;
-  /* if the length is currently above 56 bytes we append zeros
+
+  /* If the length is currently above 56 bytes we append zeros
    * then compress.  Then we can fall back to padding zeros and length
    * encoding like normal.
    */
@@ -239,29 +451,44 @@
     sha256_compress(md, md->buf);
     md->curlen = 0;
   }
-  /* pad up to 56 bytes of zeroes */
+
+  /* Pad up to 56 bytes of zeroes */
   while(md->curlen < 56) {
     md->buf[md->curlen++] = (unsigned char)0;
   }
-  /* store length */
+
+  /* Store length */
   WPA_PUT_BE64(md->buf + 56, md->length);
   sha256_compress(md, md->buf);
-  /* copy output */
+
+  /* Copy output */
   for(i = 0; i < 8; i++)
     WPA_PUT_BE32(out + (4 * i), md->state[i]);
+
   return 0;
 }
-/* ===== end - public domain SHA256 implementation ===== */
 
-#endif
+#endif /* CRYPTO LIBS */
 
-void Curl_sha256it(unsigned char *outbuffer, /* 32 unsigned chars */
-                   const unsigned char *input)
+/*
+ * Curl_sha256it()
+ *
+ * Generates a SHA256 hash for the given input data.
+ *
+ * Parameters:
+ *
+ * output [in/out] - The output buffer.
+ * input  [in]     - The input data.
+ * length [in]     - The input length.
+ */
+void Curl_sha256it(unsigned char *output, const unsigned char *input,
+                   const size_t length)
 {
   SHA256_CTX ctx;
+
   SHA256_Init(&ctx);
-  SHA256_Update(&ctx, input, curlx_uztoui(strlen((char *)input)));
-  SHA256_Final(outbuffer, &ctx);
+  SHA256_Update(&ctx, input, curlx_uztoui(length));
+  SHA256_Final(output, &ctx);
 }
 
 #endif /* CURL_DISABLE_CRYPTO_AUTH */
diff --git a/Utilities/cmcurl/lib/share.c b/Utilities/cmcurl/lib/share.c
index 3d51086..a2d8960 100644
--- a/Utilities/cmcurl/lib/share.c
+++ b/Utilities/cmcurl/lib/share.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -70,7 +70,7 @@
   case CURLSHOPT_SHARE:
     /* this is a type this share will share */
     type = va_arg(param, int);
-    share->specifier |= (1<<type);
+
     switch(type) {
     case CURL_LOCK_DATA_DNS:
       break;
@@ -102,7 +102,7 @@
 #endif
       break;
 
-    case CURL_LOCK_DATA_CONNECT:     /* not supported (yet) */
+    case CURL_LOCK_DATA_CONNECT:
       if(Curl_conncache_init(&share->conn_cache, 103))
         res = CURLSHE_NOMEM;
       break;
@@ -116,6 +116,8 @@
     default:
       res = CURLSHE_BAD_OPTION;
     }
+    if(!res)
+      share->specifier |= (1<<type);
     break;
 
   case CURLSHOPT_UNSHARE:
diff --git a/Utilities/cmcurl/lib/slist.c b/Utilities/cmcurl/lib/slist.c
index 392b84d..d27fbe1 100644
--- a/Utilities/cmcurl/lib/slist.c
+++ b/Utilities/cmcurl/lib/slist.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
diff --git a/Utilities/cmcurl/lib/slist.h b/Utilities/cmcurl/lib/slist.h
index d73dbf6..799b3c0 100644
--- a/Utilities/cmcurl/lib/slist.h
+++ b/Utilities/cmcurl/lib/slist.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2013, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
diff --git a/Utilities/cmcurl/lib/smb.c b/Utilities/cmcurl/lib/smb.c
index 76c99a2..d493adc 100644
--- a/Utilities/cmcurl/lib/smb.c
+++ b/Utilities/cmcurl/lib/smb.c
@@ -6,7 +6,7 @@
  *                             \___|\___/|_| \_\_____|
  *
  * Copyright (C) 2014, Bill Nagel <wnagel@tycoint.com>, Exacq Technologies
- * Copyright (C) 2016-2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 2016-2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -64,8 +64,7 @@
 static CURLcode smb_done(struct connectdata *conn, CURLcode status,
                          bool premature);
 static CURLcode smb_disconnect(struct connectdata *conn, bool dead);
-static int smb_getsock(struct connectdata *conn, curl_socket_t *socks,
-                       int numsocks);
+static int smb_getsock(struct connectdata *conn, curl_socket_t *socks);
 static CURLcode smb_parse_url_path(struct connectdata *conn);
 
 /*
@@ -607,6 +606,7 @@
 {
   struct smb_conn *smbc = &conn->proto.smbc;
   CURLcode result;
+  *msg = NULL; /* if it returns early */
 
   /* Check if there is data in the transfer buffer */
   if(!smbc->send_size && smbc->upload_size) {
@@ -682,7 +682,8 @@
 
   switch(smbc->state) {
   case SMB_NEGOTIATE:
-    if(h->status || smbc->got < sizeof(*nrsp) + sizeof(smbc->challenge) - 1) {
+    if((smbc->got < sizeof(*nrsp) + sizeof(smbc->challenge) - 1) ||
+       h->status) {
       connclose(conn, "SMB: negotiation failed");
       return CURLE_COULDNT_CONNECT;
     }
@@ -785,6 +786,8 @@
   case SMB_OPEN:
     if(h->status || smbc->got < sizeof(struct smb_nt_create_response)) {
       req->result = CURLE_REMOTE_FILE_NOT_FOUND;
+      if(h->status == smb_swap32(SMB_ERR_NOACCESS))
+        req->result = CURLE_REMOTE_ACCESS_DENIED;
       next_state = SMB_TREE_DISCONNECT;
       break;
     }
@@ -934,12 +937,8 @@
   return CURLE_OK;
 }
 
-static int smb_getsock(struct connectdata *conn, curl_socket_t *socks,
-                       int numsocks)
+static int smb_getsock(struct connectdata *conn, curl_socket_t *socks)
 {
-  if(!numsocks)
-    return GETSOCK_BLANK;
-
   socks[0] = conn->sock[FIRSTSOCKET];
   return GETSOCK_READSOCK(0) | GETSOCK_WRITESOCK(0);
 }
@@ -957,7 +956,6 @@
 
 static CURLcode smb_parse_url_path(struct connectdata *conn)
 {
-  CURLcode result = CURLE_OK;
   struct Curl_easy *data = conn->data;
   struct smb_request *req = data->req.protop;
   struct smb_conn *smbc = &conn->proto.smbc;
@@ -965,7 +963,8 @@
   char *slash;
 
   /* URL decode the path */
-  result = Curl_urldecode(data, data->state.up.path, 0, &path, NULL, TRUE);
+  CURLcode result = Curl_urldecode(data, data->state.up.path, 0, &path, NULL,
+                                   REJECT_CTRL);
   if(result)
     return result;
 
diff --git a/Utilities/cmcurl/lib/smb.h b/Utilities/cmcurl/lib/smb.h
index 9ce6b56..136a89c 100644
--- a/Utilities/cmcurl/lib/smb.h
+++ b/Utilities/cmcurl/lib/smb.h
@@ -8,7 +8,7 @@
  *                             \___|\___/|_| \_\_____|
  *
  * Copyright (C) 2014, Bill Nagel <wnagel@tycoint.com>, Exacq Technologies
- * Copyright (C) 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 2018 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -193,7 +193,6 @@
   unsigned int ext_file_attributes;
   curl_off_t allocation_size;
   curl_off_t end_of_file;
-
 } PACK;
 
 struct smb_read {
diff --git a/Utilities/cmcurl/lib/smtp.c b/Utilities/cmcurl/lib/smtp.c
index 4a3462b..685513b 100644
--- a/Utilities/cmcurl/lib/smtp.c
+++ b/Utilities/cmcurl/lib/smtp.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -27,6 +27,9 @@
  * RFC4752 The Kerberos V5 ("GSSAPI") SASL Mechanism
  * RFC4954 SMTP Authentication
  * RFC5321 SMTP protocol
+ * RFC5890 Internationalized Domain Names for Applications (IDNA)
+ * RFC6531 SMTP Extension for Internationalized Email
+ * RFC6532 Internationalized Email Headers
  * RFC6749 OAuth 2.0 Authorization Framework
  * RFC8314 Use of TLS for Email Submission and Access
  * Draft   SMTP URL Interface   <draft-earhart-url-smtp-00.txt>
@@ -95,13 +98,14 @@
 static CURLcode smtp_connect(struct connectdata *conn, bool *done);
 static CURLcode smtp_disconnect(struct connectdata *conn, bool dead);
 static CURLcode smtp_multi_statemach(struct connectdata *conn, bool *done);
-static int smtp_getsock(struct connectdata *conn, curl_socket_t *socks,
-                        int numsocks);
+static int smtp_getsock(struct connectdata *conn, curl_socket_t *socks);
 static CURLcode smtp_doing(struct connectdata *conn, bool *dophase_done);
 static CURLcode smtp_setup_connection(struct connectdata *conn);
 static CURLcode smtp_parse_url_options(struct connectdata *conn);
 static CURLcode smtp_parse_url_path(struct connectdata *conn);
 static CURLcode smtp_parse_custom_request(struct connectdata *conn);
+static CURLcode smtp_parse_address(struct connectdata *conn, const char *fqma,
+                                   char **address, struct hostname *host);
 static CURLcode smtp_perform_auth(struct connectdata *conn, const char *mech,
                                   const char *initresp);
 static CURLcode smtp_continue_auth(struct connectdata *conn, const char *resp);
@@ -179,7 +183,7 @@
   conn->handler = &Curl_handler_smtps;
 
   /* Set the connection's upgraded to TLS flag */
-  conn->tls_upgraded = TRUE;
+  conn->bits.tls_upgraded = TRUE;
 }
 #else
 #define smtp_to_smtps(x) Curl_nop_stmt
@@ -359,10 +363,8 @@
  */
 static CURLcode smtp_perform_starttls(struct connectdata *conn)
 {
-  CURLcode result = CURLE_OK;
-
   /* Send the STARTTLS command */
-  result = Curl_pp_sendf(&conn->proto.smtpc.pp, "%s", "STARTTLS");
+  CURLcode result = Curl_pp_sendf(&conn->proto.smtpc.pp, "%s", "STARTTLS");
 
   if(!result)
     state(conn, SMTP_STARTTLS);
@@ -378,11 +380,10 @@
  */
 static CURLcode smtp_perform_upgrade_tls(struct connectdata *conn)
 {
-  CURLcode result = CURLE_OK;
-  struct smtp_conn *smtpc = &conn->proto.smtpc;
-
   /* Start the SSL connection */
-  result = Curl_ssl_connect_nonblocking(conn, FIRSTSOCKET, &smtpc->ssldone);
+  struct smtp_conn *smtpc = &conn->proto.smtpc;
+  CURLcode result = Curl_ssl_connect_nonblocking(conn, FIRSTSOCKET,
+                                                 &smtpc->ssldone);
 
   if(!result) {
     if(smtpc->state != SMTP_UPGRADETLS)
@@ -485,13 +486,55 @@
   struct Curl_easy *data = conn->data;
   struct SMTP *smtp = data->req.protop;
 
-  /* Send the command */
-  if(smtp->rcpt)
-    result = Curl_pp_sendf(&conn->proto.smtpc.pp, "%s %s",
-                           smtp->custom && smtp->custom[0] != '\0' ?
-                           smtp->custom : "VRFY",
-                           smtp->rcpt->data);
+  if(smtp->rcpt) {
+    /* We notify the server we are sending UTF-8 data if a) it supports the
+       SMTPUTF8 extension and b) The mailbox contains UTF-8 charaacters, in
+       either the local address or host name parts. This is regardless of
+       whether the host name is encoded using IDN ACE */
+    bool utf8 = FALSE;
+
+    if((!smtp->custom) || (!smtp->custom[0])) {
+      char *address = NULL;
+      struct hostname host = { NULL, NULL, NULL, NULL };
+
+      /* Parse the mailbox to verify into the local address and host name
+         parts, converting the host name to an IDN A-label if necessary */
+      result = smtp_parse_address(conn, smtp->rcpt->data,
+                                  &address, &host);
+      if(result)
+        return result;
+
+      /* Establish whether we should report SMTPUTF8 to the server for this
+         mailbox as per RFC-6531 sect. 3.1 point 6 */
+      utf8 = (conn->proto.smtpc.utf8_supported) &&
+             ((host.encalloc) || (!Curl_is_ASCII_name(address)) ||
+              (!Curl_is_ASCII_name(host.name)));
+
+      /* Send the VRFY command (Note: The host name part may be absent when the
+         host is a local system) */
+      result = Curl_pp_sendf(&conn->proto.smtpc.pp, "VRFY %s%s%s%s",
+                             address,
+                             host.name ? "@" : "",
+                             host.name ? host.name : "",
+                             utf8 ? " SMTPUTF8" : "");
+
+      Curl_free_idnconverted_hostname(&host);
+      free(address);
+    }
+    else {
+      /* Establish whether we should report that we support SMTPUTF8 for EXPN
+         commands to the server as per RFC-6531 sect. 3.1 point 6 */
+      utf8 = (conn->proto.smtpc.utf8_supported) &&
+             (!strcmp(smtp->custom, "EXPN"));
+
+      /* Send the custom recipient based command such as the EXPN command */
+      result = Curl_pp_sendf(&conn->proto.smtpc.pp, "%s %s%s", smtp->custom,
+                             smtp->rcpt->data,
+                             utf8 ? " SMTPUTF8" : "");
+    }
+  }
   else
+    /* Send the non-recipient based command such as HELP */
     result = Curl_pp_sendf(&conn->proto.smtpc.pp, "%s",
                            smtp->custom && smtp->custom[0] != '\0' ?
                            smtp->custom : "HELP");
@@ -516,22 +559,83 @@
   CURLcode result = CURLE_OK;
   struct Curl_easy *data = conn->data;
 
+  /* We notify the server we are sending UTF-8 data if a) it supports the
+     SMTPUTF8 extension and b) The mailbox contains UTF-8 charaacters, in
+     either the local address or host name parts. This is regardless of
+     whether the host name is encoded using IDN ACE */
+  bool utf8 = FALSE;
+
   /* Calculate the FROM parameter */
-  if(!data->set.str[STRING_MAIL_FROM])
+  if(data->set.str[STRING_MAIL_FROM]) {
+    char *address = NULL;
+    struct hostname host = { NULL, NULL, NULL, NULL };
+
+    /* Parse the FROM mailbox into the local address and host name parts,
+       converting the host name to an IDN A-label if necessary */
+    result = smtp_parse_address(conn, data->set.str[STRING_MAIL_FROM],
+                                &address, &host);
+    if(result)
+      return result;
+
+    /* Establish whether we should report SMTPUTF8 to the server for this
+       mailbox as per RFC-6531 sect. 3.1 point 4 and sect. 3.4 */
+    utf8 = (conn->proto.smtpc.utf8_supported) &&
+           ((host.encalloc) || (!Curl_is_ASCII_name(address)) ||
+            (!Curl_is_ASCII_name(host.name)));
+
+    if(host.name) {
+      from = aprintf("<%s@%s>", address, host.name);
+
+      Curl_free_idnconverted_hostname(&host);
+    }
+    else
+      /* An invalid mailbox was provided but we'll simply let the server worry
+         about that and reply with a 501 error */
+      from = aprintf("<%s>", address);
+
+    free(address);
+  }
+  else
     /* Null reverse-path, RFC-5321, sect. 3.6.3 */
     from = strdup("<>");
-  else if(data->set.str[STRING_MAIL_FROM][0] == '<')
-    from = aprintf("%s", data->set.str[STRING_MAIL_FROM]);
-  else
-    from = aprintf("<%s>", data->set.str[STRING_MAIL_FROM]);
 
   if(!from)
     return CURLE_OUT_OF_MEMORY;
 
   /* Calculate the optional AUTH parameter */
   if(data->set.str[STRING_MAIL_AUTH] && conn->proto.smtpc.sasl.authused) {
-    if(data->set.str[STRING_MAIL_AUTH][0] != '\0')
-      auth = aprintf("%s", data->set.str[STRING_MAIL_AUTH]);
+    if(data->set.str[STRING_MAIL_AUTH][0] != '\0') {
+      char *address = NULL;
+      struct hostname host = { NULL, NULL, NULL, NULL };
+
+      /* Parse the AUTH mailbox into the local address and host name parts,
+         converting the host name to an IDN A-label if necessary */
+      result = smtp_parse_address(conn, data->set.str[STRING_MAIL_AUTH],
+                                  &address, &host);
+      if(result) {
+        free(from);
+        return result;
+      }
+
+      /* Establish whether we should report SMTPUTF8 to the server for this
+         mailbox as per RFC-6531 sect. 3.1 point 4 and sect. 3.4 */
+      if((!utf8) && (conn->proto.smtpc.utf8_supported) &&
+         ((host.encalloc) || (!Curl_is_ASCII_name(address)) ||
+          (!Curl_is_ASCII_name(host.name))))
+        utf8 = TRUE;
+
+      if(host.name) {
+        auth = aprintf("<%s@%s>", address, host.name);
+
+        Curl_free_idnconverted_hostname(&host);
+      }
+      else
+        /* An invalid mailbox was provided but we'll simply let the server
+           worry about it */
+        auth = aprintf("<%s>", address);
+
+      free(address);
+    }
     else
       /* Empty AUTH, RFC-2554, sect. 5 */
       auth = strdup("<>");
@@ -565,6 +669,7 @@
     if(result) {
       free(from);
       free(auth);
+
       return result;
     }
 
@@ -587,19 +692,33 @@
     }
   }
 
+  /* If the mailboxes in the FROM and AUTH parameters don't include a UTF-8
+     based address then quickly scan through the recipient list and check if
+     any there do, as we need to correctly identify our support for SMTPUTF8
+     in the envelope, as per RFC-6531 sect. 3.4 */
+  if(conn->proto.smtpc.utf8_supported && !utf8) {
+    struct SMTP *smtp = data->req.protop;
+    struct curl_slist *rcpt = smtp->rcpt;
+
+    while(rcpt && !utf8) {
+      /* Does the host name contain non-ASCII characters? */
+      if(!Curl_is_ASCII_name(rcpt->data))
+        utf8 = TRUE;
+
+      rcpt = rcpt->next;
+    }
+  }
+
   /* Send the MAIL command */
-  if(!auth && !size)
-    result = Curl_pp_sendf(&conn->proto.smtpc.pp,
-                           "MAIL FROM:%s", from);
-  else if(auth && !size)
-    result = Curl_pp_sendf(&conn->proto.smtpc.pp,
-                           "MAIL FROM:%s AUTH=%s", from, auth);
-  else if(auth && size)
-    result = Curl_pp_sendf(&conn->proto.smtpc.pp,
-                           "MAIL FROM:%s AUTH=%s SIZE=%s", from, auth, size);
-  else
-    result = Curl_pp_sendf(&conn->proto.smtpc.pp,
-                           "MAIL FROM:%s SIZE=%s", from, size);
+  result = Curl_pp_sendf(&conn->proto.smtpc.pp,
+                         "MAIL FROM:%s%s%s%s%s%s",
+                         from,                 /* Mandatory                 */
+                         auth ? " AUTH=" : "", /* Optional on AUTH support  */
+                         auth ? auth : "",     /*                           */
+                         size ? " SIZE=" : "", /* Optional on SIZE support  */
+                         size ? size : "",     /*                           */
+                         utf8 ? " SMTPUTF8"    /* Internationalised mailbox */
+                               : "");          /* included in our envelope  */
 
   free(from);
   free(auth);
@@ -623,14 +742,28 @@
   CURLcode result = CURLE_OK;
   struct Curl_easy *data = conn->data;
   struct SMTP *smtp = data->req.protop;
+  char *address = NULL;
+  struct hostname host = { NULL, NULL, NULL, NULL };
+
+  /* Parse the recipient mailbox into the local address and host name parts,
+     converting the host name to an IDN A-label if necessary */
+  result = smtp_parse_address(conn, smtp->rcpt->data,
+                              &address, &host);
+  if(result)
+    return result;
 
   /* Send the RCPT TO command */
-  if(smtp->rcpt->data[0] == '<')
-    result = Curl_pp_sendf(&conn->proto.smtpc.pp, "RCPT TO:%s",
-                           smtp->rcpt->data);
+  if(host.name)
+    result = Curl_pp_sendf(&conn->proto.smtpc.pp, "RCPT TO:<%s@%s>", address,
+                           host.name);
   else
-    result = Curl_pp_sendf(&conn->proto.smtpc.pp, "RCPT TO:<%s>",
-                           smtp->rcpt->data);
+    /* An invalid mailbox was provided but we'll simply let the server worry
+       about that and reply with a 501 error */
+    result = Curl_pp_sendf(&conn->proto.smtpc.pp, "RCPT TO:<%s>", address);
+
+  Curl_free_idnconverted_hostname(&host);
+  free(address);
+
   if(!result)
     state(conn, SMTP_RCPT);
 
@@ -645,10 +778,8 @@
  */
 static CURLcode smtp_perform_quit(struct connectdata *conn)
 {
-  CURLcode result = CURLE_OK;
-
   /* Send the QUIT command */
-  result = Curl_pp_sendf(&conn->proto.smtpc.pp, "%s", "QUIT");
+  CURLcode result = Curl_pp_sendf(&conn->proto.smtpc.pp, "%s", "QUIT");
 
   if(!result)
     state(conn, SMTP_QUIT);
@@ -720,7 +851,7 @@
       result = CURLE_REMOTE_ACCESS_DENIED;
     }
   }
-  else {
+  else if(len >= 4) {
     line += 4;
     len -= 4;
 
@@ -732,6 +863,10 @@
     else if(len >= 4 && !memcmp(line, "SIZE", 4))
       smtpc->size_supported = TRUE;
 
+    /* Does the server support the UTF-8 capability? */
+    else if(len >= 8 && !memcmp(line, "SMTPUTF8", 8))
+      smtpc->utf8_supported = TRUE;
+
     /* Does the server support authentication? */
     else if(len >= 5 && !memcmp(line, "AUTH ", 5)) {
       smtpc->auth_supported = TRUE;
@@ -791,6 +926,10 @@
         result = smtp_perform_authentication(conn);
     }
   }
+  else {
+    failf(data, "Unexpectedly short EHLO response");
+    result = CURLE_WEIRD_SERVER_REPLY;
+  }
 
   return result;
 }
@@ -917,25 +1056,53 @@
   CURLcode result = CURLE_OK;
   struct Curl_easy *data = conn->data;
   struct SMTP *smtp = data->req.protop;
+  bool is_smtp_err = FALSE;
+  bool is_smtp_blocking_err = FALSE;
 
   (void)instate; /* no use for this yet */
 
-  if(smtpcode/100 != 2) {
-    failf(data, "RCPT failed: %d", smtpcode);
-    result = CURLE_SEND_ERROR;
+  is_smtp_err = (smtpcode/100 != 2) ? TRUE : FALSE;
+
+  /* If there's multiple RCPT TO to be issued, it's possible to ignore errors
+     and proceed with only the valid addresses. */
+  is_smtp_blocking_err =
+    (is_smtp_err && !data->set.mail_rcpt_allowfails) ? TRUE : FALSE;
+
+  if(is_smtp_err) {
+    /* Remembering the last failure which we can report if all "RCPT TO" have
+       failed and we cannot proceed. */
+    smtp->rcpt_last_error = smtpcode;
+
+    if(is_smtp_blocking_err) {
+      failf(data, "RCPT failed: %d", smtpcode);
+      result = CURLE_SEND_ERROR;
+    }
   }
   else {
+    /* Some RCPT TO commands have succeeded. */
+    smtp->rcpt_had_ok = TRUE;
+  }
+
+  if(!is_smtp_blocking_err) {
     smtp->rcpt = smtp->rcpt->next;
 
     if(smtp->rcpt)
       /* Send the next RCPT TO command */
       result = smtp_perform_rcpt_to(conn);
     else {
-      /* Send the DATA command */
-      result = Curl_pp_sendf(&conn->proto.smtpc.pp, "%s", "DATA");
+      /* We weren't able to issue a successful RCPT TO command while going
+         over recipients (potentially multiple). Sending back last error. */
+      if(!smtp->rcpt_had_ok) {
+        failf(data, "RCPT failed: %d (last error)", smtp->rcpt_last_error);
+        result = CURLE_SEND_ERROR;
+      }
+      else {
+        /* Send the DATA command */
+        result = Curl_pp_sendf(&conn->proto.smtpc.pp, "%s", "DATA");
 
-      if(!result)
-        state(conn, SMTP_DATA);
+        if(!result)
+          state(conn, SMTP_DATA);
+      }
     }
   }
 
@@ -1119,10 +1286,9 @@
 }
 
 /* For the SMTP "protocol connect" and "doing" phases only */
-static int smtp_getsock(struct connectdata *conn, curl_socket_t *socks,
-                        int numsocks)
+static int smtp_getsock(struct connectdata *conn, curl_socket_t *socks)
 {
-  return Curl_pp_getsock(&conn->proto.smtpc.pp, socks, numsocks);
+  return Curl_pp_getsock(&conn->proto.smtpc.pp, socks);
 }
 
 /***********************************************************************
@@ -1290,6 +1456,12 @@
   /* Store the first recipient (or NULL if not specified) */
   smtp->rcpt = data->set.mail_rcpt;
 
+  /* Track of whether we've successfully sent at least one RCPT TO command */
+  smtp->rcpt_had_ok = FALSE;
+
+  /* Track of the last error we've received by sending RCPT TO command */
+  smtp->rcpt_last_error = 0;
+
   /* Initial data character is the first character in line: it is implicitly
      preceded by a virtual CRLF. */
   smtp->trailing_crlf = TRUE;
@@ -1445,7 +1617,7 @@
   CURLcode result;
 
   /* Clear the TLS upgraded flag */
-  conn->tls_upgraded = FALSE;
+  conn->bits.tls_upgraded = FALSE;
 
   /* Initialise the SMTP layer */
   result = smtp_init(conn);
@@ -1517,7 +1689,8 @@
   }
 
   /* URL decode the path and use it as the domain in our EHLO */
-  return Curl_urldecode(conn->data, path, 0, &smtpc->domain, NULL, TRUE);
+  return Curl_urldecode(conn->data, path, 0, &smtpc->domain, NULL,
+                        REJECT_CTRL);
 }
 
 /***********************************************************************
@@ -1535,7 +1708,77 @@
 
   /* URL decode the custom request */
   if(custom)
-    result = Curl_urldecode(data, custom, 0, &smtp->custom, NULL, TRUE);
+    result = Curl_urldecode(data, custom, 0, &smtp->custom, NULL, REJECT_CTRL);
+
+  return result;
+}
+
+/***********************************************************************
+ *
+ * smtp_parse_address()
+ *
+ * Parse the fully qualified mailbox address into a local address part and the
+ * host name, converting the host name to an IDN A-label, as per RFC-5890, if
+ * necessary.
+ *
+ * Parameters:
+ *
+ * conn  [in]              - The connection handle.
+ * fqma  [in]              - The fully qualified mailbox address (which may or
+ *                           may not contain UTF-8 characters).
+ * address        [in/out] - A new allocated buffer which holds the local
+ *                           address part of the mailbox. This buffer must be
+ *                           free'ed by the caller.
+ * host           [in/out] - The host name structure that holds the original,
+ *                           and optionally encoded, host name.
+ *                           Curl_free_idnconverted_hostname() must be called
+ *                           once the caller has finished with the structure.
+ *
+ * Returns CURLE_OK on success.
+ *
+ * Notes:
+ *
+ * Should a UTF-8 host name require conversion to IDN ACE and we cannot honor
+ * that conversion then we shall return success. This allow the caller to send
+ * the data to the server as a U-label (as per RFC-6531 sect. 3.2).
+ *
+ * If an mailbox '@' separator cannot be located then the mailbox is considered
+ * to be either a local mailbox or an invalid mailbox (depending on what the
+ * calling function deems it to be) then the input will simply be returned in
+ * the address part with the host name being NULL.
+ */
+static CURLcode smtp_parse_address(struct connectdata *conn, const char *fqma,
+                                   char **address, struct hostname *host)
+{
+  CURLcode result = CURLE_OK;
+  size_t length;
+
+  /* Duplicate the fully qualified email address so we can manipulate it,
+     ensuring it doesn't contain the delimiters if specified */
+  char *dup = strdup(fqma[0] == '<' ? fqma + 1  : fqma);
+  if(!dup)
+    return CURLE_OUT_OF_MEMORY;
+
+  length = strlen(dup);
+  if(dup[length - 1] == '>')
+    dup[length - 1] = '\0';
+
+  /* Extract the host name from the address (if we can) */
+  host->name = strpbrk(dup, "@");
+  if(host->name) {
+    *host->name = '\0';
+    host->name = host->name + 1;
+
+    /* Attempt to convert the host name to IDN ACE */
+    (void) Curl_idnconvert_hostname(conn, host);
+
+    /* If Curl_idnconvert_hostname() fails then we shall attempt to continue
+       and send the host name using UTF-8 rather than as 7-bit ACE (which is
+       our preference) */
+  }
+
+  /* Extract the local address from the mailbox */
+  *address = dup;
 
   return result;
 }
diff --git a/Utilities/cmcurl/lib/smtp.h b/Utilities/cmcurl/lib/smtp.h
index b67340a..164a175 100644
--- a/Utilities/cmcurl/lib/smtp.h
+++ b/Utilities/cmcurl/lib/smtp.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 2009 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 2009 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -55,6 +55,9 @@
   curl_pp_transfer transfer;
   char *custom;            /* Custom Request */
   struct curl_slist *rcpt; /* Recipient list */
+  bool rcpt_had_ok;        /* Whether any of RCPT TO commands (depends on
+                              total number of recipients) succeeded so far */
+  int rcpt_last_error;     /* The last error received for RCPT TO command */
   size_t eob;              /* Number of bytes of the EOB (End Of Body) that
                               have been received so far */
   bool trailing_crlf;      /* Specifies if the tailing CRLF is present */
@@ -71,6 +74,8 @@
   bool tls_supported;      /* StartTLS capability supported by server */
   bool size_supported;     /* If server supports SIZE extension according to
                               RFC 1870 */
+  bool utf8_supported;     /* If server supports SMTPUTF8 extension according
+                              to RFC 6531 */
   bool auth_supported;     /* AUTH capability supported by server */
 };
 
diff --git a/Utilities/cmcurl/lib/sockaddr.h b/Utilities/cmcurl/lib/sockaddr.h
index db14680..b037ee0 100644
--- a/Utilities/cmcurl/lib/sockaddr.h
+++ b/Utilities/cmcurl/lib/sockaddr.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2009, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
diff --git a/Utilities/cmcurl/lib/socketpair.c b/Utilities/cmcurl/lib/socketpair.c
new file mode 100644
index 0000000..1ec0d75
--- /dev/null
+++ b/Utilities/cmcurl/lib/socketpair.c
@@ -0,0 +1,121 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+#include "socketpair.h"
+
+#ifndef HAVE_SOCKETPAIR
+#ifdef WIN32
+/*
+ * This is a socketpair() implementation for Windows.
+ */
+#include <string.h>
+#include <winsock2.h>
+#include <ws2tcpip.h>
+#include <windows.h>
+#include <io.h>
+#else
+#ifdef HAVE_NETDB_H
+#include <netdb.h>
+#endif
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h> /* IPPROTO_TCP */
+#endif
+#ifdef HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+#ifndef INADDR_LOOPBACK
+#define INADDR_LOOPBACK 0x7f000001
+#endif /* !INADDR_LOOPBACK */
+#endif /* !WIN32 */
+
+/* The last 3 #include files should be in this order */
+#include "curl_printf.h"
+#include "curl_memory.h"
+#include "memdebug.h"
+
+int Curl_socketpair(int domain, int type, int protocol,
+                    curl_socket_t socks[2])
+{
+  union {
+    struct sockaddr_in inaddr;
+    struct sockaddr addr;
+  } a;
+  curl_socket_t listener;
+  curl_socklen_t addrlen = sizeof(a.inaddr);
+  int reuse = 1;
+  char data[2][12];
+  ssize_t dlen;
+  (void)domain;
+  (void)type;
+  (void)protocol;
+
+  listener = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
+  if(listener == CURL_SOCKET_BAD)
+    return -1;
+
+  memset(&a, 0, sizeof(a));
+  a.inaddr.sin_family = AF_INET;
+  a.inaddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
+  a.inaddr.sin_port = 0;
+
+  socks[0] = socks[1] = CURL_SOCKET_BAD;
+
+  if(setsockopt(listener, SOL_SOCKET, SO_REUSEADDR,
+                (char *)&reuse, (curl_socklen_t)sizeof(reuse)) == -1)
+    goto error;
+  if(bind(listener, &a.addr, sizeof(a.inaddr)) == -1)
+    goto error;
+  if(getsockname(listener, &a.addr, &addrlen) == -1)
+    goto error;
+  if(listen(listener, 1) == -1)
+    goto error;
+  socks[0] = socket(AF_INET, SOCK_STREAM, 0);
+  if(socks[0] == CURL_SOCKET_BAD)
+    goto error;
+  if(connect(socks[0], &a.addr, sizeof(a.inaddr)) == -1)
+    goto error;
+  socks[1] = accept(listener, NULL, NULL);
+  if(socks[1] == CURL_SOCKET_BAD)
+    goto error;
+
+  /* verify that nothing else connected */
+  msnprintf(data[0], sizeof(data[0]), "%p", socks);
+  dlen = strlen(data[0]);
+  if(swrite(socks[0], data[0], dlen) != dlen)
+    goto error;
+  if(sread(socks[1], data[1], sizeof(data[1])) != dlen)
+    goto error;
+  if(memcmp(data[0], data[1], dlen))
+    goto error;
+
+  sclose(listener);
+  return 0;
+
+  error:
+  sclose(listener);
+  sclose(socks[0]);
+  sclose(socks[1]);
+  return -1;
+}
+
+#endif /* ! HAVE_SOCKETPAIR */
diff --git a/Utilities/cmcurl/lib/socketpair.h b/Utilities/cmcurl/lib/socketpair.h
new file mode 100644
index 0000000..be9fb24
--- /dev/null
+++ b/Utilities/cmcurl/lib/socketpair.h
@@ -0,0 +1,36 @@
+#ifndef HEADER_CURL_SOCKETPAIR_H
+#define HEADER_CURL_SOCKETPAIR_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+#ifndef HAVE_SOCKETPAIR
+int Curl_socketpair(int domain, int type, int protocol,
+                    curl_socket_t socks[2]);
+#else
+#define Curl_socketpair(a,b,c,d) socketpair(a,b,c,d)
+#endif
+
+/* Defined here to allow specific build configs to disable it completely */
+#define USE_SOCKETPAIR 1
+
+#endif /* HEADER_CURL_SOCKETPAIR_H */
diff --git a/Utilities/cmcurl/lib/socks.c b/Utilities/cmcurl/lib/socks.c
index d8fcc3b..b2215fe 100644
--- a/Utilities/cmcurl/lib/socks.c
+++ b/Utilities/cmcurl/lib/socks.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -37,16 +37,19 @@
 #include "connect.h"
 #include "timeval.h"
 #include "socks.h"
+#include "multiif.h" /* for getsock macros */
 
-/* The last #include file should be: */
+/* The last 3 #include files should be in this order */
+#include "curl_printf.h"
+#include "curl_memory.h"
 #include "memdebug.h"
 
+#if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI)
 /*
  * Helper read-from-socket functions. Does the same as Curl_read() but it
  * blocks until all bytes amount of buffersize will be read. No more, no less.
  *
- * This is STUPID BLOCKING behaviour which we frown upon, but right now this
- * is what we have...
+ * This is STUPID BLOCKING behavior. Only used by the SOCKS GSSAPI functions.
  */
 int Curl_blockread_all(struct connectdata *conn, /* connection data */
                        curl_socket_t sockfd,     /* read from this socket */
@@ -59,13 +62,15 @@
   int result;
   *n = 0;
   for(;;) {
-    timediff_t timeleft = Curl_timeleft(conn->data, NULL, TRUE);
-    if(timeleft < 0) {
+    timediff_t timeout_ms = Curl_timeleft(conn->data, NULL, TRUE);
+    if(timeout_ms < 0) {
       /* we already got the timeout */
       result = CURLE_OPERATION_TIMEDOUT;
       break;
     }
-    if(SOCKET_READABLE(sockfd, timeleft) <= 0) {
+    if(!timeout_ms)
+      timeout_ms = TIMEDIFF_T_MAX;
+    if(SOCKET_READABLE(sockfd, timeout_ms) <= 0) {
       result = ~CURLE_OK;
       break;
     }
@@ -92,6 +97,81 @@
   }
   return result;
 }
+#endif
+
+#ifndef DEBUGBUILD
+#define sxstate(x,y) socksstate(x,y)
+#else
+#define sxstate(x,y) socksstate(x,y, __LINE__)
+#endif
+
+
+/* always use this function to change state, to make debugging easier */
+static void socksstate(struct connectdata *conn,
+                       enum connect_t state
+#ifdef DEBUGBUILD
+                       , int lineno
+#endif
+)
+{
+  enum connect_t oldstate = conn->cnnct.state;
+#if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS)
+  /* synced with the state list in urldata.h */
+  static const char * const statename[] = {
+    "INIT",
+    "SOCKS_INIT",
+    "SOCKS_SEND",
+    "SOCKS_READ_INIT",
+    "SOCKS_READ",
+    "GSSAPI_INIT",
+    "AUTH_INIT",
+    "AUTH_SEND",
+    "AUTH_READ",
+    "REQ_INIT",
+    "RESOLVING",
+    "RESOLVED",
+    "RESOLVE_REMOTE",
+    "REQ_SEND",
+    "REQ_SENDING",
+    "REQ_READ",
+    "REQ_READ_MORE",
+    "DONE"
+  };
+#endif
+
+  if(oldstate == state)
+    /* don't bother when the new state is the same as the old state */
+    return;
+
+  conn->cnnct.state = state;
+
+#if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS)
+  infof(conn->data,
+        "SXSTATE: %s => %s conn %p; line %d\n",
+        statename[oldstate], statename[conn->cnnct.state], conn,
+        lineno);
+#endif
+}
+
+int Curl_SOCKS_getsock(struct connectdata *conn, curl_socket_t *sock,
+                       int sockindex)
+{
+  int rc = 0;
+  sock[0] = conn->sock[sockindex];
+  switch(conn->cnnct.state) {
+  case CONNECT_RESOLVING:
+  case CONNECT_SOCKS_READ:
+  case CONNECT_AUTH_READ:
+  case CONNECT_REQ_READ:
+  case CONNECT_REQ_READ_MORE:
+    rc = GETSOCK_READSOCK(0);
+    break;
+  default:
+    rc = GETSOCK_WRITESOCK(0);
+    break;
+  }
+  return rc;
+}
 
 /*
 * This function logs in to a SOCKS4 proxy and sends the specifics to the final
@@ -108,62 +188,91 @@
                      const char *hostname,
                      int remote_port,
                      int sockindex,
-                     struct connectdata *conn)
+                     struct connectdata *conn,
+                     bool *done)
 {
   const bool protocol4a =
     (conn->socks_proxy.proxytype == CURLPROXY_SOCKS4A) ? TRUE : FALSE;
-#define SOCKS4REQLEN 262
-  unsigned char socksreq[SOCKS4REQLEN]; /* room for SOCKS4 request incl. user
-                                           id */
-  CURLcode code;
-  curl_socket_t sock = conn->sock[sockindex];
+  unsigned char *socksreq = &conn->cnnct.socksreq[0];
+  CURLcode result;
+  curl_socket_t sockfd = conn->sock[sockindex];
   struct Curl_easy *data = conn->data;
+  struct connstate *sx = &conn->cnnct;
+  struct Curl_dns_entry *dns = NULL;
+  ssize_t actualread;
+  ssize_t written;
 
-  if(Curl_timeleft(data, NULL, TRUE) < 0) {
-    /* time-out, bail out, go home */
-    failf(data, "Connection time-out");
-    return CURLE_OPERATION_TIMEDOUT;
-  }
+  if(!SOCKS_STATE(sx->state) && !*done)
+    sxstate(conn, CONNECT_SOCKS_INIT);
 
-  if(conn->bits.httpproxy)
-    infof(conn->data, "SOCKS4%s: connecting to HTTP proxy %s port %d\n",
-          protocol4a ? "a" : "", hostname, remote_port);
+  switch(sx->state) {
+  case CONNECT_SOCKS_INIT:
+    /* SOCKS4 can only do IPv4, insist! */
+    conn->ip_version = CURL_IPRESOLVE_V4;
+    if(conn->bits.httpproxy)
+      infof(conn->data, "SOCKS4%s: connecting to HTTP proxy %s port %d\n",
+            protocol4a ? "a" : "", hostname, remote_port);
 
-  (void)curlx_nonblock(sock, FALSE);
+    infof(data, "SOCKS4 communication to %s:%d\n", hostname, remote_port);
 
-  infof(data, "SOCKS4 communication to %s:%d\n", hostname, remote_port);
+    /*
+     * Compose socks4 request
+     *
+     * Request format
+     *
+     *     +----+----+----+----+----+----+----+----+----+----+....+----+
+     *     | VN | CD | DSTPORT |      DSTIP        | USERID       |NULL|
+     *     +----+----+----+----+----+----+----+----+----+----+....+----+
+     * # of bytes:  1    1      2              4           variable       1
+     */
 
-  /*
-   * Compose socks4 request
-   *
-   * Request format
-   *
-   *     +----+----+----+----+----+----+----+----+----+----+....+----+
-   *     | VN | CD | DSTPORT |      DSTIP        | USERID       |NULL|
-   *     +----+----+----+----+----+----+----+----+----+----+....+----+
-   * # of bytes:  1    1      2              4           variable       1
-   */
+    socksreq[0] = 4; /* version (SOCKS4) */
+    socksreq[1] = 1; /* connect */
+    socksreq[2] = (unsigned char)((remote_port >> 8) & 0xff); /* PORT MSB */
+    socksreq[3] = (unsigned char)(remote_port & 0xff);        /* PORT LSB */
 
-  socksreq[0] = 4; /* version (SOCKS4) */
-  socksreq[1] = 1; /* connect */
-  socksreq[2] = (unsigned char)((remote_port >> 8) & 0xff); /* PORT MSB */
-  socksreq[3] = (unsigned char)(remote_port & 0xff);        /* PORT LSB */
+    /* DNS resolve only for SOCKS4, not SOCKS4a */
+    if(!protocol4a) {
+      enum resolve_t rc =
+        Curl_resolv(conn, hostname, remote_port, FALSE, &dns);
 
-  /* DNS resolve only for SOCKS4, not SOCKS4a */
-  if(!protocol4a) {
-    struct Curl_dns_entry *dns;
-    Curl_addrinfo *hp = NULL;
-    int rc;
+      if(rc == CURLRESOLV_ERROR)
+        return CURLE_COULDNT_RESOLVE_PROXY;
+      else if(rc == CURLRESOLV_PENDING) {
+        sxstate(conn, CONNECT_RESOLVING);
+        infof(data, "SOCKS4 non-blocking resolve of %s\n", hostname);
+        return CURLE_OK;
+      }
+      sxstate(conn, CONNECT_RESOLVED);
+      goto CONNECT_RESOLVED;
+    }
 
-    rc = Curl_resolv(conn, hostname, remote_port, FALSE, &dns);
+    /* socks4a doesn't resolve anything locally */
+    sxstate(conn, CONNECT_REQ_INIT);
+    goto CONNECT_REQ_INIT;
 
-    if(rc == CURLRESOLV_ERROR)
-      return CURLE_COULDNT_RESOLVE_PROXY;
+  case CONNECT_RESOLVING:
+    /* check if we have the name resolved by now */
+    dns = Curl_fetch_addr(conn, hostname, (int)conn->port);
 
-    if(rc == CURLRESOLV_PENDING)
-      /* ignores the return code, but 'dns' remains NULL on failure */
-      (void)Curl_resolver_wait_resolv(conn, &dns);
-
+    if(dns) {
+#ifdef CURLRES_ASYNCH
+      conn->async.dns = dns;
+      conn->async.done = TRUE;
+#endif
+      infof(data, "Hostname '%s' was found\n", hostname);
+      sxstate(conn, CONNECT_RESOLVED);
+    }
+    else {
+      result = Curl_resolv_check(data->conn, &dns);
+      if(!dns)
+        return result;
+    }
+    /* FALLTHROUGH */
+  CONNECT_RESOLVED:
+  case CONNECT_RESOLVED: {
+    struct Curl_addrinfo *hp = NULL;
+    char buf[64];
     /*
      * We cannot use 'hostent' as a struct that Curl_resolv() returns.  It
      * returns a Curl_addrinfo pointer that may not always look the same.
@@ -171,7 +280,6 @@
     if(dns)
       hp = dns->addr;
     if(hp) {
-      char buf[64];
       Curl_printable_address(hp, buf, sizeof(buf));
 
       if(hp->ai_family == AF_INET) {
@@ -187,7 +295,6 @@
       }
       else {
         hp = NULL; /* fail! */
-
         failf(data, "SOCKS4 connection to %s not supported\n", buf);
       }
 
@@ -199,149 +306,171 @@
       return CURLE_COULDNT_RESOLVE_HOST;
     }
   }
-
-  /*
-   * This is currently not supporting "Identification Protocol (RFC1413)".
-   */
-  socksreq[8] = 0; /* ensure empty userid is NUL-terminated */
-  if(proxy_user) {
-    size_t plen = strlen(proxy_user);
-    if(plen >= sizeof(socksreq) - 8) {
-      failf(data, "Too long SOCKS proxy name, can't use!\n");
-      return CURLE_COULDNT_CONNECT;
-    }
-    /* copy the proxy name WITH trailing zero */
-    memcpy(socksreq + 8, proxy_user, plen + 1);
-  }
-
-  /*
-   * Make connection
-   */
-  {
-    int result;
-    ssize_t actualread;
-    ssize_t written;
-    ssize_t hostnamelen = 0;
-    ssize_t packetsize = 9 +
-      strlen((char *)socksreq + 8); /* size including NUL */
-
-    /* If SOCKS4a, set special invalid IP address 0.0.0.x */
-    if(protocol4a) {
-      socksreq[4] = 0;
-      socksreq[5] = 0;
-      socksreq[6] = 0;
-      socksreq[7] = 1;
-      /* If still enough room in buffer, also append hostname */
-      hostnamelen = (ssize_t)strlen(hostname) + 1; /* length including NUL */
-      if(packetsize + hostnamelen <= SOCKS4REQLEN)
-        strcpy((char *)socksreq + packetsize, hostname);
-      else
-        hostnamelen = 0; /* Flag: hostname did not fit in buffer */
-    }
-
-    /* Send request */
-    code = Curl_write_plain(conn, sock, (char *)socksreq,
-                            packetsize + hostnamelen,
-                            &written);
-    if(code || (written != packetsize + hostnamelen)) {
-      failf(data, "Failed to send SOCKS4 connect request.");
-      return CURLE_COULDNT_CONNECT;
-    }
-    if(protocol4a && hostnamelen == 0) {
-      /* SOCKS4a with very long hostname - send that name separately */
-      hostnamelen = (ssize_t)strlen(hostname) + 1;
-      code = Curl_write_plain(conn, sock, (char *)hostname, hostnamelen,
-                              &written);
-      if(code || (written != hostnamelen)) {
-        failf(data, "Failed to send SOCKS4 connect request.");
+    /* FALLTHROUGH */
+  CONNECT_REQ_INIT:
+  case CONNECT_REQ_INIT:
+    /*
+     * This is currently not supporting "Identification Protocol (RFC1413)".
+     */
+    socksreq[8] = 0; /* ensure empty userid is NUL-terminated */
+    if(proxy_user) {
+      size_t plen = strlen(proxy_user);
+      if(plen >= sizeof(sx->socksreq) - 8) {
+        failf(data, "Too long SOCKS proxy name, can't use!\n");
         return CURLE_COULDNT_CONNECT;
       }
-    }
-
-    packetsize = 8; /* receive data size */
-
-    /* Receive response */
-    result = Curl_blockread_all(conn, sock, (char *)socksreq, packetsize,
-                                &actualread);
-    if(result || (actualread != packetsize)) {
-      failf(data, "Failed to receive SOCKS4 connect request ack.");
-      return CURLE_COULDNT_CONNECT;
+      /* copy the proxy name WITH trailing zero */
+      memcpy(socksreq + 8, proxy_user, plen + 1);
     }
 
     /*
-     * Response format
-     *
-     *     +----+----+----+----+----+----+----+----+
-     *     | VN | CD | DSTPORT |      DSTIP        |
-     *     +----+----+----+----+----+----+----+----+
-     * # of bytes:  1    1      2              4
-     *
-     * VN is the version of the reply code and should be 0. CD is the result
-     * code with one of the following values:
-     *
-     * 90: request granted
-     * 91: request rejected or failed
-     * 92: request rejected because SOCKS server cannot connect to
-     *     identd on the client
-     * 93: request rejected because the client program and identd
-     *     report different user-ids
+     * Make connection
      */
+    {
+      ssize_t packetsize = 9 +
+        strlen((char *)socksreq + 8); /* size including NUL */
 
-    /* wrong version ? */
-    if(socksreq[0] != 0) {
-      failf(data,
-            "SOCKS4 reply has wrong version, version should be 0.");
+      /* If SOCKS4a, set special invalid IP address 0.0.0.x */
+      if(protocol4a) {
+        ssize_t hostnamelen = 0;
+        socksreq[4] = 0;
+        socksreq[5] = 0;
+        socksreq[6] = 0;
+        socksreq[7] = 1;
+        /* append hostname */
+        hostnamelen = (ssize_t)strlen(hostname) + 1; /* length including NUL */
+        if(hostnamelen <= 255)
+          strcpy((char *)socksreq + packetsize, hostname);
+        else {
+          failf(data, "SOCKS4: too long host name");
+          return CURLE_COULDNT_CONNECT;
+        }
+        packetsize += hostnamelen;
+      }
+      sx->outp = socksreq;
+      sx->outstanding = packetsize;
+      sxstate(conn, CONNECT_REQ_SENDING);
+    }
+    /* FALLTHROUGH */
+  case CONNECT_REQ_SENDING:
+    /* Send request */
+    result = Curl_write_plain(conn, sockfd, (char *)sx->outp,
+                              sx->outstanding, &written);
+    if(result && (CURLE_AGAIN != result)) {
+      failf(data, "Failed to send SOCKS4 connect request.");
       return CURLE_COULDNT_CONNECT;
     }
+    if(written != sx->outstanding) {
+      /* not done, remain in state */
+      sx->outstanding -= written;
+      sx->outp += written;
+      return CURLE_OK;
+    }
 
-    /* Result */
-    switch(socksreq[1]) {
-    case 90:
-      infof(data, "SOCKS4%s request granted.\n", protocol4a?"a":"");
-      break;
-    case 91:
-      failf(data,
-            "Can't complete SOCKS4 connection to %d.%d.%d.%d:%d. (%d)"
-            ", request rejected or failed.",
-            (unsigned char)socksreq[4], (unsigned char)socksreq[5],
-            (unsigned char)socksreq[6], (unsigned char)socksreq[7],
-            (((unsigned char)socksreq[2] << 8) | (unsigned char)socksreq[3]),
-            (unsigned char)socksreq[1]);
-      return CURLE_COULDNT_CONNECT;
-    case 92:
-      failf(data,
-            "Can't complete SOCKS4 connection to %d.%d.%d.%d:%d. (%d)"
-            ", request rejected because SOCKS server cannot connect to "
-            "identd on the client.",
-            (unsigned char)socksreq[4], (unsigned char)socksreq[5],
-            (unsigned char)socksreq[6], (unsigned char)socksreq[7],
-            (((unsigned char)socksreq[2] << 8) | (unsigned char)socksreq[3]),
-            (unsigned char)socksreq[1]);
-      return CURLE_COULDNT_CONNECT;
-    case 93:
-      failf(data,
-            "Can't complete SOCKS4 connection to %d.%d.%d.%d:%d. (%d)"
-            ", request rejected because the client program and identd "
-            "report different user-ids.",
-            (unsigned char)socksreq[4], (unsigned char)socksreq[5],
-            (unsigned char)socksreq[6], (unsigned char)socksreq[7],
-            (((unsigned char)socksreq[2] << 8) | (unsigned char)socksreq[3]),
-            (unsigned char)socksreq[1]);
-      return CURLE_COULDNT_CONNECT;
-    default:
-      failf(data,
-            "Can't complete SOCKS4 connection to %d.%d.%d.%d:%d. (%d)"
-            ", Unknown.",
-            (unsigned char)socksreq[4], (unsigned char)socksreq[5],
-            (unsigned char)socksreq[6], (unsigned char)socksreq[7],
-            (((unsigned char)socksreq[2] << 8) | (unsigned char)socksreq[3]),
-            (unsigned char)socksreq[1]);
+    /* done sending! */
+    sx->outstanding = 8; /* receive data size */
+    sx->outp = socksreq;
+    sxstate(conn, CONNECT_SOCKS_READ);
+
+    /* FALLTHROUGH */
+  case CONNECT_SOCKS_READ:
+    /* Receive response */
+    result = Curl_read_plain(sockfd, (char *)sx->outp,
+                             sx->outstanding, &actualread);
+    if(result && (CURLE_AGAIN != result)) {
+      failf(data, "SOCKS4: Failed receiving connect request ack: %s",
+            curl_easy_strerror(result));
       return CURLE_COULDNT_CONNECT;
     }
+    else if(!result && !actualread) {
+      /* connection closed */
+      failf(data, "connection to proxy closed");
+      return CURLE_COULDNT_CONNECT;
+    }
+    else if(actualread != sx->outstanding) {
+      /* remain in reading state */
+      sx->outstanding -= actualread;
+      sx->outp += actualread;
+      return CURLE_OK;
+    }
+    sxstate(conn, CONNECT_DONE);
+    break;
+  default: /* lots of unused states in SOCKS4 */
+    break;
   }
 
-  (void)curlx_nonblock(sock, TRUE);
+  /*
+   * Response format
+   *
+   *     +----+----+----+----+----+----+----+----+
+   *     | VN | CD | DSTPORT |      DSTIP        |
+   *     +----+----+----+----+----+----+----+----+
+   * # of bytes:  1    1      2              4
+   *
+   * VN is the version of the reply code and should be 0. CD is the result
+   * code with one of the following values:
+   *
+   * 90: request granted
+   * 91: request rejected or failed
+   * 92: request rejected because SOCKS server cannot connect to
+   *     identd on the client
+   * 93: request rejected because the client program and identd
+   *     report different user-ids
+   */
 
+  /* wrong version ? */
+  if(socksreq[0] != 0) {
+    failf(data,
+          "SOCKS4 reply has wrong version, version should be 0.");
+    return CURLE_COULDNT_CONNECT;
+  }
+
+  /* Result */
+  switch(socksreq[1]) {
+  case 90:
+    infof(data, "SOCKS4%s request granted.\n", protocol4a?"a":"");
+    break;
+  case 91:
+    failf(data,
+          "Can't complete SOCKS4 connection to %d.%d.%d.%d:%d. (%d)"
+          ", request rejected or failed.",
+          (unsigned char)socksreq[4], (unsigned char)socksreq[5],
+          (unsigned char)socksreq[6], (unsigned char)socksreq[7],
+          (((unsigned char)socksreq[2] << 8) | (unsigned char)socksreq[3]),
+          (unsigned char)socksreq[1]);
+    return CURLE_COULDNT_CONNECT;
+  case 92:
+    failf(data,
+          "Can't complete SOCKS4 connection to %d.%d.%d.%d:%d. (%d)"
+          ", request rejected because SOCKS server cannot connect to "
+          "identd on the client.",
+          (unsigned char)socksreq[4], (unsigned char)socksreq[5],
+          (unsigned char)socksreq[6], (unsigned char)socksreq[7],
+          (((unsigned char)socksreq[2] << 8) | (unsigned char)socksreq[3]),
+          (unsigned char)socksreq[1]);
+    return CURLE_COULDNT_CONNECT;
+  case 93:
+    failf(data,
+          "Can't complete SOCKS4 connection to %d.%d.%d.%d:%d. (%d)"
+          ", request rejected because the client program and identd "
+          "report different user-ids.",
+          (unsigned char)socksreq[4], (unsigned char)socksreq[5],
+          (unsigned char)socksreq[6], (unsigned char)socksreq[7],
+          (((unsigned char)socksreq[2] << 8) | (unsigned char)socksreq[3]),
+          (unsigned char)socksreq[1]);
+    return CURLE_COULDNT_CONNECT;
+  default:
+    failf(data,
+          "Can't complete SOCKS4 connection to %d.%d.%d.%d:%d. (%d)"
+          ", Unknown.",
+          (unsigned char)socksreq[4], (unsigned char)socksreq[5],
+          (unsigned char)socksreq[6], (unsigned char)socksreq[7],
+          (((unsigned char)socksreq[2] << 8) | (unsigned char)socksreq[3]),
+          (unsigned char)socksreq[1]);
+    return CURLE_COULDNT_CONNECT;
+  }
+
+  *done = TRUE;
   return CURLE_OK; /* Proxy was successful! */
 }
 
@@ -354,7 +483,8 @@
                      const char *hostname,
                      int remote_port,
                      int sockindex,
-                     struct connectdata *conn)
+                     struct connectdata *conn,
+                     bool *done)
 {
   /*
     According to the RFC1928, section "6.  Replies". This is what a SOCK5
@@ -372,140 +502,162 @@
     o  REP    Reply field:
     o  X'00' succeeded
   */
-
-  unsigned char socksreq[600]; /* room for large user/pw (255 max each) */
+  unsigned char *socksreq = &conn->cnnct.socksreq[0];
+  char dest[256] = "unknown";  /* printable hostname:port */
   int idx;
   ssize_t actualread;
   ssize_t written;
-  int result;
-  CURLcode code;
-  curl_socket_t sock = conn->sock[sockindex];
+  CURLcode result;
+  curl_socket_t sockfd = conn->sock[sockindex];
   struct Curl_easy *data = conn->data;
-  timediff_t timeout;
   bool socks5_resolve_local =
     (conn->socks_proxy.proxytype == CURLPROXY_SOCKS5) ? TRUE : FALSE;
   const size_t hostname_len = strlen(hostname);
   ssize_t len = 0;
   const unsigned long auth = data->set.socks5auth;
   bool allow_gssapi = FALSE;
+  struct connstate *sx = &conn->cnnct;
+  struct Curl_dns_entry *dns = NULL;
 
-  if(conn->bits.httpproxy)
-    infof(conn->data, "SOCKS5: connecting to HTTP proxy %s port %d\n",
-          hostname, remote_port);
+  if(!SOCKS_STATE(sx->state) && !*done)
+    sxstate(conn, CONNECT_SOCKS_INIT);
 
-  /* RFC1928 chapter 5 specifies max 255 chars for domain name in packet */
-  if(!socks5_resolve_local && hostname_len > 255) {
-    infof(conn->data, "SOCKS5: server resolving disabled for hostnames of "
-          "length > 255 [actual len=%zu]\n", hostname_len);
-    socks5_resolve_local = TRUE;
-  }
+  switch(sx->state) {
+  case CONNECT_SOCKS_INIT:
+    if(conn->bits.httpproxy)
+      infof(conn->data, "SOCKS5: connecting to HTTP proxy %s port %d\n",
+            hostname, remote_port);
 
-  /* get timeout */
-  timeout = Curl_timeleft(data, NULL, TRUE);
+    /* RFC1928 chapter 5 specifies max 255 chars for domain name in packet */
+    if(!socks5_resolve_local && hostname_len > 255) {
+      infof(conn->data, "SOCKS5: server resolving disabled for hostnames of "
+            "length > 255 [actual len=%zu]\n", hostname_len);
+      socks5_resolve_local = TRUE;
+    }
 
-  if(timeout < 0) {
-    /* time-out, bail out, go home */
-    failf(data, "Connection time-out");
-    return CURLE_OPERATION_TIMEDOUT;
-  }
-
-  (void)curlx_nonblock(sock, TRUE);
-
-  /* wait until socket gets connected */
-  result = SOCKET_WRITABLE(sock, timeout);
-
-  if(-1 == result) {
-    failf(conn->data, "SOCKS5: no connection here");
-    return CURLE_COULDNT_CONNECT;
-  }
-  if(0 == result) {
-    failf(conn->data, "SOCKS5: connection timeout");
-    return CURLE_OPERATION_TIMEDOUT;
-  }
-
-  if(result & CURL_CSELECT_ERR) {
-    failf(conn->data, "SOCKS5: error occurred during connection");
-    return CURLE_COULDNT_CONNECT;
-  }
-
-  if(auth & ~(CURLAUTH_BASIC | CURLAUTH_GSSAPI))
-    infof(conn->data,
-        "warning: unsupported value passed to CURLOPT_SOCKS5_AUTH: %lu\n",
-        auth);
-  if(!(auth & CURLAUTH_BASIC))
-    /* disable username/password auth */
-    proxy_user = NULL;
+    if(auth & ~(CURLAUTH_BASIC | CURLAUTH_GSSAPI))
+      infof(conn->data,
+            "warning: unsupported value passed to CURLOPT_SOCKS5_AUTH: %lu\n",
+            auth);
+    if(!(auth & CURLAUTH_BASIC))
+      /* disable username/password auth */
+      proxy_user = NULL;
 #if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI)
-  if(auth & CURLAUTH_GSSAPI)
-    allow_gssapi = TRUE;
+    if(auth & CURLAUTH_GSSAPI)
+      allow_gssapi = TRUE;
 #endif
 
-  idx = 0;
-  socksreq[idx++] = 5;   /* version */
-  idx++;                 /* reserve for the number of authentication methods */
-  socksreq[idx++] = 0;   /* no authentication */
-  if(allow_gssapi)
-    socksreq[idx++] = 1; /* GSS-API */
-  if(proxy_user)
-    socksreq[idx++] = 2; /* username/password */
-  /* write the number of authentication methods */
-  socksreq[1] = (unsigned char) (idx - 2);
+    idx = 0;
+    socksreq[idx++] = 5;   /* version */
+    idx++;                 /* number of authentication methods */
+    socksreq[idx++] = 0;   /* no authentication */
+    if(allow_gssapi)
+      socksreq[idx++] = 1; /* GSS-API */
+    if(proxy_user)
+      socksreq[idx++] = 2; /* username/password */
+    /* write the number of authentication methods */
+    socksreq[1] = (unsigned char) (idx - 2);
 
-  (void)curlx_nonblock(sock, FALSE);
-
-  infof(data, "SOCKS5 communication to %s:%d\n", hostname, remote_port);
-
-  code = Curl_write_plain(conn, sock, (char *)socksreq, (2 + (int)socksreq[1]),
-                          &written);
-  if(code || (written != (2 + (int)socksreq[1]))) {
-    failf(data, "Unable to send initial SOCKS5 request.");
-    return CURLE_COULDNT_CONNECT;
-  }
-
-  (void)curlx_nonblock(sock, TRUE);
-
-  result = SOCKET_READABLE(sock, timeout);
-
-  if(-1 == result) {
-    failf(conn->data, "SOCKS5 nothing to read");
-    return CURLE_COULDNT_CONNECT;
-  }
-  if(0 == result) {
-    failf(conn->data, "SOCKS5 read timeout");
-    return CURLE_OPERATION_TIMEDOUT;
-  }
-
-  if(result & CURL_CSELECT_ERR) {
-    failf(conn->data, "SOCKS5 read error occurred");
-    return CURLE_RECV_ERROR;
-  }
-
-  (void)curlx_nonblock(sock, FALSE);
-
-  result = Curl_blockread_all(conn, sock, (char *)socksreq, 2, &actualread);
-  if(result || (actualread != 2)) {
-    failf(data, "Unable to receive initial SOCKS5 response.");
-    return CURLE_COULDNT_CONNECT;
-  }
-
-  if(socksreq[0] != 5) {
-    failf(data, "Received invalid version in initial SOCKS5 response.");
-    return CURLE_COULDNT_CONNECT;
-  }
-  if(socksreq[1] == 0) {
-    /* Nothing to do, no authentication needed */
-    ;
-  }
-#if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI)
-  else if(allow_gssapi && (socksreq[1] == 1)) {
-    code = Curl_SOCKS5_gssapi_negotiate(sockindex, conn);
-    if(code) {
-      failf(data, "Unable to negotiate SOCKS5 GSS-API context.");
+    result = Curl_write_plain(conn, sockfd, (char *)socksreq, idx, &written);
+    if(result && (CURLE_AGAIN != result)) {
+      failf(data, "Unable to send initial SOCKS5 request.");
       return CURLE_COULDNT_CONNECT;
     }
-  }
+    if(written != idx) {
+      sxstate(conn, CONNECT_SOCKS_SEND);
+      sx->outstanding = idx - written;
+      sx->outp = &socksreq[written];
+      return CURLE_OK;
+    }
+    sxstate(conn, CONNECT_SOCKS_READ);
+    goto CONNECT_SOCKS_READ_INIT;
+  case CONNECT_SOCKS_SEND:
+    result = Curl_write_plain(conn, sockfd, (char *)sx->outp,
+                              sx->outstanding, &written);
+    if(result && (CURLE_AGAIN != result)) {
+      failf(data, "Unable to send initial SOCKS5 request.");
+      return CURLE_COULDNT_CONNECT;
+    }
+    if(written != sx->outstanding) {
+      /* not done, remain in state */
+      sx->outstanding -= written;
+      sx->outp += written;
+      return CURLE_OK;
+    }
+    /* FALLTHROUGH */
+  CONNECT_SOCKS_READ_INIT:
+  case CONNECT_SOCKS_READ_INIT:
+    sx->outstanding = 2; /* expect two bytes */
+    sx->outp = socksreq; /* store it here */
+    /* FALLTHROUGH */
+  case CONNECT_SOCKS_READ:
+    result = Curl_read_plain(sockfd, (char *)sx->outp,
+                             sx->outstanding, &actualread);
+    if(result && (CURLE_AGAIN != result)) {
+      failf(data, "Unable to receive initial SOCKS5 response.");
+      return CURLE_COULDNT_CONNECT;
+    }
+    else if(!result && !actualread) {
+      /* connection closed */
+      failf(data, "Connection to proxy closed");
+      return CURLE_COULDNT_CONNECT;
+    }
+    else if(actualread != sx->outstanding) {
+      /* remain in reading state */
+      sx->outstanding -= actualread;
+      sx->outp += actualread;
+      return CURLE_OK;
+    }
+    else if(socksreq[0] != 5) {
+      failf(data, "Received invalid version in initial SOCKS5 response.");
+      return CURLE_COULDNT_CONNECT;
+    }
+    else if(socksreq[1] == 0) {
+      /* DONE! No authentication needed. Send request. */
+      sxstate(conn, CONNECT_REQ_INIT);
+      goto CONNECT_REQ_INIT;
+    }
+    else if(socksreq[1] == 2) {
+      /* regular name + password authentication */
+      sxstate(conn, CONNECT_AUTH_INIT);
+      goto CONNECT_AUTH_INIT;
+    }
+#if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI)
+    else if(allow_gssapi && (socksreq[1] == 1)) {
+      sxstate(conn, CONNECT_GSSAPI_INIT);
+      result = Curl_SOCKS5_gssapi_negotiate(sockindex, conn);
+      if(result) {
+        failf(data, "Unable to negotiate SOCKS5 GSS-API context.");
+        return CURLE_COULDNT_CONNECT;
+      }
+    }
 #endif
-  else if(socksreq[1] == 2) {
+    else {
+      /* error */
+      if(!allow_gssapi && (socksreq[1] == 1)) {
+        failf(data,
+              "SOCKS5 GSSAPI per-message authentication is not supported.");
+        return CURLE_COULDNT_CONNECT;
+      }
+      else if(socksreq[1] == 255) {
+        failf(data, "No authentication method was acceptable.");
+        return CURLE_COULDNT_CONNECT;
+      }
+    }
+    failf(data,
+          "Undocumented SOCKS5 mode attempted to be used by server.");
+    return CURLE_COULDNT_CONNECT;
+#if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI)
+  case CONNECT_GSSAPI_INIT:
+    /* GSSAPI stuff done non-blocking */
+    break;
+#endif
+
+  default: /* do nothing! */
+    break;
+
+  CONNECT_AUTH_INIT:
+  case CONNECT_AUTH_INIT: {
     /* Needs user name and password */
     size_t proxy_user_len, proxy_password_len;
     if(proxy_user && proxy_password) {
@@ -546,257 +698,310 @@
       memcpy(socksreq + len, proxy_password, proxy_password_len);
     }
     len += proxy_password_len;
-
-    code = Curl_write_plain(conn, sock, (char *)socksreq, len, &written);
-    if(code || (len != written)) {
+    sxstate(conn, CONNECT_AUTH_SEND);
+    sx->outstanding = len;
+    sx->outp = socksreq;
+  }
+    /* FALLTHROUGH */
+  case CONNECT_AUTH_SEND:
+    result = Curl_write_plain(conn, sockfd, (char *)sx->outp,
+                              sx->outstanding, &written);
+    if(result && (CURLE_AGAIN != result)) {
       failf(data, "Failed to send SOCKS5 sub-negotiation request.");
       return CURLE_COULDNT_CONNECT;
     }
-
-    result = Curl_blockread_all(conn, sock, (char *)socksreq, 2, &actualread);
-    if(result || (actualread != 2)) {
+    if(sx->outstanding != written) {
+      /* remain in state */
+      sx->outstanding -= written;
+      sx->outp += written;
+      return CURLE_OK;
+    }
+    sx->outp = socksreq;
+    sx->outstanding = 2;
+    sxstate(conn, CONNECT_AUTH_READ);
+    /* FALLTHROUGH */
+  case CONNECT_AUTH_READ:
+    result = Curl_read_plain(sockfd, (char *)sx->outp,
+                             sx->outstanding, &actualread);
+    if(result && (CURLE_AGAIN != result)) {
       failf(data, "Unable to receive SOCKS5 sub-negotiation response.");
       return CURLE_COULDNT_CONNECT;
     }
-
+    else if(!result && !actualread) {
+      /* connection closed */
+      failf(data, "connection to proxy closed");
+      return CURLE_COULDNT_CONNECT;
+    }
+    else if(actualread != sx->outstanding) {
+      /* remain in state */
+      sx->outstanding -= actualread;
+      sx->outp += actualread;
+      return CURLE_OK;
+    }
     /* ignore the first (VER) byte */
-    if(socksreq[1] != 0) { /* status */
+    else if(socksreq[1] != 0) { /* status */
       failf(data, "User was rejected by the SOCKS5 server (%d %d).",
             socksreq[0], socksreq[1]);
       return CURLE_COULDNT_CONNECT;
     }
 
     /* Everything is good so far, user was authenticated! */
-  }
-  else {
-    /* error */
-    if(!allow_gssapi && (socksreq[1] == 1)) {
-      failf(data,
-            "SOCKS5 GSSAPI per-message authentication is not supported.");
-      return CURLE_COULDNT_CONNECT;
-    }
-    if(socksreq[1] == 255) {
-      if(!proxy_user || !*proxy_user) {
-        failf(data,
-              "No authentication method was acceptable. (It is quite likely"
-              " that the SOCKS5 server wanted a username/password, since none"
-              " was supplied to the server on this connection.)");
+    sxstate(conn, CONNECT_REQ_INIT);
+    /* FALLTHROUGH */
+  CONNECT_REQ_INIT:
+  case CONNECT_REQ_INIT:
+    if(socks5_resolve_local) {
+      enum resolve_t rc = Curl_resolv(conn, hostname, remote_port,
+                                      FALSE, &dns);
+
+      if(rc == CURLRESOLV_ERROR)
+        return CURLE_COULDNT_RESOLVE_HOST;
+
+      if(rc == CURLRESOLV_PENDING) {
+        sxstate(conn, CONNECT_RESOLVING);
+        return CURLE_OK;
       }
-      else {
-        failf(data, "No authentication method was acceptable.");
-      }
-      return CURLE_COULDNT_CONNECT;
+      sxstate(conn, CONNECT_RESOLVED);
+      goto CONNECT_RESOLVED;
     }
-    else {
-      failf(data,
-            "Undocumented SOCKS5 mode attempted to be used by server.");
-      return CURLE_COULDNT_CONNECT;
-    }
-  }
+    goto CONNECT_RESOLVE_REMOTE;
 
-  /* Authentication is complete, now specify destination to the proxy */
-  len = 0;
-  socksreq[len++] = 5; /* version (SOCKS5) */
-  socksreq[len++] = 1; /* connect */
-  socksreq[len++] = 0; /* must be zero */
+  case CONNECT_RESOLVING:
+    /* check if we have the name resolved by now */
+    dns = Curl_fetch_addr(conn, hostname, (int)conn->port);
 
-  if(!socks5_resolve_local) {
-    socksreq[len++] = 3; /* ATYP: domain name = 3 */
-    socksreq[len++] = (char) hostname_len; /* address length */
-    memcpy(&socksreq[len], hostname, hostname_len); /* address str w/o NULL */
-    len += hostname_len;
-  }
-  else {
-    struct Curl_dns_entry *dns;
-    Curl_addrinfo *hp = NULL;
-    int rc = Curl_resolv(conn, hostname, remote_port, FALSE, &dns);
-
-    if(rc == CURLRESOLV_ERROR)
-      return CURLE_COULDNT_RESOLVE_HOST;
-
-    if(rc == CURLRESOLV_PENDING) {
-      /* this requires that we're in "wait for resolve" state */
-      code = Curl_resolver_wait_resolv(conn, &dns);
-      if(code)
-        return code;
+    if(dns) {
+#ifdef CURLRES_ASYNCH
+      conn->async.dns = dns;
+      conn->async.done = TRUE;
+#endif
+      infof(data, "SOCKS5: hostname '%s' found\n", hostname);
     }
 
-    /*
-     * We cannot use 'hostent' as a struct that Curl_resolv() returns.  It
-     * returns a Curl_addrinfo pointer that may not always look the same.
-     */
+    if(!dns) {
+      result = Curl_resolv_check(data->conn, &dns);
+      if(!dns)
+        return result;
+    }
+    /* FALLTHROUGH */
+  CONNECT_RESOLVED:
+  case CONNECT_RESOLVED: {
+    struct Curl_addrinfo *hp = NULL;
+    size_t destlen;
     if(dns)
       hp = dns->addr;
-    if(hp) {
-      char buf[64];
-      Curl_printable_address(hp, buf, sizeof(buf));
-
-      if(hp->ai_family == AF_INET) {
-        int i;
-        struct sockaddr_in *saddr_in;
-        socksreq[len++] = 1; /* ATYP: IPv4 = 1 */
-
-        saddr_in = (struct sockaddr_in *)(void *)hp->ai_addr;
-        for(i = 0; i < 4; i++) {
-          socksreq[len++] = ((unsigned char *)&saddr_in->sin_addr.s_addr)[i];
-        }
-
-        infof(data, "SOCKS5 connect to IPv4 %s (locally resolved)\n", buf);
-      }
-#ifdef ENABLE_IPV6
-      else if(hp->ai_family == AF_INET6) {
-        int i;
-        struct sockaddr_in6 *saddr_in6;
-        socksreq[len++] = 4; /* ATYP: IPv6 = 4 */
-
-        saddr_in6 = (struct sockaddr_in6 *)(void *)hp->ai_addr;
-        for(i = 0; i < 16; i++) {
-          socksreq[len++] =
-            ((unsigned char *)&saddr_in6->sin6_addr.s6_addr)[i];
-        }
-
-        infof(data, "SOCKS5 connect to IPv6 %s (locally resolved)\n", buf);
-      }
-#endif
-      else {
-        hp = NULL; /* fail! */
-
-        failf(data, "SOCKS5 connection to %s not supported\n", buf);
-      }
-
-      Curl_resolv_unlock(data, dns); /* not used anymore from now on */
-    }
     if(!hp) {
       failf(data, "Failed to resolve \"%s\" for SOCKS5 connect.",
             hostname);
       return CURLE_COULDNT_RESOLVE_HOST;
     }
-  }
 
-  socksreq[len++] = (unsigned char)((remote_port >> 8) & 0xff); /* PORT MSB */
-  socksreq[len++] = (unsigned char)(remote_port & 0xff);        /* PORT LSB */
+    Curl_printable_address(hp, dest, sizeof(dest));
+    destlen = strlen(dest);
+    msnprintf(dest + destlen, sizeof(dest) - destlen, ":%d", remote_port);
 
-#if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI)
-  if(conn->socks5_gssapi_enctype) {
-    failf(data, "SOCKS5 GSS-API protection not yet implemented.");
-  }
-  else
-#endif
-    code = Curl_write_plain(conn, sock, (char *)socksreq, len, &written);
+    len = 0;
+    socksreq[len++] = 5; /* version (SOCKS5) */
+    socksreq[len++] = 1; /* connect */
+    socksreq[len++] = 0; /* must be zero */
+    if(hp->ai_family == AF_INET) {
+      int i;
+      struct sockaddr_in *saddr_in;
+      socksreq[len++] = 1; /* ATYP: IPv4 = 1 */
 
-  if(code || (len != written)) {
-    failf(data, "Failed to send SOCKS5 connect request.");
-    return CURLE_COULDNT_CONNECT;
-  }
-
-  len = 10; /* minimum packet size is 10 */
-
-#if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI)
-  if(conn->socks5_gssapi_enctype) {
-    failf(data, "SOCKS5 GSS-API protection not yet implemented.");
-  }
-  else
-#endif
-    result = Curl_blockread_all(conn, sock, (char *)socksreq,
-                                len, &actualread);
-
-  if(result || (len != actualread)) {
-    failf(data, "Failed to receive SOCKS5 connect request ack.");
-    return CURLE_COULDNT_CONNECT;
-  }
-
-  if(socksreq[0] != 5) { /* version */
-    failf(data,
-          "SOCKS5 reply has wrong version, version should be 5.");
-    return CURLE_COULDNT_CONNECT;
-  }
-
-  /* Fix: in general, returned BND.ADDR is variable length parameter by RFC
-     1928, so the reply packet should be read until the end to avoid errors at
-     subsequent protocol level.
-
-    +----+-----+-------+------+----------+----------+
-    |VER | REP |  RSV  | ATYP | BND.ADDR | BND.PORT |
-    +----+-----+-------+------+----------+----------+
-    | 1  |  1  | X'00' |  1   | Variable |    2     |
-    +----+-----+-------+------+----------+----------+
-
-     ATYP:
-     o  IP v4 address: X'01', BND.ADDR = 4 byte
-     o  domain name:  X'03', BND.ADDR = [ 1 byte length, string ]
-     o  IP v6 address: X'04', BND.ADDR = 16 byte
-     */
-
-  /* Calculate real packet size */
-  if(socksreq[3] == 3) {
-    /* domain name */
-    int addrlen = (int) socksreq[4];
-    len = 5 + addrlen + 2;
-  }
-  else if(socksreq[3] == 4) {
-    /* IPv6 */
-    len = 4 + 16 + 2;
-  }
-
-  /* At this point we already read first 10 bytes */
-#if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI)
-  if(!conn->socks5_gssapi_enctype) {
-    /* decrypt_gssapi_blockread already read the whole packet */
-#endif
-    if(len > 10) {
-      result = Curl_blockread_all(conn, sock, (char *)&socksreq[10],
-                                  len - 10, &actualread);
-      if(result || ((len - 10) != actualread)) {
-        failf(data, "Failed to receive SOCKS5 connect request ack.");
-        return CURLE_COULDNT_CONNECT;
+      saddr_in = (struct sockaddr_in *)(void *)hp->ai_addr;
+      for(i = 0; i < 4; i++) {
+        socksreq[len++] = ((unsigned char *)&saddr_in->sin_addr.s_addr)[i];
       }
+
+      infof(data, "SOCKS5 connect to IPv4 %s (locally resolved)\n", dest);
+    }
+#ifdef ENABLE_IPV6
+    else if(hp->ai_family == AF_INET6) {
+      int i;
+      struct sockaddr_in6 *saddr_in6;
+      socksreq[len++] = 4; /* ATYP: IPv6 = 4 */
+
+      saddr_in6 = (struct sockaddr_in6 *)(void *)hp->ai_addr;
+      for(i = 0; i < 16; i++) {
+        socksreq[len++] =
+          ((unsigned char *)&saddr_in6->sin6_addr.s6_addr)[i];
+      }
+
+      infof(data, "SOCKS5 connect to IPv6 %s (locally resolved)\n", dest);
+    }
+#endif
+    else {
+      hp = NULL; /* fail! */
+      failf(data, "SOCKS5 connection to %s not supported\n", dest);
+    }
+
+    Curl_resolv_unlock(data, dns); /* not used anymore from now on */
+    goto CONNECT_REQ_SEND;
+  }
+  CONNECT_RESOLVE_REMOTE:
+  case CONNECT_RESOLVE_REMOTE:
+    /* Authentication is complete, now specify destination to the proxy */
+    len = 0;
+    socksreq[len++] = 5; /* version (SOCKS5) */
+    socksreq[len++] = 1; /* connect */
+    socksreq[len++] = 0; /* must be zero */
+
+    if(!socks5_resolve_local) {
+      socksreq[len++] = 3; /* ATYP: domain name = 3 */
+      socksreq[len++] = (char) hostname_len; /* one byte address length */
+      memcpy(&socksreq[len], hostname, hostname_len); /* address w/o NULL */
+      len += hostname_len;
+      infof(data, "SOCKS5 connect to %s:%d (remotely resolved)\n",
+            hostname, remote_port);
+    }
+    /* FALLTHROUGH */
+
+  CONNECT_REQ_SEND:
+  case CONNECT_REQ_SEND:
+    /* PORT MSB */
+    socksreq[len++] = (unsigned char)((remote_port >> 8) & 0xff);
+    /* PORT LSB */
+    socksreq[len++] = (unsigned char)(remote_port & 0xff);
+
+#if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI)
+    if(conn->socks5_gssapi_enctype) {
+      failf(data, "SOCKS5 GSS-API protection not yet implemented.");
+      return CURLE_COULDNT_CONNECT;
+    }
+#endif
+    sx->outp = socksreq;
+    sx->outstanding = len;
+    sxstate(conn, CONNECT_REQ_SENDING);
+    /* FALLTHROUGH */
+  case CONNECT_REQ_SENDING:
+    result = Curl_write_plain(conn, sockfd, (char *)sx->outp,
+                              sx->outstanding, &written);
+    if(result && (CURLE_AGAIN != result)) {
+      failf(data, "Failed to send SOCKS5 connect request.");
+      return CURLE_COULDNT_CONNECT;
+    }
+    if(sx->outstanding != written) {
+      /* remain in state */
+      sx->outstanding -= written;
+      sx->outp += written;
+      return CURLE_OK;
     }
 #if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI)
-  }
-#endif
-
-  if(socksreq[1] != 0) { /* Anything besides 0 is an error */
-    if(socksreq[3] == 1) {
-      failf(data,
-            "Can't complete SOCKS5 connection to %d.%d.%d.%d:%d. (%d)",
-            (unsigned char)socksreq[4], (unsigned char)socksreq[5],
-            (unsigned char)socksreq[6], (unsigned char)socksreq[7],
-            (((unsigned char)socksreq[8] << 8) |
-             (unsigned char)socksreq[9]),
-            (unsigned char)socksreq[1]);
+    if(conn->socks5_gssapi_enctype) {
+      failf(data, "SOCKS5 GSS-API protection not yet implemented.");
+      return CURLE_COULDNT_CONNECT;
     }
-    else if(socksreq[3] == 3) {
-      unsigned char port_upper = (unsigned char)socksreq[len - 2];
-      socksreq[len - 2] = 0;
+#endif
+    sx->outstanding = 10; /* minimum packet size is 10 */
+    sx->outp = socksreq;
+    sxstate(conn, CONNECT_REQ_READ);
+    /* FALLTHROUGH */
+  case CONNECT_REQ_READ:
+    result = Curl_read_plain(sockfd, (char *)sx->outp,
+                             sx->outstanding, &actualread);
+    if(result && (CURLE_AGAIN != result)) {
+      failf(data, "Failed to receive SOCKS5 connect request ack.");
+      return CURLE_COULDNT_CONNECT;
+    }
+    else if(!result && !actualread) {
+      /* connection closed */
+      failf(data, "connection to proxy closed");
+      return CURLE_COULDNT_CONNECT;
+    }
+    else if(actualread != sx->outstanding) {
+      /* remain in state */
+      sx->outstanding -= actualread;
+      sx->outp += actualread;
+      return CURLE_OK;
+    }
+
+    if(socksreq[0] != 5) { /* version */
       failf(data,
-            "Can't complete SOCKS5 connection to %s:%d. (%d)",
-            (char *)&socksreq[5],
-            ((port_upper << 8) |
-             (unsigned char)socksreq[len - 1]),
-            (unsigned char)socksreq[1]);
-      socksreq[len - 2] = port_upper;
+            "SOCKS5 reply has wrong version, version should be 5.");
+      return CURLE_COULDNT_CONNECT;
+    }
+    else if(socksreq[1] != 0) { /* Anything besides 0 is an error */
+      failf(data, "Can't complete SOCKS5 connection to %s. (%d)",
+            hostname, (unsigned char)socksreq[1]);
+      return CURLE_COULDNT_CONNECT;
+    }
+
+    /* Fix: in general, returned BND.ADDR is variable length parameter by RFC
+       1928, so the reply packet should be read until the end to avoid errors
+       at subsequent protocol level.
+
+       +----+-----+-------+------+----------+----------+
+       |VER | REP |  RSV  | ATYP | BND.ADDR | BND.PORT |
+       +----+-----+-------+------+----------+----------+
+       | 1  |  1  | X'00' |  1   | Variable |    2     |
+       +----+-----+-------+------+----------+----------+
+
+       ATYP:
+       o  IP v4 address: X'01', BND.ADDR = 4 byte
+       o  domain name:  X'03', BND.ADDR = [ 1 byte length, string ]
+       o  IP v6 address: X'04', BND.ADDR = 16 byte
+    */
+
+    /* Calculate real packet size */
+    if(socksreq[3] == 3) {
+      /* domain name */
+      int addrlen = (int) socksreq[4];
+      len = 5 + addrlen + 2;
     }
     else if(socksreq[3] == 4) {
-      failf(data,
-            "Can't complete SOCKS5 connection to %02x%02x:%02x%02x:"
-            "%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%d. (%d)",
-            (unsigned char)socksreq[4], (unsigned char)socksreq[5],
-            (unsigned char)socksreq[6], (unsigned char)socksreq[7],
-            (unsigned char)socksreq[8], (unsigned char)socksreq[9],
-            (unsigned char)socksreq[10], (unsigned char)socksreq[11],
-            (unsigned char)socksreq[12], (unsigned char)socksreq[13],
-            (unsigned char)socksreq[14], (unsigned char)socksreq[15],
-            (unsigned char)socksreq[16], (unsigned char)socksreq[17],
-            (unsigned char)socksreq[18], (unsigned char)socksreq[19],
-            (((unsigned char)socksreq[20] << 8) |
-             (unsigned char)socksreq[21]),
-            (unsigned char)socksreq[1]);
+      /* IPv6 */
+      len = 4 + 16 + 2;
     }
-    return CURLE_COULDNT_CONNECT;
+    else if(socksreq[3] == 1) {
+      len = 4 + 4 + 2;
+    }
+    else {
+      failf(data, "SOCKS5 reply has wrong address type.");
+      return CURLE_COULDNT_CONNECT;
+    }
+
+    /* At this point we already read first 10 bytes */
+#if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI)
+    if(!conn->socks5_gssapi_enctype) {
+      /* decrypt_gssapi_blockread already read the whole packet */
+#endif
+      if(len > 10) {
+        sx->outstanding = len - 10; /* get the rest */
+        sx->outp = &socksreq[10];
+        sxstate(conn, CONNECT_REQ_READ_MORE);
+      }
+      else {
+        sxstate(conn, CONNECT_DONE);
+        break;
+      }
+#if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI)
+    }
+#endif
+    /* FALLTHROUGH */
+  case CONNECT_REQ_READ_MORE:
+    result = Curl_read_plain(sockfd, (char *)sx->outp,
+                             sx->outstanding, &actualread);
+    if(result && (CURLE_AGAIN != result)) {
+      failf(data, "Failed to receive SOCKS5 connect request ack.");
+      return CURLE_COULDNT_CONNECT;
+    }
+    else if(!result && !actualread) {
+      /* connection closed */
+      failf(data, "connection to proxy closed");
+      return CURLE_COULDNT_CONNECT;
+    }
+    else if(actualread != sx->outstanding) {
+      /* remain in state */
+      sx->outstanding -= actualread;
+      sx->outp += actualread;
+      return CURLE_OK;
+    }
+    sxstate(conn, CONNECT_DONE);
   }
   infof(data, "SOCKS5 request granted.\n");
 
-  (void)curlx_nonblock(sock, TRUE);
+  *done = TRUE;
   return CURLE_OK; /* Proxy was successful! */
 }
 
diff --git a/Utilities/cmcurl/lib/socks.h b/Utilities/cmcurl/lib/socks.h
index daa07c1..64a7563 100644
--- a/Utilities/cmcurl/lib/socks.h
+++ b/Utilities/cmcurl/lib/socks.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -27,13 +27,13 @@
 #ifdef CURL_DISABLE_PROXY
 #define Curl_SOCKS4(a,b,c,d,e) CURLE_NOT_BUILT_IN
 #define Curl_SOCKS5(a,b,c,d,e,f) CURLE_NOT_BUILT_IN
+#define Curl_SOCKS_getsock(x,y,z) 0
 #else
 /*
  * Helper read-from-socket functions. Does the same as Curl_read() but it
  * blocks until all bytes amount of buffersize will be read. No more, no less.
  *
- * This is STUPID BLOCKING behaviour which we frown upon, but right now this
- * is what we have...
+ * This is STUPID BLOCKING behavior
  */
 int Curl_blockread_all(struct connectdata *conn,
                        curl_socket_t sockfd,
@@ -41,6 +41,9 @@
                        ssize_t buffersize,
                        ssize_t *n);
 
+int Curl_SOCKS_getsock(struct connectdata *conn,
+                       curl_socket_t *sock,
+                       int sockindex);
 /*
  * This function logs in to a SOCKS4(a) proxy and sends the specifics to the
  * final destination server.
@@ -49,7 +52,8 @@
                      const char *hostname,
                      int remote_port,
                      int sockindex,
-                     struct connectdata *conn);
+                     struct connectdata *conn,
+                     bool *done);
 
 /*
  * This function logs in to a SOCKS5 proxy and sends the specifics to the
@@ -60,7 +64,8 @@
                      const char *hostname,
                      int remote_port,
                      int sockindex,
-                     struct connectdata *conn);
+                     struct connectdata *conn,
+                     bool *done);
 
 #if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI)
 /*
diff --git a/Utilities/cmcurl/lib/socks_gssapi.c b/Utilities/cmcurl/lib/socks_gssapi.c
index 65294bb..2e36b99 100644
--- a/Utilities/cmcurl/lib/socks_gssapi.c
+++ b/Utilities/cmcurl/lib/socks_gssapi.c
@@ -5,8 +5,8 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
+ * Copyright (C) 2012 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  * Copyright (C) 2009, Markus Moeller, <markus_moeller@compuserve.com>
- * Copyright (C) 2012 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -115,7 +115,7 @@
   gss_buffer_desc  gss_send_token = GSS_C_EMPTY_BUFFER;
   gss_buffer_desc  gss_recv_token = GSS_C_EMPTY_BUFFER;
   gss_buffer_desc  gss_w_token = GSS_C_EMPTY_BUFFER;
-  gss_buffer_desc* gss_token = GSS_C_NO_BUFFER;
+  gss_buffer_desc *gss_token = GSS_C_NO_BUFFER;
   gss_name_t       server = GSS_C_NO_NAME;
   gss_name_t       gss_client_name = GSS_C_NO_NAME;
   unsigned short   us_length;
@@ -167,6 +167,8 @@
     return CURLE_COULDNT_CONNECT;
   }
 
+  (void)curlx_nonblock(sock, FALSE);
+
   /* As long as we need to keep sending some context info, and there's no  */
   /* errors, keep sending it...                                            */
   for(;;) {
@@ -225,7 +227,8 @@
 
     gss_release_buffer(&gss_status, &gss_send_token);
     gss_release_buffer(&gss_status, &gss_recv_token);
-    if(gss_major_status != GSS_S_CONTINUE_NEEDED) break;
+    if(gss_major_status != GSS_S_CONTINUE_NEEDED)
+      break;
 
     /* analyse response */
 
@@ -325,7 +328,7 @@
   user[gss_send_token.length] = '\0';
   gss_release_name(&gss_status, &gss_client_name);
   gss_release_buffer(&gss_status, &gss_send_token);
-  infof(data, "SOCKS5 server authencticated user %s with GSS-API.\n",user);
+  infof(data, "SOCKS5 server authenticated user %s with GSS-API.\n",user);
   free(user);
   user = NULL;
 
@@ -513,6 +516,8 @@
     gss_release_buffer(&gss_status, &gss_recv_token);
   }
 
+  (void)curlx_nonblock(sock, TRUE);
+
   infof(data, "SOCKS5 access with%s protection granted.\n",
         (socksreq[0] == 0)?"out GSS-API data":
         ((socksreq[0] == 1)?" GSS-API integrity":" GSS-API confidentiality"));
diff --git a/Utilities/cmcurl/lib/socks_sspi.c b/Utilities/cmcurl/lib/socks_sspi.c
index 57027ef..2f1fd36 100644
--- a/Utilities/cmcurl/lib/socks_sspi.c
+++ b/Utilities/cmcurl/lib/socks_sspi.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 2012 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 2012 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  * Copyright (C) 2009, 2011, Markus Moeller, <markus_moeller@compuserve.com>
  *
  * This software is licensed as described in the file COPYING, which
@@ -153,12 +153,14 @@
     return CURLE_COULDNT_CONNECT;
   }
 
+  (void)curlx_nonblock(sock, FALSE);
+
   /* As long as we need to keep sending some context info, and there's no  */
   /* errors, keep sending it...                                            */
   for(;;) {
     TCHAR *sname;
 
-    sname = Curl_convert_UTF8_to_tchar(service_name);
+    sname = curlx_convert_UTF8_to_tchar(service_name);
     if(!sname)
       return CURLE_OUT_OF_MEMORY;
 
@@ -178,7 +180,7 @@
                                                  &sspi_ret_flags,
                                                  &expiry);
 
-    Curl_unicodefree(sname);
+    curlx_unicodefree(sname);
 
     if(sspi_recv_token.pvBuffer) {
       s_pSecFn->FreeContextBuffer(sspi_recv_token.pvBuffer);
@@ -325,7 +327,7 @@
     failf(data, "Failed to determine user name.");
     return CURLE_COULDNT_CONNECT;
   }
-  infof(data, "SOCKS5 server authencticated user %s with GSS-API.\n",
+  infof(data, "SOCKS5 server authenticated user %s with GSS-API.\n",
         names.sUserName);
   s_pSecFn->FreeContextBuffer(names.sUserName);
 
@@ -587,6 +589,7 @@
     memcpy(socksreq, sspi_w_token[0].pvBuffer, sspi_w_token[0].cbBuffer);
     s_pSecFn->FreeContextBuffer(sspi_w_token[0].pvBuffer);
   }
+  (void)curlx_nonblock(sock, TRUE);
 
   infof(data, "SOCKS5 access with%s protection granted.\n",
         (socksreq[0] == 0)?"out GSS-API data":
diff --git a/Utilities/cmcurl/lib/splay.h b/Utilities/cmcurl/lib/splay.h
index 4612ec2..9292f34 100644
--- a/Utilities/cmcurl/lib/splay.h
+++ b/Utilities/cmcurl/lib/splay.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1997 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1997 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -59,10 +59,4 @@
                                    ( ((i.tv_usec) < (j.tv_usec)) ? -1 : \
                                    ( ((i.tv_usec) > (j.tv_usec)) ?  1 : 0))))
 
-#ifdef DEBUGBUILD
-void Curl_splayprint(struct Curl_tree * t, int d, char output);
-#else
-#define Curl_splayprint(x,y,z) Curl_nop_stmt
-#endif
-
 #endif /* HEADER_CURL_SPLAY_H */
diff --git a/Utilities/cmcurl/lib/ssh-libssh.c b/Utilities/cmcurl/lib/ssh-libssh.c
deleted file mode 100644
index 6cfd6bd..0000000
--- a/Utilities/cmcurl/lib/ssh-libssh.c
+++ /dev/null
@@ -1,2740 +0,0 @@
-/***************************************************************************
- *                                  _   _ ____  _
- *  Project                     ___| | | |  _ \| |
- *                             / __| | | | |_) | |
- *                            | (__| |_| |  _ <| |___
- *                             \___|\___/|_| \_\_____|
- *
- * Copyright (C) 2017 - 2019 Red Hat, Inc.
- *
- * Authors: Nikos Mavrogiannopoulos, Tomas Mraz, Stanislav Zidek,
- *          Robert Kolcun, Andreas Schneider
- *
- * This software is licensed as described in the file COPYING, which
- * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
- *
- * You may opt to use, copy, modify, merge, publish, distribute and/or sell
- * copies of the Software, and permit persons to whom the Software is
- * furnished to do so, under the terms of the COPYING file.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- ***************************************************************************/
-
-#include "curl_setup.h"
-
-#ifdef USE_LIBSSH
-
-#include <limits.h>
-
-#include <libssh/libssh.h>
-#include <libssh/sftp.h>
-
-#ifdef HAVE_FCNTL_H
-#include <fcntl.h>
-#endif
-
-#ifdef HAVE_NETINET_IN_H
-#include <netinet/in.h>
-#endif
-#ifdef HAVE_ARPA_INET_H
-#include <arpa/inet.h>
-#endif
-#ifdef HAVE_UTSNAME_H
-#include <sys/utsname.h>
-#endif
-#ifdef HAVE_NETDB_H
-#include <netdb.h>
-#endif
-#ifdef __VMS
-#include <in.h>
-#include <inet.h>
-#endif
-
-#if (defined(NETWARE) && defined(__NOVELL_LIBC__))
-#undef in_addr_t
-#define in_addr_t unsigned long
-#endif
-
-#include <curl/curl.h>
-#include "urldata.h"
-#include "sendf.h"
-#include "hostip.h"
-#include "progress.h"
-#include "transfer.h"
-#include "escape.h"
-#include "http.h"               /* for HTTP proxy tunnel stuff */
-#include "ssh.h"
-#include "url.h"
-#include "speedcheck.h"
-#include "getinfo.h"
-#include "strdup.h"
-#include "strcase.h"
-#include "vtls/vtls.h"
-#include "connect.h"
-#include "strerror.h"
-#include "inet_ntop.h"
-#include "parsedate.h"          /* for the week day and month names */
-#include "sockaddr.h"           /* required for Curl_sockaddr_storage */
-#include "strtoofft.h"
-#include "multiif.h"
-#include "select.h"
-#include "warnless.h"
-
-/* for permission and open flags */
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <unistd.h>
-#include <fcntl.h>
-
-/* The last 3 #include files should be in this order */
-#include "curl_printf.h"
-#include "curl_memory.h"
-#include "memdebug.h"
-#include "curl_path.h"
-
-/* A recent macro provided by libssh. Or make our own. */
-#ifndef SSH_STRING_FREE_CHAR
-/* !checksrc! disable ASSIGNWITHINCONDITION 1 */
-#define SSH_STRING_FREE_CHAR(x) \
-    do { if((x) != NULL) { ssh_string_free_char(x); x = NULL; } } while(0)
-#endif
-
-/* Local functions: */
-static CURLcode myssh_connect(struct connectdata *conn, bool *done);
-static CURLcode myssh_multi_statemach(struct connectdata *conn,
-                                      bool *done);
-static CURLcode myssh_do_it(struct connectdata *conn, bool *done);
-
-static CURLcode scp_done(struct connectdata *conn,
-                         CURLcode, bool premature);
-static CURLcode scp_doing(struct connectdata *conn, bool *dophase_done);
-static CURLcode scp_disconnect(struct connectdata *conn,
-                               bool dead_connection);
-
-static CURLcode sftp_done(struct connectdata *conn,
-                          CURLcode, bool premature);
-static CURLcode sftp_doing(struct connectdata *conn,
-                           bool *dophase_done);
-static CURLcode sftp_disconnect(struct connectdata *conn, bool dead);
-static
-CURLcode sftp_perform(struct connectdata *conn,
-                      bool *connected,
-                      bool *dophase_done);
-
-static void sftp_quote(struct connectdata *conn);
-static void sftp_quote_stat(struct connectdata *conn);
-
-static int myssh_getsock(struct connectdata *conn, curl_socket_t *sock,
-                         int numsocks);
-
-static int myssh_perform_getsock(const struct connectdata *conn,
-                                 curl_socket_t *sock,
-                                 int numsocks);
-
-static CURLcode myssh_setup_connection(struct connectdata *conn);
-
-/*
- * SCP protocol handler.
- */
-
-const struct Curl_handler Curl_handler_scp = {
-  "SCP",                        /* scheme */
-  myssh_setup_connection,       /* setup_connection */
-  myssh_do_it,                  /* do_it */
-  scp_done,                     /* done */
-  ZERO_NULL,                    /* do_more */
-  myssh_connect,                /* connect_it */
-  myssh_multi_statemach,        /* connecting */
-  scp_doing,                    /* doing */
-  myssh_getsock,                /* proto_getsock */
-  myssh_getsock,                /* doing_getsock */
-  ZERO_NULL,                    /* domore_getsock */
-  myssh_perform_getsock,        /* perform_getsock */
-  scp_disconnect,               /* disconnect */
-  ZERO_NULL,                    /* readwrite */
-  ZERO_NULL,                    /* connection_check */
-  PORT_SSH,                     /* defport */
-  CURLPROTO_SCP,                /* protocol */
-  PROTOPT_DIRLOCK | PROTOPT_CLOSEACTION | PROTOPT_NOURLQUERY    /* flags */
-};
-
-/*
- * SFTP protocol handler.
- */
-
-const struct Curl_handler Curl_handler_sftp = {
-  "SFTP",                               /* scheme */
-  myssh_setup_connection,               /* setup_connection */
-  myssh_do_it,                          /* do_it */
-  sftp_done,                            /* done */
-  ZERO_NULL,                            /* do_more */
-  myssh_connect,                        /* connect_it */
-  myssh_multi_statemach,                /* connecting */
-  sftp_doing,                           /* doing */
-  myssh_getsock,                        /* proto_getsock */
-  myssh_getsock,                        /* doing_getsock */
-  ZERO_NULL,                            /* domore_getsock */
-  myssh_perform_getsock,                /* perform_getsock */
-  sftp_disconnect,                      /* disconnect */
-  ZERO_NULL,                            /* readwrite */
-  ZERO_NULL,                            /* connection_check */
-  PORT_SSH,                             /* defport */
-  CURLPROTO_SFTP,                       /* protocol */
-  PROTOPT_DIRLOCK | PROTOPT_CLOSEACTION
-  | PROTOPT_NOURLQUERY                  /* flags */
-};
-
-static CURLcode sftp_error_to_CURLE(int err)
-{
-  switch(err) {
-    case SSH_FX_OK:
-      return CURLE_OK;
-
-    case SSH_FX_NO_SUCH_FILE:
-    case SSH_FX_NO_SUCH_PATH:
-      return CURLE_REMOTE_FILE_NOT_FOUND;
-
-    case SSH_FX_PERMISSION_DENIED:
-    case SSH_FX_WRITE_PROTECT:
-      return CURLE_REMOTE_ACCESS_DENIED;
-
-    case SSH_FX_FILE_ALREADY_EXISTS:
-      return CURLE_REMOTE_FILE_EXISTS;
-
-    default:
-      break;
-  }
-
-  return CURLE_SSH;
-}
-
-#ifndef DEBUGBUILD
-#define state(x,y) mystate(x,y)
-#else
-#define state(x,y) mystate(x,y, __LINE__)
-#endif
-
-/*
- * SSH State machine related code
- */
-/* This is the ONLY way to change SSH state! */
-static void mystate(struct connectdata *conn, sshstate nowstate
-#ifdef DEBUGBUILD
-                    , int lineno
-#endif
-  )
-{
-  struct ssh_conn *sshc = &conn->proto.sshc;
-#if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS)
-  /* for debug purposes */
-  static const char *const names[] = {
-    "SSH_STOP",
-    "SSH_INIT",
-    "SSH_S_STARTUP",
-    "SSH_HOSTKEY",
-    "SSH_AUTHLIST",
-    "SSH_AUTH_PKEY_INIT",
-    "SSH_AUTH_PKEY",
-    "SSH_AUTH_PASS_INIT",
-    "SSH_AUTH_PASS",
-    "SSH_AUTH_AGENT_INIT",
-    "SSH_AUTH_AGENT_LIST",
-    "SSH_AUTH_AGENT",
-    "SSH_AUTH_HOST_INIT",
-    "SSH_AUTH_HOST",
-    "SSH_AUTH_KEY_INIT",
-    "SSH_AUTH_KEY",
-    "SSH_AUTH_GSSAPI",
-    "SSH_AUTH_DONE",
-    "SSH_SFTP_INIT",
-    "SSH_SFTP_REALPATH",
-    "SSH_SFTP_QUOTE_INIT",
-    "SSH_SFTP_POSTQUOTE_INIT",
-    "SSH_SFTP_QUOTE",
-    "SSH_SFTP_NEXT_QUOTE",
-    "SSH_SFTP_QUOTE_STAT",
-    "SSH_SFTP_QUOTE_SETSTAT",
-    "SSH_SFTP_QUOTE_SYMLINK",
-    "SSH_SFTP_QUOTE_MKDIR",
-    "SSH_SFTP_QUOTE_RENAME",
-    "SSH_SFTP_QUOTE_RMDIR",
-    "SSH_SFTP_QUOTE_UNLINK",
-    "SSH_SFTP_QUOTE_STATVFS",
-    "SSH_SFTP_GETINFO",
-    "SSH_SFTP_FILETIME",
-    "SSH_SFTP_TRANS_INIT",
-    "SSH_SFTP_UPLOAD_INIT",
-    "SSH_SFTP_CREATE_DIRS_INIT",
-    "SSH_SFTP_CREATE_DIRS",
-    "SSH_SFTP_CREATE_DIRS_MKDIR",
-    "SSH_SFTP_READDIR_INIT",
-    "SSH_SFTP_READDIR",
-    "SSH_SFTP_READDIR_LINK",
-    "SSH_SFTP_READDIR_BOTTOM",
-    "SSH_SFTP_READDIR_DONE",
-    "SSH_SFTP_DOWNLOAD_INIT",
-    "SSH_SFTP_DOWNLOAD_STAT",
-    "SSH_SFTP_CLOSE",
-    "SSH_SFTP_SHUTDOWN",
-    "SSH_SCP_TRANS_INIT",
-    "SSH_SCP_UPLOAD_INIT",
-    "SSH_SCP_DOWNLOAD_INIT",
-    "SSH_SCP_DOWNLOAD",
-    "SSH_SCP_DONE",
-    "SSH_SCP_SEND_EOF",
-    "SSH_SCP_WAIT_EOF",
-    "SSH_SCP_WAIT_CLOSE",
-    "SSH_SCP_CHANNEL_FREE",
-    "SSH_SESSION_DISCONNECT",
-    "SSH_SESSION_FREE",
-    "QUIT"
-  };
-
-
-  if(sshc->state != nowstate) {
-    infof(conn->data, "SSH %p state change from %s to %s (line %d)\n",
-          (void *) sshc, names[sshc->state], names[nowstate],
-          lineno);
-  }
-#endif
-
-  sshc->state = nowstate;
-}
-
-/* Multiple options:
- * 1. data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5] is set with an MD5
- *    hash (90s style auth, not sure we should have it here)
- * 2. data->set.ssh_keyfunc callback is set. Then we do trust on first
- *    use. We even save on knownhosts if CURLKHSTAT_FINE_ADD_TO_FILE
- *    is returned by it.
- * 3. none of the above. We only accept if it is present on known hosts.
- *
- * Returns SSH_OK or SSH_ERROR.
- */
-static int myssh_is_known(struct connectdata *conn)
-{
-  int rc;
-  struct Curl_easy *data = conn->data;
-  struct ssh_conn *sshc = &conn->proto.sshc;
-  ssh_key pubkey;
-  size_t hlen;
-  unsigned char *hash = NULL;
-  char *base64 = NULL;
-  int vstate;
-  enum curl_khmatch keymatch;
-  struct curl_khkey foundkey;
-  curl_sshkeycallback func =
-    data->set.ssh_keyfunc;
-
-  rc = ssh_get_publickey(sshc->ssh_session, &pubkey);
-  if(rc != SSH_OK)
-    return rc;
-
-  if(data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5]) {
-    rc = ssh_get_publickey_hash(pubkey, SSH_PUBLICKEY_HASH_MD5,
-                                &hash, &hlen);
-    if(rc != SSH_OK)
-      goto cleanup;
-
-    if(hlen != strlen(data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5]) ||
-       memcmp(&data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5], hash, hlen)) {
-      rc = SSH_ERROR;
-      goto cleanup;
-    }
-
-    rc = SSH_OK;
-    goto cleanup;
-  }
-
-  if(data->set.ssl.primary.verifyhost != TRUE) {
-    rc = SSH_OK;
-    goto cleanup;
-  }
-
-  vstate = ssh_is_server_known(sshc->ssh_session);
-  switch(vstate) {
-    case SSH_SERVER_KNOWN_OK:
-      keymatch = CURLKHMATCH_OK;
-      break;
-    case SSH_SERVER_FILE_NOT_FOUND:
-      /* fallthrough */
-    case SSH_SERVER_NOT_KNOWN:
-      keymatch = CURLKHMATCH_MISSING;
-      break;
-  default:
-      keymatch = CURLKHMATCH_MISMATCH;
-      break;
-  }
-
-  if(func) { /* use callback to determine action */
-    rc = ssh_pki_export_pubkey_base64(pubkey, &base64);
-    if(rc != SSH_OK)
-      goto cleanup;
-
-    foundkey.key = base64;
-    foundkey.len = strlen(base64);
-
-    switch(ssh_key_type(pubkey)) {
-      case SSH_KEYTYPE_RSA:
-        foundkey.keytype = CURLKHTYPE_RSA;
-        break;
-      case SSH_KEYTYPE_RSA1:
-        foundkey.keytype = CURLKHTYPE_RSA1;
-        break;
-      case SSH_KEYTYPE_ECDSA:
-        foundkey.keytype = CURLKHTYPE_ECDSA;
-        break;
-#if LIBSSH_VERSION_INT >= SSH_VERSION_INT(0,7,0)
-      case SSH_KEYTYPE_ED25519:
-        foundkey.keytype = CURLKHTYPE_ED25519;
-        break;
-#endif
-      case SSH_KEYTYPE_DSS:
-        foundkey.keytype = CURLKHTYPE_DSS;
-        break;
-      default:
-        rc = SSH_ERROR;
-        goto cleanup;
-    }
-
-    /* we don't have anything equivalent to knownkey. Always NULL */
-    Curl_set_in_callback(data, true);
-    rc = func(data, NULL, &foundkey, /* from the remote host */
-              keymatch, data->set.ssh_keyfunc_userp);
-    Curl_set_in_callback(data, false);
-
-    switch(rc) {
-      case CURLKHSTAT_FINE_ADD_TO_FILE:
-        rc = ssh_write_knownhost(sshc->ssh_session);
-        if(rc != SSH_OK) {
-          goto cleanup;
-        }
-        break;
-      case CURLKHSTAT_FINE:
-        break;
-      default: /* REJECT/DEFER */
-        rc = SSH_ERROR;
-        goto cleanup;
-    }
-  }
-  else {
-    if(keymatch != CURLKHMATCH_OK) {
-      rc = SSH_ERROR;
-      goto cleanup;
-    }
-  }
-  rc = SSH_OK;
-
-cleanup:
-  if(hash)
-    ssh_clean_pubkey_hash(&hash);
-  ssh_key_free(pubkey);
-  return rc;
-}
-
-#define MOVE_TO_ERROR_STATE(_r) { \
-  state(conn, SSH_SESSION_DISCONNECT); \
-  sshc->actualcode = _r; \
-  rc = SSH_ERROR; \
-  break; \
-}
-
-#define MOVE_TO_SFTP_CLOSE_STATE() { \
-  state(conn, SSH_SFTP_CLOSE); \
-  sshc->actualcode = sftp_error_to_CURLE(sftp_get_error(sshc->sftp_session)); \
-  rc = SSH_ERROR; \
-  break; \
-}
-
-#define MOVE_TO_LAST_AUTH \
-  if(sshc->auth_methods & SSH_AUTH_METHOD_PASSWORD) { \
-    rc = SSH_OK; \
-    state(conn, SSH_AUTH_PASS_INIT); \
-    break; \
-  } \
-  else { \
-    MOVE_TO_ERROR_STATE(CURLE_LOGIN_DENIED); \
-  }
-
-#define MOVE_TO_TERTIARY_AUTH \
-  if(sshc->auth_methods & SSH_AUTH_METHOD_INTERACTIVE) { \
-    rc = SSH_OK; \
-    state(conn, SSH_AUTH_KEY_INIT); \
-    break; \
-  } \
-  else { \
-    MOVE_TO_LAST_AUTH; \
-  }
-
-#define MOVE_TO_SECONDARY_AUTH \
-  if(sshc->auth_methods & SSH_AUTH_METHOD_GSSAPI_MIC) { \
-    rc = SSH_OK; \
-    state(conn, SSH_AUTH_GSSAPI); \
-    break; \
-  } \
-  else { \
-    MOVE_TO_TERTIARY_AUTH; \
-  }
-
-static
-int myssh_auth_interactive(struct connectdata *conn)
-{
-  int rc;
-  struct ssh_conn *sshc = &conn->proto.sshc;
-  int nprompts;
-
-restart:
-  switch(sshc->kbd_state) {
-    case 0:
-      rc = ssh_userauth_kbdint(sshc->ssh_session, NULL, NULL);
-      if(rc == SSH_AUTH_AGAIN)
-        return SSH_AGAIN;
-
-      if(rc != SSH_AUTH_INFO)
-        return SSH_ERROR;
-
-      nprompts = ssh_userauth_kbdint_getnprompts(sshc->ssh_session);
-      if(nprompts == SSH_ERROR || nprompts != 1)
-        return SSH_ERROR;
-
-      rc = ssh_userauth_kbdint_setanswer(sshc->ssh_session, 0, conn->passwd);
-      if(rc < 0)
-        return SSH_ERROR;
-
-    /* FALLTHROUGH */
-    case 1:
-      sshc->kbd_state = 1;
-
-      rc = ssh_userauth_kbdint(sshc->ssh_session, NULL, NULL);
-      if(rc == SSH_AUTH_AGAIN)
-        return SSH_AGAIN;
-      else if(rc == SSH_AUTH_SUCCESS)
-        rc = SSH_OK;
-      else if(rc == SSH_AUTH_INFO) {
-        nprompts = ssh_userauth_kbdint_getnprompts(sshc->ssh_session);
-        if(nprompts != 0)
-          return SSH_ERROR;
-
-        sshc->kbd_state = 2;
-        goto restart;
-      }
-      else
-        rc = SSH_ERROR;
-      break;
-    case 2:
-      sshc->kbd_state = 2;
-
-      rc = ssh_userauth_kbdint(sshc->ssh_session, NULL, NULL);
-      if(rc == SSH_AUTH_AGAIN)
-        return SSH_AGAIN;
-      else if(rc == SSH_AUTH_SUCCESS)
-        rc = SSH_OK;
-      else
-        rc = SSH_ERROR;
-
-      break;
-    default:
-      return SSH_ERROR;
-  }
-
-  sshc->kbd_state = 0;
-  return rc;
-}
-
-/*
- * ssh_statemach_act() runs the SSH state machine as far as it can without
- * blocking and without reaching the end.  The data the pointer 'block' points
- * to will be set to TRUE if the libssh function returns SSH_AGAIN
- * meaning it wants to be called again when the socket is ready
- */
-static CURLcode myssh_statemach_act(struct connectdata *conn, bool *block)
-{
-  CURLcode result = CURLE_OK;
-  struct Curl_easy *data = conn->data;
-  struct SSHPROTO *protop = data->req.protop;
-  struct ssh_conn *sshc = &conn->proto.sshc;
-  curl_socket_t sock = conn->sock[FIRSTSOCKET];
-  int rc = SSH_NO_ERROR, err;
-  char *new_readdir_line;
-  int seekerr = CURL_SEEKFUNC_OK;
-  const char *err_msg;
-  *block = 0;                   /* we're not blocking by default */
-
-  do {
-
-    switch(sshc->state) {
-    case SSH_INIT:
-      sshc->secondCreateDirs = 0;
-      sshc->nextstate = SSH_NO_STATE;
-      sshc->actualcode = CURLE_OK;
-
-#if 0
-      ssh_set_log_level(SSH_LOG_PROTOCOL);
-#endif
-
-      /* Set libssh to non-blocking, since everything internally is
-         non-blocking */
-      ssh_set_blocking(sshc->ssh_session, 0);
-
-      state(conn, SSH_S_STARTUP);
-      /* FALLTHROUGH */
-
-    case SSH_S_STARTUP:
-      rc = ssh_connect(sshc->ssh_session);
-      if(rc == SSH_AGAIN)
-        break;
-
-      if(rc != SSH_OK) {
-        failf(data, "Failure establishing ssh session");
-        MOVE_TO_ERROR_STATE(CURLE_FAILED_INIT);
-      }
-
-      state(conn, SSH_HOSTKEY);
-
-      /* FALLTHROUGH */
-    case SSH_HOSTKEY:
-
-      rc = myssh_is_known(conn);
-      if(rc != SSH_OK) {
-        MOVE_TO_ERROR_STATE(CURLE_PEER_FAILED_VERIFICATION);
-      }
-
-      state(conn, SSH_AUTHLIST);
-      /* FALLTHROUGH */
-    case SSH_AUTHLIST:{
-        sshc->authed = FALSE;
-
-        rc = ssh_userauth_none(sshc->ssh_session, NULL);
-        if(rc == SSH_AUTH_AGAIN) {
-          rc = SSH_AGAIN;
-          break;
-        }
-
-        if(rc == SSH_AUTH_SUCCESS) {
-          sshc->authed = TRUE;
-          infof(data, "Authenticated with none\n");
-          state(conn, SSH_AUTH_DONE);
-          break;
-        }
-        else if(rc == SSH_AUTH_ERROR) {
-          MOVE_TO_ERROR_STATE(CURLE_LOGIN_DENIED);
-        }
-
-        sshc->auth_methods = ssh_userauth_list(sshc->ssh_session, NULL);
-        if(sshc->auth_methods & SSH_AUTH_METHOD_PUBLICKEY) {
-          state(conn, SSH_AUTH_PKEY_INIT);
-          infof(data, "Authentication using SSH public key file\n");
-        }
-        else if(sshc->auth_methods & SSH_AUTH_METHOD_GSSAPI_MIC) {
-          state(conn, SSH_AUTH_GSSAPI);
-        }
-        else if(sshc->auth_methods & SSH_AUTH_METHOD_INTERACTIVE) {
-          state(conn, SSH_AUTH_KEY_INIT);
-        }
-        else if(sshc->auth_methods & SSH_AUTH_METHOD_PASSWORD) {
-          state(conn, SSH_AUTH_PASS_INIT);
-        }
-        else {                  /* unsupported authentication method */
-          MOVE_TO_ERROR_STATE(CURLE_LOGIN_DENIED);
-        }
-
-        break;
-      }
-    case SSH_AUTH_PKEY_INIT:
-      if(!(data->set.ssh_auth_types & CURLSSH_AUTH_PUBLICKEY)) {
-        MOVE_TO_SECONDARY_AUTH;
-      }
-
-      /* Two choices, (1) private key was given on CMD,
-       * (2) use the "default" keys. */
-      if(data->set.str[STRING_SSH_PRIVATE_KEY]) {
-        if(sshc->pubkey && !data->set.ssl.key_passwd) {
-          rc = ssh_userauth_try_publickey(sshc->ssh_session, NULL,
-                                          sshc->pubkey);
-          if(rc == SSH_AUTH_AGAIN) {
-            rc = SSH_AGAIN;
-            break;
-          }
-
-          if(rc != SSH_OK) {
-            MOVE_TO_SECONDARY_AUTH;
-          }
-        }
-
-        rc = ssh_pki_import_privkey_file(data->
-                                         set.str[STRING_SSH_PRIVATE_KEY],
-                                         data->set.ssl.key_passwd, NULL,
-                                         NULL, &sshc->privkey);
-        if(rc != SSH_OK) {
-          failf(data, "Could not load private key file %s",
-                data->set.str[STRING_SSH_PRIVATE_KEY]);
-          MOVE_TO_ERROR_STATE(CURLE_LOGIN_DENIED);
-          break;
-        }
-
-        state(conn, SSH_AUTH_PKEY);
-        break;
-
-      }
-      else {
-        rc = ssh_userauth_publickey_auto(sshc->ssh_session, NULL,
-                                         data->set.ssl.key_passwd);
-        if(rc == SSH_AUTH_AGAIN) {
-          rc = SSH_AGAIN;
-          break;
-        }
-        if(rc == SSH_AUTH_SUCCESS) {
-          rc = SSH_OK;
-          sshc->authed = TRUE;
-          infof(data, "Completed public key authentication\n");
-          state(conn, SSH_AUTH_DONE);
-          break;
-        }
-
-        MOVE_TO_SECONDARY_AUTH;
-      }
-      break;
-    case SSH_AUTH_PKEY:
-      rc = ssh_userauth_publickey(sshc->ssh_session, NULL, sshc->privkey);
-      if(rc == SSH_AUTH_AGAIN) {
-        rc = SSH_AGAIN;
-        break;
-      }
-
-      if(rc == SSH_AUTH_SUCCESS) {
-        sshc->authed = TRUE;
-        infof(data, "Completed public key authentication\n");
-        state(conn, SSH_AUTH_DONE);
-        break;
-      }
-      else {
-        infof(data, "Failed public key authentication (rc: %d)\n", rc);
-        MOVE_TO_SECONDARY_AUTH;
-      }
-      break;
-
-    case SSH_AUTH_GSSAPI:
-      if(!(data->set.ssh_auth_types & CURLSSH_AUTH_GSSAPI)) {
-        MOVE_TO_TERTIARY_AUTH;
-      }
-
-      rc = ssh_userauth_gssapi(sshc->ssh_session);
-      if(rc == SSH_AUTH_AGAIN) {
-        rc = SSH_AGAIN;
-        break;
-      }
-
-      if(rc == SSH_AUTH_SUCCESS) {
-        rc = SSH_OK;
-        sshc->authed = TRUE;
-        infof(data, "Completed gssapi authentication\n");
-        state(conn, SSH_AUTH_DONE);
-        break;
-      }
-
-      MOVE_TO_TERTIARY_AUTH;
-      break;
-
-    case SSH_AUTH_KEY_INIT:
-      if(data->set.ssh_auth_types & CURLSSH_AUTH_KEYBOARD) {
-        state(conn, SSH_AUTH_KEY);
-      }
-      else {
-        MOVE_TO_LAST_AUTH;
-      }
-      break;
-
-    case SSH_AUTH_KEY:
-
-      /* Authentication failed. Continue with keyboard-interactive now. */
-      rc = myssh_auth_interactive(conn);
-      if(rc == SSH_AGAIN) {
-        break;
-      }
-      if(rc == SSH_OK) {
-        sshc->authed = TRUE;
-        infof(data, "completed keyboard interactive authentication\n");
-      }
-      state(conn, SSH_AUTH_DONE);
-      break;
-
-    case SSH_AUTH_PASS_INIT:
-      if(!(data->set.ssh_auth_types & CURLSSH_AUTH_PASSWORD)) {
-        /* Host key authentication is intentionally not implemented */
-        MOVE_TO_ERROR_STATE(CURLE_LOGIN_DENIED);
-      }
-      state(conn, SSH_AUTH_PASS);
-      /* FALLTHROUGH */
-
-    case SSH_AUTH_PASS:
-      rc = ssh_userauth_password(sshc->ssh_session, NULL, conn->passwd);
-      if(rc == SSH_AUTH_AGAIN) {
-        rc = SSH_AGAIN;
-        break;
-      }
-
-      if(rc == SSH_AUTH_SUCCESS) {
-        sshc->authed = TRUE;
-        infof(data, "Completed password authentication\n");
-        state(conn, SSH_AUTH_DONE);
-      }
-      else {
-        MOVE_TO_ERROR_STATE(CURLE_LOGIN_DENIED);
-      }
-      break;
-
-    case SSH_AUTH_DONE:
-      if(!sshc->authed) {
-        failf(data, "Authentication failure");
-        MOVE_TO_ERROR_STATE(CURLE_LOGIN_DENIED);
-        break;
-      }
-
-      /*
-       * At this point we have an authenticated ssh session.
-       */
-      infof(data, "Authentication complete\n");
-
-      Curl_pgrsTime(conn->data, TIMER_APPCONNECT);      /* SSH is connected */
-
-      conn->sockfd = sock;
-      conn->writesockfd = CURL_SOCKET_BAD;
-
-      if(conn->handler->protocol == CURLPROTO_SFTP) {
-        state(conn, SSH_SFTP_INIT);
-        break;
-      }
-      infof(data, "SSH CONNECT phase done\n");
-      state(conn, SSH_STOP);
-      break;
-
-    case SSH_SFTP_INIT:
-      ssh_set_blocking(sshc->ssh_session, 1);
-
-      sshc->sftp_session = sftp_new(sshc->ssh_session);
-      if(!sshc->sftp_session) {
-        failf(data, "Failure initializing sftp session: %s",
-              ssh_get_error(sshc->ssh_session));
-        MOVE_TO_ERROR_STATE(CURLE_COULDNT_CONNECT);
-        break;
-      }
-
-      rc = sftp_init(sshc->sftp_session);
-      if(rc != SSH_OK) {
-        rc = sftp_get_error(sshc->sftp_session);
-        failf(data, "Failure initializing sftp session: %s",
-              ssh_get_error(sshc->ssh_session));
-        MOVE_TO_ERROR_STATE(sftp_error_to_CURLE(rc));
-        break;
-      }
-      state(conn, SSH_SFTP_REALPATH);
-      /* FALLTHROUGH */
-    case SSH_SFTP_REALPATH:
-      /*
-       * Get the "home" directory
-       */
-      sshc->homedir = sftp_canonicalize_path(sshc->sftp_session, ".");
-      if(sshc->homedir == NULL) {
-        MOVE_TO_ERROR_STATE(CURLE_COULDNT_CONNECT);
-      }
-      conn->data->state.most_recent_ftp_entrypath = sshc->homedir;
-
-      /* This is the last step in the SFTP connect phase. Do note that while
-         we get the homedir here, we get the "workingpath" in the DO action
-         since the homedir will remain the same between request but the
-         working path will not. */
-      DEBUGF(infof(data, "SSH CONNECT phase done\n"));
-      state(conn, SSH_STOP);
-      break;
-
-    case SSH_SFTP_QUOTE_INIT:
-
-      result = Curl_getworkingpath(conn, sshc->homedir, &protop->path);
-      if(result) {
-        sshc->actualcode = result;
-        state(conn, SSH_STOP);
-        break;
-      }
-
-      if(data->set.quote) {
-        infof(data, "Sending quote commands\n");
-        sshc->quote_item = data->set.quote;
-        state(conn, SSH_SFTP_QUOTE);
-      }
-      else {
-        state(conn, SSH_SFTP_GETINFO);
-      }
-      break;
-
-    case SSH_SFTP_POSTQUOTE_INIT:
-      if(data->set.postquote) {
-        infof(data, "Sending quote commands\n");
-        sshc->quote_item = data->set.postquote;
-        state(conn, SSH_SFTP_QUOTE);
-      }
-      else {
-        state(conn, SSH_STOP);
-      }
-      break;
-
-    case SSH_SFTP_QUOTE:
-      /* Send any quote commands */
-      sftp_quote(conn);
-      break;
-
-    case SSH_SFTP_NEXT_QUOTE:
-      Curl_safefree(sshc->quote_path1);
-      Curl_safefree(sshc->quote_path2);
-
-      sshc->quote_item = sshc->quote_item->next;
-
-      if(sshc->quote_item) {
-        state(conn, SSH_SFTP_QUOTE);
-      }
-      else {
-        if(sshc->nextstate != SSH_NO_STATE) {
-          state(conn, sshc->nextstate);
-          sshc->nextstate = SSH_NO_STATE;
-        }
-        else {
-          state(conn, SSH_SFTP_GETINFO);
-        }
-      }
-      break;
-
-    case SSH_SFTP_QUOTE_STAT:
-      sftp_quote_stat(conn);
-      break;
-
-    case SSH_SFTP_QUOTE_SETSTAT:
-      rc = sftp_setstat(sshc->sftp_session, sshc->quote_path2,
-                        sshc->quote_attrs);
-      if(rc != 0 && !sshc->acceptfail) {
-        Curl_safefree(sshc->quote_path1);
-        Curl_safefree(sshc->quote_path2);
-        failf(data, "Attempt to set SFTP stats failed: %s",
-              ssh_get_error(sshc->ssh_session));
-        state(conn, SSH_SFTP_CLOSE);
-        sshc->nextstate = SSH_NO_STATE;
-        sshc->actualcode = CURLE_QUOTE_ERROR;
-        /* sshc->actualcode = sftp_error_to_CURLE(err);
-         * we do not send the actual error; we return
-         * the error the libssh2 backend is returning */
-        break;
-      }
-      state(conn, SSH_SFTP_NEXT_QUOTE);
-      break;
-
-    case SSH_SFTP_QUOTE_SYMLINK:
-      rc = sftp_symlink(sshc->sftp_session, sshc->quote_path2,
-                        sshc->quote_path1);
-      if(rc != 0 && !sshc->acceptfail) {
-        Curl_safefree(sshc->quote_path1);
-        Curl_safefree(sshc->quote_path2);
-        failf(data, "symlink command failed: %s",
-              ssh_get_error(sshc->ssh_session));
-        state(conn, SSH_SFTP_CLOSE);
-        sshc->nextstate = SSH_NO_STATE;
-        sshc->actualcode = CURLE_QUOTE_ERROR;
-        break;
-      }
-      state(conn, SSH_SFTP_NEXT_QUOTE);
-      break;
-
-    case SSH_SFTP_QUOTE_MKDIR:
-      rc = sftp_mkdir(sshc->sftp_session, sshc->quote_path1,
-                      (mode_t)data->set.new_directory_perms);
-      if(rc != 0 && !sshc->acceptfail) {
-        Curl_safefree(sshc->quote_path1);
-        failf(data, "mkdir command failed: %s",
-              ssh_get_error(sshc->ssh_session));
-        state(conn, SSH_SFTP_CLOSE);
-        sshc->nextstate = SSH_NO_STATE;
-        sshc->actualcode = CURLE_QUOTE_ERROR;
-        break;
-      }
-      state(conn, SSH_SFTP_NEXT_QUOTE);
-      break;
-
-    case SSH_SFTP_QUOTE_RENAME:
-      rc = sftp_rename(sshc->sftp_session, sshc->quote_path1,
-                       sshc->quote_path2);
-      if(rc != 0 && !sshc->acceptfail) {
-        Curl_safefree(sshc->quote_path1);
-        Curl_safefree(sshc->quote_path2);
-        failf(data, "rename command failed: %s",
-              ssh_get_error(sshc->ssh_session));
-        state(conn, SSH_SFTP_CLOSE);
-        sshc->nextstate = SSH_NO_STATE;
-        sshc->actualcode = CURLE_QUOTE_ERROR;
-        break;
-      }
-      state(conn, SSH_SFTP_NEXT_QUOTE);
-      break;
-
-    case SSH_SFTP_QUOTE_RMDIR:
-      rc = sftp_rmdir(sshc->sftp_session, sshc->quote_path1);
-      if(rc != 0 && !sshc->acceptfail) {
-        Curl_safefree(sshc->quote_path1);
-        failf(data, "rmdir command failed: %s",
-              ssh_get_error(sshc->ssh_session));
-        state(conn, SSH_SFTP_CLOSE);
-        sshc->nextstate = SSH_NO_STATE;
-        sshc->actualcode = CURLE_QUOTE_ERROR;
-        break;
-      }
-      state(conn, SSH_SFTP_NEXT_QUOTE);
-      break;
-
-    case SSH_SFTP_QUOTE_UNLINK:
-      rc = sftp_unlink(sshc->sftp_session, sshc->quote_path1);
-      if(rc != 0 && !sshc->acceptfail) {
-        Curl_safefree(sshc->quote_path1);
-        failf(data, "rm command failed: %s",
-              ssh_get_error(sshc->ssh_session));
-        state(conn, SSH_SFTP_CLOSE);
-        sshc->nextstate = SSH_NO_STATE;
-        sshc->actualcode = CURLE_QUOTE_ERROR;
-        break;
-      }
-      state(conn, SSH_SFTP_NEXT_QUOTE);
-      break;
-
-    case SSH_SFTP_QUOTE_STATVFS:
-    {
-      sftp_statvfs_t statvfs;
-
-      statvfs = sftp_statvfs(sshc->sftp_session, sshc->quote_path1);
-      if(!statvfs && !sshc->acceptfail) {
-        Curl_safefree(sshc->quote_path1);
-        failf(data, "statvfs command failed: %s",
-              ssh_get_error(sshc->ssh_session));
-        state(conn, SSH_SFTP_CLOSE);
-        sshc->nextstate = SSH_NO_STATE;
-        sshc->actualcode = CURLE_QUOTE_ERROR;
-        break;
-      }
-      else if(statvfs) {
-        char *tmp = aprintf("statvfs:\n"
-                            "f_bsize: %llu\n" "f_frsize: %llu\n"
-                            "f_blocks: %llu\n" "f_bfree: %llu\n"
-                            "f_bavail: %llu\n" "f_files: %llu\n"
-                            "f_ffree: %llu\n" "f_favail: %llu\n"
-                            "f_fsid: %llu\n" "f_flag: %llu\n"
-                            "f_namemax: %llu\n",
-                            statvfs->f_bsize, statvfs->f_frsize,
-                            statvfs->f_blocks, statvfs->f_bfree,
-                            statvfs->f_bavail, statvfs->f_files,
-                            statvfs->f_ffree, statvfs->f_favail,
-                            statvfs->f_fsid, statvfs->f_flag,
-                            statvfs->f_namemax);
-        sftp_statvfs_free(statvfs);
-
-        if(!tmp) {
-          result = CURLE_OUT_OF_MEMORY;
-          state(conn, SSH_SFTP_CLOSE);
-          sshc->nextstate = SSH_NO_STATE;
-          break;
-        }
-
-        result = Curl_client_write(conn, CLIENTWRITE_HEADER, tmp, strlen(tmp));
-        free(tmp);
-        if(result) {
-          state(conn, SSH_SFTP_CLOSE);
-          sshc->nextstate = SSH_NO_STATE;
-          sshc->actualcode = result;
-        }
-      }
-      state(conn, SSH_SFTP_NEXT_QUOTE);
-      break;
-    }
-
-    case SSH_SFTP_GETINFO:
-      if(data->set.get_filetime) {
-        state(conn, SSH_SFTP_FILETIME);
-      }
-      else {
-        state(conn, SSH_SFTP_TRANS_INIT);
-      }
-      break;
-
-    case SSH_SFTP_FILETIME:
-    {
-      sftp_attributes attrs;
-
-      attrs = sftp_stat(sshc->sftp_session, protop->path);
-      if(attrs != 0) {
-        data->info.filetime = attrs->mtime;
-        sftp_attributes_free(attrs);
-      }
-
-      state(conn, SSH_SFTP_TRANS_INIT);
-      break;
-    }
-
-    case SSH_SFTP_TRANS_INIT:
-      if(data->set.upload)
-        state(conn, SSH_SFTP_UPLOAD_INIT);
-      else {
-        if(protop->path[strlen(protop->path)-1] == '/')
-          state(conn, SSH_SFTP_READDIR_INIT);
-        else
-          state(conn, SSH_SFTP_DOWNLOAD_INIT);
-      }
-      break;
-
-    case SSH_SFTP_UPLOAD_INIT:
-    {
-      int flags;
-
-      if(data->state.resume_from != 0) {
-        sftp_attributes attrs;
-
-        if(data->state.resume_from < 0) {
-          attrs = sftp_stat(sshc->sftp_session, protop->path);
-          if(attrs != 0) {
-            curl_off_t size = attrs->size;
-            if(size < 0) {
-              failf(data, "Bad file size (%" CURL_FORMAT_CURL_OFF_T ")", size);
-              MOVE_TO_ERROR_STATE(CURLE_BAD_DOWNLOAD_RESUME);
-            }
-            data->state.resume_from = attrs->size;
-
-            sftp_attributes_free(attrs);
-          }
-          else {
-            data->state.resume_from = 0;
-          }
-        }
-      }
-
-      if(data->set.ftp_append)
-        /* Try to open for append, but create if nonexisting */
-        flags = O_WRONLY|O_CREAT|O_APPEND;
-      else if(data->state.resume_from > 0)
-        /* If we have restart position then open for append */
-        flags = O_WRONLY|O_APPEND;
-      else
-        /* Clear file before writing (normal behaviour) */
-        flags = O_WRONLY|O_APPEND|O_CREAT|O_TRUNC;
-
-      if(sshc->sftp_file)
-        sftp_close(sshc->sftp_file);
-      sshc->sftp_file =
-        sftp_open(sshc->sftp_session, protop->path,
-                  flags, (mode_t)data->set.new_file_perms);
-      if(!sshc->sftp_file) {
-        err = sftp_get_error(sshc->sftp_session);
-
-        if(((err == SSH_FX_NO_SUCH_FILE || err == SSH_FX_FAILURE ||
-             err == SSH_FX_NO_SUCH_PATH)) &&
-             (data->set.ftp_create_missing_dirs &&
-             (strlen(protop->path) > 1))) {
-               /* try to create the path remotely */
-               rc = 0;
-               sshc->secondCreateDirs = 1;
-               state(conn, SSH_SFTP_CREATE_DIRS_INIT);
-               break;
-        }
-        else {
-          MOVE_TO_SFTP_CLOSE_STATE();
-        }
-      }
-
-      /* If we have a restart point then we need to seek to the correct
-         position. */
-      if(data->state.resume_from > 0) {
-        /* Let's read off the proper amount of bytes from the input. */
-        if(conn->seek_func) {
-          Curl_set_in_callback(data, true);
-          seekerr = conn->seek_func(conn->seek_client, data->state.resume_from,
-                                    SEEK_SET);
-          Curl_set_in_callback(data, false);
-        }
-
-        if(seekerr != CURL_SEEKFUNC_OK) {
-          curl_off_t passed = 0;
-
-          if(seekerr != CURL_SEEKFUNC_CANTSEEK) {
-            failf(data, "Could not seek stream");
-            return CURLE_FTP_COULDNT_USE_REST;
-          }
-          /* seekerr == CURL_SEEKFUNC_CANTSEEK (can't seek to offset) */
-          do {
-            size_t readthisamountnow =
-              (data->state.resume_from - passed > data->set.buffer_size) ?
-              (size_t)data->set.buffer_size :
-              curlx_sotouz(data->state.resume_from - passed);
-
-            size_t actuallyread =
-              data->state.fread_func(data->state.buffer, 1,
-                                     readthisamountnow, data->state.in);
-
-            passed += actuallyread;
-            if((actuallyread == 0) || (actuallyread > readthisamountnow)) {
-              /* this checks for greater-than only to make sure that the
-                 CURL_READFUNC_ABORT return code still aborts */
-              failf(data, "Failed to read data");
-              MOVE_TO_ERROR_STATE(CURLE_FTP_COULDNT_USE_REST);
-            }
-          } while(passed < data->state.resume_from);
-        }
-
-        /* now, decrease the size of the read */
-        if(data->state.infilesize > 0) {
-          data->state.infilesize -= data->state.resume_from;
-          data->req.size = data->state.infilesize;
-          Curl_pgrsSetUploadSize(data, data->state.infilesize);
-        }
-
-        rc = sftp_seek64(sshc->sftp_file, data->state.resume_from);
-        if(rc != 0) {
-          MOVE_TO_SFTP_CLOSE_STATE();
-        }
-      }
-      if(data->state.infilesize > 0) {
-        data->req.size = data->state.infilesize;
-        Curl_pgrsSetUploadSize(data, data->state.infilesize);
-      }
-      /* upload data */
-      Curl_setup_transfer(data, -1, -1, FALSE, FIRSTSOCKET);
-
-      /* not set by Curl_setup_transfer to preserve keepon bits */
-      conn->sockfd = conn->writesockfd;
-
-      /* store this original bitmask setup to use later on if we can't
-         figure out a "real" bitmask */
-      sshc->orig_waitfor = data->req.keepon;
-
-      /* we want to use the _sending_ function even when the socket turns
-         out readable as the underlying libssh sftp send function will deal
-         with both accordingly */
-      conn->cselect_bits = CURL_CSELECT_OUT;
-
-      /* since we don't really wait for anything at this point, we want the
-         state machine to move on as soon as possible so we set a very short
-         timeout here */
-      Curl_expire(data, 0, EXPIRE_RUN_NOW);
-
-      state(conn, SSH_STOP);
-      break;
-    }
-
-    case SSH_SFTP_CREATE_DIRS_INIT:
-      if(strlen(protop->path) > 1) {
-        sshc->slash_pos = protop->path + 1; /* ignore the leading '/' */
-        state(conn, SSH_SFTP_CREATE_DIRS);
-      }
-      else {
-        state(conn, SSH_SFTP_UPLOAD_INIT);
-      }
-      break;
-
-    case SSH_SFTP_CREATE_DIRS:
-      sshc->slash_pos = strchr(sshc->slash_pos, '/');
-      if(sshc->slash_pos) {
-        *sshc->slash_pos = 0;
-
-        infof(data, "Creating directory '%s'\n", protop->path);
-        state(conn, SSH_SFTP_CREATE_DIRS_MKDIR);
-        break;
-      }
-      state(conn, SSH_SFTP_UPLOAD_INIT);
-      break;
-
-    case SSH_SFTP_CREATE_DIRS_MKDIR:
-      /* 'mode' - parameter is preliminary - default to 0644 */
-      rc = sftp_mkdir(sshc->sftp_session, protop->path,
-                      (mode_t)data->set.new_directory_perms);
-      *sshc->slash_pos = '/';
-      ++sshc->slash_pos;
-      if(rc < 0) {
-        /*
-         * Abort if failure wasn't that the dir already exists or the
-         * permission was denied (creation might succeed further down the
-         * path) - retry on unspecific FAILURE also
-         */
-        err = sftp_get_error(sshc->sftp_session);
-        if((err != SSH_FX_FILE_ALREADY_EXISTS) &&
-           (err != SSH_FX_FAILURE) &&
-           (err != SSH_FX_PERMISSION_DENIED)) {
-          MOVE_TO_SFTP_CLOSE_STATE();
-        }
-        rc = 0; /* clear rc and continue */
-      }
-      state(conn, SSH_SFTP_CREATE_DIRS);
-      break;
-
-    case SSH_SFTP_READDIR_INIT:
-      Curl_pgrsSetDownloadSize(data, -1);
-      if(data->set.opt_no_body) {
-        state(conn, SSH_STOP);
-        break;
-      }
-
-      /*
-       * This is a directory that we are trying to get, so produce a directory
-       * listing
-       */
-      sshc->sftp_dir = sftp_opendir(sshc->sftp_session,
-                                    protop->path);
-      if(!sshc->sftp_dir) {
-        failf(data, "Could not open directory for reading: %s",
-              ssh_get_error(sshc->ssh_session));
-        MOVE_TO_SFTP_CLOSE_STATE();
-      }
-      state(conn, SSH_SFTP_READDIR);
-      break;
-
-    case SSH_SFTP_READDIR:
-
-      if(sshc->readdir_attrs)
-        sftp_attributes_free(sshc->readdir_attrs);
-
-      sshc->readdir_attrs = sftp_readdir(sshc->sftp_session, sshc->sftp_dir);
-      if(sshc->readdir_attrs) {
-        sshc->readdir_filename = sshc->readdir_attrs->name;
-        sshc->readdir_longentry = sshc->readdir_attrs->longname;
-        sshc->readdir_len = strlen(sshc->readdir_filename);
-
-        if(data->set.ftp_list_only) {
-          char *tmpLine;
-
-          tmpLine = aprintf("%s\n", sshc->readdir_filename);
-          if(tmpLine == NULL) {
-            state(conn, SSH_SFTP_CLOSE);
-            sshc->actualcode = CURLE_OUT_OF_MEMORY;
-            break;
-          }
-          result = Curl_client_write(conn, CLIENTWRITE_BODY,
-                                     tmpLine, sshc->readdir_len + 1);
-          free(tmpLine);
-
-          if(result) {
-            state(conn, SSH_STOP);
-            break;
-          }
-          /* since this counts what we send to the client, we include the
-             newline in this counter */
-          data->req.bytecount += sshc->readdir_len + 1;
-
-          /* output debug output if that is requested */
-          if(data->set.verbose) {
-            Curl_debug(data, CURLINFO_DATA_OUT,
-                       (char *)sshc->readdir_filename,
-                       sshc->readdir_len);
-          }
-        }
-        else {
-          sshc->readdir_currLen = strlen(sshc->readdir_longentry);
-          sshc->readdir_totalLen = 80 + sshc->readdir_currLen;
-          sshc->readdir_line = calloc(sshc->readdir_totalLen, 1);
-          if(!sshc->readdir_line) {
-            state(conn, SSH_SFTP_CLOSE);
-            sshc->actualcode = CURLE_OUT_OF_MEMORY;
-            break;
-          }
-
-          memcpy(sshc->readdir_line, sshc->readdir_longentry,
-                 sshc->readdir_currLen);
-          if((sshc->readdir_attrs->flags & SSH_FILEXFER_ATTR_PERMISSIONS) &&
-             ((sshc->readdir_attrs->permissions & S_IFMT) ==
-              S_IFLNK)) {
-            sshc->readdir_linkPath = malloc(PATH_MAX + 1);
-            if(sshc->readdir_linkPath == NULL) {
-              state(conn, SSH_SFTP_CLOSE);
-              sshc->actualcode = CURLE_OUT_OF_MEMORY;
-              break;
-            }
-
-            msnprintf(sshc->readdir_linkPath, PATH_MAX, "%s%s", protop->path,
-                      sshc->readdir_filename);
-
-            state(conn, SSH_SFTP_READDIR_LINK);
-            break;
-          }
-          state(conn, SSH_SFTP_READDIR_BOTTOM);
-          break;
-        }
-      }
-      else if(sshc->readdir_attrs == NULL && sftp_dir_eof(sshc->sftp_dir)) {
-        state(conn, SSH_SFTP_READDIR_DONE);
-        break;
-      }
-      else {
-        failf(data, "Could not open remote file for reading: %s",
-              ssh_get_error(sshc->ssh_session));
-        MOVE_TO_SFTP_CLOSE_STATE();
-        break;
-      }
-      break;
-
-    case SSH_SFTP_READDIR_LINK:
-      if(sshc->readdir_link_attrs)
-        sftp_attributes_free(sshc->readdir_link_attrs);
-
-      sshc->readdir_link_attrs = sftp_lstat(sshc->sftp_session,
-                                            sshc->readdir_linkPath);
-      if(sshc->readdir_link_attrs == 0) {
-        failf(data, "Could not read symlink for reading: %s",
-              ssh_get_error(sshc->ssh_session));
-        MOVE_TO_SFTP_CLOSE_STATE();
-      }
-
-      if(sshc->readdir_link_attrs->name == NULL) {
-        sshc->readdir_tmp = sftp_readlink(sshc->sftp_session,
-                                          sshc->readdir_linkPath);
-        if(sshc->readdir_filename == NULL)
-          sshc->readdir_len = 0;
-        else
-          sshc->readdir_len = strlen(sshc->readdir_tmp);
-        sshc->readdir_longentry = NULL;
-        sshc->readdir_filename = sshc->readdir_tmp;
-      }
-      else {
-        sshc->readdir_len = strlen(sshc->readdir_link_attrs->name);
-        sshc->readdir_filename = sshc->readdir_link_attrs->name;
-        sshc->readdir_longentry = sshc->readdir_link_attrs->longname;
-      }
-
-      Curl_safefree(sshc->readdir_linkPath);
-
-      /* get room for the filename and extra output */
-      sshc->readdir_totalLen += 4 + sshc->readdir_len;
-      new_readdir_line = Curl_saferealloc(sshc->readdir_line,
-                                          sshc->readdir_totalLen);
-      if(!new_readdir_line) {
-        sshc->readdir_line = NULL;
-        state(conn, SSH_SFTP_CLOSE);
-        sshc->actualcode = CURLE_OUT_OF_MEMORY;
-        break;
-      }
-      sshc->readdir_line = new_readdir_line;
-
-      sshc->readdir_currLen += msnprintf(sshc->readdir_line +
-                                         sshc->readdir_currLen,
-                                         sshc->readdir_totalLen -
-                                         sshc->readdir_currLen,
-                                         " -> %s",
-                                         sshc->readdir_filename);
-
-      sftp_attributes_free(sshc->readdir_link_attrs);
-      sshc->readdir_link_attrs = NULL;
-      sshc->readdir_filename = NULL;
-      sshc->readdir_longentry = NULL;
-
-      state(conn, SSH_SFTP_READDIR_BOTTOM);
-      /* FALLTHROUGH */
-    case SSH_SFTP_READDIR_BOTTOM:
-      sshc->readdir_currLen += msnprintf(sshc->readdir_line +
-                                         sshc->readdir_currLen,
-                                         sshc->readdir_totalLen -
-                                         sshc->readdir_currLen, "\n");
-      result = Curl_client_write(conn, CLIENTWRITE_BODY,
-                                 sshc->readdir_line,
-                                 sshc->readdir_currLen);
-
-      if(!result) {
-
-        /* output debug output if that is requested */
-        if(data->set.verbose) {
-          Curl_debug(data, CURLINFO_DATA_OUT, sshc->readdir_line,
-                     sshc->readdir_currLen);
-        }
-        data->req.bytecount += sshc->readdir_currLen;
-      }
-      Curl_safefree(sshc->readdir_line);
-      ssh_string_free_char(sshc->readdir_tmp);
-      sshc->readdir_tmp = NULL;
-
-      if(result) {
-        state(conn, SSH_STOP);
-      }
-      else
-        state(conn, SSH_SFTP_READDIR);
-      break;
-
-    case SSH_SFTP_READDIR_DONE:
-      sftp_closedir(sshc->sftp_dir);
-      sshc->sftp_dir = NULL;
-
-      /* no data to transfer */
-      Curl_setup_transfer(data, -1, -1, FALSE, -1);
-      state(conn, SSH_STOP);
-      break;
-
-    case SSH_SFTP_DOWNLOAD_INIT:
-      /*
-       * Work on getting the specified file
-       */
-      if(sshc->sftp_file)
-        sftp_close(sshc->sftp_file);
-
-      sshc->sftp_file = sftp_open(sshc->sftp_session, protop->path,
-                                  O_RDONLY, (mode_t)data->set.new_file_perms);
-      if(!sshc->sftp_file) {
-        failf(data, "Could not open remote file for reading: %s",
-              ssh_get_error(sshc->ssh_session));
-
-        MOVE_TO_SFTP_CLOSE_STATE();
-      }
-
-      state(conn, SSH_SFTP_DOWNLOAD_STAT);
-      break;
-
-    case SSH_SFTP_DOWNLOAD_STAT:
-    {
-      sftp_attributes attrs;
-      curl_off_t size;
-
-      attrs = sftp_fstat(sshc->sftp_file);
-      if(!attrs ||
-              !(attrs->flags & SSH_FILEXFER_ATTR_SIZE) ||
-              (attrs->size == 0)) {
-        /*
-         * sftp_fstat didn't return an error, so maybe the server
-         * just doesn't support stat()
-         * OR the server doesn't return a file size with a stat()
-         * OR file size is 0
-         */
-        data->req.size = -1;
-        data->req.maxdownload = -1;
-        Curl_pgrsSetDownloadSize(data, -1);
-        size = 0;
-      }
-      else {
-        size = attrs->size;
-
-        sftp_attributes_free(attrs);
-
-        if(size < 0) {
-          failf(data, "Bad file size (%" CURL_FORMAT_CURL_OFF_T ")", size);
-          return CURLE_BAD_DOWNLOAD_RESUME;
-        }
-        if(conn->data->state.use_range) {
-          curl_off_t from, to;
-          char *ptr;
-          char *ptr2;
-          CURLofft to_t;
-          CURLofft from_t;
-
-          from_t = curlx_strtoofft(conn->data->state.range, &ptr, 0, &from);
-          if(from_t == CURL_OFFT_FLOW) {
-            return CURLE_RANGE_ERROR;
-          }
-          while(*ptr && (ISSPACE(*ptr) || (*ptr == '-')))
-            ptr++;
-          to_t = curlx_strtoofft(ptr, &ptr2, 0, &to);
-          if(to_t == CURL_OFFT_FLOW) {
-            return CURLE_RANGE_ERROR;
-          }
-          if((to_t == CURL_OFFT_INVAL) /* no "to" value given */
-             || (to >= size)) {
-            to = size - 1;
-          }
-          if(from_t) {
-            /* from is relative to end of file */
-            from = size - to;
-            to = size - 1;
-          }
-          if(from > size) {
-            failf(data, "Offset (%"
-                  CURL_FORMAT_CURL_OFF_T ") was beyond file size (%"
-                  CURL_FORMAT_CURL_OFF_T ")", from, size);
-            return CURLE_BAD_DOWNLOAD_RESUME;
-          }
-          if(from > to) {
-            from = to;
-            size = 0;
-          }
-          else {
-            size = to - from + 1;
-          }
-
-          rc = sftp_seek64(sshc->sftp_file, from);
-          if(rc != 0) {
-            MOVE_TO_SFTP_CLOSE_STATE();
-          }
-        }
-        data->req.size = size;
-        data->req.maxdownload = size;
-        Curl_pgrsSetDownloadSize(data, size);
-      }
-
-      /* We can resume if we can seek to the resume position */
-      if(data->state.resume_from) {
-        if(data->state.resume_from < 0) {
-          /* We're supposed to download the last abs(from) bytes */
-          if((curl_off_t)size < -data->state.resume_from) {
-            failf(data, "Offset (%"
-                  CURL_FORMAT_CURL_OFF_T ") was beyond file size (%"
-                  CURL_FORMAT_CURL_OFF_T ")",
-                  data->state.resume_from, size);
-            return CURLE_BAD_DOWNLOAD_RESUME;
-          }
-          /* download from where? */
-          data->state.resume_from += size;
-        }
-        else {
-          if((curl_off_t)size < data->state.resume_from) {
-            failf(data, "Offset (%" CURL_FORMAT_CURL_OFF_T
-                  ") was beyond file size (%" CURL_FORMAT_CURL_OFF_T ")",
-                  data->state.resume_from, size);
-            return CURLE_BAD_DOWNLOAD_RESUME;
-          }
-        }
-        /* Does a completed file need to be seeked and started or closed ? */
-        /* Now store the number of bytes we are expected to download */
-        data->req.size = size - data->state.resume_from;
-        data->req.maxdownload = size - data->state.resume_from;
-        Curl_pgrsSetDownloadSize(data,
-                                 size - data->state.resume_from);
-
-        rc = sftp_seek64(sshc->sftp_file, data->state.resume_from);
-        if(rc != 0) {
-          MOVE_TO_SFTP_CLOSE_STATE();
-        }
-      }
-    }
-
-    /* Setup the actual download */
-    if(data->req.size == 0) {
-      /* no data to transfer */
-      Curl_setup_transfer(data, -1, -1, FALSE, -1);
-      infof(data, "File already completely downloaded\n");
-      state(conn, SSH_STOP);
-      break;
-    }
-    Curl_setup_transfer(data, FIRSTSOCKET, data->req.size, FALSE, -1);
-
-    /* not set by Curl_setup_transfer to preserve keepon bits */
-    conn->writesockfd = conn->sockfd;
-
-    /* we want to use the _receiving_ function even when the socket turns
-       out writableable as the underlying libssh recv function will deal
-       with both accordingly */
-    conn->cselect_bits = CURL_CSELECT_IN;
-
-    if(result) {
-      /* this should never occur; the close state should be entered
-         at the time the error occurs */
-      state(conn, SSH_SFTP_CLOSE);
-      sshc->actualcode = result;
-    }
-    else {
-      sshc->sftp_recv_state = 0;
-      state(conn, SSH_STOP);
-    }
-    break;
-
-    case SSH_SFTP_CLOSE:
-      if(sshc->sftp_file) {
-        sftp_close(sshc->sftp_file);
-        sshc->sftp_file = NULL;
-      }
-      Curl_safefree(protop->path);
-
-      DEBUGF(infof(data, "SFTP DONE done\n"));
-
-      /* Check if nextstate is set and move .nextstate could be POSTQUOTE_INIT
-         After nextstate is executed, the control should come back to
-         SSH_SFTP_CLOSE to pass the correct result back  */
-      if(sshc->nextstate != SSH_NO_STATE &&
-         sshc->nextstate != SSH_SFTP_CLOSE) {
-        state(conn, sshc->nextstate);
-        sshc->nextstate = SSH_SFTP_CLOSE;
-      }
-      else {
-        state(conn, SSH_STOP);
-        result = sshc->actualcode;
-      }
-      break;
-
-    case SSH_SFTP_SHUTDOWN:
-      /* during times we get here due to a broken transfer and then the
-         sftp_handle might not have been taken down so make sure that is done
-         before we proceed */
-
-      if(sshc->sftp_file) {
-        sftp_close(sshc->sftp_file);
-        sshc->sftp_file = NULL;
-      }
-
-      if(sshc->sftp_session) {
-        sftp_free(sshc->sftp_session);
-        sshc->sftp_session = NULL;
-      }
-
-      SSH_STRING_FREE_CHAR(sshc->homedir);
-      conn->data->state.most_recent_ftp_entrypath = NULL;
-
-      state(conn, SSH_SESSION_DISCONNECT);
-      break;
-
-
-    case SSH_SCP_TRANS_INIT:
-      result = Curl_getworkingpath(conn, sshc->homedir, &protop->path);
-      if(result) {
-        sshc->actualcode = result;
-        state(conn, SSH_STOP);
-        break;
-      }
-
-      /* Functions from the SCP subsystem cannot handle/return SSH_AGAIN */
-      ssh_set_blocking(sshc->ssh_session, 1);
-
-      if(data->set.upload) {
-        if(data->state.infilesize < 0) {
-          failf(data, "SCP requires a known file size for upload");
-          sshc->actualcode = CURLE_UPLOAD_FAILED;
-          MOVE_TO_ERROR_STATE(CURLE_UPLOAD_FAILED);
-        }
-
-        sshc->scp_session =
-          ssh_scp_new(sshc->ssh_session, SSH_SCP_WRITE, protop->path);
-        state(conn, SSH_SCP_UPLOAD_INIT);
-      }
-      else {
-        sshc->scp_session =
-          ssh_scp_new(sshc->ssh_session, SSH_SCP_READ, protop->path);
-        state(conn, SSH_SCP_DOWNLOAD_INIT);
-      }
-
-      if(!sshc->scp_session) {
-        err_msg = ssh_get_error(sshc->ssh_session);
-        failf(conn->data, "%s", err_msg);
-        MOVE_TO_ERROR_STATE(CURLE_UPLOAD_FAILED);
-      }
-
-      break;
-
-    case SSH_SCP_UPLOAD_INIT:
-
-      rc = ssh_scp_init(sshc->scp_session);
-      if(rc != SSH_OK) {
-        err_msg = ssh_get_error(sshc->ssh_session);
-        failf(conn->data, "%s", err_msg);
-        MOVE_TO_ERROR_STATE(CURLE_UPLOAD_FAILED);
-      }
-
-      rc = ssh_scp_push_file(sshc->scp_session, protop->path,
-                             data->state.infilesize,
-                             (int)data->set.new_file_perms);
-      if(rc != SSH_OK) {
-        err_msg = ssh_get_error(sshc->ssh_session);
-        failf(conn->data, "%s", err_msg);
-        MOVE_TO_ERROR_STATE(CURLE_UPLOAD_FAILED);
-      }
-
-      /* upload data */
-      Curl_setup_transfer(data, -1, data->req.size, FALSE, FIRSTSOCKET);
-
-      /* not set by Curl_setup_transfer to preserve keepon bits */
-      conn->sockfd = conn->writesockfd;
-
-      /* store this original bitmask setup to use later on if we can't
-         figure out a "real" bitmask */
-      sshc->orig_waitfor = data->req.keepon;
-
-      /* we want to use the _sending_ function even when the socket turns
-         out readable as the underlying libssh scp send function will deal
-         with both accordingly */
-      conn->cselect_bits = CURL_CSELECT_OUT;
-
-      state(conn, SSH_STOP);
-
-      break;
-
-    case SSH_SCP_DOWNLOAD_INIT:
-
-      rc = ssh_scp_init(sshc->scp_session);
-      if(rc != SSH_OK) {
-        err_msg = ssh_get_error(sshc->ssh_session);
-        failf(conn->data, "%s", err_msg);
-        MOVE_TO_ERROR_STATE(CURLE_COULDNT_CONNECT);
-      }
-      state(conn, SSH_SCP_DOWNLOAD);
-      /* FALLTHROUGH */
-
-    case SSH_SCP_DOWNLOAD:{
-        curl_off_t bytecount;
-
-        rc = ssh_scp_pull_request(sshc->scp_session);
-        if(rc != SSH_SCP_REQUEST_NEWFILE) {
-          err_msg = ssh_get_error(sshc->ssh_session);
-          failf(conn->data, "%s", err_msg);
-          MOVE_TO_ERROR_STATE(CURLE_REMOTE_FILE_NOT_FOUND);
-          break;
-        }
-
-        /* download data */
-        bytecount = ssh_scp_request_get_size(sshc->scp_session);
-        data->req.maxdownload = (curl_off_t) bytecount;
-        Curl_setup_transfer(data, FIRSTSOCKET, bytecount, FALSE, -1);
-
-        /* not set by Curl_setup_transfer to preserve keepon bits */
-        conn->writesockfd = conn->sockfd;
-
-        /* we want to use the _receiving_ function even when the socket turns
-           out writableable as the underlying libssh recv function will deal
-           with both accordingly */
-        conn->cselect_bits = CURL_CSELECT_IN;
-
-        state(conn, SSH_STOP);
-        break;
-      }
-    case SSH_SCP_DONE:
-      if(data->set.upload)
-        state(conn, SSH_SCP_SEND_EOF);
-      else
-        state(conn, SSH_SCP_CHANNEL_FREE);
-      break;
-
-    case SSH_SCP_SEND_EOF:
-      if(sshc->scp_session) {
-        rc = ssh_scp_close(sshc->scp_session);
-        if(rc == SSH_AGAIN) {
-          /* Currently the ssh_scp_close handles waiting for EOF in
-           * blocking way.
-           */
-          break;
-        }
-        if(rc != SSH_OK) {
-          infof(data, "Failed to close libssh scp channel: %s\n",
-                ssh_get_error(sshc->ssh_session));
-        }
-      }
-
-      state(conn, SSH_SCP_CHANNEL_FREE);
-      break;
-
-    case SSH_SCP_CHANNEL_FREE:
-      if(sshc->scp_session) {
-        ssh_scp_free(sshc->scp_session);
-        sshc->scp_session = NULL;
-      }
-      DEBUGF(infof(data, "SCP DONE phase complete\n"));
-
-      ssh_set_blocking(sshc->ssh_session, 0);
-
-      state(conn, SSH_SESSION_DISCONNECT);
-      /* FALLTHROUGH */
-
-    case SSH_SESSION_DISCONNECT:
-      /* during weird times when we've been prematurely aborted, the channel
-         is still alive when we reach this state and we MUST kill the channel
-         properly first */
-      if(sshc->scp_session) {
-        ssh_scp_free(sshc->scp_session);
-        sshc->scp_session = NULL;
-      }
-
-      ssh_disconnect(sshc->ssh_session);
-
-      SSH_STRING_FREE_CHAR(sshc->homedir);
-      conn->data->state.most_recent_ftp_entrypath = NULL;
-
-      state(conn, SSH_SESSION_FREE);
-      /* FALLTHROUGH */
-    case SSH_SESSION_FREE:
-      if(sshc->ssh_session) {
-        ssh_free(sshc->ssh_session);
-        sshc->ssh_session = NULL;
-      }
-
-      /* worst-case scenario cleanup */
-
-      DEBUGASSERT(sshc->ssh_session == NULL);
-      DEBUGASSERT(sshc->scp_session == NULL);
-
-      if(sshc->readdir_tmp) {
-        ssh_string_free_char(sshc->readdir_tmp);
-        sshc->readdir_tmp = NULL;
-      }
-
-      if(sshc->quote_attrs)
-        sftp_attributes_free(sshc->quote_attrs);
-
-      if(sshc->readdir_attrs)
-        sftp_attributes_free(sshc->readdir_attrs);
-
-      if(sshc->readdir_link_attrs)
-        sftp_attributes_free(sshc->readdir_link_attrs);
-
-      if(sshc->privkey)
-        ssh_key_free(sshc->privkey);
-      if(sshc->pubkey)
-        ssh_key_free(sshc->pubkey);
-
-      Curl_safefree(sshc->rsa_pub);
-      Curl_safefree(sshc->rsa);
-      Curl_safefree(sshc->quote_path1);
-      Curl_safefree(sshc->quote_path2);
-      Curl_safefree(sshc->readdir_line);
-      Curl_safefree(sshc->readdir_linkPath);
-      SSH_STRING_FREE_CHAR(sshc->homedir);
-
-      /* the code we are about to return */
-      result = sshc->actualcode;
-
-      memset(sshc, 0, sizeof(struct ssh_conn));
-
-      connclose(conn, "SSH session free");
-      sshc->state = SSH_SESSION_FREE;   /* current */
-      sshc->nextstate = SSH_NO_STATE;
-      state(conn, SSH_STOP);
-      break;
-
-    case SSH_QUIT:
-      /* fallthrough, just stop! */
-    default:
-      /* internal error */
-      sshc->nextstate = SSH_NO_STATE;
-      state(conn, SSH_STOP);
-      break;
-
-    }
-  } while(!rc && (sshc->state != SSH_STOP));
-
-
-  if(rc == SSH_AGAIN) {
-    /* we would block, we need to wait for the socket to be ready (in the
-       right direction too)! */
-    *block = TRUE;
-  }
-
-  return result;
-}
-
-
-/* called by the multi interface to figure out what socket(s) to wait for and
-   for what actions in the DO_DONE, PERFORM and WAITPERFORM states */
-static int myssh_perform_getsock(const struct connectdata *conn,
-                                 curl_socket_t *sock,  /* points to numsocks
-                                                          number of sockets */
-                                 int numsocks)
-{
-  int bitmap = GETSOCK_BLANK;
-  (void) numsocks;
-
-  sock[0] = conn->sock[FIRSTSOCKET];
-
-  if(conn->waitfor & KEEP_RECV)
-    bitmap |= GETSOCK_READSOCK(FIRSTSOCKET);
-
-  if(conn->waitfor & KEEP_SEND)
-    bitmap |= GETSOCK_WRITESOCK(FIRSTSOCKET);
-
-  return bitmap;
-}
-
-/* Generic function called by the multi interface to figure out what socket(s)
-   to wait for and for what actions during the DOING and PROTOCONNECT states*/
-static int myssh_getsock(struct connectdata *conn,
-                         curl_socket_t *sock,  /* points to numsocks
-                                                   number of sockets */
-                         int numsocks)
-{
-  /* if we know the direction we can use the generic *_getsock() function even
-     for the protocol_connect and doing states */
-  return myssh_perform_getsock(conn, sock, numsocks);
-}
-
-static void myssh_block2waitfor(struct connectdata *conn, bool block)
-{
-  struct ssh_conn *sshc = &conn->proto.sshc;
-
-  /* If it didn't block, or nothing was returned by ssh_get_poll_flags
-   * have the original set */
-  conn->waitfor = sshc->orig_waitfor;
-
-  if(block) {
-    int dir = ssh_get_poll_flags(sshc->ssh_session);
-    if(dir & SSH_READ_PENDING) {
-      /* translate the libssh define bits into our own bit defines */
-      conn->waitfor = KEEP_RECV;
-    }
-    else if(dir & SSH_WRITE_PENDING) {
-      conn->waitfor = KEEP_SEND;
-    }
-  }
-}
-
-/* called repeatedly until done from multi.c */
-static CURLcode myssh_multi_statemach(struct connectdata *conn,
-                                      bool *done)
-{
-  struct ssh_conn *sshc = &conn->proto.sshc;
-  CURLcode result = CURLE_OK;
-  bool block;    /* we store the status and use that to provide a ssh_getsock()
-                    implementation */
-
-  result = myssh_statemach_act(conn, &block);
-  *done = (sshc->state == SSH_STOP) ? TRUE : FALSE;
-  myssh_block2waitfor(conn, block);
-
-  return result;
-}
-
-static CURLcode myssh_block_statemach(struct connectdata *conn,
-                                      bool disconnect)
-{
-  struct ssh_conn *sshc = &conn->proto.sshc;
-  CURLcode result = CURLE_OK;
-  struct Curl_easy *data = conn->data;
-
-  while((sshc->state != SSH_STOP) && !result) {
-    bool block;
-    timediff_t left = 1000;
-    struct curltime now = Curl_now();
-
-    result = myssh_statemach_act(conn, &block);
-    if(result)
-      break;
-
-    if(!disconnect) {
-      if(Curl_pgrsUpdate(conn))
-        return CURLE_ABORTED_BY_CALLBACK;
-
-      result = Curl_speedcheck(data, now);
-      if(result)
-        break;
-
-      left = Curl_timeleft(data, NULL, FALSE);
-      if(left < 0) {
-        failf(data, "Operation timed out");
-        return CURLE_OPERATION_TIMEDOUT;
-      }
-    }
-
-    if(!result && block) {
-      curl_socket_t fd_read = conn->sock[FIRSTSOCKET];
-      /* wait for the socket to become ready */
-      (void) Curl_socket_check(fd_read, CURL_SOCKET_BAD,
-                               CURL_SOCKET_BAD, left > 1000 ? 1000 : left);
-    }
-
-  }
-
-  return result;
-}
-
-/*
- * SSH setup connection
- */
-static CURLcode myssh_setup_connection(struct connectdata *conn)
-{
-  struct SSHPROTO *ssh;
-
-  conn->data->req.protop = ssh = calloc(1, sizeof(struct SSHPROTO));
-  if(!ssh)
-    return CURLE_OUT_OF_MEMORY;
-
-  return CURLE_OK;
-}
-
-static Curl_recv scp_recv, sftp_recv;
-static Curl_send scp_send, sftp_send;
-
-/*
- * Curl_ssh_connect() gets called from Curl_protocol_connect() to allow us to
- * do protocol-specific actions at connect-time.
- */
-static CURLcode myssh_connect(struct connectdata *conn, bool *done)
-{
-  struct ssh_conn *ssh;
-  CURLcode result;
-  curl_socket_t sock = conn->sock[FIRSTSOCKET];
-  struct Curl_easy *data = conn->data;
-
-  /* initialize per-handle data if not already */
-  if(!data->req.protop)
-    myssh_setup_connection(conn);
-
-  /* We default to persistent connections. We set this already in this connect
-     function to make the re-use checks properly be able to check this bit. */
-  connkeep(conn, "SSH default");
-
-  if(conn->handler->protocol & CURLPROTO_SCP) {
-    conn->recv[FIRSTSOCKET] = scp_recv;
-    conn->send[FIRSTSOCKET] = scp_send;
-  }
-  else {
-    conn->recv[FIRSTSOCKET] = sftp_recv;
-    conn->send[FIRSTSOCKET] = sftp_send;
-  }
-
-  ssh = &conn->proto.sshc;
-
-  ssh->ssh_session = ssh_new();
-  if(ssh->ssh_session == NULL) {
-    failf(data, "Failure initialising ssh session");
-    return CURLE_FAILED_INIT;
-  }
-
-  ssh_options_set(ssh->ssh_session, SSH_OPTIONS_FD, &sock);
-
-  if(conn->user) {
-    infof(data, "User: %s\n", conn->user);
-    ssh_options_set(ssh->ssh_session, SSH_OPTIONS_USER, conn->user);
-  }
-
-  if(data->set.str[STRING_SSH_KNOWNHOSTS]) {
-    infof(data, "Known hosts: %s\n", data->set.str[STRING_SSH_KNOWNHOSTS]);
-    ssh_options_set(ssh->ssh_session, SSH_OPTIONS_KNOWNHOSTS,
-                    data->set.str[STRING_SSH_KNOWNHOSTS]);
-  }
-
-  ssh_options_set(ssh->ssh_session, SSH_OPTIONS_HOST, conn->host.name);
-  if(conn->remote_port)
-    ssh_options_set(ssh->ssh_session, SSH_OPTIONS_PORT,
-                    &conn->remote_port);
-
-  if(data->set.ssh_compression) {
-    ssh_options_set(ssh->ssh_session, SSH_OPTIONS_COMPRESSION,
-                    "zlib,zlib@openssh.com,none");
-  }
-
-  ssh->privkey = NULL;
-  ssh->pubkey = NULL;
-
-  if(data->set.str[STRING_SSH_PUBLIC_KEY]) {
-    int rc = ssh_pki_import_pubkey_file(data->set.str[STRING_SSH_PUBLIC_KEY],
-                                        &ssh->pubkey);
-    if(rc != SSH_OK) {
-      failf(data, "Could not load public key file");
-      /* ignore */
-    }
-  }
-
-  /* we do not verify here, we do it at the state machine,
-   * after connection */
-
-  state(conn, SSH_INIT);
-
-  result = myssh_multi_statemach(conn, done);
-
-  return result;
-}
-
-/* called from multi.c while DOing */
-static CURLcode scp_doing(struct connectdata *conn, bool *dophase_done)
-{
-  CURLcode result;
-
-  result = myssh_multi_statemach(conn, dophase_done);
-
-  if(*dophase_done) {
-    DEBUGF(infof(conn->data, "DO phase is complete\n"));
-  }
-  return result;
-}
-
-/*
- ***********************************************************************
- *
- * scp_perform()
- *
- * This is the actual DO function for SCP. Get a file according to
- * the options previously setup.
- */
-
-static
-CURLcode scp_perform(struct connectdata *conn,
-                     bool *connected, bool *dophase_done)
-{
-  CURLcode result = CURLE_OK;
-
-  DEBUGF(infof(conn->data, "DO phase starts\n"));
-
-  *dophase_done = FALSE;        /* not done yet */
-
-  /* start the first command in the DO phase */
-  state(conn, SSH_SCP_TRANS_INIT);
-
-  result = myssh_multi_statemach(conn, dophase_done);
-
-  *connected = conn->bits.tcpconnect[FIRSTSOCKET];
-
-  if(*dophase_done) {
-    DEBUGF(infof(conn->data, "DO phase is complete\n"));
-  }
-
-  return result;
-}
-
-static CURLcode myssh_do_it(struct connectdata *conn, bool *done)
-{
-  CURLcode result;
-  bool connected = 0;
-  struct Curl_easy *data = conn->data;
-  struct ssh_conn *sshc = &conn->proto.sshc;
-
-  *done = FALSE;                /* default to false */
-
-  data->req.size = -1;          /* make sure this is unknown at this point */
-
-  sshc->actualcode = CURLE_OK;  /* reset error code */
-  sshc->secondCreateDirs = 0;   /* reset the create dir attempt state
-                                   variable */
-
-  Curl_pgrsSetUploadCounter(data, 0);
-  Curl_pgrsSetDownloadCounter(data, 0);
-  Curl_pgrsSetUploadSize(data, -1);
-  Curl_pgrsSetDownloadSize(data, -1);
-
-  if(conn->handler->protocol & CURLPROTO_SCP)
-    result = scp_perform(conn, &connected, done);
-  else
-    result = sftp_perform(conn, &connected, done);
-
-  return result;
-}
-
-/* BLOCKING, but the function is using the state machine so the only reason
-   this is still blocking is that the multi interface code has no support for
-   disconnecting operations that takes a while */
-static CURLcode scp_disconnect(struct connectdata *conn,
-                               bool dead_connection)
-{
-  CURLcode result = CURLE_OK;
-  struct ssh_conn *ssh = &conn->proto.sshc;
-  (void) dead_connection;
-
-  if(ssh->ssh_session) {
-    /* only if there's a session still around to use! */
-
-    state(conn, SSH_SESSION_DISCONNECT);
-
-    result = myssh_block_statemach(conn, TRUE);
-  }
-
-  return result;
-}
-
-/* generic done function for both SCP and SFTP called from their specific
-   done functions */
-static CURLcode myssh_done(struct connectdata *conn, CURLcode status)
-{
-  CURLcode result = CURLE_OK;
-  struct SSHPROTO *protop = conn->data->req.protop;
-
-  if(!status) {
-    /* run the state-machine */
-    result = myssh_block_statemach(conn, FALSE);
-  }
-  else
-    result = status;
-
-  if(protop)
-    Curl_safefree(protop->path);
-  if(Curl_pgrsDone(conn))
-    return CURLE_ABORTED_BY_CALLBACK;
-
-  conn->data->req.keepon = 0;   /* clear all bits */
-  return result;
-}
-
-
-static CURLcode scp_done(struct connectdata *conn, CURLcode status,
-                         bool premature)
-{
-  (void) premature;             /* not used */
-
-  if(!status)
-    state(conn, SSH_SCP_DONE);
-
-  return myssh_done(conn, status);
-
-}
-
-static ssize_t scp_send(struct connectdata *conn, int sockindex,
-                        const void *mem, size_t len, CURLcode *err)
-{
-  int rc;
-  (void) sockindex; /* we only support SCP on the fixed known primary socket */
-  (void) err;
-
-  rc = ssh_scp_write(conn->proto.sshc.scp_session, mem, len);
-
-#if 0
-  /* The following code is misleading, mostly added as wishful thinking
-   * that libssh at some point will implement non-blocking ssh_scp_write/read.
-   * Currently rc can only be number of bytes read or SSH_ERROR. */
-  myssh_block2waitfor(conn, (rc == SSH_AGAIN) ? TRUE : FALSE);
-
-  if(rc == SSH_AGAIN) {
-    *err = CURLE_AGAIN;
-    return 0;
-  }
-  else
-#endif
-  if(rc != SSH_OK) {
-    *err = CURLE_SSH;
-    return -1;
-  }
-
-  return len;
-}
-
-static ssize_t scp_recv(struct connectdata *conn, int sockindex,
-                        char *mem, size_t len, CURLcode *err)
-{
-  ssize_t nread;
-  (void) err;
-  (void) sockindex; /* we only support SCP on the fixed known primary socket */
-
-  /* libssh returns int */
-  nread = ssh_scp_read(conn->proto.sshc.scp_session, mem, len);
-
-#if 0
-  /* The following code is misleading, mostly added as wishful thinking
-   * that libssh at some point will implement non-blocking ssh_scp_write/read.
-   * Currently rc can only be SSH_OK or SSH_ERROR. */
-
-  myssh_block2waitfor(conn, (nread == SSH_AGAIN) ? TRUE : FALSE);
-  if(nread == SSH_AGAIN) {
-    *err = CURLE_AGAIN;
-    nread = -1;
-  }
-#endif
-
-  return nread;
-}
-
-/*
- * =============== SFTP ===============
- */
-
-/*
- ***********************************************************************
- *
- * sftp_perform()
- *
- * This is the actual DO function for SFTP. Get a file/directory according to
- * the options previously setup.
- */
-
-static
-CURLcode sftp_perform(struct connectdata *conn,
-                      bool *connected,
-                      bool *dophase_done)
-{
-  CURLcode result = CURLE_OK;
-
-  DEBUGF(infof(conn->data, "DO phase starts\n"));
-
-  *dophase_done = FALSE; /* not done yet */
-
-  /* start the first command in the DO phase */
-  state(conn, SSH_SFTP_QUOTE_INIT);
-
-  /* run the state-machine */
-  result = myssh_multi_statemach(conn, dophase_done);
-
-  *connected = conn->bits.tcpconnect[FIRSTSOCKET];
-
-  if(*dophase_done) {
-    DEBUGF(infof(conn->data, "DO phase is complete\n"));
-  }
-
-  return result;
-}
-
-/* called from multi.c while DOing */
-static CURLcode sftp_doing(struct connectdata *conn,
-                           bool *dophase_done)
-{
-  CURLcode result = myssh_multi_statemach(conn, dophase_done);
-  if(*dophase_done) {
-    DEBUGF(infof(conn->data, "DO phase is complete\n"));
-  }
-  return result;
-}
-
-/* BLOCKING, but the function is using the state machine so the only reason
-   this is still blocking is that the multi interface code has no support for
-   disconnecting operations that takes a while */
-static CURLcode sftp_disconnect(struct connectdata *conn, bool dead_connection)
-{
-  CURLcode result = CURLE_OK;
-  (void) dead_connection;
-
-  DEBUGF(infof(conn->data, "SSH DISCONNECT starts now\n"));
-
-  if(conn->proto.sshc.ssh_session) {
-    /* only if there's a session still around to use! */
-    state(conn, SSH_SFTP_SHUTDOWN);
-    result = myssh_block_statemach(conn, TRUE);
-  }
-
-  DEBUGF(infof(conn->data, "SSH DISCONNECT is done\n"));
-
-  return result;
-
-}
-
-static CURLcode sftp_done(struct connectdata *conn, CURLcode status,
-                               bool premature)
-{
-  struct ssh_conn *sshc = &conn->proto.sshc;
-
-  if(!status) {
-    /* Post quote commands are executed after the SFTP_CLOSE state to avoid
-       errors that could happen due to open file handles during POSTQUOTE
-       operation */
-    if(!premature && conn->data->set.postquote && !conn->bits.retry)
-      sshc->nextstate = SSH_SFTP_POSTQUOTE_INIT;
-    state(conn, SSH_SFTP_CLOSE);
-  }
-  return myssh_done(conn, status);
-}
-
-/* return number of sent bytes */
-static ssize_t sftp_send(struct connectdata *conn, int sockindex,
-                         const void *mem, size_t len, CURLcode *err)
-{
-  ssize_t nwrite;
-  (void)sockindex;
-
-  nwrite = sftp_write(conn->proto.sshc.sftp_file, mem, len);
-
-  myssh_block2waitfor(conn, FALSE);
-
-#if 0 /* not returned by libssh on write */
-  if(nwrite == SSH_AGAIN) {
-    *err = CURLE_AGAIN;
-    nwrite = 0;
-  }
-  else
-#endif
-  if(nwrite < 0) {
-    *err = CURLE_SSH;
-    nwrite = -1;
-  }
-
-  return nwrite;
-}
-
-/*
- * Return number of received (decrypted) bytes
- * or <0 on error
- */
-static ssize_t sftp_recv(struct connectdata *conn, int sockindex,
-                         char *mem, size_t len, CURLcode *err)
-{
-  ssize_t nread;
-  (void)sockindex;
-
-  DEBUGASSERT(len < CURL_MAX_READ_SIZE);
-
-  switch(conn->proto.sshc.sftp_recv_state) {
-    case 0:
-      conn->proto.sshc.sftp_file_index =
-            sftp_async_read_begin(conn->proto.sshc.sftp_file,
-                                  (uint32_t)len);
-      if(conn->proto.sshc.sftp_file_index < 0) {
-        *err = CURLE_RECV_ERROR;
-        return -1;
-      }
-
-      /* FALLTHROUGH */
-    case 1:
-      conn->proto.sshc.sftp_recv_state = 1;
-
-      nread = sftp_async_read(conn->proto.sshc.sftp_file,
-                              mem, (uint32_t)len,
-                              conn->proto.sshc.sftp_file_index);
-
-      myssh_block2waitfor(conn, (nread == SSH_AGAIN)?TRUE:FALSE);
-
-      if(nread == SSH_AGAIN) {
-        *err = CURLE_AGAIN;
-        return -1;
-      }
-      else if(nread < 0) {
-        *err = CURLE_RECV_ERROR;
-        return -1;
-      }
-
-      conn->proto.sshc.sftp_recv_state = 0;
-      return nread;
-
-    default:
-      /* we never reach here */
-      return -1;
-  }
-}
-
-static void sftp_quote(struct connectdata *conn)
-{
-  const char *cp;
-  struct Curl_easy *data = conn->data;
-  struct SSHPROTO *protop = data->req.protop;
-  struct ssh_conn *sshc = &conn->proto.sshc;
-  CURLcode result;
-
-  /*
-   * Support some of the "FTP" commands
-   */
-  char *cmd = sshc->quote_item->data;
-  sshc->acceptfail = FALSE;
-
-  /* if a command starts with an asterisk, which a legal SFTP command never
-     can, the command will be allowed to fail without it causing any
-     aborts or cancels etc. It will cause libcurl to act as if the command
-     is successful, whatever the server reponds. */
-
-  if(cmd[0] == '*') {
-    cmd++;
-    sshc->acceptfail = TRUE;
-  }
-
-  if(strcasecompare("pwd", cmd)) {
-    /* output debug output if that is requested */
-    char *tmp = aprintf("257 \"%s\" is current directory.\n",
-                        protop->path);
-    if(!tmp) {
-      sshc->actualcode = CURLE_OUT_OF_MEMORY;
-      state(conn, SSH_SFTP_CLOSE);
-      sshc->nextstate = SSH_NO_STATE;
-      return;
-    }
-    if(data->set.verbose) {
-      Curl_debug(data, CURLINFO_HEADER_OUT, (char *) "PWD\n", 4);
-      Curl_debug(data, CURLINFO_HEADER_IN, tmp, strlen(tmp));
-    }
-    /* this sends an FTP-like "header" to the header callback so that the
-       current directory can be read very similar to how it is read when
-       using ordinary FTP. */
-    result = Curl_client_write(conn, CLIENTWRITE_HEADER, tmp, strlen(tmp));
-    free(tmp);
-    if(result) {
-      state(conn, SSH_SFTP_CLOSE);
-      sshc->nextstate = SSH_NO_STATE;
-      sshc->actualcode = result;
-    }
-    else
-      state(conn, SSH_SFTP_NEXT_QUOTE);
-    return;
-  }
-
-  /*
-   * the arguments following the command must be separated from the
-   * command with a space so we can check for it unconditionally
-   */
-  cp = strchr(cmd, ' ');
-  if(cp == NULL) {
-    failf(data, "Syntax error in SFTP command. Supply parameter(s)!");
-    state(conn, SSH_SFTP_CLOSE);
-    sshc->nextstate = SSH_NO_STATE;
-    sshc->actualcode = CURLE_QUOTE_ERROR;
-    return;
-  }
-
-  /*
-   * also, every command takes at least one argument so we get that
-   * first argument right now
-   */
-  result = Curl_get_pathname(&cp, &sshc->quote_path1, sshc->homedir);
-  if(result) {
-    if(result == CURLE_OUT_OF_MEMORY)
-      failf(data, "Out of memory");
-    else
-      failf(data, "Syntax error: Bad first parameter");
-    state(conn, SSH_SFTP_CLOSE);
-    sshc->nextstate = SSH_NO_STATE;
-    sshc->actualcode = result;
-    return;
-  }
-
-  /*
-   * SFTP is a binary protocol, so we don't send text commands
-   * to the server. Instead, we scan for commands used by
-   * OpenSSH's sftp program and call the appropriate libssh
-   * functions.
-   */
-  if(strncasecompare(cmd, "chgrp ", 6) ||
-     strncasecompare(cmd, "chmod ", 6) ||
-     strncasecompare(cmd, "chown ", 6)) {
-    /* attribute change */
-
-    /* sshc->quote_path1 contains the mode to set */
-    /* get the destination */
-    result = Curl_get_pathname(&cp, &sshc->quote_path2, sshc->homedir);
-    if(result) {
-      if(result == CURLE_OUT_OF_MEMORY)
-        failf(data, "Out of memory");
-      else
-        failf(data, "Syntax error in chgrp/chmod/chown: "
-              "Bad second parameter");
-      Curl_safefree(sshc->quote_path1);
-      state(conn, SSH_SFTP_CLOSE);
-      sshc->nextstate = SSH_NO_STATE;
-      sshc->actualcode = result;
-      return;
-    }
-    sshc->quote_attrs = NULL;
-    state(conn, SSH_SFTP_QUOTE_STAT);
-    return;
-  }
-  if(strncasecompare(cmd, "ln ", 3) ||
-     strncasecompare(cmd, "symlink ", 8)) {
-    /* symbolic linking */
-    /* sshc->quote_path1 is the source */
-    /* get the destination */
-    result = Curl_get_pathname(&cp, &sshc->quote_path2, sshc->homedir);
-    if(result) {
-      if(result == CURLE_OUT_OF_MEMORY)
-        failf(data, "Out of memory");
-      else
-        failf(data, "Syntax error in ln/symlink: Bad second parameter");
-      Curl_safefree(sshc->quote_path1);
-      state(conn, SSH_SFTP_CLOSE);
-      sshc->nextstate = SSH_NO_STATE;
-      sshc->actualcode = result;
-      return;
-    }
-    state(conn, SSH_SFTP_QUOTE_SYMLINK);
-    return;
-  }
-  else if(strncasecompare(cmd, "mkdir ", 6)) {
-    /* create dir */
-    state(conn, SSH_SFTP_QUOTE_MKDIR);
-    return;
-  }
-  else if(strncasecompare(cmd, "rename ", 7)) {
-    /* rename file */
-    /* first param is the source path */
-    /* second param is the dest. path */
-    result = Curl_get_pathname(&cp, &sshc->quote_path2, sshc->homedir);
-    if(result) {
-      if(result == CURLE_OUT_OF_MEMORY)
-        failf(data, "Out of memory");
-      else
-        failf(data, "Syntax error in rename: Bad second parameter");
-      Curl_safefree(sshc->quote_path1);
-      state(conn, SSH_SFTP_CLOSE);
-      sshc->nextstate = SSH_NO_STATE;
-      sshc->actualcode = result;
-      return;
-    }
-    state(conn, SSH_SFTP_QUOTE_RENAME);
-    return;
-  }
-  else if(strncasecompare(cmd, "rmdir ", 6)) {
-    /* delete dir */
-    state(conn, SSH_SFTP_QUOTE_RMDIR);
-    return;
-  }
-  else if(strncasecompare(cmd, "rm ", 3)) {
-    state(conn, SSH_SFTP_QUOTE_UNLINK);
-    return;
-  }
-#ifdef HAS_STATVFS_SUPPORT
-  else if(strncasecompare(cmd, "statvfs ", 8)) {
-    state(conn, SSH_SFTP_QUOTE_STATVFS);
-    return;
-  }
-#endif
-
-  failf(data, "Unknown SFTP command");
-  Curl_safefree(sshc->quote_path1);
-  Curl_safefree(sshc->quote_path2);
-  state(conn, SSH_SFTP_CLOSE);
-  sshc->nextstate = SSH_NO_STATE;
-  sshc->actualcode = CURLE_QUOTE_ERROR;
-}
-
-static void sftp_quote_stat(struct connectdata *conn)
-{
-  struct Curl_easy *data = conn->data;
-  struct ssh_conn *sshc = &conn->proto.sshc;
-  char *cmd = sshc->quote_item->data;
-  sshc->acceptfail = FALSE;
-
-  /* if a command starts with an asterisk, which a legal SFTP command never
-     can, the command will be allowed to fail without it causing any
-     aborts or cancels etc. It will cause libcurl to act as if the command
-     is successful, whatever the server reponds. */
-
-  if(cmd[0] == '*') {
-    cmd++;
-    sshc->acceptfail = TRUE;
-  }
-
-  /* We read the file attributes, store them in sshc->quote_attrs
-   * and modify them accordingly to command. Then we switch to
-   * QUOTE_SETSTAT state to write new ones.
-   */
-
-  if(sshc->quote_attrs)
-    sftp_attributes_free(sshc->quote_attrs);
-  sshc->quote_attrs = sftp_stat(sshc->sftp_session, sshc->quote_path2);
-  if(sshc->quote_attrs == NULL) {
-    Curl_safefree(sshc->quote_path1);
-    Curl_safefree(sshc->quote_path2);
-    failf(data, "Attempt to get SFTP stats failed: %d",
-          sftp_get_error(sshc->sftp_session));
-    state(conn, SSH_SFTP_CLOSE);
-    sshc->nextstate = SSH_NO_STATE;
-    sshc->actualcode = CURLE_QUOTE_ERROR;
-    return;
-  }
-
-  /* Now set the new attributes... */
-  if(strncasecompare(cmd, "chgrp", 5)) {
-    sshc->quote_attrs->gid = (uint32_t)strtoul(sshc->quote_path1, NULL, 10);
-    if(sshc->quote_attrs->gid == 0 && !ISDIGIT(sshc->quote_path1[0]) &&
-        !sshc->acceptfail) {
-      Curl_safefree(sshc->quote_path1);
-      Curl_safefree(sshc->quote_path2);
-      failf(data, "Syntax error: chgrp gid not a number");
-      state(conn, SSH_SFTP_CLOSE);
-      sshc->nextstate = SSH_NO_STATE;
-      sshc->actualcode = CURLE_QUOTE_ERROR;
-      return;
-    }
-    sshc->quote_attrs->flags |= SSH_FILEXFER_ATTR_UIDGID;
-  }
-  else if(strncasecompare(cmd, "chmod", 5)) {
-    mode_t perms;
-    perms = (mode_t)strtoul(sshc->quote_path1, NULL, 8);
-    /* permissions are octal */
-    if(perms == 0 && !ISDIGIT(sshc->quote_path1[0])) {
-      Curl_safefree(sshc->quote_path1);
-      Curl_safefree(sshc->quote_path2);
-      failf(data, "Syntax error: chmod permissions not a number");
-      state(conn, SSH_SFTP_CLOSE);
-      sshc->nextstate = SSH_NO_STATE;
-      sshc->actualcode = CURLE_QUOTE_ERROR;
-      return;
-    }
-    sshc->quote_attrs->permissions = perms;
-    sshc->quote_attrs->flags |= SSH_FILEXFER_ATTR_PERMISSIONS;
-  }
-  else if(strncasecompare(cmd, "chown", 5)) {
-    sshc->quote_attrs->uid = (uint32_t)strtoul(sshc->quote_path1, NULL, 10);
-    if(sshc->quote_attrs->uid == 0 && !ISDIGIT(sshc->quote_path1[0]) &&
-        !sshc->acceptfail) {
-      Curl_safefree(sshc->quote_path1);
-      Curl_safefree(sshc->quote_path2);
-      failf(data, "Syntax error: chown uid not a number");
-      state(conn, SSH_SFTP_CLOSE);
-      sshc->nextstate = SSH_NO_STATE;
-      sshc->actualcode = CURLE_QUOTE_ERROR;
-      return;
-    }
-    sshc->quote_attrs->flags |= SSH_FILEXFER_ATTR_UIDGID;
-  }
-
-  /* Now send the completed structure... */
-  state(conn, SSH_SFTP_QUOTE_SETSTAT);
-  return;
-}
-
-
-#endif                          /* USE_LIBSSH */
diff --git a/Utilities/cmcurl/lib/ssh.c b/Utilities/cmcurl/lib/ssh.c
deleted file mode 100644
index a265c3c..0000000
--- a/Utilities/cmcurl/lib/ssh.c
+++ /dev/null
@@ -1,3337 +0,0 @@
-/***************************************************************************
- *                                  _   _ ____  _
- *  Project                     ___| | | |  _ \| |
- *                             / __| | | | |_) | |
- *                            | (__| |_| |  _ <| |___
- *                             \___|\___/|_| \_\_____|
- *
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * This software is licensed as described in the file COPYING, which
- * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
- *
- * You may opt to use, copy, modify, merge, publish, distribute and/or sell
- * copies of the Software, and permit persons to whom the Software is
- * furnished to do so, under the terms of the COPYING file.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- ***************************************************************************/
-
-/* #define CURL_LIBSSH2_DEBUG */
-
-#include "curl_setup.h"
-
-#ifdef USE_LIBSSH2
-
-#include <limits.h>
-
-#include <libssh2.h>
-#include <libssh2_sftp.h>
-
-#ifdef HAVE_FCNTL_H
-#include <fcntl.h>
-#endif
-
-#ifdef HAVE_NETINET_IN_H
-#include <netinet/in.h>
-#endif
-#ifdef HAVE_ARPA_INET_H
-#include <arpa/inet.h>
-#endif
-#ifdef HAVE_UTSNAME_H
-#include <sys/utsname.h>
-#endif
-#ifdef HAVE_NETDB_H
-#include <netdb.h>
-#endif
-#ifdef __VMS
-#include <in.h>
-#include <inet.h>
-#endif
-
-#if (defined(NETWARE) && defined(__NOVELL_LIBC__))
-#undef in_addr_t
-#define in_addr_t unsigned long
-#endif
-
-#include <curl/curl.h>
-#include "urldata.h"
-#include "sendf.h"
-#include "hostip.h"
-#include "progress.h"
-#include "transfer.h"
-#include "escape.h"
-#include "http.h" /* for HTTP proxy tunnel stuff */
-#include "ssh.h"
-#include "url.h"
-#include "speedcheck.h"
-#include "getinfo.h"
-#include "strdup.h"
-#include "strcase.h"
-#include "vtls/vtls.h"
-#include "connect.h"
-#include "strerror.h"
-#include "inet_ntop.h"
-#include "parsedate.h" /* for the week day and month names */
-#include "sockaddr.h" /* required for Curl_sockaddr_storage */
-#include "strtoofft.h"
-#include "multiif.h"
-#include "select.h"
-#include "warnless.h"
-#include "curl_path.h"
-
-/* The last 3 #include files should be in this order */
-#include "curl_printf.h"
-#include "curl_memory.h"
-#include "memdebug.h"
-
-#if LIBSSH2_VERSION_NUM >= 0x010206
-/* libssh2_sftp_statvfs and friends were added in 1.2.6 */
-#define HAS_STATVFS_SUPPORT 1
-#endif
-
-#define sftp_libssh2_last_error(s) curlx_ultosi(libssh2_sftp_last_error(s))
-
-#define sftp_libssh2_realpath(s,p,t,m) \
-        libssh2_sftp_symlink_ex((s), (p), curlx_uztoui(strlen(p)), \
-                                (t), (m), LIBSSH2_SFTP_REALPATH)
-
-
-/* Local functions: */
-static const char *sftp_libssh2_strerror(int err);
-static LIBSSH2_ALLOC_FUNC(my_libssh2_malloc);
-static LIBSSH2_REALLOC_FUNC(my_libssh2_realloc);
-static LIBSSH2_FREE_FUNC(my_libssh2_free);
-
-static CURLcode ssh_connect(struct connectdata *conn, bool *done);
-static CURLcode ssh_multi_statemach(struct connectdata *conn, bool *done);
-static CURLcode ssh_do(struct connectdata *conn, bool *done);
-
-static CURLcode scp_done(struct connectdata *conn,
-                         CURLcode, bool premature);
-static CURLcode scp_doing(struct connectdata *conn,
-                          bool *dophase_done);
-static CURLcode scp_disconnect(struct connectdata *conn, bool dead_connection);
-
-static CURLcode sftp_done(struct connectdata *conn,
-                          CURLcode, bool premature);
-static CURLcode sftp_doing(struct connectdata *conn,
-                           bool *dophase_done);
-static CURLcode sftp_disconnect(struct connectdata *conn, bool dead);
-static
-CURLcode sftp_perform(struct connectdata *conn,
-                      bool *connected,
-                      bool *dophase_done);
-
-static int ssh_getsock(struct connectdata *conn,
-                       curl_socket_t *sock, /* points to numsocks number
-                                               of sockets */
-                       int numsocks);
-
-static int ssh_perform_getsock(const struct connectdata *conn,
-                               curl_socket_t *sock, /* points to numsocks
-                                                       number of sockets */
-                               int numsocks);
-
-static CURLcode ssh_setup_connection(struct connectdata *conn);
-
-/*
- * SCP protocol handler.
- */
-
-const struct Curl_handler Curl_handler_scp = {
-  "SCP",                                /* scheme */
-  ssh_setup_connection,                 /* setup_connection */
-  ssh_do,                               /* do_it */
-  scp_done,                             /* done */
-  ZERO_NULL,                            /* do_more */
-  ssh_connect,                          /* connect_it */
-  ssh_multi_statemach,                  /* connecting */
-  scp_doing,                            /* doing */
-  ssh_getsock,                          /* proto_getsock */
-  ssh_getsock,                          /* doing_getsock */
-  ZERO_NULL,                            /* domore_getsock */
-  ssh_perform_getsock,                  /* perform_getsock */
-  scp_disconnect,                       /* disconnect */
-  ZERO_NULL,                            /* readwrite */
-  ZERO_NULL,                            /* connection_check */
-  PORT_SSH,                             /* defport */
-  CURLPROTO_SCP,                        /* protocol */
-  PROTOPT_DIRLOCK | PROTOPT_CLOSEACTION
-  | PROTOPT_NOURLQUERY                  /* flags */
-};
-
-
-/*
- * SFTP protocol handler.
- */
-
-const struct Curl_handler Curl_handler_sftp = {
-  "SFTP",                               /* scheme */
-  ssh_setup_connection,                 /* setup_connection */
-  ssh_do,                               /* do_it */
-  sftp_done,                            /* done */
-  ZERO_NULL,                            /* do_more */
-  ssh_connect,                          /* connect_it */
-  ssh_multi_statemach,                  /* connecting */
-  sftp_doing,                           /* doing */
-  ssh_getsock,                          /* proto_getsock */
-  ssh_getsock,                          /* doing_getsock */
-  ZERO_NULL,                            /* domore_getsock */
-  ssh_perform_getsock,                  /* perform_getsock */
-  sftp_disconnect,                      /* disconnect */
-  ZERO_NULL,                            /* readwrite */
-  ZERO_NULL,                            /* connection_check */
-  PORT_SSH,                             /* defport */
-  CURLPROTO_SFTP,                       /* protocol */
-  PROTOPT_DIRLOCK | PROTOPT_CLOSEACTION
-  | PROTOPT_NOURLQUERY                  /* flags */
-};
-
-static void
-kbd_callback(const char *name, int name_len, const char *instruction,
-             int instruction_len, int num_prompts,
-             const LIBSSH2_USERAUTH_KBDINT_PROMPT *prompts,
-             LIBSSH2_USERAUTH_KBDINT_RESPONSE *responses,
-             void **abstract)
-{
-  struct connectdata *conn = (struct connectdata *)*abstract;
-
-#ifdef CURL_LIBSSH2_DEBUG
-  fprintf(stderr, "name=%s\n", name);
-  fprintf(stderr, "name_len=%d\n", name_len);
-  fprintf(stderr, "instruction=%s\n", instruction);
-  fprintf(stderr, "instruction_len=%d\n", instruction_len);
-  fprintf(stderr, "num_prompts=%d\n", num_prompts);
-#else
-  (void)name;
-  (void)name_len;
-  (void)instruction;
-  (void)instruction_len;
-#endif  /* CURL_LIBSSH2_DEBUG */
-  if(num_prompts == 1) {
-    responses[0].text = strdup(conn->passwd);
-    responses[0].length = curlx_uztoui(strlen(conn->passwd));
-  }
-  (void)prompts;
-  (void)abstract;
-} /* kbd_callback */
-
-static CURLcode sftp_libssh2_error_to_CURLE(int err)
-{
-  switch(err) {
-    case LIBSSH2_FX_OK:
-      return CURLE_OK;
-
-    case LIBSSH2_FX_NO_SUCH_FILE:
-    case LIBSSH2_FX_NO_SUCH_PATH:
-      return CURLE_REMOTE_FILE_NOT_FOUND;
-
-    case LIBSSH2_FX_PERMISSION_DENIED:
-    case LIBSSH2_FX_WRITE_PROTECT:
-    case LIBSSH2_FX_LOCK_CONFlICT:
-      return CURLE_REMOTE_ACCESS_DENIED;
-
-    case LIBSSH2_FX_NO_SPACE_ON_FILESYSTEM:
-    case LIBSSH2_FX_QUOTA_EXCEEDED:
-      return CURLE_REMOTE_DISK_FULL;
-
-    case LIBSSH2_FX_FILE_ALREADY_EXISTS:
-      return CURLE_REMOTE_FILE_EXISTS;
-
-    case LIBSSH2_FX_DIR_NOT_EMPTY:
-      return CURLE_QUOTE_ERROR;
-
-    default:
-      break;
-  }
-
-  return CURLE_SSH;
-}
-
-static CURLcode libssh2_session_error_to_CURLE(int err)
-{
-  switch(err) {
-    /* Ordered by order of appearance in libssh2.h */
-    case LIBSSH2_ERROR_NONE:
-      return CURLE_OK;
-
-    /* This is the error returned by libssh2_scp_recv2
-     * on unknown file */
-    case LIBSSH2_ERROR_SCP_PROTOCOL:
-      return CURLE_REMOTE_FILE_NOT_FOUND;
-
-    case LIBSSH2_ERROR_SOCKET_NONE:
-      return CURLE_COULDNT_CONNECT;
-
-    case LIBSSH2_ERROR_ALLOC:
-      return CURLE_OUT_OF_MEMORY;
-
-    case LIBSSH2_ERROR_SOCKET_SEND:
-      return CURLE_SEND_ERROR;
-
-    case LIBSSH2_ERROR_HOSTKEY_INIT:
-    case LIBSSH2_ERROR_HOSTKEY_SIGN:
-    case LIBSSH2_ERROR_PUBLICKEY_UNRECOGNIZED:
-    case LIBSSH2_ERROR_PUBLICKEY_UNVERIFIED:
-      return CURLE_PEER_FAILED_VERIFICATION;
-
-    case LIBSSH2_ERROR_PASSWORD_EXPIRED:
-      return CURLE_LOGIN_DENIED;
-
-    case LIBSSH2_ERROR_SOCKET_TIMEOUT:
-    case LIBSSH2_ERROR_TIMEOUT:
-      return CURLE_OPERATION_TIMEDOUT;
-
-    case LIBSSH2_ERROR_EAGAIN:
-      return CURLE_AGAIN;
-  }
-
-  return CURLE_SSH;
-}
-
-static LIBSSH2_ALLOC_FUNC(my_libssh2_malloc)
-{
-  (void)abstract; /* arg not used */
-  return malloc(count);
-}
-
-static LIBSSH2_REALLOC_FUNC(my_libssh2_realloc)
-{
-  (void)abstract; /* arg not used */
-  return realloc(ptr, count);
-}
-
-static LIBSSH2_FREE_FUNC(my_libssh2_free)
-{
-  (void)abstract; /* arg not used */
-  if(ptr) /* ssh2 agent sometimes call free with null ptr */
-    free(ptr);
-}
-
-/*
- * SSH State machine related code
- */
-/* This is the ONLY way to change SSH state! */
-static void state(struct connectdata *conn, sshstate nowstate)
-{
-  struct ssh_conn *sshc = &conn->proto.sshc;
-#if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS)
-  /* for debug purposes */
-  static const char * const names[] = {
-    "SSH_STOP",
-    "SSH_INIT",
-    "SSH_S_STARTUP",
-    "SSH_HOSTKEY",
-    "SSH_AUTHLIST",
-    "SSH_AUTH_PKEY_INIT",
-    "SSH_AUTH_PKEY",
-    "SSH_AUTH_PASS_INIT",
-    "SSH_AUTH_PASS",
-    "SSH_AUTH_AGENT_INIT",
-    "SSH_AUTH_AGENT_LIST",
-    "SSH_AUTH_AGENT",
-    "SSH_AUTH_HOST_INIT",
-    "SSH_AUTH_HOST",
-    "SSH_AUTH_KEY_INIT",
-    "SSH_AUTH_KEY",
-    "SSH_AUTH_GSSAPI",
-    "SSH_AUTH_DONE",
-    "SSH_SFTP_INIT",
-    "SSH_SFTP_REALPATH",
-    "SSH_SFTP_QUOTE_INIT",
-    "SSH_SFTP_POSTQUOTE_INIT",
-    "SSH_SFTP_QUOTE",
-    "SSH_SFTP_NEXT_QUOTE",
-    "SSH_SFTP_QUOTE_STAT",
-    "SSH_SFTP_QUOTE_SETSTAT",
-    "SSH_SFTP_QUOTE_SYMLINK",
-    "SSH_SFTP_QUOTE_MKDIR",
-    "SSH_SFTP_QUOTE_RENAME",
-    "SSH_SFTP_QUOTE_RMDIR",
-    "SSH_SFTP_QUOTE_UNLINK",
-    "SSH_SFTP_QUOTE_STATVFS",
-    "SSH_SFTP_GETINFO",
-    "SSH_SFTP_FILETIME",
-    "SSH_SFTP_TRANS_INIT",
-    "SSH_SFTP_UPLOAD_INIT",
-    "SSH_SFTP_CREATE_DIRS_INIT",
-    "SSH_SFTP_CREATE_DIRS",
-    "SSH_SFTP_CREATE_DIRS_MKDIR",
-    "SSH_SFTP_READDIR_INIT",
-    "SSH_SFTP_READDIR",
-    "SSH_SFTP_READDIR_LINK",
-    "SSH_SFTP_READDIR_BOTTOM",
-    "SSH_SFTP_READDIR_DONE",
-    "SSH_SFTP_DOWNLOAD_INIT",
-    "SSH_SFTP_DOWNLOAD_STAT",
-    "SSH_SFTP_CLOSE",
-    "SSH_SFTP_SHUTDOWN",
-    "SSH_SCP_TRANS_INIT",
-    "SSH_SCP_UPLOAD_INIT",
-    "SSH_SCP_DOWNLOAD_INIT",
-    "SSH_SCP_DOWNLOAD",
-    "SSH_SCP_DONE",
-    "SSH_SCP_SEND_EOF",
-    "SSH_SCP_WAIT_EOF",
-    "SSH_SCP_WAIT_CLOSE",
-    "SSH_SCP_CHANNEL_FREE",
-    "SSH_SESSION_DISCONNECT",
-    "SSH_SESSION_FREE",
-    "QUIT"
-  };
-
-  /* a precaution to make sure the lists are in sync */
-  DEBUGASSERT(sizeof(names)/sizeof(names[0]) == SSH_LAST);
-
-  if(sshc->state != nowstate) {
-    infof(conn->data, "SFTP %p state change from %s to %s\n",
-          (void *)sshc, names[sshc->state], names[nowstate]);
-  }
-#endif
-
-  sshc->state = nowstate;
-}
-
-
-#ifdef HAVE_LIBSSH2_KNOWNHOST_API
-static int sshkeycallback(struct Curl_easy *easy,
-                          const struct curl_khkey *knownkey, /* known */
-                          const struct curl_khkey *foundkey, /* found */
-                          enum curl_khmatch match,
-                          void *clientp)
-{
-  (void)easy;
-  (void)knownkey;
-  (void)foundkey;
-  (void)clientp;
-
-  /* we only allow perfect matches, and we reject everything else */
-  return (match != CURLKHMATCH_OK)?CURLKHSTAT_REJECT:CURLKHSTAT_FINE;
-}
-#endif
-
-/*
- * Earlier libssh2 versions didn't have the ability to seek to 64bit positions
- * with 32bit size_t.
- */
-#ifdef HAVE_LIBSSH2_SFTP_SEEK64
-#define SFTP_SEEK(x,y) libssh2_sftp_seek64(x, (libssh2_uint64_t)y)
-#else
-#define SFTP_SEEK(x,y) libssh2_sftp_seek(x, (size_t)y)
-#endif
-
-/*
- * Earlier libssh2 versions didn't do SCP properly beyond 32bit sizes on 32bit
- * architectures so we check of the necessary function is present.
- */
-#ifndef HAVE_LIBSSH2_SCP_SEND64
-#define SCP_SEND(a,b,c,d) libssh2_scp_send_ex(a, b, (int)(c), (size_t)d, 0, 0)
-#else
-#define SCP_SEND(a,b,c,d) libssh2_scp_send64(a, b, (int)(c),            \
-                                             (libssh2_uint64_t)d, 0, 0)
-#endif
-
-/*
- * libssh2 1.2.8 fixed the problem with 32bit ints used for sockets on win64.
- */
-#ifdef HAVE_LIBSSH2_SESSION_HANDSHAKE
-#define libssh2_session_startup(x,y) libssh2_session_handshake(x,y)
-#endif
-
-static CURLcode ssh_knownhost(struct connectdata *conn)
-{
-  CURLcode result = CURLE_OK;
-
-#ifdef HAVE_LIBSSH2_KNOWNHOST_API
-  struct Curl_easy *data = conn->data;
-
-  if(data->set.str[STRING_SSH_KNOWNHOSTS]) {
-    /* we're asked to verify the host against a file */
-    struct ssh_conn *sshc = &conn->proto.sshc;
-    int rc;
-    int keytype;
-    size_t keylen;
-    const char *remotekey = libssh2_session_hostkey(sshc->ssh_session,
-                                                    &keylen, &keytype);
-    int keycheck = LIBSSH2_KNOWNHOST_CHECK_FAILURE;
-    int keybit = 0;
-
-    if(remotekey) {
-      /*
-       * A subject to figure out is what host name we need to pass in here.
-       * What host name does OpenSSH store in its file if an IDN name is
-       * used?
-       */
-      struct libssh2_knownhost *host;
-      enum curl_khmatch keymatch;
-      curl_sshkeycallback func =
-        data->set.ssh_keyfunc?data->set.ssh_keyfunc:sshkeycallback;
-      struct curl_khkey knownkey;
-      struct curl_khkey *knownkeyp = NULL;
-      struct curl_khkey foundkey;
-
-      keybit = (keytype == LIBSSH2_HOSTKEY_TYPE_RSA)?
-        LIBSSH2_KNOWNHOST_KEY_SSHRSA:LIBSSH2_KNOWNHOST_KEY_SSHDSS;
-
-#ifdef HAVE_LIBSSH2_KNOWNHOST_CHECKP
-      keycheck = libssh2_knownhost_checkp(sshc->kh,
-                                          conn->host.name,
-                                          (conn->remote_port != PORT_SSH)?
-                                          conn->remote_port:-1,
-                                          remotekey, keylen,
-                                          LIBSSH2_KNOWNHOST_TYPE_PLAIN|
-                                          LIBSSH2_KNOWNHOST_KEYENC_RAW|
-                                          keybit,
-                                          &host);
-#else
-      keycheck = libssh2_knownhost_check(sshc->kh,
-                                         conn->host.name,
-                                         remotekey, keylen,
-                                         LIBSSH2_KNOWNHOST_TYPE_PLAIN|
-                                         LIBSSH2_KNOWNHOST_KEYENC_RAW|
-                                         keybit,
-                                         &host);
-#endif
-
-      infof(data, "SSH host check: %d, key: %s\n", keycheck,
-            (keycheck <= LIBSSH2_KNOWNHOST_CHECK_MISMATCH)?
-            host->key:"<none>");
-
-      /* setup 'knownkey' */
-      if(keycheck <= LIBSSH2_KNOWNHOST_CHECK_MISMATCH) {
-        knownkey.key = host->key;
-        knownkey.len = 0;
-        knownkey.keytype = (keytype == LIBSSH2_HOSTKEY_TYPE_RSA)?
-          CURLKHTYPE_RSA : CURLKHTYPE_DSS;
-        knownkeyp = &knownkey;
-      }
-
-      /* setup 'foundkey' */
-      foundkey.key = remotekey;
-      foundkey.len = keylen;
-      foundkey.keytype = (keytype == LIBSSH2_HOSTKEY_TYPE_RSA)?
-        CURLKHTYPE_RSA : CURLKHTYPE_DSS;
-
-      /*
-       * if any of the LIBSSH2_KNOWNHOST_CHECK_* defines and the
-       * curl_khmatch enum are ever modified, we need to introduce a
-       * translation table here!
-       */
-      keymatch = (enum curl_khmatch)keycheck;
-
-      /* Ask the callback how to behave */
-      Curl_set_in_callback(data, true);
-      rc = func(data, knownkeyp, /* from the knownhosts file */
-                &foundkey, /* from the remote host */
-                keymatch, data->set.ssh_keyfunc_userp);
-      Curl_set_in_callback(data, false);
-    }
-    else
-      /* no remotekey means failure! */
-      rc = CURLKHSTAT_REJECT;
-
-    switch(rc) {
-    default: /* unknown return codes will equal reject */
-      /* FALLTHROUGH */
-    case CURLKHSTAT_REJECT:
-      state(conn, SSH_SESSION_FREE);
-      /* FALLTHROUGH */
-    case CURLKHSTAT_DEFER:
-      /* DEFER means bail out but keep the SSH_HOSTKEY state */
-      result = sshc->actualcode = CURLE_PEER_FAILED_VERIFICATION;
-      break;
-    case CURLKHSTAT_FINE:
-    case CURLKHSTAT_FINE_ADD_TO_FILE:
-      /* proceed */
-      if(keycheck != LIBSSH2_KNOWNHOST_CHECK_MATCH) {
-        /* the found host+key didn't match but has been told to be fine
-           anyway so we add it in memory */
-        int addrc = libssh2_knownhost_add(sshc->kh,
-                                          conn->host.name, NULL,
-                                          remotekey, keylen,
-                                          LIBSSH2_KNOWNHOST_TYPE_PLAIN|
-                                          LIBSSH2_KNOWNHOST_KEYENC_RAW|
-                                          keybit, NULL);
-        if(addrc)
-          infof(data, "Warning adding the known host %s failed!\n",
-                conn->host.name);
-        else if(rc == CURLKHSTAT_FINE_ADD_TO_FILE) {
-          /* now we write the entire in-memory list of known hosts to the
-             known_hosts file */
-          int wrc =
-            libssh2_knownhost_writefile(sshc->kh,
-                                        data->set.str[STRING_SSH_KNOWNHOSTS],
-                                        LIBSSH2_KNOWNHOST_FILE_OPENSSH);
-          if(wrc) {
-            infof(data, "Warning, writing %s failed!\n",
-                  data->set.str[STRING_SSH_KNOWNHOSTS]);
-          }
-        }
-      }
-      break;
-    }
-  }
-#else /* HAVE_LIBSSH2_KNOWNHOST_API */
-  (void)conn;
-#endif
-  return result;
-}
-
-static CURLcode ssh_check_fingerprint(struct connectdata *conn)
-{
-  struct ssh_conn *sshc = &conn->proto.sshc;
-  struct Curl_easy *data = conn->data;
-  const char *pubkey_md5 = data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5];
-  char md5buffer[33];
-
-  const char *fingerprint = libssh2_hostkey_hash(sshc->ssh_session,
-      LIBSSH2_HOSTKEY_HASH_MD5);
-
-  if(fingerprint) {
-    /* The fingerprint points to static storage (!), don't free() it. */
-    int i;
-    for(i = 0; i < 16; i++)
-      msnprintf(&md5buffer[i*2], 3, "%02x", (unsigned char) fingerprint[i]);
-    infof(data, "SSH MD5 fingerprint: %s\n", md5buffer);
-  }
-
-  /* Before we authenticate we check the hostkey's MD5 fingerprint
-   * against a known fingerprint, if available.
-   */
-  if(pubkey_md5 && strlen(pubkey_md5) == 32) {
-    if(!fingerprint || !strcasecompare(md5buffer, pubkey_md5)) {
-      if(fingerprint)
-        failf(data,
-            "Denied establishing ssh session: mismatch md5 fingerprint. "
-            "Remote %s is not equal to %s", md5buffer, pubkey_md5);
-      else
-        failf(data,
-            "Denied establishing ssh session: md5 fingerprint not available");
-      state(conn, SSH_SESSION_FREE);
-      sshc->actualcode = CURLE_PEER_FAILED_VERIFICATION;
-      return sshc->actualcode;
-    }
-    infof(data, "MD5 checksum match!\n");
-    /* as we already matched, we skip the check for known hosts */
-    return CURLE_OK;
-  }
-  return ssh_knownhost(conn);
-}
-
-/*
- * ssh_statemach_act() runs the SSH state machine as far as it can without
- * blocking and without reaching the end.  The data the pointer 'block' points
- * to will be set to TRUE if the libssh2 function returns LIBSSH2_ERROR_EAGAIN
- * meaning it wants to be called again when the socket is ready
- */
-
-static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
-{
-  CURLcode result = CURLE_OK;
-  struct Curl_easy *data = conn->data;
-  struct SSHPROTO *sftp_scp = data->req.protop;
-  struct ssh_conn *sshc = &conn->proto.sshc;
-  curl_socket_t sock = conn->sock[FIRSTSOCKET];
-  char *new_readdir_line;
-  int rc = LIBSSH2_ERROR_NONE;
-  int err;
-  int seekerr = CURL_SEEKFUNC_OK;
-  *block = 0; /* we're not blocking by default */
-
-  do {
-
-    switch(sshc->state) {
-    case SSH_INIT:
-      sshc->secondCreateDirs = 0;
-      sshc->nextstate = SSH_NO_STATE;
-      sshc->actualcode = CURLE_OK;
-
-      /* Set libssh2 to non-blocking, since everything internally is
-         non-blocking */
-      libssh2_session_set_blocking(sshc->ssh_session, 0);
-
-      state(conn, SSH_S_STARTUP);
-      /* FALLTHROUGH */
-
-    case SSH_S_STARTUP:
-      rc = libssh2_session_startup(sshc->ssh_session, (int)sock);
-      if(rc == LIBSSH2_ERROR_EAGAIN) {
-        break;
-      }
-      if(rc) {
-        char *err_msg = NULL;
-        (void)libssh2_session_last_error(sshc->ssh_session, &err_msg, NULL, 0);
-        failf(data, "Failure establishing ssh session: %d, %s", rc, err_msg);
-
-        state(conn, SSH_SESSION_FREE);
-        sshc->actualcode = CURLE_FAILED_INIT;
-        break;
-      }
-
-      state(conn, SSH_HOSTKEY);
-
-      /* FALLTHROUGH */
-    case SSH_HOSTKEY:
-      /*
-       * Before we authenticate we should check the hostkey's fingerprint
-       * against our known hosts. How that is handled (reading from file,
-       * whatever) is up to us.
-       */
-      result = ssh_check_fingerprint(conn);
-      if(!result)
-        state(conn, SSH_AUTHLIST);
-      /* ssh_check_fingerprint sets state appropriately on error */
-      break;
-
-    case SSH_AUTHLIST:
-      /*
-       * Figure out authentication methods
-       * NB: As soon as we have provided a username to an openssh server we
-       * must never change it later. Thus, always specify the correct username
-       * here, even though the libssh2 docs kind of indicate that it should be
-       * possible to get a 'generic' list (not user-specific) of authentication
-       * methods, presumably with a blank username. That won't work in my
-       * experience.
-       * So always specify it here.
-       */
-      sshc->authlist = libssh2_userauth_list(sshc->ssh_session,
-                                             conn->user,
-                                             curlx_uztoui(strlen(conn->user)));
-
-      if(!sshc->authlist) {
-        if(libssh2_userauth_authenticated(sshc->ssh_session)) {
-          sshc->authed = TRUE;
-          infof(data, "SSH user accepted with no authentication\n");
-          state(conn, SSH_AUTH_DONE);
-          break;
-        }
-        err = libssh2_session_last_errno(sshc->ssh_session);
-        if(err == LIBSSH2_ERROR_EAGAIN)
-          rc = LIBSSH2_ERROR_EAGAIN;
-        else {
-          state(conn, SSH_SESSION_FREE);
-          sshc->actualcode = libssh2_session_error_to_CURLE(err);
-        }
-        break;
-      }
-      infof(data, "SSH authentication methods available: %s\n",
-            sshc->authlist);
-
-      state(conn, SSH_AUTH_PKEY_INIT);
-      break;
-
-    case SSH_AUTH_PKEY_INIT:
-      /*
-       * Check the supported auth types in the order I feel is most secure
-       * with the requested type of authentication
-       */
-      sshc->authed = FALSE;
-
-      if((data->set.ssh_auth_types & CURLSSH_AUTH_PUBLICKEY) &&
-         (strstr(sshc->authlist, "publickey") != NULL)) {
-        bool out_of_memory = FALSE;
-
-        sshc->rsa_pub = sshc->rsa = NULL;
-
-        if(data->set.str[STRING_SSH_PRIVATE_KEY])
-          sshc->rsa = strdup(data->set.str[STRING_SSH_PRIVATE_KEY]);
-        else {
-          /* To ponder about: should really the lib be messing about with the
-             HOME environment variable etc? */
-          char *home = curl_getenv("HOME");
-
-          /* If no private key file is specified, try some common paths. */
-          if(home) {
-            /* Try ~/.ssh first. */
-            sshc->rsa = aprintf("%s/.ssh/id_rsa", home);
-            if(!sshc->rsa)
-              out_of_memory = TRUE;
-            else if(access(sshc->rsa, R_OK) != 0) {
-              Curl_safefree(sshc->rsa);
-              sshc->rsa = aprintf("%s/.ssh/id_dsa", home);
-              if(!sshc->rsa)
-                out_of_memory = TRUE;
-              else if(access(sshc->rsa, R_OK) != 0) {
-                Curl_safefree(sshc->rsa);
-              }
-            }
-            free(home);
-          }
-          if(!out_of_memory && !sshc->rsa) {
-            /* Nothing found; try the current dir. */
-            sshc->rsa = strdup("id_rsa");
-            if(sshc->rsa && access(sshc->rsa, R_OK) != 0) {
-              Curl_safefree(sshc->rsa);
-              sshc->rsa = strdup("id_dsa");
-              if(sshc->rsa && access(sshc->rsa, R_OK) != 0) {
-                Curl_safefree(sshc->rsa);
-                /* Out of guesses. Set to the empty string to avoid
-                 * surprising info messages. */
-                sshc->rsa = strdup("");
-              }
-            }
-          }
-        }
-
-        /*
-         * Unless the user explicitly specifies a public key file, let
-         * libssh2 extract the public key from the private key file.
-         * This is done by simply passing sshc->rsa_pub = NULL.
-         */
-        if(data->set.str[STRING_SSH_PUBLIC_KEY]
-           /* treat empty string the same way as NULL */
-           && data->set.str[STRING_SSH_PUBLIC_KEY][0]) {
-          sshc->rsa_pub = strdup(data->set.str[STRING_SSH_PUBLIC_KEY]);
-          if(!sshc->rsa_pub)
-            out_of_memory = TRUE;
-        }
-
-        if(out_of_memory || sshc->rsa == NULL) {
-          Curl_safefree(sshc->rsa);
-          Curl_safefree(sshc->rsa_pub);
-          state(conn, SSH_SESSION_FREE);
-          sshc->actualcode = CURLE_OUT_OF_MEMORY;
-          break;
-        }
-
-        sshc->passphrase = data->set.ssl.key_passwd;
-        if(!sshc->passphrase)
-          sshc->passphrase = "";
-
-        if(sshc->rsa_pub)
-          infof(data, "Using SSH public key file '%s'\n", sshc->rsa_pub);
-        infof(data, "Using SSH private key file '%s'\n", sshc->rsa);
-
-        state(conn, SSH_AUTH_PKEY);
-      }
-      else {
-        state(conn, SSH_AUTH_PASS_INIT);
-      }
-      break;
-
-    case SSH_AUTH_PKEY:
-      /* The function below checks if the files exists, no need to stat() here.
-       */
-      rc = libssh2_userauth_publickey_fromfile_ex(sshc->ssh_session,
-                                                  conn->user,
-                                                  curlx_uztoui(
-                                                    strlen(conn->user)),
-                                                  sshc->rsa_pub,
-                                                  sshc->rsa, sshc->passphrase);
-      if(rc == LIBSSH2_ERROR_EAGAIN) {
-        break;
-      }
-
-      Curl_safefree(sshc->rsa_pub);
-      Curl_safefree(sshc->rsa);
-
-      if(rc == 0) {
-        sshc->authed = TRUE;
-        infof(data, "Initialized SSH public key authentication\n");
-        state(conn, SSH_AUTH_DONE);
-      }
-      else {
-        char *err_msg = NULL;
-        (void)libssh2_session_last_error(sshc->ssh_session,
-                                         &err_msg, NULL, 0);
-        infof(data, "SSH public key authentication failed: %s\n", err_msg);
-        state(conn, SSH_AUTH_PASS_INIT);
-        rc = 0; /* clear rc and continue */
-      }
-      break;
-
-    case SSH_AUTH_PASS_INIT:
-      if((data->set.ssh_auth_types & CURLSSH_AUTH_PASSWORD) &&
-         (strstr(sshc->authlist, "password") != NULL)) {
-        state(conn, SSH_AUTH_PASS);
-      }
-      else {
-        state(conn, SSH_AUTH_HOST_INIT);
-        rc = 0; /* clear rc and continue */
-      }
-      break;
-
-    case SSH_AUTH_PASS:
-      rc = libssh2_userauth_password_ex(sshc->ssh_session, conn->user,
-                                        curlx_uztoui(strlen(conn->user)),
-                                        conn->passwd,
-                                        curlx_uztoui(strlen(conn->passwd)),
-                                        NULL);
-      if(rc == LIBSSH2_ERROR_EAGAIN) {
-        break;
-      }
-      if(rc == 0) {
-        sshc->authed = TRUE;
-        infof(data, "Initialized password authentication\n");
-        state(conn, SSH_AUTH_DONE);
-      }
-      else {
-        state(conn, SSH_AUTH_HOST_INIT);
-        rc = 0; /* clear rc and continue */
-      }
-      break;
-
-    case SSH_AUTH_HOST_INIT:
-      if((data->set.ssh_auth_types & CURLSSH_AUTH_HOST) &&
-         (strstr(sshc->authlist, "hostbased") != NULL)) {
-        state(conn, SSH_AUTH_HOST);
-      }
-      else {
-        state(conn, SSH_AUTH_AGENT_INIT);
-      }
-      break;
-
-    case SSH_AUTH_HOST:
-      state(conn, SSH_AUTH_AGENT_INIT);
-      break;
-
-    case SSH_AUTH_AGENT_INIT:
-#ifdef HAVE_LIBSSH2_AGENT_API
-      if((data->set.ssh_auth_types & CURLSSH_AUTH_AGENT)
-         && (strstr(sshc->authlist, "publickey") != NULL)) {
-
-        /* Connect to the ssh-agent */
-        /* The agent could be shared by a curl thread i believe
-           but nothing obvious as keys can be added/removed at any time */
-        if(!sshc->ssh_agent) {
-          sshc->ssh_agent = libssh2_agent_init(sshc->ssh_session);
-          if(!sshc->ssh_agent) {
-            infof(data, "Could not create agent object\n");
-
-            state(conn, SSH_AUTH_KEY_INIT);
-            break;
-          }
-        }
-
-        rc = libssh2_agent_connect(sshc->ssh_agent);
-        if(rc == LIBSSH2_ERROR_EAGAIN)
-          break;
-        if(rc < 0) {
-          infof(data, "Failure connecting to agent\n");
-          state(conn, SSH_AUTH_KEY_INIT);
-          rc = 0; /* clear rc and continue */
-        }
-        else {
-          state(conn, SSH_AUTH_AGENT_LIST);
-        }
-      }
-      else
-#endif /* HAVE_LIBSSH2_AGENT_API */
-        state(conn, SSH_AUTH_KEY_INIT);
-      break;
-
-    case SSH_AUTH_AGENT_LIST:
-#ifdef HAVE_LIBSSH2_AGENT_API
-      rc = libssh2_agent_list_identities(sshc->ssh_agent);
-
-      if(rc == LIBSSH2_ERROR_EAGAIN)
-        break;
-      if(rc < 0) {
-        infof(data, "Failure requesting identities to agent\n");
-        state(conn, SSH_AUTH_KEY_INIT);
-        rc = 0; /* clear rc and continue */
-      }
-      else {
-        state(conn, SSH_AUTH_AGENT);
-        sshc->sshagent_prev_identity = NULL;
-      }
-#endif
-      break;
-
-    case SSH_AUTH_AGENT:
-#ifdef HAVE_LIBSSH2_AGENT_API
-      /* as prev_identity evolves only after an identity user auth finished we
-         can safely request it again as long as EAGAIN is returned here or by
-         libssh2_agent_userauth */
-      rc = libssh2_agent_get_identity(sshc->ssh_agent,
-                                      &sshc->sshagent_identity,
-                                      sshc->sshagent_prev_identity);
-      if(rc == LIBSSH2_ERROR_EAGAIN)
-        break;
-
-      if(rc == 0) {
-        rc = libssh2_agent_userauth(sshc->ssh_agent, conn->user,
-                                    sshc->sshagent_identity);
-
-        if(rc < 0) {
-          if(rc != LIBSSH2_ERROR_EAGAIN) {
-            /* tried and failed? go to next identity */
-            sshc->sshagent_prev_identity = sshc->sshagent_identity;
-          }
-          break;
-        }
-      }
-
-      if(rc < 0)
-        infof(data, "Failure requesting identities to agent\n");
-      else if(rc == 1)
-        infof(data, "No identity would match\n");
-
-      if(rc == LIBSSH2_ERROR_NONE) {
-        sshc->authed = TRUE;
-        infof(data, "Agent based authentication successful\n");
-        state(conn, SSH_AUTH_DONE);
-      }
-      else {
-        state(conn, SSH_AUTH_KEY_INIT);
-        rc = 0; /* clear rc and continue */
-      }
-#endif
-      break;
-
-    case SSH_AUTH_KEY_INIT:
-      if((data->set.ssh_auth_types & CURLSSH_AUTH_KEYBOARD)
-         && (strstr(sshc->authlist, "keyboard-interactive") != NULL)) {
-        state(conn, SSH_AUTH_KEY);
-      }
-      else {
-        state(conn, SSH_AUTH_DONE);
-      }
-      break;
-
-    case SSH_AUTH_KEY:
-      /* Authentication failed. Continue with keyboard-interactive now. */
-      rc = libssh2_userauth_keyboard_interactive_ex(sshc->ssh_session,
-                                                    conn->user,
-                                                    curlx_uztoui(
-                                                      strlen(conn->user)),
-                                                    &kbd_callback);
-      if(rc == LIBSSH2_ERROR_EAGAIN) {
-        break;
-      }
-      if(rc == 0) {
-        sshc->authed = TRUE;
-        infof(data, "Initialized keyboard interactive authentication\n");
-      }
-      state(conn, SSH_AUTH_DONE);
-      break;
-
-    case SSH_AUTH_DONE:
-      if(!sshc->authed) {
-        failf(data, "Authentication failure");
-        state(conn, SSH_SESSION_FREE);
-        sshc->actualcode = CURLE_LOGIN_DENIED;
-        break;
-      }
-
-      /*
-       * At this point we have an authenticated ssh session.
-       */
-      infof(data, "Authentication complete\n");
-
-      Curl_pgrsTime(conn->data, TIMER_APPCONNECT); /* SSH is connected */
-
-      conn->sockfd = sock;
-      conn->writesockfd = CURL_SOCKET_BAD;
-
-      if(conn->handler->protocol == CURLPROTO_SFTP) {
-        state(conn, SSH_SFTP_INIT);
-        break;
-      }
-      infof(data, "SSH CONNECT phase done\n");
-      state(conn, SSH_STOP);
-      break;
-
-    case SSH_SFTP_INIT:
-      /*
-       * Start the libssh2 sftp session
-       */
-      sshc->sftp_session = libssh2_sftp_init(sshc->ssh_session);
-      if(!sshc->sftp_session) {
-        char *err_msg = NULL;
-        if(libssh2_session_last_errno(sshc->ssh_session) ==
-           LIBSSH2_ERROR_EAGAIN) {
-          rc = LIBSSH2_ERROR_EAGAIN;
-          break;
-        }
-
-        (void)libssh2_session_last_error(sshc->ssh_session,
-                                         &err_msg, NULL, 0);
-        failf(data, "Failure initializing sftp session: %s", err_msg);
-        state(conn, SSH_SESSION_FREE);
-        sshc->actualcode = CURLE_FAILED_INIT;
-        break;
-      }
-      state(conn, SSH_SFTP_REALPATH);
-      break;
-
-    case SSH_SFTP_REALPATH:
-    {
-      char tempHome[PATH_MAX];
-
-      /*
-       * Get the "home" directory
-       */
-      rc = sftp_libssh2_realpath(sshc->sftp_session, ".",
-                                 tempHome, PATH_MAX-1);
-      if(rc == LIBSSH2_ERROR_EAGAIN) {
-        break;
-      }
-      if(rc > 0) {
-        /* It seems that this string is not always NULL terminated */
-        tempHome[rc] = '\0';
-        sshc->homedir = strdup(tempHome);
-        if(!sshc->homedir) {
-          state(conn, SSH_SFTP_CLOSE);
-          sshc->actualcode = CURLE_OUT_OF_MEMORY;
-          break;
-        }
-        conn->data->state.most_recent_ftp_entrypath = sshc->homedir;
-      }
-      else {
-        /* Return the error type */
-        err = sftp_libssh2_last_error(sshc->sftp_session);
-        if(err)
-          result = sftp_libssh2_error_to_CURLE(err);
-        else
-          /* in this case, the error wasn't in the SFTP level but for example
-             a time-out or similar */
-          result = CURLE_SSH;
-        sshc->actualcode = result;
-        DEBUGF(infof(data, "error = %d makes libcurl = %d\n",
-                     err, (int)result));
-        state(conn, SSH_STOP);
-        break;
-      }
-    }
-    /* This is the last step in the SFTP connect phase. Do note that while
-       we get the homedir here, we get the "workingpath" in the DO action
-       since the homedir will remain the same between request but the
-       working path will not. */
-    DEBUGF(infof(data, "SSH CONNECT phase done\n"));
-    state(conn, SSH_STOP);
-    break;
-
-    case SSH_SFTP_QUOTE_INIT:
-
-      result = Curl_getworkingpath(conn, sshc->homedir, &sftp_scp->path);
-      if(result) {
-        sshc->actualcode = result;
-        state(conn, SSH_STOP);
-        break;
-      }
-
-      if(data->set.quote) {
-        infof(data, "Sending quote commands\n");
-        sshc->quote_item = data->set.quote;
-        state(conn, SSH_SFTP_QUOTE);
-      }
-      else {
-        state(conn, SSH_SFTP_GETINFO);
-      }
-      break;
-
-    case SSH_SFTP_POSTQUOTE_INIT:
-      if(data->set.postquote) {
-        infof(data, "Sending quote commands\n");
-        sshc->quote_item = data->set.postquote;
-        state(conn, SSH_SFTP_QUOTE);
-      }
-      else {
-        state(conn, SSH_STOP);
-      }
-      break;
-
-    case SSH_SFTP_QUOTE:
-      /* Send any quote commands */
-    {
-      const char *cp;
-
-      /*
-       * Support some of the "FTP" commands
-       *
-       * 'sshc->quote_item' is already verified to be non-NULL before it
-       * switched to this state.
-       */
-      char *cmd = sshc->quote_item->data;
-      sshc->acceptfail = FALSE;
-
-      /* if a command starts with an asterisk, which a legal SFTP command never
-         can, the command will be allowed to fail without it causing any
-         aborts or cancels etc. It will cause libcurl to act as if the command
-         is successful, whatever the server reponds. */
-
-      if(cmd[0] == '*') {
-        cmd++;
-        sshc->acceptfail = TRUE;
-      }
-
-      if(strcasecompare("pwd", cmd)) {
-        /* output debug output if that is requested */
-        char *tmp = aprintf("257 \"%s\" is current directory.\n",
-                            sftp_scp->path);
-        if(!tmp) {
-          result = CURLE_OUT_OF_MEMORY;
-          state(conn, SSH_SFTP_CLOSE);
-          sshc->nextstate = SSH_NO_STATE;
-          break;
-        }
-        if(data->set.verbose) {
-          Curl_debug(data, CURLINFO_HEADER_OUT, (char *)"PWD\n", 4);
-          Curl_debug(data, CURLINFO_HEADER_IN, tmp, strlen(tmp));
-        }
-        /* this sends an FTP-like "header" to the header callback so that the
-           current directory can be read very similar to how it is read when
-           using ordinary FTP. */
-        result = Curl_client_write(conn, CLIENTWRITE_HEADER, tmp, strlen(tmp));
-        free(tmp);
-        if(result) {
-          state(conn, SSH_SFTP_CLOSE);
-          sshc->nextstate = SSH_NO_STATE;
-          sshc->actualcode = result;
-        }
-        else
-          state(conn, SSH_SFTP_NEXT_QUOTE);
-        break;
-      }
-      {
-        /*
-         * the arguments following the command must be separated from the
-         * command with a space so we can check for it unconditionally
-         */
-        cp = strchr(cmd, ' ');
-        if(cp == NULL) {
-          failf(data, "Syntax error in SFTP command. Supply parameter(s)!");
-          state(conn, SSH_SFTP_CLOSE);
-          sshc->nextstate = SSH_NO_STATE;
-          sshc->actualcode = CURLE_QUOTE_ERROR;
-          break;
-        }
-
-        /*
-         * also, every command takes at least one argument so we get that
-         * first argument right now
-         */
-        result = Curl_get_pathname(&cp, &sshc->quote_path1, sshc->homedir);
-        if(result) {
-          if(result == CURLE_OUT_OF_MEMORY)
-            failf(data, "Out of memory");
-          else
-            failf(data, "Syntax error: Bad first parameter");
-          state(conn, SSH_SFTP_CLOSE);
-          sshc->nextstate = SSH_NO_STATE;
-          sshc->actualcode = result;
-          break;
-        }
-
-        /*
-         * SFTP is a binary protocol, so we don't send text commands
-         * to the server. Instead, we scan for commands used by
-         * OpenSSH's sftp program and call the appropriate libssh2
-         * functions.
-         */
-        if(strncasecompare(cmd, "chgrp ", 6) ||
-           strncasecompare(cmd, "chmod ", 6) ||
-           strncasecompare(cmd, "chown ", 6) ) {
-          /* attribute change */
-
-          /* sshc->quote_path1 contains the mode to set */
-          /* get the destination */
-          result = Curl_get_pathname(&cp, &sshc->quote_path2, sshc->homedir);
-          if(result) {
-            if(result == CURLE_OUT_OF_MEMORY)
-              failf(data, "Out of memory");
-            else
-              failf(data, "Syntax error in chgrp/chmod/chown: "
-                    "Bad second parameter");
-            Curl_safefree(sshc->quote_path1);
-            state(conn, SSH_SFTP_CLOSE);
-            sshc->nextstate = SSH_NO_STATE;
-            sshc->actualcode = result;
-            break;
-          }
-          memset(&sshc->quote_attrs, 0, sizeof(LIBSSH2_SFTP_ATTRIBUTES));
-          state(conn, SSH_SFTP_QUOTE_STAT);
-          break;
-        }
-        if(strncasecompare(cmd, "ln ", 3) ||
-           strncasecompare(cmd, "symlink ", 8)) {
-          /* symbolic linking */
-          /* sshc->quote_path1 is the source */
-          /* get the destination */
-          result = Curl_get_pathname(&cp, &sshc->quote_path2, sshc->homedir);
-          if(result) {
-            if(result == CURLE_OUT_OF_MEMORY)
-              failf(data, "Out of memory");
-            else
-              failf(data,
-                    "Syntax error in ln/symlink: Bad second parameter");
-            Curl_safefree(sshc->quote_path1);
-            state(conn, SSH_SFTP_CLOSE);
-            sshc->nextstate = SSH_NO_STATE;
-            sshc->actualcode = result;
-            break;
-          }
-          state(conn, SSH_SFTP_QUOTE_SYMLINK);
-          break;
-        }
-        else if(strncasecompare(cmd, "mkdir ", 6)) {
-          /* create dir */
-          state(conn, SSH_SFTP_QUOTE_MKDIR);
-          break;
-        }
-        else if(strncasecompare(cmd, "rename ", 7)) {
-          /* rename file */
-          /* first param is the source path */
-          /* second param is the dest. path */
-          result = Curl_get_pathname(&cp, &sshc->quote_path2, sshc->homedir);
-          if(result) {
-            if(result == CURLE_OUT_OF_MEMORY)
-              failf(data, "Out of memory");
-            else
-              failf(data, "Syntax error in rename: Bad second parameter");
-            Curl_safefree(sshc->quote_path1);
-            state(conn, SSH_SFTP_CLOSE);
-            sshc->nextstate = SSH_NO_STATE;
-            sshc->actualcode = result;
-            break;
-          }
-          state(conn, SSH_SFTP_QUOTE_RENAME);
-          break;
-        }
-        else if(strncasecompare(cmd, "rmdir ", 6)) {
-          /* delete dir */
-          state(conn, SSH_SFTP_QUOTE_RMDIR);
-          break;
-        }
-        else if(strncasecompare(cmd, "rm ", 3)) {
-          state(conn, SSH_SFTP_QUOTE_UNLINK);
-          break;
-        }
-#ifdef HAS_STATVFS_SUPPORT
-        else if(strncasecompare(cmd, "statvfs ", 8)) {
-          state(conn, SSH_SFTP_QUOTE_STATVFS);
-          break;
-        }
-#endif
-
-        failf(data, "Unknown SFTP command");
-        Curl_safefree(sshc->quote_path1);
-        Curl_safefree(sshc->quote_path2);
-        state(conn, SSH_SFTP_CLOSE);
-        sshc->nextstate = SSH_NO_STATE;
-        sshc->actualcode = CURLE_QUOTE_ERROR;
-        break;
-      }
-    }
-    break;
-
-    case SSH_SFTP_NEXT_QUOTE:
-      Curl_safefree(sshc->quote_path1);
-      Curl_safefree(sshc->quote_path2);
-
-      sshc->quote_item = sshc->quote_item->next;
-
-      if(sshc->quote_item) {
-        state(conn, SSH_SFTP_QUOTE);
-      }
-      else {
-        if(sshc->nextstate != SSH_NO_STATE) {
-          state(conn, sshc->nextstate);
-          sshc->nextstate = SSH_NO_STATE;
-        }
-        else {
-          state(conn, SSH_SFTP_GETINFO);
-        }
-      }
-      break;
-
-    case SSH_SFTP_QUOTE_STAT:
-    {
-      char *cmd = sshc->quote_item->data;
-      sshc->acceptfail = FALSE;
-
-      /* if a command starts with an asterisk, which a legal SFTP command never
-         can, the command will be allowed to fail without it causing any
-         aborts or cancels etc. It will cause libcurl to act as if the command
-         is successful, whatever the server reponds. */
-
-      if(cmd[0] == '*') {
-        cmd++;
-        sshc->acceptfail = TRUE;
-      }
-
-      if(!strncasecompare(cmd, "chmod", 5)) {
-        /* Since chown and chgrp only set owner OR group but libssh2 wants to
-         * set them both at once, we need to obtain the current ownership
-         * first.  This takes an extra protocol round trip.
-         */
-        rc = libssh2_sftp_stat_ex(sshc->sftp_session, sshc->quote_path2,
-                                  curlx_uztoui(strlen(sshc->quote_path2)),
-                                  LIBSSH2_SFTP_STAT,
-                                  &sshc->quote_attrs);
-        if(rc == LIBSSH2_ERROR_EAGAIN) {
-          break;
-        }
-        if(rc != 0 && !sshc->acceptfail) { /* get those attributes */
-          err = sftp_libssh2_last_error(sshc->sftp_session);
-          Curl_safefree(sshc->quote_path1);
-          Curl_safefree(sshc->quote_path2);
-          failf(data, "Attempt to get SFTP stats failed: %s",
-                sftp_libssh2_strerror(err));
-          state(conn, SSH_SFTP_CLOSE);
-          sshc->nextstate = SSH_NO_STATE;
-          sshc->actualcode = CURLE_QUOTE_ERROR;
-          break;
-        }
-      }
-
-      /* Now set the new attributes... */
-      if(strncasecompare(cmd, "chgrp", 5)) {
-        sshc->quote_attrs.gid = strtoul(sshc->quote_path1, NULL, 10);
-        sshc->quote_attrs.flags = LIBSSH2_SFTP_ATTR_UIDGID;
-        if(sshc->quote_attrs.gid == 0 && !ISDIGIT(sshc->quote_path1[0]) &&
-           !sshc->acceptfail) {
-          Curl_safefree(sshc->quote_path1);
-          Curl_safefree(sshc->quote_path2);
-          failf(data, "Syntax error: chgrp gid not a number");
-          state(conn, SSH_SFTP_CLOSE);
-          sshc->nextstate = SSH_NO_STATE;
-          sshc->actualcode = CURLE_QUOTE_ERROR;
-          break;
-        }
-      }
-      else if(strncasecompare(cmd, "chmod", 5)) {
-        sshc->quote_attrs.permissions = strtoul(sshc->quote_path1, NULL, 8);
-        sshc->quote_attrs.flags = LIBSSH2_SFTP_ATTR_PERMISSIONS;
-        /* permissions are octal */
-        if(sshc->quote_attrs.permissions == 0 &&
-           !ISDIGIT(sshc->quote_path1[0])) {
-          Curl_safefree(sshc->quote_path1);
-          Curl_safefree(sshc->quote_path2);
-          failf(data, "Syntax error: chmod permissions not a number");
-          state(conn, SSH_SFTP_CLOSE);
-          sshc->nextstate = SSH_NO_STATE;
-          sshc->actualcode = CURLE_QUOTE_ERROR;
-          break;
-        }
-      }
-      else if(strncasecompare(cmd, "chown", 5)) {
-        sshc->quote_attrs.uid = strtoul(sshc->quote_path1, NULL, 10);
-        sshc->quote_attrs.flags = LIBSSH2_SFTP_ATTR_UIDGID;
-        if(sshc->quote_attrs.uid == 0 && !ISDIGIT(sshc->quote_path1[0]) &&
-           !sshc->acceptfail) {
-          Curl_safefree(sshc->quote_path1);
-          Curl_safefree(sshc->quote_path2);
-          failf(data, "Syntax error: chown uid not a number");
-          state(conn, SSH_SFTP_CLOSE);
-          sshc->nextstate = SSH_NO_STATE;
-          sshc->actualcode = CURLE_QUOTE_ERROR;
-          break;
-        }
-      }
-
-      /* Now send the completed structure... */
-      state(conn, SSH_SFTP_QUOTE_SETSTAT);
-      break;
-    }
-
-    case SSH_SFTP_QUOTE_SETSTAT:
-      rc = libssh2_sftp_stat_ex(sshc->sftp_session, sshc->quote_path2,
-                                curlx_uztoui(strlen(sshc->quote_path2)),
-                                LIBSSH2_SFTP_SETSTAT,
-                                &sshc->quote_attrs);
-      if(rc == LIBSSH2_ERROR_EAGAIN) {
-        break;
-      }
-      if(rc != 0 && !sshc->acceptfail) {
-        err = sftp_libssh2_last_error(sshc->sftp_session);
-        Curl_safefree(sshc->quote_path1);
-        Curl_safefree(sshc->quote_path2);
-        failf(data, "Attempt to set SFTP stats failed: %s",
-              sftp_libssh2_strerror(err));
-        state(conn, SSH_SFTP_CLOSE);
-        sshc->nextstate = SSH_NO_STATE;
-        sshc->actualcode = CURLE_QUOTE_ERROR;
-        break;
-      }
-      state(conn, SSH_SFTP_NEXT_QUOTE);
-      break;
-
-    case SSH_SFTP_QUOTE_SYMLINK:
-      rc = libssh2_sftp_symlink_ex(sshc->sftp_session, sshc->quote_path1,
-                                   curlx_uztoui(strlen(sshc->quote_path1)),
-                                   sshc->quote_path2,
-                                   curlx_uztoui(strlen(sshc->quote_path2)),
-                                   LIBSSH2_SFTP_SYMLINK);
-      if(rc == LIBSSH2_ERROR_EAGAIN) {
-        break;
-      }
-      if(rc != 0 && !sshc->acceptfail) {
-        err = sftp_libssh2_last_error(sshc->sftp_session);
-        Curl_safefree(sshc->quote_path1);
-        Curl_safefree(sshc->quote_path2);
-        failf(data, "symlink command failed: %s",
-              sftp_libssh2_strerror(err));
-        state(conn, SSH_SFTP_CLOSE);
-        sshc->nextstate = SSH_NO_STATE;
-        sshc->actualcode = CURLE_QUOTE_ERROR;
-        break;
-      }
-      state(conn, SSH_SFTP_NEXT_QUOTE);
-      break;
-
-    case SSH_SFTP_QUOTE_MKDIR:
-      rc = libssh2_sftp_mkdir_ex(sshc->sftp_session, sshc->quote_path1,
-                                 curlx_uztoui(strlen(sshc->quote_path1)),
-                                 data->set.new_directory_perms);
-      if(rc == LIBSSH2_ERROR_EAGAIN) {
-        break;
-      }
-      if(rc != 0 && !sshc->acceptfail) {
-        err = sftp_libssh2_last_error(sshc->sftp_session);
-        Curl_safefree(sshc->quote_path1);
-        failf(data, "mkdir command failed: %s", sftp_libssh2_strerror(err));
-        state(conn, SSH_SFTP_CLOSE);
-        sshc->nextstate = SSH_NO_STATE;
-        sshc->actualcode = CURLE_QUOTE_ERROR;
-        break;
-      }
-      state(conn, SSH_SFTP_NEXT_QUOTE);
-      break;
-
-    case SSH_SFTP_QUOTE_RENAME:
-      rc = libssh2_sftp_rename_ex(sshc->sftp_session, sshc->quote_path1,
-                                  curlx_uztoui(strlen(sshc->quote_path1)),
-                                  sshc->quote_path2,
-                                  curlx_uztoui(strlen(sshc->quote_path2)),
-                                  LIBSSH2_SFTP_RENAME_OVERWRITE |
-                                  LIBSSH2_SFTP_RENAME_ATOMIC |
-                                  LIBSSH2_SFTP_RENAME_NATIVE);
-
-      if(rc == LIBSSH2_ERROR_EAGAIN) {
-        break;
-      }
-      if(rc != 0 && !sshc->acceptfail) {
-        err = sftp_libssh2_last_error(sshc->sftp_session);
-        Curl_safefree(sshc->quote_path1);
-        Curl_safefree(sshc->quote_path2);
-        failf(data, "rename command failed: %s", sftp_libssh2_strerror(err));
-        state(conn, SSH_SFTP_CLOSE);
-        sshc->nextstate = SSH_NO_STATE;
-        sshc->actualcode = CURLE_QUOTE_ERROR;
-        break;
-      }
-      state(conn, SSH_SFTP_NEXT_QUOTE);
-      break;
-
-    case SSH_SFTP_QUOTE_RMDIR:
-      rc = libssh2_sftp_rmdir_ex(sshc->sftp_session, sshc->quote_path1,
-                                 curlx_uztoui(strlen(sshc->quote_path1)));
-      if(rc == LIBSSH2_ERROR_EAGAIN) {
-        break;
-      }
-      if(rc != 0 && !sshc->acceptfail) {
-        err = sftp_libssh2_last_error(sshc->sftp_session);
-        Curl_safefree(sshc->quote_path1);
-        failf(data, "rmdir command failed: %s", sftp_libssh2_strerror(err));
-        state(conn, SSH_SFTP_CLOSE);
-        sshc->nextstate = SSH_NO_STATE;
-        sshc->actualcode = CURLE_QUOTE_ERROR;
-        break;
-      }
-      state(conn, SSH_SFTP_NEXT_QUOTE);
-      break;
-
-    case SSH_SFTP_QUOTE_UNLINK:
-      rc = libssh2_sftp_unlink_ex(sshc->sftp_session, sshc->quote_path1,
-                                  curlx_uztoui(strlen(sshc->quote_path1)));
-      if(rc == LIBSSH2_ERROR_EAGAIN) {
-        break;
-      }
-      if(rc != 0 && !sshc->acceptfail) {
-        err = sftp_libssh2_last_error(sshc->sftp_session);
-        Curl_safefree(sshc->quote_path1);
-        failf(data, "rm command failed: %s", sftp_libssh2_strerror(err));
-        state(conn, SSH_SFTP_CLOSE);
-        sshc->nextstate = SSH_NO_STATE;
-        sshc->actualcode = CURLE_QUOTE_ERROR;
-        break;
-      }
-      state(conn, SSH_SFTP_NEXT_QUOTE);
-      break;
-
-#ifdef HAS_STATVFS_SUPPORT
-    case SSH_SFTP_QUOTE_STATVFS:
-    {
-      LIBSSH2_SFTP_STATVFS statvfs;
-      rc = libssh2_sftp_statvfs(sshc->sftp_session, sshc->quote_path1,
-                                curlx_uztoui(strlen(sshc->quote_path1)),
-                                &statvfs);
-
-      if(rc == LIBSSH2_ERROR_EAGAIN) {
-        break;
-      }
-      if(rc != 0 && !sshc->acceptfail) {
-        err = sftp_libssh2_last_error(sshc->sftp_session);
-        Curl_safefree(sshc->quote_path1);
-        failf(data, "statvfs command failed: %s", sftp_libssh2_strerror(err));
-        state(conn, SSH_SFTP_CLOSE);
-        sshc->nextstate = SSH_NO_STATE;
-        sshc->actualcode = CURLE_QUOTE_ERROR;
-        break;
-      }
-      else if(rc == 0) {
-        char *tmp = aprintf("statvfs:\n"
-                            "f_bsize: %llu\n" "f_frsize: %llu\n"
-                            "f_blocks: %llu\n" "f_bfree: %llu\n"
-                            "f_bavail: %llu\n" "f_files: %llu\n"
-                            "f_ffree: %llu\n" "f_favail: %llu\n"
-                            "f_fsid: %llu\n" "f_flag: %llu\n"
-                            "f_namemax: %llu\n",
-                            statvfs.f_bsize, statvfs.f_frsize,
-                            statvfs.f_blocks, statvfs.f_bfree,
-                            statvfs.f_bavail, statvfs.f_files,
-                            statvfs.f_ffree, statvfs.f_favail,
-                            statvfs.f_fsid, statvfs.f_flag,
-                            statvfs.f_namemax);
-        if(!tmp) {
-          result = CURLE_OUT_OF_MEMORY;
-          state(conn, SSH_SFTP_CLOSE);
-          sshc->nextstate = SSH_NO_STATE;
-          break;
-        }
-
-        result = Curl_client_write(conn, CLIENTWRITE_HEADER, tmp, strlen(tmp));
-        free(tmp);
-        if(result) {
-          state(conn, SSH_SFTP_CLOSE);
-          sshc->nextstate = SSH_NO_STATE;
-          sshc->actualcode = result;
-        }
-      }
-      state(conn, SSH_SFTP_NEXT_QUOTE);
-      break;
-    }
-#endif
-    case SSH_SFTP_GETINFO:
-    {
-      if(data->set.get_filetime) {
-        state(conn, SSH_SFTP_FILETIME);
-      }
-      else {
-        state(conn, SSH_SFTP_TRANS_INIT);
-      }
-      break;
-    }
-
-    case SSH_SFTP_FILETIME:
-    {
-      LIBSSH2_SFTP_ATTRIBUTES attrs;
-
-      rc = libssh2_sftp_stat_ex(sshc->sftp_session, sftp_scp->path,
-                                curlx_uztoui(strlen(sftp_scp->path)),
-                                LIBSSH2_SFTP_STAT, &attrs);
-      if(rc == LIBSSH2_ERROR_EAGAIN) {
-        break;
-      }
-      if(rc == 0) {
-        data->info.filetime = attrs.mtime;
-      }
-
-      state(conn, SSH_SFTP_TRANS_INIT);
-      break;
-    }
-
-    case SSH_SFTP_TRANS_INIT:
-      if(data->set.upload)
-        state(conn, SSH_SFTP_UPLOAD_INIT);
-      else {
-        if(sftp_scp->path[strlen(sftp_scp->path)-1] == '/')
-          state(conn, SSH_SFTP_READDIR_INIT);
-        else
-          state(conn, SSH_SFTP_DOWNLOAD_INIT);
-      }
-      break;
-
-    case SSH_SFTP_UPLOAD_INIT:
-    {
-      unsigned long flags;
-      /*
-       * NOTE!!!  libssh2 requires that the destination path is a full path
-       *          that includes the destination file and name OR ends in a "/"
-       *          If this is not done the destination file will be named the
-       *          same name as the last directory in the path.
-       */
-
-      if(data->state.resume_from != 0) {
-        LIBSSH2_SFTP_ATTRIBUTES attrs;
-        if(data->state.resume_from < 0) {
-          rc = libssh2_sftp_stat_ex(sshc->sftp_session, sftp_scp->path,
-                                    curlx_uztoui(strlen(sftp_scp->path)),
-                                    LIBSSH2_SFTP_STAT, &attrs);
-          if(rc == LIBSSH2_ERROR_EAGAIN) {
-            break;
-          }
-          if(rc) {
-            data->state.resume_from = 0;
-          }
-          else {
-            curl_off_t size = attrs.filesize;
-            if(size < 0) {
-              failf(data, "Bad file size (%" CURL_FORMAT_CURL_OFF_T ")", size);
-              return CURLE_BAD_DOWNLOAD_RESUME;
-            }
-            data->state.resume_from = attrs.filesize;
-          }
-        }
-      }
-
-      if(data->set.ftp_append)
-        /* Try to open for append, but create if nonexisting */
-        flags = LIBSSH2_FXF_WRITE|LIBSSH2_FXF_CREAT|LIBSSH2_FXF_APPEND;
-      else if(data->state.resume_from > 0)
-        /* If we have restart position then open for append */
-        flags = LIBSSH2_FXF_WRITE|LIBSSH2_FXF_APPEND;
-      else
-        /* Clear file before writing (normal behaviour) */
-        flags = LIBSSH2_FXF_WRITE|LIBSSH2_FXF_CREAT|LIBSSH2_FXF_TRUNC;
-
-      sshc->sftp_handle =
-        libssh2_sftp_open_ex(sshc->sftp_session, sftp_scp->path,
-                             curlx_uztoui(strlen(sftp_scp->path)),
-                             flags, data->set.new_file_perms,
-                             LIBSSH2_SFTP_OPENFILE);
-
-      if(!sshc->sftp_handle) {
-        rc = libssh2_session_last_errno(sshc->ssh_session);
-
-        if(LIBSSH2_ERROR_EAGAIN == rc)
-          break;
-
-        if(LIBSSH2_ERROR_SFTP_PROTOCOL == rc)
-          /* only when there was an SFTP protocol error can we extract
-             the sftp error! */
-          err = sftp_libssh2_last_error(sshc->sftp_session);
-        else
-          err = -1; /* not an sftp error at all */
-
-        if(sshc->secondCreateDirs) {
-          state(conn, SSH_SFTP_CLOSE);
-          sshc->actualcode = err>= LIBSSH2_FX_OK?
-            sftp_libssh2_error_to_CURLE(err):CURLE_SSH;
-          failf(data, "Creating the dir/file failed: %s",
-                sftp_libssh2_strerror(err));
-          break;
-        }
-        if(((err == LIBSSH2_FX_NO_SUCH_FILE) ||
-            (err == LIBSSH2_FX_FAILURE) ||
-            (err == LIBSSH2_FX_NO_SUCH_PATH)) &&
-           (data->set.ftp_create_missing_dirs &&
-            (strlen(sftp_scp->path) > 1))) {
-          /* try to create the path remotely */
-          rc = 0; /* clear rc and continue */
-          sshc->secondCreateDirs = 1;
-          state(conn, SSH_SFTP_CREATE_DIRS_INIT);
-          break;
-        }
-        state(conn, SSH_SFTP_CLOSE);
-        sshc->actualcode = err>= LIBSSH2_FX_OK?
-          sftp_libssh2_error_to_CURLE(err):CURLE_SSH;
-        if(!sshc->actualcode) {
-          /* Sometimes, for some reason libssh2_sftp_last_error() returns
-             zero even though libssh2_sftp_open() failed previously! We need
-             to work around that! */
-          sshc->actualcode = CURLE_SSH;
-          err = -1;
-        }
-        failf(data, "Upload failed: %s (%d/%d)",
-              err>= LIBSSH2_FX_OK?sftp_libssh2_strerror(err):"ssh error",
-              err, rc);
-        break;
-      }
-
-      /* If we have a restart point then we need to seek to the correct
-         position. */
-      if(data->state.resume_from > 0) {
-        /* Let's read off the proper amount of bytes from the input. */
-        if(conn->seek_func) {
-          Curl_set_in_callback(data, true);
-          seekerr = conn->seek_func(conn->seek_client, data->state.resume_from,
-                                    SEEK_SET);
-          Curl_set_in_callback(data, false);
-        }
-
-        if(seekerr != CURL_SEEKFUNC_OK) {
-          curl_off_t passed = 0;
-
-          if(seekerr != CURL_SEEKFUNC_CANTSEEK) {
-            failf(data, "Could not seek stream");
-            return CURLE_FTP_COULDNT_USE_REST;
-          }
-          /* seekerr == CURL_SEEKFUNC_CANTSEEK (can't seek to offset) */
-          do {
-            size_t readthisamountnow =
-              (data->state.resume_from - passed > data->set.buffer_size) ?
-              (size_t)data->set.buffer_size :
-              curlx_sotouz(data->state.resume_from - passed);
-
-            size_t actuallyread;
-            Curl_set_in_callback(data, true);
-            actuallyread = data->state.fread_func(data->state.buffer, 1,
-                                                  readthisamountnow,
-                                                  data->state.in);
-            Curl_set_in_callback(data, false);
-
-            passed += actuallyread;
-            if((actuallyread == 0) || (actuallyread > readthisamountnow)) {
-              /* this checks for greater-than only to make sure that the
-                 CURL_READFUNC_ABORT return code still aborts */
-              failf(data, "Failed to read data");
-              return CURLE_FTP_COULDNT_USE_REST;
-            }
-          } while(passed < data->state.resume_from);
-        }
-
-        /* now, decrease the size of the read */
-        if(data->state.infilesize > 0) {
-          data->state.infilesize -= data->state.resume_from;
-          data->req.size = data->state.infilesize;
-          Curl_pgrsSetUploadSize(data, data->state.infilesize);
-        }
-
-        SFTP_SEEK(sshc->sftp_handle, data->state.resume_from);
-      }
-      if(data->state.infilesize > 0) {
-        data->req.size = data->state.infilesize;
-        Curl_pgrsSetUploadSize(data, data->state.infilesize);
-      }
-      /* upload data */
-      Curl_setup_transfer(data, -1, -1, FALSE, FIRSTSOCKET);
-
-      /* not set by Curl_setup_transfer to preserve keepon bits */
-      conn->sockfd = conn->writesockfd;
-
-      if(result) {
-        state(conn, SSH_SFTP_CLOSE);
-        sshc->actualcode = result;
-      }
-      else {
-        /* store this original bitmask setup to use later on if we can't
-           figure out a "real" bitmask */
-        sshc->orig_waitfor = data->req.keepon;
-
-        /* we want to use the _sending_ function even when the socket turns
-           out readable as the underlying libssh2 sftp send function will deal
-           with both accordingly */
-        conn->cselect_bits = CURL_CSELECT_OUT;
-
-        /* since we don't really wait for anything at this point, we want the
-           state machine to move on as soon as possible so we set a very short
-           timeout here */
-        Curl_expire(data, 0, EXPIRE_RUN_NOW);
-
-        state(conn, SSH_STOP);
-      }
-      break;
-    }
-
-    case SSH_SFTP_CREATE_DIRS_INIT:
-      if(strlen(sftp_scp->path) > 1) {
-        sshc->slash_pos = sftp_scp->path + 1; /* ignore the leading '/' */
-        state(conn, SSH_SFTP_CREATE_DIRS);
-      }
-      else {
-        state(conn, SSH_SFTP_UPLOAD_INIT);
-      }
-      break;
-
-    case SSH_SFTP_CREATE_DIRS:
-      sshc->slash_pos = strchr(sshc->slash_pos, '/');
-      if(sshc->slash_pos) {
-        *sshc->slash_pos = 0;
-
-        infof(data, "Creating directory '%s'\n", sftp_scp->path);
-        state(conn, SSH_SFTP_CREATE_DIRS_MKDIR);
-        break;
-      }
-      state(conn, SSH_SFTP_UPLOAD_INIT);
-      break;
-
-    case SSH_SFTP_CREATE_DIRS_MKDIR:
-      /* 'mode' - parameter is preliminary - default to 0644 */
-      rc = libssh2_sftp_mkdir_ex(sshc->sftp_session, sftp_scp->path,
-                                 curlx_uztoui(strlen(sftp_scp->path)),
-                                 data->set.new_directory_perms);
-      if(rc == LIBSSH2_ERROR_EAGAIN) {
-        break;
-      }
-      *sshc->slash_pos = '/';
-      ++sshc->slash_pos;
-      if(rc < 0) {
-        /*
-         * Abort if failure wasn't that the dir already exists or the
-         * permission was denied (creation might succeed further down the
-         * path) - retry on unspecific FAILURE also
-         */
-        err = sftp_libssh2_last_error(sshc->sftp_session);
-        if((err != LIBSSH2_FX_FILE_ALREADY_EXISTS) &&
-           (err != LIBSSH2_FX_FAILURE) &&
-           (err != LIBSSH2_FX_PERMISSION_DENIED)) {
-          result = sftp_libssh2_error_to_CURLE(err);
-          state(conn, SSH_SFTP_CLOSE);
-          sshc->actualcode = result?result:CURLE_SSH;
-          break;
-        }
-        rc = 0; /* clear rc and continue */
-      }
-      state(conn, SSH_SFTP_CREATE_DIRS);
-      break;
-
-    case SSH_SFTP_READDIR_INIT:
-      Curl_pgrsSetDownloadSize(data, -1);
-      if(data->set.opt_no_body) {
-        state(conn, SSH_STOP);
-        break;
-      }
-
-      /*
-       * This is a directory that we are trying to get, so produce a directory
-       * listing
-       */
-      sshc->sftp_handle = libssh2_sftp_open_ex(sshc->sftp_session,
-                                               sftp_scp->path,
-                                               curlx_uztoui(
-                                                 strlen(sftp_scp->path)),
-                                               0, 0, LIBSSH2_SFTP_OPENDIR);
-      if(!sshc->sftp_handle) {
-        if(libssh2_session_last_errno(sshc->ssh_session) ==
-           LIBSSH2_ERROR_EAGAIN) {
-          rc = LIBSSH2_ERROR_EAGAIN;
-          break;
-        }
-        err = sftp_libssh2_last_error(sshc->sftp_session);
-        failf(data, "Could not open directory for reading: %s",
-              sftp_libssh2_strerror(err));
-        state(conn, SSH_SFTP_CLOSE);
-        result = sftp_libssh2_error_to_CURLE(err);
-        sshc->actualcode = result?result:CURLE_SSH;
-        break;
-      }
-      sshc->readdir_filename = malloc(PATH_MAX + 1);
-      if(!sshc->readdir_filename) {
-        state(conn, SSH_SFTP_CLOSE);
-        sshc->actualcode = CURLE_OUT_OF_MEMORY;
-        break;
-      }
-      sshc->readdir_longentry = malloc(PATH_MAX + 1);
-      if(!sshc->readdir_longentry) {
-        Curl_safefree(sshc->readdir_filename);
-        state(conn, SSH_SFTP_CLOSE);
-        sshc->actualcode = CURLE_OUT_OF_MEMORY;
-        break;
-      }
-      state(conn, SSH_SFTP_READDIR);
-      break;
-
-    case SSH_SFTP_READDIR:
-      rc = libssh2_sftp_readdir_ex(sshc->sftp_handle,
-                                   sshc->readdir_filename,
-                                   PATH_MAX,
-                                   sshc->readdir_longentry,
-                                   PATH_MAX,
-                                   &sshc->readdir_attrs);
-      if(rc == LIBSSH2_ERROR_EAGAIN) {
-        break;
-      }
-      if(rc > 0) {
-        sshc->readdir_len = (size_t) rc;
-        sshc->readdir_filename[sshc->readdir_len] = '\0';
-
-        if(data->set.ftp_list_only) {
-          char *tmpLine;
-
-          tmpLine = aprintf("%s\n", sshc->readdir_filename);
-          if(tmpLine == NULL) {
-            state(conn, SSH_SFTP_CLOSE);
-            sshc->actualcode = CURLE_OUT_OF_MEMORY;
-            break;
-          }
-          result = Curl_client_write(conn, CLIENTWRITE_BODY,
-                                     tmpLine, sshc->readdir_len + 1);
-          free(tmpLine);
-
-          if(result) {
-            state(conn, SSH_STOP);
-            break;
-          }
-          /* since this counts what we send to the client, we include the
-             newline in this counter */
-          data->req.bytecount += sshc->readdir_len + 1;
-
-          /* output debug output if that is requested */
-          if(data->set.verbose) {
-            Curl_debug(data, CURLINFO_DATA_OUT, sshc->readdir_filename,
-                       sshc->readdir_len);
-          }
-        }
-        else {
-          sshc->readdir_currLen = strlen(sshc->readdir_longentry);
-          sshc->readdir_totalLen = 80 + sshc->readdir_currLen;
-          sshc->readdir_line = calloc(sshc->readdir_totalLen, 1);
-          if(!sshc->readdir_line) {
-            Curl_safefree(sshc->readdir_filename);
-            Curl_safefree(sshc->readdir_longentry);
-            state(conn, SSH_SFTP_CLOSE);
-            sshc->actualcode = CURLE_OUT_OF_MEMORY;
-            break;
-          }
-
-          memcpy(sshc->readdir_line, sshc->readdir_longentry,
-                 sshc->readdir_currLen);
-          if((sshc->readdir_attrs.flags & LIBSSH2_SFTP_ATTR_PERMISSIONS) &&
-             ((sshc->readdir_attrs.permissions & LIBSSH2_SFTP_S_IFMT) ==
-              LIBSSH2_SFTP_S_IFLNK)) {
-            sshc->readdir_linkPath = malloc(PATH_MAX + 1);
-            if(sshc->readdir_linkPath == NULL) {
-              Curl_safefree(sshc->readdir_filename);
-              Curl_safefree(sshc->readdir_longentry);
-              state(conn, SSH_SFTP_CLOSE);
-              sshc->actualcode = CURLE_OUT_OF_MEMORY;
-              break;
-            }
-
-            msnprintf(sshc->readdir_linkPath, PATH_MAX, "%s%s", sftp_scp->path,
-                      sshc->readdir_filename);
-            state(conn, SSH_SFTP_READDIR_LINK);
-            break;
-          }
-          state(conn, SSH_SFTP_READDIR_BOTTOM);
-          break;
-        }
-      }
-      else if(rc == 0) {
-        Curl_safefree(sshc->readdir_filename);
-        Curl_safefree(sshc->readdir_longentry);
-        state(conn, SSH_SFTP_READDIR_DONE);
-        break;
-      }
-      else if(rc < 0) {
-        err = sftp_libssh2_last_error(sshc->sftp_session);
-        result = sftp_libssh2_error_to_CURLE(err);
-        sshc->actualcode = result?result:CURLE_SSH;
-        failf(data, "Could not open remote file for reading: %s :: %d",
-              sftp_libssh2_strerror(err),
-              libssh2_session_last_errno(sshc->ssh_session));
-        Curl_safefree(sshc->readdir_filename);
-        Curl_safefree(sshc->readdir_longentry);
-        state(conn, SSH_SFTP_CLOSE);
-        break;
-      }
-      break;
-
-    case SSH_SFTP_READDIR_LINK:
-      rc =
-        libssh2_sftp_symlink_ex(sshc->sftp_session,
-                                sshc->readdir_linkPath,
-                                curlx_uztoui(strlen(sshc->readdir_linkPath)),
-                                sshc->readdir_filename,
-                                PATH_MAX, LIBSSH2_SFTP_READLINK);
-      if(rc == LIBSSH2_ERROR_EAGAIN) {
-        break;
-      }
-      sshc->readdir_len = (size_t) rc;
-      Curl_safefree(sshc->readdir_linkPath);
-
-      /* get room for the filename and extra output */
-      sshc->readdir_totalLen += 4 + sshc->readdir_len;
-      new_readdir_line = Curl_saferealloc(sshc->readdir_line,
-                                          sshc->readdir_totalLen);
-      if(!new_readdir_line) {
-        sshc->readdir_line = NULL;
-        Curl_safefree(sshc->readdir_filename);
-        Curl_safefree(sshc->readdir_longentry);
-        state(conn, SSH_SFTP_CLOSE);
-        sshc->actualcode = CURLE_OUT_OF_MEMORY;
-        break;
-      }
-      sshc->readdir_line = new_readdir_line;
-
-      sshc->readdir_currLen += msnprintf(sshc->readdir_line +
-                                         sshc->readdir_currLen,
-                                         sshc->readdir_totalLen -
-                                         sshc->readdir_currLen,
-                                         " -> %s",
-                                         sshc->readdir_filename);
-
-      state(conn, SSH_SFTP_READDIR_BOTTOM);
-      break;
-
-    case SSH_SFTP_READDIR_BOTTOM:
-      sshc->readdir_currLen += msnprintf(sshc->readdir_line +
-                                         sshc->readdir_currLen,
-                                         sshc->readdir_totalLen -
-                                         sshc->readdir_currLen, "\n");
-      result = Curl_client_write(conn, CLIENTWRITE_BODY,
-                                 sshc->readdir_line,
-                                 sshc->readdir_currLen);
-
-      if(!result) {
-
-        /* output debug output if that is requested */
-        if(data->set.verbose) {
-          Curl_debug(data, CURLINFO_DATA_OUT, sshc->readdir_line,
-                     sshc->readdir_currLen);
-        }
-        data->req.bytecount += sshc->readdir_currLen;
-      }
-      Curl_safefree(sshc->readdir_line);
-      if(result) {
-        state(conn, SSH_STOP);
-      }
-      else
-        state(conn, SSH_SFTP_READDIR);
-      break;
-
-    case SSH_SFTP_READDIR_DONE:
-      if(libssh2_sftp_closedir(sshc->sftp_handle) ==
-         LIBSSH2_ERROR_EAGAIN) {
-        rc = LIBSSH2_ERROR_EAGAIN;
-        break;
-      }
-      sshc->sftp_handle = NULL;
-      Curl_safefree(sshc->readdir_filename);
-      Curl_safefree(sshc->readdir_longentry);
-
-      /* no data to transfer */
-      Curl_setup_transfer(data, -1, -1, FALSE, -1);
-      state(conn, SSH_STOP);
-      break;
-
-    case SSH_SFTP_DOWNLOAD_INIT:
-      /*
-       * Work on getting the specified file
-       */
-      sshc->sftp_handle =
-        libssh2_sftp_open_ex(sshc->sftp_session, sftp_scp->path,
-                             curlx_uztoui(strlen(sftp_scp->path)),
-                             LIBSSH2_FXF_READ, data->set.new_file_perms,
-                             LIBSSH2_SFTP_OPENFILE);
-      if(!sshc->sftp_handle) {
-        if(libssh2_session_last_errno(sshc->ssh_session) ==
-           LIBSSH2_ERROR_EAGAIN) {
-          rc = LIBSSH2_ERROR_EAGAIN;
-          break;
-        }
-        err = sftp_libssh2_last_error(sshc->sftp_session);
-        failf(data, "Could not open remote file for reading: %s",
-              sftp_libssh2_strerror(err));
-        state(conn, SSH_SFTP_CLOSE);
-        result = sftp_libssh2_error_to_CURLE(err);
-        sshc->actualcode = result?result:CURLE_SSH;
-        break;
-      }
-      state(conn, SSH_SFTP_DOWNLOAD_STAT);
-      break;
-
-    case SSH_SFTP_DOWNLOAD_STAT:
-    {
-      LIBSSH2_SFTP_ATTRIBUTES attrs;
-
-      rc = libssh2_sftp_stat_ex(sshc->sftp_session, sftp_scp->path,
-                                curlx_uztoui(strlen(sftp_scp->path)),
-                                LIBSSH2_SFTP_STAT, &attrs);
-      if(rc == LIBSSH2_ERROR_EAGAIN) {
-        break;
-      }
-      if(rc ||
-         !(attrs.flags & LIBSSH2_SFTP_ATTR_SIZE) ||
-         (attrs.filesize == 0)) {
-        /*
-         * libssh2_sftp_open() didn't return an error, so maybe the server
-         * just doesn't support stat()
-         * OR the server doesn't return a file size with a stat()
-         * OR file size is 0
-         */
-        data->req.size = -1;
-        data->req.maxdownload = -1;
-        Curl_pgrsSetDownloadSize(data, -1);
-      }
-      else {
-        curl_off_t size = attrs.filesize;
-
-        if(size < 0) {
-          failf(data, "Bad file size (%" CURL_FORMAT_CURL_OFF_T ")", size);
-          return CURLE_BAD_DOWNLOAD_RESUME;
-        }
-        if(conn->data->state.use_range) {
-          curl_off_t from, to;
-          char *ptr;
-          char *ptr2;
-          CURLofft to_t;
-          CURLofft from_t;
-
-          from_t = curlx_strtoofft(conn->data->state.range, &ptr, 0, &from);
-          if(from_t == CURL_OFFT_FLOW)
-            return CURLE_RANGE_ERROR;
-          while(*ptr && (ISSPACE(*ptr) || (*ptr == '-')))
-            ptr++;
-          to_t = curlx_strtoofft(ptr, &ptr2, 0, &to);
-          if(to_t == CURL_OFFT_FLOW)
-            return CURLE_RANGE_ERROR;
-          if((to_t == CURL_OFFT_INVAL) /* no "to" value given */
-             || (to >= size)) {
-            to = size - 1;
-          }
-          if(from_t) {
-            /* from is relative to end of file */
-            from = size - to;
-            to = size - 1;
-          }
-          if(from > size) {
-            failf(data, "Offset (%"
-                  CURL_FORMAT_CURL_OFF_T ") was beyond file size (%"
-                  CURL_FORMAT_CURL_OFF_T ")", from, attrs.filesize);
-            return CURLE_BAD_DOWNLOAD_RESUME;
-          }
-          if(from > to) {
-            from = to;
-            size = 0;
-          }
-          else {
-            size = to - from + 1;
-          }
-
-          SFTP_SEEK(conn->proto.sshc.sftp_handle, from);
-        }
-        data->req.size = size;
-        data->req.maxdownload = size;
-        Curl_pgrsSetDownloadSize(data, size);
-      }
-
-      /* We can resume if we can seek to the resume position */
-      if(data->state.resume_from) {
-        if(data->state.resume_from < 0) {
-          /* We're supposed to download the last abs(from) bytes */
-          if((curl_off_t)attrs.filesize < -data->state.resume_from) {
-            failf(data, "Offset (%"
-                  CURL_FORMAT_CURL_OFF_T ") was beyond file size (%"
-                  CURL_FORMAT_CURL_OFF_T ")",
-                  data->state.resume_from, attrs.filesize);
-            return CURLE_BAD_DOWNLOAD_RESUME;
-          }
-          /* download from where? */
-          data->state.resume_from += attrs.filesize;
-        }
-        else {
-          if((curl_off_t)attrs.filesize < data->state.resume_from) {
-            failf(data, "Offset (%" CURL_FORMAT_CURL_OFF_T
-                  ") was beyond file size (%" CURL_FORMAT_CURL_OFF_T ")",
-                  data->state.resume_from, attrs.filesize);
-            return CURLE_BAD_DOWNLOAD_RESUME;
-          }
-        }
-        /* Does a completed file need to be seeked and started or closed ? */
-        /* Now store the number of bytes we are expected to download */
-        data->req.size = attrs.filesize - data->state.resume_from;
-        data->req.maxdownload = attrs.filesize - data->state.resume_from;
-        Curl_pgrsSetDownloadSize(data,
-                                 attrs.filesize - data->state.resume_from);
-        SFTP_SEEK(sshc->sftp_handle, data->state.resume_from);
-      }
-    }
-
-    /* Setup the actual download */
-    if(data->req.size == 0) {
-      /* no data to transfer */
-      Curl_setup_transfer(data, -1, -1, FALSE, -1);
-      infof(data, "File already completely downloaded\n");
-      state(conn, SSH_STOP);
-      break;
-    }
-    Curl_setup_transfer(data, FIRSTSOCKET, data->req.size, FALSE, -1);
-
-    /* not set by Curl_setup_transfer to preserve keepon bits */
-    conn->writesockfd = conn->sockfd;
-
-    /* we want to use the _receiving_ function even when the socket turns
-       out writableable as the underlying libssh2 recv function will deal
-       with both accordingly */
-    conn->cselect_bits = CURL_CSELECT_IN;
-
-    if(result) {
-      /* this should never occur; the close state should be entered
-         at the time the error occurs */
-      state(conn, SSH_SFTP_CLOSE);
-      sshc->actualcode = result;
-    }
-    else {
-      state(conn, SSH_STOP);
-    }
-    break;
-
-    case SSH_SFTP_CLOSE:
-      if(sshc->sftp_handle) {
-        rc = libssh2_sftp_close(sshc->sftp_handle);
-        if(rc == LIBSSH2_ERROR_EAGAIN) {
-          break;
-        }
-        if(rc < 0) {
-          char *err_msg = NULL;
-          (void)libssh2_session_last_error(sshc->ssh_session,
-                                           &err_msg, NULL, 0);
-          infof(data, "Failed to close libssh2 file: %d %s\n", rc, err_msg);
-        }
-        sshc->sftp_handle = NULL;
-      }
-
-      Curl_safefree(sftp_scp->path);
-
-      DEBUGF(infof(data, "SFTP DONE done\n"));
-
-      /* Check if nextstate is set and move .nextstate could be POSTQUOTE_INIT
-         After nextstate is executed, the control should come back to
-         SSH_SFTP_CLOSE to pass the correct result back  */
-      if(sshc->nextstate != SSH_NO_STATE &&
-         sshc->nextstate != SSH_SFTP_CLOSE) {
-        state(conn, sshc->nextstate);
-        sshc->nextstate = SSH_SFTP_CLOSE;
-      }
-      else {
-        state(conn, SSH_STOP);
-        result = sshc->actualcode;
-      }
-      break;
-
-    case SSH_SFTP_SHUTDOWN:
-      /* during times we get here due to a broken transfer and then the
-         sftp_handle might not have been taken down so make sure that is done
-         before we proceed */
-
-      if(sshc->sftp_handle) {
-        rc = libssh2_sftp_close(sshc->sftp_handle);
-        if(rc == LIBSSH2_ERROR_EAGAIN) {
-          break;
-        }
-        if(rc < 0) {
-          char *err_msg = NULL;
-          (void)libssh2_session_last_error(sshc->ssh_session, &err_msg,
-                                           NULL, 0);
-          infof(data, "Failed to close libssh2 file: %d %s\n", rc, err_msg);
-        }
-        sshc->sftp_handle = NULL;
-      }
-      if(sshc->sftp_session) {
-        rc = libssh2_sftp_shutdown(sshc->sftp_session);
-        if(rc == LIBSSH2_ERROR_EAGAIN) {
-          break;
-        }
-        if(rc < 0) {
-          infof(data, "Failed to stop libssh2 sftp subsystem\n");
-        }
-        sshc->sftp_session = NULL;
-      }
-
-      Curl_safefree(sshc->homedir);
-      conn->data->state.most_recent_ftp_entrypath = NULL;
-
-      state(conn, SSH_SESSION_DISCONNECT);
-      break;
-
-    case SSH_SCP_TRANS_INIT:
-      result = Curl_getworkingpath(conn, sshc->homedir, &sftp_scp->path);
-      if(result) {
-        sshc->actualcode = result;
-        state(conn, SSH_STOP);
-        break;
-      }
-
-      if(data->set.upload) {
-        if(data->state.infilesize < 0) {
-          failf(data, "SCP requires a known file size for upload");
-          sshc->actualcode = CURLE_UPLOAD_FAILED;
-          state(conn, SSH_SCP_CHANNEL_FREE);
-          break;
-        }
-        state(conn, SSH_SCP_UPLOAD_INIT);
-      }
-      else {
-        state(conn, SSH_SCP_DOWNLOAD_INIT);
-      }
-      break;
-
-    case SSH_SCP_UPLOAD_INIT:
-      /*
-       * libssh2 requires that the destination path is a full path that
-       * includes the destination file and name OR ends in a "/" .  If this is
-       * not done the destination file will be named the same name as the last
-       * directory in the path.
-       */
-      sshc->ssh_channel =
-        SCP_SEND(sshc->ssh_session, sftp_scp->path, data->set.new_file_perms,
-                 data->state.infilesize);
-      if(!sshc->ssh_channel) {
-        int ssh_err;
-        char *err_msg = NULL;
-
-        if(libssh2_session_last_errno(sshc->ssh_session) ==
-           LIBSSH2_ERROR_EAGAIN) {
-          rc = LIBSSH2_ERROR_EAGAIN;
-          break;
-        }
-
-        ssh_err = (int)(libssh2_session_last_error(sshc->ssh_session,
-                                                   &err_msg, NULL, 0));
-        failf(conn->data, "%s", err_msg);
-        state(conn, SSH_SCP_CHANNEL_FREE);
-        sshc->actualcode = libssh2_session_error_to_CURLE(ssh_err);
-        /* Map generic errors to upload failed */
-        if(sshc->actualcode == CURLE_SSH ||
-           sshc->actualcode == CURLE_REMOTE_FILE_NOT_FOUND)
-          sshc->actualcode = CURLE_UPLOAD_FAILED;
-        break;
-      }
-
-      /* upload data */
-      Curl_setup_transfer(data, -1, data->req.size, FALSE, FIRSTSOCKET);
-
-      /* not set by Curl_setup_transfer to preserve keepon bits */
-      conn->sockfd = conn->writesockfd;
-
-      if(result) {
-        state(conn, SSH_SCP_CHANNEL_FREE);
-        sshc->actualcode = result;
-      }
-      else {
-        /* store this original bitmask setup to use later on if we can't
-           figure out a "real" bitmask */
-        sshc->orig_waitfor = data->req.keepon;
-
-        /* we want to use the _sending_ function even when the socket turns
-           out readable as the underlying libssh2 scp send function will deal
-           with both accordingly */
-        conn->cselect_bits = CURL_CSELECT_OUT;
-
-        state(conn, SSH_STOP);
-      }
-      break;
-
-    case SSH_SCP_DOWNLOAD_INIT:
-    {
-      curl_off_t bytecount;
-
-      /*
-       * We must check the remote file; if it is a directory no values will
-       * be set in sb
-       */
-
-      /*
-       * If support for >2GB files exists, use it.
-       */
-
-      /* get a fresh new channel from the ssh layer */
-#if LIBSSH2_VERSION_NUM < 0x010700
-      struct stat sb;
-      memset(&sb, 0, sizeof(struct stat));
-      sshc->ssh_channel = libssh2_scp_recv(sshc->ssh_session,
-                                           sftp_scp->path, &sb);
-#else
-      libssh2_struct_stat sb;
-      memset(&sb, 0, sizeof(libssh2_struct_stat));
-      sshc->ssh_channel = libssh2_scp_recv2(sshc->ssh_session,
-                                            sftp_scp->path, &sb);
-#endif
-
-      if(!sshc->ssh_channel) {
-        int ssh_err;
-        char *err_msg = NULL;
-
-        if(libssh2_session_last_errno(sshc->ssh_session) ==
-           LIBSSH2_ERROR_EAGAIN) {
-          rc = LIBSSH2_ERROR_EAGAIN;
-          break;
-        }
-
-
-        ssh_err = (int)(libssh2_session_last_error(sshc->ssh_session,
-                                                   &err_msg, NULL, 0));
-        failf(conn->data, "%s", err_msg);
-        state(conn, SSH_SCP_CHANNEL_FREE);
-        sshc->actualcode = libssh2_session_error_to_CURLE(ssh_err);
-        break;
-      }
-
-      /* download data */
-      bytecount = (curl_off_t)sb.st_size;
-      data->req.maxdownload =  (curl_off_t)sb.st_size;
-      Curl_setup_transfer(data, FIRSTSOCKET, bytecount, FALSE, -1);
-
-      /* not set by Curl_setup_transfer to preserve keepon bits */
-      conn->writesockfd = conn->sockfd;
-
-      /* we want to use the _receiving_ function even when the socket turns
-         out writableable as the underlying libssh2 recv function will deal
-         with both accordingly */
-      conn->cselect_bits = CURL_CSELECT_IN;
-
-      if(result) {
-        state(conn, SSH_SCP_CHANNEL_FREE);
-        sshc->actualcode = result;
-      }
-      else
-        state(conn, SSH_STOP);
-    }
-    break;
-
-    case SSH_SCP_DONE:
-      if(data->set.upload)
-        state(conn, SSH_SCP_SEND_EOF);
-      else
-        state(conn, SSH_SCP_CHANNEL_FREE);
-      break;
-
-    case SSH_SCP_SEND_EOF:
-      if(sshc->ssh_channel) {
-        rc = libssh2_channel_send_eof(sshc->ssh_channel);
-        if(rc == LIBSSH2_ERROR_EAGAIN) {
-          break;
-        }
-        if(rc) {
-          char *err_msg = NULL;
-          (void)libssh2_session_last_error(sshc->ssh_session,
-                                           &err_msg, NULL, 0);
-          infof(data, "Failed to send libssh2 channel EOF: %d %s\n",
-                rc, err_msg);
-        }
-      }
-      state(conn, SSH_SCP_WAIT_EOF);
-      break;
-
-    case SSH_SCP_WAIT_EOF:
-      if(sshc->ssh_channel) {
-        rc = libssh2_channel_wait_eof(sshc->ssh_channel);
-        if(rc == LIBSSH2_ERROR_EAGAIN) {
-          break;
-        }
-        if(rc) {
-          char *err_msg = NULL;
-          (void)libssh2_session_last_error(sshc->ssh_session,
-                                           &err_msg, NULL, 0);
-          infof(data, "Failed to get channel EOF: %d %s\n", rc, err_msg);
-        }
-      }
-      state(conn, SSH_SCP_WAIT_CLOSE);
-      break;
-
-    case SSH_SCP_WAIT_CLOSE:
-      if(sshc->ssh_channel) {
-        rc = libssh2_channel_wait_closed(sshc->ssh_channel);
-        if(rc == LIBSSH2_ERROR_EAGAIN) {
-          break;
-        }
-        if(rc) {
-          char *err_msg = NULL;
-          (void)libssh2_session_last_error(sshc->ssh_session,
-                                           &err_msg, NULL, 0);
-          infof(data, "Channel failed to close: %d %s\n", rc, err_msg);
-        }
-      }
-      state(conn, SSH_SCP_CHANNEL_FREE);
-      break;
-
-    case SSH_SCP_CHANNEL_FREE:
-      if(sshc->ssh_channel) {
-        rc = libssh2_channel_free(sshc->ssh_channel);
-        if(rc == LIBSSH2_ERROR_EAGAIN) {
-          break;
-        }
-        if(rc < 0) {
-          char *err_msg = NULL;
-          (void)libssh2_session_last_error(sshc->ssh_session,
-                                           &err_msg, NULL, 0);
-          infof(data, "Failed to free libssh2 scp subsystem: %d %s\n",
-                rc, err_msg);
-        }
-        sshc->ssh_channel = NULL;
-      }
-      DEBUGF(infof(data, "SCP DONE phase complete\n"));
-#if 0 /* PREV */
-      state(conn, SSH_SESSION_DISCONNECT);
-#endif
-      state(conn, SSH_STOP);
-      result = sshc->actualcode;
-      break;
-
-    case SSH_SESSION_DISCONNECT:
-      /* during weird times when we've been prematurely aborted, the channel
-         is still alive when we reach this state and we MUST kill the channel
-         properly first */
-      if(sshc->ssh_channel) {
-        rc = libssh2_channel_free(sshc->ssh_channel);
-        if(rc == LIBSSH2_ERROR_EAGAIN) {
-          break;
-        }
-        if(rc < 0) {
-          char *err_msg = NULL;
-          (void)libssh2_session_last_error(sshc->ssh_session,
-                                           &err_msg, NULL, 0);
-          infof(data, "Failed to free libssh2 scp subsystem: %d %s\n",
-                rc, err_msg);
-        }
-        sshc->ssh_channel = NULL;
-      }
-
-      if(sshc->ssh_session) {
-        rc = libssh2_session_disconnect(sshc->ssh_session, "Shutdown");
-        if(rc == LIBSSH2_ERROR_EAGAIN) {
-          break;
-        }
-        if(rc < 0) {
-          char *err_msg = NULL;
-          (void)libssh2_session_last_error(sshc->ssh_session,
-                                           &err_msg, NULL, 0);
-          infof(data, "Failed to disconnect libssh2 session: %d %s\n",
-                rc, err_msg);
-        }
-      }
-
-      Curl_safefree(sshc->homedir);
-      conn->data->state.most_recent_ftp_entrypath = NULL;
-
-      state(conn, SSH_SESSION_FREE);
-      break;
-
-    case SSH_SESSION_FREE:
-#ifdef HAVE_LIBSSH2_KNOWNHOST_API
-      if(sshc->kh) {
-        libssh2_knownhost_free(sshc->kh);
-        sshc->kh = NULL;
-      }
-#endif
-
-#ifdef HAVE_LIBSSH2_AGENT_API
-      if(sshc->ssh_agent) {
-        rc = libssh2_agent_disconnect(sshc->ssh_agent);
-        if(rc == LIBSSH2_ERROR_EAGAIN) {
-          break;
-        }
-        if(rc < 0) {
-          char *err_msg = NULL;
-          (void)libssh2_session_last_error(sshc->ssh_session,
-                                           &err_msg, NULL, 0);
-          infof(data, "Failed to disconnect from libssh2 agent: %d %s\n",
-                rc, err_msg);
-        }
-        libssh2_agent_free(sshc->ssh_agent);
-        sshc->ssh_agent = NULL;
-
-        /* NB: there is no need to free identities, they are part of internal
-           agent stuff */
-        sshc->sshagent_identity = NULL;
-        sshc->sshagent_prev_identity = NULL;
-      }
-#endif
-
-      if(sshc->ssh_session) {
-        rc = libssh2_session_free(sshc->ssh_session);
-        if(rc == LIBSSH2_ERROR_EAGAIN) {
-          break;
-        }
-        if(rc < 0) {
-          char *err_msg = NULL;
-          (void)libssh2_session_last_error(sshc->ssh_session,
-                                           &err_msg, NULL, 0);
-          infof(data, "Failed to free libssh2 session: %d %s\n", rc, err_msg);
-        }
-        sshc->ssh_session = NULL;
-      }
-
-      /* worst-case scenario cleanup */
-
-      DEBUGASSERT(sshc->ssh_session == NULL);
-      DEBUGASSERT(sshc->ssh_channel == NULL);
-      DEBUGASSERT(sshc->sftp_session == NULL);
-      DEBUGASSERT(sshc->sftp_handle == NULL);
-#ifdef HAVE_LIBSSH2_KNOWNHOST_API
-      DEBUGASSERT(sshc->kh == NULL);
-#endif
-#ifdef HAVE_LIBSSH2_AGENT_API
-      DEBUGASSERT(sshc->ssh_agent == NULL);
-#endif
-
-      Curl_safefree(sshc->rsa_pub);
-      Curl_safefree(sshc->rsa);
-
-      Curl_safefree(sshc->quote_path1);
-      Curl_safefree(sshc->quote_path2);
-
-      Curl_safefree(sshc->homedir);
-
-      Curl_safefree(sshc->readdir_filename);
-      Curl_safefree(sshc->readdir_longentry);
-      Curl_safefree(sshc->readdir_line);
-      Curl_safefree(sshc->readdir_linkPath);
-
-      /* the code we are about to return */
-      result = sshc->actualcode;
-
-      memset(sshc, 0, sizeof(struct ssh_conn));
-
-      connclose(conn, "SSH session free");
-      sshc->state = SSH_SESSION_FREE; /* current */
-      sshc->nextstate = SSH_NO_STATE;
-      state(conn, SSH_STOP);
-      break;
-
-    case SSH_QUIT:
-      /* fallthrough, just stop! */
-    default:
-      /* internal error */
-      sshc->nextstate = SSH_NO_STATE;
-      state(conn, SSH_STOP);
-      break;
-    }
-
-  } while(!rc && (sshc->state != SSH_STOP));
-
-  if(rc == LIBSSH2_ERROR_EAGAIN) {
-    /* we would block, we need to wait for the socket to be ready (in the
-       right direction too)! */
-    *block = TRUE;
-  }
-
-  return result;
-}
-
-/* called by the multi interface to figure out what socket(s) to wait for and
-   for what actions in the DO_DONE, PERFORM and WAITPERFORM states */
-static int ssh_perform_getsock(const struct connectdata *conn,
-                               curl_socket_t *sock, /* points to numsocks
-                                                       number of sockets */
-                               int numsocks)
-{
-#ifdef HAVE_LIBSSH2_SESSION_BLOCK_DIRECTION
-  int bitmap = GETSOCK_BLANK;
-  (void)numsocks;
-
-  sock[0] = conn->sock[FIRSTSOCKET];
-
-  if(conn->waitfor & KEEP_RECV)
-    bitmap |= GETSOCK_READSOCK(FIRSTSOCKET);
-
-  if(conn->waitfor & KEEP_SEND)
-    bitmap |= GETSOCK_WRITESOCK(FIRSTSOCKET);
-
-  return bitmap;
-#else
-  /* if we don't know the direction we can use the generic *_getsock()
-     function even for the protocol_connect and doing states */
-  return Curl_single_getsock(conn, sock, numsocks);
-#endif
-}
-
-/* Generic function called by the multi interface to figure out what socket(s)
-   to wait for and for what actions during the DOING and PROTOCONNECT states*/
-static int ssh_getsock(struct connectdata *conn,
-                       curl_socket_t *sock, /* points to numsocks number
-                                               of sockets */
-                       int numsocks)
-{
-#ifndef HAVE_LIBSSH2_SESSION_BLOCK_DIRECTION
-  (void)conn;
-  (void)sock;
-  (void)numsocks;
-  /* if we don't know any direction we can just play along as we used to and
-     not provide any sensible info */
-  return GETSOCK_BLANK;
-#else
-  /* if we know the direction we can use the generic *_getsock() function even
-     for the protocol_connect and doing states */
-  return ssh_perform_getsock(conn, sock, numsocks);
-#endif
-}
-
-#ifdef HAVE_LIBSSH2_SESSION_BLOCK_DIRECTION
-/*
- * When one of the libssh2 functions has returned LIBSSH2_ERROR_EAGAIN this
- * function is used to figure out in what direction and stores this info so
- * that the multi interface can take advantage of it. Make sure to call this
- * function in all cases so that when it _doesn't_ return EAGAIN we can
- * restore the default wait bits.
- */
-static void ssh_block2waitfor(struct connectdata *conn, bool block)
-{
-  struct ssh_conn *sshc = &conn->proto.sshc;
-  int dir = 0;
-  if(block) {
-    dir = libssh2_session_block_directions(sshc->ssh_session);
-    if(dir) {
-      /* translate the libssh2 define bits into our own bit defines */
-      conn->waitfor = ((dir&LIBSSH2_SESSION_BLOCK_INBOUND)?KEEP_RECV:0) |
-        ((dir&LIBSSH2_SESSION_BLOCK_OUTBOUND)?KEEP_SEND:0);
-    }
-  }
-  if(!dir)
-    /* It didn't block or libssh2 didn't reveal in which direction, put back
-       the original set */
-    conn->waitfor = sshc->orig_waitfor;
-}
-#else
-  /* no libssh2 directional support so we simply don't know */
-#define ssh_block2waitfor(x,y) Curl_nop_stmt
-#endif
-
-/* called repeatedly until done from multi.c */
-static CURLcode ssh_multi_statemach(struct connectdata *conn, bool *done)
-{
-  struct ssh_conn *sshc = &conn->proto.sshc;
-  CURLcode result = CURLE_OK;
-  bool block; /* we store the status and use that to provide a ssh_getsock()
-                 implementation */
-  do {
-    result = ssh_statemach_act(conn, &block);
-    *done = (sshc->state == SSH_STOP) ? TRUE : FALSE;
-    /* if there's no error, it isn't done and it didn't EWOULDBLOCK, then
-       try again */
-  } while(!result && !*done && !block);
-  ssh_block2waitfor(conn, block);
-
-  return result;
-}
-
-static CURLcode ssh_block_statemach(struct connectdata *conn,
-                                    bool disconnect)
-{
-  struct ssh_conn *sshc = &conn->proto.sshc;
-  CURLcode result = CURLE_OK;
-  struct Curl_easy *data = conn->data;
-
-  while((sshc->state != SSH_STOP) && !result) {
-    bool block;
-    timediff_t left = 1000;
-    struct curltime now = Curl_now();
-
-    result = ssh_statemach_act(conn, &block);
-    if(result)
-      break;
-
-    if(!disconnect) {
-      if(Curl_pgrsUpdate(conn))
-        return CURLE_ABORTED_BY_CALLBACK;
-
-      result = Curl_speedcheck(data, now);
-      if(result)
-        break;
-
-      left = Curl_timeleft(data, NULL, FALSE);
-      if(left < 0) {
-        failf(data, "Operation timed out");
-        return CURLE_OPERATION_TIMEDOUT;
-      }
-    }
-
-#ifdef HAVE_LIBSSH2_SESSION_BLOCK_DIRECTION
-    if(!result && block) {
-      int dir = libssh2_session_block_directions(sshc->ssh_session);
-      curl_socket_t sock = conn->sock[FIRSTSOCKET];
-      curl_socket_t fd_read = CURL_SOCKET_BAD;
-      curl_socket_t fd_write = CURL_SOCKET_BAD;
-      if(LIBSSH2_SESSION_BLOCK_INBOUND & dir)
-        fd_read = sock;
-      if(LIBSSH2_SESSION_BLOCK_OUTBOUND & dir)
-        fd_write = sock;
-      /* wait for the socket to become ready */
-      (void)Curl_socket_check(fd_read, CURL_SOCKET_BAD, fd_write,
-                              left>1000?1000:left); /* ignore result */
-    }
-#endif
-
-  }
-
-  return result;
-}
-
-/*
- * SSH setup and connection
- */
-static CURLcode ssh_setup_connection(struct connectdata *conn)
-{
-  struct SSHPROTO *ssh;
-
-  conn->data->req.protop = ssh = calloc(1, sizeof(struct SSHPROTO));
-  if(!ssh)
-    return CURLE_OUT_OF_MEMORY;
-
-  return CURLE_OK;
-}
-
-static Curl_recv scp_recv, sftp_recv;
-static Curl_send scp_send, sftp_send;
-
-/*
- * Curl_ssh_connect() gets called from Curl_protocol_connect() to allow us to
- * do protocol-specific actions at connect-time.
- */
-static CURLcode ssh_connect(struct connectdata *conn, bool *done)
-{
-#ifdef CURL_LIBSSH2_DEBUG
-  curl_socket_t sock;
-#endif
-  struct ssh_conn *ssh;
-  CURLcode result;
-  struct Curl_easy *data = conn->data;
-
-  /* initialize per-handle data if not already */
-  if(!data->req.protop)
-    ssh_setup_connection(conn);
-
-  /* We default to persistent connections. We set this already in this connect
-     function to make the re-use checks properly be able to check this bit. */
-  connkeep(conn, "SSH default");
-
-  if(conn->handler->protocol & CURLPROTO_SCP) {
-    conn->recv[FIRSTSOCKET] = scp_recv;
-    conn->send[FIRSTSOCKET] = scp_send;
-  }
-  else {
-    conn->recv[FIRSTSOCKET] = sftp_recv;
-    conn->send[FIRSTSOCKET] = sftp_send;
-  }
-  ssh = &conn->proto.sshc;
-
-#ifdef CURL_LIBSSH2_DEBUG
-  if(conn->user) {
-    infof(data, "User: %s\n", conn->user);
-  }
-  if(conn->passwd) {
-    infof(data, "Password: %s\n", conn->passwd);
-  }
-  sock = conn->sock[FIRSTSOCKET];
-#endif /* CURL_LIBSSH2_DEBUG */
-
-  ssh->ssh_session = libssh2_session_init_ex(my_libssh2_malloc,
-                                             my_libssh2_free,
-                                             my_libssh2_realloc, conn);
-  if(ssh->ssh_session == NULL) {
-    failf(data, "Failure initialising ssh session");
-    return CURLE_FAILED_INIT;
-  }
-
-  if(data->set.ssh_compression) {
-#if LIBSSH2_VERSION_NUM >= 0x010208
-    if(libssh2_session_flag(ssh->ssh_session, LIBSSH2_FLAG_COMPRESS, 1) < 0)
-#endif
-      infof(data, "Failed to enable compression for ssh session\n");
-  }
-
-#ifdef HAVE_LIBSSH2_KNOWNHOST_API
-  if(data->set.str[STRING_SSH_KNOWNHOSTS]) {
-    int rc;
-    ssh->kh = libssh2_knownhost_init(ssh->ssh_session);
-    if(!ssh->kh) {
-      libssh2_session_free(ssh->ssh_session);
-      return CURLE_FAILED_INIT;
-    }
-
-    /* read all known hosts from there */
-    rc = libssh2_knownhost_readfile(ssh->kh,
-                                    data->set.str[STRING_SSH_KNOWNHOSTS],
-                                    LIBSSH2_KNOWNHOST_FILE_OPENSSH);
-    if(rc < 0)
-      infof(data, "Failed to read known hosts from %s\n",
-            data->set.str[STRING_SSH_KNOWNHOSTS]);
-  }
-#endif /* HAVE_LIBSSH2_KNOWNHOST_API */
-
-#ifdef CURL_LIBSSH2_DEBUG
-  libssh2_trace(ssh->ssh_session, ~0);
-  infof(data, "SSH socket: %d\n", (int)sock);
-#endif /* CURL_LIBSSH2_DEBUG */
-
-  state(conn, SSH_INIT);
-
-  result = ssh_multi_statemach(conn, done);
-
-  return result;
-}
-
-/*
- ***********************************************************************
- *
- * scp_perform()
- *
- * This is the actual DO function for SCP. Get a file according to
- * the options previously setup.
- */
-
-static
-CURLcode scp_perform(struct connectdata *conn,
-                      bool *connected,
-                      bool *dophase_done)
-{
-  CURLcode result = CURLE_OK;
-
-  DEBUGF(infof(conn->data, "DO phase starts\n"));
-
-  *dophase_done = FALSE; /* not done yet */
-
-  /* start the first command in the DO phase */
-  state(conn, SSH_SCP_TRANS_INIT);
-
-  /* run the state-machine */
-  result = ssh_multi_statemach(conn, dophase_done);
-
-  *connected = conn->bits.tcpconnect[FIRSTSOCKET];
-
-  if(*dophase_done) {
-    DEBUGF(infof(conn->data, "DO phase is complete\n"));
-  }
-
-  return result;
-}
-
-/* called from multi.c while DOing */
-static CURLcode scp_doing(struct connectdata *conn,
-                               bool *dophase_done)
-{
-  CURLcode result;
-  result = ssh_multi_statemach(conn, dophase_done);
-
-  if(*dophase_done) {
-    DEBUGF(infof(conn->data, "DO phase is complete\n"));
-  }
-  return result;
-}
-
-/*
- * The DO function is generic for both protocols. There was previously two
- * separate ones but this way means less duplicated code.
- */
-
-static CURLcode ssh_do(struct connectdata *conn, bool *done)
-{
-  CURLcode result;
-  bool connected = 0;
-  struct Curl_easy *data = conn->data;
-  struct ssh_conn *sshc = &conn->proto.sshc;
-
-  *done = FALSE; /* default to false */
-
-  data->req.size = -1; /* make sure this is unknown at this point */
-
-  sshc->actualcode = CURLE_OK; /* reset error code */
-  sshc->secondCreateDirs = 0;   /* reset the create dir attempt state
-                                   variable */
-
-  Curl_pgrsSetUploadCounter(data, 0);
-  Curl_pgrsSetDownloadCounter(data, 0);
-  Curl_pgrsSetUploadSize(data, -1);
-  Curl_pgrsSetDownloadSize(data, -1);
-
-  if(conn->handler->protocol & CURLPROTO_SCP)
-    result = scp_perform(conn, &connected,  done);
-  else
-    result = sftp_perform(conn, &connected,  done);
-
-  return result;
-}
-
-/* BLOCKING, but the function is using the state machine so the only reason
-   this is still blocking is that the multi interface code has no support for
-   disconnecting operations that takes a while */
-static CURLcode scp_disconnect(struct connectdata *conn, bool dead_connection)
-{
-  CURLcode result = CURLE_OK;
-  struct ssh_conn *ssh = &conn->proto.sshc;
-  (void) dead_connection;
-
-  if(ssh->ssh_session) {
-    /* only if there's a session still around to use! */
-
-    state(conn, SSH_SESSION_DISCONNECT);
-
-    result = ssh_block_statemach(conn, TRUE);
-  }
-
-  return result;
-}
-
-/* generic done function for both SCP and SFTP called from their specific
-   done functions */
-static CURLcode ssh_done(struct connectdata *conn, CURLcode status)
-{
-  CURLcode result = CURLE_OK;
-  struct SSHPROTO *sftp_scp = conn->data->req.protop;
-
-  if(!status) {
-    /* run the state-machine */
-    result = ssh_block_statemach(conn, FALSE);
-  }
-  else
-    result = status;
-
-  if(sftp_scp)
-    Curl_safefree(sftp_scp->path);
-  if(Curl_pgrsDone(conn))
-    return CURLE_ABORTED_BY_CALLBACK;
-
-  conn->data->req.keepon = 0; /* clear all bits */
-  return result;
-}
-
-
-static CURLcode scp_done(struct connectdata *conn, CURLcode status,
-                         bool premature)
-{
-  (void)premature; /* not used */
-
-  if(!status)
-    state(conn, SSH_SCP_DONE);
-
-  return ssh_done(conn, status);
-
-}
-
-static ssize_t scp_send(struct connectdata *conn, int sockindex,
-                        const void *mem, size_t len, CURLcode *err)
-{
-  ssize_t nwrite;
-  (void)sockindex; /* we only support SCP on the fixed known primary socket */
-
-  /* libssh2_channel_write() returns int! */
-  nwrite = (ssize_t)
-    libssh2_channel_write(conn->proto.sshc.ssh_channel, mem, len);
-
-  ssh_block2waitfor(conn, (nwrite == LIBSSH2_ERROR_EAGAIN)?TRUE:FALSE);
-
-  if(nwrite == LIBSSH2_ERROR_EAGAIN) {
-    *err = CURLE_AGAIN;
-    nwrite = 0;
-  }
-  else if(nwrite < LIBSSH2_ERROR_NONE) {
-    *err = libssh2_session_error_to_CURLE((int)nwrite);
-    nwrite = -1;
-  }
-
-  return nwrite;
-}
-
-static ssize_t scp_recv(struct connectdata *conn, int sockindex,
-                        char *mem, size_t len, CURLcode *err)
-{
-  ssize_t nread;
-  (void)sockindex; /* we only support SCP on the fixed known primary socket */
-
-  /* libssh2_channel_read() returns int */
-  nread = (ssize_t)
-    libssh2_channel_read(conn->proto.sshc.ssh_channel, mem, len);
-
-  ssh_block2waitfor(conn, (nread == LIBSSH2_ERROR_EAGAIN)?TRUE:FALSE);
-  if(nread == LIBSSH2_ERROR_EAGAIN) {
-    *err = CURLE_AGAIN;
-    nread = -1;
-  }
-
-  return nread;
-}
-
-/*
- * =============== SFTP ===============
- */
-
-/*
- ***********************************************************************
- *
- * sftp_perform()
- *
- * This is the actual DO function for SFTP. Get a file/directory according to
- * the options previously setup.
- */
-
-static
-CURLcode sftp_perform(struct connectdata *conn,
-                      bool *connected,
-                      bool *dophase_done)
-{
-  CURLcode result = CURLE_OK;
-
-  DEBUGF(infof(conn->data, "DO phase starts\n"));
-
-  *dophase_done = FALSE; /* not done yet */
-
-  /* start the first command in the DO phase */
-  state(conn, SSH_SFTP_QUOTE_INIT);
-
-  /* run the state-machine */
-  result = ssh_multi_statemach(conn, dophase_done);
-
-  *connected = conn->bits.tcpconnect[FIRSTSOCKET];
-
-  if(*dophase_done) {
-    DEBUGF(infof(conn->data, "DO phase is complete\n"));
-  }
-
-  return result;
-}
-
-/* called from multi.c while DOing */
-static CURLcode sftp_doing(struct connectdata *conn,
-                           bool *dophase_done)
-{
-  CURLcode result = ssh_multi_statemach(conn, dophase_done);
-
-  if(*dophase_done) {
-    DEBUGF(infof(conn->data, "DO phase is complete\n"));
-  }
-  return result;
-}
-
-/* BLOCKING, but the function is using the state machine so the only reason
-   this is still blocking is that the multi interface code has no support for
-   disconnecting operations that takes a while */
-static CURLcode sftp_disconnect(struct connectdata *conn, bool dead_connection)
-{
-  CURLcode result = CURLE_OK;
-  (void) dead_connection;
-
-  DEBUGF(infof(conn->data, "SSH DISCONNECT starts now\n"));
-
-  if(conn->proto.sshc.ssh_session) {
-    /* only if there's a session still around to use! */
-    state(conn, SSH_SFTP_SHUTDOWN);
-    result = ssh_block_statemach(conn, TRUE);
-  }
-
-  DEBUGF(infof(conn->data, "SSH DISCONNECT is done\n"));
-
-  return result;
-
-}
-
-static CURLcode sftp_done(struct connectdata *conn, CURLcode status,
-                               bool premature)
-{
-  struct ssh_conn *sshc = &conn->proto.sshc;
-
-  if(!status) {
-    /* Post quote commands are executed after the SFTP_CLOSE state to avoid
-       errors that could happen due to open file handles during POSTQUOTE
-       operation */
-    if(!premature && conn->data->set.postquote && !conn->bits.retry)
-      sshc->nextstate = SSH_SFTP_POSTQUOTE_INIT;
-    state(conn, SSH_SFTP_CLOSE);
-  }
-  return ssh_done(conn, status);
-}
-
-/* return number of sent bytes */
-static ssize_t sftp_send(struct connectdata *conn, int sockindex,
-                         const void *mem, size_t len, CURLcode *err)
-{
-  ssize_t nwrite;   /* libssh2_sftp_write() used to return size_t in 0.14
-                       but is changed to ssize_t in 0.15. These days we don't
-                       support libssh2 0.15*/
-  (void)sockindex;
-
-  nwrite = libssh2_sftp_write(conn->proto.sshc.sftp_handle, mem, len);
-
-  ssh_block2waitfor(conn, (nwrite == LIBSSH2_ERROR_EAGAIN)?TRUE:FALSE);
-
-  if(nwrite == LIBSSH2_ERROR_EAGAIN) {
-    *err = CURLE_AGAIN;
-    nwrite = 0;
-  }
-  else if(nwrite < LIBSSH2_ERROR_NONE) {
-    *err = libssh2_session_error_to_CURLE((int)nwrite);
-    nwrite = -1;
-  }
-
-  return nwrite;
-}
-
-/*
- * Return number of received (decrypted) bytes
- * or <0 on error
- */
-static ssize_t sftp_recv(struct connectdata *conn, int sockindex,
-                         char *mem, size_t len, CURLcode *err)
-{
-  ssize_t nread;
-  (void)sockindex;
-
-  nread = libssh2_sftp_read(conn->proto.sshc.sftp_handle, mem, len);
-
-  ssh_block2waitfor(conn, (nread == LIBSSH2_ERROR_EAGAIN)?TRUE:FALSE);
-
-  if(nread == LIBSSH2_ERROR_EAGAIN) {
-    *err = CURLE_AGAIN;
-    nread = -1;
-
-  }
-  else if(nread < 0) {
-    *err = libssh2_session_error_to_CURLE((int)nread);
-  }
-  return nread;
-}
-
-static const char *sftp_libssh2_strerror(int err)
-{
-  switch(err) {
-    case LIBSSH2_FX_NO_SUCH_FILE:
-      return "No such file or directory";
-
-    case LIBSSH2_FX_PERMISSION_DENIED:
-      return "Permission denied";
-
-    case LIBSSH2_FX_FAILURE:
-      return "Operation failed";
-
-    case LIBSSH2_FX_BAD_MESSAGE:
-      return "Bad message from SFTP server";
-
-    case LIBSSH2_FX_NO_CONNECTION:
-      return "Not connected to SFTP server";
-
-    case LIBSSH2_FX_CONNECTION_LOST:
-      return "Connection to SFTP server lost";
-
-    case LIBSSH2_FX_OP_UNSUPPORTED:
-      return "Operation not supported by SFTP server";
-
-    case LIBSSH2_FX_INVALID_HANDLE:
-      return "Invalid handle";
-
-    case LIBSSH2_FX_NO_SUCH_PATH:
-      return "No such file or directory";
-
-    case LIBSSH2_FX_FILE_ALREADY_EXISTS:
-      return "File already exists";
-
-    case LIBSSH2_FX_WRITE_PROTECT:
-      return "File is write protected";
-
-    case LIBSSH2_FX_NO_MEDIA:
-      return "No media";
-
-    case LIBSSH2_FX_NO_SPACE_ON_FILESYSTEM:
-      return "Disk full";
-
-    case LIBSSH2_FX_QUOTA_EXCEEDED:
-      return "User quota exceeded";
-
-    case LIBSSH2_FX_UNKNOWN_PRINCIPLE:
-      return "Unknown principle";
-
-    case LIBSSH2_FX_LOCK_CONFlICT:
-      return "File lock conflict";
-
-    case LIBSSH2_FX_DIR_NOT_EMPTY:
-      return "Directory not empty";
-
-    case LIBSSH2_FX_NOT_A_DIRECTORY:
-      return "Not a directory";
-
-    case LIBSSH2_FX_INVALID_FILENAME:
-      return "Invalid filename";
-
-    case LIBSSH2_FX_LINK_LOOP:
-      return "Link points to itself";
-  }
-  return "Unknown error in libssh2";
-}
-
-#endif /* USE_LIBSSH2 */
diff --git a/Utilities/cmcurl/lib/ssh.h b/Utilities/cmcurl/lib/ssh.h
deleted file mode 100644
index 0620aac..0000000
--- a/Utilities/cmcurl/lib/ssh.h
+++ /dev/null
@@ -1,245 +0,0 @@
-#ifndef HEADER_CURL_SSH_H
-#define HEADER_CURL_SSH_H
-/***************************************************************************
- *                                  _   _ ____  _
- *  Project                     ___| | | |  _ \| |
- *                             / __| | | | |_) | |
- *                            | (__| |_| |  _ <| |___
- *                             \___|\___/|_| \_\_____|
- *
- * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * This software is licensed as described in the file COPYING, which
- * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
- *
- * You may opt to use, copy, modify, merge, publish, distribute and/or sell
- * copies of the Software, and permit persons to whom the Software is
- * furnished to do so, under the terms of the COPYING file.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- ***************************************************************************/
-
-#include "curl_setup.h"
-
-#if defined(HAVE_LIBSSH2_H)
-#include <libssh2.h>
-#include <libssh2_sftp.h>
-#elif defined(HAVE_LIBSSH_LIBSSH_H)
-#include <libssh/libssh.h>
-#include <libssh/sftp.h>
-#endif /* HAVE_LIBSSH2_H */
-
-/****************************************************************************
- * SSH unique setup
- ***************************************************************************/
-typedef enum {
-  SSH_NO_STATE = -1,  /* Used for "nextState" so say there is none */
-  SSH_STOP = 0,       /* do nothing state, stops the state machine */
-
-  SSH_INIT,           /* First state in SSH-CONNECT */
-  SSH_S_STARTUP,      /* Session startup */
-  SSH_HOSTKEY,        /* verify hostkey */
-  SSH_AUTHLIST,
-  SSH_AUTH_PKEY_INIT,
-  SSH_AUTH_PKEY,
-  SSH_AUTH_PASS_INIT,
-  SSH_AUTH_PASS,
-  SSH_AUTH_AGENT_INIT, /* initialize then wait for connection to agent */
-  SSH_AUTH_AGENT_LIST, /* ask for list then wait for entire list to come */
-  SSH_AUTH_AGENT,      /* attempt one key at a time */
-  SSH_AUTH_HOST_INIT,
-  SSH_AUTH_HOST,
-  SSH_AUTH_KEY_INIT,
-  SSH_AUTH_KEY,
-  SSH_AUTH_GSSAPI,
-  SSH_AUTH_DONE,
-  SSH_SFTP_INIT,
-  SSH_SFTP_REALPATH,   /* Last state in SSH-CONNECT */
-
-  SSH_SFTP_QUOTE_INIT, /* First state in SFTP-DO */
-  SSH_SFTP_POSTQUOTE_INIT, /* (Possibly) First state in SFTP-DONE */
-  SSH_SFTP_QUOTE,
-  SSH_SFTP_NEXT_QUOTE,
-  SSH_SFTP_QUOTE_STAT,
-  SSH_SFTP_QUOTE_SETSTAT,
-  SSH_SFTP_QUOTE_SYMLINK,
-  SSH_SFTP_QUOTE_MKDIR,
-  SSH_SFTP_QUOTE_RENAME,
-  SSH_SFTP_QUOTE_RMDIR,
-  SSH_SFTP_QUOTE_UNLINK,
-  SSH_SFTP_QUOTE_STATVFS,
-  SSH_SFTP_GETINFO,
-  SSH_SFTP_FILETIME,
-  SSH_SFTP_TRANS_INIT,
-  SSH_SFTP_UPLOAD_INIT,
-  SSH_SFTP_CREATE_DIRS_INIT,
-  SSH_SFTP_CREATE_DIRS,
-  SSH_SFTP_CREATE_DIRS_MKDIR,
-  SSH_SFTP_READDIR_INIT,
-  SSH_SFTP_READDIR,
-  SSH_SFTP_READDIR_LINK,
-  SSH_SFTP_READDIR_BOTTOM,
-  SSH_SFTP_READDIR_DONE,
-  SSH_SFTP_DOWNLOAD_INIT,
-  SSH_SFTP_DOWNLOAD_STAT, /* Last state in SFTP-DO */
-  SSH_SFTP_CLOSE,    /* Last state in SFTP-DONE */
-  SSH_SFTP_SHUTDOWN, /* First state in SFTP-DISCONNECT */
-  SSH_SCP_TRANS_INIT, /* First state in SCP-DO */
-  SSH_SCP_UPLOAD_INIT,
-  SSH_SCP_DOWNLOAD_INIT,
-  SSH_SCP_DOWNLOAD,
-  SSH_SCP_DONE,
-  SSH_SCP_SEND_EOF,
-  SSH_SCP_WAIT_EOF,
-  SSH_SCP_WAIT_CLOSE,
-  SSH_SCP_CHANNEL_FREE,   /* Last state in SCP-DONE */
-  SSH_SESSION_DISCONNECT, /* First state in SCP-DISCONNECT */
-  SSH_SESSION_FREE,       /* Last state in SCP/SFTP-DISCONNECT */
-  SSH_QUIT,
-  SSH_LAST  /* never used */
-} sshstate;
-
-/* this struct is used in the HandleData struct which is part of the
-   Curl_easy, which means this is used on a per-easy handle basis.
-   Everything that is strictly related to a connection is banned from this
-   struct. */
-struct SSHPROTO {
-  char *path;                  /* the path we operate on */
-};
-
-/* ssh_conn is used for struct connection-oriented data in the connectdata
-   struct */
-struct ssh_conn {
-  const char *authlist;       /* List of auth. methods, managed by libssh2 */
-
-  /* common */
-  const char *passphrase;     /* pass-phrase to use */
-  char *rsa_pub;              /* path name */
-  char *rsa;                  /* path name */
-  bool authed;                /* the connection has been authenticated fine */
-  sshstate state;             /* always use ssh.c:state() to change state! */
-  sshstate nextstate;         /* the state to goto after stopping */
-  CURLcode actualcode;        /* the actual error code */
-  struct curl_slist *quote_item; /* for the quote option */
-  char *quote_path1;          /* two generic pointers for the QUOTE stuff */
-  char *quote_path2;
-
-  bool acceptfail;            /* used by the SFTP_QUOTE (continue if
-                                 quote command fails) */
-  char *homedir;              /* when doing SFTP we figure out home dir in the
-                                 connect phase */
-  size_t readdir_len, readdir_totalLen, readdir_currLen;
-  char *readdir_line;
-  char *readdir_linkPath;
-  /* end of READDIR stuff */
-
-  int secondCreateDirs;         /* counter use by the code to see if the
-                                   second attempt has been made to change
-                                   to/create a directory */
-  char *slash_pos;              /* used by the SFTP_CREATE_DIRS state */
-
-  int orig_waitfor;             /* default READ/WRITE bits wait for */
-
-#if defined(USE_LIBSSH)
-/* our variables */
-  unsigned kbd_state; /* 0 or 1 */
-  ssh_key privkey;
-  ssh_key pubkey;
-  int auth_methods;
-  ssh_session ssh_session;
-  ssh_scp scp_session;
-  sftp_session sftp_session;
-  sftp_file sftp_file;
-  sftp_dir sftp_dir;
-
-  unsigned sftp_recv_state; /* 0 or 1 */
-  int sftp_file_index; /* for async read */
-  sftp_attributes readdir_attrs; /* used by the SFTP readdir actions */
-  sftp_attributes readdir_link_attrs; /* used by the SFTP readdir actions */
-  sftp_attributes quote_attrs; /* used by the SFTP_QUOTE state */
-
-  const char *readdir_filename; /* points within readdir_attrs */
-  const char *readdir_longentry;
-  char *readdir_tmp;
-#elif defined(USE_LIBSSH2)
-  char *readdir_filename;
-  char *readdir_longentry;
-
-  LIBSSH2_SFTP_ATTRIBUTES quote_attrs; /* used by the SFTP_QUOTE state */
-
-  /* Here's a set of struct members used by the SFTP_READDIR state */
-  LIBSSH2_SFTP_ATTRIBUTES readdir_attrs;
-  LIBSSH2_SESSION *ssh_session; /* Secure Shell session */
-  LIBSSH2_CHANNEL *ssh_channel; /* Secure Shell channel handle */
-  LIBSSH2_SFTP *sftp_session;   /* SFTP handle */
-  LIBSSH2_SFTP_HANDLE *sftp_handle;
-
-#ifdef HAVE_LIBSSH2_AGENT_API
-  LIBSSH2_AGENT *ssh_agent;     /* proxy to ssh-agent/pageant */
-  struct libssh2_agent_publickey *sshagent_identity,
-                                 *sshagent_prev_identity;
-#endif
-
-  /* note that HAVE_LIBSSH2_KNOWNHOST_API is a define set in the libssh2.h
-     header */
-#ifdef HAVE_LIBSSH2_KNOWNHOST_API
-  LIBSSH2_KNOWNHOSTS *kh;
-#endif
-#endif /* USE_LIBSSH */
-};
-
-#if defined(USE_LIBSSH)
-
-#define CURL_LIBSSH_VERSION ssh_version(0)
-
-extern const struct Curl_handler Curl_handler_scp;
-extern const struct Curl_handler Curl_handler_sftp;
-
-#elif defined(USE_LIBSSH2)
-
-/* Feature detection based on version numbers to better work with
-   non-configure platforms */
-
-#if !defined(LIBSSH2_VERSION_NUM) || (LIBSSH2_VERSION_NUM < 0x001000)
-#  error "SCP/SFTP protocols require libssh2 0.16 or later"
-#endif
-
-#if LIBSSH2_VERSION_NUM >= 0x010000
-#define HAVE_LIBSSH2_SFTP_SEEK64 1
-#endif
-
-#if LIBSSH2_VERSION_NUM >= 0x010100
-#define HAVE_LIBSSH2_VERSION 1
-#endif
-
-#if LIBSSH2_VERSION_NUM >= 0x010205
-#define HAVE_LIBSSH2_INIT 1
-#define HAVE_LIBSSH2_EXIT 1
-#endif
-
-#if LIBSSH2_VERSION_NUM >= 0x010206
-#define HAVE_LIBSSH2_KNOWNHOST_CHECKP 1
-#define HAVE_LIBSSH2_SCP_SEND64 1
-#endif
-
-#if LIBSSH2_VERSION_NUM >= 0x010208
-#define HAVE_LIBSSH2_SESSION_HANDSHAKE 1
-#endif
-
-#ifdef HAVE_LIBSSH2_VERSION
-/* get it run-time if possible */
-#define CURL_LIBSSH2_VERSION libssh2_version(0)
-#else
-/* use build-time if run-time not possible */
-#define CURL_LIBSSH2_VERSION LIBSSH2_VERSION
-#endif
-
-extern const struct Curl_handler Curl_handler_scp;
-extern const struct Curl_handler Curl_handler_sftp;
-
-#endif /* USE_LIBSSH2 */
-
-#endif /* HEADER_CURL_SSH_H */
diff --git a/Utilities/cmcurl/lib/strcase.c b/Utilities/cmcurl/lib/strcase.c
index 24bcca9..a309e35 100644
--- a/Utilities/cmcurl/lib/strcase.c
+++ b/Utilities/cmcurl/lib/strcase.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -26,6 +26,8 @@
 
 #include "strcase.h"
 
+static char raw_tolower(char in);
+
 /* Portable, consistent toupper (remember EBCDIC). Do not use toupper() because
    its behavior is altered by the current locale. */
 char Curl_raw_toupper(char in)
@@ -93,6 +95,75 @@
   return in;
 }
 
+
+/* Portable, consistent tolower (remember EBCDIC). Do not use tolower() because
+   its behavior is altered by the current locale. */
+static char raw_tolower(char in)
+{
+#if !defined(CURL_DOES_CONVERSIONS)
+  if(in >= 'A' && in <= 'Z')
+    return (char)('a' + in - 'A');
+#else
+  switch(in) {
+  case 'A':
+    return 'a';
+  case 'B':
+    return 'b';
+  case 'C':
+    return 'c';
+  case 'D':
+    return 'd';
+  case 'E':
+    return 'e';
+  case 'F':
+    return 'f';
+  case 'G':
+    return 'g';
+  case 'H':
+    return 'h';
+  case 'I':
+    return 'i';
+  case 'J':
+    return 'j';
+  case 'K':
+    return 'k';
+  case 'L':
+    return 'l';
+  case 'M':
+    return 'm';
+  case 'N':
+    return 'n';
+  case 'O':
+    return 'o';
+  case 'P':
+    return 'p';
+  case 'Q':
+    return 'q';
+  case 'R':
+    return 'r';
+  case 'S':
+    return 's';
+  case 'T':
+    return 't';
+  case 'U':
+    return 'u';
+  case 'V':
+    return 'v';
+  case 'W':
+    return 'w';
+  case 'X':
+    return 'x';
+  case 'Y':
+    return 'y';
+  case 'Z':
+    return 'z';
+  }
+#endif
+
+  return in;
+}
+
+
 /*
  * Curl_strcasecompare() is for doing "raw" case insensitive strings. This is
  * meant to be locale independent and only compare strings we know are safe
@@ -165,6 +236,21 @@
   } while(*src++ && --n);
 }
 
+/* Copy a lower case version of the string from src to dest.  The
+ * strings may overlap.  No more than n characters of the string are copied
+ * (including any NUL) and the destination string will NOT be
+ * NUL-terminated if that limit is reached.
+ */
+void Curl_strntolower(char *dest, const char *src, size_t n)
+{
+  if(n < 1)
+    return;
+
+  do {
+    *dest++ = raw_tolower(*src);
+  } while(*src++ && --n);
+}
+
 /* --- public functions --- */
 
 int curl_strequal(const char *first, const char *second)
diff --git a/Utilities/cmcurl/lib/strcase.h b/Utilities/cmcurl/lib/strcase.h
index 6fee384..cd4c419 100644
--- a/Utilities/cmcurl/lib/strcase.h
+++ b/Utilities/cmcurl/lib/strcase.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -46,5 +46,6 @@
 #define checkprefix(a,b)    curl_strnequal(a,b,strlen(a))
 
 void Curl_strntoupper(char *dest, const char *src, size_t n);
+void Curl_strntolower(char *dest, const char *src, size_t n);
 
 #endif /* HEADER_CURL_STRCASE_H */
diff --git a/Utilities/cmcurl/lib/strdup.c b/Utilities/cmcurl/lib/strdup.c
index 51e7978..1ab10fd 100644
--- a/Utilities/cmcurl/lib/strdup.c
+++ b/Utilities/cmcurl/lib/strdup.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
diff --git a/Utilities/cmcurl/lib/strerror.c b/Utilities/cmcurl/lib/strerror.c
index e273f37..015e588 100644
--- a/Utilities/cmcurl/lib/strerror.c
+++ b/Utilities/cmcurl/lib/strerror.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 2004 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 2004 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -311,6 +311,15 @@
   case CURLE_RECURSIVE_API_CALL:
     return "API function called from within callback";
 
+  case CURLE_AUTH_ERROR:
+    return "An authentication function returned an error";
+
+  case CURLE_HTTP3:
+    return "HTTP/3 error";
+
+  case CURLE_QUIC_CONNECT_ERROR:
+    return "QUIC connection error";
+
     /* error codes not used by current libcurl */
   case CURLE_OBSOLETE20:
   case CURLE_OBSOLETE24:
@@ -383,6 +392,12 @@
   case CURLM_RECURSIVE_API_CALL:
     return "API function called from within callback";
 
+  case CURLM_WAKEUP_FAILURE:
+    return "Wakeup is unavailable or failed";
+
+  case CURLM_BAD_FUNCTION_ARGUMENT:
+    return "A libcurl function was given a bad argument";
+
   case CURLM_LAST:
     break;
   }
@@ -433,19 +448,26 @@
 }
 
 #ifdef USE_WINSOCK
-
-/* This function handles most / all (?) Winsock errors curl is able to produce.
+/* This is a helper function for Curl_strerror that converts Winsock error
+ * codes (WSAGetLastError) to error messages.
+ * Returns NULL if no error message was found for error code.
  */
 static const char *
 get_winsock_error (int err, char *buf, size_t len)
 {
-#ifdef PRESERVE_WINDOWS_ERROR_CODE
-  DWORD old_win_err = GetLastError();
-#endif
-  int old_errno = errno;
-  const char *p;
-
 #ifndef CURL_DISABLE_VERBOSE_STRINGS
+  const char *p;
+#endif
+
+  if(!len)
+    return NULL;
+
+  *buf = '\0';
+
+#ifdef CURL_DISABLE_VERBOSE_STRINGS
+  (void)err;
+  return NULL;
+#else
   switch(err) {
   case WSAEINTR:
     p = "Call interrupted";
@@ -614,27 +636,64 @@
   default:
     return NULL;
   }
-#else
-  if(!err)
-    return NULL;
-  else
-    p = "error";
-#endif
   strncpy(buf, p, len);
   buf [len-1] = '\0';
-
-  if(errno != old_errno)
-    errno = old_errno;
-
-#ifdef PRESERVE_WINDOWS_ERROR_CODE
-  if(old_win_err != GetLastError())
-    SetLastError(old_win_err);
-#endif
-
   return buf;
+#endif
 }
 #endif   /* USE_WINSOCK */
 
+#if defined(WIN32) || defined(_WIN32_WCE)
+/* This is a helper function for Curl_strerror that converts Windows API error
+ * codes (GetLastError) to error messages.
+ * Returns NULL if no error message was found for error code.
+ */
+static const char *
+get_winapi_error(int err, char *buf, size_t buflen)
+{
+  char *p;
+
+  if(!buflen)
+    return NULL;
+
+  *buf = '\0';
+
+#ifdef _WIN32_WCE
+  {
+    wchar_t wbuf[256];
+    wbuf[0] = L'\0';
+
+    if(FormatMessage((FORMAT_MESSAGE_FROM_SYSTEM |
+                      FORMAT_MESSAGE_IGNORE_INSERTS), NULL, err,
+                     LANG_NEUTRAL, wbuf, sizeof(wbuf)/sizeof(wchar_t), NULL)) {
+      size_t written = wcstombs(buf, wbuf, buflen - 1);
+      if(written != (size_t)-1)
+        buf[written] = '\0';
+      else
+        *buf = '\0';
+    }
+  }
+#else
+  if(!FormatMessageA((FORMAT_MESSAGE_FROM_SYSTEM |
+                      FORMAT_MESSAGE_IGNORE_INSERTS), NULL, err,
+                     LANG_NEUTRAL, buf, (DWORD)buflen, NULL)) {
+    *buf = '\0';
+  }
+#endif
+
+  /* Truncate multiple lines */
+  p = strchr(buf, '\n');
+  if(p) {
+    if(p > buf && *(p-1) == '\r')
+      *(p-1) = '\0';
+    else
+      *p = '\0';
+  }
+
+  return (*buf ? buf : NULL);
+}
+#endif /* WIN32 || _WIN32_WCE */
+
 /*
  * Our thread-safe and smart strerror() replacement.
  *
@@ -645,6 +704,14 @@
  *
  * We don't do range checking (on systems other than Windows) since there is
  * no good reliable and portable way to do it.
+ *
+ * On Windows different types of error codes overlap. This function has an
+ * order of preference when trying to match error codes:
+ * CRT (errno), Winsock (WSAGetLastError), Windows API (GetLastError).
+ *
+ * It may be more correct to call one of the variant functions instead:
+ * Call Curl_sspi_strerror if the error code is definitely Windows SSPI.
+ * Call Curl_winapi_strerror if the error code is definitely Windows API.
  */
 const char *Curl_strerror(int err, char *buf, size_t buflen)
 {
@@ -655,35 +722,30 @@
   char *p;
   size_t max;
 
+  if(!buflen)
+    return NULL;
+
   DEBUGASSERT(err >= 0);
 
   max = buflen - 1;
   *buf = '\0';
 
-#ifdef USE_WINSOCK
-
-#ifdef _WIN32_WCE
-  {
-    wchar_t wbuf[256];
-    wbuf[0] = L'\0';
-
-    FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, err,
-                  LANG_NEUTRAL, wbuf, sizeof(wbuf)/sizeof(wchar_t), NULL);
-    wcstombs(buf, wbuf, max);
-  }
-#else
+#if defined(WIN32) || defined(_WIN32_WCE)
+#if defined(WIN32)
   /* 'sys_nerr' is the maximum errno number, it is not widely portable */
   if(err >= 0 && err < sys_nerr)
     strncpy(buf, strerror(err), max);
-  else {
-    if(!get_winsock_error(err, buf, max) &&
-       !FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM, NULL, err,
-                       LANG_NEUTRAL, buf, (DWORD)max, NULL))
+  else
+#endif
+  {
+    if(
+#ifdef USE_WINSOCK
+       !get_winsock_error(err, buf, max) &&
+#endif
+       !get_winapi_error((DWORD)err, buf, max))
       msnprintf(buf, max, "Unknown error %d (%#x)", err, err);
   }
-#endif
-
-#else /* not USE_WINSOCK coming up */
+#else /* not Windows coming up */
 
 #if defined(HAVE_STRERROR_R) && defined(HAVE_POSIX_STRERROR_R)
  /*
@@ -731,9 +793,9 @@
   }
 #endif
 
-#endif /* end of ! USE_WINSOCK */
+#endif /* end of not Windows */
 
-  buf[max] = '\0'; /* make sure the string is zero terminated */
+  buf[max] = '\0'; /* make sure the string is null-terminated */
 
   /* strip trailing '\r\n' or '\n'. */
   p = strrchr(buf, '\n');
@@ -754,341 +816,35 @@
   return buf;
 }
 
-#ifdef USE_WINDOWS_SSPI
-const char *Curl_sspi_strerror(int err, char *buf, size_t buflen)
+/*
+ * Curl_winapi_strerror:
+ * Variant of Curl_strerror if the error code is definitely Windows API.
+ */
+#if defined(WIN32) || defined(_WIN32_WCE)
+const char *Curl_winapi_strerror(DWORD err, char *buf, size_t buflen)
 {
 #ifdef PRESERVE_WINDOWS_ERROR_CODE
   DWORD old_win_err = GetLastError();
 #endif
   int old_errno = errno;
-  const char *txt;
-  char *outbuf;
-  size_t outmax;
-#ifndef CURL_DISABLE_VERBOSE_STRINGS
-  char txtbuf[80];
-  char msgbuf[256];
-  char *p, *str, *msg = NULL;
-  bool msg_formatted = FALSE;
-#endif
 
-  outbuf = buf;
-  outmax = buflen - 1;
-  *outbuf = '\0';
+  if(!buflen)
+    return NULL;
+
+  *buf = '\0';
 
 #ifndef CURL_DISABLE_VERBOSE_STRINGS
-
-  switch(err) {
-    case SEC_E_OK:
-      txt = "No error";
-      break;
-    case CRYPT_E_REVOKED:
-      txt = "CRYPT_E_REVOKED";
-      break;
-    case SEC_E_ALGORITHM_MISMATCH:
-      txt = "SEC_E_ALGORITHM_MISMATCH";
-      break;
-    case SEC_E_BAD_BINDINGS:
-      txt = "SEC_E_BAD_BINDINGS";
-      break;
-    case SEC_E_BAD_PKGID:
-      txt = "SEC_E_BAD_PKGID";
-      break;
-    case SEC_E_BUFFER_TOO_SMALL:
-      txt = "SEC_E_BUFFER_TOO_SMALL";
-      break;
-    case SEC_E_CANNOT_INSTALL:
-      txt = "SEC_E_CANNOT_INSTALL";
-      break;
-    case SEC_E_CANNOT_PACK:
-      txt = "SEC_E_CANNOT_PACK";
-      break;
-    case SEC_E_CERT_EXPIRED:
-      txt = "SEC_E_CERT_EXPIRED";
-      break;
-    case SEC_E_CERT_UNKNOWN:
-      txt = "SEC_E_CERT_UNKNOWN";
-      break;
-    case SEC_E_CERT_WRONG_USAGE:
-      txt = "SEC_E_CERT_WRONG_USAGE";
-      break;
-    case SEC_E_CONTEXT_EXPIRED:
-      txt = "SEC_E_CONTEXT_EXPIRED";
-      break;
-    case SEC_E_CROSSREALM_DELEGATION_FAILURE:
-      txt = "SEC_E_CROSSREALM_DELEGATION_FAILURE";
-      break;
-    case SEC_E_CRYPTO_SYSTEM_INVALID:
-      txt = "SEC_E_CRYPTO_SYSTEM_INVALID";
-      break;
-    case SEC_E_DECRYPT_FAILURE:
-      txt = "SEC_E_DECRYPT_FAILURE";
-      break;
-    case SEC_E_DELEGATION_POLICY:
-      txt = "SEC_E_DELEGATION_POLICY";
-      break;
-    case SEC_E_DELEGATION_REQUIRED:
-      txt = "SEC_E_DELEGATION_REQUIRED";
-      break;
-    case SEC_E_DOWNGRADE_DETECTED:
-      txt = "SEC_E_DOWNGRADE_DETECTED";
-      break;
-    case SEC_E_ENCRYPT_FAILURE:
-      txt = "SEC_E_ENCRYPT_FAILURE";
-      break;
-    case SEC_E_ILLEGAL_MESSAGE:
-      txt = "SEC_E_ILLEGAL_MESSAGE";
-      break;
-    case SEC_E_INCOMPLETE_CREDENTIALS:
-      txt = "SEC_E_INCOMPLETE_CREDENTIALS";
-      break;
-    case SEC_E_INCOMPLETE_MESSAGE:
-      txt = "SEC_E_INCOMPLETE_MESSAGE";
-      break;
-    case SEC_E_INSUFFICIENT_MEMORY:
-      txt = "SEC_E_INSUFFICIENT_MEMORY";
-      break;
-    case SEC_E_INTERNAL_ERROR:
-      txt = "SEC_E_INTERNAL_ERROR";
-      break;
-    case SEC_E_INVALID_HANDLE:
-      txt = "SEC_E_INVALID_HANDLE";
-      break;
-    case SEC_E_INVALID_PARAMETER:
-      txt = "SEC_E_INVALID_PARAMETER";
-      break;
-    case SEC_E_INVALID_TOKEN:
-      txt = "SEC_E_INVALID_TOKEN";
-      break;
-    case SEC_E_ISSUING_CA_UNTRUSTED:
-      txt = "SEC_E_ISSUING_CA_UNTRUSTED";
-      break;
-    case SEC_E_ISSUING_CA_UNTRUSTED_KDC:
-      txt = "SEC_E_ISSUING_CA_UNTRUSTED_KDC";
-      break;
-    case SEC_E_KDC_CERT_EXPIRED:
-      txt = "SEC_E_KDC_CERT_EXPIRED";
-      break;
-    case SEC_E_KDC_CERT_REVOKED:
-      txt = "SEC_E_KDC_CERT_REVOKED";
-      break;
-    case SEC_E_KDC_INVALID_REQUEST:
-      txt = "SEC_E_KDC_INVALID_REQUEST";
-      break;
-    case SEC_E_KDC_UNABLE_TO_REFER:
-      txt = "SEC_E_KDC_UNABLE_TO_REFER";
-      break;
-    case SEC_E_KDC_UNKNOWN_ETYPE:
-      txt = "SEC_E_KDC_UNKNOWN_ETYPE";
-      break;
-    case SEC_E_LOGON_DENIED:
-      txt = "SEC_E_LOGON_DENIED";
-      break;
-    case SEC_E_MAX_REFERRALS_EXCEEDED:
-      txt = "SEC_E_MAX_REFERRALS_EXCEEDED";
-      break;
-    case SEC_E_MESSAGE_ALTERED:
-      txt = "SEC_E_MESSAGE_ALTERED";
-      break;
-    case SEC_E_MULTIPLE_ACCOUNTS:
-      txt = "SEC_E_MULTIPLE_ACCOUNTS";
-      break;
-    case SEC_E_MUST_BE_KDC:
-      txt = "SEC_E_MUST_BE_KDC";
-      break;
-    case SEC_E_NOT_OWNER:
-      txt = "SEC_E_NOT_OWNER";
-      break;
-    case SEC_E_NO_AUTHENTICATING_AUTHORITY:
-      txt = "SEC_E_NO_AUTHENTICATING_AUTHORITY";
-      break;
-    case SEC_E_NO_CREDENTIALS:
-      txt = "SEC_E_NO_CREDENTIALS";
-      break;
-    case SEC_E_NO_IMPERSONATION:
-      txt = "SEC_E_NO_IMPERSONATION";
-      break;
-    case SEC_E_NO_IP_ADDRESSES:
-      txt = "SEC_E_NO_IP_ADDRESSES";
-      break;
-    case SEC_E_NO_KERB_KEY:
-      txt = "SEC_E_NO_KERB_KEY";
-      break;
-    case SEC_E_NO_PA_DATA:
-      txt = "SEC_E_NO_PA_DATA";
-      break;
-    case SEC_E_NO_S4U_PROT_SUPPORT:
-      txt = "SEC_E_NO_S4U_PROT_SUPPORT";
-      break;
-    case SEC_E_NO_TGT_REPLY:
-      txt = "SEC_E_NO_TGT_REPLY";
-      break;
-    case SEC_E_OUT_OF_SEQUENCE:
-      txt = "SEC_E_OUT_OF_SEQUENCE";
-      break;
-    case SEC_E_PKINIT_CLIENT_FAILURE:
-      txt = "SEC_E_PKINIT_CLIENT_FAILURE";
-      break;
-    case SEC_E_PKINIT_NAME_MISMATCH:
-      txt = "SEC_E_PKINIT_NAME_MISMATCH";
-      break;
-    case SEC_E_POLICY_NLTM_ONLY:
-      txt = "SEC_E_POLICY_NLTM_ONLY";
-      break;
-    case SEC_E_QOP_NOT_SUPPORTED:
-      txt = "SEC_E_QOP_NOT_SUPPORTED";
-      break;
-    case SEC_E_REVOCATION_OFFLINE_C:
-      txt = "SEC_E_REVOCATION_OFFLINE_C";
-      break;
-    case SEC_E_REVOCATION_OFFLINE_KDC:
-      txt = "SEC_E_REVOCATION_OFFLINE_KDC";
-      break;
-    case SEC_E_SECPKG_NOT_FOUND:
-      txt = "SEC_E_SECPKG_NOT_FOUND";
-      break;
-    case SEC_E_SECURITY_QOS_FAILED:
-      txt = "SEC_E_SECURITY_QOS_FAILED";
-      break;
-    case SEC_E_SHUTDOWN_IN_PROGRESS:
-      txt = "SEC_E_SHUTDOWN_IN_PROGRESS";
-      break;
-    case SEC_E_SMARTCARD_CERT_EXPIRED:
-      txt = "SEC_E_SMARTCARD_CERT_EXPIRED";
-      break;
-    case SEC_E_SMARTCARD_CERT_REVOKED:
-      txt = "SEC_E_SMARTCARD_CERT_REVOKED";
-      break;
-    case SEC_E_SMARTCARD_LOGON_REQUIRED:
-      txt = "SEC_E_SMARTCARD_LOGON_REQUIRED";
-      break;
-    case SEC_E_STRONG_CRYPTO_NOT_SUPPORTED:
-      txt = "SEC_E_STRONG_CRYPTO_NOT_SUPPORTED";
-      break;
-    case SEC_E_TARGET_UNKNOWN:
-      txt = "SEC_E_TARGET_UNKNOWN";
-      break;
-    case SEC_E_TIME_SKEW:
-      txt = "SEC_E_TIME_SKEW";
-      break;
-    case SEC_E_TOO_MANY_PRINCIPALS:
-      txt = "SEC_E_TOO_MANY_PRINCIPALS";
-      break;
-    case SEC_E_UNFINISHED_CONTEXT_DELETED:
-      txt = "SEC_E_UNFINISHED_CONTEXT_DELETED";
-      break;
-    case SEC_E_UNKNOWN_CREDENTIALS:
-      txt = "SEC_E_UNKNOWN_CREDENTIALS";
-      break;
-    case SEC_E_UNSUPPORTED_FUNCTION:
-      txt = "SEC_E_UNSUPPORTED_FUNCTION";
-      break;
-    case SEC_E_UNSUPPORTED_PREAUTH:
-      txt = "SEC_E_UNSUPPORTED_PREAUTH";
-      break;
-    case SEC_E_UNTRUSTED_ROOT:
-      txt = "SEC_E_UNTRUSTED_ROOT";
-      break;
-    case SEC_E_WRONG_CREDENTIAL_HANDLE:
-      txt = "SEC_E_WRONG_CREDENTIAL_HANDLE";
-      break;
-    case SEC_E_WRONG_PRINCIPAL:
-      txt = "SEC_E_WRONG_PRINCIPAL";
-      break;
-    case SEC_I_COMPLETE_AND_CONTINUE:
-      txt = "SEC_I_COMPLETE_AND_CONTINUE";
-      break;
-    case SEC_I_COMPLETE_NEEDED:
-      txt = "SEC_I_COMPLETE_NEEDED";
-      break;
-    case SEC_I_CONTEXT_EXPIRED:
-      txt = "SEC_I_CONTEXT_EXPIRED";
-      break;
-    case SEC_I_CONTINUE_NEEDED:
-      txt = "SEC_I_CONTINUE_NEEDED";
-      break;
-    case SEC_I_INCOMPLETE_CREDENTIALS:
-      txt = "SEC_I_INCOMPLETE_CREDENTIALS";
-      break;
-    case SEC_I_LOCAL_LOGON:
-      txt = "SEC_I_LOCAL_LOGON";
-      break;
-    case SEC_I_NO_LSA_CONTEXT:
-      txt = "SEC_I_NO_LSA_CONTEXT";
-      break;
-    case SEC_I_RENEGOTIATE:
-      txt = "SEC_I_RENEGOTIATE";
-      break;
-    case SEC_I_SIGNATURE_NEEDED:
-      txt = "SEC_I_SIGNATURE_NEEDED";
-      break;
-    default:
-      txt = "Unknown error";
+  if(!get_winapi_error(err, buf, buflen)) {
+    msnprintf(buf, buflen, "Unknown error %u (0x%08X)", err, err);
   }
-
-  if(err == SEC_E_OK)
-    strncpy(outbuf, txt, outmax);
-  else if(err == SEC_E_ILLEGAL_MESSAGE)
-    msnprintf(outbuf, outmax,
-              "SEC_E_ILLEGAL_MESSAGE (0x%08X) - This error usually occurs "
-              "when a fatal SSL/TLS alert is received (e.g. handshake failed)."
-              " More detail may be available in the Windows System event log.",
-              err);
-  else {
-    str = txtbuf;
-    msnprintf(txtbuf, sizeof(txtbuf), "%s (0x%08X)", txt, err);
-    txtbuf[sizeof(txtbuf)-1] = '\0';
-
-#ifdef _WIN32_WCE
-    {
-      wchar_t wbuf[256];
-      wbuf[0] = L'\0';
-
-      if(FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM |
-                       FORMAT_MESSAGE_IGNORE_INSERTS,
-                       NULL, err, LANG_NEUTRAL,
-                       wbuf, sizeof(wbuf)/sizeof(wchar_t), NULL)) {
-        wcstombs(msgbuf, wbuf, sizeof(msgbuf)-1);
-        msg_formatted = TRUE;
-      }
-    }
 #else
-    if(FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM |
-                      FORMAT_MESSAGE_IGNORE_INSERTS,
-                      NULL, err, LANG_NEUTRAL,
-                      msgbuf, sizeof(msgbuf)-1, NULL)) {
-      msg_formatted = TRUE;
-    }
-#endif
-    if(msg_formatted) {
-      msgbuf[sizeof(msgbuf)-1] = '\0';
-      /* strip trailing '\r\n' or '\n' */
-      p = strrchr(msgbuf, '\n');
-      if(p && (p - msgbuf) >= 2)
-        *p = '\0';
-      p = strrchr(msgbuf, '\r');
-      if(p && (p - msgbuf) >= 1)
-        *p = '\0';
-      msg = msgbuf;
-    }
-    if(msg)
-      msnprintf(outbuf, outmax, "%s - %s", str, msg);
-    else
-      strncpy(outbuf, str, outmax);
+  {
+    const char *txt = (err == ERROR_SUCCESS) ? "No error" : "Error";
+    strncpy(buf, txt, buflen);
+    buf[buflen - 1] = '\0';
   }
-
-#else
-
-  if(err == SEC_E_OK)
-    txt = "No error";
-  else
-    txt = "Error";
-
-  strncpy(outbuf, txt, outmax);
-
 #endif
 
-  outbuf[outmax] = '\0';
-
   if(errno != old_errno)
     errno = old_errno;
 
@@ -1097,6 +853,157 @@
     SetLastError(old_win_err);
 #endif
 
-  return outbuf;
+  return buf;
+}
+#endif /* WIN32 || _WIN32_WCE */
+
+#ifdef USE_WINDOWS_SSPI
+/*
+ * Curl_sspi_strerror:
+ * Variant of Curl_strerror if the error code is definitely Windows SSPI.
+ */
+const char *Curl_sspi_strerror(int err, char *buf, size_t buflen)
+{
+#ifdef PRESERVE_WINDOWS_ERROR_CODE
+  DWORD old_win_err = GetLastError();
+#endif
+  int old_errno = errno;
+  const char *txt;
+
+  if(!buflen)
+    return NULL;
+
+  *buf = '\0';
+
+#ifndef CURL_DISABLE_VERBOSE_STRINGS
+
+  switch(err) {
+    case SEC_E_OK:
+      txt = "No error";
+      break;
+#define SEC2TXT(sec) case sec: txt = #sec; break
+    SEC2TXT(CRYPT_E_REVOKED);
+    SEC2TXT(SEC_E_ALGORITHM_MISMATCH);
+    SEC2TXT(SEC_E_BAD_BINDINGS);
+    SEC2TXT(SEC_E_BAD_PKGID);
+    SEC2TXT(SEC_E_BUFFER_TOO_SMALL);
+    SEC2TXT(SEC_E_CANNOT_INSTALL);
+    SEC2TXT(SEC_E_CANNOT_PACK);
+    SEC2TXT(SEC_E_CERT_EXPIRED);
+    SEC2TXT(SEC_E_CERT_UNKNOWN);
+    SEC2TXT(SEC_E_CERT_WRONG_USAGE);
+    SEC2TXT(SEC_E_CONTEXT_EXPIRED);
+    SEC2TXT(SEC_E_CROSSREALM_DELEGATION_FAILURE);
+    SEC2TXT(SEC_E_CRYPTO_SYSTEM_INVALID);
+    SEC2TXT(SEC_E_DECRYPT_FAILURE);
+    SEC2TXT(SEC_E_DELEGATION_POLICY);
+    SEC2TXT(SEC_E_DELEGATION_REQUIRED);
+    SEC2TXT(SEC_E_DOWNGRADE_DETECTED);
+    SEC2TXT(SEC_E_ENCRYPT_FAILURE);
+    SEC2TXT(SEC_E_ILLEGAL_MESSAGE);
+    SEC2TXT(SEC_E_INCOMPLETE_CREDENTIALS);
+    SEC2TXT(SEC_E_INCOMPLETE_MESSAGE);
+    SEC2TXT(SEC_E_INSUFFICIENT_MEMORY);
+    SEC2TXT(SEC_E_INTERNAL_ERROR);
+    SEC2TXT(SEC_E_INVALID_HANDLE);
+    SEC2TXT(SEC_E_INVALID_PARAMETER);
+    SEC2TXT(SEC_E_INVALID_TOKEN);
+    SEC2TXT(SEC_E_ISSUING_CA_UNTRUSTED);
+    SEC2TXT(SEC_E_ISSUING_CA_UNTRUSTED_KDC);
+    SEC2TXT(SEC_E_KDC_CERT_EXPIRED);
+    SEC2TXT(SEC_E_KDC_CERT_REVOKED);
+    SEC2TXT(SEC_E_KDC_INVALID_REQUEST);
+    SEC2TXT(SEC_E_KDC_UNABLE_TO_REFER);
+    SEC2TXT(SEC_E_KDC_UNKNOWN_ETYPE);
+    SEC2TXT(SEC_E_LOGON_DENIED);
+    SEC2TXT(SEC_E_MAX_REFERRALS_EXCEEDED);
+    SEC2TXT(SEC_E_MESSAGE_ALTERED);
+    SEC2TXT(SEC_E_MULTIPLE_ACCOUNTS);
+    SEC2TXT(SEC_E_MUST_BE_KDC);
+    SEC2TXT(SEC_E_NOT_OWNER);
+    SEC2TXT(SEC_E_NO_AUTHENTICATING_AUTHORITY);
+    SEC2TXT(SEC_E_NO_CREDENTIALS);
+    SEC2TXT(SEC_E_NO_IMPERSONATION);
+    SEC2TXT(SEC_E_NO_IP_ADDRESSES);
+    SEC2TXT(SEC_E_NO_KERB_KEY);
+    SEC2TXT(SEC_E_NO_PA_DATA);
+    SEC2TXT(SEC_E_NO_S4U_PROT_SUPPORT);
+    SEC2TXT(SEC_E_NO_TGT_REPLY);
+    SEC2TXT(SEC_E_OUT_OF_SEQUENCE);
+    SEC2TXT(SEC_E_PKINIT_CLIENT_FAILURE);
+    SEC2TXT(SEC_E_PKINIT_NAME_MISMATCH);
+    SEC2TXT(SEC_E_POLICY_NLTM_ONLY);
+    SEC2TXT(SEC_E_QOP_NOT_SUPPORTED);
+    SEC2TXT(SEC_E_REVOCATION_OFFLINE_C);
+    SEC2TXT(SEC_E_REVOCATION_OFFLINE_KDC);
+    SEC2TXT(SEC_E_SECPKG_NOT_FOUND);
+    SEC2TXT(SEC_E_SECURITY_QOS_FAILED);
+    SEC2TXT(SEC_E_SHUTDOWN_IN_PROGRESS);
+    SEC2TXT(SEC_E_SMARTCARD_CERT_EXPIRED);
+    SEC2TXT(SEC_E_SMARTCARD_CERT_REVOKED);
+    SEC2TXT(SEC_E_SMARTCARD_LOGON_REQUIRED);
+    SEC2TXT(SEC_E_STRONG_CRYPTO_NOT_SUPPORTED);
+    SEC2TXT(SEC_E_TARGET_UNKNOWN);
+    SEC2TXT(SEC_E_TIME_SKEW);
+    SEC2TXT(SEC_E_TOO_MANY_PRINCIPALS);
+    SEC2TXT(SEC_E_UNFINISHED_CONTEXT_DELETED);
+    SEC2TXT(SEC_E_UNKNOWN_CREDENTIALS);
+    SEC2TXT(SEC_E_UNSUPPORTED_FUNCTION);
+    SEC2TXT(SEC_E_UNSUPPORTED_PREAUTH);
+    SEC2TXT(SEC_E_UNTRUSTED_ROOT);
+    SEC2TXT(SEC_E_WRONG_CREDENTIAL_HANDLE);
+    SEC2TXT(SEC_E_WRONG_PRINCIPAL);
+    SEC2TXT(SEC_I_COMPLETE_AND_CONTINUE);
+    SEC2TXT(SEC_I_COMPLETE_NEEDED);
+    SEC2TXT(SEC_I_CONTEXT_EXPIRED);
+    SEC2TXT(SEC_I_CONTINUE_NEEDED);
+    SEC2TXT(SEC_I_INCOMPLETE_CREDENTIALS);
+    SEC2TXT(SEC_I_LOCAL_LOGON);
+    SEC2TXT(SEC_I_NO_LSA_CONTEXT);
+    SEC2TXT(SEC_I_RENEGOTIATE);
+    SEC2TXT(SEC_I_SIGNATURE_NEEDED);
+    default:
+      txt = "Unknown error";
+  }
+
+  if(err == SEC_E_ILLEGAL_MESSAGE) {
+    msnprintf(buf, buflen,
+              "SEC_E_ILLEGAL_MESSAGE (0x%08X) - This error usually occurs "
+              "when a fatal SSL/TLS alert is received (e.g. handshake failed)."
+              " More detail may be available in the Windows System event log.",
+              err);
+  }
+  else {
+    char txtbuf[80];
+    char msgbuf[256];
+
+    msnprintf(txtbuf, sizeof(txtbuf), "%s (0x%08X)", txt, err);
+
+    if(get_winapi_error(err, msgbuf, sizeof(msgbuf)))
+      msnprintf(buf, buflen, "%s - %s", txtbuf, msgbuf);
+    else {
+      strncpy(buf, txtbuf, buflen);
+      buf[buflen - 1] = '\0';
+    }
+  }
+
+#else
+  if(err == SEC_E_OK)
+    txt = "No error";
+  else
+    txt = "Error";
+  strncpy(buf, txt, buflen);
+  buf[buflen - 1] = '\0';
+#endif
+
+  if(errno != old_errno)
+    errno = old_errno;
+
+#ifdef PRESERVE_WINDOWS_ERROR_CODE
+  if(old_win_err != GetLastError())
+    SetLastError(old_win_err);
+#endif
+
+  return buf;
 }
 #endif /* USE_WINDOWS_SSPI */
diff --git a/Utilities/cmcurl/lib/strerror.h b/Utilities/cmcurl/lib/strerror.h
index 683b5b4..bae8f89 100644
--- a/Utilities/cmcurl/lib/strerror.h
+++ b/Utilities/cmcurl/lib/strerror.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -24,9 +24,12 @@
 
 #include "urldata.h"
 
-#define STRERROR_LEN 128 /* a suitable length */
+#define STRERROR_LEN 256 /* a suitable length */
 
 const char *Curl_strerror(int err, char *buf, size_t buflen);
+#if defined(WIN32) || defined(_WIN32_WCE)
+const char *Curl_winapi_strerror(DWORD err, char *buf, size_t buflen);
+#endif
 #ifdef USE_WINDOWS_SSPI
 const char *Curl_sspi_strerror(int err, char *buf, size_t buflen);
 #endif
diff --git a/Utilities/cmcurl/lib/strtok.c b/Utilities/cmcurl/lib/strtok.c
index 460eb87..ba6e025 100644
--- a/Utilities/cmcurl/lib/strtok.c
+++ b/Utilities/cmcurl/lib/strtok.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -52,7 +52,7 @@
 
     if(**end) {
       /* the end is not a null byte */
-      **end = '\0';  /* zero terminate it! */
+      **end = '\0';  /* null-terminate it! */
       ++*end;        /* advance the last pointer to beyond the null byte */
     }
 
diff --git a/Utilities/cmcurl/lib/strtok.h b/Utilities/cmcurl/lib/strtok.h
index 90b831e..e221fa6 100644
--- a/Utilities/cmcurl/lib/strtok.h
+++ b/Utilities/cmcurl/lib/strtok.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2010, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
diff --git a/Utilities/cmcurl/lib/strtoofft.c b/Utilities/cmcurl/lib/strtoofft.c
index 546a3ff..96e3820 100644
--- a/Utilities/cmcurl/lib/strtoofft.c
+++ b/Utilities/cmcurl/lib/strtoofft.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
diff --git a/Utilities/cmcurl/lib/system_win32.c b/Utilities/cmcurl/lib/system_win32.c
index f7f817d..b9587b5 100644
--- a/Utilities/cmcurl/lib/system_win32.c
+++ b/Utilities/cmcurl/lib/system_win32.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 2016 - 2017, Steve Holme, <steve_holme@hotmail.com>.
+ * Copyright (C) 2016 - 2020, Steve Holme, <steve_holme@hotmail.com>.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -36,6 +36,12 @@
 LARGE_INTEGER Curl_freq;
 bool Curl_isVistaOrGreater;
 
+/* Handle of iphlpapp.dll */
+static HMODULE s_hIpHlpApiDll = NULL;
+
+/* Pointer to the if_nametoindex function */
+IF_NAMETOINDEX_FN Curl_if_nametoindex = NULL;
+
 /* Curl_win32_init() performs win32 global initialization */
 CURLcode Curl_win32_init(long flags)
 {
@@ -89,20 +95,37 @@
   }
 #endif
 
+  s_hIpHlpApiDll = Curl_load_library(TEXT("iphlpapi.dll"));
+  if(s_hIpHlpApiDll) {
+    /* Get the address of the if_nametoindex function */
+    IF_NAMETOINDEX_FN pIfNameToIndex =
+      CURLX_FUNCTION_CAST(IF_NAMETOINDEX_FN,
+                          (GetProcAddress(s_hIpHlpApiDll, "if_nametoindex")));
+
+    if(pIfNameToIndex)
+      Curl_if_nametoindex = pIfNameToIndex;
+  }
+
   if(Curl_verify_windows_version(6, 0, PLATFORM_WINNT,
                                  VERSION_GREATER_THAN_EQUAL)) {
     Curl_isVistaOrGreater = TRUE;
-    QueryPerformanceFrequency(&Curl_freq);
   }
   else
     Curl_isVistaOrGreater = FALSE;
 
+  QueryPerformanceFrequency(&Curl_freq);
   return CURLE_OK;
 }
 
 /* Curl_win32_cleanup() is the opposite of Curl_win32_init() */
 void Curl_win32_cleanup(long init_flags)
 {
+  if(s_hIpHlpApiDll) {
+    FreeLibrary(s_hIpHlpApiDll);
+    s_hIpHlpApiDll = NULL;
+    Curl_if_nametoindex = NULL;
+  }
+
 #ifdef USE_WINDOWS_SSPI
   Curl_sspi_global_cleanup();
 #endif
@@ -114,10 +137,6 @@
   }
 }
 
-#if defined(USE_WINDOWS_SSPI) || (!defined(CURL_DISABLE_TELNET) && \
-                                  defined(USE_WINSOCK))
-
-
 #if !defined(LOAD_WITH_ALTERED_SEARCH_PATH)
 #define LOAD_WITH_ALTERED_SEARCH_PATH  0x00000008
 #endif
@@ -140,8 +159,6 @@
 #  define LOADLIBARYEX    "LoadLibraryExA"
 #endif
 
-#endif /* USE_WINDOWS_SSPI || (!CURL_DISABLE_TELNET && USE_WINSOCK) */
-
 /*
  * Curl_verify_windows_version()
  *
@@ -334,9 +351,6 @@
   return matched;
 }
 
-#if defined(USE_WINDOWS_SSPI) || (!defined(CURL_DISABLE_TELNET) && \
-                                  defined(USE_WINSOCK))
-
 /*
  * Curl_load_library()
  *
@@ -353,6 +367,7 @@
  */
 HMODULE Curl_load_library(LPCTSTR filename)
 {
+#ifndef CURL_WINDOWS_APP
   HMODULE hModule = NULL;
   LOADLIBRARYEX_FN pLoadLibraryEx = NULL;
 
@@ -407,10 +422,12 @@
       free(path);
     }
   }
-
   return hModule;
+#else
+  /* the Universal Windows Platform (UWP) can't do this */
+  (void)filename;
+  return NULL;
+#endif
 }
 
-#endif /* USE_WINDOWS_SSPI || (!CURL_DISABLE_TELNET && USE_WINSOCK) */
-
 #endif /* WIN32 */
diff --git a/Utilities/cmcurl/lib/system_win32.h b/Utilities/cmcurl/lib/system_win32.h
index 926328a..d2882fc 100644
--- a/Utilities/cmcurl/lib/system_win32.h
+++ b/Utilities/cmcurl/lib/system_win32.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 2016, Steve Holme, <steve_holme@hotmail.com>.
+ * Copyright (C) 2016 - 2019, Steve Holme, <steve_holme@hotmail.com>.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -48,20 +48,21 @@
   PLATFORM_WINNT
 } PlatformIdentifier;
 
+/* We use our own typedef here since some headers might lack this */
+typedef unsigned int(WINAPI *IF_NAMETOINDEX_FN)(const char *);
+
+/* This is used instead of if_nametoindex if available on Windows */
+extern IF_NAMETOINDEX_FN Curl_if_nametoindex;
+
 /* This is used to verify if we are running on a specific windows version */
 bool Curl_verify_windows_version(const unsigned int majorVersion,
                                  const unsigned int minorVersion,
                                  const PlatformIdentifier platform,
                                  const VersionCondition condition);
 
-#if defined(USE_WINDOWS_SSPI) || (!defined(CURL_DISABLE_TELNET) && \
-                                  defined(USE_WINSOCK))
-
 /* This is used to dynamically load DLLs */
 HMODULE Curl_load_library(LPCTSTR filename);
 
-#endif /* USE_WINDOWS_SSPI || (!CURL_DISABLE_TELNET && USE_WINSOCK) */
-
 #endif /* WIN32 */
 
 #endif /* HEADER_CURL_SYSTEM_WIN32_H */
diff --git a/Utilities/cmcurl/lib/telnet.c b/Utilities/cmcurl/lib/telnet.c
index 955255c..c3b58e5 100644
--- a/Utilities/cmcurl/lib/telnet.c
+++ b/Utilities/cmcurl/lib/telnet.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -69,12 +69,12 @@
   do {                                                  \
     x->subend = x->subpointer;                          \
     CURL_SB_CLEAR(x);                                   \
-  } WHILE_FALSE
+  } while(0)
 #define CURL_SB_ACCUM(x,c)                                      \
   do {                                                          \
     if(x->subpointer < (x->subbuffer + sizeof(x->subbuffer)))   \
       *x->subpointer++ = (c);                                   \
-  } WHILE_FALSE
+  } while(0)
 
 #define  CURL_SB_GET(x) ((*x->subpointer++)&0xff)
 #define  CURL_SB_LEN(x) (x->subend - x->subpointer)
@@ -1315,7 +1315,7 @@
   DWORD readfile_read;
   int err;
 #else
-  int interval_ms;
+  timediff_t interval_ms;
   struct pollfd pfd[2];
   int poll_cnt;
   curl_off_t total_dl = 0;
diff --git a/Utilities/cmcurl/lib/telnet.h b/Utilities/cmcurl/lib/telnet.h
index 668a78a..431427f 100644
--- a/Utilities/cmcurl/lib/telnet.h
+++ b/Utilities/cmcurl/lib/telnet.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
diff --git a/Utilities/cmcurl/lib/tftp.c b/Utilities/cmcurl/lib/tftp.c
index 289cda2..378d956 100644
--- a/Utilities/cmcurl/lib/tftp.c
+++ b/Utilities/cmcurl/lib/tftp.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -115,11 +115,11 @@
   TFTP_ERR_NORESPONSE
 } tftp_error_t;
 
-typedef struct tftp_packet {
+struct tftp_packet {
   unsigned char *data;
-} tftp_packet_t;
+};
 
-typedef struct tftp_state_data {
+struct tftp_state_data {
   tftp_state_t    state;
   tftp_mode_t     mode;
   tftp_error_t    error;
@@ -140,25 +140,24 @@
   int             sbytes;
   int             blksize;
   int             requested_blksize;
-  tftp_packet_t   rpacket;
-  tftp_packet_t   spacket;
-} tftp_state_data_t;
+  struct tftp_packet rpacket;
+  struct tftp_packet spacket;
+};
 
 
 /* Forward declarations */
-static CURLcode tftp_rx(tftp_state_data_t *state, tftp_event_t event);
-static CURLcode tftp_tx(tftp_state_data_t *state, tftp_event_t event);
+static CURLcode tftp_rx(struct tftp_state_data *state, tftp_event_t event);
+static CURLcode tftp_tx(struct tftp_state_data *state, tftp_event_t event);
 static CURLcode tftp_connect(struct connectdata *conn, bool *done);
 static CURLcode tftp_disconnect(struct connectdata *conn,
                                 bool dead_connection);
 static CURLcode tftp_do(struct connectdata *conn, bool *done);
 static CURLcode tftp_done(struct connectdata *conn,
                           CURLcode, bool premature);
-static CURLcode tftp_setup_connection(struct connectdata * conn);
+static CURLcode tftp_setup_connection(struct connectdata *conn);
 static CURLcode tftp_multi_statemach(struct connectdata *conn, bool *done);
 static CURLcode tftp_doing(struct connectdata *conn, bool *dophase_done);
-static int tftp_getsock(struct connectdata *conn, curl_socket_t *socks,
-                        int numsocks);
+static int tftp_getsock(struct connectdata *conn, curl_socket_t *socks);
 static CURLcode tftp_translate_code(tftp_error_t error);
 
 
@@ -197,7 +196,7 @@
  *
  *
  **********************************************************/
-static CURLcode tftp_set_timeouts(tftp_state_data_t *state)
+static CURLcode tftp_set_timeouts(struct tftp_state_data *state)
 {
   time_t maxtime, timeout;
   timediff_t timeout_ms;
@@ -280,25 +279,25 @@
  *
  **********************************************************/
 
-static void setpacketevent(tftp_packet_t *packet, unsigned short num)
+static void setpacketevent(struct tftp_packet *packet, unsigned short num)
 {
   packet->data[0] = (unsigned char)(num >> 8);
   packet->data[1] = (unsigned char)(num & 0xff);
 }
 
 
-static void setpacketblock(tftp_packet_t *packet, unsigned short num)
+static void setpacketblock(struct tftp_packet *packet, unsigned short num)
 {
   packet->data[2] = (unsigned char)(num >> 8);
   packet->data[3] = (unsigned char)(num & 0xff);
 }
 
-static unsigned short getrpacketevent(const tftp_packet_t *packet)
+static unsigned short getrpacketevent(const struct tftp_packet *packet)
 {
   return (unsigned short)((packet->data[0] << 8) | packet->data[1]);
 }
 
-static unsigned short getrpacketblock(const tftp_packet_t *packet)
+static unsigned short getrpacketblock(const struct tftp_packet *packet)
 {
   return (unsigned short)((packet->data[2] << 8) | packet->data[3]);
 }
@@ -331,7 +330,7 @@
   return &buf[loc];
 }
 
-static CURLcode tftp_parse_option_ack(tftp_state_data_t *state,
+static CURLcode tftp_parse_option_ack(struct tftp_state_data *state,
                                       const char *ptr, int len)
 {
   const char *tmp = ptr;
@@ -404,16 +403,17 @@
   return CURLE_OK;
 }
 
-static size_t tftp_option_add(tftp_state_data_t *state, size_t csize,
-                              char *buf, const char *option)
+static CURLcode tftp_option_add(struct tftp_state_data *state, size_t *csize,
+                                char *buf, const char *option)
 {
-  if(( strlen(option) + csize + 1) > (size_t)state->blksize)
-    return 0;
+  if(( strlen(option) + *csize + 1) > (size_t)state->blksize)
+    return CURLE_TFTP_ILLEGAL;
   strcpy(buf, option);
-  return strlen(option) + 1;
+  *csize += strlen(option) + 1;
+  return CURLE_OK;
 }
 
-static CURLcode tftp_connect_for_tx(tftp_state_data_t *state,
+static CURLcode tftp_connect_for_tx(struct tftp_state_data *state,
                                     tftp_event_t event)
 {
   CURLcode result;
@@ -429,7 +429,7 @@
   return tftp_tx(state, event);
 }
 
-static CURLcode tftp_connect_for_rx(tftp_state_data_t *state,
+static CURLcode tftp_connect_for_rx(struct tftp_state_data *state,
                                     tftp_event_t event)
 {
   CURLcode result;
@@ -445,7 +445,8 @@
   return tftp_rx(state, event);
 }
 
-static CURLcode tftp_send_first(tftp_state_data_t *state, tftp_event_t event)
+static CURLcode tftp_send_first(struct tftp_state_data *state,
+                                tftp_event_t event)
 {
   size_t sbytes;
   ssize_t senddata;
@@ -486,7 +487,7 @@
        file name so we skip the always-present first letter of the path
        string. */
     result = Curl_urldecode(data, &state->conn->data->state.up.path[1], 0,
-                            &filename, NULL, FALSE);
+                            &filename, NULL, REJECT_ZERO);
     if(result)
       return result;
 
@@ -511,26 +512,38 @@
       else
         strcpy(buf, "0"); /* the destination is large enough */
 
-      sbytes += tftp_option_add(state, sbytes,
-                                (char *)state->spacket.data + sbytes,
-                                TFTP_OPTION_TSIZE);
-      sbytes += tftp_option_add(state, sbytes,
-                                (char *)state->spacket.data + sbytes, buf);
+      result = tftp_option_add(state, &sbytes,
+                               (char *)state->spacket.data + sbytes,
+                               TFTP_OPTION_TSIZE);
+      if(result == CURLE_OK)
+        result = tftp_option_add(state, &sbytes,
+                                 (char *)state->spacket.data + sbytes, buf);
+
       /* add blksize option */
       msnprintf(buf, sizeof(buf), "%d", state->requested_blksize);
-      sbytes += tftp_option_add(state, sbytes,
-                                (char *)state->spacket.data + sbytes,
-                                TFTP_OPTION_BLKSIZE);
-      sbytes += tftp_option_add(state, sbytes,
-                                (char *)state->spacket.data + sbytes, buf);
+      if(result == CURLE_OK)
+        result = tftp_option_add(state, &sbytes,
+                                 (char *)state->spacket.data + sbytes,
+                                 TFTP_OPTION_BLKSIZE);
+      if(result == CURLE_OK)
+        result = tftp_option_add(state, &sbytes,
+                                 (char *)state->spacket.data + sbytes, buf);
 
       /* add timeout option */
       msnprintf(buf, sizeof(buf), "%d", state->retry_time);
-      sbytes += tftp_option_add(state, sbytes,
-                                (char *)state->spacket.data + sbytes,
-                                TFTP_OPTION_INTERVAL);
-      sbytes += tftp_option_add(state, sbytes,
-                                (char *)state->spacket.data + sbytes, buf);
+      if(result == CURLE_OK)
+        result = tftp_option_add(state, &sbytes,
+                                 (char *)state->spacket.data + sbytes,
+                                 TFTP_OPTION_INTERVAL);
+      if(result == CURLE_OK)
+        result = tftp_option_add(state, &sbytes,
+                                 (char *)state->spacket.data + sbytes, buf);
+
+      if(result != CURLE_OK) {
+        failf(data, "TFTP buffer too small for options");
+        free(filename);
+        return CURLE_TFTP_ILLEGAL;
+      }
     }
 
     /* the typecase for the 3rd argument is mostly for systems that do
@@ -586,7 +599,8 @@
  * Event handler for the RX state
  *
  **********************************************************/
-static CURLcode tftp_rx(tftp_state_data_t *state, tftp_event_t event)
+static CURLcode tftp_rx(struct tftp_state_data *state,
+                        tftp_event_t event)
 {
   ssize_t sbytes;
   int rblock;
@@ -708,7 +722,7 @@
  * Event handler for the TX state
  *
  **********************************************************/
-static CURLcode tftp_tx(tftp_state_data_t *state, tftp_event_t event)
+static CURLcode tftp_tx(struct tftp_state_data *state, tftp_event_t event)
 {
   struct Curl_easy *data = state->conn->data;
   ssize_t sbytes;
@@ -908,7 +922,7 @@
  * The tftp state machine event dispatcher
  *
  **********************************************************/
-static CURLcode tftp_state_machine(tftp_state_data_t *state,
+static CURLcode tftp_state_machine(struct tftp_state_data *state,
                                    tftp_event_t event)
 {
   CURLcode result = CURLE_OK;
@@ -949,7 +963,7 @@
  **********************************************************/
 static CURLcode tftp_disconnect(struct connectdata *conn, bool dead_connection)
 {
-  tftp_state_data_t *state = conn->proto.tftpc;
+  struct tftp_state_data *state = conn->proto.tftpc;
   (void) dead_connection;
 
   /* done, free dynamically allocated pkt buffers */
@@ -971,12 +985,13 @@
  **********************************************************/
 static CURLcode tftp_connect(struct connectdata *conn, bool *done)
 {
-  tftp_state_data_t *state;
+  struct tftp_state_data *state;
   int blksize;
+  int need_blksize;
 
   blksize = TFTP_BLKSIZE_DEFAULT;
 
-  state = conn->proto.tftpc = calloc(1, sizeof(tftp_state_data_t));
+  state = conn->proto.tftpc = calloc(1, sizeof(struct tftp_state_data));
   if(!state)
     return CURLE_OUT_OF_MEMORY;
 
@@ -987,15 +1002,20 @@
       return CURLE_TFTP_ILLEGAL;
   }
 
+  need_blksize = blksize;
+  /* default size is the fallback when no OACK is received */
+  if(need_blksize < TFTP_BLKSIZE_DEFAULT)
+    need_blksize = TFTP_BLKSIZE_DEFAULT;
+
   if(!state->rpacket.data) {
-    state->rpacket.data = calloc(1, blksize + 2 + 2);
+    state->rpacket.data = calloc(1, need_blksize + 2 + 2);
 
     if(!state->rpacket.data)
       return CURLE_OUT_OF_MEMORY;
   }
 
   if(!state->spacket.data) {
-    state->spacket.data = calloc(1, blksize + 2 + 2);
+    state->spacket.data = calloc(1, need_blksize + 2 + 2);
 
     if(!state->spacket.data)
       return CURLE_OUT_OF_MEMORY;
@@ -1009,7 +1029,7 @@
   state->sockfd = state->conn->sock[FIRSTSOCKET];
   state->state = TFTP_STATE_START;
   state->error = TFTP_ERR_NONE;
-  state->blksize = blksize;
+  state->blksize = TFTP_BLKSIZE_DEFAULT; /* Unless updated by OACK response */
   state->requested_blksize = blksize;
 
   ((struct sockaddr *)&state->local_addr)->sa_family =
@@ -1060,7 +1080,7 @@
                           bool premature)
 {
   CURLcode result = CURLE_OK;
-  tftp_state_data_t *state = (tftp_state_data_t *)conn->proto.tftpc;
+  struct tftp_state_data *state = conn->proto.tftpc;
 
   (void)status; /* unused */
   (void)premature; /* not used */
@@ -1082,14 +1102,9 @@
  * The getsock callback
  *
  **********************************************************/
-static int tftp_getsock(struct connectdata *conn, curl_socket_t *socks,
-                        int numsocks)
+static int tftp_getsock(struct connectdata *conn, curl_socket_t *socks)
 {
-  if(!numsocks)
-    return GETSOCK_BLANK;
-
   socks[0] = conn->sock[FIRSTSOCKET];
-
   return GETSOCK_READSOCK(0);
 }
 
@@ -1106,7 +1121,7 @@
   curl_socklen_t        fromlen;
   CURLcode              result = CURLE_OK;
   struct Curl_easy  *data = conn->data;
-  tftp_state_data_t     *state = (tftp_state_data_t *)conn->proto.tftpc;
+  struct tftp_state_data *state = conn->proto.tftpc;
   struct SingleRequest  *k = &data->req;
 
   /* Receive the packet */
@@ -1193,8 +1208,8 @@
  **********************************************************/
 static long tftp_state_timeout(struct connectdata *conn, tftp_event_t *event)
 {
-  time_t                current;
-  tftp_state_data_t     *state = (tftp_state_data_t *)conn->proto.tftpc;
+  time_t current;
+  struct tftp_state_data *state = conn->proto.tftpc;
 
   if(event)
     *event = TFTP_EVENT_NONE;
@@ -1231,7 +1246,7 @@
   tftp_event_t          event;
   CURLcode              result = CURLE_OK;
   struct Curl_easy  *data = conn->data;
-  tftp_state_data_t     *state = (tftp_state_data_t *)conn->proto.tftpc;
+  struct tftp_state_data *state = conn->proto.tftpc;
   long                  timeout_ms = tftp_state_timeout(conn, &event);
 
   *done = FALSE;
@@ -1315,7 +1330,7 @@
 static CURLcode tftp_perform(struct connectdata *conn, bool *dophase_done)
 {
   CURLcode              result = CURLE_OK;
-  tftp_state_data_t     *state = (tftp_state_data_t *)conn->proto.tftpc;
+  struct tftp_state_data *state = conn->proto.tftpc;
 
   *dophase_done = FALSE;
 
@@ -1345,7 +1360,7 @@
 
 static CURLcode tftp_do(struct connectdata *conn, bool *done)
 {
-  tftp_state_data_t *state;
+  struct tftp_state_data *state;
   CURLcode result;
 
   *done = FALSE;
@@ -1356,7 +1371,7 @@
       return result;
   }
 
-  state = (tftp_state_data_t *)conn->proto.tftpc;
+  state = conn->proto.tftpc;
   if(!state)
     return CURLE_TFTP_ILLEGAL;
 
@@ -1371,12 +1386,12 @@
   return result;
 }
 
-static CURLcode tftp_setup_connection(struct connectdata * conn)
+static CURLcode tftp_setup_connection(struct connectdata *conn)
 {
   struct Curl_easy *data = conn->data;
   char *type;
 
-  conn->socktype = SOCK_DGRAM;   /* UDP datagram based */
+  conn->transport = TRNSPRT_UDP;
 
   /* TFTP URLs support an extension like ";mode=<typecode>" that
    * we'll try to get now! */
diff --git a/Utilities/cmcurl/lib/tftp.h b/Utilities/cmcurl/lib/tftp.h
index 1335f64..3334830 100644
--- a/Utilities/cmcurl/lib/tftp.h
+++ b/Utilities/cmcurl/lib/tftp.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
diff --git a/Utilities/cmcurl/lib/timeval.c b/Utilities/cmcurl/lib/timeval.c
index e2bd7fd..e761966 100644
--- a/Utilities/cmcurl/lib/timeval.c
+++ b/Utilities/cmcurl/lib/timeval.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -28,6 +28,7 @@
 extern LARGE_INTEGER Curl_freq;
 extern bool Curl_isVistaOrGreater;
 
+/* In case of bug fix this function has a counterpart in tool_util.c */
 struct curltime Curl_now(void)
 {
   struct curltime now;
@@ -174,14 +175,6 @@
 
 #endif
 
-#if SIZEOF_TIME_T < 8
-#define TIME_MAX INT_MAX
-#define TIME_MIN INT_MIN
-#else
-#define TIME_MAX 9223372036854775807LL
-#define TIME_MIN -9223372036854775807LL
-#endif
-
 /*
  * Returns: time difference in number of milliseconds. For too large diffs it
  * returns max value.
@@ -191,10 +184,10 @@
 timediff_t Curl_timediff(struct curltime newer, struct curltime older)
 {
   timediff_t diff = (timediff_t)newer.tv_sec-older.tv_sec;
-  if(diff >= (TIME_MAX/1000))
-    return TIME_MAX;
-  else if(diff <= (TIME_MIN/1000))
-    return TIME_MIN;
+  if(diff >= (TIMEDIFF_T_MAX/1000))
+    return TIMEDIFF_T_MAX;
+  else if(diff <= (TIMEDIFF_T_MIN/1000))
+    return TIMEDIFF_T_MIN;
   return diff * 1000 + (newer.tv_usec-older.tv_usec)/1000;
 }
 
@@ -205,9 +198,9 @@
 timediff_t Curl_timediff_us(struct curltime newer, struct curltime older)
 {
   timediff_t diff = (timediff_t)newer.tv_sec-older.tv_sec;
-  if(diff >= (TIME_MAX/1000000))
-    return TIME_MAX;
-  else if(diff <= (TIME_MIN/1000000))
-    return TIME_MIN;
+  if(diff >= (TIMEDIFF_T_MAX/1000000))
+    return TIMEDIFF_T_MAX;
+  else if(diff <= (TIMEDIFF_T_MIN/1000000))
+    return TIMEDIFF_T_MIN;
   return diff * 1000000 + newer.tv_usec-older.tv_usec;
 }
diff --git a/Utilities/cmcurl/lib/timeval.h b/Utilities/cmcurl/lib/timeval.h
index 96867d7..53e0636 100644
--- a/Utilities/cmcurl/lib/timeval.h
+++ b/Utilities/cmcurl/lib/timeval.h
@@ -24,13 +24,13 @@
 
 #include "curl_setup.h"
 
-#if SIZEOF_TIME_T < 8
-typedef int timediff_t;
-#define CURL_FORMAT_TIMEDIFF_T "d"
-#else
+/* Use a larger type even for 32 bit time_t systems so that we can keep
+   microsecond accuracy in it */
 typedef curl_off_t timediff_t;
 #define CURL_FORMAT_TIMEDIFF_T CURL_FORMAT_CURL_OFF_T
-#endif
+
+#define TIMEDIFF_T_MAX CURL_OFF_T_MAX
+#define TIMEDIFF_T_MIN CURL_OFF_T_MIN
 
 struct curltime {
   time_t tv_sec; /* seconds */
diff --git a/Utilities/cmcurl/lib/transfer.c b/Utilities/cmcurl/lib/transfer.c
index 514330e..133a478 100644
--- a/Utilities/cmcurl/lib/transfer.c
+++ b/Utilities/cmcurl/lib/transfer.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -48,6 +48,8 @@
 
 #ifdef HAVE_SYS_SELECT_H
 #include <sys/select.h>
+#elif defined(HAVE_UNISTD_H)
+#include <unistd.h>
 #endif
 
 #ifndef HAVE_SOCKET
@@ -126,12 +128,13 @@
                                  void *raw)
 {
   struct Curl_easy *data = (struct Curl_easy *)raw;
-  Curl_send_buffer *trailers_buf = data->state.trailers_buf;
-  size_t bytes_left = trailers_buf->size_used-data->state.trailers_bytes_sent;
+  struct dynbuf *trailers_buf = &data->state.trailers_buf;
+  size_t bytes_left = Curl_dyn_len(trailers_buf) -
+    data->state.trailers_bytes_sent;
   size_t to_copy = (size*nitems < bytes_left) ? size*nitems : bytes_left;
   if(to_copy) {
     memcpy(buffer,
-           &trailers_buf->buffer[data->state.trailers_bytes_sent],
+           Curl_dyn_ptr(trailers_buf) + data->state.trailers_bytes_sent,
            to_copy);
     data->state.trailers_bytes_sent += to_copy;
   }
@@ -141,8 +144,8 @@
 static size_t Curl_trailers_left(void *raw)
 {
   struct Curl_easy *data = (struct Curl_easy *)raw;
-  Curl_send_buffer *trailers_buf = data->state.trailers_buf;
-  return trailers_buf->size_used - data->state.trailers_bytes_sent;
+  struct dynbuf *trailers_buf = &data->state.trailers_buf;
+  return Curl_dyn_len(trailers_buf) - data->state.trailers_bytes_sent;
 }
 #endif
 
@@ -176,7 +179,7 @@
 #ifndef CURL_DISABLE_HTTP
   if(data->state.trailers_state == TRAILERS_INITIALIZED) {
     struct curl_slist *trailers = NULL;
-    CURLcode c;
+    CURLcode result;
     int trailers_ret_code;
 
     /* at this point we already verified that the callback exists
@@ -184,28 +187,26 @@
     infof(data,
           "Moving trailers state machine from initialized to sending.\n");
     data->state.trailers_state = TRAILERS_SENDING;
-    data->state.trailers_buf = Curl_add_buffer_init();
-    if(!data->state.trailers_buf) {
-      failf(data, "Unable to allocate trailing headers buffer !");
-      return CURLE_OUT_OF_MEMORY;
-    }
+    Curl_dyn_init(&data->state.trailers_buf, DYN_TRAILERS);
+
     data->state.trailers_bytes_sent = 0;
     Curl_set_in_callback(data, true);
     trailers_ret_code = data->set.trailer_callback(&trailers,
                                                    data->set.trailer_data);
     Curl_set_in_callback(data, false);
     if(trailers_ret_code == CURL_TRAILERFUNC_OK) {
-      c = Curl_http_compile_trailers(trailers, data->state.trailers_buf, data);
+      result = Curl_http_compile_trailers(trailers, &data->state.trailers_buf,
+                                          data);
     }
     else {
       failf(data, "operation aborted by trailing headers callback");
       *nreadp = 0;
-      c = CURLE_ABORTED_BY_CALLBACK;
+      result = CURLE_ABORTED_BY_CALLBACK;
     }
-    if(c != CURLE_OK) {
-      Curl_add_buffer_free(&data->state.trailers_buf);
+    if(result) {
+      Curl_dyn_free(&data->state.trailers_buf);
       curl_slist_free_all(trailers);
-      return c;
+      return result;
     }
     infof(data, "Successfully compiled trailers.\r\n");
     curl_slist_free_all(trailers);
@@ -225,7 +226,7 @@
   if(data->state.trailers_state == TRAILERS_SENDING) {
     /* if we're here then that means that we already sent the last empty chunk
        but we didn't send a final CR LF, so we sent 0 CR LF. We then start
-       pulling trailing data until we ²have no more at which point we
+       pulling trailing data until we have no more at which point we
        simply return to the previous point in the state machine as if
        nothing happened.
        */
@@ -366,7 +367,7 @@
 #ifndef CURL_DISABLE_HTTP
     if(data->state.trailers_state == TRAILERS_SENDING &&
        !Curl_trailers_left(data)) {
-      Curl_add_buffer_free(&data->state.trailers_buf);
+      Curl_dyn_free(&data->state.trailers_buf);
       data->state.trailers_state = TRAILERS_DONE;
       data->set.trailer_data = NULL;
       data->set.trailer_callback = NULL;
@@ -432,8 +433,8 @@
   }
   if(data->set.postfields)
     ; /* do nothing */
-  else if(data->set.httpreq == HTTPREQ_POST_MIME ||
-          data->set.httpreq == HTTPREQ_POST_FORM) {
+  else if(data->state.httpreq == HTTPREQ_POST_MIME ||
+          data->state.httpreq == HTTPREQ_POST_FORM) {
     if(Curl_mime_rewind(mimepart)) {
       failf(data, "Cannot rewind mime/post data");
       return CURLE_SEND_FAIL_REWIND;
@@ -483,8 +484,9 @@
   return CURLE_OK;
 }
 
-static int data_pending(const struct connectdata *conn)
+static int data_pending(const struct Curl_easy *data)
 {
+  struct connectdata *conn = data->conn;
   /* in the case of libssh2, we can never be really sure that we have emptied
      its internal buffers so we MUST always try until we get EAGAIN back */
   return conn->handler->protocol&(CURLPROTO_SCP|CURLPROTO_SFTP) ||
@@ -497,7 +499,9 @@
        TRUE. The thing is if we read everything, then http2_recv won't
        be called and we cannot signal the HTTP/2 stream has closed. As
        a workaround, we return nonzero here to call http2_recv. */
-    ((conn->handler->protocol&PROTO_FAMILY_HTTP) && conn->httpversion == 20);
+    ((conn->handler->protocol&PROTO_FAMILY_HTTP) && conn->httpversion >= 20);
+#elif defined(ENABLE_QUIC)
+    Curl_ssl_data_pending(conn, FIRSTSOCKET) || Curl_quic_data_pending(data);
 #else
     Curl_ssl_data_pending(conn, FIRSTSOCKET);
 #endif
@@ -554,6 +558,8 @@
   size_t excess = 0; /* excess bytes read */
   bool readmore = FALSE; /* used by RTP to signal for more data */
   int maxloops = 100;
+  char *buf = data->state.buffer;
+  DEBUGASSERT(buf);
 
   *done = FALSE;
   *comeback = FALSE;
@@ -564,17 +570,20 @@
     bool is_empty_data = FALSE;
     size_t buffersize = data->set.buffer_size;
     size_t bytestoread = buffersize;
+#ifdef USE_NGHTTP2
+    bool is_http2 = ((conn->handler->protocol & PROTO_FAMILY_HTTP) &&
+                     (conn->httpversion == 20));
+#endif
 
     if(
-#if defined(USE_NGHTTP2)
+#ifdef USE_NGHTTP2
        /* For HTTP/2, read data without caring about the content
           length. This is safe because body in HTTP/2 is always
           segmented thanks to its framing layer. Meanwhile, we have to
           call Curl_read to ensure that http2_handle_stream_close is
           called when we read all incoming bytes for a particular
           stream. */
-       !((conn->handler->protocol & PROTO_FAMILY_HTTP) &&
-         conn->httpversion == 20) &&
+       !is_http2 &&
 #endif
        k->size != -1 && !k->header) {
       /* make sure we don't read too much */
@@ -585,7 +594,7 @@
 
     if(bytestoread) {
       /* receive data from the network! */
-      result = Curl_read(conn, conn->sockfd, k->buf, bytestoread, &nread);
+      result = Curl_read(conn, conn->sockfd, buf, bytestoread, &nread);
 
       /* read would've blocked */
       if(CURLE_AGAIN == result)
@@ -601,7 +610,7 @@
       nread = 0;
     }
 
-    if((k->bytecount == 0) && (k->writebytecount == 0)) {
+    if(!k->bytecount) {
       Curl_pgrsTime(data, TIMER_STARTTRANSFER);
       if(k->exp100 > EXP100_SEND_DATA)
         /* set time stamp to compare with when waiting for the 100 */
@@ -612,21 +621,25 @@
     /* indicates data of zero size, i.e. empty file */
     is_empty_data = ((nread == 0) && (k->bodywrites == 0)) ? TRUE : FALSE;
 
-    /* NUL terminate, allowing string ops to be used */
     if(0 < nread || is_empty_data) {
-      k->buf[nread] = 0;
+      buf[nread] = 0;
     }
     else {
-      /* if we receive 0 or less here, the server closed the connection
-         and we bail out from this! */
-      DEBUGF(infof(data, "nread <= 0, server closed connection, bailing\n"));
+      /* if we receive 0 or less here, either the http2 stream is closed or the
+         server closed the connection and we bail out from this! */
+#ifdef USE_NGHTTP2
+      if(is_http2 && !nread)
+        DEBUGF(infof(data, "nread == 0, stream closed, bailing\n"));
+      else
+#endif
+        DEBUGF(infof(data, "nread <= 0, server closed connection, bailing\n"));
       k->keepon &= ~KEEP_RECV;
       break;
     }
 
     /* Default buffer to use when we write the buffer, it may be changed
        in the flow below before the actual storing is done. */
-    k->str = k->buf;
+    k->str = buf;
 
     if(conn->handler->readwrite) {
       result = conn->handler->readwrite(data, conn, &nread, &readmore);
@@ -675,7 +688,7 @@
     /* This is not an 'else if' since it may be a rest from the header
        parsing, where the beginning of the buffer is headers and the end
        is non-headers. */
-    if(k->str && !k->header && (nread > 0 || is_empty_data)) {
+    if(!k->header && (nread > 0 || is_empty_data)) {
 
       if(data->set.opt_no_body) {
         /* data arrives although we want none, bail out */
@@ -706,7 +719,7 @@
             infof(data, "Ignoring the response-body\n");
           }
           if(data->state.resume_from && !k->content_range &&
-             (data->set.httpreq == HTTPREQ_GET) &&
+             (data->state.httpreq == HTTPREQ_GET) &&
              !k->ignorebody) {
 
             if(k->size == data->state.resume_from) {
@@ -756,8 +769,9 @@
       /* pass data to the debug function before it gets "dechunked" */
       if(data->set.verbose) {
         if(k->badheader) {
-          Curl_debug(data, CURLINFO_DATA_IN, data->state.headerbuff,
-                     (size_t)k->hbuflen);
+          Curl_debug(data, CURLINFO_DATA_IN,
+                     Curl_dyn_ptr(&data->state.headerb),
+                     Curl_dyn_len(&data->state.headerb));
           if(k->badheader == HEADER_PARTHEADER)
             Curl_debug(data, CURLINFO_DATA_IN,
                        k->str, (size_t)nread);
@@ -775,14 +789,14 @@
          * and writes away the data. The returned 'nread' holds the number
          * of actual data it wrote to the client.
          */
-
+        CURLcode extra;
         CHUNKcode res =
-          Curl_httpchunk_read(conn, k->str, nread, &nread);
+          Curl_httpchunk_read(conn, k->str, nread, &nread, &extra);
 
         if(CHUNKE_OK < res) {
-          if(CHUNKE_WRITE_ERROR == res) {
-            failf(data, "Failed writing data");
-            return CURLE_WRITE_ERROR;
+          if(CHUNKE_PASSTHRU_ERROR == res) {
+            failf(data, "Failed reading the chunked-encoded stream");
+            return extra;
           }
           failf(data, "%s in chunked-encoding", Curl_chunked_strerror(res));
           return CURLE_RECV_ERROR;
@@ -808,9 +822,9 @@
 
       /* Account for body content stored in the header buffer */
       if((k->badheader == HEADER_PARTHEADER) && !k->ignorebody) {
-        DEBUGF(infof(data, "Increasing bytecount by %zu from hbuflen\n",
-                     k->hbuflen));
-        k->bytecount += k->hbuflen;
+        size_t headlen = Curl_dyn_len(&data->state.headerb);
+        DEBUGF(infof(data, "Increasing bytecount by %zu\n", headlen));
+        k->bytecount += headlen;
       }
 
       if((-1 != k->maxdownload) &&
@@ -825,6 +839,7 @@
                 ", maxdownload = %" CURL_FORMAT_CURL_OFF_T
                 ", bytecount = %" CURL_FORMAT_CURL_OFF_T "\n",
                 excess, k->size, k->maxdownload, k->bytecount);
+          connclose(conn, "excess found in a read");
         }
 
         nread = (ssize_t) (k->maxdownload - k->bytecount);
@@ -844,15 +859,16 @@
         if(k->badheader && !k->ignorebody) {
           /* we parsed a piece of data wrongly assuming it was a header
              and now we output it as body instead */
+          size_t headlen = Curl_dyn_len(&data->state.headerb);
 
           /* Don't let excess data pollute body writes */
-          if(k->maxdownload == -1 || (curl_off_t)k->hbuflen <= k->maxdownload)
+          if(k->maxdownload == -1 || (curl_off_t)headlen <= k->maxdownload)
             result = Curl_client_write(conn, CLIENTWRITE_BODY,
-                                       data->state.headerbuff,
-                                       k->hbuflen);
+                                       Curl_dyn_ptr(&data->state.headerb),
+                                       headlen);
           else
             result = Curl_client_write(conn, CLIENTWRITE_BODY,
-                                       data->state.headerbuff,
+                                       Curl_dyn_ptr(&data->state.headerb),
                                        (size_t)k->maxdownload);
 
           if(result)
@@ -886,14 +902,14 @@
 
     } /* if(!header and data to read) */
 
-    if(conn->handler->readwrite && excess && !conn->bits.stream_was_rewound) {
+    if(conn->handler->readwrite && excess) {
       /* Parse the excess data */
       k->str += nread;
 
-      if(&k->str[excess] > &k->buf[data->set.buffer_size]) {
+      if(&k->str[excess] > &buf[data->set.buffer_size]) {
         /* the excess amount was too excessive(!), make sure
            it doesn't read out of buffer */
-        excess = &k->buf[data->set.buffer_size] - k->str;
+        excess = &buf[data->set.buffer_size] - k->str;
       }
       nread = (ssize_t)excess;
 
@@ -917,7 +933,7 @@
       break;
     }
 
-  } while(data_pending(conn) && maxloops--);
+  } while(data_pending(data) && maxloops--);
 
   if(maxloops <= 0) {
     /* we mark it as read-again-please */
@@ -937,12 +953,14 @@
   return CURLE_OK;
 }
 
-static CURLcode done_sending(struct connectdata *conn,
-                             struct SingleRequest *k)
+CURLcode Curl_done_sending(struct connectdata *conn,
+                           struct SingleRequest *k)
 {
   k->keepon &= ~KEEP_SEND; /* we're done writing */
 
+  /* These functions should be moved into the handler struct! */
   Curl_http2_done_sending(conn);
+  Curl_quic_done_sending(conn);
 
   if(conn->bits.rewindaftersend) {
     CURLcode result = Curl_readrewind(conn);
@@ -1046,7 +1064,7 @@
         break;
       }
       if(nread <= 0) {
-        result = done_sending(conn, k);
+        result = Curl_done_sending(conn, k);
         if(result)
           return result;
         break;
@@ -1164,14 +1182,14 @@
       k->upload_present = 0; /* no more bytes left */
 
       if(k->upload_done) {
-        result = done_sending(conn, k);
+        result = Curl_done_sending(conn, k);
         if(result)
           return result;
       }
     }
 
 
-  } WHILE_FALSE; /* just to break out from! */
+  } while(0); /* just to break out from! */
 
   return CURLE_OK;
 }
@@ -1228,9 +1246,7 @@
   /* We go ahead and do a read if we have a readable socket or if
      the stream was rewound (in which case we have data in a
      buffer) */
-  if((k->keepon & KEEP_RECV) &&
-     ((select_res & CURL_CSELECT_IN) || conn->bits.stream_was_rewound)) {
-
+  if((k->keepon & KEEP_RECV) && (select_res & CURL_CSELECT_IN)) {
     result = readwrite_data(data, conn, k, &didwhat, done, comeback);
     if(result || *done)
       return result;
@@ -1354,20 +1370,14 @@
  * in the proper state to have this information available.
  */
 int Curl_single_getsock(const struct connectdata *conn,
-                        curl_socket_t *sock, /* points to numsocks number
-                                                of sockets */
-                        int numsocks)
+                        curl_socket_t *sock)
 {
   const struct Curl_easy *data = conn->data;
   int bitmap = GETSOCK_BLANK;
   unsigned sockindex = 0;
 
   if(conn->handler->perform_getsock)
-    return conn->handler->perform_getsock(conn, sock, numsocks);
-
-  if(numsocks < 2)
-    /* simple check but we might need two slots */
-    return GETSOCK_BLANK;
+    return conn->handler->perform_getsock(conn, sock);
 
   /* don't include HOLD and PAUSE connections */
   if((data->req.keepon & KEEP_RECVBITS) == KEEP_RECV) {
@@ -1439,6 +1449,7 @@
     }
   }
 
+  data->state.httpreq = data->set.method;
   data->change.url = data->set.str[STRING_SET_URL];
 
   /* Init the SSL session ID cache here. We do it here since we want to do it
@@ -1458,12 +1469,11 @@
   data->state.authhost.want = data->set.httpauth;
   data->state.authproxy.want = data->set.proxyauth;
   Curl_safefree(data->info.wouldredirect);
-  data->info.wouldredirect = NULL;
 
-  if(data->set.httpreq == HTTPREQ_PUT)
+  if(data->state.httpreq == HTTPREQ_PUT)
     data->state.infilesize = data->set.filesize;
-  else if((data->set.httpreq != HTTPREQ_GET) &&
-          (data->set.httpreq != HTTPREQ_HEAD)) {
+  else if((data->state.httpreq != HTTPREQ_GET) &&
+          (data->state.httpreq != HTTPREQ_HEAD)) {
     data->state.infilesize = data->set.postfieldsize;
     if(data->set.postfields && (data->state.infilesize == -1))
       data->state.infilesize = (curl_off_t)strlen(data->set.postfields);
@@ -1513,6 +1523,7 @@
       }
     }
 #endif
+    Curl_http2_init_state(&data->state);
   }
 
   return result;
@@ -1594,7 +1605,8 @@
 
   DEBUGASSERT(data->state.uh);
   uc = curl_url_set(data->state.uh, CURLUPART_URL, newurl,
-                    (type == FOLLOW_FAKE) ? CURLU_NON_SUPPORT_SCHEME : 0);
+                    (type == FOLLOW_FAKE) ? CURLU_NON_SUPPORT_SCHEME :
+                    ((type == FOLLOW_REDIR) ? CURLU_URLENCODE : 0) );
   if(uc) {
     if(type != FOLLOW_FAKE)
       return Curl_uc_to_curlcode(uc);
@@ -1672,12 +1684,12 @@
      * This behaviour is forbidden by RFC1945 and the obsolete RFC2616, and
      * can be overridden with CURLOPT_POSTREDIR.
      */
-    if((data->set.httpreq == HTTPREQ_POST
-        || data->set.httpreq == HTTPREQ_POST_FORM
-        || data->set.httpreq == HTTPREQ_POST_MIME)
+    if((data->state.httpreq == HTTPREQ_POST
+        || data->state.httpreq == HTTPREQ_POST_FORM
+        || data->state.httpreq == HTTPREQ_POST_MIME)
        && !(data->set.keep_post & CURL_REDIR_POST_301)) {
       infof(data, "Switch from POST to GET\n");
-      data->set.httpreq = HTTPREQ_GET;
+      data->state.httpreq = HTTPREQ_GET;
     }
     break;
   case 302: /* Found */
@@ -1697,22 +1709,29 @@
      * This behaviour is forbidden by RFC1945 and the obsolete RFC2616, and
      * can be overridden with CURLOPT_POSTREDIR.
      */
-    if((data->set.httpreq == HTTPREQ_POST
-        || data->set.httpreq == HTTPREQ_POST_FORM
-        || data->set.httpreq == HTTPREQ_POST_MIME)
+    if((data->state.httpreq == HTTPREQ_POST
+        || data->state.httpreq == HTTPREQ_POST_FORM
+        || data->state.httpreq == HTTPREQ_POST_MIME)
        && !(data->set.keep_post & CURL_REDIR_POST_302)) {
       infof(data, "Switch from POST to GET\n");
-      data->set.httpreq = HTTPREQ_GET;
+      data->state.httpreq = HTTPREQ_GET;
     }
     break;
 
   case 303: /* See Other */
-    /* Disable both types of POSTs, unless the user explicitly
-       asks for POST after POST */
-    if(data->set.httpreq != HTTPREQ_GET
-      && !(data->set.keep_post & CURL_REDIR_POST_303)) {
-      data->set.httpreq = HTTPREQ_GET; /* enforce GET request */
-      infof(data, "Disables POST, goes with %s\n",
+    /* 'See Other' location is not the resource but a substitute for the
+     * resource. In this case we switch the method to GET/HEAD, unless the
+     * method is POST and the user specified to keep it as POST.
+     * https://github.com/curl/curl/issues/5237#issuecomment-614641049
+     */
+    if(data->state.httpreq != HTTPREQ_GET &&
+       ((data->state.httpreq != HTTPREQ_POST &&
+         data->state.httpreq != HTTPREQ_POST_FORM &&
+         data->state.httpreq != HTTPREQ_POST_MIME) ||
+        !(data->set.keep_post & CURL_REDIR_POST_303))) {
+      data->state.httpreq = HTTPREQ_GET;
+      data->set.upload = false;
+      infof(data, "Switch to %s\n",
             data->set.opt_no_body?"HEAD":"GET");
     }
     break;
@@ -1779,6 +1798,12 @@
     retry = TRUE;
   }
   if(retry) {
+#define CONN_MAX_RETRIES 5
+    if(conn->retrycount++ >= CONN_MAX_RETRIES) {
+      failf(data, "Connection died, tried %d times before giving up",
+            CONN_MAX_RETRIES);
+      return CURLE_SEND_ERROR;
+    }
     infof(conn->data, "Connection died, retrying a fresh connect\n");
     *url = strdup(conn->data->change.url);
     if(!*url)
@@ -1821,15 +1846,21 @@
 {
   struct SingleRequest *k = &data->req;
   struct connectdata *conn = data->conn;
+  struct HTTP *http = data->req.protop;
+  bool httpsending = ((conn->handler->protocol&PROTO_FAMILY_HTTP) &&
+                      (http->sending == HTTPSEND_REQUEST));
   DEBUGASSERT(conn != NULL);
   DEBUGASSERT((sockindex <= 1) && (sockindex >= -1));
 
-  if(conn->bits.multiplex || conn->httpversion == 20) {
+  if(conn->bits.multiplex || conn->httpversion == 20 || httpsending) {
     /* when multiplexing, the read/write sockets need to be the same! */
     conn->sockfd = sockindex == -1 ?
       ((writesockindex == -1 ? CURL_SOCKET_BAD : conn->sock[writesockindex])) :
       conn->sock[sockindex];
     conn->writesockfd = conn->sockfd;
+    if(httpsending)
+      /* special and very HTTP-specific */
+      writesockindex = FIRSTSOCKET;
   }
   else {
     conn->sockfd = sockindex == -1 ?
@@ -1857,7 +1888,6 @@
       k->keepon |= KEEP_RECV;
 
     if(writesockindex != -1) {
-      struct HTTP *http = data->req.protop;
       /* HTTP 1.1 magic:
 
          Even if we require a 100-return code before uploading data, we might
diff --git a/Utilities/cmcurl/lib/transfer.h b/Utilities/cmcurl/lib/transfer.h
index a9bff63..67fd91f 100644
--- a/Utilities/cmcurl/lib/transfer.h
+++ b/Utilities/cmcurl/lib/transfer.h
@@ -29,7 +29,6 @@
 void Curl_init_CONNECT(struct Curl_easy *data);
 
 CURLcode Curl_pretransfer(struct Curl_easy *data);
-CURLcode Curl_second_connect(struct connectdata *conn);
 CURLcode Curl_posttransfer(struct Curl_easy *data);
 
 typedef enum {
@@ -48,8 +47,7 @@
                         struct Curl_easy *data, bool *done,
                         bool *comeback);
 int Curl_single_getsock(const struct connectdata *conn,
-                        curl_socket_t *socks,
-                        int numsocks);
+                        curl_socket_t *socks);
 CURLcode Curl_readrewind(struct connectdata *conn);
 CURLcode Curl_fillreadbuffer(struct connectdata *conn, size_t bytes,
                              size_t *nreadp);
@@ -57,6 +55,9 @@
 bool Curl_meets_timecondition(struct Curl_easy *data, time_t timeofdoc);
 CURLcode Curl_get_upload_buffer(struct Curl_easy *data);
 
+CURLcode Curl_done_sending(struct connectdata *conn,
+                           struct SingleRequest *k);
+
 /* This sets up a forthcoming transfer */
 void
 Curl_setup_transfer (struct Curl_easy *data,
diff --git a/Utilities/cmcurl/lib/url.c b/Utilities/cmcurl/lib/url.c
index c441ae7..a1a6b69 100644
--- a/Utilities/cmcurl/lib/url.c
+++ b/Utilities/cmcurl/lib/url.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -34,10 +34,12 @@
 #ifdef HAVE_NET_IF_H
 #include <net/if.h>
 #endif
+#ifdef HAVE_IPHLPAPI_H
+#include <Iphlpapi.h>
+#endif
 #ifdef HAVE_SYS_IOCTL_H
 #include <sys/ioctl.h>
 #endif
-
 #ifdef HAVE_SYS_PARAM_H
 #include <sys/param.h>
 #endif
@@ -93,6 +95,7 @@
 #include "inet_pton.h"
 #include "getinfo.h"
 #include "urlapi-int.h"
+#include "system_win32.h"
 
 /* And now for the protocols */
 #include "ftp.h"
@@ -103,15 +106,15 @@
 #include "http2.h"
 #include "file.h"
 #include "curl_ldap.h"
-#include "ssh.h"
+#include "vssh/ssh.h"
 #include "imap.h"
 #include "url.h"
 #include "connect.h"
 #include "inet_ntop.h"
 #include "http_ntlm.h"
-#include "socks.h"
 #include "curl_rtmp.h"
 #include "gopher.h"
+#include "mqtt.h"
 #include "http_proxy.h"
 #include "conncache.h"
 #include "multihandle.h"
@@ -119,6 +122,7 @@
 #include "strdup.h"
 #include "setopt.h"
 #include "altsvc.h"
+#include "dynbuf.h"
 
 /* The last 3 #include files should be in this order */
 #include "curl_printf.h"
@@ -126,7 +130,6 @@
 #include "memdebug.h"
 
 static void conn_free(struct connectdata *conn);
-static void free_idnconverted_hostname(struct hostname *host);
 static unsigned int get_protocol_family(unsigned int protocol);
 
 /* Some parts of the code (e.g. chunked encoding) assume this buffer has at
@@ -139,19 +142,21 @@
 
 
 /*
- * Protocol table.
+ * Protocol table. Schemes (roughly) in 2019 popularity order:
+ *
+ * HTTPS, HTTP, FTP, FTPS, SFTP, FILE, SCP, SMTP, LDAP, IMAPS, TELNET, IMAP,
+ * LDAPS, SMTPS, TFTP, SMB, POP3, GOPHER POP3S, RTSP, RTMP, SMBS, DICT
  */
-
 static const struct Curl_handler * const protocols[] = {
 
-#ifndef CURL_DISABLE_HTTP
-  &Curl_handler_http,
-#endif
-
 #if defined(USE_SSL) && !defined(CURL_DISABLE_HTTP)
   &Curl_handler_https,
 #endif
 
+#ifndef CURL_DISABLE_HTTP
+  &Curl_handler_http,
+#endif
+
 #ifndef CURL_DISABLE_FTP
   &Curl_handler_ftp,
 #endif
@@ -160,12 +165,23 @@
   &Curl_handler_ftps,
 #endif
 
-#ifndef CURL_DISABLE_TELNET
-  &Curl_handler_telnet,
+#if defined(USE_SSH)
+  &Curl_handler_sftp,
 #endif
 
-#ifndef CURL_DISABLE_DICT
-  &Curl_handler_dict,
+#ifndef CURL_DISABLE_FILE
+  &Curl_handler_file,
+#endif
+
+#if defined(USE_SSH) && !defined(USE_WOLFSSH)
+  &Curl_handler_scp,
+#endif
+
+#ifndef CURL_DISABLE_SMTP
+  &Curl_handler_smtp,
+#ifdef USE_SSL
+  &Curl_handler_smtps,
+#endif
 #endif
 
 #ifndef CURL_DISABLE_LDAP
@@ -177,22 +193,6 @@
 #endif
 #endif
 
-#ifndef CURL_DISABLE_FILE
-  &Curl_handler_file,
-#endif
-
-#ifndef CURL_DISABLE_TFTP
-  &Curl_handler_tftp,
-#endif
-
-#if defined(USE_SSH)
-  &Curl_handler_scp,
-#endif
-
-#if defined(USE_SSH)
-  &Curl_handler_sftp,
-#endif
-
 #ifndef CURL_DISABLE_IMAP
   &Curl_handler_imap,
 #ifdef USE_SSL
@@ -200,6 +200,14 @@
 #endif
 #endif
 
+#ifndef CURL_DISABLE_TELNET
+  &Curl_handler_telnet,
+#endif
+
+#ifndef CURL_DISABLE_TFTP
+  &Curl_handler_tftp,
+#endif
+
 #ifndef CURL_DISABLE_POP3
   &Curl_handler_pop3,
 #ifdef USE_SSL
@@ -216,17 +224,14 @@
 #endif
 #endif
 
-#ifndef CURL_DISABLE_SMTP
-  &Curl_handler_smtp,
-#ifdef USE_SSL
-  &Curl_handler_smtps,
-#endif
-#endif
-
 #ifndef CURL_DISABLE_RTSP
   &Curl_handler_rtsp,
 #endif
 
+#ifdef CURL_ENABLE_MQTT
+  &Curl_handler_mqtt,
+#endif
+
 #ifndef CURL_DISABLE_GOPHER
   &Curl_handler_gopher,
 #endif
@@ -240,6 +245,10 @@
   &Curl_handler_rtmpts,
 #endif
 
+#ifndef CURL_DISABLE_DICT
+  &Curl_handler_dict,
+#endif
+
   (struct Curl_handler *) NULL
 };
 
@@ -272,10 +281,16 @@
 {
   /* Free all dynamic strings stored in the data->set substructure. */
   enum dupstring i;
+  enum dupblob j;
+
   for(i = (enum dupstring)0; i < STRING_LAST; i++) {
     Curl_safefree(data->set.str[i]);
   }
 
+  for(j = (enum dupblob)0; j < BLOB_LAST; j++) {
+    Curl_safefree(data->set.blobs[j]);
+  }
+
   if(data->change.referer_alloc) {
     Curl_safefree(data->change.referer);
     data->change.referer_alloc = FALSE;
@@ -315,13 +330,17 @@
  * when curl_easy_perform() is invoked.
  */
 
-CURLcode Curl_close(struct Curl_easy *data)
+CURLcode Curl_close(struct Curl_easy **datap)
 {
   struct Curl_multi *m;
+  struct Curl_easy *data;
 
-  if(!data)
+  if(!datap || !*datap)
     return CURLE_OK;
 
+  data = *datap;
+  *datap = NULL;
+
   Curl_expire_clear(data); /* shut off timers */
 
   m = data->multi;
@@ -370,11 +389,11 @@
 
   up_free(data);
   Curl_safefree(data->state.buffer);
-  Curl_safefree(data->state.headerbuff);
+  Curl_dyn_free(&data->state.headerb);
   Curl_safefree(data->state.ulbuf);
-  Curl_flush_cookies(data, 1);
+  Curl_flush_cookies(data, TRUE);
 #ifdef USE_ALTSVC
-  Curl_altsvc_save(data->asi, data->set.str[STRING_ALTSVC]);
+  Curl_altsvc_save(data, data->asi, data->set.str[STRING_ALTSVC]);
   Curl_altsvc_cleanup(data->asi);
   data->asi = NULL;
 #endif
@@ -397,6 +416,23 @@
     Curl_share_unlock(data, CURL_LOCK_DATA_SHARE);
   }
 
+  Curl_safefree(data->state.aptr.proxyuserpwd);
+  Curl_safefree(data->state.aptr.uagent);
+  Curl_safefree(data->state.aptr.userpwd);
+  Curl_safefree(data->state.aptr.accept_encoding);
+  Curl_safefree(data->state.aptr.te);
+  Curl_safefree(data->state.aptr.rangeline);
+  Curl_safefree(data->state.aptr.ref);
+  Curl_safefree(data->state.aptr.host);
+  Curl_safefree(data->state.aptr.cookiehost);
+  Curl_safefree(data->state.aptr.rtsp_transport);
+
+#ifndef CURL_DISABLE_DOH
+  Curl_dyn_free(&data->req.doh.probe[0].serverdoh);
+  Curl_dyn_free(&data->req.doh.probe[1].serverdoh);
+  curl_slist_free_all(data->req.doh.headers);
+#endif
+
   /* destruct wildcard structures if it is needed */
   Curl_wildcard_dtor(&data->wildcard);
   Curl_freeset(data);
@@ -437,9 +473,9 @@
   set->postfieldsize = -1;   /* unknown size */
   set->maxredirs = -1;       /* allow any amount by default */
 
-  set->httpreq = HTTPREQ_GET; /* Default HTTP request */
+  set->method = HTTPREQ_GET; /* Default HTTP request */
   set->rtspreq = RTSPREQ_OPTIONS; /* Default RTSP request */
-#ifndef CURL_DISABLE_FILE
+#ifndef CURL_DISABLE_FTP
   set->ftp_use_epsv = TRUE;   /* FTP defaults to EPSV operations */
   set->ftp_use_eprt = TRUE;   /* FTP defaults to EPRT operations */
   set->ftp_use_pret = FALSE;  /* mainly useful for drftpd servers */
@@ -476,7 +512,9 @@
                                                       type */
   set->ssl.primary.sessionid = TRUE; /* session ID caching enabled by
                                         default */
+#ifndef CURL_DISABLE_PROXY
   set->proxy_ssl = set->ssl;
+#endif
 
   set->new_file_perms = 0644;    /* Default permissions */
   set->new_directory_perms = 0755; /* Default permissions */
@@ -485,9 +523,8 @@
      define since we internally only use the lower 16 bits for the passed
      in bitmask to not conflict with the private bits */
   set->allowed_protocols = CURLPROTO_ALL;
-  set->redir_protocols = CURLPROTO_ALL &  /* All except FILE, SCP and SMB */
-                          ~(CURLPROTO_FILE | CURLPROTO_SCP | CURLPROTO_SMB |
-                            CURLPROTO_SMBS);
+  set->redir_protocols = CURLPROTO_HTTP | CURLPROTO_HTTPS | CURLPROTO_FTP |
+                         CURLPROTO_FTPS;
 
 #if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI)
   /*
@@ -544,7 +581,7 @@
   set->upkeep_interval_ms = CURL_UPKEEP_INTERVAL_DEFAULT;
   set->maxconnects = DEFAULT_CONNCACHE_SIZE; /* for easy handles */
   set->maxage_conn = 118;
-  set->http09_allowed = TRUE;
+  set->http09_allowed = FALSE;
   set->httpversion =
 #ifdef USE_NGHTTP2
     CURL_HTTP_VERSION_2TLS
@@ -586,40 +623,22 @@
     return result;
   }
 
-  /* We do some initial setup here, all those fields that can't be just 0 */
+  result = Curl_init_userdefined(data);
+  if(!result) {
+    Curl_dyn_init(&data->state.headerb, CURL_MAX_HTTP_HEADER);
+    Curl_convert_init(data);
+    Curl_initinfo(data);
 
-  data->state.buffer = malloc(READBUFFER_SIZE + 1);
-  if(!data->state.buffer) {
-    DEBUGF(fprintf(stderr, "Error: malloc of buffer failed\n"));
-    result = CURLE_OUT_OF_MEMORY;
-  }
-  else {
-    data->state.headerbuff = malloc(HEADERSIZE);
-    if(!data->state.headerbuff) {
-      DEBUGF(fprintf(stderr, "Error: malloc of headerbuff failed\n"));
-      result = CURLE_OUT_OF_MEMORY;
-    }
-    else {
-      result = Curl_init_userdefined(data);
+    /* most recent connection is not yet defined */
+    data->state.lastconnect = NULL;
 
-      data->state.headersize = HEADERSIZE;
-      Curl_convert_init(data);
-      Curl_initinfo(data);
-
-      /* most recent connection is not yet defined */
-      data->state.lastconnect = NULL;
-
-      data->progress.flags |= PGRS_HIDE;
-      data->state.current_speed = -1; /* init to negative == impossible */
-
-      Curl_http2_init_state(&data->state);
-    }
+    data->progress.flags |= PGRS_HIDE;
+    data->state.current_speed = -1; /* init to negative == impossible */
   }
 
   if(result) {
     Curl_resolver_cleanup(data->state.resolver);
-    free(data->state.buffer);
-    free(data->state.headerbuff);
+    Curl_dyn_free(&data->state.headerb);
     Curl_freeset(data);
     free(data);
     data = NULL;
@@ -665,15 +684,13 @@
 }
 #else  /* ! USE_RECV_BEFORE_SEND_WORKAROUND */
 /* Use "do-nothing" macro instead of function when workaround not used */
-#define conn_reset_all_postponed_data(c) do {} WHILE_FALSE
+#define conn_reset_all_postponed_data(c) do {} while(0)
 #endif /* ! USE_RECV_BEFORE_SEND_WORKAROUND */
 
 
 static void conn_shutdown(struct connectdata *conn)
 {
-  if(!conn)
-    return;
-
+  DEBUGASSERT(conn);
   infof(conn->data, "Closing connection %ld\n", conn->connection_id);
   DEBUGASSERT(conn->data);
 
@@ -694,54 +711,40 @@
     Curl_closesocket(conn, conn->tempsock[0]);
   if(CURL_SOCKET_BAD != conn->tempsock[1])
     Curl_closesocket(conn, conn->tempsock[1]);
-
-  /* unlink ourselves. this should be called last since other shutdown
-     procedures need a valid conn->data and this may clear it. */
-  Curl_conncache_remove_conn(conn->data, conn, TRUE);
 }
 
 static void conn_free(struct connectdata *conn)
 {
-  if(!conn)
-    return;
+  DEBUGASSERT(conn);
 
-  free_idnconverted_hostname(&conn->host);
-  free_idnconverted_hostname(&conn->conn_to_host);
-  free_idnconverted_hostname(&conn->http_proxy.host);
-  free_idnconverted_hostname(&conn->socks_proxy.host);
-
-  Curl_safefree(conn->user);
-  Curl_safefree(conn->passwd);
-  Curl_safefree(conn->oauth_bearer);
-  Curl_safefree(conn->options);
+  Curl_free_idnconverted_hostname(&conn->host);
+  Curl_free_idnconverted_hostname(&conn->conn_to_host);
+#ifndef CURL_DISABLE_PROXY
+  Curl_free_idnconverted_hostname(&conn->http_proxy.host);
+  Curl_free_idnconverted_hostname(&conn->socks_proxy.host);
   Curl_safefree(conn->http_proxy.user);
   Curl_safefree(conn->socks_proxy.user);
   Curl_safefree(conn->http_proxy.passwd);
   Curl_safefree(conn->socks_proxy.passwd);
-  Curl_safefree(conn->allocptr.proxyuserpwd);
-  Curl_safefree(conn->allocptr.uagent);
-  Curl_safefree(conn->allocptr.userpwd);
-  Curl_safefree(conn->allocptr.accept_encoding);
-  Curl_safefree(conn->allocptr.te);
-  Curl_safefree(conn->allocptr.rangeline);
-  Curl_safefree(conn->allocptr.ref);
-  Curl_safefree(conn->allocptr.host);
-  Curl_safefree(conn->allocptr.cookiehost);
-  Curl_safefree(conn->allocptr.rtsp_transport);
-  Curl_safefree(conn->trailer);
+  Curl_safefree(conn->http_proxy.host.rawalloc); /* http proxy name buffer */
+  Curl_safefree(conn->socks_proxy.host.rawalloc); /* socks proxy name buffer */
+  Curl_free_primary_ssl_config(&conn->proxy_ssl_config);
+#endif
+  Curl_safefree(conn->user);
+  Curl_safefree(conn->passwd);
+  Curl_safefree(conn->sasl_authzid);
+  Curl_safefree(conn->options);
+  Curl_dyn_free(&conn->trailer);
   Curl_safefree(conn->host.rawalloc); /* host name buffer */
   Curl_safefree(conn->conn_to_host.rawalloc); /* host name buffer */
   Curl_safefree(conn->hostname_resolve);
   Curl_safefree(conn->secondaryhostname);
-  Curl_safefree(conn->http_proxy.host.rawalloc); /* http proxy name buffer */
-  Curl_safefree(conn->socks_proxy.host.rawalloc); /* socks proxy name buffer */
   Curl_safefree(conn->connect_state);
 
   conn_reset_all_postponed_data(conn);
   Curl_llist_destroy(&conn->easyq, NULL);
   Curl_safefree(conn->localdev);
   Curl_free_primary_ssl_config(&conn->ssl_config);
-  Curl_free_primary_ssl_config(&conn->proxy_ssl_config);
 
 #ifdef USE_UNIX_SOCKETS
   Curl_safefree(conn->unix_domain_socket);
@@ -770,13 +773,17 @@
 CURLcode Curl_disconnect(struct Curl_easy *data,
                          struct connectdata *conn, bool dead_connection)
 {
-  if(!conn)
-    return CURLE_OK; /* this is closed and fine already */
+  /* there must be a connection to close */
+  DEBUGASSERT(conn);
 
-  if(!data) {
-    DEBUGF(infof(data, "DISCONNECT without easy handle, ignoring\n"));
-    return CURLE_OK;
-  }
+  /* it must be removed from the connection cache */
+  DEBUGASSERT(!conn->bundle);
+
+  /* there must be an associated transfer */
+  DEBUGASSERT(data);
+
+  /* the transfer must be detached from the connection */
+  DEBUGASSERT(!data->conn);
 
   /*
    * If this connection isn't marked to force-close, leave it open if there
@@ -792,16 +799,11 @@
     conn->dns_entry = NULL;
   }
 
-  Curl_hostcache_prune(data); /* kill old DNS cache entries */
-
-#if !defined(CURL_DISABLE_HTTP) && defined(USE_NTLM)
   /* Cleanup NTLM connection-related data */
   Curl_http_auth_cleanup_ntlm(conn);
-#endif
-#if !defined(CURL_DISABLE_HTTP) && defined(USE_SPNEGO)
+
   /* Cleanup NEGOTIATE connection-related data */
   Curl_http_auth_cleanup_negotiate(conn);
-#endif
 
   /* the protocol specific disconnect handler and conn_shutdown need a transfer
      for the connection! */
@@ -863,8 +865,8 @@
 
 #ifndef CURL_DISABLE_PROXY
 static bool
-proxy_info_matches(const struct proxy_info* data,
-                   const struct proxy_info* needle)
+proxy_info_matches(const struct proxy_info *data,
+                   const struct proxy_info *needle)
 {
   if((data->proxytype == needle->proxytype) &&
      (data->port == needle->port) &&
@@ -873,11 +875,59 @@
 
   return FALSE;
 }
+
+static bool
+socks_proxy_info_matches(const struct proxy_info *data,
+                         const struct proxy_info *needle)
+{
+  if(!proxy_info_matches(data, needle))
+    return FALSE;
+
+  /* the user information is case-sensitive
+     or at least it is not defined as case-insensitive
+     see https://tools.ietf.org/html/rfc3986#section-3.2.1 */
+  if((data->user == NULL) != (needle->user == NULL))
+    return FALSE;
+  /* curl_strequal does a case insentive comparison, so do not use it here! */
+  if(data->user &&
+     needle->user &&
+     strcmp(data->user, needle->user) != 0)
+    return FALSE;
+  if((data->passwd == NULL) != (needle->passwd == NULL))
+    return FALSE;
+  /* curl_strequal does a case insentive comparison, so do not use it here! */
+  if(data->passwd &&
+     needle->passwd &&
+     strcmp(data->passwd, needle->passwd) != 0)
+    return FALSE;
+  return TRUE;
+}
 #else
 /* disabled, won't get called */
 #define proxy_info_matches(x,y) FALSE
+#define socks_proxy_info_matches(x,y) FALSE
 #endif
 
+/* A connection has to have been idle for a shorter time than 'maxage_conn' to
+   be subject for reuse. The success rate is just too low after this. */
+
+static bool conn_maxage(struct Curl_easy *data,
+                        struct connectdata *conn,
+                        struct curltime now)
+{
+  if(!conn->data) {
+    timediff_t idletime = Curl_timediff(now, conn->lastused);
+    idletime /= 1000; /* integer seconds is fine */
+
+    if(idletime > data->set.maxage_conn) {
+      infof(data, "Too old connection (%ld seconds), disconnect it\n",
+            idletime);
+      return TRUE;
+    }
+  }
+  return FALSE;
+}
+
 /*
  * This function checks if the given connection is dead and extracts it from
  * the connection cache if so.
@@ -894,7 +944,11 @@
     /* The check for a dead socket makes sense only if the connection isn't in
        use */
     bool dead;
-    if(conn->handler->connection_check) {
+    struct curltime now = Curl_now();
+    if(conn_maxage(data, conn, now)) {
+      dead = TRUE;
+    }
+    else if(conn->handler->connection_check) {
       /* The protocol has a special method for checking the state of the
          connection. Use it to check if the connection is dead. */
       unsigned int state;
@@ -946,7 +1000,12 @@
 static void prune_dead_connections(struct Curl_easy *data)
 {
   struct curltime now = Curl_now();
-  time_t elapsed = Curl_timediff(now, data->state.conn_cache->last_cleanup);
+  timediff_t elapsed;
+
+  CONNCACHE_LOCK(data);
+  elapsed =
+    Curl_timediff(now, data->state.conn_cache->last_cleanup);
+  CONNCACHE_UNLOCK(data);
 
   if(elapsed >= 1000L) {
     struct prunedead prune;
@@ -954,32 +1013,20 @@
     prune.extracted = NULL;
     while(Curl_conncache_foreach(data, data->state.conn_cache, &prune,
                                  call_extract_if_dead)) {
+      /* unlocked */
+
+      /* remove connection from cache */
+      Curl_conncache_remove_conn(data, prune.extracted, TRUE);
+
       /* disconnect it */
       (void)Curl_disconnect(data, prune.extracted, /* dead_connection */TRUE);
     }
+    CONNCACHE_LOCK(data);
     data->state.conn_cache->last_cleanup = now;
+    CONNCACHE_UNLOCK(data);
   }
 }
 
-/* A connection has to have been idle for a shorter time than 'maxage_conn' to
-   be subject for reuse. The success rate is just too low after this. */
-
-static bool conn_maxage(struct Curl_easy *data,
-                        struct connectdata *conn,
-                        struct curltime now)
-{
-  if(!conn->data) {
-    timediff_t idletime = Curl_timediff(now, conn->lastused);
-    idletime /= 1000; /* integer seconds is fine */
-
-    if(idletime/1000 > data->set.maxage_conn) {
-      infof(data, "Too old connection (%ld seconds), disconnect it\n",
-            idletime);
-      return TRUE;
-    }
-  }
-  return FALSE;
-}
 /*
  * Given one filled in connection struct (named needle), this function should
  * detect if there already is one that has all the significant details
@@ -1003,16 +1050,20 @@
   bool foundPendingCandidate = FALSE;
   bool canmultiplex = IsMultiplexingPossible(data, needle);
   struct connectbundle *bundle;
-  struct curltime now = Curl_now();
+  const char *hostbundle;
 
 #ifdef USE_NTLM
   bool wantNTLMhttp = ((data->state.authhost.want &
                       (CURLAUTH_NTLM | CURLAUTH_NTLM_WB)) &&
                       (needle->handler->protocol & PROTO_FAMILY_HTTP));
+#ifndef CURL_DISABLE_PROXY
   bool wantProxyNTLMhttp = (needle->bits.proxy_user_passwd &&
                            ((data->state.authproxy.want &
                            (CURLAUTH_NTLM | CURLAUTH_NTLM_WB)) &&
                            (needle->handler->protocol & PROTO_FAMILY_HTTP)));
+#else
+  bool wantProxyNTLMhttp = FALSE;
+#endif
 #endif
 
   *force_reuse = FALSE;
@@ -1020,24 +1071,23 @@
 
   /* Look up the bundle with all the connections to this particular host.
      Locks the connection cache, beware of early returns! */
-  bundle = Curl_conncache_find_bundle(needle, data->state.conn_cache);
+  bundle = Curl_conncache_find_bundle(needle, data->state.conn_cache,
+                                      &hostbundle);
   if(bundle) {
     /* Max pipe length is zero (unlimited) for multiplexed connections */
     struct curl_llist_element *curr;
 
     infof(data, "Found bundle for host %s: %p [%s]\n",
-          (needle->bits.conn_to_host ? needle->conn_to_host.name :
-           needle->host.name), (void *)bundle,
-          (bundle->multiuse == BUNDLE_MULTIPLEX ?
-           "can multiplex" : "serially"));
+          hostbundle, (void *)bundle, (bundle->multiuse == BUNDLE_MULTIPLEX ?
+                                       "can multiplex" : "serially"));
 
     /* We can't multiplex if we don't know anything about the server */
     if(canmultiplex) {
       if(bundle->multiuse == BUNDLE_UNKNOWN) {
-        if((bundle->multiuse == BUNDLE_UNKNOWN) && data->set.pipewait) {
+        if(data->set.pipewait) {
           infof(data, "Server doesn't support multiplex yet, wait\n");
           *waitpipe = TRUE;
-          Curl_conncache_unlock(data);
+          CONNCACHE_UNLOCK(data);
           return FALSE; /* no re-use */
         }
 
@@ -1058,7 +1108,7 @@
     curr = bundle->conn_list.head;
     while(curr) {
       bool match = FALSE;
-      size_t multiplexed;
+      size_t multiplexed = 0;
 
       /*
        * Note that if we use a HTTP proxy in normal mode (no tunneling), we
@@ -1067,22 +1117,15 @@
       check = curr->ptr;
       curr = curr->next;
 
-      if(check->bits.connect_only)
-        /* connect-only connections will not be reused */
+      if(check->bits.connect_only || check->bits.close)
+        /* connect-only or to-be-closed connections will not be reused */
         continue;
 
-      if(conn_maxage(data, check, now) || extract_if_dead(check, data)) {
-        /* disconnect it */
-        (void)Curl_disconnect(data, check, /* dead_connection */TRUE);
-        continue;
-      }
-
-      multiplexed = CONN_INUSE(check) &&
-        (bundle->multiuse == BUNDLE_MULTIPLEX);
+      if(bundle->multiuse == BUNDLE_MULTIPLEX)
+        multiplexed = CONN_INUSE(check);
 
       if(canmultiplex) {
-        if(check->bits.protoconnstart && check->bits.close)
-          continue;
+        ;
       }
       else {
         if(multiplexed) {
@@ -1102,12 +1145,9 @@
           }
         }
 
-        if((check->sock[FIRSTSOCKET] == CURL_SOCKET_BAD) ||
-           check->bits.close) {
-          if(!check->bits.close)
-            foundPendingCandidate = TRUE;
-          /* Don't pick a connection that hasn't connected yet or that is going
-             to get closed. */
+        if(check->sock[FIRSTSOCKET] == CURL_SOCKET_BAD) {
+          foundPendingCandidate = TRUE;
+          /* Don't pick a connection that hasn't connected yet */
           infof(data, "Connection #%ld isn't open enough, can't reuse\n",
                 check->connection_id);
           continue;
@@ -1120,7 +1160,8 @@
           continue;
         if(strcmp(needle->unix_domain_socket, check->unix_domain_socket))
           continue;
-        if(needle->abstract_unix_socket != check->abstract_unix_socket)
+        if(needle->bits.abstract_unix_socket !=
+           check->bits.abstract_unix_socket)
           continue;
       }
       else if(check->unix_domain_socket)
@@ -1131,18 +1172,20 @@
          (check->handler->flags&PROTOPT_SSL))
         /* don't do mixed SSL and non-SSL connections */
         if(get_protocol_family(check->handler->protocol) !=
-           needle->handler->protocol || !check->tls_upgraded)
+           needle->handler->protocol || !check->bits.tls_upgraded)
           /* except protocols that have been upgraded via TLS */
           continue;
 
+#ifndef CURL_DISABLE_PROXY
       if(needle->bits.httpproxy != check->bits.httpproxy ||
          needle->bits.socksproxy != check->bits.socksproxy)
         continue;
 
-      if(needle->bits.socksproxy && !proxy_info_matches(&needle->socks_proxy,
-                                                        &check->socks_proxy))
+      if(needle->bits.socksproxy &&
+        !socks_proxy_info_matches(&needle->socks_proxy,
+                                  &check->socks_proxy))
         continue;
-
+#endif
       if(needle->bits.conn_to_host != check->bits.conn_to_host)
         /* don't mix connections that use the "connect to host" feature and
          * connections that don't use this feature */
@@ -1153,6 +1196,7 @@
          * connections that don't use this feature */
         continue;
 
+#ifndef CURL_DISABLE_PROXY
       if(needle->bits.httpproxy) {
         if(!proxy_info_matches(&needle->http_proxy, &check->http_proxy))
           continue;
@@ -1179,14 +1223,16 @@
           }
         }
       }
+#endif
+
+      DEBUGASSERT(!check->data || GOOD_EASY_HANDLE(check->data));
 
       if(!canmultiplex && check->data)
         /* this request can't be multiplexed but the checked connection is
            already in use so we skip it */
         continue;
 
-      if(CONN_INUSE(check) && check->data &&
-         (check->data->multi != needle->data->multi))
+      if(check->data && (check->data->multi != needle->data->multi))
         /* this could be subject for multiplex use, but only if they belong to
          * the same multi handle */
         continue;
@@ -1220,22 +1266,25 @@
         }
       }
 
-      if(!needle->bits.httpproxy || (needle->handler->flags&PROTOPT_SSL) ||
-         needle->bits.tunnel_proxy) {
+      if((needle->handler->flags&PROTOPT_SSL)
+#ifndef CURL_DISABLE_PROXY
+         || !needle->bits.httpproxy || needle->bits.tunnel_proxy
+#endif
+        ) {
         /* The requested connection does not use a HTTP proxy or it uses SSL or
            it is a non-SSL protocol tunneled or it is a non-SSL protocol which
            is allowed to be upgraded via TLS */
 
         if((strcasecompare(needle->handler->scheme, check->handler->scheme) ||
             (get_protocol_family(check->handler->protocol) ==
-             needle->handler->protocol && check->tls_upgraded)) &&
+             needle->handler->protocol && check->bits.tls_upgraded)) &&
            (!needle->bits.conn_to_host || strcasecompare(
             needle->conn_to_host.name, check->conn_to_host.name)) &&
            (!needle->bits.conn_to_port ||
              needle->conn_to_port == check->conn_to_port) &&
            strcasecompare(needle->host.name, check->host.name) &&
            needle->remote_port == check->remote_port) {
-          /* The schemes match or the the protocol family is the same and the
+          /* The schemes match or the protocol family is the same and the
              previous connection was TLS upgraded, and the hostname and host
              port match */
           if(needle->handler->flags & PROTOPT_SSL) {
@@ -1276,14 +1325,21 @@
            partway through a handshake!) */
         if(wantNTLMhttp) {
           if(strcmp(needle->user, check->user) ||
-             strcmp(needle->passwd, check->passwd))
+             strcmp(needle->passwd, check->passwd)) {
+
+            /* we prefer a credential match, but this is at least a connection
+               that can be reused and "upgraded" to NTLM */
+            if(check->http_ntlm_state == NTLMSTATE_NONE)
+              chosen = check;
             continue;
+          }
         }
         else if(check->http_ntlm_state != NTLMSTATE_NONE) {
           /* Connection is using NTLM auth but we don't want NTLM */
           continue;
         }
 
+#ifndef CURL_DISABLE_PROXY
         /* Same for Proxy NTLM authentication */
         if(wantProxyNTLMhttp) {
           /* Both check->http_proxy.user and check->http_proxy.passwd can be
@@ -1299,7 +1355,7 @@
           /* Proxy connection is using NTLM auth but we don't want NTLM */
           continue;
         }
-
+#endif
         if(wantNTLMhttp || wantProxyNTLMhttp) {
           /* Credentials are already checked, we can use this connection */
           chosen = check;
@@ -1337,6 +1393,13 @@
                     multiplexed);
               continue;
             }
+            else if(multiplexed >=
+                    Curl_multi_max_concurrent_streams(needle->data->multi)) {
+              infof(data, "client side MAX_CONCURRENT_STREAMS reached"
+                    ", skip (%zu)\n",
+                    multiplexed);
+              continue;
+            }
           }
 #endif
           /* When not multiplexed, we have a match here! */
@@ -1356,11 +1419,12 @@
   if(chosen) {
     /* mark it as used before releasing the lock */
     chosen->data = data; /* own it! */
-    Curl_conncache_unlock(data);
+    Curl_attach_connnection(data, chosen);
+    CONNCACHE_UNLOCK(data);
     *usethis = chosen;
     return TRUE; /* yes, we found one to use! */
   }
-  Curl_conncache_unlock(data);
+  CONNCACHE_UNLOCK(data);
 
   if(foundPendingCandidate && data->set.pipewait) {
     infof(data,
@@ -1371,58 +1435,6 @@
   return FALSE; /* no matching connecting exists */
 }
 
-/* after a TCP connection to the proxy has been verified, this function does
-   the next magic step.
-
-   Note: this function's sub-functions call failf()
-
-*/
-CURLcode Curl_connected_proxy(struct connectdata *conn, int sockindex)
-{
-  CURLcode result = CURLE_OK;
-
-  if(conn->bits.socksproxy) {
-#ifndef CURL_DISABLE_PROXY
-    /* for the secondary socket (FTP), use the "connect to host"
-     * but ignore the "connect to port" (use the secondary port)
-     */
-    const char * const host = conn->bits.httpproxy ?
-                              conn->http_proxy.host.name :
-                              conn->bits.conn_to_host ?
-                              conn->conn_to_host.name :
-                              sockindex == SECONDARYSOCKET ?
-                              conn->secondaryhostname : conn->host.name;
-    const int port = conn->bits.httpproxy ? (int)conn->http_proxy.port :
-                     sockindex == SECONDARYSOCKET ? conn->secondary_port :
-                     conn->bits.conn_to_port ? conn->conn_to_port :
-                     conn->remote_port;
-    conn->bits.socksproxy_connecting = TRUE;
-    switch(conn->socks_proxy.proxytype) {
-    case CURLPROXY_SOCKS5:
-    case CURLPROXY_SOCKS5_HOSTNAME:
-      result = Curl_SOCKS5(conn->socks_proxy.user, conn->socks_proxy.passwd,
-                         host, port, sockindex, conn);
-      break;
-
-    case CURLPROXY_SOCKS4:
-    case CURLPROXY_SOCKS4A:
-      result = Curl_SOCKS4(conn->socks_proxy.user, host, port, sockindex,
-                           conn);
-      break;
-
-    default:
-      failf(conn->data, "unknown proxytype option given");
-      result = CURLE_COULDNT_CONNECT;
-    } /* switch proxytype */
-    conn->bits.socksproxy_connecting = FALSE;
-#else
-  (void)sockindex;
-#endif /* CURL_DISABLE_PROXY */
-  }
-
-  return result;
-}
-
 /*
  * verboseconnect() displays verbose information after a connect
  */
@@ -1431,142 +1443,27 @@
 {
   if(conn->data->set.verbose)
     infof(conn->data, "Connected to %s (%s) port %ld (#%ld)\n",
+#ifndef CURL_DISABLE_PROXY
           conn->bits.socksproxy ? conn->socks_proxy.host.dispname :
           conn->bits.httpproxy ? conn->http_proxy.host.dispname :
+#endif
           conn->bits.conn_to_host ? conn->conn_to_host.dispname :
           conn->host.dispname,
           conn->ip_addr_str, conn->port, conn->connection_id);
 }
 #endif
 
-int Curl_protocol_getsock(struct connectdata *conn,
-                          curl_socket_t *socks,
-                          int numsocks)
-{
-  if(conn->handler->proto_getsock)
-    return conn->handler->proto_getsock(conn, socks, numsocks);
-  /* Backup getsock logic. Since there is a live socket in use, we must wait
-     for it or it will be removed from watching when the multi_socket API is
-     used. */
-  socks[0] = conn->sock[FIRSTSOCKET];
-  return GETSOCK_READSOCK(0) | GETSOCK_WRITESOCK(0);
-}
-
-int Curl_doing_getsock(struct connectdata *conn,
-                       curl_socket_t *socks,
-                       int numsocks)
-{
-  if(conn && conn->handler->doing_getsock)
-    return conn->handler->doing_getsock(conn, socks, numsocks);
-  return GETSOCK_BLANK;
-}
-
-/*
- * We are doing protocol-specific connecting and this is being called over and
- * over from the multi interface until the connection phase is done on
- * protocol layer.
- */
-
-CURLcode Curl_protocol_connecting(struct connectdata *conn,
-                                  bool *done)
-{
-  CURLcode result = CURLE_OK;
-
-  if(conn && conn->handler->connecting) {
-    *done = FALSE;
-    result = conn->handler->connecting(conn, done);
-  }
-  else
-    *done = TRUE;
-
-  return result;
-}
-
-/*
- * We are DOING this is being called over and over from the multi interface
- * until the DOING phase is done on protocol layer.
- */
-
-CURLcode Curl_protocol_doing(struct connectdata *conn, bool *done)
-{
-  CURLcode result = CURLE_OK;
-
-  if(conn && conn->handler->doing) {
-    *done = FALSE;
-    result = conn->handler->doing(conn, done);
-  }
-  else
-    *done = TRUE;
-
-  return result;
-}
-
-/*
- * We have discovered that the TCP connection has been successful, we can now
- * proceed with some action.
- *
- */
-CURLcode Curl_protocol_connect(struct connectdata *conn,
-                               bool *protocol_done)
-{
-  CURLcode result = CURLE_OK;
-
-  *protocol_done = FALSE;
-
-  if(conn->bits.tcpconnect[FIRSTSOCKET] && conn->bits.protoconnstart) {
-    /* We already are connected, get back. This may happen when the connect
-       worked fine in the first call, like when we connect to a local server
-       or proxy. Note that we don't know if the protocol is actually done.
-
-       Unless this protocol doesn't have any protocol-connect callback, as
-       then we know we're done. */
-    if(!conn->handler->connecting)
-      *protocol_done = TRUE;
-
-    return CURLE_OK;
-  }
-
-  if(!conn->bits.protoconnstart) {
-
-    result = Curl_proxy_connect(conn, FIRSTSOCKET);
-    if(result)
-      return result;
-
-    if(CONNECT_FIRSTSOCKET_PROXY_SSL())
-      /* wait for HTTPS proxy SSL initialization to complete */
-      return CURLE_OK;
-
-    if(conn->bits.tunnel_proxy && conn->bits.httpproxy &&
-       Curl_connect_ongoing(conn))
-      /* when using an HTTP tunnel proxy, await complete tunnel establishment
-         before proceeding further. Return CURLE_OK so we'll be called again */
-      return CURLE_OK;
-
-    if(conn->handler->connect_it) {
-      /* is there a protocol-specific connect() procedure? */
-
-      /* Call the protocol-specific connect function */
-      result = conn->handler->connect_it(conn, protocol_done);
-    }
-    else
-      *protocol_done = TRUE;
-
-    /* it has started, possibly even completed but that knowledge isn't stored
-       in this bit! */
-    if(!result)
-      conn->bits.protoconnstart = TRUE;
-  }
-
-  return result; /* pass back status */
-}
-
 /*
  * Helpers for IDNA conversions.
  */
-static bool is_ASCII_name(const char *hostname)
+bool Curl_is_ASCII_name(const char *hostname)
 {
+  /* get an UNSIGNED local version of the pointer */
   const unsigned char *ch = (const unsigned char *)hostname;
 
+  if(!hostname) /* bad input, consider it ASCII! */
+    return TRUE;
+
   while(*ch) {
     if(*ch++ & 0x80)
       return FALSE;
@@ -1591,8 +1488,8 @@
 /*
  * Perform any necessary IDN conversion of hostname
  */
-static CURLcode idnconvert_hostname(struct connectdata *conn,
-                                    struct hostname *host)
+CURLcode Curl_idnconvert_hostname(struct connectdata *conn,
+                                  struct hostname *host)
 {
   struct Curl_easy *data = conn->data;
 
@@ -1607,7 +1504,7 @@
   host->dispname = host->name;
 
   /* Check name for non-ASCII and convert hostname to ACE form if we can */
-  if(!is_ASCII_name(host->name)) {
+  if(!Curl_is_ASCII_name(host->name)) {
 #ifdef USE_LIBIDN2
     if(idn2_check_version(IDN2_VERSION)) {
       char *ace_hostname = NULL;
@@ -1640,7 +1537,9 @@
       host->name = host->encalloc;
     }
     else {
-      failf(data, "Failed to convert %s to ACE;\n", host->name);
+      char buffer[STRERROR_LEN];
+      failf(data, "Failed to convert %s to ACE; %s\n", host->name,
+            Curl_winapi_strerror(GetLastError(), buffer, sizeof(buffer)));
       return CURLE_URL_MALFORMAT;
     }
 #else
@@ -1653,7 +1552,7 @@
 /*
  * Frees data allocated by idnconvert_hostname()
  */
-static void free_idnconverted_hostname(struct hostname *host)
+void Curl_free_idnconverted_hostname(struct hostname *host)
 {
 #if defined(USE_LIBIDN2)
   if(host->encalloc) {
@@ -1670,13 +1569,6 @@
 #endif
 }
 
-static void llist_dtor(void *user, void *element)
-{
-  (void)user;
-  (void)element;
-  /* Do nothing */
-}
-
 /*
  * Allocate and initialize a new connectdata object.
  */
@@ -1701,8 +1593,10 @@
     conn->ssl_extra = ssl;
     conn->ssl[0].backend = (void *)ssl;
     conn->ssl[1].backend = (void *)(ssl + sslsize);
+#ifndef CURL_DISABLE_PROXY
     conn->proxy_ssl[0].backend = (void *)(ssl + 2 * sslsize);
     conn->proxy_ssl[1].backend = (void *)(ssl + 3 * sslsize);
+#endif
   }
 #endif
 
@@ -1741,10 +1635,10 @@
   conn->data = data; /* Setup the association between this connection
                         and the Curl_easy */
 
+#ifndef CURL_DISABLE_PROXY
   conn->http_proxy.proxytype = data->set.proxytype;
   conn->socks_proxy.proxytype = CURLPROXY_SOCKS4;
 
-#if !defined(CURL_DISABLE_PROXY)
   /* note that these two proxy bits are now just on what looks to be
      requested, they may be altered down the road */
   conn->bits.proxy = (data->set.str[STRING_PROXY] &&
@@ -1775,20 +1669,24 @@
   conn->ssl_config.verifystatus = data->set.ssl.primary.verifystatus;
   conn->ssl_config.verifypeer = data->set.ssl.primary.verifypeer;
   conn->ssl_config.verifyhost = data->set.ssl.primary.verifyhost;
+#ifndef CURL_DISABLE_PROXY
   conn->proxy_ssl_config.verifystatus =
     data->set.proxy_ssl.primary.verifystatus;
   conn->proxy_ssl_config.verifypeer = data->set.proxy_ssl.primary.verifypeer;
   conn->proxy_ssl_config.verifyhost = data->set.proxy_ssl.primary.verifyhost;
+#endif
   conn->ip_version = data->set.ipver;
   conn->bits.connect_only = data->set.connect_only;
+  conn->transport = TRNSPRT_TCP; /* most of them are TCP streams */
 
 #if !defined(CURL_DISABLE_HTTP) && defined(USE_NTLM) && \
     defined(NTLM_WB_ENABLED)
-  conn->ntlm_auth_hlpr_socket = CURL_SOCKET_BAD;
+  conn->ntlm.ntlm_auth_hlpr_socket = CURL_SOCKET_BAD;
+  conn->proxyntlm.ntlm_auth_hlpr_socket = CURL_SOCKET_BAD;
 #endif
 
   /* Initialize the easy handle list */
-  Curl_llist_init(&conn->easyq, (curl_llist_dtor) llist_dtor);
+  Curl_llist_init(&conn->easyq, NULL);
 
 #ifdef HAVE_GSSAPI
   conn->data_prot = PROT_CLEAR;
@@ -1807,6 +1705,7 @@
      it may live on without (this specific) Curl_easy */
   conn->fclosesocket = data->set.fclosesocket;
   conn->closesocket_client = data->set.closesocket_client;
+  conn->lastused = Curl_now(); /* used now */
 
   return conn;
   error:
@@ -1884,6 +1783,50 @@
 }
 
 /*
+ * If the URL was set with an IPv6 numerical address with a zone id part, set
+ * the scope_id based on that!
+ */
+
+static void zonefrom_url(CURLU *uh, struct connectdata *conn)
+{
+  char *zoneid;
+  CURLUcode uc;
+
+  uc = curl_url_get(uh, CURLUPART_ZONEID, &zoneid, 0);
+
+  if(!uc && zoneid) {
+    char *endp;
+    unsigned long scope = strtoul(zoneid, &endp, 10);
+    if(!*endp && (scope < UINT_MAX))
+      /* A plain number, use it directly as a scope id. */
+      conn->scope_id = (unsigned int)scope;
+#if defined(HAVE_IF_NAMETOINDEX)
+    else {
+#elif defined(WIN32)
+    else if(Curl_if_nametoindex) {
+#endif
+
+#if defined(HAVE_IF_NAMETOINDEX) || defined(WIN32)
+      /* Zone identifier is not numeric */
+      unsigned int scopeidx = 0;
+#if defined(WIN32)
+      scopeidx = Curl_if_nametoindex(zoneid);
+#else
+      scopeidx = if_nametoindex(zoneid);
+#endif
+      if(!scopeidx)
+        infof(conn->data, "Invalid zoneid: %s; %s\n", zoneid,
+              strerror(errno));
+      else
+        conn->scope_id = scopeidx;
+    }
+#endif /* HAVE_IF_NAMETOINDEX || WIN32 */
+
+    free(zoneid);
+  }
+}
+
+/*
  * Parse URL and fill in the relevant members of the connection struct.
  */
 static CURLcode parseurlandfillconn(struct Curl_easy *data,
@@ -1921,6 +1864,7 @@
   }
 
   if(!data->set.uh) {
+    char *newurl;
     uc = curl_url_set(uh, CURLUPART_URL, data->change.url,
                     CURLU_GUESS_SCHEME |
                     CURLU_NON_SUPPORT_SCHEME |
@@ -1931,6 +1875,15 @@
       DEBUGF(infof(data, "curl_url_set rejected %s\n", data->change.url));
       return Curl_uc_to_curlcode(uc);
     }
+
+    /* after it was parsed, get the generated normalized version */
+    uc = curl_url_get(uh, CURLUPART_URL, &newurl, 0);
+    if(uc)
+      return Curl_uc_to_curlcode(uc);
+    if(data->change.url_alloc)
+      free(data->change.url);
+    data->change.url = newurl;
+    data->change.url_alloc = TRUE;
   }
 
   uc = curl_url_get(uh, CURLUPART_SCHEME, &data->state.up.scheme, 0);
@@ -1941,23 +1894,32 @@
   if(result)
     return result;
 
-  uc = curl_url_get(uh, CURLUPART_USER, &data->state.up.user,
-                    CURLU_URLDECODE);
+  /* we don't use the URL API's URL decoder option here since it rejects
+     control codes and we want to allow them for some schemes in the user and
+     password fields */
+  uc = curl_url_get(uh, CURLUPART_USER, &data->state.up.user, 0);
   if(!uc) {
-    conn->user = strdup(data->state.up.user);
-    if(!conn->user)
-      return CURLE_OUT_OF_MEMORY;
+    char *decoded;
+    result = Curl_urldecode(NULL, data->state.up.user, 0, &decoded, NULL,
+                            conn->handler->flags&PROTOPT_USERPWDCTRL ?
+                            REJECT_ZERO : REJECT_CTRL);
+    if(result)
+      return result;
+    conn->user = decoded;
     conn->bits.user_passwd = TRUE;
   }
   else if(uc != CURLUE_NO_USER)
     return Curl_uc_to_curlcode(uc);
 
-  uc = curl_url_get(uh, CURLUPART_PASSWORD, &data->state.up.password,
-                    CURLU_URLDECODE);
+  uc = curl_url_get(uh, CURLUPART_PASSWORD, &data->state.up.password, 0);
   if(!uc) {
-    conn->passwd = strdup(data->state.up.password);
-    if(!conn->passwd)
-      return CURLE_OUT_OF_MEMORY;
+    char *decoded;
+    result = Curl_urldecode(NULL, data->state.up.password, 0, &decoded, NULL,
+                            conn->handler->flags&PROTOPT_USERPWDCTRL ?
+                            REJECT_ZERO : REJECT_CTRL);
+    if(result)
+      return result;
+    conn->passwd = decoded;
     conn->bits.user_passwd = TRUE;
   }
   else if(uc != CURLUE_NO_PASSWORD)
@@ -1991,55 +1953,27 @@
   }
   else {
     unsigned long port = strtoul(data->state.up.port, NULL, 10);
-    conn->remote_port = curlx_ultous(port);
+    conn->port = conn->remote_port = curlx_ultous(port);
   }
 
   (void)curl_url_get(uh, CURLUPART_QUERY, &data->state.up.query, 0);
 
   hostname = data->state.up.hostname;
-  if(!hostname)
-    /* this is for file:// transfers, get a dummy made */
-    hostname = (char *)"";
-
-  if(hostname[0] == '[') {
+  if(hostname && hostname[0] == '[') {
     /* This looks like an IPv6 address literal. See if there is an address
        scope. */
-    char *zoneid;
     size_t hlen;
-    uc = curl_url_get(uh, CURLUPART_ZONEID, &zoneid, 0);
     conn->bits.ipv6_ip = TRUE;
-
     /* cut off the brackets! */
     hostname++;
     hlen = strlen(hostname);
     hostname[hlen - 1] = 0;
-    if(!uc && zoneid) {
-      char *endp;
-      unsigned long scope;
-      scope = strtoul(zoneid, &endp, 10);
-      if(!*endp && (scope < UINT_MAX)) {
-        /* A plain number, use it direcly as a scope id. */
-        conn->scope_id = (unsigned int)scope;
-      }
-#ifdef HAVE_IF_NAMETOINDEX
-      else {
-        /* Zone identifier is not numeric */
-        unsigned int scopeidx = 0;
-        scopeidx = if_nametoindex(zoneid);
-        if(!scopeidx)
-          infof(data, "Invalid zoneid id: %s; %s\n", zoneid,
-                strerror(errno));
-        else
-          conn->scope_id = scopeidx;
 
-      }
-#endif /* HAVE_IF_NAMETOINDEX */
-      free(zoneid);
-    }
+    zonefrom_url(uh, conn);
   }
 
   /* make sure the connect struct gets its own copy of the host name */
-  conn->host.rawalloc = strdup(hostname);
+  conn->host.rawalloc = strdup(hostname ? hostname : "");
   if(!conn->host.rawalloc)
     return CURLE_OUT_OF_MEMORY;
   conn->host.name = conn->host.rawalloc;
@@ -2095,9 +2029,8 @@
  */
 static CURLcode setup_connection_internals(struct connectdata *conn)
 {
-  const struct Curl_handler * p;
+  const struct Curl_handler *p;
   CURLcode result;
-  conn->socktype = SOCK_STREAM; /* most of them are TCP streams */
 
   /* Perform setup complement if some. */
   p = conn->handler;
@@ -2128,6 +2061,11 @@
 {
   Curl_safefree(data->req.protop);
   Curl_safefree(data->req.newurl);
+
+#ifndef CURL_DISABLE_DOH
+  Curl_close(&data->req.doh.probe[0].easy);
+  Curl_close(&data->req.doh.probe[1].easy);
+#endif
 }
 
 
@@ -2298,7 +2236,7 @@
                             struct connectdata *conn, char *proxy,
                             curl_proxytype proxytype)
 {
-  char *portptr;
+  char *portptr = NULL;
   long port = -1;
   char *proxyuser = NULL;
   char *proxypasswd = NULL;
@@ -2422,6 +2360,7 @@
     size_t len = strlen(host);
     host[len-1] = 0; /* clear the trailing bracket */
     host++;
+    zonefrom_url(uhp, conn);
   }
   proxyinfo->host.name = host;
 
@@ -2437,26 +2376,16 @@
 static CURLcode parse_proxy_auth(struct Curl_easy *data,
                                  struct connectdata *conn)
 {
-  char proxyuser[MAX_CURL_USER_LENGTH]="";
-  char proxypasswd[MAX_CURL_PASSWORD_LENGTH]="";
-  CURLcode result;
+  char *proxyuser = data->set.str[STRING_PROXYUSERNAME];
+  char *proxypasswd = data->set.str[STRING_PROXYPASSWORD];
+  CURLcode result = CURLE_OK;
 
-  if(data->set.str[STRING_PROXYUSERNAME] != NULL) {
-    strncpy(proxyuser, data->set.str[STRING_PROXYUSERNAME],
-            MAX_CURL_USER_LENGTH);
-    proxyuser[MAX_CURL_USER_LENGTH-1] = '\0';   /*To be on safe side*/
-  }
-  if(data->set.str[STRING_PROXYPASSWORD] != NULL) {
-    strncpy(proxypasswd, data->set.str[STRING_PROXYPASSWORD],
-            MAX_CURL_PASSWORD_LENGTH);
-    proxypasswd[MAX_CURL_PASSWORD_LENGTH-1] = '\0'; /*To be on safe side*/
-  }
-
-  result = Curl_urldecode(data, proxyuser, 0, &conn->http_proxy.user, NULL,
-                          FALSE);
-  if(!result)
+  if(proxyuser)
+    result = Curl_urldecode(data, proxyuser, 0, &conn->http_proxy.user, NULL,
+                            REJECT_ZERO);
+  if(!result && proxypasswd)
     result = Curl_urldecode(data, proxypasswd, 0, &conn->http_proxy.passwd,
-                            NULL, FALSE);
+                            NULL, REJECT_ZERO);
   return result;
 }
 
@@ -2674,6 +2603,12 @@
   size_t plen;
   size_t olen;
 
+  /* the input length check is because this is called directcly from setopt
+     and isn't going through the regular string length check */
+  size_t llen = strlen(login);
+  if(llen > CURL_MAX_INPUT_LENGTH)
+    return CURLE_BAD_FUNCTION_ARGUMENT;
+
   /* Attempt to find the password separator */
   if(passwdp) {
     psep = strchr(login, ':');
@@ -2846,8 +2781,7 @@
                           &netrc_user_changed, &netrc_passwd_changed,
                           data->set.str[STRING_NETRC_FILE]);
     if(ret > 0) {
-      infof(data, "Couldn't find host %s in the "
-            DOT_CHAR "netrc file; using defaults\n",
+      infof(data, "Couldn't find host %s in the .netrc file; using defaults\n",
             conn->host.name);
     }
     else if(ret < 0) {
@@ -2871,12 +2805,14 @@
 
   /* for updated strings, we update them in the URL */
   if(user_changed) {
-    uc = curl_url_set(data->state.uh, CURLUPART_USER, *userp, 0);
+    uc = curl_url_set(data->state.uh, CURLUPART_USER, *userp,
+                      CURLU_URLENCODE);
     if(uc)
       return Curl_uc_to_curlcode(uc);
   }
   if(passwd_changed) {
-    uc = curl_url_set(data->state.uh, CURLUPART_PASSWORD, *passwdp, 0);
+    uc = curl_url_set(data->state.uh, CURLUPART_PASSWORD, *passwdp,
+                      CURLU_URLENCODE);
     if(uc)
       return Curl_uc_to_curlcode(uc);
   }
@@ -2913,13 +2849,6 @@
       result = CURLE_OUT_OF_MEMORY;
   }
 
-  /* if there's a user without password, consider password blank */
-  if(conn->user && !conn->passwd) {
-    conn->passwd = strdup("");
-    if(!conn->passwd)
-      result = CURLE_OUT_OF_MEMORY;
-  }
-
   return result;
 }
 
@@ -3142,28 +3071,74 @@
 
 #ifdef USE_ALTSVC
   if(data->asi && !host && (port == -1) &&
-     (conn->handler->protocol == CURLPROTO_HTTPS)) {
+     ((conn->handler->protocol == CURLPROTO_HTTPS) ||
+#ifdef CURLDEBUG
+      /* allow debug builds to circumvent the HTTPS restriction */
+      getenv("CURL_ALTSVC_HTTP")
+#else
+      0
+#endif
+       )) {
     /* no connect_to match, try alt-svc! */
-    const char *nhost;
-    int nport;
-    enum alpnid nalpnid;
+    enum alpnid srcalpnid;
     bool hit;
+    struct altsvc *as;
+    const int allowed_versions = ( ALPN_h1
+#ifdef USE_NGHTTP2
+      | ALPN_h2
+#endif
+#ifdef ENABLE_QUIC
+      | ALPN_h3
+#endif
+      ) & data->asi->flags;
+
     host = conn->host.rawalloc;
+#ifdef USE_NGHTTP2
+    /* with h2 support, check that first */
+    srcalpnid = ALPN_h2;
     hit = Curl_altsvc_lookup(data->asi,
-                             ALPN_h1, host, conn->remote_port, /* from */
-                             &nalpnid, &nhost, &nport /* to */);
+                             srcalpnid, host, conn->remote_port, /* from */
+                             &as /* to */,
+                             allowed_versions);
+    if(!hit)
+#endif
+    {
+      srcalpnid = ALPN_h1;
+      hit = Curl_altsvc_lookup(data->asi,
+                               srcalpnid, host, conn->remote_port, /* from */
+                               &as /* to */,
+                               allowed_versions);
+    }
     if(hit) {
-      char *hostd = strdup((char *)nhost);
+      char *hostd = strdup((char *)as->dst.host);
       if(!hostd)
         return CURLE_OUT_OF_MEMORY;
       conn->conn_to_host.rawalloc = hostd;
       conn->conn_to_host.name = hostd;
       conn->bits.conn_to_host = TRUE;
-      conn->conn_to_port = nport;
+      conn->conn_to_port = as->dst.port;
       conn->bits.conn_to_port = TRUE;
+      conn->bits.altused = TRUE;
       infof(data, "Alt-svc connecting from [%s]%s:%d to [%s]%s:%d\n",
-            Curl_alpnid2str(ALPN_h1), host, conn->remote_port,
-            Curl_alpnid2str(nalpnid), hostd, nport);
+            Curl_alpnid2str(srcalpnid), host, conn->remote_port,
+            Curl_alpnid2str(as->dst.alpnid), hostd, as->dst.port);
+      if(srcalpnid != as->dst.alpnid) {
+        /* protocol version switch */
+        switch(as->dst.alpnid) {
+        case ALPN_h1:
+          conn->httpversion = 11;
+          break;
+        case ALPN_h2:
+          conn->httpversion = 20;
+          break;
+        case ALPN_h3:
+          conn->transport = TRNSPRT_QUIC;
+          conn->httpversion = 30;
+          break;
+        default: /* shouldn't be possible */
+          break;
+        }
+      }
     }
   }
 #endif
@@ -3210,7 +3185,7 @@
       else {
         bool longpath = FALSE;
         hostaddr->addr = Curl_unix2addr(path, &longpath,
-                                        conn->abstract_unix_socket);
+                                        conn->bits.abstract_unix_socket);
         if(hostaddr->addr)
           hostaddr->inuse++;
         else {
@@ -3228,6 +3203,7 @@
     }
     else
 #endif
+
     if(!conn->bits.proxy) {
       struct hostname *connhost;
       if(conn->bits.conn_to_host)
@@ -3256,10 +3232,11 @@
 
       else if(!hostaddr) {
         failf(data, "Couldn't resolve host '%s'", connhost->dispname);
-        result =  CURLE_COULDNT_RESOLVE_HOST;
+        result = CURLE_COULDNT_RESOLVE_HOST;
         /* don't return yet, we need to clean up the timeout first */
       }
     }
+#ifndef CURL_DISABLE_PROXY
     else {
       /* This is a proxy that hasn't been resolved yet. */
 
@@ -3285,6 +3262,7 @@
         /* don't return yet, we need to clean up the timeout first */
       }
     }
+#endif
     DEBUGASSERT(conn->dns_entry == NULL);
     conn->dns_entry = hostaddr;
   }
@@ -3300,16 +3278,17 @@
 static void reuse_conn(struct connectdata *old_conn,
                        struct connectdata *conn)
 {
-  free_idnconverted_hostname(&old_conn->http_proxy.host);
-  free_idnconverted_hostname(&old_conn->socks_proxy.host);
+#ifndef CURL_DISABLE_PROXY
+  Curl_free_idnconverted_hostname(&old_conn->http_proxy.host);
+  Curl_free_idnconverted_hostname(&old_conn->socks_proxy.host);
 
   free(old_conn->http_proxy.host.rawalloc);
   free(old_conn->socks_proxy.host.rawalloc);
-
+  Curl_free_primary_ssl_config(&old_conn->proxy_ssl_config);
+#endif
   /* free the SSL config struct from this connection struct as this was
      allocated in vain and is targeted for destruction */
   Curl_free_primary_ssl_config(&old_conn->ssl_config);
-  Curl_free_primary_ssl_config(&old_conn->proxy_ssl_config);
 
   conn->data = old_conn->data;
 
@@ -3326,6 +3305,7 @@
     old_conn->passwd = NULL;
   }
 
+#ifndef CURL_DISABLE_PROXY
   conn->bits.proxy_user_passwd = old_conn->bits.proxy_user_passwd;
   if(conn->bits.proxy_user_passwd) {
     /* use the new proxy user name and proxy password though */
@@ -3342,11 +3322,16 @@
     old_conn->http_proxy.passwd = NULL;
     old_conn->socks_proxy.passwd = NULL;
   }
+  Curl_safefree(old_conn->http_proxy.user);
+  Curl_safefree(old_conn->socks_proxy.user);
+  Curl_safefree(old_conn->http_proxy.passwd);
+  Curl_safefree(old_conn->socks_proxy.passwd);
+#endif
 
   /* host can change, when doing keepalive with a proxy or if the case is
      different this time etc */
-  free_idnconverted_hostname(&conn->host);
-  free_idnconverted_hostname(&conn->conn_to_host);
+  Curl_free_idnconverted_hostname(&conn->host);
+  Curl_free_idnconverted_hostname(&conn->conn_to_host);
   Curl_safefree(conn->host.rawalloc);
   Curl_safefree(conn->conn_to_host.rawalloc);
   conn->host = old_conn->host;
@@ -3369,10 +3354,6 @@
   Curl_safefree(old_conn->user);
   Curl_safefree(old_conn->passwd);
   Curl_safefree(old_conn->options);
-  Curl_safefree(old_conn->http_proxy.user);
-  Curl_safefree(old_conn->socks_proxy.user);
-  Curl_safefree(old_conn->http_proxy.passwd);
-  Curl_safefree(old_conn->socks_proxy.passwd);
   Curl_safefree(old_conn->localdev);
   Curl_llist_destroy(&old_conn->easyq, NULL);
 
@@ -3442,9 +3423,9 @@
   if(result)
     goto out;
 
-  if(data->set.str[STRING_BEARER]) {
-    conn->oauth_bearer = strdup(data->set.str[STRING_BEARER]);
-    if(!conn->oauth_bearer) {
+  if(data->set.str[STRING_SASL_AUTHZID]) {
+    conn->sasl_authzid = strdup(data->set.str[STRING_SASL_AUTHZID]);
+    if(!conn->sasl_authzid) {
       result = CURLE_OUT_OF_MEMORY;
       goto out;
     }
@@ -3457,7 +3438,7 @@
       result = CURLE_OUT_OF_MEMORY;
       goto out;
     }
-    conn->abstract_unix_socket = data->set.abstract_unix_socket;
+    conn->bits.abstract_unix_socket = data->set.abstract_unix_socket;
   }
 #endif
 
@@ -3467,7 +3448,6 @@
   result = create_conn_helper_init_proxy(conn);
   if(result)
     goto out;
-#endif
 
   /*************************************************************
    * If the protocol is using SSL and HTTP proxy is used, we set
@@ -3475,6 +3455,7 @@
    *************************************************************/
   if((conn->given->flags&PROTOPT_SSL) && conn->bits.httpproxy)
     conn->bits.tunnel_proxy = TRUE;
+#endif
 
   /*************************************************************
    * Figure out the remote port number and fix it in the URL
@@ -3505,24 +3486,26 @@
   /*************************************************************
    * IDN-convert the hostnames
    *************************************************************/
-  result = idnconvert_hostname(conn, &conn->host);
+  result = Curl_idnconvert_hostname(conn, &conn->host);
   if(result)
     goto out;
   if(conn->bits.conn_to_host) {
-    result = idnconvert_hostname(conn, &conn->conn_to_host);
+    result = Curl_idnconvert_hostname(conn, &conn->conn_to_host);
     if(result)
       goto out;
   }
+#ifndef CURL_DISABLE_PROXY
   if(conn->bits.httpproxy) {
-    result = idnconvert_hostname(conn, &conn->http_proxy.host);
+    result = Curl_idnconvert_hostname(conn, &conn->http_proxy.host);
     if(result)
       goto out;
   }
   if(conn->bits.socksproxy) {
-    result = idnconvert_hostname(conn, &conn->socks_proxy.host);
+    result = Curl_idnconvert_hostname(conn, &conn->socks_proxy.host);
     if(result)
       goto out;
   }
+#endif
 
   /*************************************************************
    * Check whether the host and the "connect to host" are equal.
@@ -3541,6 +3524,7 @@
     conn->bits.conn_to_port = FALSE;
   }
 
+#ifndef CURL_DISABLE_PROXY
   /*************************************************************
    * If the "connect to" feature is used with an HTTP proxy,
    * we set the tunnel_proxy bit.
@@ -3548,6 +3532,7 @@
   if((conn->bits.conn_to_host || conn->bits.conn_to_port) &&
       conn->bits.httpproxy)
     conn->bits.tunnel_proxy = TRUE;
+#endif
 
   /*************************************************************
    * Setup internals depending on protocol. Needs to be done after
@@ -3580,6 +3565,7 @@
     if(!result) {
       conn->bits.tcpconnect[FIRSTSOCKET] = TRUE; /* we are "connected */
 
+      Curl_attach_connnection(data, conn);
       result = Curl_conncache_add_conn(data->state.conn_cache, conn);
       if(result)
         goto out;
@@ -3594,7 +3580,6 @@
         (void)conn->handler->done(conn, result, FALSE);
         goto out;
       }
-      Curl_attach_connnection(data, conn);
       Curl_setup_transfer(data, -1, -1, FALSE, -1);
     }
 
@@ -3615,57 +3600,75 @@
      copies will be separately allocated.
   */
   data->set.ssl.primary.CApath = data->set.str[STRING_SSL_CAPATH_ORIG];
-  data->set.proxy_ssl.primary.CApath = data->set.str[STRING_SSL_CAPATH_PROXY];
   data->set.ssl.primary.CAfile = data->set.str[STRING_SSL_CAFILE_ORIG];
-  data->set.proxy_ssl.primary.CAfile = data->set.str[STRING_SSL_CAFILE_PROXY];
   data->set.ssl.primary.random_file = data->set.str[STRING_SSL_RANDOM_FILE];
-  data->set.proxy_ssl.primary.random_file =
-    data->set.str[STRING_SSL_RANDOM_FILE];
   data->set.ssl.primary.egdsocket = data->set.str[STRING_SSL_EGDSOCKET];
-  data->set.proxy_ssl.primary.egdsocket = data->set.str[STRING_SSL_EGDSOCKET];
   data->set.ssl.primary.cipher_list =
     data->set.str[STRING_SSL_CIPHER_LIST_ORIG];
-  data->set.proxy_ssl.primary.cipher_list =
-    data->set.str[STRING_SSL_CIPHER_LIST_PROXY];
   data->set.ssl.primary.cipher_list13 =
     data->set.str[STRING_SSL_CIPHER13_LIST_ORIG];
+  data->set.ssl.primary.pinned_key =
+    data->set.str[STRING_SSL_PINNEDPUBLICKEY_ORIG];
+  data->set.ssl.primary.cert_blob = data->set.blobs[BLOB_CERT_ORIG];
+
+#ifndef CURL_DISABLE_PROXY
+  data->set.proxy_ssl.primary.CApath = data->set.str[STRING_SSL_CAPATH_PROXY];
+  data->set.proxy_ssl.primary.CAfile = data->set.str[STRING_SSL_CAFILE_PROXY];
+  data->set.proxy_ssl.primary.random_file =
+    data->set.str[STRING_SSL_RANDOM_FILE];
+  data->set.proxy_ssl.primary.egdsocket = data->set.str[STRING_SSL_EGDSOCKET];
+  data->set.proxy_ssl.primary.cipher_list =
+    data->set.str[STRING_SSL_CIPHER_LIST_PROXY];
   data->set.proxy_ssl.primary.cipher_list13 =
     data->set.str[STRING_SSL_CIPHER13_LIST_PROXY];
-
-  data->set.ssl.CRLfile = data->set.str[STRING_SSL_CRLFILE_ORIG];
+  data->set.proxy_ssl.primary.pinned_key =
+    data->set.str[STRING_SSL_PINNEDPUBLICKEY_PROXY];
+  data->set.proxy_ssl.primary.cert_blob = data->set.blobs[BLOB_CERT_PROXY];
   data->set.proxy_ssl.CRLfile = data->set.str[STRING_SSL_CRLFILE_PROXY];
-  data->set.ssl.issuercert = data->set.str[STRING_SSL_ISSUERCERT_ORIG];
   data->set.proxy_ssl.issuercert = data->set.str[STRING_SSL_ISSUERCERT_PROXY];
-  data->set.ssl.cert = data->set.str[STRING_CERT_ORIG];
   data->set.proxy_ssl.cert = data->set.str[STRING_CERT_PROXY];
-  data->set.ssl.cert_type = data->set.str[STRING_CERT_TYPE_ORIG];
   data->set.proxy_ssl.cert_type = data->set.str[STRING_CERT_TYPE_PROXY];
-  data->set.ssl.key = data->set.str[STRING_KEY_ORIG];
   data->set.proxy_ssl.key = data->set.str[STRING_KEY_PROXY];
-  data->set.ssl.key_type = data->set.str[STRING_KEY_TYPE_ORIG];
   data->set.proxy_ssl.key_type = data->set.str[STRING_KEY_TYPE_PROXY];
-  data->set.ssl.key_passwd = data->set.str[STRING_KEY_PASSWD_ORIG];
   data->set.proxy_ssl.key_passwd = data->set.str[STRING_KEY_PASSWD_PROXY];
-  data->set.ssl.primary.clientcert = data->set.str[STRING_CERT_ORIG];
   data->set.proxy_ssl.primary.clientcert = data->set.str[STRING_CERT_PROXY];
+  data->set.proxy_ssl.cert_blob = data->set.blobs[BLOB_CERT_PROXY];
+  data->set.proxy_ssl.key_blob = data->set.blobs[BLOB_KEY_PROXY];
+#endif
+  data->set.ssl.CRLfile = data->set.str[STRING_SSL_CRLFILE_ORIG];
+  data->set.ssl.issuercert = data->set.str[STRING_SSL_ISSUERCERT_ORIG];
+  data->set.ssl.cert = data->set.str[STRING_CERT_ORIG];
+  data->set.ssl.cert_type = data->set.str[STRING_CERT_TYPE_ORIG];
+  data->set.ssl.key = data->set.str[STRING_KEY_ORIG];
+  data->set.ssl.key_type = data->set.str[STRING_KEY_TYPE_ORIG];
+  data->set.ssl.key_passwd = data->set.str[STRING_KEY_PASSWD_ORIG];
+  data->set.ssl.primary.clientcert = data->set.str[STRING_CERT_ORIG];
 #ifdef USE_TLS_SRP
   data->set.ssl.username = data->set.str[STRING_TLSAUTH_USERNAME_ORIG];
-  data->set.proxy_ssl.username = data->set.str[STRING_TLSAUTH_USERNAME_PROXY];
   data->set.ssl.password = data->set.str[STRING_TLSAUTH_PASSWORD_ORIG];
+#ifndef CURL_DISABLE_PROXY
+  data->set.proxy_ssl.username = data->set.str[STRING_TLSAUTH_USERNAME_PROXY];
   data->set.proxy_ssl.password = data->set.str[STRING_TLSAUTH_PASSWORD_PROXY];
 #endif
+#endif
+
+  data->set.ssl.cert_blob = data->set.blobs[BLOB_CERT_ORIG];
+  data->set.ssl.key_blob = data->set.blobs[BLOB_KEY_ORIG];
+  data->set.ssl.issuercert_blob = data->set.blobs[BLOB_SSL_ISSUERCERT_ORIG];
 
   if(!Curl_clone_primary_ssl_config(&data->set.ssl.primary,
-     &conn->ssl_config)) {
+                                    &conn->ssl_config)) {
     result = CURLE_OUT_OF_MEMORY;
     goto out;
   }
 
+#ifndef CURL_DISABLE_PROXY
   if(!Curl_clone_primary_ssl_config(&data->set.proxy_ssl.primary,
                                     &conn->proxy_ssl_config)) {
     result = CURLE_OUT_OF_MEMORY;
     goto out;
   }
+#endif
 
   prune_dead_connections(data);
 
@@ -3688,25 +3691,6 @@
   else
     reuse = ConnectionExists(data, conn, &conn_temp, &force_reuse, &waitpipe);
 
-  /* If we found a reusable connection that is now marked as in use, we may
-     still want to open a new connection if we are multiplexing. */
-  if(reuse && !force_reuse && IsMultiplexingPossible(data, conn_temp)) {
-    size_t multiplexed = CONN_INUSE(conn_temp);
-    if(multiplexed > 0) {
-      infof(data, "Found connection %ld, with %zu requests on it\n",
-            conn_temp->connection_id, multiplexed);
-
-      if(Curl_conncache_bundle_size(conn_temp) < max_host_connections &&
-         Curl_conncache_size(data) < max_total_connections) {
-        /* We want a new connection anyway */
-        reuse = FALSE;
-
-        infof(data, "We can reuse, but we want a new connection anyway\n");
-        Curl_conncache_return_conn(conn_temp);
-      }
-    }
-  }
-
   if(reuse) {
     /*
      * We already have a connection for this, we got the former connection
@@ -3722,12 +3706,17 @@
     conn = conn_temp;
     *in_connect = conn;
 
+#ifndef CURL_DISABLE_PROXY
     infof(data, "Re-using existing connection! (#%ld) with %s %s\n",
           conn->connection_id,
           conn->bits.proxy?"proxy":"host",
           conn->socks_proxy.host.name ? conn->socks_proxy.host.dispname :
           conn->http_proxy.host.name ? conn->http_proxy.host.dispname :
-                                       conn->host.dispname);
+          conn->host.dispname);
+#else
+    infof(data, "Re-using existing connection! (#%ld) with host %s\n",
+          conn->connection_id, conn->host.dispname);
+#endif
   }
   else {
     /* We have decided that we want a new connection. However, we may not
@@ -3749,8 +3738,9 @@
       connections_available = FALSE;
     else {
       /* this gets a lock on the conncache */
+      const char *bundlehost;
       struct connectbundle *bundle =
-        Curl_conncache_find_bundle(conn, data->state.conn_cache);
+        Curl_conncache_find_bundle(conn, data->state.conn_cache, &bundlehost);
 
       if(max_host_connections > 0 && bundle &&
          (bundle->num_connections >= max_host_connections)) {
@@ -3758,19 +3748,19 @@
 
         /* The bundle is full. Extract the oldest connection. */
         conn_candidate = Curl_conncache_extract_bundle(data, bundle);
-        Curl_conncache_unlock(data);
+        CONNCACHE_UNLOCK(data);
 
         if(conn_candidate)
           (void)Curl_disconnect(data, conn_candidate,
                                 /* dead_connection */ FALSE);
         else {
-          infof(data, "No more connections allowed to host: %zu\n",
-                max_host_connections);
+          infof(data, "No more connections allowed to host %s: %zu\n",
+                bundlehost, max_host_connections);
           connections_available = FALSE;
         }
       }
       else
-        Curl_conncache_unlock(data);
+        CONNCACHE_UNLOCK(data);
 
     }
 
@@ -3804,6 +3794,8 @@
        * This is a brand new connection, so let's store it in the connection
        * cache of ours!
        */
+      Curl_attach_connnection(data, conn);
+
       result = Curl_conncache_add_conn(data->state.conn_cache, conn);
       if(result)
         goto out;
@@ -3855,10 +3847,12 @@
 
   /* Strip trailing dots. resolve_server copied the name. */
   strip_trailing_dot(&conn->host);
+#ifndef CURL_DISABLE_PROXY
   if(conn->bits.httpproxy)
     strip_trailing_dot(&conn->http_proxy.host);
   if(conn->bits.socksproxy)
     strip_trailing_dot(&conn->socks_proxy.host);
+#endif
   if(conn->bits.conn_to_host)
     strip_trailing_dot(&conn->conn_to_host);
 
@@ -3889,22 +3883,23 @@
   }
   *protocol_done = FALSE; /* default to not done */
 
+#ifndef CURL_DISABLE_PROXY
   /* set proxy_connect_closed to false unconditionally already here since it
      is used strictly to provide extra information to a parent function in the
      case of proxy CONNECT failures and we must make sure we don't have it
      lingering set from a previous invoke */
   conn->bits.proxy_connect_closed = FALSE;
-
+#endif
   /*
    * Set user-agent. Used for HTTP, but since we can attempt to tunnel
    * basically anything through a http proxy we can't limit this based on
    * protocol.
    */
   if(data->set.str[STRING_USERAGENT]) {
-    Curl_safefree(conn->allocptr.uagent);
-    conn->allocptr.uagent =
+    Curl_safefree(data->state.aptr.uagent);
+    data->state.aptr.uagent =
       aprintf("User-Agent: %s\r\n", data->set.str[STRING_USERAGENT]);
-    if(!conn->allocptr.uagent)
+    if(!data->state.aptr.uagent)
       return CURLE_OUT_OF_MEMORY;
   }
 
@@ -3926,7 +3921,9 @@
   }
   else {
     Curl_pgrsTime(data, TIMER_CONNECT);    /* we're connected already */
-    Curl_pgrsTime(data, TIMER_APPCONNECT); /* we're connected already */
+    if(conn->ssl[FIRSTSOCKET].use ||
+       (conn->handler->protocol & PROTO_FAMILY_SSH))
+      Curl_pgrsTime(data, TIMER_APPCONNECT); /* we're connected already */
     conn->bits.tcpconnect[FIRSTSOCKET] = TRUE;
     *protocol_done = TRUE;
     Curl_updateconninfo(conn, conn->sock[FIRSTSOCKET]);
@@ -3956,7 +3953,7 @@
   result = create_conn(data, &conn, asyncp);
 
   if(!result) {
-    if(CONN_INUSE(conn))
+    if(CONN_INUSE(conn) > 1)
       /* multiplexed */
       *protocol_done = TRUE;
     else if(!*asyncp) {
@@ -3973,11 +3970,10 @@
   else if(result && conn) {
     /* We're not allowed to return failure with memory left allocated in the
        connectdata struct, free those here */
+    Curl_detach_connnection(data);
+    Curl_conncache_remove_conn(data, conn, TRUE);
     Curl_disconnect(data, conn, TRUE);
   }
-  else if(!result && !data->conn)
-    /* FILE: transfers already have the connection attached */
-    Curl_attach_connnection(data, conn);
 
   return result;
 }
@@ -3996,6 +3992,11 @@
 {
   struct SingleRequest *k = &data->req;
 
+  /* if this is a pushed stream, we need this: */
+  CURLcode result = Curl_preconnect(data);
+  if(result)
+    return result;
+
   if(conn) {
     conn->bits.do_more = FALSE; /* by default there's no curl_do_more() to
                                    use */
@@ -4008,30 +4009,17 @@
   data->state.done = FALSE; /* *_done() is not called yet */
   data->state.expect100header = FALSE;
 
-
   if(data->set.opt_no_body)
     /* in HTTP lingo, no body means using the HEAD request... */
-    data->set.httpreq = HTTPREQ_HEAD;
-  else if(HTTPREQ_HEAD == data->set.httpreq)
-    /* ... but if unset there really is no perfect method that is the
-       "opposite" of HEAD but in reality most people probably think GET
-       then. The important thing is that we can't let it remain HEAD if the
-       opt_no_body is set FALSE since then we'll behave wrong when getting
-       HTTP. */
-    data->set.httpreq = HTTPREQ_GET;
+    data->state.httpreq = HTTPREQ_HEAD;
 
   k->start = Curl_now(); /* start time */
   k->now = k->start;   /* current time is now */
   k->header = TRUE; /* assume header */
-
   k->bytecount = 0;
-
-  k->buf = data->state.buffer;
-  k->hbufp = data->state.headerbuff;
   k->ignorebody = FALSE;
 
   Curl_speedinit(data);
-
   Curl_pgrsSetUploadCounter(data, 0);
   Curl_pgrsSetDownloadCounter(data, 0);
 
@@ -4147,34 +4135,3 @@
 
   return family;
 }
-
-
-/*
- * Wrapper to call functions in Curl_conncache_foreach()
- *
- * Returns always 0.
- */
-static int conn_upkeep(struct connectdata *conn,
-                       void *param)
-{
-  /* Param is unused. */
-  (void)param;
-
-  if(conn->handler->connection_check) {
-    /* Do a protocol-specific keepalive check on the connection. */
-    conn->handler->connection_check(conn, CONNCHECK_KEEPALIVE);
-  }
-
-  return 0; /* continue iteration */
-}
-
-CURLcode Curl_upkeep(struct conncache *conn_cache,
-                          void *data)
-{
-  /* Loop over every connection and make connection alive. */
-  Curl_conncache_foreach(data,
-                         conn_cache,
-                         data,
-                         conn_upkeep);
-  return CURLE_OK;
-}
diff --git a/Utilities/cmcurl/lib/url.h b/Utilities/cmcurl/lib/url.h
index 4db9e86..1941dc6 100644
--- a/Utilities/cmcurl/lib/url.h
+++ b/Utilities/cmcurl/lib/url.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -47,47 +47,40 @@
 CURLcode Curl_open(struct Curl_easy **curl);
 CURLcode Curl_init_userdefined(struct Curl_easy *data);
 
-void Curl_freeset(struct Curl_easy * data);
-/* free the URL pieces */
-void Curl_up_free(struct Curl_easy *data);
+void Curl_freeset(struct Curl_easy *data);
 CURLcode Curl_uc_to_curlcode(CURLUcode uc);
-CURLcode Curl_close(struct Curl_easy *data); /* opposite of curl_open() */
+CURLcode Curl_close(struct Curl_easy **datap); /* opposite of curl_open() */
 CURLcode Curl_connect(struct Curl_easy *, bool *async, bool *protocol_connect);
 CURLcode Curl_disconnect(struct Curl_easy *data,
                          struct connectdata *, bool dead_connection);
-CURLcode Curl_protocol_connect(struct connectdata *conn, bool *done);
-CURLcode Curl_protocol_connecting(struct connectdata *conn, bool *done);
-CURLcode Curl_protocol_doing(struct connectdata *conn, bool *done);
 CURLcode Curl_setup_conn(struct connectdata *conn,
                          bool *protocol_done);
 void Curl_free_request_state(struct Curl_easy *data);
-
-int Curl_protocol_getsock(struct connectdata *conn,
-                          curl_socket_t *socks,
-                          int numsocks);
-int Curl_doing_getsock(struct connectdata *conn,
-                       curl_socket_t *socks,
-                       int numsocks);
 CURLcode Curl_parse_login_details(const char *login, const size_t len,
                                   char **userptr, char **passwdptr,
                                   char **optionsptr);
-void Curl_close_connections(struct Curl_easy *data);
-CURLcode Curl_upkeep(struct conncache *conn_cache, void *data);
 
 const struct Curl_handler *Curl_builtin_scheme(const char *scheme);
 
+bool Curl_is_ASCII_name(const char *hostname);
+CURLcode Curl_idnconvert_hostname(struct connectdata *conn,
+                                  struct hostname *host);
+void Curl_free_idnconverted_hostname(struct hostname *host);
+
 #define CURL_DEFAULT_PROXY_PORT 1080 /* default proxy port unless specified */
 #define CURL_DEFAULT_HTTPS_PROXY_PORT 443 /* default https proxy port unless
                                              specified */
 
-CURLcode Curl_connected_proxy(struct connectdata *conn, int sockindex);
-
 #ifdef CURL_DISABLE_VERBOSE_STRINGS
 #define Curl_verboseconnect(x)  Curl_nop_stmt
 #else
 void Curl_verboseconnect(struct connectdata *conn);
 #endif
 
+#ifdef CURL_DISABLE_PROXY
+#define CONNECT_PROXY_SSL() FALSE
+#else
+
 #define CONNECT_PROXY_SSL()\
   (conn->http_proxy.proxytype == CURLPROXY_HTTPS &&\
   !conn->bits.proxy_ssl_connected[sockindex])
@@ -99,5 +92,6 @@
 #define CONNECT_SECONDARYSOCKET_PROXY_SSL()\
   (conn->http_proxy.proxytype == CURLPROXY_HTTPS &&\
   !conn->bits.proxy_ssl_connected[SECONDARYSOCKET])
+#endif /* !CURL_DISABLE_PROXY */
 
 #endif /* HEADER_CURL_URL_H */
diff --git a/Utilities/cmcurl/lib/urlapi-int.h b/Utilities/cmcurl/lib/urlapi-int.h
index 5f059c2..d14d53d 100644
--- a/Utilities/cmcurl/lib/urlapi-int.h
+++ b/Utilities/cmcurl/lib/urlapi-int.h
@@ -26,9 +26,6 @@
 #define MAX_SCHEME_LEN 40
 
 bool Curl_is_absolute_url(const char *url, char *scheme, size_t buflen);
-char *Curl_concat_url(const char *base, const char *relurl);
-size_t Curl_strlen_url(const char *url, bool relative);
-void Curl_strcpy_url(char *output, const char *url, bool relative);
 
 #ifdef DEBUGBUILD
 CURLUcode Curl_parse_port(struct Curl_URL *u, char *hostname);
diff --git a/Utilities/cmcurl/lib/urlapi.c b/Utilities/cmcurl/lib/urlapi.c
index d07e4f5..acbfb82 100644
--- a/Utilities/cmcurl/lib/urlapi.c
+++ b/Utilities/cmcurl/lib/urlapi.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -29,6 +29,7 @@
 #include "url.h"
 #include "escape.h"
 #include "curl_ctype.h"
+#include "inet_pton.h"
 
 /* The last 3 #include files should be in this order */
 #include "curl_printf.h"
@@ -63,6 +64,7 @@
   char *fragment;
 
   char *scratch; /* temporary scratch area */
+  char *temppath; /* temporary path pointer */
   long portnum; /* the numerical version */
 };
 
@@ -81,6 +83,7 @@
   free(u->query);
   free(u->fragment);
   free(u->scratch);
+  free(u->temppath);
 }
 
 /* move the full contents of one handle onto another and
@@ -222,7 +225,7 @@
       break;
     }
   }
-  *optr = 0; /* zero terminate output buffer */
+  *optr = 0; /* null-terminate output buffer */
 
 }
 
@@ -350,7 +353,7 @@
   else {
     /* We got a new absolute path for this server */
 
-    if((relurl[0] == '/') && (relurl[1] == '/')) {
+    if(relurl[1] == '/') {
       /* the new URL starts with //, just keep the protocol part from the
          original one */
       *protsep = 0;
@@ -425,7 +428,6 @@
  *
  */
 static CURLUcode parse_hostname_login(struct Curl_URL *u,
-                                      const struct Curl_handler *h,
                                       char **hostname,
                                       unsigned int flags)
 {
@@ -434,6 +436,7 @@
   char *userp = NULL;
   char *passwdp = NULL;
   char *optionsp = NULL;
+  const struct Curl_handler *h = NULL;
 
   /* At this point, we're hoping all the other special cases have
    * been taken care of, so conn->host.name is at most
@@ -453,6 +456,10 @@
    * ftp://user:password@ftp.my.site:8021/README */
   *hostname = ++ptr;
 
+  /* if this is a known scheme, get some details */
+  if(u->scheme)
+    h = Curl_builtin_scheme(u->scheme);
+
   /* We could use the login information in the URL so extract it. Only parse
      options if the handler says we should. Note that 'h' might be NULL! */
   ccode = Curl_parse_login_details(login, ptr - login - 1,
@@ -568,7 +575,7 @@
 }
 
 /* scan for byte values < 31 or 127 */
-static CURLUcode junkscan(char *part)
+static CURLUcode junkscan(const char *part)
 {
   if(part) {
     static const char badbytes[]={
@@ -577,7 +584,7 @@
       0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
       0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
       0x7f,
-      0x00 /* zero terminate */
+      0x00 /* null-terminate */
     };
     size_t n = strlen(part);
     size_t nfine = strcspn(part, badbytes);
@@ -591,20 +598,26 @@
 
 static CURLUcode hostname_check(struct Curl_URL *u, char *hostname)
 {
-  const char *l = NULL; /* accepted characters */
   size_t len;
   size_t hlen = strlen(hostname);
 
   if(hostname[0] == '[') {
+#ifdef ENABLE_IPV6
+    char dest[16]; /* fits a binary IPv6 address */
+#endif
+    const char *l = "0123456789abcdefABCDEF:.";
+    if(hlen < 4) /* '[::]' is the shortest possible valid string */
+      return CURLUE_MALFORMED_INPUT;
     hostname++;
-    l = "0123456789abcdefABCDEF::.";
     hlen -= 2;
-  }
 
-  if(l) {
+    if(hostname[hlen] != ']')
+      return CURLUE_MALFORMED_INPUT;
+
     /* only valid letters are ok */
     len = strspn(hostname, l);
     if(hlen != len) {
+      hlen = len;
       if(hostname[len] == '%') {
         /* this could now be '%[zone id]' */
         char zoneid[16];
@@ -628,6 +641,12 @@
         return CURLUE_MALFORMED_INPUT;
       /* hostname is fine */
     }
+#ifdef ENABLE_IPV6
+    hostname[hlen] = 0; /* end the address there */
+    if(1 != Curl_inet_pton(AF_INET6, hostname, dest))
+      return CURLUE_MALFORMED_INPUT;
+    hostname[hlen] = ']'; /* restore ending bracket */
+#endif
   }
   else {
     /* letters from the second string is not ok */
@@ -653,10 +672,9 @@
   CURLUcode result;
   bool url_has_scheme = FALSE;
   char schemebuf[MAX_SCHEME_LEN + 1];
-  char *schemep = NULL;
+  const char *schemep = NULL;
   size_t schemelen = 0;
   size_t urllen;
-  const struct Curl_handler *h = NULL;
 
   if(!url)
     return CURLUE_MALFORMED_INPUT;
@@ -775,6 +793,7 @@
 
       if(junkscan(schemep))
         return CURLUE_MALFORMED_INPUT;
+
     }
     else {
       /* no scheme! */
@@ -782,7 +801,7 @@
       if(!(flags & (CURLU_DEFAULT_SCHEME|CURLU_GUESS_SCHEME)))
         return CURLUE_MALFORMED_INPUT;
       if(flags & CURLU_DEFAULT_SCHEME)
-        schemep = (char *) DEFAULT_SCHEME;
+        schemep = DEFAULT_SCHEME;
 
       /*
        * The URL was badly formatted, let's try without scheme specified.
@@ -795,74 +814,83 @@
       p++;
 
     len = p - hostp;
-    if(!len)
-      return CURLUE_MALFORMED_INPUT;
-
-    memcpy(hostname, hostp, len);
-    hostname[len] = 0;
-
-    if((flags & CURLU_GUESS_SCHEME) && !schemep) {
-      /* legacy curl-style guess based on host name */
-      if(checkprefix("ftp.", hostname))
-        schemep = (char *)"ftp";
-      else if(checkprefix("dict.", hostname))
-        schemep = (char *)"dict";
-      else if(checkprefix("ldap.", hostname))
-        schemep = (char *)"ldap";
-      else if(checkprefix("imap.", hostname))
-        schemep = (char *)"imap";
-      else if(checkprefix("smtp.", hostname))
-        schemep = (char *)"smtp";
-      else if(checkprefix("pop3.", hostname))
-        schemep = (char *)"pop3";
-      else
-        schemep = (char *)"http";
+    if(len) {
+      memcpy(hostname, hostp, len);
+      hostname[len] = 0;
+    }
+    else {
+      if(!(flags & CURLU_NO_AUTHORITY))
+        return CURLUE_MALFORMED_INPUT;
     }
 
     len = strlen(p);
     memcpy(path, p, len);
     path[len] = 0;
 
-    u->scheme = strdup(schemep);
-    if(!u->scheme)
-      return CURLUE_OUT_OF_MEMORY;
+    if(schemep) {
+      u->scheme = strdup(schemep);
+      if(!u->scheme)
+        return CURLUE_OUT_OF_MEMORY;
+    }
   }
 
-  /* if this is a known scheme, get some details */
-  h = Curl_builtin_scheme(u->scheme);
-
   if(junkscan(path))
     return CURLUE_MALFORMED_INPUT;
 
-  query = strchr(path, '?');
-  if(query)
-    *query++ = 0;
-
-  fragment = strchr(query?query:path, '#');
-  if(fragment)
-    *fragment++ = 0;
-
-  if(!path[0])
-    /* if there's no path set, unset */
-    path = NULL;
-  else if(!(flags & CURLU_PATH_AS_IS)) {
-    /* sanitise paths and remove ../ and ./ sequences according to RFC3986 */
-    char *newp = Curl_dedotdotify(path);
+  if((flags & CURLU_URLENCODE) && path[0]) {
+    /* worst case output length is 3x the original! */
+    char *newp = malloc(strlen(path) * 3);
     if(!newp)
       return CURLUE_OUT_OF_MEMORY;
-
-    if(strcmp(newp, path)) {
-      /* if we got a new version */
-      path = newp;
-      path_alloced = TRUE;
-    }
-    else
-      free(newp);
+    path_alloced = TRUE;
+    strcpy_url(newp, path, TRUE); /* consider it relative */
+    u->temppath = path = newp;
   }
-  if(path) {
+
+  fragment = strchr(path, '#');
+  if(fragment) {
+    *fragment++ = 0;
+    if(fragment[0]) {
+      u->fragment = strdup(fragment);
+      if(!u->fragment)
+        return CURLUE_OUT_OF_MEMORY;
+    }
+  }
+
+  query = strchr(path, '?');
+  if(query) {
+    *query++ = 0;
+    /* done even if the query part is a blank string */
+    u->query = strdup(query);
+    if(!u->query)
+      return CURLUE_OUT_OF_MEMORY;
+  }
+
+  if(!path[0])
+    /* if there's no path left set, unset */
+    path = NULL;
+  else {
+    if(!(flags & CURLU_PATH_AS_IS)) {
+      /* remove ../ and ./ sequences according to RFC3986 */
+      char *newp = Curl_dedotdotify(path);
+      if(!newp)
+        return CURLUE_OUT_OF_MEMORY;
+
+      if(strcmp(newp, path)) {
+        /* if we got a new version */
+        if(path_alloced)
+          Curl_safefree(u->temppath);
+        u->temppath = path = newp;
+        path_alloced = TRUE;
+      }
+      else
+        free(newp);
+    }
+
     u->path = path_alloced?path:strdup(path);
     if(!u->path)
       return CURLUE_OUT_OF_MEMORY;
+    u->temppath = NULL; /* used now */
   }
 
   if(hostname) {
@@ -872,7 +900,7 @@
     if(junkscan(hostname))
       return CURLUE_MALFORMED_INPUT;
 
-    result = parse_hostname_login(u, h, &hostname, flags);
+    result = parse_hostname_login(u, &hostname, flags);
     if(result)
       return result;
 
@@ -880,28 +908,44 @@
     if(result)
       return result;
 
-    result = hostname_check(u, hostname);
-    if(result)
-      return result;
+    if(0 == strlen(hostname) && (flags & CURLU_NO_AUTHORITY)) {
+      /* Skip hostname check, it's allowed to be empty. */
+    }
+    else {
+      result = hostname_check(u, hostname);
+      if(result)
+        return result;
+    }
 
     u->host = strdup(hostname);
     if(!u->host)
       return CURLUE_OUT_OF_MEMORY;
+
+    if((flags & CURLU_GUESS_SCHEME) && !schemep) {
+      /* legacy curl-style guess based on host name */
+      if(checkprefix("ftp.", hostname))
+        schemep = "ftp";
+      else if(checkprefix("dict.", hostname))
+        schemep = "dict";
+      else if(checkprefix("ldap.", hostname))
+        schemep = "ldap";
+      else if(checkprefix("imap.", hostname))
+        schemep = "imap";
+      else if(checkprefix("smtp.", hostname))
+        schemep = "smtp";
+      else if(checkprefix("pop3.", hostname))
+        schemep = "pop3";
+      else
+        schemep = "http";
+
+      u->scheme = strdup(schemep);
+      if(!u->scheme)
+        return CURLUE_OUT_OF_MEMORY;
+    }
   }
 
-  if(query) {
-    u->query = strdup(query);
-    if(!u->query)
-      return CURLUE_OUT_OF_MEMORY;
-  }
-  if(fragment && fragment[0]) {
-    u->fragment = strdup(fragment);
-    if(!u->fragment)
-      return CURLUE_OUT_OF_MEMORY;
-  }
-
-  free(u->scratch);
-  u->scratch = NULL;
+  Curl_safefree(u->scratch);
+  Curl_safefree(u->temppath);
 
   return CURLUE_OK;
 }
@@ -1066,24 +1110,23 @@
       else
         return CURLUE_NO_SCHEME;
 
-      if(scheme) {
-        h = Curl_builtin_scheme(scheme);
-        if(!port && (flags & CURLU_DEFAULT_PORT)) {
-          /* there's no stored port number, but asked to deliver
-             a default one for the scheme */
-          if(h) {
-            msnprintf(portbuf, sizeof(portbuf), "%ld", h->defport);
-            port = portbuf;
-          }
-        }
-        else if(port) {
-          /* there is a stored port number, but asked to inhibit if it matches
-             the default one for the scheme */
-          if(h && (h->defport == u->portnum) &&
-             (flags & CURLU_NO_DEFAULT_PORT))
-            port = NULL;
+      h = Curl_builtin_scheme(scheme);
+      if(!port && (flags & CURLU_DEFAULT_PORT)) {
+        /* there's no stored port number, but asked to deliver
+           a default one for the scheme */
+        if(h) {
+          msnprintf(portbuf, sizeof(portbuf), "%ld", h->defport);
+          port = portbuf;
         }
       }
+      else if(port) {
+        /* there is a stored port number, but asked to inhibit if it matches
+           the default one for the scheme */
+        if(h && (h->defport == u->portnum) &&
+           (flags & CURLU_NO_DEFAULT_PORT))
+          port = NULL;
+      }
+
       if(h && !(h->flags & PROTOPT_URLOPTIONS))
         options = NULL;
 
@@ -1142,7 +1185,10 @@
     if(urldecode) {
       char *decoded;
       size_t dlen;
-      CURLcode res = Curl_urldecode(NULL, *part, 0, &decoded, &dlen, TRUE);
+      /* this unconditional rejection of control bytes is documented
+         API behavior */
+      CURLcode res = Curl_urldecode(NULL, *part, 0, &decoded, &dlen,
+                                    REJECT_CTRL);
       free(*part);
       if(res) {
         *part = NULL;
@@ -1331,7 +1377,8 @@
   default:
     return CURLUE_UNKNOWN_PART;
   }
-  if(storep) {
+  DEBUGASSERT(storep);
+  {
     const char *newp = part;
     size_t nalloc = strlen(part);
 
@@ -1351,7 +1398,7 @@
         i = (const unsigned char *)part;
         for(o = enc; *i; ++o, ++i)
           *o = (*i == ' ') ? '+' : *i;
-        *o = 0; /* zero terminate */
+        *o = 0; /* null-terminate */
         part = strdup(enc);
         if(!part) {
           free(enc);
@@ -1375,7 +1422,7 @@
           o += 3;
         }
       }
-      *o = 0; /* zero terminate */
+      *o = 0; /* null-terminate */
       newp = enc;
       if(free_part)
         free((char *)part);
@@ -1423,9 +1470,14 @@
     }
 
     if(what == CURLUPART_HOST) {
-      if(hostname_check(u, (char *)newp)) {
-        free((char *)newp);
-        return CURLUE_MALFORMED_INPUT;
+      if(0 == strlen(newp) && (flags & CURLU_NO_AUTHORITY)) {
+        /* Skip hostname check, it's allowed to be empty. */
+      }
+      else {
+        if(hostname_check(u, (char *)newp)) {
+          free((char *)newp);
+          return CURLUE_MALFORMED_INPUT;
+        }
       }
     }
 
diff --git a/Utilities/cmcurl/lib/urldata.h b/Utilities/cmcurl/lib/urldata.h
index d759592..f80a02d 100644
--- a/Utilities/cmcurl/lib/urldata.h
+++ b/Utilities/cmcurl/lib/urldata.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -49,6 +49,7 @@
 #define PORT_RTMPT PORT_HTTP
 #define PORT_RTMPS PORT_HTTPS
 #define PORT_GOPHER 70
+#define PORT_MQTT 1883
 
 #define DICT_MATCH "/MATCH:"
 #define DICT_MATCH2 "/M:"
@@ -68,6 +69,7 @@
 #define PROTO_FAMILY_POP3 (CURLPROTO_POP3|CURLPROTO_POP3S)
 #define PROTO_FAMILY_SMB  (CURLPROTO_SMB|CURLPROTO_SMBS)
 #define PROTO_FAMILY_SMTP (CURLPROTO_SMTP|CURLPROTO_SMTPS)
+#define PROTO_FAMILY_SSH  (CURLPROTO_SCP|CURLPROTO_SFTP)
 
 #define DEFAULT_CONNCACHE_SIZE 5
 
@@ -79,7 +81,7 @@
 */
 #define RESP_TIMEOUT (120*1000)
 
-/* Max string intput length is a precaution against abuse and to detect junk
+/* Max string input length is a precaution against abuse and to detect junk
    input easier and better. */
 #define CURL_MAX_INPUT_LENGTH 8000000
 
@@ -102,6 +104,7 @@
 #include "hostip.h"
 #include "hash.h"
 #include "splay.h"
+#include "dynbuf.h"
 
 /* return the count of bytes sent, or -1 on error */
 typedef ssize_t (Curl_send)(struct connectdata *conn, /* connection data */
@@ -123,12 +126,14 @@
 #include "smtp.h"
 #include "ftp.h"
 #include "file.h"
-#include "ssh.h"
+#include "vssh/ssh.h"
 #include "http.h"
 #include "rtsp.h"
 #include "smb.h"
+#include "mqtt.h"
 #include "wildcard.h"
 #include "multihandle.h"
+#include "quic.h"
 
 #ifdef HAVE_GSSAPI
 # ifdef HAVE_GSSGNU
@@ -148,16 +153,18 @@
 #include <libssh2_sftp.h>
 #endif /* HAVE_LIBSSH2_H */
 
-/* Initial size of the buffer to store headers in, it'll be enlarged in case
-   of need. */
-#define HEADERSIZE 256
-
 #define CURLEASY_MAGIC_NUMBER 0xc0dedbadU
 #define GOOD_EASY_HANDLE(x) \
   ((x) && ((x)->magic == CURLEASY_MAGIC_NUMBER))
 
 /* the type we use for storing a single boolean bit */
+#ifdef _MSC_VER
+typedef bool bit;
+#define BIT(x) bool x
+#else
 typedef unsigned int bit;
+#define BIT(x) bit x:1
+#endif
 
 #ifdef HAVE_GSSAPI
 /* Types needed for krb5-ftp connections */
@@ -165,7 +172,7 @@
   void *data;
   size_t size;
   size_t index;
-  bit eof_flag:1;
+  BIT(eof_flag);
 };
 
 enum protection_level {
@@ -208,7 +215,7 @@
 #if defined(USE_SSL)
   struct ssl_backend_data *backend;
 #endif
-  bit use:1;
+  BIT(use);
 };
 
 struct ssl_primary_config {
@@ -221,10 +228,12 @@
   char *egdsocket;       /* path to file containing the EGD daemon socket */
   char *cipher_list;     /* list of ciphers to use */
   char *cipher_list13;   /* list of TLS 1.3 cipher suites to use */
-  bit verifypeer:1;      /* set TRUE if this is desired */
-  bit verifyhost:1;      /* set TRUE if CN/SAN must match hostname */
-  bit verifystatus:1;    /* set TRUE if certificate status must be checked */
-  bit sessionid:1;       /* cache session IDs or not */
+  char *pinned_key;
+  struct curl_blob *cert_blob;
+  BIT(verifypeer);       /* set TRUE if this is desired */
+  BIT(verifyhost);       /* set TRUE if CN/SAN must match hostname */
+  BIT(verifystatus);     /* set TRUE if certificate status must be checked */
+  BIT(sessionid);        /* cache session IDs or not */
 };
 
 struct ssl_config_data {
@@ -232,11 +241,14 @@
   long certverifyresult; /* result from the certificate verification */
   char *CRLfile;   /* CRL to check certificate revocation */
   char *issuercert;/* optional issuer certificate filename */
+  struct curl_blob *issuercert_blob;
   curl_ssl_ctx_callback fsslctx; /* function to initialize ssl ctx */
   void *fsslctxp;        /* parameter for call back */
   char *cert; /* client certificate file name */
+  struct curl_blob *cert_blob;
   char *cert_type; /* format for certificate (default: PEM)*/
   char *key; /* private key file name */
+  struct curl_blob *key_blob;
   char *key_type; /* format for private key (default: PEM) */
   char *key_passwd; /* plain text private key password */
 #ifdef USE_TLS_SRP
@@ -244,10 +256,14 @@
   char *password; /* TLS password (for, e.g., SRP) */
   enum CURL_TLSAUTH authtype; /* TLS authentication type (default SRP) */
 #endif
-  bit certinfo:1;     /* gather lots of certificate info */
-  bit falsestart:1;
-  bit enable_beast:1; /* allow this flaw for interoperability's sake*/
-  bit no_revoke:1;    /* disable SSL certificate revocation checks */
+  BIT(certinfo);     /* gather lots of certificate info */
+  BIT(falsestart);
+  BIT(enable_beast); /* allow this flaw for interoperability's sake*/
+  BIT(no_revoke);    /* disable SSL certificate revocation checks */
+  BIT(no_partialchain); /* don't accept partial certificate chains */
+  BIT(revoke_best_effort); /* ignore SSL revocation offline/missing revocation
+                              list errors */
+  BIT(native_ca_store); /* use the native ca store of operating system */
 };
 
 struct ssl_general_config {
@@ -290,8 +306,8 @@
   char *qop;
   char *algorithm;
   int nc; /* nounce count */
-  bit stale:1; /* set true for re-negotiation */
-  bit userhash:1;
+  BIT(stale); /* set true for re-negotiation */
+  BIT(userhash);
 #endif
 };
 
@@ -357,6 +373,14 @@
   unsigned char nonce[8];
   void *target_info; /* TargetInfo received in the ntlm type-2 message */
   unsigned int target_info_len;
+
+#if defined(NTLM_WB_ENABLED)
+  /* used for communication with Samba's winbind daemon helper ntlm_auth */
+  curl_socket_t ntlm_auth_hlpr_socket;
+  pid_t ntlm_auth_hlpr_pid;
+  char *challenge; /* The received base64 encoded ntlm type-2 message */
+  char *response;  /* The generated base64 ntlm type-1/type-3 message */
+#endif
 #endif
 };
 #endif
@@ -385,10 +409,10 @@
   size_t output_token_length;
 #endif
 #endif
-  bool noauthpersist;
-  bool havenoauthpersist;
-  bool havenegdata;
-  bool havemultiplerequests;
+  BIT(noauthpersist);
+  BIT(havenoauthpersist);
+  BIT(havenegdata);
+  BIT(havemultiplerequests);
 };
 #endif
 
@@ -397,68 +421,75 @@
  * Boolean values that concerns this connection.
  */
 struct ConnectBits {
-  /* always modify bits.close with the connclose() and connkeep() macros! */
-  bool proxy_ssl_connected[2]; /* TRUE when SSL initialization for HTTPS proxy
-                                  is complete */
   bool tcpconnect[2]; /* the TCP layer (or similar) is connected, this is set
                          the first time on the first connect function call */
-  bit close:1; /* if set, we close the connection after this request */
-  bit reuse:1; /* if set, this is a re-used connection */
-  bit conn_to_host:1; /* if set, this connection has a "connect to host"
-                         that overrides the host in the URL */
-  bit conn_to_port:1; /* if set, this connection has a "connect to port"
-                         that overrides the port in the URL (remote port) */
-  bit proxy:1; /* if set, this transfer is done through a proxy - any type */
-  bit httpproxy:1;  /* if set, this transfer is done through a http proxy */
-  bit socksproxy:1; /* if set, this transfer is done through a socks proxy */
-  bit user_passwd:1; /* do we use user+password for this connection? */
-  bit proxy_user_passwd:1; /* user+password for the proxy? */
-  bit ipv6_ip:1; /* we communicate with a remote site specified with pure IPv6
-                    IP address */
-  bit ipv6:1;    /* we communicate with a site using an IPv6 address */
-  bit do_more:1; /* this is set TRUE if the ->curl_do_more() function is
-                    supposed to be called, after ->curl_do() */
-  bit protoconnstart:1;/* the protocol layer has STARTED its operation after
-                          the TCP layer connect */
-  bit retry:1;         /* this connection is about to get closed and then
-                          re-attempted at another connection. */
-  bit tunnel_proxy:1;  /* if CONNECT is used to "tunnel" through the proxy.
-                          This is implicit when SSL-protocols are used through
-                          proxies, but can also be enabled explicitly by
-                          apps */
-  bit authneg:1;       /* TRUE when the auth phase has started, which means
-                          that we are creating a request with an auth header,
-                          but it is not the final request in the auth
-                          negotiation. */
-  bit rewindaftersend:1;/* TRUE when the sending couldn't be stopped even
-                           though it will be discarded. When the whole send
-                           operation is done, we must call the data rewind
-                           callback. */
-#ifndef CURL_DISABLE_FTP
-  bit ftp_use_epsv:1;  /* As set with CURLOPT_FTP_USE_EPSV, but if we find out
-                          EPSV doesn't work we disable it for the forthcoming
-                          requests */
-  bit ftp_use_eprt:1;  /* As set with CURLOPT_FTP_USE_EPRT, but if we find out
-                          EPRT doesn't work we disable it for the forthcoming
-                          requests */
-  bit ftp_use_data_ssl:1; /* Enabled SSL for the data connection */
+#ifndef CURL_DISABLE_PROXY
+  bool proxy_ssl_connected[2]; /* TRUE when SSL initialization for HTTPS proxy
+                                  is complete */
+  BIT(httpproxy);  /* if set, this transfer is done through a http proxy */
+  BIT(socksproxy); /* if set, this transfer is done through a socks proxy */
+  BIT(proxy_user_passwd); /* user+password for the proxy? */
+  BIT(tunnel_proxy);  /* if CONNECT is used to "tunnel" through the proxy.
+                         This is implicit when SSL-protocols are used through
+                         proxies, but can also be enabled explicitly by
+                         apps */
+  BIT(proxy_connect_closed); /* TRUE if a proxy disconnected the connection
+                                in a CONNECT request with auth, so that
+                                libcurl should reconnect and continue. */
 #endif
-  bit netrc:1;         /* name+password provided by netrc */
-  bit userpwd_in_url:1; /* name+password found in url */
-  bit stream_was_rewound:1; /* The stream was rewound after a request read
-                               past the end of its response byte boundary */
-  bit proxy_connect_closed:1; /* TRUE if a proxy disconnected the connection
-                                 in a CONNECT request with auth, so that
-                                 libcurl should reconnect and continue. */
-  bit bound:1; /* set true if bind() has already been done on this socket/
-                  connection */
-  bit type_set:1;  /* type= was used in the URL */
-  bit multiplex:1; /* connection is multiplexed */
-  bit tcp_fastopen:1; /* use TCP Fast Open */
-  bit tls_enable_npn:1;  /* TLS NPN extension? */
-  bit tls_enable_alpn:1; /* TLS ALPN extension? */
-  bit socksproxy_connecting:1; /* connecting through a socks proxy */
-  bit connect_only:1;
+  /* always modify bits.close with the connclose() and connkeep() macros! */
+  BIT(close); /* if set, we close the connection after this request */
+  BIT(reuse); /* if set, this is a re-used connection */
+  BIT(altused); /* this is an alt-svc "redirect" */
+  BIT(conn_to_host); /* if set, this connection has a "connect to host"
+                        that overrides the host in the URL */
+  BIT(conn_to_port); /* if set, this connection has a "connect to port"
+                        that overrides the port in the URL (remote port) */
+  BIT(proxy); /* if set, this transfer is done through a proxy - any type */
+  BIT(user_passwd); /* do we use user+password for this connection? */
+  BIT(ipv6_ip); /* we communicate with a remote site specified with pure IPv6
+                   IP address */
+  BIT(ipv6);    /* we communicate with a site using an IPv6 address */
+  BIT(do_more); /* this is set TRUE if the ->curl_do_more() function is
+                   supposed to be called, after ->curl_do() */
+  BIT(protoconnstart);/* the protocol layer has STARTED its operation after
+                         the TCP layer connect */
+  BIT(retry);         /* this connection is about to get closed and then
+                         re-attempted at another connection. */
+  BIT(authneg);       /* TRUE when the auth phase has started, which means
+                         that we are creating a request with an auth header,
+                         but it is not the final request in the auth
+                         negotiation. */
+  BIT(rewindaftersend);/* TRUE when the sending couldn't be stopped even
+                          though it will be discarded. When the whole send
+                          operation is done, we must call the data rewind
+                          callback. */
+#ifndef CURL_DISABLE_FTP
+  BIT(ftp_use_epsv);  /* As set with CURLOPT_FTP_USE_EPSV, but if we find out
+                         EPSV doesn't work we disable it for the forthcoming
+                         requests */
+  BIT(ftp_use_eprt);  /* As set with CURLOPT_FTP_USE_EPRT, but if we find out
+                         EPRT doesn't work we disable it for the forthcoming
+                         requests */
+  BIT(ftp_use_data_ssl); /* Enabled SSL for the data connection */
+#endif
+  BIT(netrc);         /* name+password provided by netrc */
+  BIT(bound); /* set true if bind() has already been done on this socket/
+                 connection */
+  BIT(multiplex); /* connection is multiplexed */
+  BIT(tcp_fastopen); /* use TCP Fast Open */
+  BIT(tls_enable_npn);  /* TLS NPN extension? */
+  BIT(tls_enable_alpn); /* TLS ALPN extension? */
+  BIT(connect_only);
+  BIT(doh);
+#ifdef USE_UNIX_SOCKETS
+  BIT(abstract_unix_socket);
+#endif
+  BIT(tls_upgraded);
+  BIT(sock_accepted); /* TRUE if the SECONDARYSOCKET was created with
+                         accept() */
+  BIT(parallel_connect); /* set TRUE when a parallel connect attempt has
+                            started (happy eyeballs) */
 };
 
 struct hostname {
@@ -491,7 +522,7 @@
   struct Curl_dns_entry *dns;
   int status; /* if done is TRUE, this is the status from the callback */
   void *os_specific;  /* 'struct thread_data' for Windows */
-  bit done:1;  /* set TRUE when the lookup is complete */
+  BIT(done);  /* set TRUE when the lookup is complete */
 };
 
 #define FIRSTSOCKET     0
@@ -518,9 +549,22 @@
   UPGR101_WORKING             /* talking upgraded protocol */
 };
 
-struct dohresponse {
-  unsigned char *memory;
-  size_t size;
+enum doh_slots {
+  /* Explicit values for first two symbols so as to match hard-coded
+   * constants in existing code
+   */
+  DOH_PROBE_SLOT_IPADDR_V4 = 0, /* make 'V4' stand out for readability */
+  DOH_PROBE_SLOT_IPADDR_V6 = 1, /* 'V6' likewise */
+
+  /* Space here for (possibly build-specific) additional slot definitions */
+
+  /* for example */
+  /* #ifdef WANT_DOH_FOOBAR_TXT */
+  /*   DOH_PROBE_SLOT_FOOBAR_TXT, */
+  /* #endif */
+
+  /* AFTER all slot definitions, establish how many we have */
+  DOH_PROBE_SLOTS
 };
 
 /* one of these for each DoH request */
@@ -529,12 +573,12 @@
   int dnstype;
   unsigned char dohbuffer[512];
   size_t dohlen;
-  struct dohresponse serverdoh;
+  struct dynbuf serverdoh;
 };
 
 struct dohdata {
   struct curl_slist *headers;
-  struct dnsprobe probe[2];
+  struct dnsprobe probe[DOH_PROBE_SLOTS];
   unsigned int pending; /* still outstanding requests */
   const char *host;
   int port;
@@ -573,12 +617,7 @@
                                    written as body */
   int headerline;               /* counts header lines to better track the
                                    first one */
-  char *hbufp;                  /* points at *end* of header line */
-  size_t hbuflen;
   char *str;                    /* within buf */
-  char *str_start;              /* within buf */
-  char *end_ptr;                /* within buf */
-  char *p;                      /* within headerbuff */
   curl_off_t offset;            /* possible resume offset read from the
                                    Content-Range: header */
   int httpcode;                 /* error code from the 'HTTP/1.? XXX' or
@@ -587,11 +626,10 @@
   enum expect100 exp100;        /* expect 100 continue state */
   enum upgrade101 upgr101;      /* 101 upgrade state */
 
-  struct contenc_writer_s *writer_stack;  /* Content unencoding stack. */
-                                          /* See sec 3.5, RFC2616. */
+  /* Content unencoding stack. See sec 3.5, RFC2616. */
+  struct contenc_writer *writer_stack;
   time_t timeofdoc;
   long bodywrites;
-  char *buf;
   int keepon;
   char *location;   /* This points to an allocated version of the Location:
                        header data */
@@ -612,20 +650,20 @@
 #ifndef CURL_DISABLE_DOH
   struct dohdata doh; /* DoH specific data for this request */
 #endif
-  bit header:1;       /* incoming data has HTTP header */
-  bit content_range:1; /* set TRUE if Content-Range: was found */
-  bit upload_done:1;  /* set to TRUE when doing chunked transfer-encoding
-                         upload and we're uploading the last chunk */
-  bit ignorebody:1;   /* we read a response-body but we ignore it! */
-  bit ignorecl:1;     /* This HTTP response has no body so we ignore the
-                         Content-Length: header */
-  bit chunk:1; /* if set, this is a chunked transfer-encoding */
-  bit upload_chunky:1; /* set TRUE if we are doing chunked transfer-encoding
-                          on upload */
-  bit getheader:1;    /* TRUE if header parsing is wanted */
-  bit forbidchunk:1;  /* used only to explicitly forbid chunk-upload for
-                         specific upload buffers. See readmoredata() in http.c
-                         for details. */
+  BIT(header);       /* incoming data has HTTP header */
+  BIT(content_range); /* set TRUE if Content-Range: was found */
+  BIT(upload_done);  /* set to TRUE when doing chunked transfer-encoding
+                        upload and we're uploading the last chunk */
+  BIT(ignorebody);   /* we read a response-body but we ignore it! */
+  BIT(http_bodyless); /* HTTP response status code is between 100 and 199,
+                         204 or 304 */
+  BIT(chunk); /* if set, this is a chunked transfer-encoding */
+  BIT(upload_chunky); /* set TRUE if we are doing chunked transfer-encoding
+                         on upload */
+  BIT(getheader);    /* TRUE if header parsing is wanted */
+  BIT(forbidchunk);  /* used only to explicitly forbid chunk-upload for
+                        specific upload buffers. See readmoredata() in http.c
+                        for details. */
 };
 
 /*
@@ -663,27 +701,23 @@
   /* Called from the multi interface during the PROTOCONNECT phase, and it
      should then return a proper fd set */
   int (*proto_getsock)(struct connectdata *conn,
-                       curl_socket_t *socks,
-                       int numsocks);
+                       curl_socket_t *socks);
 
   /* Called from the multi interface during the DOING phase, and it should
      then return a proper fd set */
   int (*doing_getsock)(struct connectdata *conn,
-                       curl_socket_t *socks,
-                       int numsocks);
+                       curl_socket_t *socks);
 
   /* Called from the multi interface during the DO_MORE phase, and it should
      then return a proper fd set */
   int (*domore_getsock)(struct connectdata *conn,
-                        curl_socket_t *socks,
-                        int numsocks);
+                        curl_socket_t *socks);
 
   /* Called from the multi interface during the DO_DONE, PERFORM and
      WAITPERFORM phases, and it should then return a proper fd set. Not setting
      this will make libcurl use the generic default one. */
   int (*perform_getsock)(const struct connectdata *conn,
-                         curl_socket_t *socks,
-                         int numsocks);
+                         curl_socket_t *socks);
 
   /* This function *MAY* be set to a protocol-dependent function that is run
    * by the curl_disconnect(), as a step in the disconnection.  If the handler
@@ -733,6 +767,8 @@
                                          HTTP proxy as HTTP proxies may know
                                          this protocol and act as a gateway */
 #define PROTOPT_WILDCARD (1<<12) /* protocol supports wildcard matching */
+#define PROTOPT_USERPWDCTRL (1<<13) /* Allow "control bytes" (< 32 ascii) in
+                                       user name and password */
 
 #define CONNCHECK_NONE 0                 /* No checks */
 #define CONNCHECK_ISDEAD (1<<0)          /* Check if the connection is dead. */
@@ -763,23 +799,55 @@
   char *passwd;  /* proxy password string, allocated */
 };
 
-#define CONNECT_BUFFER_SIZE 16384
-
 /* struct for HTTP CONNECT state data */
 struct http_connect_state {
-  char connect_buffer[CONNECT_BUFFER_SIZE];
-  int perline; /* count bytes per line */
+  struct dynbuf rcvbuf;
   int keepon;
-  char *line_start;
-  char *ptr; /* where to store more data */
   curl_off_t cl; /* size of content to read and ignore */
   enum {
     TUNNEL_INIT,    /* init/default/no tunnel state */
     TUNNEL_CONNECT, /* CONNECT has been sent off */
     TUNNEL_COMPLETE /* CONNECT response received completely */
   } tunnel_state;
-  bit chunked_encoding:1;
-  bit close_connection:1;
+  BIT(chunked_encoding);
+  BIT(close_connection);
+};
+
+struct ldapconninfo;
+
+/* for the (SOCKS) connect state machine */
+enum connect_t {
+  CONNECT_INIT,
+  CONNECT_SOCKS_INIT, /* 1 */
+  CONNECT_SOCKS_SEND, /* 2 waiting to send more first data */
+  CONNECT_SOCKS_READ_INIT, /* 3 set up read */
+  CONNECT_SOCKS_READ, /* 4 read server response */
+  CONNECT_GSSAPI_INIT, /* 5 */
+  CONNECT_AUTH_INIT, /* 6 setup outgoing auth buffer */
+  CONNECT_AUTH_SEND, /* 7 send auth */
+  CONNECT_AUTH_READ, /* 8 read auth response */
+  CONNECT_REQ_INIT,  /* 9 init SOCKS "request" */
+  CONNECT_RESOLVING, /* 10 */
+  CONNECT_RESOLVED,  /* 11 */
+  CONNECT_RESOLVE_REMOTE, /* 12 */
+  CONNECT_REQ_SEND,  /* 13 */
+  CONNECT_REQ_SENDING, /* 14 */
+  CONNECT_REQ_READ,  /* 15 */
+  CONNECT_REQ_READ_MORE, /* 16 */
+  CONNECT_DONE /* 17 connected fine to the remote or the SOCKS proxy */
+};
+
+#define SOCKS_STATE(x) (((x) >= CONNECT_SOCKS_INIT) &&  \
+                        ((x) < CONNECT_DONE))
+#define SOCKS_REQUEST_BUFSIZE 600  /* room for large user/pw (255 max each) */
+
+struct connstate {
+  enum connect_t state;
+  unsigned char socksreq[SOCKS_REQUEST_BUFSIZE];
+
+  /* CONNECT_SOCKS_SEND */
+  ssize_t outstanding;  /* send this many bytes more */
+  unsigned char *outp; /* send from this pointer */
 };
 
 /*
@@ -791,7 +859,7 @@
      caution that this might very well vary between different times this
      connection is used! */
   struct Curl_easy *data;
-
+  struct connstate cnnct;
   struct curl_llist_element bundle_node; /* conncache */
 
   /* chunk is for HTTP chunked encoding, but is in the general connectdata
@@ -814,15 +882,15 @@
 
   /* 'dns_entry' is the particular host we use. This points to an entry in the
      DNS cache and it will not get pruned while locked. It gets unlocked in
-     Curl_done(). This entry will be NULL if the connection is re-used as then
+     multi_done(). This entry will be NULL if the connection is re-used as then
      there is no name resolve done. */
   struct Curl_dns_entry *dns_entry;
 
   /* 'ip_addr' is the particular IP we connected to. It points to a struct
      within the DNS cache, so this pointer is only valid as long as the DNS
-     cache entry remains locked. It gets unlocked in Curl_done() */
-  Curl_addrinfo *ip_addr;
-  Curl_addrinfo *tempaddr[2]; /* for happy eyeballs */
+     cache entry remains locked. It gets unlocked in multi_done() */
+  struct Curl_addrinfo *ip_addr;
+  struct Curl_addrinfo *tempaddr[2]; /* for happy eyeballs */
 
   /* 'ip_addr_str' is the ip_addr data as a human readable string.
      It remains available as long as the connection does, which is longer than
@@ -831,17 +899,26 @@
 
   unsigned int scope_id;  /* Scope id for IPv6 */
 
-  int socktype;  /* SOCK_STREAM or SOCK_DGRAM */
+  enum {
+    TRNSPRT_TCP = 3,
+    TRNSPRT_UDP = 4,
+    TRNSPRT_QUIC = 5
+  } transport;
+
+#ifdef ENABLE_QUIC
+  struct quicsocket hequic[2]; /* two, for happy eyeballs! */
+  struct quicsocket *quic;
+#endif
 
   struct hostname host;
   char *hostname_resolve; /* host name to resolve to address, allocated */
   char *secondaryhostname; /* secondary socket host name (ftp) */
   struct hostname conn_to_host; /* the host to connect to. valid only if
                                    bits.conn_to_host is set */
-
+#ifndef CURL_DISABLE_PROXY
   struct proxy_info socks_proxy;
   struct proxy_info http_proxy;
-
+#endif
   long port;       /* which port to use locally */
   int remote_port; /* the remote port, not the proxy port! */
   int conn_to_port; /* the remote port to connect to. valid only if
@@ -870,7 +947,7 @@
   char *passwd;  /* password string, allocated */
   char *options; /* options string, allocated */
 
-  char *oauth_bearer; /* bearer token for OAuth 2.0, allocated */
+  char *sasl_authzid;     /* authorisation identity string, allocated */
 
   int httpversion;        /* the HTTP version*10 reported by the server */
   int rtspversion;        /* the RTSP version*10 reported by the server */
@@ -881,8 +958,7 @@
   curl_socket_t sock[2]; /* two sockets, the second is used for the data
                             transfer when doing FTP */
   curl_socket_t tempsock[2]; /* temporary sockets for happy eyeballs */
-  bool sock_accepted[2]; /* TRUE if the socket on this index was created with
-                            accept() */
+  int tempfamily[2]; /* family used for the temp sockets */
   Curl_recv *recv[2];
   Curl_send *send[2];
 
@@ -890,12 +966,16 @@
   struct postponed_data postponed[2]; /* two buffers for two sockets */
 #endif /* USE_RECV_BEFORE_SEND_WORKAROUND */
   struct ssl_connect_data ssl[2]; /* this is for ssl-stuff */
+#ifndef CURL_DISABLE_PROXY
   struct ssl_connect_data proxy_ssl[2]; /* this is for proxy ssl-stuff */
+#endif
 #ifdef USE_SSL
   void *ssl_extra; /* separately allocated backend-specific data */
 #endif
   struct ssl_primary_config ssl_config;
+#ifndef CURL_DISABLE_PROXY
   struct ssl_primary_config proxy_ssl_config;
+#endif
   struct ConnectBits bits;    /* various state-flags for this connection */
 
  /* connecttime: when connect() is called on the current IP address. Used to
@@ -904,8 +984,10 @@
   struct curltime connecttime;
   /* The two fields below get set in Curl_connecthost */
   int num_addr; /* number of addresses to try to connect to */
-  time_t timeoutms_per_addr; /* how long time in milliseconds to spend on
-                                trying to connect to each IP address */
+
+  /* how long time in milliseconds to spend on trying to connect to each IP
+     address, per family */
+  timediff_t timeoutms_per_addr[2];
 
   const struct Curl_handler *handler; /* Connection's protocol handler */
   const struct Curl_handler *given;   /* The protocol first given */
@@ -926,23 +1008,8 @@
                                 well be the same we read from.
                                 CURL_SOCKET_BAD disables */
 
-  /** Dynamically allocated strings, MUST be freed before this **/
-  /** struct is killed.                                      **/
-  struct dynamically_allocated_data {
-    char *proxyuserpwd;
-    char *uagent;
-    char *accept_encoding;
-    char *userpwd;
-    char *rangeline;
-    char *ref;
-    char *host;
-    char *cookiehost;
-    char *rtsp_transport;
-    char *te; /* TE: request header */
-  } allocptr;
-
 #ifdef HAVE_GSSAPI
-  bit sec_complete:1; /* if Kerberos is enabled for this connection */
+  BIT(sec_complete); /* if Kerberos is enabled for this connection */
   enum protection_level command_prot;
   enum protection_level data_prot;
   enum protection_level request_data_prot;
@@ -974,14 +1041,6 @@
                                because it authenticates connections, not
                                single requests! */
   struct ntlmdata proxyntlm; /* NTLM data for proxy */
-
-#if defined(NTLM_WB_ENABLED)
-  /* used for communication with Samba's winbind daemon helper ntlm_auth */
-  curl_socket_t ntlm_auth_hlpr_socket;
-  pid_t ntlm_auth_hlpr_pid;
-  char *challenge_header;
-  char *response_header;
-#endif
 #endif
 
 #ifdef USE_SPNEGO
@@ -995,10 +1054,8 @@
   /* data used for the asynch name resolve callback */
   struct Curl_async async;
 
-  /* These three are used for chunked-encoding trailer support */
-  char *trailer; /* allocated buffer to store trailer in */
-  int trlMax;    /* allocated buffer size */
-  int trlPos;    /* index of where to store data */
+  /* for chunked-encoded trailer */
+  struct dynbuf trailer;
 
   union {
     struct ftp_conn ftpc;
@@ -1010,7 +1067,9 @@
     struct smtp_conn smtpc;
     struct rtsp_conn rtspc;
     struct smb_conn smbc;
-    void *generic; /* RTMP and LDAP use this */
+    void *rtmp;
+    struct ldapconninfo *ldapc;
+    struct mqtt_conn mqtt;
   } proto;
 
   int cselect_bits; /* bitmask of socket events */
@@ -1031,19 +1090,10 @@
   struct http_connect_state *connect_state; /* for HTTP CONNECT */
   struct connectbundle *bundle; /* The bundle we are member of */
   int negnpn; /* APLN or NPN TLS negotiated protocol, CURL_HTTP_VERSION* */
-
+  int retrycount; /* number of retries on a new connection */
 #ifdef USE_UNIX_SOCKETS
   char *unix_domain_socket;
-  bit abstract_unix_socket:1;
 #endif
-  bit tls_upgraded:1;
-  /* the two following *_inuse fields are only flags, not counters in any way.
-     If TRUE it means the channel is in use, and if FALSE it means the channel
-     is up for grabs by one. */
-  bit readchannel_inuse:1;  /* whether the read channel is in use by an easy
-                               handle */
-  bit writechannel_inuse:1; /* whether the write channel is in use by an easy
-                               handle */
 };
 
 /* The end of connectdata. */
@@ -1065,6 +1115,7 @@
   long numconnects; /* how many new connection did libcurl created */
   char *contenttype; /* the content type of the object */
   char *wouldredirect; /* URL this would've been redirected to if asked to */
+  curl_off_t retry_after; /* info from Retry-After: header */
 
   /* PureInfo members 'conn_primary_ip', 'conn_primary_port', 'conn_local_ip'
      and, 'conn_local_port' are copied over from the connectdata struct in
@@ -1081,11 +1132,11 @@
   const char *conn_scheme;
   unsigned int conn_protocol;
   struct curl_certinfo certs; /* info about the certs, only populated in
-                                 OpenSSL builds. Asked for with
-                                 CURLOPT_CERTINFO / CURLINFO_CERTINFO */
-
-  bit timecond:1;  /* set to TRUE if the time condition didn't match, which
-                      thus made the document NOT get fetched */
+                                 OpenSSL, GnuTLS, Schannel, NSS and GSKit
+                                 builds. Asked for with CURLOPT_CERTINFO
+                                 / CURLINFO_CERTINFO */
+  BIT(timecond);  /* set to TRUE if the time condition didn't match, which
+                     thus made the document NOT get fetched */
 };
 
 
@@ -1102,17 +1153,17 @@
   int width; /* screen width at download start */
   int flags; /* see progress.h */
 
-  time_t timespent;
+  timediff_t timespent;
 
   curl_off_t dlspeed;
   curl_off_t ulspeed;
 
-  time_t t_nslookup;
-  time_t t_connect;
-  time_t t_appconnect;
-  time_t t_pretransfer;
-  time_t t_starttransfer;
-  time_t t_redirect;
+  timediff_t t_nslookup;
+  timediff_t t_connect;
+  timediff_t t_appconnect;
+  timediff_t t_pretransfer;
+  timediff_t t_starttransfer;
+  timediff_t t_redirect;
 
   struct curltime start;
   struct curltime t_startsingle;
@@ -1132,8 +1183,8 @@
   curl_off_t speeder[ CURR_TIME ];
   struct curltime speeder_time[ CURR_TIME ];
   int speeder_c;
-  bit callback:1;  /* set when progress callback is used */
-  bit is_t_startransfer_set:1;
+  BIT(callback);  /* set when progress callback is used */
+  BIT(is_t_startransfer_set);
 };
 
 typedef enum {
@@ -1164,29 +1215,18 @@
     RTSPREQ_LAST /* last in list */
 } Curl_RtspReq;
 
-/*
- * Values that are generated, temporary or calculated internally for a
- * "session handle" must be defined within the 'struct UrlState'.  This struct
- * will be used within the Curl_easy struct. When the 'Curl_easy'
- * struct is cloned, this data MUST NOT be copied.
- *
- * Remember that any "state" information goes globally for the curl handle.
- * Session-data MUST be put in the connectdata struct and here.  */
-#define MAX_CURL_USER_LENGTH 256
-#define MAX_CURL_PASSWORD_LENGTH 256
-
 struct auth {
   unsigned long want;  /* Bitmask set to the authentication methods wanted by
                           app (with CURLOPT_HTTPAUTH or CURLOPT_PROXYAUTH). */
   unsigned long picked;
   unsigned long avail; /* Bitmask for what the server reports to support for
                           this resource */
-  bit done:1;  /* TRUE when the auth phase is done and ready to do the
-                 *actual* request */
-  bit multipass:1; /* TRUE if this is not yet authenticated but within the
-                       auth multipass negotiation */
-  bit iestyle:1; /* TRUE if digest should be done IE-style or FALSE if it
-                     should be RFC compliant */
+  BIT(done);  /* TRUE when the auth phase is done and ready to do the
+                 actual request */
+  BIT(multipass); /* TRUE if this is not yet authenticated but within the
+                     auth multipass negotiation */
+  BIT(iestyle); /* TRUE if digest should be done IE-style or FALSE if it
+                   should be RFC compliant */
 };
 
 struct Curl_http2_dep {
@@ -1200,9 +1240,7 @@
  * BODY).
  */
 struct tempbuf {
-  char *buf;  /* allocated buffer to keep data in when a write callback
-                 returns to make the connection paused */
-  size_t len; /* size of the 'tempwrite' allocated buffer */
+  struct dynbuf b;
   int type;   /* type of the 'tempwrite' buffer as a bitmask that is used with
                  Curl_client_write() */
 };
@@ -1212,7 +1250,8 @@
   EXPIRE_100_TIMEOUT,
   EXPIRE_ASYNC_NAME,
   EXPIRE_CONNECTTIMEOUT,
-  EXPIRE_DNS_PER_NAME,
+  EXPIRE_DNS_PER_NAME, /* family1 */
+  EXPIRE_DNS_PER_NAME2, /* family2 */
   EXPIRE_HAPPY_EYEBALLS_DNS, /* See asyn-ares.c */
   EXPIRE_HAPPY_EYEBALLS,
   EXPIRE_MULTI_PENDING,
@@ -1220,6 +1259,7 @@
   EXPIRE_SPEEDCHECK,
   EXPIRE_TIMEOUT,
   EXPIRE_TOOFAST,
+  EXPIRE_QUIC,
   EXPIRE_LAST /* not an actual timer, used as a marker only */
 } expire_id;
 
@@ -1254,7 +1294,6 @@
 };
 
 struct UrlState {
-
   /* Points to the connection cache */
   struct conncache *conn_cache;
 
@@ -1262,9 +1301,7 @@
   struct curltime keeps_speed; /* for the progress meter really */
 
   struct connectdata *lastconnect; /* The last connection, NULL if undefined */
-
-  char *headerbuff; /* allocated buffer to store headers in */
-  size_t headersize;   /* size of the allocation */
+  struct dynbuf headerb; /* buffer to store headers in */
 
   char *buffer; /* download buffer */
   char *ulbuf; /* allocated upload buffer or NULL */
@@ -1315,7 +1352,7 @@
 /* do FTP line-end conversions on most platforms */
 #define CURL_DO_LINEEND_CONV
   /* for FTP downloads: track CRLF sequences that span blocks */
-  bit prev_block_had_trailing_cr:1;
+  BIT(prev_block_had_trailing_cr);
   /* for FTP downloads: how many CRLFs did we converted to LFs? */
   curl_off_t crlf_conversions;
 #endif
@@ -1342,40 +1379,60 @@
   int stream_weight;
   CURLU *uh; /* URL handle for the current parsed URL */
   struct urlpieces up;
+  Curl_HttpReq httpreq; /* what kind of HTTP request (if any) is this */
 #ifndef CURL_DISABLE_HTTP
   size_t trailers_bytes_sent;
-  Curl_send_buffer *trailers_buf; /* a buffer containing the compiled trailing
-                                  headers */
+  struct dynbuf trailers_buf; /* a buffer containing the compiled trailing
+                                 headers */
 #endif
   trailers_state trailers_state; /* whether we are sending trailers
                                        and what stage are we at */
+
+  /* Dynamically allocated strings, MUST be freed before this struct is
+     killed. */
+  struct dynamically_allocated_data {
+    char *proxyuserpwd;
+    char *uagent;
+    char *accept_encoding;
+    char *userpwd;
+    char *rangeline;
+    char *ref;
+    char *host;
+    char *cookiehost;
+    char *rtsp_transport;
+    char *te; /* TE: request header */
+  } aptr;
+
 #ifdef CURLDEBUG
-  bit conncache_lock:1;
+  BIT(conncache_lock);
 #endif
   /* when curl_easy_perform() is called, the multi handle is "owned" by
      the easy handle so curl_easy_cleanup() on such an easy handle will
      also close the multi handle! */
-  bit multi_owned_by_easy:1;
+  BIT(multi_owned_by_easy);
 
-  bit this_is_a_follow:1; /* this is a followed Location: request */
-  bit refused_stream:1; /* this was refused, try again */
-  bit errorbuf:1; /* Set to TRUE if the error buffer is already filled in.
+  BIT(this_is_a_follow); /* this is a followed Location: request */
+  BIT(refused_stream); /* this was refused, try again */
+  BIT(errorbuf); /* Set to TRUE if the error buffer is already filled in.
                     This must be set to FALSE every time _easy_perform() is
                     called. */
-  bit allow_port:1; /* Is set.use_port allowed to take effect or not. This
+  BIT(allow_port); /* Is set.use_port allowed to take effect or not. This
                       is always set TRUE when curl_easy_perform() is called. */
-  bit authproblem:1; /* TRUE if there's some problem authenticating */
+  BIT(authproblem); /* TRUE if there's some problem authenticating */
   /* set after initial USER failure, to prevent an authentication loop */
-  bit ftp_trying_alternative:1;
-  bit wildcardmatch:1; /* enable wildcard matching */
-  bit expect100header:1;  /* TRUE if we added Expect: 100-continue */
-  bit use_range:1;
-  bit rangestringalloc:1; /* the range string is malloc()'ed */
-  bit done:1; /* set to FALSE when Curl_init_do() is called and set to TRUE
+  BIT(ftp_trying_alternative);
+  BIT(wildcardmatch); /* enable wildcard matching */
+  BIT(expect100header);  /* TRUE if we added Expect: 100-continue */
+  BIT(disableexpect);    /* TRUE if Expect: is disabled due to a previous
+                            417 response */
+  BIT(use_range);
+  BIT(rangestringalloc); /* the range string is malloc()'ed */
+  BIT(done); /* set to FALSE when Curl_init_do() is called and set to TRUE
                   when multi_done() is called, to prevent multi_done() to get
                   invoked twice when the multi interface is used. */
-  bit stream_depends_e:1; /* set or don't set the Exclusive bit */
-  bit previouslypending:1; /* this transfer WAS in the multi->pending queue */
+  BIT(stream_depends_e); /* set or don't set the Exclusive bit */
+  BIT(previouslypending); /* this transfer WAS in the multi->pending queue */
+  BIT(cookie_engine);
 };
 
 
@@ -1393,9 +1450,9 @@
                                     curl_easy_setopt(COOKIEFILE) calls */
   struct curl_slist *resolve; /* set to point to the set.resolve list when
                                  this should be dealt with in pretransfer */
-  bit url_alloc:1;   /* URL string is malloc()'ed */
-  bit referer_alloc:1; /* referer string is malloc()ed */
-  bit wildcard_resolve:1; /* Set to true if any resolve change is a
+  BIT(url_alloc);   /* URL string is malloc()'ed */
+  BIT(referer_alloc); /* referer string is malloc()ed */
+  BIT(wildcard_resolve); /* Set to true if any resolve change is a
                               wildcard */
 };
 
@@ -1410,6 +1467,14 @@
 
 struct Curl_multi;    /* declared and used only in multi.c */
 
+/*
+ * This enumeration MUST not use conditional directives (#ifdefs), new
+ * null terminated strings MUST be added to the enumeration immediately
+ * before STRING_LASTZEROTERMINATED, binary fields immediately before
+ * STRING_LAST. When doing so, ensure that the packages/OS400/chkstring.c
+ * test is updated and applicable changes for EBCDIC to ASCII conversion
+ * are catered for in curl_easy_setopt_ccsid()
+ */
 enum dupstring {
   STRING_CERT_ORIG,       /* client certificate file name */
   STRING_CERT_PROXY,      /* client certificate file name */
@@ -1466,33 +1531,41 @@
   STRING_RTSP_SESSION_ID, /* Session ID to use */
   STRING_RTSP_STREAM_URI, /* Stream URI for this request */
   STRING_RTSP_TRANSPORT,  /* Transport for this session */
-#ifdef USE_SSH
+
   STRING_SSH_PRIVATE_KEY, /* path to the private key file for auth */
   STRING_SSH_PUBLIC_KEY,  /* path to the public key file for auth */
   STRING_SSH_HOST_PUBLIC_KEY_MD5, /* md5 of host public key in ascii hex */
   STRING_SSH_KNOWNHOSTS,  /* file name of knownhosts file */
-#endif
+
   STRING_PROXY_SERVICE_NAME, /* Proxy service name */
   STRING_SERVICE_NAME,    /* Service name */
   STRING_MAIL_FROM,
   STRING_MAIL_AUTH,
 
-#ifdef USE_TLS_SRP
   STRING_TLSAUTH_USERNAME_ORIG,  /* TLS auth <username> */
   STRING_TLSAUTH_USERNAME_PROXY, /* TLS auth <username> */
   STRING_TLSAUTH_PASSWORD_ORIG,  /* TLS auth <password> */
   STRING_TLSAUTH_PASSWORD_PROXY, /* TLS auth <password> */
-#endif
+
   STRING_BEARER,                /* <bearer>, if used */
-#ifdef USE_UNIX_SOCKETS
+
   STRING_UNIX_SOCKET_PATH,      /* path to Unix socket, if used */
-#endif
+
   STRING_TARGET,                /* CURLOPT_REQUEST_TARGET */
   STRING_DOH,                   /* CURLOPT_DOH_URL */
-#ifdef USE_ALTSVC
+
   STRING_ALTSVC,                /* CURLOPT_ALTSVC */
-#endif
-  /* -- end of zero-terminated strings -- */
+
+  STRING_SASL_AUTHZID,          /* CURLOPT_SASL_AUTHZID */
+
+  STRING_TEMP_URL,              /* temp URL storage for proxy use */
+
+  STRING_DNS_SERVERS,
+  STRING_DNS_INTERFACE,
+  STRING_DNS_LOCAL_IP4,
+  STRING_DNS_LOCAL_IP6,
+
+  /* -- end of null-terminated strings -- */
 
   STRING_LASTZEROTERMINATED,
 
@@ -1500,9 +1573,20 @@
 
   STRING_COPYPOSTFIELDS,  /* if POST, set the fields' values here */
 
+
   STRING_LAST /* not used, just an end-of-list marker */
 };
 
+enum dupblob {
+  BLOB_CERT_ORIG,
+  BLOB_CERT_PROXY,
+  BLOB_KEY_ORIG,
+  BLOB_KEY_PROXY,
+  BLOB_SSL_ISSUERCERT_ORIG,
+  BLOB_SSL_ISSUERCERT_PROXY,
+  BLOB_LAST
+};
+
 /* callback that gets called when this easy handle is completed within a multi
    handle.  Only used for internally created transfers, like for example
    DoH. */
@@ -1600,11 +1684,13 @@
                                     the hostname and port to connect to */
   curl_TimeCond timecondition; /* kind of time/date comparison */
   time_t timevalue;       /* what time to compare with */
-  Curl_HttpReq httpreq;   /* what kind of HTTP request (if any) is this */
+  Curl_HttpReq method;   /* what kind of HTTP request (if any) is this */
   long httpversion; /* when non-zero, a specific HTTP version requested to
                        be used in the library's request(s) */
   struct ssl_config_data ssl;  /* user defined SSL stuff */
+#ifndef CURL_DISABLE_PROXY
   struct ssl_config_data proxy_ssl;  /* user defined SSL stuff for proxy */
+#endif
   struct ssl_general_config general_ssl; /* general user defined SSL stuff */
   curl_proxytype proxytype; /* what kind of proxy that is in use */
   long dns_cache_timeout; /* DNS cache timeout */
@@ -1634,6 +1720,7 @@
   long new_directory_perms; /* Permissions to use when creating remote dirs */
   long ssh_auth_types;   /* allowed SSH auth types */
   char *str[STRING_LAST]; /* array of strings, pointing to allocated memory */
+  struct curl_blob *blobs[BLOB_LAST];
   unsigned int scope_id;  /* Scope id for IPv6 */
   long allowed_protocols;
   long redir_protocols;
@@ -1671,84 +1758,84 @@
   CURLU *uh; /* URL handle for the current parsed URL */
   void *trailer_data; /* pointer to pass to trailer data callback */
   curl_trailer_callback trailer_callback; /* trailing data callback */
-  bit is_fread_set:1; /* has read callback been set to non-NULL? */
-  bit is_fwrite_set:1; /* has write callback been set to non-NULL? */
-  bit free_referer:1; /* set TRUE if 'referer' points to a string we
+  BIT(is_fread_set); /* has read callback been set to non-NULL? */
+  BIT(is_fwrite_set); /* has write callback been set to non-NULL? */
+  BIT(free_referer); /* set TRUE if 'referer' points to a string we
                         allocated */
-  bit tftp_no_options:1; /* do not send TFTP options requests */
-  bit sep_headers:1;     /* handle host and proxy headers separately */
-  bit cookiesession:1;   /* new cookie session? */
-  bit crlf:1;            /* convert crlf on ftp upload(?) */
-  bit strip_path_slash:1; /* strip off initial slash from path */
-  bit ssh_compression:1;            /* enable SSH compression */
+  BIT(tftp_no_options); /* do not send TFTP options requests */
+  BIT(sep_headers);     /* handle host and proxy headers separately */
+  BIT(cookiesession);   /* new cookie session? */
+  BIT(crlf);            /* convert crlf on ftp upload(?) */
+  BIT(strip_path_slash); /* strip off initial slash from path */
+  BIT(ssh_compression);            /* enable SSH compression */
 
 /* Here follows boolean settings that define how to behave during
    this session. They are STATIC, set by libcurl users or at least initially
    and they don't change during operations. */
-  bit get_filetime:1;     /* get the time and get of the remote file */
-  bit tunnel_thru_httpproxy:1; /* use CONNECT through a HTTP proxy */
-  bit prefer_ascii:1;     /* ASCII rather than binary */
-  bit ftp_append:1;       /* append, not overwrite, on upload */
-  bit ftp_list_only:1;    /* switch FTP command for listing directories */
+  BIT(get_filetime);     /* get the time and get of the remote file */
+  BIT(tunnel_thru_httpproxy); /* use CONNECT through a HTTP proxy */
+  BIT(prefer_ascii);     /* ASCII rather than binary */
+  BIT(ftp_append);       /* append, not overwrite, on upload */
+  BIT(ftp_list_only);    /* switch FTP command for listing directories */
 #ifndef CURL_DISABLE_FTP
-  bit ftp_use_port:1;     /* use the FTP PORT command */
-  bit ftp_use_epsv:1;   /* if EPSV is to be attempted or not */
-  bit ftp_use_eprt:1;   /* if EPRT is to be attempted or not */
-  bit ftp_use_pret:1;   /* if PRET is to be used before PASV or not */
-  bit ftp_skip_ip:1;    /* skip the IP address the FTP server passes on to
+  BIT(ftp_use_port);     /* use the FTP PORT command */
+  BIT(ftp_use_epsv);     /* if EPSV is to be attempted or not */
+  BIT(ftp_use_eprt);     /* if EPRT is to be attempted or not */
+  BIT(ftp_use_pret);     /* if PRET is to be used before PASV or not */
+  BIT(ftp_skip_ip);      /* skip the IP address the FTP server passes on to
                             us */
 #endif
-  bit hide_progress:1;    /* don't use the progress meter */
-  bit http_fail_on_error:1;  /* fail on HTTP error codes >= 400 */
-  bit http_keep_sending_on_error:1; /* for HTTP status codes >= 300 */
-  bit http_follow_location:1; /* follow HTTP redirects */
-  bit http_transfer_encoding:1; /* request compressed HTTP
-                                    transfer-encoding */
-  bit allow_auth_to_other_hosts:1;
-  bit include_header:1; /* include received protocol headers in data output */
-  bit http_set_referer:1; /* is a custom referer used */
-  bit http_auto_referer:1; /* set "correct" referer when following
-                               location: */
-  bit opt_no_body:1;    /* as set with CURLOPT_NOBODY */
-  bit upload:1;         /* upload request */
-  bit verbose:1;        /* output verbosity */
-  bit krb:1;            /* Kerberos connection requested */
-  bit reuse_forbid:1;   /* forbidden to be reused, close after use */
-  bit reuse_fresh:1;    /* do not re-use an existing connection  */
-
-  bit no_signal:1;      /* do not use any signal/alarm handler */
-  bit tcp_nodelay:1;    /* whether to enable TCP_NODELAY or not */
-  bit ignorecl:1;       /* ignore content length */
-  bit connect_only:1;   /* make connection, let application use the socket */
-  bit http_te_skip:1;   /* pass the raw body data to the user, even when
-                            transfer-encoded (chunked, compressed) */
-  bit http_ce_skip:1;   /* pass the raw body data to the user, even when
-                            content-encoded (chunked, compressed) */
-  bit proxy_transfer_mode:1; /* set transfer mode (;type=<a|i>) when doing
-                                 FTP via an HTTP proxy */
+  BIT(hide_progress);    /* don't use the progress meter */
+  BIT(http_fail_on_error);  /* fail on HTTP error codes >= 400 */
+  BIT(http_keep_sending_on_error); /* for HTTP status codes >= 300 */
+  BIT(http_follow_location); /* follow HTTP redirects */
+  BIT(http_transfer_encoding); /* request compressed HTTP transfer-encoding */
+  BIT(allow_auth_to_other_hosts);
+  BIT(include_header); /* include received protocol headers in data output */
+  BIT(http_set_referer); /* is a custom referer used */
+  BIT(http_auto_referer); /* set "correct" referer when following
+                             location: */
+  BIT(opt_no_body);    /* as set with CURLOPT_NOBODY */
+  BIT(upload);         /* upload request */
+  BIT(verbose);        /* output verbosity */
+  BIT(krb);            /* Kerberos connection requested */
+  BIT(reuse_forbid);   /* forbidden to be reused, close after use */
+  BIT(reuse_fresh);    /* do not re-use an existing connection  */
+  BIT(no_signal);      /* do not use any signal/alarm handler */
+  BIT(tcp_nodelay);    /* whether to enable TCP_NODELAY or not */
+  BIT(ignorecl);       /* ignore content length */
+  BIT(connect_only);   /* make connection, let application use the socket */
+  BIT(http_te_skip);   /* pass the raw body data to the user, even when
+                          transfer-encoded (chunked, compressed) */
+  BIT(http_ce_skip);   /* pass the raw body data to the user, even when
+                          content-encoded (chunked, compressed) */
+  BIT(proxy_transfer_mode); /* set transfer mode (;type=<a|i>) when doing
+                               FTP via an HTTP proxy */
 #if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI)
-  bit socks5_gssapi_nec:1; /* Flag to support NEC SOCKS5 server */
+  BIT(socks5_gssapi_nec); /* Flag to support NEC SOCKS5 server */
 #endif
-  bit sasl_ir:1;         /* Enable/disable SASL initial response */
-  bit wildcard_enabled:1; /* enable wildcard matching */
-  bit tcp_keepalive:1;  /* use TCP keepalives */
-  bit tcp_fastopen:1;   /* use TCP Fast Open */
-  bit ssl_enable_npn:1; /* TLS NPN extension? */
-  bit ssl_enable_alpn:1;/* TLS ALPN extension? */
-  bit path_as_is:1;     /* allow dotdots? */
-  bit pipewait:1;       /* wait for multiplex status before starting a new
-                           connection */
-  bit suppress_connect_headers:1; /* suppress proxy CONNECT response headers
-                                      from user callbacks */
-  bit dns_shuffle_addresses:1; /* whether to shuffle addresses before use */
-  bit stream_depends_e:1; /* set or don't set the Exclusive bit */
-  bit haproxyprotocol:1; /* whether to send HAProxy PROXY protocol v1
-                             header */
-  bit abstract_unix_socket:1;
-  bit disallow_username_in_url:1; /* disallow username in url */
-  bit doh:1; /* DNS-over-HTTPS enabled */
-  bit doh_get:1; /* use GET for DoH requests, instead of POST */
-  bit http09_allowed:1; /* allow HTTP/0.9 responses */
+  BIT(sasl_ir);         /* Enable/disable SASL initial response */
+  BIT(wildcard_enabled); /* enable wildcard matching */
+  BIT(tcp_keepalive);  /* use TCP keepalives */
+  BIT(tcp_fastopen);   /* use TCP Fast Open */
+  BIT(ssl_enable_npn); /* TLS NPN extension? */
+  BIT(ssl_enable_alpn);/* TLS ALPN extension? */
+  BIT(path_as_is);     /* allow dotdots? */
+  BIT(pipewait);       /* wait for multiplex status before starting a new
+                          connection */
+  BIT(suppress_connect_headers); /* suppress proxy CONNECT response headers
+                                    from user callbacks */
+  BIT(dns_shuffle_addresses); /* whether to shuffle addresses before use */
+  BIT(stream_depends_e); /* set or don't set the Exclusive bit */
+  BIT(haproxyprotocol); /* whether to send HAProxy PROXY protocol v1
+                           header */
+  BIT(abstract_unix_socket);
+  BIT(disallow_username_in_url); /* disallow username in url */
+  BIT(doh); /* DNS-over-HTTPS enabled */
+  BIT(doh_get); /* use GET for DoH requests, instead of POST */
+  BIT(http09_allowed); /* allow HTTP/0.9 responses */
+  BIT(mail_rcpt_allowfails); /* allow RCPT TO command to fail for some
+                                recipients */
 };
 
 struct Names {
@@ -1777,7 +1864,6 @@
 
   struct connectdata *conn;
   struct curl_llist_element connect_queue;
-  struct curl_llist_element sh_queue; /* list per Curl_sh_entry */
   struct curl_llist_element conn_queue; /* list per connectdata */
 
   CURLMstate mstate;  /* the handle's state */
diff --git a/Utilities/cmcurl/lib/vauth/cleartext.c b/Utilities/cmcurl/lib/vauth/cleartext.c
index 6f452c1..3a5c943 100644
--- a/Utilities/cmcurl/lib/vauth/cleartext.c
+++ b/Utilities/cmcurl/lib/vauth/cleartext.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -81,7 +81,8 @@
   plen = strlen(passwd);
 
   /* Compute binary message length. Check for overflows. */
-  if(((zlen + clen) > SIZE_T_MAX/4) || (plen > (SIZE_T_MAX/2 - 2)))
+  if((zlen > SIZE_T_MAX/4) || (clen > SIZE_T_MAX/4) ||
+     (plen > (SIZE_T_MAX/2 - 2)))
     return CURLE_OUT_OF_MEMORY;
   plainlen = zlen + clen + plen + 2;
 
diff --git a/Utilities/cmcurl/lib/vauth/cram.c b/Utilities/cmcurl/lib/vauth/cram.c
index d148618..717d7f0 100644
--- a/Utilities/cmcurl/lib/vauth/cram.c
+++ b/Utilities/cmcurl/lib/vauth/cram.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -96,7 +96,7 @@
 {
   CURLcode result = CURLE_OK;
   size_t chlglen = 0;
-  HMAC_context *ctxt;
+  struct HMAC_context *ctxt;
   unsigned char digest[MD5_DIGEST_LEN];
   char *response;
 
diff --git a/Utilities/cmcurl/lib/vauth/digest.c b/Utilities/cmcurl/lib/vauth/digest.c
index f9cdc9d..b9210a8 100644
--- a/Utilities/cmcurl/lib/vauth/digest.c
+++ b/Utilities/cmcurl/lib/vauth/digest.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -62,7 +62,7 @@
    what ultimately goes over the network.
 */
 #define CURL_OUTPUT_DIGEST_CONV(a, b) \
-  result = Curl_convert_to_network(a, (char *)b, strlen((const char *)b)); \
+  result = Curl_convert_to_network(a, b, strlen(b)); \
   if(result) { \
     free(b); \
     return result; \
@@ -357,9 +357,8 @@
                                              const char *service,
                                              char **outptr, size_t *outlen)
 {
-  CURLcode result = CURLE_OK;
   size_t i;
-  MD5_context *ctxt;
+  struct MD5_context *ctxt;
   char *response = NULL;
   unsigned char digest[MD5_DIGEST_LEN];
   char HA1_hex[2 * MD5_DIGEST_LEN + 1];
@@ -377,10 +376,12 @@
   char *spn         = NULL;
 
   /* Decode the challenge message */
-  result = auth_decode_digest_md5_message(chlg64, nonce, sizeof(nonce),
-                                          realm, sizeof(realm),
-                                          algorithm, sizeof(algorithm),
-                                          qop_options, sizeof(qop_options));
+  CURLcode result = auth_decode_digest_md5_message(chlg64, nonce,
+                                                   sizeof(nonce), realm,
+                                                   sizeof(realm), algorithm,
+                                                   sizeof(algorithm),
+                                                   qop_options,
+                                                   sizeof(qop_options));
   if(result)
     return result;
 
@@ -659,7 +660,7 @@
 }
 
 /*
- * _Curl_auth_create_digest_http_message()
+ * auth_create_digest_http_message()
  *
  * This is used to generate a HTTP DIGEST response message ready for sending
  * to the recipient.
@@ -678,7 +679,7 @@
  *
  * Returns CURLE_OK on success.
  */
-static CURLcode _Curl_auth_create_digest_http_message(
+static CURLcode auth_create_digest_http_message(
                   struct Curl_easy *data,
                   const char *userp,
                   const char *passwdp,
@@ -687,12 +688,12 @@
                   struct digestdata *digest,
                   char **outptr, size_t *outlen,
                   void (*convert_to_ascii)(unsigned char *, unsigned char *),
-                  void (*hash)(unsigned char *, const unsigned char *))
+                  void (*hash)(unsigned char *, const unsigned char *,
+                               const size_t))
 {
   CURLcode result;
   unsigned char hashbuf[32]; /* 32 bytes/256 bits */
   unsigned char request_digest[65];
-  unsigned char *hashthis;
   unsigned char ha1[65];    /* 64 digits and 1 zero byte */
   unsigned char ha2[65];    /* 64 digits and 1 zero byte */
   char userh[65];
@@ -700,6 +701,7 @@
   size_t cnonce_sz = 0;
   char *userp_quoted;
   char *response = NULL;
+  char *hashthis = NULL;
   char *tmp = NULL;
 
   if(!digest->nc)
@@ -721,12 +723,12 @@
   }
 
   if(digest->userhash) {
-    hashthis = (unsigned char *) aprintf("%s:%s", userp, digest->realm);
+    hashthis = aprintf("%s:%s", userp, digest->realm);
     if(!hashthis)
       return CURLE_OUT_OF_MEMORY;
 
     CURL_OUTPUT_DIGEST_CONV(data, hashthis);
-    hash(hashbuf, hashthis);
+    hash(hashbuf, (unsigned char *) hashthis, strlen(hashthis));
     free(hashthis);
     convert_to_ascii(hashbuf, (unsigned char *)userh);
   }
@@ -742,14 +744,13 @@
            unq(nonce-value) ":" unq(cnonce-value)
   */
 
-  hashthis = (unsigned char *)
-    aprintf("%s:%s:%s", digest->userhash ? userh : userp,
-                                    digest->realm, passwdp);
+  hashthis = aprintf("%s:%s:%s", digest->userhash ? userh : userp,
+                                 digest->realm, passwdp);
   if(!hashthis)
     return CURLE_OUT_OF_MEMORY;
 
   CURL_OUTPUT_DIGEST_CONV(data, hashthis); /* convert on non-ASCII machines */
-  hash(hashbuf, hashthis);
+  hash(hashbuf, (unsigned char *) hashthis, strlen(hashthis));
   free(hashthis);
   convert_to_ascii(hashbuf, ha1);
 
@@ -762,7 +763,7 @@
       return CURLE_OUT_OF_MEMORY;
 
     CURL_OUTPUT_DIGEST_CONV(data, tmp); /* Convert on non-ASCII machines */
-    hash(hashbuf, (unsigned char *) tmp);
+    hash(hashbuf, (unsigned char *) tmp, strlen(tmp));
     free(tmp);
     convert_to_ascii(hashbuf, ha1);
   }
@@ -780,19 +781,19 @@
     5.1.1 of RFC 2616)
   */
 
-  hashthis = (unsigned char *) aprintf("%s:%s", request, uripath);
+  hashthis = aprintf("%s:%s", request, uripath);
   if(!hashthis)
     return CURLE_OUT_OF_MEMORY;
 
   if(digest->qop && strcasecompare(digest->qop, "auth-int")) {
     /* We don't support auth-int for PUT or POST */
     char hashed[65];
-    unsigned char *hashthis2;
+    char *hashthis2;
 
-    hash(hashbuf, (const unsigned char *)"");
+    hash(hashbuf, (const unsigned char *)"", 0);
     convert_to_ascii(hashbuf, (unsigned char *)hashed);
 
-    hashthis2 = (unsigned char *)aprintf("%s:%s", hashthis, hashed);
+    hashthis2 = aprintf("%s:%s", hashthis, hashed);
     free(hashthis);
     hashthis = hashthis2;
   }
@@ -801,31 +802,23 @@
     return CURLE_OUT_OF_MEMORY;
 
   CURL_OUTPUT_DIGEST_CONV(data, hashthis); /* convert on non-ASCII machines */
-  hash(hashbuf, hashthis);
+  hash(hashbuf, (unsigned char *) hashthis, strlen(hashthis));
   free(hashthis);
   convert_to_ascii(hashbuf, ha2);
 
   if(digest->qop) {
-    hashthis = (unsigned char *) aprintf("%s:%s:%08x:%s:%s:%s",
-                                        ha1,
-                                        digest->nonce,
-                                        digest->nc,
-                                        digest->cnonce,
-                                        digest->qop,
-                                        ha2);
+    hashthis = aprintf("%s:%s:%08x:%s:%s:%s", ha1, digest->nonce, digest->nc,
+                       digest->cnonce, digest->qop, ha2);
   }
   else {
-    hashthis = (unsigned char *) aprintf("%s:%s:%s",
-                                        ha1,
-                                        digest->nonce,
-                                        ha2);
+    hashthis = aprintf("%s:%s:%s", ha1, digest->nonce, ha2);
   }
 
   if(!hashthis)
     return CURLE_OUT_OF_MEMORY;
 
   CURL_OUTPUT_DIGEST_CONV(data, hashthis); /* convert on non-ASCII machines */
-  hash(hashbuf, hashthis);
+  hash(hashbuf, (unsigned char *) hashthis, strlen(hashthis));
   free(hashthis);
   convert_to_ascii(hashbuf, request_digest);
 
@@ -898,7 +891,7 @@
 
   if(digest->algorithm) {
     /* Append the algorithm */
-    tmp = aprintf("%s, algorithm=\"%s\"", response, digest->algorithm);
+    tmp = aprintf("%s, algorithm=%s", response, digest->algorithm);
     free(response);
     if(!tmp)
       return CURLE_OUT_OF_MEMORY;
@@ -954,21 +947,21 @@
   switch(digest->algo) {
   case CURLDIGESTALGO_MD5:
   case CURLDIGESTALGO_MD5SESS:
-    return _Curl_auth_create_digest_http_message(data, userp, passwdp,
-                                                 request, uripath, digest,
-                                                 outptr, outlen,
-                                                 auth_digest_md5_to_ascii,
-                                                 Curl_md5it);
+    return auth_create_digest_http_message(data, userp, passwdp,
+                                           request, uripath, digest,
+                                           outptr, outlen,
+                                           auth_digest_md5_to_ascii,
+                                           Curl_md5it);
 
   case CURLDIGESTALGO_SHA256:
   case CURLDIGESTALGO_SHA256SESS:
   case CURLDIGESTALGO_SHA512_256:
   case CURLDIGESTALGO_SHA512_256SESS:
-    return _Curl_auth_create_digest_http_message(data, userp, passwdp,
-                                                 request, uripath, digest,
-                                                 outptr, outlen,
-                                                 auth_digest_sha256_to_ascii,
-                                                 Curl_sha256it);
+    return auth_create_digest_http_message(data, userp, passwdp,
+                                           request, uripath, digest,
+                                           outptr, outlen,
+                                           auth_digest_sha256_to_ascii,
+                                           Curl_sha256it);
 
   default:
     return CURLE_UNSUPPORTED_PROTOCOL;
diff --git a/Utilities/cmcurl/lib/vauth/digest.h b/Utilities/cmcurl/lib/vauth/digest.h
index 8686c44..cc05fdb 100644
--- a/Utilities/cmcurl/lib/vauth/digest.h
+++ b/Utilities/cmcurl/lib/vauth/digest.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
diff --git a/Utilities/cmcurl/lib/vauth/digest_sspi.c b/Utilities/cmcurl/lib/vauth/digest_sspi.c
index fe8093e..4998306 100644
--- a/Utilities/cmcurl/lib/vauth/digest_sspi.c
+++ b/Utilities/cmcurl/lib/vauth/digest_sspi.c
@@ -6,7 +6,7 @@
  *                             \___|\___/|_| \_\_____|
  *
  * Copyright (C) 2014 - 2016, Steve Holme, <steve_holme@hotmail.com>.
- * Copyright (C) 2015 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 2015 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -61,6 +61,11 @@
   status = s_pSecFn->QuerySecurityPackageInfo((TCHAR *) TEXT(SP_NAME_DIGEST),
                                               &SecurityPackage);
 
+  /* Release the package buffer as it is not required anymore */
+  if(status == SEC_E_OK) {
+    s_pSecFn->FreeContextBuffer(SecurityPackage);
+  }
+
   return (status == SEC_E_OK ? TRUE : FALSE);
 }
 
@@ -129,7 +134,8 @@
   if(status != SEC_E_OK) {
     free(input_token);
 
-    return CURLE_NOT_BUILT_IN;
+    failf(data, "SSPI: couldn't get auth info\n");
+    return CURLE_AUTH_ERROR;
   }
 
   token_max = SecurityPackage->cbMaxToken;
@@ -220,7 +226,10 @@
     free(output_token);
     free(input_token);
 
-    return CURLE_RECV_ERROR;
+    if(status == SEC_E_INSUFFICIENT_MEMORY)
+      return CURLE_OUT_OF_MEMORY;
+
+    return CURLE_AUTH_ERROR;
   }
 
   /* Base64 encode the response */
@@ -280,13 +289,13 @@
         if(strcasecompare(value, "realm")) {
 
           /* Setup identity's domain and length */
-          domain.tchar_ptr = Curl_convert_UTF8_to_tchar((char *) content);
+          domain.tchar_ptr = curlx_convert_UTF8_to_tchar((char *) content);
           if(!domain.tchar_ptr)
             return CURLE_OUT_OF_MEMORY;
 
           dup_domain.tchar_ptr = _tcsdup(domain.tchar_ptr);
           if(!dup_domain.tchar_ptr) {
-            Curl_unicodefree(domain.tchar_ptr);
+            curlx_unicodefree(domain.tchar_ptr);
             return CURLE_OUT_OF_MEMORY;
           }
 
@@ -295,7 +304,7 @@
           identity->DomainLength = curlx_uztoul(_tcslen(dup_domain.tchar_ptr));
           dup_domain.tchar_ptr = NULL;
 
-          Curl_unicodefree(domain.tchar_ptr);
+          curlx_unicodefree(domain.tchar_ptr);
         }
         else {
           /* Unknown specifier, ignore it! */
@@ -423,8 +432,10 @@
   /* Query the security package for DigestSSP */
   status = s_pSecFn->QuerySecurityPackageInfo((TCHAR *) TEXT(SP_NAME_DIGEST),
                                               &SecurityPackage);
-  if(status != SEC_E_OK)
-    return CURLE_NOT_BUILT_IN;
+  if(status != SEC_E_OK) {
+    failf(data, "SSPI: couldn't get auth info\n");
+    return CURLE_AUTH_ERROR;
+  }
 
   token_max = SecurityPackage->cbMaxToken;
 
@@ -572,7 +583,7 @@
     resp_buf.pvBuffer   = output_token;
     resp_buf.cbBuffer   = curlx_uztoul(token_max);
 
-    spn = Curl_convert_UTF8_to_tchar((char *) uripath);
+    spn = curlx_convert_UTF8_to_tchar((char *) uripath);
     if(!spn) {
       s_pSecFn->FreeCredentialsHandle(&credentials);
 
@@ -594,7 +605,7 @@
                                                  &chlg_desc, 0,
                                                  digest->http_context,
                                                  &resp_desc, &attrs, &expiry);
-    Curl_unicodefree(spn);
+    curlx_unicodefree(spn);
 
     if(status == SEC_I_COMPLETE_NEEDED ||
        status == SEC_I_COMPLETE_AND_CONTINUE)
@@ -607,7 +618,10 @@
 
       Curl_safefree(digest->http_context);
 
-      return CURLE_OUT_OF_MEMORY;
+      if(status == SEC_E_INSUFFICIENT_MEMORY)
+        return CURLE_OUT_OF_MEMORY;
+
+      return CURLE_AUTH_ERROR;
     }
 
     output_token_len = resp_buf.cbBuffer;
diff --git a/Utilities/cmcurl/lib/vauth/krb5_gssapi.c b/Utilities/cmcurl/lib/vauth/krb5_gssapi.c
index ea0a5f1..95bab0e 100644
--- a/Utilities/cmcurl/lib/vauth/krb5_gssapi.c
+++ b/Utilities/cmcurl/lib/vauth/krb5_gssapi.c
@@ -121,7 +121,7 @@
 
       free(spn);
 
-      return CURLE_OUT_OF_MEMORY;
+      return CURLE_AUTH_ERROR;
     }
 
     free(spn);
@@ -168,7 +168,7 @@
     Curl_gss_log_error(data, "gss_init_sec_context() failed: ",
                        major_status, minor_status);
 
-    return CURLE_RECV_ERROR;
+    return CURLE_AUTH_ERROR;
   }
 
   if(output_token.value && output_token.length) {
@@ -252,7 +252,7 @@
 
     free(chlg);
 
-    return CURLE_OUT_OF_MEMORY;
+    return CURLE_AUTH_ERROR;
   }
 
   /* Convert the username from internal format to a displayable token */
@@ -264,7 +264,7 @@
 
     free(chlg);
 
-    return CURLE_OUT_OF_MEMORY;
+    return CURLE_AUTH_ERROR;
   }
 
   /* Setup the challenge "input" security buffer */
@@ -355,7 +355,7 @@
 
     free(message);
 
-    return CURLE_OUT_OF_MEMORY;
+    return CURLE_AUTH_ERROR;
   }
 
   /* Base64 encode the response */
diff --git a/Utilities/cmcurl/lib/vauth/krb5_sspi.c b/Utilities/cmcurl/lib/vauth/krb5_sspi.c
index 1f6e462..1fb6257 100644
--- a/Utilities/cmcurl/lib/vauth/krb5_sspi.c
+++ b/Utilities/cmcurl/lib/vauth/krb5_sspi.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 2014 - 2019, Steve Holme, <steve_holme@hotmail.com>.
+ * Copyright (C) 2014 - 2020, Steve Holme, <steve_holme@hotmail.com>.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -58,6 +58,11 @@
                                               TEXT(SP_NAME_KERBEROS),
                                               &SecurityPackage);
 
+  /* Release the package buffer as it is not required anymore */
+  if(status == SEC_E_OK) {
+    s_pSecFn->FreeContextBuffer(SecurityPackage);
+  }
+
   return (status == SEC_E_OK ? TRUE : FALSE);
 }
 
@@ -120,7 +125,8 @@
                                                 TEXT(SP_NAME_KERBEROS),
                                                 &SecurityPackage);
     if(status != SEC_E_OK) {
-      return CURLE_NOT_BUILT_IN;
+      failf(data, "SSPI: couldn't get auth info\n");
+      return CURLE_AUTH_ERROR;
     }
 
     krb5->token_max = SecurityPackage->cbMaxToken;
@@ -217,8 +223,12 @@
   /* Free the decoded challenge as it is not required anymore */
   free(chlg);
 
+  if(status == SEC_E_INSUFFICIENT_MEMORY) {
+    return CURLE_OUT_OF_MEMORY;
+  }
+
   if(status != SEC_E_OK && status != SEC_I_CONTINUE_NEEDED) {
-    return CURLE_RECV_ERROR;
+    return CURLE_AUTH_ERROR;
   }
 
   if(memcmp(&context, krb5->context, sizeof(context))) {
@@ -309,7 +319,10 @@
   if(status != SEC_E_OK) {
     free(chlg);
 
-    return CURLE_OUT_OF_MEMORY;
+    if(status == SEC_E_INSUFFICIENT_MEMORY)
+      return CURLE_OUT_OF_MEMORY;
+
+    return CURLE_AUTH_ERROR;
   }
 
   /* Get the fully qualified username back from the context */
@@ -319,7 +332,10 @@
   if(status != SEC_E_OK) {
     free(chlg);
 
-    return CURLE_RECV_ERROR;
+    if(status == SEC_E_INSUFFICIENT_MEMORY)
+      return CURLE_OUT_OF_MEMORY;
+
+    return CURLE_AUTH_ERROR;
   }
 
   /* Setup the "input" security buffer */
@@ -380,7 +396,7 @@
     return CURLE_OUT_OF_MEMORY;
 
   /* Convert the user name to UTF8 when operating with Unicode */
-  user_name = Curl_convert_tchar_to_UTF8(names.sUserName);
+  user_name = curlx_convert_tchar_to_UTF8(names.sUserName);
   if(!user_name) {
     free(trailer);
 
@@ -392,7 +408,7 @@
   message = malloc(messagelen);
   if(!message) {
     free(trailer);
-    Curl_unicodefree(user_name);
+    curlx_unicodefree(user_name);
 
     return CURLE_OUT_OF_MEMORY;
   }
@@ -405,7 +421,7 @@
   outdata = htonl(max_size) | sec_layer;
   memcpy(message, &outdata, sizeof(outdata));
   strcpy((char *) message + sizeof(outdata), user_name);
-  Curl_unicodefree(user_name);
+  curlx_unicodefree(user_name);
 
   /* Allocate the padding */
   padding = malloc(sizes.cbBlockSize);
@@ -438,7 +454,10 @@
     free(message);
     free(trailer);
 
-    return CURLE_OUT_OF_MEMORY;
+    if(status == SEC_E_INSUFFICIENT_MEMORY)
+      return CURLE_OUT_OF_MEMORY;
+
+    return CURLE_AUTH_ERROR;
   }
 
   /* Allocate the encryption (wrap) buffer */
diff --git a/Utilities/cmcurl/lib/vauth/ntlm.c b/Utilities/cmcurl/lib/vauth/ntlm.c
index 047c2b5..3b46e1a 100644
--- a/Utilities/cmcurl/lib/vauth/ntlm.c
+++ b/Utilities/cmcurl/lib/vauth/ntlm.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -40,6 +40,7 @@
 #include "curl_ntlm_core.h"
 #include "curl_gethostname.h"
 #include "curl_multibyte.h"
+#include "curl_md5.h"
 #include "warnless.h"
 #include "rand.h"
 #include "vtls/vtls.h"
@@ -599,11 +600,14 @@
 #endif
 
 #if defined(USE_NTRESPONSES) && defined(USE_NTLM2SESSION)
+
+#define CURL_MD5_DIGEST_LENGTH 16 /* fixed size */
+
   /* We don't support NTLM2 if we don't have USE_NTRESPONSES */
   if(ntlm->flags & NTLMFLAG_NEGOTIATE_NTLM_KEY) {
     unsigned char ntbuffer[0x18];
     unsigned char tmp[0x18];
-    unsigned char md5sum[MD5_DIGEST_LENGTH];
+    unsigned char md5sum[CURL_MD5_DIGEST_LENGTH];
     unsigned char entropy[8];
 
     /* Need to create 8 bytes random data */
@@ -621,11 +625,11 @@
     memcpy(tmp, &ntlm->nonce[0], 8);
     memcpy(tmp + 8, entropy, 8);
 
-    result = Curl_ssl_md5sum(tmp, 16, md5sum, MD5_DIGEST_LENGTH);
-    if(!result)
-      /* We shall only use the first 8 bytes of md5sum, but the des code in
-         Curl_ntlm_core_lm_resp only encrypt the first 8 bytes */
-      result = Curl_ntlm_core_mk_nt_hash(data, passwdp, ntbuffer);
+    Curl_md5it(md5sum, tmp, 16);
+
+    /* We shall only use the first 8 bytes of md5sum, but the des code in
+       Curl_ntlm_core_lm_resp only encrypt the first 8 bytes */
+    result = Curl_ntlm_core_mk_nt_hash(data, passwdp, ntbuffer);
     if(result)
       return result;
 
diff --git a/Utilities/cmcurl/lib/vauth/ntlm_sspi.c b/Utilities/cmcurl/lib/vauth/ntlm_sspi.c
index 589cca1..84ea51d 100644
--- a/Utilities/cmcurl/lib/vauth/ntlm_sspi.c
+++ b/Utilities/cmcurl/lib/vauth/ntlm_sspi.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -56,6 +56,11 @@
   status = s_pSecFn->QuerySecurityPackageInfo((TCHAR *) TEXT(SP_NAME_NTLM),
                                               &SecurityPackage);
 
+  /* Release the package buffer as it is not required anymore */
+  if(status == SEC_E_OK) {
+    s_pSecFn->FreeContextBuffer(SecurityPackage);
+  }
+
   return (status == SEC_E_OK ? TRUE : FALSE);
 }
 
@@ -100,8 +105,10 @@
   /* Query the security package for NTLM */
   status = s_pSecFn->QuerySecurityPackageInfo((TCHAR *) TEXT(SP_NAME_NTLM),
                                               &SecurityPackage);
-  if(status != SEC_E_OK)
-    return CURLE_NOT_BUILT_IN;
+  if(status != SEC_E_OK) {
+    failf(data, "SSPI: couldn't get auth info\n");
+    return CURLE_AUTH_ERROR;
+  }
 
   ntlm->token_max = SecurityPackage->cbMaxToken;
 
@@ -169,8 +176,10 @@
   if(status == SEC_I_COMPLETE_NEEDED ||
     status == SEC_I_COMPLETE_AND_CONTINUE)
     s_pSecFn->CompleteAuthToken(ntlm->context, &type_1_desc);
+  else if(status == SEC_E_INSUFFICIENT_MEMORY)
+    return CURLE_OUT_OF_MEMORY;
   else if(status != SEC_E_OK && status != SEC_I_CONTINUE_NEEDED)
-    return CURLE_RECV_ERROR;
+    return CURLE_AUTH_ERROR;
 
   /* Base64 encode the response */
   return Curl_base64_encode(data, (char *) ntlm->output_token,
@@ -316,7 +325,10 @@
     infof(data, "NTLM handshake failure (type-3 message): Status=%x\n",
           status);
 
-    return CURLE_RECV_ERROR;
+    if(status == SEC_E_INSUFFICIENT_MEMORY)
+      return CURLE_OUT_OF_MEMORY;
+
+    return CURLE_AUTH_ERROR;
   }
 
   /* Base64 encode the response */
diff --git a/Utilities/cmcurl/lib/vauth/spnego_gssapi.c b/Utilities/cmcurl/lib/vauth/spnego_gssapi.c
index 5d43e11..ed7ce02 100644
--- a/Utilities/cmcurl/lib/vauth/spnego_gssapi.c
+++ b/Utilities/cmcurl/lib/vauth/spnego_gssapi.c
@@ -121,7 +121,7 @@
 
       free(spn);
 
-      return CURLE_OUT_OF_MEMORY;
+      return CURLE_AUTH_ERROR;
     }
 
     free(spn);
@@ -170,14 +170,14 @@
     Curl_gss_log_error(data, "gss_init_sec_context() failed: ",
                        major_status, minor_status);
 
-    return CURLE_LOGIN_DENIED;
+    return CURLE_AUTH_ERROR;
   }
 
   if(!output_token.value || !output_token.length) {
     if(output_token.value)
       gss_release_buffer(&unused_status, &output_token);
 
-    return CURLE_OUT_OF_MEMORY;
+    return CURLE_AUTH_ERROR;
   }
 
   /* Free previous token */
diff --git a/Utilities/cmcurl/lib/vauth/spnego_sspi.c b/Utilities/cmcurl/lib/vauth/spnego_sspi.c
index 4b21cc7..194f250 100644
--- a/Utilities/cmcurl/lib/vauth/spnego_sspi.c
+++ b/Utilities/cmcurl/lib/vauth/spnego_sspi.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -59,6 +59,12 @@
                                               TEXT(SP_NAME_NEGOTIATE),
                                               &SecurityPackage);
 
+  /* Release the package buffer as it is not required anymore */
+  if(status == SEC_E_OK) {
+    s_pSecFn->FreeContextBuffer(SecurityPackage);
+  }
+
+
   return (status == SEC_E_OK ? TRUE : FALSE);
 }
 
@@ -123,8 +129,10 @@
     nego->status = s_pSecFn->QuerySecurityPackageInfo((TCHAR *)
                                                       TEXT(SP_NAME_NEGOTIATE),
                                                       &SecurityPackage);
-    if(nego->status != SEC_E_OK)
-      return CURLE_NOT_BUILT_IN;
+    if(nego->status != SEC_E_OK) {
+      failf(data, "SSPI: couldn't get auth info\n");
+      return CURLE_AUTH_ERROR;
+    }
 
     nego->token_max = SecurityPackage->cbMaxToken;
 
@@ -165,7 +173,7 @@
                                          nego->p_identity, NULL, NULL,
                                          nego->credentials, &expiry);
     if(nego->status != SEC_E_OK)
-      return CURLE_LOGIN_DENIED;
+      return CURLE_AUTH_ERROR;
 
     /* Allocate our new context handle */
     nego->context = calloc(1, sizeof(CtxtHandle));
@@ -251,14 +259,25 @@
     char buffer[STRERROR_LEN];
     failf(data, "InitializeSecurityContext failed: %s",
           Curl_sspi_strerror(nego->status, buffer, sizeof(buffer)));
-    return CURLE_OUT_OF_MEMORY;
+
+    if(nego->status == (DWORD)SEC_E_INSUFFICIENT_MEMORY)
+      return CURLE_OUT_OF_MEMORY;
+
+    return CURLE_AUTH_ERROR;
   }
 
   if(nego->status == SEC_I_COMPLETE_NEEDED ||
      nego->status == SEC_I_COMPLETE_AND_CONTINUE) {
     nego->status = s_pSecFn->CompleteAuthToken(nego->context, &resp_desc);
     if(GSS_ERROR(nego->status)) {
-      return CURLE_RECV_ERROR;
+      char buffer[STRERROR_LEN];
+      failf(data, "CompleteAuthToken failed: %s",
+            Curl_sspi_strerror(nego->status, buffer, sizeof(buffer)));
+
+      if(nego->status == (DWORD)SEC_E_INSUFFICIENT_MEMORY)
+        return CURLE_OUT_OF_MEMORY;
+
+      return CURLE_AUTH_ERROR;
     }
   }
 
diff --git a/Utilities/cmcurl/lib/vauth/vauth.c b/Utilities/cmcurl/lib/vauth/vauth.c
index a9c5c9c..d98e66c 100644
--- a/Utilities/cmcurl/lib/vauth/vauth.c
+++ b/Utilities/cmcurl/lib/vauth/vauth.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 2014 - 2019, Steve Holme, <steve_holme@hotmail.com>.
+ * Copyright (C) 2014 - 2020, Steve Holme, <steve_holme@hotmail.com>.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -89,7 +89,7 @@
   }
 
   /* Allocate our TCHAR based SPN */
-  tchar_spn = Curl_convert_UTF8_to_tchar(utf8_spn);
+  tchar_spn = curlx_convert_UTF8_to_tchar(utf8_spn);
   if(!tchar_spn) {
     free(utf8_spn);
 
@@ -97,7 +97,7 @@
   }
 
   /* Release the UTF8 variant when operating with Unicode */
-  Curl_unicodefree(utf8_spn);
+  curlx_unicodefree(utf8_spn);
 
   /* Return our newly allocated SPN */
   return tchar_spn;
diff --git a/Utilities/cmcurl/lib/vauth/vauth.h b/Utilities/cmcurl/lib/vauth/vauth.h
index 73bd25e..a1a557d 100644
--- a/Utilities/cmcurl/lib/vauth/vauth.h
+++ b/Utilities/cmcurl/lib/vauth/vauth.h
@@ -43,7 +43,7 @@
 #endif
 
 #if defined(USE_WINDOWS_SSPI)
-#define GSS_ERROR(status) (status & 0x80000000)
+#define GSS_ERROR(status) ((status) & 0x80000000)
 #endif
 
 /* This is used to build a SPN string */
diff --git a/Utilities/cmcurl/lib/version.c b/Utilities/cmcurl/lib/version.c
index 14b0531..14e5096 100644
--- a/Utilities/cmcurl/lib/version.c
+++ b/Utilities/cmcurl/lib/version.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -26,7 +26,8 @@
 #include "urldata.h"
 #include "vtls/vtls.h"
 #include "http2.h"
-#include "ssh.h"
+#include "vssh/ssh.h"
+#include "quic.h"
 #include "curl_printf.h"
 
 #ifdef USE_ARES
@@ -53,18 +54,6 @@
 #include <librtmp/rtmp.h>
 #endif
 
-#ifdef USE_LIBSSH2
-#include <libssh2.h>
-#endif
-
-#ifdef HAVE_LIBSSH2_VERSION
-/* get it run-time if possible */
-#define CURL_LIBSSH2_VERSION libssh2_version(0)
-#else
-/* use build-time if run-time not possible */
-#define CURL_LIBSSH2_VERSION LIBSSH2_VERSION
-#endif
-
 #ifdef HAVE_ZLIB_H
 #include <zlib.h>
 #ifdef __SYMBIAN32__
@@ -77,16 +66,6 @@
 #include <brotli/decode.h>
 #endif
 
-void Curl_version_init(void);
-
-/* For thread safety purposes this function is called by global_init so that
-   the static data in both version functions is initialized. */
-void Curl_version_init(void)
-{
-  curl_version();
-  curl_version_info(CURLVERSION_NOW);
-}
-
 #ifdef HAVE_BROTLI
 static size_t brotli_version(char *buf, size_t bufsz)
 {
@@ -99,93 +78,118 @@
 }
 #endif
 
+/*
+ * curl_version() returns a pointer to a static buffer.
+ *
+ * It is implemented to work multi-threaded by making sure repeated invokes
+ * generate the exact same string and never write any temporary data like
+ * zeros in the data.
+ */
+
+#define VERSION_PARTS 14 /* number of substrings we can concatenate */
+
 char *curl_version(void)
 {
-  static bool initialized;
-  static char version[200];
-  char *ptr = version;
-  size_t len;
-  size_t left = sizeof(version);
-
-  if(initialized)
-    return version;
-
-  strcpy(ptr, LIBCURL_NAME "/" LIBCURL_VERSION);
-  len = strlen(ptr);
-  left -= len;
-  ptr += len;
-
-  if(left > 1) {
-    len = Curl_ssl_version(ptr + 1, left - 1);
-
-    if(len > 0) {
-      *ptr = ' ';
-      left -= ++len;
-      ptr += len;
-    }
-  }
-
+  static char out[300];
+  char *outp;
+  size_t outlen;
+  const char *src[VERSION_PARTS];
+#ifdef USE_SSL
+  char ssl_version[200];
+#endif
 #ifdef HAVE_LIBZ
-  len = msnprintf(ptr, left, " zlib/%s", zlibVersion());
-  left -= len;
-  ptr += len;
+  char z_version[40];
 #endif
 #ifdef HAVE_BROTLI
-  len = msnprintf(ptr, left, "%s", " brotli/");
-  left -= len;
-  ptr += len;
-  len = brotli_version(ptr, left);
-  left -= len;
-  ptr += len;
+  char br_version[40] = "brotli/";
 #endif
 #ifdef USE_ARES
-  /* this function is only present in c-ares, not in the original ares */
-  len = msnprintf(ptr, left, " c-ares/%s", ares_version(NULL));
-  left -= len;
-  ptr += len;
+  char cares_version[40];
 #endif
-#ifdef USE_LIBIDN2
-  if(idn2_check_version(IDN2_VERSION)) {
-    len = msnprintf(ptr, left, " libidn2/%s", idn2_check_version(NULL));
-    left -= len;
-    ptr += len;
-  }
+#if defined(USE_LIBIDN2)
+  char idn_version[40];
 #endif
 #ifdef USE_LIBPSL
-  len = msnprintf(ptr, left, " libpsl/%s", psl_get_version());
-  left -= len;
-  ptr += len;
+  char psl_version[40];
 #endif
-#ifdef USE_WIN32_IDN
-  len = msnprintf(ptr, left, " WinIDN");
-  left -= len;
-  ptr += len;
+#if defined(HAVE_ICONV) && defined(CURL_DOES_CONVERSIONS)
+  char iconv_version[40]="iconv";
+#endif
+#ifdef USE_SSH
+  char ssh_version[40];
+#endif
+#ifdef USE_NGHTTP2
+  char h2_version[40];
+#endif
+#ifdef ENABLE_QUIC
+  char h3_version[40];
+#endif
+#ifdef USE_LIBRTMP
+  char rtmp_version[40];
+#endif
+  int i = 0;
+  int j;
+
+#ifdef DEBUGBUILD
+  /* Override version string when environment variable CURL_VERSION is set */
+  const char *debugversion = getenv("CURL_VERSION");
+  if(debugversion) {
+    strncpy(out, debugversion, sizeof(out)-1);
+    out[sizeof(out)-1] = '\0';
+    return out;
+  }
+#endif
+
+  src[i++] = LIBCURL_NAME "/" LIBCURL_VERSION;
+#ifdef USE_SSL
+  Curl_ssl_version(ssl_version, sizeof(ssl_version));
+  src[i++] = ssl_version;
+#endif
+#ifdef HAVE_LIBZ
+  msnprintf(z_version, sizeof(z_version), "zlib/%s", zlibVersion());
+  src[i++] = z_version;
+#endif
+#ifdef HAVE_BROTLI
+  brotli_version(&br_version[7], sizeof(br_version) - 7);
+  src[i++] = br_version;
+#endif
+#ifdef USE_ARES
+  msnprintf(cares_version, sizeof(cares_version),
+            "c-ares/%s", ares_version(NULL));
+  src[i++] = cares_version;
+#endif
+#ifdef USE_LIBIDN2
+  msnprintf(idn_version, sizeof(idn_version),
+            "libidn2/%s", idn2_check_version(NULL));
+  src[i++] = idn_version;
+#elif defined(USE_WIN32_IDN)
+  src[i++] = (char *)"WinIDN";
+#endif
+
+#ifdef USE_LIBPSL
+  msnprintf(psl_version, sizeof(psl_version), "libpsl/%s", psl_get_version());
+  src[i++] = psl_version;
 #endif
 #if defined(HAVE_ICONV) && defined(CURL_DOES_CONVERSIONS)
 #ifdef _LIBICONV_VERSION
-  len = msnprintf(ptr, left, " iconv/%d.%d",
-                  _LIBICONV_VERSION >> 8, _LIBICONV_VERSION & 255);
+  msnprintf(iconv_version, sizeof(iconv_version), "iconv/%d.%d",
+            _LIBICONV_VERSION >> 8, _LIBICONV_VERSION & 255);
 #else
-  /* version unknown */
-  len = msnprintf(ptr, left, " iconv");
+  /* version unknown, let the default stand */
 #endif /* _LIBICONV_VERSION */
-  left -= len;
-  ptr += len;
+  src[i++] = iconv_version;
 #endif
-#ifdef USE_LIBSSH2
-  len = msnprintf(ptr, left, " libssh2/%s", CURL_LIBSSH2_VERSION);
-  left -= len;
-  ptr += len;
-#endif
-#ifdef USE_LIBSSH
-  len = msnprintf(ptr, left, " libssh/%s", CURL_LIBSSH_VERSION);
-  left -= len;
-  ptr += len;
+#ifdef USE_SSH
+  Curl_ssh_version(ssh_version, sizeof(ssh_version));
+  src[i++] = ssh_version;
 #endif
 #ifdef USE_NGHTTP2
-  len = Curl_http2_ver(ptr, left);
-  left -= len;
-  ptr += len;
+  Curl_http2_ver(h2_version, sizeof(h2_version));
+  src[i++] = h2_version;
+#endif
+#ifdef ENABLE_QUIC
+  Curl_quic_ver(h3_version, sizeof(h3_version));
+  src[i++] = h3_version;
 #endif
 #ifdef USE_LIBRTMP
   {
@@ -197,27 +201,34 @@
     else
       suff[0] = '\0';
 
-    msnprintf(ptr, left, " librtmp/%d.%d%s",
+    msnprintf(rtmp_version, sizeof(rtmp_version), "librtmp/%d.%d%s",
               RTMP_LIB_VERSION >> 16, (RTMP_LIB_VERSION >> 8) & 0xff,
               suff);
-/*
-  If another lib version is added below this one, this code would
-  also have to do:
-
-    len = what msnprintf() returned
-
-    left -= len;
-    ptr += len;
-*/
+    src[i++] = rtmp_version;
   }
 #endif
 
-  /* Silent scan-build even if librtmp is not enabled. */
-  (void) left;
-  (void) ptr;
+  DEBUGASSERT(i <= VERSION_PARTS);
 
-  initialized = true;
-  return version;
+  outp = &out[0];
+  outlen = sizeof(out);
+  for(j = 0; j < i; j++) {
+    size_t n = strlen(src[j]);
+    /* we need room for a space, the string and the final zero */
+    if(outlen <= (n + 2))
+      break;
+    if(j) {
+      /* prepend a space if not the first */
+      *outp++ = ' ';
+      outlen--;
+    }
+    memcpy(outp, src[j], n);
+    outp += n;
+    outlen -= n;
+  }
+  *outp = 0;
+
+  return out;
 }
 
 /* data for curl_version_info
@@ -262,6 +273,9 @@
   "ldaps",
 #endif
 #endif
+#ifdef CURL_ENABLE_MQTT
+  "mqtt",
+#endif
 #ifndef CURL_DISABLE_POP3
   "pop3",
 #endif
@@ -274,8 +288,10 @@
 #ifndef CURL_DISABLE_RTSP
   "rtsp",
 #endif
-#if defined(USE_SSH)
+#if defined(USE_SSH) && !defined(USE_WOLFSSH)
   "scp",
+#endif
+#ifdef USE_SSH
   "sftp",
 #endif
 #if !defined(CURL_DISABLE_SMB) && defined(USE_NTLM) && \
@@ -358,6 +374,9 @@
 #if defined(USE_NGHTTP2)
   | CURL_VERSION_HTTP2
 #endif
+#if defined(ENABLE_QUIC)
+  | CURL_VERSION_HTTP3
+#endif
 #if defined(USE_UNIX_SOCKETS)
   | CURL_VERSION_UNIX_SOCKETS
 #endif
@@ -385,11 +404,23 @@
   NULL, /* ssh lib version */
   0,    /* brotli_ver_num */
   NULL, /* brotli version */
+  0,    /* nghttp2 version number */
+  NULL, /* nghttp2 version string */
+  NULL, /* quic library string */
+#ifdef CURL_CA_BUNDLE
+  CURL_CA_BUNDLE, /* cainfo */
+#else
+  NULL,
+#endif
+#ifdef CURL_CA_PATH
+  CURL_CA_PATH  /* capath */
+#else
+  NULL
+#endif
 };
 
 curl_version_info_data *curl_version_info(CURLversion stamp)
 {
-  static bool initialized;
 #if defined(USE_SSH)
   static char ssh_buffer[80];
 #endif
@@ -404,9 +435,6 @@
   static char brotli_buffer[80];
 #endif
 
-  if(initialized)
-    return &version_info;
-
 #ifdef USE_SSL
   Curl_ssl_version(ssl_buffer, sizeof(ssl_buffer));
   version_info.ssl_version = ssl_buffer;
@@ -446,11 +474,8 @@
 #endif /* _LIBICONV_VERSION */
 #endif
 
-#if defined(USE_LIBSSH2)
-  msnprintf(ssh_buffer, sizeof(ssh_buffer), "libssh2/%s", LIBSSH2_VERSION);
-  version_info.libssh_version = ssh_buffer;
-#elif defined(USE_LIBSSH)
-  msnprintf(ssh_buffer, sizeof(ssh_buffer), "libssh/%s", CURL_LIBSSH_VERSION);
+#if defined(USE_SSH)
+  Curl_ssh_version(ssh_buffer, sizeof(ssh_buffer));
   version_info.libssh_version = ssh_buffer;
 #endif
 
@@ -460,8 +485,22 @@
   version_info.brotli_version = brotli_buffer;
 #endif
 
-  (void)stamp; /* avoid compiler warnings, we don't use this */
+#ifdef USE_NGHTTP2
+  {
+    nghttp2_info *h2 = nghttp2_version(0);
+    version_info.nghttp2_ver_num = h2->version_num;
+    version_info.nghttp2_version = h2->version_str;
+  }
+#endif
 
-  initialized = true;
+#ifdef ENABLE_QUIC
+  {
+    static char quicbuffer[80];
+    Curl_quic_ver(quicbuffer, sizeof(quicbuffer));
+    version_info.quic_version = quicbuffer;
+  }
+#endif
+
+  (void)stamp; /* avoid compiler warnings, we don't use this */
   return &version_info;
 }
diff --git a/Utilities/cmcurl/lib/vquic/ngtcp2.c b/Utilities/cmcurl/lib/vquic/ngtcp2.c
new file mode 100644
index 0000000..d29cb37
--- /dev/null
+++ b/Utilities/cmcurl/lib/vquic/ngtcp2.c
@@ -0,0 +1,1947 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#ifdef USE_NGTCP2
+#include <ngtcp2/ngtcp2.h>
+#include <ngtcp2/ngtcp2_crypto.h>
+#include <nghttp3/nghttp3.h>
+#ifdef USE_OPENSSL
+#include <openssl/err.h>
+#endif
+#include "urldata.h"
+#include "sendf.h"
+#include "strdup.h"
+#include "rand.h"
+#include "ngtcp2.h"
+#include "multiif.h"
+#include "strcase.h"
+#include "connect.h"
+#include "strerror.h"
+#include "dynbuf.h"
+#include "vquic.h"
+#include "vtls/keylog.h"
+
+/* The last 3 #include files should be in this order */
+#include "curl_printf.h"
+#include "curl_memory.h"
+#include "memdebug.h"
+
+/* #define DEBUG_NGTCP2 */
+#ifdef CURLDEBUG
+#define DEBUG_HTTP3
+#endif
+#ifdef DEBUG_HTTP3
+#define H3BUGF(x) x
+#else
+#define H3BUGF(x) do { } while(0)
+#endif
+
+/*
+ * This holds outgoing HTTP/3 stream data that is used by nghttp3 until acked.
+ * It is used as a circular buffer. Add new bytes at the end until it reaches
+ * the far end, then start over at index 0 again.
+ */
+
+#define H3_SEND_SIZE (20*1024)
+struct h3out {
+  uint8_t buf[H3_SEND_SIZE];
+  size_t used;   /* number of bytes used in the buffer */
+  size_t windex; /* index in the buffer where to start writing the next
+                    data block */
+};
+
+#define QUIC_MAX_STREAMS (256*1024)
+#define QUIC_MAX_DATA (1*1024*1024)
+#define QUIC_IDLE_TIMEOUT 60000 /* milliseconds */
+
+#ifdef USE_OPENSSL
+#define QUIC_CIPHERS                                                          \
+  "TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_"               \
+  "POLY1305_SHA256:TLS_AES_128_CCM_SHA256"
+#define QUIC_GROUPS "P-256:X25519:P-384:P-521"
+#elif defined(USE_GNUTLS)
+#define QUIC_PRIORITY \
+  "NORMAL:-VERS-ALL:+VERS-TLS1.3:-CIPHER-ALL:+AES-128-GCM:+AES-256-GCM:" \
+  "+CHACHA20-POLY1305:+AES-128-CCM:-GROUP-ALL:+GROUP-SECP256R1:" \
+  "+GROUP-X25519:+GROUP-SECP384R1:+GROUP-SECP521R1"
+#endif
+
+static CURLcode ng_process_ingress(struct connectdata *conn,
+                                   curl_socket_t sockfd,
+                                   struct quicsocket *qs);
+static CURLcode ng_flush_egress(struct connectdata *conn, int sockfd,
+                                struct quicsocket *qs);
+static int cb_h3_acked_stream_data(nghttp3_conn *conn, int64_t stream_id,
+                                   size_t datalen, void *user_data,
+                                   void *stream_user_data);
+
+static ngtcp2_tstamp timestamp(void)
+{
+  struct curltime ct = Curl_now();
+  return ct.tv_sec * NGTCP2_SECONDS + ct.tv_usec * NGTCP2_MICROSECONDS;
+}
+
+#ifdef DEBUG_NGTCP2
+static void quic_printf(void *user_data, const char *fmt, ...)
+{
+  va_list ap;
+  (void)user_data; /* TODO, use this to do infof() instead long-term */
+  va_start(ap, fmt);
+  vfprintf(stderr, fmt, ap);
+  va_end(ap);
+  fprintf(stderr, "\n");
+}
+#endif
+
+#ifdef USE_OPENSSL
+static ngtcp2_crypto_level
+quic_from_ossl_level(OSSL_ENCRYPTION_LEVEL ossl_level)
+{
+  switch(ossl_level) {
+  case ssl_encryption_initial:
+    return NGTCP2_CRYPTO_LEVEL_INITIAL;
+  case ssl_encryption_early_data:
+    return NGTCP2_CRYPTO_LEVEL_EARLY;
+  case ssl_encryption_handshake:
+    return NGTCP2_CRYPTO_LEVEL_HANDSHAKE;
+  case ssl_encryption_application:
+    return NGTCP2_CRYPTO_LEVEL_APP;
+  default:
+    assert(0);
+  }
+}
+#elif defined(USE_GNUTLS)
+static ngtcp2_crypto_level
+quic_from_gtls_level(gnutls_record_encryption_level_t gtls_level)
+{
+  switch(gtls_level) {
+  case GNUTLS_ENCRYPTION_LEVEL_INITIAL:
+    return NGTCP2_CRYPTO_LEVEL_INITIAL;
+  case GNUTLS_ENCRYPTION_LEVEL_EARLY:
+    return NGTCP2_CRYPTO_LEVEL_EARLY;
+  case GNUTLS_ENCRYPTION_LEVEL_HANDSHAKE:
+    return NGTCP2_CRYPTO_LEVEL_HANDSHAKE;
+  case GNUTLS_ENCRYPTION_LEVEL_APPLICATION:
+    return NGTCP2_CRYPTO_LEVEL_APP;
+  default:
+    assert(0);
+  }
+}
+#endif
+
+static void qlog_callback(void *user_data, const void *data, size_t datalen)
+{
+  struct quicsocket *qs = (struct quicsocket *)user_data;
+  if(qs->qlogfd != -1) {
+    ssize_t rc = write(qs->qlogfd, data, datalen);
+    if(rc == -1) {
+      /* on write error, stop further write attempts */
+      close(qs->qlogfd);
+      qs->qlogfd = -1;
+    }
+  }
+
+}
+
+static void quic_settings(struct quicsocket *qs,
+                          uint64_t stream_buffer_size)
+{
+  ngtcp2_settings *s = &qs->settings;
+  ngtcp2_settings_default(s);
+#ifdef DEBUG_NGTCP2
+  s->log_printf = quic_printf;
+#else
+  s->log_printf = NULL;
+#endif
+  s->initial_ts = timestamp();
+  s->transport_params.initial_max_stream_data_bidi_local = stream_buffer_size;
+  s->transport_params.initial_max_stream_data_bidi_remote = QUIC_MAX_STREAMS;
+  s->transport_params.initial_max_stream_data_uni = QUIC_MAX_STREAMS;
+  s->transport_params.initial_max_data = QUIC_MAX_DATA;
+  s->transport_params.initial_max_streams_bidi = 1;
+  s->transport_params.initial_max_streams_uni = 3;
+  s->transport_params.max_idle_timeout = QUIC_IDLE_TIMEOUT;
+  if(qs->qlogfd != -1) {
+    s->qlog.write = qlog_callback;
+  }
+}
+
+#ifdef USE_OPENSSL
+static void keylog_callback(const SSL *ssl, const char *line)
+{
+  (void)ssl;
+  Curl_tls_keylog_write_line(line);
+}
+#elif defined(USE_GNUTLS)
+static int keylog_callback(gnutls_session_t session, const char *label,
+                    const gnutls_datum_t *secret)
+{
+  gnutls_datum_t crandom;
+  gnutls_datum_t srandom;
+
+  gnutls_session_get_random(session, &crandom, &srandom);
+  if(crandom.size != 32) {
+    return -1;
+  }
+
+  Curl_tls_keylog_write(label, crandom.data, secret->data, secret->size);
+  return 0;
+}
+#endif
+
+static int init_ngh3_conn(struct quicsocket *qs);
+
+static int write_client_handshake(struct quicsocket *qs,
+                                  ngtcp2_crypto_level level,
+                                  const uint8_t *data, size_t len)
+{
+  struct quic_handshake *crypto_data;
+  int rv;
+
+  crypto_data = &qs->crypto_data[level];
+  if(crypto_data->buf == NULL) {
+    crypto_data->buf = malloc(4096);
+    if(!crypto_data->buf)
+      return 0;
+    crypto_data->alloclen = 4096;
+  }
+
+  /* TODO Just pretend that handshake does not grow more than 4KiB for
+     now */
+  assert(crypto_data->len + len <= crypto_data->alloclen);
+
+  memcpy(&crypto_data->buf[crypto_data->len], data, len);
+  crypto_data->len += len;
+
+  rv = ngtcp2_conn_submit_crypto_data(
+    qs->qconn, level, (uint8_t *)(&crypto_data->buf[crypto_data->len] - len),
+    len);
+  if(rv) {
+    H3BUGF(fprintf(stderr, "write_client_handshake failed\n"));
+  }
+  assert(0 == rv);
+
+  return 1;
+}
+
+#ifdef USE_OPENSSL
+static int quic_set_encryption_secrets(SSL *ssl,
+                                       OSSL_ENCRYPTION_LEVEL ossl_level,
+                                       const uint8_t *rx_secret,
+                                       const uint8_t *tx_secret,
+                                       size_t secretlen)
+{
+  struct quicsocket *qs = (struct quicsocket *)SSL_get_app_data(ssl);
+  int level = quic_from_ossl_level(ossl_level);
+
+  if(ngtcp2_crypto_derive_and_install_rx_key(
+       qs->qconn, NULL, NULL, NULL, level, rx_secret, secretlen) != 0)
+    return 0;
+
+  if(ngtcp2_crypto_derive_and_install_tx_key(
+       qs->qconn, NULL, NULL, NULL, level, tx_secret, secretlen) != 0)
+    return 0;
+
+  if(level == NGTCP2_CRYPTO_LEVEL_APP) {
+    if(init_ngh3_conn(qs) != CURLE_OK)
+      return 0;
+  }
+
+  return 1;
+}
+
+static int quic_add_handshake_data(SSL *ssl, OSSL_ENCRYPTION_LEVEL ossl_level,
+                                   const uint8_t *data, size_t len)
+{
+  struct quicsocket *qs = (struct quicsocket *)SSL_get_app_data(ssl);
+  ngtcp2_crypto_level level = quic_from_ossl_level(ossl_level);
+
+  return write_client_handshake(qs, level, data, len);
+}
+
+static int quic_flush_flight(SSL *ssl)
+{
+  (void)ssl;
+  return 1;
+}
+
+static int quic_send_alert(SSL *ssl, enum ssl_encryption_level_t level,
+                           uint8_t alert)
+{
+  struct quicsocket *qs = (struct quicsocket *)SSL_get_app_data(ssl);
+  (void)level;
+
+  qs->tls_alert = alert;
+  return 1;
+}
+
+static SSL_QUIC_METHOD quic_method = {quic_set_encryption_secrets,
+                                      quic_add_handshake_data,
+                                      quic_flush_flight, quic_send_alert};
+
+static SSL_CTX *quic_ssl_ctx(struct Curl_easy *data)
+{
+  SSL_CTX *ssl_ctx = SSL_CTX_new(TLS_method());
+
+  SSL_CTX_set_min_proto_version(ssl_ctx, TLS1_3_VERSION);
+  SSL_CTX_set_max_proto_version(ssl_ctx, TLS1_3_VERSION);
+
+  SSL_CTX_set_default_verify_paths(ssl_ctx);
+
+  if(SSL_CTX_set_ciphersuites(ssl_ctx, QUIC_CIPHERS) != 1) {
+    char error_buffer[256];
+    ERR_error_string_n(ERR_get_error(), error_buffer, sizeof(error_buffer));
+    failf(data, "SSL_CTX_set_ciphersuites: %s", error_buffer);
+    return NULL;
+  }
+
+  if(SSL_CTX_set1_groups_list(ssl_ctx, QUIC_GROUPS) != 1) {
+    failf(data, "SSL_CTX_set1_groups_list failed");
+    return NULL;
+  }
+
+  SSL_CTX_set_quic_method(ssl_ctx, &quic_method);
+
+  /* Open the file if a TLS or QUIC backend has not done this before. */
+  Curl_tls_keylog_open();
+  if(Curl_tls_keylog_enabled()) {
+    SSL_CTX_set_keylog_callback(ssl_ctx, keylog_callback);
+  }
+
+  return ssl_ctx;
+}
+
+/** SSL callbacks ***/
+
+static int quic_init_ssl(struct quicsocket *qs)
+{
+  const uint8_t *alpn = NULL;
+  size_t alpnlen = 0;
+  /* this will need some attention when HTTPS proxy over QUIC get fixed */
+  const char * const hostname = qs->conn->host.name;
+
+  DEBUGASSERT(!qs->ssl);
+  qs->ssl = SSL_new(qs->sslctx);
+
+  SSL_set_app_data(qs->ssl, qs);
+  SSL_set_connect_state(qs->ssl);
+
+  switch(qs->version) {
+#ifdef NGTCP2_PROTO_VER
+  case NGTCP2_PROTO_VER:
+    alpn = (const uint8_t *)NGHTTP3_ALPN_H3;
+    alpnlen = sizeof(NGHTTP3_ALPN_H3) - 1;
+    break;
+#endif
+  }
+  if(alpn)
+    SSL_set_alpn_protos(qs->ssl, alpn, (int)alpnlen);
+
+  /* set SNI */
+  SSL_set_tlsext_host_name(qs->ssl, hostname);
+  return 0;
+}
+#elif defined(USE_GNUTLS)
+static int secret_func(gnutls_session_t ssl,
+                       gnutls_record_encryption_level_t gtls_level,
+                       const void *rx_secret,
+                       const void *tx_secret, size_t secretlen)
+{
+  struct quicsocket *qs = gnutls_session_get_ptr(ssl);
+  int level = quic_from_gtls_level(gtls_level);
+
+  if(level != NGTCP2_CRYPTO_LEVEL_EARLY &&
+     ngtcp2_crypto_derive_and_install_rx_key(
+       qs->qconn, NULL, NULL, NULL, level, rx_secret, secretlen) != 0)
+    return 0;
+
+  if(ngtcp2_crypto_derive_and_install_tx_key(
+       qs->qconn, NULL, NULL, NULL, level, tx_secret, secretlen) != 0)
+    return 0;
+
+  if(level == NGTCP2_CRYPTO_LEVEL_APP) {
+    if(init_ngh3_conn(qs) != CURLE_OK)
+      return -1;
+  }
+
+  return 0;
+}
+
+static int read_func(gnutls_session_t ssl,
+                     gnutls_record_encryption_level_t gtls_level,
+                     gnutls_handshake_description_t htype, const void *data,
+                     size_t len)
+{
+  struct quicsocket *qs = gnutls_session_get_ptr(ssl);
+  ngtcp2_crypto_level level = quic_from_gtls_level(gtls_level);
+  int rv;
+
+  if(htype == GNUTLS_HANDSHAKE_CHANGE_CIPHER_SPEC)
+    return 0;
+
+  rv = write_client_handshake(qs, level, data, len);
+  if(rv == 0)
+    return -1;
+
+  return 0;
+}
+
+static int alert_read_func(gnutls_session_t ssl,
+                           gnutls_record_encryption_level_t gtls_level,
+                           gnutls_alert_level_t alert_level,
+                           gnutls_alert_description_t alert_desc)
+{
+  struct quicsocket *qs = gnutls_session_get_ptr(ssl);
+  (void)gtls_level;
+  (void)alert_level;
+
+  qs->tls_alert = alert_desc;
+  return 1;
+}
+
+static int tp_recv_func(gnutls_session_t ssl, const uint8_t *data,
+                        size_t data_size)
+{
+  struct quicsocket *qs = gnutls_session_get_ptr(ssl);
+  ngtcp2_transport_params params;
+
+  if(ngtcp2_decode_transport_params(
+       &params, NGTCP2_TRANSPORT_PARAMS_TYPE_ENCRYPTED_EXTENSIONS,
+       data, data_size) != 0)
+    return -1;
+
+  if(ngtcp2_conn_set_remote_transport_params(qs->qconn, &params) != 0)
+    return -1;
+
+  return 0;
+}
+
+static int tp_send_func(gnutls_session_t ssl, gnutls_buffer_t extdata)
+{
+  struct quicsocket *qs = gnutls_session_get_ptr(ssl);
+  uint8_t paramsbuf[64];
+  ngtcp2_transport_params params;
+  ssize_t nwrite;
+  int rc;
+
+  ngtcp2_conn_get_local_transport_params(qs->qconn, &params);
+  nwrite = ngtcp2_encode_transport_params(
+    paramsbuf, sizeof(paramsbuf), NGTCP2_TRANSPORT_PARAMS_TYPE_CLIENT_HELLO,
+    &params);
+  if(nwrite < 0) {
+    H3BUGF(fprintf(stderr, "ngtcp2_encode_transport_params: %s\n",
+                   ngtcp2_strerror((int)nwrite)));
+    return -1;
+  }
+
+  rc = gnutls_buffer_append_data(extdata, paramsbuf, nwrite);
+  if(rc < 0)
+    return rc;
+
+  return (int)nwrite;
+}
+
+static int quic_init_ssl(struct quicsocket *qs)
+{
+  gnutls_datum_t alpn = {NULL, 0};
+  /* this will need some attention when HTTPS proxy over QUIC get fixed */
+  const char * const hostname = qs->conn->host.name;
+  int rc;
+
+  DEBUGASSERT(!qs->ssl);
+
+  gnutls_init(&qs->ssl, GNUTLS_CLIENT);
+  gnutls_session_set_ptr(qs->ssl, qs);
+
+  rc = gnutls_priority_set_direct(qs->ssl, QUIC_PRIORITY, NULL);
+  if(rc < 0) {
+    H3BUGF(fprintf(stderr, "gnutls_priority_set_direct failed: %s\n",
+                   gnutls_strerror(rc)));
+    return 1;
+  }
+
+  gnutls_handshake_set_secret_function(qs->ssl, secret_func);
+  gnutls_handshake_set_read_function(qs->ssl, read_func);
+  gnutls_alert_set_read_function(qs->ssl, alert_read_func);
+
+  rc = gnutls_session_ext_register(qs->ssl, "QUIC Transport Parameters",
+                                   0xffa5, GNUTLS_EXT_TLS,
+                                   tp_recv_func, tp_send_func,
+                                   NULL, NULL, NULL,
+                                   GNUTLS_EXT_FLAG_TLS |
+                                   GNUTLS_EXT_FLAG_CLIENT_HELLO |
+                                   GNUTLS_EXT_FLAG_EE);
+  if(rc < 0) {
+    H3BUGF(fprintf(stderr, "gnutls_session_ext_register failed: %s\n",
+                   gnutls_strerror(rc)));
+    return 1;
+  }
+
+  /* Open the file if a TLS or QUIC backend has not done this before. */
+  Curl_tls_keylog_open();
+  if(Curl_tls_keylog_enabled()) {
+    gnutls_session_set_keylog_function(qs->ssl, keylog_callback);
+  }
+
+  if(qs->cred)
+    gnutls_certificate_free_credentials(qs->cred);
+
+  rc = gnutls_certificate_allocate_credentials(&qs->cred);
+  if(rc < 0) {
+    H3BUGF(fprintf(stderr,
+                   "gnutls_certificate_allocate_credentials failed: %s\n",
+                   gnutls_strerror(rc)));
+    return 1;
+  }
+
+  rc = gnutls_certificate_set_x509_system_trust(qs->cred);
+  if(rc < 0) {
+    H3BUGF(fprintf(stderr,
+                   "gnutls_certificate_set_x509_system_trust failed: %s\n",
+                   gnutls_strerror(rc)));
+    return 1;
+  }
+
+  rc = gnutls_credentials_set(qs->ssl, GNUTLS_CRD_CERTIFICATE, qs->cred);
+  if(rc < 0) {
+    H3BUGF(fprintf(stderr, "gnutls_credentials_set failed: %s\n",
+                   gnutls_strerror(rc)));
+    return 1;
+  }
+
+  switch(qs->version) {
+#ifdef NGTCP2_PROTO_VER
+  case NGTCP2_PROTO_VER:
+    /* strip the first byte (the length) from NGHTTP3_ALPN_H3 */
+    alpn.data = (unsigned char *)NGHTTP3_ALPN_H3 + 1;
+    alpn.size = sizeof(NGHTTP3_ALPN_H3) - 2;
+    break;
+#endif
+  }
+  if(alpn.data)
+    gnutls_alpn_set_protocols(qs->ssl, &alpn, 1, 0);
+
+  /* set SNI */
+  gnutls_server_name_set(qs->ssl, GNUTLS_NAME_DNS, hostname, strlen(hostname));
+  return 0;
+}
+#endif
+
+static int
+cb_recv_crypto_data(ngtcp2_conn *tconn, ngtcp2_crypto_level crypto_level,
+                    uint64_t offset,
+                    const uint8_t *data, size_t datalen,
+                    void *user_data)
+{
+  (void)offset;
+  (void)user_data;
+
+  if(ngtcp2_crypto_read_write_crypto_data(tconn, crypto_level, data,
+                                          datalen) != 0)
+    return NGTCP2_ERR_CRYPTO;
+
+  return 0;
+}
+
+static int cb_handshake_completed(ngtcp2_conn *tconn, void *user_data)
+{
+  struct quicsocket *qs = (struct quicsocket *)user_data;
+  (void)tconn;
+  infof(qs->conn->data, "QUIC handshake is completed\n");
+
+  return 0;
+}
+
+static void extend_stream_window(ngtcp2_conn *tconn,
+                                 struct HTTP *stream)
+{
+  size_t thismuch = stream->unacked_window;
+  ngtcp2_conn_extend_max_stream_offset(tconn, stream->stream3_id, thismuch);
+  ngtcp2_conn_extend_max_offset(tconn, thismuch);
+  stream->unacked_window = 0;
+}
+
+
+static int cb_recv_stream_data(ngtcp2_conn *tconn, uint32_t flags,
+                               int64_t stream_id, uint64_t offset,
+                               const uint8_t *buf, size_t buflen,
+                               void *user_data, void *stream_user_data)
+{
+  struct quicsocket *qs = (struct quicsocket *)user_data;
+  ssize_t nconsumed;
+  int fin = flags & NGTCP2_STREAM_DATA_FLAG_FIN ? 1 : 0;
+  (void)offset;
+  (void)stream_user_data;
+
+  nconsumed =
+    nghttp3_conn_read_stream(qs->h3conn, stream_id, buf, buflen, fin);
+  if(nconsumed < 0) {
+    failf(qs->conn->data, "nghttp3_conn_read_stream returned error: %s\n",
+          nghttp3_strerror((int)nconsumed));
+    return NGTCP2_ERR_CALLBACK_FAILURE;
+  }
+
+  /* number of bytes inside buflen which consists of framing overhead
+   * including QPACK HEADERS. In other words, it does not consume payload of
+   * DATA frame. */
+  ngtcp2_conn_extend_max_stream_offset(tconn, stream_id, nconsumed);
+  ngtcp2_conn_extend_max_offset(tconn, nconsumed);
+
+  return 0;
+}
+
+static int
+cb_acked_stream_data_offset(ngtcp2_conn *tconn, int64_t stream_id,
+                            uint64_t offset, size_t datalen, void *user_data,
+                            void *stream_user_data)
+{
+  struct quicsocket *qs = (struct quicsocket *)user_data;
+  int rv;
+  (void)stream_id;
+  (void)tconn;
+  (void)offset;
+  (void)datalen;
+  (void)stream_user_data;
+
+  rv = nghttp3_conn_add_ack_offset(qs->h3conn, stream_id, datalen);
+  if(rv != 0) {
+    failf(qs->conn->data, "nghttp3_conn_add_ack_offset returned error: %s\n",
+          nghttp3_strerror(rv));
+    return NGTCP2_ERR_CALLBACK_FAILURE;
+  }
+
+  return 0;
+}
+
+static int cb_stream_close(ngtcp2_conn *tconn, int64_t stream_id,
+                           uint64_t app_error_code,
+                           void *user_data, void *stream_user_data)
+{
+  struct quicsocket *qs = (struct quicsocket *)user_data;
+  int rv;
+  (void)tconn;
+  (void)stream_user_data;
+  /* stream is closed... */
+
+  rv = nghttp3_conn_close_stream(qs->h3conn, stream_id,
+                                 app_error_code);
+  if(rv != 0) {
+    failf(qs->conn->data, "nghttp3_conn_close_stream returned error: %s\n",
+          nghttp3_strerror(rv));
+    return NGTCP2_ERR_CALLBACK_FAILURE;
+  }
+
+  return 0;
+}
+
+static int cb_stream_reset(ngtcp2_conn *tconn, int64_t stream_id,
+                           uint64_t final_size, uint64_t app_error_code,
+                           void *user_data, void *stream_user_data)
+{
+  struct quicsocket *qs = (struct quicsocket *)user_data;
+  int rv;
+  (void)tconn;
+  (void)final_size;
+  (void)app_error_code;
+  (void)stream_user_data;
+
+  rv = nghttp3_conn_reset_stream(qs->h3conn, stream_id);
+  if(rv != 0) {
+    failf(qs->conn->data, "nghttp3_conn_reset_stream returned error: %s\n",
+          nghttp3_strerror(rv));
+    return NGTCP2_ERR_CALLBACK_FAILURE;
+  }
+
+  return 0;
+}
+
+static int cb_extend_max_local_streams_bidi(ngtcp2_conn *tconn,
+                                            uint64_t max_streams,
+                                            void *user_data)
+{
+  (void)tconn;
+  (void)max_streams;
+  (void)user_data;
+
+  return 0;
+}
+
+static int cb_extend_max_stream_data(ngtcp2_conn *tconn, int64_t stream_id,
+                                     uint64_t max_data, void *user_data,
+                                     void *stream_user_data)
+{
+  struct quicsocket *qs = (struct quicsocket *)user_data;
+  int rv;
+  (void)tconn;
+  (void)max_data;
+  (void)stream_user_data;
+
+  rv = nghttp3_conn_unblock_stream(qs->h3conn, stream_id);
+  if(rv != 0) {
+    failf(qs->conn->data, "nghttp3_conn_unblock_stream returned error: %s\n",
+          nghttp3_strerror(rv));
+    return NGTCP2_ERR_CALLBACK_FAILURE;
+  }
+
+  return 0;
+}
+
+static int cb_get_new_connection_id(ngtcp2_conn *tconn, ngtcp2_cid *cid,
+                                    uint8_t *token, size_t cidlen,
+                                    void *user_data)
+{
+  struct quicsocket *qs = (struct quicsocket *)user_data;
+  CURLcode result;
+  (void)tconn;
+
+  result = Curl_rand(qs->conn->data, cid->data, cidlen);
+  if(result)
+    return NGTCP2_ERR_CALLBACK_FAILURE;
+  cid->datalen = cidlen;
+
+  result = Curl_rand(qs->conn->data, token, NGTCP2_STATELESS_RESET_TOKENLEN);
+  if(result)
+    return NGTCP2_ERR_CALLBACK_FAILURE;
+
+  return 0;
+}
+
+static ngtcp2_conn_callbacks ng_callbacks = {
+  ngtcp2_crypto_client_initial_cb,
+  NULL, /* recv_client_initial */
+  cb_recv_crypto_data,
+  cb_handshake_completed,
+  NULL, /* recv_version_negotiation */
+  ngtcp2_crypto_encrypt_cb,
+  ngtcp2_crypto_decrypt_cb,
+  ngtcp2_crypto_hp_mask_cb,
+  cb_recv_stream_data,
+  NULL, /* acked_crypto_offset */
+  cb_acked_stream_data_offset,
+  NULL, /* stream_open */
+  cb_stream_close,
+  NULL, /* recv_stateless_reset */
+  ngtcp2_crypto_recv_retry_cb,
+  cb_extend_max_local_streams_bidi,
+  NULL, /* extend_max_local_streams_uni */
+  NULL, /* rand  */
+  cb_get_new_connection_id,
+  NULL, /* remove_connection_id */
+  ngtcp2_crypto_update_key_cb, /* update_key */
+  NULL, /* path_validation */
+  NULL, /* select_preferred_addr */
+  cb_stream_reset,
+  NULL, /* extend_max_remote_streams_bidi */
+  NULL, /* extend_max_remote_streams_uni */
+  cb_extend_max_stream_data,
+  NULL, /* dcid_status */
+  NULL, /* handshake_confirmed */
+  NULL, /* recv_new_token */
+  ngtcp2_crypto_delete_crypto_aead_ctx_cb,
+  ngtcp2_crypto_delete_crypto_cipher_ctx_cb
+};
+
+/*
+ * Might be called twice for happy eyeballs.
+ */
+CURLcode Curl_quic_connect(struct connectdata *conn,
+                           curl_socket_t sockfd,
+                           int sockindex,
+                           const struct sockaddr *addr,
+                           socklen_t addrlen)
+{
+  int rc;
+  int rv;
+  CURLcode result;
+  ngtcp2_path path; /* TODO: this must be initialized properly */
+  struct Curl_easy *data = conn->data;
+  struct quicsocket *qs = &conn->hequic[sockindex];
+  char ipbuf[40];
+  long port;
+  int qfd;
+
+  if(qs->conn)
+    Curl_quic_disconnect(conn, sockindex);
+  qs->conn = conn;
+
+  /* extract the used address as a string */
+  if(!Curl_addr2string((struct sockaddr*)addr, addrlen, ipbuf, &port)) {
+    char buffer[STRERROR_LEN];
+    failf(data, "ssrem inet_ntop() failed with errno %d: %s",
+          SOCKERRNO, Curl_strerror(SOCKERRNO, buffer, sizeof(buffer)));
+    return CURLE_BAD_FUNCTION_ARGUMENT;
+  }
+
+  infof(data, "Connect socket %d over QUIC to %s:%ld\n",
+        sockfd, ipbuf, port);
+
+  qs->version = NGTCP2_PROTO_VER;
+#ifdef USE_OPENSSL
+  qs->sslctx = quic_ssl_ctx(data);
+  if(!qs->sslctx)
+    return CURLE_QUIC_CONNECT_ERROR;
+#endif
+
+  if(quic_init_ssl(qs))
+    return CURLE_QUIC_CONNECT_ERROR;
+
+  qs->dcid.datalen = NGTCP2_MAX_CIDLEN;
+  result = Curl_rand(data, qs->dcid.data, NGTCP2_MAX_CIDLEN);
+  if(result)
+    return result;
+
+  qs->scid.datalen = NGTCP2_MAX_CIDLEN;
+  result = Curl_rand(data, qs->scid.data, NGTCP2_MAX_CIDLEN);
+  if(result)
+    return result;
+
+  (void)Curl_qlogdir(data, qs->scid.data, NGTCP2_MAX_CIDLEN, &qfd);
+  qs->qlogfd = qfd; /* -1 if failure above */
+  quic_settings(qs, data->set.buffer_size);
+
+  qs->local_addrlen = sizeof(qs->local_addr);
+  rv = getsockname(sockfd, (struct sockaddr *)&qs->local_addr,
+                   &qs->local_addrlen);
+  if(rv == -1)
+    return CURLE_QUIC_CONNECT_ERROR;
+
+  ngtcp2_addr_init(&path.local, (uint8_t *)&qs->local_addr, qs->local_addrlen,
+                   NULL);
+  ngtcp2_addr_init(&path.remote, (uint8_t*)addr, addrlen, NULL);
+
+#ifdef NGTCP2_PROTO_VER
+#define QUICVER NGTCP2_PROTO_VER
+#else
+#error "unsupported ngtcp2 version"
+#endif
+  rc = ngtcp2_conn_client_new(&qs->qconn, &qs->dcid, &qs->scid, &path, QUICVER,
+                              &ng_callbacks, &qs->settings, NULL, qs);
+  if(rc)
+    return CURLE_QUIC_CONNECT_ERROR;
+
+  ngtcp2_conn_set_tls_native_handle(qs->qconn, qs->ssl);
+
+  return CURLE_OK;
+}
+
+/*
+ * Store ngtp2 version info in this buffer, Prefix with a space.  Return total
+ * length written.
+ */
+int Curl_quic_ver(char *p, size_t len)
+{
+  ngtcp2_info *ng2 = ngtcp2_version(0);
+  nghttp3_info *ht3 = nghttp3_version(0);
+  return msnprintf(p, len, "ngtcp2/%s nghttp3/%s",
+                   ng2->version_str, ht3->version_str);
+}
+
+static int ng_getsock(struct connectdata *conn, curl_socket_t *socks)
+{
+  struct SingleRequest *k = &conn->data->req;
+  int bitmap = GETSOCK_BLANK;
+
+  socks[0] = conn->sock[FIRSTSOCKET];
+
+  /* in a HTTP/2 connection we can basically always get a frame so we should
+     always be ready for one */
+  bitmap |= GETSOCK_READSOCK(FIRSTSOCKET);
+
+  /* we're still uploading or the HTTP/2 layer wants to send data */
+  if((k->keepon & (KEEP_SEND|KEEP_SEND_PAUSE)) == KEEP_SEND)
+    bitmap |= GETSOCK_WRITESOCK(FIRSTSOCKET);
+
+  return bitmap;
+}
+
+static int ng_perform_getsock(const struct connectdata *conn,
+                              curl_socket_t *socks)
+{
+  return ng_getsock((struct connectdata *)conn, socks);
+}
+
+static void qs_disconnect(struct quicsocket *qs)
+{
+  int i;
+  if(!qs->conn) /* already closed */
+    return;
+  qs->conn = NULL;
+  if(qs->qlogfd != -1) {
+    close(qs->qlogfd);
+    qs->qlogfd = -1;
+  }
+  if(qs->ssl)
+#ifdef USE_OPENSSL
+    SSL_free(qs->ssl);
+#elif defined(USE_GNUTLS)
+    gnutls_deinit(qs->ssl);
+#endif
+  qs->ssl = NULL;
+#ifdef USE_GNUTLS
+  if(qs->cred)
+    gnutls_certificate_free_credentials(qs->cred);
+#endif
+  for(i = 0; i < 3; i++)
+    Curl_safefree(qs->crypto_data[i].buf);
+  nghttp3_conn_del(qs->h3conn);
+  ngtcp2_conn_del(qs->qconn);
+#ifdef USE_OPENSSL
+  SSL_CTX_free(qs->sslctx);
+#endif
+}
+
+void Curl_quic_disconnect(struct connectdata *conn,
+                          int tempindex)
+{
+  if(conn->transport == TRNSPRT_QUIC)
+    qs_disconnect(&conn->hequic[tempindex]);
+}
+
+static CURLcode ng_disconnect(struct connectdata *conn,
+                              bool dead_connection)
+{
+  (void)dead_connection;
+  Curl_quic_disconnect(conn, 0);
+  Curl_quic_disconnect(conn, 1);
+  return CURLE_OK;
+}
+
+static unsigned int ng_conncheck(struct connectdata *conn,
+                                 unsigned int checks_to_perform)
+{
+  (void)conn;
+  (void)checks_to_perform;
+  return CONNRESULT_NONE;
+}
+
+static const struct Curl_handler Curl_handler_http3 = {
+  "HTTPS",                              /* scheme */
+  ZERO_NULL,                            /* setup_connection */
+  Curl_http,                            /* do_it */
+  Curl_http_done,                       /* done */
+  ZERO_NULL,                            /* do_more */
+  ZERO_NULL,                            /* connect_it */
+  ZERO_NULL,                            /* connecting */
+  ZERO_NULL,                            /* doing */
+  ng_getsock,                           /* proto_getsock */
+  ng_getsock,                           /* doing_getsock */
+  ZERO_NULL,                            /* domore_getsock */
+  ng_perform_getsock,                   /* perform_getsock */
+  ng_disconnect,                        /* disconnect */
+  ZERO_NULL,                            /* readwrite */
+  ng_conncheck,                         /* connection_check */
+  PORT_HTTP,                            /* defport */
+  CURLPROTO_HTTPS,                      /* protocol */
+  PROTOPT_SSL | PROTOPT_STREAM          /* flags */
+};
+
+static int cb_h3_stream_close(nghttp3_conn *conn, int64_t stream_id,
+                              uint64_t app_error_code, void *user_data,
+                              void *stream_user_data)
+{
+  struct Curl_easy *data = stream_user_data;
+  struct HTTP *stream = data->req.protop;
+  (void)conn;
+  (void)stream_id;
+  (void)app_error_code;
+  (void)user_data;
+  H3BUGF(infof(data, "cb_h3_stream_close CALLED\n"));
+
+  stream->closed = TRUE;
+  Curl_expire(data, 0, EXPIRE_QUIC);
+  /* make sure that ngh3_stream_recv is called again to complete the transfer
+     even if there are no more packets to be received from the server. */
+  data->state.drain = 1;
+  return 0;
+}
+
+/*
+ * write_data() copies data to the stream's receive buffer. If not enough
+ * space is available in the receive buffer, it copies the rest to the
+ * stream's overflow buffer.
+ */
+static CURLcode write_data(struct HTTP *stream, const void *mem, size_t memlen)
+{
+  CURLcode result = CURLE_OK;
+  const char *buf = mem;
+  size_t ncopy = memlen;
+  /* copy as much as possible to the receive buffer */
+  if(stream->len) {
+    size_t len = CURLMIN(ncopy, stream->len);
+    memcpy(stream->mem, buf, len);
+    stream->len -= len;
+    stream->memlen += len;
+    stream->mem += len;
+    buf += len;
+    ncopy -= len;
+  }
+  /* copy the rest to the overflow buffer */
+  if(ncopy)
+    result = Curl_dyn_addn(&stream->overflow, buf, ncopy);
+  return result;
+}
+
+static int cb_h3_recv_data(nghttp3_conn *conn, int64_t stream_id,
+                           const uint8_t *buf, size_t buflen,
+                           void *user_data, void *stream_user_data)
+{
+  struct Curl_easy *data = stream_user_data;
+  struct HTTP *stream = data->req.protop;
+  CURLcode result = CURLE_OK;
+  (void)conn;
+
+  result = write_data(stream, buf, buflen);
+  if(result) {
+    return -1;
+  }
+  stream->unacked_window += buflen;
+  (void)stream_id;
+  (void)user_data;
+  return 0;
+}
+
+static int cb_h3_deferred_consume(nghttp3_conn *conn, int64_t stream_id,
+                                  size_t consumed, void *user_data,
+                                  void *stream_user_data)
+{
+  struct quicsocket *qs = user_data;
+  (void)conn;
+  (void)stream_user_data;
+  (void)stream_id;
+
+  ngtcp2_conn_extend_max_stream_offset(qs->qconn, stream_id, consumed);
+  ngtcp2_conn_extend_max_offset(qs->qconn, consumed);
+  return 0;
+}
+
+/* Decode HTTP status code.  Returns -1 if no valid status code was
+   decoded. (duplicate from http2.c) */
+static int decode_status_code(const uint8_t *value, size_t len)
+{
+  int i;
+  int res;
+
+  if(len != 3) {
+    return -1;
+  }
+
+  res = 0;
+
+  for(i = 0; i < 3; ++i) {
+    char c = value[i];
+
+    if(c < '0' || c > '9') {
+      return -1;
+    }
+
+    res *= 10;
+    res += c - '0';
+  }
+
+  return res;
+}
+
+static int cb_h3_end_headers(nghttp3_conn *conn, int64_t stream_id,
+                             void *user_data, void *stream_user_data)
+{
+  struct Curl_easy *data = stream_user_data;
+  struct HTTP *stream = data->req.protop;
+  CURLcode result = CURLE_OK;
+  (void)conn;
+  (void)stream_id;
+  (void)user_data;
+
+  /* add a CRLF only if we've received some headers */
+  if(stream->firstheader) {
+    result = write_data(stream, "\r\n", 2);
+    if(result) {
+      return -1;
+    }
+  }
+  return 0;
+}
+
+static int cb_h3_recv_header(nghttp3_conn *conn, int64_t stream_id,
+                             int32_t token, nghttp3_rcbuf *name,
+                             nghttp3_rcbuf *value, uint8_t flags,
+                             void *user_data, void *stream_user_data)
+{
+  nghttp3_vec h3name = nghttp3_rcbuf_get_buf(name);
+  nghttp3_vec h3val = nghttp3_rcbuf_get_buf(value);
+  struct Curl_easy *data = stream_user_data;
+  struct HTTP *stream = data->req.protop;
+  CURLcode result = CURLE_OK;
+  (void)conn;
+  (void)stream_id;
+  (void)token;
+  (void)flags;
+  (void)user_data;
+
+  if(h3name.len == sizeof(":status") - 1 &&
+     !memcmp(":status", h3name.base, h3name.len)) {
+    char line[14]; /* status line is always 13 characters long */
+    size_t ncopy;
+    int status = decode_status_code(h3val.base, h3val.len);
+    DEBUGASSERT(status != -1);
+    ncopy = msnprintf(line, sizeof(line), "HTTP/3 %03d \r\n", status);
+    result = write_data(stream, line, ncopy);
+    if(result) {
+      return -1;
+    }
+  }
+  else {
+    /* store as a HTTP1-style header */
+    result = write_data(stream, h3name.base, h3name.len);
+    if(result) {
+      return -1;
+    }
+    result = write_data(stream, ": ", 2);
+    if(result) {
+      return -1;
+    }
+    result = write_data(stream, h3val.base, h3val.len);
+    if(result) {
+      return -1;
+    }
+    result = write_data(stream, "\r\n", 2);
+    if(result) {
+      return -1;
+    }
+  }
+
+  stream->firstheader = TRUE;
+  return 0;
+}
+
+static int cb_h3_send_stop_sending(nghttp3_conn *conn, int64_t stream_id,
+                                   uint64_t app_error_code,
+                                   void *user_data,
+                                   void *stream_user_data)
+{
+  (void)conn;
+  (void)stream_id;
+  (void)app_error_code;
+  (void)user_data;
+  (void)stream_user_data;
+  return 0;
+}
+
+static nghttp3_conn_callbacks ngh3_callbacks = {
+  cb_h3_acked_stream_data, /* acked_stream_data */
+  cb_h3_stream_close,
+  cb_h3_recv_data,
+  cb_h3_deferred_consume,
+  NULL, /* begin_headers */
+  cb_h3_recv_header,
+  cb_h3_end_headers,
+  NULL, /* begin_trailers */
+  cb_h3_recv_header,
+  NULL, /* end_trailers */
+  NULL, /* http_begin_push_promise */
+  NULL, /* http_recv_push_promise */
+  NULL, /* http_end_push_promise */
+  NULL, /* http_cancel_push */
+  cb_h3_send_stop_sending,
+  NULL, /* push_stream */
+  NULL, /* end_stream */
+};
+
+static int init_ngh3_conn(struct quicsocket *qs)
+{
+  CURLcode result;
+  int rc;
+  int64_t ctrl_stream_id, qpack_enc_stream_id, qpack_dec_stream_id;
+
+  if(ngtcp2_conn_get_max_local_streams_uni(qs->qconn) < 3) {
+    failf(qs->conn->data, "too few available QUIC streams");
+    return CURLE_QUIC_CONNECT_ERROR;
+  }
+
+  nghttp3_conn_settings_default(&qs->h3settings);
+
+  rc = nghttp3_conn_client_new(&qs->h3conn,
+                               &ngh3_callbacks,
+                               &qs->h3settings,
+                               nghttp3_mem_default(),
+                               qs);
+  if(rc) {
+    result = CURLE_OUT_OF_MEMORY;
+    goto fail;
+  }
+
+  rc = ngtcp2_conn_open_uni_stream(qs->qconn, &ctrl_stream_id, NULL);
+  if(rc) {
+    result = CURLE_QUIC_CONNECT_ERROR;
+    goto fail;
+  }
+
+  rc = nghttp3_conn_bind_control_stream(qs->h3conn, ctrl_stream_id);
+  if(rc) {
+    result = CURLE_QUIC_CONNECT_ERROR;
+    goto fail;
+  }
+
+  rc = ngtcp2_conn_open_uni_stream(qs->qconn, &qpack_enc_stream_id, NULL);
+  if(rc) {
+    result = CURLE_QUIC_CONNECT_ERROR;
+    goto fail;
+  }
+
+  rc = ngtcp2_conn_open_uni_stream(qs->qconn, &qpack_dec_stream_id, NULL);
+  if(rc) {
+    result = CURLE_QUIC_CONNECT_ERROR;
+    goto fail;
+  }
+
+  rc = nghttp3_conn_bind_qpack_streams(qs->h3conn, qpack_enc_stream_id,
+                                       qpack_dec_stream_id);
+  if(rc) {
+    result = CURLE_QUIC_CONNECT_ERROR;
+    goto fail;
+  }
+
+  return CURLE_OK;
+  fail:
+
+  return result;
+}
+
+static Curl_recv ngh3_stream_recv;
+static Curl_send ngh3_stream_send;
+
+static size_t drain_overflow_buffer(struct HTTP *stream)
+{
+  size_t overlen = Curl_dyn_len(&stream->overflow);
+  size_t ncopy = CURLMIN(overlen, stream->len);
+  if(ncopy > 0) {
+    memcpy(stream->mem, Curl_dyn_ptr(&stream->overflow), ncopy);
+    stream->len -= ncopy;
+    stream->mem += ncopy;
+    stream->memlen += ncopy;
+    if(ncopy != overlen)
+      /* make the buffer only keep the tail */
+      (void)Curl_dyn_tail(&stream->overflow, overlen - ncopy);
+  }
+  return ncopy;
+}
+
+/* incoming data frames on the h3 stream */
+static ssize_t ngh3_stream_recv(struct connectdata *conn,
+                                int sockindex,
+                                char *buf,
+                                size_t buffersize,
+                                CURLcode *curlcode)
+{
+  curl_socket_t sockfd = conn->sock[sockindex];
+  struct HTTP *stream = conn->data->req.protop;
+  struct quicsocket *qs = conn->quic;
+
+  if(!stream->memlen) {
+    /* remember where to store incoming data for this stream and how big the
+       buffer is */
+    stream->mem = buf;
+    stream->len = buffersize;
+  }
+  /* else, there's data in the buffer already */
+
+  /* if there's data in the overflow buffer from a previous call, copy as much
+     as possible to the receive buffer before receiving more */
+  drain_overflow_buffer(stream);
+
+  if(ng_process_ingress(conn, sockfd, qs)) {
+    *curlcode = CURLE_RECV_ERROR;
+    return -1;
+  }
+  if(ng_flush_egress(conn, sockfd, qs)) {
+    *curlcode = CURLE_SEND_ERROR;
+    return -1;
+  }
+
+  if(stream->memlen) {
+    ssize_t memlen = stream->memlen;
+    /* data arrived */
+    *curlcode = CURLE_OK;
+    /* reset to allow more data to come */
+    stream->memlen = 0;
+    stream->mem = buf;
+    stream->len = buffersize;
+    /* extend the stream window with the data we're consuming and send out
+       any additional packets to tell the server that we can receive more */
+    extend_stream_window(qs->qconn, stream);
+    if(ng_flush_egress(conn, sockfd, qs)) {
+      *curlcode = CURLE_SEND_ERROR;
+      return -1;
+    }
+    return memlen;
+  }
+
+  if(stream->closed) {
+    *curlcode = CURLE_OK;
+    return 0;
+  }
+
+  infof(conn->data, "ngh3_stream_recv returns 0 bytes and EAGAIN\n");
+  *curlcode = CURLE_AGAIN;
+  return -1;
+}
+
+/* this amount of data has now been acked on this stream */
+static int cb_h3_acked_stream_data(nghttp3_conn *conn, int64_t stream_id,
+                                   size_t datalen, void *user_data,
+                                   void *stream_user_data)
+{
+  struct Curl_easy *data = stream_user_data;
+  struct HTTP *stream = data->req.protop;
+  (void)conn;
+  (void)stream_id;
+  (void)user_data;
+
+  if(!data->set.postfields) {
+    stream->h3out->used -= datalen;
+    H3BUGF(infof(data,
+                 "cb_h3_acked_stream_data, %zd bytes, %zd left unacked\n",
+                 datalen, stream->h3out->used));
+    DEBUGASSERT(stream->h3out->used < H3_SEND_SIZE);
+  }
+  return 0;
+}
+
+static ssize_t cb_h3_readfunction(nghttp3_conn *conn, int64_t stream_id,
+                                  nghttp3_vec *vec, size_t veccnt,
+                                  uint32_t *pflags, void *user_data,
+                                  void *stream_user_data)
+{
+  struct Curl_easy *data = stream_user_data;
+  size_t nread;
+  struct HTTP *stream = data->req.protop;
+  (void)conn;
+  (void)stream_id;
+  (void)user_data;
+  (void)veccnt;
+
+  if(data->set.postfields) {
+    vec[0].base = data->set.postfields;
+    vec[0].len = data->state.infilesize;
+    *pflags = NGHTTP3_DATA_FLAG_EOF;
+    return 1;
+  }
+
+  nread = CURLMIN(stream->upload_len, H3_SEND_SIZE - stream->h3out->used);
+  if(nread > 0) {
+    /* nghttp3 wants us to hold on to the data until it tells us it is okay to
+       delete it. Append the data at the end of the h3out buffer. Since we can
+       only return consecutive data, copy the amount that fits and the next
+       part comes in next invoke. */
+    struct h3out *out = stream->h3out;
+    if(nread + out->windex > H3_SEND_SIZE)
+      nread = H3_SEND_SIZE - out->windex;
+
+    memcpy(&out->buf[out->windex], stream->upload_mem, nread);
+    out->windex += nread;
+    out->used += nread;
+
+    /* that's the chunk we return to nghttp3 */
+    vec[0].base = &out->buf[out->windex];
+    vec[0].len = nread;
+
+    if(out->windex == H3_SEND_SIZE)
+      out->windex = 0; /* wrap */
+    stream->upload_mem += nread;
+    stream->upload_len -= nread;
+    if(data->state.infilesize != -1) {
+      stream->upload_left -= nread;
+      if(!stream->upload_left)
+        *pflags = NGHTTP3_DATA_FLAG_EOF;
+    }
+    H3BUGF(infof(data, "cb_h3_readfunction %zd bytes%s (at %zd unacked)\n",
+                 nread, *pflags == NGHTTP3_DATA_FLAG_EOF?" EOF":"",
+                 out->used));
+  }
+  if(stream->upload_done && !stream->upload_len &&
+     (stream->upload_left <= 0)) {
+    H3BUGF(infof(data, "!!!!!!!!! cb_h3_readfunction sets EOF\n"));
+    *pflags = NGHTTP3_DATA_FLAG_EOF;
+    return 0;
+  }
+  else if(!nread) {
+    return NGHTTP3_ERR_WOULDBLOCK;
+  }
+  return 1;
+}
+
+/* Index where :authority header field will appear in request header
+   field list. */
+#define AUTHORITY_DST_IDX 3
+
+static CURLcode http_request(struct connectdata *conn, const void *mem,
+                             size_t len)
+{
+  struct HTTP *stream = conn->data->req.protop;
+  size_t nheader;
+  size_t i;
+  size_t authority_idx;
+  char *hdbuf = (char *)mem;
+  char *end, *line_end;
+  struct quicsocket *qs = conn->quic;
+  CURLcode result = CURLE_OK;
+  struct Curl_easy *data = conn->data;
+  nghttp3_nv *nva = NULL;
+  int64_t stream3_id;
+  int rc;
+  struct h3out *h3out = NULL;
+
+  rc = ngtcp2_conn_open_bidi_stream(qs->qconn, &stream3_id, NULL);
+  if(rc) {
+    failf(conn->data, "can get bidi streams");
+    result = CURLE_SEND_ERROR;
+    goto fail;
+  }
+
+  stream->stream3_id = stream3_id;
+  stream->h3req = TRUE; /* senf off! */
+  Curl_dyn_init(&stream->overflow, CURL_MAX_READ_SIZE);
+
+  /* Calculate number of headers contained in [mem, mem + len). Assumes a
+     correctly generated HTTP header field block. */
+  nheader = 0;
+  for(i = 1; i < len; ++i) {
+    if(hdbuf[i] == '\n' && hdbuf[i - 1] == '\r') {
+      ++nheader;
+      ++i;
+    }
+  }
+  if(nheader < 2)
+    goto fail;
+
+  /* We counted additional 2 \r\n in the first and last line. We need 3
+     new headers: :method, :path and :scheme. Therefore we need one
+     more space. */
+  nheader += 1;
+  nva = malloc(sizeof(nghttp3_nv) * nheader);
+  if(!nva) {
+    result = CURLE_OUT_OF_MEMORY;
+    goto fail;
+  }
+
+  /* Extract :method, :path from request line
+     We do line endings with CRLF so checking for CR is enough */
+  line_end = memchr(hdbuf, '\r', len);
+  if(!line_end) {
+    result = CURLE_BAD_FUNCTION_ARGUMENT; /* internal error */
+    goto fail;
+  }
+
+  /* Method does not contain spaces */
+  end = memchr(hdbuf, ' ', line_end - hdbuf);
+  if(!end || end == hdbuf)
+    goto fail;
+  nva[0].name = (unsigned char *)":method";
+  nva[0].namelen = strlen((char *)nva[0].name);
+  nva[0].value = (unsigned char *)hdbuf;
+  nva[0].valuelen = (size_t)(end - hdbuf);
+  nva[0].flags = NGHTTP3_NV_FLAG_NONE;
+
+  hdbuf = end + 1;
+
+  /* Path may contain spaces so scan backwards */
+  end = NULL;
+  for(i = (size_t)(line_end - hdbuf); i; --i) {
+    if(hdbuf[i - 1] == ' ') {
+      end = &hdbuf[i - 1];
+      break;
+    }
+  }
+  if(!end || end == hdbuf)
+    goto fail;
+  nva[1].name = (unsigned char *)":path";
+  nva[1].namelen = strlen((char *)nva[1].name);
+  nva[1].value = (unsigned char *)hdbuf;
+  nva[1].valuelen = (size_t)(end - hdbuf);
+  nva[1].flags = NGHTTP3_NV_FLAG_NONE;
+
+  nva[2].name = (unsigned char *)":scheme";
+  nva[2].namelen = strlen((char *)nva[2].name);
+  if(conn->handler->flags & PROTOPT_SSL)
+    nva[2].value = (unsigned char *)"https";
+  else
+    nva[2].value = (unsigned char *)"http";
+  nva[2].valuelen = strlen((char *)nva[2].value);
+  nva[2].flags = NGHTTP3_NV_FLAG_NONE;
+
+
+  authority_idx = 0;
+  i = 3;
+  while(i < nheader) {
+    size_t hlen;
+
+    hdbuf = line_end + 2;
+
+    /* check for next CR, but only within the piece of data left in the given
+       buffer */
+    line_end = memchr(hdbuf, '\r', len - (hdbuf - (char *)mem));
+    if(!line_end || (line_end == hdbuf))
+      goto fail;
+
+    /* header continuation lines are not supported */
+    if(*hdbuf == ' ' || *hdbuf == '\t')
+      goto fail;
+
+    for(end = hdbuf; end < line_end && *end != ':'; ++end)
+      ;
+    if(end == hdbuf || end == line_end)
+      goto fail;
+    hlen = end - hdbuf;
+
+    if(hlen == 4 && strncasecompare("host", hdbuf, 4)) {
+      authority_idx = i;
+      nva[i].name = (unsigned char *)":authority";
+      nva[i].namelen = strlen((char *)nva[i].name);
+    }
+    else {
+      nva[i].namelen = (size_t)(end - hdbuf);
+      /* Lower case the header name for HTTP/3 */
+      Curl_strntolower((char *)hdbuf, hdbuf, nva[i].namelen);
+      nva[i].name = (unsigned char *)hdbuf;
+    }
+    nva[i].flags = NGHTTP3_NV_FLAG_NONE;
+    hdbuf = end + 1;
+    while(*hdbuf == ' ' || *hdbuf == '\t')
+      ++hdbuf;
+    end = line_end;
+
+#if 0 /* This should probably go in more or less like this */
+    switch(inspect_header((const char *)nva[i].name, nva[i].namelen, hdbuf,
+                          end - hdbuf)) {
+    case HEADERINST_IGNORE:
+      /* skip header fields prohibited by HTTP/2 specification. */
+      --nheader;
+      continue;
+    case HEADERINST_TE_TRAILERS:
+      nva[i].value = (uint8_t*)"trailers";
+      nva[i].value_len = sizeof("trailers") - 1;
+      break;
+    default:
+      nva[i].value = (unsigned char *)hdbuf;
+      nva[i].value_len = (size_t)(end - hdbuf);
+    }
+#endif
+    nva[i].value = (unsigned char *)hdbuf;
+    nva[i].valuelen = (size_t)(end - hdbuf);
+    nva[i].flags = NGHTTP3_NV_FLAG_NONE;
+
+    ++i;
+  }
+
+  /* :authority must come before non-pseudo header fields */
+  if(authority_idx != 0 && authority_idx != AUTHORITY_DST_IDX) {
+    nghttp3_nv authority = nva[authority_idx];
+    for(i = authority_idx; i > AUTHORITY_DST_IDX; --i) {
+      nva[i] = nva[i - 1];
+    }
+    nva[i] = authority;
+  }
+
+  /* Warn stream may be rejected if cumulative length of headers is too
+     large. */
+#define MAX_ACC 60000  /* <64KB to account for some overhead */
+  {
+    size_t acc = 0;
+    for(i = 0; i < nheader; ++i)
+      acc += nva[i].namelen + nva[i].valuelen;
+
+    if(acc > MAX_ACC) {
+      infof(data, "http_request: Warning: The cumulative length of all "
+            "headers exceeds %zu bytes and that could cause the "
+            "stream to be rejected.\n", MAX_ACC);
+    }
+  }
+
+  switch(data->state.httpreq) {
+  case HTTPREQ_POST:
+  case HTTPREQ_POST_FORM:
+  case HTTPREQ_POST_MIME:
+  case HTTPREQ_PUT: {
+    nghttp3_data_reader data_reader;
+    if(data->state.infilesize != -1)
+      stream->upload_left = data->state.infilesize;
+    else
+      /* data sending without specifying the data amount up front */
+      stream->upload_left = -1; /* unknown, but not zero */
+
+    data_reader.read_data = cb_h3_readfunction;
+
+    h3out = calloc(sizeof(struct h3out), 1);
+    if(!h3out) {
+      result = CURLE_OUT_OF_MEMORY;
+      goto fail;
+    }
+    stream->h3out = h3out;
+
+    rc = nghttp3_conn_submit_request(qs->h3conn, stream->stream3_id,
+                                     nva, nheader, &data_reader,
+                                     conn->data);
+    if(rc) {
+      result = CURLE_SEND_ERROR;
+      goto fail;
+    }
+    break;
+  }
+  default:
+    stream->upload_left = 0; /* nothing left to send */
+    rc = nghttp3_conn_submit_request(qs->h3conn, stream->stream3_id,
+                                     nva, nheader,
+                                     NULL, /* no body! */
+                                     conn->data);
+    if(rc) {
+      result = CURLE_SEND_ERROR;
+      goto fail;
+    }
+    break;
+  }
+
+  Curl_safefree(nva);
+
+  infof(data, "Using HTTP/3 Stream ID: %x (easy handle %p)\n",
+        stream3_id, (void *)data);
+
+  return CURLE_OK;
+
+fail:
+  free(nva);
+  return result;
+}
+static ssize_t ngh3_stream_send(struct connectdata *conn,
+                                int sockindex,
+                                const void *mem,
+                                size_t len,
+                                CURLcode *curlcode)
+{
+  ssize_t sent;
+  struct quicsocket *qs = conn->quic;
+  curl_socket_t sockfd = conn->sock[sockindex];
+  struct HTTP *stream = conn->data->req.protop;
+
+  if(!stream->h3req) {
+    CURLcode result = http_request(conn, mem, len);
+    if(result) {
+      *curlcode = CURLE_SEND_ERROR;
+      return -1;
+    }
+    sent = len;
+  }
+  else {
+    H3BUGF(infof(conn->data, "ngh3_stream_send() wants to send %zd bytes\n",
+                 len));
+    if(!stream->upload_len) {
+      stream->upload_mem = mem;
+      stream->upload_len = len;
+      (void)nghttp3_conn_resume_stream(qs->h3conn, stream->stream3_id);
+      sent = len;
+    }
+    else {
+      *curlcode = CURLE_AGAIN;
+      return -1;
+    }
+  }
+
+  if(ng_flush_egress(conn, sockfd, qs)) {
+    *curlcode = CURLE_SEND_ERROR;
+    return -1;
+  }
+
+  *curlcode = CURLE_OK;
+  return sent;
+}
+
+static void ng_has_connected(struct connectdata *conn, int tempindex)
+{
+  conn->recv[FIRSTSOCKET] = ngh3_stream_recv;
+  conn->send[FIRSTSOCKET] = ngh3_stream_send;
+  conn->handler = &Curl_handler_http3;
+  conn->bits.multiplex = TRUE; /* at least potentially multiplexed */
+  conn->httpversion = 30;
+  conn->bundle->multiuse = BUNDLE_MULTIPLEX;
+  conn->quic = &conn->hequic[tempindex];
+  DEBUGF(infof(conn->data, "ngtcp2 established connection!\n"));
+}
+
+/*
+ * There can be multiple connection attempts going on in parallel.
+ */
+CURLcode Curl_quic_is_connected(struct connectdata *conn,
+                                int sockindex,
+                                bool *done)
+{
+  CURLcode result;
+  struct quicsocket *qs = &conn->hequic[sockindex];
+  curl_socket_t sockfd = conn->tempsock[sockindex];
+
+  result = ng_process_ingress(conn, sockfd, qs);
+  if(result)
+    goto error;
+
+  result = ng_flush_egress(conn, sockfd, qs);
+  if(result)
+    goto error;
+
+  if(ngtcp2_conn_get_handshake_completed(qs->qconn)) {
+    *done = TRUE;
+    ng_has_connected(conn, sockindex);
+  }
+
+  return result;
+  error:
+  (void)qs_disconnect(qs);
+  return result;
+
+}
+
+static CURLcode ng_process_ingress(struct connectdata *conn, int sockfd,
+                                   struct quicsocket *qs)
+{
+  ssize_t recvd;
+  int rv;
+  uint8_t buf[65536];
+  size_t bufsize = sizeof(buf);
+  struct sockaddr_storage remote_addr;
+  socklen_t remote_addrlen;
+  ngtcp2_path path;
+  ngtcp2_tstamp ts = timestamp();
+
+  for(;;) {
+    remote_addrlen = sizeof(remote_addr);
+    while((recvd = recvfrom(sockfd, buf, bufsize, 0,
+                            (struct sockaddr *)&remote_addr,
+                            &remote_addrlen)) == -1 &&
+          SOCKERRNO == EINTR)
+      ;
+    if(recvd == -1) {
+      if(SOCKERRNO == EAGAIN || SOCKERRNO == EWOULDBLOCK)
+        break;
+
+      failf(conn->data, "ngtcp2: recvfrom() unexpectedly returned %d", recvd);
+      return CURLE_RECV_ERROR;
+    }
+
+    ngtcp2_addr_init(&path.local, (uint8_t *)&qs->local_addr,
+                     qs->local_addrlen, NULL);
+    ngtcp2_addr_init(&path.remote, (uint8_t *)&remote_addr, remote_addrlen,
+                     NULL);
+
+    rv = ngtcp2_conn_read_pkt(qs->qconn, &path, buf, recvd, ts);
+    if(rv != 0) {
+      /* TODO Send CONNECTION_CLOSE if possible */
+      return CURLE_RECV_ERROR;
+    }
+  }
+
+  return CURLE_OK;
+}
+
+static CURLcode ng_flush_egress(struct connectdata *conn, int sockfd,
+                                struct quicsocket *qs)
+{
+  int rv;
+  ssize_t sent;
+  ssize_t outlen;
+  uint8_t out[NGTCP2_MAX_PKTLEN_IPV4];
+  size_t pktlen;
+  ngtcp2_path_storage ps;
+  ngtcp2_tstamp ts = timestamp();
+  struct sockaddr_storage remote_addr;
+  ngtcp2_tstamp expiry;
+  ngtcp2_duration timeout;
+  int64_t stream_id;
+  ssize_t veccnt;
+  int fin;
+  nghttp3_vec vec[16];
+  ssize_t ndatalen;
+
+  switch(qs->local_addr.ss_family) {
+  case AF_INET:
+    pktlen = NGTCP2_MAX_PKTLEN_IPV4;
+    break;
+#ifdef ENABLE_IPV6
+  case AF_INET6:
+    pktlen = NGTCP2_MAX_PKTLEN_IPV6;
+    break;
+#endif
+  default:
+    assert(0);
+  }
+
+  rv = ngtcp2_conn_handle_expiry(qs->qconn, ts);
+  if(rv != 0) {
+    failf(conn->data, "ngtcp2_conn_handle_expiry returned error: %s\n",
+          ngtcp2_strerror(rv));
+    return CURLE_SEND_ERROR;
+  }
+
+  ngtcp2_path_storage_zero(&ps);
+
+  for(;;) {
+    outlen = -1;
+    if(qs->h3conn && ngtcp2_conn_get_max_data_left(qs->qconn)) {
+      veccnt = nghttp3_conn_writev_stream(qs->h3conn, &stream_id, &fin, vec,
+                                          sizeof(vec) / sizeof(vec[0]));
+      if(veccnt < 0) {
+        failf(conn->data, "nghttp3_conn_writev_stream returned error: %s\n",
+              nghttp3_strerror((int)veccnt));
+        return CURLE_SEND_ERROR;
+      }
+      else if(veccnt > 0) {
+        uint32_t flags = NGTCP2_WRITE_STREAM_FLAG_MORE |
+          (fin ? NGTCP2_WRITE_STREAM_FLAG_FIN : 0);
+        outlen =
+          ngtcp2_conn_writev_stream(qs->qconn, &ps.path,
+                                    out, pktlen, &ndatalen,
+                                    flags, stream_id,
+                                    (const ngtcp2_vec *)vec, veccnt, ts);
+        if(outlen == 0) {
+          break;
+        }
+        if(outlen < 0) {
+          if(outlen == NGTCP2_ERR_STREAM_DATA_BLOCKED ||
+             outlen == NGTCP2_ERR_STREAM_SHUT_WR) {
+            assert(ndatalen == -1);
+            rv = nghttp3_conn_block_stream(qs->h3conn, stream_id);
+            if(rv != 0) {
+              failf(conn->data,
+                    "nghttp3_conn_block_stream returned error: %s\n",
+                    nghttp3_strerror(rv));
+              return CURLE_SEND_ERROR;
+            }
+            continue;
+          }
+          else if(outlen == NGTCP2_ERR_WRITE_STREAM_MORE) {
+            assert(ndatalen > 0);
+            rv = nghttp3_conn_add_write_offset(qs->h3conn, stream_id,
+                                               ndatalen);
+            if(rv != 0) {
+              failf(conn->data,
+                    "nghttp3_conn_add_write_offset returned error: %s\n",
+                    nghttp3_strerror(rv));
+              return CURLE_SEND_ERROR;
+            }
+            continue;
+          }
+          else {
+            assert(ndatalen == -1);
+            failf(conn->data, "ngtcp2_conn_writev_stream returned error: %s\n",
+                  ngtcp2_strerror((int)outlen));
+            return CURLE_SEND_ERROR;
+          }
+        }
+        else {
+          assert(ndatalen == -1);
+        }
+      }
+    }
+    if(outlen < 0) {
+      outlen = ngtcp2_conn_write_pkt(qs->qconn, &ps.path, out, pktlen, ts);
+      if(outlen < 0) {
+        failf(conn->data, "ngtcp2_conn_write_pkt returned error: %s\n",
+              ngtcp2_strerror((int)outlen));
+        return CURLE_SEND_ERROR;
+      }
+      if(outlen == 0)
+        break;
+    }
+
+    memcpy(&remote_addr, ps.path.remote.addr, ps.path.remote.addrlen);
+    while((sent = send(sockfd, out, outlen, 0)) == -1 &&
+          SOCKERRNO == EINTR)
+      ;
+
+    if(sent == -1) {
+      if(SOCKERRNO == EAGAIN || SOCKERRNO == EWOULDBLOCK) {
+        /* TODO Cache packet */
+        break;
+      }
+      else {
+        failf(conn->data, "send() returned %zd (errno %d)\n", sent,
+              SOCKERRNO);
+        return CURLE_SEND_ERROR;
+      }
+    }
+  }
+
+  expiry = ngtcp2_conn_get_expiry(qs->qconn);
+  if(expiry != UINT64_MAX) {
+    if(expiry <= ts) {
+      timeout = NGTCP2_MILLISECONDS;
+    }
+    else {
+      timeout = expiry - ts;
+    }
+    Curl_expire(conn->data, timeout / NGTCP2_MILLISECONDS, EXPIRE_QUIC);
+  }
+
+  return CURLE_OK;
+}
+
+/*
+ * Called from transfer.c:done_sending when we stop HTTP/3 uploading.
+ */
+CURLcode Curl_quic_done_sending(struct connectdata *conn)
+{
+  if(conn->handler == &Curl_handler_http3) {
+    /* only for HTTP/3 transfers */
+    struct HTTP *stream = conn->data->req.protop;
+    struct quicsocket *qs = conn->quic;
+    stream->upload_done = TRUE;
+    (void)nghttp3_conn_resume_stream(qs->h3conn, stream->stream3_id);
+  }
+
+  return CURLE_OK;
+}
+
+/*
+ * Called from http.c:Curl_http_done when a request completes.
+ */
+void Curl_quic_done(struct Curl_easy *data, bool premature)
+{
+  (void)premature;
+  if(data->conn->handler == &Curl_handler_http3) {
+    /* only for HTTP/3 transfers */
+    struct HTTP *stream = data->req.protop;
+    Curl_dyn_free(&stream->overflow);
+  }
+}
+
+/*
+ * Called from transfer.c:data_pending to know if we should keep looping
+ * to receive more data from the connection.
+ */
+bool Curl_quic_data_pending(const struct Curl_easy *data)
+{
+  /* We may have received more data than we're able to hold in the receive
+     buffer and allocated an overflow buffer. Since it's possible that
+     there's no more data coming on the socket, we need to keep reading
+     until the overflow buffer is empty. */
+  const struct HTTP *stream = data->req.protop;
+  return Curl_dyn_len(&stream->overflow) > 0;
+}
+
+#endif
diff --git a/Utilities/cmcurl/lib/vquic/ngtcp2.h b/Utilities/cmcurl/lib/vquic/ngtcp2.h
new file mode 100644
index 0000000..e2f8b56
--- /dev/null
+++ b/Utilities/cmcurl/lib/vquic/ngtcp2.h
@@ -0,0 +1,73 @@
+#ifndef HEADER_CURL_VQUIC_NGTCP2_H
+#define HEADER_CURL_VQUIC_NGTCP2_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#ifdef USE_NGTCP2
+
+#include <ngtcp2/ngtcp2.h>
+#include <nghttp3/nghttp3.h>
+#ifdef USE_OPENSSL
+#include <openssl/ssl.h>
+#elif defined(USE_GNUTLS)
+#include <gnutls/gnutls.h>
+#endif
+
+struct quic_handshake {
+  char *buf;       /* pointer to the buffer */
+  size_t alloclen; /* size of allocation */
+  size_t len;      /* size of content in buffer */
+  size_t nread;    /* how many bytes have been read */
+};
+
+struct quicsocket {
+  struct connectdata *conn; /* point back to the connection */
+  ngtcp2_conn *qconn;
+  ngtcp2_cid dcid;
+  ngtcp2_cid scid;
+  uint32_t version;
+  ngtcp2_settings settings;
+#ifdef USE_OPENSSL
+  SSL_CTX *sslctx;
+  SSL *ssl;
+#elif defined(USE_GNUTLS)
+  gnutls_certificate_credentials_t cred;
+  gnutls_session_t ssl;
+#endif
+  struct quic_handshake crypto_data[3];
+  /* the last TLS alert description generated by the local endpoint */
+  uint8_t tls_alert;
+  struct sockaddr_storage local_addr;
+  socklen_t local_addrlen;
+
+  nghttp3_conn *h3conn;
+  nghttp3_conn_settings h3settings;
+  int qlogfd;
+};
+
+#include "urldata.h"
+
+#endif
+
+#endif /* HEADER_CURL_VQUIC_NGTCP2_H */
diff --git a/Utilities/cmcurl/lib/vquic/quiche.c b/Utilities/cmcurl/lib/vquic/quiche.c
new file mode 100644
index 0000000..be6f15c
--- /dev/null
+++ b/Utilities/cmcurl/lib/vquic/quiche.c
@@ -0,0 +1,853 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#ifdef USE_QUICHE
+#include <quiche.h>
+#include <openssl/err.h>
+#include "urldata.h"
+#include "sendf.h"
+#include "strdup.h"
+#include "rand.h"
+#include "quic.h"
+#include "strcase.h"
+#include "multiif.h"
+#include "connect.h"
+#include "strerror.h"
+#include "vquic.h"
+
+/* The last 3 #include files should be in this order */
+#include "curl_printf.h"
+#include "curl_memory.h"
+#include "memdebug.h"
+
+#define DEBUG_HTTP3
+/* #define DEBUG_QUICHE */
+#ifdef DEBUG_HTTP3
+#define H3BUGF(x) x
+#else
+#define H3BUGF(x) do { } while(0)
+#endif
+
+#define QUIC_MAX_STREAMS (256*1024)
+#define QUIC_MAX_DATA (1*1024*1024)
+#define QUIC_IDLE_TIMEOUT (60 * 1000) /* milliseconds */
+
+static CURLcode process_ingress(struct connectdata *conn,
+                                curl_socket_t sockfd,
+                                struct quicsocket *qs);
+
+static CURLcode flush_egress(struct connectdata *conn, curl_socket_t sockfd,
+                             struct quicsocket *qs);
+
+static CURLcode http_request(struct connectdata *conn, const void *mem,
+                             size_t len);
+static Curl_recv h3_stream_recv;
+static Curl_send h3_stream_send;
+
+static int quiche_getsock(struct connectdata *conn, curl_socket_t *socks)
+{
+  struct SingleRequest *k = &conn->data->req;
+  int bitmap = GETSOCK_BLANK;
+
+  socks[0] = conn->sock[FIRSTSOCKET];
+
+  /* in a HTTP/2 connection we can basically always get a frame so we should
+     always be ready for one */
+  bitmap |= GETSOCK_READSOCK(FIRSTSOCKET);
+
+  /* we're still uploading or the HTTP/2 layer wants to send data */
+  if((k->keepon & (KEEP_SEND|KEEP_SEND_PAUSE)) == KEEP_SEND)
+    bitmap |= GETSOCK_WRITESOCK(FIRSTSOCKET);
+
+  return bitmap;
+}
+
+static int quiche_perform_getsock(const struct connectdata *conn,
+                                  curl_socket_t *socks)
+{
+  return quiche_getsock((struct connectdata *)conn, socks);
+}
+
+static CURLcode qs_disconnect(struct quicsocket *qs)
+{
+  if(qs->h3config)
+    quiche_h3_config_free(qs->h3config);
+  if(qs->h3c)
+    quiche_h3_conn_free(qs->h3c);
+  quiche_config_free(qs->cfg);
+  quiche_conn_free(qs->conn);
+  return CURLE_OK;
+}
+
+static CURLcode quiche_disconnect(struct connectdata *conn,
+                                  bool dead_connection)
+{
+  struct quicsocket *qs = conn->quic;
+  (void)dead_connection;
+  return qs_disconnect(qs);
+}
+
+void Curl_quic_disconnect(struct connectdata *conn,
+                          int tempindex)
+{
+  if(conn->transport == TRNSPRT_QUIC)
+    qs_disconnect(&conn->hequic[tempindex]);
+}
+
+static unsigned int quiche_conncheck(struct connectdata *conn,
+                                     unsigned int checks_to_perform)
+{
+  (void)conn;
+  (void)checks_to_perform;
+  return CONNRESULT_NONE;
+}
+
+static CURLcode quiche_do(struct connectdata *conn, bool *done)
+{
+  struct HTTP *stream = conn->data->req.protop;
+  stream->h3req = FALSE; /* not sent */
+  return Curl_http(conn, done);
+}
+
+static const struct Curl_handler Curl_handler_http3 = {
+  "HTTPS",                              /* scheme */
+  ZERO_NULL,                            /* setup_connection */
+  quiche_do,                            /* do_it */
+  Curl_http_done,                       /* done */
+  ZERO_NULL,                            /* do_more */
+  ZERO_NULL,                            /* connect_it */
+  ZERO_NULL,                            /* connecting */
+  ZERO_NULL,                            /* doing */
+  quiche_getsock,                       /* proto_getsock */
+  quiche_getsock,                       /* doing_getsock */
+  ZERO_NULL,                            /* domore_getsock */
+  quiche_perform_getsock,               /* perform_getsock */
+  quiche_disconnect,                    /* disconnect */
+  ZERO_NULL,                            /* readwrite */
+  quiche_conncheck,                     /* connection_check */
+  PORT_HTTP,                            /* defport */
+  CURLPROTO_HTTPS,                      /* protocol */
+  PROTOPT_SSL | PROTOPT_STREAM          /* flags */
+};
+
+#ifdef DEBUG_QUICHE
+static void quiche_debug_log(const char *line, void *argp)
+{
+  (void)argp;
+  fprintf(stderr, "%s\n", line);
+}
+#endif
+
+CURLcode Curl_quic_connect(struct connectdata *conn, curl_socket_t sockfd,
+                           int sockindex,
+                           const struct sockaddr *addr, socklen_t addrlen)
+{
+  CURLcode result;
+  struct quicsocket *qs = &conn->hequic[sockindex];
+  struct Curl_easy *data = conn->data;
+  char *keylog_file = NULL;
+
+#ifdef DEBUG_QUICHE
+  /* initialize debug log callback only once */
+  static int debug_log_init = 0;
+  if(!debug_log_init) {
+    quiche_enable_debug_logging(quiche_debug_log, NULL);
+    debug_log_init = 1;
+  }
+#endif
+
+  (void)addr;
+  (void)addrlen;
+
+  qs->cfg = quiche_config_new(QUICHE_PROTOCOL_VERSION);
+  if(!qs->cfg) {
+    failf(data, "can't create quiche config");
+    return CURLE_FAILED_INIT;
+  }
+
+  quiche_config_set_max_idle_timeout(qs->cfg, QUIC_IDLE_TIMEOUT);
+  quiche_config_set_initial_max_data(qs->cfg, QUIC_MAX_DATA);
+  quiche_config_set_initial_max_stream_data_bidi_local(qs->cfg, QUIC_MAX_DATA);
+  quiche_config_set_initial_max_stream_data_bidi_remote(qs->cfg,
+                                                        QUIC_MAX_DATA);
+  quiche_config_set_initial_max_stream_data_uni(qs->cfg, QUIC_MAX_DATA);
+  quiche_config_set_initial_max_streams_bidi(qs->cfg, QUIC_MAX_STREAMS);
+  quiche_config_set_initial_max_streams_uni(qs->cfg, QUIC_MAX_STREAMS);
+  quiche_config_set_application_protos(qs->cfg,
+                                       (uint8_t *)
+                                       QUICHE_H3_APPLICATION_PROTOCOL,
+                                       sizeof(QUICHE_H3_APPLICATION_PROTOCOL)
+                                       - 1);
+
+  result = Curl_rand(data, qs->scid, sizeof(qs->scid));
+  if(result)
+    return result;
+
+  keylog_file = getenv("SSLKEYLOGFILE");
+
+  if(keylog_file)
+    quiche_config_log_keys(qs->cfg);
+
+  qs->conn = quiche_connect(conn->host.name, (const uint8_t *) qs->scid,
+                            sizeof(qs->scid), qs->cfg);
+  if(!qs->conn) {
+    failf(data, "can't create quiche connection");
+    return CURLE_OUT_OF_MEMORY;
+  }
+
+  if(keylog_file)
+    quiche_conn_set_keylog_path(qs->conn, keylog_file);
+
+  /* Known to not work on Windows */
+#if !defined(WIN32) && defined(HAVE_QUICHE_CONN_SET_QLOG_FD)
+  {
+    int qfd;
+    (void)Curl_qlogdir(data, qs->scid, sizeof(qs->scid), &qfd);
+    if(qfd != -1)
+      quiche_conn_set_qlog_fd(qs->conn, qfd,
+                              "qlog title", "curl qlog");
+  }
+#endif
+
+  result = flush_egress(conn, sockfd, qs);
+  if(result)
+    return result;
+
+  /* store the used address as a string */
+  if(!Curl_addr2string((struct sockaddr*)addr, addrlen,
+                       conn->primary_ip, &conn->primary_port)) {
+    char buffer[STRERROR_LEN];
+    failf(data, "ssrem inet_ntop() failed with errno %d: %s",
+          SOCKERRNO, Curl_strerror(SOCKERRNO, buffer, sizeof(buffer)));
+    return CURLE_BAD_FUNCTION_ARGUMENT;
+  }
+  memcpy(conn->ip_addr_str, conn->primary_ip, MAX_IPADR_LEN);
+  Curl_persistconninfo(conn);
+
+  /* for connection reuse purposes: */
+  conn->ssl[FIRSTSOCKET].state = ssl_connection_complete;
+
+  {
+    unsigned char alpn_protocols[] = QUICHE_H3_APPLICATION_PROTOCOL;
+    unsigned alpn_len, offset = 0;
+
+    /* Replace each ALPN length prefix by a comma. */
+    while(offset < sizeof(alpn_protocols) - 1) {
+      alpn_len = alpn_protocols[offset];
+      alpn_protocols[offset] = ',';
+      offset += 1 + alpn_len;
+    }
+
+    infof(data, "Sent QUIC client Initial, ALPN: %s\n",
+          alpn_protocols + 1);
+  }
+
+  return CURLE_OK;
+}
+
+static CURLcode quiche_has_connected(struct connectdata *conn,
+                                     int sockindex,
+                                     int tempindex)
+{
+  CURLcode result;
+  struct quicsocket *qs = conn->quic = &conn->hequic[tempindex];
+
+  conn->recv[sockindex] = h3_stream_recv;
+  conn->send[sockindex] = h3_stream_send;
+  conn->handler = &Curl_handler_http3;
+  conn->bits.multiplex = TRUE; /* at least potentially multiplexed */
+  conn->httpversion = 30;
+  conn->bundle->multiuse = BUNDLE_MULTIPLEX;
+
+  qs->h3config = quiche_h3_config_new();
+  if(!qs->h3config)
+    return CURLE_OUT_OF_MEMORY;
+
+  /* Create a new HTTP/3 connection on the QUIC connection. */
+  qs->h3c = quiche_h3_conn_new_with_transport(qs->conn, qs->h3config);
+  if(!qs->h3c) {
+    result = CURLE_OUT_OF_MEMORY;
+    goto fail;
+  }
+  if(conn->hequic[1-tempindex].cfg) {
+    qs = &conn->hequic[1-tempindex];
+    quiche_config_free(qs->cfg);
+    quiche_conn_free(qs->conn);
+    qs->cfg = NULL;
+    qs->conn = NULL;
+  }
+  return CURLE_OK;
+  fail:
+  quiche_h3_config_free(qs->h3config);
+  quiche_h3_conn_free(qs->h3c);
+  return result;
+}
+
+/*
+ * This function gets polled to check if this QUIC connection has connected.
+ */
+CURLcode Curl_quic_is_connected(struct connectdata *conn, int sockindex,
+                                bool *done)
+{
+  CURLcode result;
+  struct quicsocket *qs = &conn->hequic[sockindex];
+  curl_socket_t sockfd = conn->tempsock[sockindex];
+
+  result = process_ingress(conn, sockfd, qs);
+  if(result)
+    goto error;
+
+  result = flush_egress(conn, sockfd, qs);
+  if(result)
+    goto error;
+
+  if(quiche_conn_is_established(qs->conn)) {
+    *done = TRUE;
+    result = quiche_has_connected(conn, 0, sockindex);
+    DEBUGF(infof(conn->data, "quiche established connection!\n"));
+  }
+
+  return result;
+  error:
+  qs_disconnect(qs);
+  return result;
+}
+
+static CURLcode process_ingress(struct connectdata *conn, int sockfd,
+                                struct quicsocket *qs)
+{
+  ssize_t recvd;
+  struct Curl_easy *data = conn->data;
+  uint8_t *buf = (uint8_t *)data->state.buffer;
+  size_t bufsize = data->set.buffer_size;
+
+  /* in case the timeout expired */
+  quiche_conn_on_timeout(qs->conn);
+
+  do {
+    recvd = recv(sockfd, buf, bufsize, 0);
+    if((recvd < 0) && ((SOCKERRNO == EAGAIN) || (SOCKERRNO == EWOULDBLOCK)))
+      break;
+
+    if(recvd < 0) {
+      failf(conn->data, "quiche: recv() unexpectedly returned %d "
+            "(errno: %d, socket %d)", recvd, SOCKERRNO, sockfd);
+      return CURLE_RECV_ERROR;
+    }
+
+    recvd = quiche_conn_recv(qs->conn, buf, recvd);
+    if(recvd == QUICHE_ERR_DONE)
+      break;
+
+    if(recvd < 0) {
+      failf(conn->data, "quiche_conn_recv() == %d", recvd);
+      return CURLE_RECV_ERROR;
+    }
+  } while(1);
+
+  return CURLE_OK;
+}
+
+/*
+ * flush_egress drains the buffers and sends off data.
+ * Calls failf() on errors.
+ */
+static CURLcode flush_egress(struct connectdata *conn, int sockfd,
+                             struct quicsocket *qs)
+{
+  ssize_t sent;
+  static uint8_t out[1200];
+  int64_t timeout_ns;
+
+  do {
+    sent = quiche_conn_send(qs->conn, out, sizeof(out));
+    if(sent == QUICHE_ERR_DONE)
+      break;
+
+    if(sent < 0) {
+      failf(conn->data, "quiche_conn_send returned %zd\n",
+            sent);
+      return CURLE_SEND_ERROR;
+    }
+
+    sent = send(sockfd, out, sent, 0);
+    if(sent < 0) {
+      failf(conn->data, "send() returned %zd\n", sent);
+      return CURLE_SEND_ERROR;
+    }
+  } while(1);
+
+  /* time until the next timeout event, as nanoseconds. */
+  timeout_ns = quiche_conn_timeout_as_nanos(qs->conn);
+  if(timeout_ns)
+    /* expire uses milliseconds */
+    Curl_expire(conn->data, (timeout_ns + 999999) / 1000000, EXPIRE_QUIC);
+
+  return CURLE_OK;
+}
+
+struct h3h1header {
+  char *dest;
+  size_t destlen; /* left to use */
+  size_t nlen; /* used */
+};
+
+static int cb_each_header(uint8_t *name, size_t name_len,
+                          uint8_t *value, size_t value_len,
+                          void *argp)
+{
+  struct h3h1header *headers = (struct h3h1header *)argp;
+  size_t olen = 0;
+
+  if((name_len == 7) && !strncmp(":status", (char *)name, 7)) {
+    msnprintf(headers->dest,
+              headers->destlen, "HTTP/3 %.*s\n",
+              (int) value_len, value);
+  }
+  else if(!headers->nlen) {
+    return CURLE_HTTP3;
+  }
+  else {
+    msnprintf(headers->dest,
+              headers->destlen, "%.*s: %.*s\n",
+              (int)name_len, name, (int) value_len, value);
+  }
+  olen = strlen(headers->dest);
+  headers->destlen -= olen;
+  headers->nlen += olen;
+  headers->dest += olen;
+  return 0;
+}
+
+static ssize_t h3_stream_recv(struct connectdata *conn,
+                              int sockindex,
+                              char *buf,
+                              size_t buffersize,
+                              CURLcode *curlcode)
+{
+  ssize_t recvd = -1;
+  ssize_t rcode;
+  struct quicsocket *qs = conn->quic;
+  curl_socket_t sockfd = conn->sock[sockindex];
+  quiche_h3_event *ev;
+  int rc;
+  struct h3h1header headers;
+  struct Curl_easy *data = conn->data;
+  struct HTTP *stream = data->req.protop;
+  headers.dest = buf;
+  headers.destlen = buffersize;
+  headers.nlen = 0;
+
+  if(process_ingress(conn, sockfd, qs)) {
+    infof(data, "h3_stream_recv returns on ingress\n");
+    *curlcode = CURLE_RECV_ERROR;
+    return -1;
+  }
+
+  while(recvd < 0) {
+    int64_t s = quiche_h3_conn_poll(qs->h3c, qs->conn, &ev);
+    if(s < 0)
+      /* nothing more to do */
+      break;
+
+    if(s != stream->stream3_id) {
+      /* another transfer, ignore for now */
+      infof(data, "Got h3 for stream %u, expects %u\n",
+            s, stream->stream3_id);
+      continue;
+    }
+
+    switch(quiche_h3_event_type(ev)) {
+    case QUICHE_H3_EVENT_HEADERS:
+      rc = quiche_h3_event_for_each_header(ev, cb_each_header, &headers);
+      if(rc) {
+        *curlcode = rc;
+        failf(data, "Error in HTTP/3 response header");
+        break;
+      }
+      recvd = headers.nlen;
+      break;
+    case QUICHE_H3_EVENT_DATA:
+      if(!stream->firstbody) {
+        /* add a header-body separator CRLF */
+        buf[0] = '\r';
+        buf[1] = '\n';
+        buf += 2;
+        buffersize -= 2;
+        stream->firstbody = TRUE;
+        recvd = 2; /* two bytes already */
+      }
+      else
+        recvd = 0;
+      rcode = quiche_h3_recv_body(qs->h3c, qs->conn, s, (unsigned char *)buf,
+                                  buffersize);
+      if(rcode <= 0) {
+        recvd = -1;
+        break;
+      }
+      recvd += rcode;
+      break;
+
+    case QUICHE_H3_EVENT_FINISHED:
+      streamclose(conn, "End of stream");
+      recvd = 0; /* end of stream */
+      break;
+    default:
+      break;
+    }
+
+    quiche_h3_event_free(ev);
+  }
+  if(flush_egress(conn, sockfd, qs)) {
+    *curlcode = CURLE_SEND_ERROR;
+    return -1;
+  }
+
+  *curlcode = (-1 == recvd)? CURLE_AGAIN : CURLE_OK;
+  if(recvd >= 0)
+    /* Get this called again to drain the event queue */
+    Curl_expire(data, 0, EXPIRE_QUIC);
+
+  data->state.drain = (recvd >= 0) ? 1 : 0;
+  return recvd;
+}
+
+static ssize_t h3_stream_send(struct connectdata *conn,
+                              int sockindex,
+                              const void *mem,
+                              size_t len,
+                              CURLcode *curlcode)
+{
+  ssize_t sent;
+  struct quicsocket *qs = conn->quic;
+  curl_socket_t sockfd = conn->sock[sockindex];
+  struct HTTP *stream = conn->data->req.protop;
+
+  if(!stream->h3req) {
+    CURLcode result = http_request(conn, mem, len);
+    if(result) {
+      *curlcode = CURLE_SEND_ERROR;
+      return -1;
+    }
+    sent = len;
+  }
+  else {
+    H3BUGF(infof(conn->data, "Pass on %zd body bytes to quiche\n",
+                 len));
+    sent = quiche_h3_send_body(qs->h3c, qs->conn, stream->stream3_id,
+                               (uint8_t *)mem, len, FALSE);
+    if(sent < 0) {
+      *curlcode = CURLE_SEND_ERROR;
+      return -1;
+    }
+  }
+
+  if(flush_egress(conn, sockfd, qs)) {
+    *curlcode = CURLE_SEND_ERROR;
+    return -1;
+  }
+
+  *curlcode = CURLE_OK;
+  return sent;
+}
+
+/*
+ * Store quiche version info in this buffer, Prefix with a space.  Return total
+ * length written.
+ */
+int Curl_quic_ver(char *p, size_t len)
+{
+  return msnprintf(p, len, "quiche/%s", quiche_version());
+}
+
+/* Index where :authority header field will appear in request header
+   field list. */
+#define AUTHORITY_DST_IDX 3
+
+static CURLcode http_request(struct connectdata *conn, const void *mem,
+                             size_t len)
+{
+  /*
+   */
+  struct HTTP *stream = conn->data->req.protop;
+  size_t nheader;
+  size_t i;
+  size_t authority_idx;
+  char *hdbuf = (char *)mem;
+  char *end, *line_end;
+  int64_t stream3_id;
+  quiche_h3_header *nva = NULL;
+  struct quicsocket *qs = conn->quic;
+  CURLcode result = CURLE_OK;
+  struct Curl_easy *data = conn->data;
+
+  stream->h3req = TRUE; /* senf off! */
+
+  /* Calculate number of headers contained in [mem, mem + len). Assumes a
+     correctly generated HTTP header field block. */
+  nheader = 0;
+  for(i = 1; i < len; ++i) {
+    if(hdbuf[i] == '\n' && hdbuf[i - 1] == '\r') {
+      ++nheader;
+      ++i;
+    }
+  }
+  if(nheader < 2)
+    goto fail;
+
+  /* We counted additional 2 \r\n in the first and last line. We need 3
+     new headers: :method, :path and :scheme. Therefore we need one
+     more space. */
+  nheader += 1;
+  nva = malloc(sizeof(quiche_h3_header) * nheader);
+  if(!nva) {
+    result = CURLE_OUT_OF_MEMORY;
+    goto fail;
+  }
+
+  /* Extract :method, :path from request line
+     We do line endings with CRLF so checking for CR is enough */
+  line_end = memchr(hdbuf, '\r', len);
+  if(!line_end) {
+    result = CURLE_BAD_FUNCTION_ARGUMENT; /* internal error */
+    goto fail;
+  }
+
+  /* Method does not contain spaces */
+  end = memchr(hdbuf, ' ', line_end - hdbuf);
+  if(!end || end == hdbuf)
+    goto fail;
+  nva[0].name = (unsigned char *)":method";
+  nva[0].name_len = strlen((char *)nva[0].name);
+  nva[0].value = (unsigned char *)hdbuf;
+  nva[0].value_len = (size_t)(end - hdbuf);
+
+  hdbuf = end + 1;
+
+  /* Path may contain spaces so scan backwards */
+  end = NULL;
+  for(i = (size_t)(line_end - hdbuf); i; --i) {
+    if(hdbuf[i - 1] == ' ') {
+      end = &hdbuf[i - 1];
+      break;
+    }
+  }
+  if(!end || end == hdbuf)
+    goto fail;
+  nva[1].name = (unsigned char *)":path";
+  nva[1].name_len = strlen((char *)nva[1].name);
+  nva[1].value = (unsigned char *)hdbuf;
+  nva[1].value_len = (size_t)(end - hdbuf);
+
+  nva[2].name = (unsigned char *)":scheme";
+  nva[2].name_len = strlen((char *)nva[2].name);
+  if(conn->handler->flags & PROTOPT_SSL)
+    nva[2].value = (unsigned char *)"https";
+  else
+    nva[2].value = (unsigned char *)"http";
+  nva[2].value_len = strlen((char *)nva[2].value);
+
+
+  authority_idx = 0;
+  i = 3;
+  while(i < nheader) {
+    size_t hlen;
+
+    hdbuf = line_end + 2;
+
+    /* check for next CR, but only within the piece of data left in the given
+       buffer */
+    line_end = memchr(hdbuf, '\r', len - (hdbuf - (char *)mem));
+    if(!line_end || (line_end == hdbuf))
+      goto fail;
+
+    /* header continuation lines are not supported */
+    if(*hdbuf == ' ' || *hdbuf == '\t')
+      goto fail;
+
+    for(end = hdbuf; end < line_end && *end != ':'; ++end)
+      ;
+    if(end == hdbuf || end == line_end)
+      goto fail;
+    hlen = end - hdbuf;
+
+    if(hlen == 4 && strncasecompare("host", hdbuf, 4)) {
+      authority_idx = i;
+      nva[i].name = (unsigned char *)":authority";
+      nva[i].name_len = strlen((char *)nva[i].name);
+    }
+    else {
+      nva[i].name_len = (size_t)(end - hdbuf);
+      /* Lower case the header name for HTTP/3 */
+      Curl_strntolower((char *)hdbuf, hdbuf, nva[i].name_len);
+      nva[i].name = (unsigned char *)hdbuf;
+    }
+    hdbuf = end + 1;
+    while(*hdbuf == ' ' || *hdbuf == '\t')
+      ++hdbuf;
+    end = line_end;
+
+#if 0 /* This should probably go in more or less like this */
+    switch(inspect_header((const char *)nva[i].name, nva[i].namelen, hdbuf,
+                          end - hdbuf)) {
+    case HEADERINST_IGNORE:
+      /* skip header fields prohibited by HTTP/2 specification. */
+      --nheader;
+      continue;
+    case HEADERINST_TE_TRAILERS:
+      nva[i].value = (uint8_t*)"trailers";
+      nva[i].value_len = sizeof("trailers") - 1;
+      break;
+    default:
+      nva[i].value = (unsigned char *)hdbuf;
+      nva[i].value_len = (size_t)(end - hdbuf);
+    }
+#endif
+    nva[i].value = (unsigned char *)hdbuf;
+    nva[i].value_len = (size_t)(end - hdbuf);
+
+    ++i;
+  }
+
+  /* :authority must come before non-pseudo header fields */
+  if(authority_idx != 0 && authority_idx != AUTHORITY_DST_IDX) {
+    quiche_h3_header authority = nva[authority_idx];
+    for(i = authority_idx; i > AUTHORITY_DST_IDX; --i) {
+      nva[i] = nva[i - 1];
+    }
+    nva[i] = authority;
+  }
+
+  /* Warn stream may be rejected if cumulative length of headers is too
+     large. */
+#define MAX_ACC 60000  /* <64KB to account for some overhead */
+  {
+    size_t acc = 0;
+
+    for(i = 0; i < nheader; ++i) {
+      acc += nva[i].name_len + nva[i].value_len;
+
+      H3BUGF(infof(data, "h3 [%.*s: %.*s]\n",
+                   nva[i].name_len, nva[i].name,
+                   nva[i].value_len, nva[i].value));
+    }
+
+    if(acc > MAX_ACC) {
+      infof(data, "http_request: Warning: The cumulative length of all "
+            "headers exceeds %zu bytes and that could cause the "
+            "stream to be rejected.\n", MAX_ACC);
+    }
+  }
+
+  switch(data->state.httpreq) {
+  case HTTPREQ_POST:
+  case HTTPREQ_POST_FORM:
+  case HTTPREQ_POST_MIME:
+  case HTTPREQ_PUT:
+    if(data->state.infilesize != -1)
+      stream->upload_left = data->state.infilesize;
+    else
+      /* data sending without specifying the data amount up front */
+      stream->upload_left = -1; /* unknown, but not zero */
+
+    stream3_id = quiche_h3_send_request(qs->h3c, qs->conn, nva, nheader,
+                                        stream->upload_left ? FALSE: TRUE);
+    if((stream3_id >= 0) && data->set.postfields) {
+      ssize_t sent = quiche_h3_send_body(qs->h3c, qs->conn, stream3_id,
+                                         (uint8_t *)data->set.postfields,
+                                         stream->upload_left, TRUE);
+      if(sent <= 0) {
+        failf(data, "quiche_h3_send_body failed!");
+        result = CURLE_SEND_ERROR;
+      }
+      stream->upload_left = 0; /* nothing left to send */
+    }
+    break;
+  default:
+    stream3_id = quiche_h3_send_request(qs->h3c, qs->conn, nva, nheader,
+                                        TRUE);
+    break;
+  }
+
+  Curl_safefree(nva);
+
+  if(stream3_id < 0) {
+    H3BUGF(infof(data, "quiche_h3_send_request returned %d\n",
+                 stream3_id));
+    result = CURLE_SEND_ERROR;
+    goto fail;
+  }
+
+  infof(data, "Using HTTP/3 Stream ID: %x (easy handle %p)\n",
+        stream3_id, (void *)data);
+  stream->stream3_id = stream3_id;
+
+  return CURLE_OK;
+
+fail:
+  free(nva);
+  return result;
+}
+
+/*
+ * Called from transfer.c:done_sending when we stop HTTP/3 uploading.
+ */
+CURLcode Curl_quic_done_sending(struct connectdata *conn)
+{
+  if(conn->handler == &Curl_handler_http3) {
+    /* only for HTTP/3 transfers */
+    ssize_t sent;
+    struct HTTP *stream = conn->data->req.protop;
+    struct quicsocket *qs = conn->quic;
+    fprintf(stderr, "!!! Curl_quic_done_sending\n");
+    stream->upload_done = TRUE;
+    sent = quiche_h3_send_body(qs->h3c, qs->conn, stream->stream3_id,
+                               NULL, 0, TRUE);
+    if(sent < 0)
+      return CURLE_SEND_ERROR;
+  }
+
+  return CURLE_OK;
+}
+
+/*
+ * Called from http.c:Curl_http_done when a request completes.
+ */
+void Curl_quic_done(struct Curl_easy *data, bool premature)
+{
+  (void)data;
+  (void)premature;
+}
+
+/*
+ * Called from transfer.c:data_pending to know if we should keep looping
+ * to receive more data from the connection.
+ */
+bool Curl_quic_data_pending(const struct Curl_easy *data)
+{
+  (void)data;
+  return FALSE;
+}
+
+#endif
diff --git a/Utilities/cmcurl/lib/vquic/quiche.h b/Utilities/cmcurl/lib/vquic/quiche.h
new file mode 100644
index 0000000..c8d1837
--- /dev/null
+++ b/Utilities/cmcurl/lib/vquic/quiche.h
@@ -0,0 +1,49 @@
+#ifndef HEADER_CURL_VQUIC_QUICHE_H
+#define HEADER_CURL_VQUIC_QUICHE_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#ifdef USE_QUICHE
+
+#include <quiche.h>
+
+struct quic_handshake {
+  char *buf;       /* pointer to the buffer */
+  size_t alloclen; /* size of allocation */
+  size_t len;      /* size of content in buffer */
+  size_t nread;    /* how many bytes have been read */
+};
+
+struct quicsocket {
+  quiche_config *cfg;
+  quiche_conn *conn;
+  quiche_h3_conn *h3c;
+  quiche_h3_config *h3config;
+  uint8_t scid[QUICHE_MAX_CONN_ID_LEN];
+  uint32_t version;
+};
+
+#endif
+
+#endif /* HEADER_CURL_VQUIC_QUICHE_H */
diff --git a/Utilities/cmcurl/lib/vquic/vquic.c b/Utilities/cmcurl/lib/vquic/vquic.c
new file mode 100644
index 0000000..aae8e09
--- /dev/null
+++ b/Utilities/cmcurl/lib/vquic/vquic.c
@@ -0,0 +1,85 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#ifdef ENABLE_QUIC
+
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+#include "urldata.h"
+#include "dynbuf.h"
+#include "curl_printf.h"
+#include "vquic.h"
+
+#ifdef O_BINARY
+#define QLOGMODE O_WRONLY|O_CREAT|O_BINARY
+#else
+#define QLOGMODE O_WRONLY|O_CREAT
+#endif
+
+/*
+ * If the QLOGDIR environment variable is set, open and return a file
+ * descriptor to write the log to.
+ *
+ * This function returns error if something failed outside of failing to
+ * create the file. Open file success is deemed by seeing if the returned fd
+ * is != -1.
+ */
+CURLcode Curl_qlogdir(struct Curl_easy *data,
+                      unsigned char *scid,
+                      size_t scidlen,
+                      int *qlogfdp)
+{
+  const char *qlog_dir = getenv("QLOGDIR");
+  *qlogfdp = -1;
+  if(qlog_dir) {
+    struct dynbuf fname;
+    CURLcode result;
+    unsigned int i;
+    Curl_dyn_init(&fname, DYN_QLOG_NAME);
+    result = Curl_dyn_add(&fname, qlog_dir);
+    if(!result)
+      result = Curl_dyn_add(&fname, "/");
+    for(i = 0; (i < scidlen) && !result; i++) {
+      char hex[3];
+      msnprintf(hex, 3, "%02x", scid[i]);
+      result = Curl_dyn_add(&fname, hex);
+    }
+    if(!result)
+      result = Curl_dyn_add(&fname, ".qlog");
+
+    if(!result) {
+      int qlogfd = open(Curl_dyn_ptr(&fname), QLOGMODE,
+                        data->set.new_file_perms);
+      if(qlogfd != -1)
+        *qlogfdp = qlogfd;
+    }
+    Curl_dyn_free(&fname);
+    if(result)
+      return result;
+  }
+
+  return CURLE_OK;
+}
+#endif
diff --git a/Utilities/cmcurl/lib/vquic/vquic.h b/Utilities/cmcurl/lib/vquic/vquic.h
new file mode 100644
index 0000000..ecff0ed
--- /dev/null
+++ b/Utilities/cmcurl/lib/vquic/vquic.h
@@ -0,0 +1,34 @@
+#ifndef HEADER_CURL_VQUIC_QUIC_H
+#define HEADER_CURL_VQUIC_QUIC_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#ifdef ENABLE_QUIC
+CURLcode Curl_qlogdir(struct Curl_easy *data,
+                      unsigned char *scid,
+                      size_t scidlen,
+                      int *qlogfdp);
+#endif
+
+#endif /* HEADER_CURL_VQUIC_QUIC_H */
diff --git a/Utilities/cmcurl/lib/vssh/libssh.c b/Utilities/cmcurl/lib/vssh/libssh.c
new file mode 100644
index 0000000..8988e23
--- /dev/null
+++ b/Utilities/cmcurl/lib/vssh/libssh.c
@@ -0,0 +1,2891 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 2017 - 2020 Red Hat, Inc.
+ *
+ * Authors: Nikos Mavrogiannopoulos, Tomas Mraz, Stanislav Zidek,
+ *          Robert Kolcun, Andreas Schneider
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#ifdef USE_LIBSSH
+
+#include <limits.h>
+
+#include <libssh/libssh.h>
+#include <libssh/sftp.h>
+
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#ifdef HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+#ifdef HAVE_UTSNAME_H
+#include <sys/utsname.h>
+#endif
+#ifdef HAVE_NETDB_H
+#include <netdb.h>
+#endif
+#ifdef __VMS
+#include <in.h>
+#include <inet.h>
+#endif
+
+#if (defined(NETWARE) && defined(__NOVELL_LIBC__))
+#undef in_addr_t
+#define in_addr_t unsigned long
+#endif
+
+#include <curl/curl.h>
+#include "urldata.h"
+#include "sendf.h"
+#include "hostip.h"
+#include "progress.h"
+#include "transfer.h"
+#include "escape.h"
+#include "http.h"               /* for HTTP proxy tunnel stuff */
+#include "ssh.h"
+#include "url.h"
+#include "speedcheck.h"
+#include "getinfo.h"
+#include "strdup.h"
+#include "strcase.h"
+#include "vtls/vtls.h"
+#include "connect.h"
+#include "strerror.h"
+#include "inet_ntop.h"
+#include "parsedate.h"          /* for the week day and month names */
+#include "sockaddr.h"           /* required for Curl_sockaddr_storage */
+#include "strtoofft.h"
+#include "multiif.h"
+#include "select.h"
+#include "warnless.h"
+
+/* for permission and open flags */
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <fcntl.h>
+
+/* The last 3 #include files should be in this order */
+#include "curl_printf.h"
+#include "curl_memory.h"
+#include "memdebug.h"
+#include "curl_path.h"
+
+/* A recent macro provided by libssh. Or make our own. */
+#ifndef SSH_STRING_FREE_CHAR
+#define SSH_STRING_FREE_CHAR(x)                 \
+  do {                                          \
+    if(x) {                                     \
+      ssh_string_free_char(x);                  \
+      x = NULL;                                 \
+    }                                           \
+  } while(0)
+#endif
+
+/* Local functions: */
+static CURLcode myssh_connect(struct connectdata *conn, bool *done);
+static CURLcode myssh_multi_statemach(struct connectdata *conn,
+                                      bool *done);
+static CURLcode myssh_do_it(struct connectdata *conn, bool *done);
+
+static CURLcode scp_done(struct connectdata *conn,
+                         CURLcode, bool premature);
+static CURLcode scp_doing(struct connectdata *conn, bool *dophase_done);
+static CURLcode scp_disconnect(struct connectdata *conn,
+                               bool dead_connection);
+
+static CURLcode sftp_done(struct connectdata *conn,
+                          CURLcode, bool premature);
+static CURLcode sftp_doing(struct connectdata *conn,
+                           bool *dophase_done);
+static CURLcode sftp_disconnect(struct connectdata *conn, bool dead);
+static
+CURLcode sftp_perform(struct connectdata *conn,
+                      bool *connected,
+                      bool *dophase_done);
+
+static void sftp_quote(struct connectdata *conn);
+static void sftp_quote_stat(struct connectdata *conn);
+static int myssh_getsock(struct connectdata *conn, curl_socket_t *sock);
+static int myssh_perform_getsock(const struct connectdata *conn,
+                                 curl_socket_t *sock);
+
+static CURLcode myssh_setup_connection(struct connectdata *conn);
+
+/*
+ * SCP protocol handler.
+ */
+
+const struct Curl_handler Curl_handler_scp = {
+  "SCP",                        /* scheme */
+  myssh_setup_connection,       /* setup_connection */
+  myssh_do_it,                  /* do_it */
+  scp_done,                     /* done */
+  ZERO_NULL,                    /* do_more */
+  myssh_connect,                /* connect_it */
+  myssh_multi_statemach,        /* connecting */
+  scp_doing,                    /* doing */
+  myssh_getsock,                /* proto_getsock */
+  myssh_getsock,                /* doing_getsock */
+  ZERO_NULL,                    /* domore_getsock */
+  myssh_perform_getsock,        /* perform_getsock */
+  scp_disconnect,               /* disconnect */
+  ZERO_NULL,                    /* readwrite */
+  ZERO_NULL,                    /* connection_check */
+  PORT_SSH,                     /* defport */
+  CURLPROTO_SCP,                /* protocol */
+  PROTOPT_DIRLOCK | PROTOPT_CLOSEACTION | PROTOPT_NOURLQUERY    /* flags */
+};
+
+/*
+ * SFTP protocol handler.
+ */
+
+const struct Curl_handler Curl_handler_sftp = {
+  "SFTP",                               /* scheme */
+  myssh_setup_connection,               /* setup_connection */
+  myssh_do_it,                          /* do_it */
+  sftp_done,                            /* done */
+  ZERO_NULL,                            /* do_more */
+  myssh_connect,                        /* connect_it */
+  myssh_multi_statemach,                /* connecting */
+  sftp_doing,                           /* doing */
+  myssh_getsock,                        /* proto_getsock */
+  myssh_getsock,                        /* doing_getsock */
+  ZERO_NULL,                            /* domore_getsock */
+  myssh_perform_getsock,                /* perform_getsock */
+  sftp_disconnect,                      /* disconnect */
+  ZERO_NULL,                            /* readwrite */
+  ZERO_NULL,                            /* connection_check */
+  PORT_SSH,                             /* defport */
+  CURLPROTO_SFTP,                       /* protocol */
+  PROTOPT_DIRLOCK | PROTOPT_CLOSEACTION
+  | PROTOPT_NOURLQUERY                  /* flags */
+};
+
+static CURLcode sftp_error_to_CURLE(int err)
+{
+  switch(err) {
+    case SSH_FX_OK:
+      return CURLE_OK;
+
+    case SSH_FX_NO_SUCH_FILE:
+    case SSH_FX_NO_SUCH_PATH:
+      return CURLE_REMOTE_FILE_NOT_FOUND;
+
+    case SSH_FX_PERMISSION_DENIED:
+    case SSH_FX_WRITE_PROTECT:
+      return CURLE_REMOTE_ACCESS_DENIED;
+
+    case SSH_FX_FILE_ALREADY_EXISTS:
+      return CURLE_REMOTE_FILE_EXISTS;
+
+    default:
+      break;
+  }
+
+  return CURLE_SSH;
+}
+
+#ifndef DEBUGBUILD
+#define state(x,y) mystate(x,y)
+#else
+#define state(x,y) mystate(x,y, __LINE__)
+#endif
+
+/*
+ * SSH State machine related code
+ */
+/* This is the ONLY way to change SSH state! */
+static void mystate(struct connectdata *conn, sshstate nowstate
+#ifdef DEBUGBUILD
+                    , int lineno
+#endif
+  )
+{
+  struct ssh_conn *sshc = &conn->proto.sshc;
+#if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS)
+  /* for debug purposes */
+  static const char *const names[] = {
+    "SSH_STOP",
+    "SSH_INIT",
+    "SSH_S_STARTUP",
+    "SSH_HOSTKEY",
+    "SSH_AUTHLIST",
+    "SSH_AUTH_PKEY_INIT",
+    "SSH_AUTH_PKEY",
+    "SSH_AUTH_PASS_INIT",
+    "SSH_AUTH_PASS",
+    "SSH_AUTH_AGENT_INIT",
+    "SSH_AUTH_AGENT_LIST",
+    "SSH_AUTH_AGENT",
+    "SSH_AUTH_HOST_INIT",
+    "SSH_AUTH_HOST",
+    "SSH_AUTH_KEY_INIT",
+    "SSH_AUTH_KEY",
+    "SSH_AUTH_GSSAPI",
+    "SSH_AUTH_DONE",
+    "SSH_SFTP_INIT",
+    "SSH_SFTP_REALPATH",
+    "SSH_SFTP_QUOTE_INIT",
+    "SSH_SFTP_POSTQUOTE_INIT",
+    "SSH_SFTP_QUOTE",
+    "SSH_SFTP_NEXT_QUOTE",
+    "SSH_SFTP_QUOTE_STAT",
+    "SSH_SFTP_QUOTE_SETSTAT",
+    "SSH_SFTP_QUOTE_SYMLINK",
+    "SSH_SFTP_QUOTE_MKDIR",
+    "SSH_SFTP_QUOTE_RENAME",
+    "SSH_SFTP_QUOTE_RMDIR",
+    "SSH_SFTP_QUOTE_UNLINK",
+    "SSH_SFTP_QUOTE_STATVFS",
+    "SSH_SFTP_GETINFO",
+    "SSH_SFTP_FILETIME",
+    "SSH_SFTP_TRANS_INIT",
+    "SSH_SFTP_UPLOAD_INIT",
+    "SSH_SFTP_CREATE_DIRS_INIT",
+    "SSH_SFTP_CREATE_DIRS",
+    "SSH_SFTP_CREATE_DIRS_MKDIR",
+    "SSH_SFTP_READDIR_INIT",
+    "SSH_SFTP_READDIR",
+    "SSH_SFTP_READDIR_LINK",
+    "SSH_SFTP_READDIR_BOTTOM",
+    "SSH_SFTP_READDIR_DONE",
+    "SSH_SFTP_DOWNLOAD_INIT",
+    "SSH_SFTP_DOWNLOAD_STAT",
+    "SSH_SFTP_CLOSE",
+    "SSH_SFTP_SHUTDOWN",
+    "SSH_SCP_TRANS_INIT",
+    "SSH_SCP_UPLOAD_INIT",
+    "SSH_SCP_DOWNLOAD_INIT",
+    "SSH_SCP_DOWNLOAD",
+    "SSH_SCP_DONE",
+    "SSH_SCP_SEND_EOF",
+    "SSH_SCP_WAIT_EOF",
+    "SSH_SCP_WAIT_CLOSE",
+    "SSH_SCP_CHANNEL_FREE",
+    "SSH_SESSION_DISCONNECT",
+    "SSH_SESSION_FREE",
+    "QUIT"
+  };
+
+
+  if(sshc->state != nowstate) {
+    infof(conn->data, "SSH %p state change from %s to %s (line %d)\n",
+          (void *) sshc, names[sshc->state], names[nowstate],
+          lineno);
+  }
+#endif
+
+  sshc->state = nowstate;
+}
+
+/* Multiple options:
+ * 1. data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5] is set with an MD5
+ *    hash (90s style auth, not sure we should have it here)
+ * 2. data->set.ssh_keyfunc callback is set. Then we do trust on first
+ *    use. We even save on knownhosts if CURLKHSTAT_FINE_ADD_TO_FILE
+ *    is returned by it.
+ * 3. none of the above. We only accept if it is present on known hosts.
+ *
+ * Returns SSH_OK or SSH_ERROR.
+ */
+static int myssh_is_known(struct connectdata *conn)
+{
+  int rc;
+  struct Curl_easy *data = conn->data;
+  struct ssh_conn *sshc = &conn->proto.sshc;
+  ssh_key pubkey;
+  size_t hlen;
+  unsigned char *hash = NULL;
+  char *found_base64 = NULL;
+  char *known_base64 = NULL;
+  int vstate;
+  enum curl_khmatch keymatch;
+  struct curl_khkey foundkey;
+  struct curl_khkey *knownkeyp = NULL;
+  curl_sshkeycallback func =
+    data->set.ssh_keyfunc;
+
+#if LIBSSH_VERSION_INT >= SSH_VERSION_INT(0,9,0)
+  struct ssh_knownhosts_entry *knownhostsentry = NULL;
+  struct curl_khkey knownkey;
+#endif
+
+#if LIBSSH_VERSION_INT >= SSH_VERSION_INT(0,8,0)
+  rc = ssh_get_server_publickey(sshc->ssh_session, &pubkey);
+#else
+  rc = ssh_get_publickey(sshc->ssh_session, &pubkey);
+#endif
+  if(rc != SSH_OK)
+    return rc;
+
+  if(data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5]) {
+    int i;
+    char md5buffer[33];
+    const char *pubkey_md5 = data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5];
+
+    rc = ssh_get_publickey_hash(pubkey, SSH_PUBLICKEY_HASH_MD5,
+                                &hash, &hlen);
+    if(rc != SSH_OK || hlen != 16) {
+      failf(data,
+            "Denied establishing ssh session: md5 fingerprint not available");
+      goto cleanup;
+    }
+
+    for(i = 0; i < 16; i++)
+      msnprintf(&md5buffer[i*2], 3, "%02x", (unsigned char)hash[i]);
+
+    infof(data, "SSH MD5 fingerprint: %s\n", md5buffer);
+
+    if(!strcasecompare(md5buffer, pubkey_md5)) {
+      failf(data,
+            "Denied establishing ssh session: mismatch md5 fingerprint. "
+            "Remote %s is not equal to %s", md5buffer, pubkey_md5);
+      rc = SSH_ERROR;
+      goto cleanup;
+    }
+
+    rc = SSH_OK;
+    goto cleanup;
+  }
+
+  if(data->set.ssl.primary.verifyhost != TRUE) {
+    rc = SSH_OK;
+    goto cleanup;
+  }
+
+#if LIBSSH_VERSION_INT >= SSH_VERSION_INT(0,9,0)
+  /* Get the known_key from the known hosts file */
+  vstate = ssh_session_get_known_hosts_entry(sshc->ssh_session,
+                                             &knownhostsentry);
+
+  /* Case an entry was found in a known hosts file */
+  if(knownhostsentry) {
+    if(knownhostsentry->publickey) {
+      rc = ssh_pki_export_pubkey_base64(knownhostsentry->publickey,
+                                        &known_base64);
+      if(rc != SSH_OK) {
+        goto cleanup;
+      }
+      knownkey.key = known_base64;
+      knownkey.len = strlen(known_base64);
+
+      switch(ssh_key_type(knownhostsentry->publickey)) {
+        case SSH_KEYTYPE_RSA:
+          knownkey.keytype = CURLKHTYPE_RSA;
+          break;
+        case SSH_KEYTYPE_RSA1:
+          knownkey.keytype = CURLKHTYPE_RSA1;
+          break;
+        case SSH_KEYTYPE_ECDSA:
+        case SSH_KEYTYPE_ECDSA_P256:
+        case SSH_KEYTYPE_ECDSA_P384:
+        case SSH_KEYTYPE_ECDSA_P521:
+          knownkey.keytype = CURLKHTYPE_ECDSA;
+          break;
+        case SSH_KEYTYPE_ED25519:
+          knownkey.keytype = CURLKHTYPE_ED25519;
+          break;
+        case SSH_KEYTYPE_DSS:
+          knownkey.keytype = CURLKHTYPE_DSS;
+          break;
+        default:
+          rc = SSH_ERROR;
+          goto cleanup;
+      }
+      knownkeyp = &knownkey;
+    }
+  }
+
+  switch(vstate) {
+    case SSH_KNOWN_HOSTS_OK:
+      keymatch = CURLKHMATCH_OK;
+      break;
+    case SSH_KNOWN_HOSTS_OTHER:
+      /* fallthrough */
+    case SSH_KNOWN_HOSTS_NOT_FOUND:
+      /* fallthrough */
+    case SSH_KNOWN_HOSTS_UNKNOWN:
+      /* fallthrough */
+    case SSH_KNOWN_HOSTS_ERROR:
+      keymatch = CURLKHMATCH_MISSING;
+      break;
+  default:
+      keymatch = CURLKHMATCH_MISMATCH;
+      break;
+  }
+
+#else
+  vstate = ssh_is_server_known(sshc->ssh_session);
+  switch(vstate) {
+    case SSH_SERVER_KNOWN_OK:
+      keymatch = CURLKHMATCH_OK;
+      break;
+    case SSH_SERVER_FILE_NOT_FOUND:
+      /* fallthrough */
+    case SSH_SERVER_NOT_KNOWN:
+      keymatch = CURLKHMATCH_MISSING;
+      break;
+  default:
+      keymatch = CURLKHMATCH_MISMATCH;
+      break;
+  }
+#endif
+
+  if(func) { /* use callback to determine action */
+    rc = ssh_pki_export_pubkey_base64(pubkey, &found_base64);
+    if(rc != SSH_OK)
+      goto cleanup;
+
+    foundkey.key = found_base64;
+    foundkey.len = strlen(found_base64);
+
+    switch(ssh_key_type(pubkey)) {
+      case SSH_KEYTYPE_RSA:
+        foundkey.keytype = CURLKHTYPE_RSA;
+        break;
+      case SSH_KEYTYPE_RSA1:
+        foundkey.keytype = CURLKHTYPE_RSA1;
+        break;
+      case SSH_KEYTYPE_ECDSA:
+#if LIBSSH_VERSION_INT >= SSH_VERSION_INT(0,9,0)
+      case SSH_KEYTYPE_ECDSA_P256:
+      case SSH_KEYTYPE_ECDSA_P384:
+      case SSH_KEYTYPE_ECDSA_P521:
+#endif
+        foundkey.keytype = CURLKHTYPE_ECDSA;
+        break;
+#if LIBSSH_VERSION_INT >= SSH_VERSION_INT(0,7,0)
+      case SSH_KEYTYPE_ED25519:
+        foundkey.keytype = CURLKHTYPE_ED25519;
+        break;
+#endif
+      case SSH_KEYTYPE_DSS:
+        foundkey.keytype = CURLKHTYPE_DSS;
+        break;
+      default:
+        rc = SSH_ERROR;
+        goto cleanup;
+    }
+
+    Curl_set_in_callback(data, true);
+    rc = func(data, knownkeyp, /* from the knownhosts file */
+              &foundkey, /* from the remote host */
+              keymatch, data->set.ssh_keyfunc_userp);
+    Curl_set_in_callback(data, false);
+
+    switch(rc) {
+      case CURLKHSTAT_FINE_ADD_TO_FILE:
+#if LIBSSH_VERSION_INT >= SSH_VERSION_INT(0,8,0)
+        rc = ssh_session_update_known_hosts(sshc->ssh_session);
+#else
+        rc = ssh_write_knownhost(sshc->ssh_session);
+#endif
+        if(rc != SSH_OK) {
+          goto cleanup;
+        }
+        break;
+      case CURLKHSTAT_FINE:
+        break;
+      default: /* REJECT/DEFER */
+        rc = SSH_ERROR;
+        goto cleanup;
+    }
+  }
+  else {
+    if(keymatch != CURLKHMATCH_OK) {
+      rc = SSH_ERROR;
+      goto cleanup;
+    }
+  }
+  rc = SSH_OK;
+
+cleanup:
+  if(found_base64) {
+    free(found_base64);
+  }
+  if(known_base64) {
+    free(known_base64);
+  }
+  if(hash)
+    ssh_clean_pubkey_hash(&hash);
+  ssh_key_free(pubkey);
+#if LIBSSH_VERSION_INT >= SSH_VERSION_INT(0,9,0)
+  if(knownhostsentry) {
+    ssh_knownhosts_entry_free(knownhostsentry);
+  }
+#endif
+  return rc;
+}
+
+#define MOVE_TO_ERROR_STATE(_r) { \
+  state(conn, SSH_SESSION_DISCONNECT); \
+  sshc->actualcode = _r; \
+  rc = SSH_ERROR; \
+  break; \
+}
+
+#define MOVE_TO_SFTP_CLOSE_STATE() { \
+  state(conn, SSH_SFTP_CLOSE); \
+  sshc->actualcode = sftp_error_to_CURLE(sftp_get_error(sshc->sftp_session)); \
+  rc = SSH_ERROR; \
+  break; \
+}
+
+#define MOVE_TO_LAST_AUTH \
+  if(sshc->auth_methods & SSH_AUTH_METHOD_PASSWORD) { \
+    rc = SSH_OK; \
+    state(conn, SSH_AUTH_PASS_INIT); \
+    break; \
+  } \
+  else { \
+    MOVE_TO_ERROR_STATE(CURLE_LOGIN_DENIED); \
+  }
+
+#define MOVE_TO_TERTIARY_AUTH \
+  if(sshc->auth_methods & SSH_AUTH_METHOD_INTERACTIVE) { \
+    rc = SSH_OK; \
+    state(conn, SSH_AUTH_KEY_INIT); \
+    break; \
+  } \
+  else { \
+    MOVE_TO_LAST_AUTH; \
+  }
+
+#define MOVE_TO_SECONDARY_AUTH \
+  if(sshc->auth_methods & SSH_AUTH_METHOD_GSSAPI_MIC) { \
+    rc = SSH_OK; \
+    state(conn, SSH_AUTH_GSSAPI); \
+    break; \
+  } \
+  else { \
+    MOVE_TO_TERTIARY_AUTH; \
+  }
+
+static
+int myssh_auth_interactive(struct connectdata *conn)
+{
+  int rc;
+  struct ssh_conn *sshc = &conn->proto.sshc;
+  int nprompts;
+
+restart:
+  switch(sshc->kbd_state) {
+    case 0:
+      rc = ssh_userauth_kbdint(sshc->ssh_session, NULL, NULL);
+      if(rc == SSH_AUTH_AGAIN)
+        return SSH_AGAIN;
+
+      if(rc != SSH_AUTH_INFO)
+        return SSH_ERROR;
+
+      nprompts = ssh_userauth_kbdint_getnprompts(sshc->ssh_session);
+      if(nprompts != 1)
+        return SSH_ERROR;
+
+      rc = ssh_userauth_kbdint_setanswer(sshc->ssh_session, 0, conn->passwd);
+      if(rc < 0)
+        return SSH_ERROR;
+
+    /* FALLTHROUGH */
+    case 1:
+      sshc->kbd_state = 1;
+
+      rc = ssh_userauth_kbdint(sshc->ssh_session, NULL, NULL);
+      if(rc == SSH_AUTH_AGAIN)
+        return SSH_AGAIN;
+      else if(rc == SSH_AUTH_SUCCESS)
+        rc = SSH_OK;
+      else if(rc == SSH_AUTH_INFO) {
+        nprompts = ssh_userauth_kbdint_getnprompts(sshc->ssh_session);
+        if(nprompts != 0)
+          return SSH_ERROR;
+
+        sshc->kbd_state = 2;
+        goto restart;
+      }
+      else
+        rc = SSH_ERROR;
+      break;
+    case 2:
+      sshc->kbd_state = 2;
+
+      rc = ssh_userauth_kbdint(sshc->ssh_session, NULL, NULL);
+      if(rc == SSH_AUTH_AGAIN)
+        return SSH_AGAIN;
+      else if(rc == SSH_AUTH_SUCCESS)
+        rc = SSH_OK;
+      else
+        rc = SSH_ERROR;
+
+      break;
+    default:
+      return SSH_ERROR;
+  }
+
+  sshc->kbd_state = 0;
+  return rc;
+}
+
+/*
+ * ssh_statemach_act() runs the SSH state machine as far as it can without
+ * blocking and without reaching the end.  The data the pointer 'block' points
+ * to will be set to TRUE if the libssh function returns SSH_AGAIN
+ * meaning it wants to be called again when the socket is ready
+ */
+static CURLcode myssh_statemach_act(struct connectdata *conn, bool *block)
+{
+  CURLcode result = CURLE_OK;
+  struct Curl_easy *data = conn->data;
+  struct SSHPROTO *protop = data->req.protop;
+  struct ssh_conn *sshc = &conn->proto.sshc;
+  curl_socket_t sock = conn->sock[FIRSTSOCKET];
+  int rc = SSH_NO_ERROR, err;
+  char *new_readdir_line;
+  int seekerr = CURL_SEEKFUNC_OK;
+  const char *err_msg;
+  *block = 0;                   /* we're not blocking by default */
+
+  do {
+
+    switch(sshc->state) {
+    case SSH_INIT:
+      sshc->secondCreateDirs = 0;
+      sshc->nextstate = SSH_NO_STATE;
+      sshc->actualcode = CURLE_OK;
+
+#if 0
+      ssh_set_log_level(SSH_LOG_PROTOCOL);
+#endif
+
+      /* Set libssh to non-blocking, since everything internally is
+         non-blocking */
+      ssh_set_blocking(sshc->ssh_session, 0);
+
+      state(conn, SSH_S_STARTUP);
+      /* FALLTHROUGH */
+
+    case SSH_S_STARTUP:
+      rc = ssh_connect(sshc->ssh_session);
+      if(rc == SSH_AGAIN)
+        break;
+
+      if(rc != SSH_OK) {
+        failf(data, "Failure establishing ssh session");
+        MOVE_TO_ERROR_STATE(CURLE_FAILED_INIT);
+      }
+
+      state(conn, SSH_HOSTKEY);
+
+      /* FALLTHROUGH */
+    case SSH_HOSTKEY:
+
+      rc = myssh_is_known(conn);
+      if(rc != SSH_OK) {
+        MOVE_TO_ERROR_STATE(CURLE_PEER_FAILED_VERIFICATION);
+      }
+
+      state(conn, SSH_AUTHLIST);
+      /* FALLTHROUGH */
+    case SSH_AUTHLIST:{
+        sshc->authed = FALSE;
+
+        rc = ssh_userauth_none(sshc->ssh_session, NULL);
+        if(rc == SSH_AUTH_AGAIN) {
+          rc = SSH_AGAIN;
+          break;
+        }
+
+        if(rc == SSH_AUTH_SUCCESS) {
+          sshc->authed = TRUE;
+          infof(data, "Authenticated with none\n");
+          state(conn, SSH_AUTH_DONE);
+          break;
+        }
+        else if(rc == SSH_AUTH_ERROR) {
+          MOVE_TO_ERROR_STATE(CURLE_LOGIN_DENIED);
+        }
+
+        sshc->auth_methods = ssh_userauth_list(sshc->ssh_session, NULL);
+        if(sshc->auth_methods & SSH_AUTH_METHOD_PUBLICKEY) {
+          state(conn, SSH_AUTH_PKEY_INIT);
+          infof(data, "Authentication using SSH public key file\n");
+        }
+        else if(sshc->auth_methods & SSH_AUTH_METHOD_GSSAPI_MIC) {
+          state(conn, SSH_AUTH_GSSAPI);
+        }
+        else if(sshc->auth_methods & SSH_AUTH_METHOD_INTERACTIVE) {
+          state(conn, SSH_AUTH_KEY_INIT);
+        }
+        else if(sshc->auth_methods & SSH_AUTH_METHOD_PASSWORD) {
+          state(conn, SSH_AUTH_PASS_INIT);
+        }
+        else {                  /* unsupported authentication method */
+          MOVE_TO_ERROR_STATE(CURLE_LOGIN_DENIED);
+        }
+
+        break;
+      }
+    case SSH_AUTH_PKEY_INIT:
+      if(!(data->set.ssh_auth_types & CURLSSH_AUTH_PUBLICKEY)) {
+        MOVE_TO_SECONDARY_AUTH;
+      }
+
+      /* Two choices, (1) private key was given on CMD,
+       * (2) use the "default" keys. */
+      if(data->set.str[STRING_SSH_PRIVATE_KEY]) {
+        if(sshc->pubkey && !data->set.ssl.key_passwd) {
+          rc = ssh_userauth_try_publickey(sshc->ssh_session, NULL,
+                                          sshc->pubkey);
+          if(rc == SSH_AUTH_AGAIN) {
+            rc = SSH_AGAIN;
+            break;
+          }
+
+          if(rc != SSH_OK) {
+            MOVE_TO_SECONDARY_AUTH;
+          }
+        }
+
+        rc = ssh_pki_import_privkey_file(data->
+                                         set.str[STRING_SSH_PRIVATE_KEY],
+                                         data->set.ssl.key_passwd, NULL,
+                                         NULL, &sshc->privkey);
+        if(rc != SSH_OK) {
+          failf(data, "Could not load private key file %s",
+                data->set.str[STRING_SSH_PRIVATE_KEY]);
+          MOVE_TO_ERROR_STATE(CURLE_LOGIN_DENIED);
+          break;
+        }
+
+        state(conn, SSH_AUTH_PKEY);
+        break;
+
+      }
+      else {
+        rc = ssh_userauth_publickey_auto(sshc->ssh_session, NULL,
+                                         data->set.ssl.key_passwd);
+        if(rc == SSH_AUTH_AGAIN) {
+          rc = SSH_AGAIN;
+          break;
+        }
+        if(rc == SSH_AUTH_SUCCESS) {
+          rc = SSH_OK;
+          sshc->authed = TRUE;
+          infof(data, "Completed public key authentication\n");
+          state(conn, SSH_AUTH_DONE);
+          break;
+        }
+
+        MOVE_TO_SECONDARY_AUTH;
+      }
+      break;
+    case SSH_AUTH_PKEY:
+      rc = ssh_userauth_publickey(sshc->ssh_session, NULL, sshc->privkey);
+      if(rc == SSH_AUTH_AGAIN) {
+        rc = SSH_AGAIN;
+        break;
+      }
+
+      if(rc == SSH_AUTH_SUCCESS) {
+        sshc->authed = TRUE;
+        infof(data, "Completed public key authentication\n");
+        state(conn, SSH_AUTH_DONE);
+        break;
+      }
+      else {
+        infof(data, "Failed public key authentication (rc: %d)\n", rc);
+        MOVE_TO_SECONDARY_AUTH;
+      }
+      break;
+
+    case SSH_AUTH_GSSAPI:
+      if(!(data->set.ssh_auth_types & CURLSSH_AUTH_GSSAPI)) {
+        MOVE_TO_TERTIARY_AUTH;
+      }
+
+      rc = ssh_userauth_gssapi(sshc->ssh_session);
+      if(rc == SSH_AUTH_AGAIN) {
+        rc = SSH_AGAIN;
+        break;
+      }
+
+      if(rc == SSH_AUTH_SUCCESS) {
+        rc = SSH_OK;
+        sshc->authed = TRUE;
+        infof(data, "Completed gssapi authentication\n");
+        state(conn, SSH_AUTH_DONE);
+        break;
+      }
+
+      MOVE_TO_TERTIARY_AUTH;
+      break;
+
+    case SSH_AUTH_KEY_INIT:
+      if(data->set.ssh_auth_types & CURLSSH_AUTH_KEYBOARD) {
+        state(conn, SSH_AUTH_KEY);
+      }
+      else {
+        MOVE_TO_LAST_AUTH;
+      }
+      break;
+
+    case SSH_AUTH_KEY:
+
+      /* Authentication failed. Continue with keyboard-interactive now. */
+      rc = myssh_auth_interactive(conn);
+      if(rc == SSH_AGAIN) {
+        break;
+      }
+      if(rc == SSH_OK) {
+        sshc->authed = TRUE;
+        infof(data, "completed keyboard interactive authentication\n");
+      }
+      state(conn, SSH_AUTH_DONE);
+      break;
+
+    case SSH_AUTH_PASS_INIT:
+      if(!(data->set.ssh_auth_types & CURLSSH_AUTH_PASSWORD)) {
+        /* Host key authentication is intentionally not implemented */
+        MOVE_TO_ERROR_STATE(CURLE_LOGIN_DENIED);
+      }
+      state(conn, SSH_AUTH_PASS);
+      /* FALLTHROUGH */
+
+    case SSH_AUTH_PASS:
+      rc = ssh_userauth_password(sshc->ssh_session, NULL, conn->passwd);
+      if(rc == SSH_AUTH_AGAIN) {
+        rc = SSH_AGAIN;
+        break;
+      }
+
+      if(rc == SSH_AUTH_SUCCESS) {
+        sshc->authed = TRUE;
+        infof(data, "Completed password authentication\n");
+        state(conn, SSH_AUTH_DONE);
+      }
+      else {
+        MOVE_TO_ERROR_STATE(CURLE_LOGIN_DENIED);
+      }
+      break;
+
+    case SSH_AUTH_DONE:
+      if(!sshc->authed) {
+        failf(data, "Authentication failure");
+        MOVE_TO_ERROR_STATE(CURLE_LOGIN_DENIED);
+        break;
+      }
+
+      /*
+       * At this point we have an authenticated ssh session.
+       */
+      infof(data, "Authentication complete\n");
+
+      Curl_pgrsTime(conn->data, TIMER_APPCONNECT);      /* SSH is connected */
+
+      conn->sockfd = sock;
+      conn->writesockfd = CURL_SOCKET_BAD;
+
+      if(conn->handler->protocol == CURLPROTO_SFTP) {
+        state(conn, SSH_SFTP_INIT);
+        break;
+      }
+      infof(data, "SSH CONNECT phase done\n");
+      state(conn, SSH_STOP);
+      break;
+
+    case SSH_SFTP_INIT:
+      ssh_set_blocking(sshc->ssh_session, 1);
+
+      sshc->sftp_session = sftp_new(sshc->ssh_session);
+      if(!sshc->sftp_session) {
+        failf(data, "Failure initializing sftp session: %s",
+              ssh_get_error(sshc->ssh_session));
+        MOVE_TO_ERROR_STATE(CURLE_COULDNT_CONNECT);
+        break;
+      }
+
+      rc = sftp_init(sshc->sftp_session);
+      if(rc != SSH_OK) {
+        rc = sftp_get_error(sshc->sftp_session);
+        failf(data, "Failure initializing sftp session: %s",
+              ssh_get_error(sshc->ssh_session));
+        MOVE_TO_ERROR_STATE(sftp_error_to_CURLE(rc));
+        break;
+      }
+      state(conn, SSH_SFTP_REALPATH);
+      /* FALLTHROUGH */
+    case SSH_SFTP_REALPATH:
+      /*
+       * Get the "home" directory
+       */
+      sshc->homedir = sftp_canonicalize_path(sshc->sftp_session, ".");
+      if(sshc->homedir == NULL) {
+        MOVE_TO_ERROR_STATE(CURLE_COULDNT_CONNECT);
+      }
+      conn->data->state.most_recent_ftp_entrypath = sshc->homedir;
+
+      /* This is the last step in the SFTP connect phase. Do note that while
+         we get the homedir here, we get the "workingpath" in the DO action
+         since the homedir will remain the same between request but the
+         working path will not. */
+      DEBUGF(infof(data, "SSH CONNECT phase done\n"));
+      state(conn, SSH_STOP);
+      break;
+
+    case SSH_SFTP_QUOTE_INIT:
+
+      result = Curl_getworkingpath(conn, sshc->homedir, &protop->path);
+      if(result) {
+        sshc->actualcode = result;
+        state(conn, SSH_STOP);
+        break;
+      }
+
+      if(data->set.quote) {
+        infof(data, "Sending quote commands\n");
+        sshc->quote_item = data->set.quote;
+        state(conn, SSH_SFTP_QUOTE);
+      }
+      else {
+        state(conn, SSH_SFTP_GETINFO);
+      }
+      break;
+
+    case SSH_SFTP_POSTQUOTE_INIT:
+      if(data->set.postquote) {
+        infof(data, "Sending quote commands\n");
+        sshc->quote_item = data->set.postquote;
+        state(conn, SSH_SFTP_QUOTE);
+      }
+      else {
+        state(conn, SSH_STOP);
+      }
+      break;
+
+    case SSH_SFTP_QUOTE:
+      /* Send any quote commands */
+      sftp_quote(conn);
+      break;
+
+    case SSH_SFTP_NEXT_QUOTE:
+      Curl_safefree(sshc->quote_path1);
+      Curl_safefree(sshc->quote_path2);
+
+      sshc->quote_item = sshc->quote_item->next;
+
+      if(sshc->quote_item) {
+        state(conn, SSH_SFTP_QUOTE);
+      }
+      else {
+        if(sshc->nextstate != SSH_NO_STATE) {
+          state(conn, sshc->nextstate);
+          sshc->nextstate = SSH_NO_STATE;
+        }
+        else {
+          state(conn, SSH_SFTP_GETINFO);
+        }
+      }
+      break;
+
+    case SSH_SFTP_QUOTE_STAT:
+      sftp_quote_stat(conn);
+      break;
+
+    case SSH_SFTP_QUOTE_SETSTAT:
+      rc = sftp_setstat(sshc->sftp_session, sshc->quote_path2,
+                        sshc->quote_attrs);
+      if(rc != 0 && !sshc->acceptfail) {
+        Curl_safefree(sshc->quote_path1);
+        Curl_safefree(sshc->quote_path2);
+        failf(data, "Attempt to set SFTP stats failed: %s",
+              ssh_get_error(sshc->ssh_session));
+        state(conn, SSH_SFTP_CLOSE);
+        sshc->nextstate = SSH_NO_STATE;
+        sshc->actualcode = CURLE_QUOTE_ERROR;
+        /* sshc->actualcode = sftp_error_to_CURLE(err);
+         * we do not send the actual error; we return
+         * the error the libssh2 backend is returning */
+        break;
+      }
+      state(conn, SSH_SFTP_NEXT_QUOTE);
+      break;
+
+    case SSH_SFTP_QUOTE_SYMLINK:
+      rc = sftp_symlink(sshc->sftp_session, sshc->quote_path2,
+                        sshc->quote_path1);
+      if(rc != 0 && !sshc->acceptfail) {
+        Curl_safefree(sshc->quote_path1);
+        Curl_safefree(sshc->quote_path2);
+        failf(data, "symlink command failed: %s",
+              ssh_get_error(sshc->ssh_session));
+        state(conn, SSH_SFTP_CLOSE);
+        sshc->nextstate = SSH_NO_STATE;
+        sshc->actualcode = CURLE_QUOTE_ERROR;
+        break;
+      }
+      state(conn, SSH_SFTP_NEXT_QUOTE);
+      break;
+
+    case SSH_SFTP_QUOTE_MKDIR:
+      rc = sftp_mkdir(sshc->sftp_session, sshc->quote_path1,
+                      (mode_t)data->set.new_directory_perms);
+      if(rc != 0 && !sshc->acceptfail) {
+        Curl_safefree(sshc->quote_path1);
+        failf(data, "mkdir command failed: %s",
+              ssh_get_error(sshc->ssh_session));
+        state(conn, SSH_SFTP_CLOSE);
+        sshc->nextstate = SSH_NO_STATE;
+        sshc->actualcode = CURLE_QUOTE_ERROR;
+        break;
+      }
+      state(conn, SSH_SFTP_NEXT_QUOTE);
+      break;
+
+    case SSH_SFTP_QUOTE_RENAME:
+      rc = sftp_rename(sshc->sftp_session, sshc->quote_path1,
+                       sshc->quote_path2);
+      if(rc != 0 && !sshc->acceptfail) {
+        Curl_safefree(sshc->quote_path1);
+        Curl_safefree(sshc->quote_path2);
+        failf(data, "rename command failed: %s",
+              ssh_get_error(sshc->ssh_session));
+        state(conn, SSH_SFTP_CLOSE);
+        sshc->nextstate = SSH_NO_STATE;
+        sshc->actualcode = CURLE_QUOTE_ERROR;
+        break;
+      }
+      state(conn, SSH_SFTP_NEXT_QUOTE);
+      break;
+
+    case SSH_SFTP_QUOTE_RMDIR:
+      rc = sftp_rmdir(sshc->sftp_session, sshc->quote_path1);
+      if(rc != 0 && !sshc->acceptfail) {
+        Curl_safefree(sshc->quote_path1);
+        failf(data, "rmdir command failed: %s",
+              ssh_get_error(sshc->ssh_session));
+        state(conn, SSH_SFTP_CLOSE);
+        sshc->nextstate = SSH_NO_STATE;
+        sshc->actualcode = CURLE_QUOTE_ERROR;
+        break;
+      }
+      state(conn, SSH_SFTP_NEXT_QUOTE);
+      break;
+
+    case SSH_SFTP_QUOTE_UNLINK:
+      rc = sftp_unlink(sshc->sftp_session, sshc->quote_path1);
+      if(rc != 0 && !sshc->acceptfail) {
+        Curl_safefree(sshc->quote_path1);
+        failf(data, "rm command failed: %s",
+              ssh_get_error(sshc->ssh_session));
+        state(conn, SSH_SFTP_CLOSE);
+        sshc->nextstate = SSH_NO_STATE;
+        sshc->actualcode = CURLE_QUOTE_ERROR;
+        break;
+      }
+      state(conn, SSH_SFTP_NEXT_QUOTE);
+      break;
+
+    case SSH_SFTP_QUOTE_STATVFS:
+    {
+      sftp_statvfs_t statvfs;
+
+      statvfs = sftp_statvfs(sshc->sftp_session, sshc->quote_path1);
+      if(!statvfs && !sshc->acceptfail) {
+        Curl_safefree(sshc->quote_path1);
+        failf(data, "statvfs command failed: %s",
+              ssh_get_error(sshc->ssh_session));
+        state(conn, SSH_SFTP_CLOSE);
+        sshc->nextstate = SSH_NO_STATE;
+        sshc->actualcode = CURLE_QUOTE_ERROR;
+        break;
+      }
+      else if(statvfs) {
+        char *tmp = aprintf("statvfs:\n"
+                            "f_bsize: %llu\n" "f_frsize: %llu\n"
+                            "f_blocks: %llu\n" "f_bfree: %llu\n"
+                            "f_bavail: %llu\n" "f_files: %llu\n"
+                            "f_ffree: %llu\n" "f_favail: %llu\n"
+                            "f_fsid: %llu\n" "f_flag: %llu\n"
+                            "f_namemax: %llu\n",
+                            statvfs->f_bsize, statvfs->f_frsize,
+                            statvfs->f_blocks, statvfs->f_bfree,
+                            statvfs->f_bavail, statvfs->f_files,
+                            statvfs->f_ffree, statvfs->f_favail,
+                            statvfs->f_fsid, statvfs->f_flag,
+                            statvfs->f_namemax);
+        sftp_statvfs_free(statvfs);
+
+        if(!tmp) {
+          result = CURLE_OUT_OF_MEMORY;
+          state(conn, SSH_SFTP_CLOSE);
+          sshc->nextstate = SSH_NO_STATE;
+          break;
+        }
+
+        result = Curl_client_write(conn, CLIENTWRITE_HEADER, tmp, strlen(tmp));
+        free(tmp);
+        if(result) {
+          state(conn, SSH_SFTP_CLOSE);
+          sshc->nextstate = SSH_NO_STATE;
+          sshc->actualcode = result;
+        }
+      }
+      state(conn, SSH_SFTP_NEXT_QUOTE);
+      break;
+    }
+
+    case SSH_SFTP_GETINFO:
+      if(data->set.get_filetime) {
+        state(conn, SSH_SFTP_FILETIME);
+      }
+      else {
+        state(conn, SSH_SFTP_TRANS_INIT);
+      }
+      break;
+
+    case SSH_SFTP_FILETIME:
+    {
+      sftp_attributes attrs;
+
+      attrs = sftp_stat(sshc->sftp_session, protop->path);
+      if(attrs != 0) {
+        data->info.filetime = attrs->mtime;
+        sftp_attributes_free(attrs);
+      }
+
+      state(conn, SSH_SFTP_TRANS_INIT);
+      break;
+    }
+
+    case SSH_SFTP_TRANS_INIT:
+      if(data->set.upload)
+        state(conn, SSH_SFTP_UPLOAD_INIT);
+      else {
+        if(protop->path[strlen(protop->path)-1] == '/')
+          state(conn, SSH_SFTP_READDIR_INIT);
+        else
+          state(conn, SSH_SFTP_DOWNLOAD_INIT);
+      }
+      break;
+
+    case SSH_SFTP_UPLOAD_INIT:
+    {
+      int flags;
+
+      if(data->state.resume_from != 0) {
+        sftp_attributes attrs;
+
+        if(data->state.resume_from < 0) {
+          attrs = sftp_stat(sshc->sftp_session, protop->path);
+          if(attrs != 0) {
+            curl_off_t size = attrs->size;
+            if(size < 0) {
+              failf(data, "Bad file size (%" CURL_FORMAT_CURL_OFF_T ")", size);
+              MOVE_TO_ERROR_STATE(CURLE_BAD_DOWNLOAD_RESUME);
+            }
+            data->state.resume_from = attrs->size;
+
+            sftp_attributes_free(attrs);
+          }
+          else {
+            data->state.resume_from = 0;
+          }
+        }
+      }
+
+      if(data->set.ftp_append)
+        /* Try to open for append, but create if nonexisting */
+        flags = O_WRONLY|O_CREAT|O_APPEND;
+      else if(data->state.resume_from > 0)
+        /* If we have restart position then open for append */
+        flags = O_WRONLY|O_APPEND;
+      else
+        /* Clear file before writing (normal behaviour) */
+        flags = O_WRONLY|O_CREAT|O_TRUNC;
+
+      if(sshc->sftp_file)
+        sftp_close(sshc->sftp_file);
+      sshc->sftp_file =
+        sftp_open(sshc->sftp_session, protop->path,
+                  flags, (mode_t)data->set.new_file_perms);
+      if(!sshc->sftp_file) {
+        err = sftp_get_error(sshc->sftp_session);
+
+        if(((err == SSH_FX_NO_SUCH_FILE || err == SSH_FX_FAILURE ||
+             err == SSH_FX_NO_SUCH_PATH)) &&
+             (data->set.ftp_create_missing_dirs &&
+             (strlen(protop->path) > 1))) {
+               /* try to create the path remotely */
+               rc = 0;
+               sshc->secondCreateDirs = 1;
+               state(conn, SSH_SFTP_CREATE_DIRS_INIT);
+               break;
+        }
+        else {
+          MOVE_TO_SFTP_CLOSE_STATE();
+        }
+      }
+
+      /* If we have a restart point then we need to seek to the correct
+         position. */
+      if(data->state.resume_from > 0) {
+        /* Let's read off the proper amount of bytes from the input. */
+        if(conn->seek_func) {
+          Curl_set_in_callback(data, true);
+          seekerr = conn->seek_func(conn->seek_client, data->state.resume_from,
+                                    SEEK_SET);
+          Curl_set_in_callback(data, false);
+        }
+
+        if(seekerr != CURL_SEEKFUNC_OK) {
+          curl_off_t passed = 0;
+
+          if(seekerr != CURL_SEEKFUNC_CANTSEEK) {
+            failf(data, "Could not seek stream");
+            return CURLE_FTP_COULDNT_USE_REST;
+          }
+          /* seekerr == CURL_SEEKFUNC_CANTSEEK (can't seek to offset) */
+          do {
+            size_t readthisamountnow =
+              (data->state.resume_from - passed > data->set.buffer_size) ?
+              (size_t)data->set.buffer_size :
+              curlx_sotouz(data->state.resume_from - passed);
+
+            size_t actuallyread =
+              data->state.fread_func(data->state.buffer, 1,
+                                     readthisamountnow, data->state.in);
+
+            passed += actuallyread;
+            if((actuallyread == 0) || (actuallyread > readthisamountnow)) {
+              /* this checks for greater-than only to make sure that the
+                 CURL_READFUNC_ABORT return code still aborts */
+              failf(data, "Failed to read data");
+              MOVE_TO_ERROR_STATE(CURLE_FTP_COULDNT_USE_REST);
+            }
+          } while(passed < data->state.resume_from);
+        }
+
+        /* now, decrease the size of the read */
+        if(data->state.infilesize > 0) {
+          data->state.infilesize -= data->state.resume_from;
+          data->req.size = data->state.infilesize;
+          Curl_pgrsSetUploadSize(data, data->state.infilesize);
+        }
+
+        rc = sftp_seek64(sshc->sftp_file, data->state.resume_from);
+        if(rc != 0) {
+          MOVE_TO_SFTP_CLOSE_STATE();
+        }
+      }
+      if(data->state.infilesize > 0) {
+        data->req.size = data->state.infilesize;
+        Curl_pgrsSetUploadSize(data, data->state.infilesize);
+      }
+      /* upload data */
+      Curl_setup_transfer(data, -1, -1, FALSE, FIRSTSOCKET);
+
+      /* not set by Curl_setup_transfer to preserve keepon bits */
+      conn->sockfd = conn->writesockfd;
+
+      /* store this original bitmask setup to use later on if we can't
+         figure out a "real" bitmask */
+      sshc->orig_waitfor = data->req.keepon;
+
+      /* we want to use the _sending_ function even when the socket turns
+         out readable as the underlying libssh sftp send function will deal
+         with both accordingly */
+      conn->cselect_bits = CURL_CSELECT_OUT;
+
+      /* since we don't really wait for anything at this point, we want the
+         state machine to move on as soon as possible so we set a very short
+         timeout here */
+      Curl_expire(data, 0, EXPIRE_RUN_NOW);
+
+      state(conn, SSH_STOP);
+      break;
+    }
+
+    case SSH_SFTP_CREATE_DIRS_INIT:
+      if(strlen(protop->path) > 1) {
+        sshc->slash_pos = protop->path + 1; /* ignore the leading '/' */
+        state(conn, SSH_SFTP_CREATE_DIRS);
+      }
+      else {
+        state(conn, SSH_SFTP_UPLOAD_INIT);
+      }
+      break;
+
+    case SSH_SFTP_CREATE_DIRS:
+      sshc->slash_pos = strchr(sshc->slash_pos, '/');
+      if(sshc->slash_pos) {
+        *sshc->slash_pos = 0;
+
+        infof(data, "Creating directory '%s'\n", protop->path);
+        state(conn, SSH_SFTP_CREATE_DIRS_MKDIR);
+        break;
+      }
+      state(conn, SSH_SFTP_UPLOAD_INIT);
+      break;
+
+    case SSH_SFTP_CREATE_DIRS_MKDIR:
+      /* 'mode' - parameter is preliminary - default to 0644 */
+      rc = sftp_mkdir(sshc->sftp_session, protop->path,
+                      (mode_t)data->set.new_directory_perms);
+      *sshc->slash_pos = '/';
+      ++sshc->slash_pos;
+      if(rc < 0) {
+        /*
+         * Abort if failure wasn't that the dir already exists or the
+         * permission was denied (creation might succeed further down the
+         * path) - retry on unspecific FAILURE also
+         */
+        err = sftp_get_error(sshc->sftp_session);
+        if((err != SSH_FX_FILE_ALREADY_EXISTS) &&
+           (err != SSH_FX_FAILURE) &&
+           (err != SSH_FX_PERMISSION_DENIED)) {
+          MOVE_TO_SFTP_CLOSE_STATE();
+        }
+        rc = 0; /* clear rc and continue */
+      }
+      state(conn, SSH_SFTP_CREATE_DIRS);
+      break;
+
+    case SSH_SFTP_READDIR_INIT:
+      Curl_pgrsSetDownloadSize(data, -1);
+      if(data->set.opt_no_body) {
+        state(conn, SSH_STOP);
+        break;
+      }
+
+      /*
+       * This is a directory that we are trying to get, so produce a directory
+       * listing
+       */
+      sshc->sftp_dir = sftp_opendir(sshc->sftp_session,
+                                    protop->path);
+      if(!sshc->sftp_dir) {
+        failf(data, "Could not open directory for reading: %s",
+              ssh_get_error(sshc->ssh_session));
+        MOVE_TO_SFTP_CLOSE_STATE();
+      }
+      state(conn, SSH_SFTP_READDIR);
+      break;
+
+    case SSH_SFTP_READDIR:
+
+      if(sshc->readdir_attrs)
+        sftp_attributes_free(sshc->readdir_attrs);
+
+      sshc->readdir_attrs = sftp_readdir(sshc->sftp_session, sshc->sftp_dir);
+      if(sshc->readdir_attrs) {
+        sshc->readdir_filename = sshc->readdir_attrs->name;
+        sshc->readdir_longentry = sshc->readdir_attrs->longname;
+        sshc->readdir_len = strlen(sshc->readdir_filename);
+
+        if(data->set.ftp_list_only) {
+          char *tmpLine;
+
+          tmpLine = aprintf("%s\n", sshc->readdir_filename);
+          if(tmpLine == NULL) {
+            state(conn, SSH_SFTP_CLOSE);
+            sshc->actualcode = CURLE_OUT_OF_MEMORY;
+            break;
+          }
+          result = Curl_client_write(conn, CLIENTWRITE_BODY,
+                                     tmpLine, sshc->readdir_len + 1);
+          free(tmpLine);
+
+          if(result) {
+            state(conn, SSH_STOP);
+            break;
+          }
+          /* since this counts what we send to the client, we include the
+             newline in this counter */
+          data->req.bytecount += sshc->readdir_len + 1;
+
+          /* output debug output if that is requested */
+          if(data->set.verbose) {
+            Curl_debug(data, CURLINFO_DATA_OUT,
+                       (char *)sshc->readdir_filename,
+                       sshc->readdir_len);
+          }
+        }
+        else {
+          sshc->readdir_currLen = strlen(sshc->readdir_longentry);
+          sshc->readdir_totalLen = 80 + sshc->readdir_currLen;
+          sshc->readdir_line = calloc(sshc->readdir_totalLen, 1);
+          if(!sshc->readdir_line) {
+            state(conn, SSH_SFTP_CLOSE);
+            sshc->actualcode = CURLE_OUT_OF_MEMORY;
+            break;
+          }
+
+          memcpy(sshc->readdir_line, sshc->readdir_longentry,
+                 sshc->readdir_currLen);
+          if((sshc->readdir_attrs->flags & SSH_FILEXFER_ATTR_PERMISSIONS) &&
+             ((sshc->readdir_attrs->permissions & S_IFMT) ==
+              S_IFLNK)) {
+            sshc->readdir_linkPath = malloc(PATH_MAX + 1);
+            if(sshc->readdir_linkPath == NULL) {
+              state(conn, SSH_SFTP_CLOSE);
+              sshc->actualcode = CURLE_OUT_OF_MEMORY;
+              break;
+            }
+
+            msnprintf(sshc->readdir_linkPath, PATH_MAX, "%s%s", protop->path,
+                      sshc->readdir_filename);
+
+            state(conn, SSH_SFTP_READDIR_LINK);
+            break;
+          }
+          state(conn, SSH_SFTP_READDIR_BOTTOM);
+          break;
+        }
+      }
+      else if(sftp_dir_eof(sshc->sftp_dir)) {
+        state(conn, SSH_SFTP_READDIR_DONE);
+        break;
+      }
+      else {
+        failf(data, "Could not open remote file for reading: %s",
+              ssh_get_error(sshc->ssh_session));
+        MOVE_TO_SFTP_CLOSE_STATE();
+        break;
+      }
+      break;
+
+    case SSH_SFTP_READDIR_LINK:
+      if(sshc->readdir_link_attrs)
+        sftp_attributes_free(sshc->readdir_link_attrs);
+
+      sshc->readdir_link_attrs = sftp_lstat(sshc->sftp_session,
+                                            sshc->readdir_linkPath);
+      if(sshc->readdir_link_attrs == 0) {
+        failf(data, "Could not read symlink for reading: %s",
+              ssh_get_error(sshc->ssh_session));
+        MOVE_TO_SFTP_CLOSE_STATE();
+      }
+
+      if(sshc->readdir_link_attrs->name == NULL) {
+        sshc->readdir_tmp = sftp_readlink(sshc->sftp_session,
+                                          sshc->readdir_linkPath);
+        if(sshc->readdir_filename == NULL)
+          sshc->readdir_len = 0;
+        else
+          sshc->readdir_len = strlen(sshc->readdir_tmp);
+        sshc->readdir_longentry = NULL;
+        sshc->readdir_filename = sshc->readdir_tmp;
+      }
+      else {
+        sshc->readdir_len = strlen(sshc->readdir_link_attrs->name);
+        sshc->readdir_filename = sshc->readdir_link_attrs->name;
+        sshc->readdir_longentry = sshc->readdir_link_attrs->longname;
+      }
+
+      Curl_safefree(sshc->readdir_linkPath);
+
+      /* get room for the filename and extra output */
+      sshc->readdir_totalLen += 4 + sshc->readdir_len;
+      new_readdir_line = Curl_saferealloc(sshc->readdir_line,
+                                          sshc->readdir_totalLen);
+      if(!new_readdir_line) {
+        sshc->readdir_line = NULL;
+        state(conn, SSH_SFTP_CLOSE);
+        sshc->actualcode = CURLE_OUT_OF_MEMORY;
+        break;
+      }
+      sshc->readdir_line = new_readdir_line;
+
+      sshc->readdir_currLen += msnprintf(sshc->readdir_line +
+                                         sshc->readdir_currLen,
+                                         sshc->readdir_totalLen -
+                                         sshc->readdir_currLen,
+                                         " -> %s",
+                                         sshc->readdir_filename);
+
+      sftp_attributes_free(sshc->readdir_link_attrs);
+      sshc->readdir_link_attrs = NULL;
+      sshc->readdir_filename = NULL;
+      sshc->readdir_longentry = NULL;
+
+      state(conn, SSH_SFTP_READDIR_BOTTOM);
+      /* FALLTHROUGH */
+    case SSH_SFTP_READDIR_BOTTOM:
+      sshc->readdir_currLen += msnprintf(sshc->readdir_line +
+                                         sshc->readdir_currLen,
+                                         sshc->readdir_totalLen -
+                                         sshc->readdir_currLen, "\n");
+      result = Curl_client_write(conn, CLIENTWRITE_BODY,
+                                 sshc->readdir_line,
+                                 sshc->readdir_currLen);
+
+      if(!result) {
+
+        /* output debug output if that is requested */
+        if(data->set.verbose) {
+          Curl_debug(data, CURLINFO_DATA_OUT, sshc->readdir_line,
+                     sshc->readdir_currLen);
+        }
+        data->req.bytecount += sshc->readdir_currLen;
+      }
+      Curl_safefree(sshc->readdir_line);
+      ssh_string_free_char(sshc->readdir_tmp);
+      sshc->readdir_tmp = NULL;
+
+      if(result) {
+        state(conn, SSH_STOP);
+      }
+      else
+        state(conn, SSH_SFTP_READDIR);
+      break;
+
+    case SSH_SFTP_READDIR_DONE:
+      sftp_closedir(sshc->sftp_dir);
+      sshc->sftp_dir = NULL;
+
+      /* no data to transfer */
+      Curl_setup_transfer(data, -1, -1, FALSE, -1);
+      state(conn, SSH_STOP);
+      break;
+
+    case SSH_SFTP_DOWNLOAD_INIT:
+      /*
+       * Work on getting the specified file
+       */
+      if(sshc->sftp_file)
+        sftp_close(sshc->sftp_file);
+
+      sshc->sftp_file = sftp_open(sshc->sftp_session, protop->path,
+                                  O_RDONLY, (mode_t)data->set.new_file_perms);
+      if(!sshc->sftp_file) {
+        failf(data, "Could not open remote file for reading: %s",
+              ssh_get_error(sshc->ssh_session));
+
+        MOVE_TO_SFTP_CLOSE_STATE();
+      }
+
+      state(conn, SSH_SFTP_DOWNLOAD_STAT);
+      break;
+
+    case SSH_SFTP_DOWNLOAD_STAT:
+    {
+      sftp_attributes attrs;
+      curl_off_t size;
+
+      attrs = sftp_fstat(sshc->sftp_file);
+      if(!attrs ||
+              !(attrs->flags & SSH_FILEXFER_ATTR_SIZE) ||
+              (attrs->size == 0)) {
+        /*
+         * sftp_fstat didn't return an error, so maybe the server
+         * just doesn't support stat()
+         * OR the server doesn't return a file size with a stat()
+         * OR file size is 0
+         */
+        data->req.size = -1;
+        data->req.maxdownload = -1;
+        Curl_pgrsSetDownloadSize(data, -1);
+        size = 0;
+      }
+      else {
+        size = attrs->size;
+
+        sftp_attributes_free(attrs);
+
+        if(size < 0) {
+          failf(data, "Bad file size (%" CURL_FORMAT_CURL_OFF_T ")", size);
+          return CURLE_BAD_DOWNLOAD_RESUME;
+        }
+        if(conn->data->state.use_range) {
+          curl_off_t from, to;
+          char *ptr;
+          char *ptr2;
+          CURLofft to_t;
+          CURLofft from_t;
+
+          from_t = curlx_strtoofft(conn->data->state.range, &ptr, 0, &from);
+          if(from_t == CURL_OFFT_FLOW) {
+            return CURLE_RANGE_ERROR;
+          }
+          while(*ptr && (ISSPACE(*ptr) || (*ptr == '-')))
+            ptr++;
+          to_t = curlx_strtoofft(ptr, &ptr2, 0, &to);
+          if(to_t == CURL_OFFT_FLOW) {
+            return CURLE_RANGE_ERROR;
+          }
+          if((to_t == CURL_OFFT_INVAL) /* no "to" value given */
+             || (to >= size)) {
+            to = size - 1;
+          }
+          if(from_t) {
+            /* from is relative to end of file */
+            from = size - to;
+            to = size - 1;
+          }
+          if(from > size) {
+            failf(data, "Offset (%"
+                  CURL_FORMAT_CURL_OFF_T ") was beyond file size (%"
+                  CURL_FORMAT_CURL_OFF_T ")", from, size);
+            return CURLE_BAD_DOWNLOAD_RESUME;
+          }
+          if(from > to) {
+            from = to;
+            size = 0;
+          }
+          else {
+            size = to - from + 1;
+          }
+
+          rc = sftp_seek64(sshc->sftp_file, from);
+          if(rc != 0) {
+            MOVE_TO_SFTP_CLOSE_STATE();
+          }
+        }
+        data->req.size = size;
+        data->req.maxdownload = size;
+        Curl_pgrsSetDownloadSize(data, size);
+      }
+
+      /* We can resume if we can seek to the resume position */
+      if(data->state.resume_from) {
+        if(data->state.resume_from < 0) {
+          /* We're supposed to download the last abs(from) bytes */
+          if((curl_off_t)size < -data->state.resume_from) {
+            failf(data, "Offset (%"
+                  CURL_FORMAT_CURL_OFF_T ") was beyond file size (%"
+                  CURL_FORMAT_CURL_OFF_T ")",
+                  data->state.resume_from, size);
+            return CURLE_BAD_DOWNLOAD_RESUME;
+          }
+          /* download from where? */
+          data->state.resume_from += size;
+        }
+        else {
+          if((curl_off_t)size < data->state.resume_from) {
+            failf(data, "Offset (%" CURL_FORMAT_CURL_OFF_T
+                  ") was beyond file size (%" CURL_FORMAT_CURL_OFF_T ")",
+                  data->state.resume_from, size);
+            return CURLE_BAD_DOWNLOAD_RESUME;
+          }
+        }
+        /* Now store the number of bytes we are expected to download */
+        data->req.size = size - data->state.resume_from;
+        data->req.maxdownload = size - data->state.resume_from;
+        Curl_pgrsSetDownloadSize(data,
+                                 size - data->state.resume_from);
+
+        rc = sftp_seek64(sshc->sftp_file, data->state.resume_from);
+        if(rc != 0) {
+          MOVE_TO_SFTP_CLOSE_STATE();
+        }
+      }
+    }
+
+    /* Setup the actual download */
+    if(data->req.size == 0) {
+      /* no data to transfer */
+      Curl_setup_transfer(data, -1, -1, FALSE, -1);
+      infof(data, "File already completely downloaded\n");
+      state(conn, SSH_STOP);
+      break;
+    }
+    Curl_setup_transfer(data, FIRSTSOCKET, data->req.size, FALSE, -1);
+
+    /* not set by Curl_setup_transfer to preserve keepon bits */
+    conn->writesockfd = conn->sockfd;
+
+    /* we want to use the _receiving_ function even when the socket turns
+       out writableable as the underlying libssh recv function will deal
+       with both accordingly */
+    conn->cselect_bits = CURL_CSELECT_IN;
+
+    if(result) {
+      /* this should never occur; the close state should be entered
+         at the time the error occurs */
+      state(conn, SSH_SFTP_CLOSE);
+      sshc->actualcode = result;
+    }
+    else {
+      sshc->sftp_recv_state = 0;
+      state(conn, SSH_STOP);
+    }
+    break;
+
+    case SSH_SFTP_CLOSE:
+      if(sshc->sftp_file) {
+        sftp_close(sshc->sftp_file);
+        sshc->sftp_file = NULL;
+      }
+      Curl_safefree(protop->path);
+
+      DEBUGF(infof(data, "SFTP DONE done\n"));
+
+      /* Check if nextstate is set and move .nextstate could be POSTQUOTE_INIT
+         After nextstate is executed, the control should come back to
+         SSH_SFTP_CLOSE to pass the correct result back  */
+      if(sshc->nextstate != SSH_NO_STATE &&
+         sshc->nextstate != SSH_SFTP_CLOSE) {
+        state(conn, sshc->nextstate);
+        sshc->nextstate = SSH_SFTP_CLOSE;
+      }
+      else {
+        state(conn, SSH_STOP);
+        result = sshc->actualcode;
+      }
+      break;
+
+    case SSH_SFTP_SHUTDOWN:
+      /* during times we get here due to a broken transfer and then the
+         sftp_handle might not have been taken down so make sure that is done
+         before we proceed */
+
+      if(sshc->sftp_file) {
+        sftp_close(sshc->sftp_file);
+        sshc->sftp_file = NULL;
+      }
+
+      if(sshc->sftp_session) {
+        sftp_free(sshc->sftp_session);
+        sshc->sftp_session = NULL;
+      }
+
+      SSH_STRING_FREE_CHAR(sshc->homedir);
+      conn->data->state.most_recent_ftp_entrypath = NULL;
+
+      state(conn, SSH_SESSION_DISCONNECT);
+      break;
+
+
+    case SSH_SCP_TRANS_INIT:
+      result = Curl_getworkingpath(conn, sshc->homedir, &protop->path);
+      if(result) {
+        sshc->actualcode = result;
+        state(conn, SSH_STOP);
+        break;
+      }
+
+      /* Functions from the SCP subsystem cannot handle/return SSH_AGAIN */
+      ssh_set_blocking(sshc->ssh_session, 1);
+
+      if(data->set.upload) {
+        if(data->state.infilesize < 0) {
+          failf(data, "SCP requires a known file size for upload");
+          sshc->actualcode = CURLE_UPLOAD_FAILED;
+          MOVE_TO_ERROR_STATE(CURLE_UPLOAD_FAILED);
+        }
+
+        sshc->scp_session =
+          ssh_scp_new(sshc->ssh_session, SSH_SCP_WRITE, protop->path);
+        state(conn, SSH_SCP_UPLOAD_INIT);
+      }
+      else {
+        sshc->scp_session =
+          ssh_scp_new(sshc->ssh_session, SSH_SCP_READ, protop->path);
+        state(conn, SSH_SCP_DOWNLOAD_INIT);
+      }
+
+      if(!sshc->scp_session) {
+        err_msg = ssh_get_error(sshc->ssh_session);
+        failf(conn->data, "%s", err_msg);
+        MOVE_TO_ERROR_STATE(CURLE_UPLOAD_FAILED);
+      }
+
+      break;
+
+    case SSH_SCP_UPLOAD_INIT:
+
+      rc = ssh_scp_init(sshc->scp_session);
+      if(rc != SSH_OK) {
+        err_msg = ssh_get_error(sshc->ssh_session);
+        failf(conn->data, "%s", err_msg);
+        MOVE_TO_ERROR_STATE(CURLE_UPLOAD_FAILED);
+      }
+
+      rc = ssh_scp_push_file(sshc->scp_session, protop->path,
+                             data->state.infilesize,
+                             (int)data->set.new_file_perms);
+      if(rc != SSH_OK) {
+        err_msg = ssh_get_error(sshc->ssh_session);
+        failf(conn->data, "%s", err_msg);
+        MOVE_TO_ERROR_STATE(CURLE_UPLOAD_FAILED);
+      }
+
+      /* upload data */
+      Curl_setup_transfer(data, -1, data->req.size, FALSE, FIRSTSOCKET);
+
+      /* not set by Curl_setup_transfer to preserve keepon bits */
+      conn->sockfd = conn->writesockfd;
+
+      /* store this original bitmask setup to use later on if we can't
+         figure out a "real" bitmask */
+      sshc->orig_waitfor = data->req.keepon;
+
+      /* we want to use the _sending_ function even when the socket turns
+         out readable as the underlying libssh scp send function will deal
+         with both accordingly */
+      conn->cselect_bits = CURL_CSELECT_OUT;
+
+      state(conn, SSH_STOP);
+
+      break;
+
+    case SSH_SCP_DOWNLOAD_INIT:
+
+      rc = ssh_scp_init(sshc->scp_session);
+      if(rc != SSH_OK) {
+        err_msg = ssh_get_error(sshc->ssh_session);
+        failf(conn->data, "%s", err_msg);
+        MOVE_TO_ERROR_STATE(CURLE_COULDNT_CONNECT);
+      }
+      state(conn, SSH_SCP_DOWNLOAD);
+      /* FALLTHROUGH */
+
+    case SSH_SCP_DOWNLOAD:{
+        curl_off_t bytecount;
+
+        rc = ssh_scp_pull_request(sshc->scp_session);
+        if(rc != SSH_SCP_REQUEST_NEWFILE) {
+          err_msg = ssh_get_error(sshc->ssh_session);
+          failf(conn->data, "%s", err_msg);
+          MOVE_TO_ERROR_STATE(CURLE_REMOTE_FILE_NOT_FOUND);
+          break;
+        }
+
+        /* download data */
+        bytecount = ssh_scp_request_get_size(sshc->scp_session);
+        data->req.maxdownload = (curl_off_t) bytecount;
+        Curl_setup_transfer(data, FIRSTSOCKET, bytecount, FALSE, -1);
+
+        /* not set by Curl_setup_transfer to preserve keepon bits */
+        conn->writesockfd = conn->sockfd;
+
+        /* we want to use the _receiving_ function even when the socket turns
+           out writableable as the underlying libssh recv function will deal
+           with both accordingly */
+        conn->cselect_bits = CURL_CSELECT_IN;
+
+        state(conn, SSH_STOP);
+        break;
+      }
+    case SSH_SCP_DONE:
+      if(data->set.upload)
+        state(conn, SSH_SCP_SEND_EOF);
+      else
+        state(conn, SSH_SCP_CHANNEL_FREE);
+      break;
+
+    case SSH_SCP_SEND_EOF:
+      if(sshc->scp_session) {
+        rc = ssh_scp_close(sshc->scp_session);
+        if(rc == SSH_AGAIN) {
+          /* Currently the ssh_scp_close handles waiting for EOF in
+           * blocking way.
+           */
+          break;
+        }
+        if(rc != SSH_OK) {
+          infof(data, "Failed to close libssh scp channel: %s\n",
+                ssh_get_error(sshc->ssh_session));
+        }
+      }
+
+      state(conn, SSH_SCP_CHANNEL_FREE);
+      break;
+
+    case SSH_SCP_CHANNEL_FREE:
+      if(sshc->scp_session) {
+        ssh_scp_free(sshc->scp_session);
+        sshc->scp_session = NULL;
+      }
+      DEBUGF(infof(data, "SCP DONE phase complete\n"));
+
+      ssh_set_blocking(sshc->ssh_session, 0);
+
+      state(conn, SSH_SESSION_DISCONNECT);
+      /* FALLTHROUGH */
+
+    case SSH_SESSION_DISCONNECT:
+      /* during weird times when we've been prematurely aborted, the channel
+         is still alive when we reach this state and we MUST kill the channel
+         properly first */
+      if(sshc->scp_session) {
+        ssh_scp_free(sshc->scp_session);
+        sshc->scp_session = NULL;
+      }
+
+      ssh_disconnect(sshc->ssh_session);
+
+      SSH_STRING_FREE_CHAR(sshc->homedir);
+      conn->data->state.most_recent_ftp_entrypath = NULL;
+
+      state(conn, SSH_SESSION_FREE);
+      /* FALLTHROUGH */
+    case SSH_SESSION_FREE:
+      if(sshc->ssh_session) {
+        ssh_free(sshc->ssh_session);
+        sshc->ssh_session = NULL;
+      }
+
+      /* worst-case scenario cleanup */
+
+      DEBUGASSERT(sshc->ssh_session == NULL);
+      DEBUGASSERT(sshc->scp_session == NULL);
+
+      if(sshc->readdir_tmp) {
+        ssh_string_free_char(sshc->readdir_tmp);
+        sshc->readdir_tmp = NULL;
+      }
+
+      if(sshc->quote_attrs)
+        sftp_attributes_free(sshc->quote_attrs);
+
+      if(sshc->readdir_attrs)
+        sftp_attributes_free(sshc->readdir_attrs);
+
+      if(sshc->readdir_link_attrs)
+        sftp_attributes_free(sshc->readdir_link_attrs);
+
+      if(sshc->privkey)
+        ssh_key_free(sshc->privkey);
+      if(sshc->pubkey)
+        ssh_key_free(sshc->pubkey);
+
+      Curl_safefree(sshc->rsa_pub);
+      Curl_safefree(sshc->rsa);
+      Curl_safefree(sshc->quote_path1);
+      Curl_safefree(sshc->quote_path2);
+      Curl_safefree(sshc->readdir_line);
+      Curl_safefree(sshc->readdir_linkPath);
+      SSH_STRING_FREE_CHAR(sshc->homedir);
+
+      /* the code we are about to return */
+      result = sshc->actualcode;
+
+      memset(sshc, 0, sizeof(struct ssh_conn));
+
+      connclose(conn, "SSH session free");
+      sshc->state = SSH_SESSION_FREE;   /* current */
+      sshc->nextstate = SSH_NO_STATE;
+      state(conn, SSH_STOP);
+      break;
+
+    case SSH_QUIT:
+      /* fallthrough, just stop! */
+    default:
+      /* internal error */
+      sshc->nextstate = SSH_NO_STATE;
+      state(conn, SSH_STOP);
+      break;
+
+    }
+  } while(!rc && (sshc->state != SSH_STOP));
+
+
+  if(rc == SSH_AGAIN) {
+    /* we would block, we need to wait for the socket to be ready (in the
+       right direction too)! */
+    *block = TRUE;
+  }
+
+  return result;
+}
+
+
+/* called by the multi interface to figure out what socket(s) to wait for and
+   for what actions in the DO_DONE, PERFORM and WAITPERFORM states */
+static int myssh_perform_getsock(const struct connectdata *conn,
+                                 curl_socket_t *sock)
+{
+  int bitmap = GETSOCK_BLANK;
+  sock[0] = conn->sock[FIRSTSOCKET];
+
+  if(conn->waitfor & KEEP_RECV)
+    bitmap |= GETSOCK_READSOCK(FIRSTSOCKET);
+
+  if(conn->waitfor & KEEP_SEND)
+    bitmap |= GETSOCK_WRITESOCK(FIRSTSOCKET);
+
+  return bitmap;
+}
+
+/* Generic function called by the multi interface to figure out what socket(s)
+   to wait for and for what actions during the DOING and PROTOCONNECT states*/
+static int myssh_getsock(struct connectdata *conn,
+                         curl_socket_t *sock)
+{
+  /* if we know the direction we can use the generic *_getsock() function even
+     for the protocol_connect and doing states */
+  return myssh_perform_getsock(conn, sock);
+}
+
+static void myssh_block2waitfor(struct connectdata *conn, bool block)
+{
+  struct ssh_conn *sshc = &conn->proto.sshc;
+
+  /* If it didn't block, or nothing was returned by ssh_get_poll_flags
+   * have the original set */
+  conn->waitfor = sshc->orig_waitfor;
+
+  if(block) {
+    int dir = ssh_get_poll_flags(sshc->ssh_session);
+    if(dir & SSH_READ_PENDING) {
+      /* translate the libssh define bits into our own bit defines */
+      conn->waitfor = KEEP_RECV;
+    }
+    else if(dir & SSH_WRITE_PENDING) {
+      conn->waitfor = KEEP_SEND;
+    }
+  }
+}
+
+/* called repeatedly until done from multi.c */
+static CURLcode myssh_multi_statemach(struct connectdata *conn,
+                                      bool *done)
+{
+  struct ssh_conn *sshc = &conn->proto.sshc;
+  bool block;    /* we store the status and use that to provide a ssh_getsock()
+                    implementation */
+  CURLcode result = myssh_statemach_act(conn, &block);
+
+  *done = (sshc->state == SSH_STOP) ? TRUE : FALSE;
+  myssh_block2waitfor(conn, block);
+
+  return result;
+}
+
+static CURLcode myssh_block_statemach(struct connectdata *conn,
+                                      bool disconnect)
+{
+  struct ssh_conn *sshc = &conn->proto.sshc;
+  CURLcode result = CURLE_OK;
+  struct Curl_easy *data = conn->data;
+
+  while((sshc->state != SSH_STOP) && !result) {
+    bool block;
+    timediff_t left = 1000;
+    struct curltime now = Curl_now();
+
+    result = myssh_statemach_act(conn, &block);
+    if(result)
+      break;
+
+    if(!disconnect) {
+      if(Curl_pgrsUpdate(conn))
+        return CURLE_ABORTED_BY_CALLBACK;
+
+      result = Curl_speedcheck(data, now);
+      if(result)
+        break;
+
+      left = Curl_timeleft(data, NULL, FALSE);
+      if(left < 0) {
+        failf(data, "Operation timed out");
+        return CURLE_OPERATION_TIMEDOUT;
+      }
+    }
+
+    if(block) {
+      curl_socket_t fd_read = conn->sock[FIRSTSOCKET];
+      /* wait for the socket to become ready */
+      (void) Curl_socket_check(fd_read, CURL_SOCKET_BAD,
+                               CURL_SOCKET_BAD, left > 1000 ? 1000 : left);
+    }
+
+  }
+
+  return result;
+}
+
+/*
+ * SSH setup connection
+ */
+static CURLcode myssh_setup_connection(struct connectdata *conn)
+{
+  struct SSHPROTO *ssh;
+
+  conn->data->req.protop = ssh = calloc(1, sizeof(struct SSHPROTO));
+  if(!ssh)
+    return CURLE_OUT_OF_MEMORY;
+
+  return CURLE_OK;
+}
+
+static Curl_recv scp_recv, sftp_recv;
+static Curl_send scp_send, sftp_send;
+
+/*
+ * Curl_ssh_connect() gets called from Curl_protocol_connect() to allow us to
+ * do protocol-specific actions at connect-time.
+ */
+static CURLcode myssh_connect(struct connectdata *conn, bool *done)
+{
+  struct ssh_conn *ssh;
+  CURLcode result;
+  curl_socket_t sock = conn->sock[FIRSTSOCKET];
+  struct Curl_easy *data = conn->data;
+  int rc;
+
+  /* initialize per-handle data if not already */
+  if(!data->req.protop)
+    myssh_setup_connection(conn);
+
+  /* We default to persistent connections. We set this already in this connect
+     function to make the re-use checks properly be able to check this bit. */
+  connkeep(conn, "SSH default");
+
+  if(conn->handler->protocol & CURLPROTO_SCP) {
+    conn->recv[FIRSTSOCKET] = scp_recv;
+    conn->send[FIRSTSOCKET] = scp_send;
+  }
+  else {
+    conn->recv[FIRSTSOCKET] = sftp_recv;
+    conn->send[FIRSTSOCKET] = sftp_send;
+  }
+
+  ssh = &conn->proto.sshc;
+
+  ssh->ssh_session = ssh_new();
+  if(ssh->ssh_session == NULL) {
+    failf(data, "Failure initialising ssh session");
+    return CURLE_FAILED_INIT;
+  }
+
+  rc = ssh_options_set(ssh->ssh_session, SSH_OPTIONS_HOST, conn->host.name);
+  if(rc != SSH_OK) {
+    failf(data, "Could not set remote host");
+    return CURLE_FAILED_INIT;
+  }
+
+  rc = ssh_options_parse_config(ssh->ssh_session, NULL);
+  if(rc != SSH_OK) {
+    infof(data, "Could not parse SSH configuration files");
+    /* ignore */
+  }
+
+  rc = ssh_options_set(ssh->ssh_session, SSH_OPTIONS_FD, &sock);
+  if(rc != SSH_OK) {
+    failf(data, "Could not set socket");
+    return CURLE_FAILED_INIT;
+  }
+
+  if(conn->user && conn->user[0] != '\0') {
+    infof(data, "User: %s\n", conn->user);
+    rc = ssh_options_set(ssh->ssh_session, SSH_OPTIONS_USER, conn->user);
+    if(rc != SSH_OK) {
+      failf(data, "Could not set user");
+      return CURLE_FAILED_INIT;
+    }
+  }
+
+  if(data->set.str[STRING_SSH_KNOWNHOSTS]) {
+    infof(data, "Known hosts: %s\n", data->set.str[STRING_SSH_KNOWNHOSTS]);
+    rc = ssh_options_set(ssh->ssh_session, SSH_OPTIONS_KNOWNHOSTS,
+                         data->set.str[STRING_SSH_KNOWNHOSTS]);
+    if(rc != SSH_OK) {
+      failf(data, "Could not set known hosts file path");
+      return CURLE_FAILED_INIT;
+    }
+  }
+
+  if(conn->remote_port) {
+    rc = ssh_options_set(ssh->ssh_session, SSH_OPTIONS_PORT,
+                         &conn->remote_port);
+    if(rc != SSH_OK) {
+      failf(data, "Could not set remote port");
+      return CURLE_FAILED_INIT;
+    }
+  }
+
+  if(data->set.ssh_compression) {
+    rc = ssh_options_set(ssh->ssh_session, SSH_OPTIONS_COMPRESSION,
+                         "zlib,zlib@openssh.com,none");
+    if(rc != SSH_OK) {
+      failf(data, "Could not set compression");
+      return CURLE_FAILED_INIT;
+    }
+  }
+
+  ssh->privkey = NULL;
+  ssh->pubkey = NULL;
+
+  if(data->set.str[STRING_SSH_PUBLIC_KEY]) {
+    rc = ssh_pki_import_pubkey_file(data->set.str[STRING_SSH_PUBLIC_KEY],
+                                    &ssh->pubkey);
+    if(rc != SSH_OK) {
+      failf(data, "Could not load public key file");
+      return CURLE_FAILED_INIT;
+    }
+  }
+
+  /* we do not verify here, we do it at the state machine,
+   * after connection */
+
+  state(conn, SSH_INIT);
+
+  result = myssh_multi_statemach(conn, done);
+
+  return result;
+}
+
+/* called from multi.c while DOing */
+static CURLcode scp_doing(struct connectdata *conn, bool *dophase_done)
+{
+  CURLcode result;
+
+  result = myssh_multi_statemach(conn, dophase_done);
+
+  if(*dophase_done) {
+    DEBUGF(infof(conn->data, "DO phase is complete\n"));
+  }
+  return result;
+}
+
+/*
+ ***********************************************************************
+ *
+ * scp_perform()
+ *
+ * This is the actual DO function for SCP. Get a file according to
+ * the options previously setup.
+ */
+
+static
+CURLcode scp_perform(struct connectdata *conn,
+                     bool *connected, bool *dophase_done)
+{
+  CURLcode result = CURLE_OK;
+
+  DEBUGF(infof(conn->data, "DO phase starts\n"));
+
+  *dophase_done = FALSE;        /* not done yet */
+
+  /* start the first command in the DO phase */
+  state(conn, SSH_SCP_TRANS_INIT);
+
+  result = myssh_multi_statemach(conn, dophase_done);
+
+  *connected = conn->bits.tcpconnect[FIRSTSOCKET];
+
+  if(*dophase_done) {
+    DEBUGF(infof(conn->data, "DO phase is complete\n"));
+  }
+
+  return result;
+}
+
+static CURLcode myssh_do_it(struct connectdata *conn, bool *done)
+{
+  CURLcode result;
+  bool connected = 0;
+  struct Curl_easy *data = conn->data;
+  struct ssh_conn *sshc = &conn->proto.sshc;
+
+  *done = FALSE;                /* default to false */
+
+  data->req.size = -1;          /* make sure this is unknown at this point */
+
+  sshc->actualcode = CURLE_OK;  /* reset error code */
+  sshc->secondCreateDirs = 0;   /* reset the create dir attempt state
+                                   variable */
+
+  Curl_pgrsSetUploadCounter(data, 0);
+  Curl_pgrsSetDownloadCounter(data, 0);
+  Curl_pgrsSetUploadSize(data, -1);
+  Curl_pgrsSetDownloadSize(data, -1);
+
+  if(conn->handler->protocol & CURLPROTO_SCP)
+    result = scp_perform(conn, &connected, done);
+  else
+    result = sftp_perform(conn, &connected, done);
+
+  return result;
+}
+
+/* BLOCKING, but the function is using the state machine so the only reason
+   this is still blocking is that the multi interface code has no support for
+   disconnecting operations that takes a while */
+static CURLcode scp_disconnect(struct connectdata *conn,
+                               bool dead_connection)
+{
+  CURLcode result = CURLE_OK;
+  struct ssh_conn *ssh = &conn->proto.sshc;
+  (void) dead_connection;
+
+  if(ssh->ssh_session) {
+    /* only if there's a session still around to use! */
+
+    state(conn, SSH_SESSION_DISCONNECT);
+
+    result = myssh_block_statemach(conn, TRUE);
+  }
+
+  return result;
+}
+
+/* generic done function for both SCP and SFTP called from their specific
+   done functions */
+static CURLcode myssh_done(struct connectdata *conn, CURLcode status)
+{
+  CURLcode result = CURLE_OK;
+  struct SSHPROTO *protop = conn->data->req.protop;
+
+  if(!status) {
+    /* run the state-machine */
+    result = myssh_block_statemach(conn, FALSE);
+  }
+  else
+    result = status;
+
+  if(protop)
+    Curl_safefree(protop->path);
+  if(Curl_pgrsDone(conn))
+    return CURLE_ABORTED_BY_CALLBACK;
+
+  conn->data->req.keepon = 0;   /* clear all bits */
+  return result;
+}
+
+
+static CURLcode scp_done(struct connectdata *conn, CURLcode status,
+                         bool premature)
+{
+  (void) premature;             /* not used */
+
+  if(!status)
+    state(conn, SSH_SCP_DONE);
+
+  return myssh_done(conn, status);
+
+}
+
+static ssize_t scp_send(struct connectdata *conn, int sockindex,
+                        const void *mem, size_t len, CURLcode *err)
+{
+  int rc;
+  (void) sockindex; /* we only support SCP on the fixed known primary socket */
+  (void) err;
+
+  rc = ssh_scp_write(conn->proto.sshc.scp_session, mem, len);
+
+#if 0
+  /* The following code is misleading, mostly added as wishful thinking
+   * that libssh at some point will implement non-blocking ssh_scp_write/read.
+   * Currently rc can only be number of bytes read or SSH_ERROR. */
+  myssh_block2waitfor(conn, (rc == SSH_AGAIN) ? TRUE : FALSE);
+
+  if(rc == SSH_AGAIN) {
+    *err = CURLE_AGAIN;
+    return 0;
+  }
+  else
+#endif
+  if(rc != SSH_OK) {
+    *err = CURLE_SSH;
+    return -1;
+  }
+
+  return len;
+}
+
+static ssize_t scp_recv(struct connectdata *conn, int sockindex,
+                        char *mem, size_t len, CURLcode *err)
+{
+  ssize_t nread;
+  (void) err;
+  (void) sockindex; /* we only support SCP on the fixed known primary socket */
+
+  /* libssh returns int */
+  nread = ssh_scp_read(conn->proto.sshc.scp_session, mem, len);
+
+#if 0
+  /* The following code is misleading, mostly added as wishful thinking
+   * that libssh at some point will implement non-blocking ssh_scp_write/read.
+   * Currently rc can only be SSH_OK or SSH_ERROR. */
+
+  myssh_block2waitfor(conn, (nread == SSH_AGAIN) ? TRUE : FALSE);
+  if(nread == SSH_AGAIN) {
+    *err = CURLE_AGAIN;
+    nread = -1;
+  }
+#endif
+
+  return nread;
+}
+
+/*
+ * =============== SFTP ===============
+ */
+
+/*
+ ***********************************************************************
+ *
+ * sftp_perform()
+ *
+ * This is the actual DO function for SFTP. Get a file/directory according to
+ * the options previously setup.
+ */
+
+static
+CURLcode sftp_perform(struct connectdata *conn,
+                      bool *connected,
+                      bool *dophase_done)
+{
+  CURLcode result = CURLE_OK;
+
+  DEBUGF(infof(conn->data, "DO phase starts\n"));
+
+  *dophase_done = FALSE; /* not done yet */
+
+  /* start the first command in the DO phase */
+  state(conn, SSH_SFTP_QUOTE_INIT);
+
+  /* run the state-machine */
+  result = myssh_multi_statemach(conn, dophase_done);
+
+  *connected = conn->bits.tcpconnect[FIRSTSOCKET];
+
+  if(*dophase_done) {
+    DEBUGF(infof(conn->data, "DO phase is complete\n"));
+  }
+
+  return result;
+}
+
+/* called from multi.c while DOing */
+static CURLcode sftp_doing(struct connectdata *conn,
+                           bool *dophase_done)
+{
+  CURLcode result = myssh_multi_statemach(conn, dophase_done);
+  if(*dophase_done) {
+    DEBUGF(infof(conn->data, "DO phase is complete\n"));
+  }
+  return result;
+}
+
+/* BLOCKING, but the function is using the state machine so the only reason
+   this is still blocking is that the multi interface code has no support for
+   disconnecting operations that takes a while */
+static CURLcode sftp_disconnect(struct connectdata *conn, bool dead_connection)
+{
+  CURLcode result = CURLE_OK;
+  (void) dead_connection;
+
+  DEBUGF(infof(conn->data, "SSH DISCONNECT starts now\n"));
+
+  if(conn->proto.sshc.ssh_session) {
+    /* only if there's a session still around to use! */
+    state(conn, SSH_SFTP_SHUTDOWN);
+    result = myssh_block_statemach(conn, TRUE);
+  }
+
+  DEBUGF(infof(conn->data, "SSH DISCONNECT is done\n"));
+
+  return result;
+
+}
+
+static CURLcode sftp_done(struct connectdata *conn, CURLcode status,
+                               bool premature)
+{
+  struct ssh_conn *sshc = &conn->proto.sshc;
+
+  if(!status) {
+    /* Post quote commands are executed after the SFTP_CLOSE state to avoid
+       errors that could happen due to open file handles during POSTQUOTE
+       operation */
+    if(!premature && conn->data->set.postquote && !conn->bits.retry)
+      sshc->nextstate = SSH_SFTP_POSTQUOTE_INIT;
+    state(conn, SSH_SFTP_CLOSE);
+  }
+  return myssh_done(conn, status);
+}
+
+/* return number of sent bytes */
+static ssize_t sftp_send(struct connectdata *conn, int sockindex,
+                         const void *mem, size_t len, CURLcode *err)
+{
+  ssize_t nwrite;
+  (void)sockindex;
+
+  nwrite = sftp_write(conn->proto.sshc.sftp_file, mem, len);
+
+  myssh_block2waitfor(conn, FALSE);
+
+#if 0 /* not returned by libssh on write */
+  if(nwrite == SSH_AGAIN) {
+    *err = CURLE_AGAIN;
+    nwrite = 0;
+  }
+  else
+#endif
+  if(nwrite < 0) {
+    *err = CURLE_SSH;
+    nwrite = -1;
+  }
+
+  return nwrite;
+}
+
+/*
+ * Return number of received (decrypted) bytes
+ * or <0 on error
+ */
+static ssize_t sftp_recv(struct connectdata *conn, int sockindex,
+                         char *mem, size_t len, CURLcode *err)
+{
+  ssize_t nread;
+  (void)sockindex;
+
+  DEBUGASSERT(len < CURL_MAX_READ_SIZE);
+
+  switch(conn->proto.sshc.sftp_recv_state) {
+    case 0:
+      conn->proto.sshc.sftp_file_index =
+            sftp_async_read_begin(conn->proto.sshc.sftp_file,
+                                  (uint32_t)len);
+      if(conn->proto.sshc.sftp_file_index < 0) {
+        *err = CURLE_RECV_ERROR;
+        return -1;
+      }
+
+      /* FALLTHROUGH */
+    case 1:
+      conn->proto.sshc.sftp_recv_state = 1;
+
+      nread = sftp_async_read(conn->proto.sshc.sftp_file,
+                              mem, (uint32_t)len,
+                              conn->proto.sshc.sftp_file_index);
+
+      myssh_block2waitfor(conn, (nread == SSH_AGAIN)?TRUE:FALSE);
+
+      if(nread == SSH_AGAIN) {
+        *err = CURLE_AGAIN;
+        return -1;
+      }
+      else if(nread < 0) {
+        *err = CURLE_RECV_ERROR;
+        return -1;
+      }
+
+      conn->proto.sshc.sftp_recv_state = 0;
+      return nread;
+
+    default:
+      /* we never reach here */
+      return -1;
+  }
+}
+
+static void sftp_quote(struct connectdata *conn)
+{
+  const char *cp;
+  struct Curl_easy *data = conn->data;
+  struct SSHPROTO *protop = data->req.protop;
+  struct ssh_conn *sshc = &conn->proto.sshc;
+  CURLcode result;
+
+  /*
+   * Support some of the "FTP" commands
+   */
+  char *cmd = sshc->quote_item->data;
+  sshc->acceptfail = FALSE;
+
+  /* if a command starts with an asterisk, which a legal SFTP command never
+     can, the command will be allowed to fail without it causing any
+     aborts or cancels etc. It will cause libcurl to act as if the command
+     is successful, whatever the server reponds. */
+
+  if(cmd[0] == '*') {
+    cmd++;
+    sshc->acceptfail = TRUE;
+  }
+
+  if(strcasecompare("pwd", cmd)) {
+    /* output debug output if that is requested */
+    char *tmp = aprintf("257 \"%s\" is current directory.\n",
+                        protop->path);
+    if(!tmp) {
+      sshc->actualcode = CURLE_OUT_OF_MEMORY;
+      state(conn, SSH_SFTP_CLOSE);
+      sshc->nextstate = SSH_NO_STATE;
+      return;
+    }
+    if(data->set.verbose) {
+      Curl_debug(data, CURLINFO_HEADER_OUT, (char *) "PWD\n", 4);
+      Curl_debug(data, CURLINFO_HEADER_IN, tmp, strlen(tmp));
+    }
+    /* this sends an FTP-like "header" to the header callback so that the
+       current directory can be read very similar to how it is read when
+       using ordinary FTP. */
+    result = Curl_client_write(conn, CLIENTWRITE_HEADER, tmp, strlen(tmp));
+    free(tmp);
+    if(result) {
+      state(conn, SSH_SFTP_CLOSE);
+      sshc->nextstate = SSH_NO_STATE;
+      sshc->actualcode = result;
+    }
+    else
+      state(conn, SSH_SFTP_NEXT_QUOTE);
+    return;
+  }
+
+  /*
+   * the arguments following the command must be separated from the
+   * command with a space so we can check for it unconditionally
+   */
+  cp = strchr(cmd, ' ');
+  if(cp == NULL) {
+    failf(data, "Syntax error in SFTP command. Supply parameter(s)!");
+    state(conn, SSH_SFTP_CLOSE);
+    sshc->nextstate = SSH_NO_STATE;
+    sshc->actualcode = CURLE_QUOTE_ERROR;
+    return;
+  }
+
+  /*
+   * also, every command takes at least one argument so we get that
+   * first argument right now
+   */
+  result = Curl_get_pathname(&cp, &sshc->quote_path1, sshc->homedir);
+  if(result) {
+    if(result == CURLE_OUT_OF_MEMORY)
+      failf(data, "Out of memory");
+    else
+      failf(data, "Syntax error: Bad first parameter");
+    state(conn, SSH_SFTP_CLOSE);
+    sshc->nextstate = SSH_NO_STATE;
+    sshc->actualcode = result;
+    return;
+  }
+
+  /*
+   * SFTP is a binary protocol, so we don't send text commands
+   * to the server. Instead, we scan for commands used by
+   * OpenSSH's sftp program and call the appropriate libssh
+   * functions.
+   */
+  if(strncasecompare(cmd, "chgrp ", 6) ||
+     strncasecompare(cmd, "chmod ", 6) ||
+     strncasecompare(cmd, "chown ", 6)) {
+    /* attribute change */
+
+    /* sshc->quote_path1 contains the mode to set */
+    /* get the destination */
+    result = Curl_get_pathname(&cp, &sshc->quote_path2, sshc->homedir);
+    if(result) {
+      if(result == CURLE_OUT_OF_MEMORY)
+        failf(data, "Out of memory");
+      else
+        failf(data, "Syntax error in chgrp/chmod/chown: "
+              "Bad second parameter");
+      Curl_safefree(sshc->quote_path1);
+      state(conn, SSH_SFTP_CLOSE);
+      sshc->nextstate = SSH_NO_STATE;
+      sshc->actualcode = result;
+      return;
+    }
+    sshc->quote_attrs = NULL;
+    state(conn, SSH_SFTP_QUOTE_STAT);
+    return;
+  }
+  if(strncasecompare(cmd, "ln ", 3) ||
+     strncasecompare(cmd, "symlink ", 8)) {
+    /* symbolic linking */
+    /* sshc->quote_path1 is the source */
+    /* get the destination */
+    result = Curl_get_pathname(&cp, &sshc->quote_path2, sshc->homedir);
+    if(result) {
+      if(result == CURLE_OUT_OF_MEMORY)
+        failf(data, "Out of memory");
+      else
+        failf(data, "Syntax error in ln/symlink: Bad second parameter");
+      Curl_safefree(sshc->quote_path1);
+      state(conn, SSH_SFTP_CLOSE);
+      sshc->nextstate = SSH_NO_STATE;
+      sshc->actualcode = result;
+      return;
+    }
+    state(conn, SSH_SFTP_QUOTE_SYMLINK);
+    return;
+  }
+  else if(strncasecompare(cmd, "mkdir ", 6)) {
+    /* create dir */
+    state(conn, SSH_SFTP_QUOTE_MKDIR);
+    return;
+  }
+  else if(strncasecompare(cmd, "rename ", 7)) {
+    /* rename file */
+    /* first param is the source path */
+    /* second param is the dest. path */
+    result = Curl_get_pathname(&cp, &sshc->quote_path2, sshc->homedir);
+    if(result) {
+      if(result == CURLE_OUT_OF_MEMORY)
+        failf(data, "Out of memory");
+      else
+        failf(data, "Syntax error in rename: Bad second parameter");
+      Curl_safefree(sshc->quote_path1);
+      state(conn, SSH_SFTP_CLOSE);
+      sshc->nextstate = SSH_NO_STATE;
+      sshc->actualcode = result;
+      return;
+    }
+    state(conn, SSH_SFTP_QUOTE_RENAME);
+    return;
+  }
+  else if(strncasecompare(cmd, "rmdir ", 6)) {
+    /* delete dir */
+    state(conn, SSH_SFTP_QUOTE_RMDIR);
+    return;
+  }
+  else if(strncasecompare(cmd, "rm ", 3)) {
+    state(conn, SSH_SFTP_QUOTE_UNLINK);
+    return;
+  }
+#ifdef HAS_STATVFS_SUPPORT
+  else if(strncasecompare(cmd, "statvfs ", 8)) {
+    state(conn, SSH_SFTP_QUOTE_STATVFS);
+    return;
+  }
+#endif
+
+  failf(data, "Unknown SFTP command");
+  Curl_safefree(sshc->quote_path1);
+  Curl_safefree(sshc->quote_path2);
+  state(conn, SSH_SFTP_CLOSE);
+  sshc->nextstate = SSH_NO_STATE;
+  sshc->actualcode = CURLE_QUOTE_ERROR;
+}
+
+static void sftp_quote_stat(struct connectdata *conn)
+{
+  struct Curl_easy *data = conn->data;
+  struct ssh_conn *sshc = &conn->proto.sshc;
+  char *cmd = sshc->quote_item->data;
+  sshc->acceptfail = FALSE;
+
+  /* if a command starts with an asterisk, which a legal SFTP command never
+     can, the command will be allowed to fail without it causing any
+     aborts or cancels etc. It will cause libcurl to act as if the command
+     is successful, whatever the server reponds. */
+
+  if(cmd[0] == '*') {
+    cmd++;
+    sshc->acceptfail = TRUE;
+  }
+
+  /* We read the file attributes, store them in sshc->quote_attrs
+   * and modify them accordingly to command. Then we switch to
+   * QUOTE_SETSTAT state to write new ones.
+   */
+
+  if(sshc->quote_attrs)
+    sftp_attributes_free(sshc->quote_attrs);
+  sshc->quote_attrs = sftp_stat(sshc->sftp_session, sshc->quote_path2);
+  if(sshc->quote_attrs == NULL) {
+    Curl_safefree(sshc->quote_path1);
+    Curl_safefree(sshc->quote_path2);
+    failf(data, "Attempt to get SFTP stats failed: %d",
+          sftp_get_error(sshc->sftp_session));
+    state(conn, SSH_SFTP_CLOSE);
+    sshc->nextstate = SSH_NO_STATE;
+    sshc->actualcode = CURLE_QUOTE_ERROR;
+    return;
+  }
+
+  /* Now set the new attributes... */
+  if(strncasecompare(cmd, "chgrp", 5)) {
+    sshc->quote_attrs->gid = (uint32_t)strtoul(sshc->quote_path1, NULL, 10);
+    if(sshc->quote_attrs->gid == 0 && !ISDIGIT(sshc->quote_path1[0]) &&
+        !sshc->acceptfail) {
+      Curl_safefree(sshc->quote_path1);
+      Curl_safefree(sshc->quote_path2);
+      failf(data, "Syntax error: chgrp gid not a number");
+      state(conn, SSH_SFTP_CLOSE);
+      sshc->nextstate = SSH_NO_STATE;
+      sshc->actualcode = CURLE_QUOTE_ERROR;
+      return;
+    }
+    sshc->quote_attrs->flags |= SSH_FILEXFER_ATTR_UIDGID;
+  }
+  else if(strncasecompare(cmd, "chmod", 5)) {
+    mode_t perms;
+    perms = (mode_t)strtoul(sshc->quote_path1, NULL, 8);
+    /* permissions are octal */
+    if(perms == 0 && !ISDIGIT(sshc->quote_path1[0])) {
+      Curl_safefree(sshc->quote_path1);
+      Curl_safefree(sshc->quote_path2);
+      failf(data, "Syntax error: chmod permissions not a number");
+      state(conn, SSH_SFTP_CLOSE);
+      sshc->nextstate = SSH_NO_STATE;
+      sshc->actualcode = CURLE_QUOTE_ERROR;
+      return;
+    }
+    sshc->quote_attrs->permissions = perms;
+    sshc->quote_attrs->flags |= SSH_FILEXFER_ATTR_PERMISSIONS;
+  }
+  else if(strncasecompare(cmd, "chown", 5)) {
+    sshc->quote_attrs->uid = (uint32_t)strtoul(sshc->quote_path1, NULL, 10);
+    if(sshc->quote_attrs->uid == 0 && !ISDIGIT(sshc->quote_path1[0]) &&
+        !sshc->acceptfail) {
+      Curl_safefree(sshc->quote_path1);
+      Curl_safefree(sshc->quote_path2);
+      failf(data, "Syntax error: chown uid not a number");
+      state(conn, SSH_SFTP_CLOSE);
+      sshc->nextstate = SSH_NO_STATE;
+      sshc->actualcode = CURLE_QUOTE_ERROR;
+      return;
+    }
+    sshc->quote_attrs->flags |= SSH_FILEXFER_ATTR_UIDGID;
+  }
+
+  /* Now send the completed structure... */
+  state(conn, SSH_SFTP_QUOTE_SETSTAT);
+  return;
+}
+
+CURLcode Curl_ssh_init(void)
+{
+  if(ssh_init()) {
+    DEBUGF(fprintf(stderr, "Error: libssh_init failed\n"));
+    return CURLE_FAILED_INIT;
+  }
+  return CURLE_OK;
+}
+
+void Curl_ssh_cleanup(void)
+{
+  (void)ssh_finalize();
+}
+
+size_t Curl_ssh_version(char *buffer, size_t buflen)
+{
+  return msnprintf(buffer, buflen, "libssh/%s", CURL_LIBSSH_VERSION);
+}
+
+#endif                          /* USE_LIBSSH */
diff --git a/Utilities/cmcurl/lib/vssh/libssh2.c b/Utilities/cmcurl/lib/vssh/libssh2.c
new file mode 100644
index 0000000..555afc9
--- /dev/null
+++ b/Utilities/cmcurl/lib/vssh/libssh2.c
@@ -0,0 +1,3497 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+/* #define CURL_LIBSSH2_DEBUG */
+
+#include "curl_setup.h"
+
+#ifdef USE_LIBSSH2
+
+#include <limits.h>
+
+#include <libssh2.h>
+#include <libssh2_sftp.h>
+
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#ifdef HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+#ifdef HAVE_UTSNAME_H
+#include <sys/utsname.h>
+#endif
+#ifdef HAVE_NETDB_H
+#include <netdb.h>
+#endif
+#ifdef __VMS
+#include <in.h>
+#include <inet.h>
+#endif
+
+#if (defined(NETWARE) && defined(__NOVELL_LIBC__))
+#undef in_addr_t
+#define in_addr_t unsigned long
+#endif
+
+#include <curl/curl.h>
+#include "urldata.h"
+#include "sendf.h"
+#include "hostip.h"
+#include "progress.h"
+#include "transfer.h"
+#include "escape.h"
+#include "http.h" /* for HTTP proxy tunnel stuff */
+#include "ssh.h"
+#include "url.h"
+#include "speedcheck.h"
+#include "getinfo.h"
+#include "strdup.h"
+#include "strcase.h"
+#include "vtls/vtls.h"
+#include "connect.h"
+#include "strerror.h"
+#include "inet_ntop.h"
+#include "parsedate.h" /* for the week day and month names */
+#include "sockaddr.h" /* required for Curl_sockaddr_storage */
+#include "strtoofft.h"
+#include "multiif.h"
+#include "select.h"
+#include "warnless.h"
+#include "curl_path.h"
+
+/* The last 3 #include files should be in this order */
+#include "curl_printf.h"
+#include "curl_memory.h"
+#include "memdebug.h"
+
+#if LIBSSH2_VERSION_NUM >= 0x010206
+/* libssh2_sftp_statvfs and friends were added in 1.2.6 */
+#define HAS_STATVFS_SUPPORT 1
+#endif
+
+#define sftp_libssh2_realpath(s,p,t,m)                          \
+  libssh2_sftp_symlink_ex((s), (p), curlx_uztoui(strlen(p)),    \
+                          (t), (m), LIBSSH2_SFTP_REALPATH)
+
+/* Local functions: */
+static const char *sftp_libssh2_strerror(unsigned long err);
+static LIBSSH2_ALLOC_FUNC(my_libssh2_malloc);
+static LIBSSH2_REALLOC_FUNC(my_libssh2_realloc);
+static LIBSSH2_FREE_FUNC(my_libssh2_free);
+
+static CURLcode ssh_force_knownhost_key_type(struct connectdata *conn);
+static CURLcode ssh_connect(struct connectdata *conn, bool *done);
+static CURLcode ssh_multi_statemach(struct connectdata *conn, bool *done);
+static CURLcode ssh_do(struct connectdata *conn, bool *done);
+
+static CURLcode scp_done(struct connectdata *conn,
+                         CURLcode, bool premature);
+static CURLcode scp_doing(struct connectdata *conn,
+                          bool *dophase_done);
+static CURLcode scp_disconnect(struct connectdata *conn, bool dead_connection);
+
+static CURLcode sftp_done(struct connectdata *conn,
+                          CURLcode, bool premature);
+static CURLcode sftp_doing(struct connectdata *conn,
+                           bool *dophase_done);
+static CURLcode sftp_disconnect(struct connectdata *conn, bool dead);
+static
+CURLcode sftp_perform(struct connectdata *conn,
+                      bool *connected,
+                      bool *dophase_done);
+static int ssh_getsock(struct connectdata *conn, curl_socket_t *sock);
+static int ssh_perform_getsock(const struct connectdata *conn,
+                               curl_socket_t *sock);
+static CURLcode ssh_setup_connection(struct connectdata *conn);
+
+/*
+ * SCP protocol handler.
+ */
+
+const struct Curl_handler Curl_handler_scp = {
+  "SCP",                                /* scheme */
+  ssh_setup_connection,                 /* setup_connection */
+  ssh_do,                               /* do_it */
+  scp_done,                             /* done */
+  ZERO_NULL,                            /* do_more */
+  ssh_connect,                          /* connect_it */
+  ssh_multi_statemach,                  /* connecting */
+  scp_doing,                            /* doing */
+  ssh_getsock,                          /* proto_getsock */
+  ssh_getsock,                          /* doing_getsock */
+  ZERO_NULL,                            /* domore_getsock */
+  ssh_perform_getsock,                  /* perform_getsock */
+  scp_disconnect,                       /* disconnect */
+  ZERO_NULL,                            /* readwrite */
+  ZERO_NULL,                            /* connection_check */
+  PORT_SSH,                             /* defport */
+  CURLPROTO_SCP,                        /* protocol */
+  PROTOPT_DIRLOCK | PROTOPT_CLOSEACTION
+  | PROTOPT_NOURLQUERY                  /* flags */
+};
+
+
+/*
+ * SFTP protocol handler.
+ */
+
+const struct Curl_handler Curl_handler_sftp = {
+  "SFTP",                               /* scheme */
+  ssh_setup_connection,                 /* setup_connection */
+  ssh_do,                               /* do_it */
+  sftp_done,                            /* done */
+  ZERO_NULL,                            /* do_more */
+  ssh_connect,                          /* connect_it */
+  ssh_multi_statemach,                  /* connecting */
+  sftp_doing,                           /* doing */
+  ssh_getsock,                          /* proto_getsock */
+  ssh_getsock,                          /* doing_getsock */
+  ZERO_NULL,                            /* domore_getsock */
+  ssh_perform_getsock,                  /* perform_getsock */
+  sftp_disconnect,                      /* disconnect */
+  ZERO_NULL,                            /* readwrite */
+  ZERO_NULL,                            /* connection_check */
+  PORT_SSH,                             /* defport */
+  CURLPROTO_SFTP,                       /* protocol */
+  PROTOPT_DIRLOCK | PROTOPT_CLOSEACTION
+  | PROTOPT_NOURLQUERY                  /* flags */
+};
+
+static void
+kbd_callback(const char *name, int name_len, const char *instruction,
+             int instruction_len, int num_prompts,
+             const LIBSSH2_USERAUTH_KBDINT_PROMPT *prompts,
+             LIBSSH2_USERAUTH_KBDINT_RESPONSE *responses,
+             void **abstract)
+{
+  struct connectdata *conn = (struct connectdata *)*abstract;
+
+#ifdef CURL_LIBSSH2_DEBUG
+  fprintf(stderr, "name=%s\n", name);
+  fprintf(stderr, "name_len=%d\n", name_len);
+  fprintf(stderr, "instruction=%s\n", instruction);
+  fprintf(stderr, "instruction_len=%d\n", instruction_len);
+  fprintf(stderr, "num_prompts=%d\n", num_prompts);
+#else
+  (void)name;
+  (void)name_len;
+  (void)instruction;
+  (void)instruction_len;
+#endif  /* CURL_LIBSSH2_DEBUG */
+  if(num_prompts == 1) {
+    responses[0].text = strdup(conn->passwd);
+    responses[0].length = curlx_uztoui(strlen(conn->passwd));
+  }
+  (void)prompts;
+  (void)abstract;
+} /* kbd_callback */
+
+static CURLcode sftp_libssh2_error_to_CURLE(unsigned long err)
+{
+  switch(err) {
+    case LIBSSH2_FX_OK:
+      return CURLE_OK;
+
+    case LIBSSH2_FX_NO_SUCH_FILE:
+    case LIBSSH2_FX_NO_SUCH_PATH:
+      return CURLE_REMOTE_FILE_NOT_FOUND;
+
+    case LIBSSH2_FX_PERMISSION_DENIED:
+    case LIBSSH2_FX_WRITE_PROTECT:
+    case LIBSSH2_FX_LOCK_CONFlICT:
+      return CURLE_REMOTE_ACCESS_DENIED;
+
+    case LIBSSH2_FX_NO_SPACE_ON_FILESYSTEM:
+    case LIBSSH2_FX_QUOTA_EXCEEDED:
+      return CURLE_REMOTE_DISK_FULL;
+
+    case LIBSSH2_FX_FILE_ALREADY_EXISTS:
+      return CURLE_REMOTE_FILE_EXISTS;
+
+    case LIBSSH2_FX_DIR_NOT_EMPTY:
+      return CURLE_QUOTE_ERROR;
+
+    default:
+      break;
+  }
+
+  return CURLE_SSH;
+}
+
+static CURLcode libssh2_session_error_to_CURLE(int err)
+{
+  switch(err) {
+    /* Ordered by order of appearance in libssh2.h */
+    case LIBSSH2_ERROR_NONE:
+      return CURLE_OK;
+
+    /* This is the error returned by libssh2_scp_recv2
+     * on unknown file */
+    case LIBSSH2_ERROR_SCP_PROTOCOL:
+      return CURLE_REMOTE_FILE_NOT_FOUND;
+
+    case LIBSSH2_ERROR_SOCKET_NONE:
+      return CURLE_COULDNT_CONNECT;
+
+    case LIBSSH2_ERROR_ALLOC:
+      return CURLE_OUT_OF_MEMORY;
+
+    case LIBSSH2_ERROR_SOCKET_SEND:
+      return CURLE_SEND_ERROR;
+
+    case LIBSSH2_ERROR_HOSTKEY_INIT:
+    case LIBSSH2_ERROR_HOSTKEY_SIGN:
+    case LIBSSH2_ERROR_PUBLICKEY_UNRECOGNIZED:
+    case LIBSSH2_ERROR_PUBLICKEY_UNVERIFIED:
+      return CURLE_PEER_FAILED_VERIFICATION;
+
+    case LIBSSH2_ERROR_PASSWORD_EXPIRED:
+      return CURLE_LOGIN_DENIED;
+
+    case LIBSSH2_ERROR_SOCKET_TIMEOUT:
+    case LIBSSH2_ERROR_TIMEOUT:
+      return CURLE_OPERATION_TIMEDOUT;
+
+    case LIBSSH2_ERROR_EAGAIN:
+      return CURLE_AGAIN;
+  }
+
+  return CURLE_SSH;
+}
+
+static LIBSSH2_ALLOC_FUNC(my_libssh2_malloc)
+{
+  (void)abstract; /* arg not used */
+  return malloc(count);
+}
+
+static LIBSSH2_REALLOC_FUNC(my_libssh2_realloc)
+{
+  (void)abstract; /* arg not used */
+  return realloc(ptr, count);
+}
+
+static LIBSSH2_FREE_FUNC(my_libssh2_free)
+{
+  (void)abstract; /* arg not used */
+  if(ptr) /* ssh2 agent sometimes call free with null ptr */
+    free(ptr);
+}
+
+/*
+ * SSH State machine related code
+ */
+/* This is the ONLY way to change SSH state! */
+static void state(struct connectdata *conn, sshstate nowstate)
+{
+  struct ssh_conn *sshc = &conn->proto.sshc;
+#if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS)
+  /* for debug purposes */
+  static const char * const names[] = {
+    "SSH_STOP",
+    "SSH_INIT",
+    "SSH_S_STARTUP",
+    "SSH_HOSTKEY",
+    "SSH_AUTHLIST",
+    "SSH_AUTH_PKEY_INIT",
+    "SSH_AUTH_PKEY",
+    "SSH_AUTH_PASS_INIT",
+    "SSH_AUTH_PASS",
+    "SSH_AUTH_AGENT_INIT",
+    "SSH_AUTH_AGENT_LIST",
+    "SSH_AUTH_AGENT",
+    "SSH_AUTH_HOST_INIT",
+    "SSH_AUTH_HOST",
+    "SSH_AUTH_KEY_INIT",
+    "SSH_AUTH_KEY",
+    "SSH_AUTH_GSSAPI",
+    "SSH_AUTH_DONE",
+    "SSH_SFTP_INIT",
+    "SSH_SFTP_REALPATH",
+    "SSH_SFTP_QUOTE_INIT",
+    "SSH_SFTP_POSTQUOTE_INIT",
+    "SSH_SFTP_QUOTE",
+    "SSH_SFTP_NEXT_QUOTE",
+    "SSH_SFTP_QUOTE_STAT",
+    "SSH_SFTP_QUOTE_SETSTAT",
+    "SSH_SFTP_QUOTE_SYMLINK",
+    "SSH_SFTP_QUOTE_MKDIR",
+    "SSH_SFTP_QUOTE_RENAME",
+    "SSH_SFTP_QUOTE_RMDIR",
+    "SSH_SFTP_QUOTE_UNLINK",
+    "SSH_SFTP_QUOTE_STATVFS",
+    "SSH_SFTP_GETINFO",
+    "SSH_SFTP_FILETIME",
+    "SSH_SFTP_TRANS_INIT",
+    "SSH_SFTP_UPLOAD_INIT",
+    "SSH_SFTP_CREATE_DIRS_INIT",
+    "SSH_SFTP_CREATE_DIRS",
+    "SSH_SFTP_CREATE_DIRS_MKDIR",
+    "SSH_SFTP_READDIR_INIT",
+    "SSH_SFTP_READDIR",
+    "SSH_SFTP_READDIR_LINK",
+    "SSH_SFTP_READDIR_BOTTOM",
+    "SSH_SFTP_READDIR_DONE",
+    "SSH_SFTP_DOWNLOAD_INIT",
+    "SSH_SFTP_DOWNLOAD_STAT",
+    "SSH_SFTP_CLOSE",
+    "SSH_SFTP_SHUTDOWN",
+    "SSH_SCP_TRANS_INIT",
+    "SSH_SCP_UPLOAD_INIT",
+    "SSH_SCP_DOWNLOAD_INIT",
+    "SSH_SCP_DOWNLOAD",
+    "SSH_SCP_DONE",
+    "SSH_SCP_SEND_EOF",
+    "SSH_SCP_WAIT_EOF",
+    "SSH_SCP_WAIT_CLOSE",
+    "SSH_SCP_CHANNEL_FREE",
+    "SSH_SESSION_DISCONNECT",
+    "SSH_SESSION_FREE",
+    "QUIT"
+  };
+
+  /* a precaution to make sure the lists are in sync */
+  DEBUGASSERT(sizeof(names)/sizeof(names[0]) == SSH_LAST);
+
+  if(sshc->state != nowstate) {
+    infof(conn->data, "SFTP %p state change from %s to %s\n",
+          (void *)sshc, names[sshc->state], names[nowstate]);
+  }
+#endif
+
+  sshc->state = nowstate;
+}
+
+
+#ifdef HAVE_LIBSSH2_KNOWNHOST_API
+static int sshkeycallback(struct Curl_easy *easy,
+                          const struct curl_khkey *knownkey, /* known */
+                          const struct curl_khkey *foundkey, /* found */
+                          enum curl_khmatch match,
+                          void *clientp)
+{
+  (void)easy;
+  (void)knownkey;
+  (void)foundkey;
+  (void)clientp;
+
+  /* we only allow perfect matches, and we reject everything else */
+  return (match != CURLKHMATCH_OK)?CURLKHSTAT_REJECT:CURLKHSTAT_FINE;
+}
+#endif
+
+/*
+ * Earlier libssh2 versions didn't have the ability to seek to 64bit positions
+ * with 32bit size_t.
+ */
+#ifdef HAVE_LIBSSH2_SFTP_SEEK64
+#define SFTP_SEEK(x,y) libssh2_sftp_seek64(x, (libssh2_uint64_t)y)
+#else
+#define SFTP_SEEK(x,y) libssh2_sftp_seek(x, (size_t)y)
+#endif
+
+/*
+ * Earlier libssh2 versions didn't do SCP properly beyond 32bit sizes on 32bit
+ * architectures so we check of the necessary function is present.
+ */
+#ifndef HAVE_LIBSSH2_SCP_SEND64
+#define SCP_SEND(a,b,c,d) libssh2_scp_send_ex(a, b, (int)(c), (size_t)d, 0, 0)
+#else
+#define SCP_SEND(a,b,c,d) libssh2_scp_send64(a, b, (int)(c),            \
+                                             (libssh2_uint64_t)d, 0, 0)
+#endif
+
+/*
+ * libssh2 1.2.8 fixed the problem with 32bit ints used for sockets on win64.
+ */
+#ifdef HAVE_LIBSSH2_SESSION_HANDSHAKE
+#define libssh2_session_startup(x,y) libssh2_session_handshake(x,y)
+#endif
+
+static CURLcode ssh_knownhost(struct connectdata *conn)
+{
+  CURLcode result = CURLE_OK;
+
+#ifdef HAVE_LIBSSH2_KNOWNHOST_API
+  struct Curl_easy *data = conn->data;
+
+  if(data->set.str[STRING_SSH_KNOWNHOSTS]) {
+    /* we're asked to verify the host against a file */
+    struct ssh_conn *sshc = &conn->proto.sshc;
+    int rc;
+    int keytype;
+    size_t keylen;
+    const char *remotekey = libssh2_session_hostkey(sshc->ssh_session,
+                                                    &keylen, &keytype);
+    int keycheck = LIBSSH2_KNOWNHOST_CHECK_FAILURE;
+    int keybit = 0;
+
+    if(remotekey) {
+      /*
+       * A subject to figure out is what host name we need to pass in here.
+       * What host name does OpenSSH store in its file if an IDN name is
+       * used?
+       */
+      struct libssh2_knownhost *host;
+      enum curl_khmatch keymatch;
+      curl_sshkeycallback func =
+        data->set.ssh_keyfunc?data->set.ssh_keyfunc:sshkeycallback;
+      struct curl_khkey knownkey;
+      struct curl_khkey *knownkeyp = NULL;
+      struct curl_khkey foundkey;
+
+      switch(keytype) {
+      case LIBSSH2_HOSTKEY_TYPE_RSA:
+        keybit = LIBSSH2_KNOWNHOST_KEY_SSHRSA;
+        break;
+      case LIBSSH2_HOSTKEY_TYPE_DSS:
+        keybit = LIBSSH2_KNOWNHOST_KEY_SSHDSS;
+        break;
+#ifdef LIBSSH2_HOSTKEY_TYPE_ECDSA_256
+      case LIBSSH2_HOSTKEY_TYPE_ECDSA_256:
+        keybit = LIBSSH2_KNOWNHOST_KEY_ECDSA_256;
+        break;
+#endif
+#ifdef LIBSSH2_HOSTKEY_TYPE_ECDSA_384
+      case LIBSSH2_HOSTKEY_TYPE_ECDSA_384:
+        keybit = LIBSSH2_KNOWNHOST_KEY_ECDSA_384;
+        break;
+#endif
+#ifdef LIBSSH2_HOSTKEY_TYPE_ECDSA_521
+      case LIBSSH2_HOSTKEY_TYPE_ECDSA_521:
+        keybit = LIBSSH2_KNOWNHOST_KEY_ECDSA_521;
+        break;
+#endif
+#ifdef LIBSSH2_HOSTKEY_TYPE_ED25519
+      case LIBSSH2_HOSTKEY_TYPE_ED25519:
+        keybit = LIBSSH2_KNOWNHOST_KEY_ED25519;
+        break;
+#endif
+      default:
+        infof(data, "unsupported key type, can't check knownhosts!\n");
+        keybit = 0;
+        break;
+      }
+      if(!keybit)
+        /* no check means failure! */
+        rc = CURLKHSTAT_REJECT;
+      else {
+#ifdef HAVE_LIBSSH2_KNOWNHOST_CHECKP
+        keycheck = libssh2_knownhost_checkp(sshc->kh,
+                                            conn->host.name,
+                                            (conn->remote_port != PORT_SSH)?
+                                            conn->remote_port:-1,
+                                            remotekey, keylen,
+                                            LIBSSH2_KNOWNHOST_TYPE_PLAIN|
+                                            LIBSSH2_KNOWNHOST_KEYENC_RAW|
+                                            keybit,
+                                            &host);
+#else
+        keycheck = libssh2_knownhost_check(sshc->kh,
+                                           conn->host.name,
+                                           remotekey, keylen,
+                                           LIBSSH2_KNOWNHOST_TYPE_PLAIN|
+                                           LIBSSH2_KNOWNHOST_KEYENC_RAW|
+                                           keybit,
+                                           &host);
+#endif
+
+        infof(data, "SSH host check: %d, key: %s\n", keycheck,
+              (keycheck <= LIBSSH2_KNOWNHOST_CHECK_MISMATCH)?
+              host->key:"<none>");
+
+        /* setup 'knownkey' */
+        if(keycheck <= LIBSSH2_KNOWNHOST_CHECK_MISMATCH) {
+          knownkey.key = host->key;
+          knownkey.len = 0;
+          knownkey.keytype = (keytype == LIBSSH2_HOSTKEY_TYPE_RSA)?
+            CURLKHTYPE_RSA : CURLKHTYPE_DSS;
+          knownkeyp = &knownkey;
+        }
+
+        /* setup 'foundkey' */
+        foundkey.key = remotekey;
+        foundkey.len = keylen;
+        foundkey.keytype = (keytype == LIBSSH2_HOSTKEY_TYPE_RSA)?
+          CURLKHTYPE_RSA : CURLKHTYPE_DSS;
+
+        /*
+         * if any of the LIBSSH2_KNOWNHOST_CHECK_* defines and the
+         * curl_khmatch enum are ever modified, we need to introduce a
+         * translation table here!
+         */
+        keymatch = (enum curl_khmatch)keycheck;
+
+        /* Ask the callback how to behave */
+        Curl_set_in_callback(data, true);
+        rc = func(data, knownkeyp, /* from the knownhosts file */
+                  &foundkey, /* from the remote host */
+                  keymatch, data->set.ssh_keyfunc_userp);
+        Curl_set_in_callback(data, false);
+      }
+    }
+    else
+      /* no remotekey means failure! */
+      rc = CURLKHSTAT_REJECT;
+
+    switch(rc) {
+    default: /* unknown return codes will equal reject */
+      /* FALLTHROUGH */
+    case CURLKHSTAT_REJECT:
+      state(conn, SSH_SESSION_FREE);
+      /* FALLTHROUGH */
+    case CURLKHSTAT_DEFER:
+      /* DEFER means bail out but keep the SSH_HOSTKEY state */
+      result = sshc->actualcode = CURLE_PEER_FAILED_VERIFICATION;
+      break;
+    case CURLKHSTAT_FINE:
+    case CURLKHSTAT_FINE_ADD_TO_FILE:
+      /* proceed */
+      if(keycheck != LIBSSH2_KNOWNHOST_CHECK_MATCH) {
+        /* the found host+key didn't match but has been told to be fine
+           anyway so we add it in memory */
+        int addrc = libssh2_knownhost_add(sshc->kh,
+                                          conn->host.name, NULL,
+                                          remotekey, keylen,
+                                          LIBSSH2_KNOWNHOST_TYPE_PLAIN|
+                                          LIBSSH2_KNOWNHOST_KEYENC_RAW|
+                                          keybit, NULL);
+        if(addrc)
+          infof(data, "Warning adding the known host %s failed!\n",
+                conn->host.name);
+        else if(rc == CURLKHSTAT_FINE_ADD_TO_FILE) {
+          /* now we write the entire in-memory list of known hosts to the
+             known_hosts file */
+          int wrc =
+            libssh2_knownhost_writefile(sshc->kh,
+                                        data->set.str[STRING_SSH_KNOWNHOSTS],
+                                        LIBSSH2_KNOWNHOST_FILE_OPENSSH);
+          if(wrc) {
+            infof(data, "Warning, writing %s failed!\n",
+                  data->set.str[STRING_SSH_KNOWNHOSTS]);
+          }
+        }
+      }
+      break;
+    }
+  }
+#else /* HAVE_LIBSSH2_KNOWNHOST_API */
+  (void)conn;
+#endif
+  return result;
+}
+
+static CURLcode ssh_check_fingerprint(struct connectdata *conn)
+{
+  struct ssh_conn *sshc = &conn->proto.sshc;
+  struct Curl_easy *data = conn->data;
+  const char *pubkey_md5 = data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5];
+  char md5buffer[33];
+
+  const char *fingerprint = libssh2_hostkey_hash(sshc->ssh_session,
+      LIBSSH2_HOSTKEY_HASH_MD5);
+
+  if(fingerprint) {
+    /* The fingerprint points to static storage (!), don't free() it. */
+    int i;
+    for(i = 0; i < 16; i++)
+      msnprintf(&md5buffer[i*2], 3, "%02x", (unsigned char) fingerprint[i]);
+    infof(data, "SSH MD5 fingerprint: %s\n", md5buffer);
+  }
+
+  /* Before we authenticate we check the hostkey's MD5 fingerprint
+   * against a known fingerprint, if available.
+   */
+  if(pubkey_md5 && strlen(pubkey_md5) == 32) {
+    if(!fingerprint || !strcasecompare(md5buffer, pubkey_md5)) {
+      if(fingerprint)
+        failf(data,
+            "Denied establishing ssh session: mismatch md5 fingerprint. "
+            "Remote %s is not equal to %s", md5buffer, pubkey_md5);
+      else
+        failf(data,
+            "Denied establishing ssh session: md5 fingerprint not available");
+      state(conn, SSH_SESSION_FREE);
+      sshc->actualcode = CURLE_PEER_FAILED_VERIFICATION;
+      return sshc->actualcode;
+    }
+    infof(data, "MD5 checksum match!\n");
+    /* as we already matched, we skip the check for known hosts */
+    return CURLE_OK;
+  }
+  return ssh_knownhost(conn);
+}
+
+/*
+ * ssh_force_knownhost_key_type() will check the known hosts file and try to
+ * force a specific public key type from the server if an entry is found.
+ */
+static CURLcode ssh_force_knownhost_key_type(struct connectdata *conn)
+{
+  CURLcode result = CURLE_OK;
+
+#ifdef HAVE_LIBSSH2_KNOWNHOST_API
+
+#ifdef LIBSSH2_KNOWNHOST_KEY_ED25519
+  static const char * const hostkey_method_ssh_ed25519
+    = "ssh-ed25519";
+#endif
+#ifdef LIBSSH2_KNOWNHOST_KEY_ECDSA_521
+  static const char * const hostkey_method_ssh_ecdsa_521
+    = "ecdsa-sha2-nistp521";
+#endif
+#ifdef LIBSSH2_KNOWNHOST_KEY_ECDSA_384
+  static const char * const hostkey_method_ssh_ecdsa_384
+    = "ecdsa-sha2-nistp384";
+#endif
+#ifdef LIBSSH2_KNOWNHOST_KEY_ECDSA_256
+  static const char * const hostkey_method_ssh_ecdsa_256
+    = "ecdsa-sha2-nistp256";
+#endif
+  static const char * const hostkey_method_ssh_rsa
+    = "ssh-rsa";
+  static const char * const hostkey_method_ssh_dss
+    = "ssh-dss";
+
+  const char *hostkey_method = NULL;
+  struct ssh_conn *sshc = &conn->proto.sshc;
+  struct Curl_easy *data = conn->data;
+  struct libssh2_knownhost* store = NULL;
+  const char *kh_name_end = NULL;
+  size_t kh_name_size = 0;
+  int port = 0;
+  bool found = false;
+
+  if(sshc->kh && !data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5]) {
+    /* lets try to find our host in the known hosts file */
+    while(!libssh2_knownhost_get(sshc->kh, &store, store)) {
+      /* For non-standard ports, the name will be enclosed in */
+      /* square brackets, followed by a colon and the port */
+      if(store) {
+        if(store->name) {
+          if(store->name[0] == '[') {
+            kh_name_end = strstr(store->name, "]:");
+            if(!kh_name_end) {
+              infof(data, "Invalid host pattern %s in %s\n",
+                    store->name, data->set.str[STRING_SSH_KNOWNHOSTS]);
+              continue;
+            }
+            port = atoi(kh_name_end + 2);
+            if(kh_name_end && (port == conn->remote_port)) {
+              kh_name_size = strlen(store->name) - 1 - strlen(kh_name_end);
+              if(strncmp(store->name + 1,
+                 conn->host.name, kh_name_size) == 0) {
+                found = true;
+                break;
+              }
+            }
+          }
+          else if(strcmp(store->name, conn->host.name) == 0) {
+            found = true;
+            break;
+          }
+        }
+        else {
+          found = true;
+          break;
+        }
+      }
+    }
+
+    if(found) {
+      infof(data, "Found host %s in %s\n",
+            conn->host.name, data->set.str[STRING_SSH_KNOWNHOSTS]);
+
+      switch(store->typemask & LIBSSH2_KNOWNHOST_KEY_MASK) {
+#ifdef LIBSSH2_KNOWNHOST_KEY_ED25519
+      case LIBSSH2_KNOWNHOST_KEY_ED25519:
+        hostkey_method = hostkey_method_ssh_ed25519;
+        break;
+#endif
+#ifdef LIBSSH2_KNOWNHOST_KEY_ECDSA_521
+      case LIBSSH2_KNOWNHOST_KEY_ECDSA_521:
+        hostkey_method = hostkey_method_ssh_ecdsa_521;
+        break;
+#endif
+#ifdef LIBSSH2_KNOWNHOST_KEY_ECDSA_384
+      case LIBSSH2_KNOWNHOST_KEY_ECDSA_384:
+        hostkey_method = hostkey_method_ssh_ecdsa_384;
+        break;
+#endif
+#ifdef LIBSSH2_KNOWNHOST_KEY_ECDSA_256
+      case LIBSSH2_KNOWNHOST_KEY_ECDSA_256:
+        hostkey_method = hostkey_method_ssh_ecdsa_256;
+        break;
+#endif
+      case LIBSSH2_KNOWNHOST_KEY_SSHRSA:
+        hostkey_method = hostkey_method_ssh_rsa;
+        break;
+      case LIBSSH2_KNOWNHOST_KEY_SSHDSS:
+        hostkey_method = hostkey_method_ssh_dss;
+        break;
+      case LIBSSH2_KNOWNHOST_KEY_RSA1:
+        failf(data, "Found host key type RSA1 which is not supported\n");
+        return CURLE_SSH;
+      default:
+        failf(data, "Unknown host key type: %i\n",
+              (store->typemask & LIBSSH2_KNOWNHOST_KEY_MASK));
+        return CURLE_SSH;
+      }
+
+      infof(data, "Set \"%s\" as SSH hostkey type\n", hostkey_method);
+      result = libssh2_session_error_to_CURLE(
+          libssh2_session_method_pref(
+              sshc->ssh_session, LIBSSH2_METHOD_HOSTKEY, hostkey_method));
+    }
+    else {
+      infof(data, "Did not find host %s in %s\n",
+            conn->host.name, data->set.str[STRING_SSH_KNOWNHOSTS]);
+    }
+  }
+
+#endif /* HAVE_LIBSSH2_KNOWNHOST_API */
+
+  return result;
+}
+
+/*
+ * ssh_statemach_act() runs the SSH state machine as far as it can without
+ * blocking and without reaching the end.  The data the pointer 'block' points
+ * to will be set to TRUE if the libssh2 function returns LIBSSH2_ERROR_EAGAIN
+ * meaning it wants to be called again when the socket is ready
+ */
+
+static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
+{
+  CURLcode result = CURLE_OK;
+  struct Curl_easy *data = conn->data;
+  struct SSHPROTO *sftp_scp = data->req.protop;
+  struct ssh_conn *sshc = &conn->proto.sshc;
+  curl_socket_t sock = conn->sock[FIRSTSOCKET];
+  int rc = LIBSSH2_ERROR_NONE;
+  int ssherr;
+  unsigned long sftperr;
+  int seekerr = CURL_SEEKFUNC_OK;
+  size_t readdir_len;
+  *block = 0; /* we're not blocking by default */
+
+  do {
+
+    switch(sshc->state) {
+    case SSH_INIT:
+      sshc->secondCreateDirs = 0;
+      sshc->nextstate = SSH_NO_STATE;
+      sshc->actualcode = CURLE_OK;
+
+      /* Set libssh2 to non-blocking, since everything internally is
+         non-blocking */
+      libssh2_session_set_blocking(sshc->ssh_session, 0);
+
+      result = ssh_force_knownhost_key_type(conn);
+      if(result) {
+        state(conn, SSH_SESSION_FREE);
+        break;
+      }
+
+      state(conn, SSH_S_STARTUP);
+      /* FALLTHROUGH */
+
+    case SSH_S_STARTUP:
+      rc = libssh2_session_startup(sshc->ssh_session, (int)sock);
+      if(rc == LIBSSH2_ERROR_EAGAIN) {
+        break;
+      }
+      if(rc) {
+        char *err_msg = NULL;
+        (void)libssh2_session_last_error(sshc->ssh_session, &err_msg, NULL, 0);
+        failf(data, "Failure establishing ssh session: %d, %s", rc, err_msg);
+
+        state(conn, SSH_SESSION_FREE);
+        sshc->actualcode = CURLE_FAILED_INIT;
+        break;
+      }
+
+      state(conn, SSH_HOSTKEY);
+
+      /* FALLTHROUGH */
+    case SSH_HOSTKEY:
+      /*
+       * Before we authenticate we should check the hostkey's fingerprint
+       * against our known hosts. How that is handled (reading from file,
+       * whatever) is up to us.
+       */
+      result = ssh_check_fingerprint(conn);
+      if(!result)
+        state(conn, SSH_AUTHLIST);
+      /* ssh_check_fingerprint sets state appropriately on error */
+      break;
+
+    case SSH_AUTHLIST:
+      /*
+       * Figure out authentication methods
+       * NB: As soon as we have provided a username to an openssh server we
+       * must never change it later. Thus, always specify the correct username
+       * here, even though the libssh2 docs kind of indicate that it should be
+       * possible to get a 'generic' list (not user-specific) of authentication
+       * methods, presumably with a blank username. That won't work in my
+       * experience.
+       * So always specify it here.
+       */
+      sshc->authlist = libssh2_userauth_list(sshc->ssh_session,
+                                             conn->user,
+                                             curlx_uztoui(strlen(conn->user)));
+
+      if(!sshc->authlist) {
+        if(libssh2_userauth_authenticated(sshc->ssh_session)) {
+          sshc->authed = TRUE;
+          infof(data, "SSH user accepted with no authentication\n");
+          state(conn, SSH_AUTH_DONE);
+          break;
+        }
+        ssherr = libssh2_session_last_errno(sshc->ssh_session);
+        if(ssherr == LIBSSH2_ERROR_EAGAIN)
+          rc = LIBSSH2_ERROR_EAGAIN;
+        else {
+          state(conn, SSH_SESSION_FREE);
+          sshc->actualcode = libssh2_session_error_to_CURLE(ssherr);
+        }
+        break;
+      }
+      infof(data, "SSH authentication methods available: %s\n",
+            sshc->authlist);
+
+      state(conn, SSH_AUTH_PKEY_INIT);
+      break;
+
+    case SSH_AUTH_PKEY_INIT:
+      /*
+       * Check the supported auth types in the order I feel is most secure
+       * with the requested type of authentication
+       */
+      sshc->authed = FALSE;
+
+      if((data->set.ssh_auth_types & CURLSSH_AUTH_PUBLICKEY) &&
+         (strstr(sshc->authlist, "publickey") != NULL)) {
+        bool out_of_memory = FALSE;
+
+        sshc->rsa_pub = sshc->rsa = NULL;
+
+        if(data->set.str[STRING_SSH_PRIVATE_KEY])
+          sshc->rsa = strdup(data->set.str[STRING_SSH_PRIVATE_KEY]);
+        else {
+          /* To ponder about: should really the lib be messing about with the
+             HOME environment variable etc? */
+          char *home = curl_getenv("HOME");
+
+          /* If no private key file is specified, try some common paths. */
+          if(home) {
+            /* Try ~/.ssh first. */
+            sshc->rsa = aprintf("%s/.ssh/id_rsa", home);
+            if(!sshc->rsa)
+              out_of_memory = TRUE;
+            else if(access(sshc->rsa, R_OK) != 0) {
+              Curl_safefree(sshc->rsa);
+              sshc->rsa = aprintf("%s/.ssh/id_dsa", home);
+              if(!sshc->rsa)
+                out_of_memory = TRUE;
+              else if(access(sshc->rsa, R_OK) != 0) {
+                Curl_safefree(sshc->rsa);
+              }
+            }
+            free(home);
+          }
+          if(!out_of_memory && !sshc->rsa) {
+            /* Nothing found; try the current dir. */
+            sshc->rsa = strdup("id_rsa");
+            if(sshc->rsa && access(sshc->rsa, R_OK) != 0) {
+              Curl_safefree(sshc->rsa);
+              sshc->rsa = strdup("id_dsa");
+              if(sshc->rsa && access(sshc->rsa, R_OK) != 0) {
+                Curl_safefree(sshc->rsa);
+                /* Out of guesses. Set to the empty string to avoid
+                 * surprising info messages. */
+                sshc->rsa = strdup("");
+              }
+            }
+          }
+        }
+
+        /*
+         * Unless the user explicitly specifies a public key file, let
+         * libssh2 extract the public key from the private key file.
+         * This is done by simply passing sshc->rsa_pub = NULL.
+         */
+        if(data->set.str[STRING_SSH_PUBLIC_KEY]
+           /* treat empty string the same way as NULL */
+           && data->set.str[STRING_SSH_PUBLIC_KEY][0]) {
+          sshc->rsa_pub = strdup(data->set.str[STRING_SSH_PUBLIC_KEY]);
+          if(!sshc->rsa_pub)
+            out_of_memory = TRUE;
+        }
+
+        if(out_of_memory || sshc->rsa == NULL) {
+          Curl_safefree(sshc->rsa);
+          Curl_safefree(sshc->rsa_pub);
+          state(conn, SSH_SESSION_FREE);
+          sshc->actualcode = CURLE_OUT_OF_MEMORY;
+          break;
+        }
+
+        sshc->passphrase = data->set.ssl.key_passwd;
+        if(!sshc->passphrase)
+          sshc->passphrase = "";
+
+        if(sshc->rsa_pub)
+          infof(data, "Using SSH public key file '%s'\n", sshc->rsa_pub);
+        infof(data, "Using SSH private key file '%s'\n", sshc->rsa);
+
+        state(conn, SSH_AUTH_PKEY);
+      }
+      else {
+        state(conn, SSH_AUTH_PASS_INIT);
+      }
+      break;
+
+    case SSH_AUTH_PKEY:
+      /* The function below checks if the files exists, no need to stat() here.
+       */
+      rc = libssh2_userauth_publickey_fromfile_ex(sshc->ssh_session,
+                                                  conn->user,
+                                                  curlx_uztoui(
+                                                    strlen(conn->user)),
+                                                  sshc->rsa_pub,
+                                                  sshc->rsa, sshc->passphrase);
+      if(rc == LIBSSH2_ERROR_EAGAIN) {
+        break;
+      }
+
+      Curl_safefree(sshc->rsa_pub);
+      Curl_safefree(sshc->rsa);
+
+      if(rc == 0) {
+        sshc->authed = TRUE;
+        infof(data, "Initialized SSH public key authentication\n");
+        state(conn, SSH_AUTH_DONE);
+      }
+      else {
+        char *err_msg = NULL;
+        (void)libssh2_session_last_error(sshc->ssh_session,
+                                         &err_msg, NULL, 0);
+        infof(data, "SSH public key authentication failed: %s\n", err_msg);
+        state(conn, SSH_AUTH_PASS_INIT);
+        rc = 0; /* clear rc and continue */
+      }
+      break;
+
+    case SSH_AUTH_PASS_INIT:
+      if((data->set.ssh_auth_types & CURLSSH_AUTH_PASSWORD) &&
+         (strstr(sshc->authlist, "password") != NULL)) {
+        state(conn, SSH_AUTH_PASS);
+      }
+      else {
+        state(conn, SSH_AUTH_HOST_INIT);
+        rc = 0; /* clear rc and continue */
+      }
+      break;
+
+    case SSH_AUTH_PASS:
+      rc = libssh2_userauth_password_ex(sshc->ssh_session, conn->user,
+                                        curlx_uztoui(strlen(conn->user)),
+                                        conn->passwd,
+                                        curlx_uztoui(strlen(conn->passwd)),
+                                        NULL);
+      if(rc == LIBSSH2_ERROR_EAGAIN) {
+        break;
+      }
+      if(rc == 0) {
+        sshc->authed = TRUE;
+        infof(data, "Initialized password authentication\n");
+        state(conn, SSH_AUTH_DONE);
+      }
+      else {
+        state(conn, SSH_AUTH_HOST_INIT);
+        rc = 0; /* clear rc and continue */
+      }
+      break;
+
+    case SSH_AUTH_HOST_INIT:
+      if((data->set.ssh_auth_types & CURLSSH_AUTH_HOST) &&
+         (strstr(sshc->authlist, "hostbased") != NULL)) {
+        state(conn, SSH_AUTH_HOST);
+      }
+      else {
+        state(conn, SSH_AUTH_AGENT_INIT);
+      }
+      break;
+
+    case SSH_AUTH_HOST:
+      state(conn, SSH_AUTH_AGENT_INIT);
+      break;
+
+    case SSH_AUTH_AGENT_INIT:
+#ifdef HAVE_LIBSSH2_AGENT_API
+      if((data->set.ssh_auth_types & CURLSSH_AUTH_AGENT)
+         && (strstr(sshc->authlist, "publickey") != NULL)) {
+
+        /* Connect to the ssh-agent */
+        /* The agent could be shared by a curl thread i believe
+           but nothing obvious as keys can be added/removed at any time */
+        if(!sshc->ssh_agent) {
+          sshc->ssh_agent = libssh2_agent_init(sshc->ssh_session);
+          if(!sshc->ssh_agent) {
+            infof(data, "Could not create agent object\n");
+
+            state(conn, SSH_AUTH_KEY_INIT);
+            break;
+          }
+        }
+
+        rc = libssh2_agent_connect(sshc->ssh_agent);
+        if(rc == LIBSSH2_ERROR_EAGAIN)
+          break;
+        if(rc < 0) {
+          infof(data, "Failure connecting to agent\n");
+          state(conn, SSH_AUTH_KEY_INIT);
+          rc = 0; /* clear rc and continue */
+        }
+        else {
+          state(conn, SSH_AUTH_AGENT_LIST);
+        }
+      }
+      else
+#endif /* HAVE_LIBSSH2_AGENT_API */
+        state(conn, SSH_AUTH_KEY_INIT);
+      break;
+
+    case SSH_AUTH_AGENT_LIST:
+#ifdef HAVE_LIBSSH2_AGENT_API
+      rc = libssh2_agent_list_identities(sshc->ssh_agent);
+
+      if(rc == LIBSSH2_ERROR_EAGAIN)
+        break;
+      if(rc < 0) {
+        infof(data, "Failure requesting identities to agent\n");
+        state(conn, SSH_AUTH_KEY_INIT);
+        rc = 0; /* clear rc and continue */
+      }
+      else {
+        state(conn, SSH_AUTH_AGENT);
+        sshc->sshagent_prev_identity = NULL;
+      }
+#endif
+      break;
+
+    case SSH_AUTH_AGENT:
+#ifdef HAVE_LIBSSH2_AGENT_API
+      /* as prev_identity evolves only after an identity user auth finished we
+         can safely request it again as long as EAGAIN is returned here or by
+         libssh2_agent_userauth */
+      rc = libssh2_agent_get_identity(sshc->ssh_agent,
+                                      &sshc->sshagent_identity,
+                                      sshc->sshagent_prev_identity);
+      if(rc == LIBSSH2_ERROR_EAGAIN)
+        break;
+
+      if(rc == 0) {
+        rc = libssh2_agent_userauth(sshc->ssh_agent, conn->user,
+                                    sshc->sshagent_identity);
+
+        if(rc < 0) {
+          if(rc != LIBSSH2_ERROR_EAGAIN) {
+            /* tried and failed? go to next identity */
+            sshc->sshagent_prev_identity = sshc->sshagent_identity;
+          }
+          break;
+        }
+      }
+
+      if(rc < 0)
+        infof(data, "Failure requesting identities to agent\n");
+      else if(rc == 1)
+        infof(data, "No identity would match\n");
+
+      if(rc == LIBSSH2_ERROR_NONE) {
+        sshc->authed = TRUE;
+        infof(data, "Agent based authentication successful\n");
+        state(conn, SSH_AUTH_DONE);
+      }
+      else {
+        state(conn, SSH_AUTH_KEY_INIT);
+        rc = 0; /* clear rc and continue */
+      }
+#endif
+      break;
+
+    case SSH_AUTH_KEY_INIT:
+      if((data->set.ssh_auth_types & CURLSSH_AUTH_KEYBOARD)
+         && (strstr(sshc->authlist, "keyboard-interactive") != NULL)) {
+        state(conn, SSH_AUTH_KEY);
+      }
+      else {
+        state(conn, SSH_AUTH_DONE);
+      }
+      break;
+
+    case SSH_AUTH_KEY:
+      /* Authentication failed. Continue with keyboard-interactive now. */
+      rc = libssh2_userauth_keyboard_interactive_ex(sshc->ssh_session,
+                                                    conn->user,
+                                                    curlx_uztoui(
+                                                      strlen(conn->user)),
+                                                    &kbd_callback);
+      if(rc == LIBSSH2_ERROR_EAGAIN) {
+        break;
+      }
+      if(rc == 0) {
+        sshc->authed = TRUE;
+        infof(data, "Initialized keyboard interactive authentication\n");
+      }
+      state(conn, SSH_AUTH_DONE);
+      break;
+
+    case SSH_AUTH_DONE:
+      if(!sshc->authed) {
+        failf(data, "Authentication failure");
+        state(conn, SSH_SESSION_FREE);
+        sshc->actualcode = CURLE_LOGIN_DENIED;
+        break;
+      }
+
+      /*
+       * At this point we have an authenticated ssh session.
+       */
+      infof(data, "Authentication complete\n");
+
+      Curl_pgrsTime(conn->data, TIMER_APPCONNECT); /* SSH is connected */
+
+      conn->sockfd = sock;
+      conn->writesockfd = CURL_SOCKET_BAD;
+
+      if(conn->handler->protocol == CURLPROTO_SFTP) {
+        state(conn, SSH_SFTP_INIT);
+        break;
+      }
+      infof(data, "SSH CONNECT phase done\n");
+      state(conn, SSH_STOP);
+      break;
+
+    case SSH_SFTP_INIT:
+      /*
+       * Start the libssh2 sftp session
+       */
+      sshc->sftp_session = libssh2_sftp_init(sshc->ssh_session);
+      if(!sshc->sftp_session) {
+        char *err_msg = NULL;
+        if(libssh2_session_last_errno(sshc->ssh_session) ==
+           LIBSSH2_ERROR_EAGAIN) {
+          rc = LIBSSH2_ERROR_EAGAIN;
+          break;
+        }
+
+        (void)libssh2_session_last_error(sshc->ssh_session,
+                                         &err_msg, NULL, 0);
+        failf(data, "Failure initializing sftp session: %s", err_msg);
+        state(conn, SSH_SESSION_FREE);
+        sshc->actualcode = CURLE_FAILED_INIT;
+        break;
+      }
+      state(conn, SSH_SFTP_REALPATH);
+      break;
+
+    case SSH_SFTP_REALPATH:
+    {
+      char tempHome[PATH_MAX];
+
+      /*
+       * Get the "home" directory
+       */
+      rc = sftp_libssh2_realpath(sshc->sftp_session, ".",
+                                 tempHome, PATH_MAX-1);
+      if(rc == LIBSSH2_ERROR_EAGAIN) {
+        break;
+      }
+      if(rc > 0) {
+        /* It seems that this string is not always NULL terminated */
+        tempHome[rc] = '\0';
+        sshc->homedir = strdup(tempHome);
+        if(!sshc->homedir) {
+          state(conn, SSH_SFTP_CLOSE);
+          sshc->actualcode = CURLE_OUT_OF_MEMORY;
+          break;
+        }
+        conn->data->state.most_recent_ftp_entrypath = sshc->homedir;
+      }
+      else {
+        /* Return the error type */
+        sftperr = libssh2_sftp_last_error(sshc->sftp_session);
+        if(sftperr)
+          result = sftp_libssh2_error_to_CURLE(sftperr);
+        else
+          /* in this case, the error wasn't in the SFTP level but for example
+             a time-out or similar */
+          result = CURLE_SSH;
+        sshc->actualcode = result;
+        DEBUGF(infof(data, "error = %d makes libcurl = %d\n",
+                     ssherr, (int)result));
+        state(conn, SSH_STOP);
+        break;
+      }
+    }
+    /* This is the last step in the SFTP connect phase. Do note that while
+       we get the homedir here, we get the "workingpath" in the DO action
+       since the homedir will remain the same between request but the
+       working path will not. */
+    DEBUGF(infof(data, "SSH CONNECT phase done\n"));
+    state(conn, SSH_STOP);
+    break;
+
+    case SSH_SFTP_QUOTE_INIT:
+
+      result = Curl_getworkingpath(conn, sshc->homedir, &sftp_scp->path);
+      if(result) {
+        sshc->actualcode = result;
+        state(conn, SSH_STOP);
+        break;
+      }
+
+      if(data->set.quote) {
+        infof(data, "Sending quote commands\n");
+        sshc->quote_item = data->set.quote;
+        state(conn, SSH_SFTP_QUOTE);
+      }
+      else {
+        state(conn, SSH_SFTP_GETINFO);
+      }
+      break;
+
+    case SSH_SFTP_POSTQUOTE_INIT:
+      if(data->set.postquote) {
+        infof(data, "Sending quote commands\n");
+        sshc->quote_item = data->set.postquote;
+        state(conn, SSH_SFTP_QUOTE);
+      }
+      else {
+        state(conn, SSH_STOP);
+      }
+      break;
+
+    case SSH_SFTP_QUOTE:
+      /* Send any quote commands */
+    {
+      const char *cp;
+
+      /*
+       * Support some of the "FTP" commands
+       *
+       * 'sshc->quote_item' is already verified to be non-NULL before it
+       * switched to this state.
+       */
+      char *cmd = sshc->quote_item->data;
+      sshc->acceptfail = FALSE;
+
+      /* if a command starts with an asterisk, which a legal SFTP command never
+         can, the command will be allowed to fail without it causing any
+         aborts or cancels etc. It will cause libcurl to act as if the command
+         is successful, whatever the server reponds. */
+
+      if(cmd[0] == '*') {
+        cmd++;
+        sshc->acceptfail = TRUE;
+      }
+
+      if(strcasecompare("pwd", cmd)) {
+        /* output debug output if that is requested */
+        char *tmp = aprintf("257 \"%s\" is current directory.\n",
+                            sftp_scp->path);
+        if(!tmp) {
+          result = CURLE_OUT_OF_MEMORY;
+          state(conn, SSH_SFTP_CLOSE);
+          sshc->nextstate = SSH_NO_STATE;
+          break;
+        }
+        if(data->set.verbose) {
+          Curl_debug(data, CURLINFO_HEADER_OUT, (char *)"PWD\n", 4);
+          Curl_debug(data, CURLINFO_HEADER_IN, tmp, strlen(tmp));
+        }
+        /* this sends an FTP-like "header" to the header callback so that the
+           current directory can be read very similar to how it is read when
+           using ordinary FTP. */
+        result = Curl_client_write(conn, CLIENTWRITE_HEADER, tmp, strlen(tmp));
+        free(tmp);
+        if(result) {
+          state(conn, SSH_SFTP_CLOSE);
+          sshc->nextstate = SSH_NO_STATE;
+          sshc->actualcode = result;
+        }
+        else
+          state(conn, SSH_SFTP_NEXT_QUOTE);
+        break;
+      }
+      {
+        /*
+         * the arguments following the command must be separated from the
+         * command with a space so we can check for it unconditionally
+         */
+        cp = strchr(cmd, ' ');
+        if(cp == NULL) {
+          failf(data, "Syntax error command '%s'. Missing parameter!",
+                cmd);
+          state(conn, SSH_SFTP_CLOSE);
+          sshc->nextstate = SSH_NO_STATE;
+          sshc->actualcode = CURLE_QUOTE_ERROR;
+          break;
+        }
+
+        /*
+         * also, every command takes at least one argument so we get that
+         * first argument right now
+         */
+        result = Curl_get_pathname(&cp, &sshc->quote_path1, sshc->homedir);
+        if(result) {
+          if(result == CURLE_OUT_OF_MEMORY)
+            failf(data, "Out of memory");
+          else
+            failf(data, "Syntax error: Bad first parameter to '%s'", cmd);
+          state(conn, SSH_SFTP_CLOSE);
+          sshc->nextstate = SSH_NO_STATE;
+          sshc->actualcode = result;
+          break;
+        }
+
+        /*
+         * SFTP is a binary protocol, so we don't send text commands
+         * to the server. Instead, we scan for commands used by
+         * OpenSSH's sftp program and call the appropriate libssh2
+         * functions.
+         */
+        if(strncasecompare(cmd, "chgrp ", 6) ||
+           strncasecompare(cmd, "chmod ", 6) ||
+           strncasecompare(cmd, "chown ", 6) ) {
+          /* attribute change */
+
+          /* sshc->quote_path1 contains the mode to set */
+          /* get the destination */
+          result = Curl_get_pathname(&cp, &sshc->quote_path2, sshc->homedir);
+          if(result) {
+            if(result == CURLE_OUT_OF_MEMORY)
+              failf(data, "Out of memory");
+            else
+              failf(data, "Syntax error in %s: Bad second parameter", cmd);
+            Curl_safefree(sshc->quote_path1);
+            state(conn, SSH_SFTP_CLOSE);
+            sshc->nextstate = SSH_NO_STATE;
+            sshc->actualcode = result;
+            break;
+          }
+          memset(&sshc->quote_attrs, 0, sizeof(LIBSSH2_SFTP_ATTRIBUTES));
+          state(conn, SSH_SFTP_QUOTE_STAT);
+          break;
+        }
+        if(strncasecompare(cmd, "ln ", 3) ||
+           strncasecompare(cmd, "symlink ", 8)) {
+          /* symbolic linking */
+          /* sshc->quote_path1 is the source */
+          /* get the destination */
+          result = Curl_get_pathname(&cp, &sshc->quote_path2, sshc->homedir);
+          if(result) {
+            if(result == CURLE_OUT_OF_MEMORY)
+              failf(data, "Out of memory");
+            else
+              failf(data,
+                    "Syntax error in ln/symlink: Bad second parameter");
+            Curl_safefree(sshc->quote_path1);
+            state(conn, SSH_SFTP_CLOSE);
+            sshc->nextstate = SSH_NO_STATE;
+            sshc->actualcode = result;
+            break;
+          }
+          state(conn, SSH_SFTP_QUOTE_SYMLINK);
+          break;
+        }
+        else if(strncasecompare(cmd, "mkdir ", 6)) {
+          /* create dir */
+          state(conn, SSH_SFTP_QUOTE_MKDIR);
+          break;
+        }
+        else if(strncasecompare(cmd, "rename ", 7)) {
+          /* rename file */
+          /* first param is the source path */
+          /* second param is the dest. path */
+          result = Curl_get_pathname(&cp, &sshc->quote_path2, sshc->homedir);
+          if(result) {
+            if(result == CURLE_OUT_OF_MEMORY)
+              failf(data, "Out of memory");
+            else
+              failf(data, "Syntax error in rename: Bad second parameter");
+            Curl_safefree(sshc->quote_path1);
+            state(conn, SSH_SFTP_CLOSE);
+            sshc->nextstate = SSH_NO_STATE;
+            sshc->actualcode = result;
+            break;
+          }
+          state(conn, SSH_SFTP_QUOTE_RENAME);
+          break;
+        }
+        else if(strncasecompare(cmd, "rmdir ", 6)) {
+          /* delete dir */
+          state(conn, SSH_SFTP_QUOTE_RMDIR);
+          break;
+        }
+        else if(strncasecompare(cmd, "rm ", 3)) {
+          state(conn, SSH_SFTP_QUOTE_UNLINK);
+          break;
+        }
+#ifdef HAS_STATVFS_SUPPORT
+        else if(strncasecompare(cmd, "statvfs ", 8)) {
+          state(conn, SSH_SFTP_QUOTE_STATVFS);
+          break;
+        }
+#endif
+
+        failf(data, "Unknown SFTP command");
+        Curl_safefree(sshc->quote_path1);
+        Curl_safefree(sshc->quote_path2);
+        state(conn, SSH_SFTP_CLOSE);
+        sshc->nextstate = SSH_NO_STATE;
+        sshc->actualcode = CURLE_QUOTE_ERROR;
+        break;
+      }
+    }
+    break;
+
+    case SSH_SFTP_NEXT_QUOTE:
+      Curl_safefree(sshc->quote_path1);
+      Curl_safefree(sshc->quote_path2);
+
+      sshc->quote_item = sshc->quote_item->next;
+
+      if(sshc->quote_item) {
+        state(conn, SSH_SFTP_QUOTE);
+      }
+      else {
+        if(sshc->nextstate != SSH_NO_STATE) {
+          state(conn, sshc->nextstate);
+          sshc->nextstate = SSH_NO_STATE;
+        }
+        else {
+          state(conn, SSH_SFTP_GETINFO);
+        }
+      }
+      break;
+
+    case SSH_SFTP_QUOTE_STAT:
+    {
+      char *cmd = sshc->quote_item->data;
+      sshc->acceptfail = FALSE;
+
+      /* if a command starts with an asterisk, which a legal SFTP command never
+         can, the command will be allowed to fail without it causing any
+         aborts or cancels etc. It will cause libcurl to act as if the command
+         is successful, whatever the server reponds. */
+
+      if(cmd[0] == '*') {
+        cmd++;
+        sshc->acceptfail = TRUE;
+      }
+
+      if(!strncasecompare(cmd, "chmod", 5)) {
+        /* Since chown and chgrp only set owner OR group but libssh2 wants to
+         * set them both at once, we need to obtain the current ownership
+         * first.  This takes an extra protocol round trip.
+         */
+        rc = libssh2_sftp_stat_ex(sshc->sftp_session, sshc->quote_path2,
+                                  curlx_uztoui(strlen(sshc->quote_path2)),
+                                  LIBSSH2_SFTP_STAT,
+                                  &sshc->quote_attrs);
+        if(rc == LIBSSH2_ERROR_EAGAIN) {
+          break;
+        }
+        if(rc != 0 && !sshc->acceptfail) { /* get those attributes */
+          sftperr = libssh2_sftp_last_error(sshc->sftp_session);
+          Curl_safefree(sshc->quote_path1);
+          Curl_safefree(sshc->quote_path2);
+          failf(data, "Attempt to get SFTP stats failed: %s",
+                sftp_libssh2_strerror(sftperr));
+          state(conn, SSH_SFTP_CLOSE);
+          sshc->nextstate = SSH_NO_STATE;
+          sshc->actualcode = CURLE_QUOTE_ERROR;
+          break;
+        }
+      }
+
+      /* Now set the new attributes... */
+      if(strncasecompare(cmd, "chgrp", 5)) {
+        sshc->quote_attrs.gid = strtoul(sshc->quote_path1, NULL, 10);
+        sshc->quote_attrs.flags = LIBSSH2_SFTP_ATTR_UIDGID;
+        if(sshc->quote_attrs.gid == 0 && !ISDIGIT(sshc->quote_path1[0]) &&
+           !sshc->acceptfail) {
+          Curl_safefree(sshc->quote_path1);
+          Curl_safefree(sshc->quote_path2);
+          failf(data, "Syntax error: chgrp gid not a number");
+          state(conn, SSH_SFTP_CLOSE);
+          sshc->nextstate = SSH_NO_STATE;
+          sshc->actualcode = CURLE_QUOTE_ERROR;
+          break;
+        }
+      }
+      else if(strncasecompare(cmd, "chmod", 5)) {
+        sshc->quote_attrs.permissions = strtoul(sshc->quote_path1, NULL, 8);
+        sshc->quote_attrs.flags = LIBSSH2_SFTP_ATTR_PERMISSIONS;
+        /* permissions are octal */
+        if(sshc->quote_attrs.permissions == 0 &&
+           !ISDIGIT(sshc->quote_path1[0])) {
+          Curl_safefree(sshc->quote_path1);
+          Curl_safefree(sshc->quote_path2);
+          failf(data, "Syntax error: chmod permissions not a number");
+          state(conn, SSH_SFTP_CLOSE);
+          sshc->nextstate = SSH_NO_STATE;
+          sshc->actualcode = CURLE_QUOTE_ERROR;
+          break;
+        }
+      }
+      else if(strncasecompare(cmd, "chown", 5)) {
+        sshc->quote_attrs.uid = strtoul(sshc->quote_path1, NULL, 10);
+        sshc->quote_attrs.flags = LIBSSH2_SFTP_ATTR_UIDGID;
+        if(sshc->quote_attrs.uid == 0 && !ISDIGIT(sshc->quote_path1[0]) &&
+           !sshc->acceptfail) {
+          Curl_safefree(sshc->quote_path1);
+          Curl_safefree(sshc->quote_path2);
+          failf(data, "Syntax error: chown uid not a number");
+          state(conn, SSH_SFTP_CLOSE);
+          sshc->nextstate = SSH_NO_STATE;
+          sshc->actualcode = CURLE_QUOTE_ERROR;
+          break;
+        }
+      }
+
+      /* Now send the completed structure... */
+      state(conn, SSH_SFTP_QUOTE_SETSTAT);
+      break;
+    }
+
+    case SSH_SFTP_QUOTE_SETSTAT:
+      rc = libssh2_sftp_stat_ex(sshc->sftp_session, sshc->quote_path2,
+                                curlx_uztoui(strlen(sshc->quote_path2)),
+                                LIBSSH2_SFTP_SETSTAT,
+                                &sshc->quote_attrs);
+      if(rc == LIBSSH2_ERROR_EAGAIN) {
+        break;
+      }
+      if(rc != 0 && !sshc->acceptfail) {
+        sftperr = libssh2_sftp_last_error(sshc->sftp_session);
+        Curl_safefree(sshc->quote_path1);
+        Curl_safefree(sshc->quote_path2);
+        failf(data, "Attempt to set SFTP stats failed: %s",
+              sftp_libssh2_strerror(sftperr));
+        state(conn, SSH_SFTP_CLOSE);
+        sshc->nextstate = SSH_NO_STATE;
+        sshc->actualcode = CURLE_QUOTE_ERROR;
+        break;
+      }
+      state(conn, SSH_SFTP_NEXT_QUOTE);
+      break;
+
+    case SSH_SFTP_QUOTE_SYMLINK:
+      rc = libssh2_sftp_symlink_ex(sshc->sftp_session, sshc->quote_path1,
+                                   curlx_uztoui(strlen(sshc->quote_path1)),
+                                   sshc->quote_path2,
+                                   curlx_uztoui(strlen(sshc->quote_path2)),
+                                   LIBSSH2_SFTP_SYMLINK);
+      if(rc == LIBSSH2_ERROR_EAGAIN) {
+        break;
+      }
+      if(rc != 0 && !sshc->acceptfail) {
+        sftperr = libssh2_sftp_last_error(sshc->sftp_session);
+        Curl_safefree(sshc->quote_path1);
+        Curl_safefree(sshc->quote_path2);
+        failf(data, "symlink command failed: %s",
+              sftp_libssh2_strerror(sftperr));
+        state(conn, SSH_SFTP_CLOSE);
+        sshc->nextstate = SSH_NO_STATE;
+        sshc->actualcode = CURLE_QUOTE_ERROR;
+        break;
+      }
+      state(conn, SSH_SFTP_NEXT_QUOTE);
+      break;
+
+    case SSH_SFTP_QUOTE_MKDIR:
+      rc = libssh2_sftp_mkdir_ex(sshc->sftp_session, sshc->quote_path1,
+                                 curlx_uztoui(strlen(sshc->quote_path1)),
+                                 data->set.new_directory_perms);
+      if(rc == LIBSSH2_ERROR_EAGAIN) {
+        break;
+      }
+      if(rc != 0 && !sshc->acceptfail) {
+        sftperr = libssh2_sftp_last_error(sshc->sftp_session);
+        Curl_safefree(sshc->quote_path1);
+        failf(data, "mkdir command failed: %s",
+              sftp_libssh2_strerror(sftperr));
+        state(conn, SSH_SFTP_CLOSE);
+        sshc->nextstate = SSH_NO_STATE;
+        sshc->actualcode = CURLE_QUOTE_ERROR;
+        break;
+      }
+      state(conn, SSH_SFTP_NEXT_QUOTE);
+      break;
+
+    case SSH_SFTP_QUOTE_RENAME:
+      rc = libssh2_sftp_rename_ex(sshc->sftp_session, sshc->quote_path1,
+                                  curlx_uztoui(strlen(sshc->quote_path1)),
+                                  sshc->quote_path2,
+                                  curlx_uztoui(strlen(sshc->quote_path2)),
+                                  LIBSSH2_SFTP_RENAME_OVERWRITE |
+                                  LIBSSH2_SFTP_RENAME_ATOMIC |
+                                  LIBSSH2_SFTP_RENAME_NATIVE);
+
+      if(rc == LIBSSH2_ERROR_EAGAIN) {
+        break;
+      }
+      if(rc != 0 && !sshc->acceptfail) {
+        sftperr = libssh2_sftp_last_error(sshc->sftp_session);
+        Curl_safefree(sshc->quote_path1);
+        Curl_safefree(sshc->quote_path2);
+        failf(data, "rename command failed: %s",
+              sftp_libssh2_strerror(sftperr));
+        state(conn, SSH_SFTP_CLOSE);
+        sshc->nextstate = SSH_NO_STATE;
+        sshc->actualcode = CURLE_QUOTE_ERROR;
+        break;
+      }
+      state(conn, SSH_SFTP_NEXT_QUOTE);
+      break;
+
+    case SSH_SFTP_QUOTE_RMDIR:
+      rc = libssh2_sftp_rmdir_ex(sshc->sftp_session, sshc->quote_path1,
+                                 curlx_uztoui(strlen(sshc->quote_path1)));
+      if(rc == LIBSSH2_ERROR_EAGAIN) {
+        break;
+      }
+      if(rc != 0 && !sshc->acceptfail) {
+        sftperr = libssh2_sftp_last_error(sshc->sftp_session);
+        Curl_safefree(sshc->quote_path1);
+        failf(data, "rmdir command failed: %s",
+              sftp_libssh2_strerror(sftperr));
+        state(conn, SSH_SFTP_CLOSE);
+        sshc->nextstate = SSH_NO_STATE;
+        sshc->actualcode = CURLE_QUOTE_ERROR;
+        break;
+      }
+      state(conn, SSH_SFTP_NEXT_QUOTE);
+      break;
+
+    case SSH_SFTP_QUOTE_UNLINK:
+      rc = libssh2_sftp_unlink_ex(sshc->sftp_session, sshc->quote_path1,
+                                  curlx_uztoui(strlen(sshc->quote_path1)));
+      if(rc == LIBSSH2_ERROR_EAGAIN) {
+        break;
+      }
+      if(rc != 0 && !sshc->acceptfail) {
+        sftperr = libssh2_sftp_last_error(sshc->sftp_session);
+        Curl_safefree(sshc->quote_path1);
+        failf(data, "rm command failed: %s", sftp_libssh2_strerror(sftperr));
+        state(conn, SSH_SFTP_CLOSE);
+        sshc->nextstate = SSH_NO_STATE;
+        sshc->actualcode = CURLE_QUOTE_ERROR;
+        break;
+      }
+      state(conn, SSH_SFTP_NEXT_QUOTE);
+      break;
+
+#ifdef HAS_STATVFS_SUPPORT
+    case SSH_SFTP_QUOTE_STATVFS:
+    {
+      LIBSSH2_SFTP_STATVFS statvfs;
+      rc = libssh2_sftp_statvfs(sshc->sftp_session, sshc->quote_path1,
+                                curlx_uztoui(strlen(sshc->quote_path1)),
+                                &statvfs);
+
+      if(rc == LIBSSH2_ERROR_EAGAIN) {
+        break;
+      }
+      if(rc != 0 && !sshc->acceptfail) {
+        sftperr = libssh2_sftp_last_error(sshc->sftp_session);
+        Curl_safefree(sshc->quote_path1);
+        failf(data, "statvfs command failed: %s",
+              sftp_libssh2_strerror(sftperr));
+        state(conn, SSH_SFTP_CLOSE);
+        sshc->nextstate = SSH_NO_STATE;
+        sshc->actualcode = CURLE_QUOTE_ERROR;
+        break;
+      }
+      else if(rc == 0) {
+        char *tmp = aprintf("statvfs:\n"
+                            "f_bsize: %llu\n" "f_frsize: %llu\n"
+                            "f_blocks: %llu\n" "f_bfree: %llu\n"
+                            "f_bavail: %llu\n" "f_files: %llu\n"
+                            "f_ffree: %llu\n" "f_favail: %llu\n"
+                            "f_fsid: %llu\n" "f_flag: %llu\n"
+                            "f_namemax: %llu\n",
+                            statvfs.f_bsize, statvfs.f_frsize,
+                            statvfs.f_blocks, statvfs.f_bfree,
+                            statvfs.f_bavail, statvfs.f_files,
+                            statvfs.f_ffree, statvfs.f_favail,
+                            statvfs.f_fsid, statvfs.f_flag,
+                            statvfs.f_namemax);
+        if(!tmp) {
+          result = CURLE_OUT_OF_MEMORY;
+          state(conn, SSH_SFTP_CLOSE);
+          sshc->nextstate = SSH_NO_STATE;
+          break;
+        }
+
+        result = Curl_client_write(conn, CLIENTWRITE_HEADER, tmp, strlen(tmp));
+        free(tmp);
+        if(result) {
+          state(conn, SSH_SFTP_CLOSE);
+          sshc->nextstate = SSH_NO_STATE;
+          sshc->actualcode = result;
+        }
+      }
+      state(conn, SSH_SFTP_NEXT_QUOTE);
+      break;
+    }
+#endif
+    case SSH_SFTP_GETINFO:
+    {
+      if(data->set.get_filetime) {
+        state(conn, SSH_SFTP_FILETIME);
+      }
+      else {
+        state(conn, SSH_SFTP_TRANS_INIT);
+      }
+      break;
+    }
+
+    case SSH_SFTP_FILETIME:
+    {
+      LIBSSH2_SFTP_ATTRIBUTES attrs;
+
+      rc = libssh2_sftp_stat_ex(sshc->sftp_session, sftp_scp->path,
+                                curlx_uztoui(strlen(sftp_scp->path)),
+                                LIBSSH2_SFTP_STAT, &attrs);
+      if(rc == LIBSSH2_ERROR_EAGAIN) {
+        break;
+      }
+      if(rc == 0) {
+        data->info.filetime = attrs.mtime;
+      }
+
+      state(conn, SSH_SFTP_TRANS_INIT);
+      break;
+    }
+
+    case SSH_SFTP_TRANS_INIT:
+      if(data->set.upload)
+        state(conn, SSH_SFTP_UPLOAD_INIT);
+      else {
+        if(sftp_scp->path[strlen(sftp_scp->path)-1] == '/')
+          state(conn, SSH_SFTP_READDIR_INIT);
+        else
+          state(conn, SSH_SFTP_DOWNLOAD_INIT);
+      }
+      break;
+
+    case SSH_SFTP_UPLOAD_INIT:
+    {
+      unsigned long flags;
+      /*
+       * NOTE!!!  libssh2 requires that the destination path is a full path
+       *          that includes the destination file and name OR ends in a "/"
+       *          If this is not done the destination file will be named the
+       *          same name as the last directory in the path.
+       */
+
+      if(data->state.resume_from != 0) {
+        LIBSSH2_SFTP_ATTRIBUTES attrs;
+        if(data->state.resume_from < 0) {
+          rc = libssh2_sftp_stat_ex(sshc->sftp_session, sftp_scp->path,
+                                    curlx_uztoui(strlen(sftp_scp->path)),
+                                    LIBSSH2_SFTP_STAT, &attrs);
+          if(rc == LIBSSH2_ERROR_EAGAIN) {
+            break;
+          }
+          if(rc) {
+            data->state.resume_from = 0;
+          }
+          else {
+            curl_off_t size = attrs.filesize;
+            if(size < 0) {
+              failf(data, "Bad file size (%" CURL_FORMAT_CURL_OFF_T ")", size);
+              return CURLE_BAD_DOWNLOAD_RESUME;
+            }
+            data->state.resume_from = attrs.filesize;
+          }
+        }
+      }
+
+      if(data->set.ftp_append)
+        /* Try to open for append, but create if nonexisting */
+        flags = LIBSSH2_FXF_WRITE|LIBSSH2_FXF_CREAT|LIBSSH2_FXF_APPEND;
+      else if(data->state.resume_from > 0)
+        /* If we have restart position then open for append */
+        flags = LIBSSH2_FXF_WRITE|LIBSSH2_FXF_APPEND;
+      else
+        /* Clear file before writing (normal behaviour) */
+        flags = LIBSSH2_FXF_WRITE|LIBSSH2_FXF_CREAT|LIBSSH2_FXF_TRUNC;
+
+      sshc->sftp_handle =
+        libssh2_sftp_open_ex(sshc->sftp_session, sftp_scp->path,
+                             curlx_uztoui(strlen(sftp_scp->path)),
+                             flags, data->set.new_file_perms,
+                             LIBSSH2_SFTP_OPENFILE);
+
+      if(!sshc->sftp_handle) {
+        rc = libssh2_session_last_errno(sshc->ssh_session);
+
+        if(LIBSSH2_ERROR_EAGAIN == rc)
+          break;
+
+        if(LIBSSH2_ERROR_SFTP_PROTOCOL == rc)
+          /* only when there was an SFTP protocol error can we extract
+             the sftp error! */
+          sftperr = libssh2_sftp_last_error(sshc->sftp_session);
+        else
+          sftperr = LIBSSH2_FX_OK; /* not an sftp error at all */
+
+        if(sshc->secondCreateDirs) {
+          state(conn, SSH_SFTP_CLOSE);
+          sshc->actualcode = sftperr != LIBSSH2_FX_OK ?
+            sftp_libssh2_error_to_CURLE(sftperr):CURLE_SSH;
+          failf(data, "Creating the dir/file failed: %s",
+                sftp_libssh2_strerror(sftperr));
+          break;
+        }
+        if(((sftperr == LIBSSH2_FX_NO_SUCH_FILE) ||
+            (sftperr == LIBSSH2_FX_FAILURE) ||
+            (sftperr == LIBSSH2_FX_NO_SUCH_PATH)) &&
+           (data->set.ftp_create_missing_dirs &&
+            (strlen(sftp_scp->path) > 1))) {
+          /* try to create the path remotely */
+          rc = 0; /* clear rc and continue */
+          sshc->secondCreateDirs = 1;
+          state(conn, SSH_SFTP_CREATE_DIRS_INIT);
+          break;
+        }
+        state(conn, SSH_SFTP_CLOSE);
+        sshc->actualcode = sftperr != LIBSSH2_FX_OK ?
+          sftp_libssh2_error_to_CURLE(sftperr):CURLE_SSH;
+        if(!sshc->actualcode) {
+          /* Sometimes, for some reason libssh2_sftp_last_error() returns zero
+             even though libssh2_sftp_open() failed previously! We need to
+             work around that! */
+          sshc->actualcode = CURLE_SSH;
+          sftperr = LIBSSH2_FX_OK;
+        }
+        failf(data, "Upload failed: %s (%d/%d)",
+              sftperr != LIBSSH2_FX_OK ?
+              sftp_libssh2_strerror(sftperr):"ssh error",
+              sftperr, rc);
+        break;
+      }
+
+      /* If we have a restart point then we need to seek to the correct
+         position. */
+      if(data->state.resume_from > 0) {
+        /* Let's read off the proper amount of bytes from the input. */
+        if(conn->seek_func) {
+          Curl_set_in_callback(data, true);
+          seekerr = conn->seek_func(conn->seek_client, data->state.resume_from,
+                                    SEEK_SET);
+          Curl_set_in_callback(data, false);
+        }
+
+        if(seekerr != CURL_SEEKFUNC_OK) {
+          curl_off_t passed = 0;
+
+          if(seekerr != CURL_SEEKFUNC_CANTSEEK) {
+            failf(data, "Could not seek stream");
+            return CURLE_FTP_COULDNT_USE_REST;
+          }
+          /* seekerr == CURL_SEEKFUNC_CANTSEEK (can't seek to offset) */
+          do {
+            size_t readthisamountnow =
+              (data->state.resume_from - passed > data->set.buffer_size) ?
+              (size_t)data->set.buffer_size :
+              curlx_sotouz(data->state.resume_from - passed);
+
+            size_t actuallyread;
+            Curl_set_in_callback(data, true);
+            actuallyread = data->state.fread_func(data->state.buffer, 1,
+                                                  readthisamountnow,
+                                                  data->state.in);
+            Curl_set_in_callback(data, false);
+
+            passed += actuallyread;
+            if((actuallyread == 0) || (actuallyread > readthisamountnow)) {
+              /* this checks for greater-than only to make sure that the
+                 CURL_READFUNC_ABORT return code still aborts */
+              failf(data, "Failed to read data");
+              return CURLE_FTP_COULDNT_USE_REST;
+            }
+          } while(passed < data->state.resume_from);
+        }
+
+        /* now, decrease the size of the read */
+        if(data->state.infilesize > 0) {
+          data->state.infilesize -= data->state.resume_from;
+          data->req.size = data->state.infilesize;
+          Curl_pgrsSetUploadSize(data, data->state.infilesize);
+        }
+
+        SFTP_SEEK(sshc->sftp_handle, data->state.resume_from);
+      }
+      if(data->state.infilesize > 0) {
+        data->req.size = data->state.infilesize;
+        Curl_pgrsSetUploadSize(data, data->state.infilesize);
+      }
+      /* upload data */
+      Curl_setup_transfer(data, -1, -1, FALSE, FIRSTSOCKET);
+
+      /* not set by Curl_setup_transfer to preserve keepon bits */
+      conn->sockfd = conn->writesockfd;
+
+      if(result) {
+        state(conn, SSH_SFTP_CLOSE);
+        sshc->actualcode = result;
+      }
+      else {
+        /* store this original bitmask setup to use later on if we can't
+           figure out a "real" bitmask */
+        sshc->orig_waitfor = data->req.keepon;
+
+        /* we want to use the _sending_ function even when the socket turns
+           out readable as the underlying libssh2 sftp send function will deal
+           with both accordingly */
+        conn->cselect_bits = CURL_CSELECT_OUT;
+
+        /* since we don't really wait for anything at this point, we want the
+           state machine to move on as soon as possible so we set a very short
+           timeout here */
+        Curl_expire(data, 0, EXPIRE_RUN_NOW);
+
+        state(conn, SSH_STOP);
+      }
+      break;
+    }
+
+    case SSH_SFTP_CREATE_DIRS_INIT:
+      if(strlen(sftp_scp->path) > 1) {
+        sshc->slash_pos = sftp_scp->path + 1; /* ignore the leading '/' */
+        state(conn, SSH_SFTP_CREATE_DIRS);
+      }
+      else {
+        state(conn, SSH_SFTP_UPLOAD_INIT);
+      }
+      break;
+
+    case SSH_SFTP_CREATE_DIRS:
+      sshc->slash_pos = strchr(sshc->slash_pos, '/');
+      if(sshc->slash_pos) {
+        *sshc->slash_pos = 0;
+
+        infof(data, "Creating directory '%s'\n", sftp_scp->path);
+        state(conn, SSH_SFTP_CREATE_DIRS_MKDIR);
+        break;
+      }
+      state(conn, SSH_SFTP_UPLOAD_INIT);
+      break;
+
+    case SSH_SFTP_CREATE_DIRS_MKDIR:
+      /* 'mode' - parameter is preliminary - default to 0644 */
+      rc = libssh2_sftp_mkdir_ex(sshc->sftp_session, sftp_scp->path,
+                                 curlx_uztoui(strlen(sftp_scp->path)),
+                                 data->set.new_directory_perms);
+      if(rc == LIBSSH2_ERROR_EAGAIN) {
+        break;
+      }
+      *sshc->slash_pos = '/';
+      ++sshc->slash_pos;
+      if(rc < 0) {
+        /*
+         * Abort if failure wasn't that the dir already exists or the
+         * permission was denied (creation might succeed further down the
+         * path) - retry on unspecific FAILURE also
+         */
+        sftperr = libssh2_sftp_last_error(sshc->sftp_session);
+        if((sftperr != LIBSSH2_FX_FILE_ALREADY_EXISTS) &&
+           (sftperr != LIBSSH2_FX_FAILURE) &&
+           (sftperr != LIBSSH2_FX_PERMISSION_DENIED)) {
+          result = sftp_libssh2_error_to_CURLE(sftperr);
+          state(conn, SSH_SFTP_CLOSE);
+          sshc->actualcode = result?result:CURLE_SSH;
+          break;
+        }
+        rc = 0; /* clear rc and continue */
+      }
+      state(conn, SSH_SFTP_CREATE_DIRS);
+      break;
+
+    case SSH_SFTP_READDIR_INIT:
+      Curl_pgrsSetDownloadSize(data, -1);
+      if(data->set.opt_no_body) {
+        state(conn, SSH_STOP);
+        break;
+      }
+
+      /*
+       * This is a directory that we are trying to get, so produce a directory
+       * listing
+       */
+      sshc->sftp_handle = libssh2_sftp_open_ex(sshc->sftp_session,
+                                               sftp_scp->path,
+                                               curlx_uztoui(
+                                                 strlen(sftp_scp->path)),
+                                               0, 0, LIBSSH2_SFTP_OPENDIR);
+      if(!sshc->sftp_handle) {
+        if(libssh2_session_last_errno(sshc->ssh_session) ==
+           LIBSSH2_ERROR_EAGAIN) {
+          rc = LIBSSH2_ERROR_EAGAIN;
+          break;
+        }
+        sftperr = libssh2_sftp_last_error(sshc->sftp_session);
+        failf(data, "Could not open directory for reading: %s",
+              sftp_libssh2_strerror(sftperr));
+        state(conn, SSH_SFTP_CLOSE);
+        result = sftp_libssh2_error_to_CURLE(sftperr);
+        sshc->actualcode = result?result:CURLE_SSH;
+        break;
+      }
+      sshc->readdir_filename = malloc(PATH_MAX + 1);
+      if(!sshc->readdir_filename) {
+        state(conn, SSH_SFTP_CLOSE);
+        sshc->actualcode = CURLE_OUT_OF_MEMORY;
+        break;
+      }
+      sshc->readdir_longentry = malloc(PATH_MAX + 1);
+      if(!sshc->readdir_longentry) {
+        Curl_safefree(sshc->readdir_filename);
+        state(conn, SSH_SFTP_CLOSE);
+        sshc->actualcode = CURLE_OUT_OF_MEMORY;
+        break;
+      }
+      Curl_dyn_init(&sshc->readdir, PATH_MAX * 2);
+      state(conn, SSH_SFTP_READDIR);
+      break;
+
+    case SSH_SFTP_READDIR:
+      rc = libssh2_sftp_readdir_ex(sshc->sftp_handle,
+                                   sshc->readdir_filename,
+                                   PATH_MAX,
+                                   sshc->readdir_longentry,
+                                   PATH_MAX,
+                                   &sshc->readdir_attrs);
+      if(rc == LIBSSH2_ERROR_EAGAIN) {
+        break;
+      }
+      if(rc > 0) {
+        readdir_len = (size_t) rc;
+        sshc->readdir_filename[readdir_len] = '\0';
+
+        if(data->set.ftp_list_only) {
+          result = Curl_client_write(conn, CLIENTWRITE_BODY,
+                                     sshc->readdir_filename,
+                                     readdir_len);
+          if(!result)
+            result = Curl_client_write(conn, CLIENTWRITE_BODY,
+                                       (char *)"\n", 1);
+          if(result) {
+            state(conn, SSH_STOP);
+            break;
+          }
+          /* since this counts what we send to the client, we include the
+             newline in this counter */
+          data->req.bytecount += readdir_len + 1;
+
+          /* output debug output if that is requested */
+          if(data->set.verbose) {
+            Curl_debug(data, CURLINFO_DATA_IN, sshc->readdir_filename,
+                       readdir_len);
+            Curl_debug(data, CURLINFO_DATA_IN, (char *)"\n", 1);
+          }
+        }
+        else {
+          result = Curl_dyn_add(&sshc->readdir, sshc->readdir_longentry);
+
+          if(!result) {
+            if((sshc->readdir_attrs.flags & LIBSSH2_SFTP_ATTR_PERMISSIONS) &&
+               ((sshc->readdir_attrs.permissions & LIBSSH2_SFTP_S_IFMT) ==
+                LIBSSH2_SFTP_S_IFLNK)) {
+              Curl_dyn_init(&sshc->readdir_link, PATH_MAX);
+              result = Curl_dyn_add(&sshc->readdir_link, sftp_scp->path);
+              state(conn, SSH_SFTP_READDIR_LINK);
+              if(!result)
+                break;
+            }
+            else {
+              state(conn, SSH_SFTP_READDIR_BOTTOM);
+              break;
+            }
+          }
+          sshc->actualcode = result;
+          state(conn, SSH_SFTP_CLOSE);
+          break;
+        }
+      }
+      else if(rc == 0) {
+        Curl_safefree(sshc->readdir_filename);
+        Curl_safefree(sshc->readdir_longentry);
+        state(conn, SSH_SFTP_READDIR_DONE);
+        break;
+      }
+      else if(rc < 0) {
+        sftperr = libssh2_sftp_last_error(sshc->sftp_session);
+        result = sftp_libssh2_error_to_CURLE(sftperr);
+        sshc->actualcode = result?result:CURLE_SSH;
+        failf(data, "Could not open remote file for reading: %s :: %d",
+              sftp_libssh2_strerror(sftperr),
+              libssh2_session_last_errno(sshc->ssh_session));
+        Curl_safefree(sshc->readdir_filename);
+        Curl_safefree(sshc->readdir_longentry);
+        state(conn, SSH_SFTP_CLOSE);
+        break;
+      }
+      break;
+
+    case SSH_SFTP_READDIR_LINK:
+      rc =
+        libssh2_sftp_symlink_ex(sshc->sftp_session,
+                                Curl_dyn_ptr(&sshc->readdir_link),
+                                (int)Curl_dyn_len(&sshc->readdir_link),
+                                sshc->readdir_filename,
+                                PATH_MAX, LIBSSH2_SFTP_READLINK);
+      if(rc == LIBSSH2_ERROR_EAGAIN) {
+        break;
+      }
+      readdir_len = (size_t) rc;
+      Curl_dyn_free(&sshc->readdir_link);
+
+      /* append filename and extra output */
+      result = Curl_dyn_addf(&sshc->readdir, " -> %s", sshc->readdir_filename);
+
+      if(result) {
+        sshc->readdir_line = NULL;
+        Curl_safefree(sshc->readdir_filename);
+        Curl_safefree(sshc->readdir_longentry);
+        state(conn, SSH_SFTP_CLOSE);
+        sshc->actualcode = result;
+        break;
+      }
+
+      state(conn, SSH_SFTP_READDIR_BOTTOM);
+      break;
+
+    case SSH_SFTP_READDIR_BOTTOM:
+      result = Curl_dyn_addn(&sshc->readdir, "\n", 1);
+      if(!result)
+        result = Curl_client_write(conn, CLIENTWRITE_BODY,
+                                   Curl_dyn_ptr(&sshc->readdir),
+                                   Curl_dyn_len(&sshc->readdir));
+
+      if(!result) {
+
+        /* output debug output if that is requested */
+        if(data->set.verbose) {
+          Curl_debug(data, CURLINFO_DATA_IN,
+                     Curl_dyn_ptr(&sshc->readdir),
+                     Curl_dyn_len(&sshc->readdir));
+        }
+        data->req.bytecount += Curl_dyn_len(&sshc->readdir);
+      }
+      if(result) {
+        Curl_dyn_free(&sshc->readdir);
+        state(conn, SSH_STOP);
+      }
+      else {
+        Curl_dyn_reset(&sshc->readdir);
+        state(conn, SSH_SFTP_READDIR);
+      }
+      break;
+
+    case SSH_SFTP_READDIR_DONE:
+      if(libssh2_sftp_closedir(sshc->sftp_handle) ==
+         LIBSSH2_ERROR_EAGAIN) {
+        rc = LIBSSH2_ERROR_EAGAIN;
+        break;
+      }
+      sshc->sftp_handle = NULL;
+      Curl_safefree(sshc->readdir_filename);
+      Curl_safefree(sshc->readdir_longentry);
+
+      /* no data to transfer */
+      Curl_setup_transfer(data, -1, -1, FALSE, -1);
+      state(conn, SSH_STOP);
+      break;
+
+    case SSH_SFTP_DOWNLOAD_INIT:
+      /*
+       * Work on getting the specified file
+       */
+      sshc->sftp_handle =
+        libssh2_sftp_open_ex(sshc->sftp_session, sftp_scp->path,
+                             curlx_uztoui(strlen(sftp_scp->path)),
+                             LIBSSH2_FXF_READ, data->set.new_file_perms,
+                             LIBSSH2_SFTP_OPENFILE);
+      if(!sshc->sftp_handle) {
+        if(libssh2_session_last_errno(sshc->ssh_session) ==
+           LIBSSH2_ERROR_EAGAIN) {
+          rc = LIBSSH2_ERROR_EAGAIN;
+          break;
+        }
+        sftperr = libssh2_sftp_last_error(sshc->sftp_session);
+        failf(data, "Could not open remote file for reading: %s",
+              sftp_libssh2_strerror(sftperr));
+        state(conn, SSH_SFTP_CLOSE);
+        result = sftp_libssh2_error_to_CURLE(sftperr);
+        sshc->actualcode = result?result:CURLE_SSH;
+        break;
+      }
+      state(conn, SSH_SFTP_DOWNLOAD_STAT);
+      break;
+
+    case SSH_SFTP_DOWNLOAD_STAT:
+    {
+      LIBSSH2_SFTP_ATTRIBUTES attrs;
+
+      rc = libssh2_sftp_stat_ex(sshc->sftp_session, sftp_scp->path,
+                                curlx_uztoui(strlen(sftp_scp->path)),
+                                LIBSSH2_SFTP_STAT, &attrs);
+      if(rc == LIBSSH2_ERROR_EAGAIN) {
+        break;
+      }
+      if(rc ||
+         !(attrs.flags & LIBSSH2_SFTP_ATTR_SIZE) ||
+         (attrs.filesize == 0)) {
+        /*
+         * libssh2_sftp_open() didn't return an error, so maybe the server
+         * just doesn't support stat()
+         * OR the server doesn't return a file size with a stat()
+         * OR file size is 0
+         */
+        data->req.size = -1;
+        data->req.maxdownload = -1;
+        Curl_pgrsSetDownloadSize(data, -1);
+      }
+      else {
+        curl_off_t size = attrs.filesize;
+
+        if(size < 0) {
+          failf(data, "Bad file size (%" CURL_FORMAT_CURL_OFF_T ")", size);
+          return CURLE_BAD_DOWNLOAD_RESUME;
+        }
+        if(conn->data->state.use_range) {
+          curl_off_t from, to;
+          char *ptr;
+          char *ptr2;
+          CURLofft to_t;
+          CURLofft from_t;
+
+          from_t = curlx_strtoofft(conn->data->state.range, &ptr, 0, &from);
+          if(from_t == CURL_OFFT_FLOW)
+            return CURLE_RANGE_ERROR;
+          while(*ptr && (ISSPACE(*ptr) || (*ptr == '-')))
+            ptr++;
+          to_t = curlx_strtoofft(ptr, &ptr2, 0, &to);
+          if(to_t == CURL_OFFT_FLOW)
+            return CURLE_RANGE_ERROR;
+          if((to_t == CURL_OFFT_INVAL) /* no "to" value given */
+             || (to >= size)) {
+            to = size - 1;
+          }
+          if(from_t) {
+            /* from is relative to end of file */
+            from = size - to;
+            to = size - 1;
+          }
+          if(from > size) {
+            failf(data, "Offset (%"
+                  CURL_FORMAT_CURL_OFF_T ") was beyond file size (%"
+                  CURL_FORMAT_CURL_OFF_T ")", from, attrs.filesize);
+            return CURLE_BAD_DOWNLOAD_RESUME;
+          }
+          if(from > to) {
+            from = to;
+            size = 0;
+          }
+          else {
+            size = to - from + 1;
+          }
+
+          SFTP_SEEK(conn->proto.sshc.sftp_handle, from);
+        }
+        data->req.size = size;
+        data->req.maxdownload = size;
+        Curl_pgrsSetDownloadSize(data, size);
+      }
+
+      /* We can resume if we can seek to the resume position */
+      if(data->state.resume_from) {
+        if(data->state.resume_from < 0) {
+          /* We're supposed to download the last abs(from) bytes */
+          if((curl_off_t)attrs.filesize < -data->state.resume_from) {
+            failf(data, "Offset (%"
+                  CURL_FORMAT_CURL_OFF_T ") was beyond file size (%"
+                  CURL_FORMAT_CURL_OFF_T ")",
+                  data->state.resume_from, attrs.filesize);
+            return CURLE_BAD_DOWNLOAD_RESUME;
+          }
+          /* download from where? */
+          data->state.resume_from += attrs.filesize;
+        }
+        else {
+          if((curl_off_t)attrs.filesize < data->state.resume_from) {
+            failf(data, "Offset (%" CURL_FORMAT_CURL_OFF_T
+                  ") was beyond file size (%" CURL_FORMAT_CURL_OFF_T ")",
+                  data->state.resume_from, attrs.filesize);
+            return CURLE_BAD_DOWNLOAD_RESUME;
+          }
+        }
+        /* Now store the number of bytes we are expected to download */
+        data->req.size = attrs.filesize - data->state.resume_from;
+        data->req.maxdownload = attrs.filesize - data->state.resume_from;
+        Curl_pgrsSetDownloadSize(data,
+                                 attrs.filesize - data->state.resume_from);
+        SFTP_SEEK(sshc->sftp_handle, data->state.resume_from);
+      }
+    }
+
+    /* Setup the actual download */
+    if(data->req.size == 0) {
+      /* no data to transfer */
+      Curl_setup_transfer(data, -1, -1, FALSE, -1);
+      infof(data, "File already completely downloaded\n");
+      state(conn, SSH_STOP);
+      break;
+    }
+    Curl_setup_transfer(data, FIRSTSOCKET, data->req.size, FALSE, -1);
+
+    /* not set by Curl_setup_transfer to preserve keepon bits */
+    conn->writesockfd = conn->sockfd;
+
+    /* we want to use the _receiving_ function even when the socket turns
+       out writableable as the underlying libssh2 recv function will deal
+       with both accordingly */
+    conn->cselect_bits = CURL_CSELECT_IN;
+
+    if(result) {
+      /* this should never occur; the close state should be entered
+         at the time the error occurs */
+      state(conn, SSH_SFTP_CLOSE);
+      sshc->actualcode = result;
+    }
+    else {
+      state(conn, SSH_STOP);
+    }
+    break;
+
+    case SSH_SFTP_CLOSE:
+      if(sshc->sftp_handle) {
+        rc = libssh2_sftp_close(sshc->sftp_handle);
+        if(rc == LIBSSH2_ERROR_EAGAIN) {
+          break;
+        }
+        if(rc < 0) {
+          char *err_msg = NULL;
+          (void)libssh2_session_last_error(sshc->ssh_session,
+                                           &err_msg, NULL, 0);
+          infof(data, "Failed to close libssh2 file: %d %s\n", rc, err_msg);
+        }
+        sshc->sftp_handle = NULL;
+      }
+
+      Curl_safefree(sftp_scp->path);
+
+      DEBUGF(infof(data, "SFTP DONE done\n"));
+
+      /* Check if nextstate is set and move .nextstate could be POSTQUOTE_INIT
+         After nextstate is executed, the control should come back to
+         SSH_SFTP_CLOSE to pass the correct result back  */
+      if(sshc->nextstate != SSH_NO_STATE &&
+         sshc->nextstate != SSH_SFTP_CLOSE) {
+        state(conn, sshc->nextstate);
+        sshc->nextstate = SSH_SFTP_CLOSE;
+      }
+      else {
+        state(conn, SSH_STOP);
+        result = sshc->actualcode;
+      }
+      break;
+
+    case SSH_SFTP_SHUTDOWN:
+      /* during times we get here due to a broken transfer and then the
+         sftp_handle might not have been taken down so make sure that is done
+         before we proceed */
+
+      if(sshc->sftp_handle) {
+        rc = libssh2_sftp_close(sshc->sftp_handle);
+        if(rc == LIBSSH2_ERROR_EAGAIN) {
+          break;
+        }
+        if(rc < 0) {
+          char *err_msg = NULL;
+          (void)libssh2_session_last_error(sshc->ssh_session, &err_msg,
+                                           NULL, 0);
+          infof(data, "Failed to close libssh2 file: %d %s\n", rc, err_msg);
+        }
+        sshc->sftp_handle = NULL;
+      }
+      if(sshc->sftp_session) {
+        rc = libssh2_sftp_shutdown(sshc->sftp_session);
+        if(rc == LIBSSH2_ERROR_EAGAIN) {
+          break;
+        }
+        if(rc < 0) {
+          infof(data, "Failed to stop libssh2 sftp subsystem\n");
+        }
+        sshc->sftp_session = NULL;
+      }
+
+      Curl_safefree(sshc->homedir);
+      conn->data->state.most_recent_ftp_entrypath = NULL;
+
+      state(conn, SSH_SESSION_DISCONNECT);
+      break;
+
+    case SSH_SCP_TRANS_INIT:
+      result = Curl_getworkingpath(conn, sshc->homedir, &sftp_scp->path);
+      if(result) {
+        sshc->actualcode = result;
+        state(conn, SSH_STOP);
+        break;
+      }
+
+      if(data->set.upload) {
+        if(data->state.infilesize < 0) {
+          failf(data, "SCP requires a known file size for upload");
+          sshc->actualcode = CURLE_UPLOAD_FAILED;
+          state(conn, SSH_SCP_CHANNEL_FREE);
+          break;
+        }
+        state(conn, SSH_SCP_UPLOAD_INIT);
+      }
+      else {
+        state(conn, SSH_SCP_DOWNLOAD_INIT);
+      }
+      break;
+
+    case SSH_SCP_UPLOAD_INIT:
+      /*
+       * libssh2 requires that the destination path is a full path that
+       * includes the destination file and name OR ends in a "/" .  If this is
+       * not done the destination file will be named the same name as the last
+       * directory in the path.
+       */
+      sshc->ssh_channel =
+        SCP_SEND(sshc->ssh_session, sftp_scp->path, data->set.new_file_perms,
+                 data->state.infilesize);
+      if(!sshc->ssh_channel) {
+        int ssh_err;
+        char *err_msg = NULL;
+
+        if(libssh2_session_last_errno(sshc->ssh_session) ==
+           LIBSSH2_ERROR_EAGAIN) {
+          rc = LIBSSH2_ERROR_EAGAIN;
+          break;
+        }
+
+        ssh_err = (int)(libssh2_session_last_error(sshc->ssh_session,
+                                                   &err_msg, NULL, 0));
+        failf(conn->data, "%s", err_msg);
+        state(conn, SSH_SCP_CHANNEL_FREE);
+        sshc->actualcode = libssh2_session_error_to_CURLE(ssh_err);
+        /* Map generic errors to upload failed */
+        if(sshc->actualcode == CURLE_SSH ||
+           sshc->actualcode == CURLE_REMOTE_FILE_NOT_FOUND)
+          sshc->actualcode = CURLE_UPLOAD_FAILED;
+        break;
+      }
+
+      /* upload data */
+      data->req.size = data->state.infilesize;
+      Curl_pgrsSetUploadSize(data, data->state.infilesize);
+      Curl_setup_transfer(data, -1, -1, FALSE, FIRSTSOCKET);
+
+      /* not set by Curl_setup_transfer to preserve keepon bits */
+      conn->sockfd = conn->writesockfd;
+
+      if(result) {
+        state(conn, SSH_SCP_CHANNEL_FREE);
+        sshc->actualcode = result;
+      }
+      else {
+        /* store this original bitmask setup to use later on if we can't
+           figure out a "real" bitmask */
+        sshc->orig_waitfor = data->req.keepon;
+
+        /* we want to use the _sending_ function even when the socket turns
+           out readable as the underlying libssh2 scp send function will deal
+           with both accordingly */
+        conn->cselect_bits = CURL_CSELECT_OUT;
+
+        state(conn, SSH_STOP);
+      }
+      break;
+
+    case SSH_SCP_DOWNLOAD_INIT:
+    {
+      curl_off_t bytecount;
+
+      /*
+       * We must check the remote file; if it is a directory no values will
+       * be set in sb
+       */
+
+      /*
+       * If support for >2GB files exists, use it.
+       */
+
+      /* get a fresh new channel from the ssh layer */
+#if LIBSSH2_VERSION_NUM < 0x010700
+      struct stat sb;
+      memset(&sb, 0, sizeof(struct stat));
+      sshc->ssh_channel = libssh2_scp_recv(sshc->ssh_session,
+                                           sftp_scp->path, &sb);
+#else
+      libssh2_struct_stat sb;
+      memset(&sb, 0, sizeof(libssh2_struct_stat));
+      sshc->ssh_channel = libssh2_scp_recv2(sshc->ssh_session,
+                                            sftp_scp->path, &sb);
+#endif
+
+      if(!sshc->ssh_channel) {
+        int ssh_err;
+        char *err_msg = NULL;
+
+        if(libssh2_session_last_errno(sshc->ssh_session) ==
+           LIBSSH2_ERROR_EAGAIN) {
+          rc = LIBSSH2_ERROR_EAGAIN;
+          break;
+        }
+
+
+        ssh_err = (int)(libssh2_session_last_error(sshc->ssh_session,
+                                                   &err_msg, NULL, 0));
+        failf(conn->data, "%s", err_msg);
+        state(conn, SSH_SCP_CHANNEL_FREE);
+        sshc->actualcode = libssh2_session_error_to_CURLE(ssh_err);
+        break;
+      }
+
+      /* download data */
+      bytecount = (curl_off_t)sb.st_size;
+      data->req.maxdownload = (curl_off_t)sb.st_size;
+      Curl_setup_transfer(data, FIRSTSOCKET, bytecount, FALSE, -1);
+
+      /* not set by Curl_setup_transfer to preserve keepon bits */
+      conn->writesockfd = conn->sockfd;
+
+      /* we want to use the _receiving_ function even when the socket turns
+         out writableable as the underlying libssh2 recv function will deal
+         with both accordingly */
+      conn->cselect_bits = CURL_CSELECT_IN;
+
+      if(result) {
+        state(conn, SSH_SCP_CHANNEL_FREE);
+        sshc->actualcode = result;
+      }
+      else
+        state(conn, SSH_STOP);
+    }
+    break;
+
+    case SSH_SCP_DONE:
+      if(data->set.upload)
+        state(conn, SSH_SCP_SEND_EOF);
+      else
+        state(conn, SSH_SCP_CHANNEL_FREE);
+      break;
+
+    case SSH_SCP_SEND_EOF:
+      if(sshc->ssh_channel) {
+        rc = libssh2_channel_send_eof(sshc->ssh_channel);
+        if(rc == LIBSSH2_ERROR_EAGAIN) {
+          break;
+        }
+        if(rc) {
+          char *err_msg = NULL;
+          (void)libssh2_session_last_error(sshc->ssh_session,
+                                           &err_msg, NULL, 0);
+          infof(data, "Failed to send libssh2 channel EOF: %d %s\n",
+                rc, err_msg);
+        }
+      }
+      state(conn, SSH_SCP_WAIT_EOF);
+      break;
+
+    case SSH_SCP_WAIT_EOF:
+      if(sshc->ssh_channel) {
+        rc = libssh2_channel_wait_eof(sshc->ssh_channel);
+        if(rc == LIBSSH2_ERROR_EAGAIN) {
+          break;
+        }
+        if(rc) {
+          char *err_msg = NULL;
+          (void)libssh2_session_last_error(sshc->ssh_session,
+                                           &err_msg, NULL, 0);
+          infof(data, "Failed to get channel EOF: %d %s\n", rc, err_msg);
+        }
+      }
+      state(conn, SSH_SCP_WAIT_CLOSE);
+      break;
+
+    case SSH_SCP_WAIT_CLOSE:
+      if(sshc->ssh_channel) {
+        rc = libssh2_channel_wait_closed(sshc->ssh_channel);
+        if(rc == LIBSSH2_ERROR_EAGAIN) {
+          break;
+        }
+        if(rc) {
+          char *err_msg = NULL;
+          (void)libssh2_session_last_error(sshc->ssh_session,
+                                           &err_msg, NULL, 0);
+          infof(data, "Channel failed to close: %d %s\n", rc, err_msg);
+        }
+      }
+      state(conn, SSH_SCP_CHANNEL_FREE);
+      break;
+
+    case SSH_SCP_CHANNEL_FREE:
+      if(sshc->ssh_channel) {
+        rc = libssh2_channel_free(sshc->ssh_channel);
+        if(rc == LIBSSH2_ERROR_EAGAIN) {
+          break;
+        }
+        if(rc < 0) {
+          char *err_msg = NULL;
+          (void)libssh2_session_last_error(sshc->ssh_session,
+                                           &err_msg, NULL, 0);
+          infof(data, "Failed to free libssh2 scp subsystem: %d %s\n",
+                rc, err_msg);
+        }
+        sshc->ssh_channel = NULL;
+      }
+      DEBUGF(infof(data, "SCP DONE phase complete\n"));
+#if 0 /* PREV */
+      state(conn, SSH_SESSION_DISCONNECT);
+#endif
+      state(conn, SSH_STOP);
+      result = sshc->actualcode;
+      break;
+
+    case SSH_SESSION_DISCONNECT:
+      /* during weird times when we've been prematurely aborted, the channel
+         is still alive when we reach this state and we MUST kill the channel
+         properly first */
+      if(sshc->ssh_channel) {
+        rc = libssh2_channel_free(sshc->ssh_channel);
+        if(rc == LIBSSH2_ERROR_EAGAIN) {
+          break;
+        }
+        if(rc < 0) {
+          char *err_msg = NULL;
+          (void)libssh2_session_last_error(sshc->ssh_session,
+                                           &err_msg, NULL, 0);
+          infof(data, "Failed to free libssh2 scp subsystem: %d %s\n",
+                rc, err_msg);
+        }
+        sshc->ssh_channel = NULL;
+      }
+
+      if(sshc->ssh_session) {
+        rc = libssh2_session_disconnect(sshc->ssh_session, "Shutdown");
+        if(rc == LIBSSH2_ERROR_EAGAIN) {
+          break;
+        }
+        if(rc < 0) {
+          char *err_msg = NULL;
+          (void)libssh2_session_last_error(sshc->ssh_session,
+                                           &err_msg, NULL, 0);
+          infof(data, "Failed to disconnect libssh2 session: %d %s\n",
+                rc, err_msg);
+        }
+      }
+
+      Curl_safefree(sshc->homedir);
+      conn->data->state.most_recent_ftp_entrypath = NULL;
+
+      state(conn, SSH_SESSION_FREE);
+      break;
+
+    case SSH_SESSION_FREE:
+#ifdef HAVE_LIBSSH2_KNOWNHOST_API
+      if(sshc->kh) {
+        libssh2_knownhost_free(sshc->kh);
+        sshc->kh = NULL;
+      }
+#endif
+
+#ifdef HAVE_LIBSSH2_AGENT_API
+      if(sshc->ssh_agent) {
+        rc = libssh2_agent_disconnect(sshc->ssh_agent);
+        if(rc == LIBSSH2_ERROR_EAGAIN) {
+          break;
+        }
+        if(rc < 0) {
+          char *err_msg = NULL;
+          (void)libssh2_session_last_error(sshc->ssh_session,
+                                           &err_msg, NULL, 0);
+          infof(data, "Failed to disconnect from libssh2 agent: %d %s\n",
+                rc, err_msg);
+        }
+        libssh2_agent_free(sshc->ssh_agent);
+        sshc->ssh_agent = NULL;
+
+        /* NB: there is no need to free identities, they are part of internal
+           agent stuff */
+        sshc->sshagent_identity = NULL;
+        sshc->sshagent_prev_identity = NULL;
+      }
+#endif
+
+      if(sshc->ssh_session) {
+        rc = libssh2_session_free(sshc->ssh_session);
+        if(rc == LIBSSH2_ERROR_EAGAIN) {
+          break;
+        }
+        if(rc < 0) {
+          char *err_msg = NULL;
+          (void)libssh2_session_last_error(sshc->ssh_session,
+                                           &err_msg, NULL, 0);
+          infof(data, "Failed to free libssh2 session: %d %s\n", rc, err_msg);
+        }
+        sshc->ssh_session = NULL;
+      }
+
+      /* worst-case scenario cleanup */
+
+      DEBUGASSERT(sshc->ssh_session == NULL);
+      DEBUGASSERT(sshc->ssh_channel == NULL);
+      DEBUGASSERT(sshc->sftp_session == NULL);
+      DEBUGASSERT(sshc->sftp_handle == NULL);
+#ifdef HAVE_LIBSSH2_KNOWNHOST_API
+      DEBUGASSERT(sshc->kh == NULL);
+#endif
+#ifdef HAVE_LIBSSH2_AGENT_API
+      DEBUGASSERT(sshc->ssh_agent == NULL);
+#endif
+
+      Curl_safefree(sshc->rsa_pub);
+      Curl_safefree(sshc->rsa);
+
+      Curl_safefree(sshc->quote_path1);
+      Curl_safefree(sshc->quote_path2);
+
+      Curl_safefree(sshc->homedir);
+
+      Curl_safefree(sshc->readdir_filename);
+      Curl_safefree(sshc->readdir_longentry);
+      Curl_safefree(sshc->readdir_line);
+      Curl_dyn_free(&sshc->readdir);
+
+      /* the code we are about to return */
+      result = sshc->actualcode;
+
+      memset(sshc, 0, sizeof(struct ssh_conn));
+
+      connclose(conn, "SSH session free");
+      sshc->state = SSH_SESSION_FREE; /* current */
+      sshc->nextstate = SSH_NO_STATE;
+      state(conn, SSH_STOP);
+      break;
+
+    case SSH_QUIT:
+      /* fallthrough, just stop! */
+    default:
+      /* internal error */
+      sshc->nextstate = SSH_NO_STATE;
+      state(conn, SSH_STOP);
+      break;
+    }
+
+  } while(!rc && (sshc->state != SSH_STOP));
+
+  if(rc == LIBSSH2_ERROR_EAGAIN) {
+    /* we would block, we need to wait for the socket to be ready (in the
+       right direction too)! */
+    *block = TRUE;
+  }
+
+  return result;
+}
+
+/* called by the multi interface to figure out what socket(s) to wait for and
+   for what actions in the DO_DONE, PERFORM and WAITPERFORM states */
+static int ssh_perform_getsock(const struct connectdata *conn,
+                               curl_socket_t *sock)
+{
+#ifdef HAVE_LIBSSH2_SESSION_BLOCK_DIRECTION
+  int bitmap = GETSOCK_BLANK;
+
+  sock[0] = conn->sock[FIRSTSOCKET];
+
+  if(conn->waitfor & KEEP_RECV)
+    bitmap |= GETSOCK_READSOCK(FIRSTSOCKET);
+
+  if(conn->waitfor & KEEP_SEND)
+    bitmap |= GETSOCK_WRITESOCK(FIRSTSOCKET);
+
+  return bitmap;
+#else
+  /* if we don't know the direction we can use the generic *_getsock()
+     function even for the protocol_connect and doing states */
+  return Curl_single_getsock(conn, sock);
+#endif
+}
+
+/* Generic function called by the multi interface to figure out what socket(s)
+   to wait for and for what actions during the DOING and PROTOCONNECT states*/
+static int ssh_getsock(struct connectdata *conn,
+                       curl_socket_t *sock)
+{
+#ifndef HAVE_LIBSSH2_SESSION_BLOCK_DIRECTION
+  (void)conn;
+  (void)sock;
+  /* if we don't know any direction we can just play along as we used to and
+     not provide any sensible info */
+  return GETSOCK_BLANK;
+#else
+  /* if we know the direction we can use the generic *_getsock() function even
+     for the protocol_connect and doing states */
+  return ssh_perform_getsock(conn, sock);
+#endif
+}
+
+#ifdef HAVE_LIBSSH2_SESSION_BLOCK_DIRECTION
+/*
+ * When one of the libssh2 functions has returned LIBSSH2_ERROR_EAGAIN this
+ * function is used to figure out in what direction and stores this info so
+ * that the multi interface can take advantage of it. Make sure to call this
+ * function in all cases so that when it _doesn't_ return EAGAIN we can
+ * restore the default wait bits.
+ */
+static void ssh_block2waitfor(struct connectdata *conn, bool block)
+{
+  struct ssh_conn *sshc = &conn->proto.sshc;
+  int dir = 0;
+  if(block) {
+    dir = libssh2_session_block_directions(sshc->ssh_session);
+    if(dir) {
+      /* translate the libssh2 define bits into our own bit defines */
+      conn->waitfor = ((dir&LIBSSH2_SESSION_BLOCK_INBOUND)?KEEP_RECV:0) |
+        ((dir&LIBSSH2_SESSION_BLOCK_OUTBOUND)?KEEP_SEND:0);
+    }
+  }
+  if(!dir)
+    /* It didn't block or libssh2 didn't reveal in which direction, put back
+       the original set */
+    conn->waitfor = sshc->orig_waitfor;
+}
+#else
+  /* no libssh2 directional support so we simply don't know */
+#define ssh_block2waitfor(x,y) Curl_nop_stmt
+#endif
+
+/* called repeatedly until done from multi.c */
+static CURLcode ssh_multi_statemach(struct connectdata *conn, bool *done)
+{
+  struct ssh_conn *sshc = &conn->proto.sshc;
+  CURLcode result = CURLE_OK;
+  bool block; /* we store the status and use that to provide a ssh_getsock()
+                 implementation */
+  do {
+    result = ssh_statemach_act(conn, &block);
+    *done = (sshc->state == SSH_STOP) ? TRUE : FALSE;
+    /* if there's no error, it isn't done and it didn't EWOULDBLOCK, then
+       try again */
+  } while(!result && !*done && !block);
+  ssh_block2waitfor(conn, block);
+
+  return result;
+}
+
+static CURLcode ssh_block_statemach(struct connectdata *conn,
+                                   bool duringconnect)
+{
+  struct ssh_conn *sshc = &conn->proto.sshc;
+  CURLcode result = CURLE_OK;
+  struct Curl_easy *data = conn->data;
+
+  while((sshc->state != SSH_STOP) && !result) {
+    bool block;
+    timediff_t left = 1000;
+    struct curltime now = Curl_now();
+
+    result = ssh_statemach_act(conn, &block);
+    if(result)
+      break;
+
+    if(Curl_pgrsUpdate(conn))
+      return CURLE_ABORTED_BY_CALLBACK;
+
+    result = Curl_speedcheck(data, now);
+    if(result)
+      break;
+
+    left = Curl_timeleft(data, NULL, duringconnect);
+    if(left < 0) {
+      failf(data, "Operation timed out");
+      return CURLE_OPERATION_TIMEDOUT;
+    }
+
+#ifdef HAVE_LIBSSH2_SESSION_BLOCK_DIRECTION
+    if(block) {
+      int dir = libssh2_session_block_directions(sshc->ssh_session);
+      curl_socket_t sock = conn->sock[FIRSTSOCKET];
+      curl_socket_t fd_read = CURL_SOCKET_BAD;
+      curl_socket_t fd_write = CURL_SOCKET_BAD;
+      if(LIBSSH2_SESSION_BLOCK_INBOUND & dir)
+        fd_read = sock;
+      if(LIBSSH2_SESSION_BLOCK_OUTBOUND & dir)
+        fd_write = sock;
+      /* wait for the socket to become ready */
+      (void)Curl_socket_check(fd_read, CURL_SOCKET_BAD, fd_write,
+                              left>1000?1000:left);
+    }
+#endif
+
+  }
+
+  return result;
+}
+
+/*
+ * SSH setup and connection
+ */
+static CURLcode ssh_setup_connection(struct connectdata *conn)
+{
+  struct SSHPROTO *ssh;
+
+  conn->data->req.protop = ssh = calloc(1, sizeof(struct SSHPROTO));
+  if(!ssh)
+    return CURLE_OUT_OF_MEMORY;
+
+  return CURLE_OK;
+}
+
+static Curl_recv scp_recv, sftp_recv;
+static Curl_send scp_send, sftp_send;
+
+/*
+ * Curl_ssh_connect() gets called from Curl_protocol_connect() to allow us to
+ * do protocol-specific actions at connect-time.
+ */
+static CURLcode ssh_connect(struct connectdata *conn, bool *done)
+{
+#ifdef CURL_LIBSSH2_DEBUG
+  curl_socket_t sock;
+#endif
+  struct ssh_conn *ssh;
+  CURLcode result;
+  struct Curl_easy *data = conn->data;
+
+  /* initialize per-handle data if not already */
+  if(!data->req.protop)
+    ssh_setup_connection(conn);
+
+  /* We default to persistent connections. We set this already in this connect
+     function to make the re-use checks properly be able to check this bit. */
+  connkeep(conn, "SSH default");
+
+  if(conn->handler->protocol & CURLPROTO_SCP) {
+    conn->recv[FIRSTSOCKET] = scp_recv;
+    conn->send[FIRSTSOCKET] = scp_send;
+  }
+  else {
+    conn->recv[FIRSTSOCKET] = sftp_recv;
+    conn->send[FIRSTSOCKET] = sftp_send;
+  }
+  ssh = &conn->proto.sshc;
+
+#ifdef CURL_LIBSSH2_DEBUG
+  if(conn->user) {
+    infof(data, "User: %s\n", conn->user);
+  }
+  if(conn->passwd) {
+    infof(data, "Password: %s\n", conn->passwd);
+  }
+  sock = conn->sock[FIRSTSOCKET];
+#endif /* CURL_LIBSSH2_DEBUG */
+
+  ssh->ssh_session = libssh2_session_init_ex(my_libssh2_malloc,
+                                             my_libssh2_free,
+                                             my_libssh2_realloc, conn);
+  if(ssh->ssh_session == NULL) {
+    failf(data, "Failure initialising ssh session");
+    return CURLE_FAILED_INIT;
+  }
+
+  if(data->set.ssh_compression) {
+#if LIBSSH2_VERSION_NUM >= 0x010208
+    if(libssh2_session_flag(ssh->ssh_session, LIBSSH2_FLAG_COMPRESS, 1) < 0)
+#endif
+      infof(data, "Failed to enable compression for ssh session\n");
+  }
+
+#ifdef HAVE_LIBSSH2_KNOWNHOST_API
+  if(data->set.str[STRING_SSH_KNOWNHOSTS]) {
+    int rc;
+    ssh->kh = libssh2_knownhost_init(ssh->ssh_session);
+    if(!ssh->kh) {
+      libssh2_session_free(ssh->ssh_session);
+      return CURLE_FAILED_INIT;
+    }
+
+    /* read all known hosts from there */
+    rc = libssh2_knownhost_readfile(ssh->kh,
+                                    data->set.str[STRING_SSH_KNOWNHOSTS],
+                                    LIBSSH2_KNOWNHOST_FILE_OPENSSH);
+    if(rc < 0)
+      infof(data, "Failed to read known hosts from %s\n",
+            data->set.str[STRING_SSH_KNOWNHOSTS]);
+  }
+#endif /* HAVE_LIBSSH2_KNOWNHOST_API */
+
+#ifdef CURL_LIBSSH2_DEBUG
+  libssh2_trace(ssh->ssh_session, ~0);
+  infof(data, "SSH socket: %d\n", (int)sock);
+#endif /* CURL_LIBSSH2_DEBUG */
+
+  state(conn, SSH_INIT);
+
+  result = ssh_multi_statemach(conn, done);
+
+  return result;
+}
+
+/*
+ ***********************************************************************
+ *
+ * scp_perform()
+ *
+ * This is the actual DO function for SCP. Get a file according to
+ * the options previously setup.
+ */
+
+static
+CURLcode scp_perform(struct connectdata *conn,
+                      bool *connected,
+                      bool *dophase_done)
+{
+  CURLcode result = CURLE_OK;
+
+  DEBUGF(infof(conn->data, "DO phase starts\n"));
+
+  *dophase_done = FALSE; /* not done yet */
+
+  /* start the first command in the DO phase */
+  state(conn, SSH_SCP_TRANS_INIT);
+
+  /* run the state-machine */
+  result = ssh_multi_statemach(conn, dophase_done);
+
+  *connected = conn->bits.tcpconnect[FIRSTSOCKET];
+
+  if(*dophase_done) {
+    DEBUGF(infof(conn->data, "DO phase is complete\n"));
+  }
+
+  return result;
+}
+
+/* called from multi.c while DOing */
+static CURLcode scp_doing(struct connectdata *conn,
+                               bool *dophase_done)
+{
+  CURLcode result;
+  result = ssh_multi_statemach(conn, dophase_done);
+
+  if(*dophase_done) {
+    DEBUGF(infof(conn->data, "DO phase is complete\n"));
+  }
+  return result;
+}
+
+/*
+ * The DO function is generic for both protocols. There was previously two
+ * separate ones but this way means less duplicated code.
+ */
+
+static CURLcode ssh_do(struct connectdata *conn, bool *done)
+{
+  CURLcode result;
+  bool connected = 0;
+  struct Curl_easy *data = conn->data;
+  struct ssh_conn *sshc = &conn->proto.sshc;
+
+  *done = FALSE; /* default to false */
+
+  data->req.size = -1; /* make sure this is unknown at this point */
+
+  sshc->actualcode = CURLE_OK; /* reset error code */
+  sshc->secondCreateDirs = 0;   /* reset the create dir attempt state
+                                   variable */
+
+  Curl_pgrsSetUploadCounter(data, 0);
+  Curl_pgrsSetDownloadCounter(data, 0);
+  Curl_pgrsSetUploadSize(data, -1);
+  Curl_pgrsSetDownloadSize(data, -1);
+
+  if(conn->handler->protocol & CURLPROTO_SCP)
+    result = scp_perform(conn, &connected,  done);
+  else
+    result = sftp_perform(conn, &connected,  done);
+
+  return result;
+}
+
+/* BLOCKING, but the function is using the state machine so the only reason
+   this is still blocking is that the multi interface code has no support for
+   disconnecting operations that takes a while */
+static CURLcode scp_disconnect(struct connectdata *conn, bool dead_connection)
+{
+  CURLcode result = CURLE_OK;
+  struct ssh_conn *ssh = &conn->proto.sshc;
+  (void) dead_connection;
+
+  if(ssh->ssh_session) {
+    /* only if there's a session still around to use! */
+
+    state(conn, SSH_SESSION_DISCONNECT);
+
+    result = ssh_block_statemach(conn, FALSE);
+  }
+
+  return result;
+}
+
+/* generic done function for both SCP and SFTP called from their specific
+   done functions */
+static CURLcode ssh_done(struct connectdata *conn, CURLcode status)
+{
+  CURLcode result = CURLE_OK;
+  struct SSHPROTO *sftp_scp = conn->data->req.protop;
+
+  if(!status) {
+    /* run the state-machine */
+    result = ssh_block_statemach(conn, FALSE);
+  }
+  else
+    result = status;
+
+  if(sftp_scp)
+    Curl_safefree(sftp_scp->path);
+  if(Curl_pgrsDone(conn))
+    return CURLE_ABORTED_BY_CALLBACK;
+
+  conn->data->req.keepon = 0; /* clear all bits */
+  return result;
+}
+
+
+static CURLcode scp_done(struct connectdata *conn, CURLcode status,
+                         bool premature)
+{
+  (void)premature; /* not used */
+
+  if(!status)
+    state(conn, SSH_SCP_DONE);
+
+  return ssh_done(conn, status);
+
+}
+
+static ssize_t scp_send(struct connectdata *conn, int sockindex,
+                        const void *mem, size_t len, CURLcode *err)
+{
+  ssize_t nwrite;
+  (void)sockindex; /* we only support SCP on the fixed known primary socket */
+
+  /* libssh2_channel_write() returns int! */
+  nwrite = (ssize_t)
+    libssh2_channel_write(conn->proto.sshc.ssh_channel, mem, len);
+
+  ssh_block2waitfor(conn, (nwrite == LIBSSH2_ERROR_EAGAIN)?TRUE:FALSE);
+
+  if(nwrite == LIBSSH2_ERROR_EAGAIN) {
+    *err = CURLE_AGAIN;
+    nwrite = 0;
+  }
+  else if(nwrite < LIBSSH2_ERROR_NONE) {
+    *err = libssh2_session_error_to_CURLE((int)nwrite);
+    nwrite = -1;
+  }
+
+  return nwrite;
+}
+
+static ssize_t scp_recv(struct connectdata *conn, int sockindex,
+                        char *mem, size_t len, CURLcode *err)
+{
+  ssize_t nread;
+  (void)sockindex; /* we only support SCP on the fixed known primary socket */
+
+  /* libssh2_channel_read() returns int */
+  nread = (ssize_t)
+    libssh2_channel_read(conn->proto.sshc.ssh_channel, mem, len);
+
+  ssh_block2waitfor(conn, (nread == LIBSSH2_ERROR_EAGAIN)?TRUE:FALSE);
+  if(nread == LIBSSH2_ERROR_EAGAIN) {
+    *err = CURLE_AGAIN;
+    nread = -1;
+  }
+
+  return nread;
+}
+
+/*
+ * =============== SFTP ===============
+ */
+
+/*
+ ***********************************************************************
+ *
+ * sftp_perform()
+ *
+ * This is the actual DO function for SFTP. Get a file/directory according to
+ * the options previously setup.
+ */
+
+static
+CURLcode sftp_perform(struct connectdata *conn,
+                      bool *connected,
+                      bool *dophase_done)
+{
+  CURLcode result = CURLE_OK;
+
+  DEBUGF(infof(conn->data, "DO phase starts\n"));
+
+  *dophase_done = FALSE; /* not done yet */
+
+  /* start the first command in the DO phase */
+  state(conn, SSH_SFTP_QUOTE_INIT);
+
+  /* run the state-machine */
+  result = ssh_multi_statemach(conn, dophase_done);
+
+  *connected = conn->bits.tcpconnect[FIRSTSOCKET];
+
+  if(*dophase_done) {
+    DEBUGF(infof(conn->data, "DO phase is complete\n"));
+  }
+
+  return result;
+}
+
+/* called from multi.c while DOing */
+static CURLcode sftp_doing(struct connectdata *conn,
+                           bool *dophase_done)
+{
+  CURLcode result = ssh_multi_statemach(conn, dophase_done);
+
+  if(*dophase_done) {
+    DEBUGF(infof(conn->data, "DO phase is complete\n"));
+  }
+  return result;
+}
+
+/* BLOCKING, but the function is using the state machine so the only reason
+   this is still blocking is that the multi interface code has no support for
+   disconnecting operations that takes a while */
+static CURLcode sftp_disconnect(struct connectdata *conn, bool dead_connection)
+{
+  CURLcode result = CURLE_OK;
+  (void) dead_connection;
+
+  DEBUGF(infof(conn->data, "SSH DISCONNECT starts now\n"));
+
+  if(conn->proto.sshc.ssh_session) {
+    /* only if there's a session still around to use! */
+    state(conn, SSH_SFTP_SHUTDOWN);
+    result = ssh_block_statemach(conn, FALSE);
+  }
+
+  DEBUGF(infof(conn->data, "SSH DISCONNECT is done\n"));
+
+  return result;
+
+}
+
+static CURLcode sftp_done(struct connectdata *conn, CURLcode status,
+                               bool premature)
+{
+  struct ssh_conn *sshc = &conn->proto.sshc;
+
+  if(!status) {
+    /* Post quote commands are executed after the SFTP_CLOSE state to avoid
+       errors that could happen due to open file handles during POSTQUOTE
+       operation */
+    if(!premature && conn->data->set.postquote && !conn->bits.retry)
+      sshc->nextstate = SSH_SFTP_POSTQUOTE_INIT;
+    state(conn, SSH_SFTP_CLOSE);
+  }
+  return ssh_done(conn, status);
+}
+
+/* return number of sent bytes */
+static ssize_t sftp_send(struct connectdata *conn, int sockindex,
+                         const void *mem, size_t len, CURLcode *err)
+{
+  ssize_t nwrite;   /* libssh2_sftp_write() used to return size_t in 0.14
+                       but is changed to ssize_t in 0.15. These days we don't
+                       support libssh2 0.15*/
+  (void)sockindex;
+
+  nwrite = libssh2_sftp_write(conn->proto.sshc.sftp_handle, mem, len);
+
+  ssh_block2waitfor(conn, (nwrite == LIBSSH2_ERROR_EAGAIN)?TRUE:FALSE);
+
+  if(nwrite == LIBSSH2_ERROR_EAGAIN) {
+    *err = CURLE_AGAIN;
+    nwrite = 0;
+  }
+  else if(nwrite < LIBSSH2_ERROR_NONE) {
+    *err = libssh2_session_error_to_CURLE((int)nwrite);
+    nwrite = -1;
+  }
+
+  return nwrite;
+}
+
+/*
+ * Return number of received (decrypted) bytes
+ * or <0 on error
+ */
+static ssize_t sftp_recv(struct connectdata *conn, int sockindex,
+                         char *mem, size_t len, CURLcode *err)
+{
+  ssize_t nread;
+  (void)sockindex;
+
+  nread = libssh2_sftp_read(conn->proto.sshc.sftp_handle, mem, len);
+
+  ssh_block2waitfor(conn, (nread == LIBSSH2_ERROR_EAGAIN)?TRUE:FALSE);
+
+  if(nread == LIBSSH2_ERROR_EAGAIN) {
+    *err = CURLE_AGAIN;
+    nread = -1;
+
+  }
+  else if(nread < 0) {
+    *err = libssh2_session_error_to_CURLE((int)nread);
+  }
+  return nread;
+}
+
+static const char *sftp_libssh2_strerror(unsigned long err)
+{
+  switch(err) {
+    case LIBSSH2_FX_NO_SUCH_FILE:
+      return "No such file or directory";
+
+    case LIBSSH2_FX_PERMISSION_DENIED:
+      return "Permission denied";
+
+    case LIBSSH2_FX_FAILURE:
+      return "Operation failed";
+
+    case LIBSSH2_FX_BAD_MESSAGE:
+      return "Bad message from SFTP server";
+
+    case LIBSSH2_FX_NO_CONNECTION:
+      return "Not connected to SFTP server";
+
+    case LIBSSH2_FX_CONNECTION_LOST:
+      return "Connection to SFTP server lost";
+
+    case LIBSSH2_FX_OP_UNSUPPORTED:
+      return "Operation not supported by SFTP server";
+
+    case LIBSSH2_FX_INVALID_HANDLE:
+      return "Invalid handle";
+
+    case LIBSSH2_FX_NO_SUCH_PATH:
+      return "No such file or directory";
+
+    case LIBSSH2_FX_FILE_ALREADY_EXISTS:
+      return "File already exists";
+
+    case LIBSSH2_FX_WRITE_PROTECT:
+      return "File is write protected";
+
+    case LIBSSH2_FX_NO_MEDIA:
+      return "No media";
+
+    case LIBSSH2_FX_NO_SPACE_ON_FILESYSTEM:
+      return "Disk full";
+
+    case LIBSSH2_FX_QUOTA_EXCEEDED:
+      return "User quota exceeded";
+
+    case LIBSSH2_FX_UNKNOWN_PRINCIPLE:
+      return "Unknown principle";
+
+    case LIBSSH2_FX_LOCK_CONFlICT:
+      return "File lock conflict";
+
+    case LIBSSH2_FX_DIR_NOT_EMPTY:
+      return "Directory not empty";
+
+    case LIBSSH2_FX_NOT_A_DIRECTORY:
+      return "Not a directory";
+
+    case LIBSSH2_FX_INVALID_FILENAME:
+      return "Invalid filename";
+
+    case LIBSSH2_FX_LINK_LOOP:
+      return "Link points to itself";
+  }
+  return "Unknown error in libssh2";
+}
+
+CURLcode Curl_ssh_init(void)
+{
+#ifdef HAVE_LIBSSH2_INIT
+  if(libssh2_init(0)) {
+    DEBUGF(fprintf(stderr, "Error: libssh2_init failed\n"));
+    return CURLE_FAILED_INIT;
+  }
+#endif
+  return CURLE_OK;
+}
+
+void Curl_ssh_cleanup(void)
+{
+#ifdef HAVE_LIBSSH2_EXIT
+  (void)libssh2_exit();
+#endif
+}
+
+size_t Curl_ssh_version(char *buffer, size_t buflen)
+{
+  return msnprintf(buffer, buflen, "libssh2/%s", LIBSSH2_VERSION);
+}
+
+#endif /* USE_LIBSSH2 */
diff --git a/Utilities/cmcurl/lib/vssh/ssh.h b/Utilities/cmcurl/lib/vssh/ssh.h
new file mode 100644
index 0000000..9e49993
--- /dev/null
+++ b/Utilities/cmcurl/lib/vssh/ssh.h
@@ -0,0 +1,264 @@
+#ifndef HEADER_CURL_SSH_H
+#define HEADER_CURL_SSH_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#if defined(HAVE_LIBSSH2_H)
+#include <libssh2.h>
+#include <libssh2_sftp.h>
+#elif defined(HAVE_LIBSSH_LIBSSH_H)
+#include <libssh/libssh.h>
+#include <libssh/sftp.h>
+#elif defined(USE_WOLFSSH)
+#include <wolfssh/ssh.h>
+#include <wolfssh/wolfsftp.h>
+#endif
+
+/****************************************************************************
+ * SSH unique setup
+ ***************************************************************************/
+typedef enum {
+  SSH_NO_STATE = -1,  /* Used for "nextState" so say there is none */
+  SSH_STOP = 0,       /* do nothing state, stops the state machine */
+
+  SSH_INIT,           /* First state in SSH-CONNECT */
+  SSH_S_STARTUP,      /* Session startup */
+  SSH_HOSTKEY,        /* verify hostkey */
+  SSH_AUTHLIST,
+  SSH_AUTH_PKEY_INIT,
+  SSH_AUTH_PKEY,
+  SSH_AUTH_PASS_INIT,
+  SSH_AUTH_PASS,
+  SSH_AUTH_AGENT_INIT, /* initialize then wait for connection to agent */
+  SSH_AUTH_AGENT_LIST, /* ask for list then wait for entire list to come */
+  SSH_AUTH_AGENT,      /* attempt one key at a time */
+  SSH_AUTH_HOST_INIT,
+  SSH_AUTH_HOST,
+  SSH_AUTH_KEY_INIT,
+  SSH_AUTH_KEY,
+  SSH_AUTH_GSSAPI,
+  SSH_AUTH_DONE,
+  SSH_SFTP_INIT,
+  SSH_SFTP_REALPATH,   /* Last state in SSH-CONNECT */
+
+  SSH_SFTP_QUOTE_INIT, /* First state in SFTP-DO */
+  SSH_SFTP_POSTQUOTE_INIT, /* (Possibly) First state in SFTP-DONE */
+  SSH_SFTP_QUOTE,
+  SSH_SFTP_NEXT_QUOTE,
+  SSH_SFTP_QUOTE_STAT,
+  SSH_SFTP_QUOTE_SETSTAT,
+  SSH_SFTP_QUOTE_SYMLINK,
+  SSH_SFTP_QUOTE_MKDIR,
+  SSH_SFTP_QUOTE_RENAME,
+  SSH_SFTP_QUOTE_RMDIR,
+  SSH_SFTP_QUOTE_UNLINK,
+  SSH_SFTP_QUOTE_STATVFS,
+  SSH_SFTP_GETINFO,
+  SSH_SFTP_FILETIME,
+  SSH_SFTP_TRANS_INIT,
+  SSH_SFTP_UPLOAD_INIT,
+  SSH_SFTP_CREATE_DIRS_INIT,
+  SSH_SFTP_CREATE_DIRS,
+  SSH_SFTP_CREATE_DIRS_MKDIR,
+  SSH_SFTP_READDIR_INIT,
+  SSH_SFTP_READDIR,
+  SSH_SFTP_READDIR_LINK,
+  SSH_SFTP_READDIR_BOTTOM,
+  SSH_SFTP_READDIR_DONE,
+  SSH_SFTP_DOWNLOAD_INIT,
+  SSH_SFTP_DOWNLOAD_STAT, /* Last state in SFTP-DO */
+  SSH_SFTP_CLOSE,    /* Last state in SFTP-DONE */
+  SSH_SFTP_SHUTDOWN, /* First state in SFTP-DISCONNECT */
+  SSH_SCP_TRANS_INIT, /* First state in SCP-DO */
+  SSH_SCP_UPLOAD_INIT,
+  SSH_SCP_DOWNLOAD_INIT,
+  SSH_SCP_DOWNLOAD,
+  SSH_SCP_DONE,
+  SSH_SCP_SEND_EOF,
+  SSH_SCP_WAIT_EOF,
+  SSH_SCP_WAIT_CLOSE,
+  SSH_SCP_CHANNEL_FREE,   /* Last state in SCP-DONE */
+  SSH_SESSION_DISCONNECT, /* First state in SCP-DISCONNECT */
+  SSH_SESSION_FREE,       /* Last state in SCP/SFTP-DISCONNECT */
+  SSH_QUIT,
+  SSH_LAST  /* never used */
+} sshstate;
+
+/* this struct is used in the HandleData struct which is part of the
+   Curl_easy, which means this is used on a per-easy handle basis.
+   Everything that is strictly related to a connection is banned from this
+   struct. */
+struct SSHPROTO {
+  char *path;                  /* the path we operate on */
+};
+
+/* ssh_conn is used for struct connection-oriented data in the connectdata
+   struct */
+struct ssh_conn {
+  const char *authlist;       /* List of auth. methods, managed by libssh2 */
+
+  /* common */
+  const char *passphrase;     /* pass-phrase to use */
+  char *rsa_pub;              /* path name */
+  char *rsa;                  /* path name */
+  bool authed;                /* the connection has been authenticated fine */
+  sshstate state;             /* always use ssh.c:state() to change state! */
+  sshstate nextstate;         /* the state to goto after stopping */
+  CURLcode actualcode;        /* the actual error code */
+  struct curl_slist *quote_item; /* for the quote option */
+  char *quote_path1;          /* two generic pointers for the QUOTE stuff */
+  char *quote_path2;
+
+  bool acceptfail;            /* used by the SFTP_QUOTE (continue if
+                                 quote command fails) */
+  char *homedir;              /* when doing SFTP we figure out home dir in the
+                                 connect phase */
+  char *readdir_line;
+  /* end of READDIR stuff */
+
+  int secondCreateDirs;         /* counter use by the code to see if the
+                                   second attempt has been made to change
+                                   to/create a directory */
+  char *slash_pos;              /* used by the SFTP_CREATE_DIRS state */
+
+  int orig_waitfor;             /* default READ/WRITE bits wait for */
+
+#if defined(USE_LIBSSH)
+  char *readdir_linkPath;
+  size_t readdir_len, readdir_totalLen, readdir_currLen;
+/* our variables */
+  unsigned kbd_state; /* 0 or 1 */
+  ssh_key privkey;
+  ssh_key pubkey;
+  int auth_methods;
+  ssh_session ssh_session;
+  ssh_scp scp_session;
+  sftp_session sftp_session;
+  sftp_file sftp_file;
+  sftp_dir sftp_dir;
+
+  unsigned sftp_recv_state; /* 0 or 1 */
+  int sftp_file_index; /* for async read */
+  sftp_attributes readdir_attrs; /* used by the SFTP readdir actions */
+  sftp_attributes readdir_link_attrs; /* used by the SFTP readdir actions */
+  sftp_attributes quote_attrs; /* used by the SFTP_QUOTE state */
+
+  const char *readdir_filename; /* points within readdir_attrs */
+  const char *readdir_longentry;
+  char *readdir_tmp;
+#elif defined(USE_LIBSSH2)
+  struct dynbuf readdir_link;
+  struct dynbuf readdir;
+  char *readdir_filename;
+  char *readdir_longentry;
+
+  LIBSSH2_SFTP_ATTRIBUTES quote_attrs; /* used by the SFTP_QUOTE state */
+
+  /* Here's a set of struct members used by the SFTP_READDIR state */
+  LIBSSH2_SFTP_ATTRIBUTES readdir_attrs;
+  LIBSSH2_SESSION *ssh_session; /* Secure Shell session */
+  LIBSSH2_CHANNEL *ssh_channel; /* Secure Shell channel handle */
+  LIBSSH2_SFTP *sftp_session;   /* SFTP handle */
+  LIBSSH2_SFTP_HANDLE *sftp_handle;
+
+#ifdef HAVE_LIBSSH2_AGENT_API
+  LIBSSH2_AGENT *ssh_agent;     /* proxy to ssh-agent/pageant */
+  struct libssh2_agent_publickey *sshagent_identity,
+                                 *sshagent_prev_identity;
+#endif
+
+  /* note that HAVE_LIBSSH2_KNOWNHOST_API is a define set in the libssh2.h
+     header */
+#ifdef HAVE_LIBSSH2_KNOWNHOST_API
+  LIBSSH2_KNOWNHOSTS *kh;
+#endif
+#elif defined(USE_WOLFSSH)
+  WOLFSSH *ssh_session;
+  WOLFSSH_CTX *ctx;
+  word32 handleSz;
+  byte handle[WOLFSSH_MAX_HANDLE];
+  curl_off_t offset;
+#endif /* USE_LIBSSH */
+};
+
+#if defined(USE_LIBSSH)
+
+#define CURL_LIBSSH_VERSION ssh_version(0)
+
+#elif defined(USE_LIBSSH2)
+
+/* Feature detection based on version numbers to better work with
+   non-configure platforms */
+
+#if !defined(LIBSSH2_VERSION_NUM) || (LIBSSH2_VERSION_NUM < 0x001000)
+#  error "SCP/SFTP protocols require libssh2 0.16 or later"
+#endif
+
+#if LIBSSH2_VERSION_NUM >= 0x010000
+#define HAVE_LIBSSH2_SFTP_SEEK64 1
+#endif
+
+#if LIBSSH2_VERSION_NUM >= 0x010100
+#define HAVE_LIBSSH2_VERSION 1
+#endif
+
+#if LIBSSH2_VERSION_NUM >= 0x010205
+#define HAVE_LIBSSH2_INIT 1
+#define HAVE_LIBSSH2_EXIT 1
+#endif
+
+#if LIBSSH2_VERSION_NUM >= 0x010206
+#define HAVE_LIBSSH2_KNOWNHOST_CHECKP 1
+#define HAVE_LIBSSH2_SCP_SEND64 1
+#endif
+
+#if LIBSSH2_VERSION_NUM >= 0x010208
+#define HAVE_LIBSSH2_SESSION_HANDSHAKE 1
+#endif
+
+#ifdef HAVE_LIBSSH2_VERSION
+/* get it run-time if possible */
+#define CURL_LIBSSH2_VERSION libssh2_version(0)
+#else
+/* use build-time if run-time not possible */
+#define CURL_LIBSSH2_VERSION LIBSSH2_VERSION
+#endif
+
+#endif /* USE_LIBSSH2 */
+
+#ifdef USE_SSH
+
+extern const struct Curl_handler Curl_handler_scp;
+extern const struct Curl_handler Curl_handler_sftp;
+
+/* generic SSH backend functions */
+CURLcode Curl_ssh_init(void);
+void Curl_ssh_cleanup(void);
+size_t Curl_ssh_version(char *buffer, size_t buflen);
+#else
+/* for non-SSH builds */
+#define Curl_ssh_cleanup()
+#endif
+
+#endif /* HEADER_CURL_SSH_H */
diff --git a/Utilities/cmcurl/lib/vssh/wolfssh.c b/Utilities/cmcurl/lib/vssh/wolfssh.c
new file mode 100644
index 0000000..dcbbab6
--- /dev/null
+++ b/Utilities/cmcurl/lib/vssh/wolfssh.c
@@ -0,0 +1,1156 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 2019 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#ifdef USE_WOLFSSH
+
+#include <limits.h>
+
+#include <wolfssh/ssh.h>
+#include <wolfssh/wolfsftp.h>
+#include "urldata.h"
+#include "connect.h"
+#include "sendf.h"
+#include "progress.h"
+#include "curl_path.h"
+#include "strtoofft.h"
+#include "transfer.h"
+#include "speedcheck.h"
+#include "select.h"
+#include "multiif.h"
+#include "warnless.h"
+
+/* The last 3 #include files should be in this order */
+#include "curl_printf.h"
+#include "curl_memory.h"
+#include "memdebug.h"
+
+static CURLcode wssh_connect(struct connectdata *conn, bool *done);
+static CURLcode wssh_multi_statemach(struct connectdata *conn, bool *done);
+static CURLcode wssh_do(struct connectdata *conn, bool *done);
+#if 0
+static CURLcode wscp_done(struct connectdata *conn,
+                          CURLcode, bool premature);
+static CURLcode wscp_doing(struct connectdata *conn,
+                           bool *dophase_done);
+static CURLcode wscp_disconnect(struct connectdata *conn,
+                                bool dead_connection);
+#endif
+static CURLcode wsftp_done(struct connectdata *conn,
+                           CURLcode, bool premature);
+static CURLcode wsftp_doing(struct connectdata *conn,
+                            bool *dophase_done);
+static CURLcode wsftp_disconnect(struct connectdata *conn, bool dead);
+static int wssh_getsock(struct connectdata *conn,
+                        curl_socket_t *sock);
+static int wssh_perform_getsock(const struct connectdata *conn,
+                                curl_socket_t *sock);
+static CURLcode wssh_setup_connection(struct connectdata *conn);
+
+#if 0
+/*
+ * SCP protocol handler.
+ */
+
+const struct Curl_handler Curl_handler_scp = {
+  "SCP",                                /* scheme */
+  wssh_setup_connection,                /* setup_connection */
+  wssh_do,                              /* do_it */
+  wscp_done,                            /* done */
+  ZERO_NULL,                            /* do_more */
+  wssh_connect,                         /* connect_it */
+  wssh_multi_statemach,                 /* connecting */
+  wscp_doing,                           /* doing */
+  wssh_getsock,                         /* proto_getsock */
+  wssh_getsock,                         /* doing_getsock */
+  ZERO_NULL,                            /* domore_getsock */
+  wssh_perform_getsock,                 /* perform_getsock */
+  wscp_disconnect,                      /* disconnect */
+  ZERO_NULL,                            /* readwrite */
+  ZERO_NULL,                            /* connection_check */
+  PORT_SSH,                             /* defport */
+  CURLPROTO_SCP,                        /* protocol */
+  PROTOPT_DIRLOCK | PROTOPT_CLOSEACTION
+  | PROTOPT_NOURLQUERY                  /* flags */
+};
+
+#endif
+
+/*
+ * SFTP protocol handler.
+ */
+
+const struct Curl_handler Curl_handler_sftp = {
+  "SFTP",                               /* scheme */
+  wssh_setup_connection,                /* setup_connection */
+  wssh_do,                              /* do_it */
+  wsftp_done,                           /* done */
+  ZERO_NULL,                            /* do_more */
+  wssh_connect,                         /* connect_it */
+  wssh_multi_statemach,                 /* connecting */
+  wsftp_doing,                          /* doing */
+  wssh_getsock,                         /* proto_getsock */
+  wssh_getsock,                         /* doing_getsock */
+  ZERO_NULL,                            /* domore_getsock */
+  wssh_perform_getsock,                 /* perform_getsock */
+  wsftp_disconnect,                     /* disconnect */
+  ZERO_NULL,                            /* readwrite */
+  ZERO_NULL,                            /* connection_check */
+  PORT_SSH,                             /* defport */
+  CURLPROTO_SFTP,                       /* protocol */
+  PROTOPT_DIRLOCK | PROTOPT_CLOSEACTION
+  | PROTOPT_NOURLQUERY                  /* flags */
+};
+
+/*
+ * SSH State machine related code
+ */
+/* This is the ONLY way to change SSH state! */
+static void state(struct connectdata *conn, sshstate nowstate)
+{
+  struct ssh_conn *sshc = &conn->proto.sshc;
+#if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS)
+  /* for debug purposes */
+  static const char * const names[] = {
+    "SSH_STOP",
+    "SSH_INIT",
+    "SSH_S_STARTUP",
+    "SSH_HOSTKEY",
+    "SSH_AUTHLIST",
+    "SSH_AUTH_PKEY_INIT",
+    "SSH_AUTH_PKEY",
+    "SSH_AUTH_PASS_INIT",
+    "SSH_AUTH_PASS",
+    "SSH_AUTH_AGENT_INIT",
+    "SSH_AUTH_AGENT_LIST",
+    "SSH_AUTH_AGENT",
+    "SSH_AUTH_HOST_INIT",
+    "SSH_AUTH_HOST",
+    "SSH_AUTH_KEY_INIT",
+    "SSH_AUTH_KEY",
+    "SSH_AUTH_GSSAPI",
+    "SSH_AUTH_DONE",
+    "SSH_SFTP_INIT",
+    "SSH_SFTP_REALPATH",
+    "SSH_SFTP_QUOTE_INIT",
+    "SSH_SFTP_POSTQUOTE_INIT",
+    "SSH_SFTP_QUOTE",
+    "SSH_SFTP_NEXT_QUOTE",
+    "SSH_SFTP_QUOTE_STAT",
+    "SSH_SFTP_QUOTE_SETSTAT",
+    "SSH_SFTP_QUOTE_SYMLINK",
+    "SSH_SFTP_QUOTE_MKDIR",
+    "SSH_SFTP_QUOTE_RENAME",
+    "SSH_SFTP_QUOTE_RMDIR",
+    "SSH_SFTP_QUOTE_UNLINK",
+    "SSH_SFTP_QUOTE_STATVFS",
+    "SSH_SFTP_GETINFO",
+    "SSH_SFTP_FILETIME",
+    "SSH_SFTP_TRANS_INIT",
+    "SSH_SFTP_UPLOAD_INIT",
+    "SSH_SFTP_CREATE_DIRS_INIT",
+    "SSH_SFTP_CREATE_DIRS",
+    "SSH_SFTP_CREATE_DIRS_MKDIR",
+    "SSH_SFTP_READDIR_INIT",
+    "SSH_SFTP_READDIR",
+    "SSH_SFTP_READDIR_LINK",
+    "SSH_SFTP_READDIR_BOTTOM",
+    "SSH_SFTP_READDIR_DONE",
+    "SSH_SFTP_DOWNLOAD_INIT",
+    "SSH_SFTP_DOWNLOAD_STAT",
+    "SSH_SFTP_CLOSE",
+    "SSH_SFTP_SHUTDOWN",
+    "SSH_SCP_TRANS_INIT",
+    "SSH_SCP_UPLOAD_INIT",
+    "SSH_SCP_DOWNLOAD_INIT",
+    "SSH_SCP_DOWNLOAD",
+    "SSH_SCP_DONE",
+    "SSH_SCP_SEND_EOF",
+    "SSH_SCP_WAIT_EOF",
+    "SSH_SCP_WAIT_CLOSE",
+    "SSH_SCP_CHANNEL_FREE",
+    "SSH_SESSION_DISCONNECT",
+    "SSH_SESSION_FREE",
+    "QUIT"
+  };
+
+  /* a precaution to make sure the lists are in sync */
+  DEBUGASSERT(sizeof(names)/sizeof(names[0]) == SSH_LAST);
+
+  if(sshc->state != nowstate) {
+    infof(conn->data, "wolfssh %p state change from %s to %s\n",
+          (void *)sshc, names[sshc->state], names[nowstate]);
+  }
+#endif
+
+  sshc->state = nowstate;
+}
+
+static ssize_t wscp_send(struct connectdata *conn, int sockindex,
+                         const void *mem, size_t len, CURLcode *err)
+{
+  ssize_t nwrite = 0;
+  (void)conn;
+  (void)sockindex; /* we only support SCP on the fixed known primary socket */
+  (void)mem;
+  (void)len;
+  (void)err;
+
+  return nwrite;
+}
+
+static ssize_t wscp_recv(struct connectdata *conn, int sockindex,
+                         char *mem, size_t len, CURLcode *err)
+{
+  ssize_t nread = 0;
+  (void)conn;
+  (void)sockindex; /* we only support SCP on the fixed known primary socket */
+  (void)mem;
+  (void)len;
+  (void)err;
+
+  return nread;
+}
+
+/* return number of sent bytes */
+static ssize_t wsftp_send(struct connectdata *conn, int sockindex,
+                          const void *mem, size_t len, CURLcode *err)
+{
+  struct ssh_conn *sshc = &conn->proto.sshc;
+  word32 offset[2];
+  int rc;
+  (void)sockindex;
+
+  offset[0] = (word32)sshc->offset&0xFFFFFFFF;
+  offset[1] = (word32)(sshc->offset>>32)&0xFFFFFFFF;
+
+  rc = wolfSSH_SFTP_SendWritePacket(sshc->ssh_session, sshc->handle,
+                                    sshc->handleSz,
+                                    &offset[0],
+                                    (byte *)mem, (word32)len);
+
+  if(rc == WS_FATAL_ERROR)
+    rc = wolfSSH_get_error(sshc->ssh_session);
+  if(rc == WS_WANT_READ) {
+    conn->waitfor = KEEP_RECV;
+    *err = CURLE_AGAIN;
+    return -1;
+  }
+  else if(rc == WS_WANT_WRITE) {
+    conn->waitfor = KEEP_SEND;
+    *err = CURLE_AGAIN;
+    return -1;
+  }
+  if(rc < 0) {
+    failf(conn->data, "wolfSSH_SFTP_SendWritePacket returned %d\n", rc);
+    return -1;
+  }
+  DEBUGASSERT(rc == (int)len);
+  infof(conn->data, "sent %zd bytes SFTP from offset %zd\n",
+        len, sshc->offset);
+  sshc->offset += len;
+  return (ssize_t)rc;
+}
+
+/*
+ * Return number of received (decrypted) bytes
+ * or <0 on error
+ */
+static ssize_t wsftp_recv(struct connectdata *conn, int sockindex,
+                          char *mem, size_t len, CURLcode *err)
+{
+  int rc;
+  struct ssh_conn *sshc = &conn->proto.sshc;
+  word32 offset[2];
+  (void)sockindex;
+
+  offset[0] = (word32)sshc->offset&0xFFFFFFFF;
+  offset[1] = (word32)(sshc->offset>>32)&0xFFFFFFFF;
+
+  rc = wolfSSH_SFTP_SendReadPacket(sshc->ssh_session, sshc->handle,
+                                   sshc->handleSz,
+                                   &offset[0],
+                                   (byte *)mem, (word32)len);
+  if(rc == WS_FATAL_ERROR)
+    rc = wolfSSH_get_error(sshc->ssh_session);
+  if(rc == WS_WANT_READ) {
+    conn->waitfor = KEEP_RECV;
+    *err = CURLE_AGAIN;
+    return -1;
+  }
+  else if(rc == WS_WANT_WRITE) {
+    conn->waitfor = KEEP_SEND;
+    *err = CURLE_AGAIN;
+    return -1;
+  }
+
+  DEBUGASSERT(rc <= (int)len);
+
+  if(rc < 0) {
+    failf(conn->data, "wolfSSH_SFTP_SendReadPacket returned %d\n", rc);
+    return -1;
+  }
+  sshc->offset += len;
+
+  return (ssize_t)rc;
+}
+
+/*
+ * SSH setup and connection
+ */
+static CURLcode wssh_setup_connection(struct connectdata *conn)
+{
+  struct SSHPROTO *ssh;
+
+  conn->data->req.protop = ssh = calloc(1, sizeof(struct SSHPROTO));
+  if(!ssh)
+    return CURLE_OUT_OF_MEMORY;
+
+  return CURLE_OK;
+}
+
+static Curl_recv wscp_recv, wsftp_recv;
+static Curl_send wscp_send, wsftp_send;
+
+static int userauth(byte authtype,
+                    WS_UserAuthData* authdata,
+                    void *ctx)
+{
+  struct connectdata *conn = ctx;
+  DEBUGF(infof(conn->data, "wolfssh callback: type %s\n",
+               authtype == WOLFSSH_USERAUTH_PASSWORD ? "PASSWORD" :
+               "PUBLICCKEY"));
+  if(authtype == WOLFSSH_USERAUTH_PASSWORD) {
+    authdata->sf.password.password = (byte *)conn->passwd;
+    authdata->sf.password.passwordSz = (word32) strlen(conn->passwd);
+  }
+
+  return 0;
+}
+
+static CURLcode wssh_connect(struct connectdata *conn, bool *done)
+{
+  struct Curl_easy *data = conn->data;
+  struct ssh_conn *sshc;
+  curl_socket_t sock = conn->sock[FIRSTSOCKET];
+  int rc;
+
+  /* initialize per-handle data if not already */
+  if(!data->req.protop)
+    wssh_setup_connection(conn);
+
+  /* We default to persistent connections. We set this already in this connect
+     function to make the re-use checks properly be able to check this bit. */
+  connkeep(conn, "SSH default");
+
+  if(conn->handler->protocol & CURLPROTO_SCP) {
+    conn->recv[FIRSTSOCKET] = wscp_recv;
+    conn->send[FIRSTSOCKET] = wscp_send;
+  }
+  else {
+    conn->recv[FIRSTSOCKET] = wsftp_recv;
+    conn->send[FIRSTSOCKET] = wsftp_send;
+  }
+  sshc = &conn->proto.sshc;
+  sshc->ctx = wolfSSH_CTX_new(WOLFSSH_ENDPOINT_CLIENT, NULL);
+  if(!sshc->ctx) {
+    failf(data, "No wolfSSH context");
+    goto error;
+  }
+
+  sshc->ssh_session = wolfSSH_new(sshc->ctx);
+  if(sshc->ssh_session == NULL) {
+    failf(data, "No wolfSSH session");
+    goto error;
+  }
+
+  rc = wolfSSH_SetUsername(sshc->ssh_session, conn->user);
+  if(rc != WS_SUCCESS) {
+    failf(data, "wolfSSH failed to set user name");
+    goto error;
+  }
+
+  /* set callback for authentication */
+  wolfSSH_SetUserAuth(sshc->ctx, userauth);
+  wolfSSH_SetUserAuthCtx(sshc->ssh_session, conn);
+
+  rc = wolfSSH_set_fd(sshc->ssh_session, (int)sock);
+  if(rc) {
+    failf(data, "wolfSSH failed to set socket");
+    goto error;
+  }
+
+#if 0
+  wolfSSH_Debugging_ON();
+#endif
+
+  *done = TRUE;
+  if(conn->handler->protocol & CURLPROTO_SCP)
+    state(conn, SSH_INIT);
+  else
+    state(conn, SSH_SFTP_INIT);
+
+  return wssh_multi_statemach(conn, done);
+  error:
+  wolfSSH_free(sshc->ssh_session);
+  wolfSSH_CTX_free(sshc->ctx);
+  return CURLE_FAILED_INIT;
+}
+
+/*
+ * wssh_statemach_act() runs the SSH state machine as far as it can without
+ * blocking and without reaching the end.  The data the pointer 'block' points
+ * to will be set to TRUE if the wolfssh function returns EAGAIN meaning it
+ * wants to be called again when the socket is ready
+ */
+
+static CURLcode wssh_statemach_act(struct connectdata *conn, bool *block)
+{
+  CURLcode result = CURLE_OK;
+  struct ssh_conn *sshc = &conn->proto.sshc;
+  struct Curl_easy *data = conn->data;
+  struct SSHPROTO *sftp_scp = data->req.protop;
+  WS_SFTPNAME *name;
+  int rc = 0;
+  *block = FALSE; /* we're not blocking by default */
+
+  do {
+    switch(sshc->state) {
+    case SSH_INIT:
+      state(conn, SSH_S_STARTUP);
+      /* FALLTHROUGH */
+    case SSH_S_STARTUP:
+      rc = wolfSSH_connect(sshc->ssh_session);
+      if(rc != WS_SUCCESS)
+        rc = wolfSSH_get_error(sshc->ssh_session);
+      if(rc == WS_WANT_READ) {
+        *block = TRUE;
+        conn->waitfor = KEEP_RECV;
+        return CURLE_OK;
+      }
+      else if(rc == WS_WANT_WRITE) {
+        *block = TRUE;
+        conn->waitfor = KEEP_SEND;
+        return CURLE_OK;
+      }
+      else if(rc != WS_SUCCESS) {
+        state(conn, SSH_STOP);
+        return CURLE_SSH;
+      }
+      infof(data, "wolfssh connected!\n");
+      state(conn, SSH_STOP);
+      break;
+    case SSH_STOP:
+      break;
+
+    case SSH_SFTP_INIT:
+      rc = wolfSSH_SFTP_connect(sshc->ssh_session);
+      if(rc != WS_SUCCESS)
+        rc = wolfSSH_get_error(sshc->ssh_session);
+      if(rc == WS_WANT_READ) {
+        *block = TRUE;
+        conn->waitfor = KEEP_RECV;
+        return CURLE_OK;
+      }
+      else if(rc == WS_WANT_WRITE) {
+        *block = TRUE;
+        conn->waitfor = KEEP_SEND;
+        return CURLE_OK;
+      }
+      else if(rc == WS_SUCCESS) {
+        infof(data, "wolfssh SFTP connected!\n");
+        state(conn, SSH_SFTP_REALPATH);
+      }
+      else {
+        failf(data, "wolfssh SFTP connect error %d", rc);
+        return CURLE_SSH;
+      }
+      break;
+    case SSH_SFTP_REALPATH:
+      name = wolfSSH_SFTP_RealPath(sshc->ssh_session, (char *)".");
+      rc = wolfSSH_get_error(sshc->ssh_session);
+      if(rc == WS_WANT_READ) {
+        *block = TRUE;
+        conn->waitfor = KEEP_RECV;
+        return CURLE_OK;
+      }
+      else if(rc == WS_WANT_WRITE) {
+        *block = TRUE;
+        conn->waitfor = KEEP_SEND;
+        return CURLE_OK;
+      }
+      else if(name && (rc == WS_SUCCESS)) {
+        sshc->homedir = malloc(name->fSz + 1);
+        if(!sshc->homedir) {
+          sshc->actualcode = CURLE_OUT_OF_MEMORY;
+        }
+        else {
+          memcpy(sshc->homedir, name->fName, name->fSz);
+          sshc->homedir[name->fSz] = 0;
+          infof(data, "wolfssh SFTP realpath succeeded!\n");
+        }
+        wolfSSH_SFTPNAME_list_free(name);
+        state(conn, SSH_STOP);
+        return CURLE_OK;
+      }
+      failf(data, "wolfssh SFTP realpath %d", rc);
+      return CURLE_SSH;
+
+    case SSH_SFTP_QUOTE_INIT:
+      result = Curl_getworkingpath(conn, sshc->homedir, &sftp_scp->path);
+      if(result) {
+        sshc->actualcode = result;
+        state(conn, SSH_STOP);
+        break;
+      }
+
+      if(data->set.quote) {
+        infof(data, "Sending quote commands\n");
+        sshc->quote_item = data->set.quote;
+        state(conn, SSH_SFTP_QUOTE);
+      }
+      else {
+        state(conn, SSH_SFTP_GETINFO);
+      }
+      break;
+    case SSH_SFTP_GETINFO:
+      if(data->set.get_filetime) {
+        state(conn, SSH_SFTP_FILETIME);
+      }
+      else {
+        state(conn, SSH_SFTP_TRANS_INIT);
+      }
+      break;
+    case SSH_SFTP_TRANS_INIT:
+      if(data->set.upload)
+        state(conn, SSH_SFTP_UPLOAD_INIT);
+      else {
+        if(sftp_scp->path[strlen(sftp_scp->path)-1] == '/')
+          state(conn, SSH_SFTP_READDIR_INIT);
+        else
+          state(conn, SSH_SFTP_DOWNLOAD_INIT);
+      }
+      break;
+    case SSH_SFTP_UPLOAD_INIT: {
+      word32 flags;
+      WS_SFTP_FILEATRB createattrs;
+      if(data->state.resume_from) {
+        WS_SFTP_FILEATRB attrs;
+        if(data->state.resume_from < 0) {
+          rc = wolfSSH_SFTP_STAT(sshc->ssh_session, sftp_scp->path,
+                                 &attrs);
+          if(rc != WS_SUCCESS)
+            break;
+
+          if(rc) {
+            data->state.resume_from = 0;
+          }
+          else {
+            curl_off_t size = ((curl_off_t)attrs.sz[1] << 32) | attrs.sz[0];
+            if(size < 0) {
+              failf(data, "Bad file size (%" CURL_FORMAT_CURL_OFF_T ")", size);
+              return CURLE_BAD_DOWNLOAD_RESUME;
+            }
+            data->state.resume_from = size;
+          }
+        }
+      }
+
+      if(data->set.ftp_append)
+        /* Try to open for append, but create if nonexisting */
+        flags = WOLFSSH_FXF_WRITE|WOLFSSH_FXF_CREAT|WOLFSSH_FXF_APPEND;
+      else if(data->state.resume_from > 0)
+        /* If we have restart position then open for append */
+        flags = WOLFSSH_FXF_WRITE|WOLFSSH_FXF_APPEND;
+      else
+        /* Clear file before writing (normal behaviour) */
+        flags = WOLFSSH_FXF_WRITE|WOLFSSH_FXF_CREAT|WOLFSSH_FXF_TRUNC;
+
+      memset(&createattrs, 0, sizeof(createattrs));
+      createattrs.per = (word32)data->set.new_file_perms;
+      sshc->handleSz = sizeof(sshc->handle);
+      rc = wolfSSH_SFTP_Open(sshc->ssh_session, sftp_scp->path,
+                             flags, &createattrs,
+                             sshc->handle, &sshc->handleSz);
+      if(rc == WS_FATAL_ERROR)
+        rc = wolfSSH_get_error(sshc->ssh_session);
+      if(rc == WS_WANT_READ) {
+        *block = TRUE;
+        conn->waitfor = KEEP_RECV;
+        return CURLE_OK;
+      }
+      else if(rc == WS_WANT_WRITE) {
+        *block = TRUE;
+        conn->waitfor = KEEP_SEND;
+        return CURLE_OK;
+      }
+      else if(rc == WS_SUCCESS) {
+        infof(data, "wolfssh SFTP open succeeded!\n");
+      }
+      else {
+        failf(data, "wolfssh SFTP upload open failed: %d", rc);
+        return CURLE_SSH;
+      }
+      state(conn, SSH_SFTP_DOWNLOAD_STAT);
+
+      /* If we have a restart point then we need to seek to the correct
+         position. */
+      if(data->state.resume_from > 0) {
+        /* Let's read off the proper amount of bytes from the input. */
+        int seekerr = CURL_SEEKFUNC_OK;
+        if(conn->seek_func) {
+          Curl_set_in_callback(data, true);
+          seekerr = conn->seek_func(conn->seek_client, data->state.resume_from,
+                                    SEEK_SET);
+          Curl_set_in_callback(data, false);
+        }
+
+        if(seekerr != CURL_SEEKFUNC_OK) {
+          curl_off_t passed = 0;
+
+          if(seekerr != CURL_SEEKFUNC_CANTSEEK) {
+            failf(data, "Could not seek stream");
+            return CURLE_FTP_COULDNT_USE_REST;
+          }
+          /* seekerr == CURL_SEEKFUNC_CANTSEEK (can't seek to offset) */
+          do {
+            size_t readthisamountnow =
+              (data->state.resume_from - passed > data->set.buffer_size) ?
+              (size_t)data->set.buffer_size :
+              curlx_sotouz(data->state.resume_from - passed);
+
+            size_t actuallyread;
+            Curl_set_in_callback(data, true);
+            actuallyread = data->state.fread_func(data->state.buffer, 1,
+                                                  readthisamountnow,
+                                                  data->state.in);
+            Curl_set_in_callback(data, false);
+
+            passed += actuallyread;
+            if((actuallyread == 0) || (actuallyread > readthisamountnow)) {
+              /* this checks for greater-than only to make sure that the
+                 CURL_READFUNC_ABORT return code still aborts */
+              failf(data, "Failed to read data");
+              return CURLE_FTP_COULDNT_USE_REST;
+            }
+          } while(passed < data->state.resume_from);
+        }
+
+        /* now, decrease the size of the read */
+        if(data->state.infilesize > 0) {
+          data->state.infilesize -= data->state.resume_from;
+          data->req.size = data->state.infilesize;
+          Curl_pgrsSetUploadSize(data, data->state.infilesize);
+        }
+
+        sshc->offset += data->state.resume_from;
+      }
+      if(data->state.infilesize > 0) {
+        data->req.size = data->state.infilesize;
+        Curl_pgrsSetUploadSize(data, data->state.infilesize);
+      }
+      /* upload data */
+      Curl_setup_transfer(data, -1, -1, FALSE, FIRSTSOCKET);
+
+      /* not set by Curl_setup_transfer to preserve keepon bits */
+      conn->sockfd = conn->writesockfd;
+
+      if(result) {
+        state(conn, SSH_SFTP_CLOSE);
+        sshc->actualcode = result;
+      }
+      else {
+        /* store this original bitmask setup to use later on if we can't
+           figure out a "real" bitmask */
+        sshc->orig_waitfor = data->req.keepon;
+
+        /* we want to use the _sending_ function even when the socket turns
+           out readable as the underlying libssh2 sftp send function will deal
+           with both accordingly */
+        conn->cselect_bits = CURL_CSELECT_OUT;
+
+        /* since we don't really wait for anything at this point, we want the
+           state machine to move on as soon as possible so we set a very short
+           timeout here */
+        Curl_expire(data, 0, EXPIRE_RUN_NOW);
+
+        state(conn, SSH_STOP);
+      }
+      break;
+    }
+    case SSH_SFTP_DOWNLOAD_INIT:
+      sshc->handleSz = sizeof(sshc->handle);
+      rc = wolfSSH_SFTP_Open(sshc->ssh_session, sftp_scp->path,
+                             WOLFSSH_FXF_READ, NULL,
+                             sshc->handle, &sshc->handleSz);
+      if(rc == WS_FATAL_ERROR)
+        rc = wolfSSH_get_error(sshc->ssh_session);
+      if(rc == WS_WANT_READ) {
+        *block = TRUE;
+        conn->waitfor = KEEP_RECV;
+        return CURLE_OK;
+      }
+      else if(rc == WS_WANT_WRITE) {
+        *block = TRUE;
+        conn->waitfor = KEEP_SEND;
+        return CURLE_OK;
+      }
+      else if(rc == WS_SUCCESS) {
+        infof(data, "wolfssh SFTP open succeeded!\n");
+        state(conn, SSH_SFTP_DOWNLOAD_STAT);
+        return CURLE_OK;
+      }
+
+      failf(data, "wolfssh SFTP open failed: %d", rc);
+      return CURLE_SSH;
+
+    case SSH_SFTP_DOWNLOAD_STAT: {
+      WS_SFTP_FILEATRB attrs;
+      curl_off_t size;
+
+      rc = wolfSSH_SFTP_STAT(sshc->ssh_session, sftp_scp->path, &attrs);
+      if(rc == WS_FATAL_ERROR)
+        rc = wolfSSH_get_error(sshc->ssh_session);
+      if(rc == WS_WANT_READ) {
+        *block = TRUE;
+        conn->waitfor = KEEP_RECV;
+        return CURLE_OK;
+      }
+      else if(rc == WS_WANT_WRITE) {
+        *block = TRUE;
+        conn->waitfor = KEEP_SEND;
+        return CURLE_OK;
+      }
+      else if(rc == WS_SUCCESS) {
+        infof(data, "wolfssh STAT succeeded!\n");
+      }
+      else {
+        failf(data, "wolfssh SFTP open failed: %d", rc);
+        data->req.size = -1;
+        data->req.maxdownload = -1;
+        Curl_pgrsSetDownloadSize(data, -1);
+        return CURLE_SSH;
+      }
+
+      size = ((curl_off_t)attrs.sz[1] <<32) | attrs.sz[0];
+
+      data->req.size = size;
+      data->req.maxdownload = size;
+      Curl_pgrsSetDownloadSize(data, size);
+
+      infof(data, "SFTP download %" CURL_FORMAT_CURL_OFF_T " bytes\n", size);
+
+      /* We cannot seek with wolfSSH so resuming and range requests are not
+         possible */
+      if(conn->data->state.use_range || data->state.resume_from) {
+        infof(data, "wolfSSH cannot do range/seek on SFTP\n");
+        return CURLE_BAD_DOWNLOAD_RESUME;
+      }
+
+      /* Setup the actual download */
+      if(data->req.size == 0) {
+        /* no data to transfer */
+        Curl_setup_transfer(data, -1, -1, FALSE, -1);
+        infof(data, "File already completely downloaded\n");
+        state(conn, SSH_STOP);
+        break;
+      }
+      Curl_setup_transfer(data, FIRSTSOCKET, data->req.size, FALSE, -1);
+
+      /* not set by Curl_setup_transfer to preserve keepon bits */
+      conn->writesockfd = conn->sockfd;
+
+      /* we want to use the _receiving_ function even when the socket turns
+         out writableable as the underlying libssh2 recv function will deal
+         with both accordingly */
+      conn->cselect_bits = CURL_CSELECT_IN;
+
+      if(result) {
+        /* this should never occur; the close state should be entered
+           at the time the error occurs */
+        state(conn, SSH_SFTP_CLOSE);
+        sshc->actualcode = result;
+      }
+      else {
+        state(conn, SSH_STOP);
+      }
+      break;
+    }
+    case SSH_SFTP_CLOSE:
+      if(sshc->handleSz)
+        rc = wolfSSH_SFTP_Close(sshc->ssh_session, sshc->handle,
+                                sshc->handleSz);
+      else
+        rc = WS_SUCCESS; /* directory listing */
+      if(rc == WS_WANT_READ) {
+        *block = TRUE;
+        conn->waitfor = KEEP_RECV;
+        return CURLE_OK;
+      }
+      else if(rc == WS_WANT_WRITE) {
+        *block = TRUE;
+        conn->waitfor = KEEP_SEND;
+        return CURLE_OK;
+      }
+      else if(rc == WS_SUCCESS) {
+        state(conn, SSH_STOP);
+        return CURLE_OK;
+      }
+
+      failf(data, "wolfssh SFTP CLOSE failed: %d", rc);
+      return CURLE_SSH;
+
+    case SSH_SFTP_READDIR_INIT:
+      Curl_pgrsSetDownloadSize(data, -1);
+      if(data->set.opt_no_body) {
+        state(conn, SSH_STOP);
+        break;
+      }
+      state(conn, SSH_SFTP_READDIR);
+      /* FALLTHROUGH */
+    case SSH_SFTP_READDIR:
+      name = wolfSSH_SFTP_LS(sshc->ssh_session, sftp_scp->path);
+      if(!name)
+        rc = wolfSSH_get_error(sshc->ssh_session);
+      else
+        rc = WS_SUCCESS;
+
+      if(rc == WS_WANT_READ) {
+        *block = TRUE;
+        conn->waitfor = KEEP_RECV;
+        return CURLE_OK;
+      }
+      else if(rc == WS_WANT_WRITE) {
+        *block = TRUE;
+        conn->waitfor = KEEP_SEND;
+        return CURLE_OK;
+      }
+      else if(name && (rc == WS_SUCCESS)) {
+        WS_SFTPNAME *origname = name;
+        result = CURLE_OK;
+        while(name) {
+          char *line = aprintf("%s\n",
+                               data->set.ftp_list_only ?
+                               name->fName : name->lName);
+          if(line == NULL) {
+            state(conn, SSH_SFTP_CLOSE);
+            sshc->actualcode = CURLE_OUT_OF_MEMORY;
+            break;
+          }
+          result = Curl_client_write(conn, CLIENTWRITE_BODY,
+                                     line, strlen(line));
+          free(line);
+          if(result) {
+            sshc->actualcode = result;
+            break;
+          }
+          name = name->next;
+        }
+        wolfSSH_SFTPNAME_list_free(origname);
+        state(conn, SSH_STOP);
+        return result;
+      }
+      failf(data, "wolfssh SFTP ls failed: %d", rc);
+      return CURLE_SSH;
+
+    case SSH_SFTP_SHUTDOWN:
+      Curl_safefree(sshc->homedir);
+      wolfSSH_free(sshc->ssh_session);
+      wolfSSH_CTX_free(sshc->ctx);
+      state(conn, SSH_STOP);
+      return CURLE_OK;
+    default:
+      break;
+    }
+  } while(!rc && (sshc->state != SSH_STOP));
+  return result;
+}
+
+/* called repeatedly until done from multi.c */
+static CURLcode wssh_multi_statemach(struct connectdata *conn, bool *done)
+{
+  struct ssh_conn *sshc = &conn->proto.sshc;
+  CURLcode result = CURLE_OK;
+  bool block; /* we store the status and use that to provide a ssh_getsock()
+                 implementation */
+  do {
+    result = wssh_statemach_act(conn, &block);
+    *done = (sshc->state == SSH_STOP) ? TRUE : FALSE;
+    /* if there's no error, it isn't done and it didn't EWOULDBLOCK, then
+       try again */
+    if(*done) {
+      DEBUGF(infof(conn->data, "wssh_statemach_act says DONE\n"));
+    }
+  } while(!result && !*done && !block);
+
+  return result;
+}
+
+static
+CURLcode wscp_perform(struct connectdata *conn,
+                      bool *connected,
+                      bool *dophase_done)
+{
+  (void)conn;
+  (void)connected;
+  (void)dophase_done;
+  return CURLE_OK;
+}
+
+static
+CURLcode wsftp_perform(struct connectdata *conn,
+                       bool *connected,
+                       bool *dophase_done)
+{
+  CURLcode result = CURLE_OK;
+
+  DEBUGF(infof(conn->data, "DO phase starts\n"));
+
+  *dophase_done = FALSE; /* not done yet */
+
+  /* start the first command in the DO phase */
+  state(conn, SSH_SFTP_QUOTE_INIT);
+
+  /* run the state-machine */
+  result = wssh_multi_statemach(conn, dophase_done);
+
+  *connected = conn->bits.tcpconnect[FIRSTSOCKET];
+
+  if(*dophase_done) {
+    DEBUGF(infof(conn->data, "DO phase is complete\n"));
+  }
+
+  return result;
+}
+
+/*
+ * The DO function is generic for both protocols.
+ */
+static CURLcode wssh_do(struct connectdata *conn, bool *done)
+{
+  CURLcode result;
+  bool connected = 0;
+  struct Curl_easy *data = conn->data;
+  struct ssh_conn *sshc = &conn->proto.sshc;
+
+  *done = FALSE; /* default to false */
+  data->req.size = -1; /* make sure this is unknown at this point */
+  sshc->actualcode = CURLE_OK; /* reset error code */
+  sshc->secondCreateDirs = 0;   /* reset the create dir attempt state
+                                   variable */
+
+  Curl_pgrsSetUploadCounter(data, 0);
+  Curl_pgrsSetDownloadCounter(data, 0);
+  Curl_pgrsSetUploadSize(data, -1);
+  Curl_pgrsSetDownloadSize(data, -1);
+
+  if(conn->handler->protocol & CURLPROTO_SCP)
+    result = wscp_perform(conn, &connected,  done);
+  else
+    result = wsftp_perform(conn, &connected,  done);
+
+  return result;
+}
+
+static CURLcode wssh_block_statemach(struct connectdata *conn,
+                                    bool disconnect)
+{
+  struct ssh_conn *sshc = &conn->proto.sshc;
+  CURLcode result = CURLE_OK;
+  struct Curl_easy *data = conn->data;
+
+  while((sshc->state != SSH_STOP) && !result) {
+    bool block;
+    timediff_t left = 1000;
+    struct curltime now = Curl_now();
+
+    result = wssh_statemach_act(conn, &block);
+    if(result)
+      break;
+
+    if(!disconnect) {
+      if(Curl_pgrsUpdate(conn))
+        return CURLE_ABORTED_BY_CALLBACK;
+
+      result = Curl_speedcheck(data, now);
+      if(result)
+        break;
+
+      left = Curl_timeleft(data, NULL, FALSE);
+      if(left < 0) {
+        failf(data, "Operation timed out");
+        return CURLE_OPERATION_TIMEDOUT;
+      }
+    }
+
+    if(!result) {
+      int dir = conn->waitfor;
+      curl_socket_t sock = conn->sock[FIRSTSOCKET];
+      curl_socket_t fd_read = CURL_SOCKET_BAD;
+      curl_socket_t fd_write = CURL_SOCKET_BAD;
+      if(dir == KEEP_RECV)
+        fd_read = sock;
+      else if(dir == KEEP_SEND)
+        fd_write = sock;
+
+      /* wait for the socket to become ready */
+      (void)Curl_socket_check(fd_read, CURL_SOCKET_BAD, fd_write,
+                              left>1000?1000:left); /* ignore result */
+    }
+  }
+
+  return result;
+}
+
+/* generic done function for both SCP and SFTP called from their specific
+   done functions */
+static CURLcode wssh_done(struct connectdata *conn, CURLcode status)
+{
+  CURLcode result = CURLE_OK;
+  struct SSHPROTO *sftp_scp = conn->data->req.protop;
+
+  if(!status) {
+    /* run the state-machine */
+    result = wssh_block_statemach(conn, FALSE);
+  }
+  else
+    result = status;
+
+  if(sftp_scp)
+    Curl_safefree(sftp_scp->path);
+  if(Curl_pgrsDone(conn))
+    return CURLE_ABORTED_BY_CALLBACK;
+
+  conn->data->req.keepon = 0; /* clear all bits */
+  return result;
+}
+
+#if 0
+static CURLcode wscp_done(struct connectdata *conn,
+                         CURLcode code, bool premature)
+{
+  CURLcode result = CURLE_OK;
+  (void)conn;
+  (void)code;
+  (void)premature;
+
+  return result;
+}
+
+static CURLcode wscp_doing(struct connectdata *conn,
+                          bool *dophase_done)
+{
+  CURLcode result = CURLE_OK;
+  (void)conn;
+  (void)dophase_done;
+
+  return result;
+}
+
+static CURLcode wscp_disconnect(struct connectdata *conn, bool dead_connection)
+{
+  CURLcode result = CURLE_OK;
+  (void)conn;
+  (void)dead_connection;
+
+  return result;
+}
+#endif
+
+static CURLcode wsftp_done(struct connectdata *conn,
+                          CURLcode code, bool premature)
+{
+  (void)premature;
+  state(conn, SSH_SFTP_CLOSE);
+
+  return wssh_done(conn, code);
+}
+
+static CURLcode wsftp_doing(struct connectdata *conn,
+                           bool *dophase_done)
+{
+  CURLcode result = wssh_multi_statemach(conn, dophase_done);
+
+  if(*dophase_done) {
+    DEBUGF(infof(conn->data, "DO phase is complete\n"));
+  }
+  return result;
+}
+
+static CURLcode wsftp_disconnect(struct connectdata *conn, bool dead)
+{
+  CURLcode result = CURLE_OK;
+  (void)dead;
+
+  DEBUGF(infof(conn->data, "SSH DISCONNECT starts now\n"));
+
+  if(conn->proto.sshc.ssh_session) {
+    /* only if there's a session still around to use! */
+    state(conn, SSH_SFTP_SHUTDOWN);
+    result = wssh_block_statemach(conn, TRUE);
+  }
+
+  DEBUGF(infof(conn->data, "SSH DISCONNECT is done\n"));
+  return result;
+}
+
+static int wssh_getsock(struct connectdata *conn,
+                        curl_socket_t *sock)
+{
+  return wssh_perform_getsock(conn, sock);
+}
+
+static int wssh_perform_getsock(const struct connectdata *conn,
+                                curl_socket_t *sock)
+{
+  int bitmap = GETSOCK_BLANK;
+  int dir = conn->waitfor;
+  sock[0] = conn->sock[FIRSTSOCKET];
+
+  if(dir == KEEP_RECV)
+    bitmap |= GETSOCK_READSOCK(FIRSTSOCKET);
+  else if(dir == KEEP_SEND)
+    bitmap |= GETSOCK_WRITESOCK(FIRSTSOCKET);
+
+  return bitmap;
+}
+
+size_t Curl_ssh_version(char *buffer, size_t buflen)
+{
+  return msnprintf(buffer, buflen, "wolfssh/%s", LIBWOLFSSH_VERSION_STRING);
+}
+
+CURLcode Curl_ssh_init(void)
+{
+  if(WS_SUCCESS != wolfSSH_Init()) {
+    DEBUGF(fprintf(stderr, "Error: wolfSSH_Init failed\n"));
+    return CURLE_FAILED_INIT;
+  }
+
+  return CURLE_OK;
+}
+void Curl_ssh_cleanup(void)
+{
+}
+
+#endif /* USE_WOLFSSH */
diff --git a/Utilities/cmcurl/lib/vssh/wolfssh.h b/Utilities/cmcurl/lib/vssh/wolfssh.h
new file mode 100644
index 0000000..a9b9a3b
--- /dev/null
+++ b/Utilities/cmcurl/lib/vssh/wolfssh.h
@@ -0,0 +1,27 @@
+#ifndef HEADER_CURL_WOLFSSH_H
+#define HEADER_CURL_WOLFSSH_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 2019 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+extern const struct Curl_handler Curl_handler_sftp;
+
+#endif /* HEADER_CURL_WOLFSSH_H */
diff --git a/Utilities/cmcurl/lib/vtls/bearssl.c b/Utilities/cmcurl/lib/vtls/bearssl.c
new file mode 100644
index 0000000..628e16a
--- /dev/null
+++ b/Utilities/cmcurl/lib/vtls/bearssl.c
@@ -0,0 +1,870 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 2019 - 2020, Michael Forney, <mforney@mforney.org>
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include "curl_setup.h"
+
+#ifdef USE_BEARSSL
+
+#include <bearssl.h>
+
+#include "bearssl.h"
+#include "urldata.h"
+#include "sendf.h"
+#include "inet_pton.h"
+#include "vtls.h"
+#include "connect.h"
+#include "select.h"
+#include "multiif.h"
+#include "curl_printf.h"
+#include "curl_memory.h"
+
+struct x509_context {
+  const br_x509_class *vtable;
+  br_x509_minimal_context minimal;
+  bool verifyhost;
+  bool verifypeer;
+};
+
+struct ssl_backend_data {
+  br_ssl_client_context ctx;
+  struct x509_context x509;
+  unsigned char buf[BR_SSL_BUFSIZE_BIDI];
+  br_x509_trust_anchor *anchors;
+  size_t anchors_len;
+  const char *protocols[2];
+  /* SSL client context is active */
+  bool active;
+  /* size of pending write, yet to be flushed */
+  size_t pending_write;
+};
+
+struct cafile_parser {
+  CURLcode err;
+  bool in_cert;
+  br_x509_decoder_context xc;
+  /* array of trust anchors loaded from CAfile */
+  br_x509_trust_anchor *anchors;
+  size_t anchors_len;
+  /* buffer for DN data */
+  unsigned char dn[1024];
+  size_t dn_len;
+};
+
+static void append_dn(void *ctx, const void *buf, size_t len)
+{
+  struct cafile_parser *ca = ctx;
+
+  if(ca->err != CURLE_OK || !ca->in_cert)
+    return;
+  if(sizeof(ca->dn) - ca->dn_len < len) {
+    ca->err = CURLE_FAILED_INIT;
+    return;
+  }
+  memcpy(ca->dn + ca->dn_len, buf, len);
+  ca->dn_len += len;
+}
+
+static void x509_push(void *ctx, const void *buf, size_t len)
+{
+  struct cafile_parser *ca = ctx;
+
+  if(ca->in_cert)
+    br_x509_decoder_push(&ca->xc, buf, len);
+}
+
+static CURLcode load_cafile(const char *path, br_x509_trust_anchor **anchors,
+                            size_t *anchors_len)
+{
+  struct cafile_parser ca;
+  br_pem_decoder_context pc;
+  br_x509_trust_anchor *ta;
+  size_t ta_size;
+  br_x509_trust_anchor *new_anchors;
+  size_t new_anchors_len;
+  br_x509_pkey *pkey;
+  FILE *fp;
+  unsigned char buf[BUFSIZ], *p;
+  const char *name;
+  size_t n, i, pushed;
+
+  fp = fopen(path, "rb");
+  if(!fp)
+    return CURLE_SSL_CACERT_BADFILE;
+
+  ca.err = CURLE_OK;
+  ca.in_cert = FALSE;
+  ca.anchors = NULL;
+  ca.anchors_len = 0;
+  br_pem_decoder_init(&pc);
+  br_pem_decoder_setdest(&pc, x509_push, &ca);
+  for(;;) {
+    n = fread(buf, 1, sizeof(buf), fp);
+    if(n == 0)
+      break;
+    p = buf;
+    while(n) {
+      pushed = br_pem_decoder_push(&pc, p, n);
+      if(ca.err)
+        goto fail;
+      p += pushed;
+      n -= pushed;
+
+      switch(br_pem_decoder_event(&pc)) {
+      case 0:
+        break;
+      case BR_PEM_BEGIN_OBJ:
+        name = br_pem_decoder_name(&pc);
+        if(strcmp(name, "CERTIFICATE") && strcmp(name, "X509 CERTIFICATE"))
+          break;
+        br_x509_decoder_init(&ca.xc, append_dn, &ca);
+        if(ca.anchors_len == SIZE_MAX / sizeof(ca.anchors[0])) {
+          ca.err = CURLE_OUT_OF_MEMORY;
+          goto fail;
+        }
+        new_anchors_len = ca.anchors_len + 1;
+        new_anchors = realloc(ca.anchors,
+                              new_anchors_len * sizeof(ca.anchors[0]));
+        if(!new_anchors) {
+          ca.err = CURLE_OUT_OF_MEMORY;
+          goto fail;
+        }
+        ca.anchors = new_anchors;
+        ca.anchors_len = new_anchors_len;
+        ca.in_cert = TRUE;
+        ca.dn_len = 0;
+        ta = &ca.anchors[ca.anchors_len - 1];
+        ta->dn.data = NULL;
+        break;
+      case BR_PEM_END_OBJ:
+        if(!ca.in_cert)
+          break;
+        ca.in_cert = FALSE;
+        if(br_x509_decoder_last_error(&ca.xc)) {
+          ca.err = CURLE_SSL_CACERT_BADFILE;
+          goto fail;
+        }
+        ta->flags = 0;
+        if(br_x509_decoder_isCA(&ca.xc))
+          ta->flags |= BR_X509_TA_CA;
+        pkey = br_x509_decoder_get_pkey(&ca.xc);
+        if(!pkey) {
+          ca.err = CURLE_SSL_CACERT_BADFILE;
+          goto fail;
+        }
+        ta->pkey = *pkey;
+
+        /* calculate space needed for trust anchor data */
+        ta_size = ca.dn_len;
+        switch(pkey->key_type) {
+        case BR_KEYTYPE_RSA:
+          ta_size += pkey->key.rsa.nlen + pkey->key.rsa.elen;
+          break;
+        case BR_KEYTYPE_EC:
+          ta_size += pkey->key.ec.qlen;
+          break;
+        default:
+          ca.err = CURLE_FAILED_INIT;
+          goto fail;
+        }
+
+        /* fill in trust anchor DN and public key data */
+        ta->dn.data = malloc(ta_size);
+        if(!ta->dn.data) {
+          ca.err = CURLE_OUT_OF_MEMORY;
+          goto fail;
+        }
+        memcpy(ta->dn.data, ca.dn, ca.dn_len);
+        ta->dn.len = ca.dn_len;
+        switch(pkey->key_type) {
+        case BR_KEYTYPE_RSA:
+          ta->pkey.key.rsa.n = ta->dn.data + ta->dn.len;
+          memcpy(ta->pkey.key.rsa.n, pkey->key.rsa.n, pkey->key.rsa.nlen);
+          ta->pkey.key.rsa.e = ta->pkey.key.rsa.n + ta->pkey.key.rsa.nlen;
+          memcpy(ta->pkey.key.rsa.e, pkey->key.rsa.e, pkey->key.rsa.elen);
+          break;
+        case BR_KEYTYPE_EC:
+          ta->pkey.key.ec.q = ta->dn.data + ta->dn.len;
+          memcpy(ta->pkey.key.ec.q, pkey->key.ec.q, pkey->key.ec.qlen);
+          break;
+        }
+        break;
+      default:
+        ca.err = CURLE_SSL_CACERT_BADFILE;
+        goto fail;
+      }
+    }
+  }
+  if(ferror(fp))
+    ca.err = CURLE_READ_ERROR;
+
+fail:
+  fclose(fp);
+  if(ca.err == CURLE_OK) {
+    *anchors = ca.anchors;
+    *anchors_len = ca.anchors_len;
+  }
+  else {
+    for(i = 0; i < ca.anchors_len; ++i)
+      free(ca.anchors[i].dn.data);
+    free(ca.anchors);
+  }
+
+  return ca.err;
+}
+
+static void x509_start_chain(const br_x509_class **ctx,
+                             const char *server_name)
+{
+  struct x509_context *x509 = (struct x509_context *)ctx;
+
+  if(!x509->verifyhost)
+    server_name = NULL;
+  x509->minimal.vtable->start_chain(&x509->minimal.vtable, server_name);
+}
+
+static void x509_start_cert(const br_x509_class **ctx, uint32_t length)
+{
+  struct x509_context *x509 = (struct x509_context *)ctx;
+
+  x509->minimal.vtable->start_cert(&x509->minimal.vtable, length);
+}
+
+static void x509_append(const br_x509_class **ctx, const unsigned char *buf,
+                        size_t len)
+{
+  struct x509_context *x509 = (struct x509_context *)ctx;
+
+  x509->minimal.vtable->append(&x509->minimal.vtable, buf, len);
+}
+
+static void x509_end_cert(const br_x509_class **ctx)
+{
+  struct x509_context *x509 = (struct x509_context *)ctx;
+
+  x509->minimal.vtable->end_cert(&x509->minimal.vtable);
+}
+
+static unsigned x509_end_chain(const br_x509_class **ctx)
+{
+  struct x509_context *x509 = (struct x509_context *)ctx;
+  unsigned err;
+
+  err = x509->minimal.vtable->end_chain(&x509->minimal.vtable);
+  if(err && !x509->verifypeer) {
+    /* ignore any X.509 errors */
+    err = BR_ERR_OK;
+  }
+
+  return err;
+}
+
+static const br_x509_pkey *x509_get_pkey(const br_x509_class *const *ctx,
+                                         unsigned *usages)
+{
+  struct x509_context *x509 = (struct x509_context *)ctx;
+
+  return x509->minimal.vtable->get_pkey(&x509->minimal.vtable, usages);
+}
+
+static const br_x509_class x509_vtable = {
+  sizeof(struct x509_context),
+  x509_start_chain,
+  x509_start_cert,
+  x509_append,
+  x509_end_cert,
+  x509_end_chain,
+  x509_get_pkey
+};
+
+static CURLcode bearssl_connect_step1(struct connectdata *conn, int sockindex)
+{
+  struct Curl_easy *data = conn->data;
+  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+  struct ssl_backend_data *backend = connssl->backend;
+  const char * const ssl_cafile = SSL_CONN_CONFIG(CAfile);
+  const char *hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name :
+    conn->host.name;
+  const bool verifypeer = SSL_CONN_CONFIG(verifypeer);
+  const bool verifyhost = SSL_CONN_CONFIG(verifyhost);
+  CURLcode ret;
+  unsigned version_min, version_max;
+#ifdef ENABLE_IPV6
+  struct in6_addr addr;
+#else
+  struct in_addr addr;
+#endif
+
+  switch(SSL_CONN_CONFIG(version)) {
+  case CURL_SSLVERSION_SSLv2:
+    failf(data, "BearSSL does not support SSLv2");
+    return CURLE_SSL_CONNECT_ERROR;
+  case CURL_SSLVERSION_SSLv3:
+    failf(data, "BearSSL does not support SSLv3");
+    return CURLE_SSL_CONNECT_ERROR;
+  case CURL_SSLVERSION_TLSv1_0:
+    version_min = BR_TLS10;
+    version_max = BR_TLS10;
+    break;
+  case CURL_SSLVERSION_TLSv1_1:
+    version_min = BR_TLS11;
+    version_max = BR_TLS11;
+    break;
+  case CURL_SSLVERSION_TLSv1_2:
+    version_min = BR_TLS12;
+    version_max = BR_TLS12;
+    break;
+  case CURL_SSLVERSION_DEFAULT:
+  case CURL_SSLVERSION_TLSv1:
+    version_min = BR_TLS10;
+    version_max = BR_TLS12;
+    break;
+  default:
+    failf(data, "BearSSL: unknown CURLOPT_SSLVERSION");
+    return CURLE_SSL_CONNECT_ERROR;
+  }
+
+  if(ssl_cafile) {
+    ret = load_cafile(ssl_cafile, &backend->anchors, &backend->anchors_len);
+    if(ret != CURLE_OK) {
+      if(verifypeer) {
+        failf(data, "error setting certificate verify locations:\n"
+              "  CAfile: %s\n", ssl_cafile);
+        return ret;
+      }
+      infof(data, "error setting certificate verify locations,"
+            " continuing anyway:\n");
+    }
+  }
+
+  /* initialize SSL context */
+  br_ssl_client_init_full(&backend->ctx, &backend->x509.minimal,
+                          backend->anchors, backend->anchors_len);
+  br_ssl_engine_set_versions(&backend->ctx.eng, version_min, version_max);
+  br_ssl_engine_set_buffer(&backend->ctx.eng, backend->buf,
+                           sizeof(backend->buf), 1);
+
+  /* initialize X.509 context */
+  backend->x509.vtable = &x509_vtable;
+  backend->x509.verifypeer = verifypeer;
+  backend->x509.verifyhost = verifyhost;
+  br_ssl_engine_set_x509(&backend->ctx.eng, &backend->x509.vtable);
+
+  if(SSL_SET_OPTION(primary.sessionid)) {
+    void *session;
+
+    Curl_ssl_sessionid_lock(conn);
+    if(!Curl_ssl_getsessionid(conn, &session, NULL, sockindex)) {
+      br_ssl_engine_set_session_parameters(&backend->ctx.eng, session);
+      infof(data, "BearSSL: re-using session ID\n");
+    }
+    Curl_ssl_sessionid_unlock(conn);
+  }
+
+  if(conn->bits.tls_enable_alpn) {
+    int cur = 0;
+
+    /* NOTE: when adding more protocols here, increase the size of the
+     * protocols array in `struct ssl_backend_data`.
+     */
+
+#ifdef USE_NGHTTP2
+    if(data->set.httpversion >= CURL_HTTP_VERSION_2 &&
+       (!SSL_IS_PROXY() || !conn->bits.tunnel_proxy)) {
+      backend->protocols[cur++] = NGHTTP2_PROTO_VERSION_ID;
+      infof(data, "ALPN, offering %s\n", NGHTTP2_PROTO_VERSION_ID);
+    }
+#endif
+
+    backend->protocols[cur++] = ALPN_HTTP_1_1;
+    infof(data, "ALPN, offering %s\n", ALPN_HTTP_1_1);
+
+    br_ssl_engine_set_protocol_names(&backend->ctx.eng,
+                                     backend->protocols, cur);
+  }
+
+  if((1 == Curl_inet_pton(AF_INET, hostname, &addr))
+#ifdef ENABLE_IPV6
+      || (1 == Curl_inet_pton(AF_INET6, hostname, &addr))
+#endif
+     ) {
+    if(verifyhost) {
+      failf(data, "BearSSL: "
+            "host verification of IP address is not supported");
+      return CURLE_PEER_FAILED_VERIFICATION;
+    }
+    hostname = NULL;
+  }
+
+  if(!br_ssl_client_reset(&backend->ctx, hostname, 0))
+    return CURLE_FAILED_INIT;
+  backend->active = TRUE;
+
+  connssl->connecting_state = ssl_connect_2;
+
+  return CURLE_OK;
+}
+
+static CURLcode bearssl_run_until(struct connectdata *conn, int sockindex,
+                                  unsigned target)
+{
+  struct Curl_easy *data = conn->data;
+  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+  struct ssl_backend_data *backend = connssl->backend;
+  curl_socket_t sockfd = conn->sock[sockindex];
+  unsigned state;
+  unsigned char *buf;
+  size_t len;
+  ssize_t ret;
+  int err;
+
+  for(;;) {
+    state = br_ssl_engine_current_state(&backend->ctx.eng);
+    if(state & BR_SSL_CLOSED) {
+      err = br_ssl_engine_last_error(&backend->ctx.eng);
+      switch(err) {
+      case BR_ERR_OK:
+        /* TLS close notify */
+        if(connssl->state != ssl_connection_complete) {
+          failf(data, "SSL: connection closed during handshake");
+          return CURLE_SSL_CONNECT_ERROR;
+        }
+        return CURLE_OK;
+      case BR_ERR_X509_EXPIRED:
+        failf(data, "SSL: X.509 verification: "
+              "certificate is expired or not yet valid");
+        return CURLE_PEER_FAILED_VERIFICATION;
+      case BR_ERR_X509_BAD_SERVER_NAME:
+        failf(data, "SSL: X.509 verification: "
+              "expected server name was not found in the chain");
+        return CURLE_PEER_FAILED_VERIFICATION;
+      case BR_ERR_X509_NOT_TRUSTED:
+        failf(data, "SSL: X.509 verification: "
+              "chain could not be linked to a trust anchor");
+        return CURLE_PEER_FAILED_VERIFICATION;
+      }
+      /* X.509 errors are documented to have the range 32..63 */
+      if(err >= 32 && err < 64)
+        return CURLE_PEER_FAILED_VERIFICATION;
+      return CURLE_SSL_CONNECT_ERROR;
+    }
+    if(state & target)
+      return CURLE_OK;
+    if(state & BR_SSL_SENDREC) {
+      buf = br_ssl_engine_sendrec_buf(&backend->ctx.eng, &len);
+      ret = swrite(sockfd, buf, len);
+      if(ret == -1) {
+        if(SOCKERRNO == EAGAIN || SOCKERRNO == EWOULDBLOCK) {
+          if(connssl->state != ssl_connection_complete)
+            connssl->connecting_state = ssl_connect_2_writing;
+          return CURLE_AGAIN;
+        }
+        return CURLE_WRITE_ERROR;
+      }
+      br_ssl_engine_sendrec_ack(&backend->ctx.eng, ret);
+    }
+    else if(state & BR_SSL_RECVREC) {
+      buf = br_ssl_engine_recvrec_buf(&backend->ctx.eng, &len);
+      ret = sread(sockfd, buf, len);
+      if(ret == 0) {
+        failf(data, "SSL: EOF without close notify");
+        return CURLE_READ_ERROR;
+      }
+      if(ret == -1) {
+        if(SOCKERRNO == EAGAIN || SOCKERRNO == EWOULDBLOCK) {
+          if(connssl->state != ssl_connection_complete)
+            connssl->connecting_state = ssl_connect_2_reading;
+          return CURLE_AGAIN;
+        }
+        return CURLE_READ_ERROR;
+      }
+      br_ssl_engine_recvrec_ack(&backend->ctx.eng, ret);
+    }
+  }
+}
+
+static CURLcode bearssl_connect_step2(struct connectdata *conn, int sockindex)
+{
+  struct Curl_easy *data = conn->data;
+  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+  struct ssl_backend_data *backend = connssl->backend;
+  CURLcode ret;
+
+  ret = bearssl_run_until(conn, sockindex, BR_SSL_SENDAPP | BR_SSL_RECVAPP);
+  if(ret == CURLE_AGAIN)
+    return CURLE_OK;
+  if(ret == CURLE_OK) {
+    if(br_ssl_engine_current_state(&backend->ctx.eng) == BR_SSL_CLOSED) {
+      failf(data, "SSL: connection closed during handshake");
+      return CURLE_SSL_CONNECT_ERROR;
+    }
+    connssl->connecting_state = ssl_connect_3;
+  }
+  return ret;
+}
+
+static CURLcode bearssl_connect_step3(struct connectdata *conn, int sockindex)
+{
+  struct Curl_easy *data = conn->data;
+  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+  struct ssl_backend_data *backend = connssl->backend;
+  CURLcode ret;
+
+  DEBUGASSERT(ssl_connect_3 == connssl->connecting_state);
+
+  if(conn->bits.tls_enable_alpn) {
+    const char *protocol;
+
+    protocol = br_ssl_engine_get_selected_protocol(&backend->ctx.eng);
+    if(protocol) {
+      infof(data, "ALPN, server accepted to use %s\n", protocol);
+
+#ifdef USE_NGHTTP2
+      if(!strcmp(protocol, NGHTTP2_PROTO_VERSION_ID))
+        conn->negnpn = CURL_HTTP_VERSION_2;
+      else
+#endif
+      if(!strcmp(protocol, ALPN_HTTP_1_1))
+        conn->negnpn = CURL_HTTP_VERSION_1_1;
+      else
+        infof(data, "ALPN, unrecognized protocol %s\n", protocol);
+      Curl_multiuse_state(conn, conn->negnpn == CURL_HTTP_VERSION_2 ?
+                          BUNDLE_MULTIPLEX : BUNDLE_NO_MULTIUSE);
+    }
+    else
+      infof(data, "ALPN, server did not agree to a protocol\n");
+  }
+
+  if(SSL_SET_OPTION(primary.sessionid)) {
+    bool incache;
+    void *oldsession;
+    br_ssl_session_parameters *session;
+
+    session = malloc(sizeof(*session));
+    if(!session)
+      return CURLE_OUT_OF_MEMORY;
+    br_ssl_engine_get_session_parameters(&backend->ctx.eng, session);
+    Curl_ssl_sessionid_lock(conn);
+    incache = !(Curl_ssl_getsessionid(conn, &oldsession, NULL, sockindex));
+    if(incache)
+      Curl_ssl_delsessionid(conn, oldsession);
+    ret = Curl_ssl_addsessionid(conn, session, 0, sockindex);
+    Curl_ssl_sessionid_unlock(conn);
+    if(ret) {
+      free(session);
+      return CURLE_OUT_OF_MEMORY;
+    }
+  }
+
+  connssl->connecting_state = ssl_connect_done;
+
+  return CURLE_OK;
+}
+
+static ssize_t bearssl_send(struct connectdata *conn, int sockindex,
+                            const void *buf, size_t len, CURLcode *err)
+{
+  struct Curl_easy *data = conn->data;
+  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+  struct ssl_backend_data *backend = connssl->backend;
+  unsigned char *app;
+  size_t applen;
+
+  for(;;) {
+    *err = bearssl_run_until(conn, sockindex, BR_SSL_SENDAPP);
+    if (*err != CURLE_OK)
+      return -1;
+    app = br_ssl_engine_sendapp_buf(&backend->ctx.eng, &applen);
+    if(!app) {
+      failf(data, "SSL: connection closed during write");
+      *err = CURLE_SEND_ERROR;
+      return -1;
+    }
+    if(backend->pending_write) {
+      applen = backend->pending_write;
+      backend->pending_write = 0;
+      return applen;
+    }
+    if(applen > len)
+      applen = len;
+    memcpy(app, buf, applen);
+    br_ssl_engine_sendapp_ack(&backend->ctx.eng, applen);
+    br_ssl_engine_flush(&backend->ctx.eng, 0);
+    backend->pending_write = applen;
+  }
+}
+
+static ssize_t bearssl_recv(struct connectdata *conn, int sockindex,
+                            char *buf, size_t len, CURLcode *err)
+{
+  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+  struct ssl_backend_data *backend = connssl->backend;
+  unsigned char *app;
+  size_t applen;
+
+  *err = bearssl_run_until(conn, sockindex, BR_SSL_RECVAPP);
+  if(*err != CURLE_OK)
+    return -1;
+  app = br_ssl_engine_recvapp_buf(&backend->ctx.eng, &applen);
+  if(!app)
+    return 0;
+  if(applen > len)
+    applen = len;
+  memcpy(buf, app, applen);
+  br_ssl_engine_recvapp_ack(&backend->ctx.eng, applen);
+
+  return applen;
+}
+
+static CURLcode bearssl_connect_common(struct connectdata *conn,
+                                       int sockindex,
+                                       bool nonblocking,
+                                       bool *done)
+{
+  CURLcode ret;
+  struct Curl_easy *data = conn->data;
+  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+  curl_socket_t sockfd = conn->sock[sockindex];
+  timediff_t timeout_ms;
+  int what;
+
+  /* check if the connection has already been established */
+  if(ssl_connection_complete == connssl->state) {
+    *done = TRUE;
+    return CURLE_OK;
+  }
+
+  if(ssl_connect_1 == connssl->connecting_state) {
+    ret = bearssl_connect_step1(conn, sockindex);
+    if(ret)
+      return ret;
+  }
+
+  while(ssl_connect_2 == connssl->connecting_state ||
+        ssl_connect_2_reading == connssl->connecting_state ||
+        ssl_connect_2_writing == connssl->connecting_state) {
+    /* check allowed time left */
+    timeout_ms = Curl_timeleft(data, NULL, TRUE);
+
+    if(timeout_ms < 0) {
+      /* no need to continue if time already is up */
+      failf(data, "SSL connection timeout");
+      return CURLE_OPERATION_TIMEDOUT;
+    }
+
+    /* if ssl is expecting something, check if it's available. */
+    if(ssl_connect_2_reading == connssl->connecting_state ||
+       ssl_connect_2_writing == connssl->connecting_state) {
+
+      curl_socket_t writefd = ssl_connect_2_writing ==
+        connssl->connecting_state?sockfd:CURL_SOCKET_BAD;
+      curl_socket_t readfd = ssl_connect_2_reading ==
+        connssl->connecting_state?sockfd:CURL_SOCKET_BAD;
+
+      what = Curl_socket_check(readfd, CURL_SOCKET_BAD, writefd,
+                               nonblocking?0:timeout_ms);
+      if(what < 0) {
+        /* fatal error */
+        failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO);
+        return CURLE_SSL_CONNECT_ERROR;
+      }
+      else if(0 == what) {
+        if(nonblocking) {
+          *done = FALSE;
+          return CURLE_OK;
+        }
+        else {
+          /* timeout */
+          failf(data, "SSL connection timeout");
+          return CURLE_OPERATION_TIMEDOUT;
+        }
+      }
+      /* socket is readable or writable */
+    }
+
+    /* Run transaction, and return to the caller if it failed or if this
+     * connection is done nonblocking and this loop would execute again. This
+     * permits the owner of a multi handle to abort a connection attempt
+     * before step2 has completed while ensuring that a client using select()
+     * or epoll() will always have a valid fdset to wait on.
+     */
+    ret = bearssl_connect_step2(conn, sockindex);
+    if(ret || (nonblocking &&
+               (ssl_connect_2 == connssl->connecting_state ||
+                ssl_connect_2_reading == connssl->connecting_state ||
+                ssl_connect_2_writing == connssl->connecting_state)))
+      return ret;
+  }
+
+  if(ssl_connect_3 == connssl->connecting_state) {
+    ret = bearssl_connect_step3(conn, sockindex);
+    if(ret)
+      return ret;
+  }
+
+  if(ssl_connect_done == connssl->connecting_state) {
+    connssl->state = ssl_connection_complete;
+    conn->recv[sockindex] = bearssl_recv;
+    conn->send[sockindex] = bearssl_send;
+    *done = TRUE;
+  }
+  else
+    *done = FALSE;
+
+  /* Reset our connect state machine */
+  connssl->connecting_state = ssl_connect_1;
+
+  return CURLE_OK;
+}
+
+static size_t Curl_bearssl_version(char *buffer, size_t size)
+{
+  return msnprintf(buffer, size, "BearSSL");
+}
+
+static bool Curl_bearssl_data_pending(const struct connectdata *conn,
+                                      int connindex)
+{
+  const struct ssl_connect_data *connssl = &conn->ssl[connindex];
+  struct ssl_backend_data *backend = connssl->backend;
+  return br_ssl_engine_current_state(&backend->ctx.eng) & BR_SSL_RECVAPP;
+}
+
+static CURLcode Curl_bearssl_random(struct Curl_easy *data UNUSED_PARAM,
+                                    unsigned char *entropy, size_t length)
+{
+  static br_hmac_drbg_context ctx;
+  static bool seeded = FALSE;
+
+  if(!seeded) {
+    br_prng_seeder seeder;
+
+    br_hmac_drbg_init(&ctx, &br_sha256_vtable, NULL, 0);
+    seeder = br_prng_seeder_system(NULL);
+    if(!seeder || !seeder(&ctx.vtable))
+      return CURLE_FAILED_INIT;
+    seeded = TRUE;
+  }
+  br_hmac_drbg_generate(&ctx, entropy, length);
+
+  return CURLE_OK;
+}
+
+static CURLcode Curl_bearssl_connect(struct connectdata *conn, int sockindex)
+{
+  CURLcode ret;
+  bool done = FALSE;
+
+  ret = bearssl_connect_common(conn, sockindex, FALSE, &done);
+  if(ret)
+    return ret;
+
+  DEBUGASSERT(done);
+
+  return CURLE_OK;
+}
+
+static CURLcode Curl_bearssl_connect_nonblocking(struct connectdata *conn,
+                                                 int sockindex, bool *done)
+{
+  return bearssl_connect_common(conn, sockindex, TRUE, done);
+}
+
+static void *Curl_bearssl_get_internals(struct ssl_connect_data *connssl,
+                                        CURLINFO info UNUSED_PARAM)
+{
+  struct ssl_backend_data *backend = connssl->backend;
+  return &backend->ctx;
+}
+
+static void Curl_bearssl_close(struct connectdata *conn, int sockindex)
+{
+  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+  struct ssl_backend_data *backend = connssl->backend;
+  size_t i;
+
+  if(backend->active) {
+    br_ssl_engine_close(&backend->ctx.eng);
+    (void)bearssl_run_until(conn, sockindex, BR_SSL_CLOSED);
+  }
+  for(i = 0; i < backend->anchors_len; ++i)
+    free(backend->anchors[i].dn.data);
+  free(backend->anchors);
+}
+
+static void Curl_bearssl_session_free(void *ptr)
+{
+  free(ptr);
+}
+
+static CURLcode Curl_bearssl_md5sum(unsigned char *input,
+                                    size_t inputlen,
+                                    unsigned char *md5sum,
+                                    size_t md5len UNUSED_PARAM)
+{
+  br_md5_context ctx;
+
+  br_md5_init(&ctx);
+  br_md5_update(&ctx, input, inputlen);
+  br_md5_out(&ctx, md5sum);
+  return CURLE_OK;
+}
+
+static CURLcode Curl_bearssl_sha256sum(const unsigned char *input,
+                                       size_t inputlen,
+                                       unsigned char *sha256sum,
+                                       size_t sha256len UNUSED_PARAM)
+{
+  br_sha256_context ctx;
+
+  br_sha256_init(&ctx);
+  br_sha256_update(&ctx, input, inputlen);
+  br_sha256_out(&ctx, sha256sum);
+  return CURLE_OK;
+}
+
+const struct Curl_ssl Curl_ssl_bearssl = {
+  { CURLSSLBACKEND_BEARSSL, "bearssl" },
+  0,
+  sizeof(struct ssl_backend_data),
+
+  Curl_none_init,
+  Curl_none_cleanup,
+  Curl_bearssl_version,
+  Curl_none_check_cxn,
+  Curl_none_shutdown,
+  Curl_bearssl_data_pending,
+  Curl_bearssl_random,
+  Curl_none_cert_status_request,
+  Curl_bearssl_connect,
+  Curl_bearssl_connect_nonblocking,
+  Curl_bearssl_get_internals,
+  Curl_bearssl_close,
+  Curl_none_close_all,
+  Curl_bearssl_session_free,
+  Curl_none_set_engine,
+  Curl_none_set_engine_default,
+  Curl_none_engines_list,
+  Curl_none_false_start,
+  Curl_bearssl_md5sum,
+  Curl_bearssl_sha256sum
+};
+
+#endif /* USE_BEARSSL */
diff --git a/Utilities/cmcurl/lib/vtls/bearssl.h b/Utilities/cmcurl/lib/vtls/bearssl.h
new file mode 100644
index 0000000..5f94922
--- /dev/null
+++ b/Utilities/cmcurl/lib/vtls/bearssl.h
@@ -0,0 +1,32 @@
+#ifndef HEADER_CURL_BEARSSL_H
+#define HEADER_CURL_BEARSSL_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 2019, Michael Forney, <mforney@mforney.org>
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#ifdef USE_BEARSSL
+
+extern const struct Curl_ssl Curl_ssl_bearssl;
+
+#endif /* USE_BEARSSL */
+#endif /* HEADER_CURL_BEARSSL_H */
diff --git a/Utilities/cmcurl/lib/vtls/cyassl.c b/Utilities/cmcurl/lib/vtls/cyassl.c
deleted file mode 100644
index 44a2bdd..0000000
--- a/Utilities/cmcurl/lib/vtls/cyassl.c
+++ /dev/null
@@ -1,1018 +0,0 @@
-/***************************************************************************
- *                                  _   _ ____  _
- *  Project                     ___| | | |  _ \| |
- *                             / __| | | | |_) | |
- *                            | (__| |_| |  _ <| |___
- *                             \___|\___/|_| \_\_____|
- *
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * This software is licensed as described in the file COPYING, which
- * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
- *
- * You may opt to use, copy, modify, merge, publish, distribute and/or sell
- * copies of the Software, and permit persons to whom the Software is
- * furnished to do so, under the terms of the COPYING file.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- ***************************************************************************/
-
-/*
- * Source file for all CyaSSL-specific code for the TLS/SSL layer. No code
- * but vtls.c should ever call or use these functions.
- *
- */
-
-#include "curl_setup.h"
-
-#ifdef USE_CYASSL
-
-#define WOLFSSL_OPTIONS_IGNORE_SYS
-/* CyaSSL's version.h, which should contain only the version, should come
-before all other CyaSSL includes and be immediately followed by build config
-aka options.h. https://curl.haxx.se/mail/lib-2015-04/0069.html */
-#include <cyassl/version.h>
-#if defined(HAVE_CYASSL_OPTIONS_H) && (LIBCYASSL_VERSION_HEX > 0x03004008)
-#if defined(CYASSL_API) || defined(WOLFSSL_API)
-/* Safety measure. If either is defined some API include was already included
-and that's a problem since options.h hasn't been included yet. */
-#error "CyaSSL API was included before the CyaSSL build options."
-#endif
-#include <cyassl/options.h>
-#endif
-
-/* To determine what functions are available we rely on one or both of:
-   - the user's options.h generated by CyaSSL/wolfSSL
-   - the symbols detected by curl's configure
-   Since they are markedly different from one another, and one or the other may
-   not be available, we do some checking below to bring things in sync. */
-
-/* HAVE_ALPN is wolfSSL's build time symbol for enabling ALPN in options.h. */
-#ifndef HAVE_ALPN
-#ifdef HAVE_WOLFSSL_USEALPN
-#define HAVE_ALPN
-#endif
-#endif
-
-/* WOLFSSL_ALLOW_SSLV3 is wolfSSL's build time symbol for enabling SSLv3 in
-   options.h, but is only seen in >= 3.6.6 since that's when they started
-   disabling SSLv3 by default. */
-#ifndef WOLFSSL_ALLOW_SSLV3
-#if (LIBCYASSL_VERSION_HEX < 0x03006006) || \
-    defined(HAVE_WOLFSSLV3_CLIENT_METHOD)
-#define WOLFSSL_ALLOW_SSLV3
-#endif
-#endif
-
-#include <limits.h>
-
-#include "urldata.h"
-#include "sendf.h"
-#include "inet_pton.h"
-#include "vtls.h"
-#include "parsedate.h"
-#include "connect.h" /* for the connect timeout */
-#include "select.h"
-#include "strcase.h"
-#include "x509asn1.h"
-#include "curl_printf.h"
-#include "multiif.h"
-
-#include <cyassl/openssl/ssl.h>
-#include <cyassl/ssl.h>
-#ifdef HAVE_CYASSL_ERROR_SSL_H
-#include <cyassl/error-ssl.h>
-#else
-#include <cyassl/error.h>
-#endif
-#include <cyassl/ctaocrypt/random.h>
-#include <cyassl/ctaocrypt/sha256.h>
-
-#include "cyassl.h"
-
-/* The last #include files should be: */
-#include "curl_memory.h"
-#include "memdebug.h"
-
-#if LIBCYASSL_VERSION_HEX < 0x02007002 /* < 2.7.2 */
-#define CYASSL_MAX_ERROR_SZ 80
-#endif
-
-/* KEEP_PEER_CERT is a product of the presence of build time symbol
-   OPENSSL_EXTRA without NO_CERTS, depending on the version. KEEP_PEER_CERT is
-   in wolfSSL's settings.h, and the latter two are build time symbols in
-   options.h. */
-#ifndef KEEP_PEER_CERT
-#if defined(HAVE_CYASSL_GET_PEER_CERTIFICATE) || \
-    defined(HAVE_WOLFSSL_GET_PEER_CERTIFICATE) || \
-    (defined(OPENSSL_EXTRA) && !defined(NO_CERTS))
-#define KEEP_PEER_CERT
-#endif
-#endif
-
-struct ssl_backend_data {
-  SSL_CTX* ctx;
-  SSL*     handle;
-};
-
-#define BACKEND connssl->backend
-
-static Curl_recv cyassl_recv;
-static Curl_send cyassl_send;
-
-
-static int do_file_type(const char *type)
-{
-  if(!type || !type[0])
-    return SSL_FILETYPE_PEM;
-  if(strcasecompare(type, "PEM"))
-    return SSL_FILETYPE_PEM;
-  if(strcasecompare(type, "DER"))
-    return SSL_FILETYPE_ASN1;
-  return -1;
-}
-
-/*
- * This function loads all the client/CA certificates and CRLs. Setup the TLS
- * layer and do all necessary magic.
- */
-static CURLcode
-cyassl_connect_step1(struct connectdata *conn,
-                     int sockindex)
-{
-  char *ciphers;
-  struct Curl_easy *data = conn->data;
-  struct ssl_connect_data* connssl = &conn->ssl[sockindex];
-  SSL_METHOD* req_method = NULL;
-  curl_socket_t sockfd = conn->sock[sockindex];
-#ifdef HAVE_SNI
-  bool sni = FALSE;
-#define use_sni(x)  sni = (x)
-#else
-#define use_sni(x)  Curl_nop_stmt
-#endif
-
-  if(connssl->state == ssl_connection_complete)
-    return CURLE_OK;
-
-  if(SSL_CONN_CONFIG(version_max) != CURL_SSLVERSION_MAX_NONE) {
-    failf(data, "CyaSSL does not support to set maximum SSL/TLS version");
-    return CURLE_SSL_CONNECT_ERROR;
-  }
-
-  /* check to see if we've been told to use an explicit SSL/TLS version */
-  switch(SSL_CONN_CONFIG(version)) {
-  case CURL_SSLVERSION_DEFAULT:
-  case CURL_SSLVERSION_TLSv1:
-#if LIBCYASSL_VERSION_HEX >= 0x03003000 /* >= 3.3.0 */
-    /* minimum protocol version is set later after the CTX object is created */
-    req_method = SSLv23_client_method();
-#else
-    infof(data, "CyaSSL <3.3.0 cannot be configured to use TLS 1.0-1.2, "
-          "TLS 1.0 is used exclusively\n");
-    req_method = TLSv1_client_method();
-#endif
-    use_sni(TRUE);
-    break;
-  case CURL_SSLVERSION_TLSv1_0:
-#ifdef WOLFSSL_ALLOW_TLSV10
-    req_method = TLSv1_client_method();
-    use_sni(TRUE);
-#else
-    failf(data, "CyaSSL does not support TLS 1.0");
-    return CURLE_NOT_BUILT_IN;
-#endif
-    break;
-  case CURL_SSLVERSION_TLSv1_1:
-    req_method = TLSv1_1_client_method();
-    use_sni(TRUE);
-    break;
-  case CURL_SSLVERSION_TLSv1_2:
-    req_method = TLSv1_2_client_method();
-    use_sni(TRUE);
-    break;
-  case CURL_SSLVERSION_TLSv1_3:
-#ifdef WOLFSSL_TLS13
-    req_method = wolfTLSv1_3_client_method();
-    use_sni(TRUE);
-    break;
-#else
-    failf(data, "CyaSSL: TLS 1.3 is not yet supported");
-    return CURLE_SSL_CONNECT_ERROR;
-#endif
-  case CURL_SSLVERSION_SSLv3:
-#ifdef WOLFSSL_ALLOW_SSLV3
-    req_method = SSLv3_client_method();
-    use_sni(FALSE);
-#else
-    failf(data, "CyaSSL does not support SSLv3");
-    return CURLE_NOT_BUILT_IN;
-#endif
-    break;
-  case CURL_SSLVERSION_SSLv2:
-    failf(data, "CyaSSL does not support SSLv2");
-    return CURLE_SSL_CONNECT_ERROR;
-  default:
-    failf(data, "Unrecognized parameter passed via CURLOPT_SSLVERSION");
-    return CURLE_SSL_CONNECT_ERROR;
-  }
-
-  if(!req_method) {
-    failf(data, "SSL: couldn't create a method!");
-    return CURLE_OUT_OF_MEMORY;
-  }
-
-  if(BACKEND->ctx)
-    SSL_CTX_free(BACKEND->ctx);
-  BACKEND->ctx = SSL_CTX_new(req_method);
-
-  if(!BACKEND->ctx) {
-    failf(data, "SSL: couldn't create a context!");
-    return CURLE_OUT_OF_MEMORY;
-  }
-
-  switch(SSL_CONN_CONFIG(version)) {
-  case CURL_SSLVERSION_DEFAULT:
-  case CURL_SSLVERSION_TLSv1:
-#if LIBCYASSL_VERSION_HEX > 0x03004006 /* > 3.4.6 */
-    /* Versions 3.3.0 to 3.4.6 we know the minimum protocol version is whatever
-    minimum version of TLS was built in and at least TLS 1.0. For later library
-    versions that could change (eg TLS 1.0 built in but defaults to TLS 1.1) so
-    we have this short circuit evaluation to find the minimum supported TLS
-    version. We use wolfSSL_CTX_SetMinVersion and not CyaSSL_SetMinVersion
-    because only the former will work before the user's CTX callback is called.
-    */
-    if((wolfSSL_CTX_SetMinVersion(BACKEND->ctx, WOLFSSL_TLSV1) != 1) &&
-       (wolfSSL_CTX_SetMinVersion(BACKEND->ctx, WOLFSSL_TLSV1_1) != 1) &&
-       (wolfSSL_CTX_SetMinVersion(BACKEND->ctx, WOLFSSL_TLSV1_2) != 1)
-#ifdef WOLFSSL_TLS13
-       && (wolfSSL_CTX_SetMinVersion(BACKEND->ctx, WOLFSSL_TLSV1_3) != 1)
-#endif
-      ) {
-      failf(data, "SSL: couldn't set the minimum protocol version");
-      return CURLE_SSL_CONNECT_ERROR;
-    }
-#endif
-    break;
-  }
-
-  ciphers = SSL_CONN_CONFIG(cipher_list);
-  if(ciphers) {
-    if(!SSL_CTX_set_cipher_list(BACKEND->ctx, ciphers)) {
-      failf(data, "failed setting cipher list: %s", ciphers);
-      return CURLE_SSL_CIPHER;
-    }
-    infof(data, "Cipher selection: %s\n", ciphers);
-  }
-
-#ifndef NO_FILESYSTEM
-  /* load trusted cacert */
-  if(SSL_CONN_CONFIG(CAfile)) {
-    if(1 != SSL_CTX_load_verify_locations(BACKEND->ctx,
-                                      SSL_CONN_CONFIG(CAfile),
-                                      SSL_CONN_CONFIG(CApath))) {
-      if(SSL_CONN_CONFIG(verifypeer)) {
-        /* Fail if we insist on successfully verifying the server. */
-        failf(data, "error setting certificate verify locations:\n"
-              "  CAfile: %s\n  CApath: %s",
-              SSL_CONN_CONFIG(CAfile)?
-              SSL_CONN_CONFIG(CAfile): "none",
-              SSL_CONN_CONFIG(CApath)?
-              SSL_CONN_CONFIG(CApath) : "none");
-        return CURLE_SSL_CACERT_BADFILE;
-      }
-      else {
-        /* Just continue with a warning if no strict certificate
-           verification is required. */
-        infof(data, "error setting certificate verify locations,"
-              " continuing anyway:\n");
-      }
-    }
-    else {
-      /* Everything is fine. */
-      infof(data, "successfully set certificate verify locations:\n");
-    }
-    infof(data,
-          "  CAfile: %s\n"
-          "  CApath: %s\n",
-          SSL_CONN_CONFIG(CAfile) ? SSL_CONN_CONFIG(CAfile):
-          "none",
-          SSL_CONN_CONFIG(CApath) ? SSL_CONN_CONFIG(CApath):
-          "none");
-  }
-
-  /* Load the client certificate, and private key */
-  if(SSL_SET_OPTION(cert) && SSL_SET_OPTION(key)) {
-    int file_type = do_file_type(SSL_SET_OPTION(cert_type));
-
-    if(SSL_CTX_use_certificate_file(BACKEND->ctx, SSL_SET_OPTION(cert),
-                                     file_type) != 1) {
-      failf(data, "unable to use client certificate (no key or wrong pass"
-            " phrase?)");
-      return CURLE_SSL_CONNECT_ERROR;
-    }
-
-    file_type = do_file_type(SSL_SET_OPTION(key_type));
-    if(SSL_CTX_use_PrivateKey_file(BACKEND->ctx, SSL_SET_OPTION(key),
-                                    file_type) != 1) {
-      failf(data, "unable to set private key");
-      return CURLE_SSL_CONNECT_ERROR;
-    }
-  }
-#endif /* !NO_FILESYSTEM */
-
-  /* SSL always tries to verify the peer, this only says whether it should
-   * fail to connect if the verification fails, or if it should continue
-   * anyway. In the latter case the result of the verification is checked with
-   * SSL_get_verify_result() below. */
-  SSL_CTX_set_verify(BACKEND->ctx,
-                     SSL_CONN_CONFIG(verifypeer)?SSL_VERIFY_PEER:
-                                                 SSL_VERIFY_NONE,
-                     NULL);
-
-#ifdef HAVE_SNI
-  if(sni) {
-    struct in_addr addr4;
-#ifdef ENABLE_IPV6
-    struct in6_addr addr6;
-#endif
-    const char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name :
-      conn->host.name;
-    size_t hostname_len = strlen(hostname);
-    if((hostname_len < USHRT_MAX) &&
-       (0 == Curl_inet_pton(AF_INET, hostname, &addr4)) &&
-#ifdef ENABLE_IPV6
-       (0 == Curl_inet_pton(AF_INET6, hostname, &addr6)) &&
-#endif
-       (CyaSSL_CTX_UseSNI(BACKEND->ctx, CYASSL_SNI_HOST_NAME, hostname,
-                          (unsigned short)hostname_len) != 1)) {
-      infof(data, "WARNING: failed to configure server name indication (SNI) "
-            "TLS extension\n");
-    }
-  }
-#endif
-
-  /* give application a chance to interfere with SSL set up. */
-  if(data->set.ssl.fsslctx) {
-    CURLcode result = CURLE_OK;
-    result = (*data->set.ssl.fsslctx)(data, BACKEND->ctx,
-                                      data->set.ssl.fsslctxp);
-    if(result) {
-      failf(data, "error signaled by ssl ctx callback");
-      return result;
-    }
-  }
-#ifdef NO_FILESYSTEM
-  else if(SSL_CONN_CONFIG(verifypeer)) {
-    failf(data, "SSL: Certificates couldn't be loaded because CyaSSL was built"
-          " with \"no filesystem\". Either disable peer verification"
-          " (insecure) or if you are building an application with libcurl you"
-          " can load certificates via CURLOPT_SSL_CTX_FUNCTION.");
-    return CURLE_SSL_CONNECT_ERROR;
-  }
-#endif
-
-  /* Let's make an SSL structure */
-  if(BACKEND->handle)
-    SSL_free(BACKEND->handle);
-  BACKEND->handle = SSL_new(BACKEND->ctx);
-  if(!BACKEND->handle) {
-    failf(data, "SSL: couldn't create a context (handle)!");
-    return CURLE_OUT_OF_MEMORY;
-  }
-
-#ifdef HAVE_ALPN
-  if(conn->bits.tls_enable_alpn) {
-    char protocols[128];
-    *protocols = '\0';
-
-    /* wolfSSL's ALPN protocol name list format is a comma separated string of
-       protocols in descending order of preference, eg: "h2,http/1.1" */
-
-#ifdef USE_NGHTTP2
-    if(data->set.httpversion >= CURL_HTTP_VERSION_2) {
-      strcpy(protocols + strlen(protocols), NGHTTP2_PROTO_VERSION_ID ",");
-      infof(data, "ALPN, offering %s\n", NGHTTP2_PROTO_VERSION_ID);
-    }
-#endif
-
-    strcpy(protocols + strlen(protocols), ALPN_HTTP_1_1);
-    infof(data, "ALPN, offering %s\n", ALPN_HTTP_1_1);
-
-    if(wolfSSL_UseALPN(BACKEND->handle, protocols,
-                       (unsigned)strlen(protocols),
-                       WOLFSSL_ALPN_CONTINUE_ON_MISMATCH) != SSL_SUCCESS) {
-      failf(data, "SSL: failed setting ALPN protocols");
-      return CURLE_SSL_CONNECT_ERROR;
-    }
-  }
-#endif /* HAVE_ALPN */
-
-  /* Check if there's a cached ID we can/should use here! */
-  if(SSL_SET_OPTION(primary.sessionid)) {
-    void *ssl_sessionid = NULL;
-
-    Curl_ssl_sessionid_lock(conn);
-    if(!Curl_ssl_getsessionid(conn, &ssl_sessionid, NULL, sockindex)) {
-      /* we got a session id, use it! */
-      if(!SSL_set_session(BACKEND->handle, ssl_sessionid)) {
-        char error_buffer[CYASSL_MAX_ERROR_SZ];
-        Curl_ssl_sessionid_unlock(conn);
-        failf(data, "SSL: SSL_set_session failed: %s",
-              ERR_error_string(SSL_get_error(BACKEND->handle, 0),
-              error_buffer));
-        return CURLE_SSL_CONNECT_ERROR;
-      }
-      /* Informational message */
-      infof(data, "SSL re-using session ID\n");
-    }
-    Curl_ssl_sessionid_unlock(conn);
-  }
-
-  /* pass the raw socket into the SSL layer */
-  if(!SSL_set_fd(BACKEND->handle, (int)sockfd)) {
-    failf(data, "SSL: SSL_set_fd failed");
-    return CURLE_SSL_CONNECT_ERROR;
-  }
-
-  connssl->connecting_state = ssl_connect_2;
-  return CURLE_OK;
-}
-
-
-static CURLcode
-cyassl_connect_step2(struct connectdata *conn,
-                     int sockindex)
-{
-  int ret = -1;
-  struct Curl_easy *data = conn->data;
-  struct ssl_connect_data* connssl = &conn->ssl[sockindex];
-  const char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name :
-    conn->host.name;
-  const char * const dispname = SSL_IS_PROXY() ?
-    conn->http_proxy.host.dispname : conn->host.dispname;
-  const char * const pinnedpubkey = SSL_IS_PROXY() ?
-                        data->set.str[STRING_SSL_PINNEDPUBLICKEY_PROXY] :
-                        data->set.str[STRING_SSL_PINNEDPUBLICKEY_ORIG];
-
-  conn->recv[sockindex] = cyassl_recv;
-  conn->send[sockindex] = cyassl_send;
-
-  /* Enable RFC2818 checks */
-  if(SSL_CONN_CONFIG(verifyhost)) {
-    ret = CyaSSL_check_domain_name(BACKEND->handle, hostname);
-    if(ret == SSL_FAILURE)
-      return CURLE_OUT_OF_MEMORY;
-  }
-
-  ret = SSL_connect(BACKEND->handle);
-  if(ret != 1) {
-    char error_buffer[CYASSL_MAX_ERROR_SZ];
-    int  detail = SSL_get_error(BACKEND->handle, ret);
-
-    if(SSL_ERROR_WANT_READ == detail) {
-      connssl->connecting_state = ssl_connect_2_reading;
-      return CURLE_OK;
-    }
-    else if(SSL_ERROR_WANT_WRITE == detail) {
-      connssl->connecting_state = ssl_connect_2_writing;
-      return CURLE_OK;
-    }
-    /* There is no easy way to override only the CN matching.
-     * This will enable the override of both mismatching SubjectAltNames
-     * as also mismatching CN fields */
-    else if(DOMAIN_NAME_MISMATCH == detail) {
-#if 1
-      failf(data, "\tsubject alt name(s) or common name do not match \"%s\"\n",
-            dispname);
-      return CURLE_PEER_FAILED_VERIFICATION;
-#else
-      /* When the CyaSSL_check_domain_name() is used and you desire to continue
-       * on a DOMAIN_NAME_MISMATCH, i.e. 'conn->ssl_config.verifyhost == 0',
-       * CyaSSL version 2.4.0 will fail with an INCOMPLETE_DATA error. The only
-       * way to do this is currently to switch the CyaSSL_check_domain_name()
-       * in and out based on the 'conn->ssl_config.verifyhost' value. */
-      if(SSL_CONN_CONFIG(verifyhost)) {
-        failf(data,
-              "\tsubject alt name(s) or common name do not match \"%s\"\n",
-              dispname);
-        return CURLE_PEER_FAILED_VERIFICATION;
-      }
-      else {
-        infof(data,
-              "\tsubject alt name(s) and/or common name do not match \"%s\"\n",
-              dispname);
-        return CURLE_OK;
-      }
-#endif
-    }
-#if LIBCYASSL_VERSION_HEX >= 0x02007000 /* 2.7.0 */
-    else if(ASN_NO_SIGNER_E == detail) {
-      if(SSL_CONN_CONFIG(verifypeer)) {
-        failf(data, "\tCA signer not available for verification\n");
-        return CURLE_SSL_CACERT_BADFILE;
-      }
-      else {
-        /* Just continue with a warning if no strict certificate
-           verification is required. */
-        infof(data, "CA signer not available for verification, "
-                    "continuing anyway\n");
-      }
-    }
-#endif
-    else {
-      failf(data, "SSL_connect failed with error %d: %s", detail,
-          ERR_error_string(detail, error_buffer));
-      return CURLE_SSL_CONNECT_ERROR;
-    }
-  }
-
-  if(pinnedpubkey) {
-#ifdef KEEP_PEER_CERT
-    X509 *x509;
-    const char *x509_der;
-    int x509_der_len;
-    curl_X509certificate x509_parsed;
-    curl_asn1Element *pubkey;
-    CURLcode result;
-
-    x509 = SSL_get_peer_certificate(BACKEND->handle);
-    if(!x509) {
-      failf(data, "SSL: failed retrieving server certificate");
-      return CURLE_SSL_PINNEDPUBKEYNOTMATCH;
-    }
-
-    x509_der = (const char *)CyaSSL_X509_get_der(x509, &x509_der_len);
-    if(!x509_der) {
-      failf(data, "SSL: failed retrieving ASN.1 server certificate");
-      return CURLE_SSL_PINNEDPUBKEYNOTMATCH;
-    }
-
-    memset(&x509_parsed, 0, sizeof(x509_parsed));
-    if(Curl_parseX509(&x509_parsed, x509_der, x509_der + x509_der_len))
-      return CURLE_SSL_PINNEDPUBKEYNOTMATCH;
-
-    pubkey = &x509_parsed.subjectPublicKeyInfo;
-    if(!pubkey->header || pubkey->end <= pubkey->header) {
-      failf(data, "SSL: failed retrieving public key from server certificate");
-      return CURLE_SSL_PINNEDPUBKEYNOTMATCH;
-    }
-
-    result = Curl_pin_peer_pubkey(data,
-                                  pinnedpubkey,
-                                  (const unsigned char *)pubkey->header,
-                                  (size_t)(pubkey->end - pubkey->header));
-    if(result) {
-      failf(data, "SSL: public key does not match pinned public key!");
-      return result;
-    }
-#else
-    failf(data, "Library lacks pinning support built-in");
-    return CURLE_NOT_BUILT_IN;
-#endif
-  }
-
-#ifdef HAVE_ALPN
-  if(conn->bits.tls_enable_alpn) {
-    int rc;
-    char *protocol = NULL;
-    unsigned short protocol_len = 0;
-
-    rc = wolfSSL_ALPN_GetProtocol(BACKEND->handle, &protocol, &protocol_len);
-
-    if(rc == SSL_SUCCESS) {
-      infof(data, "ALPN, server accepted to use %.*s\n", protocol_len,
-            protocol);
-
-      if(protocol_len == ALPN_HTTP_1_1_LENGTH &&
-         !memcmp(protocol, ALPN_HTTP_1_1, ALPN_HTTP_1_1_LENGTH))
-        conn->negnpn = CURL_HTTP_VERSION_1_1;
-#ifdef USE_NGHTTP2
-      else if(data->set.httpversion >= CURL_HTTP_VERSION_2 &&
-              protocol_len == NGHTTP2_PROTO_VERSION_ID_LEN &&
-              !memcmp(protocol, NGHTTP2_PROTO_VERSION_ID,
-                      NGHTTP2_PROTO_VERSION_ID_LEN))
-        conn->negnpn = CURL_HTTP_VERSION_2;
-#endif
-      else
-        infof(data, "ALPN, unrecognized protocol %.*s\n", protocol_len,
-              protocol);
-      Curl_multiuse_state(conn, conn->negnpn == CURL_HTTP_VERSION_2 ?
-                          BUNDLE_MULTIPLEX : BUNDLE_NO_MULTIUSE);
-    }
-    else if(rc == SSL_ALPN_NOT_FOUND)
-      infof(data, "ALPN, server did not agree to a protocol\n");
-    else {
-      failf(data, "ALPN, failure getting protocol, error %d", rc);
-      return CURLE_SSL_CONNECT_ERROR;
-    }
-  }
-#endif /* HAVE_ALPN */
-
-  connssl->connecting_state = ssl_connect_3;
-#if (LIBCYASSL_VERSION_HEX >= 0x03009010)
-  infof(data, "SSL connection using %s / %s\n",
-        wolfSSL_get_version(BACKEND->handle),
-        wolfSSL_get_cipher_name(BACKEND->handle));
-#else
-  infof(data, "SSL connected\n");
-#endif
-
-  return CURLE_OK;
-}
-
-
-static CURLcode
-cyassl_connect_step3(struct connectdata *conn,
-                     int sockindex)
-{
-  CURLcode result = CURLE_OK;
-  struct Curl_easy *data = conn->data;
-  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
-
-  DEBUGASSERT(ssl_connect_3 == connssl->connecting_state);
-
-  if(SSL_SET_OPTION(primary.sessionid)) {
-    bool incache;
-    SSL_SESSION *our_ssl_sessionid;
-    void *old_ssl_sessionid = NULL;
-
-    our_ssl_sessionid = SSL_get_session(BACKEND->handle);
-
-    Curl_ssl_sessionid_lock(conn);
-    incache = !(Curl_ssl_getsessionid(conn, &old_ssl_sessionid, NULL,
-                                      sockindex));
-    if(incache) {
-      if(old_ssl_sessionid != our_ssl_sessionid) {
-        infof(data, "old SSL session ID is stale, removing\n");
-        Curl_ssl_delsessionid(conn, old_ssl_sessionid);
-        incache = FALSE;
-      }
-    }
-
-    if(!incache) {
-      result = Curl_ssl_addsessionid(conn, our_ssl_sessionid,
-                                     0 /* unknown size */, sockindex);
-      if(result) {
-        Curl_ssl_sessionid_unlock(conn);
-        failf(data, "failed to store ssl session");
-        return result;
-      }
-    }
-    Curl_ssl_sessionid_unlock(conn);
-  }
-
-  connssl->connecting_state = ssl_connect_done;
-
-  return result;
-}
-
-
-static ssize_t cyassl_send(struct connectdata *conn,
-                           int sockindex,
-                           const void *mem,
-                           size_t len,
-                           CURLcode *curlcode)
-{
-  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
-  char error_buffer[CYASSL_MAX_ERROR_SZ];
-  int  memlen = (len > (size_t)INT_MAX) ? INT_MAX : (int)len;
-  int  rc     = SSL_write(BACKEND->handle, mem, memlen);
-
-  if(rc < 0) {
-    int err = SSL_get_error(BACKEND->handle, rc);
-
-    switch(err) {
-    case SSL_ERROR_WANT_READ:
-    case SSL_ERROR_WANT_WRITE:
-      /* there's data pending, re-invoke SSL_write() */
-      *curlcode = CURLE_AGAIN;
-      return -1;
-    default:
-      failf(conn->data, "SSL write: %s, errno %d",
-            ERR_error_string(err, error_buffer),
-            SOCKERRNO);
-      *curlcode = CURLE_SEND_ERROR;
-      return -1;
-    }
-  }
-  return rc;
-}
-
-static void Curl_cyassl_close(struct connectdata *conn, int sockindex)
-{
-  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
-
-  if(BACKEND->handle) {
-    (void)SSL_shutdown(BACKEND->handle);
-    SSL_free(BACKEND->handle);
-    BACKEND->handle = NULL;
-  }
-  if(BACKEND->ctx) {
-    SSL_CTX_free(BACKEND->ctx);
-    BACKEND->ctx = NULL;
-  }
-}
-
-static ssize_t cyassl_recv(struct connectdata *conn,
-                           int num,
-                           char *buf,
-                           size_t buffersize,
-                           CURLcode *curlcode)
-{
-  struct ssl_connect_data *connssl = &conn->ssl[num];
-  char error_buffer[CYASSL_MAX_ERROR_SZ];
-  int  buffsize = (buffersize > (size_t)INT_MAX) ? INT_MAX : (int)buffersize;
-  int  nread    = SSL_read(BACKEND->handle, buf, buffsize);
-
-  if(nread < 0) {
-    int err = SSL_get_error(BACKEND->handle, nread);
-
-    switch(err) {
-    case SSL_ERROR_ZERO_RETURN: /* no more data */
-      break;
-    case SSL_ERROR_WANT_READ:
-    case SSL_ERROR_WANT_WRITE:
-      /* there's data pending, re-invoke SSL_read() */
-      *curlcode = CURLE_AGAIN;
-      return -1;
-    default:
-      failf(conn->data, "SSL read: %s, errno %d",
-            ERR_error_string(err, error_buffer),
-            SOCKERRNO);
-      *curlcode = CURLE_RECV_ERROR;
-      return -1;
-    }
-  }
-  return nread;
-}
-
-
-static void Curl_cyassl_session_free(void *ptr)
-{
-  (void)ptr;
-  /* CyaSSL reuses sessions on own, no free */
-}
-
-
-static size_t Curl_cyassl_version(char *buffer, size_t size)
-{
-#if LIBCYASSL_VERSION_HEX >= 0x03006000
-  return msnprintf(buffer, size, "wolfSSL/%s", wolfSSL_lib_version());
-#elif defined(WOLFSSL_VERSION)
-  return msnprintf(buffer, size, "wolfSSL/%s", WOLFSSL_VERSION);
-#elif defined(CYASSL_VERSION)
-  return msnprintf(buffer, size, "CyaSSL/%s", CYASSL_VERSION);
-#else
-  return msnprintf(buffer, size, "CyaSSL/%s", "<1.8.8");
-#endif
-}
-
-
-static int Curl_cyassl_init(void)
-{
-  return (CyaSSL_Init() == SSL_SUCCESS);
-}
-
-
-static void Curl_cyassl_cleanup(void)
-{
-  CyaSSL_Cleanup();
-}
-
-
-static bool Curl_cyassl_data_pending(const struct connectdata* conn,
-                                     int connindex)
-{
-  const struct ssl_connect_data *connssl = &conn->ssl[connindex];
-  if(BACKEND->handle)   /* SSL is in use */
-    return (0 != SSL_pending(BACKEND->handle)) ? TRUE : FALSE;
-  else
-    return FALSE;
-}
-
-
-/*
- * This function is called to shut down the SSL layer but keep the
- * socket open (CCC - Clear Command Channel)
- */
-static int Curl_cyassl_shutdown(struct connectdata *conn, int sockindex)
-{
-  int retval = 0;
-  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
-
-  if(BACKEND->handle) {
-    SSL_free(BACKEND->handle);
-    BACKEND->handle = NULL;
-  }
-  return retval;
-}
-
-
-static CURLcode
-cyassl_connect_common(struct connectdata *conn,
-                      int sockindex,
-                      bool nonblocking,
-                      bool *done)
-{
-  CURLcode result;
-  struct Curl_easy *data = conn->data;
-  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
-  curl_socket_t sockfd = conn->sock[sockindex];
-  time_t timeout_ms;
-  int what;
-
-  /* check if the connection has already been established */
-  if(ssl_connection_complete == connssl->state) {
-    *done = TRUE;
-    return CURLE_OK;
-  }
-
-  if(ssl_connect_1 == connssl->connecting_state) {
-    /* Find out how much more time we're allowed */
-    timeout_ms = Curl_timeleft(data, NULL, TRUE);
-
-    if(timeout_ms < 0) {
-      /* no need to continue if time already is up */
-      failf(data, "SSL connection timeout");
-      return CURLE_OPERATION_TIMEDOUT;
-    }
-
-    result = cyassl_connect_step1(conn, sockindex);
-    if(result)
-      return result;
-  }
-
-  while(ssl_connect_2 == connssl->connecting_state ||
-        ssl_connect_2_reading == connssl->connecting_state ||
-        ssl_connect_2_writing == connssl->connecting_state) {
-
-    /* check allowed time left */
-    timeout_ms = Curl_timeleft(data, NULL, TRUE);
-
-    if(timeout_ms < 0) {
-      /* no need to continue if time already is up */
-      failf(data, "SSL connection timeout");
-      return CURLE_OPERATION_TIMEDOUT;
-    }
-
-    /* if ssl is expecting something, check if it's available. */
-    if(connssl->connecting_state == ssl_connect_2_reading
-       || connssl->connecting_state == ssl_connect_2_writing) {
-
-      curl_socket_t writefd = ssl_connect_2_writing ==
-        connssl->connecting_state?sockfd:CURL_SOCKET_BAD;
-      curl_socket_t readfd = ssl_connect_2_reading ==
-        connssl->connecting_state?sockfd:CURL_SOCKET_BAD;
-
-      what = Curl_socket_check(readfd, CURL_SOCKET_BAD, writefd,
-                               nonblocking?0:timeout_ms);
-      if(what < 0) {
-        /* fatal error */
-        failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO);
-        return CURLE_SSL_CONNECT_ERROR;
-      }
-      else if(0 == what) {
-        if(nonblocking) {
-          *done = FALSE;
-          return CURLE_OK;
-        }
-        else {
-          /* timeout */
-          failf(data, "SSL connection timeout");
-          return CURLE_OPERATION_TIMEDOUT;
-        }
-      }
-      /* socket is readable or writable */
-    }
-
-    /* Run transaction, and return to the caller if it failed or if
-     * this connection is part of a multi handle and this loop would
-     * execute again. This permits the owner of a multi handle to
-     * abort a connection attempt before step2 has completed while
-     * ensuring that a client using select() or epoll() will always
-     * have a valid fdset to wait on.
-     */
-    result = cyassl_connect_step2(conn, sockindex);
-    if(result || (nonblocking &&
-                  (ssl_connect_2 == connssl->connecting_state ||
-                   ssl_connect_2_reading == connssl->connecting_state ||
-                   ssl_connect_2_writing == connssl->connecting_state)))
-      return result;
-  } /* repeat step2 until all transactions are done. */
-
-  if(ssl_connect_3 == connssl->connecting_state) {
-    result = cyassl_connect_step3(conn, sockindex);
-    if(result)
-      return result;
-  }
-
-  if(ssl_connect_done == connssl->connecting_state) {
-    connssl->state = ssl_connection_complete;
-    conn->recv[sockindex] = cyassl_recv;
-    conn->send[sockindex] = cyassl_send;
-    *done = TRUE;
-  }
-  else
-    *done = FALSE;
-
-  /* Reset our connect state machine */
-  connssl->connecting_state = ssl_connect_1;
-
-  return CURLE_OK;
-}
-
-
-static CURLcode Curl_cyassl_connect_nonblocking(struct connectdata *conn,
-                                                int sockindex, bool *done)
-{
-  return cyassl_connect_common(conn, sockindex, TRUE, done);
-}
-
-
-static CURLcode Curl_cyassl_connect(struct connectdata *conn, int sockindex)
-{
-  CURLcode result;
-  bool done = FALSE;
-
-  result = cyassl_connect_common(conn, sockindex, FALSE, &done);
-  if(result)
-    return result;
-
-  DEBUGASSERT(done);
-
-  return CURLE_OK;
-}
-
-static CURLcode Curl_cyassl_random(struct Curl_easy *data,
-                                   unsigned char *entropy, size_t length)
-{
-  RNG rng;
-  (void)data;
-  if(InitRng(&rng))
-    return CURLE_FAILED_INIT;
-  if(length > UINT_MAX)
-    return CURLE_FAILED_INIT;
-  if(RNG_GenerateBlock(&rng, entropy, (unsigned)length))
-    return CURLE_FAILED_INIT;
-  if(FreeRng(&rng))
-    return CURLE_FAILED_INIT;
-  return CURLE_OK;
-}
-
-static CURLcode Curl_cyassl_sha256sum(const unsigned char *tmp, /* input */
-                                  size_t tmplen,
-                                  unsigned char *sha256sum /* output */,
-                                  size_t unused)
-{
-  Sha256 SHA256pw;
-  (void)unused;
-  InitSha256(&SHA256pw);
-  Sha256Update(&SHA256pw, tmp, (word32)tmplen);
-  Sha256Final(&SHA256pw, sha256sum);
-  return CURLE_OK;
-}
-
-static void *Curl_cyassl_get_internals(struct ssl_connect_data *connssl,
-                                       CURLINFO info UNUSED_PARAM)
-{
-  (void)info;
-  return BACKEND->handle;
-}
-
-const struct Curl_ssl Curl_ssl_cyassl = {
-  { CURLSSLBACKEND_WOLFSSL, "WolfSSL" }, /* info */
-
-#ifdef KEEP_PEER_CERT
-  SSLSUPP_PINNEDPUBKEY |
-#endif
-  SSLSUPP_SSL_CTX,
-
-  sizeof(struct ssl_backend_data),
-
-  Curl_cyassl_init,                /* init */
-  Curl_cyassl_cleanup,             /* cleanup */
-  Curl_cyassl_version,             /* version */
-  Curl_none_check_cxn,             /* check_cxn */
-  Curl_cyassl_shutdown,            /* shutdown */
-  Curl_cyassl_data_pending,        /* data_pending */
-  Curl_cyassl_random,              /* random */
-  Curl_none_cert_status_request,   /* cert_status_request */
-  Curl_cyassl_connect,             /* connect */
-  Curl_cyassl_connect_nonblocking, /* connect_nonblocking */
-  Curl_cyassl_get_internals,       /* get_internals */
-  Curl_cyassl_close,               /* close_one */
-  Curl_none_close_all,             /* close_all */
-  Curl_cyassl_session_free,        /* session_free */
-  Curl_none_set_engine,            /* set_engine */
-  Curl_none_set_engine_default,    /* set_engine_default */
-  Curl_none_engines_list,          /* engines_list */
-  Curl_none_false_start,           /* false_start */
-  Curl_none_md5sum,                /* md5sum */
-  Curl_cyassl_sha256sum            /* sha256sum */
-};
-
-#endif
diff --git a/Utilities/cmcurl/lib/vtls/cyassl.h b/Utilities/cmcurl/lib/vtls/cyassl.h
deleted file mode 100644
index 01e11cc..0000000
--- a/Utilities/cmcurl/lib/vtls/cyassl.h
+++ /dev/null
@@ -1,31 +0,0 @@
-#ifndef HEADER_CURL_CYASSL_H
-#define HEADER_CURL_CYASSL_H
-/***************************************************************************
- *                                  _   _ ____  _
- *  Project                     ___| | | |  _ \| |
- *                             / __| | | | |_) | |
- *                            | (__| |_| |  _ <| |___
- *                             \___|\___/|_| \_\_____|
- *
- * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * This software is licensed as described in the file COPYING, which
- * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
- *
- * You may opt to use, copy, modify, merge, publish, distribute and/or sell
- * copies of the Software, and permit persons to whom the Software is
- * furnished to do so, under the terms of the COPYING file.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- ***************************************************************************/
-#include "curl_setup.h"
-
-#ifdef USE_CYASSL
-
-extern const struct Curl_ssl Curl_ssl_cyassl;
-
-#endif /* USE_CYASSL */
-#endif /* HEADER_CURL_CYASSL_H */
diff --git a/Utilities/cmcurl/lib/vtls/gskit.c b/Utilities/cmcurl/lib/vtls/gskit.c
index b93ff5d..0538e4a 100644
--- a/Utilities/cmcurl/lib/vtls/gskit.c
+++ b/Utilities/cmcurl/lib/vtls/gskit.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -26,6 +26,8 @@
 
 #include <gskssl.h>
 #include <qsoasync.h>
+#undef HAVE_SOCKETPAIR /* because the native one isn't good enough */
+#include "socketpair.h"
 
 /* Some symbols are undefined/unsupported on OS400 versions < V7R1. */
 #ifndef GSK_SSL_EXTN_SERVERNAME_REQUEST
@@ -106,13 +108,13 @@
 #define BACKEND connssl->backend
 
 /* Supported ciphers. */
-typedef struct {
+struct gskit_cipher {
   const char *name;            /* Cipher name. */
   const char *gsktoken;        /* Corresponding token for GSKit String. */
   unsigned int versions;       /* SSL version flags. */
-}  gskit_cipher;
+};
 
-static const gskit_cipher  ciphertable[] = {
+static const struct gskit_cipher  ciphertable[] = {
   { "null-md5",         "01",
       CURL_GSKPROTO_SSLV3_MASK | CURL_GSKPROTO_TLSV10_MASK |
       CURL_GSKPROTO_TLSV11_MASK | CURL_GSKPROTO_TLSV12_MASK },
@@ -305,7 +307,7 @@
   struct Curl_easy *data = conn->data;
   const char *cipherlist = SSL_CONN_CONFIG(cipher_list);
   const char *clp;
-  const gskit_cipher *ctp;
+  const struct gskit_cipher *ctp;
   int i;
   int l;
   bool unsupported;
@@ -511,100 +513,6 @@
   BACKEND->iocport = -1;
 }
 
-/* SSL over SSL
- * Problems:
- * 1) GSKit can only perform SSL on an AF_INET or AF_INET6 stream socket. To
- *    pipe an SSL stream into another, it is therefore needed to have a pair
- *    of such communicating sockets and handle the pipelining explicitly.
- * 2) OS/400 socketpair() is only implemented for domain AF_UNIX, thus cannot
- *    be used to produce the pipeline.
- * The solution is to simulate socketpair() for AF_INET with low-level API
- *    listen(), bind() and connect().
- */
-
-static int
-inetsocketpair(int sv[2])
-{
-  int lfd;      /* Listening socket. */
-  int sfd;      /* Server socket. */
-  int cfd;      /* Client socket. */
-  int len;
-  struct sockaddr_in addr1;
-  struct sockaddr_in addr2;
-
-  /* Create listening socket on a local dynamic port. */
-  lfd = socket(AF_INET, SOCK_STREAM, 0);
-  if(lfd < 0)
-    return -1;
-  memset((char *) &addr1, 0, sizeof(addr1));
-  addr1.sin_family = AF_INET;
-  addr1.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
-  addr1.sin_port = 0;
-  if(bind(lfd, (struct sockaddr *) &addr1, sizeof(addr1)) ||
-     listen(lfd, 2) < 0) {
-    close(lfd);
-    return -1;
-  }
-
-  /* Get the allocated port. */
-  len = sizeof(addr1);
-  if(getsockname(lfd, (struct sockaddr *) &addr1, &len) < 0) {
-    close(lfd);
-    return -1;
-  }
-
-  /* Create the client socket. */
-  cfd = socket(AF_INET, SOCK_STREAM, 0);
-  if(cfd < 0) {
-    close(lfd);
-    return -1;
-  }
-
-  /* Request unblocking connection to the listening socket. */
-  curlx_nonblock(cfd, TRUE);
-  if(connect(cfd, (struct sockaddr *) &addr1, sizeof(addr1)) < 0 &&
-     errno != EINPROGRESS) {
-    close(lfd);
-    close(cfd);
-    return -1;
-  }
-
-  /* Get the client dynamic port for intrusion check below. */
-  len = sizeof(addr2);
-  if(getsockname(cfd, (struct sockaddr *) &addr2, &len) < 0) {
-    close(lfd);
-    close(cfd);
-    return -1;
-  }
-
-  /* Accept the incoming connection and get the server socket. */
-  curlx_nonblock(lfd, TRUE);
-  for(;;) {
-    len = sizeof(addr1);
-    sfd = accept(lfd, (struct sockaddr *) &addr1, &len);
-    if(sfd < 0) {
-      close(lfd);
-      close(cfd);
-      return -1;
-    }
-
-    /* Check for possible intrusion from an external process. */
-    if(addr1.sin_addr.s_addr == addr2.sin_addr.s_addr &&
-       addr1.sin_port == addr2.sin_port)
-      break;
-
-    /* Intrusion: reject incoming connection. */
-    close(sfd);
-  }
-
-  /* Done, return sockets and succeed. */
-  close(lfd);
-  curlx_nonblock(cfd, FALSE);
-  sv[0] = cfd;
-  sv[1] = sfd;
-  return 0;
-}
-
 static int pipe_ssloverssl(struct connectdata *conn, int sockindex,
                            int directions)
 {
@@ -616,7 +524,6 @@
   int m;
   int i;
   int ret = 0;
-  struct timeval tv = {0, 0};
   char buf[CURL_MAX_WRITE_SIZE];
 
   if(!connssl->use || !connproxyssl->use)
@@ -636,7 +543,7 @@
     if(n < conn->sock[sockindex])
       n = conn->sock[sockindex];
   }
-  i = select(n + 1, &fds_read, &fds_write, NULL, &tv);
+  i = Curl_select(n + 1, &fds_read, &fds_write, NULL, 0);
   if(i < 0)
     return -1;  /* Select error. */
 
@@ -855,7 +762,7 @@
 
   /* Establish a pipelining socket pair for SSL over SSL. */
   if(conn->proxy_ssl[sockindex].use) {
-    if(inetsocketpair(sockpair))
+    if(Curl_socketpair(0, 0, 0, sockpair))
       return CURLE_SSL_CONNECT_ERROR;
     BACKEND->localfd = sockpair[0];
     BACKEND->remotefd = sockpair[1];
@@ -912,7 +819,7 @@
   if(!result) {
     /* Compute the handshake timeout. Since GSKit granularity is 1 second,
        we round up the required value. */
-    long timeout = Curl_timeleft(data, NULL, TRUE);
+    timediff_t timeout = Curl_timeleft(data, NULL, TRUE);
     if(timeout < 0)
       result = CURLE_OPERATION_TIMEDOUT;
     else
@@ -1025,7 +932,7 @@
   /* Poll or wait for end of SSL asynchronous handshake. */
 
   for(;;) {
-    long timeout_ms = nonblocking? 0: Curl_timeleft(data, NULL, TRUE);
+    timediff_t timeout_ms = nonblocking? 0: Curl_timeleft(data, NULL, TRUE);
     if(timeout_ms < 0)
       timeout_ms = 0;
     stmv.tv_sec = timeout_ms / 1000;
@@ -1157,7 +1064,7 @@
 {
   struct Curl_easy *data = conn->data;
   struct ssl_connect_data *connssl = &conn->ssl[sockindex];
-  long timeout_ms;
+  timediff_t timeout_ms;
   CURLcode result = CURLE_OK;
 
   *done = connssl->state == ssl_connection_complete;
diff --git a/Utilities/cmcurl/lib/vtls/gskit.h b/Utilities/cmcurl/lib/vtls/gskit.h
index 466ee4d..b06b5e1 100644
--- a/Utilities/cmcurl/lib/vtls/gskit.h
+++ b/Utilities/cmcurl/lib/vtls/gskit.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
diff --git a/Utilities/cmcurl/lib/vtls/gtls.c b/Utilities/cmcurl/lib/vtls/gtls.c
index 8693cdc..9b4c365 100644
--- a/Utilities/cmcurl/lib/vtls/gtls.c
+++ b/Utilities/cmcurl/lib/vtls/gtls.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -72,36 +72,11 @@
 #endif
 static bool gtls_inited = FALSE;
 
-#if defined(GNUTLS_VERSION_NUMBER)
-#  if (GNUTLS_VERSION_NUMBER >= 0x020c00)
-#    undef gnutls_transport_set_lowat
-#    define gnutls_transport_set_lowat(A,B) Curl_nop_stmt
-#    define USE_GNUTLS_PRIORITY_SET_DIRECT 1
-#  endif
-#  if (GNUTLS_VERSION_NUMBER >= 0x020c03)
-#    define GNUTLS_MAPS_WINSOCK_ERRORS 1
-#  endif
-
-#  if HAVE_GNUTLS_ALPN_SET_PROTOCOLS
-#    define HAS_ALPN
-#  endif
-
-#  if HAVE_GNUTLS_OCSP_REQ_INIT
-#    define HAS_OCSP
-#  endif
-
-#  if (GNUTLS_VERSION_NUMBER >= 0x030306)
-#    define HAS_CAPATH
-#  endif
+#if !defined(GNUTLS_VERSION_NUMBER) || (GNUTLS_VERSION_NUMBER < 0x03010a)
+#error "too old GnuTLS version"
 #endif
 
-#if (GNUTLS_VERSION_NUMBER >= 0x030603)
-#define HAS_TLS13
-#endif
-
-#ifdef HAS_OCSP
 # include <gnutls/ocsp.h>
-#endif
 
 struct ssl_backend_data {
   gnutls_session_t session;
@@ -111,58 +86,10 @@
 #endif
 };
 
-#define BACKEND connssl->backend
-
-/*
- * Custom push and pull callback functions used by GNU TLS to read and write
- * to the socket.  These functions are simple wrappers to send() and recv()
- * (although here using the sread/swrite macros as defined by
- * curl_setup_once.h).
- * We use custom functions rather than the GNU TLS defaults because it allows
- * us to get specific about the fourth "flags" argument, and to use arbitrary
- * private data with gnutls_transport_set_ptr if we wish.
- *
- * When these custom push and pull callbacks fail, GNU TLS checks its own
- * session-specific error variable, and when not set also its own global
- * errno variable, in order to take appropriate action. GNU TLS does not
- * require that the transport is actually a socket. This implies that for
- * Windows builds these callbacks should ideally set the session-specific
- * error variable using function gnutls_transport_set_errno or as a last
- * resort global errno variable using gnutls_transport_set_global_errno,
- * with a transport agnostic error value. This implies that some winsock
- * error translation must take place in these callbacks.
- *
- * Paragraph above applies to GNU TLS versions older than 2.12.3, since
- * this version GNU TLS does its own internal winsock error translation
- * using system_errno() function.
- */
-
-#if defined(USE_WINSOCK) && !defined(GNUTLS_MAPS_WINSOCK_ERRORS)
-#  define gtls_EINTR  4
-#  define gtls_EIO    5
-#  define gtls_EAGAIN 11
-static int gtls_mapped_sockerrno(void)
-{
-  switch(SOCKERRNO) {
-  case WSAEWOULDBLOCK:
-    return gtls_EAGAIN;
-  case WSAEINTR:
-    return gtls_EINTR;
-  default:
-    break;
-  }
-  return gtls_EIO;
-}
-#endif
-
 static ssize_t Curl_gtls_push(void *s, const void *buf, size_t len)
 {
   curl_socket_t sock = *(curl_socket_t *)s;
   ssize_t ret = swrite(sock, buf, len);
-#if defined(USE_WINSOCK) && !defined(GNUTLS_MAPS_WINSOCK_ERRORS)
-  if(ret < 0)
-    gnutls_transport_set_global_errno(gtls_mapped_sockerrno());
-#endif
   return ret;
 }
 
@@ -170,10 +97,6 @@
 {
   curl_socket_t sock = *(curl_socket_t *)s;
   ssize_t ret = sread(sock, buf, len);
-#if defined(USE_WINSOCK) && !defined(GNUTLS_MAPS_WINSOCK_ERRORS)
-  if(ret < 0)
-    gnutls_transport_set_global_errno(gtls_mapped_sockerrno());
-#endif
   return ret;
 }
 
@@ -284,11 +207,12 @@
 {
   struct Curl_easy *data = conn->data;
   struct ssl_connect_data *connssl = &conn->ssl[sockindex];
-  gnutls_session_t session = BACKEND->session;
+  struct ssl_backend_data *backend = connssl->backend;
+  gnutls_session_t session = backend->session;
   curl_socket_t sockfd = conn->sock[sockindex];
 
   for(;;) {
-    time_t timeout_ms;
+    timediff_t timeout_ms;
     int rc;
 
     /* check allowed time left */
@@ -383,51 +307,6 @@
   return -1;
 }
 
-#ifndef USE_GNUTLS_PRIORITY_SET_DIRECT
-static CURLcode
-set_ssl_version_min_max(int *list, size_t list_size, struct connectdata *conn)
-{
-  struct Curl_easy *data = conn->data;
-  long ssl_version = SSL_CONN_CONFIG(version);
-  long ssl_version_max = SSL_CONN_CONFIG(version_max);
-  long i = ssl_version;
-  long protocol_priority_idx = 0;
-
-  switch(ssl_version_max) {
-    case CURL_SSLVERSION_MAX_NONE:
-    case CURL_SSLVERSION_MAX_DEFAULT:
-#ifdef HAS_TLS13
-      ssl_version_max = CURL_SSLVERSION_MAX_TLSv1_3;
-#endif
-      ssl_version_max = CURL_SSLVERSION_MAX_TLSv1_2;
-      break;
-  }
-
-  for(; i <= (ssl_version_max >> 16) &&
-        protocol_priority_idx < list_size; ++i) {
-    switch(i) {
-      case CURL_SSLVERSION_TLSv1_0:
-        protocol_priority[protocol_priority_idx++] = GNUTLS_TLS1_0;
-        break;
-      case CURL_SSLVERSION_TLSv1_1:
-        protocol_priority[protocol_priority_idx++] = GNUTLS_TLS1_1;
-        break;
-      case CURL_SSLVERSION_TLSv1_2:
-        protocol_priority[protocol_priority_idx++] = GNUTLS_TLS1_2;
-        break;
-      case CURL_SSLVERSION_TLSv1_3:
-#ifdef HAS_TLS13
-        protocol_priority[protocol_priority_idx++] = GNUTLS_TLS1_3;
-        break;
-#else
-        failf(data, "GnuTLS: TLS 1.3 is not yet supported");
-        return CURLE_SSL_CONNECT_ERROR;
-#endif
-    }
-  }
-  return CURLE_OK;
-}
-#else
 #define GNUTLS_CIPHERS "NORMAL:-ARCFOUR-128:-CTYPE-ALL:+CTYPE-X509"
 /* If GnuTLS was compiled without support for SRP it will error out if SRP is
    requested in the priority string, so treat it specially
@@ -445,77 +324,59 @@
     ssl_version_max = CURL_SSLVERSION_MAX_DEFAULT;
   }
   switch(ssl_version | ssl_version_max) {
-    case CURL_SSLVERSION_TLSv1_0 | CURL_SSLVERSION_MAX_TLSv1_0:
-      *prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0:-VERS-TLS-ALL:"
-                      "+VERS-TLS1.0:" GNUTLS_SRP;
-      return CURLE_OK;
-    case CURL_SSLVERSION_TLSv1_0 | CURL_SSLVERSION_MAX_TLSv1_1:
-      *prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0:-VERS-TLS-ALL:"
-                      "+VERS-TLS1.0:+VERS-TLS1.1:" GNUTLS_SRP;
-      return CURLE_OK;
-    case CURL_SSLVERSION_TLSv1_0 | CURL_SSLVERSION_MAX_TLSv1_2:
-      *prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0:-VERS-TLS-ALL:"
-                      "+VERS-TLS1.0:+VERS-TLS1.1:+VERS-TLS1.2:" GNUTLS_SRP;
-      return CURLE_OK;
-    case CURL_SSLVERSION_TLSv1_1 | CURL_SSLVERSION_MAX_TLSv1_1:
-      *prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0:-VERS-TLS-ALL:"
-                      "+VERS-TLS1.1:" GNUTLS_SRP;
-      return CURLE_OK;
-    case CURL_SSLVERSION_TLSv1_1 | CURL_SSLVERSION_MAX_TLSv1_2:
-      *prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0:-VERS-TLS-ALL:"
-                      "+VERS-TLS1.1:+VERS-TLS1.2:" GNUTLS_SRP;
-      return CURLE_OK;
-    case CURL_SSLVERSION_TLSv1_2 | CURL_SSLVERSION_MAX_TLSv1_2:
-      *prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0:-VERS-TLS-ALL:"
-                      "+VERS-TLS1.2:" GNUTLS_SRP;
-      return CURLE_OK;
-    case CURL_SSLVERSION_TLSv1_3 | CURL_SSLVERSION_MAX_TLSv1_3:
-#ifdef HAS_TLS13
-       *prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0:-VERS-TLS-ALL:"
-                       "+VERS-TLS1.3:" GNUTLS_SRP;
-      return CURLE_OK;
-#else
-       failf(data, "GnuTLS: TLS 1.3 is not yet supported");
-      return CURLE_SSL_CONNECT_ERROR;
-#endif
-    case CURL_SSLVERSION_TLSv1_0 | CURL_SSLVERSION_MAX_DEFAULT:
-      *prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0:-VERS-TLS-ALL:"
-                      "+VERS-TLS1.0:+VERS-TLS1.1:+VERS-TLS1.2:"
-#ifdef HAS_TLS13
-                      "+VERS-TLS1.3:"
-#endif
-                      GNUTLS_SRP;
-      return CURLE_OK;
-    case CURL_SSLVERSION_TLSv1_1 | CURL_SSLVERSION_MAX_DEFAULT:
-      *prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0:-VERS-TLS-ALL:"
-                      "+VERS-TLS1.1:+VERS-TLS1.2:"
-#ifdef HAS_TLS13
-                      "+VERS-TLS1.3:"
-#endif
-                      GNUTLS_SRP;
-      return CURLE_OK;
-    case CURL_SSLVERSION_TLSv1_2 | CURL_SSLVERSION_MAX_DEFAULT:
-      *prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0:-VERS-TLS-ALL:"
-                      "+VERS-TLS1.2:"
-#ifdef HAS_TLS13
-                      "+VERS-TLS1.3:"
-#endif
-                      GNUTLS_SRP;
-      return CURLE_OK;
-    case CURL_SSLVERSION_TLSv1_3 | CURL_SSLVERSION_MAX_DEFAULT:
-      *prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0:-VERS-TLS-ALL:"
-                      "+VERS-TLS1.2:"
-#ifdef HAS_TLS13
-                      "+VERS-TLS1.3:"
-#endif
-                      GNUTLS_SRP;
-      return CURLE_OK;
+  case CURL_SSLVERSION_TLSv1_0 | CURL_SSLVERSION_MAX_TLSv1_0:
+    *prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0:-VERS-TLS-ALL:"
+      "+VERS-TLS1.0";
+    return CURLE_OK;
+  case CURL_SSLVERSION_TLSv1_0 | CURL_SSLVERSION_MAX_TLSv1_1:
+    *prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0:-VERS-TLS-ALL:"
+      "+VERS-TLS1.0:+VERS-TLS1.1";
+    return CURLE_OK;
+  case CURL_SSLVERSION_TLSv1_0 | CURL_SSLVERSION_MAX_TLSv1_2:
+    *prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0:-VERS-TLS-ALL:"
+      "+VERS-TLS1.0:+VERS-TLS1.1:+VERS-TLS1.2";
+    return CURLE_OK;
+  case CURL_SSLVERSION_TLSv1_1 | CURL_SSLVERSION_MAX_TLSv1_1:
+    *prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0:-VERS-TLS-ALL:"
+      "+VERS-TLS1.1";
+    return CURLE_OK;
+  case CURL_SSLVERSION_TLSv1_1 | CURL_SSLVERSION_MAX_TLSv1_2:
+    *prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0:-VERS-TLS-ALL:"
+      "+VERS-TLS1.1:+VERS-TLS1.2";
+    return CURLE_OK;
+  case CURL_SSLVERSION_TLSv1_2 | CURL_SSLVERSION_MAX_TLSv1_2:
+    *prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0:-VERS-TLS-ALL:"
+      "+VERS-TLS1.2";
+    return CURLE_OK;
+  case CURL_SSLVERSION_TLSv1_3 | CURL_SSLVERSION_MAX_TLSv1_3:
+    *prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0:-VERS-TLS-ALL:"
+      "+VERS-TLS1.3";
+    return CURLE_OK;
+  case CURL_SSLVERSION_TLSv1_0 | CURL_SSLVERSION_MAX_DEFAULT:
+    *prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0:-VERS-TLS-ALL:"
+      "+VERS-TLS1.0:+VERS-TLS1.1:+VERS-TLS1.2"
+      ":+VERS-TLS1.3";
+    return CURLE_OK;
+  case CURL_SSLVERSION_TLSv1_1 | CURL_SSLVERSION_MAX_DEFAULT:
+    *prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0:-VERS-TLS-ALL:"
+      "+VERS-TLS1.1:+VERS-TLS1.2"
+      ":+VERS-TLS1.3";
+    return CURLE_OK;
+  case CURL_SSLVERSION_TLSv1_2 | CURL_SSLVERSION_MAX_DEFAULT:
+    *prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0:-VERS-TLS-ALL:"
+      "+VERS-TLS1.2"
+      ":+VERS-TLS1.3";
+    return CURLE_OK;
+  case CURL_SSLVERSION_TLSv1_3 | CURL_SSLVERSION_MAX_DEFAULT:
+    *prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0:-VERS-TLS-ALL:"
+      "+VERS-TLS1.2"
+      ":+VERS-TLS1.3";
+    return CURLE_OK;
   }
 
   failf(data, "GnuTLS: cannot set ssl protocol");
   return CURLE_SSL_CONNECT_ERROR;
 }
-#endif
 
 static CURLcode
 gtls_connect_step1(struct connectdata *conn,
@@ -523,6 +384,7 @@
 {
   struct Curl_easy *data = conn->data;
   struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+  struct ssl_backend_data *backend = connssl->backend;
   unsigned int init_flags;
   gnutls_session_t session;
   int rc;
@@ -535,28 +397,12 @@
 #else
   struct in_addr addr;
 #endif
-#ifndef USE_GNUTLS_PRIORITY_SET_DIRECT
-  static const int cipher_priority[] = {
-  /* These two ciphers were added to GnuTLS as late as ver. 3.0.1,
-     but this code path is only ever used for ver. < 2.12.0.
-     GNUTLS_CIPHER_AES_128_GCM,
-     GNUTLS_CIPHER_AES_256_GCM,
-  */
-    GNUTLS_CIPHER_AES_128_CBC,
-    GNUTLS_CIPHER_AES_256_CBC,
-    GNUTLS_CIPHER_CAMELLIA_128_CBC,
-    GNUTLS_CIPHER_CAMELLIA_256_CBC,
-    GNUTLS_CIPHER_3DES_CBC,
-  };
-  static const int cert_type_priority[] = { GNUTLS_CRT_X509, 0 };
-  int protocol_priority[] = { 0, 0, 0, 0 };
-#else
   const char *prioritylist;
   const char *err = NULL;
-#endif
-
   const char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name :
     conn->host.name;
+  long * const certverifyresult = SSL_IS_PROXY() ?
+    &data->set.proxy_ssl.certverifyresult : &data->set.ssl.certverifyresult;
 
   if(connssl->state == ssl_connection_complete)
     /* to make us tolerant against being called more than once for the
@@ -566,6 +412,9 @@
   if(!gtls_inited)
     Curl_gtls_init();
 
+  /* Initialize certverifyresult to OK */
+  *certverifyresult = 0;
+
   if(SSL_CONN_CONFIG(version) == CURL_SSLVERSION_SSLv2) {
     failf(data, "GnuTLS does not support SSLv2");
     return CURLE_SSL_CONNECT_ERROR;
@@ -574,7 +423,7 @@
     sni = FALSE; /* SSLv3 has no SNI */
 
   /* allocate a cred struct */
-  rc = gnutls_certificate_allocate_credentials(&BACKEND->cred);
+  rc = gnutls_certificate_allocate_credentials(&backend->cred);
   if(rc != GNUTLS_E_SUCCESS) {
     failf(data, "gnutls_cert_all_cred() failed: %s", gnutls_strerror(rc));
     return CURLE_SSL_CONNECT_ERROR;
@@ -585,14 +434,14 @@
     infof(data, "Using TLS-SRP username: %s\n", SSL_SET_OPTION(username));
 
     rc = gnutls_srp_allocate_client_credentials(
-           &BACKEND->srp_client_cred);
+           &backend->srp_client_cred);
     if(rc != GNUTLS_E_SUCCESS) {
       failf(data, "gnutls_srp_allocate_client_cred() failed: %s",
             gnutls_strerror(rc));
       return CURLE_OUT_OF_MEMORY;
     }
 
-    rc = gnutls_srp_set_client_credentials(BACKEND->srp_client_cred,
+    rc = gnutls_srp_set_client_credentials(backend->srp_client_cred,
                                            SSL_SET_OPTION(username),
                                            SSL_SET_OPTION(password));
     if(rc != GNUTLS_E_SUCCESS) {
@@ -605,52 +454,54 @@
 
   if(SSL_CONN_CONFIG(CAfile)) {
     /* set the trusted CA cert bundle file */
-    gnutls_certificate_set_verify_flags(BACKEND->cred,
+    gnutls_certificate_set_verify_flags(backend->cred,
                                         GNUTLS_VERIFY_ALLOW_X509_V1_CA_CRT);
 
-    rc = gnutls_certificate_set_x509_trust_file(BACKEND->cred,
+    rc = gnutls_certificate_set_x509_trust_file(backend->cred,
                                                 SSL_CONN_CONFIG(CAfile),
                                                 GNUTLS_X509_FMT_PEM);
     if(rc < 0) {
       infof(data, "error reading ca cert file %s (%s)\n",
             SSL_CONN_CONFIG(CAfile), gnutls_strerror(rc));
-      if(SSL_CONN_CONFIG(verifypeer))
+      if(SSL_CONN_CONFIG(verifypeer)) {
+        *certverifyresult = rc;
         return CURLE_SSL_CACERT_BADFILE;
+      }
     }
     else
       infof(data, "found %d certificates in %s\n", rc,
             SSL_CONN_CONFIG(CAfile));
   }
 
-#ifdef HAS_CAPATH
   if(SSL_CONN_CONFIG(CApath)) {
     /* set the trusted CA cert directory */
-    rc = gnutls_certificate_set_x509_trust_dir(BACKEND->cred,
+    rc = gnutls_certificate_set_x509_trust_dir(backend->cred,
                                                SSL_CONN_CONFIG(CApath),
                                                GNUTLS_X509_FMT_PEM);
     if(rc < 0) {
       infof(data, "error reading ca cert file %s (%s)\n",
             SSL_CONN_CONFIG(CApath), gnutls_strerror(rc));
-      if(SSL_CONN_CONFIG(verifypeer))
+      if(SSL_CONN_CONFIG(verifypeer)) {
+        *certverifyresult = rc;
         return CURLE_SSL_CACERT_BADFILE;
+      }
     }
     else
       infof(data, "found %d certificates in %s\n",
             rc, SSL_CONN_CONFIG(CApath));
   }
-#endif
 
 #ifdef CURL_CA_FALLBACK
   /* use system ca certificate store as fallback */
   if(SSL_CONN_CONFIG(verifypeer) &&
      !(SSL_CONN_CONFIG(CAfile) || SSL_CONN_CONFIG(CApath))) {
-    gnutls_certificate_set_x509_system_trust(BACKEND->cred);
+    gnutls_certificate_set_x509_system_trust(backend->cred);
   }
 #endif
 
   if(SSL_SET_OPTION(CRLfile)) {
     /* set the CRL list file */
-    rc = gnutls_certificate_set_x509_crl_file(BACKEND->cred,
+    rc = gnutls_certificate_set_x509_crl_file(backend->cred,
                                               SSL_SET_OPTION(CRLfile),
                                               GNUTLS_X509_FMT_PEM);
     if(rc < 0) {
@@ -666,19 +517,23 @@
   /* Initialize TLS session as a client */
   init_flags = GNUTLS_CLIENT;
 
+#if defined(GNUTLS_FORCE_CLIENT_CERT)
+  init_flags |= GNUTLS_FORCE_CLIENT_CERT;
+#endif
+
 #if defined(GNUTLS_NO_TICKETS)
   /* Disable TLS session tickets */
   init_flags |= GNUTLS_NO_TICKETS;
 #endif
 
-  rc = gnutls_init(&BACKEND->session, init_flags);
+  rc = gnutls_init(&backend->session, init_flags);
   if(rc != GNUTLS_E_SUCCESS) {
     failf(data, "gnutls_init() failed: %d", rc);
     return CURLE_SSL_CONNECT_ERROR;
   }
 
   /* convenient assign */
-  session = BACKEND->session;
+  session = backend->session;
 
   if((0 == Curl_inet_pton(AF_INET, hostname, &addr)) &&
 #ifdef ENABLE_IPV6
@@ -695,62 +550,6 @@
   if(rc != GNUTLS_E_SUCCESS)
     return CURLE_SSL_CONNECT_ERROR;
 
-#ifndef USE_GNUTLS_PRIORITY_SET_DIRECT
-  rc = gnutls_cipher_set_priority(session, cipher_priority);
-  if(rc != GNUTLS_E_SUCCESS)
-    return CURLE_SSL_CONNECT_ERROR;
-
-  /* Sets the priority on the certificate types supported by gnutls. Priority
-   is higher for types specified before others. After specifying the types
-   you want, you must append a 0. */
-  rc = gnutls_certificate_type_set_priority(session, cert_type_priority);
-  if(rc != GNUTLS_E_SUCCESS)
-    return CURLE_SSL_CONNECT_ERROR;
-
-  if(SSL_CONN_CONFIG(cipher_list) != NULL) {
-    failf(data, "can't pass a custom cipher list to older GnuTLS"
-          " versions");
-    return CURLE_SSL_CONNECT_ERROR;
-  }
-
-  switch(SSL_CONN_CONFIG(version)) {
-    case CURL_SSLVERSION_SSLv3:
-      protocol_priority[0] = GNUTLS_SSL3;
-      break;
-    case CURL_SSLVERSION_DEFAULT:
-    case CURL_SSLVERSION_TLSv1:
-      protocol_priority[0] = GNUTLS_TLS1_0;
-      protocol_priority[1] = GNUTLS_TLS1_1;
-      protocol_priority[2] = GNUTLS_TLS1_2;
-#ifdef HAS_TLS13
-      protocol_priority[3] = GNUTLS_TLS1_3;
-#endif
-      break;
-    case CURL_SSLVERSION_TLSv1_0:
-    case CURL_SSLVERSION_TLSv1_1:
-    case CURL_SSLVERSION_TLSv1_2:
-    case CURL_SSLVERSION_TLSv1_3:
-      {
-        CURLcode result = set_ssl_version_min_max(protocol_priority,
-                sizeof(protocol_priority)/sizeof(protocol_priority[0]), conn);
-        if(result != CURLE_OK)
-          return result;
-        break;
-      }
-    case CURL_SSLVERSION_SSLv2:
-      failf(data, "GnuTLS does not support SSLv2");
-      return CURLE_SSL_CONNECT_ERROR;
-    default:
-      failf(data, "Unrecognized parameter passed via CURLOPT_SSLVERSION");
-      return CURLE_SSL_CONNECT_ERROR;
-  }
-  rc = gnutls_protocol_set_priority(session, protocol_priority);
-  if(rc != GNUTLS_E_SUCCESS) {
-    failf(data, "Did you pass a valid GnuTLS cipher list?");
-    return CURLE_SSL_CONNECT_ERROR;
-  }
-
-#else
   /* Ensure +SRP comes at the *end* of all relevant strings so that it can be
    * removed if a run-time error indicates that SRP is not supported by this
    * GnuTLS version */
@@ -760,11 +559,11 @@
       break;
     case CURL_SSLVERSION_DEFAULT:
     case CURL_SSLVERSION_TLSv1:
-      prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0:"
+      prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0"
 #ifdef HAS_TLS13
-                     "+VERS-TLS1.3:"
+                     ":+VERS-TLS1.3"
 #endif
-                     GNUTLS_SRP;
+                     ;
       break;
     case CURL_SSLVERSION_TLSv1_0:
     case CURL_SSLVERSION_TLSv1_1:
@@ -783,32 +582,39 @@
       failf(data, "Unrecognized parameter passed via CURLOPT_SSLVERSION");
       return CURLE_SSL_CONNECT_ERROR;
   }
-  rc = gnutls_priority_set_direct(session, prioritylist, &err);
-  if((rc == GNUTLS_E_INVALID_REQUEST) && err) {
-    if(!strcmp(err, GNUTLS_SRP)) {
-      /* This GnuTLS was probably compiled without support for SRP.
-       * Note that fact and try again without it. */
-      int validprioritylen = curlx_uztosi(err - prioritylist);
-      char *prioritycopy = strdup(prioritylist);
-      if(!prioritycopy)
-        return CURLE_OUT_OF_MEMORY;
 
+#ifdef USE_TLS_SRP
+  /* Only add SRP to the cipher list if SRP is requested. Otherwise
+   * GnuTLS will disable TLS 1.3 support. */
+  if(SSL_SET_OPTION(authtype) == CURL_TLSAUTH_SRP) {
+    size_t len = strlen(prioritylist);
+
+    char *prioritysrp = malloc(len + sizeof(GNUTLS_SRP) + 1);
+    if(!prioritysrp)
+      return CURLE_OUT_OF_MEMORY;
+    strcpy(prioritysrp, prioritylist);
+    strcpy(prioritysrp + len, ":" GNUTLS_SRP);
+
+    rc = gnutls_priority_set_direct(session, prioritysrp, &err);
+    free(prioritysrp);
+
+    if((rc == GNUTLS_E_INVALID_REQUEST) && err) {
       infof(data, "This GnuTLS does not support SRP\n");
-      if(validprioritylen)
-        /* Remove the :+SRP */
-        prioritycopy[validprioritylen - 1] = 0;
-      rc = gnutls_priority_set_direct(session, prioritycopy, &err);
-      free(prioritycopy);
     }
   }
+  else {
+#endif
+    rc = gnutls_priority_set_direct(session, prioritylist, &err);
+#ifdef USE_TLS_SRP
+  }
+#endif
+
   if(rc != GNUTLS_E_SUCCESS) {
     failf(data, "Error %d setting GnuTLS cipher list starting with %s",
           rc, err);
     return CURLE_SSL_CONNECT_ERROR;
   }
-#endif
 
-#ifdef HAS_ALPN
   if(conn->bits.tls_enable_alpn) {
     int cur = 0;
     gnutls_datum_t protocols[2];
@@ -830,18 +636,16 @@
 
     gnutls_alpn_set_protocols(session, protocols, cur, 0);
   }
-#endif
 
   if(SSL_SET_OPTION(cert)) {
     if(SSL_SET_OPTION(key_passwd)) {
-#if HAVE_GNUTLS_CERTIFICATE_SET_X509_KEY_FILE2
       const unsigned int supported_key_encryption_algorithms =
         GNUTLS_PKCS_USE_PKCS12_3DES | GNUTLS_PKCS_USE_PKCS12_ARCFOUR |
         GNUTLS_PKCS_USE_PKCS12_RC2_40 | GNUTLS_PKCS_USE_PBES2_3DES |
         GNUTLS_PKCS_USE_PBES2_AES_128 | GNUTLS_PKCS_USE_PBES2_AES_192 |
         GNUTLS_PKCS_USE_PBES2_AES_256;
       rc = gnutls_certificate_set_x509_key_file2(
-           BACKEND->cred,
+           backend->cred,
            SSL_SET_OPTION(cert),
            SSL_SET_OPTION(key) ?
            SSL_SET_OPTION(key) : SSL_SET_OPTION(cert),
@@ -854,14 +658,10 @@
               gnutls_strerror(rc));
         return CURLE_SSL_CONNECT_ERROR;
       }
-#else
-      failf(data, "gnutls lacks support for encrypted key files");
-      return CURLE_SSL_CONNECT_ERROR;
-#endif
     }
     else {
       if(gnutls_certificate_set_x509_key_file(
-           BACKEND->cred,
+           backend->cred,
            SSL_SET_OPTION(cert),
            SSL_SET_OPTION(key) ?
            SSL_SET_OPTION(key) : SSL_SET_OPTION(cert),
@@ -877,7 +677,7 @@
   /* put the credentials to the current session */
   if(SSL_SET_OPTION(authtype) == CURL_TLSAUTH_SRP) {
     rc = gnutls_credentials_set(session, GNUTLS_CRD_SRP,
-                                BACKEND->srp_client_cred);
+                                backend->srp_client_cred);
     if(rc != GNUTLS_E_SUCCESS) {
       failf(data, "gnutls_credentials_set() failed: %s", gnutls_strerror(rc));
       return CURLE_SSL_CONNECT_ERROR;
@@ -887,7 +687,7 @@
 #endif
   {
     rc = gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE,
-                                BACKEND->cred);
+                                backend->cred);
     if(rc != GNUTLS_E_SUCCESS) {
       failf(data, "gnutls_credentials_set() failed: %s", gnutls_strerror(rc));
       return CURLE_SSL_CONNECT_ERROR;
@@ -913,10 +713,6 @@
   gnutls_transport_set_push_function(session, gnutls_transport_push);
   gnutls_transport_set_pull_function(session, gnutls_transport_pull);
 
-  /* lowat must be set to zero when using custom push and pull functions. */
-  gnutls_transport_set_lowat(session, 0);
-
-#ifdef HAS_OCSP
   if(SSL_CONN_CONFIG(verifystatus)) {
     rc = gnutls_ocsp_status_request_enable_client(session, NULL, 0, NULL);
     if(rc != GNUTLS_E_SUCCESS) {
@@ -924,7 +720,6 @@
       return CURLE_SSL_CONNECT_ERROR;
     }
   }
-#endif
 
   /* This might be a reconnect, so we check for a session ID in the cache
      to speed up things */
@@ -1016,17 +811,17 @@
   unsigned int verify_status = 0;
   gnutls_x509_crt_t x509_cert, x509_issuer;
   gnutls_datum_t issuerp;
-  char certbuf[256] = ""; /* big enough? */
+  gnutls_datum_t certfields;
+  char certname[65] = ""; /* limited to 64 chars by ASN.1 */
   size_t size;
   time_t certclock;
   const char *ptr;
   struct Curl_easy *data = conn->data;
   struct ssl_connect_data *connssl = &conn->ssl[sockindex];
-  gnutls_session_t session = BACKEND->session;
+  struct ssl_backend_data *backend = connssl->backend;
+  gnutls_session_t session = backend->session;
   int rc;
-#ifdef HAS_ALPN
   gnutls_datum_t proto;
-#endif
   CURLcode result = CURLE_OK;
 #ifndef CURL_DISABLE_VERBOSE_STRINGS
   unsigned int algo;
@@ -1035,6 +830,8 @@
 #endif
   const char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name :
     conn->host.name;
+  long * const certverifyresult = SSL_IS_PROXY() ?
+    &data->set.proxy_ssl.certverifyresult : &data->set.ssl.certverifyresult;
 
   /* the name of the cipher suite used, e.g. ECDHE_RSA_AES_256_GCM_SHA384. */
   ptr = gnutls_cipher_suite_get_name(gnutls_kx_get(session),
@@ -1066,6 +863,7 @@
       else {
 #endif
         failf(data, "failed to get server cert");
+        *certverifyresult = GNUTLS_E_NO_CERTIFICATE_FOUND;
         return CURLE_PEER_FAILED_VERIFICATION;
 #ifdef USE_TLS_SRP
       }
@@ -1102,9 +900,12 @@
     rc = gnutls_certificate_verify_peers2(session, &verify_status);
     if(rc < 0) {
       failf(data, "server cert verify failed: %d", rc);
+      *certverifyresult = rc;
       return CURLE_SSL_CONNECT_ERROR;
     }
 
+    *certverifyresult = verify_status;
+
     /* verify_status is a bitmask of gnutls_certificate_status bits */
     if(verify_status & GNUTLS_CERT_INVALID) {
       if(SSL_CONN_CONFIG(verifypeer)) {
@@ -1123,7 +924,6 @@
   else
     infof(data, "\t server certificate verification SKIPPED\n");
 
-#ifdef HAS_OCSP
   if(SSL_CONN_CONFIG(verifystatus)) {
     if(gnutls_ocsp_status_request_is_checked(session, 0) == 0) {
       gnutls_datum_t status_request;
@@ -1226,7 +1026,6 @@
   }
   else
     infof(data, "\t server certificate status verification SKIPPED\n");
-#endif
 
   /* initialize an X.509 certificate structure. */
   gnutls_x509_crt_init(&x509_cert);
@@ -1253,11 +1052,11 @@
           SSL_SET_OPTION(issuercert)?SSL_SET_OPTION(issuercert):"none");
   }
 
-  size = sizeof(certbuf);
+  size = sizeof(certname);
   rc = gnutls_x509_crt_get_dn_by_oid(x509_cert, GNUTLS_OID_X520_COMMON_NAME,
                                      0, /* the first and only one */
                                      FALSE,
-                                     certbuf,
+                                     certname,
                                      &size);
   if(rc) {
     infof(data, "error fetching CN from cert:%s\n",
@@ -1318,16 +1117,16 @@
 
     if(SSL_CONN_CONFIG(verifyhost)) {
       failf(data, "SSL: certificate subject name (%s) does not match "
-            "target host name '%s'", certbuf, dispname);
+            "target host name '%s'", certname, dispname);
       gnutls_x509_crt_deinit(x509_cert);
       return CURLE_PEER_FAILED_VERIFICATION;
     }
     else
       infof(data, "\t common name: %s (does not match '%s')\n",
-            certbuf, dispname);
+            certname, dispname);
   }
   else
-    infof(data, "\t common name: %s (matched)\n", certbuf);
+    infof(data, "\t common name: %s (matched)\n", certname);
 
   /* Check for time-based validity */
   certclock = gnutls_x509_crt_get_expiration_time(x509_cert);
@@ -1335,6 +1134,7 @@
   if(certclock == (time_t)-1) {
     if(SSL_CONN_CONFIG(verifypeer)) {
       failf(data, "server cert expiration date verify failed");
+      *certverifyresult = GNUTLS_CERT_EXPIRED;
       gnutls_x509_crt_deinit(x509_cert);
       return CURLE_SSL_CONNECT_ERROR;
     }
@@ -1345,6 +1145,7 @@
     if(certclock < time(NULL)) {
       if(SSL_CONN_CONFIG(verifypeer)) {
         failf(data, "server certificate expiration date has passed.");
+        *certverifyresult = GNUTLS_CERT_EXPIRED;
         gnutls_x509_crt_deinit(x509_cert);
         return CURLE_PEER_FAILED_VERIFICATION;
       }
@@ -1360,6 +1161,7 @@
   if(certclock == (time_t)-1) {
     if(SSL_CONN_CONFIG(verifypeer)) {
       failf(data, "server cert activation date verify failed");
+      *certverifyresult = GNUTLS_CERT_NOT_ACTIVATED;
       gnutls_x509_crt_deinit(x509_cert);
       return CURLE_SSL_CONNECT_ERROR;
     }
@@ -1370,6 +1172,7 @@
     if(certclock > time(NULL)) {
       if(SSL_CONN_CONFIG(verifypeer)) {
         failf(data, "server certificate not activated yet.");
+        *certverifyresult = GNUTLS_CERT_NOT_ACTIVATED;
         gnutls_x509_crt_deinit(x509_cert);
         return CURLE_PEER_FAILED_VERIFICATION;
       }
@@ -1412,9 +1215,10 @@
         gnutls_x509_crt_get_version(x509_cert));
 
 
-  size = sizeof(certbuf);
-  gnutls_x509_crt_get_dn(x509_cert, certbuf, &size);
-  infof(data, "\t subject: %s\n", certbuf);
+  rc = gnutls_x509_crt_get_dn2(x509_cert, &certfields);
+  if(rc != 0)
+    return CURLE_OUT_OF_MEMORY;
+  infof(data, "\t subject: %s\n", certfields.data);
 
   certclock = gnutls_x509_crt_get_activation_time(x509_cert);
   showtime(data, "start date", certclock);
@@ -1422,14 +1226,14 @@
   certclock = gnutls_x509_crt_get_expiration_time(x509_cert);
   showtime(data, "expire date", certclock);
 
-  size = sizeof(certbuf);
-  gnutls_x509_crt_get_issuer_dn(x509_cert, certbuf, &size);
-  infof(data, "\t issuer: %s\n", certbuf);
+  rc = gnutls_x509_crt_get_issuer_dn2(x509_cert, &certfields);
+  if(rc != 0)
+    return CURLE_OUT_OF_MEMORY;
+  infof(data, "\t issuer: %s\n", certfields.data);
 #endif
 
   gnutls_x509_crt_deinit(x509_cert);
 
-#ifdef HAS_ALPN
   if(conn->bits.tls_enable_alpn) {
     rc = gnutls_alpn_get_selected_protocol(session, &proto);
     if(rc == 0) {
@@ -1455,7 +1259,6 @@
     Curl_multiuse_state(conn, conn->negnpn == CURL_HTTP_VERSION_2 ?
                         BUNDLE_MULTIPLEX : BUNDLE_NO_MULTIUSE);
   }
-#endif
 
   conn->ssl[sockindex].state = ssl_connection_complete;
   conn->recv[sockindex] = gtls_recv;
@@ -1573,13 +1376,14 @@
 {
   const struct ssl_connect_data *connssl = &conn->ssl[connindex];
   bool res = FALSE;
-  if(BACKEND->session &&
-     0 != gnutls_record_check_pending(BACKEND->session))
+  struct ssl_backend_data *backend = connssl->backend;
+  if(backend->session &&
+     0 != gnutls_record_check_pending(backend->session))
     res = TRUE;
 
   connssl = &conn->proxy_ssl[connindex];
-  if(BACKEND->session &&
-     0 != gnutls_record_check_pending(BACKEND->session))
+  if(backend->session &&
+     0 != gnutls_record_check_pending(backend->session))
     res = TRUE;
 
   return res;
@@ -1592,7 +1396,8 @@
                          CURLcode *curlcode)
 {
   struct ssl_connect_data *connssl = &conn->ssl[sockindex];
-  ssize_t rc = gnutls_record_send(BACKEND->session, mem, len);
+  struct ssl_backend_data *backend = connssl->backend;
+  ssize_t rc = gnutls_record_send(backend->session, mem, len);
 
   if(rc < 0) {
     *curlcode = (rc == GNUTLS_E_AGAIN)
@@ -1607,19 +1412,20 @@
 
 static void close_one(struct ssl_connect_data *connssl)
 {
-  if(BACKEND->session) {
-    gnutls_bye(BACKEND->session, GNUTLS_SHUT_RDWR);
-    gnutls_deinit(BACKEND->session);
-    BACKEND->session = NULL;
+  struct ssl_backend_data *backend = connssl->backend;
+  if(backend->session) {
+    gnutls_bye(backend->session, GNUTLS_SHUT_WR);
+    gnutls_deinit(backend->session);
+    backend->session = NULL;
   }
-  if(BACKEND->cred) {
-    gnutls_certificate_free_credentials(BACKEND->cred);
-    BACKEND->cred = NULL;
+  if(backend->cred) {
+    gnutls_certificate_free_credentials(backend->cred);
+    backend->cred = NULL;
   }
 #ifdef USE_TLS_SRP
-  if(BACKEND->srp_client_cred) {
-    gnutls_srp_free_client_credentials(BACKEND->srp_client_cred);
-    BACKEND->srp_client_cred = NULL;
+  if(backend->srp_client_cred) {
+    gnutls_srp_free_client_credentials(backend->srp_client_cred);
+    backend->srp_client_cred = NULL;
   }
 #endif
 }
@@ -1637,6 +1443,7 @@
 static int Curl_gtls_shutdown(struct connectdata *conn, int sockindex)
 {
   struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+  struct ssl_backend_data *backend = connssl->backend;
   int retval = 0;
   struct Curl_easy *data = conn->data;
 
@@ -1647,10 +1454,10 @@
      we do not send one. Let's hope other servers do the same... */
 
   if(data->set.ftp_ccc == CURLFTPSSL_CCC_ACTIVE)
-      gnutls_bye(BACKEND->session, GNUTLS_SHUT_WR);
+    gnutls_bye(backend->session, GNUTLS_SHUT_WR);
 #endif
 
-  if(BACKEND->session) {
+  if(backend->session) {
     ssize_t result;
     bool done = FALSE;
     char buf[120];
@@ -1661,7 +1468,7 @@
       if(what > 0) {
         /* Something to read, let's do it and hope that it is the close
            notify alert from the server */
-        result = gnutls_record_recv(BACKEND->session,
+        result = gnutls_record_recv(backend->session,
                                     buf, sizeof(buf));
         switch(result) {
         case 0:
@@ -1691,18 +1498,18 @@
         done = TRUE;
       }
     }
-    gnutls_deinit(BACKEND->session);
+    gnutls_deinit(backend->session);
   }
-  gnutls_certificate_free_credentials(BACKEND->cred);
+  gnutls_certificate_free_credentials(backend->cred);
 
 #ifdef USE_TLS_SRP
   if(SSL_SET_OPTION(authtype) == CURL_TLSAUTH_SRP
      && SSL_SET_OPTION(username) != NULL)
-    gnutls_srp_free_client_credentials(BACKEND->srp_client_cred);
+    gnutls_srp_free_client_credentials(backend->srp_client_cred);
 #endif
 
-  BACKEND->cred = NULL;
-  BACKEND->session = NULL;
+  backend->cred = NULL;
+  backend->session = NULL;
 
   return retval;
 }
@@ -1714,9 +1521,10 @@
                          CURLcode *curlcode)
 {
   struct ssl_connect_data *connssl = &conn->ssl[num];
+  struct ssl_backend_data *backend = connssl->backend;
   ssize_t ret;
 
-  ret = gnutls_record_recv(BACKEND->session, buf, buffersize);
+  ret = gnutls_record_recv(backend->session, buf, buffersize);
   if((ret == GNUTLS_E_AGAIN) || (ret == GNUTLS_E_INTERRUPTED)) {
     *curlcode = CURLE_AGAIN;
     return -1;
@@ -1832,18 +1640,15 @@
 
 static bool Curl_gtls_cert_status_request(void)
 {
-#ifdef HAS_OCSP
   return TRUE;
-#else
-  return FALSE;
-#endif
 }
 
 static void *Curl_gtls_get_internals(struct ssl_connect_data *connssl,
                                      CURLINFO info UNUSED_PARAM)
 {
+  struct ssl_backend_data *backend = connssl->backend;
   (void)info;
-  return BACKEND->session;
+  return backend->session;
 }
 
 const struct Curl_ssl Curl_ssl_gnutls = {
diff --git a/Utilities/cmcurl/lib/vtls/keylog.c b/Utilities/cmcurl/lib/vtls/keylog.c
new file mode 100644
index 0000000..70d22ec
--- /dev/null
+++ b/Utilities/cmcurl/lib/vtls/keylog.c
@@ -0,0 +1,156 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include "curl_setup.h"
+
+#include "keylog.h"
+
+/* The last #include files should be: */
+#include "curl_memory.h"
+#include "memdebug.h"
+
+#define KEYLOG_LABEL_MAXLEN (sizeof("CLIENT_HANDSHAKE_TRAFFIC_SECRET") - 1)
+
+#define CLIENT_RANDOM_SIZE  32
+
+/*
+ * The master secret in TLS 1.2 and before is always 48 bytes. In TLS 1.3, the
+ * secret size depends on the cipher suite's hash function which is 32 bytes
+ * for SHA-256 and 48 bytes for SHA-384.
+ */
+#define SECRET_MAXLEN       48
+
+
+/* The fp for the open SSLKEYLOGFILE, or NULL if not open */
+static FILE *keylog_file_fp;
+
+void
+Curl_tls_keylog_open(void)
+{
+  char *keylog_file_name;
+
+  if(!keylog_file_fp) {
+    keylog_file_name = curl_getenv("SSLKEYLOGFILE");
+    if(keylog_file_name) {
+      keylog_file_fp = fopen(keylog_file_name, FOPEN_APPENDTEXT);
+      if(keylog_file_fp) {
+#ifdef WIN32
+        if(setvbuf(keylog_file_fp, NULL, _IONBF, 0))
+#else
+        if(setvbuf(keylog_file_fp, NULL, _IOLBF, 4096))
+#endif
+        {
+          fclose(keylog_file_fp);
+          keylog_file_fp = NULL;
+        }
+      }
+      Curl_safefree(keylog_file_name);
+    }
+  }
+}
+
+void
+Curl_tls_keylog_close(void)
+{
+  if(keylog_file_fp) {
+    fclose(keylog_file_fp);
+    keylog_file_fp = NULL;
+  }
+}
+
+bool
+Curl_tls_keylog_enabled(void)
+{
+  return keylog_file_fp != NULL;
+}
+
+bool
+Curl_tls_keylog_write_line(const char *line)
+{
+  /* The current maximum valid keylog line length LF and NUL is 195. */
+  size_t linelen;
+  char buf[256];
+
+  if(!keylog_file_fp || !line) {
+    return false;
+  }
+
+  linelen = strlen(line);
+  if(linelen == 0 || linelen > sizeof(buf) - 2) {
+    /* Empty line or too big to fit in a LF and NUL. */
+    return false;
+  }
+
+  memcpy(buf, line, linelen);
+  if(line[linelen - 1] != '\n') {
+    buf[linelen++] = '\n';
+  }
+  buf[linelen] = '\0';
+
+  /* Using fputs here instead of fprintf since libcurl's fprintf replacement
+     may not be thread-safe. */
+  fputs(buf, keylog_file_fp);
+  return true;
+}
+
+bool
+Curl_tls_keylog_write(const char *label,
+                      const unsigned char client_random[CLIENT_RANDOM_SIZE],
+                      const unsigned char *secret, size_t secretlen)
+{
+  const char *hex = "0123456789ABCDEF";
+  size_t pos, i;
+  char line[KEYLOG_LABEL_MAXLEN + 1 + 2 * CLIENT_RANDOM_SIZE + 1 +
+            2 * SECRET_MAXLEN + 1 + 1];
+
+  if(!keylog_file_fp) {
+    return false;
+  }
+
+  pos = strlen(label);
+  if(pos > KEYLOG_LABEL_MAXLEN || !secretlen || secretlen > SECRET_MAXLEN) {
+    /* Should never happen - sanity check anyway. */
+    return false;
+  }
+
+  memcpy(line, label, pos);
+  line[pos++] = ' ';
+
+  /* Client Random */
+  for(i = 0; i < CLIENT_RANDOM_SIZE; i++) {
+    line[pos++] = hex[client_random[i] >> 4];
+    line[pos++] = hex[client_random[i] & 0xF];
+  }
+  line[pos++] = ' ';
+
+  /* Secret */
+  for(i = 0; i < secretlen; i++) {
+    line[pos++] = hex[secret[i] >> 4];
+    line[pos++] = hex[secret[i] & 0xF];
+  }
+  line[pos++] = '\n';
+  line[pos] = '\0';
+
+  /* Using fputs here instead of fprintf since libcurl's fprintf replacement
+     may not be thread-safe. */
+  fputs(line, keylog_file_fp);
+  return true;
+}
diff --git a/Utilities/cmcurl/lib/vtls/keylog.h b/Utilities/cmcurl/lib/vtls/keylog.h
new file mode 100644
index 0000000..c6b99db
--- /dev/null
+++ b/Utilities/cmcurl/lib/vtls/keylog.h
@@ -0,0 +1,56 @@
+#ifndef HEADER_CURL_KEYLOG_H
+#define HEADER_CURL_KEYLOG_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include "curl_setup.h"
+
+/*
+ * Opens the TLS key log file if requested by the user. The SSLKEYLOGFILE
+ * environment variable specifies the output file.
+ */
+void Curl_tls_keylog_open(void);
+
+/*
+ * Closes the TLS key log file if not already.
+ */
+void Curl_tls_keylog_close(void);
+
+/*
+ * Returns true if the user successfully enabled the TLS key log file.
+ */
+bool Curl_tls_keylog_enabled(void);
+
+/*
+ * Appends a key log file entry.
+ * Returns true iff the key log file is open and a valid entry was provided.
+ */
+bool Curl_tls_keylog_write(const char *label,
+                           const unsigned char client_random[32],
+                           const unsigned char *secret, size_t secretlen);
+
+/*
+ * Appends a line to the key log file, ensure it is terminated by a LF.
+ * Returns true iff the key log file is open and a valid line was provided.
+ */
+bool Curl_tls_keylog_write_line(const char *line);
+
+#endif /* HEADER_CURL_KEYLOG_H */
diff --git a/Utilities/cmcurl/lib/vtls/mbedtls.c b/Utilities/cmcurl/lib/vtls/mbedtls.c
index 63d1f4c..545f824 100644
--- a/Utilities/cmcurl/lib/vtls/mbedtls.c
+++ b/Utilities/cmcurl/lib/vtls/mbedtls.c
@@ -6,7 +6,7 @@
  *                             \___|\___/|_| \_\_____|
  *
  * Copyright (C) 2010 - 2011, Hoi-Ho Chan, <hoiho.chan@gmail.com>
- * Copyright (C) 2012 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 2012 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -55,7 +55,7 @@
 #include "connect.h" /* for the connect timeout */
 #include "select.h"
 #include "multiif.h"
-#include "polarssl_threadlock.h"
+#include "mbedtls_threadlock.h"
 
 /* The last 3 #include files should be in this order */
 #include "curl_printf.h"
@@ -75,8 +75,6 @@
   const char *protocols[3];
 };
 
-#define BACKEND connssl->backend
-
 /* apply threading? */
 #if defined(USE_THREADS_POSIX) || defined(USE_THREADS_WIN32)
 #define THREADING_SUPPORT
@@ -91,12 +89,12 @@
 static void entropy_init_mutex(mbedtls_entropy_context *ctx)
 {
   /* lock 0 = entropy_init_mutex() */
-  Curl_polarsslthreadlock_lock_function(0);
+  Curl_mbedtlsthreadlock_lock_function(0);
   if(entropy_init_initialized == 0) {
     mbedtls_entropy_init(ctx);
     entropy_init_initialized = 1;
   }
-  Curl_polarsslthreadlock_unlock_function(0);
+  Curl_mbedtlsthreadlock_unlock_function(0);
 }
 /* end of entropy_init_mutex() */
 
@@ -105,9 +103,9 @@
 {
   int ret;
   /* lock 1 = entropy_func_mutex() */
-  Curl_polarsslthreadlock_lock_function(1);
+  Curl_mbedtlsthreadlock_lock_function(1);
   ret = mbedtls_entropy_func(data, output, len);
-  Curl_polarsslthreadlock_unlock_function(1);
+  Curl_mbedtlsthreadlock_unlock_function(1);
 
   return ret;
 }
@@ -196,6 +194,7 @@
 {
   struct Curl_easy *data = conn->data;
   struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+  struct ssl_backend_data *backend = connssl->backend;
   int mbedtls_ver_min = MBEDTLS_SSL_MINOR_VERSION_1;
   int mbedtls_ver_max = MBEDTLS_SSL_MINOR_VERSION_1;
   long ssl_version = SSL_CONN_CONFIG(version);
@@ -227,9 +226,9 @@
     return result;
   }
 
-  mbedtls_ssl_conf_min_version(&BACKEND->config, MBEDTLS_SSL_MAJOR_VERSION_3,
+  mbedtls_ssl_conf_min_version(&backend->config, MBEDTLS_SSL_MAJOR_VERSION_3,
                                mbedtls_ver_min);
-  mbedtls_ssl_conf_max_version(&BACKEND->config, MBEDTLS_SSL_MAJOR_VERSION_3,
+  mbedtls_ssl_conf_max_version(&backend->config, MBEDTLS_SSL_MAJOR_VERSION_3,
                                mbedtls_ver_max);
 
   return result;
@@ -240,15 +239,21 @@
                    int sockindex)
 {
   struct Curl_easy *data = conn->data;
-  struct ssl_connect_data* connssl = &conn->ssl[sockindex];
+  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+  struct ssl_backend_data *backend = connssl->backend;
   const char * const ssl_cafile = SSL_CONN_CONFIG(CAfile);
   const bool verifypeer = SSL_CONN_CONFIG(verifypeer);
   const char * const ssl_capath = SSL_CONN_CONFIG(CApath);
   char * const ssl_cert = SSL_SET_OPTION(cert);
   const char * const ssl_crlfile = SSL_SET_OPTION(CRLfile);
+#ifndef CURL_DISABLE_PROXY
   const char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name :
     conn->host.name;
   const long int port = SSL_IS_PROXY() ? conn->port : conn->remote_port;
+#else
+  const char * const hostname = conn->host.name;
+  const long int port = conn->remote_port;
+#endif
   int ret = -1;
   char errorbuf[128];
   errorbuf[0] = 0;
@@ -261,9 +266,9 @@
 
 #ifdef THREADING_SUPPORT
   entropy_init_mutex(&ts_entropy);
-  mbedtls_ctr_drbg_init(&BACKEND->ctr_drbg);
+  mbedtls_ctr_drbg_init(&backend->ctr_drbg);
 
-  ret = mbedtls_ctr_drbg_seed(&BACKEND->ctr_drbg, entropy_func_mutex,
+  ret = mbedtls_ctr_drbg_seed(&backend->ctr_drbg, entropy_func_mutex,
                               &ts_entropy, NULL, 0);
   if(ret) {
 #ifdef MBEDTLS_ERROR_C
@@ -273,11 +278,11 @@
           -ret, errorbuf);
   }
 #else
-  mbedtls_entropy_init(&BACKEND->entropy);
-  mbedtls_ctr_drbg_init(&BACKEND->ctr_drbg);
+  mbedtls_entropy_init(&backend->entropy);
+  mbedtls_ctr_drbg_init(&backend->ctr_drbg);
 
-  ret = mbedtls_ctr_drbg_seed(&BACKEND->ctr_drbg, mbedtls_entropy_func,
-                              &BACKEND->entropy, NULL, 0);
+  ret = mbedtls_ctr_drbg_seed(&backend->ctr_drbg, mbedtls_entropy_func,
+                              &backend->entropy, NULL, 0);
   if(ret) {
 #ifdef MBEDTLS_ERROR_C
     mbedtls_strerror(ret, errorbuf, sizeof(errorbuf));
@@ -288,10 +293,10 @@
 #endif /* THREADING_SUPPORT */
 
   /* Load the trusted CA */
-  mbedtls_x509_crt_init(&BACKEND->cacert);
+  mbedtls_x509_crt_init(&backend->cacert);
 
   if(ssl_cafile) {
-    ret = mbedtls_x509_crt_parse_file(&BACKEND->cacert, ssl_cafile);
+    ret = mbedtls_x509_crt_parse_file(&backend->cacert, ssl_cafile);
 
     if(ret<0) {
 #ifdef MBEDTLS_ERROR_C
@@ -306,7 +311,7 @@
   }
 
   if(ssl_capath) {
-    ret = mbedtls_x509_crt_parse_path(&BACKEND->cacert, ssl_capath);
+    ret = mbedtls_x509_crt_parse_path(&backend->cacert, ssl_capath);
 
     if(ret<0) {
 #ifdef MBEDTLS_ERROR_C
@@ -321,10 +326,10 @@
   }
 
   /* Load the client certificate */
-  mbedtls_x509_crt_init(&BACKEND->clicert);
+  mbedtls_x509_crt_init(&backend->clicert);
 
   if(ssl_cert) {
-    ret = mbedtls_x509_crt_parse_file(&BACKEND->clicert, ssl_cert);
+    ret = mbedtls_x509_crt_parse_file(&backend->clicert, ssl_cert);
 
     if(ret) {
 #ifdef MBEDTLS_ERROR_C
@@ -338,13 +343,13 @@
   }
 
   /* Load the client private key */
-  mbedtls_pk_init(&BACKEND->pk);
+  mbedtls_pk_init(&backend->pk);
 
   if(SSL_SET_OPTION(key)) {
-    ret = mbedtls_pk_parse_keyfile(&BACKEND->pk, SSL_SET_OPTION(key),
+    ret = mbedtls_pk_parse_keyfile(&backend->pk, SSL_SET_OPTION(key),
                                    SSL_SET_OPTION(key_passwd));
-    if(ret == 0 && !(mbedtls_pk_can_do(&BACKEND->pk, MBEDTLS_PK_RSA) ||
-                     mbedtls_pk_can_do(&BACKEND->pk, MBEDTLS_PK_ECKEY)))
+    if(ret == 0 && !(mbedtls_pk_can_do(&backend->pk, MBEDTLS_PK_RSA) ||
+                     mbedtls_pk_can_do(&backend->pk, MBEDTLS_PK_ECKEY)))
       ret = MBEDTLS_ERR_PK_TYPE_MISMATCH;
 
     if(ret) {
@@ -359,10 +364,10 @@
   }
 
   /* Load the CRL */
-  mbedtls_x509_crl_init(&BACKEND->crl);
+  mbedtls_x509_crl_init(&backend->crl);
 
   if(ssl_crlfile) {
-    ret = mbedtls_x509_crl_parse_file(&BACKEND->crl, ssl_crlfile);
+    ret = mbedtls_x509_crl_parse_file(&backend->crl, ssl_crlfile);
 
     if(ret) {
 #ifdef MBEDTLS_ERROR_C
@@ -377,14 +382,14 @@
 
   infof(data, "mbedTLS: Connecting to %s:%ld\n", hostname, port);
 
-  mbedtls_ssl_config_init(&BACKEND->config);
+  mbedtls_ssl_config_init(&backend->config);
 
-  mbedtls_ssl_init(&BACKEND->ssl);
-  if(mbedtls_ssl_setup(&BACKEND->ssl, &BACKEND->config)) {
+  mbedtls_ssl_init(&backend->ssl);
+  if(mbedtls_ssl_setup(&backend->ssl, &backend->config)) {
     failf(data, "mbedTLS: ssl_init failed");
     return CURLE_SSL_CONNECT_ERROR;
   }
-  ret = mbedtls_ssl_config_defaults(&BACKEND->config,
+  ret = mbedtls_ssl_config_defaults(&backend->config,
                                     MBEDTLS_SSL_IS_CLIENT,
                                     MBEDTLS_SSL_TRANSPORT_STREAM,
                                     MBEDTLS_SSL_PRESET_DEFAULT);
@@ -394,20 +399,20 @@
   }
 
   /* new profile with RSA min key len = 1024 ... */
-  mbedtls_ssl_conf_cert_profile(&BACKEND->config,
+  mbedtls_ssl_conf_cert_profile(&backend->config,
                                 &mbedtls_x509_crt_profile_fr);
 
   switch(SSL_CONN_CONFIG(version)) {
   case CURL_SSLVERSION_DEFAULT:
   case CURL_SSLVERSION_TLSv1:
-    mbedtls_ssl_conf_min_version(&BACKEND->config, MBEDTLS_SSL_MAJOR_VERSION_3,
+    mbedtls_ssl_conf_min_version(&backend->config, MBEDTLS_SSL_MAJOR_VERSION_3,
                                  MBEDTLS_SSL_MINOR_VERSION_1);
     infof(data, "mbedTLS: Set min SSL version to TLS 1.0\n");
     break;
   case CURL_SSLVERSION_SSLv3:
-    mbedtls_ssl_conf_min_version(&BACKEND->config, MBEDTLS_SSL_MAJOR_VERSION_3,
+    mbedtls_ssl_conf_min_version(&backend->config, MBEDTLS_SSL_MAJOR_VERSION_3,
                                  MBEDTLS_SSL_MINOR_VERSION_0);
-    mbedtls_ssl_conf_max_version(&BACKEND->config, MBEDTLS_SSL_MAJOR_VERSION_3,
+    mbedtls_ssl_conf_max_version(&backend->config, MBEDTLS_SSL_MAJOR_VERSION_3,
                                  MBEDTLS_SSL_MINOR_VERSION_0);
     infof(data, "mbedTLS: Set SSL version to SSLv3\n");
     break;
@@ -426,25 +431,25 @@
     return CURLE_SSL_CONNECT_ERROR;
   }
 
-  mbedtls_ssl_conf_authmode(&BACKEND->config, MBEDTLS_SSL_VERIFY_OPTIONAL);
+  mbedtls_ssl_conf_authmode(&backend->config, MBEDTLS_SSL_VERIFY_OPTIONAL);
 
-  mbedtls_ssl_conf_rng(&BACKEND->config, mbedtls_ctr_drbg_random,
-                       &BACKEND->ctr_drbg);
-  mbedtls_ssl_set_bio(&BACKEND->ssl, &conn->sock[sockindex],
+  mbedtls_ssl_conf_rng(&backend->config, mbedtls_ctr_drbg_random,
+                       &backend->ctr_drbg);
+  mbedtls_ssl_set_bio(&backend->ssl, &conn->sock[sockindex],
                       mbedtls_net_send,
                       mbedtls_net_recv,
                       NULL /*  rev_timeout() */);
 
-  mbedtls_ssl_conf_ciphersuites(&BACKEND->config,
+  mbedtls_ssl_conf_ciphersuites(&backend->config,
                                 mbedtls_ssl_list_ciphersuites());
 
 #if defined(MBEDTLS_SSL_RENEGOTIATION)
-  mbedtls_ssl_conf_renegotiation(&BACKEND->config,
+  mbedtls_ssl_conf_renegotiation(&backend->config,
                                  MBEDTLS_SSL_RENEGOTIATION_ENABLED);
 #endif
 
 #if defined(MBEDTLS_SSL_SESSION_TICKETS)
-  mbedtls_ssl_conf_session_tickets(&BACKEND->config,
+  mbedtls_ssl_conf_session_tickets(&backend->config,
                                    MBEDTLS_SSL_SESSION_TICKETS_DISABLED);
 #endif
 
@@ -454,7 +459,7 @@
 
     Curl_ssl_sessionid_lock(conn);
     if(!Curl_ssl_getsessionid(conn, &old_session, NULL, sockindex)) {
-      ret = mbedtls_ssl_set_session(&BACKEND->ssl, old_session);
+      ret = mbedtls_ssl_set_session(&backend->ssl, old_session);
       if(ret) {
         Curl_ssl_sessionid_unlock(conn);
         failf(data, "mbedtls_ssl_set_session returned -0x%x", -ret);
@@ -465,15 +470,15 @@
     Curl_ssl_sessionid_unlock(conn);
   }
 
-  mbedtls_ssl_conf_ca_chain(&BACKEND->config,
-                            &BACKEND->cacert,
-                            &BACKEND->crl);
+  mbedtls_ssl_conf_ca_chain(&backend->config,
+                            &backend->cacert,
+                            &backend->crl);
 
   if(SSL_SET_OPTION(key)) {
-    mbedtls_ssl_conf_own_cert(&BACKEND->config,
-                              &BACKEND->clicert, &BACKEND->pk);
+    mbedtls_ssl_conf_own_cert(&backend->config,
+                              &backend->clicert, &backend->pk);
   }
-  if(mbedtls_ssl_set_hostname(&BACKEND->ssl, hostname)) {
+  if(mbedtls_ssl_set_hostname(&backend->ssl, hostname)) {
     /* mbedtls_ssl_set_hostname() sets the name to use in CN/SAN checks *and*
        the name to set in the SNI extension. So even if curl connects to a
        host specified as an IP address, this function must be used. */
@@ -483,7 +488,7 @@
 
 #ifdef HAS_ALPN
   if(conn->bits.tls_enable_alpn) {
-    const char **p = &BACKEND->protocols[0];
+    const char **p = &backend->protocols[0];
 #ifdef USE_NGHTTP2
     if(data->set.httpversion >= CURL_HTTP_VERSION_2)
       *p++ = NGHTTP2_PROTO_VERSION_ID;
@@ -492,19 +497,19 @@
     *p = NULL;
     /* this function doesn't clone the protocols array, which is why we need
        to keep it around */
-    if(mbedtls_ssl_conf_alpn_protocols(&BACKEND->config,
-                                       &BACKEND->protocols[0])) {
+    if(mbedtls_ssl_conf_alpn_protocols(&backend->config,
+                                       &backend->protocols[0])) {
       failf(data, "Failed setting ALPN protocols");
       return CURLE_SSL_CONNECT_ERROR;
     }
-    for(p = &BACKEND->protocols[0]; *p; ++p)
+    for(p = &backend->protocols[0]; *p; ++p)
       infof(data, "ALPN, offering %s\n", *p);
   }
 #endif
 
 #ifdef MBEDTLS_DEBUG
   /* In order to make that work in mbedtls MBEDTLS_DEBUG_C must be defined. */
-  mbedtls_ssl_conf_dbg(&BACKEND->config, mbed_debug, data);
+  mbedtls_ssl_conf_dbg(&backend->config, mbed_debug, data);
   /* - 0 No debug
    * - 1 Error
    * - 2 State change
@@ -516,7 +521,7 @@
 
   /* give application a chance to interfere with mbedTLS set up. */
   if(data->set.ssl.fsslctx) {
-    ret = (*data->set.ssl.fsslctx)(data, &BACKEND->config,
+    ret = (*data->set.ssl.fsslctx)(data, &backend->config,
                                    data->set.ssl.fsslctxp);
     if(ret) {
       failf(data, "error signaled by ssl ctx callback");
@@ -535,16 +540,22 @@
 {
   int ret;
   struct Curl_easy *data = conn->data;
-  struct ssl_connect_data* connssl = &conn->ssl[sockindex];
+  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+  struct ssl_backend_data *backend = connssl->backend;
   const mbedtls_x509_crt *peercert;
+#ifndef CURL_DISABLE_PROXY
   const char * const pinnedpubkey = SSL_IS_PROXY() ?
-        data->set.str[STRING_SSL_PINNEDPUBLICKEY_PROXY] :
-        data->set.str[STRING_SSL_PINNEDPUBLICKEY_ORIG];
+    data->set.str[STRING_SSL_PINNEDPUBLICKEY_PROXY] :
+    data->set.str[STRING_SSL_PINNEDPUBLICKEY_ORIG];
+#else
+  const char * const pinnedpubkey =
+    data->set.str[STRING_SSL_PINNEDPUBLICKEY_ORIG];
+#endif
 
   conn->recv[sockindex] = mbed_recv;
   conn->send[sockindex] = mbed_send;
 
-  ret = mbedtls_ssl_handshake(&BACKEND->ssl);
+  ret = mbedtls_ssl_handshake(&backend->ssl);
 
   if(ret == MBEDTLS_ERR_SSL_WANT_READ) {
     connssl->connecting_state = ssl_connect_2_reading;
@@ -566,10 +577,10 @@
   }
 
   infof(data, "mbedTLS: Handshake complete, cipher is %s\n",
-        mbedtls_ssl_get_ciphersuite(&BACKEND->ssl)
+        mbedtls_ssl_get_ciphersuite(&backend->ssl)
     );
 
-  ret = mbedtls_ssl_get_verify_result(&BACKEND->ssl);
+  ret = mbedtls_ssl_get_verify_result(&backend->ssl);
 
   if(!SSL_CONN_CONFIG(verifyhost))
     /* Ignore hostname errors if verifyhost is disabled */
@@ -588,10 +599,13 @@
     else if(ret & MBEDTLS_X509_BADCERT_NOT_TRUSTED)
       failf(data, "Cert verify failed: BADCERT_NOT_TRUSTED");
 
+    else if(ret & MBEDTLS_X509_BADCERT_FUTURE)
+      failf(data, "Cert verify failed: BADCERT_FUTURE");
+
     return CURLE_PEER_FAILED_VERIFICATION;
   }
 
-  peercert = mbedtls_ssl_get_peer_cert(&BACKEND->ssl);
+  peercert = mbedtls_ssl_get_peer_cert(&backend->ssl);
 
   if(peercert && data->set.verbose) {
     const size_t bufsize = 16384;
@@ -661,7 +675,7 @@
 
 #ifdef HAS_ALPN
   if(conn->bits.tls_enable_alpn) {
-    const char *next_protocol = mbedtls_ssl_get_alpn_protocol(&BACKEND->ssl);
+    const char *next_protocol = mbedtls_ssl_get_alpn_protocol(&backend->ssl);
 
     if(next_protocol) {
       infof(data, "ALPN, server accepted to use %s\n", next_protocol);
@@ -698,6 +712,7 @@
 {
   CURLcode retcode = CURLE_OK;
   struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+  struct ssl_backend_data *backend = connssl->backend;
   struct Curl_easy *data = conn->data;
 
   DEBUGASSERT(ssl_connect_3 == connssl->connecting_state);
@@ -713,7 +728,7 @@
 
     mbedtls_ssl_session_init(our_ssl_sessionid);
 
-    ret = mbedtls_ssl_get_session(&BACKEND->ssl, our_ssl_sessionid);
+    ret = mbedtls_ssl_get_session(&backend->ssl, our_ssl_sessionid);
     if(ret) {
       if(ret != MBEDTLS_ERR_SSL_ALLOC_FAILED)
         mbedtls_ssl_session_free(our_ssl_sessionid);
@@ -747,9 +762,10 @@
                          CURLcode *curlcode)
 {
   struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+  struct ssl_backend_data *backend = connssl->backend;
   int ret = -1;
 
-  ret = mbedtls_ssl_write(&BACKEND->ssl,
+  ret = mbedtls_ssl_write(&backend->ssl,
                           (unsigned char *)mem, len);
 
   if(ret < 0) {
@@ -769,15 +785,16 @@
 static void Curl_mbedtls_close(struct connectdata *conn, int sockindex)
 {
   struct ssl_connect_data *connssl = &conn->ssl[sockindex];
-  mbedtls_pk_free(&BACKEND->pk);
-  mbedtls_x509_crt_free(&BACKEND->clicert);
-  mbedtls_x509_crt_free(&BACKEND->cacert);
-  mbedtls_x509_crl_free(&BACKEND->crl);
-  mbedtls_ssl_config_free(&BACKEND->config);
-  mbedtls_ssl_free(&BACKEND->ssl);
-  mbedtls_ctr_drbg_free(&BACKEND->ctr_drbg);
+  struct ssl_backend_data *backend = connssl->backend;
+  mbedtls_pk_free(&backend->pk);
+  mbedtls_x509_crt_free(&backend->clicert);
+  mbedtls_x509_crt_free(&backend->cacert);
+  mbedtls_x509_crl_free(&backend->crl);
+  mbedtls_ssl_config_free(&backend->config);
+  mbedtls_ssl_free(&backend->ssl);
+  mbedtls_ctr_drbg_free(&backend->ctr_drbg);
 #ifndef THREADING_SUPPORT
-  mbedtls_entropy_free(&BACKEND->entropy);
+  mbedtls_entropy_free(&backend->entropy);
 #endif /* THREADING_SUPPORT */
 }
 
@@ -786,11 +803,12 @@
                          CURLcode *curlcode)
 {
   struct ssl_connect_data *connssl = &conn->ssl[num];
+  struct ssl_backend_data *backend = connssl->backend;
   int ret = -1;
   ssize_t len = -1;
 
   memset(buf, 0, buffersize);
-  ret = mbedtls_ssl_read(&BACKEND->ssl, (unsigned char *)buf,
+  ret = mbedtls_ssl_read(&backend->ssl, (unsigned char *)buf,
                          buffersize);
 
   if(ret <= 0) {
@@ -884,7 +902,7 @@
   struct Curl_easy *data = conn->data;
   struct ssl_connect_data *connssl = &conn->ssl[sockindex];
   curl_socket_t sockfd = conn->sock[sockindex];
-  long timeout_ms;
+  timediff_t timeout_ms;
   int what;
 
   /* check if the connection has already been established */
@@ -1014,19 +1032,20 @@
  */
 static int Curl_mbedtls_init(void)
 {
-  return Curl_polarsslthreadlock_thread_setup();
+  return Curl_mbedtlsthreadlock_thread_setup();
 }
 
 static void Curl_mbedtls_cleanup(void)
 {
-  (void)Curl_polarsslthreadlock_thread_cleanup();
+  (void)Curl_mbedtlsthreadlock_thread_cleanup();
 }
 
 static bool Curl_mbedtls_data_pending(const struct connectdata *conn,
                                       int sockindex)
 {
   const struct ssl_connect_data *connssl = &conn->ssl[sockindex];
-  return mbedtls_ssl_get_bytes_avail(&BACKEND->ssl) != 0;
+  struct ssl_backend_data *backend = connssl->backend;
+  return mbedtls_ssl_get_bytes_avail(&backend->ssl) != 0;
 }
 
 static CURLcode Curl_mbedtls_sha256sum(const unsigned char *input,
@@ -1048,8 +1067,9 @@
 static void *Curl_mbedtls_get_internals(struct ssl_connect_data *connssl,
                                         CURLINFO info UNUSED_PARAM)
 {
+  struct ssl_backend_data *backend = connssl->backend;
   (void)info;
-  return &BACKEND->ssl;
+  return &backend->ssl;
 }
 
 const struct Curl_ssl Curl_ssl_mbedtls = {
diff --git a/Utilities/cmcurl/lib/vtls/mbedtls.h b/Utilities/cmcurl/lib/vtls/mbedtls.h
index 4a93860..0cc64b3 100644
--- a/Utilities/cmcurl/lib/vtls/mbedtls.h
+++ b/Utilities/cmcurl/lib/vtls/mbedtls.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 2012 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 2012 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
  * Copyright (C) 2010, Hoi-Ho Chan, <hoiho.chan@gmail.com>
  *
  * This software is licensed as described in the file COPYING, which
diff --git a/Utilities/cmcurl/lib/vtls/mbedtls_threadlock.c b/Utilities/cmcurl/lib/vtls/mbedtls_threadlock.c
new file mode 100644
index 0000000..4d672f1
--- /dev/null
+++ b/Utilities/cmcurl/lib/vtls/mbedtls_threadlock.c
@@ -0,0 +1,144 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 2013 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 2010, 2011, Hoi-Ho Chan, <hoiho.chan@gmail.com>
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include "curl_setup.h"
+
+#if defined(USE_MBEDTLS) &&                                     \
+  ((defined(USE_THREADS_POSIX) && defined(HAVE_PTHREAD_H)) ||   \
+   (defined(USE_THREADS_WIN32) && defined(HAVE_PROCESS_H)))
+
+#if defined(USE_THREADS_POSIX) && defined(HAVE_PTHREAD_H)
+#  include <pthread.h>
+#  define MBEDTLS_MUTEX_T pthread_mutex_t
+#elif defined(USE_THREADS_WIN32) && defined(HAVE_PROCESS_H)
+#  include <process.h>
+#  define MBEDTLS_MUTEX_T HANDLE
+#endif
+
+#include "mbedtls_threadlock.h"
+#include "curl_printf.h"
+#include "curl_memory.h"
+/* The last #include file should be: */
+#include "memdebug.h"
+
+/* number of thread locks */
+#define NUMT                    2
+
+/* This array will store all of the mutexes available to Mbedtls. */
+static MBEDTLS_MUTEX_T *mutex_buf = NULL;
+
+int Curl_mbedtlsthreadlock_thread_setup(void)
+{
+  int i;
+
+  mutex_buf = calloc(NUMT * sizeof(MBEDTLS_MUTEX_T), 1);
+  if(!mutex_buf)
+    return 0;     /* error, no number of threads defined */
+
+  for(i = 0;  i < NUMT;  i++) {
+    int ret;
+#if defined(USE_THREADS_POSIX) && defined(HAVE_PTHREAD_H)
+    ret = pthread_mutex_init(&mutex_buf[i], NULL);
+    if(ret)
+      return 0; /* pthread_mutex_init failed */
+#elif defined(USE_THREADS_WIN32) && defined(HAVE_PROCESS_H)
+    mutex_buf[i] = CreateMutex(0, FALSE, 0);
+    if(mutex_buf[i] == 0)
+      return 0;  /* CreateMutex failed */
+#endif /* USE_THREADS_POSIX && HAVE_PTHREAD_H */
+  }
+
+  return 1; /* OK */
+}
+
+int Curl_mbedtlsthreadlock_thread_cleanup(void)
+{
+  int i;
+
+  if(!mutex_buf)
+    return 0; /* error, no threads locks defined */
+
+  for(i = 0; i < NUMT; i++) {
+    int ret;
+#if defined(USE_THREADS_POSIX) && defined(HAVE_PTHREAD_H)
+    ret = pthread_mutex_destroy(&mutex_buf[i]);
+    if(ret)
+      return 0; /* pthread_mutex_destroy failed */
+#elif defined(USE_THREADS_WIN32) && defined(HAVE_PROCESS_H)
+    ret = CloseHandle(mutex_buf[i]);
+    if(!ret)
+      return 0; /* CloseHandle failed */
+#endif /* USE_THREADS_POSIX && HAVE_PTHREAD_H */
+  }
+  free(mutex_buf);
+  mutex_buf = NULL;
+
+  return 1; /* OK */
+}
+
+int Curl_mbedtlsthreadlock_lock_function(int n)
+{
+  if(n < NUMT) {
+    int ret;
+#if defined(USE_THREADS_POSIX) && defined(HAVE_PTHREAD_H)
+    ret = pthread_mutex_lock(&mutex_buf[n]);
+    if(ret) {
+      DEBUGF(fprintf(stderr,
+                     "Error: mbedtlsthreadlock_lock_function failed\n"));
+      return 0; /* pthread_mutex_lock failed */
+    }
+#elif defined(USE_THREADS_WIN32) && defined(HAVE_PROCESS_H)
+    ret = (WaitForSingleObject(mutex_buf[n], INFINITE) == WAIT_FAILED?1:0);
+    if(ret) {
+      DEBUGF(fprintf(stderr,
+                     "Error: mbedtlsthreadlock_lock_function failed\n"));
+      return 0; /* pthread_mutex_lock failed */
+    }
+#endif /* USE_THREADS_POSIX && HAVE_PTHREAD_H */
+  }
+  return 1; /* OK */
+}
+
+int Curl_mbedtlsthreadlock_unlock_function(int n)
+{
+  if(n < NUMT) {
+    int ret;
+#if defined(USE_THREADS_POSIX) && defined(HAVE_PTHREAD_H)
+    ret = pthread_mutex_unlock(&mutex_buf[n]);
+    if(ret) {
+      DEBUGF(fprintf(stderr,
+                     "Error: mbedtlsthreadlock_unlock_function failed\n"));
+      return 0; /* pthread_mutex_unlock failed */
+    }
+#elif defined(USE_THREADS_WIN32) && defined(HAVE_PROCESS_H)
+    ret = ReleaseMutex(mutex_buf[n]);
+    if(!ret) {
+      DEBUGF(fprintf(stderr,
+                     "Error: mbedtlsthreadlock_unlock_function failed\n"));
+      return 0; /* pthread_mutex_lock failed */
+    }
+#endif /* USE_THREADS_POSIX && HAVE_PTHREAD_H */
+  }
+  return 1; /* OK */
+}
+
+#endif /* USE_MBEDTLS */
diff --git a/Utilities/cmcurl/lib/vtls/mbedtls_threadlock.h b/Utilities/cmcurl/lib/vtls/mbedtls_threadlock.h
new file mode 100644
index 0000000..96a787d
--- /dev/null
+++ b/Utilities/cmcurl/lib/vtls/mbedtls_threadlock.h
@@ -0,0 +1,48 @@
+#ifndef HEADER_CURL_MBEDTLS_THREADLOCK_H
+#define HEADER_CURL_MBEDTLS_THREADLOCK_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 2013 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 2010, Hoi-Ho Chan, <hoiho.chan@gmail.com>
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include "curl_setup.h"
+
+#ifdef USE_MBEDTLS
+
+#if (defined(USE_THREADS_POSIX) && defined(HAVE_PTHREAD_H)) || \
+    (defined(USE_THREADS_WIN32) && defined(HAVE_PROCESS_H))
+
+int Curl_mbedtlsthreadlock_thread_setup(void);
+int Curl_mbedtlsthreadlock_thread_cleanup(void);
+int Curl_mbedtlsthreadlock_lock_function(int n);
+int Curl_mbedtlsthreadlock_unlock_function(int n);
+
+#else
+
+#define Curl_mbedtlsthreadlock_thread_setup() 1
+#define Curl_mbedtlsthreadlock_thread_cleanup() 1
+#define Curl_mbedtlsthreadlock_lock_function(x) 1
+#define Curl_mbedtlsthreadlock_unlock_function(x) 1
+
+#endif /* USE_THREADS_POSIX || USE_THREADS_WIN32 */
+
+#endif /* USE_MBEDTLS */
+
+#endif /* HEADER_CURL_MBEDTLS_THREADLOCK_H */
diff --git a/Utilities/cmcurl/lib/vtls/mesalink.c b/Utilities/cmcurl/lib/vtls/mesalink.c
index 718c282..7132bdf 100644
--- a/Utilities/cmcurl/lib/vtls/mesalink.c
+++ b/Utilities/cmcurl/lib/vtls/mesalink.c
@@ -6,7 +6,7 @@
  *                             \___|\___/|_| \_\_____|
  *
  * Copyright (C) 2017 - 2018, Yiming Jing, <jingyiming@baidu.com>
- * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -73,6 +73,17 @@
 static Curl_recv mesalink_recv;
 static Curl_send mesalink_send;
 
+static int do_file_type(const char *type)
+{
+  if(!type || !type[0])
+    return SSL_FILETYPE_PEM;
+  if(strcasecompare(type, "PEM"))
+    return SSL_FILETYPE_PEM;
+  if(strcasecompare(type, "DER"))
+    return SSL_FILETYPE_ASN1;
+  return -1;
+}
+
 /*
  * This function loads all the client/CA certificates and CRLs. Setup the TLS
  * layer and do all necessary magic.
@@ -83,9 +94,6 @@
   char *ciphers;
   struct Curl_easy *data = conn->data;
   struct ssl_connect_data *connssl = &conn->ssl[sockindex];
-  const bool verifypeer = SSL_CONN_CONFIG(verifypeer);
-  const char *const ssl_cafile = SSL_CONN_CONFIG(CAfile);
-  const char *const ssl_capath = SSL_CONN_CONFIG(CApath);
   struct in_addr addr4;
 #ifdef ENABLE_IPV6
   struct in6_addr addr6;
@@ -142,21 +150,25 @@
   }
 
   SSL_CTX_set_verify(
-    BACKEND->ctx, verifypeer ? SSL_VERIFY_PEER : SSL_VERIFY_NONE, NULL);
+    BACKEND->ctx, SSL_CONN_CONFIG(verifypeer) ?
+      SSL_VERIFY_PEER : SSL_VERIFY_NONE, NULL);
 
-  if(ssl_cafile || ssl_capath) {
-    if(!SSL_CTX_load_verify_locations(BACKEND->ctx, ssl_cafile, ssl_capath)) {
-      if(verifypeer) {
+  if(SSL_CONN_CONFIG(CAfile) || SSL_CONN_CONFIG(CApath)) {
+    if(!SSL_CTX_load_verify_locations(BACKEND->ctx, SSL_CONN_CONFIG(CAfile),
+                                                    SSL_CONN_CONFIG(CApath))) {
+      if(SSL_CONN_CONFIG(verifypeer)) {
         failf(data,
               "error setting certificate verify locations:\n"
               "  CAfile: %s\n  CApath: %s",
-              ssl_cafile ? ssl_cafile : "none",
-              ssl_capath ? ssl_capath : "none");
+              SSL_CONN_CONFIG(CAfile) ?
+              SSL_CONN_CONFIG(CAfile) : "none",
+              SSL_CONN_CONFIG(CApath) ?
+              SSL_CONN_CONFIG(CApath) : "none");
         return CURLE_SSL_CACERT_BADFILE;
       }
       infof(data,
-            "error setting certificate verify locations,"
-            " continuing anyway:\n");
+          "error setting certificate verify locations,"
+          " continuing anyway:\n");
     }
     else {
       infof(data, "successfully set certificate verify locations:\n");
@@ -164,8 +176,32 @@
     infof(data,
           "  CAfile: %s\n"
           "  CApath: %s\n",
-          ssl_cafile ? ssl_cafile : "none",
-          ssl_capath ? ssl_capath : "none");
+          SSL_CONN_CONFIG(CAfile)?
+          SSL_CONN_CONFIG(CAfile): "none",
+          SSL_CONN_CONFIG(CApath)?
+          SSL_CONN_CONFIG(CApath): "none");
+  }
+
+  if(SSL_SET_OPTION(cert) && SSL_SET_OPTION(key)) {
+    int file_type = do_file_type(SSL_SET_OPTION(cert_type));
+
+    if(SSL_CTX_use_certificate_chain_file(BACKEND->ctx, SSL_SET_OPTION(cert),
+                                     file_type) != 1) {
+      failf(data, "unable to use client certificate (no key or wrong pass"
+            " phrase?)");
+      return CURLE_SSL_CONNECT_ERROR;
+    }
+
+    file_type = do_file_type(SSL_SET_OPTION(key_type));
+    if(SSL_CTX_use_PrivateKey_file(BACKEND->ctx, SSL_SET_OPTION(key),
+                                    file_type) != 1) {
+      failf(data, "unable to set private key");
+      return CURLE_SSL_CONNECT_ERROR;
+    }
+    infof(data,
+          "client cert: %s\n",
+          SSL_CONN_CONFIG(clientcert)?
+          SSL_CONN_CONFIG(clientcert): "none");
   }
 
   ciphers = SSL_CONN_CONFIG(cipher_list);
@@ -265,7 +301,6 @@
 
   ret = SSL_connect(BACKEND->handle);
   if(ret != SSL_SUCCESS) {
-    char error_buffer[MESALINK_MAX_ERROR_SZ];
     int detail = SSL_get_error(BACKEND->handle, ret);
 
     if(SSL_ERROR_WANT_CONNECT == detail || SSL_ERROR_WANT_READ == detail) {
@@ -273,6 +308,7 @@
       return CURLE_OK;
     }
     else {
+      char error_buffer[MESALINK_MAX_ERROR_SZ];
       failf(data,
             "SSL_connect failed with error %d: %s",
             detail,
@@ -458,7 +494,7 @@
   struct Curl_easy *data = conn->data;
   struct ssl_connect_data *connssl = &conn->ssl[sockindex];
   curl_socket_t sockfd = conn->sock[sockindex];
-  time_t timeout_ms;
+  timediff_t timeout_ms;
   int what;
 
   /* check if the connection has already been established */
@@ -506,8 +542,8 @@
                                ? sockfd
                                : CURL_SOCKET_BAD;
 
-      what = Curl_socket_check(
-        readfd, CURL_SOCKET_BAD, writefd, nonblocking ? 0 : timeout_ms);
+      what = Curl_socket_check(readfd, CURL_SOCKET_BAD, writefd,
+                               nonblocking ? 0 : timeout_ms);
       if(what < 0) {
         /* fatal error */
         failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO);
diff --git a/Utilities/cmcurl/lib/vtls/nss.c b/Utilities/cmcurl/lib/vtls/nss.c
index 491def1..fca2926 100644
--- a/Utilities/cmcurl/lib/vtls/nss.c
+++ b/Utilities/cmcurl/lib/vtls/nss.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -87,8 +87,6 @@
   PK11GenericObject *obj_clicert;
 };
 
-#define BACKEND connssl->backend
-
 static PRLock *nss_initlock = NULL;
 static PRLock *nss_crllock = NULL;
 static PRLock *nss_findslot_lock = NULL;
@@ -103,22 +101,22 @@
   struct curl_llist_element node;
 };
 
-typedef struct {
+struct cipher_s {
   const char *name;
   int num;
-} cipher_s;
+};
 
 #define PK11_SETATTRS(_attr, _idx, _type, _val, _len) do {  \
   CK_ATTRIBUTE *ptr = (_attr) + ((_idx)++);                 \
   ptr->type = (_type);                                      \
   ptr->pValue = (_val);                                     \
   ptr->ulValueLen = (_len);                                 \
-} WHILE_FALSE
+} while(0)
 
 #define CERT_NewTempCertificate __CERT_NewTempCertificate
 
 #define NUM_OF_CIPHERS sizeof(cipherlist)/sizeof(cipherlist[0])
-static const cipher_s cipherlist[] = {
+static const struct cipher_s cipherlist[] = {
   /* SSL2 cipher suites */
   {"rc4",                        SSL_EN_RC4_128_WITH_MD5},
   {"rc4-md5",                    SSL_EN_RC4_128_WITH_MD5},
@@ -216,11 +214,19 @@
  {"dhe_rsa_chacha20_poly1305_sha_256",
      TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256},
 #endif
+#ifdef TLS_AES_256_GCM_SHA384
+ {"aes_128_gcm_sha_256",              TLS_AES_128_GCM_SHA256},
+ {"aes_256_gcm_sha_384",              TLS_AES_256_GCM_SHA384},
+ {"chacha20_poly1305_sha_256",        TLS_CHACHA20_POLY1305_SHA256},
+#endif
 };
 
-#ifdef WIN32
+#if defined(WIN32)
 static const char *pem_library = "nsspem.dll";
 static const char *trust_library = "nssckbi.dll";
+#elif defined(__APPLE__)
+static const char *pem_library = "libnsspem.dylib";
+static const char *trust_library = "libnssckbi.dylib";
 #else
 static const char *pem_library = "libnsspem.so";
 static const char *trust_library = "libnssckbi.so";
@@ -454,6 +460,7 @@
 
   const int slot_id = (cacert) ? 0 : 1;
   char *slot_name = aprintf("PEM Token #%d", slot_id);
+  struct ssl_backend_data *backend = connssl->backend;
   if(!slot_name)
     return CURLE_OUT_OF_MEMORY;
 
@@ -487,14 +494,14 @@
   if(!obj)
     return result;
 
-  if(insert_wrapped_ptr(&BACKEND->obj_list, obj) != CURLE_OK) {
+  if(insert_wrapped_ptr(&backend->obj_list, obj) != CURLE_OK) {
     PK11_DestroyGenericObject(obj);
     return CURLE_OUT_OF_MEMORY;
   }
 
   if(!cacert && CKO_CERTIFICATE == obj_class)
     /* store reference to a client certificate */
-    BACKEND->obj_clicert = obj;
+    backend->obj_clicert = obj;
 
   return CURLE_OK;
 }
@@ -573,19 +580,21 @@
   /* acquire lock before call of CERT_CacheCRL() and accessing nss_crl_list */
   PR_Lock(nss_crllock);
 
-  /* store the CRL item so that we can free it in Curl_nss_cleanup() */
-  if(insert_wrapped_ptr(&nss_crl_list, crl_der) != CURLE_OK) {
-    SECITEM_FreeItem(crl_der, PR_TRUE);
-    PR_Unlock(nss_crllock);
-    return CURLE_OUT_OF_MEMORY;
-  }
-
   if(SECSuccess != CERT_CacheCRL(db, crl_der)) {
     /* unable to cache CRL */
+    SECITEM_FreeItem(crl_der, PR_TRUE);
     PR_Unlock(nss_crllock);
     return CURLE_SSL_CRL_BADFILE;
   }
 
+  /* store the CRL item so that we can free it in Curl_nss_cleanup() */
+  if(insert_wrapped_ptr(&nss_crl_list, crl_der) != CURLE_OK) {
+    if(SECSuccess == CERT_UncacheCRL(db, crl_der))
+      SECITEM_FreeItem(crl_der, PR_TRUE);
+    PR_Unlock(nss_crllock);
+    return CURLE_OUT_OF_MEMORY;
+  }
+
   /* we need to clear session cache, so that the CRL could take effect */
   SSL_ClearSessionCache();
   PR_Unlock(nss_crllock);
@@ -681,7 +690,10 @@
   tmp = SECMOD_WaitForAnyTokenEvent(pem_module, 0, 0);
   if(tmp)
     PK11_FreeSlot(tmp);
-  PK11_IsPresent(slot);
+  if(!PK11_IsPresent(slot)) {
+    PK11_FreeSlot(slot);
+    return CURLE_SSL_CERTPROBLEM;
+  }
 
   status = PK11_Authenticate(slot, PR_TRUE, SSL_SET_OPTION(key_passwd));
   PK11_FreeSlot(slot);
@@ -1071,7 +1083,8 @@
                                 const char *pinnedpubkey)
 {
   CURLcode result = CURLE_SSL_PINNEDPUBKEYNOTMATCH;
-  struct Curl_easy *data = BACKEND->data;
+  struct ssl_backend_data *backend = connssl->backend;
+  struct Curl_easy *data = backend->data;
   CERTCertificate *cert;
 
   if(!pinnedpubkey)
@@ -1079,7 +1092,7 @@
     return CURLE_OK;
 
   /* get peer certificate */
-  cert = SSL_PeerCertificate(BACKEND->handle);
+  cert = SSL_PeerCertificate(backend->handle);
   if(cert) {
     /* extract public key from peer certificate */
     SECKEYPublicKey *pubkey = CERT_ExtractPublicKey(cert);
@@ -1123,11 +1136,12 @@
                                   struct SECKEYPrivateKeyStr **pRetKey)
 {
   struct ssl_connect_data *connssl = (struct ssl_connect_data *)arg;
-  struct Curl_easy *data = BACKEND->data;
-  const char *nickname = BACKEND->client_nickname;
+  struct ssl_backend_data *backend = connssl->backend;
+  struct Curl_easy *data = backend->data;
+  const char *nickname = backend->client_nickname;
   static const char pem_slotname[] = "PEM Token #1";
 
-  if(BACKEND->obj_clicert) {
+  if(backend->obj_clicert) {
     /* use the cert/key provided by PEM reader */
     SECItem cert_der = { 0, NULL, 0 };
     void *proto_win = SSL_RevealPinArg(sock);
@@ -1140,7 +1154,7 @@
       return SECFailure;
     }
 
-    if(PK11_ReadRawAttribute(PK11_TypeGeneric, BACKEND->obj_clicert, CKA_VALUE,
+    if(PK11_ReadRawAttribute(PK11_TypeGeneric, backend->obj_clicert, CKA_VALUE,
                              &cert_der) != SECSuccess) {
       failf(data, "NSS: CKA_VALUE not found in PK11 generic object");
       PK11_FreeSlot(slot);
@@ -1416,7 +1430,7 @@
 {
   /* curl_global_init() is not thread-safe so this test is ok */
   if(nss_initlock == NULL) {
-    PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 256);
+    PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0);
     nss_initlock = PR_NewLock();
     nss_crllock = PR_NewLock();
     nss_findslot_lock = PR_NewLock();
@@ -1490,11 +1504,12 @@
 static int Curl_nss_check_cxn(struct connectdata *conn)
 {
   struct ssl_connect_data *connssl = &conn->ssl[FIRSTSOCKET];
+  struct ssl_backend_data *backend = connssl->backend;
   int rc;
   char buf;
 
   rc =
-    PR_Recv(BACKEND->handle, (void *)&buf, 1, PR_MSG_PEEK,
+    PR_Recv(backend->handle, (void *)&buf, 1, PR_MSG_PEEK,
             PR_SecondsToInterval(1));
   if(rc > 0)
     return 1; /* connection still in place */
@@ -1508,26 +1523,27 @@
 static void nss_close(struct ssl_connect_data *connssl)
 {
   /* before the cleanup, check whether we are using a client certificate */
-  const bool client_cert = (BACKEND->client_nickname != NULL)
-    || (BACKEND->obj_clicert != NULL);
+  struct ssl_backend_data *backend = connssl->backend;
+  const bool client_cert = (backend->client_nickname != NULL)
+    || (backend->obj_clicert != NULL);
 
-  free(BACKEND->client_nickname);
-  BACKEND->client_nickname = NULL;
+  free(backend->client_nickname);
+  backend->client_nickname = NULL;
 
   /* destroy all NSS objects in order to avoid failure of NSS shutdown */
-  Curl_llist_destroy(&BACKEND->obj_list, NULL);
-  BACKEND->obj_clicert = NULL;
+  Curl_llist_destroy(&backend->obj_list, NULL);
+  backend->obj_clicert = NULL;
 
-  if(BACKEND->handle) {
+  if(backend->handle) {
     if(client_cert)
       /* A server might require different authentication based on the
        * particular path being requested by the client.  To support this
        * scenario, we must ensure that a connection will never reuse the
        * authentication data from a previous connection. */
-      SSL_InvalidateSession(BACKEND->handle);
+      SSL_InvalidateSession(backend->handle);
 
-    PR_Close(BACKEND->handle);
-    BACKEND->handle = NULL;
+    PR_Close(backend->handle);
+    backend->handle = NULL;
   }
 }
 
@@ -1538,15 +1554,16 @@
 {
   struct ssl_connect_data *connssl = &conn->ssl[sockindex];
   struct ssl_connect_data *connssl_proxy = &conn->proxy_ssl[sockindex];
+  struct ssl_backend_data *backend = connssl->backend;
 
-  if(BACKEND->handle || connssl_proxy->backend->handle) {
+  if(backend->handle || connssl_proxy->backend->handle) {
     /* NSS closes the socket we previously handed to it, so we must mark it
        as closed to avoid double close */
     fake_sclose(conn->sock[sockindex]);
     conn->sock[sockindex] = CURL_SOCKET_BAD;
   }
 
-  if(BACKEND->handle)
+  if(backend->handle)
     /* nss_close(connssl) will transitively close also
        connssl_proxy->backend->handle if both are used. Clear it to avoid
        a double close leading to crash. */
@@ -1721,20 +1738,16 @@
   CURLcode result;
   const long min = SSL_CONN_CONFIG(version);
   const long max = SSL_CONN_CONFIG(version_max);
-
-  /* map CURL_SSLVERSION_DEFAULT to NSS default */
-  if(min == CURL_SSLVERSION_DEFAULT || max == CURL_SSLVERSION_MAX_DEFAULT) {
-    /* map CURL_SSLVERSION_DEFAULT to NSS default */
-    if(SSL_VersionRangeGetDefault(ssl_variant_stream, sslver) != SECSuccess)
-      return CURLE_SSL_CONNECT_ERROR;
-    /* ... but make sure we use at least TLSv1.0 according to libcurl API */
-    if(sslver->min < SSL_LIBRARY_VERSION_TLS_1_0)
-      sslver->min = SSL_LIBRARY_VERSION_TLS_1_0;
-  }
+  SSLVersionRange vrange;
 
   switch(min) {
   case CURL_SSLVERSION_TLSv1:
   case CURL_SSLVERSION_DEFAULT:
+    /* Bump our minimum TLS version if NSS has stricter requirements. */
+    if(SSL_VersionRangeGetDefault(ssl_variant_stream, &vrange) != SECSuccess)
+      return CURLE_SSL_CONNECT_ERROR;
+    if(sslver->min < vrange.min)
+      sslver->min = vrange.min;
     break;
   default:
     result = nss_sslver_from_curl(&sslver->min, min);
@@ -1764,6 +1777,7 @@
                                  CURLcode curlerr)
 {
   PRErrorCode err = 0;
+  struct ssl_backend_data *backend = connssl->backend;
 
   if(is_nss_error(curlerr)) {
     /* read NSPR error code */
@@ -1779,7 +1793,7 @@
   }
 
   /* cleanup on connection failure */
-  Curl_llist_destroy(&BACKEND->obj_list, NULL);
+  Curl_llist_destroy(&backend->obj_list, NULL);
 
   return curlerr;
 }
@@ -1790,10 +1804,11 @@
                                  bool blocking)
 {
   static PRSocketOptionData sock_opt;
+  struct ssl_backend_data *backend = connssl->backend;
   sock_opt.option = PR_SockOpt_Nonblocking;
   sock_opt.value.non_blocking = !blocking;
 
-  if(PR_SetSocketOption(BACKEND->handle, &sock_opt) != PR_SUCCESS)
+  if(PR_SetSocketOption(backend->handle, &sock_opt) != PR_SUCCESS)
     return nss_fail_connect(connssl, data, CURLE_SSL_CONNECT_ERROR);
 
   return CURLE_OK;
@@ -1809,6 +1824,7 @@
   struct Curl_easy *data = conn->data;
   curl_socket_t sockfd = conn->sock[sockindex];
   struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+  struct ssl_backend_data *backend = connssl->backend;
   CURLcode result;
   bool second_layer = FALSE;
   SSLVersionRange sslver_supported;
@@ -1826,10 +1842,10 @@
 #endif
   };
 
-  BACKEND->data = data;
+  backend->data = data;
 
   /* list of all NSS objects we need to destroy in Curl_nss_close() */
-  Curl_llist_init(&BACKEND->obj_list, nss_destroy_object);
+  Curl_llist_init(&backend->obj_list, nss_destroy_object);
 
   PR_Lock(nss_initlock);
   result = nss_init(conn->data);
@@ -1951,7 +1967,7 @@
     char *nickname = dup_nickname(data, SSL_SET_OPTION(cert));
     if(nickname) {
       /* we are not going to use libnsspem.so to read the client cert */
-      BACKEND->obj_clicert = NULL;
+      backend->obj_clicert = NULL;
     }
     else {
       CURLcode rv = cert_stuff(conn, sockindex, SSL_SET_OPTION(cert),
@@ -1964,10 +1980,10 @@
     }
 
     /* store the nickname for SelectClientCert() called during handshake */
-    BACKEND->client_nickname = nickname;
+    backend->client_nickname = nickname;
   }
   else
-    BACKEND->client_nickname = NULL;
+    backend->client_nickname = NULL;
 
   if(SSL_GetClientAuthDataHook(model, SelectClientCert,
                                (void *)connssl) != SECSuccess) {
@@ -2008,8 +2024,8 @@
   }
 
   /* import our model socket onto the current I/O stack */
-  BACKEND->handle = SSL_ImportFD(model, nspr_io);
-  if(!BACKEND->handle) {
+  backend->handle = SSL_ImportFD(model, nspr_io);
+  if(!backend->handle) {
     if(!second_layer)
       PR_Close(nspr_io);
     goto error;
@@ -2020,36 +2036,36 @@
 
   /* This is the password associated with the cert that we're using */
   if(SSL_SET_OPTION(key_passwd)) {
-    SSL_SetPKCS11PinArg(BACKEND->handle, SSL_SET_OPTION(key_passwd));
+    SSL_SetPKCS11PinArg(backend->handle, SSL_SET_OPTION(key_passwd));
   }
 
 #ifdef SSL_ENABLE_OCSP_STAPLING
   if(SSL_CONN_CONFIG(verifystatus)) {
-    if(SSL_OptionSet(BACKEND->handle, SSL_ENABLE_OCSP_STAPLING, PR_TRUE)
+    if(SSL_OptionSet(backend->handle, SSL_ENABLE_OCSP_STAPLING, PR_TRUE)
         != SECSuccess)
       goto error;
   }
 #endif
 
 #ifdef SSL_ENABLE_NPN
-  if(SSL_OptionSet(BACKEND->handle, SSL_ENABLE_NPN, conn->bits.tls_enable_npn
+  if(SSL_OptionSet(backend->handle, SSL_ENABLE_NPN, conn->bits.tls_enable_npn
                    ? PR_TRUE : PR_FALSE) != SECSuccess)
     goto error;
 #endif
 
 #ifdef SSL_ENABLE_ALPN
-  if(SSL_OptionSet(BACKEND->handle, SSL_ENABLE_ALPN, conn->bits.tls_enable_alpn
+  if(SSL_OptionSet(backend->handle, SSL_ENABLE_ALPN, conn->bits.tls_enable_alpn
                    ? PR_TRUE : PR_FALSE) != SECSuccess)
     goto error;
 #endif
 
 #if NSSVERNUM >= 0x030f04 /* 3.15.4 */
   if(data->set.ssl.falsestart) {
-    if(SSL_OptionSet(BACKEND->handle, SSL_ENABLE_FALSE_START, PR_TRUE)
+    if(SSL_OptionSet(backend->handle, SSL_ENABLE_FALSE_START, PR_TRUE)
         != SECSuccess)
       goto error;
 
-    if(SSL_SetCanFalseStartCallback(BACKEND->handle, CanFalseStartCallback,
+    if(SSL_SetCanFalseStartCallback(backend->handle, CanFalseStartCallback,
         conn) != SECSuccess)
       goto error;
   }
@@ -2073,24 +2089,24 @@
     memcpy(&protocols[cur], ALPN_HTTP_1_1, ALPN_HTTP_1_1_LENGTH);
     cur += ALPN_HTTP_1_1_LENGTH;
 
-    if(SSL_SetNextProtoNego(BACKEND->handle, protocols, cur) != SECSuccess)
+    if(SSL_SetNextProtoNego(backend->handle, protocols, cur) != SECSuccess)
       goto error;
   }
 #endif
 
 
   /* Force handshake on next I/O */
-  if(SSL_ResetHandshake(BACKEND->handle, /* asServer */ PR_FALSE)
+  if(SSL_ResetHandshake(backend->handle, /* asServer */ PR_FALSE)
       != SECSuccess)
     goto error;
 
   /* propagate hostname to the TLS layer */
-  if(SSL_SetURL(BACKEND->handle, SSL_IS_PROXY() ? conn->http_proxy.host.name :
+  if(SSL_SetURL(backend->handle, SSL_IS_PROXY() ? conn->http_proxy.host.name :
                 conn->host.name) != SECSuccess)
     goto error;
 
   /* prevent NSS from re-using the session for a different hostname */
-  if(SSL_SetSockPeerID(BACKEND->handle, SSL_IS_PROXY() ?
+  if(SSL_SetSockPeerID(backend->handle, SSL_IS_PROXY() ?
                        conn->http_proxy.host.name : conn->host.name)
      != SECSuccess)
     goto error;
@@ -2107,6 +2123,7 @@
 static CURLcode nss_do_connect(struct connectdata *conn, int sockindex)
 {
   struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+  struct ssl_backend_data *backend = connssl->backend;
   struct Curl_easy *data = conn->data;
   CURLcode result = CURLE_SSL_CONNECT_ERROR;
   PRUint32 timeout;
@@ -2118,7 +2135,7 @@
 
 
   /* check timeout situation */
-  const time_t time_left = Curl_timeleft(data, NULL, TRUE);
+  const timediff_t time_left = Curl_timeleft(data, NULL, TRUE);
   if(time_left < 0) {
     failf(data, "timed out before SSL handshake");
     result = CURLE_OPERATION_TIMEDOUT;
@@ -2127,7 +2144,7 @@
 
   /* Force the handshake now */
   timeout = PR_MillisecondsToInterval((PRUint32) time_left);
-  if(SSL_ForceHandshakeWithTimeout(BACKEND->handle, timeout) != SECSuccess) {
+  if(SSL_ForceHandshakeWithTimeout(backend->handle, timeout) != SECSuccess) {
     if(PR_GetError() == PR_WOULD_BLOCK_ERROR)
       /* blocking direction is updated by nss_update_connecting_state() */
       return CURLE_AGAIN;
@@ -2138,7 +2155,7 @@
     goto error;
   }
 
-  result = display_conn_info(conn, BACKEND->handle);
+  result = display_conn_info(conn, backend->handle);
   if(result)
     goto error;
 
@@ -2147,7 +2164,7 @@
     char *nickname = dup_nickname(data, SSL_SET_OPTION(issuercert));
     if(nickname) {
       /* we support only nicknames in case of issuercert for now */
-      ret = check_issuer_cert(BACKEND->handle, nickname);
+      ret = check_issuer_cert(backend->handle, nickname);
       free(nickname);
     }
 
@@ -2251,13 +2268,14 @@
                         CURLcode *curlcode)
 {
   struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+  struct ssl_backend_data *backend = connssl->backend;
   ssize_t rc;
 
   /* The SelectClientCert() hook uses this for infof() and failf() but the
      handle stored in nss_setup_connect() could have already been freed. */
-  BACKEND->data = conn->data;
+  backend->data = conn->data;
 
-  rc = PR_Send(BACKEND->handle, mem, (int)len, 0, PR_INTERVAL_NO_WAIT);
+  rc = PR_Send(backend->handle, mem, (int)len, 0, PR_INTERVAL_NO_WAIT);
   if(rc < 0) {
     PRInt32 err = PR_GetError();
     if(err == PR_WOULD_BLOCK_ERROR)
@@ -2288,13 +2306,14 @@
                         CURLcode *curlcode)
 {
   struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+  struct ssl_backend_data *backend = connssl->backend;
   ssize_t nread;
 
   /* The SelectClientCert() hook uses this for infof() and failf() but the
      handle stored in nss_setup_connect() could have already been freed. */
-  BACKEND->data = conn->data;
+  backend->data = conn->data;
 
-  nread = PR_Recv(BACKEND->handle, buf, (int)buffersize, 0,
+  nread = PR_Recv(backend->handle, buf, (int)buffersize, 0,
                   PR_INTERVAL_NO_WAIT);
   if(nread < 0) {
     /* failed SSL read */
@@ -2355,6 +2374,9 @@
   PK11Context *MD5pw = PK11_CreateDigestContext(SEC_OID_MD5);
   unsigned int MD5out;
 
+  if(!MD5pw)
+    return CURLE_NOT_BUILT_IN;
+
   PK11_DigestOp(MD5pw, tmp, curlx_uztoui(tmplen));
   PK11_DigestFinal(MD5pw, md5sum, &MD5out, curlx_uztoui(md5len));
   PK11_DestroyContext(MD5pw, PR_TRUE);
@@ -2370,6 +2392,9 @@
   PK11Context *SHA256pw = PK11_CreateDigestContext(SEC_OID_SHA256);
   unsigned int SHA256out;
 
+  if(!SHA256pw)
+    return CURLE_NOT_BUILT_IN;
+
   PK11_DigestOp(SHA256pw, tmp, curlx_uztoui(tmplen));
   PK11_DigestFinal(SHA256pw, sha256sum, &SHA256out, curlx_uztoui(sha256len));
   PK11_DestroyContext(SHA256pw, PR_TRUE);
@@ -2398,8 +2423,9 @@
 static void *Curl_nss_get_internals(struct ssl_connect_data *connssl,
                                     CURLINFO info UNUSED_PARAM)
 {
+  struct ssl_backend_data *backend = connssl->backend;
   (void)info;
-  return BACKEND->handle;
+  return backend->handle;
 }
 
 const struct Curl_ssl Curl_ssl_nss = {
diff --git a/Utilities/cmcurl/lib/vtls/openssl.c b/Utilities/cmcurl/lib/vtls/openssl.c
index 85e9be6..2e9f900 100644
--- a/Utilities/cmcurl/lib/vtls/openssl.c
+++ b/Utilities/cmcurl/lib/vtls/openssl.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -25,17 +25,17 @@
  * but vtls.c should ever call or use these functions.
  */
 
-/*
- * The original SSLeay-using code for curl was written by Linas Vepstas and
- * Sampo Kellomaki 1998.
- */
-
 #include "curl_setup.h"
 
 #ifdef USE_OPENSSL
 
 #include <limits.h>
 
+/* Wincrypt must be included before anything that could include OpenSSL. */
+#if defined(USE_WIN32_CRYPTO)
+#include <wincrypt.h>
+#endif
+
 #include "urldata.h"
 #include "sendf.h"
 #include "formdata.h" /* for the boundary function */
@@ -46,10 +46,13 @@
 #include "slist.h"
 #include "select.h"
 #include "vtls.h"
+#include "keylog.h"
 #include "strcase.h"
 #include "hostcheck.h"
 #include "multiif.h"
+#include "strerror.h"
 #include "curl_printf.h"
+
 #include <openssl/ssl.h>
 #include <openssl/rand.h>
 #include <openssl/x509v3.h>
@@ -75,7 +78,7 @@
 #endif
 
 #if (OPENSSL_VERSION_NUMBER >= 0x0090700fL) && /* 0.9.7 or later */     \
-  !defined(OPENSSL_NO_ENGINE)
+  !defined(OPENSSL_NO_ENGINE) && !defined(OPENSSL_NO_UI_CONSOLE)
 #define USE_OPENSSL_ENGINE
 #include <openssl/engine.h>
 #endif
@@ -146,16 +149,16 @@
 #endif
 #endif
 
-#ifdef LIBRESSL_VERSION_NUMBER
-#define OpenSSL_version_num() LIBRESSL_VERSION_NUMBER
-#endif
-
 #if (OPENSSL_VERSION_NUMBER >= 0x1000200fL) && /* 1.0.2 or later */ \
     !(defined(LIBRESSL_VERSION_NUMBER) && \
       LIBRESSL_VERSION_NUMBER < 0x20700000L)
 #define HAVE_X509_GET0_SIGNATURE 1
 #endif
 
+#if (OPENSSL_VERSION_NUMBER >= 0x1000200fL) /* 1.0.2 or later */
+#define HAVE_SSL_GET_SHUTDOWN 1
+#endif
+
 #if OPENSSL_VERSION_NUMBER >= 0x10002003L && \
   OPENSSL_VERSION_NUMBER <= 0x10002FFFL && \
   !defined(OPENSSL_NO_COMP)
@@ -211,29 +214,17 @@
   "ALL:!EXPORT:!EXPORT40:!EXPORT56:!aNULL:!LOW:!RC4:@STRENGTH"
 #endif
 
-#define ENABLE_SSLKEYLOGFILE
-
-#ifdef ENABLE_SSLKEYLOGFILE
-typedef struct ssl_tap_state {
-  int master_key_length;
-  unsigned char master_key[SSL_MAX_MASTER_KEY_LENGTH];
-  unsigned char client_random[SSL3_RANDOM_SIZE];
-} ssl_tap_state_t;
-#endif /* ENABLE_SSLKEYLOGFILE */
-
 struct ssl_backend_data {
   /* these ones requires specific SSL-types */
   SSL_CTX* ctx;
   SSL*     handle;
   X509*    server_cert;
-#ifdef ENABLE_SSLKEYLOGFILE
-  /* tap_state holds the last seen master key if we're logging them */
-  ssl_tap_state_t tap_state;
+#ifndef HAVE_KEYLOG_CALLBACK
+  /* Set to true once a valid keylog entry has been created to avoid dupes. */
+  bool     keylog_done;
 #endif
 };
 
-#define BACKEND connssl->backend
-
 /*
  * Number of bytes to read from the random number seed file. This must be
  * a finite value (because some entropy "files" like /dev/urandom have
@@ -242,57 +233,27 @@
  */
 #define RAND_LOAD_LENGTH 1024
 
-#ifdef ENABLE_SSLKEYLOGFILE
-/* The fp for the open SSLKEYLOGFILE, or NULL if not open */
-static FILE *keylog_file_fp;
-
 #ifdef HAVE_KEYLOG_CALLBACK
 static void ossl_keylog_callback(const SSL *ssl, const char *line)
 {
   (void)ssl;
 
-  /* Using fputs here instead of fprintf since libcurl's fprintf replacement
-     may not be thread-safe. */
-  if(keylog_file_fp && line && *line) {
-    char stackbuf[256];
-    char *buf;
-    size_t linelen = strlen(line);
-
-    if(linelen <= sizeof(stackbuf) - 2)
-      buf = stackbuf;
-    else {
-      buf = malloc(linelen + 2);
-      if(!buf)
-        return;
-    }
-    memcpy(buf, line, linelen);
-    buf[linelen] = '\n';
-    buf[linelen + 1] = '\0';
-
-    fputs(buf, keylog_file_fp);
-    if(buf != stackbuf)
-      free(buf);
-  }
+  Curl_tls_keylog_write_line(line);
 }
 #else
-#define KEYLOG_PREFIX      "CLIENT_RANDOM "
-#define KEYLOG_PREFIX_LEN  (sizeof(KEYLOG_PREFIX) - 1)
 /*
- * tap_ssl_key is called by libcurl to make the CLIENT_RANDOMs if the OpenSSL
- * being used doesn't have native support for doing that.
+ * ossl_log_tls12_secret is called by libcurl to make the CLIENT_RANDOMs if the
+ * OpenSSL being used doesn't have native support for doing that.
  */
-static void tap_ssl_key(const SSL *ssl, ssl_tap_state_t *state)
+static void
+ossl_log_tls12_secret(const SSL *ssl, bool *keylog_done)
 {
-  const char *hex = "0123456789ABCDEF";
-  int pos, i;
-  char line[KEYLOG_PREFIX_LEN + 2 * SSL3_RANDOM_SIZE + 1 +
-            2 * SSL_MAX_MASTER_KEY_LENGTH + 1 + 1];
   const SSL_SESSION *session = SSL_get_session(ssl);
   unsigned char client_random[SSL3_RANDOM_SIZE];
   unsigned char master_key[SSL_MAX_MASTER_KEY_LENGTH];
   int master_key_length = 0;
 
-  if(!session || !keylog_file_fp)
+  if(!session || *keylog_done)
     return;
 
 #if OPENSSL_VERSION_NUMBER >= 0x10100000L && \
@@ -311,44 +272,17 @@
   }
 #endif
 
+  /* The handshake has not progressed sufficiently yet, or this is a TLS 1.3
+   * session (when curl was built with older OpenSSL headers and running with
+   * newer OpenSSL runtime libraries). */
   if(master_key_length <= 0)
     return;
 
-  /* Skip writing keys if there is no key or it did not change. */
-  if(state->master_key_length == master_key_length &&
-     !memcmp(state->master_key, master_key, master_key_length) &&
-     !memcmp(state->client_random, client_random, SSL3_RANDOM_SIZE)) {
-    return;
-  }
-
-  state->master_key_length = master_key_length;
-  memcpy(state->master_key, master_key, master_key_length);
-  memcpy(state->client_random, client_random, SSL3_RANDOM_SIZE);
-
-  memcpy(line, KEYLOG_PREFIX, KEYLOG_PREFIX_LEN);
-  pos = KEYLOG_PREFIX_LEN;
-
-  /* Client Random for SSLv3/TLS */
-  for(i = 0; i < SSL3_RANDOM_SIZE; i++) {
-    line[pos++] = hex[client_random[i] >> 4];
-    line[pos++] = hex[client_random[i] & 0xF];
-  }
-  line[pos++] = ' ';
-
-  /* Master Secret (size is at most SSL_MAX_MASTER_KEY_LENGTH) */
-  for(i = 0; i < master_key_length; i++) {
-    line[pos++] = hex[master_key[i] >> 4];
-    line[pos++] = hex[master_key[i] & 0xF];
-  }
-  line[pos++] = '\n';
-  line[pos] = '\0';
-
-  /* Using fputs here instead of fprintf since libcurl's fprintf replacement
-     may not be thread-safe. */
-  fputs(line, keylog_file_fp);
+  *keylog_done = true;
+  Curl_tls_keylog_write("CLIENT_RANDOM", client_random,
+                        master_key, master_key_length);
 }
 #endif /* !HAVE_KEYLOG_CALLBACK */
-#endif /* ENABLE_SSLKEYLOGFILE */
 
 static const char *SSL_ERROR_to_str(int err)
 {
@@ -392,7 +326,20 @@
  */
 static char *ossl_strerror(unsigned long error, char *buf, size_t size)
 {
+  if(size)
+    *buf = '\0';
+
+#ifdef OPENSSL_IS_BORINGSSL
+  ERR_error_string_n((uint32_t)error, buf, size);
+#else
   ERR_error_string_n(error, buf, size);
+#endif
+
+  if(size > 1 && !*buf) {
+    strncpy(buf, (error ? "Unknown error" : "No error"), size);
+    buf[size - 1] = '\0';
+  }
+
   return buf;
 }
 
@@ -609,12 +556,136 @@
 static CURLcode Curl_ossl_set_engine(struct Curl_easy *data,
                                      const char *engine);
 
+static int
+SSL_CTX_use_certificate_bio(SSL_CTX *ctx, BIO *in, int type,
+                            const char *key_passwd)
+{
+  int ret = 0;
+  X509 *x = NULL;
+
+  if(type == SSL_FILETYPE_ASN1) {
+    /* j = ERR_R_ASN1_LIB; */
+    x = d2i_X509_bio(in, NULL);
+  }
+  else if(type == SSL_FILETYPE_PEM) {
+    /* ERR_R_PEM_LIB; */
+    x = PEM_read_bio_X509(in, NULL,
+                          passwd_callback, (void *)key_passwd);
+  }
+  else {
+    ret = 0;
+    goto end;
+  }
+
+  if(x == NULL) {
+    ret = 0;
+    goto end;
+  }
+
+  ret = SSL_CTX_use_certificate(ctx, x);
+ end:
+  X509_free(x);
+  return ret;
+}
+
+static int
+SSL_CTX_use_PrivateKey_bio(SSL_CTX *ctx, BIO* in, int type,
+                           const char *key_passwd)
+{
+  int ret = 0;
+  EVP_PKEY *pkey = NULL;
+
+  if(type == SSL_FILETYPE_PEM)
+    pkey = PEM_read_bio_PrivateKey(in, NULL, passwd_callback,
+                                   (void *)key_passwd);
+  else if(type == SSL_FILETYPE_ASN1)
+    pkey = d2i_PrivateKey_bio(in, NULL);
+  else {
+    ret = 0;
+    goto end;
+  }
+  if(pkey == NULL) {
+    ret = 0;
+    goto end;
+  }
+  ret = SSL_CTX_use_PrivateKey(ctx, pkey);
+  EVP_PKEY_free(pkey);
+  end:
+  return ret;
+}
+
+static int
+SSL_CTX_use_certificate_chain_bio(SSL_CTX *ctx, BIO* in,
+                                  const char *key_passwd)
+{
+/* SSL_CTX_add1_chain_cert introduced in OpenSSL 1.0.2 */
+#if (OPENSSL_VERSION_NUMBER >= 0x1000200fL) /* 1.0.2 or later */
+  int ret = 0;
+  X509 *x = NULL;
+  void *passwd_callback_userdata = (void *)key_passwd;
+
+  ERR_clear_error();
+
+  x = PEM_read_bio_X509_AUX(in, NULL,
+                            passwd_callback, (void *)key_passwd);
+
+  if(x == NULL) {
+    ret = 0;
+    goto end;
+  }
+
+  ret = SSL_CTX_use_certificate(ctx, x);
+
+  if(ERR_peek_error() != 0)
+      ret = 0;
+
+  if(ret) {
+    X509 *ca;
+    unsigned long err;
+
+    if(!SSL_CTX_clear_chain_certs(ctx)) {
+      ret = 0;
+      goto end;
+    }
+
+    while((ca = PEM_read_bio_X509(in, NULL, passwd_callback,
+                                  passwd_callback_userdata))
+          != NULL) {
+
+      if(!SSL_CTX_add0_chain_cert(ctx, ca)) {
+        X509_free(ca);
+        ret = 0;
+        goto end;
+      }
+    }
+
+    err = ERR_peek_last_error();
+    if((ERR_GET_LIB(err) == ERR_LIB_PEM) &&
+       (ERR_GET_REASON(err) == PEM_R_NO_START_LINE))
+      ERR_clear_error();
+    else
+      ret = 0;
+  }
+
+ end:
+  X509_free(x);
+  return ret;
+#else
+  (void)ctx; /* unused */
+  (void)in; /* unused */
+  (void)key_passwd; /* unused */
+  return 0;
+#endif
+}
+
 static
 int cert_stuff(struct connectdata *conn,
                SSL_CTX* ctx,
                char *cert_file,
+               BIO *cert_bio,
                const char *cert_type,
                char *key_file,
+               BIO* key_bio,
                const char *key_type,
                char *key_passwd)
 {
@@ -624,10 +695,11 @@
 
   int file_type = do_file_type(cert_type);
 
-  if(cert_file || (file_type == SSL_FILETYPE_ENGINE)) {
+  if(cert_file || cert_bio || (file_type == SSL_FILETYPE_ENGINE)) {
     SSL *ssl;
     X509 *x509;
     int cert_done = 0;
+    int cert_use_result;
 
     if(key_passwd) {
       /* set the password in the callback userdata */
@@ -640,8 +712,10 @@
     switch(file_type) {
     case SSL_FILETYPE_PEM:
       /* SSL_CTX_use_certificate_chain_file() only works on PEM files */
-      if(SSL_CTX_use_certificate_chain_file(ctx,
-                                            cert_file) != 1) {
+      cert_use_result = cert_bio ?
+          SSL_CTX_use_certificate_chain_bio(ctx, cert_bio, key_passwd) :
+          SSL_CTX_use_certificate_chain_file(ctx, cert_file);
+      if(cert_use_result != 1) {
         failf(data,
               "could not load PEM client certificate, " OSSL_PACKAGE
               " error %s, "
@@ -656,9 +730,12 @@
       /* SSL_CTX_use_certificate_file() works with either PEM or ASN1, but
          we use the case above for PEM so this can only be performed with
          ASN1 files. */
-      if(SSL_CTX_use_certificate_file(ctx,
-                                      cert_file,
-                                      file_type) != 1) {
+
+      cert_use_result = cert_bio ?
+          SSL_CTX_use_certificate_bio(ctx, cert_bio,
+                                      file_type, key_passwd) :
+          SSL_CTX_use_certificate_file(ctx, cert_file, file_type);
+      if(cert_use_result != 1) {
         failf(data,
               "could not load ASN1 client certificate, " OSSL_PACKAGE
               " error %s, "
@@ -738,27 +815,31 @@
       PKCS12 *p12 = NULL;
       EVP_PKEY *pri;
       STACK_OF(X509) *ca = NULL;
+      if(!cert_bio) {
+        fp = BIO_new(BIO_s_file());
+        if(fp == NULL) {
+          failf(data,
+                "BIO_new return NULL, " OSSL_PACKAGE
+                " error %s",
+                ossl_strerror(ERR_get_error(), error_buffer,
+                              sizeof(error_buffer)) );
+          return 0;
+        }
 
-      fp = BIO_new(BIO_s_file());
-      if(fp == NULL) {
-        failf(data,
-              "BIO_new return NULL, " OSSL_PACKAGE
-              " error %s",
-              ossl_strerror(ERR_get_error(), error_buffer,
-                            sizeof(error_buffer)) );
-        return 0;
+        if(BIO_read_filename(fp, cert_file) <= 0) {
+          failf(data, "could not open PKCS12 file '%s'", cert_file);
+          BIO_free(fp);
+          return 0;
+        }
       }
 
-      if(BIO_read_filename(fp, cert_file) <= 0) {
-        failf(data, "could not open PKCS12 file '%s'", cert_file);
+      p12 = d2i_PKCS12_bio(cert_bio ? cert_bio : fp, NULL);
+      if(fp)
         BIO_free(fp);
-        return 0;
-      }
-      p12 = d2i_PKCS12_bio(fp, NULL);
-      BIO_free(fp);
 
       if(!p12) {
-        failf(data, "error reading PKCS12 file '%s'", cert_file);
+        failf(data, "error reading PKCS12 file '%s'",
+              cert_bio ? "(memory blob)" : cert_file);
         return 0;
       }
 
@@ -839,8 +920,10 @@
       return 0;
     }
 
-    if(!key_file)
+    if((!key_file) && (!key_bio)) {
       key_file = cert_file;
+      key_bio = cert_bio;
+    }
     else
       file_type = do_file_type(key_type);
 
@@ -850,9 +933,12 @@
         break;
       /* FALLTHROUGH */
     case SSL_FILETYPE_ASN1:
-      if(SSL_CTX_use_PrivateKey_file(ctx, key_file, file_type) != 1) {
+      cert_use_result = key_bio ?
+        SSL_CTX_use_PrivateKey_bio(ctx, key_bio, file_type, key_passwd) :
+        SSL_CTX_use_PrivateKey_file(ctx, key_file, file_type);
+      if(cert_use_result != 1) {
         failf(data, "unable to set private key file: '%s' type %s",
-              key_file, key_type?key_type:"PEM");
+              key_file?key_file:"(memory blob)", key_type?key_type:"PEM");
         return 0;
       }
       break;
@@ -1012,24 +1098,14 @@
  */
 static int Curl_ossl_init(void)
 {
-#ifdef ENABLE_SSLKEYLOGFILE
-  char *keylog_file_name;
-#endif
-
   OPENSSL_load_builtin_modules();
 
 #ifdef USE_OPENSSL_ENGINE
   ENGINE_load_builtin_engines();
 #endif
 
-  /* OPENSSL_config(NULL); is "strongly recommended" to use but unfortunately
-     that function makes an exit() call on wrongly formatted config files
-     which makes it hard to use in some situations. OPENSSL_config() itself
-     calls CONF_modules_load_file() and we use that instead and we ignore
-     its return code! */
-
-  /* CONF_MFLAGS_DEFAULT_SECTION introduced some time between 0.9.8b and
-     0.9.8e */
+/* CONF_MFLAGS_DEFAULT_SECTION was introduced some time between 0.9.8b and
+   0.9.8e */
 #ifndef CONF_MFLAGS_DEFAULT_SECTION
 #define CONF_MFLAGS_DEFAULT_SECTION 0x0
 #endif
@@ -1054,26 +1130,7 @@
   OpenSSL_add_all_algorithms();
 #endif
 
-#ifdef ENABLE_SSLKEYLOGFILE
-  if(!keylog_file_fp) {
-    keylog_file_name = curl_getenv("SSLKEYLOGFILE");
-    if(keylog_file_name) {
-      keylog_file_fp = fopen(keylog_file_name, FOPEN_APPENDTEXT);
-      if(keylog_file_fp) {
-#ifdef WIN32
-        if(setvbuf(keylog_file_fp, NULL, _IONBF, 0))
-#else
-        if(setvbuf(keylog_file_fp, NULL, _IOLBF, 4096))
-#endif
-        {
-          fclose(keylog_file_fp);
-          keylog_file_fp = NULL;
-        }
-      }
-      Curl_safefree(keylog_file_name);
-    }
-  }
-#endif
+  Curl_tls_keylog_open();
 
   /* Initialize the extra data indexes */
   if(ossl_get_ssl_conn_index() < 0 || ossl_get_ssl_sockindex_index() < 0)
@@ -1116,12 +1173,7 @@
 #endif
 #endif
 
-#ifdef ENABLE_SSLKEYLOGFILE
-  if(keylog_file_fp) {
-    fclose(keylog_file_fp);
-    keylog_file_fp = NULL;
-  }
-#endif
+  Curl_tls_keylog_close();
 }
 
 /*
@@ -1266,19 +1318,19 @@
   return list;
 }
 
-
 static void ossl_close(struct ssl_connect_data *connssl)
 {
-  if(BACKEND->handle) {
-    (void)SSL_shutdown(BACKEND->handle);
-    SSL_set_connect_state(BACKEND->handle);
+  struct ssl_backend_data *backend = connssl->backend;
+  if(backend->handle) {
+    (void)SSL_shutdown(backend->handle);
+    SSL_set_connect_state(backend->handle);
 
-    SSL_free(BACKEND->handle);
-    BACKEND->handle = NULL;
+    SSL_free(backend->handle);
+    backend->handle = NULL;
   }
-  if(BACKEND->ctx) {
-    SSL_CTX_free(BACKEND->ctx);
-    BACKEND->ctx = NULL;
+  if(backend->ctx) {
+    SSL_CTX_free(backend->ctx);
+    backend->ctx = NULL;
   }
 }
 
@@ -1288,7 +1340,9 @@
 static void Curl_ossl_close(struct connectdata *conn, int sockindex)
 {
   ossl_close(&conn->ssl[sockindex]);
+#ifndef CURL_DISABLE_PROXY
   ossl_close(&conn->proxy_ssl[sockindex]);
+#endif
 }
 
 /*
@@ -1307,6 +1361,7 @@
   int buffsize;
   int err;
   bool done = FALSE;
+  struct ssl_backend_data *backend = connssl->backend;
 
 #ifndef CURL_DISABLE_FTP
   /* This has only been tested on the proftpd server, and the mod_tls code
@@ -1315,10 +1370,10 @@
      we do not send one. Let's hope other servers do the same... */
 
   if(data->set.ftp_ccc == CURLFTPSSL_CCC_ACTIVE)
-      (void)SSL_shutdown(BACKEND->handle);
+      (void)SSL_shutdown(backend->handle);
 #endif
 
-  if(BACKEND->handle) {
+  if(backend->handle) {
     buffsize = (int)sizeof(buf);
     while(!done) {
       int what = SOCKET_READABLE(conn->sock[sockindex],
@@ -1328,8 +1383,8 @@
 
         /* Something to read, let's do it and hope that it is the close
            notify alert from the server */
-        nread = (ssize_t)SSL_read(BACKEND->handle, buf, buffsize);
-        err = SSL_get_error(BACKEND->handle, (int)nread);
+        nread = (ssize_t)SSL_read(backend->handle, buf, buffsize);
+        err = SSL_get_error(backend->handle, (int)nread);
 
         switch(err) {
         case SSL_ERROR_NONE: /* this is not an error */
@@ -1374,7 +1429,7 @@
 
     if(data->set.verbose) {
 #ifdef HAVE_SSL_GET_SHUTDOWN
-      switch(SSL_get_shutdown(BACKEND->handle)) {
+      switch(SSL_get_shutdown(backend->handle)) {
       case SSL_SENT_SHUTDOWN:
         infof(data, "SSL_get_shutdown() returned SSL_SENT_SHUTDOWN\n");
         break;
@@ -1389,8 +1444,8 @@
 #endif
     }
 
-    SSL_free(BACKEND->handle);
-    BACKEND->handle = NULL;
+    SSL_free(backend->handle);
+    backend->handle = NULL;
   }
   return retval;
 }
@@ -1514,10 +1569,16 @@
   CURLcode result = CURLE_OK;
   bool dNSName = FALSE; /* if a dNSName field exists in the cert */
   bool iPAddress = FALSE; /* if a iPAddress field exists in the cert */
-  const char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name :
-    conn->host.name;
+#ifndef CURL_DISABLE_PROXY
+  const char * const hostname = SSL_IS_PROXY() ?
+    conn->http_proxy.host.name : conn->host.name;
   const char * const dispname = SSL_IS_PROXY() ?
     conn->http_proxy.host.dispname : conn->host.dispname;
+#else
+  /* disabled proxy support */
+  const char * const hostname = conn->host.name;
+  const char * const dispname = conn->host.dispname;
+#endif
 
 #ifdef ENABLE_IPV6
   if(conn->bits.ipv6_ip &&
@@ -1536,8 +1597,13 @@
   altnames = X509_get_ext_d2i(server_cert, NID_subject_alt_name, NULL, NULL);
 
   if(altnames) {
+#ifdef OPENSSL_IS_BORINGSSL
+    size_t numalts;
+    size_t i;
+#else
     int numalts;
     int i;
+#endif
     bool dnsmatched = FALSE;
     bool ipmatched = FALSE;
 
@@ -1567,11 +1633,10 @@
              assumed that the data returned by ASN1_STRING_data() is null
              terminated or does not contain embedded nulls." But also that
              "The actual format of the data will depend on the actual string
-             type itself: for example for and IA5String the data will be ASCII"
+             type itself: for example for an IA5String the data will be ASCII"
 
-             Gisle researched the OpenSSL sources:
-             "I checked the 0.9.6 and 0.9.8 sources before my patch and
-             it always 0-terminates an IA5String."
+             It has been however verified that in 0.9.6 and 0.9.7, IA5String
+             is always null-terminated.
           */
           if((altlen == strlen(altptr)) &&
              /* if this isn't true, there was an embedded zero in the name
@@ -1635,8 +1700,7 @@
       /* In OpenSSL 0.9.7d and earlier, ASN1_STRING_to_UTF8 fails if the input
          is already UTF-8 encoded. We check for this case and copy the raw
          string manually to avoid the problem. This code can be made
-         conditional in the future when OpenSSL has been fixed. Work-around
-         brought by Alexis S. L. Carvalho. */
+         conditional in the future when OpenSSL has been fixed. */
       if(tmp) {
         if(ASN1_STRING_type(tmp) == V_ASN1_UTF8STRING) {
           j = ASN1_STRING_length(tmp);
@@ -1706,13 +1770,13 @@
   const unsigned char *p;
   CURLcode result = CURLE_OK;
   struct Curl_easy *data = conn->data;
-
   OCSP_RESPONSE *rsp = NULL;
   OCSP_BASICRESP *br = NULL;
   X509_STORE     *st = NULL;
   STACK_OF(X509) *ch = NULL;
+  struct ssl_backend_data *backend = connssl->backend;
 
-  long len = SSL_get_tlsext_status_ocsp_resp(BACKEND->handle, &status);
+  long len = SSL_get_tlsext_status_ocsp_resp(backend->handle, &status);
 
   if(!status) {
     failf(data, "No OCSP response received");
@@ -1742,8 +1806,8 @@
     goto end;
   }
 
-  ch = SSL_get_peer_cert_chain(BACKEND->handle);
-  st = SSL_CTX_get_cert_store(BACKEND->ctx);
+  ch = SSL_get_peer_cert_chain(backend->handle);
+  st = SSL_CTX_get_cert_store(backend->ctx);
 
 #if ((OPENSSL_VERSION_NUMBER <= 0x1000201fL) /* Fixed after 1.0.2a */ || \
      (defined(LIBRESSL_VERSION_NUMBER) &&                               \
@@ -1819,7 +1883,8 @@
   }
 
 end:
-  if(br) OCSP_BASICRESP_free(br);
+  if(br)
+    OCSP_BASICRESP_free(br);
   OCSP_RESPONSE_free(rsp);
 
   return result;
@@ -2156,9 +2221,100 @@
 }
 #endif
 
+#if (OPENSSL_VERSION_NUMBER >= 0x10100000L) /* 1.1.0 */
 static CURLcode
-set_ssl_version_min_max(long *ctx_options, struct connectdata *conn,
-                        int sockindex)
+set_ssl_version_min_max(SSL_CTX *ctx, struct connectdata *conn)
+{
+  /* first, TLS min version... */
+  long curl_ssl_version_min = SSL_CONN_CONFIG(version);
+  long curl_ssl_version_max;
+
+  /* convert cURL min SSL version option to OpenSSL constant */
+#if defined(OPENSSL_IS_BORINGSSL) || defined(LIBRESSL_VERSION_NUMBER)
+  uint16_t ossl_ssl_version_min = 0;
+  uint16_t ossl_ssl_version_max = 0;
+#else
+  long ossl_ssl_version_min = 0;
+  long ossl_ssl_version_max = 0;
+#endif
+  switch(curl_ssl_version_min) {
+    case CURL_SSLVERSION_TLSv1: /* TLS 1.x */
+    case CURL_SSLVERSION_TLSv1_0:
+      ossl_ssl_version_min = TLS1_VERSION;
+      break;
+    case CURL_SSLVERSION_TLSv1_1:
+      ossl_ssl_version_min = TLS1_1_VERSION;
+      break;
+    case CURL_SSLVERSION_TLSv1_2:
+      ossl_ssl_version_min = TLS1_2_VERSION;
+      break;
+#ifdef TLS1_3_VERSION
+    case CURL_SSLVERSION_TLSv1_3:
+      ossl_ssl_version_min = TLS1_3_VERSION;
+      break;
+#endif
+  }
+
+  /* CURL_SSLVERSION_DEFAULT means that no option was selected.
+     We don't want to pass 0 to SSL_CTX_set_min_proto_version as
+     it would enable all versions down to the lowest supported by
+     the library.
+     So we skip this, and stay with the OS default
+  */
+  if(curl_ssl_version_min != CURL_SSLVERSION_DEFAULT) {
+    if(!SSL_CTX_set_min_proto_version(ctx, ossl_ssl_version_min)) {
+      return CURLE_SSL_CONNECT_ERROR;
+    }
+  }
+
+  /* ... then, TLS max version */
+  curl_ssl_version_max = SSL_CONN_CONFIG(version_max);
+
+  /* convert cURL max SSL version option to OpenSSL constant */
+  switch(curl_ssl_version_max) {
+    case CURL_SSLVERSION_MAX_TLSv1_0:
+      ossl_ssl_version_max = TLS1_VERSION;
+      break;
+    case CURL_SSLVERSION_MAX_TLSv1_1:
+      ossl_ssl_version_max = TLS1_1_VERSION;
+      break;
+    case CURL_SSLVERSION_MAX_TLSv1_2:
+      ossl_ssl_version_max = TLS1_2_VERSION;
+      break;
+#ifdef TLS1_3_VERSION
+    case CURL_SSLVERSION_MAX_TLSv1_3:
+      ossl_ssl_version_max = TLS1_3_VERSION;
+      break;
+#endif
+    case CURL_SSLVERSION_MAX_NONE:  /* none selected */
+    case CURL_SSLVERSION_MAX_DEFAULT:  /* max selected */
+    default:
+      /* SSL_CTX_set_max_proto_version states that:
+        setting the maximum to 0 will enable
+        protocol versions up to the highest version
+        supported by the library */
+      ossl_ssl_version_max = 0;
+      break;
+  }
+
+  if(!SSL_CTX_set_max_proto_version(ctx, ossl_ssl_version_max)) {
+    return CURLE_SSL_CONNECT_ERROR;
+  }
+
+  return CURLE_OK;
+}
+#endif
+
+#ifdef OPENSSL_IS_BORINGSSL
+typedef uint32_t ctx_option_t;
+#else
+typedef long ctx_option_t;
+#endif
+
+#if (OPENSSL_VERSION_NUMBER < 0x10100000L) /* 1.1.0 */
+static CURLcode
+set_ssl_version_min_max_legacy(ctx_option_t *ctx_options,
+                              struct connectdata *conn, int sockindex)
 {
 #if (OPENSSL_VERSION_NUMBER < 0x1000100FL) || !defined(TLS1_3_VERSION)
   /* convoluted #if condition just to avoid compiler warnings on unused
@@ -2173,7 +2329,7 @@
 #ifdef TLS1_3_VERSION
     {
       struct ssl_connect_data *connssl = &conn->ssl[sockindex];
-      SSL_CTX_set_max_proto_version(BACKEND->ctx, TLS1_3_VERSION);
+      SSL_CTX_set_max_proto_version(backend->ctx, TLS1_3_VERSION);
       *ctx_options |= SSL_OP_NO_TLSv1_2;
     }
 #else
@@ -2230,6 +2386,7 @@
   }
   return CURLE_OK;
 }
+#endif
 
 /* The "new session" callback must return zero if the session can be removed
  * or non-zero if the session has been put into the session cache.
@@ -2296,30 +2453,43 @@
   X509_LOOKUP *lookup = NULL;
   curl_socket_t sockfd = conn->sock[sockindex];
   struct ssl_connect_data *connssl = &conn->ssl[sockindex];
-  long ctx_options = 0;
+  ctx_option_t ctx_options = 0;
+
 #ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
   bool sni;
+#ifndef CURL_DISABLE_PROXY
   const char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name :
     conn->host.name;
+#else
+  const char * const hostname = conn->host.name;
+#endif
+
 #ifdef ENABLE_IPV6
   struct in6_addr addr;
 #else
   struct in_addr addr;
 #endif
 #endif
+#ifndef CURL_DISABLE_PROXY
   long * const certverifyresult = SSL_IS_PROXY() ?
     &data->set.proxy_ssl.certverifyresult : &data->set.ssl.certverifyresult;
+#else
+  long * const certverifyresult = &data->set.ssl.certverifyresult;
+#endif
   const long int ssl_version = SSL_CONN_CONFIG(version);
 #ifdef USE_TLS_SRP
   const enum CURL_TLSAUTH ssl_authtype = SSL_SET_OPTION(authtype);
 #endif
   char * const ssl_cert = SSL_SET_OPTION(cert);
+  const struct curl_blob *ssl_cert_blob = SSL_SET_OPTION(cert_blob);
   const char * const ssl_cert_type = SSL_SET_OPTION(cert_type);
   const char * const ssl_cafile = SSL_CONN_CONFIG(CAfile);
   const char * const ssl_capath = SSL_CONN_CONFIG(CApath);
   const bool verifypeer = SSL_CONN_CONFIG(verifypeer);
   const char * const ssl_crlfile = SSL_SET_OPTION(CRLfile);
   char error_buffer[256];
+  struct ssl_backend_data *backend = connssl->backend;
+  bool imported_native_ca = false;
 
   DEBUGASSERT(ssl_connect_1 == connssl->connecting_state);
 
@@ -2378,25 +2548,25 @@
     return CURLE_SSL_CONNECT_ERROR;
   }
 
-  if(BACKEND->ctx)
-    SSL_CTX_free(BACKEND->ctx);
-  BACKEND->ctx = SSL_CTX_new(req_method);
+  if(backend->ctx)
+    SSL_CTX_free(backend->ctx);
+  backend->ctx = SSL_CTX_new(req_method);
 
-  if(!BACKEND->ctx) {
+  if(!backend->ctx) {
     failf(data, "SSL: couldn't create a context: %s",
           ossl_strerror(ERR_peek_error(), error_buffer, sizeof(error_buffer)));
     return CURLE_OUT_OF_MEMORY;
   }
 
 #ifdef SSL_MODE_RELEASE_BUFFERS
-  SSL_CTX_set_mode(BACKEND->ctx, SSL_MODE_RELEASE_BUFFERS);
+  SSL_CTX_set_mode(backend->ctx, SSL_MODE_RELEASE_BUFFERS);
 #endif
 
 #ifdef SSL_CTRL_SET_MSG_CALLBACK
   if(data->set.fdebug && data->set.verbose) {
     /* the SSL trace callback is only used for verbose logging */
-    SSL_CTX_set_msg_callback(BACKEND->ctx, ssl_tls_trace);
-    SSL_CTX_set_msg_callback_arg(BACKEND->ctx, conn);
+    SSL_CTX_set_msg_callback(backend->ctx, ssl_tls_trace);
+    SSL_CTX_set_msg_callback_arg(backend->ctx, conn);
   }
 #endif
 
@@ -2459,55 +2629,73 @@
 #endif
 
   switch(ssl_version) {
-  case CURL_SSLVERSION_SSLv3:
-    ctx_options |= SSL_OP_NO_SSLv2;
-    ctx_options |= SSL_OP_NO_TLSv1;
-#if OPENSSL_VERSION_NUMBER >= 0x1000100FL
-    ctx_options |= SSL_OP_NO_TLSv1_1;
-    ctx_options |= SSL_OP_NO_TLSv1_2;
-#ifdef TLS1_3_VERSION
-    ctx_options |= SSL_OP_NO_TLSv1_3;
+    /* "--sslv2" option means SSLv2 only, disable all others */
+    case CURL_SSLVERSION_SSLv2:
+#if OPENSSL_VERSION_NUMBER >= 0x10100000L /* 1.1.0 */
+      SSL_CTX_set_min_proto_version(backend->ctx, SSL2_VERSION);
+      SSL_CTX_set_max_proto_version(backend->ctx, SSL2_VERSION);
+#else
+      ctx_options |= SSL_OP_NO_SSLv3;
+      ctx_options |= SSL_OP_NO_TLSv1;
+#  if OPENSSL_VERSION_NUMBER >= 0x1000100FL
+      ctx_options |= SSL_OP_NO_TLSv1_1;
+      ctx_options |= SSL_OP_NO_TLSv1_2;
+#    ifdef TLS1_3_VERSION
+      ctx_options |= SSL_OP_NO_TLSv1_3;
+#    endif
+#  endif
 #endif
-#endif
-    break;
+      break;
 
-  case CURL_SSLVERSION_DEFAULT:
-  case CURL_SSLVERSION_TLSv1:
-  case CURL_SSLVERSION_TLSv1_0:
-  case CURL_SSLVERSION_TLSv1_1:
-  case CURL_SSLVERSION_TLSv1_2:
-  case CURL_SSLVERSION_TLSv1_3:
-    /* asking for any TLS version as the minimum, means no SSL versions
-       allowed */
-    ctx_options |= SSL_OP_NO_SSLv2;
-    ctx_options |= SSL_OP_NO_SSLv3;
-    result = set_ssl_version_min_max(&ctx_options, conn, sockindex);
-    if(result != CURLE_OK)
-       return result;
-    break;
-
-  case CURL_SSLVERSION_SSLv2:
-    ctx_options |= SSL_OP_NO_SSLv3;
-    ctx_options |= SSL_OP_NO_TLSv1;
-#if OPENSSL_VERSION_NUMBER >= 0x1000100FL
-    ctx_options |= SSL_OP_NO_TLSv1_1;
-    ctx_options |= SSL_OP_NO_TLSv1_2;
-#ifdef TLS1_3_VERSION
-    ctx_options |= SSL_OP_NO_TLSv1_3;
+    /* "--sslv3" option means SSLv3 only, disable all others */
+    case CURL_SSLVERSION_SSLv3:
+#if OPENSSL_VERSION_NUMBER >= 0x10100000L /* 1.1.0 */
+      SSL_CTX_set_min_proto_version(backend->ctx, SSL3_VERSION);
+      SSL_CTX_set_max_proto_version(backend->ctx, SSL3_VERSION);
+#else
+      ctx_options |= SSL_OP_NO_SSLv2;
+      ctx_options |= SSL_OP_NO_TLSv1;
+#  if OPENSSL_VERSION_NUMBER >= 0x1000100FL
+      ctx_options |= SSL_OP_NO_TLSv1_1;
+      ctx_options |= SSL_OP_NO_TLSv1_2;
+#    ifdef TLS1_3_VERSION
+      ctx_options |= SSL_OP_NO_TLSv1_3;
+#    endif
+#  endif
 #endif
-#endif
-    break;
+      break;
 
-  default:
-    failf(data, "Unrecognized parameter passed via CURLOPT_SSLVERSION");
-    return CURLE_SSL_CONNECT_ERROR;
+    /* "--tlsv<x.y>" options mean TLS >= version <x.y> */
+    case CURL_SSLVERSION_DEFAULT:
+    case CURL_SSLVERSION_TLSv1: /* TLS >= version 1.0 */
+    case CURL_SSLVERSION_TLSv1_0: /* TLS >= version 1.0 */
+    case CURL_SSLVERSION_TLSv1_1: /* TLS >= version 1.1 */
+    case CURL_SSLVERSION_TLSv1_2: /* TLS >= version 1.2 */
+    case CURL_SSLVERSION_TLSv1_3: /* TLS >= version 1.3 */
+      /* asking for any TLS version as the minimum, means no SSL versions
+        allowed */
+      ctx_options |= SSL_OP_NO_SSLv2;
+      ctx_options |= SSL_OP_NO_SSLv3;
+
+#if (OPENSSL_VERSION_NUMBER >= 0x10100000L) /* 1.1.0 */
+      result = set_ssl_version_min_max(backend->ctx, conn);
+#else
+      result = set_ssl_version_min_max_legacy(&ctx_options, conn, sockindex);
+#endif
+      if(result != CURLE_OK)
+        return result;
+      break;
+
+    default:
+      failf(data, "Unrecognized parameter passed via CURLOPT_SSLVERSION");
+      return CURLE_SSL_CONNECT_ERROR;
   }
 
-  SSL_CTX_set_options(BACKEND->ctx, ctx_options);
+  SSL_CTX_set_options(backend->ctx, ctx_options);
 
 #ifdef HAS_NPN
   if(conn->bits.tls_enable_npn)
-    SSL_CTX_set_next_proto_select_cb(BACKEND->ctx, select_next_proto_cb, conn);
+    SSL_CTX_set_next_proto_select_cb(backend->ctx, select_next_proto_cb, conn);
 #endif
 
 #ifdef HAS_ALPN
@@ -2516,8 +2704,11 @@
     unsigned char protocols[128];
 
 #ifdef USE_NGHTTP2
-    if(data->set.httpversion >= CURL_HTTP_VERSION_2 &&
-       (!SSL_IS_PROXY() || !conn->bits.tunnel_proxy)) {
+    if(data->set.httpversion >= CURL_HTTP_VERSION_2
+#ifndef CURL_DISABLE_PROXY
+       && (!SSL_IS_PROXY() || !conn->bits.tunnel_proxy)
+#endif
+      ) {
       protocols[cur++] = NGHTTP2_PROTO_VERSION_ID_LEN;
 
       memcpy(&protocols[cur], NGHTTP2_PROTO_VERSION_ID,
@@ -2535,14 +2726,37 @@
     /* expects length prefixed preference ordered list of protocols in wire
      * format
      */
-    SSL_CTX_set_alpn_protos(BACKEND->ctx, protocols, cur);
+    SSL_CTX_set_alpn_protos(backend->ctx, protocols, cur);
   }
 #endif
 
-  if(ssl_cert || ssl_cert_type) {
-    if(!cert_stuff(conn, BACKEND->ctx, ssl_cert, ssl_cert_type,
-                   SSL_SET_OPTION(key), SSL_SET_OPTION(key_type),
-                   SSL_SET_OPTION(key_passwd))) {
+  if(ssl_cert || ssl_cert_blob || ssl_cert_type) {
+    BIO *ssl_cert_bio = NULL;
+    BIO *ssl_key_bio = NULL;
+    int result_cert_stuff;
+    if(ssl_cert_blob) {
+      /* the typecast of blob->len is fine since it is guaranteed to never be
+         larger than CURL_MAX_INPUT_LENGTH */
+      ssl_cert_bio = BIO_new_mem_buf(ssl_cert_blob->data,
+                                     (int)ssl_cert_blob->len);
+      if(!ssl_cert_bio)
+        return CURLE_SSL_CERTPROBLEM;
+    }
+    if(SSL_SET_OPTION(key_blob)) {
+      ssl_key_bio = BIO_new_mem_buf(SSL_SET_OPTION(key_blob)->data,
+                                    (int)SSL_SET_OPTION(key_blob)->len);
+      if(!ssl_key_bio)
+        return CURLE_SSL_CERTPROBLEM;
+    }
+    result_cert_stuff = cert_stuff(conn, backend->ctx,
+                   ssl_cert, ssl_cert_bio, ssl_cert_type,
+                   SSL_SET_OPTION(key), ssl_key_bio,
+                   SSL_SET_OPTION(key_type), SSL_SET_OPTION(key_passwd));
+    if(ssl_cert_bio)
+      BIO_free(ssl_cert_bio);
+    if(ssl_key_bio)
+      BIO_free(ssl_key_bio);
+    if(!result_cert_stuff) {
       /* failf() is already done in cert_stuff() */
       return CURLE_SSL_CERTPROBLEM;
     }
@@ -2552,7 +2766,7 @@
   if(!ciphers)
     ciphers = (char *)DEFAULT_CIPHER_SELECTION;
   if(ciphers) {
-    if(!SSL_CTX_set_cipher_list(BACKEND->ctx, ciphers)) {
+    if(!SSL_CTX_set_cipher_list(backend->ctx, ciphers)) {
       failf(data, "failed setting cipher list: %s", ciphers);
       return CURLE_SSL_CIPHER;
     }
@@ -2563,7 +2777,7 @@
   {
     char *ciphers13 = SSL_CONN_CONFIG(cipher_list13);
     if(ciphers13) {
-      if(!SSL_CTX_set_ciphersuites(BACKEND->ctx, ciphers13)) {
+      if(!SSL_CTX_set_ciphersuites(backend->ctx, ciphers13)) {
         failf(data, "failed setting TLS 1.3 cipher suite: %s", ciphers13);
         return CURLE_SSL_CIPHER;
       }
@@ -2574,7 +2788,7 @@
 
 #ifdef HAVE_SSL_CTX_SET_POST_HANDSHAKE_AUTH
   /* OpenSSL 1.1.1 requires clients to opt-in for PHA */
-  SSL_CTX_set_post_handshake_auth(BACKEND->ctx, 1);
+  SSL_CTX_set_post_handshake_auth(backend->ctx, 1);
 #endif
 
 #ifdef USE_TLS_SRP
@@ -2583,18 +2797,18 @@
 
     infof(data, "Using TLS-SRP username: %s\n", ssl_username);
 
-    if(!SSL_CTX_set_srp_username(BACKEND->ctx, ssl_username)) {
+    if(!SSL_CTX_set_srp_username(backend->ctx, ssl_username)) {
       failf(data, "Unable to set SRP user name");
       return CURLE_BAD_FUNCTION_ARGUMENT;
     }
-    if(!SSL_CTX_set_srp_password(BACKEND->ctx, SSL_SET_OPTION(password))) {
+    if(!SSL_CTX_set_srp_password(backend->ctx, SSL_SET_OPTION(password))) {
       failf(data, "failed setting SRP password");
       return CURLE_BAD_FUNCTION_ARGUMENT;
     }
     if(!SSL_CONN_CONFIG(cipher_list)) {
       infof(data, "Setting cipher list SRP\n");
 
-      if(!SSL_CTX_set_cipher_list(BACKEND->ctx, "SRP")) {
+      if(!SSL_CTX_set_cipher_list(backend->ctx, "SRP")) {
         failf(data, "failed setting SRP cipher list");
         return CURLE_SSL_CIPHER;
       }
@@ -2602,11 +2816,186 @@
   }
 #endif
 
+
+#if defined(USE_WIN32_CRYPTO)
+  /* Import certificates from the Windows root certificate store if requested.
+     https://stackoverflow.com/questions/9507184/
+     https://github.com/d3x0r/SACK/blob/master/src/netlib/ssl_layer.c#L1037
+     https://tools.ietf.org/html/rfc5280 */
+  if((SSL_CONN_CONFIG(verifypeer) || SSL_CONN_CONFIG(verifyhost)) &&
+     (SSL_SET_OPTION(native_ca_store))) {
+    X509_STORE *store = SSL_CTX_get_cert_store(backend->ctx);
+    HCERTSTORE hStore = CertOpenSystemStoreA((HCRYPTPROV_LEGACY)NULL, "ROOT");
+
+    if(hStore) {
+      PCCERT_CONTEXT pContext = NULL;
+      /* The array of enhanced key usage OIDs will vary per certificate and is
+         declared outside of the loop so that rather than malloc/free each
+         iteration we can grow it with realloc, when necessary. */
+      CERT_ENHKEY_USAGE *enhkey_usage = NULL;
+      DWORD enhkey_usage_size = 0;
+
+      /* This loop makes a best effort to import all valid certificates from
+         the MS root store. If a certificate cannot be imported it is skipped.
+         'result' is used to store only hard-fail conditions (such as out of
+         memory) that cause an early break. */
+      result = CURLE_OK;
+      for(;;) {
+        X509 *x509;
+        FILETIME now;
+        BYTE key_usage[2];
+        DWORD req_size;
+        const unsigned char *encoded_cert;
+#if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS)
+        char cert_name[256];
+#endif
+
+        pContext = CertEnumCertificatesInStore(hStore, pContext);
+        if(!pContext)
+          break;
+
+#if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS)
+        if(!CertGetNameStringA(pContext, CERT_NAME_SIMPLE_DISPLAY_TYPE, 0,
+                               NULL, cert_name, sizeof(cert_name))) {
+          strcpy(cert_name, "Unknown");
+        }
+        infof(data, "SSL: Checking cert \"%s\"\n", cert_name);
+#endif
+
+        encoded_cert = (const unsigned char *)pContext->pbCertEncoded;
+        if(!encoded_cert)
+          continue;
+
+        GetSystemTimeAsFileTime(&now);
+        if(CompareFileTime(&pContext->pCertInfo->NotBefore, &now) > 0 ||
+           CompareFileTime(&now, &pContext->pCertInfo->NotAfter) > 0)
+          continue;
+
+        /* If key usage exists check for signing attribute */
+        if(CertGetIntendedKeyUsage(pContext->dwCertEncodingType,
+                                   pContext->pCertInfo,
+                                   key_usage, sizeof(key_usage))) {
+          if(!(key_usage[0] & CERT_KEY_CERT_SIGN_KEY_USAGE))
+            continue;
+        }
+        else if(GetLastError())
+          continue;
+
+        /* If enhanced key usage exists check for server auth attribute.
+         *
+         * Note "In a Microsoft environment, a certificate might also have EKU
+         * extended properties that specify valid uses for the certificate."
+         * The call below checks both, and behavior varies depending on what is
+         * found. For more details see CertGetEnhancedKeyUsage doc.
+         */
+        if(CertGetEnhancedKeyUsage(pContext, 0, NULL, &req_size)) {
+          if(req_size && req_size > enhkey_usage_size) {
+            void *tmp = realloc(enhkey_usage, req_size);
+
+            if(!tmp) {
+              failf(data, "SSL: Out of memory allocating for OID list");
+              result = CURLE_OUT_OF_MEMORY;
+              break;
+            }
+
+            enhkey_usage = (CERT_ENHKEY_USAGE *)tmp;
+            enhkey_usage_size = req_size;
+          }
+
+          if(CertGetEnhancedKeyUsage(pContext, 0, enhkey_usage, &req_size)) {
+            if(!enhkey_usage->cUsageIdentifier) {
+              /* "If GetLastError returns CRYPT_E_NOT_FOUND, the certificate is
+                 good for all uses. If it returns zero, the certificate has no
+                 valid uses." */
+              if(GetLastError() != CRYPT_E_NOT_FOUND)
+                continue;
+            }
+            else {
+              DWORD i;
+              bool found = false;
+
+              for(i = 0; i < enhkey_usage->cUsageIdentifier; ++i) {
+                if(!strcmp("1.3.6.1.5.5.7.3.1" /* OID server auth */,
+                           enhkey_usage->rgpszUsageIdentifier[i])) {
+                  found = true;
+                  break;
+                }
+              }
+
+              if(!found)
+                continue;
+            }
+          }
+          else
+            continue;
+        }
+        else
+          continue;
+
+        x509 = d2i_X509(NULL, &encoded_cert, pContext->cbCertEncoded);
+        if(!x509)
+          continue;
+
+        /* Try to import the certificate. This may fail for legitimate reasons
+           such as duplicate certificate, which is allowed by MS but not
+           OpenSSL. */
+        if(X509_STORE_add_cert(store, x509) == 1) {
+#if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS)
+          infof(data, "SSL: Imported cert \"%s\"\n", cert_name);
+#endif
+          imported_native_ca = true;
+        }
+        X509_free(x509);
+      }
+
+      free(enhkey_usage);
+      CertFreeCertificateContext(pContext);
+      CertCloseStore(hStore, 0);
+
+      if(result)
+        return result;
+    }
+    if(imported_native_ca)
+      infof(data, "successfully imported windows ca store\n");
+    else
+      infof(data, "error importing windows ca store, continuing anyway\n");
+  }
+#endif
+
+#if defined(OPENSSL_VERSION_MAJOR) && (OPENSSL_VERSION_MAJOR >= 3)
+  /* OpenSSL 3.0.0 has deprecated SSL_CTX_load_verify_locations */
+  {
+    if(ssl_cafile) {
+      if(!SSL_CTX_load_verify_file(backend->ctx, ssl_cafile)) {
+        if(verifypeer) {
+          /* Fail if we insist on successfully verifying the server. */
+          failf(data, "error setting certificate file: %s", ssl_cafile);
+          return CURLE_SSL_CACERT_BADFILE;
+        }
+        /* Continue with a warning if no certificate verif is required. */
+        infof(data, "error setting certificate file, continuing anyway\n");
+      }
+      infof(data, "  CAfile: %s\n", ssl_cafile);
+    }
+    if(ssl_capath) {
+      if(!SSL_CTX_load_verify_dir(backend->ctx, ssl_capath)) {
+        if(verifypeer) {
+          /* Fail if we insist on successfully verifying the server. */
+          failf(data, "error setting certificate path: %s", ssl_capath);
+          return CURLE_SSL_CACERT_BADFILE;
+        }
+        /* Continue with a warning if no certificate verif is required. */
+        infof(data, "error setting certificate path, continuing anyway\n");
+      }
+      infof(data, "  CApath: %s\n", ssl_capath);
+    }
+  }
+#else
   if(ssl_cafile || ssl_capath) {
     /* tell SSL where to find CA certificates that are used to verify
        the servers certificate. */
-    if(!SSL_CTX_load_verify_locations(BACKEND->ctx, ssl_cafile, ssl_capath)) {
-      if(verifypeer) {
+    if(!SSL_CTX_load_verify_locations(backend->ctx, ssl_cafile, ssl_capath)) {
+      if(verifypeer && !imported_native_ca) {
         /* Fail if we insist on successfully verifying the server. */
         failf(data, "error setting certificate verify locations:\n"
               "  CAfile: %s\n  CApath: %s",
@@ -2614,7 +3003,7 @@
               ssl_capath ? ssl_capath : "none");
         return CURLE_SSL_CACERT_BADFILE;
       }
-      /* Just continue with a warning if no strict  certificate verification
+      /* Just continue with a warning if no strict certificate verification
          is required. */
       infof(data, "error setting certificate verify locations,"
             " continuing anyway:\n");
@@ -2629,18 +3018,20 @@
           ssl_cafile ? ssl_cafile : "none",
           ssl_capath ? ssl_capath : "none");
   }
+#endif
+
 #ifdef CURL_CA_FALLBACK
-  else if(verifypeer) {
+  if(verifypeer && !ssl_cafile && !ssl_capath && !imported_native_ca) {
     /* verifying the peer without any CA certificates won't
        work so use openssl's built in default as fallback */
-    SSL_CTX_set_default_verify_paths(BACKEND->ctx);
+    SSL_CTX_set_default_verify_paths(backend->ctx);
   }
 #endif
 
   if(ssl_crlfile) {
     /* tell SSL where to find CRL file that is used to check certificate
      * revocation */
-    lookup = X509_STORE_add_lookup(SSL_CTX_get_cert_store(BACKEND->ctx),
+    lookup = X509_STORE_add_lookup(SSL_CTX_get_cert_store(backend->ctx),
                                  X509_LOOKUP_file());
     if(!lookup ||
        (!X509_load_crl_file(lookup, ssl_crlfile, X509_FILETYPE_PEM)) ) {
@@ -2649,37 +3040,50 @@
     }
     /* Everything is fine. */
     infof(data, "successfully load CRL file:\n");
-    X509_STORE_set_flags(SSL_CTX_get_cert_store(BACKEND->ctx),
+    X509_STORE_set_flags(SSL_CTX_get_cert_store(backend->ctx),
                          X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL);
 
     infof(data, "  CRLfile: %s\n", ssl_crlfile);
   }
 
-  /* Try building a chain using issuers in the trusted store first to avoid
-  problems with server-sent legacy intermediates.
-  Newer versions of OpenSSL do alternate chain checking by default which
-  gives us the same fix without as much of a performance hit (slight), so we
-  prefer that if available.
-  https://rt.openssl.org/Ticket/Display.html?id=3621&user=guest&pass=guest
-  */
-#if defined(X509_V_FLAG_TRUSTED_FIRST) && !defined(X509_V_FLAG_NO_ALT_CHAINS)
   if(verifypeer) {
-    X509_STORE_set_flags(SSL_CTX_get_cert_store(BACKEND->ctx),
+    /* Try building a chain using issuers in the trusted store first to avoid
+       problems with server-sent legacy intermediates.  Newer versions of
+       OpenSSL do alternate chain checking by default but we do not know how to
+       determine that in a reliable manner.
+       https://rt.openssl.org/Ticket/Display.html?id=3621&user=guest&pass=guest
+    */
+#if defined(X509_V_FLAG_TRUSTED_FIRST)
+    X509_STORE_set_flags(SSL_CTX_get_cert_store(backend->ctx),
                          X509_V_FLAG_TRUSTED_FIRST);
-  }
 #endif
+#ifdef X509_V_FLAG_PARTIAL_CHAIN
+    if(!SSL_SET_OPTION(no_partialchain) && !ssl_crlfile) {
+      /* Have intermediate certificates in the trust store be treated as
+         trust-anchors, in the same way as self-signed root CA certificates
+         are. This allows users to verify servers using the intermediate cert
+         only, instead of needing the whole chain.
+
+         Due to OpenSSL bug https://github.com/openssl/openssl/issues/5081 we
+         cannot do partial chains with CRL check.
+      */
+      X509_STORE_set_flags(SSL_CTX_get_cert_store(backend->ctx),
+                           X509_V_FLAG_PARTIAL_CHAIN);
+    }
+#endif
+  }
 
   /* SSL always tries to verify the peer, this only says whether it should
    * fail to connect if the verification fails, or if it should continue
    * anyway. In the latter case the result of the verification is checked with
    * SSL_get_verify_result() below. */
-  SSL_CTX_set_verify(BACKEND->ctx,
+  SSL_CTX_set_verify(backend->ctx,
                      verifypeer ? SSL_VERIFY_PEER : SSL_VERIFY_NONE, NULL);
 
   /* Enable logging of secrets to the file specified in env SSLKEYLOGFILE. */
-#if defined(ENABLE_SSLKEYLOGFILE) && defined(HAVE_KEYLOG_CALLBACK)
-  if(keylog_file_fp) {
-    SSL_CTX_set_keylog_callback(BACKEND->ctx, ossl_keylog_callback);
+#ifdef HAVE_KEYLOG_CALLBACK
+  if(Curl_tls_keylog_enabled()) {
+    SSL_CTX_set_keylog_callback(backend->ctx, ossl_keylog_callback);
   }
 #endif
 
@@ -2687,14 +3091,16 @@
    * callback. Use the "external storage" mode to avoid that OpenSSL creates
    * an internal session cache.
    */
-  SSL_CTX_set_session_cache_mode(BACKEND->ctx,
+  SSL_CTX_set_session_cache_mode(backend->ctx,
       SSL_SESS_CACHE_CLIENT | SSL_SESS_CACHE_NO_INTERNAL);
-  SSL_CTX_sess_set_new_cb(BACKEND->ctx, ossl_new_session_cb);
+  SSL_CTX_sess_set_new_cb(backend->ctx, ossl_new_session_cb);
 
   /* give application a chance to interfere with SSL set up. */
   if(data->set.ssl.fsslctx) {
-    result = (*data->set.ssl.fsslctx)(data, BACKEND->ctx,
+    Curl_set_in_callback(data, true);
+    result = (*data->set.ssl.fsslctx)(data, backend->ctx,
                                       data->set.ssl.fsslctxp);
+    Curl_set_in_callback(data, false);
     if(result) {
       failf(data, "error signaled by ssl ctx callback");
       return result;
@@ -2702,10 +3108,10 @@
   }
 
   /* Lets make an SSL structure */
-  if(BACKEND->handle)
-    SSL_free(BACKEND->handle);
-  BACKEND->handle = SSL_new(BACKEND->ctx);
-  if(!BACKEND->handle) {
+  if(backend->handle)
+    SSL_free(backend->handle);
+  backend->handle = SSL_new(backend->ctx);
+  if(!backend->handle) {
     failf(data, "SSL: couldn't create a context (handle)!");
     return CURLE_OUT_OF_MEMORY;
   }
@@ -2713,23 +3119,23 @@
 #if (OPENSSL_VERSION_NUMBER >= 0x0090808fL) && !defined(OPENSSL_NO_TLSEXT) && \
     !defined(OPENSSL_NO_OCSP)
   if(SSL_CONN_CONFIG(verifystatus))
-    SSL_set_tlsext_status_type(BACKEND->handle, TLSEXT_STATUSTYPE_ocsp);
+    SSL_set_tlsext_status_type(backend->handle, TLSEXT_STATUSTYPE_ocsp);
 #endif
 
 #if defined(OPENSSL_IS_BORINGSSL) && defined(ALLOW_RENEG)
-  SSL_set_renegotiate_mode(BACKEND->handle, ssl_renegotiate_freely);
+  SSL_set_renegotiate_mode(backend->handle, ssl_renegotiate_freely);
 #endif
 
-  SSL_set_connect_state(BACKEND->handle);
+  SSL_set_connect_state(backend->handle);
 
-  BACKEND->server_cert = 0x0;
+  backend->server_cert = 0x0;
 #ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
   if((0 == Curl_inet_pton(AF_INET, hostname, &addr)) &&
 #ifdef ENABLE_IPV6
      (0 == Curl_inet_pton(AF_INET6, hostname, &addr)) &&
 #endif
      sni &&
-     !SSL_set_tlsext_host_name(BACKEND->handle, hostname))
+     !SSL_set_tlsext_host_name(backend->handle, hostname))
     infof(data, "WARNING: failed to configure server name indication (SNI) "
           "TLS extension\n");
 #endif
@@ -2743,14 +3149,14 @@
     if(connectdata_idx >= 0 && sockindex_idx >= 0) {
       /* Store the data needed for the "new session" callback.
        * The sockindex is stored as a pointer to an array element. */
-      SSL_set_ex_data(BACKEND->handle, connectdata_idx, conn);
-      SSL_set_ex_data(BACKEND->handle, sockindex_idx, conn->sock + sockindex);
+      SSL_set_ex_data(backend->handle, connectdata_idx, conn);
+      SSL_set_ex_data(backend->handle, sockindex_idx, conn->sock + sockindex);
     }
 
     Curl_ssl_sessionid_lock(conn);
     if(!Curl_ssl_getsessionid(conn, &ssl_sessionid, NULL, sockindex)) {
       /* we got a session id, use it! */
-      if(!SSL_set_session(BACKEND->handle, ssl_sessionid)) {
+      if(!SSL_set_session(backend->handle, ssl_sessionid)) {
         Curl_ssl_sessionid_unlock(conn);
         failf(data, "SSL: SSL_set_session failed: %s",
               ossl_strerror(ERR_get_error(), error_buffer,
@@ -2763,6 +3169,7 @@
     Curl_ssl_sessionid_unlock(conn);
   }
 
+#ifndef CURL_DISABLE_PROXY
   if(conn->proxy_ssl[sockindex].use) {
     BIO *const bio = BIO_new(BIO_f_ssl());
     SSL *handle = conn->proxy_ssl[sockindex].backend->handle;
@@ -2770,9 +3177,11 @@
     DEBUGASSERT(handle != NULL);
     DEBUGASSERT(bio != NULL);
     BIO_set_ssl(bio, handle, FALSE);
-    SSL_set_bio(BACKEND->handle, bio, bio);
+    SSL_set_bio(backend->handle, bio, bio);
   }
-  else if(!SSL_set_fd(BACKEND->handle, (int)sockfd)) {
+  else
+#endif
+    if(!SSL_set_fd(backend->handle, (int)sockfd)) {
     /* pass the raw socket into the SSL layers */
     failf(data, "SSL: SSL_set_fd failed: %s",
           ossl_strerror(ERR_get_error(), error_buffer, sizeof(error_buffer)));
@@ -2789,26 +3198,34 @@
   struct Curl_easy *data = conn->data;
   int err;
   struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+#ifndef CURL_DISABLE_PROXY
   long * const certverifyresult = SSL_IS_PROXY() ?
     &data->set.proxy_ssl.certverifyresult : &data->set.ssl.certverifyresult;
+#else
+  long * const certverifyresult = &data->set.ssl.certverifyresult;
+#endif
+  struct ssl_backend_data *backend = connssl->backend;
   DEBUGASSERT(ssl_connect_2 == connssl->connecting_state
               || ssl_connect_2_reading == connssl->connecting_state
               || ssl_connect_2_writing == connssl->connecting_state);
 
   ERR_clear_error();
 
-  err = SSL_connect(BACKEND->handle);
-  /* If keylogging is enabled but the keylog callback is not supported then log
-     secrets here, immediately after SSL_connect by using tap_ssl_key. */
-#if defined(ENABLE_SSLKEYLOGFILE) && !defined(HAVE_KEYLOG_CALLBACK)
-  tap_ssl_key(BACKEND->handle, &BACKEND->tap_state);
+  err = SSL_connect(backend->handle);
+#ifndef HAVE_KEYLOG_CALLBACK
+  if(Curl_tls_keylog_enabled()) {
+    /* If key logging is enabled, wait for the handshake to complete and then
+     * proceed with logging secrets (for TLS 1.2 or older).
+     */
+    ossl_log_tls12_secret(backend->handle, &backend->keylog_done);
+  }
 #endif
 
   /* 1  is fine
      0  is "not successful but was shut down controlled"
      <0 is "handshake was not successful, because a fatal error occurred" */
   if(1 != err) {
-    int detail = SSL_get_error(BACKEND->handle, err);
+    int detail = SSL_get_error(backend->handle, err);
 
     if(SSL_ERROR_WANT_READ == detail) {
       connssl->connecting_state = ssl_connect_2_reading;
@@ -2848,7 +3265,7 @@
          (reason == SSL_R_CERTIFICATE_VERIFY_FAILED)) {
         result = CURLE_PEER_FAILED_VERIFICATION;
 
-        lerr = SSL_get_verify_result(BACKEND->handle);
+        lerr = SSL_get_verify_result(backend->handle);
         if(lerr != X509_V_OK) {
           *certverifyresult = lerr;
           msnprintf(error_buffer, sizeof(error_buffer),
@@ -2872,11 +3289,21 @@
        * the SO_ERROR is also lost.
        */
       if(CURLE_SSL_CONNECT_ERROR == result && errdetail == 0) {
+#ifndef CURL_DISABLE_PROXY
         const char * const hostname = SSL_IS_PROXY() ?
           conn->http_proxy.host.name : conn->host.name;
         const long int port = SSL_IS_PROXY() ? conn->port : conn->remote_port;
+#else
+        const char * const hostname = conn->host.name;
+        const long int port = conn->remote_port;
+#endif
+        char extramsg[80]="";
+        int sockerr = SOCKERRNO;
+        if(sockerr && detail == SSL_ERROR_SYSCALL)
+          Curl_strerror(sockerr, extramsg, sizeof(extramsg));
         failf(data, OSSL_PACKAGE " SSL_connect: %s in connection to %s:%ld ",
-              SSL_ERROR_to_str(detail), hostname, port);
+              extramsg[0] ? extramsg : SSL_ERROR_to_str(detail),
+              hostname, port);
         return result;
       }
 
@@ -2892,8 +3319,8 @@
 
     /* Informational message */
     infof(data, "SSL connection using %s / %s\n",
-          get_ssl_version_txt(BACKEND->handle),
-          SSL_get_cipher(BACKEND->handle));
+          get_ssl_version_txt(backend->handle),
+          SSL_get_cipher(backend->handle));
 
 #ifdef HAS_ALPN
     /* Sets data and len to negotiated protocol, len is 0 if no protocol was
@@ -2902,7 +3329,7 @@
     if(conn->bits.tls_enable_alpn) {
       const unsigned char *neg_protocol;
       unsigned int len;
-      SSL_get0_alpn_selected(BACKEND->handle, &neg_protocol, &len);
+      SSL_get0_alpn_selected(backend->handle, &neg_protocol, &len);
       if(len != 0) {
         infof(data, "ALPN, server accepted to use %.*s\n", len, neg_protocol);
 
@@ -2952,7 +3379,7 @@
   Curl_ssl_push_certinfo_len(data, _num, _label, ptr, info_len); \
   if(1 != BIO_reset(mem))                                        \
     break;                                                       \
-} WHILE_FALSE
+} while(0)
 
 static void pubkey_show(struct Curl_easy *data,
                         BIO *mem,
@@ -2984,31 +3411,28 @@
   if(_type->_name) { \
     pubkey_show(data, mem, _num, #_type, #_name, _type->_name); \
   } \
-} WHILE_FALSE
+} while(0)
 #endif
 
-static int X509V3_ext(struct Curl_easy *data,
+static void X509V3_ext(struct Curl_easy *data,
                       int certnum,
                       CONST_EXTS STACK_OF(X509_EXTENSION) *exts)
 {
   int i;
-  size_t j;
 
   if((int)sk_X509_EXTENSION_num(exts) <= 0)
     /* no extensions, bail out */
-    return 1;
+    return;
 
   for(i = 0; i < (int)sk_X509_EXTENSION_num(exts); i++) {
     ASN1_OBJECT *obj;
     X509_EXTENSION *ext = sk_X509_EXTENSION_value(exts, i);
     BUF_MEM *biomem;
-    char buf[512];
-    char *ptr = buf;
     char namebuf[128];
     BIO *bio_out = BIO_new(BIO_s_mem());
 
     if(!bio_out)
-      return 1;
+      return;
 
     obj = X509_EXTENSION_get_object(ext);
 
@@ -3018,28 +3442,18 @@
       ASN1_STRING_print(bio_out, (ASN1_STRING *)X509_EXTENSION_get_data(ext));
 
     BIO_get_mem_ptr(bio_out, &biomem);
-
-    for(j = 0; j < (size_t)biomem->length; j++) {
-      const char *sep = "";
-      if(biomem->data[j] == '\n') {
-        sep = ", ";
-        j++; /* skip the newline */
-      };
-      while((j<(size_t)biomem->length) && (biomem->data[j] == ' '))
-        j++;
-      if(j<(size_t)biomem->length)
-        ptr += msnprintf(ptr, sizeof(buf)-(ptr-buf), "%s%c", sep,
-                         biomem->data[j]);
-    }
-
-    Curl_ssl_push_certinfo(data, certnum, namebuf, buf);
-
+    Curl_ssl_push_certinfo_len(data, certnum, namebuf, biomem->data,
+                               biomem->length);
     BIO_free(bio_out);
-
   }
-  return 0; /* all is fine */
 }
 
+#ifdef OPENSSL_IS_BORINGSSL
+typedef size_t numcert_t;
+#else
+typedef int numcert_t;
+#endif
+
 static CURLcode get_cert_chain(struct connectdata *conn,
                                struct ssl_connect_data *connssl)
 
@@ -3048,24 +3462,25 @@
   STACK_OF(X509) *sk;
   int i;
   struct Curl_easy *data = conn->data;
-  int numcerts;
+  numcert_t numcerts;
   BIO *mem;
+  struct ssl_backend_data *backend = connssl->backend;
 
-  sk = SSL_get_peer_cert_chain(BACKEND->handle);
+  sk = SSL_get_peer_cert_chain(backend->handle);
   if(!sk) {
     return CURLE_OUT_OF_MEMORY;
   }
 
   numcerts = sk_X509_num(sk);
 
-  result = Curl_ssl_init_certinfo(data, numcerts);
+  result = Curl_ssl_init_certinfo(data, (int)numcerts);
   if(result) {
     return result;
   }
 
   mem = BIO_new(BIO_s_mem());
 
-  for(i = 0; i < numcerts; i++) {
+  for(i = 0; i < (int)numcerts; i++) {
     ASN1_INTEGER *num;
     X509 *x = sk_X509_value(sk, i);
     EVP_PKEY *pubkey = NULL;
@@ -3091,18 +3506,25 @@
 
 #if defined(HAVE_X509_GET0_SIGNATURE) && defined(HAVE_X509_GET0_EXTENSIONS)
     {
-      const X509_ALGOR *palg = NULL;
-      ASN1_STRING *a = ASN1_STRING_new();
-      if(a) {
-        X509_get0_signature(&psig, &palg, x);
-        X509_signature_print(mem, ARG2_X509_signature_print palg, a);
-        ASN1_STRING_free(a);
+      const X509_ALGOR *sigalg = NULL;
+      X509_PUBKEY *xpubkey = NULL;
+      ASN1_OBJECT *pubkeyoid = NULL;
 
-        if(palg) {
-          i2a_ASN1_OBJECT(mem, palg->algorithm);
+      X509_get0_signature(&psig, &sigalg, x);
+      if(sigalg) {
+        i2a_ASN1_OBJECT(mem, sigalg->algorithm);
+        push_certinfo("Signature Algorithm", i);
+      }
+
+      xpubkey = X509_get_X509_PUBKEY(x);
+      if(xpubkey) {
+        X509_PUBKEY_get0_param(&pubkeyoid, NULL, NULL, NULL, xpubkey);
+        if(pubkeyoid) {
+          i2a_ASN1_OBJECT(mem, pubkeyoid);
           push_certinfo("Public Key Algorithm", i);
         }
       }
+
       X509V3_ext(data, i, X509_get0_extensions(x));
     }
 #else
@@ -3154,7 +3576,7 @@
           const BIGNUM *e;
 
           RSA_get0_key(rsa, &n, &e, NULL);
-          BN_print(mem, n);
+          BIO_printf(mem, "%d", BN_num_bits(n));
           push_certinfo("RSA Public Key", i);
           print_pubkey_BN(rsa, n, i);
           print_pubkey_BN(rsa, e, i);
@@ -3279,7 +3701,6 @@
     if(len1 < 1)
       break; /* failed */
 
-    /* https://www.openssl.org/docs/crypto/buffer.html */
     buff1 = temp = malloc(len1);
     if(!buff1)
       break; /* failed */
@@ -3301,7 +3722,6 @@
     result = Curl_pin_peer_pubkey(data, pinnedpubkey, buff1, len1);
   } while(0);
 
-  /* https://www.openssl.org/docs/crypto/buffer.html */
   if(buff1)
     free(buff1);
 
@@ -3329,16 +3749,21 @@
   char error_buffer[256]="";
   char buffer[2048];
   const char *ptr;
+#ifndef CURL_DISABLE_PROXY
   long * const certverifyresult = SSL_IS_PROXY() ?
     &data->set.proxy_ssl.certverifyresult : &data->set.ssl.certverifyresult;
+#else
+  long * const certverifyresult = &data->set.ssl.certverifyresult;
+#endif
   BIO *mem = BIO_new(BIO_s_mem());
+  struct ssl_backend_data *backend = connssl->backend;
 
   if(data->set.ssl.certinfo)
     /* we've been asked to gather certificate info! */
     (void)get_cert_chain(conn, connssl);
 
-  BACKEND->server_cert = SSL_get_peer_certificate(BACKEND->handle);
-  if(!BACKEND->server_cert) {
+  backend->server_cert = SSL_get_peer_certificate(backend->handle);
+  if(!backend->server_cert) {
     BIO_free(mem);
     if(!strict)
       return CURLE_OK;
@@ -3349,19 +3774,19 @@
 
   infof(data, "%s certificate:\n", SSL_IS_PROXY() ? "Proxy" : "Server");
 
-  rc = x509_name_oneline(X509_get_subject_name(BACKEND->server_cert),
+  rc = x509_name_oneline(X509_get_subject_name(backend->server_cert),
                          buffer, sizeof(buffer));
   infof(data, " subject: %s\n", rc?"[NONE]":buffer);
 
 #ifndef CURL_DISABLE_VERBOSE_STRINGS
   {
     long len;
-    ASN1_TIME_print(mem, X509_get0_notBefore(BACKEND->server_cert));
+    ASN1_TIME_print(mem, X509_get0_notBefore(backend->server_cert));
     len = BIO_get_mem_data(mem, (char **) &ptr);
     infof(data, " start date: %.*s\n", len, ptr);
     (void)BIO_reset(mem);
 
-    ASN1_TIME_print(mem, X509_get0_notAfter(BACKEND->server_cert));
+    ASN1_TIME_print(mem, X509_get0_notAfter(backend->server_cert));
     len = BIO_get_mem_data(mem, (char **) &ptr);
     infof(data, " expire date: %.*s\n", len, ptr);
     (void)BIO_reset(mem);
@@ -3371,15 +3796,15 @@
   BIO_free(mem);
 
   if(SSL_CONN_CONFIG(verifyhost)) {
-    result = verifyhost(conn, BACKEND->server_cert);
+    result = verifyhost(conn, backend->server_cert);
     if(result) {
-      X509_free(BACKEND->server_cert);
-      BACKEND->server_cert = NULL;
+      X509_free(backend->server_cert);
+      backend->server_cert = NULL;
       return result;
     }
   }
 
-  rc = x509_name_oneline(X509_get_issuer_name(BACKEND->server_cert),
+  rc = x509_name_oneline(X509_get_issuer_name(backend->server_cert),
                          buffer, sizeof(buffer));
   if(rc) {
     if(strict)
@@ -3393,27 +3818,32 @@
        deallocating the certificate. */
 
     /* e.g. match issuer name with provided issuer certificate */
-    if(SSL_SET_OPTION(issuercert)) {
-      fp = BIO_new(BIO_s_file());
-      if(fp == NULL) {
-        failf(data,
-              "BIO_new return NULL, " OSSL_PACKAGE
-              " error %s",
-              ossl_strerror(ERR_get_error(), error_buffer,
-                            sizeof(error_buffer)) );
-        X509_free(BACKEND->server_cert);
-        BACKEND->server_cert = NULL;
-        return CURLE_OUT_OF_MEMORY;
-      }
+    if(SSL_SET_OPTION(issuercert) || SSL_SET_OPTION(issuercert_blob)) {
+      if(SSL_SET_OPTION(issuercert_blob))
+        fp = BIO_new_mem_buf(SSL_SET_OPTION(issuercert_blob)->data,
+                             (int)SSL_SET_OPTION(issuercert_blob)->len);
+      else {
+        fp = BIO_new(BIO_s_file());
+        if(fp == NULL) {
+          failf(data,
+                "BIO_new return NULL, " OSSL_PACKAGE
+                " error %s",
+                ossl_strerror(ERR_get_error(), error_buffer,
+                              sizeof(error_buffer)) );
+          X509_free(backend->server_cert);
+          backend->server_cert = NULL;
+          return CURLE_OUT_OF_MEMORY;
+        }
 
-      if(BIO_read_filename(fp, SSL_SET_OPTION(issuercert)) <= 0) {
-        if(strict)
-          failf(data, "SSL: Unable to open issuer cert (%s)",
-                SSL_SET_OPTION(issuercert));
-        BIO_free(fp);
-        X509_free(BACKEND->server_cert);
-        BACKEND->server_cert = NULL;
-        return CURLE_SSL_ISSUER_ERROR;
+        if(BIO_read_filename(fp, SSL_SET_OPTION(issuercert)) <= 0) {
+          if(strict)
+            failf(data, "SSL: Unable to open issuer cert (%s)",
+                  SSL_SET_OPTION(issuercert));
+          BIO_free(fp);
+          X509_free(backend->server_cert);
+          backend->server_cert = NULL;
+          return CURLE_SSL_ISSUER_ERROR;
+        }
       }
 
       issuer = PEM_read_bio_X509(fp, NULL, ZERO_NULL, NULL);
@@ -3423,19 +3853,19 @@
                 SSL_SET_OPTION(issuercert));
         BIO_free(fp);
         X509_free(issuer);
-        X509_free(BACKEND->server_cert);
-        BACKEND->server_cert = NULL;
+        X509_free(backend->server_cert);
+        backend->server_cert = NULL;
         return CURLE_SSL_ISSUER_ERROR;
       }
 
-      if(X509_check_issued(issuer, BACKEND->server_cert) != X509_V_OK) {
+      if(X509_check_issued(issuer, backend->server_cert) != X509_V_OK) {
         if(strict)
           failf(data, "SSL: Certificate issuer check failed (%s)",
                 SSL_SET_OPTION(issuercert));
         BIO_free(fp);
         X509_free(issuer);
-        X509_free(BACKEND->server_cert);
-        BACKEND->server_cert = NULL;
+        X509_free(backend->server_cert);
+        backend->server_cert = NULL;
         return CURLE_SSL_ISSUER_ERROR;
       }
 
@@ -3445,7 +3875,7 @@
       X509_free(issuer);
     }
 
-    lerr = *certverifyresult = SSL_get_verify_result(BACKEND->handle);
+    lerr = *certverifyresult = SSL_get_verify_result(backend->handle);
 
     if(*certverifyresult != X509_V_OK) {
       if(SSL_CONN_CONFIG(verifypeer)) {
@@ -3470,8 +3900,8 @@
   if(SSL_CONN_CONFIG(verifystatus)) {
     result = verifystatus(conn, connssl);
     if(result) {
-      X509_free(BACKEND->server_cert);
-      BACKEND->server_cert = NULL;
+      X509_free(backend->server_cert);
+      backend->server_cert = NULL;
       return result;
     }
   }
@@ -3484,13 +3914,13 @@
   ptr = SSL_IS_PROXY() ? data->set.str[STRING_SSL_PINNEDPUBLICKEY_PROXY] :
                          data->set.str[STRING_SSL_PINNEDPUBLICKEY_ORIG];
   if(!result && ptr) {
-    result = pkp_pin_peer_pubkey(data, BACKEND->server_cert, ptr);
+    result = pkp_pin_peer_pubkey(data, backend->server_cert, ptr);
     if(result)
       failf(data, "SSL: public key does not match pinned public key!");
   }
 
-  X509_free(BACKEND->server_cert);
-  BACKEND->server_cert = NULL;
+  X509_free(backend->server_cert);
+  backend->server_cert = NULL;
   connssl->connecting_state = ssl_connect_done;
 
   return result;
@@ -3531,7 +3961,6 @@
   struct Curl_easy *data = conn->data;
   struct ssl_connect_data *connssl = &conn->ssl[sockindex];
   curl_socket_t sockfd = conn->sock[sockindex];
-  time_t timeout_ms;
   int what;
 
   /* check if the connection has already been established */
@@ -3542,7 +3971,7 @@
 
   if(ssl_connect_1 == connssl->connecting_state) {
     /* Find out how much more time we're allowed */
-    timeout_ms = Curl_timeleft(data, NULL, TRUE);
+    const timediff_t timeout_ms = Curl_timeleft(data, NULL, TRUE);
 
     if(timeout_ms < 0) {
       /* no need to continue if time already is up */
@@ -3560,7 +3989,7 @@
         ssl_connect_2_writing == connssl->connecting_state) {
 
     /* check allowed time left */
-    timeout_ms = Curl_timeleft(data, NULL, TRUE);
+    const timediff_t timeout_ms = Curl_timeleft(data, NULL, TRUE);
 
     if(timeout_ms < 0) {
       /* no need to continue if time already is up */
@@ -3657,14 +4086,15 @@
                                    int connindex)
 {
   const struct ssl_connect_data *connssl = &conn->ssl[connindex];
-  const struct ssl_connect_data *proxyssl = &conn->proxy_ssl[connindex];
-
   if(connssl->backend->handle && SSL_pending(connssl->backend->handle))
     return TRUE;
-
-  if(proxyssl->backend->handle && SSL_pending(proxyssl->backend->handle))
-    return TRUE;
-
+#ifndef CURL_DISABLE_PROXY
+  {
+    const struct ssl_connect_data *proxyssl = &conn->proxy_ssl[connindex];
+    if(proxyssl->backend->handle && SSL_pending(proxyssl->backend->handle))
+      return TRUE;
+  }
+#endif
   return FALSE;
 }
 
@@ -3684,14 +4114,15 @@
   int memlen;
   int rc;
   struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+  struct ssl_backend_data *backend = connssl->backend;
 
   ERR_clear_error();
 
   memlen = (len > (size_t)INT_MAX) ? INT_MAX : (int)len;
-  rc = SSL_write(BACKEND->handle, mem, memlen);
+  rc = SSL_write(backend->handle, mem, memlen);
 
   if(rc <= 0) {
-    err = SSL_get_error(BACKEND->handle, rc);
+    err = SSL_get_error(backend->handle, rc);
 
     switch(err) {
     case SSL_ERROR_WANT_READ:
@@ -3702,18 +4133,33 @@
       *curlcode = CURLE_AGAIN;
       return -1;
     case SSL_ERROR_SYSCALL:
-      failf(conn->data, "SSL_write() returned SYSCALL, errno = %d",
-            SOCKERRNO);
-      *curlcode = CURLE_SEND_ERROR;
-      return -1;
+      {
+        int sockerr = SOCKERRNO;
+        sslerror = ERR_get_error();
+        if(sslerror)
+          ossl_strerror(sslerror, error_buffer, sizeof(error_buffer));
+        else if(sockerr)
+          Curl_strerror(sockerr, error_buffer, sizeof(error_buffer));
+        else {
+          strncpy(error_buffer, SSL_ERROR_to_str(err), sizeof(error_buffer));
+          error_buffer[sizeof(error_buffer) - 1] = '\0';
+        }
+        failf(conn->data, OSSL_PACKAGE " SSL_write: %s, errno %d",
+              error_buffer, sockerr);
+        *curlcode = CURLE_SEND_ERROR;
+        return -1;
+      }
     case SSL_ERROR_SSL:
       /*  A failure in the SSL library occurred, usually a protocol error.
           The OpenSSL error queue contains more information on the error. */
       sslerror = ERR_get_error();
       if(ERR_GET_LIB(sslerror) == ERR_LIB_SSL &&
          ERR_GET_REASON(sslerror) == SSL_R_BIO_NOT_SET &&
-         conn->ssl[sockindex].state == ssl_connection_complete &&
-         conn->proxy_ssl[sockindex].state == ssl_connection_complete) {
+         conn->ssl[sockindex].state == ssl_connection_complete
+#ifndef CURL_DISABLE_PROXY
+         && conn->proxy_ssl[sockindex].state == ssl_connection_complete
+#endif
+        ) {
         char ver[120];
         Curl_ossl_version(ver, 120);
         failf(conn->data, "Error: %s does not support double SSL tunneling.",
@@ -3746,21 +4192,25 @@
   ssize_t nread;
   int buffsize;
   struct ssl_connect_data *connssl = &conn->ssl[num];
+  struct ssl_backend_data *backend = connssl->backend;
 
   ERR_clear_error();
 
   buffsize = (buffersize > (size_t)INT_MAX) ? INT_MAX : (int)buffersize;
-  nread = (ssize_t)SSL_read(BACKEND->handle, buf, buffsize);
+  nread = (ssize_t)SSL_read(backend->handle, buf, buffsize);
   if(nread <= 0) {
     /* failed SSL_read */
-    int err = SSL_get_error(BACKEND->handle, (int)nread);
+    int err = SSL_get_error(backend->handle, (int)nread);
 
     switch(err) {
     case SSL_ERROR_NONE: /* this is not an error */
       break;
     case SSL_ERROR_ZERO_RETURN: /* no more data */
       /* close_notify alert */
-      connclose(conn, "TLS close_notify");
+      if(num == FIRSTSOCKET)
+        /* mark the connection for close if it is indeed the control
+           connection */
+        connclose(conn, "TLS close_notify");
       break;
     case SSL_ERROR_WANT_READ:
     case SSL_ERROR_WANT_WRITE:
@@ -3775,14 +4225,44 @@
       if((nread < 0) || sslerror) {
         /* If the return code was negative or there actually is an error in the
            queue */
+        int sockerr = SOCKERRNO;
+        if(sslerror)
+          ossl_strerror(sslerror, error_buffer, sizeof(error_buffer));
+        else if(sockerr && err == SSL_ERROR_SYSCALL)
+          Curl_strerror(sockerr, error_buffer, sizeof(error_buffer));
+        else {
+          strncpy(error_buffer, SSL_ERROR_to_str(err), sizeof(error_buffer));
+          error_buffer[sizeof(error_buffer) - 1] = '\0';
+        }
         failf(conn->data, OSSL_PACKAGE " SSL_read: %s, errno %d",
-              (sslerror ?
-               ossl_strerror(sslerror, error_buffer, sizeof(error_buffer)) :
-               SSL_ERROR_to_str(err)),
-              SOCKERRNO);
+              error_buffer, sockerr);
         *curlcode = CURLE_RECV_ERROR;
         return -1;
       }
+      /* For debug builds be a little stricter and error on any
+         SSL_ERROR_SYSCALL. For example a server may have closed the connection
+         abruptly without a close_notify alert. For compatibility with older
+         peers we don't do this by default. #4624
+
+         We can use this to gauge how many users may be affected, and
+         if it goes ok eventually transition to allow in dev and release with
+         the newest OpenSSL: #if (OPENSSL_VERSION_NUMBER >= 0x10101000L) */
+#ifdef DEBUGBUILD
+      if(err == SSL_ERROR_SYSCALL) {
+        int sockerr = SOCKERRNO;
+        if(sockerr)
+          Curl_strerror(sockerr, error_buffer, sizeof(error_buffer));
+        else {
+          msnprintf(error_buffer, sizeof(error_buffer),
+                    "Connection closed abruptly");
+        }
+        failf(conn->data, OSSL_PACKAGE " SSL_read: %s, errno %d"
+              " (Fatal because this is a curl debug build)",
+              error_buffer, sockerr);
+        *curlcode = CURLE_RECV_ERROR;
+        return -1;
+      }
+#endif
     }
   }
   return nread;
@@ -3790,13 +4270,35 @@
 
 static size_t Curl_ossl_version(char *buffer, size_t size)
 {
-#ifdef OPENSSL_IS_BORINGSSL
+#ifdef LIBRESSL_VERSION_NUMBER
+#if LIBRESSL_VERSION_NUMBER < 0x2070100fL
+  return msnprintf(buffer, size, "%s/%lx.%lx.%lx",
+                   OSSL_PACKAGE,
+                   (LIBRESSL_VERSION_NUMBER>>28)&0xf,
+                   (LIBRESSL_VERSION_NUMBER>>20)&0xff,
+                   (LIBRESSL_VERSION_NUMBER>>12)&0xff);
+#else /* OpenSSL_version() first appeared in LibreSSL 2.7.1 */
+  char *p;
+  int count;
+  const char *ver = OpenSSL_version(OPENSSL_VERSION);
+  const char expected[] = OSSL_PACKAGE " "; /* ie "LibreSSL " */
+  if(Curl_strncasecompare(ver, expected, sizeof(expected) - 1)) {
+    ver += sizeof(expected) - 1;
+  }
+  count = msnprintf(buffer, size, "%s/%s", OSSL_PACKAGE, ver);
+  for(p = buffer; *p; ++p) {
+    if(ISSPACE(*p))
+      *p = '_';
+  }
+  return count;
+#endif
+#elif defined(OPENSSL_IS_BORINGSSL)
   return msnprintf(buffer, size, OSSL_PACKAGE);
 #elif defined(HAVE_OPENSSL_VERSION) && defined(OPENSSL_VERSION_STRING)
   return msnprintf(buffer, size, "%s/%s",
                    OSSL_PACKAGE, OpenSSL_version(OPENSSL_VERSION_STRING));
 #else
-  /* not BoringSSL and not using OpenSSL_version */
+  /* not LibreSSL, BoringSSL and not using OpenSSL_version */
 
   char sub[3];
   unsigned long ssleay_value;
@@ -3881,7 +4383,7 @@
   unsigned int len = 0;
   (void) unused;
 
-  mdctx =  EVP_MD_CTX_create();
+  mdctx = EVP_MD_CTX_create();
   EVP_DigestInit_ex(mdctx, EVP_sha256(), NULL);
   EVP_DigestUpdate(mdctx, tmp, tmplen);
   EVP_DigestFinal_ex(mdctx, sha256sum, &len);
@@ -3904,8 +4406,9 @@
                                      CURLINFO info)
 {
   /* Legacy: CURLINFO_TLS_SESSION must return an SSL_CTX pointer. */
+  struct ssl_backend_data *backend = connssl->backend;
   return info == CURLINFO_TLS_SESSION ?
-         (void *)BACKEND->ctx : (void *)BACKEND->handle;
+         (void *)backend->ctx : (void *)backend->handle;
 }
 
 const struct Curl_ssl Curl_ssl_openssl = {
diff --git a/Utilities/cmcurl/lib/vtls/polarssl.c b/Utilities/cmcurl/lib/vtls/polarssl.c
deleted file mode 100644
index 7ea26b4..0000000
--- a/Utilities/cmcurl/lib/vtls/polarssl.c
+++ /dev/null
@@ -1,931 +0,0 @@
-/***************************************************************************
- *                                  _   _ ____  _
- *  Project                     ___| | | |  _ \| |
- *                             / __| | | | |_) | |
- *                            | (__| |_| |  _ <| |___
- *                             \___|\___/|_| \_\_____|
- *
- * Copyright (C) 2012 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
- * Copyright (C) 2010 - 2011, Hoi-Ho Chan, <hoiho.chan@gmail.com>
- *
- * This software is licensed as described in the file COPYING, which
- * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
- *
- * You may opt to use, copy, modify, merge, publish, distribute and/or sell
- * copies of the Software, and permit persons to whom the Software is
- * furnished to do so, under the terms of the COPYING file.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- ***************************************************************************/
-
-/*
- * Source file for all PolarSSL-specific code for the TLS/SSL layer. No code
- * but vtls.c should ever call or use these functions.
- *
- */
-
-#include "curl_setup.h"
-
-#ifdef USE_POLARSSL
-#include <polarssl/net.h>
-#include <polarssl/ssl.h>
-#include <polarssl/certs.h>
-#include <polarssl/x509.h>
-#include <polarssl/version.h>
-#include <polarssl/sha256.h>
-
-#if POLARSSL_VERSION_NUMBER < 0x01030000
-#error too old PolarSSL
-#endif
-
-#include <polarssl/error.h>
-#include <polarssl/entropy.h>
-#include <polarssl/ctr_drbg.h>
-
-#include "urldata.h"
-#include "sendf.h"
-#include "inet_pton.h"
-#include "polarssl.h"
-#include "vtls.h"
-#include "parsedate.h"
-#include "connect.h" /* for the connect timeout */
-#include "select.h"
-#include "strcase.h"
-#include "polarssl_threadlock.h"
-#include "multiif.h"
-#include "curl_printf.h"
-#include "curl_memory.h"
-/* The last #include file should be: */
-#include "memdebug.h"
-
-/* See https://tls.mbed.org/discussions/generic/
-   howto-determine-exact-buffer-len-for-mbedtls_pk_write_pubkey_der
-*/
-#define RSA_PUB_DER_MAX_BYTES   (38 + 2 * POLARSSL_MPI_MAX_SIZE)
-#define ECP_PUB_DER_MAX_BYTES   (30 + 2 * POLARSSL_ECP_MAX_BYTES)
-
-#define PUB_DER_MAX_BYTES   (RSA_PUB_DER_MAX_BYTES > ECP_PUB_DER_MAX_BYTES ? \
-                             RSA_PUB_DER_MAX_BYTES : ECP_PUB_DER_MAX_BYTES)
-
-struct ssl_backend_data {
-  ctr_drbg_context ctr_drbg;
-  entropy_context entropy;
-  ssl_context ssl;
-  int server_fd;
-  x509_crt cacert;
-  x509_crt clicert;
-  x509_crl crl;
-  rsa_context rsa;
-};
-
-#define BACKEND connssl->backend
-
-/* apply threading? */
-#if defined(USE_THREADS_POSIX) || defined(USE_THREADS_WIN32)
-#define THREADING_SUPPORT
-#endif
-
-#ifndef POLARSSL_ERROR_C
-#define error_strerror(x,y,z)
-#endif /* POLARSSL_ERROR_C */
-
-
-#if defined(THREADING_SUPPORT)
-static entropy_context entropy;
-
-static int  entropy_init_initialized  = 0;
-
-/* start of entropy_init_mutex() */
-static void entropy_init_mutex(entropy_context *ctx)
-{
-  /* lock 0 = entropy_init_mutex() */
-  Curl_polarsslthreadlock_lock_function(0);
-  if(entropy_init_initialized == 0) {
-    entropy_init(ctx);
-    entropy_init_initialized = 1;
-  }
-  Curl_polarsslthreadlock_unlock_function(0);
-}
-/* end of entropy_init_mutex() */
-
-/* start of entropy_func_mutex() */
-static int entropy_func_mutex(void *data, unsigned char *output, size_t len)
-{
-  int ret;
-  /* lock 1 = entropy_func_mutex() */
-  Curl_polarsslthreadlock_lock_function(1);
-  ret = entropy_func(data, output, len);
-  Curl_polarsslthreadlock_unlock_function(1);
-
-  return ret;
-}
-/* end of entropy_func_mutex() */
-
-#endif /* THREADING_SUPPORT */
-
-/* Define this to enable lots of debugging for PolarSSL */
-#undef POLARSSL_DEBUG
-
-#ifdef POLARSSL_DEBUG
-static void polarssl_debug(void *context, int level, const char *line)
-{
-  struct Curl_easy *data = NULL;
-
-  if(!context)
-    return;
-
-  data = (struct Curl_easy *)context;
-
-  infof(data, "%s", line);
-  (void) level;
-}
-#else
-#endif
-
-/* ALPN for http2? */
-#ifdef POLARSSL_SSL_ALPN
-#  define HAS_ALPN
-#endif
-
-static Curl_recv polarssl_recv;
-static Curl_send polarssl_send;
-
-static CURLcode polarssl_version_from_curl(int *polarver, long ssl_version)
-{
-  switch(ssl_version) {
-    case CURL_SSLVERSION_TLSv1_0:
-      *polarver = SSL_MINOR_VERSION_1;
-      return CURLE_OK;
-    case CURL_SSLVERSION_TLSv1_1:
-      *polarver = SSL_MINOR_VERSION_2;
-      return CURLE_OK;
-    case CURL_SSLVERSION_TLSv1_2:
-      *polarver = SSL_MINOR_VERSION_3;
-      return CURLE_OK;
-    case CURL_SSLVERSION_TLSv1_3:
-      break;
-  }
-  return CURLE_SSL_CONNECT_ERROR;
-}
-
-static CURLcode
-set_ssl_version_min_max(struct connectdata *conn, int sockindex)
-{
-  struct Curl_easy *data = conn->data;
-  struct ssl_connect_data* connssl = &conn->ssl[sockindex];
-  long ssl_version = SSL_CONN_CONFIG(version);
-  long ssl_version_max = SSL_CONN_CONFIG(version_max);
-  int ssl_min_ver = SSL_MINOR_VERSION_1;
-  int ssl_max_ver = SSL_MINOR_VERSION_1;
-  CURLcode result = CURLE_OK;
-
-  switch(ssl_version) {
-    case CURL_SSLVERSION_DEFAULT:
-    case CURL_SSLVERSION_TLSv1:
-      ssl_version = CURL_SSLVERSION_TLSv1_0;
-      break;
-  }
-
-  switch(ssl_version_max) {
-    case CURL_SSLVERSION_MAX_NONE:
-    case CURL_SSLVERSION_MAX_DEFAULT:
-      ssl_version_max = CURL_SSLVERSION_MAX_TLSv1_2;
-      break;
-  }
-
-  result = polarssl_version_from_curl(&ssl_min_ver, ssl_version);
-  if(result) {
-    failf(data, "unsupported min version passed via CURLOPT_SSLVERSION");
-    return result;
-  }
-  result = polarssl_version_from_curl(&ssl_max_ver, ssl_version_max >> 16);
-  if(result) {
-    failf(data, "unsupported max version passed via CURLOPT_SSLVERSION");
-    return result;
-  }
-
-  ssl_set_min_version(&BACKEND->ssl, SSL_MAJOR_VERSION_3, ssl_min_ver);
-  ssl_set_max_version(&BACKEND->ssl, SSL_MAJOR_VERSION_3, ssl_max_ver);
-
-  return result;
-}
-
-static CURLcode
-polarssl_connect_step1(struct connectdata *conn,
-                       int sockindex)
-{
-  struct Curl_easy *data = conn->data;
-  struct ssl_connect_data* connssl = &conn->ssl[sockindex];
-  const char *capath = SSL_CONN_CONFIG(CApath);
-  const char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name :
-    conn->host.name;
-  const long int port = SSL_IS_PROXY() ? conn->port : conn->remote_port;
-  int ret = -1;
-  char errorbuf[128];
-  errorbuf[0] = 0;
-
-  /* PolarSSL only supports SSLv3 and TLSv1 */
-  if(SSL_CONN_CONFIG(version) == CURL_SSLVERSION_SSLv2) {
-    failf(data, "PolarSSL does not support SSLv2");
-    return CURLE_SSL_CONNECT_ERROR;
-  }
-
-#ifdef THREADING_SUPPORT
-  entropy_init_mutex(&entropy);
-
-  if((ret = ctr_drbg_init(&BACKEND->ctr_drbg, entropy_func_mutex, &entropy,
-                          NULL, 0)) != 0) {
-    error_strerror(ret, errorbuf, sizeof(errorbuf));
-    failf(data, "Failed - PolarSSL: ctr_drbg_init returned (-0x%04X) %s\n",
-          -ret, errorbuf);
-  }
-#else
-  entropy_init(&BACKEND->entropy);
-
-  if((ret = ctr_drbg_init(&BACKEND->ctr_drbg, entropy_func, &BACKEND->entropy,
-                          NULL, 0)) != 0) {
-    error_strerror(ret, errorbuf, sizeof(errorbuf));
-    failf(data, "Failed - PolarSSL: ctr_drbg_init returned (-0x%04X) %s\n",
-          -ret, errorbuf);
-  }
-#endif /* THREADING_SUPPORT */
-
-  /* Load the trusted CA */
-  memset(&BACKEND->cacert, 0, sizeof(x509_crt));
-
-  if(SSL_CONN_CONFIG(CAfile)) {
-    ret = x509_crt_parse_file(&BACKEND->cacert,
-                              SSL_CONN_CONFIG(CAfile));
-
-    if(ret<0) {
-      error_strerror(ret, errorbuf, sizeof(errorbuf));
-      failf(data, "Error reading ca cert file %s - PolarSSL: (-0x%04X) %s",
-            SSL_CONN_CONFIG(CAfile), -ret, errorbuf);
-
-      if(SSL_CONN_CONFIG(verifypeer))
-        return CURLE_SSL_CACERT_BADFILE;
-    }
-  }
-
-  if(capath) {
-    ret = x509_crt_parse_path(&BACKEND->cacert, capath);
-
-    if(ret<0) {
-      error_strerror(ret, errorbuf, sizeof(errorbuf));
-      failf(data, "Error reading ca cert path %s - PolarSSL: (-0x%04X) %s",
-            capath, -ret, errorbuf);
-
-      if(SSL_CONN_CONFIG(verifypeer))
-        return CURLE_SSL_CACERT_BADFILE;
-    }
-  }
-
-  /* Load the client certificate */
-  memset(&BACKEND->clicert, 0, sizeof(x509_crt));
-
-  if(SSL_SET_OPTION(cert)) {
-    ret = x509_crt_parse_file(&BACKEND->clicert,
-                              SSL_SET_OPTION(cert));
-
-    if(ret) {
-      error_strerror(ret, errorbuf, sizeof(errorbuf));
-      failf(data, "Error reading client cert file %s - PolarSSL: (-0x%04X) %s",
-            SSL_SET_OPTION(cert), -ret, errorbuf);
-
-      return CURLE_SSL_CERTPROBLEM;
-    }
-  }
-
-  /* Load the client private key */
-  if(SSL_SET_OPTION(key)) {
-    pk_context pk;
-    pk_init(&pk);
-    ret = pk_parse_keyfile(&pk, SSL_SET_OPTION(key),
-                           SSL_SET_OPTION(key_passwd));
-    if(ret == 0 && !pk_can_do(&pk, POLARSSL_PK_RSA))
-      ret = POLARSSL_ERR_PK_TYPE_MISMATCH;
-    if(ret == 0)
-      rsa_copy(&BACKEND->rsa, pk_rsa(pk));
-    else
-      rsa_free(&BACKEND->rsa);
-    pk_free(&pk);
-
-    if(ret) {
-      error_strerror(ret, errorbuf, sizeof(errorbuf));
-      failf(data, "Error reading private key %s - PolarSSL: (-0x%04X) %s",
-            SSL_SET_OPTION(key), -ret, errorbuf);
-
-      return CURLE_SSL_CERTPROBLEM;
-    }
-  }
-
-  /* Load the CRL */
-  memset(&BACKEND->crl, 0, sizeof(x509_crl));
-
-  if(SSL_SET_OPTION(CRLfile)) {
-    ret = x509_crl_parse_file(&BACKEND->crl,
-                              SSL_SET_OPTION(CRLfile));
-
-    if(ret) {
-      error_strerror(ret, errorbuf, sizeof(errorbuf));
-      failf(data, "Error reading CRL file %s - PolarSSL: (-0x%04X) %s",
-            SSL_SET_OPTION(CRLfile), -ret, errorbuf);
-
-      return CURLE_SSL_CRL_BADFILE;
-    }
-  }
-
-  infof(data, "PolarSSL: Connecting to %s:%d\n", hostname, port);
-
-  if(ssl_init(&BACKEND->ssl)) {
-    failf(data, "PolarSSL: ssl_init failed");
-    return CURLE_SSL_CONNECT_ERROR;
-  }
-
-  switch(SSL_CONN_CONFIG(version)) {
-  case CURL_SSLVERSION_DEFAULT:
-  case CURL_SSLVERSION_TLSv1:
-    ssl_set_min_version(&BACKEND->ssl, SSL_MAJOR_VERSION_3,
-                        SSL_MINOR_VERSION_1);
-    break;
-  case CURL_SSLVERSION_SSLv3:
-    ssl_set_min_version(&BACKEND->ssl, SSL_MAJOR_VERSION_3,
-                        SSL_MINOR_VERSION_0);
-    ssl_set_max_version(&BACKEND->ssl, SSL_MAJOR_VERSION_3,
-                        SSL_MINOR_VERSION_0);
-    infof(data, "PolarSSL: Forced min. SSL Version to be SSLv3\n");
-    break;
-  case CURL_SSLVERSION_TLSv1_0:
-  case CURL_SSLVERSION_TLSv1_1:
-  case CURL_SSLVERSION_TLSv1_2:
-  case CURL_SSLVERSION_TLSv1_3:
-    {
-      CURLcode result = set_ssl_version_min_max(conn, sockindex);
-      if(result != CURLE_OK)
-        return result;
-      break;
-    }
-  default:
-    failf(data, "Unrecognized parameter passed via CURLOPT_SSLVERSION");
-    return CURLE_SSL_CONNECT_ERROR;
-  }
-
-  ssl_set_endpoint(&BACKEND->ssl, SSL_IS_CLIENT);
-  ssl_set_authmode(&BACKEND->ssl, SSL_VERIFY_OPTIONAL);
-
-  ssl_set_rng(&BACKEND->ssl, ctr_drbg_random,
-              &BACKEND->ctr_drbg);
-  ssl_set_bio(&BACKEND->ssl,
-              net_recv, &conn->sock[sockindex],
-              net_send, &conn->sock[sockindex]);
-
-  ssl_set_ciphersuites(&BACKEND->ssl, ssl_list_ciphersuites());
-
-  /* Check if there's a cached ID we can/should use here! */
-  if(SSL_SET_OPTION(primary.sessionid)) {
-    void *old_session = NULL;
-
-    Curl_ssl_sessionid_lock(conn);
-    if(!Curl_ssl_getsessionid(conn, &old_session, NULL, sockindex)) {
-      ret = ssl_set_session(&BACKEND->ssl, old_session);
-      if(ret) {
-        Curl_ssl_sessionid_unlock(conn);
-        failf(data, "ssl_set_session returned -0x%x", -ret);
-        return CURLE_SSL_CONNECT_ERROR;
-      }
-      infof(data, "PolarSSL re-using session\n");
-    }
-    Curl_ssl_sessionid_unlock(conn);
-  }
-
-  ssl_set_ca_chain(&BACKEND->ssl,
-                   &BACKEND->cacert,
-                   &BACKEND->crl,
-                   hostname);
-
-  ssl_set_own_cert_rsa(&BACKEND->ssl,
-                       &BACKEND->clicert, &BACKEND->rsa);
-
-  if(ssl_set_hostname(&BACKEND->ssl, hostname)) {
-    /* ssl_set_hostname() sets the name to use in CN/SAN checks *and* the name
-       to set in the SNI extension. So even if curl connects to a host
-       specified as an IP address, this function must be used. */
-    failf(data, "couldn't set hostname in PolarSSL");
-    return CURLE_SSL_CONNECT_ERROR;
-  }
-
-#ifdef HAS_ALPN
-  if(conn->bits.tls_enable_alpn) {
-    static const char *protocols[3];
-    int cur = 0;
-
-#ifdef USE_NGHTTP2
-    if(data->set.httpversion >= CURL_HTTP_VERSION_2) {
-      protocols[cur++] = NGHTTP2_PROTO_VERSION_ID;
-      infof(data, "ALPN, offering %s\n", NGHTTP2_PROTO_VERSION_ID);
-    }
-#endif
-
-    protocols[cur++] = ALPN_HTTP_1_1;
-    infof(data, "ALPN, offering %s\n", ALPN_HTTP_1_1);
-
-    protocols[cur] = NULL;
-
-    ssl_set_alpn_protocols(&BACKEND->ssl, protocols);
-  }
-#endif
-
-#ifdef POLARSSL_DEBUG
-  ssl_set_dbg(&BACKEND->ssl, polarssl_debug, data);
-#endif
-
-  connssl->connecting_state = ssl_connect_2;
-
-  return CURLE_OK;
-}
-
-static CURLcode
-polarssl_connect_step2(struct connectdata *conn,
-                       int sockindex)
-{
-  int ret;
-  struct Curl_easy *data = conn->data;
-  struct ssl_connect_data* connssl = &conn->ssl[sockindex];
-  char buffer[1024];
-  const char * const pinnedpubkey = SSL_IS_PROXY() ?
-            data->set.str[STRING_SSL_PINNEDPUBLICKEY_PROXY] :
-            data->set.str[STRING_SSL_PINNEDPUBLICKEY_ORIG];
-
-
-  char errorbuf[128];
-  errorbuf[0] = 0;
-
-  conn->recv[sockindex] = polarssl_recv;
-  conn->send[sockindex] = polarssl_send;
-
-  ret = ssl_handshake(&BACKEND->ssl);
-
-  switch(ret) {
-  case 0:
-    break;
-
-  case POLARSSL_ERR_NET_WANT_READ:
-    connssl->connecting_state = ssl_connect_2_reading;
-    return CURLE_OK;
-
-  case POLARSSL_ERR_NET_WANT_WRITE:
-    connssl->connecting_state = ssl_connect_2_writing;
-    return CURLE_OK;
-
-  default:
-    error_strerror(ret, errorbuf, sizeof(errorbuf));
-    failf(data, "ssl_handshake returned - PolarSSL: (-0x%04X) %s",
-          -ret, errorbuf);
-    return CURLE_SSL_CONNECT_ERROR;
-  }
-
-  infof(data, "PolarSSL: Handshake complete, cipher is %s\n",
-        ssl_get_ciphersuite(&BACKEND->ssl) );
-
-  ret = ssl_get_verify_result(&BACKEND->ssl);
-
-  if(ret && SSL_CONN_CONFIG(verifypeer)) {
-    if(ret & BADCERT_EXPIRED)
-      failf(data, "Cert verify failed: BADCERT_EXPIRED");
-
-    if(ret & BADCERT_REVOKED) {
-      failf(data, "Cert verify failed: BADCERT_REVOKED");
-      return CURLE_PEER_FAILED_VERIFICATION;
-    }
-
-    if(ret & BADCERT_CN_MISMATCH)
-      failf(data, "Cert verify failed: BADCERT_CN_MISMATCH");
-
-    if(ret & BADCERT_NOT_TRUSTED)
-      failf(data, "Cert verify failed: BADCERT_NOT_TRUSTED");
-
-    return CURLE_PEER_FAILED_VERIFICATION;
-  }
-
-  if(ssl_get_peer_cert(&(BACKEND->ssl))) {
-    /* If the session was resumed, there will be no peer certs */
-    memset(buffer, 0, sizeof(buffer));
-
-    if(x509_crt_info(buffer, sizeof(buffer), (char *)"* ",
-                     ssl_get_peer_cert(&(BACKEND->ssl))) != -1)
-      infof(data, "Dumping cert info:\n%s\n", buffer);
-  }
-
-  /* adapted from mbedtls.c */
-  if(pinnedpubkey) {
-    int size;
-    CURLcode result;
-    x509_crt *p;
-    unsigned char pubkey[PUB_DER_MAX_BYTES];
-    const x509_crt *peercert;
-
-    peercert = ssl_get_peer_cert(&BACKEND->ssl);
-
-    if(!peercert || !peercert->raw.p || !peercert->raw.len) {
-      failf(data, "Failed due to missing peer certificate");
-      return CURLE_SSL_PINNEDPUBKEYNOTMATCH;
-    }
-
-    p = calloc(1, sizeof(*p));
-
-    if(!p)
-      return CURLE_OUT_OF_MEMORY;
-
-    x509_crt_init(p);
-
-    /* Make a copy of our const peercert because pk_write_pubkey_der
-       needs a non-const key, for now.
-       https://github.com/ARMmbed/mbedtls/issues/396 */
-    if(x509_crt_parse_der(p, peercert->raw.p, peercert->raw.len)) {
-      failf(data, "Failed copying peer certificate");
-      x509_crt_free(p);
-      free(p);
-      return CURLE_SSL_PINNEDPUBKEYNOTMATCH;
-    }
-
-    size = pk_write_pubkey_der(&p->pk, pubkey, PUB_DER_MAX_BYTES);
-
-    if(size <= 0) {
-      failf(data, "Failed copying public key from peer certificate");
-      x509_crt_free(p);
-      free(p);
-      return CURLE_SSL_PINNEDPUBKEYNOTMATCH;
-    }
-
-    /* pk_write_pubkey_der writes data at the end of the buffer. */
-    result = Curl_pin_peer_pubkey(data,
-                                  pinnedpubkey,
-                                  &pubkey[PUB_DER_MAX_BYTES - size], size);
-    if(result) {
-      x509_crt_free(p);
-      free(p);
-      return result;
-    }
-
-    x509_crt_free(p);
-    free(p);
-  }
-
-#ifdef HAS_ALPN
-  if(conn->bits.tls_enable_alpn) {
-    const char *next_protocol = ssl_get_alpn_protocol(&BACKEND->ssl);
-
-    if(next_protocol != NULL) {
-      infof(data, "ALPN, server accepted to use %s\n", next_protocol);
-
-#ifdef USE_NGHTTP2
-      if(!strncmp(next_protocol, NGHTTP2_PROTO_VERSION_ID,
-                  NGHTTP2_PROTO_VERSION_ID_LEN)) {
-        conn->negnpn = CURL_HTTP_VERSION_2;
-      }
-      else
-#endif
-        if(!strncmp(next_protocol, ALPN_HTTP_1_1, ALPN_HTTP_1_1_LENGTH)) {
-          conn->negnpn = CURL_HTTP_VERSION_1_1;
-        }
-    }
-    else
-      infof(data, "ALPN, server did not agree to a protocol\n");
-    Curl_multiuse_state(conn, conn->negnpn == CURL_HTTP_VERSION_2 ?
-                        BUNDLE_MULTIPLEX : BUNDLE_NO_MULTIUSE);
-  }
-#endif
-
-  connssl->connecting_state = ssl_connect_3;
-  infof(data, "SSL connected\n");
-
-  return CURLE_OK;
-}
-
-static CURLcode
-polarssl_connect_step3(struct connectdata *conn,
-                       int sockindex)
-{
-  CURLcode retcode = CURLE_OK;
-  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
-  struct Curl_easy *data = conn->data;
-
-  DEBUGASSERT(ssl_connect_3 == connssl->connecting_state);
-
-  if(SSL_SET_OPTION(primary.sessionid)) {
-    int ret;
-    ssl_session *our_ssl_sessionid;
-    void *old_ssl_sessionid = NULL;
-
-    our_ssl_sessionid = calloc(1, sizeof(ssl_session));
-    if(!our_ssl_sessionid)
-      return CURLE_OUT_OF_MEMORY;
-
-    ret = ssl_get_session(&BACKEND->ssl, our_ssl_sessionid);
-    if(ret) {
-      failf(data, "ssl_get_session returned -0x%x", -ret);
-      return CURLE_SSL_CONNECT_ERROR;
-    }
-
-    /* If there's already a matching session in the cache, delete it */
-    Curl_ssl_sessionid_lock(conn);
-    if(!Curl_ssl_getsessionid(conn, &old_ssl_sessionid, NULL, sockindex))
-      Curl_ssl_delsessionid(conn, old_ssl_sessionid);
-
-    retcode = Curl_ssl_addsessionid(conn, our_ssl_sessionid, 0, sockindex);
-    Curl_ssl_sessionid_unlock(conn);
-    if(retcode) {
-      free(our_ssl_sessionid);
-      failf(data, "failed to store ssl session");
-      return retcode;
-    }
-  }
-
-  connssl->connecting_state = ssl_connect_done;
-
-  return CURLE_OK;
-}
-
-static ssize_t polarssl_send(struct connectdata *conn,
-                             int sockindex,
-                             const void *mem,
-                             size_t len,
-                             CURLcode *curlcode)
-{
-  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
-  int ret = -1;
-
-  ret = ssl_write(&BACKEND->ssl,
-                  (unsigned char *)mem, len);
-
-  if(ret < 0) {
-    *curlcode = (ret == POLARSSL_ERR_NET_WANT_WRITE) ?
-      CURLE_AGAIN : CURLE_SEND_ERROR;
-    ret = -1;
-  }
-
-  return ret;
-}
-
-static void Curl_polarssl_close(struct connectdata *conn, int sockindex)
-{
-  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
-  rsa_free(&BACKEND->rsa);
-  x509_crt_free(&BACKEND->clicert);
-  x509_crt_free(&BACKEND->cacert);
-  x509_crl_free(&BACKEND->crl);
-  ssl_free(&BACKEND->ssl);
-}
-
-static ssize_t polarssl_recv(struct connectdata *conn,
-                             int num,
-                             char *buf,
-                             size_t buffersize,
-                             CURLcode *curlcode)
-{
-  struct ssl_connect_data *connssl = &conn->ssl[num];
-  int ret = -1;
-  ssize_t len = -1;
-
-  memset(buf, 0, buffersize);
-  ret = ssl_read(&BACKEND->ssl, (unsigned char *)buf, buffersize);
-
-  if(ret <= 0) {
-    if(ret == POLARSSL_ERR_SSL_PEER_CLOSE_NOTIFY)
-      return 0;
-
-    *curlcode = (ret == POLARSSL_ERR_NET_WANT_READ) ?
-      CURLE_AGAIN : CURLE_RECV_ERROR;
-    return -1;
-  }
-
-  len = ret;
-
-  return len;
-}
-
-static void Curl_polarssl_session_free(void *ptr)
-{
-  ssl_session_free(ptr);
-  free(ptr);
-}
-
-/* 1.3.10 was the first rebranded version. All new releases (in 1.3 branch and
-   higher) will be mbed TLS branded.. */
-
-static size_t Curl_polarssl_version(char *buffer, size_t size)
-{
-  unsigned int version = version_get_number();
-  return msnprintf(buffer, size, "%s/%d.%d.%d",
-                   version >= 0x01030A00?"mbedTLS":"PolarSSL",
-                   version>>24, (version>>16)&0xff, (version>>8)&0xff);
-}
-
-static CURLcode
-polarssl_connect_common(struct connectdata *conn,
-                        int sockindex,
-                        bool nonblocking,
-                        bool *done)
-{
-  CURLcode result;
-  struct Curl_easy *data = conn->data;
-  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
-  curl_socket_t sockfd = conn->sock[sockindex];
-  long timeout_ms;
-  int what;
-
-  /* check if the connection has already been established */
-  if(ssl_connection_complete == connssl->state) {
-    *done = TRUE;
-    return CURLE_OK;
-  }
-
-  if(ssl_connect_1 == connssl->connecting_state) {
-    /* Find out how much more time we're allowed */
-    timeout_ms = Curl_timeleft(data, NULL, TRUE);
-
-    if(timeout_ms < 0) {
-      /* no need to continue if time already is up */
-      failf(data, "SSL connection timeout");
-      return CURLE_OPERATION_TIMEDOUT;
-    }
-
-    result = polarssl_connect_step1(conn, sockindex);
-    if(result)
-      return result;
-  }
-
-  while(ssl_connect_2 == connssl->connecting_state ||
-        ssl_connect_2_reading == connssl->connecting_state ||
-        ssl_connect_2_writing == connssl->connecting_state) {
-
-    /* check allowed time left */
-    timeout_ms = Curl_timeleft(data, NULL, TRUE);
-
-    if(timeout_ms < 0) {
-      /* no need to continue if time already is up */
-      failf(data, "SSL connection timeout");
-      return CURLE_OPERATION_TIMEDOUT;
-    }
-
-    /* if ssl is expecting something, check if it's available. */
-    if(connssl->connecting_state == ssl_connect_2_reading ||
-       connssl->connecting_state == ssl_connect_2_writing) {
-
-      curl_socket_t writefd = ssl_connect_2_writing ==
-        connssl->connecting_state?sockfd:CURL_SOCKET_BAD;
-      curl_socket_t readfd = ssl_connect_2_reading ==
-        connssl->connecting_state?sockfd:CURL_SOCKET_BAD;
-
-      what = Curl_socket_check(readfd, CURL_SOCKET_BAD, writefd,
-                               nonblocking?0:timeout_ms);
-      if(what < 0) {
-        /* fatal error */
-        failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO);
-        return CURLE_SSL_CONNECT_ERROR;
-      }
-      else if(0 == what) {
-        if(nonblocking) {
-          *done = FALSE;
-          return CURLE_OK;
-        }
-        else {
-          /* timeout */
-          failf(data, "SSL connection timeout");
-          return CURLE_OPERATION_TIMEDOUT;
-        }
-      }
-      /* socket is readable or writable */
-    }
-
-    /* Run transaction, and return to the caller if it failed or if
-     * this connection is part of a multi handle and this loop would
-     * execute again. This permits the owner of a multi handle to
-     * abort a connection attempt before step2 has completed while
-     * ensuring that a client using select() or epoll() will always
-     * have a valid fdset to wait on.
-     */
-    result = polarssl_connect_step2(conn, sockindex);
-    if(result || (nonblocking &&
-                  (ssl_connect_2 == connssl->connecting_state ||
-                   ssl_connect_2_reading == connssl->connecting_state ||
-                   ssl_connect_2_writing == connssl->connecting_state)))
-      return result;
-
-  } /* repeat step2 until all transactions are done. */
-
-  if(ssl_connect_3 == connssl->connecting_state) {
-    result = polarssl_connect_step3(conn, sockindex);
-    if(result)
-      return result;
-  }
-
-  if(ssl_connect_done == connssl->connecting_state) {
-    connssl->state = ssl_connection_complete;
-    conn->recv[sockindex] = polarssl_recv;
-    conn->send[sockindex] = polarssl_send;
-    *done = TRUE;
-  }
-  else
-    *done = FALSE;
-
-  /* Reset our connect state machine */
-  connssl->connecting_state = ssl_connect_1;
-
-  return CURLE_OK;
-}
-
-static CURLcode Curl_polarssl_connect_nonblocking(struct connectdata *conn,
-                                                  int sockindex, bool *done)
-{
-  return polarssl_connect_common(conn, sockindex, TRUE, done);
-}
-
-
-static CURLcode Curl_polarssl_connect(struct connectdata *conn, int sockindex)
-{
-  CURLcode result;
-  bool done = FALSE;
-
-  result = polarssl_connect_common(conn, sockindex, FALSE, &done);
-  if(result)
-    return result;
-
-  DEBUGASSERT(done);
-
-  return CURLE_OK;
-}
-
-/*
- * return 0 error initializing SSL
- * return 1 SSL initialized successfully
- */
-static int Curl_polarssl_init(void)
-{
-  return Curl_polarsslthreadlock_thread_setup();
-}
-
-static void Curl_polarssl_cleanup(void)
-{
-  (void)Curl_polarsslthreadlock_thread_cleanup();
-}
-
-static bool Curl_polarssl_data_pending(const struct connectdata *conn,
-                                       int sockindex)
-{
-  const struct ssl_connect_data *connssl = &conn->ssl[sockindex];
-  return ssl_get_bytes_avail(&BACKEND->ssl) != 0;
-}
-
-static CURLcode Curl_polarssl_sha256sum(const unsigned char *input,
-                                    size_t inputlen,
-                                    unsigned char *sha256sum,
-                                    size_t sha256len UNUSED_PARAM)
-{
-  (void)sha256len;
-  sha256(input, inputlen, sha256sum, 0);
-  return CURLE_OK;
-}
-
-static void *Curl_polarssl_get_internals(struct ssl_connect_data *connssl,
-                                         CURLINFO info UNUSED_PARAM)
-{
-  (void)info;
-  return &BACKEND->ssl;
-}
-
-const struct Curl_ssl Curl_ssl_polarssl = {
-  { CURLSSLBACKEND_POLARSSL, "polarssl" }, /* info */
-
-  SSLSUPP_CA_PATH |
-  SSLSUPP_PINNEDPUBKEY,
-
-  sizeof(struct ssl_backend_data),
-
-  Curl_polarssl_init,                /* init */
-  Curl_polarssl_cleanup,             /* cleanup */
-  Curl_polarssl_version,             /* version */
-  Curl_none_check_cxn,               /* check_cxn */
-  Curl_none_shutdown,                /* shutdown */
-  Curl_polarssl_data_pending,        /* data_pending */
-  /* This might cause libcurl to use a weeker random! */
-  Curl_none_random,                  /* random */
-  Curl_none_cert_status_request,     /* cert_status_request */
-  Curl_polarssl_connect,             /* connect */
-  Curl_polarssl_connect_nonblocking, /* connect_nonblocking */
-  Curl_polarssl_get_internals,       /* get_internals */
-  Curl_polarssl_close,               /* close_one */
-  Curl_none_close_all,               /* close_all */
-  Curl_polarssl_session_free,        /* session_free */
-  Curl_none_set_engine,              /* set_engine */
-  Curl_none_set_engine_default,      /* set_engine_default */
-  Curl_none_engines_list,            /* engines_list */
-  Curl_none_false_start,             /* false_start */
-  Curl_none_md5sum,                  /* md5sum */
-  Curl_polarssl_sha256sum            /* sha256sum */
-};
-
-#endif /* USE_POLARSSL */
diff --git a/Utilities/cmcurl/lib/vtls/polarssl.h b/Utilities/cmcurl/lib/vtls/polarssl.h
deleted file mode 100644
index 23c3636..0000000
--- a/Utilities/cmcurl/lib/vtls/polarssl.h
+++ /dev/null
@@ -1,32 +0,0 @@
-#ifndef HEADER_CURL_POLARSSL_H
-#define HEADER_CURL_POLARSSL_H
-/***************************************************************************
- *                                  _   _ ____  _
- *  Project                     ___| | | |  _ \| |
- *                             / __| | | | |_) | |
- *                            | (__| |_| |  _ <| |___
- *                             \___|\___/|_| \_\_____|
- *
- * Copyright (C) 2012 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
- * Copyright (C) 2010, Hoi-Ho Chan, <hoiho.chan@gmail.com>
- *
- * This software is licensed as described in the file COPYING, which
- * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
- *
- * You may opt to use, copy, modify, merge, publish, distribute and/or sell
- * copies of the Software, and permit persons to whom the Software is
- * furnished to do so, under the terms of the COPYING file.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- ***************************************************************************/
-#include "curl_setup.h"
-
-#ifdef USE_POLARSSL
-
-extern const struct Curl_ssl Curl_ssl_polarssl;
-
-#endif /* USE_POLARSSL */
-#endif /* HEADER_CURL_POLARSSL_H */
diff --git a/Utilities/cmcurl/lib/vtls/polarssl_threadlock.c b/Utilities/cmcurl/lib/vtls/polarssl_threadlock.c
deleted file mode 100644
index 27c94b1..0000000
--- a/Utilities/cmcurl/lib/vtls/polarssl_threadlock.c
+++ /dev/null
@@ -1,144 +0,0 @@
-/***************************************************************************
- *                                  _   _ ____  _
- *  Project                     ___| | | |  _ \| |
- *                             / __| | | | |_) | |
- *                            | (__| |_| |  _ <| |___
- *                             \___|\___/|_| \_\_____|
- *
- * Copyright (C) 2013-2017, Daniel Stenberg, <daniel@haxx.se>, et al.
- * Copyright (C) 2010, 2011, Hoi-Ho Chan, <hoiho.chan@gmail.com>
- *
- * This software is licensed as described in the file COPYING, which
- * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
- *
- * You may opt to use, copy, modify, merge, publish, distribute and/or sell
- * copies of the Software, and permit persons to whom the Software is
- * furnished to do so, under the terms of the COPYING file.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- ***************************************************************************/
-#include "curl_setup.h"
-
-#if (defined(USE_POLARSSL) || defined(USE_MBEDTLS)) && \
-    ((defined(USE_THREADS_POSIX) && defined(HAVE_PTHREAD_H)) || \
-     (defined(USE_THREADS_WIN32) && defined(HAVE_PROCESS_H)))
-
-#if defined(USE_THREADS_POSIX) && defined(HAVE_PTHREAD_H)
-#  include <pthread.h>
-#  define POLARSSL_MUTEX_T pthread_mutex_t
-#elif defined(USE_THREADS_WIN32) && defined(HAVE_PROCESS_H)
-#  include <process.h>
-#  define POLARSSL_MUTEX_T HANDLE
-#endif
-
-#include "polarssl_threadlock.h"
-#include "curl_printf.h"
-#include "curl_memory.h"
-/* The last #include file should be: */
-#include "memdebug.h"
-
-/* number of thread locks */
-#define NUMT                    2
-
-/* This array will store all of the mutexes available to PolarSSL. */
-static POLARSSL_MUTEX_T *mutex_buf = NULL;
-
-int Curl_polarsslthreadlock_thread_setup(void)
-{
-  int i;
-
-  mutex_buf = calloc(NUMT * sizeof(POLARSSL_MUTEX_T), 1);
-  if(!mutex_buf)
-    return 0;     /* error, no number of threads defined */
-
-  for(i = 0;  i < NUMT;  i++) {
-    int ret;
-#if defined(USE_THREADS_POSIX) && defined(HAVE_PTHREAD_H)
-    ret = pthread_mutex_init(&mutex_buf[i], NULL);
-    if(ret)
-      return 0; /* pthread_mutex_init failed */
-#elif defined(USE_THREADS_WIN32) && defined(HAVE_PROCESS_H)
-    mutex_buf[i] = CreateMutex(0, FALSE, 0);
-    if(mutex_buf[i] == 0)
-      return 0;  /* CreateMutex failed */
-#endif /* USE_THREADS_POSIX && HAVE_PTHREAD_H */
-  }
-
-  return 1; /* OK */
-}
-
-int Curl_polarsslthreadlock_thread_cleanup(void)
-{
-  int i;
-
-  if(!mutex_buf)
-    return 0; /* error, no threads locks defined */
-
-  for(i = 0; i < NUMT; i++) {
-    int ret;
-#if defined(USE_THREADS_POSIX) && defined(HAVE_PTHREAD_H)
-    ret = pthread_mutex_destroy(&mutex_buf[i]);
-    if(ret)
-      return 0; /* pthread_mutex_destroy failed */
-#elif defined(USE_THREADS_WIN32) && defined(HAVE_PROCESS_H)
-    ret = CloseHandle(mutex_buf[i]);
-    if(!ret)
-      return 0; /* CloseHandle failed */
-#endif /* USE_THREADS_POSIX && HAVE_PTHREAD_H */
-  }
-  free(mutex_buf);
-  mutex_buf = NULL;
-
-  return 1; /* OK */
-}
-
-int Curl_polarsslthreadlock_lock_function(int n)
-{
-  if(n < NUMT) {
-    int ret;
-#if defined(USE_THREADS_POSIX) && defined(HAVE_PTHREAD_H)
-    ret = pthread_mutex_lock(&mutex_buf[n]);
-    if(ret) {
-      DEBUGF(fprintf(stderr,
-                     "Error: polarsslthreadlock_lock_function failed\n"));
-      return 0; /* pthread_mutex_lock failed */
-    }
-#elif defined(USE_THREADS_WIN32) && defined(HAVE_PROCESS_H)
-    ret = (WaitForSingleObject(mutex_buf[n], INFINITE) == WAIT_FAILED?1:0);
-    if(ret) {
-      DEBUGF(fprintf(stderr,
-                     "Error: polarsslthreadlock_lock_function failed\n"));
-      return 0; /* pthread_mutex_lock failed */
-    }
-#endif /* USE_THREADS_POSIX && HAVE_PTHREAD_H */
-  }
-  return 1; /* OK */
-}
-
-int Curl_polarsslthreadlock_unlock_function(int n)
-{
-  if(n < NUMT) {
-    int ret;
-#if defined(USE_THREADS_POSIX) && defined(HAVE_PTHREAD_H)
-    ret = pthread_mutex_unlock(&mutex_buf[n]);
-    if(ret) {
-      DEBUGF(fprintf(stderr,
-                     "Error: polarsslthreadlock_unlock_function failed\n"));
-      return 0; /* pthread_mutex_unlock failed */
-    }
-#elif defined(USE_THREADS_WIN32) && defined(HAVE_PROCESS_H)
-    ret = ReleaseMutex(mutex_buf[n]);
-    if(!ret) {
-      DEBUGF(fprintf(stderr,
-                     "Error: polarsslthreadlock_unlock_function failed\n"));
-      return 0; /* pthread_mutex_lock failed */
-    }
-#endif /* USE_THREADS_POSIX && HAVE_PTHREAD_H */
-  }
-  return 1; /* OK */
-}
-
-#endif /* USE_POLARSSL || USE_MBEDTLS */
diff --git a/Utilities/cmcurl/lib/vtls/polarssl_threadlock.h b/Utilities/cmcurl/lib/vtls/polarssl_threadlock.h
deleted file mode 100644
index 1226475..0000000
--- a/Utilities/cmcurl/lib/vtls/polarssl_threadlock.h
+++ /dev/null
@@ -1,48 +0,0 @@
-#ifndef HEADER_CURL_POLARSSL_THREADLOCK_H
-#define HEADER_CURL_POLARSSL_THREADLOCK_H
-/***************************************************************************
- *                                  _   _ ____  _
- *  Project                     ___| | | |  _ \| |
- *                             / __| | | | |_) | |
- *                            | (__| |_| |  _ <| |___
- *                             \___|\___/|_| \_\_____|
- *
- * Copyright (C) 2013-2015, Daniel Stenberg, <daniel@haxx.se>, et al.
- * Copyright (C) 2010, Hoi-Ho Chan, <hoiho.chan@gmail.com>
- *
- * This software is licensed as described in the file COPYING, which
- * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
- *
- * You may opt to use, copy, modify, merge, publish, distribute and/or sell
- * copies of the Software, and permit persons to whom the Software is
- * furnished to do so, under the terms of the COPYING file.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- ***************************************************************************/
-#include "curl_setup.h"
-
-#if (defined USE_POLARSSL) || (defined USE_MBEDTLS)
-
-#if (defined(USE_THREADS_POSIX) && defined(HAVE_PTHREAD_H)) || \
-    (defined(USE_THREADS_WIN32) && defined(HAVE_PROCESS_H))
-
-int Curl_polarsslthreadlock_thread_setup(void);
-int Curl_polarsslthreadlock_thread_cleanup(void);
-int Curl_polarsslthreadlock_lock_function(int n);
-int Curl_polarsslthreadlock_unlock_function(int n);
-
-#else
-
-#define Curl_polarsslthreadlock_thread_setup() 1
-#define Curl_polarsslthreadlock_thread_cleanup() 1
-#define Curl_polarsslthreadlock_lock_function(x) 1
-#define Curl_polarsslthreadlock_unlock_function(x) 1
-
-#endif /* USE_THREADS_POSIX || USE_THREADS_WIN32 */
-
-#endif /* USE_POLARSSL */
-
-#endif /* HEADER_CURL_POLARSSL_THREADLOCK_H */
diff --git a/Utilities/cmcurl/lib/vtls/schannel.c b/Utilities/cmcurl/lib/vtls/schannel.c
index 0f6f734..1996526 100644
--- a/Utilities/cmcurl/lib/vtls/schannel.c
+++ b/Utilities/cmcurl/lib/vtls/schannel.c
@@ -7,7 +7,7 @@
  *
  * Copyright (C) 2012 - 2016, Marc Hoersken, <info@marc-hoersken.de>
  * Copyright (C) 2012, Mark Salisbury, <mark.salisbury@hp.com>
- * Copyright (C) 2012 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 2012 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -27,16 +27,6 @@
  * but vtls.c should ever call or use these functions.
  */
 
-/*
- * Based upon the PolarSSL implementation in polarssl.c and polarssl.h:
- *   Copyright (C) 2010, 2011, Hoi-Ho Chan, <hoiho.chan@gmail.com>
- *
- * Based upon the CyaSSL implementation in cyassl.c and cyassl.h:
- *   Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * Thanks for code and inspiration!
- */
-
 #include "curl_setup.h"
 
 #ifdef USE_SCHANNEL
@@ -49,10 +39,11 @@
 
 #include "schannel.h"
 #include "vtls.h"
+#include "strcase.h"
 #include "sendf.h"
 #include "connect.h" /* for the connect timeout */
 #include "strerror.h"
-#include "select.h" /* for the socket readyness */
+#include "select.h" /* for the socket readiness */
 #include "inet_pton.h" /* for IP addr SNI check */
 #include "curl_multibyte.h"
 #include "warnless.h"
@@ -61,7 +52,7 @@
 #include "multiif.h"
 #include "system_win32.h"
 
- /* The last #include file should be: */
+/* The last #include file should be: */
 #include "curl_memory.h"
 #include "memdebug.h"
 
@@ -179,25 +170,25 @@
   long i = ssl_version;
 
   switch(ssl_version_max) {
-    case CURL_SSLVERSION_MAX_NONE:
-    case CURL_SSLVERSION_MAX_DEFAULT:
-      ssl_version_max = CURL_SSLVERSION_MAX_TLSv1_2;
-      break;
+  case CURL_SSLVERSION_MAX_NONE:
+  case CURL_SSLVERSION_MAX_DEFAULT:
+    ssl_version_max = CURL_SSLVERSION_MAX_TLSv1_2;
+    break;
   }
   for(; i <= (ssl_version_max >> 16); ++i) {
     switch(i) {
-      case CURL_SSLVERSION_TLSv1_0:
-        schannel_cred->grbitEnabledProtocols |= SP_PROT_TLS1_0_CLIENT;
-        break;
-      case CURL_SSLVERSION_TLSv1_1:
-        schannel_cred->grbitEnabledProtocols |= SP_PROT_TLS1_1_CLIENT;
-        break;
-      case CURL_SSLVERSION_TLSv1_2:
-        schannel_cred->grbitEnabledProtocols |= SP_PROT_TLS1_2_CLIENT;
-        break;
-      case CURL_SSLVERSION_TLSv1_3:
-        failf(data, "schannel: TLS 1.3 is not yet supported");
-        return CURLE_SSL_CONNECT_ERROR;
+    case CURL_SSLVERSION_TLSv1_0:
+      schannel_cred->grbitEnabledProtocols |= SP_PROT_TLS1_0_CLIENT;
+      break;
+    case CURL_SSLVERSION_TLSv1_1:
+      schannel_cred->grbitEnabledProtocols |= SP_PROT_TLS1_1_CLIENT;
+      break;
+    case CURL_SSLVERSION_TLSv1_2:
+      schannel_cred->grbitEnabledProtocols |= SP_PROT_TLS1_2_CLIENT;
+      break;
+    case CURL_SSLVERSION_TLSv1_3:
+      failf(data, "schannel: TLS 1.3 is not yet supported");
+      return CURLE_SSL_CONNECT_ERROR;
     }
   }
   return CURLE_OK;
@@ -205,9 +196,9 @@
 
 /*longest is 26, buffer is slightly bigger*/
 #define LONGEST_ALG_ID 32
-#define CIPHEROPTION(X) \
-if(strcmp(#X, tmp) == 0) \
-  return X
+#define CIPHEROPTION(X)                         \
+  if(strcmp(#X, tmp) == 0)                      \
+    return X
 
 static int
 get_alg_id_by_name(char *name)
@@ -283,11 +274,11 @@
 #ifdef CALG_HMAC
   CIPHEROPTION(CALG_HMAC);
 #endif
-#if !defined(__W32API_MAJOR_VERSION) || \
-    !defined(__W32API_MINOR_VERSION) || \
-    defined(__MINGW64_VERSION_MAJOR) || \
-    (__W32API_MAJOR_VERSION > 5)     || \
-    ((__W32API_MAJOR_VERSION == 5) && (__W32API_MINOR_VERSION > 0))
+#if !defined(__W32API_MAJOR_VERSION) ||                                 \
+  !defined(__W32API_MINOR_VERSION) ||                                   \
+  defined(__MINGW64_VERSION_MAJOR) ||                                   \
+  (__W32API_MAJOR_VERSION > 5)     ||                                   \
+  ((__W32API_MAJOR_VERSION == 5) && (__W32API_MINOR_VERSION > 0))
   /* CALG_TLS1PRF has a syntax error in MinGW's w32api up to version 5.0,
      see https://osdn.net/projects/mingw/ticket/38391 */
   CIPHEROPTION(CALG_TLS1PRF);
@@ -349,7 +340,7 @@
     if(startCur)
       startCur++;
   }
-    schannel_cred->palgSupportedAlgs = algIds;
+  schannel_cred->palgSupportedAlgs = algIds;
   schannel_cred->cSupportedAlgs = algCount;
   return CURLE_OK;
 }
@@ -434,8 +425,12 @@
 #endif
   TCHAR *host_name;
   CURLcode result;
+#ifndef CURL_DISABLE_PROXY
   char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name :
     conn->host.name;
+#else
+  char * const hostname = conn->host.name;
+#endif
 
   DEBUGF(infof(data,
                "schannel: SSL/TLS connection with %s port %hu (step 1/3)\n",
@@ -443,20 +438,20 @@
 
   if(Curl_verify_windows_version(5, 1, PLATFORM_WINNT,
                                  VERSION_LESS_THAN_EQUAL)) {
-     /* Schannel in Windows XP (OS version 5.1) uses legacy handshakes and
-        algorithms that may not be supported by all servers. */
-     infof(data, "schannel: Windows version is old and may not be able to "
-           "connect to some servers due to lack of SNI, algorithms, etc.\n");
+    /* Schannel in Windows XP (OS version 5.1) uses legacy handshakes and
+       algorithms that may not be supported by all servers. */
+    infof(data, "schannel: Windows version is old and may not be able to "
+          "connect to some servers due to lack of SNI, algorithms, etc.\n");
   }
 
 #ifdef HAS_ALPN
   /* ALPN is only supported on Windows 8.1 / Server 2012 R2 and above.
      Also it doesn't seem to be supported for Wine, see curl bug #983. */
   BACKEND->use_alpn = conn->bits.tls_enable_alpn &&
-                      !GetProcAddress(GetModuleHandleA("ntdll"),
-                                      "wine_get_version") &&
-                      Curl_verify_windows_version(6, 3, PLATFORM_WINNT,
-                                                  VERSION_GREATER_THAN_EQUAL);
+    !GetProcAddress(GetModuleHandleA("ntdll"),
+                    "wine_get_version") &&
+    Curl_verify_windows_version(6, 3, PLATFORM_WINNT,
+                                VERSION_GREATER_THAN_EQUAL);
 #else
   BACKEND->use_alpn = false;
 #endif
@@ -530,8 +525,15 @@
         DEBUGF(infof(data, "schannel: disabled server certificate revocation "
                      "checks\n"));
       }
+      else if(data->set.ssl.revoke_best_effort) {
+        schannel_cred.dwFlags |= SCH_CRED_IGNORE_NO_REVOCATION_CHECK |
+          SCH_CRED_IGNORE_REVOCATION_OFFLINE | SCH_CRED_REVOCATION_CHECK_CHAIN;
+
+        DEBUGF(infof(data, "schannel: ignore revocation offline errors"));
+      }
       else {
         schannel_cred.dwFlags |= SCH_CRED_REVOCATION_CHECK_CHAIN;
+
         DEBUGF(infof(data,
                      "schannel: checking server certificate revocation\n"));
       }
@@ -554,20 +556,16 @@
     switch(conn->ssl_config.version) {
     case CURL_SSLVERSION_DEFAULT:
     case CURL_SSLVERSION_TLSv1:
-      schannel_cred.grbitEnabledProtocols = SP_PROT_TLS1_0_CLIENT |
-        SP_PROT_TLS1_1_CLIENT |
-        SP_PROT_TLS1_2_CLIENT;
-      break;
     case CURL_SSLVERSION_TLSv1_0:
     case CURL_SSLVERSION_TLSv1_1:
     case CURL_SSLVERSION_TLSv1_2:
     case CURL_SSLVERSION_TLSv1_3:
-      {
-        result = set_ssl_version_min_max(&schannel_cred, conn);
-        if(result != CURLE_OK)
-          return result;
-        break;
-      }
+    {
+      result = set_ssl_version_min_max(&schannel_cred, conn);
+      if(result != CURLE_OK)
+        return result;
+      break;
+    }
     case CURL_SSLVERSION_SSLv3:
       schannel_cred.grbitEnabledProtocols = SP_PROT_SSL3_CLIENT;
       break;
@@ -590,68 +588,186 @@
 
 #ifdef HAS_CLIENT_CERT_PATH
     /* client certificate */
-    if(data->set.ssl.cert) {
-      DWORD cert_store_name;
-      TCHAR *cert_store_path;
-      TCHAR *cert_thumbprint_str;
+    if(data->set.ssl.cert || data->set.ssl.cert_blob) {
+      DWORD cert_store_name = 0;
+      TCHAR *cert_store_path = NULL;
+      TCHAR *cert_thumbprint_str = NULL;
       CRYPT_HASH_BLOB cert_thumbprint;
       BYTE cert_thumbprint_data[CERT_THUMBPRINT_DATA_LEN];
-      HCERTSTORE cert_store;
+      HCERTSTORE cert_store = NULL;
+      FILE *fInCert = NULL;
+      void *certdata = NULL;
+      size_t certsize = 0;
+      bool blob = data->set.ssl.cert_blob != NULL;
+      TCHAR *cert_path = NULL;
+      if(blob) {
+        certdata = data->set.ssl.cert_blob->data;
+        certsize = data->set.ssl.cert_blob->len;
+      }
+      else {
+        cert_path = curlx_convert_UTF8_to_tchar(data->set.ssl.cert);
+        if(!cert_path)
+          return CURLE_OUT_OF_MEMORY;
 
-      TCHAR *cert_path = Curl_convert_UTF8_to_tchar(data->set.ssl.cert);
-      if(!cert_path)
-        return CURLE_OUT_OF_MEMORY;
+        result = get_cert_location(cert_path, &cert_store_name,
+          &cert_store_path, &cert_thumbprint_str);
 
-      result = get_cert_location(cert_path, &cert_store_name,
-                                 &cert_store_path, &cert_thumbprint_str);
-      if(result != CURLE_OK) {
-        failf(data, "schannel: Failed to get certificate location for %s",
-              cert_path);
-        Curl_unicodefree(cert_path);
-        return result;
+        if(result && (data->set.ssl.cert[0]!='\0'))
+          fInCert = fopen(data->set.ssl.cert, "rb");
+
+        if(result && !fInCert) {
+          failf(data, "schannel: Failed to get certificate location"
+                " or file for %s",
+                data->set.ssl.cert);
+          curlx_unicodefree(cert_path);
+          return result;
+        }
       }
 
-      cert_store =
-        CertOpenStore(CURL_CERT_STORE_PROV_SYSTEM, 0,
-                      (HCRYPTPROV)NULL,
-                      CERT_STORE_OPEN_EXISTING_FLAG | cert_store_name,
-                      cert_store_path);
-      if(!cert_store) {
-        failf(data, "schannel: Failed to open cert store %x %s, "
-              "last error is %x",
-              cert_store_name, cert_store_path, GetLastError());
-        free(cert_store_path);
-        Curl_unicodefree(cert_path);
-        return CURLE_SSL_CERTPROBLEM;
-      }
-      free(cert_store_path);
-
-      cert_thumbprint.pbData = cert_thumbprint_data;
-      cert_thumbprint.cbData = CERT_THUMBPRINT_DATA_LEN;
-
-      if(!CryptStringToBinary(cert_thumbprint_str, CERT_THUMBPRINT_STR_LEN,
-                              CRYPT_STRING_HEX,
-                              cert_thumbprint_data, &cert_thumbprint.cbData,
-                              NULL, NULL)) {
-        Curl_unicodefree(cert_path);
+      if((fInCert || blob) && (data->set.ssl.cert_type) &&
+          (!strcasecompare(data->set.ssl.cert_type, "P12"))) {
+        failf(data, "schannel: certificate format compatibility error "
+                " for %s",
+                blob ? "(memory blob)" : data->set.ssl.cert);
+        curlx_unicodefree(cert_path);
         return CURLE_SSL_CERTPROBLEM;
       }
 
-      client_certs[0] = CertFindCertificateInStore(
-        cert_store, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, 0,
-        CERT_FIND_HASH, &cert_thumbprint, NULL);
+      if(fInCert || blob) {
+        /* Reading a .P12 or .pfx file, like the example at bottom of
+             https://social.msdn.microsoft.com/Forums/windowsdesktop/
+                            en-US/3e7bc95f-b21a-4bcd-bd2c-7f996718cae5
+        */
+        CRYPT_DATA_BLOB datablob;
+        WCHAR* pszPassword;
+        size_t pwd_len = 0;
+        int str_w_len = 0;
+        const char *cert_showfilename_error = blob ?
+          "(memory blob)" : data->set.ssl.cert;
+        curlx_unicodefree(cert_path);
+        if(fInCert) {
+          long cert_tell = 0;
+          bool continue_reading = fseek(fInCert, 0, SEEK_END) == 0;
+          if(continue_reading)
+            cert_tell = ftell(fInCert);
+          if(cert_tell < 0)
+            continue_reading = FALSE;
+          else
+            certsize = (size_t)cert_tell;
+          if(continue_reading)
+            continue_reading = fseek(fInCert, 0, SEEK_SET) == 0;
+          if(continue_reading)
+            certdata = malloc(certsize + 1);
+          if((!certdata) ||
+             ((int) fread(certdata, certsize, 1, fInCert) != 1))
+            continue_reading = FALSE;
+          fclose(fInCert);
+          if(!continue_reading) {
+            failf(data, "schannel: Failed to read cert file %s",
+                data->set.ssl.cert);
+            free(certdata);
+            return CURLE_SSL_CERTPROBLEM;
+          }
+        }
 
-      Curl_unicodefree(cert_path);
+        /* Convert key-pair data to the in-memory certificate store */
+        datablob.pbData = (BYTE*)certdata;
+        datablob.cbData = (DWORD)certsize;
 
-      if(client_certs[0]) {
+        if(data->set.ssl.key_passwd != NULL)
+          pwd_len = strlen(data->set.ssl.key_passwd);
+        pszPassword = (WCHAR*)malloc(sizeof(WCHAR)*(pwd_len + 1));
+        if(pszPassword) {
+          if(pwd_len > 0)
+            str_w_len = MultiByteToWideChar(CP_UTF8,
+               MB_ERR_INVALID_CHARS,
+               data->set.ssl.key_passwd, (int)pwd_len,
+               pszPassword, (int)(pwd_len + 1));
+
+          if((str_w_len >= 0) && (str_w_len <= (int)pwd_len))
+            pszPassword[str_w_len] = 0;
+          else
+            pszPassword[0] = 0;
+
+          cert_store = PFXImportCertStore(&datablob, pszPassword, 0);
+          free(pszPassword);
+        }
+        if(!blob)
+          free(certdata);
+        if(cert_store == NULL) {
+          DWORD errorcode = GetLastError();
+          if(errorcode == ERROR_INVALID_PASSWORD)
+            failf(data, "schannel: Failed to import cert file %s, "
+                  "password is bad",
+                  cert_showfilename_error);
+          else
+            failf(data, "schannel: Failed to import cert file %s, "
+                  "last error is 0x%x",
+                  cert_showfilename_error, errorcode);
+          return CURLE_SSL_CERTPROBLEM;
+        }
+
+        client_certs[0] = CertFindCertificateInStore(
+          cert_store, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, 0,
+          CERT_FIND_ANY, NULL, NULL);
+
+        if(client_certs[0] == NULL) {
+          failf(data, "schannel: Failed to get certificate from file %s"
+                ", last error is 0x%x",
+                cert_showfilename_error, GetLastError());
+          CertCloseStore(cert_store, 0);
+          return CURLE_SSL_CERTPROBLEM;
+        }
+
         schannel_cred.cCreds = 1;
         schannel_cred.paCred = client_certs;
       }
       else {
-        /* CRYPT_E_NOT_FOUND / E_INVALIDARG */
-        return CURLE_SSL_CERTPROBLEM;
-      }
+        cert_store =
+          CertOpenStore(CURL_CERT_STORE_PROV_SYSTEM, 0,
+                        (HCRYPTPROV)NULL,
+                        CERT_STORE_OPEN_EXISTING_FLAG | cert_store_name,
+                        cert_store_path);
+        if(!cert_store) {
+          failf(data, "schannel: Failed to open cert store %x %s, "
+                "last error is 0x%x",
+                cert_store_name, cert_store_path, GetLastError());
+          free(cert_store_path);
+          curlx_unicodefree(cert_path);
+          return CURLE_SSL_CERTPROBLEM;
+        }
+        free(cert_store_path);
 
+        cert_thumbprint.pbData = cert_thumbprint_data;
+        cert_thumbprint.cbData = CERT_THUMBPRINT_DATA_LEN;
+
+        if(!CryptStringToBinary(cert_thumbprint_str,
+                                CERT_THUMBPRINT_STR_LEN,
+                                CRYPT_STRING_HEX,
+                                cert_thumbprint_data,
+                                &cert_thumbprint.cbData,
+                                NULL, NULL)) {
+          curlx_unicodefree(cert_path);
+          CertCloseStore(cert_store, 0);
+          return CURLE_SSL_CERTPROBLEM;
+        }
+
+        client_certs[0] = CertFindCertificateInStore(
+          cert_store, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, 0,
+          CERT_FIND_HASH, &cert_thumbprint, NULL);
+
+        curlx_unicodefree(cert_path);
+
+        if(client_certs[0]) {
+          schannel_cred.cCreds = 1;
+          schannel_cred.paCred = client_certs;
+        }
+        else {
+          /* CRYPT_E_NOT_FOUND / E_INVALIDARG */
+          CertCloseStore(cert_store, 0);
+          return CURLE_SSL_CERTPROBLEM;
+        }
+      }
       CertCloseStore(cert_store, 0);
     }
 #else
@@ -675,7 +791,7 @@
     BACKEND->cred->refcount = 1;
 
     /* https://msdn.microsoft.com/en-us/library/windows/desktop/aa374716.aspx
-       */
+     */
     sspi_status =
       s_pSecFn->AcquireCredentialsHandle(NULL, (TCHAR *)UNISP_NAME,
                                          SECPKG_CRED_OUTBOUND, NULL,
@@ -692,15 +808,15 @@
             Curl_sspi_strerror(sspi_status, buffer, sizeof(buffer)));
       Curl_safefree(BACKEND->cred);
       switch(sspi_status) {
-        case SEC_E_INSUFFICIENT_MEMORY:
-          return CURLE_OUT_OF_MEMORY;
-        case SEC_E_NO_CREDENTIALS:
-        case SEC_E_SECPKG_NOT_FOUND:
-        case SEC_E_NOT_OWNER:
-        case SEC_E_UNKNOWN_CREDENTIALS:
-        case SEC_E_INTERNAL_ERROR:
-        default:
-          return CURLE_SSL_CONNECT_ERROR;
+      case SEC_E_INSUFFICIENT_MEMORY:
+        return CURLE_OUT_OF_MEMORY;
+      case SEC_E_NO_CREDENTIALS:
+      case SEC_E_SECPKG_NOT_FOUND:
+      case SEC_E_NOT_OWNER:
+      case SEC_E_UNKNOWN_CREDENTIALS:
+      case SEC_E_INTERNAL_ERROR:
+      default:
+        return CURLE_SSL_CONNECT_ERROR;
       }
     }
   }
@@ -722,7 +838,7 @@
     unsigned short* list_len = NULL;
 
     /* The first four bytes will be an unsigned int indicating number
-       of bytes of data in the rest of the the buffer. */
+       of bytes of data in the rest of the buffer. */
     extension_len = (unsigned int *)(&alpn_buffer[cur]);
     cur += sizeof(unsigned int);
 
@@ -784,7 +900,7 @@
     return CURLE_OUT_OF_MEMORY;
   }
 
-  host_name = Curl_convert_UTF8_to_tchar(hostname);
+  host_name = curlx_convert_UTF8_to_tchar(hostname);
   if(!host_name)
     return CURLE_OUT_OF_MEMORY;
 
@@ -801,35 +917,35 @@
     0, &BACKEND->ctxt->ctxt_handle,
     &outbuf_desc, &BACKEND->ret_flags, &BACKEND->ctxt->time_stamp);
 
-  Curl_unicodefree(host_name);
+  curlx_unicodefree(host_name);
 
   if(sspi_status != SEC_I_CONTINUE_NEEDED) {
     char buffer[STRERROR_LEN];
     Curl_safefree(BACKEND->ctxt);
     switch(sspi_status) {
-      case SEC_E_INSUFFICIENT_MEMORY:
-        failf(data, "schannel: initial InitializeSecurityContext failed: %s",
-              Curl_sspi_strerror(sspi_status, buffer, sizeof(buffer)));
-        return CURLE_OUT_OF_MEMORY;
-      case SEC_E_WRONG_PRINCIPAL:
-        failf(data, "schannel: SNI or certificate check failed: %s",
-              Curl_sspi_strerror(sspi_status, buffer, sizeof(buffer)));
-        return CURLE_PEER_FAILED_VERIFICATION;
-        /*
-      case SEC_E_INVALID_HANDLE:
-      case SEC_E_INVALID_TOKEN:
-      case SEC_E_LOGON_DENIED:
-      case SEC_E_TARGET_UNKNOWN:
-      case SEC_E_NO_AUTHENTICATING_AUTHORITY:
-      case SEC_E_INTERNAL_ERROR:
-      case SEC_E_NO_CREDENTIALS:
-      case SEC_E_UNSUPPORTED_FUNCTION:
-      case SEC_E_APPLICATION_PROTOCOL_MISMATCH:
-        */
-      default:
-        failf(data, "schannel: initial InitializeSecurityContext failed: %s",
-              Curl_sspi_strerror(sspi_status, buffer, sizeof(buffer)));
-        return CURLE_SSL_CONNECT_ERROR;
+    case SEC_E_INSUFFICIENT_MEMORY:
+      failf(data, "schannel: initial InitializeSecurityContext failed: %s",
+            Curl_sspi_strerror(sspi_status, buffer, sizeof(buffer)));
+      return CURLE_OUT_OF_MEMORY;
+    case SEC_E_WRONG_PRINCIPAL:
+      failf(data, "schannel: SNI or certificate check failed: %s",
+            Curl_sspi_strerror(sspi_status, buffer, sizeof(buffer)));
+      return CURLE_PEER_FAILED_VERIFICATION;
+      /*
+        case SEC_E_INVALID_HANDLE:
+        case SEC_E_INVALID_TOKEN:
+        case SEC_E_LOGON_DENIED:
+        case SEC_E_TARGET_UNKNOWN:
+        case SEC_E_NO_AUTHENTICATING_AUTHORITY:
+        case SEC_E_INTERNAL_ERROR:
+        case SEC_E_NO_CREDENTIALS:
+        case SEC_E_UNSUPPORTED_FUNCTION:
+        case SEC_E_APPLICATION_PROTOCOL_MISMATCH:
+      */
+    default:
+      failf(data, "schannel: initial InitializeSecurityContext failed: %s",
+            Curl_sspi_strerror(sspi_status, buffer, sizeof(buffer)));
+      return CURLE_SSL_CONNECT_ERROR;
     }
   }
 
@@ -875,8 +991,12 @@
   SECURITY_STATUS sspi_status = SEC_E_OK;
   CURLcode result;
   bool doread;
+#ifndef CURL_DISABLE_PROXY
   char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name :
     conn->host.name;
+#else
+  char * const hostname = conn->host.name;
+#endif
   const char *pubkey_ptr;
 
   doread = (connssl->connecting_state != ssl_connect_2_writing) ? TRUE : FALSE;
@@ -984,18 +1104,18 @@
     memcpy(inbuf[0].pvBuffer, BACKEND->encdata_buffer,
            BACKEND->encdata_offset);
 
-    host_name = Curl_convert_UTF8_to_tchar(hostname);
+    host_name = curlx_convert_UTF8_to_tchar(hostname);
     if(!host_name)
       return CURLE_OUT_OF_MEMORY;
 
     /* https://msdn.microsoft.com/en-us/library/windows/desktop/aa375924.aspx
-       */
+     */
     sspi_status = s_pSecFn->InitializeSecurityContext(
       &BACKEND->cred->cred_handle, &BACKEND->ctxt->ctxt_handle,
       host_name, BACKEND->req_flags, 0, 0, &inbuf_desc, 0, NULL,
       &outbuf_desc, &BACKEND->ret_flags, &BACKEND->ctxt->time_stamp);
 
-    Curl_unicodefree(host_name);
+    curlx_unicodefree(host_name);
 
     /* free buffer for received handshake data */
     Curl_safefree(inbuf[0].pvBuffer);
@@ -1050,29 +1170,29 @@
     else {
       char buffer[STRERROR_LEN];
       switch(sspi_status) {
-        case SEC_E_INSUFFICIENT_MEMORY:
-          failf(data, "schannel: next InitializeSecurityContext failed: %s",
-                Curl_sspi_strerror(sspi_status, buffer, sizeof(buffer)));
-          return CURLE_OUT_OF_MEMORY;
-        case SEC_E_WRONG_PRINCIPAL:
-          failf(data, "schannel: SNI or certificate check failed: %s",
-                Curl_sspi_strerror(sspi_status, buffer, sizeof(buffer)));
-          return CURLE_PEER_FAILED_VERIFICATION;
-          /*
-        case SEC_E_INVALID_HANDLE:
-        case SEC_E_INVALID_TOKEN:
-        case SEC_E_LOGON_DENIED:
-        case SEC_E_TARGET_UNKNOWN:
-        case SEC_E_NO_AUTHENTICATING_AUTHORITY:
-        case SEC_E_INTERNAL_ERROR:
-        case SEC_E_NO_CREDENTIALS:
-        case SEC_E_UNSUPPORTED_FUNCTION:
-        case SEC_E_APPLICATION_PROTOCOL_MISMATCH:
-          */
-        default:
-          failf(data, "schannel: next InitializeSecurityContext failed: %s",
-                Curl_sspi_strerror(sspi_status, buffer, sizeof(buffer)));
-          return CURLE_SSL_CONNECT_ERROR;
+      case SEC_E_INSUFFICIENT_MEMORY:
+        failf(data, "schannel: next InitializeSecurityContext failed: %s",
+              Curl_sspi_strerror(sspi_status, buffer, sizeof(buffer)));
+        return CURLE_OUT_OF_MEMORY;
+      case SEC_E_WRONG_PRINCIPAL:
+        failf(data, "schannel: SNI or certificate check failed: %s",
+              Curl_sspi_strerror(sspi_status, buffer, sizeof(buffer)));
+        return CURLE_PEER_FAILED_VERIFICATION;
+        /*
+          case SEC_E_INVALID_HANDLE:
+          case SEC_E_INVALID_TOKEN:
+          case SEC_E_LOGON_DENIED:
+          case SEC_E_TARGET_UNKNOWN:
+          case SEC_E_NO_AUTHENTICATING_AUTHORITY:
+          case SEC_E_INTERNAL_ERROR:
+          case SEC_E_NO_CREDENTIALS:
+          case SEC_E_UNSUPPORTED_FUNCTION:
+          case SEC_E_APPLICATION_PROTOCOL_MISMATCH:
+        */
+      default:
+        failf(data, "schannel: next InitializeSecurityContext failed: %s",
+              Curl_sspi_strerror(sspi_status, buffer, sizeof(buffer)));
+        return CURLE_SSL_CONNECT_ERROR;
       }
     }
 
@@ -1181,6 +1301,7 @@
   struct connectdata *conn;
   CURLcode result;
   int idx;
+  int certs_count;
 };
 
 static bool
@@ -1191,7 +1312,9 @@
   if(valid_cert_encoding(ccert_context)) {
     const char *beg = (const char *) ccert_context->pbCertEncoded;
     const char *end = beg + ccert_context->cbCertEncoded;
-    args->result = Curl_extract_certinfo(args->conn, (args->idx)++, beg, end);
+    int insert_index = (args->certs_count - 1) - args->idx;
+    args->result = Curl_extract_certinfo(args->conn, insert_index, beg, end);
+    args->idx++;
   }
   return args->result == CURLE_OK;
 }
@@ -1238,8 +1361,10 @@
 
 #ifdef HAS_ALPN
   if(BACKEND->use_alpn) {
-    sspi_status = s_pSecFn->QueryContextAttributes(&BACKEND->ctxt->ctxt_handle,
-      SECPKG_ATTR_APPLICATION_PROTOCOL, &alpn_result);
+    sspi_status =
+      s_pSecFn->QueryContextAttributes(&BACKEND->ctxt->ctxt_handle,
+                                       SECPKG_ATTR_APPLICATION_PROTOCOL,
+                                       &alpn_result);
 
     if(sspi_status != SEC_E_OK) {
       failf(data, "schannel: failed to retrieve ALPN result");
@@ -1250,21 +1375,21 @@
        SecApplicationProtocolNegotiationStatus_Success) {
 
       infof(data, "schannel: ALPN, server accepted to use %.*s\n",
-        alpn_result.ProtocolIdSize, alpn_result.ProtocolId);
+            alpn_result.ProtocolIdSize, alpn_result.ProtocolId);
 
 #ifdef USE_NGHTTP2
       if(alpn_result.ProtocolIdSize == NGHTTP2_PROTO_VERSION_ID_LEN &&
          !memcmp(NGHTTP2_PROTO_VERSION_ID, alpn_result.ProtocolId,
-          NGHTTP2_PROTO_VERSION_ID_LEN)) {
+                 NGHTTP2_PROTO_VERSION_ID_LEN)) {
         conn->negnpn = CURL_HTTP_VERSION_2;
       }
       else
 #endif
-      if(alpn_result.ProtocolIdSize == ALPN_HTTP_1_1_LENGTH &&
-         !memcmp(ALPN_HTTP_1_1, alpn_result.ProtocolId,
-           ALPN_HTTP_1_1_LENGTH)) {
-        conn->negnpn = CURL_HTTP_VERSION_1_1;
-      }
+        if(alpn_result.ProtocolIdSize == ALPN_HTTP_1_1_LENGTH &&
+           !memcmp(ALPN_HTTP_1_1, alpn_result.ProtocolId,
+                   ALPN_HTTP_1_1_LENGTH)) {
+          conn->negnpn = CURL_HTTP_VERSION_1_1;
+        }
     }
     else
       infof(data, "ALPN, server did not agree to a protocol\n");
@@ -1311,8 +1436,10 @@
 
   if(data->set.ssl.certinfo) {
     int certs_count = 0;
-    sspi_status = s_pSecFn->QueryContextAttributes(&BACKEND->ctxt->ctxt_handle,
-      SECPKG_ATTR_REMOTE_CERT_CONTEXT, &ccert_context);
+    sspi_status =
+      s_pSecFn->QueryContextAttributes(&BACKEND->ctxt->ctxt_handle,
+                                       SECPKG_ATTR_REMOTE_CERT_CONTEXT,
+                                       &ccert_context);
 
     if((sspi_status != SEC_E_OK) || (ccert_context == NULL)) {
       failf(data, "schannel: failed to retrieve remote cert context");
@@ -1326,6 +1453,7 @@
       struct Adder_args args;
       args.conn = conn;
       args.idx = 0;
+      args.certs_count = certs_count;
       traverse_cert_store(ccert_context, add_cert_to_certinfo, &args);
       result = args.result;
     }
@@ -1347,7 +1475,7 @@
   struct Curl_easy *data = conn->data;
   struct ssl_connect_data *connssl = &conn->ssl[sockindex];
   curl_socket_t sockfd = conn->sock[sockindex];
-  time_t timeout_ms;
+  timediff_t timeout_ms;
   int what;
 
   /* check if the connection has already been established */
@@ -1543,14 +1671,10 @@
 
     /* send entire message or fail */
     while(len > (size_t)written) {
-      ssize_t this_write;
-      time_t timeleft;
+      ssize_t this_write = 0;
       int what;
-
-      this_write = 0;
-
-      timeleft = Curl_timeleft(conn->data, NULL, FALSE);
-      if(timeleft < 0) {
+      timediff_t timeout_ms = Curl_timeleft(conn->data, NULL, FALSE);
+      if(timeout_ms < 0) {
         /* we already got the timeout */
         failf(conn->data, "schannel: timed out sending data "
               "(bytes sent: %zd)", written);
@@ -1558,8 +1682,9 @@
         written = -1;
         break;
       }
-
-      what = SOCKET_WRITABLE(conn->sock[sockindex], timeleft);
+      else if(!timeout_ms)
+        timeout_ms = TIMEDIFF_T_MAX;
+      what = SOCKET_WRITABLE(conn->sock[sockindex], timeout_ms);
       if(what < 0) {
         /* fatal error */
         failf(conn->data, "select/poll on SSL socket, errno: %d", SOCKERRNO);
@@ -1653,8 +1778,8 @@
   }
   else if(!len) {
     /* It's debatable what to return when !len. Regardless we can't return
-    immediately because there may be data to decrypt (in the case we want to
-    decrypt all encrypted cached data) so handle !len later in cleanup.
+       immediately because there may be data to decrypt (in the case we want to
+       decrypt all encrypted cached data) so handle !len later in cleanup.
     */
     ; /* do nothing */
   }
@@ -1664,7 +1789,7 @@
     if(size < CURL_SCHANNEL_BUFFER_FREE_SIZE ||
        BACKEND->encdata_length < min_encdata_length) {
       reallocated_length = BACKEND->encdata_offset +
-                           CURL_SCHANNEL_BUFFER_FREE_SIZE;
+        CURL_SCHANNEL_BUFFER_FREE_SIZE;
       if(reallocated_length < min_encdata_length) {
         reallocated_length = min_encdata_length;
       }
@@ -1732,7 +1857,7 @@
     InitSecBufferDesc(&inbuf_desc, inbuf, 4);
 
     /* https://msdn.microsoft.com/en-us/library/windows/desktop/aa375348.aspx
-       */
+     */
     sspi_status = s_pSecFn->DecryptMessage(&BACKEND->ctxt->ctxt_handle,
                                            &inbuf_desc, 0, NULL);
 
@@ -1748,7 +1873,7 @@
 
         /* increase buffer in order to fit the received amount of data */
         size = inbuf[1].cbBuffer > CURL_SCHANNEL_BUFFER_FREE_SIZE ?
-               inbuf[1].cbBuffer : CURL_SCHANNEL_BUFFER_FREE_SIZE;
+          inbuf[1].cbBuffer : CURL_SCHANNEL_BUFFER_FREE_SIZE;
         if(BACKEND->decdata_length - BACKEND->decdata_offset < size ||
            BACKEND->decdata_length < len) {
           /* increase internal decrypted data buffer */
@@ -1818,7 +1943,7 @@
         if(BACKEND->encdata_offset) {
           *err = CURLE_RECV_ERROR;
           infof(data, "schannel: can't renogotiate, "
-                      "encrypted data available\n");
+                "encrypted data available\n");
           goto cleanup;
         }
         /* begin renegotiation */
@@ -1855,7 +1980,9 @@
       goto cleanup;
     }
     else {
+#ifndef CURL_DISABLE_VERBOSE_STRINGS
       char buffer[STRERROR_LEN];
+#endif
       *err = CURLE_RECV_ERROR;
       infof(data, "schannel: failed to read data from server: %s\n",
             Curl_sspi_strerror(sspi_status, buffer, sizeof(buffer)));
@@ -1871,17 +1998,20 @@
                "schannel: decrypted data buffer: offset %zu length %zu\n",
                BACKEND->decdata_offset, BACKEND->decdata_length));
 
-cleanup:
+  cleanup:
   /* Warning- there is no guarantee the encdata state is valid at this point */
   DEBUGF(infof(data, "schannel: schannel_recv cleanup\n"));
 
   /* Error if the connection has closed without a close_notify.
-  Behavior here is a matter of debate. We don't want to be vulnerable to a
-  truncation attack however there's some browser precedent for ignoring the
-  close_notify for compatibility reasons.
-  Additionally, Windows 2000 (v5.0) is a special case since it seems it doesn't
-  return close_notify. In that case if the connection was closed we assume it
-  was graceful (close_notify) since there doesn't seem to be a way to tell.
+
+     The behavior here is a matter of debate. We don't want to be vulnerable
+     to a truncation attack however there's some browser precedent for
+     ignoring the close_notify for compatibility reasons.
+
+     Additionally, Windows 2000 (v5.0) is a special case since it seems it
+     doesn't return close_notify. In that case if the connection was closed we
+     assume it was graceful (close_notify) since there doesn't seem to be a
+     way to tell.
   */
   if(len && !BACKEND->decdata_offset && BACKEND->recv_connection_closed &&
      !BACKEND->recv_sspi_close_notify) {
@@ -1898,7 +2028,7 @@
 
   /* Any error other than CURLE_AGAIN is an unrecoverable error. */
   if(*err && *err != CURLE_AGAIN)
-      BACKEND->recv_unrecoverable_err = *err;
+    BACKEND->recv_unrecoverable_err = *err;
 
   size = len < BACKEND->decdata_offset ? len : BACKEND->decdata_offset;
   if(size) {
@@ -1915,10 +2045,11 @@
   }
 
   if(!*err && !BACKEND->recv_connection_closed)
-      *err = CURLE_AGAIN;
+    *err = CURLE_AGAIN;
 
-  /* It's debatable what to return when !len. We could return whatever error we
-  got from decryption but instead we override here so the return is consistent.
+  /* It's debatable what to return when !len. We could return whatever error
+     we got from decryption but instead we override here so the return is
+     consistent.
   */
   if(!len)
     *err = CURLE_OK;
@@ -1984,8 +2115,12 @@
    */
   struct Curl_easy *data = conn->data;
   struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+#ifndef CURL_DISABLE_PROXY
   char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name :
     conn->host.name;
+#else
+  char * const hostname = conn->host.name;
+#endif
 
   DEBUGASSERT(data);
 
@@ -2014,7 +2149,7 @@
             Curl_sspi_strerror(sspi_status, buffer, sizeof(buffer)));
     }
 
-    host_name = Curl_convert_UTF8_to_tchar(hostname);
+    host_name = curlx_convert_UTF8_to_tchar(hostname);
     if(!host_name)
       return CURLE_OUT_OF_MEMORY;
 
@@ -2036,7 +2171,7 @@
       &BACKEND->ret_flags,
       &BACKEND->ctxt->time_stamp);
 
-    Curl_unicodefree(host_name);
+    curlx_unicodefree(host_name);
 
     if((sspi_status == SEC_E_OK) || (sspi_status == SEC_I_CONTEXT_EXPIRED)) {
       /* send close message which is in output buffer */
@@ -2145,8 +2280,8 @@
     SECURITY_STATUS sspi_status;
     const char *x509_der;
     DWORD x509_der_len;
-    curl_X509certificate x509_parsed;
-    curl_asn1Element *pubkey;
+    struct Curl_X509certificate x509_parsed;
+    struct Curl_asn1Element *pubkey;
 
     sspi_status =
       s_pSecFn->QueryContextAttributes(&BACKEND->ctxt->ctxt_handle,
@@ -2162,7 +2297,7 @@
 
 
     if(!(((pCertContextServer->dwCertEncodingType & X509_ASN_ENCODING) != 0) &&
-       (pCertContextServer->cbCertEncoded > 0)))
+         (pCertContextServer->cbCertEncoded > 0)))
       break;
 
     x509_der = (const char *)pCertContextServer->pbCertEncoded;
@@ -2211,7 +2346,7 @@
   memset(checksum, 0, checksumlen);
 
   if(!CryptAcquireContext(&hProv, NULL, NULL, provType,
-                          CRYPT_VERIFYCONTEXT))
+                          CRYPT_VERIFYCONTEXT | CRYPT_SILENT))
     return; /* failed */
 
   do {
@@ -2253,9 +2388,9 @@
 }
 
 static CURLcode Curl_schannel_sha256sum(const unsigned char *input,
-                                    size_t inputlen,
-                                    unsigned char *sha256sum,
-                                    size_t sha256len)
+                                        size_t inputlen,
+                                        unsigned char *sha256sum,
+                                        size_t sha256len)
 {
   Curl_schannel_checksum(input, inputlen, sha256sum, sha256len,
                          PROV_RSA_AES, CALG_SHA_256);
diff --git a/Utilities/cmcurl/lib/vtls/schannel_verify.c b/Utilities/cmcurl/lib/vtls/schannel_verify.c
index 5a09e96..bdd7199 100644
--- a/Utilities/cmcurl/lib/vtls/schannel_verify.c
+++ b/Utilities/cmcurl/lib/vtls/schannel_verify.c
@@ -7,7 +7,7 @@
  *
  * Copyright (C) 2012 - 2016, Marc Hoersken, <info@marc-hoersken.de>
  * Copyright (C) 2012, Mark Salisbury, <mark.salisbury@hp.com>
- * Copyright (C) 2012 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 2012 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -57,7 +57,7 @@
 #define BEGIN_CERT "-----BEGIN CERTIFICATE-----"
 #define END_CERT "\n-----END CERTIFICATE-----"
 
-typedef struct {
+struct cert_chain_engine_config_win7 {
   DWORD cbSize;
   HCERTSTORE hRestrictedRoot;
   HCERTSTORE hRestrictedTrust;
@@ -70,7 +70,7 @@
   DWORD CycleDetectionModulus;
   HCERTSTORE hExclusiveRoot;
   HCERTSTORE hExclusiveTrustedPeople;
-} CERT_CHAIN_ENGINE_CONFIG_WIN7, *PCERT_CHAIN_ENGINE_CONFIG_WIN7;
+};
 
 static int is_cr_or_lf(char c)
 {
@@ -94,12 +94,13 @@
   int num_certs = 0;
   size_t END_CERT_LEN;
 
-  ca_file_tstr = Curl_convert_UTF8_to_tchar((char *)ca_file);
+  ca_file_tstr = curlx_convert_UTF8_to_tchar((char *)ca_file);
   if(!ca_file_tstr) {
     char buffer[STRERROR_LEN];
     failf(data,
           "schannel: invalid path name for CA file '%s': %s",
-          ca_file, Curl_strerror(GetLastError(), buffer, sizeof(buffer)));
+          ca_file,
+          Curl_winapi_strerror(GetLastError(), buffer, sizeof(buffer)));
     result = CURLE_SSL_CACERT_BADFILE;
     goto cleanup;
   }
@@ -111,7 +112,7 @@
    */
   ca_file_handle = CreateFile(ca_file_tstr,
                               GENERIC_READ,
-                              0,
+                              FILE_SHARE_READ,
                               NULL,
                               OPEN_EXISTING,
                               FILE_ATTRIBUTE_NORMAL,
@@ -120,7 +121,8 @@
     char buffer[STRERROR_LEN];
     failf(data,
           "schannel: failed to open CA file '%s': %s",
-          ca_file, Curl_strerror(GetLastError(), buffer, sizeof(buffer)));
+          ca_file,
+          Curl_winapi_strerror(GetLastError(), buffer, sizeof(buffer)));
     result = CURLE_SSL_CACERT_BADFILE;
     goto cleanup;
   }
@@ -129,7 +131,8 @@
     char buffer[STRERROR_LEN];
     failf(data,
           "schannel: failed to determine size of CA file '%s': %s",
-          ca_file, Curl_strerror(GetLastError(), buffer, sizeof(buffer)));
+          ca_file,
+          Curl_winapi_strerror(GetLastError(), buffer, sizeof(buffer)));
     result = CURLE_SSL_CACERT_BADFILE;
     goto cleanup;
   }
@@ -159,7 +162,8 @@
       char buffer[STRERROR_LEN];
       failf(data,
             "schannel: failed to read from CA file '%s': %s",
-            ca_file, Curl_strerror(GetLastError(), buffer, sizeof(buffer)));
+            ca_file,
+            Curl_winapi_strerror(GetLastError(), buffer, sizeof(buffer)));
       result = CURLE_SSL_CACERT_BADFILE;
       goto cleanup;
     }
@@ -223,7 +227,7 @@
                 "schannel: failed to extract certificate from CA file "
                 "'%s': %s",
                 ca_file,
-                Curl_strerror(GetLastError(), buffer, sizeof(buffer)));
+                Curl_winapi_strerror(GetLastError(), buffer, sizeof(buffer)));
           result = CURLE_SSL_CACERT_BADFILE;
           more_certs = 0;
         }
@@ -252,7 +256,8 @@
                     "schannel: failed to add certificate from CA file '%s' "
                     "to certificate store: %s",
                     ca_file,
-                    Curl_strerror(GetLastError(), buffer, sizeof(buffer)));
+                    Curl_winapi_strerror(GetLastError(), buffer,
+                                         sizeof(buffer)));
               result = CURLE_SSL_CACERT_BADFILE;
               more_certs = 0;
             }
@@ -283,11 +288,138 @@
     CloseHandle(ca_file_handle);
   }
   Curl_safefree(ca_file_buffer);
-  Curl_unicodefree(ca_file_tstr);
+  curlx_unicodefree(ca_file_tstr);
 
   return result;
 }
 
+/*
+ * Returns the number of characters necessary to populate all the host_names.
+ * If host_names is not NULL, populate it with all the host names. Each string
+ * in the host_names is null-terminated and the last string is double
+ * null-terminated. If no DNS names are found, a single null-terminated empty
+ * string is returned.
+ */
+static DWORD cert_get_name_string(struct Curl_easy *data,
+                                  CERT_CONTEXT *cert_context,
+                                  LPTSTR host_names,
+                                  DWORD length)
+{
+  DWORD actual_length = 0;
+  BOOL compute_content = FALSE;
+  CERT_INFO *cert_info = NULL;
+  CERT_EXTENSION *extension = NULL;
+  CRYPT_DECODE_PARA decode_para = {0, 0, 0};
+  CERT_ALT_NAME_INFO *alt_name_info = NULL;
+  DWORD alt_name_info_size = 0;
+  BOOL ret_val = FALSE;
+  LPTSTR current_pos = NULL;
+  DWORD i;
+
+  /* CERT_NAME_SEARCH_ALL_NAMES_FLAG is available from Windows 8 onwards. */
+  if(Curl_verify_windows_version(6, 2, PLATFORM_WINNT,
+                                 VERSION_GREATER_THAN_EQUAL)) {
+#ifdef CERT_NAME_SEARCH_ALL_NAMES_FLAG
+    /* CertGetNameString will provide the 8-bit character string without
+     * any decoding */
+    DWORD name_flags =
+      CERT_NAME_DISABLE_IE4_UTF8_FLAG | CERT_NAME_SEARCH_ALL_NAMES_FLAG;
+    actual_length = CertGetNameString(cert_context,
+                                      CERT_NAME_DNS_TYPE,
+                                      name_flags,
+                                      NULL,
+                                      host_names,
+                                      length);
+    return actual_length;
+#endif
+  }
+
+  compute_content = host_names != NULL && length != 0;
+
+  /* Initialize default return values. */
+  actual_length = 1;
+  if(compute_content) {
+    *host_names = '\0';
+  }
+
+  if(!cert_context) {
+    failf(data, "schannel: Null certificate context.");
+    return actual_length;
+  }
+
+  cert_info = cert_context->pCertInfo;
+  if(!cert_info) {
+    failf(data, "schannel: Null certificate info.");
+    return actual_length;
+  }
+
+  extension = CertFindExtension(szOID_SUBJECT_ALT_NAME2,
+                                cert_info->cExtension,
+                                cert_info->rgExtension);
+  if(!extension) {
+    failf(data, "schannel: CertFindExtension() returned no extension.");
+    return actual_length;
+  }
+
+  decode_para.cbSize = sizeof(CRYPT_DECODE_PARA);
+
+  ret_val =
+    CryptDecodeObjectEx(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
+                        szOID_SUBJECT_ALT_NAME2,
+                        extension->Value.pbData,
+                        extension->Value.cbData,
+                        CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_NOCOPY_FLAG,
+                        &decode_para,
+                        &alt_name_info,
+                        &alt_name_info_size);
+  if(!ret_val) {
+    failf(data,
+          "schannel: CryptDecodeObjectEx() returned no alternate name "
+          "information.");
+    return actual_length;
+  }
+
+  current_pos = host_names;
+
+  /* Iterate over the alternate names and populate host_names. */
+  for(i = 0; i < alt_name_info->cAltEntry; i++) {
+    const CERT_ALT_NAME_ENTRY *entry = &alt_name_info->rgAltEntry[i];
+    wchar_t *dns_w = NULL;
+    size_t current_length = 0;
+
+    if(entry->dwAltNameChoice != CERT_ALT_NAME_DNS_NAME) {
+      continue;
+    }
+    if(entry->pwszDNSName == NULL) {
+      infof(data, "schannel: Empty DNS name.");
+      continue;
+    }
+    current_length = wcslen(entry->pwszDNSName) + 1;
+    if(!compute_content) {
+      actual_length += (DWORD)current_length;
+      continue;
+    }
+    /* Sanity check to prevent buffer overrun. */
+    if((actual_length + current_length) > length) {
+      failf(data, "schannel: Not enough memory to list all host names.");
+      break;
+    }
+    dns_w = entry->pwszDNSName;
+    /* pwszDNSName is in ia5 string format and hence doesn't contain any
+     * non-ascii characters. */
+    while(*dns_w != '\0') {
+      *current_pos++ = (char)(*dns_w++);
+    }
+    *current_pos++ = '\0';
+    actual_length += (DWORD)current_length;
+  }
+  if(compute_content) {
+    /* Last string has double null-terminator. */
+    *current_pos = '\0';
+  }
+  return actual_length;
+}
+
 static CURLcode verify_host(struct Curl_easy *data,
                             CERT_CONTEXT *pCertContextServer,
                             const char * const conn_hostname)
@@ -298,21 +430,8 @@
   DWORD len = 0;
   DWORD actual_len = 0;
 
-  /* CertGetNameString will provide the 8-bit character string without
-   * any decoding */
-  DWORD name_flags = CERT_NAME_DISABLE_IE4_UTF8_FLAG;
-
-#ifdef CERT_NAME_SEARCH_ALL_NAMES_FLAG
-  name_flags |= CERT_NAME_SEARCH_ALL_NAMES_FLAG;
-#endif
-
   /* Determine the size of the string needed for the cert hostname */
-  len = CertGetNameString(pCertContextServer,
-                          CERT_NAME_DNS_TYPE,
-                          name_flags,
-                          NULL,
-                          NULL,
-                          0);
+  len = cert_get_name_string(data, pCertContextServer, NULL, 0);
   if(len == 0) {
     failf(data,
           "schannel: CertGetNameString() returned no "
@@ -329,12 +448,8 @@
     result = CURLE_OUT_OF_MEMORY;
     goto cleanup;
   }
-  actual_len = CertGetNameString(pCertContextServer,
-                                 CERT_NAME_DNS_TYPE,
-                                 name_flags,
-                                 NULL,
-                                 (LPTSTR) cert_hostname_buff,
-                                 len);
+  actual_len = cert_get_name_string(
+    data, pCertContextServer, (LPTSTR)cert_hostname_buff, len);
 
   /* Sanity check */
   if(actual_len != len) {
@@ -361,7 +476,7 @@
      * is acceptable since both values are assumed to use ASCII
      * (or some equivalent) encoding
      */
-    cert_hostname = Curl_convert_tchar_to_UTF8(
+    cert_hostname = curlx_convert_tchar_to_UTF8(
         &cert_hostname_buff[cert_hostname_buff_index]);
     if(!cert_hostname) {
       result = CURLE_OUT_OF_MEMORY;
@@ -393,7 +508,7 @@
 
         result = CURLE_PEER_FAILED_VERIFICATION;
       }
-      Curl_unicodefree(cert_hostname);
+      curlx_unicodefree(cert_hostname);
     }
   }
 
@@ -407,7 +522,7 @@
     failf(data, "schannel: server certificate name verification failed");
 
 cleanup:
-  Curl_unicodefree(cert_hostname_buff);
+  curlx_unicodefree(cert_hostname_buff);
 
   return result;
 }
@@ -422,9 +537,13 @@
   const CERT_CHAIN_CONTEXT *pChainContext = NULL;
   HCERTCHAINENGINE cert_chain_engine = NULL;
   HCERTSTORE trust_store = NULL;
+#ifndef CURL_DISABLE_PROXY
   const char * const conn_hostname = SSL_IS_PROXY() ?
     conn->http_proxy.host.name :
     conn->host.name;
+#else
+  const char * const conn_hostname = conn->host.name;
+#endif
 
   sspi_status =
     s_pSecFn->QueryContextAttributes(&BACKEND->ctxt->ctxt_handle,
@@ -460,7 +579,7 @@
       if(!trust_store) {
         char buffer[STRERROR_LEN];
         failf(data, "schannel: failed to create certificate store: %s",
-              Curl_strerror(GetLastError(), buffer, sizeof(buffer)));
+              Curl_winapi_strerror(GetLastError(), buffer, sizeof(buffer)));
         result = CURLE_SSL_CACERT_BADFILE;
       }
       else {
@@ -470,7 +589,7 @@
     }
 
     if(result == CURLE_OK) {
-      CERT_CHAIN_ENGINE_CONFIG_WIN7 engine_config;
+      struct cert_chain_engine_config_win7 engine_config;
       BOOL create_engine_result;
 
       memset(&engine_config, 0, sizeof(engine_config));
@@ -489,7 +608,7 @@
         char buffer[STRERROR_LEN];
         failf(data,
               "schannel: failed to create certificate chain engine: %s",
-              Curl_strerror(GetLastError(), buffer, sizeof(buffer)));
+              Curl_winapi_strerror(GetLastError(), buffer, sizeof(buffer)));
         result = CURLE_SSL_CACERT_BADFILE;
       }
     }
@@ -512,7 +631,7 @@
                                 &pChainContext)) {
       char buffer[STRERROR_LEN];
       failf(data, "schannel: CertGetCertificateChain failed: %s",
-            Curl_strerror(GetLastError(), buffer, sizeof(buffer)));
+            Curl_winapi_strerror(GetLastError(), buffer, sizeof(buffer)));
       pChainContext = NULL;
       result = CURLE_PEER_FAILED_VERIFICATION;
     }
@@ -521,6 +640,15 @@
       CERT_SIMPLE_CHAIN *pSimpleChain = pChainContext->rgpChain[0];
       DWORD dwTrustErrorMask = ~(DWORD)(CERT_TRUST_IS_NOT_TIME_NESTED);
       dwTrustErrorMask &= pSimpleChain->TrustStatus.dwErrorStatus;
+
+      if(data->set.ssl.revoke_best_effort) {
+        /* Ignore errors when root certificates are missing the revocation
+         * list URL, or when the list could not be downloaded because the
+         * server is currently unreachable. */
+        dwTrustErrorMask &= ~(DWORD)(CERT_TRUST_REVOCATION_STATUS_UNKNOWN |
+          CERT_TRUST_IS_OFFLINE_REVOCATION);
+      }
+
       if(dwTrustErrorMask) {
         if(dwTrustErrorMask & CERT_TRUST_IS_REVOKED)
           failf(data, "schannel: CertGetCertificateChain trust error"
diff --git a/Utilities/cmcurl/lib/vtls/sectransp.c b/Utilities/cmcurl/lib/vtls/sectransp.c
index 2fdf662..2627aff 100644
--- a/Utilities/cmcurl/lib/vtls/sectransp.c
+++ b/Utilities/cmcurl/lib/vtls/sectransp.c
@@ -6,7 +6,7 @@
  *                             \___|\___/|_| \_\_____|
  *
  * Copyright (C) 2012 - 2017, Nick Zitzmann, <nickzman@gmail.com>.
- * Copyright (C) 2012 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 2012 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -79,7 +79,7 @@
 /* These macros mean "the following code is present to allow runtime backward
    compatibility with at least this cat or earlier":
    (You set this at build-time using the compiler command line option
-   "-mmacos-version-min.") */
+   "-mmacosx-version-min.") */
 #define CURL_SUPPORT_MAC_10_5 MAC_OS_X_VERSION_MIN_REQUIRED <= 1050
 #define CURL_SUPPORT_MAC_10_6 MAC_OS_X_VERSION_MIN_REQUIRED <= 1060
 #define CURL_SUPPORT_MAC_10_7 MAC_OS_X_VERSION_MIN_REQUIRED <= 1070
@@ -138,8 +138,6 @@
   size_t ssl_write_buffered_length;
 };
 
-#define BACKEND connssl->backend
-
 /* pinned public key support tests */
 
 /* version 1 supports macOS 10.12+ and iOS 10+ */
@@ -201,7 +199,8 @@
   UInt8 *currData = (UInt8 *)data;
   /*int sock = *(int *)connection;*/
   struct ssl_connect_data *connssl = (struct ssl_connect_data *)connection;
-  int sock = BACKEND->ssl_sockfd;
+  struct ssl_backend_data *backend = connssl->backend;
+  int sock = backend->ssl_sockfd;
   OSStatus rtn = noErr;
   size_t bytesRead;
   ssize_t rrtn;
@@ -230,7 +229,7 @@
             break;
           case EAGAIN:
             rtn = errSSLWouldBlock;
-            BACKEND->ssl_direction = false;
+            backend->ssl_direction = false;
             break;
           default:
             rtn = ioErr;
@@ -261,7 +260,8 @@
   size_t bytesSent = 0;
   /*int sock = *(int *)connection;*/
   struct ssl_connect_data *connssl = (struct ssl_connect_data *)connection;
-  int sock = BACKEND->ssl_sockfd;
+  struct ssl_backend_data *backend = connssl->backend;
+  int sock = backend->ssl_sockfd;
   ssize_t length;
   size_t dataLen = *dataLength;
   const UInt8 *dataPtr = (UInt8 *)data;
@@ -281,7 +281,7 @@
     theErr = errno;
     if(theErr == EAGAIN) {
       ortn = errSSLWouldBlock;
-      BACKEND->ssl_direction = true;
+      backend->ssl_direction = true;
     }
     else {
       ortn = ioErr;
@@ -1126,12 +1126,12 @@
 }
 
 static OSStatus CopyIdentityFromPKCS12File(const char *cPath,
+                                           const struct curl_blob *blob,
                                            const char *cPassword,
                                            SecIdentityRef *out_cert_and_key)
 {
   OSStatus status = errSecItemNotFound;
-  CFURLRef pkcs_url = CFURLCreateFromFileSystemRepresentation(NULL,
-    (const UInt8 *)cPath, strlen(cPath), false);
+  CFURLRef pkcs_url = NULL;
   CFStringRef password = cPassword ? CFStringCreateWithCString(NULL,
     cPassword, kCFStringEncodingUTF8) : NULL;
   CFDataRef pkcs_data = NULL;
@@ -1140,8 +1140,26 @@
   /* These constants are documented as having first appeared in 10.6 but they
      raise linker errors when used on that cat for some reason. */
 #if CURL_BUILD_MAC_10_7 || CURL_BUILD_IOS
-  if(CFURLCreateDataAndPropertiesFromResource(NULL, pkcs_url, &pkcs_data,
-   NULL, NULL, &status)) {
+  bool resource_imported;
+
+  if(blob) {
+    pkcs_data = CFDataCreate(kCFAllocatorDefault,
+                             (const unsigned char *)blob->data, blob->len);
+    status = (pkcs_data != NULL) ? errSecSuccess : errSecAllocate;
+    resource_imported = (pkcs_data != NULL);
+  }
+  else {
+    pkcs_url =
+      CFURLCreateFromFileSystemRepresentation(NULL,
+                                              (const UInt8 *)cPath,
+                                              strlen(cPath), false);
+    resource_imported =
+      CFURLCreateDataAndPropertiesFromResource(NULL,
+                                               pkcs_url, &pkcs_data,
+                                               NULL, NULL, &status);
+  }
+
+  if(resource_imported) {
     CFArrayRef items = NULL;
 
   /* On iOS SecPKCS12Import will never add the client certificate to the
@@ -1164,7 +1182,7 @@
    * the Keychain.
    *
    * As this doesn't match iOS, and apps may not want to see their client
-   * certificate saved in the the user's keychain, we use SecItemImport
+   * certificate saved in the user's keychain, we use SecItemImport
    * with a NULL keychain to avoid importing it.
    *
    * This returns a SecCertificateRef from which we can construct a
@@ -1219,7 +1237,8 @@
 #endif /* CURL_BUILD_MAC_10_7 || CURL_BUILD_IOS */
   if(password)
     CFRelease(password);
-  CFRelease(pkcs_url);
+  if(pkcs_url)
+    CFRelease(pkcs_url);
   return status;
 }
 
@@ -1276,6 +1295,7 @@
 {
   struct Curl_easy *data = conn->data;
   struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+  struct ssl_backend_data *backend = connssl->backend;
   long ssl_version = SSL_CONN_CONFIG(version);
   long ssl_version_max = SSL_CONN_CONFIG(version_max);
   long max_supported_version_by_os;
@@ -1326,30 +1346,30 @@
       return result;
     }
 
-    (void)SSLSetProtocolVersionMin(BACKEND->ssl_ctx, darwin_ver_min);
-    (void)SSLSetProtocolVersionMax(BACKEND->ssl_ctx, darwin_ver_max);
+    (void)SSLSetProtocolVersionMin(backend->ssl_ctx, darwin_ver_min);
+    (void)SSLSetProtocolVersionMax(backend->ssl_ctx, darwin_ver_max);
     return result;
   }
   else {
 #if CURL_SUPPORT_MAC_10_8
     long i = ssl_version;
-    (void)SSLSetProtocolVersionEnabled(BACKEND->ssl_ctx,
+    (void)SSLSetProtocolVersionEnabled(backend->ssl_ctx,
                                        kSSLProtocolAll,
                                        false);
     for(; i <= (ssl_version_max >> 16); i++) {
       switch(i) {
         case CURL_SSLVERSION_TLSv1_0:
-          (void)SSLSetProtocolVersionEnabled(BACKEND->ssl_ctx,
+          (void)SSLSetProtocolVersionEnabled(backend->ssl_ctx,
                                             kTLSProtocol1,
                                             true);
           break;
         case CURL_SSLVERSION_TLSv1_1:
-          (void)SSLSetProtocolVersionEnabled(BACKEND->ssl_ctx,
+          (void)SSLSetProtocolVersionEnabled(backend->ssl_ctx,
                                             kTLSProtocol11,
                                             true);
           break;
         case CURL_SSLVERSION_TLSv1_2:
-          (void)SSLSetProtocolVersionEnabled(BACKEND->ssl_ctx,
+          (void)SSLSetProtocolVersionEnabled(backend->ssl_ctx,
                                             kTLSProtocol12,
                                             true);
           break;
@@ -1373,9 +1393,12 @@
   struct Curl_easy *data = conn->data;
   curl_socket_t sockfd = conn->sock[sockindex];
   struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+  struct ssl_backend_data *backend = connssl->backend;
   const char * const ssl_cafile = SSL_CONN_CONFIG(CAfile);
+  const struct curl_blob *ssl_cablob = NULL;
   const bool verifypeer = SSL_CONN_CONFIG(verifypeer);
   char * const ssl_cert = SSL_SET_OPTION(cert);
+  const struct curl_blob *ssl_cert_blob = SSL_SET_OPTION(cert_blob);
   const char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name :
     conn->host.name;
   const long int port = SSL_IS_PROXY() ? conn->port : conn->remote_port;
@@ -1395,10 +1418,10 @@
 
 #if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS
   if(SSLCreateContext != NULL) {  /* use the newer API if available */
-    if(BACKEND->ssl_ctx)
-      CFRelease(BACKEND->ssl_ctx);
-    BACKEND->ssl_ctx = SSLCreateContext(NULL, kSSLClientSide, kSSLStreamType);
-    if(!BACKEND->ssl_ctx) {
+    if(backend->ssl_ctx)
+      CFRelease(backend->ssl_ctx);
+    backend->ssl_ctx = SSLCreateContext(NULL, kSSLClientSide, kSSLStreamType);
+    if(!backend->ssl_ctx) {
       failf(data, "SSL: couldn't create a context!");
       return CURLE_OUT_OF_MEMORY;
     }
@@ -1406,9 +1429,9 @@
   else {
   /* The old ST API does not exist under iOS, so don't compile it: */
 #if CURL_SUPPORT_MAC_10_8
-    if(BACKEND->ssl_ctx)
-      (void)SSLDisposeContext(BACKEND->ssl_ctx);
-    err = SSLNewContext(false, &(BACKEND->ssl_ctx));
+    if(backend->ssl_ctx)
+      (void)SSLDisposeContext(backend->ssl_ctx);
+    err = SSLNewContext(false, &(backend->ssl_ctx));
     if(err != noErr) {
       failf(data, "SSL: couldn't create a context: OSStatus %d", err);
       return CURLE_OUT_OF_MEMORY;
@@ -1416,31 +1439,31 @@
 #endif /* CURL_SUPPORT_MAC_10_8 */
   }
 #else
-  if(BACKEND->ssl_ctx)
-    (void)SSLDisposeContext(BACKEND->ssl_ctx);
-  err = SSLNewContext(false, &(BACKEND->ssl_ctx));
+  if(backend->ssl_ctx)
+    (void)SSLDisposeContext(backend->ssl_ctx);
+  err = SSLNewContext(false, &(backend->ssl_ctx));
   if(err != noErr) {
     failf(data, "SSL: couldn't create a context: OSStatus %d", err);
     return CURLE_OUT_OF_MEMORY;
   }
 #endif /* CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS */
-  BACKEND->ssl_write_buffered_length = 0UL; /* reset buffered write length */
+  backend->ssl_write_buffered_length = 0UL; /* reset buffered write length */
 
   /* check to see if we've been told to use an explicit SSL/TLS version */
 #if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS
   if(SSLSetProtocolVersionMax != NULL) {
     switch(conn->ssl_config.version) {
     case CURL_SSLVERSION_TLSv1:
-      (void)SSLSetProtocolVersionMin(BACKEND->ssl_ctx, kTLSProtocol1);
+      (void)SSLSetProtocolVersionMin(backend->ssl_ctx, kTLSProtocol1);
 #if (CURL_BUILD_MAC_10_13 || CURL_BUILD_IOS_11) && HAVE_BUILTIN_AVAILABLE == 1
       if(__builtin_available(macOS 10.13, iOS 11.0, *)) {
-        (void)SSLSetProtocolVersionMax(BACKEND->ssl_ctx, kTLSProtocol13);
+        (void)SSLSetProtocolVersionMax(backend->ssl_ctx, kTLSProtocol13);
       }
       else {
-        (void)SSLSetProtocolVersionMax(BACKEND->ssl_ctx, kTLSProtocol12);
+        (void)SSLSetProtocolVersionMax(backend->ssl_ctx, kTLSProtocol12);
       }
 #else
-      (void)SSLSetProtocolVersionMax(BACKEND->ssl_ctx, kTLSProtocol12);
+      (void)SSLSetProtocolVersionMax(backend->ssl_ctx, kTLSProtocol12);
 #endif /* (CURL_BUILD_MAC_10_13 || CURL_BUILD_IOS_11) &&
           HAVE_BUILTIN_AVAILABLE == 1 */
       break;
@@ -1456,20 +1479,20 @@
         break;
       }
     case CURL_SSLVERSION_SSLv3:
-      err = SSLSetProtocolVersionMin(BACKEND->ssl_ctx, kSSLProtocol3);
+      err = SSLSetProtocolVersionMin(backend->ssl_ctx, kSSLProtocol3);
       if(err != noErr) {
         failf(data, "Your version of the OS does not support SSLv3");
         return CURLE_SSL_CONNECT_ERROR;
       }
-      (void)SSLSetProtocolVersionMax(BACKEND->ssl_ctx, kSSLProtocol3);
+      (void)SSLSetProtocolVersionMax(backend->ssl_ctx, kSSLProtocol3);
       break;
     case CURL_SSLVERSION_SSLv2:
-      err = SSLSetProtocolVersionMin(BACKEND->ssl_ctx, kSSLProtocol2);
+      err = SSLSetProtocolVersionMin(backend->ssl_ctx, kSSLProtocol2);
       if(err != noErr) {
         failf(data, "Your version of the OS does not support SSLv2");
         return CURLE_SSL_CONNECT_ERROR;
       }
-      (void)SSLSetProtocolVersionMax(BACKEND->ssl_ctx, kSSLProtocol2);
+      (void)SSLSetProtocolVersionMax(backend->ssl_ctx, kSSLProtocol2);
       break;
     default:
       failf(data, "Unrecognized parameter passed via CURLOPT_SSLVERSION");
@@ -1478,19 +1501,19 @@
   }
   else {
 #if CURL_SUPPORT_MAC_10_8
-    (void)SSLSetProtocolVersionEnabled(BACKEND->ssl_ctx,
+    (void)SSLSetProtocolVersionEnabled(backend->ssl_ctx,
                                        kSSLProtocolAll,
                                        false);
     switch(conn->ssl_config.version) {
     case CURL_SSLVERSION_DEFAULT:
     case CURL_SSLVERSION_TLSv1:
-      (void)SSLSetProtocolVersionEnabled(BACKEND->ssl_ctx,
+      (void)SSLSetProtocolVersionEnabled(backend->ssl_ctx,
                                          kTLSProtocol1,
                                          true);
-      (void)SSLSetProtocolVersionEnabled(BACKEND->ssl_ctx,
+      (void)SSLSetProtocolVersionEnabled(backend->ssl_ctx,
                                          kTLSProtocol11,
                                          true);
-      (void)SSLSetProtocolVersionEnabled(BACKEND->ssl_ctx,
+      (void)SSLSetProtocolVersionEnabled(backend->ssl_ctx,
                                          kTLSProtocol12,
                                          true);
       break;
@@ -1505,7 +1528,7 @@
         break;
       }
     case CURL_SSLVERSION_SSLv3:
-      err = SSLSetProtocolVersionEnabled(BACKEND->ssl_ctx,
+      err = SSLSetProtocolVersionEnabled(backend->ssl_ctx,
                                          kSSLProtocol3,
                                          true);
       if(err != noErr) {
@@ -1514,7 +1537,7 @@
       }
       break;
     case CURL_SSLVERSION_SSLv2:
-      err = SSLSetProtocolVersionEnabled(BACKEND->ssl_ctx,
+      err = SSLSetProtocolVersionEnabled(backend->ssl_ctx,
                                          kSSLProtocol2,
                                          true);
       if(err != noErr) {
@@ -1534,12 +1557,12 @@
                 " SSL/TLS version");
     return CURLE_SSL_CONNECT_ERROR;
   }
-  (void)SSLSetProtocolVersionEnabled(BACKEND->ssl_ctx, kSSLProtocolAll, false);
+  (void)SSLSetProtocolVersionEnabled(backend->ssl_ctx, kSSLProtocolAll, false);
   switch(conn->ssl_config.version) {
   case CURL_SSLVERSION_DEFAULT:
   case CURL_SSLVERSION_TLSv1:
   case CURL_SSLVERSION_TLSv1_0:
-    (void)SSLSetProtocolVersionEnabled(BACKEND->ssl_ctx,
+    (void)SSLSetProtocolVersionEnabled(backend->ssl_ctx,
                                        kTLSProtocol1,
                                        true);
     break;
@@ -1553,7 +1576,7 @@
     failf(data, "Your version of the OS does not support TLSv1.3");
     return CURLE_SSL_CONNECT_ERROR;
   case CURL_SSLVERSION_SSLv2:
-    err = SSLSetProtocolVersionEnabled(BACKEND->ssl_ctx,
+    err = SSLSetProtocolVersionEnabled(backend->ssl_ctx,
                                        kSSLProtocol2,
                                        true);
     if(err != noErr) {
@@ -1562,7 +1585,7 @@
     }
     break;
   case CURL_SSLVERSION_SSLv3:
-    err = SSLSetProtocolVersionEnabled(BACKEND->ssl_ctx,
+    err = SSLSetProtocolVersionEnabled(backend->ssl_ctx,
                                        kSSLProtocol3,
                                        true);
     if(err != noErr) {
@@ -1596,7 +1619,7 @@
       /* expects length prefixed preference ordered list of protocols in wire
        * format
        */
-      err = SSLSetALPNProtocols(BACKEND->ssl_ctx, alpnArr);
+      err = SSLSetALPNProtocols(backend->ssl_ctx, alpnArr);
       if(err != noErr)
         infof(data, "WARNING: failed to set ALPN protocols; OSStatus %d\n",
               err);
@@ -1610,15 +1633,16 @@
           "Transport. The private key must be in the Keychain.\n");
   }
 
-  if(ssl_cert) {
+  if(ssl_cert || ssl_cert_blob) {
+    bool is_cert_data = ssl_cert_blob != NULL;
+    bool is_cert_file = (!is_cert_data) && is_file(ssl_cert);
     SecIdentityRef cert_and_key = NULL;
-    bool is_cert_file = is_file(ssl_cert);
 
     /* User wants to authenticate with a client cert. Look for it:
        If we detect that this is a file on disk, then let's load it.
        Otherwise, assume that the user wants to use an identity loaded
        from the Keychain. */
-    if(is_cert_file) {
+    if(is_cert_file || is_cert_data) {
       if(!SSL_SET_OPTION(cert_type))
         infof(data, "WARNING: SSL: Certificate type not set, assuming "
                     "PKCS#12 format.\n");
@@ -1627,7 +1651,7 @@
         infof(data, "WARNING: SSL: The Security framework only supports "
                     "loading identities that are in PKCS#12 format.\n");
 
-      err = CopyIdentityFromPKCS12File(ssl_cert,
+      err = CopyIdentityFromPKCS12File(ssl_cert, ssl_cert_blob,
         SSL_SET_OPTION(key_passwd), &cert_and_key);
     }
     else
@@ -1657,7 +1681,7 @@
       certs_c[0] = cert_and_key;
       certs = CFArrayCreate(NULL, (const void **)certs_c, 1L,
                             &kCFTypeArrayCallBacks);
-      err = SSLSetCertificate(BACKEND->ssl_ctx, certs);
+      err = SSLSetCertificate(backend->ssl_ctx, certs);
       if(certs)
         CFRelease(certs);
       if(err != noErr) {
@@ -1667,27 +1691,30 @@
       CFRelease(cert_and_key);
     }
     else {
+      const char *cert_showfilename_error =
+        is_cert_data ? "(memory blob)" : ssl_cert;
+
       switch(err) {
       case errSecAuthFailed: case -25264: /* errSecPkcs12VerifyFailure */
         failf(data, "SSL: Incorrect password for the certificate \"%s\" "
-                    "and its private key.", ssl_cert);
+                    "and its private key.", cert_showfilename_error);
         break;
       case -26275: /* errSecDecode */ case -25257: /* errSecUnknownFormat */
         failf(data, "SSL: Couldn't make sense of the data in the "
                     "certificate \"%s\" and its private key.",
-                    ssl_cert);
+                    cert_showfilename_error);
         break;
       case -25260: /* errSecPassphraseRequired */
         failf(data, "SSL The certificate \"%s\" requires a password.",
-                    ssl_cert);
+                    cert_showfilename_error);
         break;
       case errSecItemNotFound:
         failf(data, "SSL: Can't find the certificate \"%s\" and its private "
-                    "key in the Keychain.", ssl_cert);
+                    "key in the Keychain.", cert_showfilename_error);
         break;
       default:
         failf(data, "SSL: Can't load the certificate \"%s\" and its private "
-                    "key: OSStatus %d", ssl_cert, err);
+                    "key: OSStatus %d", cert_showfilename_error, err);
         break;
       }
       return CURLE_SSL_CERTPROBLEM;
@@ -1719,8 +1746,9 @@
 #else
   if(SSLSetSessionOption != NULL) {
 #endif /* CURL_BUILD_MAC */
-    bool break_on_auth = !conn->ssl_config.verifypeer || ssl_cafile;
-    err = SSLSetSessionOption(BACKEND->ssl_ctx,
+    bool break_on_auth = !conn->ssl_config.verifypeer ||
+      ssl_cafile || ssl_cablob;
+    err = SSLSetSessionOption(backend->ssl_ctx,
                               kSSLSessionOptionBreakOnServerAuth,
                               break_on_auth);
     if(err != noErr) {
@@ -1730,7 +1758,7 @@
   }
   else {
 #if CURL_SUPPORT_MAC_10_8
-    err = SSLSetEnableCertVerify(BACKEND->ssl_ctx,
+    err = SSLSetEnableCertVerify(backend->ssl_ctx,
                                  conn->ssl_config.verifypeer?true:false);
     if(err != noErr) {
       failf(data, "SSL: SSLSetEnableCertVerify() failed: OSStatus %d", err);
@@ -1739,7 +1767,7 @@
 #endif /* CURL_SUPPORT_MAC_10_8 */
   }
 #else
-  err = SSLSetEnableCertVerify(BACKEND->ssl_ctx,
+  err = SSLSetEnableCertVerify(backend->ssl_ctx,
                                conn->ssl_config.verifypeer?true:false);
   if(err != noErr) {
     failf(data, "SSL: SSLSetEnableCertVerify() failed: OSStatus %d", err);
@@ -1747,10 +1775,11 @@
   }
 #endif /* CURL_BUILD_MAC_10_6 || CURL_BUILD_IOS */
 
-  if(ssl_cafile && verifypeer) {
-    bool is_cert_file = is_file(ssl_cafile);
+  if((ssl_cafile || ssl_cablob) && verifypeer) {
+    bool is_cert_data = ssl_cablob != NULL;
+    bool is_cert_file = (!is_cert_data) && is_file(ssl_cafile);
 
-    if(!is_cert_file) {
+    if(!(is_cert_file || is_cert_data)) {
       failf(data, "SSL: can't load CA certificate file %s", ssl_cafile);
       return CURLE_SSL_CACERT_BADFILE;
     }
@@ -1760,7 +1789,7 @@
    * Both hostname check and SNI require SSLSetPeerDomainName().
    * Also: the verifyhost setting influences SNI usage */
   if(conn->ssl_config.verifyhost) {
-    err = SSLSetPeerDomainName(BACKEND->ssl_ctx, hostname,
+    err = SSLSetPeerDomainName(backend->ssl_ctx, hostname,
     strlen(hostname));
 
     if(err != noErr) {
@@ -1786,7 +1815,7 @@
      higher priority, but it's probably better that we not connect at all than
      to give the user a false sense of security if the server only supports
      insecure ciphers. (Note: We don't care about SSLv2-only ciphers.) */
-  err = SSLGetNumberSupportedCiphers(BACKEND->ssl_ctx, &all_ciphers_count);
+  err = SSLGetNumberSupportedCiphers(backend->ssl_ctx, &all_ciphers_count);
   if(err != noErr) {
     failf(data, "SSL: SSLGetNumberSupportedCiphers() failed: OSStatus %d",
           err);
@@ -1803,7 +1832,7 @@
     failf(data, "SSL: Failed to allocate memory for allowed ciphers");
     return CURLE_OUT_OF_MEMORY;
   }
-  err = SSLGetSupportedCiphers(BACKEND->ssl_ctx, all_ciphers,
+  err = SSLGetSupportedCiphers(backend->ssl_ctx, all_ciphers,
                                &all_ciphers_count);
   if(err != noErr) {
     Curl_safefree(all_ciphers);
@@ -1890,7 +1919,7 @@
         break;
     }
   }
-  err = SSLSetEnabledCiphers(BACKEND->ssl_ctx, allowed_ciphers,
+  err = SSLSetEnabledCiphers(backend->ssl_ctx, allowed_ciphers,
                              allowed_ciphers_count);
   Curl_safefree(all_ciphers);
   Curl_safefree(allowed_ciphers);
@@ -1903,9 +1932,9 @@
   /* We want to enable 1/n-1 when using a CBC cipher unless the user
      specifically doesn't want us doing that: */
   if(SSLSetSessionOption != NULL) {
-    SSLSetSessionOption(BACKEND->ssl_ctx, kSSLSessionOptionSendOneByteRecord,
+    SSLSetSessionOption(backend->ssl_ctx, kSSLSessionOptionSendOneByteRecord,
                       !data->set.ssl.enable_beast);
-    SSLSetSessionOption(BACKEND->ssl_ctx, kSSLSessionOptionFalseStart,
+    SSLSetSessionOption(backend->ssl_ctx, kSSLSessionOptionFalseStart,
                       data->set.ssl.falsestart); /* false start support */
   }
 #endif /* CURL_BUILD_MAC_10_9 || CURL_BUILD_IOS_7 */
@@ -1919,7 +1948,7 @@
     if(!Curl_ssl_getsessionid(conn, (void **)&ssl_sessionid,
                               &ssl_sessionid_len, sockindex)) {
       /* we got a session id, use it! */
-      err = SSLSetPeerID(BACKEND->ssl_ctx, ssl_sessionid, ssl_sessionid_len);
+      err = SSLSetPeerID(backend->ssl_ctx, ssl_sessionid, ssl_sessionid_len);
       Curl_ssl_sessionid_unlock(conn);
       if(err != noErr) {
         failf(data, "SSL: SSLSetPeerID() failed: OSStatus %d", err);
@@ -1937,7 +1966,7 @@
                 verifypeer, SSL_CONN_CONFIG(verifyhost), hostname, port);
       ssl_sessionid_len = strlen(ssl_sessionid);
 
-      err = SSLSetPeerID(BACKEND->ssl_ctx, ssl_sessionid, ssl_sessionid_len);
+      err = SSLSetPeerID(backend->ssl_ctx, ssl_sessionid, ssl_sessionid_len);
       if(err != noErr) {
         Curl_ssl_sessionid_unlock(conn);
         failf(data, "SSL: SSLSetPeerID() failed: OSStatus %d", err);
@@ -1954,7 +1983,7 @@
     }
   }
 
-  err = SSLSetIOFuncs(BACKEND->ssl_ctx, SocketRead, SocketWrite);
+  err = SSLSetIOFuncs(backend->ssl_ctx, SocketRead, SocketWrite);
   if(err != noErr) {
     failf(data, "SSL: SSLSetIOFuncs() failed: OSStatus %d", err);
     return CURLE_SSL_CONNECT_ERROR;
@@ -1964,8 +1993,8 @@
   /* We need to store the FD in a constant memory address, because
    * SSLSetConnection() will not copy that address. I've found that
    * conn->sock[sockindex] may change on its own. */
-  BACKEND->ssl_sockfd = sockfd;
-  err = SSLSetConnection(BACKEND->ssl_ctx, connssl);
+  backend->ssl_sockfd = sockfd;
+  err = SSLSetConnection(backend->ssl_ctx, connssl);
   if(err != noErr) {
     failf(data, "SSL: SSLSetConnection() failed: %d", err);
     return CURLE_SSL_CONNECT_ERROR;
@@ -2111,8 +2140,8 @@
     return CURLE_OK;
 }
 
-static int verify_cert(const char *cafile, struct Curl_easy *data,
-                       SSLContextRef ctx)
+static CURLcode verify_cert(const char *cafile, struct Curl_easy *data,
+                            SSLContextRef ctx)
 {
   int n = 0, rc;
   long res;
@@ -2346,6 +2375,7 @@
 {
   struct Curl_easy *data = conn->data;
   struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+  struct ssl_backend_data *backend = connssl->backend;
   OSStatus err;
   SSLCipherSuite cipher;
   SSLProtocol protocol = 0;
@@ -2357,12 +2387,12 @@
               || ssl_connect_2_writing == connssl->connecting_state);
 
   /* Here goes nothing: */
-  err = SSLHandshake(BACKEND->ssl_ctx);
+  err = SSLHandshake(backend->ssl_ctx);
 
   if(err != noErr) {
     switch(err) {
       case errSSLWouldBlock:  /* they're not done with us yet */
-        connssl->connecting_state = BACKEND->ssl_direction ?
+        connssl->connecting_state = backend->ssl_direction ?
             ssl_connect_2_writing : ssl_connect_2_reading;
         return CURLE_OK;
 
@@ -2370,10 +2400,10 @@
         Leopard's headers */
       case -9841:
         if(SSL_CONN_CONFIG(CAfile) && SSL_CONN_CONFIG(verifypeer)) {
-          int res = verify_cert(SSL_CONN_CONFIG(CAfile), data,
-                                BACKEND->ssl_ctx);
-          if(res != CURLE_OK)
-            return res;
+          CURLcode result = verify_cert(SSL_CONN_CONFIG(CAfile), data,
+                                        backend->ssl_ctx);
+          if(result)
+            return result;
         }
         /* the documentation says we need to call SSLHandshake() again */
         return sectransp_connect_step2(conn, sockindex);
@@ -2580,7 +2610,7 @@
 
 #ifdef SECTRANSP_PINNEDPUBKEY
     if(data->set.str[STRING_SSL_PINNEDPUBLICKEY_ORIG]) {
-      CURLcode result = pkp_pin_peer_pubkey(data, BACKEND->ssl_ctx,
+      CURLcode result = pkp_pin_peer_pubkey(data, backend->ssl_ctx,
                             data->set.str[STRING_SSL_PINNEDPUBLICKEY_ORIG]);
       if(result) {
         failf(data, "SSL: public key does not match pinned public key!");
@@ -2590,8 +2620,8 @@
 #endif /* SECTRANSP_PINNEDPUBKEY */
 
     /* Informational message */
-    (void)SSLGetNegotiatedCipher(BACKEND->ssl_ctx, &cipher);
-    (void)SSLGetNegotiatedProtocolVersion(BACKEND->ssl_ctx, &protocol);
+    (void)SSLGetNegotiatedCipher(backend->ssl_ctx, &cipher);
+    (void)SSLGetNegotiatedProtocolVersion(backend->ssl_ctx, &protocol);
     switch(protocol) {
       case kSSLProtocol2:
         infof(data, "SSL 2.0 connection using %s\n",
@@ -2631,7 +2661,7 @@
       if(__builtin_available(macOS 10.13.4, iOS 11, tvOS 11, *)) {
         CFArrayRef alpnArr = NULL;
         CFStringRef chosenProtocol = NULL;
-        err = SSLCopyALPNProtocols(BACKEND->ssl_ctx, &alpnArr);
+        err = SSLCopyALPNProtocols(backend->ssl_ctx, &alpnArr);
 
         if(err == noErr && alpnArr && CFArrayGetCount(alpnArr) >= 1)
           chosenProtocol = CFArrayGetValueAtIndex(alpnArr, 0);
@@ -2674,19 +2704,20 @@
 {
   struct Curl_easy *data = conn->data;
   struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+  struct ssl_backend_data *backend = connssl->backend;
   CFArrayRef server_certs = NULL;
   SecCertificateRef server_cert;
   OSStatus err;
   CFIndex i, count;
   SecTrustRef trust = NULL;
 
-  if(!BACKEND->ssl_ctx)
+  if(!backend->ssl_ctx)
     return;
 
 #if CURL_BUILD_MAC_10_7 || CURL_BUILD_IOS
 #if CURL_BUILD_IOS
 #pragma unused(server_certs)
-  err = SSLCopyPeerTrust(BACKEND->ssl_ctx, &trust);
+  err = SSLCopyPeerTrust(backend->ssl_ctx, &trust);
   /* For some reason, SSLCopyPeerTrust() can return noErr and yet return
      a null trust, so be on guard for that: */
   if(err == noErr && trust) {
@@ -2712,7 +2743,7 @@
      Lion or later. */
   if(SecTrustEvaluateAsync != NULL) {
 #pragma unused(server_certs)
-    err = SSLCopyPeerTrust(BACKEND->ssl_ctx, &trust);
+    err = SSLCopyPeerTrust(backend->ssl_ctx, &trust);
     /* For some reason, SSLCopyPeerTrust() can return noErr and yet return
        a null trust, so be on guard for that: */
     if(err == noErr && trust) {
@@ -2732,7 +2763,7 @@
   }
   else {
 #if CURL_SUPPORT_MAC_10_8
-    err = SSLCopyPeerCertificates(BACKEND->ssl_ctx, &server_certs);
+    err = SSLCopyPeerCertificates(backend->ssl_ctx, &server_certs);
     /* Just in case SSLCopyPeerCertificates() returns null too... */
     if(err == noErr && server_certs) {
       count = CFArrayGetCount(server_certs);
@@ -2754,7 +2785,7 @@
 #endif /* CURL_BUILD_IOS */
 #else
 #pragma unused(trust)
-  err = SSLCopyPeerCertificates(BACKEND->ssl_ctx, &server_certs);
+  err = SSLCopyPeerCertificates(backend->ssl_ctx, &server_certs);
   if(err == noErr) {
     count = CFArrayGetCount(server_certs);
     for(i = 0L ; i < count ; i++) {
@@ -2805,7 +2836,6 @@
   struct Curl_easy *data = conn->data;
   struct ssl_connect_data *connssl = &conn->ssl[sockindex];
   curl_socket_t sockfd = conn->sock[sockindex];
-  long timeout_ms;
   int what;
 
   /* check if the connection has already been established */
@@ -2816,7 +2846,7 @@
 
   if(ssl_connect_1 == connssl->connecting_state) {
     /* Find out how much more time we're allowed */
-    timeout_ms = Curl_timeleft(data, NULL, TRUE);
+    const timediff_t timeout_ms = Curl_timeleft(data, NULL, TRUE);
 
     if(timeout_ms < 0) {
       /* no need to continue if time already is up */
@@ -2834,7 +2864,7 @@
         ssl_connect_2_writing == connssl->connecting_state) {
 
     /* check allowed time left */
-    timeout_ms = Curl_timeleft(data, NULL, TRUE);
+    const timediff_t timeout_ms = Curl_timeleft(data, NULL, TRUE);
 
     if(timeout_ms < 0) {
       /* no need to continue if time already is up */
@@ -2852,7 +2882,7 @@
       connssl->connecting_state?sockfd:CURL_SOCKET_BAD;
 
       what = Curl_socket_check(readfd, CURL_SOCKET_BAD, writefd,
-                               nonblocking?0:timeout_ms);
+                               nonblocking ? 0 : timeout_ms);
       if(what < 0) {
         /* fatal error */
         failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO);
@@ -2933,34 +2963,36 @@
 static void Curl_sectransp_close(struct connectdata *conn, int sockindex)
 {
   struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+  struct ssl_backend_data *backend = connssl->backend;
 
-  if(BACKEND->ssl_ctx) {
-    (void)SSLClose(BACKEND->ssl_ctx);
+  if(backend->ssl_ctx) {
+    (void)SSLClose(backend->ssl_ctx);
 #if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS
     if(SSLCreateContext != NULL)
-      CFRelease(BACKEND->ssl_ctx);
+      CFRelease(backend->ssl_ctx);
 #if CURL_SUPPORT_MAC_10_8
     else
-      (void)SSLDisposeContext(BACKEND->ssl_ctx);
+      (void)SSLDisposeContext(backend->ssl_ctx);
 #endif  /* CURL_SUPPORT_MAC_10_8 */
 #else
-    (void)SSLDisposeContext(BACKEND->ssl_ctx);
+    (void)SSLDisposeContext(backend->ssl_ctx);
 #endif /* CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS */
-    BACKEND->ssl_ctx = NULL;
+    backend->ssl_ctx = NULL;
   }
-  BACKEND->ssl_sockfd = 0;
+  backend->ssl_sockfd = 0;
 }
 
 static int Curl_sectransp_shutdown(struct connectdata *conn, int sockindex)
 {
   struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+  struct ssl_backend_data *backend = connssl->backend;
   struct Curl_easy *data = conn->data;
   ssize_t nread;
   int what;
   int rc;
   char buf[120];
 
-  if(!BACKEND->ssl_ctx)
+  if(!backend->ssl_ctx)
     return 0;
 
 #ifndef CURL_DISABLE_FTP
@@ -3033,11 +3065,12 @@
 static int Curl_sectransp_check_cxn(struct connectdata *conn)
 {
   struct ssl_connect_data *connssl = &conn->ssl[FIRSTSOCKET];
+  struct ssl_backend_data *backend = connssl->backend;
   OSStatus err;
   SSLSessionState state;
 
-  if(BACKEND->ssl_ctx) {
-    err = SSLGetSessionState(BACKEND->ssl_ctx, &state);
+  if(backend->ssl_ctx) {
+    err = SSLGetSessionState(backend->ssl_ctx, &state);
     if(err == noErr)
       return state == kSSLConnected || state == kSSLHandshake;
     return -1;
@@ -3049,11 +3082,12 @@
                                         int connindex)
 {
   const struct ssl_connect_data *connssl = &conn->ssl[connindex];
+  struct ssl_backend_data *backend = connssl->backend;
   OSStatus err;
   size_t buffer;
 
-  if(BACKEND->ssl_ctx) {  /* SSL is in use */
-    err = SSLGetBufferedReadSize(BACKEND->ssl_ctx, &buffer);
+  if(backend->ssl_ctx) {  /* SSL is in use */
+    err = SSLGetBufferedReadSize(backend->ssl_ctx, &buffer);
     if(err == noErr)
       return buffer > 0UL;
     return false;
@@ -3119,6 +3153,7 @@
 {
   /*struct Curl_easy *data = conn->data;*/
   struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+  struct ssl_backend_data *backend = connssl->backend;
   size_t processed = 0UL;
   OSStatus err;
 
@@ -3137,15 +3172,15 @@
      over again with no new data until it quits returning errSSLWouldBlock. */
 
   /* Do we have buffered data to write from the last time we were called? */
-  if(BACKEND->ssl_write_buffered_length) {
+  if(backend->ssl_write_buffered_length) {
     /* Write the buffered data: */
-    err = SSLWrite(BACKEND->ssl_ctx, NULL, 0UL, &processed);
+    err = SSLWrite(backend->ssl_ctx, NULL, 0UL, &processed);
     switch(err) {
       case noErr:
         /* processed is always going to be 0 because we didn't write to
            the buffer, so return how much was written to the socket */
-        processed = BACKEND->ssl_write_buffered_length;
-        BACKEND->ssl_write_buffered_length = 0UL;
+        processed = backend->ssl_write_buffered_length;
+        backend->ssl_write_buffered_length = 0UL;
         break;
       case errSSLWouldBlock: /* argh, try again */
         *curlcode = CURLE_AGAIN;
@@ -3158,13 +3193,13 @@
   }
   else {
     /* We've got new data to write: */
-    err = SSLWrite(BACKEND->ssl_ctx, mem, len, &processed);
+    err = SSLWrite(backend->ssl_ctx, mem, len, &processed);
     if(err != noErr) {
       switch(err) {
         case errSSLWouldBlock:
           /* Data was buffered but not sent, we have to tell the caller
              to try sending again, and remember how much was buffered */
-          BACKEND->ssl_write_buffered_length = len;
+          backend->ssl_write_buffered_length = len;
           *curlcode = CURLE_AGAIN;
           return -1L;
         default:
@@ -3185,8 +3220,12 @@
 {
   /*struct Curl_easy *data = conn->data;*/
   struct ssl_connect_data *connssl = &conn->ssl[num];
+  struct ssl_backend_data *backend = connssl->backend;
   size_t processed = 0UL;
-  OSStatus err = SSLRead(BACKEND->ssl_ctx, buf, buffersize, &processed);
+  OSStatus err;
+
+  again:
+  err = SSLRead(backend->ssl_ctx, buf, buffersize, &processed);
 
   if(err != noErr) {
     switch(err) {
@@ -3207,6 +3246,16 @@
         return -1L;
         break;
 
+        /* The below is errSSLPeerAuthCompleted; it's not defined in
+           Leopard's headers */
+      case -9841:
+        if(SSL_CONN_CONFIG(CAfile) && SSL_CONN_CONFIG(verifypeer)) {
+          CURLcode result = verify_cert(SSL_CONN_CONFIG(CAfile), conn->data,
+                                        backend->ssl_ctx);
+          if(result)
+            return result;
+        }
+        goto again;
       default:
         failf(conn->data, "SSLRead() return error %d", err);
         *curlcode = CURLE_RECV_ERROR;
@@ -3220,8 +3269,9 @@
 static void *Curl_sectransp_get_internals(struct ssl_connect_data *connssl,
                                           CURLINFO info UNUSED_PARAM)
 {
+  struct ssl_backend_data *backend = connssl->backend;
   (void)info;
-  return BACKEND->ssl_ctx;
+  return backend->ssl_ctx;
 }
 
 const struct Curl_ssl Curl_ssl_sectransp = {
diff --git a/Utilities/cmcurl/lib/vtls/vtls.c b/Utilities/cmcurl/lib/vtls/vtls.c
index a7452dc..c3a55fb 100644
--- a/Utilities/cmcurl/lib/vtls/vtls.c
+++ b/Utilities/cmcurl/lib/vtls/vtls.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -63,6 +63,7 @@
 #include "warnless.h"
 #include "curl_base64.h"
 #include "curl_printf.h"
+#include "strdup.h"
 
 /* The last #include files should be: */
 #include "curl_memory.h"
@@ -82,22 +83,62 @@
   else                                       \
     dest->var = NULL;
 
+#define CLONE_BLOB(var)                         \
+  if(blobdup(&dest->var, source->var))         \
+    return FALSE;
+
+static CURLcode blobdup(struct curl_blob **dest,
+                        struct curl_blob *src)
+{
+  DEBUGASSERT(dest);
+  DEBUGASSERT(!*dest);
+  if(src) {
+    /* only if there's data to dupe! */
+    struct curl_blob *d;
+    d = malloc(sizeof(struct curl_blob) + src->len);
+    if(!d)
+      return CURLE_OUT_OF_MEMORY;
+    d->len = src->len;
+    /* Always duplicate because the connection may survive longer than the
+       handle that passed in the blob. */
+    d->flags = CURL_BLOB_COPY;
+    d->data = (void *)((char *)d + sizeof(struct curl_blob));
+    memcpy(d->data, src->data, src->len);
+    *dest = d;
+  }
+  return CURLE_OK;
+}
+
+/* returns TRUE if the blobs are identical */
+static bool blobcmp(struct curl_blob *first, struct curl_blob *second)
+{
+  if(!first && !second) /* both are NULL */
+    return TRUE;
+  if(!first || !second) /* one is NULL */
+    return FALSE;
+  if(first->len != second->len) /* different sizes */
+    return FALSE;
+  return !memcmp(first->data, second->data, first->len); /* same data */
+}
+
 bool
-Curl_ssl_config_matches(struct ssl_primary_config* data,
-                        struct ssl_primary_config* needle)
+Curl_ssl_config_matches(struct ssl_primary_config *data,
+                        struct ssl_primary_config *needle)
 {
   if((data->version == needle->version) &&
      (data->version_max == needle->version_max) &&
      (data->verifypeer == needle->verifypeer) &&
      (data->verifyhost == needle->verifyhost) &&
      (data->verifystatus == needle->verifystatus) &&
+     blobcmp(data->cert_blob, needle->cert_blob) &&
      Curl_safe_strcasecompare(data->CApath, needle->CApath) &&
      Curl_safe_strcasecompare(data->CAfile, needle->CAfile) &&
      Curl_safe_strcasecompare(data->clientcert, needle->clientcert) &&
      Curl_safe_strcasecompare(data->random_file, needle->random_file) &&
      Curl_safe_strcasecompare(data->egdsocket, needle->egdsocket) &&
      Curl_safe_strcasecompare(data->cipher_list, needle->cipher_list) &&
-     Curl_safe_strcasecompare(data->cipher_list13, needle->cipher_list13))
+     Curl_safe_strcasecompare(data->cipher_list13, needle->cipher_list13) &&
+     Curl_safe_strcasecompare(data->pinned_key, needle->pinned_key))
     return TRUE;
 
   return FALSE;
@@ -114,6 +155,7 @@
   dest->verifystatus = source->verifystatus;
   dest->sessionid = source->sessionid;
 
+  CLONE_BLOB(cert_blob);
   CLONE_STRING(CApath);
   CLONE_STRING(CAfile);
   CLONE_STRING(clientcert);
@@ -121,11 +163,12 @@
   CLONE_STRING(egdsocket);
   CLONE_STRING(cipher_list);
   CLONE_STRING(cipher_list13);
+  CLONE_STRING(pinned_key);
 
   return TRUE;
 }
 
-void Curl_free_primary_ssl_config(struct ssl_primary_config* sslc)
+void Curl_free_primary_ssl_config(struct ssl_primary_config *sslc)
 {
   Curl_safefree(sslc->CApath);
   Curl_safefree(sslc->CAfile);
@@ -134,6 +177,8 @@
   Curl_safefree(sslc->egdsocket);
   Curl_safefree(sslc->cipher_list);
   Curl_safefree(sslc->cipher_list13);
+  Curl_safefree(sslc->pinned_key);
+  Curl_safefree(sslc->cert_blob);
 }
 
 #ifdef USE_SSL
@@ -171,6 +216,9 @@
   return Curl_ssl->init();
 }
 
+#if defined(CURL_WITH_MULTI_SSL)
+static const struct Curl_ssl Curl_ssl_multi;
+#endif
 
 /* Global cleanup */
 void Curl_ssl_cleanup(void)
@@ -178,6 +226,9 @@
   if(init_ssl) {
     /* only cleanup if we did a previous init */
     Curl_ssl->cleanup();
+#if defined(CURL_WITH_MULTI_SSL)
+    Curl_ssl = &Curl_ssl_multi;
+#endif
     init_ssl = FALSE;
   }
 }
@@ -206,6 +257,7 @@
   return TRUE;
 }
 
+#ifndef CURL_DISABLE_PROXY
 static CURLcode
 ssl_connect_init_proxy(struct connectdata *conn, int sockindex)
 {
@@ -229,17 +281,20 @@
   }
   return CURLE_OK;
 }
+#endif
 
 CURLcode
 Curl_ssl_connect(struct connectdata *conn, int sockindex)
 {
   CURLcode result;
 
+#ifndef CURL_DISABLE_PROXY
   if(conn->bits.proxy_ssl_connected[sockindex]) {
     result = ssl_connect_init_proxy(conn, sockindex);
     if(result)
       return result;
   }
+#endif
 
   if(!ssl_prefs_check(conn->data))
     return CURLE_SSL_CONNECT_ERROR;
@@ -261,12 +316,13 @@
                              bool *done)
 {
   CURLcode result;
+#ifndef CURL_DISABLE_PROXY
   if(conn->bits.proxy_ssl_connected[sockindex]) {
     result = ssl_connect_init_proxy(conn, sockindex);
     if(result)
       return result;
   }
-
+#endif
   if(!ssl_prefs_check(conn->data))
     return CURLE_SSL_CONNECT_ERROR;
 
@@ -312,13 +368,21 @@
   long *general_age;
   bool no_match = TRUE;
 
+#ifndef CURL_DISABLE_PROXY
   const bool isProxy = CONNECT_PROXY_SSL();
   struct ssl_primary_config * const ssl_config = isProxy ?
     &conn->proxy_ssl_config :
     &conn->ssl_config;
-  const char * const name = isProxy ? conn->http_proxy.host.name :
-    conn->host.name;
+  const char * const name = isProxy ?
+    conn->http_proxy.host.name : conn->host.name;
   int port = isProxy ? (int)conn->port : conn->remote_port;
+#else
+  /* no proxy support */
+  struct ssl_primary_config * const ssl_config = &conn->ssl_config;
+  const char * const name = conn->host.name;
+  int port = conn->remote_port;
+  (void)sockindex;
+#endif
   *ssl_sessionid = NULL;
 
   DEBUGASSERT(SSL_SET_OPTION(primary.sessionid));
@@ -420,14 +484,23 @@
   char *clone_conn_to_host;
   int conn_to_port;
   long *general_age;
+#ifndef CURL_DISABLE_PROXY
   const bool isProxy = CONNECT_PROXY_SSL();
   struct ssl_primary_config * const ssl_config = isProxy ?
     &conn->proxy_ssl_config :
     &conn->ssl_config;
-
+  const char *hostname = isProxy ? conn->http_proxy.host.name :
+    conn->host.name;
+#else
+  /* proxy support disabled */
+  const bool isProxy = FALSE;
+  struct ssl_primary_config * const ssl_config = &conn->ssl_config;
+  const char *hostname = conn->host.name;
+  (void)sockindex;
+#endif
   DEBUGASSERT(SSL_SET_OPTION(primary.sessionid));
 
-  clone_host = strdup(isProxy ? conn->http_proxy.host.name : conn->host.name);
+  clone_host = strdup(hostname);
   if(!clone_host)
     return CURLE_OUT_OF_MEMORY; /* bail out */
 
@@ -486,6 +559,7 @@
   store->scheme = conn->handler->scheme;
 
   if(!Curl_clone_primary_ssl_config(ssl_config, &store->ssl_config)) {
+    Curl_free_primary_ssl_config(&store->ssl_config);
     store->sessionid = NULL; /* let caller free sessionid */
     free(clone_host);
     free(clone_conn_to_host);
@@ -513,16 +587,12 @@
 }
 
 #if defined(USE_OPENSSL) || defined(USE_GNUTLS) || defined(USE_SCHANNEL) || \
-  defined(USE_SECTRANSP) || defined(USE_POLARSSL) || defined(USE_NSS) || \
-  defined(USE_MBEDTLS) || defined(USE_CYASSL)
-int Curl_ssl_getsock(struct connectdata *conn, curl_socket_t *socks,
-                     int numsocks)
+  defined(USE_SECTRANSP) || defined(USE_NSS) || \
+  defined(USE_MBEDTLS) || defined(USE_WOLFSSL) || defined(USE_BEARSSL)
+int Curl_ssl_getsock(struct connectdata *conn, curl_socket_t *socks)
 {
   struct ssl_connect_data *connssl = &conn->ssl[FIRSTSOCKET];
 
-  if(!numsocks)
-    return GETSOCK_BLANK;
-
   if(connssl->connecting_state == ssl_connect_2_writing) {
     /* write mode */
     socks[0] = conn->sock[FIRSTSOCKET];
@@ -538,12 +608,10 @@
 }
 #else
 int Curl_ssl_getsock(struct connectdata *conn,
-                     curl_socket_t *socks,
-                     int numsocks)
+                     curl_socket_t *socks)
 {
   (void)conn;
   (void)socks;
-  (void)numsocks;
   return GETSOCK_BLANK;
 }
 /* USE_OPENSSL || USE_GNUTLS || USE_SCHANNEL || USE_SECTRANSP || USE_NSS */
@@ -680,7 +748,7 @@
 }
 
 /*
- * 'value' is NOT a zero terminated string
+ * 'value' is NOT a null-terminated string
  */
 CURLcode Curl_ssl_push_certinfo_len(struct Curl_easy *data,
                                     int certnum,
@@ -702,10 +770,10 @@
   /* sprintf the label and colon */
   msnprintf(output, outlen, "%s:", label);
 
-  /* memcpy the value (it might not be zero terminated) */
+  /* memcpy the value (it might not be null-terminated) */
   memcpy(&output[labellen + 1], value, valuelen);
 
-  /* zero terminate the output */
+  /* null-terminate the output */
   output[labellen + 1 + valuelen] = 0;
 
   nl = Curl_slist_append_nodup(ci->certinfo[certnum], output);
@@ -1080,7 +1148,7 @@
 CURLcode Curl_none_md5sum(unsigned char *input, size_t inputlen,
                           unsigned char *md5sum, size_t md5len UNUSED_PARAM)
 {
-  MD5_context *MD5pw;
+  struct MD5_context *MD5pw;
 
   (void)md5len;
 
@@ -1172,8 +1240,8 @@
 const struct Curl_ssl *Curl_ssl =
 #if defined(CURL_WITH_MULTI_SSL)
   &Curl_ssl_multi;
-#elif defined(USE_CYASSL)
-  &Curl_ssl_cyassl;
+#elif defined(USE_WOLFSSL)
+  &Curl_ssl_wolfssl;
 #elif defined(USE_SECTRANSP)
   &Curl_ssl_sectransp;
 #elif defined(USE_GNUTLS)
@@ -1186,19 +1254,19 @@
   &Curl_ssl_nss;
 #elif defined(USE_OPENSSL)
   &Curl_ssl_openssl;
-#elif defined(USE_POLARSSL)
-  &Curl_ssl_polarssl;
 #elif defined(USE_SCHANNEL)
   &Curl_ssl_schannel;
 #elif defined(USE_MESALINK)
   &Curl_ssl_mesalink;
+#elif defined(USE_BEARSSL)
+  &Curl_ssl_bearssl;
 #else
 #error "Missing struct Curl_ssl for selected SSL backend"
 #endif
 
 static const struct Curl_ssl *available_backends[] = {
-#if defined(USE_CYASSL)
-  &Curl_ssl_cyassl,
+#if defined(USE_WOLFSSL)
+  &Curl_ssl_wolfssl,
 #endif
 #if defined(USE_SECTRANSP)
   &Curl_ssl_sectransp,
@@ -1218,15 +1286,15 @@
 #if defined(USE_OPENSSL)
   &Curl_ssl_openssl,
 #endif
-#if defined(USE_POLARSSL)
-  &Curl_ssl_polarssl,
-#endif
 #if defined(USE_SCHANNEL)
   &Curl_ssl_schannel,
 #endif
 #if defined(USE_MESALINK)
   &Curl_ssl_mesalink,
 #endif
+#if defined(USE_BEARSSL)
+  &Curl_ssl_bearssl,
+#endif
   NULL
 };
 
@@ -1234,7 +1302,7 @@
 {
   static const struct Curl_ssl *selected;
   static char backends[200];
-  static size_t total;
+  static size_t backends_len;
   const struct Curl_ssl *current;
 
   current = Curl_ssl == &Curl_ssl_multi ? available_backends[0] : Curl_ssl;
@@ -1246,27 +1314,32 @@
 
     selected = current;
 
-    for(i = 0; available_backends[i] && p < (end - 4); i++) {
-      if(i)
-        *(p++) = ' ';
-      if(selected != available_backends[i])
-        *(p++) = '(';
-      p += available_backends[i]->version(p, end - p - 2);
-      if(selected != available_backends[i])
-        *(p++) = ')';
+    backends[0] = '\0';
+
+    for(i = 0; available_backends[i]; ++i) {
+      char vb[200];
+      bool paren = (selected != available_backends[i]);
+
+      if(available_backends[i]->version(vb, sizeof(vb))) {
+        p += msnprintf(p, end - p, "%s%s%s%s", (p != backends ? " " : ""),
+                       (paren ? "(" : ""), vb, (paren ? ")" : ""));
+      }
     }
-    *p = '\0';
-    total = p - backends;
+
+    backends_len = p - backends;
   }
 
-  if(size > total)
-    memcpy(buffer, backends, total + 1);
-  else {
-    memcpy(buffer, backends, size - 1);
+  if(!size)
+    return 0;
+
+  if(size <= backends_len) {
+    strncpy(buffer, backends, size - 1);
     buffer[size - 1] = '\0';
+    return size - 1;
   }
 
-  return CURLMIN(size - 1, total);
+  strcpy(buffer, backends);
+  return backends_len;
 }
 
 static int multissl_init(const struct Curl_ssl *backend)
diff --git a/Utilities/cmcurl/lib/vtls/vtls.h b/Utilities/cmcurl/lib/vtls/vtls.h
index 2a87ca1..bcc8444 100644
--- a/Utilities/cmcurl/lib/vtls/vtls.h
+++ b/Utilities/cmcurl/lib/vtls/vtls.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -102,23 +102,17 @@
 #include "gtls.h"           /* GnuTLS versions */
 #include "nssg.h"           /* NSS versions */
 #include "gskit.h"          /* Global Secure ToolKit versions */
-#include "polarssl.h"       /* PolarSSL versions */
-#include "cyassl.h"         /* CyaSSL versions */
+#include "wolfssl.h"        /* wolfSSL versions */
 #include "schannel.h"       /* Schannel SSPI version */
 #include "sectransp.h"      /* SecureTransport (Darwin) version */
 #include "mbedtls.h"        /* mbedTLS versions */
 #include "mesalink.h"       /* MesaLink versions */
+#include "bearssl.h"        /* BearSSL versions */
 
 #ifndef MAX_PINNED_PUBKEY_SIZE
 #define MAX_PINNED_PUBKEY_SIZE 1048576 /* 1MB */
 #endif
 
-#ifndef MD5_DIGEST_LENGTH
-#ifndef LIBWOLFSSL_VERSION_HEX /* because WolfSSL borks this */
-#define MD5_DIGEST_LENGTH 16 /* fixed size */
-#endif
-#endif
-
 #ifndef CURL_SHA256_DIGEST_LENGTH
 #define CURL_SHA256_DIGEST_LENGTH 32 /* fixed size */
 #endif
@@ -129,22 +123,28 @@
 
 /* set of helper macros for the backends to access the correct fields. For the
    proxy or for the remote host - to properly support HTTPS proxy */
+#ifndef CURL_DISABLE_PROXY
+#define SSL_IS_PROXY()                                                  \
+  (CURLPROXY_HTTPS == conn->http_proxy.proxytype &&                     \
+   ssl_connection_complete !=                                           \
+   conn->proxy_ssl[conn->sock[SECONDARYSOCKET] ==                       \
+                   CURL_SOCKET_BAD ? FIRSTSOCKET : SECONDARYSOCKET].state)
+#define SSL_SET_OPTION(var)                                             \
+  (SSL_IS_PROXY() ? data->set.proxy_ssl.var : data->set.ssl.var)
+#define SSL_CONN_CONFIG(var)                                            \
+  (SSL_IS_PROXY() ? conn->proxy_ssl_config.var : conn->ssl_config.var)
+#else
+#define SSL_IS_PROXY() FALSE
+#define SSL_SET_OPTION(var) data->set.ssl.var
+#define SSL_CONN_CONFIG(var) conn->ssl_config.var
+#endif
 
-#define SSL_IS_PROXY() (CURLPROXY_HTTPS == conn->http_proxy.proxytype && \
-  ssl_connection_complete != conn->proxy_ssl[conn->sock[SECONDARYSOCKET] == \
-  CURL_SOCKET_BAD ? FIRSTSOCKET : SECONDARYSOCKET].state)
-#define SSL_SET_OPTION(var) (SSL_IS_PROXY() ? data->set.proxy_ssl.var : \
-                             data->set.ssl.var)
-#define SSL_CONN_CONFIG(var) (SSL_IS_PROXY() ?          \
-  conn->proxy_ssl_config.var : conn->ssl_config.var)
-
-bool Curl_ssl_config_matches(struct ssl_primary_config* data,
-                             struct ssl_primary_config* needle);
+bool Curl_ssl_config_matches(struct ssl_primary_config *data,
+                             struct ssl_primary_config *needle);
 bool Curl_clone_primary_ssl_config(struct ssl_primary_config *source,
                                    struct ssl_primary_config *dest);
-void Curl_free_primary_ssl_config(struct ssl_primary_config* sslc);
-int Curl_ssl_getsock(struct connectdata *conn, curl_socket_t *socks,
-                     int numsocks);
+void Curl_free_primary_ssl_config(struct ssl_primary_config *sslc);
+int Curl_ssl_getsock(struct connectdata *conn, curl_socket_t *socks);
 
 int Curl_ssl_backend(void);
 
@@ -263,7 +263,6 @@
 #define Curl_ssl_send(a,b,c,d,e) -1
 #define Curl_ssl_recv(a,b,c,d,e) -1
 #define Curl_ssl_initsessions(x,y) CURLE_OK
-#define Curl_ssl_version(x,y) 0
 #define Curl_ssl_data_pending(x,y) 0
 #define Curl_ssl_check_cxn(x) 0
 #define Curl_ssl_free_certinfo(x) Curl_nop_stmt
diff --git a/Utilities/cmcurl/lib/vtls/wolfssl.c b/Utilities/cmcurl/lib/vtls/wolfssl.c
new file mode 100644
index 0000000..7b2a124
--- /dev/null
+++ b/Utilities/cmcurl/lib/vtls/wolfssl.c
@@ -0,0 +1,1151 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+/*
+ * Source file for all wolfSSL specific code for the TLS/SSL layer. No code
+ * but vtls.c should ever call or use these functions.
+ *
+ */
+
+#include "curl_setup.h"
+
+#ifdef USE_WOLFSSL
+
+#define WOLFSSL_OPTIONS_IGNORE_SYS
+#include <wolfssl/version.h>
+#include <wolfssl/options.h>
+
+/* To determine what functions are available we rely on one or both of:
+   - the user's options.h generated by wolfSSL
+   - the symbols detected by curl's configure
+   Since they are markedly different from one another, and one or the other may
+   not be available, we do some checking below to bring things in sync. */
+
+/* HAVE_ALPN is wolfSSL's build time symbol for enabling ALPN in options.h. */
+#ifndef HAVE_ALPN
+#ifdef HAVE_WOLFSSL_USEALPN
+#define HAVE_ALPN
+#endif
+#endif
+
+/* WOLFSSL_ALLOW_SSLV3 is wolfSSL's build time symbol for enabling SSLv3 in
+   options.h, but is only seen in >= 3.6.6 since that's when they started
+   disabling SSLv3 by default. */
+#ifndef WOLFSSL_ALLOW_SSLV3
+#if (LIBWOLFSSL_VERSION_HEX < 0x03006006) || \
+  defined(HAVE_WOLFSSLV3_CLIENT_METHOD)
+#define WOLFSSL_ALLOW_SSLV3
+#endif
+#endif
+
+#include <limits.h>
+
+#include "urldata.h"
+#include "sendf.h"
+#include "inet_pton.h"
+#include "vtls.h"
+#include "keylog.h"
+#include "parsedate.h"
+#include "connect.h" /* for the connect timeout */
+#include "select.h"
+#include "strcase.h"
+#include "x509asn1.h"
+#include "curl_printf.h"
+#include "multiif.h"
+
+#include <wolfssl/openssl/ssl.h>
+#include <wolfssl/ssl.h>
+#include <wolfssl/error-ssl.h>
+#include "wolfssl.h"
+
+/* The last #include files should be: */
+#include "curl_memory.h"
+#include "memdebug.h"
+
+/* KEEP_PEER_CERT is a product of the presence of build time symbol
+   OPENSSL_EXTRA without NO_CERTS, depending on the version. KEEP_PEER_CERT is
+   in wolfSSL's settings.h, and the latter two are build time symbols in
+   options.h. */
+#ifndef KEEP_PEER_CERT
+#if defined(HAVE_WOLFSSL_GET_PEER_CERTIFICATE) || \
+    (defined(OPENSSL_EXTRA) && !defined(NO_CERTS))
+#define KEEP_PEER_CERT
+#endif
+#endif
+
+struct ssl_backend_data {
+  SSL_CTX* ctx;
+  SSL*     handle;
+};
+
+static Curl_recv wolfssl_recv;
+static Curl_send wolfssl_send;
+
+#ifdef OPENSSL_EXTRA
+/*
+ * Availability note:
+ * The TLS 1.3 secret callback (wolfSSL_set_tls13_secret_cb) was added in
+ * WolfSSL 4.4.0, but requires the -DHAVE_SECRET_CALLBACK build option. If that
+ * option is not set, then TLS 1.3 will not be logged.
+ * For TLS 1.2 and before, we use wolfSSL_get_keys().
+ * SSL_get_client_random and wolfSSL_get_keys require OPENSSL_EXTRA
+ * (--enable-opensslextra or --enable-all).
+ */
+#if defined(HAVE_SECRET_CALLBACK) && defined(WOLFSSL_TLS13)
+static int
+wolfssl_tls13_secret_callback(SSL *ssl, int id, const unsigned char *secret,
+                              int secretSz, void *ctx)
+{
+  const char *label;
+  unsigned char client_random[SSL3_RANDOM_SIZE];
+  (void)ctx;
+
+  if(!ssl || !Curl_tls_keylog_enabled()) {
+    return 0;
+  }
+
+  switch(id) {
+  case CLIENT_EARLY_TRAFFIC_SECRET:
+    label = "CLIENT_EARLY_TRAFFIC_SECRET";
+    break;
+  case CLIENT_HANDSHAKE_TRAFFIC_SECRET:
+    label = "CLIENT_HANDSHAKE_TRAFFIC_SECRET";
+    break;
+  case SERVER_HANDSHAKE_TRAFFIC_SECRET:
+    label = "SERVER_HANDSHAKE_TRAFFIC_SECRET";
+    break;
+  case CLIENT_TRAFFIC_SECRET:
+    label = "CLIENT_TRAFFIC_SECRET_0";
+    break;
+  case SERVER_TRAFFIC_SECRET:
+    label = "SERVER_TRAFFIC_SECRET_0";
+    break;
+  case EARLY_EXPORTER_SECRET:
+    label = "EARLY_EXPORTER_SECRET";
+    break;
+  case EXPORTER_SECRET:
+    label = "EXPORTER_SECRET";
+    break;
+  default:
+    return 0;
+  }
+
+  if(SSL_get_client_random(ssl, client_random, SSL3_RANDOM_SIZE) == 0) {
+    /* Should never happen as wolfSSL_KeepArrays() was called before. */
+    return 0;
+  }
+
+  Curl_tls_keylog_write(label, client_random, secret, secretSz);
+  return 0;
+}
+#endif /* defined(HAVE_SECRET_CALLBACK) && defined(WOLFSSL_TLS13) */
+
+static void
+wolfssl_log_tls12_secret(SSL *ssl)
+{
+  unsigned char *ms, *sr, *cr;
+  unsigned int msLen, srLen, crLen, i, x = 0;
+
+#if LIBWOLFSSL_VERSION_HEX >= 0x0300d000 /* >= 3.13.0 */
+  /* wolfSSL_GetVersion is available since 3.13, we use it instead of
+   * SSL_version since the latter relies on OPENSSL_ALL (--enable-opensslall or
+   * --enable-all). Failing to perform this check could result in an unusable
+   * key log line when TLS 1.3 is actually negotiated. */
+  switch(wolfSSL_GetVersion(ssl)) {
+  case WOLFSSL_SSLV3:
+  case WOLFSSL_TLSV1:
+  case WOLFSSL_TLSV1_1:
+  case WOLFSSL_TLSV1_2:
+    break;
+  default:
+    /* TLS 1.3 does not use this mechanism, the "master secret" returned below
+     * is not directly usable. */
+    return;
+  }
+#endif
+
+  if(SSL_get_keys(ssl, &ms, &msLen, &sr, &srLen, &cr, &crLen) != SSL_SUCCESS) {
+    return;
+  }
+
+  /* Check for a missing master secret and skip logging. That can happen if
+   * curl rejects the server certificate and aborts the handshake.
+   */
+  for(i = 0; i < msLen; i++) {
+    x |= ms[i];
+  }
+  if(x == 0) {
+    return;
+  }
+
+  Curl_tls_keylog_write("CLIENT_RANDOM", cr, ms, msLen);
+}
+#endif /* OPENSSL_EXTRA */
+
+static int do_file_type(const char *type)
+{
+  if(!type || !type[0])
+    return SSL_FILETYPE_PEM;
+  if(strcasecompare(type, "PEM"))
+    return SSL_FILETYPE_PEM;
+  if(strcasecompare(type, "DER"))
+    return SSL_FILETYPE_ASN1;
+  return -1;
+}
+
+/*
+ * This function loads all the client/CA certificates and CRLs. Setup the TLS
+ * layer and do all necessary magic.
+ */
+static CURLcode
+wolfssl_connect_step1(struct connectdata *conn,
+                     int sockindex)
+{
+  char *ciphers;
+  struct Curl_easy *data = conn->data;
+  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+  struct ssl_backend_data *backend = connssl->backend;
+  SSL_METHOD* req_method = NULL;
+  curl_socket_t sockfd = conn->sock[sockindex];
+#ifdef HAVE_SNI
+  bool sni = FALSE;
+#define use_sni(x)  sni = (x)
+#else
+#define use_sni(x)  Curl_nop_stmt
+#endif
+
+  if(connssl->state == ssl_connection_complete)
+    return CURLE_OK;
+
+  if(SSL_CONN_CONFIG(version_max) != CURL_SSLVERSION_MAX_NONE) {
+    failf(data, "wolfSSL does not support to set maximum SSL/TLS version");
+    return CURLE_SSL_CONNECT_ERROR;
+  }
+
+  /* check to see if we've been told to use an explicit SSL/TLS version */
+  switch(SSL_CONN_CONFIG(version)) {
+  case CURL_SSLVERSION_DEFAULT:
+  case CURL_SSLVERSION_TLSv1:
+#if LIBWOLFSSL_VERSION_HEX >= 0x03003000 /* >= 3.3.0 */
+    /* minimum protocol version is set later after the CTX object is created */
+    req_method = SSLv23_client_method();
+#else
+    infof(data, "wolfSSL <3.3.0 cannot be configured to use TLS 1.0-1.2, "
+          "TLS 1.0 is used exclusively\n");
+    req_method = TLSv1_client_method();
+#endif
+    use_sni(TRUE);
+    break;
+  case CURL_SSLVERSION_TLSv1_0:
+#ifdef WOLFSSL_ALLOW_TLSV10
+    req_method = TLSv1_client_method();
+    use_sni(TRUE);
+#else
+    failf(data, "wolfSSL does not support TLS 1.0");
+    return CURLE_NOT_BUILT_IN;
+#endif
+    break;
+  case CURL_SSLVERSION_TLSv1_1:
+    req_method = TLSv1_1_client_method();
+    use_sni(TRUE);
+    break;
+  case CURL_SSLVERSION_TLSv1_2:
+    req_method = TLSv1_2_client_method();
+    use_sni(TRUE);
+    break;
+  case CURL_SSLVERSION_TLSv1_3:
+#ifdef WOLFSSL_TLS13
+    req_method = wolfTLSv1_3_client_method();
+    use_sni(TRUE);
+    break;
+#else
+    failf(data, "wolfSSL: TLS 1.3 is not yet supported");
+    return CURLE_SSL_CONNECT_ERROR;
+#endif
+  case CURL_SSLVERSION_SSLv3:
+#ifdef WOLFSSL_ALLOW_SSLV3
+    req_method = SSLv3_client_method();
+    use_sni(FALSE);
+#else
+    failf(data, "wolfSSL does not support SSLv3");
+    return CURLE_NOT_BUILT_IN;
+#endif
+    break;
+  case CURL_SSLVERSION_SSLv2:
+    failf(data, "wolfSSL does not support SSLv2");
+    return CURLE_SSL_CONNECT_ERROR;
+  default:
+    failf(data, "Unrecognized parameter passed via CURLOPT_SSLVERSION");
+    return CURLE_SSL_CONNECT_ERROR;
+  }
+
+  if(!req_method) {
+    failf(data, "SSL: couldn't create a method!");
+    return CURLE_OUT_OF_MEMORY;
+  }
+
+  if(backend->ctx)
+    SSL_CTX_free(backend->ctx);
+  backend->ctx = SSL_CTX_new(req_method);
+
+  if(!backend->ctx) {
+    failf(data, "SSL: couldn't create a context!");
+    return CURLE_OUT_OF_MEMORY;
+  }
+
+  switch(SSL_CONN_CONFIG(version)) {
+  case CURL_SSLVERSION_DEFAULT:
+  case CURL_SSLVERSION_TLSv1:
+#if LIBWOLFSSL_VERSION_HEX > 0x03004006 /* > 3.4.6 */
+    /* Versions 3.3.0 to 3.4.6 we know the minimum protocol version is
+     * whatever minimum version of TLS was built in and at least TLS 1.0. For
+     * later library versions that could change (eg TLS 1.0 built in but
+     * defaults to TLS 1.1) so we have this short circuit evaluation to find
+     * the minimum supported TLS version.
+    */
+    if((wolfSSL_CTX_SetMinVersion(backend->ctx, WOLFSSL_TLSV1) != 1) &&
+       (wolfSSL_CTX_SetMinVersion(backend->ctx, WOLFSSL_TLSV1_1) != 1) &&
+       (wolfSSL_CTX_SetMinVersion(backend->ctx, WOLFSSL_TLSV1_2) != 1)
+#ifdef WOLFSSL_TLS13
+       && (wolfSSL_CTX_SetMinVersion(backend->ctx, WOLFSSL_TLSV1_3) != 1)
+#endif
+      ) {
+      failf(data, "SSL: couldn't set the minimum protocol version");
+      return CURLE_SSL_CONNECT_ERROR;
+    }
+#endif
+    break;
+  }
+
+  ciphers = SSL_CONN_CONFIG(cipher_list);
+  if(ciphers) {
+    if(!SSL_CTX_set_cipher_list(backend->ctx, ciphers)) {
+      failf(data, "failed setting cipher list: %s", ciphers);
+      return CURLE_SSL_CIPHER;
+    }
+    infof(data, "Cipher selection: %s\n", ciphers);
+  }
+
+#ifndef NO_FILESYSTEM
+  /* load trusted cacert */
+  if(SSL_CONN_CONFIG(CAfile)) {
+    if(1 != SSL_CTX_load_verify_locations(backend->ctx,
+                                      SSL_CONN_CONFIG(CAfile),
+                                      SSL_CONN_CONFIG(CApath))) {
+      if(SSL_CONN_CONFIG(verifypeer)) {
+        /* Fail if we insist on successfully verifying the server. */
+        failf(data, "error setting certificate verify locations:\n"
+              "  CAfile: %s\n  CApath: %s",
+              SSL_CONN_CONFIG(CAfile)?
+              SSL_CONN_CONFIG(CAfile): "none",
+              SSL_CONN_CONFIG(CApath)?
+              SSL_CONN_CONFIG(CApath) : "none");
+        return CURLE_SSL_CACERT_BADFILE;
+      }
+      else {
+        /* Just continue with a warning if no strict certificate
+           verification is required. */
+        infof(data, "error setting certificate verify locations,"
+              " continuing anyway:\n");
+      }
+    }
+    else {
+      /* Everything is fine. */
+      infof(data, "successfully set certificate verify locations:\n");
+    }
+    infof(data,
+          "  CAfile: %s\n"
+          "  CApath: %s\n",
+          SSL_CONN_CONFIG(CAfile) ? SSL_CONN_CONFIG(CAfile):
+          "none",
+          SSL_CONN_CONFIG(CApath) ? SSL_CONN_CONFIG(CApath):
+          "none");
+  }
+
+  /* Load the client certificate, and private key */
+  if(SSL_SET_OPTION(cert) && SSL_SET_OPTION(key)) {
+    int file_type = do_file_type(SSL_SET_OPTION(cert_type));
+
+    if(SSL_CTX_use_certificate_file(backend->ctx, SSL_SET_OPTION(cert),
+                                     file_type) != 1) {
+      failf(data, "unable to use client certificate (no key or wrong pass"
+            " phrase?)");
+      return CURLE_SSL_CONNECT_ERROR;
+    }
+
+    file_type = do_file_type(SSL_SET_OPTION(key_type));
+    if(SSL_CTX_use_PrivateKey_file(backend->ctx, SSL_SET_OPTION(key),
+                                    file_type) != 1) {
+      failf(data, "unable to set private key");
+      return CURLE_SSL_CONNECT_ERROR;
+    }
+  }
+#endif /* !NO_FILESYSTEM */
+
+  /* SSL always tries to verify the peer, this only says whether it should
+   * fail to connect if the verification fails, or if it should continue
+   * anyway. In the latter case the result of the verification is checked with
+   * SSL_get_verify_result() below. */
+  SSL_CTX_set_verify(backend->ctx,
+                     SSL_CONN_CONFIG(verifypeer)?SSL_VERIFY_PEER:
+                                                 SSL_VERIFY_NONE,
+                     NULL);
+
+#ifdef HAVE_SNI
+  if(sni) {
+    struct in_addr addr4;
+#ifdef ENABLE_IPV6
+    struct in6_addr addr6;
+#endif
+#ifndef CURL_DISABLE_PROXY
+    const char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name :
+      conn->host.name;
+#else
+    const char * const hostname = conn->host.name;
+#endif
+    size_t hostname_len = strlen(hostname);
+    if((hostname_len < USHRT_MAX) &&
+       (0 == Curl_inet_pton(AF_INET, hostname, &addr4)) &&
+#ifdef ENABLE_IPV6
+       (0 == Curl_inet_pton(AF_INET6, hostname, &addr6)) &&
+#endif
+       (wolfSSL_CTX_UseSNI(backend->ctx, WOLFSSL_SNI_HOST_NAME, hostname,
+                          (unsigned short)hostname_len) != 1)) {
+      infof(data, "WARNING: failed to configure server name indication (SNI) "
+            "TLS extension\n");
+    }
+  }
+#endif
+
+  /* give application a chance to interfere with SSL set up. */
+  if(data->set.ssl.fsslctx) {
+    CURLcode result = (*data->set.ssl.fsslctx)(data, backend->ctx,
+                                               data->set.ssl.fsslctxp);
+    if(result) {
+      failf(data, "error signaled by ssl ctx callback");
+      return result;
+    }
+  }
+#ifdef NO_FILESYSTEM
+  else if(SSL_CONN_CONFIG(verifypeer)) {
+    failf(data, "SSL: Certificates can't be loaded because wolfSSL was built"
+          " with \"no filesystem\". Either disable peer verification"
+          " (insecure) or if you are building an application with libcurl you"
+          " can load certificates via CURLOPT_SSL_CTX_FUNCTION.");
+    return CURLE_SSL_CONNECT_ERROR;
+  }
+#endif
+
+  /* Let's make an SSL structure */
+  if(backend->handle)
+    SSL_free(backend->handle);
+  backend->handle = SSL_new(backend->ctx);
+  if(!backend->handle) {
+    failf(data, "SSL: couldn't create a context (handle)!");
+    return CURLE_OUT_OF_MEMORY;
+  }
+
+#ifdef HAVE_ALPN
+  if(conn->bits.tls_enable_alpn) {
+    char protocols[128];
+    *protocols = '\0';
+
+    /* wolfSSL's ALPN protocol name list format is a comma separated string of
+       protocols in descending order of preference, eg: "h2,http/1.1" */
+
+#ifdef USE_NGHTTP2
+    if(data->set.httpversion >= CURL_HTTP_VERSION_2) {
+      strcpy(protocols + strlen(protocols), NGHTTP2_PROTO_VERSION_ID ",");
+      infof(data, "ALPN, offering %s\n", NGHTTP2_PROTO_VERSION_ID);
+    }
+#endif
+
+    strcpy(protocols + strlen(protocols), ALPN_HTTP_1_1);
+    infof(data, "ALPN, offering %s\n", ALPN_HTTP_1_1);
+
+    if(wolfSSL_UseALPN(backend->handle, protocols,
+                       (unsigned)strlen(protocols),
+                       WOLFSSL_ALPN_CONTINUE_ON_MISMATCH) != SSL_SUCCESS) {
+      failf(data, "SSL: failed setting ALPN protocols");
+      return CURLE_SSL_CONNECT_ERROR;
+    }
+  }
+#endif /* HAVE_ALPN */
+
+#ifdef OPENSSL_EXTRA
+  if(Curl_tls_keylog_enabled()) {
+    /* Ensure the Client Random is preserved. */
+    wolfSSL_KeepArrays(backend->handle);
+#if defined(HAVE_SECRET_CALLBACK) && defined(WOLFSSL_TLS13)
+    wolfSSL_set_tls13_secret_cb(backend->handle,
+                                wolfssl_tls13_secret_callback, NULL);
+#endif
+  }
+#endif /* OPENSSL_EXTRA */
+
+  /* Check if there's a cached ID we can/should use here! */
+  if(SSL_SET_OPTION(primary.sessionid)) {
+    void *ssl_sessionid = NULL;
+
+    Curl_ssl_sessionid_lock(conn);
+    if(!Curl_ssl_getsessionid(conn, &ssl_sessionid, NULL, sockindex)) {
+      /* we got a session id, use it! */
+      if(!SSL_set_session(backend->handle, ssl_sessionid)) {
+        char error_buffer[WOLFSSL_MAX_ERROR_SZ];
+        Curl_ssl_sessionid_unlock(conn);
+        failf(data, "SSL: SSL_set_session failed: %s",
+              ERR_error_string(SSL_get_error(backend->handle, 0),
+                               error_buffer));
+        return CURLE_SSL_CONNECT_ERROR;
+      }
+      /* Informational message */
+      infof(data, "SSL re-using session ID\n");
+    }
+    Curl_ssl_sessionid_unlock(conn);
+  }
+
+  /* pass the raw socket into the SSL layer */
+  if(!SSL_set_fd(backend->handle, (int)sockfd)) {
+    failf(data, "SSL: SSL_set_fd failed");
+    return CURLE_SSL_CONNECT_ERROR;
+  }
+
+  connssl->connecting_state = ssl_connect_2;
+  return CURLE_OK;
+}
+
+
+static CURLcode
+wolfssl_connect_step2(struct connectdata *conn,
+                     int sockindex)
+{
+  int ret = -1;
+  struct Curl_easy *data = conn->data;
+  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+  struct ssl_backend_data *backend = connssl->backend;
+#ifndef CURL_DISABLE_PROXY
+  const char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name :
+    conn->host.name;
+  const char * const dispname = SSL_IS_PROXY() ?
+    conn->http_proxy.host.dispname : conn->host.dispname;
+  const char * const pinnedpubkey = SSL_IS_PROXY() ?
+    data->set.str[STRING_SSL_PINNEDPUBLICKEY_PROXY] :
+    data->set.str[STRING_SSL_PINNEDPUBLICKEY_ORIG];
+#else
+  const char * const hostname = conn->host.name;
+  const char * const dispname = conn->host.dispname;
+  const char * const pinnedpubkey =
+    data->set.str[STRING_SSL_PINNEDPUBLICKEY_ORIG];
+#endif
+
+  conn->recv[sockindex] = wolfssl_recv;
+  conn->send[sockindex] = wolfssl_send;
+
+  /* Enable RFC2818 checks */
+  if(SSL_CONN_CONFIG(verifyhost)) {
+    ret = wolfSSL_check_domain_name(backend->handle, hostname);
+    if(ret == SSL_FAILURE)
+      return CURLE_OUT_OF_MEMORY;
+  }
+
+  ret = SSL_connect(backend->handle);
+
+#ifdef OPENSSL_EXTRA
+  if(Curl_tls_keylog_enabled()) {
+    /* If key logging is enabled, wait for the handshake to complete and then
+     * proceed with logging secrets (for TLS 1.2 or older).
+     *
+     * During the handshake (ret==-1), wolfSSL_want_read() is true as it waits
+     * for the server response. At that point the master secret is not yet
+     * available, so we must not try to read it.
+     * To log the secret on completion with a handshake failure, detect
+     * completion via the observation that there is nothing to read or write.
+     * Note that OpenSSL SSL_want_read() is always true here. If wolfSSL ever
+     * changes, the worst case is that no key is logged on error.
+     */
+    if(ret == SSL_SUCCESS ||
+       (!wolfSSL_want_read(backend->handle) &&
+        !wolfSSL_want_write(backend->handle))) {
+      wolfssl_log_tls12_secret(backend->handle);
+      /* Client Random and master secrets are no longer needed, erase these.
+       * Ignored while the handshake is still in progress. */
+      wolfSSL_FreeArrays(backend->handle);
+    }
+  }
+#endif  /* OPENSSL_EXTRA */
+
+  if(ret != 1) {
+    char error_buffer[WOLFSSL_MAX_ERROR_SZ];
+    int  detail = SSL_get_error(backend->handle, ret);
+
+    if(SSL_ERROR_WANT_READ == detail) {
+      connssl->connecting_state = ssl_connect_2_reading;
+      return CURLE_OK;
+    }
+    else if(SSL_ERROR_WANT_WRITE == detail) {
+      connssl->connecting_state = ssl_connect_2_writing;
+      return CURLE_OK;
+    }
+    /* There is no easy way to override only the CN matching.
+     * This will enable the override of both mismatching SubjectAltNames
+     * as also mismatching CN fields */
+    else if(DOMAIN_NAME_MISMATCH == detail) {
+#if 1
+      failf(data, "\tsubject alt name(s) or common name do not match \"%s\"\n",
+            dispname);
+      return CURLE_PEER_FAILED_VERIFICATION;
+#else
+      /* When the wolfssl_check_domain_name() is used and you desire to
+       * continue on a DOMAIN_NAME_MISMATCH, i.e. 'conn->ssl_config.verifyhost
+       * == 0', CyaSSL version 2.4.0 will fail with an INCOMPLETE_DATA
+       * error. The only way to do this is currently to switch the
+       * Wolfssl_check_domain_name() in and out based on the
+       * 'conn->ssl_config.verifyhost' value. */
+      if(SSL_CONN_CONFIG(verifyhost)) {
+        failf(data,
+              "\tsubject alt name(s) or common name do not match \"%s\"\n",
+              dispname);
+        return CURLE_PEER_FAILED_VERIFICATION;
+      }
+      else {
+        infof(data,
+              "\tsubject alt name(s) and/or common name do not match \"%s\"\n",
+              dispname);
+        return CURLE_OK;
+      }
+#endif
+    }
+#if LIBWOLFSSL_VERSION_HEX >= 0x02007000 /* 2.7.0 */
+    else if(ASN_NO_SIGNER_E == detail) {
+      if(SSL_CONN_CONFIG(verifypeer)) {
+        failf(data, "\tCA signer not available for verification\n");
+        return CURLE_SSL_CACERT_BADFILE;
+      }
+      else {
+        /* Just continue with a warning if no strict certificate
+           verification is required. */
+        infof(data, "CA signer not available for verification, "
+                    "continuing anyway\n");
+      }
+    }
+#endif
+    else {
+      failf(data, "SSL_connect failed with error %d: %s", detail,
+          ERR_error_string(detail, error_buffer));
+      return CURLE_SSL_CONNECT_ERROR;
+    }
+  }
+
+  if(pinnedpubkey) {
+#ifdef KEEP_PEER_CERT
+    X509 *x509;
+    const char *x509_der;
+    int x509_der_len;
+    struct Curl_X509certificate x509_parsed;
+    struct Curl_asn1Element *pubkey;
+    CURLcode result;
+
+    x509 = SSL_get_peer_certificate(backend->handle);
+    if(!x509) {
+      failf(data, "SSL: failed retrieving server certificate");
+      return CURLE_SSL_PINNEDPUBKEYNOTMATCH;
+    }
+
+    x509_der = (const char *)wolfSSL_X509_get_der(x509, &x509_der_len);
+    if(!x509_der) {
+      failf(data, "SSL: failed retrieving ASN.1 server certificate");
+      return CURLE_SSL_PINNEDPUBKEYNOTMATCH;
+    }
+
+    memset(&x509_parsed, 0, sizeof(x509_parsed));
+    if(Curl_parseX509(&x509_parsed, x509_der, x509_der + x509_der_len))
+      return CURLE_SSL_PINNEDPUBKEYNOTMATCH;
+
+    pubkey = &x509_parsed.subjectPublicKeyInfo;
+    if(!pubkey->header || pubkey->end <= pubkey->header) {
+      failf(data, "SSL: failed retrieving public key from server certificate");
+      return CURLE_SSL_PINNEDPUBKEYNOTMATCH;
+    }
+
+    result = Curl_pin_peer_pubkey(data,
+                                  pinnedpubkey,
+                                  (const unsigned char *)pubkey->header,
+                                  (size_t)(pubkey->end - pubkey->header));
+    if(result) {
+      failf(data, "SSL: public key does not match pinned public key!");
+      return result;
+    }
+#else
+    failf(data, "Library lacks pinning support built-in");
+    return CURLE_NOT_BUILT_IN;
+#endif
+  }
+
+#ifdef HAVE_ALPN
+  if(conn->bits.tls_enable_alpn) {
+    int rc;
+    char *protocol = NULL;
+    unsigned short protocol_len = 0;
+
+    rc = wolfSSL_ALPN_GetProtocol(backend->handle, &protocol, &protocol_len);
+
+    if(rc == SSL_SUCCESS) {
+      infof(data, "ALPN, server accepted to use %.*s\n", protocol_len,
+            protocol);
+
+      if(protocol_len == ALPN_HTTP_1_1_LENGTH &&
+         !memcmp(protocol, ALPN_HTTP_1_1, ALPN_HTTP_1_1_LENGTH))
+        conn->negnpn = CURL_HTTP_VERSION_1_1;
+#ifdef USE_NGHTTP2
+      else if(data->set.httpversion >= CURL_HTTP_VERSION_2 &&
+              protocol_len == NGHTTP2_PROTO_VERSION_ID_LEN &&
+              !memcmp(protocol, NGHTTP2_PROTO_VERSION_ID,
+                      NGHTTP2_PROTO_VERSION_ID_LEN))
+        conn->negnpn = CURL_HTTP_VERSION_2;
+#endif
+      else
+        infof(data, "ALPN, unrecognized protocol %.*s\n", protocol_len,
+              protocol);
+      Curl_multiuse_state(conn, conn->negnpn == CURL_HTTP_VERSION_2 ?
+                          BUNDLE_MULTIPLEX : BUNDLE_NO_MULTIUSE);
+    }
+    else if(rc == SSL_ALPN_NOT_FOUND)
+      infof(data, "ALPN, server did not agree to a protocol\n");
+    else {
+      failf(data, "ALPN, failure getting protocol, error %d", rc);
+      return CURLE_SSL_CONNECT_ERROR;
+    }
+  }
+#endif /* HAVE_ALPN */
+
+  connssl->connecting_state = ssl_connect_3;
+#if (LIBWOLFSSL_VERSION_HEX >= 0x03009010)
+  infof(data, "SSL connection using %s / %s\n",
+        wolfSSL_get_version(backend->handle),
+        wolfSSL_get_cipher_name(backend->handle));
+#else
+  infof(data, "SSL connected\n");
+#endif
+
+  return CURLE_OK;
+}
+
+
+static CURLcode
+wolfssl_connect_step3(struct connectdata *conn,
+                     int sockindex)
+{
+  CURLcode result = CURLE_OK;
+  struct Curl_easy *data = conn->data;
+  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+  struct ssl_backend_data *backend = connssl->backend;
+
+  DEBUGASSERT(ssl_connect_3 == connssl->connecting_state);
+
+  if(SSL_SET_OPTION(primary.sessionid)) {
+    bool incache;
+    SSL_SESSION *our_ssl_sessionid;
+    void *old_ssl_sessionid = NULL;
+
+    our_ssl_sessionid = SSL_get_session(backend->handle);
+
+    Curl_ssl_sessionid_lock(conn);
+    incache = !(Curl_ssl_getsessionid(conn, &old_ssl_sessionid, NULL,
+                                      sockindex));
+    if(incache) {
+      if(old_ssl_sessionid != our_ssl_sessionid) {
+        infof(data, "old SSL session ID is stale, removing\n");
+        Curl_ssl_delsessionid(conn, old_ssl_sessionid);
+        incache = FALSE;
+      }
+    }
+
+    if(!incache) {
+      result = Curl_ssl_addsessionid(conn, our_ssl_sessionid,
+                                     0 /* unknown size */, sockindex);
+      if(result) {
+        Curl_ssl_sessionid_unlock(conn);
+        failf(data, "failed to store ssl session");
+        return result;
+      }
+    }
+    Curl_ssl_sessionid_unlock(conn);
+  }
+
+  connssl->connecting_state = ssl_connect_done;
+
+  return result;
+}
+
+
+static ssize_t wolfssl_send(struct connectdata *conn,
+                           int sockindex,
+                           const void *mem,
+                           size_t len,
+                           CURLcode *curlcode)
+{
+  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+  struct ssl_backend_data *backend = connssl->backend;
+  char error_buffer[WOLFSSL_MAX_ERROR_SZ];
+  int memlen = (len > (size_t)INT_MAX) ? INT_MAX : (int)len;
+  int rc = SSL_write(backend->handle, mem, memlen);
+
+  if(rc < 0) {
+    int err = SSL_get_error(backend->handle, rc);
+
+    switch(err) {
+    case SSL_ERROR_WANT_READ:
+    case SSL_ERROR_WANT_WRITE:
+      /* there's data pending, re-invoke SSL_write() */
+      *curlcode = CURLE_AGAIN;
+      return -1;
+    default:
+      failf(conn->data, "SSL write: %s, errno %d",
+            ERR_error_string(err, error_buffer),
+            SOCKERRNO);
+      *curlcode = CURLE_SEND_ERROR;
+      return -1;
+    }
+  }
+  return rc;
+}
+
+static void Curl_wolfssl_close(struct connectdata *conn, int sockindex)
+{
+  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+  struct ssl_backend_data *backend = connssl->backend;
+
+  if(backend->handle) {
+    (void)SSL_shutdown(backend->handle);
+    SSL_free(backend->handle);
+    backend->handle = NULL;
+  }
+  if(backend->ctx) {
+    SSL_CTX_free(backend->ctx);
+    backend->ctx = NULL;
+  }
+}
+
+static ssize_t wolfssl_recv(struct connectdata *conn,
+                            int num,
+                            char *buf,
+                            size_t buffersize,
+                            CURLcode *curlcode)
+{
+  struct ssl_connect_data *connssl = &conn->ssl[num];
+  struct ssl_backend_data *backend = connssl->backend;
+  char error_buffer[WOLFSSL_MAX_ERROR_SZ];
+  int buffsize = (buffersize > (size_t)INT_MAX) ? INT_MAX : (int)buffersize;
+  int nread = SSL_read(backend->handle, buf, buffsize);
+
+  if(nread < 0) {
+    int err = SSL_get_error(backend->handle, nread);
+
+    switch(err) {
+    case SSL_ERROR_ZERO_RETURN: /* no more data */
+      break;
+    case SSL_ERROR_WANT_READ:
+    case SSL_ERROR_WANT_WRITE:
+      /* there's data pending, re-invoke SSL_read() */
+      *curlcode = CURLE_AGAIN;
+      return -1;
+    default:
+      failf(conn->data, "SSL read: %s, errno %d",
+            ERR_error_string(err, error_buffer),
+            SOCKERRNO);
+      *curlcode = CURLE_RECV_ERROR;
+      return -1;
+    }
+  }
+  return nread;
+}
+
+
+static void Curl_wolfssl_session_free(void *ptr)
+{
+  (void)ptr;
+  /* wolfSSL reuses sessions on own, no free */
+}
+
+
+static size_t Curl_wolfssl_version(char *buffer, size_t size)
+{
+#if LIBWOLFSSL_VERSION_HEX >= 0x03006000
+  return msnprintf(buffer, size, "wolfSSL/%s", wolfSSL_lib_version());
+#elif defined(WOLFSSL_VERSION)
+  return msnprintf(buffer, size, "wolfSSL/%s", WOLFSSL_VERSION);
+#endif
+}
+
+
+static int Curl_wolfssl_init(void)
+{
+#ifdef OPENSSL_EXTRA
+  Curl_tls_keylog_open();
+#endif
+  return (wolfSSL_Init() == SSL_SUCCESS);
+}
+
+
+static void Curl_wolfssl_cleanup(void)
+{
+  wolfSSL_Cleanup();
+#ifdef OPENSSL_EXTRA
+  Curl_tls_keylog_close();
+#endif
+}
+
+
+static bool Curl_wolfssl_data_pending(const struct connectdata *conn,
+                                      int connindex)
+{
+  const struct ssl_connect_data *connssl = &conn->ssl[connindex];
+  struct ssl_backend_data *backend = connssl->backend;
+  if(backend->handle)   /* SSL is in use */
+    return (0 != SSL_pending(backend->handle)) ? TRUE : FALSE;
+  else
+    return FALSE;
+}
+
+
+/*
+ * This function is called to shut down the SSL layer but keep the
+ * socket open (CCC - Clear Command Channel)
+ */
+static int Curl_wolfssl_shutdown(struct connectdata *conn, int sockindex)
+{
+  int retval = 0;
+  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+  struct ssl_backend_data *backend = connssl->backend;
+
+  if(backend->handle) {
+    SSL_free(backend->handle);
+    backend->handle = NULL;
+  }
+  return retval;
+}
+
+
+static CURLcode
+wolfssl_connect_common(struct connectdata *conn,
+                      int sockindex,
+                      bool nonblocking,
+                      bool *done)
+{
+  CURLcode result;
+  struct Curl_easy *data = conn->data;
+  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+  curl_socket_t sockfd = conn->sock[sockindex];
+  int what;
+
+  /* check if the connection has already been established */
+  if(ssl_connection_complete == connssl->state) {
+    *done = TRUE;
+    return CURLE_OK;
+  }
+
+  if(ssl_connect_1 == connssl->connecting_state) {
+    /* Find out how much more time we're allowed */
+    const timediff_t timeout_ms = Curl_timeleft(data, NULL, TRUE);
+
+    if(timeout_ms < 0) {
+      /* no need to continue if time already is up */
+      failf(data, "SSL connection timeout");
+      return CURLE_OPERATION_TIMEDOUT;
+    }
+
+    result = wolfssl_connect_step1(conn, sockindex);
+    if(result)
+      return result;
+  }
+
+  while(ssl_connect_2 == connssl->connecting_state ||
+        ssl_connect_2_reading == connssl->connecting_state ||
+        ssl_connect_2_writing == connssl->connecting_state) {
+
+    /* check allowed time left */
+    const timediff_t timeout_ms = Curl_timeleft(data, NULL, TRUE);
+
+    if(timeout_ms < 0) {
+      /* no need to continue if time already is up */
+      failf(data, "SSL connection timeout");
+      return CURLE_OPERATION_TIMEDOUT;
+    }
+
+    /* if ssl is expecting something, check if it's available. */
+    if(connssl->connecting_state == ssl_connect_2_reading
+       || connssl->connecting_state == ssl_connect_2_writing) {
+
+      curl_socket_t writefd = ssl_connect_2_writing ==
+        connssl->connecting_state?sockfd:CURL_SOCKET_BAD;
+      curl_socket_t readfd = ssl_connect_2_reading ==
+        connssl->connecting_state?sockfd:CURL_SOCKET_BAD;
+
+      what = Curl_socket_check(readfd, CURL_SOCKET_BAD, writefd,
+                               nonblocking?0:timeout_ms);
+      if(what < 0) {
+        /* fatal error */
+        failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO);
+        return CURLE_SSL_CONNECT_ERROR;
+      }
+      else if(0 == what) {
+        if(nonblocking) {
+          *done = FALSE;
+          return CURLE_OK;
+        }
+        else {
+          /* timeout */
+          failf(data, "SSL connection timeout");
+          return CURLE_OPERATION_TIMEDOUT;
+        }
+      }
+      /* socket is readable or writable */
+    }
+
+    /* Run transaction, and return to the caller if it failed or if
+     * this connection is part of a multi handle and this loop would
+     * execute again. This permits the owner of a multi handle to
+     * abort a connection attempt before step2 has completed while
+     * ensuring that a client using select() or epoll() will always
+     * have a valid fdset to wait on.
+     */
+    result = wolfssl_connect_step2(conn, sockindex);
+    if(result || (nonblocking &&
+                  (ssl_connect_2 == connssl->connecting_state ||
+                   ssl_connect_2_reading == connssl->connecting_state ||
+                   ssl_connect_2_writing == connssl->connecting_state)))
+      return result;
+  } /* repeat step2 until all transactions are done. */
+
+  if(ssl_connect_3 == connssl->connecting_state) {
+    result = wolfssl_connect_step3(conn, sockindex);
+    if(result)
+      return result;
+  }
+
+  if(ssl_connect_done == connssl->connecting_state) {
+    connssl->state = ssl_connection_complete;
+    conn->recv[sockindex] = wolfssl_recv;
+    conn->send[sockindex] = wolfssl_send;
+    *done = TRUE;
+  }
+  else
+    *done = FALSE;
+
+  /* Reset our connect state machine */
+  connssl->connecting_state = ssl_connect_1;
+
+  return CURLE_OK;
+}
+
+
+static CURLcode Curl_wolfssl_connect_nonblocking(struct connectdata *conn,
+                                                int sockindex, bool *done)
+{
+  return wolfssl_connect_common(conn, sockindex, TRUE, done);
+}
+
+
+static CURLcode Curl_wolfssl_connect(struct connectdata *conn, int sockindex)
+{
+  CURLcode result;
+  bool done = FALSE;
+
+  result = wolfssl_connect_common(conn, sockindex, FALSE, &done);
+  if(result)
+    return result;
+
+  DEBUGASSERT(done);
+
+  return CURLE_OK;
+}
+
+static CURLcode Curl_wolfssl_random(struct Curl_easy *data,
+                                   unsigned char *entropy, size_t length)
+{
+  WC_RNG rng;
+  (void)data;
+  if(wc_InitRng(&rng))
+    return CURLE_FAILED_INIT;
+  if(length > UINT_MAX)
+    return CURLE_FAILED_INIT;
+  if(wc_RNG_GenerateBlock(&rng, entropy, (unsigned)length))
+    return CURLE_FAILED_INIT;
+  if(wc_FreeRng(&rng))
+    return CURLE_FAILED_INIT;
+  return CURLE_OK;
+}
+
+static CURLcode Curl_wolfssl_sha256sum(const unsigned char *tmp, /* input */
+                                       size_t tmplen,
+                                       unsigned char *sha256sum /* output */,
+                                       size_t unused)
+{
+  wc_Sha256 SHA256pw;
+  (void)unused;
+  wc_InitSha256(&SHA256pw);
+  wc_Sha256Update(&SHA256pw, tmp, (word32)tmplen);
+  wc_Sha256Final(&SHA256pw, sha256sum);
+  return CURLE_OK;
+}
+
+static void *Curl_wolfssl_get_internals(struct ssl_connect_data *connssl,
+                                        CURLINFO info UNUSED_PARAM)
+{
+  struct ssl_backend_data *backend = connssl->backend;
+  (void)info;
+  return backend->handle;
+}
+
+const struct Curl_ssl Curl_ssl_wolfssl = {
+  { CURLSSLBACKEND_WOLFSSL, "WolfSSL" }, /* info */
+
+#ifdef KEEP_PEER_CERT
+  SSLSUPP_PINNEDPUBKEY |
+#endif
+  SSLSUPP_SSL_CTX,
+
+  sizeof(struct ssl_backend_data),
+
+  Curl_wolfssl_init,                /* init */
+  Curl_wolfssl_cleanup,             /* cleanup */
+  Curl_wolfssl_version,             /* version */
+  Curl_none_check_cxn,             /* check_cxn */
+  Curl_wolfssl_shutdown,            /* shutdown */
+  Curl_wolfssl_data_pending,        /* data_pending */
+  Curl_wolfssl_random,              /* random */
+  Curl_none_cert_status_request,   /* cert_status_request */
+  Curl_wolfssl_connect,             /* connect */
+  Curl_wolfssl_connect_nonblocking, /* connect_nonblocking */
+  Curl_wolfssl_get_internals,       /* get_internals */
+  Curl_wolfssl_close,               /* close_one */
+  Curl_none_close_all,             /* close_all */
+  Curl_wolfssl_session_free,        /* session_free */
+  Curl_none_set_engine,            /* set_engine */
+  Curl_none_set_engine_default,    /* set_engine_default */
+  Curl_none_engines_list,          /* engines_list */
+  Curl_none_false_start,           /* false_start */
+  Curl_none_md5sum,                /* md5sum */
+  Curl_wolfssl_sha256sum            /* sha256sum */
+};
+
+#endif
diff --git a/Utilities/cmcurl/lib/vtls/wolfssl.h b/Utilities/cmcurl/lib/vtls/wolfssl.h
new file mode 100644
index 0000000..2b9673c
--- /dev/null
+++ b/Utilities/cmcurl/lib/vtls/wolfssl.h
@@ -0,0 +1,31 @@
+#ifndef HEADER_CURL_WOLFSSL_H
+#define HEADER_CURL_WOLFSSL_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include "curl_setup.h"
+
+#ifdef USE_WOLFSSL
+
+extern const struct Curl_ssl Curl_ssl_wolfssl;
+
+#endif /* USE_WOLFSSL */
+#endif /* HEADER_CURL_WOLFSSL_H */
diff --git a/Utilities/cmcurl/lib/warnless.h b/Utilities/cmcurl/lib/warnless.h
index ea4c439..ab78f94 100644
--- a/Utilities/cmcurl/lib/warnless.h
+++ b/Utilities/cmcurl/lib/warnless.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -94,19 +94,6 @@
 
 unsigned short curlx_ntohs(unsigned short usnum);
 
-#ifndef BUILDING_WARNLESS_C
-#  undef  FD_ISSET
-#  define FD_ISSET(a,b) curlx_FD_ISSET((a),(b))
-#  undef  FD_SET
-#  define FD_SET(a,b)   curlx_FD_SET((a),(b))
-#  undef  FD_ZERO
-#  define FD_ZERO(a)    curlx_FD_ZERO((a))
-#  undef  htons
-#  define htons(a)      curlx_htons((a))
-#  undef  ntohs
-#  define ntohs(a)      curlx_ntohs((a))
-#endif
-
 #endif /* __INTEL_COMPILER && __unix__ */
 
 #endif /* HEADER_CURL_WARNLESS_H */
diff --git a/Utilities/cmcurl/lib/x509asn1.c b/Utilities/cmcurl/lib/x509asn1.c
index 0c1256b..52747d5 100644
--- a/Utilities/cmcurl/lib/x509asn1.c
+++ b/Utilities/cmcurl/lib/x509asn1.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -23,7 +23,7 @@
 #include "curl_setup.h"
 
 #if defined(USE_GSKIT) || defined(USE_NSS) || defined(USE_GNUTLS) || \
-    defined(USE_CYASSL) || defined(USE_SCHANNEL)
+    defined(USE_WOLFSSL) || defined(USE_SCHANNEL)
 
 #include <curl/curl.h>
 #include "urldata.h"
@@ -44,7 +44,7 @@
 static const char       cnOID[] = "2.5.4.3";    /* Common name. */
 static const char       sanOID[] = "2.5.29.17"; /* Subject alternative name. */
 
-static const curl_OID   OIDtable[] = {
+static const struct Curl_OID OIDtable[] = {
   { "1.2.840.10040.4.1",        "dsa" },
   { "1.2.840.10040.4.3",        "dsa-with-sha1" },
   { "1.2.840.10045.2.1",        "ecPublicKey" },
@@ -103,16 +103,16 @@
  * Please note there is no pretention here to rewrite a full SSL library.
  */
 
-static const char *getASN1Element(curl_asn1Element *elem,
+static const char *getASN1Element(struct Curl_asn1Element *elem,
                                   const char *beg, const char *end)
   WARN_UNUSED_RESULT;
 
-static const char *getASN1Element(curl_asn1Element *elem,
+static const char *getASN1Element(struct Curl_asn1Element *elem,
                                   const char *beg, const char *end)
 {
   unsigned char b;
   unsigned long len;
-  curl_asn1Element lelem;
+  struct Curl_asn1Element lelem;
 
   /* Get a single ASN.1 element into `elem', parse ASN.1 string at `beg'
      ending at `end'.
@@ -176,9 +176,9 @@
  * Search the null terminated OID or OID identifier in local table.
  * Return the table entry pointer or NULL if not found.
  */
-static const curl_OID * searchOID(const char *oid)
+static const struct Curl_OID *searchOID(const char *oid)
 {
-  const curl_OID *op;
+  const struct Curl_OID *op;
   for(op = OIDtable; op->numoid; op++)
     if(!strcmp(op->numoid, oid) || strcasecompare(op->textoid, oid))
       return op;
@@ -445,7 +445,7 @@
         buf[buflen] = '\0';
 
         if(symbolic) {
-          const curl_OID *op = searchOID(buf);
+          const struct Curl_OID *op = searchOID(buf);
           if(op) {
             free(buf);
             buf = strdup(op->textoid);
@@ -565,7 +565,7 @@
  * Convert an ASN.1 element to a printable string.
  * Return the dynamically allocated string, or NULL if an error occurs.
  */
-static const char *ASN1tostr(curl_asn1Element *elem, int type)
+static const char *ASN1tostr(struct Curl_asn1Element *elem, int type)
 {
   if(elem->constructed)
     return NULL; /* No conversion of structured elements. */
@@ -609,12 +609,12 @@
  * ASCII encode distinguished name at `dn' into the `buflen'-sized buffer at
  * `buf'.  Return the total string length, even if larger than `buflen'.
  */
-static ssize_t encodeDN(char *buf, size_t buflen, curl_asn1Element *dn)
+static ssize_t encodeDN(char *buf, size_t buflen, struct Curl_asn1Element *dn)
 {
-  curl_asn1Element rdn;
-  curl_asn1Element atv;
-  curl_asn1Element oid;
-  curl_asn1Element value;
+  struct Curl_asn1Element rdn;
+  struct Curl_asn1Element atv;
+  struct Curl_asn1Element oid;
+  struct Curl_asn1Element value;
   size_t l = 0;
   const char *p1;
   const char *p2;
@@ -683,7 +683,7 @@
  * Convert an ASN.1 distinguished name into a printable string.
  * Return the dynamically allocated string, or NULL if an error occurs.
  */
-static const char *DNtostr(curl_asn1Element *dn)
+static const char *DNtostr(struct Curl_asn1Element *dn)
 {
   char *buf = NULL;
   ssize_t buflen = encodeDN(NULL, 0, dn);
@@ -703,11 +703,11 @@
  * Syntax is assumed to have already been checked by the SSL backend.
  * See RFC 5280.
  */
-int Curl_parseX509(curl_X509certificate *cert,
+int Curl_parseX509(struct Curl_X509certificate *cert,
                    const char *beg, const char *end)
 {
-  curl_asn1Element elem;
-  curl_asn1Element tbsCertificate;
+  struct Curl_asn1Element elem;
+  struct Curl_asn1Element tbsCertificate;
   const char *ccp;
   static const char defaultVersion = 0;  /* v1. */
 
@@ -835,10 +835,10 @@
   return i;
 }
 
-static const char *dumpAlgo(curl_asn1Element *param,
+static const char *dumpAlgo(struct Curl_asn1Element *param,
                             const char *beg, const char *end)
 {
-  curl_asn1Element oid;
+  struct Curl_asn1Element oid;
 
   /* Get algorithm parameters and return algorithm name. */
 
@@ -855,7 +855,7 @@
 }
 
 static void do_pubkey_field(struct Curl_easy *data, int certnum,
-                            const char *label, curl_asn1Element *elem)
+                            const char *label, struct Curl_asn1Element *elem)
 {
   const char *output;
 
@@ -872,11 +872,11 @@
 }
 
 static void do_pubkey(struct Curl_easy *data, int certnum,
-                      const char *algo, curl_asn1Element *param,
-                      curl_asn1Element *pubkey)
+                      const char *algo, struct Curl_asn1Element *param,
+                      struct Curl_asn1Element *pubkey)
 {
-  curl_asn1Element elem;
-  curl_asn1Element pk;
+  struct Curl_asn1Element elem;
+  struct Curl_asn1Element pk;
   const char *p;
 
   /* Generate all information records for the public key. */
@@ -950,9 +950,9 @@
                                const char *beg,
                                const char *end)
 {
-  curl_X509certificate cert;
+  struct Curl_X509certificate cert;
   struct Curl_easy *data = conn->data;
-  curl_asn1Element param;
+  struct Curl_asn1Element param;
   const char *ccp;
   char *cp1;
   size_t cl1;
@@ -1104,14 +1104,14 @@
   return CURLE_OK;
 }
 
-#endif /* USE_GSKIT or USE_NSS or USE_GNUTLS or USE_CYASSL or USE_SCHANNEL */
+#endif /* USE_GSKIT or USE_NSS or USE_GNUTLS or USE_WOLFSSL or USE_SCHANNEL */
 
 #if defined(USE_GSKIT)
 
 static const char *checkOID(const char *beg, const char *end,
                             const char *oid)
 {
-  curl_asn1Element e;
+  struct Curl_asn1Element e;
   const char *ccp;
   const char *p;
   bool matched;
@@ -1136,22 +1136,21 @@
                          const char *beg, const char *end)
 {
   struct Curl_easy *data = conn->data;
-  curl_X509certificate cert;
-  curl_asn1Element dn;
-  curl_asn1Element elem;
-  curl_asn1Element ext;
-  curl_asn1Element name;
+  struct Curl_X509certificate cert;
+  struct Curl_asn1Element dn;
+  struct Curl_asn1Element elem;
+  struct Curl_asn1Element ext;
+  struct Curl_asn1Element name;
   const char *p;
   const char *q;
   char *dnsname;
   int matched = -1;
   size_t addrlen = (size_t) -1;
   ssize_t len;
-  const char * const hostname = SSL_IS_PROXY()? conn->http_proxy.host.name:
-                                                conn->host.name;
-  const char * const dispname = SSL_IS_PROXY()?
-                                  conn->http_proxy.host.dispname:
-                                  conn->host.dispname;
+  const char *const hostname = SSL_IS_PROXY()?
+    conn->http_proxy.host.name : conn->host.name;
+  const char *const dispname = SSL_IS_PROXY()?
+    conn->http_proxy.host.dispname : conn->host.dispname;
 #ifdef ENABLE_IPV6
   struct in6_addr addr;
 #else
diff --git a/Utilities/cmcurl/lib/x509asn1.h b/Utilities/cmcurl/lib/x509asn1.h
index ce40297..0b7fb88 100644
--- a/Utilities/cmcurl/lib/x509asn1.h
+++ b/Utilities/cmcurl/lib/x509asn1.h
@@ -8,7 +8,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -26,7 +26,7 @@
 #include "curl_setup.h"
 
 #if defined(USE_GSKIT) || defined(USE_NSS) || defined(USE_GNUTLS) || \
-    defined(USE_CYASSL) || defined(USE_SCHANNEL)
+    defined(USE_WOLFSSL) || defined(USE_SCHANNEL)
 
 #include "urldata.h"
 
@@ -79,56 +79,55 @@
  */
 
 /* ASN.1 parsed element. */
-typedef struct {
-  const char *  header;         /* Pointer to header byte. */
-  const char *  beg;            /* Pointer to element data. */
-  const char *  end;            /* Pointer to 1st byte after element. */
-  unsigned char class;          /* ASN.1 element class. */
-  unsigned char tag;            /* ASN.1 element tag. */
-  bool          constructed;    /* Element is constructed. */
-}  curl_asn1Element;
+struct Curl_asn1Element {
+  const char *header;         /* Pointer to header byte. */
+  const char *beg;            /* Pointer to element data. */
+  const char *end;            /* Pointer to 1st byte after element. */
+  unsigned char class;        /* ASN.1 element class. */
+  unsigned char tag;          /* ASN.1 element tag. */
+  bool          constructed;  /* Element is constructed. */
+};
 
 
 /* ASN.1 OID table entry. */
-typedef struct {
-  const char *  numoid;         /* Dotted-numeric OID. */
-  const char *  textoid;        /* OID name. */
-}  curl_OID;
+struct Curl_OID {
+  const char *numoid;  /* Dotted-numeric OID. */
+  const char *textoid; /* OID name. */
+};
 
 
 /* X509 certificate: RFC 5280. */
-typedef struct {
-  curl_asn1Element      certificate;
-  curl_asn1Element      version;
-  curl_asn1Element      serialNumber;
-  curl_asn1Element      signatureAlgorithm;
-  curl_asn1Element      signature;
-  curl_asn1Element      issuer;
-  curl_asn1Element      notBefore;
-  curl_asn1Element      notAfter;
-  curl_asn1Element      subject;
-  curl_asn1Element      subjectPublicKeyInfo;
-  curl_asn1Element      subjectPublicKeyAlgorithm;
-  curl_asn1Element      subjectPublicKey;
-  curl_asn1Element      issuerUniqueID;
-  curl_asn1Element      subjectUniqueID;
-  curl_asn1Element      extensions;
-}  curl_X509certificate;
-
+struct Curl_X509certificate {
+  struct Curl_asn1Element certificate;
+  struct Curl_asn1Element version;
+  struct Curl_asn1Element serialNumber;
+  struct Curl_asn1Element signatureAlgorithm;
+  struct Curl_asn1Element signature;
+  struct Curl_asn1Element issuer;
+  struct Curl_asn1Element notBefore;
+  struct Curl_asn1Element notAfter;
+  struct Curl_asn1Element subject;
+  struct Curl_asn1Element subjectPublicKeyInfo;
+  struct Curl_asn1Element subjectPublicKeyAlgorithm;
+  struct Curl_asn1Element subjectPublicKey;
+  struct Curl_asn1Element issuerUniqueID;
+  struct Curl_asn1Element subjectUniqueID;
+  struct Curl_asn1Element extensions;
+};
 
 /*
  * Prototypes.
  */
 
-const char *Curl_getASN1Element(curl_asn1Element *elem,
-                                 const char *beg, const char *end);
-const char *Curl_ASN1tostr(curl_asn1Element *elem, int type);
-const char *Curl_DNtostr(curl_asn1Element *dn);
-int Curl_parseX509(curl_X509certificate *cert,
+const char *Curl_getASN1Element(struct Curl_asn1Element *elem,
+                                const char *beg, const char *end);
+const char *Curl_ASN1tostr(struct Curl_asn1Element *elem, int type);
+const char *Curl_DNtostr(struct Curl_asn1Element *dn);
+int Curl_parseX509(struct Curl_X509certificate *cert,
                    const char *beg, const char *end);
 CURLcode Curl_extract_certinfo(struct connectdata *conn, int certnum,
                                const char *beg, const char *end);
 CURLcode Curl_verifyhost(struct connectdata *conn,
                          const char *beg, const char *end);
-#endif /* USE_GSKIT or USE_NSS or USE_GNUTLS or USE_CYASSL or USE_SCHANNEL */
+#endif /* USE_GSKIT or USE_NSS or USE_GNUTLS or USE_WOLFSSL or USE_SCHANNEL */
 #endif /* HEADER_CURL_X509ASN1_H */
diff --git a/Utilities/cmexpat/ConfigureChecks.cmake b/Utilities/cmexpat/ConfigureChecks.cmake
index d85e48c..4da252c 100644
--- a/Utilities/cmexpat/ConfigureChecks.cmake
+++ b/Utilities/cmexpat/ConfigureChecks.cmake
@@ -44,14 +44,6 @@
     set(BYTEORDER 1234)
 endif(WORDS_BIGENDIAN)
 
-if(HAVE_SYS_TYPES_H)
-    check_symbol_exists("off_t" "sys/types.h" OFF_T)
-    check_symbol_exists("size_t" "sys/types.h" SIZE_T)
-else(HAVE_SYS_TYPES_H)
-    set(OFF_T "long")
-    set(SIZE_T "unsigned")
-endif(HAVE_SYS_TYPES_H)
-
 check_c_source_compiles("
         #include <stdlib.h>  /* for NULL */
         #include <unistd.h>  /* for syscall */
@@ -61,6 +53,3 @@
             return 0;
         }"
     HAVE_SYSCALL_GETRANDOM)
-
-check_c_compiler_flag("-fno-strict-aliasing" FLAG_NO_STRICT_ALIASING)
-check_c_compiler_flag("-fvisibility=hidden" FLAG_VISIBILITY)
diff --git a/Utilities/cmexpat/expat_config.h.cmake b/Utilities/cmexpat/expat_config.h.cmake
index 795b607..e91861e 100644
--- a/Utilities/cmexpat/expat_config.h.cmake
+++ b/Utilities/cmexpat/expat_config.h.cmake
@@ -86,9 +86,3 @@
 #ifdef _MSC_VER
 #  define __func__ __FUNCTION__
 #endif
-
-/* Define to `long' if <sys/types.h> does not define. */
-#cmakedefine off_t @OFF_T@
-
-/* Define to `unsigned' if <sys/types.h> does not define. */
-#cmakedefine size_t @SIZE_T@
diff --git a/Utilities/cmexpat/lib/siphash.h b/Utilities/cmexpat/lib/siphash.h
index 95f78f8..a335ec0 100644
--- a/Utilities/cmexpat/lib/siphash.h
+++ b/Utilities/cmexpat/lib/siphash.h
@@ -97,7 +97,7 @@
 
 #include <stddef.h> /* size_t */
 
-#include <cm_kwiml.h>
+#include <cm3p/kwiml/int.h>
 
 #ifndef KWIML_INT_HAVE_UINT64_T
 # define uint64_t KWIML_INT_uint64_t
diff --git a/Utilities/cmlibarchive/CMakeLists.txt b/Utilities/cmlibarchive/CMakeLists.txt
index 26a9aa9..bfcaf30 100644
--- a/Utilities/cmlibarchive/CMakeLists.txt
+++ b/Utilities/cmlibarchive/CMakeLists.txt
@@ -1,9 +1,43 @@
+#
+IF(0) # CMake handles policy settings in its own build.
+CMAKE_MINIMUM_REQUIRED(VERSION 2.8.12 FATAL_ERROR)
+if(POLICY CMP0074)
+  cmake_policy(SET CMP0074 NEW) #3.12.0 `find_package()`` uses ``<PackageName>_ROOT`` variables.
+endif()
+ENDIF()
+#
 PROJECT(libarchive C)
 #
 SET(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/build/cmake")
 if(NOT CMAKE_RUNTIME_OUTPUT_DIRECTORY)
   set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${libarchive_BINARY_DIR}/bin)
 endif()
+IF(0) # CMake handles build type selection in its own build.
+#
+# Set the Build type for make based generators.
+# You can choose following types:
+#   Debug          : Debug build
+#   Release        : Release build
+#   RelWithDebInfo : Release build with Debug Info
+#   MinSizeRel     : Release Min Size build
+IF(NOT CMAKE_BUILD_TYPE)
+  SET(CMAKE_BUILD_TYPE "Release" CACHE STRING "Build Type" FORCE)
+ENDIF(NOT CMAKE_BUILD_TYPE)
+# Set a value type to properly display CMAKE_BUILD_TYPE on GUI if the
+# value type is "UNINITIALIZED".
+GET_PROPERTY(cached_type CACHE CMAKE_BUILD_TYPE PROPERTY TYPE)
+IF("${cached_type}" STREQUAL "UNINITIALIZED")
+  SET(CMAKE_BUILD_TYPE "${CMAKE_BUILD_TYPE}" CACHE STRING "Build Type" FORCE)
+ENDIF("${cached_type}" STREQUAL "UNINITIALIZED")
+# Check the Build Type.
+IF(NOT "${CMAKE_BUILD_TYPE}"
+       MATCHES "^(Debug|Release|RelWithDebInfo|MinSizeRel)\$")
+  MESSAGE(FATAL_ERROR
+          "Unknown keyword for CMAKE_BUILD_TYPE: ${CMAKE_BUILD_TYPE}\n"
+          "Acceptable keywords: Debug,Release,RelWithDebInfo,MinSizeRel")
+ENDIF(NOT "${CMAKE_BUILD_TYPE}"
+          MATCHES "^(Debug|Release|RelWithDebInfo|MinSizeRel)\$")
+ENDIF()
 
 # On MacOS, prefer MacPorts libraries to system libraries.
 # I haven't come up with a compelling argument for this to be conditional.
@@ -66,14 +100,122 @@
   SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -woffall")
 ENDIF()
 
+IF(0) # CMake does not need flags specific to libarchive upstream development.
+if (CMAKE_BUILD_TYPE STREQUAL "Debug")
+  OPTION(ENABLE_WERROR "Treat warnings as errors - default is ON for Debug, OFF otherwise." ON)
+else ()
+  OPTION(ENABLE_WERROR "Treat warnings as errors - default is ON for Debug, OFF otherwise." OFF)
+endif ()
+
+# Especially for early development, we want to be a little
+# aggressive about diagnosing build problems; this can get
+# relaxed somewhat in final shipping versions.
+IF (CMAKE_C_COMPILER_ID MATCHES "^GNU$")
+  SET(CMAKE_REQUIRED_FLAGS "-Wall -Wformat -Wformat-security")
+  #################################################################
+  # Set compile flags for all build types.
+  SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wformat -Wformat-security")
+  if (ENABLE_WERROR)
+    SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Werror")
+  endif ()
+  #################################################################
+  # Set compile flags for debug build.
+  # This is added into CMAKE_C_FLAGS when CMAKE_BUILD_TYPE is "Debug"
+  SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -Wextra")
+  SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -Wunused")
+  SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -Wshadow")
+  SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -Wmissing-prototypes")
+  SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -Wcast-qual")
+ENDIF (CMAKE_C_COMPILER_ID MATCHES "^GNU$")
+IF (CMAKE_C_COMPILER_ID MATCHES "^Clang$")
+  SET(CMAKE_REQUIRED_FLAGS "-Wall -Wformat -Wformat-security")
+  #################################################################
+  # Set compile flags for all build types.
+  SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wformat -Wformat-security")
+  if (ENABLE_WERROR)
+    SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Werror")
+  endif ()
+  #################################################################
+  # Set compile flags for debug build.
+  # This is added into CMAKE_C_FLAGS when CMAKE_BUILD_TYPE is "Debug"
+  SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -g")
+  SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -Wextra")
+  SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -Wunused")
+  SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -Wshadow")
+  SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -Wmissing-prototypes")
+  SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -Wcast-qual")
+ENDIF (CMAKE_C_COMPILER_ID MATCHES "^Clang$")
+IF (CMAKE_C_COMPILER_ID MATCHES "^XL$")
+  SET(CMAKE_C_COMPILER "xlc_r")
+  SET(CMAKE_REQUIRED_FLAGS "-qflag=e:e -qformat=sec")
+  #################################################################
+  # Set compile flags for all build types.
+  SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -qflag=e:e -qformat=sec")
+  if (ENABLE_WERROR)
+    SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -qhalt=w")
+  endif ()
+  #################################################################
+  # Set compile flags for debug build.
+  # This is added into CMAKE_C_FLAGS when CMAKE_BUILD_TYPE is "Debug"
+  SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -g")
+  SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -qflag=w:w")
+  SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -qinfo=pro:use")
+ENDIF(CMAKE_C_COMPILER_ID MATCHES "^XL$")
+IF (MSVC)
+  if (ENABLE_WERROR)
+    # /WX option is the same as gcc's -Werror option.
+    SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /WX")
+  endif ()
+  #################################################################
+  # Set compile flags for debug build.
+  # This is added into CMAKE_C_FLAGS when CMAKE_BUILD_TYPE is "Debug"
+  # Enable level 4 C4062: The enumerate has no associated handler in a switch
+  #                       statement and there is no default that can catch it.
+  SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} /we4062")
+  # Enable level 4 C4254: A larger bit field was assigned to a smaller bit
+  #                       field.
+  SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} /we4254")
+  # Enable level 4 C4295: An array was initialized but the last character in
+  #                       the array is not a null; accessing the array may
+  #                       produce unexpected results.
+  SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} /we4295")
+  # Enable level 4 C4296: An unsigned variable was used in a comparison
+  #                       operation with zero.
+  SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} /we4296")
+  # Enable level 4 C4389: An operation involved signed and unsigned variables.
+  #                       This could result in a loss of data.
+  SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} /we4389")
+  # Enable level 4 C4505: The given function is local and not referenced in
+  #                       the body of the module; therefore, the function is
+  #                       dead code.
+  SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} /we4505")
+  # Enable level 4 C4514: The optimizer removed an inline function that is not
+  #                       called.
+  SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} /we4514")
+  # Enable level 4 C4702: Unreachable code.
+  SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} /we4702")
+  # Enable level 4 C4706: The test value in a conditional expression was the
+  #                       result of an assignment.
+  SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} /we4706")
+  # /Oi option enables built-in functions.
+  SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} /Oi")
+  #################################################################
+  # Set compile flags for release build.
+  SET(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} /Oi")
+ENDIF (MSVC)
+ENDIF()
+
 # Enable CTest/CDash support
 include(CTest)
 
-OPTION(ENABLE_NETTLE "Enable use of Nettle" ON)
+OPTION(ENABLE_MBEDTLS "Enable use of mbed TLS" OFF)
+OPTION(ENABLE_NETTLE "Enable use of Nettle" OFF)
 OPTION(ENABLE_OPENSSL "Enable use of OpenSSL" ON)
+OPTION(ENABLE_LIBB2 "Enable the use of the system LIBB2 library if found" ON)
 OPTION(ENABLE_LZ4 "Enable the use of the system LZ4 library if found" ON)
 OPTION(ENABLE_LZO "Enable the use of the system LZO library if found" OFF)
 OPTION(ENABLE_LZMA "Enable the use of the system LZMA library if found" ON)
+OPTION(ENABLE_ZSTD "Enable the use of the system zstd library if found" ON)
 
 OPTION(ENABLE_ZLIB "Enable the use of the system ZLIB library if found" ON)
 OPTION(ENABLE_BZip2 "Enable the use of the system BZip2 library if found" ON)
@@ -84,23 +226,98 @@
 # CNG is used for encrypt/decrypt Zip archives on Windows.
 OPTION(ENABLE_CNG "Enable the use of CNG(Crypto Next Generation)" ON)
 
+IF(0) # CMake does not build libarchive's command-line tools.
+OPTION(ENABLE_TAR "Enable tar building" ON)
+OPTION(ENABLE_TAR_SHARED "Enable dynamic build of tar" FALSE)
+OPTION(ENABLE_CPIO "Enable cpio building" ON)
+OPTION(ENABLE_CPIO_SHARED "Enable dynamic build of cpio" FALSE)
+OPTION(ENABLE_CAT "Enable cat building" ON)
+OPTION(ENABLE_CAT_SHARED "Enable dynamic build of cat" FALSE)
+ENDIF()
 OPTION(ENABLE_XATTR "Enable extended attribute support" ON)
 OPTION(ENABLE_ACL "Enable ACL support" ON)
 OPTION(ENABLE_ICONV "Enable iconv support" ON)
+IF(0) # CMake does not build libarchive's tests.
+OPTION(ENABLE_TEST "Enable unit and regression tests" ON)
+OPTION(ENABLE_COVERAGE "Enable code coverage (GCC only, automatically sets ENABLE_TEST to ON)" FALSE)
+OPTION(ENABLE_INSTALL "Enable installing of libraries" ON)
+
+SET(POSIX_REGEX_LIB "AUTO" CACHE STRING "Choose what library should provide POSIX regular expression support")
+SET(ENABLE_SAFESEH "AUTO" CACHE STRING "Enable use of /SAFESEH linker flag (MSVC only)")
+SET(WINDOWS_VERSION "WIN7" CACHE STRING "Set Windows version to use (Windows only)")
+
+IF(ENABLE_COVERAGE)
+       include(LibarchiveCodeCoverage)
+ENDIF(ENABLE_COVERAGE)
+
+IF(ENABLE_TEST)
+       ENABLE_TESTING()
+ENDIF(ENABLE_TEST)
+ENDIF()
 
 IF(WIN32)
-  #ELSEIF(WINDOWS_VERSION STREQUAL "WINXP")
   SET(NTDDI_VERSION 0x05010000)
   SET(_WIN32_WINNT 0x0501)
   SET(WINVER 0x0501)
 ENDIF(WIN32)
 
-set(HAVE_PTHREAD_H 0) # no threads in CMake
+IF(0) # CMake hard-codes its own supported version of Windows.
+IF(WIN32)
+  IF(WINDOWS_VERSION STREQUAL "WIN8")
+    SET(NTDDI_VERSION 0x06020000)
+    SET(_WIN32_WINNT 0x0602)
+    SET(WINVER 0x0602)
+  ELSEIF(WINDOWS_VERSION STREQUAL "WIN7")
+    SET(NTDDI_VERSION 0x06010000)
+    SET(_WIN32_WINNT 0x0601)
+    SET(WINVER 0x0601)
+  ELSEIF(WINDOWS_VERSION STREQUAL "WS08")
+    SET(NTDDI_VERSION 0x06000100)
+    SET(_WIN32_WINNT 0x0600)
+    SET(WINVER 0x0600)
+  ELSEIF(WINDOWS_VERSION STREQUAL "VISTA")
+    SET(NTDDI_VERSION 0x06000000)
+    SET(_WIN32_WINNT 0x0600)
+    SET(WINVER 0x0600)
+  ELSEIF(WINDOWS_VERSION STREQUAL "WS03")
+    SET(NTDDI_VERSION 0x05020000)
+    SET(_WIN32_WINNT 0x0502)
+    SET(WINVER 0x0502)
+  ELSEIF(WINDOWS_VERSION STREQUAL "WINXP")
+    SET(NTDDI_VERSION 0x05010000)
+    SET(_WIN32_WINNT 0x0501)
+    SET(WINVER 0x0501)
+  ELSE(WINDOWS_VERSION STREQUAL "WIN8")
+    # Default to Windows Server 2003 API if we don't recognize the specifier
+    SET(NTDDI_VERSION 0x05020000)
+    SET(_WIN32_WINNT 0x0502)
+    SET(WINVER 0x0502)
+  ENDIF(WINDOWS_VERSION STREQUAL "WIN8")
+ENDIF(WIN32)
+
+IF(MSVC)
+  IF(ENABLE_SAFESEH STREQUAL "YES")
+    SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /SAFESEH")
+    SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} /SAFESEH")
+    SET(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} /SAFESEH")
+    SET(ENV{LDFLAGS} "$ENV{LDFLAGS} /SAFESEH")
+  ELSEIF(ENABLE_SAFESEH STREQUAL "NO")
+    SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /SAFESEH:NO")
+    SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} /SAFESEH:NO")
+    SET(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} /SAFESEH:NO")
+    SET(ENV{LDFLAGS} "$ENV{LDFLAGS} /SAFESEH:NO")
+  ENDIF(ENABLE_SAFESEH STREQUAL "YES")
+ENDIF(MSVC)
+ENDIF()
 
 IF("${CMAKE_C_PLATFORM_ID}" MATCHES "^(HP-UX)$")
   ADD_DEFINITIONS(-D_XOPEN_SOURCE=500) # Ask wchar.h for mbstate_t
 ENDIF()
 
+IF(MINGW)
+  ADD_DEFINITIONS(-D__USE_MINGW_ANSI_STDIO)
+ENDIF()
+
 #
 INCLUDE(CheckCSourceCompiles)
 INCLUDE(CheckCSourceRuns)
@@ -280,7 +497,6 @@
     ADD_DEFINITIONS(-DUSE_BZIP2_STATIC)
   ENDIF(USE_BZIP2_DLL)
 ENDIF(BZIP2_FOUND)
-MARK_AS_ADVANCED(CLEAR BZIP2_INCLUDE_DIR)
 
 
 #
@@ -289,12 +505,15 @@
 IF(ENABLE_LZMA)
   FIND_PACKAGE(LibLZMA)
 ELSE()
-  SET(LIBZMA_FOUND FALSE) # Override cached value
+  SET(LIBLZMA_FOUND FALSE) # Override cached value
 ENDIF()
 
 IF(LIBLZMA_FOUND)
   SET(HAVE_LIBLZMA 1)
   SET(HAVE_LZMA_H 1)
+  CMAKE_PUSH_CHECK_STATE()
+  SET(CMAKE_REQUIRED_INCLUDES ${LIBLZMA_INCLUDE_DIR})
+  SET(CMAKE_REQUIRED_LIBRARIES ${LIBLZMA_LIBRARIES})
   INCLUDE_DIRECTORIES(${LIBLZMA_INCLUDE_DIRS})
   LIST(APPEND ADDITIONAL_LIBS ${LIBLZMA_LIBRARIES})
   IF(CMAKE_USE_SYSTEM_LIBLZMA)
@@ -310,10 +529,10 @@
   ELSE()
     ADD_DEFINITIONS(-DLZMA_API_STATIC)
   ENDIF()
+  CMAKE_POP_CHECK_STATE()
 ELSE(LIBLZMA_FOUND)
 # LZMA not found and will not be used.
 ENDIF(LIBLZMA_FOUND)
-IF(0) # CMake does not need LZO2 support in libarchive
 #
 # Find LZO2
 #
@@ -340,10 +559,35 @@
   # TODO: test for static library.
   #
 ENDIF(LZO2_FOUND)
-MARK_AS_ADVANCED(CLEAR LZO2_INCLUDE_DIR)
-MARK_AS_ADVANCED(CLEAR LZO2_LIBRARY)
-ENDIF()
-IF(0) # CMake does not need LZ4 support in libarchive
+#
+# Find libb2
+#
+IF(ENABLE_LIBB2)
+  IF (LIBB2_INCLUDE_DIR)
+    # Already in cache, be silent
+    SET(LIBB2_FIND_QUIETLY TRUE)
+  ENDIF (LIBB2_INCLUDE_DIR)
+
+  FIND_PATH(LIBB2_INCLUDE_DIR blake2.h)
+  FIND_LIBRARY(LIBB2_LIBRARY NAMES b2 libb2)
+  INCLUDE(FindPackageHandleStandardArgs)
+  FIND_PACKAGE_HANDLE_STANDARD_ARGS(LIBB2 DEFAULT_MSG LIBB2_LIBRARY LIBB2_INCLUDE_DIR)
+ELSE(ENABLE_LIBB2)
+  SET(LIBB2_FOUND FALSE) # Override cached value
+ENDIF(ENABLE_LIBB2)
+IF(LIBB2_FOUND)
+  SET(HAVE_LIBB2 1)
+  SET(HAVE_BLAKE2_H 1)
+  SET(ARCHIVE_BLAKE2 FALSE)
+  LIST(APPEND ADDITIONAL_LIBS ${LIBB2_LIBRARY})
+  CMAKE_PUSH_CHECK_STATE()
+  SET(CMAKE_REQUIRED_LIBRARIES ${LIBB2_LIBRARY})
+  SET(CMAKE_REQUIRED_INCLUDES ${LIBB2_INCLUDE_DIR})
+  CHECK_FUNCTION_EXISTS(blake2sp_init HAVE_LIBB2)
+  CMAKE_POP_CHECK_STATE()
+ELSE(LIBB2_FOUND)
+  SET(ARCHIVE_BLAKE2 TRUE)
+ENDIF(LIBB2_FOUND)
 #
 # Find LZ4
 #
@@ -373,33 +617,42 @@
   # TODO: test for static library.
   #
 ENDIF(LZ4_FOUND)
-MARK_AS_ADVANCED(CLEAR LZ4_INCLUDE_DIR)
-MARK_AS_ADVANCED(CLEAR LZ4_LIBRARY)
-ENDIF()
 #
 # Find Zstd
 #
-IF (ZSTD_INCLUDE_DIR)
-  # Already in cache, be silent
-  SET(ZSTD_FIND_QUIETLY TRUE)
-ENDIF (ZSTD_INCLUDE_DIR)
+IF(ENABLE_ZSTD)
+  IF (ZSTD_INCLUDE_DIR)
+    # Already in cache, be silent
+    SET(ZSTD_FIND_QUIETLY TRUE)
+  ENDIF (ZSTD_INCLUDE_DIR)
 
-FIND_PATH(ZSTD_INCLUDE_DIR zstd.h)
-FIND_LIBRARY(ZSTD_LIBRARY NAMES zstd libzstd)
-INCLUDE(FindPackageHandleStandardArgs)
-FIND_PACKAGE_HANDLE_STANDARD_ARGS(ZSTD DEFAULT_MSG ZSTD_LIBRARY ZSTD_INCLUDE_DIR)
+  FIND_PATH(ZSTD_INCLUDE_DIR zstd.h)
+  FIND_LIBRARY(ZSTD_LIBRARY NAMES zstd libzstd)
+  INCLUDE(FindPackageHandleStandardArgs)
+  FIND_PACKAGE_HANDLE_STANDARD_ARGS(ZSTD DEFAULT_MSG ZSTD_LIBRARY ZSTD_INCLUDE_DIR)
+ELSE(ENABLE_ZSTD)
+  SET(ZSTD_FOUND FALSE) # Override cached value
+ENDIF(ENABLE_ZSTD)
 IF(ZSTD_FOUND)
   SET(HAVE_ZSTD_H 1)
   INCLUDE_DIRECTORIES(${ZSTD_INCLUDE_DIR})
   LIST(APPEND ADDITIONAL_LIBS ${ZSTD_LIBRARY})
   SET(HAVE_LIBZSTD 1)
+  IF(0) # CMake expects the zstd library to work.
+  CMAKE_PUSH_CHECK_STATE()
+  SET(CMAKE_REQUIRED_LIBRARIES ${ZSTD_LIBRARY})
+  SET(CMAKE_REQUIRED_INCLUDES ${ZSTD_INCLUDE_DIR})
+  CHECK_FUNCTION_EXISTS(ZSTD_compressStream HAVE_LIBZSTD)
   #
   # TODO: test for static library.
   #
+  CMAKE_POP_CHECK_STATE()
+  ENDIF()
 ENDIF(ZSTD_FOUND)
 MARK_AS_ADVANCED(CLEAR ZSTD_INCLUDE_DIR)
 MARK_AS_ADVANCED(CLEAR ZSTD_LIBRARY)
 
+
 #
 # Check headers
 #
@@ -419,9 +672,11 @@
 # Alphabetize the rest unless there's a compelling reason
 IF(ENABLE_ACL)
   LA_CHECK_INCLUDE_FILE("acl/libacl.h" HAVE_ACL_LIBACL_H)
-ELSE(ENABLE_ACL)
+  LA_CHECK_INCLUDE_FILE("attr/xattr.h" HAVE_ATTR_XATTR_H)
+ELSE()
   SET(HAVE_ACL_LIBACL_H FALSE)
-ENDIF(ENABLE_ACL)
+  SET(HAVE_ATTR_XATTR_H FALSE)
+ENDIF()
 LA_CHECK_INCLUDE_FILE("ctype.h" HAVE_CTYPE_H)
 LA_CHECK_INCLUDE_FILE("copyfile.h" HAVE_COPYFILE_H)
 LA_CHECK_INCLUDE_FILE("direct.h" HAVE_DIRECT_H)
@@ -435,7 +690,6 @@
 
 LA_CHECK_INCLUDE_FILE("fcntl.h" HAVE_FCNTL_H)
 LA_CHECK_INCLUDE_FILE("grp.h" HAVE_GRP_H)
-LA_CHECK_INCLUDE_FILE("inttypes.h" HAVE_INTTYPES_H)
 LA_CHECK_INCLUDE_FILE("io.h" HAVE_IO_H)
 LA_CHECK_INCLUDE_FILE("langinfo.h" HAVE_LANGINFO_H)
 LA_CHECK_INCLUDE_FILE("limits.h" HAVE_LIMITS_H)
@@ -461,7 +715,6 @@
 LA_CHECK_INCLUDE_FILE("signal.h" HAVE_SIGNAL_H)
 LA_CHECK_INCLUDE_FILE("spawn.h" HAVE_SPAWN_H)
 LA_CHECK_INCLUDE_FILE("stdarg.h" HAVE_STDARG_H)
-LA_CHECK_INCLUDE_FILE("stdint.h" HAVE_STDINT_H)
 LA_CHECK_INCLUDE_FILE("stdlib.h" HAVE_STDLIB_H)
 LA_CHECK_INCLUDE_FILE("string.h" HAVE_STRING_H)
 LA_CHECK_INCLUDE_FILE("strings.h" HAVE_STRINGS_H)
@@ -519,6 +772,26 @@
  SAFE_TO_DEFINE_EXTENSIONS)
 
 #
+# Find mbed TLS
+#
+IF(ENABLE_MBEDTLS)
+  FIND_PACKAGE(MbedTLS)
+  IF(MBEDTLS_FOUND)
+    SET(HAVE_LIBMBEDCRYPTO 1)
+    LIST(APPEND ADDITIONAL_LIBS ${MBEDCRYPTO_LIBRARY})
+    INCLUDE_DIRECTORIES(${MBEDTLS_INCLUDE_DIRS})
+
+    LIST(APPEND CMAKE_REQUIRED_INCLUDES ${MBEDTLS_INCLUDE_DIRS})
+    LA_CHECK_INCLUDE_FILE("mbedtls/aes.h" HAVE_MBEDTLS_AES_H)
+    LA_CHECK_INCLUDE_FILE("mbedtls/md.h" HAVE_MBEDTLS_MD_H)
+    LA_CHECK_INCLUDE_FILE("mbedtls/pkcs5.h" HAVE_MBEDTLS_PKCS5_H)
+
+  ENDIF(MBEDTLS_FOUND)
+  MARK_AS_ADVANCED(CLEAR MBEDTLS_INCLUDE_DIRS)
+  MARK_AS_ADVANCED(CLEAR MBEDCRYPTO_LIBRARY)
+ENDIF(ENABLE_MBEDTLS)
+
+#
 # Find Nettle
 #
 IF(ENABLE_NETTLE)
@@ -579,6 +852,8 @@
       STRING(TOUPPER "${ALGORITHM}" algorithm)
       IF ("${IMPLEMENTATION}" MATCHES "^OPENSSL$" AND NOT OPENSSL_FOUND)
         SET(ARCHIVE_CRYPTO_${ALGORITHM}_${IMPLEMENTATION} FALSE)
+      ELSEIF("${IMPLEMENTATION}" MATCHES "^MBEDTLS$" AND NOT MBEDTLS_FOUND)
+        SET(ARCHIVE_CRYPTO_${ALGORITHM}_${IMPLEMENTATION} FALSE)
       ELSEIF("${IMPLEMENTATION}" MATCHES "^NETTLE$" AND NOT NETTLE_FOUND)
         SET(ARCHIVE_CRYPTO_${ALGORITHM}_${IMPLEMENTATION} FALSE)
       ENDIF("${IMPLEMENTATION}" MATCHES "^OPENSSL$" AND NOT OPENSSL_FOUND)
@@ -594,6 +869,11 @@
 	      "${TRY_CRYPTO_REQUIRED_INCLUDES};${OPENSSL_INCLUDE_DIR}")
 	    SET(TRY_CRYPTO_REQUIRED_LIBS
 	        "-DLINK_LIBRARIES:STRING=${OPENSSL_LIBRARIES}")
+	ELSEIF("${IMPLEMENTATION}" MATCHES "^MBEDTLS$" AND MBEDTLS_FOUND)
+	    SET(TRY_CRYPTO_REQUIRED_INCLUDES
+	      "${TRY_CRYPTO_REQUIRED_INCLUDES};${MBEDTLS_INCLUDE_DIRS}")
+	    SET(TRY_CRYPTO_REQUIRED_LIBS
+	      "-DLINK_LIBRARIES:STRING=${MBEDCRYPTO_LIBRARY}")
 	ELSEIF("${IMPLEMENTATION}" MATCHES "^NETTLE$" AND NETTLE_FOUND)
 	    SET(TRY_CRYPTO_REQUIRED_INCLUDES
 	      "${TRY_CRYPTO_REQUIRED_INCLUDES};${NETTLE_INCLUDE_DIR}")
@@ -758,18 +1038,19 @@
 MACRO(CHECK_ICONV LIB TRY_ICONV_CONST)
   IF(NOT HAVE_ICONV)
     CMAKE_PUSH_CHECK_STATE()	# Save the state of the variables
-    IF (CMAKE_C_COMPILER_ID STREQUAL "GNU" OR
-        CMAKE_C_COMPILER_ID STREQUAL "Clang")
+    IF (CMAKE_C_COMPILER_ID MATCHES "^GNU$" OR
+        CMAKE_C_COMPILER_ID MATCHES "^Clang$")
       #
       # During checking iconv proto type, we should use -Werror to avoid the
       # success of iconv detection with a warnig which success is a miss
       # detection. So this needs for all build mode(even it's a release mode).
       #
       SET(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -Werror")
-    ENDIF ()
-    IF (CMAKE_C_COMPILER_ID STREQUAL "XL")
+    ENDIF (CMAKE_C_COMPILER_ID MATCHES "^GNU$" OR
+           CMAKE_C_COMPILER_ID MATCHES "^Clang$")
+    IF (CMAKE_C_COMPILER_ID MATCHES "^XL$")
       SET(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -qhalt=w -qflag=w:w")
-    ENDIF ()
+    ENDIF (CMAKE_C_COMPILER_ID MATCHES "^XL$")
     IF (MSVC)
       # NOTE: /WX option is the same as gcc's -Werror option.
       SET(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} /WX")
@@ -889,7 +1170,6 @@
   UNSET(LIBCHARSET_STATIC CACHE)
 ENDIF(ENABLE_ICONV)
 
-IF(0) # CMake does not need XML support in libarchive
 #
 # Find Libxml2
 #
@@ -936,23 +1216,135 @@
     CMAKE_POP_CHECK_STATE()	# Restore the state of the variables
   ENDIF(EXPAT_FOUND)
 ENDIF(LIBXML2_FOUND)
-MARK_AS_ADVANCED(CLEAR LIBXML2_INCLUDE_DIR)
-MARK_AS_ADVANCED(CLEAR LIBXML2_LIBRARIES)
-ENDIF()
+
+#
+# POSIX Regular Expression support
+#
+IF(POSIX_REGEX_LIB MATCHES "^(AUTO|LIBC|LIBREGEX)$")
+  #
+  # If PCREPOSIX is not found or not requested, try using regex
+  # from libc or libregex
+  #
+  FIND_PATH(REGEX_INCLUDE_DIR regex.h)
+  IF(REGEX_INCLUDE_DIR)
+    CHECK_FUNCTION_EXISTS_GLIBC(regcomp HAVE_REGCOMP_LIBC)
+    #
+    # If libc does not provide regex, find libregex.
+    #
+    IF(NOT HAVE_REGCOMP_LIBC)
+      CMAKE_PUSH_CHECK_STATE()	# Save the state of the variables
+      FIND_LIBRARY(REGEX_LIBRARY regex)
+      IF(REGEX_LIBRARY)
+        SET(CMAKE_REQUIRED_LIBRARIES ${REGEX_LIBRARY})
+        CHECK_FUNCTION_EXISTS_GLIBC(regcomp HAVE_REGCOMP_LIBREGEX)
+        IF(HAVE_REGCOMP_LIBREGEX)
+          LIST(APPEND ADDITIONAL_LIBS ${REGEX_LIBRARY})
+          #
+          # If regex.h is not found, retry looking for regex.h at
+          # REGEX_INCLUDE_DIR
+          #
+          IF(NOT HAVE_REGEX_H)
+            UNSET(HAVE_REGEX_H CACHE)
+            INCLUDE_DIRECTORIES(${REGEX_INCLUDE_DIR})
+            SET(CMAKE_REQUIRED_INCLUDES ${REGEX_INCLUDE_DIR})
+            LA_CHECK_INCLUDE_FILE("regex.h" HAVE_REGEX_H)
+          ENDIF(NOT HAVE_REGEX_H)
+          # Test if a macro is needed for the library.
+          TRY_MACRO_FOR_LIBRARY(
+            "${REGEX_INCLUDE_DIR}" "${REGEX_LIBRARY}"
+            COMPILES
+            "#include <stddef.h>\n#include <regex.h>\nint main() {regex_t r;return regcomp(&r, \"\", 0);}"
+            "USE_REGEX_DLL;USE_REGEX_STATIC")
+          IF(USE_REGEX_DLL)
+            ADD_DEFINITIONS(-DUSE_REGEX_DLL)
+          ELSEIF(USE_REGEX_STATIC)
+            ADD_DEFINITIONS(-DUSE_REGEX_STATIC)
+          ENDIF(USE_REGEX_DLL)
+        ENDIF(HAVE_REGCOMP_LIBREGEX)
+      ENDIF(REGEX_LIBRARY)
+      CMAKE_POP_CHECK_STATE()	# Restore the state of the variables
+    ENDIF(NOT HAVE_REGCOMP_LIBC)
+  ENDIF(REGEX_INCLUDE_DIR)
+  IF(HAVE_REGCOMP_LIBC OR HAVE_REGCOMP_LIBREGEX)
+    SET(FOUND_POSIX_REGEX_LIB 1)
+  ENDIF(HAVE_REGCOMP_LIBC OR HAVE_REGCOMP_LIBREGEX)
+ENDIF(POSIX_REGEX_LIB MATCHES "^(AUTO|LIBC|LIBREGEX)$")
+
+IF(NOT FOUND_POSIX_REGEX_LIB AND POSIX_REGEX_LIB MATCHES "^(AUTO|LIBPCREPOSIX)$")
+  #
+  # If requested, try finding library for PCREPOSIX
+  #
+  IF(ENABLE_LibGCC)
+    FIND_PACKAGE(LibGCC)
+  ELSE()
+    SET(LIBGCC_FOUND FALSE) # Override cached value
+  ENDIF()
+  IF(ENABLE_PCREPOSIX)
+    FIND_PACKAGE(PCREPOSIX)
+  ELSE()
+    SET(PCREPOSIX_FOUND FALSE) # Override cached value
+  ENDIF()
+  IF(PCREPOSIX_FOUND)
+    INCLUDE_DIRECTORIES(${PCRE_INCLUDE_DIR})
+    LIST(APPEND ADDITIONAL_LIBS ${PCREPOSIX_LIBRARIES})
+    # Test if a macro is needed for the library.
+    TRY_MACRO_FOR_LIBRARY(
+      "${PCRE_INCLUDE_DIR}" "${PCREPOSIX_LIBRARIES}"
+      COMPILES
+      "#include <pcreposix.h>\nint main() {regex_t r;return regcomp(&r, \"\", 0);}"
+      "WITHOUT_PCRE_STATIC;PCRE_STATIC")
+    IF(NOT WITHOUT_PCRE_STATIC AND PCRE_STATIC)
+      ADD_DEFINITIONS(-DPCRE_STATIC)
+	ELSEIF(NOT WITHOUT_PCRE_STATIC AND NOT PCRE_STATIC AND PCRE_FOUND)
+	  # Determine if pcre static libraries are to be used.
+      LIST(APPEND ADDITIONAL_LIBS ${PCRE_LIBRARIES})
+      SET(TMP_LIBRARIES ${PCREPOSIX_LIBRARIES} ${PCRE_LIBRARIES})
+      MESSAGE(STATUS "trying again with -lpcre included")
+      TRY_MACRO_FOR_LIBRARY(
+        "${PCRE_INCLUDE_DIR}" "${TMP_LIBRARIES}"
+        COMPILES
+        "#include <pcreposix.h>\nint main() {regex_t r;return regcomp(&r, \"\", 0);}"
+        "WITHOUT_PCRE_STATIC;PCRE_STATIC")
+      IF(NOT WITHOUT_PCRE_STATIC AND PCRE_STATIC)
+        ADD_DEFINITIONS(-DPCRE_STATIC)
+      ELSEIF(NOT WITHOUT_PCRE_STATIC AND NOT PCRE_STATIC AND MSVC AND LIBGCC_FOUND)
+        # When doing a Visual Studio build using pcre static libraries
+        # built using the mingw toolchain, -lgcc is needed to resolve
+        # ___chkstk_ms.
+        MESSAGE(STATUS "Visual Studio build detected, trying again with -lgcc included")
+        LIST(APPEND ADDITIONAL_LIBS ${LIBGCC_LIBRARIES})
+        SET(TMP_LIBRARIES ${PCREPOSIX_LIBRARIES} ${PCRE_LIBRARIES} ${LIBGCC_LIBRARIES})
+          TRY_MACRO_FOR_LIBRARY(
+            "${PCRE_INCLUDE_DIR}" "${TMP_LIBRARIES}"
+            COMPILES
+            "#include <pcreposix.h>\nint main() {regex_t r;return regcomp(&r, \"\", 0);}"
+            "WITHOUT_PCRE_STATIC;PCRE_STATIC")
+          IF(NOT WITHOUT_PCRE_STATIC AND PCRE_STATIC)
+            ADD_DEFINITIONS(-DPCRE_STATIC)
+          ENDIF(NOT WITHOUT_PCRE_STATIC AND PCRE_STATIC)
+      ENDIF(NOT WITHOUT_PCRE_STATIC AND PCRE_STATIC)
+    ENDIF(NOT WITHOUT_PCRE_STATIC AND PCRE_STATIC)
+  ENDIF(PCREPOSIX_FOUND)
+  MARK_AS_ADVANCED(CLEAR PCRE_INCLUDE_DIR)
+  MARK_AS_ADVANCED(CLEAR PCREPOSIX_LIBRARIES)
+  MARK_AS_ADVANCED(CLEAR PCRE_LIBRARIES)
+  MARK_AS_ADVANCED(CLEAR LIBGCC_LIBRARIES)
+ENDIF(NOT FOUND_POSIX_REGEX_LIB AND POSIX_REGEX_LIB MATCHES "^(AUTO|LIBPCREPOSIX)$")
 
 #
 # Check functions
 #
 CMAKE_PUSH_CHECK_STATE()	# Save the state of the variables
-IF (CMAKE_C_COMPILER_ID STREQUAL "GNU" OR
-    CMAKE_C_COMPILER_ID STREQUAL "Clang")
+IF (CMAKE_C_COMPILER_ID MATCHES "^GNU$" OR
+    CMAKE_C_COMPILER_ID MATCHES "^Clang$")
   #
   # During checking functions, we should use -fno-builtin to avoid the
   # failure of function detection which failure is an error "conflicting
   # types for built-in function" caused by using -Werror option.
   #
   SET(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -fno-builtin")
-ENDIF ()
+ENDIF (CMAKE_C_COMPILER_ID MATCHES "^GNU$" OR
+       CMAKE_C_COMPILER_ID MATCHES "^Clang$")
 CHECK_SYMBOL_EXISTS(_CrtSetReportMode "crtdbg.h" HAVE__CrtSetReportMode)
 CHECK_FUNCTION_EXISTS_GLIBC(arc4random_buf HAVE_ARC4RANDOM_BUF)
 CHECK_FUNCTION_EXISTS_GLIBC(chflags HAVE_CHFLAGS)
@@ -1016,6 +1408,7 @@
 CHECK_FUNCTION_EXISTS_GLIBC(symlink HAVE_SYMLINK)
 CHECK_FUNCTION_EXISTS_GLIBC(timegm HAVE_TIMEGM)
 CHECK_FUNCTION_EXISTS_GLIBC(tzset HAVE_TZSET)
+CHECK_FUNCTION_EXISTS_GLIBC(unlinkat HAVE_UNLINKAT)
 CHECK_FUNCTION_EXISTS_GLIBC(unsetenv HAVE_UNSETENV)
 CHECK_FUNCTION_EXISTS_GLIBC(utime HAVE_UTIME)
 CHECK_FUNCTION_EXISTS_GLIBC(utimes HAVE_UTIMES)
@@ -1029,6 +1422,7 @@
 CHECK_FUNCTION_EXISTS_GLIBC(_ctime64_s HAVE__CTIME64_S)
 CHECK_FUNCTION_EXISTS_GLIBC(_fseeki64 HAVE__FSEEKI64)
 CHECK_FUNCTION_EXISTS_GLIBC(_get_timezone HAVE__GET_TIMEZONE)
+CHECK_FUNCTION_EXISTS_GLIBC(_gmtime64_s HAVE__GMTIME64_S)
 CHECK_FUNCTION_EXISTS_GLIBC(_localtime64_s HAVE__LOCALTIME64_S)
 CHECK_FUNCTION_EXISTS_GLIBC(_mkgmtime64 HAVE__MKGMTIME64)
 
@@ -1092,27 +1486,9 @@
 #
 # Check defines
 #
-SET(headers "limits.h")
-IF(HAVE_STDINT_H)
-  LIST(APPEND headers "stdint.h")
-ENDIF(HAVE_STDINT_H)
-IF(HAVE_INTTYPES_H)
-  LIST(APPEND headers "inttypes.h")
-ENDIF(HAVE_INTTYPES_H)
 CHECK_SYMBOL_EXISTS(EFTYPE           "errno.h"    HAVE_EFTYPE)
 CHECK_SYMBOL_EXISTS(EILSEQ           "errno.h"    HAVE_EILSEQ)
 CHECK_SYMBOL_EXISTS(D_MD_ORDER       "langinfo.h" HAVE_D_MD_ORDER)
-CHECK_SYMBOL_EXISTS(INT32_MAX        "${headers}" HAVE_DECL_INT32_MAX)
-CHECK_SYMBOL_EXISTS(INT32_MIN        "${headers}" HAVE_DECL_INT32_MIN)
-CHECK_SYMBOL_EXISTS(INT64_MAX        "${headers}" HAVE_DECL_INT64_MAX)
-CHECK_SYMBOL_EXISTS(INT64_MIN        "${headers}" HAVE_DECL_INT64_MIN)
-CHECK_SYMBOL_EXISTS(INTMAX_MAX       "${headers}" HAVE_DECL_INTMAX_MAX)
-CHECK_SYMBOL_EXISTS(INTMAX_MIN       "${headers}" HAVE_DECL_INTMAX_MIN)
-CHECK_SYMBOL_EXISTS(UINT32_MAX       "${headers}" HAVE_DECL_UINT32_MAX)
-CHECK_SYMBOL_EXISTS(UINT64_MAX       "${headers}" HAVE_DECL_UINT64_MAX)
-CHECK_SYMBOL_EXISTS(UINTMAX_MAX      "${headers}" HAVE_DECL_UINTMAX_MAX)
-CHECK_SYMBOL_EXISTS(SIZE_MAX         "${headers}" HAVE_DECL_SIZE_MAX)
-CHECK_SYMBOL_EXISTS(SSIZE_MAX        "limits.h"   HAVE_DECL_SSIZE_MAX)
 
 #
 # Check struct members
@@ -1161,33 +1537,6 @@
 CHECK_STRUCT_HAS_MEMBER("struct tm" tm_sec
     "sys/types.h;sys/time.h;time.h" TIME_WITH_SYS_TIME)
 
-#
-# Check for integer types
-#
-#
-CHECK_TYPE_SIZE("short" SIZE_OF_SHORT)
-CHECK_TYPE_SIZE("int" SIZE_OF_INT)
-CHECK_TYPE_SIZE("long" SIZE_OF_LONG)
-CHECK_TYPE_SIZE("long long"     SIZE_OF_LONG_LONG)
-
-CHECK_TYPE_SIZE("unsigned short" SIZE_OF_UNSIGNED_SHORT)
-CHECK_TYPE_SIZE("unsigned" SIZE_OF_UNSIGNED)
-CHECK_TYPE_SIZE("unsigned long" SIZE_OF_UNSIGNED_LONG)
-CHECK_TYPE_SIZE("unsigned long long" SIZE_OF_UNSIGNED_LONG_LONG)
-
-CHECK_TYPE_SIZE("__int64" __INT64)
-CHECK_TYPE_SIZE("unsigned __int64" UNSIGNED___INT64)
-
-CHECK_TYPE_SIZE(int16_t INT16_T)
-CHECK_TYPE_SIZE(int32_t INT32_T)
-CHECK_TYPE_SIZE(int64_t INT64_T)
-CHECK_TYPE_SIZE(intmax_t INTMAX_T)
-CHECK_TYPE_SIZE(uint8_t UINT8_T)
-CHECK_TYPE_SIZE(uint16_t UINT16_T)
-CHECK_TYPE_SIZE(uint32_t UINT32_T)
-CHECK_TYPE_SIZE(uint64_t UINT64_T)
-CHECK_TYPE_SIZE(uintmax_t UINTMAX_T)
-
 CHECK_TYPE_SIZE(dev_t       DEV_T)
 IF(NOT HAVE_DEV_T)
   IF(MSVC)
@@ -1263,24 +1612,6 @@
   ENDIF(WIN32)
 ENDIF(NOT HAVE_PID_T)
 #
-CHECK_TYPE_SIZE(intptr_t   INTPTR_T)
-IF(NOT HAVE_INTPTR_T)
-  IF("${CMAKE_SIZEOF_VOID_P}" EQUAL 8)
-    SET(intptr_t "int64_t")
-  ELSE()
-    SET(intptr_t "int32_t")
-  ENDIF()
-ENDIF(NOT HAVE_INTPTR_T)
-#
-CHECK_TYPE_SIZE(uintptr_t   UINTPTR_T)
-IF(NOT HAVE_UINTPTR_T)
-  IF("${CMAKE_SIZEOF_VOID_P}" EQUAL 8)
-    SET(uintptr_t "uint64_t")
-  ELSE()
-    SET(uintptr_t "uint32_t")
-  ENDIF()
-ENDIF(NOT HAVE_UINTPTR_T)
-#
 CHECK_TYPE_SIZE(wchar_t     SIZEOF_WCHAR_T)
 IF(HAVE_SIZEOF_WCHAR_T)
   SET(HAVE_WCHAR_T 1)
@@ -1297,6 +1628,11 @@
   CHECK_LIBRARY_EXISTS(attr "setxattr" "" HAVE_LIBATTR)
   IF(HAVE_LIBATTR)
     SET(CMAKE_REQUIRED_LIBRARIES "attr")
+  ELSE()
+    CHECK_LIBRARY_EXISTS(gnu "setxattr" "" HAVE_LIBATTR_GNU)
+    IF(HAVE_LIBATTR_GNU)
+      SET(CMAKE_REQUIRED_LIBRARIES "gnu")
+    ENDIF()
   ENDIF(HAVE_LIBATTR)
   CHECK_SYMBOL_EXISTS(EXTATTR_NAMESPACE_USER "sys/types.h;sys/extattr.h" HAVE_DECL_EXTATTR_NAMESPACE_USER)
   CHECK_SYMBOL_EXISTS(XATTR_NOFOLLOW "sys/xattr.h" HAVE_DECL_XATTR_NOFOLLOW)
@@ -1620,6 +1956,7 @@
 CHECK_CRYPTO("SHA256;SHA384;SHA512" LIBC2)
 CHECK_CRYPTO("SHA256;SHA384;SHA512" LIBC3)
 CHECK_CRYPTO("MD5;SHA1;SHA256;SHA384;SHA512" LIBSYSTEM)
+CHECK_CRYPTO("MD5;RMD160;SHA1;SHA256;SHA384;SHA512" MBEDTLS)
 CHECK_CRYPTO("MD5;RMD160;SHA1;SHA256;SHA384;SHA512" NETTLE)
 CHECK_CRYPTO("MD5;RMD160;SHA1;SHA256;SHA384;SHA512" OPENSSL)
 
@@ -1634,6 +1971,11 @@
 INCLUDE_DIRECTORIES(BEFORE ${CMAKE_CURRENT_BINARY_DIR})
 ADD_DEFINITIONS(-DHAVE_CONFIG_H)
 
+IF(0) # CMake does not build libarchive's packages.
+# Handle generation of the libarchive.pc file for pkg-config
+INCLUDE(CreatePkgConfigFile)
+ENDIF()
+
 #
 # Register installation of PDF documents.
 #
@@ -1659,11 +2001,22 @@
   ADD_DEFINITIONS(-D_CRT_SECURE_NO_DEPRECATE)
 ENDIF(MSVC)
 
+IF(0) # CMake does not build libarchive's tests.
+IF(ENABLE_TEST)
+  ADD_CUSTOM_TARGET(run_all_tests)
+ENDIF(ENABLE_TEST)
+ENDIF()
+
 # We need CoreServices on Mac OS.
 IF(APPLE)
   LIST(APPEND ADDITIONAL_LIBS "-framework CoreServices")
 ENDIF(APPLE)
 
 add_subdirectory(libarchive)
+IF(0) # CMake does not build libarchive's command-line tools.
+add_subdirectory(cat)
+add_subdirectory(tar)
+add_subdirectory(cpio)
+ENDIF()
 
 install(FILES COPYING DESTINATION ${CMAKE_DOC_DIR}/cmlibarchive)
diff --git a/Utilities/cmlibarchive/COPYING b/Utilities/cmlibarchive/COPYING
index 93952b7..14bbefa 100644
--- a/Utilities/cmlibarchive/COPYING
+++ b/Utilities/cmlibarchive/COPYING
@@ -23,6 +23,13 @@
 * The following source files are in the public domain:
    libarchive/archive_getdate.c
 
+* The following source files are triple-licensed with the ability to choose
+  from CC0 1.0 Universal, OpenSSL or Apache 2.0 licenses:
+   libarchive/archive_blake2.h
+   libarchive/archive_blake2_impl.h
+   libarchive/archive_blake2s_ref.c
+   libarchive/archive_blake2sp_ref.c
+
 * The build files---including Makefiles, configure scripts,
   and auxiliary scripts used as part of the compile process---have
   widely varying licensing terms.  Please check individual files before
@@ -34,7 +41,7 @@
 seems to be an unavoidable mess.
 
 
-Copyright (c) 2003-2009 <author(s)>
+Copyright (c) 2003-2018 <author(s)>
 All rights reserved.
 
 Redistribution and use in source and binary forms, with or without
diff --git a/Utilities/cmlibarchive/build/cmake/FindMbedTLS.cmake b/Utilities/cmlibarchive/build/cmake/FindMbedTLS.cmake
new file mode 100644
index 0000000..a916395
--- /dev/null
+++ b/Utilities/cmlibarchive/build/cmake/FindMbedTLS.cmake
@@ -0,0 +1,13 @@
+find_path(MBEDTLS_INCLUDE_DIRS mbedtls/ssl.h)
+
+find_library(MBEDTLS_LIBRARY mbedtls)
+find_library(MBEDX509_LIBRARY mbedx509)
+find_library(MBEDCRYPTO_LIBRARY mbedcrypto)
+
+set(MBEDTLS_LIBRARIES "${MBEDTLS_LIBRARY}" "${MBEDX509_LIBRARY}" "${MBEDCRYPTO_LIBRARY}")
+
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(MBEDTLS DEFAULT_MSG
+    MBEDTLS_INCLUDE_DIRS MBEDTLS_LIBRARY MBEDX509_LIBRARY MBEDCRYPTO_LIBRARY)
+
+mark_as_advanced(MBEDTLS_INCLUDE_DIRS MBEDTLS_LIBRARY MBEDX509_LIBRARY MBEDCRYPTO_LIBRARY)
diff --git a/Utilities/cmlibarchive/build/cmake/config.h.in b/Utilities/cmlibarchive/build/cmake/config.h.in
index 1851d81..f38601f 100644
--- a/Utilities/cmlibarchive/build/cmake/config.h.in
+++ b/Utilities/cmlibarchive/build/cmake/config.h.in
@@ -7,178 +7,6 @@
  * Ensure we have C99-style int64_t, etc, all defined.
  */
 
-/* First, we need to know if the system has already defined them. */
-#cmakedefine HAVE_INT16_T
-#cmakedefine HAVE_INT32_T
-#cmakedefine HAVE_INT64_T
-#cmakedefine HAVE_INTMAX_T
-
-#cmakedefine HAVE_UINT8_T
-#cmakedefine HAVE_UINT16_T
-#cmakedefine HAVE_UINT32_T
-#cmakedefine HAVE_UINT64_T
-#cmakedefine HAVE_UINTMAX_T
-
-/* We might have the types we want under other spellings. */
-#cmakedefine HAVE___INT64
-#cmakedefine HAVE_U_INT64_T
-#cmakedefine HAVE_UNSIGNED___INT64
-
-/* The sizes of various standard integer types. */
-@SIZE_OF_SHORT_CODE@
-@SIZE_OF_INT_CODE@
-@SIZE_OF_LONG_CODE@
-@SIZE_OF_LONG_LONG_CODE@
-@SIZE_OF_UNSIGNED_SHORT_CODE@
-@SIZE_OF_UNSIGNED_CODE@
-@SIZE_OF_UNSIGNED_LONG_CODE@
-@SIZE_OF_UNSIGNED_LONG_LONG_CODE@
-
-/*
- * If we lack int64_t, define it to the first of __int64, int, long, and long long
- * that exists and is the right size.
- */
-#if !defined(HAVE_INT64_T) && defined(HAVE___INT64)
-typedef __int64 int64_t;
-#define HAVE_INT64_T
-#endif
-
-#if !defined(HAVE_INT64_T) && SIZE_OF_INT == 8
-typedef int int64_t;
-#define HAVE_INT64_T
-#endif
-
-#if !defined(HAVE_INT64_T) && SIZE_OF_LONG == 8
-typedef long int64_t;
-#define HAVE_INT64_T
-#endif
-
-#if !defined(HAVE_INT64_T) && SIZE_OF_LONG_LONG == 8
-typedef long long int64_t;
-#define HAVE_INT64_T
-#endif
-
-#if !defined(HAVE_INT64_T)
-#error No 64-bit integer type was found.
-#endif
-
-/*
- * Similarly for int32_t
- */
-#if !defined(HAVE_INT32_T) && SIZE_OF_INT == 4
-typedef int int32_t;
-#define HAVE_INT32_T
-#endif
-
-#if !defined(HAVE_INT32_T) && SIZE_OF_LONG == 4
-typedef long int32_t;
-#define HAVE_INT32_T
-#endif
-
-#if !defined(HAVE_INT32_T)
-#error No 32-bit integer type was found.
-#endif
-
-/*
- * Similarly for int16_t
- */
-#if !defined(HAVE_INT16_T) && SIZE_OF_INT == 2
-typedef int int16_t;
-#define HAVE_INT16_T
-#endif
-
-#if !defined(HAVE_INT16_T) && SIZE_OF_SHORT == 2
-typedef short int16_t;
-#define HAVE_INT16_T
-#endif
-
-#if !defined(HAVE_INT16_T)
-#error No 16-bit integer type was found.
-#endif
-
-/*
- * Similarly for uint64_t
- */
-#if !defined(HAVE_UINT64_T) && defined(HAVE_UNSIGNED___INT64)
-typedef unsigned __int64 uint64_t;
-#define HAVE_UINT64_T
-#endif
-
-#if !defined(HAVE_UINT64_T) && SIZE_OF_UNSIGNED == 8
-typedef unsigned uint64_t;
-#define HAVE_UINT64_T
-#endif
-
-#if !defined(HAVE_UINT64_T) && SIZE_OF_UNSIGNED_LONG == 8
-typedef unsigned long uint64_t;
-#define HAVE_UINT64_T
-#endif
-
-#if !defined(HAVE_UINT64_T) && SIZE_OF_UNSIGNED_LONG_LONG == 8
-typedef unsigned long long uint64_t;
-#define HAVE_UINT64_T
-#endif
-
-#if !defined(HAVE_UINT64_T)
-#error No 64-bit unsigned integer type was found.
-#endif
-
-
-/*
- * Similarly for uint32_t
- */
-#if !defined(HAVE_UINT32_T) && SIZE_OF_UNSIGNED == 4
-typedef unsigned uint32_t;
-#define HAVE_UINT32_T
-#endif
-
-#if !defined(HAVE_UINT32_T) && SIZE_OF_UNSIGNED_LONG == 4
-typedef unsigned long uint32_t;
-#define HAVE_UINT32_T
-#endif
-
-#if !defined(HAVE_UINT32_T)
-#error No 32-bit unsigned integer type was found.
-#endif
-
-/*
- * Similarly for uint16_t
- */
-#if !defined(HAVE_UINT16_T) && SIZE_OF_UNSIGNED == 2
-typedef unsigned uint16_t;
-#define HAVE_UINT16_T
-#endif
-
-#if !defined(HAVE_UINT16_T) && SIZE_OF_UNSIGNED_SHORT == 2
-typedef unsigned short uint16_t;
-#define HAVE_UINT16_T
-#endif
-
-#if !defined(HAVE_UINT16_T)
-#error No 16-bit unsigned integer type was found.
-#endif
-
-/*
- * Similarly for uint8_t
- */
-#if !defined(HAVE_UINT8_T)
-typedef unsigned char uint8_t;
-#define HAVE_UINT8_T
-#endif
-
-#if !defined(HAVE_UINT16_T)
-#error No 8-bit unsigned integer type was found.
-#endif
-
-/* Define intmax_t and uintmax_t if they are not already defined. */
-#if !defined(HAVE_INTMAX_T)
-typedef int64_t intmax_t;
-#endif
-
-#if !defined(HAVE_UINTMAX_T)
-typedef uint64_t uintmax_t;
-#endif
-
 /* Define ZLIB_WINAPI if zlib was built on Visual Studio. */
 #cmakedefine ZLIB_WINAPI 1
 
@@ -426,58 +254,14 @@
    don't. */
 #cmakedefine HAVE_DECL_ACL_USER 1
 
-/* Define to 1 if you have the declaration of `INT32_MAX', and to 0 if you
-   don't. */
-#cmakedefine HAVE_DECL_INT32_MAX 1
-
-/* Define to 1 if you have the declaration of `INT32_MIN', and to 0 if you
-   don't. */
-#cmakedefine HAVE_DECL_INT32_MIN 1
-
-/* Define to 1 if you have the declaration of `INT64_MAX', and to 0 if you
-   don't. */
-#cmakedefine HAVE_DECL_INT64_MAX 1
-
-/* Define to 1 if you have the declaration of `INT64_MIN', and to 0 if you
-   don't. */
-#cmakedefine HAVE_DECL_INT64_MIN 1
-
-/* Define to 1 if you have the declaration of `INTMAX_MAX', and to 0 if you
-   don't. */
-#cmakedefine HAVE_DECL_INTMAX_MAX 1
-
-/* Define to 1 if you have the declaration of `INTMAX_MIN', and to 0 if you
-   don't. */
-#cmakedefine HAVE_DECL_INTMAX_MIN 1
-
 /* Define to 1 if you have the declaration of `SETACL', and to 0 if you don't.
    */
 #cmakedefine HAVE_DECL_SETACL 1
 
-/* Define to 1 if you have the declaration of `SIZE_MAX', and to 0 if you
-   don't. */
-#cmakedefine HAVE_DECL_SIZE_MAX 1
-
-/* Define to 1 if you have the declaration of `SSIZE_MAX', and to 0 if you
-   don't. */
-#cmakedefine HAVE_DECL_SSIZE_MAX 1
-
 /* Define to 1 if you have the declaration of `strerror_r', and to 0 if you
    don't. */
 #cmakedefine HAVE_DECL_STRERROR_R 1
 
-/* Define to 1 if you have the declaration of `UINT32_MAX', and to 0 if you
-   don't. */
-#cmakedefine HAVE_DECL_UINT32_MAX 1
-
-/* Define to 1 if you have the declaration of `UINT64_MAX', and to 0 if you
-   don't. */
-#cmakedefine HAVE_DECL_UINT64_MAX 1
-
-/* Define to 1 if you have the declaration of `UINTMAX_MAX', and to 0 if you
-   don't. */
-#cmakedefine HAVE_DECL_UINTMAX_MAX 1
-
 /* Define to 1 if you have the declaration of `XATTR_NOFOLLOW', and to 0 if
    you don't. */
 #cmakedefine HAVE_DECL_XATTR_NOFOLLOW 1
@@ -647,9 +431,6 @@
 /* Define to 1 if you have the <iconv.h> header file. */
 #cmakedefine HAVE_ICONV_H 1
 
-/* Define to 1 if you have the <inttypes.h> header file. */
-#cmakedefine HAVE_INTTYPES_H 1
-
 /* Define to 1 if you have the <io.h> header file. */
 #cmakedefine HAVE_IO_H 1
 
@@ -683,6 +464,12 @@
 /* Define to 1 if you have the `bz2' library (-lbz2). */
 #cmakedefine HAVE_LIBBZ2 1
 
+/* Define to 1 if you have the `b2' library (-lb2). */
+#cmakedefine HAVE_LIBB2 1
+
+/* Define to 1 if you have the <blake2.h> header file. */
+#cmakedefine HAVE_BLAKE2_H 1
+
 /* Define to 1 if you have the `charset' library (-lcharset). */
 #cmakedefine HAVE_LIBCHARSET 1
 
@@ -707,6 +494,9 @@
 /* Define to 1 if you have the `lzo2' library (-llzo2). */
 #cmakedefine HAVE_LIBLZO2 1
 
+/* Define to 1 if you have the `mbedcrypto' library (-lmbedcrypto). */
+#cmakedefine HAVE_LIBMBEDCRYPTO 1
+
 /* Define to 1 if you have the `nettle' library (-lnettle). */
 #cmakedefine HAVE_LIBNETTLE 1
 
@@ -946,9 +736,6 @@
 /* Define to 1 if you have the <stdarg.h> header file. */
 #cmakedefine HAVE_STDARG_H 1
 
-/* Define to 1 if you have the <stdint.h> header file. */
-#cmakedefine HAVE_STDINT_H 1
-
 /* Define to 1 if you have the <stdlib.h> header file. */
 #cmakedefine HAVE_STDLIB_H 1
 
@@ -1111,6 +898,9 @@
 /* Define to 1 if you have the <unistd.h> header file. */
 #cmakedefine HAVE_UNISTD_H 1
 
+/* Define to 1 if you have the `unlinkat' function. */
+#cmakedefine HAVE_UNLINKAT 1
+
 /* Define to 1 if you have the `unsetenv' function. */
 #cmakedefine HAVE_UNSETENV 1
 
@@ -1204,6 +994,9 @@
 /* Define to 1 if you have the `_get_timezone' function. */
 #cmakedefine HAVE__GET_TIMEZONE 1
 
+/* Define to 1 if you have the `_gmtime64_s' function. */
+#cmakedefine HAVE__GMTIME64_S 1
+
 /* Define to 1 if you have the `_localtime64_s' function. */
 #cmakedefine HAVE__LOCALTIME64_S 1
 
@@ -1322,8 +1115,45 @@
 /* Define to `int' if <sys/types.h> doesn't define. */
 #cmakedefine uid_t ${uid_t}
 
-/* Define to `int' if <sys/types.h> does not define. */
-#cmakedefine intptr_t ${intptr_t}
+#include <cm3p/kwiml/int.h>
 
-/* Define to `unsigned int' if <sys/types.h> does not define. */
-#cmakedefine uintptr_t ${uintptr_t}
+#ifndef KWIML_INT_HAVE_INT64_T
+typedef KWIML_INT_int64_t int64_t;
+#endif
+#ifndef KWIML_INT_HAVE_INT32_T
+typedef KWIML_INT_int32_t int32_t;
+#endif
+#ifndef KWIML_INT_HAVE_INT16_T
+typedef KWIML_INT_int16_t int16_t;
+#endif
+#ifndef KWIML_INT_HAVE_INT8_T
+typedef KWIML_INT_int8_t int8_t;
+#endif
+#ifndef KWIML_INT_HAVE_INTPTR_T
+typedef KWIML_INT_intptr_t intptr_t;
+#endif
+#ifndef KWIML_INT_HAVE_UINT64_T
+typedef KWIML_INT_uint64_t uint64_t;
+#endif
+#ifndef KWIML_INT_HAVE_UINT32_T
+typedef KWIML_INT_uint32_t uint32_t;
+#endif
+#ifndef KWIML_INT_HAVE_UINT16_T
+typedef KWIML_INT_uint16_t uint16_t;
+#endif
+#ifndef KWIML_INT_HAVE_UINT8_T
+typedef KWIML_INT_uint8_t uint8_t;
+#endif
+#ifndef KWIML_INT_HAVE_UINTPTR_T
+typedef KWIML_INT_uintptr_t uintptr_t;
+#endif
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#ifdef KWIML_INT_HAVE_STDINT_H
+# define HAVE_STDINT_H 1
+#endif
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#ifdef KWIML_INT_HAVE_INTTYPES_H
+# define HAVE_INTTYPES_H 1
+#endif
diff --git a/Utilities/cmlibarchive/build/version b/Utilities/cmlibarchive/build/version
index 2427eab..78be3ab 100644
--- a/Utilities/cmlibarchive/build/version
+++ b/Utilities/cmlibarchive/build/version
@@ -1 +1 @@
-3003003
+3004002
diff --git a/Utilities/cmlibarchive/libarchive/CMakeLists.txt b/Utilities/cmlibarchive/libarchive/CMakeLists.txt
index e38d664..891a140 100644
--- a/Utilities/cmlibarchive/libarchive/CMakeLists.txt
+++ b/Utilities/cmlibarchive/libarchive/CMakeLists.txt
@@ -51,6 +51,8 @@
   archive_platform_acl.h
   archive_platform_xattr.h
   archive_ppmd_private.h
+  archive_ppmd8.c
+  archive_ppmd8_private.h
   archive_ppmd7.c
   archive_ppmd7_private.h
   archive_private.h
@@ -100,6 +102,7 @@
   archive_read_support_format_lha.c
   archive_read_support_format_mtree.c
   archive_read_support_format_rar.c
+  archive_read_support_format_rar5.c
   archive_read_support_format_raw.c
   archive_read_support_format_tar.c
   archive_read_support_format_warc.c
@@ -147,6 +150,7 @@
   archive_write_set_format_iso9660.c
   archive_write_set_format_mtree.c
   archive_write_set_format_pax.c
+  archive_write_set_format_private.h
   archive_write_set_format_raw.c
   archive_write_set_format_shar.c
   archive_write_set_format_ustar.c
@@ -167,6 +171,7 @@
   archive_entry.3
   archive_entry_acl.3
   archive_entry_linkify.3
+  archive_entry_misc.3
   archive_entry_paths.3
   archive_entry_perms.3
   archive_entry_stat.3
@@ -215,6 +220,11 @@
   LIST(APPEND libarchive_SOURCES filter_fork_windows.c)
 ENDIF(WIN32 AND NOT CYGWIN)
 
+IF(ARCHIVE_BLAKE2)
+  LIST(APPEND libarchive_SOURCES archive_blake2sp_ref.c)
+  LIST(APPEND libarchive_SOURCES archive_blake2s_ref.c)
+ENDIF(ARCHIVE_BLAKE2)
+
 IF(ARCHIVE_ACL_DARWIN)
   LIST(APPEND libarchive_SOURCES archive_disk_acl_darwin.c)
 ELSEIF(ARCHIVE_ACL_FREEBSD)
@@ -228,3 +238,33 @@
 # CMake needs just one static "cmlibarchive" library.
 ADD_LIBRARY(cmlibarchive STATIC ${libarchive_SOURCES} ${include_HEADERS})
 TARGET_LINK_LIBRARIES(cmlibarchive ${ADDITIONAL_LIBS})
+
+IF(0) # CMake does not build libarchive's full package.
+# Libarchive is a shared library
+ADD_LIBRARY(archive SHARED ${libarchive_SOURCES} ${include_HEADERS})
+TARGET_INCLUDE_DIRECTORIES(archive PUBLIC .)
+TARGET_LINK_LIBRARIES(archive ${ADDITIONAL_LIBS})
+SET_TARGET_PROPERTIES(archive PROPERTIES SOVERSION ${SOVERSION})
+
+# archive_static is a static library
+ADD_LIBRARY(archive_static STATIC ${libarchive_SOURCES} ${include_HEADERS})
+TARGET_LINK_LIBRARIES(archive_static ${ADDITIONAL_LIBS})
+SET_TARGET_PROPERTIES(archive_static PROPERTIES COMPILE_DEFINITIONS
+  LIBARCHIVE_STATIC)
+# On Posix systems, libarchive.so and libarchive.a can co-exist.
+IF(NOT WIN32 OR CYGWIN)
+  SET_TARGET_PROPERTIES(archive_static PROPERTIES OUTPUT_NAME archive)
+ENDIF(NOT WIN32 OR CYGWIN)
+
+IF(ENABLE_INSTALL)
+  # How to install the libraries
+  INSTALL(TARGETS archive archive_static
+          RUNTIME DESTINATION bin
+          LIBRARY DESTINATION lib
+          ARCHIVE DESTINATION lib)
+  INSTALL_MAN(${libarchive_MANS})
+  INSTALL(FILES ${include_HEADERS} DESTINATION include)
+ENDIF()
+
+add_subdirectory(test)
+ENDIF()
diff --git a/Utilities/cmlibarchive/libarchive/archive.h b/Utilities/cmlibarchive/libarchive/archive.h
index f3ebbfe..574e087 100644
--- a/Utilities/cmlibarchive/libarchive/archive.h
+++ b/Utilities/cmlibarchive/libarchive/archive.h
@@ -36,7 +36,7 @@
  * assert that ARCHIVE_VERSION_NUMBER >= 2012108.
  */
 /* Note: Compiler will complain if this does not match archive_entry.h! */
-#define	ARCHIVE_VERSION_NUMBER 3003003
+#define	ARCHIVE_VERSION_NUMBER 3004002
 
 #include <sys/stat.h>
 #include <stddef.h>  /* for wchar_t */
@@ -52,7 +52,7 @@
  */
 #if defined(__BORLANDC__) && __BORLANDC__ >= 0x560
 # include <stdint.h>
-#elif !defined(__WATCOMC__) && !defined(_MSC_VER) && !defined(__INTERIX) && !defined(__BORLANDC__) && !defined(_SCO_DS) && !defined(__osf__)
+#elif !defined(__WATCOMC__) && !defined(_MSC_VER) && !defined(__INTERIX) && !defined(__BORLANDC__) && !defined(_SCO_DS) && !defined(__osf__) && !defined(__CLANG_INTTYPES_H)
 # include <inttypes.h>
 #endif
 
@@ -152,7 +152,7 @@
 /*
  * Textual name/version of the library, useful for version displays.
  */
-#define	ARCHIVE_VERSION_ONLY_STRING "3.3.3"
+#define	ARCHIVE_VERSION_ONLY_STRING "3.4.2"
 #define	ARCHIVE_VERSION_STRING "libarchive " ARCHIVE_VERSION_ONLY_STRING
 __LA_DECL const char *	archive_version_string(void);
 
@@ -337,6 +337,7 @@
 #define	ARCHIVE_FORMAT_RAR			0xD0000
 #define	ARCHIVE_FORMAT_7ZIP			0xE0000
 #define	ARCHIVE_FORMAT_WARC			0xF0000
+#define	ARCHIVE_FORMAT_RAR_V5			0x100000
 
 /*
  * Codes returned by archive_read_format_capabilities().
@@ -446,6 +447,7 @@
 __LA_DECL int archive_read_support_format_lha(struct archive *);
 __LA_DECL int archive_read_support_format_mtree(struct archive *);
 __LA_DECL int archive_read_support_format_rar(struct archive *);
+__LA_DECL int archive_read_support_format_rar5(struct archive *);
 __LA_DECL int archive_read_support_format_raw(struct archive *);
 __LA_DECL int archive_read_support_format_tar(struct archive *);
 __LA_DECL int archive_read_support_format_warc(struct archive *);
@@ -688,6 +690,8 @@
 #define ARCHIVE_EXTRACT_SECURE_NOABSOLUTEPATHS (0x10000)
 /* Default: Do not clear no-change flags when unlinking object */
 #define	ARCHIVE_EXTRACT_CLEAR_NOCHANGE_FFLAGS	(0x20000)
+/* Default: Do not extract atomically (using rename) */
+#define	ARCHIVE_EXTRACT_SAFE_WRITES		(0x40000)
 
 __LA_DECL int archive_read_extract(struct archive *, struct archive_entry *,
 		     int flags);
@@ -1090,6 +1094,8 @@
  */
 __LA_DECL int	archive_match_path_excluded(struct archive *,
 		    struct archive_entry *);
+/* Control recursive inclusion of directory content when directory is included. Default on. */
+__LA_DECL int	archive_match_set_inclusion_recursion(struct archive *, int);
 /* Add exclusion pathname pattern. */
 __LA_DECL int	archive_match_exclude_pattern(struct archive *, const char *);
 __LA_DECL int	archive_match_exclude_pattern_w(struct archive *,
diff --git a/Utilities/cmlibarchive/libarchive/archive_acl.c b/Utilities/cmlibarchive/libarchive/archive_acl.c
index 4736531..952e20d 100644
--- a/Utilities/cmlibarchive/libarchive/archive_acl.c
+++ b/Utilities/cmlibarchive/libarchive/archive_acl.c
@@ -138,14 +138,10 @@
 		free(acl->acl_head);
 		acl->acl_head = ap;
 	}
-	if (acl->acl_text_w != NULL) {
-		free(acl->acl_text_w);
-		acl->acl_text_w = NULL;
-	}
-	if (acl->acl_text != NULL) {
-		free(acl->acl_text);
-		acl->acl_text = NULL;
-	}
+	free(acl->acl_text_w);
+	acl->acl_text_w = NULL;
+	free(acl->acl_text);
+	acl->acl_text = NULL;
 	acl->acl_p = NULL;
 	acl->acl_types = 0;
 	acl->acl_state = 0; /* Not counting. */
@@ -324,14 +320,10 @@
 		return (NULL);
 	}
 
-	if (acl->acl_text_w != NULL) {
-		free(acl->acl_text_w);
-		acl->acl_text_w = NULL;
-	}
-	if (acl->acl_text != NULL) {
-		free(acl->acl_text);
-		acl->acl_text = NULL;
-	}
+	free(acl->acl_text_w);
+	acl->acl_text_w = NULL;
+	free(acl->acl_text);
+	acl->acl_text = NULL;
 
 	/*
 	 * If there's a matching entry already in the list, overwrite it.
@@ -753,8 +745,10 @@
 			append_entry_w(&wp, prefix, ap->type, ap->tag, flags,
 			    wname, ap->permset, id);
 			count++;
-		} else if (r < 0 && errno == ENOMEM)
+		} else if (r < 0 && errno == ENOMEM) {
+			free(ws);
 			return (NULL);
+		}
 	}
 
 	/* Add terminating character */
@@ -975,8 +969,10 @@
 			prefix = NULL;
 		r = archive_mstring_get_mbs_l(
 		    &ap->name, &name, &len, sc);
-		if (r != 0)
+		if (r != 0) {
+			free(s);
 			return (NULL);
+		}
 		if (count > 0)
 			*p++ = separator;
 		if (name == NULL ||
@@ -1581,17 +1577,29 @@
 
 	/* Scan for the separator. */
 	while (**wp != L'\0' && **wp != L',' && **wp != L':' &&
-	    **wp != L'\n') {
+	    **wp != L'\n' && **wp != L'#') {
 		(*wp)++;
 	}
 	*sep = **wp;
 
-	/* Trim trailing whitespace to locate end of field. */
-	*end = *wp - 1;
-	while (**end == L' ' || **end == L'\t' || **end == L'\n') {
-		(*end)--;
+	/* Locate end of field, trim trailing whitespace if necessary */
+	if (*wp == *start) {
+		*end = *wp;
+	} else {
+		*end = *wp - 1;
+		while (**end == L' ' || **end == L'\t' || **end == L'\n') {
+			(*end)--;
+		}
+		(*end)++;
 	}
-	(*end)++;
+
+	/* Handle in-field comments */
+	if (*sep == L'#') {
+		while (**wp != L'\0' && **wp != L',' && **wp != L'\n') {
+			(*wp)++;
+		}
+		*sep = **wp;
+	}
 
 	/* Adjust scanner location. */
 	if (**wp != L'\0')
@@ -1642,7 +1650,7 @@
 	ret = ARCHIVE_OK;
 	types = 0;
 
-	while (text != NULL  &&  *text != '\0') {
+	while (text != NULL &&  *text != '\0') {
 		/*
 		 * Parse the fields out of the next entry,
 		 * advance 'text' to start of next entry.
@@ -1707,6 +1715,11 @@
 			st = field[n].start + 1;
 			len = field[n].end - field[n].start;
 
+			if (len == 0) {
+				ret = ARCHIVE_WARN;
+				continue;
+			}
+
 			switch (*s) {
 			case 'u':
 				if (len == 1 || (len == 4
@@ -2053,17 +2066,30 @@
 	*start = *p;
 
 	/* Scan for the separator. */
-	while (**p != '\0' && **p != ',' && **p != ':' && **p != '\n') {
+	while (**p != '\0' && **p != ',' && **p != ':' && **p != '\n' &&
+	    **p != '#') {
 		(*p)++;
 	}
 	*sep = **p;
 
-	/* Trim trailing whitespace to locate end of field. */
-	*end = *p - 1;
-	while (**end == ' ' || **end == '\t' || **end == '\n') {
-		(*end)--;
+	/* Locate end of field, trim trailing whitespace if necessary */
+	if (*p == *start) {
+		*end = *p;
+	} else {
+		*end = *p - 1;
+		while (**end == ' ' || **end == '\t' || **end == '\n') {
+			(*end)--;
+		}
+		(*end)++;
 	}
-	(*end)++;
+
+	/* Handle in-field comments */
+	if (*sep == '#') {
+		while (**p != '\0' && **p != ',' && **p != '\n') {
+			(*p)++;
+		}
+		*sep = **p;
+	}
 
 	/* Adjust scanner location. */
 	if (**p != '\0')
diff --git a/Utilities/cmlibarchive/libarchive/archive_acl_private.h b/Utilities/cmlibarchive/libarchive/archive_acl_private.h
index ef0b023..af10816 100644
--- a/Utilities/cmlibarchive/libarchive/archive_acl_private.h
+++ b/Utilities/cmlibarchive/libarchive/archive_acl_private.h
@@ -25,13 +25,13 @@
  * $FreeBSD$
  */
 
+#ifndef ARCHIVE_ACL_PRIVATE_H_INCLUDED
+#define ARCHIVE_ACL_PRIVATE_H_INCLUDED
+
 #ifndef __LIBARCHIVE_BUILD
 #error This header is only to be used internally to libarchive.
 #endif
 
-#ifndef ARCHIVE_ACL_PRIVATE_H_INCLUDED
-#define	ARCHIVE_ACL_PRIVATE_H_INCLUDED
-
 #include "archive_string.h"
 
 struct archive_acl_entry {
diff --git a/Utilities/cmlibarchive/libarchive/archive_blake2.h b/Utilities/cmlibarchive/libarchive/archive_blake2.h
new file mode 100644
index 0000000..dd6fe6f
--- /dev/null
+++ b/Utilities/cmlibarchive/libarchive/archive_blake2.h
@@ -0,0 +1,195 @@
+/*
+   BLAKE2 reference source code package - reference C implementations
+
+   Copyright 2012, Samuel Neves <sneves@dei.uc.pt>.  You may use this under the
+   terms of the CC0, the OpenSSL Licence, or the Apache Public License 2.0, at
+   your option.  The terms of these licenses can be found at:
+
+   - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0
+   - OpenSSL license   : https://www.openssl.org/source/license.html
+   - Apache 2.0        : http://www.apache.org/licenses/LICENSE-2.0
+
+   More information about the BLAKE2 hash function can be found at
+   https://blake2.net.
+*/
+
+#ifndef ARCHIVE_BLAKE2_H
+#define ARCHIVE_BLAKE2_H
+
+#include <stddef.h>
+#include <stdint.h>
+
+#if defined(_MSC_VER)
+#define BLAKE2_PACKED(x) __pragma(pack(push, 1)) x __pragma(pack(pop))
+#else
+#define BLAKE2_PACKED(x) x __attribute__((packed))
+#endif
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+  enum blake2s_constant
+  {
+    BLAKE2S_BLOCKBYTES = 64,
+    BLAKE2S_OUTBYTES   = 32,
+    BLAKE2S_KEYBYTES   = 32,
+    BLAKE2S_SALTBYTES  = 8,
+    BLAKE2S_PERSONALBYTES = 8
+  };
+
+  enum blake2b_constant
+  {
+    BLAKE2B_BLOCKBYTES = 128,
+    BLAKE2B_OUTBYTES   = 64,
+    BLAKE2B_KEYBYTES   = 64,
+    BLAKE2B_SALTBYTES  = 16,
+    BLAKE2B_PERSONALBYTES = 16
+  };
+
+  typedef struct blake2s_state__
+  {
+    uint32_t h[8];
+    uint32_t t[2];
+    uint32_t f[2];
+    uint8_t  buf[BLAKE2S_BLOCKBYTES];
+    size_t   buflen;
+    size_t   outlen;
+    uint8_t  last_node;
+  } blake2s_state;
+
+  typedef struct blake2b_state__
+  {
+    uint64_t h[8];
+    uint64_t t[2];
+    uint64_t f[2];
+    uint8_t  buf[BLAKE2B_BLOCKBYTES];
+    size_t   buflen;
+    size_t   outlen;
+    uint8_t  last_node;
+  } blake2b_state;
+
+  typedef struct blake2sp_state__
+  {
+    blake2s_state S[8][1];
+    blake2s_state R[1];
+    uint8_t       buf[8 * BLAKE2S_BLOCKBYTES];
+    size_t        buflen;
+    size_t        outlen;
+  } blake2sp_state;
+
+  typedef struct blake2bp_state__
+  {
+    blake2b_state S[4][1];
+    blake2b_state R[1];
+    uint8_t       buf[4 * BLAKE2B_BLOCKBYTES];
+    size_t        buflen;
+    size_t        outlen;
+  } blake2bp_state;
+
+  BLAKE2_PACKED(struct blake2s_param__
+  {
+    uint8_t  digest_length; /* 1 */
+    uint8_t  key_length;    /* 2 */
+    uint8_t  fanout;        /* 3 */
+    uint8_t  depth;         /* 4 */
+    uint32_t leaf_length;   /* 8 */
+    uint32_t node_offset;  /* 12 */
+    uint16_t xof_length;    /* 14 */
+    uint8_t  node_depth;    /* 15 */
+    uint8_t  inner_length;  /* 16 */
+    /* uint8_t  reserved[0]; */
+    uint8_t  salt[BLAKE2S_SALTBYTES]; /* 24 */
+    uint8_t  personal[BLAKE2S_PERSONALBYTES];  /* 32 */
+  });
+
+  typedef struct blake2s_param__ blake2s_param;
+
+  BLAKE2_PACKED(struct blake2b_param__
+  {
+    uint8_t  digest_length; /* 1 */
+    uint8_t  key_length;    /* 2 */
+    uint8_t  fanout;        /* 3 */
+    uint8_t  depth;         /* 4 */
+    uint32_t leaf_length;   /* 8 */
+    uint32_t node_offset;   /* 12 */
+    uint32_t xof_length;    /* 16 */
+    uint8_t  node_depth;    /* 17 */
+    uint8_t  inner_length;  /* 18 */
+    uint8_t  reserved[14];  /* 32 */
+    uint8_t  salt[BLAKE2B_SALTBYTES]; /* 48 */
+    uint8_t  personal[BLAKE2B_PERSONALBYTES];  /* 64 */
+  });
+
+  typedef struct blake2b_param__ blake2b_param;
+
+  typedef struct blake2xs_state__
+  {
+    blake2s_state S[1];
+    blake2s_param P[1];
+  } blake2xs_state;
+
+  typedef struct blake2xb_state__
+  {
+    blake2b_state S[1];
+    blake2b_param P[1];
+  } blake2xb_state;
+
+  /* Padded structs result in a compile-time error */
+  enum {
+    BLAKE2_DUMMY_1 = 1/(sizeof(blake2s_param) == BLAKE2S_OUTBYTES),
+    BLAKE2_DUMMY_2 = 1/(sizeof(blake2b_param) == BLAKE2B_OUTBYTES)
+  };
+
+  /* Streaming API */
+  int blake2s_init( blake2s_state *S, size_t outlen );
+  int blake2s_init_key( blake2s_state *S, size_t outlen, const void *key, size_t keylen );
+  int blake2s_init_param( blake2s_state *S, const blake2s_param *P );
+  int blake2s_update( blake2s_state *S, const void *in, size_t inlen );
+  int blake2s_final( blake2s_state *S, void *out, size_t outlen );
+
+  int blake2b_init( blake2b_state *S, size_t outlen );
+  int blake2b_init_key( blake2b_state *S, size_t outlen, const void *key, size_t keylen );
+  int blake2b_init_param( blake2b_state *S, const blake2b_param *P );
+  int blake2b_update( blake2b_state *S, const void *in, size_t inlen );
+  int blake2b_final( blake2b_state *S, void *out, size_t outlen );
+
+  int blake2sp_init( blake2sp_state *S, size_t outlen );
+  int blake2sp_init_key( blake2sp_state *S, size_t outlen, const void *key, size_t keylen );
+  int blake2sp_update( blake2sp_state *S, const void *in, size_t inlen );
+  int blake2sp_final( blake2sp_state *S, void *out, size_t outlen );
+
+  int blake2bp_init( blake2bp_state *S, size_t outlen );
+  int blake2bp_init_key( blake2bp_state *S, size_t outlen, const void *key, size_t keylen );
+  int blake2bp_update( blake2bp_state *S, const void *in, size_t inlen );
+  int blake2bp_final( blake2bp_state *S, void *out, size_t outlen );
+
+  /* Variable output length API */
+  int blake2xs_init( blake2xs_state *S, const size_t outlen );
+  int blake2xs_init_key( blake2xs_state *S, const size_t outlen, const void *key, size_t keylen );
+  int blake2xs_update( blake2xs_state *S, const void *in, size_t inlen );
+  int blake2xs_final(blake2xs_state *S, void *out, size_t outlen);
+
+  int blake2xb_init( blake2xb_state *S, const size_t outlen );
+  int blake2xb_init_key( blake2xb_state *S, const size_t outlen, const void *key, size_t keylen );
+  int blake2xb_update( blake2xb_state *S, const void *in, size_t inlen );
+  int blake2xb_final(blake2xb_state *S, void *out, size_t outlen);
+
+  /* Simple API */
+  int blake2s( void *out, size_t outlen, const void *in, size_t inlen, const void *key, size_t keylen );
+  int blake2b( void *out, size_t outlen, const void *in, size_t inlen, const void *key, size_t keylen );
+
+  int blake2sp( void *out, size_t outlen, const void *in, size_t inlen, const void *key, size_t keylen );
+  int blake2bp( void *out, size_t outlen, const void *in, size_t inlen, const void *key, size_t keylen );
+
+  int blake2xs( void *out, size_t outlen, const void *in, size_t inlen, const void *key, size_t keylen );
+  int blake2xb( void *out, size_t outlen, const void *in, size_t inlen, const void *key, size_t keylen );
+
+  /* This is simply an alias for blake2b */
+  int blake2( void *out, size_t outlen, const void *in, size_t inlen, const void *key, size_t keylen );
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif
diff --git a/Utilities/cmlibarchive/libarchive/archive_blake2_impl.h b/Utilities/cmlibarchive/libarchive/archive_blake2_impl.h
new file mode 100644
index 0000000..0f05def
--- /dev/null
+++ b/Utilities/cmlibarchive/libarchive/archive_blake2_impl.h
@@ -0,0 +1,161 @@
+/*
+   BLAKE2 reference source code package - reference C implementations
+
+   Copyright 2012, Samuel Neves <sneves@dei.uc.pt>.  You may use this under the
+   terms of the CC0, the OpenSSL Licence, or the Apache Public License 2.0, at
+   your option.  The terms of these licenses can be found at:
+
+   - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0
+   - OpenSSL license   : https://www.openssl.org/source/license.html
+   - Apache 2.0        : http://www.apache.org/licenses/LICENSE-2.0
+
+   More information about the BLAKE2 hash function can be found at
+   https://blake2.net.
+*/
+
+#ifndef ARCHIVE_BLAKE2_IMPL_H
+#define ARCHIVE_BLAKE2_IMPL_H
+
+#include <stdint.h>
+#include <string.h>
+
+#if !defined(__cplusplus) && (!defined(__STDC_VERSION__) || __STDC_VERSION__ < 199901L)
+  #if   defined(_MSC_VER)
+    #define BLAKE2_INLINE __inline
+  #elif defined(__GNUC__)
+    #define BLAKE2_INLINE __inline__
+  #else
+    #define BLAKE2_INLINE
+  #endif
+#else
+  #define BLAKE2_INLINE inline
+#endif
+
+static BLAKE2_INLINE uint32_t load32( const void *src )
+{
+#if defined(NATIVE_LITTLE_ENDIAN)
+  uint32_t w;
+  memcpy(&w, src, sizeof w);
+  return w;
+#else
+  const uint8_t *p = ( const uint8_t * )src;
+  return (( uint32_t )( p[0] ) <<  0) |
+         (( uint32_t )( p[1] ) <<  8) |
+         (( uint32_t )( p[2] ) << 16) |
+         (( uint32_t )( p[3] ) << 24) ;
+#endif
+}
+
+static BLAKE2_INLINE uint64_t load64( const void *src )
+{
+#if defined(NATIVE_LITTLE_ENDIAN)
+  uint64_t w;
+  memcpy(&w, src, sizeof w);
+  return w;
+#else
+  const uint8_t *p = ( const uint8_t * )src;
+  return (( uint64_t )( p[0] ) <<  0) |
+         (( uint64_t )( p[1] ) <<  8) |
+         (( uint64_t )( p[2] ) << 16) |
+         (( uint64_t )( p[3] ) << 24) |
+         (( uint64_t )( p[4] ) << 32) |
+         (( uint64_t )( p[5] ) << 40) |
+         (( uint64_t )( p[6] ) << 48) |
+         (( uint64_t )( p[7] ) << 56) ;
+#endif
+}
+
+static BLAKE2_INLINE uint16_t load16( const void *src )
+{
+#if defined(NATIVE_LITTLE_ENDIAN)
+  uint16_t w;
+  memcpy(&w, src, sizeof w);
+  return w;
+#else
+  const uint8_t *p = ( const uint8_t * )src;
+  return ( uint16_t )((( uint32_t )( p[0] ) <<  0) |
+                      (( uint32_t )( p[1] ) <<  8));
+#endif
+}
+
+static BLAKE2_INLINE void store16( void *dst, uint16_t w )
+{
+#if defined(NATIVE_LITTLE_ENDIAN)
+  memcpy(dst, &w, sizeof w);
+#else
+  uint8_t *p = ( uint8_t * )dst;
+  *p++ = ( uint8_t )w; w >>= 8;
+  *p++ = ( uint8_t )w;
+#endif
+}
+
+static BLAKE2_INLINE void store32( void *dst, uint32_t w )
+{
+#if defined(NATIVE_LITTLE_ENDIAN)
+  memcpy(dst, &w, sizeof w);
+#else
+  uint8_t *p = ( uint8_t * )dst;
+  p[0] = (uint8_t)(w >>  0);
+  p[1] = (uint8_t)(w >>  8);
+  p[2] = (uint8_t)(w >> 16);
+  p[3] = (uint8_t)(w >> 24);
+#endif
+}
+
+static BLAKE2_INLINE void store64( void *dst, uint64_t w )
+{
+#if defined(NATIVE_LITTLE_ENDIAN)
+  memcpy(dst, &w, sizeof w);
+#else
+  uint8_t *p = ( uint8_t * )dst;
+  p[0] = (uint8_t)(w >>  0);
+  p[1] = (uint8_t)(w >>  8);
+  p[2] = (uint8_t)(w >> 16);
+  p[3] = (uint8_t)(w >> 24);
+  p[4] = (uint8_t)(w >> 32);
+  p[5] = (uint8_t)(w >> 40);
+  p[6] = (uint8_t)(w >> 48);
+  p[7] = (uint8_t)(w >> 56);
+#endif
+}
+
+static BLAKE2_INLINE uint64_t load48( const void *src )
+{
+  const uint8_t *p = ( const uint8_t * )src;
+  return (( uint64_t )( p[0] ) <<  0) |
+         (( uint64_t )( p[1] ) <<  8) |
+         (( uint64_t )( p[2] ) << 16) |
+         (( uint64_t )( p[3] ) << 24) |
+         (( uint64_t )( p[4] ) << 32) |
+         (( uint64_t )( p[5] ) << 40) ;
+}
+
+static BLAKE2_INLINE void store48( void *dst, uint64_t w )
+{
+  uint8_t *p = ( uint8_t * )dst;
+  p[0] = (uint8_t)(w >>  0);
+  p[1] = (uint8_t)(w >>  8);
+  p[2] = (uint8_t)(w >> 16);
+  p[3] = (uint8_t)(w >> 24);
+  p[4] = (uint8_t)(w >> 32);
+  p[5] = (uint8_t)(w >> 40);
+}
+
+static BLAKE2_INLINE uint32_t rotr32( const uint32_t w, const unsigned c )
+{
+  return ( w >> c ) | ( w << ( 32 - c ) );
+}
+
+static BLAKE2_INLINE uint64_t rotr64( const uint64_t w, const unsigned c )
+{
+  return ( w >> c ) | ( w << ( 64 - c ) );
+}
+
+/* prevents compiler optimizing out memset() */
+static BLAKE2_INLINE void secure_zero_memory(void *v, size_t n)
+{
+  static void *(*const volatile memset_v)(void *, int, size_t) = &memset;
+  memset_v(v, 0, n);
+}
+
+#endif
diff --git a/Utilities/cmlibarchive/libarchive/archive_blake2s_ref.c b/Utilities/cmlibarchive/libarchive/archive_blake2s_ref.c
new file mode 100644
index 0000000..d92ffd0
--- /dev/null
+++ b/Utilities/cmlibarchive/libarchive/archive_blake2s_ref.c
@@ -0,0 +1,367 @@
+/*
+   BLAKE2 reference source code package - reference C implementations
+
+   Copyright 2012, Samuel Neves <sneves@dei.uc.pt>.  You may use this under the
+   terms of the CC0, the OpenSSL Licence, or the Apache Public License 2.0, at
+   your option.  The terms of these licenses can be found at:
+
+   - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0
+   - OpenSSL license   : https://www.openssl.org/source/license.html
+   - Apache 2.0        : http://www.apache.org/licenses/LICENSE-2.0
+
+   More information about the BLAKE2 hash function can be found at
+   https://blake2.net.
+*/
+
+#include <stdint.h>
+#include <string.h>
+#include <stdio.h>
+
+#include "archive_blake2.h"
+#include "archive_blake2_impl.h"
+
+static const uint32_t blake2s_IV[8] =
+{
+  0x6A09E667UL, 0xBB67AE85UL, 0x3C6EF372UL, 0xA54FF53AUL,
+  0x510E527FUL, 0x9B05688CUL, 0x1F83D9ABUL, 0x5BE0CD19UL
+};
+
+static const uint8_t blake2s_sigma[10][16] =
+{
+  {  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15 } ,
+  { 14, 10,  4,  8,  9, 15, 13,  6,  1, 12,  0,  2, 11,  7,  5,  3 } ,
+  { 11,  8, 12,  0,  5,  2, 15, 13, 10, 14,  3,  6,  7,  1,  9,  4 } ,
+  {  7,  9,  3,  1, 13, 12, 11, 14,  2,  6,  5, 10,  4,  0, 15,  8 } ,
+  {  9,  0,  5,  7,  2,  4, 10, 15, 14,  1, 11, 12,  6,  8,  3, 13 } ,
+  {  2, 12,  6, 10,  0, 11,  8,  3,  4, 13,  7,  5, 15, 14,  1,  9 } ,
+  { 12,  5,  1, 15, 14, 13,  4, 10,  0,  7,  6,  3,  9,  2,  8, 11 } ,
+  { 13, 11,  7, 14, 12,  1,  3,  9,  5,  0, 15,  4,  8,  6,  2, 10 } ,
+  {  6, 15, 14,  9, 11,  3,  0,  8, 12,  2, 13,  7,  1,  4, 10,  5 } ,
+  { 10,  2,  8,  4,  7,  6,  1,  5, 15, 11,  9, 14,  3, 12, 13 , 0 } ,
+};
+
+static void blake2s_set_lastnode( blake2s_state *S )
+{
+  S->f[1] = (uint32_t)-1;
+}
+
+/* Some helper functions, not necessarily useful */
+static int blake2s_is_lastblock( const blake2s_state *S )
+{
+  return S->f[0] != 0;
+}
+
+static void blake2s_set_lastblock( blake2s_state *S )
+{
+  if( S->last_node ) blake2s_set_lastnode( S );
+
+  S->f[0] = (uint32_t)-1;
+}
+
+static void blake2s_increment_counter( blake2s_state *S, const uint32_t inc )
+{
+  S->t[0] += inc;
+  S->t[1] += ( S->t[0] < inc );
+}
+
+static void blake2s_init0( blake2s_state *S )
+{
+  size_t i;
+  memset( S, 0, sizeof( blake2s_state ) );
+
+  for( i = 0; i < 8; ++i ) S->h[i] = blake2s_IV[i];
+}
+
+/* init2 xors IV with input parameter block */
+int blake2s_init_param( blake2s_state *S, const blake2s_param *P )
+{
+  const unsigned char *p = ( const unsigned char * )( P );
+  size_t i;
+
+  blake2s_init0( S );
+
+  /* IV XOR ParamBlock */
+  for( i = 0; i < 8; ++i )
+    S->h[i] ^= load32( &p[i * 4] );
+
+  S->outlen = P->digest_length;
+  return 0;
+}
+
+
+/* Sequential blake2s initialization */
+int blake2s_init( blake2s_state *S, size_t outlen )
+{
+  blake2s_param P[1];
+
+  /* Move interval verification here? */
+  if ( ( !outlen ) || ( outlen > BLAKE2S_OUTBYTES ) ) return -1;
+
+  P->digest_length = (uint8_t)outlen;
+  P->key_length    = 0;
+  P->fanout        = 1;
+  P->depth         = 1;
+  store32( &P->leaf_length, 0 );
+  store32( &P->node_offset, 0 );
+  store16( &P->xof_length, 0 );
+  P->node_depth    = 0;
+  P->inner_length  = 0;
+  /* memset(P->reserved, 0, sizeof(P->reserved) ); */
+  memset( P->salt,     0, sizeof( P->salt ) );
+  memset( P->personal, 0, sizeof( P->personal ) );
+  return blake2s_init_param( S, P );
+}
+
+int blake2s_init_key( blake2s_state *S, size_t outlen, const void *key, size_t keylen )
+{
+  blake2s_param P[1];
+
+  if ( ( !outlen ) || ( outlen > BLAKE2S_OUTBYTES ) ) return -1;
+
+  if ( !key || !keylen || keylen > BLAKE2S_KEYBYTES ) return -1;
+
+  P->digest_length = (uint8_t)outlen;
+  P->key_length    = (uint8_t)keylen;
+  P->fanout        = 1;
+  P->depth         = 1;
+  store32( &P->leaf_length, 0 );
+  store32( &P->node_offset, 0 );
+  store16( &P->xof_length, 0 );
+  P->node_depth    = 0;
+  P->inner_length  = 0;
+  /* memset(P->reserved, 0, sizeof(P->reserved) ); */
+  memset( P->salt,     0, sizeof( P->salt ) );
+  memset( P->personal, 0, sizeof( P->personal ) );
+
+  if( blake2s_init_param( S, P ) < 0 ) return -1;
+
+  {
+    uint8_t block[BLAKE2S_BLOCKBYTES];
+    memset( block, 0, BLAKE2S_BLOCKBYTES );
+    memcpy( block, key, keylen );
+    blake2s_update( S, block, BLAKE2S_BLOCKBYTES );
+    secure_zero_memory( block, BLAKE2S_BLOCKBYTES ); /* Burn the key from stack */
+  }
+  return 0;
+}
+
+#define G(r,i,a,b,c,d)                      \
+  do {                                      \
+    a = a + b + m[blake2s_sigma[r][2*i+0]]; \
+    d = rotr32(d ^ a, 16);                  \
+    c = c + d;                              \
+    b = rotr32(b ^ c, 12);                  \
+    a = a + b + m[blake2s_sigma[r][2*i+1]]; \
+    d = rotr32(d ^ a, 8);                   \
+    c = c + d;                              \
+    b = rotr32(b ^ c, 7);                   \
+  } while(0)
+
+#define ROUND(r)                    \
+  do {                              \
+    G(r,0,v[ 0],v[ 4],v[ 8],v[12]); \
+    G(r,1,v[ 1],v[ 5],v[ 9],v[13]); \
+    G(r,2,v[ 2],v[ 6],v[10],v[14]); \
+    G(r,3,v[ 3],v[ 7],v[11],v[15]); \
+    G(r,4,v[ 0],v[ 5],v[10],v[15]); \
+    G(r,5,v[ 1],v[ 6],v[11],v[12]); \
+    G(r,6,v[ 2],v[ 7],v[ 8],v[13]); \
+    G(r,7,v[ 3],v[ 4],v[ 9],v[14]); \
+  } while(0)
+
+static void blake2s_compress( blake2s_state *S, const uint8_t in[BLAKE2S_BLOCKBYTES] )
+{
+  uint32_t m[16];
+  uint32_t v[16];
+  size_t i;
+
+  for( i = 0; i < 16; ++i ) {
+    m[i] = load32( in + i * sizeof( m[i] ) );
+  }
+
+  for( i = 0; i < 8; ++i ) {
+    v[i] = S->h[i];
+  }
+
+  v[ 8] = blake2s_IV[0];
+  v[ 9] = blake2s_IV[1];
+  v[10] = blake2s_IV[2];
+  v[11] = blake2s_IV[3];
+  v[12] = S->t[0] ^ blake2s_IV[4];
+  v[13] = S->t[1] ^ blake2s_IV[5];
+  v[14] = S->f[0] ^ blake2s_IV[6];
+  v[15] = S->f[1] ^ blake2s_IV[7];
+
+  ROUND( 0 );
+  ROUND( 1 );
+  ROUND( 2 );
+  ROUND( 3 );
+  ROUND( 4 );
+  ROUND( 5 );
+  ROUND( 6 );
+  ROUND( 7 );
+  ROUND( 8 );
+  ROUND( 9 );
+
+  for( i = 0; i < 8; ++i ) {
+    S->h[i] = S->h[i] ^ v[i] ^ v[i + 8];
+  }
+}
+
+#undef G
+#undef ROUND
+
+int blake2s_update( blake2s_state *S, const void *pin, size_t inlen )
+{
+  const unsigned char * in = (const unsigned char *)pin;
+  if( inlen > 0 )
+  {
+    size_t left = S->buflen;
+    size_t fill = BLAKE2S_BLOCKBYTES - left;
+    if( inlen > fill )
+    {
+      S->buflen = 0;
+      memcpy( S->buf + left, in, fill ); /* Fill buffer */
+      blake2s_increment_counter( S, BLAKE2S_BLOCKBYTES );
+      blake2s_compress( S, S->buf ); /* Compress */
+      in += fill; inlen -= fill;
+      while(inlen > BLAKE2S_BLOCKBYTES) {
+        blake2s_increment_counter(S, BLAKE2S_BLOCKBYTES);
+        blake2s_compress( S, in );
+        in += BLAKE2S_BLOCKBYTES;
+        inlen -= BLAKE2S_BLOCKBYTES;
+      }
+    }
+    memcpy( S->buf + S->buflen, in, inlen );
+    S->buflen += inlen;
+  }
+  return 0;
+}
+
+int blake2s_final( blake2s_state *S, void *out, size_t outlen )
+{
+  uint8_t buffer[BLAKE2S_OUTBYTES] = {0};
+  size_t i;
+
+  if( out == NULL || outlen < S->outlen )
+    return -1;
+
+  if( blake2s_is_lastblock( S ) )
+    return -1;
+
+  blake2s_increment_counter( S, ( uint32_t )S->buflen );
+  blake2s_set_lastblock( S );
+  memset( S->buf + S->buflen, 0, BLAKE2S_BLOCKBYTES - S->buflen ); /* Padding */
+  blake2s_compress( S, S->buf );
+
+  for( i = 0; i < 8; ++i ) /* Output full hash to temp buffer */
+    store32( buffer + sizeof( S->h[i] ) * i, S->h[i] );
+
+  memcpy( out, buffer, outlen );
+  secure_zero_memory(buffer, sizeof(buffer));
+  return 0;
+}
+
+int blake2s( void *out, size_t outlen, const void *in, size_t inlen, const void *key, size_t keylen )
+{
+  blake2s_state S[1];
+
+  /* Verify parameters */
+  if ( NULL == in && inlen > 0 ) return -1;
+
+  if ( NULL == out ) return -1;
+
+  if ( NULL == key && keylen > 0) return -1;
+
+  if( !outlen || outlen > BLAKE2S_OUTBYTES ) return -1;
+
+  if( keylen > BLAKE2S_KEYBYTES ) return -1;
+
+  if( keylen > 0 )
+  {
+    if( blake2s_init_key( S, outlen, key, keylen ) < 0 ) return -1;
+  }
+  else
+  {
+    if( blake2s_init( S, outlen ) < 0 ) return -1;
+  }
+
+  blake2s_update( S, ( const uint8_t * )in, inlen );
+  blake2s_final( S, out, outlen );
+  return 0;
+}
+
+#if defined(SUPERCOP)
+int crypto_hash( unsigned char *out, unsigned char *in, unsigned long long inlen )
+{
+  return blake2s( out, BLAKE2S_OUTBYTES, in, inlen, NULL, 0 );
+}
+#endif
+
+#if defined(BLAKE2S_SELFTEST)
+#include <string.h>
+#include "blake2-kat.h"
+int main( void )
+{
+  uint8_t key[BLAKE2S_KEYBYTES];
+  uint8_t buf[BLAKE2_KAT_LENGTH];
+  size_t i, step;
+
+  for( i = 0; i < BLAKE2S_KEYBYTES; ++i )
+    key[i] = ( uint8_t )i;
+
+  for( i = 0; i < BLAKE2_KAT_LENGTH; ++i )
+    buf[i] = ( uint8_t )i;
+
+  /* Test simple API */
+  for( i = 0; i < BLAKE2_KAT_LENGTH; ++i )
+  {
+    uint8_t hash[BLAKE2S_OUTBYTES];
+    blake2s( hash, BLAKE2S_OUTBYTES, buf, i, key, BLAKE2S_KEYBYTES );
+
+    if( 0 != memcmp( hash, blake2s_keyed_kat[i], BLAKE2S_OUTBYTES ) )
+    {
+      goto fail;
+    }
+  }
+
+  /* Test streaming API */
+  for(step = 1; step < BLAKE2S_BLOCKBYTES; ++step) {
+    for (i = 0; i < BLAKE2_KAT_LENGTH; ++i) {
+      uint8_t hash[BLAKE2S_OUTBYTES];
+      blake2s_state S;
+      uint8_t * p = buf;
+      size_t mlen = i;
+      int err = 0;
+
+      if( (err = blake2s_init_key(&S, BLAKE2S_OUTBYTES, key, BLAKE2S_KEYBYTES)) < 0 ) {
+        goto fail;
+      }
+
+      while (mlen >= step) {
+        if ( (err = blake2s_update(&S, p, step)) < 0 ) {
+          goto fail;
+        }
+        mlen -= step;
+        p += step;
+      }
+      if ( (err = blake2s_update(&S, p, mlen)) < 0) {
+        goto fail;
+      }
+      if ( (err = blake2s_final(&S, hash, BLAKE2S_OUTBYTES)) < 0) {
+        goto fail;
+      }
+
+      if (0 != memcmp(hash, blake2s_keyed_kat[i], BLAKE2S_OUTBYTES)) {
+        goto fail;
+      }
+    }
+  }
+
+  puts( "ok" );
+  return 0;
+fail:
+  puts("error");
+  return -1;
+}
+#endif
diff --git a/Utilities/cmlibarchive/libarchive/archive_blake2sp_ref.c b/Utilities/cmlibarchive/libarchive/archive_blake2sp_ref.c
new file mode 100644
index 0000000..aef1010
--- /dev/null
+++ b/Utilities/cmlibarchive/libarchive/archive_blake2sp_ref.c
@@ -0,0 +1,359 @@
+/*
+   BLAKE2 reference source code package - reference C implementations
+
+   Copyright 2012, Samuel Neves <sneves@dei.uc.pt>.  You may use this under the
+   terms of the CC0, the OpenSSL Licence, or the Apache Public License 2.0, at
+   your option.  The terms of these licenses can be found at:
+
+   - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0
+   - OpenSSL license   : https://www.openssl.org/source/license.html
+   - Apache 2.0        : http://www.apache.org/licenses/LICENSE-2.0
+
+   More information about the BLAKE2 hash function can be found at
+   https://blake2.net.
+*/
+
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+
+#if defined(_OPENMP)
+#include <omp.h>
+#endif
+
+#include "archive_blake2.h"
+#include "archive_blake2_impl.h"
+
+#define PARALLELISM_DEGREE 8
+
+/*
+  blake2sp_init_param defaults to setting the expecting output length
+  from the digest_length parameter block field.
+
+  In some cases, however, we do not want this, as the output length
+  of these instances is given by inner_length instead.
+*/
+static int blake2sp_init_leaf_param( blake2s_state *S, const blake2s_param *P )
+{
+  int err = blake2s_init_param(S, P);
+  S->outlen = P->inner_length;
+  return err;
+}
+
+static int blake2sp_init_leaf( blake2s_state *S, size_t outlen, size_t keylen, uint32_t offset )
+{
+  blake2s_param P[1];
+  P->digest_length = (uint8_t)outlen;
+  P->key_length = (uint8_t)keylen;
+  P->fanout = PARALLELISM_DEGREE;
+  P->depth = 2;
+  store32( &P->leaf_length, 0 );
+  store32( &P->node_offset, offset );
+  store16( &P->xof_length, 0 );
+  P->node_depth = 0;
+  P->inner_length = BLAKE2S_OUTBYTES;
+  memset( P->salt, 0, sizeof( P->salt ) );
+  memset( P->personal, 0, sizeof( P->personal ) );
+  return blake2sp_init_leaf_param( S, P );
+}
+
+static int blake2sp_init_root( blake2s_state *S, size_t outlen, size_t keylen )
+{
+  blake2s_param P[1];
+  P->digest_length = (uint8_t)outlen;
+  P->key_length = (uint8_t)keylen;
+  P->fanout = PARALLELISM_DEGREE;
+  P->depth = 2;
+  store32( &P->leaf_length, 0 );
+  store32( &P->node_offset, 0 );
+  store16( &P->xof_length, 0 );
+  P->node_depth = 1;
+  P->inner_length = BLAKE2S_OUTBYTES;
+  memset( P->salt, 0, sizeof( P->salt ) );
+  memset( P->personal, 0, sizeof( P->personal ) );
+  return blake2s_init_param( S, P );
+}
+
+
+int blake2sp_init( blake2sp_state *S, size_t outlen )
+{
+  size_t i;
+
+  if( !outlen || outlen > BLAKE2S_OUTBYTES ) return -1;
+
+  memset( S->buf, 0, sizeof( S->buf ) );
+  S->buflen = 0;
+  S->outlen = outlen;
+
+  if( blake2sp_init_root( S->R, outlen, 0 ) < 0 )
+    return -1;
+
+  for( i = 0; i < PARALLELISM_DEGREE; ++i )
+    if( blake2sp_init_leaf( S->S[i], outlen, 0, (uint32_t)i ) < 0 ) return -1;
+
+  S->R->last_node = 1;
+  S->S[PARALLELISM_DEGREE - 1]->last_node = 1;
+  return 0;
+}
+
+int blake2sp_init_key( blake2sp_state *S, size_t outlen, const void *key, size_t keylen )
+{
+  size_t i;
+
+  if( !outlen || outlen > BLAKE2S_OUTBYTES ) return -1;
+
+  if( !key || !keylen || keylen > BLAKE2S_KEYBYTES ) return -1;
+
+  memset( S->buf, 0, sizeof( S->buf ) );
+  S->buflen = 0;
+  S->outlen = outlen;
+
+  if( blake2sp_init_root( S->R, outlen, keylen ) < 0 )
+    return -1;
+
+  for( i = 0; i < PARALLELISM_DEGREE; ++i )
+    if( blake2sp_init_leaf( S->S[i], outlen, keylen, (uint32_t)i ) < 0 ) return -1;
+
+  S->R->last_node = 1;
+  S->S[PARALLELISM_DEGREE - 1]->last_node = 1;
+  {
+    uint8_t block[BLAKE2S_BLOCKBYTES];
+    memset( block, 0, BLAKE2S_BLOCKBYTES );
+    memcpy( block, key, keylen );
+
+    for( i = 0; i < PARALLELISM_DEGREE; ++i )
+      blake2s_update( S->S[i], block, BLAKE2S_BLOCKBYTES );
+
+    secure_zero_memory( block, BLAKE2S_BLOCKBYTES ); /* Burn the key from stack */
+  }
+  return 0;
+}
+
+
+int blake2sp_update( blake2sp_state *S, const void *pin, size_t inlen )
+{
+  const unsigned char * in = (const unsigned char *)pin;
+  size_t left = S->buflen;
+  size_t fill = sizeof( S->buf ) - left;
+  size_t i;
+
+  if( left && inlen >= fill )
+  {
+    memcpy( S->buf + left, in, fill );
+
+    for( i = 0; i < PARALLELISM_DEGREE; ++i )
+      blake2s_update( S->S[i], S->buf + i * BLAKE2S_BLOCKBYTES, BLAKE2S_BLOCKBYTES );
+
+    in += fill;
+    inlen -= fill;
+    left = 0;
+  }
+
+#if defined(_OPENMP)
+  #pragma omp parallel shared(S), num_threads(PARALLELISM_DEGREE)
+#else
+  for( i = 0; i < PARALLELISM_DEGREE; ++i )
+#endif
+  {
+#if defined(_OPENMP)
+    size_t      i = omp_get_thread_num();
+#endif
+    size_t inlen__ = inlen;
+    const unsigned char *in__ = ( const unsigned char * )in;
+    in__ += i * BLAKE2S_BLOCKBYTES;
+
+    while( inlen__ >= PARALLELISM_DEGREE * BLAKE2S_BLOCKBYTES )
+    {
+      blake2s_update( S->S[i], in__, BLAKE2S_BLOCKBYTES );
+      in__ += PARALLELISM_DEGREE * BLAKE2S_BLOCKBYTES;
+      inlen__ -= PARALLELISM_DEGREE * BLAKE2S_BLOCKBYTES;
+    }
+  }
+
+  in += inlen - inlen % ( PARALLELISM_DEGREE * BLAKE2S_BLOCKBYTES );
+  inlen %= PARALLELISM_DEGREE * BLAKE2S_BLOCKBYTES;
+
+  if( inlen > 0 )
+    memcpy( S->buf + left, in, inlen );
+
+  S->buflen = left + inlen;
+  return 0;
+}
+
+
+int blake2sp_final( blake2sp_state *S, void *out, size_t outlen )
+{
+  uint8_t hash[PARALLELISM_DEGREE][BLAKE2S_OUTBYTES];
+  size_t i;
+
+  if(out == NULL || outlen < S->outlen) {
+    return -1;
+  }
+
+  for( i = 0; i < PARALLELISM_DEGREE; ++i )
+  {
+    if( S->buflen > i * BLAKE2S_BLOCKBYTES )
+    {
+      size_t left = S->buflen - i * BLAKE2S_BLOCKBYTES;
+
+      if( left > BLAKE2S_BLOCKBYTES ) left = BLAKE2S_BLOCKBYTES;
+
+      blake2s_update( S->S[i], S->buf + i * BLAKE2S_BLOCKBYTES, left );
+    }
+
+    blake2s_final( S->S[i], hash[i], BLAKE2S_OUTBYTES );
+  }
+
+  for( i = 0; i < PARALLELISM_DEGREE; ++i )
+    blake2s_update( S->R, hash[i], BLAKE2S_OUTBYTES );
+
+  return blake2s_final( S->R, out, S->outlen );
+}
+
+
+int blake2sp( void *out, size_t outlen, const void *in, size_t inlen, const void *key, size_t keylen )
+{
+  uint8_t hash[PARALLELISM_DEGREE][BLAKE2S_OUTBYTES];
+  blake2s_state S[PARALLELISM_DEGREE][1];
+  blake2s_state FS[1];
+  size_t i;
+
+  /* Verify parameters */
+  if ( NULL == in && inlen > 0 ) return -1;
+
+  if ( NULL == out ) return -1;
+
+  if ( NULL == key && keylen > 0) return -1;
+
+  if( !outlen || outlen > BLAKE2S_OUTBYTES ) return -1;
+
+  if( keylen > BLAKE2S_KEYBYTES ) return -1;
+
+  for( i = 0; i < PARALLELISM_DEGREE; ++i )
+    if( blake2sp_init_leaf( S[i], outlen, keylen, (uint32_t)i ) < 0 ) return -1;
+
+  S[PARALLELISM_DEGREE - 1]->last_node = 1; /* mark last node */
+
+  if( keylen > 0 )
+  {
+    uint8_t block[BLAKE2S_BLOCKBYTES];
+    memset( block, 0, BLAKE2S_BLOCKBYTES );
+    memcpy( block, key, keylen );
+
+    for( i = 0; i < PARALLELISM_DEGREE; ++i )
+      blake2s_update( S[i], block, BLAKE2S_BLOCKBYTES );
+
+    secure_zero_memory( block, BLAKE2S_BLOCKBYTES ); /* Burn the key from stack */
+  }
+
+#if defined(_OPENMP)
+  #pragma omp parallel shared(S,hash), num_threads(PARALLELISM_DEGREE)
+#else
+
+  for( i = 0; i < PARALLELISM_DEGREE; ++i )
+#endif
+  {
+#if defined(_OPENMP)
+    size_t      i = omp_get_thread_num();
+#endif
+    size_t inlen__ = inlen;
+    const unsigned char *in__ = ( const unsigned char * )in;
+    in__ += i * BLAKE2S_BLOCKBYTES;
+
+    while( inlen__ >= PARALLELISM_DEGREE * BLAKE2S_BLOCKBYTES )
+    {
+      blake2s_update( S[i], in__, BLAKE2S_BLOCKBYTES );
+      in__ += PARALLELISM_DEGREE * BLAKE2S_BLOCKBYTES;
+      inlen__ -= PARALLELISM_DEGREE * BLAKE2S_BLOCKBYTES;
+    }
+
+    if( inlen__ > i * BLAKE2S_BLOCKBYTES )
+    {
+      const size_t left = inlen__ - i * BLAKE2S_BLOCKBYTES;
+      const size_t len = left <= BLAKE2S_BLOCKBYTES ? left : BLAKE2S_BLOCKBYTES;
+      blake2s_update( S[i], in__, len );
+    }
+
+    blake2s_final( S[i], hash[i], BLAKE2S_OUTBYTES );
+  }
+
+  if( blake2sp_init_root( FS, outlen, keylen ) < 0 )
+    return -1;
+
+  FS->last_node = 1;
+
+  for( i = 0; i < PARALLELISM_DEGREE; ++i )
+    blake2s_update( FS, hash[i], BLAKE2S_OUTBYTES );
+
+  return blake2s_final( FS, out, outlen );
+}
+
+
+
+#if defined(BLAKE2SP_SELFTEST)
+#include <string.h>
+#include "blake2-kat.h"
+int main( void )
+{
+  uint8_t key[BLAKE2S_KEYBYTES];
+  uint8_t buf[BLAKE2_KAT_LENGTH];
+  size_t i, step;
+
+  for( i = 0; i < BLAKE2S_KEYBYTES; ++i )
+    key[i] = ( uint8_t )i;
+
+  for( i = 0; i < BLAKE2_KAT_LENGTH; ++i )
+    buf[i] = ( uint8_t )i;
+
+  /* Test simple API */
+  for( i = 0; i < BLAKE2_KAT_LENGTH; ++i )
+  {
+    uint8_t hash[BLAKE2S_OUTBYTES];
+    blake2sp( hash, BLAKE2S_OUTBYTES, buf, i, key, BLAKE2S_KEYBYTES );
+
+    if( 0 != memcmp( hash, blake2sp_keyed_kat[i], BLAKE2S_OUTBYTES ) )
+    {
+      goto fail;
+    }
+  }
+
+  /* Test streaming API */
+  for(step = 1; step < BLAKE2S_BLOCKBYTES; ++step) {
+    for (i = 0; i < BLAKE2_KAT_LENGTH; ++i) {
+      uint8_t hash[BLAKE2S_OUTBYTES];
+      blake2sp_state S;
+      uint8_t * p = buf;
+      size_t mlen = i;
+      int err = 0;
+
+      if( (err = blake2sp_init_key(&S, BLAKE2S_OUTBYTES, key, BLAKE2S_KEYBYTES)) < 0 ) {
+        goto fail;
+      }
+
+      while (mlen >= step) {
+        if ( (err = blake2sp_update(&S, p, step)) < 0 ) {
+          goto fail;
+        }
+        mlen -= step;
+        p += step;
+      }
+      if ( (err = blake2sp_update(&S, p, mlen)) < 0) {
+        goto fail;
+      }
+      if ( (err = blake2sp_final(&S, hash, BLAKE2S_OUTBYTES)) < 0) {
+        goto fail;
+      }
+
+      if (0 != memcmp(hash, blake2sp_keyed_kat[i], BLAKE2S_OUTBYTES)) {
+        goto fail;
+      }
+    }
+  }
+
+  puts( "ok" );
+  return 0;
+fail:
+  puts("error");
+  return -1;
+}
+#endif
diff --git a/Utilities/cmlibarchive/libarchive/archive_cmdline_private.h b/Utilities/cmlibarchive/libarchive/archive_cmdline_private.h
index 4e409e8..57a1949 100644
--- a/Utilities/cmlibarchive/libarchive/archive_cmdline_private.h
+++ b/Utilities/cmlibarchive/libarchive/archive_cmdline_private.h
@@ -25,15 +25,15 @@
  * $FreeBSD$
  */
 
+#ifndef ARCHIVE_CMDLINE_PRIVATE_H
+#define ARCHIVE_CMDLINE_PRIVATE_H
+
 #ifndef __LIBARCHIVE_BUILD
 #ifndef __LIBARCHIVE_TEST
 #error This header is only to be used internally to libarchive.
 #endif
 #endif
 
-#ifndef ARCHIVE_CMDLINE_PRIVATE_H
-#define ARCHIVE_CMDLINE_PRIVATE_H
-
 struct archive_cmdline {
         char            *path;
         char            **argv;
diff --git a/Utilities/cmlibarchive/libarchive/archive_crc32.h b/Utilities/cmlibarchive/libarchive/archive_crc32.h
index cd633af..4f1aed3 100644
--- a/Utilities/cmlibarchive/libarchive/archive_crc32.h
+++ b/Utilities/cmlibarchive/libarchive/archive_crc32.h
@@ -25,6 +25,9 @@
  * $FreeBSD: head/lib/libarchive/archive_crc32.h 201102 2009-12-28 03:11:36Z kientzle $
  */
 
+#ifndef ARCHIVE_CRC32_H
+#define ARCHIVE_CRC32_H
+
 #ifndef __LIBARCHIVE_BUILD
 #error This header is only to be used internally to libarchive.
 #endif
@@ -76,3 +79,5 @@
 		crc = crc_tbl[(crc ^ *p++) & 0xff] ^ (crc >> 8);
 	return (crc ^ 0xffffffffUL);
 }
+
+#endif
diff --git a/Utilities/cmlibarchive/libarchive/archive_cryptor.c b/Utilities/cmlibarchive/libarchive/archive_cryptor.c
index 71967c9..8ab2b09 100644
--- a/Utilities/cmlibarchive/libarchive/archive_cryptor.c
+++ b/Utilities/cmlibarchive/libarchive/archive_cryptor.c
@@ -85,6 +85,35 @@
 	return (BCRYPT_SUCCESS(status)) ? 0: -1;
 }
 
+#elif defined(HAVE_LIBMBEDCRYPTO) && defined(HAVE_MBEDTLS_PKCS5_H)
+
+static int
+pbkdf2_sha1(const char *pw, size_t pw_len, const uint8_t *salt,
+    size_t salt_len, unsigned rounds, uint8_t *derived_key,
+    size_t derived_key_len)
+{
+	mbedtls_md_context_t ctx;
+	const mbedtls_md_info_t *info;
+	int ret;
+
+	mbedtls_md_init(&ctx);
+	info = mbedtls_md_info_from_type(MBEDTLS_MD_SHA1);
+	if (info == NULL) {
+		mbedtls_md_free(&ctx);
+		return (-1);
+	}
+	ret = mbedtls_md_setup(&ctx, info, 1);
+	if (ret != 0) {
+		mbedtls_md_free(&ctx);
+		return (-1);
+	}
+	ret = mbedtls_pkcs5_pbkdf2_hmac(&ctx, (const unsigned char *)pw,
+	    pw_len, salt, salt_len, rounds, derived_key_len, derived_key);
+
+	mbedtls_md_free(&ctx);
+	return (ret);
+}
+
 #elif defined(HAVE_LIBNETTLE) && defined(HAVE_NETTLE_PBKDF2_H)
 
 static int
@@ -269,6 +298,39 @@
 	return 0;
 }
 
+#elif defined(HAVE_LIBMBEDCRYPTO) && defined(HAVE_MBEDTLS_AES_H)
+
+static int
+aes_ctr_init(archive_crypto_ctx *ctx, const uint8_t *key, size_t key_len)
+{
+	mbedtls_aes_init(&ctx->ctx);
+	ctx->key_len = key_len;
+	memcpy(ctx->key, key, key_len);
+	memset(ctx->nonce, 0, sizeof(ctx->nonce));
+	ctx->encr_pos = AES_BLOCK_SIZE;
+	return 0;
+}
+
+static int
+aes_ctr_encrypt_counter(archive_crypto_ctx *ctx)
+{
+	if (mbedtls_aes_setkey_enc(&ctx->ctx, ctx->key,
+	    ctx->key_len * 8) != 0)
+		return (-1);
+	if (mbedtls_aes_crypt_ecb(&ctx->ctx, MBEDTLS_AES_ENCRYPT, ctx->nonce,
+	    ctx->encr_buf) != 0)
+		return (-1);
+	return 0;
+}
+
+static int
+aes_ctr_release(archive_crypto_ctx *ctx)
+{
+	mbedtls_aes_free(&ctx->ctx);
+	memset(ctx, 0, sizeof(*ctx));
+	return 0;
+}
+
 #elif defined(HAVE_LIBNETTLE) && defined(HAVE_NETTLE_AES_H)
 
 static int
@@ -316,7 +378,14 @@
 	memcpy(ctx->key, key, key_len);
 	memset(ctx->nonce, 0, sizeof(ctx->nonce));
 	ctx->encr_pos = AES_BLOCK_SIZE;
+#if OPENSSL_VERSION_NUMBER  >= 0x10100000L && !defined(LIBRESSL_VERSION_NUMBER)
+	if (!EVP_CIPHER_CTX_reset(ctx->ctx)) {
+		EVP_CIPHER_CTX_free(ctx->ctx);
+		ctx->ctx = NULL;
+	}
+#else
 	EVP_CIPHER_CTX_init(ctx->ctx);
+#endif
 	return 0;
 }
 
diff --git a/Utilities/cmlibarchive/libarchive/archive_cryptor_private.h b/Utilities/cmlibarchive/libarchive/archive_cryptor_private.h
index b975922..64a2055 100644
--- a/Utilities/cmlibarchive/libarchive/archive_cryptor_private.h
+++ b/Utilities/cmlibarchive/libarchive/archive_cryptor_private.h
@@ -23,13 +23,12 @@
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
 
-#ifndef __LIBARCHIVE_BUILD
-#error This header is only to be used internally to libarchive.
-#endif
-
 #ifndef ARCHIVE_CRYPTOR_PRIVATE_H_INCLUDED
 #define ARCHIVE_CRYPTOR_PRIVATE_H_INCLUDED
 
+#ifndef __LIBARCHIVE_BUILD
+#error This header is only to be used internally to libarchive.
+#endif
 /*
  * On systems that do not support any recognized crypto libraries,
  * the archive_cryptor.c file will normally define no usable symbols.
@@ -83,6 +82,23 @@
 	unsigned	encr_pos;
 } archive_crypto_ctx;
 
+#elif defined(HAVE_LIBMBEDCRYPTO) && defined(HAVE_MBEDTLS_AES_H)
+#include <mbedtls/aes.h>
+#include <mbedtls/md.h>
+#include <mbedtls/pkcs5.h>
+
+#define AES_MAX_KEY_SIZE 32
+#define AES_BLOCK_SIZE 16
+
+typedef struct {
+	mbedtls_aes_context	ctx;
+	uint8_t		key[AES_MAX_KEY_SIZE];
+	unsigned	key_len;
+	uint8_t		nonce[AES_BLOCK_SIZE];
+	uint8_t		encr_buf[AES_BLOCK_SIZE];
+	unsigned	encr_pos;
+} archive_crypto_ctx;
+
 #elif defined(HAVE_LIBNETTLE) && defined(HAVE_NETTLE_AES_H)
 #if defined(HAVE_NETTLE_PBKDF2_H)
 #include <nettle/pbkdf2.h>
diff --git a/Utilities/cmlibarchive/libarchive/archive_digest.c b/Utilities/cmlibarchive/libarchive/archive_digest.c
index 4153923..34c58ac 100644
--- a/Utilities/cmlibarchive/libarchive/archive_digest.c
+++ b/Utilities/cmlibarchive/libarchive/archive_digest.c
@@ -178,6 +178,40 @@
   return (ARCHIVE_OK);
 }
 
+#elif defined(ARCHIVE_CRYPTO_MD5_MBEDTLS)
+
+static int
+__archive_mbedtls_md5init(archive_md5_ctx *ctx)
+{
+  mbedtls_md5_init(ctx);
+  if (mbedtls_md5_starts_ret(ctx) == 0)
+    return (ARCHIVE_OK);
+  else
+    return (ARCHIVE_FATAL);
+}
+
+static int
+__archive_mbedtls_md5update(archive_md5_ctx *ctx, const void *indata,
+    size_t insize)
+{
+  if (mbedtls_md5_update_ret(ctx, indata, insize) == 0)
+    return (ARCHIVE_OK);
+  else
+    return (ARCHIVE_FATAL);
+}
+
+static int
+__archive_mbedtls_md5final(archive_md5_ctx *ctx, void *md)
+{
+  if (mbedtls_md5_finish_ret(ctx, md) == 0) {
+    mbedtls_md5_free(ctx);
+    return (ARCHIVE_OK);
+  } else {
+    mbedtls_md5_free(ctx);
+    return (ARCHIVE_FATAL);
+  }
+}
+
 #elif defined(ARCHIVE_CRYPTO_MD5_NETTLE)
 
 static int
@@ -335,6 +369,40 @@
   return (ARCHIVE_OK);
 }
 
+#elif defined(ARCHIVE_CRYPTO_RMD160_MBEDTLS)
+
+static int
+__archive_mbedtls_ripemd160init(archive_rmd160_ctx *ctx)
+{
+  mbedtls_ripemd160_init(ctx);
+  if (mbedtls_ripemd160_starts_ret(ctx) == 0)
+    return (ARCHIVE_OK);
+  else
+    return (ARCHIVE_FATAL);
+}
+
+static int
+__archive_mbedtls_ripemd160update(archive_rmd160_ctx *ctx, const void *indata,
+    size_t insize)
+{
+  if (mbedtls_ripemd160_update_ret(ctx, indata, insize) == 0)
+    return (ARCHIVE_OK);
+  else
+    return (ARCHIVE_FATAL);
+}
+
+static int
+__archive_mbedtls_ripemd160final(archive_rmd160_ctx *ctx, void *md)
+{
+  if (mbedtls_ripemd160_finish_ret(ctx, md) == 0) {
+    mbedtls_ripemd160_free(ctx);
+    return (ARCHIVE_OK);
+  } else {
+    mbedtls_ripemd160_free(ctx);
+    return (ARCHIVE_FATAL);
+  }
+}
+
 #elif defined(ARCHIVE_CRYPTO_RMD160_NETTLE)
 
 static int
@@ -491,6 +559,40 @@
   return (ARCHIVE_OK);
 }
 
+#elif defined(ARCHIVE_CRYPTO_SHA1_MBEDTLS)
+
+static int
+__archive_mbedtls_sha1init(archive_sha1_ctx *ctx)
+{
+  mbedtls_sha1_init(ctx);
+  if (mbedtls_sha1_starts_ret(ctx) == 0)
+    return (ARCHIVE_OK);
+  else
+    return (ARCHIVE_FATAL);
+}
+
+static int
+__archive_mbedtls_sha1update(archive_sha1_ctx *ctx, const void *indata,
+    size_t insize)
+{
+  if (mbedtls_sha1_update_ret(ctx, indata, insize) == 0)
+    return (ARCHIVE_OK);
+  else
+    return (ARCHIVE_FATAL);
+}
+
+static int
+__archive_mbedtls_sha1final(archive_sha1_ctx *ctx, void *md)
+{
+  if (mbedtls_sha1_finish_ret(ctx, md) == 0) {
+    mbedtls_sha1_free(ctx);
+    return (ARCHIVE_OK);
+  } else {
+    mbedtls_sha1_free(ctx);
+    return (ARCHIVE_FATAL);
+  }
+}
+
 #elif defined(ARCHIVE_CRYPTO_SHA1_NETTLE)
 
 static int
@@ -720,6 +822,40 @@
   return (ARCHIVE_OK);
 }
 
+#elif defined(ARCHIVE_CRYPTO_SHA256_MBEDTLS)
+
+static int
+__archive_mbedtls_sha256init(archive_sha256_ctx *ctx)
+{
+  mbedtls_sha256_init(ctx);
+  if (mbedtls_sha256_starts_ret(ctx, 0) == 0)
+    return (ARCHIVE_OK);
+  else
+    return (ARCHIVE_FATAL);
+}
+
+static int
+__archive_mbedtls_sha256update(archive_sha256_ctx *ctx, const void *indata,
+    size_t insize)
+{
+  if (mbedtls_sha256_update_ret(ctx, indata, insize) == 0)
+    return (ARCHIVE_OK);
+  else
+    return (ARCHIVE_FATAL);
+}
+
+static int
+__archive_mbedtls_sha256final(archive_sha256_ctx *ctx, void *md)
+{
+  if (mbedtls_sha256_finish_ret(ctx, md) == 0) {
+    mbedtls_sha256_free(ctx);
+    return (ARCHIVE_OK);
+  } else {
+    mbedtls_sha256_free(ctx);
+    return (ARCHIVE_FATAL);
+  }
+}
+
 #elif defined(ARCHIVE_CRYPTO_SHA256_NETTLE)
 
 static int
@@ -921,6 +1057,40 @@
   return (ARCHIVE_OK);
 }
 
+#elif defined(ARCHIVE_CRYPTO_SHA384_MBEDTLS)
+
+static int
+__archive_mbedtls_sha384init(archive_sha384_ctx *ctx)
+{
+  mbedtls_sha512_init(ctx);
+  if (mbedtls_sha512_starts_ret(ctx, 1) == 0)
+    return (ARCHIVE_OK);
+  else
+    return (ARCHIVE_FATAL);
+}
+
+static int
+__archive_mbedtls_sha384update(archive_sha384_ctx *ctx, const void *indata,
+    size_t insize)
+{
+  if (mbedtls_sha512_update_ret(ctx, indata, insize) == 0)
+    return (ARCHIVE_OK);
+  else
+    return (ARCHIVE_FATAL);
+}
+
+static int
+__archive_mbedtls_sha384final(archive_sha384_ctx *ctx, void *md)
+{
+  if (mbedtls_sha512_finish_ret(ctx, md) == 0) {
+    mbedtls_sha512_free(ctx);
+    return (ARCHIVE_OK);
+  } else {
+    mbedtls_sha512_free(ctx);
+    return (ARCHIVE_FATAL);
+  }
+}
+
 #elif defined(ARCHIVE_CRYPTO_SHA384_NETTLE)
 
 static int
@@ -1146,6 +1316,40 @@
   return (ARCHIVE_OK);
 }
 
+#elif defined(ARCHIVE_CRYPTO_SHA512_MBEDTLS)
+
+static int
+__archive_mbedtls_sha512init(archive_sha512_ctx *ctx)
+{
+  mbedtls_sha512_init(ctx);
+  if (mbedtls_sha512_starts_ret(ctx, 0) == 0)
+    return (ARCHIVE_OK);
+  else
+    return (ARCHIVE_FATAL);
+}
+
+static int
+__archive_mbedtls_sha512update(archive_sha512_ctx *ctx, const void *indata,
+    size_t insize)
+{
+  if (mbedtls_sha512_update_ret(ctx, indata, insize) == 0)
+    return (ARCHIVE_OK);
+  else
+    return (ARCHIVE_FATAL);
+}
+
+static int
+__archive_mbedtls_sha512final(archive_sha512_ctx *ctx, void *md)
+{
+  if (mbedtls_sha512_finish_ret(ctx, md) == 0) {
+    mbedtls_sha512_free(ctx);
+    return (ARCHIVE_OK);
+  } else {
+    mbedtls_sha512_free(ctx);
+    return (ARCHIVE_FATAL);
+  }
+}
+
 #elif defined(ARCHIVE_CRYPTO_SHA512_NETTLE)
 
 static int
@@ -1276,6 +1480,10 @@
   &__archive_libsystem_md5init,
   &__archive_libsystem_md5update,
   &__archive_libsystem_md5final,
+#elif defined(ARCHIVE_CRYPTO_MD5_MBEDTLS)
+  &__archive_mbedtls_md5init,
+  &__archive_mbedtls_md5update,
+  &__archive_mbedtls_md5final,
 #elif defined(ARCHIVE_CRYPTO_MD5_NETTLE)
   &__archive_nettle_md5init,
   &__archive_nettle_md5update,
@@ -1303,6 +1511,10 @@
   &__archive_libmd_ripemd160init,
   &__archive_libmd_ripemd160update,
   &__archive_libmd_ripemd160final,
+#elif defined(ARCHIVE_CRYPTO_RMD160_MBEDTLS)
+  &__archive_mbedtls_ripemd160init,
+  &__archive_mbedtls_ripemd160update,
+  &__archive_mbedtls_ripemd160final,
 #elif defined(ARCHIVE_CRYPTO_RMD160_NETTLE)
   &__archive_nettle_ripemd160init,
   &__archive_nettle_ripemd160update,
@@ -1330,6 +1542,10 @@
   &__archive_libsystem_sha1init,
   &__archive_libsystem_sha1update,
   &__archive_libsystem_sha1final,
+#elif defined(ARCHIVE_CRYPTO_SHA1_MBEDTLS)
+  &__archive_mbedtls_sha1init,
+  &__archive_mbedtls_sha1update,
+  &__archive_mbedtls_sha1final,
 #elif defined(ARCHIVE_CRYPTO_SHA1_NETTLE)
   &__archive_nettle_sha1init,
   &__archive_nettle_sha1update,
@@ -1369,6 +1585,10 @@
   &__archive_libsystem_sha256init,
   &__archive_libsystem_sha256update,
   &__archive_libsystem_sha256final,
+#elif defined(ARCHIVE_CRYPTO_SHA256_MBEDTLS)
+  &__archive_mbedtls_sha256init,
+  &__archive_mbedtls_sha256update,
+  &__archive_mbedtls_sha256final,
 #elif defined(ARCHIVE_CRYPTO_SHA256_NETTLE)
   &__archive_nettle_sha256init,
   &__archive_nettle_sha256update,
@@ -1404,6 +1624,10 @@
   &__archive_libsystem_sha384init,
   &__archive_libsystem_sha384update,
   &__archive_libsystem_sha384final,
+#elif defined(ARCHIVE_CRYPTO_SHA384_MBEDTLS)
+  &__archive_mbedtls_sha384init,
+  &__archive_mbedtls_sha384update,
+  &__archive_mbedtls_sha384final,
 #elif defined(ARCHIVE_CRYPTO_SHA384_NETTLE)
   &__archive_nettle_sha384init,
   &__archive_nettle_sha384update,
@@ -1443,6 +1667,10 @@
   &__archive_libsystem_sha512init,
   &__archive_libsystem_sha512update,
   &__archive_libsystem_sha512final
+#elif defined(ARCHIVE_CRYPTO_SHA512_MBEDTLS)
+  &__archive_mbedtls_sha512init,
+  &__archive_mbedtls_sha512update,
+  &__archive_mbedtls_sha512final
 #elif defined(ARCHIVE_CRYPTO_SHA512_NETTLE)
   &__archive_nettle_sha512init,
   &__archive_nettle_sha512update,
diff --git a/Utilities/cmlibarchive/libarchive/archive_digest_private.h b/Utilities/cmlibarchive/libarchive/archive_digest_private.h
index b4fd6ca..15312ee 100644
--- a/Utilities/cmlibarchive/libarchive/archive_digest_private.h
+++ b/Utilities/cmlibarchive/libarchive/archive_digest_private.h
@@ -24,13 +24,12 @@
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
 
+#ifndef ARCHIVE_DIGEST_PRIVATE_H_INCLUDED
+#define ARCHIVE_DIGEST_PRIVATE_H_INCLUDED
+
 #ifndef __LIBARCHIVE_BUILD
 #error This header is only to be used internally to libarchive.
 #endif
-
-#ifndef ARCHIVE_CRYPTO_PRIVATE_H_INCLUDED
-#define ARCHIVE_CRYPTO_PRIVATE_H_INCLUDED
-
 /*
  * Crypto support in various Operating Systems:
  *
@@ -112,6 +111,24 @@
 #include <CommonCrypto/CommonDigest.h>
 #endif
 
+/* mbed TLS crypto headers */
+#if defined(ARCHIVE_CRYPTO_MD5_MBEDTLS)
+#include <mbedtls/md5.h>
+#endif
+#if defined(ARCHIVE_CRYPTO_RMD160_MBEDTLS)
+#include <mbedtls/ripemd160.h>
+#endif
+#if defined(ARCHIVE_CRYPTO_SHA1_MBEDTLS)
+#include <mbedtls/sha1.h>
+#endif
+#if defined(ARCHIVE_CRYPTO_SHA256_MBEDTLS)
+#include <mbedtls/sha256.h>
+#endif
+#if defined(ARCHIVE_CRYPTO_SHA384_MBEDTLS) ||\
+  defined(ARCHIVE_CRYPTO_SHA512_MBEDTLS)
+#include <mbedtls/sha512.h>
+#endif
+
 /* Nettle crypto headers */
 #if defined(ARCHIVE_CRYPTO_MD5_NETTLE)
 #include <nettle/md5.h>
@@ -159,6 +176,8 @@
 typedef MD5_CTX archive_md5_ctx;
 #elif defined(ARCHIVE_CRYPTO_MD5_LIBSYSTEM)
 typedef CC_MD5_CTX archive_md5_ctx;
+#elif defined(ARCHIVE_CRYPTO_MD5_MBEDTLS)
+typedef mbedtls_md5_context archive_md5_ctx;
 #elif defined(ARCHIVE_CRYPTO_MD5_NETTLE)
 typedef struct md5_ctx archive_md5_ctx;
 #elif defined(ARCHIVE_CRYPTO_MD5_OPENSSL)
@@ -173,6 +192,8 @@
 typedef RMD160_CTX archive_rmd160_ctx;
 #elif defined(ARCHIVE_CRYPTO_RMD160_LIBMD)
 typedef RIPEMD160_CTX archive_rmd160_ctx;
+#elif defined(ARCHIVE_CRYPTO_RMD160_MBEDTLS)
+typedef mbedtls_ripemd160_context archive_rmd160_ctx;
 #elif defined(ARCHIVE_CRYPTO_RMD160_NETTLE)
 typedef struct ripemd160_ctx archive_rmd160_ctx;
 #elif defined(ARCHIVE_CRYPTO_RMD160_OPENSSL)
@@ -187,6 +208,8 @@
 typedef SHA1_CTX archive_sha1_ctx;
 #elif defined(ARCHIVE_CRYPTO_SHA1_LIBSYSTEM)
 typedef CC_SHA1_CTX archive_sha1_ctx;
+#elif defined(ARCHIVE_CRYPTO_SHA1_MBEDTLS)
+typedef mbedtls_sha1_context archive_sha1_ctx;
 #elif defined(ARCHIVE_CRYPTO_SHA1_NETTLE)
 typedef struct sha1_ctx archive_sha1_ctx;
 #elif defined(ARCHIVE_CRYPTO_SHA1_OPENSSL)
@@ -207,6 +230,8 @@
 typedef SHA256_CTX archive_sha256_ctx;
 #elif defined(ARCHIVE_CRYPTO_SHA256_LIBSYSTEM)
 typedef CC_SHA256_CTX archive_sha256_ctx;
+#elif defined(ARCHIVE_CRYPTO_SHA256_MBEDTLS)
+typedef mbedtls_sha256_context archive_sha256_ctx;
 #elif defined(ARCHIVE_CRYPTO_SHA256_NETTLE)
 typedef struct sha256_ctx archive_sha256_ctx;
 #elif defined(ARCHIVE_CRYPTO_SHA256_OPENSSL)
@@ -225,6 +250,8 @@
 typedef SHA2_CTX archive_sha384_ctx;
 #elif defined(ARCHIVE_CRYPTO_SHA384_LIBSYSTEM)
 typedef CC_SHA512_CTX archive_sha384_ctx;
+#elif defined(ARCHIVE_CRYPTO_SHA384_MBEDTLS)
+typedef mbedtls_sha512_context archive_sha384_ctx;
 #elif defined(ARCHIVE_CRYPTO_SHA384_NETTLE)
 typedef struct sha384_ctx archive_sha384_ctx;
 #elif defined(ARCHIVE_CRYPTO_SHA384_OPENSSL)
@@ -245,6 +272,8 @@
 typedef SHA512_CTX archive_sha512_ctx;
 #elif defined(ARCHIVE_CRYPTO_SHA512_LIBSYSTEM)
 typedef CC_SHA512_CTX archive_sha512_ctx;
+#elif defined(ARCHIVE_CRYPTO_SHA512_MBEDTLS)
+typedef mbedtls_sha512_context archive_sha512_ctx;
 #elif defined(ARCHIVE_CRYPTO_SHA512_NETTLE)
 typedef struct sha512_ctx archive_sha512_ctx;
 #elif defined(ARCHIVE_CRYPTO_SHA512_OPENSSL)
@@ -259,6 +288,7 @@
 #if defined(ARCHIVE_CRYPTO_MD5_LIBC) ||\
   defined(ARCHIVE_CRYPTO_MD5_LIBMD) ||	\
   defined(ARCHIVE_CRYPTO_MD5_LIBSYSTEM) ||\
+  defined(ARCHIVE_CRYPTO_MD5_MBEDTLS) ||\
   defined(ARCHIVE_CRYPTO_MD5_NETTLE) ||\
   defined(ARCHIVE_CRYPTO_MD5_OPENSSL) ||\
   defined(ARCHIVE_CRYPTO_MD5_WIN)
@@ -272,6 +302,7 @@
   __archive_digest.md5update(ctx, buf, n)
 
 #if defined(ARCHIVE_CRYPTO_RMD160_LIBC) ||\
+  defined(ARCHIVE_CRYPTO_RMD160_MBEDTLS) ||\
   defined(ARCHIVE_CRYPTO_RMD160_NETTLE) ||\
   defined(ARCHIVE_CRYPTO_RMD160_OPENSSL)
 #define ARCHIVE_HAS_RMD160
@@ -286,6 +317,7 @@
 #if defined(ARCHIVE_CRYPTO_SHA1_LIBC) ||\
   defined(ARCHIVE_CRYPTO_SHA1_LIBMD) ||	\
   defined(ARCHIVE_CRYPTO_SHA1_LIBSYSTEM) ||\
+  defined(ARCHIVE_CRYPTO_SHA1_MBEDTLS) ||\
   defined(ARCHIVE_CRYPTO_SHA1_NETTLE) ||\
   defined(ARCHIVE_CRYPTO_SHA1_OPENSSL) ||\
   defined(ARCHIVE_CRYPTO_SHA1_WIN)
@@ -303,6 +335,7 @@
   defined(ARCHIVE_CRYPTO_SHA256_LIBC3) ||\
   defined(ARCHIVE_CRYPTO_SHA256_LIBMD) ||\
   defined(ARCHIVE_CRYPTO_SHA256_LIBSYSTEM) ||\
+  defined(ARCHIVE_CRYPTO_SHA256_MBEDTLS) ||\
   defined(ARCHIVE_CRYPTO_SHA256_NETTLE) ||\
   defined(ARCHIVE_CRYPTO_SHA256_OPENSSL) ||\
   defined(ARCHIVE_CRYPTO_SHA256_WIN)
@@ -319,6 +352,7 @@
   defined(ARCHIVE_CRYPTO_SHA384_LIBC2) ||\
   defined(ARCHIVE_CRYPTO_SHA384_LIBC3) ||\
   defined(ARCHIVE_CRYPTO_SHA384_LIBSYSTEM) ||\
+  defined(ARCHIVE_CRYPTO_SHA384_MBEDTLS) ||\
   defined(ARCHIVE_CRYPTO_SHA384_NETTLE) ||\
   defined(ARCHIVE_CRYPTO_SHA384_OPENSSL) ||\
   defined(ARCHIVE_CRYPTO_SHA384_WIN)
@@ -336,6 +370,7 @@
   defined(ARCHIVE_CRYPTO_SHA512_LIBC3) ||\
   defined(ARCHIVE_CRYPTO_SHA512_LIBMD) ||\
   defined(ARCHIVE_CRYPTO_SHA512_LIBSYSTEM) ||\
+  defined(ARCHIVE_CRYPTO_SHA512_MBEDTLS) ||\
   defined(ARCHIVE_CRYPTO_SHA512_NETTLE) ||\
   defined(ARCHIVE_CRYPTO_SHA512_OPENSSL) ||\
   defined(ARCHIVE_CRYPTO_SHA512_WIN)
diff --git a/Utilities/cmlibarchive/libarchive/archive_disk_acl_sunos.c b/Utilities/cmlibarchive/libarchive/archive_disk_acl_sunos.c
index bc84fd6..b0f5dfa 100644
--- a/Utilities/cmlibarchive/libarchive/archive_disk_acl_sunos.c
+++ b/Utilities/cmlibarchive/libarchive/archive_disk_acl_sunos.c
@@ -145,10 +145,8 @@
 					cnt = facl(fd, cmd, cnt, aclp);
 			}
 		} else {
-			if (aclp != NULL) {
-				free(aclp);
-				aclp = NULL;
-			}
+			free(aclp);
+			aclp = NULL;
 			break;
 		}
 	}
diff --git a/Utilities/cmlibarchive/libarchive/archive_endian.h b/Utilities/cmlibarchive/libarchive/archive_endian.h
index 1c48563..e6d3f2c 100644
--- a/Utilities/cmlibarchive/libarchive/archive_endian.h
+++ b/Utilities/cmlibarchive/libarchive/archive_endian.h
@@ -28,16 +28,15 @@
  * Borrowed from FreeBSD's <sys/endian.h>
  */
 
-#ifndef __LIBARCHIVE_BUILD
-#error This header is only to be used internally to libarchive.
-#endif
+#ifndef ARCHIVE_ENDIAN_H_INCLUDED
+#define ARCHIVE_ENDIAN_H_INCLUDED
 
 /* Note:  This is a purely internal header! */
 /* Do not use this outside of libarchive internal code! */
 
-#ifndef ARCHIVE_ENDIAN_H_INCLUDED
-#define ARCHIVE_ENDIAN_H_INCLUDED
-
+#ifndef __LIBARCHIVE_BUILD
+#error This header is only to be used internally to libarchive.
+#endif
 
 /*
  * Disabling inline keyword for compilers known to choke on it:
diff --git a/Utilities/cmlibarchive/libarchive/archive_entry.3 b/Utilities/cmlibarchive/libarchive/archive_entry.3
index f75916c..2f62a4b 100644
--- a/Utilities/cmlibarchive/libarchive/archive_entry.3
+++ b/Utilities/cmlibarchive/libarchive/archive_entry.3
@@ -32,7 +32,7 @@
 .Nm archive_entry_clear ,
 .Nm archive_entry_clone ,
 .Nm archive_entry_free ,
-.Nm archive_entry_new ,
+.Nm archive_entry_new
 .Nd functions for managing archive entry descriptions
 .Sh LIBRARY
 Streaming Archive Library (libarchive, -larchive)
@@ -126,7 +126,6 @@
 Similarly, if you store a wide string and then store a
 narrow string for the same data, the previously-set wide string will
 be discarded in favor of the new data.
-.Pp
 .\" .Sh EXAMPLE
 .\" .Sh RETURN VALUES
 .\" .Sh ERRORS
@@ -134,8 +133,8 @@
 .Xr archive_entry_acl 3 ,
 .Xr archive_entry_paths 3 ,
 .Xr archive_entry_perms 3 ,
-.Xr archive_entry_time 3
-.Xr libarchive 3 ,
+.Xr archive_entry_time 3 ,
+.Xr libarchive 3
 .Sh HISTORY
 The
 .Nm libarchive
diff --git a/Utilities/cmlibarchive/libarchive/archive_entry.c b/Utilities/cmlibarchive/libarchive/archive_entry.c
index f722bbe..a15e98c 100644
--- a/Utilities/cmlibarchive/libarchive/archive_entry.c
+++ b/Utilities/cmlibarchive/libarchive/archive_entry.c
@@ -168,6 +168,7 @@
 	archive_entry_xattr_clear(entry);
 	archive_entry_sparse_clear(entry);
 	free(entry->stat);
+	entry->ae_symlink_type = AE_SYMLINK_TYPE_UNDEFINED;
 	memset(entry, 0, sizeof(*entry));
 	return entry;
 }
@@ -202,6 +203,9 @@
 	entry2->ae_set = entry->ae_set;
 	archive_mstring_copy(&entry2->ae_uname, &entry->ae_uname);
 
+	/* Copy symlink type */
+	entry2->ae_symlink_type = entry->ae_symlink_type;
+
 	/* Copy encryption status */
 	entry2->encryption = entry->encryption;
 	
@@ -253,6 +257,7 @@
 	if (entry == NULL)
 		return (NULL);
 	entry->archive = a;
+	entry->ae_symlink_type = AE_SYMLINK_TYPE_UNDEFINED;
 	return (entry);
 }
 
@@ -675,6 +680,12 @@
 	return (NULL);
 }
 
+int
+archive_entry_symlink_type(struct archive_entry *entry)
+{
+	return (entry->ae_symlink_type);
+}
+
 const char *
 archive_entry_symlink_utf8(struct archive_entry *entry)
 {
@@ -1246,6 +1257,12 @@
 }
 
 void
+archive_entry_set_symlink_type(struct archive_entry *entry, int type)
+{
+	entry->ae_symlink_type = type;
+}
+
+void
 archive_entry_set_symlink_utf8(struct archive_entry *entry, const char *linkname)
 {
 	archive_mstring_copy_utf8(&entry->ae_symlink, linkname);
@@ -1560,10 +1577,8 @@
 const wchar_t *
 archive_entry_acl_text_w(struct archive_entry *entry, int flags)
 {
-	if (entry->acl.acl_text_w != NULL) {
-		free(entry->acl.acl_text_w);
-		entry->acl.acl_text_w = NULL;
-	}
+	free(entry->acl.acl_text_w);
+	entry->acl.acl_text_w = NULL;
 	if (archive_entry_acl_text_compat(&flags) == 0)
 		entry->acl.acl_text_w = archive_acl_to_text_w(&entry->acl,
 		    NULL, flags, entry->archive);
@@ -1574,10 +1589,8 @@
 const char *
 archive_entry_acl_text(struct archive_entry *entry, int flags)
 {
-	if (entry->acl.acl_text != NULL) {
-		free(entry->acl.acl_text);
-		entry->acl.acl_text = NULL;
-	}
+	free(entry->acl.acl_text);
+	entry->acl.acl_text = NULL;
 	if (archive_entry_acl_text_compat(&flags) == 0)
 		entry->acl.acl_text = archive_acl_to_text_l(&entry->acl, NULL,
 		    flags, NULL);
@@ -1590,10 +1603,8 @@
 _archive_entry_acl_text_l(struct archive_entry *entry, int flags,
     const char **acl_text, size_t *len, struct archive_string_conv *sc)
 {
-	if (entry->acl.acl_text != NULL) {
-		free(entry->acl.acl_text);
-		entry->acl.acl_text = NULL;
-        }
+	free(entry->acl.acl_text);
+	entry->acl.acl_text = NULL;
 
 	if (archive_entry_acl_text_compat(&flags) == 0)
 		entry->acl.acl_text = archive_acl_to_text_l(&entry->acl,
@@ -1638,198 +1649,215 @@
  * SUCH DAMAGE.
  */
 
+/*
+ * Supported file flags on FreeBSD and Mac OS:
+ * sappnd,sappend		SF_APPEND
+ * arch,archived		SF_ARCHIVED
+ * schg,schange,simmutable	SF_IMMUTABLE
+ * sunlnk,sunlink		SF_NOUNLINK	(FreeBSD only)
+ * uappnd,uappend		UF_APPEND
+ * compressed			UF_COMPRESSED	(Mac OS only)
+ * hidden,uhidden		UF_HIDDEN
+ * uchg,uchange,uimmutable	UF_IMMUTABLE
+ * nodump			UF_NODUMP
+ * uunlnk,uunlink		UF_NOUNLINK	(FreeBSD only)
+ * offline,uoffline		UF_OFFLINE	(FreeBSD only)
+ * opaque			UF_OPAQUE
+ * rdonly,urdonly,readonly	UF_READONLY	(FreeBSD only)
+ * reparse,ureparse		UF_REPARSE	(FreeBSD only)
+ * sparse,usparse		UF_SPARSE	(FreeBSD only)
+ * system,usystem		UF_SYSTEM	(FreeBSD only)
+ *
+ * See chflags(2) for more information
+ *
+ * Supported file attributes on Linux:
+ * a	append only			FS_APPEND_FL		sappnd
+ * A	no atime updates		FS_NOATIME_FL		atime
+ * c	compress			FS_COMPR_FL		compress
+ * C	no copy on write		FS_NOCOW_FL		cow
+ * d	no dump				FS_NODUMP_FL		dump
+ * D	synchronous directory updates	FS_DIRSYNC_FL		dirsync
+ * i	immutable			FS_IMMUTABLE_FL		schg
+ * j	data journalling		FS_JOURNAL_DATA_FL	journal
+ * P	project hierarchy		FS_PROJINHERIT_FL	projinherit
+ * s	secure deletion			FS_SECRM_FL		securedeletion
+ * S	synchronous updates		FS_SYNC_FL		sync
+ * t	no tail-merging			FS_NOTAIL_FL		tail
+ * T	top of directory hierarchy	FS_TOPDIR_FL		topdir
+ * u	undeletable			FS_UNRM_FL		undel
+ *
+ * See ioctl_iflags(2) for more information
+ *
+ * Equivalent file flags supported on FreeBSD / Mac OS and Linux:
+ * SF_APPEND		FS_APPEND_FL		sappnd
+ * SF_IMMUTABLE		FS_IMMUTABLE_FL		schg
+ * UF_NODUMP		FS_NODUMP_FL		nodump
+ */
+
 static const struct flag {
 	const char	*name;
 	const wchar_t	*wname;
 	unsigned long	 set;
 	unsigned long	 clear;
-} flags[] = {
+} fileflags[] = {
 	/* Preferred (shorter) names per flag first, all prefixed by "no" */
 #ifdef SF_APPEND
-	{ "nosappnd",	L"nosappnd",		SF_APPEND,	0 },
-	{ "nosappend",	L"nosappend",		SF_APPEND,	0 },
+	{ "nosappnd",	L"nosappnd",		SF_APPEND,	0},
+	{ "nosappend",	L"nosappend",		SF_APPEND,	0},
 #endif
 #if defined(FS_APPEND_FL)			/* 'a' */
-	{ "nosappnd",	L"nosappnd",		FS_APPEND_FL,	0 },
-	{ "nosappend",	L"nosappend",		FS_APPEND_FL,	0 },
+	{ "nosappnd",	L"nosappnd",		FS_APPEND_FL,	0},
+	{ "nosappend",	L"nosappend",		FS_APPEND_FL,	0},
 #elif defined(EXT2_APPEND_FL)			/* 'a' */
-	{ "nosappnd",	L"nosappnd",		EXT2_APPEND_FL,	0 },
-	{ "nosappend",	L"nosappend",		EXT2_APPEND_FL,	0 },
+	{ "nosappnd",	L"nosappnd",		EXT2_APPEND_FL,	0},
+	{ "nosappend",	L"nosappend",		EXT2_APPEND_FL,	0},
 #endif
 #ifdef SF_ARCHIVED
-	{ "noarch",	L"noarch",		SF_ARCHIVED,	0 },
-	{ "noarchived",	L"noarchived",       	SF_ARCHIVED,	0 },
+	{ "noarch",	L"noarch",		SF_ARCHIVED,	0},
+	{ "noarchived",	L"noarchived",       	SF_ARCHIVED,	0},
 #endif
 #ifdef SF_IMMUTABLE
-	{ "noschg",	L"noschg",		SF_IMMUTABLE,	0 },
-	{ "noschange",	L"noschange",		SF_IMMUTABLE,	0 },
-	{ "nosimmutable",	L"nosimmutable",	SF_IMMUTABLE,	0 },
+	{ "noschg",	L"noschg",		SF_IMMUTABLE,	0},
+	{ "noschange",	L"noschange",		SF_IMMUTABLE,	0},
+	{ "nosimmutable",	L"nosimmutable",	SF_IMMUTABLE,	0},
 #endif
 #if defined(FS_IMMUTABLE_FL)			/* 'i' */
-	{ "noschg",	L"noschg",		FS_IMMUTABLE_FL,	0 },
-	{ "noschange",	L"noschange",		FS_IMMUTABLE_FL,	0 },
-	{ "nosimmutable",	L"nosimmutable",	FS_IMMUTABLE_FL,	0 },
+	{ "noschg",	L"noschg",		FS_IMMUTABLE_FL,	0},
+	{ "noschange",	L"noschange",		FS_IMMUTABLE_FL,	0},
+	{ "nosimmutable",	L"nosimmutable",	FS_IMMUTABLE_FL,	0},
 #elif defined(EXT2_IMMUTABLE_FL)		/* 'i' */
-	{ "noschg",	L"noschg",		EXT2_IMMUTABLE_FL,	0 },
-	{ "noschange",	L"noschange",		EXT2_IMMUTABLE_FL,	0 },
-	{ "nosimmutable",	L"nosimmutable",	EXT2_IMMUTABLE_FL,	0 },
+	{ "noschg",	L"noschg",		EXT2_IMMUTABLE_FL,	0},
+	{ "noschange",	L"noschange",		EXT2_IMMUTABLE_FL,	0},
+	{ "nosimmutable",	L"nosimmutable",	EXT2_IMMUTABLE_FL,	0},
 #endif
 #ifdef SF_NOUNLINK
-	{ "nosunlnk",	L"nosunlnk",		SF_NOUNLINK,	0 },
-	{ "nosunlink",	L"nosunlink",		SF_NOUNLINK,	0 },
-#endif
-#ifdef SF_SNAPSHOT
-	{ "nosnapshot",	L"nosnapshot",	SF_SNAPSHOT,	0 },
+	{ "nosunlnk",	L"nosunlnk",		SF_NOUNLINK,	0},
+	{ "nosunlink",	L"nosunlink",		SF_NOUNLINK,	0},
 #endif
 #ifdef UF_APPEND
-	{ "nouappnd",	L"nouappnd",		UF_APPEND,	0 },
-	{ "nouappend",	L"nouappend",		UF_APPEND,	0 },
+	{ "nouappnd",	L"nouappnd",		UF_APPEND,	0},
+	{ "nouappend",	L"nouappend",		UF_APPEND,	0},
 #endif
 #ifdef UF_IMMUTABLE
-	{ "nouchg",	L"nouchg",		UF_IMMUTABLE,	0 },
-	{ "nouchange",	L"nouchange",		UF_IMMUTABLE,	0 },
-	{ "nouimmutable",	L"nouimmutable",	UF_IMMUTABLE,	0 },
+	{ "nouchg",	L"nouchg",		UF_IMMUTABLE,	0},
+	{ "nouchange",	L"nouchange",		UF_IMMUTABLE,	0},
+	{ "nouimmutable",	L"nouimmutable",	UF_IMMUTABLE,	0},
 #endif
 #ifdef UF_NODUMP
 	{ "nodump",	L"nodump",		0,		UF_NODUMP},
 #endif
 #if defined(FS_NODUMP_FL)	/* 'd' */
 	{ "nodump",	L"nodump",		0,		FS_NODUMP_FL},
-#elif defined(EXT2_NODUMP_FL) 	/* 'd' */
+#elif defined(EXT2_NODUMP_FL)
 	{ "nodump",	L"nodump",		0,		EXT2_NODUMP_FL},
 #endif
 #ifdef UF_OPAQUE
-	{ "noopaque",	L"noopaque",		UF_OPAQUE,	0 },
+	{ "noopaque",	L"noopaque",		UF_OPAQUE,	0},
 #endif
 #ifdef UF_NOUNLINK
-	{ "nouunlnk",	L"nouunlnk",		UF_NOUNLINK,	0 },
-	{ "nouunlink",	L"nouunlink",		UF_NOUNLINK,	0 },
+	{ "nouunlnk",	L"nouunlnk",		UF_NOUNLINK,	0},
+	{ "nouunlink",	L"nouunlink",		UF_NOUNLINK,	0},
 #endif
 #ifdef UF_COMPRESSED
-	{ "nocompressed",L"nocompressed",	UF_COMPRESSED,	0 },
+	/* Mac OS */
+	{ "nocompressed",	L"nocompressed",	UF_COMPRESSED,	0},
 #endif
 #ifdef UF_HIDDEN
-	{ "nohidden",	L"nohidden",		UF_HIDDEN,	0 },
+	{ "nohidden",	L"nohidden",		UF_HIDDEN,	0},
+	{ "nouhidden",	L"nouhidden",		UF_HIDDEN,	0},
 #endif
-#if defined(FS_UNRM_FL)
-        { "nouunlink",	L"nouunlink",		FS_UNRM_FL,	0},
+#ifdef FILE_ATTRIBUTE_HIDDEN
+	{ "nohidden",	L"nohidden",	FILE_ATTRIBUTE_HIDDEN,	0},
+	{ "nouhidden",	L"nouhidden",	FILE_ATTRIBUTE_HIDDEN,	0},
+#endif
+#ifdef UF_OFFLINE
+	{ "nooffline",	L"nooffline",		UF_OFFLINE,	0},
+	{ "nouoffline",	L"nouoffline",		UF_OFFLINE,	0},
+#endif
+#ifdef UF_READONLY
+	{ "nordonly",	L"nordonly",		UF_READONLY,	0},
+	{ "nourdonly",	L"nourdonly",		UF_READONLY,	0},
+	{ "noreadonly",	L"noreadonly",		UF_READONLY,	0},
+#endif
+#ifdef FILE_ATTRIBUTE_READONLY
+	{ "nordonly",	L"nordonly",	FILE_ATTRIBUTE_READONLY,	0},
+	{ "nourdonly",	L"nourdonly",	FILE_ATTRIBUTE_READONLY,	0},
+	{ "noreadonly",	L"noreadonly",	FILE_ATTRIBUTE_READONLY,	0},
+#endif
+#ifdef UF_SPARSE
+	{ "nosparse",	L"nosparse",		UF_SPARSE,	0},
+	{ "nousparse",	L"nousparse",		UF_SPARSE,	0},
+#endif
+#ifdef UF_REPARSE
+	{ "noreparse",	L"noreparse",		UF_REPARSE,	0},
+	{ "noureparse",	L"noureparse",		UF_REPARSE,	0},
+#endif
+#ifdef UF_SYSTEM
+	{ "nosystem",	L"nosystem",		UF_SYSTEM,	0},
+	{ "nousystem",	L"nousystem",		UF_SYSTEM,	0},
+#endif
+#ifdef FILE_ATTRIBUTE_SYSTEM
+	{ "nosystem",	L"nosystem",	FILE_ATTRIBUTE_SYSTEM,	0},
+	{ "nousystem",	L"nousystem",	FILE_ATTRIBUTE_SYSTEM,	0},
+#endif
+#if defined(FS_UNRM_FL)		/* 'u' */
+	{ "noundel",	L"noundel",		FS_UNRM_FL,	0},
 #elif defined(EXT2_UNRM_FL)
-        { "nouunlink",	L"nouunlink",		EXT2_UNRM_FL,	0},
+	{ "noundel",	L"noundel",		EXT2_UNRM_FL,	0},
 #endif
 
-#if defined(FS_BTREE_FL)
-        { "nobtree",	L"nobtree",       	FS_BTREE_FL,	0 },
-#elif defined(EXT2_BTREE_FL)
-        { "nobtree",	L"nobtree",       	EXT2_BTREE_FL,	0 },
+#if defined(FS_COMPR_FL)	/* 'c' */
+	{ "nocompress",	L"nocompress",       	FS_COMPR_FL,	0},
+#elif defined(EXT2_COMPR_FL)
+	{ "nocompress",	L"nocompress",       	EXT2_COMPR_FL,	0},
 #endif
 
-#if defined(FS_ECOMPR_FL)
-        { "nocomperr",	L"nocomperr",       	FS_ECOMPR_FL,	0 },
-#elif defined(EXT2_ECOMPR_FL)
-        { "nocomperr",	L"nocomperr",       	EXT2_ECOMPR_FL,	0 },
+#if defined(FS_NOATIME_FL)	/* 'A' */
+	{ "noatime",	L"noatime",		0,		FS_NOATIME_FL},
+#elif defined(EXT2_NOATIME_FL)
+	{ "noatime",	L"noatime",		0,		EXT2_NOATIME_FL},
 #endif
-
-#if defined(FS_COMPR_FL)			/* 'c' */
-        { "nocompress",	L"nocompress",       	FS_COMPR_FL,	0 },
-#elif defined(EXT2_COMPR_FL)			/* 'c' */
-        { "nocompress",	L"nocompress",       	EXT2_COMPR_FL,	0 },
-#endif
-
-#if defined(FS_NOATIME_FL)			/* 'A' */
-        { "noatime",	L"noatime",		0,		FS_NOATIME_FL},
-#elif defined(EXT2_NOATIME_FL)			/* 'A' */
-        { "noatime",	L"noatime",		0,		EXT2_NOATIME_FL},
-#endif
-
-#if defined(FS_DIRTY_FL)
-        { "nocompdirty",L"nocompdirty",		FS_DIRTY_FL,		0},
-#elif defined(EXT2_DIRTY_FL)
-        { "nocompdirty",L"nocompdirty",		EXT2_DIRTY_FL,		0},
-#endif
-
-#if defined(FS_COMPRBLK_FL)
-#if defined(FS_NOCOMPR_FL)
-        { "nocomprblk",	L"nocomprblk",		FS_COMPRBLK_FL, FS_NOCOMPR_FL},
-#else
-        { "nocomprblk",	L"nocomprblk",		FS_COMPRBLK_FL,	0},
-#endif
-#elif defined(EXT2_COMPRBLK_FL)
-#if defined(EXT2_NOCOMPR_FL)
-        { "nocomprblk",	L"nocomprblk",		EXT2_COMPRBLK_FL, EXT2_NOCOMPR_FL},
-#else
-        { "nocomprblk",	L"nocomprblk",		EXT2_COMPRBLK_FL,	0},
-#endif
-#endif
-#if defined(FS_DIRSYNC_FL)
-        { "nodirsync",	L"nodirsync",		FS_DIRSYNC_FL,	0},
+#if defined(FS_DIRSYNC_FL)	/* 'D' */
+	{ "nodirsync",	L"nodirsync",		FS_DIRSYNC_FL,		0},
 #elif defined(EXT2_DIRSYNC_FL)
-        { "nodirsync",	L"nodirsync",		EXT2_DIRSYNC_FL,	0},
+	{ "nodirsync",	L"nodirsync",		EXT2_DIRSYNC_FL,	0},
 #endif
-#if defined(FS_INDEX_FL)
-        { "nohashidx",	L"nohashidx",		FS_INDEX_FL,		0},
-#elif defined(EXT2_INDEX_FL)
-        { "nohashidx",	L"nohashidx",		EXT2_INDEX_FL,		0},
-#endif
-#if defined(FS_IMAGIC_FL)
-        { "noimagic",	L"noimagic",		FS_IMAGIC_FL,		0},
-#elif defined(EXT2_IMAGIC_FL)
-        { "noimagic",	L"noimagic",		EXT2_IMAGIC_FL,		0},
-#endif
-#if defined(FS_JOURNAL_DATA_FL)
-        { "nojournal",	L"nojournal",		FS_JOURNAL_DATA_FL,	0},
+#if defined(FS_JOURNAL_DATA_FL)	/* 'j' */
+	{ "nojournal-data",L"nojournal-data",	FS_JOURNAL_DATA_FL,	0},
+	{ "nojournal",	L"nojournal",		FS_JOURNAL_DATA_FL,	0},
 #elif defined(EXT3_JOURNAL_DATA_FL)
-        { "nojournal",	L"nojournal",		EXT3_JOURNAL_DATA_FL,	0},
+	{ "nojournal-data",L"nojournal-data",	EXT3_JOURNAL_DATA_FL,	0},
+	{ "nojournal",	L"nojournal",		EXT3_JOURNAL_DATA_FL,	0},
 #endif
-#if defined(FS_SECRM_FL)
-        { "nosecuredeletion",L"nosecuredeletion",FS_SECRM_FL,		0},
+#if defined(FS_SECRM_FL)	/* 's' */
+	{ "nosecdel",	L"nosecdel",		FS_SECRM_FL,		0},
+	{ "nosecuredeletion",L"nosecuredeletion",FS_SECRM_FL,		0},
 #elif defined(EXT2_SECRM_FL)
-        { "nosecuredeletion",L"nosecuredeletion",EXT2_SECRM_FL,		0},
+	{ "nosecdel",	L"nosecdel",		EXT2_SECRM_FL,		0},
+	{ "nosecuredeletion",L"nosecuredeletion",EXT2_SECRM_FL,		0},
 #endif
-#if defined(FS_SYNC_FL)
-        { "nosync",	L"nosync",		FS_SYNC_FL,		0},
+#if defined(FS_SYNC_FL)		/* 'S' */
+	{ "nosync",	L"nosync",		FS_SYNC_FL,		0},
 #elif defined(EXT2_SYNC_FL)
-        { "nosync",	L"nosync",		EXT2_SYNC_FL,		0},
+	{ "nosync",	L"nosync",		EXT2_SYNC_FL,		0},
 #endif
-#if defined(FS_NOTAIL_FL)
-        { "notail",	L"notail",		0,		FS_NOTAIL_FL},
+#if defined(FS_NOTAIL_FL)	/* 't' */
+	{ "notail",	L"notail",		0,		FS_NOTAIL_FL},
 #elif defined(EXT2_NOTAIL_FL)
-        { "notail",	L"notail",		0,		EXT2_NOTAIL_FL},
+	{ "notail",	L"notail",		0,		EXT2_NOTAIL_FL},
 #endif
-#if defined(FS_TOPDIR_FL)
-        { "notopdir",	L"notopdir",		FS_TOPDIR_FL,		0},
+#if defined(FS_TOPDIR_FL)	/* 'T' */
+	{ "notopdir",	L"notopdir",		FS_TOPDIR_FL,		0},
 #elif defined(EXT2_TOPDIR_FL)
-        { "notopdir",	L"notopdir",		EXT2_TOPDIR_FL,		0},
+	{ "notopdir",	L"notopdir",		EXT2_TOPDIR_FL,		0},
 #endif
-#ifdef FS_ENCRYPT_FL
-        { "noencrypt",	L"noencrypt",		FS_ENCRYPT_FL,	0},
+#ifdef FS_NOCOW_FL	/* 'C' */
+	{ "nocow",	L"nocow",		0,	FS_NOCOW_FL},
 #endif
-#ifdef FS_HUGE_FILE_FL
-        { "nohugefile",	L"nohugefile",		FS_HUGE_FILE_FL,	0},
+#ifdef FS_PROJINHERIT_FL	/* 'P' */
+	{ "noprojinherit",L"noprojinherit",	FS_PROJINHERIT_FL,	0},
 #endif
-#ifdef FS_EXTENT_FL
-        { "noextent",	L"noextent",		FS_EXTENT_FL,	0},
-#endif
-#ifdef FS_EA_INODE_FL
-        { "noeainode",	L"noeainode",		FS_EA_INODE_FL,	0},
-#endif
-#ifdef FS_EOFBLOCKS_FL
-        { "noeofblocks",L"noeofblocks",		FS_EOFBLOCKS_FL,	0},
-#endif
-#ifdef FS_NOCOW_FL
-        { "nocow",	L"nocow",		FS_NOCOW_FL,	0},
-#endif
-#ifdef FS_INLINE_DATA_FL
-        { "noinlinedata",L"noinlinedata",	FS_INLINE_DATA_FL,	0},
-#endif
-#ifdef FS_PROJINHERIT_FL
-        { "noprojinherit",L"noprojinherit",	FS_PROJINHERIT_FL,	0},
-#endif
-#if defined(FS_RESERVED_FL)
-        { "noreserved",	L"noreserved",		FS_RESERVED_FL,	0},
-#elif defined(EXT2_RESERVED_FL)
-        { "noreserved",	L"noreserved",		EXT2_RESERVED_FL,	0},
-#endif
-	{ NULL,		NULL,			0,		0 }
+	{ NULL,		NULL,			0,		0}
 };
 
 /*
@@ -1848,7 +1876,7 @@
 
 	bits = bitset | bitclear;
 	length = 0;
-	for (flag = flags; flag->name != NULL; flag++)
+	for (flag = fileflags; flag->name != NULL; flag++)
 		if (bits & (flag->set | flag->clear)) {
 			length += strlen(flag->name) + 1;
 			bits &= ~(flag->set | flag->clear);
@@ -1861,7 +1889,7 @@
 		return (NULL);
 
 	dp = string;
-	for (flag = flags; flag->name != NULL; flag++) {
+	for (flag = fileflags; flag->name != NULL; flag++) {
 		if (bitset & flag->set || bitclear & flag->clear) {
 			sp = flag->name + 2;
 		} else if (bitset & flag->clear  ||  bitclear & flag->set) {
@@ -1913,7 +1941,7 @@
 		    *end != ' '  &&  *end != ',')
 			end++;
 		length = end - start;
-		for (flag = flags; flag->name != NULL; flag++) {
+		for (flag = fileflags; flag->name != NULL; flag++) {
 			size_t flag_length = strlen(flag->name);
 			if (length == flag_length
 			    && memcmp(start, flag->name, length) == 0) {
@@ -1981,7 +2009,7 @@
 		    *end != L' '  &&  *end != L',')
 			end++;
 		length = end - start;
-		for (flag = flags; flag->wname != NULL; flag++) {
+		for (flag = fileflags; flag->wname != NULL; flag++) {
 			size_t flag_length = wcslen(flag->wname);
 			if (length == flag_length
 			    && wmemcmp(start, flag->wname, length) == 0) {
diff --git a/Utilities/cmlibarchive/libarchive/archive_entry.h b/Utilities/cmlibarchive/libarchive/archive_entry.h
index a9134f6..0053faa 100644
--- a/Utilities/cmlibarchive/libarchive/archive_entry.h
+++ b/Utilities/cmlibarchive/libarchive/archive_entry.h
@@ -30,7 +30,7 @@
 #define	ARCHIVE_ENTRY_H_INCLUDED
 
 /* Note: Compiler will complain if this does not match archive.h! */
-#define	ARCHIVE_VERSION_NUMBER 3003003
+#define	ARCHIVE_VERSION_NUMBER 3004002
 
 /*
  * Note: archive_entry.h is for use outside of libarchive; the
@@ -188,6 +188,13 @@
 #define AE_IFIFO	((__LA_MODE_T)0010000)
 
 /*
+ * Symlink types
+ */
+#define AE_SYMLINK_TYPE_UNDEFINED	0
+#define AE_SYMLINK_TYPE_FILE		1
+#define AE_SYMLINK_TYPE_DIRECTORY	2
+
+/*
  * Basic object manipulation
  */
 
@@ -272,6 +279,7 @@
 __LA_DECL const char	*archive_entry_strmode(struct archive_entry *);
 __LA_DECL const char	*archive_entry_symlink(struct archive_entry *);
 __LA_DECL const char	*archive_entry_symlink_utf8(struct archive_entry *);
+__LA_DECL int		 archive_entry_symlink_type(struct archive_entry *);
 __LA_DECL const wchar_t	*archive_entry_symlink_w(struct archive_entry *);
 __LA_DECL la_int64_t	 archive_entry_uid(struct archive_entry *);
 __LA_DECL const char	*archive_entry_uname(struct archive_entry *);
@@ -347,6 +355,7 @@
 __LA_DECL void	archive_entry_copy_sourcepath(struct archive_entry *, const char *);
 __LA_DECL void	archive_entry_copy_sourcepath_w(struct archive_entry *, const wchar_t *);
 __LA_DECL void	archive_entry_set_symlink(struct archive_entry *, const char *);
+__LA_DECL void	archive_entry_set_symlink_type(struct archive_entry *, int);
 __LA_DECL void	archive_entry_set_symlink_utf8(struct archive_entry *, const char *);
 __LA_DECL void	archive_entry_copy_symlink(struct archive_entry *, const char *);
 __LA_DECL void	archive_entry_copy_symlink_w(struct archive_entry *, const wchar_t *);
@@ -512,9 +521,6 @@
 __LA_DECL int	 archive_entry_acl_next(struct archive_entry *, int /* want_type */,
 	    int * /* type */, int * /* permset */, int * /* tag */,
 	    int * /* qual */, const char ** /* name */);
-__LA_DECL int	 archive_entry_acl_next_w(struct archive_entry *, int /* want_type */,
-	    int * /* type */, int * /* permset */, int * /* tag */,
-	    int * /* qual */, const wchar_t ** /* name */);
 
 /*
  * Construct a text-format ACL.  The flags argument is a bitmask that
@@ -689,7 +695,6 @@
     struct archive_entry **, struct archive_entry **);
 __LA_DECL struct archive_entry *archive_entry_partial_links(
     struct archive_entry_linkresolver *res, unsigned int *links);
-
 #ifdef __cplusplus
 }
 #endif
diff --git a/Utilities/cmlibarchive/libarchive/archive_entry_acl.3 b/Utilities/cmlibarchive/libarchive/archive_entry_acl.3
index 534dbfa..50dd642 100644
--- a/Utilities/cmlibarchive/libarchive/archive_entry_acl.3
+++ b/Utilities/cmlibarchive/libarchive/archive_entry_acl.3
@@ -34,7 +34,6 @@
 .Nm archive_entry_acl_from_text ,
 .Nm archive_entry_acl_from_text_w ,
 .Nm archive_entry_acl_next ,
-.Nm archive_entry_acl_next_w ,
 .Nm archive_entry_acl_reset ,
 .Nm archive_entry_acl_to_text ,
 .Nm archive_entry_acl_to_text_w ,
@@ -89,16 +88,6 @@
 .Fa "const char **ret_name"
 .Fc
 .Ft int
-.Fo archive_entry_acl_next_w
-.Fa "struct archive_entry *a"
-.Fa "int type"
-.Fa "int *ret_type"
-.Fa "int *ret_permset"
-.Fa "int *ret_tag"
-.Fa "int *ret_qual"
-.Fa "const wchar_t **ret_name"
-.Fc
-.Ft int
 .Fn archive_entry_acl_reset "struct archive_entry *a" "int type"
 .Ft char *
 .Fo archive_entry_acl_to_text
@@ -118,15 +107,16 @@
 .Sh DESCRIPTION
 The
 .Dq Access Control Lists (ACLs)
-extend the standard Unix perssion model.
+extend the standard Unix permission model.
 The ACL interface of
 .Nm libarchive
-supports both POSIX.1e and NFSv4 style ACLs. Use of ACLs is restricted by
+supports both POSIX.1e and NFSv4 style ACLs.
+Use of ACLs is restricted by
 various levels of ACL support in operating systems, file systems and archive
 formats.
 .Ss POSIX.1e Access Control Lists
 A POSIX.1e ACL consists of a number of independent entries.
-Each entry specifies the permission set as bitmask of basic permissions.
+Each entry specifies the permission set as a bitmask of basic permissions.
 Valid permissions in the
 .Fa permset
 are:
@@ -147,13 +137,13 @@
 .It Dv ARCHIVE_ENTRY_ACL_USER_OBJ
 The owner of the file.
 .It Dv ARCHIVE_ENTRY_ACL_GROUP
-The group specied by the name field.
+The group specified by the name field.
 .It Dv ARCHIVE_ENTRY_ACL_GROUP_OBJ
-The group who owns the file.
+The group which owns the file.
 .It Dv ARCHIVE_ENTRY_ACL_MASK
 The maximum permissions to be obtained via group permissions.
 .It Dv ARCHIVE_ENTRY_ACL_OTHER
-Any principal who is not file owner or a member of the owning group.
+Any principal who is not the file owner or a member of the owning group.
 .El
 .Pp
 The principals
@@ -164,12 +154,12 @@
 are equivalent to user, group and other in the classic Unix permission
 model and specify non-extended ACL entries.
 .Pp
-All files with have an access ACL
+All files have an access ACL
 .Pq Dv ARCHIVE_ENTRY_ACL_TYPE_ACCESS .
 This specifies the permissions required for access to the file itself.
 Directories have an additional ACL
 .Pq Dv ARCHIVE_ENTRY_ACL_TYPE_DEFAULT ,
-which controls the initial access ACL for newly created directory entries.
+which controls the initial access ACL for newly-created directory entries.
 .Ss NFSv4 Access Control Lists
 A NFSv4 ACL consists of multiple individual entries called Access Control
 Entries (ACEs).
@@ -197,11 +187,11 @@
 .It Dv ARCHIVE_ENTRY_ACL_USER_OBJ
 The owner of the file.
 .It Dv ARCHIVE_ENTRY_ACL_GROUP
-The group specied by the name field.
+The group specified by the name field.
 .It Dv ARCHIVE_ENTRY_ACL_GROUP_OBJ
-The group who owns the file.
+The group which owns the file.
 .It Dv ARCHIVE_ENTRY_ACL_EVERYONE
-Any principal who is not file owner or a member of the owning group.
+Any principal who is not the file owner or a member of the owning group.
 .El
 .Pp
 Entries with the
@@ -216,9 +206,10 @@
 .Pp
 NFSv4 ACE permissions and flags are stored in the same
 .Fa permset
-bitfield. Some permissions share the same constant and permission character but
-have different effect on directories than on files. The following ACE
-permissions are supported:
+bitfield.
+Some permissions share the same constant and permission character
+but have different effect on directories than on files.
+The following ACE permissions are supported:
 .Bl -tag -offset indent -compact -width ARCHIV
 .It Dv ARCHIVE_ENTRY_ACL_READ_DATA ( Sy r )
 Read data (file).
@@ -265,7 +256,8 @@
 .It Dv ARCHIVE_ENTRY_ACL_ENTRY_INHERIT_ONLY ( Sy i )
 Only inherit, do not apply the permission on the directory itself.
 .It Dv ARCHIVE_ENTRY_ACL_ENTRY_NO_PROPAGATE_INHERIT ( Sy n )
-Do not propagate inherit flags. Only first-level entries inherit ACLs.
+Do not propagate inherit flags.
+Only first-level entries inherit ACLs.
 .It Dv ARCHIVE_ENTRY_ACL_ENTRY_SUCCESSFUL_ACCESS ( Sy S )
 Trigger alarm or audit on successful access.
 .It Dv ARCHIVE_ENTRY_ACL_ENTRY_FAILED_ACCESS ( Sy F )
@@ -279,8 +271,8 @@
 .Fn archive_entry_acl_add_entry_w
 add a single ACL entry.
 For the access ACL and non-extended principals, the classic Unix permissions
-are updated. An archive entry cannot contain both POSIX.1e and NFSv4 ACL
-entries.
+are updated.
+An archive entry cannot contain both POSIX.1e and NFSv4 ACL entries.
 .Pp
 .Fn archive_entry_acl_clear
 removes all ACL entries and resets the enumeration pointer.
@@ -300,7 +292,8 @@
 .It Dv ARCHIVE_ENTRY_ACL_TYPE_AUDIT
 .It Dv ARCHIVE_ENTRY_ACL_TYPE_ALARM
 .El
-for NFSv4 ACLs. For POSIX.1e ACLs if
+for NFSv4 ACLs.
+For POSIX.1e ACLs if
 .Dv ARCHIVE_ENTRY_ACL_TYPE_ACCESS
 is included and at least one extended ACL entry is found,
 the three non-extended ACLs are added.
@@ -312,7 +305,8 @@
 .Pq or merge with existing
 ACL entries from
 .Pq wide
-text. The argument
+text.
+The argument
 .Fa type
 may take one of the following values:
 .Bl -tag -offset indent -compact -width "ARCHIVE_ENTRY_ACL_TYPE_DEFAULT"
@@ -322,11 +316,13 @@
 .El
 Supports all formats that can be created with
 .Fn archive_entry_acl_to_text
-or respective
+or respectively
 .Fn archive_entry_acl_to_text_w .
-Existing ACL entries are preserved. To get a clean new ACL from text
+Existing ACL entries are preserved.
+To get a clean new ACL from text
 .Fn archive_entry_acl_clear
-must be called first. Entries prefixed with
+must be called first.
+Entries prefixed with
 .Dq default:
 are treated as
 .Dv ARCHIVE_ENTRY_ACL_TYPE_DEFAULT
@@ -342,8 +338,6 @@
 are skipped.
 .Pp
 .Fn archive_entry_acl_next
-and
-.Fn archive_entry_acl_next_w
 return the next entry of the ACL list.
 This functions may only be called after
 .Fn archive_entry_acl_reset
@@ -351,10 +345,8 @@
 .Pp
 .Fn archive_entry_acl_reset
 prepare reading the list of ACL entries with
-.Fn archive_entry_acl_next
-or
-.Fn archive_entry_acl_next_w .
-The function returns either 0, if no non-extended ACLs are found.
+.Fn archive_entry_acl_next .
+The function returns 0 if no non-extended ACLs are found.
 In this case, the access permissions should be obtained by
 .Xr archive_entry_mode 3
 or set using
@@ -367,7 +359,8 @@
 .Fn archive_entry_acl_to_text_w
 convert the ACL entries for the given type into a
 .Pq wide
-string of ACL entries separated by newline. If the pointer
+string of ACL entries separated by newline.
+If the pointer
 .Fa len_p
 is not NULL, then the function shall return the length of the string
 .Pq not including the NULL terminator
@@ -415,7 +408,8 @@
 .Dq default: .
 .Pp
 .Fn archive_entry_acl_types
-get ACL entry types contained in an archive entry's ACL. As POSIX.1e and NFSv4
+get ACL entry types contained in an archive entry's ACL.
+As POSIX.1e and NFSv4
 ACL entries cannot be mixed, this function is a very efficient way to detect if
 an ACL already contains POSIX.1e or NFSv4 ACL entries.
 .Sh RETURN VALUES
@@ -438,9 +432,7 @@
 if one or more entries were invalid or non-parseable.
 .Pp
 .Fn archive_entry_acl_next
-and
-.Fn archive_entry_acl_next_w
-return
+returns
 .Dv ARCHIVE_OK
 on success,
 .Dv ARCHIVE_EOF
diff --git a/Utilities/cmlibarchive/libarchive/archive_entry_locale.h b/Utilities/cmlibarchive/libarchive/archive_entry_locale.h
index 44550c5..803c036 100644
--- a/Utilities/cmlibarchive/libarchive/archive_entry_locale.h
+++ b/Utilities/cmlibarchive/libarchive/archive_entry_locale.h
@@ -25,13 +25,13 @@
  * $FreeBSD$
  */
 
+#ifndef ARCHIVE_ENTRY_LOCALE_H_INCLUDED
+#define ARCHIVE_ENTRY_LOCALE_H_INCLUDED
+
 #ifndef __LIBARCHIVE_BUILD
 #error This header is only to be used internally to libarchive.
 #endif
 
-#ifndef ARCHIVE_ENTRY_LOCALE_H_INCLUDED
-#define	ARCHIVE_ENTRY_LOCALE_H_INCLUDED
-
 struct archive_entry;
 struct archive_string_conv;
 
diff --git a/Utilities/cmlibarchive/libarchive/archive_entry_misc.3 b/Utilities/cmlibarchive/libarchive/archive_entry_misc.3
new file mode 100644
index 0000000..dfab7dd
--- /dev/null
+++ b/Utilities/cmlibarchive/libarchive/archive_entry_misc.3
@@ -0,0 +1,63 @@
+.\" Copyright (c) 2019 Martin Matuska
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\"    notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\"    notice, this list of conditions and the following disclaimer in the
+.\"    documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.Dd April 15, 2019
+.Dt ARCHIVE_ENTRY_MISC 3
+.Os
+.Sh NAME
+.Nm archive_entry_symlink_type ,
+.Nm archive_entry_set_symlink_type
+.Nd miscellaneous functions for manipulating properties of archive_entry
+.Sh LIBRARY
+Streaming Archive Library (libarchive, -larchive)
+.Sh SYNOPSIS
+.In archive_entry.h
+.Ft int
+.Fn archive_entry_symlink_type "struct archive_entry *a"
+.Ft void
+.Fn archive_entry_set_symlink_type "struct archive_entry *a" "int"
+.Sh DESCRIPTION
+The function
+.Fn archive_entry_symlink_type
+returns and the function
+.Fn archive_entry_set_symlink_type
+sets the type of the symbolic link stored in an archive entry.
+These functions
+have special meaning on operating systems that support multiple symbolic link
+types (e.g. Microsoft Windows).
+.Pp
+Supported values are:
+.Bl -tag -width "AE_SYMLINK_TYPE_DIRECTORY" -compact
+.It AE_SYMLINK_TYPE_UNDEFINED
+Symbolic link target type is not defined (default on unix systems)
+.It AE_SYMLINK_TYPE_FILE
+Symbolic link points to a file
+.It AE_SYMLINK_TYPE_DIRECTORY
+Symbolic link points to a directory
+.El
+.Sh SEE ALSO
+.Xr archive_entry 3 ,
+.Xr archive_entry_paths 3 ,
+.Xr archive_entry_stat 3 ,
+.Xr libarchive 3
diff --git a/Utilities/cmlibarchive/libarchive/archive_entry_paths.3 b/Utilities/cmlibarchive/libarchive/archive_entry_paths.3
index f647212..0f849c9 100644
--- a/Utilities/cmlibarchive/libarchive/archive_entry_paths.3
+++ b/Utilities/cmlibarchive/libarchive/archive_entry_paths.3
@@ -133,7 +133,7 @@
 .Fn XXX_w .
 .It UTF-8
 Unicode strings encoded as UTF-8.
-This are convience functions to update both the multibyte and wide
+These are convenience functions to update both the multibyte and wide
 character strings at the same time.
 .El
 .Pp
@@ -141,13 +141,13 @@
 archive directly.
 .Pp
 For that reason, it is only available as multibyte string.
-The link path is a convience function for conditionally setting
+The link path is a convenience function for conditionally setting
 hardlink or symlink destination.
 It doesn't have a corresponding get accessor function.
 .Pp
 .Fn archive_entry_set_XXX
-is an alias for 
+is an alias for
 .Fn archive_entry_copy_XXX .
 .Sh SEE ALSO
-.Xr archive_entry 3
-.Xr libarchive 3 ,
+.Xr archive_entry 3 ,
+.Xr libarchive 3
diff --git a/Utilities/cmlibarchive/libarchive/archive_entry_perms.3 b/Utilities/cmlibarchive/libarchive/archive_entry_perms.3
index aae3648..0291b7b 100644
--- a/Utilities/cmlibarchive/libarchive/archive_entry_perms.3
+++ b/Utilities/cmlibarchive/libarchive/archive_entry_perms.3
@@ -126,7 +126,7 @@
 and
 .Fn archive_entry_set_perm
 store the given user id, group id and permission in the entry.
-The permission is also set as side effect of calling
+The permission is also set as a side effect of calling
 .Fn archive_entry_set_mode .
 .Pp
 .Fn archive_entry_strmode
@@ -143,12 +143,12 @@
 .Fn XXX_w .
 .It UTF-8
 Unicode strings encoded as UTF-8.
-This are convience functions to update both the multibyte and wide
+These are convenience functions to update both the multibyte and wide
 character strings at the same time.
 .El
 .Pp
 .Fn archive_entry_set_XXX
-is an alias for 
+is an alias for
 .Fn archive_entry_copy_XXX .
 .Ss File Flags
 File flags are transparently converted between a bitmap
@@ -182,7 +182,7 @@
 .Fn archive_entry_copy_fflags_text
 and
 .Fn archive_entry_copy_fflags_text_w
-functions parse the provided text and sets the internal bitmap values.
+functions parse the provided text and set the internal bitmap values.
 This is a platform-specific operation; names that are not meaningful
 on the current platform will be ignored.
 The function returns a pointer to the start of the first name that was not
@@ -197,8 +197,8 @@
 .Xr archive_entry 3 ,
 .Xr archive_entry_acl 3 ,
 .Xr archive_read_disk 3 ,
-.Xr archive_write_disk 3
-.Xr libarchive 3 ,
+.Xr archive_write_disk 3 ,
+.Xr libarchive 3
 .Sh BUGS
 The platform types
 .Vt uid_t
diff --git a/Utilities/cmlibarchive/libarchive/archive_entry_private.h b/Utilities/cmlibarchive/libarchive/archive_entry_private.h
index c69233e..2b9a084 100644
--- a/Utilities/cmlibarchive/libarchive/archive_entry_private.h
+++ b/Utilities/cmlibarchive/libarchive/archive_entry_private.h
@@ -25,13 +25,13 @@
  * $FreeBSD: head/lib/libarchive/archive_entry_private.h 201096 2009-12-28 02:41:27Z kientzle $
  */
 
+#ifndef ARCHIVE_ENTRY_PRIVATE_H_INCLUDED
+#define ARCHIVE_ENTRY_PRIVATE_H_INCLUDED
+
 #ifndef __LIBARCHIVE_BUILD
 #error This header is only to be used internally to libarchive.
 #endif
 
-#ifndef ARCHIVE_ENTRY_PRIVATE_H_INCLUDED
-#define	ARCHIVE_ENTRY_PRIVATE_H_INCLUDED
-
 #include "archive_acl_private.h"
 #include "archive_string.h"
 
@@ -176,6 +176,9 @@
 
 	/* Miscellaneous. */
 	char		 strmode[12];
+
+	/* Symlink type support */
+	int ae_symlink_type;
 };
 
 #endif /* ARCHIVE_ENTRY_PRIVATE_H_INCLUDED */
diff --git a/Utilities/cmlibarchive/libarchive/archive_entry_stat.3 b/Utilities/cmlibarchive/libarchive/archive_entry_stat.3
index 26611e4..aa5c8e0 100644
--- a/Utilities/cmlibarchive/libarchive/archive_entry_stat.3
+++ b/Utilities/cmlibarchive/libarchive/archive_entry_stat.3
@@ -54,7 +54,7 @@
 .Nm archive_entry_rdevmajor ,
 .Nm archive_entry_set_rdevmajor ,
 .Nm archive_entry_rdevminor ,
-.Nm archive_entry_set_rdevminor ,
+.Nm archive_entry_set_rdevminor
 .Nd accessor functions for manipulating archive entry descriptions
 .Sh LIBRARY
 Streaming Archive Library (libarchive, -larchive)
@@ -267,8 +267,8 @@
 Some archive formats use the combined form, while other formats use
 the split form.
 .Sh SEE ALSO
+.Xr stat 2 ,
 .Xr archive_entry_acl 3 ,
 .Xr archive_entry_perms 3 ,
 .Xr archive_entry_time 3 ,
-.Xr libarchive 3 ,
-.Xr stat 2
+.Xr libarchive 3
diff --git a/Utilities/cmlibarchive/libarchive/archive_entry_time.3 b/Utilities/cmlibarchive/libarchive/archive_entry_time.3
index 1864521..d0563ea 100644
--- a/Utilities/cmlibarchive/libarchive/archive_entry_time.3
+++ b/Utilities/cmlibarchive/libarchive/archive_entry_time.3
@@ -48,7 +48,7 @@
 .Nm archive_entry_mtime_nsec ,
 .Nm archive_entry_mtime_is_set ,
 .Nm archive_entry_set_mtime ,
-.Nm archive_entry_unset_mtime ,
+.Nm archive_entry_unset_mtime
 .Nd functions for manipulating times in archive entry descriptions
 .Sh LIBRARY
 Streaming Archive Library (libarchive, -larchive)
@@ -113,8 +113,8 @@
 .Fn XXX_is_set .
 Unset time fields have a second and nanosecond field of 0.
 .Sh SEE ALSO
-.Xr archive_entry 3
-.Xr libarchive 3 ,
+.Xr archive_entry 3 ,
+.Xr libarchive 3
 .Sh HISTORY
 The
 .Nm libarchive
diff --git a/Utilities/cmlibarchive/libarchive/archive_getdate.c b/Utilities/cmlibarchive/libarchive/archive_getdate.c
index 030c083..6786d35 100644
--- a/Utilities/cmlibarchive/libarchive/archive_getdate.c
+++ b/Utilities/cmlibarchive/libarchive/archive_getdate.c
@@ -27,6 +27,9 @@
 **  This code is in the public domain and has no copyright.
 */
 
+#ifndef CM_GET_DATE
+#include "archive_platform.h"
+#endif
 #ifdef __FreeBSD__
 #include <sys/cdefs.h>
 __FBSDID("$FreeBSD$");
@@ -694,8 +697,16 @@
 	signed char DaysInMonth[12] = {
 		31, 0, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
 	};
-	time_t	Julian;
-	int	i;
+	time_t		Julian;
+	int		i;
+	struct tm	*ltime;
+#if defined(HAVE_LOCALTIME_R) || defined(HAVE__LOCALTIME64_S)
+	struct tm	tmbuf;
+#endif
+#if defined(HAVE__LOCALTIME64_S)
+	errno_t		terr;
+	__time64_t	tmptime;
+#endif
 
 	if (Year < 69)
 		Year += 2000;
@@ -722,21 +733,64 @@
 	Julian *= DAY;
 	Julian += Timezone;
 	Julian += Hours * HOUR + Minutes * MINUTE + Seconds;
+#if defined(HAVE_LOCALTIME_R)
+	ltime = localtime_r(&Julian, &tmbuf);
+#elif defined(HAVE__LOCALTIME64_S)
+	tmptime = Julian;
+	terr = _localtime64_s(&tmbuf, &tmptime);
+	if (terr)
+		ltime = NULL;
+	else
+		ltime = &tmbuf;
+#else
+	ltime = localtime(&Julian);
+#endif
 	if (DSTmode == DSTon
-	    || (DSTmode == DSTmaybe && localtime(&Julian)->tm_isdst))
+	    || (DSTmode == DSTmaybe && ltime->tm_isdst))
 		Julian -= HOUR;
 	return Julian;
 }
 
-
 static time_t
 DSTcorrect(time_t Start, time_t Future)
 {
-	time_t	StartDay;
-	time_t	FutureDay;
+	time_t		StartDay;
+	time_t		FutureDay;
+	struct tm	*ltime;
+#if defined(HAVE_LOCALTIME_R) || defined(HAVE__LOCALTIME64_S)
+	struct tm	tmbuf;
+#endif
+#if defined(HAVE__LOCALTIME64_S)
+	errno_t		terr;
+	__time64_t	tmptime;
+#endif
 
-	StartDay = (localtime(&Start)->tm_hour + 1) % 24;
-	FutureDay = (localtime(&Future)->tm_hour + 1) % 24;
+#if defined(HAVE_LOCALTIME_R)
+	ltime = localtime_r(&Start, &tmbuf);
+#elif defined(HAVE__LOCALTIME64_S)
+	tmptime = Start;
+	terr = _localtime64_s(&tmbuf, &tmptime);
+	if (terr)
+		ltime = NULL;
+	else
+		ltime = &tmbuf;
+#else
+	ltime = localtime(&Start);
+#endif
+	StartDay = (ltime->tm_hour + 1) % 24;
+#if defined(HAVE_LOCALTIME_R)
+	ltime = localtime_r(&Future, &tmbuf);
+#elif defined(HAVE__LOCALTIME64_S)
+	tmptime = Future;
+	terr = _localtime64_s(&tmbuf, &tmptime);
+	if (terr)
+		ltime = NULL;
+	else
+		ltime = &tmbuf;
+#else
+	ltime = localtime(&Future);
+#endif
+	FutureDay = (ltime->tm_hour + 1) % 24;
 	return (Future - Start) + (StartDay - FutureDay) * HOUR;
 }
 
@@ -747,9 +801,27 @@
 {
 	struct tm	*tm;
 	time_t	t, now;
+#if defined(HAVE_GMTIME_R) || defined(HAVE__GMTIME64_S)
+	struct tm	tmbuf;
+#endif
+#if defined(HAVE__GMTIME64_S)
+	errno_t		terr;
+	__time64_t	tmptime;
+#endif
 
 	t = Start - zone;
+#if defined(HAVE_GMTIME_R)
+	tm = gmtime_r(&t, &tmbuf);
+#elif defined(HAVE__GMTIME64_S)
+	tmptime = t;
+	terr = _gmtime64_s(&tmbuf, &tmptime);
+	if (terr)
+		tm = NULL;
+	else
+		tm = &tmbuf;
+#else
 	tm = gmtime(&t);
+#endif
 	now = Start;
 	now += DAY * ((DayNumber - tm->tm_wday + 7) % 7);
 	now += 7 * DAY * (DayOrdinal <= 0 ? DayOrdinal : DayOrdinal - 1);
@@ -765,10 +837,28 @@
 	struct tm	*tm;
 	time_t	Month;
 	time_t	Year;
+#if defined(HAVE_LOCALTIME_R) || defined(HAVE__LOCALTIME64_S)
+	struct tm	tmbuf;
+#endif
+#if defined(HAVE__LOCALTIME64_S)
+	errno_t		terr;
+	__time64_t	tmptime;
+#endif
 
 	if (RelMonth == 0)
 		return 0;
+#if defined(HAVE_LOCALTIME_R)
+	tm = localtime_r(&Start, &tmbuf);
+#elif defined(HAVE__LOCALTIME64_S)
+	tmptime = Start;
+	terr = _localtime64_s(&tmbuf, &tmptime);
+	if (terr)
+		tm = NULL;
+	else
+		tm = &tmbuf;
+#else
 	tm = localtime(&Start);
+#endif
 	Month = 12 * (tm->tm_year + 1900) + tm->tm_mon + RelMonth;
 	Year = Month / 12;
 	Month = Month % 12 + 1;
@@ -905,6 +995,10 @@
 	time_t		Start;
 	time_t		tod;
 	long		tzone;
+#if defined(HAVE__LOCALTIME64_S) || defined(HAVE__GMTIME64_S)
+	errno_t		terr;
+	__time64_t	tmptime;
+#endif
 
 	/* Clear out the parsed token array. */
 	memset(tokens, 0, sizeof(tokens));
@@ -913,20 +1007,44 @@
 	gds = &_gds;
 
 	/* Look up the current time. */
+#if defined(HAVE_LOCALTIME_R)
+	tm = localtime_r(&now, &local);
+#elif defined(HAVE__LOCALTIME64_S)
+	tmptime = now;
+	terr = _localtime64_s(&local, &tmptime);
+	if (terr)
+		tm = NULL;
+	else
+		tm = &local;
+#else
 	memset(&local, 0, sizeof(local));
-	tm = localtime (&now);
+	tm = localtime(&now);
+#endif
 	if (tm == NULL)
 		return -1;
+#if !defined(HAVE_LOCALTIME_R) && !defined(HAVE__LOCALTIME64_S)
 	local = *tm;
+#endif
 
 	/* Look up UTC if we can and use that to determine the current
 	 * timezone offset. */
+#if defined(HAVE_GMTIME_R)
+	gmt_ptr = gmtime_r(&now, &gmt);
+#elif defined(HAVE__GMTIME64_S)
+	tmptime = now;
+	terr = _gmtime64_s(&gmt, &tmptime);
+	if (terr)
+		gmt_ptr = NULL;
+	else
+		gmt_ptr = &gmt;
+#else
 	memset(&gmt, 0, sizeof(gmt));
-	gmt_ptr = gmtime (&now);
+	gmt_ptr = gmtime(&now);
 	if (gmt_ptr != NULL) {
 		/* Copy, in case localtime and gmtime use the same buffer. */
 		gmt = *gmt_ptr;
 	}
+#endif
 	if (gmt_ptr != NULL)
 		tzone = difftm (&gmt, &local);
 	else
@@ -960,7 +1078,18 @@
 	 * time components instead of the local timezone. */
 	if (gds->HaveZone && gmt_ptr != NULL) {
 		now -= gds->Timezone;
-		gmt_ptr = gmtime (&now);
+#if defined(HAVE_GMTIME_R)
+		gmt_ptr = gmtime_r(&now, &gmt);
+#elif defined(HAVE__GMTIME64_S)
+		tmptime = now;
+		terr = _gmtime64_s(&gmt, &tmptime);
+		if (terr)
+			gmt_ptr = NULL;
+		else
+			gmt_ptr = &gmt;
+#else
+		gmt_ptr = gmtime(&now);
+#endif
 		if (gmt_ptr != NULL)
 			local = *gmt_ptr;
 		now += gds->Timezone;
diff --git a/Utilities/cmlibarchive/libarchive/archive_getdate.h b/Utilities/cmlibarchive/libarchive/archive_getdate.h
index 666ff5f..900a8f6 100644
--- a/Utilities/cmlibarchive/libarchive/archive_getdate.h
+++ b/Utilities/cmlibarchive/libarchive/archive_getdate.h
@@ -25,13 +25,13 @@
  * $FreeBSD$
  */
 
+#ifndef ARCHIVE_GETDATE_H_INCLUDED
+#define ARCHIVE_GETDATE_H_INCLUDED
+
 #ifndef __LIBARCHIVE_BUILD
 #error This header is only to be used internally to libarchive.
 #endif
 
-#ifndef ARCHIVE_GETDATE_H_INCLUDED
-#define	ARCHIVE_GETDATE_H_INCLUDED
-
 #include <time.h>
 
 time_t __archive_get_date(time_t now, const char *);
diff --git a/Utilities/cmlibarchive/libarchive/archive_hmac.c b/Utilities/cmlibarchive/libarchive/archive_hmac.c
index f299655..2a9d04c 100644
--- a/Utilities/cmlibarchive/libarchive/archive_hmac.c
+++ b/Utilities/cmlibarchive/libarchive/archive_hmac.c
@@ -83,6 +83,9 @@
 static int
 __hmac_sha1_init(archive_hmac_sha1_ctx *ctx, const uint8_t *key, size_t key_len)
 {
+#ifdef __GNUC__
+#pragma GCC diagnostic ignored "-Wcast-qual"
+#endif
 	BCRYPT_ALG_HANDLE hAlg;
 	BCRYPT_HASH_HANDLE hHash;
 	DWORD hash_len;
@@ -147,6 +150,53 @@
 	}
 }
 
+#elif defined(HAVE_LIBMBEDCRYPTO) && defined(HAVE_MBEDTLS_MD_H)
+
+static int
+__hmac_sha1_init(archive_hmac_sha1_ctx *ctx, const uint8_t *key, size_t key_len)
+{
+        const mbedtls_md_info_t *info;
+        int ret;
+
+        mbedtls_md_init(ctx);
+        info = mbedtls_md_info_from_type(MBEDTLS_MD_SHA1);
+        if (info == NULL) {
+                mbedtls_md_free(ctx);
+                return (-1);
+        }
+        ret = mbedtls_md_setup(ctx, info, 1);
+        if (ret != 0) {
+                mbedtls_md_free(ctx);
+                return (-1);
+        }
+	ret = mbedtls_md_hmac_starts(ctx, key, key_len);
+	if (ret != 0) {
+		mbedtls_md_free(ctx);
+		return (-1);
+	}
+	return 0;
+}
+
+static void
+__hmac_sha1_update(archive_hmac_sha1_ctx *ctx, const uint8_t *data,
+    size_t data_len)
+{
+	mbedtls_md_hmac_update(ctx, data, data_len);
+}
+
+static void __hmac_sha1_final(archive_hmac_sha1_ctx *ctx, uint8_t *out, size_t *out_len)
+{
+	(void)out_len;	/* UNUSED */
+
+	mbedtls_md_hmac_finish(ctx, out);
+}
+
+static void __hmac_sha1_cleanup(archive_hmac_sha1_ctx *ctx)
+{
+	mbedtls_md_free(ctx);
+	memset(ctx, 0, sizeof(*ctx));
+}
+
 #elif defined(HAVE_LIBNETTLE) && defined(HAVE_NETTLE_HMAC_H)
 
 static int
@@ -198,6 +248,7 @@
 __hmac_sha1_final(archive_hmac_sha1_ctx *ctx, uint8_t *out, size_t *out_len)
 {
 	unsigned int len = (unsigned int)*out_len;
+
 	HMAC_Final(*ctx, out, &len);
 	*out_len = len;
 }
diff --git a/Utilities/cmlibarchive/libarchive/archive_hmac_private.h b/Utilities/cmlibarchive/libarchive/archive_hmac_private.h
index eb45c4e..13a67d4 100644
--- a/Utilities/cmlibarchive/libarchive/archive_hmac_private.h
+++ b/Utilities/cmlibarchive/libarchive/archive_hmac_private.h
@@ -23,13 +23,12 @@
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
 
-#ifndef __LIBARCHIVE_BUILD
-#error This header is only to be used internally to libarchive.
-#endif
-
 #ifndef ARCHIVE_HMAC_PRIVATE_H_INCLUDED
 #define ARCHIVE_HMAC_PRIVATE_H_INCLUDED
 
+#ifndef __LIBARCHIVE_BUILD
+#error This header is only to be used internally to libarchive.
+#endif
 /*
  * On systems that do not support any recognized crypto libraries,
  * the archive_hmac.c file is expected to define no usable symbols.
@@ -64,6 +63,11 @@
 
 } archive_hmac_sha1_ctx;
 
+#elif defined(HAVE_LIBMBEDCRYPTO) && defined(HAVE_MBEDTLS_MD_H)
+#include <mbedtls/md.h>
+
+typedef mbedtls_md_context_t archive_hmac_sha1_ctx;
+
 #elif defined(HAVE_LIBNETTLE) && defined(HAVE_NETTLE_HMAC_H)
 #include <nettle/hmac.h>
 
diff --git a/Utilities/cmlibarchive/libarchive/archive_match.c b/Utilities/cmlibarchive/libarchive/archive_match.c
index f150e82..04747b1 100644
--- a/Utilities/cmlibarchive/libarchive/archive_match.c
+++ b/Utilities/cmlibarchive/libarchive/archive_match.c
@@ -93,6 +93,9 @@
 	/* exclusion/inclusion set flag. */
 	int			 setflag;
 
+	/* Recursively include directory content? */
+	int			 recursive_include;
+
 	/*
 	 * Matching filename patterns.
 	 */
@@ -223,6 +226,7 @@
 		return (NULL);
 	a->archive.magic = ARCHIVE_MATCH_MAGIC;
 	a->archive.state = ARCHIVE_STATE_NEW;
+	a->recursive_include = 1;
 	match_list_init(&(a->inclusions));
 	match_list_init(&(a->exclusions));
 	__archive_rb_tree_init(&(a->exclusion_tree), &rb_ops_mbs);
@@ -471,6 +475,28 @@
 }
 
 /*
+ * When recursive inclusion of directory content is enabled,
+ * an inclusion pattern that matches a directory will also
+ * include everything beneath that directory. Enabled by default.
+ *
+ * For compatibility with GNU tar, exclusion patterns always
+ * match if a subset of the full patch matches (i.e., they are
+ * are not rooted at the beginning of the path) and thus there
+ * is no corresponding non-recursive exclusion mode.
+ */
+int
+archive_match_set_inclusion_recursion(struct archive *_a, int enabled)
+{
+	struct archive_match *a;
+
+	archive_check_magic(_a, ARCHIVE_MATCH_MAGIC,
+	    ARCHIVE_STATE_NEW, "archive_match_set_inclusion_recursion");
+	a = (struct archive_match *)_a;
+	a->recursive_include = enabled;
+	return (ARCHIVE_OK);
+}
+
+/*
  * Utility functions to get statistic information for inclusion patterns.
  */
 int
@@ -781,7 +807,10 @@
 match_path_inclusion(struct archive_match *a, struct match *m,
     int mbs, const void *pn)
 {
-	int flag = PATHMATCH_NO_ANCHOR_END;
+	/* Recursive operation requires only a prefix match. */
+	int flag = a->recursive_include ?
+		PATHMATCH_NO_ANCHOR_END :
+		0;
 	int r;
 
 	if (mbs) {
@@ -1232,7 +1261,7 @@
 		archive_set_error(&(a->archive), EINVAL, "pathname is empty");
 		return (ARCHIVE_FAILED);
 	}
-	if (stat(path, &st) != 0) {
+	if (la_stat(path, &st) != 0) {
 		archive_set_error(&(a->archive), errno, "Failed to stat()");
 		return (ARCHIVE_FAILED);
 	}
diff --git a/Utilities/cmlibarchive/libarchive/archive_openssl_evp_private.h b/Utilities/cmlibarchive/libarchive/archive_openssl_evp_private.h
index 43a3ccc..ebb0670 100644
--- a/Utilities/cmlibarchive/libarchive/archive_openssl_evp_private.h
+++ b/Utilities/cmlibarchive/libarchive/archive_openssl_evp_private.h
@@ -22,9 +22,14 @@
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
+
 #ifndef ARCHIVE_OPENSSL_EVP_PRIVATE_H_INCLUDED
 #define ARCHIVE_OPENSSL_EVP_PRIVATE_H_INCLUDED
 
+#ifndef __LIBARCHIVE_BUILD
+#error This header is only to be used internally to libarchive.
+#endif
+
 #include <openssl/evp.h>
 #include <openssl/opensslv.h>
 
diff --git a/Utilities/cmlibarchive/libarchive/archive_openssl_hmac_private.h b/Utilities/cmlibarchive/libarchive/archive_openssl_hmac_private.h
index 921249b..25c8dda 100644
--- a/Utilities/cmlibarchive/libarchive/archive_openssl_hmac_private.h
+++ b/Utilities/cmlibarchive/libarchive/archive_openssl_hmac_private.h
@@ -22,9 +22,14 @@
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
+
 #ifndef ARCHIVE_OPENSSL_HMAC_PRIVATE_H_INCLUDED
 #define ARCHIVE_OPENSSL_HMAC_PRIVATE_H_INCLUDED
 
+#ifndef __LIBARCHIVE_BUILD
+#error This header is only to be used internally to libarchive.
+#endif
+
 #include <openssl/hmac.h>
 #include <openssl/opensslv.h>
 
diff --git a/Utilities/cmlibarchive/libarchive/archive_options_private.h b/Utilities/cmlibarchive/libarchive/archive_options_private.h
index 6ef0165..9a7f808 100644
--- a/Utilities/cmlibarchive/libarchive/archive_options_private.h
+++ b/Utilities/cmlibarchive/libarchive/archive_options_private.h
@@ -23,6 +23,9 @@
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
+#ifndef ARCHIVE_OPTIONS_PRIVATE_H_INCLUDED
+#define ARCHIVE_OPTIONS_PRIVATE_H_INCLUDED
+
 #include "archive_platform.h"
 __FBSDID("$FreeBSD$");
 
@@ -45,3 +48,4 @@
     const char *m, const char *o, const char *v,
     option_handler use_format_option, option_handler use_filter_option);
 
+#endif
diff --git a/Utilities/cmlibarchive/libarchive/archive_pack_dev.h b/Utilities/cmlibarchive/libarchive/archive_pack_dev.h
index 749fd3d..eaf23e3 100644
--- a/Utilities/cmlibarchive/libarchive/archive_pack_dev.h
+++ b/Utilities/cmlibarchive/libarchive/archive_pack_dev.h
@@ -31,8 +31,8 @@
 
 /* Originally from NetBSD's mknod(8) source. */
 
-#ifndef	_PACK_DEV_H
-#define	_PACK_DEV_H
+#ifndef	ARCHIVE_PACK_DEV_H
+#define	ARCHIVE_PACK_DEV_H
 
 typedef	dev_t pack_t(int, unsigned long [], const char **);
 
@@ -46,4 +46,4 @@
 					 (((y) << 12) & 0xfff00000) | \
 					 (((y) <<  0) & 0x000000ff)))
 
-#endif	/* _PACK_DEV_H */
+#endif	/* ARCHIVE_PACK_DEV_H */
diff --git a/Utilities/cmlibarchive/libarchive/archive_pathmatch.h b/Utilities/cmlibarchive/libarchive/archive_pathmatch.h
index e690177..9995142 100644
--- a/Utilities/cmlibarchive/libarchive/archive_pathmatch.h
+++ b/Utilities/cmlibarchive/libarchive/archive_pathmatch.h
@@ -26,15 +26,15 @@
  * $FreeBSD$
  */
 
+#ifndef ARCHIVE_PATHMATCH_H
+#define ARCHIVE_PATHMATCH_H
+
 #ifndef __LIBARCHIVE_BUILD
 #ifndef __LIBARCHIVE_TEST
 #error This header is only to be used internally to libarchive.
 #endif
 #endif
 
-#ifndef ARCHIVE_PATHMATCH_H
-#define ARCHIVE_PATHMATCH_H
-
 /* Don't anchor at beginning unless the pattern starts with "^" */
 #define PATHMATCH_NO_ANCHOR_START	1
 /* Don't anchor at end unless the pattern ends with "$" */
diff --git a/Utilities/cmlibarchive/libarchive/archive_platform.h b/Utilities/cmlibarchive/libarchive/archive_platform.h
index e161e64..3273930 100644
--- a/Utilities/cmlibarchive/libarchive/archive_platform.h
+++ b/Utilities/cmlibarchive/libarchive/archive_platform.h
@@ -69,6 +69,8 @@
  * either Windows or Posix APIs. */
 #if (defined(__WIN32__) || defined(_WIN32) || defined(__WIN32)) && !defined(__CYGWIN__)
 #include "archive_windows.h"
+#else
+#define la_stat(path,stref)		stat(path,stref)
 #endif
 
 /*
@@ -105,56 +107,44 @@
 
 /* Borland warns about its own constants!  */
 #if defined(__BORLANDC__)
-# if HAVE_DECL_UINT64_MAX
-#  undef	UINT64_MAX
-#  undef	HAVE_DECL_UINT64_MAX
-# endif
-# if HAVE_DECL_UINT64_MIN
-#  undef	UINT64_MIN
-#  undef	HAVE_DECL_UINT64_MIN
-# endif
-# if HAVE_DECL_INT64_MAX
-#  undef	INT64_MAX
-#  undef	HAVE_DECL_INT64_MAX
-# endif
-# if HAVE_DECL_INT64_MIN
-#  undef	INT64_MIN
-#  undef	HAVE_DECL_INT64_MIN
-# endif
+# undef	UINT64_MAX
+# undef	UINT64_MIN
+# undef	INT64_MAX
+# undef	INT64_MIN
 #endif
 
 /* Some platforms lack the standard *_MAX definitions. */
-#if !HAVE_DECL_SIZE_MAX
+#ifndef SIZE_MAX
 #define	SIZE_MAX (~(size_t)0)
 #endif
-#if !HAVE_DECL_SSIZE_MAX
+#ifndef SSIZE_MAX
 #define	SSIZE_MAX ((ssize_t)(SIZE_MAX >> 1))
 #endif
-#if !HAVE_DECL_UINT32_MAX
+#ifndef UINT32_MAX
 #define	UINT32_MAX (~(uint32_t)0)
 #endif
-#if !HAVE_DECL_INT32_MAX
+#ifndef INT32_MAX
 #define	INT32_MAX ((int32_t)(UINT32_MAX >> 1))
 #endif
-#if !HAVE_DECL_INT32_MIN
+#ifndef INT32_MIN
 #define	INT32_MIN ((int32_t)(~INT32_MAX))
 #endif
-#if !HAVE_DECL_UINT64_MAX
+#ifndef UINT64_MAX
 #define	UINT64_MAX (~(uint64_t)0)
 #endif
-#if !HAVE_DECL_INT64_MAX
+#ifndef INT64_MAX
 #define	INT64_MAX ((int64_t)(UINT64_MAX >> 1))
 #endif
-#if !HAVE_DECL_INT64_MIN
+#ifndef INT64_MIN
 #define	INT64_MIN ((int64_t)(~INT64_MAX))
 #endif
-#if !HAVE_DECL_UINTMAX_MAX
+#ifndef UINTMAX_MAX
 #define	UINTMAX_MAX (~(uintmax_t)0)
 #endif
-#if !HAVE_DECL_INTMAX_MAX
+#ifndef INTMAX_MAX
 #define	INTMAX_MAX ((intmax_t)(UINTMAX_MAX >> 1))
 #endif
-#if !HAVE_DECL_INTMAX_MIN
+#ifndef INTMAX_MIN
 #define	INTMAX_MIN ((intmax_t)(~INTMAX_MAX))
 #endif
 
diff --git a/Utilities/cmlibarchive/libarchive/archive_platform_acl.h b/Utilities/cmlibarchive/libarchive/archive_platform_acl.h
index 3498f78..264e6de 100644
--- a/Utilities/cmlibarchive/libarchive/archive_platform_acl.h
+++ b/Utilities/cmlibarchive/libarchive/archive_platform_acl.h
@@ -30,6 +30,12 @@
 #ifndef ARCHIVE_PLATFORM_ACL_H_INCLUDED
 #define ARCHIVE_PLATFORM_ACL_H_INCLUDED
 
+#ifndef __LIBARCHIVE_BUILD
+#ifndef __LIBARCHIVE_TEST_COMMON
+#error This header is only to be used internally to libarchive.
+#endif
+#endif
+
 /*
  * Determine what ACL types are supported
  */
diff --git a/Utilities/cmlibarchive/libarchive/archive_platform_xattr.h b/Utilities/cmlibarchive/libarchive/archive_platform_xattr.h
index 4edfecf..ad4b90a 100644
--- a/Utilities/cmlibarchive/libarchive/archive_platform_xattr.h
+++ b/Utilities/cmlibarchive/libarchive/archive_platform_xattr.h
@@ -30,6 +30,12 @@
 #ifndef ARCHIVE_PLATFORM_XATTR_H_INCLUDED
 #define ARCHIVE_PLATFORM_XATTR_H_INCLUDED
 
+#ifndef __LIBARCHIVE_BUILD
+#ifndef __LIBARCHIVE_TEST_COMMON
+#error This header is only to be used internally to libarchive.
+#endif
+#endif
+
 /*
  * Determine if we support extended attributes
  */
diff --git a/Utilities/cmlibarchive/libarchive/archive_ppmd7.c b/Utilities/cmlibarchive/libarchive/archive_ppmd7.c
index d0bacc6..4029395 100644
--- a/Utilities/cmlibarchive/libarchive/archive_ppmd7.c
+++ b/Utilities/cmlibarchive/libarchive/archive_ppmd7.c
@@ -1000,7 +1000,7 @@
 
 static void RangeEnc_Encode(CPpmd7z_RangeEnc *p, UInt32 start, UInt32 size, UInt32 total)
 {
-  p->Low += start * (p->Range /= total);
+  p->Low += (UInt64)start * (UInt64)(p->Range /= total);
   p->Range *= size;
   while (p->Range < kTopValue)
   {
diff --git a/Utilities/cmlibarchive/libarchive/archive_ppmd7_private.h b/Utilities/cmlibarchive/libarchive/archive_ppmd7_private.h
index 577d6fb..71b9544 100644
--- a/Utilities/cmlibarchive/libarchive/archive_ppmd7_private.h
+++ b/Utilities/cmlibarchive/libarchive/archive_ppmd7_private.h
@@ -6,13 +6,13 @@
 of RangeCoder from 7z, instead of RangeCoder from original PPMd var.H.
 If you need the compatibility with original PPMd var.H, you can use external RangeDecoder */
 
+#ifndef ARCHIVE_PPMD7_PRIVATE_H_INCLUDED
+#define ARCHIVE_PPMD7_PRIVATE_H_INCLUDED
+
 #ifndef __LIBARCHIVE_BUILD
 #error This header is only to be used internally to libarchive.
 #endif
 
-#ifndef ARCHIVE_PPMD7_PRIVATE_H_INCLUDED
-#define ARCHIVE_PPMD7_PRIVATE_H_INCLUDED
-
 #include "archive_ppmd_private.h"
 
 #define PPMD7_MIN_ORDER 2
diff --git a/Utilities/cmlibarchive/libarchive/archive_ppmd8.c b/Utilities/cmlibarchive/libarchive/archive_ppmd8.c
new file mode 100644
index 0000000..d177939
--- /dev/null
+++ b/Utilities/cmlibarchive/libarchive/archive_ppmd8.c
@@ -0,0 +1,1287 @@
+/* Ppmd8.c -- PPMdI codec
+2016-05-21 : Igor Pavlov : Public domain
+This code is based on PPMd var.I (2002): Dmitry Shkarin : Public domain */
+
+#include "archive_platform.h"
+
+#include <string.h>
+
+#include "archive_ppmd8_private.h"
+
+const Byte PPMD8_kExpEscape[16] = { 25, 14, 9, 7, 5, 5, 4, 4, 4, 3, 3, 3, 2, 2, 2, 2 };
+static const UInt16 kInitBinEsc[] = { 0x3CDD, 0x1F3F, 0x59BF, 0x48F3, 0x64A1, 0x5ABC, 0x6632, 0x6051};
+
+#define MAX_FREQ 124
+#define UNIT_SIZE 12
+
+#define U2B(nu) ((UInt32)(nu) * UNIT_SIZE)
+#define U2I(nu) (p->Units2Indx[(nu) - 1])
+#define I2U(indx) (p->Indx2Units[indx])
+
+#ifdef PPMD_32BIT
+  #define REF(ptr) (ptr)
+#else
+  #define REF(ptr) ((UInt32)((Byte *)(ptr) - (p)->Base))
+#endif
+
+#define STATS_REF(ptr) ((CPpmd_State_Ref)REF(ptr))
+
+#define CTX(ref) ((CPpmd8_Context *)Ppmd8_GetContext(p, ref))
+#define STATS(ctx) Ppmd8_GetStats(p, ctx)
+#define ONE_STATE(ctx) Ppmd8Context_OneState(ctx)
+#define SUFFIX(ctx) CTX((ctx)->Suffix)
+
+#define kTop (1 << 24)
+#define kBot (1 << 15)
+
+typedef CPpmd8_Context * CTX_PTR;
+
+struct CPpmd8_Node_;
+
+typedef
+  #ifdef PPMD_32BIT
+    struct CPpmd8_Node_ *
+  #else
+    UInt32
+  #endif
+  CPpmd8_Node_Ref;
+
+typedef struct CPpmd8_Node_
+{
+  UInt32 Stamp;
+  CPpmd8_Node_Ref Next;
+  UInt32 NU;
+} CPpmd8_Node;
+
+#ifdef PPMD_32BIT
+  #define NODE(ptr) (ptr)
+#else
+  #define NODE(offs) ((CPpmd8_Node *)(p->Base + (offs)))
+#endif
+
+#define EMPTY_NODE 0xFFFFFFFF
+
+void Ppmd8_Construct(CPpmd8 *p)
+{
+  unsigned i, k, m;
+
+  p->Base = 0;
+
+  for (i = 0, k = 0; i < PPMD_NUM_INDEXES; i++)
+  {
+    unsigned step = (i >= 12 ? 4 : (i >> 2) + 1);
+    do { p->Units2Indx[k++] = (Byte)i; } while (--step);
+    p->Indx2Units[i] = (Byte)k;
+  }
+
+  p->NS2BSIndx[0] = (0 << 1);
+  p->NS2BSIndx[1] = (1 << 1);
+  memset(p->NS2BSIndx + 2, (2 << 1), 9);
+  memset(p->NS2BSIndx + 11, (3 << 1), 256 - 11);
+
+  for (i = 0; i < 5; i++)
+    p->NS2Indx[i] = (Byte)i;
+  for (m = i, k = 1; i < 260; i++)
+  {
+    p->NS2Indx[i] = (Byte)m;
+    if (--k == 0)
+      k = (++m) - 4;
+  }
+}
+
+void Ppmd8_Free(CPpmd8 *p)
+{
+  free(p->Base);
+  p->Size = 0;
+  p->Base = 0;
+}
+
+Bool Ppmd8_Alloc(CPpmd8 *p, UInt32 size)
+{
+  if (p->Base == 0 || p->Size != size)
+  {
+    Ppmd8_Free(p);
+    p->AlignOffset =
+      #ifdef PPMD_32BIT
+        (4 - size) & 3;
+      #else
+        4 - (size & 3);
+      #endif
+    if ((p->Base = (Byte *)malloc(p->AlignOffset + size)) == 0)
+      return False;
+    p->Size = size;
+  }
+  return True;
+}
+
+static void InsertNode(CPpmd8 *p, void *node, unsigned indx)
+{
+  ((CPpmd8_Node *)node)->Stamp = EMPTY_NODE;
+  ((CPpmd8_Node *)node)->Next = (CPpmd8_Node_Ref)p->FreeList[indx];
+  ((CPpmd8_Node *)node)->NU = I2U(indx);
+  p->FreeList[indx] = REF(node);
+  p->Stamps[indx]++;
+}
+
+static void *RemoveNode(CPpmd8 *p, unsigned indx)
+{
+  CPpmd8_Node *node = NODE((CPpmd8_Node_Ref)p->FreeList[indx]);
+  p->FreeList[indx] = node->Next;
+  p->Stamps[indx]--;
+  return node;
+}
+
+static void SplitBlock(CPpmd8 *p, void *ptr, unsigned oldIndx, unsigned newIndx)
+{
+  unsigned i, nu = I2U(oldIndx) - I2U(newIndx);
+  ptr = (Byte *)ptr + U2B(I2U(newIndx));
+  if (I2U(i = U2I(nu)) != nu)
+  {
+    unsigned k = I2U(--i);
+    InsertNode(p, ((Byte *)ptr) + U2B(k), nu - k - 1);
+  }
+  InsertNode(p, ptr, i);
+}
+
+static void GlueFreeBlocks(CPpmd8 *p)
+{
+  CPpmd8_Node_Ref head = 0;
+  CPpmd8_Node_Ref *prev = &head;
+  unsigned i;
+
+  p->GlueCount = 1 << 13;
+  memset(p->Stamps, 0, sizeof(p->Stamps));
+  
+  /* Order-0 context is always at top UNIT, so we don't need guard NODE at the end.
+     All blocks up to p->LoUnit can be free, so we need guard NODE at LoUnit. */
+  if (p->LoUnit != p->HiUnit)
+    ((CPpmd8_Node *)p->LoUnit)->Stamp = 0;
+
+  /* Glue free blocks */
+  for (i = 0; i < PPMD_NUM_INDEXES; i++)
+  {
+    CPpmd8_Node_Ref next = (CPpmd8_Node_Ref)p->FreeList[i];
+    p->FreeList[i] = 0;
+    while (next != 0)
+    {
+      CPpmd8_Node *node = NODE(next);
+      if (node->NU != 0)
+      {
+        CPpmd8_Node *node2;
+        *prev = next;
+        prev = &(node->Next);
+        while ((node2 = node + node->NU)->Stamp == EMPTY_NODE)
+        {
+          node->NU += node2->NU;
+          node2->NU = 0;
+        }
+      }
+      next = node->Next;
+    }
+  }
+  *prev = 0;
+  
+  /* Fill lists of free blocks */
+  while (head != 0)
+  {
+    CPpmd8_Node *node = NODE(head);
+    unsigned nu;
+    head = node->Next;
+    nu = node->NU;
+    if (nu == 0)
+      continue;
+    for (; nu > 128; nu -= 128, node += 128)
+      InsertNode(p, node, PPMD_NUM_INDEXES - 1);
+    if (I2U(i = U2I(nu)) != nu)
+    {
+      unsigned k = I2U(--i);
+      InsertNode(p, node + k, nu - k - 1);
+    }
+    InsertNode(p, node, i);
+  }
+}
+
+static void *AllocUnitsRare(CPpmd8 *p, unsigned indx)
+{
+  unsigned i;
+  void *retVal;
+  if (p->GlueCount == 0)
+  {
+    GlueFreeBlocks(p);
+    if (p->FreeList[indx] != 0)
+      return RemoveNode(p, indx);
+  }
+  i = indx;
+  do
+  {
+    if (++i == PPMD_NUM_INDEXES)
+    {
+      UInt32 numBytes = U2B(I2U(indx));
+      p->GlueCount--;
+      return ((UInt32)(p->UnitsStart - p->Text) > numBytes) ? (p->UnitsStart -= numBytes) : (NULL);
+    }
+  }
+  while (p->FreeList[i] == 0);
+  retVal = RemoveNode(p, i);
+  SplitBlock(p, retVal, i, indx);
+  return retVal;
+}
+
+static void *AllocUnits(CPpmd8 *p, unsigned indx)
+{
+  UInt32 numBytes;
+  if (p->FreeList[indx] != 0)
+    return RemoveNode(p, indx);
+  numBytes = U2B(I2U(indx));
+  if (numBytes <= (UInt32)(p->HiUnit - p->LoUnit))
+  {
+    void *retVal = p->LoUnit;
+    p->LoUnit += numBytes;
+    return retVal;
+  }
+  return AllocUnitsRare(p, indx);
+}
+
+#define MyMem12Cpy(dest, src, num) \
+  { UInt32 *d = (UInt32 *)dest; const UInt32 *z = (const UInt32 *)src; UInt32 n = num; \
+    do { d[0] = z[0]; d[1] = z[1]; d[2] = z[2]; z += 3; d += 3; } while (--n); }
+
+static void *ShrinkUnits(CPpmd8 *p, void *oldPtr, unsigned oldNU, unsigned newNU)
+{
+  unsigned i0 = U2I(oldNU);
+  unsigned i1 = U2I(newNU);
+  if (i0 == i1)
+    return oldPtr;
+  if (p->FreeList[i1] != 0)
+  {
+    void *ptr = RemoveNode(p, i1);
+    MyMem12Cpy(ptr, oldPtr, newNU);
+    InsertNode(p, oldPtr, i0);
+    return ptr;
+  }
+  SplitBlock(p, oldPtr, i0, i1);
+  return oldPtr;
+}
+
+static void FreeUnits(CPpmd8 *p, void *ptr, unsigned nu)
+{
+  InsertNode(p, ptr, U2I(nu));
+}
+
+static void SpecialFreeUnit(CPpmd8 *p, void *ptr)
+{
+  if ((Byte *)ptr != p->UnitsStart)
+    InsertNode(p, ptr, 0);
+  else
+  {
+    #ifdef PPMD8_FREEZE_SUPPORT
+    *(UInt32 *)ptr = EMPTY_NODE; /* it's used for (Flags == 0xFF) check in RemoveBinContexts */
+    #endif
+    p->UnitsStart += UNIT_SIZE;
+  }
+}
+
+static void *MoveUnitsUp(CPpmd8 *p, void *oldPtr, unsigned nu)
+{
+  unsigned indx = U2I(nu);
+  void *ptr;
+  if ((Byte *)oldPtr > p->UnitsStart + 16 * 1024 || REF(oldPtr) > p->FreeList[indx])
+    return oldPtr;
+  ptr = RemoveNode(p, indx);
+  MyMem12Cpy(ptr, oldPtr, nu);
+  if ((Byte*)oldPtr != p->UnitsStart)
+    InsertNode(p, oldPtr, indx);
+  else
+    p->UnitsStart += U2B(I2U(indx));
+  return ptr;
+}
+
+static void ExpandTextArea(CPpmd8 *p)
+{
+  UInt32 count[PPMD_NUM_INDEXES];
+  unsigned i;
+  memset(count, 0, sizeof(count));
+  if (p->LoUnit != p->HiUnit)
+    ((CPpmd8_Node *)p->LoUnit)->Stamp = 0;
+  
+  {
+    CPpmd8_Node *node = (CPpmd8_Node *)p->UnitsStart;
+    for (; node->Stamp == EMPTY_NODE; node += node->NU)
+    {
+      node->Stamp = 0;
+      count[U2I(node->NU)]++;
+    }
+    p->UnitsStart = (Byte *)node;
+  }
+  
+  for (i = 0; i < PPMD_NUM_INDEXES; i++)
+  {
+    CPpmd8_Node_Ref *next = (CPpmd8_Node_Ref *)&p->FreeList[i];
+    while (count[i] != 0)
+    {
+      CPpmd8_Node *node = NODE(*next);
+      while (node->Stamp == 0)
+      {
+        *next = node->Next;
+        node = NODE(*next);
+        p->Stamps[i]--;
+        if (--count[i] == 0)
+          break;
+      }
+      next = &node->Next;
+    }
+  }
+}
+
+#define SUCCESSOR(p) ((CPpmd_Void_Ref)((p)->SuccessorLow | ((UInt32)(p)->SuccessorHigh << 16)))
+
+static void SetSuccessor(CPpmd_State *p, CPpmd_Void_Ref v)
+{
+  (p)->SuccessorLow = (UInt16)((UInt32)(v) & 0xFFFF);
+  (p)->SuccessorHigh = (UInt16)(((UInt32)(v) >> 16) & 0xFFFF);
+}
+
+#define RESET_TEXT(offs) { p->Text = p->Base + p->AlignOffset + (offs); }
+
+static void RestartModel(CPpmd8 *p)
+{
+  unsigned i, k, m, r;
+
+  memset(p->FreeList, 0, sizeof(p->FreeList));
+  memset(p->Stamps, 0, sizeof(p->Stamps));
+  RESET_TEXT(0);
+  p->HiUnit = p->Text + p->Size;
+  p->LoUnit = p->UnitsStart = p->HiUnit - p->Size / 8 / UNIT_SIZE * 7 * UNIT_SIZE;
+  p->GlueCount = 0;
+
+  p->OrderFall = p->MaxOrder;
+  p->RunLength = p->InitRL = -(Int32)((p->MaxOrder < 12) ? p->MaxOrder : 12) - 1;
+  p->PrevSuccess = 0;
+
+  p->MinContext = p->MaxContext = (CTX_PTR)(p->HiUnit -= UNIT_SIZE); /* AllocContext(p); */
+  p->MinContext->Suffix = 0;
+  p->MinContext->NumStats = 255;
+  p->MinContext->Flags = 0;
+  p->MinContext->SummFreq = 256 + 1;
+  p->FoundState = (CPpmd_State *)p->LoUnit; /* AllocUnits(p, PPMD_NUM_INDEXES - 1); */
+  p->LoUnit += U2B(256 / 2);
+  p->MinContext->Stats = REF(p->FoundState);
+  for (i = 0; i < 256; i++)
+  {
+    CPpmd_State *s = &p->FoundState[i];
+    s->Symbol = (Byte)i;
+    s->Freq = 1;
+    SetSuccessor(s, 0);
+  }
+
+  for (i = m = 0; m < 25; m++)
+  {
+    while (p->NS2Indx[i] == m)
+      i++;
+    for (k = 0; k < 8; k++)
+    {
+      UInt16 val = (UInt16)(PPMD_BIN_SCALE - kInitBinEsc[k] / (i + 1));
+      UInt16 *dest = p->BinSumm[m] + k;
+      for (r = 0; r < 64; r += 8)
+        dest[r] = val;
+    }
+  }
+
+  for (i = m = 0; m < 24; m++)
+  {
+    while (p->NS2Indx[i + 3] == m + 3)
+      i++;
+    for (k = 0; k < 32; k++)
+    {
+      CPpmd_See *s = &p->See[m][k];
+      s->Summ = (UInt16)((2 * i + 5) << (s->Shift = PPMD_PERIOD_BITS - 4));
+      s->Count = 7;
+    }
+  }
+}
+
+void Ppmd8_Init(CPpmd8 *p, unsigned maxOrder, unsigned restoreMethod)
+{
+  p->MaxOrder = maxOrder;
+  p->RestoreMethod = restoreMethod;
+  RestartModel(p);
+  p->DummySee.Shift = PPMD_PERIOD_BITS;
+  p->DummySee.Summ = 0; /* unused */
+  p->DummySee.Count = 64; /* unused */
+}
+
+static void Refresh(CPpmd8 *p, CTX_PTR ctx, unsigned oldNU, unsigned scale)
+{
+  unsigned i = ctx->NumStats, escFreq, sumFreq, flags;
+  CPpmd_State *s = (CPpmd_State *)ShrinkUnits(p, STATS(ctx), oldNU, (i + 2) >> 1);
+  ctx->Stats = REF(s);
+  #ifdef PPMD8_FREEZE_SUPPORT
+  /* fixed over Shkarin's code. Fixed code is not compatible with original code for some files in FREEZE mode. */
+  scale |= (ctx->SummFreq >= ((UInt32)1 << 15));
+  #endif
+  flags = (ctx->Flags & (0x10 + 0x04 * scale)) + 0x08 * (s->Symbol >= 0x40);
+  escFreq = ctx->SummFreq - s->Freq;
+  sumFreq = (s->Freq = (Byte)((s->Freq + scale) >> scale));
+  do
+  {
+    escFreq -= (++s)->Freq;
+    sumFreq += (s->Freq = (Byte)((s->Freq + scale) >> scale));
+    flags |= 0x08 * (s->Symbol >= 0x40);
+  }
+  while (--i);
+  ctx->SummFreq = (UInt16)(sumFreq + ((escFreq + scale) >> scale));
+  ctx->Flags = (Byte)flags;
+}
+
+static void SwapStates(CPpmd_State *t1, CPpmd_State *t2)
+{
+  CPpmd_State tmp = *t1;
+  *t1 = *t2;
+  *t2 = tmp;
+}
+
+static CPpmd_Void_Ref CutOff(CPpmd8 *p, CTX_PTR ctx, unsigned order)
+{
+  int i;
+  unsigned tmp;
+  CPpmd_State *s;
+  
+  if (!ctx->NumStats)
+  {
+    s = ONE_STATE(ctx);
+    if ((Byte *)Ppmd8_GetPtr(p, SUCCESSOR(s)) >= p->UnitsStart)
+    {
+      if (order < p->MaxOrder)
+        SetSuccessor(s, CutOff(p, CTX(SUCCESSOR(s)), order + 1));
+      else
+        SetSuccessor(s, 0);
+      if (SUCCESSOR(s) || order <= 9) /* O_BOUND */
+        return REF(ctx);
+    }
+    SpecialFreeUnit(p, ctx);
+    return 0;
+  }
+
+  ctx->Stats = STATS_REF(MoveUnitsUp(p, STATS(ctx), tmp = ((unsigned)ctx->NumStats + 2) >> 1));
+
+  for (s = STATS(ctx) + (i = ctx->NumStats); s >= STATS(ctx); s--)
+    if ((Byte *)Ppmd8_GetPtr(p, SUCCESSOR(s)) < p->UnitsStart)
+    {
+      CPpmd_State *s2 = STATS(ctx) + (i--);
+      SetSuccessor(s, 0);
+      SwapStates(s, s2);
+    }
+    else if (order < p->MaxOrder)
+      SetSuccessor(s, CutOff(p, CTX(SUCCESSOR(s)), order + 1));
+    else
+      SetSuccessor(s, 0);
+    
+  if (i != ctx->NumStats && order)
+  {
+    ctx->NumStats = (Byte)i;
+    s = STATS(ctx);
+    if (i < 0)
+    {
+      FreeUnits(p, s, tmp);
+      SpecialFreeUnit(p, ctx);
+      return 0;
+    }
+    if (i == 0)
+    {
+      ctx->Flags = (Byte)((ctx->Flags & 0x10) + 0x08 * (s->Symbol >= 0x40));
+      *ONE_STATE(ctx) = *s;
+      FreeUnits(p, s, tmp);
+      /* 9.31: the code was fixed. It's was not BUG, if Freq <= MAX_FREQ = 124 */
+      ONE_STATE(ctx)->Freq = (Byte)(((unsigned)ONE_STATE(ctx)->Freq + 11) >> 3);
+    }
+    else
+      Refresh(p, ctx, tmp, ctx->SummFreq > 16 * i);
+  }
+  return REF(ctx);
+}
+
+#ifdef PPMD8_FREEZE_SUPPORT
+static CPpmd_Void_Ref RemoveBinContexts(CPpmd8 *p, CTX_PTR ctx, unsigned order)
+{
+  CPpmd_State *s;
+  if (!ctx->NumStats)
+  {
+    s = ONE_STATE(ctx);
+    if ((Byte *)Ppmd8_GetPtr(p, SUCCESSOR(s)) >= p->UnitsStart && order < p->MaxOrder)
+      SetSuccessor(s, RemoveBinContexts(p, CTX(SUCCESSOR(s)), order + 1));
+    else
+      SetSuccessor(s, 0);
+    /* Suffix context can be removed already, since different (high-order)
+       Successors may refer to same context. So we check Flags == 0xFF (Stamp == EMPTY_NODE) */
+    if (!SUCCESSOR(s) && (!SUFFIX(ctx)->NumStats || SUFFIX(ctx)->Flags == 0xFF))
+    {
+      FreeUnits(p, ctx, 1);
+      return 0;
+    }
+    else
+      return REF(ctx);
+  }
+
+  for (s = STATS(ctx) + ctx->NumStats; s >= STATS(ctx); s--)
+    if ((Byte *)Ppmd8_GetPtr(p, SUCCESSOR(s)) >= p->UnitsStart && order < p->MaxOrder)
+      SetSuccessor(s, RemoveBinContexts(p, CTX(SUCCESSOR(s)), order + 1));
+    else
+      SetSuccessor(s, 0);
+  
+  return REF(ctx);
+}
+#endif
+
+static UInt32 GetUsedMemory(const CPpmd8 *p)
+{
+  UInt32 v = 0;
+  unsigned i;
+  for (i = 0; i < PPMD_NUM_INDEXES; i++)
+    v += p->Stamps[i] * I2U(i);
+  return p->Size - (UInt32)(p->HiUnit - p->LoUnit) - (UInt32)(p->UnitsStart - p->Text) - U2B(v);
+}
+
+#ifdef PPMD8_FREEZE_SUPPORT
+  #define RESTORE_MODEL(c1, fSuccessor) RestoreModel(p, c1, fSuccessor)
+#else
+  #define RESTORE_MODEL(c1, fSuccessor) RestoreModel(p, c1)
+#endif
+
+static void RestoreModel(CPpmd8 *p, CTX_PTR c1
+    #ifdef PPMD8_FREEZE_SUPPORT
+    , CTX_PTR fSuccessor
+    #endif
+    )
+{
+  CTX_PTR c;
+  CPpmd_State *s;
+  RESET_TEXT(0);
+  for (c = p->MaxContext; c != c1; c = SUFFIX(c))
+    if (--(c->NumStats) == 0)
+    {
+      s = STATS(c);
+      c->Flags = (Byte)((c->Flags & 0x10) + 0x08 * (s->Symbol >= 0x40));
+      *ONE_STATE(c) = *s;
+      SpecialFreeUnit(p, s);
+      ONE_STATE(c)->Freq = (Byte)(((unsigned)ONE_STATE(c)->Freq + 11) >> 3);
+    }
+    else
+      Refresh(p, c, (c->NumStats+3) >> 1, 0);
+ 
+  for (; c != p->MinContext; c = SUFFIX(c))
+    if (!c->NumStats)
+      ONE_STATE(c)->Freq = (Byte)(ONE_STATE(c)->Freq - (ONE_STATE(c)->Freq >> 1));
+    else if ((c->SummFreq += 4) > 128 + 4 * c->NumStats)
+      Refresh(p, c, (c->NumStats + 2) >> 1, 1);
+
+  #ifdef PPMD8_FREEZE_SUPPORT
+  if (p->RestoreMethod > PPMD8_RESTORE_METHOD_FREEZE)
+  {
+    p->MaxContext = fSuccessor;
+    p->GlueCount += !(p->Stamps[1] & 1);
+  }
+  else if (p->RestoreMethod == PPMD8_RESTORE_METHOD_FREEZE)
+  {
+    while (p->MaxContext->Suffix)
+      p->MaxContext = SUFFIX(p->MaxContext);
+    RemoveBinContexts(p, p->MaxContext, 0);
+    p->RestoreMethod++;
+    p->GlueCount = 0;
+    p->OrderFall = p->MaxOrder;
+  }
+  else
+  #endif
+  if (p->RestoreMethod == PPMD8_RESTORE_METHOD_RESTART || GetUsedMemory(p) < (p->Size >> 1))
+    RestartModel(p);
+  else
+  {
+    while (p->MaxContext->Suffix)
+      p->MaxContext = SUFFIX(p->MaxContext);
+    do
+    {
+      CutOff(p, p->MaxContext, 0);
+      ExpandTextArea(p);
+    }
+    while (GetUsedMemory(p) > 3 * (p->Size >> 2));
+    p->GlueCount = 0;
+    p->OrderFall = p->MaxOrder;
+  }
+}
+
+static CTX_PTR CreateSuccessors(CPpmd8 *p, Bool skip, CPpmd_State *s1, CTX_PTR c)
+{
+  CPpmd_State upState;
+  Byte flags;
+  CPpmd_Byte_Ref upBranch = (CPpmd_Byte_Ref)SUCCESSOR(p->FoundState);
+  /* fixed over Shkarin's code. Maybe it could work without + 1 too. */
+  CPpmd_State *ps[PPMD8_MAX_ORDER + 1];
+  unsigned numPs = 0;
+  
+  if (!skip)
+    ps[numPs++] = p->FoundState;
+  
+  while (c->Suffix)
+  {
+    CPpmd_Void_Ref successor;
+    CPpmd_State *s;
+    c = SUFFIX(c);
+    if (s1)
+    {
+      s = s1;
+      s1 = NULL;
+    }
+    else if (c->NumStats != 0)
+    {
+      for (s = STATS(c); s->Symbol != p->FoundState->Symbol; s++);
+      if (s->Freq < MAX_FREQ - 9)
+      {
+        s->Freq++;
+        c->SummFreq++;
+      }
+    }
+    else
+    {
+      s = ONE_STATE(c);
+      s->Freq = (Byte)(s->Freq + (!SUFFIX(c)->NumStats & (s->Freq < 24)));
+    }
+    successor = SUCCESSOR(s);
+    if (successor != upBranch)
+    {
+      c = CTX(successor);
+      if (numPs == 0)
+        return c;
+      break;
+    }
+    ps[numPs++] = s;
+  }
+  
+  upState.Symbol = *(const Byte *)Ppmd8_GetPtr(p, upBranch);
+  SetSuccessor(&upState, upBranch + 1);
+  flags = (Byte)(0x10 * (p->FoundState->Symbol >= 0x40) + 0x08 * (upState.Symbol >= 0x40));
+
+  if (c->NumStats == 0)
+    upState.Freq = ONE_STATE(c)->Freq;
+  else
+  {
+    UInt32 cf, s0;
+    CPpmd_State *s;
+    for (s = STATS(c); s->Symbol != upState.Symbol; s++);
+    cf = s->Freq - 1;
+    s0 = c->SummFreq - c->NumStats - cf;
+    upState.Freq = (Byte)(1 + ((2 * cf <= s0) ? (5 * cf > s0) : ((cf + 2 * s0 - 3) / s0)));
+  }
+
+  do
+  {
+    /* Create Child */
+    CTX_PTR c1; /* = AllocContext(p); */
+    if (p->HiUnit != p->LoUnit)
+      c1 = (CTX_PTR)(p->HiUnit -= UNIT_SIZE);
+    else if (p->FreeList[0] != 0)
+      c1 = (CTX_PTR)RemoveNode(p, 0);
+    else
+    {
+      c1 = (CTX_PTR)AllocUnitsRare(p, 0);
+      if (!c1)
+        return NULL;
+    }
+    c1->NumStats = 0;
+    c1->Flags = flags;
+    *ONE_STATE(c1) = upState;
+    c1->Suffix = REF(c);
+    SetSuccessor(ps[--numPs], REF(c1));
+    c = c1;
+  }
+  while (numPs != 0);
+  
+  return c;
+}
+
+static CTX_PTR ReduceOrder(CPpmd8 *p, CPpmd_State *s1, CTX_PTR c)
+{
+  CPpmd_State *s = NULL;
+  CTX_PTR c1 = c;
+  CPpmd_Void_Ref upBranch = REF(p->Text);
+  
+  #ifdef PPMD8_FREEZE_SUPPORT
+  /* The BUG in Shkarin's code was fixed: ps could overflow in CUT_OFF mode. */
+  CPpmd_State *ps[PPMD8_MAX_ORDER + 1];
+  unsigned numPs = 0;
+  ps[numPs++] = p->FoundState;
+  #endif
+
+  SetSuccessor(p->FoundState, upBranch);
+  p->OrderFall++;
+
+  for (;;)
+  {
+    if (s1)
+    {
+      c = SUFFIX(c);
+      s = s1;
+      s1 = NULL;
+    }
+    else
+    {
+      if (!c->Suffix)
+      {
+        #ifdef PPMD8_FREEZE_SUPPORT
+        if (p->RestoreMethod > PPMD8_RESTORE_METHOD_FREEZE)
+        {
+          do { SetSuccessor(ps[--numPs], REF(c)); } while (numPs);
+          RESET_TEXT(1);
+          p->OrderFall = 1;
+        }
+        #endif
+        return c;
+      }
+      c = SUFFIX(c);
+      if (c->NumStats)
+      {
+        if ((s = STATS(c))->Symbol != p->FoundState->Symbol)
+          do { s++; } while (s->Symbol != p->FoundState->Symbol);
+        if (s->Freq < MAX_FREQ - 9)
+        {
+          s->Freq += 2;
+          c->SummFreq += 2;
+        }
+      }
+      else
+      {
+        s = ONE_STATE(c);
+        s->Freq = (Byte)(s->Freq + (s->Freq < 32));
+      }
+    }
+    if (SUCCESSOR(s))
+      break;
+    #ifdef PPMD8_FREEZE_SUPPORT
+    ps[numPs++] = s;
+    #endif
+    SetSuccessor(s, upBranch);
+    p->OrderFall++;
+  }
+  
+  #ifdef PPMD8_FREEZE_SUPPORT
+  if (p->RestoreMethod > PPMD8_RESTORE_METHOD_FREEZE)
+  {
+    c = CTX(SUCCESSOR(s));
+    do { SetSuccessor(ps[--numPs], REF(c)); } while (numPs);
+    RESET_TEXT(1);
+    p->OrderFall = 1;
+    return c;
+  }
+  else
+  #endif
+  if (SUCCESSOR(s) <= upBranch)
+  {
+    CTX_PTR successor;
+    CPpmd_State *s2 = p->FoundState;
+    p->FoundState = s;
+
+    successor = CreateSuccessors(p, False, NULL, c);
+    if (successor == NULL)
+      SetSuccessor(s, 0);
+    else
+      SetSuccessor(s, REF(successor));
+    p->FoundState = s2;
+  }
+  
+  if (p->OrderFall == 1 && c1 == p->MaxContext)
+  {
+    SetSuccessor(p->FoundState, SUCCESSOR(s));
+    p->Text--;
+  }
+  if (SUCCESSOR(s) == 0)
+    return NULL;
+  return CTX(SUCCESSOR(s));
+}
+
+static void UpdateModel(CPpmd8 *p)
+{
+  CPpmd_Void_Ref successor, fSuccessor = SUCCESSOR(p->FoundState);
+  CTX_PTR c;
+  unsigned s0, ns, fFreq = p->FoundState->Freq;
+  Byte flag, fSymbol = p->FoundState->Symbol;
+  CPpmd_State *s = NULL;
+  
+  if (p->FoundState->Freq < MAX_FREQ / 4 && p->MinContext->Suffix != 0)
+  {
+    c = SUFFIX(p->MinContext);
+    
+    if (c->NumStats == 0)
+    {
+      s = ONE_STATE(c);
+      if (s->Freq < 32)
+        s->Freq++;
+    }
+    else
+    {
+      s = STATS(c);
+      if (s->Symbol != p->FoundState->Symbol)
+      {
+        do { s++; } while (s->Symbol != p->FoundState->Symbol);
+        if (s[0].Freq >= s[-1].Freq)
+        {
+          SwapStates(&s[0], &s[-1]);
+          s--;
+        }
+      }
+      if (s->Freq < MAX_FREQ - 9)
+      {
+        s->Freq += 2;
+        c->SummFreq += 2;
+      }
+    }
+  }
+  
+  c = p->MaxContext;
+  if (p->OrderFall == 0 && fSuccessor)
+  {
+    CTX_PTR cs = CreateSuccessors(p, True, s, p->MinContext);
+    if (cs == 0)
+    {
+      SetSuccessor(p->FoundState, 0);
+      RESTORE_MODEL(c, CTX(fSuccessor));
+    }
+    else
+    {
+      SetSuccessor(p->FoundState, REF(cs));
+      p->MaxContext = cs;
+    }
+    return;
+  }
+  
+  *p->Text++ = p->FoundState->Symbol;
+  successor = REF(p->Text);
+  if (p->Text >= p->UnitsStart)
+  {
+    RESTORE_MODEL(c, CTX(fSuccessor)); /* check it */
+    return;
+  }
+  
+  if (!fSuccessor)
+  {
+    CTX_PTR cs = ReduceOrder(p, s, p->MinContext);
+    if (cs == NULL)
+    {
+      RESTORE_MODEL(c, 0);
+      return;
+    }
+    fSuccessor = REF(cs);
+  }
+  else if ((Byte *)Ppmd8_GetPtr(p, fSuccessor) < p->UnitsStart)
+  {
+    CTX_PTR cs = CreateSuccessors(p, False, s, p->MinContext);
+    if (cs == NULL)
+    {
+      RESTORE_MODEL(c, 0);
+      return;
+    }
+    fSuccessor = REF(cs);
+  }
+  
+  if (--p->OrderFall == 0)
+  {
+    successor = fSuccessor;
+    p->Text -= (p->MaxContext != p->MinContext);
+  }
+  #ifdef PPMD8_FREEZE_SUPPORT
+  else if (p->RestoreMethod > PPMD8_RESTORE_METHOD_FREEZE)
+  {
+    successor = fSuccessor;
+    RESET_TEXT(0);
+    p->OrderFall = 0;
+  }
+  #endif
+  
+  s0 = p->MinContext->SummFreq - (ns = p->MinContext->NumStats) - fFreq;
+  flag = (Byte)(0x08 * (fSymbol >= 0x40));
+  
+  for (; c != p->MinContext; c = SUFFIX(c))
+  {
+    unsigned ns1;
+    UInt32 cf, sf;
+    if ((ns1 = c->NumStats) != 0)
+    {
+      if ((ns1 & 1) != 0)
+      {
+        /* Expand for one UNIT */
+        unsigned oldNU = (ns1 + 1) >> 1;
+        unsigned i = U2I(oldNU);
+        if (i != U2I(oldNU + 1))
+        {
+          void *ptr = AllocUnits(p, i + 1);
+          void *oldPtr;
+          if (!ptr)
+          {
+            RESTORE_MODEL(c, CTX(fSuccessor));
+            return;
+          }
+          oldPtr = STATS(c);
+          MyMem12Cpy(ptr, oldPtr, oldNU);
+          InsertNode(p, oldPtr, i);
+          c->Stats = STATS_REF(ptr);
+        }
+      }
+      c->SummFreq = (UInt16)(c->SummFreq + (3 * ns1 + 1 < ns));
+    }
+    else
+    {
+      CPpmd_State *s2 = (CPpmd_State*)AllocUnits(p, 0);
+      if (!s2)
+      {
+        RESTORE_MODEL(c, CTX(fSuccessor));
+        return;
+      }
+      *s2 = *ONE_STATE(c);
+      c->Stats = REF(s2);
+      if (s2->Freq < MAX_FREQ / 4 - 1)
+        s2->Freq <<= 1;
+      else
+        s2->Freq = MAX_FREQ - 4;
+      c->SummFreq = (UInt16)(s2->Freq + p->InitEsc + (ns > 2));
+    }
+    cf = 2 * fFreq * (c->SummFreq + 6);
+    sf = (UInt32)s0 + c->SummFreq;
+    if (cf < 6 * sf)
+    {
+      cf = 1 + (cf > sf) + (cf >= 4 * sf);
+      c->SummFreq += 4;
+    }
+    else
+    {
+      cf = 4 + (cf > 9 * sf) + (cf > 12 * sf) + (cf > 15 * sf);
+      c->SummFreq = (UInt16)(c->SummFreq + cf);
+    }
+    {
+      CPpmd_State *s2 = STATS(c) + ns1 + 1;
+      SetSuccessor(s2, successor);
+      s2->Symbol = fSymbol;
+      s2->Freq = (Byte)cf;
+      c->Flags |= flag;
+      c->NumStats = (Byte)(ns1 + 1);
+    }
+  }
+  p->MaxContext = p->MinContext = CTX(fSuccessor);
+}
+  
+static void Rescale(CPpmd8 *p)
+{
+  unsigned i, adder, sumFreq, escFreq;
+  CPpmd_State *stats = STATS(p->MinContext);
+  CPpmd_State *s = p->FoundState;
+  {
+    CPpmd_State tmp = *s;
+    for (; s != stats; s--)
+      s[0] = s[-1];
+    *s = tmp;
+  }
+  escFreq = p->MinContext->SummFreq - s->Freq;
+  s->Freq += 4;
+  adder = (p->OrderFall != 0
+      #ifdef PPMD8_FREEZE_SUPPORT
+      || p->RestoreMethod > PPMD8_RESTORE_METHOD_FREEZE
+      #endif
+      );
+  s->Freq = (Byte)((s->Freq + adder) >> 1);
+  sumFreq = s->Freq;
+  
+  i = p->MinContext->NumStats;
+  do
+  {
+    escFreq -= (++s)->Freq;
+    s->Freq = (Byte)((s->Freq + adder) >> 1);
+    sumFreq += s->Freq;
+    if (s[0].Freq > s[-1].Freq)
+    {
+      CPpmd_State *s1 = s;
+      CPpmd_State tmp = *s1;
+      do
+        s1[0] = s1[-1];
+      while (--s1 != stats && tmp.Freq > s1[-1].Freq);
+      *s1 = tmp;
+    }
+  }
+  while (--i);
+  
+  if (s->Freq == 0)
+  {
+    unsigned numStats = p->MinContext->NumStats;
+    unsigned n0, n1;
+    do { i++; } while ((--s)->Freq == 0);
+    escFreq += i;
+    p->MinContext->NumStats = (Byte)(p->MinContext->NumStats - i);
+    if (p->MinContext->NumStats == 0)
+    {
+      CPpmd_State tmp = *stats;
+      tmp.Freq = (Byte)((2 * tmp.Freq + escFreq - 1) / escFreq);
+      if (tmp.Freq > MAX_FREQ / 3)
+        tmp.Freq = MAX_FREQ / 3;
+      InsertNode(p, stats, U2I((numStats + 2) >> 1));
+      p->MinContext->Flags = (Byte)((p->MinContext->Flags & 0x10) + 0x08 * (tmp.Symbol >= 0x40));
+      *(p->FoundState = ONE_STATE(p->MinContext)) = tmp;
+      return;
+    }
+    n0 = (numStats + 2) >> 1;
+    n1 = (p->MinContext->NumStats + 2) >> 1;
+    if (n0 != n1)
+      p->MinContext->Stats = STATS_REF(ShrinkUnits(p, stats, n0, n1));
+    p->MinContext->Flags &= ~0x08;
+    p->MinContext->Flags |= 0x08 * ((s = STATS(p->MinContext))->Symbol >= 0x40);
+    i = p->MinContext->NumStats;
+    do { p->MinContext->Flags |= 0x08*((++s)->Symbol >= 0x40); } while (--i);
+  }
+  p->MinContext->SummFreq = (UInt16)(sumFreq + escFreq - (escFreq >> 1));
+  p->MinContext->Flags |= 0x4;
+  p->FoundState = STATS(p->MinContext);
+}
+
+CPpmd_See *Ppmd8_MakeEscFreq(CPpmd8 *p, unsigned numMasked1, UInt32 *escFreq)
+{
+  CPpmd_See *see;
+  if (p->MinContext->NumStats != 0xFF)
+  {
+    see = p->See[(unsigned)p->NS2Indx[(unsigned)p->MinContext->NumStats + 2] - 3] +
+        (p->MinContext->SummFreq > 11 * ((unsigned)p->MinContext->NumStats + 1)) +
+        2 * (unsigned)(2 * (unsigned)p->MinContext->NumStats <
+        ((unsigned)SUFFIX(p->MinContext)->NumStats + numMasked1)) +
+        p->MinContext->Flags;
+    {
+      unsigned r = (see->Summ >> see->Shift);
+      see->Summ = (UInt16)(see->Summ - r);
+      *escFreq = r + (r == 0);
+    }
+  }
+  else
+  {
+    see = &p->DummySee;
+    *escFreq = 1;
+  }
+  return see;
+}
+
+static void NextContext(CPpmd8 *p)
+{
+  CTX_PTR c = CTX(SUCCESSOR(p->FoundState));
+  if (p->OrderFall == 0 && (Byte *)c >= p->UnitsStart)
+    p->MinContext = p->MaxContext = c;
+  else
+  {
+    UpdateModel(p);
+    p->MinContext = p->MaxContext;
+  }
+}
+
+void Ppmd8_Update1(CPpmd8 *p)
+{
+  CPpmd_State *s = p->FoundState;
+  s->Freq += 4;
+  p->MinContext->SummFreq += 4;
+  if (s[0].Freq > s[-1].Freq)
+  {
+    SwapStates(&s[0], &s[-1]);
+    p->FoundState = --s;
+    if (s->Freq > MAX_FREQ)
+      Rescale(p);
+  }
+  NextContext(p);
+}
+
+void Ppmd8_Update1_0(CPpmd8 *p)
+{
+  p->PrevSuccess = (2 * p->FoundState->Freq >= p->MinContext->SummFreq);
+  p->RunLength += p->PrevSuccess;
+  p->MinContext->SummFreq += 4;
+  if ((p->FoundState->Freq += 4) > MAX_FREQ)
+    Rescale(p);
+  NextContext(p);
+}
+
+void Ppmd8_UpdateBin(CPpmd8 *p)
+{
+  p->FoundState->Freq = (Byte)(p->FoundState->Freq + (p->FoundState->Freq < 196));
+  p->PrevSuccess = 1;
+  p->RunLength++;
+  NextContext(p);
+}
+
+void Ppmd8_Update2(CPpmd8 *p)
+{
+  p->MinContext->SummFreq += 4;
+  if ((p->FoundState->Freq += 4) > MAX_FREQ)
+    Rescale(p);
+  p->RunLength = p->InitRL;
+  UpdateModel(p);
+  p->MinContext = p->MaxContext;
+}
+
+/* Ppmd8Dec.c -- PPMdI Decoder
+2010-04-16 : Igor Pavlov : Public domain
+This code is based on:
+  PPMd var.I (2002): Dmitry Shkarin : Public domain
+  Carryless rangecoder (1999): Dmitry Subbotin : Public domain */
+
+Bool Ppmd8_RangeDec_Init(CPpmd8 *p)
+{
+  unsigned i;
+  p->Low = 0;
+  p->Range = 0xFFFFFFFF;
+  p->Code = 0;
+  for (i = 0; i < 4; i++)
+    p->Code = (p->Code << 8) | p->Stream.In->Read(p->Stream.In);
+  return (p->Code < 0xFFFFFFFF);
+}
+
+static UInt32 RangeDec_GetThreshold(CPpmd8 *p, UInt32 total)
+{
+  return p->Code / (p->Range /= total);
+}
+
+static void RangeDec_Decode(CPpmd8 *p, UInt32 start, UInt32 size)
+{
+  start *= p->Range;
+  p->Low += start;
+  p->Code -= start;
+  p->Range *= size;
+
+  while ((p->Low ^ (p->Low + p->Range)) < kTop ||
+      (p->Range < kBot && ((p->Range = (0 - p->Low) & (kBot - 1)), 1)))
+  {
+    p->Code = (p->Code << 8) | p->Stream.In->Read(p->Stream.In);
+    p->Range <<= 8;
+    p->Low <<= 8;
+  }
+}
+
+#define MASK(sym) ((signed char *)charMask)[sym]
+
+int Ppmd8_DecodeSymbol(CPpmd8 *p)
+{
+  size_t charMask[256 / sizeof(size_t)];
+  if (p->MinContext->NumStats != 0)
+  {
+    CPpmd_State *s = Ppmd8_GetStats(p, p->MinContext);
+    unsigned i;
+    UInt32 count, hiCnt;
+    if ((count = RangeDec_GetThreshold(p, p->MinContext->SummFreq)) < (hiCnt = s->Freq))
+    {
+      Byte symbol;
+      RangeDec_Decode(p, 0, s->Freq);
+      p->FoundState = s;
+      symbol = s->Symbol;
+      Ppmd8_Update1_0(p);
+      return symbol;
+    }
+    p->PrevSuccess = 0;
+    i = p->MinContext->NumStats;
+    do
+    {
+      if ((hiCnt += (++s)->Freq) > count)
+      {
+        Byte symbol;
+        RangeDec_Decode(p, hiCnt - s->Freq, s->Freq);
+        p->FoundState = s;
+        symbol = s->Symbol;
+        Ppmd8_Update1(p);
+        return symbol;
+      }
+    }
+    while (--i);
+    if (count >= p->MinContext->SummFreq)
+      return -2;
+    RangeDec_Decode(p, hiCnt, p->MinContext->SummFreq - hiCnt);
+    PPMD_SetAllBitsIn256Bytes(charMask);
+    MASK(s->Symbol) = 0;
+    i = p->MinContext->NumStats;
+    do { MASK((--s)->Symbol) = 0; } while (--i);
+  }
+  else
+  {
+    UInt16 *prob = Ppmd8_GetBinSumm(p);
+    if (((p->Code / (p->Range >>= 14)) < *prob))
+    {
+      Byte symbol;
+      RangeDec_Decode(p, 0, *prob);
+      *prob = (UInt16)PPMD_UPDATE_PROB_0(*prob);
+      symbol = (p->FoundState = Ppmd8Context_OneState(p->MinContext))->Symbol;
+      Ppmd8_UpdateBin(p);
+      return symbol;
+    }
+    RangeDec_Decode(p, *prob, (1 << 14) - *prob);
+    *prob = (UInt16)PPMD_UPDATE_PROB_1(*prob);
+    p->InitEsc = PPMD8_kExpEscape[*prob >> 10];
+    PPMD_SetAllBitsIn256Bytes(charMask);
+    MASK(Ppmd8Context_OneState(p->MinContext)->Symbol) = 0;
+    p->PrevSuccess = 0;
+  }
+  for (;;)
+  {
+    CPpmd_State *ps[256], *s;
+    UInt32 freqSum, count, hiCnt;
+    CPpmd_See *see;
+    unsigned i, num, numMasked = p->MinContext->NumStats;
+    do
+    {
+      p->OrderFall++;
+      if (!p->MinContext->Suffix)
+        return -1;
+      p->MinContext = Ppmd8_GetContext(p, p->MinContext->Suffix);
+    }
+    while (p->MinContext->NumStats == numMasked);
+    hiCnt = 0;
+    s = Ppmd8_GetStats(p, p->MinContext);
+    i = 0;
+    num = p->MinContext->NumStats - numMasked;
+    do
+    {
+      int k = (int)(MASK(s->Symbol));
+      hiCnt += (s->Freq & k);
+      ps[i] = s++;
+      i -= k;
+    }
+    while (i != num);
+    
+    see = Ppmd8_MakeEscFreq(p, numMasked, &freqSum);
+    freqSum += hiCnt;
+    count = RangeDec_GetThreshold(p, freqSum);
+    
+    if (count < hiCnt)
+    {
+      Byte symbol;
+      CPpmd_State **pps = ps;
+      for (hiCnt = 0; (hiCnt += (*pps)->Freq) <= count; pps++);
+      s = *pps;
+      RangeDec_Decode(p, hiCnt - s->Freq, s->Freq);
+      Ppmd_See_Update(see);
+      p->FoundState = s;
+      symbol = s->Symbol;
+      Ppmd8_Update2(p);
+      return symbol;
+    }
+    if (count >= freqSum)
+      return -2;
+    RangeDec_Decode(p, hiCnt, freqSum - hiCnt);
+    see->Summ = (UInt16)(see->Summ + freqSum);
+    do { MASK(ps[--i]->Symbol) = 0; } while (i != 0);
+  }
+}
+
+/* H->I changes:
+  NS2Indx
+  GlewCount, and Glue method
+  BinSum
+  See / EscFreq
+  CreateSuccessors updates more suffix contexts
+  UpdateModel consts.
+  PrevSuccess Update
+*/
+
+const IPpmd8 __archive_ppmd8_functions =
+{
+  &Ppmd8_Construct,
+  &Ppmd8_Alloc,
+  &Ppmd8_Free,
+  &Ppmd8_Init,
+  &Ppmd8_RangeDec_Init,
+  &Ppmd8_DecodeSymbol,
+};
diff --git a/Utilities/cmlibarchive/libarchive/archive_ppmd8_private.h b/Utilities/cmlibarchive/libarchive/archive_ppmd8_private.h
new file mode 100644
index 0000000..454b75f
--- /dev/null
+++ b/Utilities/cmlibarchive/libarchive/archive_ppmd8_private.h
@@ -0,0 +1,148 @@
+/* Ppmd8.h -- PPMdI codec
+2011-01-27 : Igor Pavlov : Public domain
+This code is based on:
+  PPMd var.I (2002): Dmitry Shkarin : Public domain
+  Carryless rangecoder (1999): Dmitry Subbotin : Public domain */
+
+#ifndef ARCHIVE_PPMD8_PRIVATE_H_INCLUDED
+#define ARCHIVE_PPMD8_PRIVATE_H_INCLUDED
+
+#include "archive_ppmd_private.h"
+
+#define PPMD8_MIN_ORDER 2
+#define PPMD8_MAX_ORDER 16
+
+struct CPpmd8_Context_;
+
+typedef
+  #ifdef PPMD_32BIT
+    struct CPpmd8_Context_ *
+  #else
+    UInt32
+  #endif
+  CPpmd8_Context_Ref;
+
+#pragma pack(push, 1)
+
+typedef struct CPpmd8_Context_
+{
+  Byte NumStats;
+  Byte Flags;
+  UInt16 SummFreq;
+  CPpmd_State_Ref Stats;
+  CPpmd8_Context_Ref Suffix;
+} CPpmd8_Context;
+
+#pragma pack(pop)
+
+#define Ppmd8Context_OneState(p) ((CPpmd_State *)&(p)->SummFreq)
+
+/* The BUG in Shkarin's code for FREEZE mode was fixed, but that fixed
+   code is not compatible with original code for some files compressed
+   in FREEZE mode. So we disable FREEZE mode support. */
+
+enum
+{
+  PPMD8_RESTORE_METHOD_RESTART,
+  PPMD8_RESTORE_METHOD_CUT_OFF
+  #ifdef PPMD8_FREEZE_SUPPORT
+  , PPMD8_RESTORE_METHOD_FREEZE
+  #endif
+};
+
+typedef struct
+{
+  CPpmd8_Context *MinContext, *MaxContext;
+  CPpmd_State *FoundState;
+  unsigned OrderFall, InitEsc, PrevSuccess, MaxOrder;
+  Int32 RunLength, InitRL; /* must be 32-bit at least */
+
+  UInt32 Size;
+  UInt32 GlueCount;
+  Byte *Base, *LoUnit, *HiUnit, *Text, *UnitsStart;
+  UInt32 AlignOffset;
+  unsigned RestoreMethod;
+
+  /* Range Coder */
+  UInt32 Range;
+  UInt32 Code;
+  UInt32 Low;
+  union
+  {
+    IByteIn *In;
+    IByteOut *Out;
+  } Stream;
+
+  Byte Indx2Units[PPMD_NUM_INDEXES];
+  Byte Units2Indx[128];
+  CPpmd_Void_Ref FreeList[PPMD_NUM_INDEXES];
+  UInt32 Stamps[PPMD_NUM_INDEXES];
+
+  Byte NS2BSIndx[256], NS2Indx[260];
+  CPpmd_See DummySee, See[24][32];
+  UInt16 BinSumm[25][64];
+} CPpmd8;
+
+void Ppmd8_Construct(CPpmd8 *p);
+Bool Ppmd8_Alloc(CPpmd8 *p, UInt32 size);
+void Ppmd8_Free(CPpmd8 *p);
+void Ppmd8_Init(CPpmd8 *p, unsigned maxOrder, unsigned restoreMethod);
+#define Ppmd8_WasAllocated(p) ((p)->Base != NULL)
+
+
+/* ---------- Internal Functions ---------- */
+
+extern const Byte PPMD8_kExpEscape[16];
+
+#ifdef PPMD_32BIT
+  #define Ppmd8_GetPtr(p, ptr) (ptr)
+  #define Ppmd8_GetContext(p, ptr) (ptr)
+  #define Ppmd8_GetStats(p, ctx) ((ctx)->Stats)
+#else
+  #define Ppmd8_GetPtr(p, offs) ((void *)((p)->Base + (offs)))
+  #define Ppmd8_GetContext(p, offs) ((CPpmd8_Context *)Ppmd8_GetPtr((p), (offs)))
+  #define Ppmd8_GetStats(p, ctx) ((CPpmd_State *)Ppmd8_GetPtr((p), ((ctx)->Stats)))
+#endif
+
+void Ppmd8_Update1(CPpmd8 *p);
+void Ppmd8_Update1_0(CPpmd8 *p);
+void Ppmd8_Update2(CPpmd8 *p);
+void Ppmd8_UpdateBin(CPpmd8 *p);
+
+#define Ppmd8_GetBinSumm(p) \
+    &p->BinSumm[p->NS2Indx[Ppmd8Context_OneState(p->MinContext)->Freq - 1]][ \
+    p->NS2BSIndx[Ppmd8_GetContext(p, p->MinContext->Suffix)->NumStats] + \
+    p->PrevSuccess + p->MinContext->Flags + ((p->RunLength >> 26) & 0x20)]
+
+CPpmd_See *Ppmd8_MakeEscFreq(CPpmd8 *p, unsigned numMasked, UInt32 *scale);
+
+
+/* ---------- Decode ---------- */
+
+Bool Ppmd8_RangeDec_Init(CPpmd8 *p);
+#define Ppmd8_RangeDec_IsFinishedOK(p) ((p)->Code == 0)
+int Ppmd8_DecodeSymbol(CPpmd8 *p); /* returns: -1 as EndMarker, -2 as DataError */
+
+/* ---------- Encode ---------- */
+
+#define Ppmd8_RangeEnc_Init(p) { (p)->Low = 0; (p)->Range = 0xFFFFFFFF; }
+void Ppmd8_RangeEnc_FlushData(CPpmd8 *p);
+void Ppmd8_EncodeSymbol(CPpmd8 *p, int symbol); /* symbol = -1 means EndMarker */
+
+typedef struct
+{
+  /* Base Functions */
+  void (*Ppmd8_Construct)(CPpmd8 *p);
+  Bool (*Ppmd8_Alloc)(CPpmd8 *p, UInt32 size);
+  void (*Ppmd8_Free)(CPpmd8 *p);
+  void (*Ppmd8_Init)(CPpmd8 *p, unsigned max_order, unsigned restore_method);
+  #define Ppmd7_WasAllocated(p) ((p)->Base != NULL)
+
+  /* Decode Functions */
+  int (*Ppmd8_RangeDec_Init)(CPpmd8 *p);
+  int (*Ppmd8_DecodeSymbol)(CPpmd8 *p);
+} IPpmd8;
+
+extern const IPpmd8 __archive_ppmd8_functions;
+
+#endif
diff --git a/Utilities/cmlibarchive/libarchive/archive_ppmd_private.h b/Utilities/cmlibarchive/libarchive/archive_ppmd_private.h
index a83b851..582803e 100644
--- a/Utilities/cmlibarchive/libarchive/archive_ppmd_private.h
+++ b/Utilities/cmlibarchive/libarchive/archive_ppmd_private.h
@@ -2,13 +2,13 @@
 2010-03-12 : Igor Pavlov : Public domain
 This code is based on PPMd var.H (2001): Dmitry Shkarin : Public domain */
 
+#ifndef ARCHIVE_PPMD_PRIVATE_H_INCLUDED
+#define ARCHIVE_PPMD_PRIVATE_H_INCLUDED
+
 #ifndef __LIBARCHIVE_BUILD
 #error This header is only to be used internally to libarchive.
 #endif
 
-#ifndef ARCHIVE_PPMD_PRIVATE_H_INCLUDED
-#define ARCHIVE_PPMD_PRIVATE_H_INCLUDED
-
 #include <stddef.h>
 
 #include "archive_read_private.h"
diff --git a/Utilities/cmlibarchive/libarchive/archive_private.h b/Utilities/cmlibarchive/libarchive/archive_private.h
index 4b4be97..937a87b 100644
--- a/Utilities/cmlibarchive/libarchive/archive_private.h
+++ b/Utilities/cmlibarchive/libarchive/archive_private.h
@@ -25,13 +25,13 @@
  * $FreeBSD: head/lib/libarchive/archive_private.h 201098 2009-12-28 02:58:14Z kientzle $
  */
 
+#ifndef ARCHIVE_PRIVATE_H_INCLUDED
+#define ARCHIVE_PRIVATE_H_INCLUDED
+
 #ifndef __LIBARCHIVE_BUILD
 #error This header is only to be used internally to libarchive.
 #endif
 
-#ifndef ARCHIVE_PRIVATE_H_INCLUDED
-#define	ARCHIVE_PRIVATE_H_INCLUDED
-
 #if HAVE_ICONV_H
 #include <iconv.h>
 #endif
@@ -153,6 +153,11 @@
 
 void	__archive_ensure_cloexec_flag(int fd);
 int	__archive_mktemp(const char *tmpdir);
+#if defined(_WIN32) && !defined(__CYGWIN__)
+int	__archive_mkstemp(wchar_t *template);
+#else
+int	__archive_mkstemp(char *template);
+#endif
 
 int	__archive_clean(struct archive *);
 
diff --git a/Utilities/cmlibarchive/libarchive/archive_random_private.h b/Utilities/cmlibarchive/libarchive/archive_random_private.h
index c414779..08b91b3 100644
--- a/Utilities/cmlibarchive/libarchive/archive_random_private.h
+++ b/Utilities/cmlibarchive/libarchive/archive_random_private.h
@@ -23,13 +23,13 @@
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
+#ifndef ARCHIVE_RANDOM_PRIVATE_H_INCLUDED
+#define ARCHIVE_RANDOM_PRIVATE_H_INCLUDED
+
 #ifndef __LIBARCHIVE_BUILD
 #error This header is only to be used internally to libarchive.
 #endif
 
-#ifndef ARCHIVE_RANDOM_PRIVATE_H_INCLUDED
-#define ARCHIVE_RANDOM_PRIVATE_H_INCLUDED
-
 /* Random number generator. */
 int archive_random(void *buf, size_t nbytes);
 
diff --git a/Utilities/cmlibarchive/libarchive/archive_rb.h b/Utilities/cmlibarchive/libarchive/archive_rb.h
index 4562e9e..8851f10 100644
--- a/Utilities/cmlibarchive/libarchive/archive_rb.h
+++ b/Utilities/cmlibarchive/libarchive/archive_rb.h
@@ -28,8 +28,9 @@
  *
  * Based on NetBSD: rb.h,v 1.13 2009/08/16 10:57:01 yamt Exp
  */
-#ifndef ARCHIVE_RB_H_
-#define	ARCHIVE_RB_H_
+
+#ifndef ARCHIVE_RB_H_INCLUDED
+#define	ARCHIVE_RB_H_INCLUDED
 
 struct archive_rb_node {
 	struct archive_rb_node *rb_nodes[2];
@@ -48,12 +49,24 @@
     __archive_rb_tree_iterate((T), NULL, ARCHIVE_RB_DIR_LEFT)
 #define ARCHIVE_RB_TREE_MAX(T) \
     __archive_rb_tree_iterate((T), NULL, ARCHIVE_RB_DIR_RIGHT)
+#define ARCHIVE_RB_TREE_NEXT(T, N) \
+    __archive_rb_tree_iterate((T), (N), ARCHIVE_RB_DIR_RIGHT)
+#define ARCHIVE_RB_TREE_PREV(T, N) \
+    __archive_rb_tree_iterate((T), (N), ARCHIVE_RB_DIR_LEFT)
 #define ARCHIVE_RB_TREE_FOREACH(N, T) \
     for ((N) = ARCHIVE_RB_TREE_MIN(T); (N); \
-	(N) = __archive_rb_tree_iterate((T), (N), ARCHIVE_RB_DIR_RIGHT))
+	(N) = ARCHIVE_RB_TREE_NEXT((T), (N)))
 #define ARCHIVE_RB_TREE_FOREACH_REVERSE(N, T) \
     for ((N) = ARCHIVE_RB_TREE_MAX(T); (N); \
-	(N) = __archive_rb_tree_iterate((T), (N), ARCHIVE_RB_DIR_LEFT))
+	(N) = ARCHIVE_RB_TREE_PREV((T), (N)))
+#define ARCHIVE_RB_TREE_FOREACH_SAFE(N, T, S) \
+    for ((N) = ARCHIVE_RB_TREE_MIN(T); \
+	(N) && ((S) = ARCHIVE_RB_TREE_NEXT((T), (N)), 1); \
+	(N) = (S))
+#define ARCHIVE_RB_TREE_FOREACH_REVERSE_SAFE(N, T, S) \
+    for ((N) = ARCHIVE_RB_TREE_MAX(T); \
+        (N) && ((S) = ARCHIVE_RB_TREE_PREV((T), (N)), 1); \
+        (N) = (S))
 
 /*
  * archive_rbto_compare_nodes_fn:
diff --git a/Utilities/cmlibarchive/libarchive/archive_read.3 b/Utilities/cmlibarchive/libarchive/archive_read.3
index d37e732..cbedd0a 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read.3
+++ b/Utilities/cmlibarchive/libarchive/archive_read.3
@@ -155,7 +155,7 @@
 .Fn archive_read_free
 to release all resources, including all memory allocated by the library.
 .\"
-.Sh EXAMPLE
+.Sh EXAMPLES
 The following illustrates basic usage of the library.
 In this example,
 the callback functions are simply wrappers around the standard
@@ -217,16 +217,16 @@
 .\" .Sh ERRORS
 .Sh SEE ALSO
 .Xr tar 1 ,
-.Xr libarchive 3 ,
-.Xr archive_read_new 3 ,
 .Xr archive_read_data 3 ,
 .Xr archive_read_extract 3 ,
 .Xr archive_read_filter 3 ,
 .Xr archive_read_format 3 ,
 .Xr archive_read_header 3 ,
+.Xr archive_read_new 3 ,
 .Xr archive_read_open 3 ,
 .Xr archive_read_set_options 3 ,
 .Xr archive_util 3 ,
+.Xr libarchive 3 ,
 .Xr tar 5
 .Sh HISTORY
 The
diff --git a/Utilities/cmlibarchive/libarchive/archive_read.c b/Utilities/cmlibarchive/libarchive/archive_read.c
index 0e56e76..4a933b2 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read.c
+++ b/Utilities/cmlibarchive/libarchive/archive_read.c
@@ -433,7 +433,7 @@
 		return ARCHIVE_FATAL;
 	}
 	a->client.dataset = (struct archive_read_data_node *)p;
-	for (i = a->client.nodes - 1; i > iindex && i > 0; i--) {
+	for (i = a->client.nodes - 1; i > iindex; i--) {
 		a->client.dataset[i].data = a->client.dataset[i-1].data;
 		a->client.dataset[i].begin_position = -1;
 		a->client.dataset[i].total_size = -1;
@@ -611,6 +611,15 @@
 	return (ARCHIVE_FATAL);
 }
 
+int
+__archive_read_header(struct archive_read *a, struct archive_entry *entry)
+{
+	if (a->filter->read_header)
+		return a->filter->read_header(a->filter, entry);
+	else
+		return (ARCHIVE_OK);
+}
+
 /*
  * Read header of next entry.
  */
@@ -835,7 +844,8 @@
 	dest = (char *)buff;
 
 	while (s > 0) {
-		if (a->read_data_remaining == 0) {
+		if (a->read_data_offset == a->read_data_output_offset &&
+		    a->read_data_remaining == 0) {
 			read_buf = a->read_data_block;
 			a->read_data_is_posix_read = 1;
 			a->read_data_requested = s;
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_add_passphrase.3 b/Utilities/cmlibarchive/libarchive/archive_read_add_passphrase.3
index 8b242ea..ca60d4f 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_add_passphrase.3
+++ b/Utilities/cmlibarchive/libarchive/archive_read_add_passphrase.3
@@ -59,16 +59,16 @@
 will be returned.
 Otherwise,
 .Cm ARCHIVE_OK
-will be returned. 
+will be returned.
 .It Fn archive_read_set_passphrase_callback
-Register callback function that will be invoked to get a passphrase 
-for decrption after trying all passphrases registered by the
+Register a callback function that will be invoked to get a passphrase 
+for decryption after trying all the passphrases registered by the
 .Fn archive_read_add_passphrase
 function failed.
 .El
 .\" .Sh ERRORS
 .Sh SEE ALSO
 .Xr tar 1 ,
-.Xr libarchive 3 ,
 .Xr archive_read 3 ,
-.Xr archive_read_set_options 3
+.Xr archive_read_set_options 3 ,
+.Xr libarchive 3
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_data.3 b/Utilities/cmlibarchive/libarchive/archive_read_data.3
index c1bc15d..78c0c90 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_data.3
+++ b/Utilities/cmlibarchive/libarchive/archive_read_data.3
@@ -28,7 +28,7 @@
 .Dt ARCHIVE_READ_DATA 3
 .Os
 .Sh NAME
-.Nm archive_read_data
+.Nm archive_read_data ,
 .Nm archive_read_data_block ,
 .Nm archive_read_data_skip ,
 .Nm archive_read_data_into_fd
@@ -118,7 +118,6 @@
 .\"
 .Sh SEE ALSO
 .Xr tar 1 ,
-.Xr libarchive 3 ,
 .Xr archive_read 3 ,
 .Xr archive_read_extract 3 ,
 .Xr archive_read_filter 3 ,
@@ -127,4 +126,5 @@
 .Xr archive_read_open 3 ,
 .Xr archive_read_set_options 3 ,
 .Xr archive_util 3 ,
+.Xr libarchive 3 ,
 .Xr tar 5
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_disk.3 b/Utilities/cmlibarchive/libarchive/archive_read_disk.3
index 027f63c..82d6a5c 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_disk.3
+++ b/Utilities/cmlibarchive/libarchive/archive_read_disk.3
@@ -99,9 +99,10 @@
 .Bl -tag -compact -width "indent"
 .It Cm ARCHIVE_READDISK_HONOR_NODUMP
 Skip files and directories with the nodump file attribute (file flag) set.
-By default, the nodump file atrribute is ignored.
+By default, the nodump file attribute is ignored.
 .It Cm ARCHIVE_READDISK_MAC_COPYFILE
-Mac OS X specific. Read metadata (ACLs and extended attributes) with
+Mac OS X specific.
+Read metadata (ACLs and extended attributes) with
 .Xr copyfile 3 .
 By default, metadata is read using
 .Xr copyfile 3 .
@@ -120,7 +121,7 @@
 for more information on file attributes.
 .It Cm ARCHIVE_READDISK_NO_TRAVERSE_MOUNTS
 Do not traverse mount points.
-By defaut, moint points are traversed.
+By default, mount points are traversed.
 .It Cm ARCHIVE_READDISK_NO_XATTR
 Do not read extended file attributes (xattrs).
 By default, extended file attributes are read from disk.
@@ -216,7 +217,7 @@
 (For example, directory traversal libraries often provide this information.)
 .Pp
 Where necessary, user and group ids are converted to user and group names
-using the currently registered lookup functions above.
+using the currently-registered lookup functions above.
 This affects the file ownership fields and ACL values in the
 .Tn struct archive_entry
 object.
@@ -226,7 +227,7 @@
 object and the overall design of the library can be found in the
 .Xr libarchive 3
 overview.
-.Sh EXAMPLE
+.Sh EXAMPLES
 The following illustrates basic usage of the library by
 showing how to use it to copy an item on disk into an archive.
 .Bd -literal -offset indent
@@ -291,11 +292,11 @@
 functions.
 .\"
 .Sh SEE ALSO
+.Xr tar 1 ,
 .Xr archive_read 3 ,
 .Xr archive_util 3 ,
 .Xr archive_write 3 ,
 .Xr archive_write_disk 3 ,
-.Xr tar 1 ,
 .Xr libarchive 3
 .Sh HISTORY
 The
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_disk_entry_from_file.c b/Utilities/cmlibarchive/libarchive/archive_read_disk_entry_from_file.c
index 1786cff..2a8cec8 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_disk_entry_from_file.c
+++ b/Utilities/cmlibarchive/libarchive/archive_read_disk_entry_from_file.c
@@ -163,6 +163,9 @@
 	int initial_fd = fd;
 	int r, r1;
 
+	archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC, ARCHIVE_STATE_ANY,
+		"archive_read_disk_entry_from_file");
+
 	archive_clear_error(_a);
 	path = archive_entry_sourcepath(entry);
 	if (path == NULL)
@@ -188,7 +191,7 @@
 				}
 			} else
 #endif
-			if (stat(path, &s) != 0) {
+			if (la_stat(path, &s) != 0) {
 				archive_set_error(&a->archive, errno,
 				    "Can't stat %s", path);
 				return (ARCHIVE_FAILED);
@@ -246,11 +249,11 @@
 
 #if defined(HAVE_READLINK) || defined(HAVE_READLINKAT)
 	if (S_ISLNK(st->st_mode)) {
-		size_t linkbuffer_len = st->st_size + 1;
+		size_t linkbuffer_len = st->st_size;
 		char *linkbuffer;
 		int lnklen;
 
-		linkbuffer = malloc(linkbuffer_len);
+		linkbuffer = malloc(linkbuffer_len + 1);
 		if (linkbuffer == NULL) {
 			archive_set_error(&a->archive, ENOMEM,
 			    "Couldn't read link data");
@@ -277,7 +280,7 @@
 			free(linkbuffer);
 			return (ARCHIVE_FAILED);
 		}
-		linkbuffer[lnklen] = 0;
+		linkbuffer[lnklen] = '\0';
 		archive_entry_set_symlink(entry, linkbuffer);
 		free(linkbuffer);
 	}
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_disk_posix.c b/Utilities/cmlibarchive/libarchive/archive_read_disk_posix.c
index cdf7541..52fec7b 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_disk_posix.c
+++ b/Utilities/cmlibarchive/libarchive/archive_read_disk_posix.c
@@ -694,6 +694,7 @@
 	struct tree *t = a->tree;
 	int r;
 	ssize_t bytes;
+	int64_t sparse_bytes;
 	size_t buffbytes;
 	int empty_sparse_region = 0;
 
@@ -728,27 +729,23 @@
 		if ((t->flags & needsRestoreTimes) != 0 &&
 		    t->restore_time.noatime == 0)
 			flags |= O_NOATIME;
-		do {
 #endif
-			t->entry_fd = open_on_current_dir(t,
-			    tree_current_access_path(t), flags);
-			__archive_ensure_cloexec_flag(t->entry_fd);
+		t->entry_fd = open_on_current_dir(t,
+		    tree_current_access_path(t), flags);
+		__archive_ensure_cloexec_flag(t->entry_fd);
 #if defined(O_NOATIME)
-			/*
-			 * When we did open the file with O_NOATIME flag,
-			 * if successful, set 1 to t->restore_time.noatime
-			 * not to restore an atime of the file later.
-			 * if failed by EPERM, retry it without O_NOATIME flag.
-			 */
-			if (flags & O_NOATIME) {
-				if (t->entry_fd >= 0)
-					t->restore_time.noatime = 1;
-				else if (errno == EPERM) {
-					flags &= ~O_NOATIME;
-					continue;
-				}
-			}
-		} while (0);
+		/*
+		 * When we did open the file with O_NOATIME flag,
+		 * if successful, set 1 to t->restore_time.noatime
+		 * not to restore an atime of the file later.
+		 * if failed by EPERM, retry it without O_NOATIME flag.
+		 */
+		if (flags & O_NOATIME) {
+			if (t->entry_fd >= 0)
+				t->restore_time.noatime = 1;
+			else if (errno == EPERM)
+				flags &= ~O_NOATIME;
+		}
 #endif
 		if (t->entry_fd < 0) {
 			archive_set_error(&a->archive, errno,
@@ -792,9 +789,9 @@
 			a->archive.state = ARCHIVE_STATE_FATAL;
 			goto abort_read_data;
 		}
-		bytes = t->current_sparse->offset - t->entry_total;
-		t->entry_remaining_bytes -= bytes;
-		t->entry_total += bytes;
+		sparse_bytes = t->current_sparse->offset - t->entry_total;
+		t->entry_remaining_bytes -= sparse_bytes;
+		t->entry_total += sparse_bytes;
 	}
 
 	/*
@@ -856,7 +853,12 @@
 	const struct stat *st; /* info to use for this entry */
 	const struct stat *lst;/* lstat() information */
 	const char *name;
-	int descend, r;
+	int delayed, delayed_errno, descend, r;
+	struct archive_string delayed_str;
+
+	delayed = ARCHIVE_OK;
+	delayed_errno = 0;
+	archive_string_init(&delayed_str);
 
 	st = NULL;
 	lst = NULL;
@@ -885,14 +887,26 @@
 		case TREE_REGULAR:
 			lst = tree_current_lstat(t);
 			if (lst == NULL) {
+			    if (errno == ENOENT && t->depth > 0) {
+				delayed = ARCHIVE_WARN;
+				delayed_errno = errno;
+				if (delayed_str.length == 0) {
+					archive_string_sprintf(&delayed_str,
+					    "%s", tree_current_path(t));
+				} else {
+					archive_string_sprintf(&delayed_str,
+					    " %s", tree_current_path(t));
+				}
+			    } else {
 				archive_set_error(&a->archive, errno,
 				    "%s: Cannot stat",
 				    tree_current_path(t));
 				tree_enter_initial_dir(t);
 				return (ARCHIVE_FAILED);
+			    }
 			}
 			break;
-		}	
+		}
 	} while (lst == NULL);
 
 #ifdef __APPLE__
@@ -1083,6 +1097,17 @@
 	r = archive_read_disk_entry_from_file(&(a->archive), entry,
 		t->entry_fd, st);
 
+	if (r == ARCHIVE_OK) {
+		r = delayed;
+		if (r != ARCHIVE_OK) {
+			archive_string_sprintf(&delayed_str, ": %s",
+			    "File removed before we read it");
+			archive_set_error(&(a->archive), delayed_errno,
+			    "%s", delayed_str.s);
+		}
+	}
+	archive_string_free(&delayed_str);
+
 	return (r);
 }
 
@@ -1114,6 +1139,8 @@
 		t->entry_fd = -1;
 	}
 
+	archive_entry_clear(entry);
+
 	for (;;) {
 		r = next_entry(a, t, entry);
 		if (t->entry_fd >= 0) {
@@ -1266,10 +1293,23 @@
 	if (t->visit_type != TREE_REGULAR || !t->descend)
 		return (ARCHIVE_OK);
 
+	/*
+	 * We must not treat the initial specified path as a physical dir,
+	 * because if we do then we will try and ascend out of it by opening
+	 * ".." which is (a) wrong and (b) causes spurious permissions errors
+	 * if ".." is not readable by us. Instead, treat it as if it were a
+	 * symlink. (This uses an extra fd, but it can only happen once at the
+	 * top level of a traverse.) But we can't necessarily assume t->st is
+	 * valid here (though t->lst is), which complicates the logic a
+	 * little.
+	 */
 	if (tree_current_is_physical_dir(t)) {
 		tree_push(t, t->basename, t->current_filesystem_id,
 		    t->lst.st_dev, t->lst.st_ino, &t->restore_time);
-		t->stack->flags |= isDir;
+		if (t->stack->parent->parent != NULL)
+			t->stack->flags |= isDir;
+		else
+			t->stack->flags |= isDirLink;
 	} else if (tree_current_is_dir(t)) {
 		tree_push(t, t->basename, t->current_filesystem_id,
 		    t->st.st_dev, t->st.st_ino, &t->restore_time);
@@ -2122,6 +2162,17 @@
 static struct tree *
 tree_reopen(struct tree *t, const char *path, int restore_time)
 {
+#if defined(O_PATH)
+	/* Linux */
+	const int o_flag = O_PATH;
+#elif defined(O_SEARCH)
+	/* SunOS */
+	const int o_flag = O_SEARCH;
+#elif defined(__FreeBSD__) && defined(O_EXEC)
+	/* FreeBSD */
+	const int o_flag = O_EXEC;
+#endif
+
 	t->flags = (restore_time != 0)?needsRestoreTimes:0;
 	t->flags |= onInitialDir;
 	t->visit_type = 0;
@@ -2143,6 +2194,16 @@
 	t->stack->flags = needsFirstVisit;
 	t->maxOpenCount = t->openCount = 1;
 	t->initial_dir_fd = open(".", O_RDONLY | O_CLOEXEC);
+#if defined(O_PATH) || defined(O_SEARCH) || \
+ (defined(__FreeBSD__) && defined(O_EXEC))
+	/*
+	 * Most likely reason to fail opening "." is that it's not readable,
+	 * so try again for execute. The consequences of not opening this are
+	 * unhelpful and unnecessary errors later.
+	 */
+	if (t->initial_dir_fd < 0)
+		t->initial_dir_fd = open(".", o_flag | O_CLOEXEC);
+#endif
 	__archive_ensure_cloexec_flag(t->initial_dir_fd);
 	t->working_dir_fd = tree_dup(t->initial_dir_fd);
 	return (t);
@@ -2450,7 +2511,7 @@
 #else
 		if (tree_enter_working_dir(t) != 0)
 			return NULL;
-		if (stat(tree_current_access_path(t), &t->st) != 0)
+		if (la_stat(tree_current_access_path(t), &t->st) != 0)
 #endif
 			return NULL;
 		t->flags |= hasStat;
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_disk_private.h b/Utilities/cmlibarchive/libarchive/archive_read_disk_private.h
index f03a0a9..bc8abc1 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_disk_private.h
+++ b/Utilities/cmlibarchive/libarchive/archive_read_disk_private.h
@@ -26,13 +26,13 @@
  * $FreeBSD: head/lib/libarchive/archive_read_disk_private.h 201105 2009-12-28 03:20:54Z kientzle $
  */
 
+#ifndef ARCHIVE_READ_DISK_PRIVATE_H_INCLUDED
+#define ARCHIVE_READ_DISK_PRIVATE_H_INCLUDED
+
 #ifndef __LIBARCHIVE_BUILD
 #error This header is only to be used internally to libarchive.
 #endif
 
-#ifndef ARCHIVE_READ_DISK_PRIVATE_H_INCLUDED
-#define ARCHIVE_READ_DISK_PRIVATE_H_INCLUDED
-
 #include "archive_platform_acl.h"
 
 struct tree;
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_disk_windows.c b/Utilities/cmlibarchive/libarchive/archive_read_disk_windows.c
index d82048d..fdd376f 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_disk_windows.c
+++ b/Utilities/cmlibarchive/libarchive/archive_read_disk_windows.c
@@ -299,8 +299,155 @@
 		    struct restore_time *);
 static int	setup_sparse_from_disk(struct archive_read_disk *,
 		    struct archive_entry *, HANDLE);
+static int	la_linkname_from_handle(HANDLE, wchar_t **, int *);
+static int	la_linkname_from_pathw(const wchar_t *, wchar_t **, int *);
+static void	entry_symlink_from_pathw(struct archive_entry *,
+		    const wchar_t *path);
 
+typedef struct _REPARSE_DATA_BUFFER {
+	ULONG	ReparseTag;
+	USHORT ReparseDataLength;
+	USHORT	Reserved;
+	union {
+		struct {
+			USHORT	SubstituteNameOffset;
+			USHORT	SubstituteNameLength;
+			USHORT	PrintNameOffset;
+			USHORT	PrintNameLength;
+			ULONG	Flags;
+			WCHAR	PathBuffer[1];
+		} SymbolicLinkReparseBuffer;
+		struct {
+			USHORT	SubstituteNameOffset;
+			USHORT	SubstituteNameLength;
+			USHORT	PrintNameOffset;
+			USHORT	PrintNameLength;
+			WCHAR	PathBuffer[1];
+		} MountPointReparseBuffer;
+		struct {
+			UCHAR	DataBuffer[1];
+		} GenericReparseBuffer;
+	} DUMMYUNIONNAME;
+} REPARSE_DATA_BUFFER, *PREPARSE_DATA_BUFFER;
 
+/*
+ * Reads the target of a symbolic link
+ *
+ * Returns 0 on success and -1 on failure
+ * outbuf is allocated in the function
+ */
+static int
+la_linkname_from_handle(HANDLE h, wchar_t **linkname, int *linktype)
+{
+	DWORD inbytes;
+	REPARSE_DATA_BUFFER *buf;
+	BY_HANDLE_FILE_INFORMATION st;
+	size_t len;
+	BOOL ret;
+	BYTE *indata;
+	wchar_t *tbuf;
+
+	ret = GetFileInformationByHandle(h, &st);
+	if (ret == 0 ||
+	    (st.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) == 0) {
+		return (-1);
+	}
+
+	indata = malloc(MAXIMUM_REPARSE_DATA_BUFFER_SIZE);
+	ret = DeviceIoControl(h, FSCTL_GET_REPARSE_POINT, NULL, 0, indata,
+	    1024, &inbytes, NULL);
+	if (ret == 0) {
+		la_dosmaperr(GetLastError());
+		free(indata);
+		return (-1);
+	}
+
+	buf = (REPARSE_DATA_BUFFER *) indata;
+	if (buf->ReparseTag != IO_REPARSE_TAG_SYMLINK) {
+		free(indata);
+		/* File is not a symbolic link */
+		errno = EINVAL;
+		return (-1);
+	}
+
+	len = buf->SymbolicLinkReparseBuffer.SubstituteNameLength;
+	if (len <= 0) {
+		free(indata);
+		return (-1);
+	}
+
+	tbuf = malloc(len + 1 * sizeof(wchar_t));
+	if (tbuf == NULL) {
+		free(indata);
+		return (-1);
+	}
+
+	memcpy(tbuf, &((BYTE *)buf->SymbolicLinkReparseBuffer.PathBuffer)
+	    [buf->SymbolicLinkReparseBuffer.SubstituteNameOffset], len);
+	free(indata);
+
+	tbuf[len / sizeof(wchar_t)] = L'\0';
+
+	*linkname = tbuf;
+
+	/*
+	 * Translate backslashes to slashes for libarchive internal use
+	 */
+	while(*tbuf != L'\0') {
+		if (*tbuf == L'\\')
+			*tbuf = L'/';
+		tbuf++;
+	}
+
+	if ((st.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0)
+		*linktype = AE_SYMLINK_TYPE_FILE;
+	else
+		*linktype = AE_SYMLINK_TYPE_DIRECTORY;
+
+	return (0);
+}
+
+/*
+ * Returns AE_SYMLINK_TYPE_FILE, AE_SYMLINK_TYPE_DIRECTORY or -1 on error
+ */
+static int
+la_linkname_from_pathw(const wchar_t *path, wchar_t **outbuf, int *linktype)
+{
+	HANDLE h;
+	const DWORD flag = FILE_FLAG_BACKUP_SEMANTICS |
+	    FILE_FLAG_OPEN_REPARSE_POINT;
+	int ret;
+
+	h = CreateFileW(path, 0, FILE_SHARE_READ, NULL, OPEN_EXISTING, flag,
+	    NULL);
+	if (h == INVALID_HANDLE_VALUE) {
+		la_dosmaperr(GetLastError());
+		return (-1);
+	}
+
+	ret = la_linkname_from_handle(h, outbuf, linktype);
+	CloseHandle(h);
+
+	return (ret);
+}
+
+static void
+entry_symlink_from_pathw(struct archive_entry *entry, const wchar_t *path)
+{
+	wchar_t *linkname = NULL;
+	int ret, linktype;
+
+	ret = la_linkname_from_pathw(path, &linkname, &linktype);
+	if (ret != 0)
+		return;
+	if (linktype >= 0) {
+		archive_entry_copy_symlink_w(entry, linkname);
+		archive_entry_set_symlink_type(entry, linktype);
+	}
+	free(linkname);
+
+	return;
+}
 
 static struct archive_vtable *
 archive_read_disk_vtable(void)
@@ -900,6 +1047,19 @@
 	}
 
 	/*
+	 * File attributes
+	 */
+	if ((a->flags & ARCHIVE_READDISK_NO_FFLAGS) == 0) {
+		const int supported_attrs =
+		    FILE_ATTRIBUTE_READONLY |
+		    FILE_ATTRIBUTE_HIDDEN |
+		    FILE_ATTRIBUTE_SYSTEM;
+		DWORD file_attrs = st->dwFileAttributes & supported_attrs;
+		if (file_attrs != 0)
+			archive_entry_set_fflags(entry, file_attrs, 0);
+	}
+
+	/*
 	 * Invoke a meta data filter callback.
 	 */
 	if (a->metadata_filter_func) {
@@ -966,6 +1126,8 @@
 		t->entry_fh = INVALID_HANDLE_VALUE;
 	}
 
+	archive_entry_clear(entry);
+
 	while ((r = next_entry(a, t, entry)) == ARCHIVE_RETRY)
 		archive_entry_clear(entry);
 
@@ -1838,9 +2000,10 @@
 		mode |= S_IWUSR | S_IWGRP | S_IWOTH;
 	if ((bhfi->dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) &&
 	    findData != NULL &&
-	    findData->dwReserved0 == IO_REPARSE_TAG_SYMLINK)
+	    findData->dwReserved0 == IO_REPARSE_TAG_SYMLINK) {
 		mode |= S_IFLNK;
-	else if (bhfi->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
+		entry_symlink_from_pathw(entry, path);
+	} else if (bhfi->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
 		mode |= S_IFDIR | S_IXUSR | S_IXGRP | S_IXOTH;
 	else {
 		const wchar_t *p;
@@ -2139,6 +2302,8 @@
 		fileAttributes = bhfi.dwFileAttributes;
 	} else {
 		archive_entry_copy_stat(entry, st);
+		if (st->st_mode & S_IFLNK)
+			entry_symlink_from_pathw(entry, path);
 		h = INVALID_HANDLE_VALUE;
 	}
 
@@ -2151,6 +2316,19 @@
 		archive_entry_copy_gname(entry, name);
 
 	/*
+	 * File attributes
+	 */
+	if ((a->flags & ARCHIVE_READDISK_NO_FFLAGS) == 0) {
+		const int supported_attrs =
+		    FILE_ATTRIBUTE_READONLY |
+		    FILE_ATTRIBUTE_HIDDEN |
+		    FILE_ATTRIBUTE_SYSTEM;
+		DWORD file_attrs = fileAttributes & supported_attrs;
+		if (file_attrs != 0)
+			archive_entry_set_fflags(entry, file_attrs, 0);
+	}
+
+	/*
 	 * Can this file be sparse file ?
 	 */
 	if (archive_entry_filetype(entry) != AE_IFREG
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_extract.3 b/Utilities/cmlibarchive/libarchive/archive_read_extract.3
index 6ec0ced..858f397 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_extract.3
+++ b/Utilities/cmlibarchive/libarchive/archive_read_extract.3
@@ -126,7 +126,6 @@
 functions.
 .Sh SEE ALSO
 .Xr tar 1 ,
-.Xr libarchive 3 ,
 .Xr archive_read 3 ,
 .Xr archive_read_data 3 ,
 .Xr archive_read_filter 3 ,
@@ -134,4 +133,5 @@
 .Xr archive_read_open 3 ,
 .Xr archive_read_set_options 3 ,
 .Xr archive_util 3 ,
+.Xr libarchive 3 ,
 .Xr tar 5
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_filter.3 b/Utilities/cmlibarchive/libarchive/archive_read_filter.3
index ef0a701..1ba5fcb 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_filter.3
+++ b/Utilities/cmlibarchive/libarchive/archive_read_filter.3
@@ -147,8 +147,8 @@
 functions.
 .\"
 .Sh SEE ALSO
-.Xr libarchive 3 ,
 .Xr archive_read 3 ,
 .Xr archive_read_data 3 ,
 .Xr archive_read_format 3 ,
-.Xr archive_read_format 3
+.Xr archive_read_format 3 ,
+.Xr libarchive 3
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_format.3 b/Utilities/cmlibarchive/libarchive/archive_read_format.3
index 91c5d2c..f3804ce 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_format.3
+++ b/Utilities/cmlibarchive/libarchive/archive_read_format.3
@@ -102,7 +102,7 @@
 .Fn archive_read_support_format_tar
 enables support for a variety of standard tar formats, old-style tar,
 ustar, pax interchange format, and many common variants.
-.It Fn archive_read_support_format_all 
+.It Fn archive_read_support_format_all
 Enables support for all available formats except the
 .Dq raw
 format (see below).
@@ -125,7 +125,7 @@
 an empty file based purely on contents.
 So empty files are treated by libarchive as a distinct
 format.
-.It Fn archive_read_support_format_raw 
+.It Fn archive_read_support_format_raw
 The
 .Dq raw
 format handler allows libarchive to be used to read arbitrary data.
@@ -153,11 +153,11 @@
 .\"
 .Sh SEE ALSO
 .Xr tar 1 ,
-.Xr libarchive 3 ,
 .Xr archive_read_data 3 ,
 .Xr archive_read_filter 3 ,
 .Xr archive_read_set_options 3 ,
 .Xr archive_util 3 ,
+.Xr libarchive 3 ,
 .Xr tar 5
 .Sh BUGS
 Many traditional archiver programs treat
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_free.3 b/Utilities/cmlibarchive/libarchive/archive_read_free.3
index 5b21822..8371c3a 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_free.3
+++ b/Utilities/cmlibarchive/libarchive/archive_read_free.3
@@ -83,11 +83,11 @@
 functions.
 .\"
 .Sh SEE ALSO
-.Xr libarchive 3 ,
-.Xr archive_read_new 3 ,
 .Xr archive_read_data 3 ,
 .Xr archive_read_filter 3 ,
 .Xr archive_read_format 3 ,
+.Xr archive_read_new 3 ,
 .Xr archive_read_open 3 ,
 .Xr archive_read_set_options 3 ,
-.Xr archive_util 3
+.Xr archive_util 3 ,
+.Xr libarchive 3
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_header.3 b/Utilities/cmlibarchive/libarchive/archive_read_header.3
index 480a666..1e97f3a 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_header.3
+++ b/Utilities/cmlibarchive/libarchive/archive_read_header.3
@@ -79,7 +79,6 @@
 .\"
 .Sh SEE ALSO
 .Xr tar 1 ,
-.Xr libarchive 3 ,
 .Xr archive_read 3 ,
 .Xr archive_read_data 3 ,
 .Xr archive_read_extract 3 ,
@@ -88,4 +87,5 @@
 .Xr archive_read_open 3 ,
 .Xr archive_read_set_options 3 ,
 .Xr archive_util 3 ,
+.Xr libarchive 3 ,
 .Xr tar 5
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_new.3 b/Utilities/cmlibarchive/libarchive/archive_read_new.3
index 0c9d1a7..8bb6b84 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_new.3
+++ b/Utilities/cmlibarchive/libarchive/archive_read_new.3
@@ -50,10 +50,10 @@
 .\" .Sh ERRORS
 .Sh SEE ALSO
 .Xr tar 1 ,
-.Xr libarchive 3 ,
 .Xr archive_read_data 3 ,
 .Xr archive_read_filter 3 ,
 .Xr archive_read_format 3 ,
 .Xr archive_read_set_options 3 ,
 .Xr archive_util 3 ,
+.Xr libarchive 3 ,
 .Xr tar 5
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_open.3 b/Utilities/cmlibarchive/libarchive/archive_read_open.3
index 2278ebc..f676778 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_open.3
+++ b/Utilities/cmlibarchive/libarchive/archive_read_open.3
@@ -205,7 +205,7 @@
 .Fn archive_set_error
 to register an error code and message and
 return
-.Cm ARCHIVE_FATAL.
+.Cm ARCHIVE_FATAL .
 .\" .Sh EXAMPLE
 .\"
 .Sh RETURN VALUES
@@ -223,11 +223,11 @@
 .\"
 .Sh SEE ALSO
 .Xr tar 1 ,
-.Xr libarchive 3 ,
 .Xr archive_read 3 ,
 .Xr archive_read_data 3 ,
 .Xr archive_read_filter 3 ,
 .Xr archive_read_format 3 ,
 .Xr archive_read_set_options 3 ,
 .Xr archive_util 3 ,
+.Xr libarchive 3 ,
 .Xr tar 5
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_open_file.c b/Utilities/cmlibarchive/libarchive/archive_read_open_file.c
index bfe933b..101dae6 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_open_file.c
+++ b/Utilities/cmlibarchive/libarchive/archive_read_open_file.c
@@ -174,8 +174,7 @@
 	struct read_FILE_data *mine = (struct read_FILE_data *)client_data;
 
 	(void)a; /* UNUSED */
-	if (mine->buffer != NULL)
-		free(mine->buffer);
+	free(mine->buffer);
 	free(mine);
 	return (ARCHIVE_OK);
 }
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_private.h b/Utilities/cmlibarchive/libarchive/archive_read_private.h
index 78546dc..c842e6f 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_private.h
+++ b/Utilities/cmlibarchive/libarchive/archive_read_private.h
@@ -25,15 +25,15 @@
  * $FreeBSD: head/lib/libarchive/archive_read_private.h 201088 2009-12-28 02:18:55Z kientzle $
  */
 
+#ifndef ARCHIVE_READ_PRIVATE_H_INCLUDED
+#define ARCHIVE_READ_PRIVATE_H_INCLUDED
+
 #ifndef __LIBARCHIVE_BUILD
 #ifndef __LIBARCHIVE_TEST
 #error This header is only to be used internally to libarchive.
 #endif
 #endif
 
-#ifndef ARCHIVE_READ_PRIVATE_H_INCLUDED
-#define	ARCHIVE_READ_PRIVATE_H_INCLUDED
-
 #include "archive.h"
 #include "archive_string.h"
 #include "archive_private.h"
@@ -98,6 +98,8 @@
 	int (*close)(struct archive_read_filter *self);
 	/* Function that handles switching from reading one block to the next/prev */
 	int (*sswitch)(struct archive_read_filter *self, unsigned int iindex);
+	/* Read any header metadata if available. */
+	int (*read_header)(struct archive_read_filter *self, struct archive_entry *entry);
 	/* My private data. */
 	void *data;
 
@@ -250,6 +252,7 @@
 int64_t	__archive_read_filter_seek(struct archive_read_filter *, int64_t, int);
 int64_t	__archive_read_consume(struct archive_read *, int64_t);
 int64_t	__archive_read_filter_consume(struct archive_read_filter *, int64_t);
+int __archive_read_header(struct archive_read *, struct archive_entry *);
 int __archive_read_program(struct archive_read_filter *, const char *);
 void __archive_read_free_filters(struct archive_read *);
 struct archive_read_extract *__archive_read_get_extract(struct archive_read *);
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_set_format.c b/Utilities/cmlibarchive/libarchive/archive_read_set_format.c
index 190f436..1d3e49d 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_set_format.c
+++ b/Utilities/cmlibarchive/libarchive/archive_read_set_format.c
@@ -73,6 +73,9 @@
     case ARCHIVE_FORMAT_RAR:
       strcpy(str, "rar");
       break;
+    case ARCHIVE_FORMAT_RAR_V5:
+      strcpy(str, "rar5");
+      break;
     case ARCHIVE_FORMAT_TAR:
       strcpy(str, "tar");
       break;
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_set_options.3 b/Utilities/cmlibarchive/libarchive/archive_read_set_options.3
index 1a251ce..78d9999 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_set_options.3
+++ b/Utilities/cmlibarchive/libarchive/archive_read_set_options.3
@@ -24,7 +24,7 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd February 2, 2012
+.Dd January 31, 2020
 .Dt ARCHIVE_READ_OPTIONS 3
 .Os
 .Sh NAME
@@ -180,6 +180,18 @@
 .\"
 .Sh OPTIONS
 .Bl -tag -compact -width indent
+.It Format cab
+.Bl -tag -compact -width indent
+.It Cm hdrcharset
+The value is used as a character set name that will be
+used when translating file names.
+.El
+.It Format cpio
+.Bl -tag -compact -width indent
+.It Cm hdrcharset
+The value is used as a character set name that will be
+used when translating file names.
+.El
 .It Format iso9660
 .Bl -tag -compact -width indent
 .It Cm joliet
@@ -193,6 +205,24 @@
 .Cm !rockridge
 to disable.
 .El
+.It Format lha
+.Bl -tag -compact -width indent
+.It Cm hdrcharset
+The value is used as a character set name that will be
+used when translating file names.
+.El
+.It Format mtree
+.Bl -tag -compact -width indent
+.It Cm checkfs
+Allow reading information missing from the mtree from the file system.
+Disabled by default.
+.El
+.It Format rar
+.Bl -tag -compact -width indent
+.It Cm hdrcharset
+The value is used as a character set name that will be
+used when translating file names.
+.El
 .It Format tar
 .Bl -tag -compact -width indent
 .It Cm compat-2x
@@ -202,7 +232,7 @@
 so that such archives can be read correctly.
 .It Cm hdrcharset
 The value is used as a character set name that will be
-used when translating filenames.
+used when translating file names.
 .It Cm mac-ext
 Support Mac OS metadata extension that records data in special
 files beginning with a period and underscore.
@@ -212,7 +242,8 @@
 to disable.
 .It Cm read_concatenated_archives
 Ignore zeroed blocks in the archive, which occurs when multiple tar archives
-have been concatenated together.  Without this option, only the contents of
+have been concatenated together.
+Without this option, only the contents of
 the first concatenated archive would be read.
 .El
 .El
@@ -226,6 +257,6 @@
 .\"
 .Sh SEE ALSO
 .Xr tar 1 ,
-.Xr libarchive 3 ,
+.Xr archive_read 3 ,
 .Xr archive_write_set_options 3 ,
-.Xr archive_read 3
+.Xr libarchive 3
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_support_filter_bzip2.c b/Utilities/cmlibarchive/libarchive/archive_read_support_filter_bzip2.c
index 2b1a5e2..5333d47 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_support_filter_bzip2.c
+++ b/Utilities/cmlibarchive/libarchive/archive_read_support_filter_bzip2.c
@@ -41,7 +41,7 @@
 #include <unistd.h>
 #endif
 #ifdef HAVE_BZLIB_H
-#include <cm_bzlib.h>
+#include <cm3p/bzlib.h>
 #endif
 
 #include "archive.h"
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_support_filter_gzip.c b/Utilities/cmlibarchive/libarchive/archive_read_support_filter_gzip.c
index e9f59f1..ac0b694 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_support_filter_gzip.c
+++ b/Utilities/cmlibarchive/libarchive/archive_read_support_filter_gzip.c
@@ -37,14 +37,19 @@
 #ifdef HAVE_STRING_H
 #include <string.h>
 #endif
+#ifdef HAVE_LIMITS_H
+#include <limits.h>
+#endif
 #ifdef HAVE_UNISTD_H
 #include <unistd.h>
 #endif
 #ifdef HAVE_ZLIB_H
-#include <cm_zlib.h>
+#include <cm3p/zlib.h>
 #endif
 
 #include "archive.h"
+#include "archive_entry.h"
+#include "archive_endian.h"
 #include "archive_private.h"
 #include "archive_read_private.h"
 
@@ -56,6 +61,8 @@
 	size_t		 out_block_size;
 	int64_t		 total_out;
 	unsigned long	 crc;
+	uint32_t	 mtime;
+	char		*name;
 	char		 eof; /* True = found end of compressed data. */
 };
 
@@ -123,12 +130,21 @@
  * count of bits verified, suitable for use by bidder.
  */
 static ssize_t
-peek_at_header(struct archive_read_filter *filter, int *pbits)
+peek_at_header(struct archive_read_filter *filter, int *pbits,
+#ifdef HAVE_ZLIB_H
+	       struct private_data *state
+#else
+	       void *state
+#endif
+	      )
 {
 	const unsigned char *p;
 	ssize_t avail, len;
 	int bits = 0;
 	int header_flags;
+#ifndef HAVE_ZLIB_H
+	(void)state; /* UNUSED */
+#endif
 
 	/* Start by looking at the first ten bytes of the header, which
 	 * is all fixed layout. */
@@ -144,7 +160,11 @@
 		return (0);
 	bits += 3;
 	header_flags = p[3];
-	/* Bytes 4-7 are mod time. */
+	/* Bytes 4-7 are mod time in little endian. */
+#ifdef HAVE_ZLIB_H
+	if (state)
+		state->mtime = archive_le32dec(p + 4);
+#endif
 	/* Byte 8 is deflate flags. */
 	/* XXXX TODO: return deflate flags back to consume_header for use
 	   in initializing the decompressor. */
@@ -161,6 +181,9 @@
 
 	/* Null-terminated optional filename. */
 	if (header_flags & 8) {
+#ifdef HAVE_ZLIB_H
+		ssize_t file_start = len;
+#endif
 		do {
 			++len;
 			if (avail < len)
@@ -169,6 +192,14 @@
 			if (p == NULL)
 				return (0);
 		} while (p[len - 1] != 0);
+
+#ifdef HAVE_ZLIB_H
+		if (state) {
+			/* Reset the name in case of repeat header reads. */
+			free(state->name);
+			state->name = strdup((const char *)&p[file_start]);
+		}
+#endif
 	}
 
 	/* Null-terminated optional comment. */
@@ -214,12 +245,11 @@
 
 	(void)self; /* UNUSED */
 
-	if (peek_at_header(filter, &bits_checked))
+	if (peek_at_header(filter, &bits_checked, NULL))
 		return (bits_checked);
 	return (0);
 }
 
-
 #ifndef HAVE_ZLIB_H
 
 /*
@@ -243,6 +273,24 @@
 
 #else
 
+static int
+gzip_read_header(struct archive_read_filter *self, struct archive_entry *entry)
+{
+	struct private_data *state;
+
+	state = (struct private_data *)self->data;
+
+	/* A mtime of 0 is considered invalid/missing. */
+	if (state->mtime != 0)
+		archive_entry_set_mtime(entry, state->mtime, 0);
+
+	/* If the name is available, extract it. */
+	if (state->name)
+		archive_entry_set_pathname(entry, state->name);
+
+	return (ARCHIVE_OK);
+}
+
 /*
  * Initialize the filter object.
  */
@@ -272,6 +320,9 @@
 	self->read = gzip_filter_read;
 	self->skip = NULL; /* not supported */
 	self->close = gzip_filter_close;
+#ifdef HAVE_ZLIB_H
+	self->read_header = gzip_read_header;
+#endif
 
 	state->in_stream = 0; /* We're not actually within a stream yet. */
 
@@ -289,7 +340,7 @@
 	state = (struct private_data *)self->data;
 
 	/* If this is a real header, consume it. */
-	len = peek_at_header(self->upstream, NULL);
+	len = peek_at_header(self->upstream, NULL, state);
 	if (len == 0)
 		return (ARCHIVE_EOF);
 	__archive_read_filter_consume(self->upstream, len);
@@ -374,7 +425,7 @@
 {
 	struct private_data *state;
 	size_t decompressed;
-	ssize_t avail_in;
+	ssize_t avail_in, max_in;
 	int ret;
 
 	state = (struct private_data *)self->data;
@@ -408,6 +459,12 @@
 			    "truncated gzip input");
 			return (ARCHIVE_FATAL);
 		}
+		if (UINT_MAX >= SSIZE_MAX)
+			max_in = SSIZE_MAX;
+		else
+			max_in = UINT_MAX;
+		if (avail_in > max_in)
+			avail_in = max_in;
 		state->stream.avail_in = (uInt)avail_in;
 
 		/* Decompress and consume some of that data. */
@@ -469,6 +526,7 @@
 		}
 	}
 
+	free(state->name);
 	free(state->out_block);
 	free(state);
 	return (ret);
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_support_filter_lz4.c b/Utilities/cmlibarchive/libarchive/archive_read_support_filter_lz4.c
index 147f502..43ee6c2 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_support_filter_lz4.c
+++ b/Utilities/cmlibarchive/libarchive/archive_read_support_filter_lz4.c
@@ -460,7 +460,7 @@
 
 	__archive_read_filter_consume(self->upstream, descriptor_bytes);
 
-	/* Make sure we have an enough buffer for uncompressed data. */
+	/* Make sure we have a large enough buffer for uncompressed data. */
 	if (lz4_allocate_out_block(self) != ARCHIVE_OK)
 		return (ARCHIVE_FATAL);
 	if (state->flags.stream_checksum)
@@ -520,7 +520,7 @@
 	if (read_buf == NULL)
 		goto truncated_error;
 
-	/* Optional process, checking a block sum. */
+	/* Optional processing, checking a block sum. */
 	if (checksum_size) {
 		unsigned int chsum = __archive_xxhash.XXH32(
 			read_buf + 4, (int)compressed_size, 0);
@@ -640,7 +640,7 @@
 	if (ret == 0 && *p == NULL)
 		state->stage = SELECT_STREAM;
 
-	/* Optional process, checking a stream sum. */
+	/* Optional processing, checking a stream sum. */
 	if (state->flags.stream_checksum) {
 		if (state->stage == SELECT_STREAM) {
 			unsigned int checksum;
@@ -660,7 +660,7 @@
 			if (checksum != checksum_stream) {
 				archive_set_error(&self->archive->archive,
 				    ARCHIVE_ERRNO_MISC,
-				    "lz4 stream cheksum error");
+				    "lz4 stream checksum error");
 				return (ARCHIVE_FATAL);
 			}
 		} else if (ret > 0)
@@ -674,7 +674,7 @@
 lz4_filter_read_legacy_stream(struct archive_read_filter *self, const void **p)
 {
 	struct private_data *state = (struct private_data *)self->data;
-	int compressed;
+	uint32_t compressed;
 	const char *read_buf;
 	ssize_t ret;
 
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_support_filter_lzop.c b/Utilities/cmlibarchive/libarchive/archive_read_support_filter_lzop.c
index 4356b82..05f740b 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_support_filter_lzop.c
+++ b/Utilities/cmlibarchive/libarchive/archive_read_support_filter_lzop.c
@@ -50,7 +50,7 @@
 #include <lzo/lzo1x.h>
 #endif
 #ifdef HAVE_ZLIB_H
-#include <cm_zlib.h> /* for crc32 and adler32 */
+#include <cm3p/zlib.h> /* for crc32 and adler32 */
 #endif
 
 #include "archive.h"
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_support_filter_uu.c b/Utilities/cmlibarchive/libarchive/archive_read_support_filter_uu.c
index 6412979..67ddffb 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_support_filter_uu.c
+++ b/Utilities/cmlibarchive/libarchive/archive_read_support_filter_uu.c
@@ -574,14 +574,13 @@
 			while (l > 0) {
 				int n = 0;
 
-				if (l > 0) {
-					if (!uuchar[b[0]] || !uuchar[b[1]])
-						break;
-					n = UUDECODE(*b++) << 18;
-					n |= UUDECODE(*b++) << 12;
-					*out++ = n >> 16; total++;
-					--l;
-				}
+				if (!uuchar[b[0]] || !uuchar[b[1]])
+					break;
+				n = UUDECODE(*b++) << 18;
+				n |= UUDECODE(*b++) << 12;
+				*out++ = n >> 16; total++;
+				--l;
+
 				if (l > 0) {
 					if (!uuchar[b[0]])
 						break;
@@ -626,14 +625,13 @@
 			while (l > 0) {
 				int n = 0;
 
-				if (l > 0) {
-					if (!base64[b[0]] || !base64[b[1]])
-						break;
-					n = base64num[*b++] << 18;
-					n |= base64num[*b++] << 12;
-					*out++ = n >> 16; total++;
-					l -= 2;
-				}
+				if (!base64[b[0]] || !base64[b[1]])
+					break;
+				n = base64num[*b++] << 18;
+				n |= base64num[*b++] << 12;
+				*out++ = n >> 16; total++;
+				l -= 2;
+
 				if (l > 0) {
 					if (*b == '=')
 						break;
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_support_filter_xz.c b/Utilities/cmlibarchive/libarchive/archive_read_support_filter_xz.c
index a188186..3223b38 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_support_filter_xz.c
+++ b/Utilities/cmlibarchive/libarchive/archive_read_support_filter_xz.c
@@ -42,7 +42,7 @@
 #include <unistd.h>
 #endif
 #if HAVE_LZMA_H
-#include <cm_lzma.h>
+#include <cm3p/lzma.h>
 #endif
 
 #include "archive.h"
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_support_filter_zstd.c b/Utilities/cmlibarchive/libarchive/archive_read_support_filter_zstd.c
index 4513706..e1ec60e 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_support_filter_zstd.c
+++ b/Utilities/cmlibarchive/libarchive/archive_read_support_filter_zstd.c
@@ -45,7 +45,7 @@
 #include <unistd.h>
 #endif
 #if HAVE_ZSTD_H
-#include <cm_zstd.h>
+#include <cm3p/zstd.h>
 #endif
 
 #include "archive.h"
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_support_format_7zip.c b/Utilities/cmlibarchive/libarchive/archive_read_support_format_7zip.c
index a885a4c..456b2f8 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_support_format_7zip.c
+++ b/Utilities/cmlibarchive/libarchive/archive_read_support_format_7zip.c
@@ -33,13 +33,13 @@
 #include <stdlib.h>
 #endif
 #ifdef HAVE_BZLIB_H
-#include <cm_bzlib.h>
+#include <cm3p/bzlib.h>
 #endif
 #ifdef HAVE_LZMA_H
-#include <cm_lzma.h>
+#include <cm3p/lzma.h>
 #endif
 #ifdef HAVE_ZLIB_H
-#include <cm_zlib.h>
+#include <cm3p/zlib.h>
 #endif
 
 #include "archive.h"
@@ -1086,10 +1086,17 @@
 				zip->bcj_state = 0;
 				break;
 			case _7Z_DELTA:
+				if (coder2->propertiesSize != 1) {
+					archive_set_error(&a->archive,
+					    ARCHIVE_ERRNO_MISC,
+					    "Invalid Delta parameter");
+					return (ARCHIVE_FAILED);
+				}
 				filters[fi].id = LZMA_FILTER_DELTA;
 				memset(&delta_opt, 0, sizeof(delta_opt));
 				delta_opt.type = LZMA_DELTA_TYPE_BYTE;
-				delta_opt.dist = 1;
+				delta_opt.dist =
+				    (uint32_t)coder2->properties[0] + 1;
 				filters[fi].options = &delta_opt;
 				fi++;
 				break;
@@ -1787,7 +1794,7 @@
 		return (0);
 	}
 
-	if (*p != kSize)
+	if (*p != kCRC)
 		return (-1);
 
 	if (read_Digests(a, &(pi->digest), (size_t)pi->numPackStreams) < 0)
@@ -2964,13 +2971,7 @@
 	if (zip->codec == _7Z_COPY && zip->codec2 == (unsigned long)-1) {
 		/* Copy mode. */
 
-		/*
-		 * Note: '1' here is a performance optimization.
-		 * Recall that the decompression layer returns a count of
-		 * available bytes; asking for more than that forces the
-		 * decompressor to combine reads by copying data.
-		 */
-		*buff = __archive_read_ahead(a, 1, &bytes_avail);
+		*buff = __archive_read_ahead(a, minimum, &bytes_avail);
 		if (bytes_avail <= 0) {
 			archive_set_error(&a->archive,
 			    ARCHIVE_ERRNO_FILE_FORMAT,
@@ -3323,8 +3324,7 @@
 	 * Release the memory which the previous folder used for BCJ2.
 	 */
 	for (i = 0; i < 3; i++) {
-		if (zip->sub_stream_buff[i] != NULL)
-			free(zip->sub_stream_buff[i]);
+		free(zip->sub_stream_buff[i]);
 		zip->sub_stream_buff[i] = NULL;
 	}
 
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_support_format_all.c b/Utilities/cmlibarchive/libarchive/archive_read_support_format_all.c
index 2127ebd3..dea558b 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_support_format_all.c
+++ b/Utilities/cmlibarchive/libarchive/archive_read_support_format_all.c
@@ -72,6 +72,7 @@
 	archive_read_support_format_7zip(a);
 	archive_read_support_format_cab(a);
 	archive_read_support_format_rar(a);
+	archive_read_support_format_rar5(a);
 	archive_read_support_format_iso9660(a);
 	/* Seek is really bad, since it forces the read-ahead
 	 * logic to discard buffered data. */
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_support_format_ar.c b/Utilities/cmlibarchive/libarchive/archive_read_support_format_ar.c
index b6b9fc3..296b7db 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_support_format_ar.c
+++ b/Utilities/cmlibarchive/libarchive/archive_read_support_format_ar.c
@@ -138,8 +138,7 @@
 	struct ar *ar;
 
 	ar = (struct ar *)(a->format->data);
-	if (ar->strtab)
-		free(ar->strtab);
+	free(ar->strtab);
 	free(ar);
 	(a->format->data) = NULL;
 	return (ARCHIVE_OK);
@@ -388,9 +387,10 @@
 
 	/*
 	 * "/" is the SVR4/GNU archive symbol table.
+	 * "/SYM64/" is the SVR4/GNU 64-bit variant archive symbol table.
 	 */
-	if (strcmp(filename, "/") == 0) {
-		archive_entry_copy_pathname(entry, "/");
+	if (strcmp(filename, "/") == 0 || strcmp(filename, "/SYM64/") == 0) {
+		archive_entry_copy_pathname(entry, filename);
 		/* Parse the time, owner, mode, size fields. */
 		r = ar_parse_common_header(ar, entry, h);
 		/* Force the file type to a regular file. */
@@ -459,6 +459,7 @@
 	uint64_t n;
 
 	/* Copy remaining header */
+	archive_entry_set_filetype(entry, AE_IFREG);
 	archive_entry_set_mtime(entry,
 	    (time_t)ar_atol10(h + AR_date_offset, AR_date_size), 0L);
 	archive_entry_set_uid(entry,
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_support_format_by_code.c b/Utilities/cmlibarchive/libarchive/archive_read_support_format_by_code.c
index 084563f..034353d 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_support_format_by_code.c
+++ b/Utilities/cmlibarchive/libarchive/archive_read_support_format_by_code.c
@@ -60,6 +60,9 @@
 	case ARCHIVE_FORMAT_RAR:
 		return archive_read_support_format_rar(a);
 		break;
+	case ARCHIVE_FORMAT_RAR_V5:
+		return archive_read_support_format_rar5(a);
+		break;
 	case ARCHIVE_FORMAT_TAR:
 		return archive_read_support_format_tar(a);
 		break;
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_support_format_cab.c b/Utilities/cmlibarchive/libarchive/archive_read_support_format_cab.c
index 51f79fa..58644ba 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_support_format_cab.c
+++ b/Utilities/cmlibarchive/libarchive/archive_read_support_format_cab.c
@@ -38,7 +38,7 @@
 #include <string.h>
 #endif
 #ifdef HAVE_ZLIB_H
-#include <cm_zlib.h>
+#include <cm3p/zlib.h>
 #endif
 
 #include "archive.h"
@@ -1509,8 +1509,8 @@
 			}
 			if (mszip == 1 && cab->stream.next_in[0] != 0x4b)
 				goto nomszip;
-			else if (cab->stream.next_in[0] != 0x43 ||
-			    cab->stream.next_in[1] != 0x4b)
+			else if (mszip == 2 && (cab->stream.next_in[0] != 0x43 ||
+			    cab->stream.next_in[1] != 0x4b))
 				goto nomszip;
 			cab->stream.next_in += mszip;
 			cab->stream.avail_in -= mszip;
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_support_format_cpio.c b/Utilities/cmlibarchive/libarchive/archive_read_support_format_cpio.c
index 67d5b21..1c96e6a 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_support_format_cpio.c
+++ b/Utilities/cmlibarchive/libarchive/archive_read_support_format_cpio.c
@@ -955,8 +955,7 @@
         while (cpio->links_head != NULL) {
                 struct links_entry *lp = cpio->links_head->next;
 
-                if (cpio->links_head->name)
-                        free(cpio->links_head->name);
+                free(cpio->links_head->name);
                 free(cpio->links_head);
                 cpio->links_head = lp;
         }
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_support_format_iso9660.c b/Utilities/cmlibarchive/libarchive/archive_read_support_format_iso9660.c
index 93649f8..9121166 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_support_format_iso9660.c
+++ b/Utilities/cmlibarchive/libarchive/archive_read_support_format_iso9660.c
@@ -41,7 +41,7 @@
 #endif
 #include <time.h>
 #ifdef HAVE_ZLIB_H
-#include <cm_zlib.h>
+#include <cm3p/zlib.h>
 #endif
 
 #include "archive.h"
@@ -1724,8 +1724,7 @@
 	free(iso9660->read_ce_req.reqs);
 	archive_string_free(&iso9660->pathname);
 	archive_string_free(&iso9660->previous_pathname);
-	if (iso9660->pending_files.files)
-		free(iso9660->pending_files.files);
+	free(iso9660->pending_files.files);
 #ifdef HAVE_ZLIB_H
 	free(iso9660->entry_zisofs.uncompressed_buffer);
 	free(iso9660->entry_zisofs.block_pointers);
@@ -2102,6 +2101,7 @@
     const unsigned char *p, const unsigned char *end)
 {
 	struct iso9660 *iso9660;
+	int entry_seen = 0;
 
 	iso9660 = (struct iso9660 *)(a->format->data);
 
@@ -2257,8 +2257,16 @@
 		}
 
 		p += p[2];
+		entry_seen = 1;
 	}
-	return (ARCHIVE_OK);
+
+	if (entry_seen)
+		return (ARCHIVE_OK);
+	else {
+		archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+				  "Tried to parse Rockridge extensions, but none found");
+		return (ARCHIVE_WARN);
+	}
 }
 
 static int
@@ -3029,8 +3037,7 @@
 		if (heap->allocated)
 			memcpy(new_pending_files, heap->files,
 			    heap->allocated * sizeof(new_pending_files[0]));
-		if (heap->files != NULL)
-			free(heap->files);
+		free(heap->files);
 		heap->files = new_pending_files;
 		heap->allocated = new_size;
 	}
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_support_format_lha.c b/Utilities/cmlibarchive/libarchive/archive_read_support_format_lha.c
index 98d02c6..1357f9a 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_support_format_lha.c
+++ b/Utilities/cmlibarchive/libarchive/archive_read_support_format_lha.c
@@ -175,7 +175,9 @@
 	struct archive_string 	 gname;
 	uint16_t		 header_crc;
 	uint16_t		 crc;
-	struct archive_string_conv *sconv;
+	/* dirname and filename could be in different codepages */
+	struct archive_string_conv *sconv_dir;
+	struct archive_string_conv *sconv_fname;
 	struct archive_string_conv *opt_sconv;
 
 	struct archive_string 	 dirname;
@@ -232,8 +234,8 @@
 static time_t	lha_win_time(uint64_t, long *);
 static unsigned char	lha_calcsum(unsigned char, const void *,
 		    int, size_t);
-static int	lha_parse_linkname(struct archive_string *,
-		    struct archive_string *);
+static int	lha_parse_linkname(struct archive_wstring *,
+		    struct archive_wstring *);
 static int	lha_read_data_none(struct archive_read *, const void **,
 		    size_t *, int64_t *);
 static int	lha_read_data_lzh(struct archive_read *, const void **,
@@ -473,13 +475,15 @@
 archive_read_format_lha_read_header(struct archive_read *a,
     struct archive_entry *entry)
 {
-	struct archive_string linkname;
-	struct archive_string pathname;
+	struct archive_wstring linkname;
+	struct archive_wstring pathname;
 	struct lha *lha;
 	const unsigned char *p;
 	const char *signature;
 	int err;
-	
+	struct archive_mstring conv_buffer;
+	const wchar_t *conv_buffer_p;
+
 	lha_crc16_init();
 
 	a->archive.archive_format = ARCHIVE_FORMAT_LHA;
@@ -561,10 +565,13 @@
 	archive_string_empty(&lha->dirname);
 	archive_string_empty(&lha->filename);
 	lha->dos_attr = 0;
-	if (lha->opt_sconv != NULL)
-		lha->sconv = lha->opt_sconv;
-	else
-		lha->sconv = NULL;
+	if (lha->opt_sconv != NULL) {
+		lha->sconv_dir = lha->opt_sconv;
+		lha->sconv_fname = lha->opt_sconv;
+	} else {
+		lha->sconv_dir = NULL;
+		lha->sconv_fname = NULL;
+	}
 
 	switch (p[H_LEVEL_OFFSET]) {
 	case 0:
@@ -594,12 +601,54 @@
 		return (truncated_error(a));
 
 	/*
-	 * Make a pathname from a dirname and a filename.
-	 */
-	archive_string_concat(&lha->dirname, &lha->filename);
+	 * Make a pathname from a dirname and a filename, after converting to Unicode.
+	 * This is because codepages might differ between dirname and filename.
+	*/
 	archive_string_init(&pathname);
 	archive_string_init(&linkname);
-	archive_string_copy(&pathname, &lha->dirname);
+	archive_string_init(&conv_buffer.aes_mbs);
+	archive_string_init(&conv_buffer.aes_mbs_in_locale);
+	archive_string_init(&conv_buffer.aes_utf8);
+	archive_string_init(&conv_buffer.aes_wcs);
+	if (0 != archive_mstring_copy_mbs_len_l(&conv_buffer, lha->dirname.s, lha->dirname.length, lha->sconv_dir)) {
+		archive_set_error(&a->archive,
+			ARCHIVE_ERRNO_FILE_FORMAT,
+			"Pathname cannot be converted "
+			"from %s to Unicode.",
+			archive_string_conversion_charset_name(lha->sconv_dir));
+		err = ARCHIVE_FATAL;
+	} else if (0 != archive_mstring_get_wcs(&a->archive, &conv_buffer, &conv_buffer_p))
+		err = ARCHIVE_FATAL;
+	if (err == ARCHIVE_FATAL) {
+		archive_mstring_clean(&conv_buffer);
+		archive_wstring_free(&pathname);
+		archive_wstring_free(&linkname);
+		return (err);
+	}
+	archive_wstring_copy(&pathname, &conv_buffer.aes_wcs);
+
+	archive_string_empty(&conv_buffer.aes_mbs);
+	archive_string_empty(&conv_buffer.aes_mbs_in_locale);
+	archive_string_empty(&conv_buffer.aes_utf8);
+	archive_wstring_empty(&conv_buffer.aes_wcs);
+	if (0 != archive_mstring_copy_mbs_len_l(&conv_buffer, lha->filename.s, lha->filename.length, lha->sconv_fname)) {
+		archive_set_error(&a->archive,
+			ARCHIVE_ERRNO_FILE_FORMAT,
+			"Pathname cannot be converted "
+			"from %s to Unicode.",
+			archive_string_conversion_charset_name(lha->sconv_fname));
+		err = ARCHIVE_FATAL;
+	}
+	else if (0 != archive_mstring_get_wcs(&a->archive, &conv_buffer, &conv_buffer_p))
+		err = ARCHIVE_FATAL;
+	if (err == ARCHIVE_FATAL) {
+		archive_mstring_clean(&conv_buffer);
+		archive_wstring_free(&pathname);
+		archive_wstring_free(&linkname);
+		return (err);
+	}
+	archive_wstring_concat(&pathname, &conv_buffer.aes_wcs);
+	archive_mstring_clean(&conv_buffer);
 
 	if ((lha->mode & AE_IFMT) == AE_IFLNK) {
 		/*
@@ -610,8 +659,8 @@
 			archive_set_error(&a->archive,
 		    	    ARCHIVE_ERRNO_FILE_FORMAT,
 			    "Unknown symlink-name");
-			archive_string_free(&pathname);
-			archive_string_free(&linkname);
+			archive_wstring_free(&pathname);
+			archive_wstring_free(&linkname);
 			return (ARCHIVE_FAILED);
 		}
 	} else {
@@ -629,39 +678,13 @@
 	/*
 	 * Set basic file parameters.
 	 */
-	if (archive_entry_copy_pathname_l(entry, pathname.s,
-	    pathname.length, lha->sconv) != 0) {
-		if (errno == ENOMEM) {
-			archive_set_error(&a->archive, ENOMEM,
-			    "Can't allocate memory for Pathname");
-			return (ARCHIVE_FATAL);
-		}
-		archive_set_error(&a->archive,
-		    ARCHIVE_ERRNO_FILE_FORMAT,
-		    "Pathname cannot be converted "
-		    "from %s to current locale.",
-		    archive_string_conversion_charset_name(lha->sconv));
-		err = ARCHIVE_WARN;
-	}
-	archive_string_free(&pathname);
+	archive_entry_copy_pathname_w(entry, pathname.s);
+	archive_wstring_free(&pathname);
 	if (archive_strlen(&linkname) > 0) {
-		if (archive_entry_copy_symlink_l(entry, linkname.s,
-		    linkname.length, lha->sconv) != 0) {
-			if (errno == ENOMEM) {
-				archive_set_error(&a->archive, ENOMEM,
-				    "Can't allocate memory for Linkname");
-				return (ARCHIVE_FATAL);
-			}
-			archive_set_error(&a->archive,
-			    ARCHIVE_ERRNO_FILE_FORMAT,
-			    "Linkname cannot be converted "
-			    "from %s to current locale.",
-			    archive_string_conversion_charset_name(lha->sconv));
-			err = ARCHIVE_WARN;
-		}
+		archive_entry_copy_symlink_w(entry, linkname.s);
 	} else
 		archive_entry_set_symlink(entry, NULL);
-	archive_string_free(&linkname);
+	archive_wstring_free(&linkname);
 	/*
 	 * When a header level is 0, there is a possibility that
 	 * a pathname and a symlink has '\' character, a directory
@@ -1208,6 +1231,27 @@
 			archive_strncpy(&lha->filename,
 			    (const char *)extdheader, datasize);
 			break;
+		case EXT_UTF16_FILENAME:
+			if (datasize == 0) {
+				/* maybe directory header */
+				archive_string_empty(&lha->filename);
+				break;
+			} else if (datasize & 1) {
+				/* UTF-16 characters take always 2 or 4 bytes */
+				goto invalid;
+			}
+			if (extdheader[0] == '\0')
+				goto invalid;
+			archive_string_empty(&lha->filename);
+			archive_array_append(&lha->filename,
+				(const char *)extdheader, datasize);
+			/* Setup a string conversion for a filename. */
+			lha->sconv_fname =
+			    archive_string_conversion_from_charset(&a->archive,
+			        "UTF-16LE", 1);
+			if (lha->sconv_fname == NULL)
+				return (ARCHIVE_FATAL);
+			break;
 		case EXT_DIRECTORY:
 			if (datasize == 0 || extdheader[0] == '\0')
 				/* no directory name data. exit this case. */
@@ -1228,6 +1272,50 @@
 				/* invalid directory data */
 				goto invalid;
 			break;
+		case EXT_UTF16_DIRECTORY:
+			/* UTF-16 characters take always 2 or 4 bytes */
+			if (datasize == 0 || (datasize & 1) ||
+			    extdheader[0] == '\0') {
+				/* no directory name data. exit this case. */
+				goto invalid;
+			}
+
+			archive_string_empty(&lha->dirname);
+			archive_array_append(&lha->dirname,
+				(const char *)extdheader, datasize);
+			lha->sconv_dir =
+			    archive_string_conversion_from_charset(&a->archive,
+			        "UTF-16LE", 1);
+			if (lha->sconv_dir == NULL)
+				return (ARCHIVE_FATAL);
+			else {
+				/*
+				 * Convert directory delimiter from 0xFFFF
+				 * to '/' for local system.
+				 */
+				uint16_t dirSep;
+				uint16_t d = 1;
+				if (archive_be16dec(&d) == 1)
+					dirSep = 0x2F00;
+				else
+					dirSep = 0x002F;
+
+				/* UTF-16LE character */
+				uint16_t *utf16name =
+				    (uint16_t *)lha->dirname.s;
+				for (i = 0; i < lha->dirname.length / 2; i++) {
+					if (utf16name[i] == 0xFFFF) {
+						utf16name[i] = dirSep;
+					}
+				}
+				/* Is last character directory separator? */
+				if (utf16name[lha->dirname.length / 2 - 1] !=
+				    dirSep) {
+					/* invalid directory data */
+					goto invalid;
+				}
+			}
+			break;
 		case EXT_DOS_ATTR:
 			if (datasize == 2)
 				lha->dos_attr = (unsigned char)
@@ -1276,11 +1364,16 @@
 					charset = cp.s;
 					break;
 				}
-				lha->sconv =
+				lha->sconv_dir =
+				    archive_string_conversion_from_charset(
+					&(a->archive), charset, 1);
+				lha->sconv_fname =
 				    archive_string_conversion_from_charset(
 					&(a->archive), charset, 1);
 				archive_string_free(&cp);
-				if (lha->sconv == NULL)
+				if (lha->sconv_dir == NULL)
+					return (ARCHIVE_FATAL);
+				if (lha->sconv_fname == NULL)
 					return (ARCHIVE_FATAL);
 			}
 			break;
@@ -1336,8 +1429,7 @@
 			}
 			break;
 		case EXT_TIMEZONE:		/* Not supported */
-		case EXT_UTF16_FILENAME:	/* Not supported */
-		case EXT_UTF16_DIRECTORY:	/* Not supported */
+			break;
 		default:
 			break;
 		}
@@ -1600,19 +1692,19 @@
  *  then a archived pathname is 'xxx/bbb|aaa/bb/cc'
  */
 static int
-lha_parse_linkname(struct archive_string *linkname,
-    struct archive_string *pathname)
+lha_parse_linkname(struct archive_wstring *linkname,
+    struct archive_wstring *pathname)
 {
-	char *	linkptr;
+	wchar_t *	linkptr;
 	size_t 	symlen;
 
-	linkptr = strchr(pathname->s, '|');
+	linkptr = wcschr(pathname->s, L'|');
 	if (linkptr != NULL) {
-		symlen = strlen(linkptr + 1);
-		archive_strncpy(linkname, linkptr+1, symlen);
+		symlen = wcslen(linkptr + 1);
+		archive_wstrncpy(linkname, linkptr+1, symlen);
 
 		*linkptr = 0;
-		pathname->length = strlen(pathname->s);
+		pathname->length = wcslen(pathname->s);
 
 		return (1);
 	}
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_support_format_mtree.c b/Utilities/cmlibarchive/libarchive/archive_read_support_format_mtree.c
index 5b0eadc..332944a 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_support_format_mtree.c
+++ b/Utilities/cmlibarchive/libarchive/archive_read_support_format_mtree.c
@@ -45,6 +45,9 @@
 #ifdef HAVE_STRING_H
 #include <string.h>
 #endif
+#ifdef HAVE_CTYPE_H
+#include <ctype.h>
+#endif
 
 #include "archive.h"
 #include "archive_entry.h"
@@ -255,6 +258,7 @@
 		    "Can't allocate mtree data");
 		return (ARCHIVE_FATAL);
 	}
+	mtree->checkfs = 0;
 	mtree->fd = -1;
 
 	__archive_rb_tree_init(&mtree->rbtree, &rb_ops);
@@ -1011,7 +1015,7 @@
 {
 	ssize_t len;
 	uintmax_t counter;
-	char *p;
+	char *p, *s;
 	struct mtree_option *global;
 	struct mtree_entry *last_entry;
 	int r, is_form_d;
@@ -1025,6 +1029,7 @@
 	(void)detect_form(a, &is_form_d);
 
 	for (counter = 1; ; ++counter) {
+		r = ARCHIVE_OK;
 		len = readline(a, mtree, &p, 65536);
 		if (len == 0) {
 			mtree->this_entry = mtree->entries;
@@ -1045,6 +1050,15 @@
 			continue;
 		if (*p == '\r' || *p == '\n' || *p == '\0')
 			continue;
+		/* Non-printable characters are not allowed */
+		for (s = p;s < p + len - 1; s++) {
+			if (!isprint(*s)) {
+				r = ARCHIVE_FATAL;
+				break;
+			}
+		}
+		if (r != ARCHIVE_OK)
+			break;
 		if (*p != '/') {
 			r = process_add_entry(a, mtree, &global, p, len,
 			    &last_entry, is_form_d);
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_support_format_rar.c b/Utilities/cmlibarchive/libarchive/archive_read_support_format_rar.c
index c68d77b..61f2330 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_support_format_rar.c
+++ b/Utilities/cmlibarchive/libarchive/archive_read_support_format_rar.c
@@ -32,7 +32,7 @@
 #include <time.h>
 #include <limits.h>
 #ifdef HAVE_ZLIB_H
-#include <cm_zlib.h> /* crc32 */
+#include <cm3p/zlib.h> /* crc32 */
 #endif
 
 #include "archive.h"
@@ -148,6 +148,9 @@
 #define FILE_ATTRIBUTE_DIRECTORY 0x10
 #endif
 
+#undef minimum
+#define minimum(a, b)	((a)<(b)?(a):(b))
+
 /* Fields common to all headers */
 struct rar_header
 {
@@ -258,6 +261,7 @@
   struct data_block_offsets *dbo;
   unsigned int cursor;
   unsigned int nodes;
+  char filename_must_match;
 
   /* LZSS members */
   struct huffman_code maincode;
@@ -1023,8 +1027,11 @@
   case COMPRESS_METHOD_GOOD:
   case COMPRESS_METHOD_BEST:
     ret = read_data_compressed(a, buff, size, offset);
-    if (ret != ARCHIVE_OK && ret != ARCHIVE_WARN)
+    if (ret != ARCHIVE_OK && ret != ARCHIVE_WARN) {
       __archive_ppmd7_functions.Ppmd7_Free(&rar->ppmd7_context);
+      rar->start_new_table = 1;
+      rar->ppmd_valid = 0;
+    }
     break;
 
   default:
@@ -1560,6 +1567,12 @@
     }
     return ret;
   }
+  else if (rar->filename_must_match)
+  {
+    archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+      "Mismatch of file parts split across multi-volume archive");
+    return (ARCHIVE_FATAL);
+  }
 
   rar->filename_save = (char*)realloc(rar->filename_save,
                                       filename_size + 1);
@@ -1712,6 +1725,13 @@
   struct tm *tm;
   time_t t;
   long nsec;
+#if defined(HAVE_LOCALTIME_R) || defined(HAVE__LOCALTIME64_S)
+  struct tm tmbuf;
+#endif
+#if defined(HAVE__LOCALTIME64_S)
+  errno_t terr;
+  __time64_t tmptime;
+#endif
 
   if (p + 2 > endp)
     return (-1);
@@ -1743,7 +1763,18 @@
         rem = (((unsigned)(unsigned char)*p) << 16) | (rem >> 8);
         p++;
       }
+#if defined(HAVE_LOCALTIME_R)
+      tm = localtime_r(&t, &tmbuf);
+#elif defined(HAVE__LOCALTIME64_S)
+      tmptime = t;
+      terr = _localtime64_s(&tmbuf, &tmptime);
+      if (terr)
+        tm = NULL;
+      else
+        tm = &tmbuf;
+#else
       tm = localtime(&t);
+#endif
       nsec = tm->tm_sec + rem / NS_UNIT;
       if (rmode & 4)
       {
@@ -2300,6 +2331,11 @@
       new_size = DICTIONARY_MAX_SIZE;
     else
       new_size = rar_fls((unsigned int)rar->unp_size) << 1;
+    if (new_size == 0) {
+      archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+                        "Zero window size is invalid.");
+      return (ARCHIVE_FATAL);
+    }
     new_window = realloc(rar->lzss.window, new_size);
     if (new_window == NULL) {
       archive_set_error(&a->archive, ENOMEM,
@@ -2437,8 +2473,11 @@
       if (add_value(a, code, j, codebits, i) != ARCHIVE_OK)
         return (ARCHIVE_FATAL);
       codebits++;
-      if (--symbolsleft <= 0) { break; break; }
+      if (--symbolsleft <= 0)
+        break;
     }
+    if (symbolsleft <= 0)
+      break;
     codebits <<= 1;
   }
   return (ARCHIVE_OK);
@@ -2448,7 +2487,8 @@
 add_value(struct archive_read *a, struct huffman_code *code, int value,
           int codebits, int length)
 {
-  int repeatpos, lastnode, bitpos, bit, repeatnode, nextnode;
+  int lastnode, bitpos, bit;
+  /* int repeatpos, repeatnode, nextnode; */
 
   free(code->table);
   code->table = NULL;
@@ -2458,6 +2498,9 @@
   if(length < code->minlength)
     code->minlength = length;
 
+  /*
+   * Dead code, repeatpos was is -1
+   *
   repeatpos = -1;
   if (repeatpos == 0 || (repeatpos >= 0
     && (((codebits >> (repeatpos - 1)) & 3) == 0
@@ -2467,6 +2510,7 @@
                       "Invalid repeat position");
     return (ARCHIVE_FATAL);
   }
+  */
 
   lastnode = 0;
   for (bitpos = length - 1; bitpos >= 0; bitpos--)
@@ -2482,9 +2526,12 @@
       return (ARCHIVE_FATAL);
     }
 
+    /*
+     * Dead code, repeatpos was -1, bitpos >=0
+     *
     if (bitpos == repeatpos)
     {
-      /* Open branch check */
+      * Open branch check *
       if (!(code->tree[lastnode].branches[bit] < 0))
       {
         archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
@@ -2503,16 +2550,17 @@
         return (ARCHIVE_FATAL);
       }
 
-      /* Set branches */
+      * Set branches *
       code->tree[lastnode].branches[bit] = repeatnode;
       code->tree[repeatnode].branches[bit] = repeatnode;
       code->tree[repeatnode].branches[bit^1] = nextnode;
       lastnode = nextnode;
 
-      bitpos++; /* terminating bit already handled, skip it */
+      bitpos++; * terminating bit already handled, skip it *
     }
     else
     {
+    */
       /* Open branch check */
       if (code->tree[lastnode].branches[bit] < 0)
       {
@@ -2526,7 +2574,7 @@
 
       /* set to branch */
       lastnode = code->tree[lastnode].branches[bit];
-    }
+ /* } */
   }
 
   if (!(code->tree[lastnode].branches[0] == -1
@@ -2610,11 +2658,15 @@
       table[i].value = code->tree[node].branches[0];
     }
   }
+  /*
+   * Dead code, node >= 0
+   *
   else if (node < 0)
   {
     for(i = 0; i < currtablesize; i++)
       table[i].length = -1;
   }
+   */
   else
   {
     if(depth == maxdepth)
@@ -2646,6 +2698,10 @@
       0, 1, 1, 1, 1, 2, 2,
       2, 2, 3, 3, 3, 3, 4,
       4, 4, 4, 5, 5, 5, 5 };
+  static const int lengthb_min = minimum(
+    (int)(sizeof(lengthbases)/sizeof(lengthbases[0])),
+    (int)(sizeof(lengthbits)/sizeof(lengthbits[0]))
+  );
   static const unsigned int offsetbases[] =
     {       0,       1,       2,       3,       4,       6,
             8,      12,      16,      24,      32,      48,
@@ -2663,6 +2719,10 @@
       11, 11, 12, 12, 13, 13, 14, 14, 15, 15, 16, 16,
       16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
       18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18 };
+  static const int offsetb_min = minimum(
+    (int)(sizeof(offsetbases)/sizeof(offsetbases[0])),
+    (int)(sizeof(offsetbits)/sizeof(offsetbits[0]))
+  );
   static const unsigned char shortbases[] =
     { 0, 4, 8, 16, 32, 64, 128, 192 };
   static const unsigned char shortbits[] =
@@ -2742,9 +2802,7 @@
 
       if ((lensymbol = read_next_symbol(a, &rar->lengthcode)) < 0)
         goto bad_data;
-      if (lensymbol > (int)(sizeof(lengthbases)/sizeof(lengthbases[0])))
-        goto bad_data;
-      if (lensymbol > (int)(sizeof(lengthbits)/sizeof(lengthbits[0])))
+      if (lensymbol > lengthb_min)
         goto bad_data;
       len = lengthbases[lensymbol] + 2;
       if (lengthbits[lensymbol] > 0) {
@@ -2776,9 +2834,7 @@
     }
     else
     {
-      if (symbol-271 > (int)(sizeof(lengthbases)/sizeof(lengthbases[0])))
-        goto bad_data;
-      if (symbol-271 > (int)(sizeof(lengthbits)/sizeof(lengthbits[0])))
+      if (symbol-271 > lengthb_min)
         goto bad_data;
       len = lengthbases[symbol-271]+3;
       if(lengthbits[symbol-271] > 0) {
@@ -2790,9 +2846,7 @@
 
       if ((offssymbol = read_next_symbol(a, &rar->offsetcode)) < 0)
         goto bad_data;
-      if (offssymbol > (int)(sizeof(offsetbases)/sizeof(offsetbases[0])))
-        goto bad_data;
-      if (offssymbol > (int)(sizeof(offsetbits)/sizeof(offsetbits[0])))
+      if (offssymbol > offsetb_min)
         goto bad_data;
       offs = offsetbases[offssymbol]+1;
       if(offsetbits[offssymbol] > 0)
@@ -2928,12 +2982,14 @@
     else if (*avail == 0 && rar->main_flags & MHD_VOLUME &&
       rar->file_flags & FHD_SPLIT_AFTER)
     {
+      rar->filename_must_match = 1;
       ret = archive_read_format_rar_read_header(a, a->entry);
       if (ret == (ARCHIVE_EOF))
       {
         rar->has_endarc_header = 1;
         ret = archive_read_format_rar_read_header(a, a->entry);
       }
+      rar->filename_must_match = 0;
       if (ret != (ARCHIVE_OK))
         return NULL;
       return rar_read_ahead(a, min, avail);
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_support_format_rar5.c b/Utilities/cmlibarchive/libarchive/archive_read_support_format_rar5.c
new file mode 100644
index 0000000..d3a1c1b
--- /dev/null
+++ b/Utilities/cmlibarchive/libarchive/archive_read_support_format_rar5.c
@@ -0,0 +1,4103 @@
+/*-
+* Copyright (c) 2018 Grzegorz Antoniak (http://antoniak.org)
+* All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions
+* are met:
+* 1. Redistributions of source code must retain the above copyright
+*    notice, this list of conditions and the following disclaimer.
+* 2. Redistributions in binary form must reproduce the above copyright
+*    notice, this list of conditions and the following disclaimer in the
+*    documentation and/or other materials provided with the distribution.
+*
+* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+* IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include "archive_platform.h"
+#include "archive_endian.h"
+
+#ifdef HAVE_ERRNO_H
+#include <errno.h>
+#endif
+#include <time.h>
+#ifdef HAVE_ZLIB_H
+#include <cm3p/zlib.h> /* crc32 */
+#endif
+#ifdef HAVE_LIMITS_H
+#include <limits.h>
+#endif
+
+#include "archive.h"
+#ifndef HAVE_ZLIB_H
+#include "archive_crc32.h"
+#endif
+
+#include "archive_entry.h"
+#include "archive_entry_locale.h"
+#include "archive_ppmd7_private.h"
+#include "archive_entry_private.h"
+
+#ifdef HAVE_BLAKE2_H
+#include <blake2.h>
+#else
+#include "archive_blake2.h"
+#endif
+
+/*#define CHECK_CRC_ON_SOLID_SKIP*/
+/*#define DONT_FAIL_ON_CRC_ERROR*/
+/*#define DEBUG*/
+
+#define rar5_min(a, b) (((a) > (b)) ? (b) : (a))
+#define rar5_max(a, b) (((a) > (b)) ? (a) : (b))
+#define rar5_countof(X) ((const ssize_t) (sizeof(X) / sizeof(*X)))
+
+#if defined DEBUG
+#define DEBUG_CODE if(1)
+#define LOG(...) do { printf("rar5: " __VA_ARGS__); puts(""); } while(0)
+#else
+#define DEBUG_CODE if(0)
+#endif
+
+/* Real RAR5 magic number is:
+ *
+ * 0x52, 0x61, 0x72, 0x21, 0x1a, 0x07, 0x01, 0x00
+ * "Rar!→•☺·\x00"
+ *
+ * Retrieved with `rar5_signature()` by XOR'ing it with 0xA1, because I don't
+ * want to put this magic sequence in each binary that uses libarchive, so
+ * applications that scan through the file for this marker won't trigger on
+ * this "false" one.
+ *
+ * The array itself is decrypted in `rar5_init` function. */
+
+static unsigned char rar5_signature_xor[] = { 243, 192, 211, 128, 187, 166, 160, 161 };
+static const size_t g_unpack_window_size = 0x20000;
+
+/* These could have been static const's, but they aren't, because of
+ * Visual Studio. */
+#define MAX_NAME_IN_CHARS 2048
+#define MAX_NAME_IN_BYTES (4 * MAX_NAME_IN_CHARS)
+
+struct file_header {
+	ssize_t bytes_remaining;
+	ssize_t unpacked_size;
+	int64_t last_offset;         /* Used in sanity checks. */
+	int64_t last_size;           /* Used in sanity checks. */
+
+	uint8_t solid : 1;           /* Is this a solid stream? */
+	uint8_t service : 1;         /* Is this file a service data? */
+	uint8_t eof : 1;             /* Did we finish unpacking the file? */
+	uint8_t dir : 1;             /* Is this file entry a directory? */
+
+	/* Optional time fields. */
+	uint64_t e_mtime;
+	uint64_t e_ctime;
+	uint64_t e_atime;
+	uint32_t e_unix_ns;
+
+	/* Optional hash fields. */
+	uint32_t stored_crc32;
+	uint32_t calculated_crc32;
+	uint8_t blake2sp[32];
+	blake2sp_state b2state;
+	char has_blake2;
+
+	/* Optional redir fields */
+	uint64_t redir_type;
+	uint64_t redir_flags;
+
+	ssize_t solid_window_size; /* Used in file format check. */
+};
+
+enum EXTRA {
+	EX_CRYPT = 0x01,
+	EX_HASH = 0x02,
+	EX_HTIME = 0x03,
+	EX_VERSION = 0x04,
+	EX_REDIR = 0x05,
+	EX_UOWNER = 0x06,
+	EX_SUBDATA = 0x07
+};
+
+#define REDIR_SYMLINK_IS_DIR	1
+
+enum REDIR_TYPE {
+	REDIR_TYPE_NONE = 0,
+	REDIR_TYPE_UNIXSYMLINK = 1,
+	REDIR_TYPE_WINSYMLINK = 2,
+	REDIR_TYPE_JUNCTION = 3,
+	REDIR_TYPE_HARDLINK = 4,
+	REDIR_TYPE_FILECOPY = 5,
+};
+
+#define	OWNER_USER_NAME		0x01
+#define	OWNER_GROUP_NAME	0x02
+#define	OWNER_USER_UID		0x04
+#define	OWNER_GROUP_GID		0x08
+#define	OWNER_MAXNAMELEN	256
+
+enum FILTER_TYPE {
+	FILTER_DELTA = 0,   /* Generic pattern. */
+	FILTER_E8    = 1,   /* Intel x86 code. */
+	FILTER_E8E9  = 2,   /* Intel x86 code. */
+	FILTER_ARM   = 3,   /* ARM code. */
+	FILTER_AUDIO = 4,   /* Audio filter, not used in RARv5. */
+	FILTER_RGB   = 5,   /* Color palette, not used in RARv5. */
+	FILTER_ITANIUM = 6, /* Intel's Itanium, not used in RARv5. */
+	FILTER_PPM   = 7,   /* Predictive pattern matching, not used in
+			       RARv5. */
+	FILTER_NONE  = 8,
+};
+
+struct filter_info {
+	int type;
+	int channels;
+	int pos_r;
+
+	int64_t block_start;
+	ssize_t block_length;
+	uint16_t width;
+};
+
+struct data_ready {
+	char used;
+	const uint8_t* buf;
+	size_t size;
+	int64_t offset;
+};
+
+struct cdeque {
+	uint16_t beg_pos;
+	uint16_t end_pos;
+	uint16_t cap_mask;
+	uint16_t size;
+	size_t* arr;
+};
+
+struct decode_table {
+	uint32_t size;
+	int32_t decode_len[16];
+	uint32_t decode_pos[16];
+	uint32_t quick_bits;
+	uint8_t quick_len[1 << 10];
+	uint16_t quick_num[1 << 10];
+	uint16_t decode_num[306];
+};
+
+struct comp_state {
+	/* Flag used to specify if unpacker needs to reinitialize the
+	   uncompression context. */
+	uint8_t initialized : 1;
+
+	/* Flag used when applying filters. */
+	uint8_t all_filters_applied : 1;
+
+	/* Flag used to skip file context reinitialization, used when unpacker
+	   is skipping through different multivolume archives. */
+	uint8_t switch_multivolume : 1;
+
+	/* Flag used to specify if unpacker has processed the whole data block
+	   or just a part of it. */
+	uint8_t block_parsing_finished : 1;
+
+	signed int notused : 4;
+
+	int flags;                   /* Uncompression flags. */
+	int method;                  /* Uncompression algorithm method. */
+	int version;                 /* Uncompression algorithm version. */
+	ssize_t window_size;         /* Size of window_buf. */
+	uint8_t* window_buf;         /* Circular buffer used during
+	                                decompression. */
+	uint8_t* filtered_buf;       /* Buffer used when applying filters. */
+	const uint8_t* block_buf;    /* Buffer used when merging blocks. */
+	size_t window_mask;          /* Convenience field; window_size - 1. */
+	int64_t write_ptr;           /* This amount of data has been unpacked
+					in the window buffer. */
+	int64_t last_write_ptr;      /* This amount of data has been stored in
+	                                the output file. */
+	int64_t last_unstore_ptr;    /* Counter of bytes extracted during
+	                                unstoring. This is separate from
+	                                last_write_ptr because of how SERVICE
+	                                base blocks are handled during skipping
+	                                in solid multiarchive archives. */
+	int64_t solid_offset;        /* Additional offset inside the window
+	                                buffer, used in unpacking solid
+	                                archives. */
+	ssize_t cur_block_size;      /* Size of current data block. */
+	int last_len;                /* Flag used in lzss decompression. */
+
+	/* Decode tables used during lzss uncompression. */
+
+#define HUFF_BC 20
+	struct decode_table bd;      /* huffman bit lengths */
+#define HUFF_NC 306
+	struct decode_table ld;      /* literals */
+#define HUFF_DC 64
+	struct decode_table dd;      /* distances */
+#define HUFF_LDC 16
+	struct decode_table ldd;     /* lower bits of distances */
+#define HUFF_RC 44
+	struct decode_table rd;      /* repeating distances */
+#define HUFF_TABLE_SIZE (HUFF_NC + HUFF_DC + HUFF_RC + HUFF_LDC)
+
+	/* Circular deque for storing filters. */
+	struct cdeque filters;
+	int64_t last_block_start;    /* Used for sanity checking. */
+	ssize_t last_block_length;   /* Used for sanity checking. */
+
+	/* Distance cache used during lzss uncompression. */
+	int dist_cache[4];
+
+	/* Data buffer stack. */
+	struct data_ready dready[2];
+};
+
+/* Bit reader state. */
+struct bit_reader {
+	int8_t bit_addr;    /* Current bit pointer inside current byte. */
+	int in_addr;        /* Current byte pointer. */
+};
+
+/* RARv5 block header structure. Use bf_* functions to get values from
+ * block_flags_u8 field. I.e. bf_byte_count, etc. */
+struct compressed_block_header {
+	/* block_flags_u8 contain fields encoded in little-endian bitfield:
+	 *
+	 * - table present flag (shr 7, and 1),
+	 * - last block flag    (shr 6, and 1),
+	 * - byte_count         (shr 3, and 7),
+	 * - bit_size           (shr 0, and 7).
+	 */
+	uint8_t block_flags_u8;
+	uint8_t block_cksum;
+};
+
+/* RARv5 main header structure. */
+struct main_header {
+	/* Does the archive contain solid streams? */
+	uint8_t solid : 1;
+
+	/* If this a multi-file archive? */
+	uint8_t volume : 1;
+	uint8_t endarc : 1;
+	uint8_t notused : 5;
+
+	unsigned int vol_no;
+};
+
+struct generic_header {
+	uint8_t split_after : 1;
+	uint8_t split_before : 1;
+	uint8_t padding : 6;
+	int size;
+	int last_header_id;
+};
+
+struct multivolume {
+	unsigned int expected_vol_no;
+	uint8_t* push_buf;
+};
+
+/* Main context structure. */
+struct rar5 {
+	int header_initialized;
+
+	/* Set to 1 if current file is positioned AFTER the magic value
+	 * of the archive file. This is used in header reading functions. */
+	int skipped_magic;
+
+	/* Set to not zero if we're in skip mode (either by calling
+	 * rar5_data_skip function or when skipping over solid streams).
+	 * Set to 0 when in * extraction mode. This is used during checksum
+	 * calculation functions. */
+	int skip_mode;
+
+	/* Set to not zero if we're in block merging mode (i.e. when switching
+	 * to another file in multivolume archive, last block from 1st archive
+	 * needs to be merged with 1st block from 2nd archive). This flag
+	 * guards against recursive use of the merging function, which doesn't
+	 * support recursive calls. */
+	int merge_mode;
+
+	/* An offset to QuickOpen list. This is not supported by this unpacker,
+	 * because we're focusing on streaming interface. QuickOpen is designed
+	 * to make things quicker for non-stream interfaces, so it's not our
+	 * use case. */
+	uint64_t qlist_offset;
+
+	/* An offset to additional Recovery data. This is not supported by this
+	 * unpacker. Recovery data are additional Reed-Solomon codes that could
+	 * be used to calculate bytes that are missing in archive or are
+	 * corrupted. */
+	uint64_t rr_offset;
+
+	/* Various context variables grouped to different structures. */
+	struct generic_header generic;
+	struct main_header main;
+	struct comp_state cstate;
+	struct file_header file;
+	struct bit_reader bits;
+	struct multivolume vol;
+
+	/* The header of currently processed RARv5 block. Used in main
+	 * decompression logic loop. */
+	struct compressed_block_header last_block_hdr;
+};
+
+/* Forward function declarations. */
+
+static void rar5_signature(char *buf);
+static int verify_global_checksums(struct archive_read* a);
+static int rar5_read_data_skip(struct archive_read *a);
+static int push_data_ready(struct archive_read* a, struct rar5* rar,
+	const uint8_t* buf, size_t size, int64_t offset);
+
+/* CDE_xxx = Circular Double Ended (Queue) return values. */
+enum CDE_RETURN_VALUES {
+	CDE_OK, CDE_ALLOC, CDE_PARAM, CDE_OUT_OF_BOUNDS,
+};
+
+/* Clears the contents of this circular deque. */
+static void cdeque_clear(struct cdeque* d) {
+	d->size = 0;
+	d->beg_pos = 0;
+	d->end_pos = 0;
+}
+
+/* Creates a new circular deque object. Capacity must be power of 2: 8, 16, 32,
+ * 64, 256, etc. When the user will add another item above current capacity,
+ * the circular deque will overwrite the oldest entry. */
+static int cdeque_init(struct cdeque* d, int max_capacity_power_of_2) {
+	if(d == NULL || max_capacity_power_of_2 == 0)
+		return CDE_PARAM;
+
+	d->cap_mask = max_capacity_power_of_2 - 1;
+	d->arr = NULL;
+
+	if((max_capacity_power_of_2 & d->cap_mask) != 0)
+		return CDE_PARAM;
+
+	cdeque_clear(d);
+	d->arr = malloc(sizeof(void*) * max_capacity_power_of_2);
+
+	return d->arr ? CDE_OK : CDE_ALLOC;
+}
+
+/* Return the current size (not capacity) of circular deque `d`. */
+static size_t cdeque_size(struct cdeque* d) {
+	return d->size;
+}
+
+/* Returns the first element of current circular deque. Note that this function
+ * doesn't perform any bounds checking. If you need bounds checking, use
+ * `cdeque_front()` function instead. */
+static void cdeque_front_fast(struct cdeque* d, void** value) {
+	*value = (void*) d->arr[d->beg_pos];
+}
+
+/* Returns the first element of current circular deque. This function
+ * performs bounds checking. */
+static int cdeque_front(struct cdeque* d, void** value) {
+	if(d->size > 0) {
+		cdeque_front_fast(d, value);
+		return CDE_OK;
+	} else
+		return CDE_OUT_OF_BOUNDS;
+}
+
+/* Pushes a new element into the end of this circular deque object. If current
+ * size will exceed capacity, the oldest element will be overwritten. */
+static int cdeque_push_back(struct cdeque* d, void* item) {
+	if(d == NULL)
+		return CDE_PARAM;
+
+	if(d->size == d->cap_mask + 1)
+		return CDE_OUT_OF_BOUNDS;
+
+	d->arr[d->end_pos] = (size_t) item;
+	d->end_pos = (d->end_pos + 1) & d->cap_mask;
+	d->size++;
+
+	return CDE_OK;
+}
+
+/* Pops a front element of this circular deque object and returns its value.
+ * This function doesn't perform any bounds checking. */
+static void cdeque_pop_front_fast(struct cdeque* d, void** value) {
+	*value = (void*) d->arr[d->beg_pos];
+	d->beg_pos = (d->beg_pos + 1) & d->cap_mask;
+	d->size--;
+}
+
+/* Pops a front element of this circular deque object and returns its value.
+ * This function performs bounds checking. */
+static int cdeque_pop_front(struct cdeque* d, void** value) {
+	if(!d || !value)
+		return CDE_PARAM;
+
+	if(d->size == 0)
+		return CDE_OUT_OF_BOUNDS;
+
+	cdeque_pop_front_fast(d, value);
+	return CDE_OK;
+}
+
+/* Convenience function to cast filter_info** to void **. */
+static void** cdeque_filter_p(struct filter_info** f) {
+	return (void**) (size_t) f;
+}
+
+/* Convenience function to cast filter_info* to void *. */
+static void* cdeque_filter(struct filter_info* f) {
+	return (void**) (size_t) f;
+}
+
+/* Destroys this circular deque object. Deallocates the memory of the
+ * collection buffer, but doesn't deallocate the memory of any pointer passed
+ * to this deque as a value. */
+static void cdeque_free(struct cdeque* d) {
+	if(!d)
+		return;
+
+	if(!d->arr)
+		return;
+
+	free(d->arr);
+
+	d->arr = NULL;
+	d->beg_pos = -1;
+	d->end_pos = -1;
+	d->cap_mask = 0;
+}
+
+static inline
+uint8_t bf_bit_size(const struct compressed_block_header* hdr) {
+	return hdr->block_flags_u8 & 7;
+}
+
+static inline
+uint8_t bf_byte_count(const struct compressed_block_header* hdr) {
+	return (hdr->block_flags_u8 >> 3) & 7;
+}
+
+static inline
+uint8_t bf_is_table_present(const struct compressed_block_header* hdr) {
+	return (hdr->block_flags_u8 >> 7) & 1;
+}
+
+static inline struct rar5* get_context(struct archive_read* a) {
+	return (struct rar5*) a->format->data;
+}
+
+/* Convenience functions used by filter implementations. */
+static void circular_memcpy(uint8_t* dst, uint8_t* window, const uint64_t mask,
+    int64_t start, int64_t end)
+{
+	if((start & mask) > (end & mask)) {
+		ssize_t len1 = mask + 1 - (start & mask);
+		ssize_t len2 = end & mask;
+
+		memcpy(dst, &window[start & mask], len1);
+		memcpy(dst + len1, window, len2);
+	} else {
+		memcpy(dst, &window[start & mask], (size_t) (end - start));
+	}
+}
+
+static uint32_t read_filter_data(struct rar5* rar, uint32_t offset) {
+	uint8_t linear_buf[4];
+	circular_memcpy(linear_buf, rar->cstate.window_buf,
+	    rar->cstate.window_mask, offset, offset + 4);
+	return archive_le32dec(linear_buf);
+}
+
+static void write_filter_data(struct rar5* rar, uint32_t offset,
+    uint32_t value)
+{
+	archive_le32enc(&rar->cstate.filtered_buf[offset], value);
+}
+
+/* Allocates a new filter descriptor and adds it to the filter array. */
+static struct filter_info* add_new_filter(struct rar5* rar) {
+	struct filter_info* f =
+		(struct filter_info*) calloc(1, sizeof(struct filter_info));
+
+	if(!f) {
+		return NULL;
+	}
+
+	cdeque_push_back(&rar->cstate.filters, cdeque_filter(f));
+	return f;
+}
+
+static int run_delta_filter(struct rar5* rar, struct filter_info* flt) {
+	int i;
+	ssize_t dest_pos, src_pos = 0;
+
+	for(i = 0; i < flt->channels; i++) {
+		uint8_t prev_byte = 0;
+		for(dest_pos = i;
+				dest_pos < flt->block_length;
+				dest_pos += flt->channels)
+		{
+			uint8_t byte;
+
+			byte = rar->cstate.window_buf[
+			    (rar->cstate.solid_offset + flt->block_start +
+			    src_pos) & rar->cstate.window_mask];
+
+			prev_byte -= byte;
+			rar->cstate.filtered_buf[dest_pos] = prev_byte;
+			src_pos++;
+		}
+	}
+
+	return ARCHIVE_OK;
+}
+
+static int run_e8e9_filter(struct rar5* rar, struct filter_info* flt,
+		int extended)
+{
+	const uint32_t file_size = 0x1000000;
+	ssize_t i;
+
+	circular_memcpy(rar->cstate.filtered_buf,
+	    rar->cstate.window_buf, rar->cstate.window_mask,
+	    rar->cstate.solid_offset + flt->block_start,
+	    rar->cstate.solid_offset + flt->block_start + flt->block_length);
+
+	for(i = 0; i < flt->block_length - 4;) {
+		uint8_t b = rar->cstate.window_buf[
+		    (rar->cstate.solid_offset + flt->block_start +
+		    i++) & rar->cstate.window_mask];
+
+		/*
+		 * 0xE8 = x86's call <relative_addr_uint32> (function call)
+		 * 0xE9 = x86's jmp <relative_addr_uint32> (unconditional jump)
+		 */
+		if(b == 0xE8 || (extended && b == 0xE9)) {
+
+			uint32_t addr;
+			uint32_t offset = (i + flt->block_start) % file_size;
+
+			addr = read_filter_data(rar,
+			    (uint32_t)(rar->cstate.solid_offset +
+			    flt->block_start + i) & rar->cstate.window_mask);
+
+			if(addr & 0x80000000) {
+				if(((addr + offset) & 0x80000000) == 0) {
+					write_filter_data(rar, (uint32_t)i,
+					    addr + file_size);
+				}
+			} else {
+				if((addr - file_size) & 0x80000000) {
+					uint32_t naddr = addr - offset;
+					write_filter_data(rar, (uint32_t)i,
+					    naddr);
+				}
+			}
+
+			i += 4;
+		}
+	}
+
+	return ARCHIVE_OK;
+}
+
+static int run_arm_filter(struct rar5* rar, struct filter_info* flt) {
+	ssize_t i = 0;
+	uint32_t offset;
+
+	circular_memcpy(rar->cstate.filtered_buf,
+	    rar->cstate.window_buf, rar->cstate.window_mask,
+	    rar->cstate.solid_offset + flt->block_start,
+	    rar->cstate.solid_offset + flt->block_start + flt->block_length);
+
+	for(i = 0; i < flt->block_length - 3; i += 4) {
+		uint8_t* b = &rar->cstate.window_buf[
+		    (rar->cstate.solid_offset +
+		    flt->block_start + i + 3) & rar->cstate.window_mask];
+
+		if(*b == 0xEB) {
+			/* 0xEB = ARM's BL (branch + link) instruction. */
+			offset = read_filter_data(rar,
+			    (rar->cstate.solid_offset + flt->block_start + i) &
+			     rar->cstate.window_mask) & 0x00ffffff;
+
+			offset -= (uint32_t) ((i + flt->block_start) / 4);
+			offset = (offset & 0x00ffffff) | 0xeb000000;
+			write_filter_data(rar, (uint32_t)i, offset);
+		}
+	}
+
+	return ARCHIVE_OK;
+}
+
+static int run_filter(struct archive_read* a, struct filter_info* flt) {
+	int ret;
+	struct rar5* rar = get_context(a);
+
+	free(rar->cstate.filtered_buf);
+
+	rar->cstate.filtered_buf = malloc(flt->block_length);
+	if(!rar->cstate.filtered_buf) {
+		archive_set_error(&a->archive, ENOMEM,
+		    "Can't allocate memory for filter data.");
+		return ARCHIVE_FATAL;
+	}
+
+	switch(flt->type) {
+		case FILTER_DELTA:
+			ret = run_delta_filter(rar, flt);
+			break;
+
+		case FILTER_E8:
+			/* fallthrough */
+		case FILTER_E8E9:
+			ret = run_e8e9_filter(rar, flt,
+			    flt->type == FILTER_E8E9);
+			break;
+
+		case FILTER_ARM:
+			ret = run_arm_filter(rar, flt);
+			break;
+
+		default:
+			archive_set_error(&a->archive,
+			    ARCHIVE_ERRNO_FILE_FORMAT,
+			    "Unsupported filter type: 0x%x", flt->type);
+			return ARCHIVE_FATAL;
+	}
+
+	if(ret != ARCHIVE_OK) {
+		/* Filter has failed. */
+		return ret;
+	}
+
+	if(ARCHIVE_OK != push_data_ready(a, rar, rar->cstate.filtered_buf,
+	    flt->block_length, rar->cstate.last_write_ptr))
+	{
+		archive_set_error(&a->archive, ARCHIVE_ERRNO_PROGRAMMER,
+		    "Stack overflow when submitting unpacked data");
+
+		return ARCHIVE_FATAL;
+	}
+
+	rar->cstate.last_write_ptr += flt->block_length;
+	return ARCHIVE_OK;
+}
+
+/* The `push_data` function submits the selected data range to the user.
+ * Next call of `use_data` will use the pointer, size and offset arguments
+ * that are specified here. These arguments are pushed to the FIFO stack here,
+ * and popped from the stack by the `use_data` function. */
+static void push_data(struct archive_read* a, struct rar5* rar,
+    const uint8_t* buf, int64_t idx_begin, int64_t idx_end)
+{
+	const uint64_t wmask = rar->cstate.window_mask;
+	const ssize_t solid_write_ptr = (rar->cstate.solid_offset +
+	    rar->cstate.last_write_ptr) & wmask;
+
+	idx_begin += rar->cstate.solid_offset;
+	idx_end += rar->cstate.solid_offset;
+
+	/* Check if our unpacked data is wrapped inside the window circular
+	 * buffer.  If it's not wrapped, it can be copied out by using
+	 * a single memcpy, but when it's wrapped, we need to copy the first
+	 * part with one memcpy, and the second part with another memcpy. */
+
+	if((idx_begin & wmask) > (idx_end & wmask)) {
+		/* The data is wrapped (begin offset sis bigger than end
+		 * offset). */
+		const ssize_t frag1_size = rar->cstate.window_size -
+		    (idx_begin & wmask);
+		const ssize_t frag2_size = idx_end & wmask;
+
+		/* Copy the first part of the buffer first. */
+		push_data_ready(a, rar, buf + solid_write_ptr, frag1_size,
+		    rar->cstate.last_write_ptr);
+
+		/* Copy the second part of the buffer. */
+		push_data_ready(a, rar, buf, frag2_size,
+		    rar->cstate.last_write_ptr + frag1_size);
+
+		rar->cstate.last_write_ptr += frag1_size + frag2_size;
+	} else {
+		/* Data is not wrapped, so we can just use one call to copy the
+		 * data. */
+		push_data_ready(a, rar,
+		    buf + solid_write_ptr, (idx_end - idx_begin) & wmask,
+		    rar->cstate.last_write_ptr);
+
+		rar->cstate.last_write_ptr += idx_end - idx_begin;
+	}
+}
+
+/* Convenience function that submits the data to the user. It uses the
+ * unpack window buffer as a source location. */
+static void push_window_data(struct archive_read* a, struct rar5* rar,
+    int64_t idx_begin, int64_t idx_end)
+{
+	push_data(a, rar, rar->cstate.window_buf, idx_begin, idx_end);
+}
+
+static int apply_filters(struct archive_read* a) {
+	struct filter_info* flt;
+	struct rar5* rar = get_context(a);
+	int ret;
+
+	rar->cstate.all_filters_applied = 0;
+
+	/* Get the first filter that can be applied to our data. The data
+	 * needs to be fully unpacked before the filter can be run. */
+	if(CDE_OK == cdeque_front(&rar->cstate.filters,
+	    cdeque_filter_p(&flt))) {
+		/* Check if our unpacked data fully covers this filter's
+		 * range. */
+		if(rar->cstate.write_ptr > flt->block_start &&
+		    rar->cstate.write_ptr >= flt->block_start +
+		    flt->block_length) {
+			/* Check if we have some data pending to be written
+			 * right before the filter's start offset. */
+			if(rar->cstate.last_write_ptr == flt->block_start) {
+				/* Run the filter specified by descriptor
+				 * `flt`. */
+				ret = run_filter(a, flt);
+				if(ret != ARCHIVE_OK) {
+					/* Filter failure, return error. */
+					return ret;
+				}
+
+				/* Filter descriptor won't be needed anymore
+				 * after it's used, * so remove it from the
+				 * filter list and free its memory. */
+				(void) cdeque_pop_front(&rar->cstate.filters,
+				    cdeque_filter_p(&flt));
+
+				free(flt);
+			} else {
+				/* We can't run filters yet, dump the memory
+				 * right before the filter. */
+				push_window_data(a, rar,
+				    rar->cstate.last_write_ptr,
+				    flt->block_start);
+			}
+
+			/* Return 'filter applied or not needed' state to the
+			 * caller. */
+			return ARCHIVE_RETRY;
+		}
+	}
+
+	rar->cstate.all_filters_applied = 1;
+	return ARCHIVE_OK;
+}
+
+static void dist_cache_push(struct rar5* rar, int value) {
+	int* q = rar->cstate.dist_cache;
+
+	q[3] = q[2];
+	q[2] = q[1];
+	q[1] = q[0];
+	q[0] = value;
+}
+
+static int dist_cache_touch(struct rar5* rar, int idx) {
+	int* q = rar->cstate.dist_cache;
+	int i, dist = q[idx];
+
+	for(i = idx; i > 0; i--)
+		q[i] = q[i - 1];
+
+	q[0] = dist;
+	return dist;
+}
+
+static void free_filters(struct rar5* rar) {
+	struct cdeque* d = &rar->cstate.filters;
+
+	/* Free any remaining filters. All filters should be naturally
+	 * consumed by the unpacking function, so remaining filters after
+	 * unpacking normally mean that unpacking wasn't successful.
+	 * But still of course we shouldn't leak memory in such case. */
+
+	/* cdeque_size() is a fast operation, so we can use it as a loop
+	 * expression. */
+	while(cdeque_size(d) > 0) {
+		struct filter_info* f = NULL;
+
+		/* Pop_front will also decrease the collection's size. */
+		if (CDE_OK == cdeque_pop_front(d, cdeque_filter_p(&f)))
+			free(f);
+	}
+
+	cdeque_clear(d);
+
+	/* Also clear out the variables needed for sanity checking. */
+	rar->cstate.last_block_start = 0;
+	rar->cstate.last_block_length = 0;
+}
+
+static void reset_file_context(struct rar5* rar) {
+	memset(&rar->file, 0, sizeof(rar->file));
+	blake2sp_init(&rar->file.b2state, 32);
+
+	if(rar->main.solid) {
+		rar->cstate.solid_offset += rar->cstate.write_ptr;
+	} else {
+		rar->cstate.solid_offset = 0;
+	}
+
+	rar->cstate.write_ptr = 0;
+	rar->cstate.last_write_ptr = 0;
+	rar->cstate.last_unstore_ptr = 0;
+
+	rar->file.redir_type = REDIR_TYPE_NONE;
+	rar->file.redir_flags = 0;
+
+	free_filters(rar);
+}
+
+static inline int get_archive_read(struct archive* a,
+    struct archive_read** ar)
+{
+	*ar = (struct archive_read*) a;
+	archive_check_magic(a, ARCHIVE_READ_MAGIC, ARCHIVE_STATE_NEW,
+	    "archive_read_support_format_rar5");
+
+	return ARCHIVE_OK;
+}
+
+static int read_ahead(struct archive_read* a, size_t how_many,
+    const uint8_t** ptr)
+{
+	ssize_t avail = -1;
+	if(!ptr)
+		return 0;
+
+	*ptr = __archive_read_ahead(a, how_many, &avail);
+	if(*ptr == NULL) {
+		return 0;
+	}
+
+	return 1;
+}
+
+static int consume(struct archive_read* a, int64_t how_many) {
+	int ret;
+
+	ret = how_many == __archive_read_consume(a, how_many)
+		? ARCHIVE_OK
+		: ARCHIVE_FATAL;
+
+	return ret;
+}
+
+/**
+ * Read a RAR5 variable sized numeric value. This value will be stored in
+ * `pvalue`. The `pvalue_len` argument points to a variable that will receive
+ * the byte count that was consumed in order to decode the `pvalue` value, plus
+ * one.
+ *
+ * pvalue_len is optional and can be NULL.
+ *
+ * NOTE: if `pvalue_len` is NOT NULL, the caller needs to manually consume
+ * the number of bytes that `pvalue_len` value contains. If the `pvalue_len`
+ * is NULL, this consuming operation is done automatically.
+ *
+ * Returns 1 if *pvalue was successfully read.
+ * Returns 0 if there was an error. In this case, *pvalue contains an
+ *           invalid value.
+ */
+
+static int read_var(struct archive_read* a, uint64_t* pvalue,
+    uint64_t* pvalue_len)
+{
+	uint64_t result = 0;
+	size_t shift, i;
+	const uint8_t* p;
+	uint8_t b;
+
+	/* We will read maximum of 8 bytes. We don't have to handle the
+	 * situation to read the RAR5 variable-sized value stored at the end of
+	 * the file, because such situation will never happen. */
+	if(!read_ahead(a, 8, &p))
+		return 0;
+
+	for(shift = 0, i = 0; i < 8; i++, shift += 7) {
+		b = p[i];
+
+		/* Strip the MSB from the input byte and add the resulting
+		 * number to the `result`. */
+		result += (b & (uint64_t)0x7F) << shift;
+
+		/* MSB set to 1 means we need to continue decoding process.
+		 * MSB set to 0 means we're done.
+		 *
+		 * This conditional checks for the second case. */
+		if((b & 0x80) == 0) {
+			if(pvalue) {
+				*pvalue = result;
+			}
+
+			/* If the caller has passed the `pvalue_len` pointer,
+			 * store the number of consumed bytes in it and do NOT
+			 * consume those bytes, since the caller has all the
+			 * information it needs to perform */
+			if(pvalue_len) {
+				*pvalue_len = 1 + i;
+			} else {
+				/* If the caller did not provide the
+				 * `pvalue_len` pointer, it will not have the
+				 * possibility to advance the file pointer,
+				 * because it will not know how many bytes it
+				 * needs to consume. This is why we handle
+				 * such situation here automatically. */
+				if(ARCHIVE_OK != consume(a, 1 + i)) {
+					return 0;
+				}
+			}
+
+			/* End of decoding process, return success. */
+			return 1;
+		}
+	}
+
+	/* The decoded value takes the maximum number of 8 bytes.
+	 * It's a maximum number of bytes, so end decoding process here
+	 * even if the first bit of last byte is 1. */
+	if(pvalue) {
+		*pvalue = result;
+	}
+
+	if(pvalue_len) {
+		*pvalue_len = 9;
+	} else {
+		if(ARCHIVE_OK != consume(a, 9)) {
+			return 0;
+		}
+	}
+
+	return 1;
+}
+
+static int read_var_sized(struct archive_read* a, size_t* pvalue,
+    size_t* pvalue_len)
+{
+	uint64_t v;
+	uint64_t v_size = 0;
+
+	const int ret = pvalue_len ? read_var(a, &v, &v_size)
+				   : read_var(a, &v, NULL);
+
+	if(ret == 1 && pvalue) {
+		*pvalue = (size_t) v;
+	}
+
+	if(pvalue_len) {
+		/* Possible data truncation should be safe. */
+		*pvalue_len = (size_t) v_size;
+	}
+
+	return ret;
+}
+
+static int read_bits_32(struct rar5* rar, const uint8_t* p, uint32_t* value) {
+	uint32_t bits = ((uint32_t) p[rar->bits.in_addr]) << 24;
+	bits |= p[rar->bits.in_addr + 1] << 16;
+	bits |= p[rar->bits.in_addr + 2] << 8;
+	bits |= p[rar->bits.in_addr + 3];
+	bits <<= rar->bits.bit_addr;
+	bits |= p[rar->bits.in_addr + 4] >> (8 - rar->bits.bit_addr);
+	*value = bits;
+	return ARCHIVE_OK;
+}
+
+static int read_bits_16(struct rar5* rar, const uint8_t* p, uint16_t* value) {
+	int bits = (int) ((uint32_t) p[rar->bits.in_addr]) << 16;
+	bits |= (int) p[rar->bits.in_addr + 1] << 8;
+	bits |= (int) p[rar->bits.in_addr + 2];
+	bits >>= (8 - rar->bits.bit_addr);
+	*value = bits & 0xffff;
+	return ARCHIVE_OK;
+}
+
+static void skip_bits(struct rar5* rar, int bits) {
+	const int new_bits = rar->bits.bit_addr + bits;
+	rar->bits.in_addr += new_bits >> 3;
+	rar->bits.bit_addr = new_bits & 7;
+}
+
+/* n = up to 16 */
+static int read_consume_bits(struct rar5* rar, const uint8_t* p, int n,
+    int* value)
+{
+	uint16_t v;
+	int ret, num;
+
+	if(n == 0 || n > 16) {
+		/* This is a programmer error and should never happen
+		 * in runtime. */
+		return ARCHIVE_FATAL;
+	}
+
+	ret = read_bits_16(rar, p, &v);
+	if(ret != ARCHIVE_OK)
+		return ret;
+
+	num = (int) v;
+	num >>= 16 - n;
+
+	skip_bits(rar, n);
+
+	if(value)
+		*value = num;
+
+	return ARCHIVE_OK;
+}
+
+static int read_u32(struct archive_read* a, uint32_t* pvalue) {
+	const uint8_t* p;
+	if(!read_ahead(a, 4, &p))
+		return 0;
+
+	*pvalue = archive_le32dec(p);
+	return ARCHIVE_OK == consume(a, 4) ? 1 : 0;
+}
+
+static int read_u64(struct archive_read* a, uint64_t* pvalue) {
+	const uint8_t* p;
+	if(!read_ahead(a, 8, &p))
+		return 0;
+
+	*pvalue = archive_le64dec(p);
+	return ARCHIVE_OK == consume(a, 8) ? 1 : 0;
+}
+
+static int bid_standard(struct archive_read* a) {
+	const uint8_t* p;
+	char signature[sizeof(rar5_signature_xor)];
+
+	rar5_signature(signature);
+
+	if(!read_ahead(a, sizeof(rar5_signature_xor), &p))
+		return -1;
+
+	if(!memcmp(signature, p, sizeof(rar5_signature_xor)))
+		return 30;
+
+	return -1;
+}
+
+static int rar5_bid(struct archive_read* a, int best_bid) {
+	int my_bid;
+
+	if(best_bid > 30)
+		return -1;
+
+	my_bid = bid_standard(a);
+	if(my_bid > -1) {
+		return my_bid;
+	}
+
+	return -1;
+}
+
+static int rar5_options(struct archive_read *a, const char *key,
+    const char *val) {
+	(void) a;
+	(void) key;
+	(void) val;
+
+	/* No options supported in this version. Return the ARCHIVE_WARN code
+	 * to signal the options supervisor that the unpacker didn't handle
+	 * setting this option. */
+
+	return ARCHIVE_WARN;
+}
+
+static void init_header(struct archive_read* a) {
+	a->archive.archive_format = ARCHIVE_FORMAT_RAR_V5;
+	a->archive.archive_format_name = "RAR5";
+}
+
+static void init_window_mask(struct rar5* rar) {
+	if (rar->cstate.window_size)
+		rar->cstate.window_mask = rar->cstate.window_size - 1;
+	else
+		rar->cstate.window_mask = 0;
+}
+
+enum HEADER_FLAGS {
+	HFL_EXTRA_DATA = 0x0001,
+	HFL_DATA = 0x0002,
+	HFL_SKIP_IF_UNKNOWN = 0x0004,
+	HFL_SPLIT_BEFORE = 0x0008,
+	HFL_SPLIT_AFTER = 0x0010,
+	HFL_CHILD = 0x0020,
+	HFL_INHERITED = 0x0040
+};
+
+static int process_main_locator_extra_block(struct archive_read* a,
+    struct rar5* rar)
+{
+	uint64_t locator_flags;
+
+	enum LOCATOR_FLAGS {
+		QLIST = 0x01, RECOVERY = 0x02,
+	};
+
+	if(!read_var(a, &locator_flags, NULL)) {
+		return ARCHIVE_EOF;
+	}
+
+	if(locator_flags & QLIST) {
+		if(!read_var(a, &rar->qlist_offset, NULL)) {
+			return ARCHIVE_EOF;
+		}
+
+		/* qlist is not used */
+	}
+
+	if(locator_flags & RECOVERY) {
+		if(!read_var(a, &rar->rr_offset, NULL)) {
+			return ARCHIVE_EOF;
+		}
+
+		/* rr is not used */
+	}
+
+	return ARCHIVE_OK;
+}
+
+static int parse_file_extra_hash(struct archive_read* a, struct rar5* rar,
+    ssize_t* extra_data_size)
+{
+	size_t hash_type = 0;
+	size_t value_len;
+
+	enum HASH_TYPE {
+		BLAKE2sp = 0x00
+	};
+
+	if(!read_var_sized(a, &hash_type, &value_len))
+		return ARCHIVE_EOF;
+
+	*extra_data_size -= value_len;
+	if(ARCHIVE_OK != consume(a, value_len)) {
+		return ARCHIVE_EOF;
+	}
+
+	/* The file uses BLAKE2sp checksum algorithm instead of plain old
+	 * CRC32. */
+	if(hash_type == BLAKE2sp) {
+		const uint8_t* p;
+		const int hash_size = sizeof(rar->file.blake2sp);
+
+		if(!read_ahead(a, hash_size, &p))
+			return ARCHIVE_EOF;
+
+		rar->file.has_blake2 = 1;
+		memcpy(&rar->file.blake2sp, p, hash_size);
+
+		if(ARCHIVE_OK != consume(a, hash_size)) {
+			return ARCHIVE_EOF;
+		}
+
+		*extra_data_size -= hash_size;
+	} else {
+		archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+		    "Unsupported hash type (0x%x)", (int) hash_type);
+		return ARCHIVE_FATAL;
+	}
+
+	return ARCHIVE_OK;
+}
+
+static uint64_t time_win_to_unix(uint64_t win_time) {
+	const size_t ns_in_sec = 10000000;
+	const uint64_t sec_to_unix = 11644473600LL;
+	return win_time / ns_in_sec - sec_to_unix;
+}
+
+static int parse_htime_item(struct archive_read* a, char unix_time,
+    uint64_t* where, ssize_t* extra_data_size)
+{
+	if(unix_time) {
+		uint32_t time_val;
+		if(!read_u32(a, &time_val))
+			return ARCHIVE_EOF;
+
+		*extra_data_size -= 4;
+		*where = (uint64_t) time_val;
+	} else {
+		uint64_t windows_time;
+		if(!read_u64(a, &windows_time))
+			return ARCHIVE_EOF;
+
+		*where = time_win_to_unix(windows_time);
+		*extra_data_size -= 8;
+	}
+
+	return ARCHIVE_OK;
+}
+
+static int parse_file_extra_version(struct archive_read* a,
+    struct archive_entry* e, ssize_t* extra_data_size)
+{
+	size_t flags = 0;
+	size_t version = 0;
+	size_t value_len = 0;
+	struct archive_string version_string;
+	struct archive_string name_utf8_string;
+	const char* cur_filename;
+
+	/* Flags are ignored. */
+	if(!read_var_sized(a, &flags, &value_len))
+		return ARCHIVE_EOF;
+
+	*extra_data_size -= value_len;
+	if(ARCHIVE_OK != consume(a, value_len))
+		return ARCHIVE_EOF;
+
+	if(!read_var_sized(a, &version, &value_len))
+		return ARCHIVE_EOF;
+
+	*extra_data_size -= value_len;
+	if(ARCHIVE_OK != consume(a, value_len))
+		return ARCHIVE_EOF;
+
+	/* extra_data_size should be zero here. */
+
+	cur_filename = archive_entry_pathname_utf8(e);
+	if(cur_filename == NULL) {
+		archive_set_error(&a->archive, ARCHIVE_ERRNO_PROGRAMMER,
+		    "Version entry without file name");
+		return ARCHIVE_FATAL;
+	}
+
+	archive_string_init(&version_string);
+	archive_string_init(&name_utf8_string);
+
+	/* Prepare a ;123 suffix for the filename, where '123' is the version
+	 * value of this file. */
+	archive_string_sprintf(&version_string, ";%zu", version);
+
+	/* Build the new filename. */
+	archive_strcat(&name_utf8_string, cur_filename);
+	archive_strcat(&name_utf8_string, version_string.s);
+
+	/* Apply the new filename into this file's context. */
+	archive_entry_update_pathname_utf8(e, name_utf8_string.s);
+
+	/* Free buffers. */
+	archive_string_free(&version_string);
+	archive_string_free(&name_utf8_string);
+	return ARCHIVE_OK;
+}
+
+static int parse_file_extra_htime(struct archive_read* a,
+    struct archive_entry* e, struct rar5* rar, ssize_t* extra_data_size)
+{
+	char unix_time = 0;
+	size_t flags = 0;
+	size_t value_len;
+
+	enum HTIME_FLAGS {
+		IS_UNIX       = 0x01,
+		HAS_MTIME     = 0x02,
+		HAS_CTIME     = 0x04,
+		HAS_ATIME     = 0x08,
+		HAS_UNIX_NS   = 0x10,
+	};
+
+	if(!read_var_sized(a, &flags, &value_len))
+		return ARCHIVE_EOF;
+
+	*extra_data_size -= value_len;
+	if(ARCHIVE_OK != consume(a, value_len)) {
+		return ARCHIVE_EOF;
+	}
+
+	unix_time = flags & IS_UNIX;
+
+	if(flags & HAS_MTIME) {
+		parse_htime_item(a, unix_time, &rar->file.e_mtime,
+		    extra_data_size);
+		archive_entry_set_mtime(e, rar->file.e_mtime, 0);
+	}
+
+	if(flags & HAS_CTIME) {
+		parse_htime_item(a, unix_time, &rar->file.e_ctime,
+		    extra_data_size);
+		archive_entry_set_ctime(e, rar->file.e_ctime, 0);
+	}
+
+	if(flags & HAS_ATIME) {
+		parse_htime_item(a, unix_time, &rar->file.e_atime,
+		    extra_data_size);
+		archive_entry_set_atime(e, rar->file.e_atime, 0);
+	}
+
+	if(flags & HAS_UNIX_NS) {
+		if(!read_u32(a, &rar->file.e_unix_ns))
+			return ARCHIVE_EOF;
+
+		*extra_data_size -= 4;
+	}
+
+	return ARCHIVE_OK;
+}
+
+static int parse_file_extra_redir(struct archive_read* a,
+    struct archive_entry* e, struct rar5* rar, ssize_t* extra_data_size)
+{
+	uint64_t value_size = 0;
+	size_t target_size = 0;
+	char target_utf8_buf[MAX_NAME_IN_BYTES];
+	const uint8_t* p;
+
+	if(!read_var(a, &rar->file.redir_type, &value_size))
+		return ARCHIVE_EOF;
+	if(ARCHIVE_OK != consume(a, (int64_t)value_size))
+		return ARCHIVE_EOF;
+	*extra_data_size -= value_size;
+
+	if(!read_var(a, &rar->file.redir_flags, &value_size))
+		return ARCHIVE_EOF;
+	if(ARCHIVE_OK != consume(a, (int64_t)value_size))
+		return ARCHIVE_EOF;
+	*extra_data_size -= value_size;
+
+	if(!read_var_sized(a, &target_size, NULL))
+		return ARCHIVE_EOF;
+	*extra_data_size -= target_size + 1;
+
+	if(!read_ahead(a, target_size, &p))
+		return ARCHIVE_EOF;
+
+	if(target_size > (MAX_NAME_IN_CHARS - 1)) {
+		archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+		    "Link target is too long");
+		return ARCHIVE_FATAL;
+	}
+
+	if(target_size == 0) {
+		archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+		    "No link target specified");
+		return ARCHIVE_FATAL;
+	}
+
+	memcpy(target_utf8_buf, p, target_size);
+	target_utf8_buf[target_size] = 0;
+
+	if(ARCHIVE_OK != consume(a, (int64_t)target_size))
+		return ARCHIVE_EOF;
+
+	switch(rar->file.redir_type) {
+		case REDIR_TYPE_UNIXSYMLINK:
+		case REDIR_TYPE_WINSYMLINK:
+			archive_entry_set_filetype(e, AE_IFLNK);
+			archive_entry_update_symlink_utf8(e, target_utf8_buf);
+			if (rar->file.redir_flags & REDIR_SYMLINK_IS_DIR) {
+				archive_entry_set_symlink_type(e,
+					AE_SYMLINK_TYPE_DIRECTORY);
+			} else {
+				archive_entry_set_symlink_type(e,
+				AE_SYMLINK_TYPE_FILE);
+			}
+			break;
+
+		case REDIR_TYPE_HARDLINK:
+			archive_entry_set_filetype(e, AE_IFREG);
+			archive_entry_update_hardlink_utf8(e, target_utf8_buf);
+			break;
+
+		default:
+			/* Unknown redir type, skip it. */
+			break;
+	}
+	return ARCHIVE_OK;
+}
+
+static int parse_file_extra_owner(struct archive_read* a,
+    struct archive_entry* e, ssize_t* extra_data_size)
+{
+	uint64_t flags = 0;
+	uint64_t value_size = 0;
+	uint64_t id = 0;
+	size_t name_len = 0;
+	size_t name_size = 0;
+	char namebuf[OWNER_MAXNAMELEN];
+	const uint8_t* p;
+
+	if(!read_var(a, &flags, &value_size))
+		return ARCHIVE_EOF;
+	if(ARCHIVE_OK != consume(a, (int64_t)value_size))
+		return ARCHIVE_EOF;
+	*extra_data_size -= value_size;
+
+	if ((flags & OWNER_USER_NAME) != 0) {
+		if(!read_var_sized(a, &name_size, NULL))
+			return ARCHIVE_EOF;
+		*extra_data_size -= name_size + 1;
+
+		if(!read_ahead(a, name_size, &p))
+			return ARCHIVE_EOF;
+
+		if (name_size >= OWNER_MAXNAMELEN) {
+			name_len = OWNER_MAXNAMELEN - 1;
+		} else {
+			name_len = name_size;
+		}
+
+		memcpy(namebuf, p, name_len);
+		namebuf[name_len] = 0;
+		if(ARCHIVE_OK != consume(a, (int64_t)name_size))
+			return ARCHIVE_EOF;
+
+		archive_entry_set_uname(e, namebuf);
+	}
+	if ((flags & OWNER_GROUP_NAME) != 0) {
+		if(!read_var_sized(a, &name_size, NULL))
+			return ARCHIVE_EOF;
+		*extra_data_size -= name_size + 1;
+
+		if(!read_ahead(a, name_size, &p))
+			return ARCHIVE_EOF;
+
+		if (name_size >= OWNER_MAXNAMELEN) {
+			name_len = OWNER_MAXNAMELEN - 1;
+		} else {
+			name_len = name_size;
+		}
+
+		memcpy(namebuf, p, name_len);
+		namebuf[name_len] = 0;
+		if(ARCHIVE_OK != consume(a, (int64_t)name_size))
+			return ARCHIVE_EOF;
+
+		archive_entry_set_gname(e, namebuf);
+	}
+	if ((flags & OWNER_USER_UID) != 0) {
+		if(!read_var(a, &id, &value_size))
+			return ARCHIVE_EOF;
+		if(ARCHIVE_OK != consume(a, (int64_t)value_size))
+			return ARCHIVE_EOF;
+		*extra_data_size -= value_size;
+
+		archive_entry_set_uid(e, (la_int64_t)id);
+	}
+	if ((flags & OWNER_GROUP_GID) != 0) {
+		if(!read_var(a, &id, &value_size))
+			return ARCHIVE_EOF;
+		if(ARCHIVE_OK != consume(a, (int64_t)value_size))
+			return ARCHIVE_EOF;
+		*extra_data_size -= value_size;
+
+		archive_entry_set_gid(e, (la_int64_t)id);
+	}
+	return ARCHIVE_OK;
+}
+
+static int process_head_file_extra(struct archive_read* a,
+    struct archive_entry* e, struct rar5* rar, ssize_t extra_data_size)
+{
+	size_t extra_field_size;
+	size_t extra_field_id = 0;
+	int ret = ARCHIVE_FATAL;
+	size_t var_size;
+
+	while(extra_data_size > 0) {
+		if(!read_var_sized(a, &extra_field_size, &var_size))
+			return ARCHIVE_EOF;
+
+		extra_data_size -= var_size;
+		if(ARCHIVE_OK != consume(a, var_size)) {
+			return ARCHIVE_EOF;
+		}
+
+		if(!read_var_sized(a, &extra_field_id, &var_size))
+			return ARCHIVE_EOF;
+
+		extra_data_size -= var_size;
+		if(ARCHIVE_OK != consume(a, var_size)) {
+			return ARCHIVE_EOF;
+		}
+
+		switch(extra_field_id) {
+			case EX_HASH:
+				ret = parse_file_extra_hash(a, rar,
+				    &extra_data_size);
+				break;
+			case EX_HTIME:
+				ret = parse_file_extra_htime(a, e, rar,
+				    &extra_data_size);
+				break;
+			case EX_REDIR:
+				ret = parse_file_extra_redir(a, e, rar,
+				    &extra_data_size);
+				break;
+			case EX_UOWNER:
+				ret = parse_file_extra_owner(a, e,
+				    &extra_data_size);
+				break;
+			case EX_VERSION:
+				ret = parse_file_extra_version(a, e,
+				    &extra_data_size);
+				break;
+			case EX_CRYPT:
+				/* fallthrough */
+			case EX_SUBDATA:
+				/* fallthrough */
+			default:
+				/* Skip unsupported entry. */
+				return consume(a, extra_data_size);
+		}
+	}
+
+	if(ret != ARCHIVE_OK) {
+		/* Attribute not implemented. */
+		return ret;
+	}
+
+	return ARCHIVE_OK;
+}
+
+static int process_head_file(struct archive_read* a, struct rar5* rar,
+    struct archive_entry* entry, size_t block_flags)
+{
+	ssize_t extra_data_size = 0;
+	size_t data_size = 0;
+	size_t file_flags = 0;
+	size_t file_attr = 0;
+	size_t compression_info = 0;
+	size_t host_os = 0;
+	size_t name_size = 0;
+	uint64_t unpacked_size, window_size;
+	uint32_t mtime = 0, crc = 0;
+	int c_method = 0, c_version = 0;
+	char name_utf8_buf[MAX_NAME_IN_BYTES];
+	const uint8_t* p;
+
+	enum FILE_FLAGS {
+		DIRECTORY = 0x0001, UTIME = 0x0002, CRC32 = 0x0004,
+		UNKNOWN_UNPACKED_SIZE = 0x0008,
+	};
+
+	enum FILE_ATTRS {
+		ATTR_READONLY = 0x1, ATTR_HIDDEN = 0x2, ATTR_SYSTEM = 0x4,
+		ATTR_DIRECTORY = 0x10,
+	};
+
+	enum COMP_INFO_FLAGS {
+		SOLID = 0x0040,
+	};
+
+	enum HOST_OS {
+		HOST_WINDOWS = 0,
+		HOST_UNIX = 1,
+	};
+
+	archive_entry_clear(entry);
+
+	/* Do not reset file context if we're switching archives. */
+	if(!rar->cstate.switch_multivolume) {
+		reset_file_context(rar);
+	}
+
+	if(block_flags & HFL_EXTRA_DATA) {
+		size_t edata_size = 0;
+		if(!read_var_sized(a, &edata_size, NULL))
+			return ARCHIVE_EOF;
+
+		/* Intentional type cast from unsigned to signed. */
+		extra_data_size = (ssize_t) edata_size;
+	}
+
+	if(block_flags & HFL_DATA) {
+		if(!read_var_sized(a, &data_size, NULL))
+			return ARCHIVE_EOF;
+
+		rar->file.bytes_remaining = data_size;
+	} else {
+		rar->file.bytes_remaining = 0;
+
+		archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+				"no data found in file/service block");
+		return ARCHIVE_FATAL;
+	}
+
+	if(!read_var_sized(a, &file_flags, NULL))
+		return ARCHIVE_EOF;
+
+	if(!read_var(a, &unpacked_size, NULL))
+		return ARCHIVE_EOF;
+
+	if(file_flags & UNKNOWN_UNPACKED_SIZE) {
+		archive_set_error(&a->archive, ARCHIVE_ERRNO_PROGRAMMER,
+		    "Files with unknown unpacked size are not supported");
+		return ARCHIVE_FATAL;
+	}
+
+	rar->file.dir = (uint8_t) ((file_flags & DIRECTORY) > 0);
+
+	if(!read_var_sized(a, &file_attr, NULL))
+		return ARCHIVE_EOF;
+
+	if(file_flags & UTIME) {
+		if(!read_u32(a, &mtime))
+			return ARCHIVE_EOF;
+	}
+
+	if(file_flags & CRC32) {
+		if(!read_u32(a, &crc))
+			return ARCHIVE_EOF;
+	}
+
+	if(!read_var_sized(a, &compression_info, NULL))
+		return ARCHIVE_EOF;
+
+	c_method = (int) (compression_info >> 7) & 0x7;
+	c_version = (int) (compression_info & 0x3f);
+
+	/* RAR5 seems to limit the dictionary size to 64MB. */
+	window_size = (rar->file.dir > 0) ?
+		0 :
+		g_unpack_window_size << ((compression_info >> 10) & 15);
+	rar->cstate.method = c_method;
+	rar->cstate.version = c_version + 50;
+	rar->file.solid = (compression_info & SOLID) > 0;
+
+	/* Archives which declare solid files without initializing the window
+	 * buffer first are invalid. */
+
+	if(rar->file.solid > 0 && rar->cstate.window_buf == NULL) {
+		archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+				  "Declared solid file, but no window buffer "
+				  "initialized yet.");
+		return ARCHIVE_FATAL;
+	}
+
+	/* Check if window_size is a sane value. Also, if the file is not
+	 * declared as a directory, disallow window_size == 0. */
+	if(window_size > (64 * 1024 * 1024) ||
+	    (rar->file.dir == 0 && window_size == 0))
+	{
+		archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+		    "Declared dictionary size is not supported.");
+		return ARCHIVE_FATAL;
+	}
+
+	if(rar->file.solid > 0) {
+		/* Re-check if current window size is the same as previous
+		 * window size (for solid files only). */
+		if(rar->file.solid_window_size > 0 &&
+		    rar->file.solid_window_size != (ssize_t) window_size)
+		{
+			archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+			    "Window size for this solid file doesn't match "
+			    "the window size used in previous solid file. ");
+			return ARCHIVE_FATAL;
+		}
+	}
+
+	/* If we're currently switching volumes, ignore the new definition of
+	 * window_size. */
+	if(rar->cstate.switch_multivolume == 0) {
+		/* Values up to 64M should fit into ssize_t on every
+		 * architecture. */
+		rar->cstate.window_size = (ssize_t) window_size;
+	}
+
+	if(rar->file.solid > 0 && rar->file.solid_window_size == 0) {
+		/* Solid files have to have the same window_size across
+		   whole archive. Remember the window_size parameter
+		   for first solid file found. */
+		rar->file.solid_window_size = rar->cstate.window_size;
+	}
+
+	init_window_mask(rar);
+
+	rar->file.service = 0;
+
+	if(!read_var_sized(a, &host_os, NULL))
+		return ARCHIVE_EOF;
+
+	if(host_os == HOST_WINDOWS) {
+		/* Host OS is Windows */
+
+		__LA_MODE_T mode;
+
+		if(file_attr & ATTR_DIRECTORY) {
+			if (file_attr & ATTR_READONLY) {
+				mode = 0555 | AE_IFDIR;
+			} else {
+				mode = 0755 | AE_IFDIR;
+			}
+		} else {
+			if (file_attr & ATTR_READONLY) {
+				mode = 0444 | AE_IFREG;
+			} else {
+				mode = 0644 | AE_IFREG;
+			}
+		}
+
+		archive_entry_set_mode(entry, mode);
+
+		if (file_attr & (ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM)) {
+			char *fflags_text, *ptr;
+			/* allocate for "rdonly,hidden,system," */
+			fflags_text = malloc(22 * sizeof(char));
+			if (fflags_text != NULL) {
+				ptr = fflags_text;
+				if (file_attr & ATTR_READONLY) {
+					strcpy(ptr, "rdonly,");
+					ptr = ptr + 7;
+				}
+				if (file_attr & ATTR_HIDDEN) {
+					strcpy(ptr, "hidden,");
+					ptr = ptr + 7;
+				}
+				if (file_attr & ATTR_SYSTEM) {
+					strcpy(ptr, "system,");
+					ptr = ptr + 7;
+				}
+				if (ptr > fflags_text) {
+					/* Delete trailing comma */
+					*(ptr - 1) = '\0';
+					archive_entry_copy_fflags_text(entry,
+					    fflags_text);
+				}
+				free(fflags_text);
+			}
+		}
+	} else if(host_os == HOST_UNIX) {
+		/* Host OS is Unix */
+		archive_entry_set_mode(entry, (__LA_MODE_T) file_attr);
+	} else {
+		/* Unknown host OS */
+		archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+				"Unsupported Host OS: 0x%x", (int) host_os);
+
+		return ARCHIVE_FATAL;
+	}
+
+	if(!read_var_sized(a, &name_size, NULL))
+		return ARCHIVE_EOF;
+
+	if(!read_ahead(a, name_size, &p))
+		return ARCHIVE_EOF;
+
+	if(name_size > (MAX_NAME_IN_CHARS - 1)) {
+		archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+				"Filename is too long");
+
+		return ARCHIVE_FATAL;
+	}
+
+	if(name_size == 0) {
+		archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+				"No filename specified");
+
+		return ARCHIVE_FATAL;
+	}
+
+	memcpy(name_utf8_buf, p, name_size);
+	name_utf8_buf[name_size] = 0;
+	if(ARCHIVE_OK != consume(a, name_size)) {
+		return ARCHIVE_EOF;
+	}
+
+	archive_entry_update_pathname_utf8(entry, name_utf8_buf);
+
+	if(extra_data_size > 0) {
+		int ret = process_head_file_extra(a, entry, rar,
+		    extra_data_size);
+
+		/*
+		 * TODO: rewrite or remove useless sanity check
+		 *       as extra_data_size is not passed as a pointer
+		 *
+		if(extra_data_size < 0) {
+			archive_set_error(&a->archive, ARCHIVE_ERRNO_PROGRAMMER,
+			    "File extra data size is not zero");
+			return ARCHIVE_FATAL;
+		}
+		 */
+
+		if(ret != ARCHIVE_OK)
+			return ret;
+	}
+
+	if((file_flags & UNKNOWN_UNPACKED_SIZE) == 0) {
+		rar->file.unpacked_size = (ssize_t) unpacked_size;
+		if(rar->file.redir_type == REDIR_TYPE_NONE)
+			archive_entry_set_size(entry, unpacked_size);
+	}
+
+	if(file_flags & UTIME) {
+		archive_entry_set_mtime(entry, (time_t) mtime, 0);
+	}
+
+	if(file_flags & CRC32) {
+		rar->file.stored_crc32 = crc;
+	}
+
+	if(!rar->cstate.switch_multivolume) {
+		/* Do not reinitialize unpacking state if we're switching
+		 * archives. */
+		rar->cstate.block_parsing_finished = 1;
+		rar->cstate.all_filters_applied = 1;
+		rar->cstate.initialized = 0;
+	}
+
+	if(rar->generic.split_before > 0) {
+		/* If now we're standing on a header that has a 'split before'
+		 * mark, it means we're standing on a 'continuation' file
+		 * header. Signal the caller that if it wants to move to
+		 * another file, it must call rar5_read_header() function
+		 * again. */
+
+		return ARCHIVE_RETRY;
+	} else {
+		return ARCHIVE_OK;
+	}
+}
+
+static int process_head_service(struct archive_read* a, struct rar5* rar,
+    struct archive_entry* entry, size_t block_flags)
+{
+	/* Process this SERVICE block the same way as FILE blocks. */
+	int ret = process_head_file(a, rar, entry, block_flags);
+	if(ret != ARCHIVE_OK)
+		return ret;
+
+	rar->file.service = 1;
+
+	/* But skip the data part automatically. It's no use for the user
+	 * anyway.  It contains only service data, not even needed to
+	 * properly unpack the file. */
+	ret = rar5_read_data_skip(a);
+	if(ret != ARCHIVE_OK)
+		return ret;
+
+	/* After skipping, try parsing another block automatically. */
+	return ARCHIVE_RETRY;
+}
+
+static int process_head_main(struct archive_read* a, struct rar5* rar,
+    struct archive_entry* entry, size_t block_flags)
+{
+	int ret;
+	size_t extra_data_size = 0;
+	size_t extra_field_size = 0;
+	size_t extra_field_id = 0;
+	size_t archive_flags = 0;
+
+	enum MAIN_FLAGS {
+		VOLUME = 0x0001,         /* multi-volume archive */
+		VOLUME_NUMBER = 0x0002,  /* volume number, first vol doesn't
+					  * have it */
+		SOLID = 0x0004,          /* solid archive */
+		PROTECT = 0x0008,        /* contains Recovery info */
+		LOCK = 0x0010,           /* readonly flag, not used */
+	};
+
+	enum MAIN_EXTRA {
+		// Just one attribute here.
+		LOCATOR = 0x01,
+	};
+
+	(void) entry;
+
+	if(block_flags & HFL_EXTRA_DATA) {
+		if(!read_var_sized(a, &extra_data_size, NULL))
+			return ARCHIVE_EOF;
+	} else {
+		extra_data_size = 0;
+	}
+
+	if(!read_var_sized(a, &archive_flags, NULL)) {
+		return ARCHIVE_EOF;
+	}
+
+	rar->main.volume = (archive_flags & VOLUME) > 0;
+	rar->main.solid = (archive_flags & SOLID) > 0;
+
+	if(archive_flags & VOLUME_NUMBER) {
+		size_t v = 0;
+		if(!read_var_sized(a, &v, NULL)) {
+			return ARCHIVE_EOF;
+		}
+
+		if (v > UINT_MAX) {
+			archive_set_error(&a->archive,
+			    ARCHIVE_ERRNO_FILE_FORMAT,
+			    "Invalid volume number");
+			return ARCHIVE_FATAL;
+		}
+
+		rar->main.vol_no = (unsigned int) v;
+	} else {
+		rar->main.vol_no = 0;
+	}
+
+	if(rar->vol.expected_vol_no > 0 &&
+		rar->main.vol_no != rar->vol.expected_vol_no)
+	{
+		/* Returning EOF instead of FATAL because of strange
+		 * libarchive behavior. When opening multiple files via
+		 * archive_read_open_filenames(), after reading up the whole
+		 * last file, the __archive_read_ahead function wraps up to
+		 * the first archive instead of returning EOF. */
+		return ARCHIVE_EOF;
+	}
+
+	if(extra_data_size == 0) {
+		/* Early return. */
+		return ARCHIVE_OK;
+	}
+
+	if(!read_var_sized(a, &extra_field_size, NULL)) {
+		return ARCHIVE_EOF;
+	}
+
+	if(!read_var_sized(a, &extra_field_id, NULL)) {
+		return ARCHIVE_EOF;
+	}
+
+	if(extra_field_size == 0) {
+		archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+		    "Invalid extra field size");
+		return ARCHIVE_FATAL;
+	}
+
+	switch(extra_field_id) {
+		case LOCATOR:
+			ret = process_main_locator_extra_block(a, rar);
+			if(ret != ARCHIVE_OK) {
+				/* Error while parsing main locator extra
+				 * block. */
+				return ret;
+			}
+
+			break;
+		default:
+			archive_set_error(&a->archive,
+			    ARCHIVE_ERRNO_FILE_FORMAT,
+			    "Unsupported extra type (0x%x)",
+			    (int) extra_field_id);
+			return ARCHIVE_FATAL;
+	}
+
+	return ARCHIVE_OK;
+}
+
+static int skip_unprocessed_bytes(struct archive_read* a) {
+	struct rar5* rar = get_context(a);
+	int ret;
+
+	if(rar->file.bytes_remaining) {
+		/* Use different skipping method in block merging mode than in
+		 * normal mode. If merge mode is active, rar5_read_data_skip
+		 * can't be used, because it could allow recursive use of
+		 * merge_block() * function, and this function doesn't support
+		 * recursive use. */
+		if(rar->merge_mode) {
+			/* Discard whole merged block. This is valid in solid
+			 * mode as well, because the code will discard blocks
+			 * only if those blocks are safe to discard (i.e.
+			 * they're not FILE blocks).  */
+			ret = consume(a, rar->file.bytes_remaining);
+			if(ret != ARCHIVE_OK) {
+				return ret;
+			}
+			rar->file.bytes_remaining = 0;
+		} else {
+			/* If we're not in merge mode, use safe skipping code.
+			 * This will ensure we'll handle solid archives
+			 * properly. */
+			ret = rar5_read_data_skip(a);
+			if(ret != ARCHIVE_OK) {
+				return ret;
+			}
+		}
+	}
+
+	return ARCHIVE_OK;
+}
+
+static int scan_for_signature(struct archive_read* a);
+
+/* Base block processing function. A 'base block' is a RARv5 header block
+ * that tells the reader what kind of data is stored inside the block.
+ *
+ * From the birds-eye view a RAR file looks file this:
+ *
+ * <magic><base_block_1><base_block_2>...<base_block_n>
+ *
+ * There are a few types of base blocks. Those types are specified inside
+ * the 'switch' statement in this function. For example purposes, I'll write
+ * how a standard RARv5 file could look like here:
+ *
+ * <magic><MAIN><FILE><FILE><FILE><SERVICE><ENDARC>
+ *
+ * The structure above could describe an archive file with 3 files in it,
+ * one service "QuickOpen" block (that is ignored by this parser), and an
+ * end of file base block marker.
+ *
+ * If the file is stored in multiple archive files ("multiarchive"), it might
+ * look like this:
+ *
+ * .part01.rar: <magic><MAIN><FILE><ENDARC>
+ * .part02.rar: <magic><MAIN><FILE><ENDARC>
+ * .part03.rar: <magic><MAIN><FILE><ENDARC>
+ *
+ * This example could describe 3 RAR files that contain ONE archived file.
+ * Or it could describe 3 RAR files that contain 3 different files. Or 3
+ * RAR files than contain 2 files. It all depends what metadata is stored in
+ * the headers of <FILE> blocks.
+ *
+ * Each <FILE> block contains info about its size, the name of the file it's
+ * storing inside, and whether this FILE block is a continuation block of
+ * previous archive ('split before'), and is this FILE block should be
+ * continued in another archive ('split after'). By parsing the 'split before'
+ * and 'split after' flags, we're able to tell if multiple <FILE> base blocks
+ * are describing one file, or multiple files (with the same filename, for
+ * example).
+ *
+ * One thing to note is that if we're parsing the first <FILE> block, and
+ * we see 'split after' flag, then we need to jump over to another <FILE>
+ * block to be able to decompress rest of the data. To do this, we need
+ * to skip the <ENDARC> block, then switch to another file, then skip the
+ * <magic> block, <MAIN> block, and then we're standing on the proper
+ * <FILE> block.
+ */
+
+static int process_base_block(struct archive_read* a,
+    struct archive_entry* entry)
+{
+	const size_t SMALLEST_RAR5_BLOCK_SIZE = 3;
+
+	struct rar5* rar = get_context(a);
+	uint32_t hdr_crc, computed_crc;
+	size_t raw_hdr_size = 0, hdr_size_len, hdr_size;
+	size_t header_id = 0;
+	size_t header_flags = 0;
+	const uint8_t* p;
+	int ret;
+
+	enum HEADER_TYPE {
+		HEAD_MARK    = 0x00, HEAD_MAIN  = 0x01, HEAD_FILE   = 0x02,
+		HEAD_SERVICE = 0x03, HEAD_CRYPT = 0x04, HEAD_ENDARC = 0x05,
+		HEAD_UNKNOWN = 0xff,
+	};
+
+	/* Skip any unprocessed data for this file. */
+	ret = skip_unprocessed_bytes(a);
+	if(ret != ARCHIVE_OK)
+		return ret;
+
+	/* Read the expected CRC32 checksum. */
+	if(!read_u32(a, &hdr_crc)) {
+		return ARCHIVE_EOF;
+	}
+
+	/* Read header size. */
+	if(!read_var_sized(a, &raw_hdr_size, &hdr_size_len)) {
+		return ARCHIVE_EOF;
+	}
+
+	hdr_size = raw_hdr_size + hdr_size_len;
+
+	/* Sanity check, maximum header size for RAR5 is 2MB. */
+	if(hdr_size > (2 * 1024 * 1024)) {
+		archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+		    "Base block header is too large");
+
+		return ARCHIVE_FATAL;
+	}
+
+	/* Additional sanity checks to weed out invalid files. */
+	if(raw_hdr_size == 0 || hdr_size_len == 0 ||
+		hdr_size < SMALLEST_RAR5_BLOCK_SIZE)
+	{
+		archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+		    "Too small block encountered (%zu bytes)",
+		    raw_hdr_size);
+
+		return ARCHIVE_FATAL;
+	}
+
+	/* Read the whole header data into memory, maximum memory use here is
+	 * 2MB. */
+	if(!read_ahead(a, hdr_size, &p)) {
+		return ARCHIVE_EOF;
+	}
+
+	/* Verify the CRC32 of the header data. */
+	computed_crc = (uint32_t) crc32(0, p, (int) hdr_size);
+	if(computed_crc != hdr_crc) {
+		archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+		    "Header CRC error");
+
+		return ARCHIVE_FATAL;
+	}
+
+	/* If the checksum is OK, we proceed with parsing. */
+	if(ARCHIVE_OK != consume(a, hdr_size_len)) {
+		return ARCHIVE_EOF;
+	}
+
+	if(!read_var_sized(a, &header_id, NULL))
+		return ARCHIVE_EOF;
+
+	if(!read_var_sized(a, &header_flags, NULL))
+		return ARCHIVE_EOF;
+
+	rar->generic.split_after = (header_flags & HFL_SPLIT_AFTER) > 0;
+	rar->generic.split_before = (header_flags & HFL_SPLIT_BEFORE) > 0;
+	rar->generic.size = (int)hdr_size;
+	rar->generic.last_header_id = (int)header_id;
+	rar->main.endarc = 0;
+
+	/* Those are possible header ids in RARv5. */
+	switch(header_id) {
+		case HEAD_MAIN:
+			ret = process_head_main(a, rar, entry, header_flags);
+
+			/* Main header doesn't have any files in it, so it's
+			 * pointless to return to the caller. Retry to next
+			 * header, which should be HEAD_FILE/HEAD_SERVICE. */
+			if(ret == ARCHIVE_OK)
+				return ARCHIVE_RETRY;
+
+			return ret;
+		case HEAD_SERVICE:
+			ret = process_head_service(a, rar, entry, header_flags);
+			return ret;
+		case HEAD_FILE:
+			ret = process_head_file(a, rar, entry, header_flags);
+			return ret;
+		case HEAD_CRYPT:
+			archive_set_error(&a->archive,
+			    ARCHIVE_ERRNO_FILE_FORMAT,
+			    "Encryption is not supported");
+			return ARCHIVE_FATAL;
+		case HEAD_ENDARC:
+			rar->main.endarc = 1;
+
+			/* After encountering an end of file marker, we need
+			 * to take into consideration if this archive is
+			 * continued in another file (i.e. is it part01.rar:
+			 * is there a part02.rar?) */
+			if(rar->main.volume) {
+				/* In case there is part02.rar, position the
+				 * read pointer in a proper place, so we can
+				 * resume parsing. */
+				ret = scan_for_signature(a);
+				if(ret == ARCHIVE_FATAL) {
+					return ARCHIVE_EOF;
+				} else {
+					if(rar->vol.expected_vol_no ==
+					    UINT_MAX) {
+						archive_set_error(&a->archive,
+						    ARCHIVE_ERRNO_FILE_FORMAT,
+						    "Header error");
+							return ARCHIVE_FATAL;
+					}
+
+					rar->vol.expected_vol_no =
+					    rar->main.vol_no + 1;
+					return ARCHIVE_OK;
+				}
+			} else {
+				return ARCHIVE_EOF;
+			}
+		case HEAD_MARK:
+			return ARCHIVE_EOF;
+		default:
+			if((header_flags & HFL_SKIP_IF_UNKNOWN) == 0) {
+				archive_set_error(&a->archive,
+				    ARCHIVE_ERRNO_FILE_FORMAT,
+				    "Header type error");
+				return ARCHIVE_FATAL;
+			} else {
+				/* If the block is marked as 'skip if unknown',
+				 * do as the flag says: skip the block
+				 * instead on failing on it. */
+				return ARCHIVE_RETRY;
+			}
+	}
+
+#if !defined WIN32
+	// Not reached.
+	archive_set_error(&a->archive, ARCHIVE_ERRNO_PROGRAMMER,
+	    "Internal unpacker error");
+	return ARCHIVE_FATAL;
+#endif
+}
+
+static int skip_base_block(struct archive_read* a) {
+	int ret;
+	struct rar5* rar = get_context(a);
+
+	/* Create a new local archive_entry structure that will be operated on
+	 * by header reader; operations on this archive_entry will be discarded.
+	 */
+	struct archive_entry* entry = archive_entry_new();
+	ret = process_base_block(a, entry);
+
+	/* Discard operations on this archive_entry structure. */
+	archive_entry_free(entry);
+	if(ret == ARCHIVE_FATAL)
+		return ret;
+
+	if(rar->generic.last_header_id == 2 && rar->generic.split_before > 0)
+		return ARCHIVE_OK;
+
+	if(ret == ARCHIVE_OK)
+		return ARCHIVE_RETRY;
+	else
+		return ret;
+}
+
+static int rar5_read_header(struct archive_read *a,
+    struct archive_entry *entry)
+{
+	struct rar5* rar = get_context(a);
+	int ret;
+
+	if(rar->header_initialized == 0) {
+		init_header(a);
+		rar->header_initialized = 1;
+	}
+
+	if(rar->skipped_magic == 0) {
+		if(ARCHIVE_OK != consume(a, sizeof(rar5_signature_xor))) {
+			return ARCHIVE_EOF;
+		}
+
+		rar->skipped_magic = 1;
+	}
+
+	do {
+		ret = process_base_block(a, entry);
+	} while(ret == ARCHIVE_RETRY ||
+			(rar->main.endarc > 0 && ret == ARCHIVE_OK));
+
+	return ret;
+}
+
+static void init_unpack(struct rar5* rar) {
+	rar->file.calculated_crc32 = 0;
+	init_window_mask(rar);
+
+	free(rar->cstate.window_buf);
+	free(rar->cstate.filtered_buf);
+
+	if(rar->cstate.window_size > 0) {
+		rar->cstate.window_buf = calloc(1, rar->cstate.window_size);
+		rar->cstate.filtered_buf = calloc(1, rar->cstate.window_size);
+	} else {
+		rar->cstate.window_buf = NULL;
+		rar->cstate.filtered_buf = NULL;
+	}
+
+	rar->cstate.write_ptr = 0;
+	rar->cstate.last_write_ptr = 0;
+
+	memset(&rar->cstate.bd, 0, sizeof(rar->cstate.bd));
+	memset(&rar->cstate.ld, 0, sizeof(rar->cstate.ld));
+	memset(&rar->cstate.dd, 0, sizeof(rar->cstate.dd));
+	memset(&rar->cstate.ldd, 0, sizeof(rar->cstate.ldd));
+	memset(&rar->cstate.rd, 0, sizeof(rar->cstate.rd));
+}
+
+static void update_crc(struct rar5* rar, const uint8_t* p, size_t to_read) {
+    int verify_crc;
+
+	if(rar->skip_mode) {
+#if defined CHECK_CRC_ON_SOLID_SKIP
+		verify_crc = 1;
+#else
+		verify_crc = 0;
+#endif
+	} else
+		verify_crc = 1;
+
+	if(verify_crc) {
+		/* Don't update CRC32 if the file doesn't have the
+		 * `stored_crc32` info filled in. */
+		if(rar->file.stored_crc32 > 0) {
+			rar->file.calculated_crc32 =
+				crc32(rar->file.calculated_crc32, p, to_read);
+		}
+
+		/* Check if the file uses an optional BLAKE2sp checksum
+		 * algorithm. */
+		if(rar->file.has_blake2 > 0) {
+			/* Return value of the `update` function is always 0,
+			 * so we can explicitly ignore it here. */
+			(void) blake2sp_update(&rar->file.b2state, p, to_read);
+		}
+	}
+}
+
+static int create_decode_tables(uint8_t* bit_length,
+    struct decode_table* table, int size)
+{
+	int code, upper_limit = 0, i, lc[16];
+	uint32_t decode_pos_clone[rar5_countof(table->decode_pos)];
+	ssize_t cur_len, quick_data_size;
+
+	memset(&lc, 0, sizeof(lc));
+	memset(table->decode_num, 0, sizeof(table->decode_num));
+	table->size = size;
+	table->quick_bits = size == HUFF_NC ? 10 : 7;
+
+	for(i = 0; i < size; i++) {
+		lc[bit_length[i] & 15]++;
+	}
+
+	lc[0] = 0;
+	table->decode_pos[0] = 0;
+	table->decode_len[0] = 0;
+
+	for(i = 1; i < 16; i++) {
+		upper_limit += lc[i];
+
+		table->decode_len[i] = upper_limit << (16 - i);
+		table->decode_pos[i] = table->decode_pos[i - 1] + lc[i - 1];
+
+		upper_limit <<= 1;
+	}
+
+	memcpy(decode_pos_clone, table->decode_pos, sizeof(decode_pos_clone));
+
+	for(i = 0; i < size; i++) {
+		uint8_t clen = bit_length[i] & 15;
+		if(clen > 0) {
+			int last_pos = decode_pos_clone[clen];
+			table->decode_num[last_pos] = i;
+			decode_pos_clone[clen]++;
+		}
+	}
+
+	quick_data_size = (int64_t)1 << table->quick_bits;
+	cur_len = 1;
+	for(code = 0; code < quick_data_size; code++) {
+		int bit_field = code << (16 - table->quick_bits);
+		int dist, pos;
+
+		while(cur_len < rar5_countof(table->decode_len) &&
+				bit_field >= table->decode_len[cur_len]) {
+			cur_len++;
+		}
+
+		table->quick_len[code] = (uint8_t) cur_len;
+
+		dist = bit_field - table->decode_len[cur_len - 1];
+		dist >>= (16 - cur_len);
+
+		pos = table->decode_pos[cur_len & 15] + dist;
+		if(cur_len < rar5_countof(table->decode_pos) && pos < size) {
+			table->quick_num[code] = table->decode_num[pos];
+		} else {
+			table->quick_num[code] = 0;
+		}
+	}
+
+	return ARCHIVE_OK;
+}
+
+static int decode_number(struct archive_read* a, struct decode_table* table,
+    const uint8_t* p, uint16_t* num)
+{
+	int i, bits, dist;
+	uint16_t bitfield;
+	uint32_t pos;
+	struct rar5* rar = get_context(a);
+
+	if(ARCHIVE_OK != read_bits_16(rar, p, &bitfield)) {
+		return ARCHIVE_EOF;
+	}
+
+	bitfield &= 0xfffe;
+
+	if(bitfield < table->decode_len[table->quick_bits]) {
+		int code = bitfield >> (16 - table->quick_bits);
+		skip_bits(rar, table->quick_len[code]);
+		*num = table->quick_num[code];
+		return ARCHIVE_OK;
+	}
+
+	bits = 15;
+
+	for(i = table->quick_bits + 1; i < 15; i++) {
+		if(bitfield < table->decode_len[i]) {
+			bits = i;
+			break;
+		}
+	}
+
+	skip_bits(rar, bits);
+
+	dist = bitfield - table->decode_len[bits - 1];
+	dist >>= (16 - bits);
+	pos = table->decode_pos[bits] + dist;
+
+	if(pos >= table->size)
+		pos = 0;
+
+	*num = table->decode_num[pos];
+	return ARCHIVE_OK;
+}
+
+/* Reads and parses Huffman tables from the beginning of the block. */
+static int parse_tables(struct archive_read* a, struct rar5* rar,
+    const uint8_t* p)
+{
+	int ret, value, i, w, idx = 0;
+	uint8_t bit_length[HUFF_BC],
+		table[HUFF_TABLE_SIZE],
+		nibble_mask = 0xF0,
+		nibble_shift = 4;
+
+	enum { ESCAPE = 15 };
+
+	/* The data for table generation is compressed using a simple RLE-like
+	 * algorithm when storing zeroes, so we need to unpack it first. */
+	for(w = 0, i = 0; w < HUFF_BC;) {
+		if(i >= rar->cstate.cur_block_size) {
+			/* Truncated data, can't continue. */
+			archive_set_error(&a->archive,
+			    ARCHIVE_ERRNO_FILE_FORMAT,
+			    "Truncated data in huffman tables");
+			return ARCHIVE_FATAL;
+		}
+
+		value = (p[i] & nibble_mask) >> nibble_shift;
+
+		if(nibble_mask == 0x0F)
+			++i;
+
+		nibble_mask ^= 0xFF;
+		nibble_shift ^= 4;
+
+		/* Values smaller than 15 is data, so we write it directly.
+		 * Value 15 is a flag telling us that we need to unpack more
+		 * bytes. */
+		if(value == ESCAPE) {
+			value = (p[i] & nibble_mask) >> nibble_shift;
+			if(nibble_mask == 0x0F)
+				++i;
+			nibble_mask ^= 0xFF;
+			nibble_shift ^= 4;
+
+			if(value == 0) {
+				/* We sometimes need to write the actual value
+				 * of 15, so this case handles that. */
+				bit_length[w++] = ESCAPE;
+			} else {
+				int k;
+
+				/* Fill zeroes. */
+				for(k = 0; (k < value + 2) && (w < HUFF_BC);
+				    k++) {
+					bit_length[w++] = 0;
+				}
+			}
+		} else {
+			bit_length[w++] = value;
+		}
+	}
+
+	rar->bits.in_addr = i;
+	rar->bits.bit_addr = nibble_shift ^ 4;
+
+	ret = create_decode_tables(bit_length, &rar->cstate.bd, HUFF_BC);
+	if(ret != ARCHIVE_OK) {
+		archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+		    "Decoding huffman tables failed");
+		return ARCHIVE_FATAL;
+	}
+
+	for(i = 0; i < HUFF_TABLE_SIZE;) {
+		uint16_t num;
+
+		if((rar->bits.in_addr + 6) >= rar->cstate.cur_block_size) {
+			/* Truncated data, can't continue. */
+			archive_set_error(&a->archive,
+			    ARCHIVE_ERRNO_FILE_FORMAT,
+			    "Truncated data in huffman tables (#2)");
+			return ARCHIVE_FATAL;
+		}
+
+		ret = decode_number(a, &rar->cstate.bd, p, &num);
+		if(ret != ARCHIVE_OK) {
+			archive_set_error(&a->archive,
+			    ARCHIVE_ERRNO_FILE_FORMAT,
+			    "Decoding huffman tables failed");
+			return ARCHIVE_FATAL;
+		}
+
+		if(num < 16) {
+			/* 0..15: store directly */
+			table[i] = (uint8_t) num;
+			i++;
+		} else if(num < 18) {
+			/* 16..17: repeat previous code */
+			uint16_t n;
+
+			if(ARCHIVE_OK != read_bits_16(rar, p, &n))
+				return ARCHIVE_EOF;
+
+			if(num == 16) {
+				n >>= 13;
+				n += 3;
+				skip_bits(rar, 3);
+			} else {
+				n >>= 9;
+				n += 11;
+				skip_bits(rar, 7);
+			}
+
+			if(i > 0) {
+				while(n-- > 0 && i < HUFF_TABLE_SIZE) {
+					table[i] = table[i - 1];
+					i++;
+				}
+			} else {
+				archive_set_error(&a->archive,
+				    ARCHIVE_ERRNO_FILE_FORMAT,
+				    "Unexpected error when decoding "
+				    "huffman tables");
+				return ARCHIVE_FATAL;
+			}
+		} else {
+			/* other codes: fill with zeroes `n` times */
+			uint16_t n;
+
+			if(ARCHIVE_OK != read_bits_16(rar, p, &n))
+				return ARCHIVE_EOF;
+
+			if(num == 18) {
+				n >>= 13;
+				n += 3;
+				skip_bits(rar, 3);
+			} else {
+				n >>= 9;
+				n += 11;
+				skip_bits(rar, 7);
+			}
+
+			while(n-- > 0 && i < HUFF_TABLE_SIZE)
+				table[i++] = 0;
+		}
+	}
+
+	ret = create_decode_tables(&table[idx], &rar->cstate.ld, HUFF_NC);
+	if(ret != ARCHIVE_OK) {
+		archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+		     "Failed to create literal table");
+		return ARCHIVE_FATAL;
+	}
+
+	idx += HUFF_NC;
+
+	ret = create_decode_tables(&table[idx], &rar->cstate.dd, HUFF_DC);
+	if(ret != ARCHIVE_OK) {
+		archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+		    "Failed to create distance table");
+		return ARCHIVE_FATAL;
+	}
+
+	idx += HUFF_DC;
+
+	ret = create_decode_tables(&table[idx], &rar->cstate.ldd, HUFF_LDC);
+	if(ret != ARCHIVE_OK) {
+		archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+		    "Failed to create lower bits of distances table");
+		return ARCHIVE_FATAL;
+	}
+
+	idx += HUFF_LDC;
+
+	ret = create_decode_tables(&table[idx], &rar->cstate.rd, HUFF_RC);
+	if(ret != ARCHIVE_OK) {
+		archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+		    "Failed to create repeating distances table");
+		return ARCHIVE_FATAL;
+	}
+
+	return ARCHIVE_OK;
+}
+
+/* Parses the block header, verifies its CRC byte, and saves the header
+ * fields inside the `hdr` pointer. */
+static int parse_block_header(struct archive_read* a, const uint8_t* p,
+    ssize_t* block_size, struct compressed_block_header* hdr)
+{
+	uint8_t calculated_cksum;
+	memcpy(hdr, p, sizeof(struct compressed_block_header));
+
+	if(bf_byte_count(hdr) > 2) {
+		archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+		    "Unsupported block header size (was %d, max is 2)",
+		    bf_byte_count(hdr));
+		return ARCHIVE_FATAL;
+	}
+
+	/* This should probably use bit reader interface in order to be more
+	 * future-proof. */
+	*block_size = 0;
+	switch(bf_byte_count(hdr)) {
+		/* 1-byte block size */
+		case 0:
+			*block_size = *(const uint8_t*) &p[2];
+			break;
+
+		/* 2-byte block size */
+		case 1:
+			*block_size = archive_le16dec(&p[2]);
+			break;
+
+		/* 3-byte block size */
+		case 2:
+			*block_size = archive_le32dec(&p[2]);
+			*block_size &= 0x00FFFFFF;
+			break;
+
+		/* Other block sizes are not supported. This case is not
+		 * reached, because we have an 'if' guard before the switch
+		 * that makes sure of it. */
+		default:
+			return ARCHIVE_FATAL;
+	}
+
+	/* Verify the block header checksum. 0x5A is a magic value and is
+	 * always * constant. */
+	calculated_cksum = 0x5A
+	    ^ (uint8_t) hdr->block_flags_u8
+	    ^ (uint8_t) *block_size
+	    ^ (uint8_t) (*block_size >> 8)
+	    ^ (uint8_t) (*block_size >> 16);
+
+	if(calculated_cksum != hdr->block_cksum) {
+		archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+		    "Block checksum error: got 0x%x, expected 0x%x",
+		    hdr->block_cksum, calculated_cksum);
+
+		return ARCHIVE_FATAL;
+	}
+
+	return ARCHIVE_OK;
+}
+
+/* Convenience function used during filter processing. */
+static int parse_filter_data(struct rar5* rar, const uint8_t* p,
+    uint32_t* filter_data)
+{
+	int i, bytes;
+	uint32_t data = 0;
+
+	if(ARCHIVE_OK != read_consume_bits(rar, p, 2, &bytes))
+		return ARCHIVE_EOF;
+
+	bytes++;
+
+	for(i = 0; i < bytes; i++) {
+		uint16_t byte;
+
+		if(ARCHIVE_OK != read_bits_16(rar, p, &byte)) {
+			return ARCHIVE_EOF;
+		}
+
+		/* Cast to uint32_t will ensure the shift operation will not
+		 * produce undefined result. */
+		data += ((uint32_t) byte >> 8) << (i * 8);
+		skip_bits(rar, 8);
+	}
+
+	*filter_data = data;
+	return ARCHIVE_OK;
+}
+
+/* Function is used during sanity checking. */
+static int is_valid_filter_block_start(struct rar5* rar,
+    uint32_t start)
+{
+	const int64_t block_start = (ssize_t) start + rar->cstate.write_ptr;
+	const int64_t last_bs = rar->cstate.last_block_start;
+	const ssize_t last_bl = rar->cstate.last_block_length;
+
+	if(last_bs == 0 || last_bl == 0) {
+		/* We didn't have any filters yet, so accept this offset. */
+		return 1;
+	}
+
+	if(block_start >= last_bs + last_bl) {
+		/* Current offset is bigger than last block's end offset, so
+		 * accept current offset. */
+		return 1;
+	}
+
+	/* Any other case is not a normal situation and we should fail. */
+	return 0;
+}
+
+/* The function will create a new filter, read its parameters from the input
+ * stream and add it to the filter collection. */
+static int parse_filter(struct archive_read* ar, const uint8_t* p) {
+	uint32_t block_start, block_length;
+	uint16_t filter_type;
+	struct filter_info* filt = NULL;
+	struct rar5* rar = get_context(ar);
+
+	/* Read the parameters from the input stream. */
+	if(ARCHIVE_OK != parse_filter_data(rar, p, &block_start))
+		return ARCHIVE_EOF;
+
+	if(ARCHIVE_OK != parse_filter_data(rar, p, &block_length))
+		return ARCHIVE_EOF;
+
+	if(ARCHIVE_OK != read_bits_16(rar, p, &filter_type))
+		return ARCHIVE_EOF;
+
+	filter_type >>= 13;
+	skip_bits(rar, 3);
+
+	/* Perform some sanity checks on this filter parameters. Note that we
+	 * allow only DELTA, E8/E9 and ARM filters here, because rest of
+	 * filters are not used in RARv5. */
+
+	if(block_length < 4 ||
+	    block_length > 0x400000 ||
+	    filter_type > FILTER_ARM ||
+	    !is_valid_filter_block_start(rar, block_start))
+	{
+		archive_set_error(&ar->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+		    "Invalid filter encountered");
+		return ARCHIVE_FATAL;
+	}
+
+	/* Allocate a new filter. */
+	filt = add_new_filter(rar);
+	if(filt == NULL) {
+		archive_set_error(&ar->archive, ENOMEM,
+		    "Can't allocate memory for a filter descriptor.");
+		return ARCHIVE_FATAL;
+	}
+
+	filt->type = filter_type;
+	filt->block_start = rar->cstate.write_ptr + block_start;
+	filt->block_length = block_length;
+
+	rar->cstate.last_block_start = filt->block_start;
+	rar->cstate.last_block_length = filt->block_length;
+
+	/* Read some more data in case this is a DELTA filter. Other filter
+	 * types don't require any additional data over what was already
+	 * read. */
+	if(filter_type == FILTER_DELTA) {
+		int channels;
+
+		if(ARCHIVE_OK != read_consume_bits(rar, p, 5, &channels))
+			return ARCHIVE_EOF;
+
+		filt->channels = channels + 1;
+	}
+
+	return ARCHIVE_OK;
+}
+
+static int decode_code_length(struct rar5* rar, const uint8_t* p,
+    uint16_t code)
+{
+	int lbits, length = 2;
+	if(code < 8) {
+		lbits = 0;
+		length += code;
+	} else {
+		lbits = code / 4 - 1;
+		length += (4 | (code & 3)) << lbits;
+	}
+
+	if(lbits > 0) {
+		int add;
+
+		if(ARCHIVE_OK != read_consume_bits(rar, p, lbits, &add))
+			return -1;
+
+		length += add;
+	}
+
+	return length;
+}
+
+static int copy_string(struct archive_read* a, int len, int dist) {
+	struct rar5* rar = get_context(a);
+	const uint64_t cmask = rar->cstate.window_mask;
+	const uint64_t write_ptr = rar->cstate.write_ptr +
+	    rar->cstate.solid_offset;
+	int i;
+
+	if (rar->cstate.window_buf == NULL)
+		return ARCHIVE_FATAL;
+
+	/* The unpacker spends most of the time in this function. It would be
+	 * a good idea to introduce some optimizations here.
+	 *
+	 * Just remember that this loop treats buffers that overlap differently
+	 * than buffers that do not overlap. This is why a simple memcpy(3)
+	 * call will not be enough. */
+
+	for(i = 0; i < len; i++) {
+		const ssize_t write_idx = (write_ptr + i) & cmask;
+		const ssize_t read_idx = (write_ptr + i - dist) & cmask;
+		rar->cstate.window_buf[write_idx] =
+		    rar->cstate.window_buf[read_idx];
+	}
+
+	rar->cstate.write_ptr += len;
+	return ARCHIVE_OK;
+}
+
+static int do_uncompress_block(struct archive_read* a, const uint8_t* p) {
+	struct rar5* rar = get_context(a);
+	uint16_t num;
+	int ret;
+
+	const uint64_t cmask = rar->cstate.window_mask;
+	const struct compressed_block_header* hdr = &rar->last_block_hdr;
+	const uint8_t bit_size = 1 + bf_bit_size(hdr);
+
+	while(1) {
+		if(rar->cstate.write_ptr - rar->cstate.last_write_ptr >
+		    (rar->cstate.window_size >> 1)) {
+			/* Don't allow growing data by more than half of the
+			 * window size at a time. In such case, break the loop;
+			 *  next call to this function will continue processing
+			 *  from this moment. */
+			break;
+		}
+
+		if(rar->bits.in_addr > rar->cstate.cur_block_size - 1 ||
+		    (rar->bits.in_addr == rar->cstate.cur_block_size - 1 &&
+		    rar->bits.bit_addr >= bit_size))
+		{
+			/* If the program counter is here, it means the
+			 * function has finished processing the block. */
+			rar->cstate.block_parsing_finished = 1;
+			break;
+		}
+
+		/* Decode the next literal. */
+		if(ARCHIVE_OK != decode_number(a, &rar->cstate.ld, p, &num)) {
+			return ARCHIVE_EOF;
+		}
+
+		/* Num holds a decompression literal, or 'command code'.
+		 *
+		 * - Values lower than 256 are just bytes. Those codes
+		 *   can be stored in the output buffer directly.
+		 *
+		 * - Code 256 defines a new filter, which is later used to
+		 *   ransform the data block accordingly to the filter type.
+		 *   The data block needs to be fully uncompressed first.
+		 *
+		 * - Code bigger than 257 and smaller than 262 define
+		 *   a repetition pattern that should be copied from
+		 *   an already uncompressed chunk of data.
+		 */
+
+		if(num < 256) {
+			/* Directly store the byte. */
+			int64_t write_idx = rar->cstate.solid_offset +
+			    rar->cstate.write_ptr++;
+
+			rar->cstate.window_buf[write_idx & cmask] =
+			    (uint8_t) num;
+			continue;
+		} else if(num >= 262) {
+			uint16_t dist_slot;
+			int len = decode_code_length(rar, p, num - 262),
+				dbits,
+				dist = 1;
+
+			if(len == -1) {
+				archive_set_error(&a->archive,
+				    ARCHIVE_ERRNO_PROGRAMMER,
+				    "Failed to decode the code length");
+
+				return ARCHIVE_FATAL;
+			}
+
+			if(ARCHIVE_OK != decode_number(a, &rar->cstate.dd, p,
+			    &dist_slot))
+			{
+				archive_set_error(&a->archive,
+				    ARCHIVE_ERRNO_PROGRAMMER,
+				    "Failed to decode the distance slot");
+
+				return ARCHIVE_FATAL;
+			}
+
+			if(dist_slot < 4) {
+				dbits = 0;
+				dist += dist_slot;
+			} else {
+				dbits = dist_slot / 2 - 1;
+
+				/* Cast to uint32_t will make sure the shift
+				 * left operation won't produce undefined
+				 * result. Then, the uint32_t type will
+				 * be implicitly casted to int. */
+				dist += (uint32_t) (2 |
+				    (dist_slot & 1)) << dbits;
+			}
+
+			if(dbits > 0) {
+				if(dbits >= 4) {
+					uint32_t add = 0;
+					uint16_t low_dist;
+
+					if(dbits > 4) {
+						if(ARCHIVE_OK != read_bits_32(
+						    rar, p, &add)) {
+							/* Return EOF if we
+							 * can't read more
+							 * data. */
+							return ARCHIVE_EOF;
+						}
+
+						skip_bits(rar, dbits - 4);
+						add = (add >> (
+						    36 - dbits)) << 4;
+						dist += add;
+					}
+
+					if(ARCHIVE_OK != decode_number(a,
+					    &rar->cstate.ldd, p, &low_dist))
+					{
+						archive_set_error(&a->archive,
+						    ARCHIVE_ERRNO_PROGRAMMER,
+						    "Failed to decode the "
+						    "distance slot");
+
+						return ARCHIVE_FATAL;
+					}
+
+					if(dist >= INT_MAX - low_dist - 1) {
+						/* This only happens in
+						 * invalid archives. */
+						archive_set_error(&a->archive,
+						    ARCHIVE_ERRNO_FILE_FORMAT,
+						    "Distance pointer "
+						    "overflow");
+						return ARCHIVE_FATAL;
+					}
+
+					dist += low_dist;
+				} else {
+					/* dbits is one of [0,1,2,3] */
+					int add;
+
+					if(ARCHIVE_OK != read_consume_bits(rar,
+					     p, dbits, &add)) {
+						/* Return EOF if we can't read
+						 * more data. */
+						return ARCHIVE_EOF;
+					}
+
+					dist += add;
+				}
+			}
+
+			if(dist > 0x100) {
+				len++;
+
+				if(dist > 0x2000) {
+					len++;
+
+					if(dist > 0x40000) {
+						len++;
+					}
+				}
+			}
+
+			dist_cache_push(rar, dist);
+			rar->cstate.last_len = len;
+
+			if(ARCHIVE_OK != copy_string(a, len, dist))
+				return ARCHIVE_FATAL;
+
+			continue;
+		} else if(num == 256) {
+			/* Create a filter. */
+			ret = parse_filter(a, p);
+			if(ret != ARCHIVE_OK)
+				return ret;
+
+			continue;
+		} else if(num == 257) {
+			if(rar->cstate.last_len != 0) {
+				if(ARCHIVE_OK != copy_string(a,
+				    rar->cstate.last_len,
+				    rar->cstate.dist_cache[0]))
+				{
+					return ARCHIVE_FATAL;
+				}
+			}
+
+			continue;
+		} else {
+			/* num < 262 */
+			const int idx = num - 258;
+			const int dist = dist_cache_touch(rar, idx);
+
+			uint16_t len_slot;
+			int len;
+
+			if(ARCHIVE_OK != decode_number(a, &rar->cstate.rd, p,
+			    &len_slot)) {
+				return ARCHIVE_FATAL;
+			}
+
+			len = decode_code_length(rar, p, len_slot);
+			rar->cstate.last_len = len;
+
+			if(ARCHIVE_OK != copy_string(a, len, dist))
+				return ARCHIVE_FATAL;
+
+			continue;
+		}
+
+		/* The program counter shouldn't reach here. */
+		archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+		    "Unsupported block code: 0x%x", num);
+
+		return ARCHIVE_FATAL;
+	}
+
+	return ARCHIVE_OK;
+}
+
+/* Binary search for the RARv5 signature. */
+static int scan_for_signature(struct archive_read* a) {
+	const uint8_t* p;
+	const int chunk_size = 512;
+	ssize_t i;
+	char signature[sizeof(rar5_signature_xor)];
+
+	/* If we're here, it means we're on an 'unknown territory' data.
+	 * There's no indication what kind of data we're reading here.
+	 * It could be some text comment, any kind of binary data,
+	 * digital sign, dragons, etc.
+	 *
+	 * We want to find a valid RARv5 magic header inside this unknown
+	 * data. */
+
+	/* Is it possible in libarchive to just skip everything until the
+	 * end of the file? If so, it would be a better approach than the
+	 * current implementation of this function. */
+
+	rar5_signature(signature);
+
+	while(1) {
+		if(!read_ahead(a, chunk_size, &p))
+			return ARCHIVE_EOF;
+
+		for(i = 0; i < chunk_size - (int)sizeof(rar5_signature_xor);
+		    i++) {
+			if(memcmp(&p[i], signature,
+			    sizeof(rar5_signature_xor)) == 0) {
+				/* Consume the number of bytes we've used to
+				 * search for the signature, as well as the
+				 * number of bytes used by the signature
+				 * itself. After this we should be standing
+				 * on a valid base block header. */
+				(void) consume(a,
+				    i + sizeof(rar5_signature_xor));
+				return ARCHIVE_OK;
+			}
+		}
+
+		consume(a, chunk_size);
+	}
+
+	return ARCHIVE_FATAL;
+}
+
+/* This function will switch the multivolume archive file to another file,
+ * i.e. from part03 to part 04. */
+static int advance_multivolume(struct archive_read* a) {
+	int lret;
+	struct rar5* rar = get_context(a);
+
+	/* A small state machine that will skip unnecessary data, needed to
+	 * switch from one multivolume to another. Such skipping is needed if
+	 * we want to be an stream-oriented (instead of file-oriented)
+	 * unpacker.
+	 *
+	 * The state machine starts with `rar->main.endarc` == 0. It also
+	 * assumes that current stream pointer points to some base block
+	 * header.
+	 *
+	 * The `endarc` field is being set when the base block parsing
+	 * function encounters the 'end of archive' marker.
+	 */
+
+	while(1) {
+		if(rar->main.endarc == 1) {
+			int looping = 1;
+
+			rar->main.endarc = 0;
+
+			while(looping) {
+				lret = skip_base_block(a);
+				switch(lret) {
+					case ARCHIVE_RETRY:
+						/* Continue looping. */
+						break;
+					case ARCHIVE_OK:
+						/* Break loop. */
+						looping = 0;
+						break;
+					default:
+						/* Forward any errors to the
+						 * caller. */
+						return lret;
+				}
+			}
+
+			break;
+		} else {
+			/* Skip current base block. In order to properly skip
+			 * it, we really need to simply parse it and discard
+			 * the results. */
+
+			lret = skip_base_block(a);
+			if(lret == ARCHIVE_FATAL || lret == ARCHIVE_FAILED)
+				return lret;
+
+			/* The `skip_base_block` function tells us if we
+			 * should continue with skipping, or we should stop
+			 * skipping. We're trying to skip everything up to
+			 * a base FILE block. */
+
+			if(lret != ARCHIVE_RETRY) {
+				/* If there was an error during skipping, or we
+				 * have just skipped a FILE base block... */
+
+				if(rar->main.endarc == 0) {
+					return lret;
+				} else {
+					continue;
+				}
+			}
+		}
+	}
+
+	return ARCHIVE_OK;
+}
+
+/* Merges the partial block from the first multivolume archive file, and
+ * partial block from the second multivolume archive file. The result is
+ * a chunk of memory containing the whole block, and the stream pointer
+ * is advanced to the next block in the second multivolume archive file. */
+static int merge_block(struct archive_read* a, ssize_t block_size,
+    const uint8_t** p)
+{
+	struct rar5* rar = get_context(a);
+	ssize_t cur_block_size, partial_offset = 0;
+	const uint8_t* lp;
+	int ret;
+
+	if(rar->merge_mode) {
+		archive_set_error(&a->archive, ARCHIVE_ERRNO_PROGRAMMER,
+		    "Recursive merge is not allowed");
+
+		return ARCHIVE_FATAL;
+	}
+
+	/* Set a flag that we're in the switching mode. */
+	rar->cstate.switch_multivolume = 1;
+
+	/* Reallocate the memory which will hold the whole block. */
+	if(rar->vol.push_buf)
+		free((void*) rar->vol.push_buf);
+
+	/* Increasing the allocation block by 8 is due to bit reading functions,
+	 * which are using additional 2 or 4 bytes. Allocating the block size
+	 * by exact value would make bit reader perform reads from invalid
+	 * memory block when reading the last byte from the buffer. */
+	rar->vol.push_buf = malloc(block_size + 8);
+	if(!rar->vol.push_buf) {
+		archive_set_error(&a->archive, ENOMEM,
+		    "Can't allocate memory for a merge block buffer.");
+		return ARCHIVE_FATAL;
+	}
+
+	/* Valgrind complains if the extension block for bit reader is not
+	 * initialized, so initialize it. */
+	memset(&rar->vol.push_buf[block_size], 0, 8);
+
+	/* A single block can span across multiple multivolume archive files,
+	 * so we use a loop here. This loop will consume enough multivolume
+	 * archive files until the whole block is read. */
+
+	while(1) {
+		/* Get the size of current block chunk in this multivolume
+		 * archive file and read it. */
+		cur_block_size = rar5_min(rar->file.bytes_remaining,
+		    block_size - partial_offset);
+
+		if(cur_block_size == 0) {
+			archive_set_error(&a->archive,
+			    ARCHIVE_ERRNO_FILE_FORMAT,
+			    "Encountered block size == 0 during block merge");
+			return ARCHIVE_FATAL;
+		}
+
+		if(!read_ahead(a, cur_block_size, &lp))
+			return ARCHIVE_EOF;
+
+		/* Sanity check; there should never be a situation where this
+		 * function reads more data than the block's size. */
+		if(partial_offset + cur_block_size > block_size) {
+			archive_set_error(&a->archive,
+			    ARCHIVE_ERRNO_PROGRAMMER,
+			    "Consumed too much data when merging blocks.");
+			return ARCHIVE_FATAL;
+		}
+
+		/* Merge previous block chunk with current block chunk,
+		 * or create first block chunk if this is our first
+		 * iteration. */
+		memcpy(&rar->vol.push_buf[partial_offset], lp, cur_block_size);
+
+		/* Advance the stream read pointer by this block chunk size. */
+		if(ARCHIVE_OK != consume(a, cur_block_size))
+			return ARCHIVE_EOF;
+
+		/* Update the pointers. `partial_offset` contains information
+		 * about the sum of merged block chunks. */
+		partial_offset += cur_block_size;
+		rar->file.bytes_remaining -= cur_block_size;
+
+		/* If `partial_offset` is the same as `block_size`, this means
+		 * we've merged all block chunks and we have a valid full
+		 * block. */
+		if(partial_offset == block_size) {
+			break;
+		}
+
+		/* If we don't have any bytes to read, this means we should
+		 * switch to another multivolume archive file. */
+		if(rar->file.bytes_remaining == 0) {
+			rar->merge_mode++;
+			ret = advance_multivolume(a);
+			rar->merge_mode--;
+			if(ret != ARCHIVE_OK) {
+				return ret;
+			}
+		}
+	}
+
+	*p = rar->vol.push_buf;
+
+	/* If we're here, we can resume unpacking by processing the block
+	 * pointed to by the `*p` memory pointer. */
+
+	return ARCHIVE_OK;
+}
+
+static int process_block(struct archive_read* a) {
+	const uint8_t* p;
+	struct rar5* rar = get_context(a);
+	int ret;
+
+	/* If we don't have any data to be processed, this most probably means
+	 * we need to switch to the next volume. */
+	if(rar->main.volume && rar->file.bytes_remaining == 0) {
+		ret = advance_multivolume(a);
+		if(ret != ARCHIVE_OK)
+			return ret;
+	}
+
+	if(rar->cstate.block_parsing_finished) {
+		ssize_t block_size;
+		ssize_t to_skip;
+		ssize_t cur_block_size;
+
+		/* The header size won't be bigger than 6 bytes. */
+		if(!read_ahead(a, 6, &p)) {
+			/* Failed to prefetch data block header. */
+			return ARCHIVE_EOF;
+		}
+
+		/*
+		 * Read block_size by parsing block header. Validate the header
+		 * by calculating CRC byte stored inside the header. Size of
+		 * the header is not constant (block size can be stored either
+		 * in 1 or 2 bytes), that's why block size is left out from the
+		 * `compressed_block_header` structure and returned by
+		 * `parse_block_header` as the second argument. */
+
+		ret = parse_block_header(a, p, &block_size,
+		    &rar->last_block_hdr);
+		if(ret != ARCHIVE_OK) {
+			return ret;
+		}
+
+		/* Skip block header. Next data is huffman tables,
+		 * if present. */
+		to_skip = sizeof(struct compressed_block_header) +
+			bf_byte_count(&rar->last_block_hdr) + 1;
+
+		if(ARCHIVE_OK != consume(a, to_skip))
+			return ARCHIVE_EOF;
+
+		rar->file.bytes_remaining -= to_skip;
+
+		/* The block size gives information about the whole block size,
+		 * but the block could be stored in split form when using
+		 * multi-volume archives. In this case, the block size will be
+		 * bigger than the actual data stored in this file. Remaining
+		 * part of the data will be in another file. */
+
+		cur_block_size =
+			rar5_min(rar->file.bytes_remaining, block_size);
+
+		if(block_size > rar->file.bytes_remaining) {
+			/* If current blocks' size is bigger than our data
+			 * size, this means we have a multivolume archive.
+			 * In this case, skip all base headers until the end
+			 * of the file, proceed to next "partXXX.rar" volume,
+			 * find its signature, skip all headers up to the first
+			 * FILE base header, and continue from there.
+			 *
+			 * Note that `merge_block` will update the `rar`
+			 * context structure quite extensively. */
+
+			ret = merge_block(a, block_size, &p);
+			if(ret != ARCHIVE_OK) {
+				return ret;
+			}
+
+			cur_block_size = block_size;
+
+			/* Current stream pointer should be now directly
+			 * *after* the block that spanned through multiple
+			 * archive files. `p` pointer should have the data of
+			 * the *whole* block (merged from partial blocks
+			 * stored in multiple archives files). */
+		} else {
+			rar->cstate.switch_multivolume = 0;
+
+			/* Read the whole block size into memory. This can take
+			 * up to  8 megabytes of memory in theoretical cases.
+			 * Might be worth to optimize this and use a standard
+			 * chunk of 4kb's. */
+			if(!read_ahead(a, 4 + cur_block_size, &p)) {
+				/* Failed to prefetch block data. */
+				return ARCHIVE_EOF;
+			}
+		}
+
+		rar->cstate.block_buf = p;
+		rar->cstate.cur_block_size = cur_block_size;
+		rar->cstate.block_parsing_finished = 0;
+
+		rar->bits.in_addr = 0;
+		rar->bits.bit_addr = 0;
+
+		if(bf_is_table_present(&rar->last_block_hdr)) {
+			/* Load Huffman tables. */
+			ret = parse_tables(a, rar, p);
+			if(ret != ARCHIVE_OK) {
+				/* Error during decompression of Huffman
+				 * tables. */
+				return ret;
+			}
+		}
+	} else {
+		/* Block parsing not finished, reuse previous memory buffer. */
+		p = rar->cstate.block_buf;
+	}
+
+	/* Uncompress the block, or a part of it, depending on how many bytes
+	 * will be generated by uncompressing the block.
+	 *
+	 * In case too many bytes will be generated, calling this function
+	 * again will resume the uncompression operation. */
+	ret = do_uncompress_block(a, p);
+	if(ret != ARCHIVE_OK) {
+		return ret;
+	}
+
+	if(rar->cstate.block_parsing_finished &&
+	    rar->cstate.switch_multivolume == 0 &&
+	    rar->cstate.cur_block_size > 0)
+	{
+		/* If we're processing a normal block, consume the whole
+		 * block. We can do this because we've already read the whole
+		 * block to memory. */
+		if(ARCHIVE_OK != consume(a, rar->cstate.cur_block_size))
+			return ARCHIVE_FATAL;
+
+		rar->file.bytes_remaining -= rar->cstate.cur_block_size;
+	} else if(rar->cstate.switch_multivolume) {
+		/* Don't consume the block if we're doing multivolume
+		 * processing. The volume switching function will consume
+		 * the proper count of bytes instead. */
+		rar->cstate.switch_multivolume = 0;
+	}
+
+	return ARCHIVE_OK;
+}
+
+/* Pops the `buf`, `size` and `offset` from the "data ready" stack.
+ *
+ * Returns ARCHIVE_OK when those arguments can be used, ARCHIVE_RETRY
+ * when there is no data on the stack. */
+static int use_data(struct rar5* rar, const void** buf, size_t* size,
+    int64_t* offset)
+{
+	int i;
+
+	for(i = 0; i < rar5_countof(rar->cstate.dready); i++) {
+		struct data_ready *d = &rar->cstate.dready[i];
+
+		if(d->used) {
+			if(buf)    *buf = d->buf;
+			if(size)   *size = d->size;
+			if(offset) *offset = d->offset;
+
+			d->used = 0;
+			return ARCHIVE_OK;
+		}
+	}
+
+	return ARCHIVE_RETRY;
+}
+
+/* Pushes the `buf`, `size` and `offset` arguments to the rar->cstate.dready
+ * FIFO stack. Those values will be popped from this stack by the `use_data`
+ * function. */
+static int push_data_ready(struct archive_read* a, struct rar5* rar,
+    const uint8_t* buf, size_t size, int64_t offset)
+{
+	int i;
+
+	/* Don't push if we're in skip mode. This is needed because solid
+	 * streams need full processing even if we're skipping data. After
+	 * fully processing the stream, we need to discard the generated bytes,
+	 * because we're interested only in the side effect: building up the
+	 * internal window circular buffer. This window buffer will be used
+	 * later during unpacking of requested data. */
+	if(rar->skip_mode)
+		return ARCHIVE_OK;
+
+	/* Sanity check. */
+	if(offset != rar->file.last_offset + rar->file.last_size) {
+		archive_set_error(&a->archive, ARCHIVE_ERRNO_PROGRAMMER,
+		    "Sanity check error: output stream is not continuous");
+		return ARCHIVE_FATAL;
+	}
+
+	for(i = 0; i < rar5_countof(rar->cstate.dready); i++) {
+		struct data_ready* d = &rar->cstate.dready[i];
+		if(!d->used) {
+			d->used = 1;
+			d->buf = buf;
+			d->size = size;
+			d->offset = offset;
+
+			/* These fields are used only in sanity checking. */
+			rar->file.last_offset = offset;
+			rar->file.last_size = size;
+
+			/* Calculate the checksum of this new block before
+			 * submitting data to libarchive's engine. */
+			update_crc(rar, d->buf, d->size);
+
+			return ARCHIVE_OK;
+		}
+	}
+
+	/* Program counter will reach this code if the `rar->cstate.data_ready`
+	 * stack will be filled up so that no new entries will be allowed. The
+	 * code shouldn't allow such situation to occur. So we treat this case
+	 * as an internal error. */
+
+	archive_set_error(&a->archive, ARCHIVE_ERRNO_PROGRAMMER,
+	    "Error: premature end of data_ready stack");
+	return ARCHIVE_FATAL;
+}
+
+/* This function uncompresses the data that is stored in the <FILE> base
+ * block.
+ *
+ * The FILE base block looks like this:
+ *
+ * <header><huffman tables><block_1><block_2>...<block_n>
+ *
+ * The <header> is a block header, that is parsed in parse_block_header().
+ * It's a "compressed_block_header" structure, containing metadata needed
+ * to know when we should stop looking for more <block_n> blocks.
+ *
+ * <huffman tables> contain data needed to set up the huffman tables, needed
+ * for the actual decompression.
+ *
+ * Each <block_n> consists of series of literals:
+ *
+ * <literal><literal><literal>...<literal>
+ *
+ * Those literals generate the uncompression data. They operate on a circular
+ * buffer, sometimes writing raw data into it, sometimes referencing
+ * some previous data inside this buffer, and sometimes declaring a filter
+ * that will need to be executed on the data stored in the circular buffer.
+ * It all depends on the literal that is used.
+ *
+ * Sometimes blocks produce output data, sometimes they don't. For example, for
+ * some huge files that use lots of filters, sometimes a block is filled with
+ * only filter declaration literals. Such blocks won't produce any data in the
+ * circular buffer.
+ *
+ * Sometimes blocks will produce 4 bytes of data, and sometimes 1 megabyte,
+ * because a literal can reference previously decompressed data. For example,
+ * there can be a literal that says: 'append a byte 0xFE here', and after
+ * it another literal can say 'append 1 megabyte of data from circular buffer
+ * offset 0x12345'. This is how RAR format handles compressing repeated
+ * patterns.
+ *
+ * The RAR compressor creates those literals and the actual efficiency of
+ * compression depends on what those literals are. The literals can also
+ * be seen as a kind of a non-turing-complete virtual machine that simply
+ * tells the decompressor what it should do.
+ * */
+
+static int do_uncompress_file(struct archive_read* a) {
+	struct rar5* rar = get_context(a);
+	int ret;
+	int64_t max_end_pos;
+
+	if(!rar->cstate.initialized) {
+		/* Don't perform full context reinitialization if we're
+		 * processing a solid archive. */
+		if(!rar->main.solid || !rar->cstate.window_buf) {
+			init_unpack(rar);
+		}
+
+		rar->cstate.initialized = 1;
+	}
+
+	if(rar->cstate.all_filters_applied == 1) {
+		/* We use while(1) here, but standard case allows for just 1
+		 * iteration. The loop will iterate if process_block() didn't
+		 * generate any data at all. This can happen if the block
+		 * contains only filter definitions (this is common in big
+		 * files). */
+		while(1) {
+			ret = process_block(a);
+			if(ret == ARCHIVE_EOF || ret == ARCHIVE_FATAL)
+				return ret;
+
+			if(rar->cstate.last_write_ptr ==
+			    rar->cstate.write_ptr) {
+				/* The block didn't generate any new data,
+				 * so just process a new block. */
+				continue;
+			}
+
+			/* The block has generated some new data, so break
+			 * the loop. */
+			break;
+		}
+	}
+
+	/* Try to run filters. If filters won't be applied, it means that
+	 * insufficient data was generated. */
+	ret = apply_filters(a);
+	if(ret == ARCHIVE_RETRY) {
+		return ARCHIVE_OK;
+	} else if(ret == ARCHIVE_FATAL) {
+		return ARCHIVE_FATAL;
+	}
+
+	/* If apply_filters() will return ARCHIVE_OK, we can continue here. */
+
+	if(cdeque_size(&rar->cstate.filters) > 0) {
+		/* Check if we can write something before hitting first
+		 * filter. */
+		struct filter_info* flt;
+
+		/* Get the block_start offset from the first filter. */
+		if(CDE_OK != cdeque_front(&rar->cstate.filters,
+		    cdeque_filter_p(&flt)))
+		{
+			archive_set_error(&a->archive,
+			    ARCHIVE_ERRNO_PROGRAMMER,
+			    "Can't read first filter");
+			return ARCHIVE_FATAL;
+		}
+
+		max_end_pos = rar5_min(flt->block_start,
+		    rar->cstate.write_ptr);
+	} else {
+		/* There are no filters defined, or all filters were applied.
+		 * This means we can just store the data without any
+		 * postprocessing. */
+		max_end_pos = rar->cstate.write_ptr;
+	}
+
+	if(max_end_pos == rar->cstate.last_write_ptr) {
+		/* We can't write anything yet. The block uncompression
+		 * function did not generate enough data, and no filter can be
+		 * applied. At the same time we don't have any data that can be
+		 *  stored without filter postprocessing. This means we need to
+		 *  wait for more data to be generated, so we can apply the
+		 * filters.
+		 *
+		 * Signal the caller that we need more data to be able to do
+		 * anything.
+		 */
+		return ARCHIVE_RETRY;
+	} else {
+		/* We can write the data before hitting the first filter.
+		 * So let's do it. The push_window_data() function will
+		 * effectively return the selected data block to the user
+		 * application. */
+		push_window_data(a, rar, rar->cstate.last_write_ptr,
+		    max_end_pos);
+		rar->cstate.last_write_ptr = max_end_pos;
+	}
+
+	return ARCHIVE_OK;
+}
+
+static int uncompress_file(struct archive_read* a) {
+	int ret;
+
+	while(1) {
+		/* Sometimes the uncompression function will return a
+		 * 'retry' signal. If this will happen, we have to retry
+		 * the function. */
+		ret = do_uncompress_file(a);
+		if(ret != ARCHIVE_RETRY)
+			return ret;
+	}
+}
+
+
+static int do_unstore_file(struct archive_read* a,
+    struct rar5* rar, const void** buf, size_t* size, int64_t* offset)
+{
+	size_t to_read;
+	const uint8_t* p;
+
+	if(rar->file.bytes_remaining == 0 && rar->main.volume > 0 &&
+	    rar->generic.split_after > 0)
+	{
+		int ret;
+
+		rar->cstate.switch_multivolume = 1;
+		ret = advance_multivolume(a);
+		rar->cstate.switch_multivolume = 0;
+
+		if(ret != ARCHIVE_OK) {
+			/* Failed to advance to next multivolume archive
+			 * file. */
+			return ret;
+		}
+	}
+
+	to_read = rar5_min(rar->file.bytes_remaining, 64 * 1024);
+	if(to_read == 0) {
+		return ARCHIVE_EOF;
+	}
+
+	if(!read_ahead(a, to_read, &p)) {
+		archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+		    "I/O error when unstoring file");
+		return ARCHIVE_FATAL;
+	}
+
+	if(ARCHIVE_OK != consume(a, to_read)) {
+		return ARCHIVE_EOF;
+	}
+
+	if(buf)    *buf = p;
+	if(size)   *size = to_read;
+	if(offset) *offset = rar->cstate.last_unstore_ptr;
+
+	rar->file.bytes_remaining -= to_read;
+	rar->cstate.last_unstore_ptr += to_read;
+
+	update_crc(rar, p, to_read);
+	return ARCHIVE_OK;
+}
+
+static int do_unpack(struct archive_read* a, struct rar5* rar,
+    const void** buf, size_t* size, int64_t* offset)
+{
+	enum COMPRESSION_METHOD {
+		STORE = 0, FASTEST = 1, FAST = 2, NORMAL = 3, GOOD = 4,
+		BEST = 5
+	};
+
+	if(rar->file.service > 0) {
+		return do_unstore_file(a, rar, buf, size, offset);
+	} else {
+		switch(rar->cstate.method) {
+			case STORE:
+				return do_unstore_file(a, rar, buf, size,
+				    offset);
+			case FASTEST:
+				/* fallthrough */
+			case FAST:
+				/* fallthrough */
+			case NORMAL:
+				/* fallthrough */
+			case GOOD:
+				/* fallthrough */
+			case BEST:
+				return uncompress_file(a);
+			default:
+				archive_set_error(&a->archive,
+				    ARCHIVE_ERRNO_FILE_FORMAT,
+				    "Compression method not supported: 0x%x",
+				    rar->cstate.method);
+
+				return ARCHIVE_FATAL;
+		}
+	}
+
+#if !defined WIN32
+	/* Not reached. */
+	return ARCHIVE_OK;
+#endif
+}
+
+static int verify_checksums(struct archive_read* a) {
+	int verify_crc;
+	struct rar5* rar = get_context(a);
+
+	/* Check checksums only when actually unpacking the data. There's no
+	 * need to calculate checksum when we're skipping data in solid archives
+	 * (skipping in solid archives is the same thing as unpacking compressed
+	 * data and discarding the result). */
+
+	if(!rar->skip_mode) {
+		/* Always check checksums if we're not in skip mode */
+		verify_crc = 1;
+	} else {
+		/* We can override the logic above with a compile-time option
+		 * NO_CRC_ON_SOLID_SKIP. This option is used during debugging,
+		 * and it will check checksums of unpacked data even when
+		 * we're skipping it. */
+
+#if defined CHECK_CRC_ON_SOLID_SKIP
+		/* Debug case */
+		verify_crc = 1;
+#else
+		/* Normal case */
+		verify_crc = 0;
+#endif
+	}
+
+	if(verify_crc) {
+		/* During unpacking, on each unpacked block we're calling the
+		 * update_crc() function. Since we are here, the unpacking
+		 * process is already over and we can check if calculated
+		 * checksum (CRC32 or BLAKE2sp) is the same as what is stored
+		 * in the archive. */
+		if(rar->file.stored_crc32 > 0) {
+			/* Check CRC32 only when the file contains a CRC32
+			 * value for this file. */
+
+			if(rar->file.calculated_crc32 !=
+			    rar->file.stored_crc32) {
+				/* Checksums do not match; the unpacked file
+				 * is corrupted. */
+
+				DEBUG_CODE {
+					printf("Checksum error: CRC32 "
+					    "(was: %08x, expected: %08x)\n",
+					    rar->file.calculated_crc32,
+					    rar->file.stored_crc32);
+				}
+
+#ifndef DONT_FAIL_ON_CRC_ERROR
+				archive_set_error(&a->archive,
+				    ARCHIVE_ERRNO_FILE_FORMAT,
+				    "Checksum error: CRC32");
+				return ARCHIVE_FATAL;
+#endif
+			} else {
+				DEBUG_CODE {
+					printf("Checksum OK: CRC32 "
+					    "(%08x/%08x)\n",
+					    rar->file.stored_crc32,
+					    rar->file.calculated_crc32);
+				}
+			}
+		}
+
+		if(rar->file.has_blake2 > 0) {
+			/* BLAKE2sp is an optional checksum algorithm that is
+			 * added to RARv5 archives when using the `-htb` switch
+			 *  during creation of archive.
+			 *
+			 * We now finalize the hash calculation by calling the
+			 * `final` function. This will generate the final hash
+			 * value we can use to compare it with the BLAKE2sp
+			 * checksum that is stored in the archive.
+			 *
+			 * The return value of this `final` function is not
+			 * very helpful, as it guards only against improper use.
+ 			 * This is why we're explicitly ignoring it. */
+
+			uint8_t b2_buf[32];
+			(void) blake2sp_final(&rar->file.b2state, b2_buf, 32);
+
+			if(memcmp(&rar->file.blake2sp, b2_buf, 32) != 0) {
+#ifndef DONT_FAIL_ON_CRC_ERROR
+				archive_set_error(&a->archive,
+				    ARCHIVE_ERRNO_FILE_FORMAT,
+				    "Checksum error: BLAKE2");
+
+				return ARCHIVE_FATAL;
+#endif
+			}
+		}
+	}
+
+	/* Finalization for this file has been successfully completed. */
+	return ARCHIVE_OK;
+}
+
+static int verify_global_checksums(struct archive_read* a) {
+	return verify_checksums(a);
+}
+
+/*
+ * Decryption function for the magic signature pattern. Check the comment near
+ * the `rar5_signature_xor` symbol to read the rationale behind this.
+ */
+static void rar5_signature(char *buf) {
+		size_t i;
+
+		for(i = 0; i < sizeof(rar5_signature_xor); i++) {
+			buf[i] = rar5_signature_xor[i] ^ 0xA1;
+		}
+}
+
+static int rar5_read_data(struct archive_read *a, const void **buff,
+    size_t *size, int64_t *offset) {
+	int ret;
+	struct rar5* rar = get_context(a);
+
+	if(rar->file.dir > 0) {
+		/* Don't process any data if this file entry was declared
+		 * as a directory. This is needed, because entries marked as
+		 * directory doesn't have any dictionary buffer allocated, so
+		 * it's impossible to perform any decompression. */
+		archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+		    "Can't decompress an entry marked as a directory");
+		return ARCHIVE_FAILED;
+	}
+
+	if(!rar->skip_mode && (rar->cstate.last_write_ptr > rar->file.unpacked_size)) {
+		archive_set_error(&a->archive, ARCHIVE_ERRNO_PROGRAMMER,
+		    "Unpacker has written too many bytes");
+		return ARCHIVE_FATAL;
+	}
+
+	ret = use_data(rar, buff, size, offset);
+	if(ret == ARCHIVE_OK) {
+		return ret;
+	}
+
+	if(rar->file.eof == 1) {
+		return ARCHIVE_EOF;
+	}
+
+	ret = do_unpack(a, rar, buff, size, offset);
+	if(ret != ARCHIVE_OK) {
+		return ret;
+	}
+
+	if(rar->file.bytes_remaining == 0 &&
+			rar->cstate.last_write_ptr == rar->file.unpacked_size)
+	{
+		/* If all bytes of current file were processed, run
+		 * finalization.
+		 *
+		 * Finalization will check checksum against proper values. If
+		 * some of the checksums will not match, we'll return an error
+		 * value in the last `archive_read_data` call to signal an error
+		 * to the user. */
+
+		rar->file.eof = 1;
+		return verify_global_checksums(a);
+	}
+
+	return ARCHIVE_OK;
+}
+
+static int rar5_read_data_skip(struct archive_read *a) {
+	struct rar5* rar = get_context(a);
+
+	if(rar->main.solid) {
+		/* In solid archives, instead of skipping the data, we need to
+		 * extract it, and dispose the result. The side effect of this
+		 * operation will be setting up the initial window buffer state
+		 * needed to be able to extract the selected file. */
+
+		int ret;
+
+		/* Make sure to process all blocks in the compressed stream. */
+		while(rar->file.bytes_remaining > 0) {
+			/* Setting the "skip mode" will allow us to skip
+			 * checksum checks during data skipping. Checking the
+			 * checksum of skipped data isn't really necessary and
+			 * it's only slowing things down.
+			 *
+			 * This is incremented instead of setting to 1 because
+			 * this data skipping function can be called
+			 * recursively. */
+			rar->skip_mode++;
+
+			/* We're disposing 1 block of data, so we use triple
+			 * NULLs in arguments. */
+			ret = rar5_read_data(a, NULL, NULL, NULL);
+
+			/* Turn off "skip mode". */
+			rar->skip_mode--;
+
+			if(ret < 0 || ret == ARCHIVE_EOF) {
+				/* Propagate any potential error conditions
+				 * to the caller. */
+				return ret;
+			}
+		}
+	} else {
+		/* In standard archives, we can just jump over the compressed
+		 * stream. Each file in non-solid archives starts from an empty
+		 * window buffer. */
+
+		if(ARCHIVE_OK != consume(a, rar->file.bytes_remaining)) {
+			return ARCHIVE_FATAL;
+		}
+
+		rar->file.bytes_remaining = 0;
+	}
+
+	return ARCHIVE_OK;
+}
+
+static int64_t rar5_seek_data(struct archive_read *a, int64_t offset,
+    int whence)
+{
+	(void) a;
+	(void) offset;
+	(void) whence;
+
+	/* We're a streaming unpacker, and we don't support seeking. */
+
+	return ARCHIVE_FATAL;
+}
+
+static int rar5_cleanup(struct archive_read *a) {
+	struct rar5* rar = get_context(a);
+
+	free(rar->cstate.window_buf);
+	free(rar->cstate.filtered_buf);
+
+	free(rar->vol.push_buf);
+
+	free_filters(rar);
+	cdeque_free(&rar->cstate.filters);
+
+	free(rar);
+	a->format->data = NULL;
+
+	return ARCHIVE_OK;
+}
+
+static int rar5_capabilities(struct archive_read * a) {
+	(void) a;
+	return 0;
+}
+
+static int rar5_has_encrypted_entries(struct archive_read *_a) {
+	(void) _a;
+
+	/* Unsupported for now. */
+	return ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED;
+}
+
+static int rar5_init(struct rar5* rar) {
+	memset(rar, 0, sizeof(struct rar5));
+
+	if(CDE_OK != cdeque_init(&rar->cstate.filters, 8192))
+		return ARCHIVE_FATAL;
+
+	return ARCHIVE_OK;
+}
+
+int archive_read_support_format_rar5(struct archive *_a) {
+	struct archive_read* ar;
+	int ret;
+	struct rar5* rar;
+
+	if(ARCHIVE_OK != (ret = get_archive_read(_a, &ar)))
+		return ret;
+
+	rar = malloc(sizeof(*rar));
+	if(rar == NULL) {
+		archive_set_error(&ar->archive, ENOMEM,
+		    "Can't allocate rar5 data");
+		return ARCHIVE_FATAL;
+	}
+
+	if(ARCHIVE_OK != rar5_init(rar)) {
+		archive_set_error(&ar->archive, ENOMEM,
+		    "Can't allocate rar5 filter buffer");
+		return ARCHIVE_FATAL;
+	}
+
+	ret = __archive_read_register_format(ar,
+	    rar,
+	    "rar5",
+	    rar5_bid,
+	    rar5_options,
+	    rar5_read_header,
+	    rar5_read_data,
+	    rar5_read_data_skip,
+	    rar5_seek_data,
+	    rar5_cleanup,
+	    rar5_capabilities,
+	    rar5_has_encrypted_entries);
+
+	if(ret != ARCHIVE_OK) {
+		(void) rar5_cleanup(ar);
+	}
+
+	return ret;
+}
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_support_format_raw.c b/Utilities/cmlibarchive/libarchive/archive_read_support_format_raw.c
index efa2c6a..ec0520b 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_support_format_raw.c
+++ b/Utilities/cmlibarchive/libarchive/archive_read_support_format_raw.c
@@ -120,7 +120,9 @@
 	archive_entry_set_filetype(entry, AE_IFREG);
 	archive_entry_set_perm(entry, 0644);
 	/* I'm deliberately leaving most fields unset here. */
-	return (ARCHIVE_OK);
+
+	/* Let the filter fill out any fields it might have. */
+	return __archive_read_header(a, entry);
 }
 
 static int
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_support_format_tar.c b/Utilities/cmlibarchive/libarchive/archive_read_support_format_tar.c
index 60800bb..c63d46f 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_support_format_tar.c
+++ b/Utilities/cmlibarchive/libarchive/archive_read_support_format_tar.c
@@ -694,11 +694,13 @@
     struct archive_entry *entry, size_t *unconsumed)
 {
 	ssize_t bytes;
-	int err;
+	int err, eof_vol_header;
 	const char *h;
 	const struct archive_entry_header_ustar *header;
 	const struct archive_entry_header_gnutar *gnuheader;
 
+	eof_vol_header = 0;
+
 	/* Loop until we find a workable header record. */
 	for (;;) {
 		tar_flush_unconsumed(a, unconsumed);
@@ -788,6 +790,8 @@
 		break;
 	case 'V': /* GNU volume header */
 		err = header_volume(a, tar, entry, h, unconsumed);
+		if (err == ARCHIVE_EOF)
+			eof_vol_header = 1;
 		break;
 	case 'X': /* Used by SUN tar; same as 'x'. */
 		a->archive.archive_format = ARCHIVE_FORMAT_TAR_PAX_INTERCHANGE;
@@ -862,9 +866,17 @@
 		}
 		return (err);
 	}
-	if (err == ARCHIVE_EOF)
-		/* EOF when recursively reading a header is bad. */
-		archive_set_error(&a->archive, EINVAL, "Damaged tar archive");
+	if (err == ARCHIVE_EOF) {
+		if (!eof_vol_header) {
+			/* EOF when recursively reading a header is bad. */
+			archive_set_error(&a->archive, EINVAL,
+			    "Damaged tar archive");
+		} else {
+			/* If we encounter just a GNU volume header treat
+			 * this situation as an empty archive */
+			return (ARCHIVE_EOF);
+		}
+	}
 	return (ARCHIVE_FATAL);
 }
 
@@ -1942,6 +1954,15 @@
 			pax_time(value, &s, &n);
 			archive_entry_set_birthtime(entry, s, n);
 		}
+		if (strcmp(key, "LIBARCHIVE.symlinktype") == 0) {
+			if (strcmp(value, "file") == 0) {
+				archive_entry_set_symlink_type(entry,
+				    AE_SYMLINK_TYPE_FILE);
+			} else if (strcmp(value, "dir") == 0) {
+				archive_entry_set_symlink_type(entry,
+				    AE_SYMLINK_TYPE_DIRECTORY);
+			}
+		}
 		if (memcmp(key, "LIBARCHIVE.xattr.", 17) == 0)
 			pax_attribute_xattr(entry, key, value);
 		break;
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_support_format_warc.c b/Utilities/cmlibarchive/libarchive/archive_read_support_format_warc.c
index e875385..72977b8 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_support_format_warc.c
+++ b/Utilities/cmlibarchive/libarchive/archive_read_support_format_warc.c
@@ -386,6 +386,11 @@
 		return (ARCHIVE_EOF);
 	}
 
+	if (w->unconsumed) {
+		__archive_read_consume(a, w->unconsumed);
+		w->unconsumed = 0U;
+	}
+
 	rab = __archive_read_ahead(a, 1U, &nrd);
 	if (nrd < 0) {
 		*bsz = 0U;
@@ -621,7 +626,8 @@
 		if (ver >= 1200U) {
 			if (memcmp(c, "\r\n", 2U) != 0)
 				ver = 0U;
-		} else if (ver < 1200U) {
+		} else {
+			/* ver < 1200U */
 			if (*c != ' ' && *c != '\t')
 				ver = 0U;
 		}
@@ -739,8 +745,9 @@
 	/* there must be at least one digit */
 	if (!isdigit((unsigned char)*val))
 		return -1;
+	errno = 0;
 	len = strtol(val, &on, 10);
-	if (on != eol) {
+	if (errno != 0 || on != eol) {
 		/* line must end here */
 		return -1;
 	}
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_support_format_xar.c b/Utilities/cmlibarchive/libarchive/archive_read_support_format_xar.c
index 9292ed7..9489e51 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_support_format_xar.c
+++ b/Utilities/cmlibarchive/libarchive/archive_read_support_format_xar.c
@@ -39,13 +39,13 @@
 #include <expat.h>
 #endif
 #ifdef HAVE_BZLIB_H
-#include <cm_bzlib.h>
+#include <cm3p/bzlib.h>
 #endif
 #if HAVE_LZMA_H
-#include <cm_lzma.h>
+#include <cm3p/lzma.h>
 #endif
 #ifdef HAVE_ZLIB_H
-#include <cm_zlib.h>
+#include <cm3p/zlib.h>
 #endif
 
 #include "archive.h"
@@ -167,6 +167,9 @@
 #define HAS_FFLAGS		0x01000
 #define HAS_XATTR		0x02000
 #define HAS_ACL			0x04000
+#define HAS_CTIME		0x08000
+#define HAS_MTIME		0x10000
+#define HAS_ATIME		0x20000
 
 	uint64_t		 id;
 	uint64_t		 length;
@@ -695,9 +698,15 @@
 		 */
 		file_free(file);
 	}
-	archive_entry_set_atime(entry, file->atime, 0);
-	archive_entry_set_ctime(entry, file->ctime, 0);
-	archive_entry_set_mtime(entry, file->mtime, 0);
+        if (file->has & HAS_ATIME) {
+          archive_entry_set_atime(entry, file->atime, 0);
+        }
+        if (file->has & HAS_CTIME) {
+          archive_entry_set_ctime(entry, file->ctime, 0);
+        }
+        if (file->has & HAS_MTIME) {
+          archive_entry_set_mtime(entry, file->mtime, 0);
+        }
 	archive_entry_set_gid(entry, file->gid);
 	if (file->gname.length > 0 &&
 	    archive_entry_copy_gname_l(entry, file->gname.s,
@@ -789,7 +798,8 @@
 	xattr = file->xattr_list;
 	while (xattr != NULL) {
 		const void *d;
-		size_t outbytes, used;
+		size_t outbytes = 0;
+		size_t used = 0;
 
 		r = move_reading_point(a, xattr->offset);
 		if (r != ARCHIVE_OK)
@@ -811,8 +821,18 @@
 		r = checksum_final(a,
 		    xattr->a_sum.val, xattr->a_sum.len,
 		    xattr->e_sum.val, xattr->e_sum.len);
-		if (r != ARCHIVE_OK)
+		if (r != ARCHIVE_OK) {
+			archive_set_error(&(a->archive), ARCHIVE_ERRNO_MISC,
+			    "Xattr checksum error");
+			r = ARCHIVE_WARN;
 			break;
+		}
+		if (xattr->name.s == NULL) {
+			archive_set_error(&(a->archive), ARCHIVE_ERRNO_MISC,
+			    "Xattr name error");
+			r = ARCHIVE_WARN;
+			break;
+		}
 		archive_entry_xattr_add_entry(entry,
 		    xattr->name.s, d, outbytes);
 		xattr = xattr->next;
@@ -838,7 +858,7 @@
     const void **buff, size_t *size, int64_t *offset)
 {
 	struct xar *xar;
-	size_t used;
+	size_t used = 0;
 	int r;
 
 	xar = (struct xar *)(a->format->data);
@@ -967,7 +987,7 @@
 				return ((int)step);
 			xar->offset += step;
 		} else {
-			int64_t pos = __archive_read_seek(a, offset, SEEK_SET);
+			int64_t pos = __archive_read_seek(a, xar->h_base + offset, SEEK_SET);
 			if (pos == ARCHIVE_FAILED) {
 				archive_set_error(&(a->archive),
 				    ARCHIVE_ERRNO_MISC,
@@ -1220,8 +1240,7 @@
 		}
 		memcpy(new_pending_files, heap->files,
 		    heap->allocated * sizeof(new_pending_files[0]));
-		if (heap->files != NULL)
-			free(heap->files);
+		free(heap->files);
 		heap->files = new_pending_files;
 		heap->allocated = new_size;
 	}
@@ -1767,8 +1786,8 @@
 	}
 	file->parent = xar->file;
 	file->mode = 0777 | AE_IFREG;
-	file->atime = time(NULL);
-	file->mtime = time(NULL);
+	file->atime =  0;
+	file->mtime = 0;
 	xar->file = file;
 	xar->xattr = NULL;
 	for (attr = list->first; attr != NULL; attr = attr->next) {
@@ -2594,15 +2613,14 @@
 	while (l > 0) {
 		int n = 0;
 
-		if (l > 0) {
-			if (base64[b[0]] < 0 || base64[b[1]] < 0)
-				break;
-			n = base64[*b++] << 18;
-			n |= base64[*b++] << 12;
-			*out++ = n >> 16;
-			len++;
-			l -= 2;
-		}
+		if (base64[b[0]] < 0 || base64[b[1]] < 0)
+			break;
+		n = base64[*b++] << 18;
+		n |= base64[*b++] << 12;
+		*out++ = n >> 16;
+		len++;
+		l -= 2;
+
 		if (l > 0) {
 			if (base64[*b] < 0)
 				break;
@@ -2751,15 +2769,15 @@
 		xar->file->uid = atol10(s, len);
 		break;
 	case FILE_CTIME:
-		xar->file->has |= HAS_TIME;
+		xar->file->has |= HAS_TIME | HAS_CTIME;
 		xar->file->ctime = parse_time(s, len);
 		break;
 	case FILE_MTIME:
-		xar->file->has |= HAS_TIME;
+		xar->file->has |= HAS_TIME | HAS_MTIME;
 		xar->file->mtime = parse_time(s, len);
 		break;
 	case FILE_ATIME:
-		xar->file->has |= HAS_TIME;
+		xar->file->has |= HAS_TIME | HAS_ATIME;
 		xar->file->atime = parse_time(s, len);
 		break;
 	case FILE_DATA_LENGTH:
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_support_format_zip.c b/Utilities/cmlibarchive/libarchive/archive_read_support_format_zip.c
index 7e99b12..4d71f98 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_support_format_zip.c
+++ b/Utilities/cmlibarchive/libarchive/archive_read_support_format_zip.c
@@ -50,7 +50,13 @@
 #include <stdlib.h>
 #endif
 #ifdef HAVE_ZLIB_H
-#include <cm_zlib.h>
+#include <cm3p/zlib.h>
+#endif
+#ifdef HAVE_BZLIB_H
+#include <bzlib.h>
+#endif
+#ifdef HAVE_LZMA_H
+#include <lzma.h>
 #endif
 
 #include "archive.h"
@@ -63,6 +69,7 @@
 #include "archive_private.h"
 #include "archive_rb.h"
 #include "archive_read_private.h"
+#include "archive_ppmd8_private.h"
 
 #ifndef HAVE_ZLIB_H
 #include "archive_crc32.h"
@@ -165,13 +172,30 @@
 	char			decompress_init;
 	char			end_of_entry;
 
-#ifdef HAVE_ZLIB_H
 	unsigned char 		*uncompressed_buffer;
 	size_t 			uncompressed_buffer_size;
+
+#ifdef HAVE_ZLIB_H
 	z_stream		stream;
 	char			stream_valid;
 #endif
 
+#if HAVE_LZMA_H && HAVE_LIBLZMA
+	lzma_stream		zipx_lzma_stream;
+	char            zipx_lzma_valid;
+#endif
+
+#ifdef HAVE_BZLIB_H
+	bz_stream		bzstream;
+	char            bzstream_valid;
+#endif
+
+	IByteIn			zipx_ppmd_stream;
+	ssize_t			zipx_ppmd_read_compressed;
+	CPpmd8			ppmd8;
+	char			ppmd8_valid;
+	char			ppmd8_stream_failed;
+
 	struct archive_string_conv *sconv;
 	struct archive_string_conv *sconv_default;
 	struct archive_string_conv *sconv_utf8;
@@ -222,6 +246,33 @@
 /* Many systems define min or MIN, but not all. */
 #define	zipmin(a,b) ((a) < (b) ? (a) : (b))
 
+/* This function is used by Ppmd8_DecodeSymbol during decompression of Ppmd8
+ * streams inside ZIP files. It has 2 purposes: one is to fetch the next
+ * compressed byte from the stream, second one is to increase the counter how
+ * many compressed bytes were read. */
+static Byte
+ppmd_read(void* p) {
+	/* Get the handle to current decompression context. */
+	struct archive_read *a = ((IByteIn*)p)->a;
+	struct zip *zip = (struct zip*) a->format->data;
+	ssize_t bytes_avail = 0;
+
+	/* Fetch next byte. */
+	const uint8_t* data = __archive_read_ahead(a, 1, &bytes_avail);
+	if(bytes_avail < 1) {
+		zip->ppmd8_stream_failed = 1;
+		return 0;
+	}
+
+	__archive_read_consume(a, 1);
+
+	/* Increment the counter. */
+	++zip->zipx_ppmd_read_compressed;
+
+	/* Return the next compressed byte. */
+	return data[0];
+}
+
 /* ------------------------------------------------------------------------ */
 
 /*
@@ -372,6 +423,8 @@
 	{17, "reserved"}, /* Reserved by PKWARE */
 	{18, "ibm-terse-new"}, /* File is compressed using IBM TERSE (new) */
 	{19, "ibm-lz777"},/* IBM LZ77 z Architecture (PFS) */
+	{95, "xz"},       /* XZ compressed data */
+	{96, "jpeg"},     /* JPEG compressed data */
 	{97, "wav-pack"}, /* WavPack compressed data */
 	{98, "ppmd-1"},   /* PPMd version I, Rev 1 */
 	{99, "aes"}       /* WinZip AES encryption  */
@@ -419,27 +472,49 @@
  *  triplets.  id and size are 2 bytes each.
  */
 static int
-process_extra(struct archive_read *a, const char *p, size_t extra_length, struct zip_entry* zip_entry)
+process_extra(struct archive_read *a, struct archive_entry *entry,
+     const char *p, size_t extra_length, struct zip_entry* zip_entry)
 {
 	unsigned offset = 0;
+	struct zip *zip = (struct zip *)(a->format->data);
 
 	if (extra_length == 0) {
 		return ARCHIVE_OK;
 	}
 
 	if (extra_length < 4) {
-		archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
-		    "Too-small extra data: Need at least 4 bytes, but only found %d bytes", (int)extra_length);
-		return ARCHIVE_FAILED;
+		size_t i = 0;
+		/* Some ZIP files may have trailing 0 bytes. Let's check they
+		 * are all 0 and ignore them instead of returning an error.
+		 *
+		 * This is not technically correct, but some ZIP files look
+		 * like this and other tools support those files - so let's
+		 * also  support them.
+		 */
+		for (; i < extra_length; i++) {
+			if (p[i] != 0) {
+				archive_set_error(&a->archive,
+				    ARCHIVE_ERRNO_FILE_FORMAT,
+				    "Too-small extra data: "
+				    "Need at least 4 bytes, "
+				    "but only found %d bytes",
+				    (int)extra_length);
+				return ARCHIVE_FAILED;
+			}
+		}
+
+		return ARCHIVE_OK;
 	}
+
 	while (offset <= extra_length - 4) {
 		unsigned short headerid = archive_le16dec(p + offset);
 		unsigned short datasize = archive_le16dec(p + offset + 2);
 
 		offset += 4;
 		if (offset + datasize > extra_length) {
-			archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
-			    "Extra data overflow: Need %d bytes but only found %d bytes",
+			archive_set_error(&a->archive,
+			    ARCHIVE_ERRNO_FILE_FORMAT, "Extra data overflow: "
+			    "Need %d bytes but only found %d bytes",
 			    (int)datasize, (int)(extra_length - offset));
 			return ARCHIVE_FAILED;
 		}
@@ -454,9 +529,12 @@
 			if (zip_entry->uncompressed_size == 0xffffffff) {
 				uint64_t t = 0;
 				if (datasize < 8
-				    || (t = archive_le64dec(p + offset)) > INT64_MAX) {
-					archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
-					    "Malformed 64-bit uncompressed size");
+				    || (t = archive_le64dec(p + offset)) >
+				    INT64_MAX) {
+					archive_set_error(&a->archive,
+					    ARCHIVE_ERRNO_FILE_FORMAT,
+					    "Malformed 64-bit "
+					    "uncompressed size");
 					return ARCHIVE_FAILED;
 				}
 				zip_entry->uncompressed_size = t;
@@ -466,9 +544,12 @@
 			if (zip_entry->compressed_size == 0xffffffff) {
 				uint64_t t = 0;
 				if (datasize < 8
-				    || (t = archive_le64dec(p + offset)) > INT64_MAX) {
-					archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
-					    "Malformed 64-bit compressed size");
+				    || (t = archive_le64dec(p + offset)) >
+				    INT64_MAX) {
+					archive_set_error(&a->archive,
+					    ARCHIVE_ERRNO_FILE_FORMAT,
+					    "Malformed 64-bit "
+					    "compressed size");
 					return ARCHIVE_FAILED;
 				}
 				zip_entry->compressed_size = t;
@@ -478,9 +559,12 @@
 			if (zip_entry->local_header_offset == 0xffffffff) {
 				uint64_t t = 0;
 				if (datasize < 8
-				    || (t = archive_le64dec(p + offset)) > INT64_MAX) {
-					archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
-					    "Malformed 64-bit local header offset");
+				    || (t = archive_le64dec(p + offset)) >
+				    INT64_MAX) {
+					archive_set_error(&a->archive,
+					    ARCHIVE_ERRNO_FILE_FORMAT,
+					    "Malformed 64-bit "
+					    "local header offset");
 					return ARCHIVE_FAILED;
 				}
 				zip_entry->local_header_offset = t;
@@ -513,7 +597,8 @@
 			/* Extended time field "UT". */
 			int flags;
 			if (datasize == 0) {
-				archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+				archive_set_error(&a->archive,
+				    ARCHIVE_ERRNO_FILE_FORMAT,
 				    "Incomplete extended time field");
 				return ARCHIVE_FAILED;
 			}
@@ -595,7 +680,8 @@
 			 *  if bitmap & 1, 2 byte "version made by"
 			 *  if bitmap & 2, 2 byte "internal file attributes"
 			 *  if bitmap & 4, 4 byte "external file attributes"
-			 *  if bitmap & 8, 2 byte comment length + n byte comment
+			 *  if bitmap & 8, 2 byte comment length + n byte
+			 *  comment
 			 */
 			int bitmap, bitmap_last;
 
@@ -646,13 +732,18 @@
 					    = external_attributes >> 16;
 				} else if (zip_entry->system == 0) {
 					// Interpret MSDOS directory bit
-					if (0x10 == (external_attributes & 0x10)) {
-						zip_entry->mode = AE_IFDIR | 0775;
+					if (0x10 == (external_attributes &
+					    0x10)) {
+						zip_entry->mode =
+						    AE_IFDIR | 0775;
 					} else {
-						zip_entry->mode = AE_IFREG | 0664;
+						zip_entry->mode =
+						    AE_IFREG | 0664;
 					}
-					if (0x01 == (external_attributes & 0x01)) {
-						// Read-only bit; strip write permissions
+					if (0x01 == (external_attributes &
+					    0x01)) {
+						/* Read-only bit;
+						 * strip write permissions */
 						zip_entry->mode &= 0555;
 					}
 				} else {
@@ -679,6 +770,59 @@
 			}
 			break;
 		}
+		case 0x7075:
+		{
+			/* Info-ZIP Unicode Path Extra Field. */
+			if (datasize < 5 || entry == NULL)
+				break;
+			offset += 5;
+			datasize -= 5;
+
+			/* The path name in this field is always encoded
+			 * in UTF-8. */
+			if (zip->sconv_utf8 == NULL) {
+				zip->sconv_utf8 =
+					archive_string_conversion_from_charset(
+					&a->archive, "UTF-8", 1);
+				/* If the converter from UTF-8 is not
+				 * available, then the path name from the main
+				 * field will more likely be correct. */
+				if (zip->sconv_utf8 == NULL)
+					break;
+			}
+
+			/* Make sure the CRC32 of the filename matches. */
+			if (!zip->ignore_crc32) {
+				const char *cp = archive_entry_pathname(entry);
+				if (cp) {
+					unsigned long file_crc =
+					    zip->crc32func(0, cp, strlen(cp));
+					unsigned long utf_crc =
+					    archive_le32dec(p + offset - 4);
+					if (file_crc != utf_crc) {
+#ifdef DEBUG
+						fprintf(stderr,
+						    "CRC filename mismatch; "
+						    "CDE is %lx, but UTF8 "
+						    "is outdated with %lx\n",
+						    file_crc, utf_crc);
+#endif
+						break;
+					}
+				}
+			}
+
+			if (archive_entry_copy_pathname_l(entry,
+			    p + offset, datasize, zip->sconv_utf8) != 0) {
+				/* Ignore the error, and fallback to the path
+				 * name from the main field. */
+#ifdef DEBUG
+				fprintf(stderr, "Failed to read the ZIP "
+				    "0x7075 extra field path.\n");
+#endif
+			}
+			break;
+		}
 		case 0x7855:
 			/* Info-ZIP Unix Extra Field (type 2) "Ux". */
 #ifdef DEBUG
@@ -713,7 +857,8 @@
 				}
 				if (datasize >= (2 + uidsize + 3)) {
 					/* get a gid size. */
-					gidsize = 0xff & (int)p[offset+2+uidsize];
+					gidsize = 0xff &
+					    (int)p[offset+2+uidsize];
 					if (gidsize == 2)
 						zip_entry->gid =
 						    archive_le16dec(
@@ -730,7 +875,8 @@
 		case 0x9901:
 			/* WinZip AES extra data field. */
 			if (datasize < 6) {
-				archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+				archive_set_error(&a->archive,
+				    ARCHIVE_ERRNO_FILE_FORMAT,
 				    "Incomplete AES field");
 				return ARCHIVE_FAILED;
 			}
@@ -750,12 +896,6 @@
 		}
 		offset += datasize;
 	}
-	if (offset != extra_length) {
-		archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
-		    "Malformed extra data: Consumed %d bytes of %d bytes",
-		    (int)offset, (int)extra_length);
-		return ARCHIVE_FAILED;
-	}
 	return ARCHIVE_OK;
 }
 
@@ -875,7 +1015,8 @@
 		return (ARCHIVE_FATAL);
 	}
 
-	if (ARCHIVE_OK != process_extra(a, h, extra_length, zip_entry)) {
+	if (ARCHIVE_OK != process_extra(a, entry, h, extra_length,
+	    zip_entry)) {
 		return ARCHIVE_FATAL;
 	}
 	__archive_read_consume(a, extra_length);
@@ -892,8 +1033,8 @@
 		zip_entry->mode |= 0664;
 	}
 
-	/* Windows archivers sometimes use backslash as the directory separator.
-	   Normalize to slash. */
+	/* Windows archivers sometimes use backslash as the directory
+	 * separator. Normalize to slash. */
 	if (zip_entry->system == 0 &&
 	    (wp = archive_entry_pathname_w(entry)) != NULL) {
 		if (wcschr(wp, L'/') == NULL && wcschr(wp, L'\\') != NULL) {
@@ -912,7 +1053,7 @@
 
 	/* Make sure that entries with a trailing '/' are marked as directories
 	 * even if the External File Attributes contains bogus values.  If this
-	 * is not a directory and there is no type, assume regularfile. */
+	 * is not a directory and there is no type, assume a regular file. */
 	if ((zip_entry->mode & AE_IFMT) != AE_IFDIR) {
 		int has_slash;
 
@@ -963,7 +1104,7 @@
 	}
 
 	if (zip_entry->flags & LA_FROM_CENTRAL_DIRECTORY) {
-		/* If this came from the central dir, it's size info
+		/* If this came from the central dir, its size info
 		 * is definitive, so ignore the length-at-end flag. */
 		zip_entry->zip_flags &= ~ZIP_LENGTH_AT_END;
 		/* If local header is missing a value, use the one from
@@ -1202,7 +1343,8 @@
 				zip->entry->crc32 = archive_le32dec(p + 4);
 				compressed = archive_le64dec(p + 8);
 				uncompressed = archive_le64dec(p + 16);
-				if (compressed > INT64_MAX || uncompressed > INT64_MAX) {
+				if (compressed > INT64_MAX || uncompressed >
+				    INT64_MAX) {
 					archive_set_error(&a->archive,
 					    ARCHIVE_ERRNO_FILE_FORMAT,
 					    "Overflow of 64-bit file sizes");
@@ -1296,6 +1438,745 @@
 	return (ARCHIVE_OK);
 }
 
+static int
+consume_optional_marker(struct archive_read *a, struct zip *zip)
+{
+	if (zip->end_of_entry && (zip->entry->zip_flags & ZIP_LENGTH_AT_END)) {
+		const char *p;
+
+		if (NULL == (p = __archive_read_ahead(a, 24, NULL))) {
+			archive_set_error(&a->archive,
+			    ARCHIVE_ERRNO_FILE_FORMAT,
+			    "Truncated ZIP end-of-file record");
+			return (ARCHIVE_FATAL);
+		}
+		/* Consume the optional PK\007\010 marker. */
+		if (p[0] == 'P' && p[1] == 'K' &&
+		    p[2] == '\007' && p[3] == '\010') {
+			p += 4;
+			zip->unconsumed = 4;
+		}
+		if (zip->entry->flags & LA_USED_ZIP64) {
+			uint64_t compressed, uncompressed;
+			zip->entry->crc32 = archive_le32dec(p);
+			compressed = archive_le64dec(p + 4);
+			uncompressed = archive_le64dec(p + 12);
+			if (compressed > INT64_MAX ||
+			    uncompressed > INT64_MAX) {
+				archive_set_error(&a->archive,
+				    ARCHIVE_ERRNO_FILE_FORMAT,
+				    "Overflow of 64-bit file sizes");
+				return ARCHIVE_FAILED;
+			}
+			zip->entry->compressed_size = compressed;
+			zip->entry->uncompressed_size = uncompressed;
+			zip->unconsumed += 20;
+		} else {
+			zip->entry->crc32 = archive_le32dec(p);
+			zip->entry->compressed_size = archive_le32dec(p + 4);
+			zip->entry->uncompressed_size = archive_le32dec(p + 8);
+			zip->unconsumed += 12;
+		}
+	}
+
+    return (ARCHIVE_OK);
+}
+
+#if HAVE_LZMA_H && HAVE_LIBLZMA
+static int
+zipx_xz_init(struct archive_read *a, struct zip *zip)
+{
+	lzma_ret r;
+
+	if(zip->zipx_lzma_valid) {
+		lzma_end(&zip->zipx_lzma_stream);
+		zip->zipx_lzma_valid = 0;
+	}
+
+	memset(&zip->zipx_lzma_stream, 0, sizeof(zip->zipx_lzma_stream));
+	r = lzma_stream_decoder(&zip->zipx_lzma_stream, UINT64_MAX, 0);
+	if (r != LZMA_OK) {
+		archive_set_error(&(a->archive), ARCHIVE_ERRNO_MISC,
+		    "xz initialization failed(%d)",
+		    r);
+
+		return (ARCHIVE_FAILED);
+	}
+
+	zip->zipx_lzma_valid = 1;
+
+	free(zip->uncompressed_buffer);
+
+	zip->uncompressed_buffer_size = 256 * 1024;
+	zip->uncompressed_buffer =
+	    (uint8_t*) malloc(zip->uncompressed_buffer_size);
+	if (zip->uncompressed_buffer == NULL) {
+		archive_set_error(&a->archive, ENOMEM,
+		    "No memory for xz decompression");
+		    return (ARCHIVE_FATAL);
+	}
+
+	zip->decompress_init = 1;
+	return (ARCHIVE_OK);
+}
+
+static int
+zipx_lzma_alone_init(struct archive_read *a, struct zip *zip)
+{
+	lzma_ret r;
+	const uint8_t* p;
+
+#pragma pack(push)
+#pragma pack(1)
+	struct _alone_header {
+	    uint8_t bytes[5];
+	    uint64_t uncompressed_size;
+	} alone_header;
+#pragma pack(pop)
+
+	if(zip->zipx_lzma_valid) {
+		lzma_end(&zip->zipx_lzma_stream);
+		zip->zipx_lzma_valid = 0;
+	}
+
+	/* To unpack ZIPX's "LZMA" (id 14) stream we can use standard liblzma
+	 * that is a part of XZ Utils. The stream format stored inside ZIPX
+	 * file is a modified "lzma alone" file format, that was used by the
+	 * `lzma` utility which was later deprecated in favour of `xz` utility. 	 * Since those formats are nearly the same, we can use a standard
+	 * "lzma alone" decoder from XZ Utils. */
+
+	memset(&zip->zipx_lzma_stream, 0, sizeof(zip->zipx_lzma_stream));
+	r = lzma_alone_decoder(&zip->zipx_lzma_stream, UINT64_MAX);
+	if (r != LZMA_OK) {
+		archive_set_error(&(a->archive), ARCHIVE_ERRNO_MISC,
+		    "lzma initialization failed(%d)", r);
+
+		return (ARCHIVE_FAILED);
+	}
+
+	/* Flag the cleanup function that we want our lzma-related structures
+	 * to be freed later. */
+	zip->zipx_lzma_valid = 1;
+
+	/* The "lzma alone" file format and the stream format inside ZIPx are
+	 * almost the same. Here's an example of a structure of "lzma alone"
+	 * format:
+	 *
+	 * $ cat /bin/ls | lzma | xxd | head -n 1
+	 * 00000000: 5d00 0080 00ff ffff ffff ffff ff00 2814
+	 *
+	 *    5 bytes        8 bytes        n bytes
+	 * <lzma_params><uncompressed_size><data...>
+	 *
+	 * lzma_params is a 5-byte blob that has to be decoded to extract
+	 * parameters of this LZMA stream. The uncompressed_size field is an
+	 * uint64_t value that contains information about the size of the
+	 * uncompressed file, or UINT64_MAX if this value is unknown.
+	 * The <data...> part is the actual lzma-compressed data stream.
+	 *
+	 * Now here's the structure of the stream inside the ZIPX file:
+	 *
+	 * $ cat stream_inside_zipx | xxd | head -n 1
+	 * 00000000: 0914 0500 5d00 8000 0000 2814 .... ....
+	 *
+	 *  2byte   2byte    5 bytes     n bytes
+	 * <magic1><magic2><lzma_params><data...>
+	 *
+	 * This means that the ZIPX file contains an additional magic1 and
+	 * magic2 headers, the lzma_params field contains the same parameter
+	 * set as in the "lzma alone" format, and the <data...> field is the
+	 * same as in the "lzma alone" format as well. Note that also the zipx
+	 * format is missing the uncompressed_size field.
+	 *
+	 * So, in order to use the "lzma alone" decoder for the zipx lzma
+	 * stream, we simply need to shuffle around some fields, prepare a new
+	 * lzma alone header, feed it into lzma alone decoder so it will
+	 * initialize itself properly, and then we can start feeding normal
+	 * zipx lzma stream into the decoder.
+	 */
+
+	/* Read magic1,magic2,lzma_params from the ZIPX stream. */
+	if((p = __archive_read_ahead(a, 9, NULL)) == NULL) {
+		archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+		    "Truncated lzma data");
+		return (ARCHIVE_FATAL);
+	}
+
+	if(p[2] != 0x05 || p[3] != 0x00) {
+		archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+		    "Invalid lzma data");
+		return (ARCHIVE_FATAL);
+	}
+
+	/* Prepare an lzma alone header: copy the lzma_params blob into
+	 * a proper place into the lzma alone header. */
+	memcpy(&alone_header.bytes[0], p + 4, 5);
+
+	/* Initialize the 'uncompressed size' field to unknown; we'll manually
+	 * monitor how many bytes there are still to be uncompressed. */
+	alone_header.uncompressed_size = UINT64_MAX;
+
+	if(!zip->uncompressed_buffer) {
+		zip->uncompressed_buffer_size = 256 * 1024;
+		zip->uncompressed_buffer =
+			(uint8_t*) malloc(zip->uncompressed_buffer_size);
+
+		if (zip->uncompressed_buffer == NULL) {
+			archive_set_error(&a->archive, ENOMEM,
+			    "No memory for lzma decompression");
+			return (ARCHIVE_FATAL);
+		}
+	}
+
+	zip->zipx_lzma_stream.next_in = (void*) &alone_header;
+	zip->zipx_lzma_stream.avail_in = sizeof(alone_header);
+	zip->zipx_lzma_stream.total_in = 0;
+	zip->zipx_lzma_stream.next_out = zip->uncompressed_buffer;
+	zip->zipx_lzma_stream.avail_out = zip->uncompressed_buffer_size;
+	zip->zipx_lzma_stream.total_out = 0;
+
+	/* Feed only the header into the lzma alone decoder. This will
+	 * effectively initialize the decoder, and will not produce any
+	 * output bytes yet. */
+	r = lzma_code(&zip->zipx_lzma_stream, LZMA_RUN);
+	if (r != LZMA_OK) {
+		archive_set_error(&a->archive, ARCHIVE_ERRNO_PROGRAMMER,
+		    "lzma stream initialization error");
+		return ARCHIVE_FATAL;
+	}
+
+	/* We've already consumed some bytes, so take this into account. */
+	__archive_read_consume(a, 9);
+	zip->entry_bytes_remaining -= 9;
+	zip->entry_compressed_bytes_read += 9;
+
+	zip->decompress_init = 1;
+	return (ARCHIVE_OK);
+}
+
+static int
+zip_read_data_zipx_xz(struct archive_read *a, const void **buff,
+	size_t *size, int64_t *offset)
+{
+	struct zip* zip = (struct zip *)(a->format->data);
+	int ret;
+	lzma_ret lz_ret;
+	const void* compressed_buf;
+	ssize_t bytes_avail, in_bytes, to_consume = 0;
+
+	(void) offset; /* UNUSED */
+
+	/* Initialize decompressor if not yet initialized. */
+	if (!zip->decompress_init) {
+		ret = zipx_xz_init(a, zip);
+		if (ret != ARCHIVE_OK)
+			return (ret);
+	}
+
+	compressed_buf = __archive_read_ahead(a, 1, &bytes_avail);
+	if (bytes_avail < 0) {
+		archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+		    "Truncated xz file body");
+		return (ARCHIVE_FATAL);
+	}
+
+	in_bytes = zipmin(zip->entry_bytes_remaining, bytes_avail);
+	zip->zipx_lzma_stream.next_in = compressed_buf;
+	zip->zipx_lzma_stream.avail_in = in_bytes;
+	zip->zipx_lzma_stream.total_in = 0;
+	zip->zipx_lzma_stream.next_out = zip->uncompressed_buffer;
+	zip->zipx_lzma_stream.avail_out = zip->uncompressed_buffer_size;
+	zip->zipx_lzma_stream.total_out = 0;
+
+	/* Perform the decompression. */
+	lz_ret = lzma_code(&zip->zipx_lzma_stream, LZMA_RUN);
+	switch(lz_ret) {
+		case LZMA_DATA_ERROR:
+			archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+			    "xz data error (error %d)", (int) lz_ret);
+			return (ARCHIVE_FATAL);
+
+		case LZMA_NO_CHECK:
+		case LZMA_OK:
+			break;
+
+		default:
+			archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+			    "xz unknown error %d", (int) lz_ret);
+			return (ARCHIVE_FATAL);
+
+		case LZMA_STREAM_END:
+			lzma_end(&zip->zipx_lzma_stream);
+			zip->zipx_lzma_valid = 0;
+
+			if((int64_t) zip->zipx_lzma_stream.total_in !=
+			    zip->entry_bytes_remaining)
+			{
+				archive_set_error(&a->archive,
+				    ARCHIVE_ERRNO_MISC,
+				    "xz premature end of stream");
+				return (ARCHIVE_FATAL);
+			}
+
+			zip->end_of_entry = 1;
+			break;
+	}
+
+	to_consume = zip->zipx_lzma_stream.total_in;
+
+	__archive_read_consume(a, to_consume);
+	zip->entry_bytes_remaining -= to_consume;
+	zip->entry_compressed_bytes_read += to_consume;
+	zip->entry_uncompressed_bytes_read += zip->zipx_lzma_stream.total_out;
+
+	*size = zip->zipx_lzma_stream.total_out;
+	*buff = zip->uncompressed_buffer;
+
+	ret = consume_optional_marker(a, zip);
+	if (ret != ARCHIVE_OK)
+		return (ret);
+
+	return (ARCHIVE_OK);
+}
+
+static int
+zip_read_data_zipx_lzma_alone(struct archive_read *a, const void **buff,
+    size_t *size, int64_t *offset)
+{
+	struct zip* zip = (struct zip *)(a->format->data);
+	int ret;
+	lzma_ret lz_ret;
+	const void* compressed_buf;
+	ssize_t bytes_avail, in_bytes, to_consume;
+
+	(void) offset; /* UNUSED */
+
+	/* Initialize decompressor if not yet initialized. */
+	if (!zip->decompress_init) {
+		ret = zipx_lzma_alone_init(a, zip);
+		if (ret != ARCHIVE_OK)
+			return (ret);
+	}
+
+	/* Fetch more compressed data. The same note as in deflate handler
+	 * applies here as well:
+	 *
+	 * Note: '1' here is a performance optimization. Recall that the
+	 * decompression layer returns a count of available bytes; asking for
+	 * more than that forces the decompressor to combine reads by copying
+	 * data.
+	 */
+	compressed_buf = __archive_read_ahead(a, 1, &bytes_avail);
+	if (bytes_avail < 0) {
+		archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+		    "Truncated lzma file body");
+		return (ARCHIVE_FATAL);
+	}
+
+	/* Set decompressor parameters. */
+	in_bytes = zipmin(zip->entry_bytes_remaining, bytes_avail);
+
+	zip->zipx_lzma_stream.next_in = compressed_buf;
+	zip->zipx_lzma_stream.avail_in = in_bytes;
+	zip->zipx_lzma_stream.total_in = 0;
+	zip->zipx_lzma_stream.next_out = zip->uncompressed_buffer;
+	zip->zipx_lzma_stream.avail_out =
+		/* These lzma_alone streams lack end of stream marker, so let's
+		 * make sure the unpacker won't try to unpack more than it's
+		 * supposed to. */
+		zipmin((int64_t) zip->uncompressed_buffer_size,
+		    zip->entry->uncompressed_size -
+		    zip->entry_uncompressed_bytes_read);
+	zip->zipx_lzma_stream.total_out = 0;
+
+	/* Perform the decompression. */
+	lz_ret = lzma_code(&zip->zipx_lzma_stream, LZMA_RUN);
+	switch(lz_ret) {
+		case LZMA_DATA_ERROR:
+			archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+			    "lzma data error (error %d)", (int) lz_ret);
+			return (ARCHIVE_FATAL);
+
+		/* This case is optional in lzma alone format. It can happen,
+		 * but most of the files don't have it. (GitHub #1257) */
+		case LZMA_STREAM_END:
+			lzma_end(&zip->zipx_lzma_stream);
+			zip->zipx_lzma_valid = 0;
+			if((int64_t) zip->zipx_lzma_stream.total_in !=
+			    zip->entry_bytes_remaining)
+			{
+				archive_set_error(&a->archive,
+				    ARCHIVE_ERRNO_MISC,
+				    "lzma alone premature end of stream");
+				return (ARCHIVE_FATAL);
+			}
+
+			zip->end_of_entry = 1;
+			break;
+
+		case LZMA_OK:
+			break;
+
+		default:
+			archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+			    "lzma unknown error %d", (int) lz_ret);
+			return (ARCHIVE_FATAL);
+	}
+
+	to_consume = zip->zipx_lzma_stream.total_in;
+
+	/* Update pointers. */
+	__archive_read_consume(a, to_consume);
+	zip->entry_bytes_remaining -= to_consume;
+	zip->entry_compressed_bytes_read += to_consume;
+	zip->entry_uncompressed_bytes_read += zip->zipx_lzma_stream.total_out;
+
+	if(zip->entry_bytes_remaining == 0) {
+		zip->end_of_entry = 1;
+	}
+
+	/* Return values. */
+	*size = zip->zipx_lzma_stream.total_out;
+	*buff = zip->uncompressed_buffer;
+
+	/* Behave the same way as during deflate decompression. */
+	ret = consume_optional_marker(a, zip);
+	if (ret != ARCHIVE_OK)
+		return (ret);
+
+	/* Free lzma decoder handle because we'll no longer need it. */
+	if(zip->end_of_entry) {
+		lzma_end(&zip->zipx_lzma_stream);
+		zip->zipx_lzma_valid = 0;
+	}
+
+	/* If we're here, then we're good! */
+	return (ARCHIVE_OK);
+}
+#endif /* HAVE_LZMA_H && HAVE_LIBLZMA */
+
+static int
+zipx_ppmd8_init(struct archive_read *a, struct zip *zip)
+{
+	const void* p;
+	uint32_t val;
+	uint32_t order;
+	uint32_t mem;
+	uint32_t restore_method;
+
+	/* Remove previous decompression context if it exists. */
+	if(zip->ppmd8_valid) {
+		__archive_ppmd8_functions.Ppmd8_Free(&zip->ppmd8);
+		zip->ppmd8_valid = 0;
+	}
+
+	/* Create a new decompression context. */
+	__archive_ppmd8_functions.Ppmd8_Construct(&zip->ppmd8);
+	zip->ppmd8_stream_failed = 0;
+
+	/* Setup function pointers required by Ppmd8 decompressor. The
+	 * 'ppmd_read' function will feed new bytes to the decompressor,
+	 * and will increment the 'zip->zipx_ppmd_read_compressed' counter. */
+	zip->ppmd8.Stream.In = &zip->zipx_ppmd_stream;
+	zip->zipx_ppmd_stream.a = a;
+	zip->zipx_ppmd_stream.Read = &ppmd_read;
+
+	/* Reset number of read bytes to 0. */
+	zip->zipx_ppmd_read_compressed = 0;
+
+	/* Read Ppmd8 header (2 bytes). */
+	p = __archive_read_ahead(a, 2, NULL);
+	if(!p) {
+		archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+		    "Truncated file data in PPMd8 stream");
+		return (ARCHIVE_FATAL);
+	}
+	__archive_read_consume(a, 2);
+
+	/* Decode the stream's compression parameters. */
+	val = archive_le16dec(p);
+	order = (val & 15) + 1;
+	mem = ((val >> 4) & 0xff) + 1;
+	restore_method = (val >> 12);
+
+	if(order < 2 || restore_method > 2) {
+		archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+		    "Invalid parameter set in PPMd8 stream (order=%d, "
+		    "restore=%d)", order, restore_method);
+		return (ARCHIVE_FAILED);
+	}
+
+	/* Allocate the memory needed to properly decompress the file. */
+	if(!__archive_ppmd8_functions.Ppmd8_Alloc(&zip->ppmd8, mem << 20)) {
+		archive_set_error(&a->archive, ENOMEM,
+		    "Unable to allocate memory for PPMd8 stream: %d bytes",
+		    mem << 20);
+		return (ARCHIVE_FATAL);
+	}
+
+	/* Signal the cleanup function to release Ppmd8 context in the
+	 * cleanup phase. */
+	zip->ppmd8_valid = 1;
+
+	/* Perform further Ppmd8 initialization. */
+	if(!__archive_ppmd8_functions.Ppmd8_RangeDec_Init(&zip->ppmd8)) {
+		archive_set_error(&a->archive, ARCHIVE_ERRNO_PROGRAMMER,
+		    "PPMd8 stream range decoder initialization error");
+		return (ARCHIVE_FATAL);
+	}
+
+	__archive_ppmd8_functions.Ppmd8_Init(&zip->ppmd8, order,
+	    restore_method);
+
+	/* Allocate the buffer that will hold uncompressed data. */
+	free(zip->uncompressed_buffer);
+
+	zip->uncompressed_buffer_size = 256 * 1024;
+	zip->uncompressed_buffer =
+	    (uint8_t*) malloc(zip->uncompressed_buffer_size);
+
+	if(zip->uncompressed_buffer == NULL) {
+		archive_set_error(&a->archive, ENOMEM,
+		    "No memory for PPMd8 decompression");
+		return ARCHIVE_FATAL;
+	}
+
+	/* Ppmd8 initialization is done. */
+	zip->decompress_init = 1;
+
+	/* We've already read 2 bytes in the output stream. Additionally,
+	 * Ppmd8 initialization code could read some data as well. So we
+	 * are advancing the stream by 2 bytes plus whatever number of
+	 * bytes Ppmd8 init function used. */
+	zip->entry_compressed_bytes_read += 2 + zip->zipx_ppmd_read_compressed;
+
+	return ARCHIVE_OK;
+}
+
+static int
+zip_read_data_zipx_ppmd(struct archive_read *a, const void **buff,
+    size_t *size, int64_t *offset)
+{
+	struct zip* zip = (struct zip *)(a->format->data);
+	int ret;
+	size_t consumed_bytes = 0;
+	ssize_t bytes_avail = 0;
+
+	(void) offset; /* UNUSED */
+
+	/* If we're here for the first time, initialize Ppmd8 decompression
+	 * context first. */
+	if(!zip->decompress_init) {
+		ret = zipx_ppmd8_init(a, zip);
+		if(ret != ARCHIVE_OK)
+			return ret;
+	}
+
+	/* Fetch for more data. We're reading 1 byte here, but libarchive
+	 * should prefetch more bytes. */
+	(void) __archive_read_ahead(a, 1, &bytes_avail);
+	if(bytes_avail < 0) {
+		archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+		    "Truncated PPMd8 file body");
+		return (ARCHIVE_FATAL);
+	}
+
+	/* This counter will be updated inside ppmd_read(), which at one
+	 * point will be called by Ppmd8_DecodeSymbol. */
+	zip->zipx_ppmd_read_compressed = 0;
+
+	/* Decompression loop. */
+	do {
+		int sym = __archive_ppmd8_functions.Ppmd8_DecodeSymbol(
+		    &zip->ppmd8);
+		if(sym < 0) {
+			zip->end_of_entry = 1;
+			break;
+		}
+
+		/* This field is set by ppmd_read() when there was no more data
+		 * to be read. */
+		if(zip->ppmd8_stream_failed) {
+			archive_set_error(&a->archive,
+			    ARCHIVE_ERRNO_FILE_FORMAT,
+			    "Truncated PPMd8 file body");
+			return (ARCHIVE_FATAL);
+		}
+
+		zip->uncompressed_buffer[consumed_bytes] = (uint8_t) sym;
+		++consumed_bytes;
+	} while(consumed_bytes < zip->uncompressed_buffer_size);
+
+	/* Update pointers for libarchive. */
+	*buff = zip->uncompressed_buffer;
+	*size = consumed_bytes;
+
+	/* Update pointers so we can continue decompression in another call. */
+	zip->entry_bytes_remaining -= zip->zipx_ppmd_read_compressed;
+	zip->entry_compressed_bytes_read += zip->zipx_ppmd_read_compressed;
+	zip->entry_uncompressed_bytes_read += consumed_bytes;
+
+	/* If we're at the end of stream, deinitialize Ppmd8 context. */
+	if(zip->end_of_entry) {
+		__archive_ppmd8_functions.Ppmd8_Free(&zip->ppmd8);
+		zip->ppmd8_valid = 0;
+	}
+
+	/* Seek for optional marker, same way as in each zip entry. */
+	ret = consume_optional_marker(a, zip);
+	if (ret != ARCHIVE_OK)
+		return ret;
+
+	return ARCHIVE_OK;
+}
+
+#ifdef HAVE_BZLIB_H
+static int
+zipx_bzip2_init(struct archive_read *a, struct zip *zip)
+{
+	int r;
+
+	/* Deallocate already existing BZ2 decompression context if it
+	 * exists. */
+	if(zip->bzstream_valid) {
+		BZ2_bzDecompressEnd(&zip->bzstream);
+		zip->bzstream_valid = 0;
+	}
+
+	/* Allocate a new BZ2 decompression context. */
+	memset(&zip->bzstream, 0, sizeof(bz_stream));
+	r = BZ2_bzDecompressInit(&zip->bzstream, 0, 1);
+	if(r != BZ_OK) {
+		archive_set_error(&(a->archive), ARCHIVE_ERRNO_MISC,
+		    "bzip2 initialization failed(%d)",
+		    r);
+
+		return ARCHIVE_FAILED;
+	}
+
+	/* Mark the bzstream field to be released in cleanup phase. */
+	zip->bzstream_valid = 1;
+
+	/* (Re)allocate the buffer that will contain decompressed bytes. */
+	free(zip->uncompressed_buffer);
+
+	zip->uncompressed_buffer_size = 256 * 1024;
+	zip->uncompressed_buffer =
+	    (uint8_t*) malloc(zip->uncompressed_buffer_size);
+	if (zip->uncompressed_buffer == NULL) {
+		archive_set_error(&a->archive, ENOMEM,
+		    "No memory for bzip2 decompression");
+		    return ARCHIVE_FATAL;
+	}
+
+	/* Initialization done. */
+	zip->decompress_init = 1;
+	return ARCHIVE_OK;
+}
+
+static int
+zip_read_data_zipx_bzip2(struct archive_read *a, const void **buff,
+    size_t *size, int64_t *offset)
+{
+	struct zip *zip = (struct zip *)(a->format->data);
+	ssize_t bytes_avail = 0, in_bytes, to_consume;
+	const void *compressed_buff;
+	int r;
+	uint64_t total_out;
+
+	(void) offset; /* UNUSED */
+
+	/* Initialize decompression context if we're here for the first time. */
+	if(!zip->decompress_init) {
+		r = zipx_bzip2_init(a, zip);
+		if(r != ARCHIVE_OK)
+			return r;
+	}
+
+	/* Fetch more compressed bytes. */
+	compressed_buff = __archive_read_ahead(a, 1, &bytes_avail);
+	if(bytes_avail < 0) {
+		archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+		    "Truncated bzip2 file body");
+		return (ARCHIVE_FATAL);
+	}
+
+	in_bytes = zipmin(zip->entry_bytes_remaining, bytes_avail);
+	if(in_bytes < 1) {
+		/* libbz2 doesn't complain when caller feeds avail_in == 0.
+		 * It will actually return success in this case, which is
+		 * undesirable. This is why we need to make this check
+		 * manually. */
+
+		archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+		    "Truncated bzip2 file body");
+		return (ARCHIVE_FATAL);
+	}
+
+	/* Setup buffer boundaries. */
+	zip->bzstream.next_in = (char*)(uintptr_t) compressed_buff;
+	zip->bzstream.avail_in = in_bytes;
+	zip->bzstream.total_in_hi32 = 0;
+	zip->bzstream.total_in_lo32 = 0;
+	zip->bzstream.next_out = (char*) zip->uncompressed_buffer;
+	zip->bzstream.avail_out = zip->uncompressed_buffer_size;
+	zip->bzstream.total_out_hi32 = 0;
+	zip->bzstream.total_out_lo32 = 0;
+
+	/* Perform the decompression. */
+	r = BZ2_bzDecompress(&zip->bzstream);
+	switch(r) {
+		case BZ_STREAM_END:
+			/* If we're at the end of the stream, deinitialize the
+			 * decompression context now. */
+			switch(BZ2_bzDecompressEnd(&zip->bzstream)) {
+				case BZ_OK:
+					break;
+				default:
+					archive_set_error(&a->archive,
+					    ARCHIVE_ERRNO_MISC,
+					    "Failed to clean up bzip2 "
+					    "decompressor");
+					return ARCHIVE_FATAL;
+			}
+
+			zip->end_of_entry = 1;
+			break;
+		case BZ_OK:
+			/* The decompressor has successfully decoded this
+			 * chunk of data, but more data is still in queue. */
+			break;
+		default:
+			archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+			    "bzip2 decompression failed");
+			return ARCHIVE_FATAL;
+	}
+
+	/* Update the pointers so decompressor can continue decoding. */
+	to_consume = zip->bzstream.total_in_lo32;
+	__archive_read_consume(a, to_consume);
+
+	total_out = ((uint64_t) zip->bzstream.total_out_hi32 << 32) +
+	    zip->bzstream.total_out_lo32;
+
+	zip->entry_bytes_remaining -= to_consume;
+	zip->entry_compressed_bytes_read += to_consume;
+	zip->entry_uncompressed_bytes_read += total_out;
+
+	/* Give libarchive its due. */
+	*size = total_out;
+	*buff = zip->uncompressed_buffer;
+
+	/* Seek for optional marker, like in other entries. */
+	r = consume_optional_marker(a, zip);
+	if(r != ARCHIVE_OK)
+		return r;
+
+	return ARCHIVE_OK;
+}
+
+#endif
+
 #ifdef HAVE_ZLIB_H
 static int
 zip_deflate_init(struct archive_read *a, struct zip *zip)
@@ -1371,8 +2252,10 @@
 	if (zip->tctx_valid || zip->cctx_valid) {
 		if (zip->decrypted_bytes_remaining < (size_t)bytes_avail) {
 			size_t buff_remaining =
-			    (zip->decrypted_buffer + zip->decrypted_buffer_size)
-			    - (zip->decrypted_ptr + zip->decrypted_bytes_remaining);
+			    (zip->decrypted_buffer +
+			    zip->decrypted_buffer_size)
+			    - (zip->decrypted_ptr +
+			    zip->decrypted_bytes_remaining);
 
 			if (buff_remaining > (size_t)bytes_avail)
 				buff_remaining = (size_t)bytes_avail;
@@ -1383,12 +2266,12 @@
 				    + buff_remaining)
 				      > zip->entry_bytes_remaining) {
 					if (zip->entry_bytes_remaining <
-					      (int64_t)zip->decrypted_bytes_remaining)
+					    (int64_t)zip->decrypted_bytes_remaining)
 						buff_remaining = 0;
 					else
 						buff_remaining =
 						    (size_t)zip->entry_bytes_remaining
-						      - zip->decrypted_bytes_remaining;
+						    - zip->decrypted_bytes_remaining;
 				}
 			}
 			if (buff_remaining > 0) {
@@ -1407,7 +2290,8 @@
 					      + zip->decrypted_bytes_remaining,
 					    &dsize);
 				}
-				zip->decrypted_bytes_remaining += buff_remaining;
+				zip->decrypted_bytes_remaining +=
+				    buff_remaining;
 			}
 		}
 		bytes_avail = zip->decrypted_bytes_remaining;
@@ -1470,42 +2354,9 @@
 			return (r);
 	}
 
-	if (zip->end_of_entry && (zip->entry->zip_flags & ZIP_LENGTH_AT_END)) {
-		const char *p;
-
-		if (NULL == (p = __archive_read_ahead(a, 24, NULL))) {
-			archive_set_error(&a->archive,
-			    ARCHIVE_ERRNO_FILE_FORMAT,
-			    "Truncated ZIP end-of-file record");
-			return (ARCHIVE_FATAL);
-		}
-		/* Consume the optional PK\007\010 marker. */
-		if (p[0] == 'P' && p[1] == 'K' &&
-		    p[2] == '\007' && p[3] == '\010') {
-			p += 4;
-			zip->unconsumed = 4;
-		}
-		if (zip->entry->flags & LA_USED_ZIP64) {
-			uint64_t compressed, uncompressed;
-			zip->entry->crc32 = archive_le32dec(p);
-			compressed = archive_le64dec(p + 4);
-			uncompressed = archive_le64dec(p + 12);
-			if (compressed > INT64_MAX || uncompressed > INT64_MAX) {
-				archive_set_error(&a->archive,
-				    ARCHIVE_ERRNO_FILE_FORMAT,
-				    "Overflow of 64-bit file sizes");
-				return ARCHIVE_FAILED;
-			}
-			zip->entry->compressed_size = compressed;
-			zip->entry->uncompressed_size = uncompressed;
-			zip->unconsumed += 20;
-		} else {
-			zip->entry->crc32 = archive_le32dec(p);
-			zip->entry->compressed_size = archive_le32dec(p + 4);
-			zip->entry->uncompressed_size = archive_le32dec(p + 8);
-			zip->unconsumed += 12;
-		}
-	}
+	r = consume_optional_marker(a, zip);
+	if (r != ARCHIVE_OK)
+		return (r);
 
 	return (ARCHIVE_OK);
 }
@@ -1933,6 +2784,24 @@
 	case 0:  /* No compression. */
 		r =  zip_read_data_none(a, buff, size, offset);
 		break;
+#ifdef HAVE_BZLIB_H
+	case 12: /* ZIPx bzip2 compression. */
+		r = zip_read_data_zipx_bzip2(a, buff, size, offset);
+		break;
+#endif
+#if HAVE_LZMA_H && HAVE_LIBLZMA
+	case 14: /* ZIPx LZMA compression. */
+		r = zip_read_data_zipx_lzma_alone(a, buff, size, offset);
+		break;
+	case 95: /* ZIPx XZ compression. */
+		r = zip_read_data_zipx_xz(a, buff, size, offset);
+		break;
+#endif
+	/* PPMd support is built-in, so we don't need any #if guards. */
+	case 98: /* ZIPx PPMd compression. */
+		r = zip_read_data_zipx_ppmd(a, buff, size, offset);
+		break;
+
 #ifdef HAVE_ZLIB_H
 	case 8: /* Deflate compression. */
 		r =  zip_read_data_deflate(a, buff, size, offset);
@@ -1941,8 +2810,8 @@
 	default: /* Unsupported compression. */
 		/* Return a warning. */
 		archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
-		    "Unsupported ZIP compression method (%s)",
-		    compression_name(zip->entry->compression));
+		    "Unsupported ZIP compression method (%d: %s)",
+		    zip->entry->compression, compression_name(zip->entry->compression));
 		/* We can't decompress this entry, but we will
 		 * be able to skip() it and try the next entry. */
 		return (ARCHIVE_FAILED);
@@ -2000,11 +2869,29 @@
 	struct zip_entry *zip_entry, *next_zip_entry;
 
 	zip = (struct zip *)(a->format->data);
+
 #ifdef HAVE_ZLIB_H
 	if (zip->stream_valid)
 		inflateEnd(&zip->stream);
-	free(zip->uncompressed_buffer);
 #endif
+
+#if HAVE_LZMA_H && HAVE_LIBLZMA
+    if (zip->zipx_lzma_valid) {
+		lzma_end(&zip->zipx_lzma_stream);
+	}
+#endif
+
+#ifdef HAVE_BZLIB_H
+	if (zip->bzstream_valid) {
+		BZ2_bzDecompressEnd(&zip->bzstream);
+	}
+#endif
+
+	free(zip->uncompressed_buffer);
+
+	if (zip->ppmd8_valid)
+		__archive_ppmd8_functions.Ppmd8_Free(&zip->ppmd8);
+
 	if (zip->zip_entries) {
 		zip_entry = zip->zip_entries;
 		while (zip_entry != NULL) {
@@ -2628,7 +3515,8 @@
 }
 
 static int
-slurp_central_directory(struct archive_read *a, struct zip *zip)
+slurp_central_directory(struct archive_read *a, struct archive_entry* entry,
+    struct zip *zip)
 {
 	ssize_t i;
 	unsigned found;
@@ -2708,6 +3596,11 @@
 			return ARCHIVE_FATAL;
 
 		zip_entry = calloc(1, sizeof(struct zip_entry));
+		if (zip_entry == NULL) {
+			archive_set_error(&a->archive, ENOMEM,
+				"Can't allocate zip entry");
+			return ARCHIVE_FATAL;
+		}
 		zip_entry->next = zip->zip_entries;
 		zip_entry->flags |= LA_FROM_CENTRAL_DIRECTORY;
 		zip->zip_entries = zip_entry;
@@ -2733,8 +3626,10 @@
 		filename_length = archive_le16dec(p + 28);
 		extra_length = archive_le16dec(p + 30);
 		comment_length = archive_le16dec(p + 32);
-		/* disk_start = archive_le16dec(p + 34); */ /* Better be zero. */
-		/* internal_attributes = archive_le16dec(p + 36); */ /* text bit */
+		/* disk_start = archive_le16dec(p + 34);
+		 *   Better be zero.
+		 * internal_attributes = archive_le16dec(p + 36);
+		 *   text bit */
 		external_attributes = archive_le32dec(p + 38);
 		zip_entry->local_header_offset =
 		    archive_le32dec(p + 42) + correction;
@@ -2770,7 +3665,8 @@
 			    "Truncated ZIP file header");
 			return ARCHIVE_FATAL;
 		}
-		if (ARCHIVE_OK != process_extra(a, p + filename_length, extra_length, zip_entry)) {
+		if (ARCHIVE_OK != process_extra(a, entry, p + filename_length,
+		    extra_length, zip_entry)) {
 			return ARCHIVE_FATAL;
 		}
 
@@ -2792,7 +3688,8 @@
 				 * a directory. We should treat it as a non
 				 * resource fork file to expose it. */
 				if (name[filename_length-1] != '/' &&
-				    (r - name < 3 || r[0] != '.' || r[1] != '_')) {
+				    (r - name < 3 || r[0] != '.' ||
+				     r[1] != '_')) {
 					__archive_rb_tree_insert_node(
 					    &zip->tree, &zip_entry->node);
 					/* Expose its parent directories. */
@@ -2869,8 +3766,10 @@
 	switch(rsrc->compression) {
 	case 0:  /* No compression. */
 		if (rsrc->uncompressed_size != rsrc->compressed_size) {
-			archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
-			    "Malformed OS X metadata entry: inconsistent size");
+			archive_set_error(&a->archive,
+			    ARCHIVE_ERRNO_FILE_FORMAT,
+			    "Malformed OS X metadata entry: "
+			    "inconsistent size");
 			return (ARCHIVE_FATAL);
 		}
 #ifdef HAVE_ZLIB_H
@@ -3029,7 +3928,7 @@
 		a->archive.archive_format_name = "ZIP";
 
 	if (zip->zip_entries == NULL) {
-		r = slurp_central_directory(a, zip);
+		r = slurp_central_directory(a, entry, zip);
 		if (r != ARCHIVE_OK)
 			return r;
 		/* Get first entry whose local header offset is lower than
@@ -3059,8 +3958,8 @@
 	__archive_read_reset_passphrase(a);
 
 	/* File entries are sorted by the header offset, we should mostly
-	 * use __archive_read_consume to advance a read point to avoid redundant
-	 * data reading.  */
+	 * use __archive_read_consume to advance a read point to avoid
+	 * redundant data reading.  */
 	offset = archive_filter_bytes(&a->archive, 0);
 	if (offset < zip->entry->local_header_offset)
 		__archive_read_consume(a,
@@ -3141,3 +4040,5 @@
 		free(zip);
 	return (ARCHIVE_OK);
 }
+
+/*# vim:set noet:*/
diff --git a/Utilities/cmlibarchive/libarchive/archive_string.c b/Utilities/cmlibarchive/libarchive/archive_string.c
index 85594cc..c77dcf5 100644
--- a/Utilities/cmlibarchive/libarchive/archive_string.c
+++ b/Utilities/cmlibarchive/libarchive/archive_string.c
@@ -75,6 +75,9 @@
 #define wmemmove(a,b,i)  (wchar_t *)memmove((a), (b), (i) * sizeof(wchar_t))
 #endif
 
+#undef max
+#define max(a, b)       ((a)>(b)?(a):(b))
+
 struct archive_string_conv {
 	struct archive_string_conv	*next;
 	char				*from_charset;
@@ -458,7 +461,7 @@
 
 	if (from_cp == CP_C_LOCALE) {
 		/*
-		 * "C" locale special process.
+		 * "C" locale special processing.
 		 */
 		wchar_t *ws;
 		const unsigned char *mp;
@@ -591,7 +594,7 @@
 	 * No single byte will be more than one wide character,
 	 * so this length estimate will always be big enough.
 	 */
-	size_t wcs_length = len;
+	// size_t wcs_length = len;
 	size_t mbs_length = len;
 	const char *mbs = p;
 	wchar_t *wcs;
@@ -600,7 +603,11 @@
 
 	memset(&shift_state, 0, sizeof(shift_state));
 #endif
-	if (NULL == archive_wstring_ensure(dest, dest->length + wcs_length + 1))
+	/*
+	 * As we decided to have wcs_length == mbs_length == len
+	 * we can use len here instead of wcs_length
+	 */
+	if (NULL == archive_wstring_ensure(dest, dest->length + len + 1))
 		return (-1);
 	wcs = dest->s + dest->length;
 	/*
@@ -609,6 +616,12 @@
 	 * multi bytes.
 	 */
 	while (*mbs && mbs_length > 0) {
+		/*
+		 * The buffer we allocated is always big enough.
+		 * Keep this code path in a comment if we decide to choose
+		 * smaller wcs_length in the future
+		 */
+/*
 		if (wcs_length == 0) {
 			dest->length = wcs - dest->s;
 			dest->s[dest->length] = L'\0';
@@ -618,24 +631,20 @@
 				return (-1);
 			wcs = dest->s + dest->length;
 		}
+*/
 #if HAVE_MBRTOWC
-		r = mbrtowc(wcs, mbs, wcs_length, &shift_state);
+		r = mbrtowc(wcs, mbs, mbs_length, &shift_state);
 #else
-		r = mbtowc(wcs, mbs, wcs_length);
+		r = mbtowc(wcs, mbs, mbs_length);
 #endif
 		if (r == (size_t)-1 || r == (size_t)-2) {
 			ret_val = -1;
-			if (errno == EILSEQ) {
-				++mbs;
-				--mbs_length;
-				continue;
-			} else
-				break;
+			break;
 		}
 		if (r == 0 || r > mbs_length)
 			break;
 		wcs++;
-		wcs_length--;
+		// wcs_length--;
 		mbs += r;
 		mbs_length -= r;
 	}
@@ -680,7 +689,7 @@
 
 	if (to_cp == CP_C_LOCALE) {
 		/*
-		 * "C" locale special process.
+		 * "C" locale special processing.
 		 */
 		const wchar_t *wp = ws;
 		char *p;
@@ -799,7 +808,8 @@
 			as->s[as->length] = '\0';
 			/* Re-allocate buffer for MBS. */
 			if (archive_string_ensure(as,
-			    as->length + len * 2 + 1) == NULL)
+			    as->length + max(len * 2,
+			    (size_t)MB_CUR_MAX) + 1) == NULL)
 				return (-1);
 			p = as->s + as->length;
 			end = as->s + as->buffer_length - MB_CUR_MAX -1;
@@ -890,7 +900,7 @@
      struct archive_string_conv *))
 {
 	if (sc == NULL || sc->nconverter >= 2)
-		__archive_errx(1, "Programing error");
+		__archive_errx(1, "Programming error");
 	sc->converter[sc->nconverter++] = converter;
 }
 
@@ -3441,7 +3451,8 @@
 			as->length = p - as->s;
 			/* Re-allocate buffer for MBS. */
 			if (archive_string_ensure(as,
-			    as->length + len * 2 + 1) == NULL)
+			    as->length + max(len * 2,
+			    (size_t)MB_CUR_MAX) + 1) == NULL)
 				return (-1);
 			p = as->s + as->length;
 			end = as->s + as->buffer_length - MB_CUR_MAX -1;
@@ -4053,6 +4064,7 @@
 {
   if (utf8 == NULL) {
     aes->aes_set = 0;
+    return (0);
   }
   aes->aes_set = AES_SET_UTF8;
   archive_string_empty(&(aes->aes_mbs));
@@ -4067,6 +4079,7 @@
 {
 	if (wcs == NULL) {
 		aes->aes_set = 0;
+		return (0);
 	}
 	aes->aes_set = AES_SET_WCS; /* Only WCS form set. */
 	archive_string_empty(&(aes->aes_mbs));
diff --git a/Utilities/cmlibarchive/libarchive/archive_string.h b/Utilities/cmlibarchive/libarchive/archive_string.h
index 56dfbb2..27e1ad6 100644
--- a/Utilities/cmlibarchive/libarchive/archive_string.h
+++ b/Utilities/cmlibarchive/libarchive/archive_string.h
@@ -26,15 +26,15 @@
  *
  */
 
+#ifndef ARCHIVE_STRING_H_INCLUDED
+#define ARCHIVE_STRING_H_INCLUDED
+
 #ifndef __LIBARCHIVE_BUILD
 #ifndef __LIBARCHIVE_TEST
 #error This header is only to be used internally to libarchive.
 #endif
 #endif
 
-#ifndef ARCHIVE_STRING_H_INCLUDED
-#define	ARCHIVE_STRING_H_INCLUDED
-
 #include <stdarg.h>
 #ifdef HAVE_STDLIB_H
 #include <stdlib.h>  /* required for wchar_t on some systems */
diff --git a/Utilities/cmlibarchive/libarchive/archive_string_composition.h b/Utilities/cmlibarchive/libarchive/archive_string_composition.h
index 8902ac1..d0ac340 100644
--- a/Utilities/cmlibarchive/libarchive/archive_string_composition.h
+++ b/Utilities/cmlibarchive/libarchive/archive_string_composition.h
@@ -34,13 +34,13 @@
  *  See also http://unicode.org/report/tr15/
  */
 
+#ifndef ARCHIVE_STRING_COMPOSITION_H_INCLUDED
+#define ARCHIVE_STRING_COMPOSITION_H_INCLUDED
+
 #ifndef __LIBARCHIVE_BUILD
 #error This header is only to be used internally to libarchive.
 #endif
 
-#ifndef ARCHIVE_STRING_COMPOSITION_H_INCLUDED
-#define ARCHIVE_STRING_COMPOSITION_H_INCLUDED
-
 struct unicode_composition_table {
 	uint32_t cp1;
 	uint32_t cp2;
diff --git a/Utilities/cmlibarchive/libarchive/archive_util.3 b/Utilities/cmlibarchive/libarchive/archive_util.3
index 99ab842..d5d4e7d 100644
--- a/Utilities/cmlibarchive/libarchive/archive_util.3
+++ b/Utilities/cmlibarchive/libarchive/archive_util.3
@@ -92,10 +92,10 @@
 Not generally used in client code.
 .It Fn archive_compression
 Synonym for
-.Fn archive_filter_code(a, 0) .
+.Fn archive_filter_code a 0 .
 .It Fn archive_compression_name
 Synonym for
-.Fn archive_filter_name(a, 0) .
+.Fn archive_filter_name a 0 .
 .It Fn archive_copy_error
 Copies error information from one archive to another.
 .It Fn archive_errno
@@ -142,13 +142,13 @@
 filter 1 is the uudecode filter,
 and filter 2 is the pseudo-filter that wraps the archive read functions.
 In this case, requesting
-.Fn archive_position(a, -1)
+.Fn archive_position a -1
 would be a synonym for
-.Fn archive_position(a, 2)
+.Fn archive_position a 2
 which would return the number of bytes currently read from the archive, while
-.Fn archive_position(a, 1)
+.Fn archive_position a 1
 would return the number of bytes after uudecoding, and
-.Fn archive_position(a, 0)
+.Fn archive_position a 0
 would return the number of bytes after decompression.
 .It Fn archive_filter_name
 Returns a textual name identifying the indicated filter.
@@ -170,9 +170,9 @@
 .It Fn archive_position
 Returns the number of bytes read from or written to the indicated filter.
 In particular,
-.Fn archive_position(a, 0)
+.Fn archive_position a 0
 returns the number of bytes read or written by the format handler, while
-.Fn archive_position(a, -1)
+.Fn archive_position a -1
 returns the number of bytes read or written to the archive.
 See
 .Fn archive_filter_count
diff --git a/Utilities/cmlibarchive/libarchive/archive_util.c b/Utilities/cmlibarchive/libarchive/archive_util.c
index e5c6e3b..10dca73 100644
--- a/Utilities/cmlibarchive/libarchive/archive_util.c
+++ b/Utilities/cmlibarchive/libarchive/archive_util.c
@@ -46,13 +46,13 @@
 #include <wincrypt.h>
 #endif
 #ifdef HAVE_ZLIB_H
-#include <cm_zlib.h>
+#include <cm3p/zlib.h>
 #endif
 #ifdef HAVE_LZMA_H
-#include <cm_lzma.h>
+#include <cm3p/lzma.h>
 #endif
 #ifdef HAVE_BZLIB_H
-#include <cm_bzlib.h>
+#include <cm3p/bzlib.h>
 #endif
 #ifdef HAVE_LZ4_H
 #include <lz4.h>
@@ -218,8 +218,8 @@
  * Also Windows version of mktemp family including _mktemp_s
  * are not secure.
  */
-int
-__archive_mktemp(const char *tmpdir)
+static int
+__archive_mktempx(const char *tmpdir, wchar_t *template)
 {
 	static const wchar_t prefix[] = L"libarchive_";
 	static const wchar_t suffix[] = L"XXXXXXXXXX";
@@ -243,64 +243,76 @@
 	hProv = (HCRYPTPROV)NULL;
 	fd = -1;
 	ws = NULL;
-	archive_string_init(&temp_name);
 
-	/* Get a temporary directory. */
-	if (tmpdir == NULL) {
-		size_t l;
-		wchar_t *tmp;
+	if (template == NULL) {
+		archive_string_init(&temp_name);
 
-		l = GetTempPathW(0, NULL);
-		if (l == 0) {
-			la_dosmaperr(GetLastError());
-			goto exit_tmpfile;
-		}
-		tmp = malloc(l*sizeof(wchar_t));
-		if (tmp == NULL) {
-			errno = ENOMEM;
-			goto exit_tmpfile;
-		}
-		GetTempPathW((DWORD)l, tmp);
-		archive_wstrcpy(&temp_name, tmp);
-		free(tmp);
-	} else {
-		if (archive_wstring_append_from_mbs(&temp_name, tmpdir,
-		    strlen(tmpdir)) < 0)
-			goto exit_tmpfile;
-		if (temp_name.s[temp_name.length-1] != L'/')
-			archive_wstrappend_wchar(&temp_name, L'/');
-	}
+		/* Get a temporary directory. */
+		if (tmpdir == NULL) {
+			size_t l;
+			wchar_t *tmp;
 
-	/* Check if temp_name is a directory. */
-	attr = GetFileAttributesW(temp_name.s);
-	if (attr == (DWORD)-1) {
-		if (GetLastError() != ERROR_FILE_NOT_FOUND) {
-			la_dosmaperr(GetLastError());
-			goto exit_tmpfile;
+			l = GetTempPathW(0, NULL);
+			if (l == 0) {
+				la_dosmaperr(GetLastError());
+				goto exit_tmpfile;
+			}
+			tmp = malloc(l*sizeof(wchar_t));
+			if (tmp == NULL) {
+				errno = ENOMEM;
+				goto exit_tmpfile;
+			}
+			GetTempPathW((DWORD)l, tmp);
+			archive_wstrcpy(&temp_name, tmp);
+			free(tmp);
+		} else {
+			if (archive_wstring_append_from_mbs(&temp_name, tmpdir,
+			    strlen(tmpdir)) < 0)
+				goto exit_tmpfile;
+			if (temp_name.s[temp_name.length-1] != L'/')
+				archive_wstrappend_wchar(&temp_name, L'/');
 		}
-		ws = __la_win_permissive_name_w(temp_name.s);
-		if (ws == NULL) {
-			errno = EINVAL;
-			goto exit_tmpfile;
-		}
-		attr = GetFileAttributesW(ws);
+
+		/* Check if temp_name is a directory. */
+		attr = GetFileAttributesW(temp_name.s);
 		if (attr == (DWORD)-1) {
-			la_dosmaperr(GetLastError());
+			if (GetLastError() != ERROR_FILE_NOT_FOUND) {
+				la_dosmaperr(GetLastError());
+				goto exit_tmpfile;
+			}
+			ws = __la_win_permissive_name_w(temp_name.s);
+			if (ws == NULL) {
+				errno = EINVAL;
+				goto exit_tmpfile;
+			}
+			attr = GetFileAttributesW(ws);
+			if (attr == (DWORD)-1) {
+				la_dosmaperr(GetLastError());
+				goto exit_tmpfile;
+			}
+		}
+		if (!(attr & FILE_ATTRIBUTE_DIRECTORY)) {
+			errno = ENOTDIR;
 			goto exit_tmpfile;
 		}
-	}
-	if (!(attr & FILE_ATTRIBUTE_DIRECTORY)) {
-		errno = ENOTDIR;
-		goto exit_tmpfile;
-	}
 
-	/*
-	 * Create a temporary file.
-	 */
-	archive_wstrcat(&temp_name, prefix);
-	archive_wstrcat(&temp_name, suffix);
-	ep = temp_name.s + archive_strlen(&temp_name);
-	xp = ep - wcslen(suffix);
+		/*
+		 * Create a temporary file.
+		 */
+		archive_wstrcat(&temp_name, prefix);
+		archive_wstrcat(&temp_name, suffix);
+		ep = temp_name.s + archive_strlen(&temp_name);
+		xp = ep - wcslen(suffix);
+		template = temp_name.s;
+	} else {
+		xp = wcschr(template, L'X');
+		if (xp == NULL)	/* No X, programming error */
+			abort();
+		for (ep = xp; *ep == L'X'; ep++)
+			continue;
+		if (*ep)	/* X followed by non X, programming error */
+			abort();
+	}
 
 	if (!CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL,
 		CRYPT_VERIFYCONTEXT)) {
@@ -323,20 +335,24 @@
 			*p = num[((DWORD)*p) % (sizeof(num)/sizeof(num[0]))];
 
 		free(ws);
-		ws = __la_win_permissive_name_w(temp_name.s);
+		ws = __la_win_permissive_name_w(template);
 		if (ws == NULL) {
 			errno = EINVAL;
 			goto exit_tmpfile;
 		}
-		/* Specifies FILE_FLAG_DELETE_ON_CLOSE flag is to
-		 * delete this temporary file immediately when this
-		 * file closed. */
+		if (template == temp_name.s) {
+			attr = FILE_ATTRIBUTE_TEMPORARY |
+			       FILE_FLAG_DELETE_ON_CLOSE;
+		} else {
+			/* mkstemp */
+			attr = FILE_ATTRIBUTE_NORMAL;
+		}
 		h = CreateFileW(ws,
 		    GENERIC_READ | GENERIC_WRITE | DELETE,
 		    0,/* Not share */
 		    NULL,
 		    CREATE_NEW,/* Create a new file only */
-		    FILE_ATTRIBUTE_TEMPORARY | FILE_FLAG_DELETE_ON_CLOSE,
+		    attr,
 		    NULL);
 		if (h == INVALID_HANDLE_VALUE) {
 			/* The same file already exists. retry with
@@ -358,10 +374,23 @@
 	if (hProv != (HCRYPTPROV)NULL)
 		CryptReleaseContext(hProv, 0);
 	free(ws);
-	archive_wstring_free(&temp_name);
+	if (template == temp_name.s)
+		archive_wstring_free(&temp_name);
 	return (fd);
 }
 
+int
+__archive_mktemp(const char *tmpdir)
+{
+	return __archive_mktempx(tmpdir, NULL);
+}
+
+int
+__archive_mkstemp(wchar_t *template)
+{
+	return __archive_mktempx(NULL, template);
+}
+
 #else
 
 static int
@@ -414,14 +443,24 @@
 	return (fd);
 }
 
-#else
+int
+__archive_mkstemp(char *template)
+{
+	int fd = -1;
+	fd = mkstemp(template);
+	if (fd >= 0)
+		__archive_ensure_cloexec_flag(fd);
+	return (fd);
+}
+
+#else /* !HAVE_MKSTEMP */
 
 /*
  * We use a private routine.
  */
 
-int
-__archive_mktemp(const char *tmpdir)
+static int
+__archive_mktempx(const char *tmpdir, char *template)
 {
         static const char num[] = {
 		'0', '1', '2', '3', '4', '5', '6', '7',
@@ -439,26 +478,37 @@
 	char *tp, *ep;
 
 	fd = -1;
-	archive_string_init(&temp_name);
-	if (tmpdir == NULL) {
-		if (get_tempdir(&temp_name) != ARCHIVE_OK)
+	if (template == NULL) {
+		archive_string_init(&temp_name);
+		if (tmpdir == NULL) {
+			if (get_tempdir(&temp_name) != ARCHIVE_OK)
+				goto exit_tmpfile;
+		} else
+			archive_strcpy(&temp_name, tmpdir);
+		if (temp_name.s[temp_name.length-1] == '/') {
+			temp_name.s[temp_name.length-1] = '\0';
+			temp_name.length --;
+		}
+		if (la_stat(temp_name.s, &st) < 0)
 			goto exit_tmpfile;
-	} else
-		archive_strcpy(&temp_name, tmpdir);
-	if (temp_name.s[temp_name.length-1] == '/') {
-		temp_name.s[temp_name.length-1] = '\0';
-		temp_name.length --;
+		if (!S_ISDIR(st.st_mode)) {
+			errno = ENOTDIR;
+			goto exit_tmpfile;
+		}
+		archive_strcat(&temp_name, "/libarchive_");
+		tp = temp_name.s + archive_strlen(&temp_name);
+		archive_strcat(&temp_name, "XXXXXXXXXX");
+		ep = temp_name.s + archive_strlen(&temp_name);
+		template = temp_name.s;
+	} else {
+		tp = strchr(template, 'X');
+		if (tp == NULL)	/* No X, programming error */
+			abort();
+		for (ep = tp; *ep == 'X'; ep++)
+			continue;
+		if (*ep)	/* X followed by non X, programming error */
+			abort();
 	}
-	if (stat(temp_name.s, &st) < 0)
-		goto exit_tmpfile;
-	if (!S_ISDIR(st.st_mode)) {
-		errno = ENOTDIR;
-		goto exit_tmpfile;
-	}
-	archive_strcat(&temp_name, "/libarchive_");
-	tp = temp_name.s + archive_strlen(&temp_name);
-	archive_strcat(&temp_name, "XXXXXXXXXX");
-	ep = temp_name.s + archive_strlen(&temp_name);
 
 	do {
 		char *p;
@@ -469,19 +519,33 @@
 			int d = *((unsigned char *)p) % sizeof(num);
 			*p++ = num[d];
 		}
-		fd = open(temp_name.s, O_CREAT | O_EXCL | O_RDWR | O_CLOEXEC,
+		fd = open(template, O_CREAT | O_EXCL | O_RDWR | O_CLOEXEC,
 			  0600);
 	} while (fd < 0 && errno == EEXIST);
 	if (fd < 0)
 		goto exit_tmpfile;
 	__archive_ensure_cloexec_flag(fd);
-	unlink(temp_name.s);
+	if (template == temp_name.s)
+		unlink(temp_name.s);
 exit_tmpfile:
-	archive_string_free(&temp_name);
+	if (template == temp_name.s)
+		archive_string_free(&temp_name);
 	return (fd);
 }
 
-#endif /* HAVE_MKSTEMP */
+int
+__archive_mktemp(const char *tmpdir)
+{
+	return __archive_mktempx(tmpdir, NULL);
+}
+
+int
+__archive_mkstemp(char *template)
+{
+	return __archive_mktempx(NULL, template);
+}
+
+#endif /* !HAVE_MKSTEMP */
 #endif /* !_WIN32 || __CYGWIN__ */
 
 /*
diff --git a/Utilities/cmlibarchive/libarchive/archive_version_details.c b/Utilities/cmlibarchive/libarchive/archive_version_details.c
index b9af6d7..5f5a5b7 100644
--- a/Utilities/cmlibarchive/libarchive/archive_version_details.c
+++ b/Utilities/cmlibarchive/libarchive/archive_version_details.c
@@ -34,19 +34,19 @@
 #include <string.h>
 #endif
 #ifdef HAVE_ZLIB_H
-#include <cm_zlib.h>
+#include <cm3p/zlib.h>
 #endif
 #ifdef HAVE_LZMA_H
-#include <cm_lzma.h>
+#include <cm3p/lzma.h>
 #endif
 #ifdef HAVE_BZLIB_H
-#include <cm_bzlib.h>
+#include <cm3p/bzlib.h>
 #endif
 #ifdef HAVE_LZ4_H
 #include <lz4.h>
 #endif
 #ifdef HAVE_ZSTD_H
-#include <cm_zstd.h>
+#include <cm3p/zstd.h>
 #endif
 
 #include "archive.h"
diff --git a/Utilities/cmlibarchive/libarchive/archive_windows.c b/Utilities/cmlibarchive/libarchive/archive_windows.c
index 6ff8749..624e270 100644
--- a/Utilities/cmlibarchive/libarchive/archive_windows.c
+++ b/Utilities/cmlibarchive/libarchive/archive_windows.c
@@ -445,7 +445,8 @@
  * Windows' stat() does not accept the path added "\\?\" especially "?"
  * character.
  * It means we cannot access the long name path longer than MAX_PATH.
- * So I've implemented simular Windows' stat() to access the long name path.
+ * So I've implemented a function similar to Windows' stat() to access the
+ * long name path.
  * And I've added some feature.
  * 1. set st_ino by nFileIndexHigh and nFileIndexLow of
  *    BY_HANDLE_FILE_INFORMATION.
diff --git a/Utilities/cmlibarchive/libarchive/archive_windows.h b/Utilities/cmlibarchive/libarchive/archive_windows.h
index c3aed0c..dda63b8 100644
--- a/Utilities/cmlibarchive/libarchive/archive_windows.h
+++ b/Utilities/cmlibarchive/libarchive/archive_windows.h
@@ -27,10 +27,6 @@
  * $FreeBSD$
  */
 
-#ifndef __LIBARCHIVE_BUILD
-#error This header is only to be used internally to libarchive.
-#endif
-
 /*
  * TODO: A lot of stuff in here isn't actually used by libarchive and
  * can be trimmed out.  Note that this file is used by libarchive and
@@ -48,6 +44,10 @@
 #ifndef LIBARCHIVE_ARCHIVE_WINDOWS_H_INCLUDED
 #define	LIBARCHIVE_ARCHIVE_WINDOWS_H_INCLUDED
 
+#ifndef __LIBARCHIVE_BUILD
+#error This header is only to be used internally to libarchive.
+#endif
+
 /* Start of configuration for native Win32  */
 #ifndef MINGW_HAS_SECURE_API
 #define MINGW_HAS_SECURE_API 1
@@ -117,10 +117,7 @@
 #if !defined(__BORLANDC__) && !defined(__WATCOMC__)
 #define setmode		_setmode
 #endif
-#ifdef stat
-#undef stat
-#endif
-#define	stat(path,stref)		__la_stat(path,stref)
+#define	la_stat(path,stref)		__la_stat(path,stref)
 #if !defined(__WATCOMC__)
 #if !defined(__BORLANDC__)
 #define	strdup		_strdup
diff --git a/Utilities/cmlibarchive/libarchive/archive_write.3 b/Utilities/cmlibarchive/libarchive/archive_write.3
index c1164f5..e7f7f13 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write.3
+++ b/Utilities/cmlibarchive/libarchive/archive_write.3
@@ -118,7 +118,7 @@
 .Fn archive_write_free
 function to release all resources.
 .\"
-.Sh EXAMPLE
+.Sh EXAMPLES
 The following sketch illustrates basic usage of the library.
 In this example,
 the callback functions are simply wrappers around the standard
@@ -192,7 +192,7 @@
   if (archive_write_set_format_filter_by_ext(a, outname) != ARCHIVE_OK)  {
     archive_write_add_filter_gzip(a);
     archive_write_set_format_ustar(a);
-  }  
+  }
   archive_write_open(a, mydata, myopen, mywrite, myclose);
   while (*filename) {
     stat(*filename, &st);
@@ -225,8 +225,8 @@
 .Ed
 .Sh SEE ALSO
 .Xr tar 1 ,
-.Xr libarchive 3 ,
 .Xr archive_write_set_options 3 ,
+.Xr libarchive 3 ,
 .Xr cpio 5 ,
 .Xr mtree 5 ,
 .Xr tar 5
diff --git a/Utilities/cmlibarchive/libarchive/archive_write.c b/Utilities/cmlibarchive/libarchive/archive_write.c
index e8daf53..98a55fb 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write.c
+++ b/Utilities/cmlibarchive/libarchive/archive_write.c
@@ -212,6 +212,7 @@
 
 	f = calloc(1, sizeof(*f));
 	f->archive = _a;
+	f->state = ARCHIVE_WRITE_FILTER_STATE_NEW;
 	if (a->filter_first == NULL)
 		a->filter_first = f;
 	else
@@ -228,6 +229,9 @@
     const void *buff, size_t length)
 {
 	int r;
+	/* Never write to non-open filters */
+	if (f->state != ARCHIVE_WRITE_FILTER_STATE_OPEN)
+		return(ARCHIVE_FATAL);
 	if (length == 0)
 		return(ARCHIVE_OK);
 	if (f->write == NULL)
@@ -240,27 +244,70 @@
 }
 
 /*
- * Open a filter.
+ * Recursive function for opening the filter chain
+ * Last filter is opened first
  */
-int
+static int
 __archive_write_open_filter(struct archive_write_filter *f)
 {
-	if (f->open == NULL)
+	int ret;
+
+	ret = ARCHIVE_OK;
+	if (f->next_filter != NULL)
+		ret = __archive_write_open_filter(f->next_filter);
+	if (ret != ARCHIVE_OK)
+		return (ret);
+	if (f->state != ARCHIVE_WRITE_FILTER_STATE_NEW)
+		return (ARCHIVE_FATAL);
+	if (f->open == NULL) {
+		f->state = ARCHIVE_WRITE_FILTER_STATE_OPEN;
 		return (ARCHIVE_OK);
-	return (f->open)(f);
+	}
+	ret = (f->open)(f);
+	if (ret == ARCHIVE_OK)
+		f->state = ARCHIVE_WRITE_FILTER_STATE_OPEN;
+	else
+		f->state = ARCHIVE_WRITE_FILTER_STATE_FATAL;
+	return (ret);
 }
 
 /*
- * Close a filter.
+ * Open all filters
  */
-int
-__archive_write_close_filter(struct archive_write_filter *f)
+static int
+__archive_write_filters_open(struct archive_write *a)
 {
-	if (f->close != NULL)
-		return (f->close)(f);
-	if (f->next_filter != NULL)
-		return (__archive_write_close_filter(f->next_filter));
-	return (ARCHIVE_OK);
+	return (__archive_write_open_filter(a->filter_first));
+}
+
+/*
+ * Close all filtes
+ */
+static int
+__archive_write_filters_close(struct archive_write *a)
+{
+	struct archive_write_filter *f;
+	int ret, ret1;
+	ret = ARCHIVE_OK;
+	for (f = a->filter_first; f != NULL; f = f->next_filter) {
+		/* Do not close filters that are not open */
+		if (f->state == ARCHIVE_WRITE_FILTER_STATE_OPEN) {
+			if (f->close != NULL) {
+				ret1 = (f->close)(f);
+				if (ret1 < ret)
+					ret = ret1;
+				if (ret1 == ARCHIVE_OK) {
+					f->state =
+					    ARCHIVE_WRITE_FILTER_STATE_CLOSED;
+				} else {
+					f->state =
+					    ARCHIVE_WRITE_FILTER_STATE_FATAL;
+				}
+			} else
+				f->state = ARCHIVE_WRITE_FILTER_STATE_CLOSED;
+		}
+	}
+	return (ret);
 }
 
 int
@@ -292,6 +339,7 @@
 	struct archive_none *state;
 	void *buffer;
 	size_t buffer_size;
+	int ret;
 
 	f->bytes_per_block = archive_write_get_bytes_per_block(f->archive);
 	f->bytes_in_last_block =
@@ -316,7 +364,13 @@
 
 	if (a->client_opener == NULL)
 		return (ARCHIVE_OK);
-	return (a->client_opener(f->archive, a->client_data));
+	ret = a->client_opener(f->archive, a->client_data);
+	if (ret != ARCHIVE_OK) {
+		free(state->buffer);
+		free(state);
+		f->data = NULL;
+	}
+	return (ret);
 }
 
 static int
@@ -439,8 +493,6 @@
 		(*a->client_closer)(&a->archive, a->client_data);
 	free(state->buffer);
 	free(state);
-	/* Clear the close handler myself not to be called again. */
-	f->close = NULL;
 	a->client_data = NULL;
 	/* Clear passphrase. */
 	if (a->passphrase != NULL) {
@@ -448,6 +500,8 @@
 		free(a->passphrase);
 		a->passphrase = NULL;
 	}
+	/* Clear the close handler myself not to be called again. */
+	f->state = ARCHIVE_WRITE_FILTER_STATE_CLOSED;
 	return (ret);
 }
 
@@ -477,9 +531,10 @@
 	client_filter->write = archive_write_client_write;
 	client_filter->close = archive_write_client_close;
 
-	ret = __archive_write_open_filter(a->filter_first);
+	ret = __archive_write_filters_open(a);
 	if (ret < ARCHIVE_WARN) {
-		r1 = __archive_write_close_filter(a->filter_first);
+		r1 = __archive_write_filters_close(a);
+		__archive_write_filters_free(_a);
 		return (r1 < ret ? r1 : ret);
 	}
 
@@ -521,7 +576,7 @@
 	}
 
 	/* Finish the compression and close the stream. */
-	r1 = __archive_write_close_filter(a->filter_first);
+	r1 = __archive_write_filters_close(a);
 	if (r1 < r)
 		r = r1;
 
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_add_filter_b64encode.c b/Utilities/cmlibarchive/libarchive/archive_write_add_filter_b64encode.c
index b46b19a..87fdb73 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_add_filter_b64encode.c
+++ b/Utilities/cmlibarchive/libarchive/archive_write_add_filter_b64encode.c
@@ -149,11 +149,6 @@
 {
 	struct private_b64encode *state = (struct private_b64encode *)f->data;
 	size_t bs = 65536, bpb;
-	int ret;
-
-	ret = __archive_write_open_filter(f->next_filter);
-	if (ret != ARCHIVE_OK)
-		return (ret);
 
 	if (f->archive->magic == ARCHIVE_WRITE_MAGIC) {
 		/* Buffer size should be a multiple number of the of bytes
@@ -266,7 +261,6 @@
 archive_filter_b64encode_close(struct archive_write_filter *f)
 {
 	struct private_b64encode *state = (struct private_b64encode *)f->data;
-	int ret, ret2;
 
 	/* Flush remaining bytes. */
 	if (state->hold_len != 0)
@@ -274,12 +268,8 @@
 	archive_string_sprintf(&state->encoded_buff, "====\n");
 	/* Write the last block */
 	archive_write_set_bytes_in_last_block(f->archive, 1);
-	ret = __archive_write_filter(f->next_filter,
+	return __archive_write_filter(f->next_filter,
 	    state->encoded_buff.s, archive_strlen(&state->encoded_buff));
-	ret2 = __archive_write_close_filter(f->next_filter);
-	if (ret > ret2)
-		ret = ret2;
-	return (ret);
 }
 
 static int
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_add_filter_bzip2.c b/Utilities/cmlibarchive/libarchive/archive_write_add_filter_bzip2.c
index 6bd0d1d..0637e96 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_add_filter_bzip2.c
+++ b/Utilities/cmlibarchive/libarchive/archive_write_add_filter_bzip2.c
@@ -39,7 +39,7 @@
 #include <string.h>
 #endif
 #ifdef HAVE_BZLIB_H
-#include <cm_bzlib.h>
+#include <cm3p/bzlib.h>
 #endif
 
 #include "archive.h"
@@ -167,10 +167,6 @@
 	struct private_data *data = (struct private_data *)f->data;
 	int ret;
 
-	ret = __archive_write_open_filter(f->next_filter);
-	if (ret != 0)
-		return (ret);
-
 	if (data->compressed == NULL) {
 		size_t bs = 65536, bpb;
 		if (f->archive->magic == ARCHIVE_WRITE_MAGIC) {
@@ -262,7 +258,7 @@
 archive_compressor_bzip2_close(struct archive_write_filter *f)
 {
 	struct private_data *data = (struct private_data *)f->data;
-	int ret, r1;
+	int ret;
 
 	/* Finish compression cycle. */
 	ret = drive_compressor(f, data, 1);
@@ -281,9 +277,7 @@
 		    "Failed to clean up compressor");
 		ret = ARCHIVE_FATAL;
 	}
-
-	r1 = __archive_write_close_filter(f->next_filter);
-	return (r1 < ret ? r1 : ret);
+	return ret;
 }
 
 static int
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_add_filter_compress.c b/Utilities/cmlibarchive/libarchive/archive_write_add_filter_compress.c
index 26fcef4..d404fae 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_add_filter_compress.c
+++ b/Utilities/cmlibarchive/libarchive/archive_write_add_filter_compress.c
@@ -146,17 +146,12 @@
 static int
 archive_compressor_compress_open(struct archive_write_filter *f)
 {
-	int ret;
 	struct private_data *state;
 	size_t bs = 65536, bpb;
 
 	f->code = ARCHIVE_FILTER_COMPRESS;
 	f->name = "compress";
 
-	ret = __archive_write_open_filter(f->next_filter);
-	if (ret != ARCHIVE_OK)
-		return (ret);
-
 	state = (struct private_data *)calloc(1, sizeof(*state));
 	if (state == NULL) {
 		archive_set_error(f->archive, ENOMEM,
@@ -426,30 +421,27 @@
 archive_compressor_compress_close(struct archive_write_filter *f)
 {
 	struct private_data *state = (struct private_data *)f->data;
-	int ret, ret2;
+	int ret;
 
 	ret = output_code(f, state->cur_code);
 	if (ret != ARCHIVE_OK)
-		goto cleanup;
+		return ret;
 	ret = output_flush(f);
 	if (ret != ARCHIVE_OK)
-		goto cleanup;
+		return ret;
 
 	/* Write the last block */
 	ret = __archive_write_filter(f->next_filter,
 	    state->compressed, state->compressed_offset);
-cleanup:
-	ret2 = __archive_write_close_filter(f->next_filter);
-	if (ret > ret2)
-		ret = ret2;
-	free(state->compressed);
-	free(state);
 	return (ret);
 }
 
 static int
 archive_compressor_compress_free(struct archive_write_filter *f)
 {
-	(void)f; /* UNUSED */
+	struct private_data *state = (struct private_data *)f->data;
+
+	free(state->compressed);
+	free(state);
 	return (ARCHIVE_OK);
 }
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_add_filter_gzip.c b/Utilities/cmlibarchive/libarchive/archive_write_add_filter_gzip.c
index 986123a..3e26605 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_add_filter_gzip.c
+++ b/Utilities/cmlibarchive/libarchive/archive_write_add_filter_gzip.c
@@ -38,7 +38,7 @@
 #endif
 #include <time.h>
 #ifdef HAVE_ZLIB_H
-#include <cm_zlib.h>
+#include <cm3p/zlib.h>
 #endif
 
 #include "archive.h"
@@ -184,10 +184,6 @@
 	struct private_data *data = (struct private_data *)f->data;
 	int ret;
 
-	ret = __archive_write_open_filter(f->next_filter);
-	if (ret != ARCHIVE_OK)
-		return (ret);
-
 	if (data->compressed == NULL) {
 		size_t bs = 65536, bpb;
 		if (f->archive->magic == ARCHIVE_WRITE_MAGIC) {
@@ -307,7 +303,7 @@
 {
 	unsigned char trailer[8];
 	struct private_data *data = (struct private_data *)f->data;
-	int ret, r1;
+	int ret;
 
 	/* Finish compression cycle */
 	ret = drive_compressor(f, data, 1);
@@ -338,8 +334,7 @@
 		    "Failed to clean up compressor");
 		ret = ARCHIVE_FATAL;
 	}
-	r1 = __archive_write_close_filter(f->next_filter);
-	return (r1 < ret ? r1 : ret);
+	return ret;
 }
 
 /*
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_add_filter_lz4.c b/Utilities/cmlibarchive/libarchive/archive_write_add_filter_lz4.c
index 15fd494..cf19fad 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_add_filter_lz4.c
+++ b/Utilities/cmlibarchive/libarchive/archive_write_add_filter_lz4.c
@@ -223,16 +223,11 @@
 archive_filter_lz4_open(struct archive_write_filter *f)
 {
 	struct private_data *data = (struct private_data *)f->data;
-	int ret;
 	size_t required_size;
 	static size_t const bkmap[] = { 64 * 1024, 256 * 1024, 1 * 1024 * 1024,
 			   4 * 1024 * 1024 };
 	size_t pre_block_size;
 
-	ret = __archive_write_open_filter(f->next_filter);
-	if (ret != 0)
-		return (ret);
-
 	if (data->block_maximum_size < 4)
 		data->block_size = bkmap[0];
 	else
@@ -343,7 +338,7 @@
 archive_filter_lz4_close(struct archive_write_filter *f)
 {
 	struct private_data *data = (struct private_data *)f->data;
-	int ret, r1;
+	int ret;
 
 	/* Finish compression cycle. */
 	ret = (int)lz4_write_one_block(f, NULL, 0);
@@ -366,9 +361,7 @@
 		ret = __archive_write_filter(f->next_filter,
 			    data->out_buffer, data->out - data->out_buffer);
 	}
-
-	r1 = __archive_write_close_filter(f->next_filter);
-	return (r1 < ret ? r1 : ret);
+	return ret;
 }
 
 static int
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_add_filter_lzop.c b/Utilities/cmlibarchive/libarchive/archive_write_add_filter_lzop.c
index ad705c4..3bd9062 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_add_filter_lzop.c
+++ b/Utilities/cmlibarchive/libarchive/archive_write_add_filter_lzop.c
@@ -228,11 +228,6 @@
 archive_write_lzop_open(struct archive_write_filter *f)
 {
 	struct write_lzop *data = (struct write_lzop *)f->data;
-	int ret;
-
-	ret = __archive_write_open_filter(f->next_filter);
-	if (ret != ARCHIVE_OK)
-		return (ret);
 
 	switch (data->compression_level) {
 	case 1:
@@ -439,10 +434,7 @@
 	}
 	/* Write a zero uncompressed size as the end mark of the series of
 	 * compressed block. */
-	r = __archive_write_filter(f->next_filter, &endmark, sizeof(endmark));
-	if (r != ARCHIVE_OK)
-		return (r);
-	return (__archive_write_close_filter(f->next_filter));
+	return __archive_write_filter(f->next_filter, &endmark, sizeof(endmark));
 }
 
 #else
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_add_filter_program.c b/Utilities/cmlibarchive/libarchive/archive_write_add_filter_program.c
index 660f693..a4bc1d9 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_add_filter_program.c
+++ b/Utilities/cmlibarchive/libarchive/archive_write_add_filter_program.c
@@ -212,11 +212,6 @@
     struct archive_write_program_data *data, const char *cmd)
 {
 	pid_t child;
-	int ret;
-
-	ret = __archive_write_open_filter(f->next_filter);
-	if (ret != ARCHIVE_OK)
-		return (ret);
 
 	if (data->child_buf == NULL) {
 		data->child_buf_len = 65536;
@@ -353,11 +348,11 @@
 __archive_write_program_close(struct archive_write_filter *f,
     struct archive_write_program_data *data)
 {
-	int ret, r1, status;
+	int ret, status;
 	ssize_t bytes_read;
 
 	if (data->child == 0)
-		return __archive_write_close_filter(f->next_filter);
+		return ARCHIVE_OK;
 
 	ret = 0;
 	close(data->child_stdin);
@@ -409,7 +404,6 @@
 		    "Error closing program: %s", data->program_name);
 		ret = ARCHIVE_FATAL;
 	}
-	r1 = __archive_write_close_filter(f->next_filter);
-	return (r1 < ret ? r1 : ret);
+	return ret;
 }
 
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_add_filter_uuencode.c b/Utilities/cmlibarchive/libarchive/archive_write_add_filter_uuencode.c
index 23d9c15..1ad4589 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_add_filter_uuencode.c
+++ b/Utilities/cmlibarchive/libarchive/archive_write_add_filter_uuencode.c
@@ -138,11 +138,6 @@
 {
 	struct private_uuencode *state = (struct private_uuencode *)f->data;
 	size_t bs = 65536, bpb;
-	int ret;
-
-	ret = __archive_write_open_filter(f->next_filter);
-	if (ret != ARCHIVE_OK)
-		return (ret);
 
 	if (f->archive->magic == ARCHIVE_WRITE_MAGIC) {
 		/* Buffer size should be a multiple number of the of bytes
@@ -257,7 +252,6 @@
 archive_filter_uuencode_close(struct archive_write_filter *f)
 {
 	struct private_uuencode *state = (struct private_uuencode *)f->data;
-	int ret, ret2;
 
 	/* Flush remaining bytes. */
 	if (state->hold_len != 0)
@@ -265,12 +259,8 @@
 	archive_string_sprintf(&state->encoded_buff, "`\nend\n");
 	/* Write the last block */
 	archive_write_set_bytes_in_last_block(f->archive, 1);
-	ret = __archive_write_filter(f->next_filter,
+	return __archive_write_filter(f->next_filter,
 	    state->encoded_buff.s, archive_strlen(&state->encoded_buff));
-	ret2 = __archive_write_close_filter(f->next_filter);
-	if (ret > ret2)
-		ret = ret2;
-	return (ret);
 }
 
 static int
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_add_filter_xz.c b/Utilities/cmlibarchive/libarchive/archive_write_add_filter_xz.c
index e4a3535..d567ac9 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_add_filter_xz.c
+++ b/Utilities/cmlibarchive/libarchive/archive_write_add_filter_xz.c
@@ -39,7 +39,7 @@
 #endif
 #include <time.h>
 #ifdef HAVE_LZMA_H
-#include <cm_lzma.h>
+#include <cm3p/lzma.h>
 #endif
 
 #include "archive.h"
@@ -309,10 +309,6 @@
 	struct private_data *data = f->data;
 	int ret;
 
-	ret = __archive_write_open_filter(f->next_filter);
-	if (ret != ARCHIVE_OK)
-		return (ret);
-
 	if (data->compressed == NULL) {
 		size_t bs = 65536, bpb;
 		if (f->archive->magic == ARCHIVE_WRITE_MAGIC) {
@@ -390,10 +386,13 @@
 			data->compression_level = 6;
 		return (ARCHIVE_OK);
 	} else if (strcmp(key, "threads") == 0) {
+		char *endptr;
+
 		if (value == NULL)
 			return (ARCHIVE_WARN);
-		data->threads = (int)strtoul(value, NULL, 10);
-		if (data->threads == 0 && errno != 0) {
+		errno = 0;
+		data->threads = (int)strtoul(value, &endptr, 10);
+		if (errno != 0 || *endptr != '\0') {
 			data->threads = 1;
 			return (ARCHIVE_WARN);
 		}
@@ -445,7 +444,7 @@
 archive_compressor_xz_close(struct archive_write_filter *f)
 {
 	struct private_data *data = (struct private_data *)f->data;
-	int ret, r1;
+	int ret;
 
 	ret = drive_compressor(f, data, 1);
 	if (ret == ARCHIVE_OK) {
@@ -463,8 +462,7 @@
 		}
 	}
 	lzma_end(&(data->stream));
-	r1 = __archive_write_close_filter(f->next_filter);
-	return (r1 < ret ? r1 : ret);
+	return ret;
 }
 
 static int
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_add_filter_zstd.c b/Utilities/cmlibarchive/libarchive/archive_write_add_filter_zstd.c
index 251b17d..f67b025 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_add_filter_zstd.c
+++ b/Utilities/cmlibarchive/libarchive/archive_write_add_filter_zstd.c
@@ -38,7 +38,7 @@
 #include <string.h>
 #endif
 #ifdef HAVE_ZSTD_H
-#include <cm_zstd.h>
+#include <cm3p/zstd.h>
 #endif
 
 #include "archive.h"
@@ -172,11 +172,6 @@
 archive_compressor_zstd_open(struct archive_write_filter *f)
 {
 	struct private_data *data = (struct private_data *)f->data;
-	int ret;
-
-	ret = __archive_write_open_filter(f->next_filter);
-	if (ret != ARCHIVE_OK)
-		return (ret);
 
 	if (data->out.dst == NULL) {
 		size_t bs = ZSTD_CStreamOutSize(), bpb;
@@ -238,14 +233,9 @@
 archive_compressor_zstd_close(struct archive_write_filter *f)
 {
 	struct private_data *data = (struct private_data *)f->data;
-	int r1, r2;
 
 	/* Finish zstd frame */
-	r1 = drive_compressor(f, data, 1, NULL, 0);
-
-	r2 = __archive_write_close_filter(f->next_filter);
-
-	return r1 < r2 ? r1 : r2;
+	return drive_compressor(f, data, 1, NULL, 0);
 }
 
 /*
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_blocksize.3 b/Utilities/cmlibarchive/libarchive/archive_write_blocksize.3
index afd84ea..4973f99 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_blocksize.3
+++ b/Utilities/cmlibarchive/libarchive/archive_write_blocksize.3
@@ -107,8 +107,8 @@
 .\"
 .Sh SEE ALSO
 .Xr tar 1 ,
-.Xr libarchive 3 ,
 .Xr archive_write_set_options 3 ,
+.Xr libarchive 3 ,
 .Xr cpio 5 ,
 .Xr mtree 5 ,
 .Xr tar 5
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_data.3 b/Utilities/cmlibarchive/libarchive/archive_write_data.3
index 9c16cd9..bc208b4 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_data.3
+++ b/Utilities/cmlibarchive/libarchive/archive_write_data.3
@@ -82,9 +82,9 @@
 .\"
 .Sh SEE ALSO
 .Xr tar 1 ,
-.Xr libarchive 3 ,
 .Xr archive_write_finish_entry 3 ,
 .Xr archive_write_set_options 3 ,
+.Xr libarchive 3 ,
 .Xr cpio 5 ,
 .Xr mtree 5 ,
 .Xr tar 5
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_disk.3 b/Utilities/cmlibarchive/libarchive/archive_write_disk.3
index 949c9ef..2fa016e 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_disk.3
+++ b/Utilities/cmlibarchive/libarchive/archive_write_disk.3
@@ -24,7 +24,7 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd April 3, 2017
+.Dd January 19, 2020
 .Dt ARCHIVE_WRITE_DISK 3
 .Os
 .Sh NAME
@@ -113,7 +113,8 @@
 .Pq FreeBSD, Mac OS X
 for more information on file attributes.
 .It Cm ARCHIVE_EXTRACT_MAC_METADATA
-Mac OS X specific. Restore metadata using
+Mac OS X specific.
+Restore metadata using
 .Xr copyfile 3 .
 By default,
 .Xr copyfile 3
@@ -138,6 +139,11 @@
 if the default user and group IDs of newly-created objects on disk
 happen to match those specified in the archive entry.
 By default, only basic permissions are restored, and umask is obeyed.
+.It Cm ARCHIVE_EXTRACT_SAFE_WRITES
+Extract files atomically, by first creating a unique temporary file and then
+renaming it to its required destination name.
+This avoids a race where an application might see a partial file (or no
+file) during extraction.
 .It Cm ARCHIVE_EXTRACT_SECURE_NOABSOLUTEPATHS
 Refuse to extract an absolute path.
 The default is to not refuse such paths.
@@ -264,9 +270,9 @@
 functions.
 .\"
 .Sh SEE ALSO
+.Xr tar 1 ,
 .Xr archive_read 3 ,
 .Xr archive_write 3 ,
-.Xr tar 1 ,
 .Xr libarchive 3
 .Sh HISTORY
 The
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_disk_posix.c b/Utilities/cmlibarchive/libarchive/archive_write_disk_posix.c
index affa503..c4be9b0 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_disk_posix.c
+++ b/Utilities/cmlibarchive/libarchive/archive_write_disk_posix.c
@@ -131,7 +131,7 @@
 #endif
 
 #ifdef HAVE_ZLIB_H
-#include <cm_zlib.h>
+#include <cm3p/zlib.h>
 #endif
 
 /* TODO: Support Mac OS 'quarantine' feature.  This is really just a
@@ -165,6 +165,10 @@
 #define O_NOFOLLOW 0
 #endif
 
+#ifndef AT_FDCWD
+#define AT_FDCWD -100
+#endif
+
 struct fixup_entry {
 	struct fixup_entry	*next;
 	struct archive_acl	 acl;
@@ -249,6 +253,8 @@
 	struct archive_entry	*entry; /* Entry being extracted. */
 	char			*name; /* Name of entry, possibly edited. */
 	struct archive_string	 _name_data; /* backing store for 'name' */
+	char			*tmpname; /* Temporary name * */
+	struct archive_string	 _tmpname_data; /* backing store for 'tmpname' */
 	/* Tasks remaining for this object. */
 	int			 todo;
 	/* Tasks deferred until end-of-archive. */
@@ -348,6 +354,9 @@
 
 #define HFS_BLOCKS(s)	((s) >> 12)
 
+
+static int	la_opendirat(int, const char *);
+static int	la_mktemp(struct archive_write_disk *);
 static void	fsobj_error(int *, struct archive_string *, int, const char *,
 		    const char *);
 static int	check_symlinks_fsobj(char *, int *, struct archive_string *,
@@ -401,6 +410,61 @@
 		    size_t, int64_t);
 
 static int
+la_mktemp(struct archive_write_disk *a)
+{
+	int oerrno, fd;
+	mode_t mode;
+
+	archive_string_empty(&a->_tmpname_data);
+	archive_string_sprintf(&a->_tmpname_data, "%s.XXXXXX", a->name);
+	a->tmpname = a->_tmpname_data.s;
+
+	fd = __archive_mkstemp(a->tmpname);
+	if (fd == -1)
+		return -1;
+
+	mode = a->mode & 0777 & ~a->user_umask;
+	if (fchmod(fd, mode) == -1) {
+		oerrno = errno;
+		close(fd);
+		errno = oerrno;
+		return -1;
+	}
+	return fd;
+}
+
+static int
+la_opendirat(int fd, const char *path) {
+	const int flags = O_CLOEXEC
+#if defined(O_BINARY)
+	    | O_BINARY
+#endif
+#if defined(O_DIRECTORY)
+	    | O_DIRECTORY
+#endif
+#if defined(O_PATH)
+	    | O_PATH
+#elif defined(O_SEARCH)
+	    | O_SEARCH
+#elif defined(__FreeBSD__) && defined(O_EXEC)
+	    | O_EXEC
+#else
+	    | O_RDONLY
+#endif
+	    ;
+
+#if !defined(HAVE_OPENAT)
+	if (fd != AT_FDCWD) {
+		errno = ENOTSUP;
+		return (-1);
+	} else
+		return (open(path, flags));
+#else
+	return (openat(fd, path, flags));
+#endif
+}
+
+static int
 lazy_stat(struct archive_write_disk *a)
 {
 	if (a->pst != NULL) {
@@ -1705,6 +1769,20 @@
 	}
 
 	/*
+	 * HYPOTHESIS:
+	 * If we're not root, we won't be setting any security
+	 * attributes that may be wiped by the set_mode() routine
+	 * below.  We also can't set xattr on non-owner-writable files,
+	 * which may be the state after set_mode(). Perform
+	 * set_xattrs() first based on these constraints.
+	 */
+	if (a->user_uid != 0 &&
+	    (a->todo & TODO_XATTR)) {
+		int r2 = set_xattrs(a);
+		if (r2 < ret) ret = r2;
+	}
+
+	/*
 	 * set_mode must precede ACLs on systems such as Solaris and
 	 * FreeBSD where setting the mode implicitly clears extended ACLs
 	 */
@@ -1717,8 +1795,10 @@
 	 * Security-related extended attributes (such as
 	 * security.capability on Linux) have to be restored last,
 	 * since they're implicitly removed by other file changes.
+	 * We do this last only when root.
 	 */
-	if (a->todo & TODO_XATTR) {
+	if (a->user_uid == 0 &&
+	    (a->todo & TODO_XATTR)) {
 		int r2 = set_xattrs(a);
 		if (r2 < ret) ret = r2;
 	}
@@ -1773,12 +1853,18 @@
 	if (a->fd >= 0) {
 		close(a->fd);
 		a->fd = -1;
+		if (a->tmpname) {
+			if (rename(a->tmpname, a->name) == -1) {
+				archive_set_error(&a->archive, errno,
+				    "rename failed");
+				ret = ARCHIVE_FATAL;
+			}
+			a->tmpname = NULL;
+		}
 	}
 	/* If there's an entry, we can release it now. */
-	if (a->entry) {
-		archive_entry_free(a->entry);
-		a->entry = NULL;
-	}
+	archive_entry_free(a->entry);
+	a->entry = NULL;
 	a->archive.state = ARCHIVE_STATE_HEADER;
 	return (ret);
 }
@@ -1895,7 +1981,7 @@
 		return;
 
 	/* Try to record our starting dir. */
-	a->restore_pwd = open(".", O_RDONLY | O_BINARY | O_CLOEXEC);
+	a->restore_pwd = la_opendirat(AT_FDCWD, ".");
 	__archive_ensure_cloexec_flag(a->restore_pwd);
 	if (a->restore_pwd < 0)
 		return;
@@ -2018,7 +2104,7 @@
 		 * follow the symlink if we're creating a dir.
 		 */
 		if (S_ISDIR(a->mode))
-			r = stat(a->name, &a->st);
+			r = la_stat(a->name, &a->st);
 		/*
 		 * If it's not a dir (or it's a broken symlink),
 		 * then don't follow it.
@@ -2052,17 +2138,28 @@
 		}
 
 		if (!S_ISDIR(a->st.st_mode)) {
-			/* A non-dir is in the way, unlink it. */
 			if (a->flags & ARCHIVE_EXTRACT_CLEAR_NOCHANGE_FFLAGS)
 				(void)clear_nochange_fflags(a);
-			if (unlink(a->name) != 0) {
-				archive_set_error(&a->archive, errno,
-				    "Can't unlink already-existing object");
-				return (ARCHIVE_FAILED);
+
+			if ((a->flags & ARCHIVE_EXTRACT_SAFE_WRITES) &&
+			    S_ISREG(a->st.st_mode)) {
+				/* Use a temporary file to extract */
+				if ((a->fd = la_mktemp(a)) == -1)
+					return ARCHIVE_FAILED;
+				a->pst = NULL;
+				en = 0;
+			} else {
+				/* A non-dir is in the way, unlink it. */
+				if (unlink(a->name) != 0) {
+					archive_set_error(&a->archive, errno,
+					    "Can't unlink already-existing "
+					    "object");
+					return (ARCHIVE_FAILED);
+				}
+				a->pst = NULL;
+				/* Try again. */
+				en = create_filesystem_object(a);
 			}
-			a->pst = NULL;
-			/* Try again. */
-			en = create_filesystem_object(a);
 		} else if (!S_ISDIR(a->mode)) {
 			/* A dir is in the way of a non-dir, rmdir it. */
 			if (a->flags & ARCHIVE_EXTRACT_CLEAR_NOCHANGE_FFLAGS)
@@ -2164,6 +2261,13 @@
 		}
 		free(linkname_copy);
 		archive_string_free(&error_string);
+		/*
+		 * Unlinking and linking here is really not atomic,
+		 * but doing it right, would require us to construct
+		 * an mktemplink() function, and then use rename(2).
+		 */
+		if (a->flags & ARCHIVE_EXTRACT_SAFE_WRITES)
+			unlink(a->name);
 		r = link(linkname, a->name) ? errno : 0;
 		/*
 		 * New cpio and pax formats allow hardlink entries
@@ -2184,7 +2288,7 @@
 #ifdef HAVE_LSTAT
 			r = lstat(a->name, &st);
 #else
-			r = stat(a->name, &st);
+			r = la_stat(a->name, &st);
 #endif
 			if (r != 0)
 				r = errno;
@@ -2202,6 +2306,13 @@
 	linkname = archive_entry_symlink(a->entry);
 	if (linkname != NULL) {
 #if HAVE_SYMLINK
+		/*
+		 * Unlinking and linking here is really not atomic,
+		 * but doing it right, would require us to construct
+		 * an mktempsymlink() function, and then use rename(2).
+		 */
+		if (a->flags & ARCHIVE_EXTRACT_SAFE_WRITES)
+			unlink(a->name);
 		return symlink(linkname, a->name) ? errno : 0;
 #else
 		return (EPERM);
@@ -2223,11 +2334,21 @@
 	 */
 	mode = final_mode & 0777 & ~a->user_umask;
 
+	/* 
+	 * Always create writable such that [f]setxattr() works if we're not
+	 * root.
+	 */
+	if (a->user_uid != 0 &&
+	    a->todo & (TODO_HFS_COMPRESSION | TODO_XATTR)) {
+		mode |= 0200;
+	}
+
 	switch (a->mode & AE_IFMT) {
 	default:
 		/* POSIX requires that we fall through here. */
 		/* FALLTHROUGH */
 	case AE_IFREG:
+		a->tmpname = NULL;
 		a->fd = open(a->name,
 		    O_WRONLY | O_CREAT | O_EXCL | O_BINARY | O_CLOEXEC, mode);
 		__archive_ensure_cloexec_flag(a->fd);
@@ -2319,7 +2440,7 @@
 {
 	struct archive_write_disk *a = (struct archive_write_disk *)_a;
 	struct fixup_entry *next, *p;
-	int ret;
+	int fd, ret;
 
 	archive_check_magic(&a->archive, ARCHIVE_WRITE_DISK_MAGIC,
 	    ARCHIVE_STATE_HEADER | ARCHIVE_STATE_DATA,
@@ -2330,21 +2451,33 @@
 	p = sort_dir_list(a->fixup_list);
 
 	while (p != NULL) {
+		fd = -1;
 		a->pst = NULL; /* Mark stat cache as out-of-date. */
+		if (p->fixup &
+		    (TODO_TIMES | TODO_MODE_BASE | TODO_ACLS | TODO_FFLAGS)) {
+			fd = open(p->name,
+			    O_WRONLY | O_BINARY | O_NOFOLLOW | O_CLOEXEC);
+		}
 		if (p->fixup & TODO_TIMES) {
-			set_times(a, -1, p->mode, p->name,
+			set_times(a, fd, p->mode, p->name,
 			    p->atime, p->atime_nanos,
 			    p->birthtime, p->birthtime_nanos,
 			    p->mtime, p->mtime_nanos,
 			    p->ctime, p->ctime_nanos);
 		}
-		if (p->fixup & TODO_MODE_BASE)
+		if (p->fixup & TODO_MODE_BASE) {
+#ifdef HAVE_FCHMOD
+			if (fd >= 0)
+				fchmod(fd, p->mode);
+			else
+#endif
 			chmod(p->name, p->mode);
+		}
 		if (p->fixup & TODO_ACLS)
-			archive_write_disk_set_acls(&a->archive, -1, p->name,
-			    &p->acl, p->mode);
+			archive_write_disk_set_acls(&a->archive, fd,
+			    p->name, &p->acl, p->mode);
 		if (p->fixup & TODO_FFLAGS)
-			set_fflags_platform(a, -1, p->name,
+			set_fflags_platform(a, fd, p->name,
 			    p->mode, p->fflags_set, 0);
 		if (p->fixup & TODO_MAC_METADATA)
 			set_mac_metadata(a, p->name, p->mac_metadata,
@@ -2353,6 +2486,8 @@
 		archive_acl_clear(&p->acl);
 		free(p->mac_metadata);
 		free(p->name);
+		if (fd >= 0)
+			close(fd);
 		free(p);
 		p = next;
 	}
@@ -2373,9 +2508,9 @@
 	ret = _archive_write_disk_close(&a->archive);
 	archive_write_disk_set_group_lookup(&a->archive, NULL, NULL, NULL);
 	archive_write_disk_set_user_lookup(&a->archive, NULL, NULL, NULL);
-	if (a->entry)
-		archive_entry_free(a->entry);
+	archive_entry_free(a->entry);
 	archive_string_free(&a->_name_data);
+	archive_string_free(&a->_tmpname_data);
 	archive_string_free(&a->archive.error_string);
 	archive_string_free(&a->path_safe);
 	a->archive.magic = 0;
@@ -2518,8 +2653,6 @@
  * scan the path and both can be optimized by comparing against other
  * recent paths.
  */
-/* TODO: Extend this to support symlinks on Windows Vista and later. */
-
 /*
  * Checks the given path to see if any elements along it are symlinks.  Returns
  * ARCHIVE_OK if there are none, otherwise puts an error in errmsg.
@@ -2528,7 +2661,8 @@
 check_symlinks_fsobj(char *path, int *a_eno, struct archive_string *a_estr,
     int flags)
 {
-#if !defined(HAVE_LSTAT)
+#if !defined(HAVE_LSTAT) && \
+    !(defined(HAVE_OPENAT) && defined(HAVE_FSTATAT) && defined(HAVE_UNLINKAT))
 	/* Platform doesn't have lstat, so we can't look for symlinks. */
 	(void)path; /* UNUSED */
 	(void)error_number; /* UNUSED */
@@ -2543,7 +2677,10 @@
 	char c;
 	int r;
 	struct stat st;
-	int restore_pwd;
+	int chdir_fd;
+#if defined(HAVE_OPENAT) && defined(HAVE_FSTATAT) && defined(HAVE_UNLINKAT)
+	int fd;
+#endif
 
 	/* Nothing to do here if name is empty */
 	if(path[0] == '\0')
@@ -2564,10 +2701,13 @@
 	 *  c holds what used to be in *tail
 	 *  last is 1 if this is the last tail
 	 */
-	restore_pwd = open(".", O_RDONLY | O_BINARY | O_CLOEXEC);
-	__archive_ensure_cloexec_flag(restore_pwd);
-	if (restore_pwd < 0)
+	chdir_fd = la_opendirat(AT_FDCWD, ".");
+	__archive_ensure_cloexec_flag(chdir_fd);
+	if (chdir_fd < 0) {
+		fsobj_error(a_eno, a_estr, errno,
+		    "Could not open ", path);
 		return (ARCHIVE_FATAL);
+	}
 	head = path;
 	tail = path;
 	last = 0;
@@ -2596,7 +2736,11 @@
 		c = tail[0];
 		tail[0] = '\0';
 		/* Check that we haven't hit a symlink. */
+#if defined(HAVE_OPENAT) && defined(HAVE_FSTATAT) && defined(HAVE_UNLINKAT)
+		r = fstatat(chdir_fd, head, &st, AT_SYMLINK_NOFOLLOW);
+#else
 		r = lstat(head, &st);
+#endif
 		if (r != 0) {
 			tail[0] = c;
 			/* We've hit a dir that doesn't exist; stop now. */
@@ -2622,7 +2766,19 @@
 			}
 		} else if (S_ISDIR(st.st_mode)) {
 			if (!last) {
-				if (chdir(head) != 0) {
+#if defined(HAVE_OPENAT) && defined(HAVE_FSTATAT) && defined(HAVE_UNLINKAT)
+				fd = la_opendirat(chdir_fd, head);
+				if (fd < 0)
+					r = -1;
+				else {
+					r = 0;
+					close(chdir_fd);
+					chdir_fd = fd;
+				}
+#else
+				r = chdir(head);
+#endif
+				if (r != 0) {
 					tail[0] = c;
 					fsobj_error(a_eno, a_estr, errno,
 					    "Could not chdir ", path);
@@ -2639,7 +2795,12 @@
 				 * so we can overwrite it with the
 				 * item being extracted.
 				 */
-				if (unlink(head)) {
+#if defined(HAVE_OPENAT) && defined(HAVE_FSTATAT) && defined(HAVE_UNLINKAT)
+				r = unlinkat(chdir_fd, head, 0);
+#else
+				r = unlink(head);
+#endif
+				if (r != 0) {
 					tail[0] = c;
 					fsobj_error(a_eno, a_estr, errno,
 					    "Could not remove symlink ",
@@ -2669,7 +2830,12 @@
 				break;
 			} else if (flags & ARCHIVE_EXTRACT_UNLINK) {
 				/* User asked us to remove problems. */
-				if (unlink(head) != 0) {
+#if defined(HAVE_OPENAT) && defined(HAVE_FSTATAT) && defined(HAVE_UNLINKAT)
+				r = unlinkat(chdir_fd, head, 0);
+#else
+				r = unlink(head);
+#endif
+				if (r != 0) {
 					tail[0] = c;
 					fsobj_error(a_eno, a_estr, 0,
 					    "Cannot remove intervening "
@@ -2687,7 +2853,11 @@
 				 * This is needed to extract hardlinks over
 				 * symlinks.
 				 */
-				r = stat(head, &st);
+#if defined(HAVE_OPENAT) && defined(HAVE_FSTATAT) && defined(HAVE_UNLINKAT)
+				r = fstatat(chdir_fd, head, &st, 0);
+#else
+				r = la_stat(head, &st);
+#endif
 				if (r != 0) {
 					tail[0] = c;
 					if (errno == ENOENT) {
@@ -2700,7 +2870,19 @@
 						break;
 					}
 				} else if (S_ISDIR(st.st_mode)) {
-					if (chdir(head) != 0) {
+#if defined(HAVE_OPENAT) && defined(HAVE_FSTATAT) && defined(HAVE_UNLINKAT)
+					fd = la_opendirat(chdir_fd, head);
+					if (fd < 0)
+						r = -1;
+					else {
+						r = 0;
+						close(chdir_fd);
+						chdir_fd = fd;
+					}
+#else
+					r = chdir(head);
+#endif
+					if (r != 0) {
 						tail[0] = c;
 						fsobj_error(a_eno, a_estr,
 						    errno,
@@ -2736,16 +2918,21 @@
 	}
 	/* Catches loop exits via break */
 	tail[0] = c;
-#ifdef HAVE_FCHDIR
+#if defined(HAVE_OPENAT) && defined(HAVE_FSTATAT) && defined(HAVE_UNLINKAT)
+	/* If we operate with openat(), fstatat() and unlinkat() there was
+	 * no chdir(), so just close the fd */
+	if (chdir_fd >= 0)
+		close(chdir_fd);
+#elif HAVE_FCHDIR
 	/* If we changed directory above, restore it here. */
-	if (restore_pwd >= 0) {
-		r = fchdir(restore_pwd);
+	if (chdir_fd >= 0) {
+		r = fchdir(chdir_fd);
 		if (r != 0) {
 			fsobj_error(a_eno, a_estr, errno,
 			    "chdir() failure", "");
 		}
-		close(restore_pwd);
-		restore_pwd = -1;
+		close(chdir_fd);
+		chdir_fd = -1;
 		if (r != 0) {
 			res = (ARCHIVE_FATAL);
 		}
@@ -3027,7 +3214,7 @@
 	 * here loses the ability to extract through symlinks.  Also note
 	 * that this should not use the a->st cache.
 	 */
-	if (stat(path, &st) == 0) {
+	if (la_stat(path, &st) == 0) {
 		if (S_ISDIR(st.st_mode))
 			return (ARCHIVE_OK);
 		if ((a->flags & ARCHIVE_EXTRACT_NO_OVERWRITE)) {
@@ -3085,7 +3272,7 @@
 	 * don't add it to the fixup list here, as it's already been
 	 * added.
 	 */
-	if (stat(path, &st) == 0 && S_ISDIR(st.st_mode))
+	if (la_stat(path, &st) == 0 && S_ISDIR(st.st_mode))
 		return (ARCHIVE_OK);
 
 	archive_set_error(&a->archive, errno, "Failed to create dir '%s'",
@@ -3106,12 +3293,14 @@
 static int
 set_ownership(struct archive_write_disk *a)
 {
-#ifndef __CYGWIN__
-/* unfortunately, on win32 there is no 'root' user with uid 0,
-   so we just have to try the chown and see if it works */
-
-	/* If we know we can't change it, don't bother trying. */
-	if (a->user_uid != 0  &&  a->user_uid != a->uid) {
+#if !defined(__CYGWIN__) && !defined(__linux__)
+/*
+ * On Linux, a process may have the CAP_CHOWN capability.
+ * On Windows there is no 'root' user with uid 0.
+ * Elsewhere we can skip calling chown if we are not root and the desired
+ * user id does not match the current user.
+ */
+	if (a->user_uid != 0 && a->user_uid != a->uid) {
 		archive_set_error(&a->archive, errno,
 		    "Can't set UID=%jd", (intmax_t)a->uid);
 		return (ARCHIVE_WARN);
@@ -3360,6 +3549,7 @@
 set_mode(struct archive_write_disk *a, int mode)
 {
 	int r = ARCHIVE_OK;
+	int r2;
 	mode &= 07777; /* Strip off file type bits. */
 
 	if (a->todo & TODO_SGID_CHECK) {
@@ -3453,21 +3643,19 @@
 		 * post-extract fixup, which is handled elsewhere.
 		 */
 #ifdef HAVE_FCHMOD
-		if (a->fd >= 0) {
-			if (fchmod(a->fd, mode) != 0) {
-				archive_set_error(&a->archive, errno,
-				    "Can't set permissions to 0%o", (int)mode);
-				r = ARCHIVE_WARN;
-			}
-		} else
+		if (a->fd >= 0)
+			r2 = fchmod(a->fd, mode);
+		else
 #endif
-			/* If this platform lacks fchmod(), then
-			 * we'll just use chmod(). */
-			if (chmod(a->name, mode) != 0) {
-				archive_set_error(&a->archive, errno,
-				    "Can't set permissions to 0%o", (int)mode);
-				r = ARCHIVE_WARN;
-			}
+		/* If this platform lacks fchmod(), then
+		 * we'll just use chmod(). */
+		r2 = chmod(a->name, mode);
+
+		if (r2 != 0) {
+			archive_set_error(&a->archive, errno,
+			    "Can't set permissions to 0%o", (int)mode);
+			r = ARCHIVE_WARN;
+		}
 	}
 	return (r);
 }
@@ -3478,9 +3666,7 @@
 	struct fixup_entry *le;
 	unsigned long	set, clear;
 	int		r;
-	int		critical_flags;
 	mode_t		mode = archive_entry_mode(a->entry);
-
 	/*
 	 * Make 'critical_flags' hold all file flags that can't be
 	 * immediately restored.  For example, on BSD systems,
@@ -3496,33 +3682,33 @@
 	 * other programs that might try to muck with files as they're
 	 * being restored.
 	 */
-	/* Hopefully, the compiler will optimize this mess into a constant. */
-	critical_flags = 0;
+	const int	critical_flags = 0
 #ifdef SF_IMMUTABLE
-	critical_flags |= SF_IMMUTABLE;
+	    | SF_IMMUTABLE
 #endif
 #ifdef UF_IMMUTABLE
-	critical_flags |= UF_IMMUTABLE;
+	    | UF_IMMUTABLE
 #endif
 #ifdef SF_APPEND
-	critical_flags |= SF_APPEND;
+	    | SF_APPEND
 #endif
 #ifdef UF_APPEND
-	critical_flags |= UF_APPEND;
+	    | UF_APPEND
 #endif
 #if defined(FS_APPEND_FL)
-	critical_flags |= FS_APPEND_FL;
+	    | FS_APPEND_FL
 #elif defined(EXT2_APPEND_FL)
-	critical_flags |= EXT2_APPEND_FL;
+	    | EXT2_APPEND_FL
 #endif
 #if defined(FS_IMMUTABLE_FL)
-	critical_flags |= FS_IMMUTABLE_FL;
+	    | FS_IMMUTABLE_FL
 #elif defined(EXT2_IMMUTABLE_FL)
-	critical_flags |= EXT2_IMMUTABLE_FL;
+	    | EXT2_IMMUTABLE_FL
 #endif
 #ifdef FS_JOURNAL_DATA_FL
-	critical_flags |= FS_JOURNAL_DATA_FL;
+	    | FS_JOURNAL_DATA_FL
 #endif
+	;
 
 	if (a->todo & TODO_FFLAGS) {
 		archive_entry_fflags(a->entry, &set, &clear);
@@ -3553,29 +3739,27 @@
 static int
 clear_nochange_fflags(struct archive_write_disk *a)
 {
-	int		nochange_flags;
 	mode_t		mode = archive_entry_mode(a->entry);
-
-	/* Hopefully, the compiler will optimize this mess into a constant. */
-	nochange_flags = 0;
+	const int nochange_flags = 0
 #ifdef SF_IMMUTABLE
-	nochange_flags |= SF_IMMUTABLE;
+	    | SF_IMMUTABLE
 #endif
 #ifdef UF_IMMUTABLE
-	nochange_flags |= UF_IMMUTABLE;
+	    | UF_IMMUTABLE
 #endif
 #ifdef SF_APPEND
-	nochange_flags |= SF_APPEND;
+	    | SF_APPEND
 #endif
 #ifdef UF_APPEND
-	nochange_flags |= UF_APPEND;
+	    | UF_APPEND
 #endif
 #ifdef EXT2_APPEND_FL
-	nochange_flags |= EXT2_APPEND_FL;
+	    | EXT2_APPEND_FL
 #endif
 #ifdef EXT2_IMMUTABLE_FL
-	nochange_flags |= EXT2_IMMUTABLE_FL;
+	    | EXT2_IMMUTABLE_FL
 #endif
+	;
 
 	return (set_fflags_platform(a, a->fd, a->name, mode, 0,
 	    nochange_flags));
@@ -3591,8 +3775,22 @@
     mode_t mode, unsigned long set, unsigned long clear)
 {
 	int r;
-
+	const int sf_mask = 0
+#ifdef SF_APPEND
+	    | SF_APPEND
+#endif
+#ifdef SF_ARCHIVED
+	    | SF_ARCHIVED
+#endif
+#ifdef SF_IMMUTABLE
+	    | SF_IMMUTABLE
+#endif
+#ifdef SF_NOUNLINK
+	    | SF_NOUNLINK
+#endif
+	;
 	(void)mode; /* UNUSED */
+
 	if (set == 0  && clear == 0)
 		return (ARCHIVE_OK);
 
@@ -3607,6 +3805,12 @@
 
 	a->st.st_flags &= ~clear;
 	a->st.st_flags |= set;
+
+	/* Only super-user may change SF_* flags */
+
+	if (a->user_uid != 0)
+		a->st.st_flags &= ~sf_mask;
+
 #ifdef HAVE_FCHFLAGS
 	/* If platform has fchflags() and we were given an fd, use it. */
 	if (fd >= 0 && fchflags(fd, a->st.st_flags) == 0)
@@ -3648,7 +3852,28 @@
 	int		 ret;
 	int		 myfd = fd;
 	int newflags, oldflags;
-	int sf_mask = 0;
+	/*
+	 * Linux has no define for the flags that are only settable by
+	 * the root user.  This code may seem a little complex, but
+	 * there seem to be some Linux systems that lack these
+	 * defines. (?)  The code below degrades reasonably gracefully
+	 * if sf_mask is incomplete.
+	 */
+	const int sf_mask = 0
+#if defined(FS_IMMUTABLE_FL)
+	    | FS_IMMUTABLE_FL
+#elif defined(EXT2_IMMUTABLE_FL)
+	    | EXT2_IMMUTABLE_FL
+#endif
+#if defined(FS_APPEND_FL)
+	    | FS_APPEND_FL
+#elif defined(EXT2_APPEND_FL)
+	    | EXT2_APPEND_FL
+#endif
+#if defined(FS_JOURNAL_DATA_FL)
+	    | FS_JOURNAL_DATA_FL
+#endif
+	;
 
 	if (set == 0 && clear == 0)
 		return (ARCHIVE_OK);
@@ -3665,26 +3890,6 @@
 		return (ARCHIVE_OK);
 
 	/*
-	 * Linux has no define for the flags that are only settable by
-	 * the root user.  This code may seem a little complex, but
-	 * there seem to be some Linux systems that lack these
-	 * defines. (?)  The code below degrades reasonably gracefully
-	 * if sf_mask is incomplete.
-	 */
-#if defined(FS_IMMUTABLE_FL)
-	sf_mask |= FS_IMMUTABLE_FL;
-#elif defined(EXT2_IMMUTABLE_FL)
-	sf_mask |= EXT2_IMMUTABLE_FL;
-#endif
-#if defined(FS_APPEND_FL)
-	sf_mask |= FS_APPEND_FL;
-#elif defined(EXT2_APPEND_FL)
-	sf_mask |= EXT2_APPEND_FL;
-#endif
-#if defined(FS_JOURNAL_DATA_FL)
-	sf_mask |= FS_JOURNAL_DATA_FL;
-#endif
-	/*
 	 * XXX As above, this would be way simpler if we didn't have
 	 * to read the current flags from disk. XXX
 	 */
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_disk_private.h b/Utilities/cmlibarchive/libarchive/archive_write_disk_private.h
index b655dea..557d7e2 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_disk_private.h
+++ b/Utilities/cmlibarchive/libarchive/archive_write_disk_private.h
@@ -26,13 +26,13 @@
  * $FreeBSD: head/lib/libarchive/archive_write_disk_private.h 201086 2009-12-28 02:17:53Z kientzle $
  */
 
+#ifndef ARCHIVE_WRITE_DISK_PRIVATE_H_INCLUDED
+#define ARCHIVE_WRITE_DISK_PRIVATE_H_INCLUDED
+
 #ifndef __LIBARCHIVE_BUILD
 #error This header is only to be used internally to libarchive.
 #endif
 
-#ifndef ARCHIVE_WRITE_DISK_PRIVATE_H_INCLUDED
-#define ARCHIVE_WRITE_DISK_PRIVATE_H_INCLUDED
-
 #include "archive_platform_acl.h"
 #include "archive_acl_private.h"
 #include "archive_entry.h"
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_disk_set_standard_lookup.c b/Utilities/cmlibarchive/libarchive/archive_write_disk_set_standard_lookup.c
index 5c766d7..5fccdb9 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_disk_set_standard_lookup.c
+++ b/Utilities/cmlibarchive/libarchive/archive_write_disk_set_standard_lookup.c
@@ -114,8 +114,7 @@
 		return ((gid_t)b->id);
 
 	/* Free the cache slot for a new entry. */
-	if (b->name != NULL)
-		free(b->name);
+	free(b->name);
 	b->name = strdup(gname);
 	/* Note: If strdup fails, that's okay; we just won't cache. */
 	b->hash = h;
@@ -184,8 +183,7 @@
 		return ((uid_t)b->id);
 
 	/* Free the cache slot for a new entry. */
-	if (b->name != NULL)
-		free(b->name);
+	free(b->name);
 	b->name = strdup(uname);
 	/* Note: If strdup fails, that's okay; we just won't cache. */
 	b->hash = h;
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_disk_windows.c b/Utilities/cmlibarchive/libarchive/archive_write_disk_windows.c
index 78eda4a..77e36c4 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_disk_windows.c
+++ b/Utilities/cmlibarchive/libarchive/archive_write_disk_windows.c
@@ -165,6 +165,8 @@
 	struct archive_entry	*entry; /* Entry being extracted. */
 	wchar_t			*name; /* Name of entry, possibly edited. */
 	struct archive_wstring	 _name_data; /* backing store for 'name' */
+	wchar_t			*tmpname; /* Temporary name */
+	struct archive_wstring	_tmpname_data; /* backing store for 'tmpname' */
 	/* Tasks remaining for this object. */
 	int			 todo;
 	/* Tasks deferred until end-of-archive. */
@@ -205,6 +207,8 @@
 #define	MINIMUM_DIR_MODE 0700
 #define	MAXIMUM_DIR_MODE 0775
 
+static int	disk_unlink(const wchar_t *);
+static int	disk_rmdir(const wchar_t *);
 static int	check_symlinks(struct archive_write_disk *);
 static int	create_filesystem_object(struct archive_write_disk *);
 static struct fixup_entry *current_fixup(struct archive_write_disk *,
@@ -213,13 +217,17 @@
 static int	create_dir(struct archive_write_disk *, wchar_t *);
 static int	create_parent_dir(struct archive_write_disk *, wchar_t *);
 static int	la_chmod(const wchar_t *, mode_t);
+static int	la_mktemp(struct archive_write_disk *);
 static int	older(BY_HANDLE_FILE_INFORMATION *, struct archive_entry *);
 static int	permissive_name_w(struct archive_write_disk *);
 static int	restore_entry(struct archive_write_disk *);
 static int	set_acls(struct archive_write_disk *, HANDLE h,
 		    const wchar_t *, struct archive_acl *);
 static int	set_xattrs(struct archive_write_disk *);
+static int	clear_nochange_fflags(struct archive_write_disk *);
 static int	set_fflags(struct archive_write_disk *);
+static int	set_fflags_platform(const wchar_t *, unsigned long,
+		    unsigned long);
 static int	set_ownership(struct archive_write_disk *);
 static int	set_mode(struct archive_write_disk *, int mode);
 static int	set_times(struct archive_write_disk *, HANDLE, int,
@@ -474,6 +482,11 @@
 	{
 		archive_wstrncpy(&(a->_name_data), wsp, l);
 	}
+	else if (l > 2 && wsp[0] == L'\\' && wsp[1] == L'\\' && wsp[2] != L'\\')
+	{
+		archive_wstrncpy(&(a->_name_data), L"\\\\?\\UNC\\", 8);
+		archive_wstrncat(&(a->_name_data), wsp+2, l-2);
+	}
 	else
 	{
 		archive_wstrncpy(&(a->_name_data), L"\\\\?\\", 4);
@@ -524,6 +537,28 @@
 	return (ret);
 }
 
+static int
+la_mktemp(struct archive_write_disk *a)
+{
+	int fd;
+	mode_t mode;
+
+	archive_wstring_empty(&(a->_tmpname_data));
+	archive_wstrcpy(&(a->_tmpname_data), a->name);
+	archive_wstrcat(&(a->_tmpname_data), L".XXXXXX");
+	a->tmpname = a->_tmpname_data.s;
+
+	fd = __archive_mkstemp(a->tmpname);
+
+	mode = a->mode & 0777 & ~a->user_umask;
+	if (la_chmod(a->tmpname, mode) == -1) {
+		la_dosmaperr(GetLastError());
+		_close(fd);
+		return -1;
+	}
+	return (fd);
+}
+
 static void *
 la_GetFunctionKernel32(const char *name)
 {
@@ -551,8 +586,10 @@
 		set = 1;
 		f = la_GetFunctionKernel32("CreateHardLinkW");
 	}
-	if (!f)
+	if (!f) {
+		errno = ENOTSUP;
 		return (0);
+	}
 	ret = (*f)(linkname, target, NULL);
 	if (!ret) {
 		/* Under windows 2000, it is necessary to remove
@@ -577,6 +614,103 @@
 	return (ret);
 }
 
+/*
+ * Create file or directory symolic link
+ *
+ * If linktype is AE_SYMLINK_TYPE_UNDEFINED (or unknown), guess linktype from
+ * the link target
+ */
+static int
+la_CreateSymbolicLinkW(const wchar_t *linkname, const wchar_t *target,
+    int linktype) {
+	static BOOLEAN (WINAPI *f)(LPCWSTR, LPCWSTR, DWORD);
+	static int set;
+	wchar_t *ttarget, *p;
+	int len;
+	DWORD attrs = 0;
+	DWORD flags = 0;
+	DWORD newflags = 0;
+	BOOL ret = 0;
+
+	if (!set) {
+		set = 1;
+		f = la_GetFunctionKernel32("CreateSymbolicLinkW");
+	}
+	if (!f)
+		return (0);
+
+	len = wcslen(target);
+	if (len == 0) {
+		errno = EINVAL;
+		return(0);
+	}
+	/*
+	 * When writing path targets, we need to translate slashes
+	 * to backslashes
+	 */
+	ttarget = malloc((len + 1) * sizeof(wchar_t));
+	if (ttarget == NULL)
+		return(0);
+
+	p = ttarget;
+
+	while(*target != L'\0') {
+		if (*target == L'/')
+			*p = L'\\';
+		else
+			*p = *target;
+		target++;
+		p++;
+	}
+	*p = L'\0';
+
+	/*
+	 * In case of undefined symlink type we guess it from the target.
+	 * If the target equals ".", "..", ends with a backslash or a
+	 * backslash followed by "." or ".." we assume it is a directory
+	 * symlink. In all other cases we assume a file symlink.
+	 */
+	if (linktype != AE_SYMLINK_TYPE_FILE && (
+		linktype == AE_SYMLINK_TYPE_DIRECTORY ||
+		*(p - 1) == L'\\' || (*(p - 1) == L'.' && (
+	    len == 1 || *(p - 2) == L'\\' || ( *(p - 2) == L'.' && (
+	    len == 2 || *(p - 3) == L'\\')))))) {
+#if defined(SYMBOLIC_LINK_FLAG_DIRECTORY)
+		flags |= SYMBOLIC_LINK_FLAG_DIRECTORY;
+#else
+		flags |= 0x1;
+#endif
+	}
+
+#if defined(SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE)
+	newflags = flags | SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE;
+#else
+	newflags = flags | 0x2;
+#endif
+
+	/*
+	 * Windows won't overwrite existing links
+	 */
+	attrs = GetFileAttributesW(linkname);
+	if (attrs != INVALID_FILE_ATTRIBUTES) {
+		if (attrs & FILE_ATTRIBUTE_DIRECTORY)
+			disk_rmdir(linkname);
+		else
+			disk_unlink(linkname);
+	}
+
+	ret = (*f)(linkname, ttarget, newflags);
+	/*
+	 * Prior to Windows 10 calling CreateSymbolicLinkW() will fail
+	 * if SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE is set
+	 */
+	if (!ret) {
+		ret = (*f)(linkname, ttarget, flags);
+	}
+	free(ttarget);
+	return (ret);
+}
+
 static int
 la_ftruncate(HANDLE handle, int64_t length)
 {
@@ -696,10 +830,8 @@
 	a->pst = NULL;
 	a->current_fixup = NULL;
 	a->deferred = 0;
-	if (a->entry) {
-		archive_entry_free(a->entry);
-		a->entry = NULL;
-	}
+	archive_entry_free(a->entry);
+	a->entry = NULL;
 	a->entry = archive_entry_clone(entry);
 	a->fh = INVALID_HANDLE_VALUE;
 	a->fd_offset = 0;
@@ -860,9 +992,11 @@
 	}
 
 	if (a->deferred & TODO_FFLAGS) {
+		unsigned long set, clear;
+
 		fe = current_fixup(a, archive_entry_pathname_w(entry));
-		fe->fixup |= TODO_FFLAGS;
-		/* TODO: Complete this.. defer fflags from below. */
+		archive_entry_fflags(entry, &set, &clear);
+		fe->fflags_set = set;
 	}
 
 	/*
@@ -1143,12 +1277,20 @@
 	if (a->fh != INVALID_HANDLE_VALUE) {
 		CloseHandle(a->fh);
 		a->fh = INVALID_HANDLE_VALUE;
+		if (a->tmpname) {
+			/* Windows does not support atomic rename */
+			disk_unlink(a->name);
+			if (_wrename(a->tmpname, a->name) != 0) {
+				archive_set_error(&a->archive, errno,
+				    "rename failed");
+				ret = ARCHIVE_FATAL;
+			}
+			a->tmpname = NULL;
+		}
 	}
 	/* If there's an entry, we can release it now. */
-	if (a->entry) {
-		archive_entry_free(a->entry);
-		a->entry = NULL;
-	}
+	archive_entry_free(a->entry);
+	a->entry = NULL;
 	a->archive.state = ARCHIVE_STATE_HEADER;
 	return (ret);
 }
@@ -1239,7 +1381,7 @@
 }
 
 static int
-disk_unlink(wchar_t *path)
+disk_unlink(const wchar_t *path)
 {
 	wchar_t *fullname;
 	int r;
@@ -1254,7 +1396,7 @@
 }
 
 static int
-disk_rmdir(wchar_t *path)
+disk_rmdir(const wchar_t *path)
 {
 	wchar_t *fullname;
 	int r;
@@ -1285,6 +1427,8 @@
 		 * object is a dir, but that doesn't mean the old
 		 * object isn't a dir.
 		 */
+		if (a->flags & ARCHIVE_EXTRACT_CLEAR_NOCHANGE_FFLAGS)
+			(void)clear_nochange_fflags(a);
 		if (disk_unlink(a->name) == 0) {
 			/* We removed it, reset cached stat. */
 			a->pst = NULL;
@@ -1359,28 +1503,45 @@
 		en = create_filesystem_object(a);
 	} else if (en == EEXIST) {
 		mode_t st_mode;
+		mode_t lst_mode;
+		BY_HANDLE_FILE_INFORMATION lst;
 		/*
 		 * We know something is in the way, but we don't know what;
 		 * we need to find out before we go any further.
 		 */
 		int r = 0;
+		int dirlnk = 0;
+
 		/*
 		 * The SECURE_SYMLINK logic has already removed a
 		 * symlink to a dir if the client wants that.  So
 		 * follow the symlink if we're creating a dir.
-		 */
-		if (S_ISDIR(a->mode))
-			r = file_information(a, a->name, &a->st, &st_mode, 0);
-		/*
 		 * If it's not a dir (or it's a broken symlink),
 		 * then don't follow it.
+		 *
+		 * Windows distinguishes file and directory symlinks.
+		 * A file symlink may erroneously point to a directory
+		 * and a directory symlink to a file. Windows does not follow
+		 * such symlinks. We always need both source and target
+		 * information.
 		 */
-		if (r != 0 || !S_ISDIR(a->mode))
-			r = file_information(a, a->name, &a->st, &st_mode, 1);
+		r = file_information(a, a->name, &lst, &lst_mode, 1);
 		if (r != 0) {
 			archive_set_error(&a->archive, errno,
 			    "Can't stat existing object");
 			return (ARCHIVE_FAILED);
+		} else if (S_ISLNK(lst_mode)) {
+			if (lst.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
+				dirlnk = 1;
+			/* In case of a symlink we need target information */
+			r = file_information(a, a->name, &a->st, &st_mode, 0);
+			if (r != 0) {
+				a->st = lst;
+				st_mode = lst_mode;
+			}
+		} else {
+			a->st = lst;
+			st_mode = lst_mode;
 		}
 
 		/*
@@ -1404,17 +1565,50 @@
 		}
 
 		if (!S_ISDIR(st_mode)) {
-			/* A non-dir is in the way, unlink it. */
-			if (disk_unlink(a->name) != 0) {
-				archive_set_error(&a->archive, errno,
-				    "Can't unlink already-existing object");
-				return (ARCHIVE_FAILED);
+			if (a->flags &
+			    ARCHIVE_EXTRACT_CLEAR_NOCHANGE_FFLAGS) {
+				(void)clear_nochange_fflags(a);
 			}
-			a->pst = NULL;
-			/* Try again. */
-			en = create_filesystem_object(a);
+			if ((a->flags & ARCHIVE_EXTRACT_SAFE_WRITES) &&
+				S_ISREG(st_mode)) {
+				int fd = la_mktemp(a);
+
+				if (fd == -1)
+					return (ARCHIVE_FAILED);
+				a->fh = (HANDLE)_get_osfhandle(fd);
+				if (a->fh == INVALID_HANDLE_VALUE)
+					return (ARCHIVE_FAILED);
+
+				a->pst = NULL;
+				en = 0;
+			} else {
+				if (dirlnk) {
+					/* Edge case: dir symlink pointing
+					 * to a file */
+					if (disk_rmdir(a->name) != 0) {
+						archive_set_error(&a->archive,
+						    errno, "Can't unlink "
+						    "directory symlink");
+						return (ARCHIVE_FAILED);
+					}
+				} else {
+					if (disk_unlink(a->name) != 0) {
+						/* A non-dir is in the way,
+						 * unlink it. */
+						archive_set_error(&a->archive,
+						    errno, "Can't unlink "
+						    "already-existing object");
+						return (ARCHIVE_FAILED);
+					}
+				}
+				a->pst = NULL;
+				/* Try again. */
+				en = create_filesystem_object(a);
+			}
 		} else if (!S_ISDIR(a->mode)) {
 			/* A dir is in the way of a non-dir, rmdir it. */
+			if (a->flags & ARCHIVE_EXTRACT_CLEAR_NOCHANGE_FFLAGS)
+				(void)clear_nochange_fflags(a);
 			if (disk_rmdir(a->name) != 0) {
 				archive_set_error(&a->archive, errno,
 				    "Can't remove already-existing dir");
@@ -1462,6 +1656,7 @@
 	wchar_t *fullname;
 	mode_t final_mode, mode;
 	int r;
+	DWORD attrs = 0;
 
 	/* We identify hard/symlinks according to the link names. */
 	/* Since link(2) and symlink(2) don't handle modes, we're done here. */
@@ -1475,6 +1670,20 @@
 			errno = EINVAL;
 			r = -1;
 		} else {
+			/*
+			 * Unlinking and linking here is really not atomic,
+			 * but doing it right, would require us to construct
+			 * an mktemplink() function, and then use _wrename().
+			 */
+			if (a->flags & ARCHIVE_EXTRACT_SAFE_WRITES) {
+				attrs = GetFileAttributesW(namefull);
+				if (attrs != INVALID_FILE_ATTRIBUTES) {
+					if (attrs & FILE_ATTRIBUTE_DIRECTORY)
+						disk_rmdir(namefull);
+					else
+						disk_unlink(namefull);
+				}
+			}
 			r = la_CreateHardLinkW(namefull, linkfull);
 			if (r == 0) {
 				la_dosmaperr(GetLastError());
@@ -1511,10 +1720,31 @@
 	}
 	linkname = archive_entry_symlink_w(a->entry);
 	if (linkname != NULL) {
+		/*
+		 * Unlinking and linking here is really not atomic,
+		 * but doing it right, would require us to construct
+		 * an mktemplink() function, and then use _wrename().
+		 */
+		attrs = GetFileAttributesW(a->name);
+		if (attrs != INVALID_FILE_ATTRIBUTES) {
+			if (attrs & FILE_ATTRIBUTE_DIRECTORY)
+				disk_rmdir(a->name);
+			else
+				disk_unlink(a->name);
+		}
 #if HAVE_SYMLINK
 		return symlink(linkname, a->name) ? errno : 0;
 #else
-		return (EPERM);
+		errno = 0;
+		r = la_CreateSymbolicLinkW((const wchar_t *)a->name, linkname,
+		    archive_entry_symlink_type(a->entry));
+		if (r == 0) {
+			if (errno == 0)
+				la_dosmaperr(GetLastError());
+			r = errno;
+		} else
+			r = 0;
+		return (r);
 #endif
 	}
 
@@ -1538,6 +1768,7 @@
 		/* POSIX requires that we fall through here. */
 		/* FALLTHROUGH */
 	case AE_IFREG:
+		a->tmpname = NULL;
 		fullname = a->name;
 		/* O_WRONLY | O_CREAT | O_EXCL */
 		a->fh = CreateFileW(fullname, GENERIC_WRITE, 0, NULL,
@@ -1667,6 +1898,8 @@
 			la_chmod(p->name, p->mode);
 		if (p->fixup & TODO_ACLS)
 			set_acls(a, INVALID_HANDLE_VALUE, p->name, &p->acl);
+		if (p->fixup & TODO_FFLAGS)
+			set_fflags_platform(p->name, p->fflags_set, 0);
 		next = p->next;
 		archive_acl_clear(&p->acl);
 		free(p->name);
@@ -1690,9 +1923,9 @@
 	ret = _archive_write_disk_close(&a->archive);
 	archive_write_disk_set_group_lookup(&a->archive, NULL, NULL, NULL);
 	archive_write_disk_set_user_lookup(&a->archive, NULL, NULL, NULL);
-	if (a->entry)
-		archive_entry_free(a->entry);
+	archive_entry_free(a->entry);
 	archive_wstring_free(&a->_name_data);
+	archive_wstring_free(&a->_tmpname_data);
 	archive_string_free(&a->archive.error_string);
 	archive_wstring_free(&a->path_safe);
 	a->archive.magic = 0;
@@ -1784,6 +2017,7 @@
 	a->fixup_list = fe;
 	fe->fixup = 0;
 	fe->name = _wcsdup(pathname);
+	fe->fflags_set = 0;
 	return (fe);
 }
 
@@ -1798,7 +2032,6 @@
 	return (a->current_fixup);
 }
 
-/* TODO: Make this work. */
 /*
  * TODO: The deep-directory support bypasses this; disable deep directory
  * support if we're doing symlink checks.
@@ -1808,7 +2041,6 @@
  * scan the path and both can be optimized by comparing against other
  * recent paths.
  */
-/* TODO: Extend this to support symlinks on Windows Vista and later. */
 static int
 check_symlinks(struct archive_write_disk *a)
 {
@@ -1827,6 +2059,9 @@
 	p = a->path_safe.s;
 	while ((*pn != '\0') && (*p == *pn))
 		++p, ++pn;
+	/* Skip leading backslashes */
+	while (*pn == '\\')
+		++pn;
 	c = pn[0];
 	/* Keep going until we've checked the entire name. */
 	while (pn[0] != '\0' && (pn[0] != '\\' || pn[1] != '\0')) {
@@ -1844,11 +2079,21 @@
 		} else if (S_ISLNK(st_mode)) {
 			if (c == '\0') {
 				/*
-				 * Last element is symlink; remove it
-				 * so we can overwrite it with the
+				 * Last element is a file or directory symlink.
+				 * Remove it so we can overwrite it with the
 				 * item being extracted.
 				 */
-				if (disk_unlink(a->name)) {
+				if (a->flags &
+				    ARCHIVE_EXTRACT_CLEAR_NOCHANGE_FFLAGS) {
+					(void)clear_nochange_fflags(a);
+				}
+				if (st.dwFileAttributes &
+				    FILE_ATTRIBUTE_DIRECTORY) {
+					r = disk_rmdir(a->name);
+				} else {
+					r = disk_unlink(a->name);
+				}
+				if (r) {
 					archive_set_error(&a->archive, errno,
 					    "Could not remove symlink %ls",
 					    a->name);
@@ -1872,7 +2117,17 @@
 				return (0);
 			} else if (a->flags & ARCHIVE_EXTRACT_UNLINK) {
 				/* User asked us to remove problems. */
-				if (disk_unlink(a->name) != 0) {
+				if (a->flags &
+				    ARCHIVE_EXTRACT_CLEAR_NOCHANGE_FFLAGS) {
+					(void)clear_nochange_fflags(a);
+				}
+				if (st.dwFileAttributes &
+				    FILE_ATTRIBUTE_DIRECTORY) {
+					r = disk_rmdir(a->name);
+				} else {
+					r = disk_unlink(a->name);
+				}
+				if (r != 0) {
 					archive_set_error(&a->archive, 0,
 					    "Cannot remove intervening "
 					    "symlink %ls", a->name);
@@ -1888,6 +2143,8 @@
 				return (ARCHIVE_FAILED);
 			}
 		}
+		pn[0] = c;
+		pn++;
 	}
 	pn[0] = c;
 	/* We've checked and/or cleaned the whole path, so remember it. */
@@ -2438,10 +2695,56 @@
 	return (r);
 }
 
+static int set_fflags_platform(const wchar_t *name, unsigned long fflags_set,
+    unsigned long fflags_clear)
+{
+	DWORD oldflags, newflags;
+	wchar_t *fullname;
+
+	const DWORD settable_flags =
+	    FILE_ATTRIBUTE_ARCHIVE |
+	    FILE_ATTRIBUTE_HIDDEN |
+	    FILE_ATTRIBUTE_NORMAL |
+	    FILE_ATTRIBUTE_NOT_CONTENT_INDEXED |
+	    FILE_ATTRIBUTE_OFFLINE |
+	    FILE_ATTRIBUTE_READONLY |
+	    FILE_ATTRIBUTE_SYSTEM |
+	    FILE_ATTRIBUTE_TEMPORARY;
+
+	oldflags = GetFileAttributesW(name);
+	if (oldflags == (DWORD)-1 &&
+	    GetLastError() == ERROR_INVALID_NAME) {
+		fullname = __la_win_permissive_name_w(name);
+		oldflags = GetFileAttributesW(fullname);
+	}
+	if (oldflags == (DWORD)-1) {
+		la_dosmaperr(GetLastError());
+		return (ARCHIVE_WARN);
+	}
+	newflags = ((oldflags & ~fflags_clear) | fflags_set) & settable_flags;
+	if(SetFileAttributesW(name, newflags) == 0)
+		return (ARCHIVE_WARN);
+	return (ARCHIVE_OK);
+}
+
+static int
+clear_nochange_fflags(struct archive_write_disk *a)
+{
+	return (set_fflags_platform(a->name, 0, FILE_ATTRIBUTE_READONLY));
+}
+
 static int
 set_fflags(struct archive_write_disk *a)
 {
-	(void)a; /* UNUSED */
+	unsigned long	set, clear;
+
+	if (a->todo & TODO_FFLAGS) {
+		archive_entry_fflags(a->entry, &set, &clear);
+		if (set == 0  && clear == 0)
+			return (ARCHIVE_OK);
+		return (set_fflags_platform(a->name, set, clear));
+
+        }
 	return (ARCHIVE_OK);
 }
 
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_filter.3 b/Utilities/cmlibarchive/libarchive/archive_write_filter.3
index d6fa071..c83eb77 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_filter.3
+++ b/Utilities/cmlibarchive/libarchive/archive_write_filter.3
@@ -43,7 +43,7 @@
 .Nm archive_write_add_filter_program ,
 .Nm archive_write_add_filter_uuencode ,
 .Nm archive_write_add_filter_xz ,
-.Nm archive_write_add_filter_zstd ,
+.Nm archive_write_add_filter_zstd
 .Nd functions enabling output filters
 .Sh LIBRARY
 Streaming Archive Library (libarchive, -larchive)
@@ -125,10 +125,10 @@
 .\"
 .Sh SEE ALSO
 .Xr tar 1 ,
-.Xr libarchive 3 ,
 .Xr archive_write 3 ,
 .Xr archive_write_format 3 ,
 .Xr archive_write_set_options 3 ,
+.Xr libarchive 3 ,
 .Xr cpio 5 ,
 .Xr mtree 5 ,
 .Xr tar 5
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_finish_entry.3 b/Utilities/cmlibarchive/libarchive/archive_write_finish_entry.3
index dc1b94b..5797e16 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_finish_entry.3
+++ b/Utilities/cmlibarchive/libarchive/archive_write_finish_entry.3
@@ -71,9 +71,9 @@
 .\"
 .Sh SEE ALSO
 .Xr tar 1 ,
-.Xr libarchive 3 ,
 .Xr archive_write_data 3 ,
 .Xr archive_write_set_options 3 ,
+.Xr libarchive 3 ,
 .Xr cpio 5 ,
 .Xr mtree 5 ,
 .Xr tar 5
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_format.3 b/Utilities/cmlibarchive/libarchive/archive_write_format.3
index aaafb0a..47a7403 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_format.3
+++ b/Utilities/cmlibarchive/libarchive/archive_write_format.3
@@ -52,7 +52,7 @@
 .Nm archive_write_set_format_v7tar ,
 .Nm archive_write_set_format_warc ,
 .Nm archive_write_set_format_xar ,
-.Nm archive_write_set_format_zip ,
+.Nm archive_write_set_format_zip
 .Nd functions for creating archives
 .Sh LIBRARY
 Streaming Archive Library (libarchive, -larchive)
@@ -166,9 +166,9 @@
 .\"
 .Sh SEE ALSO
 .Xr tar 1 ,
-.Xr libarchive 3 ,
 .Xr archive_write 3 ,
 .Xr archive_write_set_options 3 ,
+.Xr libarchive 3 ,
 .Xr cpio 5 ,
 .Xr libarchive-formats 5 ,
 .Xr mtree 5 ,
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_free.3 b/Utilities/cmlibarchive/libarchive/archive_write_free.3
index 1b2d071..5210e2a 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_free.3
+++ b/Utilities/cmlibarchive/libarchive/archive_write_free.3
@@ -56,7 +56,7 @@
 to release the resources.
 This can be used to speed recovery when the archive creation
 must be aborted.
-Note that the created archive is likely to be malformed in this case; 
+Note that the created archive is likely to be malformed in this case;
 .It Fn archive_write_close
 Complete the archive and invoke the close callback.
 .It Fn archive_write_finish
@@ -89,8 +89,8 @@
 .\"
 .Sh SEE ALSO
 .Xr tar 1 ,
-.Xr libarchive 3 ,
 .Xr archive_write_set_options 3 ,
+.Xr libarchive 3 ,
 .Xr cpio 5 ,
 .Xr mtree 5 ,
 .Xr tar 5
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_header.3 b/Utilities/cmlibarchive/libarchive/archive_write_header.3
index 4de58f3..2217b18 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_header.3
+++ b/Utilities/cmlibarchive/libarchive/archive_write_header.3
@@ -66,8 +66,8 @@
 .\"
 .Sh SEE ALSO
 .Xr tar 1 ,
-.Xr libarchive 3 ,
 .Xr archive_write_set_options 3 ,
+.Xr libarchive 3 ,
 .Xr cpio 5 ,
 .Xr mtree 5 ,
 .Xr tar 5
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_new.3 b/Utilities/cmlibarchive/libarchive/archive_write_new.3
index f05d269..788cbb8 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_new.3
+++ b/Utilities/cmlibarchive/libarchive/archive_write_new.3
@@ -50,9 +50,9 @@
 .\" .Sh ERRORS
 .Sh SEE ALSO
 .Xr tar 1 ,
-.Xr libarchive 3 ,
 .Xr archive_write 3 ,
 .Xr archive_write_set_options 3 ,
+.Xr libarchive 3 ,
 .Xr cpio 5 ,
 .Xr mtree 5 ,
 .Xr tar 5
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_open.3 b/Utilities/cmlibarchive/libarchive/archive_write_open.3
index 457873e..0129d10 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_open.3
+++ b/Utilities/cmlibarchive/libarchive/archive_write_open.3
@@ -200,7 +200,7 @@
 .Fn archive_set_error
 to register an error code and message and
 return
-.Cm ARCHIVE_FATAL.
+.Cm ARCHIVE_FATAL .
 .Pp
 Note that if the client-provided write callback function
 returns a non-zero value, that error will be propagated back to the caller
@@ -234,13 +234,13 @@
 .\"
 .Sh SEE ALSO
 .Xr tar 1 ,
-.Xr libarchive 3 ,
 .Xr archive_write 3 ,
 .Xr archive_write_blocksize 3 ,
 .Xr archive_write_filter 3 ,
 .Xr archive_write_format 3 ,
 .Xr archive_write_new 3 ,
 .Xr archive_write_set_options 3 ,
+.Xr libarchive 3 ,
 .Xr cpio 5 ,
 .Xr mtree 5 ,
 .Xr tar 5
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_private.h b/Utilities/cmlibarchive/libarchive/archive_write_private.h
index 0dfd1b1..27cba03 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_private.h
+++ b/Utilities/cmlibarchive/libarchive/archive_write_private.h
@@ -25,19 +25,24 @@
  * $FreeBSD: head/lib/libarchive/archive_write_private.h 201155 2009-12-29 05:20:12Z kientzle $
  */
 
+#ifndef ARCHIVE_WRITE_PRIVATE_H_INCLUDED
+#define ARCHIVE_WRITE_PRIVATE_H_INCLUDED
+
 #ifndef __LIBARCHIVE_BUILD
 #ifndef __LIBARCHIVE_TEST
 #error This header is only to be used internally to libarchive.
 #endif
 #endif
 
-#ifndef ARCHIVE_WRITE_PRIVATE_H_INCLUDED
-#define	ARCHIVE_WRITE_PRIVATE_H_INCLUDED
-
 #include "archive.h"
 #include "archive_string.h"
 #include "archive_private.h"
 
+#define	ARCHIVE_WRITE_FILTER_STATE_NEW		1U
+#define	ARCHIVE_WRITE_FILTER_STATE_OPEN		2U
+#define	ARCHIVE_WRITE_FILTER_STATE_CLOSED	4U
+#define	ARCHIVE_WRITE_FILTER_STATE_FATAL	0x8000U
+
 struct archive_write;
 
 struct archive_write_filter {
@@ -55,6 +60,7 @@
 	int	  code;
 	int	  bytes_per_block;
 	int	  bytes_in_last_block;
+	int	  state;
 };
 
 #if ARCHIVE_VERSION < 4000000
@@ -66,8 +72,6 @@
 int __archive_write_output(struct archive_write *, const void *, size_t);
 int __archive_write_nulls(struct archive_write *, size_t);
 int __archive_write_filter(struct archive_write_filter *, const void *, size_t);
-int __archive_write_open_filter(struct archive_write_filter *);
-int __archive_write_close_filter(struct archive_write_filter *);
 
 struct archive_write {
 	struct archive	archive;
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_set_format.c b/Utilities/cmlibarchive/libarchive/archive_write_set_format.c
index 0f70623..12de080 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_set_format.c
+++ b/Utilities/cmlibarchive/libarchive/archive_write_set_format.c
@@ -36,6 +36,7 @@
 
 #include "archive.h"
 #include "archive_private.h"
+#include "archive_write_set_format_private.h"
 
 /* A table that maps format codes to functions. */
 static const
@@ -76,3 +77,47 @@
 	archive_set_error(a, EINVAL, "No such format");
 	return (ARCHIVE_FATAL);
 }
+
+void
+__archive_write_entry_filetype_unsupported(struct archive *a,
+    struct archive_entry *entry, const char *format)
+{
+	char *name = NULL;
+
+	switch (archive_entry_filetype(entry)) {
+	/*
+	 * All formats should be able to archive regular files (AE_IFREG)
+	 */
+	case AE_IFDIR:
+		name = "directories";
+		break;
+	case AE_IFLNK:
+		name = "symbolic links";
+		break;
+	case AE_IFCHR:
+		name = "character devices";
+		break;
+	case AE_IFBLK:
+		name = "block devices";
+		break;
+	case AE_IFIFO:
+		name = "named pipes";
+		break;
+	case AE_IFSOCK:
+		name = "sockets";
+		break;
+	default:
+		break;
+	}
+
+	if (name != NULL) {
+		archive_set_error(a, ARCHIVE_ERRNO_FILE_FORMAT,
+		    "%s: %s format cannot archive %s",
+		    archive_entry_pathname(entry), format, name);
+	} else {
+		archive_set_error(a, ARCHIVE_ERRNO_FILE_FORMAT,
+		    "%s: %s format cannot archive files with mode 0%lo",
+		    archive_entry_pathname(entry), format,
+		    (unsigned long)archive_entry_mode(entry));
+	}
+}
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_set_format_7zip.c b/Utilities/cmlibarchive/libarchive/archive_write_set_format_7zip.c
index 2bd4ec4..69af814 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_set_format_7zip.c
+++ b/Utilities/cmlibarchive/libarchive/archive_write_set_format_7zip.c
@@ -31,13 +31,13 @@
 #endif
 #include <stdlib.h>
 #ifdef HAVE_BZLIB_H
-#include <cm_bzlib.h>
+#include <cm3p/bzlib.h>
 #endif
 #if HAVE_LZMA_H
-#include <cm_lzma.h>
+#include <cm3p/lzma.h>
 #endif
 #ifdef HAVE_ZLIB_H
-#include <cm_zlib.h>
+#include <cm3p/zlib.h>
 #endif
 
 #include "archive.h"
@@ -52,6 +52,7 @@
 #include "archive_rb.h"
 #include "archive_string.h"
 #include "archive_write_private.h"
+#include "archive_write_set_format_private.h"
 
 /*
  * Codec ID
@@ -164,7 +165,7 @@
 	mode_t			 mode;
 	uint32_t		 crc32;
 
-	int			 dir:1;
+	signed int		 dir:1;
 };
 
 struct _7zip {
@@ -439,7 +440,8 @@
 
 	r = file_new(a, entry, &file);
 	if (r < ARCHIVE_WARN) {
-		file_free(file);
+		if (file != NULL)
+			file_free(file);
 		return (r);
 	}
 	if (file->size == 0 && file->dir) {
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_set_format_ar.c b/Utilities/cmlibarchive/libarchive/archive_write_set_format_ar.c
index 50305cc..fc0de1e 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_set_format_ar.c
+++ b/Utilities/cmlibarchive/libarchive/archive_write_set_format_ar.c
@@ -42,6 +42,7 @@
 #include "archive_entry.h"
 #include "archive_private.h"
 #include "archive_write_private.h"
+#include "archive_write_set_format_private.h"
 
 struct ar_w {
 	uint64_t	 entry_bytes_remaining;
@@ -187,6 +188,11 @@
 		buff[AR_name_offset] = '/';
 		goto stat;
 	}
+	if (strcmp(pathname, "/SYM64/") == 0) {
+		/* Entry is archive symbol table in GNU 64-bit format */
+		memcpy(buff + AR_name_offset, "/SYM64/", 7);
+		goto stat;
+	}
 	if (strcmp(pathname, "__.SYMDEF") == 0) {
 		/* Entry is archive symbol table in BSD format */
 		memcpy(buff + AR_name_offset, "__.SYMDEF", 9);
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_set_format_cpio.c b/Utilities/cmlibarchive/libarchive/archive_write_set_format_cpio.c
index a4c9d1e..729f9c7 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_set_format_cpio.c
+++ b/Utilities/cmlibarchive/libarchive/archive_write_set_format_cpio.c
@@ -43,6 +43,7 @@
 #include "archive_entry_locale.h"
 #include "archive_private.h"
 #include "archive_write_private.h"
+#include "archive_write_set_format_private.h"
 
 static ssize_t	archive_write_cpio_data(struct archive_write *,
 		    const void *buff, size_t s);
@@ -408,8 +409,7 @@
 		}
 	}
 exit_write_header:
-	if (entry_main)
-		archive_entry_free(entry_main);
+	archive_entry_free(entry_main);
 	return (ret_final);
 }
 
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_set_format_cpio_newc.c b/Utilities/cmlibarchive/libarchive/archive_write_set_format_cpio_newc.c
index 957f1a3..172fda6 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_set_format_cpio_newc.c
+++ b/Utilities/cmlibarchive/libarchive/archive_write_set_format_cpio_newc.c
@@ -44,6 +44,7 @@
 #include "archive_entry_locale.h"
 #include "archive_private.h"
 #include "archive_write_private.h"
+#include "archive_write_set_format_private.h"
 
 static ssize_t	archive_write_newc_data(struct archive_write *,
 		    const void *buff, size_t s);
@@ -366,8 +367,7 @@
 		}
 	}
 exit_write_header:
-	if (entry_main)
-		archive_entry_free(entry_main);
+	archive_entry_free(entry_main);
 	return (ret_final);
 }
 
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_set_format_gnutar.c b/Utilities/cmlibarchive/libarchive/archive_write_set_format_gnutar.c
index 2d858c9..ec29c5c 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_set_format_gnutar.c
+++ b/Utilities/cmlibarchive/libarchive/archive_write_set_format_gnutar.c
@@ -46,6 +46,7 @@
 #include "archive_entry_locale.h"
 #include "archive_private.h"
 #include "archive_write_private.h"
+#include "archive_write_set_format_private.h"
 
 struct gnutar {
 	uint64_t	entry_bytes_remaining;
@@ -339,7 +340,7 @@
 		 * case getting WCS failed. On POSIX, this is a
 		 * normal operation.
 		 */
-		if (p != NULL && p[strlen(p) - 1] != '/') {
+		if (p != NULL && p[0] != '\0' && p[strlen(p) - 1] != '/') {
 			struct archive_string as;
 
 			archive_string_init(&as);
@@ -534,17 +535,9 @@
 		case AE_IFBLK: tartype = '4' ; break;
 		case AE_IFDIR: tartype = '5' ; break;
 		case AE_IFIFO: tartype = '6' ; break;
-		case AE_IFSOCK:
-			archive_set_error(&a->archive,
-			    ARCHIVE_ERRNO_FILE_FORMAT,
-			    "tar format cannot archive socket");
-			ret = ARCHIVE_FAILED;
-			goto exit_write_header;
-		default:
-			archive_set_error(&a->archive,
-			    ARCHIVE_ERRNO_FILE_FORMAT,
-			    "tar format cannot archive this (mode=0%lo)",
-			    (unsigned long)archive_entry_mode(entry));
+		default: /* AE_IFSOCK and unknown */
+			__archive_write_entry_filetype_unsupported(
+                            &a->archive, entry, "gnutar");
 			ret = ARCHIVE_FAILED;
 			goto exit_write_header;
 		}
@@ -565,8 +558,7 @@
 	gnutar->entry_bytes_remaining = archive_entry_size(entry);
 	gnutar->entry_padding = 0x1ff & (-(int64_t)gnutar->entry_bytes_remaining);
 exit_write_header:
-	if (entry_main)
-		archive_entry_free(entry_main);
+	archive_entry_free(entry_main);
 	return (ret);
 }
 
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_set_format_iso9660.c b/Utilities/cmlibarchive/libarchive/archive_write_set_format_iso9660.c
index 4adf68e..5db414f 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_set_format_iso9660.c
+++ b/Utilities/cmlibarchive/libarchive/archive_write_set_format_iso9660.c
@@ -47,7 +47,7 @@
 #include <unistd.h>
 #endif
 #ifdef HAVE_ZLIB_H
-#include <cm_zlib.h>
+#include <cm3p/zlib.h>
 #endif
 
 #include "archive.h"
@@ -289,12 +289,12 @@
 		struct extr_rec	*current;
 	}			 extr_rec_list;
 
-	int			 virtual:1;
+	signed int		 virtual:1;
 	/* If set to one, this file type is a directory.
 	 * A convenience flag to be used as
 	 * "archive_entry_filetype(isoent->file->entry) == AE_IFDIR".
 	 */
-	int			 dir:1;
+	signed int		 dir:1;
 };
 
 struct hardlink {
@@ -755,9 +755,9 @@
 
 	/* Used for making zisofs. */
 	struct {
-		int		 detect_magic:1;
-		int		 making:1;
-		int		 allzero:1;
+		signed int	 detect_magic:1;
+		signed int	 making:1;
+		signed int	 allzero:1;
 		unsigned char	 magic_buffer[64];
 		int		 magic_cnt;
 
@@ -3650,7 +3650,7 @@
 	if (size > iso9660->wbuff_remaining ||
 	    iso9660->wbuff_remaining == 0) {
 		archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
-		    "Internal Programing error: iso9660:wb_consume()"
+		    "Internal Programming error: iso9660:wb_consume()"
 		    " size=%jd, wbuff_remaining=%jd",
 		    (intmax_t)size, (intmax_t)iso9660->wbuff_remaining);
 		return (ARCHIVE_FATAL);
@@ -3671,7 +3671,7 @@
 
 	if (iso9660->wbuff_type != WB_TO_TEMP) {
 		archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
-		    "Internal Programing error: iso9660:wb_set_offset()");
+		    "Internal Programming error: iso9660:wb_set_offset()");
 		return (ARCHIVE_FATAL);
 	}
 
@@ -4899,10 +4899,10 @@
 		if (p[0] == '/') {
 			if (p[1] == '/')
 				/* Convert '//' --> '/' */
-				strcpy(p, p+1);
+				memmove(p, p+1, strlen(p+1) + 1);
 			else if (p[1] == '.' && p[2] == '/')
 				/* Convert '/./' --> '/' */
-				strcpy(p, p+2);
+				memmove(p, p+2, strlen(p+2) + 1);
 			else if (p[1] == '.' && p[2] == '.' && p[3] == '/') {
 				/* Convert 'dir/dir1/../dir2/'
 				 *     --> 'dir/dir2/'
@@ -5094,13 +5094,11 @@
 static void
 isofile_free_hardlinks(struct iso9660 *iso9660)
 {
-	struct archive_rb_node *n, *next;
+	struct archive_rb_node *n, *tmp;
 
-	for (n = ARCHIVE_RB_TREE_MIN(&(iso9660->hardlink_rbtree)); n;) {
-		next = __archive_rb_tree_iterate(&(iso9660->hardlink_rbtree),
-		    n, ARCHIVE_RB_DIR_RIGHT);
+	ARCHIVE_RB_TREE_FOREACH_SAFE(n, &(iso9660->hardlink_rbtree), tmp) {
+		__archive_rb_tree_remove_node(&(iso9660->hardlink_rbtree), n);
 		free(n);
-		n = next;
 	}
 }
 
@@ -7801,8 +7799,8 @@
 	uint64_t	 pz_uncompressed_size;
 	size_t		 uncompressed_buffer_size;
 
-	int		 initialized:1;
-	int		 header_passed:1;
+	signed int	 initialized:1;
+	signed int	 header_passed:1;
 
 	uint32_t	 pz_offset;
 	unsigned char	*block_pointers;
@@ -8128,7 +8126,7 @@
 {
 	(void)buff; /* UNUSED */
 	(void)s; /* UNUSED */
-	archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, "Programing error");
+	archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, "Programming error");
 	return (ARCHIVE_FATAL);
 }
 
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_set_format_mtree.c b/Utilities/cmlibarchive/libarchive/archive_write_set_format_mtree.c
index 493d473..aa41e9a 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_set_format_mtree.c
+++ b/Utilities/cmlibarchive/libarchive/archive_write_set_format_mtree.c
@@ -186,7 +186,7 @@
 #endif
 	/* Keyword options */
 	int keys;
-#define	F_CKSUM		0x00000001		/* check sum */
+#define	F_CKSUM		0x00000001		/* checksum */
 #define	F_DEV		0x00000002		/* device type */
 #define	F_DONE		0x00000004		/* directory done */
 #define	F_FLAGS		0x00000008		/* file flags */
@@ -371,7 +371,7 @@
 }
 
 /*
- * Indent a line as mtree utility to be readable for people.
+ * Indent a line as the mtree utility does so it is readable for people.
  */
 static void
 mtree_indent(struct mtree_writer *mtree)
@@ -446,8 +446,8 @@
 
 /*
  * Write /set keyword.
- * Set most used value of uid,gid,mode and fflags, which are
- * collected by attr_counter_set_collect() function.
+ * Set the most used value of uid, gid, mode and fflags, which are
+ * collected by the attr_counter_set_collect() function.
  */
 static void
 write_global(struct mtree_writer *mtree)
@@ -649,7 +649,7 @@
 }
 
 /*
- * Tabulate uid,gid,mode and fflags of a entry in order to be used for /set.
+ * Tabulate uid, gid, mode and fflags of a entry in order to be used for /set.
  */
 static int
 attr_counter_set_collect(struct mtree_writer *mtree, struct mtree_entry *me)
@@ -912,7 +912,7 @@
 
 	/* If the current file is a regular file, we have to
 	 * compute the sum of its content.
-	 * Initialize a bunch of sum check context. */
+	 * Initialize a bunch of checksum context. */
 	if (mtree_entry->reg_info)
 		sum_init(mtree);
 
@@ -1265,7 +1265,7 @@
 	if (mtree == NULL)
 		return (ARCHIVE_OK);
 
-	/* Make sure we dot not leave any entries. */
+	/* Make sure we do not leave any entries. */
 	mtree_entry_register_free(mtree);
 	archive_string_free(&mtree->cur_dirstr);
 	archive_string_free(&mtree->ebuf);
@@ -1810,10 +1810,10 @@
 		if (p[0] == '/') {
 			if (p[1] == '/')
 				/* Convert '//' --> '/' */
-				strcpy(p, p+1);
+				memmove(p, p+1, strlen(p+1) + 1);
 			else if (p[1] == '.' && p[2] == '/')
 				/* Convert '/./' --> '/' */
-				strcpy(p, p+2);
+				memmove(p, p+2, strlen(p+2) + 1);
 			else if (p[1] == '.' && p[2] == '.' && p[3] == '/') {
 				/* Convert 'dir/dir1/../dir2/'
 				 *     --> 'dir/dir2/'
@@ -2024,7 +2024,7 @@
 
 	if (file->parentdir.length == 0) {
 		archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
-		    "Internal programing error "
+		    "Internal programming error "
 		    "in generating canonical name for %s",
 		    file->pathname.s);
 		return (ARCHIVE_FAILED);
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_set_format_pax.c b/Utilities/cmlibarchive/libarchive/archive_write_set_format_pax.c
index 3cebeae..a2b2710 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_set_format_pax.c
+++ b/Utilities/cmlibarchive/libarchive/archive_write_set_format_pax.c
@@ -43,6 +43,7 @@
 #include "archive_entry_locale.h"
 #include "archive_private.h"
 #include "archive_write_private.h"
+#include "archive_write_set_format_private.h"
 
 struct sparse_block {
 	struct sparse_block	*next;
@@ -199,6 +200,28 @@
 			archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
 			    "pax: invalid charset name");
 		return (ret);
+	} else if (strcmp(key, "xattrheader") == 0) {
+		if (val == NULL || val[0] == 0) {
+			archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+			    "pax: xattrheader requires a value");
+		} else if (strcmp(val, "ALL") == 0 ||
+		    strcmp(val, "all") == 0) {
+			pax->flags |= WRITE_LIBARCHIVE_XATTR | WRITE_SCHILY_XATTR;
+			ret = ARCHIVE_OK;
+		} else if (strcmp(val, "SCHILY") == 0 ||
+		    strcmp(val, "schily") == 0) {
+			pax->flags |= WRITE_SCHILY_XATTR;
+			pax->flags &= ~WRITE_LIBARCHIVE_XATTR;
+			ret = ARCHIVE_OK;
+		} else if (strcmp(val, "LIBARCHIVE") == 0 ||
+		    strcmp(val, "libarchive") == 0) {
+			pax->flags |= WRITE_LIBARCHIVE_XATTR;
+			pax->flags &= ~WRITE_SCHILY_XATTR;
+			ret = ARCHIVE_OK;
+		} else
+			archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+			    "pax: invalid xattr header name");
+		return (ret);
 	}
 
 	/* Note: The "warn" return is just to inform the options
@@ -522,11 +545,13 @@
 		    ARCHIVE_ERRNO_FILE_FORMAT, "%s %s %s",
 		    "Can't translate ", attr, " to UTF-8");
 		return(ARCHIVE_WARN);
-	} else if (*p != '\0') {
+	}
+
+	if (*p != '\0') {
 		add_pax_attr(&(pax->pax_header),
 		    attr, p);
-		free(p);
 	}
+	free(p);
 	return(ARCHIVE_OK);
 }
 
@@ -660,7 +685,7 @@
 			 * case getting WCS failed. On POSIX, this is a
 			 * normal operation.
 			 */
-			if (p != NULL && p[strlen(p) - 1] != '/') {
+			if (p != NULL && p[0] != '\0' && p[strlen(p) - 1] != '/') {
 				struct archive_string as;
 
 				archive_string_init(&as);
@@ -689,17 +714,9 @@
 			}
 			break;
 		}
-		case AE_IFSOCK:
-			archive_set_error(&a->archive,
-			    ARCHIVE_ERRNO_FILE_FORMAT,
-			    "tar format cannot archive socket");
-			return (ARCHIVE_FAILED);
-		default:
-			archive_set_error(&a->archive,
-			    ARCHIVE_ERRNO_FILE_FORMAT,
-			    "tar format cannot archive this (type=0%lo)",
-			    (unsigned long)
-			    archive_entry_filetype(entry_original));
+		default: /* AE_IFSOCK and unknown */
+			__archive_write_entry_filetype_unsupported(
+			    &a->archive, entry_original, "pax");
 			return (ARCHIVE_FAILED);
 		}
 	}
@@ -835,13 +852,16 @@
 	 * them do.
 	 */
 	r = get_entry_pathname(a, entry_main, &path, &path_length, sconv);
-	if (r == ARCHIVE_FATAL)
+	if (r == ARCHIVE_FATAL) {
+		archive_entry_free(entry_main);
 		return (r);
-	else if (r != ARCHIVE_OK) {
+	} else if (r != ARCHIVE_OK) {
 		r = get_entry_pathname(a, entry_main, &path,
 		    &path_length, NULL);
-		if (r == ARCHIVE_FATAL)
+		if (r == ARCHIVE_FATAL) {
+			archive_entry_free(entry_main);
 			return (r);
+		}
 		archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
 		    "Can't translate pathname '%s' to %s", path,
 		    archive_string_conversion_charset_name(sconv));
@@ -849,12 +869,15 @@
 		sconv = NULL;/* The header charset switches to binary mode. */
 	}
 	r = get_entry_uname(a, entry_main, &uname, &uname_length, sconv);
-	if (r == ARCHIVE_FATAL)
+	if (r == ARCHIVE_FATAL) {
+		archive_entry_free(entry_main);
 		return (r);
-	else if (r != ARCHIVE_OK) {
+	} else if (r != ARCHIVE_OK) {
 		r = get_entry_uname(a, entry_main, &uname, &uname_length, NULL);
-		if (r == ARCHIVE_FATAL)
+		if (r == ARCHIVE_FATAL) {
+			archive_entry_free(entry_main);
 			return (r);
+		}
 		archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
 		    "Can't translate uname '%s' to %s", uname,
 		    archive_string_conversion_charset_name(sconv));
@@ -862,12 +885,15 @@
 		sconv = NULL;/* The header charset switches to binary mode. */
 	}
 	r = get_entry_gname(a, entry_main, &gname, &gname_length, sconv);
-	if (r == ARCHIVE_FATAL)
+	if (r == ARCHIVE_FATAL) {
+		archive_entry_free(entry_main);
 		return (r);
-	else if (r != ARCHIVE_OK) {
+	} else if (r != ARCHIVE_OK) {
 		r = get_entry_gname(a, entry_main, &gname, &gname_length, NULL);
-		if (r == ARCHIVE_FATAL)
+		if (r == ARCHIVE_FATAL) {
+			archive_entry_free(entry_main);
 			return (r);
+		}
 		archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
 		    "Can't translate gname '%s' to %s", gname,
 		    archive_string_conversion_charset_name(sconv));
@@ -879,13 +905,16 @@
 	if (linkpath == NULL) {
 		r = get_entry_symlink(a, entry_main, &linkpath,
 		    &linkpath_length, sconv);
-		if (r == ARCHIVE_FATAL)
+		if (r == ARCHIVE_FATAL) {
+			archive_entry_free(entry_main);
 			return (r);
-		else if (r != ARCHIVE_OK) {
+		} else if (r != ARCHIVE_OK) {
 			r = get_entry_symlink(a, entry_main, &linkpath,
 			    &linkpath_length, NULL);
-			if (r == ARCHIVE_FATAL)
+			if (r == ARCHIVE_FATAL) {
+				archive_entry_free(entry_main);
 				return (r);
+			}
 			archive_set_error(&a->archive,
 			    ARCHIVE_ERRNO_FILE_FORMAT,
 			    "Can't translate linkname '%s' to %s", linkpath,
@@ -901,21 +930,29 @@
 		if (hardlink != NULL) {
 			r = get_entry_hardlink(a, entry_main, &hardlink,
 			    &hardlink_length, NULL);
-			if (r == ARCHIVE_FATAL)
+			if (r == ARCHIVE_FATAL) {
+				archive_entry_free(entry_main);
 				return (r);
+			}
 			linkpath = hardlink;
 			linkpath_length = hardlink_length;
 		}
 		r = get_entry_pathname(a, entry_main, &path,
 		    &path_length, NULL);
-		if (r == ARCHIVE_FATAL)
+		if (r == ARCHIVE_FATAL) {
+			archive_entry_free(entry_main);
 			return (r);
+		}
 		r = get_entry_uname(a, entry_main, &uname, &uname_length, NULL);
-		if (r == ARCHIVE_FATAL)
+		if (r == ARCHIVE_FATAL) {
+			archive_entry_free(entry_main);
 			return (r);
+		}
 		r = get_entry_gname(a, entry_main, &gname, &gname_length, NULL);
-		if (r == ARCHIVE_FATAL)
+		if (r == ARCHIVE_FATAL) {
+			archive_entry_free(entry_main);
 			return (r);
+		}
 	}
 
 	/* Store the header encoding first, to be nice to readers. */
@@ -1112,6 +1149,10 @@
 	if (!need_extension && acl_types != 0)
 		need_extension = 1;
 
+	/* If the symlink type is defined, we need an extension */
+	if (!need_extension && archive_entry_symlink_type(entry_main) > 0)
+		need_extension = 1;
+
 	/*
 	 * Libarchive used to include these in extended headers for
 	 * restricted pax format, but that confused people who
@@ -1168,24 +1209,33 @@
 			    ARCHIVE_ENTRY_ACL_STYLE_EXTRA_ID |
 			    ARCHIVE_ENTRY_ACL_STYLE_SEPARATOR_COMMA |
 			    ARCHIVE_ENTRY_ACL_STYLE_COMPACT);
-			if (ret == ARCHIVE_FATAL)
+			if (ret == ARCHIVE_FATAL) {
+				archive_entry_free(entry_main);
+				archive_string_free(&entry_name);
 				return (ARCHIVE_FATAL);
+			}
 		}
 		if (acl_types & ARCHIVE_ENTRY_ACL_TYPE_ACCESS) {
 			ret = add_pax_acl(a, entry_original, pax,
 			    ARCHIVE_ENTRY_ACL_TYPE_ACCESS |
 			    ARCHIVE_ENTRY_ACL_STYLE_EXTRA_ID |
 			    ARCHIVE_ENTRY_ACL_STYLE_SEPARATOR_COMMA);
-			if (ret == ARCHIVE_FATAL)
+			if (ret == ARCHIVE_FATAL) {
+				archive_entry_free(entry_main);
+				archive_string_free(&entry_name);
 				return (ARCHIVE_FATAL);
+			}
 		}
 		if (acl_types & ARCHIVE_ENTRY_ACL_TYPE_DEFAULT) {
 			ret = add_pax_acl(a, entry_original, pax,
 			    ARCHIVE_ENTRY_ACL_TYPE_DEFAULT |
 			    ARCHIVE_ENTRY_ACL_STYLE_EXTRA_ID |
 			    ARCHIVE_ENTRY_ACL_STYLE_SEPARATOR_COMMA);
-			if (ret == ARCHIVE_FATAL)
+			if (ret == ARCHIVE_FATAL) {
+				archive_entry_free(entry_main);
+				archive_string_free(&entry_name);
 				return (ARCHIVE_FATAL);
+			}
 		}
 
 		/* We use GNU-tar-compatible sparse attributes. */
@@ -1245,6 +1295,17 @@
 			archive_string_free(&entry_name);
 			return (ARCHIVE_FATAL);
 		}
+
+		/* Store extended symlink information */
+		if (archive_entry_symlink_type(entry_main) ==
+		    AE_SYMLINK_TYPE_FILE) {
+			add_pax_attr(&(pax->pax_header),
+			    "LIBARCHIVE.symlinktype", "file");
+		} else if (archive_entry_symlink_type(entry_main) ==
+		    AE_SYMLINK_TYPE_DIRECTORY) {
+			add_pax_attr(&(pax->pax_header),
+			    "LIBARCHIVE.symlinktype", "dir");
+		}
 	}
 
 	/* Only regular files have data. */
@@ -1313,8 +1374,11 @@
 	 * numeric fields, though they're less critical.
 	 */
 	if (__archive_write_format_header_ustar(a, ustarbuff, entry_main, -1, 0,
-	    NULL) == ARCHIVE_FATAL)
+	    NULL) == ARCHIVE_FATAL) {
+		archive_entry_free(entry_main);
+		archive_string_free(&entry_name);
 		return (ARCHIVE_FATAL);
+	}
 
 	/* If we built any extended attributes, write that entry first. */
 	if (archive_strlen(&(pax->pax_header)) > 0) {
@@ -1379,6 +1443,8 @@
 			archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
 			    "archive_write_pax_header: "
 			    "'x' header failed?!  This can't happen.\n");
+			archive_entry_free(entry_main);
+			archive_string_free(&entry_name);
 			return (ARCHIVE_FATAL);
 		} else if (r < ret)
 			ret = r;
@@ -1387,6 +1453,8 @@
 			sparse_list_clear(pax);
 			pax->entry_bytes_remaining = 0;
 			pax->entry_padding = 0;
+			archive_entry_free(entry_main);
+			archive_string_free(&entry_name);
 			return (ARCHIVE_FATAL);
 		}
 
@@ -1398,12 +1466,16 @@
 		    archive_strlen(&(pax->pax_header)));
 		if (r != ARCHIVE_OK) {
 			/* If a write fails, we're pretty much toast. */
+			archive_entry_free(entry_main);
+			archive_string_free(&entry_name);
 			return (ARCHIVE_FATAL);
 		}
 		/* Pad out the end of the entry. */
 		r = __archive_write_nulls(a, (size_t)pax->entry_padding);
 		if (r != ARCHIVE_OK) {
 			/* If a write fails, we're pretty much toast. */
+			archive_entry_free(entry_main);
+			archive_string_free(&entry_name);
 			return (ARCHIVE_FATAL);
 		}
 		pax->entry_bytes_remaining = pax->entry_padding = 0;
@@ -1411,8 +1483,11 @@
 
 	/* Write the header for main entry. */
 	r = __archive_write_output(a, ustarbuff, 512);
-	if (r != ARCHIVE_OK)
+	if (r != ARCHIVE_OK) {
+		archive_entry_free(entry_main);
+		archive_string_free(&entry_name);
 		return (r);
+	}
 
 	/*
 	 * Inform the client of the on-disk size we're using, so
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_set_format_private.h b/Utilities/cmlibarchive/libarchive/archive_write_set_format_private.h
new file mode 100644
index 0000000..e200227
--- /dev/null
+++ b/Utilities/cmlibarchive/libarchive/archive_write_set_format_private.h
@@ -0,0 +1,42 @@
+/*-
+ * Copyright (c) 2020 Martin Matuska
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef ARCHIVE_WRITE_SET_FORMAT_PRIVATE_H_INCLUDED
+#define ARCHIVE_WRITE_SET_FORMAT_PRIVATE_H_INCLUDED
+
+#ifndef __LIBARCHIVE_BUILD
+#ifndef __LIBARCHIVE_TEST
+#error This header is only to be used internally to libarchive.
+#endif
+#endif
+
+#include "archive.h"
+#include "archive_entry.h"
+
+void __archive_write_entry_filetype_unsupported(struct archive *a,
+    struct archive_entry *entry, const char *format);
+#endif
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_set_format_shar.c b/Utilities/cmlibarchive/libarchive/archive_write_set_format_shar.c
index 5be310a..9e4931c 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_set_format_shar.c
+++ b/Utilities/cmlibarchive/libarchive/archive_write_set_format_shar.c
@@ -42,6 +42,7 @@
 #include "archive_entry.h"
 #include "archive_private.h"
 #include "archive_write_private.h"
+#include "archive_write_set_format_private.h"
 
 struct shar {
 	int			 dump;
@@ -169,8 +170,7 @@
 	}
 
 	/* Save the entry for the closing. */
-	if (shar->entry)
-		archive_entry_free(shar->entry);
+	archive_entry_free(shar->entry);
 	shar->entry = archive_entry_clone(entry);
 	name = archive_entry_pathname(entry);
 
@@ -195,8 +195,8 @@
 		archive_entry_set_size(entry, 0);
 		if (archive_entry_hardlink(entry) == NULL &&
 		    archive_entry_symlink(entry) == NULL) {
-			archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
-			    "shar format cannot archive this");
+			__archive_write_entry_filetype_unsupported(
+			    &a->archive, entry, "shar");
 			return (ARCHIVE_WARN);
 		}
 	}
@@ -289,8 +289,7 @@
 			    "mkdir -p %s > /dev/null 2>&1\n",
 			    shar->quoted_name.s);
 			/* Record that we just created this directory. */
-			if (shar->last_dir != NULL)
-				free(shar->last_dir);
+			free(shar->last_dir);
 
 			shar->last_dir = strdup(name);
 			/* Trim a trailing '/'. */
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_set_format_ustar.c b/Utilities/cmlibarchive/libarchive/archive_write_set_format_ustar.c
index c54aeab..d1a06bc 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_set_format_ustar.c
+++ b/Utilities/cmlibarchive/libarchive/archive_write_set_format_ustar.c
@@ -44,6 +44,7 @@
 #include "archive_entry_locale.h"
 #include "archive_private.h"
 #include "archive_write_private.h"
+#include "archive_write_set_format_private.h"
 
 struct ustar {
 	uint64_t	entry_bytes_remaining;
@@ -352,14 +353,12 @@
 #endif
 	ret = __archive_write_format_header_ustar(a, buff, entry, -1, 1, sconv);
 	if (ret < ARCHIVE_WARN) {
-		if (entry_main)
-			archive_entry_free(entry_main);
+		archive_entry_free(entry_main);
 		return (ret);
 	}
 	ret2 = __archive_write_output(a, buff, 512);
 	if (ret2 < ARCHIVE_WARN) {
-		if (entry_main)
-			archive_entry_free(entry_main);
+		archive_entry_free(entry_main);
 		return (ret2);
 	}
 	if (ret2 < ret)
@@ -367,8 +366,7 @@
 
 	ustar->entry_bytes_remaining = archive_entry_size(entry);
 	ustar->entry_padding = 0x1ff & (-(int64_t)ustar->entry_bytes_remaining);
-	if (entry_main)
-		archive_entry_free(entry_main);
+	archive_entry_free(entry_main);
 	return (ret);
 }
 
@@ -515,9 +513,11 @@
 	}
 	if (copy_length > 0) {
 		if (copy_length > USTAR_uname_size) {
-			archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
-			    "Username too long");
-			ret = ARCHIVE_FAILED;
+			if (tartype != 'x') {
+				archive_set_error(&a->archive,
+				    ARCHIVE_ERRNO_MISC, "Username too long");
+				ret = ARCHIVE_FAILED;
+			}
 			copy_length = USTAR_uname_size;
 		}
 		memcpy(h + USTAR_uname_offset, p, copy_length);
@@ -538,9 +538,11 @@
 	}
 	if (copy_length > 0) {
 		if (strlen(p) > USTAR_gname_size) {
-			archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
-			    "Group name too long");
-			ret = ARCHIVE_FAILED;
+			if (tartype != 'x') {
+				archive_set_error(&a->archive,
+				    ARCHIVE_ERRNO_MISC, "Group name too long");
+				ret = ARCHIVE_FAILED;
+			}
 			copy_length = USTAR_gname_size;
 		}
 		memcpy(h + USTAR_gname_offset, p, copy_length);
@@ -612,16 +614,9 @@
 		case AE_IFBLK: h[USTAR_typeflag_offset] = '4' ; break;
 		case AE_IFDIR: h[USTAR_typeflag_offset] = '5' ; break;
 		case AE_IFIFO: h[USTAR_typeflag_offset] = '6' ; break;
-		case AE_IFSOCK:
-			archive_set_error(&a->archive,
-			    ARCHIVE_ERRNO_FILE_FORMAT,
-			    "tar format cannot archive socket");
-			return (ARCHIVE_FAILED);
-		default:
-			archive_set_error(&a->archive,
-			    ARCHIVE_ERRNO_FILE_FORMAT,
-			    "tar format cannot archive this (mode=0%lo)",
-			    (unsigned long)archive_entry_mode(entry));
+		default: /* AE_IFSOCK and unknown */
+			__archive_write_entry_filetype_unsupported(
+			    &a->archive, entry, "ustar");
 			ret = ARCHIVE_FAILED;
 		}
 	}
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_set_format_v7tar.c b/Utilities/cmlibarchive/libarchive/archive_write_set_format_v7tar.c
index 62b1522..5994071 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_set_format_v7tar.c
+++ b/Utilities/cmlibarchive/libarchive/archive_write_set_format_v7tar.c
@@ -44,6 +44,7 @@
 #include "archive_entry_locale.h"
 #include "archive_private.h"
 #include "archive_write_private.h"
+#include "archive_write_set_format_private.h"
 
 struct v7tar {
 	uint64_t	entry_bytes_remaining;
@@ -284,7 +285,7 @@
 		 * case getting WCS failed. On POSIX, this is a
 		 * normal operation.
 		 */
-		if (p != NULL && p[strlen(p) - 1] != '/') {
+		if (p != NULL && p[0] != '\0' && p[strlen(p) - 1] != '/') {
 			struct archive_string as;
 
 			archive_string_init(&as);
@@ -330,14 +331,12 @@
 #endif
 	ret = format_header_v7tar(a, buff, entry, 1, sconv);
 	if (ret < ARCHIVE_WARN) {
-		if (entry_main)
-			archive_entry_free(entry_main);
+		archive_entry_free(entry_main);
 		return (ret);
 	}
 	ret2 = __archive_write_output(a, buff, 512);
 	if (ret2 < ARCHIVE_WARN) {
-		if (entry_main)
-			archive_entry_free(entry_main);
+		archive_entry_free(entry_main);
 		return (ret2);
 	}
 	if (ret2 < ret)
@@ -345,8 +344,7 @@
 
 	v7tar->entry_bytes_remaining = archive_entry_size(entry);
 	v7tar->entry_padding = 0x1ff & (-(int64_t)v7tar->entry_bytes_remaining);
-	if (entry_main)
-		archive_entry_free(entry_main);
+	archive_entry_free(entry_main);
 	return (ret);
 }
 
@@ -494,31 +492,11 @@
 		case AE_IFLNK:
 			h[V7TAR_typeflag_offset] = '2';
 			break;
-		case AE_IFCHR:
-			archive_set_error(&a->archive,
-			    ARCHIVE_ERRNO_FILE_FORMAT,
-			    "tar format cannot archive character device");
-			return (ARCHIVE_FAILED);
-		case AE_IFBLK:
-			archive_set_error(&a->archive,
-			    ARCHIVE_ERRNO_FILE_FORMAT,
-			    "tar format cannot archive block device");
-			return (ARCHIVE_FAILED);
-		case AE_IFIFO:
-			archive_set_error(&a->archive,
-			    ARCHIVE_ERRNO_FILE_FORMAT,
-			    "tar format cannot archive fifo");
-			return (ARCHIVE_FAILED);
-		case AE_IFSOCK:
-			archive_set_error(&a->archive,
-			    ARCHIVE_ERRNO_FILE_FORMAT,
-			    "tar format cannot archive socket");
-			return (ARCHIVE_FAILED);
 		default:
-			archive_set_error(&a->archive,
-			    ARCHIVE_ERRNO_FILE_FORMAT,
-			    "tar format cannot archive this (mode=0%lo)",
-			    (unsigned long)archive_entry_mode(entry));
+			/* AE_IFBLK, AE_IFCHR, AE_IFIFO, AE_IFSOCK
+			 * and unknown */
+			__archive_write_entry_filetype_unsupported(
+			    &a->archive, entry, "v7tar");
 			ret = ARCHIVE_FAILED;
 		}
 	}
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_set_format_warc.c b/Utilities/cmlibarchive/libarchive/archive_write_set_format_warc.c
index edad072..46b0573 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_set_format_warc.c
+++ b/Utilities/cmlibarchive/libarchive/archive_write_set_format_warc.c
@@ -48,6 +48,7 @@
 #include "archive_private.h"
 #include "archive_random_private.h"
 #include "archive_write_private.h"
+#include "archive_write_set_format_private.h"
 
 struct warc_s {
 	unsigned int omit_warcinfo:1;
@@ -259,10 +260,8 @@
 		return (ARCHIVE_OK);
 	}
 	/* just resort to erroring as per Tim's advice */
-	archive_set_error(
-		&a->archive,
-		ARCHIVE_ERRNO_FILE_FORMAT,
-		"WARC can only process regular files");
+	__archive_write_entry_filetype_unsupported(
+	    &a->archive, entry, "WARC");
 	return (ARCHIVE_FAILED);
 }
 
@@ -333,6 +332,10 @@
 #if defined(HAVE_GMTIME_R) || defined(HAVE__GMTIME64_S)
 	struct tm timeHere;
 #endif
+#if defined(HAVE__GMTIME64_S)
+	errno_t terr;
+	__time64_t tmptime;
+#endif
 	char strtime[100];
 	size_t len;
 
@@ -340,7 +343,12 @@
 	if ((rt = gmtime_r(&t, &timeHere)) == NULL)
 		return;
 #elif defined(HAVE__GMTIME64_S)
-	_gmtime64_s(&timeHere, &t);
+	tmptime = t;
+	terr = _gmtime64_s(&timeHere, &tmptime);
+	if (terr)
+		rt = NULL;
+	else
+		rt = &timeHere;
 #else
 	if ((rt = gmtime(&t)) == NULL)
 		return;
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_set_format_xar.c b/Utilities/cmlibarchive/libarchive/archive_write_set_format_xar.c
index 3c617ec..3b0ffb3 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_set_format_xar.c
+++ b/Utilities/cmlibarchive/libarchive/archive_write_set_format_xar.c
@@ -37,13 +37,13 @@
 #include <libxml/xmlwriter.h>
 #endif
 #ifdef HAVE_BZLIB_H
-#include <cm_bzlib.h>
+#include <cm3p/bzlib.h>
 #endif
 #if HAVE_LZMA_H
-#include <cm_lzma.h>
+#include <cm3p/lzma.h>
 #endif
 #ifdef HAVE_ZLIB_H
-#include <cm_zlib.h>
+#include <cm3p/zlib.h>
 #endif
 
 #include "archive.h"
@@ -212,8 +212,8 @@
 	struct heap_data	 data;
         struct archive_string    script;
 
-	int			 virtual:1;
-	int			 dir:1;
+	signed int		 virtual:1;
+	signed int		 dir:1;
 };
 
 struct hardlink {
@@ -411,6 +411,8 @@
 	if (strcmp(key, "checksum") == 0) {
 		if (value == NULL)
 			xar->opt_sumalg = CKSUM_NONE;
+		else if (strcmp(value, "none") == 0)
+			xar->opt_sumalg = CKSUM_NONE;
 		else if (strcmp(value, "sha1") == 0)
 			xar->opt_sumalg = CKSUM_SHA1;
 		else if (strcmp(value, "md5") == 0)
@@ -429,6 +431,8 @@
 
 		if (value == NULL)
 			xar->opt_compression = NONE;
+		else if (strcmp(value, "none") == 0)
+			xar->opt_compression = NONE;
 		else if (strcmp(value, "gzip") == 0)
 			xar->opt_compression = GZIP;
 		else if (strcmp(value, "bzip2") == 0)
@@ -482,6 +486,8 @@
 	if (strcmp(key, "toc-checksum") == 0) {
 		if (value == NULL)
 			xar->opt_toc_sumalg = CKSUM_NONE;
+		else if (strcmp(value, "none") == 0)
+			xar->opt_toc_sumalg = CKSUM_NONE;
 		else if (strcmp(value, "sha1") == 0)
 			xar->opt_toc_sumalg = CKSUM_SHA1;
 		else if (strcmp(value, "md5") == 0)
@@ -496,10 +502,13 @@
 		return (ARCHIVE_OK);
 	}
 	if (strcmp(key, "threads") == 0) {
+		char *endptr;
+
 		if (value == NULL)
 			return (ARCHIVE_FAILED);
-		xar->opt_threads = (int)strtoul(value, NULL, 10);
-		if (xar->opt_threads == 0 && errno != 0) {
+		errno = 0;
+		xar->opt_threads = (int)strtoul(value, &endptr, 10);
+		if (errno != 0 || *endptr != '\0') {
 			xar->opt_threads = 1;
 			archive_set_error(&(a->archive),
 			    ARCHIVE_ERRNO_MISC,
@@ -693,13 +702,37 @@
 		else
 			run = ARCHIVE_Z_FINISH;
 		/* Compress file data. */
-		r = compression_code(&(a->archive), &(xar->stream), run);
-		if (r != ARCHIVE_OK && r != ARCHIVE_EOF)
-			return (ARCHIVE_FATAL);
+		for (;;) {
+			r = compression_code(&(a->archive), &(xar->stream),
+			    run);
+			if (r != ARCHIVE_OK && r != ARCHIVE_EOF)
+				return (ARCHIVE_FATAL);
+			if (xar->stream.avail_out == 0 ||
+			    run == ARCHIVE_Z_FINISH) {
+				size = sizeof(xar->wbuff) -
+				    xar->stream.avail_out;
+				checksum_update(&(xar->a_sumwrk), xar->wbuff,
+				    size);
+				xar->cur_file->data.length += size;
+				if (write_to_temp(a, xar->wbuff,
+				    size) != ARCHIVE_OK)
+					return (ARCHIVE_FATAL);
+				if (r == ARCHIVE_OK) {
+					/* Output buffer was full */
+					xar->stream.next_out = xar->wbuff;
+					xar->stream.avail_out =
+					    sizeof(xar->wbuff);
+				} else {
+					/* ARCHIVE_EOF - We are done */
+					break;
+				}
+			} else {
+				/* Compressor wants more input */
+				break;
+			}
+		}
 		rsize = s - xar->stream.avail_in;
 		checksum_update(&(xar->e_sumwrk), buff, rsize);
-		size = sizeof(xar->wbuff) - xar->stream.avail_out;
-		checksum_update(&(xar->a_sumwrk), xar->wbuff, size);
 	}
 #if !defined(_WIN32) || defined(__CYGWIN__)
 	if (xar->bytes_remaining ==
@@ -736,12 +769,9 @@
 	if (xar->cur_file->data.compression == NONE) {
 		if (write_to_temp(a, buff, size) != ARCHIVE_OK)
 			return (ARCHIVE_FATAL);
-	} else {
-		if (write_to_temp(a, xar->wbuff, size) != ARCHIVE_OK)
-			return (ARCHIVE_FATAL);
+		xar->cur_file->data.length += size;
 	}
 	xar->bytes_remaining -= rsize;
-	xar->cur_file->data.length += size;
 
 	return (rsize);
 }
@@ -875,11 +905,15 @@
 {
 	char timestr[100];
 	struct tm tm;
+#if defined(HAVE__GMTIME64_S)
+	__time64_t tmptime;
+#endif
 
 #if defined(HAVE_GMTIME_R)
 	gmtime_r(&t, &tm);
 #elif defined(HAVE__GMTIME64_S)
-	_gmtime64_s(&tm, &t);
+	tmptime = t;
+	_gmtime64_s(&tm, &tmptime);
 #else
 	memcpy(&tm, gmtime(&t), sizeof(tm));
 #endif
@@ -2100,7 +2134,7 @@
 	while (len > 0) {
 		size_t ll = len;
 
-		if (len > 0 && p[len-1] == '/') {
+		if (p[len-1] == '/') {
 			p[len-1] = '\0';
 			len--;
 		}
@@ -2120,10 +2154,10 @@
 		if (p[0] == '/') {
 			if (p[1] == '/')
 				/* Convert '//' --> '/' */
-				strcpy(p, p+1);
+				memmove(p, p+1, strlen(p+1) + 1);
 			else if (p[1] == '.' && p[2] == '/')
 				/* Convert '/./' --> '/' */
-				strcpy(p, p+2);
+				memmove(p, p+2, strlen(p+2) + 1);
 			else if (p[1] == '.' && p[2] == '.' && p[3] == '/') {
 				/* Convert 'dir/dir1/../dir2/'
 				 *     --> 'dir/dir2/'
@@ -2529,13 +2563,11 @@
 static void
 file_free_hardlinks(struct xar *xar)
 {
-	struct archive_rb_node *n, *next;
+	struct archive_rb_node *n, *tmp;
 
-	for (n = ARCHIVE_RB_TREE_MIN(&(xar->hardlink_rbtree)); n;) {
-		next = __archive_rb_tree_iterate(&(xar->hardlink_rbtree),
-		    n, ARCHIVE_RB_DIR_RIGHT);
+	ARCHIVE_RB_TREE_FOREACH_SAFE(n, &(xar->hardlink_rbtree), tmp) {
+		__archive_rb_tree_remove_node(&(xar->hardlink_rbtree), n);
 		free(n);
-		n = next;
 	}
 }
 
@@ -3169,8 +3201,10 @@
 			checksum_update(&(xar->a_sumwrk),
 			    xar->wbuff, size);
 			if (write_to_temp(a, xar->wbuff, size)
-			    != ARCHIVE_OK)
+			    != ARCHIVE_OK) {
+				free(heap);
 				return (ARCHIVE_FATAL);
+			}
 			if (r == ARCHIVE_OK) {
 				xar->stream.next_out = xar->wbuff;
 				xar->stream.avail_out = sizeof(xar->wbuff);
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_set_format_zip.c b/Utilities/cmlibarchive/libarchive/archive_write_set_format_zip.c
index a4ae229..b0cd215 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_set_format_zip.c
+++ b/Utilities/cmlibarchive/libarchive/archive_write_set_format_zip.c
@@ -45,7 +45,7 @@
 #include <string.h>
 #endif
 #ifdef HAVE_ZLIB_H
-#include <cm_zlib.h>
+#include <cm3p/zlib.h>
 #endif
 
 #include "archive.h"
@@ -57,6 +57,7 @@
 #include "archive_private.h"
 #include "archive_random_private.h"
 #include "archive_write_private.h"
+#include "archive_write_set_format_private.h"
 
 #ifndef HAVE_ZLIB_H
 #include "archive_crc32.h"
@@ -526,8 +527,8 @@
 	/* Ignore types of entries that we don't support. */
 	type = archive_entry_filetype(entry);
 	if (type != AE_IFREG && type != AE_IFDIR && type != AE_IFLNK) {
-		archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
-		    "Filetype not supported");
+		__archive_write_entry_filetype_unsupported(
+		    &a->archive, entry, "zip");
 		return ARCHIVE_FAILED;
 	};
 
@@ -564,10 +565,8 @@
 	zip->entry_uses_zip64 = 0;
 	zip->entry_crc32 = zip->crc32func(0, NULL, 0);
 	zip->entry_encryption = 0;
-	if (zip->entry != NULL) {
-		archive_entry_free(zip->entry);
-		zip->entry = NULL;
-	}
+	archive_entry_free(zip->entry);
+	zip->entry = NULL;
 
 	if (zip->cctx_valid)
 		archive_encrypto_aes_ctr_release(&zip->cctx);
@@ -1374,10 +1373,28 @@
 {
 	struct tm *t;
 	unsigned int dt;
+#if defined(HAVE_LOCALTIME_R) || defined(HAVE__LOCALTIME64_S)
+	struct tm tmbuf;
+#endif
+#if defined(HAVE__LOCALTIME64_S)
+	errno_t terr;
+	__time64_t tmptime;
+#endif
 
 	/* This will not preserve time when creating/extracting the archive
 	 * on two systems with different time zones. */
+#if defined(HAVE_LOCALTIME_R)
+	t = localtime_r(&unix_time, &tmbuf);
+#elif defined(HAVE__LOCALTIME64_S)
+	tmptime = unix_time;
+	terr = _localtime64_s(&tmbuf, &tmptime);
+	if (terr)
+		t = NULL;
+	else
+		t = &tmbuf;
+#else
 	t = localtime(&unix_time);
+#endif
 
 	/* MSDOS-style date/time is only between 1980-01-01 and 2107-12-31 */
 	if (t->tm_year < 1980 - 1900)
@@ -1404,18 +1421,17 @@
 {
 	mode_t type;
 	const char *path;
+	size_t len;
 
 	type = archive_entry_filetype(entry);
 	path = archive_entry_pathname(entry);
 
 	if (path == NULL)
 		return (0);
-	if (type == AE_IFDIR &&
-	    (path[0] == '\0' || path[strlen(path) - 1] != '/')) {
-		return strlen(path) + 1;
-	} else {
-		return strlen(path);
-	}
+	len = strlen(path);
+	if (type == AE_IFDIR && (path[0] == '\0' || path[len - 1] != '/'))
+		++len; /* Space for the trailing / */
+	return len;
 }
 
 static int
@@ -1430,6 +1446,9 @@
 	type = archive_entry_filetype(entry);
 	written_bytes = 0;
 
+	if (path == NULL)
+		return (ARCHIVE_FATAL);
+
 	ret = __archive_write_output(archive, path, strlen(path));
 	if (ret != ARCHIVE_OK)
 		return (ARCHIVE_FATAL);
@@ -1460,10 +1479,8 @@
 	memcpy(p, path, pathlen);
 
 	/* Folders are recognized by a trailing slash. */
-	if ((type == AE_IFDIR) & (path[pathlen - 1] != '/')) {
+	if ((type == AE_IFDIR) && (path[pathlen - 1] != '/'))
 		p[pathlen] = '/';
-		p[pathlen + 1] = '\0';
-	}
 }
 
 
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_set_options.3 b/Utilities/cmlibarchive/libarchive/archive_write_set_options.3
index aeb7a18..cffe571 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_set_options.3
+++ b/Utilities/cmlibarchive/libarchive/archive_write_set_options.3
@@ -24,7 +24,7 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd February 2, 2012
+.Dd January 31, 2020
 .Dt ARCHIVE_WRITE_OPTIONS 3
 .Os
 .Sh NAME
@@ -70,7 +70,7 @@
 .Fn archive_write_set_filter_option ,
 .Fn archive_write_set_format_option
 .Xc
-Specifies an option that will be passed to currently-registered
+Specifies an option that will be passed to the currently-registered
 filters (including decompression filters) or format readers.
 .Pp
 If
@@ -138,7 +138,7 @@
 .Cm ARCHIVE_FATAL
 will be returned
 immediately.
-Otherwise, greater of the two values will be returned.
+Otherwise, the greater of the two values will be returned.
 .\"
 .It Fn archive_write_set_options
 .Ar options
@@ -170,55 +170,153 @@
 .\"
 .Sh OPTIONS
 .Bl -tag -compact -width indent
+.It Filter b64encode
+.Bl -tag -compact -width indent
+.It Cm mode
+The value is interpreted as octal digits specifying the file mode.
+.It Cm name
+The value specifies the file name.
+.El
+.It Filter bzip2
+.Bl -tag -compact -width indent
+.It Cm compression-level
+The value is interpreted as a decimal integer specifying the
+bzip2 compression level. Supported values are from 1 to 9.
+.El
 .It Filter gzip
 .Bl -tag -compact -width indent
 .It Cm compression-level
 The value is interpreted as a decimal integer specifying the
-gzip compression level.
+gzip compression level. Supported values are from 0 to 9.
+.It Cm timestamp
+Store timestamp. This is enabled by default.
+.El
+.It Filter lrzip
+.Bl -tag -compact -width indent
+.It Cm compression Ns = Ns Ar type
+Use
+.Ar type
+as compression method.
+Supported values are
+.Dq bzip2 ,
+.Dq gzipi ,
+.Dq lzo
+.Pq ultra fast ,
+and
+.Dq zpaq
+.Pq best, extremely slow .
+.It Cm compression-level
+The value is interpreted as a decimal integer specifying the
+lrzip compression level. Supported values are from 1 to 9.
+.El
+.It Filter lz4
+.Bl -tag -compact -width indent
+.It Cm compression-level
+The value is interpreted as a decimal integer specifying the
+lz4 compression level. Supported values are from 0 to 9.
+.It Cm stream-checksum
+Enable stream checksum. This is enabled by default.
+.It Cm block-checksum
+Enable block checksum. This is disabled by default.
+.It Cm block-size
+The value is interpreted as a decimal integer specifying the
+lz4 compression block size. Supported values are from 4 to 7
+.Pq default .
+.It Cm block-dependence
+Use the previous block of the block being compressed for
+a compression dictionary to improve compression ratio.
+This is disabled by default.
+.El
+.It Filter lzop
+.Bl -tag -compact -width indent
+.It Cm compression-level
+The value is interpreted as a decimal integer specifying the
+lzop compression level. Supported values are from 1 to 9.
+.El
+.It Filter uuencode
+.Bl -tag -compact -width indent
+.It Cm mode
+The value is interpreted as octal digits specifying the file mode.
+.It Cm name
+The value specifies the file name.
 .El
 .It Filter xz
 .Bl -tag -compact -width indent
 .It Cm compression-level
 The value is interpreted as a decimal integer specifying the
-compression level.
+compression level. Supported values are from 0 to 9.
+.It Cm threads
+The value is interpreted as a decimal integer specifying the
+number of threads for multi-threaded lzma compression.
+If supported, the default value is read from
+.Fn lzma_cputhreads .
 .El
-.It Format mtree
+.It Filter zstd
 .Bl -tag -compact -width indent
-.It Cm cksum , Cm device , Cm flags , Cm gid , Cm gname , Cm indent , Cm link , Cm md5 , Cm mode , Cm nlink , Cm rmd160 , Cm sha1 , Cm sha256 , Cm sha384 , Cm sha512 , Cm size , Cm time , Cm uid , Cm uname
-Enable a particular keyword in the mtree output.
-Prefix with an exclamation mark to disable the corresponding keyword.
-The default is equivalent to
-.Dq device, flags, gid, gname, link, mode, nlink, size, time, type, uid, uname .
-.It Cm all
-Enables all of the above keywords.
-.It Cm use-set
-Enables generation of
-.Cm /set
-lines that specify default values for the following files and/or directories.
-.It Cm indent
-XXX needs explanation XXX
+.It Cm compression-level
+The value is interpreted as a decimal integer specifying the
+compression level. Supported values are from 1 to 22.
+.El
+.It Format 7zip
+.Bl -tag -compact -width indent
+.It Cm compression
+The value is one of
+.Dq store ,
+.Dq deflate ,
+.Dq bzip2 ,
+.Dq lzma1 ,
+.Dq lzma2
+or
+.Dq ppmd
+to indicate how the following entries should be compressed.
+Note that this setting is ignored for directories, symbolic links,
+and other special entries.
+.It Cm compression-level
+The value is interpreted as a decimal integer specifying the
+compression level.
+Values between 0 and 9 are supported.
+The interpretation of the compression level depends on the chosen
+compression method.
+.El
+.It Format cpio
+.Bl -tag -compact -width indent
+.It Cm hdrcharset
+The value is used as a character set name that will be
+used when translating file names.
+.El
+.It Format gnutar
+.Bl -tag -compact -width indent
+.It Cm hdrcharset
+The value is used as a character set name that will be
+used when translating file, group and user names.
 .El
 .It Format iso9660 - volume metadata
 These options are used to set standard ISO9660 metadata.
 .Bl -tag -compact -width indent
 .It Cm abstract-file Ns = Ns Ar filename
 The file with the specified name will be identified in the ISO9660 metadata
-as holding the abstract for this volume.  Default: none.
+as holding the abstract for this volume.
+Default: none.
 .It Cm application-id Ns = Ns Ar filename
 The file with the specified name will be identified in the ISO9660 metadata
-as holding the application identifier for this volume.  Default: none.
+as holding the application identifier for this volume.
+Default: none.
 .It Cm biblio-file Ns = Ns Ar filename
 The file with the specified name will be identified in the ISO9660 metadata
-as holding the bibliography for this volume.  Default: none.
+as holding the bibliography for this volume.
+Default: none.
 .It Cm copyright-file Ns = Ns Ar filename
 The file with the specified name will be identified in the ISO9660 metadata
-as holding the copyright for this volume.  Default: none.
+as holding the copyright for this volume.
+Default: none.
 .It Cm publisher Ns = Ns Ar filename
 The file with the specified name will be identified in the ISO9660 metadata
-as holding the publisher information for this volume.  Default: none.
+as holding the publisher information for this volume.
+Default: none.
 .It Cm volume-id Ns = Ns Ar string
 The specified string will be used as the Volume Identifier in the ISO9660 metadata.
-It is limited to 32 bytes. Default: none.
+It is limited to 32 bytes.
+Default: none.
 .El
 .It Format iso9660 - boot support
 These options are used to make an ISO9660 image that can be directly
@@ -266,7 +364,7 @@
 the default is
 .Cm fd ,
 otherwise the default is
-.Cm no-emulation.
+.Cm no-emulation .
 .El
 .It Format iso9660 - filename and size extensions
 Various extensions to the base ISO9660 format.
@@ -290,7 +388,7 @@
 Default: disabled.
 .It Cm allow-period
 If enabled, allows filenames to contain trailing period characters, in violation of the ISO9660 specification.
-If disabled,trailing periods will be converted to underscore characters.
+If disabled, trailing periods will be converted to underscore characters.
 This does not impact names stored in the Rockridge or Joliet extension area.
 Default: disabled.
 .It Cm allow-pvd-lowercase
@@ -398,6 +496,111 @@
 This option can be provided multiple times to suppress compression
 on many files.
 .El
+.It Format mtree
+.Bl -tag -compact -width indent
+.It Cm cksum , Cm device , Cm flags , Cm gid , Cm gname , Cm indent , Cm link , Cm md5 , Cm mode , Cm nlink , Cm rmd160 , Cm sha1 , Cm sha256 , Cm sha384 , Cm sha512 , Cm size , Cm time , Cm uid , Cm uname
+Enable a particular keyword in the mtree output.
+Prefix with an exclamation mark to disable the corresponding keyword.
+The default is equivalent to
+.Dq device, flags, gid, gname, link, mode, nlink, size, time, type, uid, uname .
+.It Cm all
+Enables all of the above keywords.
+.It Cm use-set
+Enables generation of
+.Cm /set
+lines that specify default values for the following files and/or directories.
+.It Cm indent
+XXX needs explanation XXX
+.El
+.It Format newc
+.Bl -tag -compact -width indent
+.It Cm hdrcharset
+The value is used as a character set name that will be
+used when translating file names.
+.El
+.It Format pax
+.Bl -tag -compact -width indent
+.It Cm hdrcharset
+The value is used as a character set name that will be
+used when translating file, group and user names.
+The value is one of
+.Dq BINARY
+or
+.Dq UTF-8 .
+With
+.Dq BINARY
+there is no character conversion, with
+.Dq UTF-8
+names are converted to UTF-8.
+.It Cm xattrheader
+When storing extended attributes, this option configures which
+headers should be written. The value is one of
+.Dq all ,
+.Dq LIBARCHIVE ,
+or
+.Dq SCHILY .
+By default, both
+.Dq LIBARCHIVE.xattr
+and
+.Dq SCHILY.xattr
+headers are written.
+.El
+.It Format ustar
+.Bl -tag -compact -width indent
+.It Cm hdrcharset
+The value is used as a character set name that will be
+used when translating file, group and user names.
+.El
+.It Format v7tar
+.Bl -tag -compact -width indent
+.It Cm hdrcharset
+The value is used as a character set name that will be
+used when translating file, group and user names.
+.El
+.It Format warc
+.Bl -tag -compact -width indent
+.It Cm omit-warcinfo
+Set to
+.Dq true
+to disable output of the warcinfo record.
+.El
+.It Format xar
+.Bl -tag -compact -width indent
+.It Cm checksum Ns = Ns Ar type
+Use
+.Ar type
+as file checksum method.
+Supported values are
+.Dq none ,
+.Dq md5 ,
+and
+.Dq sha1
+.Pq default .
+.It Cm compression Ns = Ns Ar type
+Use
+.Ar type
+as compression method.
+Supported values are
+.Dq none ,
+.Dq bzip2 ,
+.Dq gzip
+.Pq default ,
+.Dq lzma
+and
+.Dq xz .
+.It Cm compression_level
+The value is a decimal integer from 1 to 9 specifying the compression level.
+.It Cm toc-checksum Ns = Ns Ar type
+Use
+.Ar type
+as table of contents checksum method.
+Supported values are
+.Dq none ,
+.Dq md5
+and
+.Dq sha1
+.Pq default .
+.El
 .It Format zip
 .Bl -tag -compact -width indent
 .It Cm compression
@@ -408,6 +611,29 @@
 to indicate how the following entries should be compressed.
 Note that this setting is ignored for directories, symbolic links,
 and other special entries.
+.It Cm compression-level
+The value is interpreted as a decimal integer specifying the
+compression level.
+Values between 0 and 9 are supported.
+A compression level of 0 switches the compression method to
+.Dq store ,
+other values will enable
+.Dq deflate
+compression with the given level.
+.It Cm encryption
+Enable encryption using traditional zip encryption.
+.It Cm encryption Ns = Ns Ar type
+Use
+.Ar type
+as encryption type.
+Supported values are
+.Dq zipcrypt
+.Pq traditional zip encryption ,
+.Dq aes128
+.Pq WinZip AES-128 encryption
+and
+.Dq aes256
+.Pq WinZip AES-256 encryption .
 .It Cm experimental
 This boolean option enables or disables experimental Zip features
 that may not be compatible with other Zip implementations.
@@ -416,7 +642,8 @@
 All CRC fields are set to zero.
 It should not be used except for testing purposes.
 .It Cm hdrcharset
-This sets the character set used for filenames.
+The value is used as a character set name that will be
+used when translating file names.
 .It Cm zip64
 Zip64 extensions provide additional file size information
 for entries larger than 4 GiB.
@@ -465,9 +692,9 @@
 .\"
 .Sh SEE ALSO
 .Xr tar 1 ,
-.Xr libarchive 3 ,
 .Xr archive_read_set_options 3 ,
-.Xr archive_write 3
+.Xr archive_write 3 ,
+.Xr libarchive 3
 .Sh HISTORY
 The
 .Nm libarchive
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_set_passphrase.3 b/Utilities/cmlibarchive/libarchive/archive_write_set_passphrase.3
index 2585595..2db7703 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_set_passphrase.3
+++ b/Utilities/cmlibarchive/libarchive/archive_write_set_passphrase.3
@@ -49,7 +49,7 @@
 .Sh DESCRIPTION
 .Bl -tag -width indent
 .It Fn archive_write_set_passphrase
-Set a passphrase for writing an encryption archive.
+Set a passphrase for writing an encrypted archive.
 If
 .Ar passphrase
 is
@@ -59,16 +59,16 @@
 will be returned.
 Otherwise,
 .Cm ARCHIVE_OK
-will be returned. 
+will be returned.
 .It Fn archive_write_set_passphrase_callback
-Register callback function that will be invoked to get a passphrase
-for encrption if the passphrase was not set by the
+Register a callback function that will be invoked to get a passphrase
+for encryption if the passphrase was not set by the
 .Fn archive_write_set_passphrase
 function.
 .El
 .\" .Sh ERRORS
 .Sh SEE ALSO
 .Xr tar 1 ,
-.Xr libarchive 3 ,
 .Xr archive_write 3 ,
-.Xr archive_write_set_options 3
+.Xr archive_write_set_options 3 ,
+.Xr libarchive 3
diff --git a/Utilities/cmlibarchive/libarchive/archive_xxhash.h b/Utilities/cmlibarchive/libarchive/archive_xxhash.h
index 4272416..1c7131c 100644
--- a/Utilities/cmlibarchive/libarchive/archive_xxhash.h
+++ b/Utilities/cmlibarchive/libarchive/archive_xxhash.h
@@ -24,12 +24,13 @@
  *
  */
 
+#ifndef ARCHIVE_XXHASH_H_INCLUDED
+#define ARCHIVE_XXHASH_H_INCLUDED
+
 #ifndef __LIBARCHIVE_BUILD
 #error This header is only to be used internally to libarchive.
 #endif
 
-#ifndef ARCHIVE_XXHASH_H
-#define ARCHIVE_XXHASH_H
 
 typedef enum { XXH_OK=0, XXH_ERROR } XXH_errorcode;
 
diff --git a/Utilities/cmlibarchive/libarchive/config_freebsd.h b/Utilities/cmlibarchive/libarchive/config_freebsd.h
index be25258..f16fd34 100644
--- a/Utilities/cmlibarchive/libarchive/config_freebsd.h
+++ b/Utilities/cmlibarchive/libarchive/config_freebsd.h
@@ -210,6 +210,7 @@
 #define HAVE_TZSET 1
 #define HAVE_UINTMAX_T 1
 #define HAVE_UNISTD_H 1
+#define HAVE_UNLINKAT 1
 #define HAVE_UNSETENV 1
 #define HAVE_UNSIGNED_LONG_LONG 1
 #define HAVE_UNSIGNED_LONG_LONG_INT 1
diff --git a/Utilities/cmlibarchive/libarchive/filter_fork.h b/Utilities/cmlibarchive/libarchive/filter_fork.h
index a28272b..908e7cd 100644
--- a/Utilities/cmlibarchive/libarchive/filter_fork.h
+++ b/Utilities/cmlibarchive/libarchive/filter_fork.h
@@ -25,13 +25,13 @@
  * $FreeBSD: head/lib/libarchive/filter_fork.h 201087 2009-12-28 02:18:26Z kientzle $
  */
 
+#ifndef FILTER_FORK_H
+#define FILTER_FORK_H
+
 #ifndef __LIBARCHIVE_BUILD
 #error This header is only to be used internally to libarchive.
 #endif
 
-#ifndef FILTER_FORK_H
-#define FILTER_FORK_H
-
 pid_t
 __archive_create_child(const char *cmd, int *child_stdin, int *child_stdout);
 
diff --git a/Utilities/cmlibarchive/libarchive/libarchive_changes.3 b/Utilities/cmlibarchive/libarchive/libarchive_changes.3
index adc87fe..6bf8db0 100644
--- a/Utilities/cmlibarchive/libarchive/libarchive_changes.3
+++ b/Utilities/cmlibarchive/libarchive/libarchive_changes.3
@@ -35,7 +35,6 @@
 This page describes user-visible changes in libarchive3, and lists
 public functions and other symbols changed, deprecated or removed
 in libarchive3, along with their replacements if any.
-.Pp
 .\"
 .Ss Multiple Filters
 .\"
@@ -330,13 +329,13 @@
 .Li 10240
 .El
 .Sh SEE ALSO
-.Xr libarchive 3 ,
 .Xr archive_read 3 ,
 .Xr archive_read_filter 3 ,
 .Xr archive_read_format 3 ,
 .Xr archive_read_set_options 3 ,
+.Xr archive_util 3 ,
 .Xr archive_write 3 ,
 .Xr archive_write_filter 3 ,
 .Xr archive_write_format 3 ,
 .Xr archive_write_set_options 3 ,
-.Xr archive_util 3
+.Xr libarchive 3
diff --git a/Utilities/cmlibarchive/libarchive/libarchive_internals.3 b/Utilities/cmlibarchive/libarchive/libarchive_internals.3
index 8275d66..d672f3e 100644
--- a/Utilities/cmlibarchive/libarchive/libarchive_internals.3
+++ b/Utilities/cmlibarchive/libarchive/libarchive_internals.3
@@ -350,8 +350,8 @@
 .Xr archive_entry 3 ,
 .Xr archive_read 3 ,
 .Xr archive_write 3 ,
-.Xr archive_write_disk 3
-.Xr libarchive 3 ,
+.Xr archive_write_disk 3 ,
+.Xr libarchive 3
 .Sh HISTORY
 The
 .Nm libarchive
diff --git a/Utilities/cmlibarchive/libarchive/mtree.5 b/Utilities/cmlibarchive/libarchive/mtree.5
index e607e4a..8147796 100644
--- a/Utilities/cmlibarchive/libarchive/mtree.5
+++ b/Utilities/cmlibarchive/libarchive/mtree.5
@@ -133,7 +133,6 @@
 .Sy char
 file types.
 The value must be one of the following forms:
-.Pp
 .Bl -tag -width 4n
 .It Ar format , Ns Ar major , Ns Ar minor Ns Bo , Ns Ar subunit Bc
 A device with
@@ -165,8 +164,8 @@
 .Sy solaris ,
 .Sy sunos ,
 .Sy svr3 ,
-.Sy svr4 ,  
-and 
+.Sy svr4 ,
+and
 .Sy ultrix .
 .Pp
 See
@@ -288,12 +287,10 @@
 .It Cm uname
 The file owner as a symbolic name.
 .El
-.Pp
 .Sh SEE ALSO
 .Xr cksum 1 ,
 .Xr find 1 ,
 .Xr mtree 8
-.Sh BUGS
 .Sh HISTORY
 The
 .Nm
diff --git a/Utilities/cmlibarchive/libarchive/tar.5 b/Utilities/cmlibarchive/libarchive/tar.5
index 30b837d..34ad4f7 100644
--- a/Utilities/cmlibarchive/libarchive/tar.5
+++ b/Utilities/cmlibarchive/libarchive/tar.5
@@ -441,7 +441,7 @@
 Vendor-specific attributes used by Joerg Schilling's
 .Nm star
 implementation.
-.It Cm SCHILY.acl.access , Cm SCHILY.acl.default, Cm SCHILY.acl.ace
+.It Cm SCHILY.acl.access , Cm SCHILY.acl.default , Cm SCHILY.acl.ace
 Stores the access, default and NFSv4 ACLs as textual strings in a format
 that is an extension of the format specified by POSIX.1e draft 17.
 In particular, each user or group access specification can include
@@ -456,7 +456,7 @@
 .It Cm SCHILY.realsize
 The full size of the file on disk.
 XXX explain? XXX
-.It Cm SCHILY.dev, Cm SCHILY.ino , Cm SCHILY.nlinks
+.It Cm SCHILY.dev , Cm SCHILY.ino , Cm SCHILY.nlinks
 The device number, inode number, and link count for the entry.
 In particular, note that a pax interchange format archive using Joerg
 Schilling's
@@ -473,7 +473,7 @@
 .Dq ctime
 attribute, which refers to the time when the file
 metadata was last changed.)
-.It Cm LIBARCHIVE.xattr. Ns Ar namespace Ns . Ns Ar key
+.It Cm LIBARCHIVE.xattr . Ns Ar namespace . Ns Ar key
 Libarchive stores POSIX.1e-style extended attributes using
 keys of this form.
 The
@@ -890,7 +890,8 @@
 .It Cm M
 GNU tar multivolume marker, indicating the file is a continuation of a file from the previous volume.
 .It Cm N
-GNU tar long filename support.  Deprecated.
+GNU tar long filename support.
+Deprecated.
 .It Cm S
 GNU tar sparse regular file.
 .It Cm V
diff --git a/Utilities/cmliblzma/CMakeLists.txt b/Utilities/cmliblzma/CMakeLists.txt
index b443fd6..6b6fae6 100644
--- a/Utilities/cmliblzma/CMakeLists.txt
+++ b/Utilities/cmliblzma/CMakeLists.txt
@@ -7,11 +7,10 @@
 include(TestBigEndian)
 
 CHECK_INCLUDE_FILE(byteswap.h HAVE_BYTESWAP_H)
-CHECK_INCLUDE_FILE(inttypes.h HAVE_INTTYPES_H)
 CHECK_INCLUDE_FILE(limits.h HAVE_LIMITS_H)
 CHECK_INCLUDE_FILE(memory.h HAVE_MEMORY_H)
 CHECK_INCLUDE_FILE(strings.h HAVE_STRINGS_H)
-CHECK_INCLUDE_FILE(string.h HAVE_STRING_H)
+set(HAVE_STRING_H 1)
 CHECK_INCLUDE_FILE(sys/sysctl.h HAVE_SYS_SYSCTL_H)
 
 CHECK_INCLUDE_FILE(stdbool.h HAVE_STDBOOL_H)
@@ -60,40 +59,6 @@
 set(HAVE_MF_HC3 1)
 set(HAVE_MF_HC4 1)
 
-CHECK_TYPE_SIZE(int16_t INT16_T)
-CHECK_TYPE_SIZE(int32_t INT32_T)
-CHECK_TYPE_SIZE(int64_t INT64_T)
-CHECK_TYPE_SIZE(intmax_t INTMAX_T)
-CHECK_TYPE_SIZE(uint8_t UINT8_T)
-CHECK_TYPE_SIZE(uint16_t UINT16_T)
-CHECK_TYPE_SIZE(uint32_t UINT32_T)
-CHECK_TYPE_SIZE(uint64_t UINT64_T)
-CHECK_TYPE_SIZE(uintmax_t UINTMAX_T)
-
-CHECK_TYPE_SIZE("short" SIZE_OF_SHORT)
-CHECK_TYPE_SIZE("int" SIZE_OF_INT)
-CHECK_TYPE_SIZE("long" SIZE_OF_LONG)
-CHECK_TYPE_SIZE("long long" SIZE_OF_LONG_LONG)
-
-CHECK_TYPE_SIZE("unsigned short" SIZE_OF_UNSIGNED_SHORT)
-CHECK_TYPE_SIZE("unsigned" SIZE_OF_UNSIGNED)
-CHECK_TYPE_SIZE("unsigned long" SIZE_OF_UNSIGNED_LONG)
-CHECK_TYPE_SIZE("unsigned long long" SIZE_OF_UNSIGNED_LONG_LONG)
-CHECK_TYPE_SIZE("size_t" SIZEOF_SIZE_T)
-
-CHECK_TYPE_SIZE("__int64" __INT64)
-CHECK_TYPE_SIZE("unsigned __int64" UNSIGNED___INT64)
-
-CHECK_TYPE_SIZE(uintptr_t UINTPTR_T)
-IF(NOT HAVE_UINTPTR_T)
-  IF("${CMAKE_SIZEOF_VOID_P}" EQUAL 8)
-    SET(uintptr_t "uint64_t")
-  ELSE()
-    SET(uintptr_t "uint32_t")
-  ENDIF()
-ENDIF()
-
-
 SET(LZMA_SRCS
   common/sysdefs.h
   common/tuklib_integer.h
diff --git a/Utilities/cmliblzma/config.h.in b/Utilities/cmliblzma/config.h.in
index 06f7fcb..20916ca 100644
--- a/Utilities/cmliblzma/config.h.in
+++ b/Utilities/cmliblzma/config.h.in
@@ -3,183 +3,36 @@
  * Ensure we have C99-style int64_t, etc, all defined.
  */
 
-/* First, we need to know if the system has already defined them. */
-#cmakedefine HAVE_INT16_T
-#cmakedefine HAVE_INT32_T
-#cmakedefine HAVE_INT64_T
-#cmakedefine HAVE_INTMAX_T
+#include <cm3p/kwiml/int.h>
 
-#cmakedefine HAVE_UINT8_T
-#cmakedefine HAVE_UINT16_T
-#cmakedefine HAVE_UINT32_T
-#cmakedefine HAVE_UINT64_T
-#cmakedefine HAVE_UINTMAX_T
-
-/* We might have the types we want under other spellings. */
-#cmakedefine HAVE___INT64
-#cmakedefine HAVE_U_INT64_T
-#cmakedefine HAVE_UNSIGNED___INT64
-
-/* The sizes of various standard integer types. */
-@SIZE_OF_SHORT_CODE@
-@SIZE_OF_INT_CODE@
-@SIZE_OF_LONG_CODE@
-@SIZE_OF_LONG_LONG_CODE@
-@SIZE_OF_UNSIGNED_SHORT_CODE@
-@SIZE_OF_UNSIGNED_CODE@
-@SIZE_OF_UNSIGNED_LONG_CODE@
-@SIZE_OF_UNSIGNED_LONG_LONG_CODE@
-@SIZEOF_SIZE_T_CODE@
-
-/*
- * If we lack int64_t, define it to the first of __int64, int, long, and long long
- * that exists and is the right size.
- */
-#if !defined(HAVE_INT64_T) && defined(HAVE___INT64)
-typedef __int64 int64_t;
-#define HAVE_INT64_T
+#ifndef KWIML_INT_HAVE_INT64_T
+typedef KWIML_INT_int64_t int64_t;
 #endif
-
-#if !defined(HAVE_INT64_T) && SIZE_OF_INT == 8
-typedef int int64_t;
-#define HAVE_INT64_T
+#ifndef KWIML_INT_HAVE_INT32_T
+typedef KWIML_INT_int32_t int32_t;
 #endif
-
-#if !defined(HAVE_INT64_T) && SIZE_OF_LONG == 8
-typedef long int64_t;
-#define HAVE_INT64_T
+#ifndef KWIML_INT_HAVE_INT16_T
+typedef KWIML_INT_int16_t int16_t;
 #endif
-
-#if !defined(HAVE_INT64_T) && SIZE_OF_LONG_LONG == 8
-typedef long long int64_t;
-#define HAVE_INT64_T
+#ifndef KWIML_INT_HAVE_INT8_T
+typedef KWIML_INT_int8_t int8_t;
 #endif
-
-#if !defined(HAVE_INT64_T)
-#error No 64-bit integer type was found.
+#ifndef KWIML_INT_HAVE_UINT64_T
+typedef KWIML_INT_uint64_t uint64_t;
 #endif
-
-/*
- * Similarly for int32_t
- */
-#if !defined(HAVE_INT32_T) && SIZE_OF_INT == 4
-typedef int int32_t;
-#define HAVE_INT32_T
+#ifndef KWIML_INT_HAVE_UINT32_T
+typedef KWIML_INT_uint32_t uint32_t;
 #endif
-
-#if !defined(HAVE_INT32_T) && SIZE_OF_LONG == 4
-typedef long int32_t;
-#define HAVE_INT32_T
+#ifndef KWIML_INT_HAVE_UINT16_T
+typedef KWIML_INT_uint16_t uint16_t;
 #endif
-
-#if !defined(HAVE_INT32_T)
-#error No 32-bit integer type was found.
+#ifndef KWIML_INT_HAVE_UINT8_T
+typedef KWIML_INT_uint8_t uint8_t;
 #endif
-
-/*
- * Similarly for int16_t
- */
-#if !defined(HAVE_INT16_T) && SIZE_OF_INT == 2
-typedef int int16_t;
-#define HAVE_INT16_T
+#ifndef KWIML_INT_HAVE_UINTPTR_T
+typedef KWIML_INT_uintptr_t uintptr_t;
 #endif
 
-#if !defined(HAVE_INT16_T) && SIZE_OF_SHORT == 2
-typedef short int16_t;
-#define HAVE_INT16_T
-#endif
-
-#if !defined(HAVE_INT16_T)
-#error No 16-bit integer type was found.
-#endif
-
-/*
- * Similarly for uint64_t
- */
-#if !defined(HAVE_UINT64_T) && defined(HAVE_UNSIGNED___INT64)
-typedef unsigned __int64 uint64_t;
-#define HAVE_UINT64_T
-#endif
-
-#if !defined(HAVE_UINT64_T) && SIZE_OF_UNSIGNED == 8
-typedef unsigned uint64_t;
-#define HAVE_UINT64_T
-#endif
-
-#if !defined(HAVE_UINT64_T) && SIZE_OF_UNSIGNED_LONG == 8
-typedef unsigned long uint64_t;
-#define HAVE_UINT64_T
-#endif
-
-#if !defined(HAVE_UINT64_T) && SIZE_OF_UNSIGNED_LONG_LONG == 8
-typedef unsigned long long uint64_t;
-#define HAVE_UINT64_T
-#endif
-
-#if !defined(HAVE_UINT64_T)
-#error No 64-bit unsigned integer type was found.
-#endif
-
-/*
- * Similarly for uint32_t
- */
-#if !defined(HAVE_UINT32_T) && SIZE_OF_UNSIGNED == 4
-typedef unsigned uint32_t;
-#define HAVE_UINT32_T
-#endif
-
-#if !defined(HAVE_UINT32_T) && SIZE_OF_UNSIGNED_LONG == 4
-typedef unsigned long uint32_t;
-#define HAVE_UINT32_T
-#endif
-
-#if !defined(HAVE_UINT32_T)
-#error No 32-bit unsigned integer type was found.
-#endif
-
-/*
- * Similarly for uint16_t
- */
-#if !defined(HAVE_UINT16_T) && SIZE_OF_UNSIGNED == 2
-typedef unsigned uint16_t;
-#define HAVE_UINT16_T
-#endif
-
-#if !defined(HAVE_UINT16_T) && SIZE_OF_UNSIGNED_SHORT == 2
-typedef unsigned short uint16_t;
-#define HAVE_UINT16_T
-#endif
-
-#if !defined(HAVE_UINT16_T)
-#error No 16-bit unsigned integer type was found.
-#endif
-
-/*
- * Similarly for uint8_t
- */
-#if !defined(HAVE_UINT8_T)
-typedef unsigned char uint8_t;
-#define HAVE_UINT8_T
-#endif
-
-#if !defined(HAVE_UINT16_T)
-#error No 8-bit unsigned integer type was found.
-#endif
-
-/* Define intmax_t and uintmax_t if they are not already defined. */
-#if !defined(HAVE_INTMAX_T)
-typedef int64_t intmax_t;
-#define INTMAX_MIN INT64_MIN
-#define INTMAX_MAX INT64_MAX
-#endif
-
-#if !defined(HAVE_UINTMAX_T)
-typedef uint64_t uintmax_t;
-#endif
-
-
-#cmakedefine uintptr_t @uintptr_t@
-
 #cmakedefine WORDS_BIGENDIAN 1
 
 #cmakedefine HAVE_BYTESWAP_H 1
@@ -219,7 +72,9 @@
 #define HAVE_MF_HC4 1
 
 /* Define to 1 if you have the <inttypes.h> header file. */
-#cmakedefine HAVE_INTTYPES_H 1
+#ifdef KWIML_INT_HAVE_INTTYPES_H
+# define HAVE_INTTYPES_H 1
+#endif
 
 /* Define to 1 if you have the <limits.h> header file. */
 #cmakedefine HAVE_LIMITS_H 1
@@ -231,7 +86,9 @@
 #cmakedefine HAVE_STDBOOL_H 1
 
 /* Define to 1 if you have the <stdint.h> header file. */
-#cmakedefine HAVE_STDINT_H 1
+#ifdef KWIML_INT_HAVE_STDINT_H
+# define HAVE_STDINT_H 1
+#endif
 
 /* Define to 1 if you have the <strings.h> header file. */
 #cmakedefine HAVE_STRINGS_H 1
diff --git a/Utilities/cmlibrhash/CMakeLists.txt b/Utilities/cmlibrhash/CMakeLists.txt
index 6067b7d..1b025fc 100644
--- a/Utilities/cmlibrhash/CMakeLists.txt
+++ b/Utilities/cmlibrhash/CMakeLists.txt
@@ -37,4 +37,4 @@
 
 add_library(cmlibrhash ${librhash_sources})
 
-install(FILES COPYING README DESTINATION ${CMAKE_DOC_DIR}/cmlibrhash)
+install(FILES COPYING DESTINATION ${CMAKE_DOC_DIR}/cmlibrhash)
diff --git a/Utilities/cmlibrhash/COPYING b/Utilities/cmlibrhash/COPYING
index bf65ee1..be7d4a9 100644
--- a/Utilities/cmlibrhash/COPYING
+++ b/Utilities/cmlibrhash/COPYING
@@ -1,15 +1,15 @@
 
-                                RHash License
+                           BSD Zero Clause License
 
-Copyright (c) 2005-2014 Aleksey Kravchenko <rhash.admin@gmail.com>
+Copyright (c) 2005, Aleksey Kravchenko <rhash.admin@gmail.com>
 
-Permission is hereby granted, free of charge,  to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction,  including without limitation the rights
-to  use,  copy,  modify,  merge, publish, distribute, sublicense, and/or sell
-copies  of  the Software,  and  to permit  persons  to whom  the Software  is
-furnished to do so.
+Permission to use, copy, modify, and/or distribute this software for any
+purpose with or without fee is hereby granted.
 
-The Software  is distributed in the hope that it will be useful,  but WITHOUT
-ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-FOR A PARTICULAR PURPOSE.  Use  this  program  at  your  own  risk!
+THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
+REGARD TO THIS SOFTWARE  INCLUDING ALL IMPLIED WARRANTIES OF  MERCHANTABILITY
+AND FITNESS.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
+INDIRECT,  OR CONSEQUENTIAL DAMAGES  OR ANY DAMAGES WHATSOEVER RESULTING FROM
+LOSS OF USE,  DATA OR PROFITS,  WHETHER IN AN ACTION OF CONTRACT,  NEGLIGENCE
+OR OTHER TORTIOUS ACTION,  ARISING OUT OF  OR IN CONNECTION  WITH THE USE  OR
+PERFORMANCE OF THIS SOFTWARE.
diff --git a/Utilities/cmlibrhash/README b/Utilities/cmlibrhash/README
deleted file mode 100644
index 4ea492f..0000000
--- a/Utilities/cmlibrhash/README
+++ /dev/null
@@ -1,7 +0,0 @@
-                       === Notes on RHash License ===
-
-The RHash program and LibRHash library are distributed under  RHash License,
-see the COPYING file for details.  In particular,  the program,  the library
-and  source code  can be  used  free of charge  under  the  MIT,  BSD,  GPL,
-commercial or freeware license without additional restrictions.  In the case
-the OSI-approved license is required the  MIT license should be used.
diff --git a/Utilities/cmlibrhash/librhash/algorithms.c b/Utilities/cmlibrhash/librhash/algorithms.c
index fc01690..cdd4053 100644
--- a/Utilities/cmlibrhash/librhash/algorithms.c
+++ b/Utilities/cmlibrhash/librhash/algorithms.c
@@ -1,17 +1,17 @@
 /* algorithms.c - the algorithms supported by the rhash library
  *
- * Copyright: 2011-2012 Aleksey Kravchenko <rhash.admin@gmail.com>
+ * Copyright (c) 2011, Aleksey Kravchenko <rhash.admin@gmail.com>
  *
- * Permission is hereby granted,  free of charge,  to any person  obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction,  including without limitation
- * the rights to  use, copy, modify,  merge, publish, distribute, sublicense,
- * and/or sell copies  of  the Software,  and to permit  persons  to whom the
- * Software is furnished to do so.
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted.
  *
- * This program  is  distributed  in  the  hope  that it will be useful,  but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  Use this program  at  your own risk!
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE  INCLUDING ALL IMPLIED WARRANTIES OF  MERCHANTABILITY
+ * AND FITNESS.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT,  OR CONSEQUENTIAL DAMAGES  OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE,  DATA OR PROFITS,  WHETHER IN AN ACTION OF CONTRACT,  NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION,  ARISING OUT OF  OR IN CONNECTION  WITH THE USE  OR
+ * PERFORMANCE OF THIS SOFTWARE.
  */
 
 #include <stdio.h>
@@ -27,7 +27,8 @@
 #include "crc32.h"
 #include "ed2k.h"
 #include "edonr.h"
-#include "gost.h"
+#include "gost12.h"
+#include "gost94.h"
 #include "has160.h"
 #include "md4.h"
 #endif
@@ -54,18 +55,13 @@
 #else
 # define NEED_OPENSSL_INIT 0
 #endif /* USE_OPENSSL */
-#ifdef GENERATE_GOST_LOOKUP_TABLE
-# define NEED_GOST_INIT (RHASH_GOST | RHASH_GOST_CRYPTOPRO)
+#ifdef GENERATE_GOST94_LOOKUP_TABLE
+# define NEED_GOST94_INIT (RHASH_GOST94 | RHASH_GOST94_CRYPTOPRO)
 #else
-# define NEED_GOST_INIT 0
-#endif /* GENERATE_GOST_LOOKUP_TABLE */
-#ifdef GENERATE_CRC32_TABLE
-# define NEED_CRC32_INIT RHASH_CRC32
-#else
-# define NEED_CRC32_INIT 0
-#endif /* GENERATE_CRC32_TABLE */
+# define NEED_GOST94_INIT 0
+#endif /* GENERATE_GOST94_LOOKUP_TABLE */
 
-#define RHASH_NEED_INIT_ALG (NEED_CRC32_INIT | NEED_GOST_INIT | NEED_OPENSSL_INIT)
+#define RHASH_NEED_INIT_ALG (NEED_GOST94_INIT | NEED_OPENSSL_INIT)
 unsigned rhash_uninitialized_algorithms = RHASH_NEED_INIT_ALG;
 
 rhash_hash_info* rhash_info_table = rhash_hash_info_default;
@@ -75,10 +71,14 @@
 static void rhash_crc32_init(uint32_t* crc32);
 static void rhash_crc32_update(uint32_t* crc32, const unsigned char* msg, size_t size);
 static void rhash_crc32_final(uint32_t* crc32, unsigned char* result);
+static void rhash_crc32c_init(uint32_t* crc32);
+static void rhash_crc32c_update(uint32_t* crc32, const unsigned char* msg, size_t size);
+static void rhash_crc32c_final(uint32_t* crc32, unsigned char* result);
 #endif
 
 #if 0
-rhash_info info_crc32 = { RHASH_CRC32, F_BE32, 4, "CRC32", "crc32" };
+rhash_info info_crc32  = { RHASH_CRC32,  F_BE32, 4, "CRC32", "crc32" };
+rhash_info info_crc32c = { RHASH_CRC32C, F_BE32, 4, "CRC32C", "crc32c" };
 rhash_info info_md4 = { RHASH_MD4, F_LE32, 16, "MD4", "md4" };
 #endif
 rhash_info info_md5 = { RHASH_MD5, F_LE32, 16, "MD5", "md5" };
@@ -91,8 +91,10 @@
 rhash_info info_aich = { RHASH_AICH,      F_BS32, 20, "AICH", "aich" };
 rhash_info info_whirlpool = { RHASH_WHIRLPOOL, F_BE64, 64, "WHIRLPOOL", "whirlpool" };
 rhash_info info_rmd160 = { RHASH_RIPEMD160,  F_LE32, 20, "RIPEMD-160", "ripemd160" };
-rhash_info info_gost =   { RHASH_GOST,       F_LE32, 32, "GOST", "gost" };
-rhash_info info_gostpro = { RHASH_GOST_CRYPTOPRO, F_LE32, 32, "GOST-CRYPTOPRO", "gost-cryptopro" };
+rhash_info info_gost12_256 = { RHASH_GOST12_256, F_LE64, 32, "GOST12-256", "gost12-256" };
+rhash_info info_gost12_512 = { RHASH_GOST12_512, F_LE64, 64, "GOST12-512", "gost12-512" };
+rhash_info info_gost94 = { RHASH_GOST94,       F_LE32, 32, "GOST94", "gost94" };
+rhash_info info_gost94pro = { RHASH_GOST94_CRYPTOPRO, F_LE32, 32, "GOST94-CRYPTOPRO", "gost94-cryptopro" };
 rhash_info info_has160 = { RHASH_HAS160,     F_LE32, 20, "HAS-160", "has160" };
 rhash_info info_snf128 = { RHASH_SNEFRU128,  F_BE32, 16, "SNEFRU-128", "snefru128" };
 rhash_info info_snf256 = { RHASH_SNEFRU256,  F_BE32, 32, "SNEFRU-256", "snefru256" };
@@ -117,9 +119,10 @@
 #define upd(name) ((pupdate_t)(name##_update))
 #define fin(name) ((pfinal_t)(name##_final))
 #define iuf(name) ini(name), upd(name), fin(name)
+#define iuf2(name1, name2) ini(name1), upd(name2), fin(name2)
 #define diuf(name) dgshft(name), ini(name), upd(name), fin(name)
 
-/* information about all hashes */
+/* information about all supported hash functions */
 rhash_hash_info rhash_hash_info_default[RHASH_HASH_COUNT] =
 {
 #if 0
@@ -135,28 +138,35 @@
 	{ &info_aich, sizeof(aich_ctx), dgshft2(aich, sha1_context.hash), iuf(rhash_aich), (pcleanup_t)rhash_aich_cleanup }, /* 160 bit */
 	{ &info_whirlpool, sizeof(whirlpool_ctx), dgshft(whirlpool), iuf(rhash_whirlpool), 0 }, /* 512 bit */
 	{ &info_rmd160, sizeof(ripemd160_ctx), dgshft(ripemd160), iuf(rhash_ripemd160), 0 }, /* 160 bit */
-	{ &info_gost, sizeof(gost_ctx), dgshft(gost), iuf(rhash_gost), 0 }, /* 256 bit */
-	{ &info_gostpro, sizeof(gost_ctx), dgshft(gost), ini(rhash_gost_cryptopro), upd(rhash_gost), fin(rhash_gost), 0 }, /* 256 bit */
+	{ &info_gost94, sizeof(gost94_ctx), dgshft(gost94), iuf(rhash_gost94), 0 }, /* 256 bit */
+	{ &info_gost94pro, sizeof(gost94_ctx), dgshft(gost94), iuf2(rhash_gost94_cryptopro, rhash_gost94), 0 }, /* 256 bit */
 	{ &info_has160, sizeof(has160_ctx), dgshft(has160), iuf(rhash_has160), 0 }, /* 160 bit */
-	{ &info_snf128, sizeof(snefru_ctx), dgshft(snefru), ini(rhash_snefru128), upd(rhash_snefru), fin(rhash_snefru), 0 }, /* 128 bit */
-	{ &info_snf256, sizeof(snefru_ctx), dgshft(snefru), ini(rhash_snefru256), upd(rhash_snefru), fin(rhash_snefru), 0 }, /* 256 bit */
+	{ &info_gost12_256, sizeof(gost12_ctx), dgshft2(gost12, h) + 32, iuf2(rhash_gost12_256, rhash_gost12), 0 }, /* 256 bit */
+	{ &info_gost12_512, sizeof(gost12_ctx), dgshft2(gost12, h), iuf2(rhash_gost12_512, rhash_gost12), 0 }, /* 512 bit */
 #endif
-	{ &info_sha224, sizeof(sha256_ctx), dgshft(sha256), ini(rhash_sha224), upd(rhash_sha256), fin(rhash_sha256), 0 }, /* 224 bit */
+	{ &info_sha224, sizeof(sha256_ctx), dgshft(sha256), iuf2(rhash_sha224, rhash_sha256), 0 }, /* 224 bit */
 	{ &info_sha256, sizeof(sha256_ctx), dgshft(sha256), iuf(rhash_sha256), 0 },  /* 256 bit */
-	{ &info_sha384, sizeof(sha512_ctx), dgshft(sha512), ini(rhash_sha384), upd(rhash_sha512), fin(rhash_sha512), 0 }, /* 384 bit */
+	{ &info_sha384, sizeof(sha512_ctx), dgshft(sha512), iuf2(rhash_sha384, rhash_sha512), 0 }, /* 384 bit */
 	{ &info_sha512, sizeof(sha512_ctx), dgshft(sha512), iuf(rhash_sha512), 0 },  /* 512 bit */
 #if 0
-	{ &info_edr256, sizeof(edonr_ctx), dgshft2(edonr, u.data256.hash) + 32, iuf(rhash_edonr256), 0 },  /* 256 bit */
-	{ &info_edr512, sizeof(edonr_ctx), dgshft2(edonr, u.data512.hash) + 64, iuf(rhash_edonr512), 0 },  /* 512 bit */
+	{ &info_edr256, sizeof(edonr_ctx),  dgshft2(edonr, u.data256.hash) + 32, iuf(rhash_edonr256), 0 },  /* 256 bit */
+	{ &info_edr512, sizeof(edonr_ctx),  dgshft2(edonr, u.data512.hash) + 64, iuf(rhash_edonr512), 0 },  /* 512 bit */
 #endif
-	{ &info_sha3_224, sizeof(sha3_ctx), dgshft(sha3), ini(rhash_sha3_224), upd(rhash_sha3), fin(rhash_sha3), 0 }, /* 224 bit */
-	{ &info_sha3_256, sizeof(sha3_ctx), dgshft(sha3), ini(rhash_sha3_256), upd(rhash_sha3), fin(rhash_sha3), 0 }, /* 256 bit */
-	{ &info_sha3_384, sizeof(sha3_ctx), dgshft(sha3), ini(rhash_sha3_384), upd(rhash_sha3), fin(rhash_sha3), 0 }, /* 384 bit */
-	{ &info_sha3_512, sizeof(sha3_ctx), dgshft(sha3), ini(rhash_sha3_512), upd(rhash_sha3), fin(rhash_sha3), 0 }, /* 512 bit */
+	{ &info_sha3_224, sizeof(sha3_ctx), dgshft(sha3), iuf2(rhash_sha3_224, rhash_sha3), 0 }, /* 224 bit */
+	{ &info_sha3_256, sizeof(sha3_ctx), dgshft(sha3), iuf2(rhash_sha3_256, rhash_sha3), 0 }, /* 256 bit */
+	{ &info_sha3_384, sizeof(sha3_ctx), dgshft(sha3), iuf2(rhash_sha3_384, rhash_sha3), 0 }, /* 384 bit */
+	{ &info_sha3_512, sizeof(sha3_ctx), dgshft(sha3), iuf2(rhash_sha3_512, rhash_sha3), 0 }, /* 512 bit */
+#if 0
+	{ &info_crc32c, sizeof(uint32_t), 0, iuf(rhash_crc32c), 0 }, /* 32 bit */
+	{ &info_snf128, sizeof(snefru_ctx), dgshft(snefru), iuf2(rhash_snefru128, rhash_snefru), 0 }, /* 128 bit */
+	{ &info_snf256, sizeof(snefru_ctx), dgshft(snefru), iuf2(rhash_snefru256, rhash_snefru), 0 }, /* 256 bit */
+#endif
 };
 
 /**
  * Initialize requested algorithms.
+ *
+ * @param mask ids of hash sums to initialize
  */
 void rhash_init_algorithms(unsigned mask)
 {
@@ -165,15 +175,26 @@
 	/* verify that RHASH_HASH_COUNT is the index of the major bit of RHASH_ALL_HASHES */
 	assert(1 == (RHASH_ALL_HASHES >> (RHASH_HASH_COUNT - 1)));
 
-#ifdef GENERATE_CRC32_TABLE
-	rhash_crc32_init_table();
-#endif
-#ifdef GENERATE_GOST_LOOKUP_TABLE
-	rhash_gost_init_table();
+#ifdef GENERATE_GOST94_LOOKUP_TABLE
+	rhash_gost94_init_table();
 #endif
 	rhash_uninitialized_algorithms = 0;
 }
 
+/**
+ * Returns information about a hash function by its hash_id.
+ *
+ * @param hash_id the id of hash algorithm
+ * @return pointer to the rhash_info structure containing the information
+ */
+const rhash_info* rhash_info_by_id(unsigned hash_id)
+{
+	hash_id &= RHASH_ALL_HASHES;
+	/* check that one and only one bit is set */
+	if (!hash_id || (hash_id & (hash_id - 1)) != 0) return NULL;
+	return rhash_info_table[rhash_ctz(hash_id)].info;
+}
+
 #if 0
 /* CRC32 helper functions */
 
@@ -217,4 +238,45 @@
 	result[2] = (unsigned char)(*crc32 >> 8), result[3] = (unsigned char)(*crc32);
 #endif
 }
+
+/**
+ * Initialize crc32c hash.
+ *
+ * @param crc32c pointer to the hash to initialize
+ */
+static void rhash_crc32c_init(uint32_t* crc32c)
+{
+	*crc32c = 0; /* note: context size is sizeof(uint32_t) */
+}
+
+/**
+ * Calculate message CRC32C hash.
+ * Can be called repeatedly with chunks of the message to be hashed.
+ *
+ * @param crc32c pointer to the hash
+ * @param msg message chunk
+ * @param size length of the message chunk
+ */
+static void rhash_crc32c_update(uint32_t* crc32c, const unsigned char* msg, size_t size)
+{
+	*crc32c = rhash_get_crc32c(*crc32c, msg, size);
+}
+
+/**
+ * Store calculated hash into the given array.
+ *
+ * @param crc32c pointer to the current hash value
+ * @param result calculated hash in binary form
+ */
+static void rhash_crc32c_final(uint32_t* crc32c, unsigned char* result)
+{
+#if defined(CPU_IA32) || defined(CPU_X64)
+	/* intel CPUs support assigment with non 32-bit aligned pointers */
+	*(unsigned*)result = be2me_32(*crc32c);
+#else
+	/* correct saving BigEndian integer on all archs */
+	result[0] = (unsigned char)(*crc32c >> 24), result[1] = (unsigned char)(*crc32c >> 16);
+	result[2] = (unsigned char)(*crc32c >> 8), result[3] = (unsigned char)(*crc32c);
+#endif
+}
 #endif
diff --git a/Utilities/cmlibrhash/librhash/algorithms.h b/Utilities/cmlibrhash/librhash/algorithms.h
index 4db2517..01dda88 100644
--- a/Utilities/cmlibrhash/librhash/algorithms.h
+++ b/Utilities/cmlibrhash/librhash/algorithms.h
@@ -2,9 +2,9 @@
 #ifndef RHASH_ALGORITHMS_H
 #define RHASH_ALGORITHMS_H
 
-#include <stddef.h> /* for ptrdiff_t */
 #include "rhash.h"
 #include "byte_order.h"
+#include <stddef.h>
 
 #ifdef __cplusplus
 extern "C" {
@@ -15,8 +15,40 @@
 # define RHASH_API
 #endif
 
+/**
+ * Bit flag: default hash output format is base32.
+ */
+#define RHASH_INFO_BASE32 1
+
+/**
+ * Information about a hash function.
+ */
+typedef struct rhash_info
+{
+	/**
+	 * Hash function indentifier.
+	 */
+	unsigned hash_id;
+	/**
+	 * Flags bit-mask, including RHASH_INFO_BASE32 bit.
+	 */
+	unsigned flags;
+	/**
+	 The size of of the raw message digest in bytes.
+	 */
+	size_t digest_size;
+	/**
+	 * The hash function name.
+	 */
+	const char* name;
+	/**
+	 * The corresponding paramenter name in a magnet link.
+	 */
+	const char* magnet_name;
+} rhash_info;
+
 typedef void (*pinit_t)(void*);
-typedef void (*pupdate_t)(void *ctx, const void* msg, size_t size);
+typedef void (*pupdate_t)(void* ctx, const void* msg, size_t size);
 typedef void (*pfinal_t)(void*, unsigned char*);
 typedef void (*pcleanup_t)(void*);
 
@@ -25,7 +57,7 @@
  */
 typedef struct rhash_hash_info
 {
-	rhash_info *info;
+	rhash_info* info;
 	size_t context_size;
 	ptrdiff_t  digest_diff;
 	pinit_t    init;
@@ -40,7 +72,7 @@
 typedef struct rhash_vector_item
 {
 	struct rhash_hash_info* hash_info;
-	void *context;
+	void* context;
 } rhash_vector_item;
 
 /**
@@ -52,8 +84,9 @@
 	unsigned hash_vector_size; /* number of contained hash sums */
 	unsigned flags;
 	unsigned state;
-	void *callback, *callback_data;
-	void *bt_ctx;
+	void* callback;
+	void* callback_data;
+	void* bt_ctx;
 	rhash_vector_item vector[1]; /* contexts of contained hash sums */
 } rhash_context_ext;
 
@@ -63,6 +96,7 @@
 extern unsigned rhash_uninitialized_algorithms;
 
 extern rhash_info info_crc32;
+extern rhash_info info_crc32c;
 extern rhash_info info_md4;
 extern rhash_info info_md5;
 extern rhash_info info_sha1;
@@ -95,7 +129,7 @@
 #define F_SWAP64 4
 
 /* define endianness flags */
-#ifndef CPU_BIG_ENDIAN
+#if IS_LITTLE_ENDIAN
 #define F_LE32 0
 #define F_LE64 0
 #define F_BE32 F_SWAP32
@@ -108,6 +142,7 @@
 #endif
 
 void rhash_init_algorithms(unsigned mask);
+const rhash_info* rhash_info_by_id(unsigned hash_id); /* get hash sum info by hash id */
 
 #if defined(OPENSSL_RUNTIME) && !defined(USE_OPENSSL)
 # define USE_OPENSSL
diff --git a/Utilities/cmlibrhash/librhash/byte_order.c b/Utilities/cmlibrhash/librhash/byte_order.c
index 8ce6fc8..de2c583 100644
--- a/Utilities/cmlibrhash/librhash/byte_order.c
+++ b/Utilities/cmlibrhash/librhash/byte_order.c
@@ -1,21 +1,21 @@
 /* byte_order.c - byte order related platform dependent routines,
  *
- * Copyright: 2008-2012 Aleksey Kravchenko <rhash.admin@gmail.com>
+ * Copyright (c) 2008, Aleksey Kravchenko <rhash.admin@gmail.com>
  *
- * Permission is hereby granted,  free of charge,  to any person  obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction,  including without limitation
- * the rights to  use, copy, modify,  merge, publish, distribute, sublicense,
- * and/or sell copies  of  the Software,  and to permit  persons  to whom the
- * Software is furnished to do so.
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted.
  *
- * This program  is  distributed  in  the  hope  that it will be useful,  but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  Use this program  at  your own risk!
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE  INCLUDING ALL IMPLIED WARRANTIES OF  MERCHANTABILITY
+ * AND FITNESS.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT,  OR CONSEQUENTIAL DAMAGES  OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE,  DATA OR PROFITS,  WHETHER IN AN ACTION OF CONTRACT,  NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION,  ARISING OUT OF  OR IN CONNECTION  WITH THE USE  OR
+ * PERFORMANCE OF THIS SOFTWARE.
  */
 #include "byte_order.h"
 
-#if !(__GNUC__ >= 4 || (__GNUC__ ==3 && __GNUC_MINOR__ >= 4)) /* if !GCC or GCC < 4.3 */
+#ifndef rhash_ctz
 
 #  if _MSC_VER >= 1300 && (_M_IX86 || _M_AMD64 || _M_IA64) /* if MSVC++ >= 2002 on x86/x64 */
 #  include <intrin.h>
@@ -59,7 +59,7 @@
 	return (unsigned)bit_pos[((uint32_t)((x & -x) * 0x077CB531U)) >> 27];
 }
 #  endif /* _MSC_VER >= 1300... */
-#endif /* !(GCC >= 4.3) */
+#endif /* rhash_ctz */
 
 /**
  * Copy a memory block with simultaneous exchanging byte order.
@@ -79,10 +79,12 @@
 		const uint32_t* src = (const uint32_t*)from;
 		const uint32_t* end = (const uint32_t*)((const char*)src + length);
 		uint32_t* dst = (uint32_t*)((char*)to + index);
-		while (src < end) *(dst++) = bswap_32( *(src++) );
+		for (; src < end; dst++, src++)
+			*dst = bswap_32(*src);
 	} else {
 		const char* src = (const char*)from;
-		for (length += index; (size_t)index < length; index++) ((char*)to)[index ^ 3] = *(src++);
+		for (length += index; (size_t)index < length; index++)
+			((char*)to)[index ^ 3] = *(src++);
 	}
 }
 
@@ -141,10 +143,31 @@
  * @param arr    the array to process
  * @param length array length
  */
-void rhash_u32_mem_swap(unsigned *arr, int length)
+void rhash_u32_mem_swap(unsigned* arr, int length)
 {
 	unsigned* end = arr + length;
 	for (; arr < end; arr++) {
 		*arr = bswap_32(*arr);
 	}
 }
+
+#ifdef HAS_INTEL_CPUID
+#include <cpuid.h>
+
+static uint64_t get_cpuid_features(void)
+{
+	uint32_t tmp, edx, ecx;
+	if (__get_cpuid(1, &tmp, &tmp, &ecx, &edx))
+		return ((((uint64_t)ecx) << 32) ^ edx);
+	return 0;
+}
+
+int has_cpu_feature(unsigned feature_bit)
+{
+	static uint64_t features;
+	const uint64_t feature = ((uint64_t)1) << feature_bit;
+	if (!features)
+		features = (get_cpuid_features() | 1);
+	return !!(features & feature);
+}
+#endif
diff --git a/Utilities/cmlibrhash/librhash/byte_order.h b/Utilities/cmlibrhash/librhash/byte_order.h
index d34a020..cfb9e25 100644
--- a/Utilities/cmlibrhash/librhash/byte_order.h
+++ b/Utilities/cmlibrhash/librhash/byte_order.h
@@ -4,6 +4,19 @@
 #include "ustd.h"
 #include <stdlib.h>
 
+#if 0
+#if defined(__GLIBC__)
+# include <endian.h>
+#endif
+#endif
+
+#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
+# include <sys/types.h>
+#elif defined (__NetBSD__) || defined(__OpenBSD__)
+# include <sys/param.h>
+#endif
+
+
 #ifdef __cplusplus
 extern "C" {
 #endif
@@ -26,9 +39,7 @@
 # endif
 #endif
 
-
-/* detect CPU endianness */
-#include <cm_kwiml.h>
+#include <cm3p/kwiml/abi.h>
 #if KWIML_ABI_ENDIAN_ID == KWIML_ABI_ENDIAN_ID_LITTLE
 # define CPU_LITTLE_ENDIAN
 # define IS_BIG_ENDIAN 0
@@ -37,8 +48,53 @@
 # define CPU_BIG_ENDIAN
 # define IS_BIG_ENDIAN 1
 # define IS_LITTLE_ENDIAN 0
+#endif
+
+#if 0
+#define RHASH_BYTE_ORDER_LE 1234
+#define RHASH_BYTE_ORDER_BE 4321
+
+#if (defined(__BYTE_ORDER) && defined(__LITTLE_ENDIAN) && __BYTE_ORDER == __LITTLE_ENDIAN) || \
+    (defined(__BYTE_ORDER__) && defined(__ORDER_LITTLE_ENDIAN__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)
+#  define RHASH_BYTE_ORDER RHASH_BYTE_ORDER_LE
+#elif (defined(__BYTE_ORDER) && defined(__BIG_ENDIAN) && __BYTE_ORDER == __BIG_ENDIAN) || \
+      (defined(__BYTE_ORDER__) && defined(__ORDER_BIG_ENDIAN__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)
+#  define RHASH_BYTE_ORDER RHASH_BYTE_ORDER_BE
+#elif defined(_BYTE_ORDER)
+#  if defined(_LITTLE_ENDIAN) && (_BYTE_ORDER == _LITTLE_ENDIAN)
+#    define RHASH_BYTE_ORDER RHASH_BYTE_ORDER_LE
+#  elif defined(_BIG_ENDIAN) && (_BYTE_ORDER == _BIG_ENDIAN)
+#    define RHASH_BYTE_ORDER RHASH_BYTE_ORDER_BE
+#  endif
+#elif defined(__sun) && defined(_LITTLE_ENDIAN)
+#  define RHASH_BYTE_ORDER RHASH_BYTE_ORDER_LE
+#elif defined(__sun) && defined(_BIG_ENDIAN)
+#  define RHASH_BYTE_ORDER RHASH_BYTE_ORDER_BE
+#endif
+
+/* try detecting endianness by CPU */
+#ifdef RHASH_BYTE_ORDER
+#elif defined(CPU_IA32) || defined(CPU_X64) || defined(__ia64) || defined(__ia64__) || \
+      defined(__alpha__) || defined(_M_ALPHA) || defined(vax) || defined(MIPSEL) || \
+      defined(_ARM_) || defined(__arm__)
+#  define RHASH_BYTE_ORDER RHASH_BYTE_ORDER_LE
+#elif defined(__sparc) || defined(__sparc__) || defined(sparc) || \
+      defined(_ARCH_PPC) || defined(_ARCH_PPC64) || defined(_POWER) || \
+      defined(__POWERPC__) || defined(POWERPC) || defined(__powerpc) || \
+      defined(__powerpc__) || defined(__powerpc64__) || defined(__ppc__) || \
+      defined(__hpux)  || defined(_MIPSEB) || defined(mc68000) || \
+      defined(__s390__) || defined(__s390x__) || defined(sel)
+# define RHASH_BYTE_ORDER RHASH_BYTE_ORDER_BE
 #else
-# error "Can't detect CPU architechture"
+#  error "Can't detect CPU architechture"
+#endif
+
+#define IS_BIG_ENDIAN (RHASH_BYTE_ORDER == RHASH_BYTE_ORDER_BE)
+#define IS_LITTLE_ENDIAN (RHASH_BYTE_ORDER == RHASH_BYTE_ORDER_LE)
+#endif
+
+#ifndef __has_builtin
+# define __has_builtin(x) 0
 #endif
 
 #define IS_ALIGNED_32(p) (0 == (3 & ((const char*)(p) - (const char*)0)))
@@ -56,11 +112,23 @@
 #if defined(_MSC_VER) || defined(__BORLANDC__)
 #define I64(x) x##ui64
 #else
-#define I64(x) x##LL
+#define I64(x) x##ULL
 #endif
 
-/* convert a hash flag to index */
-#if __GNUC__ >= 4 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) /* GCC < 3.4 */
+#if defined(_MSC_VER)
+#define RHASH_INLINE __inline
+#elif defined(__GNUC__) && !defined(__STRICT_ANSI__)
+#define RHASH_INLINE inline
+#elif defined(__GNUC__)
+#define RHASH_INLINE __inline__
+#else
+#define RHASH_INLINE
+#endif
+
+/* define rhash_ctz - count traling zero bits */
+#if (defined(__GNUC__) && __GNUC__ >= 4 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)) || \
+    (defined(__clang__) && __has_builtin(__builtin_ctz))
+/* GCC >= 3.4 or clang */
 # define rhash_ctz(x) __builtin_ctz(x)
 #else
 unsigned rhash_ctz(unsigned); /* define as function */
@@ -69,42 +137,31 @@
 void rhash_swap_copy_str_to_u32(void* to, int index, const void* from, size_t length);
 void rhash_swap_copy_str_to_u64(void* to, int index, const void* from, size_t length);
 void rhash_swap_copy_u64_to_str(void* to, const void* from, size_t length);
-void rhash_u32_mem_swap(unsigned *p, int length_in_u32);
+void rhash_u32_mem_swap(unsigned* p, int length_in_u32);
 
-#ifndef __has_builtin
-# define __has_builtin(x) 0
-#endif
-
-/* define bswap_32 */
-#if defined(__GNUC__) && defined(CPU_IA32) && !defined(__i386__)
-/* for intel x86 CPU */
-static inline uint32_t bswap_32(uint32_t x) {
-	__asm("bswap\t%0" : "=r" (x) : "0" (x));
-	return x;
-}
-#elif defined(__GNUC__)  && (__GNUC__ >= 4) && (__GNUC__ > 4 || __GNUC_MINOR__ >= 3)
-/* for GCC >= 4.3 */
+/* bswap definitions */
+#if (defined(__GNUC__) && (__GNUC__ >= 4) && (__GNUC__ > 4 || __GNUC_MINOR__ >= 3)) || \
+    (defined(__clang__) && __has_builtin(__builtin_bswap32) && __has_builtin(__builtin_bswap64))
+/* GCC >= 4.3 or clang */
 # define bswap_32(x) __builtin_bswap32(x)
-#elif defined(__clang__) && __has_builtin(__builtin_bswap32)
-# define bswap_32(x) __builtin_bswap32(x)
+# define bswap_64(x) __builtin_bswap64(x)
 #elif (_MSC_VER > 1300) && (defined(CPU_IA32) || defined(CPU_X64)) /* MS VC */
 # define bswap_32(x) _byteswap_ulong((unsigned long)x)
-#else
-/* general bswap_32 definition */
-static uint32_t bswap_32(uint32_t x) {
-	x = ((x << 8) & 0xFF00FF00) | ((x >> 8) & 0x00FF00FF);
-	return (x >> 16) | (x << 16);
-}
-#endif /* bswap_32 */
-
-#if defined(__GNUC__) && (__GNUC__ >= 4) && (__GNUC__ > 4 || __GNUC_MINOR__ >= 3)
-# define bswap_64(x) __builtin_bswap64(x)
-#elif defined(__clang__) && __has_builtin(__builtin_bswap64)
-# define bswap_64(x) __builtin_bswap64(x)
-#elif (_MSC_VER > 1300) && (defined(CPU_IA32) || defined(CPU_X64)) /* MS VC */
 # define bswap_64(x) _byteswap_uint64((__int64)x)
 #else
-static uint64_t bswap_64(uint64_t x) {
+/* fallback to generic bswap definition */
+static RHASH_INLINE uint32_t bswap_32(uint32_t x)
+{
+# if defined(__GNUC__) && defined(CPU_IA32) && !defined(__i386__) && !defined(RHASH_NO_ASM)
+	__asm("bswap\t%0" : "=r" (x) : "0" (x)); /* gcc x86 version */
+	return x;
+# else
+	x = ((x << 8) & 0xFF00FF00u) | ((x >> 8) & 0x00FF00FFu);
+	return (x >> 16) | (x << 16);
+# endif
+}
+static RHASH_INLINE uint64_t bswap_64(uint64_t x)
+{
 	union {
 		uint64_t ll;
 		uint32_t l[2];
@@ -114,9 +171,9 @@
 	r.l[1] = bswap_32(w.l[0]);
 	return r.ll;
 }
-#endif
+#endif /* bswap definitions */
 
-#ifdef CPU_BIG_ENDIAN
+#if IS_BIG_ENDIAN
 # define be2me_32(x) (x)
 # define be2me_64(x) (x)
 # define le2me_32(x) bswap_32(x)
@@ -129,7 +186,7 @@
 # define me64_to_be_str(to, from, length) memcpy((to), (from), (length))
 # define me64_to_le_str(to, from, length) rhash_swap_copy_u64_to_str((to), (from), (length))
 
-#else /* CPU_BIG_ENDIAN */
+#else /* IS_BIG_ENDIAN */
 # define be2me_32(x) bswap_32(x)
 # define be2me_64(x) bswap_64(x)
 # define le2me_32(x) (x)
@@ -141,7 +198,7 @@
 # define le64_copy(to, index, from, length) memcpy((to) + (index), (from), (length))
 # define me64_to_be_str(to, from, length) rhash_swap_copy_u64_to_str((to), (from), (length))
 # define me64_to_le_str(to, from, length) memcpy((to), (from), (length))
-#endif /* CPU_BIG_ENDIAN */
+#endif /* IS_BIG_ENDIAN */
 
 /* ROTL/ROTR macros rotate a 32/64-bit word left/right by n bits */
 #define ROTL32(dword, n) ((dword) << (n) ^ ((dword) >> (32 - (n))))
@@ -149,6 +206,16 @@
 #define ROTL64(qword, n) ((qword) << (n) ^ ((qword) >> (64 - (n))))
 #define ROTR64(qword, n) ((qword) >> (n) ^ ((qword) << (64 - (n))))
 
+#define CPU_FEATURE_SSE4_2 (52)
+
+#if defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)) \
+	&& (defined(CPU_X64) || defined(CPU_IA32))
+# define HAS_INTEL_CPUID
+int has_cpu_feature(unsigned feature_bit);
+#else
+# define has_cpu_feature(x) (0)
+#endif
+
 #ifdef __cplusplus
 } /* extern "C" */
 #endif /* __cplusplus */
diff --git a/Utilities/cmlibrhash/librhash/hex.c b/Utilities/cmlibrhash/librhash/hex.c
index c941149..f0bbf04 100644
--- a/Utilities/cmlibrhash/librhash/hex.c
+++ b/Utilities/cmlibrhash/librhash/hex.c
@@ -1,71 +1,57 @@
 /* hex.c - conversion for hexadecimal and base32 strings.
  *
- * Copyright: 2008-2012 Aleksey Kravchenko <rhash.admin@gmail.com>
+ * Copyright (c) 2008, Aleksey Kravchenko <rhash.admin@gmail.com>
  *
- * Permission is hereby granted,  free of charge,  to any person  obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction,  including without limitation
- * the rights to  use, copy, modify,  merge, publish, distribute, sublicense,
- * and/or sell copies  of  the Software,  and to permit  persons  to whom the
- * Software is furnished to do so.
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted.
  *
- * This program  is  distributed  in  the  hope  that it will be useful,  but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  Use this program  at  your own risk!
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE  INCLUDING ALL IMPLIED WARRANTIES OF  MERCHANTABILITY
+ * AND FITNESS.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT,  OR CONSEQUENTIAL DAMAGES  OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE,  DATA OR PROFITS,  WHETHER IN AN ACTION OF CONTRACT,  NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION,  ARISING OUT OF  OR IN CONNECTION  WITH THE USE  OR
+ * PERFORMANCE OF THIS SOFTWARE.
  */
-#include <string.h>
-#include <ctype.h>
 #include "hex.h"
-
-/**
-* Convert a byte to a hexadecimal number. The result, consisting of two
-* hexadecimal digits is stored into a buffer.
- *
- * @param dest  the buffer to receive two symbols of hex representation
- * @param byte the byte to decode
- * @param upper_case flag to print string in uppercase
- * @return pointer to the chararcter just after the written number (dest + 2)
- */
-char* rhash_print_hex_byte(char *dest, const unsigned char byte, int upper_case)
-{
-	const char add = (upper_case ? 'A' - 10 : 'a' - 10);
-	unsigned char c = (byte >> 4) & 15;
-	*dest++ = (c > 9 ? c + add : c + '0');
-	c = byte & 15;
-	*dest++ = (c > 9 ? c + add : c + '0');
-	return dest;
-}
+#include <assert.h>
+#include <ctype.h>
+#include <string.h>
 
 /**
  * Store hexadecimal representation of a binary string to given buffer.
  *
- * @param dest the buffer to receive hexadecimal representation
+ * @param dst the buffer to receive hexadecimal representation
  * @param src binary string
- * @param len string length
+ * @param length string length
  * @param upper_case flag to print string in uppercase
  */
-void rhash_byte_to_hex(char *dest, const unsigned char *src, unsigned len, int upper_case)
+void rhash_byte_to_hex(char* dst, const unsigned char* src, size_t length, int upper_case)
 {
-	while (len-- > 0) {
-		dest = rhash_print_hex_byte(dest, *src++, upper_case);
+	const char hex_add = (upper_case ? 'A' - 10 : 'a' - 10);
+	for (; length > 0; src++, length--) {
+		const unsigned char hi = (*src >> 4) & 15;
+		const unsigned char lo = *src & 15;
+		*dst++ = (hi > 9 ? hi + hex_add : hi + '0');
+		*dst++ = (lo > 9 ? lo + hex_add : lo + '0');
 	}
-	*dest = '\0';
+	*dst = '\0';
 }
 
 /**
  * Encode a binary string to base32.
  *
- * @param dest the buffer to store result
+ * @param dst the buffer to store result
  * @param src binary string
- * @param len string length
+ * @param length string length
  * @param upper_case flag to print string in uppercase
  */
-void rhash_byte_to_base32(char* dest, const unsigned char* src, unsigned len, int upper_case)
+void rhash_byte_to_base32(char* dst, const unsigned char* src, size_t length, int upper_case)
 {
 	const char a = (upper_case ? 'A' : 'a');
 	unsigned shift = 0;
 	unsigned char word;
-	const unsigned char* e = src + len;
+	const unsigned char* e = src + length;
 	while (src < e) {
 		if (shift > 3) {
 			word = (*src & (0xFF >> shift));
@@ -79,25 +65,25 @@
 			word = ( *src >> ( (8 - shift) & 7 ) ) & 0x1F;
 			if (shift == 0) src++;
 		}
-		*dest++ = ( word < 26 ? word + a : word + '2' - 26 );
+		*dst++ = ( word < 26 ? word + a : word + '2' - 26 );
 	}
-	*dest = '\0';
+	*dst = '\0';
 }
 
 /**
  * Encode a binary string to base64.
  * Encoded output length is always a multiple of 4 bytes.
  *
- * @param dest the buffer to store result
+ * @param dst the buffer to store result
  * @param src binary string
- * @param len string length
+ * @param length string length
  */
-void rhash_byte_to_base64(char* dest, const unsigned char* src, unsigned len)
+void rhash_byte_to_base64(char* dst, const unsigned char* src, size_t length)
 {
 	static const char* tail = "0123456789+/";
 	unsigned shift = 0;
 	unsigned char word;
-	const unsigned char* e = src + len;
+	const unsigned char* e = src + length;
 	while (src < e) {
 		if (shift > 2) {
 			word = (*src & (0xFF >> shift));
@@ -111,45 +97,80 @@
 			word = ( *src >> ( (8 - shift) & 7 ) ) & 0x3F;
 			if (shift == 0) src++;
 		}
-		*dest++ = ( word < 52 ? (word < 26 ? word + 'A' : word - 26 + 'a') : tail[word - 52]);
+		*dst++ = ( word < 52 ? (word < 26 ? word + 'A' : word - 26 + 'a') : tail[word - 52]);
 	}
 	if (shift > 0) {
-		*dest++ = '=';
-		if (shift == 4) *dest++ = '=';
+		*dst++ = '=';
+		if (shift == 4) *dst++ = '=';
 	}
-	*dest = '\0';
+	*dst = '\0';
 }
 
-/* unsafe characters are "<>{}[]%#/|\^~`@:;?=&+ */
-#define IS_GOOD_URL_CHAR(c) (isalnum((unsigned char)c) || strchr("$-_.!'(),", c))
+size_t rhash_base64_url_encoded_helper(char* dst, const unsigned char* src, size_t length, int url_encode, int upper_case)
+{
+#define B64_CHUNK_SIZE 120
+	char buffer[164];
+	assert((BASE64_LENGTH(B64_CHUNK_SIZE) + 4) <= sizeof(buffer));
+	assert((B64_CHUNK_SIZE % 6) == 0);
+	if (url_encode) {
+		size_t result_length = 0;
+		for (; length > 0; src += B64_CHUNK_SIZE) {
+			size_t chunk_size = (length < B64_CHUNK_SIZE ? length : B64_CHUNK_SIZE);
+			size_t encoded_length;
+			rhash_byte_to_base64(buffer, src, chunk_size);
+			encoded_length = rhash_urlencode(dst, buffer, BASE64_LENGTH(chunk_size), upper_case);
+			result_length += encoded_length;
+			dst += encoded_length;
+			length -= chunk_size;
+		}
+		return result_length;
+	}
+	rhash_byte_to_base64(dst, src, length);
+	return BASE64_LENGTH(length);
+}
+
+/* RFC 3986: safe url characters are ascii alpha-numeric and "-._~", other characters should be percent-encoded */
+static unsigned url_safe_char_mask[4] = { 0, 0x03ff6000, 0x87fffffe, 0x47fffffe };
+#define IS_URL_GOOD_CHAR(c) ((unsigned)(c) < 128 && (url_safe_char_mask[c >> 5] & (1 << (c & 31))))
 
 /**
- * URL-encode a string.
+ * URL-encode specified binary string.
  *
- * @param dst buffer to receive result or NULL to calculate
- *    the lengths of encoded string
- * @param filename the file name
+ * @param dst (nullable) buffer to output encoded string to,
+ *            NULL to just calculate the lengths of encoded string
+ * @param src binary string to encode
+ * @param size size of the binary string
+ * @param upper_case flag to output hex-codes in uppercase
  * @return the length of the result string
  */
-int rhash_urlencode(char *dst, const char *name)
+size_t rhash_urlencode(char* dst, const char* src, size_t size, int upper_case)
 {
-	const char *start;
+	const char* start;
+	size_t i;
 	if (!dst) {
-		int len;
-		for (len = 0; *name; name++) len += (IS_GOOD_URL_CHAR(*name) ? 1 : 3);
-		return len;
-	}
-	/* encode URL as specified by RFC 1738 */
-	for (start = dst; *name; name++) {
-		if ( IS_GOOD_URL_CHAR(*name) ) {
-			*dst++ = *name;
-		} else {
-			*dst++ = '%';
-			dst = rhash_print_hex_byte(dst, *name, 'A');
+		size_t length = size;
+		for (i = 0; i < size; i++)
+			if (!IS_URL_GOOD_CHAR(src[i]))
+				length += 2;
+		return length;
+	} else {
+		const char hex_add = (upper_case ? 'A' - 10 : 'a' - 10);
+		start = dst;
+		/* percent-encode all but unreserved URL characters */
+		for (i = 0; i < size; i++) {
+			if (IS_URL_GOOD_CHAR(src[i])) {
+				*dst++ = src[i];
+			} else {
+				unsigned char hi = ((unsigned char)(src[i]) >> 4) & 0x0f;
+				unsigned char lo = (unsigned char)(src[i]) & 0x0f;
+				*dst++ = '%';
+				*dst++ = (hi > 9 ? hi + hex_add : hi + '0');
+				*dst++ = (lo > 9 ? lo + hex_add : lo + '0');
+			}
 		}
+		*dst = 0;
 	}
-	*dst = 0;
-	return (int)(dst - start);
+	return dst - start;
 }
 
 /**
@@ -160,10 +181,11 @@
  * @param number the number to print
  * @return length of the printed number (without trailing '\0')
  */
-int rhash_sprintI64(char *dst, uint64_t number)
+int rhash_sprintI64(char* dst, uint64_t number)
 {
 	/* The biggest number has 20 digits: 2^64 = 18 446 744 073 709 551 616 */
-	char buf[24], *p;
+	char buf[24];
+	char* p;
 	size_t length;
 
 	if (dst == NULL) {
diff --git a/Utilities/cmlibrhash/librhash/hex.h b/Utilities/cmlibrhash/librhash/hex.h
index 2b365e2..6bea036 100644
--- a/Utilities/cmlibrhash/librhash/hex.h
+++ b/Utilities/cmlibrhash/librhash/hex.h
@@ -8,12 +8,13 @@
 extern "C" {
 #endif
 
-void rhash_byte_to_hex(char *dest, const unsigned char *src, unsigned len, int upper_case);
-void rhash_byte_to_base32(char* dest, const unsigned char* src, unsigned len, int upper_case);
-void rhash_byte_to_base64(char* dest, const unsigned char* src, unsigned len);
-char* rhash_print_hex_byte(char *dest, const unsigned char byte, int upper_case);
-int  rhash_urlencode(char *dst, const char *name);
-int  rhash_sprintI64(char *dst, uint64_t number);
+void rhash_byte_to_hex(char* dest, const unsigned char* src, size_t length, int upper_case);
+void rhash_byte_to_base32(char* dest, const unsigned char* src, size_t length, int upper_case);
+void rhash_byte_to_base64(char* dest, const unsigned char* src, size_t length);
+char* rhash_print_hex_byte(char* dest, const unsigned char byte, int upper_case);
+size_t rhash_urlencode(char* dst, const char* str, size_t size, int upper_case);
+size_t rhash_base64_url_encoded_helper(char* dst, const unsigned char* src, size_t length, int url_encode, int upper_case);
+int rhash_sprintI64(char* dst, uint64_t number);
 
 #define BASE32_LENGTH(bytes) (((bytes) * 8 + 4) / 5)
 #define BASE64_LENGTH(bytes) ((((bytes) + 2) / 3) * 4)
diff --git a/Utilities/cmlibrhash/librhash/md5.c b/Utilities/cmlibrhash/librhash/md5.c
index b20de45..9b76822 100644
--- a/Utilities/cmlibrhash/librhash/md5.c
+++ b/Utilities/cmlibrhash/librhash/md5.c
@@ -1,17 +1,17 @@
 /* md5.c - an implementation of the MD5 algorithm, based on RFC 1321.
  *
- * Copyright: 2007-2012 Aleksey Kravchenko <rhash.admin@gmail.com>
+ * Copyright (c) 2007, Aleksey Kravchenko <rhash.admin@gmail.com>
  *
- * Permission is hereby granted,  free of charge,  to any person  obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction,  including without limitation
- * the rights to  use, copy, modify,  merge, publish, distribute, sublicense,
- * and/or sell copies  of  the Software,  and to permit  persons  to whom the
- * Software is furnished to do so.
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted.
  *
- * This program  is  distributed  in  the  hope  that it will be useful,  but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  Use this program  at  your own risk!
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE  INCLUDING ALL IMPLIED WARRANTIES OF  MERCHANTABILITY
+ * AND FITNESS.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT,  OR CONSEQUENTIAL DAMAGES  OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE,  DATA OR PROFITS,  WHETHER IN AN ACTION OF CONTRACT,  NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION,  ARISING OUT OF  OR IN CONNECTION  WITH THE USE  OR
+ * PERFORMANCE OF THIS SOFTWARE.
  */
 
 #include <string.h>
@@ -23,7 +23,7 @@
  *
  * @param ctx context to initialize
  */
-void rhash_md5_init(md5_ctx *ctx)
+void rhash_md5_init(md5_ctx* ctx)
 {
 	ctx->length = 0;
 
@@ -162,7 +162,7 @@
  * @param msg message chunk
  * @param size length of the message chunk
  */
-void rhash_md5_update(md5_ctx *ctx, const unsigned char* msg, size_t size)
+void rhash_md5_update(md5_ctx* ctx, const unsigned char* msg, size_t size)
 {
 	unsigned index = (unsigned)ctx->length & 63;
 	ctx->length += size;
@@ -205,7 +205,7 @@
  * @param ctx the algorithm context containing current hashing state
  * @param result calculated hash in binary form
  */
-void rhash_md5_final(md5_ctx *ctx, unsigned char* result)
+void rhash_md5_final(md5_ctx* ctx, unsigned char* result)
 {
 	unsigned index = ((unsigned)ctx->length & 63) >> 2;
 	unsigned shift = ((unsigned)ctx->length & 3) * 8;
diff --git a/Utilities/cmlibrhash/librhash/md5.h b/Utilities/cmlibrhash/librhash/md5.h
index 1af6f13..12a6b52 100644
--- a/Utilities/cmlibrhash/librhash/md5.h
+++ b/Utilities/cmlibrhash/librhash/md5.h
@@ -20,9 +20,9 @@
 
 /* hash functions */
 
-void rhash_md5_init(md5_ctx *ctx);
-void rhash_md5_update(md5_ctx *ctx, const unsigned char* msg, size_t size);
-void rhash_md5_final(md5_ctx *ctx, unsigned char result[16]);
+void rhash_md5_init(md5_ctx* ctx);
+void rhash_md5_update(md5_ctx* ctx, const unsigned char* msg, size_t size);
+void rhash_md5_final(md5_ctx* ctx, unsigned char result[16]);
 
 #ifdef __cplusplus
 } /* extern "C" */
diff --git a/Utilities/cmlibrhash/librhash/rhash.c b/Utilities/cmlibrhash/librhash/rhash.c
index 34e1eb3..ce6ace4 100644
--- a/Utilities/cmlibrhash/librhash/rhash.c
+++ b/Utilities/cmlibrhash/librhash/rhash.c
@@ -1,42 +1,40 @@
 /* rhash.c - implementation of LibRHash library calls
  *
- * Copyright: 2008-2012 Aleksey Kravchenko <rhash.admin@gmail.com>
+ * Copyright (c) 2008, Aleksey Kravchenko <rhash.admin@gmail.com>
  *
- * Permission is hereby granted,  free of charge,  to any person  obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction,  including without limitation
- * the rights to  use, copy, modify,  merge, publish, distribute, sublicense,
- * and/or sell copies  of  the Software,  and to permit  persons  to whom the
- * Software is furnished to do so.
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted.
  *
- * This program  is  distributed  in  the  hope  that it will be useful,  but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  Use this program  at  your own risk!
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE  INCLUDING ALL IMPLIED WARRANTIES OF  MERCHANTABILITY
+ * AND FITNESS.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT,  OR CONSEQUENTIAL DAMAGES  OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE,  DATA OR PROFITS,  WHETHER IN AN ACTION OF CONTRACT,  NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION,  ARISING OUT OF  OR IN CONNECTION  WITH THE USE  OR
+ * PERFORMANCE OF THIS SOFTWARE.
  */
 
+/* modifier for Windows DLL */
+#if (defined(_WIN32) || defined(__CYGWIN__)) && defined(RHASH_EXPORTS)
+# define RHASH_API __declspec(dllexport)
+#endif
+
 /* macros for large file support, must be defined before any include file */
 #define _LARGEFILE64_SOURCE
 #define _FILE_OFFSET_BITS 64
 
 #include "ustd.h"   /* Need this first within CMake.  */
 
-#include <string.h> /* memset() */
-#include <stdlib.h> /* free() */
-#include <stddef.h> /* ptrdiff_t */
-#include <stdio.h>
+#include "rhash.h"
+#include "algorithms.h"
+#include "byte_order.h"
+#include "hex.h"
+#include "util.h"
 #include <assert.h>
 #include <errno.h>
-
-/* modifier for Windows DLL */
-#if defined(_WIN32) && defined(RHASH_EXPORTS)
-# define RHASH_API __declspec(dllexport)
-#endif
-
-#include "byte_order.h"
-#include "algorithms.h"
-#include "util.h"
-#include "hex.h"
-#include "rhash.h" /* RHash library interface */
+#include <stdlib.h>
+#include <stddef.h>
+#include <string.h>
 
 #define STATE_ACTIVE  0xb01dbabe
 #define STATE_STOPED  0xdeadbeef
@@ -45,11 +43,8 @@
 #define RCTX_FINALIZED  0x2
 #define RCTX_FINALIZED_MASK (RCTX_AUTO_FINAL | RCTX_FINALIZED)
 #define RHPR_FORMAT (RHPR_RAW | RHPR_HEX | RHPR_BASE32 | RHPR_BASE64)
-#define RHPR_MODIFIER (RHPR_UPPERCASE | RHPR_REVERSE)
+#define RHPR_MODIFIER (RHPR_UPPERCASE | RHPR_URLENCODE | RHPR_REVERSE)
 
-/**
- * Initialize static data of rhash algorithms
- */
 void rhash_library_init(void)
 {
 	rhash_init_algorithms(RHASH_ALL_HASHES);
@@ -58,31 +53,18 @@
 #endif
 }
 
-/**
- * Returns the number of supported hash algorithms.
- *
- * @return the number of supported hash functions
- */
 int RHASH_API rhash_count(void)
 {
 	return rhash_info_size;
 }
 
-/* Lo-level rhash library functions */
+/* LOW-LEVEL LIBRHASH INTERFACE */
 
-/**
- * Allocate and initialize RHash context for calculating hash(es).
- * After initializing rhash_update()/rhash_final() functions should be used.
- * Then the context must be freed by calling rhash_free().
- *
- * @param hash_id union of bit flags, containing ids of hashes to calculate.
- * @return initialized rhash context, NULL on error and errno is set
- */
 RHASH_API rhash rhash_init(unsigned hash_id)
 {
 	unsigned tail_bit_index; /* index of hash_id trailing bit */
 	unsigned num = 0;        /* number of hashes to compute */
-	rhash_context_ext *rctx = NULL; /* allocated rhash context */
+	rhash_context_ext* rctx = NULL; /* allocated rhash context */
 	size_t hash_size_sum = 0;   /* size of hash contexts to store in rctx */
 
 	unsigned i, bit_index, id;
@@ -123,7 +105,7 @@
 	}
 
 	/* align the size of the rhash context common part */
-	aligned_size = (offsetof(rhash_context_ext, vector[num]) + 7) & ~7;
+	aligned_size = ((offsetof(rhash_context_ext, vector) + sizeof(rhash_vector_item) * num) + 7) & ~7;
 	assert(aligned_size >= sizeof(rhash_context_ext));
 
 	/* allocate rhash context with enough memory to store contexts of all used hashes */
@@ -170,11 +152,6 @@
 	return &rctx->rc; /* return allocated and initialized rhash context */
 }
 
-/**
- * Free RHash context memory.
- *
- * @param ctx the context to free.
- */
 void rhash_free(rhash ctx)
 {
 	rhash_context_ext* const ectx = (rhash_context_ext*)ctx;
@@ -195,12 +172,6 @@
 	free(ectx);
 }
 
-/**
- * Re-initialize RHash context to reuse it.
- * Useful to speed up processing of many small messages.
- *
- * @param ctx context to reinitialize
- */
 RHASH_API void rhash_reset(rhash ctx)
 {
 	rhash_context_ext* const ectx = (rhash_context_ext*)ctx;
@@ -223,15 +194,6 @@
 	ectx->flags &= ~RCTX_FINALIZED; /* clear finalized state */
 }
 
-/**
- * Calculate hashes of message.
- * Can be called repeatedly with chunks of the message to be hashed.
- *
- * @param ctx the rhash context
- * @param message message chunk
- * @param length length of the message chunk
- * @return 0 on success; On fail return -1 and set errno
- */
 RHASH_API int rhash_update(rhash ctx, const void* message, size_t length)
 {
 	rhash_context_ext* const ectx = (rhash_context_ext*)ctx;
@@ -251,13 +213,6 @@
 	return 0; /* no error processing at the moment */
 }
 
-/**
- * Finalize hash calculation and optionally store the first hash.
- *
- * @param ctx the rhash context
- * @param first_result optional buffer to store a calculated hash with the lowest available id
- * @return 0 on success; On fail return -1 and set errno
- */
 RHASH_API int rhash_final(rhash ctx, unsigned char* first_result)
 {
 	unsigned i = 0;
@@ -295,7 +250,7 @@
 {
 	rhash_context_ext* const ectx = (rhash_context_ext*)ctx;
 	unsigned i;
-	rhash_vector_item *item;
+	rhash_vector_item* item;
 	struct rhash_hash_info* info;
 	unsigned char* digest;
 
@@ -332,34 +287,14 @@
 	}
 }
 
-/**
- * Set the callback function to be called from the
- * rhash_file() and rhash_file_update() functions
- * on processing every file block. The file block
- * size is set internally by rhash and now is 8 KiB.
- *
- * @param ctx rhash context
- * @param callback pointer to the callback function
- * @param callback_data pointer to data passed to the callback
- */
 RHASH_API void rhash_set_callback(rhash ctx, rhash_callback_t callback, void* callback_data)
 {
-	((rhash_context_ext*)ctx)->callback = callback;
+	((rhash_context_ext*)ctx)->callback = (void*)callback;
 	((rhash_context_ext*)ctx)->callback_data = callback_data;
 }
 
+/* HIGH-LEVEL LIBRHASH INTERFACE */
 
-/* hi-level message hashing interface */
-
-/**
- * Compute a hash of the given message.
- *
- * @param hash_id id of hash sum to compute
- * @param message the message to process
- * @param length message length
- * @param result buffer to receive binary hash string
- * @return 0 on success, -1 on error
- */
 RHASH_API int rhash_msg(unsigned hash_id, const void* message, size_t length, unsigned char* result)
 {
 	rhash ctx;
@@ -372,22 +307,12 @@
 	return 0;
 }
 
-/**
- * Hash a file or stream. Multiple hashes can be computed.
- * First, inintialize ctx parameter with rhash_init() before calling
- * rhash_file_update(). Then use rhash_final() and rhash_print()
- * to retrive hash values. Finaly call rhash_free() on ctx
- * to free allocated memory or call rhash_reset() to reuse ctx.
- *
- * @param ctx rhash context
- * @param fd descriptor of the file to hash
- * @return 0 on success, -1 on error and errno is set
- */
 RHASH_API int rhash_file_update(rhash ctx, FILE* fd)
 {
 	rhash_context_ext* const ectx = (rhash_context_ext*)ctx;
 	const size_t block_size = 8192;
-	unsigned char *buffer, *pmem;
+	unsigned char* buffer;
+	unsigned char* pmem;
 	size_t length = 0, align8;
 	int res = 0;
 	if (ectx->state != STATE_ACTIVE) return 0; /* do nothing if canceled */
@@ -425,14 +350,6 @@
 	return res;
 }
 
-/**
- * Compute a single hash for given file.
- *
- * @param hash_id id of hash sum to compute
- * @param filepath path to the file to hash
- * @param result buffer to receive hash value with the lowest requested id
- * @return 0 on success, -1 on error and errno is set
- */
 RHASH_API int rhash_file(unsigned hash_id, const char* filepath, unsigned char* result)
 {
 	FILE* fd;
@@ -447,7 +364,10 @@
 
 	if ((fd = fopen(filepath, "rb")) == NULL) return -1;
 
-	if ((ctx = rhash_init(hash_id)) == NULL) return -1;
+	if ((ctx = rhash_init(hash_id)) == NULL) {
+		fclose(fd);
+		return -1;
+	}
 
 	res = rhash_file_update(ctx, fd); /* hash the file */
 	fclose(fd);
@@ -460,14 +380,6 @@
 #ifdef _WIN32 /* windows only function */
 #include <share.h>
 
-/**
- * Compute a single hash for given file.
- *
- * @param hash_id id of hash sum to compute
- * @param filepath path to the file to hash
- * @param result buffer to receive hash value with the lowest requested id
- * @return 0 on success, -1 on error, -1 on error and errno is set
- */
 RHASH_API int rhash_wfile(unsigned hash_id, const wchar_t* filepath, unsigned char* result)
 {
 	FILE* fd;
@@ -482,7 +394,10 @@
 
 	if ((fd = _wfsopen(filepath, L"rb", _SH_DENYWR)) == NULL) return -1;
 
-	if ((ctx = rhash_init(hash_id)) == NULL) return -1;
+	if ((ctx = rhash_init(hash_id)) == NULL) {
+		fclose(fd);
+		return -1;
+	}
 
 	res = rhash_file_update(ctx, fd); /* hash the file */
 	fclose(fd);
@@ -495,28 +410,7 @@
 
 /* RHash information functions */
 
-/**
- * Returns information about a hash function by its hash_id.
- *
- * @param hash_id the id of hash algorithm
- * @return pointer to the rhash_info structure containing the information
- */
-const rhash_info* rhash_info_by_id(unsigned hash_id)
-{
-	hash_id &= RHASH_ALL_HASHES;
-	/* check that only one bit is set */
-	if (hash_id != (hash_id & -(int)hash_id)) return NULL;
-	/* note: alternative condition is (hash_id == 0 || (hash_id & (hash_id - 1)) != 0) */
-	return rhash_info_table[rhash_ctz(hash_id)].info;
-}
-
 #if 0
-/**
- * Detect default digest output format for given hash algorithm.
- *
- * @param hash_id the id of hash algorithm
- * @return 1 for base32 format, 0 for hexadecimal
- */
 RHASH_API int rhash_is_base32(unsigned hash_id)
 {
 	/* fast method is just to test a bit-mask */
@@ -524,12 +418,6 @@
 }
 #endif
 
-/**
- * Returns size of binary digest for given hash algorithm.
- *
- * @param hash_id the id of hash algorithm
- * @return digest size in bytes
- */
 RHASH_API int rhash_get_digest_size(unsigned hash_id)
 {
 	hash_id &= RHASH_ALL_HASHES;
@@ -537,12 +425,6 @@
 	return (int)rhash_info_table[rhash_ctz(hash_id)].info->digest_size;
 }
 
-/**
- * Returns length of digest hash string in default output format.
- *
- * @param hash_id the id of hash algorithm
- * @return the length of hash string
- */
 RHASH_API int rhash_get_hash_length(unsigned hash_id)
 {
 	const rhash_info* info = rhash_info_by_id(hash_id);
@@ -550,26 +432,12 @@
 		BASE32_LENGTH(info->digest_size) : info->digest_size * 2) : 0);
 }
 
-/**
- * Returns a name of given hash algorithm.
- *
- * @param hash_id the id of hash algorithm
- * @return algorithm name
- */
 RHASH_API const char* rhash_get_name(unsigned hash_id)
 {
 	const rhash_info* info = rhash_info_by_id(hash_id);
 	return (info ? info->name : 0);
 }
 
-/**
- * Returns a name part of magnet urn of the given hash algorithm.
- * Such magnet_name is used to generate a magnet link of the form
- * urn:&lt;magnet_name&gt;=&lt;hash_value&gt;.
- *
- * @param hash_id the id of hash algorithm
- * @return name
- */
 RHASH_API const char* rhash_get_magnet_name(unsigned hash_id)
 {
 	const rhash_info* info = rhash_info_by_id(hash_id);
@@ -599,7 +467,7 @@
 	}
 
 	if (filepath) {
-		size += 4 + rhash_urlencode(NULL, filepath);
+		size += 4 + rhash_urlencode(NULL, filepath, strlen(filepath), 0);
 	}
 
 	/* loop through hash values */
@@ -610,34 +478,20 @@
 
 		size += (7 + 2) + strlen(name);
 		size += rhash_print(NULL, context, bit,
-			(bit & (RHASH_SHA1 | RHASH_BTIH) ? RHPR_BASE32 : 0));
+			(bit & RHASH_SHA1 ? RHPR_BASE32 : 0));
 	}
 
 	return size;
 }
 
-/**
- * Print magnet link with given filepath and calculated hash sums into the
- * output buffer. The hash_mask can limit which hash values will be printed.
- * The function returns the size of the required buffer.
- * If output is NULL the .
- *
- * @param output a string buffer to receive the magnet link or NULL
- * @param filepath the file path to be printed or NULL
- * @param context algorithms state
- * @param hash_mask bit mask of the hash sums to add to the link
- * @param flags   can be combination of bits RHPR_UPPERCASE, RHPR_NO_MAGNET,
- *                RHPR_FILESIZE
- * @return number of written characters, including terminating '\0' on success, 0 on fail
- */
 RHASH_API size_t rhash_print_magnet(char* output, const char* filepath,
 	rhash context, unsigned hash_mask, int flags)
 {
 	int i;
 	const char* begin = output;
 
-	if (output == NULL) return rhash_get_magnet_url_size(
-		filepath, context, hash_mask, flags);
+	if (output == NULL)
+		return rhash_get_magnet_url_size(filepath, context, hash_mask, flags);
 
 	/* RHPR_NO_MAGNET, RHPR_FILESIZE */
 	if ((flags & RHPR_NO_MAGNET) == 0) {
@@ -652,13 +506,13 @@
 		*(output++) = '&';
 	}
 
+	flags &= RHPR_UPPERCASE;
 	if (filepath) {
 		strcpy(output, "dn=");
 		output += 3;
-		output += rhash_urlencode(output, filepath);
+		output += rhash_urlencode(output, filepath, strlen(filepath), flags);
 		*(output++) = '&';
 	}
-	flags &= RHPR_UPPERCASE;
 
 	for (i = 0; i < 2; i++) {
 		unsigned bit;
@@ -679,7 +533,7 @@
 			output += strlen(name);
 			*(output++) = ':';
 			output += rhash_print(output, context, bit,
-				(bit & (RHASH_SHA1 | RHASH_BTIH) ? flags | RHPR_BASE32 : flags));
+				(bit & RHASH_SHA1 ? flags | RHPR_BASE32 : flags));
 			*(output++) = '&';
 		}
 	}
@@ -688,62 +542,39 @@
 	return (output - begin);
 }
 
-/* hash sum output */
 
-/**
- * Print a text presentation of a given hash sum to the specified buffer,
- *
- * @param output a buffer to print the hash to
- * @param bytes a hash sum to print
- * @param size a size of hash sum in bytes
- * @param flags  a bit-mask controlling how to format the hash sum,
- *               can be a mix of the flags: RHPR_RAW, RHPR_HEX, RHPR_BASE32,
- *               RHPR_BASE64, RHPR_UPPERCASE, RHPR_REVERSE
- * @return the number of written characters
- */
-size_t rhash_print_bytes(char* output, const unsigned char* bytes,
-	size_t size, int flags)
+/* HASH SUM OUTPUT INTERFACE */
+
+size_t rhash_print_bytes(char* output, const unsigned char* bytes, size_t size, int flags)
 {
-	size_t str_len;
+	size_t result_length;
 	int upper_case = (flags & RHPR_UPPERCASE);
 	int format = (flags & ~RHPR_MODIFIER);
 
 	switch (format) {
 	case RHPR_HEX:
-		str_len = size * 2;
-		rhash_byte_to_hex(output, bytes, (unsigned)size, upper_case);
+		result_length = size * 2;
+		rhash_byte_to_hex(output, bytes, size, upper_case);
 		break;
 	case RHPR_BASE32:
-		str_len = BASE32_LENGTH(size);
-		rhash_byte_to_base32(output, bytes, (unsigned)size, upper_case);
+		result_length = BASE32_LENGTH(size);
+		rhash_byte_to_base32(output, bytes, size, upper_case);
 		break;
 	case RHPR_BASE64:
-		str_len = BASE64_LENGTH(size);
-		rhash_byte_to_base64(output, bytes, (unsigned)size);
+		result_length = rhash_base64_url_encoded_helper(output, bytes, size, (flags & RHPR_URLENCODE), upper_case);
 		break;
 	default:
-		str_len = size;
-		memcpy(output, bytes, size);
+		if (flags & RHPR_URLENCODE) {
+			result_length = rhash_urlencode(output, (char*)bytes, size, upper_case);
+		} else {
+			memcpy(output, bytes, size);
+			result_length = size;
+		}
 		break;
 	}
-	return str_len;
+	return result_length;
 }
 
-/**
- * Print text presentation of a hash sum with given hash_id to the specified
- * output buffer. If the hash_id is zero, then print the hash sum with
- * the lowest id stored in the hash context.
- * The function call fails if the context doesn't include a hash with the
- * given hash_id.
- *
- * @param output a buffer to print the hash to
- * @param context algorithms state
- * @param hash_id id of the hash sum to print or 0 to print the first hash
- *                saved in the context.
- * @param flags  a bitmask controlling how to print the hash. Can contain flags
- *               RHPR_UPPERCASE, RHPR_HEX, RHPR_BASE32, RHPR_BASE64, etc.
- * @return the number of written characters on success or 0 on fail
- */
 size_t RHASH_API rhash_print(char* output, rhash context, unsigned hash_id, int flags)
 {
 	const rhash_info* info;
@@ -764,15 +595,16 @@
 	}
 
 	if (output == NULL) {
+		size_t multiplier = (flags & RHPR_URLENCODE ? 3 : 1);
 		switch (flags & RHPR_FORMAT) {
 		case RHPR_HEX:
 			return (digest_size * 2);
 		case RHPR_BASE32:
 			return BASE32_LENGTH(digest_size);
 		case RHPR_BASE64:
-			return BASE64_LENGTH(digest_size);
+			return BASE64_LENGTH(digest_size) * multiplier;
 		default:
-			return digest_size;
+			return digest_size * multiplier;
 		}
 	}
 
@@ -781,7 +613,8 @@
 
 	if ((flags & ~RHPR_UPPERCASE) == (RHPR_REVERSE | RHPR_HEX)) {
 		/* reverse the digest */
-		unsigned char *p = digest, *r = digest + digest_size - 1;
+		unsigned char* p = digest;
+		unsigned char* r = digest + digest_size - 1;
 		char tmp;
 		for (; p < r; p++, r--) {
 			tmp = *p;
@@ -793,7 +626,7 @@
 	return rhash_print_bytes(output, digest, digest_size, flags);
 }
 
-#if defined(_WIN32) && defined(RHASH_EXPORTS)
+#if (defined(_WIN32) || defined(__CYGWIN__)) && defined(RHASH_EXPORTS)
 #include <windows.h>
 BOOL APIENTRY DllMain(HMODULE hModule, DWORD reason, LPVOID reserved);
 BOOL APIENTRY DllMain(HMODULE hModule, DWORD reason, LPVOID reserved)
@@ -814,17 +647,8 @@
 }
 #endif
 
-#define PVOID2UPTR(p) ((rhash_uptr_t)((char*)p - 0))
+#define PVOID2UPTR(p) ((rhash_uptr_t)(((char*)(p)) + 0))
 
-/**
- * Process a rhash message.
- *
- * @param msg_id message identifier
- * @param dst message destination (can be NULL for generic messages)
- * @param ldata data depending on message
- * @param rdata data depending on message
- * @return message-specific data
- */
 RHASH_API rhash_uptr_t rhash_transmit(unsigned msg_id, void* dst, rhash_uptr_t ldata, rhash_uptr_t rdata)
 {
 	/* for messages working with rhash context */
@@ -865,6 +689,10 @@
 	case RMSG_GET_OPENSSL_MASK:
 		return rhash_openssl_hash_mask;
 #endif
+	case RMSG_GET_OPENSSL_SUPPORTED_MASK:
+		return rhash_get_openssl_supported_hash_mask();
+	case RMSG_GET_OPENSSL_AVAILABLE_MASK:
+		return rhash_get_openssl_available_hash_mask();
 
 	default:
 		return RHASH_ERROR; /* unknown message */
diff --git a/Utilities/cmlibrhash/librhash/rhash.h b/Utilities/cmlibrhash/librhash/rhash.h
index cee0e25..c011762 100644
--- a/Utilities/cmlibrhash/librhash/rhash.h
+++ b/Utilities/cmlibrhash/librhash/rhash.h
@@ -9,7 +9,9 @@
 #endif
 
 #ifndef RHASH_API
-/* modifier for LibRHash functions */
+/**
+ * Modifier for LibRHash functions
+ */
 # define RHASH_API
 #endif
 
@@ -32,11 +34,11 @@
 	RHASH_AICH  = 0x100,
 	RHASH_WHIRLPOOL = 0x200,
 	RHASH_RIPEMD160 = 0x400,
-	RHASH_GOST      = 0x800,
-	RHASH_GOST_CRYPTOPRO = 0x1000,
-	RHASH_HAS160    = 0x2000,
-	RHASH_SNEFRU128 = 0x4000,
-	RHASH_SNEFRU256 = 0x8000,
+	RHASH_GOST94    = 0x800,
+	RHASH_GOST94_CRYPTOPRO = 0x1000,
+	RHASH_HAS160     = 0x2000,
+	RHASH_GOST12_256 = 0x4000,
+	RHASH_GOST12_512 = 0x8000,
 	RHASH_SHA224    = 0x10000,
 	RHASH_SHA256    = 0x20000,
 	RHASH_SHA384    = 0x40000,
@@ -47,18 +49,28 @@
 	RHASH_SHA3_256  = 0x0800000,
 	RHASH_SHA3_384  = 0x1000000,
 	RHASH_SHA3_512  = 0x2000000,
+	RHASH_CRC32C    = 0x4000000,
+	RHASH_SNEFRU128 = 0x8000000,
+	RHASH_SNEFRU256 = 0x10000000,
 
-	/** The bit-mask containing all supported hashe functions */
-	RHASH_ALL_HASHES = RHASH_CRC32 | RHASH_MD4 | RHASH_MD5 | RHASH_ED2K | RHASH_SHA1 |
-		RHASH_TIGER | RHASH_TTH | RHASH_GOST | RHASH_GOST_CRYPTOPRO |
+	/**
+	 * The bit-mask containing all supported hashe functions.
+	 */
+	RHASH_ALL_HASHES = RHASH_CRC32 | RHASH_CRC32C | RHASH_MD4 | RHASH_MD5 |
+		RHASH_ED2K | RHASH_SHA1 |RHASH_TIGER | RHASH_TTH |
+		RHASH_GOST94 | RHASH_GOST94_CRYPTOPRO | RHASH_GOST12_256 | RHASH_GOST12_512 |
 		RHASH_BTIH | RHASH_AICH | RHASH_WHIRLPOOL | RHASH_RIPEMD160 |
 		RHASH_HAS160 | RHASH_SNEFRU128 | RHASH_SNEFRU256 |
 		RHASH_SHA224 | RHASH_SHA256 | RHASH_SHA384 | RHASH_SHA512 |
 		RHASH_SHA3_224 | RHASH_SHA3_256 | RHASH_SHA3_384 | RHASH_SHA3_512 |
 		RHASH_EDONR256 | RHASH_EDONR512,
 
-	/** The number of supported hash functions */
-	RHASH_HASH_COUNT = 26
+	RHASH_GOST = RHASH_GOST94, /* deprecated constant name */
+	RHASH_GOST_CRYPTOPRO = RHASH_GOST94_CRYPTOPRO, /* deprecated constant name */
+	/**
+	 * The number of supported hash functions.
+	 */
+	RHASH_HASH_COUNT = 29
 #else
 	RHASH_MD5        = 0x01,
 	RHASH_SHA1       = 0x02,
@@ -86,15 +98,17 @@
 };
 
 /**
- * The rhash context structure contains contexts for several hash functions
+ * The rhash context structure contains contexts for several hash functions.
  */
 typedef struct rhash_context
 {
-	/** The size of the hashed message */
+	/**
+	 * The size of the hashed message.
+	 */
 	unsigned long long msg_size;
 
 	/**
-	 * The bit-mask containing identifiers of the hashes being calculated
+	 * The bit-mask containing identifiers of the hashes being calculated.
 	 */
 	unsigned hash_id;
 } rhash_context;
@@ -107,109 +121,285 @@
 typedef struct rhash_context* rhash;
 #endif /* LIBRHASH_RHASH_CTX_DEFINED */
 
-/** type of a callback to be called periodically while hashing a file */
+/**
+ * Type of a callback to be called periodically while hashing a file.
+ */
 typedef void (*rhash_callback_t)(void* data, unsigned long long offset);
 
-RHASH_API void rhash_library_init(void); /* initialize static data */
+/**
+ * Initialize static data of rhash algorithms
+ */
+RHASH_API void rhash_library_init(void);
 
-/* hi-level hashing functions */
+
+/* HIGH-LEVEL LIBRHASH INTERFACE */
+
+/**
+ * Compute a hash of the given message.
+ *
+ * @param hash_id id of hash sum to compute
+ * @param message the message to process
+ * @param length message length
+ * @param result buffer to receive binary hash string
+ * @return 0 on success, -1 on error
+ */
 RHASH_API int rhash_msg(unsigned hash_id, const void* message, size_t length, unsigned char* result);
-RHASH_API int rhash_file(unsigned hash_id, const char* filepath, unsigned char* result);
-RHASH_API int rhash_file_update(rhash ctx, FILE* fd);
 
-#ifdef _WIN32 /* windows only function */
+/**
+ * Compute a single hash for given file.
+ *
+ * @param hash_id id of hash sum to compute
+ * @param filepath path to the file to hash
+ * @param result buffer to receive hash value with the lowest requested id
+ * @return 0 on success, -1 on error and errno is set
+ */
+RHASH_API int rhash_file(unsigned hash_id, const char* filepath, unsigned char* result);
+
+#ifdef _WIN32
+/**
+ * Compute a single hash for given file (Windows-specific function).
+ *
+ * @param hash_id id of hash sum to compute
+ * @param filepath path to the file to hash
+ * @param result buffer to receive hash value with the lowest requested id
+ * @return 0 on success, -1 on error, -1 on error and errno is set
+ */
 RHASH_API int rhash_wfile(unsigned hash_id, const wchar_t* filepath, unsigned char* result);
 #endif
 
-/* lo-level interface */
-RHASH_API rhash rhash_init(unsigned hash_id);
-/*RHASH_API rhash rhash_init_by_ids(unsigned hash_ids[], unsigned count);*/
-RHASH_API int  rhash_update(rhash ctx, const void* message, size_t length);
-RHASH_API int  rhash_final(rhash ctx, unsigned char* first_result);
-RHASH_API void rhash_reset(rhash ctx); /* reinitialize the context */
-RHASH_API void rhash_free(rhash ctx);
 
-/* additional lo-level functions */
-RHASH_API void  rhash_set_callback(rhash ctx, rhash_callback_t callback, void* callback_data);
-
-/** bit-flag: default hash output format is base32 */
-#define RHASH_INFO_BASE32 1
+/* LOW-LEVEL LIBRHASH INTERFACE */
 
 /**
- * Information about a hash function.
+ * Allocate and initialize RHash context for calculating hash(es).
+ * After initializing rhash_update()/rhash_final() functions should be used.
+ * Then the context must be freed by calling rhash_free().
+ *
+ * @param hash_id union of bit flags, containing ids of hashes to calculate.
+ * @return initialized rhash context, NULL on error and errno is set
  */
-typedef struct rhash_info
-{
-	/** hash function indentifier */
-	unsigned hash_id;
-	/** flags bit-mask, including RHASH_INFO_BASE32 bit */
-	unsigned flags;
-	/** size of binary message digest in bytes */
-	size_t digest_size;
-	const char* name;
-	const char* magnet_name;
-} rhash_info;
+RHASH_API rhash rhash_init(unsigned hash_id);
 
-/* information functions */
+/**
+ * Calculate hashes of message.
+ * Can be called repeatedly with chunks of the message to be hashed.
+ *
+ * @param ctx the rhash context
+ * @param message message chunk
+ * @param length length of the message chunk
+ * @return 0 on success; On fail return -1 and set errno
+ */
+RHASH_API int rhash_update(rhash ctx, const void* message, size_t length);
+
+/**
+ * Hash a file or stream. Multiple hashes can be computed.
+ * First, inintialize ctx parameter with rhash_init() before calling
+ * rhash_file_update(). Then use rhash_final() and rhash_print()
+ * to retrive hash values. Finaly call rhash_free() on ctx
+ * to free allocated memory or call rhash_reset() to reuse ctx.
+ *
+ * @param ctx rhash context
+ * @param fd descriptor of the file to hash
+ * @return 0 on success, -1 on error and errno is set
+ */
+RHASH_API int rhash_file_update(rhash ctx, FILE* fd);
+
+/**
+ * Finalize hash calculation and optionally store the first hash.
+ *
+ * @param ctx the rhash context
+ * @param first_result optional buffer to store a calculated hash with the lowest available id
+ * @return 0 on success; On fail return -1 and set errno
+ */
+RHASH_API int rhash_final(rhash ctx, unsigned char* first_result);
+
+/**
+ * Re-initialize RHash context to reuse it.
+ * Useful to speed up processing of many small messages.
+ *
+ * @param ctx context to reinitialize
+ */
+RHASH_API void rhash_reset(rhash ctx);
+
+/**
+ * Free RHash context memory.
+ *
+ * @param ctx the context to free.
+ */
+RHASH_API void rhash_free(rhash ctx);
+
+/**
+ * Set the callback function to be called from the
+ * rhash_file() and rhash_file_update() functions
+ * on processing every file block. The file block
+ * size is set internally by rhash and now is 8 KiB.
+ *
+ * @param ctx rhash context
+ * @param callback pointer to the callback function
+ * @param callback_data pointer to data passed to the callback
+ */
+RHASH_API void  rhash_set_callback(rhash ctx, rhash_callback_t callback, void* callback_data);
+
+
+/* INFORMATION FUNCTIONS */
+
+/**
+ * Returns the number of supported hash algorithms.
+ *
+ * @return the number of supported hash functions
+ */
 RHASH_API int  rhash_count(void); /* number of supported hashes */
+
+/**
+ * Returns size of binary digest for given hash algorithm.
+ *
+ * @param hash_id the id of hash algorithm
+ * @return digest size in bytes
+ */
 RHASH_API int  rhash_get_digest_size(unsigned hash_id); /* size of binary message digest */
+
+/**
+ * Returns length of digest hash string in default output format.
+ *
+ * @param hash_id the id of hash algorithm
+ * @return the length of hash string
+ */
 RHASH_API int  rhash_get_hash_length(unsigned hash_id); /* length of formatted hash string */
+
+/**
+ * Detect default digest output format for given hash algorithm.
+ *
+ * @param hash_id the id of hash algorithm
+ * @return 1 for base32 format, 0 for hexadecimal
+ */
 RHASH_API int  rhash_is_base32(unsigned hash_id); /* default digest output format */
+
+/**
+ * Returns a name of given hash algorithm.
+ *
+ * @param hash_id the id of hash algorithm
+ * @return algorithm name
+ */
 RHASH_API const char* rhash_get_name(unsigned hash_id); /* get hash function name */
+
+/**
+ * Returns a name part of magnet urn of the given hash algorithm.
+ * Such magnet_name is used to generate a magnet link of the form
+ * urn:&lt;magnet_name&gt;=&lt;hash_value&gt;.
+ *
+ * @param hash_id the id of hash algorithm
+ * @return name
+ */
 RHASH_API const char* rhash_get_magnet_name(unsigned hash_id); /* get name part of magnet urn */
 
-/* note, that rhash_info_by_id() is not exported to a shared library or DLL */
-const rhash_info* rhash_info_by_id(unsigned hash_id); /* get hash sum info by hash id */
+/* HASH SUM OUTPUT INTERFACE */
 
 #if 0
 /**
- * Flags for printing a hash sum
+ * Flags for printing a hash sum.
  */
 enum rhash_print_sum_flags
 {
-	/** print in a default format */
+	/*
+	 * Print in a default format
+	 */
 	RHPR_DEFAULT   = 0x0,
-	/** output as binary message digest */
+	/*
+	 * Output as binary message digest
+	 */
 	RHPR_RAW       = 0x1,
-	/** print as a hexadecimal string */
+	/*
+	 * Print as a hexadecimal string
+	 */
 	RHPR_HEX       = 0x2,
-	/** print as a base32-encoded string */
+	/*
+	 * Print as a base32-encoded string
+	 */
 	RHPR_BASE32    = 0x3,
-	/** print as a base64-encoded string */
+	/*
+	 * Print as a base64-encoded string
+	 */
 	RHPR_BASE64    = 0x4,
-
-	/**
+	/*
 	 * Print as an uppercase string. Can be used
 	 * for base32 or hexadecimal format only.
 	 */
 	RHPR_UPPERCASE = 0x8,
-
-	/**
+	/*
 	 * Reverse hash bytes. Can be used for GOST hash.
 	 */
 	RHPR_REVERSE   = 0x10,
-
-	/** don't print 'magnet:?' prefix in rhash_print_magnet */
+	/*
+	 * Don't print 'magnet:?' prefix in rhash_print_magnet
+	 */
 	RHPR_NO_MAGNET  = 0x20,
-	/** print file size in rhash_print_magnet */
+	/*
+	 * Print file size in rhash_print_magnet
+	 */
 	RHPR_FILESIZE  = 0x40,
+	/*
+	 * Print as URL-encoded string
+	 */
+	RHPR_URLENCODE  = 0x80
 };
 #endif
 
-/* output hash into the given buffer */
+
+/**
+ * Print a text presentation of a given hash sum to the specified buffer.
+ *
+ * @param output a buffer to print the hash to
+ * @param bytes a hash sum to print
+ * @param size a size of hash sum in bytes
+ * @param flags  a bit-mask controlling how to format the hash sum,
+ *               can be a mix of the flags: RHPR_RAW, RHPR_HEX, RHPR_BASE32,
+ *               RHPR_BASE64, RHPR_URLENCODE, RHPR_UPPERCASE, RHPR_REVERSE
+ * @return the number of written characters
+ */
 RHASH_API size_t rhash_print_bytes(char* output,
 	const unsigned char* bytes, size_t size, int flags);
 
+/**
+ * Print text presentation of a hash sum with given hash_id to the specified
+ * output buffer. If the hash_id is zero, then print the hash sum with
+ * the lowest id stored in the hash context.
+ * The function call fails if the context doesn't include a hash with the
+ * given hash_id.
+ *
+ * @param output a buffer to print the hash to
+ * @param ctx    algorithms state
+ * @param hash_id id of the hash sum to print or 0 to print the first hash
+ *                saved in the context.
+ * @param flags  a bitmask controlling how to print the hash. Can contain flags
+ *               RHPR_UPPERCASE, RHPR_HEX, RHPR_BASE32, RHPR_BASE64, etc.
+ * @return the number of written characters on success or 0 on fail
+ */
 RHASH_API size_t rhash_print(char* output, rhash ctx, unsigned hash_id,
 	int flags);
 
-/* output magnet URL into the given buffer */
+/**
+ * Print magnet link with given filepath and calculated hash sums into the
+ * output buffer. The hash_mask can limit which hash values will be printed.
+ * The function returns the size of the required buffer.
+ * If output is NULL the .
+ *
+ * @param output a string buffer to receive the magnet link or NULL
+ * @param filepath the file path to be printed or NULL
+ * @param context algorithms state
+ * @param hash_mask bit mask of the hash sums to add to the link
+ * @param flags   can be combination of bits RHPR_UPPERCASE, RHPR_NO_MAGNET,
+ *                RHPR_FILESIZE
+ * @return number of written characters, including terminating '\0' on success, 0 on fail
+ */
 RHASH_API size_t rhash_print_magnet(char* output, const char* filepath,
 	rhash context, unsigned hash_mask, int flags);
 
-/* macros for message API */
 
-/** The type of an unsigned integer large enough to hold a pointer */
+/* MESSAGE API */
+
+/**
+ * The type of an unsigned integer large enough to hold a pointer.
+ */
 #if defined(UINTPTR_MAX)
 typedef uintptr_t rhash_uptr_t;
 #elif defined(_LP64) || defined(__LP64__) || defined(__x86_64) || \
@@ -219,14 +409,28 @@
 typedef unsigned long rhash_uptr_t;
 #endif
 
-/** The value returned by rhash_transmit on error */
+/**
+ * The value returned by rhash_transmit on error.
+ */
 #define RHASH_ERROR ((rhash_uptr_t)-1)
-/** Convert a pointer to rhash_uptr_t */
+/**
+ * Convert a pointer to rhash_uptr_t.
+ */
 #define RHASH_STR2UPTR(str) ((rhash_uptr_t)(char*)(str))
-/** Convert a rhash_uptr_t to a void* pointer */
-#define RHASH_UPTR2PVOID(u) ((void*)((char*)0 + (u)))
+/**
+ * Convert a rhash_uptr_t to a void* pointer.
+ */
+#define RHASH_UPTR2PVOID(u) ((void*)((u) + 0))
 
-/* rhash API to set/get data via messages */
+/**
+ * Process a rhash message.
+ *
+ * @param msg_id message identifier
+ * @param dst message destination (can be NULL for generic messages)
+ * @param ldata data depending on message
+ * @param rdata data depending on message
+ * @return message-specific data
+ */
 RHASH_API rhash_uptr_t rhash_transmit(
 	unsigned msg_id, void* dst, rhash_uptr_t ldata, rhash_uptr_t rdata);
 
@@ -239,22 +443,32 @@
 #define RMSG_SET_AUTOFINAL 5
 #define RMSG_SET_OPENSSL_MASK 10
 #define RMSG_GET_OPENSSL_MASK 11
+#define RMSG_GET_OPENSSL_SUPPORTED_MASK 12
+#define RMSG_GET_OPENSSL_AVAILABLE_MASK 13
 
-/* helper macros */
+/* HELPER MACROS */
 
-/** Get a pointer to context of the specified hash function */
+/**
+ * Get a pointer to context of the specified hash function.
+ */
 #define rhash_get_context_ptr(ctx, hash_id) RHASH_UPTR2PVOID(rhash_transmit(RMSG_GET_CONTEXT, ctx, hash_id, 0))
-/** Cancel hash calculation of a file */
+/**
+ * Cancel hash calculation of a file.
+ */
 #define rhash_cancel(ctx) rhash_transmit(RMSG_CANCEL, ctx, 0, 0)
-/** Return non-zero if hash calculation was canceled, zero otherwise */
+/**
+ * Return non-zero if hash calculation was canceled, zero otherwise.
+ */
 #define rhash_is_canceled(ctx) rhash_transmit(RMSG_IS_CANCELED, ctx, 0, 0)
-/** Return non-zero if rhash_final was called for rhash_context */
+/**
+ * Return non-zero if rhash_final was called for rhash_context.
+ */
 #define rhash_get_finalized(ctx) rhash_transmit(RMSG_GET_FINALIZED, ctx, 0, 0)
 
 /**
  * Turn on/off the auto-final flag for the given rhash_context. By default
  * auto-final is on, which means rhash_final is called automatically, if
- * needed when a hash value is retrived by rhash_print call.
+ * needed when a hash value is retrieved by rhash_print call.
  */
 #define rhash_set_autofinal(ctx, on) rhash_transmit(RMSG_SET_AUTOFINAL, ctx, on, 0)
 
@@ -267,19 +481,36 @@
 #define rhash_set_openssl_mask(mask) rhash_transmit(RMSG_SET_OPENSSL_MASK, NULL, mask, 0)
 
 /**
- * Return current bit-mask of hash algorithms selected to be calculated
- * by OpenSSL library.
+ * Return current bit-mask of hash algorithms selected to be calculated by OpenSSL
+ * library. Return RHASH_ERROR if LibRHash is compiled without OpenSSL support.
  */
 #define rhash_get_openssl_mask() rhash_transmit(RMSG_GET_OPENSSL_MASK, NULL, 0, 0)
 
-/** The bit mask of hash algorithms implemented by OpenSSL */
-#if defined(USE_OPENSSL) || defined(OPENSSL_RUNTIME)
-# define RHASH_OPENSSL_SUPPORTED_HASHES (RHASH_MD4 | RHASH_MD5 | \
-	RHASH_SHA1 | RHASH_SHA224 | RHASH_SHA256 | RHASH_SHA384 | \
-	RHASH_SHA512 | RHASH_RIPEMD160 | RHASH_WHIRLPOOL)
-#else
-# define RHASH_OPENSSL_SUPPORTED_HASHES 0
-#endif
+/**
+ * Return the bit-mask of algorithms that can be provided by the OpenSSL plugin,
+ * if the library is compiled with OpenSSL support, 0 otherwise. This bit-mask is
+ * a constant value computed at compile-time.
+ */
+#define rhash_get_openssl_supported_mask() rhash_transmit(RMSG_GET_OPENSSL_SUPPORTED_MASK, NULL, 0, 0)
+
+/**
+ * Return the bit-mask of algorithms that are successfully loaded from
+ * OpenSSL library. If the library is not loaded or not supported by LibRHash,
+ * then return 0.
+ */
+#define rhash_get_openssl_available_mask() rhash_transmit(RMSG_GET_OPENSSL_AVAILABLE_MASK, NULL, 0, 0)
+
+
+/**
+ * Return non-zero if LibRHash hash been compiled with OpenSSL support,
+ * and zero otherwise.
+ */
+#define rhash_is_openssl_supported() (rhash_get_openssl_mask() != RHASH_ERROR)
+
+/**
+ * Legacy macro. The bit mask of hash algorithms implemented by OpenSSL.
+ */
+# define RHASH_OPENSSL_SUPPORTED_HASHES (rhash_get_openssl_supported_mask())
 
 #ifdef __cplusplus
 } /* extern "C" */
diff --git a/Utilities/cmlibrhash/librhash/sha1.c b/Utilities/cmlibrhash/librhash/sha1.c
index f5a053b..b226925 100644
--- a/Utilities/cmlibrhash/librhash/sha1.c
+++ b/Utilities/cmlibrhash/librhash/sha1.c
@@ -1,18 +1,18 @@
 /* sha1.c - an implementation of Secure Hash Algorithm 1 (SHA1)
  * based on RFC 3174.
  *
- * Copyright: 2008-2012 Aleksey Kravchenko <rhash.admin@gmail.com>
+ * Copyright (c) 2008, Aleksey Kravchenko <rhash.admin@gmail.com>
  *
- * Permission is hereby granted,  free of charge,  to any person  obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction,  including without limitation
- * the rights to  use, copy, modify,  merge, publish, distribute, sublicense,
- * and/or sell copies  of  the Software,  and to permit  persons  to whom the
- * Software is furnished to do so.
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted.
  *
- * This program  is  distributed  in  the  hope  that it will be useful,  but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  Use this program  at  your own risk!
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE  INCLUDING ALL IMPLIED WARRANTIES OF  MERCHANTABILITY
+ * AND FITNESS.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT,  OR CONSEQUENTIAL DAMAGES  OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE,  DATA OR PROFITS,  WHETHER IN AN ACTION OF CONTRACT,  NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION,  ARISING OUT OF  OR IN CONNECTION  WITH THE USE  OR
+ * PERFORMANCE OF THIS SOFTWARE.
  */
 
 #include <string.h>
@@ -24,7 +24,7 @@
  *
  * @param ctx context to initialize
  */
-void rhash_sha1_init(sha1_ctx *ctx)
+void rhash_sha1_init(sha1_ctx* ctx)
 {
 	ctx->length = 0;
 
@@ -121,7 +121,7 @@
  * @param msg message chunk
  * @param size length of the message chunk
  */
-void rhash_sha1_update(sha1_ctx *ctx, const unsigned char* msg, size_t size)
+void rhash_sha1_update(sha1_ctx* ctx, const unsigned char* msg, size_t size)
 {
 	unsigned index = (unsigned)ctx->length & 63;
 	ctx->length += size;
@@ -164,7 +164,7 @@
  * @param ctx the algorithm context containing current hashing state
  * @param result calculated hash in binary form
  */
-void rhash_sha1_final(sha1_ctx *ctx, unsigned char* result)
+void rhash_sha1_final(sha1_ctx* ctx, unsigned char* result)
 {
 	unsigned  index = (unsigned)ctx->length & 63;
 	unsigned* msg32 = (unsigned*)ctx->message;
diff --git a/Utilities/cmlibrhash/librhash/sha1.h b/Utilities/cmlibrhash/librhash/sha1.h
index 74b2f94..7e99542 100644
--- a/Utilities/cmlibrhash/librhash/sha1.h
+++ b/Utilities/cmlibrhash/librhash/sha1.h
@@ -20,9 +20,9 @@
 
 /* hash functions */
 
-void rhash_sha1_init(sha1_ctx *ctx);
-void rhash_sha1_update(sha1_ctx *ctx, const unsigned char* msg, size_t size);
-void rhash_sha1_final(sha1_ctx *ctx, unsigned char* result);
+void rhash_sha1_init(sha1_ctx* ctx);
+void rhash_sha1_update(sha1_ctx* ctx, const unsigned char* msg, size_t size);
+void rhash_sha1_final(sha1_ctx* ctx, unsigned char* result);
 
 #ifdef __cplusplus
 } /* extern "C" */
diff --git a/Utilities/cmlibrhash/librhash/sha256.c b/Utilities/cmlibrhash/librhash/sha256.c
index af5b0fe..21a69aa 100644
--- a/Utilities/cmlibrhash/librhash/sha256.c
+++ b/Utilities/cmlibrhash/librhash/sha256.c
@@ -1,18 +1,18 @@
 /* sha256.c - an implementation of SHA-256/224 hash functions
  * based on FIPS 180-3 (Federal Information Processing Standart).
  *
- * Copyright: 2010-2012 Aleksey Kravchenko <rhash.admin@gmail.com>
+ * Copyright (c) 2010, Aleksey Kravchenko <rhash.admin@gmail.com>
  *
- * Permission is hereby granted,  free of charge,  to any person  obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction,  including without limitation
- * the rights to  use, copy, modify,  merge, publish, distribute, sublicense,
- * and/or sell copies  of  the Software,  and to permit  persons  to whom the
- * Software is furnished to do so.
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted.
  *
- * This program  is  distributed  in  the  hope  that it will be useful,  but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  Use this program  at  your own risk!
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE  INCLUDING ALL IMPLIED WARRANTIES OF  MERCHANTABILITY
+ * AND FITNESS.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT,  OR CONSEQUENTIAL DAMAGES  OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE,  DATA OR PROFITS,  WHETHER IN AN ACTION OF CONTRACT,  NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION,  ARISING OUT OF  OR IN CONNECTION  WITH THE USE  OR
+ * PERFORMANCE OF THIS SOFTWARE.
  */
 
 #include <string.h>
@@ -65,7 +65,7 @@
  *
  * @param ctx context to initialize
  */
-void rhash_sha256_init(sha256_ctx *ctx)
+void rhash_sha256_init(sha256_ctx* ctx)
 {
 	/* Initial values. These words were obtained by taking the first 32
 	 * bits of the fractional parts of the square roots of the first
@@ -87,7 +87,7 @@
  *
  * @param ctx context to initialize
  */
-void rhash_sha224_init(struct sha256_ctx *ctx)
+void rhash_sha224_init(struct sha256_ctx* ctx)
 {
 	/* Initial values from FIPS 180-3. These words were obtained by taking
 	 * bits from 33th to 64th of the fractional parts of the square
@@ -113,7 +113,7 @@
 {
 	unsigned A, B, C, D, E, F, G, H;
 	unsigned W[16];
-	const unsigned *k;
+	const unsigned* k;
 	int i;
 
 	A = hash[0], B = hash[1], C = hash[2], D = hash[3];
@@ -168,7 +168,7 @@
  * @param msg message chunk
  * @param size length of the message chunk
  */
-void rhash_sha256_update(sha256_ctx *ctx, const unsigned char *msg, size_t size)
+void rhash_sha256_update(sha256_ctx* ctx, const unsigned char* msg, size_t size)
 {
 	size_t index = (size_t)ctx->length & 63;
 	ctx->length += size;
@@ -210,7 +210,7 @@
  * @param ctx the algorithm context containing current hashing state
  * @param result calculated hash in binary form
  */
-void rhash_sha256_final(sha256_ctx *ctx, unsigned char* result)
+void rhash_sha256_final(sha256_ctx* ctx, unsigned char* result)
 {
 	size_t index = ((unsigned)ctx->length & 63) >> 2;
 	unsigned shift = ((unsigned)ctx->length & 3) * 8;
diff --git a/Utilities/cmlibrhash/librhash/sha256.h b/Utilities/cmlibrhash/librhash/sha256.h
index f87ebaa..3625cfe 100644
--- a/Utilities/cmlibrhash/librhash/sha256.h
+++ b/Utilities/cmlibrhash/librhash/sha256.h
@@ -20,10 +20,10 @@
 	unsigned digest_length; /* length of the algorithm digest in bytes */
 } sha256_ctx;
 
-void rhash_sha224_init(sha256_ctx *ctx);
-void rhash_sha256_init(sha256_ctx *ctx);
-void rhash_sha256_update(sha256_ctx *ctx, const unsigned char* data, size_t length);
-void rhash_sha256_final(sha256_ctx *ctx, unsigned char result[32]);
+void rhash_sha224_init(sha256_ctx* ctx);
+void rhash_sha256_init(sha256_ctx* ctx);
+void rhash_sha256_update(sha256_ctx* ctx, const unsigned char* data, size_t length);
+void rhash_sha256_final(sha256_ctx* ctx, unsigned char result[32]);
 
 #ifdef __cplusplus
 } /* extern "C" */
diff --git a/Utilities/cmlibrhash/librhash/sha3.c b/Utilities/cmlibrhash/librhash/sha3.c
index e4a845f..bd2854f 100644
--- a/Utilities/cmlibrhash/librhash/sha3.c
+++ b/Utilities/cmlibrhash/librhash/sha3.c
@@ -3,18 +3,18 @@
  * The Keccak SHA-3 submission. Submission to NIST (Round 3), 2011
  * by Guido Bertoni, Joan Daemen, Michaël Peeters and Gilles Van Assche
  *
- * Copyright: 2013 Aleksey Kravchenko <rhash.admin@gmail.com>
+ * Copyright (c) 2013, Aleksey Kravchenko <rhash.admin@gmail.com>
  *
- * Permission is hereby granted,  free of charge,  to any person  obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction,  including without limitation
- * the rights to  use, copy, modify,  merge, publish, distribute, sublicense,
- * and/or sell copies  of  the Software,  and to permit  persons  to whom the
- * Software is furnished to do so.
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted.
  *
- * This program  is  distributed  in  the  hope  that it will be useful,  but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  Use this program  at  your own risk!
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE  INCLUDING ALL IMPLIED WARRANTIES OF  MERCHANTABILITY
+ * AND FITNESS.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT,  OR CONSEQUENTIAL DAMAGES  OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE,  DATA OR PROFITS,  WHETHER IN AN ACTION OF CONTRACT,  NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION,  ARISING OUT OF  OR IN CONNECTION  WITH THE USE  OR
+ * PERFORMANCE OF THIS SOFTWARE.
  */
 
 #include <assert.h>
@@ -36,7 +36,7 @@
 };
 
 /* Initializing a sha3 context for given number of output bits */
-static void rhash_keccak_init(sha3_ctx *ctx, unsigned bits)
+static void rhash_keccak_init(sha3_ctx* ctx, unsigned bits)
 {
 	/* NB: The Keccak capacity parameter = bits * 2 */
 	unsigned rate = 1600 - bits * 2;
@@ -51,7 +51,7 @@
  *
  * @param ctx context to initialize
  */
-void rhash_sha3_224_init(sha3_ctx *ctx)
+void rhash_sha3_224_init(sha3_ctx* ctx)
 {
 	rhash_keccak_init(ctx, 224);
 }
@@ -61,7 +61,7 @@
  *
  * @param ctx context to initialize
  */
-void rhash_sha3_256_init(sha3_ctx *ctx)
+void rhash_sha3_256_init(sha3_ctx* ctx)
 {
 	rhash_keccak_init(ctx, 256);
 }
@@ -71,7 +71,7 @@
  *
  * @param ctx context to initialize
  */
-void rhash_sha3_384_init(sha3_ctx *ctx)
+void rhash_sha3_384_init(sha3_ctx* ctx)
 {
 	rhash_keccak_init(ctx, 384);
 }
@@ -81,37 +81,37 @@
  *
  * @param ctx context to initialize
  */
-void rhash_sha3_512_init(sha3_ctx *ctx)
+void rhash_sha3_512_init(sha3_ctx* ctx)
 {
 	rhash_keccak_init(ctx, 512);
 }
 
+#define XORED_A(i) A[(i)] ^ A[(i) + 5] ^ A[(i) + 10] ^ A[(i) + 15] ^ A[(i) + 20]
+#define THETA_STEP(i) \
+	A[(i)]      ^= D[(i)]; \
+	A[(i) + 5]  ^= D[(i)]; \
+	A[(i) + 10] ^= D[(i)]; \
+	A[(i) + 15] ^= D[(i)]; \
+	A[(i) + 20] ^= D[(i)] \
+
 /* Keccak theta() transformation */
-static void keccak_theta(uint64_t *A)
+static void keccak_theta(uint64_t* A)
 {
-	unsigned int x;
-	uint64_t C[5], D[5];
-
-	for (x = 0; x < 5; x++) {
-		C[x] = A[x] ^ A[x + 5] ^ A[x + 10] ^ A[x + 15] ^ A[x + 20];
-	}
-	D[0] = ROTL64(C[1], 1) ^ C[4];
-	D[1] = ROTL64(C[2], 1) ^ C[0];
-	D[2] = ROTL64(C[3], 1) ^ C[1];
-	D[3] = ROTL64(C[4], 1) ^ C[2];
-	D[4] = ROTL64(C[0], 1) ^ C[3];
-
-	for (x = 0; x < 5; x++) {
-		A[x]      ^= D[x];
-		A[x + 5]  ^= D[x];
-		A[x + 10] ^= D[x];
-		A[x + 15] ^= D[x];
-		A[x + 20] ^= D[x];
-	}
+	uint64_t D[5];
+	D[0] = ROTL64(XORED_A(1), 1) ^ XORED_A(4);
+	D[1] = ROTL64(XORED_A(2), 1) ^ XORED_A(0);
+	D[2] = ROTL64(XORED_A(3), 1) ^ XORED_A(1);
+	D[3] = ROTL64(XORED_A(4), 1) ^ XORED_A(2);
+	D[4] = ROTL64(XORED_A(0), 1) ^ XORED_A(3);
+	THETA_STEP(0);
+	THETA_STEP(1);
+	THETA_STEP(2);
+	THETA_STEP(3);
+	THETA_STEP(4);
 }
 
 /* Keccak pi() transformation */
-static void keccak_pi(uint64_t *A)
+static void keccak_pi(uint64_t* A)
 {
 	uint64_t A1;
 	A1 = A[1];
@@ -142,21 +142,27 @@
 	/* note: A[ 0] is left as is */
 }
 
+#define CHI_STEP(i) \
+	A0 = A[0 + (i)]; \
+	A1 = A[1 + (i)]; \
+	A[0 + (i)] ^= ~A1 & A[2 + (i)]; \
+	A[1 + (i)] ^= ~A[2 + (i)] & A[3 + (i)]; \
+	A[2 + (i)] ^= ~A[3 + (i)] & A[4 + (i)]; \
+	A[3 + (i)] ^= ~A[4 + (i)] & A0; \
+	A[4 + (i)] ^= ~A0 & A1 \
+
 /* Keccak chi() transformation */
-static void keccak_chi(uint64_t *A)
+static void keccak_chi(uint64_t* A)
 {
-	int i;
-	for (i = 0; i < 25; i += 5) {
-		uint64_t A0 = A[0 + i], A1 = A[1 + i];
-		A[0 + i] ^= ~A1 & A[2 + i];
-		A[1 + i] ^= ~A[2 + i] & A[3 + i];
-		A[2 + i] ^= ~A[3 + i] & A[4 + i];
-		A[3 + i] ^= ~A[4 + i] & A0;
-		A[4 + i] ^= ~A0 & A1;
-	}
+	uint64_t A0, A1;
+	CHI_STEP(0);
+	CHI_STEP(5);
+	CHI_STEP(10);
+	CHI_STEP(15);
+	CHI_STEP(20);
 }
 
-static void rhash_sha3_permutation(uint64_t *state)
+static void rhash_sha3_permutation(uint64_t* state)
 {
 	int round;
 	for (round = 0; round < NumberOfRounds; round++)
@@ -204,7 +210,7 @@
  * @param block the message block to process
  * @param block_size the size of the processed block in bytes
  */
-static void rhash_sha3_process_block(uint64_t hash[25], const uint64_t *block, size_t block_size)
+static void rhash_sha3_process_block(uint64_t hash[25], const uint64_t* block, size_t block_size)
 {
 	/* expanded loop */
 	hash[ 0] ^= le2me_64(block[ 0]);
@@ -260,7 +266,7 @@
  * @param msg message chunk
  * @param size length of the message chunk
  */
-void rhash_sha3_update(sha3_ctx *ctx, const unsigned char *msg, size_t size)
+void rhash_sha3_update(sha3_ctx* ctx, const unsigned char* msg, size_t size)
 {
 	size_t index = (size_t)ctx->rest;
 	size_t block_size = (size_t)ctx->block_size;
@@ -305,7 +311,7 @@
  * @param ctx the algorithm context containing current hashing state
  * @param result calculated hash in binary form
  */
-void rhash_sha3_final(sha3_ctx *ctx, unsigned char* result)
+void rhash_sha3_final(sha3_ctx* ctx, unsigned char* result)
 {
 	size_t digest_length = 100 - ctx->block_size / 2;
 	const size_t block_size = ctx->block_size;
@@ -333,7 +339,7 @@
 * @param ctx the algorithm context containing current hashing state
 * @param result calculated hash in binary form
 */
-void rhash_keccak_final(sha3_ctx *ctx, unsigned char* result)
+void rhash_keccak_final(sha3_ctx* ctx, unsigned char* result)
 {
 	size_t digest_length = 100 - ctx->block_size / 2;
 	const size_t block_size = ctx->block_size;
diff --git a/Utilities/cmlibrhash/librhash/sha3.h b/Utilities/cmlibrhash/librhash/sha3.h
index 2831997..e00041d 100644
--- a/Utilities/cmlibrhash/librhash/sha3.h
+++ b/Utilities/cmlibrhash/librhash/sha3.h
@@ -31,12 +31,12 @@
 
 /* methods for calculating the hash function */
 
-void rhash_sha3_224_init(sha3_ctx *ctx);
-void rhash_sha3_256_init(sha3_ctx *ctx);
-void rhash_sha3_384_init(sha3_ctx *ctx);
-void rhash_sha3_512_init(sha3_ctx *ctx);
-void rhash_sha3_update(sha3_ctx *ctx, const unsigned char* msg, size_t size);
-void rhash_sha3_final(sha3_ctx *ctx, unsigned char* result);
+void rhash_sha3_224_init(sha3_ctx* ctx);
+void rhash_sha3_256_init(sha3_ctx* ctx);
+void rhash_sha3_384_init(sha3_ctx* ctx);
+void rhash_sha3_512_init(sha3_ctx* ctx);
+void rhash_sha3_update(sha3_ctx* ctx, const unsigned char* msg, size_t size);
+void rhash_sha3_final(sha3_ctx* ctx, unsigned char* result);
 
 #ifdef USE_KECCAK
 #define rhash_keccak_224_init rhash_sha3_224_init
@@ -44,7 +44,7 @@
 #define rhash_keccak_384_init rhash_sha3_384_init
 #define rhash_keccak_512_init rhash_sha3_512_init
 #define rhash_keccak_update rhash_sha3_update
-void rhash_keccak_final(sha3_ctx *ctx, unsigned char* result);
+void rhash_keccak_final(sha3_ctx* ctx, unsigned char* result);
 #endif
 
 #ifdef __cplusplus
diff --git a/Utilities/cmlibrhash/librhash/sha512.c b/Utilities/cmlibrhash/librhash/sha512.c
index a3e681d..555e6ef 100644
--- a/Utilities/cmlibrhash/librhash/sha512.c
+++ b/Utilities/cmlibrhash/librhash/sha512.c
@@ -1,18 +1,18 @@
 /* sha512.c - an implementation of SHA-384/512 hash functions
  * based on FIPS 180-3 (Federal Information Processing Standart).
  *
- * Copyright: 2010-2012 Aleksey Kravchenko <rhash.admin@gmail.com>
+ * Copyright (c) 2010, Aleksey Kravchenko <rhash.admin@gmail.com>
  *
- * Permission is hereby granted,  free of charge,  to any person  obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction,  including without limitation
- * the rights to  use, copy, modify,  merge, publish, distribute, sublicense,
- * and/or sell copies  of  the Software,  and to permit  persons  to whom the
- * Software is furnished to do so.
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted.
  *
- * This program  is  distributed  in  the  hope  that it will be useful,  but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  Use this program  at  your own risk!
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE  INCLUDING ALL IMPLIED WARRANTIES OF  MERCHANTABILITY
+ * AND FITNESS.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT,  OR CONSEQUENTIAL DAMAGES  OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE,  DATA OR PROFITS,  WHETHER IN AN ACTION OF CONTRACT,  NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION,  ARISING OUT OF  OR IN CONNECTION  WITH THE USE  OR
+ * PERFORMANCE OF THIS SOFTWARE.
  */
 
 #include <string.h>
@@ -81,7 +81,7 @@
  *
  * @param ctx context to initialize
  */
-void rhash_sha512_init(sha512_ctx *ctx)
+void rhash_sha512_init(sha512_ctx* ctx)
 {
 	/* Initial values. These words were obtained by taking the first 32
 	 * bits of the fractional parts of the square roots of the first
@@ -104,7 +104,7 @@
  *
  * @param ctx context to initialize
  */
-void rhash_sha384_init(struct sha512_ctx *ctx)
+void rhash_sha384_init(struct sha512_ctx* ctx)
 {
 	/* Initial values from FIPS 180-3. These words were obtained by taking
 	 * the first sixty-four bits of the fractional parts of the square
@@ -131,7 +131,7 @@
 {
 	uint64_t A, B, C, D, E, F, G, H;
 	uint64_t W[16];
-	const uint64_t *k;
+	const uint64_t* k;
 	int i;
 
 	A = hash[0], B = hash[1], C = hash[2], D = hash[3];
@@ -186,7 +186,7 @@
  * @param msg message chunk
  * @param size length of the message chunk
  */
-void rhash_sha512_update(sha512_ctx *ctx, const unsigned char *msg, size_t size)
+void rhash_sha512_update(sha512_ctx* ctx, const unsigned char* msg, size_t size)
 {
 	size_t index = (size_t)ctx->length & 127;
 	ctx->length += size;
@@ -228,7 +228,7 @@
  * @param ctx the algorithm context containing current hashing state
  * @param result calculated hash in binary form
  */
-void rhash_sha512_final(sha512_ctx *ctx, unsigned char* result)
+void rhash_sha512_final(sha512_ctx* ctx, unsigned char* result)
 {
 	size_t index = ((unsigned)ctx->length & 127) >> 3;
 	unsigned shift = ((unsigned)ctx->length & 7) * 8;
diff --git a/Utilities/cmlibrhash/librhash/sha512.h b/Utilities/cmlibrhash/librhash/sha512.h
index 7c689be..f80ae0d 100644
--- a/Utilities/cmlibrhash/librhash/sha512.h
+++ b/Utilities/cmlibrhash/librhash/sha512.h
@@ -20,10 +20,10 @@
 	unsigned digest_length; /* length of the algorithm digest in bytes */
 } sha512_ctx;
 
-void rhash_sha384_init(sha512_ctx *ctx);
-void rhash_sha512_init(sha512_ctx *ctx);
-void rhash_sha512_update(sha512_ctx *ctx, const unsigned char* data, size_t length);
-void rhash_sha512_final(sha512_ctx *ctx, unsigned char* result);
+void rhash_sha384_init(sha512_ctx* ctx);
+void rhash_sha512_init(sha512_ctx* ctx);
+void rhash_sha512_update(sha512_ctx* ctx, const unsigned char* data, size_t length);
+void rhash_sha512_final(sha512_ctx* ctx, unsigned char* result);
 
 #ifdef __cplusplus
 } /* extern "C" */
diff --git a/Utilities/cmlibrhash/librhash/ustd.h b/Utilities/cmlibrhash/librhash/ustd.h
index 019b931..756ce0b 100644
--- a/Utilities/cmlibrhash/librhash/ustd.h
+++ b/Utilities/cmlibrhash/librhash/ustd.h
@@ -9,7 +9,7 @@
 # pragma warning(push,1)
 #endif
 
-#include <cm_kwiml.h>
+#include <cm3p/kwiml/int.h>
 
 #ifndef KWIML_INT_HAVE_INT64_T
 # define int64_t KWIML_INT_int64_t
@@ -36,4 +36,36 @@
 # define uint8_t KWIML_INT_uint8_t
 #endif
 
+#include <stddef.h>
+
+#if 0
+#if _MSC_VER > 1000
+# include <stddef.h> /* size_t for vc6.0 */
+
+# if _MSC_VER >= 1600
+/* Visual Studio >= 2010 has stdint.h */
+#  include <stdint.h>
+# else
+  /* vc6.0 has bug with __int8, so using char instead */
+  typedef signed char       int8_t;
+  typedef signed __int16    int16_t;
+  typedef signed __int32    int32_t;
+  typedef signed __int64    int64_t;
+  typedef unsigned char     uint8_t;
+  typedef unsigned __int16  uint16_t;
+  typedef unsigned __int32  uint32_t;
+  typedef unsigned __int64  uint64_t;
+# endif /* _MSC_VER >= 1600 */
+
+/* disable warnings: The POSIX name for this item is deprecated. Use the ISO C++ conformant name. */
+# pragma warning(disable : 4996)
+
+#else /* _MSC_VER > 1000 */
+
+# include <stdint.h>
+# include <unistd.h>
+
+#endif /* _MSC_VER > 1000 */
+#endif
+
 #endif /* LIBRHASH_USTD_H */
diff --git a/Utilities/cmlibrhash/librhash/util.h b/Utilities/cmlibrhash/librhash/util.h
index 9f37157..57cae9b 100644
--- a/Utilities/cmlibrhash/librhash/util.h
+++ b/Utilities/cmlibrhash/librhash/util.h
@@ -20,7 +20,7 @@
 # define atomic_compare_and_swap(ptr, oldval, newval) atomic_cas_32(ptr, oldval, newval)
 #else
 /* pray that it will work */
-# define atomic_compare_and_swap(ptr, oldval, newval) { if(*(ptr) == (oldval)) *(ptr) = (newval); }
+# define atomic_compare_and_swap(ptr, oldval, newval) { if (*(ptr) == (oldval)) *(ptr) = (newval); }
 # define NO_ATOMIC_BUILTINS
 #endif
 
diff --git a/Utilities/cmlibuv/include/uv.h b/Utilities/cmlibuv/include/uv.h
index eb80bfb..6f32b48 100644
--- a/Utilities/cmlibuv/include/uv.h
+++ b/Utilities/cmlibuv/include/uv.h
@@ -31,6 +31,10 @@
 extern "C" {
 #endif
 
+#if defined(BUILDING_UV_SHARED) && defined(USING_UV_SHARED)
+#error "Define either BUILDING_UV_SHARED or USING_UV_SHARED, not both."
+#endif
+
 #ifdef _WIN32
   /* Windows - set up dll import/export decorators. */
 # if defined(BUILDING_UV_SHARED)
@@ -147,6 +151,7 @@
   XX(EREMOTEIO, "remote I/O error")                                           \
   XX(ENOTTY, "inappropriate ioctl for device")                                \
   XX(EFTYPE, "inappropriate file type or format")                             \
+  XX(EILSEQ, "illegal byte sequence")                                         \
 
 #define UV_HANDLE_TYPE_MAP(XX)                                                \
   XX(ASYNC, async)                                                            \
@@ -176,6 +181,7 @@
   XX(WORK, work)                                                              \
   XX(GETADDRINFO, getaddrinfo)                                                \
   XX(GETNAMEINFO, getnameinfo)                                                \
+  XX(RANDOM, random)                                                          \
 
 typedef enum {
 #define XX(code, _) UV_ ## code = UV__ ## code,
@@ -233,13 +239,16 @@
 typedef struct uv_udp_send_s uv_udp_send_t;
 typedef struct uv_fs_s uv_fs_t;
 typedef struct uv_work_s uv_work_t;
+typedef struct uv_random_s uv_random_t;
 
 /* None of the above. */
+typedef struct uv_env_item_s uv_env_item_t;
 typedef struct uv_cpu_info_s uv_cpu_info_t;
 typedef struct uv_interface_address_s uv_interface_address_t;
 typedef struct uv_dirent_s uv_dirent_t;
 typedef struct uv_passwd_s uv_passwd_t;
 typedef struct uv_utsname_s uv_utsname_t;
+typedef struct uv_statfs_s uv_statfs_t;
 
 typedef enum {
   UV_LOOP_BLOCK_SIGNAL
@@ -260,6 +269,8 @@
 typedef void* (*uv_calloc_func)(size_t count, size_t size);
 typedef void (*uv_free_func)(void* ptr);
 
+UV_EXTERN void uv_library_shutdown(void);
+
 UV_EXTERN int uv_replace_allocator(uv_malloc_func malloc_func,
                                    uv_realloc_func realloc_func,
                                    uv_calloc_func calloc_func,
@@ -327,6 +338,10 @@
                                   int status,
                                   const char* hostname,
                                   const char* service);
+typedef void (*uv_random_cb)(uv_random_t* req,
+                             int status,
+                             void* buf,
+                             size_t buflen);
 
 typedef struct {
   long tv_sec;
@@ -561,6 +576,7 @@
 UV_EXTERN int uv_tcp_getpeername(const uv_tcp_t* handle,
                                  struct sockaddr* name,
                                  int* namelen);
+UV_EXTERN int uv_tcp_close_reset(uv_tcp_t* handle, uv_close_cb close_cb);
 UV_EXTERN int uv_tcp_connect(uv_connect_t* req,
                              uv_tcp_t* handle,
                              const struct sockaddr* addr,
@@ -595,7 +611,17 @@
    * (provided they all set the flag) but only the last one to bind will receive
    * any traffic, in effect "stealing" the port from the previous listener.
    */
-  UV_UDP_REUSEADDR = 4
+  UV_UDP_REUSEADDR = 4,
+  /*
+   * Indicates that the message was received by recvmmsg, so the buffer provided
+   * must not be freed by the recv_cb callback.
+   */
+  UV_UDP_MMSG_CHUNK = 8,
+
+  /*
+   * Indicates that recvmmsg should be used, if available.
+   */
+  UV_UDP_RECVMMSG = 256
 };
 
 typedef void (*uv_udp_send_cb)(uv_udp_send_t* req, int status);
@@ -647,6 +673,11 @@
                                     const char* multicast_addr,
                                     const char* interface_addr,
                                     uv_membership membership);
+UV_EXTERN int uv_udp_set_source_membership(uv_udp_t* handle,
+                                           const char* multicast_addr,
+                                           const char* interface_addr,
+                                           const char* source_addr,
+                                           uv_membership membership);
 UV_EXTERN int uv_udp_set_multicast_loop(uv_udp_t* handle, int on);
 UV_EXTERN int uv_udp_set_multicast_ttl(uv_udp_t* handle, int ttl);
 UV_EXTERN int uv_udp_set_multicast_interface(uv_udp_t* handle,
@@ -691,10 +722,25 @@
   UV_TTY_MODE_IO
 } uv_tty_mode_t;
 
+typedef enum {
+  /*
+   * The console supports handling of virtual terminal sequences
+   * (Windows10 new console, ConEmu)
+   */
+  UV_TTY_SUPPORTED,
+  /* The console cannot process the virtual terminal sequence.  (Legacy
+   * console)
+   */
+  UV_TTY_UNSUPPORTED
+} uv_tty_vtermstate_t;
+
+
 UV_EXTERN int uv_tty_init(uv_loop_t*, uv_tty_t*, uv_file fd, int readable);
 UV_EXTERN int uv_tty_set_mode(uv_tty_t*, uv_tty_mode_t mode);
 UV_EXTERN int uv_tty_reset_mode(void);
 UV_EXTERN int uv_tty_get_winsize(uv_tty_t*, int* width, int* height);
+UV_EXTERN void uv_tty_set_vterm_state(uv_tty_vtermstate_t state);
+UV_EXTERN int uv_tty_get_vterm_state(uv_tty_vtermstate_t* state);
 
 #ifdef __cplusplus
 extern "C++" {
@@ -1042,11 +1088,11 @@
 
 
 struct uv_cpu_times_s {
-  uint64_t user;
-  uint64_t nice;
-  uint64_t sys;
-  uint64_t idle;
-  uint64_t irq;
+  uint64_t user; /* milliseconds */
+  uint64_t nice; /* milliseconds */
+  uint64_t sys; /* milliseconds */
+  uint64_t idle; /* milliseconds */
+  uint64_t irq; /* milliseconds */
 };
 
 struct uv_cpu_info_s {
@@ -1087,6 +1133,17 @@
      to as meaningless in the docs. */
 };
 
+struct uv_statfs_s {
+  uint64_t f_type;
+  uint64_t f_bsize;
+  uint64_t f_blocks;
+  uint64_t f_bfree;
+  uint64_t f_bavail;
+  uint64_t f_files;
+  uint64_t f_ffree;
+  uint64_t f_spare[4];
+};
+
 typedef enum {
   UV_DIRENT_UNKNOWN,
   UV_DIRENT_FILE,
@@ -1149,12 +1206,22 @@
 UV_EXTERN uv_pid_t uv_os_getpid(void);
 UV_EXTERN uv_pid_t uv_os_getppid(void);
 
-#define UV_PRIORITY_LOW 19
-#define UV_PRIORITY_BELOW_NORMAL 10
-#define UV_PRIORITY_NORMAL 0
-#define UV_PRIORITY_ABOVE_NORMAL -7
-#define UV_PRIORITY_HIGH -14
-#define UV_PRIORITY_HIGHEST -20
+#if defined(__PASE__)
+/* On IBM i PASE, the highest process priority is -10 */
+# define UV_PRIORITY_LOW 39            // RUNPTY(99)
+# define UV_PRIORITY_BELOW_NORMAL 15   // RUNPTY(50)
+# define UV_PRIORITY_NORMAL 0          // RUNPTY(20)
+# define UV_PRIORITY_ABOVE_NORMAL -4   // RUNTY(12)
+# define UV_PRIORITY_HIGH -7           // RUNPTY(6)
+# define UV_PRIORITY_HIGHEST -10       // RUNPTY(1)
+#else
+# define UV_PRIORITY_LOW 19
+# define UV_PRIORITY_BELOW_NORMAL 10
+# define UV_PRIORITY_NORMAL 0
+# define UV_PRIORITY_ABOVE_NORMAL -7
+# define UV_PRIORITY_HIGH -14
+# define UV_PRIORITY_HIGHEST -20
+#endif
 
 UV_EXTERN int uv_os_getpriority(uv_pid_t pid, int* priority);
 UV_EXTERN int uv_os_setpriority(uv_pid_t pid, int priority);
@@ -1168,6 +1235,13 @@
 UV_EXTERN void uv_free_interface_addresses(uv_interface_address_t* addresses,
                                            int count);
 
+struct uv_env_item_s {
+  char* name;
+  char* value;
+};
+
+UV_EXTERN int uv_os_environ(uv_env_item_t** envitems, int* count);
+UV_EXTERN void uv_os_free_environ(uv_env_item_t* envitems, int count);
 UV_EXTERN int uv_os_getenv(const char* name, char* buffer, size_t* size);
 UV_EXTERN int uv_os_setenv(const char* name, const char* value);
 UV_EXTERN int uv_os_unsetenv(const char* name);
@@ -1223,7 +1297,10 @@
   UV_FS_LCHOWN,
   UV_FS_OPENDIR,
   UV_FS_READDIR,
-  UV_FS_CLOSEDIR
+  UV_FS_CLOSEDIR,
+  UV_FS_STATFS,
+  UV_FS_MKSTEMP,
+  UV_FS_LUTIME
 } uv_fs_type;
 
 struct uv_dir_s {
@@ -1248,6 +1325,7 @@
 
 UV_EXTERN uv_fs_type uv_fs_get_type(const uv_fs_t*);
 UV_EXTERN ssize_t uv_fs_get_result(const uv_fs_t*);
+UV_EXTERN int uv_fs_get_system_error(const uv_fs_t*);
 UV_EXTERN void* uv_fs_get_ptr(const uv_fs_t*);
 UV_EXTERN const char* uv_fs_get_path(const uv_fs_t*);
 UV_EXTERN uv_stat_t* uv_fs_get_statbuf(uv_fs_t*);
@@ -1314,6 +1392,10 @@
                             uv_fs_t* req,
                             const char* tpl,
                             uv_fs_cb cb);
+UV_EXTERN int uv_fs_mkstemp(uv_loop_t* loop,
+                            uv_fs_t* req,
+                            const char* tpl,
+                            uv_fs_cb cb);
 UV_EXTERN int uv_fs_rmdir(uv_loop_t* loop,
                           uv_fs_t* req,
                           const char* path,
@@ -1392,6 +1474,12 @@
                            double atime,
                            double mtime,
                            uv_fs_cb cb);
+UV_EXTERN int uv_fs_lutime(uv_loop_t* loop,
+                           uv_fs_t* req,
+                           const char* path,
+                           double atime,
+                           double mtime,
+                           uv_fs_cb cb);
 UV_EXTERN int uv_fs_lstat(uv_loop_t* loop,
                           uv_fs_t* req,
                           const char* path,
@@ -1451,6 +1539,10 @@
                            uv_uid_t uid,
                            uv_gid_t gid,
                            uv_fs_cb cb);
+UV_EXTERN int uv_fs_statfs(uv_loop_t* loop,
+                           uv_fs_t* req,
+                           const char* path,
+                           uv_fs_cb cb);
 
 
 enum uv_fs_event {
@@ -1556,6 +1648,26 @@
 UV_EXTERN int uv_inet_ntop(int af, const void* src, char* dst, size_t size);
 UV_EXTERN int uv_inet_pton(int af, const char* src, void* dst);
 
+
+struct uv_random_s {
+  UV_REQ_FIELDS
+  /* read-only */
+  uv_loop_t* loop;
+  /* private */
+  int status;
+  void* buf;
+  size_t buflen;
+  uv_random_cb cb;
+  struct uv__work work_req;
+};
+
+UV_EXTERN int uv_random(uv_loop_t* loop,
+                        uv_random_t* req,
+                        void *buf,
+                        size_t buflen,
+                        unsigned flags,  /* For future extension; must be 0. */
+                        uv_random_cb cb);
+
 #if defined(IF_NAMESIZE)
 # define UV_IF_NAMESIZE (IF_NAMESIZE + 1)
 #elif defined(IFNAMSIZ)
@@ -1582,6 +1694,7 @@
 UV_EXTERN uint64_t uv_get_constrained_memory(void);
 
 UV_EXTERN uint64_t uv_hrtime(void);
+UV_EXTERN void uv_sleep(unsigned int msec);
 
 UV_EXTERN void uv_disable_stdio_inheritance(void);
 
diff --git a/Utilities/cmlibuv/include/uv/errno.h b/Utilities/cmlibuv/include/uv/errno.h
index 8eeb95d..165fd11 100644
--- a/Utilities/cmlibuv/include/uv/errno.h
+++ b/Utilities/cmlibuv/include/uv/errno.h
@@ -439,5 +439,10 @@
 # define UV__EFTYPE (-4028)
 #endif
 
+#if defined(EILSEQ) && !defined(_WIN32)
+# define UV__EILSEQ UV__ERR(EILSEQ)
+#else
+# define UV__EILSEQ (-4027)
+#endif
 
 #endif /* UV_ERRNO_H_ */
diff --git a/Utilities/cmlibuv/include/uv/unix.h b/Utilities/cmlibuv/include/uv/unix.h
index 4e26108..f30562e 100644
--- a/Utilities/cmlibuv/include/uv/unix.h
+++ b/Utilities/cmlibuv/include/uv/unix.h
@@ -47,10 +47,15 @@
 
 #ifdef CMAKE_BOOTSTRAP
 # include "posix.h"
+# if defined(__APPLE__)
+#  include <TargetConditionals.h>
+# endif
 #elif defined(__linux__)
 # include "linux.h"
 #elif defined (__MVS__)
 # include "os390.h"
+#elif defined(__PASE__)  /* __PASE__ and _AIX are both defined on IBM i */
+# include "posix.h"  /* IBM i needs uv/posix.h, not uv/aix.h */
 #elif defined(_AIX)
 # include "aix.h"
 #elif defined(__sun)
@@ -65,8 +70,7 @@
       defined(__OpenBSD__)         || \
       defined(__NetBSD__)
 # include "bsd.h"
-#elif defined(__PASE__)   || \
-      defined(__CYGWIN__) || \
+#elif defined(__CYGWIN__) || \
       defined(__MSYS__)   || \
       defined(__GNU__)
 # include "posix.h"
@@ -421,11 +425,25 @@
 #else
 # define UV_FS_O_CREAT        0
 #endif
-#if defined(O_DIRECT)
+
+#if defined(__linux__) && defined(__arm__)
+# define UV_FS_O_DIRECT       0x10000
+#elif defined(__linux__) && defined(__m68k__)
+# define UV_FS_O_DIRECT       0x10000
+#elif defined(__linux__) && defined(__mips__)
+# define UV_FS_O_DIRECT       0x08000
+#elif defined(__linux__) && defined(__powerpc__)
+# define UV_FS_O_DIRECT       0x20000
+#elif defined(__linux__) && defined(__s390x__)
+# define UV_FS_O_DIRECT       0x04000
+#elif defined(__linux__) && defined(__x86_64__)
+# define UV_FS_O_DIRECT       0x04000
+#elif defined(O_DIRECT)
 # define UV_FS_O_DIRECT       O_DIRECT
 #else
 # define UV_FS_O_DIRECT       0
 #endif
+
 #if defined(O_DIRECTORY)
 # define UV_FS_O_DIRECTORY    O_DIRECTORY
 #else
@@ -498,6 +516,7 @@
 #endif
 
 /* fs open() flags supported on other platforms: */
+#define UV_FS_O_FILEMAP       0
 #define UV_FS_O_RANDOM        0
 #define UV_FS_O_SHORT_LIVED   0
 #define UV_FS_O_SEQUENTIAL    0
diff --git a/Utilities/cmlibuv/include/uv/version.h b/Utilities/cmlibuv/include/uv/version.h
index 97f0bc2..f932483 100644
--- a/Utilities/cmlibuv/include/uv/version.h
+++ b/Utilities/cmlibuv/include/uv/version.h
@@ -26,13 +26,13 @@
  * Versions with the same major number are ABI stable. API is allowed to
  * evolve between minor releases, but only in a backwards compatible way.
  * Make sure you update the -soname directives in configure.ac
- * and uv.gyp whenever you bump UV_VERSION_MAJOR or UV_VERSION_MINOR (but
+ * whenever you bump UV_VERSION_MAJOR or UV_VERSION_MINOR (but
  * not UV_VERSION_PATCH.)
  */
 
 #define UV_VERSION_MAJOR 1
-#define UV_VERSION_MINOR 29
-#define UV_VERSION_PATCH 2
+#define UV_VERSION_MINOR 37
+#define UV_VERSION_PATCH 1
 #define UV_VERSION_IS_RELEASE 0
 #define UV_VERSION_SUFFIX "dev"
 
diff --git a/Utilities/cmlibuv/include/uv/win.h b/Utilities/cmlibuv/include/uv/win.h
index 7f77cc2..f86357b 100644
--- a/Utilities/cmlibuv/include/uv/win.h
+++ b/Utilities/cmlibuv/include/uv/win.h
@@ -528,7 +528,7 @@
       /* eol conversion state */                                              \
       unsigned char previous_eol;                                             \
       /* ansi parser state */                                                 \
-      unsigned char ansi_parser_state;                                        \
+      unsigned short ansi_parser_state;                                       \
       unsigned char ansi_csi_argc;                                            \
       unsigned short ansi_csi_argv[4];                                        \
       COORD saved_position;                                                   \
@@ -679,6 +679,7 @@
 #define UV_FS_O_APPEND       _O_APPEND
 #define UV_FS_O_CREAT        _O_CREAT
 #define UV_FS_O_EXCL         _O_EXCL
+#define UV_FS_O_FILEMAP      0x20000000
 #define UV_FS_O_RANDOM       _O_RANDOM
 #define UV_FS_O_RDONLY       _O_RDONLY
 #define UV_FS_O_RDWR         _O_RDWR
diff --git a/Utilities/cmlibuv/src/random.c b/Utilities/cmlibuv/src/random.c
new file mode 100644
index 0000000..491bf70
--- /dev/null
+++ b/Utilities/cmlibuv/src/random.c
@@ -0,0 +1,123 @@
+/* Copyright libuv contributors. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#include "uv.h"
+#include "uv-common.h"
+
+#ifdef _WIN32
+#  include "win/internal.h"
+#else
+#  include "unix/internal.h"
+#endif
+
+static int uv__random(void* buf, size_t buflen) {
+  int rc;
+
+#if defined(__PASE__)
+  rc = uv__random_readpath("/dev/urandom", buf, buflen);
+#elif defined(_AIX)
+  rc = uv__random_readpath("/dev/random", buf, buflen);
+#elif defined(__APPLE__) || defined(__OpenBSD__) || \
+     (defined(__ANDROID_API__) && __ANDROID_API__ >= 28)
+  rc = uv__random_getentropy(buf, buflen);
+  if (rc == UV_ENOSYS)
+    rc = uv__random_devurandom(buf, buflen);
+#elif defined(__NetBSD__)
+  rc = uv__random_sysctl(buf, buflen);
+#elif defined(__FreeBSD__) || defined(__linux__)
+  rc = uv__random_getrandom(buf, buflen);
+  if (rc == UV_ENOSYS)
+    rc = uv__random_devurandom(buf, buflen);
+# if defined(__linux__)
+  switch (rc) {
+    case UV_EACCES:
+    case UV_EIO:
+    case UV_ELOOP:
+    case UV_EMFILE:
+    case UV_ENFILE:
+    case UV_ENOENT:
+    case UV_EPERM:
+      rc = uv__random_sysctl(buf, buflen);
+      break;
+  }
+# endif
+#elif defined(_WIN32)
+  uv__once_init();
+  rc = uv__random_rtlgenrandom(buf, buflen);
+#else
+  rc = uv__random_devurandom(buf, buflen);
+#endif
+
+  return rc;
+}
+
+
+static void uv__random_work(struct uv__work* w) {
+  uv_random_t* req;
+
+  req = container_of(w, uv_random_t, work_req);
+  req->status = uv__random(req->buf, req->buflen);
+}
+
+
+static void uv__random_done(struct uv__work* w, int status) {
+  uv_random_t* req;
+
+  req = container_of(w, uv_random_t, work_req);
+  uv__req_unregister(req->loop, req);
+
+  if (status == 0)
+    status = req->status;
+
+  req->cb(req, status, req->buf, req->buflen);
+}
+
+
+int uv_random(uv_loop_t* loop,
+              uv_random_t* req,
+              void *buf,
+              size_t buflen,
+              unsigned flags,
+              uv_random_cb cb) {
+  if (buflen > 0x7FFFFFFFu)
+    return UV_E2BIG;
+
+  if (flags != 0)
+    return UV_EINVAL;
+
+  if (cb == NULL)
+    return uv__random(buf, buflen);
+
+  uv__req_init(loop, req, UV_RANDOM);
+  req->loop = loop;
+  req->status = 0;
+  req->cb = cb;
+  req->buf = buf;
+  req->buflen = buflen;
+
+  uv__work_submit(loop,
+                  &req->work_req,
+                  UV__WORK_CPU,
+                  uv__random_work,
+                  uv__random_done);
+
+  return 0;
+}
diff --git a/Utilities/cmlibuv/src/threadpool.c b/Utilities/cmlibuv/src/threadpool.c
index 7aa5755..0998938 100644
--- a/Utilities/cmlibuv/src/threadpool.c
+++ b/Utilities/cmlibuv/src/threadpool.c
@@ -160,8 +160,8 @@
 }
 
 
+void uv__threadpool_cleanup(void) {
 #ifndef _WIN32
-UV_DESTRUCTOR(static void cleanup(void)) {
   unsigned int i;
 
   if (nthreads == 0)
@@ -181,8 +181,8 @@
 
   threads = NULL;
   nthreads = 0;
-}
 #endif
+}
 
 
 static void init_threads(void) {
@@ -372,6 +372,10 @@
     loop = ((uv_getnameinfo_t*) req)->loop;
     wreq = &((uv_getnameinfo_t*) req)->work_req;
     break;
+  case UV_RANDOM:
+    loop = ((uv_random_t*) req)->loop;
+    wreq = &((uv_random_t*) req)->work_req;
+    break;
   case UV_WORK:
     loop =  ((uv_work_t*) req)->loop;
     wreq = &((uv_work_t*) req)->work_req;
diff --git a/Utilities/cmlibuv/src/timer.c b/Utilities/cmlibuv/src/timer.c
index dd78bcb..4cf4ed4 100644
--- a/Utilities/cmlibuv/src/timer.c
+++ b/Utilities/cmlibuv/src/timer.c
@@ -51,12 +51,7 @@
   /* Compare start_id when both have the same timeout. start_id is
    * allocated with loop->timer_counter in uv_timer_start().
    */
-  if (a->start_id < b->start_id)
-    return 1;
-  if (b->start_id < a->start_id)
-    return 0;
-
-  return 0;
+  return a->start_id < b->start_id;
 }
 
 
@@ -74,7 +69,7 @@
                    uint64_t repeat) {
   uint64_t clamped_timeout;
 
-  if (cb == NULL)
+  if (uv__is_closing(handle) || cb == NULL)
     return UV_EINVAL;
 
   if (uv__is_active(handle))
@@ -87,7 +82,7 @@
   handle->timer_cb = cb;
   handle->timeout = clamped_timeout;
   handle->repeat = repeat;
-  /* start_id is the second index to be compared in uv__timer_cmp() */
+  /* start_id is the second index to be compared in timer_less_than() */
   handle->start_id = handle->loop->timer_counter++;
 
   heap_insert(timer_heap(handle->loop),
diff --git a/Utilities/cmlibuv/src/unix/aix-common.c b/Utilities/cmlibuv/src/unix/aix-common.c
index e9697e9..44c87b1 100644
--- a/Utilities/cmlibuv/src/unix/aix-common.c
+++ b/Utilities/cmlibuv/src/unix/aix-common.c
@@ -34,6 +34,7 @@
 #include <sys/ioctl.h>
 #include <net/if.h>
 #include <netinet/in.h>
+#include <netinet/in6_var.h>
 #include <arpa/inet.h>
 
 #include <sys/time.h>
@@ -155,144 +156,3 @@
   }
 }
 
-void uv_free_cpu_info(uv_cpu_info_t* cpu_infos, int count) {
-  int i;
-
-  for (i = 0; i < count; ++i) {
-    uv__free(cpu_infos[i].model);
-  }
-
-  uv__free(cpu_infos);
-}
-
-
-int uv_interface_addresses(uv_interface_address_t** addresses, int* count) {
-  uv_interface_address_t* address;
-  int sockfd, inet6, size = 1;
-  struct ifconf ifc;
-  struct ifreq *ifr, *p, flg;
-  struct sockaddr_dl* sa_addr;
-
-  *count = 0;
-  *addresses = NULL;
-
-  if (0 > (sockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP))) {
-    return UV__ERR(errno);
-  }
-
-  if (ioctl(sockfd, SIOCGSIZIFCONF, &size) == -1) {
-    uv__close(sockfd);
-    return UV__ERR(errno);
-  }
-
-  ifc.ifc_req = (struct ifreq*)uv__malloc(size);
-  ifc.ifc_len = size;
-  if (ioctl(sockfd, SIOCGIFCONF, &ifc) == -1) {
-    uv__close(sockfd);
-    return UV__ERR(errno);
-  }
-
-#define ADDR_SIZE(p) MAX((p).sa_len, sizeof(p))
-
-  /* Count all up and running ipv4/ipv6 addresses */
-  ifr = ifc.ifc_req;
-  while ((char*)ifr < (char*)ifc.ifc_req + ifc.ifc_len) {
-    p = ifr;
-    ifr = (struct ifreq*)
-      ((char*)ifr + sizeof(ifr->ifr_name) + ADDR_SIZE(ifr->ifr_addr));
-
-    if (!(p->ifr_addr.sa_family == AF_INET6 ||
-          p->ifr_addr.sa_family == AF_INET))
-      continue;
-
-    memcpy(flg.ifr_name, p->ifr_name, sizeof(flg.ifr_name));
-    if (ioctl(sockfd, SIOCGIFFLAGS, &flg) == -1) {
-      uv__close(sockfd);
-      return UV__ERR(errno);
-    }
-
-    if (!(flg.ifr_flags & IFF_UP && flg.ifr_flags & IFF_RUNNING))
-      continue;
-
-    (*count)++;
-  }
-
-  if (*count == 0) {
-    uv__close(sockfd);
-    return 0;
-  }
-
-  /* Alloc the return interface structs */
-  *addresses = uv__malloc(*count * sizeof(uv_interface_address_t));
-  if (!(*addresses)) {
-    uv__close(sockfd);
-    return UV_ENOMEM;
-  }
-  address = *addresses;
-
-  ifr = ifc.ifc_req;
-  while ((char*)ifr < (char*)ifc.ifc_req + ifc.ifc_len) {
-    p = ifr;
-    ifr = (struct ifreq*)
-      ((char*)ifr + sizeof(ifr->ifr_name) + ADDR_SIZE(ifr->ifr_addr));
-
-    if (!(p->ifr_addr.sa_family == AF_INET6 ||
-          p->ifr_addr.sa_family == AF_INET))
-      continue;
-
-    inet6 = (p->ifr_addr.sa_family == AF_INET6);
-
-    memcpy(flg.ifr_name, p->ifr_name, sizeof(flg.ifr_name));
-    if (ioctl(sockfd, SIOCGIFFLAGS, &flg) == -1) {
-      uv__close(sockfd);
-      return UV_ENOSYS;
-    }
-
-    if (!(flg.ifr_flags & IFF_UP && flg.ifr_flags & IFF_RUNNING))
-      continue;
-
-    /* All conditions above must match count loop */
-
-    address->name = uv__strdup(p->ifr_name);
-
-    if (inet6)
-      address->address.address6 = *((struct sockaddr_in6*) &p->ifr_addr);
-    else
-      address->address.address4 = *((struct sockaddr_in*) &p->ifr_addr);
-
-    sa_addr = (struct sockaddr_dl*) &p->ifr_addr;
-    memcpy(address->phys_addr, LLADDR(sa_addr), sizeof(address->phys_addr));
-
-    if (ioctl(sockfd, SIOCGIFNETMASK, p) == -1) {
-      uv__close(sockfd);
-      return UV_ENOSYS;
-    }
-
-    if (inet6)
-      address->netmask.netmask6 = *((struct sockaddr_in6*) &p->ifr_addr);
-    else
-      address->netmask.netmask4 = *((struct sockaddr_in*) &p->ifr_addr);
-
-    address->is_internal = flg.ifr_flags & IFF_LOOPBACK ? 1 : 0;
-
-    address++;
-  }
-
-#undef ADDR_SIZE
-
-  uv__close(sockfd);
-  return 0;
-}
-
-
-void uv_free_interface_addresses(uv_interface_address_t* addresses,
-  int count) {
-  int i;
-
-  for (i = 0; i < count; ++i) {
-    uv__free(addresses[i].name);
-  }
-
-  uv__free(addresses);
-}
-
diff --git a/Utilities/cmlibuv/src/unix/aix.c b/Utilities/cmlibuv/src/unix/aix.c
index 1f36926..6b4594b 100644
--- a/Utilities/cmlibuv/src/unix/aix.c
+++ b/Utilities/cmlibuv/src/unix/aix.c
@@ -926,7 +926,7 @@
 }
 
 
-UV_DESTRUCTOR(static void free_args_mem(void)) {
+void uv__process_title_cleanup(void) {
   uv__free(args_mem);  /* Keep valgrind happy. */
   args_mem = NULL;
 }
@@ -1039,6 +1039,186 @@
 }
 
 
+int uv_interface_addresses(uv_interface_address_t** addresses, int* count) {
+  uv_interface_address_t* address;
+  int sockfd, sock6fd, inet6, i, r, size = 1;
+  struct ifconf ifc;
+  struct ifreq *ifr, *p, flg;
+  struct in6_ifreq if6;
+  struct sockaddr_dl* sa_addr;
+
+  ifc.ifc_req = NULL;
+  sock6fd = -1;
+  r = 0;
+  *count = 0;
+  *addresses = NULL;
+
+  if (0 > (sockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP))) {
+    r = UV__ERR(errno);
+    goto cleanup;
+  }
+
+  if (0 > (sock6fd = socket(AF_INET6, SOCK_DGRAM, IPPROTO_IP))) {
+    r = UV__ERR(errno);
+    goto cleanup;
+  }
+
+  if (ioctl(sockfd, SIOCGSIZIFCONF, &size) == -1) {
+    r = UV__ERR(errno);
+    goto cleanup;
+  }
+
+  ifc.ifc_req = (struct ifreq*)uv__malloc(size);
+  if (ifc.ifc_req == NULL) {
+    r = UV_ENOMEM;
+    goto cleanup;
+  }
+  ifc.ifc_len = size;
+  if (ioctl(sockfd, SIOCGIFCONF, &ifc) == -1) {
+    r = UV__ERR(errno);
+    goto cleanup;
+  }
+
+#define ADDR_SIZE(p) MAX((p).sa_len, sizeof(p))
+
+  /* Count all up and running ipv4/ipv6 addresses */
+  ifr = ifc.ifc_req;
+  while ((char*)ifr < (char*)ifc.ifc_req + ifc.ifc_len) {
+    p = ifr;
+    ifr = (struct ifreq*)
+      ((char*)ifr + sizeof(ifr->ifr_name) + ADDR_SIZE(ifr->ifr_addr));
+
+    if (!(p->ifr_addr.sa_family == AF_INET6 ||
+          p->ifr_addr.sa_family == AF_INET))
+      continue;
+
+    memcpy(flg.ifr_name, p->ifr_name, sizeof(flg.ifr_name));
+    if (ioctl(sockfd, SIOCGIFFLAGS, &flg) == -1) {
+      r = UV__ERR(errno);
+      goto cleanup;
+    }
+
+    if (!(flg.ifr_flags & IFF_UP && flg.ifr_flags & IFF_RUNNING))
+      continue;
+
+    (*count)++;
+  }
+
+  if (*count == 0)
+    goto cleanup;
+
+  /* Alloc the return interface structs */
+  *addresses = uv__calloc(*count, sizeof(**addresses));
+  if (!(*addresses)) {
+    r = UV_ENOMEM;
+    goto cleanup;
+  }
+  address = *addresses;
+
+  ifr = ifc.ifc_req;
+  while ((char*)ifr < (char*)ifc.ifc_req + ifc.ifc_len) {
+    p = ifr;
+    ifr = (struct ifreq*)
+      ((char*)ifr + sizeof(ifr->ifr_name) + ADDR_SIZE(ifr->ifr_addr));
+
+    if (!(p->ifr_addr.sa_family == AF_INET6 ||
+          p->ifr_addr.sa_family == AF_INET))
+      continue;
+
+    inet6 = (p->ifr_addr.sa_family == AF_INET6);
+
+    memcpy(flg.ifr_name, p->ifr_name, sizeof(flg.ifr_name));
+    if (ioctl(sockfd, SIOCGIFFLAGS, &flg) == -1)
+      goto syserror;
+
+    if (!(flg.ifr_flags & IFF_UP && flg.ifr_flags & IFF_RUNNING))
+      continue;
+
+    /* All conditions above must match count loop */
+
+    address->name = uv__strdup(p->ifr_name);
+
+    if (inet6)
+      address->address.address6 = *((struct sockaddr_in6*) &p->ifr_addr);
+    else
+      address->address.address4 = *((struct sockaddr_in*) &p->ifr_addr);
+
+    if (inet6) {
+      memset(&if6, 0, sizeof(if6));
+      r = uv__strscpy(if6.ifr_name, p->ifr_name, sizeof(if6.ifr_name));
+      if (r == UV_E2BIG)
+        goto cleanup;
+      r = 0;
+      memcpy(&if6.ifr_Addr, &p->ifr_addr, sizeof(if6.ifr_Addr));
+      if (ioctl(sock6fd, SIOCGIFNETMASK6, &if6) == -1)
+        goto syserror;
+      address->netmask.netmask6 = *((struct sockaddr_in6*) &if6.ifr_Addr);
+      /* Explicitly set family as the ioctl call appears to return it as 0. */
+      address->netmask.netmask6.sin6_family = AF_INET6;
+    } else {
+      if (ioctl(sockfd, SIOCGIFNETMASK, p) == -1)
+        goto syserror;
+      address->netmask.netmask4 = *((struct sockaddr_in*) &p->ifr_addr);
+      /* Explicitly set family as the ioctl call appears to return it as 0. */
+      address->netmask.netmask4.sin_family = AF_INET;
+    }
+
+    address->is_internal = flg.ifr_flags & IFF_LOOPBACK ? 1 : 0;
+
+    address++;
+  }
+
+  /* Fill in physical addresses. */
+  ifr = ifc.ifc_req;
+  while ((char*)ifr < (char*)ifc.ifc_req + ifc.ifc_len) {
+    p = ifr;
+    ifr = (struct ifreq*)
+      ((char*)ifr + sizeof(ifr->ifr_name) + ADDR_SIZE(ifr->ifr_addr));
+
+    if (p->ifr_addr.sa_family != AF_LINK)
+      continue;
+
+    address = *addresses;
+    for (i = 0; i < *count; i++) {
+      if (strcmp(address->name, p->ifr_name) == 0) {
+        sa_addr = (struct sockaddr_dl*) &p->ifr_addr;
+        memcpy(address->phys_addr, LLADDR(sa_addr), sizeof(address->phys_addr));
+      }
+      address++;
+    }
+  }
+
+#undef ADDR_SIZE
+  goto cleanup;
+
+syserror:
+  uv_free_interface_addresses(*addresses, *count);
+  *addresses = NULL;
+  *count = 0;
+  r = UV_ENOSYS;
+
+cleanup:
+  if (sockfd != -1)
+    uv__close(sockfd);
+  if (sock6fd != -1)
+    uv__close(sock6fd);
+  uv__free(ifc.ifc_req);
+  return r;
+}
+
+
+void uv_free_interface_addresses(uv_interface_address_t* addresses,
+  int count) {
+  int i;
+
+  for (i = 0; i < count; ++i) {
+    uv__free(addresses[i].name);
+  }
+
+  uv__free(addresses);
+}
+
+
 void uv__platform_invalidate_fd(uv_loop_t* loop, int fd) {
   struct pollfd* events;
   uintptr_t i;
diff --git a/Utilities/cmlibuv/src/unix/android-ifaddrs.c b/Utilities/cmlibuv/src/unix/android-ifaddrs.c
index 99fb25a..4765cc0 100644
--- a/Utilities/cmlibuv/src/unix/android-ifaddrs.c
+++ b/Utilities/cmlibuv/src/unix/android-ifaddrs.c
@@ -35,6 +35,7 @@
 #include <netinet/in.h>
 #include <linux/netlink.h>
 #include <linux/rtnetlink.h>
+#include <linux/if_packet.h>
 
 typedef struct NetlinkList
 {
@@ -469,12 +470,14 @@
         {
             case IFA_ADDRESS:
             case IFA_LOCAL:
+                l_addrSize += NLMSG_ALIGN(calcAddrLen(l_info->ifa_family, l_rtaDataSize));
                 if((l_info->ifa_family == AF_INET || l_info->ifa_family == AF_INET6) && !l_addedNetmask)
                 {
                     /* Make room for netmask */
                     l_addrSize += NLMSG_ALIGN(calcAddrLen(l_info->ifa_family, l_rtaDataSize));
                     l_addedNetmask = 1;
                 }
+                break;
             case IFA_BROADCAST:
                 l_addrSize += NLMSG_ALIGN(calcAddrLen(l_info->ifa_family, l_rtaDataSize));
                 break;
diff --git a/Utilities/cmlibuv/src/unix/async.c b/Utilities/cmlibuv/src/unix/async.c
index a5c47bc..5f58fb8 100644
--- a/Utilities/cmlibuv/src/unix/async.c
+++ b/Utilities/cmlibuv/src/unix/async.c
@@ -32,10 +32,14 @@
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
+#include <sched.h>  /* sched_yield() */
+
+#ifdef __linux__
+#include <sys/eventfd.h>
+#endif
 
 static void uv__async_send(uv_loop_t* loop);
 static int uv__async_start(uv_loop_t* loop);
-static int uv__async_eventfd(void);
 
 
 int uv_async_init(uv_loop_t* loop, uv_async_t* handle, uv_async_cb async_cb) {
@@ -78,20 +82,32 @@
 
 /* Only call this from the event loop thread. */
 static int uv__async_spin(uv_async_t* handle) {
+  int i;
   int rc;
 
   for (;;) {
-    /* rc=0 -- handle is not pending.
-     * rc=1 -- handle is pending, other thread is still working with it.
-     * rc=2 -- handle is pending, other thread is done.
+    /* 997 is not completely chosen at random. It's a prime number, acyclical
+     * by nature, and should therefore hopefully dampen sympathetic resonance.
      */
-    rc = cmpxchgi(&handle->pending, 2, 0);
+    for (i = 0; i < 997; i++) {
+      /* rc=0 -- handle is not pending.
+       * rc=1 -- handle is pending, other thread is still working with it.
+       * rc=2 -- handle is pending, other thread is done.
+       */
+      rc = cmpxchgi(&handle->pending, 2, 0);
 
-    if (rc != 1)
-      return rc;
+      if (rc != 1)
+        return rc;
 
-    /* Other thread is busy with this handle, spin until it's done. */
-    cpu_relax();
+      /* Other thread is busy with this handle, spin until it's done. */
+      cpu_relax();
+    }
+
+    /* Yield the CPU. We may have preempted the other thread while it's
+     * inside the critical section and if it's running on the same CPU
+     * as us, we'll just burn CPU cycles until the end of our time slice.
+     */
+    sched_yield();
   }
 }
 
@@ -190,36 +206,18 @@
   if (loop->async_io_watcher.fd != -1)
     return 0;
 
-  err = uv__async_eventfd();
-  if (err >= 0) {
-    pipefd[0] = err;
-    pipefd[1] = -1;
-  }
-  else if (err == UV_ENOSYS) {
-    err = uv__make_pipe(pipefd, UV__F_NONBLOCK);
-#if defined(__linux__)
-    /* Save a file descriptor by opening one of the pipe descriptors as
-     * read/write through the procfs.  That file descriptor can then
-     * function as both ends of the pipe.
-     */
-    if (err == 0) {
-      char buf[32];
-      int fd;
+#ifdef __linux__
+  err = eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK);
+  if (err < 0)
+    return UV__ERR(errno);
 
-      snprintf(buf, sizeof(buf), "/proc/self/fd/%d", pipefd[0]);
-      fd = uv__open_cloexec(buf, O_RDWR);
-      if (fd >= 0) {
-        uv__close(pipefd[0]);
-        uv__close(pipefd[1]);
-        pipefd[0] = fd;
-        pipefd[1] = fd;
-      }
-    }
-#endif
-  }
-
+  pipefd[0] = err;
+  pipefd[1] = -1;
+#else
+  err = uv__make_pipe(pipefd, UV__F_NONBLOCK);
   if (err < 0)
     return err;
+#endif
 
   uv__io_init(&loop->async_io_watcher, uv__async_io, pipefd[0]);
   uv__io_start(loop, &loop->async_io_watcher, POLLIN);
@@ -253,46 +251,3 @@
   uv__close(loop->async_io_watcher.fd);
   loop->async_io_watcher.fd = -1;
 }
-
-
-static int uv__async_eventfd(void) {
-#if defined(__linux__)
-  static int no_eventfd2;
-  static int no_eventfd;
-  int fd;
-
-  if (no_eventfd2)
-    goto skip_eventfd2;
-
-  fd = uv__eventfd2(0, UV__EFD_CLOEXEC | UV__EFD_NONBLOCK);
-  if (fd != -1)
-    return fd;
-
-  if (errno != ENOSYS)
-    return UV__ERR(errno);
-
-  no_eventfd2 = 1;
-
-skip_eventfd2:
-
-  if (no_eventfd)
-    goto skip_eventfd;
-
-  fd = uv__eventfd(0);
-  if (fd != -1) {
-    uv__cloexec(fd, 1);
-    uv__nonblock(fd, 1);
-    return fd;
-  }
-
-  if (errno != ENOSYS)
-    return UV__ERR(errno);
-
-  no_eventfd = 1;
-
-skip_eventfd:
-
-#endif
-
-  return UV_ENOSYS;
-}
diff --git a/Utilities/cmlibuv/src/unix/atomic-ops.h b/Utilities/cmlibuv/src/unix/atomic-ops.h
index 995aca6..2518a06 100644
--- a/Utilities/cmlibuv/src/unix/atomic-ops.h
+++ b/Utilities/cmlibuv/src/unix/atomic-ops.h
@@ -36,10 +36,12 @@
                         : "r" (newval), "0" (oldval)
                         : "memory");
   return out;
-#elif defined(_AIX) && (defined(__xlC__) || defined(__ibmxl__))
-  const int out = (*(volatile int*) ptr);
-  __compare_and_swap(ptr, &oldval, newval);
-  return out;
+#elif defined(_AIX) && defined(__ibmxl__)
+  /* FIXME: This is not actually atomic but XLClang 16.1 for AIX
+     does not provide __sync_val_compare_and_swap or an equivalent.
+     Its documentation suggests using C++11 atomics but this is C.  */
+  __compare_and_swap((volatile int*)ptr, &oldval, newval);
+  return oldval;
 #elif defined(__MVS__)
   unsigned int op4;
   if (__plo_CSST(ptr, (unsigned int*) &oldval, newval,
@@ -57,6 +59,8 @@
 UV_UNUSED(static void cpu_relax(void)) {
 #if defined(__i386__) || defined(__x86_64__)
   __asm__ __volatile__ ("rep; nop");  /* a.k.a. PAUSE */
+#elif (defined(__arm__) && __ARM_ARCH >= 7) || defined(__aarch64__)
+  __asm__ volatile("yield");
 #endif
 }
 
diff --git a/Utilities/cmlibuv/src/unix/bsd-ifaddrs.c b/Utilities/cmlibuv/src/unix/bsd-ifaddrs.c
index 0d7bbe6..a3385af 100644
--- a/Utilities/cmlibuv/src/unix/bsd-ifaddrs.c
+++ b/Utilities/cmlibuv/src/unix/bsd-ifaddrs.c
@@ -69,7 +69,9 @@
   struct ifaddrs* addrs;
   struct ifaddrs* ent;
   uv_interface_address_t* address;
+#if !(defined(__CYGWIN__) || defined(__MSYS__))
   int i;
+#endif
 
   *count = 0;
   *addresses = NULL;
diff --git a/Utilities/cmlibuv/src/unix/bsd-proctitle.c b/Utilities/cmlibuv/src/unix/bsd-proctitle.c
index 0ce47c8..723b81c 100644
--- a/Utilities/cmlibuv/src/unix/bsd-proctitle.c
+++ b/Utilities/cmlibuv/src/unix/bsd-proctitle.c
@@ -37,6 +37,13 @@
 }
 
 
+void uv__process_title_cleanup(void) {
+  /* TODO(bnoordhuis) uv_mutex_destroy(&process_title_mutex)
+   * and reset process_title_mutex_once?
+   */
+}
+
+
 char** uv_setup_args(int argc, char** argv) {
   process_title = argc > 0 ? uv__strdup(argv[0]) : NULL;
   return argv;
diff --git a/Utilities/cmlibuv/src/unix/cmake-bootstrap.c b/Utilities/cmlibuv/src/unix/cmake-bootstrap.c
index d42ff05..6cf42fa 100644
--- a/Utilities/cmlibuv/src/unix/cmake-bootstrap.c
+++ b/Utilities/cmlibuv/src/unix/cmake-bootstrap.c
@@ -1,6 +1,12 @@
 #include "uv.h"
 #include "internal.h"
 
+void uv__process_title_cleanup(void) {
+}
+
+void uv__threadpool_cleanup(void) {
+}
+
 int uv__tcp_nodelay(int fd, int on) {
   errno = EINVAL;
   return -1;
diff --git a/Utilities/cmlibuv/src/unix/core.c b/Utilities/cmlibuv/src/unix/core.c
index cf7dea0..7b80ed5 100644
--- a/Utilities/cmlibuv/src/unix/core.c
+++ b/Utilities/cmlibuv/src/unix/core.c
@@ -30,7 +30,7 @@
 #include <unistd.h>
 #include <sys/types.h>
 #include <sys/stat.h>
-#include <fcntl.h>
+#include <fcntl.h>  /* O_CLOEXEC */
 #include <sys/ioctl.h>
 #include <sys/socket.h>
 #include <sys/un.h>
@@ -50,37 +50,36 @@
 # include <sys/wait.h>
 #endif
 
-#ifdef __APPLE__
-# include <mach-o/dyld.h> /* _NSGetExecutablePath */
+#if defined(__APPLE__)
 # include <sys/filio.h>
-# if defined(O_CLOEXEC)
-#  define UV__O_CLOEXEC O_CLOEXEC
-# endif
-#endif
+# endif /* defined(__APPLE__) */
+
+
+#if defined(__APPLE__) && !TARGET_OS_IPHONE
+# include <crt_externs.h>
+# include <mach-o/dyld.h> /* _NSGetExecutablePath */
+# define environ (*_NSGetEnviron())
+#else /* defined(__APPLE__) && !TARGET_OS_IPHONE */
+extern char** environ;
+#endif /* !(defined(__APPLE__) && !TARGET_OS_IPHONE) */
+
 
 #if defined(__DragonFly__)      || \
     defined(__FreeBSD__)        || \
     defined(__FreeBSD_kernel__) || \
-    defined(__NetBSD__)
+    defined(__NetBSD__)         || \
+    defined(__OpenBSD__)
 # include <sys/sysctl.h>
 # include <sys/filio.h>
 # include <sys/wait.h>
 # include <sys/param.h>
 # include <sys/cpuset.h>
-# define UV__O_CLOEXEC O_CLOEXEC
-# if defined(__FreeBSD__) && __FreeBSD__ >= 10
+# if defined(__FreeBSD__)
 #  define uv__accept4 accept4
 # endif
 # if defined(__NetBSD__)
 #  define uv__accept4(a, b, c, d) paccept((a), (b), (c), NULL, (d))
 # endif
-# if (defined(__FreeBSD__) && __FreeBSD__ >= 10) || defined(__NetBSD__)
-#  define UV__SOCK_NONBLOCK SOCK_NONBLOCK
-#  define UV__SOCK_CLOEXEC  SOCK_CLOEXEC
-# endif
-# if !defined(F_DUP2FD_CLOEXEC) && defined(_F_DUP2FD_CLOEXEC)
-#  define F_DUP2FD_CLOEXEC  _F_DUP2FD_CLOEXEC
-# endif
 #endif
 
 #if defined(__ANDROID_API__) && __ANDROID_API__ < 21
@@ -92,7 +91,8 @@
 #endif
 
 #if defined(__linux__)
-#include <sys/syscall.h>
+# include <sys/syscall.h>
+# define uv__accept4 accept4
 #endif
 
 static int uv__run_pending(uv_loop_t* loop);
@@ -175,9 +175,7 @@
 
   case UV_SIGNAL:
     uv__signal_close((uv_signal_t*) handle);
-    /* Signal handles may not be closed immediately. The signal code will
-     * itself close uv__make_close_pending whenever appropriate. */
-    return;
+    break;
 
   default:
     assert(0);
@@ -242,6 +240,8 @@
 
 
 static void uv__finish_close(uv_handle_t* handle) {
+  uv_signal_t* sh;
+
   /* Note: while the handle is in the UV_HANDLE_CLOSING state now, it's still
    * possible for it to be active in the sense that uv__is_active() returns
    * true.
@@ -264,7 +264,20 @@
     case UV_FS_EVENT:
     case UV_FS_POLL:
     case UV_POLL:
+      break;
+
     case UV_SIGNAL:
+      /* If there are any caught signals "trapped" in the signal pipe,
+       * we can't call the close callback yet. Reinserting the handle
+       * into the closing queue makes the event loop spin but that's
+       * okay because we only need to deliver the pending events.
+       */
+      sh = (uv_signal_t*) handle;
+      if (sh->caught_signals > sh->dispatched_signals) {
+        handle->flags ^= UV_HANDLE_CLOSED;
+        uv__make_close_pending(handle);  /* Back into the queue. */
+        return;
+      }
       break;
 
     case UV_NAMED_PIPE:
@@ -468,52 +481,32 @@
   int peerfd;
   int err;
 
+  (void) &err;
   assert(sockfd >= 0);
 
-  while (1) {
-#if defined(__linux__)                          || \
-    (defined(__FreeBSD__) && __FreeBSD__ >= 10) || \
-    defined(__NetBSD__)
-    static int no_accept4;
+  do
+#ifdef uv__accept4
+    peerfd = uv__accept4(sockfd, NULL, NULL, SOCK_NONBLOCK|SOCK_CLOEXEC);
+#else
+    peerfd = accept(sockfd, NULL, NULL);
+#endif
+  while (peerfd == -1 && errno == EINTR);
 
-    if (no_accept4)
-      goto skip;
+  if (peerfd == -1)
+    return UV__ERR(errno);
 
-    peerfd = uv__accept4(sockfd,
-                         NULL,
-                         NULL,
-                         UV__SOCK_NONBLOCK|UV__SOCK_CLOEXEC);
-    if (peerfd != -1)
-      return peerfd;
+#ifndef uv__accept4
+  err = uv__cloexec(peerfd, 1);
+  if (err == 0)
+    err = uv__nonblock(peerfd, 1);
 
-    if (errno == EINTR)
-      continue;
-
-    if (errno != ENOSYS)
-      return UV__ERR(errno);
-
-    no_accept4 = 1;
-skip:
+  if (err != 0) {
+    uv__close(peerfd);
+    return err;
+  }
 #endif
 
-    peerfd = accept(sockfd, NULL, NULL);
-    if (peerfd == -1) {
-      if (errno == EINTR)
-        continue;
-      return UV__ERR(errno);
-    }
-
-    err = uv__cloexec(peerfd, 1);
-    if (err == 0)
-      err = uv__nonblock(peerfd, 1);
-
-    if (err) {
-      uv__close(peerfd);
-      return err;
-    }
-
-    return peerfd;
-  }
+  return peerfd;
 }
 
 
@@ -529,7 +522,7 @@
 #if defined(__APPLE__)
 #pragma GCC diagnostic push
 #pragma GCC diagnostic ignored "-Wdollar-in-identifier-extension"
-#if defined(__LP64__)
+#if defined(__LP64__) || TARGET_OS_IPHONE
   extern int close$NOCANCEL(int);
   return close$NOCANCEL(fd);
 #else
@@ -704,16 +697,38 @@
 
 
 int uv_cwd(char* buffer, size_t* size) {
+  char scratch[1 + UV__PATH_MAX];
+
   if (buffer == NULL || size == NULL)
     return UV_EINVAL;
 
-  if (getcwd(buffer, *size) == NULL)
+  /* Try to read directly into the user's buffer first... */
+  if (getcwd(buffer, *size) != NULL)
+    goto fixup;
+
+  if (errno != ERANGE)
     return UV__ERR(errno);
 
+  /* ...or into scratch space if the user's buffer is too small
+   * so we can report how much space to provide on the next try.
+   */
+  if (getcwd(scratch, sizeof(scratch)) == NULL)
+    return UV__ERR(errno);
+
+  buffer = scratch;
+
+fixup:
+
   *size = strlen(buffer);
+
   if (*size > 1 && buffer[*size - 1] == '/') {
-    buffer[*size-1] = '\0';
-    (*size)--;
+    *size -= 1;
+    buffer[*size] = '\0';
+  }
+
+  if (buffer == scratch) {
+    *size += 1;
+    return UV_ENOBUFS;
   }
 
   return 0;
@@ -823,8 +838,8 @@
   }
 
   nwatchers = next_power_of_two(len + 2) - 2;
-  watchers = uv__realloc(loop->watchers,
-                         (nwatchers + 2) * sizeof(loop->watchers[0]));
+  watchers = uv__reallocf(loop->watchers,
+                          (nwatchers + 2) * sizeof(loop->watchers[0]));
 
   if (watchers == NULL)
     abort();
@@ -977,24 +992,17 @@
 
 
 int uv__open_cloexec(const char* path, int flags) {
-  int err;
+#if defined(O_CLOEXEC)
   int fd;
 
-#if defined(UV__O_CLOEXEC)
-  static int no_cloexec;
+  fd = open(path, flags | O_CLOEXEC);
+  if (fd == -1)
+    return UV__ERR(errno);
 
-  if (!no_cloexec) {
-    fd = open(path, flags | UV__O_CLOEXEC);
-    if (fd != -1)
-      return fd;
-
-    if (errno != EINVAL)
-      return UV__ERR(errno);
-
-    /* O_CLOEXEC not supported. */
-    no_cloexec = 1;
-  }
-#endif
+  return fd;
+#else  /* O_CLOEXEC */
+  int err;
+  int fd;
 
   fd = open(path, flags);
   if (fd == -1)
@@ -1007,58 +1015,35 @@
   }
 
   return fd;
+#endif  /* O_CLOEXEC */
 }
 
 
 int uv__dup2_cloexec(int oldfd, int newfd) {
+#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__linux__)
   int r;
-#if (defined(__FreeBSD__) && __FreeBSD__ >= 10) || defined(__NetBSD__)
+
   r = dup3(oldfd, newfd, O_CLOEXEC);
   if (r == -1)
     return UV__ERR(errno);
+
   return r;
-#elif defined(__FreeBSD__) && defined(F_DUP2FD_CLOEXEC)
-  r = fcntl(oldfd, F_DUP2FD_CLOEXEC, newfd);
-  if (r != -1)
-    return r;
-  if (errno != EINVAL)
-    return UV__ERR(errno);
-  /* Fall through. */
-#elif defined(__linux__)
-  static int no_dup3;
-  if (!no_dup3) {
-    do
-      r = uv__dup3(oldfd, newfd, UV__O_CLOEXEC);
-    while (r == -1 && errno == EBUSY);
-    if (r != -1)
-      return r;
-    if (errno != ENOSYS)
-      return UV__ERR(errno);
-    /* Fall through. */
-    no_dup3 = 1;
-  }
-#endif
-  {
-    int err;
-    do
-      r = dup2(oldfd, newfd);
-#if defined(__linux__)
-    while (r == -1 && errno == EBUSY);
 #else
-    while (0);  /* Never retry. */
-#endif
+  int err;
+  int r;
 
-    if (r == -1)
-      return UV__ERR(errno);
+  r = dup2(oldfd, newfd);  /* Never retry. */
+  if (r == -1)
+    return UV__ERR(errno);
 
-    err = uv__cloexec(newfd, 1);
-    if (err) {
-      uv__close(newfd);
-      return err;
-    }
-
-    return r;
+  err = uv__cloexec(newfd, 1);
+  if (err != 0) {
+    uv__close(newfd);
+    return err;
   }
+
+  return r;
+#endif
 }
 
 
@@ -1265,6 +1250,62 @@
 }
 
 
+int uv_os_environ(uv_env_item_t** envitems, int* count) {
+  int i, j, cnt;
+  uv_env_item_t* envitem;
+
+  *envitems = NULL;
+  *count = 0;
+
+  for (i = 0; environ[i] != NULL; i++);
+
+  *envitems = uv__calloc(i, sizeof(**envitems));
+
+  if (*envitems == NULL)
+    return UV_ENOMEM;
+
+  for (j = 0, cnt = 0; j < i; j++) {
+    char* buf;
+    char* ptr;
+
+    if (environ[j] == NULL)
+      break;
+
+    buf = uv__strdup(environ[j]);
+    if (buf == NULL)
+      goto fail;
+
+    ptr = strchr(buf, '=');
+    if (ptr == NULL) {
+      uv__free(buf);
+      continue;
+    }
+
+    *ptr = '\0';
+
+    envitem = &(*envitems)[cnt];
+    envitem->name = buf;
+    envitem->value = ptr + 1;
+
+    cnt++;
+  }
+
+  *count = cnt;
+  return 0;
+
+fail:
+  for (i = 0; i < cnt; i++) {
+    envitem = &(*envitems)[cnt];
+    uv__free(envitem->name);
+  }
+  uv__free(*envitems);
+
+  *envitems = NULL;
+  *count = 0;
+  return UV_ENOMEM;
+}
+
+
 int uv_os_getenv(const char* name, char* buffer, size_t* size) {
   char* var;
   size_t len;
@@ -1488,3 +1529,17 @@
   tv->tv_usec = (int32_t) time.tv_usec;
   return 0;
 }
+
+void uv_sleep(unsigned int msec) {
+  struct timespec timeout;
+  int rc;
+
+  timeout.tv_sec = msec / 1000;
+  timeout.tv_nsec = (msec % 1000) * 1000 * 1000;
+
+  do
+    rc = nanosleep(&timeout, &timeout);
+  while (rc == -1 && errno == EINTR);
+
+  assert(rc == 0);
+}
diff --git a/Utilities/cmlibuv/src/unix/cygwin.c b/Utilities/cmlibuv/src/unix/cygwin.c
index 9da20e2..169958d 100644
--- a/Utilities/cmlibuv/src/unix/cygwin.c
+++ b/Utilities/cmlibuv/src/unix/cygwin.c
@@ -48,7 +48,6 @@
   return UV_ENOSYS;
 }
 
-void uv_free_cpu_info(uv_cpu_info_t* cpu_infos, int count) {
-  (void)cpu_infos;
-  (void)count;
+uint64_t uv_get_constrained_memory(void) {
+  return 0;  /* Memory constraints are unknown. */
 }
diff --git a/Utilities/cmlibuv/src/unix/darwin-proctitle.c b/Utilities/cmlibuv/src/unix/darwin-proctitle.c
index e505bdd..5288083 100644
--- a/Utilities/cmlibuv/src/unix/darwin-proctitle.c
+++ b/Utilities/cmlibuv/src/unix/darwin-proctitle.c
@@ -23,66 +23,61 @@
 
 #include <dlfcn.h>
 #include <errno.h>
+#include <pthread.h>
 #include <stdlib.h>
 #include <string.h>
 
 #include <TargetConditionals.h>
 
 #if !TARGET_OS_IPHONE
-# include <CoreFoundation/CoreFoundation.h>
-# include <ApplicationServices/ApplicationServices.h>
+#include "darwin-stub.h"
 #endif
 
-#define S(s) pCFStringCreateWithCString(NULL, (s), kCFStringEncodingUTF8)
 
+static int uv__pthread_setname_np(const char* name) {
+  char namebuf[64];  /* MAXTHREADNAMESIZE */
+  int err;
 
-static int (*dynamic_pthread_setname_np)(const char* name);
-#if !TARGET_OS_IPHONE
-static CFStringRef (*pCFStringCreateWithCString)(CFAllocatorRef,
-                                                 const char*,
-                                                 CFStringEncoding);
-static CFBundleRef (*pCFBundleGetBundleWithIdentifier)(CFStringRef);
-static void *(*pCFBundleGetDataPointerForName)(CFBundleRef, CFStringRef);
-static void *(*pCFBundleGetFunctionPointerForName)(CFBundleRef, CFStringRef);
-static CFTypeRef (*pLSGetCurrentApplicationASN)(void);
-static OSStatus (*pLSSetApplicationInformationItem)(int,
-                                                    CFTypeRef,
-                                                    CFStringRef,
-                                                    CFStringRef,
-                                                    CFDictionaryRef*);
-static void* application_services_handle;
-static void* core_foundation_handle;
-static CFBundleRef launch_services_bundle;
-static CFStringRef* display_name_key;
-static CFDictionaryRef (*pCFBundleGetInfoDictionary)(CFBundleRef);
-static CFBundleRef (*pCFBundleGetMainBundle)(void);
-static CFBundleRef hi_services_bundle;
-static OSStatus (*pSetApplicationIsDaemon)(int);
-static CFDictionaryRef (*pLSApplicationCheckIn)(int, CFDictionaryRef);
-static void (*pLSSetApplicationLaunchServicesServerConnectionStatus)(uint64_t,
-                                                                     void*);
+  strncpy(namebuf, name, sizeof(namebuf) - 1);
+  namebuf[sizeof(namebuf) - 1] = '\0';
 
+  err = pthread_setname_np(namebuf);
+  if (err)
+    return UV__ERR(err);
 
-UV_DESTRUCTOR(static void uv__set_process_title_platform_fini(void)) {
-  if (core_foundation_handle != NULL) {
-    dlclose(core_foundation_handle);
-    core_foundation_handle = NULL;
-  }
-
-  if (application_services_handle != NULL) {
-    dlclose(application_services_handle);
-    application_services_handle = NULL;
-  }
+  return 0;
 }
-#endif  /* !TARGET_OS_IPHONE */
 
 
-void uv__set_process_title_platform_init(void) {
-  /* pthread_setname_np() first appeared in OS X 10.6 and iOS 3.2. */
-  *(void **)(&dynamic_pthread_setname_np) =
-      dlsym(RTLD_DEFAULT, "pthread_setname_np");
+int uv__set_process_title(const char* title) {
+#if TARGET_OS_IPHONE
+  return uv__pthread_setname_np(title);
+#else
+  CFStringRef (*pCFStringCreateWithCString)(CFAllocatorRef,
+                                            const char*,
+                                            CFStringEncoding);
+  CFBundleRef (*pCFBundleGetBundleWithIdentifier)(CFStringRef);
+  void *(*pCFBundleGetDataPointerForName)(CFBundleRef, CFStringRef);
+  void *(*pCFBundleGetFunctionPointerForName)(CFBundleRef, CFStringRef);
+  CFTypeRef (*pLSGetCurrentApplicationASN)(void);
+  OSStatus (*pLSSetApplicationInformationItem)(int,
+                                               CFTypeRef,
+                                               CFStringRef,
+                                               CFStringRef,
+                                               CFDictionaryRef*);
+  void* application_services_handle;
+  void* core_foundation_handle;
+  CFBundleRef launch_services_bundle;
+  CFStringRef* display_name_key;
+  CFDictionaryRef (*pCFBundleGetInfoDictionary)(CFBundleRef);
+  CFBundleRef (*pCFBundleGetMainBundle)(void);
+  CFDictionaryRef (*pLSApplicationCheckIn)(int, CFDictionaryRef);
+  void (*pLSSetApplicationLaunchServicesServerConnectionStatus)(uint64_t,
+                                                                void*);
+  CFTypeRef asn;
+  int err;
 
-#if !TARGET_OS_IPHONE
+  err = UV_ENOENT;
   application_services_handle = dlopen("/System/Library/Frameworks/"
                                        "ApplicationServices.framework/"
                                        "Versions/A/ApplicationServices",
@@ -111,6 +106,8 @@
     goto out;
   }
 
+#define S(s) pCFStringCreateWithCString(NULL, (s), kCFStringEncodingUTF8)
+
   launch_services_bundle =
       pCFBundleGetBundleWithIdentifier(S("com.apple.LaunchServices"));
 
@@ -141,58 +138,55 @@
                                      "CFBundleGetInfoDictionary");
   *(void **)(&pCFBundleGetMainBundle) = dlsym(core_foundation_handle,
                                  "CFBundleGetMainBundle");
-
   if (pCFBundleGetInfoDictionary == NULL || pCFBundleGetMainBundle == NULL)
     goto out;
 
-  /* Black 10.9 magic, to remove (Not responding) mark in Activity Monitor */
-  hi_services_bundle =
-      pCFBundleGetBundleWithIdentifier(S("com.apple.HIServices"));
-
-  if (hi_services_bundle == NULL)
-    goto out;
-
-  *(void **)(&pSetApplicationIsDaemon) = pCFBundleGetFunctionPointerForName(
-      hi_services_bundle,
-      S("SetApplicationIsDaemon"));
   *(void **)(&pLSApplicationCheckIn) = pCFBundleGetFunctionPointerForName(
       launch_services_bundle,
       S("_LSApplicationCheckIn"));
+
+  if (pLSApplicationCheckIn == NULL)
+    goto out;
+
   *(void **)(&pLSSetApplicationLaunchServicesServerConnectionStatus) =
       pCFBundleGetFunctionPointerForName(
           launch_services_bundle,
           S("_LSSetApplicationLaunchServicesServerConnectionStatus"));
 
-  if (pSetApplicationIsDaemon == NULL ||
-      pLSApplicationCheckIn == NULL ||
-      pLSSetApplicationLaunchServicesServerConnectionStatus == NULL) {
+  if (pLSSetApplicationLaunchServicesServerConnectionStatus == NULL)
+    goto out;
+
+  pLSSetApplicationLaunchServicesServerConnectionStatus(0, NULL);
+
+  /* Check into process manager?! */
+  pLSApplicationCheckIn(-2,
+                        pCFBundleGetInfoDictionary(pCFBundleGetMainBundle()));
+
+  asn = pLSGetCurrentApplicationASN();
+
+  err = UV_EBUSY;
+  if (asn == NULL)
+    goto out;
+
+  err = UV_EINVAL;
+  if (pLSSetApplicationInformationItem(-2,  /* Magic value. */
+                                       asn,
+                                       *display_name_key,
+                                       S(title),
+                                       NULL) != noErr) {
     goto out;
   }
 
-  return;
+  uv__pthread_setname_np(title);  /* Don't care if it fails. */
+  err = 0;
 
 out:
-  uv__set_process_title_platform_fini();
+  if (core_foundation_handle != NULL)
+    dlclose(core_foundation_handle);
+
+  if (application_services_handle != NULL)
+    dlclose(application_services_handle);
+
+  return err;
 #endif  /* !TARGET_OS_IPHONE */
 }
-
-
-void uv__set_process_title(const char* title) {
-#if !TARGET_OS_IPHONE
-  if (core_foundation_handle != NULL && pSetApplicationIsDaemon(1) != noErr) {
-    CFTypeRef asn;
-    pLSSetApplicationLaunchServicesServerConnectionStatus(0, NULL);
-    pLSApplicationCheckIn(/* Magic value */ -2,
-                          pCFBundleGetInfoDictionary(pCFBundleGetMainBundle()));
-    asn = pLSGetCurrentApplicationASN();
-    pLSSetApplicationInformationItem(/* Magic value */ -2, asn,
-                                     *display_name_key, S(title), NULL);
-  }
-#endif  /* !TARGET_OS_IPHONE */
-
-  if (dynamic_pthread_setname_np != NULL) {
-    char namebuf[64];  /* MAXTHREADNAMESIZE */
-    uv__strscpy(namebuf, title, sizeof(namebuf));
-    dynamic_pthread_setname_np(namebuf);
-  }
-}
diff --git a/Utilities/cmlibuv/src/unix/darwin-stub.h b/Utilities/cmlibuv/src/unix/darwin-stub.h
new file mode 100644
index 0000000..b93cf67
--- /dev/null
+++ b/Utilities/cmlibuv/src/unix/darwin-stub.h
@@ -0,0 +1,97 @@
+/* Copyright libuv project contributors. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#ifndef UV_DARWIN_STUB_H_
+#define UV_DARWIN_STUB_H_
+
+#include <stdint.h>
+
+struct CFArrayCallBacks;
+struct CFRunLoopSourceContext;
+struct FSEventStreamContext;
+
+typedef double CFAbsoluteTime;
+typedef double CFTimeInterval;
+typedef int FSEventStreamEventFlags;
+typedef int OSStatus;
+typedef long CFIndex;
+typedef struct CFArrayCallBacks CFArrayCallBacks;
+typedef struct CFRunLoopSourceContext CFRunLoopSourceContext;
+typedef struct FSEventStreamContext FSEventStreamContext;
+typedef uint32_t FSEventStreamCreateFlags;
+typedef uint64_t FSEventStreamEventId;
+typedef unsigned CFStringEncoding;
+typedef void* CFAllocatorRef;
+typedef void* CFArrayRef;
+typedef void* CFBundleRef;
+typedef void* CFDictionaryRef;
+typedef void* CFRunLoopRef;
+typedef void* CFRunLoopSourceRef;
+typedef void* CFStringRef;
+typedef void* CFTypeRef;
+typedef void* FSEventStreamRef;
+
+typedef void (*FSEventStreamCallback)(const FSEventStreamRef,
+                                      void*,
+                                      size_t,
+                                      void*,
+                                      const FSEventStreamEventFlags*,
+                                      const FSEventStreamEventId*);
+
+struct CFRunLoopSourceContext {
+  CFIndex version;
+  void* info;
+  void* pad[7];
+  void (*perform)(void*);
+};
+
+struct FSEventStreamContext {
+  CFIndex version;
+  void* info;
+  void* pad[3];
+};
+
+static const CFStringEncoding kCFStringEncodingUTF8 = 0x8000100;
+static const OSStatus noErr = 0;
+
+static const FSEventStreamEventId kFSEventStreamEventIdSinceNow = -1;
+
+static const int kFSEventStreamCreateFlagNoDefer = 2;
+static const int kFSEventStreamCreateFlagFileEvents = 16;
+
+static const int kFSEventStreamEventFlagEventIdsWrapped = 8;
+static const int kFSEventStreamEventFlagHistoryDone = 16;
+static const int kFSEventStreamEventFlagItemChangeOwner = 0x4000;
+static const int kFSEventStreamEventFlagItemCreated = 0x100;
+static const int kFSEventStreamEventFlagItemFinderInfoMod = 0x2000;
+static const int kFSEventStreamEventFlagItemInodeMetaMod = 0x400;
+static const int kFSEventStreamEventFlagItemIsDir = 0x20000;
+static const int kFSEventStreamEventFlagItemModified = 0x1000;
+static const int kFSEventStreamEventFlagItemRemoved = 0x200;
+static const int kFSEventStreamEventFlagItemRenamed = 0x800;
+static const int kFSEventStreamEventFlagItemXattrMod = 0x8000;
+static const int kFSEventStreamEventFlagKernelDropped = 4;
+static const int kFSEventStreamEventFlagMount = 64;
+static const int kFSEventStreamEventFlagRootChanged = 32;
+static const int kFSEventStreamEventFlagUnmount = 128;
+static const int kFSEventStreamEventFlagUserDropped = 2;
+
+#endif  /* UV_DARWIN_STUB_H_ */
diff --git a/Utilities/cmlibuv/src/unix/darwin.c b/Utilities/cmlibuv/src/unix/darwin.c
index e4cd8ff..654aba2 100644
--- a/Utilities/cmlibuv/src/unix/darwin.c
+++ b/Utilities/cmlibuv/src/unix/darwin.c
@@ -110,7 +110,7 @@
   int which[] = {CTL_HW, HW_MEMSIZE};
   size_t size = sizeof(info);
 
-  if (sysctl(which, 2, &info, &size, NULL, 0))
+  if (sysctl(which, ARRAY_SIZE(which), &info, &size, NULL, 0))
     return UV__ERR(errno);
 
   return (uint64_t) info;
@@ -127,7 +127,7 @@
   size_t size = sizeof(info);
   int which[] = {CTL_VM, VM_LOADAVG};
 
-  if (sysctl(which, 2, &info, &size, NULL, 0) < 0) return;
+  if (sysctl(which, ARRAY_SIZE(which), &info, &size, NULL, 0) < 0) return;
 
   avg[0] = (double) info.ldavg[0] / info.fscale;
   avg[1] = (double) info.ldavg[1] / info.fscale;
@@ -162,7 +162,7 @@
   size_t size = sizeof(info);
   static int which[] = {CTL_KERN, KERN_BOOTTIME};
 
-  if (sysctl(which, 2, &info, &size, NULL, 0))
+  if (sysctl(which, ARRAY_SIZE(which), &info, &size, NULL, 0))
     return UV__ERR(errno);
 
   now = time(NULL);
@@ -223,14 +223,3 @@
 
   return 0;
 }
-
-
-void uv_free_cpu_info(uv_cpu_info_t* cpu_infos, int count) {
-  int i;
-
-  for (i = 0; i < count; i++) {
-    uv__free(cpu_infos[i].model);
-  }
-
-  uv__free(cpu_infos);
-}
diff --git a/Utilities/cmlibuv/src/unix/freebsd.c b/Utilities/cmlibuv/src/unix/freebsd.c
index 7de88d6..ef77e12 100644
--- a/Utilities/cmlibuv/src/unix/freebsd.c
+++ b/Utilities/cmlibuv/src/unix/freebsd.c
@@ -95,7 +95,7 @@
   mib[3] = -1;
 
   abspath_size = sizeof abspath;
-  if (sysctl(mib, 4, abspath, &abspath_size, NULL, 0))
+  if (sysctl(mib, ARRAY_SIZE(mib), abspath, &abspath_size, NULL, 0))
     return UV__ERR(errno);
 
   assert(abspath_size > 0);
@@ -130,7 +130,7 @@
 
   size_t size = sizeof(info);
 
-  if (sysctl(which, 2, &info, &size, NULL, 0))
+  if (sysctl(which, ARRAY_SIZE(which), &info, &size, NULL, 0))
     return UV__ERR(errno);
 
   return (uint64_t) info;
@@ -147,7 +147,7 @@
   size_t size = sizeof(info);
   int which[] = {CTL_VM, VM_LOADAVG};
 
-  if (sysctl(which, 2, &info, &size, NULL, 0) < 0) return;
+  if (sysctl(which, ARRAY_SIZE(which), &info, &size, NULL, 0) < 0) return;
 
   avg[0] = (double) info.ldavg[0] / info.fscale;
   avg[1] = (double) info.ldavg[1] / info.fscale;
@@ -168,7 +168,7 @@
 
   kinfo_size = sizeof(kinfo);
 
-  if (sysctl(mib, 4, &kinfo, &kinfo_size, NULL, 0))
+  if (sysctl(mib, ARRAY_SIZE(mib), &kinfo, &kinfo_size, NULL, 0))
     return UV__ERR(errno);
 
   page_size = getpagesize();
@@ -290,12 +290,26 @@
 }
 
 
-void uv_free_cpu_info(uv_cpu_info_t* cpu_infos, int count) {
-  int i;
+int uv__sendmmsg(int fd,
+                 struct uv__mmsghdr* mmsg,
+                 unsigned int vlen,
+                 unsigned int flags) {
+#if __FreeBSD__ >= 11
+  return sendmmsg(fd, mmsg, vlen, flags);
+#else
+  return errno = ENOSYS, -1;
+#endif
+}
 
-  for (i = 0; i < count; i++) {
-    uv__free(cpu_infos[i].model);
-  }
 
-  uv__free(cpu_infos);
+int uv__recvmmsg(int fd,
+                 struct uv__mmsghdr* mmsg,
+                 unsigned int vlen,
+                 unsigned int flags,
+                 struct timespec* timeout) {
+#if __FreeBSD__ >= 11
+  return recvmmsg(fd, mmsg, vlen, flags, timeout);
+#else
+  return errno = ENOSYS, -1;
+#endif
 }
diff --git a/Utilities/cmlibuv/src/unix/fs.c b/Utilities/cmlibuv/src/unix/fs.c
index 5fb34f1b..f37749c 100644
--- a/Utilities/cmlibuv/src/unix/fs.c
+++ b/Utilities/cmlibuv/src/unix/fs.c
@@ -30,6 +30,7 @@
 #include "internal.h"
 
 #include <errno.h>
+#include <dlfcn.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -70,6 +71,20 @@
 # include <utime.h>
 #endif
 
+#if defined(__APPLE__)            ||                                      \
+    defined(__DragonFly__)        ||                                      \
+    defined(__FreeBSD__)          ||                                      \
+    defined(__FreeBSD_kernel__)   ||                                      \
+    defined(__OpenBSD__)          ||                                      \
+    defined(__NetBSD__)
+# include <sys/param.h>
+# include <sys/mount.h>
+#elif defined(__sun) || defined(__MVS__) || defined(__NetBSD__) || defined(__HAIKU__)
+# include <sys/statvfs.h>
+#else
+# include <sys/statfs.h>
+#endif
+
 #if defined(_AIX) && _XOPEN_SOURCE <= 600
 extern char *mkdtemp(char *template); /* See issue #740 on AIX < 7 */
 #endif
@@ -190,6 +205,20 @@
 }
 
 
+UV_UNUSED(static struct timespec uv__fs_to_timespec(double time)) {
+  struct timespec ts;
+  ts.tv_sec  = time;
+  ts.tv_nsec = (uint64_t)(time * 1000000) % 1000000 * 1000;
+  return ts;
+}
+
+UV_UNUSED(static struct timeval uv__fs_to_timeval(double time)) {
+  struct timeval tv;
+  tv.tv_sec  = time;
+  tv.tv_usec = (uint64_t)(time * 1000000) % 1000000;
+  return tv;
+}
+
 static ssize_t uv__fs_futime(uv_fs_t* req) {
 #if defined(__linux__)                                                        \
     || defined(_AIX71)                                                        \
@@ -198,11 +227,13 @@
    * for the sake of consistency with other platforms.
    */
   struct timespec ts[2];
-  ts[0].tv_sec  = req->atime;
-  ts[0].tv_nsec = (uint64_t)(req->atime * 1000000) % 1000000 * 1000;
-  ts[1].tv_sec  = req->mtime;
-  ts[1].tv_nsec = (uint64_t)(req->mtime * 1000000) % 1000000 * 1000;
+  ts[0] = uv__fs_to_timespec(req->atime);
+  ts[1] = uv__fs_to_timespec(req->mtime);
+#if defined(__ANDROID_API__) && __ANDROID_API__ < 21
+  return utimensat(req->file, NULL, ts, 0);
+#else
   return futimens(req->file, ts);
+#endif
 #elif defined(__APPLE__)                                                      \
     || defined(__DragonFly__)                                                 \
     || defined(__FreeBSD__)                                                   \
@@ -211,10 +242,8 @@
     || defined(__OpenBSD__)                                                   \
     || defined(__sun)
   struct timeval tv[2];
-  tv[0].tv_sec  = req->atime;
-  tv[0].tv_usec = (uint64_t)(req->atime * 1000000) % 1000000;
-  tv[1].tv_sec  = req->mtime;
-  tv[1].tv_usec = (uint64_t)(req->mtime * 1000000) % 1000000;
+  tv[0] = uv__fs_to_timeval(req->atime);
+  tv[1] = uv__fs_to_timeval(req->mtime);
 # if defined(__sun)
   return futimesat(req->file, NULL, tv);
 # else
@@ -250,21 +279,97 @@
 }
 
 
-static ssize_t uv__fs_open(uv_fs_t* req) {
-  static int no_cloexec_support;
-  int r;
+static int (*uv__mkostemp)(char*, int);
 
-  /* Try O_CLOEXEC before entering locks */
-  if (no_cloexec_support == 0) {
+
+static void uv__mkostemp_initonce(void) {
+  /* z/os doesn't have RTLD_DEFAULT but that's okay
+   * because it doesn't have mkostemp(O_CLOEXEC) either.
+   */
+#ifdef RTLD_DEFAULT
+  uv__mkostemp = (int (*)(char*, int)) dlsym(RTLD_DEFAULT, "mkostemp");
+
+  /* We don't care about errors, but we do want to clean them up.
+   * If there has been no error, then dlerror() will just return
+   * NULL.
+   */
+  dlerror();
+#endif  /* RTLD_DEFAULT */
+}
+
+
+static int uv__fs_mkstemp(uv_fs_t* req) {
+  static uv_once_t once = UV_ONCE_INIT;
+  int r;
 #ifdef O_CLOEXEC
-    r = open(req->path, req->flags | O_CLOEXEC, req->mode);
+  static int no_cloexec_support;
+#endif
+  static const char pattern[] = "XXXXXX";
+  static const size_t pattern_size = sizeof(pattern) - 1;
+  char* path;
+  size_t path_length;
+
+  path = (char*) req->path;
+  path_length = strlen(path);
+
+  /* EINVAL can be returned for 2 reasons:
+      1. The template's last 6 characters were not XXXXXX
+      2. open() didn't support O_CLOEXEC
+     We want to avoid going to the fallback path in case
+     of 1, so it's manually checked before. */
+  if (path_length < pattern_size ||
+      strcmp(path + path_length - pattern_size, pattern)) {
+    errno = EINVAL;
+    return -1;
+  }
+
+  uv_once(&once, uv__mkostemp_initonce);
+
+#ifdef O_CLOEXEC
+  if (no_cloexec_support == 0 && uv__mkostemp != NULL) {
+    r = uv__mkostemp(path, O_CLOEXEC);
+
     if (r >= 0)
       return r;
+
+    /* If mkostemp() returns EINVAL, it means the kernel doesn't
+       support O_CLOEXEC, so we just fallback to mkstemp() below. */
     if (errno != EINVAL)
       return r;
+
+    /* We set the static variable so that next calls don't even
+       try to use mkostemp. */
     no_cloexec_support = 1;
-#endif  /* O_CLOEXEC */
   }
+#endif  /* O_CLOEXEC */
+
+  if (req->cb != NULL)
+    uv_rwlock_rdlock(&req->loop->cloexec_lock);
+
+  r = mkstemp(path);
+
+  /* In case of failure `uv__cloexec` will leave error in `errno`,
+   * so it is enough to just set `r` to `-1`.
+   */
+  if (r >= 0 && uv__cloexec(r, 1) != 0) {
+    r = uv__close(r);
+    if (r != 0)
+      abort();
+    r = -1;
+  }
+
+  if (req->cb != NULL)
+    uv_rwlock_rdunlock(&req->loop->cloexec_lock);
+
+  return r;
+}
+
+
+static ssize_t uv__fs_open(uv_fs_t* req) {
+#ifdef O_CLOEXEC
+  return open(req->path, req->flags | O_CLOEXEC, req->mode);
+#else  /* O_CLOEXEC */
+  int r;
 
   if (req->cb != NULL)
     uv_rwlock_rdlock(&req->loop->cloexec_lock);
@@ -285,9 +390,60 @@
     uv_rwlock_rdunlock(&req->loop->cloexec_lock);
 
   return r;
+#endif  /* O_CLOEXEC */
 }
 
 
+#if !HAVE_PREADV
+static ssize_t uv__fs_preadv(uv_file fd,
+                             uv_buf_t* bufs,
+                             unsigned int nbufs,
+                             off_t off) {
+  uv_buf_t* buf;
+  uv_buf_t* end;
+  ssize_t result;
+  ssize_t rc;
+  size_t pos;
+
+  assert(nbufs > 0);
+
+  result = 0;
+  pos = 0;
+  buf = bufs + 0;
+  end = bufs + nbufs;
+
+  for (;;) {
+    do
+      rc = pread(fd, buf->base + pos, buf->len - pos, off + result);
+    while (rc == -1 && errno == EINTR);
+
+    if (rc == 0)
+      break;
+
+    if (rc == -1 && result == 0)
+      return UV__ERR(errno);
+
+    if (rc == -1)
+      break;  /* We read some data so return that, ignore the error. */
+
+    pos += rc;
+    result += rc;
+
+    if (pos < buf->len)
+      continue;
+
+    pos = 0;
+    buf += 1;
+
+    if (buf == end)
+      break;
+  }
+
+  return result;
+}
+#endif
+
+
 static ssize_t uv__fs_read(uv_fs_t* req) {
 #if defined(__linux__)
   static int no_preadv;
@@ -317,7 +473,7 @@
     if (no_preadv) retry:
 # endif
     {
-      result = pread(req->file, req->bufs[0].base, req->bufs[0].len, req->off);
+      result = uv__fs_preadv(req->file, req->bufs, req->nbufs, req->off);
     }
 # if defined(__linux__)
     else {
@@ -481,14 +637,39 @@
   return 0;
 }
 
-#if defined(_POSIX_PATH_MAX)
-# define UV__FS_PATH_MAX _POSIX_PATH_MAX
-#elif defined(PATH_MAX)
-# define UV__FS_PATH_MAX PATH_MAX
+static int uv__fs_statfs(uv_fs_t* req) {
+  uv_statfs_t* stat_fs;
+#if defined(__sun) || defined(__MVS__) || defined(__NetBSD__) || defined(__HAIKU__)
+  struct statvfs buf;
+
+  if (0 != statvfs(req->path, &buf))
 #else
-# define UV__FS_PATH_MAX_FALLBACK 8192
-# define UV__FS_PATH_MAX UV__FS_PATH_MAX_FALLBACK
+  struct statfs buf;
+
+  if (0 != statfs(req->path, &buf))
+#endif /* defined(__sun) */
+    return -1;
+
+  stat_fs = uv__malloc(sizeof(*stat_fs));
+  if (stat_fs == NULL) {
+    errno = ENOMEM;
+    return -1;
+  }
+
+#if defined(__sun) || defined(__MVS__) || defined(__OpenBSD__) || defined(__NetBSD__) || defined(__HAIKU__)
+  stat_fs->f_type = 0;  /* f_type is not supported. */
+#else
+  stat_fs->f_type = buf.f_type;
 #endif
+  stat_fs->f_bsize = buf.f_bsize;
+  stat_fs->f_blocks = buf.f_blocks;
+  stat_fs->f_bfree = buf.f_bfree;
+  stat_fs->f_bavail = buf.f_bavail;
+  stat_fs->f_files = buf.f_files;
+  stat_fs->f_ffree = buf.f_ffree;
+  req->ptr = stat_fs;
+  return 0;
+}
 
 static ssize_t uv__fs_pathmax_size(const char* path) {
   ssize_t pathmax;
@@ -496,7 +677,7 @@
   pathmax = pathconf(path, _PC_PATH_MAX);
 
   if (pathmax == -1)
-    pathmax = UV__FS_PATH_MAX;
+    pathmax = UV__PATH_MAX;
 
   return pathmax;
 }
@@ -505,9 +686,10 @@
   ssize_t maxlen;
   ssize_t len;
   char* buf;
-  char* newbuf;
 
-#if defined(UV__FS_PATH_MAX_FALLBACK)
+#if defined(_POSIX_PATH_MAX) || defined(PATH_MAX)
+  maxlen = uv__fs_pathmax_size(req->path);
+#else
   /* We may not have a real PATH_MAX.  Read size of link.  */
   struct stat st;
   int ret;
@@ -525,8 +707,6 @@
      for some symlinks, such as those in /proc or /sys.  */
   if (maxlen == 0)
     maxlen = uv__fs_pathmax_size(req->path);
-#else
-  maxlen = uv__fs_pathmax_size(req->path);
 #endif
 
   buf = uv__malloc(maxlen);
@@ -549,14 +729,10 @@
 
   /* Uncommon case: resize to make room for the trailing nul byte. */
   if (len == maxlen) {
-    newbuf = uv__realloc(buf, len + 1);
+    buf = uv__reallocf(buf, len + 1);
 
-    if (newbuf == NULL) {
-      uv__free(buf);
+    if (buf == NULL)
       return -1;
-    }
-
-    buf = newbuf;
   }
 
   buf[len] = '\0';
@@ -816,10 +992,8 @@
    * for the sake of consistency with other platforms.
    */
   struct timespec ts[2];
-  ts[0].tv_sec  = req->atime;
-  ts[0].tv_nsec = (uint64_t)(req->atime * 1000000) % 1000000 * 1000;
-  ts[1].tv_sec  = req->mtime;
-  ts[1].tv_nsec = (uint64_t)(req->mtime * 1000000) % 1000000 * 1000;
+  ts[0] = uv__fs_to_timespec(req->atime);
+  ts[1] = uv__fs_to_timespec(req->mtime);
   return utimensat(AT_FDCWD, req->path, ts, 0);
 #elif defined(__APPLE__)                                                      \
     || defined(__DragonFly__)                                                 \
@@ -828,10 +1002,8 @@
     || defined(__NetBSD__)                                                    \
     || defined(__OpenBSD__)
   struct timeval tv[2];
-  tv[0].tv_sec  = req->atime;
-  tv[0].tv_usec = (uint64_t)(req->atime * 1000000) % 1000000;
-  tv[1].tv_sec  = req->mtime;
-  tv[1].tv_usec = (uint64_t)(req->mtime * 1000000) % 1000000;
+  tv[0] = uv__fs_to_timeval(req->atime);
+  tv[1] = uv__fs_to_timeval(req->mtime);
   return utimes(req->path, tv);
 #elif defined(_AIX)                                                           \
     && !defined(_AIX71)
@@ -854,6 +1026,31 @@
 }
 
 
+static ssize_t uv__fs_lutime(uv_fs_t* req) {
+#if defined(__linux__)            ||                                           \
+    defined(_AIX71)               ||                                           \
+    defined(__sun)                ||                                           \
+    defined(__HAIKU__)
+  struct timespec ts[2];
+  ts[0] = uv__fs_to_timespec(req->atime);
+  ts[1] = uv__fs_to_timespec(req->mtime);
+  return utimensat(AT_FDCWD, req->path, ts, AT_SYMLINK_NOFOLLOW);
+#elif defined(__APPLE__)          ||                                          \
+      defined(__DragonFly__)      ||                                          \
+      defined(__FreeBSD__)        ||                                          \
+      defined(__FreeBSD_kernel__) ||                                          \
+      defined(__NetBSD__)
+  struct timeval tv[2];
+  tv[0] = uv__fs_to_timeval(req->atime);
+  tv[1] = uv__fs_to_timeval(req->mtime);
+  return lutimes(req->path, tv);
+#else
+  errno = ENOSYS;
+  return -1;
+#endif
+}
+
+
 static ssize_t uv__fs_write(uv_fs_t* req) {
 #if defined(__linux__)
   static int no_pwritev;
@@ -918,12 +1115,15 @@
   uv_fs_t fs_req;
   uv_file srcfd;
   uv_file dstfd;
-  struct stat statsbuf;
+  struct stat src_statsbuf;
+  struct stat dst_statsbuf;
   int dst_flags;
   int result;
   int err;
-  size_t bytes_to_send;
-  int64_t in_offset;
+  off_t bytes_to_send;
+  off_t in_offset;
+  off_t bytes_written;
+  size_t bytes_chunk;
 
   dstfd = -1;
   err = 0;
@@ -936,7 +1136,7 @@
     return srcfd;
 
   /* Get the source file's mode. */
-  if (fstat(srcfd, &statsbuf)) {
+  if (fstat(srcfd, &src_statsbuf)) {
     err = UV__ERR(errno);
     goto out;
   }
@@ -951,7 +1151,7 @@
                      &fs_req,
                      req->new_path,
                      dst_flags,
-                     statsbuf.st_mode,
+                     src_statsbuf.st_mode,
                      NULL);
   uv_fs_req_cleanup(&fs_req);
 
@@ -960,26 +1160,55 @@
     goto out;
   }
 
-  if (fchmod(dstfd, statsbuf.st_mode) == -1) {
+  /* Get the destination file's mode. */
+  if (fstat(dstfd, &dst_statsbuf)) {
     err = UV__ERR(errno);
     goto out;
   }
 
+  /* Check if srcfd and dstfd refer to the same file */
+  if (src_statsbuf.st_dev == dst_statsbuf.st_dev &&
+      src_statsbuf.st_ino == dst_statsbuf.st_ino) {
+    goto out;
+  }
+
+  if (fchmod(dstfd, src_statsbuf.st_mode) == -1) {
+    err = UV__ERR(errno);
+#ifdef __linux__
+    if (err != UV_EPERM)
+      goto out;
+
+    {
+      struct statfs s;
+
+      /* fchmod() on CIFS shares always fails with EPERM unless the share is
+       * mounted with "noperm". As fchmod() is a meaningless operation on such
+       * shares anyway, detect that condition and squelch the error.
+       */
+      if (fstatfs(dstfd, &s) == -1)
+        goto out;
+
+      if (s.f_type != /* CIFS */ 0xFF534D42u)
+        goto out;
+    }
+
+    err = 0;
+#else  /* !__linux__ */
+    goto out;
+#endif  /* !__linux__ */
+  }
+
 #ifdef FICLONE
   if (req->flags & UV_FS_COPYFILE_FICLONE ||
       req->flags & UV_FS_COPYFILE_FICLONE_FORCE) {
-    if (ioctl(dstfd, FICLONE, srcfd) == -1) {
-      /* If an error occurred that the sendfile fallback also won't handle, or
-         this is a force clone then exit. Otherwise, fall through to try using
-         sendfile(). */
-      if (errno != ENOTTY && errno != EOPNOTSUPP && errno != EXDEV) {
-        err = UV__ERR(errno);
-        goto out;
-      } else if (req->flags & UV_FS_COPYFILE_FICLONE_FORCE) {
-        err = UV_ENOTSUP;
-        goto out;
-      }
-    } else {
+    if (ioctl(dstfd, FICLONE, srcfd) == 0) {
+      /* ioctl() with FICLONE succeeded. */
+      goto out;
+    }
+    /* If an error occurred and force was set, return the error to the caller;
+     * fall back to sendfile() when force was not set. */
+    if (req->flags & UV_FS_COPYFILE_FICLONE_FORCE) {
+      err = UV__ERR(errno);
       goto out;
     }
   }
@@ -990,21 +1219,23 @@
   }
 #endif
 
-  bytes_to_send = statsbuf.st_size;
+  bytes_to_send = src_statsbuf.st_size;
   in_offset = 0;
   while (bytes_to_send != 0) {
-    err = uv_fs_sendfile(NULL,
-                         &fs_req,
-                         dstfd,
-                         srcfd,
-                         in_offset,
-                         bytes_to_send,
-                         NULL);
+    bytes_chunk = SSIZE_MAX;
+    if (bytes_to_send < (off_t) bytes_chunk)
+      bytes_chunk = bytes_to_send;
+    uv_fs_sendfile(NULL, &fs_req, dstfd, srcfd, in_offset, bytes_chunk, NULL);
+    bytes_written = fs_req.result;
     uv_fs_req_cleanup(&fs_req);
-    if (err < 0)
+
+    if (bytes_written < 0) {
+      err = bytes_written;
       break;
-    bytes_to_send -= fs_req.result;
-    in_offset += fs_req.result;
+    }
+
+    bytes_to_send -= bytes_written;
+    in_offset += bytes_written;
   }
 
 out:
@@ -1151,13 +1382,22 @@
 
   rc = uv__statx(dirfd, path, flags, mode, &statxbuf);
 
-  if (rc == -1) {
+  switch (rc) {
+  case 0:
+    break;
+  case -1:
     /* EPERM happens when a seccomp filter rejects the system call.
      * Has been observed with libseccomp < 2.3.3 and docker < 18.04.
      */
     if (errno != EINVAL && errno != EPERM && errno != ENOSYS)
       return -1;
-
+    /* Fall through. */
+  default:
+    /* Normally on success, zero is returned and On error, -1 is returned.
+     * Observed on S390 RHEL running in a docker container with statx not
+     * implemented, rc might return 1 with 0 set as the error code in which
+     * case we return ENOSYS.
+     */
     no_statx = 1;
     return UV_ENOSYS;
   }
@@ -1328,10 +1568,12 @@
     X(FSYNC, uv__fs_fsync(req));
     X(FTRUNCATE, ftruncate(req->file, req->off));
     X(FUTIME, uv__fs_futime(req));
+    X(LUTIME, uv__fs_lutime(req));
     X(LSTAT, uv__fs_lstat(req->path, &req->statbuf));
     X(LINK, link(req->path, req->new_path));
     X(MKDIR, mkdir(req->path, req->mode));
     X(MKDTEMP, uv__fs_mkdtemp(req));
+    X(MKSTEMP, uv__fs_mkstemp(req));
     X(OPEN, uv__fs_open(req));
     X(READ, uv__fs_read(req));
     X(SCANDIR, uv__fs_scandir(req));
@@ -1344,6 +1586,7 @@
     X(RMDIR, rmdir(req->path));
     X(SENDFILE, uv__fs_sendfile(req));
     X(STAT, uv__fs_stat(req->path, &req->statbuf));
+    X(STATFS, uv__fs_statfs(req));
     X(SYMLINK, symlink(req->path, req->new_path));
     X(UNLINK, unlink(req->path));
     X(UTIME, uv__fs_utime(req));
@@ -1512,6 +1755,19 @@
   POST;
 }
 
+int uv_fs_lutime(uv_loop_t* loop,
+                 uv_fs_t* req,
+                 const char* path,
+                 double atime,
+                 double mtime,
+                 uv_fs_cb cb) {
+  INIT(LUTIME);
+  PATH;
+  req->atime = atime;
+  req->mtime = mtime;
+  POST;
+}
+
 
 int uv_fs_lstat(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb) {
   INIT(LSTAT);
@@ -1555,6 +1811,18 @@
 }
 
 
+int uv_fs_mkstemp(uv_loop_t* loop,
+                  uv_fs_t* req,
+                  const char* tpl,
+                  uv_fs_cb cb) {
+  INIT(MKSTEMP);
+  req->path = uv__strdup(tpl);
+  if (req->path == NULL)
+    return UV_ENOMEM;
+  POST;
+}
+
+
 int uv_fs_open(uv_loop_t* loop,
                uv_fs_t* req,
                const char* path,
@@ -1773,10 +2041,12 @@
 
   /* Only necessary for asychronous requests, i.e., requests with a callback.
    * Synchronous ones don't copy their arguments and have req->path and
-   * req->new_path pointing to user-owned memory.  UV_FS_MKDTEMP is the
-   * exception to the rule, it always allocates memory.
+   * req->new_path pointing to user-owned memory.  UV_FS_MKDTEMP and 
+   * UV_FS_MKSTEMP are the exception to the rule, they always allocate memory.
    */
-  if (req->path != NULL && (req->cb != NULL || req->fs_type == UV_FS_MKDTEMP))
+  if (req->path != NULL &&
+      (req->cb != NULL ||
+        req->fs_type == UV_FS_MKDTEMP || req->fs_type == UV_FS_MKSTEMP))
     uv__free((void*) req->path);  /* Memory is shared with req->new_path. */
 
   req->path = NULL;
@@ -1816,3 +2086,17 @@
   req->flags = flags;
   POST;
 }
+
+
+int uv_fs_statfs(uv_loop_t* loop,
+                 uv_fs_t* req,
+                 const char* path,
+                 uv_fs_cb cb) {
+  INIT(STATFS);
+  PATH;
+  POST;
+}
+
+int uv_fs_get_system_error(const uv_fs_t* req) {
+  return -req->result;
+}
diff --git a/Utilities/cmlibuv/src/unix/fsevents.c b/Utilities/cmlibuv/src/unix/fsevents.c
index ddacda3..a51f29b 100644
--- a/Utilities/cmlibuv/src/unix/fsevents.c
+++ b/Utilities/cmlibuv/src/unix/fsevents.c
@@ -41,34 +41,33 @@
 
 #else /* TARGET_OS_IPHONE */
 
+#include "darwin-stub.h"
+
 #include <dlfcn.h>
 #include <assert.h>
 #include <stdlib.h>
 #include <pthread.h>
 
-#include <CoreFoundation/CFRunLoop.h>
-#include <CoreServices/CoreServices.h>
+static const int kFSEventsModified =
+    kFSEventStreamEventFlagItemChangeOwner |
+    kFSEventStreamEventFlagItemFinderInfoMod |
+    kFSEventStreamEventFlagItemInodeMetaMod |
+    kFSEventStreamEventFlagItemModified |
+    kFSEventStreamEventFlagItemXattrMod;
 
-/* These are macros to avoid "initializer element is not constant" errors
- * with old versions of gcc.
- */
-#define kFSEventsModified (kFSEventStreamEventFlagItemFinderInfoMod |         \
-                           kFSEventStreamEventFlagItemModified |              \
-                           kFSEventStreamEventFlagItemInodeMetaMod |          \
-                           kFSEventStreamEventFlagItemChangeOwner |           \
-                           kFSEventStreamEventFlagItemXattrMod)
+static const int kFSEventsRenamed =
+    kFSEventStreamEventFlagItemCreated |
+    kFSEventStreamEventFlagItemRemoved |
+    kFSEventStreamEventFlagItemRenamed;
 
-#define kFSEventsRenamed  (kFSEventStreamEventFlagItemCreated |               \
-                           kFSEventStreamEventFlagItemRemoved |               \
-                           kFSEventStreamEventFlagItemRenamed)
-
-#define kFSEventsSystem   (kFSEventStreamEventFlagUserDropped |               \
-                           kFSEventStreamEventFlagKernelDropped |             \
-                           kFSEventStreamEventFlagEventIdsWrapped |           \
-                           kFSEventStreamEventFlagHistoryDone |               \
-                           kFSEventStreamEventFlagMount |                     \
-                           kFSEventStreamEventFlagUnmount |                   \
-                           kFSEventStreamEventFlagRootChanged)
+static const int kFSEventsSystem =
+    kFSEventStreamEventFlagUserDropped |
+    kFSEventStreamEventFlagKernelDropped |
+    kFSEventStreamEventFlagEventIdsWrapped |
+    kFSEventStreamEventFlagHistoryDone |
+    kFSEventStreamEventFlagMount |
+    kFSEventStreamEventFlagUnmount |
+    kFSEventStreamEventFlagRootChanged;
 
 typedef struct uv__fsevents_event_s uv__fsevents_event_t;
 typedef struct uv__cf_loop_signal_s uv__cf_loop_signal_t;
@@ -148,7 +147,7 @@
 static void (*pFSEventStreamScheduleWithRunLoop)(FSEventStreamRef,
                                                  CFRunLoopRef,
                                                  CFStringRef);
-static Boolean (*pFSEventStreamStart)(FSEventStreamRef);
+static int (*pFSEventStreamStart)(FSEventStreamRef);
 static void (*pFSEventStreamStop)(FSEventStreamRef);
 
 #define UV__FSEVENTS_PROCESS(handle, block)                                   \
@@ -215,7 +214,7 @@
 
 
 /* Runs in CF thread, when there're events in FSEventStream */
-static void uv__fsevents_event_cb(ConstFSEventStreamRef streamRef,
+static void uv__fsevents_event_cb(const FSEventStreamRef streamRef,
                                   void* info,
                                   size_t numEvents,
                                   void* eventPaths,
@@ -263,10 +262,12 @@
       if (len < handle->realpath_len)
         continue;
 
+      /* Make sure that realpath actually named a directory,
+       * (unless watching root, which alone keeps a trailing slash on the realpath)
+       * or that we matched the whole string */
       if (handle->realpath_len != len &&
+          handle->realpath_len > 1 &&
           path[handle->realpath_len] != '/')
-        /* Make sure that realpath actually named a directory,
-         * or that we matched the whole string */
         continue;
 
       if (memcmp(path, handle->realpath, handle->realpath_len) != 0)
@@ -338,11 +339,8 @@
   FSEventStreamCreateFlags flags;
 
   /* Initialize context */
-  ctx.version = 0;
+  memset(&ctx, 0, sizeof(ctx));
   ctx.info = loop;
-  ctx.retain = NULL;
-  ctx.release = NULL;
-  ctx.copyDescription = NULL;
 
   latency = 0.05;
 
@@ -745,6 +743,8 @@
                          state->signal_source,
                          *pkCFRunLoopDefaultMode);
 
+  state->loop = NULL;
+
   return NULL;
 }
 
@@ -797,13 +797,14 @@
 
   uv_mutex_lock(&loop->cf_mutex);
   QUEUE_INSERT_TAIL(&loop->cf_signals, &item->member);
-  uv_mutex_unlock(&loop->cf_mutex);
 
   state = loop->cf_state;
   assert(state != NULL);
   pCFRunLoopSourceSignal(state->signal_source);
   pCFRunLoopWakeUp(state->loop);
 
+  uv_mutex_unlock(&loop->cf_mutex);
+
   return 0;
 }
 
diff --git a/Utilities/cmlibuv/src/unix/haiku.c b/Utilities/cmlibuv/src/unix/haiku.c
index 7708851..cf17d83 100644
--- a/Utilities/cmlibuv/src/unix/haiku.c
+++ b/Utilities/cmlibuv/src/unix/haiku.c
@@ -165,12 +165,3 @@
 
   return 0;
 }
-
-void uv_free_cpu_info(uv_cpu_info_t* cpu_infos, int count) {
-  int i;
-
-  for (i = 0; i < count; i++)
-    uv__free(cpu_infos[i].model);
-
-  uv__free(cpu_infos);
-}
diff --git a/Utilities/cmlibuv/src/unix/ibmi.c b/Utilities/cmlibuv/src/unix/ibmi.c
index c7e1051..e4c5122 100644
--- a/Utilities/cmlibuv/src/unix/ibmi.c
+++ b/Utilities/cmlibuv/src/unix/ibmi.c
@@ -56,6 +56,7 @@
 #include <sys/vnode.h>
 
 #include <as400_protos.h>
+#include <as400_types.h>
 
 
 typedef struct {
@@ -98,24 +99,91 @@
 } SSTS0200;
 
 
+typedef struct {
+  char header[208];
+  unsigned char loca_adapter_address[12];
+} LIND0500;
+
+
+typedef struct {
+  int bytes_provided;
+  int bytes_available;
+  char msgid[7];
+} errcode_s;
+
+
+static const unsigned char e2a[256] = {
+    0, 1, 2, 3, 156, 9, 134, 127, 151, 141, 142, 11, 12, 13, 14, 15,
+    16, 17, 18, 19, 157, 133, 8, 135, 24, 25, 146, 143, 28, 29, 30, 31,
+    128, 129, 130, 131, 132, 10, 23, 27, 136, 137, 138, 139, 140, 5, 6, 7,
+    144, 145, 22, 147, 148, 149, 150, 4, 152, 153, 154, 155, 20, 21, 158, 26,
+    32, 160, 161, 162, 163, 164, 165, 166, 167, 168, 91, 46, 60, 40, 43, 33,
+    38, 169, 170, 171, 172, 173, 174, 175, 176, 177, 93, 36, 42, 41, 59, 94,
+    45, 47, 178, 179, 180, 181, 182, 183, 184, 185, 124, 44, 37, 95, 62, 63,
+    186, 187, 188, 189, 190, 191, 192, 193, 194, 96, 58, 35, 64, 39, 61, 34,
+    195, 97, 98, 99, 100, 101, 102, 103, 104, 105, 196, 197, 198, 199, 200, 201,
+    202, 106, 107, 108, 109, 110, 111, 112, 113, 114, 203, 204, 205, 206, 207, 208,
+    209, 126, 115, 116, 117, 118, 119, 120, 121, 122, 210, 211, 212, 213, 214, 215,
+    216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231,
+    123, 65, 66, 67, 68, 69, 70, 71, 72, 73, 232, 233, 234, 235, 236, 237,
+    125, 74, 75, 76, 77, 78, 79, 80, 81, 82, 238, 239, 240, 241, 242, 243,
+    92, 159, 83, 84, 85, 86, 87, 88, 89, 90, 244, 245, 246, 247, 248, 249,
+    48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 250, 251, 252, 253, 254, 255};
+
+
+static const unsigned char a2e[256] = {
+    0, 1, 2, 3, 55, 45, 46, 47, 22, 5, 37, 11, 12, 13, 14, 15,
+    16, 17, 18, 19, 60, 61, 50, 38, 24, 25, 63, 39, 28, 29, 30, 31,
+    64, 79, 127, 123, 91, 108, 80, 125, 77, 93, 92, 78, 107, 96, 75, 97,
+    240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 122, 94, 76, 126, 110, 111,
+    124, 193, 194, 195, 196, 197, 198, 199, 200, 201, 209, 210, 211, 212, 213, 214,
+    215, 216, 217, 226, 227, 228, 229, 230, 231, 232, 233, 74, 224, 90, 95, 109,
+    121, 129, 130, 131, 132, 133, 134, 135, 136, 137, 145, 146, 147, 148, 149, 150,
+    151, 152, 153, 162, 163, 164, 165, 166, 167, 168, 169, 192, 106, 208, 161, 7,
+    32, 33, 34, 35, 36, 21, 6, 23, 40, 41, 42, 43, 44, 9, 10, 27,
+    48, 49, 26, 51, 52, 53, 54, 8, 56, 57, 58, 59, 4, 20, 62, 225,
+    65, 66, 67, 68, 69, 70, 71, 72, 73, 81, 82, 83, 84, 85, 86, 87,
+    88, 89, 98, 99, 100, 101, 102, 103, 104, 105, 112, 113, 114, 115, 116, 117,
+    118, 119, 120, 128, 138, 139, 140, 141, 142, 143, 144, 154, 155, 156, 157, 158,
+    159, 160, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183,
+    184, 185, 186, 187, 188, 189, 190, 191, 202, 203, 204, 205, 206, 207, 218, 219,
+    220, 221, 222, 223, 234, 235, 236, 237, 238, 239, 250, 251, 252, 253, 254, 255};
+
+
+static void iconv_e2a(unsigned char src[], unsigned char dst[], size_t length) {
+  size_t i;
+  for (i = 0; i < length; i++)
+    dst[i] = e2a[src[i]];
+}
+
+
+static void iconv_a2e(const char* src, unsigned char dst[], size_t length) {
+  size_t srclen;
+  size_t i;
+
+  srclen = strlen(src);
+  if (srclen > length)
+    abort();
+  for (i = 0; i < srclen; i++)
+    dst[i] = a2e[src[i]];
+  /* padding the remaining part with spaces */
+  for (; i < length; i++)
+    dst[i] = a2e[' '];
+}
+
+
 static int get_ibmi_system_status(SSTS0200* rcvr) {
   /* rcvrlen is input parameter 2 to QWCRSSTS */
   unsigned int rcvrlen = sizeof(*rcvr);
+  unsigned char format[8], reset_status[10];
 
-  /* format is input parameter 3 to QWCRSSTS ("SSTS0200" in EBCDIC) */
-  unsigned char format[] = {0xE2, 0xE2, 0xE3, 0xE2, 0xF0, 0xF2, 0xF0, 0xF0};
-
-  /* reset_status is input parameter 4 to QWCRSSTS ("*NO       " in EBCDIC) */
-  unsigned char reset_status[] = {
-    0x5C, 0xD5, 0xD6, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40
-  };
+  /* format is input parameter 3 to QWCRSSTS */
+  iconv_a2e("SSTS0200", format, sizeof(format));
+  /* reset_status is input parameter 4 */
+  iconv_a2e("*NO", reset_status, sizeof(reset_status));
 
   /* errcode is input parameter 5 to QWCRSSTS */
-  struct _errcode {
-    int bytes_provided;
-    int bytes_available;
-    char msgid[7];
-  } errcode;
+  errcode_s errcode;
 
   /* qwcrssts_pointer is the 16-byte tagged system pointer to QWCRSSTS */
   ILEpointer __attribute__((aligned(16))) qwcrssts_pointer;
@@ -145,7 +213,7 @@
   qwcrssts_argv[5] = NULL;
 
   /* Call the IBM i QWCRSSTS API from PASE */
-  rc = _PGMCALL(&qwcrssts_pointer, (void**)&qwcrssts_argv, 0);
+  rc = _PGMCALL(&qwcrssts_pointer, qwcrssts_argv, 0);
 
   return rc;
 }
@@ -157,19 +225,7 @@
   if (get_ibmi_system_status(&rcvr))
     return 0;
 
-  /* The amount of main storage, in kilobytes, in the system. */
-  uint64_t main_storage_size = rcvr.main_storage_size;
-
-  /* The current amount of storage in use for temporary objects.
-   * in millions (M) of bytes.
-   */
-  uint64_t current_unprotected_storage_used =
-    rcvr.current_unprotected_storage_used * 1024ULL;
-
-  uint64_t free_storage_size =
-    (main_storage_size - current_unprotected_storage_used) * 1024ULL;
-
-  return free_storage_size < 0 ? 0 : free_storage_size;
+  return (uint64_t)rcvr.main_storage_size * 1024ULL;
 }
 
 
@@ -248,3 +304,159 @@
   return 0;
 }
 
+
+static int get_ibmi_physical_address(const char* line, char (*phys_addr)[6]) {
+  LIND0500 rcvr;
+  /* rcvrlen is input parameter 2 to QDCRLIND */
+  unsigned int rcvrlen = sizeof(rcvr);
+  unsigned char format[8], line_name[10];
+  unsigned char mac_addr[sizeof(rcvr.loca_adapter_address)];
+  int c[6];
+
+  /* format is input parameter 3 to QDCRLIND */
+  iconv_a2e("LIND0500", format, sizeof(format));
+
+  /* line_name is input parameter 4 to QDCRLIND */
+  iconv_a2e(line, line_name, sizeof(line_name));
+
+  /* err is input parameter 5 to QDCRLIND */
+  errcode_s err;
+
+  /* qwcrssts_pointer is the 16-byte tagged system pointer to QDCRLIND */
+  ILEpointer __attribute__((aligned(16))) qdcrlind_pointer;
+
+  /* qwcrssts_argv is the array of argument pointers to QDCRLIND */
+  void* qdcrlind_argv[6];
+
+  /* Set the IBM i pointer to the QSYS/QDCRLIND *PGM object */
+  int rc = _RSLOBJ2(&qdcrlind_pointer, RSLOBJ_TS_PGM, "QDCRLIND", "QSYS");
+
+  if (rc != 0)
+    return rc;
+
+  /* initialize the QDCRLIND returned info structure */
+  memset(&rcvr, 0, sizeof(rcvr));
+
+  /* initialize the QDCRLIND error code structure */
+  memset(&err, 0, sizeof(err));
+  err.bytes_provided = sizeof(err);
+
+  /* initialize the array of argument pointers for the QDCRLIND API */
+  qdcrlind_argv[0] = &rcvr;
+  qdcrlind_argv[1] = &rcvrlen;
+  qdcrlind_argv[2] = &format;
+  qdcrlind_argv[3] = &line_name;
+  qdcrlind_argv[4] = &err;
+  qdcrlind_argv[5] = NULL;
+
+  /* Call the IBM i QDCRLIND API from PASE */
+  rc = _PGMCALL(&qdcrlind_pointer, qdcrlind_argv, 0);
+  if (rc != 0)
+    return rc;
+
+  /* convert ebcdic loca_adapter_address to ascii first */
+  iconv_e2a(rcvr.loca_adapter_address, mac_addr,
+            sizeof(rcvr.loca_adapter_address));
+
+  /* convert loca_adapter_address(char[12]) to phys_addr(char[6]) */
+  int r = sscanf(mac_addr, "%02x%02x%02x%02x%02x%02x",
+                &c[0], &c[1], &c[2], &c[3], &c[4], &c[5]);
+
+  if (r == ARRAY_SIZE(c)) {
+    (*phys_addr)[0] = c[0];
+    (*phys_addr)[1] = c[1];
+    (*phys_addr)[2] = c[2];
+    (*phys_addr)[3] = c[3];
+    (*phys_addr)[4] = c[4];
+    (*phys_addr)[5] = c[5];
+  } else {
+    memset(*phys_addr, 0, sizeof(*phys_addr));
+    rc = -1;
+  }
+  return rc;
+}
+
+
+int uv_interface_addresses(uv_interface_address_t** addresses, int* count) {
+  uv_interface_address_t* address;
+  struct ifaddrs_pase *ifap = NULL, *cur;
+  int inet6, r = 0;
+
+  *count = 0;
+  *addresses = NULL;
+
+  if (Qp2getifaddrs(&ifap))
+    return UV_ENOSYS;
+
+  /* The first loop to get the size of the array to be allocated */
+  for (cur = ifap; cur; cur = cur->ifa_next) {
+    if (!(cur->ifa_addr->sa_family == AF_INET6 ||
+          cur->ifa_addr->sa_family == AF_INET))
+      continue;
+
+    if (!(cur->ifa_flags & IFF_UP && cur->ifa_flags & IFF_RUNNING))
+      continue;
+
+    (*count)++;
+  }
+
+  if (*count == 0) {
+    Qp2freeifaddrs(ifap);
+    return 0;
+  }
+
+  /* Alloc the return interface structs */
+  *addresses = uv__calloc(*count, sizeof(**addresses));
+  if (*addresses == NULL) {
+    Qp2freeifaddrs(ifap);
+    return UV_ENOMEM;
+  }
+  address = *addresses;
+
+  /* The second loop to fill in the array */
+  for (cur = ifap; cur; cur = cur->ifa_next) {
+    if (!(cur->ifa_addr->sa_family == AF_INET6 ||
+          cur->ifa_addr->sa_family == AF_INET))
+      continue;
+
+    if (!(cur->ifa_flags & IFF_UP && cur->ifa_flags & IFF_RUNNING))
+      continue;
+
+    address->name = uv__strdup(cur->ifa_name);
+
+    inet6 = (cur->ifa_addr->sa_family == AF_INET6);
+
+    if (inet6) {
+      address->address.address6 = *((struct sockaddr_in6*)cur->ifa_addr);
+      address->netmask.netmask6 = *((struct sockaddr_in6*)cur->ifa_netmask);
+      address->netmask.netmask6.sin6_family = AF_INET6;
+    } else {
+      address->address.address4 = *((struct sockaddr_in*)cur->ifa_addr);
+      address->netmask.netmask4 = *((struct sockaddr_in*)cur->ifa_netmask);
+      address->netmask.netmask4.sin_family = AF_INET;
+    }
+    address->is_internal = cur->ifa_flags & IFF_LOOPBACK ? 1 : 0;
+    if (!address->is_internal) {
+      int rc = get_ibmi_physical_address(address->name, &address->phys_addr);
+      if (rc != 0)
+        r = rc;
+    }
+
+    address++;
+  }
+
+  Qp2freeifaddrs(ifap);
+  return r;
+}
+
+
+void uv_free_interface_addresses(uv_interface_address_t* addresses, int count) {
+  int i;
+
+  for (i = 0; i < count; ++i) {
+    uv__free(addresses[i].name);
+  }
+
+  uv__free(addresses);
+}
+
diff --git a/Utilities/cmlibuv/src/unix/internal.h b/Utilities/cmlibuv/src/unix/internal.h
index b43c0b1..2549602 100644
--- a/Utilities/cmlibuv/src/unix/internal.h
+++ b/Utilities/cmlibuv/src/unix/internal.h
@@ -25,11 +25,13 @@
 #include "uv-common.h"
 
 #include <assert.h>
+#include <limits.h> /* _POSIX_PATH_MAX, PATH_MAX */
 #include <stdlib.h> /* abort */
 #include <string.h> /* strrchr */
-#include <fcntl.h>  /* O_CLOEXEC, may be */
+#include <fcntl.h>  /* O_CLOEXEC and O_NONBLOCK, if supported. */
 #include <stdio.h>
 #include <errno.h>
+#include <sys/socket.h>
 
 #if defined(__STRICT_ANSI__)
 # define inline __inline
@@ -60,6 +62,14 @@
 # include <AvailabilityMacros.h>
 #endif
 
+#if defined(_POSIX_PATH_MAX)
+# define UV__PATH_MAX _POSIX_PATH_MAX
+#elif defined(PATH_MAX)
+# define UV__PATH_MAX PATH_MAX
+#else
+# define UV__PATH_MAX 8192
+#endif
+
 #if defined(CMAKE_BOOTSTRAP)
 # undef pthread_atfork
 # define pthread_atfork(prepare, parent, child) \
@@ -106,10 +116,8 @@
 #if defined(__clang__) ||                                                     \
     defined(__GNUC__) ||                                                      \
     defined(__INTEL_COMPILER)
-# define UV_DESTRUCTOR(declaration) __attribute__((destructor)) declaration
 # define UV_UNUSED(declaration)     __attribute__((unused)) declaration
 #else
-# define UV_DESTRUCTOR(declaration) declaration
 # define UV_UNUSED(declaration)     declaration
 #endif
 
@@ -271,6 +279,12 @@
 FILE* uv__open_file(const char* path);
 int uv__getpwuid_r(uv_passwd_t* pwd);
 
+/* random */
+int uv__random_devurandom(void* buf, size_t buflen);
+int uv__random_getrandom(void* buf, size_t buflen);
+int uv__random_getentropy(void* buf, size_t buflen);
+int uv__random_readpath(const char* path, void* buf, size_t buflen);
+int uv__random_sysctl(void* buf, size_t buflen);
 
 #if defined(__APPLE__) && !defined(CMAKE_BOOTSTRAP)
 int uv___stream_fd(const uv_stream_t* handle);
@@ -279,13 +293,12 @@
 #define uv__stream_fd(handle) ((handle)->io_watcher.fd)
 #endif /* defined(__APPLE__) */
 
-#ifdef UV__O_NONBLOCK
-# define UV__F_NONBLOCK UV__O_NONBLOCK
+#ifdef O_NONBLOCK
+# define UV__F_NONBLOCK O_NONBLOCK
 #else
 # define UV__F_NONBLOCK 1
 #endif
 
-int uv__make_socketpair(int fds[2], int flags);
 int uv__make_pipe(int fds[2], int flags);
 
 #if defined(__APPLE__)
@@ -323,4 +336,27 @@
                         struct sockaddr* name,
                         int* namelen);
 
+#if defined(__linux__)            ||                                      \
+    defined(__FreeBSD__)          ||                                      \
+    defined(__FreeBSD_kernel__)
+#define HAVE_MMSG 1
+struct uv__mmsghdr {
+  struct msghdr msg_hdr;
+  unsigned int msg_len;
+};
+
+int uv__recvmmsg(int fd,
+                 struct uv__mmsghdr* mmsg,
+                 unsigned int vlen,
+                 unsigned int flags,
+                 struct timespec* timeout);
+int uv__sendmmsg(int fd,
+                 struct uv__mmsghdr* mmsg,
+                 unsigned int vlen,
+                 unsigned int flags);
+#else
+#define HAVE_MMSG 0
+#endif
+
+
 #endif /* UV_UNIX_INTERNAL_H_ */
diff --git a/Utilities/cmlibuv/src/unix/kqueue.c b/Utilities/cmlibuv/src/unix/kqueue.c
index c04e7a4..ad09f40 100644
--- a/Utilities/cmlibuv/src/unix/kqueue.c
+++ b/Utilities/cmlibuv/src/unix/kqueue.c
@@ -454,10 +454,26 @@
                       const char* path,
                       unsigned int flags) {
   int fd;
+#if defined(__APPLE__) && MAC_OS_X_VERSION_MAX_ALLOWED >= 1070
+  struct stat statbuf;
+#endif
 
   if (uv__is_active(handle))
     return UV_EINVAL;
 
+  handle->cb = cb;
+  handle->path = uv__strdup(path);
+  if (handle->path == NULL)
+    return UV_ENOMEM;
+
+  /* TODO open asynchronously - but how do we report back errors? */
+  fd = open(handle->path, O_RDONLY);
+  if (fd == -1) {
+    uv__free(handle->path);
+    handle->path = NULL;
+    return UV__ERR(errno);
+  }
+
 #if defined(__APPLE__) && MAC_OS_X_VERSION_MAX_ALLOWED >= 1070
   /* Nullify field to perform checks later */
   handle->cf_cb = NULL;
@@ -465,14 +481,17 @@
   handle->realpath_len = 0;
   handle->cf_flags = flags;
 
+  if (fstat(fd, &statbuf))
+    goto fallback;
+  /* FSEvents works only with directories */
+  if (!(statbuf.st_mode & S_IFDIR))
+    goto fallback;
+
   if (!uv__has_forked_with_cfrunloop) {
     int r;
-    /* The fallback fd is not used */
+    /* The fallback fd is no longer needed */
+    uv__close_nocheckstdio(fd);
     handle->event_watcher.fd = -1;
-    handle->path = uv__strdup(path);
-    if (handle->path == NULL)
-      return UV_ENOMEM;
-    handle->cb = cb;
     r = uv__fsevents_init(handle);
     if (r == 0) {
       uv__handle_start(handle);
@@ -482,20 +501,9 @@
     }
     return r;
   }
+fallback:
 #endif /* #if defined(__APPLE__) && MAC_OS_X_VERSION_MAX_ALLOWED >= 1070 */
 
-  /* TODO open asynchronously - but how do we report back errors? */
-  fd = open(path, O_RDONLY);
-  if (fd == -1)
-    return UV__ERR(errno);
-
-  handle->path = uv__strdup(path);
-  if (handle->path == NULL) {
-    uv__close_nocheckstdio(fd);
-    return UV_ENOMEM;
-  }
-
-  handle->cb = cb;
   uv__handle_start(handle);
   uv__io_init(&handle->event_watcher, uv__fs_event, fd);
   uv__io_start(handle->loop, &handle->event_watcher, POLLIN);
@@ -514,7 +522,7 @@
   uv__handle_stop(handle);
 
 #if defined(__APPLE__) && MAC_OS_X_VERSION_MAX_ALLOWED >= 1070
-  if (!uv__has_forked_with_cfrunloop)
+  if (!uv__has_forked_with_cfrunloop && handle->cf_cb != NULL)
     r = uv__fsevents_close(handle);
 #endif
 
diff --git a/Utilities/cmlibuv/src/unix/linux-core.c b/Utilities/cmlibuv/src/unix/linux-core.c
index b539beb..99cbb1c 100644
--- a/Utilities/cmlibuv/src/unix/linux-core.c
+++ b/Utilities/cmlibuv/src/unix/linux-core.c
@@ -90,7 +90,12 @@
    * a.k.a. Lollipop. Since EPOLL_CLOEXEC is an alias for O_CLOEXEC on all
    * architectures, we just use that instead.
    */
+#if defined(__ANDROID_API__) && __ANDROID_API__ < 21
+  fd = -1;
+  errno = ENOSYS;
+#else
   fd = epoll_create1(O_CLOEXEC);
+#endif
 
   /* epoll_create1() can fail either because it's not implemented (old kernel)
    * or because it doesn't understand the O_CLOEXEC flag.
@@ -203,6 +208,8 @@
    * that being the largest value I have seen in the wild (and only once.)
    */
   static const int max_safe_timeout = 1789569;
+  static int no_epoll_pwait;
+  static int no_epoll_wait;
   struct epoll_event events[1024];
   struct epoll_event* pe;
   struct epoll_event e;
@@ -210,7 +217,7 @@
   QUEUE* q;
   uv__io_t* w;
   sigset_t sigset;
-  sigset_t* psigset;
+  uint64_t sigmask;
   uint64_t base;
   int have_signals;
   int nevents;
@@ -262,11 +269,11 @@
     w->events = w->pevents;
   }
 
-  psigset = NULL;
+  sigmask = 0;
   if (loop->flags & UV_LOOP_BLOCK_SIGPROF) {
     sigemptyset(&sigset);
     sigaddset(&sigset, SIGPROF);
-    psigset = &sigset;
+    sigmask |= 1 << (SIGPROF - 1);
   }
 
   assert(timeout >= -1);
@@ -281,11 +288,35 @@
     if (sizeof(int32_t) == sizeof(long) && timeout >= max_safe_timeout)
       timeout = max_safe_timeout;
 
-    nfds = epoll_pwait(loop->backend_fd,
-                       events,
-                       ARRAY_SIZE(events),
-                       timeout,
-                       psigset);
+    if (sigmask != 0 && no_epoll_pwait != 0)
+      if (pthread_sigmask(SIG_BLOCK, &sigset, NULL))
+        abort();
+
+    if (no_epoll_wait != 0 || (sigmask != 0 && no_epoll_pwait == 0)) {
+#if defined(__ANDROID_API__) && __ANDROID_API__ < 21
+      nfds = -1;
+      errno = ENOSYS;
+#else
+      nfds = epoll_pwait(loop->backend_fd,
+                         events,
+                         ARRAY_SIZE(events),
+                         timeout,
+                         &sigset);
+#endif
+      if (nfds == -1 && errno == ENOSYS)
+        no_epoll_pwait = 1;
+    } else {
+      nfds = epoll_wait(loop->backend_fd,
+                        events,
+                        ARRAY_SIZE(events),
+                        timeout);
+      if (nfds == -1 && errno == ENOSYS)
+        no_epoll_wait = 1;
+    }
+
+    if (sigmask != 0 && no_epoll_pwait != 0)
+      if (pthread_sigmask(SIG_UNBLOCK, &sigset, NULL))
+        abort();
 
     /* Update loop->time unconditionally. It's tempting to skip the update when
      * timeout == 0 (i.e. non-blocking poll) but there is no guarantee that the
@@ -306,6 +337,12 @@
     }
 
     if (nfds == -1) {
+      if (errno == ENOSYS) {
+        /* epoll_wait() or epoll_pwait() failed, try the other system call. */
+        assert(no_epoll_wait == 0 || no_epoll_pwait == 0);
+        continue;
+      }
+
       if (errno != EINTR)
         abort();
 
@@ -322,9 +359,19 @@
     have_signals = 0;
     nevents = 0;
 
-    assert(loop->watchers != NULL);
-    loop->watchers[loop->nwatchers] = (void*) events;
-    loop->watchers[loop->nwatchers + 1] = (void*) (uintptr_t) nfds;
+    {
+      /* Squelch a -Waddress-of-packed-member warning with gcc >= 9. */
+      union {
+        struct epoll_event* events;
+        uv__io_t* watchers;
+      } x;
+
+      x.events = events;
+      assert(loop->watchers != NULL);
+      loop->watchers[loop->nwatchers] = x.watchers;
+      loop->watchers[loop->nwatchers + 1] = (void*) (uintptr_t) nfds;
+    }
+
     for (i = 0; i < nfds; i++) {
       pe = events + i;
       fd = pe->data.fd;
@@ -721,7 +768,8 @@
                       unsigned int numcpus,
                       uv_cpu_info_t* ci) {
   struct uv_cpu_times_s ts;
-  uint64_t clock_ticks;
+  unsigned int ticks;
+  unsigned int multiplier;
   uint64_t user;
   uint64_t nice;
   uint64_t sys;
@@ -732,9 +780,10 @@
   uint64_t len;
   char buf[1024];
 
-  clock_ticks = sysconf(_SC_CLK_TCK);
-  assert(clock_ticks != (uint64_t) -1);
-  assert(clock_ticks != 0);
+  ticks = (unsigned int)sysconf(_SC_CLK_TCK);
+  multiplier = ((uint64_t)1000L / ticks);
+  assert(ticks != (unsigned int) -1);
+  assert(ticks != 0);
 
   rewind(statfile_fp);
 
@@ -776,11 +825,11 @@
                     &irq))
       abort();
 
-    ts.user = clock_ticks * user;
-    ts.nice = clock_ticks * nice;
-    ts.sys  = clock_ticks * sys;
-    ts.idle = clock_ticks * idle;
-    ts.irq  = clock_ticks * irq;
+    ts.user = user * multiplier;
+    ts.nice = nice * multiplier;
+    ts.sys  = sys * multiplier;
+    ts.idle = idle * multiplier;
+    ts.irq  = irq * multiplier;
     ci[num++].cpu_times = ts;
   }
   assert(num == numcpus);
@@ -812,16 +861,6 @@
 }
 
 
-void uv_free_cpu_info(uv_cpu_info_t* cpu_infos, int count) {
-  int i;
-
-  for (i = 0; i < count; i++) {
-    uv__free(cpu_infos[i].model);
-  }
-
-  uv__free(cpu_infos);
-}
-
 static int uv__ifaddr_exclude(struct ifaddrs *ent, int exclude_type) {
   if (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING)))
     return 1;
@@ -953,7 +992,7 @@
   rc = 0;
   fd = uv__open_cloexec("/proc/meminfo", O_RDONLY);
 
-  if (fd == -1)
+  if (fd < 0)
     return 0;
 
   n = read(fd, buf, sizeof(buf) - 1);
diff --git a/Utilities/cmlibuv/src/unix/linux-inotify.c b/Utilities/cmlibuv/src/unix/linux-inotify.c
index 9b26202..42b601a 100644
--- a/Utilities/cmlibuv/src/unix/linux-inotify.c
+++ b/Utilities/cmlibuv/src/unix/linux-inotify.c
@@ -29,6 +29,7 @@
 #include <assert.h>
 #include <errno.h>
 
+#include <sys/inotify.h>
 #include <sys/types.h>
 #include <unistd.h>
 
@@ -64,45 +65,17 @@
 static void maybe_free_watcher_list(struct watcher_list* w,
                                     uv_loop_t* loop);
 
-static int new_inotify_fd(void) {
-  int err;
-  int fd;
-
-  fd = uv__inotify_init1(UV__IN_NONBLOCK | UV__IN_CLOEXEC);
-  if (fd != -1)
-    return fd;
-
-  if (errno != ENOSYS)
-    return UV__ERR(errno);
-
-  fd = uv__inotify_init();
-  if (fd == -1)
-    return UV__ERR(errno);
-
-  err = uv__cloexec(fd, 1);
-  if (err == 0)
-    err = uv__nonblock(fd, 1);
-
-  if (err) {
-    uv__close(fd);
-    return err;
-  }
-
-  return fd;
-}
-
-
 static int init_inotify(uv_loop_t* loop) {
-  int err;
+  int fd;
 
   if (loop->inotify_fd != -1)
     return 0;
 
-  err = new_inotify_fd();
-  if (err < 0)
-    return err;
+  fd = inotify_init1(IN_NONBLOCK | IN_CLOEXEC);
+  if (fd < 0)
+    return UV__ERR(errno);
 
-  loop->inotify_fd = err;
+  loop->inotify_fd = fd;
   uv__io_init(&loop->inotify_read_watcher, uv__inotify_read, loop->inotify_fd);
   uv__io_start(loop, &loop->inotify_read_watcher, POLLIN);
 
@@ -186,7 +159,7 @@
   if ((!w->iterating) && QUEUE_EMPTY(&w->watchers)) {
     /* No watchers left for this path. Clean up. */
     RB_REMOVE(watcher_root, CAST(&loop->inotify_watchers), w);
-    uv__inotify_rm_watch(loop->inotify_fd, w->wd);
+    inotify_rm_watch(loop->inotify_fd, w->wd);
     uv__free(w);
   }
 }
@@ -194,7 +167,7 @@
 static void uv__inotify_read(uv_loop_t* loop,
                              uv__io_t* dummy,
                              unsigned int events) {
-  const struct uv__inotify_event* e;
+  const struct inotify_event* e;
   struct watcher_list* w;
   uv_fs_event_t* h;
   QUEUE queue;
@@ -219,12 +192,12 @@
 
     /* Now we have one or more inotify_event structs. */
     for (p = buf; p < buf + size; p += sizeof(*e) + e->len) {
-      e = (const struct uv__inotify_event*)p;
+      e = (const struct inotify_event*) p;
 
       events = 0;
-      if (e->mask & (UV__IN_ATTRIB|UV__IN_MODIFY))
+      if (e->mask & (IN_ATTRIB|IN_MODIFY))
         events |= UV_CHANGE;
-      if (e->mask & ~(UV__IN_ATTRIB|UV__IN_MODIFY))
+      if (e->mask & ~(IN_ATTRIB|IN_MODIFY))
         events |= UV_RENAME;
 
       w = find_watcher(loop, e->wd);
@@ -290,16 +263,16 @@
   if (err)
     return err;
 
-  events = UV__IN_ATTRIB
-         | UV__IN_CREATE
-         | UV__IN_MODIFY
-         | UV__IN_DELETE
-         | UV__IN_DELETE_SELF
-         | UV__IN_MOVE_SELF
-         | UV__IN_MOVED_FROM
-         | UV__IN_MOVED_TO;
+  events = IN_ATTRIB
+         | IN_CREATE
+         | IN_MODIFY
+         | IN_DELETE
+         | IN_DELETE_SELF
+         | IN_MOVE_SELF
+         | IN_MOVED_FROM
+         | IN_MOVED_TO;
 
-  wd = uv__inotify_add_watch(handle->loop->inotify_fd, path, events);
+  wd = inotify_add_watch(handle->loop->inotify_fd, path, events);
   if (wd == -1)
     return UV__ERR(errno);
 
diff --git a/Utilities/cmlibuv/src/unix/linux-syscalls.c b/Utilities/cmlibuv/src/unix/linux-syscalls.c
index 5637cf9..742f26a 100644
--- a/Utilities/cmlibuv/src/unix/linux-syscalls.c
+++ b/Utilities/cmlibuv/src/unix/linux-syscalls.c
@@ -26,19 +26,6 @@
 #include <sys/types.h>
 #include <errno.h>
 
-#if defined(__has_feature)
-# if __has_feature(memory_sanitizer)
-#  define MSAN_ACTIVE 1
-#  include <sanitizer/msan_interface.h>
-# endif
-#endif
-
-#if defined(__i386__)
-# ifndef __NR_socketcall
-#  define __NR_socketcall 102
-# endif
-#endif
-
 #if defined(__arm__)
 # if defined(__thumb__) || defined(__ARM_EABI__)
 #  define UV_SYSCALL_BASE 0
@@ -47,86 +34,6 @@
 # endif
 #endif /* __arm__ */
 
-#ifndef __NR_accept4
-# if defined(__x86_64__)
-#  define __NR_accept4 288
-# elif defined(__i386__)
-   /* Nothing. Handled through socketcall(). */
-# elif defined(__arm__)
-#  define __NR_accept4 (UV_SYSCALL_BASE + 366)
-# endif
-#endif /* __NR_accept4 */
-
-#ifndef __NR_eventfd
-# if defined(__x86_64__)
-#  define __NR_eventfd 284
-# elif defined(__i386__)
-#  define __NR_eventfd 323
-# elif defined(__arm__)
-#  define __NR_eventfd (UV_SYSCALL_BASE + 351)
-# endif
-#endif /* __NR_eventfd */
-
-#ifndef __NR_eventfd2
-# if defined(__x86_64__)
-#  define __NR_eventfd2 290
-# elif defined(__i386__)
-#  define __NR_eventfd2 328
-# elif defined(__arm__)
-#  define __NR_eventfd2 (UV_SYSCALL_BASE + 356)
-# endif
-#endif /* __NR_eventfd2 */
-
-#ifndef __NR_inotify_init
-# if defined(__x86_64__)
-#  define __NR_inotify_init 253
-# elif defined(__i386__)
-#  define __NR_inotify_init 291
-# elif defined(__arm__)
-#  define __NR_inotify_init (UV_SYSCALL_BASE + 316)
-# endif
-#endif /* __NR_inotify_init */
-
-#ifndef __NR_inotify_init1
-# if defined(__x86_64__)
-#  define __NR_inotify_init1 294
-# elif defined(__i386__)
-#  define __NR_inotify_init1 332
-# elif defined(__arm__)
-#  define __NR_inotify_init1 (UV_SYSCALL_BASE + 360)
-# endif
-#endif /* __NR_inotify_init1 */
-
-#ifndef __NR_inotify_add_watch
-# if defined(__x86_64__)
-#  define __NR_inotify_add_watch 254
-# elif defined(__i386__)
-#  define __NR_inotify_add_watch 292
-# elif defined(__arm__)
-#  define __NR_inotify_add_watch (UV_SYSCALL_BASE + 317)
-# endif
-#endif /* __NR_inotify_add_watch */
-
-#ifndef __NR_inotify_rm_watch
-# if defined(__x86_64__)
-#  define __NR_inotify_rm_watch 255
-# elif defined(__i386__)
-#  define __NR_inotify_rm_watch 293
-# elif defined(__arm__)
-#  define __NR_inotify_rm_watch (UV_SYSCALL_BASE + 318)
-# endif
-#endif /* __NR_inotify_rm_watch */
-
-#ifndef __NR_pipe2
-# if defined(__x86_64__)
-#  define __NR_pipe2 293
-# elif defined(__i386__)
-#  define __NR_pipe2 331
-# elif defined(__arm__)
-#  define __NR_pipe2 (UV_SYSCALL_BASE + 359)
-# endif
-#endif /* __NR_pipe2 */
-
 #ifndef __NR_recvmmsg
 # if defined(__x86_64__)
 #  define __NR_recvmmsg 299
@@ -203,103 +110,23 @@
 # endif
 #endif /* __NR_statx */
 
-int uv__accept4(int fd, struct sockaddr* addr, socklen_t* addrlen, int flags) {
-#if defined(__i386__)
-  unsigned long args[4];
-  int r;
+#ifndef __NR_getrandom
+# if defined(__x86_64__)
+#  define __NR_getrandom 318
+# elif defined(__i386__)
+#  define __NR_getrandom 355
+# elif defined(__aarch64__)
+#  define __NR_getrandom 384
+# elif defined(__arm__)
+#  define __NR_getrandom (UV_SYSCALL_BASE + 384)
+# elif defined(__ppc__)
+#  define __NR_getrandom 359
+# elif defined(__s390__)
+#  define __NR_getrandom 349
+# endif
+#endif /* __NR_getrandom */
 
-  args[0] = (unsigned long) fd;
-  args[1] = (unsigned long) addr;
-  args[2] = (unsigned long) addrlen;
-  args[3] = (unsigned long) flags;
-
-  r = syscall(__NR_socketcall, 18 /* SYS_ACCEPT4 */, args);
-
-  /* socketcall() raises EINVAL when SYS_ACCEPT4 is not supported but so does
-   * a bad flags argument. Try to distinguish between the two cases.
-   */
-  if (r == -1)
-    if (errno == EINVAL)
-      if ((flags & ~(UV__SOCK_CLOEXEC|UV__SOCK_NONBLOCK)) == 0)
-        errno = ENOSYS;
-
-  return r;
-#elif defined(__NR_accept4)
-  return syscall(__NR_accept4, fd, addr, addrlen, flags);
-#else
-  return errno = ENOSYS, -1;
-#endif
-}
-
-
-int uv__eventfd(unsigned int count) {
-#if defined(__NR_eventfd)
-  return syscall(__NR_eventfd, count);
-#else
-  return errno = ENOSYS, -1;
-#endif
-}
-
-
-int uv__eventfd2(unsigned int count, int flags) {
-#if defined(__NR_eventfd2)
-  return syscall(__NR_eventfd2, count, flags);
-#else
-  return errno = ENOSYS, -1;
-#endif
-}
-
-
-int uv__inotify_init(void) {
-#if defined(__NR_inotify_init)
-  return syscall(__NR_inotify_init);
-#else
-  return errno = ENOSYS, -1;
-#endif
-}
-
-
-int uv__inotify_init1(int flags) {
-#if defined(__NR_inotify_init1)
-  return syscall(__NR_inotify_init1, flags);
-#else
-  return errno = ENOSYS, -1;
-#endif
-}
-
-
-int uv__inotify_add_watch(int fd, const char* path, uint32_t mask) {
-#if defined(__NR_inotify_add_watch)
-  return syscall(__NR_inotify_add_watch, fd, path, mask);
-#else
-  return errno = ENOSYS, -1;
-#endif
-}
-
-
-int uv__inotify_rm_watch(int fd, int32_t wd) {
-#if defined(__NR_inotify_rm_watch)
-  return syscall(__NR_inotify_rm_watch, fd, wd);
-#else
-  return errno = ENOSYS, -1;
-#endif
-}
-
-
-int uv__pipe2(int pipefd[2], int flags) {
-#if defined(__NR_pipe2)
-  int result;
-  result = syscall(__NR_pipe2, pipefd, flags);
-#if MSAN_ACTIVE
-  if (!result)
-    __msan_unpoison(pipefd, sizeof(int[2]));
-#endif
-  return result;
-#else
-  return errno = ENOSYS, -1;
-#endif
-}
-
+struct uv__mmsghdr;
 
 int uv__sendmmsg(int fd,
                  struct uv__mmsghdr* mmsg,
@@ -367,3 +194,12 @@
   return errno = ENOSYS, -1;
 #endif
 }
+
+
+ssize_t uv__getrandom(void* buf, size_t buflen, unsigned flags) {
+#if defined(__NR_getrandom)
+  return syscall(__NR_getrandom, buf, buflen, flags);
+#else
+  return errno = ENOSYS, -1;
+#endif
+}
diff --git a/Utilities/cmlibuv/src/unix/linux-syscalls.h b/Utilities/cmlibuv/src/unix/linux-syscalls.h
index 7e58bfa..2e8fa2a 100644
--- a/Utilities/cmlibuv/src/unix/linux-syscalls.h
+++ b/Utilities/cmlibuv/src/unix/linux-syscalls.h
@@ -31,55 +31,6 @@
 #include <sys/time.h>
 #include <sys/socket.h>
 
-#if defined(__alpha__)
-# define UV__O_CLOEXEC        0x200000
-#elif defined(__hppa__)
-# define UV__O_CLOEXEC        0x200000
-#elif defined(__sparc__)
-# define UV__O_CLOEXEC        0x400000
-#else
-# define UV__O_CLOEXEC        0x80000
-#endif
-
-#if defined(__alpha__)
-# define UV__O_NONBLOCK       0x4
-#elif defined(__hppa__)
-# define UV__O_NONBLOCK       O_NONBLOCK
-#elif defined(__mips__)
-# define UV__O_NONBLOCK       0x80
-#elif defined(__sparc__)
-# define UV__O_NONBLOCK       0x4000
-#else
-# define UV__O_NONBLOCK       0x800
-#endif
-
-#define UV__EFD_CLOEXEC       UV__O_CLOEXEC
-#define UV__EFD_NONBLOCK      UV__O_NONBLOCK
-
-#define UV__IN_CLOEXEC        UV__O_CLOEXEC
-#define UV__IN_NONBLOCK       UV__O_NONBLOCK
-
-#define UV__SOCK_CLOEXEC      UV__O_CLOEXEC
-#if defined(SOCK_NONBLOCK)
-# define UV__SOCK_NONBLOCK    SOCK_NONBLOCK
-#else
-# define UV__SOCK_NONBLOCK    UV__O_NONBLOCK
-#endif
-
-/* inotify flags */
-#define UV__IN_ACCESS         0x001
-#define UV__IN_MODIFY         0x002
-#define UV__IN_ATTRIB         0x004
-#define UV__IN_CLOSE_WRITE    0x008
-#define UV__IN_CLOSE_NOWRITE  0x010
-#define UV__IN_OPEN           0x020
-#define UV__IN_MOVED_FROM     0x040
-#define UV__IN_MOVED_TO       0x080
-#define UV__IN_CREATE         0x100
-#define UV__IN_DELETE         0x200
-#define UV__IN_DELETE_SELF    0x400
-#define UV__IN_MOVE_SELF      0x800
-
 struct uv__statx_timestamp {
   int64_t tv_sec;
   uint32_t tv_nsec;
@@ -110,36 +61,6 @@
   uint64_t unused1[14];
 };
 
-struct uv__inotify_event {
-  int32_t wd;
-  uint32_t mask;
-  uint32_t cookie;
-  uint32_t len;
-  /* char name[0]; */
-};
-
-struct uv__mmsghdr {
-  struct msghdr msg_hdr;
-  unsigned int msg_len;
-};
-
-int uv__accept4(int fd, struct sockaddr* addr, socklen_t* addrlen, int flags);
-int uv__eventfd(unsigned int count);
-int uv__eventfd2(unsigned int count, int flags);
-int uv__inotify_init(void);
-int uv__inotify_init1(int flags);
-int uv__inotify_add_watch(int fd, const char* path, uint32_t mask);
-int uv__inotify_rm_watch(int fd, int32_t wd);
-int uv__pipe2(int pipefd[2], int flags);
-int uv__recvmmsg(int fd,
-                 struct uv__mmsghdr* mmsg,
-                 unsigned int vlen,
-                 unsigned int flags,
-                 struct timespec* timeout);
-int uv__sendmmsg(int fd,
-                 struct uv__mmsghdr* mmsg,
-                 unsigned int vlen,
-                 unsigned int flags);
 ssize_t uv__preadv(int fd, const struct iovec *iov, int iovcnt, int64_t offset);
 ssize_t uv__pwritev(int fd, const struct iovec *iov, int iovcnt, int64_t offset);
 int uv__dup3(int oldfd, int newfd, int flags);
@@ -148,5 +69,6 @@
               int flags,
               unsigned int mask,
               struct uv__statx* statxbuf);
+ssize_t uv__getrandom(void* buf, size_t buflen, unsigned flags);
 
 #endif /* UV_LINUX_SYSCALL_H_ */
diff --git a/Utilities/cmlibuv/src/unix/netbsd.c b/Utilities/cmlibuv/src/unix/netbsd.c
index c649bb3..c66333f 100644
--- a/Utilities/cmlibuv/src/unix/netbsd.c
+++ b/Utilities/cmlibuv/src/unix/netbsd.c
@@ -55,7 +55,7 @@
   size_t size = sizeof(info);
   int which[] = {CTL_VM, VM_LOADAVG};
 
-  if (sysctl(which, 2, &info, &size, NULL, 0) == -1) return;
+  if (sysctl(which, ARRAY_SIZE(which), &info, &size, NULL, 0) == -1) return;
 
   avg[0] = (double) info.ldavg[0] / info.fscale;
   avg[1] = (double) info.ldavg[1] / info.fscale;
@@ -102,7 +102,7 @@
   size_t size = sizeof(info);
   int which[] = {CTL_VM, VM_UVMEXP};
 
-  if (sysctl(which, 2, &info, &size, NULL, 0))
+  if (sysctl(which, ARRAY_SIZE(which), &info, &size, NULL, 0))
     return UV__ERR(errno);
 
   return (uint64_t) info.free * sysconf(_SC_PAGESIZE);
@@ -119,7 +119,7 @@
 #endif
   size_t size = sizeof(info);
 
-  if (sysctl(which, 2, &info, &size, NULL, 0))
+  if (sysctl(which, ARRAY_SIZE(which), &info, &size, NULL, 0))
     return UV__ERR(errno);
 
   return (uint64_t) info;
@@ -167,7 +167,7 @@
   size_t size = sizeof(info);
   static int which[] = {CTL_KERN, KERN_BOOTTIME};
 
-  if (sysctl(which, 2, &info, &size, NULL, 0))
+  if (sysctl(which, ARRAY_SIZE(which), &info, &size, NULL, 0))
     return UV__ERR(errno);
 
   now = time(NULL);
@@ -235,13 +235,25 @@
   return 0;
 }
 
+int uv__random_sysctl(void* buf, size_t len) {
+  static int name[] = {CTL_KERN, KERN_ARND};
+  size_t count, req;
+  unsigned char* p;
 
-void uv_free_cpu_info(uv_cpu_info_t* cpu_infos, int count) {
-  int i;
+  p = buf;
+  while (len) {
+    req = len < 32 ? len : 32;
+    count = req;
 
-  for (i = 0; i < count; i++) {
-    uv__free(cpu_infos[i].model);
+    if (sysctl(name, ARRAY_SIZE(name), p, &count, NULL, 0) == -1)
+      return UV__ERR(errno);
+
+    if (count != req)
+      return UV_EIO;  /* Can't happen. */
+
+    p += count;
+    len -= count;
   }
 
-  uv__free(cpu_infos);
+  return 0;
 }
diff --git a/Utilities/cmlibuv/src/unix/no-proctitle.c b/Utilities/cmlibuv/src/unix/no-proctitle.c
index 165740c..32aa0af 100644
--- a/Utilities/cmlibuv/src/unix/no-proctitle.c
+++ b/Utilities/cmlibuv/src/unix/no-proctitle.c
@@ -29,6 +29,9 @@
   return argv;
 }
 
+void uv__process_title_cleanup(void) {
+}
+
 int uv_set_process_title(const char* title) {
   return 0;
 }
diff --git a/Utilities/cmlibuv/src/unix/openbsd.c b/Utilities/cmlibuv/src/unix/openbsd.c
index ffae768..f32a94d 100644
--- a/Utilities/cmlibuv/src/unix/openbsd.c
+++ b/Utilities/cmlibuv/src/unix/openbsd.c
@@ -50,7 +50,7 @@
   size_t size = sizeof(info);
   int which[] = {CTL_VM, VM_LOADAVG};
 
-  if (sysctl(which, 2, &info, &size, NULL, 0) < 0) return;
+  if (sysctl(which, ARRAY_SIZE(which), &info, &size, NULL, 0) < 0) return;
 
   avg[0] = (double) info.ldavg[0] / info.fscale;
   avg[1] = (double) info.ldavg[1] / info.fscale;
@@ -61,7 +61,6 @@
 int uv_exepath(char* buffer, size_t* size) {
   int mib[4];
   char **argsbuf = NULL;
-  char **argsbuf_tmp;
   size_t argsbuf_size = 100U;
   size_t exepath_size;
   pid_t mypid;
@@ -73,15 +72,14 @@
   mypid = getpid();
   for (;;) {
     err = UV_ENOMEM;
-    argsbuf_tmp = uv__realloc(argsbuf, argsbuf_size);
-    if (argsbuf_tmp == NULL)
+    argsbuf = uv__reallocf(argsbuf, argsbuf_size);
+    if (argsbuf == NULL)
       goto out;
-    argsbuf = argsbuf_tmp;
     mib[0] = CTL_KERN;
     mib[1] = KERN_PROC_ARGS;
     mib[2] = mypid;
     mib[3] = KERN_PROC_ARGV;
-    if (sysctl(mib, 4, argsbuf, &argsbuf_size, NULL, 0) == 0) {
+    if (sysctl(mib, ARRAY_SIZE(mib), argsbuf, &argsbuf_size, NULL, 0) == 0) {
       break;
     }
     if (errno != ENOMEM) {
@@ -117,7 +115,7 @@
   size_t size = sizeof(info);
   int which[] = {CTL_VM, VM_UVMEXP};
 
-  if (sysctl(which, 2, &info, &size, NULL, 0))
+  if (sysctl(which, ARRAY_SIZE(which), &info, &size, NULL, 0))
     return UV__ERR(errno);
 
   return (uint64_t) info.free * sysconf(_SC_PAGESIZE);
@@ -129,7 +127,7 @@
   int which[] = {CTL_HW, HW_PHYSMEM64};
   size_t size = sizeof(info);
 
-  if (sysctl(which, 2, &info, &size, NULL, 0))
+  if (sysctl(which, ARRAY_SIZE(which), &info, &size, NULL, 0))
     return UV__ERR(errno);
 
   return (uint64_t) info;
@@ -154,7 +152,7 @@
   mib[4] = sizeof(struct kinfo_proc);
   mib[5] = 1;
 
-  if (sysctl(mib, 6, &kinfo, &size, NULL, 0) < 0)
+  if (sysctl(mib, ARRAY_SIZE(mib), &kinfo, &size, NULL, 0) < 0)
     return UV__ERR(errno);
 
   *rss = kinfo.p_vm_rssize * page_size;
@@ -168,7 +166,7 @@
   size_t size = sizeof(info);
   static int which[] = {CTL_KERN, KERN_BOOTTIME};
 
-  if (sysctl(which, 2, &info, &size, NULL, 0))
+  if (sysctl(which, ARRAY_SIZE(which), &info, &size, NULL, 0))
     return UV__ERR(errno);
 
   now = time(NULL);
@@ -184,43 +182,38 @@
   uint64_t info[CPUSTATES];
   char model[512];
   int numcpus = 1;
-  int which[] = {CTL_HW,HW_MODEL,0};
+  int which[] = {CTL_HW,HW_MODEL};
+  int percpu[] = {CTL_KERN,KERN_CPTIME2,0};
   size_t size;
-  int i;
+  int i, j;
   uv_cpu_info_t* cpu_info;
 
   size = sizeof(model);
-  if (sysctl(which, 2, &model, &size, NULL, 0))
+  if (sysctl(which, ARRAY_SIZE(which), &model, &size, NULL, 0))
     return UV__ERR(errno);
 
-  which[1] = HW_NCPU;
+  which[1] = HW_NCPUONLINE;
   size = sizeof(numcpus);
-  if (sysctl(which, 2, &numcpus, &size, NULL, 0))
+  if (sysctl(which, ARRAY_SIZE(which), &numcpus, &size, NULL, 0))
     return UV__ERR(errno);
 
   *cpu_infos = uv__malloc(numcpus * sizeof(**cpu_infos));
   if (!(*cpu_infos))
     return UV_ENOMEM;
 
+  i = 0;
   *count = numcpus;
 
   which[1] = HW_CPUSPEED;
   size = sizeof(cpuspeed);
-  if (sysctl(which, 2, &cpuspeed, &size, NULL, 0)) {
-    uv__free(*cpu_infos);
-    return UV__ERR(errno);
-  }
+  if (sysctl(which, ARRAY_SIZE(which), &cpuspeed, &size, NULL, 0))
+    goto error;
 
   size = sizeof(info);
-  which[0] = CTL_KERN;
-  which[1] = KERN_CPTIME2;
   for (i = 0; i < numcpus; i++) {
-    which[2] = i;
-    size = sizeof(info);
-    if (sysctl(which, 3, &info, &size, NULL, 0)) {
-      uv__free(*cpu_infos);
-      return UV__ERR(errno);
-    }
+    percpu[2] = i;
+    if (sysctl(percpu, ARRAY_SIZE(percpu), &info, &size, NULL, 0))
+      goto error;
 
     cpu_info = &(*cpu_infos)[i];
 
@@ -235,15 +228,13 @@
   }
 
   return 0;
-}
 
+error:
+  *count = 0;
+  for (j = 0; j < i; j++)
+    uv__free((*cpu_infos)[j].model);
 
-void uv_free_cpu_info(uv_cpu_info_t* cpu_infos, int count) {
-  int i;
-
-  for (i = 0; i < count; i++) {
-    uv__free(cpu_infos[i].model);
-  }
-
-  uv__free(cpu_infos);
+  uv__free(*cpu_infos);
+  *cpu_infos = NULL;
+  return UV__ERR(errno);
 }
diff --git a/Utilities/cmlibuv/src/unix/os390-syscalls.c b/Utilities/cmlibuv/src/unix/os390-syscalls.c
index 1040d66..424cc48 100644
--- a/Utilities/cmlibuv/src/unix/os390-syscalls.c
+++ b/Utilities/cmlibuv/src/unix/os390-syscalls.c
@@ -23,11 +23,11 @@
 #include "os390-syscalls.h"
 #include <errno.h>
 #include <stdlib.h>
-#include <assert.h>
 #include <search.h>
 #include <termios.h>
 #include <sys/msg.h>
 
+#define CW_INTRPT 1
 #define CW_CONDVAR 32
 
 #pragma linkage(BPX4CTW, OS)
@@ -43,6 +43,7 @@
             int (*compar)(const struct dirent**,
             const struct dirent **)) {
   struct dirent** nl;
+  struct dirent** nl_copy;
   struct dirent* dirent;
   unsigned count;
   size_t allocated;
@@ -62,19 +63,17 @@
     if (!filter || filter(dirent)) {
       struct dirent* copy;
       copy = uv__malloc(sizeof(*copy));
-      if (!copy) {
-        while (count) {
-          dirent = nl[--count];
-          uv__free(dirent);
-        }
-        uv__free(nl);
-        closedir(mdir);
-        errno = ENOMEM;
-        return -1;
-      }
+      if (!copy)
+        goto error;
       memcpy(copy, dirent, sizeof(*copy));
 
-      nl = uv__realloc(nl, sizeof(*copy) * (count + 1));
+      nl_copy = uv__realloc(nl, sizeof(*copy) * (count + 1));
+      if (nl_copy == NULL) {
+        uv__free(copy);
+        goto error;
+      }
+
+      nl = nl_copy;
       nl[count++] = copy;
     }
   }
@@ -86,6 +85,16 @@
 
   *namelist = nl;
   return count;
+
+error:
+  while (count > 0) {
+    dirent = nl[--count];
+    uv__free(dirent);
+  }
+  uv__free(nl);
+  closedir(mdir);
+  errno = ENOMEM;
+  return -1;
 }
 
 
@@ -119,7 +128,7 @@
   }
 
   newsize = next_power_of_two(len);
-  newlst = uv__realloc(lst->items, newsize * sizeof(lst->items[0]));
+  newlst = uv__reallocf(lst->items, newsize * sizeof(lst->items[0]));
 
   if (newlst == NULL)
     abort();
@@ -269,6 +278,8 @@
   return 0;
 }
 
+#define EP_MAX_PFDS (ULONG_MAX / sizeof(struct pollfd))
+#define EP_MAX_EVENTS (INT_MAX / sizeof(struct epoll_event))
 
 int epoll_wait(uv__os390_epoll* lst, struct epoll_event* events,
                int maxevents, int timeout) {
@@ -277,18 +288,41 @@
   int pollret;
   int reventcount;
   int nevents;
+  struct pollfd msg_fd;
+  int i;
 
-  _SET_FDS_MSGS(size, 1, lst->size - 1);
+  if (!lst || !lst->items || !events) {
+    errno = EFAULT;
+    return -1;
+  }
+
+  if (lst->size > EP_MAX_PFDS) {
+    errno = EINVAL;
+    return -1;
+  }
+
+  if (maxevents <= 0 || maxevents > EP_MAX_EVENTS) {
+    errno = EINVAL;
+    return -1;
+  }
+
+  if (lst->size > 0)
+    _SET_FDS_MSGS(size, 1, lst->size - 1);
+  else
+    _SET_FDS_MSGS(size, 0, 0);
   pfds = lst->items;
   pollret = poll(pfds, size, timeout);
   if (pollret <= 0)
     return pollret;
 
+  assert(lst->size > 0);
+
   pollret = _NFDS(pollret) + _NMSGS(pollret);
 
   reventcount = 0;
   nevents = 0;
-  for (int i = 0; 
+  msg_fd = pfds[lst->size - 1];
+  for (i = 0;
        i < lst->size && i < maxevents && reventcount < pollret; ++i) {
     struct epoll_event ev;
     struct pollfd* pfd;
@@ -299,6 +333,7 @@
 
     ev.fd = pfd->fd;
     ev.events = pfd->revents;
+    ev.is_msg = 0;
     if (pfd->revents & POLLIN && pfd->revents & POLLOUT)
       reventcount += 2;
     else if (pfd->revents & (POLLIN | POLLOUT))
@@ -308,6 +343,10 @@
     events[nevents++] = ev;
   }
 
+  if (msg_fd.revents != 0 && msg_fd.fd != -1)
+    if (i == lst->size)
+      events[nevents - 1].is_msg = 1;
+
   return nevents;
 }
 
@@ -350,27 +389,36 @@
   unsigned secrem;
   unsigned nanorem;
   int rv;
-  int rc;
+  int err;
   int rsn;
 
   nano = (int)req->tv_nsec;
   seconds = req->tv_sec;
-  events = CW_CONDVAR;
+  events = CW_CONDVAR | CW_INTRPT;
+  secrem = 0;
+  nanorem = 0;
 
 #if defined(_LP64)
-  BPX4CTW(&seconds, &nano, &events, &secrem, &nanorem, &rv, &rc, &rsn);
+  BPX4CTW(&seconds, &nano, &events, &secrem, &nanorem, &rv, &err, &rsn);
 #else
-  BPX1CTW(&seconds, &nano, &events, &secrem, &nanorem, &rv, &rc, &rsn);
+  BPX1CTW(&seconds, &nano, &events, &secrem, &nanorem, &rv, &err, &rsn);
 #endif
 
-  assert(rv == -1 && errno == EAGAIN);
+  /* Don't clobber errno unless BPX1CTW/BPX4CTW errored.
+   * Don't leak EAGAIN, that just means the timeout expired.
+   */
+  if (rv == -1)
+    if (err == EAGAIN)
+      rv = 0;
+    else
+      errno = err;
 
-  if(rem != NULL) {
+  if (rem != NULL && (rv == 0 || err == EINTR)) {
     rem->tv_nsec = nanorem;
     rem->tv_sec = secrem;
   }
 
-  return 0;
+  return rv;
 }
 
 
@@ -510,3 +558,28 @@
   else
     return p - str;
 }
+
+
+int sem_init(UV_PLATFORM_SEM_T* semid, int pshared, unsigned int value) {
+  UNREACHABLE();
+}
+
+
+int sem_destroy(UV_PLATFORM_SEM_T* semid) {
+  UNREACHABLE();
+}
+
+
+int sem_post(UV_PLATFORM_SEM_T* semid) {
+  UNREACHABLE();
+}
+
+
+int sem_trywait(UV_PLATFORM_SEM_T* semid) {
+  UNREACHABLE();
+}
+
+
+int sem_wait(UV_PLATFORM_SEM_T* semid) {
+  UNREACHABLE();
+}
diff --git a/Utilities/cmlibuv/src/unix/os390-syscalls.h b/Utilities/cmlibuv/src/unix/os390-syscalls.h
index ea59910..86416bb 100644
--- a/Utilities/cmlibuv/src/unix/os390-syscalls.h
+++ b/Utilities/cmlibuv/src/unix/os390-syscalls.h
@@ -40,6 +40,7 @@
 struct epoll_event {
   int events;
   int fd;
+  int is_msg;
 };
 
 typedef struct {
@@ -64,5 +65,10 @@
 char *mkdtemp(char* path);
 ssize_t os390_readlink(const char* path, char* buf, size_t len);
 size_t strnlen(const char* str, size_t maxlen);
+int sem_init(UV_PLATFORM_SEM_T* semid, int pshared, unsigned int value);
+int sem_destroy(UV_PLATFORM_SEM_T* semid);
+int sem_post(UV_PLATFORM_SEM_T* semid);
+int sem_trywait(UV_PLATFORM_SEM_T* semid);
+int sem_wait(UV_PLATFORM_SEM_T* semid);
 
 #endif /* UV_OS390_SYSCALL_H_ */
diff --git a/Utilities/cmlibuv/src/unix/os390.c b/Utilities/cmlibuv/src/unix/os390.c
index 273ded7..dce169b 100644
--- a/Utilities/cmlibuv/src/unix/os390.c
+++ b/Utilities/cmlibuv/src/unix/os390.c
@@ -433,13 +433,6 @@
 }
 
 
-void uv_free_cpu_info(uv_cpu_info_t* cpu_infos, int count) {
-  for (int i = 0; i < count; ++i)
-    uv__free(cpu_infos[i].model);
-  uv__free(cpu_infos);
-}
-
-
 static int uv__interface_addresses_v6(uv_interface_address_t** addresses,
                                       int* count) {
   uv_interface_address_t* address;
@@ -930,7 +923,7 @@
         continue;
 
       ep = loop->ep;
-      if (fd == ep->msg_queue) {
+      if (pe->is_msg) {
         os390_message_queue_handler(ep);
         continue;
       }
diff --git a/Utilities/cmlibuv/src/unix/pipe.c b/Utilities/cmlibuv/src/unix/pipe.c
index 7d97550..52a8fd5 100644
--- a/Utilities/cmlibuv/src/unix/pipe.c
+++ b/Utilities/cmlibuv/src/unix/pipe.c
@@ -93,8 +93,12 @@
   if (uv__stream_fd(handle) == -1)
     return UV_EINVAL;
 
-#if defined(__MVS__)
+  if (handle->ipc)
+    return UV_EINVAL;
+
+#if defined(__MVS__) || defined(__PASE__)
   /* On zOS, backlog=0 has undefined behaviour */
+  /* On IBMi PASE, backlog=0 leads to "Connection refused" error */
   if (backlog == 0)
     backlog = 1;
   else if (backlog < 0)
@@ -259,7 +263,7 @@
     addrlen = strlen(sa.sun_path);
 
 
-  if (addrlen >= *size) {
+  if ((size_t)addrlen >= *size) {
     *size = addrlen + 1;
     return UV_ENOBUFS;
   }
diff --git a/Utilities/cmlibuv/src/unix/posix-poll.c b/Utilities/cmlibuv/src/unix/posix-poll.c
index a3b9f21..766e832 100644
--- a/Utilities/cmlibuv/src/unix/posix-poll.c
+++ b/Utilities/cmlibuv/src/unix/posix-poll.c
@@ -61,7 +61,7 @@
     return;
 
   n = loop->poll_fds_size ? loop->poll_fds_size * 2 : 64;
-  p = uv__realloc(loop->poll_fds, n * sizeof(*loop->poll_fds));
+  p = uv__reallocf(loop->poll_fds, n * sizeof(*loop->poll_fds));
   if (p == NULL)
     abort();
 
diff --git a/Utilities/cmlibuv/src/unix/process.c b/Utilities/cmlibuv/src/unix/process.c
index f4826bf..08aa2f3 100644
--- a/Utilities/cmlibuv/src/unix/process.c
+++ b/Utilities/cmlibuv/src/unix/process.c
@@ -123,72 +123,64 @@
 }
 
 
-int uv__make_socketpair(int fds[2], int flags) {
-#if defined(__linux__)
-  static int no_cloexec;
-
-  if (no_cloexec)
-    goto skip;
-
-  if (socketpair(AF_UNIX, SOCK_STREAM | UV__SOCK_CLOEXEC | flags, 0, fds) == 0)
-    return 0;
-
-  /* Retry on EINVAL, it means SOCK_CLOEXEC is not supported.
-   * Anything else is a genuine error.
-   */
-  if (errno != EINVAL)
+static int uv__make_socketpair(int fds[2]) {
+#if defined(__FreeBSD__) || defined(__linux__)
+  if (socketpair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0, fds))
     return UV__ERR(errno);
 
-  no_cloexec = 1;
-
-skip:
-#endif
+  return 0;
+#else
+  int err;
 
   if (socketpair(AF_UNIX, SOCK_STREAM, 0, fds))
     return UV__ERR(errno);
 
-  uv__cloexec(fds[0], 1);
-  uv__cloexec(fds[1], 1);
+  err = uv__cloexec(fds[0], 1);
+  if (err == 0)
+    err = uv__cloexec(fds[1], 1);
 
-  if (flags & UV__F_NONBLOCK) {
-    uv__nonblock(fds[0], 1);
-    uv__nonblock(fds[1], 1);
+  if (err != 0) {
+    uv__close(fds[0]);
+    uv__close(fds[1]);
+    return UV__ERR(errno);
   }
 
   return 0;
+#endif
 }
 
 
 int uv__make_pipe(int fds[2], int flags) {
-#if defined(__linux__)
-  static int no_pipe2;
-
-  if (no_pipe2)
-    goto skip;
-
-  if (uv__pipe2(fds, flags | UV__O_CLOEXEC) == 0)
-    return 0;
-
-  if (errno != ENOSYS)
+#if defined(__FreeBSD__) || defined(__linux__)
+  if (pipe2(fds, flags | O_CLOEXEC))
     return UV__ERR(errno);
 
-  no_pipe2 = 1;
-
-skip:
-#endif
-
+  return 0;
+#else
   if (pipe(fds))
     return UV__ERR(errno);
 
-  uv__cloexec(fds[0], 1);
-  uv__cloexec(fds[1], 1);
+  if (uv__cloexec(fds[0], 1))
+    goto fail;
+
+  if (uv__cloexec(fds[1], 1))
+    goto fail;
 
   if (flags & UV__F_NONBLOCK) {
-    uv__nonblock(fds[0], 1);
-    uv__nonblock(fds[1], 1);
+    if (uv__nonblock(fds[0], 1))
+      goto fail;
+
+    if (uv__nonblock(fds[1], 1))
+      goto fail;
   }
 
   return 0;
+
+fail:
+  uv__close(fds[0]);
+  uv__close(fds[1]);
+  return UV__ERR(errno);
+#endif
 }
 
 
@@ -211,7 +203,7 @@
     if (container->data.stream->type != UV_NAMED_PIPE)
       return UV_EINVAL;
     else
-      return uv__make_socketpair(fds, 0);
+      return uv__make_socketpair(fds);
 
   case UV_INHERIT_FD:
   case UV_INHERIT_STREAM:
@@ -260,7 +252,7 @@
 
 static void uv__process_close_stream(uv_stdio_container_t* container) {
   if (!(container->flags & UV_CREATE_PIPE)) return;
-  uv__stream_close((uv_stream_t*)container->data.stream);
+  uv__stream_close(container->data.stream);
 }
 
 
diff --git a/Utilities/cmlibuv/src/unix/proctitle.c b/Utilities/cmlibuv/src/unix/proctitle.c
index a5ce203..4ee991f 100644
--- a/Utilities/cmlibuv/src/unix/proctitle.c
+++ b/Utilities/cmlibuv/src/unix/proctitle.c
@@ -24,28 +24,27 @@
 #include <stdlib.h>
 #include <string.h>
 
-extern void uv__set_process_title_platform_init(void);
+struct uv__process_title {
+  char* str;
+  size_t len;  /* Length of the current process title. */
+  size_t cap;  /* Maximum capacity. Computed once in uv_setup_args(). */
+};
+
 extern void uv__set_process_title(const char* title);
 
 static uv_mutex_t process_title_mutex;
 static uv_once_t process_title_mutex_once = UV_ONCE_INIT;
+static struct uv__process_title process_title;
 static void* args_mem;
 
-static struct {
-  char* str;
-  size_t len;
-} process_title;
-
 
 static void init_process_title_mutex_once(void) {
   uv_mutex_init(&process_title_mutex);
-#ifdef __APPLE__
-  uv__set_process_title_platform_init();
-#endif
 }
 
 
 char** uv_setup_args(int argc, char** argv) {
+  struct uv__process_title pt;
   char** new_argv;
   size_t size;
   char* s;
@@ -54,20 +53,14 @@
   if (argc <= 0)
     return argv;
 
-  /* Calculate how much memory we need for the argv strings. */
-  size = 0;
-  for (i = 0; i < argc; i++)
-    size += strlen(argv[i]) + 1;
+  pt.str = argv[0];
+  pt.len = strlen(argv[0]);
+  pt.cap = pt.len + 1;
 
-#if defined(__MVS__)
-  /* argv is not adjacent. So just use argv[0] */
-  process_title.str = argv[0];
-  process_title.len = strlen(argv[0]);
-#else
-  process_title.str = argv[0];
-  process_title.len = argv[argc - 1] + strlen(argv[argc - 1]) - argv[0];
-  assert(process_title.len + 1 == size);  /* argv memory should be adjacent. */
-#endif
+  /* Calculate how much memory we need for the argv strings. */
+  size = pt.cap;
+  for (i = 1; i < argc; i++)
+    size += strlen(argv[i]) + 1;
 
   /* Add space for the argv pointers. */
   size += (argc + 1) * sizeof(char*);
@@ -75,32 +68,54 @@
   new_argv = uv__malloc(size);
   if (new_argv == NULL)
     return argv;
-  args_mem = new_argv;
 
   /* Copy over the strings and set up the pointer table. */
+  i = 0;
   s = (char*) &new_argv[argc + 1];
-  for (i = 0; i < argc; i++) {
+  size = pt.cap;
+  goto loop;
+
+  for (/* empty */; i < argc; i++) {
     size = strlen(argv[i]) + 1;
+  loop:
     memcpy(s, argv[i], size);
     new_argv[i] = s;
     s += size;
   }
   new_argv[i] = NULL;
 
+  /* argv is not adjacent on z/os, we use just argv[0] on that platform. */
+#ifndef __MVS__
+  pt.cap = argv[i - 1] + size - argv[0];
+#endif
+
+  args_mem = new_argv;
+  process_title = pt;
+
   return new_argv;
 }
 
 
 int uv_set_process_title(const char* title) {
+  struct uv__process_title* pt;
+  size_t len;
+
+  pt = &process_title;
+  len = strlen(title);
+
   uv_once(&process_title_mutex_once, init_process_title_mutex_once);
   uv_mutex_lock(&process_title_mutex);
 
-  if (process_title.len != 0) {
-    /* No need to terminate, byte after is always '\0'. */
-    strncpy(process_title.str, title, process_title.len);
-    uv__set_process_title(title);
+  if (len >= pt->cap) {
+    len = 0;
+    if (pt->cap > 0)
+      len = pt->cap - 1;
   }
 
+  memcpy(pt->str, title, len);
+  memset(pt->str + len, '\0', pt->cap - len);
+  pt->len = len;
+
   uv_mutex_unlock(&process_title_mutex);
 
   return 0;
@@ -130,7 +145,7 @@
 }
 
 
-UV_DESTRUCTOR(static void free_args_mem(void)) {
+void uv__process_title_cleanup(void) {
   uv__free(args_mem);  /* Keep valgrind happy. */
   args_mem = NULL;
 }
diff --git a/Utilities/cmlibuv/src/unix/random-devurandom.c b/Utilities/cmlibuv/src/unix/random-devurandom.c
new file mode 100644
index 0000000..05e52a5
--- /dev/null
+++ b/Utilities/cmlibuv/src/unix/random-devurandom.c
@@ -0,0 +1,93 @@
+/* Copyright libuv contributors. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#include "uv.h"
+#include "internal.h"
+
+#include <sys/stat.h>
+#include <unistd.h>
+
+static uv_once_t once = UV_ONCE_INIT;
+static int status;
+
+
+int uv__random_readpath(const char* path, void* buf, size_t buflen) {
+  struct stat s;
+  size_t pos;
+  ssize_t n;
+  int fd;
+
+  fd = uv__open_cloexec(path, O_RDONLY);
+
+  if (fd < 0)
+    return fd;
+
+  if (fstat(fd, &s)) {
+    uv__close(fd);
+    return UV__ERR(errno);
+  }
+
+  if (!S_ISCHR(s.st_mode)) {
+    uv__close(fd);
+    return UV_EIO;
+  }
+
+  for (pos = 0; pos != buflen; pos += n) {
+    do
+      n = read(fd, (char*) buf + pos, buflen - pos);
+    while (n == -1 && errno == EINTR);
+
+    if (n == -1) {
+      uv__close(fd);
+      return UV__ERR(errno);
+    }
+
+    if (n == 0) {
+      uv__close(fd);
+      return UV_EIO;
+    }
+  }
+
+  uv__close(fd);
+  return 0;
+}
+
+
+static void uv__random_devurandom_init(void) {
+  char c;
+
+  /* Linux's random(4) man page suggests applications should read at least
+   * once from /dev/random before switching to /dev/urandom in order to seed
+   * the system RNG. Reads from /dev/random can of course block indefinitely
+   * until entropy is available but that's the point.
+   */
+  status = uv__random_readpath("/dev/random", &c, 1);
+}
+
+
+int uv__random_devurandom(void* buf, size_t buflen) {
+  uv_once(&once, uv__random_devurandom_init);
+
+  if (status != 0)
+    return status;
+
+  return uv__random_readpath("/dev/urandom", buf, buflen);
+}
diff --git a/Utilities/cmlibuv/src/unix/random-getentropy.c b/Utilities/cmlibuv/src/unix/random-getentropy.c
new file mode 100644
index 0000000..c45d9fd
--- /dev/null
+++ b/Utilities/cmlibuv/src/unix/random-getentropy.c
@@ -0,0 +1,57 @@
+/* Copyright libuv contributors. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#include "uv.h"
+#include "internal.h"
+
+#include <stddef.h>
+#include <dlfcn.h>
+
+typedef int (*uv__getentropy_cb)(void *, size_t);
+
+static uv__getentropy_cb uv__getentropy;
+static uv_once_t once = UV_ONCE_INIT;
+
+
+static void uv__random_getentropy_init(void) {
+  uv__getentropy = (uv__getentropy_cb) dlsym(RTLD_DEFAULT, "getentropy");
+}
+
+
+int uv__random_getentropy(void* buf, size_t buflen) {
+  size_t pos;
+  size_t stride;
+
+  uv_once(&once, uv__random_getentropy_init);
+
+  if (uv__getentropy == NULL)
+    return UV_ENOSYS;
+
+  /* getentropy() returns an error for requests > 256 bytes. */
+  for (pos = 0, stride = 256; pos + stride < buflen; pos += stride)
+    if (uv__getentropy((char *) buf + pos, stride))
+      return UV__ERR(errno);
+
+  if (uv__getentropy((char *) buf + pos, buflen - pos))
+    return UV__ERR(errno);
+
+  return 0;
+}
diff --git a/Utilities/cmlibuv/src/unix/random-getrandom.c b/Utilities/cmlibuv/src/unix/random-getrandom.c
new file mode 100644
index 0000000..bcc9408
--- /dev/null
+++ b/Utilities/cmlibuv/src/unix/random-getrandom.c
@@ -0,0 +1,88 @@
+/* Copyright libuv contributors. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#include "uv.h"
+#include "internal.h"
+
+#ifdef __linux__
+
+#include "linux-syscalls.h"
+
+#define uv__random_getrandom_init() 0
+
+#else  /* !__linux__ */
+
+#include <stddef.h>
+#include <dlfcn.h>
+
+typedef ssize_t (*uv__getrandom_cb)(void *, size_t, unsigned);
+
+static uv__getrandom_cb uv__getrandom;
+static uv_once_t once = UV_ONCE_INIT;
+
+static void uv__random_getrandom_init_once(void) {
+  uv__getrandom = (uv__getrandom_cb) dlsym(RTLD_DEFAULT, "getrandom");
+}
+
+static int uv__random_getrandom_init(void) {
+  uv_once(&once, uv__random_getrandom_init_once);
+
+  if (uv__getrandom == NULL)
+    return UV_ENOSYS;
+
+  return 0;
+}
+
+#endif  /* !__linux__ */
+
+int uv__random_getrandom(void* buf, size_t buflen) {
+  ssize_t n;
+  size_t pos;
+  int rc;
+
+  rc = uv__random_getrandom_init();
+  if (rc != 0)
+    return rc;
+
+  for (pos = 0; pos != buflen; pos += n) {
+    do {
+      n = buflen - pos;
+
+      /* Most getrandom() implementations promise that reads <= 256 bytes
+       * will always succeed and won't be interrupted by signals.
+       * It's therefore useful to split it up in smaller reads because
+       * one big read may, in theory, continuously fail with EINTR.
+       */
+      if (n > 256)
+        n = 256;
+
+      n = uv__getrandom((char *) buf + pos, n, 0);
+    } while (n == -1 && errno == EINTR);
+
+    if (n == -1)
+      return UV__ERR(errno);
+
+    if (n == 0)
+      return UV_EIO;
+  }
+
+  return 0;
+}
diff --git a/Utilities/cmlibuv/src/unix/random-sysctl-linux.c b/Utilities/cmlibuv/src/unix/random-sysctl-linux.c
new file mode 100644
index 0000000..66ba8d7
--- /dev/null
+++ b/Utilities/cmlibuv/src/unix/random-sysctl-linux.c
@@ -0,0 +1,99 @@
+/* Copyright libuv contributors. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#include "uv.h"
+#include "internal.h"
+
+#include <errno.h>
+#include <string.h>
+
+#include <syscall.h>
+#include <unistd.h>
+
+
+struct uv__sysctl_args {
+  int* name;
+  int nlen;
+  void* oldval;
+  size_t* oldlenp;
+  void* newval;
+  size_t newlen;
+  unsigned long unused[4];
+};
+
+
+int uv__random_sysctl(void* buf, size_t buflen) {
+  static int name[] = {1 /*CTL_KERN*/, 40 /*KERN_RANDOM*/, 6 /*RANDOM_UUID*/};
+  struct uv__sysctl_args args;
+  char uuid[16];
+  char* p;
+  char* pe;
+  size_t n;
+
+  p = buf;
+  pe = p + buflen;
+
+  while (p < pe) {
+    memset(&args, 0, sizeof(args));
+
+    args.name = name;
+    args.nlen = ARRAY_SIZE(name);
+    args.oldval = uuid;
+    args.oldlenp = &n;
+    n = sizeof(uuid);
+
+    /* Emits a deprecation warning with some kernels but that seems like
+     * an okay trade-off for the fallback of the fallback: this function is
+     * only called when neither getrandom(2) nor /dev/urandom are available.
+     * Fails with ENOSYS on kernels configured without CONFIG_SYSCTL_SYSCALL.
+     * At least arm64 never had a _sysctl system call and therefore doesn't
+     * have a SYS__sysctl define either.
+     */
+#ifdef SYS__sysctl
+    if (syscall(SYS__sysctl, &args) == -1)
+      return UV__ERR(errno);
+#else
+    {
+      (void) &args;
+      return UV_ENOSYS;
+    }
+#endif
+
+    if (n != sizeof(uuid))
+      return UV_EIO;  /* Can't happen. */
+
+    /* uuid[] is now a type 4 UUID. Bytes 6 and 8 (counting from zero) contain
+     * 4 and 5 bits of entropy, respectively. For ease of use, we skip those
+     * and only use 14 of the 16 bytes.
+     */
+    uuid[6] = uuid[14];
+    uuid[8] = uuid[15];
+
+    n = pe - p;
+    if (n > 14)
+      n = 14;
+
+    memcpy(p, uuid, n);
+    p += n;
+  }
+
+  return 0;
+}
diff --git a/Utilities/cmlibuv/src/unix/signal.c b/Utilities/cmlibuv/src/unix/signal.c
index 01aa55f..1c83e09 100644
--- a/Utilities/cmlibuv/src/unix/signal.c
+++ b/Utilities/cmlibuv/src/unix/signal.c
@@ -77,7 +77,7 @@
 }
 
 
-UV_DESTRUCTOR(static void uv__signal_global_fini(void)) {
+void uv__signal_cleanup(void) {
   /* We can only use signal-safe functions here.
    * That includes read/write and close, fortunately.
    * We do all of this directly here instead of resetting
@@ -98,7 +98,7 @@
 
 
 static void uv__signal_global_reinit(void) {
-  uv__signal_global_fini();
+  uv__signal_cleanup();
 
   if (uv__make_pipe(uv__signal_lock_pipefd, 0))
     abort();
@@ -331,16 +331,7 @@
 
 
 void uv__signal_close(uv_signal_t* handle) {
-
   uv__signal_stop(handle);
-
-  /* If there are any caught signals "trapped" in the signal pipe, we can't
-   * call the close callback yet. Otherwise, add the handle to the finish_close
-   * queue.
-   */
-  if (handle->caught_signals == handle->dispatched_signals) {
-    uv__make_close_pending((uv_handle_t*) handle);
-  }
 }
 
 
@@ -375,7 +366,7 @@
 
   /* Short circuit: if the signal watcher is already watching {signum} don't
    * go through the process of deregistering and registering the handler.
-   * Additionally, this avoids pending signals getting lost in the small time
+   * Additionally, this avoids pending signals getting lost in the small
    * time frame that handle->signum == 0.
    */
   if (signum == handle->signum) {
@@ -472,15 +463,6 @@
 
       if (handle->flags & UV_SIGNAL_ONE_SHOT)
         uv__signal_stop(handle);
-
-      /* If uv_close was called while there were caught signals that were not
-       * yet dispatched, the uv__finish_close was deferred. Make close pending
-       * now if this has happened.
-       */
-      if ((handle->flags & UV_HANDLE_CLOSING) &&
-          (handle->caught_signals == handle->dispatched_signals)) {
-        uv__make_close_pending((uv_handle_t*) handle);
-      }
     }
 
     bytes -= end;
@@ -563,6 +545,7 @@
     if (first_oneshot && !rem_oneshot) {
       ret = uv__signal_register_handler(handle->signum, 1);
       assert(ret == 0);
+      (void)ret;
     }
   }
 
diff --git a/Utilities/cmlibuv/src/unix/stream.c b/Utilities/cmlibuv/src/unix/stream.c
index 8121f64..3b6da8d 100644
--- a/Utilities/cmlibuv/src/unix/stream.c
+++ b/Utilities/cmlibuv/src/unix/stream.c
@@ -1000,12 +1000,12 @@
 
 static void uv__stream_eof(uv_stream_t* stream, const uv_buf_t* buf) {
   stream->flags |= UV_HANDLE_READ_EOF;
+  stream->flags &= ~UV_HANDLE_READING;
   uv__io_stop(stream->loop, &stream->io_watcher, POLLIN);
   if (!uv__io_active(&stream->io_watcher, POLLOUT))
     uv__handle_stop(stream);
   uv__stream_osx_interrupt_select(stream);
   stream->read_cb(stream, UV_EOF, buf);
-  stream->flags &= ~UV_HANDLE_READING;
 }
 
 
@@ -1048,7 +1048,12 @@
 }
 
 
-#define UV__CMSG_FD_COUNT 64
+#if defined(__PASE__)
+/* on IBMi PASE the control message length can not exceed 256. */
+# define UV__CMSG_FD_COUNT 60
+#else
+# define UV__CMSG_FD_COUNT 64
+#endif
 #define UV__CMSG_FD_SIZE (UV__CMSG_FD_COUNT * sizeof(int))
 
 
@@ -1403,7 +1408,7 @@
     return UV_EBADF;
 
   if (!(stream->flags & UV_HANDLE_WRITABLE))
-    return -EPIPE;
+    return UV_EPIPE;
 
   if (send_handle) {
     if (stream->type != UV_NAMED_PIPE || !((uv_pipe_t*)stream)->ipc)
@@ -1557,7 +1562,7 @@
     return UV_EINVAL;
 
   if (!(stream->flags & UV_HANDLE_READABLE))
-    return -ENOTCONN;
+    return UV_ENOTCONN;
 
   /* The UV_HANDLE_READING flag is irrelevant of the state of the tcp - it just
    * expresses the desired state of the user.
diff --git a/Utilities/cmlibuv/src/unix/sunos.c b/Utilities/cmlibuv/src/unix/sunos.c
index 0cd25c1..9697648 100644
--- a/Utilities/cmlibuv/src/unix/sunos.c
+++ b/Utilities/cmlibuv/src/unix/sunos.c
@@ -700,16 +700,6 @@
 }
 
 
-void uv_free_cpu_info(uv_cpu_info_t* cpu_infos, int count) {
-  int i;
-
-  for (i = 0; i < count; i++) {
-    uv__free(cpu_infos[i].model);
-  }
-
-  uv__free(cpu_infos);
-}
-
 #ifdef SUNOS_NO_IFADDRS
 int uv_interface_addresses(uv_interface_address_t** addresses, int* count) {
   *count = 0;
diff --git a/Utilities/cmlibuv/src/unix/tcp.c b/Utilities/cmlibuv/src/unix/tcp.c
index 8cedcd6..d47e943 100644
--- a/Utilities/cmlibuv/src/unix/tcp.c
+++ b/Utilities/cmlibuv/src/unix/tcp.c
@@ -308,6 +308,23 @@
 }
 
 
+int uv_tcp_close_reset(uv_tcp_t* handle, uv_close_cb close_cb) {
+  int fd;
+  struct linger l = { 1, 0 };
+
+  /* Disallow setting SO_LINGER to zero due to some platform inconsistencies */
+  if (handle->flags & UV_HANDLE_SHUTTING)
+    return UV_EINVAL;
+
+  fd = uv__stream_fd(handle);
+  if (0 != setsockopt(fd, SOL_SOCKET, SO_LINGER, &l, sizeof(l)))
+    return UV__ERR(errno);
+
+  uv_close((uv_handle_t*) handle, close_cb);
+  return 0;
+}
+
+
 int uv_tcp_listen(uv_tcp_t* tcp, int backlog, uv_connection_cb cb) {
   static int single_accept = -1;
   unsigned long flags;
@@ -362,8 +379,16 @@
     return UV__ERR(errno);
 
 #ifdef TCP_KEEPIDLE
-  if (on && setsockopt(fd, IPPROTO_TCP, TCP_KEEPIDLE, &delay, sizeof(delay)))
-    return UV__ERR(errno);
+  if (on) {
+    int intvl = 1;  /*  1 second; same as default on Win32 */
+    int cnt = 10;  /* 10 retries; same as hardcoded on Win32 */
+    if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPIDLE, &delay, sizeof(delay)))
+      return UV__ERR(errno);
+    if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPINTVL, &intvl, sizeof(intvl)))
+      return UV__ERR(errno);
+    if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPCNT, &cnt, sizeof(cnt)))
+      return UV__ERR(errno);
+  }
 #endif
 
   /* Solaris/SmartOS, if you don't support keep-alive,
diff --git a/Utilities/cmlibuv/src/unix/thread.c b/Utilities/cmlibuv/src/unix/thread.c
index 0453221..f93aa53 100644
--- a/Utilities/cmlibuv/src/unix/thread.c
+++ b/Utilities/cmlibuv/src/unix/thread.c
@@ -37,7 +37,7 @@
 #include <sys/sem.h>
 #endif
 
-#ifdef __GLIBC__
+#if defined(__GLIBC__) && !defined(__UCLIBC__)
 #include <gnu/libc-version.h>  /* gnu_get_libc_version() */
 #endif
 
@@ -222,6 +222,12 @@
   size_t pagesize;
   size_t stack_size;
 
+  /* Used to squelch a -Wcast-function-type warning. */
+  union {
+    void (*in)(void*);
+    void* (*out)(void*);
+  } f;
+
   stack_size =
       params->flags & UV_THREAD_HAS_STACK_SIZE ? params->stack_size : 0;
 
@@ -248,7 +254,8 @@
       abort();
   }
 
-  err = pthread_create(tid, attr, (void*(*)(void*)) entry, arg);
+  f.in = entry;
+  err = pthread_create(tid, attr, f.out, arg);
 
   if (attr != NULL)
     pthread_attr_destroy(attr);
@@ -474,7 +481,7 @@
 
 #else /* !(defined(__APPLE__) && defined(__MACH__)) */
 
-#ifdef __GLIBC__
+#if defined(__GLIBC__) && !defined(__UCLIBC__)
 
 /* Hack around https://sourceware.org/bugzilla/show_bug.cgi?id=12674
  * by providing a custom implementation for glibc < 2.21 in terms of other
@@ -510,7 +517,8 @@
   unsigned int value;
 } uv_semaphore_t;
 
-#if defined(__GLIBC__) || platform_needs_custom_semaphore
+#if (defined(__GLIBC__) && !defined(__UCLIBC__)) || \
+    platform_needs_custom_semaphore
 STATIC_ASSERT(sizeof(uv_sem_t) >= sizeof(uv_semaphore_t*));
 #endif
 
@@ -639,7 +647,7 @@
 }
 
 int uv_sem_init(uv_sem_t* sem, unsigned int value) {
-#ifdef __GLIBC__
+#if defined(__GLIBC__) && !defined(__UCLIBC__)
   uv_once(&glibc_version_check_once, glibc_version_check);
 #endif
 
diff --git a/Utilities/cmlibuv/src/unix/tty.c b/Utilities/cmlibuv/src/unix/tty.c
index db479d6..82cd723 100644
--- a/Utilities/cmlibuv/src/unix/tty.c
+++ b/Utilities/cmlibuv/src/unix/tty.c
@@ -34,6 +34,34 @@
 #define IMAXBEL 0
 #endif
 
+#if defined(__PASE__)
+/* On IBM i PASE, for better compatibility with running interactive programs in
+ * a 5250 environment, isatty() will return true for the stdin/stdout/stderr
+ * streams created by QSH/QP2TERM.
+ *
+ * For more, see docs on PASE_STDIO_ISATTY in
+ * https://www.ibm.com/support/knowledgecenter/ssw_ibm_i_74/apis/pase_environ.htm
+ *
+ * This behavior causes problems for Node as it expects that if isatty() returns
+ * true that TTY ioctls will be supported by that fd (which is not an
+ * unreasonable expectation) and when they don't it crashes with assertion
+ * errors.
+ *
+ * Here, we create our own version of isatty() that uses ioctl() to identify
+ * whether the fd is *really* a TTY or not.
+ */
+static int isreallyatty(int file) {
+  int rc;
+ 
+  rc = !ioctl(file, TXISATTY + 0x81, NULL);
+  if (!rc && errno != EBADF)
+      errno = ENOTTY;
+
+  return rc;
+}
+#define isatty(fd) isreallyatty(fd)
+#endif
+
 static int orig_termios_fd = -1;
 static struct termios orig_termios;
 static uv_spinlock_t termios_spinlock = UV_SPINLOCK_INITIALIZER;
@@ -136,7 +164,7 @@
      * slave device.
      */
     if (uv__tty_is_slave(fd) && ttyname_r(fd, path, sizeof(path)) == 0)
-      r = uv__open_cloexec(path, mode);
+      r = uv__open_cloexec(path, mode | O_NOCTTY);
     else
       r = -1;
 
@@ -362,3 +390,10 @@
 
   return err;
 }
+
+void uv_tty_set_vterm_state(uv_tty_vtermstate_t state) {
+}
+
+int uv_tty_get_vterm_state(uv_tty_vtermstate_t* state) {
+  return UV_ENOTSUP;
+}
diff --git a/Utilities/cmlibuv/src/unix/udp.c b/Utilities/cmlibuv/src/unix/udp.c
index b578e7b..21b922f 100644
--- a/Utilities/cmlibuv/src/unix/udp.c
+++ b/Utilities/cmlibuv/src/unix/udp.c
@@ -32,6 +32,8 @@
 #endif
 #include <sys/un.h>
 
+#define UV__UDP_DGRAM_MAXSIZE (64 * 1024)
+
 #if defined(IPV6_JOIN_GROUP) && !defined(IPV6_ADD_MEMBERSHIP)
 # define IPV6_ADD_MEMBERSHIP IPV6_JOIN_GROUP
 #endif
@@ -49,6 +51,36 @@
                                        int domain,
                                        unsigned int flags);
 
+#if HAVE_MMSG
+
+#define UV__MMSG_MAXWIDTH 20
+
+static int uv__udp_recvmmsg(uv_udp_t* handle, uv_buf_t* buf);
+static void uv__udp_sendmmsg(uv_udp_t* handle);
+
+static int uv__recvmmsg_avail;
+static int uv__sendmmsg_avail;
+static uv_once_t once = UV_ONCE_INIT;
+
+static void uv__udp_mmsg_init(void) {
+  int ret;
+  int s;
+  s = uv__socket(AF_INET, SOCK_DGRAM, 0);
+  if (s < 0)
+    return;
+  ret = uv__sendmmsg(s, NULL, 0, 0);
+  if (ret == 0 || errno != ENOSYS) {
+    uv__sendmmsg_avail = 1;
+    uv__recvmmsg_avail = 1;
+  } else {
+    ret = uv__recvmmsg(s, NULL, 0, 0, NULL);
+    if (ret == 0 || errno != ENOSYS)
+      uv__recvmmsg_avail = 1;
+  }
+  uv__close(s);
+}
+
+#endif
 
 void uv__udp_close(uv_udp_t* handle) {
   uv__io_close(handle->loop, &handle->io_watcher);
@@ -148,6 +180,64 @@
   }
 }
 
+#if HAVE_MMSG
+static int uv__udp_recvmmsg(uv_udp_t* handle, uv_buf_t* buf) {
+  struct sockaddr_in6 peers[UV__MMSG_MAXWIDTH];
+  struct iovec iov[UV__MMSG_MAXWIDTH];
+  struct uv__mmsghdr msgs[UV__MMSG_MAXWIDTH];
+  ssize_t nread;
+  uv_buf_t chunk_buf;
+  size_t chunks;
+  int flags;
+  size_t k;
+
+  /* prepare structures for recvmmsg */
+  chunks = buf->len / UV__UDP_DGRAM_MAXSIZE;
+  if (chunks > ARRAY_SIZE(iov))
+    chunks = ARRAY_SIZE(iov);
+  for (k = 0; k < chunks; ++k) {
+    iov[k].iov_base = buf->base + k * UV__UDP_DGRAM_MAXSIZE;
+    iov[k].iov_len = UV__UDP_DGRAM_MAXSIZE;
+    msgs[k].msg_hdr.msg_iov = iov + k;
+    msgs[k].msg_hdr.msg_iovlen = 1;
+    msgs[k].msg_hdr.msg_name = peers + k;
+    msgs[k].msg_hdr.msg_namelen = sizeof(peers[0]);
+    msgs[k].msg_hdr.msg_control = NULL;
+    msgs[k].msg_hdr.msg_controllen = 0;
+    msgs[k].msg_hdr.msg_flags = 0;
+  }
+
+  do
+    nread = uv__recvmmsg(handle->io_watcher.fd, msgs, chunks, 0, NULL);
+  while (nread == -1 && errno == EINTR);
+
+  if (nread < 1) {
+    if (nread == 0 || errno == EAGAIN || errno == EWOULDBLOCK)
+      handle->recv_cb(handle, 0, buf, NULL, 0);
+    else
+      handle->recv_cb(handle, UV__ERR(errno), buf, NULL, 0);
+  } else {
+    /* pass each chunk to the application */
+    for (k = 0; k < (size_t) nread && handle->recv_cb != NULL; k++) {
+      flags = UV_UDP_MMSG_CHUNK;
+      if (msgs[k].msg_hdr.msg_flags & MSG_TRUNC)
+        flags |= UV_UDP_PARTIAL;
+
+      chunk_buf = uv_buf_init(iov[k].iov_base, iov[k].iov_len);
+      handle->recv_cb(handle,
+                      msgs[k].msg_len,
+                      &chunk_buf,
+                      msgs[k].msg_hdr.msg_name,
+                      flags);
+    }
+
+    /* one last callback so the original buffer is freed */
+    if (handle->recv_cb != NULL)
+      handle->recv_cb(handle, 0, buf, NULL, 0);
+  }
+  return nread;
+}
+#endif
 
 static void uv__udp_recvmsg(uv_udp_t* handle) {
   struct sockaddr_storage peer;
@@ -165,18 +255,30 @@
    */
   count = 32;
 
-  memset(&h, 0, sizeof(h));
-  h.msg_name = &peer;
-
   do {
     buf = uv_buf_init(NULL, 0);
-    handle->alloc_cb((uv_handle_t*) handle, 64 * 1024, &buf);
+    handle->alloc_cb((uv_handle_t*) handle, UV__UDP_DGRAM_MAXSIZE, &buf);
     if (buf.base == NULL || buf.len == 0) {
       handle->recv_cb(handle, UV_ENOBUFS, &buf, NULL, 0);
       return;
     }
     assert(buf.base != NULL);
 
+#if HAVE_MMSG
+    if (handle->flags & UV_HANDLE_UDP_RECVMMSG) {
+      uv_once(&once, uv__udp_mmsg_init);
+      if (uv__recvmmsg_avail) {
+        nread = uv__udp_recvmmsg(handle, &buf);
+        if (nread > 0)
+          count -= nread;
+        continue;
+      }
+    }
+#endif
+
+    memset(&h, 0, sizeof(h));
+    memset(&peer, 0, sizeof(peer));
+    h.msg_name = &peer;
     h.msg_namelen = sizeof(peer);
     h.msg_iov = (void*) &buf;
     h.msg_iovlen = 1;
@@ -193,33 +295,126 @@
         handle->recv_cb(handle, UV__ERR(errno), &buf, NULL, 0);
     }
     else {
-      const struct sockaddr *addr;
-      if (h.msg_namelen == 0)
-        addr = NULL;
-      else
-        addr = (const struct sockaddr*) &peer;
-
       flags = 0;
       if (h.msg_flags & MSG_TRUNC)
         flags |= UV_UDP_PARTIAL;
 
-      handle->recv_cb(handle, nread, &buf, addr, flags);
+      handle->recv_cb(handle, nread, &buf, (const struct sockaddr*) &peer, flags);
     }
+    count--;
   }
   /* recv_cb callback may decide to pause or close the handle */
   while (nread != -1
-      && count-- > 0
+      && count > 0
       && handle->io_watcher.fd != -1
       && handle->recv_cb != NULL);
 }
 
+#if HAVE_MMSG
+static void uv__udp_sendmmsg(uv_udp_t* handle) {
+  uv_udp_send_t* req;
+  struct uv__mmsghdr h[UV__MMSG_MAXWIDTH];
+  struct uv__mmsghdr *p;
+  QUEUE* q;
+  ssize_t npkts;
+  size_t pkts;
+  size_t i;
+
+  if (QUEUE_EMPTY(&handle->write_queue))
+    return;
+
+write_queue_drain:
+  for (pkts = 0, q = QUEUE_HEAD(&handle->write_queue);
+       pkts < UV__MMSG_MAXWIDTH && q != &handle->write_queue;
+       ++pkts, q = QUEUE_HEAD(q)) {
+    assert(q != NULL);
+    req = QUEUE_DATA(q, uv_udp_send_t, queue);
+    assert(req != NULL);
+
+    p = &h[pkts];
+    memset(p, 0, sizeof(*p));
+    if (req->addr.ss_family == AF_UNSPEC) {
+      p->msg_hdr.msg_name = NULL;
+      p->msg_hdr.msg_namelen = 0;
+    } else {
+      p->msg_hdr.msg_name = &req->addr;
+      if (req->addr.ss_family == AF_INET6)
+        p->msg_hdr.msg_namelen = sizeof(struct sockaddr_in6);
+      else if (req->addr.ss_family == AF_INET)
+        p->msg_hdr.msg_namelen = sizeof(struct sockaddr_in);
+      else if (req->addr.ss_family == AF_UNIX)
+        p->msg_hdr.msg_namelen = sizeof(struct sockaddr_un);
+      else {
+        assert(0 && "unsupported address family");
+        abort();
+      }
+    }
+    h[pkts].msg_hdr.msg_iov = (struct iovec*) req->bufs;
+    h[pkts].msg_hdr.msg_iovlen = req->nbufs;
+  }
+
+  do
+    npkts = uv__sendmmsg(handle->io_watcher.fd, h, pkts, 0);
+  while (npkts == -1 && errno == EINTR);
+
+  if (npkts < 1) {
+    if (errno == EAGAIN || errno == EWOULDBLOCK || errno == ENOBUFS)
+      return;
+    for (i = 0, q = QUEUE_HEAD(&handle->write_queue);
+         i < pkts && q != &handle->write_queue;
+         ++i, q = QUEUE_HEAD(q)) {
+      assert(q != NULL);
+      req = QUEUE_DATA(q, uv_udp_send_t, queue);
+      assert(req != NULL);
+
+      req->status = UV__ERR(errno);
+      QUEUE_REMOVE(&req->queue);
+      QUEUE_INSERT_TAIL(&handle->write_completed_queue, &req->queue);
+    }
+    uv__io_feed(handle->loop, &handle->io_watcher);
+    return;
+  }
+
+  for (i = 0, q = QUEUE_HEAD(&handle->write_queue);
+       i < pkts && q != &handle->write_queue;
+       ++i, q = QUEUE_HEAD(&handle->write_queue)) {
+    assert(q != NULL);
+    req = QUEUE_DATA(q, uv_udp_send_t, queue);
+    assert(req != NULL);
+
+    req->status = req->bufs[0].len;
+
+    /* Sending a datagram is an atomic operation: either all data
+     * is written or nothing is (and EMSGSIZE is raised). That is
+     * why we don't handle partial writes. Just pop the request
+     * off the write queue and onto the completed queue, done.
+     */
+    QUEUE_REMOVE(&req->queue);
+    QUEUE_INSERT_TAIL(&handle->write_completed_queue, &req->queue);
+  }
+
+  /* couldn't batch everything, continue sending (jump to avoid stack growth) */
+  if (!QUEUE_EMPTY(&handle->write_queue))
+    goto write_queue_drain;
+  uv__io_feed(handle->loop, &handle->io_watcher);
+  return;
+}
+#endif
 
 static void uv__udp_sendmsg(uv_udp_t* handle) {
   uv_udp_send_t* req;
-  QUEUE* q;
   struct msghdr h;
+  QUEUE* q;
   ssize_t size;
 
+#if HAVE_MMSG
+  uv_once(&once, uv__udp_mmsg_init);
+  if (uv__sendmmsg_avail) {
+    uv__udp_sendmmsg(handle);
+    return;
+  }
+#endif
+
   while (!QUEUE_EMPTY(&handle->write_queue)) {
     q = QUEUE_HEAD(&handle->write_queue);
     assert(q != NULL);
@@ -269,7 +464,6 @@
   }
 }
 
-
 /* On the BSDs, SO_REUSEPORT implies SO_REUSEADDR but with some additional
  * refinements for programs that use multicast.
  *
@@ -659,26 +853,111 @@
 }
 
 
-int uv_udp_init_ex(uv_loop_t* loop, uv_udp_t* handle, unsigned int flags) {
-  int domain;
+#if !defined(__OpenBSD__) && !defined(__NetBSD__) && !defined(__ANDROID__)
+static int uv__udp_set_source_membership4(uv_udp_t* handle,
+                                          const struct sockaddr_in* multicast_addr,
+                                          const char* interface_addr,
+                                          const struct sockaddr_in* source_addr,
+                                          uv_membership membership) {
+  struct ip_mreq_source mreq;
+  int optname;
   int err;
+
+  err = uv__udp_maybe_deferred_bind(handle, AF_INET, UV_UDP_REUSEADDR);
+  if (err)
+    return err;
+
+  memset(&mreq, 0, sizeof(mreq));
+
+  if (interface_addr != NULL) {
+    err = uv_inet_pton(AF_INET, interface_addr, &mreq.imr_interface.s_addr);
+    if (err)
+      return err;
+  } else {
+    mreq.imr_interface.s_addr = htonl(INADDR_ANY);
+  }
+
+  mreq.imr_multiaddr.s_addr = multicast_addr->sin_addr.s_addr;
+  mreq.imr_sourceaddr.s_addr = source_addr->sin_addr.s_addr;
+
+  if (membership == UV_JOIN_GROUP)
+    optname = IP_ADD_SOURCE_MEMBERSHIP;
+  else if (membership == UV_LEAVE_GROUP)
+    optname = IP_DROP_SOURCE_MEMBERSHIP;
+  else
+    return UV_EINVAL;
+
+  if (setsockopt(handle->io_watcher.fd,
+                 IPPROTO_IP,
+                 optname,
+                 &mreq,
+                 sizeof(mreq))) {
+    return UV__ERR(errno);
+  }
+
+  return 0;
+}
+
+
+static int uv__udp_set_source_membership6(uv_udp_t* handle,
+                                          const struct sockaddr_in6* multicast_addr,
+                                          const char* interface_addr,
+                                          const struct sockaddr_in6* source_addr,
+                                          uv_membership membership) {
+  struct group_source_req mreq;
+  struct sockaddr_in6 addr6;
+  int optname;
+  int err;
+
+  err = uv__udp_maybe_deferred_bind(handle, AF_INET6, UV_UDP_REUSEADDR);
+  if (err)
+    return err;
+
+  memset(&mreq, 0, sizeof(mreq));
+
+  if (interface_addr != NULL) {
+    err = uv_ip6_addr(interface_addr, 0, &addr6);
+    if (err)
+      return err;
+    mreq.gsr_interface = addr6.sin6_scope_id;
+  } else {
+    mreq.gsr_interface = 0;
+  }
+
+  memcpy(&mreq.gsr_group, multicast_addr, sizeof(mreq.gsr_group));
+  memcpy(&mreq.gsr_source, source_addr, sizeof(mreq.gsr_source));
+
+  if (membership == UV_JOIN_GROUP)
+    optname = MCAST_JOIN_SOURCE_GROUP;
+  else if (membership == UV_LEAVE_GROUP)
+    optname = MCAST_LEAVE_SOURCE_GROUP;
+  else
+    return UV_EINVAL;
+
+  if (setsockopt(handle->io_watcher.fd,
+                 IPPROTO_IPV6,
+                 optname,
+                 &mreq,
+                 sizeof(mreq))) {
+    return UV__ERR(errno);
+  }
+
+  return 0;
+}
+#endif
+
+
+int uv__udp_init_ex(uv_loop_t* loop,
+                    uv_udp_t* handle,
+                    unsigned flags,
+                    int domain) {
   int fd;
 
-  /* Use the lower 8 bits for the domain */
-  domain = flags & 0xFF;
-  if (domain != AF_INET && domain != AF_INET6 && domain != AF_UNSPEC)
-    return UV_EINVAL;
-
-  if (flags & ~0xFF)
-    return UV_EINVAL;
-
+  fd = -1;
   if (domain != AF_UNSPEC) {
-    err = uv__socket(domain, SOCK_DGRAM, 0);
-    if (err < 0)
-      return err;
-    fd = err;
-  } else {
-    fd = -1;
+    fd = uv__socket(domain, SOCK_DGRAM, 0);
+    if (fd < 0)
+      return fd;
   }
 
   uv__handle_init(loop, (uv_handle_t*)handle, UV_UDP);
@@ -694,11 +973,6 @@
 }
 
 
-int uv_udp_init(uv_loop_t* loop, uv_udp_t* handle) {
-  return uv_udp_init_ex(loop, handle, AF_UNSPEC);
-}
-
-
 int uv_udp_open(uv_udp_t* handle, uv_os_sock_t sock) {
   int err;
 
@@ -748,11 +1022,60 @@
   }
 }
 
+
+int uv_udp_set_source_membership(uv_udp_t* handle,
+                                 const char* multicast_addr,
+                                 const char* interface_addr,
+                                 const char* source_addr,
+                                 uv_membership membership) {
+#if !defined(__OpenBSD__) && !defined(__NetBSD__) && !defined(__ANDROID__)
+  int err;
+  struct sockaddr_storage mcast_addr;
+  struct sockaddr_in* mcast_addr4;
+  struct sockaddr_in6* mcast_addr6;
+  struct sockaddr_storage src_addr;
+  struct sockaddr_in* src_addr4;
+  struct sockaddr_in6* src_addr6;
+
+  mcast_addr4 = (struct sockaddr_in*)&mcast_addr;
+  mcast_addr6 = (struct sockaddr_in6*)&mcast_addr;
+  src_addr4 = (struct sockaddr_in*)&src_addr;
+  src_addr6 = (struct sockaddr_in6*)&src_addr;
+
+  err = uv_ip4_addr(multicast_addr, 0, mcast_addr4);
+  if (err) {
+    err = uv_ip6_addr(multicast_addr, 0, mcast_addr6);
+    if (err)
+      return err;
+    err = uv_ip6_addr(source_addr, 0, src_addr6);
+    if (err)
+      return err;
+    return uv__udp_set_source_membership6(handle,
+                                          mcast_addr6,
+                                          interface_addr,
+                                          src_addr6,
+                                          membership);
+  }
+
+  err = uv_ip4_addr(source_addr, 0, src_addr4);
+  if (err)
+    return err;
+  return uv__udp_set_source_membership4(handle,
+                                        mcast_addr4,
+                                        interface_addr,
+                                        src_addr4,
+                                        membership);
+#else
+  return UV_ENOSYS;
+#endif
+}
+
+
 static int uv__setsockopt(uv_udp_t* handle,
                          int option4,
                          int option6,
                          const void* val,
-                         size_t size) {
+                         socklen_t size) {
   int r;
 
   if (handle->flags & UV_HANDLE_IPV6)
@@ -875,7 +1198,7 @@
  * and use the general uv__setsockopt_maybe_char call otherwise.
  */
 #if defined(__sun) || defined(_AIX) || defined(__OpenBSD__) || \
-    defined(__MVS__) 
+    defined(__MVS__)
   if (handle->flags & UV_HANDLE_IPV6)
     return uv__setsockopt(handle,
                           IP_MULTICAST_LOOP,
diff --git a/Utilities/cmlibuv/src/uv-common.c b/Utilities/cmlibuv/src/uv-common.c
index f4853d6..2fcbe3d 100644
--- a/Utilities/cmlibuv/src/uv-common.c
+++ b/Utilities/cmlibuv/src/uv-common.c
@@ -100,6 +100,17 @@
   return NULL;
 }
 
+void* uv__reallocf(void* ptr, size_t size) {
+  void* newptr;
+
+  newptr = uv__realloc(ptr, size);
+  if (newptr == NULL)
+    if (size > 0)
+      uv__free(ptr);
+
+  return newptr;
+}
+
 int uv_replace_allocator(uv_malloc_func malloc_func,
                          uv_realloc_func realloc_func,
                          uv_calloc_func calloc_func,
@@ -212,6 +223,9 @@
   memset(addr, 0, sizeof(*addr));
   addr->sin_family = AF_INET;
   addr->sin_port = htons(port);
+#ifdef SIN6_LEN
+  addr->sin_len = sizeof(*addr);
+#endif
   return uv_inet_pton(AF_INET, ip, &(addr->sin_addr.s_addr));
 }
 
@@ -280,6 +294,36 @@
 }
 
 
+int uv_udp_init_ex(uv_loop_t* loop, uv_udp_t* handle, unsigned flags) {
+  unsigned extra_flags;
+  int domain;
+  int rc;
+
+  /* Use the lower 8 bits for the domain. */
+  domain = flags & 0xFF;
+  if (domain != AF_INET && domain != AF_INET6 && domain != AF_UNSPEC)
+    return UV_EINVAL;
+
+  /* Use the higher bits for extra flags. */
+  extra_flags = flags & ~0xFF;
+  if (extra_flags & ~UV_UDP_RECVMMSG)
+    return UV_EINVAL;
+
+  rc = uv__udp_init_ex(loop, handle, flags, domain);
+
+  if (rc == 0)
+    if (extra_flags & UV_UDP_RECVMMSG)
+      handle->flags |= UV_HANDLE_UDP_RECVMMSG;
+
+  return rc;
+}
+
+
+int uv_udp_init(uv_loop_t* loop, uv_udp_t* handle) {
+  return uv_udp_init_ex(loop, handle, AF_UNSPEC);
+}
+
+
 int uv_udp_bind(uv_udp_t* handle,
                 const struct sockaddr* addr,
                 unsigned int flags) {
@@ -788,3 +832,40 @@
   if (loop != default_loop)
     uv__free(loop);
 }
+
+
+void uv_os_free_environ(uv_env_item_t* envitems, int count) {
+  int i;
+
+  for (i = 0; i < count; i++) {
+    uv__free(envitems[i].name);
+  }
+
+  uv__free(envitems);
+}
+
+
+void uv_free_cpu_info(uv_cpu_info_t* cpu_infos, int count) {
+  int i;
+
+  for (i = 0; i < count; i++)
+    uv__free(cpu_infos[i].model);
+
+  uv__free(cpu_infos);
+}
+
+
+#ifdef __GNUC__  /* Also covers __clang__ and __INTEL_COMPILER. */
+__attribute__((destructor))
+#endif
+void uv_library_shutdown(void) {
+  static int was_shutdown;
+
+  if (was_shutdown)
+    return;
+
+  uv__process_title_cleanup();
+  uv__signal_cleanup();
+  uv__threadpool_cleanup();
+  was_shutdown = 1;
+}
diff --git a/Utilities/cmlibuv/src/uv-common.h b/Utilities/cmlibuv/src/uv-common.h
index f788161..0b0f5f8 100644
--- a/Utilities/cmlibuv/src/uv-common.h
+++ b/Utilities/cmlibuv/src/uv-common.h
@@ -104,6 +104,7 @@
   /* Only used by uv_udp_t handles. */
   UV_HANDLE_UDP_PROCESSING              = 0x01000000,
   UV_HANDLE_UDP_CONNECTED               = 0x02000000,
+  UV_HANDLE_UDP_RECVMMSG                = 0x04000000,
 
   /* Only used by uv_pipe_t handles. */
   UV_HANDLE_NON_OVERLAPPED_PIPE         = 0x01000000,
@@ -138,6 +139,11 @@
                    unsigned int addrlen,
                    uv_connect_cb cb);
 
+int uv__udp_init_ex(uv_loop_t* loop,
+                    uv_udp_t* handle,
+                    unsigned flags,
+                    int domain);
+
 int uv__udp_bind(uv_udp_t* handle,
                  const struct sockaddr* addr,
                  unsigned int  addrlen,
@@ -200,6 +206,10 @@
 void uv__run_timers(uv_loop_t* loop);
 void uv__timer_close(uv_timer_t* handle);
 
+void uv__process_title_cleanup(void);
+void uv__signal_cleanup(void);
+void uv__threadpool_cleanup(void);
+
 #define uv__has_active_reqs(loop)                                             \
   ((loop)->active_reqs.count > 0)
 
@@ -322,5 +332,6 @@
 void* uv__malloc(size_t size);
 void uv__free(void* ptr);
 void* uv__realloc(void* ptr, size_t size);
+void* uv__reallocf(void* ptr, size_t size);
 
 #endif /* UV_COMMON_H_ */
diff --git a/Utilities/cmlibuv/src/win/core.c b/Utilities/cmlibuv/src/win/core.c
index e9d0a58..9974a11 100644
--- a/Utilities/cmlibuv/src/win/core.c
+++ b/Utilities/cmlibuv/src/win/core.c
@@ -321,8 +321,13 @@
 
   uv__loops_remove(loop);
 
-  /* close the async handle without needing an extra loop iteration */
-  assert(!loop->wq_async.async_sent);
+  /* Close the async handle without needing an extra loop iteration.
+   * We might have a pending message, but we're just going to destroy the IOCP
+   * soon, so we can just discard it now without the usual risk of a getting
+   * another notification from GetQueuedCompletionStatusEx after calling the
+   * close_cb (which we also skip defining). We'll assert later that queue was
+   * actually empty and all reqs handled. */
+  loop->wq_async.async_sent = 0;
   loop->wq_async.close_cb = NULL;
   uv__handle_closing(&loop->wq_async);
   uv__handle_close(&loop->wq_async);
@@ -444,12 +449,12 @@
   timeout_time = loop->time + timeout;
 
   for (repeat = 0; ; repeat++) {
-    success = GetQueuedCompletionStatusEx(loop->iocp,
-                                          overlappeds,
-                                          ARRAY_SIZE(overlappeds),
-                                          &count,
-                                          timeout,
-                                          FALSE);
+    success = pGetQueuedCompletionStatusEx(loop->iocp,
+                                           overlappeds,
+                                           ARRAY_SIZE(overlappeds),
+                                           &count,
+                                           timeout,
+                                           FALSE);
 
     if (success) {
       for (i = 0; i < count; i++) {
diff --git a/Utilities/cmlibuv/src/win/error.c b/Utilities/cmlibuv/src/win/error.c
index 24924ba..3ec984c 100644
--- a/Utilities/cmlibuv/src/win/error.c
+++ b/Utilities/cmlibuv/src/win/error.c
@@ -72,6 +72,7 @@
     case ERROR_NOACCESS:                    return UV_EACCES;
     case WSAEACCES:                         return UV_EACCES;
     case ERROR_ELEVATION_REQUIRED:          return UV_EACCES;
+    case ERROR_CANT_ACCESS_FILE:            return UV_EACCES;
     case ERROR_ADDRESS_ALREADY_ASSOCIATED:  return UV_EADDRINUSE;
     case WSAEADDRINUSE:                     return UV_EADDRINUSE;
     case WSAEADDRNOTAVAIL:                  return UV_EADDRNOTAVAIL;
@@ -132,6 +133,7 @@
     case WSAENOBUFS:                        return UV_ENOBUFS;
     case ERROR_BAD_PATHNAME:                return UV_ENOENT;
     case ERROR_DIRECTORY:                   return UV_ENOENT;
+    case ERROR_ENVVAR_NOT_FOUND:            return UV_ENOENT;
     case ERROR_FILE_NOT_FOUND:              return UV_ENOENT;
     case ERROR_INVALID_NAME:                return UV_ENOENT;
     case ERROR_INVALID_DRIVE:               return UV_ENOENT;
diff --git a/Utilities/cmlibuv/src/win/fs-event.c b/Utilities/cmlibuv/src/win/fs-event.c
index acf8e11..0126c5e 100644
--- a/Utilities/cmlibuv/src/win/fs-event.c
+++ b/Utilities/cmlibuv/src/win/fs-event.c
@@ -83,6 +83,7 @@
 static int uv_split_path(const WCHAR* filename, WCHAR** dir,
     WCHAR** file) {
   size_t len, i;
+  DWORD dir_len;
 
   if (filename == NULL) {
     if (dir != NULL)
@@ -97,12 +98,16 @@
 
   if (i == 0) {
     if (dir) {
-      *dir = (WCHAR*)uv__malloc((MAX_PATH + 1) * sizeof(WCHAR));
+      dir_len = GetCurrentDirectoryW(0, NULL);
+      if (dir_len == 0) {
+        return -1;
+      }
+      *dir = (WCHAR*)uv__malloc(dir_len * sizeof(WCHAR));
       if (!*dir) {
         uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc");
       }
 
-      if (!GetCurrentDirectoryW(MAX_PATH, *dir)) {
+      if (!GetCurrentDirectoryW(dir_len, *dir)) {
         uv__free(*dir);
         *dir = NULL;
         return -1;
@@ -155,9 +160,11 @@
   int name_size, is_path_dir, size;
   DWORD attr, last_error;
   WCHAR* dir = NULL, *dir_to_watch, *pathw = NULL;
-  WCHAR short_path_buffer[MAX_PATH];
+  DWORD short_path_buffer_len;
+  WCHAR *short_path_buffer;
   WCHAR* short_path, *long_path;
 
+  short_path = NULL;
   if (uv__is_active(handle))
     return UV_EINVAL;
 
@@ -230,13 +237,23 @@
      */
 
     /* Convert to short path. */
+    short_path_buffer = NULL;
+    short_path_buffer_len = GetShortPathNameW(pathw, NULL, 0);
+    if (short_path_buffer_len == 0) {
+      goto short_path_done;
+    }
+    short_path_buffer = uv__malloc(short_path_buffer_len * sizeof(WCHAR));
+    if (short_path_buffer == NULL) {
+      goto short_path_done;
+    }
     if (GetShortPathNameW(pathw,
                           short_path_buffer,
-                          ARRAY_SIZE(short_path_buffer))) {
-      short_path = short_path_buffer;
-    } else {
-      short_path = NULL;
+                          short_path_buffer_len) == 0) {
+      uv__free(short_path_buffer);
+      short_path_buffer = NULL;
     }
+short_path_done:
+    short_path = short_path_buffer;
 
     if (uv_split_path(pathw, &dir, &handle->filew) != 0) {
       last_error = GetLastError();
@@ -346,6 +363,8 @@
   if (uv__is_active(handle))
     uv__handle_stop(handle);
 
+  uv__free(short_path);
+
   return uv_translate_sys_error(last_error);
 }
 
diff --git a/Utilities/cmlibuv/src/win/fs-fd-hash-inl.h b/Utilities/cmlibuv/src/win/fs-fd-hash-inl.h
new file mode 100644
index 0000000..7a203d2
--- /dev/null
+++ b/Utilities/cmlibuv/src/win/fs-fd-hash-inl.h
@@ -0,0 +1,178 @@
+#ifndef UV_WIN_FS_FD_HASH_INL_H_
+#define UV_WIN_FS_FD_HASH_INL_H_
+
+#include "uv.h"
+#include "internal.h"
+
+/* Files are only inserted in uv__fd_hash when the UV_FS_O_FILEMAP flag is
+ * specified. Thus, when uv__fd_hash_get returns true, the file mapping in the
+ * info structure should be used for read/write operations.
+ *
+ * If the file is empty, the mapping field will be set to
+ * INVALID_HANDLE_VALUE. This is not an issue since the file mapping needs to
+ * be created anyway when the file size changes.
+ *
+ * Since file descriptors are sequential integers, the modulo operator is used
+ * as hashing function. For each bucket, a single linked list of arrays is
+ * kept to minimize allocations. A statically allocated memory buffer is kept
+ * for the first array in each bucket. */
+
+
+#define UV__FD_HASH_SIZE 256
+#define UV__FD_HASH_GROUP_SIZE 16
+
+struct uv__fd_info_s {
+  int flags;
+  BOOLEAN is_directory;
+  HANDLE mapping;
+  LARGE_INTEGER size;
+  LARGE_INTEGER current_pos;
+};
+
+struct uv__fd_hash_entry_s {
+  uv_file fd;
+  struct uv__fd_info_s info;
+};
+
+struct uv__fd_hash_entry_group_s {
+  struct uv__fd_hash_entry_s entries[UV__FD_HASH_GROUP_SIZE];
+  struct uv__fd_hash_entry_group_s* next;
+};
+
+struct uv__fd_hash_bucket_s {
+  size_t size;
+  struct uv__fd_hash_entry_group_s* data;
+};
+
+
+static uv_mutex_t uv__fd_hash_mutex;
+
+static struct uv__fd_hash_entry_group_s
+  uv__fd_hash_entry_initial[UV__FD_HASH_SIZE * UV__FD_HASH_GROUP_SIZE];
+static struct uv__fd_hash_bucket_s uv__fd_hash[UV__FD_HASH_SIZE];
+
+
+INLINE static void uv__fd_hash_init(void) {
+  int i, err;
+
+  err = uv_mutex_init(&uv__fd_hash_mutex);
+  if (err) {
+    uv_fatal_error(err, "uv_mutex_init");
+  }
+
+  for (i = 0; i < ARRAY_SIZE(uv__fd_hash); ++i) {
+    uv__fd_hash[i].size = 0;
+    uv__fd_hash[i].data =
+        uv__fd_hash_entry_initial + i * UV__FD_HASH_GROUP_SIZE;
+  }
+}
+
+#define FIND_COMMON_VARIABLES                                                \
+  unsigned i;                                                                \
+  unsigned bucket = fd % ARRAY_SIZE(uv__fd_hash);                            \
+  struct uv__fd_hash_entry_s* entry_ptr = NULL;                              \
+  struct uv__fd_hash_entry_group_s* group_ptr;                               \
+  struct uv__fd_hash_bucket_s* bucket_ptr = &uv__fd_hash[bucket];
+
+#define FIND_IN_GROUP_PTR(group_size)                                        \
+  do {                                                                       \
+    for (i = 0; i < group_size; ++i) {                                       \
+      if (group_ptr->entries[i].fd == fd) {                                  \
+        entry_ptr = &group_ptr->entries[i];                                  \
+        break;                                                               \
+      }                                                                      \
+    }                                                                        \
+  } while (0)
+
+#define FIND_IN_BUCKET_PTR()                                                 \
+  do {                                                                       \
+    size_t first_group_size = bucket_ptr->size % UV__FD_HASH_GROUP_SIZE;     \
+    if (bucket_ptr->size != 0 && first_group_size == 0)                      \
+      first_group_size = UV__FD_HASH_GROUP_SIZE;                             \
+    group_ptr = bucket_ptr->data;                                            \
+    FIND_IN_GROUP_PTR(first_group_size);                                     \
+    for (group_ptr = group_ptr->next;                                        \
+         group_ptr != NULL && entry_ptr == NULL;                             \
+         group_ptr = group_ptr->next)                                        \
+      FIND_IN_GROUP_PTR(UV__FD_HASH_GROUP_SIZE);                             \
+  } while (0)
+
+INLINE static int uv__fd_hash_get(int fd, struct uv__fd_info_s* info) {
+  FIND_COMMON_VARIABLES
+
+  uv_mutex_lock(&uv__fd_hash_mutex);
+
+  FIND_IN_BUCKET_PTR();
+
+  if (entry_ptr != NULL) {
+    *info = entry_ptr->info;
+  }
+
+  uv_mutex_unlock(&uv__fd_hash_mutex);
+  return entry_ptr != NULL;
+}
+
+INLINE static void uv__fd_hash_add(int fd, struct uv__fd_info_s* info) {
+  FIND_COMMON_VARIABLES
+
+  uv_mutex_lock(&uv__fd_hash_mutex);
+
+  FIND_IN_BUCKET_PTR();
+
+  if (entry_ptr == NULL) {
+    i = bucket_ptr->size % UV__FD_HASH_GROUP_SIZE;
+
+    if (bucket_ptr->size != 0 && i == 0) {
+      struct uv__fd_hash_entry_group_s* new_group_ptr =
+        uv__malloc(sizeof(*new_group_ptr));
+      if (new_group_ptr == NULL) {
+        uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc");
+      }
+      new_group_ptr->next = bucket_ptr->data;
+      bucket_ptr->data = new_group_ptr;
+    }
+
+    bucket_ptr->size += 1;
+    entry_ptr = &bucket_ptr->data->entries[i];
+    entry_ptr->fd = fd;
+  }
+
+  entry_ptr->info = *info;
+
+  uv_mutex_unlock(&uv__fd_hash_mutex);
+}
+
+INLINE static int uv__fd_hash_remove(int fd, struct uv__fd_info_s* info) {
+  FIND_COMMON_VARIABLES
+
+  uv_mutex_lock(&uv__fd_hash_mutex);
+
+  FIND_IN_BUCKET_PTR();
+
+  if (entry_ptr != NULL) {
+    *info = entry_ptr->info;
+
+    bucket_ptr->size -= 1;
+
+    i = bucket_ptr->size % UV__FD_HASH_GROUP_SIZE;
+    if (entry_ptr != &bucket_ptr->data->entries[i]) {
+      *entry_ptr = bucket_ptr->data->entries[i];
+    }
+
+    if (bucket_ptr->size != 0 &&
+        bucket_ptr->size % UV__FD_HASH_GROUP_SIZE == 0) {
+      struct uv__fd_hash_entry_group_s* old_group_ptr = bucket_ptr->data;
+      bucket_ptr->data = old_group_ptr->next;
+      uv__free(old_group_ptr);
+    }
+  }
+
+  uv_mutex_unlock(&uv__fd_hash_mutex);
+  return entry_ptr != NULL;
+}
+
+#undef FIND_COMMON_VARIABLES
+#undef FIND_IN_GROUP_PTR
+#undef FIND_IN_BUCKET_PTR
+
+#endif /* UV_WIN_FS_FD_HASH_INL_H_ */
diff --git a/Utilities/cmlibuv/src/win/fs.c b/Utilities/cmlibuv/src/win/fs.c
index 9e2f084..9577bc0 100644
--- a/Utilities/cmlibuv/src/win/fs.c
+++ b/Utilities/cmlibuv/src/win/fs.c
@@ -34,8 +34,7 @@
 #include "internal.h"
 #include "req-inl.h"
 #include "handle-inl.h"
-
-#include <wincrypt.h>
+#include "fs-fd-hash-inl.h"
 
 
 #define UV_FS_FREE_PATHS         0x0002
@@ -126,6 +125,8 @@
 #define IS_LETTER(c) (((c) >= L'a' && (c) <= L'z') || \
   ((c) >= L'A' && (c) <= L'Z'))
 
+#define MIN(a,b) (((a) < (b)) ? (a) : (b))
+
 const WCHAR JUNCTION_PREFIX[] = L"\\??\\";
 const WCHAR JUNCTION_PREFIX_LEN = 4;
 
@@ -137,8 +138,16 @@
 
 static int uv__file_symlink_usermode_flag = SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE;
 
+static DWORD uv__allocation_granularity;
+
+
 void uv_fs_init(void) {
-  _fmode = _O_BINARY;
+  SYSTEM_INFO system_info;
+
+  GetSystemInfo(&system_info);
+  uv__allocation_granularity = system_info.dwAllocationGranularity;
+
+  uv__fd_hash_init();
 }
 
 
@@ -248,6 +257,7 @@
   req->loop = loop;
   req->flags = 0;
   req->fs_type = fs_type;
+  req->sys_errno_ = 0;
   req->result = 0;
   req->ptr = NULL;
   req->path = NULL;
@@ -312,6 +322,8 @@
   WCHAR* w_target;
   DWORD w_target_len;
   DWORD bytes;
+  size_t i;
+  size_t len;
 
   if (!DeviceIoControl(handle,
                        FSCTL_GET_REPARSE_POINT,
@@ -396,6 +408,38 @@
     w_target += 4;
     w_target_len -= 4;
 
+  } else if (reparse_data->ReparseTag == IO_REPARSE_TAG_APPEXECLINK) {
+    /* String #3 in the list has the target filename. */
+    if (reparse_data->AppExecLinkReparseBuffer.StringCount < 3) {
+      SetLastError(ERROR_SYMLINK_NOT_SUPPORTED);
+      return -1;
+    }
+    w_target = reparse_data->AppExecLinkReparseBuffer.StringList;
+    /* The StringList buffer contains a list of strings separated by "\0",   */
+    /* with "\0\0" terminating the list. Move to the 3rd string in the list: */
+    for (i = 0; i < 2; ++i) {
+      len = wcslen(w_target);
+      if (len == 0) {
+        SetLastError(ERROR_SYMLINK_NOT_SUPPORTED);
+        return -1;
+      }
+      w_target += len + 1;
+    }
+    w_target_len = wcslen(w_target);
+    if (w_target_len == 0) {
+      SetLastError(ERROR_SYMLINK_NOT_SUPPORTED);
+      return -1;
+    }
+    /* Make sure it is an absolute path. */
+    if (!(w_target_len >= 3 &&
+         ((w_target[0] >= L'a' && w_target[0] <= L'z') ||
+          (w_target[0] >= L'A' && w_target[0] <= L'Z')) &&
+         w_target[1] == L':' &&
+         w_target[2] == L'\\')) {
+      SetLastError(ERROR_SYMLINK_NOT_SUPPORTED);
+      return -1;
+    }
+
   } else {
     /* Reparse tag does not indicate a symlink. */
     SetLastError(ERROR_SYMLINK_NOT_SUPPORTED);
@@ -414,6 +458,27 @@
   HANDLE file;
   int fd, current_umask;
   int flags = req->fs.info.file_flags;
+  struct uv__fd_info_s fd_info;
+
+  /* Adjust flags to be compatible with the memory file mapping. Save the
+   * original flags to emulate the correct behavior. */
+  if (flags & UV_FS_O_FILEMAP) {
+    fd_info.flags = flags;
+    fd_info.current_pos.QuadPart = 0;
+
+    if ((flags & (UV_FS_O_RDONLY | UV_FS_O_WRONLY | UV_FS_O_RDWR)) ==
+        UV_FS_O_WRONLY) {
+      /* CreateFileMapping always needs read access */
+      flags = (flags & ~UV_FS_O_WRONLY) | UV_FS_O_RDWR;
+    }
+
+    if (flags & UV_FS_O_APPEND) {
+      /* Clear the append flag and ensure RDRW mode */
+      flags &= ~UV_FS_O_APPEND;
+      flags &= ~(UV_FS_O_RDONLY | UV_FS_O_WRONLY | UV_FS_O_RDWR);
+      flags |= UV_FS_O_RDWR;
+    }
+  }
 
   /* Obtain the active umask. umask() never fails and returns the previous
    * umask. */
@@ -444,7 +509,8 @@
    * Here is where we deviate significantly from what CRT's _open()
    * does. We indiscriminately use all the sharing modes, to match
    * UNIX semantics. In particular, this ensures that the file can
-   * be deleted even whilst it's open, fixing issue #1449.
+   * be deleted even whilst it's open, fixing issue
+   * https://github.com/nodejs/node-v0.x-archive/issues/1449.
    * We still support exclusive sharing mode, since it is necessary
    * for opening raw block devices, otherwise Windows will prevent
    * any attempt to write past the master boot record.
@@ -583,11 +649,55 @@
     else if (GetLastError() != ERROR_SUCCESS)
       SET_REQ_WIN32_ERROR(req, GetLastError());
     else
-      SET_REQ_WIN32_ERROR(req, UV_UNKNOWN);
+      SET_REQ_WIN32_ERROR(req, (DWORD) UV_UNKNOWN);
     CloseHandle(file);
     return;
   }
 
+  if (flags & UV_FS_O_FILEMAP) {
+    FILE_STANDARD_INFO file_info;
+    if (!GetFileInformationByHandleEx(file,
+                                      FileStandardInfo,
+                                      &file_info,
+                                      sizeof file_info)) {
+      SET_REQ_WIN32_ERROR(req, GetLastError());
+      CloseHandle(file);
+      return;
+    }
+    fd_info.is_directory = file_info.Directory;
+
+    if (fd_info.is_directory) {
+      fd_info.size.QuadPart = 0;
+      fd_info.mapping = INVALID_HANDLE_VALUE;
+    } else {
+      if (!GetFileSizeEx(file, &fd_info.size)) {
+        SET_REQ_WIN32_ERROR(req, GetLastError());
+        CloseHandle(file);
+        return;
+      }
+
+      if (fd_info.size.QuadPart == 0) {
+        fd_info.mapping = INVALID_HANDLE_VALUE;
+      } else {
+        DWORD flProtect = (fd_info.flags & (UV_FS_O_RDONLY | UV_FS_O_WRONLY |
+          UV_FS_O_RDWR)) == UV_FS_O_RDONLY ? PAGE_READONLY : PAGE_READWRITE;
+        fd_info.mapping = CreateFileMapping(file,
+                                            NULL,
+                                            flProtect,
+                                            fd_info.size.HighPart,
+                                            fd_info.size.LowPart,
+                                            NULL);
+        if (fd_info.mapping == NULL) {
+          SET_REQ_WIN32_ERROR(req, GetLastError());
+          CloseHandle(file);
+          return;
+        }
+      }
+    }
+
+    uv__fd_hash_add(fd, &fd_info);
+  }
+
   SET_REQ_RESULT(req, fd);
   return;
 
@@ -598,9 +708,16 @@
 void fs__close(uv_fs_t* req) {
   int fd = req->file.fd;
   int result;
+  struct uv__fd_info_s fd_info;
 
   VERIFY_FD(fd, req);
 
+  if (uv__fd_hash_remove(fd, &fd_info)) {
+    if (fd_info.mapping != INVALID_HANDLE_VALUE) {
+      CloseHandle(fd_info.mapping);
+    }
+  }
+
   if (fd > 2)
     result = _close(fd);
   else
@@ -618,6 +735,123 @@
 }
 
 
+LONG fs__filemap_ex_filter(LONG excode, PEXCEPTION_POINTERS pep,
+                           int* perror) {
+  if (excode != EXCEPTION_IN_PAGE_ERROR) {
+    return EXCEPTION_CONTINUE_SEARCH;
+  }
+
+  assert(perror != NULL);
+  if (pep != NULL && pep->ExceptionRecord != NULL &&
+      pep->ExceptionRecord->NumberParameters >= 3) {
+    NTSTATUS status = (NTSTATUS)pep->ExceptionRecord->ExceptionInformation[3];
+    *perror = pRtlNtStatusToDosError(status);
+    if (*perror != ERROR_SUCCESS) {
+      return EXCEPTION_EXECUTE_HANDLER;
+    }
+  }
+  *perror = UV_UNKNOWN;
+  return EXCEPTION_EXECUTE_HANDLER;
+}
+
+
+void fs__read_filemap(uv_fs_t* req, struct uv__fd_info_s* fd_info) {
+  int fd = req->file.fd; /* VERIFY_FD done in fs__read */
+  int rw_flags = fd_info->flags &
+    (UV_FS_O_RDONLY | UV_FS_O_WRONLY | UV_FS_O_RDWR);
+  size_t read_size, done_read;
+  unsigned int index;
+  LARGE_INTEGER pos, end_pos;
+  size_t view_offset;
+  LARGE_INTEGER view_base;
+  void* view;
+
+  if (rw_flags == UV_FS_O_WRONLY) {
+    SET_REQ_WIN32_ERROR(req, ERROR_ACCESS_DENIED);
+    return;
+  }
+  if (fd_info->is_directory) {
+    SET_REQ_WIN32_ERROR(req, ERROR_INVALID_FUNCTION);
+    return;
+  }
+
+  if (req->fs.info.offset == -1) {
+    pos = fd_info->current_pos;
+  } else {
+    pos.QuadPart = req->fs.info.offset;
+  }
+
+  /* Make sure we wont read past EOF. */
+  if (pos.QuadPart >= fd_info->size.QuadPart) {
+    SET_REQ_RESULT(req, 0);
+    return;
+  }
+
+  read_size = 0;
+  for (index = 0; index < req->fs.info.nbufs; ++index) {
+    read_size += req->fs.info.bufs[index].len;
+  }
+  read_size = (size_t) MIN((LONGLONG) read_size,
+                           fd_info->size.QuadPart - pos.QuadPart);
+  if (read_size == 0) {
+    SET_REQ_RESULT(req, 0);
+    return;
+  }
+
+  end_pos.QuadPart = pos.QuadPart + read_size;
+
+  view_offset = pos.QuadPart % uv__allocation_granularity;
+  view_base.QuadPart = pos.QuadPart - view_offset;
+  view = MapViewOfFile(fd_info->mapping,
+                       FILE_MAP_READ,
+                       view_base.HighPart,
+                       view_base.LowPart,
+                       view_offset + read_size);
+  if (view == NULL) {
+    SET_REQ_WIN32_ERROR(req, GetLastError());
+    return;
+  }
+
+  done_read = 0;
+  for (index = 0;
+       index < req->fs.info.nbufs && done_read < read_size;
+       ++index) {
+    int err = 0;
+    size_t this_read_size = MIN(req->fs.info.bufs[index].len,
+                                read_size - done_read);
+#ifdef _MSC_VER
+    __try {
+#endif
+      memcpy(req->fs.info.bufs[index].base,
+             (char*)view + view_offset + done_read,
+             this_read_size);
+#ifdef _MSC_VER
+    }
+    __except (fs__filemap_ex_filter(GetExceptionCode(),
+                                    GetExceptionInformation(), &err)) {
+      SET_REQ_WIN32_ERROR(req, err);
+      UnmapViewOfFile(view);
+      return;
+    }
+#endif
+    done_read += this_read_size;
+  }
+  assert(done_read == read_size);
+
+  if (!UnmapViewOfFile(view)) {
+    SET_REQ_WIN32_ERROR(req, GetLastError());
+    return;
+  }
+
+  if (req->fs.info.offset == -1) {
+    fd_info->current_pos = end_pos;
+    uv__fd_hash_add(fd, fd_info);
+  }
+
+  SET_REQ_RESULT(req, read_size);
+  return;
+}
+
 void fs__read(uv_fs_t* req) {
   int fd = req->file.fd;
   int64_t offset = req->fs.info.offset;
@@ -631,9 +865,15 @@
   LARGE_INTEGER original_position;
   LARGE_INTEGER zero_offset;
   int restore_position;
+  struct uv__fd_info_s fd_info;
 
   VERIFY_FD(fd, req);
 
+  if (uv__fd_hash_get(fd, &fd_info)) {
+    fs__read_filemap(req, &fd_info);
+    return;
+  }
+
   zero_offset.QuadPart = 0;
   restore_position = 0;
   handle = uv__get_osfhandle(fd);
@@ -690,6 +930,131 @@
 }
 
 
+void fs__write_filemap(uv_fs_t* req, HANDLE file,
+                       struct uv__fd_info_s* fd_info) {
+  int fd = req->file.fd; /* VERIFY_FD done in fs__write */
+  int force_append = fd_info->flags & UV_FS_O_APPEND;
+  int rw_flags = fd_info->flags &
+    (UV_FS_O_RDONLY | UV_FS_O_WRONLY | UV_FS_O_RDWR);
+  size_t write_size, done_write;
+  unsigned int index;
+  LARGE_INTEGER zero, pos, end_pos;
+  size_t view_offset;
+  LARGE_INTEGER view_base;
+  void* view;
+  FILETIME ft;
+
+  if (rw_flags == UV_FS_O_RDONLY) {
+    SET_REQ_WIN32_ERROR(req, ERROR_ACCESS_DENIED);
+    return;
+  }
+  if (fd_info->is_directory) {
+    SET_REQ_WIN32_ERROR(req, ERROR_INVALID_FUNCTION);
+    return;
+  }
+
+  write_size = 0;
+  for (index = 0; index < req->fs.info.nbufs; ++index) {
+    write_size += req->fs.info.bufs[index].len;
+  }
+
+  if (write_size == 0) {
+    SET_REQ_RESULT(req, 0);
+    return;
+  }
+
+  zero.QuadPart = 0;
+  if (force_append) {
+    pos = fd_info->size;
+  } else if (req->fs.info.offset == -1) {
+    pos = fd_info->current_pos;
+  } else {
+    pos.QuadPart = req->fs.info.offset;
+  }
+
+  end_pos.QuadPart = pos.QuadPart + write_size;
+
+  /* Recreate the mapping to enlarge the file if needed */
+  if (end_pos.QuadPart > fd_info->size.QuadPart) {
+    if (fd_info->mapping != INVALID_HANDLE_VALUE) {
+      CloseHandle(fd_info->mapping);
+    }
+
+    fd_info->mapping = CreateFileMapping(file,
+                                         NULL,
+                                         PAGE_READWRITE,
+                                         end_pos.HighPart,
+                                         end_pos.LowPart,
+                                         NULL);
+    if (fd_info->mapping == NULL) {
+      SET_REQ_WIN32_ERROR(req, GetLastError());
+      CloseHandle(file);
+      fd_info->mapping = INVALID_HANDLE_VALUE;
+      fd_info->size.QuadPart = 0;
+      fd_info->current_pos.QuadPart = 0;
+      uv__fd_hash_add(fd, fd_info);
+      return;
+    }
+
+    fd_info->size = end_pos;
+    uv__fd_hash_add(fd, fd_info);
+  }
+
+  view_offset = pos.QuadPart % uv__allocation_granularity;
+  view_base.QuadPart = pos.QuadPart - view_offset;
+  view = MapViewOfFile(fd_info->mapping,
+                       FILE_MAP_WRITE,
+                       view_base.HighPart,
+                       view_base.LowPart,
+                       view_offset + write_size);
+  if (view == NULL) {
+    SET_REQ_WIN32_ERROR(req, GetLastError());
+    return;
+  }
+
+  done_write = 0;
+  for (index = 0; index < req->fs.info.nbufs; ++index) {
+    int err = 0;
+#ifdef _MSC_VER
+    __try {
+#endif
+      memcpy((char*)view + view_offset + done_write,
+             req->fs.info.bufs[index].base,
+             req->fs.info.bufs[index].len);
+#ifdef _MSC_VER
+    }
+    __except (fs__filemap_ex_filter(GetExceptionCode(),
+                                    GetExceptionInformation(), &err)) {
+      SET_REQ_WIN32_ERROR(req, err);
+      UnmapViewOfFile(view);
+      return;
+    }
+#endif
+    done_write += req->fs.info.bufs[index].len;
+  }
+  assert(done_write == write_size);
+
+  if (!FlushViewOfFile(view, 0)) {
+    SET_REQ_WIN32_ERROR(req, GetLastError());
+    UnmapViewOfFile(view);
+    return;
+  }
+  if (!UnmapViewOfFile(view)) {
+    SET_REQ_WIN32_ERROR(req, GetLastError());
+    return;
+  }
+
+  if (req->fs.info.offset == -1) {
+    fd_info->current_pos = end_pos;
+    uv__fd_hash_add(fd, fd_info);
+  }
+
+  GetSystemTimeAsFileTime(&ft);
+  SetFileTime(file, NULL, NULL, &ft);
+
+  SET_REQ_RESULT(req, done_write);
+}
+
 void fs__write(uv_fs_t* req) {
   int fd = req->file.fd;
   int64_t offset = req->fs.info.offset;
@@ -702,6 +1067,7 @@
   LARGE_INTEGER original_position;
   LARGE_INTEGER zero_offset;
   int restore_position;
+  struct uv__fd_info_s fd_info;
 
   VERIFY_FD(fd, req);
 
@@ -713,6 +1079,11 @@
     return;
   }
 
+  if (uv__fd_hash_get(fd, &fd_info)) {
+    fs__write_filemap(req, handle, &fd_info);
+    return;
+  }
+
   if (offset != -1) {
     memset(&overlapped, 0, sizeof overlapped);
     overlapped_ptr = &overlapped;
@@ -850,13 +1221,19 @@
 
 void fs__mkdir(uv_fs_t* req) {
   /* TODO: use req->mode. */
-  int result = _wmkdir(req->file.pathw);
-  SET_REQ_RESULT(req, result);
+  req->result = _wmkdir(req->file.pathw);
+  if (req->result == -1) {
+    req->sys_errno_ = _doserrno;
+    req->result = req->sys_errno_ == ERROR_INVALID_NAME
+                ? UV_EINVAL
+                : uv_translate_sys_error(req->sys_errno_);
+  }
 }
 
+typedef int (*uv__fs_mktemp_func)(uv_fs_t* req);
 
 /* OpenBSD original: lib/libc/stdio/mktemp.c */
-void fs__mkdtemp(uv_fs_t* req) {
+void fs__mktemp(uv_fs_t* req, uv__fs_mktemp_func func) {
   static const WCHAR *tempchars =
     L"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
   static const size_t num_chars = 62;
@@ -864,9 +1241,7 @@
   WCHAR *cp, *ep;
   unsigned int tries, i;
   size_t len;
-  HCRYPTPROV h_crypt_prov;
   uint64_t v;
-  BOOL released;
 
   len = wcslen(req->file.pathw);
   ep = req->file.pathw + len;
@@ -875,16 +1250,10 @@
     return;
   }
 
-  if (!CryptAcquireContext(&h_crypt_prov, NULL, NULL, PROV_RSA_FULL,
-                           CRYPT_VERIFYCONTEXT)) {
-    SET_REQ_WIN32_ERROR(req, GetLastError());
-    return;
-  }
-
   tries = TMP_MAX;
   do {
-    if (!CryptGenRandom(h_crypt_prov, sizeof(v), (BYTE*) &v)) {
-      SET_REQ_WIN32_ERROR(req, GetLastError());
+    if (uv__random_rtlgenrandom((void *)&v, sizeof(v)) < 0) {
+      SET_REQ_UV_ERROR(req, UV_EIO, ERROR_IO_DEVICE);
       break;
     }
 
@@ -894,25 +1263,92 @@
       v /= num_chars;
     }
 
-    if (_wmkdir(req->file.pathw) == 0) {
-      len = strlen(req->path);
-      wcstombs((char*) req->path + len - num_x, ep - num_x, num_x);
-      SET_REQ_RESULT(req, 0);
-      break;
-    } else if (errno != EEXIST) {
-      SET_REQ_RESULT(req, -1);
+    if (func(req)) {
+      if (req->result >= 0) {
+        len = strlen(req->path);
+        wcstombs((char*) req->path + len - num_x, ep - num_x, num_x);
+      }
       break;
     }
   } while (--tries);
 
-  released = CryptReleaseContext(h_crypt_prov, 0);
-  assert(released);
   if (tries == 0) {
     SET_REQ_RESULT(req, -1);
   }
 }
 
 
+static int fs__mkdtemp_func(uv_fs_t* req) {
+  if (_wmkdir(req->file.pathw) == 0) {
+    SET_REQ_RESULT(req, 0);
+    return 1;
+  } else if (errno != EEXIST) {
+    SET_REQ_RESULT(req, -1);
+    return 1;
+  }
+
+  return 0;
+}
+
+
+void fs__mkdtemp(uv_fs_t* req) {
+  fs__mktemp(req, fs__mkdtemp_func);
+}
+
+
+static int fs__mkstemp_func(uv_fs_t* req) {
+  HANDLE file;
+  int fd;
+
+  file = CreateFileW(req->file.pathw,
+                     GENERIC_READ | GENERIC_WRITE,
+                     FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
+                     NULL,
+                     CREATE_NEW,
+                     FILE_ATTRIBUTE_NORMAL,
+                     NULL);
+
+  if (file == INVALID_HANDLE_VALUE) {
+    DWORD error;
+    error = GetLastError();
+
+    /* If the file exists, the main fs__mktemp() function
+       will retry. If it's another error, we want to stop. */
+    if (error != ERROR_FILE_EXISTS) {
+      SET_REQ_WIN32_ERROR(req, error);
+      return 1;
+    }
+
+    return 0;
+  }
+
+  fd = _open_osfhandle((intptr_t) file, 0);
+  if (fd < 0) {
+    /* The only known failure mode for _open_osfhandle() is EMFILE, in which
+     * case GetLastError() will return zero. However we'll try to handle other
+     * errors as well, should they ever occur.
+     */
+    if (errno == EMFILE)
+      SET_REQ_UV_ERROR(req, UV_EMFILE, ERROR_TOO_MANY_OPEN_FILES);
+    else if (GetLastError() != ERROR_SUCCESS)
+      SET_REQ_WIN32_ERROR(req, GetLastError());
+    else
+      SET_REQ_WIN32_ERROR(req, UV_UNKNOWN);
+    CloseHandle(file);
+    return 1;
+  }
+
+  SET_REQ_RESULT(req, fd);
+
+  return 1;
+}
+
+
+void fs__mkstemp(uv_fs_t* req) {
+  fs__mktemp(req, fs__mkstemp_func);
+}
+
+
 void fs__scandir(uv_fs_t* req) {
   static const size_t dirents_initial_size = 32;
 
@@ -1409,47 +1845,57 @@
 }
 
 
-INLINE static void fs__stat_impl(uv_fs_t* req, int do_lstat) {
+INLINE static DWORD fs__stat_impl_from_path(WCHAR* path,
+                                            int do_lstat,
+                                            uv_stat_t* statbuf) {
   HANDLE handle;
   DWORD flags;
+  DWORD ret;
 
   flags = FILE_FLAG_BACKUP_SEMANTICS;
-  if (do_lstat) {
+  if (do_lstat)
     flags |= FILE_FLAG_OPEN_REPARSE_POINT;
-  }
 
-  handle = CreateFileW(req->file.pathw,
+  handle = CreateFileW(path,
                        FILE_READ_ATTRIBUTES,
                        FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
                        NULL,
                        OPEN_EXISTING,
                        flags,
                        NULL);
-  if (handle == INVALID_HANDLE_VALUE) {
-    SET_REQ_WIN32_ERROR(req, GetLastError());
-    return;
-  }
 
-  if (fs__stat_handle(handle, &req->statbuf, do_lstat) != 0) {
-    DWORD error = GetLastError();
+  if (handle == INVALID_HANDLE_VALUE)
+    ret = GetLastError();
+  else if (fs__stat_handle(handle, statbuf, do_lstat) != 0)
+    ret = GetLastError();
+  else
+    ret = 0;
+
+  CloseHandle(handle);
+  return ret;
+}
+
+
+INLINE static void fs__stat_impl(uv_fs_t* req, int do_lstat) {
+  DWORD error;
+
+  error = fs__stat_impl_from_path(req->file.pathw, do_lstat, &req->statbuf);
+  if (error != 0) {
     if (do_lstat &&
         (error == ERROR_SYMLINK_NOT_SUPPORTED ||
          error == ERROR_NOT_A_REPARSE_POINT)) {
       /* We opened a reparse point but it was not a symlink. Try again. */
       fs__stat_impl(req, 0);
-
     } else {
       /* Stat failed. */
-      SET_REQ_WIN32_ERROR(req, GetLastError());
+      SET_REQ_WIN32_ERROR(req, error);
     }
 
-    CloseHandle(handle);
     return;
   }
 
   req->ptr = &req->statbuf;
   req->result = 0;
-  CloseHandle(handle);
 }
 
 
@@ -1526,6 +1972,7 @@
 static void fs__ftruncate(uv_fs_t* req) {
   int fd = req->file.fd;
   HANDLE handle;
+  struct uv__fd_info_s fd_info = { 0 };
   NTSTATUS status;
   IO_STATUS_BLOCK io_status;
   FILE_END_OF_FILE_INFORMATION eof_info;
@@ -1534,6 +1981,17 @@
 
   handle = uv__get_osfhandle(fd);
 
+  if (uv__fd_hash_get(fd, &fd_info)) {
+    if (fd_info.is_directory) {
+      SET_REQ_WIN32_ERROR(req, ERROR_ACCESS_DENIED);
+      return;
+    }
+
+    if (fd_info.mapping != INVALID_HANDLE_VALUE) {
+      CloseHandle(fd_info.mapping);
+    }
+  }
+
   eof_info.EndOfFile.QuadPart = req->fs.info.offset;
 
   status = pNtSetInformationFile(handle,
@@ -1546,6 +2004,43 @@
     SET_REQ_RESULT(req, 0);
   } else {
     SET_REQ_WIN32_ERROR(req, pRtlNtStatusToDosError(status));
+
+    if (fd_info.flags) {
+      CloseHandle(handle);
+      fd_info.mapping = INVALID_HANDLE_VALUE;
+      fd_info.size.QuadPart = 0;
+      fd_info.current_pos.QuadPart = 0;
+      uv__fd_hash_add(fd, &fd_info);
+      return;
+    }
+  }
+
+  if (fd_info.flags) {
+    fd_info.size = eof_info.EndOfFile;
+
+    if (fd_info.size.QuadPart == 0) {
+      fd_info.mapping = INVALID_HANDLE_VALUE;
+    } else {
+      DWORD flProtect = (fd_info.flags & (UV_FS_O_RDONLY | UV_FS_O_WRONLY |
+        UV_FS_O_RDWR)) == UV_FS_O_RDONLY ? PAGE_READONLY : PAGE_READWRITE;
+      fd_info.mapping = CreateFileMapping(handle,
+                                          NULL,
+                                          flProtect,
+                                          fd_info.size.HighPart,
+                                          fd_info.size.LowPart,
+                                          NULL);
+      if (fd_info.mapping == NULL) {
+        SET_REQ_WIN32_ERROR(req, GetLastError());
+        CloseHandle(handle);
+        fd_info.mapping = INVALID_HANDLE_VALUE;
+        fd_info.size.QuadPart = 0;
+        fd_info.current_pos.QuadPart = 0;
+        uv__fd_hash_add(fd, &fd_info);
+        return;
+      }
+    }
+
+    uv__fd_hash_add(fd, &fd_info);
   }
 }
 
@@ -1553,6 +2048,8 @@
 static void fs__copyfile(uv_fs_t* req) {
   int flags;
   int overwrite;
+  uv_stat_t statbuf;
+  uv_stat_t new_statbuf;
 
   flags = req->fs.info.file_flags;
 
@@ -1563,12 +2060,25 @@
 
   overwrite = flags & UV_FS_COPYFILE_EXCL;
 
-  if (CopyFileW(req->file.pathw, req->fs.info.new_pathw, overwrite) == 0) {
-    SET_REQ_WIN32_ERROR(req, GetLastError());
+  if (CopyFileW(req->file.pathw, req->fs.info.new_pathw, overwrite) != 0) {
+    SET_REQ_RESULT(req, 0);
     return;
   }
 
-  SET_REQ_RESULT(req, 0);
+  SET_REQ_WIN32_ERROR(req, GetLastError());
+  if (req->result != UV_EBUSY)
+    return;
+
+  /* if error UV_EBUSY check if src and dst file are the same */
+  if (fs__stat_impl_from_path(req->file.pathw, 0, &statbuf) != 0 ||
+      fs__stat_impl_from_path(req->fs.info.new_pathw, 0, &new_statbuf) != 0) {
+    return;
+  }
+
+  if (statbuf.st_dev == new_statbuf.st_dev &&
+      statbuf.st_ino == new_statbuf.st_ino) {
+    SET_REQ_RESULT(req, 0);
+  }
 }
 
 
@@ -1750,34 +2260,68 @@
   return 0;
 }
 
-
-static void fs__utime(uv_fs_t* req) {
+INLINE static DWORD fs__utime_impl_from_path(WCHAR* path,
+                                             double atime,
+                                             double mtime,
+                                             int do_lutime) {
   HANDLE handle;
+  DWORD flags;
+  DWORD ret;
 
-  handle = CreateFileW(req->file.pathw,
+  flags = FILE_FLAG_BACKUP_SEMANTICS;
+  if (do_lutime) {
+    flags |= FILE_FLAG_OPEN_REPARSE_POINT;
+  }
+
+  handle = CreateFileW(path,
                        FILE_WRITE_ATTRIBUTES,
                        FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
                        NULL,
                        OPEN_EXISTING,
-                       FILE_FLAG_BACKUP_SEMANTICS,
+                       flags,
                        NULL);
 
   if (handle == INVALID_HANDLE_VALUE) {
-    SET_REQ_WIN32_ERROR(req, GetLastError());
-    return;
-  }
-
-  if (fs__utime_handle(handle, req->fs.time.atime, req->fs.time.mtime) != 0) {
-    SET_REQ_WIN32_ERROR(req, GetLastError());
-    CloseHandle(handle);
-    return;
+    ret = GetLastError();
+  } else if (fs__utime_handle(handle, atime, mtime) != 0) {
+    ret = GetLastError();
+  } else {
+    ret = 0;
   }
 
   CloseHandle(handle);
+  return ret;
+}
+
+INLINE static void fs__utime_impl(uv_fs_t* req, int do_lutime) {
+  DWORD error;
+
+  error = fs__utime_impl_from_path(req->file.pathw,
+                                   req->fs.time.atime,
+                                   req->fs.time.mtime,
+                                   do_lutime);
+
+  if (error != 0) {
+    if (do_lutime &&
+        (error == ERROR_SYMLINK_NOT_SUPPORTED ||
+         error == ERROR_NOT_A_REPARSE_POINT)) {
+      /* Opened file is a reparse point but not a symlink. Try again. */
+      fs__utime_impl(req, 0);
+    } else {
+      /* utime failed. */
+      SET_REQ_WIN32_ERROR(req, error);
+    }
+
+    return;
+  }
 
   req->result = 0;
 }
 
+static void fs__utime(uv_fs_t* req) {
+  fs__utime_impl(req, /* do_lutime */ 0);
+}
+
 
 static void fs__futime(uv_fs_t* req) {
   int fd = req->file.fd;
@@ -1799,6 +2343,10 @@
   req->result = 0;
 }
 
+static void fs__lutime(uv_fs_t* req) {
+  fs__utime_impl(req, /* do_lutime */ 1);
+}
+
 
 static void fs__link(uv_fs_t* req) {
   DWORD r = CreateHardLinkW(req->fs.info.new_pathw, req->file.pathw, NULL);
@@ -2139,6 +2687,90 @@
   req->result = 0;
 }
 
+
+static void fs__statfs(uv_fs_t* req) {
+  uv_statfs_t* stat_fs;
+  DWORD sectors_per_cluster;
+  DWORD bytes_per_sector;
+  DWORD free_clusters;
+  DWORD total_clusters;
+  WCHAR* pathw;
+
+  pathw = req->file.pathw;
+retry_get_disk_free_space:
+  if (0 == GetDiskFreeSpaceW(pathw,
+                             &sectors_per_cluster,
+                             &bytes_per_sector,
+                             &free_clusters,
+                             &total_clusters)) {
+    DWORD err;
+    WCHAR* fpart;
+    size_t len;
+    DWORD ret;
+    BOOL is_second;
+
+    err = GetLastError();
+    is_second = pathw != req->file.pathw;
+    if (err != ERROR_DIRECTORY || is_second) {
+      if (is_second)
+        uv__free(pathw);
+
+      SET_REQ_WIN32_ERROR(req, err);
+      return;
+    }
+
+    len = MAX_PATH + 1;
+    pathw = uv__malloc(len * sizeof(*pathw));
+    if (pathw == NULL) {
+      SET_REQ_UV_ERROR(req, UV_ENOMEM, ERROR_OUTOFMEMORY);
+      return;
+    }
+retry_get_full_path_name:
+    ret = GetFullPathNameW(req->file.pathw,
+                           len,
+                           pathw,
+                           &fpart);
+    if (ret == 0) {
+      uv__free(pathw);
+      SET_REQ_WIN32_ERROR(req, err);
+      return;
+    } else if (ret > len) {
+      len = ret;
+      pathw = uv__reallocf(pathw, len * sizeof(*pathw));
+      if (pathw == NULL) {
+        SET_REQ_UV_ERROR(req, UV_ENOMEM, ERROR_OUTOFMEMORY);
+        return;
+      }
+      goto retry_get_full_path_name;
+    }
+    if (fpart != 0)
+      *fpart = L'\0';
+
+    goto retry_get_disk_free_space;
+  }
+  if (pathw != req->file.pathw) {
+    uv__free(pathw);
+  }
+
+  stat_fs = uv__malloc(sizeof(*stat_fs));
+  if (stat_fs == NULL) {
+    SET_REQ_UV_ERROR(req, UV_ENOMEM, ERROR_OUTOFMEMORY);
+    return;
+  }
+
+  stat_fs->f_type = 0;
+  stat_fs->f_bsize = bytes_per_sector * sectors_per_cluster;
+  stat_fs->f_blocks = total_clusters;
+  stat_fs->f_bfree = free_clusters;
+  stat_fs->f_bavail = free_clusters;
+  stat_fs->f_files = 0;
+  stat_fs->f_ffree = 0;
+  req->ptr = stat_fs;
+  req->flags |= UV_FS_FREE_PTR;
+  SET_REQ_RESULT(req, 0);
+}
+
+
 static void uv__fs_work(struct uv__work* w) {
   uv_fs_t* req;
 
@@ -2159,6 +2791,7 @@
     XX(FTRUNCATE, ftruncate)
     XX(UTIME, utime)
     XX(FUTIME, futime)
+    XX(LUTIME, lutime)
     XX(ACCESS, access)
     XX(CHMOD, chmod)
     XX(FCHMOD, fchmod)
@@ -2168,6 +2801,7 @@
     XX(RMDIR, rmdir)
     XX(MKDIR, mkdir)
     XX(MKDTEMP, mkdtemp)
+    XX(MKSTEMP, mkstemp)
     XX(RENAME, rename)
     XX(SCANDIR, scandir)
     XX(READDIR, readdir)
@@ -2178,8 +2812,9 @@
     XX(READLINK, readlink)
     XX(REALPATH, realpath)
     XX(CHOWN, chown)
-    XX(FCHOWN, fchown);
-    XX(LCHOWN, lchown);
+    XX(FCHOWN, fchown)
+    XX(LCHOWN, lchown)
+    XX(STATFS, statfs)
     default:
       assert(!"bad uv_fs_type");
   }
@@ -2240,7 +2875,8 @@
   INIT(UV_FS_OPEN);
   err = fs__capture_path(req, path, NULL, cb != NULL);
   if (err) {
-    return uv_translate_sys_error(err);
+    SET_REQ_WIN32_ERROR(req, err);
+    return req->result;
   }
 
   req->fs.info.file_flags = flags;
@@ -2265,8 +2901,10 @@
                uv_fs_cb cb) {
   INIT(UV_FS_READ);
 
-  if (bufs == NULL || nbufs == 0)
+  if (bufs == NULL || nbufs == 0) {
+    SET_REQ_UV_ERROR(req, UV_EINVAL, ERROR_INVALID_PARAMETER);
     return UV_EINVAL;
+  }
 
   req->file.fd = fd;
 
@@ -2275,8 +2913,10 @@
   if (nbufs > ARRAY_SIZE(req->fs.info.bufsml))
     req->fs.info.bufs = uv__malloc(nbufs * sizeof(*bufs));
 
-  if (req->fs.info.bufs == NULL)
+  if (req->fs.info.bufs == NULL) {
+    SET_REQ_UV_ERROR(req, UV_ENOMEM, ERROR_OUTOFMEMORY);
     return UV_ENOMEM;
+  }
 
   memcpy(req->fs.info.bufs, bufs, nbufs * sizeof(*bufs));
 
@@ -2294,8 +2934,10 @@
                 uv_fs_cb cb) {
   INIT(UV_FS_WRITE);
 
-  if (bufs == NULL || nbufs == 0)
+  if (bufs == NULL || nbufs == 0) {
+    SET_REQ_UV_ERROR(req, UV_EINVAL, ERROR_INVALID_PARAMETER);
     return UV_EINVAL;
+  }
 
   req->file.fd = fd;
 
@@ -2304,8 +2946,10 @@
   if (nbufs > ARRAY_SIZE(req->fs.info.bufsml))
     req->fs.info.bufs = uv__malloc(nbufs * sizeof(*bufs));
 
-  if (req->fs.info.bufs == NULL)
+  if (req->fs.info.bufs == NULL) {
+    SET_REQ_UV_ERROR(req, UV_ENOMEM, ERROR_OUTOFMEMORY);
     return UV_ENOMEM;
+  }
 
   memcpy(req->fs.info.bufs, bufs, nbufs * sizeof(*bufs));
 
@@ -2321,7 +2965,8 @@
   INIT(UV_FS_UNLINK);
   err = fs__capture_path(req, path, NULL, cb != NULL);
   if (err) {
-    return uv_translate_sys_error(err);
+    SET_REQ_WIN32_ERROR(req, err);
+    return req->result;
   }
 
   POST;
@@ -2335,7 +2980,8 @@
   INIT(UV_FS_MKDIR);
   err = fs__capture_path(req, path, NULL, cb != NULL);
   if (err) {
-    return uv_translate_sys_error(err);
+    SET_REQ_WIN32_ERROR(req, err);
+    return req->result;
   }
 
   req->fs.info.mode = mode;
@@ -2343,14 +2989,35 @@
 }
 
 
-int uv_fs_mkdtemp(uv_loop_t* loop, uv_fs_t* req, const char* tpl,
-    uv_fs_cb cb) {
+int uv_fs_mkdtemp(uv_loop_t* loop,
+                  uv_fs_t* req,
+                  const char* tpl,
+                  uv_fs_cb cb) {
   int err;
 
   INIT(UV_FS_MKDTEMP);
   err = fs__capture_path(req, tpl, NULL, TRUE);
-  if (err)
-    return uv_translate_sys_error(err);
+  if (err) {
+    SET_REQ_WIN32_ERROR(req, err);
+    return req->result;
+  }
+
+  POST;
+}
+
+
+int uv_fs_mkstemp(uv_loop_t* loop,
+                  uv_fs_t* req,
+                  const char* tpl,
+                  uv_fs_cb cb) {
+  int err;
+
+  INIT(UV_FS_MKSTEMP);
+  err = fs__capture_path(req, tpl, NULL, TRUE);
+  if (err) {
+    SET_REQ_WIN32_ERROR(req, err);
+    return req->result;
+  }
 
   POST;
 }
@@ -2362,7 +3029,8 @@
   INIT(UV_FS_RMDIR);
   err = fs__capture_path(req, path, NULL, cb != NULL);
   if (err) {
-    return uv_translate_sys_error(err);
+    SET_REQ_WIN32_ERROR(req, err);
+    return req->result;
   }
 
   POST;
@@ -2376,7 +3044,8 @@
   INIT(UV_FS_SCANDIR);
   err = fs__capture_path(req, path, NULL, cb != NULL);
   if (err) {
-    return uv_translate_sys_error(err);
+    SET_REQ_WIN32_ERROR(req, err);
+    return req->result;
   }
 
   req->fs.info.file_flags = flags;
@@ -2391,8 +3060,10 @@
 
   INIT(UV_FS_OPENDIR);
   err = fs__capture_path(req, path, NULL, cb != NULL);
-  if (err)
-    return uv_translate_sys_error(err);
+  if (err) {
+    SET_REQ_WIN32_ERROR(req, err);
+    return req->result;
+  }
   POST;
 }
 
@@ -2405,6 +3076,7 @@
   if (dir == NULL ||
       dir->dirents == NULL ||
       dir->dir_handle == INVALID_HANDLE_VALUE) {
+    SET_REQ_UV_ERROR(req, UV_EINVAL, ERROR_INVALID_PARAMETER);
     return UV_EINVAL;
   }
 
@@ -2417,8 +3089,10 @@
                    uv_dir_t* dir,
                    uv_fs_cb cb) {
   INIT(UV_FS_CLOSEDIR);
-  if (dir == NULL)
+  if (dir == NULL) {
+    SET_REQ_UV_ERROR(req, UV_EINVAL, ERROR_INVALID_PARAMETER);
     return UV_EINVAL;
+  }
   req->ptr = dir;
   POST;
 }
@@ -2430,7 +3104,8 @@
   INIT(UV_FS_LINK);
   err = fs__capture_path(req, path, new_path, cb != NULL);
   if (err) {
-    return uv_translate_sys_error(err);
+    SET_REQ_WIN32_ERROR(req, err);
+    return req->result;
   }
 
   POST;
@@ -2444,7 +3119,8 @@
   INIT(UV_FS_SYMLINK);
   err = fs__capture_path(req, path, new_path, cb != NULL);
   if (err) {
-    return uv_translate_sys_error(err);
+    SET_REQ_WIN32_ERROR(req, err);
+    return req->result;
   }
 
   req->fs.info.file_flags = flags;
@@ -2459,7 +3135,8 @@
   INIT(UV_FS_READLINK);
   err = fs__capture_path(req, path, NULL, cb != NULL);
   if (err) {
-    return uv_translate_sys_error(err);
+    SET_REQ_WIN32_ERROR(req, err);
+    return req->result;
   }
 
   POST;
@@ -2473,12 +3150,14 @@
   INIT(UV_FS_REALPATH);
 
   if (!path) {
+    SET_REQ_UV_ERROR(req, UV_EINVAL, ERROR_INVALID_PARAMETER);
     return UV_EINVAL;
   }
 
   err = fs__capture_path(req, path, NULL, cb != NULL);
   if (err) {
-    return uv_translate_sys_error(err);
+    SET_REQ_WIN32_ERROR(req, err);
+    return req->result;
   }
 
   POST;
@@ -2492,7 +3171,8 @@
   INIT(UV_FS_CHOWN);
   err = fs__capture_path(req, path, NULL, cb != NULL);
   if (err) {
-    return uv_translate_sys_error(err);
+    SET_REQ_WIN32_ERROR(req, err);
+    return req->result;
   }
 
   POST;
@@ -2513,8 +3193,10 @@
   INIT(UV_FS_LCHOWN);
   err = fs__capture_path(req, path, NULL, cb != NULL);
   if (err) {
-    return uv_translate_sys_error(err);
+    SET_REQ_WIN32_ERROR(req, err);
+    return req->result;
   }
+
   POST;
 }
 
@@ -2525,7 +3207,8 @@
   INIT(UV_FS_STAT);
   err = fs__capture_path(req, path, NULL, cb != NULL);
   if (err) {
-    return uv_translate_sys_error(err);
+    SET_REQ_WIN32_ERROR(req, err);
+    return req->result;
   }
 
   POST;
@@ -2538,7 +3221,8 @@
   INIT(UV_FS_LSTAT);
   err = fs__capture_path(req, path, NULL, cb != NULL);
   if (err) {
-    return uv_translate_sys_error(err);
+    SET_REQ_WIN32_ERROR(req, err);
+    return req->result;
   }
 
   POST;
@@ -2559,7 +3243,8 @@
   INIT(UV_FS_RENAME);
   err = fs__capture_path(req, path, new_path, cb != NULL);
   if (err) {
-    return uv_translate_sys_error(err);
+    SET_REQ_WIN32_ERROR(req, err);
+    return req->result;
   }
 
   POST;
@@ -2602,13 +3287,15 @@
   if (flags & ~(UV_FS_COPYFILE_EXCL |
                 UV_FS_COPYFILE_FICLONE |
                 UV_FS_COPYFILE_FICLONE_FORCE)) {
+    SET_REQ_UV_ERROR(req, UV_EINVAL, ERROR_INVALID_PARAMETER);
     return UV_EINVAL;
   }
 
   err = fs__capture_path(req, path, new_path, cb != NULL);
-
-  if (err)
-    return uv_translate_sys_error(err);
+  if (err) {
+    SET_REQ_WIN32_ERROR(req, err);
+    return req->result;
+  }
 
   req->fs.info.file_flags = flags;
   POST;
@@ -2635,8 +3322,10 @@
 
   INIT(UV_FS_ACCESS);
   err = fs__capture_path(req, path, NULL, cb != NULL);
-  if (err)
-    return uv_translate_sys_error(err);
+  if (err) {
+    SET_REQ_WIN32_ERROR(req, err);
+    return req->result;
+  }
 
   req->fs.info.mode = flags;
   POST;
@@ -2650,7 +3339,8 @@
   INIT(UV_FS_CHMOD);
   err = fs__capture_path(req, path, NULL, cb != NULL);
   if (err) {
-    return uv_translate_sys_error(err);
+    SET_REQ_WIN32_ERROR(req, err);
+    return req->result;
   }
 
   req->fs.info.mode = mode;
@@ -2674,7 +3364,8 @@
   INIT(UV_FS_UTIME);
   err = fs__capture_path(req, path, NULL, cb != NULL);
   if (err) {
-    return uv_translate_sys_error(err);
+    SET_REQ_WIN32_ERROR(req, err);
+    return req->result;
   }
 
   req->fs.time.atime = atime;
@@ -2691,3 +3382,40 @@
   req->fs.time.mtime = mtime;
   POST;
 }
+
+int uv_fs_lutime(uv_loop_t* loop, uv_fs_t* req, const char* path, double atime,
+    double mtime, uv_fs_cb cb) {
+  int err;
+
+  INIT(UV_FS_LUTIME);
+  err = fs__capture_path(req, path, NULL, cb != NULL);
+  if (err) {
+    SET_REQ_WIN32_ERROR(req, err);
+    return req->result;
+  }
+
+  req->fs.time.atime = atime;
+  req->fs.time.mtime = mtime;
+  POST;
+}
+
+
+int uv_fs_statfs(uv_loop_t* loop,
+                 uv_fs_t* req,
+                 const char* path,
+                 uv_fs_cb cb) {
+  int err;
+
+  INIT(UV_FS_STATFS);
+  err = fs__capture_path(req, path, NULL, cb != NULL);
+  if (err) {
+    SET_REQ_WIN32_ERROR(req, err);
+    return req->result;
+  }
+
+  POST;
+}
+
+int uv_fs_get_system_error(const uv_fs_t* req) {
+  return req->sys_errno_;
+}
diff --git a/Utilities/cmlibuv/src/win/internal.h b/Utilities/cmlibuv/src/win/internal.h
index f7d8ccf..463ef33 100644
--- a/Utilities/cmlibuv/src/win/internal.h
+++ b/Utilities/cmlibuv/src/win/internal.h
@@ -284,6 +284,8 @@
                         int* namelen,
                         int delayed_error);
 
+int uv__random_rtlgenrandom(void* buf, size_t buflen);
+
 
 /*
  * Process stdio handles.
diff --git a/Utilities/cmlibuv/src/win/pipe.c b/Utilities/cmlibuv/src/win/pipe.c
index 277f649..fc0112a 100644
--- a/Utilities/cmlibuv/src/win/pipe.c
+++ b/Utilities/cmlibuv/src/win/pipe.c
@@ -264,8 +264,9 @@
   DWORD current_mode = 0;
   DWORD err = 0;
 
-  if (!(handle->flags & UV_HANDLE_PIPESERVER) &&
-      handle->handle != INVALID_HANDLE_VALUE)
+  if (handle->flags & UV_HANDLE_PIPESERVER)
+    return UV_EINVAL;
+  if (handle->handle != INVALID_HANDLE_VALUE)
     return UV_EBUSY;
 
   if (!SetNamedPipeHandleState(pipeHandle, &mode, NULL, NULL)) {
@@ -312,7 +313,7 @@
     /* Overlapped pipe.  Try to associate with IOCP. */
     if (CreateIoCompletionPort(pipeHandle,
                                loop->iocp,
-                               (ULONG_PTR)handle,
+                               (ULONG_PTR) handle,
                                0) == NULL) {
       handle->flags |= UV_HANDLE_EMULATE_IOCP;
     }
@@ -326,6 +327,38 @@
 }
 
 
+static int pipe_alloc_accept(uv_loop_t* loop, uv_pipe_t* handle,
+                             uv_pipe_accept_t* req, BOOL firstInstance) {
+  assert(req->pipeHandle == INVALID_HANDLE_VALUE);
+
+  req->pipeHandle =
+      CreateNamedPipeW(handle->name,
+                       PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED | WRITE_DAC |
+                         (firstInstance ? FILE_FLAG_FIRST_PIPE_INSTANCE : 0),
+                       PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT,
+                       PIPE_UNLIMITED_INSTANCES, 65536, 65536, 0, NULL);
+
+  if (req->pipeHandle == INVALID_HANDLE_VALUE) {
+    return 0;
+  }
+
+  /* Associate it with IOCP so we can get events. */
+  if (CreateIoCompletionPort(req->pipeHandle,
+                             loop->iocp,
+                             (ULONG_PTR) handle,
+                             0) == NULL) {
+    uv_fatal_error(GetLastError(), "CreateIoCompletionPort");
+  }
+
+  /* Stash a handle in the server object for use from places such as
+   * getsockname and chmod. As we transfer ownership of these to client
+   * objects, we'll allocate new ones here. */
+  handle->handle = req->pipeHandle;
+
+  return 1;
+}
+
+
 static DWORD WINAPI pipe_shutdown_thread_proc(void* parameter) {
   uv_loop_t* loop;
   uv_pipe_t* handle;
@@ -458,7 +491,7 @@
           UnregisterWait(handle->read_req.wait_handle);
           handle->read_req.wait_handle = INVALID_HANDLE_VALUE;
         }
-        if (handle->read_req.event_handle) {
+        if (handle->read_req.event_handle != NULL) {
           CloseHandle(handle->read_req.event_handle);
           handle->read_req.event_handle = NULL;
         }
@@ -540,13 +573,10 @@
    * Attempt to create the first pipe with FILE_FLAG_FIRST_PIPE_INSTANCE.
    * If this fails then there's already a pipe server for the given pipe name.
    */
-  handle->pipe.serv.accept_reqs[0].pipeHandle = CreateNamedPipeW(handle->name,
-      PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED |
-      FILE_FLAG_FIRST_PIPE_INSTANCE | WRITE_DAC,
-      PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT,
-      PIPE_UNLIMITED_INSTANCES, 65536, 65536, 0, NULL);
-
-  if (handle->pipe.serv.accept_reqs[0].pipeHandle == INVALID_HANDLE_VALUE) {
+  if (!pipe_alloc_accept(loop,
+                         handle,
+                         &handle->pipe.serv.accept_reqs[0],
+                         TRUE)) {
     err = GetLastError();
     if (err == ERROR_ACCESS_DENIED) {
       err = WSAEADDRINUSE;  /* Translates to UV_EADDRINUSE. */
@@ -556,15 +586,6 @@
     goto error;
   }
 
-  if (uv_set_pipe_handle(loop,
-                         handle,
-                         handle->pipe.serv.accept_reqs[0].pipeHandle,
-                         -1,
-                         0)) {
-    err = GetLastError();
-    goto error;
-  }
-
   handle->pipe.serv.pending_accepts = NULL;
   handle->flags |= UV_HANDLE_PIPESERVER;
   handle->flags |= UV_HANDLE_BOUND;
@@ -577,11 +598,6 @@
     handle->name = NULL;
   }
 
-  if (handle->pipe.serv.accept_reqs[0].pipeHandle != INVALID_HANDLE_VALUE) {
-    CloseHandle(handle->pipe.serv.accept_reqs[0].pipeHandle);
-    handle->pipe.serv.accept_reqs[0].pipeHandle = INVALID_HANDLE_VALUE;
-  }
-
   return uv_translate_sys_error(err);
 }
 
@@ -827,29 +843,11 @@
     uv_pipe_accept_t* req, BOOL firstInstance) {
   assert(handle->flags & UV_HANDLE_LISTENING);
 
-  if (!firstInstance) {
-    assert(req->pipeHandle == INVALID_HANDLE_VALUE);
-
-    req->pipeHandle = CreateNamedPipeW(handle->name,
-        PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED | WRITE_DAC,
-        PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT,
-        PIPE_UNLIMITED_INSTANCES, 65536, 65536, 0, NULL);
-
-    if (req->pipeHandle == INVALID_HANDLE_VALUE) {
-      SET_REQ_ERROR(req, GetLastError());
-      uv_insert_pending_req(loop, (uv_req_t*) req);
-      handle->reqs_pending++;
-      return;
-    }
-
-    if (uv_set_pipe_handle(loop, handle, req->pipeHandle, -1, 0)) {
-      CloseHandle(req->pipeHandle);
-      req->pipeHandle = INVALID_HANDLE_VALUE;
-      SET_REQ_ERROR(req, GetLastError());
-      uv_insert_pending_req(loop, (uv_req_t*) req);
-      handle->reqs_pending++;
-      return;
-    }
+  if (!firstInstance && !pipe_alloc_accept(loop, handle, req, FALSE)) {
+    SET_REQ_ERROR(req, GetLastError());
+    uv_insert_pending_req(loop, (uv_req_t*) req);
+    handle->reqs_pending++;
+    return;
   }
 
   assert(req->pipeHandle != INVALID_HANDLE_VALUE);
@@ -904,7 +902,7 @@
     uv__free(item);
 
   } else {
-    pipe_client = (uv_pipe_t*)client;
+    pipe_client = (uv_pipe_t*) client;
 
     /* Find a connection instance that has been connected, but not yet
      * accepted. */
@@ -925,6 +923,7 @@
     req->next_pending = NULL;
     req->pipeHandle = INVALID_HANDLE_VALUE;
 
+    server->handle = INVALID_HANDLE_VALUE;
     if (!(server->flags & UV_HANDLE_CLOSING)) {
       uv_pipe_queue_accept(loop, server, req, FALSE);
     }
@@ -955,6 +954,10 @@
     return ERROR_NOT_SUPPORTED;
   }
 
+  if (handle->ipc) {
+    return WSAEINVAL;
+  }
+
   handle->flags |= UV_HANDLE_LISTENING;
   INCREASE_ACTIVE_COUNT(loop, handle);
   handle->stream.serv.connection_cb = cb;
@@ -1131,6 +1134,7 @@
   } else {
     memset(&req->u.io.overlapped, 0, sizeof(req->u.io.overlapped));
     if (handle->flags & UV_HANDLE_EMULATE_IOCP) {
+      assert(req->event_handle != NULL);
       req->u.io.overlapped.hEvent = (HANDLE) ((uintptr_t) req->event_handle | 1);
     }
 
@@ -1148,15 +1152,9 @@
     }
 
     if (handle->flags & UV_HANDLE_EMULATE_IOCP) {
-      if (!req->event_handle) {
-        req->event_handle = CreateEvent(NULL, 0, 0, NULL);
-        if (!req->event_handle) {
-          uv_fatal_error(GetLastError(), "CreateEvent");
-        }
-      }
       if (req->wait_handle == INVALID_HANDLE_VALUE) {
         if (!RegisterWaitForSingleObject(&req->wait_handle,
-            req->u.io.overlapped.hEvent, post_completion_read_wait, (void*) req,
+            req->event_handle, post_completion_read_wait, (void*) req,
             INFINITE, WT_EXECUTEINWAITTHREAD)) {
           SET_REQ_ERROR(req, GetLastError());
           goto error;
@@ -1190,8 +1188,16 @@
 
   /* If reading was stopped and then started again, there could still be a read
    * request pending. */
-  if (!(handle->flags & UV_HANDLE_READ_PENDING))
+  if (!(handle->flags & UV_HANDLE_READ_PENDING)) {
+    if (handle->flags & UV_HANDLE_EMULATE_IOCP &&
+        handle->read_req.event_handle == NULL) {
+      handle->read_req.event_handle = CreateEvent(NULL, 0, 0, NULL);
+      if (handle->read_req.event_handle == NULL) {
+        uv_fatal_error(GetLastError(), "CreateEvent");
+      }
+    }
     uv_pipe_queue_read(loop, handle);
+  }
 
   return 0;
 }
@@ -1326,7 +1332,16 @@
   req->coalesced = 0;
   req->event_handle = NULL;
   req->wait_handle = INVALID_HANDLE_VALUE;
+
+  /* Prepare the overlapped structure. */
   memset(&req->u.io.overlapped, 0, sizeof(req->u.io.overlapped));
+  if (handle->flags & (UV_HANDLE_EMULATE_IOCP | UV_HANDLE_BLOCKING_WRITES)) {
+    req->event_handle = CreateEvent(NULL, 0, 0, NULL);
+    if (req->event_handle == NULL) {
+      uv_fatal_error(GetLastError(), "CreateEvent");
+    }
+    req->u.io.overlapped.hEvent = (HANDLE) ((uintptr_t) req->event_handle | 1);
+  }
   req->write_buffer = uv_null_buf_;
 
   if (nbufs == 0) {
@@ -1375,11 +1390,6 @@
     handle->write_queue_size += req->u.io.queued_bytes;
   } else if (handle->flags & UV_HANDLE_BLOCKING_WRITES) {
     /* Using overlapped IO, but wait for completion before returning */
-    req->u.io.overlapped.hEvent = CreateEvent(NULL, 1, 0, NULL);
-    if (!req->u.io.overlapped.hEvent) {
-      uv_fatal_error(GetLastError(), "CreateEvent");
-    }
-
     result = WriteFile(handle->handle,
                        write_buf.base,
                        write_buf.len,
@@ -1388,7 +1398,8 @@
 
     if (!result && GetLastError() != ERROR_IO_PENDING) {
       err = GetLastError();
-      CloseHandle(req->u.io.overlapped.hEvent);
+      CloseHandle(req->event_handle);
+      req->event_handle = NULL;
       return err;
     }
 
@@ -1399,14 +1410,16 @@
       /* Request queued by the kernel. */
       req->u.io.queued_bytes = write_buf.len;
       handle->write_queue_size += req->u.io.queued_bytes;
-      if (WaitForSingleObject(req->u.io.overlapped.hEvent, INFINITE) !=
+      if (WaitForSingleObject(req->event_handle, INFINITE) !=
           WAIT_OBJECT_0) {
         err = GetLastError();
-        CloseHandle(req->u.io.overlapped.hEvent);
+        CloseHandle(req->event_handle);
+        req->event_handle = NULL;
         return err;
       }
     }
-    CloseHandle(req->u.io.overlapped.hEvent);
+    CloseHandle(req->event_handle);
+    req->event_handle = NULL;
 
     REGISTER_HANDLE_REQ(loop, handle, req);
     handle->reqs_pending++;
@@ -1433,12 +1446,8 @@
     }
 
     if (handle->flags & UV_HANDLE_EMULATE_IOCP) {
-      req->event_handle = CreateEvent(NULL, 0, 0, NULL);
-      if (!req->event_handle) {
-        uv_fatal_error(GetLastError(), "CreateEvent");
-      }
       if (!RegisterWaitForSingleObject(&req->wait_handle,
-          req->u.io.overlapped.hEvent, post_completion_write_wait, (void*) req,
+          req->event_handle, post_completion_write_wait, (void*) req,
           INFINITE, WT_EXECUTEINWAITTHREAD)) {
         return GetLastError();
       }
diff --git a/Utilities/cmlibuv/src/win/poll.c b/Utilities/cmlibuv/src/win/poll.c
index 3c66786..8785859 100644
--- a/Utilities/cmlibuv/src/win/poll.c
+++ b/Utilities/cmlibuv/src/win/poll.c
@@ -134,32 +134,6 @@
 }
 
 
-static int uv__fast_poll_cancel_poll_req(uv_loop_t* loop, uv_poll_t* handle) {
-  AFD_POLL_INFO afd_poll_info;
-  int result;
-
-  afd_poll_info.Exclusive = TRUE;
-  afd_poll_info.NumberOfHandles = 1;
-  afd_poll_info.Timeout.QuadPart = INT64_MAX;
-  afd_poll_info.Handles[0].Handle = (HANDLE) handle->socket;
-  afd_poll_info.Handles[0].Status = 0;
-  afd_poll_info.Handles[0].Events = AFD_POLL_ALL;
-
-  result = uv_msafd_poll(handle->socket,
-                         &afd_poll_info,
-                         uv__get_afd_poll_info_dummy(),
-                         uv__get_overlapped_dummy());
-
-  if (result == SOCKET_ERROR) {
-    DWORD error = WSAGetLastError();
-    if (error != WSA_IO_PENDING)
-      return error;
-  }
-
-  return 0;
-}
-
-
 static void uv__fast_poll_process_poll_req(uv_loop_t* loop, uv_poll_t* handle,
     uv_req_t* req) {
   unsigned char mask_events;
@@ -226,44 +200,6 @@
 }
 
 
-static int uv__fast_poll_set(uv_loop_t* loop, uv_poll_t* handle, int events) {
-  assert(handle->type == UV_POLL);
-  assert(!(handle->flags & UV_HANDLE_CLOSING));
-  assert((events & ~(UV_READABLE | UV_WRITABLE | UV_DISCONNECT)) == 0);
-
-  handle->events = events;
-
-  if (handle->events != 0) {
-    uv__handle_start(handle);
-  } else {
-    uv__handle_stop(handle);
-  }
-
-  if ((handle->events & ~(handle->submitted_events_1 |
-      handle->submitted_events_2)) != 0) {
-    uv__fast_poll_submit_poll_req(handle->loop, handle);
-  }
-
-  return 0;
-}
-
-
-static int uv__fast_poll_close(uv_loop_t* loop, uv_poll_t* handle) {
-  handle->events = 0;
-  uv__handle_closing(handle);
-
-  if (handle->submitted_events_1 == 0 &&
-      handle->submitted_events_2 == 0) {
-    uv_want_endgame(loop, (uv_handle_t*) handle);
-    return 0;
-  } else {
-    /* Cancel outstanding poll requests by executing another, unique poll
-     * request that forces the outstanding ones to return. */
-    return uv__fast_poll_cancel_poll_req(loop, handle);
-  }
-}
-
-
 static SOCKET uv__fast_poll_create_peer_socket(HANDLE iocp,
     WSAPROTOCOL_INFOW* protocol_info) {
   SOCKET sock = 0;
@@ -469,41 +405,6 @@
 }
 
 
-static int uv__slow_poll_set(uv_loop_t* loop, uv_poll_t* handle, int events) {
-  assert(handle->type == UV_POLL);
-  assert(!(handle->flags & UV_HANDLE_CLOSING));
-  assert((events & ~(UV_READABLE | UV_WRITABLE)) == 0);
-
-  handle->events = events;
-
-  if (handle->events != 0) {
-    uv__handle_start(handle);
-  } else {
-    uv__handle_stop(handle);
-  }
-
-  if ((handle->events &
-      ~(handle->submitted_events_1 | handle->submitted_events_2)) != 0) {
-    uv__slow_poll_submit_poll_req(handle->loop, handle);
-  }
-
-  return 0;
-}
-
-
-static int uv__slow_poll_close(uv_loop_t* loop, uv_poll_t* handle) {
-  handle->events = 0;
-  uv__handle_closing(handle);
-
-  if (handle->submitted_events_1 == 0 &&
-      handle->submitted_events_2 == 0) {
-    uv_want_endgame(loop, (uv_handle_t*) handle);
-  }
-
-  return 0;
-}
-
-
 int uv_poll_init(uv_loop_t* loop, uv_poll_t* handle, int fd) {
   return uv_poll_init_socket(loop, handle, (SOCKET) uv__get_osfhandle(fd));
 }
@@ -582,35 +483,43 @@
 }
 
 
-int uv_poll_start(uv_poll_t* handle, int events, uv_poll_cb cb) {
-  int err;
+static int uv__poll_set(uv_poll_t* handle, int events, uv_poll_cb cb) {
+  int submitted_events;
 
-  if (!(handle->flags & UV_HANDLE_POLL_SLOW)) {
-    err = uv__fast_poll_set(handle->loop, handle, events);
-  } else {
-    err = uv__slow_poll_set(handle->loop, handle, events);
-  }
+  assert(handle->type == UV_POLL);
+  assert(!(handle->flags & UV_HANDLE_CLOSING));
+  assert((events & ~(UV_READABLE | UV_WRITABLE | UV_DISCONNECT)) == 0);
 
-  if (err) {
-    return uv_translate_sys_error(err);
-  }
-
+  handle->events = events;
   handle->poll_cb = cb;
 
+  if (handle->events == 0) {
+    uv__handle_stop(handle);
+    return 0;
+  }
+
+  uv__handle_start(handle);
+  submitted_events = handle->submitted_events_1 | handle->submitted_events_2;
+
+  if (handle->events & ~submitted_events) {
+    if (handle->flags & UV_HANDLE_POLL_SLOW) {
+      uv__slow_poll_submit_poll_req(handle->loop, handle);
+    } else {
+      uv__fast_poll_submit_poll_req(handle->loop, handle);
+    }
+  }
+
   return 0;
 }
 
 
+int uv_poll_start(uv_poll_t* handle, int events, uv_poll_cb cb) {
+  return uv__poll_set(handle, events, cb);
+}
+
+
 int uv_poll_stop(uv_poll_t* handle) {
-  int err;
-
-  if (!(handle->flags & UV_HANDLE_POLL_SLOW)) {
-    err = uv__fast_poll_set(handle->loop, handle, 0);
-  } else {
-    err = uv__slow_poll_set(handle->loop, handle, 0);
-  }
-
-  return uv_translate_sys_error(err);
+  return uv__poll_set(handle, 0, handle->poll_cb);
 }
 
 
@@ -624,11 +533,43 @@
 
 
 int uv_poll_close(uv_loop_t* loop, uv_poll_t* handle) {
-  if (!(handle->flags & UV_HANDLE_POLL_SLOW)) {
-    return uv__fast_poll_close(loop, handle);
-  } else {
-    return uv__slow_poll_close(loop, handle);
+  AFD_POLL_INFO afd_poll_info;
+  DWORD error;
+  int result;
+
+  handle->events = 0;
+  uv__handle_closing(handle);
+
+  if (handle->submitted_events_1 == 0 &&
+      handle->submitted_events_2 == 0) {
+    uv_want_endgame(loop, (uv_handle_t*) handle);
+    return 0;
   }
+
+  if (handle->flags & UV_HANDLE_POLL_SLOW)
+    return 0;
+
+  /* Cancel outstanding poll requests by executing another, unique poll
+   * request that forces the outstanding ones to return. */
+  afd_poll_info.Exclusive = TRUE;
+  afd_poll_info.NumberOfHandles = 1;
+  afd_poll_info.Timeout.QuadPart = INT64_MAX;
+  afd_poll_info.Handles[0].Handle = (HANDLE) handle->socket;
+  afd_poll_info.Handles[0].Status = 0;
+  afd_poll_info.Handles[0].Events = AFD_POLL_ALL;
+
+  result = uv_msafd_poll(handle->socket,
+                         &afd_poll_info,
+                         uv__get_afd_poll_info_dummy(),
+                         uv__get_overlapped_dummy());
+
+  if (result == SOCKET_ERROR) {
+    error = WSAGetLastError();
+    if (error != WSA_IO_PENDING)
+      return uv_translate_sys_error(error);
+  }
+
+  return 0;
 }
 
 
diff --git a/Utilities/cmlibuv/src/win/process.c b/Utilities/cmlibuv/src/win/process.c
index 24037b3..04718db 100644
--- a/Utilities/cmlibuv/src/win/process.c
+++ b/Utilities/cmlibuv/src/win/process.c
@@ -58,7 +58,6 @@
   E_V("USERPROFILE"),
   E_V("WINDIR"),
 };
-static size_t n_required_vars = ARRAY_SIZE(required_vars);
 
 
 static HANDLE uv_global_job_handle_;
@@ -692,7 +691,7 @@
   WCHAR* dst_copy;
   WCHAR** ptr_copy;
   WCHAR** env_copy;
-  DWORD* required_vars_value_len = alloca(n_required_vars * sizeof(DWORD*));
+  DWORD required_vars_value_len[ARRAY_SIZE(required_vars)];
 
   /* first pass: determine size in UTF-16 */
   for (env = env_block; *env; env++) {
@@ -714,7 +713,7 @@
 
   /* second pass: copy to UTF-16 environment block */
   dst_copy = (WCHAR*)uv__malloc(env_len * sizeof(WCHAR));
-  if (!dst_copy) {
+  if (dst_copy == NULL && env_len > 0) {
     return ERROR_OUTOFMEMORY;
   }
   env_copy = alloca(env_block_count * sizeof(WCHAR*));
@@ -739,13 +738,13 @@
     }
   }
   *ptr_copy = NULL;
-  assert(env_len == (size_t) (ptr - dst_copy));
+  assert(env_len == 0 || env_len == (size_t) (ptr - dst_copy));
 
   /* sort our (UTF-16) copy */
   qsort(env_copy, env_block_count-1, sizeof(wchar_t*), qsort_wcscmp);
 
   /* third pass: check for required variables */
-  for (ptr_copy = env_copy, i = 0; i < n_required_vars; ) {
+  for (ptr_copy = env_copy, i = 0; i < ARRAY_SIZE(required_vars); ) {
     int cmp;
     if (!*ptr_copy) {
       cmp = -1;
@@ -778,10 +777,10 @@
   }
 
   for (ptr = dst, ptr_copy = env_copy, i = 0;
-       *ptr_copy || i < n_required_vars;
+       *ptr_copy || i < ARRAY_SIZE(required_vars);
        ptr += len) {
     int cmp;
-    if (i >= n_required_vars) {
+    if (i >= ARRAY_SIZE(required_vars)) {
       cmp = 1;
     } else if (!*ptr_copy) {
       cmp = -1;
diff --git a/Utilities/cmlibuv/src/win/signal.c b/Utilities/cmlibuv/src/win/signal.c
index 276dc60..3d9f92c 100644
--- a/Utilities/cmlibuv/src/win/signal.c
+++ b/Utilities/cmlibuv/src/win/signal.c
@@ -46,6 +46,11 @@
 }
 
 
+void uv__signal_cleanup(void) {
+  /* TODO(bnoordhuis) Undo effects of uv_signal_init()? */
+}
+
+
 static int uv__signal_compare(uv_signal_t* w1, uv_signal_t* w2) {
   /* Compare signums first so all watchers with the same signnum end up
    * adjacent. */
diff --git a/Utilities/cmlibuv/src/win/stream.c b/Utilities/cmlibuv/src/win/stream.c
index 7656627..46a0709 100644
--- a/Utilities/cmlibuv/src/win/stream.c
+++ b/Utilities/cmlibuv/src/win/stream.c
@@ -198,8 +198,10 @@
 int uv_shutdown(uv_shutdown_t* req, uv_stream_t* handle, uv_shutdown_cb cb) {
   uv_loop_t* loop = handle->loop;
 
-  if (!(handle->flags & UV_HANDLE_WRITABLE)) {
-    return UV_EPIPE;
+  if (!(handle->flags & UV_HANDLE_WRITABLE) ||
+      handle->flags & UV_HANDLE_SHUTTING ||
+      uv__is_closing(handle)) {
+    return UV_ENOTCONN;
   }
 
   UV_REQ_INIT(req, UV_SHUTDOWN);
@@ -207,6 +209,7 @@
   req->cb = cb;
 
   handle->flags &= ~UV_HANDLE_WRITABLE;
+  handle->flags |= UV_HANDLE_SHUTTING;
   handle->stream.conn.shutdown_req = req;
   handle->reqs_pending++;
   REGISTER_HANDLE_REQ(loop, handle, req);
diff --git a/Utilities/cmlibuv/src/win/tcp.c b/Utilities/cmlibuv/src/win/tcp.c
index f2cb527..941c801 100644
--- a/Utilities/cmlibuv/src/win/tcp.c
+++ b/Utilities/cmlibuv/src/win/tcp.c
@@ -251,7 +251,7 @@
             UnregisterWait(req->wait_handle);
             req->wait_handle = INVALID_HANDLE_VALUE;
           }
-          if (req->event_handle) {
+          if (req->event_handle != NULL) {
             CloseHandle(req->event_handle);
             req->event_handle = NULL;
           }
@@ -268,7 +268,7 @@
         UnregisterWait(handle->read_req.wait_handle);
         handle->read_req.wait_handle = INVALID_HANDLE_VALUE;
       }
-      if (handle->read_req.event_handle) {
+      if (handle->read_req.event_handle != NULL) {
         CloseHandle(handle->read_req.event_handle);
         handle->read_req.event_handle = NULL;
       }
@@ -428,6 +428,7 @@
   /* Prepare the overlapped structure. */
   memset(&(req->u.io.overlapped), 0, sizeof(req->u.io.overlapped));
   if (handle->flags & UV_HANDLE_EMULATE_IOCP) {
+    assert(req->event_handle != NULL);
     req->u.io.overlapped.hEvent = (HANDLE) ((ULONG_PTR) req->event_handle | 1);
   }
 
@@ -466,7 +467,7 @@
     closesocket(accept_socket);
     /* Destroy the event handle */
     if (handle->flags & UV_HANDLE_EMULATE_IOCP) {
-      CloseHandle(req->u.io.overlapped.hEvent);
+      CloseHandle(req->event_handle);
       req->event_handle = NULL;
     }
   }
@@ -509,7 +510,7 @@
   /* Prepare the overlapped structure. */
   memset(&(req->u.io.overlapped), 0, sizeof(req->u.io.overlapped));
   if (handle->flags & UV_HANDLE_EMULATE_IOCP) {
-    assert(req->event_handle);
+    assert(req->event_handle != NULL);
     req->u.io.overlapped.hEvent = (HANDLE) ((ULONG_PTR) req->event_handle | 1);
   }
 
@@ -549,6 +550,21 @@
 }
 
 
+int uv_tcp_close_reset(uv_tcp_t* handle, uv_close_cb close_cb) {
+  struct linger l = { 1, 0 };
+
+  /* Disallow setting SO_LINGER to zero due to some platform inconsistencies */
+  if (handle->flags & UV_HANDLE_SHUTTING)
+    return UV_EINVAL;
+
+  if (0 != setsockopt(handle->socket, SOL_SOCKET, SO_LINGER, (const char*)&l, sizeof(l)))
+    return uv_translate_sys_error(WSAGetLastError());
+
+  uv_close((uv_handle_t*) handle, close_cb);
+  return 0;
+}
+
+
 int uv_tcp_listen(uv_tcp_t* handle, int backlog, uv_connection_cb cb) {
   unsigned int i, simultaneous_accepts;
   uv_tcp_accept_t* req;
@@ -597,8 +613,8 @@
   simultaneous_accepts = handle->flags & UV_HANDLE_TCP_SINGLE_ACCEPT ? 1
     : uv_simultaneous_server_accepts;
 
-  if(!handle->tcp.serv.accept_reqs) {
-    handle->tcp.serv.accept_reqs = (uv_tcp_accept_t*)
+  if (handle->tcp.serv.accept_reqs == NULL) {
+    handle->tcp.serv.accept_reqs =
       uv__malloc(uv_simultaneous_server_accepts * sizeof(uv_tcp_accept_t));
     if (!handle->tcp.serv.accept_reqs) {
       uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc");
@@ -613,7 +629,7 @@
       req->wait_handle = INVALID_HANDLE_VALUE;
       if (handle->flags & UV_HANDLE_EMULATE_IOCP) {
         req->event_handle = CreateEvent(NULL, 0, 0, NULL);
-        if (!req->event_handle) {
+        if (req->event_handle == NULL) {
           uv_fatal_error(GetLastError(), "CreateEvent");
         }
       } else {
@@ -722,9 +738,9 @@
    * request pending. */
   if (!(handle->flags & UV_HANDLE_READ_PENDING)) {
     if (handle->flags & UV_HANDLE_EMULATE_IOCP &&
-        !handle->read_req.event_handle) {
+        handle->read_req.event_handle == NULL) {
       handle->read_req.event_handle = CreateEvent(NULL, 0, 0, NULL);
-      if (!handle->read_req.event_handle) {
+      if (handle->read_req.event_handle == NULL) {
         uv_fatal_error(GetLastError(), "CreateEvent");
       }
     }
@@ -847,7 +863,7 @@
   memset(&(req->u.io.overlapped), 0, sizeof(req->u.io.overlapped));
   if (handle->flags & UV_HANDLE_EMULATE_IOCP) {
     req->event_handle = CreateEvent(NULL, 0, 0, NULL);
-    if (!req->event_handle) {
+    if (req->event_handle == NULL) {
       uv_fatal_error(GetLastError(), "CreateEvent");
     }
     req->u.io.overlapped.hEvent = (HANDLE) ((ULONG_PTR) req->event_handle | 1);
@@ -1065,7 +1081,7 @@
       UnregisterWait(req->wait_handle);
       req->wait_handle = INVALID_HANDLE_VALUE;
     }
-    if (req->event_handle) {
+    if (req->event_handle != NULL) {
       CloseHandle(req->event_handle);
       req->event_handle = NULL;
     }
diff --git a/Utilities/cmlibuv/src/win/tty.c b/Utilities/cmlibuv/src/win/tty.c
index a98fe26..488d9b2 100644
--- a/Utilities/cmlibuv/src/win/tty.c
+++ b/Utilities/cmlibuv/src/win/tty.c
@@ -46,14 +46,16 @@
 
 #define UNICODE_REPLACEMENT_CHARACTER (0xfffd)
 
-#define ANSI_NORMAL           0x00
-#define ANSI_ESCAPE_SEEN      0x02
-#define ANSI_CSI              0x04
-#define ANSI_ST_CONTROL       0x08
-#define ANSI_IGNORE           0x10
-#define ANSI_IN_ARG           0x20
-#define ANSI_IN_STRING        0x40
-#define ANSI_BACKSLASH_SEEN   0x80
+#define ANSI_NORMAL           0x0000
+#define ANSI_ESCAPE_SEEN      0x0002
+#define ANSI_CSI              0x0004
+#define ANSI_ST_CONTROL       0x0008
+#define ANSI_IGNORE           0x0010
+#define ANSI_IN_ARG           0x0020
+#define ANSI_IN_STRING        0x0040
+#define ANSI_BACKSLASH_SEEN   0x0080
+#define ANSI_EXTENSION        0x0100
+#define ANSI_DECSCUSR         0x0200
 
 #define MAX_INPUT_BUFFER_LENGTH 8192
 #define MAX_CONSOLE_CHAR 8192
@@ -62,7 +64,12 @@
 #define ENABLE_VIRTUAL_TERMINAL_PROCESSING 0x0004
 #endif
 
-static void uv_tty_capture_initial_style(CONSOLE_SCREEN_BUFFER_INFO* info);
+#define CURSOR_SIZE_SMALL     25
+#define CURSOR_SIZE_LARGE     100
+
+static void uv_tty_capture_initial_style(
+    CONSOLE_SCREEN_BUFFER_INFO* screen_buffer_info,
+    CONSOLE_CURSOR_INFO* cursor_info);
 static void uv_tty_update_virtual_window(CONSOLE_SCREEN_BUFFER_INFO* info);
 static int uv__cancel_read_console(uv_tty_t* handle);
 
@@ -120,6 +127,8 @@
 static HANDLE uv__tty_console_handle = INVALID_HANDLE_VALUE;
 static int uv__tty_console_height = -1;
 static int uv__tty_console_width = -1;
+static HANDLE uv__tty_console_resized = INVALID_HANDLE_VALUE;
+static uv_mutex_t uv__tty_console_resize_mutex;
 
 static DWORD WINAPI uv__tty_console_resize_message_loop_thread(void* param);
 static void CALLBACK uv__tty_console_resize_event(HWINEVENTHOOK hWinEventHook,
@@ -129,6 +138,8 @@
                                                   LONG idChild,
                                                   DWORD dwEventThread,
                                                   DWORD dwmsEventTime);
+static DWORD WINAPI uv__tty_console_resize_watcher_thread(void* param);
+static void uv__tty_console_signal_resize(void);
 
 /* We use a semaphore rather than a mutex or critical section because in some
    cases (uv__cancel_read_console) we need take the lock in the main thread and
@@ -145,13 +156,11 @@
 static char uv_tty_default_bg_bright = 0;
 static char uv_tty_default_inverse = 0;
 
-typedef enum {
-  UV_SUPPORTED,
-  UV_UNCHECKED,
-  UV_UNSUPPORTED
-} uv_vtermstate_t;
+static CONSOLE_CURSOR_INFO uv_tty_default_cursor_info;
+
 /* Determine whether or not ANSI support is enabled. */
-static uv_vtermstate_t uv__vterm_state = UV_UNCHECKED;
+static BOOL uv__need_check_vterm_state = TRUE;
+static uv_tty_vtermstate_t uv__vterm_state = UV_TTY_UNSUPPORTED;
 static void uv__determine_vterm_state(HANDLE handle);
 
 void uv_console_init(void) {
@@ -165,9 +174,15 @@
                                        0,
                                        0);
   if (uv__tty_console_handle != INVALID_HANDLE_VALUE) {
+    CONSOLE_SCREEN_BUFFER_INFO sb_info;
     QueueUserWorkItem(uv__tty_console_resize_message_loop_thread,
                       NULL,
                       WT_EXECUTELONGFUNCTION);
+    uv_mutex_init(&uv__tty_console_resize_mutex);
+    if (GetConsoleScreenBufferInfo(uv__tty_console_handle, &sb_info)) {
+      uv__tty_console_width = sb_info.dwSize.X;
+      uv__tty_console_height = sb_info.srWindow.Bottom - sb_info.srWindow.Top + 1;
+    }
   }
 }
 
@@ -177,6 +192,7 @@
   DWORD NumberOfEvents;
   HANDLE handle;
   CONSOLE_SCREEN_BUFFER_INFO screen_buffer_info;
+  CONSOLE_CURSOR_INFO cursor_info;
   (void)unused;
 
   uv__once_init();
@@ -209,15 +225,20 @@
       return uv_translate_sys_error(GetLastError());
     }
 
+    /* Obtain the cursor info with the output handle. */
+    if (!GetConsoleCursorInfo(handle, &cursor_info)) {
+      return uv_translate_sys_error(GetLastError());
+    }
+
     /* Obtain the tty_output_lock because the virtual window state is shared
      * between all uv_tty_t handles. */
     uv_sem_wait(&uv_tty_output_lock);
 
-    if (uv__vterm_state == UV_UNCHECKED)
+    if (uv__need_check_vterm_state)
       uv__determine_vterm_state(handle);
 
-    /* Remember the original console text attributes. */
-    uv_tty_capture_initial_style(&screen_buffer_info);
+    /* Remember the original console text attributes and cursor info. */
+    uv_tty_capture_initial_style(&screen_buffer_info, &cursor_info);
 
     uv_tty_update_virtual_window(&screen_buffer_info);
 
@@ -268,7 +289,9 @@
 /* Set the default console text attributes based on how the console was
  * configured when libuv started.
  */
-static void uv_tty_capture_initial_style(CONSOLE_SCREEN_BUFFER_INFO* info) {
+static void uv_tty_capture_initial_style(
+    CONSOLE_SCREEN_BUFFER_INFO* screen_buffer_info,
+    CONSOLE_CURSOR_INFO* cursor_info) {
   static int style_captured = 0;
 
   /* Only do this once.
@@ -277,7 +300,7 @@
     return;
 
   /* Save raw win32 attributes. */
-  uv_tty_default_text_attributes = info->wAttributes;
+  uv_tty_default_text_attributes = screen_buffer_info->wAttributes;
 
   /* Convert black text on black background to use white text. */
   if (uv_tty_default_text_attributes == 0)
@@ -317,6 +340,9 @@
   if (uv_tty_default_text_attributes & COMMON_LVB_REVERSE_VIDEO)
     uv_tty_default_inverse = 1;
 
+  /* Save the cursor size and the cursor state. */
+  uv_tty_default_cursor_info = *cursor_info;
+
   style_captured = 1;
 }
 
@@ -728,6 +754,12 @@
       }
       records_left--;
 
+      /* We might be not subscribed to EVENT_CONSOLE_LAYOUT or we might be
+       * running under some TTY emulator that does not send those events. */
+      if (handle->tty.rd.last_input_record.EventType == WINDOW_BUFFER_SIZE_EVENT) {
+        uv__tty_console_signal_resize();
+      }
+
       /* Ignore other events that are not key events. */
       if (handle->tty.rd.last_input_record.EventType != KEY_EVENT) {
         continue;
@@ -1218,7 +1250,7 @@
 static int uv_tty_reset(uv_tty_t* handle, DWORD* error) {
   const COORD origin = {0, 0};
   const WORD char_attrs = uv_tty_default_text_attributes;
-  CONSOLE_SCREEN_BUFFER_INFO info;
+  CONSOLE_SCREEN_BUFFER_INFO screen_buffer_info;
   DWORD count, written;
 
   if (*error != ERROR_SUCCESS) {
@@ -1239,12 +1271,12 @@
 
   /* Clear the screen buffer. */
  retry:
-  if (!GetConsoleScreenBufferInfo(handle->handle, &info)) {
-    *error = GetLastError();
-    return -1;
+   if (!GetConsoleScreenBufferInfo(handle->handle, &screen_buffer_info)) {
+     *error = GetLastError();
+     return -1;
   }
 
-  count = info.dwSize.X * info.dwSize.Y;
+  count = screen_buffer_info.dwSize.X * screen_buffer_info.dwSize.Y;
 
   if (!(FillConsoleOutputCharacterW(handle->handle,
                                     L'\x20',
@@ -1267,7 +1299,13 @@
 
   /* Move the virtual window up to the top. */
   uv_tty_virtual_offset = 0;
-  uv_tty_update_virtual_window(&info);
+  uv_tty_update_virtual_window(&screen_buffer_info);
+
+  /* Reset the cursor size and the cursor state. */
+  if (!SetConsoleCursorInfo(handle->handle, &uv_tty_default_cursor_info)) {
+    *error = GetLastError();
+    return -1;
+  }
 
   return 0;
 }
@@ -1606,6 +1644,31 @@
   return 0;
 }
 
+static int uv_tty_set_cursor_shape(uv_tty_t* handle, int style, DWORD* error) {
+  CONSOLE_CURSOR_INFO cursor_info;
+
+  if (!GetConsoleCursorInfo(handle->handle, &cursor_info)) {
+    *error = GetLastError();
+    return -1;
+  }
+
+  if (style == 0) {
+    cursor_info.dwSize = uv_tty_default_cursor_info.dwSize;
+  } else if (style <= 2) {
+    cursor_info.dwSize = CURSOR_SIZE_LARGE;
+  } else {
+    cursor_info.dwSize = CURSOR_SIZE_SMALL;
+  }
+
+  if (!SetConsoleCursorInfo(handle->handle, &cursor_info)) {
+    *error = GetLastError();
+    return -1;
+  }
+
+  return 0;
+}
+
+
 static int uv_tty_write_bufs(uv_tty_t* handle,
                              const uv_buf_t bufs[],
                              unsigned int nbufs,
@@ -1613,28 +1676,16 @@
   /* We can only write 8k characters at a time. Windows can't handle much more
    * characters in a single console write anyway. */
   WCHAR utf16_buf[MAX_CONSOLE_CHAR];
-  WCHAR* utf16_buffer;
   DWORD utf16_buf_used = 0;
-  unsigned int i, len, max_len, pos;
-  int allocate = 0;
+  unsigned int i;
 
-#define FLUSH_TEXT()                                                 \
-  do {                                                               \
-    pos = 0;                                                         \
-    do {                                                             \
-      len = utf16_buf_used - pos;                                    \
-      if (len > MAX_CONSOLE_CHAR)                                    \
-        len = MAX_CONSOLE_CHAR;                                      \
-      uv_tty_emit_text(handle, &utf16_buffer[pos], len, error);      \
-      pos += len;                                                    \
-    } while (pos < utf16_buf_used);                                  \
-    if (allocate) {                                                  \
-      uv__free(utf16_buffer);                                        \
-      allocate = 0;                                                  \
-      utf16_buffer = utf16_buf;                                      \
-    }                                                                \
-    utf16_buf_used = 0;                                              \
- } while (0)
+#define FLUSH_TEXT()                                                \
+  do {                                                              \
+    if (utf16_buf_used > 0) {                                       \
+      uv_tty_emit_text(handle, utf16_buf, utf16_buf_used, error);   \
+      utf16_buf_used = 0;                                           \
+    }                                                               \
+  } while (0)
 
 #define ENSURE_BUFFER_SPACE(wchars_needed)                          \
   if (wchars_needed > ARRAY_SIZE(utf16_buf) - utf16_buf_used) {     \
@@ -1645,54 +1696,18 @@
   unsigned char utf8_bytes_left = handle->tty.wr.utf8_bytes_left;
   unsigned int utf8_codepoint = handle->tty.wr.utf8_codepoint;
   unsigned char previous_eol = handle->tty.wr.previous_eol;
-  unsigned char ansi_parser_state = handle->tty.wr.ansi_parser_state;
+  unsigned short ansi_parser_state = handle->tty.wr.ansi_parser_state;
 
   /* Store the error here. If we encounter an error, stop trying to do i/o but
    * keep parsing the buffer so we leave the parser in a consistent state. */
   *error = ERROR_SUCCESS;
 
-  utf16_buffer = utf16_buf;
-
   uv_sem_wait(&uv_tty_output_lock);
 
   for (i = 0; i < nbufs; i++) {
     uv_buf_t buf = bufs[i];
     unsigned int j;
 
-    if (uv__vterm_state == UV_SUPPORTED && buf.len > 0) {
-      utf16_buf_used = MultiByteToWideChar(CP_UTF8,
-                                           0,
-                                           buf.base,
-                                           buf.len,
-                                           NULL,
-                                           0);
-
-      if (utf16_buf_used == 0) {
-        *error = GetLastError();
-        break;
-      }
-
-      max_len = (utf16_buf_used + 1) * sizeof(WCHAR);
-      allocate = max_len > MAX_CONSOLE_CHAR;
-      if (allocate)
-        utf16_buffer = uv__malloc(max_len);
-      if (!MultiByteToWideChar(CP_UTF8,
-                               0,
-                               buf.base,
-                               buf.len,
-                               utf16_buffer,
-                               utf16_buf_used)) {
-        if (allocate)
-          uv__free(utf16_buffer);
-        *error = GetLastError();
-        break;
-      }
-
-      FLUSH_TEXT();
-
-      continue;
-    }
-
     for (j = 0; j < buf.len; j++) {
       unsigned char c = buf.base[j];
 
@@ -1749,7 +1764,9 @@
       }
 
       /* Parse vt100/ansi escape codes */
-      if (ansi_parser_state == ANSI_NORMAL) {
+      if (uv__vterm_state == UV_TTY_SUPPORTED) {
+        /* Pass through escape codes if conhost supports them. */
+      } else if (ansi_parser_state == ANSI_NORMAL) {
         switch (utf8_codepoint) {
           case '\033':
             ansi_parser_state = ANSI_ESCAPE_SEEN;
@@ -1795,7 +1812,7 @@
             ansi_parser_state = ANSI_NORMAL;
             continue;
 
-           case '8':
+          case '8':
             /* Restore the cursor position and text attributes */
             FLUSH_TEXT();
             uv_tty_restore_state(handle, 1, error);
@@ -1813,121 +1830,193 @@
             }
         }
 
+      } else if (ansi_parser_state == ANSI_IGNORE) {
+        /* We're ignoring this command. Stop only on command character. */
+        if (utf8_codepoint >= '@' && utf8_codepoint <= '~') {
+          ansi_parser_state = ANSI_NORMAL;
+        }
+        continue;
+
+      } else if (ansi_parser_state == ANSI_DECSCUSR) {
+        /* So far we've the sequence `ESC [ arg space`, and we're waiting for
+         * the final command byte. */
+        if (utf8_codepoint >= '@' && utf8_codepoint <= '~') {
+          /* Command byte */
+          if (utf8_codepoint == 'q') {
+            /* Change the cursor shape */
+            int style = handle->tty.wr.ansi_csi_argc
+              ? handle->tty.wr.ansi_csi_argv[0] : 1;
+            if (style >= 0 && style <= 6) {
+              FLUSH_TEXT();
+              uv_tty_set_cursor_shape(handle, style, error);
+            }
+          }
+
+          /* Sequence ended - go back to normal state. */
+          ansi_parser_state = ANSI_NORMAL;
+          continue;
+        }
+        /* Unexpected character, but sequence hasn't ended yet. Ignore the rest
+         * of the sequence. */
+        ansi_parser_state = ANSI_IGNORE;
+
       } else if (ansi_parser_state & ANSI_CSI) {
-        if (!(ansi_parser_state & ANSI_IGNORE)) {
-          if (utf8_codepoint >= '0' && utf8_codepoint <= '9') {
-            /* Parsing a numerical argument */
+        /* So far we've seen `ESC [`, and we may or may not have already parsed
+         * some of the arguments that follow. */
 
-            if (!(ansi_parser_state & ANSI_IN_ARG)) {
-              /* We were not currently parsing a number */
-
-              /* Check for too many arguments */
-              if (handle->tty.wr.ansi_csi_argc >= ARRAY_SIZE(handle->tty.wr.ansi_csi_argv)) {
-                ansi_parser_state |= ANSI_IGNORE;
-                continue;
-              }
-
-              ansi_parser_state |= ANSI_IN_ARG;
-              handle->tty.wr.ansi_csi_argc++;
-              handle->tty.wr.ansi_csi_argv[handle->tty.wr.ansi_csi_argc - 1] =
-                  (unsigned short) utf8_codepoint - '0';
-              continue;
-            } else {
-              /* We were already parsing a number. Parse next digit. */
-              uint32_t value = 10 *
-                  handle->tty.wr.ansi_csi_argv[handle->tty.wr.ansi_csi_argc - 1];
-
-              /* Check for overflow. */
-              if (value > UINT16_MAX) {
-                ansi_parser_state |= ANSI_IGNORE;
-                continue;
-              }
-
-               handle->tty.wr.ansi_csi_argv[handle->tty.wr.ansi_csi_argc - 1] =
-                   (unsigned short) value + (utf8_codepoint - '0');
-               continue;
-            }
-
-          } else if (utf8_codepoint == ';') {
-            /* Denotes the end of an argument. */
-            if (ansi_parser_state & ANSI_IN_ARG) {
-              ansi_parser_state &= ~ANSI_IN_ARG;
-              continue;
-
-            } else {
-              /* If ANSI_IN_ARG is not set, add another argument and default it
-               * to 0. */
-
-              /* Check for too many arguments */
-              if (handle->tty.wr.ansi_csi_argc >= ARRAY_SIZE(handle->tty.wr.ansi_csi_argv)) {
-                ansi_parser_state |= ANSI_IGNORE;
-                continue;
-              }
-
-              handle->tty.wr.ansi_csi_argc++;
-              handle->tty.wr.ansi_csi_argv[handle->tty.wr.ansi_csi_argc - 1] = 0;
+        if (utf8_codepoint >= '0' && utf8_codepoint <= '9') {
+          /* Parse a numerical argument. */
+          if (!(ansi_parser_state & ANSI_IN_ARG)) {
+            /* We were not currently parsing a number, add a new one. */
+            /* Check for that there are too many arguments. */
+            if (handle->tty.wr.ansi_csi_argc >=
+                ARRAY_SIZE(handle->tty.wr.ansi_csi_argv)) {
+              ansi_parser_state = ANSI_IGNORE;
               continue;
             }
-
-          } else if (utf8_codepoint == '?' && !(ansi_parser_state & ANSI_IN_ARG) &&
-                     handle->tty.wr.ansi_csi_argc == 0) {
-            /* Ignores '?' if it is the first character after CSI[. This is an
-             * extension character from the VT100 codeset that is supported and
-             * used by most ANSI terminals today. */
+            ansi_parser_state |= ANSI_IN_ARG;
+            handle->tty.wr.ansi_csi_argc++;
+            handle->tty.wr.ansi_csi_argv[handle->tty.wr.ansi_csi_argc - 1] =
+                (unsigned short) utf8_codepoint - '0';
             continue;
 
-          } else if (utf8_codepoint >= '@' && utf8_codepoint <= '~' &&
-                     (handle->tty.wr.ansi_csi_argc > 0 || utf8_codepoint != '[')) {
-            int x, y, d;
+          } else {
+            /* We were already parsing a number. Parse next digit. */
+            uint32_t value = 10 *
+                handle->tty.wr.ansi_csi_argv[handle->tty.wr.ansi_csi_argc - 1];
 
-            /* Command byte */
+            /* Check for overflow. */
+            if (value > UINT16_MAX) {
+              ansi_parser_state = ANSI_IGNORE;
+              continue;
+            }
+
+            handle->tty.wr.ansi_csi_argv[handle->tty.wr.ansi_csi_argc - 1] =
+                (unsigned short) value + (utf8_codepoint - '0');
+            continue;
+          }
+
+        } else if (utf8_codepoint == ';') {
+          /* Denotes the end of an argument. */
+          if (ansi_parser_state & ANSI_IN_ARG) {
+            ansi_parser_state &= ~ANSI_IN_ARG;
+            continue;
+
+          } else {
+            /* If ANSI_IN_ARG is not set, add another argument and default
+             * it to 0. */
+
+            /* Check for too many arguments */
+            if (handle->tty.wr.ansi_csi_argc >=
+
+                ARRAY_SIZE(handle->tty.wr.ansi_csi_argv)) {
+              ansi_parser_state = ANSI_IGNORE;
+              continue;
+            }
+
+            handle->tty.wr.ansi_csi_argc++;
+            handle->tty.wr.ansi_csi_argv[handle->tty.wr.ansi_csi_argc - 1] = 0;
+            continue;
+          }
+
+        } else if (utf8_codepoint == '?' &&
+                   !(ansi_parser_state & ANSI_IN_ARG) &&
+                   !(ansi_parser_state & ANSI_EXTENSION) &&
+                   handle->tty.wr.ansi_csi_argc == 0) {
+          /* Pass through '?' if it is the first character after CSI */
+          /* This is an extension character from the VT100 codeset */
+          /* that is supported and used by most ANSI terminals today. */
+          ansi_parser_state |= ANSI_EXTENSION;
+          continue;
+
+        } else if (utf8_codepoint == ' ' &&
+                   !(ansi_parser_state & ANSI_EXTENSION)) {
+          /* We expect a command byte to follow after this space. The only
+           * command that we current support is 'set cursor style'. */
+          ansi_parser_state = ANSI_DECSCUSR;
+          continue;
+
+        } else if (utf8_codepoint >= '@' && utf8_codepoint <= '~') {
+          /* Command byte */
+          if (ansi_parser_state & ANSI_EXTENSION) {
+            /* Sequence is `ESC [ ? args command`. */
+            switch (utf8_codepoint) {
+              case 'l':
+                /* Hide the cursor */
+                if (handle->tty.wr.ansi_csi_argc == 1 &&
+                    handle->tty.wr.ansi_csi_argv[0] == 25) {
+                  FLUSH_TEXT();
+                  uv_tty_set_cursor_visibility(handle, 0, error);
+                }
+                break;
+
+              case 'h':
+                /* Show the cursor */
+                if (handle->tty.wr.ansi_csi_argc == 1 &&
+                    handle->tty.wr.ansi_csi_argv[0] == 25) {
+                  FLUSH_TEXT();
+                  uv_tty_set_cursor_visibility(handle, 1, error);
+                }
+                break;
+            }
+
+          } else {
+            /* Sequence is `ESC [ args command`. */
+            int x, y, d;
             switch (utf8_codepoint) {
               case 'A':
                 /* cursor up */
                 FLUSH_TEXT();
-                y = -(handle->tty.wr.ansi_csi_argc ? handle->tty.wr.ansi_csi_argv[0] : 1);
+                y = -(handle->tty.wr.ansi_csi_argc
+                  ? handle->tty.wr.ansi_csi_argv[0] : 1);
                 uv_tty_move_caret(handle, 0, 1, y, 1, error);
                 break;
 
               case 'B':
                 /* cursor down */
                 FLUSH_TEXT();
-                y = handle->tty.wr.ansi_csi_argc ? handle->tty.wr.ansi_csi_argv[0] : 1;
+                y = handle->tty.wr.ansi_csi_argc
+                  ? handle->tty.wr.ansi_csi_argv[0] : 1;
                 uv_tty_move_caret(handle, 0, 1, y, 1, error);
                 break;
 
               case 'C':
                 /* cursor forward */
                 FLUSH_TEXT();
-                x = handle->tty.wr.ansi_csi_argc ? handle->tty.wr.ansi_csi_argv[0] : 1;
+                x = handle->tty.wr.ansi_csi_argc
+                  ? handle->tty.wr.ansi_csi_argv[0] : 1;
                 uv_tty_move_caret(handle, x, 1, 0, 1, error);
                 break;
 
               case 'D':
                 /* cursor back */
                 FLUSH_TEXT();
-                x = -(handle->tty.wr.ansi_csi_argc ? handle->tty.wr.ansi_csi_argv[0] : 1);
+                x = -(handle->tty.wr.ansi_csi_argc
+                  ? handle->tty.wr.ansi_csi_argv[0] : 1);
                 uv_tty_move_caret(handle, x, 1, 0, 1, error);
                 break;
 
               case 'E':
                 /* cursor next line */
                 FLUSH_TEXT();
-                y = handle->tty.wr.ansi_csi_argc ? handle->tty.wr.ansi_csi_argv[0] : 1;
+                y = handle->tty.wr.ansi_csi_argc
+                  ? handle->tty.wr.ansi_csi_argv[0] : 1;
                 uv_tty_move_caret(handle, 0, 0, y, 1, error);
                 break;
 
               case 'F':
                 /* cursor previous line */
                 FLUSH_TEXT();
-                y = -(handle->tty.wr.ansi_csi_argc ? handle->tty.wr.ansi_csi_argv[0] : 1);
+                y = -(handle->tty.wr.ansi_csi_argc
+                  ? handle->tty.wr.ansi_csi_argv[0] : 1);
                 uv_tty_move_caret(handle, 0, 0, y, 1, error);
                 break;
 
               case 'G':
                 /* cursor horizontal move absolute */
                 FLUSH_TEXT();
-                x = (handle->tty.wr.ansi_csi_argc >= 1 && handle->tty.wr.ansi_csi_argv[0])
+                x = (handle->tty.wr.ansi_csi_argc >= 1 &&
+                     handle->tty.wr.ansi_csi_argv[0])
                   ? handle->tty.wr.ansi_csi_argv[0] - 1 : 0;
                 uv_tty_move_caret(handle, x, 0, 0, 1, error);
                 break;
@@ -1936,9 +2025,11 @@
               case 'f':
                 /* cursor move absolute */
                 FLUSH_TEXT();
-                y = (handle->tty.wr.ansi_csi_argc >= 1 && handle->tty.wr.ansi_csi_argv[0])
+                y = (handle->tty.wr.ansi_csi_argc >= 1 &&
+                     handle->tty.wr.ansi_csi_argv[0])
                   ? handle->tty.wr.ansi_csi_argv[0] - 1 : 0;
-                x = (handle->tty.wr.ansi_csi_argc >= 2 && handle->tty.wr.ansi_csi_argv[1])
+                x = (handle->tty.wr.ansi_csi_argc >= 2 &&
+                     handle->tty.wr.ansi_csi_argv[1])
                   ? handle->tty.wr.ansi_csi_argv[1] - 1 : 0;
                 uv_tty_move_caret(handle, x, 0, y, 0, error);
                 break;
@@ -1946,7 +2037,8 @@
               case 'J':
                 /* Erase screen */
                 FLUSH_TEXT();
-                d = handle->tty.wr.ansi_csi_argc ? handle->tty.wr.ansi_csi_argv[0] : 0;
+                d = handle->tty.wr.ansi_csi_argc
+                  ? handle->tty.wr.ansi_csi_argv[0] : 0;
                 if (d >= 0 && d <= 2) {
                   uv_tty_clear(handle, d, 1, error);
                 }
@@ -1955,7 +2047,8 @@
               case 'K':
                 /* Erase line */
                 FLUSH_TEXT();
-                d = handle->tty.wr.ansi_csi_argc ? handle->tty.wr.ansi_csi_argv[0] : 0;
+                d = handle->tty.wr.ansi_csi_argc
+                  ? handle->tty.wr.ansi_csi_argv[0] : 0;
                 if (d >= 0 && d <= 2) {
                   uv_tty_clear(handle, d, 0, error);
                 }
@@ -1978,41 +2071,17 @@
                 FLUSH_TEXT();
                 uv_tty_restore_state(handle, 0, error);
                 break;
-
-              case 'l':
-                /* Hide the cursor */
-                if (handle->tty.wr.ansi_csi_argc == 1 &&
-                    handle->tty.wr.ansi_csi_argv[0] == 25) {
-                  FLUSH_TEXT();
-                  uv_tty_set_cursor_visibility(handle, 0, error);
-                }
-                break;
-
-              case 'h':
-                /* Show the cursor */
-                if (handle->tty.wr.ansi_csi_argc == 1 &&
-                    handle->tty.wr.ansi_csi_argv[0] == 25) {
-                  FLUSH_TEXT();
-                  uv_tty_set_cursor_visibility(handle, 1, error);
-                }
-                break;
             }
-
-            /* Sequence ended - go back to normal state. */
-            ansi_parser_state = ANSI_NORMAL;
-            continue;
-
-          } else {
-            /* We don't support commands that use private mode characters or
-             * intermediaries. Ignore the rest of the sequence. */
-            ansi_parser_state |= ANSI_IGNORE;
-            continue;
           }
+
+          /* Sequence ended - go back to normal state. */
+          ansi_parser_state = ANSI_NORMAL;
+          continue;
+
         } else {
-          /* We're ignoring this command. Stop only on command character. */
-          if (utf8_codepoint >= '@' && utf8_codepoint <= '~') {
-            ansi_parser_state = ANSI_NORMAL;
-          }
+          /* We don't support commands that use private mode characters or
+           * intermediaries. Ignore the rest of the sequence. */
+          ansi_parser_state = ANSI_IGNORE;
           continue;
         }
 
@@ -2264,38 +2333,56 @@
 static void uv__determine_vterm_state(HANDLE handle) {
   DWORD dwMode = 0;
 
+  uv__need_check_vterm_state = FALSE;
   if (!GetConsoleMode(handle, &dwMode)) {
-    uv__vterm_state = UV_UNSUPPORTED;
     return;
   }
 
   dwMode |= ENABLE_VIRTUAL_TERMINAL_PROCESSING;
   if (!SetConsoleMode(handle, dwMode)) {
-    uv__vterm_state = UV_UNSUPPORTED;
     return;
   }
 
-  uv__vterm_state = UV_SUPPORTED;
+  uv__vterm_state = UV_TTY_SUPPORTED;
 }
 
 static DWORD WINAPI uv__tty_console_resize_message_loop_thread(void* param) {
-  CONSOLE_SCREEN_BUFFER_INFO sb_info;
+  NTSTATUS status;
+  ULONG_PTR conhost_pid;
   MSG msg;
 
-  if (!GetConsoleScreenBufferInfo(uv__tty_console_handle, &sb_info))
+  if (pSetWinEventHook == NULL || pNtQueryInformationProcess == NULL)
     return 0;
 
-  uv__tty_console_width = sb_info.dwSize.X;
-  uv__tty_console_height = sb_info.srWindow.Bottom - sb_info.srWindow.Top + 1;
+  status = pNtQueryInformationProcess(GetCurrentProcess(),
+                                      ProcessConsoleHostProcess,
+                                      &conhost_pid,
+                                      sizeof(conhost_pid),
+                                      NULL);
 
-  if (pSetWinEventHook == NULL)
+  if (!NT_SUCCESS(status)) {
+    /* We couldn't retrieve our console host process, probably because this
+     * is a 32-bit process running on 64-bit Windows. Fall back to receiving
+     * console events from the input stream only. */
+    return 0;
+  }
+
+  /* Ensure the PID is a multiple of 4, which is required by SetWinEventHook */
+  conhost_pid &= ~(ULONG_PTR)0x3;
+
+  uv__tty_console_resized = CreateEvent(NULL, TRUE, FALSE, NULL);
+  if (uv__tty_console_resized == NULL)
+    return 0;
+  if (QueueUserWorkItem(uv__tty_console_resize_watcher_thread,
+                        NULL,
+                        WT_EXECUTELONGFUNCTION) == 0)
     return 0;
 
   if (!pSetWinEventHook(EVENT_CONSOLE_LAYOUT,
                         EVENT_CONSOLE_LAYOUT,
                         NULL,
                         uv__tty_console_resize_event,
-                        0,
+                        (DWORD)conhost_pid,
                         0,
                         WINEVENT_OUTOFCONTEXT))
     return 0;
@@ -2314,6 +2401,20 @@
                                                   LONG idChild,
                                                   DWORD dwEventThread,
                                                   DWORD dwmsEventTime) {
+  SetEvent(uv__tty_console_resized);
+}
+
+static DWORD WINAPI uv__tty_console_resize_watcher_thread(void* param) {
+  for (;;) {
+    /* Make sure to not overwhelm the system with resize events */
+    Sleep(33);
+    WaitForSingleObject(uv__tty_console_resized, INFINITE);
+    uv__tty_console_signal_resize();
+    ResetEvent(uv__tty_console_resized);
+  }
+}
+
+static void uv__tty_console_signal_resize(void) {
   CONSOLE_SCREEN_BUFFER_INFO sb_info;
   int width, height;
 
@@ -2323,9 +2424,28 @@
   width = sb_info.dwSize.X;
   height = sb_info.srWindow.Bottom - sb_info.srWindow.Top + 1;
 
+  uv_mutex_lock(&uv__tty_console_resize_mutex);
+  assert(uv__tty_console_width != -1 && uv__tty_console_height != -1);
   if (width != uv__tty_console_width || height != uv__tty_console_height) {
     uv__tty_console_width = width;
     uv__tty_console_height = height;
+    uv_mutex_unlock(&uv__tty_console_resize_mutex);
     uv__signal_dispatch(SIGWINCH);
+  } else {
+    uv_mutex_unlock(&uv__tty_console_resize_mutex);
   }
 }
+
+void uv_tty_set_vterm_state(uv_tty_vtermstate_t state) {
+  uv_sem_wait(&uv_tty_output_lock);
+  uv__need_check_vterm_state = FALSE;
+  uv__vterm_state = state;
+  uv_sem_post(&uv_tty_output_lock);
+}
+
+int uv_tty_get_vterm_state(uv_tty_vtermstate_t* state) {
+  uv_sem_wait(&uv_tty_output_lock);
+  *state = uv__vterm_state;
+  uv_sem_post(&uv_tty_output_lock);
+  return 0;
+}
diff --git a/Utilities/cmlibuv/src/win/udp.c b/Utilities/cmlibuv/src/win/udp.c
index 8aeeab3..508ed37 100644
--- a/Utilities/cmlibuv/src/win/udp.c
+++ b/Utilities/cmlibuv/src/win/udp.c
@@ -125,17 +125,10 @@
 }
 
 
-int uv_udp_init_ex(uv_loop_t* loop, uv_udp_t* handle, unsigned int flags) {
-  int domain;
-
-  /* Use the lower 8 bits for the domain */
-  domain = flags & 0xFF;
-  if (domain != AF_INET && domain != AF_INET6 && domain != AF_UNSPEC)
-    return UV_EINVAL;
-
-  if (flags & ~0xFF)
-    return UV_EINVAL;
-
+int uv__udp_init_ex(uv_loop_t* loop,
+                    uv_udp_t* handle,
+                    unsigned flags,
+                    int domain) {
   uv__handle_init(loop, (uv_handle_t*) handle, UV_UDP);
   handle->socket = INVALID_SOCKET;
   handle->reqs_pending = 0;
@@ -174,11 +167,6 @@
 }
 
 
-int uv_udp_init(uv_loop_t* loop, uv_udp_t* handle) {
-  return uv_udp_init_ex(loop, handle, AF_UNSPEC);
-}
-
-
 void uv_udp_close(uv_loop_t* loop, uv_udp_t* handle) {
   uv_udp_recv_stop(handle);
   closesocket(handle->socket);
@@ -702,6 +690,112 @@
 }
 
 
+static int uv__udp_set_source_membership4(uv_udp_t* handle,
+                                          const struct sockaddr_in* multicast_addr,
+                                          const char* interface_addr,
+                                          const struct sockaddr_in* source_addr,
+                                          uv_membership membership) {
+  struct ip_mreq_source mreq;
+  int optname;
+  int err;
+
+  if (handle->flags & UV_HANDLE_IPV6)
+    return UV_EINVAL;
+
+  /* If the socket is unbound, bind to inaddr_any. */
+  err = uv_udp_maybe_bind(handle,
+                          (const struct sockaddr*) &uv_addr_ip4_any_,
+                          sizeof(uv_addr_ip4_any_),
+                          UV_UDP_REUSEADDR);
+  if (err)
+    return uv_translate_sys_error(err);
+
+  memset(&mreq, 0, sizeof(mreq));
+
+  if (interface_addr != NULL) {
+    err = uv_inet_pton(AF_INET, interface_addr, &mreq.imr_interface.s_addr);
+    if (err)
+      return err;
+  } else {
+    mreq.imr_interface.s_addr = htonl(INADDR_ANY);
+  }
+
+  mreq.imr_multiaddr.s_addr = multicast_addr->sin_addr.s_addr;
+  mreq.imr_sourceaddr.s_addr = source_addr->sin_addr.s_addr;
+
+  if (membership == UV_JOIN_GROUP)
+    optname = IP_ADD_SOURCE_MEMBERSHIP;
+  else if (membership == UV_LEAVE_GROUP)
+    optname = IP_DROP_SOURCE_MEMBERSHIP;
+  else
+    return UV_EINVAL;
+
+  if (setsockopt(handle->socket,
+                 IPPROTO_IP,
+                 optname,
+                 (char*) &mreq,
+                 sizeof(mreq)) == SOCKET_ERROR) {
+    return uv_translate_sys_error(WSAGetLastError());
+  }
+
+  return 0;
+}
+
+
+int uv__udp_set_source_membership6(uv_udp_t* handle,
+                                   const struct sockaddr_in6* multicast_addr,
+                                   const char* interface_addr,
+                                   const struct sockaddr_in6* source_addr,
+                                   uv_membership membership) {
+  struct group_source_req mreq;
+  struct sockaddr_in6 addr6;
+  int optname;
+  int err;
+
+  if ((handle->flags & UV_HANDLE_BOUND) && !(handle->flags & UV_HANDLE_IPV6))
+    return UV_EINVAL;
+
+  err = uv_udp_maybe_bind(handle,
+                          (const struct sockaddr*) &uv_addr_ip6_any_,
+                          sizeof(uv_addr_ip6_any_),
+                          UV_UDP_REUSEADDR);
+
+  if (err)
+    return uv_translate_sys_error(err);
+
+  memset(&mreq, 0, sizeof(mreq));
+
+  if (interface_addr != NULL) {
+    err = uv_ip6_addr(interface_addr, 0, &addr6);
+    if (err)
+      return err;
+    mreq.gsr_interface = addr6.sin6_scope_id;
+  } else {
+    mreq.gsr_interface = 0;
+  }
+
+  memcpy(&mreq.gsr_group, multicast_addr, sizeof(mreq.gsr_group));
+  memcpy(&mreq.gsr_source, source_addr, sizeof(mreq.gsr_source));
+
+  if (membership == UV_JOIN_GROUP)
+    optname = MCAST_JOIN_SOURCE_GROUP;
+  else if (membership == UV_LEAVE_GROUP)
+    optname = MCAST_LEAVE_SOURCE_GROUP;
+  else
+    return UV_EINVAL;
+
+  if (setsockopt(handle->socket,
+                 IPPROTO_IPV6,
+                 optname,
+                 (char*) &mreq,
+                 sizeof(mreq)) == SOCKET_ERROR) {
+    return uv_translate_sys_error(WSAGetLastError());
+  }
+
+  return 0;
+}
+
+
 int uv_udp_set_membership(uv_udp_t* handle,
                           const char* multicast_addr,
                           const char* interface_addr,
@@ -718,6 +812,50 @@
 }
 
 
+int uv_udp_set_source_membership(uv_udp_t* handle,
+                                 const char* multicast_addr,
+                                 const char* interface_addr,
+                                 const char* source_addr,
+                                 uv_membership membership) {
+  int err;
+  struct sockaddr_storage mcast_addr;
+  struct sockaddr_in* mcast_addr4;
+  struct sockaddr_in6* mcast_addr6;
+  struct sockaddr_storage src_addr;
+  struct sockaddr_in* src_addr4;
+  struct sockaddr_in6* src_addr6;
+
+  mcast_addr4 = (struct sockaddr_in*)&mcast_addr;
+  mcast_addr6 = (struct sockaddr_in6*)&mcast_addr;
+  src_addr4 = (struct sockaddr_in*)&src_addr;
+  src_addr6 = (struct sockaddr_in6*)&src_addr;
+
+  err = uv_ip4_addr(multicast_addr, 0, mcast_addr4);
+  if (err) {
+    err = uv_ip6_addr(multicast_addr, 0, mcast_addr6);
+    if (err)
+      return err;
+    err = uv_ip6_addr(source_addr, 0, src_addr6);
+    if (err)
+      return err;
+    return uv__udp_set_source_membership6(handle,
+                                          mcast_addr6,
+                                          interface_addr,
+                                          src_addr6,
+                                          membership);
+  }
+  
+  err = uv_ip4_addr(source_addr, 0, src_addr4);
+  if (err)
+    return err;
+  return uv__udp_set_source_membership4(handle,
+                                        mcast_addr4,
+                                        interface_addr,
+                                        src_addr4,
+                                        membership);
+}
+
+
 int uv_udp_set_multicast_interface(uv_udp_t* handle, const char* interface_addr) {
   struct sockaddr_storage addr_st;
   struct sockaddr_in* addr4;
diff --git a/Utilities/cmlibuv/src/win/util.c b/Utilities/cmlibuv/src/win/util.c
index 7ca8321..9e1e7f7 100644
--- a/Utilities/cmlibuv/src/win/util.c
+++ b/Utilities/cmlibuv/src/win/util.c
@@ -60,8 +60,8 @@
 #endif
 
 
-/* Maximum environment variable size, including the terminating null */
-#define MAX_ENV_VAR_LENGTH 32767
+/* A RtlGenRandom() by any other name... */
+extern BOOLEAN NTAPI SystemFunction036(PVOID Buffer, ULONG BufferLength);
 
 /* Cached copy of the process title, plus a mutex guarding it. */
 static char *process_title;
@@ -151,20 +151,26 @@
 
 int uv_cwd(char* buffer, size_t* size) {
   DWORD utf16_len;
-  WCHAR utf16_buffer[MAX_PATH];
+  WCHAR *utf16_buffer;
   int r;
 
   if (buffer == NULL || size == NULL) {
     return UV_EINVAL;
   }
 
-  utf16_len = GetCurrentDirectoryW(MAX_PATH, utf16_buffer);
+  utf16_len = GetCurrentDirectoryW(0, NULL);
   if (utf16_len == 0) {
     return uv_translate_sys_error(GetLastError());
-  } else if (utf16_len > MAX_PATH) {
-    /* This should be impossible; however the CRT has a code path to deal with
-     * this scenario, so I added a check anyway. */
-    return UV_EIO;
+  }
+  utf16_buffer = uv__malloc(utf16_len * sizeof(WCHAR));
+  if (utf16_buffer == NULL) {
+    return UV_ENOMEM;
+  }
+
+  utf16_len = GetCurrentDirectoryW(utf16_len, utf16_buffer);
+  if (utf16_len == 0) {
+    uv__free(utf16_buffer);
+    return uv_translate_sys_error(GetLastError());
   }
 
   /* utf16_len contains the length, *not* including the terminating null. */
@@ -188,8 +194,10 @@
                           NULL,
                           NULL);
   if (r == 0) {
+    uv__free(utf16_buffer);
     return uv_translate_sys_error(GetLastError());
   } else if (r > (int) *size) {
+    uv__free(utf16_buffer);
     *size = r;
     return UV_ENOBUFS;
   }
@@ -203,6 +211,8 @@
                           *size > INT_MAX ? INT_MAX : (int) *size,
                           NULL,
                           NULL);
+  uv__free(utf16_buffer);
+
   if (r == 0) {
     return uv_translate_sys_error(GetLastError());
   }
@@ -213,43 +223,61 @@
 
 
 int uv_chdir(const char* dir) {
-  WCHAR utf16_buffer[MAX_PATH];
-  size_t utf16_len;
+  WCHAR *utf16_buffer;
+  size_t utf16_len, new_utf16_len;
   WCHAR drive_letter, env_var[4];
 
   if (dir == NULL) {
     return UV_EINVAL;
   }
 
+  utf16_len = MultiByteToWideChar(CP_UTF8,
+                                  0,
+                                  dir,
+                                  -1,
+                                  NULL,
+                                  0);
+  if (utf16_len == 0) {
+    return uv_translate_sys_error(GetLastError());
+  }
+  utf16_buffer = uv__malloc(utf16_len * sizeof(WCHAR));
+  if (utf16_buffer == NULL) {
+    return UV_ENOMEM;
+  }
+
   if (MultiByteToWideChar(CP_UTF8,
                           0,
                           dir,
                           -1,
                           utf16_buffer,
-                          MAX_PATH) == 0) {
-    DWORD error = GetLastError();
-    /* The maximum length of the current working directory is 260 chars,
-     * including terminating null. If it doesn't fit, the path name must be too
-     * long. */
-    if (error == ERROR_INSUFFICIENT_BUFFER) {
-      return UV_ENAMETOOLONG;
-    } else {
-      return uv_translate_sys_error(error);
-    }
+                          utf16_len) == 0) {
+    uv__free(utf16_buffer);
+    return uv_translate_sys_error(GetLastError());
   }
 
   if (!SetCurrentDirectoryW(utf16_buffer)) {
+    uv__free(utf16_buffer);
     return uv_translate_sys_error(GetLastError());
   }
 
   /* Windows stores the drive-local path in an "hidden" environment variable,
    * which has the form "=C:=C:\Windows". SetCurrentDirectory does not update
    * this, so we'll have to do it. */
-  utf16_len = GetCurrentDirectoryW(MAX_PATH, utf16_buffer);
+  new_utf16_len = GetCurrentDirectoryW(utf16_len, utf16_buffer);
+  if (new_utf16_len > utf16_len ) {
+    uv__free(utf16_buffer);
+    utf16_buffer = uv__malloc(new_utf16_len * sizeof(WCHAR));
+    if (utf16_buffer == NULL) {
+      /* When updating the environment variable fails, return UV_OK anyway.
+       * We did successfully change current working directory, only updating
+       * hidden env variable failed. */
+      return 0;
+    }
+    new_utf16_len = GetCurrentDirectoryW(new_utf16_len, utf16_buffer);
+  }
   if (utf16_len == 0) {
-    return uv_translate_sys_error(GetLastError());
-  } else if (utf16_len > MAX_PATH) {
-    return UV_EIO;
+    uv__free(utf16_buffer);
+    return 0;
   }
 
   /* The returned directory should not have a trailing slash, unless it points
@@ -281,11 +309,10 @@
     env_var[2] = L':';
     env_var[3] = L'\0';
 
-    if (!SetEnvironmentVariableW(env_var, utf16_buffer)) {
-      return uv_translate_sys_error(GetLastError());
-    }
+    SetEnvironmentVariableW(env_var, utf16_buffer);
   }
 
+  uv__free(utf16_buffer);
   return 0;
 }
 
@@ -358,6 +385,10 @@
 }
 
 
+void uv__process_title_cleanup(void) {
+}
+
+
 int uv_set_process_title(const char* title) {
   int err;
   int length;
@@ -721,17 +752,6 @@
 }
 
 
-void uv_free_cpu_info(uv_cpu_info_t* cpu_infos, int count) {
-  int i;
-
-  for (i = 0; i < count; i++) {
-    uv__free(cpu_infos[i].model);
-  }
-
-  uv__free(cpu_infos);
-}
-
-
 static int is_windows_version_or_greater(DWORD os_major,
                                          DWORD os_minor,
                                          WORD service_pack_major,
@@ -1171,20 +1191,29 @@
 
 
 int uv_os_tmpdir(char* buffer, size_t* size) {
-  wchar_t path[MAX_PATH + 1];
+  wchar_t *path;
   DWORD bufsize;
   size_t len;
 
   if (buffer == NULL || size == NULL || *size == 0)
     return UV_EINVAL;
 
-  len = GetTempPathW(MAX_PATH + 1, path);
-
+  len = 0;
+  len = GetTempPathW(0, NULL);
   if (len == 0) {
     return uv_translate_sys_error(GetLastError());
-  } else if (len > MAX_PATH + 1) {
-    /* This should not be possible */
-    return UV_EIO;
+  }
+  /* Include space for terminating null char. */
+  len += 1;
+  path = uv__malloc(len * sizeof(wchar_t));
+  if (path == NULL) {
+    return UV_ENOMEM;
+  }
+  len  = GetTempPathW(len, path);
+
+  if (len == 0) {
+    uv__free(path);
+    return uv_translate_sys_error(GetLastError());
   }
 
   /* The returned directory should not have a trailing slash, unless it points
@@ -1199,8 +1228,10 @@
   bufsize = WideCharToMultiByte(CP_UTF8, 0, path, -1, NULL, 0, NULL, NULL);
 
   if (bufsize == 0) {
+    uv__free(path);
     return uv_translate_sys_error(GetLastError());
   } else if (bufsize > *size) {
+    uv__free(path);
     *size = bufsize;
     return UV_ENOBUFS;
   }
@@ -1214,6 +1245,7 @@
                                 *size,
                                 NULL,
                                 NULL);
+  uv__free(path);
 
   if (bufsize == 0)
     return uv_translate_sys_error(GetLastError());
@@ -1325,7 +1357,7 @@
     return uv_translate_sys_error(GetLastError());
   }
 
-  (*utf16)[bufsize] = '\0';
+  (*utf16)[bufsize] = L'\0';
   return 0;
 }
 
@@ -1333,7 +1365,7 @@
 int uv__getpwuid_r(uv_passwd_t* pwd) {
   HANDLE token;
   wchar_t username[UNLEN + 1];
-  wchar_t path[MAX_PATH];
+  wchar_t *path;
   DWORD bufsize;
   int r;
 
@@ -1344,15 +1376,24 @@
   if (OpenProcessToken(GetCurrentProcess(), TOKEN_READ, &token) == 0)
     return uv_translate_sys_error(GetLastError());
 
-  bufsize = ARRAY_SIZE(path);
+  bufsize = 0;
+  GetUserProfileDirectoryW(token, NULL, &bufsize);
+  if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
+    r = GetLastError();
+    CloseHandle(token);
+    return uv_translate_sys_error(r);
+  }
+
+  path = uv__malloc(bufsize * sizeof(wchar_t));
+  if (path == NULL) {
+    CloseHandle(token);
+    return UV_ENOMEM;
+  }
+
   if (!GetUserProfileDirectoryW(token, path, &bufsize)) {
     r = GetLastError();
     CloseHandle(token);
-
-    /* This should not be possible */
-    if (r == ERROR_INSUFFICIENT_BUFFER)
-      return UV_ENOMEM;
-
+    uv__free(path);
     return uv_translate_sys_error(r);
   }
 
@@ -1362,6 +1403,7 @@
   bufsize = ARRAY_SIZE(username);
   if (!GetUserNameW(username, &bufsize)) {
     r = GetLastError();
+    uv__free(path);
 
     /* This should not be possible */
     if (r == ERROR_INSUFFICIENT_BUFFER)
@@ -1372,6 +1414,7 @@
 
   pwd->homedir = NULL;
   r = uv__convert_utf16_to_utf8(path, -1, &pwd->homedir);
+  uv__free(path);
 
   if (r != 0)
     return r;
@@ -1397,8 +1440,81 @@
 }
 
 
+int uv_os_environ(uv_env_item_t** envitems, int* count) {
+  wchar_t* env;
+  wchar_t* penv;
+  int i, cnt;
+  uv_env_item_t* envitem;
+
+  *envitems = NULL;
+  *count = 0;
+
+  env = GetEnvironmentStringsW();
+  if (env == NULL)
+    return 0;
+
+  for (penv = env, i = 0; *penv != L'\0'; penv += wcslen(penv) + 1, i++);
+
+  *envitems = uv__calloc(i, sizeof(**envitems));
+  if (*envitems == NULL) {
+    FreeEnvironmentStringsW(env);
+    return UV_ENOMEM;
+  }
+
+  penv = env;
+  cnt = 0;
+
+  while (*penv != L'\0' && cnt < i) {
+    char* buf;
+    char* ptr;
+
+    if (uv__convert_utf16_to_utf8(penv, -1, &buf) != 0)
+      goto fail;
+
+    /* Using buf + 1 here because we know that `buf` has length at least 1,
+     * and some special environment variables on Windows start with a = sign. */
+    ptr = strchr(buf + 1, '=');
+    if (ptr == NULL) {
+      uv__free(buf);
+      goto do_continue;
+    }
+
+    *ptr = '\0';
+
+    envitem = &(*envitems)[cnt];
+    envitem->name = buf;
+    envitem->value = ptr + 1;
+
+    cnt++;
+
+  do_continue:
+    penv += wcslen(penv) + 1;
+  }
+
+  FreeEnvironmentStringsW(env);
+
+  *count = cnt;
+  return 0;
+
+fail:
+  FreeEnvironmentStringsW(env);
+
+  for (i = 0; i < cnt; i++) {
+    envitem = &(*envitems)[cnt];
+    uv__free(envitem->name);
+  }
+  uv__free(*envitems);
+
+  *envitems = NULL;
+  *count = 0;
+  return UV_ENOMEM;
+}
+
+
 int uv_os_getenv(const char* name, char* buffer, size_t* size) {
-  wchar_t var[MAX_ENV_VAR_LENGTH];
+  wchar_t fastvar[512];
+  wchar_t* var;
+  DWORD varlen;
   wchar_t* name_w;
   DWORD bufsize;
   size_t len;
@@ -1412,27 +1528,52 @@
   if (r != 0)
     return r;
 
-  len = GetEnvironmentVariableW(name_w, var, MAX_ENV_VAR_LENGTH);
+  var = fastvar;
+  varlen = ARRAY_SIZE(fastvar);
+
+  for (;;) {
+    SetLastError(ERROR_SUCCESS);
+    len = GetEnvironmentVariableW(name_w, var, varlen);
+
+    if (len < varlen)
+      break;
+
+    /* Try repeatedly because we might have been preempted by another thread
+     * modifying the environment variable just as we're trying to read it.
+     */
+    if (var != fastvar)
+      uv__free(var);
+
+    varlen = 1 + len;
+    var = uv__malloc(varlen * sizeof(*var));
+
+    if (var == NULL) {
+      r = UV_ENOMEM;
+      goto fail;
+    }
+  }
+
   uv__free(name_w);
-  assert(len < MAX_ENV_VAR_LENGTH); /* len does not include the null */
+  name_w = NULL;
 
   if (len == 0) {
     r = GetLastError();
-
-    if (r == ERROR_ENVVAR_NOT_FOUND)
-      return UV_ENOENT;
-
-    return uv_translate_sys_error(r);
+    if (r != ERROR_SUCCESS) {
+      r = uv_translate_sys_error(r);
+      goto fail;
+    }
   }
 
   /* Check how much space we need */
   bufsize = WideCharToMultiByte(CP_UTF8, 0, var, -1, NULL, 0, NULL, NULL);
 
   if (bufsize == 0) {
-    return uv_translate_sys_error(GetLastError());
+    r = uv_translate_sys_error(GetLastError());
+    goto fail;
   } else if (bufsize > *size) {
     *size = bufsize;
-    return UV_ENOBUFS;
+    r = UV_ENOBUFS;
+    goto fail;
   }
 
   /* Convert to UTF-8 */
@@ -1445,11 +1586,23 @@
                                 NULL,
                                 NULL);
 
-  if (bufsize == 0)
-    return uv_translate_sys_error(GetLastError());
+  if (bufsize == 0) {
+    r = uv_translate_sys_error(GetLastError());
+    goto fail;
+  }
 
   *size = bufsize - 1;
-  return 0;
+  r = 0;
+
+fail:
+
+  if (name_w != NULL)
+    uv__free(name_w);
+
+  if (var != fastvar)
+    uv__free(var);
+
+  return r;
 }
 
 
@@ -1802,3 +1955,17 @@
   tv->tv_usec = (int32_t) (((ularge.QuadPart - epoch) % 10000000L) / 10);
   return 0;
 }
+
+int uv__random_rtlgenrandom(void* buf, size_t buflen) {
+  if (buflen == 0)
+    return 0;
+
+  if (SystemFunction036(buf, buflen) == FALSE)
+    return UV_EIO;
+
+  return 0;
+}
+
+void uv_sleep(unsigned int msec) {
+  Sleep(msec);
+}
diff --git a/Utilities/cmlibuv/src/win/winapi.c b/Utilities/cmlibuv/src/win/winapi.c
index fbbbcee..bb86ec8 100644
--- a/Utilities/cmlibuv/src/win/winapi.c
+++ b/Utilities/cmlibuv/src/win/winapi.c
@@ -34,6 +34,7 @@
 sNtQueryVolumeInformationFile pNtQueryVolumeInformationFile;
 sNtQueryDirectoryFile pNtQueryDirectoryFile;
 sNtQuerySystemInformation pNtQuerySystemInformation;
+sNtQueryInformationProcess pNtQueryInformationProcess;
 
 /* Kernel32 function pointers */
 sGetQueuedCompletionStatusEx pGetQueuedCompletionStatusEx;
@@ -106,6 +107,13 @@
     uv_fatal_error(GetLastError(), "GetProcAddress");
   }
 
+  pNtQueryInformationProcess = (sNtQueryInformationProcess) GetProcAddress(
+      ntdll_module,
+      "NtQueryInformationProcess");
+  if (pNtQueryInformationProcess == NULL) {
+    uv_fatal_error(GetLastError(), "GetProcAddress");
+  }
+
   kernel32_module = GetModuleHandleA("kernel32.dll");
   if (kernel32_module == NULL) {
     uv_fatal_error(GetLastError(), "GetModuleHandleA");
@@ -126,5 +134,4 @@
     pSetWinEventHook = (sSetWinEventHook)
       GetProcAddress(user32_module, "SetWinEventHook");
   }
-
 }
diff --git a/Utilities/cmlibuv/src/win/winapi.h b/Utilities/cmlibuv/src/win/winapi.h
index 1e49b57..77f1878 100644
--- a/Utilities/cmlibuv/src/win/winapi.h
+++ b/Utilities/cmlibuv/src/win/winapi.h
@@ -4109,7 +4109,7 @@
 #endif
 
 /* from winternl.h */
-#if !defined(__UNICODE_STRING_DEFINED) && defined(__MINGW32_)
+#if !defined(__UNICODE_STRING_DEFINED) && defined(__MINGW32__)
 #define __UNICODE_STRING_DEFINED
 #endif
 typedef struct _UNICODE_STRING {
@@ -4160,6 +4160,10 @@
       struct {
         UCHAR  DataBuffer[1];
       } GenericReparseBuffer;
+      struct {
+        ULONG StringCount;
+        WCHAR StringList[1];
+      } AppExecLinkReparseBuffer;
     };
   } REPARSE_DATA_BUFFER, *PREPARSE_DATA_BUFFER;
 #endif
@@ -4444,6 +4448,10 @@
 # define SystemProcessorPerformanceInformation 8
 #endif
 
+#ifndef ProcessConsoleHostProcess
+# define ProcessConsoleHostProcess 49
+#endif
+
 #ifndef FILE_DEVICE_FILE_SYSTEM
 # define FILE_DEVICE_FILE_SYSTEM 0x00000009
 #endif
@@ -4521,6 +4529,9 @@
 #ifndef IO_REPARSE_TAG_SYMLINK
 # define IO_REPARSE_TAG_SYMLINK (0xA000000CL)
 #endif
+#ifndef IO_REPARSE_TAG_APPEXECLINK
+# define IO_REPARSE_TAG_APPEXECLINK (0x8000001BL)
+#endif
 
 typedef VOID (NTAPI *PIO_APC_ROUTINE)
              (PVOID ApcContext,
@@ -4586,6 +4597,13 @@
                   BOOLEAN RestartScan
                 );
 
+typedef NTSTATUS (NTAPI *sNtQueryInformationProcess)
+                 (HANDLE ProcessHandle,
+                  UINT ProcessInformationClass,
+                  PVOID ProcessInformation,
+                  ULONG Length,
+                  PULONG ReturnLength);
+
 /*
  * Kernel32 headers
  */
@@ -4727,6 +4745,7 @@
 extern sNtQueryVolumeInformationFile pNtQueryVolumeInformationFile;
 extern sNtQueryDirectoryFile pNtQueryDirectoryFile;
 extern sNtQuerySystemInformation pNtQuerySystemInformation;
+extern sNtQueryInformationProcess pNtQueryInformationProcess;
 
 /* Kernel32 function pointers */
 extern sGetQueuedCompletionStatusEx pGetQueuedCompletionStatusEx;
diff --git a/Utilities/cmlibuv/src/win/winsock.c b/Utilities/cmlibuv/src/win/winsock.c
index 5820ba9..4cf6e6b 100644
--- a/Utilities/cmlibuv/src/win/winsock.c
+++ b/Utilities/cmlibuv/src/win/winsock.c
@@ -74,11 +74,6 @@
 }
 
 
-static int error_means_no_support(DWORD error) {
-  return error == WSAEPROTONOSUPPORT || error == WSAESOCKTNOSUPPORT ||
-         error == WSAEPFNOSUPPORT || error == WSAEAFNOSUPPORT;
-}
-
 
 void uv_winsock_init(void) {
   WSADATA wsa_data;
@@ -105,50 +100,36 @@
     uv_fatal_error(errorno, "WSAStartup");
   }
 
-  /* Detect non-IFS LSPs */
+  /* Try to detect non-IFS LSPs */
+  uv_tcp_non_ifs_lsp_ipv4 = 1;
   dummy = socket(AF_INET, SOCK_STREAM, IPPROTO_IP);
-
   if (dummy != INVALID_SOCKET) {
     opt_len = (int) sizeof protocol_info;
     if (getsockopt(dummy,
                    SOL_SOCKET,
                    SO_PROTOCOL_INFOW,
                    (char*) &protocol_info,
-                   &opt_len) == SOCKET_ERROR)
-      uv_fatal_error(WSAGetLastError(), "getsockopt");
-
-    if (!(protocol_info.dwServiceFlags1 & XP1_IFS_HANDLES))
-      uv_tcp_non_ifs_lsp_ipv4 = 1;
-
-    if (closesocket(dummy) == SOCKET_ERROR)
-      uv_fatal_error(WSAGetLastError(), "closesocket");
-
-  } else if (!error_means_no_support(WSAGetLastError())) {
-    /* Any error other than "socket type not supported" is fatal. */
-    uv_fatal_error(WSAGetLastError(), "socket");
+                   &opt_len) == 0) {
+      if (protocol_info.dwServiceFlags1 & XP1_IFS_HANDLES)
+        uv_tcp_non_ifs_lsp_ipv4 = 0;
+    }
+    closesocket(dummy);
   }
 
-  /* Detect IPV6 support and non-IFS LSPs */
+  /* Try to detect IPV6 support and non-IFS LSPs */
+  uv_tcp_non_ifs_lsp_ipv6 = 1;
   dummy = socket(AF_INET6, SOCK_STREAM, IPPROTO_IP);
-
   if (dummy != INVALID_SOCKET) {
     opt_len = (int) sizeof protocol_info;
     if (getsockopt(dummy,
                    SOL_SOCKET,
                    SO_PROTOCOL_INFOW,
                    (char*) &protocol_info,
-                   &opt_len) == SOCKET_ERROR)
-      uv_fatal_error(WSAGetLastError(), "getsockopt");
-
-    if (!(protocol_info.dwServiceFlags1 & XP1_IFS_HANDLES))
-      uv_tcp_non_ifs_lsp_ipv6 = 1;
-
-    if (closesocket(dummy) == SOCKET_ERROR)
-      uv_fatal_error(WSAGetLastError(), "closesocket");
-
-  } else if (!error_means_no_support(WSAGetLastError())) {
-    /* Any error other than "socket type not supported" is fatal. */
-    uv_fatal_error(WSAGetLastError(), "socket");
+                   &opt_len) == 0) {
+      if (protocol_info.dwServiceFlags1 & XP1_IFS_HANDLES)
+        uv_tcp_non_ifs_lsp_ipv6 = 0;
+    }
+    closesocket(dummy);
   }
 }
 
diff --git a/Utilities/cmlibuv/src/win/winsock.h b/Utilities/cmlibuv/src/win/winsock.h
index e8b274e..153632c 100644
--- a/Utilities/cmlibuv/src/win/winsock.h
+++ b/Utilities/cmlibuv/src/win/winsock.h
@@ -54,6 +54,14 @@
 # define SIO_BASE_HANDLE 0x48000022
 #endif
 
+#ifndef MCAST_JOIN_SOURCE_GROUP
+# define MCAST_JOIN_SOURCE_GROUP 45
+#endif
+
+#ifndef MCAST_LEAVE_SOURCE_GROUP
+# define MCAST_LEAVE_SOURCE_GROUP 46
+#endif
+
 /*
  * TDI defines that are only in the DDK.
  * We only need receive flags so far.
diff --git a/Utilities/cmnghttp2/.gitattributes b/Utilities/cmnghttp2/.gitattributes
new file mode 100644
index 0000000..562b12e
--- /dev/null
+++ b/Utilities/cmnghttp2/.gitattributes
@@ -0,0 +1 @@
+* -whitespace
diff --git a/Utilities/cmnghttp2/CMakeLists.txt b/Utilities/cmnghttp2/CMakeLists.txt
new file mode 100644
index 0000000..3a11ace
--- /dev/null
+++ b/Utilities/cmnghttp2/CMakeLists.txt
@@ -0,0 +1,52 @@
+# Disable warnings to avoid changing 3rd party code.
+if(CMAKE_C_COMPILER_ID MATCHES
+    "^(GNU|Clang|AppleClang|XLClang|XL|VisualAge|SunPro|HP|Intel)$")
+  set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -w")
+elseif(CMAKE_C_COMPILER_ID STREQUAL "PathScale")
+  set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -woffall")
+endif()
+
+# Re-use some check result cache entries from cmcurl:
+# * HAVE_ARPA_INET_H
+# * HAVE_NETINET_IN_H
+# * HAVE_SSIZE_T
+if(NOT HAVE_SSIZE_T)
+  set(ssize_t KWIML_INT_intptr_t)
+endif()
+configure_file(cmakeconfig.h.in config.h)
+
+add_library(cmnghttp2 STATIC
+  lib/nghttp2_buf.c
+  lib/nghttp2_callbacks.c
+  lib/nghttp2_debug.c
+  lib/nghttp2_frame.c
+  lib/nghttp2_hd.c
+  lib/nghttp2_hd_huffman.c
+  lib/nghttp2_hd_huffman_data.c
+  lib/nghttp2_helper.c
+  lib/nghttp2_http.c
+  lib/nghttp2_map.c
+  lib/nghttp2_mem.c
+  lib/nghttp2_npn.c
+  lib/nghttp2_option.c
+  lib/nghttp2_outbound_item.c
+  lib/nghttp2_pq.c
+  lib/nghttp2_priority_spec.c
+  lib/nghttp2_queue.c
+  lib/nghttp2_rcbuf.c
+  lib/nghttp2_session.c
+  lib/nghttp2_stream.c
+  lib/nghttp2_submit.c
+  lib/nghttp2_version.c
+  )
+
+target_compile_definitions(cmnghttp2
+  PUBLIC NGHTTP2_STATICLIB
+  PRIVATE HAVE_CONFIG_H
+  )
+target_include_directories(cmnghttp2 PRIVATE
+  ${CMAKE_CURRENT_BINARY_DIR}
+  ${CMAKE_CURRENT_SOURCE_DIR}/lib/includes
+  )
+
+install(FILES COPYING DESTINATION ${CMAKE_DOC_DIR}/cmnghttp2)
diff --git a/Utilities/cmnghttp2/COPYING b/Utilities/cmnghttp2/COPYING
new file mode 100644
index 0000000..8020179
--- /dev/null
+++ b/Utilities/cmnghttp2/COPYING
@@ -0,0 +1,23 @@
+The MIT License
+
+Copyright (c) 2012, 2014, 2015, 2016 Tatsuhiro Tsujikawa
+Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/Utilities/cmnghttp2/cmakeconfig.h.in b/Utilities/cmnghttp2/cmakeconfig.h.in
new file mode 100644
index 0000000..60698fb
--- /dev/null
+++ b/Utilities/cmnghttp2/cmakeconfig.h.in
@@ -0,0 +1,18 @@
+#if defined(_MSC_VER)
+# pragma warning(push,1)
+#endif
+
+#include <cm3p/kwiml/abi.h>
+#include <cm3p/kwiml/int.h>
+
+/* Define to `int' if <sys/types.h> does not define. */
+#cmakedefine ssize_t @ssize_t@
+
+/* sizeof(int *) */
+#define SIZEOF_INT_P KWIML_ABI_SIZEOF_DATA_PTR
+
+/* Define to 1 if you have the <arpa/inet.h> header file. */
+#cmakedefine HAVE_ARPA_INET_H 1
+
+/* Define to 1 if you have the <netinet/in.h> header file. */
+#cmakedefine HAVE_NETINET_IN_H 1
diff --git a/Utilities/cmnghttp2/lib/includes/nghttp2/nghttp2.h b/Utilities/cmnghttp2/lib/includes/nghttp2/nghttp2.h
new file mode 100644
index 0000000..e3aeb9f
--- /dev/null
+++ b/Utilities/cmnghttp2/lib/includes/nghttp2/nghttp2.h
@@ -0,0 +1,5487 @@
+/*
+ * nghttp2 - HTTP/2 C Library
+ *
+ * Copyright (c) 2013, 2014 Tatsuhiro Tsujikawa
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+#ifndef NGHTTP2_H
+#define NGHTTP2_H
+
+/* Define WIN32 when build target is Win32 API (borrowed from
+   libcurl) */
+#if (defined(_WIN32) || defined(__WIN32__)) && !defined(WIN32)
+#  define WIN32
+#endif
+
+/* Compatibility for non-Clang compilers */
+#ifndef __has_declspec_attribute
+#  define __has_declspec_attribute(x) 0
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdlib.h>
+#if defined(_MSC_VER) && (_MSC_VER < 1800)
+/* MSVC < 2013 does not have inttypes.h because it is not C99
+   compliant.  See compiler macros and version number in
+   https://sourceforge.net/p/predef/wiki/Compilers/ */
+#  include <stdint.h>
+#else /* !defined(_MSC_VER) || (_MSC_VER >= 1800) */
+#  include <inttypes.h>
+#endif /* !defined(_MSC_VER) || (_MSC_VER >= 1800) */
+#include <sys/types.h>
+#include <stdarg.h>
+
+#include <nghttp2/nghttp2ver.h>
+
+#ifdef NGHTTP2_STATICLIB
+#  define NGHTTP2_EXTERN
+#elif defined(WIN32) || (__has_declspec_attribute(dllexport) &&                \
+                         __has_declspec_attribute(dllimport))
+#  ifdef BUILDING_NGHTTP2
+#    define NGHTTP2_EXTERN __declspec(dllexport)
+#  else /* !BUILDING_NGHTTP2 */
+#    define NGHTTP2_EXTERN __declspec(dllimport)
+#  endif /* !BUILDING_NGHTTP2 */
+#else    /* !defined(WIN32) */
+#  ifdef BUILDING_NGHTTP2
+#    define NGHTTP2_EXTERN __attribute__((visibility("default")))
+#  else /* !BUILDING_NGHTTP2 */
+#    define NGHTTP2_EXTERN
+#  endif /* !BUILDING_NGHTTP2 */
+#endif   /* !defined(WIN32) */
+
+/**
+ * @macro
+ *
+ * The protocol version identification string of this library
+ * supports.  This identifier is used if HTTP/2 is used over TLS.
+ */
+#define NGHTTP2_PROTO_VERSION_ID "h2"
+/**
+ * @macro
+ *
+ * The length of :macro:`NGHTTP2_PROTO_VERSION_ID`.
+ */
+#define NGHTTP2_PROTO_VERSION_ID_LEN 2
+
+/**
+ * @macro
+ *
+ * The serialized form of ALPN protocol identifier this library
+ * supports.  Notice that first byte is the length of following
+ * protocol identifier.  This is the same wire format of `TLS ALPN
+ * extension <https://tools.ietf.org/html/rfc7301>`_.  This is useful
+ * to process incoming ALPN tokens in wire format.
+ */
+#define NGHTTP2_PROTO_ALPN "\x2h2"
+
+/**
+ * @macro
+ *
+ * The length of :macro:`NGHTTP2_PROTO_ALPN`.
+ */
+#define NGHTTP2_PROTO_ALPN_LEN (sizeof(NGHTTP2_PROTO_ALPN) - 1)
+
+/**
+ * @macro
+ *
+ * The protocol version identification string of this library
+ * supports.  This identifier is used if HTTP/2 is used over cleartext
+ * TCP.
+ */
+#define NGHTTP2_CLEARTEXT_PROTO_VERSION_ID "h2c"
+
+/**
+ * @macro
+ *
+ * The length of :macro:`NGHTTP2_CLEARTEXT_PROTO_VERSION_ID`.
+ */
+#define NGHTTP2_CLEARTEXT_PROTO_VERSION_ID_LEN 3
+
+struct nghttp2_session;
+/**
+ * @struct
+ *
+ * The primary structure to hold the resources needed for a HTTP/2
+ * session.  The details of this structure are intentionally hidden
+ * from the public API.
+ */
+typedef struct nghttp2_session nghttp2_session;
+
+/**
+ * @macro
+ *
+ * The age of :type:`nghttp2_info`
+ */
+#define NGHTTP2_VERSION_AGE 1
+
+/**
+ * @struct
+ *
+ * This struct is what `nghttp2_version()` returns.  It holds
+ * information about the particular nghttp2 version.
+ */
+typedef struct {
+  /**
+   * Age of this struct.  This instance of nghttp2 sets it to
+   * :macro:`NGHTTP2_VERSION_AGE` but a future version may bump it and
+   * add more struct fields at the bottom
+   */
+  int age;
+  /**
+   * the :macro:`NGHTTP2_VERSION_NUM` number (since age ==1)
+   */
+  int version_num;
+  /**
+   * points to the :macro:`NGHTTP2_VERSION` string (since age ==1)
+   */
+  const char *version_str;
+  /**
+   * points to the :macro:`NGHTTP2_PROTO_VERSION_ID` string this
+   * instance implements (since age ==1)
+   */
+  const char *proto_str;
+  /* -------- the above fields all exist when age == 1 */
+} nghttp2_info;
+
+/**
+ * @macro
+ *
+ * The default weight of stream dependency.
+ */
+#define NGHTTP2_DEFAULT_WEIGHT 16
+
+/**
+ * @macro
+ *
+ * The maximum weight of stream dependency.
+ */
+#define NGHTTP2_MAX_WEIGHT 256
+
+/**
+ * @macro
+ *
+ * The minimum weight of stream dependency.
+ */
+#define NGHTTP2_MIN_WEIGHT 1
+
+/**
+ * @macro
+ *
+ * The maximum window size
+ */
+#define NGHTTP2_MAX_WINDOW_SIZE ((int32_t)((1U << 31) - 1))
+
+/**
+ * @macro
+ *
+ * The initial window size for stream level flow control.
+ */
+#define NGHTTP2_INITIAL_WINDOW_SIZE ((1 << 16) - 1)
+/**
+ * @macro
+ *
+ * The initial window size for connection level flow control.
+ */
+#define NGHTTP2_INITIAL_CONNECTION_WINDOW_SIZE ((1 << 16) - 1)
+
+/**
+ * @macro
+ *
+ * The default header table size.
+ */
+#define NGHTTP2_DEFAULT_HEADER_TABLE_SIZE (1 << 12)
+
+/**
+ * @macro
+ *
+ * The client magic string, which is the first 24 bytes byte string of
+ * client connection preface.
+ */
+#define NGHTTP2_CLIENT_MAGIC "PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n"
+
+/**
+ * @macro
+ *
+ * The length of :macro:`NGHTTP2_CLIENT_MAGIC`.
+ */
+#define NGHTTP2_CLIENT_MAGIC_LEN 24
+
+/**
+ * @enum
+ *
+ * Error codes used in this library.  The code range is [-999, -500],
+ * inclusive. The following values are defined:
+ */
+typedef enum {
+  /**
+   * Invalid argument passed.
+   */
+  NGHTTP2_ERR_INVALID_ARGUMENT = -501,
+  /**
+   * Out of buffer space.
+   */
+  NGHTTP2_ERR_BUFFER_ERROR = -502,
+  /**
+   * The specified protocol version is not supported.
+   */
+  NGHTTP2_ERR_UNSUPPORTED_VERSION = -503,
+  /**
+   * Used as a return value from :type:`nghttp2_send_callback`,
+   * :type:`nghttp2_recv_callback` and
+   * :type:`nghttp2_send_data_callback` to indicate that the operation
+   * would block.
+   */
+  NGHTTP2_ERR_WOULDBLOCK = -504,
+  /**
+   * General protocol error
+   */
+  NGHTTP2_ERR_PROTO = -505,
+  /**
+   * The frame is invalid.
+   */
+  NGHTTP2_ERR_INVALID_FRAME = -506,
+  /**
+   * The peer performed a shutdown on the connection.
+   */
+  NGHTTP2_ERR_EOF = -507,
+  /**
+   * Used as a return value from
+   * :func:`nghttp2_data_source_read_callback` to indicate that data
+   * transfer is postponed.  See
+   * :func:`nghttp2_data_source_read_callback` for details.
+   */
+  NGHTTP2_ERR_DEFERRED = -508,
+  /**
+   * Stream ID has reached the maximum value.  Therefore no stream ID
+   * is available.
+   */
+  NGHTTP2_ERR_STREAM_ID_NOT_AVAILABLE = -509,
+  /**
+   * The stream is already closed; or the stream ID is invalid.
+   */
+  NGHTTP2_ERR_STREAM_CLOSED = -510,
+  /**
+   * RST_STREAM has been added to the outbound queue.  The stream is
+   * in closing state.
+   */
+  NGHTTP2_ERR_STREAM_CLOSING = -511,
+  /**
+   * The transmission is not allowed for this stream (e.g., a frame
+   * with END_STREAM flag set has already sent).
+   */
+  NGHTTP2_ERR_STREAM_SHUT_WR = -512,
+  /**
+   * The stream ID is invalid.
+   */
+  NGHTTP2_ERR_INVALID_STREAM_ID = -513,
+  /**
+   * The state of the stream is not valid (e.g., DATA cannot be sent
+   * to the stream if response HEADERS has not been sent).
+   */
+  NGHTTP2_ERR_INVALID_STREAM_STATE = -514,
+  /**
+   * Another DATA frame has already been deferred.
+   */
+  NGHTTP2_ERR_DEFERRED_DATA_EXIST = -515,
+  /**
+   * Starting new stream is not allowed (e.g., GOAWAY has been sent
+   * and/or received).
+   */
+  NGHTTP2_ERR_START_STREAM_NOT_ALLOWED = -516,
+  /**
+   * GOAWAY has already been sent.
+   */
+  NGHTTP2_ERR_GOAWAY_ALREADY_SENT = -517,
+  /**
+   * The received frame contains the invalid header block (e.g., There
+   * are duplicate header names; or the header names are not encoded
+   * in US-ASCII character set and not lower cased; or the header name
+   * is zero-length string; or the header value contains multiple
+   * in-sequence NUL bytes).
+   */
+  NGHTTP2_ERR_INVALID_HEADER_BLOCK = -518,
+  /**
+   * Indicates that the context is not suitable to perform the
+   * requested operation.
+   */
+  NGHTTP2_ERR_INVALID_STATE = -519,
+  /**
+   * The user callback function failed due to the temporal error.
+   */
+  NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE = -521,
+  /**
+   * The length of the frame is invalid, either too large or too small.
+   */
+  NGHTTP2_ERR_FRAME_SIZE_ERROR = -522,
+  /**
+   * Header block inflate/deflate error.
+   */
+  NGHTTP2_ERR_HEADER_COMP = -523,
+  /**
+   * Flow control error
+   */
+  NGHTTP2_ERR_FLOW_CONTROL = -524,
+  /**
+   * Insufficient buffer size given to function.
+   */
+  NGHTTP2_ERR_INSUFF_BUFSIZE = -525,
+  /**
+   * Callback was paused by the application
+   */
+  NGHTTP2_ERR_PAUSE = -526,
+  /**
+   * There are too many in-flight SETTING frame and no more
+   * transmission of SETTINGS is allowed.
+   */
+  NGHTTP2_ERR_TOO_MANY_INFLIGHT_SETTINGS = -527,
+  /**
+   * The server push is disabled.
+   */
+  NGHTTP2_ERR_PUSH_DISABLED = -528,
+  /**
+   * DATA or HEADERS frame for a given stream has been already
+   * submitted and has not been fully processed yet.  Application
+   * should wait for the transmission of the previously submitted
+   * frame before submitting another.
+   */
+  NGHTTP2_ERR_DATA_EXIST = -529,
+  /**
+   * The current session is closing due to a connection error or
+   * `nghttp2_session_terminate_session()` is called.
+   */
+  NGHTTP2_ERR_SESSION_CLOSING = -530,
+  /**
+   * Invalid HTTP header field was received and stream is going to be
+   * closed.
+   */
+  NGHTTP2_ERR_HTTP_HEADER = -531,
+  /**
+   * Violation in HTTP messaging rule.
+   */
+  NGHTTP2_ERR_HTTP_MESSAGING = -532,
+  /**
+   * Stream was refused.
+   */
+  NGHTTP2_ERR_REFUSED_STREAM = -533,
+  /**
+   * Unexpected internal error, but recovered.
+   */
+  NGHTTP2_ERR_INTERNAL = -534,
+  /**
+   * Indicates that a processing was canceled.
+   */
+  NGHTTP2_ERR_CANCEL = -535,
+  /**
+   * When a local endpoint expects to receive SETTINGS frame, it
+   * receives an other type of frame.
+   */
+  NGHTTP2_ERR_SETTINGS_EXPECTED = -536,
+  /**
+   * The errors < :enum:`NGHTTP2_ERR_FATAL` mean that the library is
+   * under unexpected condition and processing was terminated (e.g.,
+   * out of memory).  If application receives this error code, it must
+   * stop using that :type:`nghttp2_session` object and only allowed
+   * operation for that object is deallocate it using
+   * `nghttp2_session_del()`.
+   */
+  NGHTTP2_ERR_FATAL = -900,
+  /**
+   * Out of memory.  This is a fatal error.
+   */
+  NGHTTP2_ERR_NOMEM = -901,
+  /**
+   * The user callback function failed.  This is a fatal error.
+   */
+  NGHTTP2_ERR_CALLBACK_FAILURE = -902,
+  /**
+   * Invalid client magic (see :macro:`NGHTTP2_CLIENT_MAGIC`) was
+   * received and further processing is not possible.
+   */
+  NGHTTP2_ERR_BAD_CLIENT_MAGIC = -903,
+  /**
+   * Possible flooding by peer was detected in this HTTP/2 session.
+   * Flooding is measured by how many PING and SETTINGS frames with
+   * ACK flag set are queued for transmission.  These frames are
+   * response for the peer initiated frames, and peer can cause memory
+   * exhaustion on server side to send these frames forever and does
+   * not read network.
+   */
+  NGHTTP2_ERR_FLOODED = -904
+} nghttp2_error;
+
+/**
+ * @struct
+ *
+ * The object representing single contiguous buffer.
+ */
+typedef struct {
+  /**
+   * The pointer to the buffer.
+   */
+  uint8_t *base;
+  /**
+   * The length of the buffer.
+   */
+  size_t len;
+} nghttp2_vec;
+
+struct nghttp2_rcbuf;
+
+/**
+ * @struct
+ *
+ * The object representing reference counted buffer.  The details of
+ * this structure are intentionally hidden from the public API.
+ */
+typedef struct nghttp2_rcbuf nghttp2_rcbuf;
+
+/**
+ * @function
+ *
+ * Increments the reference count of |rcbuf| by 1.
+ */
+NGHTTP2_EXTERN void nghttp2_rcbuf_incref(nghttp2_rcbuf *rcbuf);
+
+/**
+ * @function
+ *
+ * Decrements the reference count of |rcbuf| by 1.  If the reference
+ * count becomes zero, the object pointed by |rcbuf| will be freed.
+ * In this case, application must not use |rcbuf| again.
+ */
+NGHTTP2_EXTERN void nghttp2_rcbuf_decref(nghttp2_rcbuf *rcbuf);
+
+/**
+ * @function
+ *
+ * Returns the underlying buffer managed by |rcbuf|.
+ */
+NGHTTP2_EXTERN nghttp2_vec nghttp2_rcbuf_get_buf(nghttp2_rcbuf *rcbuf);
+
+/**
+ * @function
+ *
+ * Returns nonzero if the underlying buffer is statically allocated,
+ * and 0 otherwise. This can be useful for language bindings that wish
+ * to avoid creating duplicate strings for these buffers.
+ */
+NGHTTP2_EXTERN int nghttp2_rcbuf_is_static(const nghttp2_rcbuf *rcbuf);
+
+/**
+ * @enum
+ *
+ * The flags for header field name/value pair.
+ */
+typedef enum {
+  /**
+   * No flag set.
+   */
+  NGHTTP2_NV_FLAG_NONE = 0,
+  /**
+   * Indicates that this name/value pair must not be indexed ("Literal
+   * Header Field never Indexed" representation must be used in HPACK
+   * encoding).  Other implementation calls this bit as "sensitive".
+   */
+  NGHTTP2_NV_FLAG_NO_INDEX = 0x01,
+  /**
+   * This flag is set solely by application.  If this flag is set, the
+   * library does not make a copy of header field name.  This could
+   * improve performance.
+   */
+  NGHTTP2_NV_FLAG_NO_COPY_NAME = 0x02,
+  /**
+   * This flag is set solely by application.  If this flag is set, the
+   * library does not make a copy of header field value.  This could
+   * improve performance.
+   */
+  NGHTTP2_NV_FLAG_NO_COPY_VALUE = 0x04
+} nghttp2_nv_flag;
+
+/**
+ * @struct
+ *
+ * The name/value pair, which mainly used to represent header fields.
+ */
+typedef struct {
+  /**
+   * The |name| byte string.  If this struct is presented from library
+   * (e.g., :type:`nghttp2_on_frame_recv_callback`), |name| is
+   * guaranteed to be NULL-terminated.  For some callbacks
+   * (:type:`nghttp2_before_frame_send_callback`,
+   * :type:`nghttp2_on_frame_send_callback`, and
+   * :type:`nghttp2_on_frame_not_send_callback`), it may not be
+   * NULL-terminated if header field is passed from application with
+   * the flag :enum:`NGHTTP2_NV_FLAG_NO_COPY_NAME`).  When application
+   * is constructing this struct, |name| is not required to be
+   * NULL-terminated.
+   */
+  uint8_t *name;
+  /**
+   * The |value| byte string.  If this struct is presented from
+   * library (e.g., :type:`nghttp2_on_frame_recv_callback`), |value|
+   * is guaranteed to be NULL-terminated.  For some callbacks
+   * (:type:`nghttp2_before_frame_send_callback`,
+   * :type:`nghttp2_on_frame_send_callback`, and
+   * :type:`nghttp2_on_frame_not_send_callback`), it may not be
+   * NULL-terminated if header field is passed from application with
+   * the flag :enum:`NGHTTP2_NV_FLAG_NO_COPY_VALUE`).  When
+   * application is constructing this struct, |value| is not required
+   * to be NULL-terminated.
+   */
+  uint8_t *value;
+  /**
+   * The length of the |name|, excluding terminating NULL.
+   */
+  size_t namelen;
+  /**
+   * The length of the |value|, excluding terminating NULL.
+   */
+  size_t valuelen;
+  /**
+   * Bitwise OR of one or more of :type:`nghttp2_nv_flag`.
+   */
+  uint8_t flags;
+} nghttp2_nv;
+
+/**
+ * @enum
+ *
+ * The frame types in HTTP/2 specification.
+ */
+typedef enum {
+  /**
+   * The DATA frame.
+   */
+  NGHTTP2_DATA = 0,
+  /**
+   * The HEADERS frame.
+   */
+  NGHTTP2_HEADERS = 0x01,
+  /**
+   * The PRIORITY frame.
+   */
+  NGHTTP2_PRIORITY = 0x02,
+  /**
+   * The RST_STREAM frame.
+   */
+  NGHTTP2_RST_STREAM = 0x03,
+  /**
+   * The SETTINGS frame.
+   */
+  NGHTTP2_SETTINGS = 0x04,
+  /**
+   * The PUSH_PROMISE frame.
+   */
+  NGHTTP2_PUSH_PROMISE = 0x05,
+  /**
+   * The PING frame.
+   */
+  NGHTTP2_PING = 0x06,
+  /**
+   * The GOAWAY frame.
+   */
+  NGHTTP2_GOAWAY = 0x07,
+  /**
+   * The WINDOW_UPDATE frame.
+   */
+  NGHTTP2_WINDOW_UPDATE = 0x08,
+  /**
+   * The CONTINUATION frame.  This frame type won't be passed to any
+   * callbacks because the library processes this frame type and its
+   * preceding HEADERS/PUSH_PROMISE as a single frame.
+   */
+  NGHTTP2_CONTINUATION = 0x09,
+  /**
+   * The ALTSVC frame, which is defined in `RFC 7383
+   * <https://tools.ietf.org/html/rfc7838#section-4>`_.
+   */
+  NGHTTP2_ALTSVC = 0x0a,
+  /**
+   * The ORIGIN frame, which is defined by `RFC 8336
+   * <https://tools.ietf.org/html/rfc8336>`_.
+   */
+  NGHTTP2_ORIGIN = 0x0c
+} nghttp2_frame_type;
+
+/**
+ * @enum
+ *
+ * The flags for HTTP/2 frames.  This enum defines all flags for all
+ * frames.
+ */
+typedef enum {
+  /**
+   * No flag set.
+   */
+  NGHTTP2_FLAG_NONE = 0,
+  /**
+   * The END_STREAM flag.
+   */
+  NGHTTP2_FLAG_END_STREAM = 0x01,
+  /**
+   * The END_HEADERS flag.
+   */
+  NGHTTP2_FLAG_END_HEADERS = 0x04,
+  /**
+   * The ACK flag.
+   */
+  NGHTTP2_FLAG_ACK = 0x01,
+  /**
+   * The PADDED flag.
+   */
+  NGHTTP2_FLAG_PADDED = 0x08,
+  /**
+   * The PRIORITY flag.
+   */
+  NGHTTP2_FLAG_PRIORITY = 0x20
+} nghttp2_flag;
+
+/**
+ * @enum
+ * The SETTINGS ID.
+ */
+typedef enum {
+  /**
+   * SETTINGS_HEADER_TABLE_SIZE
+   */
+  NGHTTP2_SETTINGS_HEADER_TABLE_SIZE = 0x01,
+  /**
+   * SETTINGS_ENABLE_PUSH
+   */
+  NGHTTP2_SETTINGS_ENABLE_PUSH = 0x02,
+  /**
+   * SETTINGS_MAX_CONCURRENT_STREAMS
+   */
+  NGHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS = 0x03,
+  /**
+   * SETTINGS_INITIAL_WINDOW_SIZE
+   */
+  NGHTTP2_SETTINGS_INITIAL_WINDOW_SIZE = 0x04,
+  /**
+   * SETTINGS_MAX_FRAME_SIZE
+   */
+  NGHTTP2_SETTINGS_MAX_FRAME_SIZE = 0x05,
+  /**
+   * SETTINGS_MAX_HEADER_LIST_SIZE
+   */
+  NGHTTP2_SETTINGS_MAX_HEADER_LIST_SIZE = 0x06,
+  /**
+   * SETTINGS_ENABLE_CONNECT_PROTOCOL
+   * (`RFC 8441 <https://tools.ietf.org/html/rfc8441>`_)
+   */
+  NGHTTP2_SETTINGS_ENABLE_CONNECT_PROTOCOL = 0x08
+} nghttp2_settings_id;
+/* Note: If we add SETTINGS, update the capacity of
+   NGHTTP2_INBOUND_NUM_IV as well */
+
+/**
+ * @macro
+ *
+ * .. warning::
+ *
+ *   Deprecated.  The initial max concurrent streams is 0xffffffffu.
+ *
+ * Default maximum number of incoming concurrent streams.  Use
+ * `nghttp2_submit_settings()` with
+ * :enum:`NGHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS` to change the
+ * maximum number of incoming concurrent streams.
+ *
+ * .. note::
+ *
+ *   The maximum number of outgoing concurrent streams is 100 by
+ *   default.
+ */
+#define NGHTTP2_INITIAL_MAX_CONCURRENT_STREAMS ((1U << 31) - 1)
+
+/**
+ * @enum
+ * The status codes for the RST_STREAM and GOAWAY frames.
+ */
+typedef enum {
+  /**
+   * No errors.
+   */
+  NGHTTP2_NO_ERROR = 0x00,
+  /**
+   * PROTOCOL_ERROR
+   */
+  NGHTTP2_PROTOCOL_ERROR = 0x01,
+  /**
+   * INTERNAL_ERROR
+   */
+  NGHTTP2_INTERNAL_ERROR = 0x02,
+  /**
+   * FLOW_CONTROL_ERROR
+   */
+  NGHTTP2_FLOW_CONTROL_ERROR = 0x03,
+  /**
+   * SETTINGS_TIMEOUT
+   */
+  NGHTTP2_SETTINGS_TIMEOUT = 0x04,
+  /**
+   * STREAM_CLOSED
+   */
+  NGHTTP2_STREAM_CLOSED = 0x05,
+  /**
+   * FRAME_SIZE_ERROR
+   */
+  NGHTTP2_FRAME_SIZE_ERROR = 0x06,
+  /**
+   * REFUSED_STREAM
+   */
+  NGHTTP2_REFUSED_STREAM = 0x07,
+  /**
+   * CANCEL
+   */
+  NGHTTP2_CANCEL = 0x08,
+  /**
+   * COMPRESSION_ERROR
+   */
+  NGHTTP2_COMPRESSION_ERROR = 0x09,
+  /**
+   * CONNECT_ERROR
+   */
+  NGHTTP2_CONNECT_ERROR = 0x0a,
+  /**
+   * ENHANCE_YOUR_CALM
+   */
+  NGHTTP2_ENHANCE_YOUR_CALM = 0x0b,
+  /**
+   * INADEQUATE_SECURITY
+   */
+  NGHTTP2_INADEQUATE_SECURITY = 0x0c,
+  /**
+   * HTTP_1_1_REQUIRED
+   */
+  NGHTTP2_HTTP_1_1_REQUIRED = 0x0d
+} nghttp2_error_code;
+
+/**
+ * @struct
+ * The frame header.
+ */
+typedef struct {
+  /**
+   * The length field of this frame, excluding frame header.
+   */
+  size_t length;
+  /**
+   * The stream identifier (aka, stream ID)
+   */
+  int32_t stream_id;
+  /**
+   * The type of this frame.  See `nghttp2_frame_type`.
+   */
+  uint8_t type;
+  /**
+   * The flags.
+   */
+  uint8_t flags;
+  /**
+   * Reserved bit in frame header.  Currently, this is always set to 0
+   * and application should not expect something useful in here.
+   */
+  uint8_t reserved;
+} nghttp2_frame_hd;
+
+/**
+ * @union
+ *
+ * This union represents the some kind of data source passed to
+ * :type:`nghttp2_data_source_read_callback`.
+ */
+typedef union {
+  /**
+   * The integer field, suitable for a file descriptor.
+   */
+  int fd;
+  /**
+   * The pointer to an arbitrary object.
+   */
+  void *ptr;
+} nghttp2_data_source;
+
+/**
+ * @enum
+ *
+ * The flags used to set in |data_flags| output parameter in
+ * :type:`nghttp2_data_source_read_callback`.
+ */
+typedef enum {
+  /**
+   * No flag set.
+   */
+  NGHTTP2_DATA_FLAG_NONE = 0,
+  /**
+   * Indicates EOF was sensed.
+   */
+  NGHTTP2_DATA_FLAG_EOF = 0x01,
+  /**
+   * Indicates that END_STREAM flag must not be set even if
+   * NGHTTP2_DATA_FLAG_EOF is set.  Usually this flag is used to send
+   * trailer fields with `nghttp2_submit_request()` or
+   * `nghttp2_submit_response()`.
+   */
+  NGHTTP2_DATA_FLAG_NO_END_STREAM = 0x02,
+  /**
+   * Indicates that application will send complete DATA frame in
+   * :type:`nghttp2_send_data_callback`.
+   */
+  NGHTTP2_DATA_FLAG_NO_COPY = 0x04
+} nghttp2_data_flag;
+
+/**
+ * @functypedef
+ *
+ * Callback function invoked when the library wants to read data from
+ * the |source|.  The read data is sent in the stream |stream_id|.
+ * The implementation of this function must read at most |length|
+ * bytes of data from |source| (or possibly other places) and store
+ * them in |buf| and return number of data stored in |buf|.  If EOF is
+ * reached, set :enum:`NGHTTP2_DATA_FLAG_EOF` flag in |*data_flags|.
+ *
+ * Sometime it is desirable to avoid copying data into |buf| and let
+ * application to send data directly.  To achieve this, set
+ * :enum:`NGHTTP2_DATA_FLAG_NO_COPY` to |*data_flags| (and possibly
+ * other flags, just like when we do copy), and return the number of
+ * bytes to send without copying data into |buf|.  The library, seeing
+ * :enum:`NGHTTP2_DATA_FLAG_NO_COPY`, will invoke
+ * :type:`nghttp2_send_data_callback`.  The application must send
+ * complete DATA frame in that callback.
+ *
+ * If this callback is set by `nghttp2_submit_request()`,
+ * `nghttp2_submit_response()` or `nghttp2_submit_headers()` and
+ * `nghttp2_submit_data()` with flag parameter
+ * :enum:`NGHTTP2_FLAG_END_STREAM` set, and
+ * :enum:`NGHTTP2_DATA_FLAG_EOF` flag is set to |*data_flags|, DATA
+ * frame will have END_STREAM flag set.  Usually, this is expected
+ * behaviour and all are fine.  One exception is send trailer fields.
+ * You cannot send trailer fields after sending frame with END_STREAM
+ * set.  To avoid this problem, one can set
+ * :enum:`NGHTTP2_DATA_FLAG_NO_END_STREAM` along with
+ * :enum:`NGHTTP2_DATA_FLAG_EOF` to signal the library not to set
+ * END_STREAM in DATA frame.  Then application can use
+ * `nghttp2_submit_trailer()` to send trailer fields.
+ * `nghttp2_submit_trailer()` can be called inside this callback.
+ *
+ * If the application wants to postpone DATA frames (e.g.,
+ * asynchronous I/O, or reading data blocks for long time), it is
+ * achieved by returning :enum:`NGHTTP2_ERR_DEFERRED` without reading
+ * any data in this invocation.  The library removes DATA frame from
+ * the outgoing queue temporarily.  To move back deferred DATA frame
+ * to outgoing queue, call `nghttp2_session_resume_data()`.
+ *
+ * By default, |length| is limited to 16KiB at maximum.  If peer
+ * allows larger frames, application can enlarge transmission buffer
+ * size.  See :type:`nghttp2_data_source_read_length_callback` for
+ * more details.
+ *
+ * If the application just wants to return from
+ * `nghttp2_session_send()` or `nghttp2_session_mem_send()` without
+ * sending anything, return :enum:`NGHTTP2_ERR_PAUSE`.
+ *
+ * In case of error, there are 2 choices. Returning
+ * :enum:`NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE` will close the stream
+ * by issuing RST_STREAM with :enum:`NGHTTP2_INTERNAL_ERROR`.  If a
+ * different error code is desirable, use
+ * `nghttp2_submit_rst_stream()` with a desired error code and then
+ * return :enum:`NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE`.  Returning
+ * :enum:`NGHTTP2_ERR_CALLBACK_FAILURE` will signal the entire session
+ * failure.
+ */
+typedef ssize_t (*nghttp2_data_source_read_callback)(
+    nghttp2_session *session, int32_t stream_id, uint8_t *buf, size_t length,
+    uint32_t *data_flags, nghttp2_data_source *source, void *user_data);
+
+/**
+ * @struct
+ *
+ * This struct represents the data source and the way to read a chunk
+ * of data from it.
+ */
+typedef struct {
+  /**
+   * The data source.
+   */
+  nghttp2_data_source source;
+  /**
+   * The callback function to read a chunk of data from the |source|.
+   */
+  nghttp2_data_source_read_callback read_callback;
+} nghttp2_data_provider;
+
+/**
+ * @struct
+ *
+ * The DATA frame.  The received data is delivered via
+ * :type:`nghttp2_on_data_chunk_recv_callback`.
+ */
+typedef struct {
+  nghttp2_frame_hd hd;
+  /**
+   * The length of the padding in this frame.  This includes PAD_HIGH
+   * and PAD_LOW.
+   */
+  size_t padlen;
+} nghttp2_data;
+
+/**
+ * @enum
+ *
+ * The category of HEADERS, which indicates the role of the frame.  In
+ * HTTP/2 spec, request, response, push response and other arbitrary
+ * headers (e.g., trailer fields) are all called just HEADERS.  To
+ * give the application the role of incoming HEADERS frame, we define
+ * several categories.
+ */
+typedef enum {
+  /**
+   * The HEADERS frame is opening new stream, which is analogous to
+   * SYN_STREAM in SPDY.
+   */
+  NGHTTP2_HCAT_REQUEST = 0,
+  /**
+   * The HEADERS frame is the first response headers, which is
+   * analogous to SYN_REPLY in SPDY.
+   */
+  NGHTTP2_HCAT_RESPONSE = 1,
+  /**
+   * The HEADERS frame is the first headers sent against reserved
+   * stream.
+   */
+  NGHTTP2_HCAT_PUSH_RESPONSE = 2,
+  /**
+   * The HEADERS frame which does not apply for the above categories,
+   * which is analogous to HEADERS in SPDY.  If non-final response
+   * (e.g., status 1xx) is used, final response HEADERS frame will be
+   * categorized here.
+   */
+  NGHTTP2_HCAT_HEADERS = 3
+} nghttp2_headers_category;
+
+/**
+ * @struct
+ *
+ * The structure to specify stream dependency.
+ */
+typedef struct {
+  /**
+   * The stream ID of the stream to depend on.  Specifying 0 makes
+   * stream not depend any other stream.
+   */
+  int32_t stream_id;
+  /**
+   * The weight of this dependency.
+   */
+  int32_t weight;
+  /**
+   * nonzero means exclusive dependency
+   */
+  uint8_t exclusive;
+} nghttp2_priority_spec;
+
+/**
+ * @struct
+ *
+ * The HEADERS frame.  It has the following members:
+ */
+typedef struct {
+  /**
+   * The frame header.
+   */
+  nghttp2_frame_hd hd;
+  /**
+   * The length of the padding in this frame.  This includes PAD_HIGH
+   * and PAD_LOW.
+   */
+  size_t padlen;
+  /**
+   * The priority specification
+   */
+  nghttp2_priority_spec pri_spec;
+  /**
+   * The name/value pairs.
+   */
+  nghttp2_nv *nva;
+  /**
+   * The number of name/value pairs in |nva|.
+   */
+  size_t nvlen;
+  /**
+   * The category of this HEADERS frame.
+   */
+  nghttp2_headers_category cat;
+} nghttp2_headers;
+
+/**
+ * @struct
+ *
+ * The PRIORITY frame.  It has the following members:
+ */
+typedef struct {
+  /**
+   * The frame header.
+   */
+  nghttp2_frame_hd hd;
+  /**
+   * The priority specification.
+   */
+  nghttp2_priority_spec pri_spec;
+} nghttp2_priority;
+
+/**
+ * @struct
+ *
+ * The RST_STREAM frame.  It has the following members:
+ */
+typedef struct {
+  /**
+   * The frame header.
+   */
+  nghttp2_frame_hd hd;
+  /**
+   * The error code.  See :type:`nghttp2_error_code`.
+   */
+  uint32_t error_code;
+} nghttp2_rst_stream;
+
+/**
+ * @struct
+ *
+ * The SETTINGS ID/Value pair.  It has the following members:
+ */
+typedef struct {
+  /**
+   * The SETTINGS ID.  See :type:`nghttp2_settings_id`.
+   */
+  int32_t settings_id;
+  /**
+   * The value of this entry.
+   */
+  uint32_t value;
+} nghttp2_settings_entry;
+
+/**
+ * @struct
+ *
+ * The SETTINGS frame.  It has the following members:
+ */
+typedef struct {
+  /**
+   * The frame header.
+   */
+  nghttp2_frame_hd hd;
+  /**
+   * The number of SETTINGS ID/Value pairs in |iv|.
+   */
+  size_t niv;
+  /**
+   * The pointer to the array of SETTINGS ID/Value pair.
+   */
+  nghttp2_settings_entry *iv;
+} nghttp2_settings;
+
+/**
+ * @struct
+ *
+ * The PUSH_PROMISE frame.  It has the following members:
+ */
+typedef struct {
+  /**
+   * The frame header.
+   */
+  nghttp2_frame_hd hd;
+  /**
+   * The length of the padding in this frame.  This includes PAD_HIGH
+   * and PAD_LOW.
+   */
+  size_t padlen;
+  /**
+   * The name/value pairs.
+   */
+  nghttp2_nv *nva;
+  /**
+   * The number of name/value pairs in |nva|.
+   */
+  size_t nvlen;
+  /**
+   * The promised stream ID
+   */
+  int32_t promised_stream_id;
+  /**
+   * Reserved bit.  Currently this is always set to 0 and application
+   * should not expect something useful in here.
+   */
+  uint8_t reserved;
+} nghttp2_push_promise;
+
+/**
+ * @struct
+ *
+ * The PING frame.  It has the following members:
+ */
+typedef struct {
+  /**
+   * The frame header.
+   */
+  nghttp2_frame_hd hd;
+  /**
+   * The opaque data
+   */
+  uint8_t opaque_data[8];
+} nghttp2_ping;
+
+/**
+ * @struct
+ *
+ * The GOAWAY frame.  It has the following members:
+ */
+typedef struct {
+  /**
+   * The frame header.
+   */
+  nghttp2_frame_hd hd;
+  /**
+   * The last stream stream ID.
+   */
+  int32_t last_stream_id;
+  /**
+   * The error code.  See :type:`nghttp2_error_code`.
+   */
+  uint32_t error_code;
+  /**
+   * The additional debug data
+   */
+  uint8_t *opaque_data;
+  /**
+   * The length of |opaque_data| member.
+   */
+  size_t opaque_data_len;
+  /**
+   * Reserved bit.  Currently this is always set to 0 and application
+   * should not expect something useful in here.
+   */
+  uint8_t reserved;
+} nghttp2_goaway;
+
+/**
+ * @struct
+ *
+ * The WINDOW_UPDATE frame.  It has the following members:
+ */
+typedef struct {
+  /**
+   * The frame header.
+   */
+  nghttp2_frame_hd hd;
+  /**
+   * The window size increment.
+   */
+  int32_t window_size_increment;
+  /**
+   * Reserved bit.  Currently this is always set to 0 and application
+   * should not expect something useful in here.
+   */
+  uint8_t reserved;
+} nghttp2_window_update;
+
+/**
+ * @struct
+ *
+ * The extension frame.  It has following members:
+ */
+typedef struct {
+  /**
+   * The frame header.
+   */
+  nghttp2_frame_hd hd;
+  /**
+   * The pointer to extension payload.  The exact pointer type is
+   * determined by hd.type.
+   *
+   * Currently, no extension is supported.  This is a place holder for
+   * the future extensions.
+   */
+  void *payload;
+} nghttp2_extension;
+
+/**
+ * @union
+ *
+ * This union includes all frames to pass them to various function
+ * calls as nghttp2_frame type.  The CONTINUATION frame is omitted
+ * from here because the library deals with it internally.
+ */
+typedef union {
+  /**
+   * The frame header, which is convenient to inspect frame header.
+   */
+  nghttp2_frame_hd hd;
+  /**
+   * The DATA frame.
+   */
+  nghttp2_data data;
+  /**
+   * The HEADERS frame.
+   */
+  nghttp2_headers headers;
+  /**
+   * The PRIORITY frame.
+   */
+  nghttp2_priority priority;
+  /**
+   * The RST_STREAM frame.
+   */
+  nghttp2_rst_stream rst_stream;
+  /**
+   * The SETTINGS frame.
+   */
+  nghttp2_settings settings;
+  /**
+   * The PUSH_PROMISE frame.
+   */
+  nghttp2_push_promise push_promise;
+  /**
+   * The PING frame.
+   */
+  nghttp2_ping ping;
+  /**
+   * The GOAWAY frame.
+   */
+  nghttp2_goaway goaway;
+  /**
+   * The WINDOW_UPDATE frame.
+   */
+  nghttp2_window_update window_update;
+  /**
+   * The extension frame.
+   */
+  nghttp2_extension ext;
+} nghttp2_frame;
+
+/**
+ * @functypedef
+ *
+ * Callback function invoked when |session| wants to send data to the
+ * remote peer.  The implementation of this function must send at most
+ * |length| bytes of data stored in |data|.  The |flags| is currently
+ * not used and always 0. It must return the number of bytes sent if
+ * it succeeds.  If it cannot send any single byte without blocking,
+ * it must return :enum:`NGHTTP2_ERR_WOULDBLOCK`.  For other errors,
+ * it must return :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`.  The
+ * |user_data| pointer is the third argument passed in to the call to
+ * `nghttp2_session_client_new()` or `nghttp2_session_server_new()`.
+ *
+ * This callback is required if the application uses
+ * `nghttp2_session_send()` to send data to the remote endpoint.  If
+ * the application uses solely `nghttp2_session_mem_send()` instead,
+ * this callback function is unnecessary.
+ *
+ * To set this callback to :type:`nghttp2_session_callbacks`, use
+ * `nghttp2_session_callbacks_set_send_callback()`.
+ *
+ * .. note::
+ *
+ *   The |length| may be very small.  If that is the case, and
+ *   application disables Nagle algorithm (``TCP_NODELAY``), then just
+ *   writing |data| to the network stack leads to very small packet,
+ *   and it is very inefficient.  An application should be responsible
+ *   to buffer up small chunks of data as necessary to avoid this
+ *   situation.
+ */
+typedef ssize_t (*nghttp2_send_callback)(nghttp2_session *session,
+                                         const uint8_t *data, size_t length,
+                                         int flags, void *user_data);
+
+/**
+ * @functypedef
+ *
+ * Callback function invoked when :enum:`NGHTTP2_DATA_FLAG_NO_COPY` is
+ * used in :type:`nghttp2_data_source_read_callback` to send complete
+ * DATA frame.
+ *
+ * The |frame| is a DATA frame to send.  The |framehd| is the
+ * serialized frame header (9 bytes). The |length| is the length of
+ * application data to send (this does not include padding).  The
+ * |source| is the same pointer passed to
+ * :type:`nghttp2_data_source_read_callback`.
+ *
+ * The application first must send frame header |framehd| of length 9
+ * bytes.  If ``frame->data.padlen > 0``, send 1 byte of value
+ * ``frame->data.padlen - 1``.  Then send exactly |length| bytes of
+ * application data.  Finally, if ``frame->data.padlen > 1``, send
+ * ``frame->data.padlen - 1`` bytes of zero as padding.
+ *
+ * The application has to send complete DATA frame in this callback.
+ * If all data were written successfully, return 0.
+ *
+ * If it cannot send any data at all, just return
+ * :enum:`NGHTTP2_ERR_WOULDBLOCK`; the library will call this callback
+ * with the same parameters later (It is recommended to send complete
+ * DATA frame at once in this function to deal with error; if partial
+ * frame data has already sent, it is impossible to send another data
+ * in that state, and all we can do is tear down connection).  When
+ * data is fully processed, but application wants to make
+ * `nghttp2_session_mem_send()` or `nghttp2_session_send()` return
+ * immediately without processing next frames, return
+ * :enum:`NGHTTP2_ERR_PAUSE`.  If application decided to reset this
+ * stream, return :enum:`NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE`, then
+ * the library will send RST_STREAM with INTERNAL_ERROR as error code.
+ * The application can also return
+ * :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`, which will result in
+ * connection closure.  Returning any other value is treated as
+ * :enum:`NGHTTP2_ERR_CALLBACK_FAILURE` is returned.
+ */
+typedef int (*nghttp2_send_data_callback)(nghttp2_session *session,
+                                          nghttp2_frame *frame,
+                                          const uint8_t *framehd, size_t length,
+                                          nghttp2_data_source *source,
+                                          void *user_data);
+
+/**
+ * @functypedef
+ *
+ * Callback function invoked when |session| wants to receive data from
+ * the remote peer.  The implementation of this function must read at
+ * most |length| bytes of data and store it in |buf|.  The |flags| is
+ * currently not used and always 0.  It must return the number of
+ * bytes written in |buf| if it succeeds.  If it cannot read any
+ * single byte without blocking, it must return
+ * :enum:`NGHTTP2_ERR_WOULDBLOCK`.  If it gets EOF before it reads any
+ * single byte, it must return :enum:`NGHTTP2_ERR_EOF`.  For other
+ * errors, it must return :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`.
+ * Returning 0 is treated as :enum:`NGHTTP2_ERR_WOULDBLOCK`.  The
+ * |user_data| pointer is the third argument passed in to the call to
+ * `nghttp2_session_client_new()` or `nghttp2_session_server_new()`.
+ *
+ * This callback is required if the application uses
+ * `nghttp2_session_recv()` to receive data from the remote endpoint.
+ * If the application uses solely `nghttp2_session_mem_recv()`
+ * instead, this callback function is unnecessary.
+ *
+ * To set this callback to :type:`nghttp2_session_callbacks`, use
+ * `nghttp2_session_callbacks_set_recv_callback()`.
+ */
+typedef ssize_t (*nghttp2_recv_callback)(nghttp2_session *session, uint8_t *buf,
+                                         size_t length, int flags,
+                                         void *user_data);
+
+/**
+ * @functypedef
+ *
+ * Callback function invoked by `nghttp2_session_recv()` and
+ * `nghttp2_session_mem_recv()` when a frame is received.  The
+ * |user_data| pointer is the third argument passed in to the call to
+ * `nghttp2_session_client_new()` or `nghttp2_session_server_new()`.
+ *
+ * If frame is HEADERS or PUSH_PROMISE, the ``nva`` and ``nvlen``
+ * member of their data structure are always ``NULL`` and 0
+ * respectively.  The header name/value pairs are emitted via
+ * :type:`nghttp2_on_header_callback`.
+ *
+ * For HEADERS, PUSH_PROMISE and DATA frames, this callback may be
+ * called after stream is closed (see
+ * :type:`nghttp2_on_stream_close_callback`).  The application should
+ * check that stream is still alive using its own stream management or
+ * :func:`nghttp2_session_get_stream_user_data()`.
+ *
+ * Only HEADERS and DATA frame can signal the end of incoming data.
+ * If ``frame->hd.flags & NGHTTP2_FLAG_END_STREAM`` is nonzero, the
+ * |frame| is the last frame from the remote peer in this stream.
+ *
+ * This callback won't be called for CONTINUATION frames.
+ * HEADERS/PUSH_PROMISE + CONTINUATIONs are treated as single frame.
+ *
+ * The implementation of this function must return 0 if it succeeds.
+ * If nonzero value is returned, it is treated as fatal error and
+ * `nghttp2_session_recv()` and `nghttp2_session_mem_recv()` functions
+ * immediately return :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`.
+ *
+ * To set this callback to :type:`nghttp2_session_callbacks`, use
+ * `nghttp2_session_callbacks_set_on_frame_recv_callback()`.
+ */
+typedef int (*nghttp2_on_frame_recv_callback)(nghttp2_session *session,
+                                              const nghttp2_frame *frame,
+                                              void *user_data);
+
+/**
+ * @functypedef
+ *
+ * Callback function invoked by `nghttp2_session_recv()` and
+ * `nghttp2_session_mem_recv()` when an invalid non-DATA frame is
+ * received.  The error is indicated by the |lib_error_code|, which is
+ * one of the values defined in :type:`nghttp2_error`.  When this
+ * callback function is invoked, the library automatically submits
+ * either RST_STREAM or GOAWAY frame.  The |user_data| pointer is the
+ * third argument passed in to the call to
+ * `nghttp2_session_client_new()` or `nghttp2_session_server_new()`.
+ *
+ * If frame is HEADERS or PUSH_PROMISE, the ``nva`` and ``nvlen``
+ * member of their data structure are always ``NULL`` and 0
+ * respectively.
+ *
+ * The implementation of this function must return 0 if it succeeds.
+ * If nonzero is returned, it is treated as fatal error and
+ * `nghttp2_session_recv()` and `nghttp2_session_mem_recv()` functions
+ * immediately return :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`.
+ *
+ * To set this callback to :type:`nghttp2_session_callbacks`, use
+ * `nghttp2_session_callbacks_set_on_invalid_frame_recv_callback()`.
+ */
+typedef int (*nghttp2_on_invalid_frame_recv_callback)(
+    nghttp2_session *session, const nghttp2_frame *frame, int lib_error_code,
+    void *user_data);
+
+/**
+ * @functypedef
+ *
+ * Callback function invoked when a chunk of data in DATA frame is
+ * received.  The |stream_id| is the stream ID this DATA frame belongs
+ * to.  The |flags| is the flags of DATA frame which this data chunk
+ * is contained.  ``(flags & NGHTTP2_FLAG_END_STREAM) != 0`` does not
+ * necessarily mean this chunk of data is the last one in the stream.
+ * You should use :type:`nghttp2_on_frame_recv_callback` to know all
+ * data frames are received.  The |user_data| pointer is the third
+ * argument passed in to the call to `nghttp2_session_client_new()` or
+ * `nghttp2_session_server_new()`.
+ *
+ * If the application uses `nghttp2_session_mem_recv()`, it can return
+ * :enum:`NGHTTP2_ERR_PAUSE` to make `nghttp2_session_mem_recv()`
+ * return without processing further input bytes.  The memory by
+ * pointed by the |data| is retained until
+ * `nghttp2_session_mem_recv()` or `nghttp2_session_recv()` is called.
+ * The application must retain the input bytes which was used to
+ * produce the |data| parameter, because it may refer to the memory
+ * region included in the input bytes.
+ *
+ * The implementation of this function must return 0 if it succeeds.
+ * If nonzero is returned, it is treated as fatal error, and
+ * `nghttp2_session_recv()` and `nghttp2_session_mem_recv()` functions
+ * immediately return :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`.
+ *
+ * To set this callback to :type:`nghttp2_session_callbacks`, use
+ * `nghttp2_session_callbacks_set_on_data_chunk_recv_callback()`.
+ */
+typedef int (*nghttp2_on_data_chunk_recv_callback)(nghttp2_session *session,
+                                                   uint8_t flags,
+                                                   int32_t stream_id,
+                                                   const uint8_t *data,
+                                                   size_t len, void *user_data);
+
+/**
+ * @functypedef
+ *
+ * Callback function invoked just before the non-DATA frame |frame| is
+ * sent.  The |user_data| pointer is the third argument passed in to
+ * the call to `nghttp2_session_client_new()` or
+ * `nghttp2_session_server_new()`.
+ *
+ * The implementation of this function must return 0 if it succeeds.
+ * It can also return :enum:`NGHTTP2_ERR_CANCEL` to cancel the
+ * transmission of the given frame.
+ *
+ * If there is a fatal error while executing this callback, the
+ * implementation should return :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`,
+ * which makes `nghttp2_session_send()` and
+ * `nghttp2_session_mem_send()` functions immediately return
+ * :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`.
+ *
+ * If the other value is returned, it is treated as if
+ * :enum:`NGHTTP2_ERR_CALLBACK_FAILURE` is returned.  But the
+ * implementation should not rely on this since the library may define
+ * new return value to extend its capability.
+ *
+ * To set this callback to :type:`nghttp2_session_callbacks`, use
+ * `nghttp2_session_callbacks_set_before_frame_send_callback()`.
+ */
+typedef int (*nghttp2_before_frame_send_callback)(nghttp2_session *session,
+                                                  const nghttp2_frame *frame,
+                                                  void *user_data);
+
+/**
+ * @functypedef
+ *
+ * Callback function invoked after the frame |frame| is sent.  The
+ * |user_data| pointer is the third argument passed in to the call to
+ * `nghttp2_session_client_new()` or `nghttp2_session_server_new()`.
+ *
+ * The implementation of this function must return 0 if it succeeds.
+ * If nonzero is returned, it is treated as fatal error and
+ * `nghttp2_session_send()` and `nghttp2_session_mem_send()` functions
+ * immediately return :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`.
+ *
+ * To set this callback to :type:`nghttp2_session_callbacks`, use
+ * `nghttp2_session_callbacks_set_on_frame_send_callback()`.
+ */
+typedef int (*nghttp2_on_frame_send_callback)(nghttp2_session *session,
+                                              const nghttp2_frame *frame,
+                                              void *user_data);
+
+/**
+ * @functypedef
+ *
+ * Callback function invoked after the non-DATA frame |frame| is not
+ * sent because of the error.  The error is indicated by the
+ * |lib_error_code|, which is one of the values defined in
+ * :type:`nghttp2_error`.  The |user_data| pointer is the third
+ * argument passed in to the call to `nghttp2_session_client_new()` or
+ * `nghttp2_session_server_new()`.
+ *
+ * The implementation of this function must return 0 if it succeeds.
+ * If nonzero is returned, it is treated as fatal error and
+ * `nghttp2_session_send()` and `nghttp2_session_mem_send()` functions
+ * immediately return :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`.
+ *
+ * `nghttp2_session_get_stream_user_data()` can be used to get
+ * associated data.
+ *
+ * To set this callback to :type:`nghttp2_session_callbacks`, use
+ * `nghttp2_session_callbacks_set_on_frame_not_send_callback()`.
+ */
+typedef int (*nghttp2_on_frame_not_send_callback)(nghttp2_session *session,
+                                                  const nghttp2_frame *frame,
+                                                  int lib_error_code,
+                                                  void *user_data);
+
+/**
+ * @functypedef
+ *
+ * Callback function invoked when the stream |stream_id| is closed.
+ * The reason of closure is indicated by the |error_code|.  The
+ * |error_code| is usually one of :enum:`nghttp2_error_code`, but that
+ * is not guaranteed.  The stream_user_data, which was specified in
+ * `nghttp2_submit_request()` or `nghttp2_submit_headers()`, is still
+ * available in this function.  The |user_data| pointer is the third
+ * argument passed in to the call to `nghttp2_session_client_new()` or
+ * `nghttp2_session_server_new()`.
+ *
+ * This function is also called for a stream in reserved state.
+ *
+ * The implementation of this function must return 0 if it succeeds.
+ * If nonzero is returned, it is treated as fatal error and
+ * `nghttp2_session_recv()`, `nghttp2_session_mem_recv()`,
+ * `nghttp2_session_send()`, and `nghttp2_session_mem_send()`
+ * functions immediately return :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`.
+ *
+ * To set this callback to :type:`nghttp2_session_callbacks`, use
+ * `nghttp2_session_callbacks_set_on_stream_close_callback()`.
+ */
+typedef int (*nghttp2_on_stream_close_callback)(nghttp2_session *session,
+                                                int32_t stream_id,
+                                                uint32_t error_code,
+                                                void *user_data);
+
+/**
+ * @functypedef
+ *
+ * Callback function invoked when the reception of header block in
+ * HEADERS or PUSH_PROMISE is started.  Each header name/value pair
+ * will be emitted by :type:`nghttp2_on_header_callback`.
+ *
+ * The ``frame->hd.flags`` may not have
+ * :enum:`NGHTTP2_FLAG_END_HEADERS` flag set, which indicates that one
+ * or more CONTINUATION frames are involved.  But the application does
+ * not need to care about that because the header name/value pairs are
+ * emitted transparently regardless of CONTINUATION frames.
+ *
+ * The server applications probably create an object to store
+ * information about new stream if ``frame->hd.type ==
+ * NGHTTP2_HEADERS`` and ``frame->headers.cat ==
+ * NGHTTP2_HCAT_REQUEST``.  If |session| is configured as server side,
+ * ``frame->headers.cat`` is either ``NGHTTP2_HCAT_REQUEST``
+ * containing request headers or ``NGHTTP2_HCAT_HEADERS`` containing
+ * trailer fields and never get PUSH_PROMISE in this callback.
+ *
+ * For the client applications, ``frame->hd.type`` is either
+ * ``NGHTTP2_HEADERS`` or ``NGHTTP2_PUSH_PROMISE``.  In case of
+ * ``NGHTTP2_HEADERS``, ``frame->headers.cat ==
+ * NGHTTP2_HCAT_RESPONSE`` means that it is the first response
+ * headers, but it may be non-final response which is indicated by 1xx
+ * status code.  In this case, there may be zero or more HEADERS frame
+ * with ``frame->headers.cat == NGHTTP2_HCAT_HEADERS`` which has
+ * non-final response code and finally client gets exactly one HEADERS
+ * frame with ``frame->headers.cat == NGHTTP2_HCAT_HEADERS``
+ * containing final response headers (non-1xx status code).  The
+ * trailer fields also has ``frame->headers.cat ==
+ * NGHTTP2_HCAT_HEADERS`` which does not contain any status code.
+ *
+ * Returning :enum:`NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE` will close
+ * the stream (promised stream if frame is PUSH_PROMISE) by issuing
+ * RST_STREAM with :enum:`NGHTTP2_INTERNAL_ERROR`.  In this case,
+ * :type:`nghttp2_on_header_callback` and
+ * :type:`nghttp2_on_frame_recv_callback` will not be invoked.  If a
+ * different error code is desirable, use
+ * `nghttp2_submit_rst_stream()` with a desired error code and then
+ * return :enum:`NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE`.  Again, use
+ * ``frame->push_promise.promised_stream_id`` as stream_id parameter
+ * in `nghttp2_submit_rst_stream()` if frame is PUSH_PROMISE.
+ *
+ * The implementation of this function must return 0 if it succeeds.
+ * It can return :enum:`NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE` to
+ * reset the stream (promised stream if frame is PUSH_PROMISE).  For
+ * critical errors, it must return
+ * :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`.  If the other value is
+ * returned, it is treated as if :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`
+ * is returned.  If :enum:`NGHTTP2_ERR_CALLBACK_FAILURE` is returned,
+ * `nghttp2_session_mem_recv()` function will immediately return
+ * :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`.
+ *
+ * To set this callback to :type:`nghttp2_session_callbacks`, use
+ * `nghttp2_session_callbacks_set_on_begin_headers_callback()`.
+ */
+typedef int (*nghttp2_on_begin_headers_callback)(nghttp2_session *session,
+                                                 const nghttp2_frame *frame,
+                                                 void *user_data);
+
+/**
+ * @functypedef
+ *
+ * Callback function invoked when a header name/value pair is received
+ * for the |frame|.  The |name| of length |namelen| is header name.
+ * The |value| of length |valuelen| is header value.  The |flags| is
+ * bitwise OR of one or more of :type:`nghttp2_nv_flag`.
+ *
+ * If :enum:`NGHTTP2_NV_FLAG_NO_INDEX` is set in |flags|, the receiver
+ * must not index this name/value pair when forwarding it to the next
+ * hop.  More specifically, "Literal Header Field never Indexed"
+ * representation must be used in HPACK encoding.
+ *
+ * When this callback is invoked, ``frame->hd.type`` is either
+ * :enum:`NGHTTP2_HEADERS` or :enum:`NGHTTP2_PUSH_PROMISE`.  After all
+ * header name/value pairs are processed with this callback, and no
+ * error has been detected, :type:`nghttp2_on_frame_recv_callback`
+ * will be invoked.  If there is an error in decompression,
+ * :type:`nghttp2_on_frame_recv_callback` for the |frame| will not be
+ * invoked.
+ *
+ * Both |name| and |value| are guaranteed to be NULL-terminated.  The
+ * |namelen| and |valuelen| do not include terminal NULL.  If
+ * `nghttp2_option_set_no_http_messaging()` is used with nonzero
+ * value, NULL character may be included in |name| or |value| before
+ * terminating NULL.
+ *
+ * Please note that unless `nghttp2_option_set_no_http_messaging()` is
+ * used, nghttp2 library does perform validation against the |name|
+ * and the |value| using `nghttp2_check_header_name()` and
+ * `nghttp2_check_header_value()`.  In addition to this, nghttp2
+ * performs validation based on HTTP Messaging rule, which is briefly
+ * explained in :ref:`http-messaging` section.
+ *
+ * If the application uses `nghttp2_session_mem_recv()`, it can return
+ * :enum:`NGHTTP2_ERR_PAUSE` to make `nghttp2_session_mem_recv()`
+ * return without processing further input bytes.  The memory pointed
+ * by |frame|, |name| and |value| parameters are retained until
+ * `nghttp2_session_mem_recv()` or `nghttp2_session_recv()` is called.
+ * The application must retain the input bytes which was used to
+ * produce these parameters, because it may refer to the memory region
+ * included in the input bytes.
+ *
+ * Returning :enum:`NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE` will close
+ * the stream (promised stream if frame is PUSH_PROMISE) by issuing
+ * RST_STREAM with :enum:`NGHTTP2_INTERNAL_ERROR`.  In this case,
+ * :type:`nghttp2_on_header_callback` and
+ * :type:`nghttp2_on_frame_recv_callback` will not be invoked.  If a
+ * different error code is desirable, use
+ * `nghttp2_submit_rst_stream()` with a desired error code and then
+ * return :enum:`NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE`.  Again, use
+ * ``frame->push_promise.promised_stream_id`` as stream_id parameter
+ * in `nghttp2_submit_rst_stream()` if frame is PUSH_PROMISE.
+ *
+ * The implementation of this function must return 0 if it succeeds.
+ * It may return :enum:`NGHTTP2_ERR_PAUSE` or
+ * :enum:`NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE`.  For other critical
+ * failures, it must return :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`.  If
+ * the other nonzero value is returned, it is treated as
+ * :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`.  If
+ * :enum:`NGHTTP2_ERR_CALLBACK_FAILURE` is returned,
+ * `nghttp2_session_recv()` and `nghttp2_session_mem_recv()` functions
+ * immediately return :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`.
+ *
+ * To set this callback to :type:`nghttp2_session_callbacks`, use
+ * `nghttp2_session_callbacks_set_on_header_callback()`.
+ *
+ * .. warning::
+ *
+ *   Application should properly limit the total buffer size to store
+ *   incoming header fields.  Without it, peer may send large number
+ *   of header fields or large header fields to cause out of memory in
+ *   local endpoint.  Due to how HPACK works, peer can do this
+ *   effectively without using much memory on their own.
+ */
+typedef int (*nghttp2_on_header_callback)(nghttp2_session *session,
+                                          const nghttp2_frame *frame,
+                                          const uint8_t *name, size_t namelen,
+                                          const uint8_t *value, size_t valuelen,
+                                          uint8_t flags, void *user_data);
+
+/**
+ * @functypedef
+ *
+ * Callback function invoked when a header name/value pair is received
+ * for the |frame|.  The |name| is header name.  The |value| is header
+ * value.  The |flags| is bitwise OR of one or more of
+ * :type:`nghttp2_nv_flag`.
+ *
+ * This callback behaves like :type:`nghttp2_on_header_callback`,
+ * except that |name| and |value| are stored in reference counted
+ * buffer.  If application wishes to keep these references without
+ * copying them, use `nghttp2_rcbuf_incref()` to increment their
+ * reference count.  It is the application's responsibility to call
+ * `nghttp2_rcbuf_decref()` if they called `nghttp2_rcbuf_incref()` so
+ * as not to leak memory.  If the |session| is created by
+ * `nghttp2_session_server_new3()` or `nghttp2_session_client_new3()`,
+ * the function to free memory is the one belongs to the mem
+ * parameter.  As long as this free function alives, |name| and
+ * |value| can live after |session| was destroyed.
+ */
+typedef int (*nghttp2_on_header_callback2)(nghttp2_session *session,
+                                           const nghttp2_frame *frame,
+                                           nghttp2_rcbuf *name,
+                                           nghttp2_rcbuf *value, uint8_t flags,
+                                           void *user_data);
+
+/**
+ * @functypedef
+ *
+ * Callback function invoked when a invalid header name/value pair is
+ * received for the |frame|.
+ *
+ * The parameter and behaviour are similar to
+ * :type:`nghttp2_on_header_callback`.  The difference is that this
+ * callback is only invoked when a invalid header name/value pair is
+ * received which is treated as stream error if this callback is not
+ * set.  Only invalid regular header field are passed to this
+ * callback.  In other words, invalid pseudo header field is not
+ * passed to this callback.  Also header fields which includes upper
+ * cased latter are also treated as error without passing them to this
+ * callback.
+ *
+ * This callback is only considered if HTTP messaging validation is
+ * turned on (which is on by default, see
+ * `nghttp2_option_set_no_http_messaging()`).
+ *
+ * With this callback, application inspects the incoming invalid
+ * field, and it also can reset stream from this callback by returning
+ * :enum:`NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE`.  By default, the
+ * error code is :enum:`NGHTTP2_PROTOCOL_ERROR`.  To change the error
+ * code, call `nghttp2_submit_rst_stream()` with the error code of
+ * choice in addition to returning
+ * :enum:`NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE`.
+ *
+ * If 0 is returned, the header field is ignored, and the stream is
+ * not reset.
+ */
+typedef int (*nghttp2_on_invalid_header_callback)(
+    nghttp2_session *session, const nghttp2_frame *frame, const uint8_t *name,
+    size_t namelen, const uint8_t *value, size_t valuelen, uint8_t flags,
+    void *user_data);
+
+/**
+ * @functypedef
+ *
+ * Callback function invoked when a invalid header name/value pair is
+ * received for the |frame|.
+ *
+ * The parameter and behaviour are similar to
+ * :type:`nghttp2_on_header_callback2`.  The difference is that this
+ * callback is only invoked when a invalid header name/value pair is
+ * received which is silently ignored if this callback is not set.
+ * Only invalid regular header field are passed to this callback.  In
+ * other words, invalid pseudo header field is not passed to this
+ * callback.  Also header fields which includes upper cased latter are
+ * also treated as error without passing them to this callback.
+ *
+ * This callback is only considered if HTTP messaging validation is
+ * turned on (which is on by default, see
+ * `nghttp2_option_set_no_http_messaging()`).
+ *
+ * With this callback, application inspects the incoming invalid
+ * field, and it also can reset stream from this callback by returning
+ * :enum:`NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE`.  By default, the
+ * error code is :enum:`NGHTTP2_INTERNAL_ERROR`.  To change the error
+ * code, call `nghttp2_submit_rst_stream()` with the error code of
+ * choice in addition to returning
+ * :enum:`NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE`.
+ */
+typedef int (*nghttp2_on_invalid_header_callback2)(
+    nghttp2_session *session, const nghttp2_frame *frame, nghttp2_rcbuf *name,
+    nghttp2_rcbuf *value, uint8_t flags, void *user_data);
+
+/**
+ * @functypedef
+ *
+ * Callback function invoked when the library asks application how
+ * many padding bytes are required for the transmission of the
+ * |frame|.  The application must choose the total length of payload
+ * including padded bytes in range [frame->hd.length, max_payloadlen],
+ * inclusive.  Choosing number not in this range will be treated as
+ * :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`.  Returning
+ * ``frame->hd.length`` means no padding is added.  Returning
+ * :enum:`NGHTTP2_ERR_CALLBACK_FAILURE` will make
+ * `nghttp2_session_send()` and `nghttp2_session_mem_send()` functions
+ * immediately return :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`.
+ *
+ * To set this callback to :type:`nghttp2_session_callbacks`, use
+ * `nghttp2_session_callbacks_set_select_padding_callback()`.
+ */
+typedef ssize_t (*nghttp2_select_padding_callback)(nghttp2_session *session,
+                                                   const nghttp2_frame *frame,
+                                                   size_t max_payloadlen,
+                                                   void *user_data);
+
+/**
+ * @functypedef
+ *
+ * Callback function invoked when library wants to get max length of
+ * data to send data to the remote peer.  The implementation of this
+ * function should return a value in the following range.  [1,
+ * min(|session_remote_window_size|, |stream_remote_window_size|,
+ * |remote_max_frame_size|)].  If a value greater than this range is
+ * returned than the max allow value will be used.  Returning a value
+ * smaller than this range is treated as
+ * :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`.  The |frame_type| is provided
+ * for future extensibility and identifies the type of frame (see
+ * :type:`nghttp2_frame_type`) for which to get the length for.
+ * Currently supported frame types are: :enum:`NGHTTP2_DATA`.
+ *
+ * This callback can be used to control the length in bytes for which
+ * :type:`nghttp2_data_source_read_callback` is allowed to send to the
+ * remote endpoint.  This callback is optional.  Returning
+ * :enum:`NGHTTP2_ERR_CALLBACK_FAILURE` will signal the entire session
+ * failure.
+ *
+ * To set this callback to :type:`nghttp2_session_callbacks`, use
+ * `nghttp2_session_callbacks_set_data_source_read_length_callback()`.
+ */
+typedef ssize_t (*nghttp2_data_source_read_length_callback)(
+    nghttp2_session *session, uint8_t frame_type, int32_t stream_id,
+    int32_t session_remote_window_size, int32_t stream_remote_window_size,
+    uint32_t remote_max_frame_size, void *user_data);
+
+/**
+ * @functypedef
+ *
+ * Callback function invoked when a frame header is received.  The
+ * |hd| points to received frame header.
+ *
+ * Unlike :type:`nghttp2_on_frame_recv_callback`, this callback will
+ * also be called when frame header of CONTINUATION frame is received.
+ *
+ * If both :type:`nghttp2_on_begin_frame_callback` and
+ * :type:`nghttp2_on_begin_headers_callback` are set and HEADERS or
+ * PUSH_PROMISE is received, :type:`nghttp2_on_begin_frame_callback`
+ * will be called first.
+ *
+ * The implementation of this function must return 0 if it succeeds.
+ * If nonzero value is returned, it is treated as fatal error and
+ * `nghttp2_session_recv()` and `nghttp2_session_mem_recv()` functions
+ * immediately return :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`.
+ *
+ * To set this callback to :type:`nghttp2_session_callbacks`, use
+ * `nghttp2_session_callbacks_set_on_begin_frame_callback()`.
+ */
+typedef int (*nghttp2_on_begin_frame_callback)(nghttp2_session *session,
+                                               const nghttp2_frame_hd *hd,
+                                               void *user_data);
+
+/**
+ * @functypedef
+ *
+ * Callback function invoked when chunk of extension frame payload is
+ * received.  The |hd| points to frame header.  The received
+ * chunk is |data| of length |len|.
+ *
+ * The implementation of this function must return 0 if it succeeds.
+ *
+ * To abort processing this extension frame, return
+ * :enum:`NGHTTP2_ERR_CANCEL`.
+ *
+ * If fatal error occurred, application should return
+ * :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`.  In this case,
+ * `nghttp2_session_recv()` and `nghttp2_session_mem_recv()` functions
+ * immediately return :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`.  If the
+ * other values are returned, currently they are treated as
+ * :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`.
+ */
+typedef int (*nghttp2_on_extension_chunk_recv_callback)(
+    nghttp2_session *session, const nghttp2_frame_hd *hd, const uint8_t *data,
+    size_t len, void *user_data);
+
+/**
+ * @functypedef
+ *
+ * Callback function invoked when library asks the application to
+ * unpack extension payload from its wire format.  The extension
+ * payload has been passed to the application using
+ * :type:`nghttp2_on_extension_chunk_recv_callback`.  The frame header
+ * is already unpacked by the library and provided as |hd|.
+ *
+ * To receive extension frames, the application must tell desired
+ * extension frame type to the library using
+ * `nghttp2_option_set_user_recv_extension_type()`.
+ *
+ * The implementation of this function may store the pointer to the
+ * created object as a result of unpacking in |*payload|, and returns
+ * 0.  The pointer stored in |*payload| is opaque to the library, and
+ * the library does not own its pointer.  |*payload| is initialized as
+ * ``NULL``.  The |*payload| is available as ``frame->ext.payload`` in
+ * :type:`nghttp2_on_frame_recv_callback`.  Therefore if application
+ * can free that memory inside :type:`nghttp2_on_frame_recv_callback`
+ * callback.  Of course, application has a liberty not ot use
+ * |*payload|, and do its own mechanism to process extension frames.
+ *
+ * To abort processing this extension frame, return
+ * :enum:`NGHTTP2_ERR_CANCEL`.
+ *
+ * If fatal error occurred, application should return
+ * :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`.  In this case,
+ * `nghttp2_session_recv()` and `nghttp2_session_mem_recv()` functions
+ * immediately return :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`.  If the
+ * other values are returned, currently they are treated as
+ * :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`.
+ */
+typedef int (*nghttp2_unpack_extension_callback)(nghttp2_session *session,
+                                                 void **payload,
+                                                 const nghttp2_frame_hd *hd,
+                                                 void *user_data);
+
+/**
+ * @functypedef
+ *
+ * Callback function invoked when library asks the application to pack
+ * extension payload in its wire format.  The frame header will be
+ * packed by library.  Application must pack payload only.
+ * ``frame->ext.payload`` is the object passed to
+ * `nghttp2_submit_extension()` as payload parameter.  Application
+ * must pack extension payload to the |buf| of its capacity |len|
+ * bytes.  The |len| is at least 16KiB.
+ *
+ * The implementation of this function should return the number of
+ * bytes written into |buf| when it succeeds.
+ *
+ * To abort processing this extension frame, return
+ * :enum:`NGHTTP2_ERR_CANCEL`, and
+ * :type:`nghttp2_on_frame_not_send_callback` will be invoked.
+ *
+ * If fatal error occurred, application should return
+ * :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`.  In this case,
+ * `nghttp2_session_send()` and `nghttp2_session_mem_send()` functions
+ * immediately return :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`.  If the
+ * other values are returned, currently they are treated as
+ * :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`.  If the return value is
+ * strictly larger than |len|, it is treated as
+ * :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`.
+ */
+typedef ssize_t (*nghttp2_pack_extension_callback)(nghttp2_session *session,
+                                                   uint8_t *buf, size_t len,
+                                                   const nghttp2_frame *frame,
+                                                   void *user_data);
+
+/**
+ * @functypedef
+ *
+ * Callback function invoked when library provides the error message
+ * intended for human consumption.  This callback is solely for
+ * debugging purpose.  The |msg| is typically NULL-terminated string
+ * of length |len|.  |len| does not include the sentinel NULL
+ * character.
+ *
+ * This function is deprecated.  The new application should use
+ * :type:`nghttp2_error_callback2`.
+ *
+ * The format of error message may change between nghttp2 library
+ * versions.  The application should not depend on the particular
+ * format.
+ *
+ * Normally, application should return 0 from this callback.  If fatal
+ * error occurred while doing something in this callback, application
+ * should return :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`.  In this case,
+ * library will return immediately with return value
+ * :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`.  Currently, if nonzero value
+ * is returned from this callback, they are treated as
+ * :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`, but application should not
+ * rely on this details.
+ */
+typedef int (*nghttp2_error_callback)(nghttp2_session *session, const char *msg,
+                                      size_t len, void *user_data);
+
+/**
+ * @functypedef
+ *
+ * Callback function invoked when library provides the error code, and
+ * message.  This callback is solely for debugging purpose.
+ * |lib_error_code| is one of error code defined in
+ * :enum:`nghttp2_error`.  The |msg| is typically NULL-terminated
+ * string of length |len|, and intended for human consumption.  |len|
+ * does not include the sentinel NULL character.
+ *
+ * The format of error message may change between nghttp2 library
+ * versions.  The application should not depend on the particular
+ * format.
+ *
+ * Normally, application should return 0 from this callback.  If fatal
+ * error occurred while doing something in this callback, application
+ * should return :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`.  In this case,
+ * library will return immediately with return value
+ * :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`.  Currently, if nonzero value
+ * is returned from this callback, they are treated as
+ * :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`, but application should not
+ * rely on this details.
+ */
+typedef int (*nghttp2_error_callback2)(nghttp2_session *session,
+                                       int lib_error_code, const char *msg,
+                                       size_t len, void *user_data);
+
+struct nghttp2_session_callbacks;
+
+/**
+ * @struct
+ *
+ * Callback functions for :type:`nghttp2_session`.  The details of
+ * this structure are intentionally hidden from the public API.
+ */
+typedef struct nghttp2_session_callbacks nghttp2_session_callbacks;
+
+/**
+ * @function
+ *
+ * Initializes |*callbacks_ptr| with NULL values.
+ *
+ * The initialized object can be used when initializing multiple
+ * :type:`nghttp2_session` objects.
+ *
+ * When the application finished using this object, it can use
+ * `nghttp2_session_callbacks_del()` to free its memory.
+ *
+ * This function returns 0 if it succeeds, or one of the following
+ * negative error codes:
+ *
+ * :enum:`NGHTTP2_ERR_NOMEM`
+ *     Out of memory.
+ */
+NGHTTP2_EXTERN int
+nghttp2_session_callbacks_new(nghttp2_session_callbacks **callbacks_ptr);
+
+/**
+ * @function
+ *
+ * Frees any resources allocated for |callbacks|.  If |callbacks| is
+ * ``NULL``, this function does nothing.
+ */
+NGHTTP2_EXTERN void
+nghttp2_session_callbacks_del(nghttp2_session_callbacks *callbacks);
+
+/**
+ * @function
+ *
+ * Sets callback function invoked when a session wants to send data to
+ * the remote peer.  This callback is not necessary if the application
+ * uses solely `nghttp2_session_mem_send()` to serialize data to
+ * transmit.
+ */
+NGHTTP2_EXTERN void nghttp2_session_callbacks_set_send_callback(
+    nghttp2_session_callbacks *cbs, nghttp2_send_callback send_callback);
+
+/**
+ * @function
+ *
+ * Sets callback function invoked when the a session wants to receive
+ * data from the remote peer.  This callback is not necessary if the
+ * application uses solely `nghttp2_session_mem_recv()` to process
+ * received data.
+ */
+NGHTTP2_EXTERN void nghttp2_session_callbacks_set_recv_callback(
+    nghttp2_session_callbacks *cbs, nghttp2_recv_callback recv_callback);
+
+/**
+ * @function
+ *
+ * Sets callback function invoked by `nghttp2_session_recv()` and
+ * `nghttp2_session_mem_recv()` when a frame is received.
+ */
+NGHTTP2_EXTERN void nghttp2_session_callbacks_set_on_frame_recv_callback(
+    nghttp2_session_callbacks *cbs,
+    nghttp2_on_frame_recv_callback on_frame_recv_callback);
+
+/**
+ * @function
+ *
+ * Sets callback function invoked by `nghttp2_session_recv()` and
+ * `nghttp2_session_mem_recv()` when an invalid non-DATA frame is
+ * received.
+ */
+NGHTTP2_EXTERN void
+nghttp2_session_callbacks_set_on_invalid_frame_recv_callback(
+    nghttp2_session_callbacks *cbs,
+    nghttp2_on_invalid_frame_recv_callback on_invalid_frame_recv_callback);
+
+/**
+ * @function
+ *
+ * Sets callback function invoked when a chunk of data in DATA frame
+ * is received.
+ */
+NGHTTP2_EXTERN void nghttp2_session_callbacks_set_on_data_chunk_recv_callback(
+    nghttp2_session_callbacks *cbs,
+    nghttp2_on_data_chunk_recv_callback on_data_chunk_recv_callback);
+
+/**
+ * @function
+ *
+ * Sets callback function invoked before a non-DATA frame is sent.
+ */
+NGHTTP2_EXTERN void nghttp2_session_callbacks_set_before_frame_send_callback(
+    nghttp2_session_callbacks *cbs,
+    nghttp2_before_frame_send_callback before_frame_send_callback);
+
+/**
+ * @function
+ *
+ * Sets callback function invoked after a frame is sent.
+ */
+NGHTTP2_EXTERN void nghttp2_session_callbacks_set_on_frame_send_callback(
+    nghttp2_session_callbacks *cbs,
+    nghttp2_on_frame_send_callback on_frame_send_callback);
+
+/**
+ * @function
+ *
+ * Sets callback function invoked when a non-DATA frame is not sent
+ * because of an error.
+ */
+NGHTTP2_EXTERN void nghttp2_session_callbacks_set_on_frame_not_send_callback(
+    nghttp2_session_callbacks *cbs,
+    nghttp2_on_frame_not_send_callback on_frame_not_send_callback);
+
+/**
+ * @function
+ *
+ * Sets callback function invoked when the stream is closed.
+ */
+NGHTTP2_EXTERN void nghttp2_session_callbacks_set_on_stream_close_callback(
+    nghttp2_session_callbacks *cbs,
+    nghttp2_on_stream_close_callback on_stream_close_callback);
+
+/**
+ * @function
+ *
+ * Sets callback function invoked when the reception of header block
+ * in HEADERS or PUSH_PROMISE is started.
+ */
+NGHTTP2_EXTERN void nghttp2_session_callbacks_set_on_begin_headers_callback(
+    nghttp2_session_callbacks *cbs,
+    nghttp2_on_begin_headers_callback on_begin_headers_callback);
+
+/**
+ * @function
+ *
+ * Sets callback function invoked when a header name/value pair is
+ * received.  If both
+ * `nghttp2_session_callbacks_set_on_header_callback()` and
+ * `nghttp2_session_callbacks_set_on_header_callback2()` are used to
+ * set callbacks, the latter has the precedence.
+ */
+NGHTTP2_EXTERN void nghttp2_session_callbacks_set_on_header_callback(
+    nghttp2_session_callbacks *cbs,
+    nghttp2_on_header_callback on_header_callback);
+
+/**
+ * @function
+ *
+ * Sets callback function invoked when a header name/value pair is
+ * received.
+ */
+NGHTTP2_EXTERN void nghttp2_session_callbacks_set_on_header_callback2(
+    nghttp2_session_callbacks *cbs,
+    nghttp2_on_header_callback2 on_header_callback2);
+
+/**
+ * @function
+ *
+ * Sets callback function invoked when a invalid header name/value
+ * pair is received.  If both
+ * `nghttp2_session_callbacks_set_on_invalid_header_callback()` and
+ * `nghttp2_session_callbacks_set_on_invalid_header_callback2()` are
+ * used to set callbacks, the latter takes the precedence.
+ */
+NGHTTP2_EXTERN void nghttp2_session_callbacks_set_on_invalid_header_callback(
+    nghttp2_session_callbacks *cbs,
+    nghttp2_on_invalid_header_callback on_invalid_header_callback);
+
+/**
+ * @function
+ *
+ * Sets callback function invoked when a invalid header name/value
+ * pair is received.
+ */
+NGHTTP2_EXTERN void nghttp2_session_callbacks_set_on_invalid_header_callback2(
+    nghttp2_session_callbacks *cbs,
+    nghttp2_on_invalid_header_callback2 on_invalid_header_callback2);
+
+/**
+ * @function
+ *
+ * Sets callback function invoked when the library asks application
+ * how many padding bytes are required for the transmission of the
+ * given frame.
+ */
+NGHTTP2_EXTERN void nghttp2_session_callbacks_set_select_padding_callback(
+    nghttp2_session_callbacks *cbs,
+    nghttp2_select_padding_callback select_padding_callback);
+
+/**
+ * @function
+ *
+ * Sets callback function determine the length allowed in
+ * :type:`nghttp2_data_source_read_callback`.
+ */
+NGHTTP2_EXTERN void
+nghttp2_session_callbacks_set_data_source_read_length_callback(
+    nghttp2_session_callbacks *cbs,
+    nghttp2_data_source_read_length_callback data_source_read_length_callback);
+
+/**
+ * @function
+ *
+ * Sets callback function invoked when a frame header is received.
+ */
+NGHTTP2_EXTERN void nghttp2_session_callbacks_set_on_begin_frame_callback(
+    nghttp2_session_callbacks *cbs,
+    nghttp2_on_begin_frame_callback on_begin_frame_callback);
+
+/**
+ * @function
+ *
+ * Sets callback function invoked when
+ * :enum:`NGHTTP2_DATA_FLAG_NO_COPY` is used in
+ * :type:`nghttp2_data_source_read_callback` to avoid data copy.
+ */
+NGHTTP2_EXTERN void nghttp2_session_callbacks_set_send_data_callback(
+    nghttp2_session_callbacks *cbs,
+    nghttp2_send_data_callback send_data_callback);
+
+/**
+ * @function
+ *
+ * Sets callback function invoked when the library asks the
+ * application to pack extension frame payload in wire format.
+ */
+NGHTTP2_EXTERN void nghttp2_session_callbacks_set_pack_extension_callback(
+    nghttp2_session_callbacks *cbs,
+    nghttp2_pack_extension_callback pack_extension_callback);
+
+/**
+ * @function
+ *
+ * Sets callback function invoked when the library asks the
+ * application to unpack extension frame payload from wire format.
+ */
+NGHTTP2_EXTERN void nghttp2_session_callbacks_set_unpack_extension_callback(
+    nghttp2_session_callbacks *cbs,
+    nghttp2_unpack_extension_callback unpack_extension_callback);
+
+/**
+ * @function
+ *
+ * Sets callback function invoked when chunk of extension frame
+ * payload is received.
+ */
+NGHTTP2_EXTERN void
+nghttp2_session_callbacks_set_on_extension_chunk_recv_callback(
+    nghttp2_session_callbacks *cbs,
+    nghttp2_on_extension_chunk_recv_callback on_extension_chunk_recv_callback);
+
+/**
+ * @function
+ *
+ * Sets callback function invoked when library tells error message to
+ * the application.
+ *
+ * This function is deprecated.  The new application should use
+ * `nghttp2_session_callbacks_set_error_callback2()`.
+ *
+ * If both :type:`nghttp2_error_callback` and
+ * :type:`nghttp2_error_callback2` are set, the latter takes
+ * precedence.
+ */
+NGHTTP2_EXTERN void nghttp2_session_callbacks_set_error_callback(
+    nghttp2_session_callbacks *cbs, nghttp2_error_callback error_callback);
+
+/**
+ * @function
+ *
+ * Sets callback function invoked when library tells error code, and
+ * message to the application.
+ *
+ * If both :type:`nghttp2_error_callback` and
+ * :type:`nghttp2_error_callback2` are set, the latter takes
+ * precedence.
+ */
+NGHTTP2_EXTERN void nghttp2_session_callbacks_set_error_callback2(
+    nghttp2_session_callbacks *cbs, nghttp2_error_callback2 error_callback2);
+
+/**
+ * @functypedef
+ *
+ * Custom memory allocator to replace malloc().  The |mem_user_data|
+ * is the mem_user_data member of :type:`nghttp2_mem` structure.
+ */
+typedef void *(*nghttp2_malloc)(size_t size, void *mem_user_data);
+
+/**
+ * @functypedef
+ *
+ * Custom memory allocator to replace free().  The |mem_user_data| is
+ * the mem_user_data member of :type:`nghttp2_mem` structure.
+ */
+typedef void (*nghttp2_free)(void *ptr, void *mem_user_data);
+
+/**
+ * @functypedef
+ *
+ * Custom memory allocator to replace calloc().  The |mem_user_data|
+ * is the mem_user_data member of :type:`nghttp2_mem` structure.
+ */
+typedef void *(*nghttp2_calloc)(size_t nmemb, size_t size, void *mem_user_data);
+
+/**
+ * @functypedef
+ *
+ * Custom memory allocator to replace realloc().  The |mem_user_data|
+ * is the mem_user_data member of :type:`nghttp2_mem` structure.
+ */
+typedef void *(*nghttp2_realloc)(void *ptr, size_t size, void *mem_user_data);
+
+/**
+ * @struct
+ *
+ * Custom memory allocator functions and user defined pointer.  The
+ * |mem_user_data| member is passed to each allocator function.  This
+ * can be used, for example, to achieve per-session memory pool.
+ *
+ * In the following example code, ``my_malloc``, ``my_free``,
+ * ``my_calloc`` and ``my_realloc`` are the replacement of the
+ * standard allocators ``malloc``, ``free``, ``calloc`` and
+ * ``realloc`` respectively::
+ *
+ *     void *my_malloc_cb(size_t size, void *mem_user_data) {
+ *       return my_malloc(size);
+ *     }
+ *
+ *     void my_free_cb(void *ptr, void *mem_user_data) { my_free(ptr); }
+ *
+ *     void *my_calloc_cb(size_t nmemb, size_t size, void *mem_user_data) {
+ *       return my_calloc(nmemb, size);
+ *     }
+ *
+ *     void *my_realloc_cb(void *ptr, size_t size, void *mem_user_data) {
+ *       return my_realloc(ptr, size);
+ *     }
+ *
+ *     void session_new() {
+ *       nghttp2_session *session;
+ *       nghttp2_session_callbacks *callbacks;
+ *       nghttp2_mem mem = {NULL, my_malloc_cb, my_free_cb, my_calloc_cb,
+ *                          my_realloc_cb};
+ *
+ *       ...
+ *
+ *       nghttp2_session_client_new3(&session, callbacks, NULL, NULL, &mem);
+ *
+ *       ...
+ *     }
+ */
+typedef struct {
+  /**
+   * An arbitrary user supplied data.  This is passed to each
+   * allocator function.
+   */
+  void *mem_user_data;
+  /**
+   * Custom allocator function to replace malloc().
+   */
+  nghttp2_malloc malloc;
+  /**
+   * Custom allocator function to replace free().
+   */
+  nghttp2_free free;
+  /**
+   * Custom allocator function to replace calloc().
+   */
+  nghttp2_calloc calloc;
+  /**
+   * Custom allocator function to replace realloc().
+   */
+  nghttp2_realloc realloc;
+} nghttp2_mem;
+
+struct nghttp2_option;
+
+/**
+ * @struct
+ *
+ * Configuration options for :type:`nghttp2_session`.  The details of
+ * this structure are intentionally hidden from the public API.
+ */
+typedef struct nghttp2_option nghttp2_option;
+
+/**
+ * @function
+ *
+ * Initializes |*option_ptr| with default values.
+ *
+ * When the application finished using this object, it can use
+ * `nghttp2_option_del()` to free its memory.
+ *
+ * This function returns 0 if it succeeds, or one of the following
+ * negative error codes:
+ *
+ * :enum:`NGHTTP2_ERR_NOMEM`
+ *     Out of memory.
+ */
+NGHTTP2_EXTERN int nghttp2_option_new(nghttp2_option **option_ptr);
+
+/**
+ * @function
+ *
+ * Frees any resources allocated for |option|.  If |option| is
+ * ``NULL``, this function does nothing.
+ */
+NGHTTP2_EXTERN void nghttp2_option_del(nghttp2_option *option);
+
+/**
+ * @function
+ *
+ * This option prevents the library from sending WINDOW_UPDATE for a
+ * connection automatically.  If this option is set to nonzero, the
+ * library won't send WINDOW_UPDATE for DATA until application calls
+ * `nghttp2_session_consume()` to indicate the consumed amount of
+ * data.  Don't use `nghttp2_submit_window_update()` for this purpose.
+ * By default, this option is set to zero.
+ */
+NGHTTP2_EXTERN void
+nghttp2_option_set_no_auto_window_update(nghttp2_option *option, int val);
+
+/**
+ * @function
+ *
+ * This option sets the SETTINGS_MAX_CONCURRENT_STREAMS value of
+ * remote endpoint as if it is received in SETTINGS frame.  Without
+ * specifying this option, the maximum number of outgoing concurrent
+ * streams is initially limited to 100 to avoid issues when the local
+ * endpoint submits lots of requests before receiving initial SETTINGS
+ * frame from the remote endpoint, since sending them at once to the
+ * remote endpoint could lead to rejection of some of the requests.
+ * This value will be overwritten when the local endpoint receives
+ * initial SETTINGS frame from the remote endpoint, either to the
+ * value advertised in SETTINGS_MAX_CONCURRENT_STREAMS or to the
+ * default value (unlimited) if none was advertised.
+ */
+NGHTTP2_EXTERN void
+nghttp2_option_set_peer_max_concurrent_streams(nghttp2_option *option,
+                                               uint32_t val);
+
+/**
+ * @function
+ *
+ * By default, nghttp2 library, if configured as server, requires
+ * first 24 bytes of client magic byte string (MAGIC).  In most cases,
+ * this will simplify the implementation of server.  But sometimes
+ * server may want to detect the application protocol based on first
+ * few bytes on clear text communication.
+ *
+ * If this option is used with nonzero |val|, nghttp2 library does not
+ * handle MAGIC.  It still checks following SETTINGS frame.  This
+ * means that applications should deal with MAGIC by themselves.
+ *
+ * If this option is not used or used with zero value, if MAGIC does
+ * not match :macro:`NGHTTP2_CLIENT_MAGIC`, `nghttp2_session_recv()`
+ * and `nghttp2_session_mem_recv()` will return error
+ * :enum:`NGHTTP2_ERR_BAD_CLIENT_MAGIC`, which is fatal error.
+ */
+NGHTTP2_EXTERN void
+nghttp2_option_set_no_recv_client_magic(nghttp2_option *option, int val);
+
+/**
+ * @function
+ *
+ * By default, nghttp2 library enforces subset of HTTP Messaging rules
+ * described in `HTTP/2 specification, section 8
+ * <https://tools.ietf.org/html/rfc7540#section-8>`_.  See
+ * :ref:`http-messaging` section for details.  For those applications
+ * who use nghttp2 library as non-HTTP use, give nonzero to |val| to
+ * disable this enforcement.  Please note that disabling this feature
+ * does not change the fundamental client and server model of HTTP.
+ * That is, even if the validation is disabled, only client can send
+ * requests.
+ */
+NGHTTP2_EXTERN void nghttp2_option_set_no_http_messaging(nghttp2_option *option,
+                                                         int val);
+
+/**
+ * @function
+ *
+ * RFC 7540 does not enforce any limit on the number of incoming
+ * reserved streams (in RFC 7540 terms, streams in reserved (remote)
+ * state).  This only affects client side, since only server can push
+ * streams.  Malicious server can push arbitrary number of streams,
+ * and make client's memory exhausted.  This option can set the
+ * maximum number of such incoming streams to avoid possible memory
+ * exhaustion.  If this option is set, and pushed streams are
+ * automatically closed on reception, without calling user provided
+ * callback, if they exceed the given limit.  The default value is
+ * 200.  If session is configured as server side, this option has no
+ * effect.  Server can control the number of streams to push.
+ */
+NGHTTP2_EXTERN void
+nghttp2_option_set_max_reserved_remote_streams(nghttp2_option *option,
+                                               uint32_t val);
+
+/**
+ * @function
+ *
+ * Sets extension frame type the application is willing to handle with
+ * user defined callbacks (see
+ * :type:`nghttp2_on_extension_chunk_recv_callback` and
+ * :type:`nghttp2_unpack_extension_callback`).  The |type| is
+ * extension frame type, and must be strictly greater than 0x9.
+ * Otherwise, this function does nothing.  The application can call
+ * this function multiple times to set more than one frame type to
+ * receive.  The application does not have to call this function if it
+ * just sends extension frames.
+ */
+NGHTTP2_EXTERN void
+nghttp2_option_set_user_recv_extension_type(nghttp2_option *option,
+                                            uint8_t type);
+
+/**
+ * @function
+ *
+ * Sets extension frame type the application is willing to receive
+ * using builtin handler.  The |type| is the extension frame type to
+ * receive, and must be strictly greater than 0x9.  Otherwise, this
+ * function does nothing.  The application can call this function
+ * multiple times to set more than one frame type to receive.  The
+ * application does not have to call this function if it just sends
+ * extension frames.
+ *
+ * If same frame type is passed to both
+ * `nghttp2_option_set_builtin_recv_extension_type()` and
+ * `nghttp2_option_set_user_recv_extension_type()`, the latter takes
+ * precedence.
+ */
+NGHTTP2_EXTERN void
+nghttp2_option_set_builtin_recv_extension_type(nghttp2_option *option,
+                                               uint8_t type);
+
+/**
+ * @function
+ *
+ * This option prevents the library from sending PING frame with ACK
+ * flag set automatically when PING frame without ACK flag set is
+ * received.  If this option is set to nonzero, the library won't send
+ * PING frame with ACK flag set in the response for incoming PING
+ * frame.  The application can send PING frame with ACK flag set using
+ * `nghttp2_submit_ping()` with :enum:`NGHTTP2_FLAG_ACK` as flags
+ * parameter.
+ */
+NGHTTP2_EXTERN void nghttp2_option_set_no_auto_ping_ack(nghttp2_option *option,
+                                                        int val);
+
+/**
+ * @function
+ *
+ * This option sets the maximum length of header block (a set of
+ * header fields per one HEADERS frame) to send.  The length of a
+ * given set of header fields is calculated using
+ * `nghttp2_hd_deflate_bound()`.  The default value is 64KiB.  If
+ * application attempts to send header fields larger than this limit,
+ * the transmission of the frame fails with error code
+ * :enum:`NGHTTP2_ERR_FRAME_SIZE_ERROR`.
+ */
+NGHTTP2_EXTERN void
+nghttp2_option_set_max_send_header_block_length(nghttp2_option *option,
+                                                size_t val);
+
+/**
+ * @function
+ *
+ * This option sets the maximum dynamic table size for deflating
+ * header fields.  The default value is 4KiB.  In HTTP/2, receiver of
+ * deflated header block can specify maximum dynamic table size.  The
+ * actual maximum size is the minimum of the size receiver specified
+ * and this option value.
+ */
+NGHTTP2_EXTERN void
+nghttp2_option_set_max_deflate_dynamic_table_size(nghttp2_option *option,
+                                                  size_t val);
+
+/**
+ * @function
+ *
+ * This option prevents the library from retaining closed streams to
+ * maintain the priority tree.  If this option is set to nonzero,
+ * applications can discard closed stream completely to save memory.
+ */
+NGHTTP2_EXTERN void nghttp2_option_set_no_closed_streams(nghttp2_option *option,
+                                                         int val);
+
+/**
+ * @function
+ *
+ * This function sets the maximum number of outgoing SETTINGS ACK and
+ * PING ACK frames retained in :type:`nghttp2_session` object.  If
+ * more than those frames are retained, the peer is considered to be
+ * misbehaving and session will be closed.  The default value is 1000.
+ */
+NGHTTP2_EXTERN void nghttp2_option_set_max_outbound_ack(nghttp2_option *option,
+                                                        size_t val);
+
+/**
+ * @function
+ *
+ * Initializes |*session_ptr| for client use.  The all members of
+ * |callbacks| are copied to |*session_ptr|.  Therefore |*session_ptr|
+ * does not store |callbacks|.  The |user_data| is an arbitrary user
+ * supplied data, which will be passed to the callback functions.
+ *
+ * The :type:`nghttp2_send_callback` must be specified.  If the
+ * application code uses `nghttp2_session_recv()`, the
+ * :type:`nghttp2_recv_callback` must be specified.  The other members
+ * of |callbacks| can be ``NULL``.
+ *
+ * If this function fails, |*session_ptr| is left untouched.
+ *
+ * This function returns 0 if it succeeds, or one of the following
+ * negative error codes:
+ *
+ * :enum:`NGHTTP2_ERR_NOMEM`
+ *     Out of memory.
+ */
+NGHTTP2_EXTERN int
+nghttp2_session_client_new(nghttp2_session **session_ptr,
+                           const nghttp2_session_callbacks *callbacks,
+                           void *user_data);
+
+/**
+ * @function
+ *
+ * Initializes |*session_ptr| for server use.  The all members of
+ * |callbacks| are copied to |*session_ptr|. Therefore |*session_ptr|
+ * does not store |callbacks|.  The |user_data| is an arbitrary user
+ * supplied data, which will be passed to the callback functions.
+ *
+ * The :type:`nghttp2_send_callback` must be specified.  If the
+ * application code uses `nghttp2_session_recv()`, the
+ * :type:`nghttp2_recv_callback` must be specified.  The other members
+ * of |callbacks| can be ``NULL``.
+ *
+ * If this function fails, |*session_ptr| is left untouched.
+ *
+ * This function returns 0 if it succeeds, or one of the following
+ * negative error codes:
+ *
+ * :enum:`NGHTTP2_ERR_NOMEM`
+ *     Out of memory.
+ */
+NGHTTP2_EXTERN int
+nghttp2_session_server_new(nghttp2_session **session_ptr,
+                           const nghttp2_session_callbacks *callbacks,
+                           void *user_data);
+
+/**
+ * @function
+ *
+ * Like `nghttp2_session_client_new()`, but with additional options
+ * specified in the |option|.
+ *
+ * The |option| can be ``NULL`` and the call is equivalent to
+ * `nghttp2_session_client_new()`.
+ *
+ * This function does not take ownership |option|.  The application is
+ * responsible for freeing |option| if it finishes using the object.
+ *
+ * The library code does not refer to |option| after this function
+ * returns.
+ *
+ * This function returns 0 if it succeeds, or one of the following
+ * negative error codes:
+ *
+ * :enum:`NGHTTP2_ERR_NOMEM`
+ *     Out of memory.
+ */
+NGHTTP2_EXTERN int
+nghttp2_session_client_new2(nghttp2_session **session_ptr,
+                            const nghttp2_session_callbacks *callbacks,
+                            void *user_data, const nghttp2_option *option);
+
+/**
+ * @function
+ *
+ * Like `nghttp2_session_server_new()`, but with additional options
+ * specified in the |option|.
+ *
+ * The |option| can be ``NULL`` and the call is equivalent to
+ * `nghttp2_session_server_new()`.
+ *
+ * This function does not take ownership |option|.  The application is
+ * responsible for freeing |option| if it finishes using the object.
+ *
+ * The library code does not refer to |option| after this function
+ * returns.
+ *
+ * This function returns 0 if it succeeds, or one of the following
+ * negative error codes:
+ *
+ * :enum:`NGHTTP2_ERR_NOMEM`
+ *     Out of memory.
+ */
+NGHTTP2_EXTERN int
+nghttp2_session_server_new2(nghttp2_session **session_ptr,
+                            const nghttp2_session_callbacks *callbacks,
+                            void *user_data, const nghttp2_option *option);
+
+/**
+ * @function
+ *
+ * Like `nghttp2_session_client_new2()`, but with additional custom
+ * memory allocator specified in the |mem|.
+ *
+ * The |mem| can be ``NULL`` and the call is equivalent to
+ * `nghttp2_session_client_new2()`.
+ *
+ * This function does not take ownership |mem|.  The application is
+ * responsible for freeing |mem|.
+ *
+ * The library code does not refer to |mem| pointer after this
+ * function returns, so the application can safely free it.
+ *
+ * This function returns 0 if it succeeds, or one of the following
+ * negative error codes:
+ *
+ * :enum:`NGHTTP2_ERR_NOMEM`
+ *     Out of memory.
+ */
+NGHTTP2_EXTERN int nghttp2_session_client_new3(
+    nghttp2_session **session_ptr, const nghttp2_session_callbacks *callbacks,
+    void *user_data, const nghttp2_option *option, nghttp2_mem *mem);
+
+/**
+ * @function
+ *
+ * Like `nghttp2_session_server_new2()`, but with additional custom
+ * memory allocator specified in the |mem|.
+ *
+ * The |mem| can be ``NULL`` and the call is equivalent to
+ * `nghttp2_session_server_new2()`.
+ *
+ * This function does not take ownership |mem|.  The application is
+ * responsible for freeing |mem|.
+ *
+ * The library code does not refer to |mem| pointer after this
+ * function returns, so the application can safely free it.
+ *
+ * This function returns 0 if it succeeds, or one of the following
+ * negative error codes:
+ *
+ * :enum:`NGHTTP2_ERR_NOMEM`
+ *     Out of memory.
+ */
+NGHTTP2_EXTERN int nghttp2_session_server_new3(
+    nghttp2_session **session_ptr, const nghttp2_session_callbacks *callbacks,
+    void *user_data, const nghttp2_option *option, nghttp2_mem *mem);
+
+/**
+ * @function
+ *
+ * Frees any resources allocated for |session|.  If |session| is
+ * ``NULL``, this function does nothing.
+ */
+NGHTTP2_EXTERN void nghttp2_session_del(nghttp2_session *session);
+
+/**
+ * @function
+ *
+ * Sends pending frames to the remote peer.
+ *
+ * This function retrieves the highest prioritized frame from the
+ * outbound queue and sends it to the remote peer.  It does this as
+ * many as possible until the user callback
+ * :type:`nghttp2_send_callback` returns
+ * :enum:`NGHTTP2_ERR_WOULDBLOCK` or the outbound queue becomes empty.
+ * This function calls several callback functions which are passed
+ * when initializing the |session|.  Here is the simple time chart
+ * which tells when each callback is invoked:
+ *
+ * 1. Get the next frame to send from outbound queue.
+ *
+ * 2. Prepare transmission of the frame.
+ *
+ * 3. If the control frame cannot be sent because some preconditions
+ *    are not met (e.g., request HEADERS cannot be sent after GOAWAY),
+ *    :type:`nghttp2_on_frame_not_send_callback` is invoked.  Abort
+ *    the following steps.
+ *
+ * 4. If the frame is HEADERS, PUSH_PROMISE or DATA,
+ *    :type:`nghttp2_select_padding_callback` is invoked.
+ *
+ * 5. If the frame is request HEADERS, the stream is opened here.
+ *
+ * 6. :type:`nghttp2_before_frame_send_callback` is invoked.
+ *
+ * 7. If :enum:`NGHTTP2_ERR_CANCEL` is returned from
+ *    :type:`nghttp2_before_frame_send_callback`, the current frame
+ *    transmission is canceled, and
+ *    :type:`nghttp2_on_frame_not_send_callback` is invoked.  Abort
+ *    the following steps.
+ *
+ * 8. :type:`nghttp2_send_callback` is invoked one or more times to
+ *    send the frame.
+ *
+ * 9. :type:`nghttp2_on_frame_send_callback` is invoked.
+ *
+ * 10. If the transmission of the frame triggers closure of the
+ *     stream, the stream is closed and
+ *     :type:`nghttp2_on_stream_close_callback` is invoked.
+ *
+ * This function returns 0 if it succeeds, or one of the following
+ * negative error codes:
+ *
+ * :enum:`NGHTTP2_ERR_NOMEM`
+ *     Out of memory.
+ * :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`
+ *     The callback function failed.
+ */
+NGHTTP2_EXTERN int nghttp2_session_send(nghttp2_session *session);
+
+/**
+ * @function
+ *
+ * Returns the serialized data to send.
+ *
+ * This function behaves like `nghttp2_session_send()` except that it
+ * does not use :type:`nghttp2_send_callback` to transmit data.
+ * Instead, it assigns the pointer to the serialized data to the
+ * |*data_ptr| and returns its length.  The other callbacks are called
+ * in the same way as they are in `nghttp2_session_send()`.
+ *
+ * If no data is available to send, this function returns 0.
+ *
+ * This function may not return all serialized data in one invocation.
+ * To get all data, call this function repeatedly until it returns 0
+ * or one of negative error codes.
+ *
+ * The assigned |*data_ptr| is valid until the next call of
+ * `nghttp2_session_mem_send()` or `nghttp2_session_send()`.
+ *
+ * The caller must send all data before sending the next chunk of
+ * data.
+ *
+ * This function returns the length of the data pointed by the
+ * |*data_ptr| if it succeeds, or one of the following negative error
+ * codes:
+ *
+ * :enum:`NGHTTP2_ERR_NOMEM`
+ *     Out of memory.
+ *
+ * .. note::
+ *
+ *   This function may produce very small byte string.  If that is the
+ *   case, and application disables Nagle algorithm (``TCP_NODELAY``),
+ *   then writing this small chunk leads to very small packet, and it
+ *   is very inefficient.  An application should be responsible to
+ *   buffer up small chunks of data as necessary to avoid this
+ *   situation.
+ */
+NGHTTP2_EXTERN ssize_t nghttp2_session_mem_send(nghttp2_session *session,
+                                                const uint8_t **data_ptr);
+
+/**
+ * @function
+ *
+ * Receives frames from the remote peer.
+ *
+ * This function receives as many frames as possible until the user
+ * callback :type:`nghttp2_recv_callback` returns
+ * :enum:`NGHTTP2_ERR_WOULDBLOCK`.  This function calls several
+ * callback functions which are passed when initializing the
+ * |session|.  Here is the simple time chart which tells when each
+ * callback is invoked:
+ *
+ * 1. :type:`nghttp2_recv_callback` is invoked one or more times to
+ *    receive frame header.
+ *
+ * 2. When frame header is received,
+ *    :type:`nghttp2_on_begin_frame_callback` is invoked.
+ *
+ * 3. If the frame is DATA frame:
+ *
+ *    1. :type:`nghttp2_recv_callback` is invoked to receive DATA
+ *       payload. For each chunk of data,
+ *       :type:`nghttp2_on_data_chunk_recv_callback` is invoked.
+ *
+ *    2. If one DATA frame is completely received,
+ *       :type:`nghttp2_on_frame_recv_callback` is invoked.  If the
+ *       reception of the frame triggers the closure of the stream,
+ *       :type:`nghttp2_on_stream_close_callback` is invoked.
+ *
+ * 4. If the frame is the control frame:
+ *
+ *    1. :type:`nghttp2_recv_callback` is invoked one or more times to
+ *       receive whole frame.
+ *
+ *    2. If the received frame is valid, then following actions are
+ *       taken.  If the frame is either HEADERS or PUSH_PROMISE,
+ *       :type:`nghttp2_on_begin_headers_callback` is invoked.  Then
+ *       :type:`nghttp2_on_header_callback` is invoked for each header
+ *       name/value pair.  For invalid header field,
+ *       :type:`nghttp2_on_invalid_header_callback` is called.  After
+ *       all name/value pairs are emitted successfully,
+ *       :type:`nghttp2_on_frame_recv_callback` is invoked.  For other
+ *       frames, :type:`nghttp2_on_frame_recv_callback` is invoked.
+ *       If the reception of the frame triggers the closure of the
+ *       stream, :type:`nghttp2_on_stream_close_callback` is invoked.
+ *
+ *    3. If the received frame is unpacked but is interpreted as
+ *       invalid, :type:`nghttp2_on_invalid_frame_recv_callback` is
+ *       invoked.
+ *
+ * This function returns 0 if it succeeds, or one of the following
+ * negative error codes:
+ *
+ * :enum:`NGHTTP2_ERR_EOF`
+ *     The remote peer did shutdown on the connection.
+ * :enum:`NGHTTP2_ERR_NOMEM`
+ *     Out of memory.
+ * :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`
+ *     The callback function failed.
+ * :enum:`NGHTTP2_ERR_BAD_CLIENT_MAGIC`
+ *     Invalid client magic was detected.  This error only returns
+ *     when |session| was configured as server and
+ *     `nghttp2_option_set_no_recv_client_magic()` is not used with
+ *     nonzero value.
+ * :enum:`NGHTTP2_ERR_FLOODED`
+ *     Flooding was detected in this HTTP/2 session, and it must be
+ *     closed.  This is most likely caused by misbehaviour of peer.
+ */
+NGHTTP2_EXTERN int nghttp2_session_recv(nghttp2_session *session);
+
+/**
+ * @function
+ *
+ * Processes data |in| as an input from the remote endpoint.  The
+ * |inlen| indicates the number of bytes in the |in|.
+ *
+ * This function behaves like `nghttp2_session_recv()` except that it
+ * does not use :type:`nghttp2_recv_callback` to receive data; the
+ * |in| is the only data for the invocation of this function.  If all
+ * bytes are processed, this function returns.  The other callbacks
+ * are called in the same way as they are in `nghttp2_session_recv()`.
+ *
+ * In the current implementation, this function always tries to
+ * processes all input data unless either an error occurs or
+ * :enum:`NGHTTP2_ERR_PAUSE` is returned from
+ * :type:`nghttp2_on_header_callback` or
+ * :type:`nghttp2_on_data_chunk_recv_callback`.  If
+ * :enum:`NGHTTP2_ERR_PAUSE` is used, the return value includes the
+ * number of bytes which was used to produce the data or frame for the
+ * callback.
+ *
+ * This function returns the number of processed bytes, or one of the
+ * following negative error codes:
+ *
+ * :enum:`NGHTTP2_ERR_NOMEM`
+ *     Out of memory.
+ * :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`
+ *     The callback function failed.
+ * :enum:`NGHTTP2_ERR_BAD_CLIENT_MAGIC`
+ *     Invalid client magic was detected.  This error only returns
+ *     when |session| was configured as server and
+ *     `nghttp2_option_set_no_recv_client_magic()` is not used with
+ *     nonzero value.
+ * :enum:`NGHTTP2_ERR_FLOODED`
+ *     Flooding was detected in this HTTP/2 session, and it must be
+ *     closed.  This is most likely caused by misbehaviour of peer.
+ */
+NGHTTP2_EXTERN ssize_t nghttp2_session_mem_recv(nghttp2_session *session,
+                                                const uint8_t *in,
+                                                size_t inlen);
+
+/**
+ * @function
+ *
+ * Puts back previously deferred DATA frame in the stream |stream_id|
+ * to the outbound queue.
+ *
+ * This function returns 0 if it succeeds, or one of the following
+ * negative error codes:
+ *
+ * :enum:`NGHTTP2_ERR_INVALID_ARGUMENT`
+ *     The stream does not exist; or no deferred data exist.
+ * :enum:`NGHTTP2_ERR_NOMEM`
+ *     Out of memory.
+ */
+NGHTTP2_EXTERN int nghttp2_session_resume_data(nghttp2_session *session,
+                                               int32_t stream_id);
+
+/**
+ * @function
+ *
+ * Returns nonzero value if |session| wants to receive data from the
+ * remote peer.
+ *
+ * If both `nghttp2_session_want_read()` and
+ * `nghttp2_session_want_write()` return 0, the application should
+ * drop the connection.
+ */
+NGHTTP2_EXTERN int nghttp2_session_want_read(nghttp2_session *session);
+
+/**
+ * @function
+ *
+ * Returns nonzero value if |session| wants to send data to the remote
+ * peer.
+ *
+ * If both `nghttp2_session_want_read()` and
+ * `nghttp2_session_want_write()` return 0, the application should
+ * drop the connection.
+ */
+NGHTTP2_EXTERN int nghttp2_session_want_write(nghttp2_session *session);
+
+/**
+ * @function
+ *
+ * Returns stream_user_data for the stream |stream_id|.  The
+ * stream_user_data is provided by `nghttp2_submit_request()`,
+ * `nghttp2_submit_headers()` or
+ * `nghttp2_session_set_stream_user_data()`.  Unless it is set using
+ * `nghttp2_session_set_stream_user_data()`, if the stream is
+ * initiated by the remote endpoint, stream_user_data is always
+ * ``NULL``.  If the stream does not exist, this function returns
+ * ``NULL``.
+ */
+NGHTTP2_EXTERN void *
+nghttp2_session_get_stream_user_data(nghttp2_session *session,
+                                     int32_t stream_id);
+
+/**
+ * @function
+ *
+ * Sets the |stream_user_data| to the stream denoted by the
+ * |stream_id|.  If a stream user data is already set to the stream,
+ * it is replaced with the |stream_user_data|.  It is valid to specify
+ * ``NULL`` in the |stream_user_data|, which nullifies the associated
+ * data pointer.
+ *
+ * It is valid to set the |stream_user_data| to the stream reserved by
+ * PUSH_PROMISE frame.
+ *
+ * This function returns 0 if it succeeds, or one of following
+ * negative error codes:
+ *
+ * :enum:`NGHTTP2_ERR_INVALID_ARGUMENT`
+ *     The stream does not exist
+ */
+NGHTTP2_EXTERN int
+nghttp2_session_set_stream_user_data(nghttp2_session *session,
+                                     int32_t stream_id, void *stream_user_data);
+
+/**
+ * @function
+ *
+ * Sets |user_data| to |session|, overwriting the existing user data
+ * specified in `nghttp2_session_client_new()`, or
+ * `nghttp2_session_server_new()`.
+ */
+NGHTTP2_EXTERN void nghttp2_session_set_user_data(nghttp2_session *session,
+                                                  void *user_data);
+
+/**
+ * @function
+ *
+ * Returns the number of frames in the outbound queue.  This does not
+ * include the deferred DATA frames.
+ */
+NGHTTP2_EXTERN size_t
+nghttp2_session_get_outbound_queue_size(nghttp2_session *session);
+
+/**
+ * @function
+ *
+ * Returns the number of DATA payload in bytes received without
+ * WINDOW_UPDATE transmission for the stream |stream_id|.  The local
+ * (receive) window size can be adjusted by
+ * `nghttp2_submit_window_update()`.  This function takes into account
+ * that and returns effective data length.  In particular, if the
+ * local window size is reduced by submitting negative
+ * window_size_increment with `nghttp2_submit_window_update()`, this
+ * function returns the number of bytes less than actually received.
+ *
+ * This function returns -1 if it fails.
+ */
+NGHTTP2_EXTERN int32_t nghttp2_session_get_stream_effective_recv_data_length(
+    nghttp2_session *session, int32_t stream_id);
+
+/**
+ * @function
+ *
+ * Returns the local (receive) window size for the stream |stream_id|.
+ * The local window size can be adjusted by
+ * `nghttp2_submit_window_update()`.  This function takes into account
+ * that and returns effective window size.
+ *
+ * This function does not take into account the amount of received
+ * data from the remote endpoint.  Use
+ * `nghttp2_session_get_stream_local_window_size()` to know the amount
+ * of data the remote endpoint can send without receiving stream level
+ * WINDOW_UPDATE frame.  Note that each stream is still subject to the
+ * connection level flow control.
+ *
+ * This function returns -1 if it fails.
+ */
+NGHTTP2_EXTERN int32_t nghttp2_session_get_stream_effective_local_window_size(
+    nghttp2_session *session, int32_t stream_id);
+
+/**
+ * @function
+ *
+ * Returns the amount of flow-controlled payload (e.g., DATA) that the
+ * remote endpoint can send without receiving stream level
+ * WINDOW_UPDATE frame.  It is also subject to the connection level
+ * flow control.  So the actual amount of data to send is
+ * min(`nghttp2_session_get_stream_local_window_size()`,
+ * `nghttp2_session_get_local_window_size()`).
+ *
+ * This function returns -1 if it fails.
+ */
+NGHTTP2_EXTERN int32_t nghttp2_session_get_stream_local_window_size(
+    nghttp2_session *session, int32_t stream_id);
+
+/**
+ * @function
+ *
+ * Returns the number of DATA payload in bytes received without
+ * WINDOW_UPDATE transmission for a connection.  The local (receive)
+ * window size can be adjusted by `nghttp2_submit_window_update()`.
+ * This function takes into account that and returns effective data
+ * length.  In particular, if the local window size is reduced by
+ * submitting negative window_size_increment with
+ * `nghttp2_submit_window_update()`, this function returns the number
+ * of bytes less than actually received.
+ *
+ * This function returns -1 if it fails.
+ */
+NGHTTP2_EXTERN int32_t
+nghttp2_session_get_effective_recv_data_length(nghttp2_session *session);
+
+/**
+ * @function
+ *
+ * Returns the local (receive) window size for a connection.  The
+ * local window size can be adjusted by
+ * `nghttp2_submit_window_update()`.  This function takes into account
+ * that and returns effective window size.
+ *
+ * This function does not take into account the amount of received
+ * data from the remote endpoint.  Use
+ * `nghttp2_session_get_local_window_size()` to know the amount of
+ * data the remote endpoint can send without receiving
+ * connection-level WINDOW_UPDATE frame.  Note that each stream is
+ * still subject to the stream level flow control.
+ *
+ * This function returns -1 if it fails.
+ */
+NGHTTP2_EXTERN int32_t
+nghttp2_session_get_effective_local_window_size(nghttp2_session *session);
+
+/**
+ * @function
+ *
+ * Returns the amount of flow-controlled payload (e.g., DATA) that the
+ * remote endpoint can send without receiving connection level
+ * WINDOW_UPDATE frame.  Note that each stream is still subject to the
+ * stream level flow control (see
+ * `nghttp2_session_get_stream_local_window_size()`).
+ *
+ * This function returns -1 if it fails.
+ */
+NGHTTP2_EXTERN int32_t
+nghttp2_session_get_local_window_size(nghttp2_session *session);
+
+/**
+ * @function
+ *
+ * Returns the remote window size for a given stream |stream_id|.
+ *
+ * This is the amount of flow-controlled payload (e.g., DATA) that the
+ * local endpoint can send without stream level WINDOW_UPDATE.  There
+ * is also connection level flow control, so the effective size of
+ * payload that the local endpoint can actually send is
+ * min(`nghttp2_session_get_stream_remote_window_size()`,
+ * `nghttp2_session_get_remote_window_size()`).
+ *
+ * This function returns -1 if it fails.
+ */
+NGHTTP2_EXTERN int32_t nghttp2_session_get_stream_remote_window_size(
+    nghttp2_session *session, int32_t stream_id);
+
+/**
+ * @function
+ *
+ * Returns the remote window size for a connection.
+ *
+ * This function always succeeds.
+ */
+NGHTTP2_EXTERN int32_t
+nghttp2_session_get_remote_window_size(nghttp2_session *session);
+
+/**
+ * @function
+ *
+ * Returns 1 if local peer half closed the given stream |stream_id|.
+ * Returns 0 if it did not.  Returns -1 if no such stream exists.
+ */
+NGHTTP2_EXTERN int
+nghttp2_session_get_stream_local_close(nghttp2_session *session,
+                                       int32_t stream_id);
+
+/**
+ * @function
+ *
+ * Returns 1 if remote peer half closed the given stream |stream_id|.
+ * Returns 0 if it did not.  Returns -1 if no such stream exists.
+ */
+NGHTTP2_EXTERN int
+nghttp2_session_get_stream_remote_close(nghttp2_session *session,
+                                        int32_t stream_id);
+
+/**
+ * @function
+ *
+ * Returns the current dynamic table size of HPACK inflater, including
+ * the overhead 32 bytes per entry described in RFC 7541.
+ */
+NGHTTP2_EXTERN size_t
+nghttp2_session_get_hd_inflate_dynamic_table_size(nghttp2_session *session);
+
+/**
+ * @function
+ *
+ * Returns the current dynamic table size of HPACK deflater including
+ * the overhead 32 bytes per entry described in RFC 7541.
+ */
+NGHTTP2_EXTERN size_t
+nghttp2_session_get_hd_deflate_dynamic_table_size(nghttp2_session *session);
+
+/**
+ * @function
+ *
+ * Signals the session so that the connection should be terminated.
+ *
+ * The last stream ID is the minimum value between the stream ID of a
+ * stream for which :type:`nghttp2_on_frame_recv_callback` was called
+ * most recently and the last stream ID we have sent to the peer
+ * previously.
+ *
+ * The |error_code| is the error code of this GOAWAY frame.  The
+ * pre-defined error code is one of :enum:`nghttp2_error_code`.
+ *
+ * After the transmission, both `nghttp2_session_want_read()` and
+ * `nghttp2_session_want_write()` return 0.
+ *
+ * This function should be called when the connection should be
+ * terminated after sending GOAWAY.  If the remaining streams should
+ * be processed after GOAWAY, use `nghttp2_submit_goaway()` instead.
+ *
+ * This function returns 0 if it succeeds, or one of the following
+ * negative error codes:
+ *
+ * :enum:`NGHTTP2_ERR_NOMEM`
+ *     Out of memory.
+ */
+NGHTTP2_EXTERN int nghttp2_session_terminate_session(nghttp2_session *session,
+                                                     uint32_t error_code);
+
+/**
+ * @function
+ *
+ * Signals the session so that the connection should be terminated.
+ *
+ * This function behaves like `nghttp2_session_terminate_session()`,
+ * but the last stream ID can be specified by the application for fine
+ * grained control of stream.  The HTTP/2 specification does not allow
+ * last_stream_id to be increased.  So the actual value sent as
+ * last_stream_id is the minimum value between the given
+ * |last_stream_id| and the last_stream_id we have previously sent to
+ * the peer.
+ *
+ * The |last_stream_id| is peer's stream ID or 0.  So if |session| is
+ * initialized as client, |last_stream_id| must be even or 0.  If
+ * |session| is initialized as server, |last_stream_id| must be odd or
+ * 0.
+ *
+ * This function returns 0 if it succeeds, or one of the following
+ * negative error codes:
+ *
+ * :enum:`NGHTTP2_ERR_NOMEM`
+ *     Out of memory.
+ * :enum:`NGHTTP2_ERR_INVALID_ARGUMENT`
+ *     The |last_stream_id| is invalid.
+ */
+NGHTTP2_EXTERN int nghttp2_session_terminate_session2(nghttp2_session *session,
+                                                      int32_t last_stream_id,
+                                                      uint32_t error_code);
+
+/**
+ * @function
+ *
+ * Signals to the client that the server started graceful shutdown
+ * procedure.
+ *
+ * This function is only usable for server.  If this function is
+ * called with client side session, this function returns
+ * :enum:`NGHTTP2_ERR_INVALID_STATE`.
+ *
+ * To gracefully shutdown HTTP/2 session, server should call this
+ * function to send GOAWAY with last_stream_id (1u << 31) - 1.  And
+ * after some delay (e.g., 1 RTT), send another GOAWAY with the stream
+ * ID that the server has some processing using
+ * `nghttp2_submit_goaway()`.  See also
+ * `nghttp2_session_get_last_proc_stream_id()`.
+ *
+ * Unlike `nghttp2_submit_goaway()`, this function just sends GOAWAY
+ * and does nothing more.  This is a mere indication to the client
+ * that session shutdown is imminent.  The application should call
+ * `nghttp2_submit_goaway()` with appropriate last_stream_id after
+ * this call.
+ *
+ * If one or more GOAWAY frame have been already sent by either
+ * `nghttp2_submit_goaway()` or `nghttp2_session_terminate_session()`,
+ * this function has no effect.
+ *
+ * This function returns 0 if it succeeds, or one of the following
+ * negative error codes:
+ *
+ * :enum:`NGHTTP2_ERR_NOMEM`
+ *     Out of memory.
+ * :enum:`NGHTTP2_ERR_INVALID_STATE`
+ *     The |session| is initialized as client.
+ */
+NGHTTP2_EXTERN int nghttp2_submit_shutdown_notice(nghttp2_session *session);
+
+/**
+ * @function
+ *
+ * Returns the value of SETTINGS |id| notified by a remote endpoint.
+ * The |id| must be one of values defined in
+ * :enum:`nghttp2_settings_id`.
+ */
+NGHTTP2_EXTERN uint32_t nghttp2_session_get_remote_settings(
+    nghttp2_session *session, nghttp2_settings_id id);
+
+/**
+ * @function
+ *
+ * Returns the value of SETTINGS |id| of local endpoint acknowledged
+ * by the remote endpoint.  The |id| must be one of the values defined
+ * in :enum:`nghttp2_settings_id`.
+ */
+NGHTTP2_EXTERN uint32_t nghttp2_session_get_local_settings(
+    nghttp2_session *session, nghttp2_settings_id id);
+
+/**
+ * @function
+ *
+ * Tells the |session| that next stream ID is |next_stream_id|.  The
+ * |next_stream_id| must be equal or greater than the value returned
+ * by `nghttp2_session_get_next_stream_id()`.
+ *
+ * This function returns 0 if it succeeds, or one of the following
+ * negative error codes:
+ *
+ * :enum:`NGHTTP2_ERR_INVALID_ARGUMENT`
+ *     The |next_stream_id| is strictly less than the value
+ *     `nghttp2_session_get_next_stream_id()` returns; or
+ *     |next_stream_id| is invalid (e.g., even integer for client, or
+ *     odd integer for server).
+ */
+NGHTTP2_EXTERN int nghttp2_session_set_next_stream_id(nghttp2_session *session,
+                                                      int32_t next_stream_id);
+
+/**
+ * @function
+ *
+ * Returns the next outgoing stream ID.  Notice that return type is
+ * uint32_t.  If we run out of stream ID for this session, this
+ * function returns 1 << 31.
+ */
+NGHTTP2_EXTERN uint32_t
+nghttp2_session_get_next_stream_id(nghttp2_session *session);
+
+/**
+ * @function
+ *
+ * Tells the |session| that |size| bytes for a stream denoted by
+ * |stream_id| were consumed by application and are ready to
+ * WINDOW_UPDATE.  The consumed bytes are counted towards both
+ * connection and stream level WINDOW_UPDATE (see
+ * `nghttp2_session_consume_connection()` and
+ * `nghttp2_session_consume_stream()` to update consumption
+ * independently).  This function is intended to be used without
+ * automatic window update (see
+ * `nghttp2_option_set_no_auto_window_update()`).
+ *
+ * This function returns 0 if it succeeds, or one of the following
+ * negative error codes:
+ *
+ * :enum:`NGHTTP2_ERR_NOMEM`
+ *     Out of memory.
+ * :enum:`NGHTTP2_ERR_INVALID_ARGUMENT`
+ *     The |stream_id| is 0.
+ * :enum:`NGHTTP2_ERR_INVALID_STATE`
+ *     Automatic WINDOW_UPDATE is not disabled.
+ */
+NGHTTP2_EXTERN int nghttp2_session_consume(nghttp2_session *session,
+                                           int32_t stream_id, size_t size);
+
+/**
+ * @function
+ *
+ * Like `nghttp2_session_consume()`, but this only tells library that
+ * |size| bytes were consumed only for connection level.  Note that
+ * HTTP/2 maintains connection and stream level flow control windows
+ * independently.
+ *
+ * This function returns 0 if it succeeds, or one of the following
+ * negative error codes:
+ *
+ * :enum:`NGHTTP2_ERR_NOMEM`
+ *     Out of memory.
+ * :enum:`NGHTTP2_ERR_INVALID_STATE`
+ *     Automatic WINDOW_UPDATE is not disabled.
+ */
+NGHTTP2_EXTERN int nghttp2_session_consume_connection(nghttp2_session *session,
+                                                      size_t size);
+
+/**
+ * @function
+ *
+ * Like `nghttp2_session_consume()`, but this only tells library that
+ * |size| bytes were consumed only for stream denoted by |stream_id|.
+ * Note that HTTP/2 maintains connection and stream level flow control
+ * windows independently.
+ *
+ * This function returns 0 if it succeeds, or one of the following
+ * negative error codes:
+ *
+ * :enum:`NGHTTP2_ERR_NOMEM`
+ *     Out of memory.
+ * :enum:`NGHTTP2_ERR_INVALID_ARGUMENT`
+ *     The |stream_id| is 0.
+ * :enum:`NGHTTP2_ERR_INVALID_STATE`
+ *     Automatic WINDOW_UPDATE is not disabled.
+ */
+NGHTTP2_EXTERN int nghttp2_session_consume_stream(nghttp2_session *session,
+                                                  int32_t stream_id,
+                                                  size_t size);
+
+/**
+ * @function
+ *
+ * Changes priority of existing stream denoted by |stream_id|.  The
+ * new priority specification is |pri_spec|.
+ *
+ * The priority is changed silently and instantly, and no PRIORITY
+ * frame will be sent to notify the peer of this change.  This
+ * function may be useful for server to change the priority of pushed
+ * stream.
+ *
+ * If |session| is initialized as server, and ``pri_spec->stream_id``
+ * points to the idle stream, the idle stream is created if it does
+ * not exist.  The created idle stream will depend on root stream
+ * (stream 0) with weight 16.
+ *
+ * Otherwise, if stream denoted by ``pri_spec->stream_id`` is not
+ * found, we use default priority instead of given |pri_spec|.  That
+ * is make stream depend on root stream with weight 16.
+ *
+ * This function returns 0 if it succeeds, or one of the following
+ * negative error codes:
+ *
+ * :enum:`NGHTTP2_ERR_NOMEM`
+ *     Out of memory.
+ * :enum:`NGHTTP2_ERR_INVALID_ARGUMENT`
+ *     Attempted to depend on itself; or no stream exist for the given
+ *     |stream_id|; or |stream_id| is 0
+ */
+NGHTTP2_EXTERN int
+nghttp2_session_change_stream_priority(nghttp2_session *session,
+                                       int32_t stream_id,
+                                       const nghttp2_priority_spec *pri_spec);
+
+/**
+ * @function
+ *
+ * Creates idle stream with the given |stream_id|, and priority
+ * |pri_spec|.
+ *
+ * The stream creation is done without sending PRIORITY frame, which
+ * means that peer does not know about the existence of this idle
+ * stream in the local endpoint.
+ *
+ * RFC 7540 does not disallow the use of creation of idle stream with
+ * odd or even stream ID regardless of client or server.  So this
+ * function can create odd or even stream ID regardless of client or
+ * server.  But probably it is a bit safer to use the stream ID the
+ * local endpoint can initiate (in other words, use odd stream ID for
+ * client, and even stream ID for server), to avoid potential
+ * collision from peer's instruction.  Also we can use
+ * `nghttp2_session_set_next_stream_id()` to avoid to open created
+ * idle streams accidentally if we follow this recommendation.
+ *
+ * If |session| is initialized as server, and ``pri_spec->stream_id``
+ * points to the idle stream, the idle stream is created if it does
+ * not exist.  The created idle stream will depend on root stream
+ * (stream 0) with weight 16.
+ *
+ * Otherwise, if stream denoted by ``pri_spec->stream_id`` is not
+ * found, we use default priority instead of given |pri_spec|.  That
+ * is make stream depend on root stream with weight 16.
+ *
+ * This function returns 0 if it succeeds, or one of the following
+ * negative error codes:
+ *
+ * :enum:`NGHTTP2_ERR_NOMEM`
+ *     Out of memory.
+ * :enum:`NGHTTP2_ERR_INVALID_ARGUMENT`
+ *     Attempted to depend on itself; or stream denoted by |stream_id|
+ *     already exists; or |stream_id| cannot be used to create idle
+ *     stream (in other words, local endpoint has already opened
+ *     stream ID greater than or equal to the given stream ID; or
+ *     |stream_id| is 0
+ */
+NGHTTP2_EXTERN int
+nghttp2_session_create_idle_stream(nghttp2_session *session, int32_t stream_id,
+                                   const nghttp2_priority_spec *pri_spec);
+
+/**
+ * @function
+ *
+ * Performs post-process of HTTP Upgrade request.  This function can
+ * be called from both client and server, but the behavior is very
+ * different in each other.
+ *
+ * .. warning::
+ *
+ *   This function is deprecated in favor of
+ *   `nghttp2_session_upgrade2()`, because this function lacks the
+ *   parameter to tell the library the request method used in the
+ *   original HTTP request.  This information is required for client
+ *   to validate actual response body length against content-length
+ *   header field (see `nghttp2_option_set_no_http_messaging()`).  If
+ *   HEAD is used in request, the length of response body must be 0
+ *   regardless of value included in content-length header field.
+ *
+ * If called from client side, the |settings_payload| must be the
+ * value sent in ``HTTP2-Settings`` header field and must be decoded
+ * by base64url decoder.  The |settings_payloadlen| is the length of
+ * |settings_payload|.  The |settings_payload| is unpacked and its
+ * setting values will be submitted using `nghttp2_submit_settings()`.
+ * This means that the client application code does not need to submit
+ * SETTINGS by itself.  The stream with stream ID=1 is opened and the
+ * |stream_user_data| is used for its stream_user_data.  The opened
+ * stream becomes half-closed (local) state.
+ *
+ * If called from server side, the |settings_payload| must be the
+ * value received in ``HTTP2-Settings`` header field and must be
+ * decoded by base64url decoder.  The |settings_payloadlen| is the
+ * length of |settings_payload|.  It is treated as if the SETTINGS
+ * frame with that payload is received.  Thus, callback functions for
+ * the reception of SETTINGS frame will be invoked.  The stream with
+ * stream ID=1 is opened.  The |stream_user_data| is ignored.  The
+ * opened stream becomes half-closed (remote).
+ *
+ * This function returns 0 if it succeeds, or one of the following
+ * negative error codes:
+ *
+ * :enum:`NGHTTP2_ERR_NOMEM`
+ *     Out of memory.
+ * :enum:`NGHTTP2_ERR_INVALID_ARGUMENT`
+ *     The |settings_payload| is badly formed.
+ * :enum:`NGHTTP2_ERR_PROTO`
+ *     The stream ID 1 is already used or closed; or is not available.
+ */
+NGHTTP2_EXTERN int nghttp2_session_upgrade(nghttp2_session *session,
+                                           const uint8_t *settings_payload,
+                                           size_t settings_payloadlen,
+                                           void *stream_user_data);
+
+/**
+ * @function
+ *
+ * Performs post-process of HTTP Upgrade request.  This function can
+ * be called from both client and server, but the behavior is very
+ * different in each other.
+ *
+ * If called from client side, the |settings_payload| must be the
+ * value sent in ``HTTP2-Settings`` header field and must be decoded
+ * by base64url decoder.  The |settings_payloadlen| is the length of
+ * |settings_payload|.  The |settings_payload| is unpacked and its
+ * setting values will be submitted using `nghttp2_submit_settings()`.
+ * This means that the client application code does not need to submit
+ * SETTINGS by itself.  The stream with stream ID=1 is opened and the
+ * |stream_user_data| is used for its stream_user_data.  The opened
+ * stream becomes half-closed (local) state.
+ *
+ * If called from server side, the |settings_payload| must be the
+ * value received in ``HTTP2-Settings`` header field and must be
+ * decoded by base64url decoder.  The |settings_payloadlen| is the
+ * length of |settings_payload|.  It is treated as if the SETTINGS
+ * frame with that payload is received.  Thus, callback functions for
+ * the reception of SETTINGS frame will be invoked.  The stream with
+ * stream ID=1 is opened.  The |stream_user_data| is ignored.  The
+ * opened stream becomes half-closed (remote).
+ *
+ * If the request method is HEAD, pass nonzero value to
+ * |head_request|.  Otherwise, pass 0.
+ *
+ * This function returns 0 if it succeeds, or one of the following
+ * negative error codes:
+ *
+ * :enum:`NGHTTP2_ERR_NOMEM`
+ *     Out of memory.
+ * :enum:`NGHTTP2_ERR_INVALID_ARGUMENT`
+ *     The |settings_payload| is badly formed.
+ * :enum:`NGHTTP2_ERR_PROTO`
+ *     The stream ID 1 is already used or closed; or is not available.
+ */
+NGHTTP2_EXTERN int nghttp2_session_upgrade2(nghttp2_session *session,
+                                            const uint8_t *settings_payload,
+                                            size_t settings_payloadlen,
+                                            int head_request,
+                                            void *stream_user_data);
+
+/**
+ * @function
+ *
+ * Serializes the SETTINGS values |iv| in the |buf|.  The size of the
+ * |buf| is specified by |buflen|.  The number of entries in the |iv|
+ * array is given by |niv|.  The required space in |buf| for the |niv|
+ * entries is ``6*niv`` bytes and if the given buffer is too small, an
+ * error is returned.  This function is used mainly for creating a
+ * SETTINGS payload to be sent with the ``HTTP2-Settings`` header
+ * field in an HTTP Upgrade request.  The data written in |buf| is NOT
+ * base64url encoded and the application is responsible for encoding.
+ *
+ * This function returns the number of bytes written in |buf|, or one
+ * of the following negative error codes:
+ *
+ * :enum:`NGHTTP2_ERR_INVALID_ARGUMENT`
+ *     The |iv| contains duplicate settings ID or invalid value.
+ *
+ * :enum:`NGHTTP2_ERR_INSUFF_BUFSIZE`
+ *     The provided |buflen| size is too small to hold the output.
+ */
+NGHTTP2_EXTERN ssize_t nghttp2_pack_settings_payload(
+    uint8_t *buf, size_t buflen, const nghttp2_settings_entry *iv, size_t niv);
+
+/**
+ * @function
+ *
+ * Returns string describing the |lib_error_code|.  The
+ * |lib_error_code| must be one of the :enum:`nghttp2_error`.
+ */
+NGHTTP2_EXTERN const char *nghttp2_strerror(int lib_error_code);
+
+/**
+ * @function
+ *
+ * Returns string representation of HTTP/2 error code |error_code|
+ * (e.g., ``PROTOCOL_ERROR`` is returned if ``error_code ==
+ * NGHTTP2_PROTOCOL_ERROR``).  If string representation is unknown for
+ * given |error_code|, this function returns string ``unknown``.
+ */
+NGHTTP2_EXTERN const char *nghttp2_http2_strerror(uint32_t error_code);
+
+/**
+ * @function
+ *
+ * Initializes |pri_spec| with the |stream_id| of the stream to depend
+ * on with |weight| and its exclusive flag.  If |exclusive| is
+ * nonzero, exclusive flag is set.
+ *
+ * The |weight| must be in [:enum:`NGHTTP2_MIN_WEIGHT`,
+ * :enum:`NGHTTP2_MAX_WEIGHT`], inclusive.
+ */
+NGHTTP2_EXTERN void nghttp2_priority_spec_init(nghttp2_priority_spec *pri_spec,
+                                               int32_t stream_id,
+                                               int32_t weight, int exclusive);
+
+/**
+ * @function
+ *
+ * Initializes |pri_spec| with the default values.  The default values
+ * are: stream_id = 0, weight = :macro:`NGHTTP2_DEFAULT_WEIGHT` and
+ * exclusive = 0.
+ */
+NGHTTP2_EXTERN void
+nghttp2_priority_spec_default_init(nghttp2_priority_spec *pri_spec);
+
+/**
+ * @function
+ *
+ * Returns nonzero if the |pri_spec| is filled with default values.
+ */
+NGHTTP2_EXTERN int
+nghttp2_priority_spec_check_default(const nghttp2_priority_spec *pri_spec);
+
+/**
+ * @function
+ *
+ * Submits HEADERS frame and optionally one or more DATA frames.
+ *
+ * The |pri_spec| is priority specification of this request.  ``NULL``
+ * means the default priority (see
+ * `nghttp2_priority_spec_default_init()`).  To specify the priority,
+ * use `nghttp2_priority_spec_init()`.  If |pri_spec| is not ``NULL``,
+ * this function will copy its data members.
+ *
+ * The ``pri_spec->weight`` must be in [:enum:`NGHTTP2_MIN_WEIGHT`,
+ * :enum:`NGHTTP2_MAX_WEIGHT`], inclusive.  If ``pri_spec->weight`` is
+ * strictly less than :enum:`NGHTTP2_MIN_WEIGHT`, it becomes
+ * :enum:`NGHTTP2_MIN_WEIGHT`.  If it is strictly greater than
+ * :enum:`NGHTTP2_MAX_WEIGHT`, it becomes :enum:`NGHTTP2_MAX_WEIGHT`.
+ *
+ * The |nva| is an array of name/value pair :type:`nghttp2_nv` with
+ * |nvlen| elements.  The application is responsible to include
+ * required pseudo-header fields (header field whose name starts with
+ * ":") in |nva| and must place pseudo-headers before regular header
+ * fields.
+ *
+ * This function creates copies of all name/value pairs in |nva|.  It
+ * also lower-cases all names in |nva|.  The order of elements in
+ * |nva| is preserved.  For header fields with
+ * :enum:`NGHTTP2_NV_FLAG_NO_COPY_NAME` and
+ * :enum:`NGHTTP2_NV_FLAG_NO_COPY_VALUE` are set, header field name
+ * and value are not copied respectively.  With
+ * :enum:`NGHTTP2_NV_FLAG_NO_COPY_NAME`, application is responsible to
+ * pass header field name in lowercase.  The application should
+ * maintain the references to them until
+ * :type:`nghttp2_on_frame_send_callback` or
+ * :type:`nghttp2_on_frame_not_send_callback` is called.
+ *
+ * HTTP/2 specification has requirement about header fields in the
+ * request HEADERS.  See the specification for more details.
+ *
+ * If |data_prd| is not ``NULL``, it provides data which will be sent
+ * in subsequent DATA frames.  In this case, a method that allows
+ * request message bodies
+ * (https://tools.ietf.org/html/rfc7231#section-4) must be specified
+ * with ``:method`` key in |nva| (e.g. ``POST``).  This function does
+ * not take ownership of the |data_prd|.  The function copies the
+ * members of the |data_prd|.  If |data_prd| is ``NULL``, HEADERS have
+ * END_STREAM set.  The |stream_user_data| is data associated to the
+ * stream opened by this request and can be an arbitrary pointer,
+ * which can be retrieved later by
+ * `nghttp2_session_get_stream_user_data()`.
+ *
+ * This function returns assigned stream ID if it succeeds, or one of
+ * the following negative error codes:
+ *
+ * :enum:`NGHTTP2_ERR_NOMEM`
+ *     Out of memory.
+ * :enum:`NGHTTP2_ERR_STREAM_ID_NOT_AVAILABLE`
+ *     No stream ID is available because maximum stream ID was
+ *     reached.
+ * :enum:`NGHTTP2_ERR_INVALID_ARGUMENT`
+ *     Trying to depend on itself (new stream ID equals
+ *     ``pri_spec->stream_id``).
+ * :enum:`NGHTTP2_ERR_PROTO`
+ *     The |session| is server session.
+ *
+ * .. warning::
+ *
+ *   This function returns assigned stream ID if it succeeds.  But
+ *   that stream is not created yet.  The application must not submit
+ *   frame to that stream ID before
+ *   :type:`nghttp2_before_frame_send_callback` is called for this
+ *   frame.  This means `nghttp2_session_get_stream_user_data()` does
+ *   not work before the callback.  But
+ *   `nghttp2_session_set_stream_user_data()` handles this situation
+ *   specially, and it can set data to a stream during this period.
+ *
+ */
+NGHTTP2_EXTERN int32_t nghttp2_submit_request(
+    nghttp2_session *session, const nghttp2_priority_spec *pri_spec,
+    const nghttp2_nv *nva, size_t nvlen, const nghttp2_data_provider *data_prd,
+    void *stream_user_data);
+
+/**
+ * @function
+ *
+ * Submits response HEADERS frame and optionally one or more DATA
+ * frames against the stream |stream_id|.
+ *
+ * The |nva| is an array of name/value pair :type:`nghttp2_nv` with
+ * |nvlen| elements.  The application is responsible to include
+ * required pseudo-header fields (header field whose name starts with
+ * ":") in |nva| and must place pseudo-headers before regular header
+ * fields.
+ *
+ * This function creates copies of all name/value pairs in |nva|.  It
+ * also lower-cases all names in |nva|.  The order of elements in
+ * |nva| is preserved.  For header fields with
+ * :enum:`NGHTTP2_NV_FLAG_NO_COPY_NAME` and
+ * :enum:`NGHTTP2_NV_FLAG_NO_COPY_VALUE` are set, header field name
+ * and value are not copied respectively.  With
+ * :enum:`NGHTTP2_NV_FLAG_NO_COPY_NAME`, application is responsible to
+ * pass header field name in lowercase.  The application should
+ * maintain the references to them until
+ * :type:`nghttp2_on_frame_send_callback` or
+ * :type:`nghttp2_on_frame_not_send_callback` is called.
+ *
+ * HTTP/2 specification has requirement about header fields in the
+ * response HEADERS.  See the specification for more details.
+ *
+ * If |data_prd| is not ``NULL``, it provides data which will be sent
+ * in subsequent DATA frames.  This function does not take ownership
+ * of the |data_prd|.  The function copies the members of the
+ * |data_prd|.  If |data_prd| is ``NULL``, HEADERS will have
+ * END_STREAM flag set.
+ *
+ * This method can be used as normal HTTP response and push response.
+ * When pushing a resource using this function, the |session| must be
+ * configured using `nghttp2_session_server_new()` or its variants and
+ * the target stream denoted by the |stream_id| must be reserved using
+ * `nghttp2_submit_push_promise()`.
+ *
+ * To send non-final response headers (e.g., HTTP status 101), don't
+ * use this function because this function half-closes the outbound
+ * stream.  Instead, use `nghttp2_submit_headers()` for this purpose.
+ *
+ * This function returns 0 if it succeeds, or one of the following
+ * negative error codes:
+ *
+ * :enum:`NGHTTP2_ERR_NOMEM`
+ *     Out of memory.
+ * :enum:`NGHTTP2_ERR_INVALID_ARGUMENT`
+ *     The |stream_id| is 0.
+ * :enum:`NGHTTP2_ERR_DATA_EXIST`
+ *     DATA or HEADERS has been already submitted and not fully
+ *     processed yet.  Normally, this does not happen, but when
+ *     application wrongly calls `nghttp2_submit_response()` twice,
+ *     this may happen.
+ * :enum:`NGHTTP2_ERR_PROTO`
+ *     The |session| is client session.
+ *
+ * .. warning::
+ *
+ *   Calling this function twice for the same stream ID may lead to
+ *   program crash.  It is generally considered to a programming error
+ *   to commit response twice.
+ */
+NGHTTP2_EXTERN int
+nghttp2_submit_response(nghttp2_session *session, int32_t stream_id,
+                        const nghttp2_nv *nva, size_t nvlen,
+                        const nghttp2_data_provider *data_prd);
+
+/**
+ * @function
+ *
+ * Submits trailer fields HEADERS against the stream |stream_id|.
+ *
+ * The |nva| is an array of name/value pair :type:`nghttp2_nv` with
+ * |nvlen| elements.  The application must not include pseudo-header
+ * fields (headers whose names starts with ":") in |nva|.
+ *
+ * This function creates copies of all name/value pairs in |nva|.  It
+ * also lower-cases all names in |nva|.  The order of elements in
+ * |nva| is preserved.  For header fields with
+ * :enum:`NGHTTP2_NV_FLAG_NO_COPY_NAME` and
+ * :enum:`NGHTTP2_NV_FLAG_NO_COPY_VALUE` are set, header field name
+ * and value are not copied respectively.  With
+ * :enum:`NGHTTP2_NV_FLAG_NO_COPY_NAME`, application is responsible to
+ * pass header field name in lowercase.  The application should
+ * maintain the references to them until
+ * :type:`nghttp2_on_frame_send_callback` or
+ * :type:`nghttp2_on_frame_not_send_callback` is called.
+ *
+ * For server, trailer fields must follow response HEADERS or response
+ * DATA without END_STREAM flat set.  The library does not enforce
+ * this requirement, and applications should do this for themselves.
+ * If `nghttp2_submit_trailer()` is called before any response HEADERS
+ * submission (usually by `nghttp2_submit_response()`), the content of
+ * |nva| will be sent as response headers, which will result in error.
+ *
+ * This function has the same effect with `nghttp2_submit_headers()`,
+ * with flags = :enum:`NGHTTP2_FLAG_END_STREAM` and both pri_spec and
+ * stream_user_data to NULL.
+ *
+ * To submit trailer fields after `nghttp2_submit_response()` is
+ * called, the application has to specify
+ * :type:`nghttp2_data_provider` to `nghttp2_submit_response()`.
+ * Inside of :type:`nghttp2_data_source_read_callback`, when setting
+ * :enum:`NGHTTP2_DATA_FLAG_EOF`, also set
+ * :enum:`NGHTTP2_DATA_FLAG_NO_END_STREAM`.  After that, the
+ * application can send trailer fields using
+ * `nghttp2_submit_trailer()`.  `nghttp2_submit_trailer()` can be used
+ * inside :type:`nghttp2_data_source_read_callback`.
+ *
+ * This function returns 0 if it succeeds and |stream_id| is -1.
+ * Otherwise, this function returns 0 if it succeeds, or one of the
+ * following negative error codes:
+ *
+ * :enum:`NGHTTP2_ERR_NOMEM`
+ *     Out of memory.
+ * :enum:`NGHTTP2_ERR_INVALID_ARGUMENT`
+ *     The |stream_id| is 0.
+ */
+NGHTTP2_EXTERN int nghttp2_submit_trailer(nghttp2_session *session,
+                                          int32_t stream_id,
+                                          const nghttp2_nv *nva, size_t nvlen);
+
+/**
+ * @function
+ *
+ * Submits HEADERS frame. The |flags| is bitwise OR of the
+ * following values:
+ *
+ * * :enum:`NGHTTP2_FLAG_END_STREAM`
+ *
+ * If |flags| includes :enum:`NGHTTP2_FLAG_END_STREAM`, this frame has
+ * END_STREAM flag set.
+ *
+ * The library handles the CONTINUATION frame internally and it
+ * correctly sets END_HEADERS to the last sequence of the PUSH_PROMISE
+ * or CONTINUATION frame.
+ *
+ * If the |stream_id| is -1, this frame is assumed as request (i.e.,
+ * request HEADERS frame which opens new stream).  In this case, the
+ * assigned stream ID will be returned.  Otherwise, specify stream ID
+ * in |stream_id|.
+ *
+ * The |pri_spec| is priority specification of this request.  ``NULL``
+ * means the default priority (see
+ * `nghttp2_priority_spec_default_init()`).  To specify the priority,
+ * use `nghttp2_priority_spec_init()`.  If |pri_spec| is not ``NULL``,
+ * this function will copy its data members.
+ *
+ * The ``pri_spec->weight`` must be in [:enum:`NGHTTP2_MIN_WEIGHT`,
+ * :enum:`NGHTTP2_MAX_WEIGHT`], inclusive.  If ``pri_spec->weight`` is
+ * strictly less than :enum:`NGHTTP2_MIN_WEIGHT`, it becomes
+ * :enum:`NGHTTP2_MIN_WEIGHT`.  If it is strictly greater than
+ * :enum:`NGHTTP2_MAX_WEIGHT`, it becomes :enum:`NGHTTP2_MAX_WEIGHT`.
+ *
+ * The |nva| is an array of name/value pair :type:`nghttp2_nv` with
+ * |nvlen| elements.  The application is responsible to include
+ * required pseudo-header fields (header field whose name starts with
+ * ":") in |nva| and must place pseudo-headers before regular header
+ * fields.
+ *
+ * This function creates copies of all name/value pairs in |nva|.  It
+ * also lower-cases all names in |nva|.  The order of elements in
+ * |nva| is preserved.  For header fields with
+ * :enum:`NGHTTP2_NV_FLAG_NO_COPY_NAME` and
+ * :enum:`NGHTTP2_NV_FLAG_NO_COPY_VALUE` are set, header field name
+ * and value are not copied respectively.  With
+ * :enum:`NGHTTP2_NV_FLAG_NO_COPY_NAME`, application is responsible to
+ * pass header field name in lowercase.  The application should
+ * maintain the references to them until
+ * :type:`nghttp2_on_frame_send_callback` or
+ * :type:`nghttp2_on_frame_not_send_callback` is called.
+ *
+ * The |stream_user_data| is a pointer to an arbitrary data which is
+ * associated to the stream this frame will open.  Therefore it is
+ * only used if this frame opens streams, in other words, it changes
+ * stream state from idle or reserved to open.
+ *
+ * This function is low-level in a sense that the application code can
+ * specify flags directly.  For usual HTTP request,
+ * `nghttp2_submit_request()` is useful.  Likewise, for HTTP response,
+ * prefer `nghttp2_submit_response()`.
+ *
+ * This function returns newly assigned stream ID if it succeeds and
+ * |stream_id| is -1.  Otherwise, this function returns 0 if it
+ * succeeds, or one of the following negative error codes:
+ *
+ * :enum:`NGHTTP2_ERR_NOMEM`
+ *     Out of memory.
+ * :enum:`NGHTTP2_ERR_STREAM_ID_NOT_AVAILABLE`
+ *     No stream ID is available because maximum stream ID was
+ *     reached.
+ * :enum:`NGHTTP2_ERR_INVALID_ARGUMENT`
+ *     The |stream_id| is 0; or trying to depend on itself (stream ID
+ *     equals ``pri_spec->stream_id``).
+ * :enum:`NGHTTP2_ERR_DATA_EXIST`
+ *     DATA or HEADERS has been already submitted and not fully
+ *     processed yet.  This happens if stream denoted by |stream_id|
+ *     is in reserved state.
+ * :enum:`NGHTTP2_ERR_PROTO`
+ *     The |stream_id| is -1, and |session| is server session.
+ *
+ * .. warning::
+ *
+ *   This function returns assigned stream ID if it succeeds and
+ *   |stream_id| is -1.  But that stream is not opened yet.  The
+ *   application must not submit frame to that stream ID before
+ *   :type:`nghttp2_before_frame_send_callback` is called for this
+ *   frame.
+ *
+ */
+NGHTTP2_EXTERN int32_t nghttp2_submit_headers(
+    nghttp2_session *session, uint8_t flags, int32_t stream_id,
+    const nghttp2_priority_spec *pri_spec, const nghttp2_nv *nva, size_t nvlen,
+    void *stream_user_data);
+
+/**
+ * @function
+ *
+ * Submits one or more DATA frames to the stream |stream_id|.  The
+ * data to be sent are provided by |data_prd|.  If |flags| contains
+ * :enum:`NGHTTP2_FLAG_END_STREAM`, the last DATA frame has END_STREAM
+ * flag set.
+ *
+ * This function does not take ownership of the |data_prd|.  The
+ * function copies the members of the |data_prd|.
+ *
+ * This function returns 0 if it succeeds, or one of the following
+ * negative error codes:
+ *
+ * :enum:`NGHTTP2_ERR_NOMEM`
+ *     Out of memory.
+ * :enum:`NGHTTP2_ERR_DATA_EXIST`
+ *     DATA or HEADERS has been already submitted and not fully
+ *     processed yet.
+ * :enum:`NGHTTP2_ERR_INVALID_ARGUMENT`
+ *     The |stream_id| is 0.
+ * :enum:`NGHTTP2_ERR_STREAM_CLOSED`
+ *     The stream was already closed; or the |stream_id| is invalid.
+ *
+ * .. note::
+ *
+ *   Currently, only one DATA or HEADERS is allowed for a stream at a
+ *   time.  Submitting these frames more than once before first DATA
+ *   or HEADERS is finished results in :enum:`NGHTTP2_ERR_DATA_EXIST`
+ *   error code.  The earliest callback which tells that previous
+ *   frame is done is :type:`nghttp2_on_frame_send_callback`.  In side
+ *   that callback, new data can be submitted using
+ *   `nghttp2_submit_data()`.  Of course, all data except for last one
+ *   must not have :enum:`NGHTTP2_FLAG_END_STREAM` flag set in
+ *   |flags|.  This sounds a bit complicated, and we recommend to use
+ *   `nghttp2_submit_request()` and `nghttp2_submit_response()` to
+ *   avoid this cascading issue.  The experience shows that for HTTP
+ *   use, these two functions are enough to implement both client and
+ *   server.
+ */
+NGHTTP2_EXTERN int nghttp2_submit_data(nghttp2_session *session, uint8_t flags,
+                                       int32_t stream_id,
+                                       const nghttp2_data_provider *data_prd);
+
+/**
+ * @function
+ *
+ * Submits PRIORITY frame to change the priority of stream |stream_id|
+ * to the priority specification |pri_spec|.
+ *
+ * The |flags| is currently ignored and should be
+ * :enum:`NGHTTP2_FLAG_NONE`.
+ *
+ * The |pri_spec| is priority specification of this request.  ``NULL``
+ * is not allowed for this function. To specify the priority, use
+ * `nghttp2_priority_spec_init()`.  This function will copy its data
+ * members.
+ *
+ * The ``pri_spec->weight`` must be in [:enum:`NGHTTP2_MIN_WEIGHT`,
+ * :enum:`NGHTTP2_MAX_WEIGHT`], inclusive.  If ``pri_spec->weight`` is
+ * strictly less than :enum:`NGHTTP2_MIN_WEIGHT`, it becomes
+ * :enum:`NGHTTP2_MIN_WEIGHT`.  If it is strictly greater than
+ * :enum:`NGHTTP2_MAX_WEIGHT`, it becomes :enum:`NGHTTP2_MAX_WEIGHT`.
+ *
+ * This function returns 0 if it succeeds, or one of the following
+ * negative error codes:
+ *
+ * :enum:`NGHTTP2_ERR_NOMEM`
+ *     Out of memory.
+ * :enum:`NGHTTP2_ERR_INVALID_ARGUMENT`
+ *     The |stream_id| is 0; or the |pri_spec| is NULL; or trying to
+ *     depend on itself.
+ */
+NGHTTP2_EXTERN int
+nghttp2_submit_priority(nghttp2_session *session, uint8_t flags,
+                        int32_t stream_id,
+                        const nghttp2_priority_spec *pri_spec);
+
+/**
+ * @function
+ *
+ * Submits RST_STREAM frame to cancel/reject the stream |stream_id|
+ * with the error code |error_code|.
+ *
+ * The pre-defined error code is one of :enum:`nghttp2_error_code`.
+ *
+ * The |flags| is currently ignored and should be
+ * :enum:`NGHTTP2_FLAG_NONE`.
+ *
+ * This function returns 0 if it succeeds, or one of the following
+ * negative error codes:
+ *
+ * :enum:`NGHTTP2_ERR_NOMEM`
+ *     Out of memory.
+ * :enum:`NGHTTP2_ERR_INVALID_ARGUMENT`
+ *     The |stream_id| is 0.
+ */
+NGHTTP2_EXTERN int nghttp2_submit_rst_stream(nghttp2_session *session,
+                                             uint8_t flags, int32_t stream_id,
+                                             uint32_t error_code);
+
+/**
+ * @function
+ *
+ * Stores local settings and submits SETTINGS frame.  The |iv| is the
+ * pointer to the array of :type:`nghttp2_settings_entry`.  The |niv|
+ * indicates the number of :type:`nghttp2_settings_entry`.
+ *
+ * The |flags| is currently ignored and should be
+ * :enum:`NGHTTP2_FLAG_NONE`.
+ *
+ * This function does not take ownership of the |iv|.  This function
+ * copies all the elements in the |iv|.
+ *
+ * While updating individual stream's local window size, if the window
+ * size becomes strictly larger than NGHTTP2_MAX_WINDOW_SIZE,
+ * RST_STREAM is issued against such a stream.
+ *
+ * SETTINGS with :enum:`NGHTTP2_FLAG_ACK` is automatically submitted
+ * by the library and application could not send it at its will.
+ *
+ * This function returns 0 if it succeeds, or one of the following
+ * negative error codes:
+ *
+ * :enum:`NGHTTP2_ERR_INVALID_ARGUMENT`
+ *     The |iv| contains invalid value (e.g., initial window size
+ *     strictly greater than (1 << 31) - 1.
+ * :enum:`NGHTTP2_ERR_NOMEM`
+ *     Out of memory.
+ */
+NGHTTP2_EXTERN int nghttp2_submit_settings(nghttp2_session *session,
+                                           uint8_t flags,
+                                           const nghttp2_settings_entry *iv,
+                                           size_t niv);
+
+/**
+ * @function
+ *
+ * Submits PUSH_PROMISE frame.
+ *
+ * The |flags| is currently ignored.  The library handles the
+ * CONTINUATION frame internally and it correctly sets END_HEADERS to
+ * the last sequence of the PUSH_PROMISE or CONTINUATION frame.
+ *
+ * The |stream_id| must be client initiated stream ID.
+ *
+ * The |nva| is an array of name/value pair :type:`nghttp2_nv` with
+ * |nvlen| elements.  The application is responsible to include
+ * required pseudo-header fields (header field whose name starts with
+ * ":") in |nva| and must place pseudo-headers before regular header
+ * fields.
+ *
+ * This function creates copies of all name/value pairs in |nva|.  It
+ * also lower-cases all names in |nva|.  The order of elements in
+ * |nva| is preserved.  For header fields with
+ * :enum:`NGHTTP2_NV_FLAG_NO_COPY_NAME` and
+ * :enum:`NGHTTP2_NV_FLAG_NO_COPY_VALUE` are set, header field name
+ * and value are not copied respectively.  With
+ * :enum:`NGHTTP2_NV_FLAG_NO_COPY_NAME`, application is responsible to
+ * pass header field name in lowercase.  The application should
+ * maintain the references to them until
+ * :type:`nghttp2_on_frame_send_callback` or
+ * :type:`nghttp2_on_frame_not_send_callback` is called.
+ *
+ * The |promised_stream_user_data| is a pointer to an arbitrary data
+ * which is associated to the promised stream this frame will open and
+ * make it in reserved state.  It is available using
+ * `nghttp2_session_get_stream_user_data()`.  The application can
+ * access it in :type:`nghttp2_before_frame_send_callback` and
+ * :type:`nghttp2_on_frame_send_callback` of this frame.
+ *
+ * The client side is not allowed to use this function.
+ *
+ * To submit response headers and data, use
+ * `nghttp2_submit_response()`.
+ *
+ * This function returns assigned promised stream ID if it succeeds,
+ * or one of the following negative error codes:
+ *
+ * :enum:`NGHTTP2_ERR_NOMEM`
+ *     Out of memory.
+ * :enum:`NGHTTP2_ERR_PROTO`
+ *     This function was invoked when |session| is initialized as
+ *     client.
+ * :enum:`NGHTTP2_ERR_STREAM_ID_NOT_AVAILABLE`
+ *     No stream ID is available because maximum stream ID was
+ *     reached.
+ * :enum:`NGHTTP2_ERR_INVALID_ARGUMENT`
+ *     The |stream_id| is 0; The |stream_id| does not designate stream
+ *     that peer initiated.
+ * :enum:`NGHTTP2_ERR_STREAM_CLOSED`
+ *     The stream was already closed; or the |stream_id| is invalid.
+ *
+ * .. warning::
+ *
+ *   This function returns assigned promised stream ID if it succeeds.
+ *   As of 1.16.0, stream object for pushed resource is created when
+ *   this function succeeds.  In that case, the application can submit
+ *   push response for the promised frame.
+ *
+ *   In 1.15.0 or prior versions, pushed stream is not opened yet when
+ *   this function succeeds.  The application must not submit frame to
+ *   that stream ID before :type:`nghttp2_before_frame_send_callback`
+ *   is called for this frame.
+ *
+ */
+NGHTTP2_EXTERN int32_t nghttp2_submit_push_promise(
+    nghttp2_session *session, uint8_t flags, int32_t stream_id,
+    const nghttp2_nv *nva, size_t nvlen, void *promised_stream_user_data);
+
+/**
+ * @function
+ *
+ * Submits PING frame.  You don't have to send PING back when you
+ * received PING frame.  The library automatically submits PING frame
+ * in this case.
+ *
+ * The |flags| is bitwise OR of 0 or more of the following value.
+ *
+ * * :enum:`NGHTTP2_FLAG_ACK`
+ *
+ * Unless `nghttp2_option_set_no_auto_ping_ack()` is used, the |flags|
+ * should be :enum:`NGHTTP2_FLAG_NONE`.
+ *
+ * If the |opaque_data| is non ``NULL``, then it should point to the 8
+ * bytes array of memory to specify opaque data to send with PING
+ * frame.  If the |opaque_data| is ``NULL``, zero-cleared 8 bytes will
+ * be sent as opaque data.
+ *
+ * This function returns 0 if it succeeds, or one of the following
+ * negative error codes:
+ *
+ * :enum:`NGHTTP2_ERR_NOMEM`
+ *     Out of memory.
+ */
+NGHTTP2_EXTERN int nghttp2_submit_ping(nghttp2_session *session, uint8_t flags,
+                                       const uint8_t *opaque_data);
+
+/**
+ * @function
+ *
+ * Submits GOAWAY frame with the last stream ID |last_stream_id| and
+ * the error code |error_code|.
+ *
+ * The pre-defined error code is one of :enum:`nghttp2_error_code`.
+ *
+ * The |flags| is currently ignored and should be
+ * :enum:`NGHTTP2_FLAG_NONE`.
+ *
+ * The |last_stream_id| is peer's stream ID or 0.  So if |session| is
+ * initialized as client, |last_stream_id| must be even or 0.  If
+ * |session| is initialized as server, |last_stream_id| must be odd or
+ * 0.
+ *
+ * The HTTP/2 specification says last_stream_id must not be increased
+ * from the value previously sent.  So the actual value sent as
+ * last_stream_id is the minimum value between the given
+ * |last_stream_id| and the last_stream_id previously sent to the
+ * peer.
+ *
+ * If the |opaque_data| is not ``NULL`` and |opaque_data_len| is not
+ * zero, those data will be sent as additional debug data.  The
+ * library makes a copy of the memory region pointed by |opaque_data|
+ * with the length |opaque_data_len|, so the caller does not need to
+ * keep this memory after the return of this function.  If the
+ * |opaque_data_len| is 0, the |opaque_data| could be ``NULL``.
+ *
+ * After successful transmission of GOAWAY, following things happen.
+ * All incoming streams having strictly more than |last_stream_id| are
+ * closed.  All incoming HEADERS which starts new stream are simply
+ * ignored.  After all active streams are handled, both
+ * `nghttp2_session_want_read()` and `nghttp2_session_want_write()`
+ * return 0 and the application can close session.
+ *
+ * This function returns 0 if it succeeds, or one of the following
+ * negative error codes:
+ *
+ * :enum:`NGHTTP2_ERR_NOMEM`
+ *     Out of memory.
+ * :enum:`NGHTTP2_ERR_INVALID_ARGUMENT`
+ *     The |opaque_data_len| is too large; the |last_stream_id| is
+ *     invalid.
+ */
+NGHTTP2_EXTERN int nghttp2_submit_goaway(nghttp2_session *session,
+                                         uint8_t flags, int32_t last_stream_id,
+                                         uint32_t error_code,
+                                         const uint8_t *opaque_data,
+                                         size_t opaque_data_len);
+
+/**
+ * @function
+ *
+ * Returns the last stream ID of a stream for which
+ * :type:`nghttp2_on_frame_recv_callback` was invoked most recently.
+ * The returned value can be used as last_stream_id parameter for
+ * `nghttp2_submit_goaway()` and
+ * `nghttp2_session_terminate_session2()`.
+ *
+ * This function always succeeds.
+ */
+NGHTTP2_EXTERN int32_t
+nghttp2_session_get_last_proc_stream_id(nghttp2_session *session);
+
+/**
+ * @function
+ *
+ * Returns nonzero if new request can be sent from local endpoint.
+ *
+ * This function return 0 if request is not allowed for this session.
+ * There are several reasons why request is not allowed.  Some of the
+ * reasons are: session is server; stream ID has been spent; GOAWAY
+ * has been sent or received.
+ *
+ * The application can call `nghttp2_submit_request()` without
+ * consulting this function.  In that case, `nghttp2_submit_request()`
+ * may return error.  Or, request is failed to sent, and
+ * :type:`nghttp2_on_stream_close_callback` is called.
+ */
+NGHTTP2_EXTERN int
+nghttp2_session_check_request_allowed(nghttp2_session *session);
+
+/**
+ * @function
+ *
+ * Returns nonzero if |session| is initialized as server side session.
+ */
+NGHTTP2_EXTERN int
+nghttp2_session_check_server_session(nghttp2_session *session);
+
+/**
+ * @function
+ *
+ * Submits WINDOW_UPDATE frame.
+ *
+ * The |flags| is currently ignored and should be
+ * :enum:`NGHTTP2_FLAG_NONE`.
+ *
+ * The |stream_id| is the stream ID to send this WINDOW_UPDATE.  To
+ * send connection level WINDOW_UPDATE, specify 0 to |stream_id|.
+ *
+ * If the |window_size_increment| is positive, the WINDOW_UPDATE with
+ * that value as window_size_increment is queued.  If the
+ * |window_size_increment| is larger than the received bytes from the
+ * remote endpoint, the local window size is increased by that
+ * difference.  If the sole purpose is to increase the local window
+ * size, consider to use `nghttp2_session_set_local_window_size()`.
+ *
+ * If the |window_size_increment| is negative, the local window size
+ * is decreased by -|window_size_increment|.  If automatic
+ * WINDOW_UPDATE is enabled
+ * (`nghttp2_option_set_no_auto_window_update()`), and the library
+ * decided that the WINDOW_UPDATE should be submitted, then
+ * WINDOW_UPDATE is queued with the current received bytes count.  If
+ * the sole purpose is to decrease the local window size, consider to
+ * use `nghttp2_session_set_local_window_size()`.
+ *
+ * If the |window_size_increment| is 0, the function does nothing and
+ * returns 0.
+ *
+ * This function returns 0 if it succeeds, or one of the following
+ * negative error codes:
+ *
+ * :enum:`NGHTTP2_ERR_FLOW_CONTROL`
+ *     The local window size overflow or gets negative.
+ * :enum:`NGHTTP2_ERR_NOMEM`
+ *     Out of memory.
+ */
+NGHTTP2_EXTERN int nghttp2_submit_window_update(nghttp2_session *session,
+                                                uint8_t flags,
+                                                int32_t stream_id,
+                                                int32_t window_size_increment);
+
+/**
+ * @function
+ *
+ * Set local window size (local endpoints's window size) to the given
+ * |window_size| for the given stream denoted by |stream_id|.  To
+ * change connection level window size, specify 0 to |stream_id|.  To
+ * increase window size, this function may submit WINDOW_UPDATE frame
+ * to transmission queue.
+ *
+ * The |flags| is currently ignored and should be
+ * :enum:`NGHTTP2_FLAG_NONE`.
+ *
+ * This sounds similar to `nghttp2_submit_window_update()`, but there
+ * are 2 differences.  The first difference is that this function
+ * takes the absolute value of window size to set, rather than the
+ * delta.  To change the window size, this may be easier to use since
+ * the application just declares the intended window size, rather than
+ * calculating delta.  The second difference is that
+ * `nghttp2_submit_window_update()` affects the received bytes count
+ * which has not acked yet.  By the specification of
+ * `nghttp2_submit_window_update()`, to strictly increase the local
+ * window size, we have to submit delta including all received bytes
+ * count, which might not be desirable in some cases.  On the other
+ * hand, this function does not affect the received bytes count.  It
+ * just sets the local window size to the given value.
+ *
+ * This function returns 0 if it succeeds, or one of the following
+ * negative error codes:
+ *
+ * :enum:`NGHTTP2_ERR_INVALID_ARGUMENT`
+ *     The |stream_id| is negative.
+ * :enum:`NGHTTP2_ERR_NOMEM`
+ *     Out of memory.
+ */
+NGHTTP2_EXTERN int
+nghttp2_session_set_local_window_size(nghttp2_session *session, uint8_t flags,
+                                      int32_t stream_id, int32_t window_size);
+
+/**
+ * @function
+ *
+ * Submits extension frame.
+ *
+ * Application can pass arbitrary frame flags and stream ID in |flags|
+ * and |stream_id| respectively.  The |payload| is opaque pointer, and
+ * it can be accessible though ``frame->ext.payload`` in
+ * :type:`nghttp2_pack_extension_callback`.  The library will not own
+ * passed |payload| pointer.
+ *
+ * The application must set :type:`nghttp2_pack_extension_callback`
+ * using `nghttp2_session_callbacks_set_pack_extension_callback()`.
+ *
+ * The application should retain the memory pointed by |payload| until
+ * the transmission of extension frame is done (which is indicated by
+ * :type:`nghttp2_on_frame_send_callback`), or transmission fails
+ * (which is indicated by :type:`nghttp2_on_frame_not_send_callback`).
+ * If application does not touch this memory region after packing it
+ * into a wire format, application can free it inside
+ * :type:`nghttp2_pack_extension_callback`.
+ *
+ * The standard HTTP/2 frame cannot be sent with this function, so
+ * |type| must be strictly grater than 0x9.  Otherwise, this function
+ * will fail with error code :enum:`NGHTTP2_ERR_INVALID_ARGUMENT`.
+ *
+ * This function returns 0 if it succeeds, or one of the following
+ * negative error codes:
+ *
+ * :enum:`NGHTTP2_ERR_INVALID_STATE`
+ *     If :type:`nghttp2_pack_extension_callback` is not set.
+ * :enum:`NGHTTP2_ERR_INVALID_ARGUMENT`
+ *     If  |type| specifies  standard  HTTP/2 frame  type.  The  frame
+ *     types  in the  rage [0x0,  0x9], both  inclusive, are  standard
+ *     HTTP/2 frame type, and cannot be sent using this function.
+ * :enum:`NGHTTP2_ERR_NOMEM`
+ *     Out of memory
+ */
+NGHTTP2_EXTERN int nghttp2_submit_extension(nghttp2_session *session,
+                                            uint8_t type, uint8_t flags,
+                                            int32_t stream_id, void *payload);
+
+/**
+ * @struct
+ *
+ * The payload of ALTSVC frame.  ALTSVC frame is a non-critical
+ * extension to HTTP/2.  If this frame is received, and
+ * `nghttp2_option_set_user_recv_extension_type()` is not set, and
+ * `nghttp2_option_set_builtin_recv_extension_type()` is set for
+ * :enum:`NGHTTP2_ALTSVC`, ``nghttp2_extension.payload`` will point to
+ * this struct.
+ *
+ * It has the following members:
+ */
+typedef struct {
+  /**
+   * The pointer to origin which this alternative service is
+   * associated with.  This is not necessarily NULL-terminated.
+   */
+  uint8_t *origin;
+  /**
+   * The length of the |origin|.
+   */
+  size_t origin_len;
+  /**
+   * The pointer to Alt-Svc field value contained in ALTSVC frame.
+   * This is not necessarily NULL-terminated.
+   */
+  uint8_t *field_value;
+  /**
+   * The length of the |field_value|.
+   */
+  size_t field_value_len;
+} nghttp2_ext_altsvc;
+
+/**
+ * @function
+ *
+ * Submits ALTSVC frame.
+ *
+ * ALTSVC frame is a non-critical extension to HTTP/2, and defined in
+ * `RFC 7383 <https://tools.ietf.org/html/rfc7838#section-4>`_.
+ *
+ * The |flags| is currently ignored and should be
+ * :enum:`NGHTTP2_FLAG_NONE`.
+ *
+ * The |origin| points to the origin this alternative service is
+ * associated with.  The |origin_len| is the length of the origin.  If
+ * |stream_id| is 0, the origin must be specified.  If |stream_id| is
+ * not zero, the origin must be empty (in other words, |origin_len|
+ * must be 0).
+ *
+ * The ALTSVC frame is only usable from server side.  If this function
+ * is invoked with client side session, this function returns
+ * :enum:`NGHTTP2_ERR_INVALID_STATE`.
+ *
+ * This function returns 0 if it succeeds, or one of the following
+ * negative error codes:
+ *
+ * :enum:`NGHTTP2_ERR_NOMEM`
+ *     Out of memory
+ * :enum:`NGHTTP2_ERR_INVALID_STATE`
+ *     The function is called from client side session
+ * :enum:`NGHTTP2_ERR_INVALID_ARGUMENT`
+ *     The sum of |origin_len| and |field_value_len| is larger than
+ *     16382; or |origin_len| is 0 while |stream_id| is 0; or
+ *     |origin_len| is not 0 while |stream_id| is not 0.
+ */
+NGHTTP2_EXTERN int nghttp2_submit_altsvc(nghttp2_session *session,
+                                         uint8_t flags, int32_t stream_id,
+                                         const uint8_t *origin,
+                                         size_t origin_len,
+                                         const uint8_t *field_value,
+                                         size_t field_value_len);
+
+/**
+ * @struct
+ *
+ * The single entry of an origin.
+ */
+typedef struct {
+  /**
+   * The pointer to origin.  No validation is made against this field
+   * by the library.  This is not necessarily NULL-terminated.
+   */
+  uint8_t *origin;
+  /**
+   * The length of the |origin|.
+   */
+  size_t origin_len;
+} nghttp2_origin_entry;
+
+/**
+ * @struct
+ *
+ * The payload of ORIGIN frame.  ORIGIN frame is a non-critical
+ * extension to HTTP/2 and defined by `RFC 8336
+ * <https://tools.ietf.org/html/rfc8336>`_.
+ *
+ * If this frame is received, and
+ * `nghttp2_option_set_user_recv_extension_type()` is not set, and
+ * `nghttp2_option_set_builtin_recv_extension_type()` is set for
+ * :enum:`NGHTTP2_ORIGIN`, ``nghttp2_extension.payload`` will point to
+ * this struct.
+ *
+ * It has the following members:
+ */
+typedef struct {
+  /**
+   * The number of origins contained in |ov|.
+   */
+  size_t nov;
+  /**
+   * The pointer to the array of origins contained in ORIGIN frame.
+   */
+  nghttp2_origin_entry *ov;
+} nghttp2_ext_origin;
+
+/**
+ * @function
+ *
+ * Submits ORIGIN frame.
+ *
+ * ORIGIN frame is a non-critical extension to HTTP/2 and defined by
+ * `RFC 8336 <https://tools.ietf.org/html/rfc8336>`_.
+ *
+ * The |flags| is currently ignored and should be
+ * :enum:`NGHTTP2_FLAG_NONE`.
+ *
+ * The |ov| points to the array of origins.  The |nov| specifies the
+ * number of origins included in |ov|.  This function creates copies
+ * of all elements in |ov|.
+ *
+ * The ORIGIN frame is only usable by a server.  If this function is
+ * invoked with client side session, this function returns
+ * :enum:`NGHTTP2_ERR_INVALID_STATE`.
+ *
+ * :enum:`NGHTTP2_ERR_NOMEM`
+ *     Out of memory
+ * :enum:`NGHTTP2_ERR_INVALID_STATE`
+ *     The function is called from client side session.
+ * :enum:`NGHTTP2_ERR_INVALID_ARGUMENT`
+ *     There are too many origins, or an origin is too large to fit
+ *     into a default frame payload.
+ */
+NGHTTP2_EXTERN int nghttp2_submit_origin(nghttp2_session *session,
+                                         uint8_t flags,
+                                         const nghttp2_origin_entry *ov,
+                                         size_t nov);
+
+/**
+ * @function
+ *
+ * Compares ``lhs->name`` of length ``lhs->namelen`` bytes and
+ * ``rhs->name`` of length ``rhs->namelen`` bytes.  Returns negative
+ * integer if ``lhs->name`` is found to be less than ``rhs->name``; or
+ * returns positive integer if ``lhs->name`` is found to be greater
+ * than ``rhs->name``; or returns 0 otherwise.
+ */
+NGHTTP2_EXTERN int nghttp2_nv_compare_name(const nghttp2_nv *lhs,
+                                           const nghttp2_nv *rhs);
+
+/**
+ * @function
+ *
+ * A helper function for dealing with NPN in client side or ALPN in
+ * server side.  The |in| contains peer's protocol list in preferable
+ * order.  The format of |in| is length-prefixed and not
+ * null-terminated.  For example, ``h2`` and
+ * ``http/1.1`` stored in |in| like this::
+ *
+ *     in[0] = 2
+ *     in[1..2] = "h2"
+ *     in[3] = 8
+ *     in[4..11] = "http/1.1"
+ *     inlen = 12
+ *
+ * The selection algorithm is as follows:
+ *
+ * 1. If peer's list contains HTTP/2 protocol the library supports,
+ *    it is selected and returns 1. The following step is not taken.
+ *
+ * 2. If peer's list contains ``http/1.1``, this function selects
+ *    ``http/1.1`` and returns 0.  The following step is not taken.
+ *
+ * 3. This function selects nothing and returns -1 (So called
+ *    non-overlap case).  In this case, |out| and |outlen| are left
+ *    untouched.
+ *
+ * Selecting ``h2`` means that ``h2`` is written into |*out| and its
+ * length (which is 2) is assigned to |*outlen|.
+ *
+ * For ALPN, refer to https://tools.ietf.org/html/rfc7301
+ *
+ * See http://technotes.googlecode.com/git/nextprotoneg.html for more
+ * details about NPN.
+ *
+ * For NPN, to use this method you should do something like::
+ *
+ *     static int select_next_proto_cb(SSL* ssl,
+ *                                     unsigned char **out,
+ *                                     unsigned char *outlen,
+ *                                     const unsigned char *in,
+ *                                     unsigned int inlen,
+ *                                     void *arg)
+ *     {
+ *         int rv;
+ *         rv = nghttp2_select_next_protocol(out, outlen, in, inlen);
+ *         if (rv == -1) {
+ *             return SSL_TLSEXT_ERR_NOACK;
+ *         }
+ *         if (rv == 1) {
+ *             ((MyType*)arg)->http2_selected = 1;
+ *         }
+ *         return SSL_TLSEXT_ERR_OK;
+ *     }
+ *     ...
+ *     SSL_CTX_set_next_proto_select_cb(ssl_ctx, select_next_proto_cb, my_obj);
+ *
+ */
+NGHTTP2_EXTERN int nghttp2_select_next_protocol(unsigned char **out,
+                                                unsigned char *outlen,
+                                                const unsigned char *in,
+                                                unsigned int inlen);
+
+/**
+ * @function
+ *
+ * Returns a pointer to a nghttp2_info struct with version information
+ * about the run-time library in use.  The |least_version| argument
+ * can be set to a 24 bit numerical value for the least accepted
+ * version number and if the condition is not met, this function will
+ * return a ``NULL``.  Pass in 0 to skip the version checking.
+ */
+NGHTTP2_EXTERN nghttp2_info *nghttp2_version(int least_version);
+
+/**
+ * @function
+ *
+ * Returns nonzero if the :type:`nghttp2_error` library error code
+ * |lib_error| is fatal.
+ */
+NGHTTP2_EXTERN int nghttp2_is_fatal(int lib_error_code);
+
+/**
+ * @function
+ *
+ * Returns nonzero if HTTP header field name |name| of length |len| is
+ * valid according to http://tools.ietf.org/html/rfc7230#section-3.2
+ *
+ * Because this is a header field name in HTTP2, the upper cased alphabet
+ * is treated as error.
+ */
+NGHTTP2_EXTERN int nghttp2_check_header_name(const uint8_t *name, size_t len);
+
+/**
+ * @function
+ *
+ * Returns nonzero if HTTP header field value |value| of length |len|
+ * is valid according to
+ * http://tools.ietf.org/html/rfc7230#section-3.2
+ */
+NGHTTP2_EXTERN int nghttp2_check_header_value(const uint8_t *value, size_t len);
+
+/**
+ * @function
+ *
+ * Returns nonzero if the |value| which is supposed to the value of
+ * :authority or host header field is valid according to
+ * https://tools.ietf.org/html/rfc3986#section-3.2
+ *
+ * |value| is valid if it merely consists of the allowed characters.
+ * In particular, it does not check whether |value| follows the syntax
+ * of authority.
+ */
+NGHTTP2_EXTERN int nghttp2_check_authority(const uint8_t *value, size_t len);
+
+/* HPACK API */
+
+struct nghttp2_hd_deflater;
+
+/**
+ * @struct
+ *
+ * HPACK deflater object.
+ */
+typedef struct nghttp2_hd_deflater nghttp2_hd_deflater;
+
+/**
+ * @function
+ *
+ * Initializes |*deflater_ptr| for deflating name/values pairs.
+ *
+ * The |max_deflate_dynamic_table_size| is the upper bound of header
+ * table size the deflater will use.
+ *
+ * If this function fails, |*deflater_ptr| is left untouched.
+ *
+ * This function returns 0 if it succeeds, or one of the following
+ * negative error codes:
+ *
+ * :enum:`NGHTTP2_ERR_NOMEM`
+ *     Out of memory.
+ */
+NGHTTP2_EXTERN int
+nghttp2_hd_deflate_new(nghttp2_hd_deflater **deflater_ptr,
+                       size_t max_deflate_dynamic_table_size);
+
+/**
+ * @function
+ *
+ * Like `nghttp2_hd_deflate_new()`, but with additional custom memory
+ * allocator specified in the |mem|.
+ *
+ * The |mem| can be ``NULL`` and the call is equivalent to
+ * `nghttp2_hd_deflate_new()`.
+ *
+ * This function does not take ownership |mem|.  The application is
+ * responsible for freeing |mem|.
+ *
+ * The library code does not refer to |mem| pointer after this
+ * function returns, so the application can safely free it.
+ */
+NGHTTP2_EXTERN int
+nghttp2_hd_deflate_new2(nghttp2_hd_deflater **deflater_ptr,
+                        size_t max_deflate_dynamic_table_size,
+                        nghttp2_mem *mem);
+
+/**
+ * @function
+ *
+ * Deallocates any resources allocated for |deflater|.
+ */
+NGHTTP2_EXTERN void nghttp2_hd_deflate_del(nghttp2_hd_deflater *deflater);
+
+/**
+ * @function
+ *
+ * Changes header table size of the |deflater| to
+ * |settings_max_dynamic_table_size| bytes.  This may trigger eviction
+ * in the dynamic table.
+ *
+ * The |settings_max_dynamic_table_size| should be the value received
+ * in SETTINGS_HEADER_TABLE_SIZE.
+ *
+ * The deflater never uses more memory than
+ * ``max_deflate_dynamic_table_size`` bytes specified in
+ * `nghttp2_hd_deflate_new()`.  Therefore, if
+ * |settings_max_dynamic_table_size| >
+ * ``max_deflate_dynamic_table_size``, resulting maximum table size
+ * becomes ``max_deflate_dynamic_table_size``.
+ *
+ * This function returns 0 if it succeeds, or one of the following
+ * negative error codes:
+ *
+ * :enum:`NGHTTP2_ERR_NOMEM`
+ *     Out of memory.
+ */
+NGHTTP2_EXTERN int
+nghttp2_hd_deflate_change_table_size(nghttp2_hd_deflater *deflater,
+                                     size_t settings_max_dynamic_table_size);
+
+/**
+ * @function
+ *
+ * Deflates the |nva|, which has the |nvlen| name/value pairs, into
+ * the |buf| of length |buflen|.
+ *
+ * If |buf| is not large enough to store the deflated header block,
+ * this function fails with :enum:`NGHTTP2_ERR_INSUFF_BUFSIZE`.  The
+ * caller should use `nghttp2_hd_deflate_bound()` to know the upper
+ * bound of buffer size required to deflate given header name/value
+ * pairs.
+ *
+ * Once this function fails, subsequent call of this function always
+ * returns :enum:`NGHTTP2_ERR_HEADER_COMP`.
+ *
+ * After this function returns, it is safe to delete the |nva|.
+ *
+ * This function returns the number of bytes written to |buf| if it
+ * succeeds, or one of the following negative error codes:
+ *
+ * :enum:`NGHTTP2_ERR_NOMEM`
+ *     Out of memory.
+ * :enum:`NGHTTP2_ERR_HEADER_COMP`
+ *     Deflation process has failed.
+ * :enum:`NGHTTP2_ERR_INSUFF_BUFSIZE`
+ *     The provided |buflen| size is too small to hold the output.
+ */
+NGHTTP2_EXTERN ssize_t nghttp2_hd_deflate_hd(nghttp2_hd_deflater *deflater,
+                                             uint8_t *buf, size_t buflen,
+                                             const nghttp2_nv *nva,
+                                             size_t nvlen);
+
+/**
+ * @function
+ *
+ * Deflates the |nva|, which has the |nvlen| name/value pairs, into
+ * the |veclen| size of buf vector |vec|.  The each size of buffer
+ * must be set in len field of :type:`nghttp2_vec`.  If and only if
+ * one chunk is filled up completely, next chunk will be used.  If
+ * |vec| is not large enough to store the deflated header block, this
+ * function fails with :enum:`NGHTTP2_ERR_INSUFF_BUFSIZE`.  The caller
+ * should use `nghttp2_hd_deflate_bound()` to know the upper bound of
+ * buffer size required to deflate given header name/value pairs.
+ *
+ * Once this function fails, subsequent call of this function always
+ * returns :enum:`NGHTTP2_ERR_HEADER_COMP`.
+ *
+ * After this function returns, it is safe to delete the |nva|.
+ *
+ * This function returns the number of bytes written to |vec| if it
+ * succeeds, or one of the following negative error codes:
+ *
+ * :enum:`NGHTTP2_ERR_NOMEM`
+ *     Out of memory.
+ * :enum:`NGHTTP2_ERR_HEADER_COMP`
+ *     Deflation process has failed.
+ * :enum:`NGHTTP2_ERR_INSUFF_BUFSIZE`
+ *     The provided |buflen| size is too small to hold the output.
+ */
+NGHTTP2_EXTERN ssize_t nghttp2_hd_deflate_hd_vec(nghttp2_hd_deflater *deflater,
+                                                 const nghttp2_vec *vec,
+                                                 size_t veclen,
+                                                 const nghttp2_nv *nva,
+                                                 size_t nvlen);
+
+/**
+ * @function
+ *
+ * Returns an upper bound on the compressed size after deflation of
+ * |nva| of length |nvlen|.
+ */
+NGHTTP2_EXTERN size_t nghttp2_hd_deflate_bound(nghttp2_hd_deflater *deflater,
+                                               const nghttp2_nv *nva,
+                                               size_t nvlen);
+
+/**
+ * @function
+ *
+ * Returns the number of entries that header table of |deflater|
+ * contains.  This is the sum of the number of static table and
+ * dynamic table, so the return value is at least 61.
+ */
+NGHTTP2_EXTERN
+size_t nghttp2_hd_deflate_get_num_table_entries(nghttp2_hd_deflater *deflater);
+
+/**
+ * @function
+ *
+ * Returns the table entry denoted by |idx| from header table of
+ * |deflater|.  The |idx| is 1-based, and idx=1 returns first entry of
+ * static table.  idx=62 returns first entry of dynamic table if it
+ * exists.  Specifying idx=0 is error, and this function returns NULL.
+ * If |idx| is strictly greater than the number of entries the tables
+ * contain, this function returns NULL.
+ */
+NGHTTP2_EXTERN
+const nghttp2_nv *
+nghttp2_hd_deflate_get_table_entry(nghttp2_hd_deflater *deflater, size_t idx);
+
+/**
+ * @function
+ *
+ * Returns the used dynamic table size, including the overhead 32
+ * bytes per entry described in RFC 7541.
+ */
+NGHTTP2_EXTERN
+size_t nghttp2_hd_deflate_get_dynamic_table_size(nghttp2_hd_deflater *deflater);
+
+/**
+ * @function
+ *
+ * Returns the maximum dynamic table size.
+ */
+NGHTTP2_EXTERN
+size_t
+nghttp2_hd_deflate_get_max_dynamic_table_size(nghttp2_hd_deflater *deflater);
+
+struct nghttp2_hd_inflater;
+
+/**
+ * @struct
+ *
+ * HPACK inflater object.
+ */
+typedef struct nghttp2_hd_inflater nghttp2_hd_inflater;
+
+/**
+ * @function
+ *
+ * Initializes |*inflater_ptr| for inflating name/values pairs.
+ *
+ * If this function fails, |*inflater_ptr| is left untouched.
+ *
+ * This function returns 0 if it succeeds, or one of the following
+ * negative error codes:
+ *
+ * :enum:`NGHTTP2_ERR_NOMEM`
+ *     Out of memory.
+ */
+NGHTTP2_EXTERN int nghttp2_hd_inflate_new(nghttp2_hd_inflater **inflater_ptr);
+
+/**
+ * @function
+ *
+ * Like `nghttp2_hd_inflate_new()`, but with additional custom memory
+ * allocator specified in the |mem|.
+ *
+ * The |mem| can be ``NULL`` and the call is equivalent to
+ * `nghttp2_hd_inflate_new()`.
+ *
+ * This function does not take ownership |mem|.  The application is
+ * responsible for freeing |mem|.
+ *
+ * The library code does not refer to |mem| pointer after this
+ * function returns, so the application can safely free it.
+ */
+NGHTTP2_EXTERN int nghttp2_hd_inflate_new2(nghttp2_hd_inflater **inflater_ptr,
+                                           nghttp2_mem *mem);
+
+/**
+ * @function
+ *
+ * Deallocates any resources allocated for |inflater|.
+ */
+NGHTTP2_EXTERN void nghttp2_hd_inflate_del(nghttp2_hd_inflater *inflater);
+
+/**
+ * @function
+ *
+ * Changes header table size in the |inflater|.  This may trigger
+ * eviction in the dynamic table.
+ *
+ * The |settings_max_dynamic_table_size| should be the value
+ * transmitted in SETTINGS_HEADER_TABLE_SIZE.
+ *
+ * This function must not be called while header block is being
+ * inflated.  In other words, this function must be called after
+ * initialization of |inflater|, but before calling
+ * `nghttp2_hd_inflate_hd2()`, or after
+ * `nghttp2_hd_inflate_end_headers()`.  Otherwise,
+ * `NGHTTP2_ERR_INVALID_STATE` was returned.
+ *
+ * This function returns 0 if it succeeds, or one of the following
+ * negative error codes:
+ *
+ * :enum:`NGHTTP2_ERR_NOMEM`
+ *     Out of memory.
+ * :enum:`NGHTTP2_ERR_INVALID_STATE`
+ *     The function is called while header block is being inflated.
+ *     Probably, application missed to call
+ *     `nghttp2_hd_inflate_end_headers()`.
+ */
+NGHTTP2_EXTERN int
+nghttp2_hd_inflate_change_table_size(nghttp2_hd_inflater *inflater,
+                                     size_t settings_max_dynamic_table_size);
+
+/**
+ * @enum
+ *
+ * The flags for header inflation.
+ */
+typedef enum {
+  /**
+   * No flag set.
+   */
+  NGHTTP2_HD_INFLATE_NONE = 0,
+  /**
+   * Indicates all headers were inflated.
+   */
+  NGHTTP2_HD_INFLATE_FINAL = 0x01,
+  /**
+   * Indicates a header was emitted.
+   */
+  NGHTTP2_HD_INFLATE_EMIT = 0x02
+} nghttp2_hd_inflate_flag;
+
+/**
+ * @function
+ *
+ * .. warning::
+ *
+ *   Deprecated.  Use `nghttp2_hd_inflate_hd2()` instead.
+ *
+ * Inflates name/value block stored in |in| with length |inlen|.  This
+ * function performs decompression.  For each successful emission of
+ * header name/value pair, :enum:`NGHTTP2_HD_INFLATE_EMIT` is set in
+ * |*inflate_flags| and name/value pair is assigned to the |nv_out|
+ * and the function returns.  The caller must not free the members of
+ * |nv_out|.
+ *
+ * The |nv_out| may include pointers to the memory region in the |in|.
+ * The caller must retain the |in| while the |nv_out| is used.
+ *
+ * The application should call this function repeatedly until the
+ * ``(*inflate_flags) & NGHTTP2_HD_INFLATE_FINAL`` is nonzero and
+ * return value is non-negative.  This means the all input values are
+ * processed successfully.  Then the application must call
+ * `nghttp2_hd_inflate_end_headers()` to prepare for the next header
+ * block input.
+ *
+ * The caller can feed complete compressed header block.  It also can
+ * feed it in several chunks.  The caller must set |in_final| to
+ * nonzero if the given input is the last block of the compressed
+ * header.
+ *
+ * This function returns the number of bytes processed if it succeeds,
+ * or one of the following negative error codes:
+ *
+ * :enum:`NGHTTP2_ERR_NOMEM`
+ *     Out of memory.
+ * :enum:`NGHTTP2_ERR_HEADER_COMP`
+ *     Inflation process has failed.
+ * :enum:`NGHTTP2_ERR_BUFFER_ERROR`
+ *     The header field name or value is too large.
+ *
+ * Example follows::
+ *
+ *     int inflate_header_block(nghttp2_hd_inflater *hd_inflater,
+ *                              uint8_t *in, size_t inlen, int final)
+ *     {
+ *         ssize_t rv;
+ *
+ *         for(;;) {
+ *             nghttp2_nv nv;
+ *             int inflate_flags = 0;
+ *
+ *             rv = nghttp2_hd_inflate_hd(hd_inflater, &nv, &inflate_flags,
+ *                                        in, inlen, final);
+ *
+ *             if(rv < 0) {
+ *                 fprintf(stderr, "inflate failed with error code %zd", rv);
+ *                 return -1;
+ *             }
+ *
+ *             in += rv;
+ *             inlen -= rv;
+ *
+ *             if(inflate_flags & NGHTTP2_HD_INFLATE_EMIT) {
+ *                 fwrite(nv.name, nv.namelen, 1, stderr);
+ *                 fprintf(stderr, ": ");
+ *                 fwrite(nv.value, nv.valuelen, 1, stderr);
+ *                 fprintf(stderr, "\n");
+ *             }
+ *             if(inflate_flags & NGHTTP2_HD_INFLATE_FINAL) {
+ *                 nghttp2_hd_inflate_end_headers(hd_inflater);
+ *                 break;
+ *             }
+ *             if((inflate_flags & NGHTTP2_HD_INFLATE_EMIT) == 0 &&
+ *                inlen == 0) {
+ *                break;
+ *             }
+ *         }
+ *
+ *         return 0;
+ *     }
+ *
+ */
+NGHTTP2_EXTERN ssize_t nghttp2_hd_inflate_hd(nghttp2_hd_inflater *inflater,
+                                             nghttp2_nv *nv_out,
+                                             int *inflate_flags, uint8_t *in,
+                                             size_t inlen, int in_final);
+
+/**
+ * @function
+ *
+ * Inflates name/value block stored in |in| with length |inlen|.  This
+ * function performs decompression.  For each successful emission of
+ * header name/value pair, :enum:`NGHTTP2_HD_INFLATE_EMIT` is set in
+ * |*inflate_flags| and name/value pair is assigned to the |nv_out|
+ * and the function returns.  The caller must not free the members of
+ * |nv_out|.
+ *
+ * The |nv_out| may include pointers to the memory region in the |in|.
+ * The caller must retain the |in| while the |nv_out| is used.
+ *
+ * The application should call this function repeatedly until the
+ * ``(*inflate_flags) & NGHTTP2_HD_INFLATE_FINAL`` is nonzero and
+ * return value is non-negative.  If that happens, all given input
+ * data (|inlen| bytes) are processed successfully.  Then the
+ * application must call `nghttp2_hd_inflate_end_headers()` to prepare
+ * for the next header block input.
+ *
+ * In other words, if |in_final| is nonzero, and this function returns
+ * |inlen|, you can assert that :enum:`NGHTTP2_HD_INFLATE_FINAL` is
+ * set in |*inflate_flags|.
+ *
+ * The caller can feed complete compressed header block.  It also can
+ * feed it in several chunks.  The caller must set |in_final| to
+ * nonzero if the given input is the last block of the compressed
+ * header.
+ *
+ * This function returns the number of bytes processed if it succeeds,
+ * or one of the following negative error codes:
+ *
+ * :enum:`NGHTTP2_ERR_NOMEM`
+ *     Out of memory.
+ * :enum:`NGHTTP2_ERR_HEADER_COMP`
+ *     Inflation process has failed.
+ * :enum:`NGHTTP2_ERR_BUFFER_ERROR`
+ *     The header field name or value is too large.
+ *
+ * Example follows::
+ *
+ *     int inflate_header_block(nghttp2_hd_inflater *hd_inflater,
+ *                              uint8_t *in, size_t inlen, int final)
+ *     {
+ *         ssize_t rv;
+ *
+ *         for(;;) {
+ *             nghttp2_nv nv;
+ *             int inflate_flags = 0;
+ *
+ *             rv = nghttp2_hd_inflate_hd2(hd_inflater, &nv, &inflate_flags,
+ *                                         in, inlen, final);
+ *
+ *             if(rv < 0) {
+ *                 fprintf(stderr, "inflate failed with error code %zd", rv);
+ *                 return -1;
+ *             }
+ *
+ *             in += rv;
+ *             inlen -= rv;
+ *
+ *             if(inflate_flags & NGHTTP2_HD_INFLATE_EMIT) {
+ *                 fwrite(nv.name, nv.namelen, 1, stderr);
+ *                 fprintf(stderr, ": ");
+ *                 fwrite(nv.value, nv.valuelen, 1, stderr);
+ *                 fprintf(stderr, "\n");
+ *             }
+ *             if(inflate_flags & NGHTTP2_HD_INFLATE_FINAL) {
+ *                 nghttp2_hd_inflate_end_headers(hd_inflater);
+ *                 break;
+ *             }
+ *             if((inflate_flags & NGHTTP2_HD_INFLATE_EMIT) == 0 &&
+ *                inlen == 0) {
+ *                break;
+ *             }
+ *         }
+ *
+ *         return 0;
+ *     }
+ *
+ */
+NGHTTP2_EXTERN ssize_t nghttp2_hd_inflate_hd2(nghttp2_hd_inflater *inflater,
+                                              nghttp2_nv *nv_out,
+                                              int *inflate_flags,
+                                              const uint8_t *in, size_t inlen,
+                                              int in_final);
+
+/**
+ * @function
+ *
+ * Signals the end of decompression for one header block.
+ *
+ * This function returns 0 if it succeeds. Currently this function
+ * always succeeds.
+ */
+NGHTTP2_EXTERN int
+nghttp2_hd_inflate_end_headers(nghttp2_hd_inflater *inflater);
+
+/**
+ * @function
+ *
+ * Returns the number of entries that header table of |inflater|
+ * contains.  This is the sum of the number of static table and
+ * dynamic table, so the return value is at least 61.
+ */
+NGHTTP2_EXTERN
+size_t nghttp2_hd_inflate_get_num_table_entries(nghttp2_hd_inflater *inflater);
+
+/**
+ * @function
+ *
+ * Returns the table entry denoted by |idx| from header table of
+ * |inflater|.  The |idx| is 1-based, and idx=1 returns first entry of
+ * static table.  idx=62 returns first entry of dynamic table if it
+ * exists.  Specifying idx=0 is error, and this function returns NULL.
+ * If |idx| is strictly greater than the number of entries the tables
+ * contain, this function returns NULL.
+ */
+NGHTTP2_EXTERN
+const nghttp2_nv *
+nghttp2_hd_inflate_get_table_entry(nghttp2_hd_inflater *inflater, size_t idx);
+
+/**
+ * @function
+ *
+ * Returns the used dynamic table size, including the overhead 32
+ * bytes per entry described in RFC 7541.
+ */
+NGHTTP2_EXTERN
+size_t nghttp2_hd_inflate_get_dynamic_table_size(nghttp2_hd_inflater *inflater);
+
+/**
+ * @function
+ *
+ * Returns the maximum dynamic table size.
+ */
+NGHTTP2_EXTERN
+size_t
+nghttp2_hd_inflate_get_max_dynamic_table_size(nghttp2_hd_inflater *inflater);
+
+struct nghttp2_stream;
+
+/**
+ * @struct
+ *
+ * The structure to represent HTTP/2 stream.  The details of this
+ * structure are intentionally hidden from the public API.
+ */
+typedef struct nghttp2_stream nghttp2_stream;
+
+/**
+ * @function
+ *
+ * Returns pointer to :type:`nghttp2_stream` object denoted by
+ * |stream_id|.  If stream was not found, returns NULL.
+ *
+ * Returns imaginary root stream (see
+ * `nghttp2_session_get_root_stream()`) if 0 is given in |stream_id|.
+ *
+ * Unless |stream_id| == 0, the returned pointer is valid until next
+ * call of `nghttp2_session_send()`, `nghttp2_session_mem_send()`,
+ * `nghttp2_session_recv()`, and `nghttp2_session_mem_recv()`.
+ */
+NGHTTP2_EXTERN nghttp2_stream *
+nghttp2_session_find_stream(nghttp2_session *session, int32_t stream_id);
+
+/**
+ * @enum
+ *
+ * State of stream as described in RFC 7540.
+ */
+typedef enum {
+  /**
+   * idle state.
+   */
+  NGHTTP2_STREAM_STATE_IDLE = 1,
+  /**
+   * open state.
+   */
+  NGHTTP2_STREAM_STATE_OPEN,
+  /**
+   * reserved (local) state.
+   */
+  NGHTTP2_STREAM_STATE_RESERVED_LOCAL,
+  /**
+   * reserved (remote) state.
+   */
+  NGHTTP2_STREAM_STATE_RESERVED_REMOTE,
+  /**
+   * half closed (local) state.
+   */
+  NGHTTP2_STREAM_STATE_HALF_CLOSED_LOCAL,
+  /**
+   * half closed (remote) state.
+   */
+  NGHTTP2_STREAM_STATE_HALF_CLOSED_REMOTE,
+  /**
+   * closed state.
+   */
+  NGHTTP2_STREAM_STATE_CLOSED
+} nghttp2_stream_proto_state;
+
+/**
+ * @function
+ *
+ * Returns state of |stream|.  The root stream retrieved by
+ * `nghttp2_session_get_root_stream()` will have stream state
+ * :enum:`NGHTTP2_STREAM_STATE_IDLE`.
+ */
+NGHTTP2_EXTERN nghttp2_stream_proto_state
+nghttp2_stream_get_state(nghttp2_stream *stream);
+
+/**
+ * @function
+ *
+ * Returns root of dependency tree, which is imaginary stream with
+ * stream ID 0.  The returned pointer is valid until |session| is
+ * freed by `nghttp2_session_del()`.
+ */
+NGHTTP2_EXTERN nghttp2_stream *
+nghttp2_session_get_root_stream(nghttp2_session *session);
+
+/**
+ * @function
+ *
+ * Returns the parent stream of |stream| in dependency tree.  Returns
+ * NULL if there is no such stream.
+ */
+NGHTTP2_EXTERN nghttp2_stream *
+nghttp2_stream_get_parent(nghttp2_stream *stream);
+
+NGHTTP2_EXTERN int32_t nghttp2_stream_get_stream_id(nghttp2_stream *stream);
+
+/**
+ * @function
+ *
+ * Returns the next sibling stream of |stream| in dependency tree.
+ * Returns NULL if there is no such stream.
+ */
+NGHTTP2_EXTERN nghttp2_stream *
+nghttp2_stream_get_next_sibling(nghttp2_stream *stream);
+
+/**
+ * @function
+ *
+ * Returns the previous sibling stream of |stream| in dependency tree.
+ * Returns NULL if there is no such stream.
+ */
+NGHTTP2_EXTERN nghttp2_stream *
+nghttp2_stream_get_previous_sibling(nghttp2_stream *stream);
+
+/**
+ * @function
+ *
+ * Returns the first child stream of |stream| in dependency tree.
+ * Returns NULL if there is no such stream.
+ */
+NGHTTP2_EXTERN nghttp2_stream *
+nghttp2_stream_get_first_child(nghttp2_stream *stream);
+
+/**
+ * @function
+ *
+ * Returns dependency weight to the parent stream of |stream|.
+ */
+NGHTTP2_EXTERN int32_t nghttp2_stream_get_weight(nghttp2_stream *stream);
+
+/**
+ * @function
+ *
+ * Returns the sum of the weight for |stream|'s children.
+ */
+NGHTTP2_EXTERN int32_t
+nghttp2_stream_get_sum_dependency_weight(nghttp2_stream *stream);
+
+/**
+ * @functypedef
+ *
+ * Callback function invoked when the library outputs debug logging.
+ * The function is called with arguments suitable for ``vfprintf(3)``
+ *
+ * The debug output is only enabled if the library is built with
+ * ``DEBUGBUILD`` macro defined.
+ */
+typedef void (*nghttp2_debug_vprintf_callback)(const char *format,
+                                               va_list args);
+
+/**
+ * @function
+ *
+ * Sets a debug output callback called by the library when built with
+ * ``DEBUGBUILD`` macro defined.  If this option is not used, debug
+ * log is written into standard error output.
+ *
+ * For builds without ``DEBUGBUILD`` macro defined, this function is
+ * noop.
+ *
+ * Note that building with ``DEBUGBUILD`` may cause significant
+ * performance penalty to libnghttp2 because of extra processing.  It
+ * should be used for debugging purpose only.
+ *
+ * .. Warning::
+ *
+ *   Building with ``DEBUGBUILD`` may cause significant performance
+ *   penalty to libnghttp2 because of extra processing.  It should be
+ *   used for debugging purpose only.  We write this two times because
+ *   this is important.
+ */
+NGHTTP2_EXTERN void nghttp2_set_debug_vprintf_callback(
+    nghttp2_debug_vprintf_callback debug_vprintf_callback);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* NGHTTP2_H */
diff --git a/Utilities/cmnghttp2/lib/includes/nghttp2/nghttp2ver.h b/Utilities/cmnghttp2/lib/includes/nghttp2/nghttp2ver.h
new file mode 100644
index 0000000..45d21e2
--- /dev/null
+++ b/Utilities/cmnghttp2/lib/includes/nghttp2/nghttp2ver.h
@@ -0,0 +1,42 @@
+/*
+ * nghttp2 - HTTP/2 C Library
+ *
+ * Copyright (c) 2012, 2013 Tatsuhiro Tsujikawa
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+#ifndef NGHTTP2VER_H
+#define NGHTTP2VER_H
+
+/**
+ * @macro
+ * Version number of the nghttp2 library release
+ */
+#define NGHTTP2_VERSION "1.40.0"
+
+/**
+ * @macro
+ * Numerical representation of the version number of the nghttp2 library
+ * release. This is a 24 bit number with 8 bits for major number, 8 bits
+ * for minor and 8 bits for patch. Version 1.2.3 becomes 0x010203.
+ */
+#define NGHTTP2_VERSION_NUM 0x012800
+
+#endif /* NGHTTP2VER_H */
diff --git a/Utilities/cmnghttp2/lib/nghttp2_buf.c b/Utilities/cmnghttp2/lib/nghttp2_buf.c
new file mode 100644
index 0000000..2a435be
--- /dev/null
+++ b/Utilities/cmnghttp2/lib/nghttp2_buf.c
@@ -0,0 +1,525 @@
+/*
+ * nghttp2 - HTTP/2 C Library
+ *
+ * Copyright (c) 2014 Tatsuhiro Tsujikawa
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+#include "nghttp2_buf.h"
+
+#include <stdio.h>
+
+#include "nghttp2_helper.h"
+#include "nghttp2_debug.h"
+
+void nghttp2_buf_init(nghttp2_buf *buf) {
+  buf->begin = NULL;
+  buf->end = NULL;
+  buf->pos = NULL;
+  buf->last = NULL;
+  buf->mark = NULL;
+}
+
+int nghttp2_buf_init2(nghttp2_buf *buf, size_t initial, nghttp2_mem *mem) {
+  nghttp2_buf_init(buf);
+  return nghttp2_buf_reserve(buf, initial, mem);
+}
+
+void nghttp2_buf_free(nghttp2_buf *buf, nghttp2_mem *mem) {
+  if (buf == NULL) {
+    return;
+  }
+
+  nghttp2_mem_free(mem, buf->begin);
+  buf->begin = NULL;
+}
+
+int nghttp2_buf_reserve(nghttp2_buf *buf, size_t new_cap, nghttp2_mem *mem) {
+  uint8_t *ptr;
+  size_t cap;
+
+  cap = nghttp2_buf_cap(buf);
+
+  if (cap >= new_cap) {
+    return 0;
+  }
+
+  new_cap = nghttp2_max(new_cap, cap * 2);
+
+  ptr = nghttp2_mem_realloc(mem, buf->begin, new_cap);
+  if (ptr == NULL) {
+    return NGHTTP2_ERR_NOMEM;
+  }
+
+  buf->pos = ptr + (buf->pos - buf->begin);
+  buf->last = ptr + (buf->last - buf->begin);
+  buf->mark = ptr + (buf->mark - buf->begin);
+  buf->begin = ptr;
+  buf->end = ptr + new_cap;
+
+  return 0;
+}
+
+void nghttp2_buf_reset(nghttp2_buf *buf) {
+  buf->pos = buf->last = buf->mark = buf->begin;
+}
+
+void nghttp2_buf_wrap_init(nghttp2_buf *buf, uint8_t *begin, size_t len) {
+  buf->begin = buf->pos = buf->last = buf->mark = begin;
+  buf->end = begin + len;
+}
+
+static int buf_chain_new(nghttp2_buf_chain **chain, size_t chunk_length,
+                         nghttp2_mem *mem) {
+  int rv;
+
+  *chain = nghttp2_mem_malloc(mem, sizeof(nghttp2_buf_chain));
+  if (*chain == NULL) {
+    return NGHTTP2_ERR_NOMEM;
+  }
+
+  (*chain)->next = NULL;
+
+  rv = nghttp2_buf_init2(&(*chain)->buf, chunk_length, mem);
+  if (rv != 0) {
+    nghttp2_mem_free(mem, *chain);
+    return NGHTTP2_ERR_NOMEM;
+  }
+
+  return 0;
+}
+
+static void buf_chain_del(nghttp2_buf_chain *chain, nghttp2_mem *mem) {
+  nghttp2_buf_free(&chain->buf, mem);
+  nghttp2_mem_free(mem, chain);
+}
+
+int nghttp2_bufs_init(nghttp2_bufs *bufs, size_t chunk_length, size_t max_chunk,
+                      nghttp2_mem *mem) {
+  return nghttp2_bufs_init2(bufs, chunk_length, max_chunk, 0, mem);
+}
+
+int nghttp2_bufs_init2(nghttp2_bufs *bufs, size_t chunk_length,
+                       size_t max_chunk, size_t offset, nghttp2_mem *mem) {
+  return nghttp2_bufs_init3(bufs, chunk_length, max_chunk, max_chunk, offset,
+                            mem);
+}
+
+int nghttp2_bufs_init3(nghttp2_bufs *bufs, size_t chunk_length,
+                       size_t max_chunk, size_t chunk_keep, size_t offset,
+                       nghttp2_mem *mem) {
+  int rv;
+  nghttp2_buf_chain *chain;
+
+  if (chunk_keep == 0 || max_chunk < chunk_keep || chunk_length < offset) {
+    return NGHTTP2_ERR_INVALID_ARGUMENT;
+  }
+
+  rv = buf_chain_new(&chain, chunk_length, mem);
+  if (rv != 0) {
+    return rv;
+  }
+
+  bufs->mem = mem;
+  bufs->offset = offset;
+
+  bufs->head = chain;
+  bufs->cur = bufs->head;
+
+  nghttp2_buf_shift_right(&bufs->cur->buf, offset);
+
+  bufs->chunk_length = chunk_length;
+  bufs->chunk_used = 1;
+  bufs->max_chunk = max_chunk;
+  bufs->chunk_keep = chunk_keep;
+
+  return 0;
+}
+
+int nghttp2_bufs_realloc(nghttp2_bufs *bufs, size_t chunk_length) {
+  int rv;
+  nghttp2_buf_chain *chain;
+
+  if (chunk_length < bufs->offset) {
+    return NGHTTP2_ERR_INVALID_ARGUMENT;
+  }
+
+  rv = buf_chain_new(&chain, chunk_length, bufs->mem);
+  if (rv != 0) {
+    return rv;
+  }
+
+  nghttp2_bufs_free(bufs);
+
+  bufs->head = chain;
+  bufs->cur = bufs->head;
+
+  nghttp2_buf_shift_right(&bufs->cur->buf, bufs->offset);
+
+  bufs->chunk_length = chunk_length;
+  bufs->chunk_used = 1;
+
+  return 0;
+}
+
+void nghttp2_bufs_free(nghttp2_bufs *bufs) {
+  nghttp2_buf_chain *chain, *next_chain;
+
+  if (bufs == NULL) {
+    return;
+  }
+
+  for (chain = bufs->head; chain;) {
+    next_chain = chain->next;
+
+    buf_chain_del(chain, bufs->mem);
+
+    chain = next_chain;
+  }
+
+  bufs->head = NULL;
+}
+
+int nghttp2_bufs_wrap_init(nghttp2_bufs *bufs, uint8_t *begin, size_t len,
+                           nghttp2_mem *mem) {
+  nghttp2_buf_chain *chain;
+
+  chain = nghttp2_mem_malloc(mem, sizeof(nghttp2_buf_chain));
+  if (chain == NULL) {
+    return NGHTTP2_ERR_NOMEM;
+  }
+
+  chain->next = NULL;
+
+  nghttp2_buf_wrap_init(&chain->buf, begin, len);
+
+  bufs->mem = mem;
+  bufs->offset = 0;
+
+  bufs->head = chain;
+  bufs->cur = bufs->head;
+
+  bufs->chunk_length = len;
+  bufs->chunk_used = 1;
+  bufs->max_chunk = 1;
+  bufs->chunk_keep = 1;
+
+  return 0;
+}
+
+int nghttp2_bufs_wrap_init2(nghttp2_bufs *bufs, const nghttp2_vec *vec,
+                            size_t veclen, nghttp2_mem *mem) {
+  size_t i = 0;
+  nghttp2_buf_chain *cur_chain;
+  nghttp2_buf_chain *head_chain;
+  nghttp2_buf_chain **dst_chain = &head_chain;
+
+  if (veclen == 0) {
+    return nghttp2_bufs_wrap_init(bufs, NULL, 0, mem);
+  }
+
+  head_chain = nghttp2_mem_malloc(mem, sizeof(nghttp2_buf_chain) * veclen);
+  if (head_chain == NULL) {
+    return NGHTTP2_ERR_NOMEM;
+  }
+
+  for (i = 0; i < veclen; ++i) {
+    cur_chain = &head_chain[i];
+    cur_chain->next = NULL;
+    nghttp2_buf_wrap_init(&cur_chain->buf, vec[i].base, vec[i].len);
+
+    *dst_chain = cur_chain;
+    dst_chain = &cur_chain->next;
+  }
+
+  bufs->mem = mem;
+  bufs->offset = 0;
+
+  bufs->head = head_chain;
+  bufs->cur = bufs->head;
+
+  /* We don't use chunk_length since no allocation is expected. */
+  bufs->chunk_length = 0;
+  bufs->chunk_used = veclen;
+  bufs->max_chunk = veclen;
+  bufs->chunk_keep = veclen;
+
+  return 0;
+}
+
+void nghttp2_bufs_wrap_free(nghttp2_bufs *bufs) {
+  if (bufs == NULL) {
+    return;
+  }
+
+  if (bufs->head) {
+    nghttp2_mem_free(bufs->mem, bufs->head);
+  }
+}
+
+void nghttp2_bufs_seek_last_present(nghttp2_bufs *bufs) {
+  nghttp2_buf_chain *ci;
+
+  for (ci = bufs->cur; ci; ci = ci->next) {
+    if (nghttp2_buf_len(&ci->buf) == 0) {
+      return;
+    } else {
+      bufs->cur = ci;
+    }
+  }
+}
+
+size_t nghttp2_bufs_len(nghttp2_bufs *bufs) {
+  nghttp2_buf_chain *ci;
+  size_t len;
+
+  len = 0;
+  for (ci = bufs->head; ci; ci = ci->next) {
+    len += nghttp2_buf_len(&ci->buf);
+  }
+
+  return len;
+}
+
+static int bufs_alloc_chain(nghttp2_bufs *bufs) {
+  int rv;
+  nghttp2_buf_chain *chain;
+
+  if (bufs->cur->next) {
+    bufs->cur = bufs->cur->next;
+
+    return 0;
+  }
+
+  if (bufs->max_chunk == bufs->chunk_used) {
+    return NGHTTP2_ERR_BUFFER_ERROR;
+  }
+
+  rv = buf_chain_new(&chain, bufs->chunk_length, bufs->mem);
+  if (rv != 0) {
+    return rv;
+  }
+
+  DEBUGF("new buffer %zu bytes allocated for bufs %p, used %zu\n",
+         bufs->chunk_length, bufs, bufs->chunk_used);
+
+  ++bufs->chunk_used;
+
+  bufs->cur->next = chain;
+  bufs->cur = chain;
+
+  nghttp2_buf_shift_right(&bufs->cur->buf, bufs->offset);
+
+  return 0;
+}
+
+int nghttp2_bufs_add(nghttp2_bufs *bufs, const void *data, size_t len) {
+  int rv;
+  size_t nwrite;
+  nghttp2_buf *buf;
+  const uint8_t *p;
+
+  p = data;
+
+  while (len) {
+    buf = &bufs->cur->buf;
+
+    nwrite = nghttp2_min(nghttp2_buf_avail(buf), len);
+    if (nwrite == 0) {
+      rv = bufs_alloc_chain(bufs);
+      if (rv != 0) {
+        return rv;
+      }
+      continue;
+    }
+
+    buf->last = nghttp2_cpymem(buf->last, p, nwrite);
+    p += nwrite;
+    len -= nwrite;
+  }
+
+  return 0;
+}
+
+static int bufs_ensure_addb(nghttp2_bufs *bufs) {
+  int rv;
+  nghttp2_buf *buf;
+
+  buf = &bufs->cur->buf;
+
+  if (nghttp2_buf_avail(buf) > 0) {
+    return 0;
+  }
+
+  rv = bufs_alloc_chain(bufs);
+  if (rv != 0) {
+    return rv;
+  }
+
+  return 0;
+}
+
+int nghttp2_bufs_addb(nghttp2_bufs *bufs, uint8_t b) {
+  int rv;
+
+  rv = bufs_ensure_addb(bufs);
+  if (rv != 0) {
+    return rv;
+  }
+
+  *bufs->cur->buf.last++ = b;
+
+  return 0;
+}
+
+int nghttp2_bufs_addb_hold(nghttp2_bufs *bufs, uint8_t b) {
+  int rv;
+
+  rv = bufs_ensure_addb(bufs);
+  if (rv != 0) {
+    return rv;
+  }
+
+  *bufs->cur->buf.last = b;
+
+  return 0;
+}
+
+int nghttp2_bufs_orb(nghttp2_bufs *bufs, uint8_t b) {
+  int rv;
+
+  rv = bufs_ensure_addb(bufs);
+  if (rv != 0) {
+    return rv;
+  }
+
+  *bufs->cur->buf.last++ |= b;
+
+  return 0;
+}
+
+int nghttp2_bufs_orb_hold(nghttp2_bufs *bufs, uint8_t b) {
+  int rv;
+
+  rv = bufs_ensure_addb(bufs);
+  if (rv != 0) {
+    return rv;
+  }
+
+  *bufs->cur->buf.last |= b;
+
+  return 0;
+}
+
+ssize_t nghttp2_bufs_remove(nghttp2_bufs *bufs, uint8_t **out) {
+  size_t len;
+  nghttp2_buf_chain *chain;
+  nghttp2_buf *buf;
+  uint8_t *res;
+  nghttp2_buf resbuf;
+
+  len = 0;
+
+  for (chain = bufs->head; chain; chain = chain->next) {
+    len += nghttp2_buf_len(&chain->buf);
+  }
+
+  if (len == 0) {
+    res = NULL;
+    return 0;
+  }
+
+  res = nghttp2_mem_malloc(bufs->mem, len);
+  if (res == NULL) {
+    return NGHTTP2_ERR_NOMEM;
+  }
+
+  nghttp2_buf_wrap_init(&resbuf, res, len);
+
+  for (chain = bufs->head; chain; chain = chain->next) {
+    buf = &chain->buf;
+    resbuf.last = nghttp2_cpymem(resbuf.last, buf->pos, nghttp2_buf_len(buf));
+  }
+
+  *out = res;
+
+  return (ssize_t)len;
+}
+
+size_t nghttp2_bufs_remove_copy(nghttp2_bufs *bufs, uint8_t *out) {
+  size_t len;
+  nghttp2_buf_chain *chain;
+  nghttp2_buf *buf;
+  nghttp2_buf resbuf;
+
+  len = nghttp2_bufs_len(bufs);
+
+  nghttp2_buf_wrap_init(&resbuf, out, len);
+
+  for (chain = bufs->head; chain; chain = chain->next) {
+    buf = &chain->buf;
+    resbuf.last = nghttp2_cpymem(resbuf.last, buf->pos, nghttp2_buf_len(buf));
+  }
+
+  return len;
+}
+
+void nghttp2_bufs_reset(nghttp2_bufs *bufs) {
+  nghttp2_buf_chain *chain, *ci;
+  size_t k;
+
+  k = bufs->chunk_keep;
+
+  for (ci = bufs->head; ci; ci = ci->next) {
+    nghttp2_buf_reset(&ci->buf);
+    nghttp2_buf_shift_right(&ci->buf, bufs->offset);
+
+    if (--k == 0) {
+      break;
+    }
+  }
+
+  if (ci) {
+    chain = ci->next;
+    ci->next = NULL;
+
+    for (ci = chain; ci;) {
+      chain = ci->next;
+
+      buf_chain_del(ci, bufs->mem);
+
+      ci = chain;
+    }
+
+    bufs->chunk_used = bufs->chunk_keep;
+  }
+
+  bufs->cur = bufs->head;
+}
+
+int nghttp2_bufs_advance(nghttp2_bufs *bufs) { return bufs_alloc_chain(bufs); }
+
+int nghttp2_bufs_next_present(nghttp2_bufs *bufs) {
+  nghttp2_buf_chain *chain;
+
+  chain = bufs->cur->next;
+
+  return chain && nghttp2_buf_len(&chain->buf);
+}
diff --git a/Utilities/cmnghttp2/lib/nghttp2_buf.h b/Utilities/cmnghttp2/lib/nghttp2_buf.h
new file mode 100644
index 0000000..06cce67
--- /dev/null
+++ b/Utilities/cmnghttp2/lib/nghttp2_buf.h
@@ -0,0 +1,412 @@
+/*
+ * nghttp2 - HTTP/2 C Library
+ *
+ * Copyright (c) 2014 Tatsuhiro Tsujikawa
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+#ifndef NGHTTP2_BUF_H
+#define NGHTTP2_BUF_H
+
+#ifdef HAVE_CONFIG_H
+#  include <config.h>
+#endif /* HAVE_CONFIG_H */
+
+#include <nghttp2/nghttp2.h>
+
+#include "nghttp2_int.h"
+#include "nghttp2_mem.h"
+
+typedef struct {
+  /* This points to the beginning of the buffer. The effective range
+     of buffer is [begin, end). */
+  uint8_t *begin;
+  /* This points to the memory one byte beyond the end of the
+     buffer. */
+  uint8_t *end;
+  /* The position indicator for effective start of the buffer. pos <=
+     last must be hold. */
+  uint8_t *pos;
+  /* The position indicator for effective one beyond of the end of the
+     buffer. last <= end must be hold. */
+  uint8_t *last;
+  /* Mark arbitrary position in buffer [begin, end) */
+  uint8_t *mark;
+} nghttp2_buf;
+
+#define nghttp2_buf_len(BUF) ((size_t)((BUF)->last - (BUF)->pos))
+#define nghttp2_buf_avail(BUF) ((size_t)((BUF)->end - (BUF)->last))
+#define nghttp2_buf_mark_avail(BUF) ((size_t)((BUF)->mark - (BUF)->last))
+#define nghttp2_buf_cap(BUF) ((size_t)((BUF)->end - (BUF)->begin))
+
+#define nghttp2_buf_pos_offset(BUF) ((size_t)((BUF)->pos - (BUF)->begin))
+#define nghttp2_buf_last_offset(BUF) ((size_t)((BUF)->last - (BUF)->begin))
+
+#define nghttp2_buf_shift_right(BUF, AMT)                                      \
+  do {                                                                         \
+    (BUF)->pos += AMT;                                                         \
+    (BUF)->last += AMT;                                                        \
+  } while (0)
+
+#define nghttp2_buf_shift_left(BUF, AMT)                                       \
+  do {                                                                         \
+    (BUF)->pos -= AMT;                                                         \
+    (BUF)->last -= AMT;                                                        \
+  } while (0)
+
+/*
+ * Initializes the |buf|. No memory is allocated in this function. Use
+ * nghttp2_buf_reserve() to allocate memory.
+ */
+void nghttp2_buf_init(nghttp2_buf *buf);
+
+/*
+ * Initializes the |buf| and allocates at least |initial| bytes of
+ * memory.
+ *
+ * This function returns 0 if it succeeds, or one of the following
+ * negative error codes:
+ *
+ * NGHTTP2_ERR_NOMEM
+ *     Out of memory
+ */
+int nghttp2_buf_init2(nghttp2_buf *buf, size_t initial, nghttp2_mem *mem);
+
+/*
+ * Frees buffer in |buf|.
+ */
+void nghttp2_buf_free(nghttp2_buf *buf, nghttp2_mem *mem);
+
+/*
+ * Extends buffer so that nghttp2_buf_cap() returns at least
+ * |new_cap|. If extensions took place, buffer pointers in |buf| will
+ * change.
+ *
+ * This function returns 0 if it succeeds, or one of the followings
+ * negative error codes:
+ *
+ * NGHTTP2_ERR_NOMEM
+ *     Out of memory
+ */
+int nghttp2_buf_reserve(nghttp2_buf *buf, size_t new_cap, nghttp2_mem *mem);
+
+/*
+ * Resets pos, last, mark member of |buf| to buf->begin.
+ */
+void nghttp2_buf_reset(nghttp2_buf *buf);
+
+/*
+ * Initializes |buf| using supplied buffer |begin| of length
+ * |len|. Semantically, the application should not call *_reserve() or
+ * nghttp2_free() functions for |buf|.
+ */
+void nghttp2_buf_wrap_init(nghttp2_buf *buf, uint8_t *begin, size_t len);
+
+struct nghttp2_buf_chain;
+
+typedef struct nghttp2_buf_chain nghttp2_buf_chain;
+
+/* Chains 2 buffers */
+struct nghttp2_buf_chain {
+  /* Points to the subsequent buffer. NULL if there is no such
+     buffer. */
+  nghttp2_buf_chain *next;
+  nghttp2_buf buf;
+};
+
+typedef struct {
+  /* Points to the first buffer */
+  nghttp2_buf_chain *head;
+  /* Buffer pointer where write occurs. */
+  nghttp2_buf_chain *cur;
+  /* Memory allocator */
+  nghttp2_mem *mem;
+  /* The buffer capacity of each buf.  This field may be 0 if
+     nghttp2_bufs is initialized by nghttp2_bufs_wrap_init* family
+     functions. */
+  size_t chunk_length;
+  /* The maximum number of nghttp2_buf_chain */
+  size_t max_chunk;
+  /* The number of nghttp2_buf_chain allocated */
+  size_t chunk_used;
+  /* The number of nghttp2_buf_chain to keep on reset */
+  size_t chunk_keep;
+  /* pos offset from begin in each buffers. On initialization and
+     reset, buf->pos and buf->last are positioned at buf->begin +
+     offset. */
+  size_t offset;
+} nghttp2_bufs;
+
+/*
+ * This is the same as calling nghttp2_bufs_init2 with the given
+ * arguments and offset = 0.
+ */
+int nghttp2_bufs_init(nghttp2_bufs *bufs, size_t chunk_length, size_t max_chunk,
+                      nghttp2_mem *mem);
+
+/*
+ * This is the same as calling nghttp2_bufs_init3 with the given
+ * arguments and chunk_keep = max_chunk.
+ */
+int nghttp2_bufs_init2(nghttp2_bufs *bufs, size_t chunk_length,
+                       size_t max_chunk, size_t offset, nghttp2_mem *mem);
+
+/*
+ * Initializes |bufs|. Each buffer size is given in the
+ * |chunk_length|.  The maximum number of buffers is given in the
+ * |max_chunk|.  On reset, first |chunk_keep| buffers are kept and
+ * remaining buffers are deleted.  Each buffer will have bufs->pos and
+ * bufs->last shifted to left by |offset| bytes on creation and reset.
+ *
+ * This function allocates first buffer.  bufs->head and bufs->cur
+ * will point to the first buffer after this call.
+ *
+ * This function returns 0 if it succeeds, or one of the following
+ * negative error codes:
+ *
+ * NGHTTP2_ERR_NOMEM
+ *     Out of memory.
+ * NGHTTP2_ERR_INVALID_ARGUMENT
+ *     chunk_keep is 0; or max_chunk < chunk_keep; or offset is too
+ *     long.
+ */
+int nghttp2_bufs_init3(nghttp2_bufs *bufs, size_t chunk_length,
+                       size_t max_chunk, size_t chunk_keep, size_t offset,
+                       nghttp2_mem *mem);
+
+/*
+ * Frees any related resources to the |bufs|.
+ */
+void nghttp2_bufs_free(nghttp2_bufs *bufs);
+
+/*
+ * Initializes |bufs| using supplied buffer |begin| of length |len|.
+ * The first buffer bufs->head uses buffer |begin|.  The buffer size
+ * is fixed and no extra chunk buffer is allocated.  In other
+ * words, max_chunk = chunk_keep = 1.  To free the resource allocated
+ * for |bufs|, use nghttp2_bufs_wrap_free().
+ *
+ * Don't use the function which performs allocation, such as
+ * nghttp2_bufs_realloc().
+ *
+ * This function returns 0 if it succeeds, or one of the following
+ * negative error codes:
+ *
+ * NGHTTP2_ERR_NOMEM
+ *     Out of memory.
+ */
+int nghttp2_bufs_wrap_init(nghttp2_bufs *bufs, uint8_t *begin, size_t len,
+                           nghttp2_mem *mem);
+
+/*
+ * Initializes |bufs| using supplied |veclen| size of buf vector
+ * |vec|.  The number of buffers is fixed and no extra chunk buffer is
+ * allocated.  In other words, max_chunk = chunk_keep = |in_len|.  To
+ * free the resource allocated for |bufs|, use
+ * nghttp2_bufs_wrap_free().
+ *
+ * Don't use the function which performs allocation, such as
+ * nghttp2_bufs_realloc().
+ *
+ * This function returns 0 if it succeeds, or one of the following
+ * negative error codes:
+ *
+ * NGHTTP2_ERR_NOMEM
+ *     Out of memory.
+ */
+int nghttp2_bufs_wrap_init2(nghttp2_bufs *bufs, const nghttp2_vec *vec,
+                            size_t veclen, nghttp2_mem *mem);
+
+/*
+ * Frees any related resource to the |bufs|.  This function does not
+ * free supplied buffer provided in nghttp2_bufs_wrap_init().
+ */
+void nghttp2_bufs_wrap_free(nghttp2_bufs *bufs);
+
+/*
+ * Reallocates internal buffer using |chunk_length|.  The max_chunk,
+ * chunk_keep and offset do not change.  After successful allocation
+ * of new buffer, previous buffers are deallocated without copying
+ * anything into new buffers.  chunk_used is reset to 1.
+ *
+ * This function returns 0 if it succeeds, or one of the following
+ * negative error codes:
+ *
+ * NGHTTP2_ERR_NOMEM
+ *     Out of memory.
+ * NGHTTP2_ERR_INVALID_ARGUMENT
+ *     chunk_length < offset
+ */
+int nghttp2_bufs_realloc(nghttp2_bufs *bufs, size_t chunk_length);
+
+/*
+ * Appends the |data| of length |len| to the |bufs|. The write starts
+ * at bufs->cur->buf.last. A new buffers will be allocated to store
+ * all data.
+ *
+ * This function returns 0 if it succeeds, or one of the following
+ * negative error codes:
+ *
+ * NGHTTP2_ERR_NOMEM
+ *     Out of memory.
+ * NGHTTP2_ERR_BUFFER_ERROR
+ *     Out of buffer space.
+ */
+int nghttp2_bufs_add(nghttp2_bufs *bufs, const void *data, size_t len);
+
+/*
+ * Appends a single byte |b| to the |bufs|. The write starts at
+ * bufs->cur->buf.last. A new buffers will be allocated to store all
+ * data.
+ *
+ * This function returns 0 if it succeeds, or one of the following
+ * negative error codes:
+ *
+ * NGHTTP2_ERR_NOMEM
+ *     Out of memory.
+ * NGHTTP2_ERR_BUFFER_ERROR
+ *     Out of buffer space.
+ */
+int nghttp2_bufs_addb(nghttp2_bufs *bufs, uint8_t b);
+
+/*
+ * Behaves like nghttp2_bufs_addb(), but this does not update
+ * buf->last pointer.
+ */
+int nghttp2_bufs_addb_hold(nghttp2_bufs *bufs, uint8_t b);
+
+#define nghttp2_bufs_fast_addb(BUFS, B)                                        \
+  do {                                                                         \
+    *(BUFS)->cur->buf.last++ = B;                                              \
+  } while (0)
+
+#define nghttp2_bufs_fast_addb_hold(BUFS, B)                                   \
+  do {                                                                         \
+    *(BUFS)->cur->buf.last = B;                                                \
+  } while (0)
+
+/*
+ * Performs bitwise-OR of |b| at bufs->cur->buf.last. A new buffers
+ * will be allocated if necessary.
+ *
+ * This function returns 0 if it succeeds, or one of the following
+ * negative error codes:
+ *
+ * NGHTTP2_ERR_NOMEM
+ *     Out of memory.
+ * NGHTTP2_ERR_BUFFER_ERROR
+ *     Out of buffer space.
+ */
+int nghttp2_bufs_orb(nghttp2_bufs *bufs, uint8_t b);
+
+/*
+ * Behaves like nghttp2_bufs_orb(), but does not update buf->last
+ * pointer.
+ */
+int nghttp2_bufs_orb_hold(nghttp2_bufs *bufs, uint8_t b);
+
+#define nghttp2_bufs_fast_orb(BUFS, B)                                         \
+  do {                                                                         \
+    uint8_t **p = &(BUFS)->cur->buf.last;                                      \
+    **p = (uint8_t)(**p | (B));                                                \
+    ++(*p);                                                                    \
+  } while (0)
+
+#define nghttp2_bufs_fast_orb_hold(BUFS, B)                                    \
+  do {                                                                         \
+    uint8_t *p = (BUFS)->cur->buf.last;                                        \
+    *p = (uint8_t)(*p | (B));                                                  \
+  } while (0)
+
+/*
+ * Copies all data stored in |bufs| to the contiguous buffer.  This
+ * function allocates the contiguous memory to store all data in
+ * |bufs| and assigns it to |*out|.
+ *
+ * The contents of |bufs| is left unchanged.
+ *
+ * This function returns the length of copied data and assigns the
+ * pointer to copied data to |*out| if it succeeds, or one of the
+ * following negative error codes:
+ *
+ * NGHTTP2_ERR_NOMEM
+ *     Out of memory
+ */
+ssize_t nghttp2_bufs_remove(nghttp2_bufs *bufs, uint8_t **out);
+
+/*
+ * Copies all data stored in |bufs| to |out|.  This function assumes
+ * that the buffer space pointed by |out| has at least
+ * nghttp2_bufs(bufs) bytes.
+ *
+ * The contents of |bufs| is left unchanged.
+ *
+ * This function returns the length of copied data.
+ */
+size_t nghttp2_bufs_remove_copy(nghttp2_bufs *bufs, uint8_t *out);
+
+/*
+ * Resets |bufs| and makes the buffers empty.
+ */
+void nghttp2_bufs_reset(nghttp2_bufs *bufs);
+
+/*
+ * Moves bufs->cur to bufs->cur->next.  If resulting bufs->cur is
+ * NULL, this function allocates new buffers and bufs->cur points to
+ * it.
+ *
+ * This function returns 0 if it succeeds, or one of the following
+ * negative error codes:
+ *
+ * NGHTTP2_ERR_NOMEM
+ *     Out of memory
+ * NGHTTP2_ERR_BUFFER_ERROR
+ *     Out of buffer space.
+ */
+int nghttp2_bufs_advance(nghttp2_bufs *bufs);
+
+/* Sets bufs->cur to bufs->head */
+#define nghttp2_bufs_rewind(BUFS)                                              \
+  do {                                                                         \
+    (BUFS)->cur = (BUFS)->head;                                                \
+  } while (0)
+
+/*
+ * Move bufs->cur, from the current position, using next member, to
+ * the last buf which has nghttp2_buf_len(buf) > 0 without seeing buf
+ * which satisfies nghttp2_buf_len(buf) == 0.  If
+ * nghttp2_buf_len(&bufs->cur->buf) == 0 or bufs->cur->next is NULL,
+ * bufs->cur is unchanged.
+ */
+void nghttp2_bufs_seek_last_present(nghttp2_bufs *bufs);
+
+/*
+ * Returns nonzero if bufs->cur->next is not empty.
+ */
+int nghttp2_bufs_next_present(nghttp2_bufs *bufs);
+
+#define nghttp2_bufs_cur_avail(BUFS) nghttp2_buf_avail(&(BUFS)->cur->buf)
+
+/*
+ * Returns the total buffer length of |bufs|.
+ */
+size_t nghttp2_bufs_len(nghttp2_bufs *bufs);
+
+#endif /* NGHTTP2_BUF_H */
diff --git a/Utilities/cmnghttp2/lib/nghttp2_callbacks.c b/Utilities/cmnghttp2/lib/nghttp2_callbacks.c
new file mode 100644
index 0000000..3c38214
--- /dev/null
+++ b/Utilities/cmnghttp2/lib/nghttp2_callbacks.c
@@ -0,0 +1,175 @@
+/*
+ * nghttp2 - HTTP/2 C Library
+ *
+ * Copyright (c) 2014 Tatsuhiro Tsujikawa
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+#include "nghttp2_callbacks.h"
+
+#include <stdlib.h>
+
+int nghttp2_session_callbacks_new(nghttp2_session_callbacks **callbacks_ptr) {
+  *callbacks_ptr = calloc(1, sizeof(nghttp2_session_callbacks));
+
+  if (*callbacks_ptr == NULL) {
+    return NGHTTP2_ERR_NOMEM;
+  }
+
+  return 0;
+}
+
+void nghttp2_session_callbacks_del(nghttp2_session_callbacks *callbacks) {
+  free(callbacks);
+}
+
+void nghttp2_session_callbacks_set_send_callback(
+    nghttp2_session_callbacks *cbs, nghttp2_send_callback send_callback) {
+  cbs->send_callback = send_callback;
+}
+
+void nghttp2_session_callbacks_set_recv_callback(
+    nghttp2_session_callbacks *cbs, nghttp2_recv_callback recv_callback) {
+  cbs->recv_callback = recv_callback;
+}
+
+void nghttp2_session_callbacks_set_on_frame_recv_callback(
+    nghttp2_session_callbacks *cbs,
+    nghttp2_on_frame_recv_callback on_frame_recv_callback) {
+  cbs->on_frame_recv_callback = on_frame_recv_callback;
+}
+
+void nghttp2_session_callbacks_set_on_invalid_frame_recv_callback(
+    nghttp2_session_callbacks *cbs,
+    nghttp2_on_invalid_frame_recv_callback on_invalid_frame_recv_callback) {
+  cbs->on_invalid_frame_recv_callback = on_invalid_frame_recv_callback;
+}
+
+void nghttp2_session_callbacks_set_on_data_chunk_recv_callback(
+    nghttp2_session_callbacks *cbs,
+    nghttp2_on_data_chunk_recv_callback on_data_chunk_recv_callback) {
+  cbs->on_data_chunk_recv_callback = on_data_chunk_recv_callback;
+}
+
+void nghttp2_session_callbacks_set_before_frame_send_callback(
+    nghttp2_session_callbacks *cbs,
+    nghttp2_before_frame_send_callback before_frame_send_callback) {
+  cbs->before_frame_send_callback = before_frame_send_callback;
+}
+
+void nghttp2_session_callbacks_set_on_frame_send_callback(
+    nghttp2_session_callbacks *cbs,
+    nghttp2_on_frame_send_callback on_frame_send_callback) {
+  cbs->on_frame_send_callback = on_frame_send_callback;
+}
+
+void nghttp2_session_callbacks_set_on_frame_not_send_callback(
+    nghttp2_session_callbacks *cbs,
+    nghttp2_on_frame_not_send_callback on_frame_not_send_callback) {
+  cbs->on_frame_not_send_callback = on_frame_not_send_callback;
+}
+
+void nghttp2_session_callbacks_set_on_stream_close_callback(
+    nghttp2_session_callbacks *cbs,
+    nghttp2_on_stream_close_callback on_stream_close_callback) {
+  cbs->on_stream_close_callback = on_stream_close_callback;
+}
+
+void nghttp2_session_callbacks_set_on_begin_headers_callback(
+    nghttp2_session_callbacks *cbs,
+    nghttp2_on_begin_headers_callback on_begin_headers_callback) {
+  cbs->on_begin_headers_callback = on_begin_headers_callback;
+}
+
+void nghttp2_session_callbacks_set_on_header_callback(
+    nghttp2_session_callbacks *cbs,
+    nghttp2_on_header_callback on_header_callback) {
+  cbs->on_header_callback = on_header_callback;
+}
+
+void nghttp2_session_callbacks_set_on_header_callback2(
+    nghttp2_session_callbacks *cbs,
+    nghttp2_on_header_callback2 on_header_callback2) {
+  cbs->on_header_callback2 = on_header_callback2;
+}
+
+void nghttp2_session_callbacks_set_on_invalid_header_callback(
+    nghttp2_session_callbacks *cbs,
+    nghttp2_on_invalid_header_callback on_invalid_header_callback) {
+  cbs->on_invalid_header_callback = on_invalid_header_callback;
+}
+
+void nghttp2_session_callbacks_set_on_invalid_header_callback2(
+    nghttp2_session_callbacks *cbs,
+    nghttp2_on_invalid_header_callback2 on_invalid_header_callback2) {
+  cbs->on_invalid_header_callback2 = on_invalid_header_callback2;
+}
+
+void nghttp2_session_callbacks_set_select_padding_callback(
+    nghttp2_session_callbacks *cbs,
+    nghttp2_select_padding_callback select_padding_callback) {
+  cbs->select_padding_callback = select_padding_callback;
+}
+
+void nghttp2_session_callbacks_set_data_source_read_length_callback(
+    nghttp2_session_callbacks *cbs,
+    nghttp2_data_source_read_length_callback data_source_read_length_callback) {
+  cbs->read_length_callback = data_source_read_length_callback;
+}
+
+void nghttp2_session_callbacks_set_on_begin_frame_callback(
+    nghttp2_session_callbacks *cbs,
+    nghttp2_on_begin_frame_callback on_begin_frame_callback) {
+  cbs->on_begin_frame_callback = on_begin_frame_callback;
+}
+
+void nghttp2_session_callbacks_set_send_data_callback(
+    nghttp2_session_callbacks *cbs,
+    nghttp2_send_data_callback send_data_callback) {
+  cbs->send_data_callback = send_data_callback;
+}
+
+void nghttp2_session_callbacks_set_pack_extension_callback(
+    nghttp2_session_callbacks *cbs,
+    nghttp2_pack_extension_callback pack_extension_callback) {
+  cbs->pack_extension_callback = pack_extension_callback;
+}
+
+void nghttp2_session_callbacks_set_unpack_extension_callback(
+    nghttp2_session_callbacks *cbs,
+    nghttp2_unpack_extension_callback unpack_extension_callback) {
+  cbs->unpack_extension_callback = unpack_extension_callback;
+}
+
+void nghttp2_session_callbacks_set_on_extension_chunk_recv_callback(
+    nghttp2_session_callbacks *cbs,
+    nghttp2_on_extension_chunk_recv_callback on_extension_chunk_recv_callback) {
+  cbs->on_extension_chunk_recv_callback = on_extension_chunk_recv_callback;
+}
+
+void nghttp2_session_callbacks_set_error_callback(
+    nghttp2_session_callbacks *cbs, nghttp2_error_callback error_callback) {
+  cbs->error_callback = error_callback;
+}
+
+void nghttp2_session_callbacks_set_error_callback2(
+    nghttp2_session_callbacks *cbs, nghttp2_error_callback2 error_callback2) {
+  cbs->error_callback2 = error_callback2;
+}
diff --git a/Utilities/cmnghttp2/lib/nghttp2_callbacks.h b/Utilities/cmnghttp2/lib/nghttp2_callbacks.h
new file mode 100644
index 0000000..61e51fa
--- /dev/null
+++ b/Utilities/cmnghttp2/lib/nghttp2_callbacks.h
@@ -0,0 +1,125 @@
+/*
+ * nghttp2 - HTTP/2 C Library
+ *
+ * Copyright (c) 2014 Tatsuhiro Tsujikawa
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+#ifndef NGHTTP2_CALLBACKS_H
+#define NGHTTP2_CALLBACKS_H
+
+#ifdef HAVE_CONFIG_H
+#  include <config.h>
+#endif /* HAVE_CONFIG_H */
+
+#include <nghttp2/nghttp2.h>
+
+/*
+ * Callback functions.
+ */
+struct nghttp2_session_callbacks {
+  /**
+   * Callback function invoked when the session wants to send data to
+   * the remote peer.  This callback is not necessary if the
+   * application uses solely `nghttp2_session_mem_send()` to serialize
+   * data to transmit.
+   */
+  nghttp2_send_callback send_callback;
+  /**
+   * Callback function invoked when the session wants to receive data
+   * from the remote peer.  This callback is not necessary if the
+   * application uses solely `nghttp2_session_mem_recv()` to process
+   * received data.
+   */
+  nghttp2_recv_callback recv_callback;
+  /**
+   * Callback function invoked by `nghttp2_session_recv()` when a
+   * frame is received.
+   */
+  nghttp2_on_frame_recv_callback on_frame_recv_callback;
+  /**
+   * Callback function invoked by `nghttp2_session_recv()` when an
+   * invalid non-DATA frame is received.
+   */
+  nghttp2_on_invalid_frame_recv_callback on_invalid_frame_recv_callback;
+  /**
+   * Callback function invoked when a chunk of data in DATA frame is
+   * received.
+   */
+  nghttp2_on_data_chunk_recv_callback on_data_chunk_recv_callback;
+  /**
+   * Callback function invoked before a non-DATA frame is sent.
+   */
+  nghttp2_before_frame_send_callback before_frame_send_callback;
+  /**
+   * Callback function invoked after a frame is sent.
+   */
+  nghttp2_on_frame_send_callback on_frame_send_callback;
+  /**
+   * The callback function invoked when a non-DATA frame is not sent
+   * because of an error.
+   */
+  nghttp2_on_frame_not_send_callback on_frame_not_send_callback;
+  /**
+   * Callback function invoked when the stream is closed.
+   */
+  nghttp2_on_stream_close_callback on_stream_close_callback;
+  /**
+   * Callback function invoked when the reception of header block in
+   * HEADERS or PUSH_PROMISE is started.
+   */
+  nghttp2_on_begin_headers_callback on_begin_headers_callback;
+  /**
+   * Callback function invoked when a header name/value pair is
+   * received.
+   */
+  nghttp2_on_header_callback on_header_callback;
+  nghttp2_on_header_callback2 on_header_callback2;
+  /**
+   * Callback function invoked when a invalid header name/value pair
+   * is received which is silently ignored if these callbacks are not
+   * set.
+   */
+  nghttp2_on_invalid_header_callback on_invalid_header_callback;
+  nghttp2_on_invalid_header_callback2 on_invalid_header_callback2;
+  /**
+   * Callback function invoked when the library asks application how
+   * many padding bytes are required for the transmission of the given
+   * frame.
+   */
+  nghttp2_select_padding_callback select_padding_callback;
+  /**
+   * The callback function used to determine the length allowed in
+   * `nghttp2_data_source_read_callback()`
+   */
+  nghttp2_data_source_read_length_callback read_length_callback;
+  /**
+   * Sets callback function invoked when a frame header is received.
+   */
+  nghttp2_on_begin_frame_callback on_begin_frame_callback;
+  nghttp2_send_data_callback send_data_callback;
+  nghttp2_pack_extension_callback pack_extension_callback;
+  nghttp2_unpack_extension_callback unpack_extension_callback;
+  nghttp2_on_extension_chunk_recv_callback on_extension_chunk_recv_callback;
+  nghttp2_error_callback error_callback;
+  nghttp2_error_callback2 error_callback2;
+};
+
+#endif /* NGHTTP2_CALLBACKS_H */
diff --git a/Utilities/cmnghttp2/lib/nghttp2_debug.c b/Utilities/cmnghttp2/lib/nghttp2_debug.c
new file mode 100644
index 0000000..cb27797
--- /dev/null
+++ b/Utilities/cmnghttp2/lib/nghttp2_debug.c
@@ -0,0 +1,60 @@
+/*
+ * nghttp2 - HTTP/2 C Library
+ *
+ * Copyright (c) 2016 Tatsuhiro Tsujikawa
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+#include "nghttp2_debug.h"
+
+#include <stdio.h>
+
+#ifdef DEBUGBUILD
+
+static void nghttp2_default_debug_vfprintf_callback(const char *fmt,
+                                                    va_list args) {
+  vfprintf(stderr, fmt, args);
+}
+
+static nghttp2_debug_vprintf_callback static_debug_vprintf_callback =
+    nghttp2_default_debug_vfprintf_callback;
+
+void nghttp2_debug_vprintf(const char *format, ...) {
+  if (static_debug_vprintf_callback) {
+    va_list args;
+    va_start(args, format);
+    static_debug_vprintf_callback(format, args);
+    va_end(args);
+  }
+}
+
+void nghttp2_set_debug_vprintf_callback(
+    nghttp2_debug_vprintf_callback debug_vprintf_callback) {
+  static_debug_vprintf_callback = debug_vprintf_callback;
+}
+
+#else /* !DEBUGBUILD */
+
+void nghttp2_set_debug_vprintf_callback(
+    nghttp2_debug_vprintf_callback debug_vprintf_callback) {
+  (void)debug_vprintf_callback;
+}
+
+#endif /* !DEBUGBUILD */
diff --git a/Utilities/cmnghttp2/lib/nghttp2_debug.h b/Utilities/cmnghttp2/lib/nghttp2_debug.h
new file mode 100644
index 0000000..cbb4dd5
--- /dev/null
+++ b/Utilities/cmnghttp2/lib/nghttp2_debug.h
@@ -0,0 +1,43 @@
+/*
+ * nghttp2 - HTTP/2 C Library
+ *
+ * Copyright (c) 2016 Tatsuhiro Tsujikawa
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+#ifndef NGHTTP2_DEBUG_H
+#define NGHTTP2_DEBUG_H
+
+#ifdef HAVE_CONFIG_H
+#  include <config.h>
+#endif /* HAVE_CONFIG_H */
+
+#include <nghttp2/nghttp2.h>
+
+#ifdef DEBUGBUILD
+#  define DEBUGF(...) nghttp2_debug_vprintf(__VA_ARGS__)
+void nghttp2_debug_vprintf(const char *format, ...);
+#else
+#  define DEBUGF(...)                                                          \
+    do {                                                                       \
+    } while (0)
+#endif
+
+#endif /* NGHTTP2_DEBUG_H */
diff --git a/Utilities/cmnghttp2/lib/nghttp2_frame.c b/Utilities/cmnghttp2/lib/nghttp2_frame.c
new file mode 100644
index 0000000..4821de4
--- /dev/null
+++ b/Utilities/cmnghttp2/lib/nghttp2_frame.c
@@ -0,0 +1,1134 @@
+/*
+ * nghttp2 - HTTP/2 C Library
+ *
+ * Copyright (c) 2013 Tatsuhiro Tsujikawa
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+#include "nghttp2_frame.h"
+
+#include <string.h>
+#include <assert.h>
+#include <stdio.h>
+#include <errno.h>
+
+#include "nghttp2_helper.h"
+#include "nghttp2_net.h"
+#include "nghttp2_priority_spec.h"
+#include "nghttp2_debug.h"
+
+void nghttp2_frame_pack_frame_hd(uint8_t *buf, const nghttp2_frame_hd *hd) {
+  nghttp2_put_uint32be(&buf[0], (uint32_t)(hd->length << 8));
+  buf[3] = hd->type;
+  buf[4] = hd->flags;
+  nghttp2_put_uint32be(&buf[5], (uint32_t)hd->stream_id);
+  /* ignore hd->reserved for now */
+}
+
+void nghttp2_frame_unpack_frame_hd(nghttp2_frame_hd *hd, const uint8_t *buf) {
+  hd->length = nghttp2_get_uint32(&buf[0]) >> 8;
+  hd->type = buf[3];
+  hd->flags = buf[4];
+  hd->stream_id = nghttp2_get_uint32(&buf[5]) & NGHTTP2_STREAM_ID_MASK;
+  hd->reserved = 0;
+}
+
+void nghttp2_frame_hd_init(nghttp2_frame_hd *hd, size_t length, uint8_t type,
+                           uint8_t flags, int32_t stream_id) {
+  hd->length = length;
+  hd->type = type;
+  hd->flags = flags;
+  hd->stream_id = stream_id;
+  hd->reserved = 0;
+}
+
+void nghttp2_frame_headers_init(nghttp2_headers *frame, uint8_t flags,
+                                int32_t stream_id, nghttp2_headers_category cat,
+                                const nghttp2_priority_spec *pri_spec,
+                                nghttp2_nv *nva, size_t nvlen) {
+  nghttp2_frame_hd_init(&frame->hd, 0, NGHTTP2_HEADERS, flags, stream_id);
+  frame->padlen = 0;
+  frame->nva = nva;
+  frame->nvlen = nvlen;
+  frame->cat = cat;
+
+  if (pri_spec) {
+    frame->pri_spec = *pri_spec;
+  } else {
+    nghttp2_priority_spec_default_init(&frame->pri_spec);
+  }
+}
+
+void nghttp2_frame_headers_free(nghttp2_headers *frame, nghttp2_mem *mem) {
+  nghttp2_nv_array_del(frame->nva, mem);
+}
+
+void nghttp2_frame_priority_init(nghttp2_priority *frame, int32_t stream_id,
+                                 const nghttp2_priority_spec *pri_spec) {
+  nghttp2_frame_hd_init(&frame->hd, NGHTTP2_PRIORITY_SPECLEN, NGHTTP2_PRIORITY,
+                        NGHTTP2_FLAG_NONE, stream_id);
+  frame->pri_spec = *pri_spec;
+}
+
+void nghttp2_frame_priority_free(nghttp2_priority *frame) { (void)frame; }
+
+void nghttp2_frame_rst_stream_init(nghttp2_rst_stream *frame, int32_t stream_id,
+                                   uint32_t error_code) {
+  nghttp2_frame_hd_init(&frame->hd, 4, NGHTTP2_RST_STREAM, NGHTTP2_FLAG_NONE,
+                        stream_id);
+  frame->error_code = error_code;
+}
+
+void nghttp2_frame_rst_stream_free(nghttp2_rst_stream *frame) { (void)frame; }
+
+void nghttp2_frame_settings_init(nghttp2_settings *frame, uint8_t flags,
+                                 nghttp2_settings_entry *iv, size_t niv) {
+  nghttp2_frame_hd_init(&frame->hd, niv * NGHTTP2_FRAME_SETTINGS_ENTRY_LENGTH,
+                        NGHTTP2_SETTINGS, flags, 0);
+  frame->niv = niv;
+  frame->iv = iv;
+}
+
+void nghttp2_frame_settings_free(nghttp2_settings *frame, nghttp2_mem *mem) {
+  nghttp2_mem_free(mem, frame->iv);
+}
+
+void nghttp2_frame_push_promise_init(nghttp2_push_promise *frame, uint8_t flags,
+                                     int32_t stream_id,
+                                     int32_t promised_stream_id,
+                                     nghttp2_nv *nva, size_t nvlen) {
+  nghttp2_frame_hd_init(&frame->hd, 0, NGHTTP2_PUSH_PROMISE, flags, stream_id);
+  frame->padlen = 0;
+  frame->nva = nva;
+  frame->nvlen = nvlen;
+  frame->promised_stream_id = promised_stream_id;
+  frame->reserved = 0;
+}
+
+void nghttp2_frame_push_promise_free(nghttp2_push_promise *frame,
+                                     nghttp2_mem *mem) {
+  nghttp2_nv_array_del(frame->nva, mem);
+}
+
+void nghttp2_frame_ping_init(nghttp2_ping *frame, uint8_t flags,
+                             const uint8_t *opaque_data) {
+  nghttp2_frame_hd_init(&frame->hd, 8, NGHTTP2_PING, flags, 0);
+  if (opaque_data) {
+    memcpy(frame->opaque_data, opaque_data, sizeof(frame->opaque_data));
+  } else {
+    memset(frame->opaque_data, 0, sizeof(frame->opaque_data));
+  }
+}
+
+void nghttp2_frame_ping_free(nghttp2_ping *frame) { (void)frame; }
+
+void nghttp2_frame_goaway_init(nghttp2_goaway *frame, int32_t last_stream_id,
+                               uint32_t error_code, uint8_t *opaque_data,
+                               size_t opaque_data_len) {
+  nghttp2_frame_hd_init(&frame->hd, 8 + opaque_data_len, NGHTTP2_GOAWAY,
+                        NGHTTP2_FLAG_NONE, 0);
+  frame->last_stream_id = last_stream_id;
+  frame->error_code = error_code;
+  frame->opaque_data = opaque_data;
+  frame->opaque_data_len = opaque_data_len;
+  frame->reserved = 0;
+}
+
+void nghttp2_frame_goaway_free(nghttp2_goaway *frame, nghttp2_mem *mem) {
+  nghttp2_mem_free(mem, frame->opaque_data);
+}
+
+void nghttp2_frame_window_update_init(nghttp2_window_update *frame,
+                                      uint8_t flags, int32_t stream_id,
+                                      int32_t window_size_increment) {
+  nghttp2_frame_hd_init(&frame->hd, 4, NGHTTP2_WINDOW_UPDATE, flags, stream_id);
+  frame->window_size_increment = window_size_increment;
+  frame->reserved = 0;
+}
+
+void nghttp2_frame_window_update_free(nghttp2_window_update *frame) {
+  (void)frame;
+}
+
+size_t nghttp2_frame_trail_padlen(nghttp2_frame *frame, size_t padlen) {
+  /* We have iframe->padlen == 0, but iframe->frame.hd.flags may have
+     NGHTTP2_FLAG_PADDED set.  This happens when receiving
+     CONTINUATION frame, since we don't reset flags after HEADERS was
+     received. */
+  if (padlen == 0) {
+    return 0;
+  }
+  return padlen - ((frame->hd.flags & NGHTTP2_FLAG_PADDED) > 0);
+}
+
+void nghttp2_frame_data_init(nghttp2_data *frame, uint8_t flags,
+                             int32_t stream_id) {
+  /* At this moment, the length of DATA frame is unknown */
+  nghttp2_frame_hd_init(&frame->hd, 0, NGHTTP2_DATA, flags, stream_id);
+  frame->padlen = 0;
+}
+
+void nghttp2_frame_data_free(nghttp2_data *frame) { (void)frame; }
+
+void nghttp2_frame_extension_init(nghttp2_extension *frame, uint8_t type,
+                                  uint8_t flags, int32_t stream_id,
+                                  void *payload) {
+  nghttp2_frame_hd_init(&frame->hd, 0, type, flags, stream_id);
+  frame->payload = payload;
+}
+
+void nghttp2_frame_extension_free(nghttp2_extension *frame) { (void)frame; }
+
+void nghttp2_frame_altsvc_init(nghttp2_extension *frame, int32_t stream_id,
+                               uint8_t *origin, size_t origin_len,
+                               uint8_t *field_value, size_t field_value_len) {
+  nghttp2_ext_altsvc *altsvc;
+
+  nghttp2_frame_hd_init(&frame->hd, 2 + origin_len + field_value_len,
+                        NGHTTP2_ALTSVC, NGHTTP2_FLAG_NONE, stream_id);
+
+  altsvc = frame->payload;
+  altsvc->origin = origin;
+  altsvc->origin_len = origin_len;
+  altsvc->field_value = field_value;
+  altsvc->field_value_len = field_value_len;
+}
+
+void nghttp2_frame_altsvc_free(nghttp2_extension *frame, nghttp2_mem *mem) {
+  nghttp2_ext_altsvc *altsvc;
+
+  altsvc = frame->payload;
+  if (altsvc == NULL) {
+    return;
+  }
+  /* We use the same buffer for altsvc->origin and
+     altsvc->field_value. */
+  nghttp2_mem_free(mem, altsvc->origin);
+}
+
+void nghttp2_frame_origin_init(nghttp2_extension *frame,
+                               nghttp2_origin_entry *ov, size_t nov) {
+  nghttp2_ext_origin *origin;
+  size_t payloadlen = 0;
+  size_t i;
+
+  for (i = 0; i < nov; ++i) {
+    payloadlen += 2 + ov[i].origin_len;
+  }
+
+  nghttp2_frame_hd_init(&frame->hd, payloadlen, NGHTTP2_ORIGIN,
+                        NGHTTP2_FLAG_NONE, 0);
+
+  origin = frame->payload;
+  origin->ov = ov;
+  origin->nov = nov;
+}
+
+void nghttp2_frame_origin_free(nghttp2_extension *frame, nghttp2_mem *mem) {
+  nghttp2_ext_origin *origin;
+
+  origin = frame->payload;
+  if (origin == NULL) {
+    return;
+  }
+  /* We use the same buffer for all resources pointed by the field of
+     origin directly or indirectly. */
+  nghttp2_mem_free(mem, origin->ov);
+}
+
+size_t nghttp2_frame_priority_len(uint8_t flags) {
+  if (flags & NGHTTP2_FLAG_PRIORITY) {
+    return NGHTTP2_PRIORITY_SPECLEN;
+  }
+
+  return 0;
+}
+
+size_t nghttp2_frame_headers_payload_nv_offset(nghttp2_headers *frame) {
+  return nghttp2_frame_priority_len(frame->hd.flags);
+}
+
+/*
+ * Call this function after payload was serialized, but not before
+ * changing buf->pos and serializing frame header.
+ *
+ * This function assumes bufs->cur points to the last buf chain of the
+ * frame(s).
+ *
+ * This function serializes frame header for HEADERS/PUSH_PROMISE and
+ * handles their successive CONTINUATION frames.
+ *
+ * We don't process any padding here.
+ */
+static int frame_pack_headers_shared(nghttp2_bufs *bufs,
+                                     nghttp2_frame_hd *frame_hd) {
+  nghttp2_buf *buf;
+  nghttp2_buf_chain *ci, *ce;
+  nghttp2_frame_hd hd;
+
+  buf = &bufs->head->buf;
+
+  hd = *frame_hd;
+  hd.length = nghttp2_buf_len(buf);
+
+  DEBUGF("send: HEADERS/PUSH_PROMISE, payloadlen=%zu\n", hd.length);
+
+  /* We have multiple frame buffers, which means one or more
+     CONTINUATION frame is involved. Remove END_HEADERS flag from the
+     first frame. */
+  if (bufs->head != bufs->cur) {
+    hd.flags = (uint8_t)(hd.flags & ~NGHTTP2_FLAG_END_HEADERS);
+  }
+
+  buf->pos -= NGHTTP2_FRAME_HDLEN;
+  nghttp2_frame_pack_frame_hd(buf->pos, &hd);
+
+  if (bufs->head != bufs->cur) {
+    /* 2nd and later frames are CONTINUATION frames. */
+    hd.type = NGHTTP2_CONTINUATION;
+    /* We don't have no flags except for last CONTINUATION */
+    hd.flags = NGHTTP2_FLAG_NONE;
+
+    ce = bufs->cur;
+
+    for (ci = bufs->head->next; ci != ce; ci = ci->next) {
+      buf = &ci->buf;
+
+      hd.length = nghttp2_buf_len(buf);
+
+      DEBUGF("send: int CONTINUATION, payloadlen=%zu\n", hd.length);
+
+      buf->pos -= NGHTTP2_FRAME_HDLEN;
+      nghttp2_frame_pack_frame_hd(buf->pos, &hd);
+    }
+
+    buf = &ci->buf;
+    hd.length = nghttp2_buf_len(buf);
+    /* Set END_HEADERS flag for last CONTINUATION */
+    hd.flags = NGHTTP2_FLAG_END_HEADERS;
+
+    DEBUGF("send: last CONTINUATION, payloadlen=%zu\n", hd.length);
+
+    buf->pos -= NGHTTP2_FRAME_HDLEN;
+    nghttp2_frame_pack_frame_hd(buf->pos, &hd);
+  }
+
+  return 0;
+}
+
+int nghttp2_frame_pack_headers(nghttp2_bufs *bufs, nghttp2_headers *frame,
+                               nghttp2_hd_deflater *deflater) {
+  size_t nv_offset;
+  int rv;
+  nghttp2_buf *buf;
+
+  assert(bufs->head == bufs->cur);
+
+  nv_offset = nghttp2_frame_headers_payload_nv_offset(frame);
+
+  buf = &bufs->cur->buf;
+
+  buf->pos += nv_offset;
+  buf->last = buf->pos;
+
+  /* This call will adjust buf->last to the correct position */
+  rv = nghttp2_hd_deflate_hd_bufs(deflater, bufs, frame->nva, frame->nvlen);
+
+  if (rv == NGHTTP2_ERR_BUFFER_ERROR) {
+    rv = NGHTTP2_ERR_HEADER_COMP;
+  }
+
+  buf->pos -= nv_offset;
+
+  if (rv != 0) {
+    return rv;
+  }
+
+  if (frame->hd.flags & NGHTTP2_FLAG_PRIORITY) {
+    nghttp2_frame_pack_priority_spec(buf->pos, &frame->pri_spec);
+  }
+
+  frame->padlen = 0;
+  frame->hd.length = nghttp2_bufs_len(bufs);
+
+  return frame_pack_headers_shared(bufs, &frame->hd);
+}
+
+void nghttp2_frame_pack_priority_spec(uint8_t *buf,
+                                      const nghttp2_priority_spec *pri_spec) {
+  nghttp2_put_uint32be(buf, (uint32_t)pri_spec->stream_id);
+  if (pri_spec->exclusive) {
+    buf[0] |= 0x80;
+  }
+  buf[4] = (uint8_t)(pri_spec->weight - 1);
+}
+
+void nghttp2_frame_unpack_priority_spec(nghttp2_priority_spec *pri_spec,
+                                        const uint8_t *payload) {
+  int32_t dep_stream_id;
+  uint8_t exclusive;
+  int32_t weight;
+
+  dep_stream_id = nghttp2_get_uint32(payload) & NGHTTP2_STREAM_ID_MASK;
+  exclusive = (payload[0] & 0x80) > 0;
+  weight = payload[4] + 1;
+
+  nghttp2_priority_spec_init(pri_spec, dep_stream_id, weight, exclusive);
+}
+
+int nghttp2_frame_unpack_headers_payload(nghttp2_headers *frame,
+                                         const uint8_t *payload) {
+  if (frame->hd.flags & NGHTTP2_FLAG_PRIORITY) {
+    nghttp2_frame_unpack_priority_spec(&frame->pri_spec, payload);
+  } else {
+    nghttp2_priority_spec_default_init(&frame->pri_spec);
+  }
+
+  frame->nva = NULL;
+  frame->nvlen = 0;
+
+  return 0;
+}
+
+int nghttp2_frame_pack_priority(nghttp2_bufs *bufs, nghttp2_priority *frame) {
+  nghttp2_buf *buf;
+
+  assert(bufs->head == bufs->cur);
+
+  buf = &bufs->head->buf;
+
+  assert(nghttp2_buf_avail(buf) >= NGHTTP2_PRIORITY_SPECLEN);
+
+  buf->pos -= NGHTTP2_FRAME_HDLEN;
+
+  nghttp2_frame_pack_frame_hd(buf->pos, &frame->hd);
+
+  nghttp2_frame_pack_priority_spec(buf->last, &frame->pri_spec);
+
+  buf->last += NGHTTP2_PRIORITY_SPECLEN;
+
+  return 0;
+}
+
+void nghttp2_frame_unpack_priority_payload(nghttp2_priority *frame,
+                                           const uint8_t *payload) {
+  nghttp2_frame_unpack_priority_spec(&frame->pri_spec, payload);
+}
+
+int nghttp2_frame_pack_rst_stream(nghttp2_bufs *bufs,
+                                  nghttp2_rst_stream *frame) {
+  nghttp2_buf *buf;
+
+  assert(bufs->head == bufs->cur);
+
+  buf = &bufs->head->buf;
+
+  assert(nghttp2_buf_avail(buf) >= 4);
+
+  buf->pos -= NGHTTP2_FRAME_HDLEN;
+
+  nghttp2_frame_pack_frame_hd(buf->pos, &frame->hd);
+
+  nghttp2_put_uint32be(buf->last, frame->error_code);
+  buf->last += 4;
+
+  return 0;
+}
+
+void nghttp2_frame_unpack_rst_stream_payload(nghttp2_rst_stream *frame,
+                                             const uint8_t *payload) {
+  frame->error_code = nghttp2_get_uint32(payload);
+}
+
+int nghttp2_frame_pack_settings(nghttp2_bufs *bufs, nghttp2_settings *frame) {
+  nghttp2_buf *buf;
+
+  assert(bufs->head == bufs->cur);
+
+  buf = &bufs->head->buf;
+
+  if (nghttp2_buf_avail(buf) < frame->hd.length) {
+    return NGHTTP2_ERR_FRAME_SIZE_ERROR;
+  }
+
+  buf->pos -= NGHTTP2_FRAME_HDLEN;
+
+  nghttp2_frame_pack_frame_hd(buf->pos, &frame->hd);
+
+  buf->last +=
+      nghttp2_frame_pack_settings_payload(buf->last, frame->iv, frame->niv);
+
+  return 0;
+}
+
+size_t nghttp2_frame_pack_settings_payload(uint8_t *buf,
+                                           const nghttp2_settings_entry *iv,
+                                           size_t niv) {
+  size_t i;
+  for (i = 0; i < niv; ++i, buf += NGHTTP2_FRAME_SETTINGS_ENTRY_LENGTH) {
+    nghttp2_put_uint16be(buf, (uint16_t)iv[i].settings_id);
+    nghttp2_put_uint32be(buf + 2, iv[i].value);
+  }
+  return NGHTTP2_FRAME_SETTINGS_ENTRY_LENGTH * niv;
+}
+
+void nghttp2_frame_unpack_settings_payload(nghttp2_settings *frame,
+                                           nghttp2_settings_entry *iv,
+                                           size_t niv) {
+  frame->iv = iv;
+  frame->niv = niv;
+}
+
+void nghttp2_frame_unpack_settings_entry(nghttp2_settings_entry *iv,
+                                         const uint8_t *payload) {
+  iv->settings_id = nghttp2_get_uint16(&payload[0]);
+  iv->value = nghttp2_get_uint32(&payload[2]);
+}
+
+int nghttp2_frame_unpack_settings_payload2(nghttp2_settings_entry **iv_ptr,
+                                           size_t *niv_ptr,
+                                           const uint8_t *payload,
+                                           size_t payloadlen,
+                                           nghttp2_mem *mem) {
+  size_t i;
+
+  *niv_ptr = payloadlen / NGHTTP2_FRAME_SETTINGS_ENTRY_LENGTH;
+
+  if (*niv_ptr == 0) {
+    *iv_ptr = NULL;
+
+    return 0;
+  }
+
+  *iv_ptr =
+      nghttp2_mem_malloc(mem, (*niv_ptr) * sizeof(nghttp2_settings_entry));
+
+  if (*iv_ptr == NULL) {
+    return NGHTTP2_ERR_NOMEM;
+  }
+
+  for (i = 0; i < *niv_ptr; ++i) {
+    size_t off = i * NGHTTP2_FRAME_SETTINGS_ENTRY_LENGTH;
+    nghttp2_frame_unpack_settings_entry(&(*iv_ptr)[i], &payload[off]);
+  }
+
+  return 0;
+}
+
+int nghttp2_frame_pack_push_promise(nghttp2_bufs *bufs,
+                                    nghttp2_push_promise *frame,
+                                    nghttp2_hd_deflater *deflater) {
+  size_t nv_offset = 4;
+  int rv;
+  nghttp2_buf *buf;
+
+  assert(bufs->head == bufs->cur);
+
+  buf = &bufs->cur->buf;
+
+  buf->pos += nv_offset;
+  buf->last = buf->pos;
+
+  /* This call will adjust buf->last to the correct position */
+  rv = nghttp2_hd_deflate_hd_bufs(deflater, bufs, frame->nva, frame->nvlen);
+
+  if (rv == NGHTTP2_ERR_BUFFER_ERROR) {
+    rv = NGHTTP2_ERR_HEADER_COMP;
+  }
+
+  buf->pos -= nv_offset;
+
+  if (rv != 0) {
+    return rv;
+  }
+
+  nghttp2_put_uint32be(buf->pos, (uint32_t)frame->promised_stream_id);
+
+  frame->padlen = 0;
+  frame->hd.length = nghttp2_bufs_len(bufs);
+
+  return frame_pack_headers_shared(bufs, &frame->hd);
+}
+
+int nghttp2_frame_unpack_push_promise_payload(nghttp2_push_promise *frame,
+                                              const uint8_t *payload) {
+  frame->promised_stream_id =
+      nghttp2_get_uint32(payload) & NGHTTP2_STREAM_ID_MASK;
+  frame->nva = NULL;
+  frame->nvlen = 0;
+  return 0;
+}
+
+int nghttp2_frame_pack_ping(nghttp2_bufs *bufs, nghttp2_ping *frame) {
+  nghttp2_buf *buf;
+
+  assert(bufs->head == bufs->cur);
+
+  buf = &bufs->head->buf;
+
+  assert(nghttp2_buf_avail(buf) >= 8);
+
+  buf->pos -= NGHTTP2_FRAME_HDLEN;
+
+  nghttp2_frame_pack_frame_hd(buf->pos, &frame->hd);
+
+  buf->last =
+      nghttp2_cpymem(buf->last, frame->opaque_data, sizeof(frame->opaque_data));
+
+  return 0;
+}
+
+void nghttp2_frame_unpack_ping_payload(nghttp2_ping *frame,
+                                       const uint8_t *payload) {
+  memcpy(frame->opaque_data, payload, sizeof(frame->opaque_data));
+}
+
+int nghttp2_frame_pack_goaway(nghttp2_bufs *bufs, nghttp2_goaway *frame) {
+  int rv;
+  nghttp2_buf *buf;
+
+  assert(bufs->head == bufs->cur);
+
+  buf = &bufs->head->buf;
+
+  buf->pos -= NGHTTP2_FRAME_HDLEN;
+
+  nghttp2_frame_pack_frame_hd(buf->pos, &frame->hd);
+
+  nghttp2_put_uint32be(buf->last, (uint32_t)frame->last_stream_id);
+  buf->last += 4;
+
+  nghttp2_put_uint32be(buf->last, frame->error_code);
+  buf->last += 4;
+
+  rv = nghttp2_bufs_add(bufs, frame->opaque_data, frame->opaque_data_len);
+
+  if (rv == NGHTTP2_ERR_BUFFER_ERROR) {
+    return NGHTTP2_ERR_FRAME_SIZE_ERROR;
+  }
+
+  if (rv != 0) {
+    return rv;
+  }
+
+  return 0;
+}
+
+void nghttp2_frame_unpack_goaway_payload(nghttp2_goaway *frame,
+                                         const uint8_t *payload,
+                                         uint8_t *var_gift_payload,
+                                         size_t var_gift_payloadlen) {
+  frame->last_stream_id = nghttp2_get_uint32(payload) & NGHTTP2_STREAM_ID_MASK;
+  frame->error_code = nghttp2_get_uint32(payload + 4);
+
+  frame->opaque_data = var_gift_payload;
+  frame->opaque_data_len = var_gift_payloadlen;
+}
+
+int nghttp2_frame_unpack_goaway_payload2(nghttp2_goaway *frame,
+                                         const uint8_t *payload,
+                                         size_t payloadlen, nghttp2_mem *mem) {
+  uint8_t *var_gift_payload;
+  size_t var_gift_payloadlen;
+
+  if (payloadlen > 8) {
+    var_gift_payloadlen = payloadlen - 8;
+  } else {
+    var_gift_payloadlen = 0;
+  }
+
+  payloadlen -= var_gift_payloadlen;
+
+  if (!var_gift_payloadlen) {
+    var_gift_payload = NULL;
+  } else {
+    var_gift_payload = nghttp2_mem_malloc(mem, var_gift_payloadlen);
+
+    if (var_gift_payload == NULL) {
+      return NGHTTP2_ERR_NOMEM;
+    }
+
+    memcpy(var_gift_payload, payload + 8, var_gift_payloadlen);
+  }
+
+  nghttp2_frame_unpack_goaway_payload(frame, payload, var_gift_payload,
+                                      var_gift_payloadlen);
+
+  return 0;
+}
+
+int nghttp2_frame_pack_window_update(nghttp2_bufs *bufs,
+                                     nghttp2_window_update *frame) {
+  nghttp2_buf *buf;
+
+  assert(bufs->head == bufs->cur);
+
+  buf = &bufs->head->buf;
+
+  assert(nghttp2_buf_avail(buf) >= 4);
+
+  buf->pos -= NGHTTP2_FRAME_HDLEN;
+
+  nghttp2_frame_pack_frame_hd(buf->pos, &frame->hd);
+
+  nghttp2_put_uint32be(buf->last, (uint32_t)frame->window_size_increment);
+  buf->last += 4;
+
+  return 0;
+}
+
+void nghttp2_frame_unpack_window_update_payload(nghttp2_window_update *frame,
+                                                const uint8_t *payload) {
+  frame->window_size_increment =
+      nghttp2_get_uint32(payload) & NGHTTP2_WINDOW_SIZE_INCREMENT_MASK;
+}
+
+int nghttp2_frame_pack_altsvc(nghttp2_bufs *bufs, nghttp2_extension *frame) {
+  int rv;
+  nghttp2_buf *buf;
+  nghttp2_ext_altsvc *altsvc;
+
+  /* This is required with --disable-assert. */
+  (void)rv;
+
+  altsvc = frame->payload;
+
+  buf = &bufs->head->buf;
+
+  assert(nghttp2_buf_avail(buf) >=
+         2 + altsvc->origin_len + altsvc->field_value_len);
+
+  buf->pos -= NGHTTP2_FRAME_HDLEN;
+
+  nghttp2_frame_pack_frame_hd(buf->pos, &frame->hd);
+
+  nghttp2_put_uint16be(buf->last, (uint16_t)altsvc->origin_len);
+  buf->last += 2;
+
+  rv = nghttp2_bufs_add(bufs, altsvc->origin, altsvc->origin_len);
+
+  assert(rv == 0);
+
+  rv = nghttp2_bufs_add(bufs, altsvc->field_value, altsvc->field_value_len);
+
+  assert(rv == 0);
+
+  return 0;
+}
+
+void nghttp2_frame_unpack_altsvc_payload(nghttp2_extension *frame,
+                                         size_t origin_len, uint8_t *payload,
+                                         size_t payloadlen) {
+  nghttp2_ext_altsvc *altsvc;
+  uint8_t *p;
+
+  altsvc = frame->payload;
+  p = payload;
+
+  altsvc->origin = p;
+
+  p += origin_len;
+
+  altsvc->origin_len = origin_len;
+
+  altsvc->field_value = p;
+  altsvc->field_value_len = (size_t)(payload + payloadlen - p);
+}
+
+int nghttp2_frame_unpack_altsvc_payload2(nghttp2_extension *frame,
+                                         const uint8_t *payload,
+                                         size_t payloadlen, nghttp2_mem *mem) {
+  uint8_t *buf;
+  size_t origin_len;
+
+  if (payloadlen < 2) {
+    return NGHTTP2_FRAME_SIZE_ERROR;
+  }
+
+  origin_len = nghttp2_get_uint16(payload);
+
+  buf = nghttp2_mem_malloc(mem, payloadlen - 2);
+  if (!buf) {
+    return NGHTTP2_ERR_NOMEM;
+  }
+
+  nghttp2_cpymem(buf, payload + 2, payloadlen - 2);
+
+  nghttp2_frame_unpack_altsvc_payload(frame, origin_len, buf, payloadlen - 2);
+
+  return 0;
+}
+
+int nghttp2_frame_pack_origin(nghttp2_bufs *bufs, nghttp2_extension *frame) {
+  nghttp2_buf *buf;
+  nghttp2_ext_origin *origin;
+  nghttp2_origin_entry *orig;
+  size_t i;
+
+  origin = frame->payload;
+
+  buf = &bufs->head->buf;
+
+  if (nghttp2_buf_avail(buf) < frame->hd.length) {
+    return NGHTTP2_ERR_FRAME_SIZE_ERROR;
+  }
+
+  buf->pos -= NGHTTP2_FRAME_HDLEN;
+
+  nghttp2_frame_pack_frame_hd(buf->pos, &frame->hd);
+
+  for (i = 0; i < origin->nov; ++i) {
+    orig = &origin->ov[i];
+    nghttp2_put_uint16be(buf->last, (uint16_t)orig->origin_len);
+    buf->last += 2;
+    buf->last = nghttp2_cpymem(buf->last, orig->origin, orig->origin_len);
+  }
+
+  assert(nghttp2_buf_len(buf) == NGHTTP2_FRAME_HDLEN + frame->hd.length);
+
+  return 0;
+}
+
+int nghttp2_frame_unpack_origin_payload(nghttp2_extension *frame,
+                                        const uint8_t *payload,
+                                        size_t payloadlen, nghttp2_mem *mem) {
+  nghttp2_ext_origin *origin;
+  const uint8_t *p, *end;
+  uint8_t *dst;
+  size_t originlen;
+  nghttp2_origin_entry *ov;
+  size_t nov = 0;
+  size_t len = 0;
+
+  origin = frame->payload;
+  p = payload;
+  end = p + payloadlen;
+
+  for (; p != end;) {
+    if (end - p < 2) {
+      return NGHTTP2_ERR_FRAME_SIZE_ERROR;
+    }
+    originlen = nghttp2_get_uint16(p);
+    p += 2;
+    if (originlen == 0) {
+      continue;
+    }
+    if (originlen > (size_t)(end - p)) {
+      return NGHTTP2_ERR_FRAME_SIZE_ERROR;
+    }
+    p += originlen;
+    /* 1 for terminal NULL */
+    len += originlen + 1;
+    ++nov;
+  }
+
+  if (nov == 0) {
+    origin->ov = NULL;
+    origin->nov = 0;
+
+    return 0;
+  }
+
+  len += nov * sizeof(nghttp2_origin_entry);
+
+  ov = nghttp2_mem_malloc(mem, len);
+  if (ov == NULL) {
+    return NGHTTP2_ERR_NOMEM;
+  }
+
+  origin->ov = ov;
+  origin->nov = nov;
+
+  dst = (uint8_t *)ov + nov * sizeof(nghttp2_origin_entry);
+  p = payload;
+
+  for (; p != end;) {
+    originlen = nghttp2_get_uint16(p);
+    p += 2;
+    if (originlen == 0) {
+      continue;
+    }
+    ov->origin = dst;
+    ov->origin_len = originlen;
+    dst = nghttp2_cpymem(dst, p, originlen);
+    *dst++ = '\0';
+    p += originlen;
+    ++ov;
+  }
+
+  return 0;
+}
+
+nghttp2_settings_entry *nghttp2_frame_iv_copy(const nghttp2_settings_entry *iv,
+                                              size_t niv, nghttp2_mem *mem) {
+  nghttp2_settings_entry *iv_copy;
+  size_t len = niv * sizeof(nghttp2_settings_entry);
+
+  if (len == 0) {
+    return NULL;
+  }
+
+  iv_copy = nghttp2_mem_malloc(mem, len);
+
+  if (iv_copy == NULL) {
+    return NULL;
+  }
+
+  memcpy(iv_copy, iv, len);
+
+  return iv_copy;
+}
+
+int nghttp2_nv_equal(const nghttp2_nv *a, const nghttp2_nv *b) {
+  return a->namelen == b->namelen && a->valuelen == b->valuelen &&
+         memcmp(a->name, b->name, a->namelen) == 0 &&
+         memcmp(a->value, b->value, a->valuelen) == 0;
+}
+
+void nghttp2_nv_array_del(nghttp2_nv *nva, nghttp2_mem *mem) {
+  nghttp2_mem_free(mem, nva);
+}
+
+static int bytes_compar(const uint8_t *a, size_t alen, const uint8_t *b,
+                        size_t blen) {
+  int rv;
+
+  if (alen == blen) {
+    return memcmp(a, b, alen);
+  }
+
+  if (alen < blen) {
+    rv = memcmp(a, b, alen);
+
+    if (rv == 0) {
+      return -1;
+    }
+
+    return rv;
+  }
+
+  rv = memcmp(a, b, blen);
+
+  if (rv == 0) {
+    return 1;
+  }
+
+  return rv;
+}
+
+int nghttp2_nv_compare_name(const nghttp2_nv *lhs, const nghttp2_nv *rhs) {
+  return bytes_compar(lhs->name, lhs->namelen, rhs->name, rhs->namelen);
+}
+
+static int nv_compar(const void *lhs, const void *rhs) {
+  const nghttp2_nv *a = (const nghttp2_nv *)lhs;
+  const nghttp2_nv *b = (const nghttp2_nv *)rhs;
+  int rv;
+
+  rv = bytes_compar(a->name, a->namelen, b->name, b->namelen);
+
+  if (rv == 0) {
+    return bytes_compar(a->value, a->valuelen, b->value, b->valuelen);
+  }
+
+  return rv;
+}
+
+void nghttp2_nv_array_sort(nghttp2_nv *nva, size_t nvlen) {
+  qsort(nva, nvlen, sizeof(nghttp2_nv), nv_compar);
+}
+
+int nghttp2_nv_array_copy(nghttp2_nv **nva_ptr, const nghttp2_nv *nva,
+                          size_t nvlen, nghttp2_mem *mem) {
+  size_t i;
+  uint8_t *data = NULL;
+  size_t buflen = 0;
+  nghttp2_nv *p;
+
+  if (nvlen == 0) {
+    *nva_ptr = NULL;
+
+    return 0;
+  }
+
+  for (i = 0; i < nvlen; ++i) {
+    /* + 1 for null-termination */
+    if ((nva[i].flags & NGHTTP2_NV_FLAG_NO_COPY_NAME) == 0) {
+      buflen += nva[i].namelen + 1;
+    }
+    if ((nva[i].flags & NGHTTP2_NV_FLAG_NO_COPY_VALUE) == 0) {
+      buflen += nva[i].valuelen + 1;
+    }
+  }
+
+  buflen += sizeof(nghttp2_nv) * nvlen;
+
+  *nva_ptr = nghttp2_mem_malloc(mem, buflen);
+
+  if (*nva_ptr == NULL) {
+    return NGHTTP2_ERR_NOMEM;
+  }
+
+  p = *nva_ptr;
+  data = (uint8_t *)(*nva_ptr) + sizeof(nghttp2_nv) * nvlen;
+
+  for (i = 0; i < nvlen; ++i) {
+    p->flags = nva[i].flags;
+
+    if (nva[i].flags & NGHTTP2_NV_FLAG_NO_COPY_NAME) {
+      p->name = nva[i].name;
+      p->namelen = nva[i].namelen;
+    } else {
+      if (nva[i].namelen) {
+        memcpy(data, nva[i].name, nva[i].namelen);
+      }
+      p->name = data;
+      p->namelen = nva[i].namelen;
+      data[p->namelen] = '\0';
+      nghttp2_downcase(p->name, p->namelen);
+      data += nva[i].namelen + 1;
+    }
+
+    if (nva[i].flags & NGHTTP2_NV_FLAG_NO_COPY_VALUE) {
+      p->value = nva[i].value;
+      p->valuelen = nva[i].valuelen;
+    } else {
+      if (nva[i].valuelen) {
+        memcpy(data, nva[i].value, nva[i].valuelen);
+      }
+      p->value = data;
+      p->valuelen = nva[i].valuelen;
+      data[p->valuelen] = '\0';
+      data += nva[i].valuelen + 1;
+    }
+
+    ++p;
+  }
+  return 0;
+}
+
+int nghttp2_iv_check(const nghttp2_settings_entry *iv, size_t niv) {
+  size_t i;
+  for (i = 0; i < niv; ++i) {
+    switch (iv[i].settings_id) {
+    case NGHTTP2_SETTINGS_HEADER_TABLE_SIZE:
+      break;
+    case NGHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS:
+      break;
+    case NGHTTP2_SETTINGS_ENABLE_PUSH:
+      if (iv[i].value != 0 && iv[i].value != 1) {
+        return 0;
+      }
+      break;
+    case NGHTTP2_SETTINGS_INITIAL_WINDOW_SIZE:
+      if (iv[i].value > (uint32_t)NGHTTP2_MAX_WINDOW_SIZE) {
+        return 0;
+      }
+      break;
+    case NGHTTP2_SETTINGS_MAX_FRAME_SIZE:
+      if (iv[i].value < NGHTTP2_MAX_FRAME_SIZE_MIN ||
+          iv[i].value > NGHTTP2_MAX_FRAME_SIZE_MAX) {
+        return 0;
+      }
+      break;
+    case NGHTTP2_SETTINGS_MAX_HEADER_LIST_SIZE:
+      break;
+    case NGHTTP2_SETTINGS_ENABLE_CONNECT_PROTOCOL:
+      if (iv[i].value != 0 && iv[i].value != 1) {
+        return 0;
+      }
+      break;
+    }
+  }
+  return 1;
+}
+
+static void frame_set_pad(nghttp2_buf *buf, size_t padlen, int framehd_only) {
+  size_t trail_padlen;
+  size_t newlen;
+
+  DEBUGF("send: padlen=%zu, shift left 1 bytes\n", padlen);
+
+  memmove(buf->pos - 1, buf->pos, NGHTTP2_FRAME_HDLEN);
+
+  --buf->pos;
+
+  buf->pos[4] |= NGHTTP2_FLAG_PADDED;
+
+  newlen = (nghttp2_get_uint32(buf->pos) >> 8) + padlen;
+  nghttp2_put_uint32be(buf->pos, (uint32_t)((newlen << 8) + buf->pos[3]));
+
+  if (framehd_only) {
+    return;
+  }
+
+  trail_padlen = padlen - 1;
+  buf->pos[NGHTTP2_FRAME_HDLEN] = (uint8_t)trail_padlen;
+
+  /* zero out padding */
+  memset(buf->last, 0, trail_padlen);
+  /* extend buffers trail_padlen bytes, since we ate previous padlen -
+     trail_padlen byte(s) */
+  buf->last += trail_padlen;
+}
+
+int nghttp2_frame_add_pad(nghttp2_bufs *bufs, nghttp2_frame_hd *hd,
+                          size_t padlen, int framehd_only) {
+  nghttp2_buf *buf;
+
+  if (padlen == 0) {
+    DEBUGF("send: padlen = 0, nothing to do\n");
+
+    return 0;
+  }
+
+  /*
+   * We have arranged bufs like this:
+   *
+   *  0                   1                   2                   3
+   *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+   * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   * | |Frame header     | Frame payload...                          :
+   * +-+-----------------+-------------------------------------------+
+   * | |Frame header     | Frame payload...                          :
+   * +-+-----------------+-------------------------------------------+
+   * | |Frame header     | Frame payload...                          :
+   * +-+-----------------+-------------------------------------------+
+   *
+   * We arranged padding so that it is included in the first frame
+   * completely.  For padded frame, we are going to adjust buf->pos of
+   * frame which includes padding and serialize (memmove) frame header
+   * in the correct position.  Also extends buf->last to include
+   * padding.
+   */
+
+  buf = &bufs->head->buf;
+
+  assert(nghttp2_buf_avail(buf) >= padlen - 1);
+
+  frame_set_pad(buf, padlen, framehd_only);
+
+  hd->length += padlen;
+  hd->flags |= NGHTTP2_FLAG_PADDED;
+
+  DEBUGF("send: final payloadlen=%zu, padlen=%zu\n", hd->length, padlen);
+
+  return 0;
+}
diff --git a/Utilities/cmnghttp2/lib/nghttp2_frame.h b/Utilities/cmnghttp2/lib/nghttp2_frame.h
new file mode 100644
index 0000000..615bbf3
--- /dev/null
+++ b/Utilities/cmnghttp2/lib/nghttp2_frame.h
@@ -0,0 +1,624 @@
+/*
+ * nghttp2 - HTTP/2 C Library
+ *
+ * Copyright (c) 2012 Tatsuhiro Tsujikawa
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+#ifndef NGHTTP2_FRAME_H
+#define NGHTTP2_FRAME_H
+
+#ifdef HAVE_CONFIG_H
+#  include <config.h>
+#endif /* HAVE_CONFIG_H */
+
+#include <nghttp2/nghttp2.h>
+#include "nghttp2_hd.h"
+#include "nghttp2_buf.h"
+
+#define NGHTTP2_STREAM_ID_MASK ((1u << 31) - 1)
+#define NGHTTP2_PRI_GROUP_ID_MASK ((1u << 31) - 1)
+#define NGHTTP2_PRIORITY_MASK ((1u << 31) - 1)
+#define NGHTTP2_WINDOW_SIZE_INCREMENT_MASK ((1u << 31) - 1)
+#define NGHTTP2_SETTINGS_ID_MASK ((1 << 24) - 1)
+
+/* The number of bytes of frame header. */
+#define NGHTTP2_FRAME_HDLEN 9
+
+#define NGHTTP2_MAX_FRAME_SIZE_MAX ((1 << 24) - 1)
+#define NGHTTP2_MAX_FRAME_SIZE_MIN (1 << 14)
+
+#define NGHTTP2_MAX_PAYLOADLEN 16384
+/* The one frame buffer length for tranmission.  We may use several of
+   them to support CONTINUATION.  To account for Pad Length field, we
+   allocate extra 1 byte, which saves extra large memcopying. */
+#define NGHTTP2_FRAMEBUF_CHUNKLEN                                              \
+  (NGHTTP2_FRAME_HDLEN + 1 + NGHTTP2_MAX_PAYLOADLEN)
+
+/* The default length of DATA frame payload. */
+#define NGHTTP2_DATA_PAYLOADLEN NGHTTP2_MAX_FRAME_SIZE_MIN
+
+/* Maximum headers block size to send, calculated using
+   nghttp2_hd_deflate_bound().  This is the default value, and can be
+   overridden by nghttp2_option_set_max_send_header_block_size(). */
+#define NGHTTP2_MAX_HEADERSLEN 65536
+
+/* The number of bytes for each SETTINGS entry */
+#define NGHTTP2_FRAME_SETTINGS_ENTRY_LENGTH 6
+
+/* Length of priority related fields in HEADERS/PRIORITY frames */
+#define NGHTTP2_PRIORITY_SPECLEN 5
+
+/* Maximum length of padding in bytes. */
+#define NGHTTP2_MAX_PADLEN 256
+
+/* Union of extension frame payload */
+typedef union {
+  nghttp2_ext_altsvc altsvc;
+  nghttp2_ext_origin origin;
+} nghttp2_ext_frame_payload;
+
+void nghttp2_frame_pack_frame_hd(uint8_t *buf, const nghttp2_frame_hd *hd);
+
+void nghttp2_frame_unpack_frame_hd(nghttp2_frame_hd *hd, const uint8_t *buf);
+
+/**
+ * Initializes frame header |hd| with given parameters.  Reserved bit
+ * is set to 0.
+ */
+void nghttp2_frame_hd_init(nghttp2_frame_hd *hd, size_t length, uint8_t type,
+                           uint8_t flags, int32_t stream_id);
+
+/**
+ * Returns the number of priority field depending on the |flags|.  If
+ * |flags| has neither NGHTTP2_FLAG_PRIORITY_GROUP nor
+ * NGHTTP2_FLAG_PRIORITY_DEPENDENCY set, return 0.
+ */
+size_t nghttp2_frame_priority_len(uint8_t flags);
+
+/**
+ * Packs the |pri_spec| in |buf|.  This function assumes |buf| has
+ * enough space for serialization.
+ */
+void nghttp2_frame_pack_priority_spec(uint8_t *buf,
+                                      const nghttp2_priority_spec *pri_spec);
+
+/**
+ * Unpacks the priority specification from payload |payload| of length
+ * |payloadlen| to |pri_spec|.  The |flags| is used to determine what
+ * kind of priority specification is in |payload|.  This function
+ * assumes the |payload| contains whole priority specification.
+ */
+void nghttp2_frame_unpack_priority_spec(nghttp2_priority_spec *pri_spec,
+                                        const uint8_t *payload);
+
+/*
+ * Returns the offset from the HEADERS frame payload where the
+ * compressed header block starts. The frame payload does not include
+ * frame header.
+ */
+size_t nghttp2_frame_headers_payload_nv_offset(nghttp2_headers *frame);
+
+/*
+ * Packs HEADERS frame |frame| in wire format and store it in |bufs|.
+ * This function expands |bufs| as necessary to store frame.
+ *
+ * The caller must make sure that nghttp2_bufs_reset(bufs) is called
+ * before calling this function.
+ *
+ * frame->hd.length is assigned after length is determined during
+ * packing process.  CONTINUATION frames are also serialized in this
+ * function. This function does not handle padding.
+ *
+ * This function returns 0 if it succeeds, or returns one of the
+ * following negative error codes:
+ *
+ * NGHTTP2_ERR_HEADER_COMP
+ *     The deflate operation failed.
+ * NGHTTP2_ERR_NOMEM
+ *     Out of memory.
+ */
+int nghttp2_frame_pack_headers(nghttp2_bufs *bufs, nghttp2_headers *frame,
+                               nghttp2_hd_deflater *deflater);
+
+/*
+ * Unpacks HEADERS frame byte sequence into |frame|.  This function
+ * only unapcks bytes that come before name/value header block and
+ * after possible Pad Length field.
+ *
+ * This function always succeeds and returns 0.
+ */
+int nghttp2_frame_unpack_headers_payload(nghttp2_headers *frame,
+                                         const uint8_t *payload);
+
+/*
+ * Packs PRIORITY frame |frame| in wire format and store it in
+ * |bufs|.
+ *
+ * The caller must make sure that nghttp2_bufs_reset(bufs) is called
+ * before calling this function.
+ *
+ * This function always succeeds and returns 0.
+ */
+int nghttp2_frame_pack_priority(nghttp2_bufs *bufs, nghttp2_priority *frame);
+
+/*
+ * Unpacks PRIORITY wire format into |frame|.
+ */
+void nghttp2_frame_unpack_priority_payload(nghttp2_priority *frame,
+                                           const uint8_t *payload);
+
+/*
+ * Packs RST_STREAM frame |frame| in wire frame format and store it in
+ * |bufs|.
+ *
+ * The caller must make sure that nghttp2_bufs_reset(bufs) is called
+ * before calling this function.
+ *
+ * This function always succeeds and returns 0.
+ */
+int nghttp2_frame_pack_rst_stream(nghttp2_bufs *bufs,
+                                  nghttp2_rst_stream *frame);
+
+/*
+ * Unpacks RST_STREAM frame byte sequence into |frame|.
+ */
+void nghttp2_frame_unpack_rst_stream_payload(nghttp2_rst_stream *frame,
+                                             const uint8_t *payload);
+
+/*
+ * Packs SETTINGS frame |frame| in wire format and store it in
+ * |bufs|.
+ *
+ * The caller must make sure that nghttp2_bufs_reset(bufs) is called
+ * before calling this function.
+ *
+ * This function returns 0 if it succeeds, or returns one of the
+ * following negative error codes:
+ *
+ * NGHTTP2_ERR_FRAME_SIZE_ERROR
+ *     The length of the frame is too large.
+ */
+int nghttp2_frame_pack_settings(nghttp2_bufs *bufs, nghttp2_settings *frame);
+
+/*
+ * Packs the |iv|, which includes |niv| entries, in the |buf|,
+ * assuming the |buf| has at least 8 * |niv| bytes.
+ *
+ * Returns the number of bytes written into the |buf|.
+ */
+size_t nghttp2_frame_pack_settings_payload(uint8_t *buf,
+                                           const nghttp2_settings_entry *iv,
+                                           size_t niv);
+
+void nghttp2_frame_unpack_settings_entry(nghttp2_settings_entry *iv,
+                                         const uint8_t *payload);
+
+/*
+ * Initializes payload of frame->settings.  The |frame| takes
+ * ownership of |iv|.
+ */
+void nghttp2_frame_unpack_settings_payload(nghttp2_settings *frame,
+                                           nghttp2_settings_entry *iv,
+                                           size_t niv);
+
+/*
+ * Unpacks SETTINGS payload into |*iv_ptr|. The number of entries are
+ * assigned to the |*niv_ptr|. This function allocates enough memory
+ * to store the result in |*iv_ptr|. The caller is responsible to free
+ * |*iv_ptr| after its use.
+ *
+ * This function returns 0 if it succeeds or one of the following
+ * negative error codes:
+ *
+ * NGHTTP2_ERR_NOMEM
+ *     Out of memory.
+ */
+int nghttp2_frame_unpack_settings_payload2(nghttp2_settings_entry **iv_ptr,
+                                           size_t *niv_ptr,
+                                           const uint8_t *payload,
+                                           size_t payloadlen, nghttp2_mem *mem);
+
+/*
+ * Packs PUSH_PROMISE frame |frame| in wire format and store it in
+ * |bufs|.  This function expands |bufs| as necessary to store
+ * frame.
+ *
+ * The caller must make sure that nghttp2_bufs_reset(bufs) is called
+ * before calling this function.
+ *
+ * frame->hd.length is assigned after length is determined during
+ * packing process.  CONTINUATION frames are also serialized in this
+ * function. This function does not handle padding.
+ *
+ * This function returns 0 if it succeeds, or returns one of the
+ * following negative error codes:
+ *
+ * NGHTTP2_ERR_HEADER_COMP
+ *     The deflate operation failed.
+ * NGHTTP2_ERR_NOMEM
+ *     Out of memory.
+ */
+int nghttp2_frame_pack_push_promise(nghttp2_bufs *bufs,
+                                    nghttp2_push_promise *frame,
+                                    nghttp2_hd_deflater *deflater);
+
+/*
+ * Unpacks PUSH_PROMISE frame byte sequence into |frame|.  This
+ * function only unapcks bytes that come before name/value header
+ * block and after possible Pad Length field.
+ *
+ * This function returns 0 if it succeeds or one of the following
+ * negative error codes:
+ *
+ * NGHTTP2_ERR_PROTO
+ *     TODO END_HEADERS flag is not set
+ */
+int nghttp2_frame_unpack_push_promise_payload(nghttp2_push_promise *frame,
+                                              const uint8_t *payload);
+
+/*
+ * Packs PING frame |frame| in wire format and store it in
+ * |bufs|.
+ *
+ * The caller must make sure that nghttp2_bufs_reset(bufs) is called
+ * before calling this function.
+ *
+ * This function always succeeds and returns 0.
+ */
+int nghttp2_frame_pack_ping(nghttp2_bufs *bufs, nghttp2_ping *frame);
+
+/*
+ * Unpacks PING wire format into |frame|.
+ */
+void nghttp2_frame_unpack_ping_payload(nghttp2_ping *frame,
+                                       const uint8_t *payload);
+
+/*
+ * Packs GOAWAY frame |frame| in wire format and store it in |bufs|.
+ * This function expands |bufs| as necessary to store frame.
+ *
+ * The caller must make sure that nghttp2_bufs_reset(bufs) is called
+ * before calling this function.
+ *
+ * This function returns 0 if it succeeds or one of the following
+ * negative error codes:
+ *
+ * NGHTTP2_ERR_NOMEM
+ *     Out of memory.
+ * NGHTTP2_ERR_FRAME_SIZE_ERROR
+ *     The length of the frame is too large.
+ */
+int nghttp2_frame_pack_goaway(nghttp2_bufs *bufs, nghttp2_goaway *frame);
+
+/*
+ * Unpacks GOAWAY wire format into |frame|.  The |payload| of length
+ * |payloadlen| contains first 8 bytes of payload.  The
+ * |var_gift_payload| of length |var_gift_payloadlen| contains
+ * remaining payload and its buffer is gifted to the function and then
+ * |frame|.  The |var_gift_payloadlen| must be freed by
+ * nghttp2_frame_goaway_free().
+ */
+void nghttp2_frame_unpack_goaway_payload(nghttp2_goaway *frame,
+                                         const uint8_t *payload,
+                                         uint8_t *var_gift_payload,
+                                         size_t var_gift_payloadlen);
+
+/*
+ * Unpacks GOAWAY wire format into |frame|.  This function only exists
+ * for unit test.  After allocating buffer for debug data, this
+ * function internally calls nghttp2_frame_unpack_goaway_payload().
+ *
+ * This function returns 0 if it succeeds, or one of the following
+ * negative error codes:
+ *
+ * NGHTTP2_ERR_NOMEM
+ *     Out of memory.
+ */
+int nghttp2_frame_unpack_goaway_payload2(nghttp2_goaway *frame,
+                                         const uint8_t *payload,
+                                         size_t payloadlen, nghttp2_mem *mem);
+
+/*
+ * Packs WINDOW_UPDATE frame |frame| in wire frame format and store it
+ * in |bufs|.
+ *
+ * The caller must make sure that nghttp2_bufs_reset(bufs) is called
+ * before calling this function.
+ *
+ * This function always succeeds and returns 0.
+ */
+int nghttp2_frame_pack_window_update(nghttp2_bufs *bufs,
+                                     nghttp2_window_update *frame);
+
+/*
+ * Unpacks WINDOW_UPDATE frame byte sequence into |frame|.
+ */
+void nghttp2_frame_unpack_window_update_payload(nghttp2_window_update *frame,
+                                                const uint8_t *payload);
+
+/*
+ * Packs ALTSVC frame |frame| in wire frame format and store it in
+ * |bufs|.
+ *
+ * The caller must make sure that nghttp2_bufs_reset(bufs) is called
+ * before calling this function.
+ *
+ * This function always succeeds and returns 0.
+ */
+int nghttp2_frame_pack_altsvc(nghttp2_bufs *bufs, nghttp2_extension *ext);
+
+/*
+ * Unpacks ALTSVC wire format into |frame|.  The |payload| of
+ * |payloadlen| bytes contains frame payload.  This function assumes
+ * that frame->payload points to the nghttp2_ext_altsvc object.
+ *
+ * This function always succeeds and returns 0.
+ */
+void nghttp2_frame_unpack_altsvc_payload(nghttp2_extension *frame,
+                                         size_t origin_len, uint8_t *payload,
+                                         size_t payloadlen);
+
+/*
+ * Unpacks ALTSVC wire format into |frame|.  This function only exists
+ * for unit test.  After allocating buffer for fields, this function
+ * internally calls nghttp2_frame_unpack_altsvc_payload().
+ *
+ * This function returns 0 if it succeeds, or one of the following
+ * negative error codes:
+ *
+ * NGHTTP2_ERR_NOMEM
+ *     Out of memory.
+ * NGHTTP2_ERR_FRAME_SIZE_ERROR
+ *     The payload is too small.
+ */
+int nghttp2_frame_unpack_altsvc_payload2(nghttp2_extension *frame,
+                                         const uint8_t *payload,
+                                         size_t payloadlen, nghttp2_mem *mem);
+
+/*
+ * Packs ORIGIN frame |frame| in wire frame format and store it in
+ * |bufs|.
+ *
+ * The caller must make sure that nghttp2_bufs_reset(bufs) is called
+ * before calling this function.
+ *
+ * This function returns 0 if it succeeds, or one of the following
+ * negative error codes:
+ *
+ * NGHTTP2_ERR_FRAME_SIZE_ERROR
+ *     The length of the frame is too large.
+ */
+int nghttp2_frame_pack_origin(nghttp2_bufs *bufs, nghttp2_extension *ext);
+
+/*
+ * Unpacks ORIGIN wire format into |frame|.  The |payload| of length
+ * |payloadlen| contains the frame payload.
+ *
+ * This function returns 0 if it succeeds, or one of the following
+ * negative error codes:
+ *
+ * NGHTTP2_ERR_NOMEM
+ *     Out of memory.
+ * NGHTTP2_ERR_FRAME_SIZE_ERROR
+ *     The payload is too small.
+ */
+int nghttp2_frame_unpack_origin_payload(nghttp2_extension *frame,
+                                        const uint8_t *payload,
+                                        size_t payloadlen, nghttp2_mem *mem);
+/*
+ * Initializes HEADERS frame |frame| with given values.  |frame| takes
+ * ownership of |nva|, so caller must not free it. If |stream_id| is
+ * not assigned yet, it must be -1.
+ */
+void nghttp2_frame_headers_init(nghttp2_headers *frame, uint8_t flags,
+                                int32_t stream_id, nghttp2_headers_category cat,
+                                const nghttp2_priority_spec *pri_spec,
+                                nghttp2_nv *nva, size_t nvlen);
+
+void nghttp2_frame_headers_free(nghttp2_headers *frame, nghttp2_mem *mem);
+
+void nghttp2_frame_priority_init(nghttp2_priority *frame, int32_t stream_id,
+                                 const nghttp2_priority_spec *pri_spec);
+
+void nghttp2_frame_priority_free(nghttp2_priority *frame);
+
+void nghttp2_frame_rst_stream_init(nghttp2_rst_stream *frame, int32_t stream_id,
+                                   uint32_t error_code);
+
+void nghttp2_frame_rst_stream_free(nghttp2_rst_stream *frame);
+
+/*
+ * Initializes PUSH_PROMISE frame |frame| with given values.  |frame|
+ * takes ownership of |nva|, so caller must not free it.
+ */
+void nghttp2_frame_push_promise_init(nghttp2_push_promise *frame, uint8_t flags,
+                                     int32_t stream_id,
+                                     int32_t promised_stream_id,
+                                     nghttp2_nv *nva, size_t nvlen);
+
+void nghttp2_frame_push_promise_free(nghttp2_push_promise *frame,
+                                     nghttp2_mem *mem);
+
+/*
+ * Initializes SETTINGS frame |frame| with given values. |frame| takes
+ * ownership of |iv|, so caller must not free it. The |flags| are
+ * bitwise-OR of one or more of nghttp2_settings_flag.
+ */
+void nghttp2_frame_settings_init(nghttp2_settings *frame, uint8_t flags,
+                                 nghttp2_settings_entry *iv, size_t niv);
+
+void nghttp2_frame_settings_free(nghttp2_settings *frame, nghttp2_mem *mem);
+
+/*
+ * Initializes PING frame |frame| with given values. If the
+ * |opqeue_data| is not NULL, it must point to 8 bytes memory region
+ * of data. The data pointed by |opaque_data| is copied. It can be
+ * NULL. In this case, 8 bytes NULL is used.
+ */
+void nghttp2_frame_ping_init(nghttp2_ping *frame, uint8_t flags,
+                             const uint8_t *opque_data);
+
+void nghttp2_frame_ping_free(nghttp2_ping *frame);
+
+/*
+ * Initializes GOAWAY frame |frame| with given values. On success,
+ * this function takes ownership of |opaque_data|, so caller must not
+ * free it. If the |opaque_data_len| is 0, opaque_data could be NULL.
+ */
+void nghttp2_frame_goaway_init(nghttp2_goaway *frame, int32_t last_stream_id,
+                               uint32_t error_code, uint8_t *opaque_data,
+                               size_t opaque_data_len);
+
+void nghttp2_frame_goaway_free(nghttp2_goaway *frame, nghttp2_mem *mem);
+
+void nghttp2_frame_window_update_init(nghttp2_window_update *frame,
+                                      uint8_t flags, int32_t stream_id,
+                                      int32_t window_size_increment);
+
+void nghttp2_frame_window_update_free(nghttp2_window_update *frame);
+
+void nghttp2_frame_extension_init(nghttp2_extension *frame, uint8_t type,
+                                  uint8_t flags, int32_t stream_id,
+                                  void *payload);
+
+void nghttp2_frame_extension_free(nghttp2_extension *frame);
+
+/*
+ * Initializes ALTSVC frame |frame| with given values.  This function
+ * assumes that frame->payload points to nghttp2_ext_altsvc object.
+ * Also |origin| and |field_value| are allocated in single buffer,
+ * starting |origin|.  On success, this function takes ownership of
+ * |origin|, so caller must not free it.
+ */
+void nghttp2_frame_altsvc_init(nghttp2_extension *frame, int32_t stream_id,
+                               uint8_t *origin, size_t origin_len,
+                               uint8_t *field_value, size_t field_value_len);
+
+/*
+ * Frees up resources under |frame|.  This function does not free
+ * nghttp2_ext_altsvc object pointed by frame->payload.  This function
+ * only frees origin pointed by nghttp2_ext_altsvc.origin.  Therefore,
+ * other fields must be allocated in the same buffer with origin.
+ */
+void nghttp2_frame_altsvc_free(nghttp2_extension *frame, nghttp2_mem *mem);
+
+/*
+ * Initializes ORIGIN frame |frame| with given values.  This function
+ * assumes that frame->payload points to nghttp2_ext_origin object.
+ * Also |ov| and the memory pointed by the field of its elements are
+ * allocated in single buffer, starting with |ov|.  On success, this
+ * function takes ownership of |ov|, so caller must not free it.
+ */
+void nghttp2_frame_origin_init(nghttp2_extension *frame,
+                               nghttp2_origin_entry *ov, size_t nov);
+
+/*
+ * Frees up resources under |frame|.  This function does not free
+ * nghttp2_ext_origin object pointed by frame->payload.  This function
+ * only frees nghttp2_ext_origin.ov.  Therefore, other fields must be
+ * allocated in the same buffer with ov.
+ */
+void nghttp2_frame_origin_free(nghttp2_extension *frame, nghttp2_mem *mem);
+
+/*
+ * Returns the number of padding bytes after payload.  The total
+ * padding length is given in the |padlen|.  The returned value does
+ * not include the Pad Length field.  If |padlen| is 0, this function
+ * returns 0, regardless of frame->hd.flags.
+ */
+size_t nghttp2_frame_trail_padlen(nghttp2_frame *frame, size_t padlen);
+
+void nghttp2_frame_data_init(nghttp2_data *frame, uint8_t flags,
+                             int32_t stream_id);
+
+void nghttp2_frame_data_free(nghttp2_data *frame);
+
+/*
+ * Makes copy of |iv| and return the copy. The |niv| is the number of
+ * entries in |iv|. This function returns the pointer to the copy if
+ * it succeeds, or NULL.
+ */
+nghttp2_settings_entry *nghttp2_frame_iv_copy(const nghttp2_settings_entry *iv,
+                                              size_t niv, nghttp2_mem *mem);
+
+/*
+ * Sorts the |nva| in ascending order of name and value. If names are
+ * equivalent, sort them by value.
+ */
+void nghttp2_nv_array_sort(nghttp2_nv *nva, size_t nvlen);
+
+/*
+ * Copies name/value pairs from |nva|, which contains |nvlen| pairs,
+ * to |*nva_ptr|, which is dynamically allocated so that all items can
+ * be stored.  The resultant name and value in nghttp2_nv are
+ * guaranteed to be NULL-terminated even if the input is not
+ * null-terminated.
+ *
+ * The |*nva_ptr| must be freed using nghttp2_nv_array_del().
+ *
+ * This function returns 0 if it succeeds or one of the following
+ * negative error codes:
+ *
+ * NGHTTP2_ERR_NOMEM
+ *     Out of memory.
+ */
+int nghttp2_nv_array_copy(nghttp2_nv **nva_ptr, const nghttp2_nv *nva,
+                          size_t nvlen, nghttp2_mem *mem);
+
+/*
+ * Returns nonzero if the name/value pair |a| equals to |b|. The name
+ * is compared in case-sensitive, because we ensure that this function
+ * is called after the name is lower-cased.
+ */
+int nghttp2_nv_equal(const nghttp2_nv *a, const nghttp2_nv *b);
+
+/*
+ * Frees |nva|.
+ */
+void nghttp2_nv_array_del(nghttp2_nv *nva, nghttp2_mem *mem);
+
+/*
+ * Checks that the |iv|, which includes |niv| entries, does not have
+ * invalid values.
+ *
+ * This function returns nonzero if it succeeds, or 0.
+ */
+int nghttp2_iv_check(const nghttp2_settings_entry *iv, size_t niv);
+
+/*
+ * Sets Pad Length field and flags and adjusts frame header position
+ * of each buffers in |bufs|.  The number of padding is given in the
+ * |padlen| including Pad Length field.  The |hd| is the frame header
+ * for the serialized data.  This function fills zeros padding region
+ * unless framehd_only is nonzero.
+ *
+ * This function returns 0 if it succeeds, or one of the following
+ * negative error codes:
+ *
+ * NGHTTP2_ERR_NOMEM
+ *     Out of memory.
+ * NGHTTP2_ERR_FRAME_SIZE_ERROR
+ *     The length of the resulting frame is too large.
+ */
+int nghttp2_frame_add_pad(nghttp2_bufs *bufs, nghttp2_frame_hd *hd,
+                          size_t padlen, int framehd_only);
+
+#endif /* NGHTTP2_FRAME_H */
diff --git a/Utilities/cmnghttp2/lib/nghttp2_hd.c b/Utilities/cmnghttp2/lib/nghttp2_hd.c
new file mode 100644
index 0000000..5e86931
--- /dev/null
+++ b/Utilities/cmnghttp2/lib/nghttp2_hd.c
@@ -0,0 +1,2351 @@
+/*
+ * nghttp2 - HTTP/2 C Library
+ *
+ * Copyright (c) 2013 Tatsuhiro Tsujikawa
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+#include "nghttp2_hd.h"
+
+#include <string.h>
+#include <assert.h>
+#include <stdio.h>
+
+#include "nghttp2_helper.h"
+#include "nghttp2_int.h"
+#include "nghttp2_debug.h"
+
+/* Make scalar initialization form of nghttp2_hd_entry */
+#define MAKE_STATIC_ENT(N, V, T, H)                                            \
+  {                                                                            \
+    {NULL, NULL, (uint8_t *)(N), sizeof((N)) - 1, -1},                         \
+        {NULL, NULL, (uint8_t *)(V), sizeof((V)) - 1, -1},                     \
+        {(uint8_t *)(N), (uint8_t *)(V), sizeof((N)) - 1, sizeof((V)) - 1, 0}, \
+        T, H                                                                   \
+  }
+
+/* Generated by mkstatictbl.py */
+/* 3rd parameter is nghttp2_token value for header field name.  We use
+   first enum value if same header names are repeated (e.g.,
+   :status). */
+static const nghttp2_hd_static_entry static_table[] = {
+    MAKE_STATIC_ENT(":authority", "", 0, 3153725150u),
+    MAKE_STATIC_ENT(":method", "GET", 1, 695666056u),
+    MAKE_STATIC_ENT(":method", "POST", 1, 695666056u),
+    MAKE_STATIC_ENT(":path", "/", 3, 3292848686u),
+    MAKE_STATIC_ENT(":path", "/index.html", 3, 3292848686u),
+    MAKE_STATIC_ENT(":scheme", "http", 5, 2510477674u),
+    MAKE_STATIC_ENT(":scheme", "https", 5, 2510477674u),
+    MAKE_STATIC_ENT(":status", "200", 7, 4000288983u),
+    MAKE_STATIC_ENT(":status", "204", 7, 4000288983u),
+    MAKE_STATIC_ENT(":status", "206", 7, 4000288983u),
+    MAKE_STATIC_ENT(":status", "304", 7, 4000288983u),
+    MAKE_STATIC_ENT(":status", "400", 7, 4000288983u),
+    MAKE_STATIC_ENT(":status", "404", 7, 4000288983u),
+    MAKE_STATIC_ENT(":status", "500", 7, 4000288983u),
+    MAKE_STATIC_ENT("accept-charset", "", 14, 3664010344u),
+    MAKE_STATIC_ENT("accept-encoding", "gzip, deflate", 15, 3379649177u),
+    MAKE_STATIC_ENT("accept-language", "", 16, 1979086614u),
+    MAKE_STATIC_ENT("accept-ranges", "", 17, 1713753958u),
+    MAKE_STATIC_ENT("accept", "", 18, 136609321u),
+    MAKE_STATIC_ENT("access-control-allow-origin", "", 19, 2710797292u),
+    MAKE_STATIC_ENT("age", "", 20, 742476188u),
+    MAKE_STATIC_ENT("allow", "", 21, 2930878514u),
+    MAKE_STATIC_ENT("authorization", "", 22, 2436257726u),
+    MAKE_STATIC_ENT("cache-control", "", 23, 1355326669u),
+    MAKE_STATIC_ENT("content-disposition", "", 24, 3889184348u),
+    MAKE_STATIC_ENT("content-encoding", "", 25, 65203592u),
+    MAKE_STATIC_ENT("content-language", "", 26, 24973587u),
+    MAKE_STATIC_ENT("content-length", "", 27, 1308181789u),
+    MAKE_STATIC_ENT("content-location", "", 28, 2302364718u),
+    MAKE_STATIC_ENT("content-range", "", 29, 3555523146u),
+    MAKE_STATIC_ENT("content-type", "", 30, 4244048277u),
+    MAKE_STATIC_ENT("cookie", "", 31, 2007449791u),
+    MAKE_STATIC_ENT("date", "", 32, 3564297305u),
+    MAKE_STATIC_ENT("etag", "", 33, 113792960u),
+    MAKE_STATIC_ENT("expect", "", 34, 2530896728u),
+    MAKE_STATIC_ENT("expires", "", 35, 1049544579u),
+    MAKE_STATIC_ENT("from", "", 36, 2513272949u),
+    MAKE_STATIC_ENT("host", "", 37, 2952701295u),
+    MAKE_STATIC_ENT("if-match", "", 38, 3597694698u),
+    MAKE_STATIC_ENT("if-modified-since", "", 39, 2213050793u),
+    MAKE_STATIC_ENT("if-none-match", "", 40, 2536202615u),
+    MAKE_STATIC_ENT("if-range", "", 41, 2340978238u),
+    MAKE_STATIC_ENT("if-unmodified-since", "", 42, 3794814858u),
+    MAKE_STATIC_ENT("last-modified", "", 43, 3226950251u),
+    MAKE_STATIC_ENT("link", "", 44, 232457833u),
+    MAKE_STATIC_ENT("location", "", 45, 200649126u),
+    MAKE_STATIC_ENT("max-forwards", "", 46, 1826162134u),
+    MAKE_STATIC_ENT("proxy-authenticate", "", 47, 2709445359u),
+    MAKE_STATIC_ENT("proxy-authorization", "", 48, 2686392507u),
+    MAKE_STATIC_ENT("range", "", 49, 4208725202u),
+    MAKE_STATIC_ENT("referer", "", 50, 3969579366u),
+    MAKE_STATIC_ENT("refresh", "", 51, 3572655668u),
+    MAKE_STATIC_ENT("retry-after", "", 52, 3336180598u),
+    MAKE_STATIC_ENT("server", "", 53, 1085029842u),
+    MAKE_STATIC_ENT("set-cookie", "", 54, 1848371000u),
+    MAKE_STATIC_ENT("strict-transport-security", "", 55, 4138147361u),
+    MAKE_STATIC_ENT("transfer-encoding", "", 56, 3719590988u),
+    MAKE_STATIC_ENT("user-agent", "", 57, 606444526u),
+    MAKE_STATIC_ENT("vary", "", 58, 1085005381u),
+    MAKE_STATIC_ENT("via", "", 59, 1762798611u),
+    MAKE_STATIC_ENT("www-authenticate", "", 60, 779865858u),
+};
+
+static int memeq(const void *s1, const void *s2, size_t n) {
+  return memcmp(s1, s2, n) == 0;
+}
+
+/*
+ * This function was generated by genlibtokenlookup.py.  Inspired by
+ * h2o header lookup.  https://github.com/h2o/h2o
+ */
+static int32_t lookup_token(const uint8_t *name, size_t namelen) {
+  switch (namelen) {
+  case 2:
+    switch (name[1]) {
+    case 'e':
+      if (memeq("t", name, 1)) {
+        return NGHTTP2_TOKEN_TE;
+      }
+      break;
+    }
+    break;
+  case 3:
+    switch (name[2]) {
+    case 'a':
+      if (memeq("vi", name, 2)) {
+        return NGHTTP2_TOKEN_VIA;
+      }
+      break;
+    case 'e':
+      if (memeq("ag", name, 2)) {
+        return NGHTTP2_TOKEN_AGE;
+      }
+      break;
+    }
+    break;
+  case 4:
+    switch (name[3]) {
+    case 'e':
+      if (memeq("dat", name, 3)) {
+        return NGHTTP2_TOKEN_DATE;
+      }
+      break;
+    case 'g':
+      if (memeq("eta", name, 3)) {
+        return NGHTTP2_TOKEN_ETAG;
+      }
+      break;
+    case 'k':
+      if (memeq("lin", name, 3)) {
+        return NGHTTP2_TOKEN_LINK;
+      }
+      break;
+    case 'm':
+      if (memeq("fro", name, 3)) {
+        return NGHTTP2_TOKEN_FROM;
+      }
+      break;
+    case 't':
+      if (memeq("hos", name, 3)) {
+        return NGHTTP2_TOKEN_HOST;
+      }
+      break;
+    case 'y':
+      if (memeq("var", name, 3)) {
+        return NGHTTP2_TOKEN_VARY;
+      }
+      break;
+    }
+    break;
+  case 5:
+    switch (name[4]) {
+    case 'e':
+      if (memeq("rang", name, 4)) {
+        return NGHTTP2_TOKEN_RANGE;
+      }
+      break;
+    case 'h':
+      if (memeq(":pat", name, 4)) {
+        return NGHTTP2_TOKEN__PATH;
+      }
+      break;
+    case 'w':
+      if (memeq("allo", name, 4)) {
+        return NGHTTP2_TOKEN_ALLOW;
+      }
+      break;
+    }
+    break;
+  case 6:
+    switch (name[5]) {
+    case 'e':
+      if (memeq("cooki", name, 5)) {
+        return NGHTTP2_TOKEN_COOKIE;
+      }
+      break;
+    case 'r':
+      if (memeq("serve", name, 5)) {
+        return NGHTTP2_TOKEN_SERVER;
+      }
+      break;
+    case 't':
+      if (memeq("accep", name, 5)) {
+        return NGHTTP2_TOKEN_ACCEPT;
+      }
+      if (memeq("expec", name, 5)) {
+        return NGHTTP2_TOKEN_EXPECT;
+      }
+      break;
+    }
+    break;
+  case 7:
+    switch (name[6]) {
+    case 'd':
+      if (memeq(":metho", name, 6)) {
+        return NGHTTP2_TOKEN__METHOD;
+      }
+      break;
+    case 'e':
+      if (memeq(":schem", name, 6)) {
+        return NGHTTP2_TOKEN__SCHEME;
+      }
+      if (memeq("upgrad", name, 6)) {
+        return NGHTTP2_TOKEN_UPGRADE;
+      }
+      break;
+    case 'h':
+      if (memeq("refres", name, 6)) {
+        return NGHTTP2_TOKEN_REFRESH;
+      }
+      break;
+    case 'r':
+      if (memeq("refere", name, 6)) {
+        return NGHTTP2_TOKEN_REFERER;
+      }
+      break;
+    case 's':
+      if (memeq(":statu", name, 6)) {
+        return NGHTTP2_TOKEN__STATUS;
+      }
+      if (memeq("expire", name, 6)) {
+        return NGHTTP2_TOKEN_EXPIRES;
+      }
+      break;
+    }
+    break;
+  case 8:
+    switch (name[7]) {
+    case 'e':
+      if (memeq("if-rang", name, 7)) {
+        return NGHTTP2_TOKEN_IF_RANGE;
+      }
+      break;
+    case 'h':
+      if (memeq("if-matc", name, 7)) {
+        return NGHTTP2_TOKEN_IF_MATCH;
+      }
+      break;
+    case 'n':
+      if (memeq("locatio", name, 7)) {
+        return NGHTTP2_TOKEN_LOCATION;
+      }
+      break;
+    }
+    break;
+  case 9:
+    switch (name[8]) {
+    case 'l':
+      if (memeq(":protoco", name, 8)) {
+        return NGHTTP2_TOKEN__PROTOCOL;
+      }
+      break;
+    }
+    break;
+  case 10:
+    switch (name[9]) {
+    case 'e':
+      if (memeq("keep-aliv", name, 9)) {
+        return NGHTTP2_TOKEN_KEEP_ALIVE;
+      }
+      if (memeq("set-cooki", name, 9)) {
+        return NGHTTP2_TOKEN_SET_COOKIE;
+      }
+      break;
+    case 'n':
+      if (memeq("connectio", name, 9)) {
+        return NGHTTP2_TOKEN_CONNECTION;
+      }
+      break;
+    case 't':
+      if (memeq("user-agen", name, 9)) {
+        return NGHTTP2_TOKEN_USER_AGENT;
+      }
+      break;
+    case 'y':
+      if (memeq(":authorit", name, 9)) {
+        return NGHTTP2_TOKEN__AUTHORITY;
+      }
+      break;
+    }
+    break;
+  case 11:
+    switch (name[10]) {
+    case 'r':
+      if (memeq("retry-afte", name, 10)) {
+        return NGHTTP2_TOKEN_RETRY_AFTER;
+      }
+      break;
+    }
+    break;
+  case 12:
+    switch (name[11]) {
+    case 'e':
+      if (memeq("content-typ", name, 11)) {
+        return NGHTTP2_TOKEN_CONTENT_TYPE;
+      }
+      break;
+    case 's':
+      if (memeq("max-forward", name, 11)) {
+        return NGHTTP2_TOKEN_MAX_FORWARDS;
+      }
+      break;
+    }
+    break;
+  case 13:
+    switch (name[12]) {
+    case 'd':
+      if (memeq("last-modifie", name, 12)) {
+        return NGHTTP2_TOKEN_LAST_MODIFIED;
+      }
+      break;
+    case 'e':
+      if (memeq("content-rang", name, 12)) {
+        return NGHTTP2_TOKEN_CONTENT_RANGE;
+      }
+      break;
+    case 'h':
+      if (memeq("if-none-matc", name, 12)) {
+        return NGHTTP2_TOKEN_IF_NONE_MATCH;
+      }
+      break;
+    case 'l':
+      if (memeq("cache-contro", name, 12)) {
+        return NGHTTP2_TOKEN_CACHE_CONTROL;
+      }
+      break;
+    case 'n':
+      if (memeq("authorizatio", name, 12)) {
+        return NGHTTP2_TOKEN_AUTHORIZATION;
+      }
+      break;
+    case 's':
+      if (memeq("accept-range", name, 12)) {
+        return NGHTTP2_TOKEN_ACCEPT_RANGES;
+      }
+      break;
+    }
+    break;
+  case 14:
+    switch (name[13]) {
+    case 'h':
+      if (memeq("content-lengt", name, 13)) {
+        return NGHTTP2_TOKEN_CONTENT_LENGTH;
+      }
+      break;
+    case 't':
+      if (memeq("accept-charse", name, 13)) {
+        return NGHTTP2_TOKEN_ACCEPT_CHARSET;
+      }
+      break;
+    }
+    break;
+  case 15:
+    switch (name[14]) {
+    case 'e':
+      if (memeq("accept-languag", name, 14)) {
+        return NGHTTP2_TOKEN_ACCEPT_LANGUAGE;
+      }
+      break;
+    case 'g':
+      if (memeq("accept-encodin", name, 14)) {
+        return NGHTTP2_TOKEN_ACCEPT_ENCODING;
+      }
+      break;
+    }
+    break;
+  case 16:
+    switch (name[15]) {
+    case 'e':
+      if (memeq("content-languag", name, 15)) {
+        return NGHTTP2_TOKEN_CONTENT_LANGUAGE;
+      }
+      if (memeq("www-authenticat", name, 15)) {
+        return NGHTTP2_TOKEN_WWW_AUTHENTICATE;
+      }
+      break;
+    case 'g':
+      if (memeq("content-encodin", name, 15)) {
+        return NGHTTP2_TOKEN_CONTENT_ENCODING;
+      }
+      break;
+    case 'n':
+      if (memeq("content-locatio", name, 15)) {
+        return NGHTTP2_TOKEN_CONTENT_LOCATION;
+      }
+      if (memeq("proxy-connectio", name, 15)) {
+        return NGHTTP2_TOKEN_PROXY_CONNECTION;
+      }
+      break;
+    }
+    break;
+  case 17:
+    switch (name[16]) {
+    case 'e':
+      if (memeq("if-modified-sinc", name, 16)) {
+        return NGHTTP2_TOKEN_IF_MODIFIED_SINCE;
+      }
+      break;
+    case 'g':
+      if (memeq("transfer-encodin", name, 16)) {
+        return NGHTTP2_TOKEN_TRANSFER_ENCODING;
+      }
+      break;
+    }
+    break;
+  case 18:
+    switch (name[17]) {
+    case 'e':
+      if (memeq("proxy-authenticat", name, 17)) {
+        return NGHTTP2_TOKEN_PROXY_AUTHENTICATE;
+      }
+      break;
+    }
+    break;
+  case 19:
+    switch (name[18]) {
+    case 'e':
+      if (memeq("if-unmodified-sinc", name, 18)) {
+        return NGHTTP2_TOKEN_IF_UNMODIFIED_SINCE;
+      }
+      break;
+    case 'n':
+      if (memeq("content-dispositio", name, 18)) {
+        return NGHTTP2_TOKEN_CONTENT_DISPOSITION;
+      }
+      if (memeq("proxy-authorizatio", name, 18)) {
+        return NGHTTP2_TOKEN_PROXY_AUTHORIZATION;
+      }
+      break;
+    }
+    break;
+  case 25:
+    switch (name[24]) {
+    case 'y':
+      if (memeq("strict-transport-securit", name, 24)) {
+        return NGHTTP2_TOKEN_STRICT_TRANSPORT_SECURITY;
+      }
+      break;
+    }
+    break;
+  case 27:
+    switch (name[26]) {
+    case 'n':
+      if (memeq("access-control-allow-origi", name, 26)) {
+        return NGHTTP2_TOKEN_ACCESS_CONTROL_ALLOW_ORIGIN;
+      }
+      break;
+    }
+    break;
+  }
+  return -1;
+}
+
+void nghttp2_hd_entry_init(nghttp2_hd_entry *ent, nghttp2_hd_nv *nv) {
+  ent->nv = *nv;
+  ent->cnv.name = nv->name->base;
+  ent->cnv.namelen = nv->name->len;
+  ent->cnv.value = nv->value->base;
+  ent->cnv.valuelen = nv->value->len;
+  ent->cnv.flags = nv->flags;
+  ent->next = NULL;
+  ent->hash = 0;
+
+  nghttp2_rcbuf_incref(ent->nv.name);
+  nghttp2_rcbuf_incref(ent->nv.value);
+}
+
+void nghttp2_hd_entry_free(nghttp2_hd_entry *ent) {
+  nghttp2_rcbuf_decref(ent->nv.value);
+  nghttp2_rcbuf_decref(ent->nv.name);
+}
+
+static int name_eq(const nghttp2_hd_nv *a, const nghttp2_nv *b) {
+  return a->name->len == b->namelen &&
+         memeq(a->name->base, b->name, b->namelen);
+}
+
+static int value_eq(const nghttp2_hd_nv *a, const nghttp2_nv *b) {
+  return a->value->len == b->valuelen &&
+         memeq(a->value->base, b->value, b->valuelen);
+}
+
+static uint32_t name_hash(const nghttp2_nv *nv) {
+  /* 32 bit FNV-1a: http://isthe.com/chongo/tech/comp/fnv/ */
+  uint32_t h = 2166136261u;
+  size_t i;
+
+  for (i = 0; i < nv->namelen; ++i) {
+    h ^= nv->name[i];
+    h += (h << 1) + (h << 4) + (h << 7) + (h << 8) + (h << 24);
+  }
+
+  return h;
+}
+
+static void hd_map_init(nghttp2_hd_map *map) {
+  memset(map, 0, sizeof(nghttp2_hd_map));
+}
+
+static void hd_map_insert(nghttp2_hd_map *map, nghttp2_hd_entry *ent) {
+  nghttp2_hd_entry **bucket;
+
+  bucket = &map->table[ent->hash & (HD_MAP_SIZE - 1)];
+
+  if (*bucket == NULL) {
+    *bucket = ent;
+    return;
+  }
+
+  /* lower index is linked near the root */
+  ent->next = *bucket;
+  *bucket = ent;
+}
+
+static nghttp2_hd_entry *hd_map_find(nghttp2_hd_map *map, int *exact_match,
+                                     const nghttp2_nv *nv, int32_t token,
+                                     uint32_t hash, int name_only) {
+  nghttp2_hd_entry *p;
+  nghttp2_hd_entry *res = NULL;
+
+  *exact_match = 0;
+
+  for (p = map->table[hash & (HD_MAP_SIZE - 1)]; p; p = p->next) {
+    if (token != p->nv.token ||
+        (token == -1 && (hash != p->hash || !name_eq(&p->nv, nv)))) {
+      continue;
+    }
+    if (!res) {
+      res = p;
+      if (name_only) {
+        break;
+      }
+    }
+    if (value_eq(&p->nv, nv)) {
+      res = p;
+      *exact_match = 1;
+      break;
+    }
+  }
+
+  return res;
+}
+
+static void hd_map_remove(nghttp2_hd_map *map, nghttp2_hd_entry *ent) {
+  nghttp2_hd_entry **dst;
+
+  dst = &map->table[ent->hash & (HD_MAP_SIZE - 1)];
+
+  for (; *dst; dst = &(*dst)->next) {
+    if (*dst != ent) {
+      continue;
+    }
+
+    *dst = ent->next;
+    ent->next = NULL;
+    return;
+  }
+}
+
+static int hd_ringbuf_init(nghttp2_hd_ringbuf *ringbuf, size_t bufsize,
+                           nghttp2_mem *mem) {
+  size_t size;
+  for (size = 1; size < bufsize; size <<= 1)
+    ;
+  ringbuf->buffer = nghttp2_mem_malloc(mem, sizeof(nghttp2_hd_entry *) * size);
+  if (ringbuf->buffer == NULL) {
+    return NGHTTP2_ERR_NOMEM;
+  }
+  ringbuf->mask = size - 1;
+  ringbuf->first = 0;
+  ringbuf->len = 0;
+  return 0;
+}
+
+static nghttp2_hd_entry *hd_ringbuf_get(nghttp2_hd_ringbuf *ringbuf,
+                                        size_t idx) {
+  assert(idx < ringbuf->len);
+  return ringbuf->buffer[(ringbuf->first + idx) & ringbuf->mask];
+}
+
+static int hd_ringbuf_reserve(nghttp2_hd_ringbuf *ringbuf, size_t bufsize,
+                              nghttp2_mem *mem) {
+  size_t i;
+  size_t size;
+  nghttp2_hd_entry **buffer;
+
+  if (ringbuf->mask + 1 >= bufsize) {
+    return 0;
+  }
+  for (size = 1; size < bufsize; size <<= 1)
+    ;
+  buffer = nghttp2_mem_malloc(mem, sizeof(nghttp2_hd_entry *) * size);
+  if (buffer == NULL) {
+    return NGHTTP2_ERR_NOMEM;
+  }
+  for (i = 0; i < ringbuf->len; ++i) {
+    buffer[i] = hd_ringbuf_get(ringbuf, i);
+  }
+  nghttp2_mem_free(mem, ringbuf->buffer);
+  ringbuf->buffer = buffer;
+  ringbuf->mask = size - 1;
+  ringbuf->first = 0;
+  return 0;
+}
+
+static void hd_ringbuf_free(nghttp2_hd_ringbuf *ringbuf, nghttp2_mem *mem) {
+  size_t i;
+  if (ringbuf == NULL) {
+    return;
+  }
+  for (i = 0; i < ringbuf->len; ++i) {
+    nghttp2_hd_entry *ent = hd_ringbuf_get(ringbuf, i);
+
+    nghttp2_hd_entry_free(ent);
+    nghttp2_mem_free(mem, ent);
+  }
+  nghttp2_mem_free(mem, ringbuf->buffer);
+}
+
+static int hd_ringbuf_push_front(nghttp2_hd_ringbuf *ringbuf,
+                                 nghttp2_hd_entry *ent, nghttp2_mem *mem) {
+  int rv;
+
+  rv = hd_ringbuf_reserve(ringbuf, ringbuf->len + 1, mem);
+
+  if (rv != 0) {
+    return rv;
+  }
+
+  ringbuf->buffer[--ringbuf->first & ringbuf->mask] = ent;
+  ++ringbuf->len;
+
+  return 0;
+}
+
+static void hd_ringbuf_pop_back(nghttp2_hd_ringbuf *ringbuf) {
+  assert(ringbuf->len > 0);
+  --ringbuf->len;
+}
+
+static int hd_context_init(nghttp2_hd_context *context, nghttp2_mem *mem) {
+  int rv;
+  context->mem = mem;
+  context->bad = 0;
+  context->hd_table_bufsize_max = NGHTTP2_HD_DEFAULT_MAX_BUFFER_SIZE;
+  rv = hd_ringbuf_init(
+      &context->hd_table,
+      context->hd_table_bufsize_max / NGHTTP2_HD_ENTRY_OVERHEAD, mem);
+  if (rv != 0) {
+    return rv;
+  }
+
+  context->hd_table_bufsize = 0;
+  context->next_seq = 0;
+
+  return 0;
+}
+
+static void hd_context_free(nghttp2_hd_context *context) {
+  hd_ringbuf_free(&context->hd_table, context->mem);
+}
+
+int nghttp2_hd_deflate_init(nghttp2_hd_deflater *deflater, nghttp2_mem *mem) {
+  return nghttp2_hd_deflate_init2(
+      deflater, NGHTTP2_HD_DEFAULT_MAX_DEFLATE_BUFFER_SIZE, mem);
+}
+
+int nghttp2_hd_deflate_init2(nghttp2_hd_deflater *deflater,
+                             size_t max_deflate_dynamic_table_size,
+                             nghttp2_mem *mem) {
+  int rv;
+  rv = hd_context_init(&deflater->ctx, mem);
+  if (rv != 0) {
+    return rv;
+  }
+
+  hd_map_init(&deflater->map);
+
+  if (max_deflate_dynamic_table_size < NGHTTP2_HD_DEFAULT_MAX_BUFFER_SIZE) {
+    deflater->notify_table_size_change = 1;
+    deflater->ctx.hd_table_bufsize_max = max_deflate_dynamic_table_size;
+  } else {
+    deflater->notify_table_size_change = 0;
+  }
+
+  deflater->deflate_hd_table_bufsize_max = max_deflate_dynamic_table_size;
+  deflater->min_hd_table_bufsize_max = UINT32_MAX;
+
+  return 0;
+}
+
+int nghttp2_hd_inflate_init(nghttp2_hd_inflater *inflater, nghttp2_mem *mem) {
+  int rv;
+
+  rv = hd_context_init(&inflater->ctx, mem);
+  if (rv != 0) {
+    goto fail;
+  }
+
+  inflater->settings_hd_table_bufsize_max = NGHTTP2_HD_DEFAULT_MAX_BUFFER_SIZE;
+  inflater->min_hd_table_bufsize_max = UINT32_MAX;
+
+  inflater->nv_name_keep = NULL;
+  inflater->nv_value_keep = NULL;
+
+  inflater->opcode = NGHTTP2_HD_OPCODE_NONE;
+  inflater->state = NGHTTP2_HD_STATE_INFLATE_START;
+
+  nghttp2_buf_init(&inflater->namebuf);
+  nghttp2_buf_init(&inflater->valuebuf);
+
+  inflater->namercbuf = NULL;
+  inflater->valuercbuf = NULL;
+
+  inflater->huffman_encoded = 0;
+  inflater->index = 0;
+  inflater->left = 0;
+  inflater->shift = 0;
+  inflater->index_required = 0;
+  inflater->no_index = 0;
+
+  return 0;
+
+fail:
+  return rv;
+}
+
+static void hd_inflate_keep_free(nghttp2_hd_inflater *inflater) {
+  nghttp2_rcbuf_decref(inflater->nv_value_keep);
+  nghttp2_rcbuf_decref(inflater->nv_name_keep);
+
+  inflater->nv_value_keep = NULL;
+  inflater->nv_name_keep = NULL;
+}
+
+void nghttp2_hd_deflate_free(nghttp2_hd_deflater *deflater) {
+  hd_context_free(&deflater->ctx);
+}
+
+void nghttp2_hd_inflate_free(nghttp2_hd_inflater *inflater) {
+  hd_inflate_keep_free(inflater);
+
+  nghttp2_rcbuf_decref(inflater->valuercbuf);
+  nghttp2_rcbuf_decref(inflater->namercbuf);
+
+  hd_context_free(&inflater->ctx);
+}
+
+static size_t entry_room(size_t namelen, size_t valuelen) {
+  return NGHTTP2_HD_ENTRY_OVERHEAD + namelen + valuelen;
+}
+
+static void emit_header(nghttp2_hd_nv *nv_out, nghttp2_hd_nv *nv) {
+  DEBUGF("inflatehd: header emission: %s: %s\n", nv->name->base,
+         nv->value->base);
+  /* ent->ref may be 0. This happens if the encoder emits literal
+     block larger than header table capacity with indexing. */
+  *nv_out = *nv;
+}
+
+static size_t count_encoded_length(size_t n, size_t prefix) {
+  size_t k = (size_t)((1 << prefix) - 1);
+  size_t len = 0;
+
+  if (n < k) {
+    return 1;
+  }
+
+  n -= k;
+  ++len;
+
+  for (; n >= 128; n >>= 7, ++len)
+    ;
+
+  return len + 1;
+}
+
+static size_t encode_length(uint8_t *buf, size_t n, size_t prefix) {
+  size_t k = (size_t)((1 << prefix) - 1);
+  uint8_t *begin = buf;
+
+  *buf = (uint8_t)(*buf & ~k);
+
+  if (n < k) {
+    *buf = (uint8_t)(*buf | n);
+    return 1;
+  }
+
+  *buf = (uint8_t)(*buf | k);
+  ++buf;
+
+  n -= k;
+
+  for (; n >= 128; n >>= 7) {
+    *buf++ = (uint8_t)((1 << 7) | (n & 0x7f));
+  }
+
+  *buf++ = (uint8_t)n;
+
+  return (size_t)(buf - begin);
+}
+
+/*
+ * Decodes |prefix| prefixed integer stored from |in|.  The |last|
+ * represents the 1 beyond the last of the valid contiguous memory
+ * region from |in|.  The decoded integer must be less than or equal
+ * to UINT32_MAX.
+ *
+ * If the |initial| is nonzero, it is used as a initial value, this
+ * function assumes the |in| starts with intermediate data.
+ *
+ * An entire integer is decoded successfully, decoded, the |*fin| is
+ * set to nonzero.
+ *
+ * This function stores the decoded integer in |*res| if it succeed,
+ * including partial decoding (in this case, number of shift to make
+ * in the next call will be stored in |*shift_ptr|) and returns number
+ * of bytes processed, or returns -1, indicating decoding error.
+ */
+static ssize_t decode_length(uint32_t *res, size_t *shift_ptr, int *fin,
+                             uint32_t initial, size_t shift, const uint8_t *in,
+                             const uint8_t *last, size_t prefix) {
+  uint32_t k = (uint8_t)((1 << prefix) - 1);
+  uint32_t n = initial;
+  const uint8_t *start = in;
+
+  *shift_ptr = 0;
+  *fin = 0;
+
+  if (n == 0) {
+    if ((*in & k) != k) {
+      *res = (*in) & k;
+      *fin = 1;
+      return 1;
+    }
+
+    n = k;
+
+    if (++in == last) {
+      *res = n;
+      return (ssize_t)(in - start);
+    }
+  }
+
+  for (; in != last; ++in, shift += 7) {
+    uint32_t add = *in & 0x7f;
+
+    if (shift >= 32) {
+      DEBUGF("inflate: shift exponent overflow\n");
+      return -1;
+    }
+
+    if ((UINT32_MAX >> shift) < add) {
+      DEBUGF("inflate: integer overflow on shift\n");
+      return -1;
+    }
+
+    add <<= shift;
+
+    if (UINT32_MAX - add < n) {
+      DEBUGF("inflate: integer overflow on addition\n");
+      return -1;
+    }
+
+    n += add;
+
+    if ((*in & (1 << 7)) == 0) {
+      break;
+    }
+  }
+
+  *shift_ptr = shift;
+
+  if (in == last) {
+    *res = n;
+    return (ssize_t)(in - start);
+  }
+
+  *res = n;
+  *fin = 1;
+  return (ssize_t)(in + 1 - start);
+}
+
+static int emit_table_size(nghttp2_bufs *bufs, size_t table_size) {
+  int rv;
+  uint8_t *bufp;
+  size_t blocklen;
+  uint8_t sb[16];
+
+  DEBUGF("deflatehd: emit table_size=%zu\n", table_size);
+
+  blocklen = count_encoded_length(table_size, 5);
+
+  if (sizeof(sb) < blocklen) {
+    return NGHTTP2_ERR_HEADER_COMP;
+  }
+
+  bufp = sb;
+
+  *bufp = 0x20u;
+
+  encode_length(bufp, table_size, 5);
+
+  rv = nghttp2_bufs_add(bufs, sb, blocklen);
+  if (rv != 0) {
+    return rv;
+  }
+
+  return 0;
+}
+
+static int emit_indexed_block(nghttp2_bufs *bufs, size_t idx) {
+  int rv;
+  size_t blocklen;
+  uint8_t sb[16];
+  uint8_t *bufp;
+
+  blocklen = count_encoded_length(idx + 1, 7);
+
+  DEBUGF("deflatehd: emit indexed index=%zu, %zu bytes\n", idx, blocklen);
+
+  if (sizeof(sb) < blocklen) {
+    return NGHTTP2_ERR_HEADER_COMP;
+  }
+
+  bufp = sb;
+  *bufp = 0x80u;
+  encode_length(bufp, idx + 1, 7);
+
+  rv = nghttp2_bufs_add(bufs, sb, blocklen);
+  if (rv != 0) {
+    return rv;
+  }
+
+  return 0;
+}
+
+static int emit_string(nghttp2_bufs *bufs, const uint8_t *str, size_t len) {
+  int rv;
+  uint8_t sb[16];
+  uint8_t *bufp;
+  size_t blocklen;
+  size_t enclen;
+  int huffman = 0;
+
+  enclen = nghttp2_hd_huff_encode_count(str, len);
+
+  if (enclen < len) {
+    huffman = 1;
+  } else {
+    enclen = len;
+  }
+
+  blocklen = count_encoded_length(enclen, 7);
+
+  DEBUGF("deflatehd: emit string str=%.*s, length=%zu, huffman=%d, "
+         "encoded_length=%zu\n",
+         (int)len, (const char *)str, len, huffman, enclen);
+
+  if (sizeof(sb) < blocklen) {
+    return NGHTTP2_ERR_HEADER_COMP;
+  }
+
+  bufp = sb;
+  *bufp = huffman ? 1 << 7 : 0;
+  encode_length(bufp, enclen, 7);
+
+  rv = nghttp2_bufs_add(bufs, sb, blocklen);
+  if (rv != 0) {
+    return rv;
+  }
+
+  if (huffman) {
+    rv = nghttp2_hd_huff_encode(bufs, str, len);
+  } else {
+    assert(enclen == len);
+    rv = nghttp2_bufs_add(bufs, str, len);
+  }
+
+  return rv;
+}
+
+static uint8_t pack_first_byte(int indexing_mode) {
+  switch (indexing_mode) {
+  case NGHTTP2_HD_WITH_INDEXING:
+    return 0x40u;
+  case NGHTTP2_HD_WITHOUT_INDEXING:
+    return 0;
+  case NGHTTP2_HD_NEVER_INDEXING:
+    return 0x10u;
+  default:
+    assert(0);
+  }
+  /* This is required to compile with android NDK r10d +
+     --enable-werror */
+  return 0;
+}
+
+static int emit_indname_block(nghttp2_bufs *bufs, size_t idx,
+                              const nghttp2_nv *nv, int indexing_mode) {
+  int rv;
+  uint8_t *bufp;
+  size_t blocklen;
+  uint8_t sb[16];
+  size_t prefixlen;
+
+  if (indexing_mode == NGHTTP2_HD_WITH_INDEXING) {
+    prefixlen = 6;
+  } else {
+    prefixlen = 4;
+  }
+
+  DEBUGF("deflatehd: emit indname index=%zu, valuelen=%zu, indexing_mode=%d\n",
+         idx, nv->valuelen, indexing_mode);
+
+  blocklen = count_encoded_length(idx + 1, prefixlen);
+
+  if (sizeof(sb) < blocklen) {
+    return NGHTTP2_ERR_HEADER_COMP;
+  }
+
+  bufp = sb;
+
+  *bufp = pack_first_byte(indexing_mode);
+
+  encode_length(bufp, idx + 1, prefixlen);
+
+  rv = nghttp2_bufs_add(bufs, sb, blocklen);
+  if (rv != 0) {
+    return rv;
+  }
+
+  rv = emit_string(bufs, nv->value, nv->valuelen);
+  if (rv != 0) {
+    return rv;
+  }
+
+  return 0;
+}
+
+static int emit_newname_block(nghttp2_bufs *bufs, const nghttp2_nv *nv,
+                              int indexing_mode) {
+  int rv;
+
+  DEBUGF(
+      "deflatehd: emit newname namelen=%zu, valuelen=%zu, indexing_mode=%d\n",
+      nv->namelen, nv->valuelen, indexing_mode);
+
+  rv = nghttp2_bufs_addb(bufs, pack_first_byte(indexing_mode));
+  if (rv != 0) {
+    return rv;
+  }
+
+  rv = emit_string(bufs, nv->name, nv->namelen);
+  if (rv != 0) {
+    return rv;
+  }
+
+  rv = emit_string(bufs, nv->value, nv->valuelen);
+  if (rv != 0) {
+    return rv;
+  }
+
+  return 0;
+}
+
+static int add_hd_table_incremental(nghttp2_hd_context *context,
+                                    nghttp2_hd_nv *nv, nghttp2_hd_map *map,
+                                    uint32_t hash) {
+  int rv;
+  nghttp2_hd_entry *new_ent;
+  size_t room;
+  nghttp2_mem *mem;
+
+  mem = context->mem;
+  room = entry_room(nv->name->len, nv->value->len);
+
+  while (context->hd_table_bufsize + room > context->hd_table_bufsize_max &&
+         context->hd_table.len > 0) {
+
+    size_t idx = context->hd_table.len - 1;
+    nghttp2_hd_entry *ent = hd_ringbuf_get(&context->hd_table, idx);
+
+    context->hd_table_bufsize -=
+        entry_room(ent->nv.name->len, ent->nv.value->len);
+
+    DEBUGF("hpack: remove item from header table: %s: %s\n",
+           (char *)ent->nv.name->base, (char *)ent->nv.value->base);
+
+    hd_ringbuf_pop_back(&context->hd_table);
+    if (map) {
+      hd_map_remove(map, ent);
+    }
+
+    nghttp2_hd_entry_free(ent);
+    nghttp2_mem_free(mem, ent);
+  }
+
+  if (room > context->hd_table_bufsize_max) {
+    /* The entry taking more than NGHTTP2_HD_MAX_BUFFER_SIZE is
+       immediately evicted.  So we don't allocate memory for it. */
+    return 0;
+  }
+
+  new_ent = nghttp2_mem_malloc(mem, sizeof(nghttp2_hd_entry));
+  if (new_ent == NULL) {
+    return NGHTTP2_ERR_NOMEM;
+  }
+
+  nghttp2_hd_entry_init(new_ent, nv);
+
+  rv = hd_ringbuf_push_front(&context->hd_table, new_ent, mem);
+
+  if (rv != 0) {
+    nghttp2_hd_entry_free(new_ent);
+    nghttp2_mem_free(mem, new_ent);
+
+    return rv;
+  }
+
+  new_ent->seq = context->next_seq++;
+  new_ent->hash = hash;
+
+  if (map) {
+    hd_map_insert(map, new_ent);
+  }
+
+  context->hd_table_bufsize += room;
+
+  return 0;
+}
+
+typedef struct {
+  ssize_t index;
+  /* Nonzero if both name and value are matched. */
+  int name_value_match;
+} search_result;
+
+static search_result search_static_table(const nghttp2_nv *nv, int32_t token,
+                                         int name_only) {
+  search_result res = {token, 0};
+  int i;
+  const nghttp2_hd_static_entry *ent;
+
+  if (name_only) {
+    return res;
+  }
+
+  for (i = token;
+       i <= NGHTTP2_TOKEN_WWW_AUTHENTICATE && static_table[i].token == token;
+       ++i) {
+    ent = &static_table[i];
+    if (ent->value.len == nv->valuelen &&
+        memcmp(ent->value.base, nv->value, nv->valuelen) == 0) {
+      res.index = i;
+      res.name_value_match = 1;
+      return res;
+    }
+  }
+  return res;
+}
+
+static search_result search_hd_table(nghttp2_hd_context *context,
+                                     const nghttp2_nv *nv, int32_t token,
+                                     int indexing_mode, nghttp2_hd_map *map,
+                                     uint32_t hash) {
+  search_result res = {-1, 0};
+  const nghttp2_hd_entry *ent;
+  int exact_match;
+  int name_only = indexing_mode == NGHTTP2_HD_NEVER_INDEXING;
+
+  exact_match = 0;
+  ent = hd_map_find(map, &exact_match, nv, token, hash, name_only);
+
+  if (!exact_match && token >= 0 && token <= NGHTTP2_TOKEN_WWW_AUTHENTICATE) {
+    return search_static_table(nv, token, name_only);
+  }
+
+  if (ent == NULL) {
+    return res;
+  }
+
+  res.index =
+      (ssize_t)(context->next_seq - 1 - ent->seq + NGHTTP2_STATIC_TABLE_LENGTH);
+  res.name_value_match = exact_match;
+
+  return res;
+}
+
+static void hd_context_shrink_table_size(nghttp2_hd_context *context,
+                                         nghttp2_hd_map *map) {
+  nghttp2_mem *mem;
+
+  mem = context->mem;
+
+  while (context->hd_table_bufsize > context->hd_table_bufsize_max &&
+         context->hd_table.len > 0) {
+    size_t idx = context->hd_table.len - 1;
+    nghttp2_hd_entry *ent = hd_ringbuf_get(&context->hd_table, idx);
+    context->hd_table_bufsize -=
+        entry_room(ent->nv.name->len, ent->nv.value->len);
+    hd_ringbuf_pop_back(&context->hd_table);
+    if (map) {
+      hd_map_remove(map, ent);
+    }
+
+    nghttp2_hd_entry_free(ent);
+    nghttp2_mem_free(mem, ent);
+  }
+}
+
+int nghttp2_hd_deflate_change_table_size(
+    nghttp2_hd_deflater *deflater, size_t settings_max_dynamic_table_size) {
+  size_t next_bufsize = nghttp2_min(settings_max_dynamic_table_size,
+                                    deflater->deflate_hd_table_bufsize_max);
+
+  deflater->ctx.hd_table_bufsize_max = next_bufsize;
+
+  deflater->min_hd_table_bufsize_max =
+      nghttp2_min(deflater->min_hd_table_bufsize_max, next_bufsize);
+
+  deflater->notify_table_size_change = 1;
+
+  hd_context_shrink_table_size(&deflater->ctx, &deflater->map);
+  return 0;
+}
+
+int nghttp2_hd_inflate_change_table_size(
+    nghttp2_hd_inflater *inflater, size_t settings_max_dynamic_table_size) {
+  switch (inflater->state) {
+  case NGHTTP2_HD_STATE_EXPECT_TABLE_SIZE:
+  case NGHTTP2_HD_STATE_INFLATE_START:
+    break;
+  default:
+    return NGHTTP2_ERR_INVALID_STATE;
+  }
+
+  /* It seems that encoder is not required to send dynamic table size
+     update if the table size is not changed after applying
+     SETTINGS_HEADER_TABLE_SIZE.  RFC 7541 is ambiguous here, but this
+     is the intention of the editor.  If new maximum table size is
+     strictly smaller than the current negotiated maximum size,
+     encoder must send dynamic table size update.  In other cases, we
+     cannot expect it to do so. */
+  if (inflater->ctx.hd_table_bufsize_max > settings_max_dynamic_table_size) {
+    inflater->state = NGHTTP2_HD_STATE_EXPECT_TABLE_SIZE;
+    /* Remember minimum value, and validate that encoder sends the
+       value less than or equal to this. */
+    inflater->min_hd_table_bufsize_max = settings_max_dynamic_table_size;
+  }
+
+  inflater->settings_hd_table_bufsize_max = settings_max_dynamic_table_size;
+
+  inflater->ctx.hd_table_bufsize_max = settings_max_dynamic_table_size;
+
+  hd_context_shrink_table_size(&inflater->ctx, NULL);
+  return 0;
+}
+
+#define INDEX_RANGE_VALID(context, idx)                                        \
+  ((idx) < (context)->hd_table.len + NGHTTP2_STATIC_TABLE_LENGTH)
+
+static size_t get_max_index(nghttp2_hd_context *context) {
+  return context->hd_table.len + NGHTTP2_STATIC_TABLE_LENGTH;
+}
+
+nghttp2_hd_nv nghttp2_hd_table_get(nghttp2_hd_context *context, size_t idx) {
+  assert(INDEX_RANGE_VALID(context, idx));
+  if (idx >= NGHTTP2_STATIC_TABLE_LENGTH) {
+    return hd_ringbuf_get(&context->hd_table, idx - NGHTTP2_STATIC_TABLE_LENGTH)
+        ->nv;
+  } else {
+    const nghttp2_hd_static_entry *ent = &static_table[idx];
+    nghttp2_hd_nv nv = {(nghttp2_rcbuf *)&ent->name,
+                        (nghttp2_rcbuf *)&ent->value, ent->token,
+                        NGHTTP2_NV_FLAG_NONE};
+    return nv;
+  }
+}
+
+static const nghttp2_nv *nghttp2_hd_table_get2(nghttp2_hd_context *context,
+                                               size_t idx) {
+  assert(INDEX_RANGE_VALID(context, idx));
+  if (idx >= NGHTTP2_STATIC_TABLE_LENGTH) {
+    return &hd_ringbuf_get(&context->hd_table,
+                           idx - NGHTTP2_STATIC_TABLE_LENGTH)
+                ->cnv;
+  }
+
+  return &static_table[idx].cnv;
+}
+
+static int hd_deflate_decide_indexing(nghttp2_hd_deflater *deflater,
+                                      const nghttp2_nv *nv, int32_t token) {
+  if (token == NGHTTP2_TOKEN__PATH || token == NGHTTP2_TOKEN_AGE ||
+      token == NGHTTP2_TOKEN_CONTENT_LENGTH || token == NGHTTP2_TOKEN_ETAG ||
+      token == NGHTTP2_TOKEN_IF_MODIFIED_SINCE ||
+      token == NGHTTP2_TOKEN_IF_NONE_MATCH || token == NGHTTP2_TOKEN_LOCATION ||
+      token == NGHTTP2_TOKEN_SET_COOKIE ||
+      entry_room(nv->namelen, nv->valuelen) >
+          deflater->ctx.hd_table_bufsize_max * 3 / 4) {
+    return NGHTTP2_HD_WITHOUT_INDEXING;
+  }
+
+  return NGHTTP2_HD_WITH_INDEXING;
+}
+
+static int deflate_nv(nghttp2_hd_deflater *deflater, nghttp2_bufs *bufs,
+                      const nghttp2_nv *nv) {
+  int rv;
+  search_result res;
+  ssize_t idx;
+  int indexing_mode;
+  int32_t token;
+  nghttp2_mem *mem;
+  uint32_t hash = 0;
+
+  DEBUGF("deflatehd: deflating %.*s: %.*s\n", (int)nv->namelen, nv->name,
+         (int)nv->valuelen, nv->value);
+
+  mem = deflater->ctx.mem;
+
+  token = lookup_token(nv->name, nv->namelen);
+  if (token == -1) {
+    hash = name_hash(nv);
+  } else if (token <= NGHTTP2_TOKEN_WWW_AUTHENTICATE) {
+    hash = static_table[token].hash;
+  }
+
+  /* Don't index authorization header field since it may contain low
+     entropy secret data (e.g., id/password).  Also cookie header
+     field with less than 20 bytes value is also never indexed.  This
+     is the same criteria used in Firefox codebase. */
+  indexing_mode =
+      token == NGHTTP2_TOKEN_AUTHORIZATION ||
+              (token == NGHTTP2_TOKEN_COOKIE && nv->valuelen < 20) ||
+              (nv->flags & NGHTTP2_NV_FLAG_NO_INDEX)
+          ? NGHTTP2_HD_NEVER_INDEXING
+          : hd_deflate_decide_indexing(deflater, nv, token);
+
+  res = search_hd_table(&deflater->ctx, nv, token, indexing_mode,
+                        &deflater->map, hash);
+
+  idx = res.index;
+
+  if (res.name_value_match) {
+
+    DEBUGF("deflatehd: name/value match index=%zd\n", idx);
+
+    rv = emit_indexed_block(bufs, (size_t)idx);
+    if (rv != 0) {
+      return rv;
+    }
+
+    return 0;
+  }
+
+  if (res.index != -1) {
+    DEBUGF("deflatehd: name match index=%zd\n", res.index);
+  }
+
+  if (indexing_mode == NGHTTP2_HD_WITH_INDEXING) {
+    nghttp2_hd_nv hd_nv;
+
+    if (idx != -1) {
+      hd_nv.name = nghttp2_hd_table_get(&deflater->ctx, (size_t)idx).name;
+      nghttp2_rcbuf_incref(hd_nv.name);
+    } else {
+      rv = nghttp2_rcbuf_new2(&hd_nv.name, nv->name, nv->namelen, mem);
+      if (rv != 0) {
+        return rv;
+      }
+    }
+
+    rv = nghttp2_rcbuf_new2(&hd_nv.value, nv->value, nv->valuelen, mem);
+
+    if (rv != 0) {
+      nghttp2_rcbuf_decref(hd_nv.name);
+      return rv;
+    }
+
+    hd_nv.token = token;
+    hd_nv.flags = NGHTTP2_NV_FLAG_NONE;
+
+    rv = add_hd_table_incremental(&deflater->ctx, &hd_nv, &deflater->map, hash);
+
+    nghttp2_rcbuf_decref(hd_nv.value);
+    nghttp2_rcbuf_decref(hd_nv.name);
+
+    if (rv != 0) {
+      return NGHTTP2_ERR_HEADER_COMP;
+    }
+  }
+  if (idx == -1) {
+    rv = emit_newname_block(bufs, nv, indexing_mode);
+  } else {
+    rv = emit_indname_block(bufs, (size_t)idx, nv, indexing_mode);
+  }
+  if (rv != 0) {
+    return rv;
+  }
+
+  return 0;
+}
+
+int nghttp2_hd_deflate_hd_bufs(nghttp2_hd_deflater *deflater,
+                               nghttp2_bufs *bufs, const nghttp2_nv *nv,
+                               size_t nvlen) {
+  size_t i;
+  int rv = 0;
+
+  if (deflater->ctx.bad) {
+    return NGHTTP2_ERR_HEADER_COMP;
+  }
+
+  if (deflater->notify_table_size_change) {
+    size_t min_hd_table_bufsize_max;
+
+    min_hd_table_bufsize_max = deflater->min_hd_table_bufsize_max;
+
+    deflater->notify_table_size_change = 0;
+    deflater->min_hd_table_bufsize_max = UINT32_MAX;
+
+    if (deflater->ctx.hd_table_bufsize_max > min_hd_table_bufsize_max) {
+
+      rv = emit_table_size(bufs, min_hd_table_bufsize_max);
+
+      if (rv != 0) {
+        goto fail;
+      }
+    }
+
+    rv = emit_table_size(bufs, deflater->ctx.hd_table_bufsize_max);
+
+    if (rv != 0) {
+      goto fail;
+    }
+  }
+
+  for (i = 0; i < nvlen; ++i) {
+    rv = deflate_nv(deflater, bufs, &nv[i]);
+    if (rv != 0) {
+      goto fail;
+    }
+  }
+
+  DEBUGF("deflatehd: all input name/value pairs were deflated\n");
+
+  return 0;
+fail:
+  DEBUGF("deflatehd: error return %d\n", rv);
+
+  deflater->ctx.bad = 1;
+  return rv;
+}
+
+ssize_t nghttp2_hd_deflate_hd(nghttp2_hd_deflater *deflater, uint8_t *buf,
+                              size_t buflen, const nghttp2_nv *nv,
+                              size_t nvlen) {
+  nghttp2_bufs bufs;
+  int rv;
+  nghttp2_mem *mem;
+
+  mem = deflater->ctx.mem;
+
+  rv = nghttp2_bufs_wrap_init(&bufs, buf, buflen, mem);
+
+  if (rv != 0) {
+    return rv;
+  }
+
+  rv = nghttp2_hd_deflate_hd_bufs(deflater, &bufs, nv, nvlen);
+
+  buflen = nghttp2_bufs_len(&bufs);
+
+  nghttp2_bufs_wrap_free(&bufs);
+
+  if (rv == NGHTTP2_ERR_BUFFER_ERROR) {
+    return NGHTTP2_ERR_INSUFF_BUFSIZE;
+  }
+
+  if (rv != 0) {
+    return rv;
+  }
+
+  return (ssize_t)buflen;
+}
+
+ssize_t nghttp2_hd_deflate_hd_vec(nghttp2_hd_deflater *deflater,
+                                  const nghttp2_vec *vec, size_t veclen,
+                                  const nghttp2_nv *nv, size_t nvlen) {
+  nghttp2_bufs bufs;
+  int rv;
+  nghttp2_mem *mem;
+  size_t buflen;
+
+  mem = deflater->ctx.mem;
+
+  rv = nghttp2_bufs_wrap_init2(&bufs, vec, veclen, mem);
+
+  if (rv != 0) {
+    return rv;
+  }
+
+  rv = nghttp2_hd_deflate_hd_bufs(deflater, &bufs, nv, nvlen);
+
+  buflen = nghttp2_bufs_len(&bufs);
+
+  nghttp2_bufs_wrap_free(&bufs);
+
+  if (rv == NGHTTP2_ERR_BUFFER_ERROR) {
+    return NGHTTP2_ERR_INSUFF_BUFSIZE;
+  }
+
+  if (rv != 0) {
+    return rv;
+  }
+
+  return (ssize_t)buflen;
+}
+
+size_t nghttp2_hd_deflate_bound(nghttp2_hd_deflater *deflater,
+                                const nghttp2_nv *nva, size_t nvlen) {
+  size_t n = 0;
+  size_t i;
+  (void)deflater;
+
+  /* Possible Maximum Header Table Size Change.  Encoding (1u << 31) -
+     1 using 4 bit prefix requires 6 bytes.  We may emit this at most
+     twice. */
+  n += 12;
+
+  /* Use Literal Header Field without indexing - New Name, since it is
+     most space consuming format.  Also we choose the less one between
+     non-huffman and huffman, so using literal byte count is
+     sufficient for upper bound.
+
+     Encoding (1u << 31) - 1 using 7 bit prefix requires 6 bytes.  We
+     need 2 of this for |nvlen| header fields. */
+  n += 6 * 2 * nvlen;
+
+  for (i = 0; i < nvlen; ++i) {
+    n += nva[i].namelen + nva[i].valuelen;
+  }
+
+  return n;
+}
+
+int nghttp2_hd_deflate_new(nghttp2_hd_deflater **deflater_ptr,
+                           size_t deflate_hd_table_bufsize_max) {
+  return nghttp2_hd_deflate_new2(deflater_ptr, deflate_hd_table_bufsize_max,
+                                 NULL);
+}
+
+int nghttp2_hd_deflate_new2(nghttp2_hd_deflater **deflater_ptr,
+                            size_t deflate_hd_table_bufsize_max,
+                            nghttp2_mem *mem) {
+  int rv;
+  nghttp2_hd_deflater *deflater;
+
+  if (mem == NULL) {
+    mem = nghttp2_mem_default();
+  }
+
+  deflater = nghttp2_mem_malloc(mem, sizeof(nghttp2_hd_deflater));
+
+  if (deflater == NULL) {
+    return NGHTTP2_ERR_NOMEM;
+  }
+
+  rv = nghttp2_hd_deflate_init2(deflater, deflate_hd_table_bufsize_max, mem);
+
+  if (rv != 0) {
+    nghttp2_mem_free(mem, deflater);
+
+    return rv;
+  }
+
+  *deflater_ptr = deflater;
+
+  return 0;
+}
+
+void nghttp2_hd_deflate_del(nghttp2_hd_deflater *deflater) {
+  nghttp2_mem *mem;
+
+  mem = deflater->ctx.mem;
+
+  nghttp2_hd_deflate_free(deflater);
+
+  nghttp2_mem_free(mem, deflater);
+}
+
+static void hd_inflate_set_huffman_encoded(nghttp2_hd_inflater *inflater,
+                                           const uint8_t *in) {
+  inflater->huffman_encoded = (*in & (1 << 7)) != 0;
+}
+
+/*
+ * Decodes the integer from the range [in, last).  The result is
+ * assigned to |inflater->left|.  If the |inflater->left| is 0, then
+ * it performs variable integer decoding from scratch. Otherwise, it
+ * uses the |inflater->left| as the initial value and continues to
+ * decode assuming that [in, last) begins with intermediary sequence.
+ *
+ * This function returns the number of bytes read if it succeeds, or
+ * one of the following negative error codes:
+ *
+ * NGHTTP2_ERR_HEADER_COMP
+ *   Integer decoding failed
+ */
+static ssize_t hd_inflate_read_len(nghttp2_hd_inflater *inflater, int *rfin,
+                                   const uint8_t *in, const uint8_t *last,
+                                   size_t prefix, size_t maxlen) {
+  ssize_t rv;
+  uint32_t out;
+
+  *rfin = 0;
+
+  rv = decode_length(&out, &inflater->shift, rfin, (uint32_t)inflater->left,
+                     inflater->shift, in, last, prefix);
+
+  if (rv == -1) {
+    DEBUGF("inflatehd: integer decoding failed\n");
+    return NGHTTP2_ERR_HEADER_COMP;
+  }
+
+  if (out > maxlen) {
+    DEBUGF("inflatehd: integer exceeded the maximum value %zu\n", maxlen);
+    return NGHTTP2_ERR_HEADER_COMP;
+  }
+
+  inflater->left = out;
+
+  DEBUGF("inflatehd: decoded integer is %u\n", out);
+
+  return rv;
+}
+
+/*
+ * Reads |inflater->left| bytes from the range [in, last) and performs
+ * huffman decoding against them and pushes the result into the
+ * |buffer|.
+ *
+ * This function returns the number of bytes read if it succeeds, or
+ * one of the following negative error codes:
+ *
+ * NGHTTP2_ERR_NOMEM
+ *   Out of memory
+ * NGHTTP2_ERR_HEADER_COMP
+ *   Huffman decoding failed
+ */
+static ssize_t hd_inflate_read_huff(nghttp2_hd_inflater *inflater,
+                                    nghttp2_buf *buf, const uint8_t *in,
+                                    const uint8_t *last) {
+  ssize_t readlen;
+  int fin = 0;
+  if ((size_t)(last - in) >= inflater->left) {
+    last = in + inflater->left;
+    fin = 1;
+  }
+  readlen = nghttp2_hd_huff_decode(&inflater->huff_decode_ctx, buf, in,
+                                   (size_t)(last - in), fin);
+
+  if (readlen < 0) {
+    DEBUGF("inflatehd: huffman decoding failed\n");
+    return readlen;
+  }
+  if (nghttp2_hd_huff_decode_failure_state(&inflater->huff_decode_ctx)) {
+    DEBUGF("inflatehd: huffman decoding failed\n");
+    return NGHTTP2_ERR_HEADER_COMP;
+  }
+
+  inflater->left -= (size_t)readlen;
+  return readlen;
+}
+
+/*
+ * Reads |inflater->left| bytes from the range [in, last) and copies
+ * them into the |buffer|.
+ *
+ * This function returns the number of bytes read if it succeeds, or
+ * one of the following negative error codes:
+ *
+ * NGHTTP2_ERR_NOMEM
+ *   Out of memory
+ * NGHTTP2_ERR_HEADER_COMP
+ *   Header decompression failed
+ */
+static ssize_t hd_inflate_read(nghttp2_hd_inflater *inflater, nghttp2_buf *buf,
+                               const uint8_t *in, const uint8_t *last) {
+  size_t len = nghttp2_min((size_t)(last - in), inflater->left);
+
+  buf->last = nghttp2_cpymem(buf->last, in, len);
+
+  inflater->left -= len;
+  return (ssize_t)len;
+}
+
+/*
+ * Finalize indexed header representation reception.  The referenced
+ * header is always emitted, and |*nv_out| is filled with that value.
+ */
+static void hd_inflate_commit_indexed(nghttp2_hd_inflater *inflater,
+                                      nghttp2_hd_nv *nv_out) {
+  nghttp2_hd_nv nv = nghttp2_hd_table_get(&inflater->ctx, inflater->index);
+
+  emit_header(nv_out, &nv);
+}
+
+/*
+ * Finalize literal header representation - new name- reception. If
+ * header is emitted, |*nv_out| is filled with that value and 0 is
+ * returned.
+ *
+ * This function returns 0 if it succeeds, or one of the following
+ * negative error codes:
+ *
+ * NGHTTP2_ERR_NOMEM
+ *   Out of memory
+ */
+static int hd_inflate_commit_newname(nghttp2_hd_inflater *inflater,
+                                     nghttp2_hd_nv *nv_out) {
+  nghttp2_hd_nv nv;
+  int rv;
+
+  if (inflater->no_index) {
+    nv.flags = NGHTTP2_NV_FLAG_NO_INDEX;
+  } else {
+    nv.flags = NGHTTP2_NV_FLAG_NONE;
+  }
+
+  nv.name = inflater->namercbuf;
+  nv.value = inflater->valuercbuf;
+  nv.token = lookup_token(inflater->namercbuf->base, inflater->namercbuf->len);
+
+  if (inflater->index_required) {
+    rv = add_hd_table_incremental(&inflater->ctx, &nv, NULL, 0);
+
+    if (rv != 0) {
+      return rv;
+    }
+  }
+
+  emit_header(nv_out, &nv);
+
+  inflater->nv_name_keep = nv.name;
+  inflater->nv_value_keep = nv.value;
+
+  inflater->namercbuf = NULL;
+  inflater->valuercbuf = NULL;
+
+  return 0;
+}
+
+/*
+ * Finalize literal header representation - indexed name-
+ * reception. If header is emitted, |*nv_out| is filled with that
+ * value and 0 is returned.
+ *
+ * This function returns 0 if it succeeds, or one of the following
+ * negative error codes:
+ *
+ * NGHTTP2_ERR_NOMEM
+ *   Out of memory
+ */
+static int hd_inflate_commit_indname(nghttp2_hd_inflater *inflater,
+                                     nghttp2_hd_nv *nv_out) {
+  nghttp2_hd_nv nv;
+  int rv;
+
+  nv = nghttp2_hd_table_get(&inflater->ctx, inflater->index);
+
+  if (inflater->no_index) {
+    nv.flags = NGHTTP2_NV_FLAG_NO_INDEX;
+  } else {
+    nv.flags = NGHTTP2_NV_FLAG_NONE;
+  }
+
+  nghttp2_rcbuf_incref(nv.name);
+
+  nv.value = inflater->valuercbuf;
+
+  if (inflater->index_required) {
+    rv = add_hd_table_incremental(&inflater->ctx, &nv, NULL, 0);
+    if (rv != 0) {
+      nghttp2_rcbuf_decref(nv.name);
+      return NGHTTP2_ERR_NOMEM;
+    }
+  }
+
+  emit_header(nv_out, &nv);
+
+  inflater->nv_name_keep = nv.name;
+  inflater->nv_value_keep = nv.value;
+
+  inflater->valuercbuf = NULL;
+
+  return 0;
+}
+
+ssize_t nghttp2_hd_inflate_hd(nghttp2_hd_inflater *inflater, nghttp2_nv *nv_out,
+                              int *inflate_flags, uint8_t *in, size_t inlen,
+                              int in_final) {
+  return nghttp2_hd_inflate_hd2(inflater, nv_out, inflate_flags, in, inlen,
+                                in_final);
+}
+
+ssize_t nghttp2_hd_inflate_hd2(nghttp2_hd_inflater *inflater,
+                               nghttp2_nv *nv_out, int *inflate_flags,
+                               const uint8_t *in, size_t inlen, int in_final) {
+  ssize_t rv;
+  nghttp2_hd_nv hd_nv;
+
+  rv = nghttp2_hd_inflate_hd_nv(inflater, &hd_nv, inflate_flags, in, inlen,
+                                in_final);
+
+  if (rv < 0) {
+    return rv;
+  }
+
+  if (*inflate_flags & NGHTTP2_HD_INFLATE_EMIT) {
+    nv_out->name = hd_nv.name->base;
+    nv_out->namelen = hd_nv.name->len;
+
+    nv_out->value = hd_nv.value->base;
+    nv_out->valuelen = hd_nv.value->len;
+
+    nv_out->flags = hd_nv.flags;
+  }
+
+  return rv;
+}
+
+ssize_t nghttp2_hd_inflate_hd_nv(nghttp2_hd_inflater *inflater,
+                                 nghttp2_hd_nv *nv_out, int *inflate_flags,
+                                 const uint8_t *in, size_t inlen,
+                                 int in_final) {
+  ssize_t rv = 0;
+  const uint8_t *first = in;
+  const uint8_t *last = in + inlen;
+  int rfin = 0;
+  int busy = 0;
+  nghttp2_mem *mem;
+
+  mem = inflater->ctx.mem;
+
+  if (inflater->ctx.bad) {
+    return NGHTTP2_ERR_HEADER_COMP;
+  }
+
+  DEBUGF("inflatehd: start state=%d\n", inflater->state);
+  hd_inflate_keep_free(inflater);
+  *inflate_flags = NGHTTP2_HD_INFLATE_NONE;
+  for (; in != last || busy;) {
+    busy = 0;
+    switch (inflater->state) {
+    case NGHTTP2_HD_STATE_EXPECT_TABLE_SIZE:
+      if ((*in & 0xe0u) != 0x20u) {
+        DEBUGF("inflatehd: header table size change was expected, but saw "
+               "0x%02x as first byte",
+               *in);
+        rv = NGHTTP2_ERR_HEADER_COMP;
+        goto fail;
+      }
+    /* fall through */
+    case NGHTTP2_HD_STATE_INFLATE_START:
+    case NGHTTP2_HD_STATE_OPCODE:
+      if ((*in & 0xe0u) == 0x20u) {
+        DEBUGF("inflatehd: header table size change\n");
+        if (inflater->state == NGHTTP2_HD_STATE_OPCODE) {
+          DEBUGF("inflatehd: header table size change must appear at the head "
+                 "of header block\n");
+          rv = NGHTTP2_ERR_HEADER_COMP;
+          goto fail;
+        }
+        inflater->opcode = NGHTTP2_HD_OPCODE_INDEXED;
+        inflater->state = NGHTTP2_HD_STATE_READ_TABLE_SIZE;
+      } else if (*in & 0x80u) {
+        DEBUGF("inflatehd: indexed repr\n");
+        inflater->opcode = NGHTTP2_HD_OPCODE_INDEXED;
+        inflater->state = NGHTTP2_HD_STATE_READ_INDEX;
+      } else {
+        if (*in == 0x40u || *in == 0 || *in == 0x10u) {
+          DEBUGF("inflatehd: literal header repr - new name\n");
+          inflater->opcode = NGHTTP2_HD_OPCODE_NEWNAME;
+          inflater->state = NGHTTP2_HD_STATE_NEWNAME_CHECK_NAMELEN;
+        } else {
+          DEBUGF("inflatehd: literal header repr - indexed name\n");
+          inflater->opcode = NGHTTP2_HD_OPCODE_INDNAME;
+          inflater->state = NGHTTP2_HD_STATE_READ_INDEX;
+        }
+        inflater->index_required = (*in & 0x40) != 0;
+        inflater->no_index = (*in & 0xf0u) == 0x10u;
+        DEBUGF("inflatehd: indexing required=%d, no_index=%d\n",
+               inflater->index_required, inflater->no_index);
+        if (inflater->opcode == NGHTTP2_HD_OPCODE_NEWNAME) {
+          ++in;
+        }
+      }
+      inflater->left = 0;
+      inflater->shift = 0;
+      break;
+    case NGHTTP2_HD_STATE_READ_TABLE_SIZE:
+      rfin = 0;
+      rv = hd_inflate_read_len(
+          inflater, &rfin, in, last, 5,
+          nghttp2_min(inflater->min_hd_table_bufsize_max,
+                      inflater->settings_hd_table_bufsize_max));
+      if (rv < 0) {
+        goto fail;
+      }
+      in += rv;
+      if (!rfin) {
+        goto almost_ok;
+      }
+      DEBUGF("inflatehd: table_size=%zu\n", inflater->left);
+      inflater->min_hd_table_bufsize_max = UINT32_MAX;
+      inflater->ctx.hd_table_bufsize_max = inflater->left;
+      hd_context_shrink_table_size(&inflater->ctx, NULL);
+      inflater->state = NGHTTP2_HD_STATE_INFLATE_START;
+      break;
+    case NGHTTP2_HD_STATE_READ_INDEX: {
+      size_t prefixlen;
+
+      if (inflater->opcode == NGHTTP2_HD_OPCODE_INDEXED) {
+        prefixlen = 7;
+      } else if (inflater->index_required) {
+        prefixlen = 6;
+      } else {
+        prefixlen = 4;
+      }
+
+      rfin = 0;
+      rv = hd_inflate_read_len(inflater, &rfin, in, last, prefixlen,
+                               get_max_index(&inflater->ctx));
+      if (rv < 0) {
+        goto fail;
+      }
+
+      in += rv;
+
+      if (!rfin) {
+        goto almost_ok;
+      }
+
+      if (inflater->left == 0) {
+        rv = NGHTTP2_ERR_HEADER_COMP;
+        goto fail;
+      }
+
+      DEBUGF("inflatehd: index=%zu\n", inflater->left);
+      if (inflater->opcode == NGHTTP2_HD_OPCODE_INDEXED) {
+        inflater->index = inflater->left;
+        --inflater->index;
+
+        hd_inflate_commit_indexed(inflater, nv_out);
+
+        inflater->state = NGHTTP2_HD_STATE_OPCODE;
+        *inflate_flags |= NGHTTP2_HD_INFLATE_EMIT;
+        return (ssize_t)(in - first);
+      } else {
+        inflater->index = inflater->left;
+        --inflater->index;
+
+        inflater->state = NGHTTP2_HD_STATE_CHECK_VALUELEN;
+      }
+      break;
+    }
+    case NGHTTP2_HD_STATE_NEWNAME_CHECK_NAMELEN:
+      hd_inflate_set_huffman_encoded(inflater, in);
+      inflater->state = NGHTTP2_HD_STATE_NEWNAME_READ_NAMELEN;
+      inflater->left = 0;
+      inflater->shift = 0;
+      DEBUGF("inflatehd: huffman encoded=%d\n", inflater->huffman_encoded != 0);
+    /* Fall through */
+    case NGHTTP2_HD_STATE_NEWNAME_READ_NAMELEN:
+      rfin = 0;
+      rv = hd_inflate_read_len(inflater, &rfin, in, last, 7, NGHTTP2_HD_MAX_NV);
+      if (rv < 0) {
+        goto fail;
+      }
+      in += rv;
+      if (!rfin) {
+        DEBUGF("inflatehd: integer not fully decoded. current=%zu\n",
+               inflater->left);
+
+        goto almost_ok;
+      }
+
+      if (inflater->huffman_encoded) {
+        nghttp2_hd_huff_decode_context_init(&inflater->huff_decode_ctx);
+
+        inflater->state = NGHTTP2_HD_STATE_NEWNAME_READ_NAMEHUFF;
+
+        rv = nghttp2_rcbuf_new(&inflater->namercbuf, inflater->left * 2 + 1,
+                               mem);
+      } else {
+        inflater->state = NGHTTP2_HD_STATE_NEWNAME_READ_NAME;
+        rv = nghttp2_rcbuf_new(&inflater->namercbuf, inflater->left + 1, mem);
+      }
+
+      if (rv != 0) {
+        goto fail;
+      }
+
+      nghttp2_buf_wrap_init(&inflater->namebuf, inflater->namercbuf->base,
+                            inflater->namercbuf->len);
+
+      break;
+    case NGHTTP2_HD_STATE_NEWNAME_READ_NAMEHUFF:
+      rv = hd_inflate_read_huff(inflater, &inflater->namebuf, in, last);
+      if (rv < 0) {
+        goto fail;
+      }
+
+      in += rv;
+
+      DEBUGF("inflatehd: %zd bytes read\n", rv);
+
+      if (inflater->left) {
+        DEBUGF("inflatehd: still %zu bytes to go\n", inflater->left);
+
+        goto almost_ok;
+      }
+
+      *inflater->namebuf.last = '\0';
+      inflater->namercbuf->len = nghttp2_buf_len(&inflater->namebuf);
+
+      inflater->state = NGHTTP2_HD_STATE_CHECK_VALUELEN;
+
+      break;
+    case NGHTTP2_HD_STATE_NEWNAME_READ_NAME:
+      rv = hd_inflate_read(inflater, &inflater->namebuf, in, last);
+      if (rv < 0) {
+        goto fail;
+      }
+
+      in += rv;
+
+      DEBUGF("inflatehd: %zd bytes read\n", rv);
+      if (inflater->left) {
+        DEBUGF("inflatehd: still %zu bytes to go\n", inflater->left);
+
+        goto almost_ok;
+      }
+
+      *inflater->namebuf.last = '\0';
+      inflater->namercbuf->len = nghttp2_buf_len(&inflater->namebuf);
+
+      inflater->state = NGHTTP2_HD_STATE_CHECK_VALUELEN;
+
+      break;
+    case NGHTTP2_HD_STATE_CHECK_VALUELEN:
+      hd_inflate_set_huffman_encoded(inflater, in);
+      inflater->state = NGHTTP2_HD_STATE_READ_VALUELEN;
+      inflater->left = 0;
+      inflater->shift = 0;
+      DEBUGF("inflatehd: huffman encoded=%d\n", inflater->huffman_encoded != 0);
+    /* Fall through */
+    case NGHTTP2_HD_STATE_READ_VALUELEN:
+      rfin = 0;
+      rv = hd_inflate_read_len(inflater, &rfin, in, last, 7, NGHTTP2_HD_MAX_NV);
+      if (rv < 0) {
+        goto fail;
+      }
+
+      in += rv;
+
+      if (!rfin) {
+        goto almost_ok;
+      }
+
+      DEBUGF("inflatehd: valuelen=%zu\n", inflater->left);
+
+      if (inflater->huffman_encoded) {
+        nghttp2_hd_huff_decode_context_init(&inflater->huff_decode_ctx);
+
+        inflater->state = NGHTTP2_HD_STATE_READ_VALUEHUFF;
+
+        rv = nghttp2_rcbuf_new(&inflater->valuercbuf, inflater->left * 2 + 1,
+                               mem);
+      } else {
+        inflater->state = NGHTTP2_HD_STATE_READ_VALUE;
+
+        rv = nghttp2_rcbuf_new(&inflater->valuercbuf, inflater->left + 1, mem);
+      }
+
+      if (rv != 0) {
+        goto fail;
+      }
+
+      nghttp2_buf_wrap_init(&inflater->valuebuf, inflater->valuercbuf->base,
+                            inflater->valuercbuf->len);
+
+      busy = 1;
+
+      break;
+    case NGHTTP2_HD_STATE_READ_VALUEHUFF:
+      rv = hd_inflate_read_huff(inflater, &inflater->valuebuf, in, last);
+      if (rv < 0) {
+        goto fail;
+      }
+
+      in += rv;
+
+      DEBUGF("inflatehd: %zd bytes read\n", rv);
+
+      if (inflater->left) {
+        DEBUGF("inflatehd: still %zu bytes to go\n", inflater->left);
+
+        goto almost_ok;
+      }
+
+      *inflater->valuebuf.last = '\0';
+      inflater->valuercbuf->len = nghttp2_buf_len(&inflater->valuebuf);
+
+      if (inflater->opcode == NGHTTP2_HD_OPCODE_NEWNAME) {
+        rv = hd_inflate_commit_newname(inflater, nv_out);
+      } else {
+        rv = hd_inflate_commit_indname(inflater, nv_out);
+      }
+
+      if (rv != 0) {
+        goto fail;
+      }
+
+      inflater->state = NGHTTP2_HD_STATE_OPCODE;
+      *inflate_flags |= NGHTTP2_HD_INFLATE_EMIT;
+
+      return (ssize_t)(in - first);
+    case NGHTTP2_HD_STATE_READ_VALUE:
+      rv = hd_inflate_read(inflater, &inflater->valuebuf, in, last);
+      if (rv < 0) {
+        DEBUGF("inflatehd: value read failure %zd: %s\n", rv,
+               nghttp2_strerror((int)rv));
+        goto fail;
+      }
+
+      in += rv;
+
+      DEBUGF("inflatehd: %zd bytes read\n", rv);
+
+      if (inflater->left) {
+        DEBUGF("inflatehd: still %zu bytes to go\n", inflater->left);
+        goto almost_ok;
+      }
+
+      *inflater->valuebuf.last = '\0';
+      inflater->valuercbuf->len = nghttp2_buf_len(&inflater->valuebuf);
+
+      if (inflater->opcode == NGHTTP2_HD_OPCODE_NEWNAME) {
+        rv = hd_inflate_commit_newname(inflater, nv_out);
+      } else {
+        rv = hd_inflate_commit_indname(inflater, nv_out);
+      }
+
+      if (rv != 0) {
+        goto fail;
+      }
+
+      inflater->state = NGHTTP2_HD_STATE_OPCODE;
+      *inflate_flags |= NGHTTP2_HD_INFLATE_EMIT;
+
+      return (ssize_t)(in - first);
+    }
+  }
+
+  assert(in == last);
+
+  DEBUGF("inflatehd: all input bytes were processed\n");
+
+  if (in_final) {
+    DEBUGF("inflatehd: in_final set\n");
+
+    if (inflater->state != NGHTTP2_HD_STATE_OPCODE &&
+        inflater->state != NGHTTP2_HD_STATE_INFLATE_START) {
+      DEBUGF("inflatehd: unacceptable state=%d\n", inflater->state);
+      rv = NGHTTP2_ERR_HEADER_COMP;
+
+      goto fail;
+    }
+    *inflate_flags |= NGHTTP2_HD_INFLATE_FINAL;
+  }
+  return (ssize_t)(in - first);
+
+almost_ok:
+  if (in_final) {
+    DEBUGF("inflatehd: input ended prematurely\n");
+
+    rv = NGHTTP2_ERR_HEADER_COMP;
+
+    goto fail;
+  }
+  return (ssize_t)(in - first);
+
+fail:
+  DEBUGF("inflatehd: error return %zd\n", rv);
+
+  inflater->ctx.bad = 1;
+  return rv;
+}
+
+int nghttp2_hd_inflate_end_headers(nghttp2_hd_inflater *inflater) {
+  hd_inflate_keep_free(inflater);
+  inflater->state = NGHTTP2_HD_STATE_INFLATE_START;
+  return 0;
+}
+
+int nghttp2_hd_inflate_new(nghttp2_hd_inflater **inflater_ptr) {
+  return nghttp2_hd_inflate_new2(inflater_ptr, NULL);
+}
+
+int nghttp2_hd_inflate_new2(nghttp2_hd_inflater **inflater_ptr,
+                            nghttp2_mem *mem) {
+  int rv;
+  nghttp2_hd_inflater *inflater;
+
+  if (mem == NULL) {
+    mem = nghttp2_mem_default();
+  }
+
+  inflater = nghttp2_mem_malloc(mem, sizeof(nghttp2_hd_inflater));
+
+  if (inflater == NULL) {
+    return NGHTTP2_ERR_NOMEM;
+  }
+
+  rv = nghttp2_hd_inflate_init(inflater, mem);
+
+  if (rv != 0) {
+    nghttp2_mem_free(mem, inflater);
+
+    return rv;
+  }
+
+  *inflater_ptr = inflater;
+
+  return 0;
+}
+
+void nghttp2_hd_inflate_del(nghttp2_hd_inflater *inflater) {
+  nghttp2_mem *mem;
+
+  mem = inflater->ctx.mem;
+  nghttp2_hd_inflate_free(inflater);
+
+  nghttp2_mem_free(mem, inflater);
+}
+
+int nghttp2_hd_emit_indname_block(nghttp2_bufs *bufs, size_t idx,
+                                  nghttp2_nv *nv, int indexing_mode) {
+
+  return emit_indname_block(bufs, idx, nv, indexing_mode);
+}
+
+int nghttp2_hd_emit_newname_block(nghttp2_bufs *bufs, nghttp2_nv *nv,
+                                  int indexing_mode) {
+  return emit_newname_block(bufs, nv, indexing_mode);
+}
+
+int nghttp2_hd_emit_table_size(nghttp2_bufs *bufs, size_t table_size) {
+  return emit_table_size(bufs, table_size);
+}
+
+ssize_t nghttp2_hd_decode_length(uint32_t *res, size_t *shift_ptr, int *fin,
+                                 uint32_t initial, size_t shift, uint8_t *in,
+                                 uint8_t *last, size_t prefix) {
+  return decode_length(res, shift_ptr, fin, initial, shift, in, last, prefix);
+}
+
+static const nghttp2_nv *hd_get_table_entry(nghttp2_hd_context *context,
+                                            size_t idx) {
+  if (idx == 0) {
+    return NULL;
+  }
+
+  --idx;
+
+  if (!INDEX_RANGE_VALID(context, idx)) {
+    return NULL;
+  }
+
+  return nghttp2_hd_table_get2(context, idx);
+}
+
+size_t nghttp2_hd_deflate_get_num_table_entries(nghttp2_hd_deflater *deflater) {
+  return get_max_index(&deflater->ctx);
+}
+
+const nghttp2_nv *
+nghttp2_hd_deflate_get_table_entry(nghttp2_hd_deflater *deflater, size_t idx) {
+  return hd_get_table_entry(&deflater->ctx, idx);
+}
+
+size_t
+nghttp2_hd_deflate_get_dynamic_table_size(nghttp2_hd_deflater *deflater) {
+  return deflater->ctx.hd_table_bufsize;
+}
+
+size_t
+nghttp2_hd_deflate_get_max_dynamic_table_size(nghttp2_hd_deflater *deflater) {
+  return deflater->ctx.hd_table_bufsize_max;
+}
+
+size_t nghttp2_hd_inflate_get_num_table_entries(nghttp2_hd_inflater *inflater) {
+  return get_max_index(&inflater->ctx);
+}
+
+const nghttp2_nv *
+nghttp2_hd_inflate_get_table_entry(nghttp2_hd_inflater *inflater, size_t idx) {
+  return hd_get_table_entry(&inflater->ctx, idx);
+}
+
+size_t
+nghttp2_hd_inflate_get_dynamic_table_size(nghttp2_hd_inflater *inflater) {
+  return inflater->ctx.hd_table_bufsize;
+}
+
+size_t
+nghttp2_hd_inflate_get_max_dynamic_table_size(nghttp2_hd_inflater *inflater) {
+  return inflater->ctx.hd_table_bufsize_max;
+}
diff --git a/Utilities/cmnghttp2/lib/nghttp2_hd.h b/Utilities/cmnghttp2/lib/nghttp2_hd.h
new file mode 100644
index 0000000..2674028
--- /dev/null
+++ b/Utilities/cmnghttp2/lib/nghttp2_hd.h
@@ -0,0 +1,439 @@
+/*
+ * nghttp2 - HTTP/2 C Library
+ *
+ * Copyright (c) 2013 Tatsuhiro Tsujikawa
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+#ifndef NGHTTP2_HD_H
+#define NGHTTP2_HD_H
+
+#ifdef HAVE_CONFIG_H
+#  include <config.h>
+#endif /* HAVE_CONFIG_H */
+
+#include <nghttp2/nghttp2.h>
+
+#include "nghttp2_hd_huffman.h"
+#include "nghttp2_buf.h"
+#include "nghttp2_mem.h"
+#include "nghttp2_rcbuf.h"
+
+#define NGHTTP2_HD_DEFAULT_MAX_BUFFER_SIZE NGHTTP2_DEFAULT_HEADER_TABLE_SIZE
+#define NGHTTP2_HD_ENTRY_OVERHEAD 32
+
+/* The maximum length of one name/value pair.  This is the sum of the
+   length of name and value.  This is not specified by the spec. We
+   just chose the arbitrary size */
+#define NGHTTP2_HD_MAX_NV 65536
+
+/* Default size of maximum table buffer size for encoder. Even if
+   remote decoder notifies larger buffer size for its decoding,
+   encoder only uses the memory up to this value. */
+#define NGHTTP2_HD_DEFAULT_MAX_DEFLATE_BUFFER_SIZE (1 << 12)
+
+/* Exported for unit test */
+#define NGHTTP2_STATIC_TABLE_LENGTH 61
+
+/* Generated by genlibtokenlookup.py */
+typedef enum {
+  NGHTTP2_TOKEN__AUTHORITY = 0,
+  NGHTTP2_TOKEN__METHOD = 1,
+  NGHTTP2_TOKEN__PATH = 3,
+  NGHTTP2_TOKEN__SCHEME = 5,
+  NGHTTP2_TOKEN__STATUS = 7,
+  NGHTTP2_TOKEN_ACCEPT_CHARSET = 14,
+  NGHTTP2_TOKEN_ACCEPT_ENCODING = 15,
+  NGHTTP2_TOKEN_ACCEPT_LANGUAGE = 16,
+  NGHTTP2_TOKEN_ACCEPT_RANGES = 17,
+  NGHTTP2_TOKEN_ACCEPT = 18,
+  NGHTTP2_TOKEN_ACCESS_CONTROL_ALLOW_ORIGIN = 19,
+  NGHTTP2_TOKEN_AGE = 20,
+  NGHTTP2_TOKEN_ALLOW = 21,
+  NGHTTP2_TOKEN_AUTHORIZATION = 22,
+  NGHTTP2_TOKEN_CACHE_CONTROL = 23,
+  NGHTTP2_TOKEN_CONTENT_DISPOSITION = 24,
+  NGHTTP2_TOKEN_CONTENT_ENCODING = 25,
+  NGHTTP2_TOKEN_CONTENT_LANGUAGE = 26,
+  NGHTTP2_TOKEN_CONTENT_LENGTH = 27,
+  NGHTTP2_TOKEN_CONTENT_LOCATION = 28,
+  NGHTTP2_TOKEN_CONTENT_RANGE = 29,
+  NGHTTP2_TOKEN_CONTENT_TYPE = 30,
+  NGHTTP2_TOKEN_COOKIE = 31,
+  NGHTTP2_TOKEN_DATE = 32,
+  NGHTTP2_TOKEN_ETAG = 33,
+  NGHTTP2_TOKEN_EXPECT = 34,
+  NGHTTP2_TOKEN_EXPIRES = 35,
+  NGHTTP2_TOKEN_FROM = 36,
+  NGHTTP2_TOKEN_HOST = 37,
+  NGHTTP2_TOKEN_IF_MATCH = 38,
+  NGHTTP2_TOKEN_IF_MODIFIED_SINCE = 39,
+  NGHTTP2_TOKEN_IF_NONE_MATCH = 40,
+  NGHTTP2_TOKEN_IF_RANGE = 41,
+  NGHTTP2_TOKEN_IF_UNMODIFIED_SINCE = 42,
+  NGHTTP2_TOKEN_LAST_MODIFIED = 43,
+  NGHTTP2_TOKEN_LINK = 44,
+  NGHTTP2_TOKEN_LOCATION = 45,
+  NGHTTP2_TOKEN_MAX_FORWARDS = 46,
+  NGHTTP2_TOKEN_PROXY_AUTHENTICATE = 47,
+  NGHTTP2_TOKEN_PROXY_AUTHORIZATION = 48,
+  NGHTTP2_TOKEN_RANGE = 49,
+  NGHTTP2_TOKEN_REFERER = 50,
+  NGHTTP2_TOKEN_REFRESH = 51,
+  NGHTTP2_TOKEN_RETRY_AFTER = 52,
+  NGHTTP2_TOKEN_SERVER = 53,
+  NGHTTP2_TOKEN_SET_COOKIE = 54,
+  NGHTTP2_TOKEN_STRICT_TRANSPORT_SECURITY = 55,
+  NGHTTP2_TOKEN_TRANSFER_ENCODING = 56,
+  NGHTTP2_TOKEN_USER_AGENT = 57,
+  NGHTTP2_TOKEN_VARY = 58,
+  NGHTTP2_TOKEN_VIA = 59,
+  NGHTTP2_TOKEN_WWW_AUTHENTICATE = 60,
+  NGHTTP2_TOKEN_TE,
+  NGHTTP2_TOKEN_CONNECTION,
+  NGHTTP2_TOKEN_KEEP_ALIVE,
+  NGHTTP2_TOKEN_PROXY_CONNECTION,
+  NGHTTP2_TOKEN_UPGRADE,
+  NGHTTP2_TOKEN__PROTOCOL,
+} nghttp2_token;
+
+struct nghttp2_hd_entry;
+typedef struct nghttp2_hd_entry nghttp2_hd_entry;
+
+typedef struct {
+  /* The buffer containing header field name.  NULL-termination is
+     guaranteed. */
+  nghttp2_rcbuf *name;
+  /* The buffer containing header field value.  NULL-termination is
+     guaranteed. */
+  nghttp2_rcbuf *value;
+  /* nghttp2_token value for name.  It could be -1 if we have no token
+     for that header field name. */
+  int32_t token;
+  /* Bitwise OR of one or more of nghttp2_nv_flag. */
+  uint8_t flags;
+} nghttp2_hd_nv;
+
+struct nghttp2_hd_entry {
+  /* The header field name/value pair */
+  nghttp2_hd_nv nv;
+  /* This is solely for nghttp2_hd_{deflate,inflate}_get_table_entry
+     APIs to keep backward compatibility. */
+  nghttp2_nv cnv;
+  /* The next entry which shares same bucket in hash table. */
+  nghttp2_hd_entry *next;
+  /* The sequence number.  We will increment it by one whenever we
+     store nghttp2_hd_entry to dynamic header table. */
+  uint32_t seq;
+  /* The hash value for header name (nv.name). */
+  uint32_t hash;
+};
+
+/* The entry used for static header table. */
+typedef struct {
+  nghttp2_rcbuf name;
+  nghttp2_rcbuf value;
+  nghttp2_nv cnv;
+  int32_t token;
+  uint32_t hash;
+} nghttp2_hd_static_entry;
+
+typedef struct {
+  nghttp2_hd_entry **buffer;
+  size_t mask;
+  size_t first;
+  size_t len;
+} nghttp2_hd_ringbuf;
+
+typedef enum {
+  NGHTTP2_HD_OPCODE_NONE,
+  NGHTTP2_HD_OPCODE_INDEXED,
+  NGHTTP2_HD_OPCODE_NEWNAME,
+  NGHTTP2_HD_OPCODE_INDNAME
+} nghttp2_hd_opcode;
+
+typedef enum {
+  NGHTTP2_HD_STATE_EXPECT_TABLE_SIZE,
+  NGHTTP2_HD_STATE_INFLATE_START,
+  NGHTTP2_HD_STATE_OPCODE,
+  NGHTTP2_HD_STATE_READ_TABLE_SIZE,
+  NGHTTP2_HD_STATE_READ_INDEX,
+  NGHTTP2_HD_STATE_NEWNAME_CHECK_NAMELEN,
+  NGHTTP2_HD_STATE_NEWNAME_READ_NAMELEN,
+  NGHTTP2_HD_STATE_NEWNAME_READ_NAMEHUFF,
+  NGHTTP2_HD_STATE_NEWNAME_READ_NAME,
+  NGHTTP2_HD_STATE_CHECK_VALUELEN,
+  NGHTTP2_HD_STATE_READ_VALUELEN,
+  NGHTTP2_HD_STATE_READ_VALUEHUFF,
+  NGHTTP2_HD_STATE_READ_VALUE
+} nghttp2_hd_inflate_state;
+
+typedef enum {
+  NGHTTP2_HD_WITH_INDEXING,
+  NGHTTP2_HD_WITHOUT_INDEXING,
+  NGHTTP2_HD_NEVER_INDEXING
+} nghttp2_hd_indexing_mode;
+
+typedef struct {
+  /* dynamic header table */
+  nghttp2_hd_ringbuf hd_table;
+  /* Memory allocator */
+  nghttp2_mem *mem;
+  /* Abstract buffer size of hd_table as described in the spec. This
+     is the sum of length of name/value in hd_table +
+     NGHTTP2_HD_ENTRY_OVERHEAD bytes overhead per each entry. */
+  size_t hd_table_bufsize;
+  /* The effective header table size. */
+  size_t hd_table_bufsize_max;
+  /* Next sequence number for nghttp2_hd_entry */
+  uint32_t next_seq;
+  /* If inflate/deflate error occurred, this value is set to 1 and
+     further invocation of inflate/deflate will fail with
+     NGHTTP2_ERR_HEADER_COMP. */
+  uint8_t bad;
+} nghttp2_hd_context;
+
+#define HD_MAP_SIZE 128
+
+typedef struct {
+  nghttp2_hd_entry *table[HD_MAP_SIZE];
+} nghttp2_hd_map;
+
+struct nghttp2_hd_deflater {
+  nghttp2_hd_context ctx;
+  nghttp2_hd_map map;
+  /* The upper limit of the header table size the deflater accepts. */
+  size_t deflate_hd_table_bufsize_max;
+  /* Minimum header table size notified in the next context update */
+  size_t min_hd_table_bufsize_max;
+  /* If nonzero, send header table size using encoding context update
+     in the next deflate process */
+  uint8_t notify_table_size_change;
+};
+
+struct nghttp2_hd_inflater {
+  nghttp2_hd_context ctx;
+  /* Stores current state of huffman decoding */
+  nghttp2_hd_huff_decode_context huff_decode_ctx;
+  /* header buffer */
+  nghttp2_buf namebuf, valuebuf;
+  nghttp2_rcbuf *namercbuf, *valuercbuf;
+  /* Pointer to the name/value pair which are used in the current
+     header emission. */
+  nghttp2_rcbuf *nv_name_keep, *nv_value_keep;
+  /* The number of bytes to read */
+  size_t left;
+  /* The index in indexed repr or indexed name */
+  size_t index;
+  /* The maximum header table size the inflater supports. This is the
+     same value transmitted in SETTINGS_HEADER_TABLE_SIZE */
+  size_t settings_hd_table_bufsize_max;
+  /* Minimum header table size set by nghttp2_hd_inflate_change_table_size */
+  size_t min_hd_table_bufsize_max;
+  /* The number of next shift to decode integer */
+  size_t shift;
+  nghttp2_hd_opcode opcode;
+  nghttp2_hd_inflate_state state;
+  /* nonzero if string is huffman encoded */
+  uint8_t huffman_encoded;
+  /* nonzero if deflater requires that current entry is indexed */
+  uint8_t index_required;
+  /* nonzero if deflater requires that current entry must not be
+     indexed */
+  uint8_t no_index;
+};
+
+/*
+ * Initializes the |ent| members.  The reference counts of nv->name
+ * and nv->value are increased by one for each.
+ */
+void nghttp2_hd_entry_init(nghttp2_hd_entry *ent, nghttp2_hd_nv *nv);
+
+/*
+ * This function decreases the reference counts of nv->name and
+ * nv->value.
+ */
+void nghttp2_hd_entry_free(nghttp2_hd_entry *ent);
+
+/*
+ * Initializes |deflater| for deflating name/values pairs.
+ *
+ * The encoder only uses up to
+ * NGHTTP2_HD_DEFAULT_MAX_DEFLATE_BUFFER_SIZE bytes for header table
+ * even if the larger value is specified later in
+ * nghttp2_hd_change_table_size().
+ *
+ * This function returns 0 if it succeeds, or one of the following
+ * negative error codes:
+ *
+ * NGHTTP2_ERR_NOMEM
+ *     Out of memory.
+ */
+int nghttp2_hd_deflate_init(nghttp2_hd_deflater *deflater, nghttp2_mem *mem);
+
+/*
+ * Initializes |deflater| for deflating name/values pairs.
+ *
+ * The encoder only uses up to |max_deflate_dynamic_table_size| bytes
+ * for header table even if the larger value is specified later in
+ * nghttp2_hd_change_table_size().
+ *
+ * This function returns 0 if it succeeds, or one of the following
+ * negative error codes:
+ *
+ * NGHTTP2_ERR_NOMEM
+ *     Out of memory.
+ */
+int nghttp2_hd_deflate_init2(nghttp2_hd_deflater *deflater,
+                             size_t max_deflate_dynamic_table_size,
+                             nghttp2_mem *mem);
+
+/*
+ * Deallocates any resources allocated for |deflater|.
+ */
+void nghttp2_hd_deflate_free(nghttp2_hd_deflater *deflater);
+
+/*
+ * Deflates the |nva|, which has the |nvlen| name/value pairs, into
+ * the |bufs|.
+ *
+ * This function expands |bufs| as necessary to store the result. If
+ * buffers is full and the process still requires more space, this
+ * function fails and returns NGHTTP2_ERR_HEADER_COMP.
+ *
+ * After this function returns, it is safe to delete the |nva|.
+ *
+ * This function returns 0 if it succeeds, or one of the following
+ * negative error codes:
+ *
+ * NGHTTP2_ERR_NOMEM
+ *     Out of memory.
+ * NGHTTP2_ERR_HEADER_COMP
+ *     Deflation process has failed.
+ * NGHTTP2_ERR_BUFFER_ERROR
+ *     Out of buffer space.
+ */
+int nghttp2_hd_deflate_hd_bufs(nghttp2_hd_deflater *deflater,
+                               nghttp2_bufs *bufs, const nghttp2_nv *nva,
+                               size_t nvlen);
+
+/*
+ * Initializes |inflater| for inflating name/values pairs.
+ *
+ * This function returns 0 if it succeeds, or one of the following
+ * negative error codes:
+ *
+ * :enum:`NGHTTP2_ERR_NOMEM`
+ *     Out of memory.
+ */
+int nghttp2_hd_inflate_init(nghttp2_hd_inflater *inflater, nghttp2_mem *mem);
+
+/*
+ * Deallocates any resources allocated for |inflater|.
+ */
+void nghttp2_hd_inflate_free(nghttp2_hd_inflater *inflater);
+
+/*
+ * Similar to nghttp2_hd_inflate_hd(), but this takes nghttp2_hd_nv
+ * instead of nghttp2_nv as output parameter |nv_out|.  Other than
+ * that return values and semantics are the same as
+ * nghttp2_hd_inflate_hd().
+ */
+ssize_t nghttp2_hd_inflate_hd_nv(nghttp2_hd_inflater *inflater,
+                                 nghttp2_hd_nv *nv_out, int *inflate_flags,
+                                 const uint8_t *in, size_t inlen, int in_final);
+
+/* For unittesting purpose */
+int nghttp2_hd_emit_indname_block(nghttp2_bufs *bufs, size_t index,
+                                  nghttp2_nv *nv, int indexing_mode);
+
+/* For unittesting purpose */
+int nghttp2_hd_emit_newname_block(nghttp2_bufs *bufs, nghttp2_nv *nv,
+                                  int indexing_mode);
+
+/* For unittesting purpose */
+int nghttp2_hd_emit_table_size(nghttp2_bufs *bufs, size_t table_size);
+
+/* For unittesting purpose */
+nghttp2_hd_nv nghttp2_hd_table_get(nghttp2_hd_context *context, size_t index);
+
+/* For unittesting purpose */
+ssize_t nghttp2_hd_decode_length(uint32_t *res, size_t *shift_ptr, int *fin,
+                                 uint32_t initial, size_t shift, uint8_t *in,
+                                 uint8_t *last, size_t prefix);
+
+/* Huffman encoding/decoding functions */
+
+/*
+ * Counts the required bytes to encode |src| with length |len|.
+ *
+ * This function returns the number of required bytes to encode given
+ * data, including padding of prefix of terminal symbol code. This
+ * function always succeeds.
+ */
+size_t nghttp2_hd_huff_encode_count(const uint8_t *src, size_t len);
+
+/*
+ * Encodes the given data |src| with length |srclen| to the |bufs|.
+ * This function expands extra buffers in |bufs| if necessary.
+ *
+ * This function returns 0 if it succeeds, or one of the following
+ * negative error codes:
+ *
+ * NGHTTP2_ERR_NOMEM
+ *     Out of memory.
+ * NGHTTP2_ERR_BUFFER_ERROR
+ *     Out of buffer space.
+ */
+int nghttp2_hd_huff_encode(nghttp2_bufs *bufs, const uint8_t *src,
+                           size_t srclen);
+
+void nghttp2_hd_huff_decode_context_init(nghttp2_hd_huff_decode_context *ctx);
+
+/*
+ * Decodes the given data |src| with length |srclen|.  The |ctx| must
+ * be initialized by nghttp2_hd_huff_decode_context_init(). The result
+ * will be written to |buf|.  This function assumes that |buf| has the
+ * enough room to store the decoded byte string.
+ *
+ * The caller must set the |fin| to nonzero if the given input is the
+ * final block.
+ *
+ * This function returns the number of read bytes from the |in|.
+ *
+ * If this function fails, it returns one of the following negative
+ * return codes:
+ *
+ * NGHTTP2_ERR_NOMEM
+ *     Out of memory.
+ * NGHTTP2_ERR_HEADER_COMP
+ *     Decoding process has failed.
+ */
+ssize_t nghttp2_hd_huff_decode(nghttp2_hd_huff_decode_context *ctx,
+                               nghttp2_buf *buf, const uint8_t *src,
+                               size_t srclen, int fin);
+
+/*
+ * nghttp2_hd_huff_decode_failure_state returns nonzero if |ctx|
+ * indicates that huffman decoding context is in failure state.
+ */
+int nghttp2_hd_huff_decode_failure_state(nghttp2_hd_huff_decode_context *ctx);
+
+#endif /* NGHTTP2_HD_H */
diff --git a/Utilities/cmnghttp2/lib/nghttp2_hd_huffman.c b/Utilities/cmnghttp2/lib/nghttp2_hd_huffman.c
new file mode 100644
index 0000000..ac90f49
--- /dev/null
+++ b/Utilities/cmnghttp2/lib/nghttp2_hd_huffman.c
@@ -0,0 +1,144 @@
+/*
+ * nghttp2 - HTTP/2 C Library
+ *
+ * Copyright (c) 2013 Tatsuhiro Tsujikawa
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+#include "nghttp2_hd_huffman.h"
+
+#include <string.h>
+#include <assert.h>
+#include <stdio.h>
+
+#include "nghttp2_hd.h"
+#include "nghttp2_net.h"
+
+size_t nghttp2_hd_huff_encode_count(const uint8_t *src, size_t len) {
+  size_t i;
+  size_t nbits = 0;
+
+  for (i = 0; i < len; ++i) {
+    nbits += huff_sym_table[src[i]].nbits;
+  }
+  /* pad the prefix of EOS (256) */
+  return (nbits + 7) / 8;
+}
+
+int nghttp2_hd_huff_encode(nghttp2_bufs *bufs, const uint8_t *src,
+                           size_t srclen) {
+  const nghttp2_huff_sym *sym;
+  const uint8_t *end = src + srclen;
+  uint64_t code = 0;
+  uint32_t x;
+  size_t nbits = 0;
+  size_t avail;
+  int rv;
+
+  avail = nghttp2_bufs_cur_avail(bufs);
+
+  for (; src != end;) {
+    sym = &huff_sym_table[*src++];
+    code |= (uint64_t)sym->code << (32 - nbits);
+    nbits += sym->nbits;
+    if (nbits < 32) {
+      continue;
+    }
+    if (avail >= 4) {
+      x = htonl((uint32_t)(code >> 32));
+      memcpy(bufs->cur->buf.last, &x, 4);
+      bufs->cur->buf.last += 4;
+      avail -= 4;
+      code <<= 32;
+      nbits -= 32;
+      continue;
+    }
+
+    for (; nbits >= 8;) {
+      rv = nghttp2_bufs_addb(bufs, (uint8_t)(code >> 56));
+      if (rv != 0) {
+        return rv;
+      }
+      code <<= 8;
+      nbits -= 8;
+    }
+
+    avail = nghttp2_bufs_cur_avail(bufs);
+  }
+
+  for (; nbits >= 8;) {
+    rv = nghttp2_bufs_addb(bufs, (uint8_t)(code >> 56));
+    if (rv != 0) {
+      return rv;
+    }
+    code <<= 8;
+    nbits -= 8;
+  }
+
+  if (nbits) {
+    rv = nghttp2_bufs_addb(
+        bufs, (uint8_t)((uint8_t)(code >> 56) | ((1 << (8 - nbits)) - 1)));
+    if (rv != 0) {
+      return rv;
+    }
+  }
+
+  return 0;
+}
+
+void nghttp2_hd_huff_decode_context_init(nghttp2_hd_huff_decode_context *ctx) {
+  ctx->fstate = NGHTTP2_HUFF_ACCEPTED;
+}
+
+ssize_t nghttp2_hd_huff_decode(nghttp2_hd_huff_decode_context *ctx,
+                               nghttp2_buf *buf, const uint8_t *src,
+                               size_t srclen, int final) {
+  const uint8_t *end = src + srclen;
+  nghttp2_huff_decode node = {ctx->fstate, 0};
+  const nghttp2_huff_decode *t = &node;
+  uint8_t c;
+
+  /* We use the decoding algorithm described in
+     http://graphics.ics.uci.edu/pub/Prefix.pdf */
+  for (; src != end;) {
+    c = *src++;
+    t = &huff_decode_table[t->fstate & 0x1ff][c >> 4];
+    if (t->fstate & NGHTTP2_HUFF_SYM) {
+      *buf->last++ = t->sym;
+    }
+
+    t = &huff_decode_table[t->fstate & 0x1ff][c & 0xf];
+    if (t->fstate & NGHTTP2_HUFF_SYM) {
+      *buf->last++ = t->sym;
+    }
+  }
+
+  ctx->fstate = t->fstate;
+
+  if (final && !(ctx->fstate & NGHTTP2_HUFF_ACCEPTED)) {
+    return NGHTTP2_ERR_HEADER_COMP;
+  }
+
+  return (ssize_t)srclen;
+}
+
+int nghttp2_hd_huff_decode_failure_state(nghttp2_hd_huff_decode_context *ctx) {
+  return ctx->fstate == 0x100;
+}
diff --git a/Utilities/cmnghttp2/lib/nghttp2_hd_huffman.h b/Utilities/cmnghttp2/lib/nghttp2_hd_huffman.h
new file mode 100644
index 0000000..2bfd531
--- /dev/null
+++ b/Utilities/cmnghttp2/lib/nghttp2_hd_huffman.h
@@ -0,0 +1,72 @@
+/*
+ * nghttp2 - HTTP/2 C Library
+ *
+ * Copyright (c) 2013 Tatsuhiro Tsujikawa
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+#ifndef NGHTTP2_HD_HUFFMAN_H
+#define NGHTTP2_HD_HUFFMAN_H
+
+#ifdef HAVE_CONFIG_H
+#  include <config.h>
+#endif /* HAVE_CONFIG_H */
+
+#include <nghttp2/nghttp2.h>
+
+typedef enum {
+  /* FSA accepts this state as the end of huffman encoding
+     sequence. */
+  NGHTTP2_HUFF_ACCEPTED = 1 << 14,
+  /* This state emits symbol */
+  NGHTTP2_HUFF_SYM = 1 << 15,
+} nghttp2_huff_decode_flag;
+
+typedef struct {
+  /* fstate is the current huffman decoding state, which is actually
+     the node ID of internal huffman tree with
+     nghttp2_huff_decode_flag OR-ed.  We have 257 leaf nodes, but they
+     are identical to root node other than emitting a symbol, so we
+     have 256 internal nodes [1..255], inclusive.  The node ID 256 is
+     a special node and it is a terminal state that means decoding
+     failed. */
+  uint16_t fstate;
+  /* symbol if NGHTTP2_HUFF_SYM flag set */
+  uint8_t sym;
+} nghttp2_huff_decode;
+
+typedef nghttp2_huff_decode huff_decode_table_type[16];
+
+typedef struct {
+  /* fstate is the current huffman decoding state. */
+  uint16_t fstate;
+} nghttp2_hd_huff_decode_context;
+
+typedef struct {
+  /* The number of bits in this code */
+  uint32_t nbits;
+  /* Huffman code aligned to LSB */
+  uint32_t code;
+} nghttp2_huff_sym;
+
+extern const nghttp2_huff_sym huff_sym_table[];
+extern const nghttp2_huff_decode huff_decode_table[][16];
+
+#endif /* NGHTTP2_HD_HUFFMAN_H */
diff --git a/Utilities/cmnghttp2/lib/nghttp2_hd_huffman_data.c b/Utilities/cmnghttp2/lib/nghttp2_hd_huffman_data.c
new file mode 100644
index 0000000..2e2e13f
--- /dev/null
+++ b/Utilities/cmnghttp2/lib/nghttp2_hd_huffman_data.c
@@ -0,0 +1,4980 @@
+/*
+ * nghttp2 - HTTP/2 C Library
+ *
+ * Copyright (c) 2013 Tatsuhiro Tsujikawa
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+#include "nghttp2_hd_huffman.h"
+
+/* Generated by mkhufftbl.py */
+
+const nghttp2_huff_sym huff_sym_table[] = {
+    {13, 0xffc00000u}, {23, 0xffffb000u}, {28, 0xfffffe20u}, {28, 0xfffffe30u},
+    {28, 0xfffffe40u}, {28, 0xfffffe50u}, {28, 0xfffffe60u}, {28, 0xfffffe70u},
+    {28, 0xfffffe80u}, {24, 0xffffea00u}, {30, 0xfffffff0u}, {28, 0xfffffe90u},
+    {28, 0xfffffea0u}, {30, 0xfffffff4u}, {28, 0xfffffeb0u}, {28, 0xfffffec0u},
+    {28, 0xfffffed0u}, {28, 0xfffffee0u}, {28, 0xfffffef0u}, {28, 0xffffff00u},
+    {28, 0xffffff10u}, {28, 0xffffff20u}, {30, 0xfffffff8u}, {28, 0xffffff30u},
+    {28, 0xffffff40u}, {28, 0xffffff50u}, {28, 0xffffff60u}, {28, 0xffffff70u},
+    {28, 0xffffff80u}, {28, 0xffffff90u}, {28, 0xffffffa0u}, {28, 0xffffffb0u},
+    {6, 0x50000000u},  {10, 0xfe000000u}, {10, 0xfe400000u}, {12, 0xffa00000u},
+    {13, 0xffc80000u}, {6, 0x54000000u},  {8, 0xf8000000u},  {11, 0xff400000u},
+    {10, 0xfe800000u}, {10, 0xfec00000u}, {8, 0xf9000000u},  {11, 0xff600000u},
+    {8, 0xfa000000u},  {6, 0x58000000u},  {6, 0x5c000000u},  {6, 0x60000000u},
+    {5, 0x0u},         {5, 0x8000000u},   {5, 0x10000000u},  {6, 0x64000000u},
+    {6, 0x68000000u},  {6, 0x6c000000u},  {6, 0x70000000u},  {6, 0x74000000u},
+    {6, 0x78000000u},  {6, 0x7c000000u},  {7, 0xb8000000u},  {8, 0xfb000000u},
+    {15, 0xfff80000u}, {6, 0x80000000u},  {12, 0xffb00000u}, {10, 0xff000000u},
+    {13, 0xffd00000u}, {6, 0x84000000u},  {7, 0xba000000u},  {7, 0xbc000000u},
+    {7, 0xbe000000u},  {7, 0xc0000000u},  {7, 0xc2000000u},  {7, 0xc4000000u},
+    {7, 0xc6000000u},  {7, 0xc8000000u},  {7, 0xca000000u},  {7, 0xcc000000u},
+    {7, 0xce000000u},  {7, 0xd0000000u},  {7, 0xd2000000u},  {7, 0xd4000000u},
+    {7, 0xd6000000u},  {7, 0xd8000000u},  {7, 0xda000000u},  {7, 0xdc000000u},
+    {7, 0xde000000u},  {7, 0xe0000000u},  {7, 0xe2000000u},  {7, 0xe4000000u},
+    {8, 0xfc000000u},  {7, 0xe6000000u},  {8, 0xfd000000u},  {13, 0xffd80000u},
+    {19, 0xfffe0000u}, {13, 0xffe00000u}, {14, 0xfff00000u}, {6, 0x88000000u},
+    {15, 0xfffa0000u}, {5, 0x18000000u},  {6, 0x8c000000u},  {5, 0x20000000u},
+    {6, 0x90000000u},  {5, 0x28000000u},  {6, 0x94000000u},  {6, 0x98000000u},
+    {6, 0x9c000000u},  {5, 0x30000000u},  {7, 0xe8000000u},  {7, 0xea000000u},
+    {6, 0xa0000000u},  {6, 0xa4000000u},  {6, 0xa8000000u},  {5, 0x38000000u},
+    {6, 0xac000000u},  {7, 0xec000000u},  {6, 0xb0000000u},  {5, 0x40000000u},
+    {5, 0x48000000u},  {6, 0xb4000000u},  {7, 0xee000000u},  {7, 0xf0000000u},
+    {7, 0xf2000000u},  {7, 0xf4000000u},  {7, 0xf6000000u},  {15, 0xfffc0000u},
+    {11, 0xff800000u}, {14, 0xfff40000u}, {13, 0xffe80000u}, {28, 0xffffffc0u},
+    {20, 0xfffe6000u}, {22, 0xffff4800u}, {20, 0xfffe7000u}, {20, 0xfffe8000u},
+    {22, 0xffff4c00u}, {22, 0xffff5000u}, {22, 0xffff5400u}, {23, 0xffffb200u},
+    {22, 0xffff5800u}, {23, 0xffffb400u}, {23, 0xffffb600u}, {23, 0xffffb800u},
+    {23, 0xffffba00u}, {23, 0xffffbc00u}, {24, 0xffffeb00u}, {23, 0xffffbe00u},
+    {24, 0xffffec00u}, {24, 0xffffed00u}, {22, 0xffff5c00u}, {23, 0xffffc000u},
+    {24, 0xffffee00u}, {23, 0xffffc200u}, {23, 0xffffc400u}, {23, 0xffffc600u},
+    {23, 0xffffc800u}, {21, 0xfffee000u}, {22, 0xffff6000u}, {23, 0xffffca00u},
+    {22, 0xffff6400u}, {23, 0xffffcc00u}, {23, 0xffffce00u}, {24, 0xffffef00u},
+    {22, 0xffff6800u}, {21, 0xfffee800u}, {20, 0xfffe9000u}, {22, 0xffff6c00u},
+    {22, 0xffff7000u}, {23, 0xffffd000u}, {23, 0xffffd200u}, {21, 0xfffef000u},
+    {23, 0xffffd400u}, {22, 0xffff7400u}, {22, 0xffff7800u}, {24, 0xfffff000u},
+    {21, 0xfffef800u}, {22, 0xffff7c00u}, {23, 0xffffd600u}, {23, 0xffffd800u},
+    {21, 0xffff0000u}, {21, 0xffff0800u}, {22, 0xffff8000u}, {21, 0xffff1000u},
+    {23, 0xffffda00u}, {22, 0xffff8400u}, {23, 0xffffdc00u}, {23, 0xffffde00u},
+    {20, 0xfffea000u}, {22, 0xffff8800u}, {22, 0xffff8c00u}, {22, 0xffff9000u},
+    {23, 0xffffe000u}, {22, 0xffff9400u}, {22, 0xffff9800u}, {23, 0xffffe200u},
+    {26, 0xfffff800u}, {26, 0xfffff840u}, {20, 0xfffeb000u}, {19, 0xfffe2000u},
+    {22, 0xffff9c00u}, {23, 0xffffe400u}, {22, 0xffffa000u}, {25, 0xfffff600u},
+    {26, 0xfffff880u}, {26, 0xfffff8c0u}, {26, 0xfffff900u}, {27, 0xfffffbc0u},
+    {27, 0xfffffbe0u}, {26, 0xfffff940u}, {24, 0xfffff100u}, {25, 0xfffff680u},
+    {19, 0xfffe4000u}, {21, 0xffff1800u}, {26, 0xfffff980u}, {27, 0xfffffc00u},
+    {27, 0xfffffc20u}, {26, 0xfffff9c0u}, {27, 0xfffffc40u}, {24, 0xfffff200u},
+    {21, 0xffff2000u}, {21, 0xffff2800u}, {26, 0xfffffa00u}, {26, 0xfffffa40u},
+    {28, 0xffffffd0u}, {27, 0xfffffc60u}, {27, 0xfffffc80u}, {27, 0xfffffca0u},
+    {20, 0xfffec000u}, {24, 0xfffff300u}, {20, 0xfffed000u}, {21, 0xffff3000u},
+    {22, 0xffffa400u}, {21, 0xffff3800u}, {21, 0xffff4000u}, {23, 0xffffe600u},
+    {22, 0xffffa800u}, {22, 0xffffac00u}, {25, 0xfffff700u}, {25, 0xfffff780u},
+    {24, 0xfffff400u}, {24, 0xfffff500u}, {26, 0xfffffa80u}, {23, 0xffffe800u},
+    {26, 0xfffffac0u}, {27, 0xfffffcc0u}, {26, 0xfffffb00u}, {26, 0xfffffb40u},
+    {27, 0xfffffce0u}, {27, 0xfffffd00u}, {27, 0xfffffd20u}, {27, 0xfffffd40u},
+    {27, 0xfffffd60u}, {28, 0xffffffe0u}, {27, 0xfffffd80u}, {27, 0xfffffda0u},
+    {27, 0xfffffdc0u}, {27, 0xfffffde0u}, {27, 0xfffffe00u}, {26, 0xfffffb80u},
+    {30, 0xfffffffcu}};
+
+const nghttp2_huff_decode huff_decode_table[][16] = {
+    /* 0 */
+    {
+        {0x04, 0},
+        {0x05, 0},
+        {0x07, 0},
+        {0x08, 0},
+        {0x0b, 0},
+        {0x0c, 0},
+        {0x10, 0},
+        {0x13, 0},
+        {0x19, 0},
+        {0x1c, 0},
+        {0x20, 0},
+        {0x23, 0},
+        {0x2a, 0},
+        {0x31, 0},
+        {0x39, 0},
+        {0x4040, 0},
+    },
+    /* 1 */
+    {
+        {0xc000, 48},
+        {0xc000, 49},
+        {0xc000, 50},
+        {0xc000, 97},
+        {0xc000, 99},
+        {0xc000, 101},
+        {0xc000, 105},
+        {0xc000, 111},
+        {0xc000, 115},
+        {0xc000, 116},
+        {0x0d, 0},
+        {0x0e, 0},
+        {0x11, 0},
+        {0x12, 0},
+        {0x14, 0},
+        {0x15, 0},
+    },
+    /* 2 */
+    {
+        {0x8001, 48},
+        {0xc016, 48},
+        {0x8001, 49},
+        {0xc016, 49},
+        {0x8001, 50},
+        {0xc016, 50},
+        {0x8001, 97},
+        {0xc016, 97},
+        {0x8001, 99},
+        {0xc016, 99},
+        {0x8001, 101},
+        {0xc016, 101},
+        {0x8001, 105},
+        {0xc016, 105},
+        {0x8001, 111},
+        {0xc016, 111},
+    },
+    /* 3 */
+    {
+        {0x8002, 48},
+        {0x8009, 48},
+        {0x8017, 48},
+        {0xc028, 48},
+        {0x8002, 49},
+        {0x8009, 49},
+        {0x8017, 49},
+        {0xc028, 49},
+        {0x8002, 50},
+        {0x8009, 50},
+        {0x8017, 50},
+        {0xc028, 50},
+        {0x8002, 97},
+        {0x8009, 97},
+        {0x8017, 97},
+        {0xc028, 97},
+    },
+    /* 4 */
+    {
+        {0x8003, 48},
+        {0x8006, 48},
+        {0x800a, 48},
+        {0x800f, 48},
+        {0x8018, 48},
+        {0x801f, 48},
+        {0x8029, 48},
+        {0xc038, 48},
+        {0x8003, 49},
+        {0x8006, 49},
+        {0x800a, 49},
+        {0x800f, 49},
+        {0x8018, 49},
+        {0x801f, 49},
+        {0x8029, 49},
+        {0xc038, 49},
+    },
+    /* 5 */
+    {
+        {0x8003, 50},
+        {0x8006, 50},
+        {0x800a, 50},
+        {0x800f, 50},
+        {0x8018, 50},
+        {0x801f, 50},
+        {0x8029, 50},
+        {0xc038, 50},
+        {0x8003, 97},
+        {0x8006, 97},
+        {0x800a, 97},
+        {0x800f, 97},
+        {0x8018, 97},
+        {0x801f, 97},
+        {0x8029, 97},
+        {0xc038, 97},
+    },
+    /* 6 */
+    {
+        {0x8002, 99},
+        {0x8009, 99},
+        {0x8017, 99},
+        {0xc028, 99},
+        {0x8002, 101},
+        {0x8009, 101},
+        {0x8017, 101},
+        {0xc028, 101},
+        {0x8002, 105},
+        {0x8009, 105},
+        {0x8017, 105},
+        {0xc028, 105},
+        {0x8002, 111},
+        {0x8009, 111},
+        {0x8017, 111},
+        {0xc028, 111},
+    },
+    /* 7 */
+    {
+        {0x8003, 99},
+        {0x8006, 99},
+        {0x800a, 99},
+        {0x800f, 99},
+        {0x8018, 99},
+        {0x801f, 99},
+        {0x8029, 99},
+        {0xc038, 99},
+        {0x8003, 101},
+        {0x8006, 101},
+        {0x800a, 101},
+        {0x800f, 101},
+        {0x8018, 101},
+        {0x801f, 101},
+        {0x8029, 101},
+        {0xc038, 101},
+    },
+    /* 8 */
+    {
+        {0x8003, 105},
+        {0x8006, 105},
+        {0x800a, 105},
+        {0x800f, 105},
+        {0x8018, 105},
+        {0x801f, 105},
+        {0x8029, 105},
+        {0xc038, 105},
+        {0x8003, 111},
+        {0x8006, 111},
+        {0x800a, 111},
+        {0x800f, 111},
+        {0x8018, 111},
+        {0x801f, 111},
+        {0x8029, 111},
+        {0xc038, 111},
+    },
+    /* 9 */
+    {
+        {0x8001, 115},
+        {0xc016, 115},
+        {0x8001, 116},
+        {0xc016, 116},
+        {0xc000, 32},
+        {0xc000, 37},
+        {0xc000, 45},
+        {0xc000, 46},
+        {0xc000, 47},
+        {0xc000, 51},
+        {0xc000, 52},
+        {0xc000, 53},
+        {0xc000, 54},
+        {0xc000, 55},
+        {0xc000, 56},
+        {0xc000, 57},
+    },
+    /* 10 */
+    {
+        {0x8002, 115},
+        {0x8009, 115},
+        {0x8017, 115},
+        {0xc028, 115},
+        {0x8002, 116},
+        {0x8009, 116},
+        {0x8017, 116},
+        {0xc028, 116},
+        {0x8001, 32},
+        {0xc016, 32},
+        {0x8001, 37},
+        {0xc016, 37},
+        {0x8001, 45},
+        {0xc016, 45},
+        {0x8001, 46},
+        {0xc016, 46},
+    },
+    /* 11 */
+    {
+        {0x8003, 115},
+        {0x8006, 115},
+        {0x800a, 115},
+        {0x800f, 115},
+        {0x8018, 115},
+        {0x801f, 115},
+        {0x8029, 115},
+        {0xc038, 115},
+        {0x8003, 116},
+        {0x8006, 116},
+        {0x800a, 116},
+        {0x800f, 116},
+        {0x8018, 116},
+        {0x801f, 116},
+        {0x8029, 116},
+        {0xc038, 116},
+    },
+    /* 12 */
+    {
+        {0x8002, 32},
+        {0x8009, 32},
+        {0x8017, 32},
+        {0xc028, 32},
+        {0x8002, 37},
+        {0x8009, 37},
+        {0x8017, 37},
+        {0xc028, 37},
+        {0x8002, 45},
+        {0x8009, 45},
+        {0x8017, 45},
+        {0xc028, 45},
+        {0x8002, 46},
+        {0x8009, 46},
+        {0x8017, 46},
+        {0xc028, 46},
+    },
+    /* 13 */
+    {
+        {0x8003, 32},
+        {0x8006, 32},
+        {0x800a, 32},
+        {0x800f, 32},
+        {0x8018, 32},
+        {0x801f, 32},
+        {0x8029, 32},
+        {0xc038, 32},
+        {0x8003, 37},
+        {0x8006, 37},
+        {0x800a, 37},
+        {0x800f, 37},
+        {0x8018, 37},
+        {0x801f, 37},
+        {0x8029, 37},
+        {0xc038, 37},
+    },
+    /* 14 */
+    {
+        {0x8003, 45},
+        {0x8006, 45},
+        {0x800a, 45},
+        {0x800f, 45},
+        {0x8018, 45},
+        {0x801f, 45},
+        {0x8029, 45},
+        {0xc038, 45},
+        {0x8003, 46},
+        {0x8006, 46},
+        {0x800a, 46},
+        {0x800f, 46},
+        {0x8018, 46},
+        {0x801f, 46},
+        {0x8029, 46},
+        {0xc038, 46},
+    },
+    /* 15 */
+    {
+        {0x8001, 47},
+        {0xc016, 47},
+        {0x8001, 51},
+        {0xc016, 51},
+        {0x8001, 52},
+        {0xc016, 52},
+        {0x8001, 53},
+        {0xc016, 53},
+        {0x8001, 54},
+        {0xc016, 54},
+        {0x8001, 55},
+        {0xc016, 55},
+        {0x8001, 56},
+        {0xc016, 56},
+        {0x8001, 57},
+        {0xc016, 57},
+    },
+    /* 16 */
+    {
+        {0x8002, 47},
+        {0x8009, 47},
+        {0x8017, 47},
+        {0xc028, 47},
+        {0x8002, 51},
+        {0x8009, 51},
+        {0x8017, 51},
+        {0xc028, 51},
+        {0x8002, 52},
+        {0x8009, 52},
+        {0x8017, 52},
+        {0xc028, 52},
+        {0x8002, 53},
+        {0x8009, 53},
+        {0x8017, 53},
+        {0xc028, 53},
+    },
+    /* 17 */
+    {
+        {0x8003, 47},
+        {0x8006, 47},
+        {0x800a, 47},
+        {0x800f, 47},
+        {0x8018, 47},
+        {0x801f, 47},
+        {0x8029, 47},
+        {0xc038, 47},
+        {0x8003, 51},
+        {0x8006, 51},
+        {0x800a, 51},
+        {0x800f, 51},
+        {0x8018, 51},
+        {0x801f, 51},
+        {0x8029, 51},
+        {0xc038, 51},
+    },
+    /* 18 */
+    {
+        {0x8003, 52},
+        {0x8006, 52},
+        {0x800a, 52},
+        {0x800f, 52},
+        {0x8018, 52},
+        {0x801f, 52},
+        {0x8029, 52},
+        {0xc038, 52},
+        {0x8003, 53},
+        {0x8006, 53},
+        {0x800a, 53},
+        {0x800f, 53},
+        {0x8018, 53},
+        {0x801f, 53},
+        {0x8029, 53},
+        {0xc038, 53},
+    },
+    /* 19 */
+    {
+        {0x8002, 54},
+        {0x8009, 54},
+        {0x8017, 54},
+        {0xc028, 54},
+        {0x8002, 55},
+        {0x8009, 55},
+        {0x8017, 55},
+        {0xc028, 55},
+        {0x8002, 56},
+        {0x8009, 56},
+        {0x8017, 56},
+        {0xc028, 56},
+        {0x8002, 57},
+        {0x8009, 57},
+        {0x8017, 57},
+        {0xc028, 57},
+    },
+    /* 20 */
+    {
+        {0x8003, 54},
+        {0x8006, 54},
+        {0x800a, 54},
+        {0x800f, 54},
+        {0x8018, 54},
+        {0x801f, 54},
+        {0x8029, 54},
+        {0xc038, 54},
+        {0x8003, 55},
+        {0x8006, 55},
+        {0x800a, 55},
+        {0x800f, 55},
+        {0x8018, 55},
+        {0x801f, 55},
+        {0x8029, 55},
+        {0xc038, 55},
+    },
+    /* 21 */
+    {
+        {0x8003, 56},
+        {0x8006, 56},
+        {0x800a, 56},
+        {0x800f, 56},
+        {0x8018, 56},
+        {0x801f, 56},
+        {0x8029, 56},
+        {0xc038, 56},
+        {0x8003, 57},
+        {0x8006, 57},
+        {0x800a, 57},
+        {0x800f, 57},
+        {0x8018, 57},
+        {0x801f, 57},
+        {0x8029, 57},
+        {0xc038, 57},
+    },
+    /* 22 */
+    {
+        {0x1a, 0},
+        {0x1b, 0},
+        {0x1d, 0},
+        {0x1e, 0},
+        {0x21, 0},
+        {0x22, 0},
+        {0x24, 0},
+        {0x25, 0},
+        {0x2b, 0},
+        {0x2e, 0},
+        {0x32, 0},
+        {0x35, 0},
+        {0x3a, 0},
+        {0x3d, 0},
+        {0x41, 0},
+        {0x4044, 0},
+    },
+    /* 23 */
+    {
+        {0xc000, 61},
+        {0xc000, 65},
+        {0xc000, 95},
+        {0xc000, 98},
+        {0xc000, 100},
+        {0xc000, 102},
+        {0xc000, 103},
+        {0xc000, 104},
+        {0xc000, 108},
+        {0xc000, 109},
+        {0xc000, 110},
+        {0xc000, 112},
+        {0xc000, 114},
+        {0xc000, 117},
+        {0x26, 0},
+        {0x27, 0},
+    },
+    /* 24 */
+    {
+        {0x8001, 61},
+        {0xc016, 61},
+        {0x8001, 65},
+        {0xc016, 65},
+        {0x8001, 95},
+        {0xc016, 95},
+        {0x8001, 98},
+        {0xc016, 98},
+        {0x8001, 100},
+        {0xc016, 100},
+        {0x8001, 102},
+        {0xc016, 102},
+        {0x8001, 103},
+        {0xc016, 103},
+        {0x8001, 104},
+        {0xc016, 104},
+    },
+    /* 25 */
+    {
+        {0x8002, 61},
+        {0x8009, 61},
+        {0x8017, 61},
+        {0xc028, 61},
+        {0x8002, 65},
+        {0x8009, 65},
+        {0x8017, 65},
+        {0xc028, 65},
+        {0x8002, 95},
+        {0x8009, 95},
+        {0x8017, 95},
+        {0xc028, 95},
+        {0x8002, 98},
+        {0x8009, 98},
+        {0x8017, 98},
+        {0xc028, 98},
+    },
+    /* 26 */
+    {
+        {0x8003, 61},
+        {0x8006, 61},
+        {0x800a, 61},
+        {0x800f, 61},
+        {0x8018, 61},
+        {0x801f, 61},
+        {0x8029, 61},
+        {0xc038, 61},
+        {0x8003, 65},
+        {0x8006, 65},
+        {0x800a, 65},
+        {0x800f, 65},
+        {0x8018, 65},
+        {0x801f, 65},
+        {0x8029, 65},
+        {0xc038, 65},
+    },
+    /* 27 */
+    {
+        {0x8003, 95},
+        {0x8006, 95},
+        {0x800a, 95},
+        {0x800f, 95},
+        {0x8018, 95},
+        {0x801f, 95},
+        {0x8029, 95},
+        {0xc038, 95},
+        {0x8003, 98},
+        {0x8006, 98},
+        {0x800a, 98},
+        {0x800f, 98},
+        {0x8018, 98},
+        {0x801f, 98},
+        {0x8029, 98},
+        {0xc038, 98},
+    },
+    /* 28 */
+    {
+        {0x8002, 100},
+        {0x8009, 100},
+        {0x8017, 100},
+        {0xc028, 100},
+        {0x8002, 102},
+        {0x8009, 102},
+        {0x8017, 102},
+        {0xc028, 102},
+        {0x8002, 103},
+        {0x8009, 103},
+        {0x8017, 103},
+        {0xc028, 103},
+        {0x8002, 104},
+        {0x8009, 104},
+        {0x8017, 104},
+        {0xc028, 104},
+    },
+    /* 29 */
+    {
+        {0x8003, 100},
+        {0x8006, 100},
+        {0x800a, 100},
+        {0x800f, 100},
+        {0x8018, 100},
+        {0x801f, 100},
+        {0x8029, 100},
+        {0xc038, 100},
+        {0x8003, 102},
+        {0x8006, 102},
+        {0x800a, 102},
+        {0x800f, 102},
+        {0x8018, 102},
+        {0x801f, 102},
+        {0x8029, 102},
+        {0xc038, 102},
+    },
+    /* 30 */
+    {
+        {0x8003, 103},
+        {0x8006, 103},
+        {0x800a, 103},
+        {0x800f, 103},
+        {0x8018, 103},
+        {0x801f, 103},
+        {0x8029, 103},
+        {0xc038, 103},
+        {0x8003, 104},
+        {0x8006, 104},
+        {0x800a, 104},
+        {0x800f, 104},
+        {0x8018, 104},
+        {0x801f, 104},
+        {0x8029, 104},
+        {0xc038, 104},
+    },
+    /* 31 */
+    {
+        {0x8001, 108},
+        {0xc016, 108},
+        {0x8001, 109},
+        {0xc016, 109},
+        {0x8001, 110},
+        {0xc016, 110},
+        {0x8001, 112},
+        {0xc016, 112},
+        {0x8001, 114},
+        {0xc016, 114},
+        {0x8001, 117},
+        {0xc016, 117},
+        {0xc000, 58},
+        {0xc000, 66},
+        {0xc000, 67},
+        {0xc000, 68},
+    },
+    /* 32 */
+    {
+        {0x8002, 108},
+        {0x8009, 108},
+        {0x8017, 108},
+        {0xc028, 108},
+        {0x8002, 109},
+        {0x8009, 109},
+        {0x8017, 109},
+        {0xc028, 109},
+        {0x8002, 110},
+        {0x8009, 110},
+        {0x8017, 110},
+        {0xc028, 110},
+        {0x8002, 112},
+        {0x8009, 112},
+        {0x8017, 112},
+        {0xc028, 112},
+    },
+    /* 33 */
+    {
+        {0x8003, 108},
+        {0x8006, 108},
+        {0x800a, 108},
+        {0x800f, 108},
+        {0x8018, 108},
+        {0x801f, 108},
+        {0x8029, 108},
+        {0xc038, 108},
+        {0x8003, 109},
+        {0x8006, 109},
+        {0x800a, 109},
+        {0x800f, 109},
+        {0x8018, 109},
+        {0x801f, 109},
+        {0x8029, 109},
+        {0xc038, 109},
+    },
+    /* 34 */
+    {
+        {0x8003, 110},
+        {0x8006, 110},
+        {0x800a, 110},
+        {0x800f, 110},
+        {0x8018, 110},
+        {0x801f, 110},
+        {0x8029, 110},
+        {0xc038, 110},
+        {0x8003, 112},
+        {0x8006, 112},
+        {0x800a, 112},
+        {0x800f, 112},
+        {0x8018, 112},
+        {0x801f, 112},
+        {0x8029, 112},
+        {0xc038, 112},
+    },
+    /* 35 */
+    {
+        {0x8002, 114},
+        {0x8009, 114},
+        {0x8017, 114},
+        {0xc028, 114},
+        {0x8002, 117},
+        {0x8009, 117},
+        {0x8017, 117},
+        {0xc028, 117},
+        {0x8001, 58},
+        {0xc016, 58},
+        {0x8001, 66},
+        {0xc016, 66},
+        {0x8001, 67},
+        {0xc016, 67},
+        {0x8001, 68},
+        {0xc016, 68},
+    },
+    /* 36 */
+    {
+        {0x8003, 114},
+        {0x8006, 114},
+        {0x800a, 114},
+        {0x800f, 114},
+        {0x8018, 114},
+        {0x801f, 114},
+        {0x8029, 114},
+        {0xc038, 114},
+        {0x8003, 117},
+        {0x8006, 117},
+        {0x800a, 117},
+        {0x800f, 117},
+        {0x8018, 117},
+        {0x801f, 117},
+        {0x8029, 117},
+        {0xc038, 117},
+    },
+    /* 37 */
+    {
+        {0x8002, 58},
+        {0x8009, 58},
+        {0x8017, 58},
+        {0xc028, 58},
+        {0x8002, 66},
+        {0x8009, 66},
+        {0x8017, 66},
+        {0xc028, 66},
+        {0x8002, 67},
+        {0x8009, 67},
+        {0x8017, 67},
+        {0xc028, 67},
+        {0x8002, 68},
+        {0x8009, 68},
+        {0x8017, 68},
+        {0xc028, 68},
+    },
+    /* 38 */
+    {
+        {0x8003, 58},
+        {0x8006, 58},
+        {0x800a, 58},
+        {0x800f, 58},
+        {0x8018, 58},
+        {0x801f, 58},
+        {0x8029, 58},
+        {0xc038, 58},
+        {0x8003, 66},
+        {0x8006, 66},
+        {0x800a, 66},
+        {0x800f, 66},
+        {0x8018, 66},
+        {0x801f, 66},
+        {0x8029, 66},
+        {0xc038, 66},
+    },
+    /* 39 */
+    {
+        {0x8003, 67},
+        {0x8006, 67},
+        {0x800a, 67},
+        {0x800f, 67},
+        {0x8018, 67},
+        {0x801f, 67},
+        {0x8029, 67},
+        {0xc038, 67},
+        {0x8003, 68},
+        {0x8006, 68},
+        {0x800a, 68},
+        {0x800f, 68},
+        {0x8018, 68},
+        {0x801f, 68},
+        {0x8029, 68},
+        {0xc038, 68},
+    },
+    /* 40 */
+    {
+        {0x2c, 0},
+        {0x2d, 0},
+        {0x2f, 0},
+        {0x30, 0},
+        {0x33, 0},
+        {0x34, 0},
+        {0x36, 0},
+        {0x37, 0},
+        {0x3b, 0},
+        {0x3c, 0},
+        {0x3e, 0},
+        {0x3f, 0},
+        {0x42, 0},
+        {0x43, 0},
+        {0x45, 0},
+        {0x4048, 0},
+    },
+    /* 41 */
+    {
+        {0xc000, 69},
+        {0xc000, 70},
+        {0xc000, 71},
+        {0xc000, 72},
+        {0xc000, 73},
+        {0xc000, 74},
+        {0xc000, 75},
+        {0xc000, 76},
+        {0xc000, 77},
+        {0xc000, 78},
+        {0xc000, 79},
+        {0xc000, 80},
+        {0xc000, 81},
+        {0xc000, 82},
+        {0xc000, 83},
+        {0xc000, 84},
+    },
+    /* 42 */
+    {
+        {0x8001, 69},
+        {0xc016, 69},
+        {0x8001, 70},
+        {0xc016, 70},
+        {0x8001, 71},
+        {0xc016, 71},
+        {0x8001, 72},
+        {0xc016, 72},
+        {0x8001, 73},
+        {0xc016, 73},
+        {0x8001, 74},
+        {0xc016, 74},
+        {0x8001, 75},
+        {0xc016, 75},
+        {0x8001, 76},
+        {0xc016, 76},
+    },
+    /* 43 */
+    {
+        {0x8002, 69},
+        {0x8009, 69},
+        {0x8017, 69},
+        {0xc028, 69},
+        {0x8002, 70},
+        {0x8009, 70},
+        {0x8017, 70},
+        {0xc028, 70},
+        {0x8002, 71},
+        {0x8009, 71},
+        {0x8017, 71},
+        {0xc028, 71},
+        {0x8002, 72},
+        {0x8009, 72},
+        {0x8017, 72},
+        {0xc028, 72},
+    },
+    /* 44 */
+    {
+        {0x8003, 69},
+        {0x8006, 69},
+        {0x800a, 69},
+        {0x800f, 69},
+        {0x8018, 69},
+        {0x801f, 69},
+        {0x8029, 69},
+        {0xc038, 69},
+        {0x8003, 70},
+        {0x8006, 70},
+        {0x800a, 70},
+        {0x800f, 70},
+        {0x8018, 70},
+        {0x801f, 70},
+        {0x8029, 70},
+        {0xc038, 70},
+    },
+    /* 45 */
+    {
+        {0x8003, 71},
+        {0x8006, 71},
+        {0x800a, 71},
+        {0x800f, 71},
+        {0x8018, 71},
+        {0x801f, 71},
+        {0x8029, 71},
+        {0xc038, 71},
+        {0x8003, 72},
+        {0x8006, 72},
+        {0x800a, 72},
+        {0x800f, 72},
+        {0x8018, 72},
+        {0x801f, 72},
+        {0x8029, 72},
+        {0xc038, 72},
+    },
+    /* 46 */
+    {
+        {0x8002, 73},
+        {0x8009, 73},
+        {0x8017, 73},
+        {0xc028, 73},
+        {0x8002, 74},
+        {0x8009, 74},
+        {0x8017, 74},
+        {0xc028, 74},
+        {0x8002, 75},
+        {0x8009, 75},
+        {0x8017, 75},
+        {0xc028, 75},
+        {0x8002, 76},
+        {0x8009, 76},
+        {0x8017, 76},
+        {0xc028, 76},
+    },
+    /* 47 */
+    {
+        {0x8003, 73},
+        {0x8006, 73},
+        {0x800a, 73},
+        {0x800f, 73},
+        {0x8018, 73},
+        {0x801f, 73},
+        {0x8029, 73},
+        {0xc038, 73},
+        {0x8003, 74},
+        {0x8006, 74},
+        {0x800a, 74},
+        {0x800f, 74},
+        {0x8018, 74},
+        {0x801f, 74},
+        {0x8029, 74},
+        {0xc038, 74},
+    },
+    /* 48 */
+    {
+        {0x8003, 75},
+        {0x8006, 75},
+        {0x800a, 75},
+        {0x800f, 75},
+        {0x8018, 75},
+        {0x801f, 75},
+        {0x8029, 75},
+        {0xc038, 75},
+        {0x8003, 76},
+        {0x8006, 76},
+        {0x800a, 76},
+        {0x800f, 76},
+        {0x8018, 76},
+        {0x801f, 76},
+        {0x8029, 76},
+        {0xc038, 76},
+    },
+    /* 49 */
+    {
+        {0x8001, 77},
+        {0xc016, 77},
+        {0x8001, 78},
+        {0xc016, 78},
+        {0x8001, 79},
+        {0xc016, 79},
+        {0x8001, 80},
+        {0xc016, 80},
+        {0x8001, 81},
+        {0xc016, 81},
+        {0x8001, 82},
+        {0xc016, 82},
+        {0x8001, 83},
+        {0xc016, 83},
+        {0x8001, 84},
+        {0xc016, 84},
+    },
+    /* 50 */
+    {
+        {0x8002, 77},
+        {0x8009, 77},
+        {0x8017, 77},
+        {0xc028, 77},
+        {0x8002, 78},
+        {0x8009, 78},
+        {0x8017, 78},
+        {0xc028, 78},
+        {0x8002, 79},
+        {0x8009, 79},
+        {0x8017, 79},
+        {0xc028, 79},
+        {0x8002, 80},
+        {0x8009, 80},
+        {0x8017, 80},
+        {0xc028, 80},
+    },
+    /* 51 */
+    {
+        {0x8003, 77},
+        {0x8006, 77},
+        {0x800a, 77},
+        {0x800f, 77},
+        {0x8018, 77},
+        {0x801f, 77},
+        {0x8029, 77},
+        {0xc038, 77},
+        {0x8003, 78},
+        {0x8006, 78},
+        {0x800a, 78},
+        {0x800f, 78},
+        {0x8018, 78},
+        {0x801f, 78},
+        {0x8029, 78},
+        {0xc038, 78},
+    },
+    /* 52 */
+    {
+        {0x8003, 79},
+        {0x8006, 79},
+        {0x800a, 79},
+        {0x800f, 79},
+        {0x8018, 79},
+        {0x801f, 79},
+        {0x8029, 79},
+        {0xc038, 79},
+        {0x8003, 80},
+        {0x8006, 80},
+        {0x800a, 80},
+        {0x800f, 80},
+        {0x8018, 80},
+        {0x801f, 80},
+        {0x8029, 80},
+        {0xc038, 80},
+    },
+    /* 53 */
+    {
+        {0x8002, 81},
+        {0x8009, 81},
+        {0x8017, 81},
+        {0xc028, 81},
+        {0x8002, 82},
+        {0x8009, 82},
+        {0x8017, 82},
+        {0xc028, 82},
+        {0x8002, 83},
+        {0x8009, 83},
+        {0x8017, 83},
+        {0xc028, 83},
+        {0x8002, 84},
+        {0x8009, 84},
+        {0x8017, 84},
+        {0xc028, 84},
+    },
+    /* 54 */
+    {
+        {0x8003, 81},
+        {0x8006, 81},
+        {0x800a, 81},
+        {0x800f, 81},
+        {0x8018, 81},
+        {0x801f, 81},
+        {0x8029, 81},
+        {0xc038, 81},
+        {0x8003, 82},
+        {0x8006, 82},
+        {0x800a, 82},
+        {0x800f, 82},
+        {0x8018, 82},
+        {0x801f, 82},
+        {0x8029, 82},
+        {0xc038, 82},
+    },
+    /* 55 */
+    {
+        {0x8003, 83},
+        {0x8006, 83},
+        {0x800a, 83},
+        {0x800f, 83},
+        {0x8018, 83},
+        {0x801f, 83},
+        {0x8029, 83},
+        {0xc038, 83},
+        {0x8003, 84},
+        {0x8006, 84},
+        {0x800a, 84},
+        {0x800f, 84},
+        {0x8018, 84},
+        {0x801f, 84},
+        {0x8029, 84},
+        {0xc038, 84},
+    },
+    /* 56 */
+    {
+        {0xc000, 85},
+        {0xc000, 86},
+        {0xc000, 87},
+        {0xc000, 89},
+        {0xc000, 106},
+        {0xc000, 107},
+        {0xc000, 113},
+        {0xc000, 118},
+        {0xc000, 119},
+        {0xc000, 120},
+        {0xc000, 121},
+        {0xc000, 122},
+        {0x46, 0},
+        {0x47, 0},
+        {0x49, 0},
+        {0x404a, 0},
+    },
+    /* 57 */
+    {
+        {0x8001, 85},
+        {0xc016, 85},
+        {0x8001, 86},
+        {0xc016, 86},
+        {0x8001, 87},
+        {0xc016, 87},
+        {0x8001, 89},
+        {0xc016, 89},
+        {0x8001, 106},
+        {0xc016, 106},
+        {0x8001, 107},
+        {0xc016, 107},
+        {0x8001, 113},
+        {0xc016, 113},
+        {0x8001, 118},
+        {0xc016, 118},
+    },
+    /* 58 */
+    {
+        {0x8002, 85},
+        {0x8009, 85},
+        {0x8017, 85},
+        {0xc028, 85},
+        {0x8002, 86},
+        {0x8009, 86},
+        {0x8017, 86},
+        {0xc028, 86},
+        {0x8002, 87},
+        {0x8009, 87},
+        {0x8017, 87},
+        {0xc028, 87},
+        {0x8002, 89},
+        {0x8009, 89},
+        {0x8017, 89},
+        {0xc028, 89},
+    },
+    /* 59 */
+    {
+        {0x8003, 85},
+        {0x8006, 85},
+        {0x800a, 85},
+        {0x800f, 85},
+        {0x8018, 85},
+        {0x801f, 85},
+        {0x8029, 85},
+        {0xc038, 85},
+        {0x8003, 86},
+        {0x8006, 86},
+        {0x800a, 86},
+        {0x800f, 86},
+        {0x8018, 86},
+        {0x801f, 86},
+        {0x8029, 86},
+        {0xc038, 86},
+    },
+    /* 60 */
+    {
+        {0x8003, 87},
+        {0x8006, 87},
+        {0x800a, 87},
+        {0x800f, 87},
+        {0x8018, 87},
+        {0x801f, 87},
+        {0x8029, 87},
+        {0xc038, 87},
+        {0x8003, 89},
+        {0x8006, 89},
+        {0x800a, 89},
+        {0x800f, 89},
+        {0x8018, 89},
+        {0x801f, 89},
+        {0x8029, 89},
+        {0xc038, 89},
+    },
+    /* 61 */
+    {
+        {0x8002, 106},
+        {0x8009, 106},
+        {0x8017, 106},
+        {0xc028, 106},
+        {0x8002, 107},
+        {0x8009, 107},
+        {0x8017, 107},
+        {0xc028, 107},
+        {0x8002, 113},
+        {0x8009, 113},
+        {0x8017, 113},
+        {0xc028, 113},
+        {0x8002, 118},
+        {0x8009, 118},
+        {0x8017, 118},
+        {0xc028, 118},
+    },
+    /* 62 */
+    {
+        {0x8003, 106},
+        {0x8006, 106},
+        {0x800a, 106},
+        {0x800f, 106},
+        {0x8018, 106},
+        {0x801f, 106},
+        {0x8029, 106},
+        {0xc038, 106},
+        {0x8003, 107},
+        {0x8006, 107},
+        {0x800a, 107},
+        {0x800f, 107},
+        {0x8018, 107},
+        {0x801f, 107},
+        {0x8029, 107},
+        {0xc038, 107},
+    },
+    /* 63 */
+    {
+        {0x8003, 113},
+        {0x8006, 113},
+        {0x800a, 113},
+        {0x800f, 113},
+        {0x8018, 113},
+        {0x801f, 113},
+        {0x8029, 113},
+        {0xc038, 113},
+        {0x8003, 118},
+        {0x8006, 118},
+        {0x800a, 118},
+        {0x800f, 118},
+        {0x8018, 118},
+        {0x801f, 118},
+        {0x8029, 118},
+        {0xc038, 118},
+    },
+    /* 64 */
+    {
+        {0x8001, 119},
+        {0xc016, 119},
+        {0x8001, 120},
+        {0xc016, 120},
+        {0x8001, 121},
+        {0xc016, 121},
+        {0x8001, 122},
+        {0xc016, 122},
+        {0xc000, 38},
+        {0xc000, 42},
+        {0xc000, 44},
+        {0xc000, 59},
+        {0xc000, 88},
+        {0xc000, 90},
+        {0x4b, 0},
+        {0x4e, 0},
+    },
+    /* 65 */
+    {
+        {0x8002, 119},
+        {0x8009, 119},
+        {0x8017, 119},
+        {0xc028, 119},
+        {0x8002, 120},
+        {0x8009, 120},
+        {0x8017, 120},
+        {0xc028, 120},
+        {0x8002, 121},
+        {0x8009, 121},
+        {0x8017, 121},
+        {0xc028, 121},
+        {0x8002, 122},
+        {0x8009, 122},
+        {0x8017, 122},
+        {0xc028, 122},
+    },
+    /* 66 */
+    {
+        {0x8003, 119},
+        {0x8006, 119},
+        {0x800a, 119},
+        {0x800f, 119},
+        {0x8018, 119},
+        {0x801f, 119},
+        {0x8029, 119},
+        {0xc038, 119},
+        {0x8003, 120},
+        {0x8006, 120},
+        {0x800a, 120},
+        {0x800f, 120},
+        {0x8018, 120},
+        {0x801f, 120},
+        {0x8029, 120},
+        {0xc038, 120},
+    },
+    /* 67 */
+    {
+        {0x8003, 121},
+        {0x8006, 121},
+        {0x800a, 121},
+        {0x800f, 121},
+        {0x8018, 121},
+        {0x801f, 121},
+        {0x8029, 121},
+        {0xc038, 121},
+        {0x8003, 122},
+        {0x8006, 122},
+        {0x800a, 122},
+        {0x800f, 122},
+        {0x8018, 122},
+        {0x801f, 122},
+        {0x8029, 122},
+        {0xc038, 122},
+    },
+    /* 68 */
+    {
+        {0x8001, 38},
+        {0xc016, 38},
+        {0x8001, 42},
+        {0xc016, 42},
+        {0x8001, 44},
+        {0xc016, 44},
+        {0x8001, 59},
+        {0xc016, 59},
+        {0x8001, 88},
+        {0xc016, 88},
+        {0x8001, 90},
+        {0xc016, 90},
+        {0x4c, 0},
+        {0x4d, 0},
+        {0x4f, 0},
+        {0x51, 0},
+    },
+    /* 69 */
+    {
+        {0x8002, 38},
+        {0x8009, 38},
+        {0x8017, 38},
+        {0xc028, 38},
+        {0x8002, 42},
+        {0x8009, 42},
+        {0x8017, 42},
+        {0xc028, 42},
+        {0x8002, 44},
+        {0x8009, 44},
+        {0x8017, 44},
+        {0xc028, 44},
+        {0x8002, 59},
+        {0x8009, 59},
+        {0x8017, 59},
+        {0xc028, 59},
+    },
+    /* 70 */
+    {
+        {0x8003, 38},
+        {0x8006, 38},
+        {0x800a, 38},
+        {0x800f, 38},
+        {0x8018, 38},
+        {0x801f, 38},
+        {0x8029, 38},
+        {0xc038, 38},
+        {0x8003, 42},
+        {0x8006, 42},
+        {0x800a, 42},
+        {0x800f, 42},
+        {0x8018, 42},
+        {0x801f, 42},
+        {0x8029, 42},
+        {0xc038, 42},
+    },
+    /* 71 */
+    {
+        {0x8003, 44},
+        {0x8006, 44},
+        {0x800a, 44},
+        {0x800f, 44},
+        {0x8018, 44},
+        {0x801f, 44},
+        {0x8029, 44},
+        {0xc038, 44},
+        {0x8003, 59},
+        {0x8006, 59},
+        {0x800a, 59},
+        {0x800f, 59},
+        {0x8018, 59},
+        {0x801f, 59},
+        {0x8029, 59},
+        {0xc038, 59},
+    },
+    /* 72 */
+    {
+        {0x8002, 88},
+        {0x8009, 88},
+        {0x8017, 88},
+        {0xc028, 88},
+        {0x8002, 90},
+        {0x8009, 90},
+        {0x8017, 90},
+        {0xc028, 90},
+        {0xc000, 33},
+        {0xc000, 34},
+        {0xc000, 40},
+        {0xc000, 41},
+        {0xc000, 63},
+        {0x50, 0},
+        {0x52, 0},
+        {0x54, 0},
+    },
+    /* 73 */
+    {
+        {0x8003, 88},
+        {0x8006, 88},
+        {0x800a, 88},
+        {0x800f, 88},
+        {0x8018, 88},
+        {0x801f, 88},
+        {0x8029, 88},
+        {0xc038, 88},
+        {0x8003, 90},
+        {0x8006, 90},
+        {0x800a, 90},
+        {0x800f, 90},
+        {0x8018, 90},
+        {0x801f, 90},
+        {0x8029, 90},
+        {0xc038, 90},
+    },
+    /* 74 */
+    {
+        {0x8001, 33},
+        {0xc016, 33},
+        {0x8001, 34},
+        {0xc016, 34},
+        {0x8001, 40},
+        {0xc016, 40},
+        {0x8001, 41},
+        {0xc016, 41},
+        {0x8001, 63},
+        {0xc016, 63},
+        {0xc000, 39},
+        {0xc000, 43},
+        {0xc000, 124},
+        {0x53, 0},
+        {0x55, 0},
+        {0x58, 0},
+    },
+    /* 75 */
+    {
+        {0x8002, 33},
+        {0x8009, 33},
+        {0x8017, 33},
+        {0xc028, 33},
+        {0x8002, 34},
+        {0x8009, 34},
+        {0x8017, 34},
+        {0xc028, 34},
+        {0x8002, 40},
+        {0x8009, 40},
+        {0x8017, 40},
+        {0xc028, 40},
+        {0x8002, 41},
+        {0x8009, 41},
+        {0x8017, 41},
+        {0xc028, 41},
+    },
+    /* 76 */
+    {
+        {0x8003, 33},
+        {0x8006, 33},
+        {0x800a, 33},
+        {0x800f, 33},
+        {0x8018, 33},
+        {0x801f, 33},
+        {0x8029, 33},
+        {0xc038, 33},
+        {0x8003, 34},
+        {0x8006, 34},
+        {0x800a, 34},
+        {0x800f, 34},
+        {0x8018, 34},
+        {0x801f, 34},
+        {0x8029, 34},
+        {0xc038, 34},
+    },
+    /* 77 */
+    {
+        {0x8003, 40},
+        {0x8006, 40},
+        {0x800a, 40},
+        {0x800f, 40},
+        {0x8018, 40},
+        {0x801f, 40},
+        {0x8029, 40},
+        {0xc038, 40},
+        {0x8003, 41},
+        {0x8006, 41},
+        {0x800a, 41},
+        {0x800f, 41},
+        {0x8018, 41},
+        {0x801f, 41},
+        {0x8029, 41},
+        {0xc038, 41},
+    },
+    /* 78 */
+    {
+        {0x8002, 63},
+        {0x8009, 63},
+        {0x8017, 63},
+        {0xc028, 63},
+        {0x8001, 39},
+        {0xc016, 39},
+        {0x8001, 43},
+        {0xc016, 43},
+        {0x8001, 124},
+        {0xc016, 124},
+        {0xc000, 35},
+        {0xc000, 62},
+        {0x56, 0},
+        {0x57, 0},
+        {0x59, 0},
+        {0x5a, 0},
+    },
+    /* 79 */
+    {
+        {0x8003, 63},
+        {0x8006, 63},
+        {0x800a, 63},
+        {0x800f, 63},
+        {0x8018, 63},
+        {0x801f, 63},
+        {0x8029, 63},
+        {0xc038, 63},
+        {0x8002, 39},
+        {0x8009, 39},
+        {0x8017, 39},
+        {0xc028, 39},
+        {0x8002, 43},
+        {0x8009, 43},
+        {0x8017, 43},
+        {0xc028, 43},
+    },
+    /* 80 */
+    {
+        {0x8003, 39},
+        {0x8006, 39},
+        {0x800a, 39},
+        {0x800f, 39},
+        {0x8018, 39},
+        {0x801f, 39},
+        {0x8029, 39},
+        {0xc038, 39},
+        {0x8003, 43},
+        {0x8006, 43},
+        {0x800a, 43},
+        {0x800f, 43},
+        {0x8018, 43},
+        {0x801f, 43},
+        {0x8029, 43},
+        {0xc038, 43},
+    },
+    /* 81 */
+    {
+        {0x8002, 124},
+        {0x8009, 124},
+        {0x8017, 124},
+        {0xc028, 124},
+        {0x8001, 35},
+        {0xc016, 35},
+        {0x8001, 62},
+        {0xc016, 62},
+        {0xc000, 0},
+        {0xc000, 36},
+        {0xc000, 64},
+        {0xc000, 91},
+        {0xc000, 93},
+        {0xc000, 126},
+        {0x5b, 0},
+        {0x5c, 0},
+    },
+    /* 82 */
+    {
+        {0x8003, 124},
+        {0x8006, 124},
+        {0x800a, 124},
+        {0x800f, 124},
+        {0x8018, 124},
+        {0x801f, 124},
+        {0x8029, 124},
+        {0xc038, 124},
+        {0x8002, 35},
+        {0x8009, 35},
+        {0x8017, 35},
+        {0xc028, 35},
+        {0x8002, 62},
+        {0x8009, 62},
+        {0x8017, 62},
+        {0xc028, 62},
+    },
+    /* 83 */
+    {
+        {0x8003, 35},
+        {0x8006, 35},
+        {0x800a, 35},
+        {0x800f, 35},
+        {0x8018, 35},
+        {0x801f, 35},
+        {0x8029, 35},
+        {0xc038, 35},
+        {0x8003, 62},
+        {0x8006, 62},
+        {0x800a, 62},
+        {0x800f, 62},
+        {0x8018, 62},
+        {0x801f, 62},
+        {0x8029, 62},
+        {0xc038, 62},
+    },
+    /* 84 */
+    {
+        {0x8001, 0},
+        {0xc016, 0},
+        {0x8001, 36},
+        {0xc016, 36},
+        {0x8001, 64},
+        {0xc016, 64},
+        {0x8001, 91},
+        {0xc016, 91},
+        {0x8001, 93},
+        {0xc016, 93},
+        {0x8001, 126},
+        {0xc016, 126},
+        {0xc000, 94},
+        {0xc000, 125},
+        {0x5d, 0},
+        {0x5e, 0},
+    },
+    /* 85 */
+    {
+        {0x8002, 0},
+        {0x8009, 0},
+        {0x8017, 0},
+        {0xc028, 0},
+        {0x8002, 36},
+        {0x8009, 36},
+        {0x8017, 36},
+        {0xc028, 36},
+        {0x8002, 64},
+        {0x8009, 64},
+        {0x8017, 64},
+        {0xc028, 64},
+        {0x8002, 91},
+        {0x8009, 91},
+        {0x8017, 91},
+        {0xc028, 91},
+    },
+    /* 86 */
+    {
+        {0x8003, 0},
+        {0x8006, 0},
+        {0x800a, 0},
+        {0x800f, 0},
+        {0x8018, 0},
+        {0x801f, 0},
+        {0x8029, 0},
+        {0xc038, 0},
+        {0x8003, 36},
+        {0x8006, 36},
+        {0x800a, 36},
+        {0x800f, 36},
+        {0x8018, 36},
+        {0x801f, 36},
+        {0x8029, 36},
+        {0xc038, 36},
+    },
+    /* 87 */
+    {
+        {0x8003, 64},
+        {0x8006, 64},
+        {0x800a, 64},
+        {0x800f, 64},
+        {0x8018, 64},
+        {0x801f, 64},
+        {0x8029, 64},
+        {0xc038, 64},
+        {0x8003, 91},
+        {0x8006, 91},
+        {0x800a, 91},
+        {0x800f, 91},
+        {0x8018, 91},
+        {0x801f, 91},
+        {0x8029, 91},
+        {0xc038, 91},
+    },
+    /* 88 */
+    {
+        {0x8002, 93},
+        {0x8009, 93},
+        {0x8017, 93},
+        {0xc028, 93},
+        {0x8002, 126},
+        {0x8009, 126},
+        {0x8017, 126},
+        {0xc028, 126},
+        {0x8001, 94},
+        {0xc016, 94},
+        {0x8001, 125},
+        {0xc016, 125},
+        {0xc000, 60},
+        {0xc000, 96},
+        {0xc000, 123},
+        {0x5f, 0},
+    },
+    /* 89 */
+    {
+        {0x8003, 93},
+        {0x8006, 93},
+        {0x800a, 93},
+        {0x800f, 93},
+        {0x8018, 93},
+        {0x801f, 93},
+        {0x8029, 93},
+        {0xc038, 93},
+        {0x8003, 126},
+        {0x8006, 126},
+        {0x800a, 126},
+        {0x800f, 126},
+        {0x8018, 126},
+        {0x801f, 126},
+        {0x8029, 126},
+        {0xc038, 126},
+    },
+    /* 90 */
+    {
+        {0x8002, 94},
+        {0x8009, 94},
+        {0x8017, 94},
+        {0xc028, 94},
+        {0x8002, 125},
+        {0x8009, 125},
+        {0x8017, 125},
+        {0xc028, 125},
+        {0x8001, 60},
+        {0xc016, 60},
+        {0x8001, 96},
+        {0xc016, 96},
+        {0x8001, 123},
+        {0xc016, 123},
+        {0x60, 0},
+        {0x6e, 0},
+    },
+    /* 91 */
+    {
+        {0x8003, 94},
+        {0x8006, 94},
+        {0x800a, 94},
+        {0x800f, 94},
+        {0x8018, 94},
+        {0x801f, 94},
+        {0x8029, 94},
+        {0xc038, 94},
+        {0x8003, 125},
+        {0x8006, 125},
+        {0x800a, 125},
+        {0x800f, 125},
+        {0x8018, 125},
+        {0x801f, 125},
+        {0x8029, 125},
+        {0xc038, 125},
+    },
+    /* 92 */
+    {
+        {0x8002, 60},
+        {0x8009, 60},
+        {0x8017, 60},
+        {0xc028, 60},
+        {0x8002, 96},
+        {0x8009, 96},
+        {0x8017, 96},
+        {0xc028, 96},
+        {0x8002, 123},
+        {0x8009, 123},
+        {0x8017, 123},
+        {0xc028, 123},
+        {0x61, 0},
+        {0x65, 0},
+        {0x6f, 0},
+        {0x85, 0},
+    },
+    /* 93 */
+    {
+        {0x8003, 60},
+        {0x8006, 60},
+        {0x800a, 60},
+        {0x800f, 60},
+        {0x8018, 60},
+        {0x801f, 60},
+        {0x8029, 60},
+        {0xc038, 60},
+        {0x8003, 96},
+        {0x8006, 96},
+        {0x800a, 96},
+        {0x800f, 96},
+        {0x8018, 96},
+        {0x801f, 96},
+        {0x8029, 96},
+        {0xc038, 96},
+    },
+    /* 94 */
+    {
+        {0x8003, 123},
+        {0x8006, 123},
+        {0x800a, 123},
+        {0x800f, 123},
+        {0x8018, 123},
+        {0x801f, 123},
+        {0x8029, 123},
+        {0xc038, 123},
+        {0x62, 0},
+        {0x63, 0},
+        {0x66, 0},
+        {0x69, 0},
+        {0x70, 0},
+        {0x77, 0},
+        {0x86, 0},
+        {0x99, 0},
+    },
+    /* 95 */
+    {
+        {0xc000, 92},
+        {0xc000, 195},
+        {0xc000, 208},
+        {0x64, 0},
+        {0x67, 0},
+        {0x68, 0},
+        {0x6a, 0},
+        {0x6b, 0},
+        {0x71, 0},
+        {0x74, 0},
+        {0x78, 0},
+        {0x7e, 0},
+        {0x87, 0},
+        {0x8e, 0},
+        {0x9a, 0},
+        {0xa9, 0},
+    },
+    /* 96 */
+    {
+        {0x8001, 92},
+        {0xc016, 92},
+        {0x8001, 195},
+        {0xc016, 195},
+        {0x8001, 208},
+        {0xc016, 208},
+        {0xc000, 128},
+        {0xc000, 130},
+        {0xc000, 131},
+        {0xc000, 162},
+        {0xc000, 184},
+        {0xc000, 194},
+        {0xc000, 224},
+        {0xc000, 226},
+        {0x6c, 0},
+        {0x6d, 0},
+    },
+    /* 97 */
+    {
+        {0x8002, 92},
+        {0x8009, 92},
+        {0x8017, 92},
+        {0xc028, 92},
+        {0x8002, 195},
+        {0x8009, 195},
+        {0x8017, 195},
+        {0xc028, 195},
+        {0x8002, 208},
+        {0x8009, 208},
+        {0x8017, 208},
+        {0xc028, 208},
+        {0x8001, 128},
+        {0xc016, 128},
+        {0x8001, 130},
+        {0xc016, 130},
+    },
+    /* 98 */
+    {
+        {0x8003, 92},
+        {0x8006, 92},
+        {0x800a, 92},
+        {0x800f, 92},
+        {0x8018, 92},
+        {0x801f, 92},
+        {0x8029, 92},
+        {0xc038, 92},
+        {0x8003, 195},
+        {0x8006, 195},
+        {0x800a, 195},
+        {0x800f, 195},
+        {0x8018, 195},
+        {0x801f, 195},
+        {0x8029, 195},
+        {0xc038, 195},
+    },
+    /* 99 */
+    {
+        {0x8003, 208},
+        {0x8006, 208},
+        {0x800a, 208},
+        {0x800f, 208},
+        {0x8018, 208},
+        {0x801f, 208},
+        {0x8029, 208},
+        {0xc038, 208},
+        {0x8002, 128},
+        {0x8009, 128},
+        {0x8017, 128},
+        {0xc028, 128},
+        {0x8002, 130},
+        {0x8009, 130},
+        {0x8017, 130},
+        {0xc028, 130},
+    },
+    /* 100 */
+    {
+        {0x8003, 128},
+        {0x8006, 128},
+        {0x800a, 128},
+        {0x800f, 128},
+        {0x8018, 128},
+        {0x801f, 128},
+        {0x8029, 128},
+        {0xc038, 128},
+        {0x8003, 130},
+        {0x8006, 130},
+        {0x800a, 130},
+        {0x800f, 130},
+        {0x8018, 130},
+        {0x801f, 130},
+        {0x8029, 130},
+        {0xc038, 130},
+    },
+    /* 101 */
+    {
+        {0x8001, 131},
+        {0xc016, 131},
+        {0x8001, 162},
+        {0xc016, 162},
+        {0x8001, 184},
+        {0xc016, 184},
+        {0x8001, 194},
+        {0xc016, 194},
+        {0x8001, 224},
+        {0xc016, 224},
+        {0x8001, 226},
+        {0xc016, 226},
+        {0xc000, 153},
+        {0xc000, 161},
+        {0xc000, 167},
+        {0xc000, 172},
+    },
+    /* 102 */
+    {
+        {0x8002, 131},
+        {0x8009, 131},
+        {0x8017, 131},
+        {0xc028, 131},
+        {0x8002, 162},
+        {0x8009, 162},
+        {0x8017, 162},
+        {0xc028, 162},
+        {0x8002, 184},
+        {0x8009, 184},
+        {0x8017, 184},
+        {0xc028, 184},
+        {0x8002, 194},
+        {0x8009, 194},
+        {0x8017, 194},
+        {0xc028, 194},
+    },
+    /* 103 */
+    {
+        {0x8003, 131},
+        {0x8006, 131},
+        {0x800a, 131},
+        {0x800f, 131},
+        {0x8018, 131},
+        {0x801f, 131},
+        {0x8029, 131},
+        {0xc038, 131},
+        {0x8003, 162},
+        {0x8006, 162},
+        {0x800a, 162},
+        {0x800f, 162},
+        {0x8018, 162},
+        {0x801f, 162},
+        {0x8029, 162},
+        {0xc038, 162},
+    },
+    /* 104 */
+    {
+        {0x8003, 184},
+        {0x8006, 184},
+        {0x800a, 184},
+        {0x800f, 184},
+        {0x8018, 184},
+        {0x801f, 184},
+        {0x8029, 184},
+        {0xc038, 184},
+        {0x8003, 194},
+        {0x8006, 194},
+        {0x800a, 194},
+        {0x800f, 194},
+        {0x8018, 194},
+        {0x801f, 194},
+        {0x8029, 194},
+        {0xc038, 194},
+    },
+    /* 105 */
+    {
+        {0x8002, 224},
+        {0x8009, 224},
+        {0x8017, 224},
+        {0xc028, 224},
+        {0x8002, 226},
+        {0x8009, 226},
+        {0x8017, 226},
+        {0xc028, 226},
+        {0x8001, 153},
+        {0xc016, 153},
+        {0x8001, 161},
+        {0xc016, 161},
+        {0x8001, 167},
+        {0xc016, 167},
+        {0x8001, 172},
+        {0xc016, 172},
+    },
+    /* 106 */
+    {
+        {0x8003, 224},
+        {0x8006, 224},
+        {0x800a, 224},
+        {0x800f, 224},
+        {0x8018, 224},
+        {0x801f, 224},
+        {0x8029, 224},
+        {0xc038, 224},
+        {0x8003, 226},
+        {0x8006, 226},
+        {0x800a, 226},
+        {0x800f, 226},
+        {0x8018, 226},
+        {0x801f, 226},
+        {0x8029, 226},
+        {0xc038, 226},
+    },
+    /* 107 */
+    {
+        {0x8002, 153},
+        {0x8009, 153},
+        {0x8017, 153},
+        {0xc028, 153},
+        {0x8002, 161},
+        {0x8009, 161},
+        {0x8017, 161},
+        {0xc028, 161},
+        {0x8002, 167},
+        {0x8009, 167},
+        {0x8017, 167},
+        {0xc028, 167},
+        {0x8002, 172},
+        {0x8009, 172},
+        {0x8017, 172},
+        {0xc028, 172},
+    },
+    /* 108 */
+    {
+        {0x8003, 153},
+        {0x8006, 153},
+        {0x800a, 153},
+        {0x800f, 153},
+        {0x8018, 153},
+        {0x801f, 153},
+        {0x8029, 153},
+        {0xc038, 153},
+        {0x8003, 161},
+        {0x8006, 161},
+        {0x800a, 161},
+        {0x800f, 161},
+        {0x8018, 161},
+        {0x801f, 161},
+        {0x8029, 161},
+        {0xc038, 161},
+    },
+    /* 109 */
+    {
+        {0x8003, 167},
+        {0x8006, 167},
+        {0x800a, 167},
+        {0x800f, 167},
+        {0x8018, 167},
+        {0x801f, 167},
+        {0x8029, 167},
+        {0xc038, 167},
+        {0x8003, 172},
+        {0x8006, 172},
+        {0x800a, 172},
+        {0x800f, 172},
+        {0x8018, 172},
+        {0x801f, 172},
+        {0x8029, 172},
+        {0xc038, 172},
+    },
+    /* 110 */
+    {
+        {0x72, 0},
+        {0x73, 0},
+        {0x75, 0},
+        {0x76, 0},
+        {0x79, 0},
+        {0x7b, 0},
+        {0x7f, 0},
+        {0x82, 0},
+        {0x88, 0},
+        {0x8b, 0},
+        {0x8f, 0},
+        {0x92, 0},
+        {0x9b, 0},
+        {0xa2, 0},
+        {0xaa, 0},
+        {0xb4, 0},
+    },
+    /* 111 */
+    {
+        {0xc000, 176},
+        {0xc000, 177},
+        {0xc000, 179},
+        {0xc000, 209},
+        {0xc000, 216},
+        {0xc000, 217},
+        {0xc000, 227},
+        {0xc000, 229},
+        {0xc000, 230},
+        {0x7a, 0},
+        {0x7c, 0},
+        {0x7d, 0},
+        {0x80, 0},
+        {0x81, 0},
+        {0x83, 0},
+        {0x84, 0},
+    },
+    /* 112 */
+    {
+        {0x8001, 176},
+        {0xc016, 176},
+        {0x8001, 177},
+        {0xc016, 177},
+        {0x8001, 179},
+        {0xc016, 179},
+        {0x8001, 209},
+        {0xc016, 209},
+        {0x8001, 216},
+        {0xc016, 216},
+        {0x8001, 217},
+        {0xc016, 217},
+        {0x8001, 227},
+        {0xc016, 227},
+        {0x8001, 229},
+        {0xc016, 229},
+    },
+    /* 113 */
+    {
+        {0x8002, 176},
+        {0x8009, 176},
+        {0x8017, 176},
+        {0xc028, 176},
+        {0x8002, 177},
+        {0x8009, 177},
+        {0x8017, 177},
+        {0xc028, 177},
+        {0x8002, 179},
+        {0x8009, 179},
+        {0x8017, 179},
+        {0xc028, 179},
+        {0x8002, 209},
+        {0x8009, 209},
+        {0x8017, 209},
+        {0xc028, 209},
+    },
+    /* 114 */
+    {
+        {0x8003, 176},
+        {0x8006, 176},
+        {0x800a, 176},
+        {0x800f, 176},
+        {0x8018, 176},
+        {0x801f, 176},
+        {0x8029, 176},
+        {0xc038, 176},
+        {0x8003, 177},
+        {0x8006, 177},
+        {0x800a, 177},
+        {0x800f, 177},
+        {0x8018, 177},
+        {0x801f, 177},
+        {0x8029, 177},
+        {0xc038, 177},
+    },
+    /* 115 */
+    {
+        {0x8003, 179},
+        {0x8006, 179},
+        {0x800a, 179},
+        {0x800f, 179},
+        {0x8018, 179},
+        {0x801f, 179},
+        {0x8029, 179},
+        {0xc038, 179},
+        {0x8003, 209},
+        {0x8006, 209},
+        {0x800a, 209},
+        {0x800f, 209},
+        {0x8018, 209},
+        {0x801f, 209},
+        {0x8029, 209},
+        {0xc038, 209},
+    },
+    /* 116 */
+    {
+        {0x8002, 216},
+        {0x8009, 216},
+        {0x8017, 216},
+        {0xc028, 216},
+        {0x8002, 217},
+        {0x8009, 217},
+        {0x8017, 217},
+        {0xc028, 217},
+        {0x8002, 227},
+        {0x8009, 227},
+        {0x8017, 227},
+        {0xc028, 227},
+        {0x8002, 229},
+        {0x8009, 229},
+        {0x8017, 229},
+        {0xc028, 229},
+    },
+    /* 117 */
+    {
+        {0x8003, 216},
+        {0x8006, 216},
+        {0x800a, 216},
+        {0x800f, 216},
+        {0x8018, 216},
+        {0x801f, 216},
+        {0x8029, 216},
+        {0xc038, 216},
+        {0x8003, 217},
+        {0x8006, 217},
+        {0x800a, 217},
+        {0x800f, 217},
+        {0x8018, 217},
+        {0x801f, 217},
+        {0x8029, 217},
+        {0xc038, 217},
+    },
+    /* 118 */
+    {
+        {0x8003, 227},
+        {0x8006, 227},
+        {0x800a, 227},
+        {0x800f, 227},
+        {0x8018, 227},
+        {0x801f, 227},
+        {0x8029, 227},
+        {0xc038, 227},
+        {0x8003, 229},
+        {0x8006, 229},
+        {0x800a, 229},
+        {0x800f, 229},
+        {0x8018, 229},
+        {0x801f, 229},
+        {0x8029, 229},
+        {0xc038, 229},
+    },
+    /* 119 */
+    {
+        {0x8001, 230},
+        {0xc016, 230},
+        {0xc000, 129},
+        {0xc000, 132},
+        {0xc000, 133},
+        {0xc000, 134},
+        {0xc000, 136},
+        {0xc000, 146},
+        {0xc000, 154},
+        {0xc000, 156},
+        {0xc000, 160},
+        {0xc000, 163},
+        {0xc000, 164},
+        {0xc000, 169},
+        {0xc000, 170},
+        {0xc000, 173},
+    },
+    /* 120 */
+    {
+        {0x8002, 230},
+        {0x8009, 230},
+        {0x8017, 230},
+        {0xc028, 230},
+        {0x8001, 129},
+        {0xc016, 129},
+        {0x8001, 132},
+        {0xc016, 132},
+        {0x8001, 133},
+        {0xc016, 133},
+        {0x8001, 134},
+        {0xc016, 134},
+        {0x8001, 136},
+        {0xc016, 136},
+        {0x8001, 146},
+        {0xc016, 146},
+    },
+    /* 121 */
+    {
+        {0x8003, 230},
+        {0x8006, 230},
+        {0x800a, 230},
+        {0x800f, 230},
+        {0x8018, 230},
+        {0x801f, 230},
+        {0x8029, 230},
+        {0xc038, 230},
+        {0x8002, 129},
+        {0x8009, 129},
+        {0x8017, 129},
+        {0xc028, 129},
+        {0x8002, 132},
+        {0x8009, 132},
+        {0x8017, 132},
+        {0xc028, 132},
+    },
+    /* 122 */
+    {
+        {0x8003, 129},
+        {0x8006, 129},
+        {0x800a, 129},
+        {0x800f, 129},
+        {0x8018, 129},
+        {0x801f, 129},
+        {0x8029, 129},
+        {0xc038, 129},
+        {0x8003, 132},
+        {0x8006, 132},
+        {0x800a, 132},
+        {0x800f, 132},
+        {0x8018, 132},
+        {0x801f, 132},
+        {0x8029, 132},
+        {0xc038, 132},
+    },
+    /* 123 */
+    {
+        {0x8002, 133},
+        {0x8009, 133},
+        {0x8017, 133},
+        {0xc028, 133},
+        {0x8002, 134},
+        {0x8009, 134},
+        {0x8017, 134},
+        {0xc028, 134},
+        {0x8002, 136},
+        {0x8009, 136},
+        {0x8017, 136},
+        {0xc028, 136},
+        {0x8002, 146},
+        {0x8009, 146},
+        {0x8017, 146},
+        {0xc028, 146},
+    },
+    /* 124 */
+    {
+        {0x8003, 133},
+        {0x8006, 133},
+        {0x800a, 133},
+        {0x800f, 133},
+        {0x8018, 133},
+        {0x801f, 133},
+        {0x8029, 133},
+        {0xc038, 133},
+        {0x8003, 134},
+        {0x8006, 134},
+        {0x800a, 134},
+        {0x800f, 134},
+        {0x8018, 134},
+        {0x801f, 134},
+        {0x8029, 134},
+        {0xc038, 134},
+    },
+    /* 125 */
+    {
+        {0x8003, 136},
+        {0x8006, 136},
+        {0x800a, 136},
+        {0x800f, 136},
+        {0x8018, 136},
+        {0x801f, 136},
+        {0x8029, 136},
+        {0xc038, 136},
+        {0x8003, 146},
+        {0x8006, 146},
+        {0x800a, 146},
+        {0x800f, 146},
+        {0x8018, 146},
+        {0x801f, 146},
+        {0x8029, 146},
+        {0xc038, 146},
+    },
+    /* 126 */
+    {
+        {0x8001, 154},
+        {0xc016, 154},
+        {0x8001, 156},
+        {0xc016, 156},
+        {0x8001, 160},
+        {0xc016, 160},
+        {0x8001, 163},
+        {0xc016, 163},
+        {0x8001, 164},
+        {0xc016, 164},
+        {0x8001, 169},
+        {0xc016, 169},
+        {0x8001, 170},
+        {0xc016, 170},
+        {0x8001, 173},
+        {0xc016, 173},
+    },
+    /* 127 */
+    {
+        {0x8002, 154},
+        {0x8009, 154},
+        {0x8017, 154},
+        {0xc028, 154},
+        {0x8002, 156},
+        {0x8009, 156},
+        {0x8017, 156},
+        {0xc028, 156},
+        {0x8002, 160},
+        {0x8009, 160},
+        {0x8017, 160},
+        {0xc028, 160},
+        {0x8002, 163},
+        {0x8009, 163},
+        {0x8017, 163},
+        {0xc028, 163},
+    },
+    /* 128 */
+    {
+        {0x8003, 154},
+        {0x8006, 154},
+        {0x800a, 154},
+        {0x800f, 154},
+        {0x8018, 154},
+        {0x801f, 154},
+        {0x8029, 154},
+        {0xc038, 154},
+        {0x8003, 156},
+        {0x8006, 156},
+        {0x800a, 156},
+        {0x800f, 156},
+        {0x8018, 156},
+        {0x801f, 156},
+        {0x8029, 156},
+        {0xc038, 156},
+    },
+    /* 129 */
+    {
+        {0x8003, 160},
+        {0x8006, 160},
+        {0x800a, 160},
+        {0x800f, 160},
+        {0x8018, 160},
+        {0x801f, 160},
+        {0x8029, 160},
+        {0xc038, 160},
+        {0x8003, 163},
+        {0x8006, 163},
+        {0x800a, 163},
+        {0x800f, 163},
+        {0x8018, 163},
+        {0x801f, 163},
+        {0x8029, 163},
+        {0xc038, 163},
+    },
+    /* 130 */
+    {
+        {0x8002, 164},
+        {0x8009, 164},
+        {0x8017, 164},
+        {0xc028, 164},
+        {0x8002, 169},
+        {0x8009, 169},
+        {0x8017, 169},
+        {0xc028, 169},
+        {0x8002, 170},
+        {0x8009, 170},
+        {0x8017, 170},
+        {0xc028, 170},
+        {0x8002, 173},
+        {0x8009, 173},
+        {0x8017, 173},
+        {0xc028, 173},
+    },
+    /* 131 */
+    {
+        {0x8003, 164},
+        {0x8006, 164},
+        {0x800a, 164},
+        {0x800f, 164},
+        {0x8018, 164},
+        {0x801f, 164},
+        {0x8029, 164},
+        {0xc038, 164},
+        {0x8003, 169},
+        {0x8006, 169},
+        {0x800a, 169},
+        {0x800f, 169},
+        {0x8018, 169},
+        {0x801f, 169},
+        {0x8029, 169},
+        {0xc038, 169},
+    },
+    /* 132 */
+    {
+        {0x8003, 170},
+        {0x8006, 170},
+        {0x800a, 170},
+        {0x800f, 170},
+        {0x8018, 170},
+        {0x801f, 170},
+        {0x8029, 170},
+        {0xc038, 170},
+        {0x8003, 173},
+        {0x8006, 173},
+        {0x800a, 173},
+        {0x800f, 173},
+        {0x8018, 173},
+        {0x801f, 173},
+        {0x8029, 173},
+        {0xc038, 173},
+    },
+    /* 133 */
+    {
+        {0x89, 0},
+        {0x8a, 0},
+        {0x8c, 0},
+        {0x8d, 0},
+        {0x90, 0},
+        {0x91, 0},
+        {0x93, 0},
+        {0x96, 0},
+        {0x9c, 0},
+        {0x9f, 0},
+        {0xa3, 0},
+        {0xa6, 0},
+        {0xab, 0},
+        {0xae, 0},
+        {0xb5, 0},
+        {0xbe, 0},
+    },
+    /* 134 */
+    {
+        {0xc000, 178},
+        {0xc000, 181},
+        {0xc000, 185},
+        {0xc000, 186},
+        {0xc000, 187},
+        {0xc000, 189},
+        {0xc000, 190},
+        {0xc000, 196},
+        {0xc000, 198},
+        {0xc000, 228},
+        {0xc000, 232},
+        {0xc000, 233},
+        {0x94, 0},
+        {0x95, 0},
+        {0x97, 0},
+        {0x98, 0},
+    },
+    /* 135 */
+    {
+        {0x8001, 178},
+        {0xc016, 178},
+        {0x8001, 181},
+        {0xc016, 181},
+        {0x8001, 185},
+        {0xc016, 185},
+        {0x8001, 186},
+        {0xc016, 186},
+        {0x8001, 187},
+        {0xc016, 187},
+        {0x8001, 189},
+        {0xc016, 189},
+        {0x8001, 190},
+        {0xc016, 190},
+        {0x8001, 196},
+        {0xc016, 196},
+    },
+    /* 136 */
+    {
+        {0x8002, 178},
+        {0x8009, 178},
+        {0x8017, 178},
+        {0xc028, 178},
+        {0x8002, 181},
+        {0x8009, 181},
+        {0x8017, 181},
+        {0xc028, 181},
+        {0x8002, 185},
+        {0x8009, 185},
+        {0x8017, 185},
+        {0xc028, 185},
+        {0x8002, 186},
+        {0x8009, 186},
+        {0x8017, 186},
+        {0xc028, 186},
+    },
+    /* 137 */
+    {
+        {0x8003, 178},
+        {0x8006, 178},
+        {0x800a, 178},
+        {0x800f, 178},
+        {0x8018, 178},
+        {0x801f, 178},
+        {0x8029, 178},
+        {0xc038, 178},
+        {0x8003, 181},
+        {0x8006, 181},
+        {0x800a, 181},
+        {0x800f, 181},
+        {0x8018, 181},
+        {0x801f, 181},
+        {0x8029, 181},
+        {0xc038, 181},
+    },
+    /* 138 */
+    {
+        {0x8003, 185},
+        {0x8006, 185},
+        {0x800a, 185},
+        {0x800f, 185},
+        {0x8018, 185},
+        {0x801f, 185},
+        {0x8029, 185},
+        {0xc038, 185},
+        {0x8003, 186},
+        {0x8006, 186},
+        {0x800a, 186},
+        {0x800f, 186},
+        {0x8018, 186},
+        {0x801f, 186},
+        {0x8029, 186},
+        {0xc038, 186},
+    },
+    /* 139 */
+    {
+        {0x8002, 187},
+        {0x8009, 187},
+        {0x8017, 187},
+        {0xc028, 187},
+        {0x8002, 189},
+        {0x8009, 189},
+        {0x8017, 189},
+        {0xc028, 189},
+        {0x8002, 190},
+        {0x8009, 190},
+        {0x8017, 190},
+        {0xc028, 190},
+        {0x8002, 196},
+        {0x8009, 196},
+        {0x8017, 196},
+        {0xc028, 196},
+    },
+    /* 140 */
+    {
+        {0x8003, 187},
+        {0x8006, 187},
+        {0x800a, 187},
+        {0x800f, 187},
+        {0x8018, 187},
+        {0x801f, 187},
+        {0x8029, 187},
+        {0xc038, 187},
+        {0x8003, 189},
+        {0x8006, 189},
+        {0x800a, 189},
+        {0x800f, 189},
+        {0x8018, 189},
+        {0x801f, 189},
+        {0x8029, 189},
+        {0xc038, 189},
+    },
+    /* 141 */
+    {
+        {0x8003, 190},
+        {0x8006, 190},
+        {0x800a, 190},
+        {0x800f, 190},
+        {0x8018, 190},
+        {0x801f, 190},
+        {0x8029, 190},
+        {0xc038, 190},
+        {0x8003, 196},
+        {0x8006, 196},
+        {0x800a, 196},
+        {0x800f, 196},
+        {0x8018, 196},
+        {0x801f, 196},
+        {0x8029, 196},
+        {0xc038, 196},
+    },
+    /* 142 */
+    {
+        {0x8001, 198},
+        {0xc016, 198},
+        {0x8001, 228},
+        {0xc016, 228},
+        {0x8001, 232},
+        {0xc016, 232},
+        {0x8001, 233},
+        {0xc016, 233},
+        {0xc000, 1},
+        {0xc000, 135},
+        {0xc000, 137},
+        {0xc000, 138},
+        {0xc000, 139},
+        {0xc000, 140},
+        {0xc000, 141},
+        {0xc000, 143},
+    },
+    /* 143 */
+    {
+        {0x8002, 198},
+        {0x8009, 198},
+        {0x8017, 198},
+        {0xc028, 198},
+        {0x8002, 228},
+        {0x8009, 228},
+        {0x8017, 228},
+        {0xc028, 228},
+        {0x8002, 232},
+        {0x8009, 232},
+        {0x8017, 232},
+        {0xc028, 232},
+        {0x8002, 233},
+        {0x8009, 233},
+        {0x8017, 233},
+        {0xc028, 233},
+    },
+    /* 144 */
+    {
+        {0x8003, 198},
+        {0x8006, 198},
+        {0x800a, 198},
+        {0x800f, 198},
+        {0x8018, 198},
+        {0x801f, 198},
+        {0x8029, 198},
+        {0xc038, 198},
+        {0x8003, 228},
+        {0x8006, 228},
+        {0x800a, 228},
+        {0x800f, 228},
+        {0x8018, 228},
+        {0x801f, 228},
+        {0x8029, 228},
+        {0xc038, 228},
+    },
+    /* 145 */
+    {
+        {0x8003, 232},
+        {0x8006, 232},
+        {0x800a, 232},
+        {0x800f, 232},
+        {0x8018, 232},
+        {0x801f, 232},
+        {0x8029, 232},
+        {0xc038, 232},
+        {0x8003, 233},
+        {0x8006, 233},
+        {0x800a, 233},
+        {0x800f, 233},
+        {0x8018, 233},
+        {0x801f, 233},
+        {0x8029, 233},
+        {0xc038, 233},
+    },
+    /* 146 */
+    {
+        {0x8001, 1},
+        {0xc016, 1},
+        {0x8001, 135},
+        {0xc016, 135},
+        {0x8001, 137},
+        {0xc016, 137},
+        {0x8001, 138},
+        {0xc016, 138},
+        {0x8001, 139},
+        {0xc016, 139},
+        {0x8001, 140},
+        {0xc016, 140},
+        {0x8001, 141},
+        {0xc016, 141},
+        {0x8001, 143},
+        {0xc016, 143},
+    },
+    /* 147 */
+    {
+        {0x8002, 1},
+        {0x8009, 1},
+        {0x8017, 1},
+        {0xc028, 1},
+        {0x8002, 135},
+        {0x8009, 135},
+        {0x8017, 135},
+        {0xc028, 135},
+        {0x8002, 137},
+        {0x8009, 137},
+        {0x8017, 137},
+        {0xc028, 137},
+        {0x8002, 138},
+        {0x8009, 138},
+        {0x8017, 138},
+        {0xc028, 138},
+    },
+    /* 148 */
+    {
+        {0x8003, 1},
+        {0x8006, 1},
+        {0x800a, 1},
+        {0x800f, 1},
+        {0x8018, 1},
+        {0x801f, 1},
+        {0x8029, 1},
+        {0xc038, 1},
+        {0x8003, 135},
+        {0x8006, 135},
+        {0x800a, 135},
+        {0x800f, 135},
+        {0x8018, 135},
+        {0x801f, 135},
+        {0x8029, 135},
+        {0xc038, 135},
+    },
+    /* 149 */
+    {
+        {0x8003, 137},
+        {0x8006, 137},
+        {0x800a, 137},
+        {0x800f, 137},
+        {0x8018, 137},
+        {0x801f, 137},
+        {0x8029, 137},
+        {0xc038, 137},
+        {0x8003, 138},
+        {0x8006, 138},
+        {0x800a, 138},
+        {0x800f, 138},
+        {0x8018, 138},
+        {0x801f, 138},
+        {0x8029, 138},
+        {0xc038, 138},
+    },
+    /* 150 */
+    {
+        {0x8002, 139},
+        {0x8009, 139},
+        {0x8017, 139},
+        {0xc028, 139},
+        {0x8002, 140},
+        {0x8009, 140},
+        {0x8017, 140},
+        {0xc028, 140},
+        {0x8002, 141},
+        {0x8009, 141},
+        {0x8017, 141},
+        {0xc028, 141},
+        {0x8002, 143},
+        {0x8009, 143},
+        {0x8017, 143},
+        {0xc028, 143},
+    },
+    /* 151 */
+    {
+        {0x8003, 139},
+        {0x8006, 139},
+        {0x800a, 139},
+        {0x800f, 139},
+        {0x8018, 139},
+        {0x801f, 139},
+        {0x8029, 139},
+        {0xc038, 139},
+        {0x8003, 140},
+        {0x8006, 140},
+        {0x800a, 140},
+        {0x800f, 140},
+        {0x8018, 140},
+        {0x801f, 140},
+        {0x8029, 140},
+        {0xc038, 140},
+    },
+    /* 152 */
+    {
+        {0x8003, 141},
+        {0x8006, 141},
+        {0x800a, 141},
+        {0x800f, 141},
+        {0x8018, 141},
+        {0x801f, 141},
+        {0x8029, 141},
+        {0xc038, 141},
+        {0x8003, 143},
+        {0x8006, 143},
+        {0x800a, 143},
+        {0x800f, 143},
+        {0x8018, 143},
+        {0x801f, 143},
+        {0x8029, 143},
+        {0xc038, 143},
+    },
+    /* 153 */
+    {
+        {0x9d, 0},
+        {0x9e, 0},
+        {0xa0, 0},
+        {0xa1, 0},
+        {0xa4, 0},
+        {0xa5, 0},
+        {0xa7, 0},
+        {0xa8, 0},
+        {0xac, 0},
+        {0xad, 0},
+        {0xaf, 0},
+        {0xb1, 0},
+        {0xb6, 0},
+        {0xb9, 0},
+        {0xbf, 0},
+        {0xcf, 0},
+    },
+    /* 154 */
+    {
+        {0xc000, 147},
+        {0xc000, 149},
+        {0xc000, 150},
+        {0xc000, 151},
+        {0xc000, 152},
+        {0xc000, 155},
+        {0xc000, 157},
+        {0xc000, 158},
+        {0xc000, 165},
+        {0xc000, 166},
+        {0xc000, 168},
+        {0xc000, 174},
+        {0xc000, 175},
+        {0xc000, 180},
+        {0xc000, 182},
+        {0xc000, 183},
+    },
+    /* 155 */
+    {
+        {0x8001, 147},
+        {0xc016, 147},
+        {0x8001, 149},
+        {0xc016, 149},
+        {0x8001, 150},
+        {0xc016, 150},
+        {0x8001, 151},
+        {0xc016, 151},
+        {0x8001, 152},
+        {0xc016, 152},
+        {0x8001, 155},
+        {0xc016, 155},
+        {0x8001, 157},
+        {0xc016, 157},
+        {0x8001, 158},
+        {0xc016, 158},
+    },
+    /* 156 */
+    {
+        {0x8002, 147},
+        {0x8009, 147},
+        {0x8017, 147},
+        {0xc028, 147},
+        {0x8002, 149},
+        {0x8009, 149},
+        {0x8017, 149},
+        {0xc028, 149},
+        {0x8002, 150},
+        {0x8009, 150},
+        {0x8017, 150},
+        {0xc028, 150},
+        {0x8002, 151},
+        {0x8009, 151},
+        {0x8017, 151},
+        {0xc028, 151},
+    },
+    /* 157 */
+    {
+        {0x8003, 147},
+        {0x8006, 147},
+        {0x800a, 147},
+        {0x800f, 147},
+        {0x8018, 147},
+        {0x801f, 147},
+        {0x8029, 147},
+        {0xc038, 147},
+        {0x8003, 149},
+        {0x8006, 149},
+        {0x800a, 149},
+        {0x800f, 149},
+        {0x8018, 149},
+        {0x801f, 149},
+        {0x8029, 149},
+        {0xc038, 149},
+    },
+    /* 158 */
+    {
+        {0x8003, 150},
+        {0x8006, 150},
+        {0x800a, 150},
+        {0x800f, 150},
+        {0x8018, 150},
+        {0x801f, 150},
+        {0x8029, 150},
+        {0xc038, 150},
+        {0x8003, 151},
+        {0x8006, 151},
+        {0x800a, 151},
+        {0x800f, 151},
+        {0x8018, 151},
+        {0x801f, 151},
+        {0x8029, 151},
+        {0xc038, 151},
+    },
+    /* 159 */
+    {
+        {0x8002, 152},
+        {0x8009, 152},
+        {0x8017, 152},
+        {0xc028, 152},
+        {0x8002, 155},
+        {0x8009, 155},
+        {0x8017, 155},
+        {0xc028, 155},
+        {0x8002, 157},
+        {0x8009, 157},
+        {0x8017, 157},
+        {0xc028, 157},
+        {0x8002, 158},
+        {0x8009, 158},
+        {0x8017, 158},
+        {0xc028, 158},
+    },
+    /* 160 */
+    {
+        {0x8003, 152},
+        {0x8006, 152},
+        {0x800a, 152},
+        {0x800f, 152},
+        {0x8018, 152},
+        {0x801f, 152},
+        {0x8029, 152},
+        {0xc038, 152},
+        {0x8003, 155},
+        {0x8006, 155},
+        {0x800a, 155},
+        {0x800f, 155},
+        {0x8018, 155},
+        {0x801f, 155},
+        {0x8029, 155},
+        {0xc038, 155},
+    },
+    /* 161 */
+    {
+        {0x8003, 157},
+        {0x8006, 157},
+        {0x800a, 157},
+        {0x800f, 157},
+        {0x8018, 157},
+        {0x801f, 157},
+        {0x8029, 157},
+        {0xc038, 157},
+        {0x8003, 158},
+        {0x8006, 158},
+        {0x800a, 158},
+        {0x800f, 158},
+        {0x8018, 158},
+        {0x801f, 158},
+        {0x8029, 158},
+        {0xc038, 158},
+    },
+    /* 162 */
+    {
+        {0x8001, 165},
+        {0xc016, 165},
+        {0x8001, 166},
+        {0xc016, 166},
+        {0x8001, 168},
+        {0xc016, 168},
+        {0x8001, 174},
+        {0xc016, 174},
+        {0x8001, 175},
+        {0xc016, 175},
+        {0x8001, 180},
+        {0xc016, 180},
+        {0x8001, 182},
+        {0xc016, 182},
+        {0x8001, 183},
+        {0xc016, 183},
+    },
+    /* 163 */
+    {
+        {0x8002, 165},
+        {0x8009, 165},
+        {0x8017, 165},
+        {0xc028, 165},
+        {0x8002, 166},
+        {0x8009, 166},
+        {0x8017, 166},
+        {0xc028, 166},
+        {0x8002, 168},
+        {0x8009, 168},
+        {0x8017, 168},
+        {0xc028, 168},
+        {0x8002, 174},
+        {0x8009, 174},
+        {0x8017, 174},
+        {0xc028, 174},
+    },
+    /* 164 */
+    {
+        {0x8003, 165},
+        {0x8006, 165},
+        {0x800a, 165},
+        {0x800f, 165},
+        {0x8018, 165},
+        {0x801f, 165},
+        {0x8029, 165},
+        {0xc038, 165},
+        {0x8003, 166},
+        {0x8006, 166},
+        {0x800a, 166},
+        {0x800f, 166},
+        {0x8018, 166},
+        {0x801f, 166},
+        {0x8029, 166},
+        {0xc038, 166},
+    },
+    /* 165 */
+    {
+        {0x8003, 168},
+        {0x8006, 168},
+        {0x800a, 168},
+        {0x800f, 168},
+        {0x8018, 168},
+        {0x801f, 168},
+        {0x8029, 168},
+        {0xc038, 168},
+        {0x8003, 174},
+        {0x8006, 174},
+        {0x800a, 174},
+        {0x800f, 174},
+        {0x8018, 174},
+        {0x801f, 174},
+        {0x8029, 174},
+        {0xc038, 174},
+    },
+    /* 166 */
+    {
+        {0x8002, 175},
+        {0x8009, 175},
+        {0x8017, 175},
+        {0xc028, 175},
+        {0x8002, 180},
+        {0x8009, 180},
+        {0x8017, 180},
+        {0xc028, 180},
+        {0x8002, 182},
+        {0x8009, 182},
+        {0x8017, 182},
+        {0xc028, 182},
+        {0x8002, 183},
+        {0x8009, 183},
+        {0x8017, 183},
+        {0xc028, 183},
+    },
+    /* 167 */
+    {
+        {0x8003, 175},
+        {0x8006, 175},
+        {0x800a, 175},
+        {0x800f, 175},
+        {0x8018, 175},
+        {0x801f, 175},
+        {0x8029, 175},
+        {0xc038, 175},
+        {0x8003, 180},
+        {0x8006, 180},
+        {0x800a, 180},
+        {0x800f, 180},
+        {0x8018, 180},
+        {0x801f, 180},
+        {0x8029, 180},
+        {0xc038, 180},
+    },
+    /* 168 */
+    {
+        {0x8003, 182},
+        {0x8006, 182},
+        {0x800a, 182},
+        {0x800f, 182},
+        {0x8018, 182},
+        {0x801f, 182},
+        {0x8029, 182},
+        {0xc038, 182},
+        {0x8003, 183},
+        {0x8006, 183},
+        {0x800a, 183},
+        {0x800f, 183},
+        {0x8018, 183},
+        {0x801f, 183},
+        {0x8029, 183},
+        {0xc038, 183},
+    },
+    /* 169 */
+    {
+        {0xc000, 188},
+        {0xc000, 191},
+        {0xc000, 197},
+        {0xc000, 231},
+        {0xc000, 239},
+        {0xb0, 0},
+        {0xb2, 0},
+        {0xb3, 0},
+        {0xb7, 0},
+        {0xb8, 0},
+        {0xba, 0},
+        {0xbb, 0},
+        {0xc0, 0},
+        {0xc7, 0},
+        {0xd0, 0},
+        {0xdf, 0},
+    },
+    /* 170 */
+    {
+        {0x8001, 188},
+        {0xc016, 188},
+        {0x8001, 191},
+        {0xc016, 191},
+        {0x8001, 197},
+        {0xc016, 197},
+        {0x8001, 231},
+        {0xc016, 231},
+        {0x8001, 239},
+        {0xc016, 239},
+        {0xc000, 9},
+        {0xc000, 142},
+        {0xc000, 144},
+        {0xc000, 145},
+        {0xc000, 148},
+        {0xc000, 159},
+    },
+    /* 171 */
+    {
+        {0x8002, 188},
+        {0x8009, 188},
+        {0x8017, 188},
+        {0xc028, 188},
+        {0x8002, 191},
+        {0x8009, 191},
+        {0x8017, 191},
+        {0xc028, 191},
+        {0x8002, 197},
+        {0x8009, 197},
+        {0x8017, 197},
+        {0xc028, 197},
+        {0x8002, 231},
+        {0x8009, 231},
+        {0x8017, 231},
+        {0xc028, 231},
+    },
+    /* 172 */
+    {
+        {0x8003, 188},
+        {0x8006, 188},
+        {0x800a, 188},
+        {0x800f, 188},
+        {0x8018, 188},
+        {0x801f, 188},
+        {0x8029, 188},
+        {0xc038, 188},
+        {0x8003, 191},
+        {0x8006, 191},
+        {0x800a, 191},
+        {0x800f, 191},
+        {0x8018, 191},
+        {0x801f, 191},
+        {0x8029, 191},
+        {0xc038, 191},
+    },
+    /* 173 */
+    {
+        {0x8003, 197},
+        {0x8006, 197},
+        {0x800a, 197},
+        {0x800f, 197},
+        {0x8018, 197},
+        {0x801f, 197},
+        {0x8029, 197},
+        {0xc038, 197},
+        {0x8003, 231},
+        {0x8006, 231},
+        {0x800a, 231},
+        {0x800f, 231},
+        {0x8018, 231},
+        {0x801f, 231},
+        {0x8029, 231},
+        {0xc038, 231},
+    },
+    /* 174 */
+    {
+        {0x8002, 239},
+        {0x8009, 239},
+        {0x8017, 239},
+        {0xc028, 239},
+        {0x8001, 9},
+        {0xc016, 9},
+        {0x8001, 142},
+        {0xc016, 142},
+        {0x8001, 144},
+        {0xc016, 144},
+        {0x8001, 145},
+        {0xc016, 145},
+        {0x8001, 148},
+        {0xc016, 148},
+        {0x8001, 159},
+        {0xc016, 159},
+    },
+    /* 175 */
+    {
+        {0x8003, 239},
+        {0x8006, 239},
+        {0x800a, 239},
+        {0x800f, 239},
+        {0x8018, 239},
+        {0x801f, 239},
+        {0x8029, 239},
+        {0xc038, 239},
+        {0x8002, 9},
+        {0x8009, 9},
+        {0x8017, 9},
+        {0xc028, 9},
+        {0x8002, 142},
+        {0x8009, 142},
+        {0x8017, 142},
+        {0xc028, 142},
+    },
+    /* 176 */
+    {
+        {0x8003, 9},
+        {0x8006, 9},
+        {0x800a, 9},
+        {0x800f, 9},
+        {0x8018, 9},
+        {0x801f, 9},
+        {0x8029, 9},
+        {0xc038, 9},
+        {0x8003, 142},
+        {0x8006, 142},
+        {0x800a, 142},
+        {0x800f, 142},
+        {0x8018, 142},
+        {0x801f, 142},
+        {0x8029, 142},
+        {0xc038, 142},
+    },
+    /* 177 */
+    {
+        {0x8002, 144},
+        {0x8009, 144},
+        {0x8017, 144},
+        {0xc028, 144},
+        {0x8002, 145},
+        {0x8009, 145},
+        {0x8017, 145},
+        {0xc028, 145},
+        {0x8002, 148},
+        {0x8009, 148},
+        {0x8017, 148},
+        {0xc028, 148},
+        {0x8002, 159},
+        {0x8009, 159},
+        {0x8017, 159},
+        {0xc028, 159},
+    },
+    /* 178 */
+    {
+        {0x8003, 144},
+        {0x8006, 144},
+        {0x800a, 144},
+        {0x800f, 144},
+        {0x8018, 144},
+        {0x801f, 144},
+        {0x8029, 144},
+        {0xc038, 144},
+        {0x8003, 145},
+        {0x8006, 145},
+        {0x800a, 145},
+        {0x800f, 145},
+        {0x8018, 145},
+        {0x801f, 145},
+        {0x8029, 145},
+        {0xc038, 145},
+    },
+    /* 179 */
+    {
+        {0x8003, 148},
+        {0x8006, 148},
+        {0x800a, 148},
+        {0x800f, 148},
+        {0x8018, 148},
+        {0x801f, 148},
+        {0x8029, 148},
+        {0xc038, 148},
+        {0x8003, 159},
+        {0x8006, 159},
+        {0x800a, 159},
+        {0x800f, 159},
+        {0x8018, 159},
+        {0x801f, 159},
+        {0x8029, 159},
+        {0xc038, 159},
+    },
+    /* 180 */
+    {
+        {0xc000, 171},
+        {0xc000, 206},
+        {0xc000, 215},
+        {0xc000, 225},
+        {0xc000, 236},
+        {0xc000, 237},
+        {0xbc, 0},
+        {0xbd, 0},
+        {0xc1, 0},
+        {0xc4, 0},
+        {0xc8, 0},
+        {0xcb, 0},
+        {0xd1, 0},
+        {0xd8, 0},
+        {0xe0, 0},
+        {0xee, 0},
+    },
+    /* 181 */
+    {
+        {0x8001, 171},
+        {0xc016, 171},
+        {0x8001, 206},
+        {0xc016, 206},
+        {0x8001, 215},
+        {0xc016, 215},
+        {0x8001, 225},
+        {0xc016, 225},
+        {0x8001, 236},
+        {0xc016, 236},
+        {0x8001, 237},
+        {0xc016, 237},
+        {0xc000, 199},
+        {0xc000, 207},
+        {0xc000, 234},
+        {0xc000, 235},
+    },
+    /* 182 */
+    {
+        {0x8002, 171},
+        {0x8009, 171},
+        {0x8017, 171},
+        {0xc028, 171},
+        {0x8002, 206},
+        {0x8009, 206},
+        {0x8017, 206},
+        {0xc028, 206},
+        {0x8002, 215},
+        {0x8009, 215},
+        {0x8017, 215},
+        {0xc028, 215},
+        {0x8002, 225},
+        {0x8009, 225},
+        {0x8017, 225},
+        {0xc028, 225},
+    },
+    /* 183 */
+    {
+        {0x8003, 171},
+        {0x8006, 171},
+        {0x800a, 171},
+        {0x800f, 171},
+        {0x8018, 171},
+        {0x801f, 171},
+        {0x8029, 171},
+        {0xc038, 171},
+        {0x8003, 206},
+        {0x8006, 206},
+        {0x800a, 206},
+        {0x800f, 206},
+        {0x8018, 206},
+        {0x801f, 206},
+        {0x8029, 206},
+        {0xc038, 206},
+    },
+    /* 184 */
+    {
+        {0x8003, 215},
+        {0x8006, 215},
+        {0x800a, 215},
+        {0x800f, 215},
+        {0x8018, 215},
+        {0x801f, 215},
+        {0x8029, 215},
+        {0xc038, 215},
+        {0x8003, 225},
+        {0x8006, 225},
+        {0x800a, 225},
+        {0x800f, 225},
+        {0x8018, 225},
+        {0x801f, 225},
+        {0x8029, 225},
+        {0xc038, 225},
+    },
+    /* 185 */
+    {
+        {0x8002, 236},
+        {0x8009, 236},
+        {0x8017, 236},
+        {0xc028, 236},
+        {0x8002, 237},
+        {0x8009, 237},
+        {0x8017, 237},
+        {0xc028, 237},
+        {0x8001, 199},
+        {0xc016, 199},
+        {0x8001, 207},
+        {0xc016, 207},
+        {0x8001, 234},
+        {0xc016, 234},
+        {0x8001, 235},
+        {0xc016, 235},
+    },
+    /* 186 */
+    {
+        {0x8003, 236},
+        {0x8006, 236},
+        {0x800a, 236},
+        {0x800f, 236},
+        {0x8018, 236},
+        {0x801f, 236},
+        {0x8029, 236},
+        {0xc038, 236},
+        {0x8003, 237},
+        {0x8006, 237},
+        {0x800a, 237},
+        {0x800f, 237},
+        {0x8018, 237},
+        {0x801f, 237},
+        {0x8029, 237},
+        {0xc038, 237},
+    },
+    /* 187 */
+    {
+        {0x8002, 199},
+        {0x8009, 199},
+        {0x8017, 199},
+        {0xc028, 199},
+        {0x8002, 207},
+        {0x8009, 207},
+        {0x8017, 207},
+        {0xc028, 207},
+        {0x8002, 234},
+        {0x8009, 234},
+        {0x8017, 234},
+        {0xc028, 234},
+        {0x8002, 235},
+        {0x8009, 235},
+        {0x8017, 235},
+        {0xc028, 235},
+    },
+    /* 188 */
+    {
+        {0x8003, 199},
+        {0x8006, 199},
+        {0x800a, 199},
+        {0x800f, 199},
+        {0x8018, 199},
+        {0x801f, 199},
+        {0x8029, 199},
+        {0xc038, 199},
+        {0x8003, 207},
+        {0x8006, 207},
+        {0x800a, 207},
+        {0x800f, 207},
+        {0x8018, 207},
+        {0x801f, 207},
+        {0x8029, 207},
+        {0xc038, 207},
+    },
+    /* 189 */
+    {
+        {0x8003, 234},
+        {0x8006, 234},
+        {0x800a, 234},
+        {0x800f, 234},
+        {0x8018, 234},
+        {0x801f, 234},
+        {0x8029, 234},
+        {0xc038, 234},
+        {0x8003, 235},
+        {0x8006, 235},
+        {0x800a, 235},
+        {0x800f, 235},
+        {0x8018, 235},
+        {0x801f, 235},
+        {0x8029, 235},
+        {0xc038, 235},
+    },
+    /* 190 */
+    {
+        {0xc2, 0},
+        {0xc3, 0},
+        {0xc5, 0},
+        {0xc6, 0},
+        {0xc9, 0},
+        {0xca, 0},
+        {0xcc, 0},
+        {0xcd, 0},
+        {0xd2, 0},
+        {0xd5, 0},
+        {0xd9, 0},
+        {0xdc, 0},
+        {0xe1, 0},
+        {0xe7, 0},
+        {0xef, 0},
+        {0xf6, 0},
+    },
+    /* 191 */
+    {
+        {0xc000, 192},
+        {0xc000, 193},
+        {0xc000, 200},
+        {0xc000, 201},
+        {0xc000, 202},
+        {0xc000, 205},
+        {0xc000, 210},
+        {0xc000, 213},
+        {0xc000, 218},
+        {0xc000, 219},
+        {0xc000, 238},
+        {0xc000, 240},
+        {0xc000, 242},
+        {0xc000, 243},
+        {0xc000, 255},
+        {0xce, 0},
+    },
+    /* 192 */
+    {
+        {0x8001, 192},
+        {0xc016, 192},
+        {0x8001, 193},
+        {0xc016, 193},
+        {0x8001, 200},
+        {0xc016, 200},
+        {0x8001, 201},
+        {0xc016, 201},
+        {0x8001, 202},
+        {0xc016, 202},
+        {0x8001, 205},
+        {0xc016, 205},
+        {0x8001, 210},
+        {0xc016, 210},
+        {0x8001, 213},
+        {0xc016, 213},
+    },
+    /* 193 */
+    {
+        {0x8002, 192},
+        {0x8009, 192},
+        {0x8017, 192},
+        {0xc028, 192},
+        {0x8002, 193},
+        {0x8009, 193},
+        {0x8017, 193},
+        {0xc028, 193},
+        {0x8002, 200},
+        {0x8009, 200},
+        {0x8017, 200},
+        {0xc028, 200},
+        {0x8002, 201},
+        {0x8009, 201},
+        {0x8017, 201},
+        {0xc028, 201},
+    },
+    /* 194 */
+    {
+        {0x8003, 192},
+        {0x8006, 192},
+        {0x800a, 192},
+        {0x800f, 192},
+        {0x8018, 192},
+        {0x801f, 192},
+        {0x8029, 192},
+        {0xc038, 192},
+        {0x8003, 193},
+        {0x8006, 193},
+        {0x800a, 193},
+        {0x800f, 193},
+        {0x8018, 193},
+        {0x801f, 193},
+        {0x8029, 193},
+        {0xc038, 193},
+    },
+    /* 195 */
+    {
+        {0x8003, 200},
+        {0x8006, 200},
+        {0x800a, 200},
+        {0x800f, 200},
+        {0x8018, 200},
+        {0x801f, 200},
+        {0x8029, 200},
+        {0xc038, 200},
+        {0x8003, 201},
+        {0x8006, 201},
+        {0x800a, 201},
+        {0x800f, 201},
+        {0x8018, 201},
+        {0x801f, 201},
+        {0x8029, 201},
+        {0xc038, 201},
+    },
+    /* 196 */
+    {
+        {0x8002, 202},
+        {0x8009, 202},
+        {0x8017, 202},
+        {0xc028, 202},
+        {0x8002, 205},
+        {0x8009, 205},
+        {0x8017, 205},
+        {0xc028, 205},
+        {0x8002, 210},
+        {0x8009, 210},
+        {0x8017, 210},
+        {0xc028, 210},
+        {0x8002, 213},
+        {0x8009, 213},
+        {0x8017, 213},
+        {0xc028, 213},
+    },
+    /* 197 */
+    {
+        {0x8003, 202},
+        {0x8006, 202},
+        {0x800a, 202},
+        {0x800f, 202},
+        {0x8018, 202},
+        {0x801f, 202},
+        {0x8029, 202},
+        {0xc038, 202},
+        {0x8003, 205},
+        {0x8006, 205},
+        {0x800a, 205},
+        {0x800f, 205},
+        {0x8018, 205},
+        {0x801f, 205},
+        {0x8029, 205},
+        {0xc038, 205},
+    },
+    /* 198 */
+    {
+        {0x8003, 210},
+        {0x8006, 210},
+        {0x800a, 210},
+        {0x800f, 210},
+        {0x8018, 210},
+        {0x801f, 210},
+        {0x8029, 210},
+        {0xc038, 210},
+        {0x8003, 213},
+        {0x8006, 213},
+        {0x800a, 213},
+        {0x800f, 213},
+        {0x8018, 213},
+        {0x801f, 213},
+        {0x8029, 213},
+        {0xc038, 213},
+    },
+    /* 199 */
+    {
+        {0x8001, 218},
+        {0xc016, 218},
+        {0x8001, 219},
+        {0xc016, 219},
+        {0x8001, 238},
+        {0xc016, 238},
+        {0x8001, 240},
+        {0xc016, 240},
+        {0x8001, 242},
+        {0xc016, 242},
+        {0x8001, 243},
+        {0xc016, 243},
+        {0x8001, 255},
+        {0xc016, 255},
+        {0xc000, 203},
+        {0xc000, 204},
+    },
+    /* 200 */
+    {
+        {0x8002, 218},
+        {0x8009, 218},
+        {0x8017, 218},
+        {0xc028, 218},
+        {0x8002, 219},
+        {0x8009, 219},
+        {0x8017, 219},
+        {0xc028, 219},
+        {0x8002, 238},
+        {0x8009, 238},
+        {0x8017, 238},
+        {0xc028, 238},
+        {0x8002, 240},
+        {0x8009, 240},
+        {0x8017, 240},
+        {0xc028, 240},
+    },
+    /* 201 */
+    {
+        {0x8003, 218},
+        {0x8006, 218},
+        {0x800a, 218},
+        {0x800f, 218},
+        {0x8018, 218},
+        {0x801f, 218},
+        {0x8029, 218},
+        {0xc038, 218},
+        {0x8003, 219},
+        {0x8006, 219},
+        {0x800a, 219},
+        {0x800f, 219},
+        {0x8018, 219},
+        {0x801f, 219},
+        {0x8029, 219},
+        {0xc038, 219},
+    },
+    /* 202 */
+    {
+        {0x8003, 238},
+        {0x8006, 238},
+        {0x800a, 238},
+        {0x800f, 238},
+        {0x8018, 238},
+        {0x801f, 238},
+        {0x8029, 238},
+        {0xc038, 238},
+        {0x8003, 240},
+        {0x8006, 240},
+        {0x800a, 240},
+        {0x800f, 240},
+        {0x8018, 240},
+        {0x801f, 240},
+        {0x8029, 240},
+        {0xc038, 240},
+    },
+    /* 203 */
+    {
+        {0x8002, 242},
+        {0x8009, 242},
+        {0x8017, 242},
+        {0xc028, 242},
+        {0x8002, 243},
+        {0x8009, 243},
+        {0x8017, 243},
+        {0xc028, 243},
+        {0x8002, 255},
+        {0x8009, 255},
+        {0x8017, 255},
+        {0xc028, 255},
+        {0x8001, 203},
+        {0xc016, 203},
+        {0x8001, 204},
+        {0xc016, 204},
+    },
+    /* 204 */
+    {
+        {0x8003, 242},
+        {0x8006, 242},
+        {0x800a, 242},
+        {0x800f, 242},
+        {0x8018, 242},
+        {0x801f, 242},
+        {0x8029, 242},
+        {0xc038, 242},
+        {0x8003, 243},
+        {0x8006, 243},
+        {0x800a, 243},
+        {0x800f, 243},
+        {0x8018, 243},
+        {0x801f, 243},
+        {0x8029, 243},
+        {0xc038, 243},
+    },
+    /* 205 */
+    {
+        {0x8003, 255},
+        {0x8006, 255},
+        {0x800a, 255},
+        {0x800f, 255},
+        {0x8018, 255},
+        {0x801f, 255},
+        {0x8029, 255},
+        {0xc038, 255},
+        {0x8002, 203},
+        {0x8009, 203},
+        {0x8017, 203},
+        {0xc028, 203},
+        {0x8002, 204},
+        {0x8009, 204},
+        {0x8017, 204},
+        {0xc028, 204},
+    },
+    /* 206 */
+    {
+        {0x8003, 203},
+        {0x8006, 203},
+        {0x800a, 203},
+        {0x800f, 203},
+        {0x8018, 203},
+        {0x801f, 203},
+        {0x8029, 203},
+        {0xc038, 203},
+        {0x8003, 204},
+        {0x8006, 204},
+        {0x800a, 204},
+        {0x800f, 204},
+        {0x8018, 204},
+        {0x801f, 204},
+        {0x8029, 204},
+        {0xc038, 204},
+    },
+    /* 207 */
+    {
+        {0xd3, 0},
+        {0xd4, 0},
+        {0xd6, 0},
+        {0xd7, 0},
+        {0xda, 0},
+        {0xdb, 0},
+        {0xdd, 0},
+        {0xde, 0},
+        {0xe2, 0},
+        {0xe4, 0},
+        {0xe8, 0},
+        {0xeb, 0},
+        {0xf0, 0},
+        {0xf3, 0},
+        {0xf7, 0},
+        {0xfa, 0},
+    },
+    /* 208 */
+    {
+        {0xc000, 211},
+        {0xc000, 212},
+        {0xc000, 214},
+        {0xc000, 221},
+        {0xc000, 222},
+        {0xc000, 223},
+        {0xc000, 241},
+        {0xc000, 244},
+        {0xc000, 245},
+        {0xc000, 246},
+        {0xc000, 247},
+        {0xc000, 248},
+        {0xc000, 250},
+        {0xc000, 251},
+        {0xc000, 252},
+        {0xc000, 253},
+    },
+    /* 209 */
+    {
+        {0x8001, 211},
+        {0xc016, 211},
+        {0x8001, 212},
+        {0xc016, 212},
+        {0x8001, 214},
+        {0xc016, 214},
+        {0x8001, 221},
+        {0xc016, 221},
+        {0x8001, 222},
+        {0xc016, 222},
+        {0x8001, 223},
+        {0xc016, 223},
+        {0x8001, 241},
+        {0xc016, 241},
+        {0x8001, 244},
+        {0xc016, 244},
+    },
+    /* 210 */
+    {
+        {0x8002, 211},
+        {0x8009, 211},
+        {0x8017, 211},
+        {0xc028, 211},
+        {0x8002, 212},
+        {0x8009, 212},
+        {0x8017, 212},
+        {0xc028, 212},
+        {0x8002, 214},
+        {0x8009, 214},
+        {0x8017, 214},
+        {0xc028, 214},
+        {0x8002, 221},
+        {0x8009, 221},
+        {0x8017, 221},
+        {0xc028, 221},
+    },
+    /* 211 */
+    {
+        {0x8003, 211},
+        {0x8006, 211},
+        {0x800a, 211},
+        {0x800f, 211},
+        {0x8018, 211},
+        {0x801f, 211},
+        {0x8029, 211},
+        {0xc038, 211},
+        {0x8003, 212},
+        {0x8006, 212},
+        {0x800a, 212},
+        {0x800f, 212},
+        {0x8018, 212},
+        {0x801f, 212},
+        {0x8029, 212},
+        {0xc038, 212},
+    },
+    /* 212 */
+    {
+        {0x8003, 214},
+        {0x8006, 214},
+        {0x800a, 214},
+        {0x800f, 214},
+        {0x8018, 214},
+        {0x801f, 214},
+        {0x8029, 214},
+        {0xc038, 214},
+        {0x8003, 221},
+        {0x8006, 221},
+        {0x800a, 221},
+        {0x800f, 221},
+        {0x8018, 221},
+        {0x801f, 221},
+        {0x8029, 221},
+        {0xc038, 221},
+    },
+    /* 213 */
+    {
+        {0x8002, 222},
+        {0x8009, 222},
+        {0x8017, 222},
+        {0xc028, 222},
+        {0x8002, 223},
+        {0x8009, 223},
+        {0x8017, 223},
+        {0xc028, 223},
+        {0x8002, 241},
+        {0x8009, 241},
+        {0x8017, 241},
+        {0xc028, 241},
+        {0x8002, 244},
+        {0x8009, 244},
+        {0x8017, 244},
+        {0xc028, 244},
+    },
+    /* 214 */
+    {
+        {0x8003, 222},
+        {0x8006, 222},
+        {0x800a, 222},
+        {0x800f, 222},
+        {0x8018, 222},
+        {0x801f, 222},
+        {0x8029, 222},
+        {0xc038, 222},
+        {0x8003, 223},
+        {0x8006, 223},
+        {0x800a, 223},
+        {0x800f, 223},
+        {0x8018, 223},
+        {0x801f, 223},
+        {0x8029, 223},
+        {0xc038, 223},
+    },
+    /* 215 */
+    {
+        {0x8003, 241},
+        {0x8006, 241},
+        {0x800a, 241},
+        {0x800f, 241},
+        {0x8018, 241},
+        {0x801f, 241},
+        {0x8029, 241},
+        {0xc038, 241},
+        {0x8003, 244},
+        {0x8006, 244},
+        {0x800a, 244},
+        {0x800f, 244},
+        {0x8018, 244},
+        {0x801f, 244},
+        {0x8029, 244},
+        {0xc038, 244},
+    },
+    /* 216 */
+    {
+        {0x8001, 245},
+        {0xc016, 245},
+        {0x8001, 246},
+        {0xc016, 246},
+        {0x8001, 247},
+        {0xc016, 247},
+        {0x8001, 248},
+        {0xc016, 248},
+        {0x8001, 250},
+        {0xc016, 250},
+        {0x8001, 251},
+        {0xc016, 251},
+        {0x8001, 252},
+        {0xc016, 252},
+        {0x8001, 253},
+        {0xc016, 253},
+    },
+    /* 217 */
+    {
+        {0x8002, 245},
+        {0x8009, 245},
+        {0x8017, 245},
+        {0xc028, 245},
+        {0x8002, 246},
+        {0x8009, 246},
+        {0x8017, 246},
+        {0xc028, 246},
+        {0x8002, 247},
+        {0x8009, 247},
+        {0x8017, 247},
+        {0xc028, 247},
+        {0x8002, 248},
+        {0x8009, 248},
+        {0x8017, 248},
+        {0xc028, 248},
+    },
+    /* 218 */
+    {
+        {0x8003, 245},
+        {0x8006, 245},
+        {0x800a, 245},
+        {0x800f, 245},
+        {0x8018, 245},
+        {0x801f, 245},
+        {0x8029, 245},
+        {0xc038, 245},
+        {0x8003, 246},
+        {0x8006, 246},
+        {0x800a, 246},
+        {0x800f, 246},
+        {0x8018, 246},
+        {0x801f, 246},
+        {0x8029, 246},
+        {0xc038, 246},
+    },
+    /* 219 */
+    {
+        {0x8003, 247},
+        {0x8006, 247},
+        {0x800a, 247},
+        {0x800f, 247},
+        {0x8018, 247},
+        {0x801f, 247},
+        {0x8029, 247},
+        {0xc038, 247},
+        {0x8003, 248},
+        {0x8006, 248},
+        {0x800a, 248},
+        {0x800f, 248},
+        {0x8018, 248},
+        {0x801f, 248},
+        {0x8029, 248},
+        {0xc038, 248},
+    },
+    /* 220 */
+    {
+        {0x8002, 250},
+        {0x8009, 250},
+        {0x8017, 250},
+        {0xc028, 250},
+        {0x8002, 251},
+        {0x8009, 251},
+        {0x8017, 251},
+        {0xc028, 251},
+        {0x8002, 252},
+        {0x8009, 252},
+        {0x8017, 252},
+        {0xc028, 252},
+        {0x8002, 253},
+        {0x8009, 253},
+        {0x8017, 253},
+        {0xc028, 253},
+    },
+    /* 221 */
+    {
+        {0x8003, 250},
+        {0x8006, 250},
+        {0x800a, 250},
+        {0x800f, 250},
+        {0x8018, 250},
+        {0x801f, 250},
+        {0x8029, 250},
+        {0xc038, 250},
+        {0x8003, 251},
+        {0x8006, 251},
+        {0x800a, 251},
+        {0x800f, 251},
+        {0x8018, 251},
+        {0x801f, 251},
+        {0x8029, 251},
+        {0xc038, 251},
+    },
+    /* 222 */
+    {
+        {0x8003, 252},
+        {0x8006, 252},
+        {0x800a, 252},
+        {0x800f, 252},
+        {0x8018, 252},
+        {0x801f, 252},
+        {0x8029, 252},
+        {0xc038, 252},
+        {0x8003, 253},
+        {0x8006, 253},
+        {0x800a, 253},
+        {0x800f, 253},
+        {0x8018, 253},
+        {0x801f, 253},
+        {0x8029, 253},
+        {0xc038, 253},
+    },
+    /* 223 */
+    {
+        {0xc000, 254},
+        {0xe3, 0},
+        {0xe5, 0},
+        {0xe6, 0},
+        {0xe9, 0},
+        {0xea, 0},
+        {0xec, 0},
+        {0xed, 0},
+        {0xf1, 0},
+        {0xf2, 0},
+        {0xf4, 0},
+        {0xf5, 0},
+        {0xf8, 0},
+        {0xf9, 0},
+        {0xfb, 0},
+        {0xfc, 0},
+    },
+    /* 224 */
+    {
+        {0x8001, 254},
+        {0xc016, 254},
+        {0xc000, 2},
+        {0xc000, 3},
+        {0xc000, 4},
+        {0xc000, 5},
+        {0xc000, 6},
+        {0xc000, 7},
+        {0xc000, 8},
+        {0xc000, 11},
+        {0xc000, 12},
+        {0xc000, 14},
+        {0xc000, 15},
+        {0xc000, 16},
+        {0xc000, 17},
+        {0xc000, 18},
+    },
+    /* 225 */
+    {
+        {0x8002, 254},
+        {0x8009, 254},
+        {0x8017, 254},
+        {0xc028, 254},
+        {0x8001, 2},
+        {0xc016, 2},
+        {0x8001, 3},
+        {0xc016, 3},
+        {0x8001, 4},
+        {0xc016, 4},
+        {0x8001, 5},
+        {0xc016, 5},
+        {0x8001, 6},
+        {0xc016, 6},
+        {0x8001, 7},
+        {0xc016, 7},
+    },
+    /* 226 */
+    {
+        {0x8003, 254},
+        {0x8006, 254},
+        {0x800a, 254},
+        {0x800f, 254},
+        {0x8018, 254},
+        {0x801f, 254},
+        {0x8029, 254},
+        {0xc038, 254},
+        {0x8002, 2},
+        {0x8009, 2},
+        {0x8017, 2},
+        {0xc028, 2},
+        {0x8002, 3},
+        {0x8009, 3},
+        {0x8017, 3},
+        {0xc028, 3},
+    },
+    /* 227 */
+    {
+        {0x8003, 2},
+        {0x8006, 2},
+        {0x800a, 2},
+        {0x800f, 2},
+        {0x8018, 2},
+        {0x801f, 2},
+        {0x8029, 2},
+        {0xc038, 2},
+        {0x8003, 3},
+        {0x8006, 3},
+        {0x800a, 3},
+        {0x800f, 3},
+        {0x8018, 3},
+        {0x801f, 3},
+        {0x8029, 3},
+        {0xc038, 3},
+    },
+    /* 228 */
+    {
+        {0x8002, 4},
+        {0x8009, 4},
+        {0x8017, 4},
+        {0xc028, 4},
+        {0x8002, 5},
+        {0x8009, 5},
+        {0x8017, 5},
+        {0xc028, 5},
+        {0x8002, 6},
+        {0x8009, 6},
+        {0x8017, 6},
+        {0xc028, 6},
+        {0x8002, 7},
+        {0x8009, 7},
+        {0x8017, 7},
+        {0xc028, 7},
+    },
+    /* 229 */
+    {
+        {0x8003, 4},
+        {0x8006, 4},
+        {0x800a, 4},
+        {0x800f, 4},
+        {0x8018, 4},
+        {0x801f, 4},
+        {0x8029, 4},
+        {0xc038, 4},
+        {0x8003, 5},
+        {0x8006, 5},
+        {0x800a, 5},
+        {0x800f, 5},
+        {0x8018, 5},
+        {0x801f, 5},
+        {0x8029, 5},
+        {0xc038, 5},
+    },
+    /* 230 */
+    {
+        {0x8003, 6},
+        {0x8006, 6},
+        {0x800a, 6},
+        {0x800f, 6},
+        {0x8018, 6},
+        {0x801f, 6},
+        {0x8029, 6},
+        {0xc038, 6},
+        {0x8003, 7},
+        {0x8006, 7},
+        {0x800a, 7},
+        {0x800f, 7},
+        {0x8018, 7},
+        {0x801f, 7},
+        {0x8029, 7},
+        {0xc038, 7},
+    },
+    /* 231 */
+    {
+        {0x8001, 8},
+        {0xc016, 8},
+        {0x8001, 11},
+        {0xc016, 11},
+        {0x8001, 12},
+        {0xc016, 12},
+        {0x8001, 14},
+        {0xc016, 14},
+        {0x8001, 15},
+        {0xc016, 15},
+        {0x8001, 16},
+        {0xc016, 16},
+        {0x8001, 17},
+        {0xc016, 17},
+        {0x8001, 18},
+        {0xc016, 18},
+    },
+    /* 232 */
+    {
+        {0x8002, 8},
+        {0x8009, 8},
+        {0x8017, 8},
+        {0xc028, 8},
+        {0x8002, 11},
+        {0x8009, 11},
+        {0x8017, 11},
+        {0xc028, 11},
+        {0x8002, 12},
+        {0x8009, 12},
+        {0x8017, 12},
+        {0xc028, 12},
+        {0x8002, 14},
+        {0x8009, 14},
+        {0x8017, 14},
+        {0xc028, 14},
+    },
+    /* 233 */
+    {
+        {0x8003, 8},
+        {0x8006, 8},
+        {0x800a, 8},
+        {0x800f, 8},
+        {0x8018, 8},
+        {0x801f, 8},
+        {0x8029, 8},
+        {0xc038, 8},
+        {0x8003, 11},
+        {0x8006, 11},
+        {0x800a, 11},
+        {0x800f, 11},
+        {0x8018, 11},
+        {0x801f, 11},
+        {0x8029, 11},
+        {0xc038, 11},
+    },
+    /* 234 */
+    {
+        {0x8003, 12},
+        {0x8006, 12},
+        {0x800a, 12},
+        {0x800f, 12},
+        {0x8018, 12},
+        {0x801f, 12},
+        {0x8029, 12},
+        {0xc038, 12},
+        {0x8003, 14},
+        {0x8006, 14},
+        {0x800a, 14},
+        {0x800f, 14},
+        {0x8018, 14},
+        {0x801f, 14},
+        {0x8029, 14},
+        {0xc038, 14},
+    },
+    /* 235 */
+    {
+        {0x8002, 15},
+        {0x8009, 15},
+        {0x8017, 15},
+        {0xc028, 15},
+        {0x8002, 16},
+        {0x8009, 16},
+        {0x8017, 16},
+        {0xc028, 16},
+        {0x8002, 17},
+        {0x8009, 17},
+        {0x8017, 17},
+        {0xc028, 17},
+        {0x8002, 18},
+        {0x8009, 18},
+        {0x8017, 18},
+        {0xc028, 18},
+    },
+    /* 236 */
+    {
+        {0x8003, 15},
+        {0x8006, 15},
+        {0x800a, 15},
+        {0x800f, 15},
+        {0x8018, 15},
+        {0x801f, 15},
+        {0x8029, 15},
+        {0xc038, 15},
+        {0x8003, 16},
+        {0x8006, 16},
+        {0x800a, 16},
+        {0x800f, 16},
+        {0x8018, 16},
+        {0x801f, 16},
+        {0x8029, 16},
+        {0xc038, 16},
+    },
+    /* 237 */
+    {
+        {0x8003, 17},
+        {0x8006, 17},
+        {0x800a, 17},
+        {0x800f, 17},
+        {0x8018, 17},
+        {0x801f, 17},
+        {0x8029, 17},
+        {0xc038, 17},
+        {0x8003, 18},
+        {0x8006, 18},
+        {0x800a, 18},
+        {0x800f, 18},
+        {0x8018, 18},
+        {0x801f, 18},
+        {0x8029, 18},
+        {0xc038, 18},
+    },
+    /* 238 */
+    {
+        {0xc000, 19},
+        {0xc000, 20},
+        {0xc000, 21},
+        {0xc000, 23},
+        {0xc000, 24},
+        {0xc000, 25},
+        {0xc000, 26},
+        {0xc000, 27},
+        {0xc000, 28},
+        {0xc000, 29},
+        {0xc000, 30},
+        {0xc000, 31},
+        {0xc000, 127},
+        {0xc000, 220},
+        {0xc000, 249},
+        {0xfd, 0},
+    },
+    /* 239 */
+    {
+        {0x8001, 19},
+        {0xc016, 19},
+        {0x8001, 20},
+        {0xc016, 20},
+        {0x8001, 21},
+        {0xc016, 21},
+        {0x8001, 23},
+        {0xc016, 23},
+        {0x8001, 24},
+        {0xc016, 24},
+        {0x8001, 25},
+        {0xc016, 25},
+        {0x8001, 26},
+        {0xc016, 26},
+        {0x8001, 27},
+        {0xc016, 27},
+    },
+    /* 240 */
+    {
+        {0x8002, 19},
+        {0x8009, 19},
+        {0x8017, 19},
+        {0xc028, 19},
+        {0x8002, 20},
+        {0x8009, 20},
+        {0x8017, 20},
+        {0xc028, 20},
+        {0x8002, 21},
+        {0x8009, 21},
+        {0x8017, 21},
+        {0xc028, 21},
+        {0x8002, 23},
+        {0x8009, 23},
+        {0x8017, 23},
+        {0xc028, 23},
+    },
+    /* 241 */
+    {
+        {0x8003, 19},
+        {0x8006, 19},
+        {0x800a, 19},
+        {0x800f, 19},
+        {0x8018, 19},
+        {0x801f, 19},
+        {0x8029, 19},
+        {0xc038, 19},
+        {0x8003, 20},
+        {0x8006, 20},
+        {0x800a, 20},
+        {0x800f, 20},
+        {0x8018, 20},
+        {0x801f, 20},
+        {0x8029, 20},
+        {0xc038, 20},
+    },
+    /* 242 */
+    {
+        {0x8003, 21},
+        {0x8006, 21},
+        {0x800a, 21},
+        {0x800f, 21},
+        {0x8018, 21},
+        {0x801f, 21},
+        {0x8029, 21},
+        {0xc038, 21},
+        {0x8003, 23},
+        {0x8006, 23},
+        {0x800a, 23},
+        {0x800f, 23},
+        {0x8018, 23},
+        {0x801f, 23},
+        {0x8029, 23},
+        {0xc038, 23},
+    },
+    /* 243 */
+    {
+        {0x8002, 24},
+        {0x8009, 24},
+        {0x8017, 24},
+        {0xc028, 24},
+        {0x8002, 25},
+        {0x8009, 25},
+        {0x8017, 25},
+        {0xc028, 25},
+        {0x8002, 26},
+        {0x8009, 26},
+        {0x8017, 26},
+        {0xc028, 26},
+        {0x8002, 27},
+        {0x8009, 27},
+        {0x8017, 27},
+        {0xc028, 27},
+    },
+    /* 244 */
+    {
+        {0x8003, 24},
+        {0x8006, 24},
+        {0x800a, 24},
+        {0x800f, 24},
+        {0x8018, 24},
+        {0x801f, 24},
+        {0x8029, 24},
+        {0xc038, 24},
+        {0x8003, 25},
+        {0x8006, 25},
+        {0x800a, 25},
+        {0x800f, 25},
+        {0x8018, 25},
+        {0x801f, 25},
+        {0x8029, 25},
+        {0xc038, 25},
+    },
+    /* 245 */
+    {
+        {0x8003, 26},
+        {0x8006, 26},
+        {0x800a, 26},
+        {0x800f, 26},
+        {0x8018, 26},
+        {0x801f, 26},
+        {0x8029, 26},
+        {0xc038, 26},
+        {0x8003, 27},
+        {0x8006, 27},
+        {0x800a, 27},
+        {0x800f, 27},
+        {0x8018, 27},
+        {0x801f, 27},
+        {0x8029, 27},
+        {0xc038, 27},
+    },
+    /* 246 */
+    {
+        {0x8001, 28},
+        {0xc016, 28},
+        {0x8001, 29},
+        {0xc016, 29},
+        {0x8001, 30},
+        {0xc016, 30},
+        {0x8001, 31},
+        {0xc016, 31},
+        {0x8001, 127},
+        {0xc016, 127},
+        {0x8001, 220},
+        {0xc016, 220},
+        {0x8001, 249},
+        {0xc016, 249},
+        {0xfe, 0},
+        {0xff, 0},
+    },
+    /* 247 */
+    {
+        {0x8002, 28},
+        {0x8009, 28},
+        {0x8017, 28},
+        {0xc028, 28},
+        {0x8002, 29},
+        {0x8009, 29},
+        {0x8017, 29},
+        {0xc028, 29},
+        {0x8002, 30},
+        {0x8009, 30},
+        {0x8017, 30},
+        {0xc028, 30},
+        {0x8002, 31},
+        {0x8009, 31},
+        {0x8017, 31},
+        {0xc028, 31},
+    },
+    /* 248 */
+    {
+        {0x8003, 28},
+        {0x8006, 28},
+        {0x800a, 28},
+        {0x800f, 28},
+        {0x8018, 28},
+        {0x801f, 28},
+        {0x8029, 28},
+        {0xc038, 28},
+        {0x8003, 29},
+        {0x8006, 29},
+        {0x800a, 29},
+        {0x800f, 29},
+        {0x8018, 29},
+        {0x801f, 29},
+        {0x8029, 29},
+        {0xc038, 29},
+    },
+    /* 249 */
+    {
+        {0x8003, 30},
+        {0x8006, 30},
+        {0x800a, 30},
+        {0x800f, 30},
+        {0x8018, 30},
+        {0x801f, 30},
+        {0x8029, 30},
+        {0xc038, 30},
+        {0x8003, 31},
+        {0x8006, 31},
+        {0x800a, 31},
+        {0x800f, 31},
+        {0x8018, 31},
+        {0x801f, 31},
+        {0x8029, 31},
+        {0xc038, 31},
+    },
+    /* 250 */
+    {
+        {0x8002, 127},
+        {0x8009, 127},
+        {0x8017, 127},
+        {0xc028, 127},
+        {0x8002, 220},
+        {0x8009, 220},
+        {0x8017, 220},
+        {0xc028, 220},
+        {0x8002, 249},
+        {0x8009, 249},
+        {0x8017, 249},
+        {0xc028, 249},
+        {0xc000, 10},
+        {0xc000, 13},
+        {0xc000, 22},
+        {0x100, 0},
+    },
+    /* 251 */
+    {
+        {0x8003, 127},
+        {0x8006, 127},
+        {0x800a, 127},
+        {0x800f, 127},
+        {0x8018, 127},
+        {0x801f, 127},
+        {0x8029, 127},
+        {0xc038, 127},
+        {0x8003, 220},
+        {0x8006, 220},
+        {0x800a, 220},
+        {0x800f, 220},
+        {0x8018, 220},
+        {0x801f, 220},
+        {0x8029, 220},
+        {0xc038, 220},
+    },
+    /* 252 */
+    {
+        {0x8003, 249},
+        {0x8006, 249},
+        {0x800a, 249},
+        {0x800f, 249},
+        {0x8018, 249},
+        {0x801f, 249},
+        {0x8029, 249},
+        {0xc038, 249},
+        {0x8001, 10},
+        {0xc016, 10},
+        {0x8001, 13},
+        {0xc016, 13},
+        {0x8001, 22},
+        {0xc016, 22},
+        {0x100, 0},
+        {0x100, 0},
+    },
+    /* 253 */
+    {
+        {0x8002, 10},
+        {0x8009, 10},
+        {0x8017, 10},
+        {0xc028, 10},
+        {0x8002, 13},
+        {0x8009, 13},
+        {0x8017, 13},
+        {0xc028, 13},
+        {0x8002, 22},
+        {0x8009, 22},
+        {0x8017, 22},
+        {0xc028, 22},
+        {0x100, 0},
+        {0x100, 0},
+        {0x100, 0},
+        {0x100, 0},
+    },
+    /* 254 */
+    {
+        {0x8003, 10},
+        {0x8006, 10},
+        {0x800a, 10},
+        {0x800f, 10},
+        {0x8018, 10},
+        {0x801f, 10},
+        {0x8029, 10},
+        {0xc038, 10},
+        {0x8003, 13},
+        {0x8006, 13},
+        {0x800a, 13},
+        {0x800f, 13},
+        {0x8018, 13},
+        {0x801f, 13},
+        {0x8029, 13},
+        {0xc038, 13},
+    },
+    /* 255 */
+    {
+        {0x8003, 22},
+        {0x8006, 22},
+        {0x800a, 22},
+        {0x800f, 22},
+        {0x8018, 22},
+        {0x801f, 22},
+        {0x8029, 22},
+        {0xc038, 22},
+        {0x100, 0},
+        {0x100, 0},
+        {0x100, 0},
+        {0x100, 0},
+        {0x100, 0},
+        {0x100, 0},
+        {0x100, 0},
+        {0x100, 0},
+    },
+    /* 256 */
+    {
+        {0x100, 0},
+        {0x100, 0},
+        {0x100, 0},
+        {0x100, 0},
+        {0x100, 0},
+        {0x100, 0},
+        {0x100, 0},
+        {0x100, 0},
+        {0x100, 0},
+        {0x100, 0},
+        {0x100, 0},
+        {0x100, 0},
+        {0x100, 0},
+        {0x100, 0},
+        {0x100, 0},
+        {0x100, 0},
+    },
+};
diff --git a/Utilities/cmnghttp2/lib/nghttp2_helper.c b/Utilities/cmnghttp2/lib/nghttp2_helper.c
new file mode 100644
index 0000000..91136a6
--- /dev/null
+++ b/Utilities/cmnghttp2/lib/nghttp2_helper.c
@@ -0,0 +1,629 @@
+/*
+ * nghttp2 - HTTP/2 C Library
+ *
+ * Copyright (c) 2012 Tatsuhiro Tsujikawa
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+#include "nghttp2_helper.h"
+
+#include <assert.h>
+#include <string.h>
+
+#include "nghttp2_net.h"
+
+void nghttp2_put_uint16be(uint8_t *buf, uint16_t n) {
+  uint16_t x = htons(n);
+  memcpy(buf, &x, sizeof(uint16_t));
+}
+
+void nghttp2_put_uint32be(uint8_t *buf, uint32_t n) {
+  uint32_t x = htonl(n);
+  memcpy(buf, &x, sizeof(uint32_t));
+}
+
+uint16_t nghttp2_get_uint16(const uint8_t *data) {
+  uint16_t n;
+  memcpy(&n, data, sizeof(uint16_t));
+  return ntohs(n);
+}
+
+uint32_t nghttp2_get_uint32(const uint8_t *data) {
+  uint32_t n;
+  memcpy(&n, data, sizeof(uint32_t));
+  return ntohl(n);
+}
+
+/* Generated by gendowncasetbl.py */
+static const uint8_t DOWNCASE_TBL[] = {
+    0 /* NUL  */,   1 /* SOH  */,   2 /* STX  */,   3 /* ETX  */,
+    4 /* EOT  */,   5 /* ENQ  */,   6 /* ACK  */,   7 /* BEL  */,
+    8 /* BS   */,   9 /* HT   */,   10 /* LF   */,  11 /* VT   */,
+    12 /* FF   */,  13 /* CR   */,  14 /* SO   */,  15 /* SI   */,
+    16 /* DLE  */,  17 /* DC1  */,  18 /* DC2  */,  19 /* DC3  */,
+    20 /* DC4  */,  21 /* NAK  */,  22 /* SYN  */,  23 /* ETB  */,
+    24 /* CAN  */,  25 /* EM   */,  26 /* SUB  */,  27 /* ESC  */,
+    28 /* FS   */,  29 /* GS   */,  30 /* RS   */,  31 /* US   */,
+    32 /* SPC  */,  33 /* !    */,  34 /* "    */,  35 /* #    */,
+    36 /* $    */,  37 /* %    */,  38 /* &    */,  39 /* '    */,
+    40 /* (    */,  41 /* )    */,  42 /* *    */,  43 /* +    */,
+    44 /* ,    */,  45 /* -    */,  46 /* .    */,  47 /* /    */,
+    48 /* 0    */,  49 /* 1    */,  50 /* 2    */,  51 /* 3    */,
+    52 /* 4    */,  53 /* 5    */,  54 /* 6    */,  55 /* 7    */,
+    56 /* 8    */,  57 /* 9    */,  58 /* :    */,  59 /* ;    */,
+    60 /* <    */,  61 /* =    */,  62 /* >    */,  63 /* ?    */,
+    64 /* @    */,  97 /* A    */,  98 /* B    */,  99 /* C    */,
+    100 /* D    */, 101 /* E    */, 102 /* F    */, 103 /* G    */,
+    104 /* H    */, 105 /* I    */, 106 /* J    */, 107 /* K    */,
+    108 /* L    */, 109 /* M    */, 110 /* N    */, 111 /* O    */,
+    112 /* P    */, 113 /* Q    */, 114 /* R    */, 115 /* S    */,
+    116 /* T    */, 117 /* U    */, 118 /* V    */, 119 /* W    */,
+    120 /* X    */, 121 /* Y    */, 122 /* Z    */, 91 /* [    */,
+    92 /* \    */,  93 /* ]    */,  94 /* ^    */,  95 /* _    */,
+    96 /* `    */,  97 /* a    */,  98 /* b    */,  99 /* c    */,
+    100 /* d    */, 101 /* e    */, 102 /* f    */, 103 /* g    */,
+    104 /* h    */, 105 /* i    */, 106 /* j    */, 107 /* k    */,
+    108 /* l    */, 109 /* m    */, 110 /* n    */, 111 /* o    */,
+    112 /* p    */, 113 /* q    */, 114 /* r    */, 115 /* s    */,
+    116 /* t    */, 117 /* u    */, 118 /* v    */, 119 /* w    */,
+    120 /* x    */, 121 /* y    */, 122 /* z    */, 123 /* {    */,
+    124 /* |    */, 125 /* }    */, 126 /* ~    */, 127 /* DEL  */,
+    128 /* 0x80 */, 129 /* 0x81 */, 130 /* 0x82 */, 131 /* 0x83 */,
+    132 /* 0x84 */, 133 /* 0x85 */, 134 /* 0x86 */, 135 /* 0x87 */,
+    136 /* 0x88 */, 137 /* 0x89 */, 138 /* 0x8a */, 139 /* 0x8b */,
+    140 /* 0x8c */, 141 /* 0x8d */, 142 /* 0x8e */, 143 /* 0x8f */,
+    144 /* 0x90 */, 145 /* 0x91 */, 146 /* 0x92 */, 147 /* 0x93 */,
+    148 /* 0x94 */, 149 /* 0x95 */, 150 /* 0x96 */, 151 /* 0x97 */,
+    152 /* 0x98 */, 153 /* 0x99 */, 154 /* 0x9a */, 155 /* 0x9b */,
+    156 /* 0x9c */, 157 /* 0x9d */, 158 /* 0x9e */, 159 /* 0x9f */,
+    160 /* 0xa0 */, 161 /* 0xa1 */, 162 /* 0xa2 */, 163 /* 0xa3 */,
+    164 /* 0xa4 */, 165 /* 0xa5 */, 166 /* 0xa6 */, 167 /* 0xa7 */,
+    168 /* 0xa8 */, 169 /* 0xa9 */, 170 /* 0xaa */, 171 /* 0xab */,
+    172 /* 0xac */, 173 /* 0xad */, 174 /* 0xae */, 175 /* 0xaf */,
+    176 /* 0xb0 */, 177 /* 0xb1 */, 178 /* 0xb2 */, 179 /* 0xb3 */,
+    180 /* 0xb4 */, 181 /* 0xb5 */, 182 /* 0xb6 */, 183 /* 0xb7 */,
+    184 /* 0xb8 */, 185 /* 0xb9 */, 186 /* 0xba */, 187 /* 0xbb */,
+    188 /* 0xbc */, 189 /* 0xbd */, 190 /* 0xbe */, 191 /* 0xbf */,
+    192 /* 0xc0 */, 193 /* 0xc1 */, 194 /* 0xc2 */, 195 /* 0xc3 */,
+    196 /* 0xc4 */, 197 /* 0xc5 */, 198 /* 0xc6 */, 199 /* 0xc7 */,
+    200 /* 0xc8 */, 201 /* 0xc9 */, 202 /* 0xca */, 203 /* 0xcb */,
+    204 /* 0xcc */, 205 /* 0xcd */, 206 /* 0xce */, 207 /* 0xcf */,
+    208 /* 0xd0 */, 209 /* 0xd1 */, 210 /* 0xd2 */, 211 /* 0xd3 */,
+    212 /* 0xd4 */, 213 /* 0xd5 */, 214 /* 0xd6 */, 215 /* 0xd7 */,
+    216 /* 0xd8 */, 217 /* 0xd9 */, 218 /* 0xda */, 219 /* 0xdb */,
+    220 /* 0xdc */, 221 /* 0xdd */, 222 /* 0xde */, 223 /* 0xdf */,
+    224 /* 0xe0 */, 225 /* 0xe1 */, 226 /* 0xe2 */, 227 /* 0xe3 */,
+    228 /* 0xe4 */, 229 /* 0xe5 */, 230 /* 0xe6 */, 231 /* 0xe7 */,
+    232 /* 0xe8 */, 233 /* 0xe9 */, 234 /* 0xea */, 235 /* 0xeb */,
+    236 /* 0xec */, 237 /* 0xed */, 238 /* 0xee */, 239 /* 0xef */,
+    240 /* 0xf0 */, 241 /* 0xf1 */, 242 /* 0xf2 */, 243 /* 0xf3 */,
+    244 /* 0xf4 */, 245 /* 0xf5 */, 246 /* 0xf6 */, 247 /* 0xf7 */,
+    248 /* 0xf8 */, 249 /* 0xf9 */, 250 /* 0xfa */, 251 /* 0xfb */,
+    252 /* 0xfc */, 253 /* 0xfd */, 254 /* 0xfe */, 255 /* 0xff */,
+};
+
+void nghttp2_downcase(uint8_t *s, size_t len) {
+  size_t i;
+  for (i = 0; i < len; ++i) {
+    s[i] = DOWNCASE_TBL[s[i]];
+  }
+}
+
+/*
+ *   local_window_size
+ *   ^  *
+ *   |  *    recv_window_size
+ *   |  *  * ^
+ *   |  *  * |
+ *  0+++++++++
+ *   |  *  *   \
+ *   |  *  *   | This rage is hidden in flow control.  But it must be
+ *   v  *  *   / kept in order to restore it when window size is enlarged.
+ *   recv_reduction
+ *   (+ for negative direction)
+ *
+ *   recv_window_size could be negative if we decrease
+ *   local_window_size more than recv_window_size:
+ *
+ *   local_window_size
+ *   ^  *
+ *   |  *
+ *   |  *
+ *   0++++++++
+ *   |  *    ^ recv_window_size (negative)
+ *   |  *    |
+ *   v  *  *
+ *   recv_reduction
+ */
+int nghttp2_adjust_local_window_size(int32_t *local_window_size_ptr,
+                                     int32_t *recv_window_size_ptr,
+                                     int32_t *recv_reduction_ptr,
+                                     int32_t *delta_ptr) {
+  if (*delta_ptr > 0) {
+    int32_t recv_reduction_delta;
+    int32_t delta;
+    int32_t new_recv_window_size =
+        nghttp2_max(0, *recv_window_size_ptr) - *delta_ptr;
+
+    if (new_recv_window_size >= 0) {
+      *recv_window_size_ptr = new_recv_window_size;
+      return 0;
+    }
+
+    delta = -new_recv_window_size;
+
+    /* The delta size is strictly more than received bytes. Increase
+       local_window_size by that difference |delta|. */
+    if (*local_window_size_ptr > NGHTTP2_MAX_WINDOW_SIZE - delta) {
+      return NGHTTP2_ERR_FLOW_CONTROL;
+    }
+    *local_window_size_ptr += delta;
+    /* If there is recv_reduction due to earlier window_size
+       reduction, we have to adjust it too. */
+    recv_reduction_delta = nghttp2_min(*recv_reduction_ptr, delta);
+    *recv_reduction_ptr -= recv_reduction_delta;
+    if (*recv_window_size_ptr < 0) {
+      *recv_window_size_ptr += recv_reduction_delta;
+    } else {
+      /* If *recv_window_size_ptr > 0, then those bytes are going to
+         be returned to the remote peer (by WINDOW_UPDATE with the
+         adjusted *delta_ptr), so it is effectively 0 now.  We set to
+         *recv_reduction_delta, because caller does not take into
+         account it in *delta_ptr. */
+      *recv_window_size_ptr = recv_reduction_delta;
+    }
+    /* recv_reduction_delta must be paid from *delta_ptr, since it was
+       added in window size reduction (see below). */
+    *delta_ptr -= recv_reduction_delta;
+
+    return 0;
+  }
+
+  if (*local_window_size_ptr + *delta_ptr < 0 ||
+      *recv_window_size_ptr < INT32_MIN - *delta_ptr ||
+      *recv_reduction_ptr > INT32_MAX + *delta_ptr) {
+    return NGHTTP2_ERR_FLOW_CONTROL;
+  }
+  /* Decreasing local window size. Note that we achieve this without
+     noticing to the remote peer. To do this, we cut
+     recv_window_size by -delta. This means that we don't send
+     WINDOW_UPDATE for -delta bytes. */
+  *local_window_size_ptr += *delta_ptr;
+  *recv_window_size_ptr += *delta_ptr;
+  *recv_reduction_ptr -= *delta_ptr;
+  *delta_ptr = 0;
+
+  return 0;
+}
+
+int nghttp2_increase_local_window_size(int32_t *local_window_size_ptr,
+                                       int32_t *recv_window_size_ptr,
+                                       int32_t *recv_reduction_ptr,
+                                       int32_t *delta_ptr) {
+  int32_t recv_reduction_delta;
+  int32_t delta;
+
+  delta = *delta_ptr;
+
+  assert(delta >= 0);
+
+  /* The delta size is strictly more than received bytes. Increase
+     local_window_size by that difference |delta|. */
+  if (*local_window_size_ptr > NGHTTP2_MAX_WINDOW_SIZE - delta) {
+    return NGHTTP2_ERR_FLOW_CONTROL;
+  }
+
+  *local_window_size_ptr += delta;
+  /* If there is recv_reduction due to earlier window_size
+     reduction, we have to adjust it too. */
+  recv_reduction_delta = nghttp2_min(*recv_reduction_ptr, delta);
+  *recv_reduction_ptr -= recv_reduction_delta;
+
+  *recv_window_size_ptr += recv_reduction_delta;
+
+  /* recv_reduction_delta must be paid from *delta_ptr, since it was
+     added in window size reduction (see below). */
+  *delta_ptr -= recv_reduction_delta;
+
+  return 0;
+}
+
+int nghttp2_should_send_window_update(int32_t local_window_size,
+                                      int32_t recv_window_size) {
+  return recv_window_size > 0 && recv_window_size >= local_window_size / 2;
+}
+
+const char *nghttp2_strerror(int error_code) {
+  switch (error_code) {
+  case 0:
+    return "Success";
+  case NGHTTP2_ERR_INVALID_ARGUMENT:
+    return "Invalid argument";
+  case NGHTTP2_ERR_BUFFER_ERROR:
+    return "Out of buffer space";
+  case NGHTTP2_ERR_UNSUPPORTED_VERSION:
+    return "Unsupported SPDY version";
+  case NGHTTP2_ERR_WOULDBLOCK:
+    return "Operation would block";
+  case NGHTTP2_ERR_PROTO:
+    return "Protocol error";
+  case NGHTTP2_ERR_INVALID_FRAME:
+    return "Invalid frame octets";
+  case NGHTTP2_ERR_EOF:
+    return "EOF";
+  case NGHTTP2_ERR_DEFERRED:
+    return "Data transfer deferred";
+  case NGHTTP2_ERR_STREAM_ID_NOT_AVAILABLE:
+    return "No more Stream ID available";
+  case NGHTTP2_ERR_STREAM_CLOSED:
+    return "Stream was already closed or invalid";
+  case NGHTTP2_ERR_STREAM_CLOSING:
+    return "Stream is closing";
+  case NGHTTP2_ERR_STREAM_SHUT_WR:
+    return "The transmission is not allowed for this stream";
+  case NGHTTP2_ERR_INVALID_STREAM_ID:
+    return "Stream ID is invalid";
+  case NGHTTP2_ERR_INVALID_STREAM_STATE:
+    return "Invalid stream state";
+  case NGHTTP2_ERR_DEFERRED_DATA_EXIST:
+    return "Another DATA frame has already been deferred";
+  case NGHTTP2_ERR_START_STREAM_NOT_ALLOWED:
+    return "request HEADERS is not allowed";
+  case NGHTTP2_ERR_GOAWAY_ALREADY_SENT:
+    return "GOAWAY has already been sent";
+  case NGHTTP2_ERR_INVALID_HEADER_BLOCK:
+    return "Invalid header block";
+  case NGHTTP2_ERR_INVALID_STATE:
+    return "Invalid state";
+  case NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE:
+    return "The user callback function failed due to the temporal error";
+  case NGHTTP2_ERR_FRAME_SIZE_ERROR:
+    return "The length of the frame is invalid";
+  case NGHTTP2_ERR_HEADER_COMP:
+    return "Header compression/decompression error";
+  case NGHTTP2_ERR_FLOW_CONTROL:
+    return "Flow control error";
+  case NGHTTP2_ERR_INSUFF_BUFSIZE:
+    return "Insufficient buffer size given to function";
+  case NGHTTP2_ERR_PAUSE:
+    return "Callback was paused by the application";
+  case NGHTTP2_ERR_TOO_MANY_INFLIGHT_SETTINGS:
+    return "Too many inflight SETTINGS";
+  case NGHTTP2_ERR_PUSH_DISABLED:
+    return "Server push is disabled by peer";
+  case NGHTTP2_ERR_DATA_EXIST:
+    return "DATA or HEADERS frame has already been submitted for the stream";
+  case NGHTTP2_ERR_SESSION_CLOSING:
+    return "The current session is closing";
+  case NGHTTP2_ERR_HTTP_HEADER:
+    return "Invalid HTTP header field was received";
+  case NGHTTP2_ERR_HTTP_MESSAGING:
+    return "Violation in HTTP messaging rule";
+  case NGHTTP2_ERR_REFUSED_STREAM:
+    return "Stream was refused";
+  case NGHTTP2_ERR_INTERNAL:
+    return "Internal error";
+  case NGHTTP2_ERR_CANCEL:
+    return "Cancel";
+  case NGHTTP2_ERR_SETTINGS_EXPECTED:
+    return "When a local endpoint expects to receive SETTINGS frame, it "
+           "receives an other type of frame";
+  case NGHTTP2_ERR_NOMEM:
+    return "Out of memory";
+  case NGHTTP2_ERR_CALLBACK_FAILURE:
+    return "The user callback function failed";
+  case NGHTTP2_ERR_BAD_CLIENT_MAGIC:
+    return "Received bad client magic byte string";
+  case NGHTTP2_ERR_FLOODED:
+    return "Flooding was detected in this HTTP/2 session, and it must be "
+           "closed";
+  default:
+    return "Unknown error code";
+  }
+}
+
+/* Generated by gennmchartbl.py */
+static const int VALID_HD_NAME_CHARS[] = {
+    0 /* NUL  */, 0 /* SOH  */, 0 /* STX  */, 0 /* ETX  */,
+    0 /* EOT  */, 0 /* ENQ  */, 0 /* ACK  */, 0 /* BEL  */,
+    0 /* BS   */, 0 /* HT   */, 0 /* LF   */, 0 /* VT   */,
+    0 /* FF   */, 0 /* CR   */, 0 /* SO   */, 0 /* SI   */,
+    0 /* DLE  */, 0 /* DC1  */, 0 /* DC2  */, 0 /* DC3  */,
+    0 /* DC4  */, 0 /* NAK  */, 0 /* SYN  */, 0 /* ETB  */,
+    0 /* CAN  */, 0 /* EM   */, 0 /* SUB  */, 0 /* ESC  */,
+    0 /* FS   */, 0 /* GS   */, 0 /* RS   */, 0 /* US   */,
+    0 /* SPC  */, 1 /* !    */, 0 /* "    */, 1 /* #    */,
+    1 /* $    */, 1 /* %    */, 1 /* &    */, 1 /* '    */,
+    0 /* (    */, 0 /* )    */, 1 /* *    */, 1 /* +    */,
+    0 /* ,    */, 1 /* -    */, 1 /* .    */, 0 /* /    */,
+    1 /* 0    */, 1 /* 1    */, 1 /* 2    */, 1 /* 3    */,
+    1 /* 4    */, 1 /* 5    */, 1 /* 6    */, 1 /* 7    */,
+    1 /* 8    */, 1 /* 9    */, 0 /* :    */, 0 /* ;    */,
+    0 /* <    */, 0 /* =    */, 0 /* >    */, 0 /* ?    */,
+    0 /* @    */, 0 /* A    */, 0 /* B    */, 0 /* C    */,
+    0 /* D    */, 0 /* E    */, 0 /* F    */, 0 /* G    */,
+    0 /* H    */, 0 /* I    */, 0 /* J    */, 0 /* K    */,
+    0 /* L    */, 0 /* M    */, 0 /* N    */, 0 /* O    */,
+    0 /* P    */, 0 /* Q    */, 0 /* R    */, 0 /* S    */,
+    0 /* T    */, 0 /* U    */, 0 /* V    */, 0 /* W    */,
+    0 /* X    */, 0 /* Y    */, 0 /* Z    */, 0 /* [    */,
+    0 /* \    */, 0 /* ]    */, 1 /* ^    */, 1 /* _    */,
+    1 /* `    */, 1 /* a    */, 1 /* b    */, 1 /* c    */,
+    1 /* d    */, 1 /* e    */, 1 /* f    */, 1 /* g    */,
+    1 /* h    */, 1 /* i    */, 1 /* j    */, 1 /* k    */,
+    1 /* l    */, 1 /* m    */, 1 /* n    */, 1 /* o    */,
+    1 /* p    */, 1 /* q    */, 1 /* r    */, 1 /* s    */,
+    1 /* t    */, 1 /* u    */, 1 /* v    */, 1 /* w    */,
+    1 /* x    */, 1 /* y    */, 1 /* z    */, 0 /* {    */,
+    1 /* |    */, 0 /* }    */, 1 /* ~    */, 0 /* DEL  */,
+    0 /* 0x80 */, 0 /* 0x81 */, 0 /* 0x82 */, 0 /* 0x83 */,
+    0 /* 0x84 */, 0 /* 0x85 */, 0 /* 0x86 */, 0 /* 0x87 */,
+    0 /* 0x88 */, 0 /* 0x89 */, 0 /* 0x8a */, 0 /* 0x8b */,
+    0 /* 0x8c */, 0 /* 0x8d */, 0 /* 0x8e */, 0 /* 0x8f */,
+    0 /* 0x90 */, 0 /* 0x91 */, 0 /* 0x92 */, 0 /* 0x93 */,
+    0 /* 0x94 */, 0 /* 0x95 */, 0 /* 0x96 */, 0 /* 0x97 */,
+    0 /* 0x98 */, 0 /* 0x99 */, 0 /* 0x9a */, 0 /* 0x9b */,
+    0 /* 0x9c */, 0 /* 0x9d */, 0 /* 0x9e */, 0 /* 0x9f */,
+    0 /* 0xa0 */, 0 /* 0xa1 */, 0 /* 0xa2 */, 0 /* 0xa3 */,
+    0 /* 0xa4 */, 0 /* 0xa5 */, 0 /* 0xa6 */, 0 /* 0xa7 */,
+    0 /* 0xa8 */, 0 /* 0xa9 */, 0 /* 0xaa */, 0 /* 0xab */,
+    0 /* 0xac */, 0 /* 0xad */, 0 /* 0xae */, 0 /* 0xaf */,
+    0 /* 0xb0 */, 0 /* 0xb1 */, 0 /* 0xb2 */, 0 /* 0xb3 */,
+    0 /* 0xb4 */, 0 /* 0xb5 */, 0 /* 0xb6 */, 0 /* 0xb7 */,
+    0 /* 0xb8 */, 0 /* 0xb9 */, 0 /* 0xba */, 0 /* 0xbb */,
+    0 /* 0xbc */, 0 /* 0xbd */, 0 /* 0xbe */, 0 /* 0xbf */,
+    0 /* 0xc0 */, 0 /* 0xc1 */, 0 /* 0xc2 */, 0 /* 0xc3 */,
+    0 /* 0xc4 */, 0 /* 0xc5 */, 0 /* 0xc6 */, 0 /* 0xc7 */,
+    0 /* 0xc8 */, 0 /* 0xc9 */, 0 /* 0xca */, 0 /* 0xcb */,
+    0 /* 0xcc */, 0 /* 0xcd */, 0 /* 0xce */, 0 /* 0xcf */,
+    0 /* 0xd0 */, 0 /* 0xd1 */, 0 /* 0xd2 */, 0 /* 0xd3 */,
+    0 /* 0xd4 */, 0 /* 0xd5 */, 0 /* 0xd6 */, 0 /* 0xd7 */,
+    0 /* 0xd8 */, 0 /* 0xd9 */, 0 /* 0xda */, 0 /* 0xdb */,
+    0 /* 0xdc */, 0 /* 0xdd */, 0 /* 0xde */, 0 /* 0xdf */,
+    0 /* 0xe0 */, 0 /* 0xe1 */, 0 /* 0xe2 */, 0 /* 0xe3 */,
+    0 /* 0xe4 */, 0 /* 0xe5 */, 0 /* 0xe6 */, 0 /* 0xe7 */,
+    0 /* 0xe8 */, 0 /* 0xe9 */, 0 /* 0xea */, 0 /* 0xeb */,
+    0 /* 0xec */, 0 /* 0xed */, 0 /* 0xee */, 0 /* 0xef */,
+    0 /* 0xf0 */, 0 /* 0xf1 */, 0 /* 0xf2 */, 0 /* 0xf3 */,
+    0 /* 0xf4 */, 0 /* 0xf5 */, 0 /* 0xf6 */, 0 /* 0xf7 */,
+    0 /* 0xf8 */, 0 /* 0xf9 */, 0 /* 0xfa */, 0 /* 0xfb */,
+    0 /* 0xfc */, 0 /* 0xfd */, 0 /* 0xfe */, 0 /* 0xff */
+};
+
+int nghttp2_check_header_name(const uint8_t *name, size_t len) {
+  const uint8_t *last;
+  if (len == 0) {
+    return 0;
+  }
+  if (*name == ':') {
+    if (len == 1) {
+      return 0;
+    }
+    ++name;
+    --len;
+  }
+  for (last = name + len; name != last; ++name) {
+    if (!VALID_HD_NAME_CHARS[*name]) {
+      return 0;
+    }
+  }
+  return 1;
+}
+
+/* Generated by genvchartbl.py */
+static const int VALID_HD_VALUE_CHARS[] = {
+    0 /* NUL  */, 0 /* SOH  */, 0 /* STX  */, 0 /* ETX  */,
+    0 /* EOT  */, 0 /* ENQ  */, 0 /* ACK  */, 0 /* BEL  */,
+    0 /* BS   */, 1 /* HT   */, 0 /* LF   */, 0 /* VT   */,
+    0 /* FF   */, 0 /* CR   */, 0 /* SO   */, 0 /* SI   */,
+    0 /* DLE  */, 0 /* DC1  */, 0 /* DC2  */, 0 /* DC3  */,
+    0 /* DC4  */, 0 /* NAK  */, 0 /* SYN  */, 0 /* ETB  */,
+    0 /* CAN  */, 0 /* EM   */, 0 /* SUB  */, 0 /* ESC  */,
+    0 /* FS   */, 0 /* GS   */, 0 /* RS   */, 0 /* US   */,
+    1 /* SPC  */, 1 /* !    */, 1 /* "    */, 1 /* #    */,
+    1 /* $    */, 1 /* %    */, 1 /* &    */, 1 /* '    */,
+    1 /* (    */, 1 /* )    */, 1 /* *    */, 1 /* +    */,
+    1 /* ,    */, 1 /* -    */, 1 /* .    */, 1 /* /    */,
+    1 /* 0    */, 1 /* 1    */, 1 /* 2    */, 1 /* 3    */,
+    1 /* 4    */, 1 /* 5    */, 1 /* 6    */, 1 /* 7    */,
+    1 /* 8    */, 1 /* 9    */, 1 /* :    */, 1 /* ;    */,
+    1 /* <    */, 1 /* =    */, 1 /* >    */, 1 /* ?    */,
+    1 /* @    */, 1 /* A    */, 1 /* B    */, 1 /* C    */,
+    1 /* D    */, 1 /* E    */, 1 /* F    */, 1 /* G    */,
+    1 /* H    */, 1 /* I    */, 1 /* J    */, 1 /* K    */,
+    1 /* L    */, 1 /* M    */, 1 /* N    */, 1 /* O    */,
+    1 /* P    */, 1 /* Q    */, 1 /* R    */, 1 /* S    */,
+    1 /* T    */, 1 /* U    */, 1 /* V    */, 1 /* W    */,
+    1 /* X    */, 1 /* Y    */, 1 /* Z    */, 1 /* [    */,
+    1 /* \    */, 1 /* ]    */, 1 /* ^    */, 1 /* _    */,
+    1 /* `    */, 1 /* a    */, 1 /* b    */, 1 /* c    */,
+    1 /* d    */, 1 /* e    */, 1 /* f    */, 1 /* g    */,
+    1 /* h    */, 1 /* i    */, 1 /* j    */, 1 /* k    */,
+    1 /* l    */, 1 /* m    */, 1 /* n    */, 1 /* o    */,
+    1 /* p    */, 1 /* q    */, 1 /* r    */, 1 /* s    */,
+    1 /* t    */, 1 /* u    */, 1 /* v    */, 1 /* w    */,
+    1 /* x    */, 1 /* y    */, 1 /* z    */, 1 /* {    */,
+    1 /* |    */, 1 /* }    */, 1 /* ~    */, 0 /* DEL  */,
+    1 /* 0x80 */, 1 /* 0x81 */, 1 /* 0x82 */, 1 /* 0x83 */,
+    1 /* 0x84 */, 1 /* 0x85 */, 1 /* 0x86 */, 1 /* 0x87 */,
+    1 /* 0x88 */, 1 /* 0x89 */, 1 /* 0x8a */, 1 /* 0x8b */,
+    1 /* 0x8c */, 1 /* 0x8d */, 1 /* 0x8e */, 1 /* 0x8f */,
+    1 /* 0x90 */, 1 /* 0x91 */, 1 /* 0x92 */, 1 /* 0x93 */,
+    1 /* 0x94 */, 1 /* 0x95 */, 1 /* 0x96 */, 1 /* 0x97 */,
+    1 /* 0x98 */, 1 /* 0x99 */, 1 /* 0x9a */, 1 /* 0x9b */,
+    1 /* 0x9c */, 1 /* 0x9d */, 1 /* 0x9e */, 1 /* 0x9f */,
+    1 /* 0xa0 */, 1 /* 0xa1 */, 1 /* 0xa2 */, 1 /* 0xa3 */,
+    1 /* 0xa4 */, 1 /* 0xa5 */, 1 /* 0xa6 */, 1 /* 0xa7 */,
+    1 /* 0xa8 */, 1 /* 0xa9 */, 1 /* 0xaa */, 1 /* 0xab */,
+    1 /* 0xac */, 1 /* 0xad */, 1 /* 0xae */, 1 /* 0xaf */,
+    1 /* 0xb0 */, 1 /* 0xb1 */, 1 /* 0xb2 */, 1 /* 0xb3 */,
+    1 /* 0xb4 */, 1 /* 0xb5 */, 1 /* 0xb6 */, 1 /* 0xb7 */,
+    1 /* 0xb8 */, 1 /* 0xb9 */, 1 /* 0xba */, 1 /* 0xbb */,
+    1 /* 0xbc */, 1 /* 0xbd */, 1 /* 0xbe */, 1 /* 0xbf */,
+    1 /* 0xc0 */, 1 /* 0xc1 */, 1 /* 0xc2 */, 1 /* 0xc3 */,
+    1 /* 0xc4 */, 1 /* 0xc5 */, 1 /* 0xc6 */, 1 /* 0xc7 */,
+    1 /* 0xc8 */, 1 /* 0xc9 */, 1 /* 0xca */, 1 /* 0xcb */,
+    1 /* 0xcc */, 1 /* 0xcd */, 1 /* 0xce */, 1 /* 0xcf */,
+    1 /* 0xd0 */, 1 /* 0xd1 */, 1 /* 0xd2 */, 1 /* 0xd3 */,
+    1 /* 0xd4 */, 1 /* 0xd5 */, 1 /* 0xd6 */, 1 /* 0xd7 */,
+    1 /* 0xd8 */, 1 /* 0xd9 */, 1 /* 0xda */, 1 /* 0xdb */,
+    1 /* 0xdc */, 1 /* 0xdd */, 1 /* 0xde */, 1 /* 0xdf */,
+    1 /* 0xe0 */, 1 /* 0xe1 */, 1 /* 0xe2 */, 1 /* 0xe3 */,
+    1 /* 0xe4 */, 1 /* 0xe5 */, 1 /* 0xe6 */, 1 /* 0xe7 */,
+    1 /* 0xe8 */, 1 /* 0xe9 */, 1 /* 0xea */, 1 /* 0xeb */,
+    1 /* 0xec */, 1 /* 0xed */, 1 /* 0xee */, 1 /* 0xef */,
+    1 /* 0xf0 */, 1 /* 0xf1 */, 1 /* 0xf2 */, 1 /* 0xf3 */,
+    1 /* 0xf4 */, 1 /* 0xf5 */, 1 /* 0xf6 */, 1 /* 0xf7 */,
+    1 /* 0xf8 */, 1 /* 0xf9 */, 1 /* 0xfa */, 1 /* 0xfb */,
+    1 /* 0xfc */, 1 /* 0xfd */, 1 /* 0xfe */, 1 /* 0xff */
+};
+
+int nghttp2_check_header_value(const uint8_t *value, size_t len) {
+  const uint8_t *last;
+  for (last = value + len; value != last; ++value) {
+    if (!VALID_HD_VALUE_CHARS[*value]) {
+      return 0;
+    }
+  }
+  return 1;
+}
+
+/* Generated by genauthroitychartbl.py */
+static char VALID_AUTHORITY_CHARS[] = {
+    0 /* NUL  */, 0 /* SOH  */, 0 /* STX  */, 0 /* ETX  */,
+    0 /* EOT  */, 0 /* ENQ  */, 0 /* ACK  */, 0 /* BEL  */,
+    0 /* BS   */, 0 /* HT   */, 0 /* LF   */, 0 /* VT   */,
+    0 /* FF   */, 0 /* CR   */, 0 /* SO   */, 0 /* SI   */,
+    0 /* DLE  */, 0 /* DC1  */, 0 /* DC2  */, 0 /* DC3  */,
+    0 /* DC4  */, 0 /* NAK  */, 0 /* SYN  */, 0 /* ETB  */,
+    0 /* CAN  */, 0 /* EM   */, 0 /* SUB  */, 0 /* ESC  */,
+    0 /* FS   */, 0 /* GS   */, 0 /* RS   */, 0 /* US   */,
+    0 /* SPC  */, 1 /* !    */, 0 /* "    */, 0 /* #    */,
+    1 /* $    */, 1 /* %    */, 1 /* &    */, 1 /* '    */,
+    1 /* (    */, 1 /* )    */, 1 /* *    */, 1 /* +    */,
+    1 /* ,    */, 1 /* -    */, 1 /* .    */, 0 /* /    */,
+    1 /* 0    */, 1 /* 1    */, 1 /* 2    */, 1 /* 3    */,
+    1 /* 4    */, 1 /* 5    */, 1 /* 6    */, 1 /* 7    */,
+    1 /* 8    */, 1 /* 9    */, 1 /* :    */, 1 /* ;    */,
+    0 /* <    */, 1 /* =    */, 0 /* >    */, 0 /* ?    */,
+    1 /* @    */, 1 /* A    */, 1 /* B    */, 1 /* C    */,
+    1 /* D    */, 1 /* E    */, 1 /* F    */, 1 /* G    */,
+    1 /* H    */, 1 /* I    */, 1 /* J    */, 1 /* K    */,
+    1 /* L    */, 1 /* M    */, 1 /* N    */, 1 /* O    */,
+    1 /* P    */, 1 /* Q    */, 1 /* R    */, 1 /* S    */,
+    1 /* T    */, 1 /* U    */, 1 /* V    */, 1 /* W    */,
+    1 /* X    */, 1 /* Y    */, 1 /* Z    */, 1 /* [    */,
+    0 /* \    */, 1 /* ]    */, 0 /* ^    */, 1 /* _    */,
+    0 /* `    */, 1 /* a    */, 1 /* b    */, 1 /* c    */,
+    1 /* d    */, 1 /* e    */, 1 /* f    */, 1 /* g    */,
+    1 /* h    */, 1 /* i    */, 1 /* j    */, 1 /* k    */,
+    1 /* l    */, 1 /* m    */, 1 /* n    */, 1 /* o    */,
+    1 /* p    */, 1 /* q    */, 1 /* r    */, 1 /* s    */,
+    1 /* t    */, 1 /* u    */, 1 /* v    */, 1 /* w    */,
+    1 /* x    */, 1 /* y    */, 1 /* z    */, 0 /* {    */,
+    0 /* |    */, 0 /* }    */, 1 /* ~    */, 0 /* DEL  */,
+    0 /* 0x80 */, 0 /* 0x81 */, 0 /* 0x82 */, 0 /* 0x83 */,
+    0 /* 0x84 */, 0 /* 0x85 */, 0 /* 0x86 */, 0 /* 0x87 */,
+    0 /* 0x88 */, 0 /* 0x89 */, 0 /* 0x8a */, 0 /* 0x8b */,
+    0 /* 0x8c */, 0 /* 0x8d */, 0 /* 0x8e */, 0 /* 0x8f */,
+    0 /* 0x90 */, 0 /* 0x91 */, 0 /* 0x92 */, 0 /* 0x93 */,
+    0 /* 0x94 */, 0 /* 0x95 */, 0 /* 0x96 */, 0 /* 0x97 */,
+    0 /* 0x98 */, 0 /* 0x99 */, 0 /* 0x9a */, 0 /* 0x9b */,
+    0 /* 0x9c */, 0 /* 0x9d */, 0 /* 0x9e */, 0 /* 0x9f */,
+    0 /* 0xa0 */, 0 /* 0xa1 */, 0 /* 0xa2 */, 0 /* 0xa3 */,
+    0 /* 0xa4 */, 0 /* 0xa5 */, 0 /* 0xa6 */, 0 /* 0xa7 */,
+    0 /* 0xa8 */, 0 /* 0xa9 */, 0 /* 0xaa */, 0 /* 0xab */,
+    0 /* 0xac */, 0 /* 0xad */, 0 /* 0xae */, 0 /* 0xaf */,
+    0 /* 0xb0 */, 0 /* 0xb1 */, 0 /* 0xb2 */, 0 /* 0xb3 */,
+    0 /* 0xb4 */, 0 /* 0xb5 */, 0 /* 0xb6 */, 0 /* 0xb7 */,
+    0 /* 0xb8 */, 0 /* 0xb9 */, 0 /* 0xba */, 0 /* 0xbb */,
+    0 /* 0xbc */, 0 /* 0xbd */, 0 /* 0xbe */, 0 /* 0xbf */,
+    0 /* 0xc0 */, 0 /* 0xc1 */, 0 /* 0xc2 */, 0 /* 0xc3 */,
+    0 /* 0xc4 */, 0 /* 0xc5 */, 0 /* 0xc6 */, 0 /* 0xc7 */,
+    0 /* 0xc8 */, 0 /* 0xc9 */, 0 /* 0xca */, 0 /* 0xcb */,
+    0 /* 0xcc */, 0 /* 0xcd */, 0 /* 0xce */, 0 /* 0xcf */,
+    0 /* 0xd0 */, 0 /* 0xd1 */, 0 /* 0xd2 */, 0 /* 0xd3 */,
+    0 /* 0xd4 */, 0 /* 0xd5 */, 0 /* 0xd6 */, 0 /* 0xd7 */,
+    0 /* 0xd8 */, 0 /* 0xd9 */, 0 /* 0xda */, 0 /* 0xdb */,
+    0 /* 0xdc */, 0 /* 0xdd */, 0 /* 0xde */, 0 /* 0xdf */,
+    0 /* 0xe0 */, 0 /* 0xe1 */, 0 /* 0xe2 */, 0 /* 0xe3 */,
+    0 /* 0xe4 */, 0 /* 0xe5 */, 0 /* 0xe6 */, 0 /* 0xe7 */,
+    0 /* 0xe8 */, 0 /* 0xe9 */, 0 /* 0xea */, 0 /* 0xeb */,
+    0 /* 0xec */, 0 /* 0xed */, 0 /* 0xee */, 0 /* 0xef */,
+    0 /* 0xf0 */, 0 /* 0xf1 */, 0 /* 0xf2 */, 0 /* 0xf3 */,
+    0 /* 0xf4 */, 0 /* 0xf5 */, 0 /* 0xf6 */, 0 /* 0xf7 */,
+    0 /* 0xf8 */, 0 /* 0xf9 */, 0 /* 0xfa */, 0 /* 0xfb */,
+    0 /* 0xfc */, 0 /* 0xfd */, 0 /* 0xfe */, 0 /* 0xff */
+};
+
+int nghttp2_check_authority(const uint8_t *value, size_t len) {
+  const uint8_t *last;
+  for (last = value + len; value != last; ++value) {
+    if (!VALID_AUTHORITY_CHARS[*value]) {
+      return 0;
+    }
+  }
+  return 1;
+}
+
+uint8_t *nghttp2_cpymem(uint8_t *dest, const void *src, size_t len) {
+  if (len == 0) {
+    return dest;
+  }
+
+  memcpy(dest, src, len);
+
+  return dest + len;
+}
+
+const char *nghttp2_http2_strerror(uint32_t error_code) {
+  switch (error_code) {
+  case NGHTTP2_NO_ERROR:
+    return "NO_ERROR";
+  case NGHTTP2_PROTOCOL_ERROR:
+    return "PROTOCOL_ERROR";
+  case NGHTTP2_INTERNAL_ERROR:
+    return "INTERNAL_ERROR";
+  case NGHTTP2_FLOW_CONTROL_ERROR:
+    return "FLOW_CONTROL_ERROR";
+  case NGHTTP2_SETTINGS_TIMEOUT:
+    return "SETTINGS_TIMEOUT";
+  case NGHTTP2_STREAM_CLOSED:
+    return "STREAM_CLOSED";
+  case NGHTTP2_FRAME_SIZE_ERROR:
+    return "FRAME_SIZE_ERROR";
+  case NGHTTP2_REFUSED_STREAM:
+    return "REFUSED_STREAM";
+  case NGHTTP2_CANCEL:
+    return "CANCEL";
+  case NGHTTP2_COMPRESSION_ERROR:
+    return "COMPRESSION_ERROR";
+  case NGHTTP2_CONNECT_ERROR:
+    return "CONNECT_ERROR";
+  case NGHTTP2_ENHANCE_YOUR_CALM:
+    return "ENHANCE_YOUR_CALM";
+  case NGHTTP2_INADEQUATE_SECURITY:
+    return "INADEQUATE_SECURITY";
+  case NGHTTP2_HTTP_1_1_REQUIRED:
+    return "HTTP_1_1_REQUIRED";
+  default:
+    return "unknown";
+  }
+}
diff --git a/Utilities/cmnghttp2/lib/nghttp2_helper.h b/Utilities/cmnghttp2/lib/nghttp2_helper.h
new file mode 100644
index 0000000..b1f18ce
--- /dev/null
+++ b/Utilities/cmnghttp2/lib/nghttp2_helper.h
@@ -0,0 +1,122 @@
+/*
+ * nghttp2 - HTTP/2 C Library
+ *
+ * Copyright (c) 2012 Tatsuhiro Tsujikawa
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+#ifndef NGHTTP2_HELPER_H
+#define NGHTTP2_HELPER_H
+
+#ifdef HAVE_CONFIG_H
+#  include <config.h>
+#endif /* HAVE_CONFIG_H */
+
+#include <string.h>
+#include <stddef.h>
+
+#include <nghttp2/nghttp2.h>
+#include "nghttp2_mem.h"
+
+#define nghttp2_min(A, B) ((A) < (B) ? (A) : (B))
+#define nghttp2_max(A, B) ((A) > (B) ? (A) : (B))
+
+#define lstreq(A, B, N) ((sizeof((A)) - 1) == (N) && memcmp((A), (B), (N)) == 0)
+
+#define nghttp2_struct_of(ptr, type, member)                                   \
+  ((type *)(void *)((char *)(ptr)-offsetof(type, member)))
+
+/*
+ * Copies 2 byte unsigned integer |n| in host byte order to |buf| in
+ * network byte order.
+ */
+void nghttp2_put_uint16be(uint8_t *buf, uint16_t n);
+
+/*
+ * Copies 4 byte unsigned integer |n| in host byte order to |buf| in
+ * network byte order.
+ */
+void nghttp2_put_uint32be(uint8_t *buf, uint32_t n);
+
+/*
+ * Retrieves 2 byte unsigned integer stored in |data| in network byte
+ * order and returns it in host byte order.
+ */
+uint16_t nghttp2_get_uint16(const uint8_t *data);
+
+/*
+ * Retrieves 4 byte unsigned integer stored in |data| in network byte
+ * order and returns it in host byte order.
+ */
+uint32_t nghttp2_get_uint32(const uint8_t *data);
+
+void nghttp2_downcase(uint8_t *s, size_t len);
+
+/*
+ * Adjusts |*local_window_size_ptr|, |*recv_window_size_ptr|,
+ * |*recv_reduction_ptr| with |*delta_ptr| which is the
+ * WINDOW_UPDATE's window_size_increment sent from local side. If
+ * |delta| is strictly larger than |*recv_window_size_ptr|,
+ * |*local_window_size_ptr| is increased by delta -
+ * *recv_window_size_ptr. If |delta| is negative,
+ * |*local_window_size_ptr| is decreased by delta.
+ *
+ * This function returns 0 if it succeeds, or one of the following
+ * negative error codes:
+ *
+ * NGHTTP2_ERR_FLOW_CONTROL
+ *     local_window_size overflow or gets negative.
+ */
+int nghttp2_adjust_local_window_size(int32_t *local_window_size_ptr,
+                                     int32_t *recv_window_size_ptr,
+                                     int32_t *recv_reduction_ptr,
+                                     int32_t *delta_ptr);
+
+/*
+ * This function works like nghttp2_adjust_local_window_size().  The
+ * difference is that this function assumes *delta_ptr >= 0, and
+ * *recv_window_size_ptr is not decreased by *delta_ptr.
+ *
+ * This function returns 0 if it succeeds, or one of the following
+ * negative error codes:
+ *
+ * NGHTTP2_ERR_FLOW_CONTROL
+ *     local_window_size overflow or gets negative.
+ */
+int nghttp2_increase_local_window_size(int32_t *local_window_size_ptr,
+                                       int32_t *recv_window_size_ptr,
+                                       int32_t *recv_reduction_ptr,
+                                       int32_t *delta_ptr);
+
+/*
+ * Returns non-zero if the function decided that WINDOW_UPDATE should
+ * be sent.
+ */
+int nghttp2_should_send_window_update(int32_t local_window_size,
+                                      int32_t recv_window_size);
+
+/*
+ * Copies the buffer |src| of length |len| to the destination pointed
+ * by the |dest|, assuming that the |dest| is at lest |len| bytes long
+ * . Returns dest + len.
+ */
+uint8_t *nghttp2_cpymem(uint8_t *dest, const void *src, size_t len);
+
+#endif /* NGHTTP2_HELPER_H */
diff --git a/Utilities/cmnghttp2/lib/nghttp2_http.c b/Utilities/cmnghttp2/lib/nghttp2_http.c
new file mode 100644
index 0000000..62f57b6
--- /dev/null
+++ b/Utilities/cmnghttp2/lib/nghttp2_http.c
@@ -0,0 +1,530 @@
+/*
+ * nghttp2 - HTTP/2 C Library
+ *
+ * Copyright (c) 2015 Tatsuhiro Tsujikawa
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+#include "nghttp2_http.h"
+
+#include <string.h>
+#include <assert.h>
+#include <stdio.h>
+
+#include "nghttp2_hd.h"
+#include "nghttp2_helper.h"
+
+static uint8_t downcase(uint8_t c) {
+  return 'A' <= c && c <= 'Z' ? (uint8_t)(c - 'A' + 'a') : c;
+}
+
+static int memieq(const void *a, const void *b, size_t n) {
+  size_t i;
+  const uint8_t *aa = a, *bb = b;
+
+  for (i = 0; i < n; ++i) {
+    if (downcase(aa[i]) != downcase(bb[i])) {
+      return 0;
+    }
+  }
+  return 1;
+}
+
+#define lstrieq(A, B, N) ((sizeof((A)) - 1) == (N) && memieq((A), (B), (N)))
+
+static int64_t parse_uint(const uint8_t *s, size_t len) {
+  int64_t n = 0;
+  size_t i;
+  if (len == 0) {
+    return -1;
+  }
+  for (i = 0; i < len; ++i) {
+    if ('0' <= s[i] && s[i] <= '9') {
+      if (n > INT64_MAX / 10) {
+        return -1;
+      }
+      n *= 10;
+      if (n > INT64_MAX - (s[i] - '0')) {
+        return -1;
+      }
+      n += s[i] - '0';
+      continue;
+    }
+    return -1;
+  }
+  return n;
+}
+
+static int lws(const uint8_t *s, size_t n) {
+  size_t i;
+  for (i = 0; i < n; ++i) {
+    if (s[i] != ' ' && s[i] != '\t') {
+      return 0;
+    }
+  }
+  return 1;
+}
+
+static int check_pseudo_header(nghttp2_stream *stream, const nghttp2_hd_nv *nv,
+                               int flag) {
+  if (stream->http_flags & flag) {
+    return 0;
+  }
+  if (lws(nv->value->base, nv->value->len)) {
+    return 0;
+  }
+  stream->http_flags = (uint16_t)(stream->http_flags | flag);
+  return 1;
+}
+
+static int expect_response_body(nghttp2_stream *stream) {
+  return (stream->http_flags & NGHTTP2_HTTP_FLAG_METH_HEAD) == 0 &&
+         stream->status_code / 100 != 1 && stream->status_code != 304 &&
+         stream->status_code != 204;
+}
+
+/* For "http" or "https" URIs, OPTIONS request may have "*" in :path
+   header field to represent system-wide OPTIONS request.  Otherwise,
+   :path header field value must start with "/".  This function must
+   be called after ":method" header field was received.  This function
+   returns nonzero if path is valid.*/
+static int check_path(nghttp2_stream *stream) {
+  return (stream->http_flags & NGHTTP2_HTTP_FLAG_SCHEME_HTTP) == 0 ||
+         ((stream->http_flags & NGHTTP2_HTTP_FLAG_PATH_REGULAR) ||
+          ((stream->http_flags & NGHTTP2_HTTP_FLAG_METH_OPTIONS) &&
+           (stream->http_flags & NGHTTP2_HTTP_FLAG_PATH_ASTERISK)));
+}
+
+static int http_request_on_header(nghttp2_stream *stream, nghttp2_hd_nv *nv,
+                                  int trailer, int connect_protocol) {
+  if (nv->name->base[0] == ':') {
+    if (trailer ||
+        (stream->http_flags & NGHTTP2_HTTP_FLAG_PSEUDO_HEADER_DISALLOWED)) {
+      return NGHTTP2_ERR_HTTP_HEADER;
+    }
+  }
+
+  switch (nv->token) {
+  case NGHTTP2_TOKEN__AUTHORITY:
+    if (!check_pseudo_header(stream, nv, NGHTTP2_HTTP_FLAG__AUTHORITY)) {
+      return NGHTTP2_ERR_HTTP_HEADER;
+    }
+    break;
+  case NGHTTP2_TOKEN__METHOD:
+    if (!check_pseudo_header(stream, nv, NGHTTP2_HTTP_FLAG__METHOD)) {
+      return NGHTTP2_ERR_HTTP_HEADER;
+    }
+    switch (nv->value->len) {
+    case 4:
+      if (lstreq("HEAD", nv->value->base, nv->value->len)) {
+        stream->http_flags |= NGHTTP2_HTTP_FLAG_METH_HEAD;
+      }
+      break;
+    case 7:
+      switch (nv->value->base[6]) {
+      case 'T':
+        if (lstreq("CONNECT", nv->value->base, nv->value->len)) {
+          if (stream->stream_id % 2 == 0) {
+            /* we won't allow CONNECT for push */
+            return NGHTTP2_ERR_HTTP_HEADER;
+          }
+          stream->http_flags |= NGHTTP2_HTTP_FLAG_METH_CONNECT;
+        }
+        break;
+      case 'S':
+        if (lstreq("OPTIONS", nv->value->base, nv->value->len)) {
+          stream->http_flags |= NGHTTP2_HTTP_FLAG_METH_OPTIONS;
+        }
+        break;
+      }
+      break;
+    }
+    break;
+  case NGHTTP2_TOKEN__PATH:
+    if (!check_pseudo_header(stream, nv, NGHTTP2_HTTP_FLAG__PATH)) {
+      return NGHTTP2_ERR_HTTP_HEADER;
+    }
+    if (nv->value->base[0] == '/') {
+      stream->http_flags |= NGHTTP2_HTTP_FLAG_PATH_REGULAR;
+    } else if (nv->value->len == 1 && nv->value->base[0] == '*') {
+      stream->http_flags |= NGHTTP2_HTTP_FLAG_PATH_ASTERISK;
+    }
+    break;
+  case NGHTTP2_TOKEN__SCHEME:
+    if (!check_pseudo_header(stream, nv, NGHTTP2_HTTP_FLAG__SCHEME)) {
+      return NGHTTP2_ERR_HTTP_HEADER;
+    }
+    if ((nv->value->len == 4 && memieq("http", nv->value->base, 4)) ||
+        (nv->value->len == 5 && memieq("https", nv->value->base, 5))) {
+      stream->http_flags |= NGHTTP2_HTTP_FLAG_SCHEME_HTTP;
+    }
+    break;
+  case NGHTTP2_TOKEN__PROTOCOL:
+    if (!connect_protocol) {
+      return NGHTTP2_ERR_HTTP_HEADER;
+    }
+
+    if (!check_pseudo_header(stream, nv, NGHTTP2_HTTP_FLAG__PROTOCOL)) {
+      return NGHTTP2_ERR_HTTP_HEADER;
+    }
+    break;
+  case NGHTTP2_TOKEN_HOST:
+    if (!check_pseudo_header(stream, nv, NGHTTP2_HTTP_FLAG_HOST)) {
+      return NGHTTP2_ERR_HTTP_HEADER;
+    }
+    break;
+  case NGHTTP2_TOKEN_CONTENT_LENGTH: {
+    if (stream->content_length != -1) {
+      return NGHTTP2_ERR_HTTP_HEADER;
+    }
+    stream->content_length = parse_uint(nv->value->base, nv->value->len);
+    if (stream->content_length == -1) {
+      return NGHTTP2_ERR_HTTP_HEADER;
+    }
+    break;
+  }
+  /* disallowed header fields */
+  case NGHTTP2_TOKEN_CONNECTION:
+  case NGHTTP2_TOKEN_KEEP_ALIVE:
+  case NGHTTP2_TOKEN_PROXY_CONNECTION:
+  case NGHTTP2_TOKEN_TRANSFER_ENCODING:
+  case NGHTTP2_TOKEN_UPGRADE:
+    return NGHTTP2_ERR_HTTP_HEADER;
+  case NGHTTP2_TOKEN_TE:
+    if (!lstrieq("trailers", nv->value->base, nv->value->len)) {
+      return NGHTTP2_ERR_HTTP_HEADER;
+    }
+    break;
+  default:
+    if (nv->name->base[0] == ':') {
+      return NGHTTP2_ERR_HTTP_HEADER;
+    }
+  }
+
+  if (nv->name->base[0] != ':') {
+    stream->http_flags |= NGHTTP2_HTTP_FLAG_PSEUDO_HEADER_DISALLOWED;
+  }
+
+  return 0;
+}
+
+static int http_response_on_header(nghttp2_stream *stream, nghttp2_hd_nv *nv,
+                                   int trailer) {
+  if (nv->name->base[0] == ':') {
+    if (trailer ||
+        (stream->http_flags & NGHTTP2_HTTP_FLAG_PSEUDO_HEADER_DISALLOWED)) {
+      return NGHTTP2_ERR_HTTP_HEADER;
+    }
+  }
+
+  switch (nv->token) {
+  case NGHTTP2_TOKEN__STATUS: {
+    if (!check_pseudo_header(stream, nv, NGHTTP2_HTTP_FLAG__STATUS)) {
+      return NGHTTP2_ERR_HTTP_HEADER;
+    }
+    if (nv->value->len != 3) {
+      return NGHTTP2_ERR_HTTP_HEADER;
+    }
+    stream->status_code = (int16_t)parse_uint(nv->value->base, nv->value->len);
+    if (stream->status_code == -1 || stream->status_code == 101) {
+      return NGHTTP2_ERR_HTTP_HEADER;
+    }
+    break;
+  }
+  case NGHTTP2_TOKEN_CONTENT_LENGTH: {
+    if (stream->status_code == 204) {
+      /* content-length header field in 204 response is prohibited by
+         RFC 7230.  But some widely used servers send content-length:
+         0.  Until they get fixed, we ignore it. */
+      if (stream->content_length != -1) {
+        /* Found multiple content-length field */
+        return NGHTTP2_ERR_HTTP_HEADER;
+      }
+      if (!lstrieq("0", nv->value->base, nv->value->len)) {
+        return NGHTTP2_ERR_HTTP_HEADER;
+      }
+      stream->content_length = 0;
+      return NGHTTP2_ERR_REMOVE_HTTP_HEADER;
+    }
+    if (stream->status_code / 100 == 1) {
+      return NGHTTP2_ERR_HTTP_HEADER;
+    }
+    /* https://tools.ietf.org/html/rfc7230#section-3.3.3 */
+    if (stream->status_code / 100 == 2 &&
+        (stream->http_flags & NGHTTP2_HTTP_FLAG_METH_CONNECT)) {
+      return NGHTTP2_ERR_REMOVE_HTTP_HEADER;
+    }
+    if (stream->content_length != -1) {
+      return NGHTTP2_ERR_HTTP_HEADER;
+    }
+    stream->content_length = parse_uint(nv->value->base, nv->value->len);
+    if (stream->content_length == -1) {
+      return NGHTTP2_ERR_HTTP_HEADER;
+    }
+    break;
+  }
+  /* disallowed header fields */
+  case NGHTTP2_TOKEN_CONNECTION:
+  case NGHTTP2_TOKEN_KEEP_ALIVE:
+  case NGHTTP2_TOKEN_PROXY_CONNECTION:
+  case NGHTTP2_TOKEN_TRANSFER_ENCODING:
+  case NGHTTP2_TOKEN_UPGRADE:
+    return NGHTTP2_ERR_HTTP_HEADER;
+  case NGHTTP2_TOKEN_TE:
+    if (!lstrieq("trailers", nv->value->base, nv->value->len)) {
+      return NGHTTP2_ERR_HTTP_HEADER;
+    }
+    break;
+  default:
+    if (nv->name->base[0] == ':') {
+      return NGHTTP2_ERR_HTTP_HEADER;
+    }
+  }
+
+  if (nv->name->base[0] != ':') {
+    stream->http_flags |= NGHTTP2_HTTP_FLAG_PSEUDO_HEADER_DISALLOWED;
+  }
+
+  return 0;
+}
+
+static int check_scheme(const uint8_t *value, size_t len) {
+  const uint8_t *last;
+  if (len == 0) {
+    return 0;
+  }
+
+  if (!(('A' <= *value && *value <= 'Z') || ('a' <= *value && *value <= 'z'))) {
+    return 0;
+  }
+
+  last = value + len;
+  ++value;
+
+  for (; value != last; ++value) {
+    if (!(('A' <= *value && *value <= 'Z') ||
+          ('a' <= *value && *value <= 'z') ||
+          ('0' <= *value && *value <= '9') || *value == '+' || *value == '-' ||
+          *value == '.')) {
+      return 0;
+    }
+  }
+  return 1;
+}
+
+int nghttp2_http_on_header(nghttp2_session *session, nghttp2_stream *stream,
+                           nghttp2_frame *frame, nghttp2_hd_nv *nv,
+                           int trailer) {
+  int rv;
+
+  /* We are strict for pseudo header field.  One bad character should
+     lead to fail.  OTOH, we should be a bit forgiving for regular
+     headers, since existing public internet has so much illegal
+     headers floating around and if we kill the stream because of
+     this, we may disrupt many web sites and/or libraries.  So we
+     become conservative here, and just ignore those illegal regular
+     headers. */
+  if (!nghttp2_check_header_name(nv->name->base, nv->name->len)) {
+    size_t i;
+    if (nv->name->len > 0 && nv->name->base[0] == ':') {
+      return NGHTTP2_ERR_HTTP_HEADER;
+    }
+    /* header field name must be lower-cased without exception */
+    for (i = 0; i < nv->name->len; ++i) {
+      uint8_t c = nv->name->base[i];
+      if ('A' <= c && c <= 'Z') {
+        return NGHTTP2_ERR_HTTP_HEADER;
+      }
+    }
+    /* When ignoring regular headers, we set this flag so that we
+       still enforce header field ordering rule for pseudo header
+       fields. */
+    stream->http_flags |= NGHTTP2_HTTP_FLAG_PSEUDO_HEADER_DISALLOWED;
+    return NGHTTP2_ERR_IGN_HTTP_HEADER;
+  }
+
+  if (nv->token == NGHTTP2_TOKEN__AUTHORITY ||
+      nv->token == NGHTTP2_TOKEN_HOST) {
+    rv = nghttp2_check_authority(nv->value->base, nv->value->len);
+  } else if (nv->token == NGHTTP2_TOKEN__SCHEME) {
+    rv = check_scheme(nv->value->base, nv->value->len);
+  } else {
+    rv = nghttp2_check_header_value(nv->value->base, nv->value->len);
+  }
+
+  if (rv == 0) {
+    assert(nv->name->len > 0);
+    if (nv->name->base[0] == ':') {
+      return NGHTTP2_ERR_HTTP_HEADER;
+    }
+    /* When ignoring regular headers, we set this flag so that we
+       still enforce header field ordering rule for pseudo header
+       fields. */
+    stream->http_flags |= NGHTTP2_HTTP_FLAG_PSEUDO_HEADER_DISALLOWED;
+    return NGHTTP2_ERR_IGN_HTTP_HEADER;
+  }
+
+  if (session->server || frame->hd.type == NGHTTP2_PUSH_PROMISE) {
+    return http_request_on_header(stream, nv, trailer,
+                                  session->server &&
+                                      session->pending_enable_connect_protocol);
+  }
+
+  return http_response_on_header(stream, nv, trailer);
+}
+
+int nghttp2_http_on_request_headers(nghttp2_stream *stream,
+                                    nghttp2_frame *frame) {
+  if (!(stream->http_flags & NGHTTP2_HTTP_FLAG__PROTOCOL) &&
+      (stream->http_flags & NGHTTP2_HTTP_FLAG_METH_CONNECT)) {
+    if ((stream->http_flags &
+         (NGHTTP2_HTTP_FLAG__SCHEME | NGHTTP2_HTTP_FLAG__PATH)) ||
+        (stream->http_flags & NGHTTP2_HTTP_FLAG__AUTHORITY) == 0) {
+      return -1;
+    }
+    stream->content_length = -1;
+  } else {
+    if ((stream->http_flags & NGHTTP2_HTTP_FLAG_REQ_HEADERS) !=
+            NGHTTP2_HTTP_FLAG_REQ_HEADERS ||
+        (stream->http_flags &
+         (NGHTTP2_HTTP_FLAG__AUTHORITY | NGHTTP2_HTTP_FLAG_HOST)) == 0) {
+      return -1;
+    }
+    if ((stream->http_flags & NGHTTP2_HTTP_FLAG__PROTOCOL) &&
+        ((stream->http_flags & NGHTTP2_HTTP_FLAG_METH_CONNECT) == 0 ||
+         (stream->http_flags & NGHTTP2_HTTP_FLAG__AUTHORITY) == 0)) {
+      return -1;
+    }
+    if (!check_path(stream)) {
+      return -1;
+    }
+  }
+
+  if (frame->hd.type == NGHTTP2_PUSH_PROMISE) {
+    /* we are going to reuse data fields for upcoming response.  Clear
+       them now, except for method flags. */
+    stream->http_flags &= NGHTTP2_HTTP_FLAG_METH_ALL;
+    stream->content_length = -1;
+  }
+
+  return 0;
+}
+
+int nghttp2_http_on_response_headers(nghttp2_stream *stream) {
+  if ((stream->http_flags & NGHTTP2_HTTP_FLAG__STATUS) == 0) {
+    return -1;
+  }
+
+  if (stream->status_code / 100 == 1) {
+    /* non-final response */
+    stream->http_flags =
+        (uint16_t)((stream->http_flags & NGHTTP2_HTTP_FLAG_METH_ALL) |
+                   NGHTTP2_HTTP_FLAG_EXPECT_FINAL_RESPONSE);
+    stream->content_length = -1;
+    stream->status_code = -1;
+    return 0;
+  }
+
+  stream->http_flags =
+      (uint16_t)(stream->http_flags & ~NGHTTP2_HTTP_FLAG_EXPECT_FINAL_RESPONSE);
+
+  if (!expect_response_body(stream)) {
+    stream->content_length = 0;
+  } else if (stream->http_flags & (NGHTTP2_HTTP_FLAG_METH_CONNECT |
+                                   NGHTTP2_HTTP_FLAG_METH_UPGRADE_WORKAROUND)) {
+    stream->content_length = -1;
+  }
+
+  return 0;
+}
+
+int nghttp2_http_on_trailer_headers(nghttp2_stream *stream,
+                                    nghttp2_frame *frame) {
+  (void)stream;
+
+  if ((frame->hd.flags & NGHTTP2_FLAG_END_STREAM) == 0) {
+    return -1;
+  }
+
+  return 0;
+}
+
+int nghttp2_http_on_remote_end_stream(nghttp2_stream *stream) {
+  if (stream->http_flags & NGHTTP2_HTTP_FLAG_EXPECT_FINAL_RESPONSE) {
+    return -1;
+  }
+
+  if (stream->content_length != -1 &&
+      stream->content_length != stream->recv_content_length) {
+    return -1;
+  }
+
+  return 0;
+}
+
+int nghttp2_http_on_data_chunk(nghttp2_stream *stream, size_t n) {
+  stream->recv_content_length += (int64_t)n;
+
+  if ((stream->http_flags & NGHTTP2_HTTP_FLAG_EXPECT_FINAL_RESPONSE) ||
+      (stream->content_length != -1 &&
+       stream->recv_content_length > stream->content_length)) {
+    return -1;
+  }
+
+  return 0;
+}
+
+void nghttp2_http_record_request_method(nghttp2_stream *stream,
+                                        nghttp2_frame *frame) {
+  const nghttp2_nv *nva;
+  size_t nvlen;
+  size_t i;
+
+  switch (frame->hd.type) {
+  case NGHTTP2_HEADERS:
+    nva = frame->headers.nva;
+    nvlen = frame->headers.nvlen;
+    break;
+  case NGHTTP2_PUSH_PROMISE:
+    nva = frame->push_promise.nva;
+    nvlen = frame->push_promise.nvlen;
+    break;
+  default:
+    return;
+  }
+
+  /* TODO we should do this strictly. */
+  for (i = 0; i < nvlen; ++i) {
+    const nghttp2_nv *nv = &nva[i];
+    if (!(nv->namelen == 7 && nv->name[6] == 'd' &&
+          memcmp(":metho", nv->name, nv->namelen - 1) == 0)) {
+      continue;
+    }
+    if (lstreq("CONNECT", nv->value, nv->valuelen)) {
+      stream->http_flags |= NGHTTP2_HTTP_FLAG_METH_CONNECT;
+      return;
+    }
+    if (lstreq("HEAD", nv->value, nv->valuelen)) {
+      stream->http_flags |= NGHTTP2_HTTP_FLAG_METH_HEAD;
+      return;
+    }
+    return;
+  }
+}
diff --git a/Utilities/cmnghttp2/lib/nghttp2_http.h b/Utilities/cmnghttp2/lib/nghttp2_http.h
new file mode 100644
index 0000000..dd057cd
--- /dev/null
+++ b/Utilities/cmnghttp2/lib/nghttp2_http.h
@@ -0,0 +1,97 @@
+/*
+ * nghttp2 - HTTP/2 C Library
+ *
+ * Copyright (c) 2015 Tatsuhiro Tsujikawa
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+#ifndef NGHTTP2_HTTP_H
+#define NGHTTP2_HTTP_H
+
+#ifdef HAVE_CONFIG_H
+#  include <config.h>
+#endif /* HAVE_CONFIG_H */
+
+#include <nghttp2/nghttp2.h>
+#include "nghttp2_session.h"
+#include "nghttp2_stream.h"
+
+/*
+ * This function is called when HTTP header field |nv| in |frame| is
+ * received for |stream|.  This function will validate |nv| against
+ * the current state of stream.
+ *
+ * This function returns 0 if it succeeds, or one of the following
+ * negative error codes:
+ *
+ * NGHTTP2_ERR_HTTP_HEADER
+ *     Invalid HTTP header field was received.
+ * NGHTTP2_ERR_IGN_HTTP_HEADER
+ *     Invalid HTTP header field was received but it can be treated as
+ *     if it was not received because of compatibility reasons.
+ */
+int nghttp2_http_on_header(nghttp2_session *session, nghttp2_stream *stream,
+                           nghttp2_frame *frame, nghttp2_hd_nv *nv,
+                           int trailer);
+
+/*
+ * This function is called when request header is received.  This
+ * function performs validation and returns 0 if it succeeds, or -1.
+ */
+int nghttp2_http_on_request_headers(nghttp2_stream *stream,
+                                    nghttp2_frame *frame);
+
+/*
+ * This function is called when response header is received.  This
+ * function performs validation and returns 0 if it succeeds, or -1.
+ */
+int nghttp2_http_on_response_headers(nghttp2_stream *stream);
+
+/*
+ * This function is called trailer header (for both request and
+ * response) is received.  This function performs validation and
+ * returns 0 if it succeeds, or -1.
+ */
+int nghttp2_http_on_trailer_headers(nghttp2_stream *stream,
+                                    nghttp2_frame *frame);
+
+/*
+ * This function is called when END_STREAM flag is seen in incoming
+ * frame.  This function performs validation and returns 0 if it
+ * succeeds, or -1.
+ */
+int nghttp2_http_on_remote_end_stream(nghttp2_stream *stream);
+
+/*
+ * This function is called when chunk of data is received.  This
+ * function performs validation and returns 0 if it succeeds, or -1.
+ */
+int nghttp2_http_on_data_chunk(nghttp2_stream *stream, size_t n);
+
+/*
+ * This function inspects header field in |frame| and records its
+ * method in stream->http_flags.  If frame->hd.type is neither
+ * NGHTTP2_HEADERS nor NGHTTP2_PUSH_PROMISE, this function does
+ * nothing.
+ */
+void nghttp2_http_record_request_method(nghttp2_stream *stream,
+                                        nghttp2_frame *frame);
+
+#endif /* NGHTTP2_HTTP_H */
diff --git a/Utilities/cmnghttp2/lib/nghttp2_int.h b/Utilities/cmnghttp2/lib/nghttp2_int.h
new file mode 100644
index 0000000..b23585c
--- /dev/null
+++ b/Utilities/cmnghttp2/lib/nghttp2_int.h
@@ -0,0 +1,58 @@
+/*
+ * nghttp2 - HTTP/2 C Library
+ *
+ * Copyright (c) 2012 Tatsuhiro Tsujikawa
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+#ifndef NGHTTP2_INT_H
+#define NGHTTP2_INT_H
+
+#ifdef HAVE_CONFIG_H
+#  include <config.h>
+#endif /* HAVE_CONFIG_H */
+
+#include <nghttp2/nghttp2.h>
+
+/* Macros, types and constants for internal use */
+
+/* "less" function, return nonzero if |lhs| is less than |rhs|. */
+typedef int (*nghttp2_less)(const void *lhs, const void *rhs);
+
+/* Internal error code. They must be in the range [-499, -100],
+   inclusive. */
+typedef enum {
+  NGHTTP2_ERR_CREDENTIAL_PENDING = -101,
+  NGHTTP2_ERR_IGN_HEADER_BLOCK = -103,
+  NGHTTP2_ERR_IGN_PAYLOAD = -104,
+  /*
+   * Invalid HTTP header field was received but it can be treated as
+   * if it was not received because of compatibility reasons.
+   */
+  NGHTTP2_ERR_IGN_HTTP_HEADER = -105,
+  /*
+   * Invalid HTTP header field was received, and it is ignored.
+   * Unlike NGHTTP2_ERR_IGN_HTTP_HEADER, this does not invoke
+   * nghttp2_on_invalid_header_callback.
+   */
+  NGHTTP2_ERR_REMOVE_HTTP_HEADER = -106
+} nghttp2_internal_error;
+
+#endif /* NGHTTP2_INT_H */
diff --git a/Utilities/cmnghttp2/lib/nghttp2_map.c b/Utilities/cmnghttp2/lib/nghttp2_map.c
new file mode 100644
index 0000000..4d9f97b
--- /dev/null
+++ b/Utilities/cmnghttp2/lib/nghttp2_map.c
@@ -0,0 +1,189 @@
+/*
+ * nghttp2 - HTTP/2 C Library
+ *
+ * Copyright (c) 2012 Tatsuhiro Tsujikawa
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+#include "nghttp2_map.h"
+
+#include <string.h>
+
+#define INITIAL_TABLE_LENGTH 256
+
+int nghttp2_map_init(nghttp2_map *map, nghttp2_mem *mem) {
+  map->mem = mem;
+  map->tablelen = INITIAL_TABLE_LENGTH;
+  map->table =
+      nghttp2_mem_calloc(mem, map->tablelen, sizeof(nghttp2_map_entry *));
+  if (map->table == NULL) {
+    return NGHTTP2_ERR_NOMEM;
+  }
+
+  map->size = 0;
+
+  return 0;
+}
+
+void nghttp2_map_free(nghttp2_map *map) {
+  nghttp2_mem_free(map->mem, map->table);
+}
+
+void nghttp2_map_each_free(nghttp2_map *map,
+                           int (*func)(nghttp2_map_entry *entry, void *ptr),
+                           void *ptr) {
+  uint32_t i;
+  for (i = 0; i < map->tablelen; ++i) {
+    nghttp2_map_entry *entry;
+    for (entry = map->table[i]; entry;) {
+      nghttp2_map_entry *next = entry->next;
+      func(entry, ptr);
+      entry = next;
+    }
+    map->table[i] = NULL;
+  }
+}
+
+int nghttp2_map_each(nghttp2_map *map,
+                     int (*func)(nghttp2_map_entry *entry, void *ptr),
+                     void *ptr) {
+  int rv;
+  uint32_t i;
+  for (i = 0; i < map->tablelen; ++i) {
+    nghttp2_map_entry *entry;
+    for (entry = map->table[i]; entry; entry = entry->next) {
+      rv = func(entry, ptr);
+      if (rv != 0) {
+        return rv;
+      }
+    }
+  }
+  return 0;
+}
+
+void nghttp2_map_entry_init(nghttp2_map_entry *entry, key_type key) {
+  entry->key = key;
+  entry->next = NULL;
+}
+
+/* Same hash function in android HashMap source code. */
+/* The |mod| must be power of 2 */
+static uint32_t hash(int32_t key, uint32_t mod) {
+  uint32_t h = (uint32_t)key;
+  h ^= (h >> 20) ^ (h >> 12);
+  h ^= (h >> 7) ^ (h >> 4);
+  return h & (mod - 1);
+}
+
+static int insert(nghttp2_map_entry **table, uint32_t tablelen,
+                  nghttp2_map_entry *entry) {
+  uint32_t h = hash(entry->key, tablelen);
+  if (table[h] == NULL) {
+    table[h] = entry;
+  } else {
+    nghttp2_map_entry *p;
+    /* We won't allow duplicated key, so check it out. */
+    for (p = table[h]; p; p = p->next) {
+      if (p->key == entry->key) {
+        return NGHTTP2_ERR_INVALID_ARGUMENT;
+      }
+    }
+    entry->next = table[h];
+    table[h] = entry;
+  }
+  return 0;
+}
+
+/* new_tablelen must be power of 2 */
+static int resize(nghttp2_map *map, uint32_t new_tablelen) {
+  uint32_t i;
+  nghttp2_map_entry **new_table;
+
+  new_table =
+      nghttp2_mem_calloc(map->mem, new_tablelen, sizeof(nghttp2_map_entry *));
+  if (new_table == NULL) {
+    return NGHTTP2_ERR_NOMEM;
+  }
+
+  for (i = 0; i < map->tablelen; ++i) {
+    nghttp2_map_entry *entry;
+    for (entry = map->table[i]; entry;) {
+      nghttp2_map_entry *next = entry->next;
+      entry->next = NULL;
+      /* This function must succeed */
+      insert(new_table, new_tablelen, entry);
+      entry = next;
+    }
+  }
+  nghttp2_mem_free(map->mem, map->table);
+  map->tablelen = new_tablelen;
+  map->table = new_table;
+
+  return 0;
+}
+
+int nghttp2_map_insert(nghttp2_map *map, nghttp2_map_entry *new_entry) {
+  int rv;
+  /* Load factor is 0.75 */
+  if ((map->size + 1) * 4 > map->tablelen * 3) {
+    rv = resize(map, map->tablelen * 2);
+    if (rv != 0) {
+      return rv;
+    }
+  }
+  rv = insert(map->table, map->tablelen, new_entry);
+  if (rv != 0) {
+    return rv;
+  }
+  ++map->size;
+  return 0;
+}
+
+nghttp2_map_entry *nghttp2_map_find(nghttp2_map *map, key_type key) {
+  uint32_t h;
+  nghttp2_map_entry *entry;
+  h = hash(key, map->tablelen);
+  for (entry = map->table[h]; entry; entry = entry->next) {
+    if (entry->key == key) {
+      return entry;
+    }
+  }
+  return NULL;
+}
+
+int nghttp2_map_remove(nghttp2_map *map, key_type key) {
+  uint32_t h;
+  nghttp2_map_entry **dst;
+
+  h = hash(key, map->tablelen);
+
+  for (dst = &map->table[h]; *dst; dst = &(*dst)->next) {
+    if ((*dst)->key != key) {
+      continue;
+    }
+
+    *dst = (*dst)->next;
+    --map->size;
+    return 0;
+  }
+  return NGHTTP2_ERR_INVALID_ARGUMENT;
+}
+
+size_t nghttp2_map_size(nghttp2_map *map) { return map->size; }
diff --git a/Utilities/cmnghttp2/lib/nghttp2_map.h b/Utilities/cmnghttp2/lib/nghttp2_map.h
new file mode 100644
index 0000000..f6e29e3
--- /dev/null
+++ b/Utilities/cmnghttp2/lib/nghttp2_map.h
@@ -0,0 +1,144 @@
+/*
+ * nghttp2 - HTTP/2 C Library
+ *
+ * Copyright (c) 2012 Tatsuhiro Tsujikawa
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+#ifndef NGHTTP2_MAP_H
+#define NGHTTP2_MAP_H
+
+#ifdef HAVE_CONFIG_H
+#  include <config.h>
+#endif /* HAVE_CONFIG_H */
+
+#include <nghttp2/nghttp2.h>
+#include "nghttp2_int.h"
+#include "nghttp2_mem.h"
+
+/* Implementation of unordered map */
+
+typedef int32_t key_type;
+
+typedef struct nghttp2_map_entry {
+  struct nghttp2_map_entry *next;
+  key_type key;
+#if SIZEOF_INT_P == 4
+  /* we requires 8 bytes aligment */
+  int64_t pad;
+#endif
+} nghttp2_map_entry;
+
+typedef struct {
+  nghttp2_map_entry **table;
+  nghttp2_mem *mem;
+  size_t size;
+  uint32_t tablelen;
+} nghttp2_map;
+
+/*
+ * Initializes the map |map|.
+ *
+ * This function returns 0 if it succeeds, or one of the following
+ * negative error codes:
+ *
+ * NGHTTP2_ERR_NOMEM
+ *   Out of memory
+ */
+int nghttp2_map_init(nghttp2_map *map, nghttp2_mem *mem);
+
+/*
+ * Deallocates any resources allocated for |map|. The stored entries
+ * are not freed by this function. Use nghttp2_map_each_free() to free
+ * each entries.
+ */
+void nghttp2_map_free(nghttp2_map *map);
+
+/*
+ * Deallocates each entries using |func| function and any resources
+ * allocated for |map|. The |func| function is responsible for freeing
+ * given the |entry| object. The |ptr| will be passed to the |func| as
+ * send argument. The return value of the |func| will be ignored.
+ */
+void nghttp2_map_each_free(nghttp2_map *map,
+                           int (*func)(nghttp2_map_entry *entry, void *ptr),
+                           void *ptr);
+
+/*
+ * Initializes the |entry| with the |key|. All entries to be inserted
+ * to the map must be initialized with this function.
+ */
+void nghttp2_map_entry_init(nghttp2_map_entry *entry, key_type key);
+
+/*
+ * Inserts the new |entry| with the key |entry->key| to the map |map|.
+ *
+ * This function returns 0 if it succeeds, or one of the following
+ * negative error codes:
+ *
+ * NGHTTP2_ERR_INVALID_ARGUMENT
+ *     The item associated by |key| already exists.
+ * NGHTTP2_ERR_NOMEM
+ *   Out of memory
+ */
+int nghttp2_map_insert(nghttp2_map *map, nghttp2_map_entry *entry);
+
+/*
+ * Returns the entry associated by the key |key|.  If there is no such
+ * entry, this function returns NULL.
+ */
+nghttp2_map_entry *nghttp2_map_find(nghttp2_map *map, key_type key);
+
+/*
+ * Removes the entry associated by the key |key| from the |map|.  The
+ * removed entry is not freed by this function.
+ *
+ * This function returns 0 if it succeeds, or one of the following
+ * negative error codes:
+ *
+ * NGHTTP2_ERR_INVALID_ARGUMENT
+ *     The entry associated by |key| does not exist.
+ */
+int nghttp2_map_remove(nghttp2_map *map, key_type key);
+
+/*
+ * Returns the number of items stored in the map |map|.
+ */
+size_t nghttp2_map_size(nghttp2_map *map);
+
+/*
+ * Applies the function |func| to each entry in the |map| with the
+ * optional user supplied pointer |ptr|.
+ *
+ * If the |func| returns 0, this function calls the |func| with the
+ * next entry. If the |func| returns nonzero, it will not call the
+ * |func| for further entries and return the return value of the
+ * |func| immediately.  Thus, this function returns 0 if all the
+ * invocations of the |func| return 0, or nonzero value which the last
+ * invocation of |func| returns.
+ *
+ * Don't use this function to free each entry. Use
+ * nghttp2_map_each_free() instead.
+ */
+int nghttp2_map_each(nghttp2_map *map,
+                     int (*func)(nghttp2_map_entry *entry, void *ptr),
+                     void *ptr);
+
+#endif /* NGHTTP2_MAP_H */
diff --git a/Utilities/cmnghttp2/lib/nghttp2_mem.c b/Utilities/cmnghttp2/lib/nghttp2_mem.c
new file mode 100644
index 0000000..6a449cf
--- /dev/null
+++ b/Utilities/cmnghttp2/lib/nghttp2_mem.c
@@ -0,0 +1,74 @@
+/*
+ * nghttp2 - HTTP/2 C Library
+ *
+ * Copyright (c) 2014 Tatsuhiro Tsujikawa
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+#include "nghttp2_mem.h"
+
+static void *default_malloc(size_t size, void *mem_user_data) {
+  (void)mem_user_data;
+
+  return malloc(size);
+}
+
+static void default_free(void *ptr, void *mem_user_data) {
+  (void)mem_user_data;
+
+  free(ptr);
+}
+
+static void *default_calloc(size_t nmemb, size_t size, void *mem_user_data) {
+  (void)mem_user_data;
+
+  return calloc(nmemb, size);
+}
+
+static void *default_realloc(void *ptr, size_t size, void *mem_user_data) {
+  (void)mem_user_data;
+
+  return realloc(ptr, size);
+}
+
+static nghttp2_mem mem_default = {NULL, default_malloc, default_free,
+                                  default_calloc, default_realloc};
+
+nghttp2_mem *nghttp2_mem_default(void) { return &mem_default; }
+
+void *nghttp2_mem_malloc(nghttp2_mem *mem, size_t size) {
+  return mem->malloc(size, mem->mem_user_data);
+}
+
+void nghttp2_mem_free(nghttp2_mem *mem, void *ptr) {
+  mem->free(ptr, mem->mem_user_data);
+}
+
+void nghttp2_mem_free2(nghttp2_free free_func, void *ptr, void *mem_user_data) {
+  free_func(ptr, mem_user_data);
+}
+
+void *nghttp2_mem_calloc(nghttp2_mem *mem, size_t nmemb, size_t size) {
+  return mem->calloc(nmemb, size, mem->mem_user_data);
+}
+
+void *nghttp2_mem_realloc(nghttp2_mem *mem, void *ptr, size_t size) {
+  return mem->realloc(ptr, size, mem->mem_user_data);
+}
diff --git a/Utilities/cmnghttp2/lib/nghttp2_mem.h b/Utilities/cmnghttp2/lib/nghttp2_mem.h
new file mode 100644
index 0000000..f83dbcb
--- /dev/null
+++ b/Utilities/cmnghttp2/lib/nghttp2_mem.h
@@ -0,0 +1,45 @@
+/*
+ * nghttp2 - HTTP/2 C Library
+ *
+ * Copyright (c) 2014 Tatsuhiro Tsujikawa
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+#ifndef NGHTTP2_MEM_H
+#define NGHTTP2_MEM_H
+
+#ifdef HAVE_CONFIG_H
+#  include <config.h>
+#endif /* HAVE_CONFIG_H */
+
+#include <nghttp2/nghttp2.h>
+
+/* The default, system standard memory allocator */
+nghttp2_mem *nghttp2_mem_default(void);
+
+/* Convenient wrapper functions to call allocator function in
+   |mem|. */
+void *nghttp2_mem_malloc(nghttp2_mem *mem, size_t size);
+void nghttp2_mem_free(nghttp2_mem *mem, void *ptr);
+void nghttp2_mem_free2(nghttp2_free free_func, void *ptr, void *mem_user_data);
+void *nghttp2_mem_calloc(nghttp2_mem *mem, size_t nmemb, size_t size);
+void *nghttp2_mem_realloc(nghttp2_mem *mem, void *ptr, size_t size);
+
+#endif /* NGHTTP2_MEM_H */
diff --git a/Utilities/cmnghttp2/lib/nghttp2_net.h b/Utilities/cmnghttp2/lib/nghttp2_net.h
new file mode 100644
index 0000000..95ffee7
--- /dev/null
+++ b/Utilities/cmnghttp2/lib/nghttp2_net.h
@@ -0,0 +1,91 @@
+/*
+ * nghttp2 - HTTP/2 C Library
+ *
+ * Copyright (c) 2012 Tatsuhiro Tsujikawa
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+#ifndef NGHTTP2_NET_H
+#define NGHTTP2_NET_H
+
+#ifdef HAVE_CONFIG_H
+#  include <config.h>
+#endif /* HAVE_CONFIG_H */
+
+#ifdef HAVE_ARPA_INET_H
+#  include <arpa/inet.h>
+#endif /* HAVE_ARPA_INET_H */
+
+#ifdef HAVE_NETINET_IN_H
+#  include <netinet/in.h>
+#endif /* HAVE_NETINET_IN_H */
+
+#include <nghttp2/nghttp2.h>
+
+#if defined(WIN32)
+/* Windows requires ws2_32 library for ntonl family functions.  We
+   define inline functions for those function so that we don't have
+   dependeny on that lib. */
+
+#  ifdef _MSC_VER
+#    define STIN static __inline
+#  else
+#    define STIN static inline
+#  endif
+
+STIN uint32_t htonl(uint32_t hostlong) {
+  uint32_t res;
+  unsigned char *p = (unsigned char *)&res;
+  *p++ = hostlong >> 24;
+  *p++ = (hostlong >> 16) & 0xffu;
+  *p++ = (hostlong >> 8) & 0xffu;
+  *p = hostlong & 0xffu;
+  return res;
+}
+
+STIN uint16_t htons(uint16_t hostshort) {
+  uint16_t res;
+  unsigned char *p = (unsigned char *)&res;
+  *p++ = hostshort >> 8;
+  *p = hostshort & 0xffu;
+  return res;
+}
+
+STIN uint32_t ntohl(uint32_t netlong) {
+  uint32_t res;
+  unsigned char *p = (unsigned char *)&netlong;
+  res = *p++ << 24;
+  res += *p++ << 16;
+  res += *p++ << 8;
+  res += *p;
+  return res;
+}
+
+STIN uint16_t ntohs(uint16_t netshort) {
+  uint16_t res;
+  unsigned char *p = (unsigned char *)&netshort;
+  res = *p++ << 8;
+  res += *p;
+  return res;
+}
+
+#endif /* WIN32 */
+
+#endif /* NGHTTP2_NET_H */
diff --git a/Utilities/cmnghttp2/lib/nghttp2_npn.c b/Utilities/cmnghttp2/lib/nghttp2_npn.c
new file mode 100644
index 0000000..d1384c8
--- /dev/null
+++ b/Utilities/cmnghttp2/lib/nghttp2_npn.c
@@ -0,0 +1,57 @@
+/*
+ * nghttp2 - HTTP/2 C Library
+ *
+ * Copyright (c) 2012 Tatsuhiro Tsujikawa
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+#include "nghttp2_npn.h"
+
+#include <string.h>
+
+static int select_next_protocol(unsigned char **out, unsigned char *outlen,
+                                const unsigned char *in, unsigned int inlen,
+                                const char *key, unsigned int keylen) {
+  unsigned int i;
+  for (i = 0; i + keylen <= inlen; i += (unsigned int)(in[i] + 1)) {
+    if (memcmp(&in[i], key, keylen) == 0) {
+      *out = (unsigned char *)&in[i + 1];
+      *outlen = in[i];
+      return 0;
+    }
+  }
+  return -1;
+}
+
+#define NGHTTP2_HTTP_1_1_ALPN "\x8http/1.1"
+#define NGHTTP2_HTTP_1_1_ALPN_LEN (sizeof(NGHTTP2_HTTP_1_1_ALPN) - 1)
+
+int nghttp2_select_next_protocol(unsigned char **out, unsigned char *outlen,
+                                 const unsigned char *in, unsigned int inlen) {
+  if (select_next_protocol(out, outlen, in, inlen, NGHTTP2_PROTO_ALPN,
+                           NGHTTP2_PROTO_ALPN_LEN) == 0) {
+    return 1;
+  }
+  if (select_next_protocol(out, outlen, in, inlen, NGHTTP2_HTTP_1_1_ALPN,
+                           NGHTTP2_HTTP_1_1_ALPN_LEN) == 0) {
+    return 0;
+  }
+  return -1;
+}
diff --git a/Utilities/cmnghttp2/lib/nghttp2_npn.h b/Utilities/cmnghttp2/lib/nghttp2_npn.h
new file mode 100644
index 0000000..c6f1c04
--- /dev/null
+++ b/Utilities/cmnghttp2/lib/nghttp2_npn.h
@@ -0,0 +1,34 @@
+/*
+ * nghttp2 - HTTP/2 C Library
+ *
+ * Copyright (c) 2012 Tatsuhiro Tsujikawa
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+#ifndef NGHTTP2_NPN_H
+#define NGHTTP2_NPN_H
+
+#ifdef HAVE_CONFIG_H
+#  include <config.h>
+#endif /* HAVE_CONFIG_H */
+
+#include <nghttp2/nghttp2.h>
+
+#endif /* NGHTTP2_NPN_H */
diff --git a/Utilities/cmnghttp2/lib/nghttp2_option.c b/Utilities/cmnghttp2/lib/nghttp2_option.c
new file mode 100644
index 0000000..e53f22d
--- /dev/null
+++ b/Utilities/cmnghttp2/lib/nghttp2_option.c
@@ -0,0 +1,123 @@
+/*
+ * nghttp2 - HTTP/2 C Library
+ *
+ * Copyright (c) 2014 Tatsuhiro Tsujikawa
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+#include "nghttp2_option.h"
+
+#include "nghttp2_session.h"
+
+int nghttp2_option_new(nghttp2_option **option_ptr) {
+  *option_ptr = calloc(1, sizeof(nghttp2_option));
+
+  if (*option_ptr == NULL) {
+    return NGHTTP2_ERR_NOMEM;
+  }
+
+  return 0;
+}
+
+void nghttp2_option_del(nghttp2_option *option) { free(option); }
+
+void nghttp2_option_set_no_auto_window_update(nghttp2_option *option, int val) {
+  option->opt_set_mask |= NGHTTP2_OPT_NO_AUTO_WINDOW_UPDATE;
+  option->no_auto_window_update = val;
+}
+
+void nghttp2_option_set_peer_max_concurrent_streams(nghttp2_option *option,
+                                                    uint32_t val) {
+  option->opt_set_mask |= NGHTTP2_OPT_PEER_MAX_CONCURRENT_STREAMS;
+  option->peer_max_concurrent_streams = val;
+}
+
+void nghttp2_option_set_no_recv_client_magic(nghttp2_option *option, int val) {
+  option->opt_set_mask |= NGHTTP2_OPT_NO_RECV_CLIENT_MAGIC;
+  option->no_recv_client_magic = val;
+}
+
+void nghttp2_option_set_no_http_messaging(nghttp2_option *option, int val) {
+  option->opt_set_mask |= NGHTTP2_OPT_NO_HTTP_MESSAGING;
+  option->no_http_messaging = val;
+}
+
+void nghttp2_option_set_max_reserved_remote_streams(nghttp2_option *option,
+                                                    uint32_t val) {
+  option->opt_set_mask |= NGHTTP2_OPT_MAX_RESERVED_REMOTE_STREAMS;
+  option->max_reserved_remote_streams = val;
+}
+
+static void set_ext_type(uint8_t *ext_types, uint8_t type) {
+  ext_types[type / 8] = (uint8_t)(ext_types[type / 8] | (1 << (type & 0x7)));
+}
+
+void nghttp2_option_set_user_recv_extension_type(nghttp2_option *option,
+                                                 uint8_t type) {
+  if (type < 10) {
+    return;
+  }
+
+  option->opt_set_mask |= NGHTTP2_OPT_USER_RECV_EXT_TYPES;
+  set_ext_type(option->user_recv_ext_types, type);
+}
+
+void nghttp2_option_set_builtin_recv_extension_type(nghttp2_option *option,
+                                                    uint8_t type) {
+  switch (type) {
+  case NGHTTP2_ALTSVC:
+    option->opt_set_mask |= NGHTTP2_OPT_BUILTIN_RECV_EXT_TYPES;
+    option->builtin_recv_ext_types |= NGHTTP2_TYPEMASK_ALTSVC;
+    return;
+  case NGHTTP2_ORIGIN:
+    option->opt_set_mask |= NGHTTP2_OPT_BUILTIN_RECV_EXT_TYPES;
+    option->builtin_recv_ext_types |= NGHTTP2_TYPEMASK_ORIGIN;
+    return;
+  default:
+    return;
+  }
+}
+
+void nghttp2_option_set_no_auto_ping_ack(nghttp2_option *option, int val) {
+  option->opt_set_mask |= NGHTTP2_OPT_NO_AUTO_PING_ACK;
+  option->no_auto_ping_ack = val;
+}
+
+void nghttp2_option_set_max_send_header_block_length(nghttp2_option *option,
+                                                     size_t val) {
+  option->opt_set_mask |= NGHTTP2_OPT_MAX_SEND_HEADER_BLOCK_LENGTH;
+  option->max_send_header_block_length = val;
+}
+
+void nghttp2_option_set_max_deflate_dynamic_table_size(nghttp2_option *option,
+                                                       size_t val) {
+  option->opt_set_mask |= NGHTTP2_OPT_MAX_DEFLATE_DYNAMIC_TABLE_SIZE;
+  option->max_deflate_dynamic_table_size = val;
+}
+
+void nghttp2_option_set_no_closed_streams(nghttp2_option *option, int val) {
+  option->opt_set_mask |= NGHTTP2_OPT_NO_CLOSED_STREAMS;
+  option->no_closed_streams = val;
+}
+
+void nghttp2_option_set_max_outbound_ack(nghttp2_option *option, size_t val) {
+  option->opt_set_mask |= NGHTTP2_OPT_MAX_OUTBOUND_ACK;
+  option->max_outbound_ack = val;
+}
diff --git a/Utilities/cmnghttp2/lib/nghttp2_option.h b/Utilities/cmnghttp2/lib/nghttp2_option.h
new file mode 100644
index 0000000..1f740aa
--- /dev/null
+++ b/Utilities/cmnghttp2/lib/nghttp2_option.h
@@ -0,0 +1,131 @@
+/*
+ * nghttp2 - HTTP/2 C Library
+ *
+ * Copyright (c) 2014 Tatsuhiro Tsujikawa
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+#ifndef NGHTTP2_OPTION_H
+#define NGHTTP2_OPTION_H
+
+#ifdef HAVE_CONFIG_H
+#  include <config.h>
+#endif /* HAVE_CONFIG_H */
+
+#include <nghttp2/nghttp2.h>
+
+/**
+ * Configuration options
+ */
+typedef enum {
+  /**
+   * This option prevents the library from sending WINDOW_UPDATE for a
+   * connection automatically.  If this option is set to nonzero, the
+   * library won't send WINDOW_UPDATE for DATA until application calls
+   * nghttp2_session_consume() to indicate the amount of consumed
+   * DATA.  By default, this option is set to zero.
+   */
+  NGHTTP2_OPT_NO_AUTO_WINDOW_UPDATE = 1,
+  /**
+   * This option sets the SETTINGS_MAX_CONCURRENT_STREAMS value of
+   * remote endpoint as if it is received in SETTINGS frame. Without
+   * specifying this option, before the local endpoint receives
+   * SETTINGS_MAX_CONCURRENT_STREAMS in SETTINGS frame from remote
+   * endpoint, SETTINGS_MAX_CONCURRENT_STREAMS is unlimited. This may
+   * cause problem if local endpoint submits lots of requests
+   * initially and sending them at once to the remote peer may lead to
+   * the rejection of some requests. Specifying this option to the
+   * sensible value, say 100, may avoid this kind of issue. This value
+   * will be overwritten if the local endpoint receives
+   * SETTINGS_MAX_CONCURRENT_STREAMS from the remote endpoint.
+   */
+  NGHTTP2_OPT_PEER_MAX_CONCURRENT_STREAMS = 1 << 1,
+  NGHTTP2_OPT_NO_RECV_CLIENT_MAGIC = 1 << 2,
+  NGHTTP2_OPT_NO_HTTP_MESSAGING = 1 << 3,
+  NGHTTP2_OPT_MAX_RESERVED_REMOTE_STREAMS = 1 << 4,
+  NGHTTP2_OPT_USER_RECV_EXT_TYPES = 1 << 5,
+  NGHTTP2_OPT_NO_AUTO_PING_ACK = 1 << 6,
+  NGHTTP2_OPT_BUILTIN_RECV_EXT_TYPES = 1 << 7,
+  NGHTTP2_OPT_MAX_SEND_HEADER_BLOCK_LENGTH = 1 << 8,
+  NGHTTP2_OPT_MAX_DEFLATE_DYNAMIC_TABLE_SIZE = 1 << 9,
+  NGHTTP2_OPT_NO_CLOSED_STREAMS = 1 << 10,
+  NGHTTP2_OPT_MAX_OUTBOUND_ACK = 1 << 11,
+} nghttp2_option_flag;
+
+/**
+ * Struct to store option values for nghttp2_session.
+ */
+struct nghttp2_option {
+  /**
+   * NGHTTP2_OPT_MAX_SEND_HEADER_BLOCK_LENGTH
+   */
+  size_t max_send_header_block_length;
+  /**
+   * NGHTTP2_OPT_MAX_DEFLATE_DYNAMIC_TABLE_SIZE
+   */
+  size_t max_deflate_dynamic_table_size;
+  /**
+   * NGHTTP2_OPT_MAX_OUTBOUND_ACK
+   */
+  size_t max_outbound_ack;
+  /**
+   * Bitwise OR of nghttp2_option_flag to determine that which fields
+   * are specified.
+   */
+  uint32_t opt_set_mask;
+  /**
+   * NGHTTP2_OPT_PEER_MAX_CONCURRENT_STREAMS
+   */
+  uint32_t peer_max_concurrent_streams;
+  /**
+   * NGHTTP2_OPT_MAX_RESERVED_REMOTE_STREAMS
+   */
+  uint32_t max_reserved_remote_streams;
+  /**
+   * NGHTTP2_OPT_BUILTIN_RECV_EXT_TYPES
+   */
+  uint32_t builtin_recv_ext_types;
+  /**
+   * NGHTTP2_OPT_NO_AUTO_WINDOW_UPDATE
+   */
+  int no_auto_window_update;
+  /**
+   * NGHTTP2_OPT_NO_RECV_CLIENT_MAGIC
+   */
+  int no_recv_client_magic;
+  /**
+   * NGHTTP2_OPT_NO_HTTP_MESSAGING
+   */
+  int no_http_messaging;
+  /**
+   * NGHTTP2_OPT_NO_AUTO_PING_ACK
+   */
+  int no_auto_ping_ack;
+  /**
+   * NGHTTP2_OPT_NO_CLOSED_STREAMS
+   */
+  int no_closed_streams;
+  /**
+   * NGHTTP2_OPT_USER_RECV_EXT_TYPES
+   */
+  uint8_t user_recv_ext_types[32];
+};
+
+#endif /* NGHTTP2_OPTION_H */
diff --git a/Utilities/cmnghttp2/lib/nghttp2_outbound_item.c b/Utilities/cmnghttp2/lib/nghttp2_outbound_item.c
new file mode 100644
index 0000000..f651c80
--- /dev/null
+++ b/Utilities/cmnghttp2/lib/nghttp2_outbound_item.c
@@ -0,0 +1,127 @@
+/*
+ * nghttp2 - HTTP/2 C Library
+ *
+ * Copyright (c) 2012 Tatsuhiro Tsujikawa
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+#include "nghttp2_outbound_item.h"
+
+#include <assert.h>
+#include <string.h>
+
+void nghttp2_outbound_item_init(nghttp2_outbound_item *item) {
+  item->cycle = 0;
+  item->qnext = NULL;
+  item->queued = 0;
+
+  memset(&item->aux_data, 0, sizeof(nghttp2_aux_data));
+}
+
+void nghttp2_outbound_item_free(nghttp2_outbound_item *item, nghttp2_mem *mem) {
+  nghttp2_frame *frame;
+
+  if (item == NULL) {
+    return;
+  }
+
+  frame = &item->frame;
+
+  switch (frame->hd.type) {
+  case NGHTTP2_DATA:
+    nghttp2_frame_data_free(&frame->data);
+    break;
+  case NGHTTP2_HEADERS:
+    nghttp2_frame_headers_free(&frame->headers, mem);
+    break;
+  case NGHTTP2_PRIORITY:
+    nghttp2_frame_priority_free(&frame->priority);
+    break;
+  case NGHTTP2_RST_STREAM:
+    nghttp2_frame_rst_stream_free(&frame->rst_stream);
+    break;
+  case NGHTTP2_SETTINGS:
+    nghttp2_frame_settings_free(&frame->settings, mem);
+    break;
+  case NGHTTP2_PUSH_PROMISE:
+    nghttp2_frame_push_promise_free(&frame->push_promise, mem);
+    break;
+  case NGHTTP2_PING:
+    nghttp2_frame_ping_free(&frame->ping);
+    break;
+  case NGHTTP2_GOAWAY:
+    nghttp2_frame_goaway_free(&frame->goaway, mem);
+    break;
+  case NGHTTP2_WINDOW_UPDATE:
+    nghttp2_frame_window_update_free(&frame->window_update);
+    break;
+  default: {
+    nghttp2_ext_aux_data *aux_data;
+
+    aux_data = &item->aux_data.ext;
+
+    if (aux_data->builtin == 0) {
+      nghttp2_frame_extension_free(&frame->ext);
+      break;
+    }
+
+    switch (frame->hd.type) {
+    case NGHTTP2_ALTSVC:
+      nghttp2_frame_altsvc_free(&frame->ext, mem);
+      break;
+    case NGHTTP2_ORIGIN:
+      nghttp2_frame_origin_free(&frame->ext, mem);
+      break;
+    default:
+      assert(0);
+      break;
+    }
+  }
+  }
+}
+
+void nghttp2_outbound_queue_init(nghttp2_outbound_queue *q) {
+  q->head = q->tail = NULL;
+  q->n = 0;
+}
+
+void nghttp2_outbound_queue_push(nghttp2_outbound_queue *q,
+                                 nghttp2_outbound_item *item) {
+  if (q->tail) {
+    q->tail = q->tail->qnext = item;
+  } else {
+    q->head = q->tail = item;
+  }
+  ++q->n;
+}
+
+void nghttp2_outbound_queue_pop(nghttp2_outbound_queue *q) {
+  nghttp2_outbound_item *item;
+  if (!q->head) {
+    return;
+  }
+  item = q->head;
+  q->head = q->head->qnext;
+  item->qnext = NULL;
+  if (!q->head) {
+    q->tail = NULL;
+  }
+  --q->n;
+}
diff --git a/Utilities/cmnghttp2/lib/nghttp2_outbound_item.h b/Utilities/cmnghttp2/lib/nghttp2_outbound_item.h
new file mode 100644
index 0000000..b5f503a
--- /dev/null
+++ b/Utilities/cmnghttp2/lib/nghttp2_outbound_item.h
@@ -0,0 +1,166 @@
+/*
+ * nghttp2 - HTTP/2 C Library
+ *
+ * Copyright (c) 2012 Tatsuhiro Tsujikawa
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+#ifndef NGHTTP2_OUTBOUND_ITEM_H
+#define NGHTTP2_OUTBOUND_ITEM_H
+
+#ifdef HAVE_CONFIG_H
+#  include <config.h>
+#endif /* HAVE_CONFIG_H */
+
+#include <nghttp2/nghttp2.h>
+#include "nghttp2_frame.h"
+#include "nghttp2_mem.h"
+
+/* struct used for HEADERS and PUSH_PROMISE frame */
+typedef struct {
+  nghttp2_data_provider data_prd;
+  void *stream_user_data;
+  /* error code when request HEADERS is canceled by RST_STREAM while
+     it is in queue. */
+  uint32_t error_code;
+  /* nonzero if request HEADERS is canceled.  The error code is stored
+     in |error_code|. */
+  uint8_t canceled;
+} nghttp2_headers_aux_data;
+
+/* struct used for DATA frame */
+typedef struct {
+  /**
+   * The data to be sent for this DATA frame.
+   */
+  nghttp2_data_provider data_prd;
+  /**
+   * The flags of DATA frame.  We use separate flags here and
+   * nghttp2_data frame.  The latter contains flags actually sent to
+   * peer.  This |flags| may contain NGHTTP2_FLAG_END_STREAM and only
+   * when |eof| becomes nonzero, flags in nghttp2_data has
+   * NGHTTP2_FLAG_END_STREAM set.
+   */
+  uint8_t flags;
+  /**
+   * The flag to indicate whether EOF was reached or not. Initially
+   * |eof| is 0. It becomes 1 after all data were read.
+   */
+  uint8_t eof;
+  /**
+   * The flag to indicate that NGHTTP2_DATA_FLAG_NO_COPY is used.
+   */
+  uint8_t no_copy;
+} nghttp2_data_aux_data;
+
+typedef enum {
+  NGHTTP2_GOAWAY_AUX_NONE = 0x0,
+  /* indicates that session should be terminated after the
+     transmission of this frame. */
+  NGHTTP2_GOAWAY_AUX_TERM_ON_SEND = 0x1,
+  /* indicates that this GOAWAY is just a notification for graceful
+     shutdown.  No nghttp2_session.goaway_flags should be updated on
+     the reaction to this frame. */
+  NGHTTP2_GOAWAY_AUX_SHUTDOWN_NOTICE = 0x2
+} nghttp2_goaway_aux_flag;
+
+/* struct used for GOAWAY frame */
+typedef struct {
+  /* bitwise-OR of one or more of nghttp2_goaway_aux_flag. */
+  uint8_t flags;
+} nghttp2_goaway_aux_data;
+
+/* struct used for extension frame */
+typedef struct {
+  /* nonzero if this extension frame is serialized by library
+     function, instead of user-defined callbacks. */
+  uint8_t builtin;
+} nghttp2_ext_aux_data;
+
+/* Additional data which cannot be stored in nghttp2_frame struct */
+typedef union {
+  nghttp2_data_aux_data data;
+  nghttp2_headers_aux_data headers;
+  nghttp2_goaway_aux_data goaway;
+  nghttp2_ext_aux_data ext;
+} nghttp2_aux_data;
+
+struct nghttp2_outbound_item;
+typedef struct nghttp2_outbound_item nghttp2_outbound_item;
+
+struct nghttp2_outbound_item {
+  nghttp2_frame frame;
+  /* Storage for extension frame payload.  frame->ext.payload points
+     to this structure to avoid frequent memory allocation. */
+  nghttp2_ext_frame_payload ext_frame_payload;
+  nghttp2_aux_data aux_data;
+  /* The priority used in priority comparion.  Smaller is served
+     earlier.  For PING, SETTINGS and non-DATA frames (excluding
+     response HEADERS frame) have dedicated cycle value defined above.
+     For DATA frame, cycle is computed by taking into account of
+     effective weight and frame payload length previously sent, so
+     that the amount of transmission is distributed across streams
+     proportional to effective weight (inside a tree). */
+  uint64_t cycle;
+  nghttp2_outbound_item *qnext;
+  /* nonzero if this object is queued, except for DATA or HEADERS
+     which are attached to stream as item. */
+  uint8_t queued;
+};
+
+/*
+ * Initializes |item|.  No memory allocation is done in this function.
+ * Don't call nghttp2_outbound_item_free() until frame member is
+ * initialized.
+ */
+void nghttp2_outbound_item_init(nghttp2_outbound_item *item);
+
+/*
+ * Deallocates resource for |item|. If |item| is NULL, this function
+ * does nothing.
+ */
+void nghttp2_outbound_item_free(nghttp2_outbound_item *item, nghttp2_mem *mem);
+
+/*
+ * queue for nghttp2_outbound_item.
+ */
+typedef struct {
+  nghttp2_outbound_item *head, *tail;
+  /* number of items in this queue. */
+  size_t n;
+} nghttp2_outbound_queue;
+
+void nghttp2_outbound_queue_init(nghttp2_outbound_queue *q);
+
+/* Pushes |item| into |q| */
+void nghttp2_outbound_queue_push(nghttp2_outbound_queue *q,
+                                 nghttp2_outbound_item *item);
+
+/* Pops |item| at the top from |q|.  If |q| is empty, nothing
+   happens. */
+void nghttp2_outbound_queue_pop(nghttp2_outbound_queue *q);
+
+/* Returns the top item. */
+#define nghttp2_outbound_queue_top(Q) ((Q)->head)
+
+/* Returns the size of the queue */
+#define nghttp2_outbound_queue_size(Q) ((Q)->n)
+
+#endif /* NGHTTP2_OUTBOUND_ITEM_H */
diff --git a/Utilities/cmnghttp2/lib/nghttp2_pq.c b/Utilities/cmnghttp2/lib/nghttp2_pq.c
new file mode 100644
index 0000000..bebccc7
--- /dev/null
+++ b/Utilities/cmnghttp2/lib/nghttp2_pq.c
@@ -0,0 +1,184 @@
+/*
+ * nghttp2 - HTTP/2 C Library
+ *
+ * Copyright (c) 2012 Tatsuhiro Tsujikawa
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+#include "nghttp2_pq.h"
+
+#include <stdio.h>
+#include <assert.h>
+
+#include "nghttp2_helper.h"
+
+int nghttp2_pq_init(nghttp2_pq *pq, nghttp2_less less, nghttp2_mem *mem) {
+  pq->mem = mem;
+  pq->capacity = 0;
+  pq->q = NULL;
+  pq->length = 0;
+  pq->less = less;
+  return 0;
+}
+
+void nghttp2_pq_free(nghttp2_pq *pq) {
+  nghttp2_mem_free(pq->mem, pq->q);
+  pq->q = NULL;
+}
+
+static void swap(nghttp2_pq *pq, size_t i, size_t j) {
+  nghttp2_pq_entry *a = pq->q[i];
+  nghttp2_pq_entry *b = pq->q[j];
+
+  pq->q[i] = b;
+  b->index = i;
+  pq->q[j] = a;
+  a->index = j;
+}
+
+static void bubble_up(nghttp2_pq *pq, size_t index) {
+  size_t parent;
+  while (index != 0) {
+    parent = (index - 1) / 2;
+    if (!pq->less(pq->q[index], pq->q[parent])) {
+      return;
+    }
+    swap(pq, parent, index);
+    index = parent;
+  }
+}
+
+int nghttp2_pq_push(nghttp2_pq *pq, nghttp2_pq_entry *item) {
+  if (pq->capacity <= pq->length) {
+    void *nq;
+    size_t ncapacity;
+
+    ncapacity = nghttp2_max(4, (pq->capacity * 2));
+
+    nq = nghttp2_mem_realloc(pq->mem, pq->q,
+                             ncapacity * sizeof(nghttp2_pq_entry *));
+    if (nq == NULL) {
+      return NGHTTP2_ERR_NOMEM;
+    }
+    pq->capacity = ncapacity;
+    pq->q = nq;
+  }
+  pq->q[pq->length] = item;
+  item->index = pq->length;
+  ++pq->length;
+  bubble_up(pq, pq->length - 1);
+  return 0;
+}
+
+nghttp2_pq_entry *nghttp2_pq_top(nghttp2_pq *pq) {
+  if (pq->length == 0) {
+    return NULL;
+  } else {
+    return pq->q[0];
+  }
+}
+
+static void bubble_down(nghttp2_pq *pq, size_t index) {
+  size_t i, j, minindex;
+  for (;;) {
+    j = index * 2 + 1;
+    minindex = index;
+    for (i = 0; i < 2; ++i, ++j) {
+      if (j >= pq->length) {
+        break;
+      }
+      if (pq->less(pq->q[j], pq->q[minindex])) {
+        minindex = j;
+      }
+    }
+    if (minindex == index) {
+      return;
+    }
+    swap(pq, index, minindex);
+    index = minindex;
+  }
+}
+
+void nghttp2_pq_pop(nghttp2_pq *pq) {
+  if (pq->length > 0) {
+    pq->q[0] = pq->q[pq->length - 1];
+    pq->q[0]->index = 0;
+    --pq->length;
+    bubble_down(pq, 0);
+  }
+}
+
+void nghttp2_pq_remove(nghttp2_pq *pq, nghttp2_pq_entry *item) {
+  assert(pq->q[item->index] == item);
+
+  if (item->index == 0) {
+    nghttp2_pq_pop(pq);
+    return;
+  }
+
+  if (item->index == pq->length - 1) {
+    --pq->length;
+    return;
+  }
+
+  pq->q[item->index] = pq->q[pq->length - 1];
+  pq->q[item->index]->index = item->index;
+  --pq->length;
+
+  if (pq->less(item, pq->q[item->index])) {
+    bubble_down(pq, item->index);
+  } else {
+    bubble_up(pq, item->index);
+  }
+}
+
+int nghttp2_pq_empty(nghttp2_pq *pq) { return pq->length == 0; }
+
+size_t nghttp2_pq_size(nghttp2_pq *pq) { return pq->length; }
+
+void nghttp2_pq_update(nghttp2_pq *pq, nghttp2_pq_item_cb fun, void *arg) {
+  size_t i;
+  int rv = 0;
+  if (pq->length == 0) {
+    return;
+  }
+  for (i = 0; i < pq->length; ++i) {
+    rv |= (*fun)(pq->q[i], arg);
+  }
+  if (rv) {
+    for (i = pq->length; i > 0; --i) {
+      bubble_down(pq, i - 1);
+    }
+  }
+}
+
+int nghttp2_pq_each(nghttp2_pq *pq, nghttp2_pq_item_cb fun, void *arg) {
+  size_t i;
+
+  if (pq->length == 0) {
+    return 0;
+  }
+  for (i = 0; i < pq->length; ++i) {
+    if ((*fun)(pq->q[i], arg)) {
+      return 1;
+    }
+  }
+  return 0;
+}
diff --git a/Utilities/cmnghttp2/lib/nghttp2_pq.h b/Utilities/cmnghttp2/lib/nghttp2_pq.h
new file mode 100644
index 0000000..2d7b702
--- /dev/null
+++ b/Utilities/cmnghttp2/lib/nghttp2_pq.h
@@ -0,0 +1,130 @@
+/*
+ * nghttp2 - HTTP/2 C Library
+ *
+ * Copyright (c) 2012 Tatsuhiro Tsujikawa
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+#ifndef NGHTTP2_PQ_H
+#define NGHTTP2_PQ_H
+
+#ifdef HAVE_CONFIG_H
+#  include <config.h>
+#endif /* HAVE_CONFIG_H */
+
+#include <nghttp2/nghttp2.h>
+#include "nghttp2_int.h"
+#include "nghttp2_mem.h"
+
+/* Implementation of priority queue */
+
+typedef struct {
+  size_t index;
+} nghttp2_pq_entry;
+
+typedef struct {
+  /* The pointer to the pointer to the item stored */
+  nghttp2_pq_entry **q;
+  /* Memory allocator */
+  nghttp2_mem *mem;
+  /* The number of items stored */
+  size_t length;
+  /* The maximum number of items this pq can store. This is
+     automatically extended when length is reached to this value. */
+  size_t capacity;
+  /* The less function between items */
+  nghttp2_less less;
+} nghttp2_pq;
+
+/*
+ * Initializes priority queue |pq| with compare function |cmp|.
+ *
+ * This function returns 0 if it succeeds, or one of the following
+ * negative error codes:
+ *
+ * NGHTTP2_ERR_NOMEM
+ *     Out of memory.
+ */
+int nghttp2_pq_init(nghttp2_pq *pq, nghttp2_less less, nghttp2_mem *mem);
+
+/*
+ * Deallocates any resources allocated for |pq|.  The stored items are
+ * not freed by this function.
+ */
+void nghttp2_pq_free(nghttp2_pq *pq);
+
+/*
+ * Adds |item| to the priority queue |pq|.
+ *
+ * This function returns 0 if it succeeds, or one of the following
+ * negative error codes:
+ *
+ * NGHTTP2_ERR_NOMEM
+ *     Out of memory.
+ */
+int nghttp2_pq_push(nghttp2_pq *pq, nghttp2_pq_entry *item);
+
+/*
+ * Returns item at the top of the queue |pq|. If the queue is empty,
+ * this function returns NULL.
+ */
+nghttp2_pq_entry *nghttp2_pq_top(nghttp2_pq *pq);
+
+/*
+ * Pops item at the top of the queue |pq|. The popped item is not
+ * freed by this function.
+ */
+void nghttp2_pq_pop(nghttp2_pq *pq);
+
+/*
+ * Returns nonzero if the queue |pq| is empty.
+ */
+int nghttp2_pq_empty(nghttp2_pq *pq);
+
+/*
+ * Returns the number of items in the queue |pq|.
+ */
+size_t nghttp2_pq_size(nghttp2_pq *pq);
+
+typedef int (*nghttp2_pq_item_cb)(nghttp2_pq_entry *item, void *arg);
+
+/*
+ * Updates each item in |pq| using function |fun| and re-construct
+ * priority queue. The |fun| must return non-zero if it modifies the
+ * item in a way that it affects ordering in the priority queue. The
+ * |arg| is passed to the 2nd parameter of |fun|.
+ */
+void nghttp2_pq_update(nghttp2_pq *pq, nghttp2_pq_item_cb fun, void *arg);
+
+/*
+ * Applys |fun| to each item in |pq|.  The |arg| is passed as arg
+ * parameter to callback function.  This function must not change the
+ * ordering key.  If the return value from callback is nonzero, this
+ * function returns 1 immediately without iterating remaining items.
+ * Otherwise this function returns 0.
+ */
+int nghttp2_pq_each(nghttp2_pq *pq, nghttp2_pq_item_cb fun, void *arg);
+
+/*
+ * Removes |item| from priority queue.
+ */
+void nghttp2_pq_remove(nghttp2_pq *pq, nghttp2_pq_entry *item);
+
+#endif /* NGHTTP2_PQ_H */
diff --git a/Utilities/cmnghttp2/lib/nghttp2_priority_spec.c b/Utilities/cmnghttp2/lib/nghttp2_priority_spec.c
new file mode 100644
index 0000000..c2196e3
--- /dev/null
+++ b/Utilities/cmnghttp2/lib/nghttp2_priority_spec.c
@@ -0,0 +1,52 @@
+/*
+ * nghttp2 - HTTP/2 C Library
+ *
+ * Copyright (c) 2014 Tatsuhiro Tsujikawa
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+#include "nghttp2_priority_spec.h"
+
+void nghttp2_priority_spec_init(nghttp2_priority_spec *pri_spec,
+                                int32_t stream_id, int32_t weight,
+                                int exclusive) {
+  pri_spec->stream_id = stream_id;
+  pri_spec->weight = weight;
+  pri_spec->exclusive = exclusive != 0;
+}
+
+void nghttp2_priority_spec_default_init(nghttp2_priority_spec *pri_spec) {
+  pri_spec->stream_id = 0;
+  pri_spec->weight = NGHTTP2_DEFAULT_WEIGHT;
+  pri_spec->exclusive = 0;
+}
+
+int nghttp2_priority_spec_check_default(const nghttp2_priority_spec *pri_spec) {
+  return pri_spec->stream_id == 0 &&
+         pri_spec->weight == NGHTTP2_DEFAULT_WEIGHT && pri_spec->exclusive == 0;
+}
+
+void nghttp2_priority_spec_normalize_weight(nghttp2_priority_spec *pri_spec) {
+  if (pri_spec->weight < NGHTTP2_MIN_WEIGHT) {
+    pri_spec->weight = NGHTTP2_MIN_WEIGHT;
+  } else if (pri_spec->weight > NGHTTP2_MAX_WEIGHT) {
+    pri_spec->weight = NGHTTP2_MAX_WEIGHT;
+  }
+}
diff --git a/Utilities/cmnghttp2/lib/nghttp2_priority_spec.h b/Utilities/cmnghttp2/lib/nghttp2_priority_spec.h
new file mode 100644
index 0000000..92ece82
--- /dev/null
+++ b/Utilities/cmnghttp2/lib/nghttp2_priority_spec.h
@@ -0,0 +1,42 @@
+/*
+ * nghttp2 - HTTP/2 C Library
+ *
+ * Copyright (c) 2014 Tatsuhiro Tsujikawa
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+#ifndef NGHTTP2_PRIORITY_SPEC_H
+#define NGHTTP2_PRIORITY_SPEC_H
+
+#ifdef HAVE_CONFIG_H
+#  include <config.h>
+#endif /* HAVE_CONFIG_H */
+
+#include <nghttp2/nghttp2.h>
+
+/*
+ * This function normalizes pri_spec->weight if it is out of range.
+ * If pri_spec->weight is less than NGHTTP2_MIN_WEIGHT, it is set to
+ * NGHTTP2_MIN_WEIGHT.  If pri_spec->weight is larger than
+ * NGHTTP2_MAX_WEIGHT, it is set to NGHTTP2_MAX_WEIGHT.
+ */
+void nghttp2_priority_spec_normalize_weight(nghttp2_priority_spec *pri_spec);
+
+#endif /* NGHTTP2_PRIORITY_SPEC_H */
diff --git a/Utilities/cmnghttp2/lib/nghttp2_queue.c b/Utilities/cmnghttp2/lib/nghttp2_queue.c
new file mode 100644
index 0000000..055eb69
--- /dev/null
+++ b/Utilities/cmnghttp2/lib/nghttp2_queue.c
@@ -0,0 +1,85 @@
+/*
+ * nghttp2 - HTTP/2 C Library
+ *
+ * Copyright (c) 2012 Tatsuhiro Tsujikawa
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+#include "nghttp2_queue.h"
+
+#include <string.h>
+#include <assert.h>
+
+void nghttp2_queue_init(nghttp2_queue *queue) {
+  queue->front = queue->back = NULL;
+}
+
+void nghttp2_queue_free(nghttp2_queue *queue) {
+  if (!queue) {
+    return;
+  } else {
+    nghttp2_queue_cell *p = queue->front;
+    while (p) {
+      nghttp2_queue_cell *next = p->next;
+      free(p);
+      p = next;
+    }
+  }
+}
+
+int nghttp2_queue_push(nghttp2_queue *queue, void *data) {
+  nghttp2_queue_cell *new_cell =
+      (nghttp2_queue_cell *)malloc(sizeof(nghttp2_queue_cell));
+  if (!new_cell) {
+    return NGHTTP2_ERR_NOMEM;
+  }
+  new_cell->data = data;
+  new_cell->next = NULL;
+  if (queue->back) {
+    queue->back->next = new_cell;
+    queue->back = new_cell;
+
+  } else {
+    queue->front = queue->back = new_cell;
+  }
+  return 0;
+}
+
+void nghttp2_queue_pop(nghttp2_queue *queue) {
+  nghttp2_queue_cell *front = queue->front;
+  assert(front);
+  queue->front = front->next;
+  if (front == queue->back) {
+    queue->back = NULL;
+  }
+  free(front);
+}
+
+void *nghttp2_queue_front(nghttp2_queue *queue) {
+  assert(queue->front);
+  return queue->front->data;
+}
+
+void *nghttp2_queue_back(nghttp2_queue *queue) {
+  assert(queue->back);
+  return queue->back->data;
+}
+
+int nghttp2_queue_empty(nghttp2_queue *queue) { return queue->front == NULL; }
diff --git a/Utilities/cmnghttp2/lib/nghttp2_queue.h b/Utilities/cmnghttp2/lib/nghttp2_queue.h
new file mode 100644
index 0000000..a06fa6c
--- /dev/null
+++ b/Utilities/cmnghttp2/lib/nghttp2_queue.h
@@ -0,0 +1,51 @@
+/*
+ * nghttp2 - HTTP/2 C Library
+ *
+ * Copyright (c) 2012 Tatsuhiro Tsujikawa
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+#ifndef NGHTTP2_QUEUE_H
+#define NGHTTP2_QUEUE_H
+
+#ifdef HAVE_CONFIG_H
+#  include "config.h"
+#endif /* HAVE_CONFIG_H */
+
+#include <nghttp2/nghttp2.h>
+
+typedef struct nghttp2_queue_cell {
+  void *data;
+  struct nghttp2_queue_cell *next;
+} nghttp2_queue_cell;
+
+typedef struct {
+  nghttp2_queue_cell *front, *back;
+} nghttp2_queue;
+
+void nghttp2_queue_init(nghttp2_queue *queue);
+void nghttp2_queue_free(nghttp2_queue *queue);
+int nghttp2_queue_push(nghttp2_queue *queue, void *data);
+void nghttp2_queue_pop(nghttp2_queue *queue);
+void *nghttp2_queue_front(nghttp2_queue *queue);
+void *nghttp2_queue_back(nghttp2_queue *queue);
+int nghttp2_queue_empty(nghttp2_queue *queue);
+
+#endif /* NGHTTP2_QUEUE_H */
diff --git a/Utilities/cmnghttp2/lib/nghttp2_rcbuf.c b/Utilities/cmnghttp2/lib/nghttp2_rcbuf.c
new file mode 100644
index 0000000..7e7814d
--- /dev/null
+++ b/Utilities/cmnghttp2/lib/nghttp2_rcbuf.c
@@ -0,0 +1,102 @@
+/*
+ * nghttp2 - HTTP/2 C Library
+ *
+ * Copyright (c) 2016 Tatsuhiro Tsujikawa
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+#include "nghttp2_rcbuf.h"
+
+#include <string.h>
+#include <assert.h>
+
+#include "nghttp2_mem.h"
+#include "nghttp2_helper.h"
+
+int nghttp2_rcbuf_new(nghttp2_rcbuf **rcbuf_ptr, size_t size,
+                      nghttp2_mem *mem) {
+  uint8_t *p;
+
+  p = nghttp2_mem_malloc(mem, sizeof(nghttp2_rcbuf) + size);
+  if (p == NULL) {
+    return NGHTTP2_ERR_NOMEM;
+  }
+
+  *rcbuf_ptr = (void *)p;
+
+  (*rcbuf_ptr)->mem_user_data = mem->mem_user_data;
+  (*rcbuf_ptr)->free = mem->free;
+  (*rcbuf_ptr)->base = p + sizeof(nghttp2_rcbuf);
+  (*rcbuf_ptr)->len = size;
+  (*rcbuf_ptr)->ref = 1;
+
+  return 0;
+}
+
+int nghttp2_rcbuf_new2(nghttp2_rcbuf **rcbuf_ptr, const uint8_t *src,
+                       size_t srclen, nghttp2_mem *mem) {
+  int rv;
+
+  rv = nghttp2_rcbuf_new(rcbuf_ptr, srclen + 1, mem);
+  if (rv != 0) {
+    return rv;
+  }
+
+  (*rcbuf_ptr)->len = srclen;
+  *nghttp2_cpymem((*rcbuf_ptr)->base, src, srclen) = '\0';
+
+  return 0;
+}
+
+/*
+ * Frees |rcbuf| itself, regardless of its reference cout.
+ */
+void nghttp2_rcbuf_del(nghttp2_rcbuf *rcbuf) {
+  nghttp2_mem_free2(rcbuf->free, rcbuf, rcbuf->mem_user_data);
+}
+
+void nghttp2_rcbuf_incref(nghttp2_rcbuf *rcbuf) {
+  if (rcbuf->ref == -1) {
+    return;
+  }
+
+  ++rcbuf->ref;
+}
+
+void nghttp2_rcbuf_decref(nghttp2_rcbuf *rcbuf) {
+  if (rcbuf == NULL || rcbuf->ref == -1) {
+    return;
+  }
+
+  assert(rcbuf->ref > 0);
+
+  if (--rcbuf->ref == 0) {
+    nghttp2_rcbuf_del(rcbuf);
+  }
+}
+
+nghttp2_vec nghttp2_rcbuf_get_buf(nghttp2_rcbuf *rcbuf) {
+  nghttp2_vec res = {rcbuf->base, rcbuf->len};
+  return res;
+}
+
+int nghttp2_rcbuf_is_static(const nghttp2_rcbuf *rcbuf) {
+  return rcbuf->ref == -1;
+}
diff --git a/Utilities/cmnghttp2/lib/nghttp2_rcbuf.h b/Utilities/cmnghttp2/lib/nghttp2_rcbuf.h
new file mode 100644
index 0000000..6814e70
--- /dev/null
+++ b/Utilities/cmnghttp2/lib/nghttp2_rcbuf.h
@@ -0,0 +1,80 @@
+/*
+ * nghttp2 - HTTP/2 C Library
+ *
+ * Copyright (c) 2016 Tatsuhiro Tsujikawa
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+#ifndef NGHTTP2_RCBUF_H
+#define NGHTTP2_RCBUF_H
+
+#ifdef HAVE_CONFIG_H
+#  include <config.h>
+#endif /* HAVE_CONFIG_H */
+
+#include <nghttp2/nghttp2.h>
+
+struct nghttp2_rcbuf {
+  /* custom memory allocator belongs to the mem parameter when
+     creating this object. */
+  void *mem_user_data;
+  nghttp2_free free;
+  /* The pointer to the underlying buffer */
+  uint8_t *base;
+  /* Size of buffer pointed by |base|. */
+  size_t len;
+  /* Reference count */
+  int32_t ref;
+};
+
+/*
+ * Allocates nghttp2_rcbuf object with |size| as initial buffer size.
+ * When the function succeeds, the reference count becomes 1.
+ *
+ * This function returns 0 if it succeeds, or one of the following
+ * negative error codes:
+ *
+ * NGHTTP2_ERR_NOMEM:
+ *     Out of memory.
+ */
+int nghttp2_rcbuf_new(nghttp2_rcbuf **rcbuf_ptr, size_t size, nghttp2_mem *mem);
+
+/*
+ * Like nghttp2_rcbuf_new(), but initializes the buffer with |src| of
+ * length |srclen|.  This function allocates additional byte at the
+ * end and puts '\0' into it, so that the resulting buffer could be
+ * used as NULL-terminated string.  Still (*rcbuf_ptr)->len equals to
+ * |srclen|.
+ *
+ * This function returns 0 if it succeeds, or one of the following
+ * negative error codes:
+ *
+ * NGHTTP2_ERR_NOMEM:
+ *     Out of memory.
+ */
+int nghttp2_rcbuf_new2(nghttp2_rcbuf **rcbuf_ptr, const uint8_t *src,
+                       size_t srclen, nghttp2_mem *mem);
+
+/*
+ * Frees |rcbuf| itself, regardless of its reference cout.
+ */
+void nghttp2_rcbuf_del(nghttp2_rcbuf *rcbuf);
+
+#endif /* NGHTTP2_RCBUF_H */
diff --git a/Utilities/cmnghttp2/lib/nghttp2_session.c b/Utilities/cmnghttp2/lib/nghttp2_session.c
new file mode 100644
index 0000000..9df3d6f
--- /dev/null
+++ b/Utilities/cmnghttp2/lib/nghttp2_session.c
@@ -0,0 +1,7780 @@
+/*
+ * nghttp2 - HTTP/2 C Library
+ *
+ * Copyright (c) 2012 Tatsuhiro Tsujikawa
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+#include "nghttp2_session.h"
+
+#include <string.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <assert.h>
+#include <stdarg.h>
+
+#include "nghttp2_helper.h"
+#include "nghttp2_net.h"
+#include "nghttp2_priority_spec.h"
+#include "nghttp2_option.h"
+#include "nghttp2_http.h"
+#include "nghttp2_pq.h"
+#include "nghttp2_debug.h"
+
+/*
+ * Returns non-zero if the number of outgoing opened streams is larger
+ * than or equal to
+ * remote_settings.max_concurrent_streams.
+ */
+static int
+session_is_outgoing_concurrent_streams_max(nghttp2_session *session) {
+  return session->remote_settings.max_concurrent_streams <=
+         session->num_outgoing_streams;
+}
+
+/*
+ * Returns non-zero if the number of incoming opened streams is larger
+ * than or equal to
+ * local_settings.max_concurrent_streams.
+ */
+static int
+session_is_incoming_concurrent_streams_max(nghttp2_session *session) {
+  return session->local_settings.max_concurrent_streams <=
+         session->num_incoming_streams;
+}
+
+/*
+ * Returns non-zero if the number of incoming opened streams is larger
+ * than or equal to
+ * session->pending_local_max_concurrent_stream.
+ */
+static int
+session_is_incoming_concurrent_streams_pending_max(nghttp2_session *session) {
+  return session->pending_local_max_concurrent_stream <=
+         session->num_incoming_streams;
+}
+
+/*
+ * Returns non-zero if |lib_error| is non-fatal error.
+ */
+static int is_non_fatal(int lib_error_code) {
+  return lib_error_code < 0 && lib_error_code > NGHTTP2_ERR_FATAL;
+}
+
+int nghttp2_is_fatal(int lib_error_code) {
+  return lib_error_code < NGHTTP2_ERR_FATAL;
+}
+
+static int session_enforce_http_messaging(nghttp2_session *session) {
+  return (session->opt_flags & NGHTTP2_OPTMASK_NO_HTTP_MESSAGING) == 0;
+}
+
+/*
+ * Returns nonzero if |frame| is trailer headers.
+ */
+static int session_trailer_headers(nghttp2_session *session,
+                                   nghttp2_stream *stream,
+                                   nghttp2_frame *frame) {
+  if (!stream || frame->hd.type != NGHTTP2_HEADERS) {
+    return 0;
+  }
+  if (session->server) {
+    return frame->headers.cat == NGHTTP2_HCAT_HEADERS;
+  }
+
+  return frame->headers.cat == NGHTTP2_HCAT_HEADERS &&
+         (stream->http_flags & NGHTTP2_HTTP_FLAG_EXPECT_FINAL_RESPONSE) == 0;
+}
+
+/* Returns nonzero if the |stream| is in reserved(remote) state */
+static int state_reserved_remote(nghttp2_session *session,
+                                 nghttp2_stream *stream) {
+  return stream->state == NGHTTP2_STREAM_RESERVED &&
+         !nghttp2_session_is_my_stream_id(session, stream->stream_id);
+}
+
+/* Returns nonzero if the |stream| is in reserved(local) state */
+static int state_reserved_local(nghttp2_session *session,
+                                nghttp2_stream *stream) {
+  return stream->state == NGHTTP2_STREAM_RESERVED &&
+         nghttp2_session_is_my_stream_id(session, stream->stream_id);
+}
+
+/*
+ * Checks whether received stream_id is valid.  This function returns
+ * 1 if it succeeds, or 0.
+ */
+static int session_is_new_peer_stream_id(nghttp2_session *session,
+                                         int32_t stream_id) {
+  return stream_id != 0 &&
+         !nghttp2_session_is_my_stream_id(session, stream_id) &&
+         session->last_recv_stream_id < stream_id;
+}
+
+static int session_detect_idle_stream(nghttp2_session *session,
+                                      int32_t stream_id) {
+  /* Assume that stream object with stream_id does not exist */
+  if (nghttp2_session_is_my_stream_id(session, stream_id)) {
+    if (session->last_sent_stream_id < stream_id) {
+      return 1;
+    }
+    return 0;
+  }
+  if (session_is_new_peer_stream_id(session, stream_id)) {
+    return 1;
+  }
+  return 0;
+}
+
+static int check_ext_type_set(const uint8_t *ext_types, uint8_t type) {
+  return (ext_types[type / 8] & (1 << (type & 0x7))) > 0;
+}
+
+static int session_call_error_callback(nghttp2_session *session,
+                                       int lib_error_code, const char *fmt,
+                                       ...) {
+  size_t bufsize;
+  va_list ap;
+  char *buf;
+  int rv;
+  nghttp2_mem *mem;
+
+  if (!session->callbacks.error_callback &&
+      !session->callbacks.error_callback2) {
+    return 0;
+  }
+
+  mem = &session->mem;
+
+  va_start(ap, fmt);
+  rv = vsnprintf(NULL, 0, fmt, ap);
+  va_end(ap);
+
+  if (rv < 0) {
+    return NGHTTP2_ERR_NOMEM;
+  }
+
+  bufsize = (size_t)(rv + 1);
+
+  buf = nghttp2_mem_malloc(mem, bufsize);
+  if (buf == NULL) {
+    return NGHTTP2_ERR_NOMEM;
+  }
+
+  va_start(ap, fmt);
+  rv = vsnprintf(buf, bufsize, fmt, ap);
+  va_end(ap);
+
+  if (rv < 0) {
+    nghttp2_mem_free(mem, buf);
+    /* vsnprintf may return error because of various things we can
+       imagine, but typically we don't want to drop session just for
+       debug callback. */
+    DEBUGF("error_callback: vsnprintf failed. The template was %s\n", fmt);
+    return 0;
+  }
+
+  if (session->callbacks.error_callback2) {
+    rv = session->callbacks.error_callback2(session, lib_error_code, buf,
+                                            (size_t)rv, session->user_data);
+  } else {
+    rv = session->callbacks.error_callback(session, buf, (size_t)rv,
+                                           session->user_data);
+  }
+
+  nghttp2_mem_free(mem, buf);
+
+  if (rv != 0) {
+    return NGHTTP2_ERR_CALLBACK_FAILURE;
+  }
+
+  return 0;
+}
+
+static int session_terminate_session(nghttp2_session *session,
+                                     int32_t last_stream_id,
+                                     uint32_t error_code, const char *reason) {
+  int rv;
+  const uint8_t *debug_data;
+  size_t debug_datalen;
+
+  if (session->goaway_flags & NGHTTP2_GOAWAY_TERM_ON_SEND) {
+    return 0;
+  }
+
+  /* Ignore all incoming frames because we are going to tear down the
+     session. */
+  session->iframe.state = NGHTTP2_IB_IGN_ALL;
+
+  if (reason == NULL) {
+    debug_data = NULL;
+    debug_datalen = 0;
+  } else {
+    debug_data = (const uint8_t *)reason;
+    debug_datalen = strlen(reason);
+  }
+
+  rv = nghttp2_session_add_goaway(session, last_stream_id, error_code,
+                                  debug_data, debug_datalen,
+                                  NGHTTP2_GOAWAY_AUX_TERM_ON_SEND);
+
+  if (rv != 0) {
+    return rv;
+  }
+
+  session->goaway_flags |= NGHTTP2_GOAWAY_TERM_ON_SEND;
+
+  return 0;
+}
+
+int nghttp2_session_terminate_session(nghttp2_session *session,
+                                      uint32_t error_code) {
+  return session_terminate_session(session, session->last_proc_stream_id,
+                                   error_code, NULL);
+}
+
+int nghttp2_session_terminate_session2(nghttp2_session *session,
+                                       int32_t last_stream_id,
+                                       uint32_t error_code) {
+  return session_terminate_session(session, last_stream_id, error_code, NULL);
+}
+
+int nghttp2_session_terminate_session_with_reason(nghttp2_session *session,
+                                                  uint32_t error_code,
+                                                  const char *reason) {
+  return session_terminate_session(session, session->last_proc_stream_id,
+                                   error_code, reason);
+}
+
+int nghttp2_session_is_my_stream_id(nghttp2_session *session,
+                                    int32_t stream_id) {
+  int rem;
+  if (stream_id == 0) {
+    return 0;
+  }
+  rem = stream_id & 0x1;
+  if (session->server) {
+    return rem == 0;
+  }
+  return rem == 1;
+}
+
+nghttp2_stream *nghttp2_session_get_stream(nghttp2_session *session,
+                                           int32_t stream_id) {
+  nghttp2_stream *stream;
+
+  stream = (nghttp2_stream *)nghttp2_map_find(&session->streams, stream_id);
+
+  if (stream == NULL || (stream->flags & NGHTTP2_STREAM_FLAG_CLOSED) ||
+      stream->state == NGHTTP2_STREAM_IDLE) {
+    return NULL;
+  }
+
+  return stream;
+}
+
+nghttp2_stream *nghttp2_session_get_stream_raw(nghttp2_session *session,
+                                               int32_t stream_id) {
+  return (nghttp2_stream *)nghttp2_map_find(&session->streams, stream_id);
+}
+
+static void session_inbound_frame_reset(nghttp2_session *session) {
+  nghttp2_inbound_frame *iframe = &session->iframe;
+  nghttp2_mem *mem = &session->mem;
+  /* A bit risky code, since if this function is called from
+     nghttp2_session_new(), we rely on the fact that
+     iframe->frame.hd.type is 0, so that no free is performed. */
+  switch (iframe->frame.hd.type) {
+  case NGHTTP2_DATA:
+    break;
+  case NGHTTP2_HEADERS:
+    nghttp2_frame_headers_free(&iframe->frame.headers, mem);
+    break;
+  case NGHTTP2_PRIORITY:
+    nghttp2_frame_priority_free(&iframe->frame.priority);
+    break;
+  case NGHTTP2_RST_STREAM:
+    nghttp2_frame_rst_stream_free(&iframe->frame.rst_stream);
+    break;
+  case NGHTTP2_SETTINGS:
+    nghttp2_frame_settings_free(&iframe->frame.settings, mem);
+
+    nghttp2_mem_free(mem, iframe->iv);
+
+    iframe->iv = NULL;
+    iframe->niv = 0;
+    iframe->max_niv = 0;
+
+    break;
+  case NGHTTP2_PUSH_PROMISE:
+    nghttp2_frame_push_promise_free(&iframe->frame.push_promise, mem);
+    break;
+  case NGHTTP2_PING:
+    nghttp2_frame_ping_free(&iframe->frame.ping);
+    break;
+  case NGHTTP2_GOAWAY:
+    nghttp2_frame_goaway_free(&iframe->frame.goaway, mem);
+    break;
+  case NGHTTP2_WINDOW_UPDATE:
+    nghttp2_frame_window_update_free(&iframe->frame.window_update);
+    break;
+  default:
+    /* extension frame */
+    if (check_ext_type_set(session->user_recv_ext_types,
+                           iframe->frame.hd.type)) {
+      nghttp2_frame_extension_free(&iframe->frame.ext);
+    } else {
+      switch (iframe->frame.hd.type) {
+      case NGHTTP2_ALTSVC:
+        if ((session->builtin_recv_ext_types & NGHTTP2_TYPEMASK_ALTSVC) == 0) {
+          break;
+        }
+        nghttp2_frame_altsvc_free(&iframe->frame.ext, mem);
+        break;
+      case NGHTTP2_ORIGIN:
+        if ((session->builtin_recv_ext_types & NGHTTP2_TYPEMASK_ORIGIN) == 0) {
+          break;
+        }
+        nghttp2_frame_origin_free(&iframe->frame.ext, mem);
+        break;
+      }
+    }
+
+    break;
+  }
+
+  memset(&iframe->frame, 0, sizeof(nghttp2_frame));
+  memset(&iframe->ext_frame_payload, 0, sizeof(nghttp2_ext_frame_payload));
+
+  iframe->state = NGHTTP2_IB_READ_HEAD;
+
+  nghttp2_buf_wrap_init(&iframe->sbuf, iframe->raw_sbuf,
+                        sizeof(iframe->raw_sbuf));
+  iframe->sbuf.mark += NGHTTP2_FRAME_HDLEN;
+
+  nghttp2_buf_free(&iframe->lbuf, mem);
+  nghttp2_buf_wrap_init(&iframe->lbuf, NULL, 0);
+
+  iframe->raw_lbuf = NULL;
+
+  iframe->payloadleft = 0;
+  iframe->padlen = 0;
+}
+
+static void init_settings(nghttp2_settings_storage *settings) {
+  settings->header_table_size = NGHTTP2_HD_DEFAULT_MAX_BUFFER_SIZE;
+  settings->enable_push = 1;
+  settings->max_concurrent_streams = NGHTTP2_DEFAULT_MAX_CONCURRENT_STREAMS;
+  settings->initial_window_size = NGHTTP2_INITIAL_WINDOW_SIZE;
+  settings->max_frame_size = NGHTTP2_MAX_FRAME_SIZE_MIN;
+  settings->max_header_list_size = UINT32_MAX;
+}
+
+static void active_outbound_item_reset(nghttp2_active_outbound_item *aob,
+                                       nghttp2_mem *mem) {
+  DEBUGF("send: reset nghttp2_active_outbound_item\n");
+  DEBUGF("send: aob->item = %p\n", aob->item);
+  nghttp2_outbound_item_free(aob->item, mem);
+  nghttp2_mem_free(mem, aob->item);
+  aob->item = NULL;
+  nghttp2_bufs_reset(&aob->framebufs);
+  aob->state = NGHTTP2_OB_POP_ITEM;
+}
+
+int nghttp2_enable_strict_preface = 1;
+
+static int session_new(nghttp2_session **session_ptr,
+                       const nghttp2_session_callbacks *callbacks,
+                       void *user_data, int server,
+                       const nghttp2_option *option, nghttp2_mem *mem) {
+  int rv;
+  size_t nbuffer;
+  size_t max_deflate_dynamic_table_size =
+      NGHTTP2_HD_DEFAULT_MAX_DEFLATE_BUFFER_SIZE;
+
+  if (mem == NULL) {
+    mem = nghttp2_mem_default();
+  }
+
+  *session_ptr = nghttp2_mem_calloc(mem, 1, sizeof(nghttp2_session));
+  if (*session_ptr == NULL) {
+    rv = NGHTTP2_ERR_NOMEM;
+    goto fail_session;
+  }
+
+  (*session_ptr)->mem = *mem;
+  mem = &(*session_ptr)->mem;
+
+  /* next_stream_id is initialized in either
+     nghttp2_session_client_new2 or nghttp2_session_server_new2 */
+
+  nghttp2_stream_init(&(*session_ptr)->root, 0, NGHTTP2_STREAM_FLAG_NONE,
+                      NGHTTP2_STREAM_IDLE, NGHTTP2_DEFAULT_WEIGHT, 0, 0, NULL,
+                      mem);
+
+  (*session_ptr)->remote_window_size = NGHTTP2_INITIAL_CONNECTION_WINDOW_SIZE;
+  (*session_ptr)->recv_window_size = 0;
+  (*session_ptr)->consumed_size = 0;
+  (*session_ptr)->recv_reduction = 0;
+  (*session_ptr)->local_window_size = NGHTTP2_INITIAL_CONNECTION_WINDOW_SIZE;
+
+  (*session_ptr)->goaway_flags = NGHTTP2_GOAWAY_NONE;
+  (*session_ptr)->local_last_stream_id = (1u << 31) - 1;
+  (*session_ptr)->remote_last_stream_id = (1u << 31) - 1;
+
+  (*session_ptr)->pending_local_max_concurrent_stream =
+      NGHTTP2_DEFAULT_MAX_CONCURRENT_STREAMS;
+  (*session_ptr)->pending_enable_push = 1;
+
+  if (server) {
+    (*session_ptr)->server = 1;
+  }
+
+  init_settings(&(*session_ptr)->remote_settings);
+  init_settings(&(*session_ptr)->local_settings);
+
+  (*session_ptr)->max_incoming_reserved_streams =
+      NGHTTP2_MAX_INCOMING_RESERVED_STREAMS;
+
+  /* Limit max outgoing concurrent streams to sensible value */
+  (*session_ptr)->remote_settings.max_concurrent_streams = 100;
+
+  (*session_ptr)->max_send_header_block_length = NGHTTP2_MAX_HEADERSLEN;
+  (*session_ptr)->max_outbound_ack = NGHTTP2_DEFAULT_MAX_OBQ_FLOOD_ITEM;
+
+  if (option) {
+    if ((option->opt_set_mask & NGHTTP2_OPT_NO_AUTO_WINDOW_UPDATE) &&
+        option->no_auto_window_update) {
+
+      (*session_ptr)->opt_flags |= NGHTTP2_OPTMASK_NO_AUTO_WINDOW_UPDATE;
+    }
+
+    if (option->opt_set_mask & NGHTTP2_OPT_PEER_MAX_CONCURRENT_STREAMS) {
+
+      (*session_ptr)->remote_settings.max_concurrent_streams =
+          option->peer_max_concurrent_streams;
+    }
+
+    if (option->opt_set_mask & NGHTTP2_OPT_MAX_RESERVED_REMOTE_STREAMS) {
+
+      (*session_ptr)->max_incoming_reserved_streams =
+          option->max_reserved_remote_streams;
+    }
+
+    if ((option->opt_set_mask & NGHTTP2_OPT_NO_RECV_CLIENT_MAGIC) &&
+        option->no_recv_client_magic) {
+
+      (*session_ptr)->opt_flags |= NGHTTP2_OPTMASK_NO_RECV_CLIENT_MAGIC;
+    }
+
+    if ((option->opt_set_mask & NGHTTP2_OPT_NO_HTTP_MESSAGING) &&
+        option->no_http_messaging) {
+
+      (*session_ptr)->opt_flags |= NGHTTP2_OPTMASK_NO_HTTP_MESSAGING;
+    }
+
+    if (option->opt_set_mask & NGHTTP2_OPT_USER_RECV_EXT_TYPES) {
+      memcpy((*session_ptr)->user_recv_ext_types, option->user_recv_ext_types,
+             sizeof((*session_ptr)->user_recv_ext_types));
+    }
+
+    if (option->opt_set_mask & NGHTTP2_OPT_BUILTIN_RECV_EXT_TYPES) {
+      (*session_ptr)->builtin_recv_ext_types = option->builtin_recv_ext_types;
+    }
+
+    if ((option->opt_set_mask & NGHTTP2_OPT_NO_AUTO_PING_ACK) &&
+        option->no_auto_ping_ack) {
+      (*session_ptr)->opt_flags |= NGHTTP2_OPTMASK_NO_AUTO_PING_ACK;
+    }
+
+    if (option->opt_set_mask & NGHTTP2_OPT_MAX_SEND_HEADER_BLOCK_LENGTH) {
+      (*session_ptr)->max_send_header_block_length =
+          option->max_send_header_block_length;
+    }
+
+    if (option->opt_set_mask & NGHTTP2_OPT_MAX_DEFLATE_DYNAMIC_TABLE_SIZE) {
+      max_deflate_dynamic_table_size = option->max_deflate_dynamic_table_size;
+    }
+
+    if ((option->opt_set_mask & NGHTTP2_OPT_NO_CLOSED_STREAMS) &&
+        option->no_closed_streams) {
+      (*session_ptr)->opt_flags |= NGHTTP2_OPTMASK_NO_CLOSED_STREAMS;
+    }
+
+    if (option->opt_set_mask & NGHTTP2_OPT_MAX_OUTBOUND_ACK) {
+      (*session_ptr)->max_outbound_ack = option->max_outbound_ack;
+    }
+  }
+
+  rv = nghttp2_hd_deflate_init2(&(*session_ptr)->hd_deflater,
+                                max_deflate_dynamic_table_size, mem);
+  if (rv != 0) {
+    goto fail_hd_deflater;
+  }
+  rv = nghttp2_hd_inflate_init(&(*session_ptr)->hd_inflater, mem);
+  if (rv != 0) {
+    goto fail_hd_inflater;
+  }
+  rv = nghttp2_map_init(&(*session_ptr)->streams, mem);
+  if (rv != 0) {
+    goto fail_map;
+  }
+
+  nbuffer = ((*session_ptr)->max_send_header_block_length +
+             NGHTTP2_FRAMEBUF_CHUNKLEN - 1) /
+            NGHTTP2_FRAMEBUF_CHUNKLEN;
+
+  if (nbuffer == 0) {
+    nbuffer = 1;
+  }
+
+  /* 1 for Pad Field. */
+  rv = nghttp2_bufs_init3(&(*session_ptr)->aob.framebufs,
+                          NGHTTP2_FRAMEBUF_CHUNKLEN, nbuffer, 1,
+                          NGHTTP2_FRAME_HDLEN + 1, mem);
+  if (rv != 0) {
+    goto fail_aob_framebuf;
+  }
+
+  active_outbound_item_reset(&(*session_ptr)->aob, mem);
+
+  (*session_ptr)->callbacks = *callbacks;
+  (*session_ptr)->user_data = user_data;
+
+  session_inbound_frame_reset(*session_ptr);
+
+  if (nghttp2_enable_strict_preface) {
+    nghttp2_inbound_frame *iframe = &(*session_ptr)->iframe;
+
+    if (server && ((*session_ptr)->opt_flags &
+                   NGHTTP2_OPTMASK_NO_RECV_CLIENT_MAGIC) == 0) {
+      iframe->state = NGHTTP2_IB_READ_CLIENT_MAGIC;
+      iframe->payloadleft = NGHTTP2_CLIENT_MAGIC_LEN;
+    } else {
+      iframe->state = NGHTTP2_IB_READ_FIRST_SETTINGS;
+    }
+
+    if (!server) {
+      (*session_ptr)->aob.state = NGHTTP2_OB_SEND_CLIENT_MAGIC;
+      nghttp2_bufs_add(&(*session_ptr)->aob.framebufs, NGHTTP2_CLIENT_MAGIC,
+                       NGHTTP2_CLIENT_MAGIC_LEN);
+    }
+  }
+
+  return 0;
+
+fail_aob_framebuf:
+  nghttp2_map_free(&(*session_ptr)->streams);
+fail_map:
+  nghttp2_hd_inflate_free(&(*session_ptr)->hd_inflater);
+fail_hd_inflater:
+  nghttp2_hd_deflate_free(&(*session_ptr)->hd_deflater);
+fail_hd_deflater:
+  nghttp2_mem_free(mem, *session_ptr);
+fail_session:
+  return rv;
+}
+
+int nghttp2_session_client_new(nghttp2_session **session_ptr,
+                               const nghttp2_session_callbacks *callbacks,
+                               void *user_data) {
+  return nghttp2_session_client_new3(session_ptr, callbacks, user_data, NULL,
+                                     NULL);
+}
+
+int nghttp2_session_client_new2(nghttp2_session **session_ptr,
+                                const nghttp2_session_callbacks *callbacks,
+                                void *user_data, const nghttp2_option *option) {
+  return nghttp2_session_client_new3(session_ptr, callbacks, user_data, option,
+                                     NULL);
+}
+
+int nghttp2_session_client_new3(nghttp2_session **session_ptr,
+                                const nghttp2_session_callbacks *callbacks,
+                                void *user_data, const nghttp2_option *option,
+                                nghttp2_mem *mem) {
+  int rv;
+  nghttp2_session *session;
+
+  rv = session_new(&session, callbacks, user_data, 0, option, mem);
+
+  if (rv != 0) {
+    return rv;
+  }
+  /* IDs for use in client */
+  session->next_stream_id = 1;
+
+  *session_ptr = session;
+
+  return 0;
+}
+
+int nghttp2_session_server_new(nghttp2_session **session_ptr,
+                               const nghttp2_session_callbacks *callbacks,
+                               void *user_data) {
+  return nghttp2_session_server_new3(session_ptr, callbacks, user_data, NULL,
+                                     NULL);
+}
+
+int nghttp2_session_server_new2(nghttp2_session **session_ptr,
+                                const nghttp2_session_callbacks *callbacks,
+                                void *user_data, const nghttp2_option *option) {
+  return nghttp2_session_server_new3(session_ptr, callbacks, user_data, option,
+                                     NULL);
+}
+
+int nghttp2_session_server_new3(nghttp2_session **session_ptr,
+                                const nghttp2_session_callbacks *callbacks,
+                                void *user_data, const nghttp2_option *option,
+                                nghttp2_mem *mem) {
+  int rv;
+  nghttp2_session *session;
+
+  rv = session_new(&session, callbacks, user_data, 1, option, mem);
+
+  if (rv != 0) {
+    return rv;
+  }
+  /* IDs for use in client */
+  session->next_stream_id = 2;
+
+  *session_ptr = session;
+
+  return 0;
+}
+
+static int free_streams(nghttp2_map_entry *entry, void *ptr) {
+  nghttp2_session *session;
+  nghttp2_stream *stream;
+  nghttp2_outbound_item *item;
+  nghttp2_mem *mem;
+
+  session = (nghttp2_session *)ptr;
+  mem = &session->mem;
+  stream = (nghttp2_stream *)entry;
+  item = stream->item;
+
+  if (item && !item->queued && item != session->aob.item) {
+    nghttp2_outbound_item_free(item, mem);
+    nghttp2_mem_free(mem, item);
+  }
+
+  nghttp2_stream_free(stream);
+  nghttp2_mem_free(mem, stream);
+
+  return 0;
+}
+
+static void ob_q_free(nghttp2_outbound_queue *q, nghttp2_mem *mem) {
+  nghttp2_outbound_item *item, *next;
+  for (item = q->head; item;) {
+    next = item->qnext;
+    nghttp2_outbound_item_free(item, mem);
+    nghttp2_mem_free(mem, item);
+    item = next;
+  }
+}
+
+static int inflight_settings_new(nghttp2_inflight_settings **settings_ptr,
+                                 const nghttp2_settings_entry *iv, size_t niv,
+                                 nghttp2_mem *mem) {
+  *settings_ptr = nghttp2_mem_malloc(mem, sizeof(nghttp2_inflight_settings));
+  if (!*settings_ptr) {
+    return NGHTTP2_ERR_NOMEM;
+  }
+
+  if (niv > 0) {
+    (*settings_ptr)->iv = nghttp2_frame_iv_copy(iv, niv, mem);
+    if (!(*settings_ptr)->iv) {
+      nghttp2_mem_free(mem, *settings_ptr);
+      return NGHTTP2_ERR_NOMEM;
+    }
+  } else {
+    (*settings_ptr)->iv = NULL;
+  }
+
+  (*settings_ptr)->niv = niv;
+  (*settings_ptr)->next = NULL;
+
+  return 0;
+}
+
+static void inflight_settings_del(nghttp2_inflight_settings *settings,
+                                  nghttp2_mem *mem) {
+  if (!settings) {
+    return;
+  }
+
+  nghttp2_mem_free(mem, settings->iv);
+  nghttp2_mem_free(mem, settings);
+}
+
+void nghttp2_session_del(nghttp2_session *session) {
+  nghttp2_mem *mem;
+  nghttp2_inflight_settings *settings;
+
+  if (session == NULL) {
+    return;
+  }
+
+  mem = &session->mem;
+
+  for (settings = session->inflight_settings_head; settings;) {
+    nghttp2_inflight_settings *next = settings->next;
+    inflight_settings_del(settings, mem);
+    settings = next;
+  }
+
+  nghttp2_stream_free(&session->root);
+
+  /* Have to free streams first, so that we can check
+     stream->item->queued */
+  nghttp2_map_each_free(&session->streams, free_streams, session);
+  nghttp2_map_free(&session->streams);
+
+  ob_q_free(&session->ob_urgent, mem);
+  ob_q_free(&session->ob_reg, mem);
+  ob_q_free(&session->ob_syn, mem);
+
+  active_outbound_item_reset(&session->aob, mem);
+  session_inbound_frame_reset(session);
+  nghttp2_hd_deflate_free(&session->hd_deflater);
+  nghttp2_hd_inflate_free(&session->hd_inflater);
+  nghttp2_bufs_free(&session->aob.framebufs);
+  nghttp2_mem_free(mem, session);
+}
+
+int nghttp2_session_reprioritize_stream(
+    nghttp2_session *session, nghttp2_stream *stream,
+    const nghttp2_priority_spec *pri_spec_in) {
+  int rv;
+  nghttp2_stream *dep_stream = NULL;
+  nghttp2_priority_spec pri_spec_default;
+  const nghttp2_priority_spec *pri_spec = pri_spec_in;
+
+  assert(pri_spec->stream_id != stream->stream_id);
+
+  if (!nghttp2_stream_in_dep_tree(stream)) {
+    return 0;
+  }
+
+  if (pri_spec->stream_id != 0) {
+    dep_stream = nghttp2_session_get_stream_raw(session, pri_spec->stream_id);
+
+    if (!dep_stream &&
+        session_detect_idle_stream(session, pri_spec->stream_id)) {
+
+      nghttp2_priority_spec_default_init(&pri_spec_default);
+
+      dep_stream = nghttp2_session_open_stream(
+          session, pri_spec->stream_id, NGHTTP2_FLAG_NONE, &pri_spec_default,
+          NGHTTP2_STREAM_IDLE, NULL);
+
+      if (dep_stream == NULL) {
+        return NGHTTP2_ERR_NOMEM;
+      }
+    } else if (!dep_stream || !nghttp2_stream_in_dep_tree(dep_stream)) {
+      nghttp2_priority_spec_default_init(&pri_spec_default);
+      pri_spec = &pri_spec_default;
+    }
+  }
+
+  if (pri_spec->stream_id == 0) {
+    dep_stream = &session->root;
+  } else if (nghttp2_stream_dep_find_ancestor(dep_stream, stream)) {
+    DEBUGF("stream: cycle detected, dep_stream(%p)=%d stream(%p)=%d\n",
+           dep_stream, dep_stream->stream_id, stream, stream->stream_id);
+
+    nghttp2_stream_dep_remove_subtree(dep_stream);
+    rv = nghttp2_stream_dep_add_subtree(stream->dep_prev, dep_stream);
+    if (rv != 0) {
+      return rv;
+    }
+  }
+
+  assert(dep_stream);
+
+  if (dep_stream == stream->dep_prev && !pri_spec->exclusive) {
+    /* This is minor optimization when just weight is changed. */
+    nghttp2_stream_change_weight(stream, pri_spec->weight);
+
+    return 0;
+  }
+
+  nghttp2_stream_dep_remove_subtree(stream);
+
+  /* We have to update weight after removing stream from tree */
+  stream->weight = pri_spec->weight;
+
+  if (pri_spec->exclusive) {
+    rv = nghttp2_stream_dep_insert_subtree(dep_stream, stream);
+  } else {
+    rv = nghttp2_stream_dep_add_subtree(dep_stream, stream);
+  }
+
+  if (rv != 0) {
+    return rv;
+  }
+
+  return 0;
+}
+
+int nghttp2_session_add_item(nghttp2_session *session,
+                             nghttp2_outbound_item *item) {
+  /* TODO Return error if stream is not found for the frame requiring
+     stream presence. */
+  int rv = 0;
+  nghttp2_stream *stream;
+  nghttp2_frame *frame;
+
+  frame = &item->frame;
+  stream = nghttp2_session_get_stream(session, frame->hd.stream_id);
+
+  switch (frame->hd.type) {
+  case NGHTTP2_DATA:
+    if (!stream) {
+      return NGHTTP2_ERR_STREAM_CLOSED;
+    }
+
+    if (stream->item) {
+      return NGHTTP2_ERR_DATA_EXIST;
+    }
+
+    rv = nghttp2_stream_attach_item(stream, item);
+
+    if (rv != 0) {
+      return rv;
+    }
+
+    return 0;
+  case NGHTTP2_HEADERS:
+    /* We push request HEADERS and push response HEADERS to
+       dedicated queue because their transmission is affected by
+       SETTINGS_MAX_CONCURRENT_STREAMS */
+    /* TODO If 2 HEADERS are submitted for reserved stream, then
+       both of them are queued into ob_syn, which is not
+       desirable. */
+    if (frame->headers.cat == NGHTTP2_HCAT_REQUEST ||
+        (stream && stream->state == NGHTTP2_STREAM_RESERVED)) {
+      nghttp2_outbound_queue_push(&session->ob_syn, item);
+      item->queued = 1;
+      return 0;
+      ;
+    }
+
+    nghttp2_outbound_queue_push(&session->ob_reg, item);
+    item->queued = 1;
+    return 0;
+  case NGHTTP2_SETTINGS:
+  case NGHTTP2_PING:
+    nghttp2_outbound_queue_push(&session->ob_urgent, item);
+    item->queued = 1;
+    return 0;
+  case NGHTTP2_RST_STREAM:
+    if (stream) {
+      stream->state = NGHTTP2_STREAM_CLOSING;
+    }
+    nghttp2_outbound_queue_push(&session->ob_reg, item);
+    item->queued = 1;
+    return 0;
+  case NGHTTP2_PUSH_PROMISE: {
+    nghttp2_headers_aux_data *aux_data;
+    nghttp2_priority_spec pri_spec;
+
+    aux_data = &item->aux_data.headers;
+
+    if (!stream) {
+      return NGHTTP2_ERR_STREAM_CLOSED;
+    }
+
+    nghttp2_priority_spec_init(&pri_spec, stream->stream_id,
+                               NGHTTP2_DEFAULT_WEIGHT, 0);
+
+    if (!nghttp2_session_open_stream(
+            session, frame->push_promise.promised_stream_id,
+            NGHTTP2_STREAM_FLAG_NONE, &pri_spec, NGHTTP2_STREAM_RESERVED,
+            aux_data->stream_user_data)) {
+      return NGHTTP2_ERR_NOMEM;
+    }
+
+    /* We don't have to call nghttp2_session_adjust_closed_stream()
+       here, since stream->stream_id is local stream_id, and it does
+       not affect closed stream count. */
+
+    nghttp2_outbound_queue_push(&session->ob_reg, item);
+    item->queued = 1;
+
+    return 0;
+  }
+  case NGHTTP2_WINDOW_UPDATE:
+    if (stream) {
+      stream->window_update_queued = 1;
+    } else if (frame->hd.stream_id == 0) {
+      session->window_update_queued = 1;
+    }
+    nghttp2_outbound_queue_push(&session->ob_reg, item);
+    item->queued = 1;
+    return 0;
+  default:
+    nghttp2_outbound_queue_push(&session->ob_reg, item);
+    item->queued = 1;
+    return 0;
+  }
+}
+
+int nghttp2_session_add_rst_stream(nghttp2_session *session, int32_t stream_id,
+                                   uint32_t error_code) {
+  int rv;
+  nghttp2_outbound_item *item;
+  nghttp2_frame *frame;
+  nghttp2_stream *stream;
+  nghttp2_mem *mem;
+
+  mem = &session->mem;
+  stream = nghttp2_session_get_stream(session, stream_id);
+  if (stream && stream->state == NGHTTP2_STREAM_CLOSING) {
+    return 0;
+  }
+
+  /* Cancel pending request HEADERS in ob_syn if this RST_STREAM
+     refers to that stream. */
+  if (!session->server && nghttp2_session_is_my_stream_id(session, stream_id) &&
+      nghttp2_outbound_queue_top(&session->ob_syn)) {
+    nghttp2_headers_aux_data *aux_data;
+    nghttp2_frame *headers_frame;
+
+    headers_frame = &nghttp2_outbound_queue_top(&session->ob_syn)->frame;
+    assert(headers_frame->hd.type == NGHTTP2_HEADERS);
+
+    if (headers_frame->hd.stream_id <= stream_id &&
+        (uint32_t)stream_id < session->next_stream_id) {
+
+      for (item = session->ob_syn.head; item; item = item->qnext) {
+        aux_data = &item->aux_data.headers;
+
+        if (item->frame.hd.stream_id < stream_id) {
+          continue;
+        }
+
+        /* stream_id in ob_syn queue must be strictly increasing.  If
+           we found larger ID, then we can break here. */
+        if (item->frame.hd.stream_id > stream_id || aux_data->canceled) {
+          break;
+        }
+
+        aux_data->error_code = error_code;
+        aux_data->canceled = 1;
+
+        return 0;
+      }
+    }
+  }
+
+  item = nghttp2_mem_malloc(mem, sizeof(nghttp2_outbound_item));
+  if (item == NULL) {
+    return NGHTTP2_ERR_NOMEM;
+  }
+
+  nghttp2_outbound_item_init(item);
+
+  frame = &item->frame;
+
+  nghttp2_frame_rst_stream_init(&frame->rst_stream, stream_id, error_code);
+  rv = nghttp2_session_add_item(session, item);
+  if (rv != 0) {
+    nghttp2_frame_rst_stream_free(&frame->rst_stream);
+    nghttp2_mem_free(mem, item);
+    return rv;
+  }
+  return 0;
+}
+
+nghttp2_stream *nghttp2_session_open_stream(nghttp2_session *session,
+                                            int32_t stream_id, uint8_t flags,
+                                            nghttp2_priority_spec *pri_spec_in,
+                                            nghttp2_stream_state initial_state,
+                                            void *stream_user_data) {
+  int rv;
+  nghttp2_stream *stream;
+  nghttp2_stream *dep_stream = NULL;
+  int stream_alloc = 0;
+  nghttp2_priority_spec pri_spec_default;
+  nghttp2_priority_spec *pri_spec = pri_spec_in;
+  nghttp2_mem *mem;
+
+  mem = &session->mem;
+  stream = nghttp2_session_get_stream_raw(session, stream_id);
+
+  if (stream) {
+    assert(stream->state == NGHTTP2_STREAM_IDLE);
+    assert(nghttp2_stream_in_dep_tree(stream));
+    nghttp2_session_detach_idle_stream(session, stream);
+    rv = nghttp2_stream_dep_remove(stream);
+    if (rv != 0) {
+      return NULL;
+    }
+  } else {
+    stream = nghttp2_mem_malloc(mem, sizeof(nghttp2_stream));
+    if (stream == NULL) {
+      return NULL;
+    }
+
+    stream_alloc = 1;
+  }
+
+  if (pri_spec->stream_id != 0) {
+    dep_stream = nghttp2_session_get_stream_raw(session, pri_spec->stream_id);
+
+    if (!dep_stream &&
+        session_detect_idle_stream(session, pri_spec->stream_id)) {
+      /* Depends on idle stream, which does not exist in memory.
+         Assign default priority for it. */
+      nghttp2_priority_spec_default_init(&pri_spec_default);
+
+      dep_stream = nghttp2_session_open_stream(
+          session, pri_spec->stream_id, NGHTTP2_FLAG_NONE, &pri_spec_default,
+          NGHTTP2_STREAM_IDLE, NULL);
+
+      if (dep_stream == NULL) {
+        if (stream_alloc) {
+          nghttp2_mem_free(mem, stream);
+        }
+
+        return NULL;
+      }
+    } else if (!dep_stream || !nghttp2_stream_in_dep_tree(dep_stream)) {
+      /* If dep_stream is not part of dependency tree, stream will get
+         default priority.  This handles the case when
+         pri_spec->stream_id == stream_id.  This happens because we
+         don't check pri_spec->stream_id against new stream ID in
+         nghttp2_submit_request.  This also handles the case when idle
+         stream created by PRIORITY frame was opened.  Somehow we
+         first remove the idle stream from dependency tree.  This is
+         done to simplify code base, but ideally we should retain old
+         dependency.  But I'm not sure this adds values. */
+      nghttp2_priority_spec_default_init(&pri_spec_default);
+      pri_spec = &pri_spec_default;
+    }
+  }
+
+  if (initial_state == NGHTTP2_STREAM_RESERVED) {
+    flags |= NGHTTP2_STREAM_FLAG_PUSH;
+  }
+
+  if (stream_alloc) {
+    nghttp2_stream_init(stream, stream_id, flags, initial_state,
+                        pri_spec->weight,
+                        (int32_t)session->remote_settings.initial_window_size,
+                        (int32_t)session->local_settings.initial_window_size,
+                        stream_user_data, mem);
+
+    rv = nghttp2_map_insert(&session->streams, &stream->map_entry);
+    if (rv != 0) {
+      nghttp2_stream_free(stream);
+      nghttp2_mem_free(mem, stream);
+      return NULL;
+    }
+  } else {
+    stream->flags = flags;
+    stream->state = initial_state;
+    stream->weight = pri_spec->weight;
+    stream->stream_user_data = stream_user_data;
+  }
+
+  switch (initial_state) {
+  case NGHTTP2_STREAM_RESERVED:
+    if (nghttp2_session_is_my_stream_id(session, stream_id)) {
+      /* reserved (local) */
+      nghttp2_stream_shutdown(stream, NGHTTP2_SHUT_RD);
+    } else {
+      /* reserved (remote) */
+      nghttp2_stream_shutdown(stream, NGHTTP2_SHUT_WR);
+      ++session->num_incoming_reserved_streams;
+    }
+    /* Reserved stream does not count in the concurrent streams
+       limit. That is one of the DOS vector. */
+    break;
+  case NGHTTP2_STREAM_IDLE:
+    /* Idle stream does not count toward the concurrent streams limit.
+       This is used as anchor node in dependency tree. */
+    nghttp2_session_keep_idle_stream(session, stream);
+    break;
+  default:
+    if (nghttp2_session_is_my_stream_id(session, stream_id)) {
+      ++session->num_outgoing_streams;
+    } else {
+      ++session->num_incoming_streams;
+    }
+  }
+
+  if (pri_spec->stream_id == 0) {
+    dep_stream = &session->root;
+  }
+
+  assert(dep_stream);
+
+  if (pri_spec->exclusive) {
+    rv = nghttp2_stream_dep_insert(dep_stream, stream);
+    if (rv != 0) {
+      return NULL;
+    }
+  } else {
+    nghttp2_stream_dep_add(dep_stream, stream);
+  }
+
+  return stream;
+}
+
+int nghttp2_session_close_stream(nghttp2_session *session, int32_t stream_id,
+                                 uint32_t error_code) {
+  int rv;
+  nghttp2_stream *stream;
+  nghttp2_mem *mem;
+  int is_my_stream_id;
+
+  mem = &session->mem;
+  stream = nghttp2_session_get_stream(session, stream_id);
+
+  if (!stream) {
+    return NGHTTP2_ERR_INVALID_ARGUMENT;
+  }
+
+  DEBUGF("stream: stream(%p)=%d close\n", stream, stream->stream_id);
+
+  if (stream->item) {
+    nghttp2_outbound_item *item;
+
+    item = stream->item;
+
+    rv = nghttp2_stream_detach_item(stream);
+
+    if (rv != 0) {
+      return rv;
+    }
+
+    /* If item is queued, it will be deleted when it is popped
+       (nghttp2_session_prep_frame() will fail).  If session->aob.item
+       points to this item, let active_outbound_item_reset()
+       free the item. */
+    if (!item->queued && item != session->aob.item) {
+      nghttp2_outbound_item_free(item, mem);
+      nghttp2_mem_free(mem, item);
+    }
+  }
+
+  /* We call on_stream_close_callback even if stream->state is
+     NGHTTP2_STREAM_INITIAL. This will happen while sending request
+     HEADERS, a local endpoint receives RST_STREAM for that stream. It
+     may be PROTOCOL_ERROR, but without notifying stream closure will
+     hang the stream in a local endpoint.
+  */
+
+  if (session->callbacks.on_stream_close_callback) {
+    if (session->callbacks.on_stream_close_callback(
+            session, stream_id, error_code, session->user_data) != 0) {
+
+      return NGHTTP2_ERR_CALLBACK_FAILURE;
+    }
+  }
+
+  is_my_stream_id = nghttp2_session_is_my_stream_id(session, stream_id);
+
+  /* pushed streams which is not opened yet is not counted toward max
+     concurrent limits */
+  if ((stream->flags & NGHTTP2_STREAM_FLAG_PUSH)) {
+    if (!is_my_stream_id) {
+      --session->num_incoming_reserved_streams;
+    }
+  } else {
+    if (is_my_stream_id) {
+      --session->num_outgoing_streams;
+    } else {
+      --session->num_incoming_streams;
+    }
+  }
+
+  /* Closes both directions just in case they are not closed yet */
+  stream->flags |= NGHTTP2_STREAM_FLAG_CLOSED;
+
+  if ((session->opt_flags & NGHTTP2_OPTMASK_NO_CLOSED_STREAMS) == 0 &&
+      session->server && !is_my_stream_id &&
+      nghttp2_stream_in_dep_tree(stream)) {
+    /* On server side, retain stream at most MAX_CONCURRENT_STREAMS
+       combined with the current active incoming streams to make
+       dependency tree work better. */
+    nghttp2_session_keep_closed_stream(session, stream);
+  } else {
+    rv = nghttp2_session_destroy_stream(session, stream);
+    if (rv != 0) {
+      return rv;
+    }
+  }
+
+  return 0;
+}
+
+int nghttp2_session_destroy_stream(nghttp2_session *session,
+                                   nghttp2_stream *stream) {
+  nghttp2_mem *mem;
+  int rv;
+
+  DEBUGF("stream: destroy closed stream(%p)=%d\n", stream, stream->stream_id);
+
+  mem = &session->mem;
+
+  if (nghttp2_stream_in_dep_tree(stream)) {
+    rv = nghttp2_stream_dep_remove(stream);
+    if (rv != 0) {
+      return rv;
+    }
+  }
+
+  nghttp2_map_remove(&session->streams, stream->stream_id);
+  nghttp2_stream_free(stream);
+  nghttp2_mem_free(mem, stream);
+
+  return 0;
+}
+
+void nghttp2_session_keep_closed_stream(nghttp2_session *session,
+                                        nghttp2_stream *stream) {
+  DEBUGF("stream: keep closed stream(%p)=%d, state=%d\n", stream,
+         stream->stream_id, stream->state);
+
+  if (session->closed_stream_tail) {
+    session->closed_stream_tail->closed_next = stream;
+    stream->closed_prev = session->closed_stream_tail;
+  } else {
+    session->closed_stream_head = stream;
+  }
+  session->closed_stream_tail = stream;
+
+  ++session->num_closed_streams;
+}
+
+void nghttp2_session_keep_idle_stream(nghttp2_session *session,
+                                      nghttp2_stream *stream) {
+  DEBUGF("stream: keep idle stream(%p)=%d, state=%d\n", stream,
+         stream->stream_id, stream->state);
+
+  if (session->idle_stream_tail) {
+    session->idle_stream_tail->closed_next = stream;
+    stream->closed_prev = session->idle_stream_tail;
+  } else {
+    session->idle_stream_head = stream;
+  }
+  session->idle_stream_tail = stream;
+
+  ++session->num_idle_streams;
+}
+
+void nghttp2_session_detach_idle_stream(nghttp2_session *session,
+                                        nghttp2_stream *stream) {
+  nghttp2_stream *prev_stream, *next_stream;
+
+  DEBUGF("stream: detach idle stream(%p)=%d, state=%d\n", stream,
+         stream->stream_id, stream->state);
+
+  prev_stream = stream->closed_prev;
+  next_stream = stream->closed_next;
+
+  if (prev_stream) {
+    prev_stream->closed_next = next_stream;
+  } else {
+    session->idle_stream_head = next_stream;
+  }
+
+  if (next_stream) {
+    next_stream->closed_prev = prev_stream;
+  } else {
+    session->idle_stream_tail = prev_stream;
+  }
+
+  stream->closed_prev = NULL;
+  stream->closed_next = NULL;
+
+  --session->num_idle_streams;
+}
+
+int nghttp2_session_adjust_closed_stream(nghttp2_session *session) {
+  size_t num_stream_max;
+  int rv;
+
+  if (session->local_settings.max_concurrent_streams ==
+      NGHTTP2_DEFAULT_MAX_CONCURRENT_STREAMS) {
+    num_stream_max = session->pending_local_max_concurrent_stream;
+  } else {
+    num_stream_max = session->local_settings.max_concurrent_streams;
+  }
+
+  DEBUGF("stream: adjusting kept closed streams num_closed_streams=%zu, "
+         "num_incoming_streams=%zu, max_concurrent_streams=%zu\n",
+         session->num_closed_streams, session->num_incoming_streams,
+         num_stream_max);
+
+  while (session->num_closed_streams > 0 &&
+         session->num_closed_streams + session->num_incoming_streams >
+             num_stream_max) {
+    nghttp2_stream *head_stream;
+    nghttp2_stream *next;
+
+    head_stream = session->closed_stream_head;
+
+    assert(head_stream);
+
+    next = head_stream->closed_next;
+
+    rv = nghttp2_session_destroy_stream(session, head_stream);
+    if (rv != 0) {
+      return rv;
+    }
+
+    /* head_stream is now freed */
+
+    session->closed_stream_head = next;
+
+    if (session->closed_stream_head) {
+      session->closed_stream_head->closed_prev = NULL;
+    } else {
+      session->closed_stream_tail = NULL;
+    }
+
+    --session->num_closed_streams;
+  }
+
+  return 0;
+}
+
+int nghttp2_session_adjust_idle_stream(nghttp2_session *session) {
+  size_t max;
+  int rv;
+
+  /* Make minimum number of idle streams 16, and maximum 100, which
+     are arbitrary chosen numbers. */
+  max = nghttp2_min(
+      100, nghttp2_max(
+               16, nghttp2_min(session->local_settings.max_concurrent_streams,
+                               session->pending_local_max_concurrent_stream)));
+
+  DEBUGF("stream: adjusting kept idle streams num_idle_streams=%zu, max=%zu\n",
+         session->num_idle_streams, max);
+
+  while (session->num_idle_streams > max) {
+    nghttp2_stream *head;
+    nghttp2_stream *next;
+
+    head = session->idle_stream_head;
+    assert(head);
+
+    next = head->closed_next;
+
+    rv = nghttp2_session_destroy_stream(session, head);
+    if (rv != 0) {
+      return rv;
+    }
+
+    /* head is now destroyed */
+
+    session->idle_stream_head = next;
+
+    if (session->idle_stream_head) {
+      session->idle_stream_head->closed_prev = NULL;
+    } else {
+      session->idle_stream_tail = NULL;
+    }
+
+    --session->num_idle_streams;
+  }
+
+  return 0;
+}
+
+/*
+ * Closes stream with stream ID |stream_id| if both transmission and
+ * reception of the stream were disallowed. The |error_code| indicates
+ * the reason of the closure.
+ *
+ * This function returns 0 if it succeeds, or one of the following
+ * negative error codes:
+ *
+ * NGHTTP2_ERR_INVALID_ARGUMENT
+ *   The stream is not found.
+ * NGHTTP2_ERR_CALLBACK_FAILURE
+ *   The callback function failed.
+ */
+int nghttp2_session_close_stream_if_shut_rdwr(nghttp2_session *session,
+                                              nghttp2_stream *stream) {
+  if ((stream->shut_flags & NGHTTP2_SHUT_RDWR) == NGHTTP2_SHUT_RDWR) {
+    return nghttp2_session_close_stream(session, stream->stream_id,
+                                        NGHTTP2_NO_ERROR);
+  }
+  return 0;
+}
+
+/*
+ * Returns nonzero if local endpoint allows reception of new stream
+ * from remote.
+ */
+static int session_allow_incoming_new_stream(nghttp2_session *session) {
+  return (session->goaway_flags &
+          (NGHTTP2_GOAWAY_TERM_ON_SEND | NGHTTP2_GOAWAY_SENT)) == 0;
+}
+
+/*
+ * This function returns nonzero if session is closing.
+ */
+static int session_is_closing(nghttp2_session *session) {
+  return (session->goaway_flags & NGHTTP2_GOAWAY_TERM_ON_SEND) != 0 ||
+         (nghttp2_session_want_read(session) == 0 &&
+          nghttp2_session_want_write(session) == 0);
+}
+
+/*
+ * Check that we can send a frame to the |stream|. This function
+ * returns 0 if we can send a frame to the |frame|, or one of the
+ * following negative error codes:
+ *
+ * NGHTTP2_ERR_STREAM_CLOSED
+ *   The stream is already closed.
+ * NGHTTP2_ERR_STREAM_SHUT_WR
+ *   The stream is half-closed for transmission.
+ * NGHTTP2_ERR_SESSION_CLOSING
+ *   This session is closing.
+ */
+static int session_predicate_for_stream_send(nghttp2_session *session,
+                                             nghttp2_stream *stream) {
+  if (stream == NULL) {
+    return NGHTTP2_ERR_STREAM_CLOSED;
+  }
+  if (session_is_closing(session)) {
+    return NGHTTP2_ERR_SESSION_CLOSING;
+  }
+  if (stream->shut_flags & NGHTTP2_SHUT_WR) {
+    return NGHTTP2_ERR_STREAM_SHUT_WR;
+  }
+  return 0;
+}
+
+int nghttp2_session_check_request_allowed(nghttp2_session *session) {
+  return !session->server && session->next_stream_id <= INT32_MAX &&
+         (session->goaway_flags & NGHTTP2_GOAWAY_RECV) == 0 &&
+         !session_is_closing(session);
+}
+
+/*
+ * This function checks request HEADERS frame, which opens stream, can
+ * be sent at this time.
+ *
+ * This function returns 0 if it succeeds, or one of the following
+ * negative error codes:
+ *
+ * NGHTTP2_ERR_START_STREAM_NOT_ALLOWED
+ *     New stream cannot be created because of GOAWAY: session is
+ *     going down or received last_stream_id is strictly less than
+ *     frame->hd.stream_id.
+ * NGHTTP2_ERR_STREAM_CLOSING
+ *     request HEADERS was canceled by RST_STREAM while it is in queue.
+ */
+static int session_predicate_request_headers_send(nghttp2_session *session,
+                                                  nghttp2_outbound_item *item) {
+  if (item->aux_data.headers.canceled) {
+    return NGHTTP2_ERR_STREAM_CLOSING;
+  }
+  /* If we are terminating session (NGHTTP2_GOAWAY_TERM_ON_SEND),
+     GOAWAY was received from peer, or session is about to close, new
+     request is not allowed. */
+  if ((session->goaway_flags & NGHTTP2_GOAWAY_RECV) ||
+      session_is_closing(session)) {
+    return NGHTTP2_ERR_START_STREAM_NOT_ALLOWED;
+  }
+  return 0;
+}
+
+/*
+ * This function checks HEADERS, which is the first frame from the
+ * server, with the |stream| can be sent at this time.  The |stream|
+ * can be NULL.
+ *
+ * This function returns 0 if it succeeds, or one of the following
+ * negative error codes:
+ *
+ * NGHTTP2_ERR_STREAM_CLOSED
+ *     The stream is already closed or does not exist.
+ * NGHTTP2_ERR_STREAM_SHUT_WR
+ *     The transmission is not allowed for this stream (e.g., a frame
+ *     with END_STREAM flag set has already sent)
+ * NGHTTP2_ERR_INVALID_STREAM_ID
+ *     The stream ID is invalid.
+ * NGHTTP2_ERR_STREAM_CLOSING
+ *     RST_STREAM was queued for this stream.
+ * NGHTTP2_ERR_INVALID_STREAM_STATE
+ *     The state of the stream is not valid.
+ * NGHTTP2_ERR_SESSION_CLOSING
+ *     This session is closing.
+ * NGHTTP2_ERR_PROTO
+ *     Client side attempted to send response.
+ */
+static int session_predicate_response_headers_send(nghttp2_session *session,
+                                                   nghttp2_stream *stream) {
+  int rv;
+  rv = session_predicate_for_stream_send(session, stream);
+  if (rv != 0) {
+    return rv;
+  }
+  assert(stream);
+  if (!session->server) {
+    return NGHTTP2_ERR_PROTO;
+  }
+  if (nghttp2_session_is_my_stream_id(session, stream->stream_id)) {
+    return NGHTTP2_ERR_INVALID_STREAM_ID;
+  }
+  switch (stream->state) {
+  case NGHTTP2_STREAM_OPENING:
+    return 0;
+  case NGHTTP2_STREAM_CLOSING:
+    return NGHTTP2_ERR_STREAM_CLOSING;
+  default:
+    return NGHTTP2_ERR_INVALID_STREAM_STATE;
+  }
+}
+
+/*
+ * This function checks HEADERS for reserved stream can be sent. The
+ * |stream| must be reserved state and the |session| is server side.
+ * The |stream| can be NULL.
+ *
+ * This function returns 0 if it succeeds, or one of the following
+ * error codes:
+ *
+ * NGHTTP2_ERR_STREAM_CLOSED
+ *   The stream is already closed.
+ * NGHTTP2_ERR_STREAM_SHUT_WR
+ *   The stream is half-closed for transmission.
+ * NGHTTP2_ERR_PROTO
+ *   The stream is not reserved state
+ * NGHTTP2_ERR_STREAM_CLOSED
+ *   RST_STREAM was queued for this stream.
+ * NGHTTP2_ERR_SESSION_CLOSING
+ *   This session is closing.
+ * NGHTTP2_ERR_START_STREAM_NOT_ALLOWED
+ *   New stream cannot be created because GOAWAY is already sent or
+ *   received.
+ * NGHTTP2_ERR_PROTO
+ *   Client side attempted to send push response.
+ */
+static int
+session_predicate_push_response_headers_send(nghttp2_session *session,
+                                             nghttp2_stream *stream) {
+  int rv;
+  /* TODO Should disallow HEADERS if GOAWAY has already been issued? */
+  rv = session_predicate_for_stream_send(session, stream);
+  if (rv != 0) {
+    return rv;
+  }
+  assert(stream);
+  if (!session->server) {
+    return NGHTTP2_ERR_PROTO;
+  }
+  if (stream->state != NGHTTP2_STREAM_RESERVED) {
+    return NGHTTP2_ERR_PROTO;
+  }
+  if (session->goaway_flags & NGHTTP2_GOAWAY_RECV) {
+    return NGHTTP2_ERR_START_STREAM_NOT_ALLOWED;
+  }
+  return 0;
+}
+
+/*
+ * This function checks HEADERS, which is neither stream-opening nor
+ * first response header, with the |stream| can be sent at this time.
+ * The |stream| can be NULL.
+ *
+ * This function returns 0 if it succeeds, or one of the following
+ * negative error codes:
+ *
+ * NGHTTP2_ERR_STREAM_CLOSED
+ *     The stream is already closed or does not exist.
+ * NGHTTP2_ERR_STREAM_SHUT_WR
+ *     The transmission is not allowed for this stream (e.g., a frame
+ *     with END_STREAM flag set has already sent)
+ * NGHTTP2_ERR_STREAM_CLOSING
+ *     RST_STREAM was queued for this stream.
+ * NGHTTP2_ERR_INVALID_STREAM_STATE
+ *     The state of the stream is not valid.
+ * NGHTTP2_ERR_SESSION_CLOSING
+ *   This session is closing.
+ */
+static int session_predicate_headers_send(nghttp2_session *session,
+                                          nghttp2_stream *stream) {
+  int rv;
+  rv = session_predicate_for_stream_send(session, stream);
+  if (rv != 0) {
+    return rv;
+  }
+  assert(stream);
+
+  switch (stream->state) {
+  case NGHTTP2_STREAM_OPENED:
+    return 0;
+  case NGHTTP2_STREAM_CLOSING:
+    return NGHTTP2_ERR_STREAM_CLOSING;
+  default:
+    if (nghttp2_session_is_my_stream_id(session, stream->stream_id)) {
+      return 0;
+    }
+    return NGHTTP2_ERR_INVALID_STREAM_STATE;
+  }
+}
+
+/*
+ * This function checks PUSH_PROMISE frame |frame| with the |stream|
+ * can be sent at this time.  The |stream| can be NULL.
+ *
+ * This function returns 0 if it succeeds, or one of the following
+ * negative error codes:
+ *
+ * NGHTTP2_ERR_START_STREAM_NOT_ALLOWED
+ *     New stream cannot be created because GOAWAY is already sent or
+ *     received.
+ * NGHTTP2_ERR_PROTO
+ *     The client side attempts to send PUSH_PROMISE, or the server
+ *     sends PUSH_PROMISE for the stream not initiated by the client.
+ * NGHTTP2_ERR_STREAM_CLOSED
+ *     The stream is already closed or does not exist.
+ * NGHTTP2_ERR_STREAM_CLOSING
+ *     RST_STREAM was queued for this stream.
+ * NGHTTP2_ERR_STREAM_SHUT_WR
+ *     The transmission is not allowed for this stream (e.g., a frame
+ *     with END_STREAM flag set has already sent)
+ * NGHTTP2_ERR_PUSH_DISABLED
+ *     The remote peer disabled reception of PUSH_PROMISE.
+ * NGHTTP2_ERR_SESSION_CLOSING
+ *   This session is closing.
+ */
+static int session_predicate_push_promise_send(nghttp2_session *session,
+                                               nghttp2_stream *stream) {
+  int rv;
+
+  if (!session->server) {
+    return NGHTTP2_ERR_PROTO;
+  }
+
+  rv = session_predicate_for_stream_send(session, stream);
+  if (rv != 0) {
+    return rv;
+  }
+
+  assert(stream);
+
+  if (session->remote_settings.enable_push == 0) {
+    return NGHTTP2_ERR_PUSH_DISABLED;
+  }
+  if (stream->state == NGHTTP2_STREAM_CLOSING) {
+    return NGHTTP2_ERR_STREAM_CLOSING;
+  }
+  if (session->goaway_flags & NGHTTP2_GOAWAY_RECV) {
+    return NGHTTP2_ERR_START_STREAM_NOT_ALLOWED;
+  }
+  return 0;
+}
+
+/*
+ * This function checks WINDOW_UPDATE with the stream ID |stream_id|
+ * can be sent at this time. Note that END_STREAM flag of the previous
+ * frame does not affect the transmission of the WINDOW_UPDATE frame.
+ *
+ * This function returns 0 if it succeeds, or one of the following
+ * negative error codes:
+ *
+ * NGHTTP2_ERR_STREAM_CLOSED
+ *     The stream is already closed or does not exist.
+ * NGHTTP2_ERR_STREAM_CLOSING
+ *     RST_STREAM was queued for this stream.
+ * NGHTTP2_ERR_INVALID_STREAM_STATE
+ *     The state of the stream is not valid.
+ * NGHTTP2_ERR_SESSION_CLOSING
+ *   This session is closing.
+ */
+static int session_predicate_window_update_send(nghttp2_session *session,
+                                                int32_t stream_id) {
+  nghttp2_stream *stream;
+
+  if (session_is_closing(session)) {
+    return NGHTTP2_ERR_SESSION_CLOSING;
+  }
+
+  if (stream_id == 0) {
+    /* Connection-level window update */
+    return 0;
+  }
+  stream = nghttp2_session_get_stream(session, stream_id);
+  if (stream == NULL) {
+    return NGHTTP2_ERR_STREAM_CLOSED;
+  }
+  if (stream->state == NGHTTP2_STREAM_CLOSING) {
+    return NGHTTP2_ERR_STREAM_CLOSING;
+  }
+  if (state_reserved_local(session, stream)) {
+    return NGHTTP2_ERR_INVALID_STREAM_STATE;
+  }
+  return 0;
+}
+
+static int session_predicate_altsvc_send(nghttp2_session *session,
+                                         int32_t stream_id) {
+  nghttp2_stream *stream;
+
+  if (session_is_closing(session)) {
+    return NGHTTP2_ERR_SESSION_CLOSING;
+  }
+
+  if (stream_id == 0) {
+    return 0;
+  }
+
+  stream = nghttp2_session_get_stream(session, stream_id);
+  if (stream == NULL) {
+    return NGHTTP2_ERR_STREAM_CLOSED;
+  }
+  if (stream->state == NGHTTP2_STREAM_CLOSING) {
+    return NGHTTP2_ERR_STREAM_CLOSING;
+  }
+
+  return 0;
+}
+
+static int session_predicate_origin_send(nghttp2_session *session) {
+  if (session_is_closing(session)) {
+    return NGHTTP2_ERR_SESSION_CLOSING;
+  }
+  return 0;
+}
+
+/* Take into account settings max frame size and both connection-level
+   flow control here */
+static ssize_t
+nghttp2_session_enforce_flow_control_limits(nghttp2_session *session,
+                                            nghttp2_stream *stream,
+                                            ssize_t requested_window_size) {
+  DEBUGF("send: remote windowsize connection=%d, remote maxframsize=%u, "
+         "stream(id %d)=%d\n",
+         session->remote_window_size, session->remote_settings.max_frame_size,
+         stream->stream_id, stream->remote_window_size);
+
+  return nghttp2_min(nghttp2_min(nghttp2_min(requested_window_size,
+                                             stream->remote_window_size),
+                                 session->remote_window_size),
+                     (int32_t)session->remote_settings.max_frame_size);
+}
+
+/*
+ * Returns the maximum length of next data read. If the
+ * connection-level and/or stream-wise flow control are enabled, the
+ * return value takes into account those current window sizes. The remote
+ * settings for max frame size is also taken into account.
+ */
+static size_t nghttp2_session_next_data_read(nghttp2_session *session,
+                                             nghttp2_stream *stream) {
+  ssize_t window_size;
+
+  window_size = nghttp2_session_enforce_flow_control_limits(
+      session, stream, NGHTTP2_DATA_PAYLOADLEN);
+
+  DEBUGF("send: available window=%zd\n", window_size);
+
+  return window_size > 0 ? (size_t)window_size : 0;
+}
+
+/*
+ * This function checks DATA with the |stream| can be sent at this
+ * time.  The |stream| can be NULL.
+ *
+ * This function returns 0 if it succeeds, or one of the following
+ * negative error codes:
+ *
+ * NGHTTP2_ERR_STREAM_CLOSED
+ *     The stream is already closed or does not exist.
+ * NGHTTP2_ERR_STREAM_SHUT_WR
+ *     The transmission is not allowed for this stream (e.g., a frame
+ *     with END_STREAM flag set has already sent)
+ * NGHTTP2_ERR_STREAM_CLOSING
+ *     RST_STREAM was queued for this stream.
+ * NGHTTP2_ERR_INVALID_STREAM_STATE
+ *     The state of the stream is not valid.
+ * NGHTTP2_ERR_SESSION_CLOSING
+ *   This session is closing.
+ */
+static int nghttp2_session_predicate_data_send(nghttp2_session *session,
+                                               nghttp2_stream *stream) {
+  int rv;
+  rv = session_predicate_for_stream_send(session, stream);
+  if (rv != 0) {
+    return rv;
+  }
+  assert(stream);
+  if (nghttp2_session_is_my_stream_id(session, stream->stream_id)) {
+    /* Request body data */
+    /* If stream->state is NGHTTP2_STREAM_CLOSING, RST_STREAM was
+       queued but not yet sent. In this case, we won't send DATA
+       frames. */
+    if (stream->state == NGHTTP2_STREAM_CLOSING) {
+      return NGHTTP2_ERR_STREAM_CLOSING;
+    }
+    if (stream->state == NGHTTP2_STREAM_RESERVED) {
+      return NGHTTP2_ERR_INVALID_STREAM_STATE;
+    }
+    return 0;
+  }
+  /* Response body data */
+  if (stream->state == NGHTTP2_STREAM_OPENED) {
+    return 0;
+  }
+  if (stream->state == NGHTTP2_STREAM_CLOSING) {
+    return NGHTTP2_ERR_STREAM_CLOSING;
+  }
+  return NGHTTP2_ERR_INVALID_STREAM_STATE;
+}
+
+static ssize_t session_call_select_padding(nghttp2_session *session,
+                                           const nghttp2_frame *frame,
+                                           size_t max_payloadlen) {
+  ssize_t rv;
+
+  if (frame->hd.length >= max_payloadlen) {
+    return (ssize_t)frame->hd.length;
+  }
+
+  if (session->callbacks.select_padding_callback) {
+    size_t max_paddedlen;
+
+    max_paddedlen =
+        nghttp2_min(frame->hd.length + NGHTTP2_MAX_PADLEN, max_payloadlen);
+
+    rv = session->callbacks.select_padding_callback(
+        session, frame, max_paddedlen, session->user_data);
+    if (rv < (ssize_t)frame->hd.length || rv > (ssize_t)max_paddedlen) {
+      return NGHTTP2_ERR_CALLBACK_FAILURE;
+    }
+    return rv;
+  }
+  return (ssize_t)frame->hd.length;
+}
+
+/* Add padding to HEADERS or PUSH_PROMISE. We use
+   frame->headers.padlen in this function to use the fact that
+   frame->push_promise has also padlen in the same position. */
+static int session_headers_add_pad(nghttp2_session *session,
+                                   nghttp2_frame *frame) {
+  int rv;
+  ssize_t padded_payloadlen;
+  nghttp2_active_outbound_item *aob;
+  nghttp2_bufs *framebufs;
+  size_t padlen;
+  size_t max_payloadlen;
+
+  aob = &session->aob;
+  framebufs = &aob->framebufs;
+
+  max_payloadlen = nghttp2_min(NGHTTP2_MAX_PAYLOADLEN,
+                               frame->hd.length + NGHTTP2_MAX_PADLEN);
+
+  padded_payloadlen =
+      session_call_select_padding(session, frame, max_payloadlen);
+
+  if (nghttp2_is_fatal((int)padded_payloadlen)) {
+    return (int)padded_payloadlen;
+  }
+
+  padlen = (size_t)padded_payloadlen - frame->hd.length;
+
+  DEBUGF("send: padding selected: payloadlen=%zd, padlen=%zu\n",
+         padded_payloadlen, padlen);
+
+  rv = nghttp2_frame_add_pad(framebufs, &frame->hd, padlen, 0);
+
+  if (rv != 0) {
+    return rv;
+  }
+
+  frame->headers.padlen = padlen;
+
+  return 0;
+}
+
+static size_t session_estimate_headers_payload(nghttp2_session *session,
+                                               const nghttp2_nv *nva,
+                                               size_t nvlen,
+                                               size_t additional) {
+  return nghttp2_hd_deflate_bound(&session->hd_deflater, nva, nvlen) +
+         additional;
+}
+
+static int session_pack_extension(nghttp2_session *session, nghttp2_bufs *bufs,
+                                  nghttp2_frame *frame) {
+  ssize_t rv;
+  nghttp2_buf *buf;
+  size_t buflen;
+  size_t framelen;
+
+  assert(session->callbacks.pack_extension_callback);
+
+  buf = &bufs->head->buf;
+  buflen = nghttp2_min(nghttp2_buf_avail(buf), NGHTTP2_MAX_PAYLOADLEN);
+
+  rv = session->callbacks.pack_extension_callback(session, buf->last, buflen,
+                                                  frame, session->user_data);
+  if (rv == NGHTTP2_ERR_CANCEL) {
+    return (int)rv;
+  }
+
+  if (rv < 0 || (size_t)rv > buflen) {
+    return NGHTTP2_ERR_CALLBACK_FAILURE;
+  }
+
+  framelen = (size_t)rv;
+
+  frame->hd.length = framelen;
+
+  assert(buf->pos == buf->last);
+  buf->last += framelen;
+  buf->pos -= NGHTTP2_FRAME_HDLEN;
+
+  nghttp2_frame_pack_frame_hd(buf->pos, &frame->hd);
+
+  return 0;
+}
+
+/*
+ * This function serializes frame for transmission.
+ *
+ * This function returns 0 if it succeeds, or one of negative error
+ * codes, including both fatal and non-fatal ones.
+ */
+static int session_prep_frame(nghttp2_session *session,
+                              nghttp2_outbound_item *item) {
+  int rv;
+  nghttp2_frame *frame;
+  nghttp2_mem *mem;
+
+  mem = &session->mem;
+  frame = &item->frame;
+
+  switch (frame->hd.type) {
+  case NGHTTP2_DATA: {
+    size_t next_readmax;
+    nghttp2_stream *stream;
+
+    stream = nghttp2_session_get_stream(session, frame->hd.stream_id);
+
+    if (stream) {
+      assert(stream->item == item);
+    }
+
+    rv = nghttp2_session_predicate_data_send(session, stream);
+    if (rv != 0) {
+      // If stream was already closed, nghttp2_session_get_stream()
+      // returns NULL, but item is still attached to the stream.
+      // Search stream including closed again.
+      stream = nghttp2_session_get_stream_raw(session, frame->hd.stream_id);
+      if (stream) {
+        int rv2;
+
+        rv2 = nghttp2_stream_detach_item(stream);
+
+        if (nghttp2_is_fatal(rv2)) {
+          return rv2;
+        }
+      }
+
+      return rv;
+    }
+    /* Assuming stream is not NULL */
+    assert(stream);
+    next_readmax = nghttp2_session_next_data_read(session, stream);
+
+    if (next_readmax == 0) {
+
+      /* This must be true since we only pop DATA frame item from
+         queue when session->remote_window_size > 0 */
+      assert(session->remote_window_size > 0);
+
+      rv = nghttp2_stream_defer_item(stream,
+                                     NGHTTP2_STREAM_FLAG_DEFERRED_FLOW_CONTROL);
+
+      if (nghttp2_is_fatal(rv)) {
+        return rv;
+      }
+
+      session->aob.item = NULL;
+      active_outbound_item_reset(&session->aob, mem);
+      return NGHTTP2_ERR_DEFERRED;
+    }
+
+    rv = nghttp2_session_pack_data(session, &session->aob.framebufs,
+                                   next_readmax, frame, &item->aux_data.data,
+                                   stream);
+    if (rv == NGHTTP2_ERR_PAUSE) {
+      return rv;
+    }
+    if (rv == NGHTTP2_ERR_DEFERRED) {
+      rv = nghttp2_stream_defer_item(stream, NGHTTP2_STREAM_FLAG_DEFERRED_USER);
+
+      if (nghttp2_is_fatal(rv)) {
+        return rv;
+      }
+
+      session->aob.item = NULL;
+      active_outbound_item_reset(&session->aob, mem);
+      return NGHTTP2_ERR_DEFERRED;
+    }
+    if (rv == NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE) {
+      rv = nghttp2_stream_detach_item(stream);
+
+      if (nghttp2_is_fatal(rv)) {
+        return rv;
+      }
+
+      rv = nghttp2_session_add_rst_stream(session, frame->hd.stream_id,
+                                          NGHTTP2_INTERNAL_ERROR);
+      if (nghttp2_is_fatal(rv)) {
+        return rv;
+      }
+      return NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE;
+    }
+    if (rv != 0) {
+      int rv2;
+
+      rv2 = nghttp2_stream_detach_item(stream);
+
+      if (nghttp2_is_fatal(rv2)) {
+        return rv2;
+      }
+
+      return rv;
+    }
+    return 0;
+  }
+  case NGHTTP2_HEADERS: {
+    nghttp2_headers_aux_data *aux_data;
+    size_t estimated_payloadlen;
+
+    aux_data = &item->aux_data.headers;
+
+    if (frame->headers.cat == NGHTTP2_HCAT_REQUEST) {
+      /* initial HEADERS, which opens stream */
+      nghttp2_stream *stream;
+
+      stream = nghttp2_session_open_stream(
+          session, frame->hd.stream_id, NGHTTP2_STREAM_FLAG_NONE,
+          &frame->headers.pri_spec, NGHTTP2_STREAM_INITIAL,
+          aux_data->stream_user_data);
+
+      if (stream == NULL) {
+        return NGHTTP2_ERR_NOMEM;
+      }
+
+      /* We don't call nghttp2_session_adjust_closed_stream() here,
+         since we don't keep closed stream in client side */
+
+      rv = session_predicate_request_headers_send(session, item);
+      if (rv != 0) {
+        return rv;
+      }
+
+      if (session_enforce_http_messaging(session)) {
+        nghttp2_http_record_request_method(stream, frame);
+      }
+    } else {
+      nghttp2_stream *stream;
+
+      stream = nghttp2_session_get_stream(session, frame->hd.stream_id);
+
+      if (stream && stream->state == NGHTTP2_STREAM_RESERVED) {
+        rv = session_predicate_push_response_headers_send(session, stream);
+        if (rv == 0) {
+          frame->headers.cat = NGHTTP2_HCAT_PUSH_RESPONSE;
+
+          if (aux_data->stream_user_data) {
+            stream->stream_user_data = aux_data->stream_user_data;
+          }
+        }
+      } else if (session_predicate_response_headers_send(session, stream) ==
+                 0) {
+        frame->headers.cat = NGHTTP2_HCAT_RESPONSE;
+        rv = 0;
+      } else {
+        frame->headers.cat = NGHTTP2_HCAT_HEADERS;
+
+        rv = session_predicate_headers_send(session, stream);
+      }
+
+      if (rv != 0) {
+        return rv;
+      }
+    }
+
+    estimated_payloadlen = session_estimate_headers_payload(
+        session, frame->headers.nva, frame->headers.nvlen,
+        NGHTTP2_PRIORITY_SPECLEN);
+
+    if (estimated_payloadlen > session->max_send_header_block_length) {
+      return NGHTTP2_ERR_FRAME_SIZE_ERROR;
+    }
+
+    rv = nghttp2_frame_pack_headers(&session->aob.framebufs, &frame->headers,
+                                    &session->hd_deflater);
+
+    if (rv != 0) {
+      return rv;
+    }
+
+    DEBUGF("send: before padding, HEADERS serialized in %zd bytes\n",
+           nghttp2_bufs_len(&session->aob.framebufs));
+
+    rv = session_headers_add_pad(session, frame);
+
+    if (rv != 0) {
+      return rv;
+    }
+
+    DEBUGF("send: HEADERS finally serialized in %zd bytes\n",
+           nghttp2_bufs_len(&session->aob.framebufs));
+
+    if (frame->headers.cat == NGHTTP2_HCAT_REQUEST) {
+      assert(session->last_sent_stream_id < frame->hd.stream_id);
+      session->last_sent_stream_id = frame->hd.stream_id;
+    }
+
+    return 0;
+  }
+  case NGHTTP2_PRIORITY: {
+    if (session_is_closing(session)) {
+      return NGHTTP2_ERR_SESSION_CLOSING;
+    }
+    /* PRIORITY frame can be sent at any time and to any stream
+       ID. */
+    nghttp2_frame_pack_priority(&session->aob.framebufs, &frame->priority);
+
+    /* Peer can send PRIORITY frame against idle stream to create
+       "anchor" in dependency tree.  Only client can do this in
+       nghttp2.  In nghttp2, only server retains non-active (closed
+       or idle) streams in memory, so we don't open stream here. */
+    return 0;
+  }
+  case NGHTTP2_RST_STREAM:
+    if (session_is_closing(session)) {
+      return NGHTTP2_ERR_SESSION_CLOSING;
+    }
+    nghttp2_frame_pack_rst_stream(&session->aob.framebufs, &frame->rst_stream);
+    return 0;
+  case NGHTTP2_SETTINGS: {
+    if (frame->hd.flags & NGHTTP2_FLAG_ACK) {
+      assert(session->obq_flood_counter_ > 0);
+      --session->obq_flood_counter_;
+      /* When session is about to close, don't send SETTINGS ACK.
+         We are required to send SETTINGS without ACK though; for
+         example, we have to send SETTINGS as a part of connection
+         preface. */
+      if (session_is_closing(session)) {
+        return NGHTTP2_ERR_SESSION_CLOSING;
+      }
+    }
+
+    rv = nghttp2_frame_pack_settings(&session->aob.framebufs, &frame->settings);
+    if (rv != 0) {
+      return rv;
+    }
+    return 0;
+  }
+  case NGHTTP2_PUSH_PROMISE: {
+    nghttp2_stream *stream;
+    size_t estimated_payloadlen;
+
+    /* stream could be NULL if associated stream was already
+       closed. */
+    stream = nghttp2_session_get_stream(session, frame->hd.stream_id);
+
+    /* predicate should fail if stream is NULL. */
+    rv = session_predicate_push_promise_send(session, stream);
+    if (rv != 0) {
+      return rv;
+    }
+
+    assert(stream);
+
+    estimated_payloadlen = session_estimate_headers_payload(
+        session, frame->push_promise.nva, frame->push_promise.nvlen, 0);
+
+    if (estimated_payloadlen > session->max_send_header_block_length) {
+      return NGHTTP2_ERR_FRAME_SIZE_ERROR;
+    }
+
+    rv = nghttp2_frame_pack_push_promise(
+        &session->aob.framebufs, &frame->push_promise, &session->hd_deflater);
+    if (rv != 0) {
+      return rv;
+    }
+    rv = session_headers_add_pad(session, frame);
+    if (rv != 0) {
+      return rv;
+    }
+
+    assert(session->last_sent_stream_id + 2 <=
+           frame->push_promise.promised_stream_id);
+    session->last_sent_stream_id = frame->push_promise.promised_stream_id;
+
+    return 0;
+  }
+  case NGHTTP2_PING:
+    if (frame->hd.flags & NGHTTP2_FLAG_ACK) {
+      assert(session->obq_flood_counter_ > 0);
+      --session->obq_flood_counter_;
+    }
+    /* PING frame is allowed to be sent unless termination GOAWAY is
+       sent */
+    if (session->goaway_flags & NGHTTP2_GOAWAY_TERM_ON_SEND) {
+      return NGHTTP2_ERR_SESSION_CLOSING;
+    }
+    nghttp2_frame_pack_ping(&session->aob.framebufs, &frame->ping);
+    return 0;
+  case NGHTTP2_GOAWAY:
+    rv = nghttp2_frame_pack_goaway(&session->aob.framebufs, &frame->goaway);
+    if (rv != 0) {
+      return rv;
+    }
+    session->local_last_stream_id = frame->goaway.last_stream_id;
+
+    return 0;
+  case NGHTTP2_WINDOW_UPDATE:
+    rv = session_predicate_window_update_send(session, frame->hd.stream_id);
+    if (rv != 0) {
+      return rv;
+    }
+    nghttp2_frame_pack_window_update(&session->aob.framebufs,
+                                     &frame->window_update);
+    return 0;
+  case NGHTTP2_CONTINUATION:
+    /* We never handle CONTINUATION here. */
+    assert(0);
+    return 0;
+  default: {
+    nghttp2_ext_aux_data *aux_data;
+
+    /* extension frame */
+
+    aux_data = &item->aux_data.ext;
+
+    if (aux_data->builtin == 0) {
+      if (session_is_closing(session)) {
+        return NGHTTP2_ERR_SESSION_CLOSING;
+      }
+
+      return session_pack_extension(session, &session->aob.framebufs, frame);
+    }
+
+    switch (frame->hd.type) {
+    case NGHTTP2_ALTSVC:
+      rv = session_predicate_altsvc_send(session, frame->hd.stream_id);
+      if (rv != 0) {
+        return rv;
+      }
+
+      nghttp2_frame_pack_altsvc(&session->aob.framebufs, &frame->ext);
+
+      return 0;
+    case NGHTTP2_ORIGIN:
+      rv = session_predicate_origin_send(session);
+      if (rv != 0) {
+        return rv;
+      }
+
+      rv = nghttp2_frame_pack_origin(&session->aob.framebufs, &frame->ext);
+      if (rv != 0) {
+        return rv;
+      }
+
+      return 0;
+    default:
+      /* Unreachable here */
+      assert(0);
+      return 0;
+    }
+  }
+  }
+}
+
+nghttp2_outbound_item *
+nghttp2_session_get_next_ob_item(nghttp2_session *session) {
+  if (nghttp2_outbound_queue_top(&session->ob_urgent)) {
+    return nghttp2_outbound_queue_top(&session->ob_urgent);
+  }
+
+  if (nghttp2_outbound_queue_top(&session->ob_reg)) {
+    return nghttp2_outbound_queue_top(&session->ob_reg);
+  }
+
+  if (!session_is_outgoing_concurrent_streams_max(session)) {
+    if (nghttp2_outbound_queue_top(&session->ob_syn)) {
+      return nghttp2_outbound_queue_top(&session->ob_syn);
+    }
+  }
+
+  if (session->remote_window_size > 0) {
+    return nghttp2_stream_next_outbound_item(&session->root);
+  }
+
+  return NULL;
+}
+
+nghttp2_outbound_item *
+nghttp2_session_pop_next_ob_item(nghttp2_session *session) {
+  nghttp2_outbound_item *item;
+
+  item = nghttp2_outbound_queue_top(&session->ob_urgent);
+  if (item) {
+    nghttp2_outbound_queue_pop(&session->ob_urgent);
+    item->queued = 0;
+    return item;
+  }
+
+  item = nghttp2_outbound_queue_top(&session->ob_reg);
+  if (item) {
+    nghttp2_outbound_queue_pop(&session->ob_reg);
+    item->queued = 0;
+    return item;
+  }
+
+  if (!session_is_outgoing_concurrent_streams_max(session)) {
+    item = nghttp2_outbound_queue_top(&session->ob_syn);
+    if (item) {
+      nghttp2_outbound_queue_pop(&session->ob_syn);
+      item->queued = 0;
+      return item;
+    }
+  }
+
+  if (session->remote_window_size > 0) {
+    return nghttp2_stream_next_outbound_item(&session->root);
+  }
+
+  return NULL;
+}
+
+static int session_call_before_frame_send(nghttp2_session *session,
+                                          nghttp2_frame *frame) {
+  int rv;
+  if (session->callbacks.before_frame_send_callback) {
+    rv = session->callbacks.before_frame_send_callback(session, frame,
+                                                       session->user_data);
+    if (rv == NGHTTP2_ERR_CANCEL) {
+      return rv;
+    }
+
+    if (rv != 0) {
+      return NGHTTP2_ERR_CALLBACK_FAILURE;
+    }
+  }
+  return 0;
+}
+
+static int session_call_on_frame_send(nghttp2_session *session,
+                                      nghttp2_frame *frame) {
+  int rv;
+  if (session->callbacks.on_frame_send_callback) {
+    rv = session->callbacks.on_frame_send_callback(session, frame,
+                                                   session->user_data);
+    if (rv != 0) {
+      return NGHTTP2_ERR_CALLBACK_FAILURE;
+    }
+  }
+  return 0;
+}
+
+static int find_stream_on_goaway_func(nghttp2_map_entry *entry, void *ptr) {
+  nghttp2_close_stream_on_goaway_arg *arg;
+  nghttp2_stream *stream;
+
+  arg = (nghttp2_close_stream_on_goaway_arg *)ptr;
+  stream = (nghttp2_stream *)entry;
+
+  if (nghttp2_session_is_my_stream_id(arg->session, stream->stream_id)) {
+    if (arg->incoming) {
+      return 0;
+    }
+  } else if (!arg->incoming) {
+    return 0;
+  }
+
+  if (stream->state != NGHTTP2_STREAM_IDLE &&
+      (stream->flags & NGHTTP2_STREAM_FLAG_CLOSED) == 0 &&
+      stream->stream_id > arg->last_stream_id) {
+    /* We are collecting streams to close because we cannot call
+       nghttp2_session_close_stream() inside nghttp2_map_each().
+       Reuse closed_next member.. bad choice? */
+    assert(stream->closed_next == NULL);
+    assert(stream->closed_prev == NULL);
+
+    if (arg->head) {
+      stream->closed_next = arg->head;
+      arg->head = stream;
+    } else {
+      arg->head = stream;
+    }
+  }
+
+  return 0;
+}
+
+/* Closes non-idle and non-closed streams whose stream ID >
+   last_stream_id.  If incoming is nonzero, we are going to close
+   incoming streams.  Otherwise, close outgoing streams. */
+static int session_close_stream_on_goaway(nghttp2_session *session,
+                                          int32_t last_stream_id,
+                                          int incoming) {
+  int rv;
+  nghttp2_stream *stream, *next_stream;
+  nghttp2_close_stream_on_goaway_arg arg = {session, NULL, last_stream_id,
+                                            incoming};
+
+  rv = nghttp2_map_each(&session->streams, find_stream_on_goaway_func, &arg);
+  assert(rv == 0);
+
+  stream = arg.head;
+  while (stream) {
+    next_stream = stream->closed_next;
+    stream->closed_next = NULL;
+    rv = nghttp2_session_close_stream(session, stream->stream_id,
+                                      NGHTTP2_REFUSED_STREAM);
+
+    /* stream may be deleted here */
+
+    stream = next_stream;
+
+    if (nghttp2_is_fatal(rv)) {
+      /* Clean up closed_next member just in case */
+      while (stream) {
+        next_stream = stream->closed_next;
+        stream->closed_next = NULL;
+        stream = next_stream;
+      }
+      return rv;
+    }
+  }
+
+  return 0;
+}
+
+static void reschedule_stream(nghttp2_stream *stream) {
+  stream->last_writelen = stream->item->frame.hd.length;
+
+  nghttp2_stream_reschedule(stream);
+}
+
+static int session_update_stream_consumed_size(nghttp2_session *session,
+                                               nghttp2_stream *stream,
+                                               size_t delta_size);
+
+static int session_update_connection_consumed_size(nghttp2_session *session,
+                                                   size_t delta_size);
+
+static int session_update_recv_connection_window_size(nghttp2_session *session,
+                                                      size_t delta_size);
+
+static int session_update_recv_stream_window_size(nghttp2_session *session,
+                                                  nghttp2_stream *stream,
+                                                  size_t delta_size,
+                                                  int send_window_update);
+
+/*
+ * Called after a frame is sent.  This function runs
+ * on_frame_send_callback and handles stream closure upon END_STREAM
+ * or RST_STREAM.  This function does not reset session->aob.  It is a
+ * responsibility of session_after_frame_sent2.
+ *
+ * This function returns 0 if it succeeds, or one of the following
+ * negative error codes:
+ *
+ * NGHTTP2_ERR_NOMEM
+ *     Out of memory.
+ * NGHTTP2_ERR_CALLBACK_FAILURE
+ *     The callback function failed.
+ */
+static int session_after_frame_sent1(nghttp2_session *session) {
+  int rv;
+  nghttp2_active_outbound_item *aob = &session->aob;
+  nghttp2_outbound_item *item = aob->item;
+  nghttp2_bufs *framebufs = &aob->framebufs;
+  nghttp2_frame *frame;
+  nghttp2_stream *stream;
+
+  frame = &item->frame;
+
+  if (frame->hd.type == NGHTTP2_DATA) {
+    nghttp2_data_aux_data *aux_data;
+
+    aux_data = &item->aux_data.data;
+
+    stream = nghttp2_session_get_stream(session, frame->hd.stream_id);
+    /* We update flow control window after a frame was completely
+       sent. This is possible because we choose payload length not to
+       exceed the window */
+    session->remote_window_size -= (int32_t)frame->hd.length;
+    if (stream) {
+      stream->remote_window_size -= (int32_t)frame->hd.length;
+    }
+
+    if (stream && aux_data->eof) {
+      rv = nghttp2_stream_detach_item(stream);
+      if (nghttp2_is_fatal(rv)) {
+        return rv;
+      }
+
+      /* Call on_frame_send_callback after
+         nghttp2_stream_detach_item(), so that application can issue
+         nghttp2_submit_data() in the callback. */
+      if (session->callbacks.on_frame_send_callback) {
+        rv = session_call_on_frame_send(session, frame);
+        if (nghttp2_is_fatal(rv)) {
+          return rv;
+        }
+      }
+
+      if (frame->hd.flags & NGHTTP2_FLAG_END_STREAM) {
+        int stream_closed;
+
+        stream_closed =
+            (stream->shut_flags & NGHTTP2_SHUT_RDWR) == NGHTTP2_SHUT_RDWR;
+
+        nghttp2_stream_shutdown(stream, NGHTTP2_SHUT_WR);
+
+        rv = nghttp2_session_close_stream_if_shut_rdwr(session, stream);
+        if (nghttp2_is_fatal(rv)) {
+          return rv;
+        }
+        /* stream may be NULL if it was closed */
+        if (stream_closed) {
+          stream = NULL;
+        }
+      }
+      return 0;
+    }
+
+    if (session->callbacks.on_frame_send_callback) {
+      rv = session_call_on_frame_send(session, frame);
+      if (nghttp2_is_fatal(rv)) {
+        return rv;
+      }
+    }
+
+    return 0;
+  }
+
+  /* non-DATA frame */
+
+  if (frame->hd.type == NGHTTP2_HEADERS ||
+      frame->hd.type == NGHTTP2_PUSH_PROMISE) {
+    if (nghttp2_bufs_next_present(framebufs)) {
+      DEBUGF("send: CONTINUATION exists, just return\n");
+      return 0;
+    }
+  }
+  rv = session_call_on_frame_send(session, frame);
+  if (nghttp2_is_fatal(rv)) {
+    return rv;
+  }
+  switch (frame->hd.type) {
+  case NGHTTP2_HEADERS: {
+    nghttp2_headers_aux_data *aux_data;
+
+    stream = nghttp2_session_get_stream(session, frame->hd.stream_id);
+    if (!stream) {
+      return 0;
+    }
+
+    switch (frame->headers.cat) {
+    case NGHTTP2_HCAT_REQUEST: {
+      stream->state = NGHTTP2_STREAM_OPENING;
+      if (frame->hd.flags & NGHTTP2_FLAG_END_STREAM) {
+        nghttp2_stream_shutdown(stream, NGHTTP2_SHUT_WR);
+      }
+      rv = nghttp2_session_close_stream_if_shut_rdwr(session, stream);
+      if (nghttp2_is_fatal(rv)) {
+        return rv;
+      }
+      /* We assume aux_data is a pointer to nghttp2_headers_aux_data */
+      aux_data = &item->aux_data.headers;
+      if (aux_data->data_prd.read_callback) {
+        /* nghttp2_submit_data() makes a copy of aux_data->data_prd */
+        rv = nghttp2_submit_data(session, NGHTTP2_FLAG_END_STREAM,
+                                 frame->hd.stream_id, &aux_data->data_prd);
+        if (nghttp2_is_fatal(rv)) {
+          return rv;
+        }
+        /* TODO nghttp2_submit_data() may fail if stream has already
+           DATA frame item.  We might have to handle it here. */
+      }
+      return 0;
+    }
+    case NGHTTP2_HCAT_PUSH_RESPONSE:
+      stream->flags = (uint8_t)(stream->flags & ~NGHTTP2_STREAM_FLAG_PUSH);
+      ++session->num_outgoing_streams;
+    /* Fall through */
+    case NGHTTP2_HCAT_RESPONSE:
+      stream->state = NGHTTP2_STREAM_OPENED;
+    /* Fall through */
+    case NGHTTP2_HCAT_HEADERS:
+      if (frame->hd.flags & NGHTTP2_FLAG_END_STREAM) {
+        nghttp2_stream_shutdown(stream, NGHTTP2_SHUT_WR);
+      }
+      rv = nghttp2_session_close_stream_if_shut_rdwr(session, stream);
+      if (nghttp2_is_fatal(rv)) {
+        return rv;
+      }
+      /* We assume aux_data is a pointer to nghttp2_headers_aux_data */
+      aux_data = &item->aux_data.headers;
+      if (aux_data->data_prd.read_callback) {
+        rv = nghttp2_submit_data(session, NGHTTP2_FLAG_END_STREAM,
+                                 frame->hd.stream_id, &aux_data->data_prd);
+        if (nghttp2_is_fatal(rv)) {
+          return rv;
+        }
+        /* TODO nghttp2_submit_data() may fail if stream has already
+           DATA frame item.  We might have to handle it here. */
+      }
+      return 0;
+    default:
+      /* Unreachable */
+      assert(0);
+      return 0;
+    }
+  }
+  case NGHTTP2_PRIORITY:
+    if (session->server) {
+      return 0;
+      ;
+    }
+
+    stream = nghttp2_session_get_stream_raw(session, frame->hd.stream_id);
+
+    if (!stream) {
+      if (!session_detect_idle_stream(session, frame->hd.stream_id)) {
+        return 0;
+      }
+
+      stream = nghttp2_session_open_stream(
+          session, frame->hd.stream_id, NGHTTP2_FLAG_NONE,
+          &frame->priority.pri_spec, NGHTTP2_STREAM_IDLE, NULL);
+      if (!stream) {
+        return NGHTTP2_ERR_NOMEM;
+      }
+    } else {
+      rv = nghttp2_session_reprioritize_stream(session, stream,
+                                               &frame->priority.pri_spec);
+      if (nghttp2_is_fatal(rv)) {
+        return rv;
+      }
+    }
+
+    rv = nghttp2_session_adjust_idle_stream(session);
+
+    if (nghttp2_is_fatal(rv)) {
+      return rv;
+    }
+
+    return 0;
+  case NGHTTP2_RST_STREAM:
+    rv = nghttp2_session_close_stream(session, frame->hd.stream_id,
+                                      frame->rst_stream.error_code);
+    if (nghttp2_is_fatal(rv)) {
+      return rv;
+    }
+    return 0;
+  case NGHTTP2_GOAWAY: {
+    nghttp2_goaway_aux_data *aux_data;
+
+    aux_data = &item->aux_data.goaway;
+
+    if ((aux_data->flags & NGHTTP2_GOAWAY_AUX_SHUTDOWN_NOTICE) == 0) {
+
+      if (aux_data->flags & NGHTTP2_GOAWAY_AUX_TERM_ON_SEND) {
+        session->goaway_flags |= NGHTTP2_GOAWAY_TERM_SENT;
+      }
+
+      session->goaway_flags |= NGHTTP2_GOAWAY_SENT;
+
+      rv = session_close_stream_on_goaway(session, frame->goaway.last_stream_id,
+                                          1);
+
+      if (nghttp2_is_fatal(rv)) {
+        return rv;
+      }
+    }
+
+    return 0;
+  }
+  case NGHTTP2_WINDOW_UPDATE:
+    if (frame->hd.stream_id == 0) {
+      session->window_update_queued = 0;
+      if (session->opt_flags & NGHTTP2_OPTMASK_NO_AUTO_WINDOW_UPDATE) {
+        rv = session_update_connection_consumed_size(session, 0);
+      } else {
+        rv = session_update_recv_connection_window_size(session, 0);
+      }
+
+      if (nghttp2_is_fatal(rv)) {
+        return rv;
+      }
+
+      return 0;
+    }
+
+    stream = nghttp2_session_get_stream(session, frame->hd.stream_id);
+    if (!stream) {
+      return 0;
+    }
+
+    stream->window_update_queued = 0;
+
+    /* We don't have to send WINDOW_UPDATE if END_STREAM from peer
+       is seen. */
+    if (stream->shut_flags & NGHTTP2_SHUT_RD) {
+      return 0;
+    }
+
+    if (session->opt_flags & NGHTTP2_OPTMASK_NO_AUTO_WINDOW_UPDATE) {
+      rv = session_update_stream_consumed_size(session, stream, 0);
+    } else {
+      rv = session_update_recv_stream_window_size(session, stream, 0, 1);
+    }
+
+    if (nghttp2_is_fatal(rv)) {
+      return rv;
+    }
+
+    return 0;
+  default:
+    return 0;
+  }
+}
+
+/*
+ * Called after a frame is sent and session_after_frame_sent1.  This
+ * function is responsible to reset session->aob.
+ *
+ * This function returns 0 if it succeeds, or one of the following
+ * negative error codes:
+ *
+ * NGHTTP2_ERR_NOMEM
+ *     Out of memory.
+ * NGHTTP2_ERR_CALLBACK_FAILURE
+ *     The callback function failed.
+ */
+static int session_after_frame_sent2(nghttp2_session *session) {
+  int rv;
+  nghttp2_active_outbound_item *aob = &session->aob;
+  nghttp2_outbound_item *item = aob->item;
+  nghttp2_bufs *framebufs = &aob->framebufs;
+  nghttp2_frame *frame;
+  nghttp2_mem *mem;
+  nghttp2_stream *stream;
+  nghttp2_data_aux_data *aux_data;
+
+  mem = &session->mem;
+  frame = &item->frame;
+
+  if (frame->hd.type != NGHTTP2_DATA) {
+
+    if (frame->hd.type == NGHTTP2_HEADERS ||
+        frame->hd.type == NGHTTP2_PUSH_PROMISE) {
+
+      if (nghttp2_bufs_next_present(framebufs)) {
+        framebufs->cur = framebufs->cur->next;
+
+        DEBUGF("send: next CONTINUATION frame, %zu bytes\n",
+               nghttp2_buf_len(&framebufs->cur->buf));
+
+        return 0;
+      }
+    }
+
+    active_outbound_item_reset(&session->aob, mem);
+
+    return 0;
+  }
+
+  /* DATA frame */
+
+  aux_data = &item->aux_data.data;
+
+  /* On EOF, we have already detached data.  Please note that
+     application may issue nghttp2_submit_data() in
+     on_frame_send_callback (call from session_after_frame_sent1),
+     which attach data to stream.  We don't want to detach it. */
+  if (aux_data->eof) {
+    active_outbound_item_reset(aob, mem);
+
+    return 0;
+  }
+
+  /* Reset no_copy here because next write may not use this. */
+  aux_data->no_copy = 0;
+
+  stream = nghttp2_session_get_stream(session, frame->hd.stream_id);
+
+  /* If session is closed or RST_STREAM was queued, we won't send
+     further data. */
+  if (nghttp2_session_predicate_data_send(session, stream) != 0) {
+    if (stream) {
+      rv = nghttp2_stream_detach_item(stream);
+
+      if (nghttp2_is_fatal(rv)) {
+        return rv;
+      }
+    }
+
+    active_outbound_item_reset(aob, mem);
+
+    return 0;
+  }
+
+  aob->item = NULL;
+  active_outbound_item_reset(&session->aob, mem);
+
+  return 0;
+}
+
+static int session_call_send_data(nghttp2_session *session,
+                                  nghttp2_outbound_item *item,
+                                  nghttp2_bufs *framebufs) {
+  int rv;
+  nghttp2_buf *buf;
+  size_t length;
+  nghttp2_frame *frame;
+  nghttp2_data_aux_data *aux_data;
+
+  buf = &framebufs->cur->buf;
+  frame = &item->frame;
+  length = frame->hd.length - frame->data.padlen;
+  aux_data = &item->aux_data.data;
+
+  rv = session->callbacks.send_data_callback(session, frame, buf->pos, length,
+                                             &aux_data->data_prd.source,
+                                             session->user_data);
+
+  switch (rv) {
+  case 0:
+  case NGHTTP2_ERR_WOULDBLOCK:
+  case NGHTTP2_ERR_PAUSE:
+  case NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE:
+    return rv;
+  default:
+    return NGHTTP2_ERR_CALLBACK_FAILURE;
+  }
+}
+
+static ssize_t nghttp2_session_mem_send_internal(nghttp2_session *session,
+                                                 const uint8_t **data_ptr,
+                                                 int fast_cb) {
+  int rv;
+  nghttp2_active_outbound_item *aob;
+  nghttp2_bufs *framebufs;
+  nghttp2_mem *mem;
+
+  mem = &session->mem;
+  aob = &session->aob;
+  framebufs = &aob->framebufs;
+
+  /* We may have idle streams more than we expect (e.g.,
+     nghttp2_session_change_stream_priority() or
+     nghttp2_session_create_idle_stream()).  Adjust them here. */
+  rv = nghttp2_session_adjust_idle_stream(session);
+  if (nghttp2_is_fatal(rv)) {
+    return rv;
+  }
+
+  for (;;) {
+    switch (aob->state) {
+    case NGHTTP2_OB_POP_ITEM: {
+      nghttp2_outbound_item *item;
+
+      item = nghttp2_session_pop_next_ob_item(session);
+      if (item == NULL) {
+        return 0;
+      }
+
+      rv = session_prep_frame(session, item);
+      if (rv == NGHTTP2_ERR_PAUSE) {
+        return 0;
+      }
+      if (rv == NGHTTP2_ERR_DEFERRED) {
+        DEBUGF("send: frame transmission deferred\n");
+        break;
+      }
+      if (rv < 0) {
+        int32_t opened_stream_id = 0;
+        uint32_t error_code = NGHTTP2_INTERNAL_ERROR;
+
+        DEBUGF("send: frame preparation failed with %s\n",
+               nghttp2_strerror(rv));
+        /* TODO If the error comes from compressor, the connection
+           must be closed. */
+        if (item->frame.hd.type != NGHTTP2_DATA &&
+            session->callbacks.on_frame_not_send_callback && is_non_fatal(rv)) {
+          nghttp2_frame *frame = &item->frame;
+          /* The library is responsible for the transmission of
+             WINDOW_UPDATE frame, so we don't call error callback for
+             it. */
+          if (frame->hd.type != NGHTTP2_WINDOW_UPDATE &&
+              session->callbacks.on_frame_not_send_callback(
+                  session, frame, rv, session->user_data) != 0) {
+
+            nghttp2_outbound_item_free(item, mem);
+            nghttp2_mem_free(mem, item);
+
+            return NGHTTP2_ERR_CALLBACK_FAILURE;
+          }
+        }
+        /* We have to close stream opened by failed request HEADERS
+           or PUSH_PROMISE. */
+        switch (item->frame.hd.type) {
+        case NGHTTP2_HEADERS:
+          if (item->frame.headers.cat == NGHTTP2_HCAT_REQUEST) {
+            opened_stream_id = item->frame.hd.stream_id;
+            if (item->aux_data.headers.canceled) {
+              error_code = item->aux_data.headers.error_code;
+            } else {
+              /* Set error_code to REFUSED_STREAM so that application
+                 can send request again. */
+              error_code = NGHTTP2_REFUSED_STREAM;
+            }
+          }
+          break;
+        case NGHTTP2_PUSH_PROMISE:
+          opened_stream_id = item->frame.push_promise.promised_stream_id;
+          break;
+        }
+        if (opened_stream_id) {
+          /* careful not to override rv */
+          int rv2;
+          rv2 = nghttp2_session_close_stream(session, opened_stream_id,
+                                             error_code);
+
+          if (nghttp2_is_fatal(rv2)) {
+            return rv2;
+          }
+        }
+
+        nghttp2_outbound_item_free(item, mem);
+        nghttp2_mem_free(mem, item);
+        active_outbound_item_reset(aob, mem);
+
+        if (rv == NGHTTP2_ERR_HEADER_COMP) {
+          /* If header compression error occurred, should terminiate
+             connection. */
+          rv = nghttp2_session_terminate_session(session,
+                                                 NGHTTP2_INTERNAL_ERROR);
+        }
+        if (nghttp2_is_fatal(rv)) {
+          return rv;
+        }
+        break;
+      }
+
+      aob->item = item;
+
+      nghttp2_bufs_rewind(framebufs);
+
+      if (item->frame.hd.type != NGHTTP2_DATA) {
+        nghttp2_frame *frame;
+
+        frame = &item->frame;
+
+        DEBUGF("send: next frame: payloadlen=%zu, type=%u, flags=0x%02x, "
+               "stream_id=%d\n",
+               frame->hd.length, frame->hd.type, frame->hd.flags,
+               frame->hd.stream_id);
+
+        rv = session_call_before_frame_send(session, frame);
+        if (nghttp2_is_fatal(rv)) {
+          return rv;
+        }
+
+        if (rv == NGHTTP2_ERR_CANCEL) {
+          int32_t opened_stream_id = 0;
+          uint32_t error_code = NGHTTP2_INTERNAL_ERROR;
+
+          if (session->callbacks.on_frame_not_send_callback) {
+            if (session->callbacks.on_frame_not_send_callback(
+                    session, frame, rv, session->user_data) != 0) {
+              return NGHTTP2_ERR_CALLBACK_FAILURE;
+            }
+          }
+
+          /* We have to close stream opened by canceled request
+             HEADERS or PUSH_PROMISE. */
+          switch (item->frame.hd.type) {
+          case NGHTTP2_HEADERS:
+            if (item->frame.headers.cat == NGHTTP2_HCAT_REQUEST) {
+              opened_stream_id = item->frame.hd.stream_id;
+              /* We don't have to check
+                 item->aux_data.headers.canceled since it has already
+                 been checked. */
+              /* Set error_code to REFUSED_STREAM so that application
+                 can send request again. */
+              error_code = NGHTTP2_REFUSED_STREAM;
+            }
+            break;
+          case NGHTTP2_PUSH_PROMISE:
+            opened_stream_id = item->frame.push_promise.promised_stream_id;
+            break;
+          }
+          if (opened_stream_id) {
+            /* careful not to override rv */
+            int rv2;
+            rv2 = nghttp2_session_close_stream(session, opened_stream_id,
+                                               error_code);
+
+            if (nghttp2_is_fatal(rv2)) {
+              return rv2;
+            }
+          }
+
+          active_outbound_item_reset(aob, mem);
+
+          break;
+        }
+      } else {
+        DEBUGF("send: next frame: DATA\n");
+
+        if (item->aux_data.data.no_copy) {
+          aob->state = NGHTTP2_OB_SEND_NO_COPY;
+          break;
+        }
+      }
+
+      DEBUGF("send: start transmitting frame type=%u, length=%zd\n",
+             framebufs->cur->buf.pos[3],
+             framebufs->cur->buf.last - framebufs->cur->buf.pos);
+
+      aob->state = NGHTTP2_OB_SEND_DATA;
+
+      break;
+    }
+    case NGHTTP2_OB_SEND_DATA: {
+      size_t datalen;
+      nghttp2_buf *buf;
+
+      buf = &framebufs->cur->buf;
+
+      if (buf->pos == buf->last) {
+        DEBUGF("send: end transmission of a frame\n");
+
+        /* Frame has completely sent */
+        if (fast_cb) {
+          rv = session_after_frame_sent2(session);
+        } else {
+          rv = session_after_frame_sent1(session);
+          if (rv < 0) {
+            /* FATAL */
+            assert(nghttp2_is_fatal(rv));
+            return rv;
+          }
+          rv = session_after_frame_sent2(session);
+        }
+        if (rv < 0) {
+          /* FATAL */
+          assert(nghttp2_is_fatal(rv));
+          return rv;
+        }
+        /* We have already adjusted the next state */
+        break;
+      }
+
+      *data_ptr = buf->pos;
+      datalen = nghttp2_buf_len(buf);
+
+      /* We increment the offset here. If send_callback does not send
+         everything, we will adjust it. */
+      buf->pos += datalen;
+
+      return (ssize_t)datalen;
+    }
+    case NGHTTP2_OB_SEND_NO_COPY: {
+      nghttp2_stream *stream;
+      nghttp2_frame *frame;
+      int pause;
+
+      DEBUGF("send: no copy DATA\n");
+
+      frame = &aob->item->frame;
+
+      stream = nghttp2_session_get_stream(session, frame->hd.stream_id);
+      if (stream == NULL) {
+        DEBUGF("send: no copy DATA cancelled because stream was closed\n");
+
+        active_outbound_item_reset(aob, mem);
+
+        break;
+      }
+
+      rv = session_call_send_data(session, aob->item, framebufs);
+      if (nghttp2_is_fatal(rv)) {
+        return rv;
+      }
+
+      if (rv == NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE) {
+        rv = nghttp2_stream_detach_item(stream);
+
+        if (nghttp2_is_fatal(rv)) {
+          return rv;
+        }
+
+        rv = nghttp2_session_add_rst_stream(session, frame->hd.stream_id,
+                                            NGHTTP2_INTERNAL_ERROR);
+        if (nghttp2_is_fatal(rv)) {
+          return rv;
+        }
+
+        active_outbound_item_reset(aob, mem);
+
+        break;
+      }
+
+      if (rv == NGHTTP2_ERR_WOULDBLOCK) {
+        return 0;
+      }
+
+      pause = (rv == NGHTTP2_ERR_PAUSE);
+
+      rv = session_after_frame_sent1(session);
+      if (rv < 0) {
+        assert(nghttp2_is_fatal(rv));
+        return rv;
+      }
+      rv = session_after_frame_sent2(session);
+      if (rv < 0) {
+        assert(nghttp2_is_fatal(rv));
+        return rv;
+      }
+
+      /* We have already adjusted the next state */
+
+      if (pause) {
+        return 0;
+      }
+
+      break;
+    }
+    case NGHTTP2_OB_SEND_CLIENT_MAGIC: {
+      size_t datalen;
+      nghttp2_buf *buf;
+
+      buf = &framebufs->cur->buf;
+
+      if (buf->pos == buf->last) {
+        DEBUGF("send: end transmission of client magic\n");
+        active_outbound_item_reset(aob, mem);
+        break;
+      }
+
+      *data_ptr = buf->pos;
+      datalen = nghttp2_buf_len(buf);
+
+      buf->pos += datalen;
+
+      return (ssize_t)datalen;
+    }
+    }
+  }
+}
+
+ssize_t nghttp2_session_mem_send(nghttp2_session *session,
+                                 const uint8_t **data_ptr) {
+  int rv;
+  ssize_t len;
+
+  *data_ptr = NULL;
+
+  len = nghttp2_session_mem_send_internal(session, data_ptr, 1);
+  if (len <= 0) {
+    return len;
+  }
+
+  if (session->aob.item) {
+    /* We have to call session_after_frame_sent1 here to handle stream
+       closure upon transmission of frames.  Otherwise, END_STREAM may
+       be reached to client before we call nghttp2_session_mem_send
+       again and we may get exceeding number of incoming streams. */
+    rv = session_after_frame_sent1(session);
+    if (rv < 0) {
+      assert(nghttp2_is_fatal(rv));
+      return (ssize_t)rv;
+    }
+  }
+
+  return len;
+}
+
+int nghttp2_session_send(nghttp2_session *session) {
+  const uint8_t *data = NULL;
+  ssize_t datalen;
+  ssize_t sentlen;
+  nghttp2_bufs *framebufs;
+
+  framebufs = &session->aob.framebufs;
+
+  for (;;) {
+    datalen = nghttp2_session_mem_send_internal(session, &data, 0);
+    if (datalen <= 0) {
+      return (int)datalen;
+    }
+    sentlen = session->callbacks.send_callback(session, data, (size_t)datalen,
+                                               0, session->user_data);
+    if (sentlen < 0) {
+      if (sentlen == NGHTTP2_ERR_WOULDBLOCK) {
+        /* Transmission canceled. Rewind the offset */
+        framebufs->cur->buf.pos -= datalen;
+
+        return 0;
+      }
+      return NGHTTP2_ERR_CALLBACK_FAILURE;
+    }
+    /* Rewind the offset to the amount of unsent bytes */
+    framebufs->cur->buf.pos -= datalen - sentlen;
+  }
+}
+
+static ssize_t session_recv(nghttp2_session *session, uint8_t *buf,
+                            size_t len) {
+  ssize_t rv;
+  rv = session->callbacks.recv_callback(session, buf, len, 0,
+                                        session->user_data);
+  if (rv > 0) {
+    if ((size_t)rv > len) {
+      return NGHTTP2_ERR_CALLBACK_FAILURE;
+    }
+  } else if (rv < 0 && rv != NGHTTP2_ERR_WOULDBLOCK && rv != NGHTTP2_ERR_EOF) {
+    return NGHTTP2_ERR_CALLBACK_FAILURE;
+  }
+  return rv;
+}
+
+static int session_call_on_begin_frame(nghttp2_session *session,
+                                       const nghttp2_frame_hd *hd) {
+  int rv;
+
+  if (session->callbacks.on_begin_frame_callback) {
+
+    rv = session->callbacks.on_begin_frame_callback(session, hd,
+                                                    session->user_data);
+
+    if (rv != 0) {
+      return NGHTTP2_ERR_CALLBACK_FAILURE;
+    }
+  }
+
+  return 0;
+}
+
+static int session_call_on_frame_received(nghttp2_session *session,
+                                          nghttp2_frame *frame) {
+  int rv;
+  if (session->callbacks.on_frame_recv_callback) {
+    rv = session->callbacks.on_frame_recv_callback(session, frame,
+                                                   session->user_data);
+    if (rv != 0) {
+      return NGHTTP2_ERR_CALLBACK_FAILURE;
+    }
+  }
+  return 0;
+}
+
+static int session_call_on_begin_headers(nghttp2_session *session,
+                                         nghttp2_frame *frame) {
+  int rv;
+  DEBUGF("recv: call on_begin_headers callback stream_id=%d\n",
+         frame->hd.stream_id);
+  if (session->callbacks.on_begin_headers_callback) {
+    rv = session->callbacks.on_begin_headers_callback(session, frame,
+                                                      session->user_data);
+    if (rv == NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE) {
+      return rv;
+    }
+    if (rv != 0) {
+      return NGHTTP2_ERR_CALLBACK_FAILURE;
+    }
+  }
+  return 0;
+}
+
+static int session_call_on_header(nghttp2_session *session,
+                                  const nghttp2_frame *frame,
+                                  const nghttp2_hd_nv *nv) {
+  int rv = 0;
+  if (session->callbacks.on_header_callback2) {
+    rv = session->callbacks.on_header_callback2(
+        session, frame, nv->name, nv->value, nv->flags, session->user_data);
+  } else if (session->callbacks.on_header_callback) {
+    rv = session->callbacks.on_header_callback(
+        session, frame, nv->name->base, nv->name->len, nv->value->base,
+        nv->value->len, nv->flags, session->user_data);
+  }
+
+  if (rv == NGHTTP2_ERR_PAUSE || rv == NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE) {
+    return rv;
+  }
+  if (rv != 0) {
+    return NGHTTP2_ERR_CALLBACK_FAILURE;
+  }
+
+  return 0;
+}
+
+static int session_call_on_invalid_header(nghttp2_session *session,
+                                          const nghttp2_frame *frame,
+                                          const nghttp2_hd_nv *nv) {
+  int rv;
+  if (session->callbacks.on_invalid_header_callback2) {
+    rv = session->callbacks.on_invalid_header_callback2(
+        session, frame, nv->name, nv->value, nv->flags, session->user_data);
+  } else if (session->callbacks.on_invalid_header_callback) {
+    rv = session->callbacks.on_invalid_header_callback(
+        session, frame, nv->name->base, nv->name->len, nv->value->base,
+        nv->value->len, nv->flags, session->user_data);
+  } else {
+    return NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE;
+  }
+
+  if (rv == NGHTTP2_ERR_PAUSE || rv == NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE) {
+    return rv;
+  }
+  if (rv != 0) {
+    return NGHTTP2_ERR_CALLBACK_FAILURE;
+  }
+
+  return 0;
+}
+
+static int
+session_call_on_extension_chunk_recv_callback(nghttp2_session *session,
+                                              const uint8_t *data, size_t len) {
+  int rv;
+  nghttp2_inbound_frame *iframe = &session->iframe;
+  nghttp2_frame *frame = &iframe->frame;
+
+  if (session->callbacks.on_extension_chunk_recv_callback) {
+    rv = session->callbacks.on_extension_chunk_recv_callback(
+        session, &frame->hd, data, len, session->user_data);
+    if (rv == NGHTTP2_ERR_CANCEL) {
+      return rv;
+    }
+    if (rv != 0) {
+      return NGHTTP2_ERR_CALLBACK_FAILURE;
+    }
+  }
+
+  return 0;
+}
+
+static int session_call_unpack_extension_callback(nghttp2_session *session) {
+  int rv;
+  nghttp2_inbound_frame *iframe = &session->iframe;
+  nghttp2_frame *frame = &iframe->frame;
+  void *payload = NULL;
+
+  rv = session->callbacks.unpack_extension_callback(
+      session, &payload, &frame->hd, session->user_data);
+  if (rv == NGHTTP2_ERR_CANCEL) {
+    return rv;
+  }
+  if (rv != 0) {
+    return NGHTTP2_ERR_CALLBACK_FAILURE;
+  }
+
+  frame->ext.payload = payload;
+
+  return 0;
+}
+
+/*
+ * Handles frame size error.
+ *
+ * This function returns 0 if it succeeds, or one of the following
+ * negative error codes:
+ *
+ * NGHTTP2_ERR_NOMEM
+ *   Out of memory.
+ */
+static int session_handle_frame_size_error(nghttp2_session *session) {
+  /* TODO Currently no callback is called for this error, because we
+     call this callback before reading any payload */
+  return nghttp2_session_terminate_session(session, NGHTTP2_FRAME_SIZE_ERROR);
+}
+
+static uint32_t get_error_code_from_lib_error_code(int lib_error_code) {
+  switch (lib_error_code) {
+  case NGHTTP2_ERR_STREAM_CLOSED:
+    return NGHTTP2_STREAM_CLOSED;
+  case NGHTTP2_ERR_HEADER_COMP:
+    return NGHTTP2_COMPRESSION_ERROR;
+  case NGHTTP2_ERR_FRAME_SIZE_ERROR:
+    return NGHTTP2_FRAME_SIZE_ERROR;
+  case NGHTTP2_ERR_FLOW_CONTROL:
+    return NGHTTP2_FLOW_CONTROL_ERROR;
+  case NGHTTP2_ERR_REFUSED_STREAM:
+    return NGHTTP2_REFUSED_STREAM;
+  case NGHTTP2_ERR_PROTO:
+  case NGHTTP2_ERR_HTTP_HEADER:
+  case NGHTTP2_ERR_HTTP_MESSAGING:
+    return NGHTTP2_PROTOCOL_ERROR;
+  default:
+    return NGHTTP2_INTERNAL_ERROR;
+  }
+}
+
+/*
+ * Calls on_invalid_frame_recv_callback if it is set to |session|.
+ *
+ * This function returns 0 if it succeeds, or one of the following
+ * negative error codes:
+ *
+ * NGHTTP2_ERR_CALLBACK_FAILURE
+ *   User defined callback function fails.
+ */
+static int session_call_on_invalid_frame_recv_callback(nghttp2_session *session,
+                                                       nghttp2_frame *frame,
+                                                       int lib_error_code) {
+  if (session->callbacks.on_invalid_frame_recv_callback) {
+    if (session->callbacks.on_invalid_frame_recv_callback(
+            session, frame, lib_error_code, session->user_data) != 0) {
+      return NGHTTP2_ERR_CALLBACK_FAILURE;
+    }
+  }
+  return 0;
+}
+
+static int session_handle_invalid_stream2(nghttp2_session *session,
+                                          int32_t stream_id,
+                                          nghttp2_frame *frame,
+                                          int lib_error_code) {
+  int rv;
+  rv = nghttp2_session_add_rst_stream(
+      session, stream_id, get_error_code_from_lib_error_code(lib_error_code));
+  if (rv != 0) {
+    return rv;
+  }
+  if (session->callbacks.on_invalid_frame_recv_callback) {
+    if (session->callbacks.on_invalid_frame_recv_callback(
+            session, frame, lib_error_code, session->user_data) != 0) {
+      return NGHTTP2_ERR_CALLBACK_FAILURE;
+    }
+  }
+  return 0;
+}
+
+static int session_handle_invalid_stream(nghttp2_session *session,
+                                         nghttp2_frame *frame,
+                                         int lib_error_code) {
+  return session_handle_invalid_stream2(session, frame->hd.stream_id, frame,
+                                        lib_error_code);
+}
+
+static int session_inflate_handle_invalid_stream(nghttp2_session *session,
+                                                 nghttp2_frame *frame,
+                                                 int lib_error_code) {
+  int rv;
+  rv = session_handle_invalid_stream(session, frame, lib_error_code);
+  if (nghttp2_is_fatal(rv)) {
+    return rv;
+  }
+  return NGHTTP2_ERR_IGN_HEADER_BLOCK;
+}
+
+/*
+ * Handles invalid frame which causes connection error.
+ */
+static int session_handle_invalid_connection(nghttp2_session *session,
+                                             nghttp2_frame *frame,
+                                             int lib_error_code,
+                                             const char *reason) {
+  if (session->callbacks.on_invalid_frame_recv_callback) {
+    if (session->callbacks.on_invalid_frame_recv_callback(
+            session, frame, lib_error_code, session->user_data) != 0) {
+      return NGHTTP2_ERR_CALLBACK_FAILURE;
+    }
+  }
+  return nghttp2_session_terminate_session_with_reason(
+      session, get_error_code_from_lib_error_code(lib_error_code), reason);
+}
+
+static int session_inflate_handle_invalid_connection(nghttp2_session *session,
+                                                     nghttp2_frame *frame,
+                                                     int lib_error_code,
+                                                     const char *reason) {
+  int rv;
+  rv =
+      session_handle_invalid_connection(session, frame, lib_error_code, reason);
+  if (nghttp2_is_fatal(rv)) {
+    return rv;
+  }
+  return NGHTTP2_ERR_IGN_HEADER_BLOCK;
+}
+
+/*
+ * Inflates header block in the memory pointed by |in| with |inlen|
+ * bytes. If this function returns NGHTTP2_ERR_PAUSE, the caller must
+ * call this function again, until it returns 0 or one of negative
+ * error code.  If |call_header_cb| is zero, the on_header_callback
+ * are not invoked and the function never return NGHTTP2_ERR_PAUSE. If
+ * the given |in| is the last chunk of header block, the |final| must
+ * be nonzero. If header block is successfully processed (which is
+ * indicated by the return value 0, NGHTTP2_ERR_PAUSE or
+ * NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE), the number of processed
+ * input bytes is assigned to the |*readlen_ptr|.
+ *
+ * This function return 0 if it succeeds, or one of the negative error
+ * codes:
+ *
+ * NGHTTP2_ERR_CALLBACK_FAILURE
+ *     The callback function failed.
+ * NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE
+ *     The callback returns this error code, indicating that this
+ *     stream should be RST_STREAMed.
+ * NGHTTP2_ERR_NOMEM
+ *     Out of memory.
+ * NGHTTP2_ERR_PAUSE
+ *     The callback function returned NGHTTP2_ERR_PAUSE
+ * NGHTTP2_ERR_HEADER_COMP
+ *     Header decompression failed
+ */
+static int inflate_header_block(nghttp2_session *session, nghttp2_frame *frame,
+                                size_t *readlen_ptr, uint8_t *in, size_t inlen,
+                                int final, int call_header_cb) {
+  ssize_t proclen;
+  int rv;
+  int inflate_flags;
+  nghttp2_hd_nv nv;
+  nghttp2_stream *stream;
+  nghttp2_stream *subject_stream;
+  int trailer = 0;
+
+  *readlen_ptr = 0;
+  stream = nghttp2_session_get_stream(session, frame->hd.stream_id);
+
+  if (frame->hd.type == NGHTTP2_PUSH_PROMISE) {
+    subject_stream = nghttp2_session_get_stream(
+        session, frame->push_promise.promised_stream_id);
+  } else {
+    subject_stream = stream;
+    trailer = session_trailer_headers(session, stream, frame);
+  }
+
+  DEBUGF("recv: decoding header block %zu bytes\n", inlen);
+  for (;;) {
+    inflate_flags = 0;
+    proclen = nghttp2_hd_inflate_hd_nv(&session->hd_inflater, &nv,
+                                       &inflate_flags, in, inlen, final);
+    if (nghttp2_is_fatal((int)proclen)) {
+      return (int)proclen;
+    }
+    if (proclen < 0) {
+      if (session->iframe.state == NGHTTP2_IB_READ_HEADER_BLOCK) {
+        if (subject_stream && subject_stream->state != NGHTTP2_STREAM_CLOSING) {
+          /* Adding RST_STREAM here is very important. It prevents
+             from invoking subsequent callbacks for the same stream
+             ID. */
+          rv = nghttp2_session_add_rst_stream(
+              session, subject_stream->stream_id, NGHTTP2_COMPRESSION_ERROR);
+
+          if (nghttp2_is_fatal(rv)) {
+            return rv;
+          }
+        }
+      }
+      rv =
+          nghttp2_session_terminate_session(session, NGHTTP2_COMPRESSION_ERROR);
+      if (nghttp2_is_fatal(rv)) {
+        return rv;
+      }
+
+      return NGHTTP2_ERR_HEADER_COMP;
+    }
+    in += proclen;
+    inlen -= (size_t)proclen;
+    *readlen_ptr += (size_t)proclen;
+
+    DEBUGF("recv: proclen=%zd\n", proclen);
+
+    if (call_header_cb && (inflate_flags & NGHTTP2_HD_INFLATE_EMIT)) {
+      rv = 0;
+      if (subject_stream) {
+        if (session_enforce_http_messaging(session)) {
+          rv = nghttp2_http_on_header(session, subject_stream, frame, &nv,
+                                      trailer);
+
+          if (rv == NGHTTP2_ERR_IGN_HTTP_HEADER) {
+            /* Don't overwrite rv here */
+            int rv2;
+
+            rv2 = session_call_on_invalid_header(session, frame, &nv);
+            if (rv2 == NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE) {
+              rv = NGHTTP2_ERR_HTTP_HEADER;
+            } else {
+              if (rv2 != 0) {
+                return rv2;
+              }
+
+              /* header is ignored */
+              DEBUGF("recv: HTTP ignored: type=%u, id=%d, header %.*s: %.*s\n",
+                     frame->hd.type, frame->hd.stream_id, (int)nv.name->len,
+                     nv.name->base, (int)nv.value->len, nv.value->base);
+
+              rv2 = session_call_error_callback(
+                  session, NGHTTP2_ERR_HTTP_HEADER,
+                  "Ignoring received invalid HTTP header field: frame type: "
+                  "%u, stream: %d, name: [%.*s], value: [%.*s]",
+                  frame->hd.type, frame->hd.stream_id, (int)nv.name->len,
+                  nv.name->base, (int)nv.value->len, nv.value->base);
+
+              if (nghttp2_is_fatal(rv2)) {
+                return rv2;
+              }
+            }
+          }
+
+          if (rv == NGHTTP2_ERR_HTTP_HEADER) {
+            DEBUGF("recv: HTTP error: type=%u, id=%d, header %.*s: %.*s\n",
+                   frame->hd.type, frame->hd.stream_id, (int)nv.name->len,
+                   nv.name->base, (int)nv.value->len, nv.value->base);
+
+            rv = session_call_error_callback(
+                session, NGHTTP2_ERR_HTTP_HEADER,
+                "Invalid HTTP header field was received: frame type: "
+                "%u, stream: %d, name: [%.*s], value: [%.*s]",
+                frame->hd.type, frame->hd.stream_id, (int)nv.name->len,
+                nv.name->base, (int)nv.value->len, nv.value->base);
+
+            if (nghttp2_is_fatal(rv)) {
+              return rv;
+            }
+
+            rv = session_handle_invalid_stream2(session,
+                                                subject_stream->stream_id,
+                                                frame, NGHTTP2_ERR_HTTP_HEADER);
+            if (nghttp2_is_fatal(rv)) {
+              return rv;
+            }
+            return NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE;
+          }
+        }
+        if (rv == 0) {
+          rv = session_call_on_header(session, frame, &nv);
+          /* This handles NGHTTP2_ERR_PAUSE and
+             NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE as well */
+          if (rv != 0) {
+            return rv;
+          }
+        }
+      }
+    }
+    if (inflate_flags & NGHTTP2_HD_INFLATE_FINAL) {
+      nghttp2_hd_inflate_end_headers(&session->hd_inflater);
+      break;
+    }
+    if ((inflate_flags & NGHTTP2_HD_INFLATE_EMIT) == 0 && inlen == 0) {
+      break;
+    }
+  }
+  return 0;
+}
+
+/*
+ * Call this function when HEADERS frame was completely received.
+ *
+ * This function returns 0 if it succeeds, or one of negative error
+ * codes:
+ *
+ * NGHTTP2_ERR_CALLBACK_FAILURE
+ *     The callback function failed.
+ * NGHTTP2_ERR_NOMEM
+ *     Out of memory.
+ */
+static int session_end_stream_headers_received(nghttp2_session *session,
+                                               nghttp2_frame *frame,
+                                               nghttp2_stream *stream) {
+  int rv;
+  if ((frame->hd.flags & NGHTTP2_FLAG_END_STREAM) == 0) {
+    return 0;
+  }
+
+  nghttp2_stream_shutdown(stream, NGHTTP2_SHUT_RD);
+  rv = nghttp2_session_close_stream_if_shut_rdwr(session, stream);
+  if (nghttp2_is_fatal(rv)) {
+    return rv;
+  }
+
+  return 0;
+}
+
+static int session_after_header_block_received(nghttp2_session *session) {
+  int rv = 0;
+  nghttp2_frame *frame = &session->iframe.frame;
+  nghttp2_stream *stream;
+
+  /* We don't call on_frame_recv_callback if stream has been closed
+     already or being closed. */
+  stream = nghttp2_session_get_stream(session, frame->hd.stream_id);
+  if (!stream || stream->state == NGHTTP2_STREAM_CLOSING) {
+    return 0;
+  }
+
+  if (session_enforce_http_messaging(session)) {
+    if (frame->hd.type == NGHTTP2_PUSH_PROMISE) {
+      nghttp2_stream *subject_stream;
+
+      subject_stream = nghttp2_session_get_stream(
+          session, frame->push_promise.promised_stream_id);
+      if (subject_stream) {
+        rv = nghttp2_http_on_request_headers(subject_stream, frame);
+      }
+    } else {
+      assert(frame->hd.type == NGHTTP2_HEADERS);
+      switch (frame->headers.cat) {
+      case NGHTTP2_HCAT_REQUEST:
+        rv = nghttp2_http_on_request_headers(stream, frame);
+        break;
+      case NGHTTP2_HCAT_RESPONSE:
+      case NGHTTP2_HCAT_PUSH_RESPONSE:
+        rv = nghttp2_http_on_response_headers(stream);
+        break;
+      case NGHTTP2_HCAT_HEADERS:
+        if (stream->http_flags & NGHTTP2_HTTP_FLAG_EXPECT_FINAL_RESPONSE) {
+          assert(!session->server);
+          rv = nghttp2_http_on_response_headers(stream);
+        } else {
+          rv = nghttp2_http_on_trailer_headers(stream, frame);
+        }
+        break;
+      default:
+        assert(0);
+      }
+      if (rv == 0 && (frame->hd.flags & NGHTTP2_FLAG_END_STREAM)) {
+        rv = nghttp2_http_on_remote_end_stream(stream);
+      }
+    }
+    if (rv != 0) {
+      int32_t stream_id;
+
+      if (frame->hd.type == NGHTTP2_PUSH_PROMISE) {
+        stream_id = frame->push_promise.promised_stream_id;
+      } else {
+        stream_id = frame->hd.stream_id;
+      }
+
+      rv = session_handle_invalid_stream2(session, stream_id, frame,
+                                          NGHTTP2_ERR_HTTP_MESSAGING);
+      if (nghttp2_is_fatal(rv)) {
+        return rv;
+      }
+
+      if (frame->hd.type == NGHTTP2_HEADERS &&
+          (frame->hd.flags & NGHTTP2_FLAG_END_STREAM)) {
+        nghttp2_stream_shutdown(stream, NGHTTP2_SHUT_RD);
+        /* Don't call nghttp2_session_close_stream_if_shut_rdwr
+           because RST_STREAM has been submitted. */
+      }
+      return 0;
+    }
+  }
+
+  rv = session_call_on_frame_received(session, frame);
+  if (nghttp2_is_fatal(rv)) {
+    return rv;
+  }
+
+  if (frame->hd.type != NGHTTP2_HEADERS) {
+    return 0;
+  }
+
+  return session_end_stream_headers_received(session, frame, stream);
+}
+
+int nghttp2_session_on_request_headers_received(nghttp2_session *session,
+                                                nghttp2_frame *frame) {
+  int rv = 0;
+  nghttp2_stream *stream;
+  if (frame->hd.stream_id == 0) {
+    return session_inflate_handle_invalid_connection(
+        session, frame, NGHTTP2_ERR_PROTO, "request HEADERS: stream_id == 0");
+  }
+
+  /* If client receives idle stream from server, it is invalid
+     regardless stream ID is even or odd.  This is because client is
+     not expected to receive request from server. */
+  if (!session->server) {
+    if (session_detect_idle_stream(session, frame->hd.stream_id)) {
+      return session_inflate_handle_invalid_connection(
+          session, frame, NGHTTP2_ERR_PROTO,
+          "request HEADERS: client received request");
+    }
+
+    return NGHTTP2_ERR_IGN_HEADER_BLOCK;
+  }
+
+  assert(session->server);
+
+  if (!session_is_new_peer_stream_id(session, frame->hd.stream_id)) {
+    if (frame->hd.stream_id == 0 ||
+        nghttp2_session_is_my_stream_id(session, frame->hd.stream_id)) {
+      return session_inflate_handle_invalid_connection(
+          session, frame, NGHTTP2_ERR_PROTO,
+          "request HEADERS: invalid stream_id");
+    }
+
+    /* RFC 7540 says if an endpoint receives a HEADERS with invalid
+     * stream ID (e.g, numerically smaller than previous), it MUST
+     * issue connection error with error code PROTOCOL_ERROR.  It is a
+     * bit hard to detect this, since we cannot remember all streams
+     * we observed so far.
+     *
+     * You might imagine this is really easy.  But no.  HTTP/2 is
+     * asynchronous protocol, and usually client and server do not
+     * share the complete picture of open/closed stream status.  For
+     * example, after server sends RST_STREAM for a stream, client may
+     * send trailer HEADERS for that stream.  If naive server detects
+     * that, and issued connection error, then it is a bug of server
+     * implementation since client is not wrong if it did not get
+     * RST_STREAM when it issued trailer HEADERS.
+     *
+     * At the moment, we are very conservative here.  We only use
+     * connection error if stream ID refers idle stream, or we are
+     * sure that stream is half-closed(remote) or closed.  Otherwise
+     * we just ignore HEADERS for now.
+     */
+    stream = nghttp2_session_get_stream_raw(session, frame->hd.stream_id);
+    if (stream && (stream->shut_flags & NGHTTP2_SHUT_RD)) {
+      return session_inflate_handle_invalid_connection(
+          session, frame, NGHTTP2_ERR_STREAM_CLOSED, "HEADERS: stream closed");
+    }
+
+    return NGHTTP2_ERR_IGN_HEADER_BLOCK;
+  }
+  session->last_recv_stream_id = frame->hd.stream_id;
+
+  if (session_is_incoming_concurrent_streams_max(session)) {
+    return session_inflate_handle_invalid_connection(
+        session, frame, NGHTTP2_ERR_PROTO,
+        "request HEADERS: max concurrent streams exceeded");
+  }
+
+  if (!session_allow_incoming_new_stream(session)) {
+    /* We just ignore stream after GOAWAY was sent */
+    return NGHTTP2_ERR_IGN_HEADER_BLOCK;
+  }
+
+  if (frame->headers.pri_spec.stream_id == frame->hd.stream_id) {
+    return session_inflate_handle_invalid_connection(
+        session, frame, NGHTTP2_ERR_PROTO, "request HEADERS: depend on itself");
+  }
+
+  if (session_is_incoming_concurrent_streams_pending_max(session)) {
+    return session_inflate_handle_invalid_stream(session, frame,
+                                                 NGHTTP2_ERR_REFUSED_STREAM);
+  }
+
+  stream = nghttp2_session_open_stream(
+      session, frame->hd.stream_id, NGHTTP2_STREAM_FLAG_NONE,
+      &frame->headers.pri_spec, NGHTTP2_STREAM_OPENING, NULL);
+  if (!stream) {
+    return NGHTTP2_ERR_NOMEM;
+  }
+
+  rv = nghttp2_session_adjust_closed_stream(session);
+  if (nghttp2_is_fatal(rv)) {
+    return rv;
+  }
+
+  session->last_proc_stream_id = session->last_recv_stream_id;
+
+  rv = session_call_on_begin_headers(session, frame);
+  if (rv != 0) {
+    return rv;
+  }
+  return 0;
+}
+
+int nghttp2_session_on_response_headers_received(nghttp2_session *session,
+                                                 nghttp2_frame *frame,
+                                                 nghttp2_stream *stream) {
+  int rv;
+  /* This function is only called if stream->state ==
+     NGHTTP2_STREAM_OPENING and stream_id is local side initiated. */
+  assert(stream->state == NGHTTP2_STREAM_OPENING &&
+         nghttp2_session_is_my_stream_id(session, frame->hd.stream_id));
+  if (frame->hd.stream_id == 0) {
+    return session_inflate_handle_invalid_connection(
+        session, frame, NGHTTP2_ERR_PROTO, "response HEADERS: stream_id == 0");
+  }
+  if (stream->shut_flags & NGHTTP2_SHUT_RD) {
+    /* half closed (remote): from the spec:
+
+       If an endpoint receives additional frames for a stream that is
+       in this state it MUST respond with a stream error (Section
+       5.4.2) of type STREAM_CLOSED.
+
+       We go further, and make it connection error.
+    */
+    return session_inflate_handle_invalid_connection(
+        session, frame, NGHTTP2_ERR_STREAM_CLOSED, "HEADERS: stream closed");
+  }
+  stream->state = NGHTTP2_STREAM_OPENED;
+  rv = session_call_on_begin_headers(session, frame);
+  if (rv != 0) {
+    return rv;
+  }
+  return 0;
+}
+
+int nghttp2_session_on_push_response_headers_received(nghttp2_session *session,
+                                                      nghttp2_frame *frame,
+                                                      nghttp2_stream *stream) {
+  int rv = 0;
+  assert(stream->state == NGHTTP2_STREAM_RESERVED);
+  if (frame->hd.stream_id == 0) {
+    return session_inflate_handle_invalid_connection(
+        session, frame, NGHTTP2_ERR_PROTO,
+        "push response HEADERS: stream_id == 0");
+  }
+
+  if (session->server) {
+    return session_inflate_handle_invalid_connection(
+        session, frame, NGHTTP2_ERR_PROTO,
+        "HEADERS: no HEADERS allowed from client in reserved state");
+  }
+
+  if (session_is_incoming_concurrent_streams_max(session)) {
+    return session_inflate_handle_invalid_connection(
+        session, frame, NGHTTP2_ERR_PROTO,
+        "push response HEADERS: max concurrent streams exceeded");
+  }
+
+  if (!session_allow_incoming_new_stream(session)) {
+    /* We don't accept new stream after GOAWAY was sent. */
+    return NGHTTP2_ERR_IGN_HEADER_BLOCK;
+  }
+
+  if (session_is_incoming_concurrent_streams_pending_max(session)) {
+    return session_inflate_handle_invalid_stream(session, frame,
+                                                 NGHTTP2_ERR_REFUSED_STREAM);
+  }
+
+  nghttp2_stream_promise_fulfilled(stream);
+  if (!nghttp2_session_is_my_stream_id(session, stream->stream_id)) {
+    --session->num_incoming_reserved_streams;
+  }
+  ++session->num_incoming_streams;
+  rv = session_call_on_begin_headers(session, frame);
+  if (rv != 0) {
+    return rv;
+  }
+  return 0;
+}
+
+int nghttp2_session_on_headers_received(nghttp2_session *session,
+                                        nghttp2_frame *frame,
+                                        nghttp2_stream *stream) {
+  int rv = 0;
+  if (frame->hd.stream_id == 0) {
+    return session_inflate_handle_invalid_connection(
+        session, frame, NGHTTP2_ERR_PROTO, "HEADERS: stream_id == 0");
+  }
+  if ((stream->shut_flags & NGHTTP2_SHUT_RD)) {
+    /* half closed (remote): from the spec:
+
+       If an endpoint receives additional frames for a stream that is
+       in this state it MUST respond with a stream error (Section
+       5.4.2) of type STREAM_CLOSED.
+
+       we go further, and make it connection error.
+    */
+    return session_inflate_handle_invalid_connection(
+        session, frame, NGHTTP2_ERR_STREAM_CLOSED, "HEADERS: stream closed");
+  }
+  if (nghttp2_session_is_my_stream_id(session, frame->hd.stream_id)) {
+    if (stream->state == NGHTTP2_STREAM_OPENED) {
+      rv = session_call_on_begin_headers(session, frame);
+      if (rv != 0) {
+        return rv;
+      }
+      return 0;
+    }
+
+    return NGHTTP2_ERR_IGN_HEADER_BLOCK;
+  }
+  /* If this is remote peer initiated stream, it is OK unless it
+     has sent END_STREAM frame already. But if stream is in
+     NGHTTP2_STREAM_CLOSING, we discard the frame. This is a race
+     condition. */
+  if (stream->state != NGHTTP2_STREAM_CLOSING) {
+    rv = session_call_on_begin_headers(session, frame);
+    if (rv != 0) {
+      return rv;
+    }
+    return 0;
+  }
+  return NGHTTP2_ERR_IGN_HEADER_BLOCK;
+}
+
+static int session_process_headers_frame(nghttp2_session *session) {
+  int rv;
+  nghttp2_inbound_frame *iframe = &session->iframe;
+  nghttp2_frame *frame = &iframe->frame;
+  nghttp2_stream *stream;
+
+  rv = nghttp2_frame_unpack_headers_payload(&frame->headers, iframe->sbuf.pos);
+
+  if (rv != 0) {
+    return nghttp2_session_terminate_session_with_reason(
+        session, NGHTTP2_PROTOCOL_ERROR, "HEADERS: could not unpack");
+  }
+  stream = nghttp2_session_get_stream(session, frame->hd.stream_id);
+  if (!stream) {
+    frame->headers.cat = NGHTTP2_HCAT_REQUEST;
+    return nghttp2_session_on_request_headers_received(session, frame);
+  }
+
+  if (stream->state == NGHTTP2_STREAM_RESERVED) {
+    frame->headers.cat = NGHTTP2_HCAT_PUSH_RESPONSE;
+    return nghttp2_session_on_push_response_headers_received(session, frame,
+                                                             stream);
+  }
+
+  if (stream->state == NGHTTP2_STREAM_OPENING &&
+      nghttp2_session_is_my_stream_id(session, frame->hd.stream_id)) {
+    frame->headers.cat = NGHTTP2_HCAT_RESPONSE;
+    return nghttp2_session_on_response_headers_received(session, frame, stream);
+  }
+
+  frame->headers.cat = NGHTTP2_HCAT_HEADERS;
+  return nghttp2_session_on_headers_received(session, frame, stream);
+}
+
+int nghttp2_session_on_priority_received(nghttp2_session *session,
+                                         nghttp2_frame *frame) {
+  int rv;
+  nghttp2_stream *stream;
+
+  if (frame->hd.stream_id == 0) {
+    return session_handle_invalid_connection(session, frame, NGHTTP2_ERR_PROTO,
+                                             "PRIORITY: stream_id == 0");
+  }
+
+  if (frame->priority.pri_spec.stream_id == frame->hd.stream_id) {
+    return nghttp2_session_terminate_session_with_reason(
+        session, NGHTTP2_PROTOCOL_ERROR, "depend on itself");
+  }
+
+  if (!session->server) {
+    /* Re-prioritization works only in server */
+    return session_call_on_frame_received(session, frame);
+  }
+
+  stream = nghttp2_session_get_stream_raw(session, frame->hd.stream_id);
+
+  if (!stream) {
+    /* PRIORITY against idle stream can create anchor node in
+       dependency tree. */
+    if (!session_detect_idle_stream(session, frame->hd.stream_id)) {
+      return 0;
+    }
+
+    stream = nghttp2_session_open_stream(
+        session, frame->hd.stream_id, NGHTTP2_STREAM_FLAG_NONE,
+        &frame->priority.pri_spec, NGHTTP2_STREAM_IDLE, NULL);
+
+    if (stream == NULL) {
+      return NGHTTP2_ERR_NOMEM;
+    }
+
+    rv = nghttp2_session_adjust_idle_stream(session);
+    if (nghttp2_is_fatal(rv)) {
+      return rv;
+    }
+  } else {
+    rv = nghttp2_session_reprioritize_stream(session, stream,
+                                             &frame->priority.pri_spec);
+
+    if (nghttp2_is_fatal(rv)) {
+      return rv;
+    }
+
+    rv = nghttp2_session_adjust_idle_stream(session);
+    if (nghttp2_is_fatal(rv)) {
+      return rv;
+    }
+  }
+
+  return session_call_on_frame_received(session, frame);
+}
+
+static int session_process_priority_frame(nghttp2_session *session) {
+  nghttp2_inbound_frame *iframe = &session->iframe;
+  nghttp2_frame *frame = &iframe->frame;
+
+  nghttp2_frame_unpack_priority_payload(&frame->priority, iframe->sbuf.pos);
+
+  return nghttp2_session_on_priority_received(session, frame);
+}
+
+int nghttp2_session_on_rst_stream_received(nghttp2_session *session,
+                                           nghttp2_frame *frame) {
+  int rv;
+  nghttp2_stream *stream;
+  if (frame->hd.stream_id == 0) {
+    return session_handle_invalid_connection(session, frame, NGHTTP2_ERR_PROTO,
+                                             "RST_STREAM: stream_id == 0");
+  }
+
+  if (session_detect_idle_stream(session, frame->hd.stream_id)) {
+    return session_handle_invalid_connection(session, frame, NGHTTP2_ERR_PROTO,
+                                             "RST_STREAM: stream in idle");
+  }
+
+  stream = nghttp2_session_get_stream(session, frame->hd.stream_id);
+  if (stream) {
+    /* We may use stream->shut_flags for strict error checking. */
+    nghttp2_stream_shutdown(stream, NGHTTP2_SHUT_RD);
+  }
+
+  rv = session_call_on_frame_received(session, frame);
+  if (rv != 0) {
+    return rv;
+  }
+  rv = nghttp2_session_close_stream(session, frame->hd.stream_id,
+                                    frame->rst_stream.error_code);
+  if (nghttp2_is_fatal(rv)) {
+    return rv;
+  }
+  return 0;
+}
+
+static int session_process_rst_stream_frame(nghttp2_session *session) {
+  nghttp2_inbound_frame *iframe = &session->iframe;
+  nghttp2_frame *frame = &iframe->frame;
+
+  nghttp2_frame_unpack_rst_stream_payload(&frame->rst_stream, iframe->sbuf.pos);
+
+  return nghttp2_session_on_rst_stream_received(session, frame);
+}
+
+static int update_remote_initial_window_size_func(nghttp2_map_entry *entry,
+                                                  void *ptr) {
+  int rv;
+  nghttp2_update_window_size_arg *arg;
+  nghttp2_stream *stream;
+
+  arg = (nghttp2_update_window_size_arg *)ptr;
+  stream = (nghttp2_stream *)entry;
+
+  rv = nghttp2_stream_update_remote_initial_window_size(
+      stream, arg->new_window_size, arg->old_window_size);
+  if (rv != 0) {
+    return nghttp2_session_add_rst_stream(arg->session, stream->stream_id,
+                                          NGHTTP2_FLOW_CONTROL_ERROR);
+  }
+
+  /* If window size gets positive, push deferred DATA frame to
+     outbound queue. */
+  if (stream->remote_window_size > 0 &&
+      nghttp2_stream_check_deferred_by_flow_control(stream)) {
+
+    rv = nghttp2_stream_resume_deferred_item(
+        stream, NGHTTP2_STREAM_FLAG_DEFERRED_FLOW_CONTROL);
+
+    if (nghttp2_is_fatal(rv)) {
+      return rv;
+    }
+  }
+  return 0;
+}
+
+/*
+ * Updates the remote initial window size of all active streams.  If
+ * error occurs, all streams may not be updated.
+ *
+ * This function returns 0 if it succeeds, or one of the following
+ * negative error codes:
+ *
+ * NGHTTP2_ERR_NOMEM
+ *     Out of memory.
+ */
+static int
+session_update_remote_initial_window_size(nghttp2_session *session,
+                                          int32_t new_initial_window_size) {
+  nghttp2_update_window_size_arg arg;
+
+  arg.session = session;
+  arg.new_window_size = new_initial_window_size;
+  arg.old_window_size = (int32_t)session->remote_settings.initial_window_size;
+
+  return nghttp2_map_each(&session->streams,
+                          update_remote_initial_window_size_func, &arg);
+}
+
+static int update_local_initial_window_size_func(nghttp2_map_entry *entry,
+                                                 void *ptr) {
+  int rv;
+  nghttp2_update_window_size_arg *arg;
+  nghttp2_stream *stream;
+  arg = (nghttp2_update_window_size_arg *)ptr;
+  stream = (nghttp2_stream *)entry;
+  rv = nghttp2_stream_update_local_initial_window_size(
+      stream, arg->new_window_size, arg->old_window_size);
+  if (rv != 0) {
+    return nghttp2_session_add_rst_stream(arg->session, stream->stream_id,
+                                          NGHTTP2_FLOW_CONTROL_ERROR);
+  }
+  if (!(arg->session->opt_flags & NGHTTP2_OPTMASK_NO_AUTO_WINDOW_UPDATE) &&
+      stream->window_update_queued == 0 &&
+      nghttp2_should_send_window_update(stream->local_window_size,
+                                        stream->recv_window_size)) {
+
+    rv = nghttp2_session_add_window_update(arg->session, NGHTTP2_FLAG_NONE,
+                                           stream->stream_id,
+                                           stream->recv_window_size);
+    if (rv != 0) {
+      return rv;
+    }
+
+    stream->recv_window_size = 0;
+  }
+  return 0;
+}
+
+/*
+ * Updates the local initial window size of all active streams.  If
+ * error occurs, all streams may not be updated.
+ *
+ * This function returns 0 if it succeeds, or one of the following
+ * negative error codes:
+ *
+ * NGHTTP2_ERR_NOMEM
+ *     Out of memory.
+ */
+static int
+session_update_local_initial_window_size(nghttp2_session *session,
+                                         int32_t new_initial_window_size,
+                                         int32_t old_initial_window_size) {
+  nghttp2_update_window_size_arg arg;
+  arg.session = session;
+  arg.new_window_size = new_initial_window_size;
+  arg.old_window_size = old_initial_window_size;
+  return nghttp2_map_each(&session->streams,
+                          update_local_initial_window_size_func, &arg);
+}
+
+/*
+ * Apply SETTINGS values |iv| having |niv| elements to the local
+ * settings.  We assumes that all values in |iv| is correct, since we
+ * validated them in nghttp2_session_add_settings() already.
+ *
+ * This function returns 0 if it succeeds, or one of the following
+ * negative error codes:
+ *
+ * NGHTTP2_ERR_HEADER_COMP
+ *     The header table size is out of range
+ * NGHTTP2_ERR_NOMEM
+ *     Out of memory
+ */
+int nghttp2_session_update_local_settings(nghttp2_session *session,
+                                          nghttp2_settings_entry *iv,
+                                          size_t niv) {
+  int rv;
+  size_t i;
+  int32_t new_initial_window_size = -1;
+  uint32_t header_table_size = 0;
+  uint32_t min_header_table_size = UINT32_MAX;
+  uint8_t header_table_size_seen = 0;
+  /* For NGHTTP2_SETTINGS_INITIAL_WINDOW_SIZE, use the value last
+     seen.  For NGHTTP2_SETTINGS_HEADER_TABLE_SIZE, use both minimum
+     value and last seen value. */
+  for (i = 0; i < niv; ++i) {
+    switch (iv[i].settings_id) {
+    case NGHTTP2_SETTINGS_HEADER_TABLE_SIZE:
+      header_table_size_seen = 1;
+      header_table_size = iv[i].value;
+      min_header_table_size = nghttp2_min(min_header_table_size, iv[i].value);
+      break;
+    case NGHTTP2_SETTINGS_INITIAL_WINDOW_SIZE:
+      new_initial_window_size = (int32_t)iv[i].value;
+      break;
+    }
+  }
+  if (header_table_size_seen) {
+    if (min_header_table_size < header_table_size) {
+      rv = nghttp2_hd_inflate_change_table_size(&session->hd_inflater,
+                                                min_header_table_size);
+      if (rv != 0) {
+        return rv;
+      }
+    }
+
+    rv = nghttp2_hd_inflate_change_table_size(&session->hd_inflater,
+                                              header_table_size);
+    if (rv != 0) {
+      return rv;
+    }
+  }
+  if (new_initial_window_size != -1) {
+    rv = session_update_local_initial_window_size(
+        session, new_initial_window_size,
+        (int32_t)session->local_settings.initial_window_size);
+    if (rv != 0) {
+      return rv;
+    }
+  }
+
+  for (i = 0; i < niv; ++i) {
+    switch (iv[i].settings_id) {
+    case NGHTTP2_SETTINGS_HEADER_TABLE_SIZE:
+      session->local_settings.header_table_size = iv[i].value;
+      break;
+    case NGHTTP2_SETTINGS_ENABLE_PUSH:
+      session->local_settings.enable_push = iv[i].value;
+      break;
+    case NGHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS:
+      session->local_settings.max_concurrent_streams = iv[i].value;
+      break;
+    case NGHTTP2_SETTINGS_INITIAL_WINDOW_SIZE:
+      session->local_settings.initial_window_size = iv[i].value;
+      break;
+    case NGHTTP2_SETTINGS_MAX_FRAME_SIZE:
+      session->local_settings.max_frame_size = iv[i].value;
+      break;
+    case NGHTTP2_SETTINGS_MAX_HEADER_LIST_SIZE:
+      session->local_settings.max_header_list_size = iv[i].value;
+      break;
+    case NGHTTP2_SETTINGS_ENABLE_CONNECT_PROTOCOL:
+      session->local_settings.enable_connect_protocol = iv[i].value;
+      break;
+    }
+  }
+
+  return 0;
+}
+
+int nghttp2_session_on_settings_received(nghttp2_session *session,
+                                         nghttp2_frame *frame, int noack) {
+  int rv;
+  size_t i;
+  nghttp2_mem *mem;
+  nghttp2_inflight_settings *settings;
+
+  mem = &session->mem;
+
+  if (frame->hd.stream_id != 0) {
+    return session_handle_invalid_connection(session, frame, NGHTTP2_ERR_PROTO,
+                                             "SETTINGS: stream_id != 0");
+  }
+  if (frame->hd.flags & NGHTTP2_FLAG_ACK) {
+    if (frame->settings.niv != 0) {
+      return session_handle_invalid_connection(
+          session, frame, NGHTTP2_ERR_FRAME_SIZE_ERROR,
+          "SETTINGS: ACK and payload != 0");
+    }
+
+    settings = session->inflight_settings_head;
+
+    if (!settings) {
+      return session_handle_invalid_connection(
+          session, frame, NGHTTP2_ERR_PROTO, "SETTINGS: unexpected ACK");
+    }
+
+    rv = nghttp2_session_update_local_settings(session, settings->iv,
+                                               settings->niv);
+
+    session->inflight_settings_head = settings->next;
+
+    inflight_settings_del(settings, mem);
+
+    if (rv != 0) {
+      if (nghttp2_is_fatal(rv)) {
+        return rv;
+      }
+      return session_handle_invalid_connection(session, frame, rv, NULL);
+    }
+    return session_call_on_frame_received(session, frame);
+  }
+
+  if (!session->remote_settings_received) {
+    session->remote_settings.max_concurrent_streams =
+        NGHTTP2_DEFAULT_MAX_CONCURRENT_STREAMS;
+    session->remote_settings_received = 1;
+  }
+
+  for (i = 0; i < frame->settings.niv; ++i) {
+    nghttp2_settings_entry *entry = &frame->settings.iv[i];
+
+    switch (entry->settings_id) {
+    case NGHTTP2_SETTINGS_HEADER_TABLE_SIZE:
+
+      rv = nghttp2_hd_deflate_change_table_size(&session->hd_deflater,
+                                                entry->value);
+      if (rv != 0) {
+        if (nghttp2_is_fatal(rv)) {
+          return rv;
+        } else {
+          return session_handle_invalid_connection(
+              session, frame, NGHTTP2_ERR_HEADER_COMP, NULL);
+        }
+      }
+
+      session->remote_settings.header_table_size = entry->value;
+
+      break;
+    case NGHTTP2_SETTINGS_ENABLE_PUSH:
+
+      if (entry->value != 0 && entry->value != 1) {
+        return session_handle_invalid_connection(
+            session, frame, NGHTTP2_ERR_PROTO,
+            "SETTINGS: invalid SETTINGS_ENBLE_PUSH");
+      }
+
+      if (!session->server && entry->value != 0) {
+        return session_handle_invalid_connection(
+            session, frame, NGHTTP2_ERR_PROTO,
+            "SETTINGS: server attempted to enable push");
+      }
+
+      session->remote_settings.enable_push = entry->value;
+
+      break;
+    case NGHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS:
+
+      session->remote_settings.max_concurrent_streams = entry->value;
+
+      break;
+    case NGHTTP2_SETTINGS_INITIAL_WINDOW_SIZE:
+
+      /* Update the initial window size of the all active streams */
+      /* Check that initial_window_size < (1u << 31) */
+      if (entry->value > NGHTTP2_MAX_WINDOW_SIZE) {
+        return session_handle_invalid_connection(
+            session, frame, NGHTTP2_ERR_FLOW_CONTROL,
+            "SETTINGS: too large SETTINGS_INITIAL_WINDOW_SIZE");
+      }
+
+      rv = session_update_remote_initial_window_size(session,
+                                                     (int32_t)entry->value);
+
+      if (nghttp2_is_fatal(rv)) {
+        return rv;
+      }
+
+      if (rv != 0) {
+        return session_handle_invalid_connection(
+            session, frame, NGHTTP2_ERR_FLOW_CONTROL, NULL);
+      }
+
+      session->remote_settings.initial_window_size = entry->value;
+
+      break;
+    case NGHTTP2_SETTINGS_MAX_FRAME_SIZE:
+
+      if (entry->value < NGHTTP2_MAX_FRAME_SIZE_MIN ||
+          entry->value > NGHTTP2_MAX_FRAME_SIZE_MAX) {
+        return session_handle_invalid_connection(
+            session, frame, NGHTTP2_ERR_PROTO,
+            "SETTINGS: invalid SETTINGS_MAX_FRAME_SIZE");
+      }
+
+      session->remote_settings.max_frame_size = entry->value;
+
+      break;
+    case NGHTTP2_SETTINGS_MAX_HEADER_LIST_SIZE:
+
+      session->remote_settings.max_header_list_size = entry->value;
+
+      break;
+    case NGHTTP2_SETTINGS_ENABLE_CONNECT_PROTOCOL:
+
+      if (entry->value != 0 && entry->value != 1) {
+        return session_handle_invalid_connection(
+            session, frame, NGHTTP2_ERR_PROTO,
+            "SETTINGS: invalid SETTINGS_ENABLE_CONNECT_PROTOCOL");
+      }
+
+      if (!session->server &&
+          session->remote_settings.enable_connect_protocol &&
+          entry->value == 0) {
+        return session_handle_invalid_connection(
+            session, frame, NGHTTP2_ERR_PROTO,
+            "SETTINGS: server attempted to disable "
+            "SETTINGS_ENABLE_CONNECT_PROTOCOL");
+      }
+
+      session->remote_settings.enable_connect_protocol = entry->value;
+
+      break;
+    }
+  }
+
+  if (!noack && !session_is_closing(session)) {
+    rv = nghttp2_session_add_settings(session, NGHTTP2_FLAG_ACK, NULL, 0);
+
+    if (rv != 0) {
+      if (nghttp2_is_fatal(rv)) {
+        return rv;
+      }
+
+      return session_handle_invalid_connection(session, frame,
+                                               NGHTTP2_ERR_INTERNAL, NULL);
+    }
+  }
+
+  return session_call_on_frame_received(session, frame);
+}
+
+static int session_process_settings_frame(nghttp2_session *session) {
+  nghttp2_inbound_frame *iframe = &session->iframe;
+  nghttp2_frame *frame = &iframe->frame;
+  size_t i;
+  nghttp2_settings_entry min_header_size_entry;
+
+  if (iframe->max_niv) {
+    min_header_size_entry = iframe->iv[iframe->max_niv - 1];
+
+    if (min_header_size_entry.value < UINT32_MAX) {
+      /* If we have less value, then we must have
+         SETTINGS_HEADER_TABLE_SIZE in i < iframe->niv */
+      for (i = 0; i < iframe->niv; ++i) {
+        if (iframe->iv[i].settings_id == NGHTTP2_SETTINGS_HEADER_TABLE_SIZE) {
+          break;
+        }
+      }
+
+      assert(i < iframe->niv);
+
+      if (min_header_size_entry.value != iframe->iv[i].value) {
+        iframe->iv[iframe->niv++] = iframe->iv[i];
+        iframe->iv[i] = min_header_size_entry;
+      }
+    }
+  }
+
+  nghttp2_frame_unpack_settings_payload(&frame->settings, iframe->iv,
+                                        iframe->niv);
+
+  iframe->iv = NULL;
+  iframe->niv = 0;
+  iframe->max_niv = 0;
+
+  return nghttp2_session_on_settings_received(session, frame, 0 /* ACK */);
+}
+
+int nghttp2_session_on_push_promise_received(nghttp2_session *session,
+                                             nghttp2_frame *frame) {
+  int rv;
+  nghttp2_stream *stream;
+  nghttp2_stream *promised_stream;
+  nghttp2_priority_spec pri_spec;
+
+  if (frame->hd.stream_id == 0) {
+    return session_inflate_handle_invalid_connection(
+        session, frame, NGHTTP2_ERR_PROTO, "PUSH_PROMISE: stream_id == 0");
+  }
+  if (session->server || session->local_settings.enable_push == 0) {
+    return session_inflate_handle_invalid_connection(
+        session, frame, NGHTTP2_ERR_PROTO, "PUSH_PROMISE: push disabled");
+  }
+
+  if (!nghttp2_session_is_my_stream_id(session, frame->hd.stream_id)) {
+    return session_inflate_handle_invalid_connection(
+        session, frame, NGHTTP2_ERR_PROTO, "PUSH_PROMISE: invalid stream_id");
+  }
+
+  if (!session_allow_incoming_new_stream(session)) {
+    /* We just discard PUSH_PROMISE after GOAWAY was sent */
+    return NGHTTP2_ERR_IGN_HEADER_BLOCK;
+  }
+
+  if (!session_is_new_peer_stream_id(session,
+                                     frame->push_promise.promised_stream_id)) {
+    /* The spec says if an endpoint receives a PUSH_PROMISE with
+       illegal stream ID is subject to a connection error of type
+       PROTOCOL_ERROR. */
+    return session_inflate_handle_invalid_connection(
+        session, frame, NGHTTP2_ERR_PROTO,
+        "PUSH_PROMISE: invalid promised_stream_id");
+  }
+
+  if (session_detect_idle_stream(session, frame->hd.stream_id)) {
+    return session_inflate_handle_invalid_connection(
+        session, frame, NGHTTP2_ERR_PROTO, "PUSH_PROMISE: stream in idle");
+  }
+
+  session->last_recv_stream_id = frame->push_promise.promised_stream_id;
+  stream = nghttp2_session_get_stream(session, frame->hd.stream_id);
+  if (!stream || stream->state == NGHTTP2_STREAM_CLOSING ||
+      !session->pending_enable_push ||
+      session->num_incoming_reserved_streams >=
+          session->max_incoming_reserved_streams) {
+    /* Currently, client does not retain closed stream, so we don't
+       check NGHTTP2_SHUT_RD condition here. */
+
+    rv = nghttp2_session_add_rst_stream(
+        session, frame->push_promise.promised_stream_id, NGHTTP2_CANCEL);
+    if (rv != 0) {
+      return rv;
+    }
+    return NGHTTP2_ERR_IGN_HEADER_BLOCK;
+  }
+
+  if (stream->shut_flags & NGHTTP2_SHUT_RD) {
+    return session_inflate_handle_invalid_connection(
+        session, frame, NGHTTP2_ERR_STREAM_CLOSED,
+        "PUSH_PROMISE: stream closed");
+  }
+
+  nghttp2_priority_spec_init(&pri_spec, stream->stream_id,
+                             NGHTTP2_DEFAULT_WEIGHT, 0);
+
+  promised_stream = nghttp2_session_open_stream(
+      session, frame->push_promise.promised_stream_id, NGHTTP2_STREAM_FLAG_NONE,
+      &pri_spec, NGHTTP2_STREAM_RESERVED, NULL);
+
+  if (!promised_stream) {
+    return NGHTTP2_ERR_NOMEM;
+  }
+
+  /* We don't call nghttp2_session_adjust_closed_stream(), since we
+     don't keep closed stream in client side */
+
+  session->last_proc_stream_id = session->last_recv_stream_id;
+  rv = session_call_on_begin_headers(session, frame);
+  if (rv != 0) {
+    return rv;
+  }
+  return 0;
+}
+
+static int session_process_push_promise_frame(nghttp2_session *session) {
+  int rv;
+  nghttp2_inbound_frame *iframe = &session->iframe;
+  nghttp2_frame *frame = &iframe->frame;
+
+  rv = nghttp2_frame_unpack_push_promise_payload(&frame->push_promise,
+                                                 iframe->sbuf.pos);
+
+  if (rv != 0) {
+    return nghttp2_session_terminate_session_with_reason(
+        session, NGHTTP2_PROTOCOL_ERROR, "PUSH_PROMISE: could not unpack");
+  }
+
+  return nghttp2_session_on_push_promise_received(session, frame);
+}
+
+int nghttp2_session_on_ping_received(nghttp2_session *session,
+                                     nghttp2_frame *frame) {
+  int rv = 0;
+  if (frame->hd.stream_id != 0) {
+    return session_handle_invalid_connection(session, frame, NGHTTP2_ERR_PROTO,
+                                             "PING: stream_id != 0");
+  }
+  if ((session->opt_flags & NGHTTP2_OPTMASK_NO_AUTO_PING_ACK) == 0 &&
+      (frame->hd.flags & NGHTTP2_FLAG_ACK) == 0 &&
+      !session_is_closing(session)) {
+    /* Peer sent ping, so ping it back */
+    rv = nghttp2_session_add_ping(session, NGHTTP2_FLAG_ACK,
+                                  frame->ping.opaque_data);
+    if (rv != 0) {
+      return rv;
+    }
+  }
+  return session_call_on_frame_received(session, frame);
+}
+
+static int session_process_ping_frame(nghttp2_session *session) {
+  nghttp2_inbound_frame *iframe = &session->iframe;
+  nghttp2_frame *frame = &iframe->frame;
+
+  nghttp2_frame_unpack_ping_payload(&frame->ping, iframe->sbuf.pos);
+
+  return nghttp2_session_on_ping_received(session, frame);
+}
+
+int nghttp2_session_on_goaway_received(nghttp2_session *session,
+                                       nghttp2_frame *frame) {
+  int rv;
+
+  if (frame->hd.stream_id != 0) {
+    return session_handle_invalid_connection(session, frame, NGHTTP2_ERR_PROTO,
+                                             "GOAWAY: stream_id != 0");
+  }
+  /* Spec says Endpoints MUST NOT increase the value they send in the
+     last stream identifier. */
+  if ((frame->goaway.last_stream_id > 0 &&
+       !nghttp2_session_is_my_stream_id(session,
+                                        frame->goaway.last_stream_id)) ||
+      session->remote_last_stream_id < frame->goaway.last_stream_id) {
+    return session_handle_invalid_connection(session, frame, NGHTTP2_ERR_PROTO,
+                                             "GOAWAY: invalid last_stream_id");
+  }
+
+  session->goaway_flags |= NGHTTP2_GOAWAY_RECV;
+
+  session->remote_last_stream_id = frame->goaway.last_stream_id;
+
+  rv = session_call_on_frame_received(session, frame);
+
+  if (nghttp2_is_fatal(rv)) {
+    return rv;
+  }
+
+  return session_close_stream_on_goaway(session, frame->goaway.last_stream_id,
+                                        0);
+}
+
+static int session_process_goaway_frame(nghttp2_session *session) {
+  nghttp2_inbound_frame *iframe = &session->iframe;
+  nghttp2_frame *frame = &iframe->frame;
+
+  nghttp2_frame_unpack_goaway_payload(&frame->goaway, iframe->sbuf.pos,
+                                      iframe->lbuf.pos,
+                                      nghttp2_buf_len(&iframe->lbuf));
+
+  nghttp2_buf_wrap_init(&iframe->lbuf, NULL, 0);
+
+  return nghttp2_session_on_goaway_received(session, frame);
+}
+
+static int
+session_on_connection_window_update_received(nghttp2_session *session,
+                                             nghttp2_frame *frame) {
+  /* Handle connection-level flow control */
+  if (frame->window_update.window_size_increment == 0) {
+    return session_handle_invalid_connection(
+        session, frame, NGHTTP2_ERR_PROTO,
+        "WINDOW_UPDATE: window_size_increment == 0");
+  }
+
+  if (NGHTTP2_MAX_WINDOW_SIZE - frame->window_update.window_size_increment <
+      session->remote_window_size) {
+    return session_handle_invalid_connection(session, frame,
+                                             NGHTTP2_ERR_FLOW_CONTROL, NULL);
+  }
+  session->remote_window_size += frame->window_update.window_size_increment;
+
+  return session_call_on_frame_received(session, frame);
+}
+
+static int session_on_stream_window_update_received(nghttp2_session *session,
+                                                    nghttp2_frame *frame) {
+  int rv;
+  nghttp2_stream *stream;
+
+  if (session_detect_idle_stream(session, frame->hd.stream_id)) {
+    return session_handle_invalid_connection(session, frame, NGHTTP2_ERR_PROTO,
+                                             "WINDOW_UPDATE to idle stream");
+  }
+
+  stream = nghttp2_session_get_stream(session, frame->hd.stream_id);
+  if (!stream) {
+    return 0;
+  }
+  if (state_reserved_remote(session, stream)) {
+    return session_handle_invalid_connection(
+        session, frame, NGHTTP2_ERR_PROTO, "WINDOW_UPADATE to reserved stream");
+  }
+  if (frame->window_update.window_size_increment == 0) {
+    return session_handle_invalid_connection(
+        session, frame, NGHTTP2_ERR_PROTO,
+        "WINDOW_UPDATE: window_size_increment == 0");
+  }
+  if (NGHTTP2_MAX_WINDOW_SIZE - frame->window_update.window_size_increment <
+      stream->remote_window_size) {
+    return session_handle_invalid_stream(session, frame,
+                                         NGHTTP2_ERR_FLOW_CONTROL);
+  }
+  stream->remote_window_size += frame->window_update.window_size_increment;
+
+  if (stream->remote_window_size > 0 &&
+      nghttp2_stream_check_deferred_by_flow_control(stream)) {
+
+    rv = nghttp2_stream_resume_deferred_item(
+        stream, NGHTTP2_STREAM_FLAG_DEFERRED_FLOW_CONTROL);
+
+    if (nghttp2_is_fatal(rv)) {
+      return rv;
+    }
+  }
+  return session_call_on_frame_received(session, frame);
+}
+
+int nghttp2_session_on_window_update_received(nghttp2_session *session,
+                                              nghttp2_frame *frame) {
+  if (frame->hd.stream_id == 0) {
+    return session_on_connection_window_update_received(session, frame);
+  } else {
+    return session_on_stream_window_update_received(session, frame);
+  }
+}
+
+static int session_process_window_update_frame(nghttp2_session *session) {
+  nghttp2_inbound_frame *iframe = &session->iframe;
+  nghttp2_frame *frame = &iframe->frame;
+
+  nghttp2_frame_unpack_window_update_payload(&frame->window_update,
+                                             iframe->sbuf.pos);
+
+  return nghttp2_session_on_window_update_received(session, frame);
+}
+
+int nghttp2_session_on_altsvc_received(nghttp2_session *session,
+                                       nghttp2_frame *frame) {
+  nghttp2_ext_altsvc *altsvc;
+  nghttp2_stream *stream;
+
+  altsvc = frame->ext.payload;
+
+  /* session->server case has been excluded */
+
+  if (frame->hd.stream_id == 0) {
+    if (altsvc->origin_len == 0) {
+      return session_call_on_invalid_frame_recv_callback(session, frame,
+                                                         NGHTTP2_ERR_PROTO);
+    }
+  } else {
+    if (altsvc->origin_len > 0) {
+      return session_call_on_invalid_frame_recv_callback(session, frame,
+                                                         NGHTTP2_ERR_PROTO);
+    }
+
+    stream = nghttp2_session_get_stream(session, frame->hd.stream_id);
+    if (!stream) {
+      return 0;
+    }
+
+    if (stream->state == NGHTTP2_STREAM_CLOSING) {
+      return 0;
+    }
+  }
+
+  if (altsvc->field_value_len == 0) {
+    return session_call_on_invalid_frame_recv_callback(session, frame,
+                                                       NGHTTP2_ERR_PROTO);
+  }
+
+  return session_call_on_frame_received(session, frame);
+}
+
+int nghttp2_session_on_origin_received(nghttp2_session *session,
+                                       nghttp2_frame *frame) {
+  return session_call_on_frame_received(session, frame);
+}
+
+static int session_process_altsvc_frame(nghttp2_session *session) {
+  nghttp2_inbound_frame *iframe = &session->iframe;
+  nghttp2_frame *frame = &iframe->frame;
+
+  nghttp2_frame_unpack_altsvc_payload(
+      &frame->ext, nghttp2_get_uint16(iframe->sbuf.pos), iframe->lbuf.pos,
+      nghttp2_buf_len(&iframe->lbuf));
+
+  /* nghttp2_frame_unpack_altsvc_payload steals buffer from
+     iframe->lbuf */
+  nghttp2_buf_wrap_init(&iframe->lbuf, NULL, 0);
+
+  return nghttp2_session_on_altsvc_received(session, frame);
+}
+
+static int session_process_origin_frame(nghttp2_session *session) {
+  nghttp2_inbound_frame *iframe = &session->iframe;
+  nghttp2_frame *frame = &iframe->frame;
+  nghttp2_mem *mem = &session->mem;
+  int rv;
+
+  rv = nghttp2_frame_unpack_origin_payload(&frame->ext, iframe->lbuf.pos,
+                                           nghttp2_buf_len(&iframe->lbuf), mem);
+  if (rv != 0) {
+    if (nghttp2_is_fatal(rv)) {
+      return rv;
+    }
+    /* Ignore ORIGIN frame which cannot be parsed. */
+    return 0;
+  }
+
+  return nghttp2_session_on_origin_received(session, frame);
+}
+
+static int session_process_extension_frame(nghttp2_session *session) {
+  int rv;
+  nghttp2_inbound_frame *iframe = &session->iframe;
+  nghttp2_frame *frame = &iframe->frame;
+
+  rv = session_call_unpack_extension_callback(session);
+  if (nghttp2_is_fatal(rv)) {
+    return rv;
+  }
+
+  /* This handles the case where rv == NGHTTP2_ERR_CANCEL as well */
+  if (rv != 0) {
+    return 0;
+  }
+
+  return session_call_on_frame_received(session, frame);
+}
+
+int nghttp2_session_on_data_received(nghttp2_session *session,
+                                     nghttp2_frame *frame) {
+  int rv = 0;
+  nghttp2_stream *stream;
+
+  /* We don't call on_frame_recv_callback if stream has been closed
+     already or being closed. */
+  stream = nghttp2_session_get_stream(session, frame->hd.stream_id);
+  if (!stream || stream->state == NGHTTP2_STREAM_CLOSING) {
+    /* This should be treated as stream error, but it results in lots
+       of RST_STREAM. So just ignore frame against nonexistent stream
+       for now. */
+    return 0;
+  }
+
+  if (session_enforce_http_messaging(session) &&
+      (frame->hd.flags & NGHTTP2_FLAG_END_STREAM)) {
+    if (nghttp2_http_on_remote_end_stream(stream) != 0) {
+      rv = nghttp2_session_add_rst_stream(session, stream->stream_id,
+                                          NGHTTP2_PROTOCOL_ERROR);
+      if (nghttp2_is_fatal(rv)) {
+        return rv;
+      }
+
+      nghttp2_stream_shutdown(stream, NGHTTP2_SHUT_RD);
+      /* Don't call nghttp2_session_close_stream_if_shut_rdwr because
+         RST_STREAM has been submitted. */
+      return 0;
+    }
+  }
+
+  rv = session_call_on_frame_received(session, frame);
+  if (nghttp2_is_fatal(rv)) {
+    return rv;
+  }
+
+  if (frame->hd.flags & NGHTTP2_FLAG_END_STREAM) {
+    nghttp2_stream_shutdown(stream, NGHTTP2_SHUT_RD);
+    rv = nghttp2_session_close_stream_if_shut_rdwr(session, stream);
+    if (nghttp2_is_fatal(rv)) {
+      return rv;
+    }
+  }
+  return 0;
+}
+
+/* For errors, this function only returns FATAL error. */
+static int session_process_data_frame(nghttp2_session *session) {
+  int rv;
+  nghttp2_frame *public_data_frame = &session->iframe.frame;
+  rv = nghttp2_session_on_data_received(session, public_data_frame);
+  if (nghttp2_is_fatal(rv)) {
+    return rv;
+  }
+  return 0;
+}
+
+/*
+ * Now we have SETTINGS synchronization, flow control error can be
+ * detected strictly. If DATA frame is received with length > 0 and
+ * current received window size + delta length is strictly larger than
+ * local window size, it is subject to FLOW_CONTROL_ERROR, so return
+ * -1. Note that local_window_size is calculated after SETTINGS ACK is
+ * received from peer, so peer must honor this limit. If the resulting
+ * recv_window_size is strictly larger than NGHTTP2_MAX_WINDOW_SIZE,
+ * return -1 too.
+ */
+static int adjust_recv_window_size(int32_t *recv_window_size_ptr, size_t delta,
+                                   int32_t local_window_size) {
+  if (*recv_window_size_ptr > local_window_size - (int32_t)delta ||
+      *recv_window_size_ptr > NGHTTP2_MAX_WINDOW_SIZE - (int32_t)delta) {
+    return -1;
+  }
+  *recv_window_size_ptr += (int32_t)delta;
+  return 0;
+}
+
+/*
+ * Accumulates received bytes |delta_size| for stream-level flow
+ * control and decides whether to send WINDOW_UPDATE to that stream.
+ * If NGHTTP2_OPT_NO_AUTO_WINDOW_UPDATE is set, WINDOW_UPDATE will not
+ * be sent.
+ *
+ * This function returns 0 if it succeeds, or one of the following
+ * negative error codes:
+ *
+ * NGHTTP2_ERR_NOMEM
+ *     Out of memory.
+ */
+static int session_update_recv_stream_window_size(nghttp2_session *session,
+                                                  nghttp2_stream *stream,
+                                                  size_t delta_size,
+                                                  int send_window_update) {
+  int rv;
+  rv = adjust_recv_window_size(&stream->recv_window_size, delta_size,
+                               stream->local_window_size);
+  if (rv != 0) {
+    return nghttp2_session_add_rst_stream(session, stream->stream_id,
+                                          NGHTTP2_FLOW_CONTROL_ERROR);
+  }
+  /* We don't have to send WINDOW_UPDATE if the data received is the
+     last chunk in the incoming stream. */
+  /* We have to use local_settings here because it is the constraint
+     the remote endpoint should honor. */
+  if (send_window_update &&
+      !(session->opt_flags & NGHTTP2_OPTMASK_NO_AUTO_WINDOW_UPDATE) &&
+      stream->window_update_queued == 0 &&
+      nghttp2_should_send_window_update(stream->local_window_size,
+                                        stream->recv_window_size)) {
+    rv = nghttp2_session_add_window_update(session, NGHTTP2_FLAG_NONE,
+                                           stream->stream_id,
+                                           stream->recv_window_size);
+    if (rv != 0) {
+      return rv;
+    }
+
+    stream->recv_window_size = 0;
+  }
+  return 0;
+}
+
+/*
+ * Accumulates received bytes |delta_size| for connection-level flow
+ * control and decides whether to send WINDOW_UPDATE to the
+ * connection.  If NGHTTP2_OPT_NO_AUTO_WINDOW_UPDATE is set,
+ * WINDOW_UPDATE will not be sent.
+ *
+ * This function returns 0 if it succeeds, or one of the following
+ * negative error codes:
+ *
+ * NGHTTP2_ERR_NOMEM
+ *     Out of memory.
+ */
+static int session_update_recv_connection_window_size(nghttp2_session *session,
+                                                      size_t delta_size) {
+  int rv;
+  rv = adjust_recv_window_size(&session->recv_window_size, delta_size,
+                               session->local_window_size);
+  if (rv != 0) {
+    return nghttp2_session_terminate_session(session,
+                                             NGHTTP2_FLOW_CONTROL_ERROR);
+  }
+  if (!(session->opt_flags & NGHTTP2_OPTMASK_NO_AUTO_WINDOW_UPDATE) &&
+      session->window_update_queued == 0 &&
+      nghttp2_should_send_window_update(session->local_window_size,
+                                        session->recv_window_size)) {
+    /* Use stream ID 0 to update connection-level flow control
+       window */
+    rv = nghttp2_session_add_window_update(session, NGHTTP2_FLAG_NONE, 0,
+                                           session->recv_window_size);
+    if (rv != 0) {
+      return rv;
+    }
+
+    session->recv_window_size = 0;
+  }
+  return 0;
+}
+
+static int session_update_consumed_size(nghttp2_session *session,
+                                        int32_t *consumed_size_ptr,
+                                        int32_t *recv_window_size_ptr,
+                                        uint8_t window_update_queued,
+                                        int32_t stream_id, size_t delta_size,
+                                        int32_t local_window_size) {
+  int32_t recv_size;
+  int rv;
+
+  if ((size_t)*consumed_size_ptr > NGHTTP2_MAX_WINDOW_SIZE - delta_size) {
+    return nghttp2_session_terminate_session(session,
+                                             NGHTTP2_FLOW_CONTROL_ERROR);
+  }
+
+  *consumed_size_ptr += (int32_t)delta_size;
+
+  if (window_update_queued == 0) {
+    /* recv_window_size may be smaller than consumed_size, because it
+       may be decreased by negative value with
+       nghttp2_submit_window_update(). */
+    recv_size = nghttp2_min(*consumed_size_ptr, *recv_window_size_ptr);
+
+    if (nghttp2_should_send_window_update(local_window_size, recv_size)) {
+      rv = nghttp2_session_add_window_update(session, NGHTTP2_FLAG_NONE,
+                                             stream_id, recv_size);
+
+      if (rv != 0) {
+        return rv;
+      }
+
+      *recv_window_size_ptr -= recv_size;
+      *consumed_size_ptr -= recv_size;
+    }
+  }
+
+  return 0;
+}
+
+static int session_update_stream_consumed_size(nghttp2_session *session,
+                                               nghttp2_stream *stream,
+                                               size_t delta_size) {
+  return session_update_consumed_size(
+      session, &stream->consumed_size, &stream->recv_window_size,
+      stream->window_update_queued, stream->stream_id, delta_size,
+      stream->local_window_size);
+}
+
+static int session_update_connection_consumed_size(nghttp2_session *session,
+                                                   size_t delta_size) {
+  return session_update_consumed_size(
+      session, &session->consumed_size, &session->recv_window_size,
+      session->window_update_queued, 0, delta_size, session->local_window_size);
+}
+
+/*
+ * Checks that we can receive the DATA frame for stream, which is
+ * indicated by |session->iframe.frame.hd.stream_id|. If it is a
+ * connection error situation, GOAWAY frame will be issued by this
+ * function.
+ *
+ * If the DATA frame is allowed, returns 0.
+ *
+ * This function returns 0 if it succeeds, or one of the following
+ * negative error codes:
+ *
+ * NGHTTP2_ERR_IGN_PAYLOAD
+ *   The reception of DATA frame is connection error; or should be
+ *   ignored.
+ * NGHTTP2_ERR_NOMEM
+ *   Out of memory.
+ */
+static int session_on_data_received_fail_fast(nghttp2_session *session) {
+  int rv;
+  nghttp2_stream *stream;
+  nghttp2_inbound_frame *iframe;
+  int32_t stream_id;
+  const char *failure_reason;
+  uint32_t error_code = NGHTTP2_PROTOCOL_ERROR;
+
+  iframe = &session->iframe;
+  stream_id = iframe->frame.hd.stream_id;
+
+  if (stream_id == 0) {
+    /* The spec says that if a DATA frame is received whose stream ID
+       is 0, the recipient MUST respond with a connection error of
+       type PROTOCOL_ERROR. */
+    failure_reason = "DATA: stream_id == 0";
+    goto fail;
+  }
+
+  if (session_detect_idle_stream(session, stream_id)) {
+    failure_reason = "DATA: stream in idle";
+    error_code = NGHTTP2_PROTOCOL_ERROR;
+    goto fail;
+  }
+
+  stream = nghttp2_session_get_stream(session, stream_id);
+  if (!stream) {
+    stream = nghttp2_session_get_stream_raw(session, stream_id);
+    if (stream && (stream->shut_flags & NGHTTP2_SHUT_RD)) {
+      failure_reason = "DATA: stream closed";
+      error_code = NGHTTP2_STREAM_CLOSED;
+      goto fail;
+    }
+
+    return NGHTTP2_ERR_IGN_PAYLOAD;
+  }
+  if (stream->shut_flags & NGHTTP2_SHUT_RD) {
+    failure_reason = "DATA: stream in half-closed(remote)";
+    error_code = NGHTTP2_STREAM_CLOSED;
+    goto fail;
+  }
+
+  if (nghttp2_session_is_my_stream_id(session, stream_id)) {
+    if (stream->state == NGHTTP2_STREAM_CLOSING) {
+      return NGHTTP2_ERR_IGN_PAYLOAD;
+    }
+    if (stream->state != NGHTTP2_STREAM_OPENED) {
+      failure_reason = "DATA: stream not opened";
+      goto fail;
+    }
+    return 0;
+  }
+  if (stream->state == NGHTTP2_STREAM_RESERVED) {
+    failure_reason = "DATA: stream in reserved";
+    goto fail;
+  }
+  if (stream->state == NGHTTP2_STREAM_CLOSING) {
+    return NGHTTP2_ERR_IGN_PAYLOAD;
+  }
+  return 0;
+fail:
+  rv = nghttp2_session_terminate_session_with_reason(session, error_code,
+                                                     failure_reason);
+  if (nghttp2_is_fatal(rv)) {
+    return rv;
+  }
+  return NGHTTP2_ERR_IGN_PAYLOAD;
+}
+
+static size_t inbound_frame_payload_readlen(nghttp2_inbound_frame *iframe,
+                                            const uint8_t *in,
+                                            const uint8_t *last) {
+  return nghttp2_min((size_t)(last - in), iframe->payloadleft);
+}
+
+/*
+ * Resets iframe->sbuf and advance its mark pointer by |left| bytes.
+ */
+static void inbound_frame_set_mark(nghttp2_inbound_frame *iframe, size_t left) {
+  nghttp2_buf_reset(&iframe->sbuf);
+  iframe->sbuf.mark += left;
+}
+
+static size_t inbound_frame_buf_read(nghttp2_inbound_frame *iframe,
+                                     const uint8_t *in, const uint8_t *last) {
+  size_t readlen;
+
+  readlen =
+      nghttp2_min((size_t)(last - in), nghttp2_buf_mark_avail(&iframe->sbuf));
+
+  iframe->sbuf.last = nghttp2_cpymem(iframe->sbuf.last, in, readlen);
+
+  return readlen;
+}
+
+/*
+ * Unpacks SETTINGS entry in iframe->sbuf.
+ */
+static void inbound_frame_set_settings_entry(nghttp2_inbound_frame *iframe) {
+  nghttp2_settings_entry iv;
+  nghttp2_settings_entry *min_header_table_size_entry;
+  size_t i;
+
+  nghttp2_frame_unpack_settings_entry(&iv, iframe->sbuf.pos);
+
+  switch (iv.settings_id) {
+  case NGHTTP2_SETTINGS_HEADER_TABLE_SIZE:
+  case NGHTTP2_SETTINGS_ENABLE_PUSH:
+  case NGHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS:
+  case NGHTTP2_SETTINGS_INITIAL_WINDOW_SIZE:
+  case NGHTTP2_SETTINGS_MAX_FRAME_SIZE:
+  case NGHTTP2_SETTINGS_MAX_HEADER_LIST_SIZE:
+  case NGHTTP2_SETTINGS_ENABLE_CONNECT_PROTOCOL:
+    break;
+  default:
+    DEBUGF("recv: unknown settings id=0x%02x\n", iv.settings_id);
+
+    iframe->iv[iframe->niv++] = iv;
+
+    return;
+  }
+
+  for (i = 0; i < iframe->niv; ++i) {
+    if (iframe->iv[i].settings_id == iv.settings_id) {
+      iframe->iv[i] = iv;
+      break;
+    }
+  }
+
+  if (i == iframe->niv) {
+    iframe->iv[iframe->niv++] = iv;
+  }
+
+  if (iv.settings_id == NGHTTP2_SETTINGS_HEADER_TABLE_SIZE) {
+    /* Keep track of minimum value of SETTINGS_HEADER_TABLE_SIZE */
+    min_header_table_size_entry = &iframe->iv[iframe->max_niv - 1];
+
+    if (iv.value < min_header_table_size_entry->value) {
+      min_header_table_size_entry->value = iv.value;
+    }
+  }
+}
+
+/*
+ * Checks PADDED flags and set iframe->sbuf to read them accordingly.
+ * If padding is set, this function returns 1.  If no padding is set,
+ * this function returns 0.  On error, returns -1.
+ */
+static int inbound_frame_handle_pad(nghttp2_inbound_frame *iframe,
+                                    nghttp2_frame_hd *hd) {
+  if (hd->flags & NGHTTP2_FLAG_PADDED) {
+    if (hd->length < 1) {
+      return -1;
+    }
+    inbound_frame_set_mark(iframe, 1);
+    return 1;
+  }
+  DEBUGF("recv: no padding in payload\n");
+  return 0;
+}
+
+/*
+ * Computes number of padding based on flags. This function returns
+ * the calculated length if it succeeds, or -1.
+ */
+static ssize_t inbound_frame_compute_pad(nghttp2_inbound_frame *iframe) {
+  size_t padlen;
+
+  /* 1 for Pad Length field */
+  padlen = (size_t)(iframe->sbuf.pos[0] + 1);
+
+  DEBUGF("recv: padlen=%zu\n", padlen);
+
+  /* We cannot use iframe->frame.hd.length because of CONTINUATION */
+  if (padlen - 1 > iframe->payloadleft) {
+    return -1;
+  }
+
+  iframe->padlen = padlen;
+
+  return (ssize_t)padlen;
+}
+
+/*
+ * This function returns the effective payload length in the data of
+ * length |readlen| when the remaning payload is |payloadleft|. The
+ * |payloadleft| does not include |readlen|. If padding was started
+ * strictly before this data chunk, this function returns -1.
+ */
+static ssize_t inbound_frame_effective_readlen(nghttp2_inbound_frame *iframe,
+                                               size_t payloadleft,
+                                               size_t readlen) {
+  size_t trail_padlen =
+      nghttp2_frame_trail_padlen(&iframe->frame, iframe->padlen);
+
+  if (trail_padlen > payloadleft) {
+    size_t padlen;
+    padlen = trail_padlen - payloadleft;
+    if (readlen < padlen) {
+      return -1;
+    }
+    return (ssize_t)(readlen - padlen);
+  }
+  return (ssize_t)(readlen);
+}
+
+ssize_t nghttp2_session_mem_recv(nghttp2_session *session, const uint8_t *in,
+                                 size_t inlen) {
+  const uint8_t *first = in, *last = in + inlen;
+  nghttp2_inbound_frame *iframe = &session->iframe;
+  size_t readlen;
+  ssize_t padlen;
+  int rv;
+  int busy = 0;
+  nghttp2_frame_hd cont_hd;
+  nghttp2_stream *stream;
+  size_t pri_fieldlen;
+  nghttp2_mem *mem;
+
+  DEBUGF("recv: connection recv_window_size=%d, local_window=%d\n",
+         session->recv_window_size, session->local_window_size);
+
+  mem = &session->mem;
+
+  /* We may have idle streams more than we expect (e.g.,
+     nghttp2_session_change_stream_priority() or
+     nghttp2_session_create_idle_stream()).  Adjust them here. */
+  rv = nghttp2_session_adjust_idle_stream(session);
+  if (nghttp2_is_fatal(rv)) {
+    return rv;
+  }
+
+  if (!nghttp2_session_want_read(session)) {
+    return (ssize_t)inlen;
+  }
+
+  for (;;) {
+    switch (iframe->state) {
+    case NGHTTP2_IB_READ_CLIENT_MAGIC:
+      readlen = nghttp2_min(inlen, iframe->payloadleft);
+
+      if (memcmp(&NGHTTP2_CLIENT_MAGIC[NGHTTP2_CLIENT_MAGIC_LEN -
+                                       iframe->payloadleft],
+                 in, readlen) != 0) {
+        return NGHTTP2_ERR_BAD_CLIENT_MAGIC;
+      }
+
+      iframe->payloadleft -= readlen;
+      in += readlen;
+
+      if (iframe->payloadleft == 0) {
+        session_inbound_frame_reset(session);
+        iframe->state = NGHTTP2_IB_READ_FIRST_SETTINGS;
+      }
+
+      break;
+    case NGHTTP2_IB_READ_FIRST_SETTINGS:
+      DEBUGF("recv: [IB_READ_FIRST_SETTINGS]\n");
+
+      readlen = inbound_frame_buf_read(iframe, in, last);
+      in += readlen;
+
+      if (nghttp2_buf_mark_avail(&iframe->sbuf)) {
+        return in - first;
+      }
+
+      if (iframe->sbuf.pos[3] != NGHTTP2_SETTINGS ||
+          (iframe->sbuf.pos[4] & NGHTTP2_FLAG_ACK)) {
+        rv = session_call_error_callback(
+            session, NGHTTP2_ERR_SETTINGS_EXPECTED,
+            "Remote peer returned unexpected data while we expected "
+            "SETTINGS frame.  Perhaps, peer does not support HTTP/2 "
+            "properly.");
+
+        if (nghttp2_is_fatal(rv)) {
+          return rv;
+        }
+
+        rv = nghttp2_session_terminate_session_with_reason(
+            session, NGHTTP2_PROTOCOL_ERROR, "SETTINGS expected");
+
+        if (nghttp2_is_fatal(rv)) {
+          return rv;
+        }
+
+        return (ssize_t)inlen;
+      }
+
+      iframe->state = NGHTTP2_IB_READ_HEAD;
+
+    /* Fall through */
+    case NGHTTP2_IB_READ_HEAD: {
+      int on_begin_frame_called = 0;
+
+      DEBUGF("recv: [IB_READ_HEAD]\n");
+
+      readlen = inbound_frame_buf_read(iframe, in, last);
+      in += readlen;
+
+      if (nghttp2_buf_mark_avail(&iframe->sbuf)) {
+        return in - first;
+      }
+
+      nghttp2_frame_unpack_frame_hd(&iframe->frame.hd, iframe->sbuf.pos);
+      iframe->payloadleft = iframe->frame.hd.length;
+
+      DEBUGF("recv: payloadlen=%zu, type=%u, flags=0x%02x, stream_id=%d\n",
+             iframe->frame.hd.length, iframe->frame.hd.type,
+             iframe->frame.hd.flags, iframe->frame.hd.stream_id);
+
+      if (iframe->frame.hd.length > session->local_settings.max_frame_size) {
+        DEBUGF("recv: length is too large %zu > %u\n", iframe->frame.hd.length,
+               session->local_settings.max_frame_size);
+
+        rv = nghttp2_session_terminate_session_with_reason(
+            session, NGHTTP2_FRAME_SIZE_ERROR, "too large frame size");
+
+        if (nghttp2_is_fatal(rv)) {
+          return rv;
+        }
+
+        return (ssize_t)inlen;
+      }
+
+      switch (iframe->frame.hd.type) {
+      case NGHTTP2_DATA: {
+        DEBUGF("recv: DATA\n");
+
+        iframe->frame.hd.flags &=
+            (NGHTTP2_FLAG_END_STREAM | NGHTTP2_FLAG_PADDED);
+        /* Check stream is open. If it is not open or closing,
+           ignore payload. */
+        busy = 1;
+
+        rv = session_on_data_received_fail_fast(session);
+        if (iframe->state == NGHTTP2_IB_IGN_ALL) {
+          return (ssize_t)inlen;
+        }
+        if (rv == NGHTTP2_ERR_IGN_PAYLOAD) {
+          DEBUGF("recv: DATA not allowed stream_id=%d\n",
+                 iframe->frame.hd.stream_id);
+          iframe->state = NGHTTP2_IB_IGN_DATA;
+          break;
+        }
+
+        if (nghttp2_is_fatal(rv)) {
+          return rv;
+        }
+
+        rv = inbound_frame_handle_pad(iframe, &iframe->frame.hd);
+        if (rv < 0) {
+          rv = nghttp2_session_terminate_session_with_reason(
+              session, NGHTTP2_PROTOCOL_ERROR,
+              "DATA: insufficient padding space");
+
+          if (nghttp2_is_fatal(rv)) {
+            return rv;
+          }
+          return (ssize_t)inlen;
+        }
+
+        if (rv == 1) {
+          iframe->state = NGHTTP2_IB_READ_PAD_DATA;
+          break;
+        }
+
+        iframe->state = NGHTTP2_IB_READ_DATA;
+        break;
+      }
+      case NGHTTP2_HEADERS:
+
+        DEBUGF("recv: HEADERS\n");
+
+        iframe->frame.hd.flags &=
+            (NGHTTP2_FLAG_END_STREAM | NGHTTP2_FLAG_END_HEADERS |
+             NGHTTP2_FLAG_PADDED | NGHTTP2_FLAG_PRIORITY);
+
+        rv = inbound_frame_handle_pad(iframe, &iframe->frame.hd);
+        if (rv < 0) {
+          rv = nghttp2_session_terminate_session_with_reason(
+              session, NGHTTP2_PROTOCOL_ERROR,
+              "HEADERS: insufficient padding space");
+          if (nghttp2_is_fatal(rv)) {
+            return rv;
+          }
+          return (ssize_t)inlen;
+        }
+
+        if (rv == 1) {
+          iframe->state = NGHTTP2_IB_READ_NBYTE;
+          break;
+        }
+
+        pri_fieldlen = nghttp2_frame_priority_len(iframe->frame.hd.flags);
+
+        if (pri_fieldlen > 0) {
+          if (iframe->payloadleft < pri_fieldlen) {
+            busy = 1;
+            iframe->state = NGHTTP2_IB_FRAME_SIZE_ERROR;
+            break;
+          }
+
+          iframe->state = NGHTTP2_IB_READ_NBYTE;
+
+          inbound_frame_set_mark(iframe, pri_fieldlen);
+
+          break;
+        }
+
+        /* Call on_begin_frame_callback here because
+           session_process_headers_frame() may call
+           on_begin_headers_callback */
+        rv = session_call_on_begin_frame(session, &iframe->frame.hd);
+
+        if (nghttp2_is_fatal(rv)) {
+          return rv;
+        }
+
+        on_begin_frame_called = 1;
+
+        rv = session_process_headers_frame(session);
+        if (nghttp2_is_fatal(rv)) {
+          return rv;
+        }
+
+        busy = 1;
+
+        if (iframe->state == NGHTTP2_IB_IGN_ALL) {
+          return (ssize_t)inlen;
+        }
+
+        if (rv == NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE) {
+          rv = nghttp2_session_add_rst_stream(
+              session, iframe->frame.hd.stream_id, NGHTTP2_INTERNAL_ERROR);
+          if (nghttp2_is_fatal(rv)) {
+            return rv;
+          }
+          iframe->state = NGHTTP2_IB_IGN_HEADER_BLOCK;
+          break;
+        }
+
+        if (rv == NGHTTP2_ERR_IGN_HEADER_BLOCK) {
+          iframe->state = NGHTTP2_IB_IGN_HEADER_BLOCK;
+          break;
+        }
+
+        iframe->state = NGHTTP2_IB_READ_HEADER_BLOCK;
+
+        break;
+      case NGHTTP2_PRIORITY:
+        DEBUGF("recv: PRIORITY\n");
+
+        iframe->frame.hd.flags = NGHTTP2_FLAG_NONE;
+
+        if (iframe->payloadleft != NGHTTP2_PRIORITY_SPECLEN) {
+          busy = 1;
+
+          iframe->state = NGHTTP2_IB_FRAME_SIZE_ERROR;
+
+          break;
+        }
+
+        iframe->state = NGHTTP2_IB_READ_NBYTE;
+
+        inbound_frame_set_mark(iframe, NGHTTP2_PRIORITY_SPECLEN);
+
+        break;
+      case NGHTTP2_RST_STREAM:
+      case NGHTTP2_WINDOW_UPDATE:
+#ifdef DEBUGBUILD
+        switch (iframe->frame.hd.type) {
+        case NGHTTP2_RST_STREAM:
+          DEBUGF("recv: RST_STREAM\n");
+          break;
+        case NGHTTP2_WINDOW_UPDATE:
+          DEBUGF("recv: WINDOW_UPDATE\n");
+          break;
+        }
+#endif /* DEBUGBUILD */
+
+        iframe->frame.hd.flags = NGHTTP2_FLAG_NONE;
+
+        if (iframe->payloadleft != 4) {
+          busy = 1;
+          iframe->state = NGHTTP2_IB_FRAME_SIZE_ERROR;
+          break;
+        }
+
+        iframe->state = NGHTTP2_IB_READ_NBYTE;
+
+        inbound_frame_set_mark(iframe, 4);
+
+        break;
+      case NGHTTP2_SETTINGS:
+        DEBUGF("recv: SETTINGS\n");
+
+        iframe->frame.hd.flags &= NGHTTP2_FLAG_ACK;
+
+        if ((iframe->frame.hd.length % NGHTTP2_FRAME_SETTINGS_ENTRY_LENGTH) ||
+            ((iframe->frame.hd.flags & NGHTTP2_FLAG_ACK) &&
+             iframe->payloadleft > 0)) {
+          busy = 1;
+          iframe->state = NGHTTP2_IB_FRAME_SIZE_ERROR;
+          break;
+        }
+
+        iframe->state = NGHTTP2_IB_READ_SETTINGS;
+
+        if (iframe->payloadleft) {
+          nghttp2_settings_entry *min_header_table_size_entry;
+
+          /* We allocate iv with additional one entry, to store the
+             minimum header table size. */
+          iframe->max_niv =
+              iframe->frame.hd.length / NGHTTP2_FRAME_SETTINGS_ENTRY_LENGTH + 1;
+
+          iframe->iv = nghttp2_mem_malloc(mem, sizeof(nghttp2_settings_entry) *
+                                                   iframe->max_niv);
+
+          if (!iframe->iv) {
+            return NGHTTP2_ERR_NOMEM;
+          }
+
+          min_header_table_size_entry = &iframe->iv[iframe->max_niv - 1];
+          min_header_table_size_entry->settings_id =
+              NGHTTP2_SETTINGS_HEADER_TABLE_SIZE;
+          min_header_table_size_entry->value = UINT32_MAX;
+
+          inbound_frame_set_mark(iframe, NGHTTP2_FRAME_SETTINGS_ENTRY_LENGTH);
+          break;
+        }
+
+        busy = 1;
+
+        inbound_frame_set_mark(iframe, 0);
+
+        break;
+      case NGHTTP2_PUSH_PROMISE:
+        DEBUGF("recv: PUSH_PROMISE\n");
+
+        iframe->frame.hd.flags &=
+            (NGHTTP2_FLAG_END_HEADERS | NGHTTP2_FLAG_PADDED);
+
+        rv = inbound_frame_handle_pad(iframe, &iframe->frame.hd);
+        if (rv < 0) {
+          rv = nghttp2_session_terminate_session_with_reason(
+              session, NGHTTP2_PROTOCOL_ERROR,
+              "PUSH_PROMISE: insufficient padding space");
+          if (nghttp2_is_fatal(rv)) {
+            return rv;
+          }
+          return (ssize_t)inlen;
+        }
+
+        if (rv == 1) {
+          iframe->state = NGHTTP2_IB_READ_NBYTE;
+          break;
+        }
+
+        if (iframe->payloadleft < 4) {
+          busy = 1;
+          iframe->state = NGHTTP2_IB_FRAME_SIZE_ERROR;
+          break;
+        }
+
+        iframe->state = NGHTTP2_IB_READ_NBYTE;
+
+        inbound_frame_set_mark(iframe, 4);
+
+        break;
+      case NGHTTP2_PING:
+        DEBUGF("recv: PING\n");
+
+        iframe->frame.hd.flags &= NGHTTP2_FLAG_ACK;
+
+        if (iframe->payloadleft != 8) {
+          busy = 1;
+          iframe->state = NGHTTP2_IB_FRAME_SIZE_ERROR;
+          break;
+        }
+
+        iframe->state = NGHTTP2_IB_READ_NBYTE;
+        inbound_frame_set_mark(iframe, 8);
+
+        break;
+      case NGHTTP2_GOAWAY:
+        DEBUGF("recv: GOAWAY\n");
+
+        iframe->frame.hd.flags = NGHTTP2_FLAG_NONE;
+
+        if (iframe->payloadleft < 8) {
+          busy = 1;
+          iframe->state = NGHTTP2_IB_FRAME_SIZE_ERROR;
+          break;
+        }
+
+        iframe->state = NGHTTP2_IB_READ_NBYTE;
+        inbound_frame_set_mark(iframe, 8);
+
+        break;
+      case NGHTTP2_CONTINUATION:
+        DEBUGF("recv: unexpected CONTINUATION\n");
+
+        /* Receiving CONTINUATION in this state are subject to
+           connection error of type PROTOCOL_ERROR */
+        rv = nghttp2_session_terminate_session_with_reason(
+            session, NGHTTP2_PROTOCOL_ERROR, "CONTINUATION: unexpected");
+        if (nghttp2_is_fatal(rv)) {
+          return rv;
+        }
+
+        return (ssize_t)inlen;
+      default:
+        DEBUGF("recv: extension frame\n");
+
+        if (check_ext_type_set(session->user_recv_ext_types,
+                               iframe->frame.hd.type)) {
+          if (!session->callbacks.unpack_extension_callback) {
+            /* Silently ignore unknown frame type. */
+
+            busy = 1;
+
+            iframe->state = NGHTTP2_IB_IGN_PAYLOAD;
+
+            break;
+          }
+
+          busy = 1;
+
+          iframe->state = NGHTTP2_IB_READ_EXTENSION_PAYLOAD;
+
+          break;
+        } else {
+          switch (iframe->frame.hd.type) {
+          case NGHTTP2_ALTSVC:
+            if ((session->builtin_recv_ext_types & NGHTTP2_TYPEMASK_ALTSVC) ==
+                0) {
+              busy = 1;
+              iframe->state = NGHTTP2_IB_IGN_PAYLOAD;
+              break;
+            }
+
+            DEBUGF("recv: ALTSVC\n");
+
+            iframe->frame.hd.flags = NGHTTP2_FLAG_NONE;
+            iframe->frame.ext.payload = &iframe->ext_frame_payload.altsvc;
+
+            if (session->server) {
+              busy = 1;
+              iframe->state = NGHTTP2_IB_IGN_PAYLOAD;
+              break;
+            }
+
+            if (iframe->payloadleft < 2) {
+              busy = 1;
+              iframe->state = NGHTTP2_IB_FRAME_SIZE_ERROR;
+              break;
+            }
+
+            busy = 1;
+
+            iframe->state = NGHTTP2_IB_READ_NBYTE;
+            inbound_frame_set_mark(iframe, 2);
+
+            break;
+          case NGHTTP2_ORIGIN:
+            if (!(session->builtin_recv_ext_types & NGHTTP2_TYPEMASK_ORIGIN)) {
+              busy = 1;
+              iframe->state = NGHTTP2_IB_IGN_PAYLOAD;
+              break;
+            }
+
+            DEBUGF("recv: ORIGIN\n");
+
+            iframe->frame.ext.payload = &iframe->ext_frame_payload.origin;
+
+            if (session->server || iframe->frame.hd.stream_id ||
+                (iframe->frame.hd.flags & 0xf0)) {
+              busy = 1;
+              iframe->state = NGHTTP2_IB_IGN_PAYLOAD;
+              break;
+            }
+
+            iframe->frame.hd.flags = NGHTTP2_FLAG_NONE;
+
+            if (iframe->payloadleft) {
+              iframe->raw_lbuf = nghttp2_mem_malloc(mem, iframe->payloadleft);
+
+              if (iframe->raw_lbuf == NULL) {
+                return NGHTTP2_ERR_NOMEM;
+              }
+
+              nghttp2_buf_wrap_init(&iframe->lbuf, iframe->raw_lbuf,
+                                    iframe->payloadleft);
+            } else {
+              busy = 1;
+            }
+
+            iframe->state = NGHTTP2_IB_READ_ORIGIN_PAYLOAD;
+
+            break;
+          default:
+            busy = 1;
+
+            iframe->state = NGHTTP2_IB_IGN_PAYLOAD;
+
+            break;
+          }
+        }
+      }
+
+      if (!on_begin_frame_called) {
+        switch (iframe->state) {
+        case NGHTTP2_IB_IGN_HEADER_BLOCK:
+        case NGHTTP2_IB_IGN_PAYLOAD:
+        case NGHTTP2_IB_FRAME_SIZE_ERROR:
+        case NGHTTP2_IB_IGN_DATA:
+        case NGHTTP2_IB_IGN_ALL:
+          break;
+        default:
+          rv = session_call_on_begin_frame(session, &iframe->frame.hd);
+
+          if (nghttp2_is_fatal(rv)) {
+            return rv;
+          }
+        }
+      }
+
+      break;
+    }
+    case NGHTTP2_IB_READ_NBYTE:
+      DEBUGF("recv: [IB_READ_NBYTE]\n");
+
+      readlen = inbound_frame_buf_read(iframe, in, last);
+      in += readlen;
+      iframe->payloadleft -= readlen;
+
+      DEBUGF("recv: readlen=%zu, payloadleft=%zu, left=%zd\n", readlen,
+             iframe->payloadleft, nghttp2_buf_mark_avail(&iframe->sbuf));
+
+      if (nghttp2_buf_mark_avail(&iframe->sbuf)) {
+        return in - first;
+      }
+
+      switch (iframe->frame.hd.type) {
+      case NGHTTP2_HEADERS:
+        if (iframe->padlen == 0 &&
+            (iframe->frame.hd.flags & NGHTTP2_FLAG_PADDED)) {
+          pri_fieldlen = nghttp2_frame_priority_len(iframe->frame.hd.flags);
+          padlen = inbound_frame_compute_pad(iframe);
+          if (padlen < 0 ||
+              (size_t)padlen + pri_fieldlen > 1 + iframe->payloadleft) {
+            rv = nghttp2_session_terminate_session_with_reason(
+                session, NGHTTP2_PROTOCOL_ERROR, "HEADERS: invalid padding");
+            if (nghttp2_is_fatal(rv)) {
+              return rv;
+            }
+            return (ssize_t)inlen;
+          }
+          iframe->frame.headers.padlen = (size_t)padlen;
+
+          if (pri_fieldlen > 0) {
+            if (iframe->payloadleft < pri_fieldlen) {
+              busy = 1;
+              iframe->state = NGHTTP2_IB_FRAME_SIZE_ERROR;
+              break;
+            }
+            iframe->state = NGHTTP2_IB_READ_NBYTE;
+            inbound_frame_set_mark(iframe, pri_fieldlen);
+            break;
+          } else {
+            /* Truncate buffers used for padding spec */
+            inbound_frame_set_mark(iframe, 0);
+          }
+        }
+
+        rv = session_process_headers_frame(session);
+        if (nghttp2_is_fatal(rv)) {
+          return rv;
+        }
+
+        busy = 1;
+
+        if (iframe->state == NGHTTP2_IB_IGN_ALL) {
+          return (ssize_t)inlen;
+        }
+
+        if (rv == NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE) {
+          rv = nghttp2_session_add_rst_stream(
+              session, iframe->frame.hd.stream_id, NGHTTP2_INTERNAL_ERROR);
+          if (nghttp2_is_fatal(rv)) {
+            return rv;
+          }
+          iframe->state = NGHTTP2_IB_IGN_HEADER_BLOCK;
+          break;
+        }
+
+        if (rv == NGHTTP2_ERR_IGN_HEADER_BLOCK) {
+          iframe->state = NGHTTP2_IB_IGN_HEADER_BLOCK;
+          break;
+        }
+
+        iframe->state = NGHTTP2_IB_READ_HEADER_BLOCK;
+
+        break;
+      case NGHTTP2_PRIORITY:
+        rv = session_process_priority_frame(session);
+        if (nghttp2_is_fatal(rv)) {
+          return rv;
+        }
+
+        if (iframe->state == NGHTTP2_IB_IGN_ALL) {
+          return (ssize_t)inlen;
+        }
+
+        session_inbound_frame_reset(session);
+
+        break;
+      case NGHTTP2_RST_STREAM:
+        rv = session_process_rst_stream_frame(session);
+        if (nghttp2_is_fatal(rv)) {
+          return rv;
+        }
+
+        if (iframe->state == NGHTTP2_IB_IGN_ALL) {
+          return (ssize_t)inlen;
+        }
+
+        session_inbound_frame_reset(session);
+
+        break;
+      case NGHTTP2_PUSH_PROMISE:
+        if (iframe->padlen == 0 &&
+            (iframe->frame.hd.flags & NGHTTP2_FLAG_PADDED)) {
+          padlen = inbound_frame_compute_pad(iframe);
+          if (padlen < 0 || (size_t)padlen + 4 /* promised stream id */
+                                > 1 + iframe->payloadleft) {
+            rv = nghttp2_session_terminate_session_with_reason(
+                session, NGHTTP2_PROTOCOL_ERROR,
+                "PUSH_PROMISE: invalid padding");
+            if (nghttp2_is_fatal(rv)) {
+              return rv;
+            }
+            return (ssize_t)inlen;
+          }
+
+          iframe->frame.push_promise.padlen = (size_t)padlen;
+
+          if (iframe->payloadleft < 4) {
+            busy = 1;
+            iframe->state = NGHTTP2_IB_FRAME_SIZE_ERROR;
+            break;
+          }
+
+          iframe->state = NGHTTP2_IB_READ_NBYTE;
+
+          inbound_frame_set_mark(iframe, 4);
+
+          break;
+        }
+
+        rv = session_process_push_promise_frame(session);
+        if (nghttp2_is_fatal(rv)) {
+          return rv;
+        }
+
+        busy = 1;
+
+        if (iframe->state == NGHTTP2_IB_IGN_ALL) {
+          return (ssize_t)inlen;
+        }
+
+        if (rv == NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE) {
+          rv = nghttp2_session_add_rst_stream(
+              session, iframe->frame.push_promise.promised_stream_id,
+              NGHTTP2_INTERNAL_ERROR);
+          if (nghttp2_is_fatal(rv)) {
+            return rv;
+          }
+          iframe->state = NGHTTP2_IB_IGN_HEADER_BLOCK;
+          break;
+        }
+
+        if (rv == NGHTTP2_ERR_IGN_HEADER_BLOCK) {
+          iframe->state = NGHTTP2_IB_IGN_HEADER_BLOCK;
+          break;
+        }
+
+        iframe->state = NGHTTP2_IB_READ_HEADER_BLOCK;
+
+        break;
+      case NGHTTP2_PING:
+        rv = session_process_ping_frame(session);
+        if (nghttp2_is_fatal(rv)) {
+          return rv;
+        }
+
+        if (iframe->state == NGHTTP2_IB_IGN_ALL) {
+          return (ssize_t)inlen;
+        }
+
+        session_inbound_frame_reset(session);
+
+        break;
+      case NGHTTP2_GOAWAY: {
+        size_t debuglen;
+
+        /* 8 is Last-stream-ID + Error Code */
+        debuglen = iframe->frame.hd.length - 8;
+
+        if (debuglen > 0) {
+          iframe->raw_lbuf = nghttp2_mem_malloc(mem, debuglen);
+
+          if (iframe->raw_lbuf == NULL) {
+            return NGHTTP2_ERR_NOMEM;
+          }
+
+          nghttp2_buf_wrap_init(&iframe->lbuf, iframe->raw_lbuf, debuglen);
+        }
+
+        busy = 1;
+
+        iframe->state = NGHTTP2_IB_READ_GOAWAY_DEBUG;
+
+        break;
+      }
+      case NGHTTP2_WINDOW_UPDATE:
+        rv = session_process_window_update_frame(session);
+        if (nghttp2_is_fatal(rv)) {
+          return rv;
+        }
+
+        if (iframe->state == NGHTTP2_IB_IGN_ALL) {
+          return (ssize_t)inlen;
+        }
+
+        session_inbound_frame_reset(session);
+
+        break;
+      case NGHTTP2_ALTSVC: {
+        size_t origin_len;
+
+        origin_len = nghttp2_get_uint16(iframe->sbuf.pos);
+
+        DEBUGF("recv: origin_len=%zu\n", origin_len);
+
+        if (origin_len > iframe->payloadleft) {
+          busy = 1;
+          iframe->state = NGHTTP2_IB_FRAME_SIZE_ERROR;
+          break;
+        }
+
+        if (iframe->frame.hd.length > 2) {
+          iframe->raw_lbuf =
+              nghttp2_mem_malloc(mem, iframe->frame.hd.length - 2);
+
+          if (iframe->raw_lbuf == NULL) {
+            return NGHTTP2_ERR_NOMEM;
+          }
+
+          nghttp2_buf_wrap_init(&iframe->lbuf, iframe->raw_lbuf,
+                                iframe->frame.hd.length);
+        }
+
+        busy = 1;
+
+        iframe->state = NGHTTP2_IB_READ_ALTSVC_PAYLOAD;
+
+        break;
+      }
+      default:
+        /* This is unknown frame */
+        session_inbound_frame_reset(session);
+
+        break;
+      }
+      break;
+    case NGHTTP2_IB_READ_HEADER_BLOCK:
+    case NGHTTP2_IB_IGN_HEADER_BLOCK: {
+      ssize_t data_readlen;
+      size_t trail_padlen;
+      int final;
+#ifdef DEBUGBUILD
+      if (iframe->state == NGHTTP2_IB_READ_HEADER_BLOCK) {
+        DEBUGF("recv: [IB_READ_HEADER_BLOCK]\n");
+      } else {
+        DEBUGF("recv: [IB_IGN_HEADER_BLOCK]\n");
+      }
+#endif /* DEBUGBUILD */
+
+      readlen = inbound_frame_payload_readlen(iframe, in, last);
+
+      DEBUGF("recv: readlen=%zu, payloadleft=%zu\n", readlen,
+             iframe->payloadleft - readlen);
+
+      data_readlen = inbound_frame_effective_readlen(
+          iframe, iframe->payloadleft - readlen, readlen);
+
+      if (data_readlen == -1) {
+        /* everything is padding */
+        data_readlen = 0;
+      }
+
+      trail_padlen = nghttp2_frame_trail_padlen(&iframe->frame, iframe->padlen);
+
+      final = (iframe->frame.hd.flags & NGHTTP2_FLAG_END_HEADERS) &&
+              iframe->payloadleft - (size_t)data_readlen == trail_padlen;
+
+      if (data_readlen > 0 || (data_readlen == 0 && final)) {
+        size_t hd_proclen = 0;
+
+        DEBUGF("recv: block final=%d\n", final);
+
+        rv =
+            inflate_header_block(session, &iframe->frame, &hd_proclen,
+                                 (uint8_t *)in, (size_t)data_readlen, final,
+                                 iframe->state == NGHTTP2_IB_READ_HEADER_BLOCK);
+
+        if (nghttp2_is_fatal(rv)) {
+          return rv;
+        }
+
+        if (iframe->state == NGHTTP2_IB_IGN_ALL) {
+          return (ssize_t)inlen;
+        }
+
+        if (rv == NGHTTP2_ERR_PAUSE) {
+          in += hd_proclen;
+          iframe->payloadleft -= hd_proclen;
+
+          return in - first;
+        }
+
+        if (rv == NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE) {
+          /* The application says no more headers. We decompress the
+             rest of the header block but not invoke on_header_callback
+             and on_frame_recv_callback. */
+          in += hd_proclen;
+          iframe->payloadleft -= hd_proclen;
+
+          /* Use promised stream ID for PUSH_PROMISE */
+          rv = nghttp2_session_add_rst_stream(
+              session,
+              iframe->frame.hd.type == NGHTTP2_PUSH_PROMISE
+                  ? iframe->frame.push_promise.promised_stream_id
+                  : iframe->frame.hd.stream_id,
+              NGHTTP2_INTERNAL_ERROR);
+          if (nghttp2_is_fatal(rv)) {
+            return rv;
+          }
+          busy = 1;
+          iframe->state = NGHTTP2_IB_IGN_HEADER_BLOCK;
+          break;
+        }
+
+        in += readlen;
+        iframe->payloadleft -= readlen;
+
+        if (rv == NGHTTP2_ERR_HEADER_COMP) {
+          /* GOAWAY is already issued */
+          if (iframe->payloadleft == 0) {
+            session_inbound_frame_reset(session);
+          } else {
+            busy = 1;
+            iframe->state = NGHTTP2_IB_IGN_PAYLOAD;
+          }
+          break;
+        }
+      } else {
+        in += readlen;
+        iframe->payloadleft -= readlen;
+      }
+
+      if (iframe->payloadleft) {
+        break;
+      }
+
+      if ((iframe->frame.hd.flags & NGHTTP2_FLAG_END_HEADERS) == 0) {
+
+        inbound_frame_set_mark(iframe, NGHTTP2_FRAME_HDLEN);
+
+        iframe->padlen = 0;
+
+        if (iframe->state == NGHTTP2_IB_READ_HEADER_BLOCK) {
+          iframe->state = NGHTTP2_IB_EXPECT_CONTINUATION;
+        } else {
+          iframe->state = NGHTTP2_IB_IGN_CONTINUATION;
+        }
+      } else {
+        if (iframe->state == NGHTTP2_IB_READ_HEADER_BLOCK) {
+          rv = session_after_header_block_received(session);
+          if (nghttp2_is_fatal(rv)) {
+            return rv;
+          }
+        }
+        session_inbound_frame_reset(session);
+      }
+      break;
+    }
+    case NGHTTP2_IB_IGN_PAYLOAD:
+      DEBUGF("recv: [IB_IGN_PAYLOAD]\n");
+
+      readlen = inbound_frame_payload_readlen(iframe, in, last);
+      iframe->payloadleft -= readlen;
+      in += readlen;
+
+      DEBUGF("recv: readlen=%zu, payloadleft=%zu\n", readlen,
+             iframe->payloadleft);
+
+      if (iframe->payloadleft) {
+        break;
+      }
+
+      switch (iframe->frame.hd.type) {
+      case NGHTTP2_HEADERS:
+      case NGHTTP2_PUSH_PROMISE:
+      case NGHTTP2_CONTINUATION:
+        /* Mark inflater bad so that we won't perform further decoding */
+        session->hd_inflater.ctx.bad = 1;
+        break;
+      default:
+        break;
+      }
+
+      session_inbound_frame_reset(session);
+
+      break;
+    case NGHTTP2_IB_FRAME_SIZE_ERROR:
+      DEBUGF("recv: [IB_FRAME_SIZE_ERROR]\n");
+
+      rv = session_handle_frame_size_error(session);
+      if (nghttp2_is_fatal(rv)) {
+        return rv;
+      }
+
+      assert(iframe->state == NGHTTP2_IB_IGN_ALL);
+
+      return (ssize_t)inlen;
+    case NGHTTP2_IB_READ_SETTINGS:
+      DEBUGF("recv: [IB_READ_SETTINGS]\n");
+
+      readlen = inbound_frame_buf_read(iframe, in, last);
+      iframe->payloadleft -= readlen;
+      in += readlen;
+
+      DEBUGF("recv: readlen=%zu, payloadleft=%zu\n", readlen,
+             iframe->payloadleft);
+
+      if (nghttp2_buf_mark_avail(&iframe->sbuf)) {
+        break;
+      }
+
+      if (readlen > 0) {
+        inbound_frame_set_settings_entry(iframe);
+      }
+      if (iframe->payloadleft) {
+        inbound_frame_set_mark(iframe, NGHTTP2_FRAME_SETTINGS_ENTRY_LENGTH);
+        break;
+      }
+
+      rv = session_process_settings_frame(session);
+
+      if (nghttp2_is_fatal(rv)) {
+        return rv;
+      }
+
+      if (iframe->state == NGHTTP2_IB_IGN_ALL) {
+        return (ssize_t)inlen;
+      }
+
+      session_inbound_frame_reset(session);
+
+      break;
+    case NGHTTP2_IB_READ_GOAWAY_DEBUG:
+      DEBUGF("recv: [IB_READ_GOAWAY_DEBUG]\n");
+
+      readlen = inbound_frame_payload_readlen(iframe, in, last);
+
+      if (readlen > 0) {
+        iframe->lbuf.last = nghttp2_cpymem(iframe->lbuf.last, in, readlen);
+
+        iframe->payloadleft -= readlen;
+        in += readlen;
+      }
+
+      DEBUGF("recv: readlen=%zu, payloadleft=%zu\n", readlen,
+             iframe->payloadleft);
+
+      if (iframe->payloadleft) {
+        assert(nghttp2_buf_avail(&iframe->lbuf) > 0);
+
+        break;
+      }
+
+      rv = session_process_goaway_frame(session);
+
+      if (nghttp2_is_fatal(rv)) {
+        return rv;
+      }
+
+      if (iframe->state == NGHTTP2_IB_IGN_ALL) {
+        return (ssize_t)inlen;
+      }
+
+      session_inbound_frame_reset(session);
+
+      break;
+    case NGHTTP2_IB_EXPECT_CONTINUATION:
+    case NGHTTP2_IB_IGN_CONTINUATION:
+#ifdef DEBUGBUILD
+      if (iframe->state == NGHTTP2_IB_EXPECT_CONTINUATION) {
+        fprintf(stderr, "recv: [IB_EXPECT_CONTINUATION]\n");
+      } else {
+        fprintf(stderr, "recv: [IB_IGN_CONTINUATION]\n");
+      }
+#endif /* DEBUGBUILD */
+
+      readlen = inbound_frame_buf_read(iframe, in, last);
+      in += readlen;
+
+      if (nghttp2_buf_mark_avail(&iframe->sbuf)) {
+        return in - first;
+      }
+
+      nghttp2_frame_unpack_frame_hd(&cont_hd, iframe->sbuf.pos);
+      iframe->payloadleft = cont_hd.length;
+
+      DEBUGF("recv: payloadlen=%zu, type=%u, flags=0x%02x, stream_id=%d\n",
+             cont_hd.length, cont_hd.type, cont_hd.flags, cont_hd.stream_id);
+
+      if (cont_hd.type != NGHTTP2_CONTINUATION ||
+          cont_hd.stream_id != iframe->frame.hd.stream_id) {
+        DEBUGF("recv: expected stream_id=%d, type=%d, but got stream_id=%d, "
+               "type=%u\n",
+               iframe->frame.hd.stream_id, NGHTTP2_CONTINUATION,
+               cont_hd.stream_id, cont_hd.type);
+        rv = nghttp2_session_terminate_session_with_reason(
+            session, NGHTTP2_PROTOCOL_ERROR,
+            "unexpected non-CONTINUATION frame or stream_id is invalid");
+        if (nghttp2_is_fatal(rv)) {
+          return rv;
+        }
+
+        return (ssize_t)inlen;
+      }
+
+      /* CONTINUATION won't bear NGHTTP2_PADDED flag */
+
+      iframe->frame.hd.flags = (uint8_t)(
+          iframe->frame.hd.flags | (cont_hd.flags & NGHTTP2_FLAG_END_HEADERS));
+      iframe->frame.hd.length += cont_hd.length;
+
+      busy = 1;
+
+      if (iframe->state == NGHTTP2_IB_EXPECT_CONTINUATION) {
+        iframe->state = NGHTTP2_IB_READ_HEADER_BLOCK;
+
+        rv = session_call_on_begin_frame(session, &cont_hd);
+
+        if (nghttp2_is_fatal(rv)) {
+          return rv;
+        }
+      } else {
+        iframe->state = NGHTTP2_IB_IGN_HEADER_BLOCK;
+      }
+
+      break;
+    case NGHTTP2_IB_READ_PAD_DATA:
+      DEBUGF("recv: [IB_READ_PAD_DATA]\n");
+
+      readlen = inbound_frame_buf_read(iframe, in, last);
+      in += readlen;
+      iframe->payloadleft -= readlen;
+
+      DEBUGF("recv: readlen=%zu, payloadleft=%zu, left=%zu\n", readlen,
+             iframe->payloadleft, nghttp2_buf_mark_avail(&iframe->sbuf));
+
+      if (nghttp2_buf_mark_avail(&iframe->sbuf)) {
+        return in - first;
+      }
+
+      /* Pad Length field is subject to flow control */
+      rv = session_update_recv_connection_window_size(session, readlen);
+      if (nghttp2_is_fatal(rv)) {
+        return rv;
+      }
+
+      if (iframe->state == NGHTTP2_IB_IGN_ALL) {
+        return (ssize_t)inlen;
+      }
+
+      /* Pad Length field is consumed immediately */
+      rv =
+          nghttp2_session_consume(session, iframe->frame.hd.stream_id, readlen);
+
+      if (nghttp2_is_fatal(rv)) {
+        return rv;
+      }
+
+      if (iframe->state == NGHTTP2_IB_IGN_ALL) {
+        return (ssize_t)inlen;
+      }
+
+      stream = nghttp2_session_get_stream(session, iframe->frame.hd.stream_id);
+      if (stream) {
+        rv = session_update_recv_stream_window_size(
+            session, stream, readlen,
+            iframe->payloadleft ||
+                (iframe->frame.hd.flags & NGHTTP2_FLAG_END_STREAM) == 0);
+        if (nghttp2_is_fatal(rv)) {
+          return rv;
+        }
+      }
+
+      busy = 1;
+
+      padlen = inbound_frame_compute_pad(iframe);
+      if (padlen < 0) {
+        rv = nghttp2_session_terminate_session_with_reason(
+            session, NGHTTP2_PROTOCOL_ERROR, "DATA: invalid padding");
+        if (nghttp2_is_fatal(rv)) {
+          return rv;
+        }
+        return (ssize_t)inlen;
+      }
+
+      iframe->frame.data.padlen = (size_t)padlen;
+
+      iframe->state = NGHTTP2_IB_READ_DATA;
+
+      break;
+    case NGHTTP2_IB_READ_DATA:
+      stream = nghttp2_session_get_stream(session, iframe->frame.hd.stream_id);
+
+      if (!stream) {
+        busy = 1;
+        iframe->state = NGHTTP2_IB_IGN_DATA;
+        break;
+      }
+
+      DEBUGF("recv: [IB_READ_DATA]\n");
+
+      readlen = inbound_frame_payload_readlen(iframe, in, last);
+      iframe->payloadleft -= readlen;
+      in += readlen;
+
+      DEBUGF("recv: readlen=%zu, payloadleft=%zu\n", readlen,
+             iframe->payloadleft);
+
+      if (readlen > 0) {
+        ssize_t data_readlen;
+
+        rv = session_update_recv_connection_window_size(session, readlen);
+        if (nghttp2_is_fatal(rv)) {
+          return rv;
+        }
+
+        if (iframe->state == NGHTTP2_IB_IGN_ALL) {
+          return (ssize_t)inlen;
+        }
+
+        rv = session_update_recv_stream_window_size(
+            session, stream, readlen,
+            iframe->payloadleft ||
+                (iframe->frame.hd.flags & NGHTTP2_FLAG_END_STREAM) == 0);
+        if (nghttp2_is_fatal(rv)) {
+          return rv;
+        }
+
+        data_readlen = inbound_frame_effective_readlen(
+            iframe, iframe->payloadleft, readlen);
+
+        if (data_readlen == -1) {
+          /* everything is padding */
+          data_readlen = 0;
+        }
+
+        padlen = (ssize_t)readlen - data_readlen;
+
+        if (padlen > 0) {
+          /* Padding is considered as "consumed" immediately */
+          rv = nghttp2_session_consume(session, iframe->frame.hd.stream_id,
+                                       (size_t)padlen);
+
+          if (nghttp2_is_fatal(rv)) {
+            return rv;
+          }
+
+          if (iframe->state == NGHTTP2_IB_IGN_ALL) {
+            return (ssize_t)inlen;
+          }
+        }
+
+        DEBUGF("recv: data_readlen=%zd\n", data_readlen);
+
+        if (data_readlen > 0) {
+          if (session_enforce_http_messaging(session)) {
+            if (nghttp2_http_on_data_chunk(stream, (size_t)data_readlen) != 0) {
+              if (session->opt_flags & NGHTTP2_OPTMASK_NO_AUTO_WINDOW_UPDATE) {
+                /* Consume all data for connection immediately here */
+                rv = session_update_connection_consumed_size(
+                    session, (size_t)data_readlen);
+
+                if (nghttp2_is_fatal(rv)) {
+                  return rv;
+                }
+
+                if (iframe->state == NGHTTP2_IB_IGN_DATA) {
+                  return (ssize_t)inlen;
+                }
+              }
+
+              rv = nghttp2_session_add_rst_stream(
+                  session, iframe->frame.hd.stream_id, NGHTTP2_PROTOCOL_ERROR);
+              if (nghttp2_is_fatal(rv)) {
+                return rv;
+              }
+              busy = 1;
+              iframe->state = NGHTTP2_IB_IGN_DATA;
+              break;
+            }
+          }
+          if (session->callbacks.on_data_chunk_recv_callback) {
+            rv = session->callbacks.on_data_chunk_recv_callback(
+                session, iframe->frame.hd.flags, iframe->frame.hd.stream_id,
+                in - readlen, (size_t)data_readlen, session->user_data);
+            if (rv == NGHTTP2_ERR_PAUSE) {
+              return in - first;
+            }
+
+            if (nghttp2_is_fatal(rv)) {
+              return NGHTTP2_ERR_CALLBACK_FAILURE;
+            }
+          }
+        }
+      }
+
+      if (iframe->payloadleft) {
+        break;
+      }
+
+      rv = session_process_data_frame(session);
+      if (nghttp2_is_fatal(rv)) {
+        return rv;
+      }
+
+      session_inbound_frame_reset(session);
+
+      break;
+    case NGHTTP2_IB_IGN_DATA:
+      DEBUGF("recv: [IB_IGN_DATA]\n");
+
+      readlen = inbound_frame_payload_readlen(iframe, in, last);
+      iframe->payloadleft -= readlen;
+      in += readlen;
+
+      DEBUGF("recv: readlen=%zu, payloadleft=%zu\n", readlen,
+             iframe->payloadleft);
+
+      if (readlen > 0) {
+        /* Update connection-level flow control window for ignored
+           DATA frame too */
+        rv = session_update_recv_connection_window_size(session, readlen);
+        if (nghttp2_is_fatal(rv)) {
+          return rv;
+        }
+
+        if (iframe->state == NGHTTP2_IB_IGN_ALL) {
+          return (ssize_t)inlen;
+        }
+
+        if (session->opt_flags & NGHTTP2_OPTMASK_NO_AUTO_WINDOW_UPDATE) {
+
+          /* Ignored DATA is considered as "consumed" immediately. */
+          rv = session_update_connection_consumed_size(session, readlen);
+
+          if (nghttp2_is_fatal(rv)) {
+            return rv;
+          }
+
+          if (iframe->state == NGHTTP2_IB_IGN_ALL) {
+            return (ssize_t)inlen;
+          }
+        }
+      }
+
+      if (iframe->payloadleft) {
+        break;
+      }
+
+      session_inbound_frame_reset(session);
+
+      break;
+    case NGHTTP2_IB_IGN_ALL:
+      return (ssize_t)inlen;
+    case NGHTTP2_IB_READ_EXTENSION_PAYLOAD:
+      DEBUGF("recv: [IB_READ_EXTENSION_PAYLOAD]\n");
+
+      readlen = inbound_frame_payload_readlen(iframe, in, last);
+      iframe->payloadleft -= readlen;
+      in += readlen;
+
+      DEBUGF("recv: readlen=%zu, payloadleft=%zu\n", readlen,
+             iframe->payloadleft);
+
+      if (readlen > 0) {
+        rv = session_call_on_extension_chunk_recv_callback(
+            session, in - readlen, readlen);
+        if (nghttp2_is_fatal(rv)) {
+          return rv;
+        }
+
+        if (rv != 0) {
+          busy = 1;
+
+          iframe->state = NGHTTP2_IB_IGN_PAYLOAD;
+
+          break;
+        }
+      }
+
+      if (iframe->payloadleft > 0) {
+        break;
+      }
+
+      rv = session_process_extension_frame(session);
+      if (nghttp2_is_fatal(rv)) {
+        return rv;
+      }
+
+      session_inbound_frame_reset(session);
+
+      break;
+    case NGHTTP2_IB_READ_ALTSVC_PAYLOAD:
+      DEBUGF("recv: [IB_READ_ALTSVC_PAYLOAD]\n");
+
+      readlen = inbound_frame_payload_readlen(iframe, in, last);
+      if (readlen > 0) {
+        iframe->lbuf.last = nghttp2_cpymem(iframe->lbuf.last, in, readlen);
+
+        iframe->payloadleft -= readlen;
+        in += readlen;
+      }
+
+      DEBUGF("recv: readlen=%zu, payloadleft=%zu\n", readlen,
+             iframe->payloadleft);
+
+      if (iframe->payloadleft) {
+        assert(nghttp2_buf_avail(&iframe->lbuf) > 0);
+
+        break;
+      }
+
+      rv = session_process_altsvc_frame(session);
+      if (nghttp2_is_fatal(rv)) {
+        return rv;
+      }
+
+      session_inbound_frame_reset(session);
+
+      break;
+    case NGHTTP2_IB_READ_ORIGIN_PAYLOAD:
+      DEBUGF("recv: [IB_READ_ORIGIN_PAYLOAD]\n");
+
+      readlen = inbound_frame_payload_readlen(iframe, in, last);
+
+      if (readlen > 0) {
+        iframe->lbuf.last = nghttp2_cpymem(iframe->lbuf.last, in, readlen);
+
+        iframe->payloadleft -= readlen;
+        in += readlen;
+      }
+
+      DEBUGF("recv: readlen=%zu, payloadleft=%zu\n", readlen,
+             iframe->payloadleft);
+
+      if (iframe->payloadleft) {
+        assert(nghttp2_buf_avail(&iframe->lbuf) > 0);
+
+        break;
+      }
+
+      rv = session_process_origin_frame(session);
+
+      if (nghttp2_is_fatal(rv)) {
+        return rv;
+      }
+
+      if (iframe->state == NGHTTP2_IB_IGN_ALL) {
+        return (ssize_t)inlen;
+      }
+
+      session_inbound_frame_reset(session);
+
+      break;
+    }
+
+    if (!busy && in == last) {
+      break;
+    }
+
+    busy = 0;
+  }
+
+  assert(in == last);
+
+  return in - first;
+}
+
+int nghttp2_session_recv(nghttp2_session *session) {
+  uint8_t buf[NGHTTP2_INBOUND_BUFFER_LENGTH];
+  while (1) {
+    ssize_t readlen;
+    readlen = session_recv(session, buf, sizeof(buf));
+    if (readlen > 0) {
+      ssize_t proclen = nghttp2_session_mem_recv(session, buf, (size_t)readlen);
+      if (proclen < 0) {
+        return (int)proclen;
+      }
+      assert(proclen == readlen);
+    } else if (readlen == 0 || readlen == NGHTTP2_ERR_WOULDBLOCK) {
+      return 0;
+    } else if (readlen == NGHTTP2_ERR_EOF) {
+      return NGHTTP2_ERR_EOF;
+    } else if (readlen < 0) {
+      return NGHTTP2_ERR_CALLBACK_FAILURE;
+    }
+  }
+}
+
+/*
+ * Returns the number of active streams, which includes streams in
+ * reserved state.
+ */
+static size_t session_get_num_active_streams(nghttp2_session *session) {
+  return nghttp2_map_size(&session->streams) - session->num_closed_streams -
+         session->num_idle_streams;
+}
+
+int nghttp2_session_want_read(nghttp2_session *session) {
+  size_t num_active_streams;
+
+  /* If this flag is set, we don't want to read. The application
+     should drop the connection. */
+  if (session->goaway_flags & NGHTTP2_GOAWAY_TERM_SENT) {
+    return 0;
+  }
+
+  num_active_streams = session_get_num_active_streams(session);
+
+  /* Unless termination GOAWAY is sent or received, we always want to
+     read incoming frames. */
+
+  if (num_active_streams > 0) {
+    return 1;
+  }
+
+  /* If there is no active streams and GOAWAY has been sent or
+     received, we are done with this session. */
+  return (session->goaway_flags &
+          (NGHTTP2_GOAWAY_SENT | NGHTTP2_GOAWAY_RECV)) == 0;
+}
+
+int nghttp2_session_want_write(nghttp2_session *session) {
+  /* If these flag is set, we don't want to write any data. The
+     application should drop the connection. */
+  if (session->goaway_flags & NGHTTP2_GOAWAY_TERM_SENT) {
+    return 0;
+  }
+
+  /*
+   * Unless termination GOAWAY is sent or received, we want to write
+   * frames if there is pending ones. If pending frame is request/push
+   * response HEADERS and concurrent stream limit is reached, we don't
+   * want to write them.
+   */
+  return session->aob.item || nghttp2_outbound_queue_top(&session->ob_urgent) ||
+         nghttp2_outbound_queue_top(&session->ob_reg) ||
+         (!nghttp2_pq_empty(&session->root.obq) &&
+          session->remote_window_size > 0) ||
+         (nghttp2_outbound_queue_top(&session->ob_syn) &&
+          !session_is_outgoing_concurrent_streams_max(session));
+}
+
+int nghttp2_session_add_ping(nghttp2_session *session, uint8_t flags,
+                             const uint8_t *opaque_data) {
+  int rv;
+  nghttp2_outbound_item *item;
+  nghttp2_frame *frame;
+  nghttp2_mem *mem;
+
+  mem = &session->mem;
+
+  if ((flags & NGHTTP2_FLAG_ACK) &&
+      session->obq_flood_counter_ >= session->max_outbound_ack) {
+    return NGHTTP2_ERR_FLOODED;
+  }
+
+  item = nghttp2_mem_malloc(mem, sizeof(nghttp2_outbound_item));
+  if (item == NULL) {
+    return NGHTTP2_ERR_NOMEM;
+  }
+
+  nghttp2_outbound_item_init(item);
+
+  frame = &item->frame;
+
+  nghttp2_frame_ping_init(&frame->ping, flags, opaque_data);
+
+  rv = nghttp2_session_add_item(session, item);
+
+  if (rv != 0) {
+    nghttp2_frame_ping_free(&frame->ping);
+    nghttp2_mem_free(mem, item);
+    return rv;
+  }
+
+  if (flags & NGHTTP2_FLAG_ACK) {
+    ++session->obq_flood_counter_;
+  }
+
+  return 0;
+}
+
+int nghttp2_session_add_goaway(nghttp2_session *session, int32_t last_stream_id,
+                               uint32_t error_code, const uint8_t *opaque_data,
+                               size_t opaque_data_len, uint8_t aux_flags) {
+  int rv;
+  nghttp2_outbound_item *item;
+  nghttp2_frame *frame;
+  uint8_t *opaque_data_copy = NULL;
+  nghttp2_goaway_aux_data *aux_data;
+  nghttp2_mem *mem;
+
+  mem = &session->mem;
+
+  if (nghttp2_session_is_my_stream_id(session, last_stream_id)) {
+    return NGHTTP2_ERR_INVALID_ARGUMENT;
+  }
+
+  if (opaque_data_len) {
+    if (opaque_data_len + 8 > NGHTTP2_MAX_PAYLOADLEN) {
+      return NGHTTP2_ERR_INVALID_ARGUMENT;
+    }
+    opaque_data_copy = nghttp2_mem_malloc(mem, opaque_data_len);
+    if (opaque_data_copy == NULL) {
+      return NGHTTP2_ERR_NOMEM;
+    }
+    memcpy(opaque_data_copy, opaque_data, opaque_data_len);
+  }
+
+  item = nghttp2_mem_malloc(mem, sizeof(nghttp2_outbound_item));
+  if (item == NULL) {
+    nghttp2_mem_free(mem, opaque_data_copy);
+    return NGHTTP2_ERR_NOMEM;
+  }
+
+  nghttp2_outbound_item_init(item);
+
+  frame = &item->frame;
+
+  /* last_stream_id must not be increased from the value previously
+     sent */
+  last_stream_id = nghttp2_min(last_stream_id, session->local_last_stream_id);
+
+  nghttp2_frame_goaway_init(&frame->goaway, last_stream_id, error_code,
+                            opaque_data_copy, opaque_data_len);
+
+  aux_data = &item->aux_data.goaway;
+  aux_data->flags = aux_flags;
+
+  rv = nghttp2_session_add_item(session, item);
+  if (rv != 0) {
+    nghttp2_frame_goaway_free(&frame->goaway, mem);
+    nghttp2_mem_free(mem, item);
+    return rv;
+  }
+  return 0;
+}
+
+int nghttp2_session_add_window_update(nghttp2_session *session, uint8_t flags,
+                                      int32_t stream_id,
+                                      int32_t window_size_increment) {
+  int rv;
+  nghttp2_outbound_item *item;
+  nghttp2_frame *frame;
+  nghttp2_mem *mem;
+
+  mem = &session->mem;
+  item = nghttp2_mem_malloc(mem, sizeof(nghttp2_outbound_item));
+  if (item == NULL) {
+    return NGHTTP2_ERR_NOMEM;
+  }
+
+  nghttp2_outbound_item_init(item);
+
+  frame = &item->frame;
+
+  nghttp2_frame_window_update_init(&frame->window_update, flags, stream_id,
+                                   window_size_increment);
+
+  rv = nghttp2_session_add_item(session, item);
+
+  if (rv != 0) {
+    nghttp2_frame_window_update_free(&frame->window_update);
+    nghttp2_mem_free(mem, item);
+    return rv;
+  }
+  return 0;
+}
+
+static void
+session_append_inflight_settings(nghttp2_session *session,
+                                 nghttp2_inflight_settings *settings) {
+  nghttp2_inflight_settings **i;
+
+  for (i = &session->inflight_settings_head; *i; i = &(*i)->next)
+    ;
+
+  *i = settings;
+}
+
+int nghttp2_session_add_settings(nghttp2_session *session, uint8_t flags,
+                                 const nghttp2_settings_entry *iv, size_t niv) {
+  nghttp2_outbound_item *item;
+  nghttp2_frame *frame;
+  nghttp2_settings_entry *iv_copy;
+  size_t i;
+  int rv;
+  nghttp2_mem *mem;
+  nghttp2_inflight_settings *inflight_settings = NULL;
+
+  mem = &session->mem;
+
+  if (flags & NGHTTP2_FLAG_ACK) {
+    if (niv != 0) {
+      return NGHTTP2_ERR_INVALID_ARGUMENT;
+    }
+
+    if (session->obq_flood_counter_ >= session->max_outbound_ack) {
+      return NGHTTP2_ERR_FLOODED;
+    }
+  }
+
+  if (!nghttp2_iv_check(iv, niv)) {
+    return NGHTTP2_ERR_INVALID_ARGUMENT;
+  }
+
+  item = nghttp2_mem_malloc(mem, sizeof(nghttp2_outbound_item));
+  if (item == NULL) {
+    return NGHTTP2_ERR_NOMEM;
+  }
+
+  if (niv > 0) {
+    iv_copy = nghttp2_frame_iv_copy(iv, niv, mem);
+    if (iv_copy == NULL) {
+      nghttp2_mem_free(mem, item);
+      return NGHTTP2_ERR_NOMEM;
+    }
+  } else {
+    iv_copy = NULL;
+  }
+
+  if ((flags & NGHTTP2_FLAG_ACK) == 0) {
+    rv = inflight_settings_new(&inflight_settings, iv, niv, mem);
+    if (rv != 0) {
+      assert(nghttp2_is_fatal(rv));
+      nghttp2_mem_free(mem, iv_copy);
+      nghttp2_mem_free(mem, item);
+      return rv;
+    }
+  }
+
+  nghttp2_outbound_item_init(item);
+
+  frame = &item->frame;
+
+  nghttp2_frame_settings_init(&frame->settings, flags, iv_copy, niv);
+  rv = nghttp2_session_add_item(session, item);
+  if (rv != 0) {
+    /* The only expected error is fatal one */
+    assert(nghttp2_is_fatal(rv));
+
+    inflight_settings_del(inflight_settings, mem);
+
+    nghttp2_frame_settings_free(&frame->settings, mem);
+    nghttp2_mem_free(mem, item);
+
+    return rv;
+  }
+
+  if (flags & NGHTTP2_FLAG_ACK) {
+    ++session->obq_flood_counter_;
+  } else {
+    session_append_inflight_settings(session, inflight_settings);
+  }
+
+  /* Extract NGHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS and ENABLE_PUSH
+     here.  We use it to refuse the incoming stream and PUSH_PROMISE
+     with RST_STREAM. */
+
+  for (i = niv; i > 0; --i) {
+    if (iv[i - 1].settings_id == NGHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS) {
+      session->pending_local_max_concurrent_stream = iv[i - 1].value;
+      break;
+    }
+  }
+
+  for (i = niv; i > 0; --i) {
+    if (iv[i - 1].settings_id == NGHTTP2_SETTINGS_ENABLE_PUSH) {
+      session->pending_enable_push = (uint8_t)iv[i - 1].value;
+      break;
+    }
+  }
+
+  for (i = niv; i > 0; --i) {
+    if (iv[i - 1].settings_id == NGHTTP2_SETTINGS_ENABLE_CONNECT_PROTOCOL) {
+      session->pending_enable_connect_protocol = (uint8_t)iv[i - 1].value;
+      break;
+    }
+  }
+
+  return 0;
+}
+
+int nghttp2_session_pack_data(nghttp2_session *session, nghttp2_bufs *bufs,
+                              size_t datamax, nghttp2_frame *frame,
+                              nghttp2_data_aux_data *aux_data,
+                              nghttp2_stream *stream) {
+  int rv;
+  uint32_t data_flags;
+  ssize_t payloadlen;
+  ssize_t padded_payloadlen;
+  nghttp2_buf *buf;
+  size_t max_payloadlen;
+
+  assert(bufs->head == bufs->cur);
+
+  buf = &bufs->cur->buf;
+
+  if (session->callbacks.read_length_callback) {
+
+    payloadlen = session->callbacks.read_length_callback(
+        session, frame->hd.type, stream->stream_id, session->remote_window_size,
+        stream->remote_window_size, session->remote_settings.max_frame_size,
+        session->user_data);
+
+    DEBUGF("send: read_length_callback=%zd\n", payloadlen);
+
+    payloadlen = nghttp2_session_enforce_flow_control_limits(session, stream,
+                                                             payloadlen);
+
+    DEBUGF("send: read_length_callback after flow control=%zd\n", payloadlen);
+
+    if (payloadlen <= 0) {
+      return NGHTTP2_ERR_CALLBACK_FAILURE;
+    }
+
+    if ((size_t)payloadlen > nghttp2_buf_avail(buf)) {
+      /* Resize the current buffer(s).  The reason why we do +1 for
+         buffer size is for possible padding field. */
+      rv = nghttp2_bufs_realloc(&session->aob.framebufs,
+                                (size_t)(NGHTTP2_FRAME_HDLEN + 1 + payloadlen));
+
+      if (rv != 0) {
+        DEBUGF("send: realloc buffer failed rv=%d", rv);
+        /* If reallocation failed, old buffers are still in tact.  So
+           use safe limit. */
+        payloadlen = (ssize_t)datamax;
+
+        DEBUGF("send: use safe limit payloadlen=%zd", payloadlen);
+      } else {
+        assert(&session->aob.framebufs == bufs);
+
+        buf = &bufs->cur->buf;
+      }
+    }
+    datamax = (size_t)payloadlen;
+  }
+
+  /* Current max DATA length is less then buffer chunk size */
+  assert(nghttp2_buf_avail(buf) >= datamax);
+
+  data_flags = NGHTTP2_DATA_FLAG_NONE;
+  payloadlen = aux_data->data_prd.read_callback(
+      session, frame->hd.stream_id, buf->pos, datamax, &data_flags,
+      &aux_data->data_prd.source, session->user_data);
+
+  if (payloadlen == NGHTTP2_ERR_DEFERRED ||
+      payloadlen == NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE ||
+      payloadlen == NGHTTP2_ERR_PAUSE) {
+    DEBUGF("send: DATA postponed due to %s\n",
+           nghttp2_strerror((int)payloadlen));
+
+    return (int)payloadlen;
+  }
+
+  if (payloadlen < 0 || datamax < (size_t)payloadlen) {
+    /* This is the error code when callback is failed. */
+    return NGHTTP2_ERR_CALLBACK_FAILURE;
+  }
+
+  buf->last = buf->pos + payloadlen;
+  buf->pos -= NGHTTP2_FRAME_HDLEN;
+
+  /* Clear flags, because this may contain previous flags of previous
+     DATA */
+  frame->hd.flags = NGHTTP2_FLAG_NONE;
+
+  if (data_flags & NGHTTP2_DATA_FLAG_EOF) {
+    aux_data->eof = 1;
+    /* If NGHTTP2_DATA_FLAG_NO_END_STREAM is set, don't set
+       NGHTTP2_FLAG_END_STREAM */
+    if ((aux_data->flags & NGHTTP2_FLAG_END_STREAM) &&
+        (data_flags & NGHTTP2_DATA_FLAG_NO_END_STREAM) == 0) {
+      frame->hd.flags |= NGHTTP2_FLAG_END_STREAM;
+    }
+  }
+
+  if (data_flags & NGHTTP2_DATA_FLAG_NO_COPY) {
+    if (session->callbacks.send_data_callback == NULL) {
+      DEBUGF("NGHTTP2_DATA_FLAG_NO_COPY requires send_data_callback set\n");
+
+      return NGHTTP2_ERR_CALLBACK_FAILURE;
+    }
+    aux_data->no_copy = 1;
+  }
+
+  frame->hd.length = (size_t)payloadlen;
+  frame->data.padlen = 0;
+
+  max_payloadlen = nghttp2_min(datamax, frame->hd.length + NGHTTP2_MAX_PADLEN);
+
+  padded_payloadlen =
+      session_call_select_padding(session, frame, max_payloadlen);
+
+  if (nghttp2_is_fatal((int)padded_payloadlen)) {
+    return (int)padded_payloadlen;
+  }
+
+  frame->data.padlen = (size_t)(padded_payloadlen - payloadlen);
+
+  nghttp2_frame_pack_frame_hd(buf->pos, &frame->hd);
+
+  rv = nghttp2_frame_add_pad(bufs, &frame->hd, frame->data.padlen,
+                             aux_data->no_copy);
+  if (rv != 0) {
+    return rv;
+  }
+
+  reschedule_stream(stream);
+
+  if (frame->hd.length == 0 && (data_flags & NGHTTP2_DATA_FLAG_EOF) &&
+      (data_flags & NGHTTP2_DATA_FLAG_NO_END_STREAM)) {
+    /* DATA payload length is 0, and DATA frame does not bear
+       END_STREAM.  In this case, there is no point to send 0 length
+       DATA frame. */
+    return NGHTTP2_ERR_CANCEL;
+  }
+
+  return 0;
+}
+
+void *nghttp2_session_get_stream_user_data(nghttp2_session *session,
+                                           int32_t stream_id) {
+  nghttp2_stream *stream;
+  stream = nghttp2_session_get_stream(session, stream_id);
+  if (stream) {
+    return stream->stream_user_data;
+  } else {
+    return NULL;
+  }
+}
+
+int nghttp2_session_set_stream_user_data(nghttp2_session *session,
+                                         int32_t stream_id,
+                                         void *stream_user_data) {
+  nghttp2_stream *stream;
+  nghttp2_frame *frame;
+  nghttp2_outbound_item *item;
+
+  stream = nghttp2_session_get_stream(session, stream_id);
+  if (stream) {
+    stream->stream_user_data = stream_user_data;
+    return 0;
+  }
+
+  if (session->server || !nghttp2_session_is_my_stream_id(session, stream_id) ||
+      !nghttp2_outbound_queue_top(&session->ob_syn)) {
+    return NGHTTP2_ERR_INVALID_ARGUMENT;
+  }
+
+  frame = &nghttp2_outbound_queue_top(&session->ob_syn)->frame;
+  assert(frame->hd.type == NGHTTP2_HEADERS);
+
+  if (frame->hd.stream_id > stream_id ||
+      (uint32_t)stream_id >= session->next_stream_id) {
+    return NGHTTP2_ERR_INVALID_ARGUMENT;
+  }
+
+  for (item = session->ob_syn.head; item; item = item->qnext) {
+    if (item->frame.hd.stream_id < stream_id) {
+      continue;
+    }
+
+    if (item->frame.hd.stream_id > stream_id) {
+      break;
+    }
+
+    item->aux_data.headers.stream_user_data = stream_user_data;
+    return 0;
+  }
+
+  return NGHTTP2_ERR_INVALID_ARGUMENT;
+}
+
+int nghttp2_session_resume_data(nghttp2_session *session, int32_t stream_id) {
+  int rv;
+  nghttp2_stream *stream;
+  stream = nghttp2_session_get_stream(session, stream_id);
+  if (stream == NULL || !nghttp2_stream_check_deferred_item(stream)) {
+    return NGHTTP2_ERR_INVALID_ARGUMENT;
+  }
+
+  rv = nghttp2_stream_resume_deferred_item(stream,
+                                           NGHTTP2_STREAM_FLAG_DEFERRED_USER);
+
+  if (nghttp2_is_fatal(rv)) {
+    return rv;
+  }
+
+  return 0;
+}
+
+size_t nghttp2_session_get_outbound_queue_size(nghttp2_session *session) {
+  return nghttp2_outbound_queue_size(&session->ob_urgent) +
+         nghttp2_outbound_queue_size(&session->ob_reg) +
+         nghttp2_outbound_queue_size(&session->ob_syn);
+  /* TODO account for item attached to stream */
+}
+
+int32_t
+nghttp2_session_get_stream_effective_recv_data_length(nghttp2_session *session,
+                                                      int32_t stream_id) {
+  nghttp2_stream *stream;
+  stream = nghttp2_session_get_stream(session, stream_id);
+  if (stream == NULL) {
+    return -1;
+  }
+  return stream->recv_window_size < 0 ? 0 : stream->recv_window_size;
+}
+
+int32_t
+nghttp2_session_get_stream_effective_local_window_size(nghttp2_session *session,
+                                                       int32_t stream_id) {
+  nghttp2_stream *stream;
+  stream = nghttp2_session_get_stream(session, stream_id);
+  if (stream == NULL) {
+    return -1;
+  }
+  return stream->local_window_size;
+}
+
+int32_t nghttp2_session_get_stream_local_window_size(nghttp2_session *session,
+                                                     int32_t stream_id) {
+  nghttp2_stream *stream;
+  int32_t size;
+  stream = nghttp2_session_get_stream(session, stream_id);
+  if (stream == NULL) {
+    return -1;
+  }
+
+  size = stream->local_window_size - stream->recv_window_size;
+
+  /* size could be negative if local endpoint reduced
+     SETTINGS_INITIAL_WINDOW_SIZE */
+  if (size < 0) {
+    return 0;
+  }
+
+  return size;
+}
+
+int32_t
+nghttp2_session_get_effective_recv_data_length(nghttp2_session *session) {
+  return session->recv_window_size < 0 ? 0 : session->recv_window_size;
+}
+
+int32_t
+nghttp2_session_get_effective_local_window_size(nghttp2_session *session) {
+  return session->local_window_size;
+}
+
+int32_t nghttp2_session_get_local_window_size(nghttp2_session *session) {
+  return session->local_window_size - session->recv_window_size;
+}
+
+int32_t nghttp2_session_get_stream_remote_window_size(nghttp2_session *session,
+                                                      int32_t stream_id) {
+  nghttp2_stream *stream;
+
+  stream = nghttp2_session_get_stream(session, stream_id);
+  if (stream == NULL) {
+    return -1;
+  }
+
+  /* stream->remote_window_size can be negative when
+     SETTINGS_INITIAL_WINDOW_SIZE is changed. */
+  return nghttp2_max(0, stream->remote_window_size);
+}
+
+int32_t nghttp2_session_get_remote_window_size(nghttp2_session *session) {
+  return session->remote_window_size;
+}
+
+uint32_t nghttp2_session_get_remote_settings(nghttp2_session *session,
+                                             nghttp2_settings_id id) {
+  switch (id) {
+  case NGHTTP2_SETTINGS_HEADER_TABLE_SIZE:
+    return session->remote_settings.header_table_size;
+  case NGHTTP2_SETTINGS_ENABLE_PUSH:
+    return session->remote_settings.enable_push;
+  case NGHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS:
+    return session->remote_settings.max_concurrent_streams;
+  case NGHTTP2_SETTINGS_INITIAL_WINDOW_SIZE:
+    return session->remote_settings.initial_window_size;
+  case NGHTTP2_SETTINGS_MAX_FRAME_SIZE:
+    return session->remote_settings.max_frame_size;
+  case NGHTTP2_SETTINGS_MAX_HEADER_LIST_SIZE:
+    return session->remote_settings.max_header_list_size;
+  case NGHTTP2_SETTINGS_ENABLE_CONNECT_PROTOCOL:
+    return session->remote_settings.enable_connect_protocol;
+  }
+
+  assert(0);
+  abort(); /* if NDEBUG is set */
+}
+
+uint32_t nghttp2_session_get_local_settings(nghttp2_session *session,
+                                            nghttp2_settings_id id) {
+  switch (id) {
+  case NGHTTP2_SETTINGS_HEADER_TABLE_SIZE:
+    return session->local_settings.header_table_size;
+  case NGHTTP2_SETTINGS_ENABLE_PUSH:
+    return session->local_settings.enable_push;
+  case NGHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS:
+    return session->local_settings.max_concurrent_streams;
+  case NGHTTP2_SETTINGS_INITIAL_WINDOW_SIZE:
+    return session->local_settings.initial_window_size;
+  case NGHTTP2_SETTINGS_MAX_FRAME_SIZE:
+    return session->local_settings.max_frame_size;
+  case NGHTTP2_SETTINGS_MAX_HEADER_LIST_SIZE:
+    return session->local_settings.max_header_list_size;
+  case NGHTTP2_SETTINGS_ENABLE_CONNECT_PROTOCOL:
+    return session->local_settings.enable_connect_protocol;
+  }
+
+  assert(0);
+  abort(); /* if NDEBUG is set */
+}
+
+static int nghttp2_session_upgrade_internal(nghttp2_session *session,
+                                            const uint8_t *settings_payload,
+                                            size_t settings_payloadlen,
+                                            void *stream_user_data) {
+  nghttp2_stream *stream;
+  nghttp2_frame frame;
+  nghttp2_settings_entry *iv;
+  size_t niv;
+  int rv;
+  nghttp2_priority_spec pri_spec;
+  nghttp2_mem *mem;
+
+  mem = &session->mem;
+
+  if ((!session->server && session->next_stream_id != 1) ||
+      (session->server && session->last_recv_stream_id >= 1)) {
+    return NGHTTP2_ERR_PROTO;
+  }
+  if (settings_payloadlen % NGHTTP2_FRAME_SETTINGS_ENTRY_LENGTH) {
+    return NGHTTP2_ERR_INVALID_ARGUMENT;
+  }
+  rv = nghttp2_frame_unpack_settings_payload2(&iv, &niv, settings_payload,
+                                              settings_payloadlen, mem);
+  if (rv != 0) {
+    return rv;
+  }
+
+  if (session->server) {
+    nghttp2_frame_hd_init(&frame.hd, settings_payloadlen, NGHTTP2_SETTINGS,
+                          NGHTTP2_FLAG_NONE, 0);
+    frame.settings.iv = iv;
+    frame.settings.niv = niv;
+    rv = nghttp2_session_on_settings_received(session, &frame, 1 /* No ACK */);
+  } else {
+    rv = nghttp2_submit_settings(session, NGHTTP2_FLAG_NONE, iv, niv);
+  }
+  nghttp2_mem_free(mem, iv);
+  if (rv != 0) {
+    return rv;
+  }
+
+  nghttp2_priority_spec_default_init(&pri_spec);
+
+  stream = nghttp2_session_open_stream(
+      session, 1, NGHTTP2_STREAM_FLAG_NONE, &pri_spec, NGHTTP2_STREAM_OPENING,
+      session->server ? NULL : stream_user_data);
+  if (stream == NULL) {
+    return NGHTTP2_ERR_NOMEM;
+  }
+
+  /* We don't call nghttp2_session_adjust_closed_stream(), since this
+     should be the first stream open. */
+
+  if (session->server) {
+    nghttp2_stream_shutdown(stream, NGHTTP2_SHUT_RD);
+    session->last_recv_stream_id = 1;
+    session->last_proc_stream_id = 1;
+  } else {
+    nghttp2_stream_shutdown(stream, NGHTTP2_SHUT_WR);
+    session->last_sent_stream_id = 1;
+    session->next_stream_id += 2;
+  }
+  return 0;
+}
+
+int nghttp2_session_upgrade(nghttp2_session *session,
+                            const uint8_t *settings_payload,
+                            size_t settings_payloadlen,
+                            void *stream_user_data) {
+  int rv;
+  nghttp2_stream *stream;
+
+  rv = nghttp2_session_upgrade_internal(session, settings_payload,
+                                        settings_payloadlen, stream_user_data);
+  if (rv != 0) {
+    return rv;
+  }
+
+  stream = nghttp2_session_get_stream(session, 1);
+  assert(stream);
+
+  /* We have no information about request header fields when Upgrade
+     was happened.  So we don't know the request method here.  If
+     request method is HEAD, we have a trouble because we may have
+     nonzero content-length header field in response headers, and we
+     will going to check it against the actual DATA frames, but we may
+     get mismatch because HEAD response body must be empty.  Because
+     of this reason, nghttp2_session_upgrade() was deprecated in favor
+     of nghttp2_session_upgrade2(), which has |head_request| parameter
+     to indicate that request method is HEAD or not. */
+  stream->http_flags |= NGHTTP2_HTTP_FLAG_METH_UPGRADE_WORKAROUND;
+  return 0;
+}
+
+int nghttp2_session_upgrade2(nghttp2_session *session,
+                             const uint8_t *settings_payload,
+                             size_t settings_payloadlen, int head_request,
+                             void *stream_user_data) {
+  int rv;
+  nghttp2_stream *stream;
+
+  rv = nghttp2_session_upgrade_internal(session, settings_payload,
+                                        settings_payloadlen, stream_user_data);
+  if (rv != 0) {
+    return rv;
+  }
+
+  stream = nghttp2_session_get_stream(session, 1);
+  assert(stream);
+
+  if (head_request) {
+    stream->http_flags |= NGHTTP2_HTTP_FLAG_METH_HEAD;
+  }
+
+  return 0;
+}
+
+int nghttp2_session_get_stream_local_close(nghttp2_session *session,
+                                           int32_t stream_id) {
+  nghttp2_stream *stream;
+
+  stream = nghttp2_session_get_stream(session, stream_id);
+
+  if (!stream) {
+    return -1;
+  }
+
+  return (stream->shut_flags & NGHTTP2_SHUT_WR) != 0;
+}
+
+int nghttp2_session_get_stream_remote_close(nghttp2_session *session,
+                                            int32_t stream_id) {
+  nghttp2_stream *stream;
+
+  stream = nghttp2_session_get_stream(session, stream_id);
+
+  if (!stream) {
+    return -1;
+  }
+
+  return (stream->shut_flags & NGHTTP2_SHUT_RD) != 0;
+}
+
+int nghttp2_session_consume(nghttp2_session *session, int32_t stream_id,
+                            size_t size) {
+  int rv;
+  nghttp2_stream *stream;
+
+  if (stream_id == 0) {
+    return NGHTTP2_ERR_INVALID_ARGUMENT;
+  }
+
+  if (!(session->opt_flags & NGHTTP2_OPTMASK_NO_AUTO_WINDOW_UPDATE)) {
+    return NGHTTP2_ERR_INVALID_STATE;
+  }
+
+  rv = session_update_connection_consumed_size(session, size);
+
+  if (nghttp2_is_fatal(rv)) {
+    return rv;
+  }
+
+  stream = nghttp2_session_get_stream(session, stream_id);
+
+  if (!stream) {
+    return 0;
+  }
+
+  rv = session_update_stream_consumed_size(session, stream, size);
+
+  if (nghttp2_is_fatal(rv)) {
+    return rv;
+  }
+
+  return 0;
+}
+
+int nghttp2_session_consume_connection(nghttp2_session *session, size_t size) {
+  int rv;
+
+  if (!(session->opt_flags & NGHTTP2_OPTMASK_NO_AUTO_WINDOW_UPDATE)) {
+    return NGHTTP2_ERR_INVALID_STATE;
+  }
+
+  rv = session_update_connection_consumed_size(session, size);
+
+  if (nghttp2_is_fatal(rv)) {
+    return rv;
+  }
+
+  return 0;
+}
+
+int nghttp2_session_consume_stream(nghttp2_session *session, int32_t stream_id,
+                                   size_t size) {
+  int rv;
+  nghttp2_stream *stream;
+
+  if (stream_id == 0) {
+    return NGHTTP2_ERR_INVALID_ARGUMENT;
+  }
+
+  if (!(session->opt_flags & NGHTTP2_OPTMASK_NO_AUTO_WINDOW_UPDATE)) {
+    return NGHTTP2_ERR_INVALID_STATE;
+  }
+
+  stream = nghttp2_session_get_stream(session, stream_id);
+
+  if (!stream) {
+    return 0;
+  }
+
+  rv = session_update_stream_consumed_size(session, stream, size);
+
+  if (nghttp2_is_fatal(rv)) {
+    return rv;
+  }
+
+  return 0;
+}
+
+int nghttp2_session_set_next_stream_id(nghttp2_session *session,
+                                       int32_t next_stream_id) {
+  if (next_stream_id <= 0 ||
+      session->next_stream_id > (uint32_t)next_stream_id) {
+    return NGHTTP2_ERR_INVALID_ARGUMENT;
+  }
+
+  if (session->server) {
+    if (next_stream_id % 2) {
+      return NGHTTP2_ERR_INVALID_ARGUMENT;
+    }
+  } else if (next_stream_id % 2 == 0) {
+    return NGHTTP2_ERR_INVALID_ARGUMENT;
+  }
+
+  session->next_stream_id = (uint32_t)next_stream_id;
+  return 0;
+}
+
+uint32_t nghttp2_session_get_next_stream_id(nghttp2_session *session) {
+  return session->next_stream_id;
+}
+
+int32_t nghttp2_session_get_last_proc_stream_id(nghttp2_session *session) {
+  return session->last_proc_stream_id;
+}
+
+nghttp2_stream *nghttp2_session_find_stream(nghttp2_session *session,
+                                            int32_t stream_id) {
+  if (stream_id == 0) {
+    return &session->root;
+  }
+
+  return nghttp2_session_get_stream_raw(session, stream_id);
+}
+
+nghttp2_stream *nghttp2_session_get_root_stream(nghttp2_session *session) {
+  return &session->root;
+}
+
+int nghttp2_session_check_server_session(nghttp2_session *session) {
+  return session->server;
+}
+
+int nghttp2_session_change_stream_priority(
+    nghttp2_session *session, int32_t stream_id,
+    const nghttp2_priority_spec *pri_spec) {
+  int rv;
+  nghttp2_stream *stream;
+  nghttp2_priority_spec pri_spec_copy;
+
+  if (stream_id == 0 || stream_id == pri_spec->stream_id) {
+    return NGHTTP2_ERR_INVALID_ARGUMENT;
+  }
+
+  stream = nghttp2_session_get_stream_raw(session, stream_id);
+  if (!stream) {
+    return NGHTTP2_ERR_INVALID_ARGUMENT;
+  }
+
+  pri_spec_copy = *pri_spec;
+  nghttp2_priority_spec_normalize_weight(&pri_spec_copy);
+
+  rv = nghttp2_session_reprioritize_stream(session, stream, &pri_spec_copy);
+
+  if (nghttp2_is_fatal(rv)) {
+    return rv;
+  }
+
+  /* We don't intentionally call nghttp2_session_adjust_idle_stream()
+     so that idle stream created by this function, and existing ones
+     are kept for application.  We will adjust number of idle stream
+     in nghttp2_session_mem_send or nghttp2_session_mem_recv is
+     called. */
+  return 0;
+}
+
+int nghttp2_session_create_idle_stream(nghttp2_session *session,
+                                       int32_t stream_id,
+                                       const nghttp2_priority_spec *pri_spec) {
+  nghttp2_stream *stream;
+  nghttp2_priority_spec pri_spec_copy;
+
+  if (stream_id == 0 || stream_id == pri_spec->stream_id ||
+      !session_detect_idle_stream(session, stream_id)) {
+    return NGHTTP2_ERR_INVALID_ARGUMENT;
+  }
+
+  stream = nghttp2_session_get_stream_raw(session, stream_id);
+  if (stream) {
+    return NGHTTP2_ERR_INVALID_ARGUMENT;
+  }
+
+  pri_spec_copy = *pri_spec;
+  nghttp2_priority_spec_normalize_weight(&pri_spec_copy);
+
+  stream =
+      nghttp2_session_open_stream(session, stream_id, NGHTTP2_STREAM_FLAG_NONE,
+                                  &pri_spec_copy, NGHTTP2_STREAM_IDLE, NULL);
+  if (!stream) {
+    return NGHTTP2_ERR_NOMEM;
+  }
+
+  /* We don't intentionally call nghttp2_session_adjust_idle_stream()
+     so that idle stream created by this function, and existing ones
+     are kept for application.  We will adjust number of idle stream
+     in nghttp2_session_mem_send or nghttp2_session_mem_recv is
+     called. */
+  return 0;
+}
+
+size_t
+nghttp2_session_get_hd_inflate_dynamic_table_size(nghttp2_session *session) {
+  return nghttp2_hd_inflate_get_dynamic_table_size(&session->hd_inflater);
+}
+
+size_t
+nghttp2_session_get_hd_deflate_dynamic_table_size(nghttp2_session *session) {
+  return nghttp2_hd_deflate_get_dynamic_table_size(&session->hd_deflater);
+}
+
+void nghttp2_session_set_user_data(nghttp2_session *session, void *user_data) {
+  session->user_data = user_data;
+}
diff --git a/Utilities/cmnghttp2/lib/nghttp2_session.h b/Utilities/cmnghttp2/lib/nghttp2_session.h
new file mode 100644
index 0000000..90ead9c
--- /dev/null
+++ b/Utilities/cmnghttp2/lib/nghttp2_session.h
@@ -0,0 +1,901 @@
+/*
+ * nghttp2 - HTTP/2 C Library
+ *
+ * Copyright (c) 2012 Tatsuhiro Tsujikawa
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+#ifndef NGHTTP2_SESSION_H
+#define NGHTTP2_SESSION_H
+
+#ifdef HAVE_CONFIG_H
+#  include <config.h>
+#endif /* HAVE_CONFIG_H */
+
+#include <nghttp2/nghttp2.h>
+#include "nghttp2_map.h"
+#include "nghttp2_frame.h"
+#include "nghttp2_hd.h"
+#include "nghttp2_stream.h"
+#include "nghttp2_outbound_item.h"
+#include "nghttp2_int.h"
+#include "nghttp2_buf.h"
+#include "nghttp2_callbacks.h"
+#include "nghttp2_mem.h"
+
+/* The global variable for tests where we want to disable strict
+   preface handling. */
+extern int nghttp2_enable_strict_preface;
+
+/*
+ * Option flags.
+ */
+typedef enum {
+  NGHTTP2_OPTMASK_NO_AUTO_WINDOW_UPDATE = 1 << 0,
+  NGHTTP2_OPTMASK_NO_RECV_CLIENT_MAGIC = 1 << 1,
+  NGHTTP2_OPTMASK_NO_HTTP_MESSAGING = 1 << 2,
+  NGHTTP2_OPTMASK_NO_AUTO_PING_ACK = 1 << 3,
+  NGHTTP2_OPTMASK_NO_CLOSED_STREAMS = 1 << 4
+} nghttp2_optmask;
+
+/*
+ * bitmask for built-in type to enable the default handling for that
+ * type of the frame.
+ */
+typedef enum {
+  NGHTTP2_TYPEMASK_NONE = 0,
+  NGHTTP2_TYPEMASK_ALTSVC = 1 << 0,
+  NGHTTP2_TYPEMASK_ORIGIN = 1 << 1
+} nghttp2_typemask;
+
+typedef enum {
+  NGHTTP2_OB_POP_ITEM,
+  NGHTTP2_OB_SEND_DATA,
+  NGHTTP2_OB_SEND_NO_COPY,
+  NGHTTP2_OB_SEND_CLIENT_MAGIC
+} nghttp2_outbound_state;
+
+typedef struct {
+  nghttp2_outbound_item *item;
+  nghttp2_bufs framebufs;
+  nghttp2_outbound_state state;
+} nghttp2_active_outbound_item;
+
+/* Buffer length for inbound raw byte stream used in
+   nghttp2_session_recv(). */
+#define NGHTTP2_INBOUND_BUFFER_LENGTH 16384
+
+/* The default maximum number of incoming reserved streams */
+#define NGHTTP2_MAX_INCOMING_RESERVED_STREAMS 200
+
+/* Even if we have less SETTINGS_MAX_CONCURRENT_STREAMS than this
+   number, we keep NGHTTP2_MIN_IDLE_STREAMS streams in idle state */
+#define NGHTTP2_MIN_IDLE_STREAMS 16
+
+/* The maximum number of items in outbound queue, which is considered
+   as flooding caused by peer.  All frames are not considered here.
+   We only consider PING + ACK and SETTINGS + ACK.  This is because
+   they both are response to the frame initiated by peer and peer can
+   send as many of them as they want.  If peer does not read network,
+   response frames are stacked up, which leads to memory exhaustion.
+   The value selected here is arbitrary, but safe value and if we have
+   these frames in this number, it is considered suspicious. */
+#define NGHTTP2_DEFAULT_MAX_OBQ_FLOOD_ITEM 1000
+
+/* The default value of maximum number of concurrent streams. */
+#define NGHTTP2_DEFAULT_MAX_CONCURRENT_STREAMS 0xffffffffu
+
+/* Internal state when receiving incoming frame */
+typedef enum {
+  /* Receiving frame header */
+  NGHTTP2_IB_READ_CLIENT_MAGIC,
+  NGHTTP2_IB_READ_FIRST_SETTINGS,
+  NGHTTP2_IB_READ_HEAD,
+  NGHTTP2_IB_READ_NBYTE,
+  NGHTTP2_IB_READ_HEADER_BLOCK,
+  NGHTTP2_IB_IGN_HEADER_BLOCK,
+  NGHTTP2_IB_IGN_PAYLOAD,
+  NGHTTP2_IB_FRAME_SIZE_ERROR,
+  NGHTTP2_IB_READ_SETTINGS,
+  NGHTTP2_IB_READ_GOAWAY_DEBUG,
+  NGHTTP2_IB_EXPECT_CONTINUATION,
+  NGHTTP2_IB_IGN_CONTINUATION,
+  NGHTTP2_IB_READ_PAD_DATA,
+  NGHTTP2_IB_READ_DATA,
+  NGHTTP2_IB_IGN_DATA,
+  NGHTTP2_IB_IGN_ALL,
+  NGHTTP2_IB_READ_ALTSVC_PAYLOAD,
+  NGHTTP2_IB_READ_ORIGIN_PAYLOAD,
+  NGHTTP2_IB_READ_EXTENSION_PAYLOAD
+} nghttp2_inbound_state;
+
+typedef struct {
+  nghttp2_frame frame;
+  /* Storage for extension frame payload.  frame->ext.payload points
+     to this structure to avoid frequent memory allocation. */
+  nghttp2_ext_frame_payload ext_frame_payload;
+  /* The received SETTINGS entry.  For the standard settings entries,
+     we only keep the last seen value.  For
+     SETTINGS_HEADER_TABLE_SIZE, we also keep minimum value in the
+     last index. */
+  nghttp2_settings_entry *iv;
+  /* buffer pointers to small buffer, raw_sbuf */
+  nghttp2_buf sbuf;
+  /* buffer pointers to large buffer, raw_lbuf */
+  nghttp2_buf lbuf;
+  /* Large buffer, malloced on demand */
+  uint8_t *raw_lbuf;
+  /* The number of entry filled in |iv| */
+  size_t niv;
+  /* The number of entries |iv| can store. */
+  size_t max_niv;
+  /* How many bytes we still need to receive for current frame */
+  size_t payloadleft;
+  /* padding length for the current frame */
+  size_t padlen;
+  nghttp2_inbound_state state;
+  /* Small buffer.  Currently the largest contiguous chunk to buffer
+     is frame header.  We buffer part of payload, but they are smaller
+     than frame header. */
+  uint8_t raw_sbuf[NGHTTP2_FRAME_HDLEN];
+} nghttp2_inbound_frame;
+
+typedef struct {
+  uint32_t header_table_size;
+  uint32_t enable_push;
+  uint32_t max_concurrent_streams;
+  uint32_t initial_window_size;
+  uint32_t max_frame_size;
+  uint32_t max_header_list_size;
+  uint32_t enable_connect_protocol;
+} nghttp2_settings_storage;
+
+typedef enum {
+  NGHTTP2_GOAWAY_NONE = 0,
+  /* Flag means that connection should be terminated after sending GOAWAY. */
+  NGHTTP2_GOAWAY_TERM_ON_SEND = 0x1,
+  /* Flag means GOAWAY to terminate session has been sent */
+  NGHTTP2_GOAWAY_TERM_SENT = 0x2,
+  /* Flag means GOAWAY was sent */
+  NGHTTP2_GOAWAY_SENT = 0x4,
+  /* Flag means GOAWAY was received */
+  NGHTTP2_GOAWAY_RECV = 0x8
+} nghttp2_goaway_flag;
+
+/* nghttp2_inflight_settings stores the SETTINGS entries which local
+   endpoint has sent to the remote endpoint, and has not received ACK
+   yet. */
+struct nghttp2_inflight_settings {
+  struct nghttp2_inflight_settings *next;
+  nghttp2_settings_entry *iv;
+  size_t niv;
+};
+
+typedef struct nghttp2_inflight_settings nghttp2_inflight_settings;
+
+struct nghttp2_session {
+  nghttp2_map /* <nghttp2_stream*> */ streams;
+  /* root of dependency tree*/
+  nghttp2_stream root;
+  /* Queue for outbound urgent frames (PING and SETTINGS) */
+  nghttp2_outbound_queue ob_urgent;
+  /* Queue for non-DATA frames */
+  nghttp2_outbound_queue ob_reg;
+  /* Queue for outbound stream-creating HEADERS (request or push
+     response) frame, which are subject to
+     SETTINGS_MAX_CONCURRENT_STREAMS limit. */
+  nghttp2_outbound_queue ob_syn;
+  nghttp2_active_outbound_item aob;
+  nghttp2_inbound_frame iframe;
+  nghttp2_hd_deflater hd_deflater;
+  nghttp2_hd_inflater hd_inflater;
+  nghttp2_session_callbacks callbacks;
+  /* Memory allocator */
+  nghttp2_mem mem;
+  void *user_data;
+  /* Points to the latest incoming closed stream.  NULL if there is no
+     closed stream.  Only used when session is initialized as
+     server. */
+  nghttp2_stream *closed_stream_head;
+  /* Points to the oldest incoming closed stream.  NULL if there is no
+     closed stream.  Only used when session is initialized as
+     server. */
+  nghttp2_stream *closed_stream_tail;
+  /* Points to the latest idle stream.  NULL if there is no idle
+     stream.  Only used when session is initialized as server .*/
+  nghttp2_stream *idle_stream_head;
+  /* Points to the oldest idle stream.  NULL if there is no idle
+     stream.  Only used when session is initialized as erver. */
+  nghttp2_stream *idle_stream_tail;
+  /* Queue of In-flight SETTINGS values.  SETTINGS bearing ACK is not
+     considered as in-flight. */
+  nghttp2_inflight_settings *inflight_settings_head;
+  /* The number of outgoing streams. This will be capped by
+     remote_settings.max_concurrent_streams. */
+  size_t num_outgoing_streams;
+  /* The number of incoming streams. This will be capped by
+     local_settings.max_concurrent_streams. */
+  size_t num_incoming_streams;
+  /* The number of incoming reserved streams.  This is the number of
+     streams in reserved (remote) state.  RFC 7540 does not limit this
+     number.  nghttp2 offers
+     nghttp2_option_set_max_reserved_remote_streams() to achieve this.
+     If it is used, num_incoming_streams is capped by
+     max_incoming_reserved_streams.  Client application should
+     consider to set this because without that server can send
+     arbitrary number of PUSH_PROMISE, and exhaust client's memory. */
+  size_t num_incoming_reserved_streams;
+  /* The maximum number of incoming reserved streams (reserved
+     (remote) state).  RST_STREAM will be sent for the pushed stream
+     which exceeds this limit. */
+  size_t max_incoming_reserved_streams;
+  /* The number of closed streams still kept in |streams| hash.  The
+     closed streams can be accessed through single linked list
+     |closed_stream_head|.  The current implementation only keeps
+     incoming streams and session is initialized as server. */
+  size_t num_closed_streams;
+  /* The number of idle streams kept in |streams| hash.  The idle
+     streams can be accessed through doubly linked list
+     |idle_stream_head|.  The current implementation only keeps idle
+     streams if session is initialized as server. */
+  size_t num_idle_streams;
+  /* The number of bytes allocated for nvbuf */
+  size_t nvbuflen;
+  /* Counter for detecting flooding in outbound queue.  If it exceeds
+     max_outbound_ack, session will be closed. */
+  size_t obq_flood_counter_;
+  /* The maximum number of outgoing SETTINGS ACK and PING ACK in
+     outbound queue. */
+  size_t max_outbound_ack;
+  /* The maximum length of header block to send.  Calculated by the
+     same way as nghttp2_hd_deflate_bound() does. */
+  size_t max_send_header_block_length;
+  /* Next Stream ID. Made unsigned int to detect >= (1 << 31). */
+  uint32_t next_stream_id;
+  /* The last stream ID this session initiated.  For client session,
+     this is the last stream ID it has sent.  For server session, it
+     is the last promised stream ID sent in PUSH_PROMISE. */
+  int32_t last_sent_stream_id;
+  /* The largest stream ID received so far */
+  int32_t last_recv_stream_id;
+  /* The largest stream ID which has been processed in some way. This
+     value will be used as last-stream-id when sending GOAWAY
+     frame. */
+  int32_t last_proc_stream_id;
+  /* Counter of unique ID of PING. Wraps when it exceeds
+     NGHTTP2_MAX_UNIQUE_ID */
+  uint32_t next_unique_id;
+  /* This is the last-stream-ID we have sent in GOAWAY */
+  int32_t local_last_stream_id;
+  /* This is the value in GOAWAY frame received from remote endpoint. */
+  int32_t remote_last_stream_id;
+  /* Current sender window size. This value is computed against the
+     current initial window size of remote endpoint. */
+  int32_t remote_window_size;
+  /* Keep track of the number of bytes received without
+     WINDOW_UPDATE. This could be negative after submitting negative
+     value to WINDOW_UPDATE. */
+  int32_t recv_window_size;
+  /* The number of bytes consumed by the application and now is
+     subject to WINDOW_UPDATE.  This is only used when auto
+     WINDOW_UPDATE is turned off. */
+  int32_t consumed_size;
+  /* The amount of recv_window_size cut using submitting negative
+     value to WINDOW_UPDATE */
+  int32_t recv_reduction;
+  /* window size for local flow control. It is initially set to
+     NGHTTP2_INITIAL_CONNECTION_WINDOW_SIZE and could be
+     increased/decreased by submitting WINDOW_UPDATE. See
+     nghttp2_submit_window_update(). */
+  int32_t local_window_size;
+  /* This flag is used to indicate that the local endpoint received initial
+     SETTINGS frame from the remote endpoint. */
+  uint8_t remote_settings_received;
+  /* Settings value received from the remote endpoint. */
+  nghttp2_settings_storage remote_settings;
+  /* Settings value of the local endpoint. */
+  nghttp2_settings_storage local_settings;
+  /* Option flags. This is bitwise-OR of 0 or more of nghttp2_optmask. */
+  uint32_t opt_flags;
+  /* Unacked local SETTINGS_MAX_CONCURRENT_STREAMS value. We use this
+     to refuse the incoming stream if it exceeds this value. */
+  uint32_t pending_local_max_concurrent_stream;
+  /* The bitwise OR of zero or more of nghttp2_typemask to indicate
+     that the default handling of extension frame is enabled. */
+  uint32_t builtin_recv_ext_types;
+  /* Unacked local ENABLE_PUSH value.  We use this to refuse
+     PUSH_PROMISE before SETTINGS ACK is received. */
+  uint8_t pending_enable_push;
+  /* Unacked local ENABLE_CONNECT_PROTOCOL value.  We use this to
+     accept :protocol header field before SETTINGS_ACK is received. */
+  uint8_t pending_enable_connect_protocol;
+  /* Nonzero if the session is server side. */
+  uint8_t server;
+  /* Flags indicating GOAWAY is sent and/or received. The flags are
+     composed by bitwise OR-ing nghttp2_goaway_flag. */
+  uint8_t goaway_flags;
+  /* This flag is used to reduce excessive queuing of WINDOW_UPDATE to
+     this session.  The nonzero does not necessarily mean
+     WINDOW_UPDATE is not queued. */
+  uint8_t window_update_queued;
+  /* Bitfield of extension frame types that application is willing to
+     receive.  To designate the bit of given frame type i, use
+     user_recv_ext_types[i / 8] & (1 << (i & 0x7)).  First 10 frame
+     types are standard frame types and not used in this bitfield.  If
+     bit is set, it indicates that incoming frame with that type is
+     passed to user defined callbacks, otherwise they are ignored. */
+  uint8_t user_recv_ext_types[32];
+};
+
+/* Struct used when updating initial window size of each active
+   stream. */
+typedef struct {
+  nghttp2_session *session;
+  int32_t new_window_size, old_window_size;
+} nghttp2_update_window_size_arg;
+
+typedef struct {
+  nghttp2_session *session;
+  /* linked list of streams to close */
+  nghttp2_stream *head;
+  int32_t last_stream_id;
+  /* nonzero if GOAWAY is sent to peer, which means we are going to
+     close incoming streams.  zero if GOAWAY is received from peer and
+     we are going to close outgoing streams. */
+  int incoming;
+} nghttp2_close_stream_on_goaway_arg;
+
+/* TODO stream timeout etc */
+
+/*
+ * Returns nonzero value if |stream_id| is initiated by local
+ * endpoint.
+ */
+int nghttp2_session_is_my_stream_id(nghttp2_session *session,
+                                    int32_t stream_id);
+
+/*
+ * Adds |item| to the outbound queue in |session|.  When this function
+ * succeeds, it takes ownership of |item|. So caller must not free it
+ * on success.
+ *
+ * This function returns 0 if it succeeds, or one of the following
+ * negative error codes:
+ *
+ * NGHTTP2_ERR_NOMEM
+ *     Out of memory.
+ * NGHTTP2_ERR_STREAM_CLOSED
+ *     Stream already closed (DATA and PUSH_PROMISE frame only)
+ */
+int nghttp2_session_add_item(nghttp2_session *session,
+                             nghttp2_outbound_item *item);
+
+/*
+ * Adds RST_STREAM frame for the stream |stream_id| with the error
+ * code |error_code|. This is a convenient function built on top of
+ * nghttp2_session_add_frame() to add RST_STREAM easily.
+ *
+ * This function simply returns 0 without adding RST_STREAM frame if
+ * given stream is in NGHTTP2_STREAM_CLOSING state, because multiple
+ * RST_STREAM for a stream is redundant.
+ *
+ * This function returns 0 if it succeeds, or one of the following
+ * negative error codes:
+ *
+ * NGHTTP2_ERR_NOMEM
+ *     Out of memory.
+ */
+int nghttp2_session_add_rst_stream(nghttp2_session *session, int32_t stream_id,
+                                   uint32_t error_code);
+
+/*
+ * Adds PING frame. This is a convenient functin built on top of
+ * nghttp2_session_add_frame() to add PING easily.
+ *
+ * If the |opaque_data| is not NULL, it must point to 8 bytes memory
+ * region of data. The data pointed by |opaque_data| is copied. It can
+ * be NULL. In this case, 8 bytes NULL is used.
+ *
+ * This function returns 0 if it succeeds, or one of the following
+ * negative error codes:
+ *
+ * NGHTTP2_ERR_NOMEM
+ *     Out of memory.
+ * NGHTTP2_ERR_FLOODED
+ *     There are too many items in outbound queue; this only happens
+ *     if NGHTTP2_FLAG_ACK is set in |flags|
+ */
+int nghttp2_session_add_ping(nghttp2_session *session, uint8_t flags,
+                             const uint8_t *opaque_data);
+
+/*
+ * Adds GOAWAY frame with the last-stream-ID |last_stream_id| and the
+ * error code |error_code|. This is a convenient function built on top
+ * of nghttp2_session_add_frame() to add GOAWAY easily.  The
+ * |aux_flags| are bitwise-OR of one or more of
+ * nghttp2_goaway_aux_flag.
+ *
+ * This function returns 0 if it succeeds, or one of the following
+ * negative error codes:
+ *
+ * NGHTTP2_ERR_NOMEM
+ *     Out of memory.
+ * NGHTTP2_ERR_INVALID_ARGUMENT
+ *     The |opaque_data_len| is too large.
+ */
+int nghttp2_session_add_goaway(nghttp2_session *session, int32_t last_stream_id,
+                               uint32_t error_code, const uint8_t *opaque_data,
+                               size_t opaque_data_len, uint8_t aux_flags);
+
+/*
+ * Adds WINDOW_UPDATE frame with stream ID |stream_id| and
+ * window-size-increment |window_size_increment|. This is a convenient
+ * function built on top of nghttp2_session_add_frame() to add
+ * WINDOW_UPDATE easily.
+ *
+ * This function returns 0 if it succeeds, or one of the following
+ * negative error codes:
+ *
+ * NGHTTP2_ERR_NOMEM
+ *     Out of memory.
+ */
+int nghttp2_session_add_window_update(nghttp2_session *session, uint8_t flags,
+                                      int32_t stream_id,
+                                      int32_t window_size_increment);
+
+/*
+ * Adds SETTINGS frame.
+ *
+ * This function returns 0 if it succeeds, or one of the following
+ * negative error codes:
+ *
+ * NGHTTP2_ERR_NOMEM
+ *     Out of memory.
+ * NGHTTP2_ERR_FLOODED
+ *     There are too many items in outbound queue; this only happens
+ *     if NGHTTP2_FLAG_ACK is set in |flags|
+ */
+int nghttp2_session_add_settings(nghttp2_session *session, uint8_t flags,
+                                 const nghttp2_settings_entry *iv, size_t niv);
+
+/*
+ * Creates new stream in |session| with stream ID |stream_id|,
+ * priority |pri_spec| and flags |flags|.  The |flags| is bitwise OR
+ * of nghttp2_stream_flag.  Since this function is called when initial
+ * HEADERS is sent or received, these flags are taken from it.  The
+ * state of stream is set to |initial_state|. The |stream_user_data|
+ * is a pointer to the arbitrary user supplied data to be associated
+ * to this stream.
+ *
+ * If |initial_state| is NGHTTP2_STREAM_RESERVED, this function sets
+ * NGHTTP2_STREAM_FLAG_PUSH flag set.
+ *
+ * This function returns a pointer to created new stream object, or
+ * NULL.
+ *
+ * This function adjusts neither the number of closed streams or idle
+ * streams.  The caller should manually call
+ * nghttp2_session_adjust_closed_stream() or
+ * nghttp2_session_adjust_idle_stream() respectively.
+ */
+nghttp2_stream *nghttp2_session_open_stream(nghttp2_session *session,
+                                            int32_t stream_id, uint8_t flags,
+                                            nghttp2_priority_spec *pri_spec,
+                                            nghttp2_stream_state initial_state,
+                                            void *stream_user_data);
+
+/*
+ * Closes stream whose stream ID is |stream_id|. The reason of closure
+ * is indicated by the |error_code|. When closing the stream,
+ * on_stream_close_callback will be called.
+ *
+ * If the session is initialized as server and |stream| is incoming
+ * stream, stream is just marked closed and this function calls
+ * nghttp2_session_keep_closed_stream() with |stream|.  Otherwise,
+ * |stream| will be deleted from memory.
+ *
+ * This function returns 0 if it succeeds, or one the following
+ * negative error codes:
+ *
+ * NGHTTP2_ERR_NOMEM
+ *     Out of memory
+ * NGHTTP2_ERR_INVALID_ARGUMENT
+ *     The specified stream does not exist.
+ * NGHTTP2_ERR_CALLBACK_FAILURE
+ *     The callback function failed.
+ */
+int nghttp2_session_close_stream(nghttp2_session *session, int32_t stream_id,
+                                 uint32_t error_code);
+
+/*
+ * Deletes |stream| from memory.  After this function returns, stream
+ * cannot be accessed.
+ *
+ * This function returns 0 if it succeeds, or one the following
+ * negative error codes:
+ *
+ * NGHTTP2_ERR_NOMEM
+ *     Out of memory
+ */
+int nghttp2_session_destroy_stream(nghttp2_session *session,
+                                   nghttp2_stream *stream);
+
+/*
+ * Tries to keep incoming closed stream |stream|.  Due to the
+ * limitation of maximum number of streams in memory, |stream| is not
+ * closed and just deleted from memory (see
+ * nghttp2_session_destroy_stream).
+ */
+void nghttp2_session_keep_closed_stream(nghttp2_session *session,
+                                        nghttp2_stream *stream);
+
+/*
+ * Appends |stream| to linked list |session->idle_stream_head|.  We
+ * apply fixed limit for list size.  To fit into that limit, one or
+ * more oldest streams are removed from list as necessary.
+ */
+void nghttp2_session_keep_idle_stream(nghttp2_session *session,
+                                      nghttp2_stream *stream);
+
+/*
+ * Detaches |stream| from idle streams linked list.
+ */
+void nghttp2_session_detach_idle_stream(nghttp2_session *session,
+                                        nghttp2_stream *stream);
+
+/*
+ * Deletes closed stream to ensure that number of incoming streams
+ * including active and closed is in the maximum number of allowed
+ * stream.
+ *
+ * This function returns 0 if it succeeds, or one the following
+ * negative error codes:
+ *
+ * NGHTTP2_ERR_NOMEM
+ *     Out of memory
+ */
+int nghttp2_session_adjust_closed_stream(nghttp2_session *session);
+
+/*
+ * Deletes idle stream to ensure that number of idle streams is in
+ * certain limit.
+ *
+ * This function returns 0 if it succeeds, or one the following
+ * negative error codes:
+ *
+ * NGHTTP2_ERR_NOMEM
+ *     Out of memory
+ */
+int nghttp2_session_adjust_idle_stream(nghttp2_session *session);
+
+/*
+ * If further receptions and transmissions over the stream |stream_id|
+ * are disallowed, close the stream with error code NGHTTP2_NO_ERROR.
+ *
+ * This function returns 0 if it
+ * succeeds, or one of the following negative error codes:
+ *
+ * NGHTTP2_ERR_INVALID_ARGUMENT
+ *     The specified stream does not exist.
+ */
+int nghttp2_session_close_stream_if_shut_rdwr(nghttp2_session *session,
+                                              nghttp2_stream *stream);
+
+int nghttp2_session_on_request_headers_received(nghttp2_session *session,
+                                                nghttp2_frame *frame);
+
+int nghttp2_session_on_response_headers_received(nghttp2_session *session,
+                                                 nghttp2_frame *frame,
+                                                 nghttp2_stream *stream);
+
+int nghttp2_session_on_push_response_headers_received(nghttp2_session *session,
+                                                      nghttp2_frame *frame,
+                                                      nghttp2_stream *stream);
+
+/*
+ * Called when HEADERS is received, assuming |frame| is properly
+ * initialized.  This function does first validate received frame and
+ * then open stream and call callback functions.
+ *
+ * This function returns 0 if it succeeds, or one of the following
+ * negative error codes:
+ *
+ * NGHTTP2_ERR_NOMEM
+ *     Out of memory.
+ * NGHTTP2_ERR_IGN_HEADER_BLOCK
+ *     Frame was rejected and header block must be decoded but
+ *     result must be ignored.
+ * NGHTTP2_ERR_CALLBACK_FAILURE
+ *     The read_callback failed
+ */
+int nghttp2_session_on_headers_received(nghttp2_session *session,
+                                        nghttp2_frame *frame,
+                                        nghttp2_stream *stream);
+
+/*
+ * Called when PRIORITY is received, assuming |frame| is properly
+ * initialized.
+ *
+ * This function returns 0 if it succeeds, or one of the following
+ * negative error codes:
+ *
+ * NGHTTP2_ERR_NOMEM
+ *     Out of memory.
+ * NGHTTP2_ERR_CALLBACK_FAILURE
+ *     The read_callback failed
+ */
+int nghttp2_session_on_priority_received(nghttp2_session *session,
+                                         nghttp2_frame *frame);
+
+/*
+ * Called when RST_STREAM is received, assuming |frame| is properly
+ * initialized.
+ *
+ * This function returns 0 if it succeeds, or one the following
+ * negative error codes:
+ *
+ * NGHTTP2_ERR_NOMEM
+ *     Out of memory
+ * NGHTTP2_ERR_CALLBACK_FAILURE
+ *     The read_callback failed
+ */
+int nghttp2_session_on_rst_stream_received(nghttp2_session *session,
+                                           nghttp2_frame *frame);
+
+/*
+ * Called when SETTINGS is received, assuming |frame| is properly
+ * initialized. If |noack| is non-zero, SETTINGS with ACK will not be
+ * submitted. If |frame| has NGHTTP2_FLAG_ACK flag set, no SETTINGS
+ * with ACK will not be submitted regardless of |noack|.
+ *
+ * This function returns 0 if it succeeds, or one the following
+ * negative error codes:
+ *
+ * NGHTTP2_ERR_NOMEM
+ *     Out of memory
+ * NGHTTP2_ERR_CALLBACK_FAILURE
+ *     The read_callback failed
+ * NGHTTP2_ERR_FLOODED
+ *     There are too many items in outbound queue, and this is most
+ *     likely caused by misbehaviour of peer.
+ */
+int nghttp2_session_on_settings_received(nghttp2_session *session,
+                                         nghttp2_frame *frame, int noack);
+
+/*
+ * Called when PUSH_PROMISE is received, assuming |frame| is properly
+ * initialized.
+ *
+ * This function returns 0 if it succeeds, or one of the following
+ * negative error codes:
+ *
+ * NGHTTP2_ERR_NOMEM
+ *     Out of memory.
+ * NGHTTP2_ERR_IGN_HEADER_BLOCK
+ *     Frame was rejected and header block must be decoded but
+ *     result must be ignored.
+ * NGHTTP2_ERR_CALLBACK_FAILURE
+ *     The read_callback failed
+ */
+int nghttp2_session_on_push_promise_received(nghttp2_session *session,
+                                             nghttp2_frame *frame);
+
+/*
+ * Called when PING is received, assuming |frame| is properly
+ * initialized.
+ *
+ * This function returns 0 if it succeeds, or one of the following
+ * negative error codes:
+ *
+ * NGHTTP2_ERR_NOMEM
+ *     Out of memory.
+ * NGHTTP2_ERR_CALLBACK_FAILURE
+ *     The callback function failed.
+ * NGHTTP2_ERR_FLOODED
+ *     There are too many items in outbound queue, and this is most
+ *     likely caused by misbehaviour of peer.
+ */
+int nghttp2_session_on_ping_received(nghttp2_session *session,
+                                     nghttp2_frame *frame);
+
+/*
+ * Called when GOAWAY is received, assuming |frame| is properly
+ * initialized.
+ *
+ * This function returns 0 if it succeeds, or one of the following
+ * negative error codes:
+ *
+ * NGHTTP2_ERR_NOMEM
+ *     Out of memory.
+ * NGHTTP2_ERR_CALLBACK_FAILURE
+ *     The callback function failed.
+ */
+int nghttp2_session_on_goaway_received(nghttp2_session *session,
+                                       nghttp2_frame *frame);
+
+/*
+ * Called when WINDOW_UPDATE is received, assuming |frame| is properly
+ * initialized.
+ *
+ * This function returns 0 if it succeeds, or one of the following
+ * negative error codes:
+ *
+ * NGHTTP2_ERR_NOMEM
+ *     Out of memory.
+ * NGHTTP2_ERR_CALLBACK_FAILURE
+ *     The callback function failed.
+ */
+int nghttp2_session_on_window_update_received(nghttp2_session *session,
+                                              nghttp2_frame *frame);
+
+/*
+ * Called when ALTSVC is received, assuming |frame| is properly
+ * initialized.
+ *
+ * This function returns 0 if it succeeds, or one of the following
+ * negative error codes:
+ *
+ * NGHTTP2_ERR_CALLBACK_FAILURE
+ *     The callback function failed.
+ */
+int nghttp2_session_on_altsvc_received(nghttp2_session *session,
+                                       nghttp2_frame *frame);
+
+/*
+ * Called when ORIGIN is received, assuming |frame| is properly
+ * initialized.
+ *
+ * This function returns 0 if it succeeds, or one of the following
+ * negative error codes:
+ *
+ * NGHTTP2_ERR_CALLBACK_FAILURE
+ *     The callback function failed.
+ */
+int nghttp2_session_on_origin_received(nghttp2_session *session,
+                                       nghttp2_frame *frame);
+
+/*
+ * Called when DATA is received, assuming |frame| is properly
+ * initialized.
+ *
+ * This function returns 0 if it succeeds, or one of the following
+ * negative error codes:
+ *
+ * NGHTTP2_ERR_NOMEM
+ *     Out of memory.
+ * NGHTTP2_ERR_CALLBACK_FAILURE
+ *     The callback function failed.
+ */
+int nghttp2_session_on_data_received(nghttp2_session *session,
+                                     nghttp2_frame *frame);
+
+/*
+ * Returns nghttp2_stream* object whose stream ID is |stream_id|.  It
+ * could be NULL if such stream does not exist.  This function returns
+ * NULL if stream is marked as closed.
+ */
+nghttp2_stream *nghttp2_session_get_stream(nghttp2_session *session,
+                                           int32_t stream_id);
+
+/*
+ * This function behaves like nghttp2_session_get_stream(), but it
+ * returns stream object even if it is marked as closed or in
+ * NGHTTP2_STREAM_IDLE state.
+ */
+nghttp2_stream *nghttp2_session_get_stream_raw(nghttp2_session *session,
+                                               int32_t stream_id);
+
+/*
+ * Packs DATA frame |frame| in wire frame format and stores it in
+ * |bufs|.  Payload will be read using |aux_data->data_prd|.  The
+ * length of payload is at most |datamax| bytes.
+ *
+ * This function returns 0 if it succeeds, or one of the following
+ * negative error codes:
+ *
+ * NGHTTP2_ERR_DEFERRED
+ *     The DATA frame is postponed.
+ * NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE
+ *     The read_callback failed (stream error).
+ * NGHTTP2_ERR_NOMEM
+ *     Out of memory.
+ * NGHTTP2_ERR_CALLBACK_FAILURE
+ *     The read_callback failed (session error).
+ */
+int nghttp2_session_pack_data(nghttp2_session *session, nghttp2_bufs *bufs,
+                              size_t datamax, nghttp2_frame *frame,
+                              nghttp2_data_aux_data *aux_data,
+                              nghttp2_stream *stream);
+
+/*
+ * Pops and returns next item to send.  If there is no such item,
+ * returns NULL.  This function takes into account max concurrent
+ * streams.  That means if session->ob_syn has item and max concurrent
+ * streams is reached, the even if other queues contain items, then
+ * this function returns NULL.
+ */
+nghttp2_outbound_item *
+nghttp2_session_pop_next_ob_item(nghttp2_session *session);
+
+/*
+ * Returns next item to send.  If there is no such item, this function
+ * returns NULL.  This function takes into account max concurrent
+ * streams.  That means if session->ob_syn has item and max concurrent
+ * streams is reached, the even if other queues contain items, then
+ * this function returns NULL.
+ */
+nghttp2_outbound_item *
+nghttp2_session_get_next_ob_item(nghttp2_session *session);
+
+/*
+ * Updates local settings with the |iv|. The number of elements in the
+ * array pointed by the |iv| is given by the |niv|.  This function
+ * assumes that the all settings_id member in |iv| are in range 1 to
+ * NGHTTP2_SETTINGS_MAX, inclusive.
+ *
+ * While updating individual stream's local window size, if the window
+ * size becomes strictly larger than NGHTTP2_MAX_WINDOW_SIZE,
+ * RST_STREAM is issued against such a stream.
+ *
+ * This function returns 0 if it succeeds, or one of the following
+ * negative error codes:
+ *
+ * NGHTTP2_ERR_NOMEM
+ *     Out of memory
+ */
+int nghttp2_session_update_local_settings(nghttp2_session *session,
+                                          nghttp2_settings_entry *iv,
+                                          size_t niv);
+
+/*
+ * Re-prioritize |stream|. The new priority specification is
+ * |pri_spec|.  Caller must ensure that stream->hd.stream_id !=
+ * pri_spec->stream_id.
+ *
+ * This function does not adjust the number of idle streams.  The
+ * caller should call nghttp2_session_adjust_idle_stream() later.
+ *
+ * This function returns 0 if it succeeds, or one of the following
+ * negative error codes:
+ *
+ * NGHTTP2_ERR_NOMEM
+ *     Out of memory
+ */
+int nghttp2_session_reprioritize_stream(nghttp2_session *session,
+                                        nghttp2_stream *stream,
+                                        const nghttp2_priority_spec *pri_spec);
+
+/*
+ * Terminates current |session| with the |error_code|.  The |reason|
+ * is NULL-terminated debug string.
+ *
+ * This function returns 0 if it succeeds, or one of the following
+ * negative error codes:
+ *
+ * NGHTTP2_ERR_NOMEM
+ *     Out of memory.
+ * NGHTTP2_ERR_INVALID_ARGUMENT
+ *     The |reason| is too long.
+ */
+int nghttp2_session_terminate_session_with_reason(nghttp2_session *session,
+                                                  uint32_t error_code,
+                                                  const char *reason);
+
+#endif /* NGHTTP2_SESSION_H */
diff --git a/Utilities/cmnghttp2/lib/nghttp2_stream.c b/Utilities/cmnghttp2/lib/nghttp2_stream.c
new file mode 100644
index 0000000..dc3a6b1
--- /dev/null
+++ b/Utilities/cmnghttp2/lib/nghttp2_stream.c
@@ -0,0 +1,1001 @@
+/*
+ * nghttp2 - HTTP/2 C Library
+ *
+ * Copyright (c) 2012 Tatsuhiro Tsujikawa
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+#include "nghttp2_stream.h"
+
+#include <assert.h>
+#include <stdio.h>
+
+#include "nghttp2_session.h"
+#include "nghttp2_helper.h"
+#include "nghttp2_debug.h"
+#include "nghttp2_frame.h"
+
+/* Maximum distance between any two stream's cycle in the same
+   prirority queue.  Imagine stream A's cycle is A, and stream B's
+   cycle is B, and A < B.  The cycle is unsigned 32 bit integer, it
+   may get overflow.  Because of how we calculate the next cycle
+   value, if B - A is less than or equals to
+   NGHTTP2_MAX_CYCLE_DISTANCE, A and B are in the same scale, in other
+   words, B is really greater than or equal to A.  Otherwise, A is a
+   result of overflow, and it is actually A > B if we consider that
+   fact. */
+#define NGHTTP2_MAX_CYCLE_DISTANCE                                             \
+  ((uint64_t)NGHTTP2_MAX_FRAME_SIZE_MAX * 256 + 255)
+
+static int stream_less(const void *lhsx, const void *rhsx) {
+  const nghttp2_stream *lhs, *rhs;
+
+  lhs = nghttp2_struct_of(lhsx, nghttp2_stream, pq_entry);
+  rhs = nghttp2_struct_of(rhsx, nghttp2_stream, pq_entry);
+
+  if (lhs->cycle == rhs->cycle) {
+    return lhs->seq < rhs->seq;
+  }
+
+  return rhs->cycle - lhs->cycle <= NGHTTP2_MAX_CYCLE_DISTANCE;
+}
+
+void nghttp2_stream_init(nghttp2_stream *stream, int32_t stream_id,
+                         uint8_t flags, nghttp2_stream_state initial_state,
+                         int32_t weight, int32_t remote_initial_window_size,
+                         int32_t local_initial_window_size,
+                         void *stream_user_data, nghttp2_mem *mem) {
+  nghttp2_map_entry_init(&stream->map_entry, (key_type)stream_id);
+  nghttp2_pq_init(&stream->obq, stream_less, mem);
+
+  stream->stream_id = stream_id;
+  stream->flags = flags;
+  stream->state = initial_state;
+  stream->shut_flags = NGHTTP2_SHUT_NONE;
+  stream->stream_user_data = stream_user_data;
+  stream->item = NULL;
+  stream->remote_window_size = remote_initial_window_size;
+  stream->local_window_size = local_initial_window_size;
+  stream->recv_window_size = 0;
+  stream->consumed_size = 0;
+  stream->recv_reduction = 0;
+  stream->window_update_queued = 0;
+
+  stream->dep_prev = NULL;
+  stream->dep_next = NULL;
+  stream->sib_prev = NULL;
+  stream->sib_next = NULL;
+
+  stream->closed_prev = NULL;
+  stream->closed_next = NULL;
+
+  stream->weight = weight;
+  stream->sum_dep_weight = 0;
+
+  stream->http_flags = NGHTTP2_HTTP_FLAG_NONE;
+  stream->content_length = -1;
+  stream->recv_content_length = 0;
+  stream->status_code = -1;
+
+  stream->queued = 0;
+  stream->descendant_last_cycle = 0;
+  stream->cycle = 0;
+  stream->pending_penalty = 0;
+  stream->descendant_next_seq = 0;
+  stream->seq = 0;
+  stream->last_writelen = 0;
+}
+
+void nghttp2_stream_free(nghttp2_stream *stream) {
+  nghttp2_pq_free(&stream->obq);
+  /* We don't free stream->item.  If it is assigned to aob, then
+     active_outbound_item_reset() will delete it.  Otherwise,
+     nghttp2_stream_close() or session_del() will delete it. */
+}
+
+void nghttp2_stream_shutdown(nghttp2_stream *stream, nghttp2_shut_flag flag) {
+  stream->shut_flags = (uint8_t)(stream->shut_flags | flag);
+}
+
+/*
+ * Returns nonzero if |stream| is active.  This function does not take
+ * into account its descendants.
+ */
+static int stream_active(nghttp2_stream *stream) {
+  return stream->item &&
+         (stream->flags & NGHTTP2_STREAM_FLAG_DEFERRED_ALL) == 0;
+}
+
+/*
+ * Returns nonzero if |stream| or one of its descendants is active
+ */
+static int stream_subtree_active(nghttp2_stream *stream) {
+  return stream_active(stream) || !nghttp2_pq_empty(&stream->obq);
+}
+
+/*
+ * Returns next cycle for |stream|.
+ */
+static void stream_next_cycle(nghttp2_stream *stream, uint64_t last_cycle) {
+  uint64_t penalty;
+
+  penalty = (uint64_t)stream->last_writelen * NGHTTP2_MAX_WEIGHT +
+            stream->pending_penalty;
+
+  stream->cycle = last_cycle + penalty / (uint32_t)stream->weight;
+  stream->pending_penalty = (uint32_t)(penalty % (uint32_t)stream->weight);
+}
+
+static int stream_obq_push(nghttp2_stream *dep_stream, nghttp2_stream *stream) {
+  int rv;
+
+  for (; dep_stream && !stream->queued;
+       stream = dep_stream, dep_stream = dep_stream->dep_prev) {
+    stream_next_cycle(stream, dep_stream->descendant_last_cycle);
+    stream->seq = dep_stream->descendant_next_seq++;
+
+    DEBUGF("stream: stream=%d obq push cycle=%lu\n", stream->stream_id,
+           stream->cycle);
+
+    DEBUGF("stream: push stream %d to stream %d\n", stream->stream_id,
+           dep_stream->stream_id);
+
+    rv = nghttp2_pq_push(&dep_stream->obq, &stream->pq_entry);
+    if (rv != 0) {
+      return rv;
+    }
+    stream->queued = 1;
+  }
+
+  return 0;
+}
+
+/*
+ * Removes |stream| from parent's obq.  If removal of |stream| makes
+ * parent's obq empty, and parent is not active, then parent is also
+ * removed.  This process is repeated recursively.
+ */
+static void stream_obq_remove(nghttp2_stream *stream) {
+  nghttp2_stream *dep_stream;
+
+  dep_stream = stream->dep_prev;
+
+  if (!stream->queued) {
+    return;
+  }
+
+  for (; dep_stream; stream = dep_stream, dep_stream = dep_stream->dep_prev) {
+    DEBUGF("stream: remove stream %d from stream %d\n", stream->stream_id,
+           dep_stream->stream_id);
+
+    nghttp2_pq_remove(&dep_stream->obq, &stream->pq_entry);
+
+    assert(stream->queued);
+
+    stream->queued = 0;
+    stream->cycle = 0;
+    stream->pending_penalty = 0;
+    stream->descendant_last_cycle = 0;
+    stream->last_writelen = 0;
+
+    if (stream_subtree_active(dep_stream)) {
+      return;
+    }
+  }
+}
+
+/*
+ * Moves |stream| from |src|'s obq to |dest|'s obq.  Removal from
+ * |src|'s obq is just done calling nghttp2_pq_remove(), so it does
+ * not recursively remove |src| and ancestors, like
+ * stream_obq_remove().
+ */
+static int stream_obq_move(nghttp2_stream *dest, nghttp2_stream *src,
+                           nghttp2_stream *stream) {
+  if (!stream->queued) {
+    return 0;
+  }
+
+  DEBUGF("stream: remove stream %d from stream %d (move)\n", stream->stream_id,
+         src->stream_id);
+
+  nghttp2_pq_remove(&src->obq, &stream->pq_entry);
+  stream->queued = 0;
+
+  return stream_obq_push(dest, stream);
+}
+
+void nghttp2_stream_reschedule(nghttp2_stream *stream) {
+  nghttp2_stream *dep_stream;
+
+  assert(stream->queued);
+
+  dep_stream = stream->dep_prev;
+
+  for (; dep_stream; stream = dep_stream, dep_stream = dep_stream->dep_prev) {
+    nghttp2_pq_remove(&dep_stream->obq, &stream->pq_entry);
+
+    stream_next_cycle(stream, dep_stream->descendant_last_cycle);
+    stream->seq = dep_stream->descendant_next_seq++;
+
+    nghttp2_pq_push(&dep_stream->obq, &stream->pq_entry);
+
+    DEBUGF("stream: stream=%d obq resched cycle=%lu\n", stream->stream_id,
+           stream->cycle);
+
+    dep_stream->last_writelen = stream->last_writelen;
+  }
+}
+
+void nghttp2_stream_change_weight(nghttp2_stream *stream, int32_t weight) {
+  nghttp2_stream *dep_stream;
+  uint64_t last_cycle;
+  int32_t old_weight;
+  uint64_t wlen_penalty;
+
+  if (stream->weight == weight) {
+    return;
+  }
+
+  old_weight = stream->weight;
+  stream->weight = weight;
+
+  dep_stream = stream->dep_prev;
+
+  if (!dep_stream) {
+    return;
+  }
+
+  dep_stream->sum_dep_weight += weight - old_weight;
+
+  if (!stream->queued) {
+    return;
+  }
+
+  nghttp2_pq_remove(&dep_stream->obq, &stream->pq_entry);
+
+  wlen_penalty = (uint64_t)stream->last_writelen * NGHTTP2_MAX_WEIGHT;
+
+  /* Compute old stream->pending_penalty we used to calculate
+     stream->cycle */
+  stream->pending_penalty =
+      (uint32_t)((stream->pending_penalty + (uint32_t)old_weight -
+                  (wlen_penalty % (uint32_t)old_weight)) %
+                 (uint32_t)old_weight);
+
+  last_cycle = stream->cycle -
+               (wlen_penalty + stream->pending_penalty) / (uint32_t)old_weight;
+
+  /* Now we have old stream->pending_penalty and new stream->weight in
+     place */
+  stream_next_cycle(stream, last_cycle);
+
+  if (dep_stream->descendant_last_cycle - stream->cycle <=
+      NGHTTP2_MAX_CYCLE_DISTANCE) {
+    stream->cycle = dep_stream->descendant_last_cycle;
+  }
+
+  /* Continue to use same stream->seq */
+
+  nghttp2_pq_push(&dep_stream->obq, &stream->pq_entry);
+
+  DEBUGF("stream: stream=%d obq resched cycle=%lu\n", stream->stream_id,
+         stream->cycle);
+}
+
+static nghttp2_stream *stream_last_sib(nghttp2_stream *stream) {
+  for (; stream->sib_next; stream = stream->sib_next)
+    ;
+
+  return stream;
+}
+
+int32_t nghttp2_stream_dep_distributed_weight(nghttp2_stream *stream,
+                                              int32_t weight) {
+  weight = stream->weight * weight / stream->sum_dep_weight;
+
+  return nghttp2_max(1, weight);
+}
+
+#ifdef STREAM_DEP_DEBUG
+
+static void ensure_inactive(nghttp2_stream *stream) {
+  nghttp2_stream *si;
+
+  if (stream->queued) {
+    fprintf(stderr, "stream(%p)=%d, stream->queued = 1; want 0\n", stream,
+            stream->stream_id);
+    assert(0);
+  }
+
+  if (stream_active(stream)) {
+    fprintf(stderr, "stream(%p)=%d, stream_active(stream) = 1; want 0\n",
+            stream, stream->stream_id);
+    assert(0);
+  }
+
+  if (!nghttp2_pq_empty(&stream->obq)) {
+    fprintf(stderr, "stream(%p)=%d, nghttp2_pq_size() = %zu; want 0\n", stream,
+            stream->stream_id, nghttp2_pq_size(&stream->obq));
+    assert(0);
+  }
+
+  for (si = stream->dep_next; si; si = si->sib_next) {
+    ensure_inactive(si);
+  }
+}
+
+static void check_queued(nghttp2_stream *stream) {
+  nghttp2_stream *si;
+  int queued;
+
+  if (stream->queued) {
+    if (!stream_subtree_active(stream)) {
+      fprintf(stderr,
+              "stream(%p)=%d, stream->queued == 1, but "
+              "stream_active() == %d and nghttp2_pq_size(&stream->obq) = %zu\n",
+              stream, stream->stream_id, stream_active(stream),
+              nghttp2_pq_size(&stream->obq));
+      assert(0);
+    }
+    if (!stream_active(stream)) {
+      queued = 0;
+      for (si = stream->dep_next; si; si = si->sib_next) {
+        if (si->queued) {
+          ++queued;
+        }
+      }
+      if (queued == 0) {
+        fprintf(stderr,
+                "stream(%p)=%d, stream->queued == 1, and "
+                "!stream_active(), but no descendants is queued\n",
+                stream, stream->stream_id);
+        assert(0);
+      }
+    }
+
+    for (si = stream->dep_next; si; si = si->sib_next) {
+      check_queued(si);
+    }
+  } else {
+    if (stream_active(stream) || !nghttp2_pq_empty(&stream->obq)) {
+      fprintf(stderr,
+              "stream(%p) = %d, stream->queued == 0, but "
+              "stream_active(stream) == %d and "
+              "nghttp2_pq_size(&stream->obq) = %zu\n",
+              stream, stream->stream_id, stream_active(stream),
+              nghttp2_pq_size(&stream->obq));
+      assert(0);
+    }
+    for (si = stream->dep_next; si; si = si->sib_next) {
+      ensure_inactive(si);
+    }
+  }
+}
+
+static void check_sum_dep(nghttp2_stream *stream) {
+  nghttp2_stream *si;
+  int32_t n = 0;
+  for (si = stream->dep_next; si; si = si->sib_next) {
+    n += si->weight;
+  }
+  if (n != stream->sum_dep_weight) {
+    fprintf(stderr, "stream(%p)=%d, sum_dep_weight = %d; want %d\n", stream,
+            stream->stream_id, n, stream->sum_dep_weight);
+    assert(0);
+  }
+  for (si = stream->dep_next; si; si = si->sib_next) {
+    check_sum_dep(si);
+  }
+}
+
+static void check_dep_prev(nghttp2_stream *stream) {
+  nghttp2_stream *si;
+  for (si = stream->dep_next; si; si = si->sib_next) {
+    if (si->dep_prev != stream) {
+      fprintf(stderr, "si->dep_prev = %p; want %p\n", si->dep_prev, stream);
+      assert(0);
+    }
+    check_dep_prev(si);
+  }
+}
+
+#endif /* STREAM_DEP_DEBUG */
+
+#ifdef STREAM_DEP_DEBUG
+static void validate_tree(nghttp2_stream *stream) {
+  nghttp2_stream *si;
+
+  if (!stream) {
+    return;
+  }
+
+  for (; stream->dep_prev; stream = stream->dep_prev)
+    ;
+
+  assert(stream->stream_id == 0);
+  assert(!stream->queued);
+
+  fprintf(stderr, "checking...\n");
+  if (nghttp2_pq_empty(&stream->obq)) {
+    fprintf(stderr, "root obq empty\n");
+    for (si = stream->dep_next; si; si = si->sib_next) {
+      ensure_inactive(si);
+    }
+  } else {
+    for (si = stream->dep_next; si; si = si->sib_next) {
+      check_queued(si);
+    }
+  }
+
+  check_sum_dep(stream);
+  check_dep_prev(stream);
+}
+#else  /* !STREAM_DEP_DEBUG */
+static void validate_tree(nghttp2_stream *stream) { (void)stream; }
+#endif /* !STREAM_DEP_DEBUG*/
+
+static int stream_update_dep_on_attach_item(nghttp2_stream *stream) {
+  int rv;
+
+  rv = stream_obq_push(stream->dep_prev, stream);
+  if (rv != 0) {
+    return rv;
+  }
+
+  validate_tree(stream);
+  return 0;
+}
+
+static int stream_update_dep_on_detach_item(nghttp2_stream *stream) {
+  if (nghttp2_pq_empty(&stream->obq)) {
+    stream_obq_remove(stream);
+  }
+
+  validate_tree(stream);
+
+  return 0;
+}
+
+int nghttp2_stream_attach_item(nghttp2_stream *stream,
+                               nghttp2_outbound_item *item) {
+  int rv;
+
+  assert((stream->flags & NGHTTP2_STREAM_FLAG_DEFERRED_ALL) == 0);
+  assert(stream->item == NULL);
+
+  DEBUGF("stream: stream=%d attach item=%p\n", stream->stream_id, item);
+
+  stream->item = item;
+
+  rv = stream_update_dep_on_attach_item(stream);
+  if (rv != 0) {
+    /* This may relave stream->queued == 1, but stream->item == NULL.
+       But only consequence of this error is fatal one, and session
+       destruction.  In that execution path, these inconsistency does
+       not matter. */
+    stream->item = NULL;
+    return rv;
+  }
+
+  return 0;
+}
+
+int nghttp2_stream_detach_item(nghttp2_stream *stream) {
+  DEBUGF("stream: stream=%d detach item=%p\n", stream->stream_id, stream->item);
+
+  stream->item = NULL;
+  stream->flags = (uint8_t)(stream->flags & ~NGHTTP2_STREAM_FLAG_DEFERRED_ALL);
+
+  return stream_update_dep_on_detach_item(stream);
+}
+
+int nghttp2_stream_defer_item(nghttp2_stream *stream, uint8_t flags) {
+  assert(stream->item);
+
+  DEBUGF("stream: stream=%d defer item=%p cause=%02x\n", stream->stream_id,
+         stream->item, flags);
+
+  stream->flags |= flags;
+
+  return stream_update_dep_on_detach_item(stream);
+}
+
+int nghttp2_stream_resume_deferred_item(nghttp2_stream *stream, uint8_t flags) {
+  assert(stream->item);
+
+  DEBUGF("stream: stream=%d resume item=%p flags=%02x\n", stream->stream_id,
+         stream->item, flags);
+
+  stream->flags = (uint8_t)(stream->flags & ~flags);
+
+  if (stream->flags & NGHTTP2_STREAM_FLAG_DEFERRED_ALL) {
+    return 0;
+  }
+
+  return stream_update_dep_on_attach_item(stream);
+}
+
+int nghttp2_stream_check_deferred_item(nghttp2_stream *stream) {
+  return stream->item && (stream->flags & NGHTTP2_STREAM_FLAG_DEFERRED_ALL);
+}
+
+int nghttp2_stream_check_deferred_by_flow_control(nghttp2_stream *stream) {
+  return stream->item &&
+         (stream->flags & NGHTTP2_STREAM_FLAG_DEFERRED_FLOW_CONTROL);
+}
+
+static int update_initial_window_size(int32_t *window_size_ptr,
+                                      int32_t new_initial_window_size,
+                                      int32_t old_initial_window_size) {
+  int64_t new_window_size = (int64_t)(*window_size_ptr) +
+                            new_initial_window_size - old_initial_window_size;
+  if (INT32_MIN > new_window_size ||
+      new_window_size > NGHTTP2_MAX_WINDOW_SIZE) {
+    return -1;
+  }
+  *window_size_ptr = (int32_t)new_window_size;
+  return 0;
+}
+
+int nghttp2_stream_update_remote_initial_window_size(
+    nghttp2_stream *stream, int32_t new_initial_window_size,
+    int32_t old_initial_window_size) {
+  return update_initial_window_size(&stream->remote_window_size,
+                                    new_initial_window_size,
+                                    old_initial_window_size);
+}
+
+int nghttp2_stream_update_local_initial_window_size(
+    nghttp2_stream *stream, int32_t new_initial_window_size,
+    int32_t old_initial_window_size) {
+  return update_initial_window_size(&stream->local_window_size,
+                                    new_initial_window_size,
+                                    old_initial_window_size);
+}
+
+void nghttp2_stream_promise_fulfilled(nghttp2_stream *stream) {
+  stream->state = NGHTTP2_STREAM_OPENED;
+  stream->flags = (uint8_t)(stream->flags & ~NGHTTP2_STREAM_FLAG_PUSH);
+}
+
+int nghttp2_stream_dep_find_ancestor(nghttp2_stream *stream,
+                                     nghttp2_stream *target) {
+  for (; stream; stream = stream->dep_prev) {
+    if (stream == target) {
+      return 1;
+    }
+  }
+  return 0;
+}
+
+int nghttp2_stream_dep_insert(nghttp2_stream *dep_stream,
+                              nghttp2_stream *stream) {
+  nghttp2_stream *si;
+  int rv;
+
+  DEBUGF("stream: dep_insert dep_stream(%p)=%d, stream(%p)=%d\n", dep_stream,
+         dep_stream->stream_id, stream, stream->stream_id);
+
+  stream->sum_dep_weight = dep_stream->sum_dep_weight;
+  dep_stream->sum_dep_weight = stream->weight;
+
+  if (dep_stream->dep_next) {
+    for (si = dep_stream->dep_next; si; si = si->sib_next) {
+      si->dep_prev = stream;
+      if (si->queued) {
+        rv = stream_obq_move(stream, dep_stream, si);
+        if (rv != 0) {
+          return rv;
+        }
+      }
+    }
+
+    if (stream_subtree_active(stream)) {
+      rv = stream_obq_push(dep_stream, stream);
+      if (rv != 0) {
+        return rv;
+      }
+    }
+
+    stream->dep_next = dep_stream->dep_next;
+  }
+
+  dep_stream->dep_next = stream;
+  stream->dep_prev = dep_stream;
+
+  validate_tree(stream);
+
+  return 0;
+}
+
+static void set_dep_prev(nghttp2_stream *stream, nghttp2_stream *dep) {
+  for (; stream; stream = stream->sib_next) {
+    stream->dep_prev = dep;
+  }
+}
+
+static void link_dep(nghttp2_stream *dep_stream, nghttp2_stream *stream) {
+  dep_stream->dep_next = stream;
+  if (stream) {
+    stream->dep_prev = dep_stream;
+  }
+}
+
+static void link_sib(nghttp2_stream *a, nghttp2_stream *b) {
+  a->sib_next = b;
+  if (b) {
+    b->sib_prev = a;
+  }
+}
+
+static void insert_link_dep(nghttp2_stream *dep_stream,
+                            nghttp2_stream *stream) {
+  nghttp2_stream *sib_next;
+
+  assert(stream->sib_prev == NULL);
+
+  sib_next = dep_stream->dep_next;
+
+  link_sib(stream, sib_next);
+
+  link_dep(dep_stream, stream);
+}
+
+static void unlink_sib(nghttp2_stream *stream) {
+  nghttp2_stream *prev, *next, *dep_next;
+
+  prev = stream->sib_prev;
+  dep_next = stream->dep_next;
+
+  assert(prev);
+
+  if (dep_next) {
+    /*
+     *  prev--stream(--sib_next--...)
+     *         |
+     *        dep_next
+     */
+
+    link_sib(prev, dep_next);
+
+    set_dep_prev(dep_next, stream->dep_prev);
+
+    if (stream->sib_next) {
+      link_sib(stream_last_sib(dep_next), stream->sib_next);
+    }
+  } else {
+    /*
+     *  prev--stream(--sib_next--...)
+     */
+    next = stream->sib_next;
+
+    prev->sib_next = next;
+
+    if (next) {
+      next->sib_prev = prev;
+    }
+  }
+}
+
+static void unlink_dep(nghttp2_stream *stream) {
+  nghttp2_stream *prev, *next, *dep_next;
+
+  prev = stream->dep_prev;
+  dep_next = stream->dep_next;
+
+  assert(prev);
+
+  if (dep_next) {
+    /*
+     * prev
+     *   |
+     * stream(--sib_next--...)
+     *   |
+     * dep_next
+     */
+    link_dep(prev, dep_next);
+
+    set_dep_prev(dep_next, stream->dep_prev);
+
+    if (stream->sib_next) {
+      link_sib(stream_last_sib(dep_next), stream->sib_next);
+    }
+
+  } else if (stream->sib_next) {
+    /*
+     * prev
+     *   |
+     * stream--sib_next
+     */
+    next = stream->sib_next;
+
+    next->sib_prev = NULL;
+
+    link_dep(prev, next);
+  } else {
+    prev->dep_next = NULL;
+  }
+}
+
+void nghttp2_stream_dep_add(nghttp2_stream *dep_stream,
+                            nghttp2_stream *stream) {
+  DEBUGF("stream: dep_add dep_stream(%p)=%d, stream(%p)=%d\n", dep_stream,
+         dep_stream->stream_id, stream, stream->stream_id);
+
+  dep_stream->sum_dep_weight += stream->weight;
+
+  if (dep_stream->dep_next == NULL) {
+    link_dep(dep_stream, stream);
+  } else {
+    insert_link_dep(dep_stream, stream);
+  }
+
+  validate_tree(stream);
+}
+
+int nghttp2_stream_dep_remove(nghttp2_stream *stream) {
+  nghttp2_stream *dep_prev, *si;
+  int32_t sum_dep_weight_delta;
+  int rv;
+
+  DEBUGF("stream: dep_remove stream(%p)=%d\n", stream, stream->stream_id);
+
+  /* Distribute weight of |stream| to direct descendants */
+  sum_dep_weight_delta = -stream->weight;
+
+  for (si = stream->dep_next; si; si = si->sib_next) {
+    si->weight = nghttp2_stream_dep_distributed_weight(stream, si->weight);
+
+    sum_dep_weight_delta += si->weight;
+
+    if (si->queued) {
+      rv = stream_obq_move(stream->dep_prev, stream, si);
+      if (rv != 0) {
+        return rv;
+      }
+    }
+  }
+
+  assert(stream->dep_prev);
+
+  dep_prev = stream->dep_prev;
+
+  dep_prev->sum_dep_weight += sum_dep_weight_delta;
+
+  if (stream->queued) {
+    stream_obq_remove(stream);
+  }
+
+  if (stream->sib_prev) {
+    unlink_sib(stream);
+  } else {
+    unlink_dep(stream);
+  }
+
+  stream->sum_dep_weight = 0;
+
+  stream->dep_prev = NULL;
+  stream->dep_next = NULL;
+  stream->sib_prev = NULL;
+  stream->sib_next = NULL;
+
+  validate_tree(dep_prev);
+
+  return 0;
+}
+
+int nghttp2_stream_dep_insert_subtree(nghttp2_stream *dep_stream,
+                                      nghttp2_stream *stream) {
+  nghttp2_stream *last_sib;
+  nghttp2_stream *dep_next;
+  nghttp2_stream *si;
+  int rv;
+
+  DEBUGF("stream: dep_insert_subtree dep_stream(%p)=%d stream(%p)=%d\n",
+         dep_stream, dep_stream->stream_id, stream, stream->stream_id);
+
+  stream->sum_dep_weight += dep_stream->sum_dep_weight;
+  dep_stream->sum_dep_weight = stream->weight;
+
+  if (dep_stream->dep_next) {
+    dep_next = dep_stream->dep_next;
+
+    link_dep(dep_stream, stream);
+
+    if (stream->dep_next) {
+      last_sib = stream_last_sib(stream->dep_next);
+
+      link_sib(last_sib, dep_next);
+    } else {
+      link_dep(stream, dep_next);
+    }
+
+    for (si = dep_next; si; si = si->sib_next) {
+      si->dep_prev = stream;
+      if (si->queued) {
+        rv = stream_obq_move(stream, dep_stream, si);
+        if (rv != 0) {
+          return rv;
+        }
+      }
+    }
+  } else {
+    link_dep(dep_stream, stream);
+  }
+
+  if (stream_subtree_active(stream)) {
+    rv = stream_obq_push(dep_stream, stream);
+    if (rv != 0) {
+      return rv;
+    }
+  }
+
+  validate_tree(dep_stream);
+
+  return 0;
+}
+
+int nghttp2_stream_dep_add_subtree(nghttp2_stream *dep_stream,
+                                   nghttp2_stream *stream) {
+  int rv;
+
+  DEBUGF("stream: dep_add_subtree dep_stream(%p)=%d stream(%p)=%d\n",
+         dep_stream, dep_stream->stream_id, stream, stream->stream_id);
+
+  dep_stream->sum_dep_weight += stream->weight;
+
+  if (dep_stream->dep_next) {
+    insert_link_dep(dep_stream, stream);
+  } else {
+    link_dep(dep_stream, stream);
+  }
+
+  if (stream_subtree_active(stream)) {
+    rv = stream_obq_push(dep_stream, stream);
+    if (rv != 0) {
+      return rv;
+    }
+  }
+
+  validate_tree(dep_stream);
+
+  return 0;
+}
+
+void nghttp2_stream_dep_remove_subtree(nghttp2_stream *stream) {
+  nghttp2_stream *next, *dep_prev;
+
+  DEBUGF("stream: dep_remove_subtree stream(%p)=%d\n", stream,
+         stream->stream_id);
+
+  assert(stream->dep_prev);
+
+  dep_prev = stream->dep_prev;
+
+  if (stream->sib_prev) {
+    link_sib(stream->sib_prev, stream->sib_next);
+  } else {
+    next = stream->sib_next;
+
+    link_dep(dep_prev, next);
+
+    if (next) {
+      next->sib_prev = NULL;
+    }
+  }
+
+  dep_prev->sum_dep_weight -= stream->weight;
+
+  if (stream->queued) {
+    stream_obq_remove(stream);
+  }
+
+  validate_tree(dep_prev);
+
+  stream->sib_prev = NULL;
+  stream->sib_next = NULL;
+  stream->dep_prev = NULL;
+}
+
+int nghttp2_stream_in_dep_tree(nghttp2_stream *stream) {
+  return stream->dep_prev || stream->dep_next || stream->sib_prev ||
+         stream->sib_next;
+}
+
+nghttp2_outbound_item *
+nghttp2_stream_next_outbound_item(nghttp2_stream *stream) {
+  nghttp2_pq_entry *ent;
+  nghttp2_stream *si;
+
+  for (;;) {
+    if (stream_active(stream)) {
+      /* Update ascendant's descendant_last_cycle here, so that we can
+         assure that new stream is scheduled based on it. */
+      for (si = stream; si->dep_prev; si = si->dep_prev) {
+        si->dep_prev->descendant_last_cycle = si->cycle;
+      }
+      return stream->item;
+    }
+    ent = nghttp2_pq_top(&stream->obq);
+    if (!ent) {
+      return NULL;
+    }
+    stream = nghttp2_struct_of(ent, nghttp2_stream, pq_entry);
+  }
+}
+
+nghttp2_stream_proto_state nghttp2_stream_get_state(nghttp2_stream *stream) {
+  if (stream->flags & NGHTTP2_STREAM_FLAG_CLOSED) {
+    return NGHTTP2_STREAM_STATE_CLOSED;
+  }
+
+  if (stream->flags & NGHTTP2_STREAM_FLAG_PUSH) {
+    if (stream->shut_flags & NGHTTP2_SHUT_RD) {
+      return NGHTTP2_STREAM_STATE_RESERVED_LOCAL;
+    }
+
+    if (stream->shut_flags & NGHTTP2_SHUT_WR) {
+      return NGHTTP2_STREAM_STATE_RESERVED_REMOTE;
+    }
+  }
+
+  if (stream->shut_flags & NGHTTP2_SHUT_RD) {
+    return NGHTTP2_STREAM_STATE_HALF_CLOSED_REMOTE;
+  }
+
+  if (stream->shut_flags & NGHTTP2_SHUT_WR) {
+    return NGHTTP2_STREAM_STATE_HALF_CLOSED_LOCAL;
+  }
+
+  if (stream->state == NGHTTP2_STREAM_IDLE) {
+    return NGHTTP2_STREAM_STATE_IDLE;
+  }
+
+  return NGHTTP2_STREAM_STATE_OPEN;
+}
+
+nghttp2_stream *nghttp2_stream_get_parent(nghttp2_stream *stream) {
+  return stream->dep_prev;
+}
+
+nghttp2_stream *nghttp2_stream_get_next_sibling(nghttp2_stream *stream) {
+  return stream->sib_next;
+}
+
+nghttp2_stream *nghttp2_stream_get_previous_sibling(nghttp2_stream *stream) {
+  return stream->sib_prev;
+}
+
+nghttp2_stream *nghttp2_stream_get_first_child(nghttp2_stream *stream) {
+  return stream->dep_next;
+}
+
+int32_t nghttp2_stream_get_weight(nghttp2_stream *stream) {
+  return stream->weight;
+}
+
+int32_t nghttp2_stream_get_sum_dependency_weight(nghttp2_stream *stream) {
+  return stream->sum_dep_weight;
+}
+
+int32_t nghttp2_stream_get_stream_id(nghttp2_stream *stream) {
+  return stream->stream_id;
+}
diff --git a/Utilities/cmnghttp2/lib/nghttp2_stream.h b/Utilities/cmnghttp2/lib/nghttp2_stream.h
new file mode 100644
index 0000000..a1b807d
--- /dev/null
+++ b/Utilities/cmnghttp2/lib/nghttp2_stream.h
@@ -0,0 +1,437 @@
+/*
+ * nghttp2 - HTTP/2 C Library
+ *
+ * Copyright (c) 2012 Tatsuhiro Tsujikawa
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+#ifndef NGHTTP2_STREAM_H
+#define NGHTTP2_STREAM_H
+
+#ifdef HAVE_CONFIG_H
+#  include <config.h>
+#endif /* HAVE_CONFIG_H */
+
+#include <nghttp2/nghttp2.h>
+#include "nghttp2_outbound_item.h"
+#include "nghttp2_map.h"
+#include "nghttp2_pq.h"
+#include "nghttp2_int.h"
+
+/*
+ * If local peer is stream initiator:
+ * NGHTTP2_STREAM_OPENING : upon sending request HEADERS
+ * NGHTTP2_STREAM_OPENED : upon receiving response HEADERS
+ * NGHTTP2_STREAM_CLOSING : upon queuing RST_STREAM
+ *
+ * If remote peer is stream initiator:
+ * NGHTTP2_STREAM_OPENING : upon receiving request HEADERS
+ * NGHTTP2_STREAM_OPENED : upon sending response HEADERS
+ * NGHTTP2_STREAM_CLOSING : upon queuing RST_STREAM
+ */
+typedef enum {
+  /* Initial state */
+  NGHTTP2_STREAM_INITIAL,
+  /* For stream initiator: request HEADERS has been sent, but response
+     HEADERS has not been received yet.  For receiver: request HEADERS
+     has been received, but it does not send response HEADERS yet. */
+  NGHTTP2_STREAM_OPENING,
+  /* For stream initiator: response HEADERS is received. For receiver:
+     response HEADERS is sent. */
+  NGHTTP2_STREAM_OPENED,
+  /* RST_STREAM is received, but somehow we need to keep stream in
+     memory. */
+  NGHTTP2_STREAM_CLOSING,
+  /* PUSH_PROMISE is received or sent */
+  NGHTTP2_STREAM_RESERVED,
+  /* Stream is created in this state if it is used as anchor in
+     dependency tree. */
+  NGHTTP2_STREAM_IDLE
+} nghttp2_stream_state;
+
+typedef enum {
+  NGHTTP2_SHUT_NONE = 0,
+  /* Indicates further receptions will be disallowed. */
+  NGHTTP2_SHUT_RD = 0x01,
+  /* Indicates further transmissions will be disallowed. */
+  NGHTTP2_SHUT_WR = 0x02,
+  /* Indicates both further receptions and transmissions will be
+     disallowed. */
+  NGHTTP2_SHUT_RDWR = NGHTTP2_SHUT_RD | NGHTTP2_SHUT_WR
+} nghttp2_shut_flag;
+
+typedef enum {
+  NGHTTP2_STREAM_FLAG_NONE = 0,
+  /* Indicates that this stream is pushed stream and not opened
+     yet. */
+  NGHTTP2_STREAM_FLAG_PUSH = 0x01,
+  /* Indicates that this stream was closed */
+  NGHTTP2_STREAM_FLAG_CLOSED = 0x02,
+  /* Indicates the item is deferred due to flow control. */
+  NGHTTP2_STREAM_FLAG_DEFERRED_FLOW_CONTROL = 0x04,
+  /* Indicates the item is deferred by user callback */
+  NGHTTP2_STREAM_FLAG_DEFERRED_USER = 0x08,
+  /* bitwise OR of NGHTTP2_STREAM_FLAG_DEFERRED_FLOW_CONTROL and
+     NGHTTP2_STREAM_FLAG_DEFERRED_USER. */
+  NGHTTP2_STREAM_FLAG_DEFERRED_ALL = 0x0c
+
+} nghttp2_stream_flag;
+
+/* HTTP related flags to enforce HTTP semantics */
+typedef enum {
+  NGHTTP2_HTTP_FLAG_NONE = 0,
+  /* header field seen so far */
+  NGHTTP2_HTTP_FLAG__AUTHORITY = 1,
+  NGHTTP2_HTTP_FLAG__PATH = 1 << 1,
+  NGHTTP2_HTTP_FLAG__METHOD = 1 << 2,
+  NGHTTP2_HTTP_FLAG__SCHEME = 1 << 3,
+  /* host is not pseudo header, but we require either host or
+     :authority */
+  NGHTTP2_HTTP_FLAG_HOST = 1 << 4,
+  NGHTTP2_HTTP_FLAG__STATUS = 1 << 5,
+  /* required header fields for HTTP request except for CONNECT
+     method. */
+  NGHTTP2_HTTP_FLAG_REQ_HEADERS = NGHTTP2_HTTP_FLAG__METHOD |
+                                  NGHTTP2_HTTP_FLAG__PATH |
+                                  NGHTTP2_HTTP_FLAG__SCHEME,
+  NGHTTP2_HTTP_FLAG_PSEUDO_HEADER_DISALLOWED = 1 << 6,
+  /* HTTP method flags */
+  NGHTTP2_HTTP_FLAG_METH_CONNECT = 1 << 7,
+  NGHTTP2_HTTP_FLAG_METH_HEAD = 1 << 8,
+  NGHTTP2_HTTP_FLAG_METH_OPTIONS = 1 << 9,
+  NGHTTP2_HTTP_FLAG_METH_UPGRADE_WORKAROUND = 1 << 10,
+  NGHTTP2_HTTP_FLAG_METH_ALL = NGHTTP2_HTTP_FLAG_METH_CONNECT |
+                               NGHTTP2_HTTP_FLAG_METH_HEAD |
+                               NGHTTP2_HTTP_FLAG_METH_OPTIONS |
+                               NGHTTP2_HTTP_FLAG_METH_UPGRADE_WORKAROUND,
+  /* :path category */
+  /* path starts with "/" */
+  NGHTTP2_HTTP_FLAG_PATH_REGULAR = 1 << 11,
+  /* path "*" */
+  NGHTTP2_HTTP_FLAG_PATH_ASTERISK = 1 << 12,
+  /* scheme */
+  /* "http" or "https" scheme */
+  NGHTTP2_HTTP_FLAG_SCHEME_HTTP = 1 << 13,
+  /* set if final response is expected */
+  NGHTTP2_HTTP_FLAG_EXPECT_FINAL_RESPONSE = 1 << 14,
+  NGHTTP2_HTTP_FLAG__PROTOCOL = 1 << 15,
+} nghttp2_http_flag;
+
+struct nghttp2_stream {
+  /* Intrusive Map */
+  nghttp2_map_entry map_entry;
+  /* Entry for dep_prev->obq */
+  nghttp2_pq_entry pq_entry;
+  /* Priority Queue storing direct descendant (nghttp2_stream).  Only
+     streams which itself has some data to send, or has a descendant
+     which has some data to sent. */
+  nghttp2_pq obq;
+  /* Content-Length of request/response body.  -1 if unknown. */
+  int64_t content_length;
+  /* Received body so far */
+  int64_t recv_content_length;
+  /* Base last_cycle for direct descendent streams. */
+  uint64_t descendant_last_cycle;
+  /* Next scheduled time to sent item */
+  uint64_t cycle;
+  /* Next seq used for direct descendant streams */
+  uint64_t descendant_next_seq;
+  /* Secondary key for prioritization to break a tie for cycle.  This
+     value is monotonically increased for single parent stream. */
+  uint64_t seq;
+  /* pointers to form dependency tree.  If multiple streams depend on
+     a stream, only one stream (left most) has non-NULL dep_prev which
+     points to the stream it depends on. The remaining streams are
+     linked using sib_prev and sib_next.  The stream which has
+     non-NULL dep_prev always NULL sib_prev.  The right most stream
+     has NULL sib_next.  If this stream is a root of dependency tree,
+     dep_prev and sib_prev are NULL. */
+  nghttp2_stream *dep_prev, *dep_next;
+  nghttp2_stream *sib_prev, *sib_next;
+  /* When stream is kept after closure, it may be kept in doubly
+     linked list pointed by nghttp2_session closed_stream_head.
+     closed_next points to the next stream object if it is the element
+     of the list. */
+  nghttp2_stream *closed_prev, *closed_next;
+  /* The arbitrary data provided by user for this stream. */
+  void *stream_user_data;
+  /* Item to send */
+  nghttp2_outbound_item *item;
+  /* Last written length of frame payload */
+  size_t last_writelen;
+  /* stream ID */
+  int32_t stream_id;
+  /* Current remote window size. This value is computed against the
+     current initial window size of remote endpoint. */
+  int32_t remote_window_size;
+  /* Keep track of the number of bytes received without
+     WINDOW_UPDATE. This could be negative after submitting negative
+     value to WINDOW_UPDATE */
+  int32_t recv_window_size;
+  /* The number of bytes consumed by the application and now is
+     subject to WINDOW_UPDATE.  This is only used when auto
+     WINDOW_UPDATE is turned off. */
+  int32_t consumed_size;
+  /* The amount of recv_window_size cut using submitting negative
+     value to WINDOW_UPDATE */
+  int32_t recv_reduction;
+  /* window size for local flow control. It is initially set to
+     NGHTTP2_INITIAL_WINDOW_SIZE and could be increased/decreased by
+     submitting WINDOW_UPDATE. See nghttp2_submit_window_update(). */
+  int32_t local_window_size;
+  /* weight of this stream */
+  int32_t weight;
+  /* This is unpaid penalty (offset) when calculating cycle. */
+  uint32_t pending_penalty;
+  /* sum of weight of direct descendants */
+  int32_t sum_dep_weight;
+  nghttp2_stream_state state;
+  /* status code from remote server */
+  int16_t status_code;
+  /* Bitwise OR of zero or more nghttp2_http_flag values */
+  uint16_t http_flags;
+  /* This is bitwise-OR of 0 or more of nghttp2_stream_flag. */
+  uint8_t flags;
+  /* Bitwise OR of zero or more nghttp2_shut_flag values */
+  uint8_t shut_flags;
+  /* Nonzero if this stream has been queued to stream pointed by
+     dep_prev.  We maintain the invariant that if a stream is queued,
+     then its ancestors, except for root, are also queued.  This
+     invariant may break in fatal error condition. */
+  uint8_t queued;
+  /* This flag is used to reduce excessive queuing of WINDOW_UPDATE to
+     this stream.  The nonzero does not necessarily mean WINDOW_UPDATE
+     is not queued. */
+  uint8_t window_update_queued;
+};
+
+void nghttp2_stream_init(nghttp2_stream *stream, int32_t stream_id,
+                         uint8_t flags, nghttp2_stream_state initial_state,
+                         int32_t weight, int32_t remote_initial_window_size,
+                         int32_t local_initial_window_size,
+                         void *stream_user_data, nghttp2_mem *mem);
+
+void nghttp2_stream_free(nghttp2_stream *stream);
+
+/*
+ * Disallow either further receptions or transmissions, or both.
+ * |flag| is bitwise OR of one or more of nghttp2_shut_flag.
+ */
+void nghttp2_stream_shutdown(nghttp2_stream *stream, nghttp2_shut_flag flag);
+
+/*
+ * Defer |stream->item|.  We won't call this function in the situation
+ * where |stream->item| == NULL.  The |flags| is bitwise OR of zero or
+ * more of NGHTTP2_STREAM_FLAG_DEFERRED_USER and
+ * NGHTTP2_STREAM_FLAG_DEFERRED_FLOW_CONTROL.  The |flags| indicates
+ * the reason of this action.
+ *
+ * This function returns 0 if it succeeds, or one of the following
+ * negative error codes:
+ *
+ * NGHTTP2_ERR_NOMEM
+ *     Out of memory
+ */
+int nghttp2_stream_defer_item(nghttp2_stream *stream, uint8_t flags);
+
+/*
+ * Put back deferred data in this stream to active state.  The |flags|
+ * are one or more of bitwise OR of the following values:
+ * NGHTTP2_STREAM_FLAG_DEFERRED_USER and
+ * NGHTTP2_STREAM_FLAG_DEFERRED_FLOW_CONTROL and given masks are
+ * cleared if they are set.  So even if this function is called, if
+ * one of flag is still set, data does not become active.
+ *
+ * This function returns 0 if it succeeds, or one of the following
+ * negative error codes:
+ *
+ * NGHTTP2_ERR_NOMEM
+ *     Out of memory
+ */
+int nghttp2_stream_resume_deferred_item(nghttp2_stream *stream, uint8_t flags);
+
+/*
+ * Returns nonzero if item is deferred by whatever reason.
+ */
+int nghttp2_stream_check_deferred_item(nghttp2_stream *stream);
+
+/*
+ * Returns nonzero if item is deferred by flow control.
+ */
+int nghttp2_stream_check_deferred_by_flow_control(nghttp2_stream *stream);
+
+/*
+ * Updates the remote window size with the new value
+ * |new_initial_window_size|. The |old_initial_window_size| is used to
+ * calculate the current window size.
+ *
+ * This function returns 0 if it succeeds or -1. The failure is due to
+ * overflow.
+ */
+int nghttp2_stream_update_remote_initial_window_size(
+    nghttp2_stream *stream, int32_t new_initial_window_size,
+    int32_t old_initial_window_size);
+
+/*
+ * Updates the local window size with the new value
+ * |new_initial_window_size|. The |old_initial_window_size| is used to
+ * calculate the current window size.
+ *
+ * This function returns 0 if it succeeds or -1. The failure is due to
+ * overflow.
+ */
+int nghttp2_stream_update_local_initial_window_size(
+    nghttp2_stream *stream, int32_t new_initial_window_size,
+    int32_t old_initial_window_size);
+
+/*
+ * Call this function if promised stream |stream| is replied with
+ * HEADERS.  This function makes the state of the |stream| to
+ * NGHTTP2_STREAM_OPENED.
+ */
+void nghttp2_stream_promise_fulfilled(nghttp2_stream *stream);
+
+/*
+ * Returns nonzero if |target| is an ancestor of |stream|.
+ */
+int nghttp2_stream_dep_find_ancestor(nghttp2_stream *stream,
+                                     nghttp2_stream *target);
+
+/*
+ * Computes distributed weight of a stream of the |weight| under the
+ * |stream| if |stream| is removed from a dependency tree.
+ */
+int32_t nghttp2_stream_dep_distributed_weight(nghttp2_stream *stream,
+                                              int32_t weight);
+
+/*
+ * Makes the |stream| depend on the |dep_stream|.  This dependency is
+ * exclusive.  All existing direct descendants of |dep_stream| become
+ * the descendants of the |stream|.  This function assumes
+ * |stream->item| is NULL.
+ *
+ * This function returns 0 if it succeeds, or one of the following
+ * negative error codes:
+ *
+ * NGHTTP2_ERR_NOMEM
+ *     Out of memory
+ */
+int nghttp2_stream_dep_insert(nghttp2_stream *dep_stream,
+                              nghttp2_stream *stream);
+
+/*
+ * Makes the |stream| depend on the |dep_stream|.  This dependency is
+ * not exclusive.  This function assumes |stream->item| is NULL.
+ */
+void nghttp2_stream_dep_add(nghttp2_stream *dep_stream, nghttp2_stream *stream);
+
+/*
+ * Removes the |stream| from the current dependency tree.  This
+ * function assumes |stream->item| is NULL.
+ */
+int nghttp2_stream_dep_remove(nghttp2_stream *stream);
+
+/*
+ * Attaches |item| to |stream|.
+ *
+ * This function returns 0 if it succeeds, or one of the following
+ * negative error codes:
+ *
+ * NGHTTP2_ERR_NOMEM
+ *     Out of memory
+ */
+int nghttp2_stream_attach_item(nghttp2_stream *stream,
+                               nghttp2_outbound_item *item);
+
+/*
+ * Detaches |stream->item|.  This function does not free
+ * |stream->item|.  The caller must free it.
+ *
+ * This function returns 0 if it succeeds, or one of the following
+ * negative error codes:
+ *
+ * NGHTTP2_ERR_NOMEM
+ *     Out of memory
+ */
+int nghttp2_stream_detach_item(nghttp2_stream *stream);
+
+/*
+ * Makes the |stream| depend on the |dep_stream|.  This dependency is
+ * exclusive.
+ *
+ * This function returns 0 if it succeeds, or one of the following
+ * negative error codes:
+ *
+ * NGHTTP2_ERR_NOMEM
+ *     Out of memory
+ */
+int nghttp2_stream_dep_insert_subtree(nghttp2_stream *dep_stream,
+                                      nghttp2_stream *stream);
+
+/*
+ * Makes the |stream| depend on the |dep_stream|.  This dependency is
+ * not exclusive.
+ *
+ * This function returns 0 if it succeeds, or one of the following
+ * negative error codes:
+ *
+ * NGHTTP2_ERR_NOMEM
+ *     Out of memory
+ */
+int nghttp2_stream_dep_add_subtree(nghttp2_stream *dep_stream,
+                                   nghttp2_stream *stream);
+
+/*
+ * Removes subtree whose root stream is |stream|.  The
+ * effective_weight of streams in removed subtree is not updated.
+ *
+ * This function returns 0 if it succeeds, or one of the following
+ * negative error codes:
+ *
+ * NGHTTP2_ERR_NOMEM
+ *     Out of memory
+ */
+void nghttp2_stream_dep_remove_subtree(nghttp2_stream *stream);
+
+/*
+ * Returns nonzero if |stream| is in any dependency tree.
+ */
+int nghttp2_stream_in_dep_tree(nghttp2_stream *stream);
+
+/*
+ * Schedules transmission of |stream|'s item, assuming stream->item is
+ * attached, and stream->last_writelen was updated.
+ */
+void nghttp2_stream_reschedule(nghttp2_stream *stream);
+
+/*
+ * Changes |stream|'s weight to |weight|.  If |stream| is queued, it
+ * will be rescheduled based on new weight.
+ */
+void nghttp2_stream_change_weight(nghttp2_stream *stream, int32_t weight);
+
+/*
+ * Returns a stream which has highest priority, updating
+ * descendant_last_cycle of selected stream's ancestors.
+ */
+nghttp2_outbound_item *
+nghttp2_stream_next_outbound_item(nghttp2_stream *stream);
+
+#endif /* NGHTTP2_STREAM */
diff --git a/Utilities/cmnghttp2/lib/nghttp2_submit.c b/Utilities/cmnghttp2/lib/nghttp2_submit.c
new file mode 100644
index 0000000..f604eff
--- /dev/null
+++ b/Utilities/cmnghttp2/lib/nghttp2_submit.c
@@ -0,0 +1,814 @@
+/*
+ * nghttp2 - HTTP/2 C Library
+ *
+ * Copyright (c) 2012, 2013 Tatsuhiro Tsujikawa
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+#include "nghttp2_submit.h"
+
+#include <string.h>
+#include <assert.h>
+
+#include "nghttp2_session.h"
+#include "nghttp2_frame.h"
+#include "nghttp2_helper.h"
+#include "nghttp2_priority_spec.h"
+
+/*
+ * Detects the dependency error, that is stream attempted to depend on
+ * itself.  If |stream_id| is -1, we use session->next_stream_id as
+ * stream ID.
+ *
+ * This function returns 0 if it succeeds, or one of the following
+ * error codes:
+ *
+ * NGHTTP2_ERR_INVALID_ARGUMENT
+ *   Stream attempted to depend on itself.
+ */
+static int detect_self_dependency(nghttp2_session *session, int32_t stream_id,
+                                  const nghttp2_priority_spec *pri_spec) {
+  assert(pri_spec);
+
+  if (stream_id == -1) {
+    if ((int32_t)session->next_stream_id == pri_spec->stream_id) {
+      return NGHTTP2_ERR_INVALID_ARGUMENT;
+    }
+    return 0;
+  }
+
+  if (stream_id == pri_spec->stream_id) {
+    return NGHTTP2_ERR_INVALID_ARGUMENT;
+  }
+
+  return 0;
+}
+
+/* This function takes ownership of |nva_copy|. Regardless of the
+   return value, the caller must not free |nva_copy| after this
+   function returns. */
+static int32_t submit_headers_shared(nghttp2_session *session, uint8_t flags,
+                                     int32_t stream_id,
+                                     const nghttp2_priority_spec *pri_spec,
+                                     nghttp2_nv *nva_copy, size_t nvlen,
+                                     const nghttp2_data_provider *data_prd,
+                                     void *stream_user_data) {
+  int rv;
+  uint8_t flags_copy;
+  nghttp2_outbound_item *item = NULL;
+  nghttp2_frame *frame = NULL;
+  nghttp2_headers_category hcat;
+  nghttp2_mem *mem;
+
+  mem = &session->mem;
+
+  item = nghttp2_mem_malloc(mem, sizeof(nghttp2_outbound_item));
+  if (item == NULL) {
+    rv = NGHTTP2_ERR_NOMEM;
+    goto fail;
+  }
+
+  nghttp2_outbound_item_init(item);
+
+  if (data_prd != NULL && data_prd->read_callback != NULL) {
+    item->aux_data.headers.data_prd = *data_prd;
+  }
+
+  item->aux_data.headers.stream_user_data = stream_user_data;
+
+  flags_copy =
+      (uint8_t)((flags & (NGHTTP2_FLAG_END_STREAM | NGHTTP2_FLAG_PRIORITY)) |
+                NGHTTP2_FLAG_END_HEADERS);
+
+  if (stream_id == -1) {
+    if (session->next_stream_id > INT32_MAX) {
+      rv = NGHTTP2_ERR_STREAM_ID_NOT_AVAILABLE;
+      goto fail;
+    }
+
+    stream_id = (int32_t)session->next_stream_id;
+    session->next_stream_id += 2;
+
+    hcat = NGHTTP2_HCAT_REQUEST;
+  } else {
+    /* More specific categorization will be done later. */
+    hcat = NGHTTP2_HCAT_HEADERS;
+  }
+
+  frame = &item->frame;
+
+  nghttp2_frame_headers_init(&frame->headers, flags_copy, stream_id, hcat,
+                             pri_spec, nva_copy, nvlen);
+
+  rv = nghttp2_session_add_item(session, item);
+
+  if (rv != 0) {
+    nghttp2_frame_headers_free(&frame->headers, mem);
+    goto fail2;
+  }
+
+  if (hcat == NGHTTP2_HCAT_REQUEST) {
+    return stream_id;
+  }
+
+  return 0;
+
+fail:
+  /* nghttp2_frame_headers_init() takes ownership of nva_copy. */
+  nghttp2_nv_array_del(nva_copy, mem);
+fail2:
+  nghttp2_mem_free(mem, item);
+
+  return rv;
+}
+
+static int32_t submit_headers_shared_nva(nghttp2_session *session,
+                                         uint8_t flags, int32_t stream_id,
+                                         const nghttp2_priority_spec *pri_spec,
+                                         const nghttp2_nv *nva, size_t nvlen,
+                                         const nghttp2_data_provider *data_prd,
+                                         void *stream_user_data) {
+  int rv;
+  nghttp2_nv *nva_copy;
+  nghttp2_priority_spec copy_pri_spec;
+  nghttp2_mem *mem;
+
+  mem = &session->mem;
+
+  if (pri_spec) {
+    copy_pri_spec = *pri_spec;
+    nghttp2_priority_spec_normalize_weight(&copy_pri_spec);
+  } else {
+    nghttp2_priority_spec_default_init(&copy_pri_spec);
+  }
+
+  rv = nghttp2_nv_array_copy(&nva_copy, nva, nvlen, mem);
+  if (rv < 0) {
+    return rv;
+  }
+
+  return submit_headers_shared(session, flags, stream_id, &copy_pri_spec,
+                               nva_copy, nvlen, data_prd, stream_user_data);
+}
+
+int nghttp2_submit_trailer(nghttp2_session *session, int32_t stream_id,
+                           const nghttp2_nv *nva, size_t nvlen) {
+  if (stream_id <= 0) {
+    return NGHTTP2_ERR_INVALID_ARGUMENT;
+  }
+
+  return (int)submit_headers_shared_nva(session, NGHTTP2_FLAG_END_STREAM,
+                                        stream_id, NULL, nva, nvlen, NULL,
+                                        NULL);
+}
+
+int32_t nghttp2_submit_headers(nghttp2_session *session, uint8_t flags,
+                               int32_t stream_id,
+                               const nghttp2_priority_spec *pri_spec,
+                               const nghttp2_nv *nva, size_t nvlen,
+                               void *stream_user_data) {
+  int rv;
+
+  if (stream_id == -1) {
+    if (session->server) {
+      return NGHTTP2_ERR_PROTO;
+    }
+  } else if (stream_id <= 0) {
+    return NGHTTP2_ERR_INVALID_ARGUMENT;
+  }
+
+  flags &= NGHTTP2_FLAG_END_STREAM;
+
+  if (pri_spec && !nghttp2_priority_spec_check_default(pri_spec)) {
+    rv = detect_self_dependency(session, stream_id, pri_spec);
+    if (rv != 0) {
+      return rv;
+    }
+
+    flags |= NGHTTP2_FLAG_PRIORITY;
+  } else {
+    pri_spec = NULL;
+  }
+
+  return submit_headers_shared_nva(session, flags, stream_id, pri_spec, nva,
+                                   nvlen, NULL, stream_user_data);
+}
+
+int nghttp2_submit_ping(nghttp2_session *session, uint8_t flags,
+                        const uint8_t *opaque_data) {
+  flags &= NGHTTP2_FLAG_ACK;
+  return nghttp2_session_add_ping(session, flags, opaque_data);
+}
+
+int nghttp2_submit_priority(nghttp2_session *session, uint8_t flags,
+                            int32_t stream_id,
+                            const nghttp2_priority_spec *pri_spec) {
+  int rv;
+  nghttp2_outbound_item *item;
+  nghttp2_frame *frame;
+  nghttp2_priority_spec copy_pri_spec;
+  nghttp2_mem *mem;
+  (void)flags;
+
+  mem = &session->mem;
+
+  if (stream_id == 0 || pri_spec == NULL) {
+    return NGHTTP2_ERR_INVALID_ARGUMENT;
+  }
+
+  if (stream_id == pri_spec->stream_id) {
+    return NGHTTP2_ERR_INVALID_ARGUMENT;
+  }
+
+  copy_pri_spec = *pri_spec;
+
+  nghttp2_priority_spec_normalize_weight(&copy_pri_spec);
+
+  item = nghttp2_mem_malloc(mem, sizeof(nghttp2_outbound_item));
+
+  if (item == NULL) {
+    return NGHTTP2_ERR_NOMEM;
+  }
+
+  nghttp2_outbound_item_init(item);
+
+  frame = &item->frame;
+
+  nghttp2_frame_priority_init(&frame->priority, stream_id, &copy_pri_spec);
+
+  rv = nghttp2_session_add_item(session, item);
+
+  if (rv != 0) {
+    nghttp2_frame_priority_free(&frame->priority);
+    nghttp2_mem_free(mem, item);
+
+    return rv;
+  }
+
+  return 0;
+}
+
+int nghttp2_submit_rst_stream(nghttp2_session *session, uint8_t flags,
+                              int32_t stream_id, uint32_t error_code) {
+  (void)flags;
+
+  if (stream_id == 0) {
+    return NGHTTP2_ERR_INVALID_ARGUMENT;
+  }
+
+  return nghttp2_session_add_rst_stream(session, stream_id, error_code);
+}
+
+int nghttp2_submit_goaway(nghttp2_session *session, uint8_t flags,
+                          int32_t last_stream_id, uint32_t error_code,
+                          const uint8_t *opaque_data, size_t opaque_data_len) {
+  (void)flags;
+
+  if (session->goaway_flags & NGHTTP2_GOAWAY_TERM_ON_SEND) {
+    return 0;
+  }
+  return nghttp2_session_add_goaway(session, last_stream_id, error_code,
+                                    opaque_data, opaque_data_len,
+                                    NGHTTP2_GOAWAY_AUX_NONE);
+}
+
+int nghttp2_submit_shutdown_notice(nghttp2_session *session) {
+  if (!session->server) {
+    return NGHTTP2_ERR_INVALID_STATE;
+  }
+  if (session->goaway_flags) {
+    return 0;
+  }
+  return nghttp2_session_add_goaway(session, (1u << 31) - 1, NGHTTP2_NO_ERROR,
+                                    NULL, 0,
+                                    NGHTTP2_GOAWAY_AUX_SHUTDOWN_NOTICE);
+}
+
+int nghttp2_submit_settings(nghttp2_session *session, uint8_t flags,
+                            const nghttp2_settings_entry *iv, size_t niv) {
+  (void)flags;
+  return nghttp2_session_add_settings(session, NGHTTP2_FLAG_NONE, iv, niv);
+}
+
+int32_t nghttp2_submit_push_promise(nghttp2_session *session, uint8_t flags,
+                                    int32_t stream_id, const nghttp2_nv *nva,
+                                    size_t nvlen,
+                                    void *promised_stream_user_data) {
+  nghttp2_outbound_item *item;
+  nghttp2_frame *frame;
+  nghttp2_nv *nva_copy;
+  uint8_t flags_copy;
+  int32_t promised_stream_id;
+  int rv;
+  nghttp2_mem *mem;
+  (void)flags;
+
+  mem = &session->mem;
+
+  if (stream_id <= 0 || nghttp2_session_is_my_stream_id(session, stream_id)) {
+    return NGHTTP2_ERR_INVALID_ARGUMENT;
+  }
+
+  if (!session->server) {
+    return NGHTTP2_ERR_PROTO;
+  }
+
+  /* All 32bit signed stream IDs are spent. */
+  if (session->next_stream_id > INT32_MAX) {
+    return NGHTTP2_ERR_STREAM_ID_NOT_AVAILABLE;
+  }
+
+  item = nghttp2_mem_malloc(mem, sizeof(nghttp2_outbound_item));
+  if (item == NULL) {
+    return NGHTTP2_ERR_NOMEM;
+  }
+
+  nghttp2_outbound_item_init(item);
+
+  item->aux_data.headers.stream_user_data = promised_stream_user_data;
+
+  frame = &item->frame;
+
+  rv = nghttp2_nv_array_copy(&nva_copy, nva, nvlen, mem);
+  if (rv < 0) {
+    nghttp2_mem_free(mem, item);
+    return rv;
+  }
+
+  flags_copy = NGHTTP2_FLAG_END_HEADERS;
+
+  promised_stream_id = (int32_t)session->next_stream_id;
+  session->next_stream_id += 2;
+
+  nghttp2_frame_push_promise_init(&frame->push_promise, flags_copy, stream_id,
+                                  promised_stream_id, nva_copy, nvlen);
+
+  rv = nghttp2_session_add_item(session, item);
+
+  if (rv != 0) {
+    nghttp2_frame_push_promise_free(&frame->push_promise, mem);
+    nghttp2_mem_free(mem, item);
+
+    return rv;
+  }
+
+  return promised_stream_id;
+}
+
+int nghttp2_submit_window_update(nghttp2_session *session, uint8_t flags,
+                                 int32_t stream_id,
+                                 int32_t window_size_increment) {
+  int rv;
+  nghttp2_stream *stream = 0;
+  (void)flags;
+
+  if (window_size_increment == 0) {
+    return 0;
+  }
+  if (stream_id == 0) {
+    rv = nghttp2_adjust_local_window_size(
+        &session->local_window_size, &session->recv_window_size,
+        &session->recv_reduction, &window_size_increment);
+    if (rv != 0) {
+      return rv;
+    }
+  } else {
+    stream = nghttp2_session_get_stream(session, stream_id);
+    if (!stream) {
+      return 0;
+    }
+
+    rv = nghttp2_adjust_local_window_size(
+        &stream->local_window_size, &stream->recv_window_size,
+        &stream->recv_reduction, &window_size_increment);
+    if (rv != 0) {
+      return rv;
+    }
+  }
+
+  if (window_size_increment > 0) {
+    if (stream_id == 0) {
+      session->consumed_size =
+          nghttp2_max(0, session->consumed_size - window_size_increment);
+    } else {
+      stream->consumed_size =
+          nghttp2_max(0, stream->consumed_size - window_size_increment);
+    }
+
+    return nghttp2_session_add_window_update(session, 0, stream_id,
+                                             window_size_increment);
+  }
+  return 0;
+}
+
+int nghttp2_session_set_local_window_size(nghttp2_session *session,
+                                          uint8_t flags, int32_t stream_id,
+                                          int32_t window_size) {
+  int32_t window_size_increment;
+  nghttp2_stream *stream;
+  int rv;
+  (void)flags;
+
+  if (window_size < 0) {
+    return NGHTTP2_ERR_INVALID_ARGUMENT;
+  }
+
+  if (stream_id == 0) {
+    window_size_increment = window_size - session->local_window_size;
+
+    if (window_size_increment == 0) {
+      return 0;
+    }
+
+    if (window_size_increment < 0) {
+      return nghttp2_adjust_local_window_size(
+          &session->local_window_size, &session->recv_window_size,
+          &session->recv_reduction, &window_size_increment);
+    }
+
+    rv = nghttp2_increase_local_window_size(
+        &session->local_window_size, &session->recv_window_size,
+        &session->recv_reduction, &window_size_increment);
+
+    if (rv != 0) {
+      return rv;
+    }
+  } else {
+    stream = nghttp2_session_get_stream(session, stream_id);
+
+    if (stream == NULL) {
+      return 0;
+    }
+
+    window_size_increment = window_size - stream->local_window_size;
+
+    if (window_size_increment == 0) {
+      return 0;
+    }
+
+    if (window_size_increment < 0) {
+      return nghttp2_adjust_local_window_size(
+          &stream->local_window_size, &stream->recv_window_size,
+          &stream->recv_reduction, &window_size_increment);
+    }
+
+    rv = nghttp2_increase_local_window_size(
+        &stream->local_window_size, &stream->recv_window_size,
+        &stream->recv_reduction, &window_size_increment);
+
+    if (rv != 0) {
+      return rv;
+    }
+  }
+
+  if (window_size_increment > 0) {
+    return nghttp2_session_add_window_update(session, 0, stream_id,
+                                             window_size_increment);
+  }
+
+  return 0;
+}
+
+int nghttp2_submit_altsvc(nghttp2_session *session, uint8_t flags,
+                          int32_t stream_id, const uint8_t *origin,
+                          size_t origin_len, const uint8_t *field_value,
+                          size_t field_value_len) {
+  nghttp2_mem *mem;
+  uint8_t *buf, *p;
+  uint8_t *origin_copy;
+  uint8_t *field_value_copy;
+  nghttp2_outbound_item *item;
+  nghttp2_frame *frame;
+  nghttp2_ext_altsvc *altsvc;
+  int rv;
+  (void)flags;
+
+  mem = &session->mem;
+
+  if (!session->server) {
+    return NGHTTP2_ERR_INVALID_STATE;
+  }
+
+  if (2 + origin_len + field_value_len > NGHTTP2_MAX_PAYLOADLEN) {
+    return NGHTTP2_ERR_INVALID_ARGUMENT;
+  }
+
+  if (stream_id == 0) {
+    if (origin_len == 0) {
+      return NGHTTP2_ERR_INVALID_ARGUMENT;
+    }
+  } else if (origin_len != 0) {
+    return NGHTTP2_ERR_INVALID_ARGUMENT;
+  }
+
+  buf = nghttp2_mem_malloc(mem, origin_len + field_value_len + 2);
+  if (buf == NULL) {
+    return NGHTTP2_ERR_NOMEM;
+  }
+
+  p = buf;
+
+  origin_copy = p;
+  if (origin_len) {
+    p = nghttp2_cpymem(p, origin, origin_len);
+  }
+  *p++ = '\0';
+
+  field_value_copy = p;
+  if (field_value_len) {
+    p = nghttp2_cpymem(p, field_value, field_value_len);
+  }
+  *p++ = '\0';
+
+  item = nghttp2_mem_malloc(mem, sizeof(nghttp2_outbound_item));
+  if (item == NULL) {
+    rv = NGHTTP2_ERR_NOMEM;
+    goto fail_item_malloc;
+  }
+
+  nghttp2_outbound_item_init(item);
+
+  item->aux_data.ext.builtin = 1;
+
+  altsvc = &item->ext_frame_payload.altsvc;
+
+  frame = &item->frame;
+  frame->ext.payload = altsvc;
+
+  nghttp2_frame_altsvc_init(&frame->ext, stream_id, origin_copy, origin_len,
+                            field_value_copy, field_value_len);
+
+  rv = nghttp2_session_add_item(session, item);
+  if (rv != 0) {
+    nghttp2_frame_altsvc_free(&frame->ext, mem);
+    nghttp2_mem_free(mem, item);
+
+    return rv;
+  }
+
+  return 0;
+
+fail_item_malloc:
+  free(buf);
+
+  return rv;
+}
+
+int nghttp2_submit_origin(nghttp2_session *session, uint8_t flags,
+                          const nghttp2_origin_entry *ov, size_t nov) {
+  nghttp2_mem *mem;
+  uint8_t *p;
+  nghttp2_outbound_item *item;
+  nghttp2_frame *frame;
+  nghttp2_ext_origin *origin;
+  nghttp2_origin_entry *ov_copy;
+  size_t len = 0;
+  size_t i;
+  int rv;
+  (void)flags;
+
+  mem = &session->mem;
+
+  if (!session->server) {
+    return NGHTTP2_ERR_INVALID_STATE;
+  }
+
+  if (nov) {
+    for (i = 0; i < nov; ++i) {
+      len += ov[i].origin_len;
+    }
+
+    if (2 * nov + len > NGHTTP2_MAX_PAYLOADLEN) {
+      return NGHTTP2_ERR_INVALID_ARGUMENT;
+    }
+
+    /* The last nov is added for terminal NULL character. */
+    ov_copy =
+        nghttp2_mem_malloc(mem, nov * sizeof(nghttp2_origin_entry) + len + nov);
+    if (ov_copy == NULL) {
+      return NGHTTP2_ERR_NOMEM;
+    }
+
+    p = (uint8_t *)ov_copy + nov * sizeof(nghttp2_origin_entry);
+
+    for (i = 0; i < nov; ++i) {
+      ov_copy[i].origin = p;
+      ov_copy[i].origin_len = ov[i].origin_len;
+      p = nghttp2_cpymem(p, ov[i].origin, ov[i].origin_len);
+      *p++ = '\0';
+    }
+
+    assert((size_t)(p - (uint8_t *)ov_copy) ==
+           nov * sizeof(nghttp2_origin_entry) + len + nov);
+  } else {
+    ov_copy = NULL;
+  }
+
+  item = nghttp2_mem_malloc(mem, sizeof(nghttp2_outbound_item));
+  if (item == NULL) {
+    rv = NGHTTP2_ERR_NOMEM;
+    goto fail_item_malloc;
+  }
+
+  nghttp2_outbound_item_init(item);
+
+  item->aux_data.ext.builtin = 1;
+
+  origin = &item->ext_frame_payload.origin;
+
+  frame = &item->frame;
+  frame->ext.payload = origin;
+
+  nghttp2_frame_origin_init(&frame->ext, ov_copy, nov);
+
+  rv = nghttp2_session_add_item(session, item);
+  if (rv != 0) {
+    nghttp2_frame_origin_free(&frame->ext, mem);
+    nghttp2_mem_free(mem, item);
+
+    return rv;
+  }
+
+  return 0;
+
+fail_item_malloc:
+  free(ov_copy);
+
+  return rv;
+}
+
+static uint8_t set_request_flags(const nghttp2_priority_spec *pri_spec,
+                                 const nghttp2_data_provider *data_prd) {
+  uint8_t flags = NGHTTP2_FLAG_NONE;
+  if (data_prd == NULL || data_prd->read_callback == NULL) {
+    flags |= NGHTTP2_FLAG_END_STREAM;
+  }
+
+  if (pri_spec) {
+    flags |= NGHTTP2_FLAG_PRIORITY;
+  }
+
+  return flags;
+}
+
+int32_t nghttp2_submit_request(nghttp2_session *session,
+                               const nghttp2_priority_spec *pri_spec,
+                               const nghttp2_nv *nva, size_t nvlen,
+                               const nghttp2_data_provider *data_prd,
+                               void *stream_user_data) {
+  uint8_t flags;
+  int rv;
+
+  if (session->server) {
+    return NGHTTP2_ERR_PROTO;
+  }
+
+  if (pri_spec && !nghttp2_priority_spec_check_default(pri_spec)) {
+    rv = detect_self_dependency(session, -1, pri_spec);
+    if (rv != 0) {
+      return rv;
+    }
+  } else {
+    pri_spec = NULL;
+  }
+
+  flags = set_request_flags(pri_spec, data_prd);
+
+  return submit_headers_shared_nva(session, flags, -1, pri_spec, nva, nvlen,
+                                   data_prd, stream_user_data);
+}
+
+static uint8_t set_response_flags(const nghttp2_data_provider *data_prd) {
+  uint8_t flags = NGHTTP2_FLAG_NONE;
+  if (data_prd == NULL || data_prd->read_callback == NULL) {
+    flags |= NGHTTP2_FLAG_END_STREAM;
+  }
+  return flags;
+}
+
+int nghttp2_submit_response(nghttp2_session *session, int32_t stream_id,
+                            const nghttp2_nv *nva, size_t nvlen,
+                            const nghttp2_data_provider *data_prd) {
+  uint8_t flags;
+
+  if (stream_id <= 0) {
+    return NGHTTP2_ERR_INVALID_ARGUMENT;
+  }
+
+  if (!session->server) {
+    return NGHTTP2_ERR_PROTO;
+  }
+
+  flags = set_response_flags(data_prd);
+  return submit_headers_shared_nva(session, flags, stream_id, NULL, nva, nvlen,
+                                   data_prd, NULL);
+}
+
+int nghttp2_submit_data(nghttp2_session *session, uint8_t flags,
+                        int32_t stream_id,
+                        const nghttp2_data_provider *data_prd) {
+  int rv;
+  nghttp2_outbound_item *item;
+  nghttp2_frame *frame;
+  nghttp2_data_aux_data *aux_data;
+  uint8_t nflags = flags & NGHTTP2_FLAG_END_STREAM;
+  nghttp2_mem *mem;
+
+  mem = &session->mem;
+
+  if (stream_id == 0) {
+    return NGHTTP2_ERR_INVALID_ARGUMENT;
+  }
+
+  item = nghttp2_mem_malloc(mem, sizeof(nghttp2_outbound_item));
+  if (item == NULL) {
+    return NGHTTP2_ERR_NOMEM;
+  }
+
+  nghttp2_outbound_item_init(item);
+
+  frame = &item->frame;
+  aux_data = &item->aux_data.data;
+  aux_data->data_prd = *data_prd;
+  aux_data->eof = 0;
+  aux_data->flags = nflags;
+
+  /* flags are sent on transmission */
+  nghttp2_frame_data_init(&frame->data, NGHTTP2_FLAG_NONE, stream_id);
+
+  rv = nghttp2_session_add_item(session, item);
+  if (rv != 0) {
+    nghttp2_frame_data_free(&frame->data);
+    nghttp2_mem_free(mem, item);
+    return rv;
+  }
+  return 0;
+}
+
+ssize_t nghttp2_pack_settings_payload(uint8_t *buf, size_t buflen,
+                                      const nghttp2_settings_entry *iv,
+                                      size_t niv) {
+  if (!nghttp2_iv_check(iv, niv)) {
+    return NGHTTP2_ERR_INVALID_ARGUMENT;
+  }
+
+  if (buflen < (niv * NGHTTP2_FRAME_SETTINGS_ENTRY_LENGTH)) {
+    return NGHTTP2_ERR_INSUFF_BUFSIZE;
+  }
+
+  return (ssize_t)nghttp2_frame_pack_settings_payload(buf, iv, niv);
+}
+
+int nghttp2_submit_extension(nghttp2_session *session, uint8_t type,
+                             uint8_t flags, int32_t stream_id, void *payload) {
+  int rv;
+  nghttp2_outbound_item *item;
+  nghttp2_frame *frame;
+  nghttp2_mem *mem;
+
+  mem = &session->mem;
+
+  if (type <= NGHTTP2_CONTINUATION) {
+    return NGHTTP2_ERR_INVALID_ARGUMENT;
+  }
+
+  if (!session->callbacks.pack_extension_callback) {
+    return NGHTTP2_ERR_INVALID_STATE;
+  }
+
+  item = nghttp2_mem_malloc(mem, sizeof(nghttp2_outbound_item));
+  if (item == NULL) {
+    return NGHTTP2_ERR_NOMEM;
+  }
+
+  nghttp2_outbound_item_init(item);
+
+  frame = &item->frame;
+  nghttp2_frame_extension_init(&frame->ext, type, flags, stream_id, payload);
+
+  rv = nghttp2_session_add_item(session, item);
+  if (rv != 0) {
+    nghttp2_frame_extension_free(&frame->ext);
+    nghttp2_mem_free(mem, item);
+    return rv;
+  }
+
+  return 0;
+}
diff --git a/Utilities/cmnghttp2/lib/nghttp2_submit.h b/Utilities/cmnghttp2/lib/nghttp2_submit.h
new file mode 100644
index 0000000..74d702f
--- /dev/null
+++ b/Utilities/cmnghttp2/lib/nghttp2_submit.h
@@ -0,0 +1,34 @@
+/*
+ * nghttp2 - HTTP/2 C Library
+ *
+ * Copyright (c) 2012 Tatsuhiro Tsujikawa
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+#ifndef NGHTTP2_SUBMIT_H
+#define NGHTTP2_SUBMIT_H
+
+#ifdef HAVE_CONFIG_H
+#  include <config.h>
+#endif /* HAVE_CONFIG_H */
+
+#include <nghttp2/nghttp2.h>
+
+#endif /* NGHTTP2_SUBMIT_H */
diff --git a/Utilities/cmnghttp2/lib/nghttp2_version.c b/Utilities/cmnghttp2/lib/nghttp2_version.c
new file mode 100644
index 0000000..4211f2c
--- /dev/null
+++ b/Utilities/cmnghttp2/lib/nghttp2_version.c
@@ -0,0 +1,38 @@
+/*
+ * nghttp2 - HTTP/2 C Library
+ *
+ * Copyright (c) 2012, 2013 Tatsuhiro Tsujikawa
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+#ifdef HAVE_CONFIG_H
+#  include <config.h>
+#endif /* HAVE_CONFIG_H */
+
+#include <nghttp2/nghttp2.h>
+
+static nghttp2_info version = {NGHTTP2_VERSION_AGE, NGHTTP2_VERSION_NUM,
+                               NGHTTP2_VERSION, NGHTTP2_PROTO_VERSION_ID};
+
+nghttp2_info *nghttp2_version(int least_version) {
+  if (least_version > NGHTTP2_VERSION_NUM)
+    return NULL;
+  return &version;
+}
diff --git a/Utilities/cmzlib/CMakeLists.txt b/Utilities/cmzlib/CMakeLists.txt
index 888c3ff..0584c55 100644
--- a/Utilities/cmzlib/CMakeLists.txt
+++ b/Utilities/cmzlib/CMakeLists.txt
@@ -38,11 +38,6 @@
 CONFIGURE_FILE(${CMZLIB_SOURCE_DIR}/zlibDllConfig.h.in
   ${CMZLIB_BINARY_DIR}/zlibDllConfig.h)
 
-FOREACH(name zlib zconf cm_zlib_mangle)
-  CONFIGURE_FILE(${CMZLIB_SOURCE_DIR}/${name}.h
-    ${CMZLIB_BINARY_DIR}/${name}.h COPYONLY)
-ENDFOREACH(name)
-
 
 ADD_LIBRARY(cmzlib ${ZLIB_SRCS})
 
diff --git a/Utilities/std/CMakeLists.txt b/Utilities/std/CMakeLists.txt
index 63c0a60..23d9104 100644
--- a/Utilities/std/CMakeLists.txt
+++ b/Utilities/std/CMakeLists.txt
@@ -1,10 +1,17 @@
 
+# To ensure maximum portability across various compilers and platforms
+# deactivate any compiler extensions
+set(CMAKE_CXX_EXTENSIONS FALSE)
+
 # source files for CMake std library
-set(SRCS cm/bits/string_view.cxx
+set(SRCS cm/bits/fs_path.cxx
+         cm/bits/string_view.cxx
+         cm/filesystem
          cm/memory
          cm/optional
          cm/shared_mutex
          cm/string_view
-         cm/utility)
+         cm/utility
+         cmext/string_view)
 
 add_library(cmstd STATIC ${SRCS})
diff --git a/Utilities/std/cm/bits/fs_path.cxx b/Utilities/std/cm/bits/fs_path.cxx
new file mode 100644
index 0000000..8089998
--- /dev/null
+++ b/Utilities/std/cm/bits/fs_path.cxx
@@ -0,0 +1,1029 @@
+/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
+   file Copyright.txt or https://cmake.org/licensing for details.  */
+
+#include <cm/filesystem> // IWYU pragma: associated
+
+#if !defined(CMake_HAVE_CXX_FILESYSTEM)
+
+#  include <algorithm>
+#  include <cassert>
+#  include <cstddef>
+#  include <cstdlib>
+#  include <functional>
+#  include <string>
+#  include <utility>
+#  include <vector>
+#  if defined(_WIN32) && !defined(__CYGWIN__)
+#    include <cctype>
+#  endif
+#  if defined(_WIN32) || defined(__CYGWIN__)
+#    include <iterator>
+#  endif
+
+#  include <cm/memory>
+#  include <cm/string_view>
+#  include <cmext/string_view>
+
+namespace cm {
+namespace filesystem {
+namespace internals {
+
+class path_parser
+{
+#  if defined(__SUNPRO_CC) && defined(__sparc)
+  // Oracle DeveloperStudio C++ compiler generates wrong code if enum size
+  // is different than the default.
+  using enum_size = int;
+#  else
+  using enum_size = unsigned char;
+#  endif
+
+  enum class state : enum_size
+  {
+    before_begin,
+    in_root_name,
+    in_root_dir,
+    in_filename,
+    trailing_separator,
+    at_end
+  };
+
+  using pointer = char const*;
+
+public:
+  enum class seek_position : enum_size
+  {
+    root_name = static_cast<enum_size>(state::in_root_name),
+    root_directory = static_cast<enum_size>(state::in_root_dir)
+  };
+  enum class peek_fragment : enum_size
+  {
+    remainder,
+    path
+  };
+
+  path_parser(cm::string_view path, bool set_at_end = false)
+    : State(set_at_end ? state::at_end : state::before_begin)
+    , Path(path)
+  {
+  }
+
+  path_parser(const path_parser&) = default;
+
+  ~path_parser() = default;
+
+  void reset() noexcept { this->set_state(state::before_begin); }
+
+  void increment() noexcept
+  {
+    const pointer start = this->next_token();
+    const pointer end = this->after_end();
+
+    if (start == end) {
+      this->set_state(state::at_end);
+      return;
+    }
+
+    switch (this->State) {
+      case state::before_begin: {
+        auto pos = this->consume_root_name(start, end);
+        if (pos) {
+          this->set_state(state::in_root_name);
+        } else {
+          pos = this->consume_separator(start, end);
+          if (pos) {
+            this->set_state(state::in_root_dir);
+          } else {
+            this->consume_filename(start, end);
+            this->set_state(state::in_filename);
+          }
+        }
+        break;
+      }
+      case state::in_root_name: {
+        auto pos = this->consume_separator(start, end);
+        if (pos) {
+          this->set_state(state::in_root_dir);
+        } else {
+          this->consume_filename(start, end);
+          this->set_state(state::in_filename);
+        }
+        break;
+      }
+      case state::in_root_dir: {
+        this->consume_filename(start, end);
+        this->set_state(state::in_filename);
+        break;
+      }
+      case state::in_filename: {
+        auto posSep = this->consume_separator(start, end);
+        if (posSep != end) {
+          auto pos = this->consume_filename(posSep, end);
+          if (pos) {
+            return;
+          }
+        }
+        set_state(state::trailing_separator);
+        break;
+      }
+      case state::trailing_separator: {
+        this->set_state(state::at_end);
+        break;
+      }
+      case state::at_end:
+        // unreachable
+        std::abort();
+    }
+  }
+
+  void decrement() noexcept
+  {
+    const pointer rstart = this->current_token() - 1;
+    const pointer rend = this->before_start();
+
+    if (rstart == rend) {
+      this->set_state(state::before_begin);
+      return;
+    }
+
+    switch (this->State) {
+      case state::at_end: {
+        auto posSep = this->consume_separator(rstart, rend);
+        if (posSep) {
+          if (posSep == rend) {
+            this->set_state(state::in_root_dir);
+          } else {
+            auto pos = this->consume_root_name(posSep, rend, true);
+            if (pos == rend) {
+              this->set_state(state::in_root_dir);
+            } else {
+              this->set_state(state::trailing_separator);
+            }
+          }
+        } else {
+          auto pos = this->consume_root_name(rstart, rend);
+          if (pos == rend) {
+            this->set_state(state::in_root_name);
+          } else {
+            this->consume_filename(rstart, rend);
+            this->set_state(state::in_filename);
+          }
+        }
+        break;
+      }
+      case state::trailing_separator: {
+        this->consume_filename(rstart, rend);
+        this->set_state(state::in_filename);
+        break;
+      }
+      case state::in_filename: {
+        auto posSep = this->consume_separator(rstart, rend);
+        if (posSep == rend) {
+          this->set_state(state::in_root_dir);
+        } else {
+          auto pos = this->consume_root_name(posSep, rend, true);
+          if (pos == rend) {
+            this->set_state(state::in_root_dir);
+          } else {
+            this->consume_filename(posSep, rend);
+            this->set_state(state::in_filename);
+          }
+        }
+        break;
+      }
+      case state::in_root_dir: {
+        auto pos = this->consume_root_name(rstart, rend);
+        if (pos) {
+          this->set_state(state::in_root_name);
+        }
+        break;
+      }
+      case state::in_root_name:
+      case state::before_begin: {
+        // unreachable
+        std::abort();
+      }
+    }
+  }
+
+  path_parser& operator++() noexcept
+  {
+    this->increment();
+    return *this;
+  }
+
+  path_parser& operator--() noexcept
+  {
+    this->decrement();
+    return *this;
+  }
+
+  cm::string_view operator*() const noexcept
+  {
+    switch (this->State) {
+      case state::before_begin:
+      case state::at_end:
+        return cm::string_view();
+      case state::trailing_separator:
+        return "";
+      case state::in_root_dir:
+      case state::in_root_name:
+      case state::in_filename:
+        return this->Entry;
+      default:
+        // unreachable
+        std::abort();
+    }
+  }
+
+  void seek(seek_position position)
+  {
+    state s = static_cast<state>(static_cast<int>(position));
+
+    while (this->State <= s) {
+      this->increment();
+    }
+  }
+
+  cm::string_view peek(peek_fragment fragment)
+  {
+    if (fragment == peek_fragment::remainder) {
+      // peek-up remain part of the initial path
+      return { this->Entry.data(),
+               std::size_t(&this->Path.back() - this->Entry.data() + 1) };
+    }
+    if (fragment == peek_fragment::path) {
+      // peek-up full path until current position
+      return { this->Path.data(),
+               std::size_t(&this->Entry.back() - this->Path.data() + 1) };
+    }
+    return {};
+  }
+
+  bool in_root_name() const { return this->State == state::in_root_name; }
+  bool in_root_directory() const { return this->State == state::in_root_dir; }
+  bool at_end() const { return this->State == state::at_end; }
+
+  bool at_start() const { return this->Entry.data() == this->Path.data(); }
+
+private:
+  void set_state(state newState) noexcept
+  {
+    this->State = newState;
+    if (newState == state::before_begin || newState == state::at_end) {
+      this->Entry = {};
+    }
+  }
+
+  pointer before_start() const noexcept { return this->Path.data() - 1; }
+  pointer after_end() const noexcept
+  {
+    return this->Path.data() + this->Path.size();
+  }
+
+  pointer current_token() const noexcept
+  {
+    switch (this->State) {
+      case state::before_begin:
+      case state::in_root_name:
+        return &this->Path.front();
+      case state::in_root_dir:
+      case state::in_filename:
+      case state::trailing_separator:
+        return &this->Entry.front();
+      case state::at_end:
+        return &this->Path.back() + 1;
+      default:
+        // unreachable
+        std::abort();
+    }
+  }
+  pointer next_token() const noexcept
+  {
+    switch (this->State) {
+      case state::before_begin:
+        return this->Path.data();
+      case state::in_root_name:
+      case state::in_root_dir:
+      case state::in_filename:
+        return &this->Entry.back() + 1;
+      case state::trailing_separator:
+      case state::at_end:
+        return after_end();
+      default:
+        // unreachable
+        std::abort();
+    }
+  }
+
+  pointer consume_separator(pointer ptr, pointer end) noexcept
+  {
+    if (ptr == end ||
+        (*ptr != '/'
+#  if defined(_WIN32)
+         && *ptr != '\\'
+#  endif
+         )) {
+      return nullptr;
+    }
+    const auto step = ptr < end ? 1 : -1;
+    ptr += step;
+    while (ptr != end &&
+           (*ptr == '/'
+#  if defined(_WIN32)
+            || *ptr == '\\'
+#  endif
+            )) {
+      ptr += step;
+    }
+    if (step == 1) {
+      this->Entry = cm::string_view(ptr - 1, 1);
+    } else {
+      this->Entry = cm::string_view(ptr + 1, 1);
+    }
+
+    return ptr;
+  }
+
+  pointer consume_filename(pointer ptr, pointer end) noexcept
+  {
+    auto start = ptr;
+
+    if (ptr == end || *ptr == '/'
+#  if defined(_WIN32)
+        || *ptr == '\\'
+#  endif
+    ) {
+      return nullptr;
+    }
+    const auto step = ptr < end ? 1 : -1;
+    ptr += step;
+    while (ptr != end && *ptr != '/'
+#  if defined(_WIN32)
+           && *ptr != '\\'
+#  endif
+    ) {
+      ptr += step;
+    }
+
+#  if defined(_WIN32)
+    if (step == -1 && (start - ptr) >= 2 && ptr == end) {
+      // rollback drive name consumption, if any
+      if (this->is_drive_name(ptr + 1)) {
+        ptr += 2;
+      }
+      if (ptr == start) {
+        return nullptr;
+      }
+    }
+#  endif
+
+    if (step == 1) {
+      this->Entry = cm::string_view(start, ptr - start);
+    } else {
+      this->Entry = cm::string_view(ptr + 1, start - ptr);
+    }
+
+    return ptr;
+  }
+
+#  if defined(_WIN32)
+  bool is_drive_name(pointer ptr)
+  {
+    return std::toupper(ptr[0]) >= 'A' && std::toupper(ptr[0]) <= 'Z' &&
+      ptr[1] == ':';
+  }
+#  endif
+
+  pointer consume_root_name(pointer ptr, pointer end,
+                            bool check_only = false) noexcept
+  {
+#  if defined(_WIN32) && !defined(__CYGWIN__)
+    if (ptr < end) {
+      if ((end - ptr) >= 2 && this->is_drive_name(ptr)) {
+        // Drive letter (X:) is a root name
+        if (!check_only) {
+          this->Entry = cm::string_view(ptr, 2);
+        }
+        return ptr + 2;
+      }
+      if ((end - ptr) > 2 && (ptr[0] == '/' || ptr[0] == '\\') &&
+          (ptr[1] == '/' || ptr[1] == '\\') &&
+          (ptr[2] != '/' && ptr[2] != '\\')) {
+        // server name (//server) is a root name
+        auto pos = std::find_if(ptr + 2, end,
+                                [](char c) { return c == '/' || c == '\\'; });
+        if (!check_only) {
+          this->Entry = cm::string_view(ptr, pos - ptr);
+        }
+        return pos;
+      }
+    } else {
+      if ((ptr - end) >= 2 && this->is_drive_name(ptr - 1)) {
+        // Drive letter (X:) is a root name
+        if (!check_only) {
+          this->Entry = cm::string_view(ptr - 1, 2);
+        }
+        return ptr - 2;
+      }
+      if ((ptr - end) > 2 && (ptr[0] != '/' && ptr[0] != '\\')) {
+        std::reverse_iterator<pointer> start(ptr);
+        std::reverse_iterator<pointer> stop(end);
+        auto res = std::find_if(start, stop,
+                                [](char c) { return c == '/' || c == '\\'; });
+        pointer pos = res.base() - 1;
+        if ((pos - 1) > end && (pos[-1] == '/' || pos[-1] == '\\')) {
+          // server name (//server) is a root name
+          if (!check_only) {
+            this->Entry = cm::string_view(pos - 1, ptr - pos + 2);
+          }
+          return pos - 2;
+        }
+      }
+    }
+#  elif defined(__CYGWIN__)
+    if (ptr < end) {
+      if ((end - ptr) > 2 && ptr[0] == '/' && ptr[1] == '/' && ptr[2] != '/') {
+        // server name (//server) is a root name
+        auto pos = std::find(ptr + 2, end, '/');
+        if (!check_only) {
+          this->Entry = cm::string_view(ptr, pos - ptr);
+        }
+        return pos;
+      }
+    } else {
+      if ((ptr - end) > 2 && ptr[0] != '/') {
+        std::reverse_iterator<pointer> start(ptr);
+        std::reverse_iterator<pointer> stop(end);
+        auto res = std::find(start, stop, '/');
+        pointer pos = res.base() - 1;
+        if ((pos - 1) > end && pos[-1] == '/') {
+          // server name (//server) is a root name
+          if (!check_only) {
+            this->Entry = cm::string_view(pos - 1, ptr - pos + 2);
+          }
+          return pos - 2;
+        }
+      }
+    }
+#  else
+    (void)ptr;
+    (void)end;
+    (void)check_only;
+#  endif
+    return nullptr;
+  }
+
+  state State;
+  const cm::string_view Path;
+  cm::string_view Entry;
+};
+
+// class unicode_helper
+void unicode_helper::append(std::string& str, std::uint32_t codepoint)
+{
+  if (codepoint <= 0x7f) {
+    str.push_back(static_cast<char>(codepoint));
+  } else if (codepoint >= 0x80 && codepoint <= 0x7ff) {
+    str.push_back(static_cast<char>((codepoint >> 6) + 192));
+    str.push_back(static_cast<char>((codepoint & 0x3f) + 128));
+  } else if ((codepoint >= 0x800 && codepoint <= 0xd7ff) ||
+             (codepoint >= 0xe000 && codepoint <= 0xffff)) {
+    str.push_back(static_cast<char>((codepoint >> 12) + 224));
+    str.push_back(static_cast<char>(((codepoint & 0xfff) >> 6) + 128));
+    str.push_back(static_cast<char>((codepoint & 0x3f) + 128));
+  } else if (codepoint >= 0x10000 && codepoint <= 0x10ffff) {
+    str.push_back(static_cast<char>((codepoint >> 18) + 240));
+    str.push_back(static_cast<char>(((codepoint & 0x3ffff) >> 12) + 128));
+    str.push_back(static_cast<char>(((codepoint & 0xfff) >> 6) + 128));
+    str.push_back(static_cast<char>((codepoint & 0x3f) + 128));
+  } else {
+    append(str, 0xfffd);
+  }
+}
+
+unicode_helper::utf8_state unicode_helper::decode(const utf8_state state,
+                                                  const std::uint8_t fragment,
+                                                  std::uint32_t& codepoint)
+{
+  const std::uint32_t utf8_state_info[] = {
+    // encoded states
+    0x11111111u, 0x11111111u, 0x77777777u, 0x77777777u, 0x88888888u,
+    0x88888888u, 0x88888888u, 0x88888888u, 0x22222299u, 0x22222222u,
+    0x22222222u, 0x22222222u, 0x3333333au, 0x33433333u, 0x9995666bu,
+    0x99999999u, 0x88888880u, 0x22818108u, 0x88888881u, 0x88888882u,
+    0x88888884u, 0x88888887u, 0x88888886u, 0x82218108u, 0x82281108u,
+    0x88888888u, 0x88888883u, 0x88888885u, 0u,          0u,
+    0u,          0u,
+  };
+  std::uint8_t category = fragment < 128
+    ? 0
+    : (utf8_state_info[(fragment >> 3) & 0xf] >> ((fragment & 7) << 2)) & 0xf;
+  codepoint = (state ? (codepoint << 6) | (fragment & 0x3fu)
+                     : (0xffu >> category) & fragment);
+  return state == s_reject
+    ? s_reject
+    : static_cast<utf8_state>(
+        (utf8_state_info[category + 16] >> (state << 2)) & 0xf);
+}
+
+} // internals
+
+// Class path
+path& path::operator/=(const path& p)
+{
+  if (p.is_absolute() ||
+      (p.has_root_name() && p.get_root_name() != this->get_root_name())) {
+    this->path_ = p.path_;
+    return *this;
+  }
+  if (p.has_root_directory()) {
+    this->path_ = static_cast<std::string>(this->get_root_name());
+    this->path_ += static_cast<std::string>(p.get_root_directory());
+  } else if (this->has_filename()) {
+    this->path_ += this->preferred_separator;
+#  if defined(_WIN32) || defined(__CYGWIN__)
+    // special case: "//host" / "b" => "//host/b"
+  } else if (this->has_root_name() && !this->has_root_directory()) {
+    if (this->path_.length() >= 3 &&
+        (this->path_[0] == '/'
+#    if defined(_WIN32) && !defined(__CYGWIN__)
+         || this->path_[0] == '\\'
+#    endif
+         ) &&
+        (this->path_[1] == '/'
+#    if defined(_WIN32) && !defined(__CYGWIN__)
+         || this->path_[1] == '\\'
+#    endif
+         ) &&
+        (this->path_[2] != '/'
+#    if defined(_WIN32) && !defined(__CYGWIN__)
+         && this->path_[2] != '\\'
+#    endif
+         )) {
+      this->path_ += this->preferred_separator;
+    }
+#  endif
+  }
+
+  this->path_ += p.get_relative_path();
+  return *this;
+}
+
+path path::lexically_normal() const
+{
+  if (this->path_.empty()) {
+    return *this;
+  }
+
+  const cm::string_view dot = "."_s;
+  const cm::string_view dotdot = ".."_s;
+
+  std::vector<cm::string_view> root_parts;
+  std::vector<cm::string_view> parts;
+  bool root_directory_defined = false;
+  bool need_final_separator = false;
+  std::size_t path_size = 0;
+
+  internals::path_parser parser(this->path_);
+  ++parser;
+  while (!parser.at_end()) {
+    auto part = *parser;
+
+    if (parser.in_root_name() || parser.in_root_directory()) {
+      if (parser.in_root_directory()) {
+        root_directory_defined = true;
+      }
+      root_parts.push_back(part);
+      path_size += part.size();
+    } else if (part == dotdot) {
+      if (!parts.empty() && parts.back() != dotdot) {
+        need_final_separator = true;
+        path_size -= parts.back().size();
+        parts.pop_back();
+      } else if ((parts.empty() || parts.back() == dotdot) &&
+                 !root_directory_defined) {
+        parts.push_back(dotdot);
+        path_size += 2;
+      }
+
+    } else if (part == dot || part.empty()) {
+      need_final_separator = true;
+      if (part.empty()) {
+        parts.push_back(part);
+      }
+    } else {
+      // filename
+      need_final_separator = false;
+      parts.push_back(part);
+      path_size += part.size();
+    }
+    ++parser;
+  }
+
+  // no final separator if last element of path is ".."
+  need_final_separator =
+    need_final_separator && !parts.empty() && parts.back() != dotdot;
+
+  // build final path
+  //// compute final size of path
+  path_size += parts.size() + (need_final_separator ? 1 : 0);
+
+  std::string np;
+  np.reserve(path_size);
+  for (const auto& p : root_parts) {
+    np += p;
+  }
+  // convert any slash to the preferred_separator
+  if (static_cast<std::string::value_type>(this->preferred_separator) != '/') {
+    std::replace(
+      np.begin(), np.end(), '/',
+      static_cast<std::string::value_type>(this->preferred_separator));
+  }
+  for (const auto& p : parts) {
+    if (!p.empty()) {
+      np += p;
+      np += static_cast<std::string::value_type>(this->preferred_separator);
+    }
+  }
+  if (!parts.empty() && !need_final_separator) {
+    // remove extra separator
+    np.pop_back();
+  }
+  if (np.empty()) {
+    np.assign(1, '.');
+  }
+
+  return path(std::move(np));
+}
+
+path path::lexically_relative(const path& base) const
+{
+  internals::path_parser parser(this->path_);
+  ++parser;
+  internals::path_parser parserbase(base.path_);
+  ++parserbase;
+  cm::string_view this_root_name, base_root_name;
+  cm::string_view this_root_dir, base_root_dir;
+
+  if (parser.in_root_name()) {
+    this_root_name = *parser;
+    ++parser;
+  }
+  if (parser.in_root_directory()) {
+    this_root_dir = *parser;
+    ++parser;
+  }
+  if (parserbase.in_root_name()) {
+    base_root_name = *parserbase;
+    ++parserbase;
+  }
+  if (parserbase.in_root_directory()) {
+    base_root_dir = *parserbase;
+    ++parserbase;
+  }
+
+  auto is_path_absolute = [](cm::string_view rn, cm::string_view rd) -> bool {
+#  if defined(_WIN32) && !defined(__CYGWIN__)
+    return !rn.empty() && !rd.empty();
+#  else
+    (void)rn;
+    return !rd.empty();
+#  endif
+  };
+
+  if (this_root_name != base_root_name ||
+      is_path_absolute(this_root_name, this_root_dir) !=
+        is_path_absolute(base_root_name, base_root_dir) ||
+      (this_root_dir.empty() && !base_root_dir.empty())) {
+    return path();
+  }
+
+#  if defined(_WIN32) && !defined(__CYGWIN__)
+  // LWG3070 handle special case: filename can also be a root-name
+  auto is_drive_name = [](cm::string_view item) -> bool {
+    return item.length() == 2 && item[1] == ':';
+  };
+  parser.reset();
+  parser.seek(internals::path_parser::seek_position::root_directory);
+  while (!parser.at_end()) {
+    if (is_drive_name(*parser)) {
+      return path();
+    }
+    ++parser;
+  }
+  parserbase.reset();
+  parserbase.seek(internals::path_parser::seek_position::root_directory);
+  while (!parserbase.at_end()) {
+    if (is_drive_name(*parserbase)) {
+      return path();
+    }
+    ++parserbase;
+  }
+#  endif
+
+  const cm::string_view dot = "."_s;
+  const cm::string_view dotdot = ".."_s;
+
+  auto a = this->begin(), aend = this->end();
+  auto b = base.begin(), bend = base.end();
+  while (a != aend && b != bend && a->string() == b->string()) {
+    ++a;
+    ++b;
+  }
+
+  int count = 0;
+  for (; b != bend; ++b) {
+    auto part = *b;
+    if (part == dotdot) {
+      --count;
+    } else if (part.string() != dot && !part.empty()) {
+      ++count;
+    }
+  }
+
+  if (count == 0 && (a == this->end() || a->empty())) {
+    return path(dot);
+  }
+  if (count >= 0) {
+    path result;
+    path p_dotdot(dotdot);
+    for (int i = 0; i < count; ++i) {
+      result /= p_dotdot;
+    }
+    for (; a != aend; ++a) {
+      result /= *a;
+    }
+    return result;
+  }
+  // count < 0
+  return path();
+}
+
+path::path_type path::get_generic() const
+{
+  auto gen_path = this->path_;
+  auto start = gen_path.begin();
+#  if defined(_WIN32) && !defined(__CYGWIN__)
+  std::replace(gen_path.begin(), gen_path.end(), '\\', '/');
+  // preserve special syntax for root_name ('//server' or '//?')
+  if (gen_path.length() > 2 && gen_path[2] != '/') {
+    start += 2;
+  }
+#  endif
+  // remove duplicate separators
+  auto new_end = std::unique(start, gen_path.end(), [](char lhs, char rhs) {
+    return lhs == rhs && lhs == '/';
+  });
+  gen_path.erase(new_end, gen_path.end());
+  return gen_path;
+}
+
+cm::string_view path::get_root_name() const
+{
+  internals::path_parser parser(this->path_);
+  ++parser;
+  if (parser.in_root_name()) {
+    return *parser;
+  }
+  return {};
+}
+
+cm::string_view path::get_root_directory() const
+{
+  internals::path_parser parser(this->path_);
+  ++parser;
+  if (parser.in_root_name()) {
+    ++parser;
+  }
+  if (parser.in_root_directory()) {
+    return *parser;
+  }
+  return {};
+}
+
+cm::string_view path::get_relative_path() const
+{
+  internals::path_parser parser(this->path_);
+  parser.seek(internals::path_parser::seek_position::root_directory);
+  if (parser.at_end()) {
+    return {};
+  }
+  return parser.peek(internals::path_parser::peek_fragment::remainder);
+}
+
+cm::string_view path::get_parent_path() const
+{
+  if (!this->has_relative_path()) {
+    return this->path_;
+  }
+
+  // peek-up full path minus last element
+  internals::path_parser parser(this->path_, true);
+  --parser;
+  if (parser.at_start()) {
+    return {};
+  }
+  --parser;
+  return parser.peek(internals::path_parser::peek_fragment::path);
+}
+
+cm::string_view path::get_filename() const
+{
+  {
+    internals::path_parser parser(this->path_);
+    parser.seek(internals::path_parser::seek_position::root_directory);
+    if (parser.at_end()) {
+      return {};
+    }
+  }
+  {
+    internals::path_parser parser(this->path_, true);
+    return *(--parser);
+  }
+}
+
+cm::string_view path::get_filename_fragment(filename_fragment fragment) const
+{
+  auto file = this->get_filename();
+
+  if (file == "." || file == ".." || file.empty()) {
+    return fragment == filename_fragment::stem ? file : cm::string_view{};
+  }
+
+  auto pos = file.find_last_of('.');
+  if (pos == cm::string_view::npos || pos == 0) {
+    return fragment == filename_fragment::stem ? file : cm::string_view{};
+  }
+  return fragment == filename_fragment::stem ? file.substr(0, pos)
+                                             : file.substr(pos);
+}
+
+int path::compare_path(cm::string_view str) const
+{
+  internals::path_parser this_pp(this->path_);
+  ++this_pp;
+  internals::path_parser other_pp(str);
+  ++other_pp;
+
+  // compare root_name part
+  {
+    bool compare_root_names = false;
+    cm::string_view this_root_name, other_root_name;
+    int res;
+
+    if (this_pp.in_root_name()) {
+      compare_root_names = true;
+      this_root_name = *this_pp;
+      ++this_pp;
+    }
+    if (other_pp.in_root_name()) {
+      compare_root_names = true;
+      other_root_name = *other_pp;
+      ++other_pp;
+    }
+    if (compare_root_names &&
+        (res = this_root_name.compare(other_root_name) != 0)) {
+      return res;
+    }
+  }
+
+  // compare root_directory part
+  {
+    if (!this_pp.in_root_directory() && other_pp.in_root_directory()) {
+      return -1;
+    } else if (this_pp.in_root_directory() && !other_pp.in_root_directory()) {
+      return 1;
+    }
+    if (this_pp.in_root_directory()) {
+      ++this_pp;
+    }
+    if (other_pp.in_root_directory()) {
+      ++other_pp;
+    }
+  }
+
+  // compare various parts of the paths
+  while (!this_pp.at_end() && !other_pp.at_end()) {
+    int res;
+    if ((res = (*this_pp).compare(*other_pp)) != 0) {
+      return res;
+    }
+    ++this_pp;
+    ++other_pp;
+  }
+
+  // final step
+  if (this_pp.at_end() && !other_pp.at_end()) {
+    return -1;
+  } else if (!this_pp.at_end() && other_pp.at_end()) {
+    return 1;
+  }
+
+  return 0;
+}
+
+// Class path::iterator
+path::iterator::iterator()
+  : path_(nullptr)
+{
+}
+path::iterator::iterator(const iterator& other)
+{
+  this->path_ = other.path_;
+  if (other.parser_) {
+    this->parser_ = cm::make_unique<internals::path_parser>(*other.parser_);
+    this->path_element_ = path(**this->parser_);
+  }
+}
+path::iterator::iterator(const path* p, bool at_end)
+  : path_(p)
+  , parser_(cm::make_unique<internals::path_parser>(p->path_, at_end))
+{
+  if (!at_end) {
+    ++(*this->parser_);
+    this->path_element_ = path(**this->parser_);
+  }
+}
+
+path::iterator::~iterator() = default;
+
+path::iterator& path::iterator::operator=(const iterator& other)
+{
+  this->path_ = other.path_;
+  if (other.parser_) {
+    this->parser_ = cm::make_unique<internals::path_parser>(*other.parser_);
+    this->path_element_ = path(**this->parser_);
+  }
+
+  return *this;
+}
+
+path::iterator& path::iterator::operator++()
+{
+  assert(this->parser_);
+
+  if (this->parser_) {
+    assert(!this->parser_->at_end());
+
+    if (!this->parser_->at_end()) {
+      ++(*this->parser_);
+      if (this->parser_->at_end()) {
+        this->path_element_ = path();
+      } else {
+        this->path_element_ = path(**this->parser_);
+      }
+    }
+  }
+
+  return *this;
+}
+
+path::iterator& path::iterator::operator--()
+{
+  assert(this->parser_);
+
+  if (this->parser_) {
+    assert(!this->parser_->at_start());
+
+    if (!this->parser_->at_start()) {
+      --(*this->parser_);
+      this->path_element_ = path(**this->parser_);
+    }
+  }
+
+  return *this;
+}
+
+bool operator==(const path::iterator& lhs, const path::iterator& rhs)
+{
+  return lhs.path_ == rhs.path_ && lhs.parser_ != nullptr &&
+    ((lhs.parser_->at_end() && rhs.parser_->at_end()) ||
+     (lhs.parser_->at_start() && rhs.parser_->at_start()) ||
+     ((**lhs.parser_).data() == (**rhs.parser_).data()));
+}
+
+std::size_t hash_value(const path& p) noexcept
+{
+  internals::path_parser parser(p.path_);
+  std::hash<cm::string_view> hasher;
+  std::size_t value = 0;
+
+  while (!parser.at_end()) {
+    value = hasher(*parser) + 0x9e3779b9 + (value << 6) + (value >> 2);
+    ++parser;
+  }
+
+  return value;
+}
+} // filesystem
+} // cm
+
+#else
+
+// Avoid empty translation unit.
+void cm_filesystem_path_cxx()
+{
+}
+
+#endif
diff --git a/Utilities/std/cm/bits/string_view.cxx b/Utilities/std/cm/bits/string_view.cxx
index e345fd3..5381fe6 100644
--- a/Utilities/std/cm/bits/string_view.cxx
+++ b/Utilities/std/cm/bits/string_view.cxx
@@ -9,7 +9,7 @@
 #  include <ostream>
 #  include <stdexcept>
 
-#  include "cm_kwiml.h"
+#  include <cm3p/kwiml/int.h>
 
 namespace cm {
 
diff --git a/Utilities/std/cm/filesystem b/Utilities/std/cm/filesystem
new file mode 100644
index 0000000..6021712
--- /dev/null
+++ b/Utilities/std/cm/filesystem
@@ -0,0 +1,1175 @@
+// -*-c++-*-
+// vim: set ft=cpp:
+
+/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
+   file Copyright.txt or https://cmake.org/licensing for details.  */
+#ifndef cm_filesystem
+#define cm_filesystem
+
+#include "cmSTL.hxx" // IWYU pragma: keep
+
+#if defined(CMake_HAVE_CXX_FILESYSTEM)
+
+#  include <filesystem> // IWYU pragma: export
+
+#else
+
+#  include <cstddef>
+#  include <cstdint>
+#  include <iostream>
+#  include <iterator>
+#  include <memory>
+#  include <string>
+#  include <utility>
+
+#  include <cm/iomanip>
+#  include <cm/string_view>
+#  include <cm/type_traits>
+#  include <cmext/iterator>
+
+#  if defined(_WIN32) && !defined(__CYGWIN__)
+#    include <algorithm>
+#  endif
+
+#endif
+
+namespace cm {
+namespace filesystem {
+
+#if defined(CMake_HAVE_CXX_FILESYSTEM)
+
+using std::filesystem::path;
+using std::filesystem::swap;
+using std::filesystem::hash_value;
+
+#else
+
+#  if !defined(CM_FILESYSTEM_SOURCE_TRAITS_ITERATOR)
+// Oracle DeveloperStudio C++ compiler on Solaris/Sparc fails to compile
+// the source_traits for iterator check.  So disable it for now.
+#    define CM_FILESYSTEM_SOURCE_TRAITS_ITERATOR 0
+#  endif
+
+namespace internals {
+
+class path_parser;
+
+class unicode_helper
+{
+protected:
+  using utf8_state = unsigned char;
+  static const utf8_state s_start = 0;
+  static const utf8_state s_reject = 8;
+
+  static inline bool in_range(std::uint32_t c, std::uint32_t lo,
+                              std::uint32_t hi)
+  {
+    return (static_cast<std::uint32_t>(c - lo) < (hi - lo + 1));
+  }
+
+  static inline bool is_surrogate(std::uint32_t c)
+  {
+    return in_range(c, 0xd800, 0xdfff);
+  }
+
+  static inline bool is_high_surrogate(std::uint32_t c)
+  {
+    return (c & 0xfffffc00) == 0xd800;
+  }
+
+  static inline bool is_low_surrogate(std::uint32_t c)
+  {
+    return (c & 0xfffffc00) == 0xdc00;
+  }
+
+  static void append(std::string& str, std::uint32_t codepoint);
+
+  static utf8_state decode(const utf8_state state, const std::uint8_t fragment,
+                           std::uint32_t& codepoint);
+};
+
+template <typename Char, typename = void>
+class unicode
+{
+};
+
+template <typename Char>
+class unicode<Char, typename std::enable_if<(sizeof(Char) == 4)>::type>
+  : public unicode_helper
+{
+public:
+  // UTF32 -> UTF8
+  static std::string to_utf8(const std::wstring& str)
+  {
+    std::string result;
+    for (auto c : str) {
+      append(result, c);
+    }
+    return result;
+  }
+  static std::string to_utf8(Char c)
+  {
+    std::string result;
+    append(result, c);
+    return result;
+  }
+
+  // UTF8 -> UTF32
+  static std::wstring from_utf8(const std::string& str)
+  {
+    std::wstring result;
+    result.reserve(str.length());
+    auto iter = str.begin();
+    utf8_state state = s_start;
+    std::uint32_t codepoint = 0;
+    while (iter < str.end()) {
+      if ((state = decode(state, static_cast<std::uint8_t>(*iter++),
+                          codepoint)) == s_start) {
+        result += static_cast<std::wstring::value_type>(codepoint);
+        codepoint = 0;
+      } else if (state == s_reject) {
+        result += static_cast<std::wstring::value_type>(0xfffd);
+        state = s_start;
+        codepoint = 0;
+      }
+    }
+    if (state) {
+      result += static_cast<std::wstring::value_type>(0xfffd);
+    }
+    return result;
+  }
+  static std::wstring from_utf8(char c)
+  {
+    std::wstring result;
+    utf8_state state = s_start;
+    std::uint32_t codepoint = 0;
+    if ((state = decode(state, static_cast<std::uint8_t>(c), codepoint)) ==
+        s_start) {
+      result += static_cast<std::wstring::value_type>(codepoint);
+    } else {
+      result += static_cast<std::wstring::value_type>(0xfffd);
+    }
+
+    return result;
+  }
+};
+
+template <typename Char>
+class unicode<Char, typename std::enable_if<(sizeof(Char) == 2)>::type>
+  : public unicode_helper
+{
+public:
+  // UTF16 -> UTF8
+  static std::string to_utf8(const std::wstring& str)
+  {
+    std::string result;
+    for (auto iter = str.begin(); iter != str.end(); ++iter) {
+      std::uint32_t c = *iter;
+      if (is_surrogate(c)) {
+        ++iter;
+        if (iter != str.end() && is_high_surrogate(c) &&
+            is_low_surrogate(*iter)) {
+          append(result, (std::uint32_t(c) << 10) + *iter - 0x35fdc00);
+        } else {
+          append(result, 0xfffd);
+          if (iter == str.end()) {
+            break;
+          }
+        }
+      } else {
+        append(result, c);
+      }
+    }
+    return result;
+  }
+  static std::string to_utf8(Char c)
+  {
+    std::string result;
+    if (is_surrogate(c)) {
+      append(result, 0xfffd);
+    } else {
+      append(result, c);
+    }
+    return result;
+  }
+
+  // UTF8 -> UTF16
+  static std::wstring from_utf8(const std::string& str)
+  {
+    std::wstring result;
+    result.reserve(str.length());
+    auto iter = str.begin();
+    utf8_state state = s_start;
+    std::uint32_t codepoint = 0;
+    while (iter < str.end()) {
+      if ((state = decode(state, static_cast<std::uint8_t>(*iter++),
+                          codepoint)) == s_start) {
+        if (codepoint <= 0xffff) {
+          result += static_cast<std::wstring::value_type>(codepoint);
+        } else {
+          codepoint -= 0x10000;
+          result +=
+            static_cast<std::wstring::value_type>((codepoint >> 10) + 0xd800);
+          result += static_cast<std::wstring::value_type>((codepoint & 0x3ff) +
+                                                          0xdc00);
+        }
+        codepoint = 0;
+      } else if (state == s_reject) {
+        result += static_cast<std::wstring::value_type>(0xfffd);
+        state = s_start;
+        codepoint = 0;
+      }
+    }
+    if (state) {
+      result += static_cast<std::wstring::value_type>(0xfffd);
+    }
+    return result;
+  }
+  static std::wstring from_utf8(char c)
+  {
+    std::wstring result;
+    utf8_state state = s_start;
+    std::uint32_t codepoint = 0;
+    if ((state = decode(state, static_cast<std::uint8_t>(c), codepoint)) ==
+        s_start) {
+      if (codepoint <= 0xffff) {
+        result += static_cast<std::wstring::value_type>(codepoint);
+      } else {
+        codepoint -= 0x10000;
+        result +=
+          static_cast<std::wstring::value_type>((codepoint >> 10) + 0xd800);
+        result +=
+          static_cast<std::wstring::value_type>((codepoint & 0x3ff) + 0xdc00);
+      }
+    } else {
+      result += static_cast<std::wstring::value_type>(0xfffd);
+    }
+    return result;
+  }
+};
+
+template <typename In, typename Out>
+class unicode_converter;
+
+template <>
+class unicode_converter<char, wchar_t>
+{
+public:
+  std::wstring operator()(const std::string& in)
+  {
+    return unicode<wchar_t>::from_utf8(in);
+  }
+  std::wstring operator()(const char* in)
+  {
+    return unicode<wchar_t>::from_utf8(in);
+  }
+  std::wstring operator()(char in) { return unicode<wchar_t>::from_utf8(in); }
+};
+template <>
+class unicode_converter<wchar_t, char>
+{
+public:
+  std::string operator()(const std::wstring& in)
+  {
+    return unicode<wchar_t>::to_utf8(in);
+  }
+  std::string operator()(const wchar_t* in)
+  {
+    return unicode<wchar_t>::to_utf8(in);
+  }
+  std::string operator()(wchar_t in) { return unicode<wchar_t>::to_utf8(in); }
+};
+template <>
+class unicode_converter<char, char>
+{
+public:
+  std::string operator()(const std::string& in) { return in; }
+  std::string operator()(const char* in) { return std::string(in); }
+  std::string operator()(char in) { return std::string(1, in); }
+};
+template <>
+class unicode_converter<wchar_t, wchar_t>
+{
+public:
+  std::wstring operator()(const std::wstring& in) { return in; }
+  std::wstring operator()(const wchar_t* in) { return std::wstring(in); }
+  std::wstring operator()(wchar_t in) { return std::wstring(1, in); }
+};
+
+template <typename In>
+struct string_converter
+{
+};
+
+template <>
+struct string_converter<char>
+{
+  // some compilers, like gcc 4.8 does not implement the following C++11
+  // signature:
+  // std::string::string(const string&, const Allocator&)
+  // As workaround, use char* pointer.
+  template <typename Char, typename Traits, typename Alloc>
+  static std::basic_string<Char, Traits, Alloc> to(const std::string& in,
+                                                   const Alloc& a)
+  {
+    return std::basic_string<Char, Traits, Alloc>(
+      unicode_converter<char, Char>()(in).c_str(), a);
+  }
+  template <typename Char, typename Traits, typename Alloc>
+  static std::basic_string<Char, Traits, Alloc> to(const char* in,
+                                                   const Alloc& a)
+  {
+    return std::basic_string<Char, Traits, Alloc>(
+      unicode_converter<char, Char>()(in).c_str(), a);
+  }
+  template <typename Char, typename Traits, typename Alloc>
+  static std::basic_string<Char, Traits, Alloc> to(char in, const Alloc& a)
+  {
+    return std::basic_string<Char, Traits, Alloc>(
+      unicode_converter<char, Char>()(in).c_str(), a);
+  }
+
+  template <typename Char>
+  static std::basic_string<Char> to(const std::string& in)
+  {
+    return std::basic_string<Char>(unicode_converter<char, Char>()(in));
+  }
+  template <typename Char>
+  static std::basic_string<Char> to(const char* in)
+  {
+    return std::basic_string<Char>(unicode_converter<char, Char>()(in));
+  }
+  template <typename Char>
+  static std::basic_string<Char> to(char in)
+  {
+    return std::basic_string<Char>(unicode_converter<char, Char>()(in));
+  }
+};
+template <>
+struct string_converter<wchar_t>
+{
+  // some compilers, like gcc 4.8 does not implement the following C++11
+  // signature:
+  // std::string::string(const string&, const Allocator&)
+  // As workaround, use char* pointer.
+  template <typename Char, typename Traits, typename Alloc>
+  static std::basic_string<Char, Traits, Alloc> to(const std::wstring& in,
+                                                   const Alloc& a)
+  {
+    return std::basic_string<Char, Traits, Alloc>(
+      unicode_converter<wchar_t, Char>()(in).c_str(), a);
+  }
+  template <typename Char, typename Traits, typename Alloc>
+  static std::basic_string<Char, Traits, Alloc> to(const wchar_t* in,
+                                                   const Alloc& a)
+  {
+    return std::basic_string<Char, Traits, Alloc>(
+      unicode_converter<wchar_t, Char>()(in).c_str(), a);
+  }
+  template <typename Char, typename Traits, typename Alloc>
+  static std::basic_string<Char, Traits, Alloc> to(wchar_t in, const Alloc& a)
+  {
+    return std::basic_string<Char, Traits, Alloc>(
+      unicode_converter<wchar_t, Char>()(in).c_str(), a);
+  }
+
+  template <typename Char>
+  static std::basic_string<Char> to(const std::wstring& in)
+  {
+    return std::basic_string<Char>(unicode_converter<wchar_t, Char>()(in));
+  }
+  template <typename Char>
+  static std::basic_string<Char> to(const wchar_t* in)
+  {
+    return std::basic_string<Char>(unicode_converter<wchar_t, Char>()(in));
+  }
+  template <typename Char>
+  static std::basic_string<Char> to(wchar_t in)
+  {
+    return std::basic_string<Char>(unicode_converter<wchar_t, Char>()(in));
+  }
+};
+
+template <typename T, typename = void>
+struct source_traits
+{
+};
+
+template <typename T, std::size_t N>
+struct source_traits<T[N]>
+{
+  using value_type = T;
+};
+
+template <typename Char, typename Traits, typename Alloc>
+struct source_traits<std::basic_string<Char, Traits, Alloc>>
+{
+  using value_type =
+    typename std::basic_string<Char, Traits, Alloc>::value_type;
+};
+
+template <>
+struct source_traits<cm::string_view>
+{
+  using value_type = cm::string_view::value_type;
+};
+
+#  if CM_FILESYSTEM_SOURCE_TRAITS_ITERATOR
+template <typename T>
+struct source_traits<T, cm::enable_if_t<cm::is_iterator<T>::value, void>>
+{
+  using value_type =
+    typename std::iterator_traits<typename std::decay<T>::type>::value_type;
+};
+#  endif
+
+template <typename In, typename Out>
+struct source_converter
+{
+};
+
+template <>
+struct source_converter<char, char>
+{
+  template <typename Iterator>
+  static void append_range(std::string& p, Iterator b, Iterator e)
+  {
+    if (b == e) {
+      return;
+    }
+    p.append(b, e);
+  }
+  template <typename Iterator>
+  static void append_range(std::string& p, Iterator b)
+  {
+    char e = '\0';
+
+    if (*b == e) {
+      return;
+    }
+    for (; *b != e; ++b) {
+      p.push_back(*b);
+    }
+  }
+
+  static void append_source(std::string& p, const cm::string_view s)
+  {
+    append_range(p, s.begin(), s.end());
+  }
+  template <typename Traits, typename Alloc>
+  static void append_source(std::string& p,
+                            const std::basic_string<char, Traits, Alloc>& s)
+  {
+    append_range(p, s.begin(), s.end());
+  }
+  template <typename Source>
+  static void append_source(std::string& p, const Source& s)
+  {
+    append_range(p, s);
+  }
+
+  static void set_source(std::string& p, std::string&& s) { p = std::move(s); }
+};
+
+template <>
+struct source_converter<wchar_t, char>
+{
+  template <typename Iterator>
+  static void append_range(std::string& p, Iterator b, Iterator e)
+  {
+    if (b == e) {
+      return;
+    }
+
+    std::wstring tmp(b, e);
+    std::string dest = string_converter<wchar_t>::to<char>(tmp);
+    p.append(dest.begin(), dest.end());
+  }
+  template <typename Iterator>
+  static void append_range(std::string& p, Iterator b)
+  {
+    wchar_t e = '\0';
+
+    if (*b == e) {
+      return;
+    }
+    std::wstring tmp;
+    for (; *b != e; ++b) {
+      tmp.push_back(*b);
+    }
+
+    std::string dest = string_converter<wchar_t>::to<char>(tmp);
+    p.append(dest.begin(), dest.end());
+  }
+
+  template <typename Traits, typename Alloc>
+  static void append_source(std::string& p,
+                            const std::basic_string<wchar_t, Traits, Alloc>& s)
+  {
+    append_range(p, s.begin(), s.end());
+  }
+  template <typename Source>
+  static void append_source(std::string& p, const Source& s)
+  {
+    append_range(p, s);
+  }
+
+  static void set_source(std::string& p, std::wstring&& s)
+  {
+    p = string_converter<wchar_t>::to<char>(s);
+  }
+};
+
+template <typename T>
+struct is_pathable_string : std::false_type
+{
+};
+template <typename Traits, typename Alloc>
+struct is_pathable_string<std::basic_string<char, Traits, Alloc>>
+  : std::true_type
+{
+};
+template <typename Traits, typename Alloc>
+struct is_pathable_string<std::basic_string<wchar_t, Traits, Alloc>>
+  : std::true_type
+{
+};
+template <>
+struct is_pathable_string<cm::string_view> : std::true_type
+{
+};
+
+template <typename T, typename = void>
+struct is_pathable_char_array : std::false_type
+{
+};
+template <typename T>
+struct is_pathable_char_array<
+  T,
+  cm::enable_if_t<
+    std::is_same<char*, typename std::decay<T>::type>::value ||
+      std::is_same<wchar_t*, typename std::decay<T>::type>::value,
+    void>>
+  : bool_constant<std::is_same<char*, typename std::decay<T>::type>::value ||
+                  std::is_same<wchar_t*, typename std::decay<T>::type>::value>
+{
+};
+
+template <typename T, typename = void>
+struct is_pathable_iterator : std::false_type
+{
+};
+template <typename T>
+struct is_pathable_iterator<
+  T,
+  cm::enable_if_t<
+    is_input_iterator<T>::value &&
+      (std::is_same<char,
+                    typename std::iterator_traits<
+                      typename std::decay<T>::type>::value_type>::value ||
+       std::is_same<wchar_t,
+                    typename std::iterator_traits<
+                      typename std::decay<T>::type>::value_type>::value),
+    void>>
+  : bool_constant<
+      std::is_same<char,
+                   typename std::iterator_traits<
+                     typename std::decay<T>::type>::value_type>::value ||
+      std::is_same<wchar_t,
+                   typename std::iterator_traits<
+                     typename std::decay<T>::type>::value_type>::value>
+{
+};
+
+#  if defined(__SUNPRO_CC) && defined(__sparc)
+// Oracle DeveloperStudio C++ compiler on Solaris/Sparc fails to compile
+// the full 'is_pathable' check.  We use it only to improve error messages
+// via 'enable_if' when calling methods with incorrect types.  Just
+// pretend all types are allowed so we can at least compile valid code.
+template <typename T>
+struct is_pathable : std::true_type
+{
+};
+#  else
+template <typename T>
+struct is_pathable
+  : bool_constant<is_pathable_string<T>::value ||
+                  is_pathable_char_array<T>::value ||
+                  is_pathable_iterator<T>::value>
+{
+};
+#  endif
+}
+
+class path
+{
+  using path_type = std::string;
+
+  template <typename Source>
+  using enable_if_pathable =
+    enable_if_t<internals::is_pathable<Source>::value, path&>;
+
+  enum class filename_fragment : unsigned char
+  {
+    stem,
+    extension
+  };
+
+public:
+#  if defined(_WIN32) && !defined(__CYGWIN__)
+  using value_type = wchar_t;
+#  else
+  using value_type = char;
+#  endif
+  using string_type = std::basic_string<value_type>;
+
+  class iterator;
+  using const_iterator = iterator;
+
+  enum format : unsigned char
+  {
+    auto_format,
+    native_format,
+    generic_format
+  };
+
+#  if defined(_WIN32) && !defined(__CYGWIN__)
+  static constexpr value_type preferred_separator = L'\\';
+#  else
+  static constexpr value_type preferred_separator = '/';
+#  endif
+
+  // Constructors
+  // ============
+  path() noexcept {}
+  path(const path& p)
+    : path_(p.path_)
+  {
+  }
+  path(path&& p) noexcept
+    : path_(std::move(p.path_))
+  {
+  }
+  path(string_type&& source, format fmt = auto_format)
+  {
+    (void)fmt;
+    internals::source_converter<value_type, path_type::value_type>::set_source(
+      this->path_, std::move(source));
+  }
+  template <typename Source, typename = enable_if_pathable<Source>>
+  path(const Source& source, format fmt = auto_format)
+  {
+    (void)fmt;
+    internals::source_converter<
+      typename internals::source_traits<Source>::value_type,
+      path_type::value_type>::append_source(this->path_, source);
+  }
+  template <typename Iterator, typename = enable_if_pathable<Iterator>>
+  path(const Iterator first, Iterator last, format fmt = auto_format)
+  {
+    (void)fmt;
+    internals::source_converter<
+      typename std::iterator_traits<Iterator>::value_type,
+      path_type::value_type>::append_range(this->path_, first, last);
+  }
+
+  ~path() = default;
+
+  // Assignments
+  // ===========
+  path& operator=(const path& p)
+  {
+    if (this != &p) {
+      this->path_ = p.path_;
+    }
+    return *this;
+  }
+  path& operator=(path&& p) noexcept
+  {
+    if (this != &p) {
+      this->path_ = std::move(p.path_);
+    }
+    return *this;
+  }
+  path& operator=(string_type&& source) { return this->assign(source); }
+  template <typename Source, typename = enable_if_pathable<Source>>
+  path& operator=(const Source& source)
+  {
+    return this->assign(source);
+  }
+
+  path& assign(string_type&& source)
+  {
+    internals::source_converter<value_type, path_type::value_type>::set_source(
+      this->path_, std::move(source));
+    return *this;
+  }
+  template <typename Source, typename = enable_if_pathable<Source>>
+  path& assign(const Source& source)
+  {
+    this->path_.clear();
+    internals::source_converter<
+      typename internals::source_traits<Source>::value_type,
+      path_type::value_type>::append_source(this->path_, source);
+    return *this;
+  }
+  template <typename Iterator, typename = enable_if_pathable<Iterator>>
+  path& assign(Iterator first, Iterator last)
+  {
+    this->path_.clear();
+    internals::source_converter<
+      typename std::iterator_traits<Iterator>::value_type,
+      path_type::value_type>::append_range(this->path_, first, last);
+    return *this;
+  }
+
+  // Concatenation
+  // =============
+  path& operator/=(const path& p);
+
+  template <typename Source, typename = enable_if_pathable<Source>>
+  path& append(const Source& source)
+  {
+    return this->operator/=(path(source));
+  }
+  template <typename Source>
+  path& operator/=(const Source& source)
+  {
+    return this->append(source);
+  }
+
+  template <typename Iterator, typename = enable_if_pathable<Iterator>>
+  path& append(Iterator first, Iterator last)
+  {
+    return this->operator/=(path(first, last));
+  }
+
+  path& operator+=(const path& p)
+  {
+    this->path_ += p.path_;
+    return *this;
+  }
+  path& operator+=(const string_type& str)
+  {
+    this->path_ +=
+      internals::string_converter<value_type>::to<path_type::value_type>(str);
+    return *this;
+  }
+  path& operator+=(cm::string_view str)
+  {
+    this->path_.append(str.begin(), str.end());
+    return *this;
+  }
+  path& operator+=(const value_type* str)
+  {
+    this->path_ +=
+      internals::string_converter<value_type>::to<path_type::value_type>(str);
+    return *this;
+  }
+  path& operator+=(const value_type c)
+  {
+    this->path_ +=
+      internals::string_converter<value_type>::to<path_type::value_type>(c);
+    return *this;
+  }
+  template <typename Source, typename = enable_if_pathable<Source>>
+  path& concat(const Source& source)
+  {
+    internals::source_converter<
+      typename internals::source_traits<Source>::value_type,
+      path_type::value_type>::append_source(this->path_, source);
+    return *this;
+  }
+  template <typename Source>
+  path& operator+=(const Source& source)
+  {
+    return this->concat(source);
+  }
+  template <typename Iterator, typename = enable_if_pathable<Iterator>>
+  path& concat(Iterator first, Iterator last)
+  {
+    internals::source_converter<
+      typename std::iterator_traits<Iterator>::value_type,
+      path_type::value_type>::append_range(this->path_, first, last);
+    return *this;
+  }
+
+  // Modifiers
+  // =========
+  void clear() noexcept { this->path_.clear(); }
+
+  path& make_preferred()
+  {
+#  if defined(_WIN32) && !defined(__CYGWIN__)
+    std::replace(
+      this->path_.begin(), this->path_.end(), '/',
+      static_cast<path_type::value_type>(this->preferred_separator));
+#  endif
+    return *this;
+  }
+
+  path& remove_filename()
+  {
+    auto fname = this->get_filename();
+    if (!fname.empty()) {
+      this->path_.erase(fname.data() - this->path_.data());
+    }
+    return *this;
+  }
+
+  path& replace_filename(const path& replacement)
+  {
+    this->remove_filename();
+    this->operator/=(replacement);
+    return *this;
+  }
+
+  path& replace_extension(const path& replacement = path())
+  {
+    auto ext = this->get_filename_fragment(filename_fragment::extension);
+    if (!ext.empty()) {
+      this->path_.erase(ext.data() - this->path_.data());
+    }
+    if (!replacement.path_.empty()) {
+      if (replacement.path_[0] != '.') {
+        this->path_ += '.';
+      }
+      this->path_.append(replacement.path_);
+    }
+    return *this;
+  }
+
+  void swap(path& other) noexcept { this->path_.swap(other.path_); }
+
+  // Format observers
+  // ================
+  const string_type& native() const noexcept
+  {
+#  if defined(_WIN32) && !defined(__CYGWIN__)
+    this->native_path_ = internals::string_converter<
+      path_type::value_type>::to<string_type::value_type>(this->path_);
+    return this->native_path_;
+#  else
+    return this->path_;
+#  endif
+  }
+  const value_type* c_str() const noexcept { return this->native().c_str(); }
+  operator string_type() const { return this->native(); }
+
+  template <
+    typename Char, typename Traits = std::char_traits<Char>,
+    typename Alloc = std::allocator<Char>,
+    cm::enable_if_t<(std::is_same<Char, char>::value &&
+                     std::is_same<Traits, std::char_traits<char>>::value) ||
+                      (std::is_same<Char, wchar_t>::value &&
+                       std::is_same<Traits, std::char_traits<wchar_t>>::value),
+                    int> = 1>
+  std::basic_string<Char, Traits, Alloc> string(const Alloc& a = Alloc()) const
+  {
+    return internals::string_converter<path_type::value_type>::to<Char, Traits,
+                                                                  Alloc>(
+      this->path_, a);
+  }
+  const std::string string() const { return this->path_; }
+  std::wstring wstring() const
+  {
+    std::string out = this->string();
+    return internals::string_converter<path_type::value_type>::to<
+      std::wstring::value_type>(out);
+  }
+
+  template <
+    typename Char, typename Traits = std::char_traits<Char>,
+    typename Alloc = std::allocator<Char>,
+    cm::enable_if_t<(std::is_same<Char, char>::value &&
+                     std::is_same<Traits, std::char_traits<char>>::value) ||
+                      (std::is_same<Char, wchar_t>::value &&
+                       std::is_same<Traits, std::char_traits<wchar_t>>::value),
+                    int> = 1>
+  std::basic_string<Char, Traits, Alloc> generic_string(
+    const Alloc& a = Alloc()) const
+  {
+    return internals::string_converter<path_type::value_type>::to<Char, Traits,
+                                                                  Alloc>(
+      this->get_generic(), a);
+  }
+  std::string generic_string() const { return this->get_generic(); }
+  std::wstring generic_wstring() const
+  {
+    auto dest = this->generic_string();
+    return internals::string_converter<path_type::value_type>::to<
+      std::wstring::value_type>(dest);
+  }
+
+  // Compare
+  // =======
+  int compare(const path& p) const noexcept
+  {
+    return this->compare_path(p.path_);
+  }
+  int compare(const string_type& str) const
+  {
+    return this->compare_path(
+      internals::string_converter<value_type>::to<path_type::value_type>(str));
+  }
+  int compare(const value_type* str) const
+  {
+    return this->compare_path(
+      internals::string_converter<value_type>::to<path_type::value_type>(str));
+  }
+  int compare(cm::string_view str) const { return this->compare_path(str); }
+
+  // Generation
+  // ==========
+  path lexically_normal() const;
+
+  path lexically_relative(const path& base) const;
+
+  path lexically_proximate(const path& base) const
+  {
+    path result = this->lexically_relative(base);
+    return result.empty() ? *this : result;
+  }
+
+  // Decomposition
+  // =============
+  path root_name() const { return get_root_name(); }
+
+  path root_directory() const { return this->get_root_directory(); }
+
+  path root_path() const
+  {
+    return this->root_name().append(this->get_root_directory());
+  }
+
+  path relative_path() const { return this->get_relative_path(); }
+
+  path parent_path() const { return this->get_parent_path(); }
+
+  path filename() const { return this->get_filename(); }
+
+  path stem() const
+  {
+    return this->get_filename_fragment(filename_fragment::stem);
+  }
+  path extension() const
+  {
+    return this->get_filename_fragment(filename_fragment::extension);
+  }
+
+  // Queries
+  // =======
+  bool empty() const noexcept { return this->path_.empty(); }
+
+  bool has_root_name() const { return !this->get_root_name().empty(); }
+
+  bool has_root_directory() const
+  {
+    return !this->get_root_directory().empty();
+  }
+
+  bool has_root_path() const
+  {
+    return this->has_root_name() || this->has_root_directory();
+  }
+
+  bool has_relative_path() const { return !this->get_relative_path().empty(); }
+
+  bool has_parent_path() const { return !this->get_parent_path().empty(); }
+
+  bool has_filename() const { return !this->get_filename().empty(); }
+
+  bool has_stem() const
+  {
+    return !this->get_filename_fragment(filename_fragment::stem).empty();
+  }
+  bool has_extension() const
+  {
+    return !this->get_filename_fragment(filename_fragment::extension).empty();
+  }
+
+  bool is_absolute() const
+  {
+#  if defined(_WIN32) && !defined(__CYGWIN__)
+    return this->has_root_name() && this->has_root_directory();
+#  else
+    // For CYGWIN, root_name (i.e. //host or /cygdrive/x) is not considered.
+    // Same as current GNU g++ implementation (9.3).
+    return this->has_root_directory();
+#  endif
+  }
+
+  bool is_relative() const { return !this->is_absolute(); }
+
+  // Iterators
+  // =========
+  inline iterator begin() const;
+  inline iterator end() const;
+
+  // Non-members
+  // ===========
+  friend inline bool operator==(const path& lhs, const path& rhs) noexcept
+  {
+    return lhs.compare(rhs) == 0;
+  }
+  friend inline bool operator!=(const path& lhs, const path& rhs) noexcept
+  {
+    return lhs.compare(rhs) != 0;
+  }
+  friend inline bool operator<(const path& lhs, const path& rhs) noexcept
+  {
+    return lhs.compare(rhs) < 0;
+  }
+  friend inline bool operator<=(const path& lhs, const path& rhs) noexcept
+  {
+    return lhs.compare(rhs) <= 0;
+  }
+  friend inline bool operator>(const path& lhs, const path& rhs) noexcept
+  {
+    return lhs.compare(rhs) > 0;
+  }
+  friend inline bool operator>=(const path& lhs, const path& rhs) noexcept
+  {
+    return lhs.compare(rhs) >= 0;
+  }
+
+  friend inline path operator/(const path& lhs, const path& rhs)
+  {
+    path result(lhs);
+    result /= rhs;
+
+    return result;
+  }
+
+  template <typename Char, typename Traits>
+  friend inline cm::enable_if_t<
+    (std::is_same<Char, path::value_type>::value &&
+     std::is_same<Traits, std::char_traits<path::value_type>>::value) ||
+      (std::is_same<Char, path::path_type::value_type>::value &&
+       std::is_same<Traits,
+                    std::char_traits<path::path_type::value_type>>::value),
+    std::basic_ostream<Char, Traits>&>
+  operator<<(std::basic_ostream<Char, Traits>& os, const path& p)
+  {
+    os << cm::quoted(p.string<Char, Traits>());
+    return os;
+  }
+
+  template <typename Char, typename Traits>
+  friend inline cm::enable_if_t<
+    (std::is_same<Char, path::value_type>::value &&
+     std::is_same<Traits, std::char_traits<path::value_type>>::value) ||
+      (std::is_same<Char, path::path_type::value_type>::value &&
+       std::is_same<Traits,
+                    std::char_traits<path::path_type::value_type>>::value),
+    std::basic_istream<Char, Traits>&>
+  operator>>(std::basic_istream<Char, Traits>& is, path& p)
+  {
+    std::basic_string<Char, Traits> tmp;
+    is >> cm::quoted(tmp);
+    p = tmp;
+    return is;
+  }
+
+private:
+  friend class iterator;
+  friend std::size_t hash_value(const path& p) noexcept;
+
+  path_type get_generic() const;
+
+  cm::string_view get_root_name() const;
+  cm::string_view get_root_directory() const;
+  cm::string_view get_relative_path() const;
+  cm::string_view get_parent_path() const;
+  cm::string_view get_filename() const;
+  cm::string_view get_filename_fragment(filename_fragment fragment) const;
+
+  int compare_path(cm::string_view str) const;
+
+  path_type path_;
+#  if defined(_WIN32) && !defined(__CYGWIN__)
+  mutable string_type native_path_;
+#  endif
+};
+
+class path::iterator
+{
+public:
+  using iterator_category = std::bidirectional_iterator_tag;
+
+  using value_type = path;
+  using difference_type = std::ptrdiff_t;
+  using pointer = const path*;
+  using reference = const path&;
+
+  iterator();
+  iterator(const iterator& other);
+
+  ~iterator();
+
+  iterator& operator=(const iterator& other);
+
+  reference operator*() const { return this->path_element_; }
+
+  pointer operator->() const { return &this->path_element_; }
+
+  iterator& operator++();
+
+  iterator operator++(int)
+  {
+    iterator it(*this);
+    this->operator++();
+    return it;
+  }
+
+  iterator& operator--();
+
+  iterator operator--(int)
+  {
+    iterator it(*this);
+    this->operator--();
+    return it;
+  }
+
+private:
+  friend class path;
+  friend bool operator==(const iterator&, const iterator&);
+
+  iterator(const path* p, bool at_end = false);
+
+  const path* path_;
+  std::unique_ptr<internals::path_parser> parser_;
+  path path_element_;
+};
+
+inline path::iterator path::begin() const
+{
+  return iterator(this);
+}
+inline path::iterator path::end() const
+{
+  return iterator(this, true);
+}
+
+bool operator==(const path::iterator& lhs, const path::iterator& rhs);
+
+inline bool operator!=(const path::iterator& lhs, const path::iterator& rhs)
+{
+  return !(lhs == rhs);
+}
+
+// Non-member functions
+// ====================
+inline void swap(path& lhs, path& rhs) noexcept
+{
+  lhs.swap(rhs);
+}
+
+std::size_t hash_value(const path& p) noexcept;
+
+#endif
+
+} // namespace filesystem
+} // namespace cm
+
+#endif
diff --git a/Utilities/std/cm/iomanip b/Utilities/std/cm/iomanip
new file mode 100644
index 0000000..6f68530
--- /dev/null
+++ b/Utilities/std/cm/iomanip
@@ -0,0 +1,183 @@
+// -*-c++-*-
+// vim: set ft=cpp:
+
+/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
+   file Copyright.txt or https://cmake.org/licensing for details.  */
+#ifndef cm_iomanip
+#define cm_iomanip
+
+#include <iomanip> // IWYU pragma: export
+#if __cplusplus < 201402L || defined(_MSVC_LANG) && _MSVC_LANG < 201402L
+#  include <ios>
+#  include <iostream>
+#  include <sstream>
+#  include <string>
+#  include <type_traits>
+#endif
+#if __cplusplus < 201703L || defined(_MSVC_LANG) && _MSVC_LANG < 201703L
+#  include <cm/string_view>
+#endif
+
+namespace cm {
+
+#if __cplusplus >= 201402L || defined(_MSVC_LANG) && _MSVC_LANG >= 201402L
+
+using std::quoted;
+
+#  if __cplusplus < 201703L || defined(_MSVC_LANG) && _MSVC_LANG < 201703L
+
+inline auto quoted(cm::string_view str, char delim = '"', char escape = '\\')
+{
+  return std::quoted(static_cast<std::string>(str), delim, escape);
+}
+
+#  endif
+
+#else
+
+namespace internals {
+
+// Struct for delimited strings.
+template <typename String, typename Char>
+struct quoted_string
+{
+  static_assert(std::is_reference<String>::value ||
+                  std::is_pointer<String>::value,
+                "String type must be pointer or reference");
+
+  quoted_string(String str, Char del, Char esc)
+    : string_(str)
+    , delim_{ del }
+    , escape_{ esc }
+  {
+  }
+
+  quoted_string& operator=(quoted_string&) = delete;
+
+  String string_;
+  Char delim_;
+  Char escape_;
+};
+
+template <>
+struct quoted_string<cm::string_view, char>
+{
+  quoted_string(cm::string_view str, char del, char esc)
+    : string_(str)
+    , delim_{ del }
+    , escape_{ esc }
+  {
+  }
+
+  quoted_string& operator=(quoted_string&) = delete;
+
+  cm::string_view string_;
+  char delim_;
+  char escape_;
+};
+
+template <typename Char, typename Traits>
+std::basic_ostream<Char, Traits>& operator<<(
+  std::basic_ostream<Char, Traits>& os,
+  const quoted_string<const Char*, Char>& str)
+{
+  std::basic_ostringstream<Char, Traits> ostr;
+  ostr << str.delim_;
+  for (const Char* c = str.string_; *c; ++c) {
+    if (*c == str.delim_ || *c == str.escape_)
+      ostr << str.escape_;
+    ostr << *c;
+  }
+  ostr << str.delim_;
+
+  return os << ostr.str();
+}
+
+template <typename Char, typename Traits, typename String>
+std::basic_ostream<Char, Traits>& operator<<(
+  std::basic_ostream<Char, Traits>& os, const quoted_string<String, Char>& str)
+{
+  std::basic_ostringstream<Char, Traits> ostr;
+  ostr << str.delim_;
+  for (auto c : str.string_) {
+    if (c == str.delim_ || c == str.escape_)
+      ostr << str.escape_;
+    ostr << c;
+  }
+  ostr << str.delim_;
+
+  return os << ostr.str();
+}
+
+template <typename Char, typename Traits, typename Alloc>
+std::basic_istream<Char, Traits>& operator>>(
+  std::basic_istream<Char, Traits>& is,
+  const quoted_string<std::basic_string<Char, Traits, Alloc>&, Char>& str)
+{
+  Char c;
+  is >> c;
+  if (!is.good())
+    return is;
+  if (c != str.delim_) {
+    is.unget();
+    is >> str.string_;
+    return is;
+  }
+  str.string_.clear();
+  std::ios_base::fmtflags flags =
+    is.flags(is.flags() & ~std::ios_base::skipws);
+  do {
+    is >> c;
+    if (!is.good())
+      break;
+    if (c == str.escape_) {
+      is >> c;
+      if (!is.good())
+        break;
+    } else if (c == str.delim_)
+      break;
+    str.string_ += c;
+  } while (true);
+  is.setf(flags);
+
+  return is;
+}
+}
+
+template <typename Char>
+inline internals::quoted_string<const Char*, Char> quoted(
+  const Char* str, Char delim = Char('"'), Char escape = Char('\\'))
+{
+  return internals::quoted_string<const Char*, Char>(str, delim, escape);
+}
+
+template <typename Char, typename Traits, typename Alloc>
+inline internals::quoted_string<const std::basic_string<Char, Traits, Alloc>&,
+                                Char>
+quoted(const std::basic_string<Char, Traits, Alloc>& str,
+       Char delim = Char('"'), Char escape = Char('\\'))
+{
+  return internals::quoted_string<
+    const std::basic_string<Char, Traits, Alloc>&, Char>(str, delim, escape);
+}
+
+template <typename Char, typename Traits, typename Alloc>
+inline internals::quoted_string<std::basic_string<Char, Traits, Alloc>&, Char>
+quoted(std::basic_string<Char, Traits, Alloc>& str, Char delim = Char('"'),
+       Char escape = Char('\\'))
+{
+  return internals::quoted_string<std::basic_string<Char, Traits, Alloc>&,
+                                  Char>(str, delim, escape);
+}
+
+inline internals::quoted_string<cm::string_view, char> quoted(
+  cm::string_view str, char delim = '"', char escape = '\\')
+{
+  return internals::quoted_string<cm::string_view, char>(str, delim, escape);
+}
+
+#endif
+
+} // namespace cm
+
+#endif
diff --git a/Utilities/std/cm/memory b/Utilities/std/cm/memory
index dd0f822..5611f6b 100644
--- a/Utilities/std/cm/memory
+++ b/Utilities/std/cm/memory
@@ -6,7 +6,10 @@
 #ifndef cm_memory
 #define cm_memory
 
+#include "cmSTL.hxx" // IWYU pragma: keep
+
 #include <memory> // IWYU pragma: export
+
 #if !defined(CMake_HAVE_CXX_MAKE_UNIQUE)
 #  include <cstddef>
 #  include <type_traits>
diff --git a/Utilities/std/cm/shared_mutex b/Utilities/std/cm/shared_mutex
index 2ac9447..ec63a7b 100644
--- a/Utilities/std/cm/shared_mutex
+++ b/Utilities/std/cm/shared_mutex
@@ -17,7 +17,7 @@
 #  include <shared_mutex> // IWYU pragma: export
 #endif
 #if !defined(CMake_HAVE_CXX_SHARED_MUTEX)
-#  include "cm_uv.h"
+#  include <cm3p/uv.h>
 #endif
 
 namespace cm {
diff --git a/Utilities/std/cmSTL.hxx.in b/Utilities/std/cmSTL.hxx.in
new file mode 100644
index 0000000..9c8605c
--- /dev/null
+++ b/Utilities/std/cmSTL.hxx.in
@@ -0,0 +1,10 @@
+/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
+   file Copyright.txt or https://cmake.org/licensing for details.  */
+#ifndef cmSTL_hxx
+#define cmSTL_hxx
+
+/* Whether CMake is using its own STL implementation.  */
+#cmakedefine CMake_HAVE_CXX_MAKE_UNIQUE
+#cmakedefine CMake_HAVE_CXX_FILESYSTEM
+
+#endif
diff --git a/Utilities/std/cmext/algorithm b/Utilities/std/cmext/algorithm
index 44e61f4..251c89a 100644
--- a/Utilities/std/cmext/algorithm
+++ b/Utilities/std/cmext/algorithm
@@ -13,12 +13,11 @@
 
 #include <cm/type_traits>
 #include <cmext/iterator>
+#include <cmext/type_traits>
 
 #if defined(__SUNPRO_CC) && defined(__sparc)
 #  include <list>
 #  include <vector>
-#else
-#  include <cmext/type_traits>
 #endif
 
 namespace cm {
@@ -158,6 +157,95 @@
 #  endif
 #endif
 
+#if defined(__SUNPRO_CC)
+template <typename Iterator, typename Key>
+auto contains(Iterator first, Iterator last, Key const& key,
+              detail::overload_selector<1>) -> decltype(first->first == key)
+#else
+template <typename Iterator, typename Key,
+          cm::enable_if_t<
+            cm::is_input_iterator<Iterator>::value &&
+              std::is_convertible<Key,
+                                  typename std::iterator_traits<
+                                    Iterator>::value_type::first_type>::value,
+            int> = 0>
+bool contains(Iterator first, Iterator last, Key const& key)
+#endif
+{
+  return std::find_if(
+           first, last,
+           [&key](
+             typename std::iterator_traits<Iterator>::value_type const& item) {
+             return item.first == key;
+           }) != last;
+}
+
+#if defined(__SUNPRO_CC)
+template <typename Iterator, typename Key>
+bool contains(Iterator first, Iterator last, Key const& key,
+              detail::overload_selector<0>)
+#else
+template <
+  typename Iterator, typename Key,
+  cm::enable_if_t<
+    cm::is_input_iterator<Iterator>::value &&
+      std::is_convertible<
+        Key, typename std::iterator_traits<Iterator>::value_type>::value,
+    int> = 0>
+bool contains(Iterator first, Iterator last, Key const& key)
+#endif
+{
+  return std::find(first, last, key) != last;
+}
+
+#if defined(__SUNPRO_CC)
+template <typename Iterator, typename Key>
+bool contains(Iterator first, Iterator last, Key const& key)
+{
+  return contains(first, last, key, detail::overload_selector<1>{});
+}
+#endif
+
+#if defined(__SUNPRO_CC)
+template <typename Range, typename Key>
+auto contains(Range const& range, Key const& key, detail::overload_selector<1>)
+  -> decltype(range.find(key) != range.end())
+#else
+template <
+  typename Range, typename Key,
+  cm::enable_if_t<cm::is_associative_container<Range>::value ||
+                    cm::is_unordered_associative_container<Range>::value,
+                  int> = 0>
+bool contains(Range const& range, Key const& key)
+#endif
+{
+  return range.find(key) != range.end();
+}
+
+#if defined(__SUNPRO_CC)
+template <typename Range, typename Key>
+bool contains(Range const& range, Key const& key, detail::overload_selector<0>)
+#else
+template <
+  typename Range, typename Key,
+  cm::enable_if_t<cm::is_input_range<Range>::value &&
+                    !(cm::is_associative_container<Range>::value ||
+                      cm::is_unordered_associative_container<Range>::value),
+                  int> = 0>
+bool contains(Range const& range, Key const& key)
+#endif
+{
+  return std::find(std::begin(range), std::end(range), key) != std::end(range);
+}
+
+#if defined(__SUNPRO_CC)
+template <typename Range, typename Key>
+bool contains(Range const& range, Key const& key)
+{
+  return contains(range, key, detail::overload_selector<1>{});
+}
+#endif
+
 } // namespace cm
 
 #endif
diff --git a/Utilities/std/cmext/iterator b/Utilities/std/cmext/iterator
index ffe94b1..ce9462f 100644
--- a/Utilities/std/cmext/iterator
+++ b/Utilities/std/cmext/iterator
@@ -23,25 +23,27 @@
   std::is_base_of<std::input_iterator_tag,
                   typename std::iterator_traits<I>::iterator_category>;
 
-// checks if a type is a range type: must have a difference_type type
+// checks if a type is a range type: std::begin() and std::end() are supported
 template <typename Range>
 using is_range = cm::bool_constant<
-  cm::is_iterator<decltype(std::declval<const Range>().begin())>::value &&
-  cm::is_iterator<decltype(std::declval<const Range>().end())>::value>;
+  cm::is_iterator<decltype(std::begin(std::declval<const Range>()))>::value &&
+  cm::is_iterator<decltype(std::end(std::declval<const Range>()))>::value>;
 
-// checks if a type is an input range type: must have methods begin() and end()
+// checks if a type is an input range type: std::begin() and std::end() are
 // returning an input iterator
 template <typename Range>
 using is_input_range =
 #if defined(_MSC_VER) && _MSC_VER < 1920
   // MS C++ is not able to evaluate complex type introspection,
   // so use a simplified version
-  cm::is_input_iterator<typename Range::const_iterator>;
+  cm::bool_constant<std::is_class<Range>::value ||
+                    std::is_pointer<Range>::value ||
+                    std::is_array<Range>::value>;
 #else
-  cm::bool_constant<
-    cm::is_input_iterator<decltype(
-      std::declval<const Range>().begin())>::value &&
-    cm::is_input_iterator<decltype(std::declval<const Range>().end())>::value>;
+  cm::bool_constant<cm::is_input_iterator<decltype(
+                      std::begin(std::declval<const Range>()))>::value &&
+                    cm::is_input_iterator<decltype(
+                      std::end(std::declval<const Range>()))>::value>;
 #endif
 
 } // namespace cm
diff --git a/Utilities/std/cmext/memory b/Utilities/std/cmext/memory
index 50e79df..fa326f0 100644
--- a/Utilities/std/cmext/memory
+++ b/Utilities/std/cmext/memory
@@ -12,18 +12,19 @@
 
 namespace cm {
 
-template <typename T, typename O,
-          cm::enable_if_t<
-            std::is_pointer<cm::invoke_result_t<decltype(&O::get), O>>::value,
-            int> = 0>
+template <
+  typename T, typename O,
+  cm::enable_if_t<std::is_pointer<decltype(std::declval<O>().get())>::value,
+                  int> = 0>
 T& static_reference_cast(O& item)
 {
   return *(static_cast<T*>(item.get()));
 }
-template <typename T, typename O,
-          cm::enable_if_t<
-            std::is_pointer<cm::invoke_result_t<decltype(&O::get), O>>::value,
-            int> = 0>
+
+template <
+  typename T, typename O,
+  cm::enable_if_t<std::is_pointer<decltype(std::declval<O>().get())>::value,
+                  int> = 0>
 T& dynamic_reference_cast(O& item)
 {
   auto p = dynamic_cast<T*>(item.get());
diff --git a/Utilities/std/cmext/string_view b/Utilities/std/cmext/string_view
new file mode 100644
index 0000000..ad52b11
--- /dev/null
+++ b/Utilities/std/cmext/string_view
@@ -0,0 +1,42 @@
+// -*-c++-*-
+// vim: set ft=cpp:
+
+/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
+   file Copyright.txt or https://cmake.org/licensing for details.  */
+#ifndef cmext_string_view
+#define cmext_string_view
+
+#include <cstddef>
+
+#include <cm/string_view>
+
+namespace cm {
+
+/** A string_view that only binds to static storage.
+ *
+ * This is used together with the `""_s` user-defined literal operator
+ * to construct a type-safe abstraction of a string_view that only views
+ * statically allocated strings.  These strings are const and available
+ * for the entire lifetime of the program.
+ */
+class static_string_view : public string_view
+{
+  static_string_view(string_view v)
+    : string_view(v)
+  {
+  }
+
+  friend static_string_view operator"" _s(const char* data, size_t size);
+};
+
+/** Create a static_string_view using `""_s` literal syntax.  */
+inline static_string_view operator"" _s(const char* data, size_t size)
+{
+  return string_view(data, size);
+}
+
+} // namespace cm
+
+using cm::operator"" _s;
+
+#endif
diff --git a/Utilities/std/cmext/type_traits b/Utilities/std/cmext/type_traits
index 00984cb..f02b488 100644
--- a/Utilities/std/cmext/type_traits
+++ b/Utilities/std/cmext/type_traits
@@ -6,6 +6,8 @@
 #ifndef cmext_type_traits
 #define cmext_type_traits
 
+#include <memory>
+
 #include <cm/type_traits>
 
 namespace cm {
diff --git a/bootstrap b/bootstrap
index 6964683..2ef0fbb 100755
--- a/bootstrap
+++ b/bootstrap
@@ -9,15 +9,23 @@
 # Compile flag extraction function.
 cmake_extract_standard_flags()
 {
-  sed -n "s/ *set *( *CMAKE_${2}${3}_EXTENSION_COMPILE_OPTION *\"\{0,1\}\([^\")]*\).*/\1/p" \
-    "${cmake_source_dir}/Modules/Compiler/"${1:-*}-${2}.cmake 2>/dev/null | tr ';' ' '
+  id="${1:-*}"
+  lang="${2}"
+  ver="${3}"
+  sed -n "s/ *set *( *CMAKE_${lang}${ver}_EXTENSION_COMPILE_OPTION *\"\{0,1\}\([^\")]*\).*/\1/p" \
+    "${cmake_source_dir}/Modules/Compiler/"${id}-${lang}.cmake \
+    2>/dev/null | tr ';' ' '
+  # Clang's CXX compiler flags are in the common module.
+  sed -n "s/ *set *( *CMAKE_\\\${lang}${ver}_EXTENSION_COMPILE_OPTION *\"\{0,1\}\([^\")]*\).*/\1/p" \
+    "${cmake_source_dir}/Modules/Compiler/Clang.cmake" \
+    2>/dev/null | tr ';' ' '
 }
 
 # Version number extraction function.
 cmake_version_component()
 {
   sed -n "
-/^set(CMake_VERSION_${1}/ {s/set(CMake_VERSION_${1} *\([0-9]*\))/\1/;p;}
+/^set(CMake_VERSION_${1}/ {s/set(CMake_VERSION_${1} *\([0-9]*\)).*/\1/;p;}
 " "${cmake_source_dir}/Source/CMakeVersion.cmake"
 }
 
@@ -52,7 +60,7 @@
 cmake_version_patch="`cmake_version_component PATCH`"
 cmake_version="${cmake_version_major}.${cmake_version_minor}.${cmake_version_patch}"
 cmake_version_rc="`cmake_version_component RC`"
-if [ "$cmake_version_rc" != "" ]; then
+if test "$cmake_version_rc" != ""; then
   cmake_version="${cmake_version}-rc${cmake_version_rc}"
 fi
 
@@ -131,7 +139,7 @@
 if echo "${cmake_system}" | grep HP-UX >/dev/null 2>&1; then
   die 'CMake no longer compiles on HP-UX.  See
 
-  https://gitlab.kitware.com/cmake/cmake/issues/17137
+  https://gitlab.kitware.com/cmake/cmake/-/issues/17137
 
 Use CMake 3.9 or lower instead.'
   cmake_system_hpux=true
@@ -201,13 +209,13 @@
 
 # Choose the default install prefix.
 if ${cmake_system_mingw}; then
-  if [ "x${PROGRAMFILES}" != "x" ]; then
+  if test "x${PROGRAMFILES}" != "x"; then
     cmake_default_prefix=`cmake_fix_slashes "${PROGRAMFILES}/CMake"`
-  elif [ "x${ProgramFiles}" != "x" ]; then
+  elif test "x${ProgramFiles}" != "x"; then
     cmake_default_prefix=`cmake_fix_slashes "${ProgramFiles}/CMake"`
-  elif [ "x${SYSTEMDRIVE}" != "x" ]; then
+  elif test "x${SYSTEMDRIVE}" != "x"; then
     cmake_default_prefix=`cmake_fix_slashes "${SYSTEMDRIVE}/Program Files/CMake"`
-  elif [ "x${SystemDrive}" != "x" ]; then
+  elif test "x${SystemDrive}" != "x"; then
     cmake_default_prefix=`cmake_fix_slashes "${SystemDrive}/Program Files/CMake"`
   else
     cmake_default_prefix="c:/Program Files/CMake"
@@ -239,8 +247,12 @@
   */CMakeCXXCompiler.cmake \
   Source/cmConfigure.h \
   Source/CTest/Curl/config.h \
-  Utilities/cmexpat/expatConfig.h \
-  Utilities/cmexpat/expatDllConfig.h \
+  Utilities/cmThirdParty.h \
+  Utilities/cmcurl/lib/curl_config.h \
+  Utilities/cmlibarchive/config.h \
+  Utilities/cmliblzma/config.h \
+  Utilities/cmnghttp2/config.h \
+  Utilities/cmzlib/zlibDllConfig.h \
   "
 
 CMAKE_UNUSED_SOURCES="\
@@ -404,7 +416,6 @@
   cmProcessOutput \
   cmProjectCommand \
   cmPropertyDefinition \
-  cmPropertyDefinitionMap \
   cmPropertyMap \
   cmReturnCommand \
   cmRulePlaceholderExpander \
@@ -421,6 +432,7 @@
   cmSiteNameCommand \
   cmSourceFile \
   cmSourceFileLocation \
+  cmStandardLevelResolver \
   cmState \
   cmStateDirectory \
   cmStateSnapshot \
@@ -467,6 +479,7 @@
 fi
 
 CMAKE_STD_CXX_HEADERS="\
+  filesystem \
   memory \
   optional \
   shared_mutex \
@@ -474,6 +487,7 @@
   utility \
 "
 CMAKE_STD_CXX_SOURCES="\
+  fs_path \
   string_view \
 "
 
@@ -611,6 +625,8 @@
   --no-system-bzip2       use cmake-provided bzip2 library (default)
   --system-liblzma        use system-installed liblzma library
   --no-system-liblzma     use cmake-provided liblzma library (default)
+  --system-nghttp2        use system-installed nghttp2 library
+  --no-system-nghttp2     use cmake-provided nghttp2 library (default)
   --system-zstd           use system-installed zstd library
   --no-system-zstd        use cmake-provided zstd library (default)
   --system-libarchive     use system-installed libarchive library
@@ -620,6 +636,8 @@
   --system-libuv          use system-installed libuv library
   --no-system-libuv       use cmake-provided libuv library (default)
 
+  --bootstrap-system-libuv use system-installed libuv library for bootstrap
+
   --qt-gui                build the Qt-based GUI (requires Qt >= 4.2)
   --no-qt-gui             do not build the Qt-based GUI (default)
   --qt-qmake=<qmake>      use <qmake> as the qmake executable to find Qt
@@ -663,7 +681,7 @@
   echo "Error when bootstrapping CMake:"
   echo "$*"
   echo "---------------------------------------------"
-  if [ -f cmake_bootstrap.log ]; then
+  if test -f cmake_bootstrap.log; then
     echo "Log of errors: `pwd`/cmake_bootstrap.log"
     #cat cmake_bootstrap.log
     echo "---------------------------------------------"
@@ -690,9 +708,9 @@
   OUTFILE="$2"
   SEARCHFOR="$3"
   REPLACEWITH="$4"
-  if [ -f "${INFILE}" ] || ${cmake_system_openvms}; then
+  if test -f "${INFILE}" || ${cmake_system_openvms}; then
     sed "s/\@${SEARCHFOR}\@/${REPLACEWITH}/g" "${INFILE}" > "${OUTFILE}${_tmp}"
-    if [ -f "${OUTFILE}${_tmp}" ]; then
+    if test -f "${OUTFILE}${_tmp}"; then
       if "${_diff}" "${OUTFILE}" "${OUTFILE}${_tmp}" > /dev/null 2> /dev/null ; then
         #echo "Files are the same"
         rm -f "${OUTFILE}${_tmp}"
@@ -711,7 +729,7 @@
   OUTFILE="$2"
   shift 2
   APPEND="$*"
-  if [ -f "${INFILE}" ] || ${cmake_system_openvms}; then
+  if test -f "${INFILE}" || ${cmake_system_openvms}; then
     echo "${APPEND}" > "${OUTFILE}${_tmp}"
     sed "/./ {s/\@KWSYS_NAMESPACE\@/cmsys/g;
               s/@KWSYS_BUILD_SHARED@/${KWSYS_BUILD_SHARED}/g;
@@ -722,7 +740,7 @@
               s/@KWSYS_CXX_HAS_EXT_STDIO_FILEBUF_H@/${KWSYS_CXX_HAS_EXT_STDIO_FILEBUF_H}/g;
               s/@KWSYS_SYSTEMTOOLS_USE_TRANSLATION_MAP@/${KWSYS_SYSTEMTOOLS_USE_TRANSLATION_MAP}/g;
              }" "${INFILE}" >> "${OUTFILE}${_tmp}"
-    if [ -f "${OUTFILE}${_tmp}" ]; then
+    if test -f "${OUTFILE}${_tmp}"; then
       if "${_diff}" "${OUTFILE}" "${OUTFILE}${_tmp}" > /dev/null 2> /dev/null ; then
         #echo "Files are the same"
         rm -f "${OUTFILE}${_tmp}"
@@ -779,7 +797,7 @@
   COMPILER=$1
   FLAGS=$2
   TESTFILE=$3
-  if [ ! -f "${TESTFILE}" ]; then
+  if test ! -f "${TESTFILE}"; then
     echo "Test file ${TESTFILE} missing. Please verify your CMake source tree."
     exit 4
   fi
@@ -791,18 +809,18 @@
   echo "------------------------------------------"
   "${COMPILER}" ${FLAGS} "${TESTFILE}" -o "${TMPFILE}"
   RES=$?
-  if [ "${RES}" -ne "0" ]; then
+  if test "${RES}" -ne "0"; then
     echo "Test failed to compile"
     return 1
   fi
-  if [ ! -f "${TMPFILE}" ] && [ ! -f "${TMPFILE}.exe" ]; then
+  if test ! -f "${TMPFILE}" && test ! -f "${TMPFILE}.exe"; then
     echo "Test failed to produce executable"
     return 2
   fi
   ./${TMPFILE}
   RES=$?
   rm -f "${TMPFILE}"
-  if [ "${RES}" -ne "0" ]; then
+  if test "${RES}" -ne "0"; then
     echo "Test produced non-zero return code"
     return 3
   fi
@@ -818,18 +836,18 @@
   echo "Try: ${MAKE_PROC}"
   "${MAKE_PROC}" ${MAKE_FLAGS}
   RES=$?
-  if [ "${RES}" -ne "0" ]; then
+  if test "${RES}" -ne "0"; then
     echo "${MAKE_PROC} does not work"
     return 1
   fi
-  if [ ! -f "test" ] && [ ! -f "test.exe" ]; then
+  if test ! -f "test" && test ! -f "test.exe"; then
     echo "${COMPILER} does not produce output"
     return 2
   fi
   ./test
   RES=$?
   rm -f "test"
-  if [ "${RES}" -ne "0" ]; then
+  if test "${RES}" -ne "0"; then
     echo "${MAKE_PROC} produces strange executable"
     return 3
   fi
@@ -842,6 +860,7 @@
 cmake_parallel_make=
 cmake_ccache_enabled=
 cmake_prefix_dir="${cmake_default_prefix}"
+bootstrap_system_libuv=
 while test $# != 0; do
   case "$1" in
   --prefix=*) dir=`cmake_arg "$1"`
@@ -855,12 +874,13 @@
   --init=*) cmake_init_file=`cmake_arg "$1"` ;;
   --system-libs) cmake_bootstrap_system_libs="${cmake_bootstrap_system_libs} -DCMAKE_USE_SYSTEM_LIBRARIES=1" ;;
   --no-system-libs) cmake_bootstrap_system_libs="${cmake_bootstrap_system_libs} -DCMAKE_USE_SYSTEM_LIBRARIES=0" ;;
-  --system-bzip2|--system-curl|--system-expat|--system-jsoncpp|--system-libarchive|--system-librhash|--system-zlib|--system-liblzma|--system-zstd|--system-libuv)
+  --system-bzip2|--system-curl|--system-expat|--system-jsoncpp|--system-libarchive|--system-librhash|--system-zlib|--system-liblzma|--system-nghttp2|--system-zstd|--system-libuv)
     lib=`cmake_arg "$1" "--system-"`
     cmake_bootstrap_system_libs="${cmake_bootstrap_system_libs} -DCMAKE_USE_SYSTEM_LIBRARY_`cmake_toupper $lib`=1" ;;
-  --no-system-bzip2|--no-system-curl|--no-system-expat|--no-system-jsoncpp|--no-system-libarchive|--no-system-librhash|--no-system-zlib|--no-system-liblzma|--no-system-zstd|--no-system-libuv)
+  --no-system-bzip2|--no-system-curl|--no-system-expat|--no-system-jsoncpp|--no-system-libarchive|--no-system-librhash|--no-system-zlib|--no-system-liblzma|--no-system-nghttp2|--no-system-zstd|--no-system-libuv)
     lib=`cmake_arg "$1" "--no-system-"`
     cmake_bootstrap_system_libs="${cmake_bootstrap_system_libs} -DCMAKE_USE_SYSTEM_LIBRARY_`cmake_toupper $lib`=0" ;;
+  --bootstrap-system-libuv) bootstrap_system_libuv="1" ;;
   --qt-gui) cmake_bootstrap_qt_gui="1" ;;
   --no-qt-gui) cmake_bootstrap_qt_gui="0" ;;
   --qt-qmake=*) cmake_bootstrap_qt_qmake=`cmake_arg "$1"` ;;
@@ -886,13 +906,13 @@
 done
 
 # If verbose, display some information about bootstrap
-if [ -n "${cmake_verbose}" ]; then
+if test -n "${cmake_verbose}"; then
   echo "---------------------------------------------"
   echo "Source directory: ${cmake_source_dir}"
   echo "Binary directory: ${cmake_binary_dir}"
   echo "Prefix directory: ${cmake_prefix_dir}"
   echo "System:           ${cmake_system}"
-  if [ "x${cmake_parallel_make}" != "x" ]; then
+  if test "x${cmake_parallel_make}" != "x"; then
     echo "Doing parallel make: ${cmake_parallel_make}"
   fi
   echo ""
@@ -904,18 +924,18 @@
 
 # Check for in-source build
 cmake_in_source_build=
-if [ -f "${cmake_binary_dir}/Source/cmake.cxx" -a \
-     -f "${cmake_binary_dir}/Source/cmake.h" ]; then
-  if [ -n "${cmake_verbose}" ]; then
+if test -f "${cmake_binary_dir}/Source/cmake.cxx" &&
+     test -f "${cmake_binary_dir}/Source/cmake.h"; then
+  if test -n "${cmake_verbose}"; then
     echo "Warning: This is an in-source build"
   fi
   cmake_in_source_build=TRUE
 fi
 
 # If this is not an in-source build, then Bootstrap stuff should not exist.
-if [ -z "${cmake_in_source_build}" ]; then
+if test -z "${cmake_in_source_build}"; then
   # Did somebody bootstrap in the source tree?
-  if [ -d "${cmake_source_dir}/Bootstrap${_cmk}" ]; then
+  if test -d "${cmake_source_dir}/Bootstrap${_cmk}"; then
     cmake_error 10 "Found directory \"${cmake_source_dir}/Bootstrap${_cmk}\".
 Looks like somebody did bootstrap CMake in the source tree, but now you are
 trying to do bootstrap in the binary tree. Please remove Bootstrap${_cmk}
@@ -923,7 +943,7 @@
   fi
   # Is there a cache in the source tree?
   for cmake_problematic_file in ${CMAKE_PROBLEMATIC_FILES}; do
-    if [ -f "${cmake_source_dir}/${cmake_problematic_file}" ]; then
+    if test -f "${cmake_source_dir}/${cmake_problematic_file}"; then
       cmake_error 10 "Found \"${cmake_source_dir}/${cmake_problematic_file}\".
 Looks like somebody tried to build CMake in the source tree, but now you are
 trying to do bootstrap in the binary tree. Please remove \"${cmake_problematic_file}\"
@@ -933,14 +953,14 @@
 fi
 
 # Make bootstrap directory
-[ -d "${cmake_bootstrap_dir}" ] || mkdir "${cmake_bootstrap_dir}"
-if [ ! -d "${cmake_bootstrap_dir}" ]; then
+test -d "${cmake_bootstrap_dir}" || mkdir "${cmake_bootstrap_dir}"
+if test ! -d "${cmake_bootstrap_dir}"; then
   cmake_error 3 "Cannot create directory ${cmake_bootstrap_dir} to bootstrap CMake."
 fi
 cd "${cmake_bootstrap_dir}"
 
-[ -d "cmsys" ] || mkdir "cmsys"
-if [ ! -d "cmsys" ]; then
+test -d "cmsys" || mkdir "cmsys"
+if test ! -d "cmsys"; then
   cmake_error 4 "Cannot create directory ${cmake_bootstrap_dir}/cmsys"
 fi
 
@@ -951,7 +971,7 @@
 
 # If building in-source, remove any cmConfigure.h that may
 # have been created by a previous run of the bootstrap cmake.
-if [ -n "${cmake_in_source_build}" ]; then
+if test -n "${cmake_in_source_build}"; then
   rm -f "${cmake_source_dir}/Source/cmConfigure.h"
 fi
 
@@ -1036,7 +1056,7 @@
   done
 }
 
-if [ -z "${CC}" -a -z "${CXX}" ]; then
+if test -z "${CC}" && test -z "${CXX}"; then
   cmake_toolchain_detect
 fi
 
@@ -1050,9 +1070,9 @@
 cmake_c_compiler=
 
 # If CC is set, use that for compiler, otherwise use list of known compilers
-if [ -n "${cmake_toolchain}" ]; then
+if test -n "${cmake_toolchain}"; then
   eval cmake_c_compilers="\${cmake_toolchain_${cmake_toolchain}_CC}"
-elif [ -n "${CC}" ]; then
+elif test -n "${CC}"; then
   cmake_c_compilers="${CC}"
 else
   cmake_c_compilers="${CMAKE_KNOWN_C_COMPILERS}"
@@ -1103,7 +1123,7 @@
 done
 rm -f "${TMPFILE}.c"
 
-if [ -z "${cmake_c_compiler}" ]; then
+if test -z "${cmake_c_compiler}"; then
   cmake_error 6 "Cannot find appropriate C compiler on this system.
 Please specify one using environment variable CC.
 See cmake_bootstrap.log for compilers attempted.
@@ -1118,9 +1138,9 @@
 # On Mac OSX, CC is the same as cc, so make sure not to try CC as c++ compiler.
 
 # If CC is set, use that for compiler, otherwise use list of known compilers
-if [ -n "${cmake_toolchain}" ]; then
+if test -n "${cmake_toolchain}"; then
   eval cmake_cxx_compilers="\${cmake_toolchain_${cmake_toolchain}_CXX}"
-elif [ -n "${CXX}" ]; then
+elif test -n "${CXX}"; then
   cmake_cxx_compilers="${CXX}"
 else
   cmake_cxx_compilers="${CMAKE_KNOWN_CXX_COMPILERS}"
@@ -1224,7 +1244,7 @@
 done
 rm -f "${TMPFILE}.cxx"
 
-if [ -z "${cmake_cxx_compiler}" ]; then
+if test -z "${cmake_cxx_compiler}"; then
 cmake_error 7 "Cannot find a C++ compiler that supports both C++11 and the specified C++ flags.
 Please specify one using environment variable CXX.
 The C++ flags are \"$cmake_cxx_flags\".
@@ -1236,7 +1256,7 @@
 #-----------------------------------------------------------------------------
 # Test CXX features
 
-cmake_cxx_features="make_unique"
+cmake_cxx_features="make_unique filesystem"
 
 for feature in ${cmake_cxx_features}; do
   eval "cmake_have_cxx_${feature}=0"
@@ -1251,11 +1271,14 @@
 for feature in ${cmake_cxx_features}; do
   feature_variable="cmake_have_cxx_${feature}"
   eval "feature_value=\${${feature_variable}}"
-  if [ "${feature_value}" -eq "1" ]; then
+  if test "${feature_value}" -eq "1"; then
     cmake_have_cxx_features="${cmake_have_cxx_features} -DCMake_HAVE_CXX_`cmake_toupper ${feature}`=${feature_value}"
   fi
 done
 
+cmake_generate_file "${cmake_bootstrap_dir}/cmSTL.hxx" ""
+
+
 #-----------------------------------------------------------------------------
 # Test Make
 
@@ -1263,7 +1286,7 @@
 cmake_make_flags=
 
 # If MAKE is set, use that for make processor, otherwise use list of known make
-if [ -n "${MAKE}" ]; then
+if test -n "${MAKE}"; then
   cmake_make_processors="${MAKE}"
 else
   cmake_make_processors="${CMAKE_KNOWN_MAKE_PROCESSORS}"
@@ -1282,20 +1305,20 @@
 int main(){ printf("1%c", (char)0x0a); return 0; }
 ' > "test.c"
 cmake_original_make_flags="${cmake_make_flags}"
-if [ "x${cmake_parallel_make}" != "x" ]; then
+if test "x${cmake_parallel_make}" != "x"; then
   cmake_make_flags="${cmake_make_flags} -j ${cmake_parallel_make}"
 fi
 for a in ${cmake_make_processors}; do
-  if [ -z "${cmake_make_processor}" ] && cmake_try_make "${a}" "${cmake_make_flags}" >> ../cmake_bootstrap.log 2>&1; then
+  if test -z "${cmake_make_processor}" && cmake_try_make "${a}" "${cmake_make_flags}" >> ../cmake_bootstrap.log 2>&1; then
     cmake_make_processor="${a}"
   fi
 done
 cmake_full_make_flags="${cmake_make_flags}"
-if [ "x${cmake_original_make_flags}" != "x${cmake_make_flags}" ]; then
-  if [ -z "${cmake_make_processor}" ]; then
+if test "x${cmake_original_make_flags}" != "x${cmake_make_flags}"; then
+  if test -z "${cmake_make_processor}"; then
     cmake_make_flags="${cmake_original_make_flags}"
     for a in ${cmake_make_processors}; do
-      if [ -z "${cmake_make_processor}" ] && cmake_try_make "${a}" "${cmake_make_flags}" >> ../cmake_bootstrap.log 2>&1; then
+      if test -z "${cmake_make_processor}" && cmake_try_make "${a}" "${cmake_make_flags}" >> ../cmake_bootstrap.log 2>&1; then
         cmake_make_processor="${a}"
       fi
     done
@@ -1303,13 +1326,13 @@
 fi
 cd "${cmake_bootstrap_dir}"
 
-if [ -z "${cmake_make_processor}" ]; then
+if test -z "${cmake_make_processor}"; then
   cmake_error 8 "Cannot find appropriate Makefile processor on this system.
 Please specify one using environment variable MAKE."
 fi
 rm -rf "${cmake_bootstrap_dir}/${TMPFILE}"
 echo "Makefile processor on this system is: ${cmake_make_processor}"
-if [ "x${cmake_full_make_flags}" != "x${cmake_make_flags}" ]; then
+if test "x${cmake_full_make_flags}" != "x${cmake_make_flags}"; then
   echo "---------------------------------------------"
   echo "Makefile processor ${cmake_make_processor} does not support parallel build"
   echo "---------------------------------------------"
@@ -1374,7 +1397,7 @@
   echo "${cmake_cxx_compiler} does not have <ext/stdio_filebuf.h>"
 fi
 
-if [ -n "${cmake_ccache_enabled}" ]; then
+if test -n "${cmake_ccache_enabled}"; then
   echo "Building CMake with ccache"
   cmake_c_compiler="ccache ${cmake_c_compiler}"
   cmake_cxx_compiler="ccache ${cmake_cxx_compiler}"
@@ -1476,9 +1499,11 @@
 for a in ${CMAKE_CXX_SOURCES} ${CMAKE_C_SOURCES} ${CMAKE_STD_CXX_SOURCES} ${LexerParser_CXX_SOURCES} ${LexerParser_C_SOURCES} ${KWSYS_CXX_SOURCES} ${KWSYS_C_SOURCES}; do
   objs="${objs} ${a}.o"
 done
-for a in ${LIBUV_C_SOURCES}; do
-  objs="${objs} uv-`cmake_obj ${a}`"
-done
+if test "x${bootstrap_system_libuv}" = "x"; then
+  for a in ${LIBUV_C_SOURCES}; do
+    objs="${objs} uv-`cmake_obj ${a}`"
+  done
+fi
 
 libs=""
 
@@ -1516,23 +1541,29 @@
       ;;
   esac
 fi
-uv_c_flags="${uv_c_flags} `cmake_escape "-I${cmake_source_dir}/Utilities/cmlibuv/include"`"
-if ${cmake_system_mingw}; then
-  uv_c_flags="${uv_c_flags} `cmake_escape "-I${cmake_source_dir}/Utilities/cmlibuv/src/win"`"
+if test "x${bootstrap_system_libuv}" = "x"; then
+  uv_c_flags="${uv_c_flags} `cmake_escape "-I${cmake_source_dir}/Utilities/cmlibuv/include"`"
+  if ${cmake_system_mingw}; then
+    uv_c_flags="${uv_c_flags} `cmake_escape "-I${cmake_source_dir}/Utilities/cmlibuv/src/win"`"
+  else
+    uv_c_flags="${uv_c_flags} `cmake_escape "-I${cmake_source_dir}/Utilities/cmlibuv/src/unix"`"
+  fi
+  uv_c_flags="${uv_c_flags} `cmake_escape "-I${cmake_source_dir}/Utilities/cmlibuv/src"`"
 else
-  uv_c_flags="${uv_c_flags} `cmake_escape "-I${cmake_source_dir}/Utilities/cmlibuv/src/unix"`"
+  if test `which pkg-config`; then
+    uv_c_flags="${uv_c_flags} `pkg-config --cflags libuv`"
+  fi
+  libs="${libs} -luv"
 fi
-uv_c_flags="${uv_c_flags} `cmake_escape "-I${cmake_source_dir}/Utilities/cmlibuv/src"`"
-
-if [ "x${cmake_ansi_cxx_flags}" != "x" ]; then
+if test "x${cmake_ansi_cxx_flags}" != "x"; then
   cmake_cxx_flags="${cmake_ansi_cxx_flags} ${cmake_cxx_flags}"
 fi
 
-if [ "x${cmake_c_flags}" != "x" ]; then
+if test "x${cmake_c_flags}" != "x"; then
   cmake_c_flags="${cmake_c_flags} "
 fi
 
-if [ "x${cmake_cxx_flags}" != "x" ]; then
+if test "x${cmake_cxx_flags}" != "x"; then
   cmake_cxx_flags="${cmake_cxx_flags} "
 fi
 
@@ -1605,11 +1636,13 @@
   echo "${a}.o : ${src} ${dep}" >> "${cmake_bootstrap_dir}/Makefile"
   echo "	${cmake_cxx_compiler} ${cmake_cxx_flags} -DKWSYS_NAMESPACE=cmsys ${src_flags} -c ${src} -o ${a}.o" >> "${cmake_bootstrap_dir}/Makefile"
 done
-for a in ${LIBUV_C_SOURCES}; do
-  src=`cmake_escape "${cmake_source_dir}/Utilities/cmlibuv/${a}"`
-  echo "uv-`cmake_obj ${a}` : ${src} ${dep}" >> "${cmake_bootstrap_dir}/Makefile"
-  echo "	${cmake_c_compiler} ${cmake_c_flags} ${uv_c_flags} -c ${src} -o uv-`cmake_obj ${a}`" >> "${cmake_bootstrap_dir}/Makefile"
-done
+if test "x${bootstrap_system_libuv}" = "x"; then
+  for a in ${LIBUV_C_SOURCES}; do
+    src=`cmake_escape "${cmake_source_dir}/Utilities/cmlibuv/${a}"`
+    echo "uv-`cmake_obj ${a}` : ${src} ${dep}" >> "${cmake_bootstrap_dir}/Makefile"
+    echo "	${cmake_c_compiler} ${cmake_c_flags} ${uv_c_flags} -c ${src} -o uv-`cmake_obj ${a}`" >> "${cmake_bootstrap_dir}/Makefile"
+  done
+fi
 echo '
 rebuild_cache:
 	cd "${cmake_binary_dir}" && "${cmake_source_dir}/bootstrap"
@@ -1629,42 +1662,42 @@
 ' > "${cmake_bootstrap_dir}/InitialCacheFlags.cmake"
 
 # Add configuration settings given as command-line options.
-if [ "x${cmake_bootstrap_qt_gui}" != "x" ]; then
+if test "x${cmake_bootstrap_qt_gui}" != "x"; then
   echo '
 set (BUILD_QtDialog '"${cmake_bootstrap_qt_gui}"' CACHE BOOL "Build Qt dialog for CMake" FORCE)
 ' >> "${cmake_bootstrap_dir}/InitialCacheFlags.cmake"
 fi
-if [ "x${cmake_bootstrap_qt_qmake}" != "x" ]; then
+if test "x${cmake_bootstrap_qt_qmake}" != "x"; then
   echo '
 set (QT_QMAKE_EXECUTABLE "'"${cmake_bootstrap_qt_qmake}"'" CACHE FILEPATH "Location of Qt qmake" FORCE)
 ' >> "${cmake_bootstrap_dir}/InitialCacheFlags.cmake"
 fi
-if [ "x${cmake_sphinx_info}" != "x" ]; then
+if test "x${cmake_sphinx_info}" != "x"; then
   echo '
 set (SPHINX_INFO "'"${cmake_sphinx_info}"'" CACHE BOOL "Build Info manual with Sphinx" FORCE)
 ' >> "${cmake_bootstrap_dir}/InitialCacheFlags.cmake"
 fi
-if [ "x${cmake_sphinx_man}" != "x" ]; then
+if test "x${cmake_sphinx_man}" != "x"; then
   echo '
 set (SPHINX_MAN "'"${cmake_sphinx_man}"'" CACHE BOOL "Build man pages with Sphinx" FORCE)
 ' >> "${cmake_bootstrap_dir}/InitialCacheFlags.cmake"
 fi
-if [ "x${cmake_sphinx_html}" != "x" ]; then
+if test "x${cmake_sphinx_html}" != "x"; then
   echo '
 set (SPHINX_HTML "'"${cmake_sphinx_html}"'" CACHE BOOL "Build html help with Sphinx" FORCE)
 ' >> "${cmake_bootstrap_dir}/InitialCacheFlags.cmake"
 fi
-if [ "x${cmake_sphinx_qthelp}" != "x" ]; then
+if test "x${cmake_sphinx_qthelp}" != "x"; then
   echo '
 set (SPHINX_QTHELP "'"${cmake_sphinx_qthelp}"'" CACHE BOOL "Build qch help with Sphinx" FORCE)
 ' >> "${cmake_bootstrap_dir}/InitialCacheFlags.cmake"
 fi
-if [ "x${cmake_sphinx_build}" != "x" ]; then
+if test "x${cmake_sphinx_build}" != "x"; then
   echo '
 set (SPHINX_EXECUTABLE "'"${cmake_sphinx_build}"'" CACHE FILEPATH "Location of Qt sphinx-build" FORCE)
 ' >> "${cmake_bootstrap_dir}/InitialCacheFlags.cmake"
 fi
-if [ "x${cmake_sphinx_flags}" != "x" ]; then
+if test "x${cmake_sphinx_flags}" != "x"; then
   echo '
 set (SPHINX_FLAGS [==['"${cmake_sphinx_flags}"']==] CACHE STRING "Flags to pass to sphinx-build" FORCE)
 ' >> "${cmake_bootstrap_dir}/InitialCacheFlags.cmake"
@@ -1674,7 +1707,7 @@
 # specification of cmake_init_file.
 (
 cd "${cmake_binary_dir}"
-if [ -f "${cmake_init_file}" ]; then
+if test -f "${cmake_init_file}"; then
   cat "${cmake_init_file}" >> "${cmake_bootstrap_dir}/InitialCacheFlags.cmake"
 fi
 )
@@ -1682,13 +1715,13 @@
 echo "---------------------------------------------"
 
 # Run make to build bootstrap cmake
-if [ "x${cmake_parallel_make}" != "x" ]; then
+if test "x${cmake_parallel_make}" != "x"; then
   ${cmake_make_processor} ${cmake_make_flags}
 else
   ${cmake_make_processor}
 fi
 RES=$?
-if [ "${RES}" -ne "0" ]; then
+if test "${RES}" -ne "0"; then
   cmake_error 9 "Problem while running ${cmake_make_processor}"
 fi
 cd "${cmake_binary_dir}"
@@ -1707,12 +1740,12 @@
 
 # Run bootstrap CMake to configure real CMake
 cmake_options="-DCMAKE_BOOTSTRAP=1"
-if [ -n "${cmake_verbose}" ]; then
+if test -n "${cmake_verbose}"; then
   cmake_options="${cmake_options} -DCMAKE_VERBOSE_MAKEFILE=1"
 fi
 "${cmake_bootstrap_dir}/cmake" "${cmake_source_dir}" "-C${cmake_bootstrap_dir}/InitialCacheFlags.cmake" "-G${cmake_bootstrap_generator}" ${cmake_options} ${cmake_bootstrap_system_libs} "$@"
 RES=$?
-if [ "${RES}" -ne "0" ]; then
+if test "${RES}" -ne "0"; then
   cmake_error 11 "Problem while running initial CMake"
 fi